aboutsummaryrefslogtreecommitdiffstats
path: root/framework
diff options
context:
space:
mode:
authorAshlee Young <ashlee@onosfw.com>2015-10-23 10:00:02 -0700
committerAshlee Young <ashlee@onosfw.com>2015-10-23 10:00:02 -0700
commit753a6c60f47f3ac4f270005b65e9d6481de8eb68 (patch)
tree3d0a1ae3b4d994550f6614b417b991eee3eb8911 /framework
parentc62d20eb3b4620c06d833be06f50b2600d96dd42 (diff)
Adding maven and ant source trees
Change-Id: I0a39b9add833a31b9c3f98d193983ae2f3a5a445 Signed-off-by: Ashlee Young <ashlee@onosfw.com>
Diffstat (limited to 'framework')
-rw-r--r--framework/src/ant/apache-ant-1.9.6/CONTRIBUTORS417
-rw-r--r--framework/src/ant/apache-ant-1.9.6/INSTALL2
-rw-r--r--framework/src/ant/apache-ant-1.9.6/KEYS1497
-rw-r--r--framework/src/ant/apache-ant-1.9.6/LICENSE272
-rw-r--r--framework/src/ant/apache-ant-1.9.6/NOTICE9
-rw-r--r--framework/src/ant/apache-ant-1.9.6/README97
-rw-r--r--framework/src/ant/apache-ant-1.9.6/WHATSNEW6263
-rw-r--r--framework/src/ant/apache-ant-1.9.6/bootstrap.bat138
-rwxr-xr-xframework/src/ant/apache-ant-1.9.6/bootstrap.sh167
-rw-r--r--framework/src/ant/apache-ant-1.9.6/build.bat40
-rwxr-xr-xframework/src/ant/apache-ant-1.9.6/build.sh57
-rw-r--r--framework/src/ant/apache-ant-1.9.6/build.xml2037
-rw-r--r--framework/src/ant/apache-ant-1.9.6/contributors.xml1671
-rw-r--r--framework/src/ant/apache-ant-1.9.6/fetch.xml335
-rw-r--r--framework/src/ant/apache-ant-1.9.6/get-m2.xml121
-rw-r--r--framework/src/ant/apache-ant-1.9.6/lib/README3
-rw-r--r--framework/src/ant/apache-ant-1.9.6/lib/libraries.properties65
-rw-r--r--framework/src/ant/apache-ant-1.9.6/lib/optional/hamcrest-core-1.3.jarbin0 -> 45024 bytes
-rw-r--r--framework/src/ant/apache-ant-1.9.6/lib/optional/junit-3.8.2.jarbin0 -> 120640 bytes
-rw-r--r--framework/src/ant/apache-ant-1.9.6/lib/optional/junit-4.11.jarbin0 -> 245039 bytes
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Integration/anttool1.gifbin0 -> 4211 bytes
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Integration/jext-plugin.html56
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Integration/remacc.gifbin0 -> 10931 bytes
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Integration/toolmenu.gifbin0 -> 17569 bytes
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/LICENSE203
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/BorlandEJBTasks.html143
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/BorlandGenerateClient.html90
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/ant.html413
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/antcall.html201
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/antlr.html200
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/antstructure.html100
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/antversion.html95
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/apply.html499
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/apt.html179
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/attrib.html167
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/augment.html83
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/available.html160
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/basename.html92
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/bindtargets.html92
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/buildnumber.html74
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/cab.html167
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/ccm.html272
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/changelog.html294
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/checksum.html269
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/chgrp.html185
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/chmod.html225
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/chown.html183
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/clearcase.html958
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/common.html59
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/componentdef.html62
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/concat.html337
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/condition.html110
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/conditions.html1087
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/copy.html376
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/copydir.html136
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/copyfile.html73
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/cvs.html230
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/cvspass.html70
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/cvstagdiff.html241
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/cvsversion.html108
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/defaultexcludes.html107
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/delete.html228
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/deltree.html56
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/depend.html216
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/dependset.html171
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/diagnostics.html49
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/dirname.html74
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/ear.html301
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/echo.html193
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/echoproperties.html146
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/echoxml.html74
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/ejb.html1777
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/exec.html460
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/fail.html143
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/filter.html79
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/fixcrlf.html327
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/ftp.html724
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/genkey.html125
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/get.html239
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/gunzip.html29
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/gzip.html29
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/hostinfo.html98
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/image-classdiagram.gifbin0 -> 132412 bytes
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/image.html261
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/import.html349
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/include.html344
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/input.html198
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/jar.html588
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/jarlib-available.html134
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/jarlib-display.html80
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/jarlib-manifest.html123
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/jarlib-resolve.html211
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/java.html405
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/javac.html860
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/javacc.html210
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/javadoc.html915
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/javah.html243
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/jdepend.html177
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/jjdoc.html123
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/jjtree.html563
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/jlink.html177
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/jspc.html308
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/junit.html802
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/junitreport.html214
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/length.html127
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/loadfile.html133
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/loadproperties.html140
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/loadresource.html93
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/local.html186
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/macrodef.html385
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/mail.html362
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/makeurl.html234
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/manifest.html197
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/manifestclasspath.html117
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/mimemail.html115
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/mkdir.html52
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/move.html258
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/native2ascii.html246
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/netrexxc.html338
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/nice.html70
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/pack.html76
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/parallel.html235
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/patch.html111
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/pathconvert.html224
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/presetdef.html184
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/projecthelper.html59
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/property.html345
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/propertyfile.html249
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/propertyhelper.html108
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/pvcstask.html295
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/recorder.html172
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/rename.html64
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/renameextensions.html123
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/replace.html242
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/replaceregexp.html205
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/resourcecount.html107
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/retry.html61
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/rexec.html116
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/rmic.html353
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/rpm.html123
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/schemavalidate.html283
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/scp.html293
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/script.html393
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/scriptdef.html332
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/sequential.html55
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/serverdeploy.html335
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/setproxy.html220
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/signjar.html299
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/sleep.html85
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/sos.html503
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/sound.html123
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/splash.html154
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/sql.html511
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/sshexec.html291
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/sshsession.html288
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/style.html629
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/subant.html608
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/symlink.html146
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/sync.html166
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/tar.html281
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/taskdef.html44
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/telnet.html155
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/tempfile.html229
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/touch.html157
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/translate.html182
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/truncate.html109
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/tstamp.html161
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/typedef.html269
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/unpack.html117
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/untar.html35
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/unzip.html244
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/uptodate.html177
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/verifyjar.html145
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/vss.html823
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/waitfor.html133
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/war.html364
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/whichresource.html120
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/wljspc.html99
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/xmlproperty.html289
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/xmlvalidate.html263
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Tasks/zip.html551
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Types/antlib.html266
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Types/assertions.html208
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Types/classfileset.html119
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Types/custom-programming.html415
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Types/description.html46
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Types/dirset.html154
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Types/extension.html114
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Types/extensionset.html83
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Types/filelist.html120
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Types/fileset.html186
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Types/filterchain.html1739
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Types/filterset.html200
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Types/mapper.html972
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Types/multirootfileset.html173
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Types/namespace.html224
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Types/patternset.html192
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Types/permissions.html164
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Types/propertyset.html143
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Types/redirector.html193
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Types/regexp.html116
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Types/resources.html1380
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Types/selectors-program.html244
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Types/selectors.html1566
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Types/tarfileset.html182
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Types/xmlcatalog.html306
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/Types/zipfileset.html148
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/antexternal.html160
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/anttaskslist.html41
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/argumentprocessor.html76
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/base_task_classes.html114
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/clonevm.html52
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/conceptstypeslist.html90
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/cover.html53
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/credits.html70
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/develop.html544
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/developlist.html53
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/dirtasks.html314
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/favicon.icobin0 -> 3638 bytes
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/feedback.html72
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/ide.html105
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/ifunless.html64
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/images/ant_logo_large.gifbin0 -> 3804 bytes
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/index.html34
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/inputhandler.html116
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/install.html1096
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/installlist.html44
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/intro.html69
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/javacprops.html53
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/listeners.html623
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/platform.html178
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/projecthelper.html150
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/properties.html399
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/proxy.html292
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/running.html622
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/runninglist.html47
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/stylesheets/style.css72
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/sysclasspath.html79
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/targets.html300
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/tasklist.html195
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/tasksoverview.html1198
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/toc.html51
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/tutorial-HelloWorldWithAnt.html520
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/tutorial-tasks-filesets-properties.html993
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/tutorial-tasks-filesets-properties.zipbin0 -> 15377 bytes
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/tutorial-writing-tasks-src.zipbin0 -> 2474 bytes
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/tutorial-writing-tasks.html819
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/tutorials.html45
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/using.html579
-rw-r--r--framework/src/ant/apache-ant-1.9.6/manual/usinglist.html50
-rw-r--r--framework/src/ant/apache-ant-1.9.6/patch.xml48
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/antidote/WHAT-IS-THIS-P6
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/ant-bin.wxs454
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/ant-msi.wxs122
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/ant-update.xsl117
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/changelog.xsl148
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/checkstyle/RequiredHeader.txt17
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/checkstyle/checkstyle-config139
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/checkstyle/checkstyle-frames-sortby-check.xsl367
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/checkstyle/checkstyle-frames.xsl299
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/checkstyle/checkstyle-text.xsl34
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/checkstyle/checkstyle-xdoc.xsl130
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/common2master.xsl73
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/coverage-frames.xsl487
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/jdepend-frames.xsl485
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/jdepend.xsl276
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/junit-frames-xalan1.xsl745
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/junit-frames.xsl972
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/junit-noframes.xsl513
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/log.xsl203
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/manifest4
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/maudit-frames.xsl502
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/mmetrics-frames.xsl1023
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/performance/build.xml124
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/performance/dirscanner.xml316
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/poms/README.txt53
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/poms/ant-antlr/pom.xml75
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/poms/ant-apache-bcel/pom.xml71
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/poms/ant-apache-bsf/pom.xml74
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/poms/ant-apache-log4j/pom.xml69
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/poms/ant-apache-oro/pom.xml74
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/poms/ant-apache-regexp/pom.xml70
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/poms/ant-apache-resolver/pom.xml69
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/poms/ant-apache-xalan2/pom.xml94
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/poms/ant-commons-logging/pom.xml70
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/poms/ant-commons-net/pom.xml75
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/poms/ant-jai/pom.xml85
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/poms/ant-javamail/pom.xml78
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/poms/ant-jdepend/pom.xml72
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/poms/ant-jmf/pom.xml65
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/poms/ant-jsch/pom.xml74
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/poms/ant-junit/pom.xml101
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/poms/ant-junit4/pom.xml71
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/poms/ant-launcher/pom.xml57
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/poms/ant-netrexx/pom.xml98
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/poms/ant-swing/pom.xml66
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/poms/ant-testutil/pom.xml74
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/poms/ant/pom.xml225
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/poms/pom.xml151
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/printFailingTests.xsl45
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/tagdiff.xsl179
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/asf-logo.gifbin0 -> 7279 bytes
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/buildfiletest-base.xml11
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/antclassloader.xml80
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/case.xml37
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/containersrc/test/SpecialSeq.java67
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/directoryscanner.xml41
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/dispatch/dispatch.xml34
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/duplicate-target-imported.xml23
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/duplicate-target.xml31
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/duplicate-target2.xml26
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/executor.xml29
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/extended-taskdef.xml73
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/immutable.xml79
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/include/basic/include.inc20
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/include/basic/include.xml25
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/include/basic/relative.xml26
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/include/frag#ment/include.inc20
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/include/frag#ment/include.xml26
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/include/frag#ment/relative.xml26
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/include/frag#ment/simple.xml23
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/include/included_file_parse_error/build.xml33
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/include/included_file_parse_error/included_file.xml21
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/include/included_file_task_error/build.xml33
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/include/included_file_task_error/included_file.xml21
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/include/including_file_parse_error/build.xml35
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/include/including_file_parse_error/included_file.xml20
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/include/including_file_task_error/build.xml34
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/include/including_file_task_error/included_file.xml20
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/include/with space/include.inc19
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/include/with space/include.xml25
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/include/with space/relative.xml25
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/include/with space/simple.xml22
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/loaderref/loaderref.xml46
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/loaderref/src/Task1.java21
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/location.xml74
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/taskcontainer.xml62
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/topleveltasks/notarget.xml21
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/topleveltasks/targetlevelant.xml22
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/topleveltasks/toplevelant.xml21
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/unknownelement.xml39
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/build.xml147
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/concat.xml117
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/dynamicfilter.xml48
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/expected/escapeunicode.test9
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/expected/head-tail.head.test10
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/expected/head-tail.headAllSkip.test58
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/expected/head-tail.headLines.test2
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/expected/head-tail.headLinesSkip.test2
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/expected/head-tail.headSkip.test10
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/expected/head-tail.headtail.test2
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/expected/head-tail.tail.test10
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/expected/head-tail.tailAllSkip.test58
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/expected/head-tail.tailLines.test2
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/expected/head-tail.tailLinesSkip.test2
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/expected/head-tail.tailSkip.test10
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/expected/linecontains.test4
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/expected/negatelinecontains.test3
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/expected/replacetokens.double.test2
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/expected/replacetokens.test2
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/expected/stripjavacomments.test19
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/head-tail.xml146
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/input/escapeunicode.test9
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/input/head-tail.small.test5
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/input/head-tail.test60
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/input/linecontains.test7
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/input/replacetokens.double.test2
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/input/replacetokens.mustache.test2
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/input/replacetokens.test2
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/input/sample.properties16
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/input/stripjavacomments.test30
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/tokenfilter.xml357
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/abstractcvstask.xml47
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/ant.topleveltest.xml20
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/ant.xml261
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/ant/ant.xml33
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/ant/references.xml33
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/antlib.current-test.xml29
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/antlib.xml72
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/antstructure.xml41
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/available.xml269
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/bar.properties15
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/basename.xml57
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/bunzip2.xml47
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/bzip2.xml44
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/calltarget.xml120
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/checksum.xml266
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/checksum/foo/Bar1
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/checksum/foo/zap/Eenie1
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/classloader.xml40
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/concat-input/A1
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/concat-input/B1
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/concat.xml214
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/condition.xml521
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/conditions/antversion.xml66
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/conditions/http.xml57
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/conditions/isfailure.xml65
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/conditions/isfileselected.xml70
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/conditions/isreachable.xml105
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/conditions/isreference.xml60
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/conditions/issigned.xml78
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/conditions/jars/apassword.jarbin0 -> 1708 bytes
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/conditions/jars/nosign.jarbin0 -> 451 bytes
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/conditions/jars/pass.jarbin0 -> 1690 bytes
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/conditions/parsersupports.xml95
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/conditions/typefound.xml75
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/conditions/xor.xml112
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/copy.filterset1
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/copy.xml268
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/copy/expected/utf-81
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/copy/input/iso8859-11
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/copydir.xml56
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/copyfile.xml56
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/cvspass.xml85
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/defaultexcludes.xml37
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/delete.xml194
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/deltree.xml29
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/dirname.xml41
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/dynamictask.xml37
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/echoxml.xml46
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/email/mail.xml40
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/exec/blabla.sh24
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/exec/blabla.xml19
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/exec/exec.xml69
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/exec/parrot.sh19
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/exec/spawn.sh29
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/expected/asf-logo-huge.tar.bz2bin0 -> 58089 bytes
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/expected/asf-logo-huge.tar.gzbin0 -> 30905 bytes
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/expected/asf-logo.gif.bz2bin0 -> 7435 bytes
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/expected/asf-logo.gif.gzbin0 -> 6996 bytes
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/expected/asf-logo.gif.md51
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/expected/asf-logo.gif.md5sum1
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/expected/asf-logo.gif.pattern1
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/expected/asf-logo.gif.svf1
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/expected/asf-logo.gif.tarbin0 -> 10240 bytes
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/expected/asf-logo.gif.tar.bz2bin0 -> 7543 bytes
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/expected/asf-logo.gif.tar.gzbin0 -> 7116 bytes
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/expected/asf-logo.gif.zipbin0 -> 7121 bytes
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/expected/copy.filterset.filtered1
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/fail.xml130
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/filter.xml72
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/filter1.txt1
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/filter2.txt1
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/filter3.txt1
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/filterdefs.properties15
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/fixcrlf/build.xml331
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/fixcrlf/expected.zipbin0 -> 5642 bytes
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/fixcrlf/input.zipbin0 -> 4815 bytes
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/foo.properties15
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/get.xml107
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/gunzip.xml58
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/gzip.xml56
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/a.xml20
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/b.xml21
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/bad.xml20
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/c.xml21
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/import.xml34
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/import_bad_import.xml20
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/import_same_target.xml21
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/imported.xml26
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/importtargetfirst.xml22
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/recursive-selfimport.xml22
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/same_target.xml20
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/subdir/importinsequential-inner.xml25
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/subdir/importinsequential.xml22
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/subdir/importintarget-inner.xml23
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/subdir/importintarget.xml24
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/subdir/serial.xml22
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/symlinks/d1/p1.xml21
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/symlinks/d2/p2.xml18
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/symlinks/d3a/p3.xml18
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/targetfirst.xml21
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/unnamed1.xml22
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/unnamed2.xml20
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/unnamedImport.xml25
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/initializeclass.xml41
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/input.properties25
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/input.stdin2
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/input.xml119
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/jar.xml285
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/java.xml404
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/javadoc/java/ClassToJavadoc.java39
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/javadoc/javadoc.xml155
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/loadfile.xml163
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/macrodef.xml290
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/makeurl.xml79
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/manifest.xml267
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/manifestclasspath.xml238
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/manifestclasspath/Alpha.java21
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/manifestclasspath/Beta.java25
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/manifests/test1.mf1
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/manifests/test2.mf2
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/manifests/test3.mf3
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/manifests/test4.mf4
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/manifests/test5.mf3
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/manifests/test6.mf5
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/manifests/test7.mf4
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/mkdir.xml39
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/move.xml263
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/multimap.xml192
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/nice.xml66
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/nopermissions.zipbin0 -> 138 bytes
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/antlr/antlr.g76
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/antlr/antlr.xml128
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/antlr/extended.calc.g23
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/antlr/java.g1162
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/antlr/java.tree.g312
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/depend/depend.xml196
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/depend/src1/A.java20
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/depend/src1/B.java19
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/depend/src1/C.java19
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/depend/src1/D.java19
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/depend/src1/E.java22
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/depend/src2/A.java21
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/depend/src2/B.java19
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/depend/src3/A.java23
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/depend/src3/B.java19
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/depend/src4/test/ContainsOnlyInner.java24
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/depend/src4/test/MethodParam.java24
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/depend/src4/test/Outer.java23
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/depend/src5/A.java22
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/depend/src5/B.java19
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/echoproperties.properties15
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/echoproperties.xml133
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/i18n/translate/expected/de/template.txt1
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/i18n/translate/input/resources_ger_DE.properties24
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/i18n/translate/input/template.txt1
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/i18n/translate/translate.xml44
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/image/image.xml73
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/image/src/badimage.jpgbin0 -> 875960 bytes
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/image/src/largeimage.jpgbin0 -> 336783 bytes
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/javah/build.xml56
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/javah/input/org/example/Foo.java26
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/jdepend/jdepend.xml70
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/jsp/1nvalid-classname.jsp25
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/jsp/WEB-INF/web.xml20
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/jsp/default.jsp25
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/jsp/missing_tld.jsp32
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/jsp/simple.jsp25
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/jsp/uriroot.jsp25
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/jsp/xml.jsp32
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/jspc.xml133
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/junit.xml361
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/junit/cdataoutput.xml28
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/junit/matches.xml25
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/junit/teardownlistener.xml50
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/junitreport-with-include/junit-frames.xsl879
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/junitreport-with-include/junit-import.xsl24
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/junitreport.xml189
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/junitreport/INCOMPLETE-sampleproject.incomplete.xml31
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/junitreport/NAMESPACE-sampleproject.namespace.xml116
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/junitreport/TEST-sampleproject.coins.CoinTest.xml115
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/junitreport/TEST-sampleproject.util.UniqueStringTest.xml93
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/junitreport/WRONGELEMENT-sampleproject.wrongelement.xml18
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/junitreport/ZEROBYTES-sampleproject.package.xml0
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/junitreport/junit-frames.xsl879
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/native2ascii/build.xml38
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/native2ascii/expected/iso8859-1.test1
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/native2ascii/input/iso8859-1.test1
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/net/ftp.xml331
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/propertyfile.xml123
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/pvcs.xml50
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/replaceregexp.properties16
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/replaceregexp.xml83
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/replaceregexp2.properties15
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/replaceregexp2.result.properties15
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/schemavalidate.xml100
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/script.xml46
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/script/scriptdef.xml145
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/script_reference.xml27
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/sos/sos.xml124
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/splash-test.xml45
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/unix/symlink.xml354
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/vss/vss.xml68
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xalan-redirect-in.xsl37
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xml/about.xml26
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xml/apache.xsl35
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xml/books.xml28
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xml/catalog2
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xml/doc-in-ns.xsd38
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xml/doc.dtd24
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xml/doc.xsd37
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xml/doc.xsl26
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xml/docwithentity.xml29
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xml/endpiece-noSchema-invalid.xml30
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xml/endpiece-noSchema.xml28
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xml/endpiece-ns-no-location.xml23
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xml/endpiece.xml23
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xml/endpiece2.xml26
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xml/entity.xml20
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xml/iso-2022-jp.xml23
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xml/stylesheet_include.xsl28
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xml/stylesheet_with_include.xsl28
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xml/test.xml25
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xml/test.xsl25
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xml/utf-8.xml23
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xml/validate.xml28
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xmlvalidate.xml208
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xslt.xml102
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xsltliaison-encoding-in.xml20
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xsltliaison-encoding-in.xsl27
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xsltliaison-in.xml23
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xsltliaison-in.xsl20
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xsltliaison-include.xml19
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xsltliaison-include.xsl20
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/parallel.xml163
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/pathconvert.xml42
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/presetdef.xml147
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/property.xml92
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/property1.properties17
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/property2.properties17
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/property3.properties18
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/property4.properties16
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/property5.properties17
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/recorder.xml73
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/recorder/rectest1.result1
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/recorder/rectest2.result2
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/recorder/rectest3.result2
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/recorder/rectest4.result1
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/recorder/rectest5.result5
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/recorder/rectest6.result3
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/recorder2.xml29
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/rename.xml50
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/replace.xml94
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/replace/result.txt7
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/replace/source.txt4
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/replace/value.txt3
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/rmic/rmic.xml499
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/rmic/src/AntTimestamp.java45
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/rmic/src/RemoteTimestamp.java26
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/rmic/src/RemoteTimestampImpl.java28
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/signjar.xml97
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/skinconfig.dtd19
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/sleep.xml47
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/style/build.xml197
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/style/data.xml18
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/style/printFilename.xsl38
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/style/printParams.xsl36
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/style/testNewerStylesheet.xsl28
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/subant.xml65
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/subant/genericsubant.xml22
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/subant/subant-test1/mysubant.xml31
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/subant/subant-test2/mysubant.xml28
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/sync.xml141
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/tar.xml200
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/taskdef.xml89
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/template.xml17
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/test.antlib.xml22
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/test2.antlib.xml22
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/toplevelant.xml24
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/toplevelantcall.xml24
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/toplevelsubant.xml26
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/touch.xml216
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/typeadapter.xml79
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/typedef.xml84
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/untar.xml103
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/unzip.xml184
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/uptodate.xml57
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/war.xml39
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/whichresource.xml37
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlns.xml67
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty.xml44
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/goldfiles/keeproot-collapse-input1.properties21
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/goldfiles/keeproot-collapse-original.properties20
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/goldfiles/keeproot-collapse-override.properties17
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/goldfiles/keeproot-nocollapse-input1.properties8
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/goldfiles/keeproot-nocollapse-original.properties20
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/goldfiles/keeproot-semantic-include.properties21
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/goldfiles/keeproot-semantic-input1.properties21
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/goldfiles/keeproot-semantic-override.properties17
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/goldfiles/nokeeproot-collapse-input1.properties21
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/goldfiles/nokeeproot-collapse-original.properties19
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/goldfiles/nokeeproot-nocollapse-input1.properties7
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/goldfiles/nokeeproot-nocollapse-multi.properties16
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/goldfiles/nokeeproot-nocollapse-original.properties19
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/goldfiles/nokeeproot-semantic-include-input1.properties21
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/goldfiles/nokeeproot-semantic-input1.properties21
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/goldfiles/nokeeproot-semantic-locations.properties16
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/goldfiles/nokeeproot-semantic-paths.properties16
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/goldfiles/nokeeproot-semantic-references.properties20
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/inputs/input1.xml27
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/inputs/locations.xml20
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/inputs/multi.xml25
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/inputs/original.xml22
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/inputs/override.xml27
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/inputs/paths.xml22
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/inputs/references.xml24
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty_data.dtd30
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty_data.xml22
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty_needscat.xml22
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty_withdtd.xml24
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/zip.xml287
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/zip/zipgroupfileset1.zipbin0 -> 2211 bytes
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/zip/zipgroupfileset2.zipbin0 -> 1825 bytes
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/zip/zipgroupfileset3.zipbin0 -> 313 bytes
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/testkeystorebin0 -> 2453 bytes
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/addtype.xml163
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/assertions.xml205
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/assertions/AssertionMain.java31
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/assertions/AssertionTest.java45
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/description1.xml22
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/description2.xml23
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/description3.xml23
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/description4.xml23
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/filelist.xml54
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/filterset.xml146
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/filterseta.txt2
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/filtersetb.txt5
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/filtersetc.txt7
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/filtersetd.txt1
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/filtersfile12
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/filtersfile21
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/flexinteger.xml35
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/gold/filterset1.txt2
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/gold/filterset2.txt5
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/gold/filterset3.txt7
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/mapper.xml67
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/mappers/define.mapperresult.xml25
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/mappers/globmapper.xml32
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/mappers/regexpmapper.xml32
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/mappers/scriptmapper.xml58
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/poly.xml62
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/quote1.xml25
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/quote2.xml26
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/redirector.xml79
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/resources/javaresource.xml24
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/resources/resourcelist.xml26
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/resources/tarentry.xml40
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/selectors.xml356
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/selectors/scriptselector.xml138
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/selectors/signedselector.xml61
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/xmlcatalog.xml150
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/xmlcatalog.xsl47
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/xmlcatalog1.xml30
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/xmlcatalog2.xml27
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/xmlfragment.xml31
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/util/simple.properties24
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/testcases/util/unusual.properties37
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/etc/yearcheck.sh101
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/AntClassLoader.java1622
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/AntTypeDefinition.java389
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/ArgumentProcessor.java72
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/ArgumentProcessorRegistry.java171
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/BuildEvent.java203
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/BuildException.java153
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/BuildListener.java110
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/BuildLogger.java72
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/ComponentHelper.java1101
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/DefaultDefinitions.java76
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/DefaultLogger.java380
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/DemuxInputStream.java74
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/DemuxOutputStream.java249
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/Diagnostics.java715
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/DirectoryScanner.java1900
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/DynamicAttribute.java38
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/DynamicAttributeNS.java41
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/DynamicConfigurator.java29
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/DynamicConfiguratorNS.java27
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/DynamicElement.java36
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/DynamicElementNS.java37
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/DynamicObjectAttribute.java41
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/Evaluable.java29
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/Executor.java48
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/ExitException.java61
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/ExitStatusException.java69
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/ExtensionPoint.java60
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/FileScanner.java158
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/IntrospectionHelper.java1745
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/Location.java179
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/MagicNames.java293
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/Main.java1317
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/NoBannerLogger.java100
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/PathTokenizer.java166
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/Project.java2494
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/ProjectComponent.java169
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/ProjectHelper.java698
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/ProjectHelperRepository.java337
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/PropertyHelper.java1215
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/RuntimeConfigurable.java608
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/SubBuildListener.java58
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/Target.java532
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/Task.java481
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/TaskAdapter.java182
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/TaskConfigurationChecker.java111
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/TaskContainer.java41
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/TypeAdapter.java66
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/UnknownElement.java699
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/UnsupportedAttributeException.java49
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/UnsupportedElementException.java57
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/XmlLogger.java474
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/antlib.xml144
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/attribute/AttributeNamespace.java28
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/attribute/BaseIfAttribute.java86
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/attribute/EnableAttribute.java35
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/attribute/IfBlankAttribute.java39
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/attribute/IfSetAttribute.java39
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/attribute/IfTrueAttribute.java41
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/defaultManifest.mf4
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/dispatch/DispatchTask.java59
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/dispatch/DispatchUtils.java124
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/dispatch/Dispatchable.java31
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/BaseFilterReader.java199
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/BaseParamFilterReader.java74
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/ChainableReader.java37
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/ClassConstants.java165
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/ConcatFilter.java218
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/EscapeUnicode.java123
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/ExpandProperties.java142
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/FixCrLfFilter.java1004
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/HeadFilter.java222
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/LineContains.java244
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/LineContainsRegExp.java242
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/PrefixLines.java164
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/ReplaceTokens.java379
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/SortFilter.java375
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/StringInputStream.java49
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/StripJavaComments.java145
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/StripLineBreaks.java154
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/StripLineComments.java237
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/SuffixLines.java174
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/TabsToSpaces.java155
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/TailFilter.java243
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/TokenFilter.java712
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/UniqFilter.java37
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/util/ChainReaderHelper.java288
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/util/JavaClassHelper.java70
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/helper/AntXMLContext.java417
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/helper/DefaultExecutor.java60
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/helper/IgnoreDependenciesExecutor.java70
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/helper/ProjectHelper2.java1238
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/helper/ProjectHelperImpl.java1026
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/helper/SingleCheckExecutor.java47
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/input/DefaultInputHandler.java120
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/input/GreedyInputHandler.java80
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/input/InputHandler.java41
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/input/InputRequest.java93
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/input/MultipleChoiceInputRequest.java58
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/input/PropertyFileInputHandler.java92
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/input/SecureInputHandler.java59
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/launch/AntMain.java42
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/launch/LaunchException.java38
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/launch/Launcher.java412
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/launch/Locator.java528
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/listener/AnsiColorLogger.java249
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/listener/BigProjectLogger.java194
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/listener/CommonsLoggingListener.java332
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/listener/Log4jListener.java177
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/listener/MailLogger.java440
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/listener/ProfileLogger.java112
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/listener/SilentLogger.java62
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/listener/SimpleBigProjectLogger.java46
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/listener/TimestampedLogger.java54
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/listener/defaults.properties58
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/loader/AntClassLoader2.java31
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/loader/AntClassLoader5.java65
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/property/GetProperty.java31
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/property/LocalProperties.java152
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/property/LocalPropertyStack.java161
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/property/NullReturn.java38
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/property/ParseNextProperty.java44
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/property/ParseProperties.java199
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/property/PropertyExpander.java51
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/property/ResolvePropertyMap.java151
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/property/package.html19
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/AbstractCvsTask.java873
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/AbstractJarSignerTask.java423
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Ant.java836
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/AntStructure.java485
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Antlib.java184
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/AntlibDefinition.java81
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Apt.java270
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/AttributeNamespaceDef.java51
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/AugmentReference.java96
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Available.java514
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/BUnzip2.java112
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/BZip2.java74
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Basename.java110
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/BindTargets.java91
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/BuildNumber.java201
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/CVSPass.java172
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/CallTarget.java255
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Checksum.java712
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Chmod.java261
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Classloader.java244
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/CloseResources.java59
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/CommandLauncherTask.java56
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Componentdef.java40
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Concat.java955
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/ConditionTask.java130
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Copy.java1111
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/CopyPath.java214
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Copydir.java163
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Copyfile.java116
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Cvs.java41
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/DefBase.java167
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/DefaultExcludes.java115
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Definer.java639
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Delete.java836
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Deltree.java112
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/DependSet.java299
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/DiagnosticsTask.java41
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Dirname.java82
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Ear.java154
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Echo.java170
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/EchoXML.java137
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Exec.java281
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/ExecTask.java726
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Execute.java734
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/ExecuteJava.java331
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/ExecuteOn.java784
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/ExecuteStreamHandler.java68
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/ExecuteWatchdog.java177
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Exit.java235
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Expand.java527
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Filter.java101
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/FixCRLF.java696
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/GUnzip.java97
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/GZip.java68
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/GenerateKey.java420
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Get.java883
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/HostInfo.java256
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/ImportTask.java348
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Input.java259
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/JDBCTask.java525
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Jar.java1238
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Java.java965
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Javac.java1270
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Javadoc.java2624
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Jikes.java132
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/JikesOutputParser.java183
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/KeySubst.java191
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Length.java335
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/LoadFile.java41
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/LoadProperties.java248
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/LoadResource.java236
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Local.java47
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/LogOutputStream.java111
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/LogStreamHandler.java70
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/MacroDef.java851
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/MacroInstance.java411
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/MakeUrl.java298
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Manifest.java1183
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/ManifestClassPath.java180
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/ManifestException.java36
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/ManifestTask.java293
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/MatchingTask.java446
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Mkdir.java114
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Move.java382
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Nice.java99
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Pack.java212
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Parallel.java489
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Patch.java215
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/PathConvert.java511
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/PreSetDef.java275
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/ProcessDestroyer.java220
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/ProjectHelperTask.java50
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Property.java726
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/PropertyHelperTask.java145
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/PumpStreamHandler.java298
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Recorder.java324
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/RecorderEntry.java367
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Redirector.java1022
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Rename.java96
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Replace.java955
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/ResourceCount.java124
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Retry.java119
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Rmic.java853
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/SQLExec.java1162
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/SendEmail.java45
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Sequential.java74
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/SignJar.java645
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Sleep.java194
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/StreamPumper.java252
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/SubAnt.java642
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Sync.java606
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Tar.java1016
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/TaskOutputStream.java96
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Taskdef.java51
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/TempFile.java163
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Touch.java381
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Transform.java30
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Truncate.java205
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Tstamp.java341
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Typedef.java46
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Unpack.java195
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Untar.java244
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/UpToDate.java277
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/VerifyJar.java207
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/WaitFor.java277
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/War.java233
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/WhichResource.java199
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/XSLTLiaison.java69
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/XSLTLiaison2.java33
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/XSLTLiaison3.java35
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/XSLTLiaison4.java42
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/XSLTLogger.java31
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/XSLTLoggerAware.java31
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/XSLTProcess.java1689
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/XmlProperty.java780
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Zip.java2274
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/compilers/AptCompilerAdapter.java187
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/compilers/AptExternalCompilerAdapter.java71
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/compilers/CompilerAdapter.java52
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/compilers/CompilerAdapterExtension.java40
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/compilers/CompilerAdapterFactory.java202
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/compilers/DefaultCompilerAdapter.java736
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/compilers/Gcj.java160
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/compilers/Javac12.java91
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/compilers/Javac13.java70
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/compilers/JavacExternal.java92
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/compilers/Jikes.java221
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/compilers/Jvc.java116
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/compilers/Kjc.java119
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/compilers/Sj.java61
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/And.java50
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/AntVersion.java171
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/Condition.java35
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/ConditionBase.java281
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/Contains.java76
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/Equals.java148
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/FilesMatch.java101
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/HasFreeSpace.java101
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/HasMethod.java192
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/Http.java117
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/IsFailure.java54
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/IsFalse.java55
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/IsFileSelected.java81
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/IsLastModified.java219
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/IsReachable.java207
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/IsReference.java89
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/IsSet.java51
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/IsSigned.java152
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/IsTrue.java55
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/Matches.java119
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/Not.java50
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/Or.java50
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/Os.java321
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/ParserSupports.java150
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/ResourceContains.java165
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/ResourceExists.java56
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/ResourcesMatch.java93
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/Socket.java87
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/TypeFound.java90
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/Xor.java49
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/cvslib/CVSEntry.java112
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/cvslib/ChangeLogParser.java321
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/cvslib/ChangeLogTask.java489
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/cvslib/ChangeLogWriter.java114
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/cvslib/CvsTagDiff.java576
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/cvslib/CvsTagEntry.java109
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/cvslib/CvsUser.java93
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/cvslib/CvsVersion.java169
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/cvslib/RCSFile.java69
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/cvslib/RedirectingOutputStream.java46
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/cvslib/RedirectingStreamHandler.java61
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/defaults.properties210
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/email/EmailAddress.java197
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/email/EmailTask.java634
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/email/Header.java61
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/email/Mailer.java277
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/email/Message.java203
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/email/MimeMailer.java343
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/email/PlainMailer.java177
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/email/UUMailer.java56
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/launcher/CommandLauncher.java213
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/launcher/CommandLauncherProxy.java54
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/launcher/Java13CommandLauncher.java66
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/launcher/MacCommandLauncher.java63
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/launcher/OS2CommandLauncher.java82
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/launcher/PerlScriptCommandLauncher.java90
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/launcher/ScriptCommandLauncher.java88
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/launcher/VmsCommandLauncher.java145
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/launcher/WinNTCommandLauncher.java78
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ANTLR.java438
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/Cab.java357
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/EchoProperties.java543
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/Javah.java513
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/Native2Ascii.java328
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/NetRexxC.java1042
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/PropertyFile.java726
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/RenameExtensions.java146
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ReplaceRegExp.java533
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/Rpm.java364
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/SchemaValidate.java529
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/Script.java133
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/TraXLiaison.java650
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/XMLValidateTask.java764
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/XSLTTraceSupport.java32
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/Xalan2TraceSupport.java54
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ccm/CCMCheck.java208
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ccm/CCMCheckin.java39
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ccm/CCMCheckinDefault.java38
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ccm/CCMCheckout.java35
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ccm/CCMCreateTask.java335
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ccm/CCMReconfigure.java159
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ccm/Continuus.java144
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCCheckin.java343
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCCheckout.java516
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCLock.java378
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCMkattr.java425
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCMkbl.java365
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCMkdir.java237
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCMkelem.java424
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCMklabel.java402
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCMklbtype.java440
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCRmtype.java373
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCUnCheckout.java141
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCUnlock.java260
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCUpdate.java331
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/ClearCase.java242
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/AntAnalyzer.java144
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/ClassFile.java121
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/ClassFileIterator.java33
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/ClassFileUtils.java52
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/Depend.java917
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/DirectoryIterator.java164
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/JarFileIterator.java89
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/ClassCPInfo.java93
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/ConstantCPInfo.java63
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/ConstantPool.java358
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/ConstantPoolEntry.java242
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/DoubleCPInfo.java58
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/FieldRefCPInfo.java130
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/FloatCPInfo.java56
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/IntegerCPInfo.java56
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/InterfaceMethodRefCPInfo.java137
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/InvokeDynamicCPInfo.java85
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/LongCPInfo.java56
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/MethodHandleCPInfo.java107
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/MethodRefCPInfo.java133
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/MethodTypeCPInfo.java82
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/NameAndTypeCPInfo.java112
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/StringCPInfo.java74
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/Utf8CPInfo.java67
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ejb/BorlandDeploymentTool.java559
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ejb/BorlandGenerateClient.java313
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ejb/DescriptorHandler.java390
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ejb/EJBDeploymentTool.java61
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ejb/EjbJar.java630
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ejb/GenericDeploymentTool.java953
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ejb/IPlanetDeploymentTool.java403
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ejb/IPlanetEjbc.java1495
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ejb/IPlanetEjbcTask.java321
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ejb/InnerClassFilenameFilter.java54
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ejb/JbossDeploymentTool.java111
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ejb/JonasDeploymentTool.java835
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ejb/WeblogicDeploymentTool.java932
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ejb/WeblogicTOPLinkDeploymentTool.java113
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ejb/WebsphereDeploymentTool.java897
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/extension/Compatability.java57
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/extension/Compatibility.java57
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/extension/DeweyDecimal.java54
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/extension/Extension.java690
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/extension/ExtensionAdapter.java215
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/extension/ExtensionResolver.java43
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/extension/ExtensionSet.java153
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/extension/ExtensionUtil.java215
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/extension/ExtraAttribute.java83
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/extension/JarLibAvailableTask.java157
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/extension/JarLibDisplayTask.java119
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/extension/JarLibManifestTask.java296
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/extension/JarLibResolveTask.java268
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/extension/LibFileSet.java117
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/extension/LibraryDisplayer.java150
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/extension/Specification.java605
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/extension/resolvers/AntResolver.java117
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/extension/resolvers/LocationResolver.java65
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/extension/resolvers/URLResolver.java133
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/i18n/Translate.java632
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/image/Image.java421
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/j2ee/AbstractHotDeploymentTool.java193
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/j2ee/GenericHotDeploymentTool.java140
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/j2ee/HotDeploymentTool.java61
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/j2ee/JonasHotDeploymentTool.java252
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/j2ee/ServerDeploy.java153
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/j2ee/WebLogicHotDeploymentTool.java247
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/javacc/JJDoc.java226
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/javacc/JJTree.java416
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/javacc/JavaCC.java579
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/javah/Gcjh.java89
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/javah/JavahAdapter.java38
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/javah/JavahAdapterFactory.java120
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/javah/Kaffeh.java94
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/javah/SunJavah.java123
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/jdepend/JDependTask.java684
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/jlink/ClassNameReader.java139
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/jlink/JlinkTask.java183
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/jlink/jlink.java458
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/jsp/Jasper41Mangler.java93
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/jsp/JspC.java709
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/jsp/JspMangler.java47
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/jsp/JspNameMangler.java155
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/jsp/WLJspc.java334
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/jsp/compilers/DefaultJspCompilerAdapter.java153
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/jsp/compilers/JasperC.java182
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/jsp/compilers/JspCompilerAdapter.java64
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/jsp/compilers/JspCompilerAdapterFactory.java122
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/AggregateTransformer.java346
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/BaseTest.java241
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/BatchTest.java202
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/BriefJUnitResultFormatter.java300
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/Constants.java46
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/CustomJUnit4TestAdapterCache.java90
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/DOMUtil.java228
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/Enumerations.java177
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/FailureRecorder.java448
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/FormatterElement.java401
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/IgnoredTestListener.java52
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/IgnoredTestResult.java99
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnit4TestMethodAdapter.java193
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitResultFormatter.java65
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTask.java2283
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTaskMirror.java190
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTaskMirrorImpl.java109
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTest.java542
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTestRunner.java1297
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitVersionHelper.java179
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/OutErrSummaryJUnitResultFormatter.java36
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/PlainJUnitResultFormatter.java317
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/SummaryJUnitResultFormatter.java213
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/TearDownOnVmCrash.java144
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/TestIgnored.java35
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/TestListenerWrapper.java63
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/XMLConstants.java141
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/XMLJUnitResultFormatter.java366
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/XMLResultAggregator.java329
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/native2ascii/DefaultNative2Ascii.java106
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/native2ascii/KaffeNative2Ascii.java88
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/native2ascii/Native2AsciiAdapter.java44
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/native2ascii/Native2AsciiAdapterFactory.java116
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/native2ascii/SunNative2Ascii.java71
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/net/FTP.java2725
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/net/FTPConfigurator.java99
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/net/FTPTask.java965
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/net/FTPTaskConfig.java28
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/net/FTPTaskMirror.java24
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/net/FTPTaskMirrorImpl.java1951
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/net/MimeMail.java43
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/net/RExecTask.java479
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/net/SetProxy.java283
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/net/TelnetTask.java397
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/pvcs/Pvcs.java675
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/pvcs/PvcsProject.java49
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/script/ScriptDef.java397
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/script/ScriptDefBase.java132
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/sos/SOS.java479
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/sos/SOSCheckin.java101
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/sos/SOSCheckout.java85
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/sos/SOSCmd.java81
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/sos/SOSGet.java116
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/sos/SOSLabel.java91
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/sos/package.html29
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/sound/AntSoundPlayer.java251
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/sound/SoundTask.java193
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/splash/SplashScreen.java181
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/splash/SplashTask.java297
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ssh/AbstractSshMessage.java272
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ssh/Directory.java196
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ssh/LogListener.java30
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ssh/SSHBase.java236
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ssh/SSHExec.java519
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ssh/SSHSession.java333
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ssh/SSHUserInfo.java217
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ssh/Scp.java486
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ssh/ScpFromMessage.java311
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ssh/ScpFromMessageBySftp.java205
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ssh/ScpToMessage.java331
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ssh/ScpToMessageBySftp.java277
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/testing/BlockFor.java71
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/testing/BuildTimeoutException.java114
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/testing/Funtest.java577
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/unix/AbstractAccessTask.java110
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/unix/Chgrp.java84
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/unix/Chown.java84
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/unix/Symlink.java600
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/vss/MSVSS.java784
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/vss/MSVSSADD.java122
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/vss/MSVSSCHECKIN.java114
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/vss/MSVSSCHECKOUT.java165
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/vss/MSVSSCP.java69
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/vss/MSVSSCREATE.java91
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/vss/MSVSSConstants.java127
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/vss/MSVSSGET.java172
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/vss/MSVSSHISTORY.java199
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/vss/MSVSSLABEL.java108
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/windows/Attrib.java196
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/rmic/DefaultRmicAdapter.java493
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/rmic/ForkingSunRmic.java90
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/rmic/KaffeRmic.java104
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/rmic/RmicAdapter.java67
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/rmic/RmicAdapterFactory.java135
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/rmic/SunRmic.java114
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/rmic/WLRmic.java136
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/rmic/XNewRmic.java52
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/AbstractFileSet.java922
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/AntFilterReader.java178
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/ArchiveFileSet.java596
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/ArchiveScanner.java363
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/Assertions.java359
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/Commandline.java689
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/CommandlineJava.java699
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/Comparison.java95
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/DTDLocation.java33
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/DataType.java367
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/Description.java116
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/DirSet.java115
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/EnumeratedAttribute.java153
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/Environment.java177
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/FileList.java219
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/FileSet.java94
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/FilterChain.java418
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/FilterSet.java654
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/FilterSetCollection.java88
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/FlexInteger.java54
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/LogLevel.java87
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/Mapper.java322
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/Parameter.java82
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/Parameterizable.java31
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/Path.java775
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/PatternSet.java541
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/Permissions.java356
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/PropertySet.java577
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/Quantifier.java146
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/RedirectorElement.java630
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/Reference.java134
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/RegularExpression.java141
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/Resource.java439
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/ResourceCollection.java50
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/ResourceFactory.java38
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/ResourceLocation.java106
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/Substitution.java77
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/TarFileSet.java269
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/TarScanner.java87
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/TimeComparison.java122
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/XMLCatalog.java1128
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/ZipFileSet.java117
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/ZipScanner.java99
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/conditions/antlib.xml93
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/defaults.properties101
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/mappers/CutDirsMapper.java76
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/mappers/FilterMapper.java87
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/optional/AbstractScriptComponent.java158
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/optional/ScriptCondition.java68
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/optional/ScriptFilter.java183
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/optional/ScriptMapper.java91
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/optional/ScriptSelector.java223
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/optional/depend/ClassfileSet.java183
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/optional/depend/DependScanner.java225
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/optional/image/Arc.java123
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/optional/image/BasicShape.java55
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/optional/image/ColorMapper.java102
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/optional/image/Draw.java102
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/optional/image/DrawOperation.java40
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/optional/image/Ellipse.java87
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/optional/image/ImageOperation.java72
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/optional/image/Rectangle.java119
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/optional/image/Rotate.java118
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/optional/image/Scale.java181
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/optional/image/Text.java128
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/optional/image/TransformOperation.java38
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resolver/ApacheCatalog.java121
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resolver/ApacheCatalogResolver.java174
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resolver/package.html35
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/AbstractClasspathResource.java265
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/AbstractResourceCollectionWrapper.java209
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/AllButFirst.java60
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/AllButLast.java53
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/Appendable.java35
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/ArchiveResource.java293
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/Archives.java194
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/BCFileSet.java73
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/BZip2Resource.java85
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/BaseResourceCollectionContainer.java268
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/BaseResourceCollectionWrapper.java56
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/CompressedResource.java60
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/ContentTransformingResource.java177
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/Difference.java63
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/FailFast.java135
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/FileProvider.java36
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/FileResource.java392
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/FileResourceIterator.java149
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/Files.java503
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/First.java48
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/GZipResource.java75
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/ImmutableResourceException.java46
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/Intersect.java64
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/JavaConstantResource.java70
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/JavaResource.java141
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/Last.java73
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/LazyResourceCollectionWrapper.java176
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/LogOutputResource.java68
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/MappedResource.java116
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/MappedResourceCollection.java267
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/MultiRootFileSet.java237
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/PropertyResource.java206
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/ResourceDecorator.java270
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/ResourceList.java239
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/Resources.java274
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/Restrict.java156
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/SizeLimitCollection.java71
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/Sort.java98
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/StringResource.java261
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/TarResource.java198
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/Tokens.java137
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/Touchable.java32
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/URLProvider.java35
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/URLResource.java454
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/Union.java156
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/ZipResource.java226
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/comparators/Content.java70
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/comparators/Date.java45
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/comparators/DelegatedResourceComparator.java125
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/comparators/Exists.java43
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/comparators/FileSystem.java60
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/comparators/Name.java38
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/comparators/ResourceComparator.java81
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/comparators/Reverse.java91
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/comparators/Size.java39
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/comparators/Type.java44
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/selectors/And.java58
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/selectors/Compare.java149
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/selectors/Date.java162
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/selectors/Exists.java37
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/selectors/InstanceOf.java130
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/selectors/Majority.java84
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/selectors/Name.java151
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/selectors/None.java59
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/selectors/Not.java66
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/selectors/Or.java58
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/selectors/ResourceSelector.java35
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/selectors/ResourceSelectorContainer.java128
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/selectors/Size.java73
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/selectors/Type.java110
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/AbstractSelectorContainer.java353
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/AndSelector.java74
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/BaseExtendSelector.java87
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/BaseSelector.java113
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/BaseSelectorContainer.java343
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/ContainsRegexpSelector.java219
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/ContainsSelector.java221
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/DateSelector.java260
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/DependSelector.java78
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/DepthSelector.java185
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/DifferentSelector.java114
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/ExtendFileSelector.java39
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/ExtendSelector.java201
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/FileSelector.java48
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/FilenameSelector.java195
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/MajoritySelector.java103
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/MappingSelector.java165
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/NoneSelector.java75
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/NotSelector.java73
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/OrSelector.java75
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/PresentSelector.java198
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/ReadableSelector.java49
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/SelectSelector.java231
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/SelectorContainer.java187
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/SelectorScanner.java49
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/SelectorUtils.java695
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/SignedSelector.java59
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/SizeSelector.java279
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/TokenizedPath.java222
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/TokenizedPattern.java177
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/TypeSelector.java135
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/WritableSelector.java46
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/modifiedselector/Algorithm.java48
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/modifiedselector/Cache.java72
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/modifiedselector/ChecksumAlgorithm.java151
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/modifiedselector/DigestAlgorithm.java208
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/modifiedselector/EqualComparator.java58
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/modifiedselector/HashvalueAlgorithm.java80
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/modifiedselector/ModifiedSelector.java971
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/modifiedselector/PropertiesfileCache.java236
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/spi/Provider.java63
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/spi/Service.java116
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/Base64Converter.java124
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/ChainedMapper.java60
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/ClasspathUtils.java463
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/CollectionUtils.java278
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/CompositeMapper.java50
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/ConcatFileInputStream.java136
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/ConcatResourceInputStream.java147
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/ContainerMapper.java119
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/DOMElementWriter.java640
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/DOMUtils.java163
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/DateUtils.java301
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/DeweyDecimal.java237
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/FileNameMapper.java60
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/FileTokenizer.java48
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/FileUtils.java1722
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/FirstMatchMapper.java45
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/FlatFileNameMapper.java54
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/GlobPatternMapper.java203
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/IdentityMapper.java52
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/IdentityStack.java130
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/JAXPUtils.java260
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/JavaEnvUtils.java573
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/KeepAliveInputStream.java66
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/KeepAliveOutputStream.java83
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/LayoutPreservingProperties.java775
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/LazyFileOutputStream.java162
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/LazyHashtable.java120
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/LeadPipeInputStream.java161
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/LineOrientedOutputStream.java158
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/LineOrientedOutputStreamRedirector.java68
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/LineTokenizer.java115
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/LinkedHashtable.java132
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/LoaderUtils.java140
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/MergingMapper.java67
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/OutputStreamFunneler.java176
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/PackageNameMapper.java49
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/ProcessUtil.java65
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/PropertyOutputStream.java69
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/ProxySetup.java115
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/ReaderInputStream.java205
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/ReflectUtil.java212
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/ReflectWrapper.java99
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/RegexpPatternMapper.java159
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/ResourceUtils.java860
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/RetryHandler.java74
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/Retryable.java38
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/ScriptFixBSFPath.java147
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/ScriptRunner.java27
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/ScriptRunnerBase.java360
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/ScriptRunnerCreator.java133
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/ScriptRunnerHelper.java206
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/SourceFileScanner.java173
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/SplitClassLoader.java73
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/StringTokenizer.java154
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/StringUtils.java273
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/SymbolicLinkUtils.java296
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/TaskLogger.java79
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/TeeOutputStream.java95
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/TimeoutObserver.java37
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/Tokenizer.java44
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/UUEncoder.java148
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/UnPackageNameMapper.java48
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/UnicodeUtil.java46
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/VectorSet.java242
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/Watchdog.java128
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/WeakishReference.java91
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/WorkerAnt.java172
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/XMLFragment.java155
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/XmlConstants.java65
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/depend/AbstractAnalyzer.java286
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/depend/DependencyAnalyzer.java130
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/depend/bcel/AncestorAnalyzer.java144
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/depend/bcel/DependencyVisitor.java192
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/depend/bcel/FullAnalyzer.java136
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/facade/FacadeTaskHelper.java165
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/facade/ImplementationSpecificArgument.java61
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/java15/ProxyDiagnostics.java108
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/optional/JavaxScriptRunner.java163
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/optional/NoExitSecurityManager.java51
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/optional/ScriptRunner.java177
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/optional/WeakishReference12.java45
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/regexp/JakartaOroMatcher.java170
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/regexp/JakartaOroRegexp.java98
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/regexp/JakartaRegexpMatcher.java161
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/regexp/JakartaRegexpRegexp.java90
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/regexp/Jdk14RegexpMatcher.java170
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/regexp/Jdk14RegexpRegexp.java105
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/regexp/Regexp.java50
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/regexp/RegexpFactory.java85
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/regexp/RegexpMatcher.java110
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/regexp/RegexpMatcherFactory.java114
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/regexp/RegexpUtil.java109
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/version.txt2
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/bzip2/BZip2Constants.java109
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/bzip2/BlockSort.java1081
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/bzip2/CBZip2InputStream.java1062
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/bzip2/CBZip2OutputStream.java1580
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/bzip2/CRC.java141
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/mail/ErrorInQuitException.java43
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/mail/MailMessage.java526
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/mail/SmtpResponseReader.java106
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/tar/TarArchiveSparseEntry.java63
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/tar/TarBuffer.java463
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/tar/TarConstants.java293
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/tar/TarEntry.java1149
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/tar/TarInputStream.java660
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/tar/TarOutputStream.java657
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/tar/TarUtils.java564
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/AbstractUnicodeExtraField.java183
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/AsiExtraField.java352
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/CentralDirectoryParsingZipExtraField.java40
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/ExtraFieldUtils.java314
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/FallbackZipEncoding.java94
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/GeneralPurposeBit.java194
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/JarMarker.java108
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/NioZipEncoding.java122
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/Simple8BitZipEncoding.java274
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/UnicodeCommentExtraField.java70
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/UnicodePathExtraField.java67
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/UnixStat.java76
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/UnparseableExtraFieldData.java115
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/UnrecognizedExtraField.java154
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/UnsupportedZipFeatureException.java89
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/Zip64ExtendedInformationExtraField.java322
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/Zip64Mode.java47
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/Zip64RequiredException.java49
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/ZipConstants.java59
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/ZipEightByteInteger.java229
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/ZipEncoding.java84
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/ZipEncodingHelper.java252
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/ZipEntry.java786
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/ZipExtraField.java85
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/ZipFile.java1048
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/ZipLong.java201
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/ZipOutputStream.java1674
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/ZipShort.java166
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/ZipUtil.java252
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/resources/org/apache/tools/ant/taskdefs/javadoc-frame-injections-fix.txt37
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/resources/org/apache/tools/ant/types/resources/comparators/antlib.xml33
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/resources/org/apache/tools/ant/types/resources/selectors/antlib.xml53
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/script/ant336
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/script/ant.bat218
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/script/ant.cmd93
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/script/antRun24
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/script/antRun.bat50
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/script/antRun.pl63
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/script/antenv.cmd98
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/script/complete-ant-cmd.pl115
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/script/envset.cmd131
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/script/lcp.bat31
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/script/runant.pl150
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/script/runant.py105
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/script/runrc.cmd60
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/antunit-base.xml60
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/bugfixes/README.txt2
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/bugfixes/br50866/br50866-test.xml13
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/bugfixes/br50866/common.xml8
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/bugfixes/br50866/middle.xml7
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/bugfixes/bugzilla-43324-stackoverflow-test.xml68
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/ant-attribute-test.xml74
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/bindtargets-test.xml39
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/classloader-test.xml88
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/createtask-test.xml50
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/dirscanner-symlinks-test.xml200
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/extension-point-test.xml210
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/extension/include-test.xml34
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/extension/module1.xml25
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/location/location.xml93
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/location/src/task/EchoLocation.java26
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/magic-names-test.xml51
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/nested-elements-test.xml125
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/nested-text-test.xml42
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/projecthelpers-test.xml86
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/projecthelpers/build-cross-extension-ref.xml26
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/projecthelpers/build-cross-extension-ref.xmlref14
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/projecthelpers/build-cross-extension.xml36
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/projecthelpers/build-cross-targets-ref.xml22
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/projecthelpers/build-cross-targets-ref.xmlref14
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/projecthelpers/build-cross-targets.xml27
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/projecthelpers/build-many-import-common.xml23
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/projecthelpers/build-many-import-commonref.xml23
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/projecthelpers/build-many-import-ref.xml24
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/projecthelpers/build-many-import-ref.xmlref14
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/projecthelpers/build-many-import.xml32
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/projecthelpers/build-many-import2-ref.xml25
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/projecthelpers/build-many-import2-ref.xmlref14
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/ref-propertyhelper-test.xml104
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/ref-psyntax-hint-test.xml28
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/target-test-helper.xml57
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/target-test.xml82
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/uuencode/src/task/BaseTask.java78
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/uuencode/src/task/UUDecodeTask.java31
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/uuencode/src/task/UUEncodeTask.java30
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/uuencode/uuencode-test.xml45
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/filters/expandproperties-test.xml92
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/filters/expected/sort.sortComparator.test10
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/filters/expected/sort.sortDefault.test10
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/filters/expected/sort.sortReverse.test10
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/filters/expected/sortuniq.txt4
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/filters/expected/uniq.txt5
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/filters/expected/unique-columns.txt1
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/filters/input/sort.sortDefault.test10
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/filters/input/uniq.txt6
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/filters/input/unique-columns.txt1
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/filters/replacetokens-test.xml68
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/filters/sort-test.xml126
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/filters/striplinecomments-test.xml85
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/filters/suffix-test.xml42
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/filters/uniq-test.xml81
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/junit-frames.xsl889
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/junit-noframes.xsl485
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/propertyhelpers.xml88
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/ant-test.xml55
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/antcall-test.xml63
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/apt-test.xml158
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/apt/AptExample.java25
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/apt/Distributed.java39
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/apt/DistributedAnnotationFactory.java50
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/apt/DistributedAnnotationProcessor.java65
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/augment-test.xml74
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/broken_cd.zipbin0 -> 326 bytes
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/bunzip2-test.xml28
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/bzip2/expected1
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/bzip2/multiple.bz2bin0 -> 74 bytes
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/checksum-test.xml83
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/commandlauncher/commandlauncher-test.xml87
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/concat-test.xml202
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/condition/antversion-test.xml70
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/condition/equals-test.xml80
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/condition/filesmatch-test.xml57
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/condition/hasfreespace-test.xml57
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/condition/hasmethod-text.xml63
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/condition/islastmodified-test.xml118
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/condition/resourcecontains-test.xml139
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/condition/resourceexists-test.xml47
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/copy-test.xml471
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/cvs.xml169
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/checkoutlist13
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/checkoutlist,v37
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/commitinfo26
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/commitinfo,v50
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/config97
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/config,v121
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/cvswrappers19
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/cvswrappers,v43
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/history65
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/loginfo36
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/loginfo,v60
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/modules26
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/modules,v50
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/notify19
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/notify,v43
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/postadmin20
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/postadmin,v44
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/postproxy22
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/postproxy,v46
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/posttag37
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/posttag,v61
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/postwatch20
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/postwatch,v44
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/preproxy24
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/preproxy,v48
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/rcsinfo13
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/rcsinfo,v37
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/taginfo46
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/taginfo,v70
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/val-tags2
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/verifymsg31
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/verifymsg,v55
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/ant module 2/test.txt,v41
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/antmodule1/foo.txt,v108
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/antmodule3/yet another test.txt,v60
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/defaultexcludes-test.xml52
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/delete-and-symlinks-test.xml84
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/delete-test.xml141
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/dependset-test.xml196
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/dirname-test.xml59
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/ear-test.xml31
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/echo-test.xml138
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/echoxml-test.xml87
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/exec/apply-test.xml792
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/exec/exec-test.xml710
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/exec/expected/utf-81
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/exec/input/iso8859-11
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/exec/parrot.sh19
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/fail-test.xml59
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/get-test.xml125
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/gzip-test.xml46
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/hostinfo-test.xml64
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/import-test.xml55
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/import-url-test.xml101
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/importtests/a.xml23
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/importtests/b.xml23
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/importtests/nested.xml21
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/importtests/override.xml25
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/importtests/w.xml22
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/importtests/x.xml22
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/importtests/y.xml22
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/importtests/z.xml21
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/include-test.xml58
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/jar-spi-test.xml149
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/jar-test.xml252
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/java-test.xml75
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/javac-dir/bad-src/Bad.java22
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/javac-dir/good-src/Simple.java20
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/javac-test.xml316
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/javadoc-test.xml157
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/length-test.xml240
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/loadproperties-test.xml192
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/loadresource-test.xml41
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/local-test.xml96
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/macrodef-test.xml60
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/manifest-test.xml180
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/manifestclasspath-test.xml30
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/move-test.xml234
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/optional/depend/depend-test.xml131
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/optional/funtest-test.xml128
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/optional/javah-test.xml65
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/optional/junit/junit-formatter-test.xml93
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/optional/junit/junit-outputtoformatters-test.xml137
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/optional/junit/junit-test.xml372
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/optional/junit/src/ExampleTest.java23
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/optional/junit/xmlformatter-test.xml126
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/optional/native2ascii-test.xml68
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/optional/propertyfile-test.xml44
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/optional/propertyfilelayout-test.xml289
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/optional/replaceregexp-test.xml32
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/optional/script/scriptdef-test.xml131
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/optional/unix/symlink-test.xml109
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/optional/windows/attrib-test.xml46
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/parallel-test.xml37
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/pathconvert-test.xml31
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/property-test.xml171
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/propertyfile-test.xml44
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/propertyhelper-test.xml151
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/replace-test.xml103
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/retry-test.xml45
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/rmic-test.xml105
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/secure-input.xml32
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/signjar-test.xml272
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/subant-helper/echo.xml20
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/subant-test.xml111
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/sync-test.xml175
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/tar-test.xml118
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/taskdef-antlib-test.xml64
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/taskdef-test.xml99
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/tempfile-test.xml30
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/touch-test.xml35
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/truncate/truncate-test.xml145
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/unzip-test.xml70
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/uptodate-test.xml86
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/utf-16.expectedbin0 -> 26 bytes
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/utf-16.expected.windowsbin0 -> 32 bytes
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/war-test.xml194
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/web.xml21
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/whichresource-test.xml51
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/xmlproperty-test.xml144
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/xmlproperty.inline-expansion.xml33
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/xmlproperty.multi.xml21
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/xslt-test.xml260
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/xslt/printParams-invalid.xsl36
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/zip-test.xml185
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/zip/Bugzilla-42940.zipbin0 -> 10930 bytes
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/build-embedded-ref.xml20
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/conditions/isreference-test.xml40
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/conditions/matches-test.xml114
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/cutdirs-test.xml56
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/defer-reference-test.xml69
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/fileset-test.xml67
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/filterset-test.xml96
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/firstmatch-test.xml41
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/javaresource-test.xml62
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/mapper-ref.xml55
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/mappers/glob-test.xml80
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/mappers/packagemapper-test.xml50
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/modified-selector-test.xml37
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/path-test.xml51
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/patternset-invert-test.xml66
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/patternset-test.xml78
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/propertyset-test.xml125
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/resources/archives-test.xml136
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/resources/comparators/test.xml299
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/resources/concat-resource-test.xml160
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/resources/fileresource-test.xml57
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/resources/files-test.xml52
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/resources/first-last-test.xml280
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/resources/javaresource-test.xml62
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/resources/latepath-test.xml34
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/resources/multirootfileset-test.xml166
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/resources/resourcelist-test.xml104
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/resources/resources-test.xml32
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/resources/selectors/name-test.xml90
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/resources/selectors/readwrite-test.xml106
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/resources/selectors/test-componentdef.xml458
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/resources/selectors/test.xml483
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/resources/test.xml460
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/resources/tokens-test.xml128
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/resources/utf-16.inbin0 -> 26 bytes
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/selectors/depend-test.xml45
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/selectors/different-test.xml46
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/selectors/filename-test.xml69
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/selectors/modified-test.xml76
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/selectors/present-test.xml45
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/selectors/readwrite-test.xml99
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/selectors/select-test.xml88
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/tarfileset-test.xml48
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/zipfileset-test.xml83
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/AntAssert.java72
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/AntClassLoaderDelegationTest.java124
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/AntClassLoaderPerformance.java56
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/AntClassLoaderTest.java210
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/BuildFileRule.java318
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/BuildFileTest.java592
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/CaseTest.java64
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/DefaultLoggerTest.java77
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/DirectoryScannerTest.java588
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/DispatchTaskTest.java46
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/DummyTaskAbstract.java32
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/DummyTaskInterface.java25
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/DummyTaskOk.java31
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/DummyTaskOkNonTask.java29
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/DummyTaskWithNonPublicExecute.java29
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/DummyTaskWithNonVoidExecute.java30
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/DummyTaskWithoutDefaultConstructor.java31
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/DummyTaskWithoutExecute.java29
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/DummyTaskWithoutPublicConstructor.java31
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/ExecutorTest.java171
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/ExtendedTaskdefTest.java68
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/FileUtilities.java88
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/ImmutableTest.java90
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/IncludeTest.java151
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/IntrospectionHelperTest.java726
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/LoaderRefTest.java52
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/LocationTest.java93
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/MockBuildListener.java64
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/PickOneTask.java31
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/ProjectComponentTest.java47
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/ProjectHelperRepositoryTest.java105
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/ProjectTest.java327
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/PropertyExpansionTest.java99
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/PropertyFileCLITest.java68
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/TaskContainerTest.java66
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/TopLevelTaskTest.java59
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/UnknownElementTest.java115
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/XmlLoggerTest.java37
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/filters/ConcatFilterTest.java143
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/filters/DynamicFilterTest.java80
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/filters/EscapeUnicodeTest.java50
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/filters/HeadTailTest.java137
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/filters/LineContainsTest.java57
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/filters/NoNewLineTest.java50
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/filters/ReplaceTokensTest.java81
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/filters/StripJavaCommentsTest.java51
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/filters/TokenFilterTest.java279
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/launch/LocatorTest.java180
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/loader/AntClassLoader5Test.java73
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/AbstractCvsTaskTest.java71
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/AntLikeTasksAtTopLevelTest.java70
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/AntStructureTest.java114
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/AntTest.java607
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/AntlibTest.java106
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/AvailableTest.java272
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/BUnzip2Test.java66
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/BZip2Test.java117
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/BasenameTest.java114
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/CVSPassTest.java119
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/CallTargetTest.java92
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/ChecksumTest.java109
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/ConcatTest.java315
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/ConditionTest.java379
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/CopyTest.java280
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/CopydirTest.java100
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/CopyfileTest.java100
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/DefaultExcludesTest.java170
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/DeleteTest.java112
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/DeltreeTest.java55
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/DemuxOutputTask.java75
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/DirnameTest.java92
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/DynamicTask.java46
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/DynamicTest.java46
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/EchoTest.java105
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/EchoXMLTest.java71
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/ExecTaskTest.java192
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/ExecuteJavaTest.java131
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/ExecuteWatchdogTest.java162
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/FailTest.java210
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/FilterTest.java147
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/FixCrLfTest.java262
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/GUnzipTest.java91
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/GetTest.java122
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/GzipTest.java113
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/ImportTest.java174
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/InitializeClassTest.java77
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/InputTest.java126
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/JarTest.java375
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/JavaTest.java475
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/JavacTest.java247
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/JavadocTest.java132
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/LoadFileTest.java170
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/MacroDefTest.java206
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/MakeUrlTest.java176
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/ManifestClassPathTest.java249
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/ManifestTest.java477
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/MkdirTest.java70
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/MoveTest.java168
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/MultiMapTest.java79
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/NiceTest.java83
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/ParallelTest.java195
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/PathConvertTest.java65
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/PreSetDefTest.java154
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/ProcessDestroyerTest.java68
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/PropertyTest.java141
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/ProtectedJarMethodsTest.java106
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/RecorderTest.java103
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/RenameTest.java88
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/ReplaceTest.java180
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/RmicAdvancedTest.java467
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/RmicTest.java104
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/SQLExecTest.java326
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/SignJarTest.java139
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/SleepTest.java120
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/StyleTest.java225
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/SubAntTest.java161
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/SyncTest.java148
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/TStampTest.java117
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/TarTest.java210
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/TaskdefTest.java128
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/TaskdefsTest.java31
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/TestProcess.java96
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/TimeProcess.java34
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/TouchTest.java211
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/TypeAdapterTest.java176
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/TypedefTest.java136
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/UntarTest.java111
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/UnzipTest.java250
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/UpToDateTest.java77
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/WarTest.java55
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/WhichResourceTest.java58
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/XmlPropertyTest.java376
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/XmlnsTest.java89
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/ZipExtraFieldTest.java109
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/ZipTest.java300
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/compilers/DefaultCompilerAdapterTest.java223
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/condition/AntVersionTest.java48
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/condition/ContainsTest.java42
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/condition/EqualsTest.java56
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/condition/HttpTest.java76
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/condition/IsFailureTest.java44
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/condition/IsFileSelectedTest.java74
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/condition/IsReachableTest.java116
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/condition/IsReferenceTest.java71
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/condition/IsSignedTest.java59
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/condition/ParserSupportsTest.java95
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/condition/TypeFoundTest.java91
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/condition/XorTest.java75
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/cvslib/ChangeLogParserTest.java67
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/cvslib/ChangeLogWriterTest.java96
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/dir1/B.java30
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/dir2/A.java40
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/email/EmailAddressTest.java112
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/email/EmailTaskTest.java63
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/email/MessageTest.java62
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/ANTLRTest.java216
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/AbstractXSLTLiaisonTest.java104
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/BeanShellScriptTest.java48
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/EchoPropertiesTest.java266
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/JavahTest.java60
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/JspcTest.java200
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/Native2AsciiTest.java57
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/PropertyFileTest.java235
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/PvcsTest.java79
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/ReplaceRegExpTest.java132
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/RhinoReferenceTest.java45
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/RhinoScriptTest.java67
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/RpmTest.java71
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/SchemaValidateTest.java128
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/TraXLiaisonTest.java129
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/XmlValidateCatalogTest.java71
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/XmlValidateTest.java193
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/XsltTest.java86
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/depend/DependTest.java213
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/i18n/TranslateTest.java87
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/image/ImageTest.java133
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/jdepend/JDependTest.java99
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/BatchTestTest.java121
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/DOMUtilTest.java53
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/JUnitClassLoaderTest.java37
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/JUnitReportTest.java211
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/JUnitTaskTest.java398
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/JUnitTestListenerTest.java111
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/JUnitTestRunnerTest.java217
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/JUnitVersionHelperTest.java102
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/NoVmCrash.java30
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/Printer.java42
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/Sleeper.java30
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/SuiteMethodTest.java42
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/TearDownOnVmCrashTest.java53
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/TestFormatter.java112
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/VmCrash.java31
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/XMLFormatterWithCDATAOnSystemOut.java83
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/XMLResultAggregatorTest.java93
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/net/FTPTest.java879
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/script/ScriptDefTest.java146
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/sos/SOSTest.java351
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/splash/SplashScreenTest.java50
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/ssh/ScpTest.java206
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/unix/SymlinkTest.java297
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/vss/MSVSSTest.java475
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/AbstractFileSetTest.java248
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/AddTypeTest.java223
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/AssertionsTest.java125
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/CommandlineJavaTest.java191
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/CommandlineTest.java180
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/DescriptionTest.java59
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/DirSetTest.java94
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/EnumeratedAttributeTest.java106
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/FileListTest.java163
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/FileSetTest.java36
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/FilterSetTest.java239
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/FlexIntegerTest.java74
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/MapperTest.java235
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/PathTest.java579
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/PatternSetTest.java206
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/PermissionsTest.java158
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/PolyTest.java79
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/RedirectorElementTest.java86
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/ResourceOutputTest.java160
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/TarFileSetTest.java119
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/XMLCatalogBuildFileTest.java98
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/XMLCatalogTest.java392
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/ZipFileSetTest.java118
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/mappers/GlobMapperTest.java49
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/mappers/MapperResult.java103
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/mappers/RegexpPatternMapperTest.java51
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/optional/ScriptMapperTest.java53
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/optional/ScriptSelectorTest.java83
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/optional/depend/ClassFileSetTest.java186
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/resources/FileResourceTest.java122
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/resources/JavaResourceTest.java62
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/resources/LazyResourceCollectionTest.java186
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/resources/MultiRootFileSetTest.java131
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/resources/ResourceListTest.java134
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/resources/TarResourceTest.java54
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/selectors/BaseSelectorRule.java125
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/selectors/BaseSelectorTest.java295
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/selectors/ContainsRegexpTest.java56
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/selectors/ContainsSelectorTest.java114
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/selectors/DateSelectorTest.java229
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/selectors/DependSelectorTest.java185
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/selectors/DepthSelectorTest.java147
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/selectors/FilenameSelectorTest.java115
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/selectors/MockAlgorithm.java37
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/selectors/MockCache.java68
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/selectors/MockComparator.java32
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/selectors/ModifiedSelectorTest.java1062
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/selectors/PresentSelectorTest.java137
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/selectors/README96
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/selectors/SignedSelectorTest.java54
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/selectors/SizeSelectorTest.java237
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/selectors/TokenizedPatternTest.java64
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/selectors/TypeSelectorTest.java81
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/Base64ConverterTest.java43
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/ClasspathUtilsTest.java67
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/CollectionUtilsTest.java102
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/DOMElementWriterTest.java305
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/DateUtilsTest.java106
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/DeweyDecimalTest.java70
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/FileUtilsTest.java625
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/GlobPatternMapperTest.java102
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/JAXPUtilsTest.java43
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/JavaEnvUtilsTest.java144
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/LayoutPreservingPropertiesTest.java316
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/LazyFileOutputStreamTest.java75
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/LineOrientedOutputStreamTest.java153
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/LinkedHashtableTest.java165
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/LoaderUtilsTest.java43
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/PackageNameMapperTest.java43
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/ReaderInputStreamTest.java142
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/ResourceUtilsTest.java63
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/StringUtilsTest.java170
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/SymlinkUtilsTest.java40
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/UnPackageNameMapperTest.java42
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/UnicodeUtilTest.java33
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/VectorSetTest.java295
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/XMLFragmentTest.java91
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/facade/FacadeTaskHelperTest.java64
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/facade/ImplementationSpecificArgumentTest.java59
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/regexp/JakartaOroMatcherTest.java35
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/regexp/JakartaOroRegexpTest.java35
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/regexp/JakartaRegexpMatcherTest.java63
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/regexp/JakartaRegexpRegexpTest.java62
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/regexp/Jdk14RegexpMatcherTest.java70
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/regexp/Jdk14RegexpRegexpTest.java71
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/regexp/RegexpMatcherTest.java204
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/regexp/RegexpTest.java63
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/bzip2/BlockSortTest.java171
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/bzip2/CBZip2StreamTest.java47
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/mail/MailMessageTest.java707
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/tar/TarEntryTest.java35
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/tar/TarOutputStreamTest.java35
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/tar/TarRoundTripTest.java74
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/zip/AsiExtraFieldTest.java163
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/zip/ExtraFieldUtilsTest.java210
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/zip/UTF8ZipFilesTest.java260
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/zip/ZipEncodingTest.java152
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/zip/ZipEntryTest.java228
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/zip/ZipLongTest.java94
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/zip/ZipOutputStreamTest.java73
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/zip/ZipShortTest.java92
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/example/junit/AbstractJUnit3TestMissed.java27
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/example/junit/AbstractJUnit3TestNotMissed.java31
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/example/junit/AbstractTestMissed.java29
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/example/junit/AbstractTestNotMissed.java32
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/example/junit/JUnit3NonTestMissed.java27
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/example/junit/JUnit3TestNotMissed.java28
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/example/junit/JUnit4Skippable.java74
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/example/junit/MultilineAsserts.java27
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/example/junit/NonTestMissed.java25
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/example/junit/Output.java37
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/example/junit/TestNotMissed.java29
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/example/junit/TestWithSuiteNotMissed.java32
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/example/junit/ThreadedOutput.java43
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/example/junit/Timeout.java32
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/example/junit/XmlParserTest.java58
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/example/tasks/TaskdefTestContainerTask.java25
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/example/tasks/TaskdefTestSimpleTask.java45
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/example/tasks/antlib.xml26
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/example/tasks/antlib2.xml26
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/example/types/TypedefTestType.java25
-rw-r--r--framework/src/maven/apache-maven-3.3.3/DEPENDENCIES111
-rw-r--r--framework/src/maven/apache-maven-3.3.3/LICENSE202
-rw-r--r--framework/src/maven/apache-maven-3.3.3/NOTICE5
-rw-r--r--framework/src/maven/apache-maven-3.3.3/README.md23
-rw-r--r--framework/src/maven/apache-maven-3.3.3/apache-maven/README.txt79
-rw-r--r--framework/src/maven/apache-maven-3.3.3/apache-maven/pom.xml216
-rw-r--r--framework/src/maven/apache-maven-3.3.3/apache-maven/src/bin/m2.conf8
-rwxr-xr-xframework/src/maven/apache-maven-3.3.3/apache-maven/src/bin/mvn232
-rw-r--r--framework/src/maven/apache-maven-3.3.3/apache-maven/src/bin/mvn.cmd176
-rwxr-xr-xframework/src/maven/apache-maven-3.3.3/apache-maven/src/bin/mvnDebug41
-rw-r--r--framework/src/maven/apache-maven-3.3.3/apache-maven/src/bin/mvnDebug.cmd31
-rwxr-xr-xframework/src/maven/apache-maven-3.3.3/apache-maven/src/bin/mvnyjp42
-rw-r--r--framework/src/maven/apache-maven-3.3.3/apache-maven/src/conf/logging/simplelogger.properties25
-rw-r--r--framework/src/maven/apache-maven-3.3.3/apache-maven/src/conf/settings.xml257
-rw-r--r--framework/src/maven/apache-maven-3.3.3/apache-maven/src/conf/toolchains.xml103
-rw-r--r--framework/src/maven/apache-maven-3.3.3/apache-maven/src/lib/ext/README.txt2
-rw-r--r--framework/src/maven/apache-maven-3.3.3/apache-maven/src/main/appended-resources/META-INF/LICENSE.vm49
-rw-r--r--framework/src/maven/apache-maven-3.3.3/apache-maven/src/main/assembly/bin.xml94
-rw-r--r--framework/src/maven/apache-maven-3.3.3/apache-maven/src/main/assembly/src.xml49
-rw-r--r--framework/src/maven/apache-maven-3.3.3/apache-maven/src/site/site.xml29
-rw-r--r--framework/src/maven/apache-maven-3.3.3/apache-maven/src/test/java/org/apache/maven/settings/GlobalSettingsTest.java59
-rw-r--r--framework/src/maven/apache-maven-3.3.3/build.xml307
-rw-r--r--framework/src/maven/apache-maven-3.3.3/deploySite.sh23
-rw-r--r--framework/src/maven/apache-maven-3.3.3/doap_Maven.rdf178
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-aether-provider/pom.xml130
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/ArtifactDescriptorReaderDelegate.java153
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/ArtifactDescriptorUtils.java81
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/DefaultArtifactDescriptorReader.java435
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/DefaultModelCache.java119
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/DefaultModelResolver.java229
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/DefaultVersionRangeResolver.java322
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/DefaultVersionResolver.java636
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/LocalSnapshotMetadata.java163
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/LocalSnapshotMetadataGenerator.java82
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/MavenAetherModule.java76
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/MavenMetadata.java150
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/MavenRepositorySystemUtils.java141
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/MavenSnapshotMetadata.java100
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/MavenWorkspaceReader.java32
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/RelocatedArtifact.java116
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/RemoteSnapshotMetadata.java152
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/RemoteSnapshotMetadataGenerator.java107
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/SnapshotMetadataGeneratorFactory.java52
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/VersionsMetadata.java133
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/VersionsMetadataGenerator.java108
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/VersionsMetadataGeneratorFactory.java52
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/package-info.java25
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/site/apt/index.apt33
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/site/site.xml36
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/test/java/org/apache/maven/repository/internal/AbstractRepositoryTestCase.java87
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/test/java/org/apache/maven/repository/internal/DefaultArtifactDescriptorReaderTest.java77
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/test/java/org/apache/maven/repository/internal/DefaultVersionResolverTest.java96
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/test/java/org/apache/maven/repository/internal/MavenRepositorySystemUtilsTest.java45
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/test/java/org/apache/maven/repository/internal/RepositorySystemTest.java220
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/test/java/org/apache/maven/repository/internal/util/ConsoleRepositoryListener.java132
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/test/java/org/apache/maven/repository/internal/util/ConsoleTransferListener.java186
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/test/resources/repo/org/apache/maven/its/dep-mng5324/07.20.3-SNAPSHOT/maven-metadata.xml49
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/test/resources/repo/org/apache/maven/its/dep-mng5459/0.4.0-SNAPSHOT/maven-metadata.xml47
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/test/resources/repo/ut/simple/artifact/1.0/artifact-1.0-classifier.zip0
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/test/resources/repo/ut/simple/artifact/1.0/artifact-1.0.jar0
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/test/resources/repo/ut/simple/artifact/1.0/artifact-1.0.pom48
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/test/resources/repo/ut/simple/artifact/1.0/artifact-1.0.zip0
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/test/resources/repo/ut/simple/artifact/maven-metadata.xml34
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/test/resources/repo/ut/simple/dependency/1.0/dependency-1.0-sources.jar0
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/test/resources/repo/ut/simple/dependency/1.0/dependency-1.0.jar0
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/test/resources/repo/ut/simple/dependency/1.0/dependency-1.0.pom31
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/test/resources/repo/ut/simple/dependency/maven-metadata.xml34
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/test/resources/repo/ut/simple/parent/1.0/parent-1.0.pom43
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/test/resources/repo/ut/simple/parent/maven-metadata.xml34
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-ant-tasks-2.1.1.jarbin0 -> 1314262 bytes
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-artifact/pom.xml58
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/Artifact.java161
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/ArtifactUtils.java215
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/DefaultArtifact.java597
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/InvalidArtifactRTException.java100
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/handler/ArtifactHandler.java42
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/metadata/ArtifactMetadata.java27
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/repository/ArtifactRepository.java135
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/repository/ArtifactRepositoryPolicy.java222
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/repository/Authentication.java126
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/repository/layout/ArtifactRepositoryLayout.java38
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/repository/layout/ArtifactRepositoryLayout2.java31
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/repository/metadata/RepositoryMetadataStoreException.java40
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/resolver/AbstractArtifactResolutionException.java347
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/resolver/ArtifactNotFoundException.java85
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/resolver/ArtifactResolutionException.java68
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/resolver/CyclicDependencyException.java45
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/resolver/MultipleArtifactsNotFoundException.java122
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/resolver/filter/ArtifactFilter.java30
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/versioning/ArtifactVersion.java42
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/versioning/ComparableVersion.java503
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/versioning/DefaultArtifactVersion.java228
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/versioning/InvalidVersionSpecificationException.java34
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/versioning/OverConstrainedVersionException.java49
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/versioning/Restriction.java195
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/versioning/VersionRange.java583
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/repository/Proxy.java197
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/repository/legacy/metadata/ArtifactMetadata.java83
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-artifact/src/site/apt/index.apt47
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-artifact/src/site/site.xml36
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-artifact/src/test/java/org/apache/maven/artifact/versioning/ComparableVersionTest.java231
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-artifact/src/test/java/org/apache/maven/artifact/versioning/DefaultArtifactVersionTest.java223
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-artifact/src/test/java/org/apache/maven/artifact/versioning/VersionRangeTest.java730
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-builder-support/pom.xml49
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-builder-support/src/main/java/org/apache/maven/building/DefaultProblem.java161
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-builder-support/src/main/java/org/apache/maven/building/DefaultProblemCollector.java64
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-builder-support/src/main/java/org/apache/maven/building/FileSource.java79
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-builder-support/src/main/java/org/apache/maven/building/Problem.java101
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-builder-support/src/main/java/org/apache/maven/building/ProblemCollector.java59
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-builder-support/src/main/java/org/apache/maven/building/ProblemCollectorFactory.java43
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-builder-support/src/main/java/org/apache/maven/building/Source.java49
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-builder-support/src/main/java/org/apache/maven/building/StringSource.java90
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-builder-support/src/main/java/org/apache/maven/building/UrlSource.java80
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-builder-support/src/site/site.xml36
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-builder-support/src/test/java/org/apache/maven/building/DefaultProblemCollectorTest.java76
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-builder-support/src/test/java/org/apache/maven/building/DefaultProblemTest.java136
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-builder-support/src/test/java/org/apache/maven/building/FileSourceTest.java93
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-builder-support/src/test/java/org/apache/maven/building/ProblemCollectorFactoryTest.java45
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-builder-support/src/test/java/org/apache/maven/building/StringSourceTest.java79
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-builder-support/src/test/java/org/apache/maven/building/UrlSourceTest.java87
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-builder-support/src/test/resources/source.txt1
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/pom.xml115
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/ArtifactScopeEnum.java133
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/ArtifactStatus.java124
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/UnknownRepositoryLayoutException.java54
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/deployer/ArtifactDeployer.java61
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/deployer/ArtifactDeploymentException.java43
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/deployer/DefaultArtifactDeployer.java161
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/installer/ArtifactInstallationException.java43
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/installer/ArtifactInstaller.java60
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/installer/DefaultArtifactInstaller.java135
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/manager/DefaultWagonManager.java182
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/manager/WagonConfigurationException.java38
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/manager/WagonManager.java56
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/repository/ArtifactRepositoryFactory.java55
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/repository/DefaultArtifactRepository.java267
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/repository/DefaultArtifactRepositoryFactory.java124
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/repository/layout/FlatRepositoryLayout.java92
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/repository/metadata/DefaultRepositoryMetadataManager.java558
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/repository/metadata/GroupRepositoryMetadata.java119
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/repository/metadata/MetadataBridge.java172
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/repository/metadata/MetadataUtils.java39
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/repository/metadata/RepositoryMetadataReadException.java40
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/repository/metadata/SnapshotArtifactRepositoryMetadata.java98
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/resolver/ArtifactCollector.java42
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/resolver/ArtifactResolver.java108
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/resolver/DebugResolutionListener.java167
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/resolver/DefaultArtifactCollector.java30
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/resolver/DefaultArtifactResolver.java643
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/resolver/ResolutionListenerForDepMgmt.java43
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/resolver/UnresolvedArtifacts.java66
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/resolver/WarningResolutionListener.java90
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/resolver/filter/InversionArtifactFilter.java65
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/resolver/filter/OrArtifactFilter.java93
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/resolver/filter/TypeArtifactFilter.java66
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/versioning/ManagedVersionMap.java56
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/execution/DefaultRuntimeInformation.java64
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/execution/RuntimeInformation.java34
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/profiles/DefaultMavenProfilesBuilder.java93
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/profiles/DefaultProfileManager.java248
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/profiles/MavenProfilesBuilder.java37
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/profiles/ProfileManager.java58
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/profiles/ProfilesConversionUtils.java151
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/profiles/activation/DetectedProfileActivator.java35
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/profiles/activation/FileProfileActivator.java109
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/profiles/activation/JdkPrefixProfileActivator.java97
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/profiles/activation/OperatingSystemProfileActivator.java161
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/profiles/activation/ProfileActivationException.java39
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/profiles/activation/ProfileActivator.java33
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/profiles/activation/SystemPropertyProfileActivator.java114
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/project/DefaultMavenProjectBuilder.java324
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/project/DefaultProjectBuilderConfiguration.java107
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/project/InvalidProjectModelException.java74
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/project/MavenProjectBuilder.java76
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/project/MissingRepositoryElementException.java38
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/project/ModelUtils.java367
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/project/ProjectBuilderConfiguration.java55
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/project/ProjectUtils.java118
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/project/inheritance/DefaultModelInheritanceAssembler.java752
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/project/inheritance/ModelInheritanceAssembler.java41
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/project/interpolation/AbstractStringBasedModelInterpolator.java407
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/project/interpolation/BuildTimestampValueSource.java63
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/project/interpolation/ModelInterpolationException.java72
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/project/interpolation/ModelInterpolator.java66
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/project/interpolation/PathTranslatingPostProcessor.java64
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/project/interpolation/RegexBasedModelInterpolator.java58
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/project/interpolation/StringSearchModelInterpolator.java410
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/project/path/DefaultPathTranslator.java261
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/project/validation/DefaultModelValidator.java76
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/project/validation/ModelValidationResult.java95
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/project/validation/ModelValidator.java37
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/reporting/MavenReportException.java39
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/DefaultMirrorSelector.java205
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/MavenArtifactMetadata.java119
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/MetadataGraph.java96
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/MetadataGraphNode.java101
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/MetadataResolutionRequest.java202
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/MetadataResolutionResult.java356
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/MirrorSelector.java44
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/UserLocalArtifactRepository.java74
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/VersionNotFoundException.java83
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/ChecksumFailedException.java42
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/DefaultUpdateCheckManager.java438
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/DefaultWagonManager.java823
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/LegacyRepositorySystem.java906
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/MavenArtifact.java96
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/TransferListenerAdapter.java187
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/UpdateCheckManager.java41
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/WagonConfigurationException.java63
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/WagonManager.java79
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/repository/ArtifactRepositoryFactory.java56
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/repository/DefaultArtifactRepositoryFactory.java144
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/resolver/DefaultLegacyArtifactCollector.java796
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/resolver/LegacyArtifactCollector.java62
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/resolver/conflict/ConflictResolver.java44
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/resolver/conflict/ConflictResolverFactory.java48
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/resolver/conflict/ConflictResolverNotFoundException.java47
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/resolver/conflict/DefaultConflictResolver.java36
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/resolver/conflict/DefaultConflictResolverFactory.java80
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/resolver/conflict/FarthestConflictResolver.java47
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/resolver/conflict/NearestConflictResolver.java48
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/resolver/conflict/NewestConflictResolver.java62
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/resolver/conflict/OldestConflictResolver.java62
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/resolver/transform/AbstractVersionTransformation.java135
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/resolver/transform/ArtifactTransformation.java86
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/resolver/transform/ArtifactTransformationManager.java82
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/resolver/transform/DefaultArtifactTransformationManager.java86
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/resolver/transform/LatestArtifactTransformation.java74
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/resolver/transform/ReleaseArtifactTransformation.java100
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/resolver/transform/SnapshotTransformation.java171
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/metadata/ArtifactMetadata.java353
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/metadata/ClasspathContainer.java144
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/metadata/ClasspathTransformation.java46
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/metadata/DefaultClasspathTransformation.java183
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/metadata/DefaultGraphConflictResolutionPolicy.java73
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/metadata/DefaultGraphConflictResolver.java249
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/metadata/GraphConflictResolutionException.java51
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/metadata/GraphConflictResolutionPolicy.java35
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/metadata/GraphConflictResolver.java48
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/metadata/MetadataGraph.java523
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/metadata/MetadataGraphEdge.java189
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/metadata/MetadataGraphTransformationException.java50
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/metadata/MetadataGraphVertex.java216
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/metadata/MetadataResolution.java71
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/metadata/MetadataResolutionException.java49
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/metadata/MetadataResolutionRequest.java79
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/metadata/MetadataResolutionRequestTypeEnum.java45
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/metadata/MetadataResolutionResult.java172
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/metadata/MetadataRetrievalException.java59
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/metadata/MetadataSource.java39
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/metadata/MetadataTreeNode.java148
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/usability/plugin/ExpressionDocumentationException.java37
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/usability/plugin/ExpressionDocumenter.java175
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/mdo/paramdoc.mdo154
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/mdo/profiles.mdo398
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/resources/META-INF/maven/plugin-expressions/project.paramdoc.xml172
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/resources/META-INF/maven/plugin-expressions/rootless.paramdoc.xml48
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/resources/META-INF/maven/plugin-expressions/settings.paramdoc.xml53
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/resources/META-INF/maven/plugin.xml218
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/site/site.xml36
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/artifact/AbstractArtifactComponentTestCase.java371
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/artifact/ArtifactUtilsTest.java79
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/artifact/DefaultArtifactTest.java140
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/artifact/deployer/ArtifactDeployerTest.java67
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/artifact/deployer/SimpleArtifactMetadataSource.java66
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/artifact/factory/DefaultArtifactFactoryTest.java49
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/artifact/handler/ArtifactHandlerMock.java100
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/artifact/installer/ArtifactInstallerTest.java61
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/artifact/metadata/TestMetadataSource.java102
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/artifact/repository/MavenArtifactRepositoryTest.java59
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/artifact/resolver/ArtifactResolutionExceptionTest.java64
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/artifact/resolver/ArtifactResolverTest.java283
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/artifact/resolver/DefaultArtifactResolverTest.java111
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/artifact/resolver/TestFileWagon.java94
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/artifact/resolver/TestTransferListener.java43
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/artifact/resolver/filter/AndArtifactFilterTest.java62
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/artifact/resolver/filter/FilterHashEqualsTest.java50
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/artifact/resolver/filter/OrArtifactFilterTest.java62
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/artifact/resolver/filter/ScopeArtifactFilterTest.java96
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/artifact/testutils/TestFileManager.java224
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/artifact/transform/TransformationManagerTest.java46
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/profiles/manager/DefaultProfileManagerTest.java232
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/AbstractMavenProjectTestCase.java185
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/ClasspathArtifactResolver.java89
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/EmptyLifecycleExecutor.java110
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/EmptyLifecyclePluginAnalyzer.java78
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/LegacyLocalRepositoryManager.java192
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/ModelUtilsTest.java616
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/ProjectClasspathTest.java149
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/TestArtifactResolver.java30
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/TestMavenRepositorySystem.java30
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/TestProjectBuilder.java68
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/inheritance/AbstractProjectInheritanceTestCase.java57
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/inheritance/t00/ProjectInheritanceTest.java93
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/inheritance/t01/ProjectInheritanceTest.java92
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/inheritance/t02/ProjectInheritanceTest.java169
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/inheritance/t03/ProjectInheritanceTest.java68
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/inheritance/t04/ProjectInheritanceTest.java86
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/inheritance/t05/ProjectInheritanceTest.java79
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/inheritance/t06/ProjectInheritanceTest.java80
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/inheritance/t07/ProjectInheritanceTest.java82
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/inheritance/t08/ProjectInheritanceTest.java81
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/inheritance/t09/ProjectInheritanceTest.java119
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/inheritance/t10/ProjectInheritanceTest.java94
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/inheritance/t11/ProjectInheritanceTest.java64
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/inheritance/t12/ProjectInheritanceTest.java65
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/inheritance/t12scm/ProjectInheritanceTest.java125
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/path/DefaultPathTranslatorTest.java58
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/DefaultMirrorSelectorTest.java38
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/LegacyRepositoryLayout.java89
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/LegacyRepositorySystemTest.java206
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/MirrorProcessorTest.java259
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/legacy/DefaultUpdateCheckManagerTest.java240
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/legacy/DefaultWagonManagerTest.java422
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/legacy/LegacyRepositorySystemTest.java88
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/legacy/PerLookupWagon.java38
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/legacy/StringWagon.java107
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/legacy/WagonA.java39
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/legacy/WagonB.java39
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/legacy/WagonC.java39
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/legacy/WagonMock.java50
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/legacy/resolver/DefaultArtifactCollectorTest.java984
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/legacy/resolver/conflict/AbstractConflictResolverTest.java143
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/legacy/resolver/conflict/FarthestConflictResolverTest.java107
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/legacy/resolver/conflict/NearestConflictResolverTest.java107
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/legacy/resolver/conflict/NewestConflictResolverTest.java107
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/legacy/resolver/conflict/OldestConflictResolverTest.java107
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/metadata/DefaultClasspathTransformationTest.java120
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/metadata/DefaultGraphConflictResolutionPolicyTest.java59
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/metadata/DefaultGraphConflictResolverTest.java153
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/metadata/TestMetadataSource.java99
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/remote-repo/org/apache/maven/its/a/0.1/a-0.1.jarbin0 -> 1898 bytes
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/remote-repo/org/apache/maven/its/a/0.1/a-0.1.pom41
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/remote-repo/org/apache/maven/its/a/maven-metadata.xml12
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/remote-repo/org/apache/maven/its/b/0.1/b-0.1.jarbin0 -> 1936 bytes
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/remote-repo/org/apache/maven/its/b/0.1/b-0.1.pom49
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/remote-repo/org/apache/maven/its/b/maven-metadata.xml12
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/repository-system/maven-core-2.1.0.jar0
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/artifact-install/artifact-1.0.jar1
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t00/maven/poms/p0-1.0.pom11
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t00/maven/poms/p1-1.0.pom16
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t00/maven/poms/p2-1.0.pom18
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t00/maven/poms/p3-1.0.pom14
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t00/maven/poms/p4-1.0.pom13
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t01/maven.t01/poms/p0-1.0.pom11
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t01/maven.t01/poms/p1-1.0.pom16
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t01/maven.t01/poms/p2-1.0.pom16
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t01/maven.t01/poms/p3-1.0.pom16
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t01/maven.t01/poms/p4-1.0.pom16
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t02/p0/p1/p2/p3/p4/p5/pom.xml32
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t02/p0/p1/p2/p3/p4/pom.xml32
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t02/p0/p1/p2/p3/pom.xml33
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t02/p0/p1/p2/pom.xml37
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t02/p0/p1/pom.xml51
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t02/p0/pom.xml30
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t03/p0/p1/pom.xml45
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t03/p0/pom.xml30
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t04/maven-test/jars/t04-a-1.0.jar1
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t04/maven-test/jars/t04-b-1.0.jar1
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t04/maven-test/jars/t04-b-2.0.jar1
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t04/maven-test/jars/t04-c-1.0.jar1
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t04/maven-test/jars/t04-c-2.0.jar1
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t04/maven-test/poms/t04-a-1.0.pom21
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t04/maven-test/poms/t04-b-1.0.pom7
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t04/maven-test/poms/t04-b-2.0.pom7
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t04/maven-test/poms/t04-c-1.0.pom7
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t04/maven-test/poms/t04-c-2.0.pom7
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t04/p0/p1/pom.xml41
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t04/p0/pom.xml37
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t05/maven-test/jars/t05-a-1.0.jar1
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t05/maven-test/jars/t05-a-2.0.jar1
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t05/maven-test/jars/t05-b-1.0.jar1
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t05/maven-test/jars/t05-b-1.1.jar1
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t05/maven-test/jars/t05-b-2.0.jar1
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t05/maven-test/jars/t05-c-1.0.jar1
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t05/maven-test/jars/t05-d-1.0.jar1
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t05/maven-test/jars/t05-d-1.1.jar1
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t05/maven-test/jars/t05-d-1.2.jar1
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t05/maven-test/poms/t05-a-1.0.pom23
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t05/maven-test/poms/t05-a-2.0.pom23
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t05/maven-test/poms/t05-b-1.0.pom24
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t05/maven-test/poms/t05-b-1.1.pom24
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t05/maven-test/poms/t05-b-2.0.pom24
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t05/maven-test/poms/t05-c-1.0.pom17
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t05/maven-test/poms/t05-d-1.0.pom7
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t05/maven-test/poms/t05-d-1.1.pom7
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t05/maven-test/poms/t05-d-1.2.pom7
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t05/p0/p1/pom.xml54
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t05/p0/pom.xml36
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t06/maven-test/jars/t06-a-1.0.jar1
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t06/maven-test/jars/t06-b-1.0.jar1
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t06/maven-test/jars/t06-b-1.1.jar1
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t06/maven-test/jars/t06-c-1.0.jar1
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t06/maven-test/jars/t06-d-1.0.jar1
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t06/maven-test/jars/t06-d-1.1.jar1
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t06/maven-test/jars/t06-d-1.2.jar1
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t06/maven-test/poms/t06-a-1.0.pom23
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t06/maven-test/poms/t06-b-1.0.pom24
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t06/maven-test/poms/t06-b-1.1.pom24
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t06/maven-test/poms/t06-c-1.0.pom17
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t06/maven-test/poms/t06-d-1.0.pom7
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t06/maven-test/poms/t06-d-1.1.pom7
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t06/maven-test/poms/t06-d-1.2.pom7
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t06/p0/p1/pom.xml54
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t06/p0/pom.xml37
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t07/maven-test/jars/t07-a-1.0.jar1
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t07/maven-test/jars/t07-b-1.0.jar1
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t07/maven-test/jars/t07-b-1.1.jar1
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t07/maven-test/jars/t07-c-1.0.jar1
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t07/maven-test/jars/t07-d-1.0.jar1
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t07/maven-test/jars/t07-d-1.1.jar1
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t07/maven-test/jars/t07-d-1.2.jar1
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t07/maven-test/poms/t07-a-1.0.pom23
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t07/maven-test/poms/t07-b-1.0.pom24
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t07/maven-test/poms/t07-b-1.1.pom24
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t07/maven-test/poms/t07-c-1.0.pom17
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t07/maven-test/poms/t07-d-1.0.pom7
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t07/maven-test/poms/t07-d-1.1.pom7
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t07/maven-test/poms/t07-d-1.2.pom7
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t07/p0/p1/pom.xml54
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t07/p0/pom.xml37
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t08/maven-test/jars/t08-a-1.0.jar1
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t08/maven-test/jars/t08-b-1.0.jar1
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t08/maven-test/jars/t08-b-1.1.jar1
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t08/maven-test/jars/t08-c-1.0.jar1
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t08/maven-test/jars/t08-d-1.0.jar1
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t08/maven-test/jars/t08-d-1.1.jar1
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t08/maven-test/jars/t08-d-1.2.jar1
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t08/maven-test/poms/t08-a-1.0.pom23
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t08/maven-test/poms/t08-b-1.0.pom24
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t08/maven-test/poms/t08-b-1.1.pom24
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t08/maven-test/poms/t08-c-1.0.pom17
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t08/maven-test/poms/t08-d-1.0.pom7
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t08/maven-test/poms/t08-d-1.1.pom7
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t08/maven-test/poms/t08-d-1.2.pom7
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t08/p0/p1/pom.xml59
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t08/p0/pom.xml37
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t09/maven-test/jars/t09-a-1.0.jar1
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t09/maven-test/jars/t09-b-1.0.jar1
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t09/maven-test/jars/t09-c-1.0.jar1
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t09/maven-test/jars/t09-d-1.0.jar1
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t09/maven-test/poms/t09-a-1.0.pom24
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t09/maven-test/poms/t09-b-1.0.pom17
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t09/maven-test/poms/t09-c-1.0.pom7
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t09/maven-test/poms/t09-d-1.0.pom17
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t09/p0/p1/pom.xml36
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t09/p0/p2/pom.xml42
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t09/p0/pom.xml38
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t10/maven-test/jars/t10-a-1.0.jar1
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t10/maven-test/jars/t10-b-1.0.jar1
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t10/maven-test/jars/t10-c-1.0.jar1
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t10/maven-test/poms/t10-a-1.0.pom24
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t10/maven-test/poms/t10-b-1.0.pom7
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t10/maven-test/poms/t10-c-1.0.pom7
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t10/p0/p1/pom.xml42
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t10/p0/pom.xml41
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t11/p0/p1/pom.xml16
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t11/p0/pom.xml27
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t12/p0/p1/pom.xml29
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t12/p0/pom.xml30
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t12scm/maven/p0/1.0/p0-1.0.pom18
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t12scm/maven/p1/1.0/p1-1.0.pom11
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t12scm/p0/modules/p1/pom.xml11
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t12scm/p0/pom.xml18
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/local-repo/marker.txt1
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/local-repo/maven-test/jars/maven-test-a-1.0.jar1
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/local-repo/maven-test/jars/maven-test-b-1.0.jar1
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/local-repo/maven-test/jars/maven-test-c-1.0.jar1
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/local-repo/maven-test/jars/maven-test-d-1.0.jar1
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/local-repo/maven-test/poms/maven-test-a-1.0.pom23
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/local-repo/maven-test/poms/maven-test-b-1.0.pom23
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/local-repo/maven-test/poms/maven-test-c-1.0.pom16
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/local-repo/maven-test/poms/maven-test-d-1.1.pom7
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/local-repo/maven-test/poms/maven-test-d-1.2.pom7
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/local-repo/snapshot-test/jars/maven-snapshot-a-1.0-SNAPSHOT.jar1
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/local-repo/snapshot-test/jars/maven-snapshot-a-1.0-SNAPSHOT.jar.snapshot-version1
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/local-repo/snapshot-test/jars/maven-snapshot-b-1.0-SNAPSHOT.jar1
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/local-repo/snapshot-test/jars/maven-snapshot-b-1.0-SNAPSHOT.jar.snapshot-version1
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/local-repo/snapshot-test/jars/maven-snapshot-e-1.0-SNAPSHOT.jar1
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/local-repo/snapshot-test/jars/maven-snapshot-e-1.0-SNAPSHOT.jar.snapshot-version1
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/local-repo/snapshot-test/poms/maven-test-snapshot-resolving-1.0.pom49
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/org/apache/maven/artifact/deployer/ArtifactDeployerTest.xml23
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/org/apache/maven/artifact/installer/ArtifactInstallerTest.xml23
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/org/apache/maven/artifact/manager/DefaultWagonManagerTest.xml48
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/org/apache/maven/artifact/resolver/ArtifactResolverTest.xml71
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/org/apache/maven/artifact/resolver/ArtifactUpdatePolicyTest.xml29
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/org/apache/maven/project/AbstractMavenProjectTestCase.xml9
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/pom.xml155
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/projects/scope/project-with-scoped-dependencies.xml99
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/projects/scope/transitive-compile-dep.xml57
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/projects/scope/transitive-default-dep.xml58
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/projects/scope/transitive-provided-dep.xml57
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/projects/scope/transitive-runtime-dep.xml58
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/projects/scope/transitive-test-dep.xml58
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/lifecycle-executor.txt217
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/plugin-manager.txt184
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/pom.xml238
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/project-builder.txt1
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/AbstractMavenLifecycleParticipant.java77
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/ArtifactFilterManager.java51
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/ArtifactFilterManagerDelegate.java34
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/BuildAbort.java39
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/BuildFailureException.java39
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/DefaultArtifactFilterManager.java112
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/DefaultMaven.java521
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/DefaultProjectDependenciesResolver.java217
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/DuplicateProjectException.java61
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/InternalErrorException.java36
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/Maven.java34
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/MavenExecutionException.java55
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/MissingModuleException.java48
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/ProjectBuildFailureException.java55
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/ProjectCycleException.java39
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/ProjectDependenciesResolver.java95
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/ReactorReader.java255
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/RepositoryUtils.java362
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/SessionScoped.java42
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/DependencyResolutionRequiredException.java35
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/InvalidRepositoryException.java65
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/factory/ArtifactFactory.java59
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/factory/DefaultArtifactFactory.java160
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/handler/DefaultArtifactHandler.java134
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/handler/manager/ArtifactHandlerManager.java37
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/handler/manager/DefaultArtifactHandlerManager.java73
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/metadata/AbstractArtifactMetadata.java33
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/metadata/ArtifactMetadataRetrievalException.java55
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/metadata/ArtifactMetadataSource.java52
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/metadata/ResolutionGroup.java46
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/repository/DefaultRepositoryRequest.java134
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/repository/LegacyLocalRepositoryManager.java435
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/repository/MavenArtifactRepository.java412
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/repository/RepositoryCache.java58
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/repository/RepositoryRequest.java95
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/repository/layout/DefaultRepositoryLayout.java112
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/repository/metadata/AbstractRepositoryMetadata.java255
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/repository/metadata/ArtifactRepositoryMetadata.java129
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/repository/metadata/RepositoryMetadata.java92
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/repository/metadata/RepositoryMetadataDeploymentException.java40
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/repository/metadata/RepositoryMetadataInstallationException.java40
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/repository/metadata/RepositoryMetadataManager.java61
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/repository/metadata/RepositoryMetadataResolutionException.java40
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/repository/metadata/io/DefaultMetadataReader.java110
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/repository/metadata/io/MetadataParseException.java93
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/repository/metadata/io/MetadataReader.java82
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/resolver/ArtifactResolutionRequest.java329
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/resolver/ArtifactResolutionResult.java358
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/resolver/DefaultResolutionErrorHandler.java89
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/resolver/ResolutionErrorHandler.java31
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/resolver/ResolutionListener.java109
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/resolver/ResolutionNode.java251
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/resolver/filter/AbstractScopeArtifactFilter.java107
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/resolver/filter/AndArtifactFilter.java99
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/resolver/filter/CumulativeScopeArtifactFilter.java122
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/resolver/filter/ExcludesArtifactFilter.java44
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/resolver/filter/ExclusionSetFilter.java86
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/resolver/filter/IncludesArtifactFilter.java93
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/resolver/filter/ScopeArtifactFilter.java78
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/bridge/MavenRepositorySystem.java785
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/classrealm/ArtifactClassRealmConstituent.java76
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/classrealm/ClassRealmConstituent.java74
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/classrealm/ClassRealmManager.java88
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/classrealm/ClassRealmManagerDelegate.java36
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/classrealm/ClassRealmRequest.java100
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/classrealm/DefaultClassRealmManager.java416
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/classrealm/DefaultClassRealmRequest.java82
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/configuration/BasedirBeanConfigurationPathTranslator.java71
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/configuration/BeanConfigurationException.java41
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/configuration/BeanConfigurationPathTranslator.java41
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/configuration/BeanConfigurationRequest.java130
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/configuration/BeanConfigurationValuePreprocessor.java45
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/configuration/BeanConfigurator.java44
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/configuration/DefaultBeanConfigurationRequest.java195
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/configuration/internal/DefaultBeanConfigurator.java160
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/eventspy/AbstractEventSpy.java45
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/eventspy/EventSpy.java77
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/eventspy/internal/EventSpyDispatcher.java158
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/eventspy/internal/EventSpyExecutionListener.java163
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/eventspy/internal/EventSpyRepositoryListener.java176
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/exception/DefaultExceptionHandler.java336
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/exception/ExceptionHandler.java30
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/exception/ExceptionSummary.java79
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/AbstractExecutionListener.java116
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/BuildFailure.java61
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/BuildSuccess.java44
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/BuildSummary.java78
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/DefaultMavenExecutionRequest.java1299
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/DefaultMavenExecutionRequestPopulator.java318
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/DefaultMavenExecutionResult.java109
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/ExecutionEvent.java92
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/ExecutionListener.java66
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/MavenExecutionRequest.java443
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/MavenExecutionRequestPopulationException.java43
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/MavenExecutionRequestPopulator.java74
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/MavenExecutionResult.java70
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/MavenSession.java438
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/MojoExecutionEvent.java86
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/MojoExecutionListener.java40
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/ProjectDependencyGraph.java64
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/ProjectExecutionEvent.java90
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/ProjectExecutionListener.java44
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/ReactorManager.java199
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/SettingsAdapter.java126
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/scope/MojoExecutionScoped.java42
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/scope/WeakMojoExecutionListener.java44
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/scope/internal/MojoExecutionScope.java190
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/scope/internal/MojoExecutionScopeCoreModule.java45
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/scope/internal/MojoExecutionScopeModule.java56
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/extension/internal/CoreExports.java75
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/extension/internal/CoreExportsProvider.java53
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/extension/internal/CoreExtensionEntry.java141
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/graph/DefaultGraphBuilder.java488
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/graph/DefaultProjectDependencyGraph.java134
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/graph/FilteredProjectDependencyGraph.java111
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/graph/GraphBuilder.java31
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/internal/aether/DefaultRepositorySystemSessionFactory.java271
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/internal/aether/LoggingRepositoryListener.java141
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/DefaultLifecycleExecutor.java177
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/DefaultLifecycles.java144
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/LifeCyclePluginAnalyzer.java32
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/Lifecycle.java80
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/LifecycleExecutionException.java111
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/LifecycleExecutor.java89
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/LifecycleMappingDelegate.java52
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/LifecycleNotFoundException.java54
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/LifecyclePhaseNotFoundException.java55
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/MavenExecutionPlan.java202
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/MissingProjectException.java41
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/MojoExecutionConfigurator.java44
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/NoGoalSpecifiedException.java41
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/BuildListCalculator.java67
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/BuildThreadFactory.java39
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/CompoundProjectExecutionListener.java72
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DefaultExecutionEvent.java77
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DefaultExecutionEventCatapult.java119
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DefaultLifecycleExecutionPlanCalculator.java591
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DefaultLifecycleMappingDelegate.java158
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DefaultLifecyclePluginAnalyzer.java258
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DefaultLifecycleTaskSegmentCalculator.java155
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DefaultMojoExecutionConfigurator.java108
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DefaultProjectArtifactFactory.java53
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DependencyContext.java114
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/ExecutionEventCatapult.java40
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/ExecutionPlanItem.java84
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/GoalTask.java45
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecycleDebugLogger.java182
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecycleDependencyResolver.java334
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecycleExecutionPlanCalculator.java67
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecycleModuleBuilder.java154
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecyclePluginResolver.java95
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecycleStarter.java150
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecycleTask.java50
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecycleTaskSegmentCalculator.java61
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/MojoDescriptorCreator.java309
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/MojoExecutor.java394
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/PhaseRecorder.java78
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/ProjectArtifactFactory.java38
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/ProjectBuildList.java158
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/ProjectIndex.java70
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/ProjectSegment.java106
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/ReactorBuildStatus.java80
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/ReactorContext.java83
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/TaskSegment.java73
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/builder/Builder.java47
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/builder/BuilderCommon.java199
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/builder/BuilderNotFoundException.java29
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/builder/multithreaded/ConcurrencyDependencyGraph.java153
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/builder/multithreaded/MultiThreadedBuilder.java197
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/builder/multithreaded/ThreadOutputMuxer.java477
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/builder/singlethreaded/SingleThreadedBuilder.java65
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/mapping/DefaultLifecycleMapping.java111
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/mapping/Lifecycle.java83
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/mapping/LifecycleMapping.java39
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/model/plugin/DefaultLifecycleBindingsInjector.java171
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/monitor/event/EventDispatcher.java37
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/monitor/event/EventMonitor.java35
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/BuildPluginManager.java54
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/CacheUtils.java211
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/CompoundMojoExecutionListener.java64
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/CycleDetectedInPluginGraphException.java46
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/DebugConfigurationListener.java91
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/DefaultBuildPluginManager.java244
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/DefaultExtensionRealmCache.java170
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/DefaultPluginArtifactsCache.java218
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/DefaultPluginDescriptorCache.java219
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/DefaultPluginRealmCache.java219
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/ExtensionRealmCache.java84
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/InvalidPluginDescriptorException.java44
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/InvalidPluginException.java48
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/LegacySupport.java59
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/MavenPluginManager.java128
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/MavenPluginValidator.java78
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/MojoExecution.java237
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/PluginArtifactsCache.java91
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/PluginConfigurationException.java74
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/PluginContainerException.java88
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/PluginDescriptorCache.java58
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/PluginDescriptorParsingException.java58
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/PluginExecutionException.java90
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/PluginIncompatibleException.java36
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/PluginLoaderException.java124
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/PluginManager.java82
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/PluginManagerException.java197
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/PluginNotFoundException.java58
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/PluginParameterException.java192
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/PluginParameterExpressionEvaluator.java482
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/PluginRealmCache.java85
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/PluginResolutionException.java47
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultLegacySupport.java74
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultMavenPluginManager.java946
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultPluginDependenciesResolver.java256
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultPluginManager.java261
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/internal/PlexusUtilsInjector.java87
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/internal/PluginDependenciesResolver.java71
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/internal/PluginDependencyResolutionListener.java158
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/internal/ValidatingConfigurationListener.java97
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/internal/WagonExcluder.java109
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/prefix/DefaultPluginPrefixRequest.java156
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/prefix/NoPluginFoundForPrefixException.java65
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/prefix/PluginPrefixRequest.java115
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/prefix/PluginPrefixResolver.java42
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/prefix/PluginPrefixResult.java55
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/prefix/internal/DefaultPluginPrefixResolver.java294
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/prefix/internal/DefaultPluginPrefixResult.java90
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/version/DefaultPluginVersionRequest.java165
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/version/PluginVersionNotFoundException.java47
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/version/PluginVersionRequest.java115
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/version/PluginVersionResolutionException.java107
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/version/PluginVersionResolver.java42
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/version/PluginVersionResult.java47
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/version/internal/DefaultPluginVersionResolver.java408
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/version/internal/DefaultPluginVersionResult.java69
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/DefaultDependencyResolutionRequest.java82
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/DefaultDependencyResolutionResult.java111
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/DefaultMavenProjectHelper.java128
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/DefaultModelBuildingListener.java155
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuilder.java929
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuildingHelper.java295
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuildingRequest.java339
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuildingResult.java110
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/DefaultProjectDependenciesResolver.java333
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/DefaultProjectRealmCache.java147
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/DependencyResolutionException.java42
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/DependencyResolutionRequest.java81
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/DependencyResolutionResult.java80
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/DuplicateArtifactAttachmentException.java64
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/DuplicateProjectException.java80
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/ExtensionDescriptor.java88
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/ExtensionDescriptorBuilder.java168
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/InvalidProjectVersionException.java59
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/MavenProject.java1976
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/MavenProjectHelper.java76
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/ProjectBuilder.java98
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/ProjectBuildingException.java145
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/ProjectBuildingHelper.java81
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/ProjectBuildingRequest.java194
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/ProjectBuildingResult.java74
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/ProjectDependenciesResolver.java40
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/ProjectModelResolver.java248
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/ProjectRealmCache.java79
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/ProjectSorter.java289
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/ReactorModelCache.java103
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/ReactorModelPool.java106
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/RepositorySessionDecorator.java36
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/artifact/ActiveProjectArtifact.java403
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/artifact/ArtifactWithDependencies.java33
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/artifact/AttachedArtifact.java185
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/artifact/DefaultMavenMetadataCache.java347
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/artifact/DefaultMetadataSource.java37
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/artifact/InvalidDependencyVersionException.java55
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/artifact/MavenMetadataCache.java38
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/artifact/MavenMetadataSource.java770
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/artifact/PluginArtifact.java94
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/artifact/ProjectArtifact.java100
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/artifact/ProjectArtifactMetadata.java130
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/path/PathTranslator.java41
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/properties/internal/EnvironmentUtils.java70
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/properties/internal/SystemProperties.java51
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/repository/ArtifactDoesNotExistException.java34
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/repository/ArtifactTransferEvent.java343
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/repository/ArtifactTransferFailedException.java35
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/repository/ArtifactTransferListener.java36
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/repository/ArtifactTransferResource.java66
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/repository/DelegatingLocalArtifactRepository.java195
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/repository/LocalArtifactRepository.java33
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/repository/LocalRepositoryNotAccessibleException.java44
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/repository/RepositorySystem.java164
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/repository/legacy/metadata/AbstractArtifactMetadata.java65
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/repository/legacy/metadata/ArtifactMetadataRetrievalException.java68
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/repository/legacy/metadata/ArtifactMetadataSource.java78
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/repository/legacy/metadata/DefaultMetadataResolutionRequest.java132
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/repository/legacy/metadata/MetadataResolutionRequest.java113
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/repository/legacy/metadata/ResolutionGroup.java83
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/rtinfo/RuntimeInformation.java49
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/rtinfo/internal/DefaultRuntimeInformation.java150
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/session/scope/internal/SessionScope.java169
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/session/scope/internal/SessionScopeModule.java63
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/settings/DefaultMavenSettingsBuilder.java158
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/settings/MavenSettingsBuilder.java81
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/settings/SettingsConfigurationException.java63
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/settings/SettingsUtils.java321
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/DefaultToolchain.java190
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/DefaultToolchainManager.java140
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/DefaultToolchainManagerPrivate.java82
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/DefaultToolchainsBuilder.java78
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/MisconfiguredToolchainException.java39
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/RequirementMatcher.java30
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/RequirementMatcherFactory.java109
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/Toolchain.java46
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/ToolchainFactory.java44
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/ToolchainManager.java64
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/ToolchainManagerPrivate.java58
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/ToolchainPrivate.java48
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/ToolchainsBuilder.java46
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/building/DefaultToolchainsBuilder.java138
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/building/DefaultToolchainsBuildingRequest.java63
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/building/DefaultToolchainsBuildingResult.java66
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/building/ToolchainsBuilder.java41
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/building/ToolchainsBuildingException.java93
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/building/ToolchainsBuildingRequest.java64
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/building/ToolchainsBuildingResult.java50
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/io/DefaultToolchainsReader.java115
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/io/ToolchainsParseException.java94
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/io/ToolchainsReader.java83
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/java/DefaultJavaToolChain.java55
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/java/JavaToolchain.java67
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/java/JavaToolchainFactory.java127
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/java/JavaToolchainImpl.java87
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/merge/MavenToolchainMerger.java103
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/mdo/extension.mdo65
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/mdo/toolchains.mdo231
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/resources/META-INF/maven/extension.xml173
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/resources/META-INF/plexus/artifact-handlers.xml219
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/resources/META-INF/plexus/components.xml134
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/resources/META-INF/plexus/default-bindings.xml399
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/resources/org/apache/maven/messages/build.properties23
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/resources/org/apache/maven/messages/messages.properties34
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/resources/org/apache/maven/messages/messages_de.properties34
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/resources/org/apache/maven/messages/messages_el.properties33
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/resources/org/apache/maven/messages/messages_en.properties23
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/resources/org/apache/maven/messages/messages_es.properties33
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/resources/org/apache/maven/messages/messages_fr.properties33
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/resources/org/apache/maven/messages/messages_ja.properties34
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/resources/org/apache/maven/messages/messages_ko.properties34
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/resources/org/apache/maven/messages/messages_nl.properties33
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/resources/org/apache/maven/messages/messages_no.properties33
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/resources/org/apache/maven/messages/messages_pl.properties33
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/resources/org/apache/maven/messages/messages_zh_CN.properties34
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/main/resources/org/apache/maven/project/standalone.xml30
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/site/apt/artifact-handlers.apt59
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/site/apt/configuration-management.apt139
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/site/apt/default-bindings.apt.vm67
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/site/apt/getting-to-container-configured-mojos.apt102
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/site/apt/index.apt77
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/site/apt/inheritance.apt100
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/site/apt/lifecycles.apt.vm49
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/site/apt/offline-mode.apt269
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/site/apt/plugin-execution-isolation.apt57
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/site/apt/scripting-support/marmalade-support.apt196
-rwxr-xr-xframework/src/maven/apache-maven-3.3.3/maven-core/src/site/resources/design/2.1-lifecycle-refactor-class-diagram.pngbin0 -> 38152 bytes
-rwxr-xr-xframework/src/maven/apache-maven-3.3.3/maven-core/src/site/resources/design/2.1-lifecycle-refactor-sequence-diagram.pngbin0 -> 87383 bytes
-rwxr-xr-xframework/src/maven/apache-maven-3.3.3/maven-core/src/site/resources/design/2.1-lifecycle-refactor.graffle4024
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/site/site.xml42
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/AbstractCoreMavenComponentTestCase.java360
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/DefaultMavenTest.java45
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/MavenLifecycleParticipantTest.java173
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/MavenTest.java69
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/ProjectDependenciesResolverTest.java114
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/artifact/handler/ArtifactHandlerTest.java89
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/configuration/DefaultBeanConfiguratorTest.java148
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/exception/DefaultExceptionHandlerTest.java60
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/execution/DefaultMavenExecutionRequestPopulatorTest.java62
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/execution/DefaultMavenExecutionTest.java52
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/execution/scope/internal/MojoExecutionScopeTest.java122
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/graph/DefaultProjectDependencyGraphTest.java172
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/DefaultLifecyclesTest.java59
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/DelegatingMojoExecutionListener.java75
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/DelegatingProjectExecutionListener.java82
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/EmptyLifecyclePluginAnalyzer.java77
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/LifecycleExecutorSubModulesTest.java98
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/LifecycleExecutorTest.java553
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/MavenExecutionPlanTest.java77
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/MojoExecutionXPathContainer.java72
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/BuildListCalculatorTest.java49
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/BuilderCommonTest.java76
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/ConcurrencyDependencyGraphTest.java94
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/LifecycleExecutionPlanCalculatorTest.java82
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/LifecycleTaskSegmentCalculatorImplTest.java57
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/PhaseRecorderTest.java49
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/ProjectBuildListTest.java42
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/builder/multithreaded/ThreadOutputMuxerTest.java167
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/AboutTheStubs.html55
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/BuildPluginManagerStub.java56
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/CompletionServiceStub.java89
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/DefaultLifecyclesStub.java63
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/ExecutionEventCatapultStub.java42
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/LifeCyclePluginAnalyzerStub.java74
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/LifecycleExecutionPlanCalculatorStub.java231
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/LifecycleTaskSegmentCalculatorStub.java89
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/LoggerStub.java110
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/MojoExecutorStub.java70
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/PluginPrefixResolverStub.java52
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/PluginVersionResolverStub.java48
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/ProjectDependenciesResolverStub.java109
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/ProjectDependencyGraphStub.java227
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/ProjectDependencyGraphStubTest.java61
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/plugin/PluginManagerTest.java342
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/plugin/PluginParameterExceptionTest.java164
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/plugin/PluginParameterExpressionEvaluatorTest.java447
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/plugin/internal/DefaultLegacySupportTest.java74
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/project/AbstractMavenProjectTestCase.java189
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/project/DefaultMavenProjectBuilderTest.java193
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/project/EmptyLifecycleExecutor.java109
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/project/EmptyProjectBuildingHelper.java62
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/project/ExtensionDescriptorBuilderTest.java101
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/project/LegacyLocalRepositoryManager.java192
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/project/MavenProjectTest.java197
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/project/PomConstructionTest.java1878
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/project/ProjectBuilderTest.java87
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/project/ProjectSorterTest.java363
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/project/TestMetadataSource.java51
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/project/artifact/DefaultMavenMetadataCacheTest.java81
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/project/artifact/MavenMetadataSourceTest.java183
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/project/canonical/CanonicalProjectBuilderTest.java101
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/project/harness/PomTestWrapper.java121
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/project/harness/Xpp3DomAttributeIterator.java89
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/project/harness/Xpp3DomAttributePointer.java105
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/project/harness/Xpp3DomNodeIterator.java161
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/project/harness/Xpp3DomNodePointer.java155
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/project/harness/Xpp3DomPointerFactory.java61
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/repository/LegacyRepositoryLayout.java89
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/repository/TestArtifactHandler.java83
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/repository/TestRepositoryConnector.java123
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/repository/TestRepositoryConnectorFactory.java48
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/repository/TestRepositorySystem.java329
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/rtinfo/internal/DefaultRuntimeInformationTest.java81
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/settings/PomConstructionWithSettingsTest.java159
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/settings/SettingsUtilsTest.java126
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/toolchain/DefaultToolchainManagerPrivateTest.java166
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/toolchain/DefaultToolchainManagerTest.java153
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/toolchain/DefaultToolchainTest.java158
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/toolchain/RequirementMatcherFactoryTest.java72
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/toolchain/building/DefaultToolchainsBuilderTest.java185
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/toolchain/building/ToolchainsBuildingExceptionTest.java73
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/toolchain/merge/MavenToolchainMergerTest.java176
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/default-maven/cyclic-reference/module-a/pom.xml19
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/default-maven/cyclic-reference/module-b/pom.xml19
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/default-maven/cyclic-reference/pom.xml14
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/lifecycle-executor/mojo-configuration/pom.xml67
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/lifecycle-executor/project-basic/pom.xml79
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/lifecycle-executor/project-with-additional-lifecycle-elements/pom.xml72
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/lifecycle-executor/project-with-additional-lifecycle-elements/src/main/java/org/apache/maven/lifecycle/test/App.java13
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/lifecycle-executor/project-with-additional-lifecycle-elements/src/test/java/org/apache/maven/lifecycle/test/AppTest.java38
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/lifecycle-executor/project-with-inheritance/pom.xml628
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/lifecycle-executor/project-with-multiple-executions/pom.xml112
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/lifecycle-executor/project-with-multiple-executions/src/main/mdo/remote-resources.mdo61
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/lifecycle-executor/project-with-multiple-executions/src/main/mdo/supplemental-model.mdo61
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/lifecycle-executor/project-with-plugin-level-configuration-only/pom.xml42
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/lifecycle-listener/lifecycle-listener-dependency-injection/pom.xml30
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/lifecycle-listener/lifecycle-participant-reactor-dependency-injection/module-a/pom.xml12
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/lifecycle-listener/lifecycle-participant-reactor-dependency-injection/module-b/pom.xml12
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/lifecycle-listener/lifecycle-participant-reactor-dependency-injection/pom.xml13
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/mng-5003-plugin-realm-cache/pom.xml8
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-contributing-system-scope-plugin-dep/pom.xml44
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-contributing-system-scope-plugin-dep/tools.jar0
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-with-build-extensions-plugin/pom.xml31
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-with-inheritance/pom.xml628
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-with-plugin-classpath-ordering/pom.xml63
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-with-plugin-classpath-ordering/sub/pom.xml77
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-with-plugin-classpath-ordering/sub/repo/org/apache/maven/its/mng3906/a/0.1/a-0.1.jarbin0 -> 5109 bytes
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-with-plugin-classpath-ordering/sub/repo/org/apache/maven/its/mng3906/a/0.1/a-0.1.pom56
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-with-plugin-classpath-ordering/sub/repo/org/apache/maven/its/mng3906/a/0.2/a-0.2.jarbin0 -> 5111 bytes
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-with-plugin-classpath-ordering/sub/repo/org/apache/maven/its/mng3906/a/0.2/a-0.2.pom56
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-with-plugin-classpath-ordering/sub/repo/org/apache/maven/its/mng3906/a/maven-metadata.xml13
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-with-plugin-classpath-ordering/sub/repo/org/apache/maven/its/mng3906/b/0.1/b-0.1.jarbin0 -> 5108 bytes
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-with-plugin-classpath-ordering/sub/repo/org/apache/maven/its/mng3906/b/0.1/b-0.1.pom56
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-with-plugin-classpath-ordering/sub/repo/org/apache/maven/its/mng3906/b/maven-metadata.xml12
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-with-plugin-classpath-ordering/sub/repo/org/apache/maven/its/mng3906/c/0.1/c-0.1.jarbin0 -> 5109 bytes
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-with-plugin-classpath-ordering/sub/repo/org/apache/maven/its/mng3906/c/0.1/c-0.1.pom56
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-with-plugin-classpath-ordering/sub/repo/org/apache/maven/its/mng3906/c/maven-metadata.xml12
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-with-plugin-classpath-ordering/sub/repo/org/apache/maven/its/mng3906/d/0.1/d-0.1.jarbin0 -> 5108 bytes
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-with-plugin-classpath-ordering/sub/repo/org/apache/maven/its/mng3906/d/0.1/d-0.1.pom56
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-with-plugin-classpath-ordering/sub/repo/org/apache/maven/its/mng3906/d/maven-metadata.xml12
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-with-plugin-classpath-ordering/sub/repo/org/apache/maven/its/mng3906/e/0.1/e-0.1.jarbin0 -> 5107 bytes
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-with-plugin-classpath-ordering/sub/repo/org/apache/maven/its/mng3906/e/0.1/e-0.1.pom56
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-with-plugin-classpath-ordering/sub/repo/org/apache/maven/its/mng3906/e/maven-metadata.xml12
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-with-plugin-classpath-ordering/sub/settings-template.xml55
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/project-builder/it0063/jdk/jre/placeholder.txt1
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/project-builder/it0063/jdk/lib/tools.jarbin0 -> 345 bytes
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/project-builder/it0063/pom.xml55
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/project-builder/mng-3023/consumer/pom.xml66
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/project-builder/mng-3023/dependency/dependency-1.jarbin0 -> 345 bytes
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/project-builder/mng-3023/dependency/pom.xml70
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/project-builder/mng-3023/pom.xml37
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/project-dependencies-resolver/it0063/jdk/jre/placeholder.txt1
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/project-dependencies-resolver/it0063/jdk/lib/tools.jarbin0 -> 345 bytes
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/project-dependencies-resolver/it0063/pom.xml55
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/project-dependencies-resolver/project-with-exclusions/pom.xml41
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/its/a/0.1/a-0.1.jarbin0 -> 1898 bytes
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/its/a/0.1/a-0.1.pom41
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/its/a/maven-metadata.xml12
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/its/b/0.1/b-0.1.jarbin0 -> 1936 bytes
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/its/b/0.1/b-0.1.pom49
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/its/b/maven-metadata.xml12
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/its/plugins/maven-it-plugin/0.1/maven-it-plugin-0.1.jarbin0 -> 13520 bytes
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/its/plugins/maven-it-plugin/0.1/maven-it-plugin-0.1.pom70
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/its/plugins/maven-it-plugin/0.1/pom.xml70
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/its/plugins/maven-it-plugin/maven-metadata.xml14
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/its/plugins/maven-metadata.xml10
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/maven-plugin-api/2.0/maven-plugin-api-2.0.jarbin0 -> 10133 bytes
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/maven-plugin-api/2.0/maven-plugin-api-2.0.pom23
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/maven/2.0/maven-2.0.pom264
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-clean-plugin/0.1/maven-clean-plugin-0.1.jarbin0 -> 6767 bytes
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-clean-plugin/0.1/maven-clean-plugin-0.1.pom70
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-clean-plugin/maven-metadata.xml14
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-compiler-plugin/0.1/maven-compiler-plugin-0.1.jarbin0 -> 8085 bytes
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-compiler-plugin/0.1/maven-compiler-plugin-0.1.pom70
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-compiler-plugin/maven-metadata.xml14
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-deploy-plugin/0.1/maven-deploy-plugin-0.1.jarbin0 -> 6777 bytes
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-deploy-plugin/0.1/maven-deploy-plugin-0.1.pom70
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-deploy-plugin/maven-metadata.xml14
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-install-plugin/0.1/maven-install-plugin-0.1.jarbin0 -> 6781 bytes
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-install-plugin/0.1/maven-install-plugin-0.1.pom70
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-install-plugin/maven-metadata.xml14
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-jar-plugin/0.1/maven-jar-plugin-0.1.jarbin0 -> 6790 bytes
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-jar-plugin/0.1/maven-jar-plugin-0.1.pom70
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-jar-plugin/maven-metadata.xml14
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-metadata.xml45
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-plugin-plugin/0.1/maven-plugin-plugin-0.1.jarbin0 -> 8007 bytes
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-plugin-plugin/0.1/maven-plugin-plugin-0.1.pom70
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-plugin-plugin/maven-metadata.xml14
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-resources-plugin/0.1/maven-resources-plugin-0.1.jarbin0 -> 8034 bytes
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-resources-plugin/0.1/maven-resources-plugin-0.1.pom70
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-resources-plugin/maven-metadata.xml14
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-surefire-plugin/0.1/maven-surefire-plugin-0.1.jarbin0 -> 6827 bytes
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-surefire-plugin/0.1/maven-surefire-plugin-0.1.pom70
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-surefire-plugin/maven-metadata.xml14
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/codehaus/plexus/plexus-utils/1.1/plexus-utils-1.1.jarbin0 -> 168568 bytes
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/codehaus/plexus/plexus-utils/1.1/plexus-utils-1.1.pom27
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/artifact-id-inheritance/child/pom.xml32
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/artifact-id-inheritance/pom.xml35
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/basedir-aligned-interpolation/pom.xml60
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/basedir-interpolation/pom-with-unusual-name.xml39
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/baseurl-interpolation/pom.xml38
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/boolean-interpolation/pom.xml82
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/build-extension-inheritance/pom.xml49
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/build-extension-inheritance/sub/pom.xml75
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/complete-model/w-parent/pom.xml31
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/complete-model/w-parent/sub/pom.xml319
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/complete-model/wo-parent/pom.xml313
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/config-with-plugin-mng/pom.xml39
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/consecutive_empty_elements/pom.xml14
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/contributors-inheritance/child-2/pom.xml45
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/contributors-inheritance/pom.xml35
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/dependency-inheritance/maven-parent.xml31
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/dependency-inheritance/pom.xml48
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/dependency-inheritance/sub/pom.xml34
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/dependency-management-with-interpolation/pom.xml19
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/dependency-management-with-interpolation/sub/pom.xml17
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/dependency-order/w-plugin-mngt/pom.xml68
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/dependency-order/wo-plugin-mngt/pom.xml66
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/dependency-scope-inheritance/pom.xml16
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/dependency-scope-inheritance/sub/pom.xml19
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/dependency-scope/pom.xml18
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/dependency-scope/sub/pom.xml24
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/developers-inheritance/child-2/pom.xml45
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/developers-inheritance/pom.xml35
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/distribution-management/pom.xml39
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/dual-execution-ids/pom.xml28
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/dual-execution-ids/sub/pom.xml43
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/duplicate-exclusions-dependency/nexus-parent.xml29
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/duplicate-exclusions-dependency/pom.xml33
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/duplicate-exclusions-dependency/sub/pom.xml16
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/empty-distMng-repo-url/pom.xml15
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/empty-scm/pom.xml58
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/equal-plugin-deps/pom.xml64
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/equal-plugin-exec-ids/pom.xml83
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/execution-configuration-join/pom.xml35
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/execution-configuration-subcollections/pom.xml42
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/execution-configuration/pom.xml58
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/foo/sub/pom.xml418
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/full-interpolation/pom.xml66
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/id-container-joining-with-empty-elements/pom.xml97
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/id-container-joining-with-empty-elements/sub/pom.xml84
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/inherited-properties-interpolation/active-profile/pom.xml50
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/inherited-properties-interpolation/active-profile/sub/pom.xml54
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/inherited-properties-interpolation/no-profile/pom.xml41
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/inherited-properties-interpolation/no-profile/sub/pom.xml45
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/interpolation-cli-wins/pom.xml39
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/jdk-activation/pom.xml105
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/join-different-containers-same-id/pom.xml66
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/licenses-inheritance/child-2/pom.xml47
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/licenses-inheritance/pom.xml37
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/limited-inheritance/child/pom.xml61
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/limited-inheritance/pom.xml87
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/mailing-lists-inheritance/child-2/pom.xml45
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/mailing-lists-inheritance/pom.xml35
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/managed-profile-dependency/pom.xml55
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/managed-profile-dependency/sub/pom.xml55
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/merged-filter-order/pom.xml44
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/merged-filter-order/sub/pom.xml49
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/merged-plugin-class-path-order/w-plugin-mngt/pom.xml64
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/merged-plugin-class-path-order/w-plugin-mngt/sub/pom.xml64
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/merged-plugin-class-path-order/wo-plugin-mngt/pom.xml62
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/merged-plugin-class-path-order/wo-plugin-mngt/sub/pom.xml64
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/merged-plugin-exec-goals-order/w-plugin-mngt/pom.xml59
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/merged-plugin-exec-goals-order/w-plugin-mngt/sub/pom.xml59
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/merged-plugin-exec-goals-order/wo-plugin-mngt/pom.xml57
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/merged-plugin-exec-goals-order/wo-plugin-mngt/sub/pom.xml59
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/merged-plugin-exec-order/w-plugin-mngt/pom.xml71
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/merged-plugin-exec-order/w-plugin-mngt/sub/pom.xml71
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/merged-plugin-exec-order/wo-plugin-mngt/pom.xml69
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/merged-plugin-exec-order/wo-plugin-mngt/sub/pom.xml71
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/micromailer/pom.xml124
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/micromailer/spice-parent-9.pom103
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/multiple-filters/pom.xml17
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/multiple-repos/pom.xml44
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/multiple-repos/sub/pom.xml45
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/nested-build-dir-interpolation/pom.xml55
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/parent-inheritance/child3.xml7
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/parent-inheritance/pom.xml11
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/parent-inheritance/sub/pom.xml9
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/parent-interpolation/pom.xml16
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/parent-interpolation/sub/pom.xml9
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/parent-pom-packaging/pom.xml35
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/parent-pom-packaging/sub/pom.xml40
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/platform-file-separator/pom.xml40
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-config-append/no-profile/pom.xml80
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-config-append/no-profile/subproject/pom.xml70
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-config-append/with-profile/pom.xml90
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-config-append/with-profile/subproject/pom.xml80
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-config-attributes/w-plugin-mngt/pom.xml62
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-config-attributes/w-profile/pom.xml74
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-config-attributes/wo-plugin-mngt/pom.xml53
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-config-merging/child/pom.xml76
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-config-merging/pom.xml72
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-config-order/w-plugin-mngt/pom.xml68
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-config-order/wo-plugin-mngt/pom.xml60
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-config-properties/pom.xml30
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-exec-config-order/w-plugin-mngt/pom.xml78
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-exec-config-order/wo-plugin-mngt/pom.xml70
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-exec-goals-order/w-plugin-mngt/pom.xml66
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-exec-goals-order/wo-plugin-mngt/pom.xml57
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-exec-inheritance/pom.xml75
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-exec-inheritance/w-merge/pom.xml48
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-exec-inheritance/wo-merge/pom.xml43
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-exec-merging-version-insensitive/pom.xml56
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-exec-merging-version-insensitive/sub/pom.xml59
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-exec-merging-wo-version/pom.xml55
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-exec-merging-wo-version/sub/pom.xml58
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-exec-merging/w-plugin-mngt/pom.xml58
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-exec-merging/w-plugin-mngt/sub/pom.xml59
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-exec-merging/wo-plugin-mngt/pom.xml56
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-exec-merging/wo-plugin-mngt/sub/pom.xml59
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-exec-order-and-default-exec/pom.xml71
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-exec-order-with-lifecycle/pom.xml52
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-exec-order/w-plugin-mngt/pom.xml76
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-exec-order/wo-plugin-mngt/pom.xml67
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-exec-w-and-wo-id/w-plugin-mngt/pom.xml72
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-exec-w-and-wo-id/wo-plugin-mngt/pom.xml64
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-inheritance-merge-order/pom.xml67
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-inheritance-merge-order/sub/pom.xml72
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-inheritance-order/child/pom.xml51
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-inheritance-order/pom.xml68
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-inheritance-simple/pom.xml17
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-inheritance-simple/sub/pom.xml20
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-injection-merge-order/pom.xml133
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-management-dependencies/pom.xml25
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-management-dependencies/sub/pom.xml25
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-management-duplicate/pom.xml39
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-management-duplicate/sub/pom.xml64
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-management-for-implicit-plugin/child/pom.xml53
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-management-for-implicit-plugin/pom.xml61
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-management-inheritance/pom.xml64
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-merge-simple/pom.xml17
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-order/nexus-parent.xml19
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-order/pom.xml28
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/pluginmanagement-inherited/pom.xml18
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/pluginmanagement-inherited/sub/pom.xml17
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/pom-encoding/latin-1/pom.xml36
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/pom-encoding/utf-8/pom.xml36
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/pom-inheritance/pom.xml188
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/pom-inheritance/sub/pom.xml36
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/prerequisites-inheritance/child/pom.xml36
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/prerequisites-inheritance/pom.xml33
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/profile-default-deactivation/pom.xml35
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/profile-dependencies-multiple-profiles/pom.xml81
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/profile-injected-dependencies/pom.xml75
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/profile-injection-order/pom.xml68
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/profile-module-inheritance/pom.xml18
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/profile-module-inheritance/sub/pom.xml12
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/profile-module/pom.xml24
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/profile-plugin-mng-dependencies/pom.xml77
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/profile-plugin-mng-dependencies/sub/pom.xml62
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/profile-plugins/pom.xml52
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/profile-properties-interpolation/pom.xml54
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/properties-inheritance/pom.xml34
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/properties-inheritance/sub/pom.xml40
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/properties-no-duplication/pom.xml12
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/properties-no-duplication/sub/pom.xml17
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/repo-inheritance/pom.xml64
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/reporting-interpolation/pom.xml6
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/reporting-plugin-config/pom.xml51
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/reporting-plugin-config/sub/pom.xml48
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/single-configuration-inheritance/jetty-parent.xml37
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/single-configuration-inheritance/pom.xml41
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/sytem-property-interpolation/pom.xml30
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/unc-path/pom.xml41
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/unc-path/sub/pom.xml57
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/unique-dependency-key/dep-mngt-in-profile/pom.xml49
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/unique-dependency-key/dep-mngt/pom.xml44
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/unique-dependency-key/deps-in-profile/pom.xml47
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/unique-dependency-key/deps/pom.xml42
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/unique-repo-id/artifact-repo-in-profile/pom.xml51
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/unique-repo-id/artifact-repo/pom.xml45
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/unique-repo-id/plugin-repo-in-profile/pom.xml51
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/unique-repo-id/plugin-repo/pom.xml45
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/unprefixed-expression-interpolation/child/pom.xml104
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/unprefixed-expression-interpolation/pom.xml36
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/url-append/child/pom.xml64
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/url-append/parent/pom.xml53
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/url-inheritance/another-parent/pom.xml36
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/url-inheritance/another-parent/sub/pom.xml35
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/url-inheritance/pom.xml74
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/url-inheritance/sub/pom.xml35
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/url-no-decoding/pom.xml64
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/xml-coalesce-text/pom.xml567
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/xml-markup-interpolation/pom.xml41
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/xml-whitespace/pom.xml43
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/xml-whitespace/sub/pom.xml49
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-settings/repositories/pom.xml29
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-settings/repositories/settings.xml55
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-settings/settings-no-pom/pom.xml13
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-settings/settings-no-pom/settings.xml20
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-settings/test-pom-and-settings-interpolation/pom.xml78
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-settings/test-pom-and-settings-interpolation/settings.xml35
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/META-INF/maven/org.apache.maven/maven-core/pom.properties1
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/META-INF/plexus/components.xml113
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/canonical-pom.xml55
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/dependencyManagement-pom.xml65
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/distributionManagement-pom.xml44
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/maven-test/jars/maven-test-a-1.0.jar1
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/maven-test/jars/maven-test-a-1.1.jar1
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/maven-test/jars/maven-test-b-1.0.jar1
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/maven-test/jars/maven-test-b-1.1.jar1
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/maven-test/jars/maven-test-c-1.0.jar1
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/maven-test/jars/maven-test-c-1.1.jar1
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/maven-test/jars/maven-test-d-1.0.jar1
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/maven-test/jars/maven-test-d-1.1.jar1
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/maven-test/jars/maven-test-d-1.2.jar1
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/maven-test/poms/maven-test-a-1.0.pom14
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/maven-test/poms/maven-test-a-1.1.pom14
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/maven-test/poms/maven-test-b-1.0.pom7
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/maven-test/poms/maven-test-b-1.1.pom7
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/maven-test/poms/maven-test-c-1.0.pom7
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/maven-test/poms/maven-test-c-1.1.pom7
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/maven-test/poms/maven-test-d-1.0.pom7
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/maven-test/poms/maven-test-d-1.1.pom7
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/maven-test/poms/maven-test-d-1.2.pom7
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/p0/p1/pom.xml45
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/p0/p2/pom.xml56
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/p0/p3/pom.xml59
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/p0/p4/pom.xml67
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/p0/pom.xml26
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/local-repo/marker.txt1
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/local-repo/maven-test/jars/maven-test-a-1.0.jar1
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/local-repo/maven-test/jars/maven-test-b-1.0.jar1
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/local-repo/maven-test/jars/maven-test-c-1.0.jar1
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/local-repo/maven-test/jars/maven-test-d-1.0.jar1
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/local-repo/maven-test/poms/maven-test-a-1.0.pom23
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/local-repo/maven-test/poms/maven-test-b-1.0.pom23
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/local-repo/maven-test/poms/maven-test-c-1.0.pom16
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/local-repo/maven-test/poms/maven-test-d-1.1.pom7
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/local-repo/maven-test/poms/maven-test-d-1.2.pom7
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/local-repo/snapshot-test/jars/maven-snapshot-a-1.0-SNAPSHOT.jar1
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/local-repo/snapshot-test/jars/maven-snapshot-a-1.0-SNAPSHOT.jar.snapshot-version1
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/local-repo/snapshot-test/jars/maven-snapshot-b-1.0-SNAPSHOT.jar1
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/local-repo/snapshot-test/jars/maven-snapshot-b-1.0-SNAPSHOT.jar.snapshot-version1
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/local-repo/snapshot-test/jars/maven-snapshot-e-1.0-SNAPSHOT.jar1
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/local-repo/snapshot-test/jars/maven-snapshot-e-1.0-SNAPSHOT.jar.snapshot-version1
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/local-repo/snapshot-test/poms/maven-test-snapshot-resolving-1.0.pom49
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/MavenLifecycleParticipantTest.xml9
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/execution/test-extension-1.jarbin0 -> 4208 bytes
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/junit/junit/3.8.1/junit-3.8.1.jarbin0 -> 121070 bytes
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/junit/junit/3.8.1/junit-3.8.1.jar.md51
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/junit/junit/3.8.1/junit-3.8.1.jar.sha11
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/junit/junit/3.8.1/junit-3.8.1.pom29
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/junit/junit/3.8.1/junit-3.8.1.pom.md51
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/junit/junit/3.8.1/junit-3.8.1.pom.sha11
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/apache/3/apache-3.pom82
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/apache/3/apache-3.pom.md51
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/apache/3/apache-3.pom.sha11
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/artifact/maven-artifact/3.0-SNAPSHOT/maven-artifact-3.0-SNAPSHOT.jarbin0 -> 163984 bytes
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/artifact/maven-artifact/3.0-SNAPSHOT/maven-artifact-3.0-SNAPSHOT.jar.md51
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/artifact/maven-artifact/3.0-SNAPSHOT/maven-artifact-3.0-SNAPSHOT.jar.sha11
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/artifact/maven-artifact/3.0-SNAPSHOT/maven-artifact-3.0-SNAPSHOT.pom112
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/artifact/maven-artifact/3.0-SNAPSHOT/maven-artifact-3.0-SNAPSHOT.pom.md51
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/artifact/maven-artifact/3.0-SNAPSHOT/maven-artifact-3.0-SNAPSHOT.pom.sha11
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/core/test/test-extension/1/test-extension-1.jarbin0 -> 4208 bytes
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/core/test/test-extension/1/test-extension-1.pom73
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/core/test/test-extension/1/test-extension-1.pom.md51
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/core/test/test-extension/1/test-extension-1.pom.sha11
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/core/test/test-lifecycle-and-artifactHandler/1/test-lifecycle-and-artifactHandler-1.jarbin0 -> 2582 bytes
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/core/test/test-lifecycle-and-artifactHandler/1/test-lifecycle-and-artifactHandler-1.pom44
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/core/test/test-lifecycle-and-artifactHandler/1/test-lifecycle-and-artifactHandler-1.pom.md51
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/core/test/test-lifecycle-and-artifactHandler/1/test-lifecycle-and-artifactHandler-1.pom.sha11
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/maven-parent/4/maven-parent-4.pom304
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/maven-parent/4/maven-parent-4.pom.md51
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/maven-parent/4/maven-parent-4.pom.sha11
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/maven-parent/5/maven-parent-5.pom466
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/maven-parent/5/maven-parent-5.pom.md51
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/maven-parent/5/maven-parent-5.pom.sha11
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/wagon/wagon-provider-api/1.0-beta-2/wagon-provider-api-1.0-beta-2.jarbin0 -> 46326 bytes
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/wagon/wagon-provider-api/1.0-beta-2/wagon-provider-api-1.0-beta-2.jar.md51
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/wagon/wagon-provider-api/1.0-beta-2/wagon-provider-api-1.0-beta-2.jar.sha11
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/wagon/wagon-provider-api/1.0-beta-2/wagon-provider-api-1.0-beta-2.pom21
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/wagon/wagon-provider-api/1.0-beta-2/wagon-provider-api-1.0-beta-2.pom.md51
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/wagon/wagon-provider-api/1.0-beta-2/wagon-provider-api-1.0-beta-2.pom.sha11
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/wagon/wagon/1.0-beta-2/wagon-1.0-beta-2.pom170
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/wagon/wagon/1.0-beta-2/wagon-1.0-beta-2.pom.md51
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/wagon/wagon/1.0-beta-2/wagon-1.0-beta-2.pom.sha11
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-active-collections/1.0-beta-1/plexus-active-collections-1.0-beta-1.jarbin0 -> 15961 bytes
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-active-collections/1.0-beta-1/plexus-active-collections-1.0-beta-1.jar.md51
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-active-collections/1.0-beta-1/plexus-active-collections-1.0-beta-1.jar.sha11
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-active-collections/1.0-beta-1/plexus-active-collections-1.0-beta-1.pom51
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-active-collections/1.0-beta-1/plexus-active-collections-1.0-beta-1.pom.md51
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-active-collections/1.0-beta-1/plexus-active-collections-1.0-beta-1.pom.sha11
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-classworlds/1.2-alpha-10/plexus-classworlds-1.2-alpha-10.jarbin0 -> 42472 bytes
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-classworlds/1.2-alpha-10/plexus-classworlds-1.2-alpha-10.jar.md51
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-classworlds/1.2-alpha-10/plexus-classworlds-1.2-alpha-10.jar.sha11
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-classworlds/1.2-alpha-10/plexus-classworlds-1.2-alpha-10.pom94
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-classworlds/1.2-alpha-10/plexus-classworlds-1.2-alpha-10.pom.md51
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-classworlds/1.2-alpha-10/plexus-classworlds-1.2-alpha-10.pom.sha11
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-classworlds/1.2-alpha-7/plexus-classworlds-1.2-alpha-7.jarbin0 -> 42636 bytes
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-classworlds/1.2-alpha-7/plexus-classworlds-1.2-alpha-7.jar.md51
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-classworlds/1.2-alpha-7/plexus-classworlds-1.2-alpha-7.jar.sha11
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-classworlds/1.2-alpha-7/plexus-classworlds-1.2-alpha-7.pom78
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-classworlds/1.2-alpha-7/plexus-classworlds-1.2-alpha-7.pom.md51
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-classworlds/1.2-alpha-7/plexus-classworlds-1.2-alpha-7.pom.sha11
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-component-api/1.0-alpha-16/plexus-component-api-1.0-alpha-16.jarbin0 -> 33149 bytes
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-component-api/1.0-alpha-16/plexus-component-api-1.0-alpha-16.jar.md51
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-component-api/1.0-alpha-16/plexus-component-api-1.0-alpha-16.jar.sha11
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-component-api/1.0-alpha-16/plexus-component-api-1.0-alpha-16.pom63
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-component-api/1.0-alpha-16/plexus-component-api-1.0-alpha-16.pom.md51
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-component-api/1.0-alpha-16/plexus-component-api-1.0-alpha-16.pom.sha11
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-component-api/1.0-alpha-32/plexus-component-api-1.0-alpha-32.jarbin0 -> 36108 bytes
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-component-api/1.0-alpha-32/plexus-component-api-1.0-alpha-32.jar.md51
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-component-api/1.0-alpha-32/plexus-component-api-1.0-alpha-32.jar.sha11
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-component-api/1.0-alpha-32/plexus-component-api-1.0-alpha-32.pom61
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-component-api/1.0-alpha-32/plexus-component-api-1.0-alpha-32.pom.md51
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-component-api/1.0-alpha-32/plexus-component-api-1.0-alpha-32.pom.sha11
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-components/1.1.6/plexus-components-1.1.6.pom60
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-components/1.1.6/plexus-components-1.1.6.pom.md51
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-components/1.1.6/plexus-components-1.1.6.pom.sha11
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-container-default/1.0-alpha-16/plexus-container-default-1.0-alpha-16.jarbin0 -> 210679 bytes
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-container-default/1.0-alpha-16/plexus-container-default-1.0-alpha-16.jar.md51
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-container-default/1.0-alpha-16/plexus-container-default-1.0-alpha-16.jar.sha11
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-container-default/1.0-alpha-16/plexus-container-default-1.0-alpha-16.pom56
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-container-default/1.0-alpha-16/plexus-container-default-1.0-alpha-16.pom.md51
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-container-default/1.0-alpha-16/plexus-container-default-1.0-alpha-16.pom.sha11
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-container-default/1.0-alpha-32/plexus-container-default-1.0-alpha-32.jarbin0 -> 238880 bytes
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-container-default/1.0-alpha-32/plexus-container-default-1.0-alpha-32.jar.md51
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-container-default/1.0-alpha-32/plexus-container-default-1.0-alpha-32.jar.sha11
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-container-default/1.0-alpha-32/plexus-container-default-1.0-alpha-32.pom98
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-container-default/1.0-alpha-32/plexus-container-default-1.0-alpha-32.pom.md51
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-container-default/1.0-alpha-32/plexus-container-default-1.0-alpha-32.pom.sha11
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-containers/1.0-alpha-16/plexus-containers-1.0-alpha-16.pom49
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-containers/1.0-alpha-16/plexus-containers-1.0-alpha-16.pom.md51
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-containers/1.0-alpha-16/plexus-containers-1.0-alpha-16.pom.sha11
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-containers/1.0-alpha-32/plexus-containers-1.0-alpha-32.pom49
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-containers/1.0-alpha-32/plexus-containers-1.0-alpha-32.pom.md51
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-containers/1.0-alpha-32/plexus-containers-1.0-alpha-32.pom.sha11
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-utils/1.1/plexus-utils-1.1.jarbin0 -> 168568 bytes
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-utils/1.1/plexus-utils-1.1.jar.md51
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-utils/1.1/plexus-utils-1.1.jar.sha11
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-utils/1.1/plexus-utils-1.1.pom27
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-utils/1.1/plexus-utils-1.1.pom.md51
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-utils/1.1/plexus-utils-1.1.pom.sha11
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-utils/1.4.5/plexus-utils-1.4.5.jarbin0 -> 205043 bytes
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-utils/1.4.5/plexus-utils-1.4.5.jar.md51
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-utils/1.4.5/plexus-utils-1.4.5.jar.sha11
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-utils/1.4.5/plexus-utils-1.4.5.pom61
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-utils/1.4.5/plexus-utils-1.4.5.pom.md51
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-utils/1.4.5/plexus-utils-1.4.5.pom.sha11
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus/1.0.10/plexus-1.0.10.pom273
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus/1.0.10/plexus-1.0.10.pom.md51
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus/1.0.10/plexus-1.0.10.pom.sha11
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus/1.0.11/plexus-1.0.11.pom308
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus/1.0.11/plexus-1.0.11.pom.md51
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus/1.0.11/plexus-1.0.11.pom.sha11
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus/1.0.4/plexus-1.0.4.pom205
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus/1.0.4/plexus-1.0.4.pom.md51
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus/1.0.4/plexus-1.0.4.pom.sha11
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus/1.0.8/plexus-1.0.8.pom259
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus/1.0.8/plexus-1.0.8.pom.md51
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus/1.0.8/plexus-1.0.8.pom.sha11
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus/1.0.9/plexus-1.0.9.pom257
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus/1.0.9/plexus-1.0.9.pom.md51
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus/1.0.9/plexus-1.0.9.pom.sha11
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/repo-marker.txt1
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/lifecycle/LifecycleExecutorTest.xml9
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/lifecycle/pom.xml628
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/plugin/PluginManagerTest.xml9
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/project/AbstractMavenProjectTestCase.xml9
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/project/PomConstructionTest.xml13
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/project/workspace/buildFromFile/pom.xml8
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/project/workspace/buildFromRepo/tests/project-caching/1/project-caching-1.pom8
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/project/workspace/buildFromRepo/tests/project-caching/maven-metadata-local.xml11
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/project/workspace/buildModelLineage/pom.xml7
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/project/workspace/resolveParentPom/childAndParent/child/pom.xml10
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/project/workspace/resolveParentPom/childAndParent/pom.xml7
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/project/workspace/resolveParentPom/pom.xml10
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/settings/PomConstructionWithSettingsTest.xml9
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/toolchain/global.xml35
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/toolchain/model/toolchains-jdks-extend.xml45
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/toolchain/model/toolchains-jdks-extra.xml45
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/toolchain/model/toolchains-jdks.xml43
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/toolchain/user.xml35
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/codehaus/plexus/plexus-utils/1.1/plexus-utils-1.1.jarbin0 -> 168568 bytes
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/codehaus/plexus/plexus-utils/1.1/plexus-utils-1.1.jar.sha11
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/codehaus/plexus/plexus-utils/1.1/plexus-utils-1.1.pom27
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/codehaus/plexus/plexus-utils/1.1/plexus-utils-1.1.pom.sha11
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/pom.xml52
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/project-dynamism/plugin-level-dep.pom.xml24
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/project-dynamism/pom-interp.xml28
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/project-dynamism/pom-relative.xml36
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/project-dynamism/pom.xml36
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/projects/bad-dependency.xml27
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/projects/bad-project.xml20
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/projects/base-directory-alignment/project-which-needs-directory-alignment-child.xml33
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/projects/base-directory-alignment/project-which-needs-directory-alignment.xml135
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/projects/base-directory-alignment/subproject/project-which-needs-directory-alignment-child.xml29
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/projects/build-path-expression-pom.xml14
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/projects/build.properties18
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/projects/child-which-inherits-from-super-model.xml28
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/projects/child-with-bogus-parent.xml29
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/projects/child.xml33
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/projects/duplicate-plugins-merged-pom.xml48
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/projects/fully-populated-child.xml168
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/projects/grandchild-check/child/grandchild/pom.xml10
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/projects/grandchild-check/child/pom.xml13
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/projects/grandchild-check/pom.xml7
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/projects/import-scope-pom-resolves-from-property-based-repository.xml31
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/projects/modelsource/module01/pom.xml12
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/projects/modelsource/pom.xml13
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/projects/project.xml162
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/projects/versionless-managed-dependency.xml24
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/remote-repo-1/maven-test/jars/maven-test-b-1.0.jarbin0 -> 18874 bytes
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/remote-repo-1/maven-test/jars/maven-test-b-1.0.jar.md51
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/remote-repo-1/maven-test/poms/maven-test-b-1.0.pom21
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/remote-repo-1/snapshot-test/jars/maven-snapshot-a-1.0-SNAPSHOT.jar1
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/remote-repo-1/snapshot-test/jars/maven-snapshot-a-1.0-SNAPSHOT.jar.snapshot-version1
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/remote-repo-1/snapshot-test/jars/maven-snapshot-b-1.0-SNAPSHOT.jar1
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/remote-repo-1/snapshot-test/jars/maven-snapshot-b-1.0-SNAPSHOT.jar.snapshot-version1
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/remote-repo-1/snapshot-test/jars/maven-snapshot-c-1.0-SNAPSHOT.jar1
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/remote-repo-1/snapshot-test/jars/maven-snapshot-c-1.0-SNAPSHOT.jar.snapshot-version1
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/remote-repo-2/maven-test/jars/maven-test-z-1.0.jar1
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/withActiveByDefaultProfile-pom.xml40
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/pom.xml144
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/examples/simple-project/pom.xml39
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/examples/simple-project/settings.xml26
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/examples/simple-project/src/main/java/org/apache/maven/embedder/App.java28
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/examples/simple-project/src/test/java/org/apache/maven/embedder/AppTest.java53
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/CLIManager.java271
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/CLIReportingUtils.java205
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/CliRequest.java120
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java1610
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/configuration/ConfigurationProcessor.java28
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/configuration/SettingsXmlConfigurationProcessor.java290
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/event/DefaultEventSpyContext.java38
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/event/ExecutionEventLogger.java381
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/internal/BootstrapCoreExtensionManager.java143
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/logging/BaseSlf4jConfiguration.java45
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/logging/Slf4jConfiguration.java47
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/logging/Slf4jConfigurationFactory.java91
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/logging/Slf4jLogger.java145
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/logging/Slf4jLoggerManager.java111
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/logging/Slf4jStdoutLogger.java306
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/logging/impl/Log4j2Configuration.java59
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/logging/impl/LogbackConfiguration.java61
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/logging/impl/Slf4jSimpleConfiguration.java63
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/logging/impl/UnsupportedSlf4jBindingConfiguration.java72
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/transfer/AbstractMavenTransferListener.java90
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/transfer/BatchModeMavenTransferListener.java32
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/transfer/ConsoleMavenTransferListener.java133
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/transfer/QuietMavenTransferListener.java31
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/transfer/Slf4jMavenTransferListener.java97
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/slf4j/MavenSlf4jFriend.java35
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/slf4j/impl/MavenSlf4jSimpleFriend.java40
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/mdo/core-extensions.mdo88
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/resources/META-INF/MANIFEST.MF7
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/resources/META-INF/maven/slf4j-configuration.properties22
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/site/apt/cli.apt.vm28
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/site/apt/index.apt.vm42
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/site/apt/logging.apt112
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/site/site.xml40
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/embedder-test-project/pom.xml48
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/embedder-test-project/src/main/java/org/apache/maven/App.java13
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/embedder-test-project/src/test/java/org/apache/maven/AppTest.java38
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/aggregate-mojo-failure/plugin/pom.xml49
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/aggregate-mojo-failure/plugin/src/main/java/org/plugin/TestPlugin.java36
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/aggregate-mojo-failure/project/pom.xml25
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/bad-build-plan/plugin/pom.xml49
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/bad-build-plan/plugin/src/main/java/org/plugin/TestPlugin.java35
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/bad-build-plan/project/pom.xml25
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/bad-dep-version/pom.xml33
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/bad-ext-direct-deps/local-repo/org/apache/maven/errortest/test-maven-ext/1/test-maven-ext-1.pom34
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/bad-ext-direct-deps/project/pom.xml35
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/bad-ext-plugin-dep-ver/local-repo/org/apache/maven/errortest/bad-ext-plugin-dep-ver-maven-plugin/1/bad-ext-plugin-dep-ver-maven-plugin-1.jarbin0 -> 3166 bytes
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/bad-ext-plugin-dep-ver/local-repo/org/apache/maven/errortest/bad-ext-plugin-dep-ver-maven-plugin/1/bad-ext-plugin-dep-ver-maven-plugin-1.pom55
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/bad-ext-plugin-dep-ver/plugin/pom.xml57
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/bad-ext-plugin-dep-ver/plugin/src/main/java/org/plugin/TestPlugin.java33
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/bad-ext-plugin-dep-ver/project/pom.xml37
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/bad-ext-plugin-maven-ver/local-repo/org/apache/maven/errortest/bad-ext-plugin-maven-ver-maven-plugin/1/bad-ext-plugin-maven-ver-maven-plugin-1.jarbin0 -> 3166 bytes
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/bad-ext-plugin-maven-ver/local-repo/org/apache/maven/errortest/bad-ext-plugin-maven-ver-maven-plugin/1/bad-ext-plugin-maven-ver-maven-plugin-1.pom54
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/bad-ext-plugin-maven-ver/local-repo/org/apache/maven/errortest/bad-ext-plugin-maven-ver-maven-plugin/maven-metadata-local.xml12
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/bad-ext-plugin-maven-ver/plugin/pom.xml57
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/bad-ext-plugin-maven-ver/plugin/src/main/java/org/plugin/TestPlugin.java33
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/bad-ext-plugin-maven-ver/project/pom.xml37
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/bad-maven-version/pom.xml11
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/bad-mg-dep-version/pom.xml35
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/bad-non-dep-version/pom.xml35
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/bad-profile-repo/pom.xml7
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/bad-profile-repo/profiles.xml18
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/config-rdonly-mojo-param/plugin/pom.xml49
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/config-rdonly-mojo-param/plugin/src/main/java/org/plugin/TestPlugin.java39
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/config-rdonly-mojo-param/project/pom.xml47
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/deploy-repo-creation-err/pom.xml41
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/duplicated-attachments/plugin/pom.xml54
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/duplicated-attachments/plugin/src/main/java/org/plugin/TestPlugin.java50
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/duplicated-attachments/project/pom.xml25
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/err-loading-plugin/local-repo/org/apache/maven/errortest/err-loading-plugin-maven-plugin/1/err-loading-plugin-maven-plugin-1.jarbin0 -> 3166 bytes
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/err-loading-plugin/local-repo/org/apache/maven/errortest/err-loading-plugin-maven-plugin/1/err-loading-plugin-maven-plugin-1.pom55
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/err-loading-plugin/project/pom.xml45
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/err-resolving-ext-plugin/local-repo/org/apache/maven/errortest/dep/1/dep-1.pom16
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/err-resolving-ext-plugin/local-repo/org/apache/maven/errortest/err-resolving-ext-plugin-maven-plugin/1/err-resolving-ext-plugin-maven-plugin-1.jarbin0 -> 3166 bytes
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/err-resolving-ext-plugin/local-repo/org/apache/maven/errortest/err-resolving-ext-plugin-maven-plugin/1/err-resolving-ext-plugin-maven-plugin-1.pom60
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/err-resolving-ext-plugin/project/pom.xml18
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/err-resolving-project-dep/project/local-repo/org/apache/maven/errortest/dep/1/dep-1.pom16
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/err-resolving-project-dep/project/pom.xml27
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/err-resolving-project-dep/project/src/main/java/org/apache/maven/test/error/mojoFailure/App.java13
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/err-resolving-project-dep/project/src/test/java/org/apache/maven/test/error/mojoFailure/AppTest.java38
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/ext-deps-resolve-err/local-repo/org/apache/maven/errortest/test-maven-ext-dep/1/test-maven-ext-dep-1.pom26
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/ext-deps-resolve-err/local-repo/org/apache/maven/errortest/test-maven-ext/1/test-maven-ext-1.pom34
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/ext-deps-resolve-err/project/pom.xml35
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/ext-plugin-artifact-missing/local-repo/org/apache/maven/errortest/ext-plugin-artifact-missing-maven-plugin/1/ext-plugin-artifact-missing-maven-plugin-1.pom55
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/ext-plugin-artifact-missing/project/pom.xml37
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/ext-plugin-realm-error/plugin/pom.xml49
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/ext-plugin-realm-error/plugin/src/main/java/org/plugin/ComponentOne.java8
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/ext-plugin-realm-error/plugin/src/main/java/org/plugin/ComponentTwo.java8
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/ext-plugin-realm-error/plugin/src/main/java/org/plugin/TestPlugin.java39
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/ext-plugin-realm-error/plugin/src/main/resources/META-INF/plexus/components.xml25
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/ext-plugin-realm-error/project/pom.xml36
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/ext-plugin-version-err/local-repo/org/apache/maven/errortest/ext-plugin-version-err-maven-plugin/1/ext-plugin-version-err-maven-plugin-1.jarbin0 -> 3166 bytes
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/ext-plugin-version-err/local-repo/org/apache/maven/errortest/ext-plugin-version-err-maven-plugin/1/ext-plugin-version-err-maven-plugin-1.pom50
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/ext-plugin-version-err/local-repo/org/apache/maven/errortest/ext-plugin-version-err-maven-plugin/maven-metadata-local.xml10
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/ext-plugin-version-err/plugin/pom.xml57
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/ext-plugin-version-err/plugin/src/main/java/org/plugin/TestPlugin.java33
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/ext-plugin-version-err/project/pom.xml36
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/ext-realm-error/ext/pom.xml38
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/ext-realm-error/ext/src/main/java/org/ext/App.java13
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/ext-realm-error/ext/src/main/resources/META-INF/plexus/components.xml1
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/ext-realm-error/project/pom.xml35
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/interp-from-model/pom.xml7
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/interp-from-project/project/local-repo/org/test/bad-pom/1/bad-pom-1.pom9
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/interp-from-project/project/pom.xml22
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/load-extern-profiles-ioex/pom.xml7
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/load-extern-profiles-xex/pom.xml7
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/load-extern-profiles-xex/profiles.xml4
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/missing-direct-invoke-mojo/plugin/pom.xml49
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/missing-direct-invoke-mojo/plugin/src/main/java/org/plugin/TestPlugin.java36
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/missing-module-pom/child1/pom.xml19
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/missing-module-pom/child1/src/main/java/org/test/App.java13
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/missing-module-pom/child1/src/test/java/org/test/AppTest.java38
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/missing-module-pom/pom.xml13
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/missing-parent-pom/pom.xml11
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/missing-req-mojo-param/plugin/pom.xml49
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/missing-req-mojo-param/plugin/src/main/java/org/plugin/TestPlugin.java38
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/missing-req-mojo-param/project/pom.xml25
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/mojo-config-error/plugin/pom.xml49
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/mojo-config-error/plugin/src/main/java/org/plugin/TestPlugin.java33
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/mojo-config-error/plugin/src/main/resources/META-INF/maven/plugin.xml38
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/mojo-config-error/project/pom.xml45
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/mojo-exec-err/plugin/pom.xml49
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/mojo-exec-err/plugin/src/main/java/org/plugin/TestPlugin.java33
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/mojo-exec-err/project/pom.xml26
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/mojo-lookup-err/plugin/pom.xml54
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/mojo-lookup-err/plugin/src/main/java/org/plugin/TestPlugin.java42
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/mojo-lookup-err/project/pom.xml25
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/parent-parse-ioex/child/pom.xml10
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/parent-parse-ioex/pom.xml0
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/parent-parse-xex/child/pom.xml10
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/parent-parse-xex/pom.xml7
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/profile-activator-err/pom.xml39
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/profile-activator-lookup-err/ext/pom.xml38
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/profile-activator-lookup-err/ext/src/main/java/org/ext/App.java13
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/profile-activator-lookup-err/ext/src/main/resources/META-INF/plexus/components.xml16
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/profile-activator-lookup-err/project/pom.xml46
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/project-collision/mod1/pom.xml7
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/project-collision/mod2/pom.xml7
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/project-collision/pom.xml12
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/project-cycle/dep/pom.xml12
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/project-cycle/pom.xml19
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/project-dep-missing/pom.xml22
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/project-dep-missing/src/main/java/org/apache/maven/test/error/mojoFailure/App.java13
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/project-dep-missing/src/test/java/org/apache/maven/test/error/mojoFailure/AppTest.java38
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/project-mojo-failure/pom.xml17
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/project-mojo-failure/src/main/java/org/apache/maven/test/error/mojoFailure/App.java14
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/project-mojo-failure/src/test/java/org/apache/maven/test/error/mojoFailure/AppTest.java38
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/project-parse-xex/pom.xml25
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/project-validation/pom.xml13
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/repo-creation-err/pom.xml41
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/eventing-projects/read-with-deps/pom.xml15
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/eventing-projects/read-with-deps/repo/tests/dep/1/dep-1.pom6
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/eventing-projects/simple-read-project/pom.xml6
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/extensions/META-INF/plexus/components.xml28
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/java/org/apache/maven/cli/CLIManagerTest.java108
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/java/org/apache/maven/cli/CLIReportingUtilsTest.java40
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/java/org/apache/maven/cli/MavenCliTest.java110
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/plugin-version-references/jar-pom.xml32
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/plugin-version-references/maven-plugin-pom.xml36
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/projects/bad-module-non-recursive/badmodule/pom.xml14
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/projects/bad-module-non-recursive/goodmodule/pom.xml14
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/projects/bad-module-non-recursive/pom.xml14
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/projects/config-illegal/.mvn/maven.config1
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/projects/config/.mvn/maven.config2
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/projects/invalid-goal/pom.xml49
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/projects/isolated-project-getting-parent-pom/project/pom.xml13
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/projects/isolated-project-getting-parent-pom/project/src/main/java/org/codehaus/m2eclipse/App.java13
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/projects/isolated-project-getting-parent-pom/project/src/test/java/org/codehaus/m2eclipse/AppTest.java38
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/projects/isolated-project-getting-parent-pom/repository/org/codehaus/m2eclipse/parent/1.0-SNAPSHOT/maven-metadata-company.xml11
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/projects/isolated-project-getting-parent-pom/repository/org/codehaus/m2eclipse/parent/1.0-SNAPSHOT/parent-1.0-SNAPSHOT.pom18
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/projects/isolated-project-getting-parent-pom/repository/org/codehaus/m2eclipse/parent/maven-metadata-local.xml11
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/projects/isolated-project-getting-parent-pom/settings.xml23
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/projects/optional-dep/pom.xml20
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/projects/readProject-missingModuleIgnored/pom.xml13
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/projects/readProject-withScmInheritance/modules/child1/pom.xml13
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/projects/readProject-withScmInheritance/pom.xml19
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/resources/META-INF/maven/org.apache.maven/maven-core/pom.properties18
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/resources/pom-with-distribution-status.xml30
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/resources/pom-without-dependencies.xml30
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/resources/pom.xml34
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/resources/pom2.xml48
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/resources/settings/invalid-settings.xml24
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/resources/settings/valid-settings.xml27
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/pom.xml86
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/AbstractModelBuildingListener.java37
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuilder.java1309
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuilderFactory.java243
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuildingEvent.java64
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuildingRequest.java408
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuildingResult.java180
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelProblem.java175
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelProblemCollector.java200
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelProcessor.java84
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/FileModelSource.java83
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/FilterModelBuildingRequest.java285
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelBuilder.java67
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelBuildingEvent.java53
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelBuildingEventCatapult.java48
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelBuildingException.java180
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelBuildingListener.java40
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelBuildingRequest.java338
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelBuildingResult.java99
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelCache.java56
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelCacheTag.java132
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelData.java222
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelProblem.java117
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelProblemCollector.java41
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelProblemCollectorExt.java37
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelProblemCollectorRequest.java101
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelProblemUtils.java171
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelProcessor.java32
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelSource.java38
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelSource2.java56
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/Result.java255
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/StringModelSource.java56
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/UrlModelSource.java46
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/composition/DefaultDependencyManagementImporter.java83
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/composition/DependencyManagementImporter.java48
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/inheritance/DefaultInheritanceAssembler.java255
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/inheritance/InheritanceAssembler.java48
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/AbstractStringBasedModelInterpolator.java271
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/BuildTimestampValueSource.java47
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/MavenBuildTimestamp.java70
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/ModelInterpolator.java54
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/PathTranslatingPostProcessor.java67
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/ProblemDetectingValueSource.java87
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/StringSearchModelInterpolator.java504
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/UrlNormalizingPostProcessor.java69
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/io/DefaultModelReader.java134
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/io/DefaultModelWriter.java118
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/io/ModelParseException.java93
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/io/ModelReader.java89
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/io/ModelWriter.java74
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/locator/DefaultModelLocator.java42
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/locator/ModelLocator.java44
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/management/DefaultDependencyManagementInjector.java110
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/management/DefaultPluginManagementInjector.java137
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/management/DependencyManagementInjector.java44
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/management/PluginManagementInjector.java44
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/merge/MavenModelMerger.java729
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/normalization/DefaultModelNormalizer.java135
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/normalization/ModelNormalizer.java54
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/path/DefaultModelPathTranslator.java111
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/path/DefaultModelUrlNormalizer.java84
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/path/DefaultPathTranslator.java66
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/path/DefaultUrlNormalizer.java65
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/path/ModelPathTranslator.java45
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/path/ModelUrlNormalizer.java42
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/path/PathTranslator.java43
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/path/UrlNormalizer.java39
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/plugin/DefaultPluginConfigurationExpander.java83
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/plugin/DefaultReportConfigurationExpander.java65
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/plugin/DefaultReportingConverter.java240
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/plugin/LifecycleBindingsInjector.java46
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/plugin/PluginConfigurationExpander.java43
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/plugin/ReportConfigurationExpander.java43
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/plugin/ReportingConverter.java43
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/profile/DefaultProfileActivationContext.java259
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/profile/DefaultProfileInjector.java249
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/profile/DefaultProfileSelector.java143
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/profile/ProfileActivationContext.java79
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/profile/ProfileInjector.java46
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/profile/ProfileSelector.java49
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/profile/activation/FileProfileActivator.java192
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/profile/activation/JdkVersionProfileActivator.java224
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/profile/activation/OperatingSystemProfileActivator.java168
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/profile/activation/ProfileActivator.java59
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/profile/activation/PropertyProfileActivator.java126
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/resolution/InvalidRepositoryException.java73
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/resolution/ModelResolver.java93
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/resolution/UnresolvableModelException.java126
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/resolution/WorkspaceModelResolver.java33
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/superpom/DefaultSuperPomProvider.java87
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/superpom/SuperPomProvider.java42
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/validation/DefaultModelValidator.java1076
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/validation/ModelValidator.java54
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/mdo/profiles.mdo399
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/resources/org/apache/maven/model/pom-4.0.0.xml150
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/site/apt/index.apt187
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/site/apt/super-pom.apt.vm30
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/site/site.xml40
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/java/org/apache/maven/model/building/ComplexActivationTest.java60
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/java/org/apache/maven/model/building/DefaultModelBuilderFactoryTest.java59
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/java/org/apache/maven/model/building/SimpleProblemCollector.java89
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/java/org/apache/maven/model/inheritance/DefaultInheritanceAssemblerTest.java108
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/java/org/apache/maven/model/interpolation/AbstractModelInterpolatorTest.java494
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/java/org/apache/maven/model/interpolation/MavenBuildTimestampTest.java38
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/java/org/apache/maven/model/interpolation/StringSearchModelInterpolatorTest.java505
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/java/org/apache/maven/model/path/DefaultUrlNormalizerTest.java85
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/java/org/apache/maven/model/profile/activation/AbstractProfileActivatorTest.java92
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/java/org/apache/maven/model/profile/activation/JdkVersionProfileActivatorTest.java185
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/java/org/apache/maven/model/profile/activation/PropertyProfileActivatorTest.java185
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/java/org/apache/maven/model/validation/DefaultModelValidatorTest.java630
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/factory/complex.xml49
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/factory/simple.xml81
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/inheritance/plugin-configuration-child.xml61
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/inheritance/plugin-configuration-expected.xml87
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/inheritance/plugin-configuration-parent.xml89
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/bad-dependency-exclusion-id.xml40
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/bad-dependency-scope.xml69
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/bad-dependency-version.xml43
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/bad-import-scope-classifier.xml38
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/bad-import-scope-type.xml37
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/bad-modelVersion.xml25
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/bad-plugin-dependency-scope.xml70
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/bad-plugin-dependency-version.xml46
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/bad-plugin-version.xml55
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/bad-repository-id.xml50
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/bad-snapshot-version.xml25
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/bad-version.xml25
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/basedir-system-path.xml42
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/distribution-management-status.xml29
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/duplicate-module.xml31
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/duplicate-plugin-execution.xml103
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/duplicate-plugin.xml81
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/duplicate-profile-id.xml35
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/empty-module.xml30
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/empty-plugin-version.xml34
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/hard-coded-system-path.xml42
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/incomplete-parent.xml30
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/invalid-aggregator-packaging-pom.xml30
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/invalid-ids-pom.xml26
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/missing-1-pom.xml21
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/missing-artifactId-pom.xml25
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/missing-dependency-artifactId-pom.xml32
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/missing-dependency-exclusion-id.xml39
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/missing-dependency-groupId-pom.xml32
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/missing-dependency-mgmt-artifactId-pom.xml34
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/missing-dependency-mgmt-groupId-pom.xml34
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/missing-dependency-mgmt-version-pom.xml34
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/missing-dependency-version-pom.xml32
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/missing-groupId-pom.xml25
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/missing-modelVersion-pom.xml25
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/missing-plugin-artifactId-pom.xml33
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/missing-plugin-dependency-artifactId.xml41
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/missing-plugin-dependency-groupId.xml41
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/missing-plugin-dependency-version.xml41
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/missing-plugin-version-pom.xml33
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/missing-report-artifactId-pom.xml33
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/missing-report-version-pom.xml57
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/missing-repository-id-pom.xml36
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/missing-resource-directory-pom.xml38
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/missing-type-pom.xml26
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/missing-version-pom.xml25
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/reserved-repository-id.xml50
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model/pom.xml132
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model/src/main/java/org/apache/maven/model/io/xpp3/package-info.java30
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model/src/main/java/org/apache/maven/model/merge/ModelMerger.java2924
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model/src/main/java/org/apache/maven/model/merge/package-info.java24
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model/src/main/java/org/apache/maven/model/package-info.java25
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model/src/main/mdo/maven.mdo3649
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model/src/site/apt/index.apt39
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model/src/site/site.xml36
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model/src/site/xdoc/navigation.xml35
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/ActivationFileTest.java56
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/ActivationOSTest.java56
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/ActivationPropertyTest.java56
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/ActivationTest.java56
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/BuildTest.java56
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/CiManagementTest.java56
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/ContributorTest.java56
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/DependencyManagementTest.java56
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/DependencyTest.java56
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/DeploymentRepositoryTest.java56
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/DeveloperTest.java56
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/DistributionManagementTest.java56
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/ExclusionTest.java56
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/ExtensionTest.java56
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/IssueManagementTest.java56
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/LicenseTest.java56
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/MailingListTest.java56
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/ModelTest.java56
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/NotifierTest.java56
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/OrganizationTest.java56
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/ParentTest.java56
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/PluginConfigurationTest.java56
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/PluginContainerTest.java56
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/PluginExecutionTest.java56
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/PluginManagementTest.java56
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/PluginTest.java56
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/PrerequisitesTest.java56
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/ProfileTest.java56
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/RelocationTest.java56
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/ReportPluginTest.java56
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/ReportSetTest.java56
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/ReportingTest.java56
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/RepositoryPolicyTest.java56
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/RepositoryTest.java56
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/ResourceTest.java56
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/ScmTest.java56
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/SiteTest.java56
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-plugin-api/pom.xml91
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/main/java/org/apache/maven/monitor/logging/DefaultLog.java131
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/main/java/org/apache/maven/plugin/AbstractMojo.java198
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/main/java/org/apache/maven/plugin/AbstractMojoExecutionException.java53
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/main/java/org/apache/maven/plugin/ContextEnabled.java45
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/main/java/org/apache/maven/plugin/Mojo.java72
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/main/java/org/apache/maven/plugin/MojoExecutionException.java80
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/main/java/org/apache/maven/plugin/MojoFailureException.java69
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/main/java/org/apache/maven/plugin/MojoNotFoundException.java85
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/DuplicateMojoDescriptorException.java34
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/DuplicateParameterException.java31
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/InvalidParameterException.java37
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/InvalidPluginDescriptorException.java38
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/MojoDescriptor.java719
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/Parameter.java207
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/PluginDescriptor.java445
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/PluginDescriptorBuilder.java358
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/Requirement.java72
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/main/java/org/apache/maven/plugin/logging/Log.java158
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/main/java/org/apache/maven/plugin/logging/SystemStreamLog.java196
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/main/mdo/lifecycle.mdo129
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/main/mdo/plugin.mdo525
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/site/apt/index.apt39
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/site/site.xml40
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/test/java/org/apache/maven/plugin/descriptor/PluginDescriptorBuilderTest.java133
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/test/java/org/apache/maven/plugin/lifecycle/LifecycleXpp3ReaderTest.java55
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/test/resources/lifecycle.xml39
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/test/resources/plugin.xml89
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-repository-metadata/pom.xml63
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-repository-metadata/src/main/mdo/metadata.mdo371
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-repository-metadata/src/site/apt/index.apt52
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-repository-metadata/src/site/site.xml36
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-settings-builder/pom.xml85
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/building/DefaultSettingsBuilder.java277
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/building/DefaultSettingsBuilderFactory.java71
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/building/DefaultSettingsBuildingRequest.java160
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/building/DefaultSettingsBuildingResult.java58
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/building/DefaultSettingsProblem.java166
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/building/DefaultSettingsProblemCollector.java70
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/building/FileSettingsSource.java59
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/building/SettingsBuilder.java40
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/building/SettingsBuildingException.java90
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/building/SettingsBuildingRequest.java131
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/building/SettingsBuildingResult.java50
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/building/SettingsProblem.java100
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/building/SettingsProblemCollector.java41
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/building/SettingsSource.java35
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/building/StringSettingsSource.java69
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/building/UrlSettingsSource.java60
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/crypto/DefaultSettingsDecrypter.java110
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/crypto/DefaultSettingsDecryptionRequest.java120
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/crypto/DefaultSettingsDecryptionResult.java81
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/crypto/SettingsDecrypter.java38
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/crypto/SettingsDecryptionRequest.java65
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/crypto/SettingsDecryptionResult.java71
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/io/DefaultSettingsReader.java113
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/io/DefaultSettingsWriter.java118
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/io/SettingsParseException.java93
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/io/SettingsReader.java82
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/io/SettingsWriter.java74
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/merge/MavenSettingsMerger.java142
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/validation/DefaultSettingsValidator.java285
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/validation/SettingsValidator.java41
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/site/site.xml36
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/test/java/org/apache/maven/settings/building/DefaultSettingsBuilderFactoryTest.java53
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/test/java/org/apache/maven/settings/validation/DefaultSettingsValidatorTest.java244
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/test/resources/settings/factory/simple.xml24
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-settings/pom.xml63
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-settings/src/main/java/org/apache/maven/settings/RuntimeInfo.java55
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-settings/src/main/mdo/settings.mdo1077
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-settings/src/site/apt/index.apt36
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-settings/src/site/site.xml36
-rw-r--r--framework/src/maven/apache-maven-3.3.3/pom.xml654
-rw-r--r--framework/src/maven/apache-maven-3.3.3/src/site/resources/images/maven-deps.pngbin0 -> 73105 bytes
-rw-r--r--framework/src/maven/apache-maven-3.3.3/src/site/site.xml75
-rw-r--r--framework/src/maven/apache-maven-3.3.3/src/site/xdoc/index.xml76
-rw-r--r--framework/src/maven/apache-maven-3.3.3/src/site/xdoc/maven-deps.odgbin0 -> 32324 bytes
4133 files changed, 576666 insertions, 0 deletions
diff --git a/framework/src/ant/apache-ant-1.9.6/CONTRIBUTORS b/framework/src/ant/apache-ant-1.9.6/CONTRIBUTORS
new file mode 100644
index 00000000..e78bd62e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/CONTRIBUTORS
@@ -0,0 +1,417 @@
+Amongst other, the following people contributed to ant:
+
+Adam Blinkinsop
+Adam Bryzak
+Adam Sotona
+Adrian Nistor
+Aleksandr Ishutin
+Alex Rosen
+Alexei Yudichev
+Alexey Panchenko
+Alexey Solofnenko
+Alfred Theorin
+Alison Winters
+Andreas Ames
+Andreas Mross
+Andrew Eisenberg
+Andrew Everitt
+Andrew Stevens
+Andrey Urazov
+André-John Mas
+Andy Wood
+Anil K. Vijendran
+Anli Shundi
+Anthony Goubard
+Anthony Green
+Anthony Wat
+Antoine Baudoux
+Antoine Levy-Lambert
+Anton Mazkovoi
+Arjan Veenstra
+Arnaud Vandyck
+Arnout J. Kuiper
+Aslak HellesĂ´y
+Atsuhiko Yamanaka
+Avik Sengupta
+Balazs Fejes 2
+Bart Vanhaute
+Benjamin Burgess
+Ben Galbraith
+Ben Gertzfield
+Benoit Moussaud
+Bernd Dutkowski
+Bernhard Rosenkraenzer
+Brad Clark
+Brant Langer Gurganus
+Brian Curnow
+Brian Deitte
+Brian Felder
+Brian Repko
+Bruce Atherton
+Cedomir Igaly
+Charles Hudak
+Charlie Hubbard
+Chris Povirk
+Christian Knorr
+Christian Schmidt
+Christoph Gysin
+Christoph Wilhelms
+Christophe Labouisse
+Christopher A. Longo
+Christopher Charlier
+Clark Archer
+Clemens Hammacher
+Clement OUDOT
+Clive Brettingham-Moore
+Conor MacNeill
+Craeg Strong
+Craig Cottingham
+Craig R. McClanahan
+Craig Richardson
+Craig Ryan
+Craig Sandvik
+Curt Arnold
+Curtis White
+Cyrille Morvan
+D'Arcy Smith
+Dale Anson
+Dale Sherwood
+Dan Armbrust
+Daniel Henrique
+Daniel Ribagnac
+Daniel Spilker
+Daniel Trebbien
+Danno Ferrin
+Danny Yates
+Dante Briones
+Davanum Srinivas
+Dave Brondsema
+Dave Brosius
+David A. Herman
+David Crossley
+David Gärtner
+David S. Johnson
+David Kavanagh
+David LeRoy
+David Leal
+David M. Lloyd
+David Maclean
+David Rees
+Denis Hennessy
+Derek Slager
+Devon C. Miller
+Diane Holt
+dIon Gillard
+Dmitry A. Kuminov
+Dominique Devienne
+Donal Quinlan
+Don Brown
+Don Ferguson
+Don Jeffery
+Drew Sudell
+Edison Guo
+Eduard Wirch
+Edwin Woudt
+Eli Tucker
+Emmanuel Bourg
+Eric Barboni
+Eric Olsen
+Eric Pugh
+Erik Costlow
+Erik Hatcher
+Erik Langenbach
+Erik Meade
+Ernst de Haan
+Frank Harnack
+Frank Somers
+Frank Zeyda
+Frantisek Kucera
+Frederic Bothamy
+Frederic Lavigne
+Gary S. Weaver
+Gautam Guliani
+Gene-Sung Chung
+Georges-Etienne Legendre
+Gero Vermaas
+Gerrit Riessen
+Gilbert Rebhan
+Gilles Scokart
+Glenn McAllister
+Glenn Twiggs
+Greg Nelson
+Greg Roodt
+Greg Schueler
+Grégoire Vatry
+Günther Kögel
+Harish Prabandham
+Haroon Rafique
+Hiroaki Nakamura
+Holger Engels
+Holger Joest
+Ignacio Coloma
+Ingenonsya France
+Ingmar Stein
+Irene Rusman
+Isaac Shabtay
+Ivan Ivanov
+J Bleijenbergh
+Jack J. Woehr
+James Duncan Davidson
+Jan Cumps
+Jan Matèrne
+Jan Mynarik
+Jan Stolze
+Jason Hunter
+Jason Pettiss
+Jason Salter
+Jason Yip
+Jay Dickon Glanville
+Jay Peck
+Jay van der Meer
+JC Mann
+J D Glanville
+Jean-Francois Brousseau
+Jean-Louis Boudart
+Jeff Gettle
+Jeff Martin
+Jeff Tulley
+Jeff Turner
+Jene Jasper
+Jeremy Mawson
+Jerome Lacoste
+Jesse Glick
+Jesse Stockall
+Jim Allers
+Joerg Wassmer
+Joel Tucci
+Joey Richey
+Johann Herunter
+John Elion
+John Sisson
+Jon Dickinson
+Jon S. Stevens
+Jon Skeet
+Jose Alberto Fernandez
+Joseph Walton
+Josh Lucas
+Juerg Wanner
+Julian Simpson
+Justin Vallon
+Keiron Liddle
+Keith Visco
+Kevin Connor Arpe
+Kevin Greiner
+Kevin Jackson
+Kevin Ross
+Kevin Z Grey
+Kim Hansen
+Kirk Wylie
+Kristian Rosenvold
+Kyle Adams
+Lajos Veres
+Larry Shatzer
+Larry Streepy
+Les Hughes
+Levi Cook
+lucas
+Lucas Werkmeister
+Ludovic Claude
+Maarten Coene
+Magesh Umasankar
+Maneesh Sahu
+Marcel Schutte
+Marcus B&ouml;rger
+Mario Frasca
+Mariusz Nowostawski
+Mark A. Ziesemer
+Mark DeLaFranier
+Mark Hecker
+Mark R. Diggory
+Mark Salter
+Markus Kahl
+Martijn Kruithof
+Martin Landers
+Martin Poeschl
+Martin van den Bemt
+Martin von Gagern
+Mathieu Champlon
+Mathieu Peltier
+Matt Albrecht
+Matt Benson
+Matt Bishop
+Matt Foemmel
+Matt Grosso
+Matt Humphrey
+Matt Small
+Matt Wildig
+Matthew Hawthorne
+Matthew Inger
+Matthew Kuperus Heun
+Matthew Watson
+Matthias Bhend
+Michael Bayne
+Michael Clarke
+Michael Davey
+Michael J. Sikorsky
+Michael McCallum
+Michael Montuori
+Michael Newcomb
+Micheal Nygard
+Michael Saunders
+Miha
+Mike Davis
+Mike Roberts
+Mike Williams
+Miroslav ZaĹĄko
+mnowostawski
+Mounir El Hajj
+Nathan Beyer
+Nick Chalko
+Nick Fortescue
+Nick Crossley
+Nick Pellow
+Nicola Ken Barozzi
+Nico Seessle
+Nigel Magnay
+Oliver Merkel
+Oliver Rossmueller
+Ondra Medek
+Omer Shapira
+Oystein Gisnas
+Patrick Altaie
+Patrick C. Beard
+Patrick Chanezon
+Patrick G. Heck (Gus Heck)
+Patrick Martin
+Paul Austin
+Paul Christmann
+Paul Galbraith
+Paul King
+Paulo Gaspar
+Pavan Bayyapu
+Pavel Jisl
+Pawel Zuzelski
+Peter B. West
+Peter Donald
+Peter Doornbosch
+Peter Hulst
+Peter Janes
+Peter Reilly
+Petr Kureš
+Phil Hanna
+Philip Hourihane
+Phillip Wells
+Pierre Delisle
+Pierre Dittgen
+riasol
+R Handerson
+Ralf Hergert
+Rami Ojares
+Randy Watler
+Raphael Pierquin
+Ray Waldin
+Remie Bolte
+René Krell
+Richard Evans
+Richard Steele
+Rick Beton
+Robbie Gibson
+Robert Anderson
+Robert Clark
+Robert Flaherty
+Robert Shaw
+Robert Streich
+Robert Watkins
+Roberto Scaramuzzi
+Robin Green
+Robin Power
+Robin Verduijn
+Rob Oxspring
+Rob van Oostrum
+Rodrigo Schmidt
+Roger Vaughn
+Roman Ivashin
+Roman Savko
+Ronen Mashal
+Russell Gold
+Ryan Bennitt
+Sam Ruby
+Sandra Metz
+Scott Carlson
+Scott Ellsworth
+Scott Johnson
+Scott M. Stirling
+Sean Egan
+Sean P. Kane
+Sebastien Arod
+Shiraz Kanga
+Sebastian Kantha
+Simon Law
+Simone Bordet
+Stefan Bodewig
+Stefan Heimann
+Stefano Mazzocchi
+Stephan Strittmatter
+Stephane Bailliez
+stephan
+Stephan Michels
+Stephen Chin
+Stephen Goetze
+Steve Cohen
+Steve Langley
+Steve Loughran
+Steve Morin
+Steve Wadsworth
+Steven E. Newton
+Sudheer Chigurupati
+Takashi Okamoto
+TAMURA Kent
+Taoufik Romdhane
+Tariq Master
+Thomas Aglassinger
+Thomas Butz
+Thomas Christen
+Thomas Christensen
+Thomas Haas
+Thomas Quas
+Tim Boemker
+Tim Drury
+Tim Fennell
+Tim Stephenson
+Tim Whittington
+Timoteo Ohara
+Timothy Gerard Endres
+Tom Ball
+Tom Brus
+Tom Cunningham
+Tom Dimock
+Tom Eugelink
+Tom May
+Tomasz Bech
+Trejkaz Xaoza
+Ulrich Schmidt
+Uwe Schindler
+Valentino Miazzo
+Victor Toni
+Vimil Saju
+Vincent Legoll
+Vitold Sedyshev
+Volker Leidl
+Waldek Herka
+Wang Weijun
+Will Wang
+William Bernardet
+William Ferguson
+William Webber
+Wolf Siberski
+Wolfgang Baer
+Wolfgang Frech
+Wolfgang Glas
+Wolfgang Werner
+Xavier Hanin
+Xavier Witdouck
+Yohann Roussel
+Yuji Yamano
+Yves Martin
+Zach Garner
+Zdenek Wagner
diff --git a/framework/src/ant/apache-ant-1.9.6/INSTALL b/framework/src/ant/apache-ant-1.9.6/INSTALL
new file mode 100644
index 00000000..83c11675
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/INSTALL
@@ -0,0 +1,2 @@
+For installation instructions see the manual in the docs subdirectory
+or online at <http://ant.apache.org/manual/index.html>.
diff --git a/framework/src/ant/apache-ant-1.9.6/KEYS b/framework/src/ant/apache-ant-1.9.6/KEYS
new file mode 100644
index 00000000..fb21736d
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/KEYS
@@ -0,0 +1,1497 @@
+This file contains the PGP keys of various developers.
+
+Users: pgp < KEYS
+ gpg --import KEYS
+Developers:
+ pgp -kxa <your name> and append it to this file.
+ (pgpk -ll <your name> && pgpk -xa <your name>) >> this file.
+ (gpg --list-sigs <your name>
+ && gpg --armor --export <your name>) >> this file.
+
+Type Bits/KeyID Date User ID
+pub 1024/FEECAAED 1998/11/11 Stefan Bodewig <bodewig@bost.de>
+ Stefan Bodewig <bodewig@apache.org>
+
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: 2.6.3i
+
+mQCNAzZJoiMAAAEEAMzhUxTOC20Nprp6K4nLTiARt+EXii/dovNWWcfzZcYXi/lX
+r3zpUTTZxlKQpd4RaHjFmGgoOraZE4jCRFARVcFJgYmGUKpcWJZO7YKL36WUizTM
++dyB2ycOtzlty1W5VmRL3FGqo67pKA9F/QHg3NSu9hY1W9xPPK7Kq3f+7KrtAAUR
+tCBTdGVmYW4gQm9kZXdpZyA8Ym9kZXdpZ0Bib3N0LmRlPokAlQIFEDZSrGXHcgyK
+jiW9zQEBshEEAMlG4qVjKp4/agdJG56M6izx9oaKecFLXHQJrFUy3w2PvZHFYtXc
+osXKorX6bPrE8uB57MxbY2WapKeVRodlG0+j39vAf501duK8q2rktfWt9Cl4JjJ4
+DbWhSWfV1ci62u2gCxwYQe22F9Wh+vhOR5NK9RTbSKhupdlFsnrk/i7xiQCVAwUQ
+NkmiI67Kq3f+7KrtAQGdxQQAlcFOzSv7G6M4uGbgvw7IGgrhx7rawtIyv9hLXgVC
+7ua9xaZV8G0Fl9gh8RnbdcZ4R/aT+KIiAFaslfZ3t6hlC4MTbnAJqvdS/NO98ZkJ
+YvnzZSKHflAbd5gyE7IVxBC9/xRlF/Wls5sYNwb6RjoRCaOjxN/y3WCLa3Va101v
+zNy0I1N0ZWZhbiBCb2Rld2lnIDxib2Rld2lnQGFwYWNoZS5vcmc+iQCVAwUQOxIo
+BK7Kq3f+7KrtAQGn6gP/SBACdHakA4H//otpyESSrk4PmyOaYF0Kyok43Gee2mT+
+m9+jZ3jLcC0oav6iH+otL/lhk9t/JDM8LjD2kAkdWWoIvvuPyCx97gOzojIo0Ve2
+1wuxJTF/VIjwyOtE8FzE7p4tkc6EubVpeZkV9Pq9HFRBCUcyKJDLnF4tbstScLU=
+=OBLe
+-----END PGP PUBLIC KEY BLOCK-----
+
+
+pub 1024D/51898504 2001-05-29 Conor MacNeill <conor@cortexebusiness.com.au>
+sig 3 51898504 2001-05-29 Conor MacNeill <conor@cortexebusiness.com.au>
+sig 5F6B8B72 2002-01-11 Stefan Bodewig <bodewig@apache.org>
+uid Conor MacNeill <conor@apache.org>
+sig 3 51898504 2001-05-29 Conor MacNeill <conor@cortexebusiness.com.au>
+sig 5F6B8B72 2002-01-11 Stefan Bodewig <bodewig@apache.org>
+sub 1024g/D1ECBA5D 2001-05-29
+sig 51898504 2001-05-29 Conor MacNeill <conor@cortexebusiness.com.au>
+
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v1.2.0 (GNU/Linux)
+
+mQGiBDsTqygRBACiZckNdclTlQFonLaIKBFGhMy0KKByw0x8XA4iwdbCXuF6xNIc
+HIFHajJ74AHchQ4d8xtomBy6b8yvFgWVeaZensvn69BlLeqGdyeJRzfPt6TgRnzZ
+2eWhb0HXdG3JwxL/2BabDhHfs4YJOrgB/vhRFQku6oCMRiBPtJj2werD6wCg0/zp
+jacYTw6+CR+sVvneCNyySFED/R3j10c4RnR8djgv1jKT8CKPuHYraupI9INEe+I6
+7qWjtJ02GzvMO6TElAtUsf4aysu45GgwkwEBnuG6mYb3Pq0V2c5tJc2A3Tj3DrdR
+i3HUNwurbus76I0sPyyENPu12QPeC6mvWLEsxVJ9o0hRKFayGvYUmrwWK9UFLjvp
+p9cXBACDHgLn7MAVLqUdYhRrUj/M+GOUpvBikEgoJJrEUmb5X4+++dffMh5HBIO4
+5LA11qEKuM2xnKqOilP7NLYXz1Fe0ocqv0jsHB4SprFTTai7ma31uwuRQvCQXVv1
+yJ5CLqYda64h/UA2kmmR2dfopmvDogYEMz/HU5voozxe7BEI7bQhQ29ub3IgTWFj
+TmVpbGwgPGNvbm9yQGFwYWNoZS5vcmc+iFcEExECABcFAjsTqygFCwcKAwQDFQMC
+AxYCAQIXgAAKCRCBBGRPUYmFBDgIAKCZztXqKhK6kXOnoGy7opCNmWU0lwCgsPDa
+4m+ruW3ch0rfbqtR75S52R+IRgQQEQIABgUCPD6eTgAKCRCiEVrhX2uLcqCcAKCr
+1Wylqju9YjBi5Twej9ze69JFBQCeOaMgo6yjnkcV3PnVInLlaMwPr5q0LUNvbm9y
+IE1hY05laWxsIDxjb25vckBjb3J0ZXhlYnVzaW5lc3MuY29tLmF1PohXBBMRAgAX
+BQI7E6xMBQsHCgMEAxUDAgMWAgECF4AACgkQgQRkT1GJhQTY0ACgmZmKheHzjPJs
+5hybpyvnvEiPYqYAn2+ryxdtz8XyOMExGRmHNlhG7svsiEYEEBECAAYFAjw+nlUA
+CgkQohFa4V9ri3JYYACg1WN+NCptfKVP1mbrIa+0ajztsiIAnAn+m70iwRRFZCxr
+jcULoY5SjyTLuQENBDsTqy0QBACfsCxJ6iCtgX8zjlVtMsMfDqu72x5sYatWKn8c
+u+4Oj5mi0x6azZIhwCa+K3ihLVOyG1mCRnzztGTIxWYRhq3TESIVOfgm+NgLGrmA
+XUTFyCT+21TExLCpuVZKmUHsWXLxDtfQ1diPeQpiQ8+Fvb/4jLGFjFIrQ2VjtFQn
+kumkSwADBgP9H0bF4hdMuVEcSJ9imxSoJshcOOA3Vd2+YiCTZhBygWM49wY5jNos
+/DArIjNCE53IlOu/UtHB2jqkSqjF0soGYsUjeCWouiTP9hLuMKPjnqj9ryJPTDKz
+nTCZ4TuB5CtzrKTlWLmPCPpFsGqe4KjMeKg/mqGqjPKl97xgStK9N9GIRgQYEQIA
+BgUCOxOrLQAKCRCBBGRPUYmFBMM6AJsF3FFyZGEmbt9aGG1W/u0oI9mcLgCfQyJ+
+aalbspazea4J9zgi59SSwOM=
+=cBdR
+-----END PGP PUBLIC KEY BLOCK-----
+
+pub 1024R/697ECEDD 2000-04-06 Henri Gomez <hgomez@slib.fr>
+sig 697ECEDD 2000-04-06 Henri Gomez <hgomez@slib.fr>
+
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v1.2.0 (GNU/Linux)
+
+mQCNAzjsydwAAAEEAMpwFU/ci3/wR3ryCGp9Exr+Rx/hTQ7hWAJcVw8ejlBXlT4T
+yITlRUs0HGfRWxME2J55PuXXsIEPZzjfozNtvOyq8WlLlJ7iaiyWxVRoPJ25sSEj
+C9etm6wjj4E66ZgzuElZkm1m69uEsCHPPNuz1oQ/g1O+SmIVxIYirlxpfs7dAAUR
+tBxIZW5yaSBHb21leiA8aGdvbWV6QHNsaWIuZnI+iQCVAwUQOOzJ3IYirlxpfs7d
+AQFQyQQAj0D9G0hEL7SQGaSCkkoXwvamQw42N8+tNm+jfWHWdE4HAiVlhJmI2GyD
+sdcXVAcR8R7ILIRB5AY7a3bF+qMk0r+vO6oR878RKKn9AvtaAIOnrh6tr0tiPwf5
+XDUMySxIWJEF3SmJAy9Lq3bAl5GMzZCFHiS0NW2gtWgmr/u1RuM=
+=6l+I
+-----END PGP PUBLIC KEY BLOCK-----
+
+pub 1024R/397DCAD5 2002-07-03 Henri Gomez <hgomez@users.sourceforge.net>
+sig 397DCAD5 2002-07-03 Henri Gomez <hgomez@users.sourceforge.net>
+
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v1.2.0 (GNU/Linux)
+
+mQCNAz0i0UUAAAEEALXePN6IHne0W96YRMnR+4EXB6402QY5f8ZLcnSUZUH55Fb1
+qcZGBc3WRKlPiUvwBD+eVYgCpNSXF/H+oV1mawxNJN5XwqBEpfYmY8MRIPcqa61h
+bJc3LBSm1qNf05G5Cwxeed+OgVm0r1HBy6DAgDHAqNlkC8DZ/BVgqMA5fcrVAAUR
+tCpIZW5yaSBHb21leiA8aGdvbWV6QHVzZXJzLnNvdXJjZWZvcmdlLm5ldD6JAJUD
+BRA9ItFFFWCowDl9ytUBASNyA/458T84LUVhqq6Y9fPBAfcFMWY2kehuDWsQEXkO
+46XoK+AnFZCkKuyDLqPHchVUO5pK/gZYsDK/xJkfh3u4FTDTsecb9wFmIeyayVIN
+SI8o6l8EZzDX/PGwqEwzxHrbQkIgIktNn5ApIoazvdBpbkQfNj1vr2wWoMYPLAWM
+8xzecA==
+=UmZ8
+-----END PGP PUBLIC KEY BLOCK-----
+
+pub 1024D/307A10A5 2002-07-18 Henri Gomez <hgomez@users.sourceforge.net>
+sig 3 307A10A5 2002-07-18 Henri Gomez <hgomez@users.sourceforge.net>
+sub 2048g/862B8F70 2002-07-18
+sig 307A10A5 2002-07-18 Henri Gomez <hgomez@users.sourceforge.net>
+
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v1.2.0 (GNU/Linux)
+
+mQGiBD02vbERBAC1v8fR6gjERpaz4UMfdy0hRVWCPSbOdF+Swm/IenjVzErco6zb
+MTa13umUNrDPBy/tTWiCCZrOnqi7fgDzWqPEqrXJjKAFVLEWE6MmKylPPEPG1/bm
+idkNGERSAZduvhKv777PzvEJJ/8eGe3wy/O8NbgIjCPtr4UklwCZS8cFuwCg8oMO
+UdT8qZRtzdxdAyu1m5fUb+MD/3IKJYWXsdtb6iBphCU4f/BoyjVC9EZJ1ywLuiVM
+siKbuaDUaXU9nWcbNKv+fx8uZ1NaadpfLokqqhnWcpnSiqw8HNR7SwsF1D33rkXK
+O4FSuVss/tIoqGdWFcJyPkP4yP5shxqR335narVw2vDa0+BiWkALbA2qVsSIdZDB
+LeFZA/47AMBS0U2BRk2rQT8LmMuFl7mR+wNBM4n7FUGdxsGn3TcYd4pXTNrEQPrV
+YNdooKlikgGk4hgFnIFX09Spmimqgq0goFue81rttVdZZ4uep8dTghY6gwmvcOxX
+jATbhWStBhdu9B35kzfHc+1QihD5Z94u4uyWIVBIzikcdiY8LbQqSGVucmkgR29t
+ZXogPGhnb21lekB1c2Vycy5zb3VyY2Vmb3JnZS5uZXQ+iFcEExECABcFAj02vbEF
+CwcKAwQDFQMCAxYCAQIXgAAKCRAZMdaEMHoQpYijAKCCP68ndU/kTXR9XAKLvibC
+3S8+1QCfUFQYte3Jo+MHKaWjsu9JGptRzo+5Ag0EPTa93RAIAKlsRJ5gOGTFsmaR
+W9k6MIh4c/MCy7J7HUxT5xTdHROa+3zUh+FAE/JaOx9ZtZtH863DFHA8cP4L+tpi
+PjBT6g2E94dwGcuH/OiSSCT4JSBukbGbOuLLdmFXqUl8+4gsL90Xal67FtNLwyLG
+1n7geLir0byD+OT7VLA5w+6G0NOpJEveV/FIa2qLgdRZ8vz73ybgMh18hBUrUmro
+jncp0rln2VU7VCH1C2aClKm7kK4mGAjIFIzKbguK+kM3b8NDHmXKpT6syyCtIM3h
+prkV1TUCAFqLI32aSdlTN79lpeA2zDga9k4/4X/RDHsFpRN2neRFGTNUtuUgYpQQ
+E5zWBmMAAwUH/RiGxyeBsad923IwE1+GAjxFl2tqF9xWk0J6yTnSK4nfhYAE9evV
+jwDEok9jRl4ILCcXx6YN/d/lWNuSbARKHz/3hLiTouPpwd3SSJ8is2x9PgpJz5JX
+cD0y1SkbPLvs3jH3ZmdcxZpuAmJeI/typqFKK5pWP44oXIH+XH/8nWDtmLEBkgKQ
+/ATQWenMTmZ6MIJ6aWKWGkO9QS6iYRz3PPPGQ1O8W02CeprM2wBtlb8J1Z3RxNhM
+rZcg/1Qi3V3D1HI4zw6tAFmDeBb8J4PaBQzqlhzx2EBTbfwNPhV8AlPvpxHEeGGn
+v+O1yhZr33SnyZdINNoNDn+owVMdmkobe9GIRgQYEQIABgUCPTa93QAKCRAZMdaE
+MHoQpRsTAJ4qst3MhLm48fBAEnzuzi/BIKr+AgCfYaCB/AvPoncQbHc8BcNGRimR
+P9A=
+=hQhz
+-----END PGP PUBLIC KEY BLOCK-----
+
+pub 1024D/EDF62C35 2002-04-10 Magesh Umasankar <umagesh@apache.org>
+sig 3 EDF62C35 2002-04-10 Magesh Umasankar <umagesh@apache.org>
+sig 3 5F6B8B72 2003-03-07 Stefan Bodewig <bodewig@apache.org>
+sub 1024g/B5FFC53F 2002-04-10
+sig EDF62C35 2002-04-10 Magesh Umasankar <umagesh@apache.org>
+
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v1.2.0 (GNU/Linux)
+
+mQGiBDy0ebgRBADuKIKD8PuJ4wKEV1h2AprwJjxCRx8vn48XNwfLZuvhw8cpArtK
+rZwhoGPPUPEEXgtTNerlKq4VwpAwcnvRz7oC/7aWkUbcR2sAyhfe2scohwPgw7Xv
++isWC0NDPdrxvXG/PUOG/cnELunr51ymybBqBxUd2gMhYIxPo67D+YPYLwCgwcZp
+yc/6kJa116ESWHrti342GD8D/1srpnRs9CiS1DQF1uZ1wW4vzj4VD61tKsjdWD8D
+V573R22iMDLSj4oMB536WxUH7snz8XsAKm/peqJ6G9m0smtmWA1ago5yzQj70WqF
+xzWBhHn2I/YfAQ8pb2s9q1lClj8elnCxT65L27ydBAZteejb2VqjtQ6iGy86PUT2
+wRUvBADZmoV1eIZJEM5NnxBv1EtvRYZtIQEzZ8dO2A1LOS7qlVr8IypljNPLGhzX
+VHNvVsjC9QMUSWeBsDedvQHQ3hJpIMnTI32XE1V4gX06gfVTZdhf2fLTtwnsHZp0
+oumqshGDVRhNJJdDYLikxWOxOfkNveKEqJFvtuBR+ZqqluQKebQlTWFnZXNoIFVt
+YXNhbmthciA8dW1hZ2VzaEBhcGFjaGUub3JnPohXBBMRAgAXBQI8tHm4BQsHCgME
+AxUDAgMWAgECF4AACgkQ76Pnee32LDWSRwCfeASWXvpdt7bSFPMtszU/7uPEktsA
+n23mYUN5WKJA1ZreW+0CcZ2ESnOviEYEExECAAYFAj5ogYgACgkQohFa4V9ri3IW
+YACgsxGig0PL0M86rJsA/IpXjBdg3ysAoJzsoUZ/7s2BxDfzF/FRTVIzS+TMuQEN
+BDy0eb8QBACBVb9YDJRp9Irzmq71Jf9FIPw+4g/cWpF3t/Eb7eSzMcOvTAXyNIWz
+aaOjHre7lFctHfq8ls/6gR7uqajiAnfQcfTcu7pp+F5KsU0Embt83SFzZ3aoJwET
+mB/LqUyrrGDiue3lU+flJO7UmcsRvtk0+BDkyCeB9HgfdpXbBLCyuwADBQP+PNxX
+4e1tg3ZJo/xNEnD2Re3HjmQRrr0RYJLUGjgQrAEONSgowx3IW8/JssmNJVjnYm0q
+jSKsb8rergCFJhPNZ8Dd/k00pKcrq+IN6j7WTYLqPce87zrGAZUtmDwDSp5mxy5E
+xWJJxsgBPk4YBQLzJt21A3BgK/i24Sze2VLbaZuIRgQYEQIABgUCPLR5vwAKCRDv
+o+d57fYsNa8xAJ4mLfonZbd64+YY9rfvhIh3Vsl3AACeLPPKtma2K6XCfhTBEDnj
+hzSr4vo=
+=lBfF
+-----END PGP PUBLIC KEY BLOCK-----
+
+pub 1024D/5F6B8B72 2001-05-28
+uid Stefan Bodewig <bodewig@apache.org>
+sig 3 5F6B8B72 2001-05-28 Stefan Bodewig <bodewig@apache.org>
+sig 51898504 2002-01-11 Conor MacNeill <conor@codefeed.com>
+sig 3 F88341D9 2003-03-17 Lars Eilebrecht <lars@eilebrecht.org>
+sig 3 2261D073 2003-03-17 Astrid Kessler (Kess) <kess@kess-net.de>
+sig 21D0A71B 2003-03-17 Dirk-Willem van Gulik (http://www.anywi.com/ - Senior partner) <dirkx@anywi.com>
+sig 75A67692 2003-03-18 Erik Abele <erik@codefaktor.de>
+sig B3B2A12C 2003-05-20 ct magazine CERTIFICATE <pgpCA@ct.heise.de>
+sig 3 8103A37E 2003-04-04 Andre Malo <nd@apache.org>
+sig 3 5F6B8B72 2001-05-28 Stefan Bodewig <bodewig@apache.org>
+sig D6298F01 2003-04-27 Paulo Henrique Gaspar Jorge <pjorge@asatnet.com.br>
+sig 0CAA68B4 2004-11-11 Patrick Rentsch <patrick.rentsch@suissimage.ch>
+sig 2FE28BCF 2005-07-01 Harald Wilhelm (HAWI) <Harald.Wilhelm@hawi.de>
+sig 5793498F 2005-07-21 Tim Ellison <tim@ellison.name>
+sig E4136392 2005-07-21 Noel J. Bergman <noel@apache.org>
+sig 8408F755 2005-07-21 Christian Geisert <chrisg@apache.org>
+sig 2 FC243F3C 2005-07-20 Henk P. Penning <penning@cs.uu.nl>
+sig 3 EC140B81 2005-07-20 Dirk-Willem van Gulik (http://www.anywi.com/ - Senior partner) <dirkx@anywi.com>
+sig 3 EE65E321 2005-07-20 Martin Kraemer <martin@apache.org>
+sig 3 A99F75DD 2005-07-21 Rodent of Unusual Size <coar@php.net>
+sig 3 3642CB4B 2005-07-20 Martin Kraemer <martin@apache.org>
+sig 3 302DA568 2005-07-21 Rodent of Unusual Size (DSA) <coar@Apache.Org>
+sig 3 2C312D2F 2005-07-21 Rodent of Unusual Size <coar@php.net>
+sig 3 CC78C893 2005-07-22 Rich Bowen <rbowen@rcbowen.com>
+sig 3 E2D774DF 2005-07-22 Sylvain Wallez <sylvain@apache.org>
+sig 3 E04F9A89 2005-07-22 Roy T. Fielding <fielding@gbiv.com>
+sig 3 015AFC8A 2005-07-22 Bertrand Delacretaz <bdelacretaz@apache.org>
+sig 3 87315C31 2005-07-23 Raphaël Luta <raphael.luta@aptiwan.com>
+sig 3 E41EDC7E 2005-07-24 Carsten Ziegeler <cziegeler@apache.org>
+sig 3 F39B3750 2005-07-24 Colm MacCarthaigh <colm@stdlib.net>
+sig 1CD4861F 2005-07-25 Eran Chinthaka <chinthaka@apache.org>
+sig EA1BA38D 2005-07-25 Ajith Harshana Ranabahu (Made at Apachecon 2005) <ajith@apache.org>
+sig 333E4E84 2005-07-26 Chathura Kamalanath Herath (Apachecon Europe 2005) <chathura@apache.org>
+sig 152924AF 2005-07-29 Sander Temme <sander@temme.net>
+sig 3 9C85222B 2005-07-24 Henning Schmiedehausen <hps@intermeta.de>
+sig 3 9978AF86 2005-07-25 [User ID not found]
+sig 3 2A623F72 2005-07-25 [User ID not found]
+sig 3 F8EA2967 2005-07-26 [User ID not found]
+sig 3 C152431A 2005-07-27 Steve Loughran <stevel@apache.org>
+sig DE885DD3 2005-11-25 Sander Striker <striker@apache.org>
+sig CE419C8F 2007-01-05 Upayavira <upayavira@odoko.co.uk>
+sig E222DE4F 2007-05-02 Mathias Herberts <Mathias.Herberts@iroise.net>
+sig 911203E4 2007-05-02 [User ID not found]
+sig F12F6072 2007-05-05 [User ID not found]
+sig 3 990ED4AA 2007-05-02 Knut Anders Hatlen <kahatlen@apache.org>
+sig 3 311A3DE5 2007-05-05 Ruediger Pluem <rpluem@apache.org>
+sig 3 88817402 2007-05-06 Thomas Vandahl <thomas@vandahl.org>
+sig 5F298824 2007-05-06 Simon Pepping <spepping@leverkruid.eu>
+sig 4CEED75F 2007-05-06 Nick Burch <nick@gagravarr.org>
+sig 4358C584 2007-05-06 Vincent Hennebert <vhennebert@apache.org>
+sig 0B7E6CFA 2007-05-06 Sami Siren <siren@apache.org>
+sig 3 01530235 2007-05-02 Luc Maisonobe (SpaceRoots) <luc@spaceroots.org>
+sig 40581837 2007-05-08 Nick Kew <nick@webthing.com>
+uid Stefan Bodewig <stefan.bodewig@freenet.de>
+sig 3 5F6B8B72 2003-03-07 Stefan Bodewig <bodewig@apache.org>
+sig 3 F88341D9 2003-03-17 Lars Eilebrecht <lars@eilebrecht.org>
+sig 3 2261D073 2003-03-17 Astrid Kessler (Kess) <kess@kess-net.de>
+sig 21D0A71B 2003-03-17 Dirk-Willem van Gulik (http://www.anywi.com/ - Senior partner) <dirkx@anywi.com>
+sig 75A67692 2003-03-18 Erik Abele <erik@codefaktor.de>
+sig B3B2A12C 2003-05-20 ct magazine CERTIFICATE <pgpCA@ct.heise.de>
+sig 3 8103A37E 2003-04-04 Andre Malo <nd@apache.org>
+sig 51898504 2005-06-21 Conor MacNeill <conor@codefeed.com>
+sig 0CAA68B4 2004-11-11 Patrick Rentsch <patrick.rentsch@suissimage.ch>
+sig 2FE28BCF 2005-07-01 Harald Wilhelm (HAWI) <Harald.Wilhelm@hawi.de>
+sig 5793498F 2005-07-21 Tim Ellison <tim@ellison.name>
+sig 8408F755 2005-07-21 Christian Geisert <chrisg@apache.org>
+sig 3 EC140B81 2005-07-20 Dirk-Willem van Gulik (http://www.anywi.com/ - Senior partner) <dirkx@anywi.com>
+sig 3 EE65E321 2005-07-20 Martin Kraemer <martin@apache.org>
+sig 3 A99F75DD 2005-07-21 Rodent of Unusual Size <coar@php.net>
+sig 3 3642CB4B 2005-07-20 Martin Kraemer <martin@apache.org>
+sig 3 302DA568 2005-07-21 Rodent of Unusual Size (DSA) <coar@Apache.Org>
+sig 3 2C312D2F 2005-07-21 Rodent of Unusual Size <coar@php.net>
+sig 3 CC78C893 2005-07-22 Rich Bowen <rbowen@rcbowen.com>
+sig 3 E2D774DF 2005-07-22 Sylvain Wallez <sylvain@apache.org>
+sig 3 E04F9A89 2005-07-22 Roy T. Fielding <fielding@gbiv.com>
+sig 3 87315C31 2005-07-23 Raphaël Luta <raphael.luta@aptiwan.com>
+sig 3 E41EDC7E 2005-07-24 Carsten Ziegeler <cziegeler@apache.org>
+sig 3 F39B3750 2005-07-24 Colm MacCarthaigh <colm@stdlib.net>
+sig 1CD4861F 2005-07-25 Eran Chinthaka <chinthaka@apache.org>
+sig EA1BA38D 2005-07-25 Ajith Harshana Ranabahu (Made at Apachecon 2005) <ajith@apache.org>
+sig 333E4E84 2005-07-26 Chathura Kamalanath Herath (Apachecon Europe 2005) <chathura@apache.org>
+sig 152924AF 2005-07-29 Sander Temme <sander@temme.net>
+sig 3 9C85222B 2005-07-24 Henning Schmiedehausen <hps@intermeta.de>
+sig 3 9978AF86 2005-07-25 [User ID not found]
+sig 3 2A623F72 2005-07-25 [User ID not found]
+sig 3 F8EA2967 2005-07-26 [User ID not found]
+sig 3 C152431A 2005-07-27 Steve Loughran <stevel@apache.org>
+sig DE885DD3 2005-11-25 Sander Striker <striker@apache.org>
+sig E222DE4F 2007-05-02 Mathias Herberts <Mathias.Herberts@iroise.net>
+sig 911203E4 2007-05-02 [User ID not found]
+sig F12F6072 2007-05-05 [User ID not found]
+sig 3 990ED4AA 2007-05-02 Knut Anders Hatlen <kahatlen@apache.org>
+sig 3 311A3DE5 2007-05-05 Ruediger Pluem <rpluem@apache.org>
+sig 3 88817402 2007-05-06 Thomas Vandahl <thomas@vandahl.org>
+sig 4CEED75F 2007-05-06 Nick Burch <nick@gagravarr.org>
+sig 4358C584 2007-05-06 Vincent Hennebert <vhennebert@apache.org>
+sig 0B7E6CFA 2007-05-06 Sami Siren <siren@apache.org>
+sig 3 DE8884A0 2007-05-07 Xavier Hanin <xavier.hanin@gmail.com>
+sig 3 01530235 2007-05-02 Luc Maisonobe (SpaceRoots) <luc@spaceroots.org>
+sig 40581837 2007-05-08 Nick Kew <nick@webthing.com>
+uid Stefan Bodewig <stefan@samaflost.de>
+sig 3 5F6B8B72 2005-05-31 Stefan Bodewig <bodewig@apache.org>
+sig 51898504 2005-06-21 Conor MacNeill <conor@codefeed.com>
+sig 2FE28BCF 2005-07-01 Harald Wilhelm (HAWI) <Harald.Wilhelm@hawi.de>
+sig 5793498F 2005-07-21 Tim Ellison <tim@ellison.name>
+sig 3 EC140B81 2005-07-20 Dirk-Willem van Gulik (http://www.anywi.com/ - Senior partner) <dirkx@anywi.com>
+sig 3 EE65E321 2005-07-20 Martin Kraemer <martin@apache.org>
+sig 3 A99F75DD 2005-07-21 Rodent of Unusual Size <coar@php.net>
+sig 3 21D0A71B 2005-07-20 Dirk-Willem van Gulik (http://www.anywi.com/ - Senior partner) <dirkx@anywi.com>
+sig 3 3642CB4B 2005-07-20 Martin Kraemer <martin@apache.org>
+sig 3 302DA568 2005-07-21 Rodent of Unusual Size (DSA) <coar@Apache.Org>
+sig 3 2C312D2F 2005-07-21 Rodent of Unusual Size <coar@php.net>
+sig 3 CC78C893 2005-07-22 Rich Bowen <rbowen@rcbowen.com>
+sig 3 E2D774DF 2005-07-22 Sylvain Wallez <sylvain@apache.org>
+sig 3 E04F9A89 2005-07-22 Roy T. Fielding <fielding@gbiv.com>
+sig 3 87315C31 2005-07-23 Raphaël Luta <raphael.luta@aptiwan.com>
+sig 3 E41EDC7E 2005-07-24 Carsten Ziegeler <cziegeler@apache.org>
+sig 3 F39B3750 2005-07-24 Colm MacCarthaigh <colm@stdlib.net>
+sig 1CD4861F 2005-07-25 Eran Chinthaka <chinthaka@apache.org>
+sig EA1BA38D 2005-07-25 Ajith Harshana Ranabahu (Made at Apachecon 2005) <ajith@apache.org>
+sig 333E4E84 2005-07-26 Chathura Kamalanath Herath (Apachecon Europe 2005) <chathura@apache.org>
+sig 152924AF 2005-07-29 Sander Temme <sander@temme.net>
+sig 3 9C85222B 2005-07-24 Henning Schmiedehausen <hps@intermeta.de>
+sig 3 9978AF86 2005-07-25 [User ID not found]
+sig 3 2A623F72 2005-07-25 [User ID not found]
+sig 3 F8EA2967 2005-07-26 [User ID not found]
+sig 3 C152431A 2005-07-27 Steve Loughran <stevel@apache.org>
+sig DE885DD3 2005-11-25 Sander Striker <striker@apache.org>
+sig E222DE4F 2007-05-02 Mathias Herberts <Mathias.Herberts@iroise.net>
+sig 911203E4 2007-05-02 [User ID not found]
+sig F12F6072 2007-05-05 [User ID not found]
+sig 3 990ED4AA 2007-05-02 Knut Anders Hatlen <kahatlen@apache.org>
+sig 3 311A3DE5 2007-05-05 Ruediger Pluem <rpluem@apache.org>
+sig 3 88817402 2007-05-06 Thomas Vandahl <thomas@vandahl.org>
+sig 4CEED75F 2007-05-06 Nick Burch <nick@gagravarr.org>
+sig 4358C584 2007-05-06 Vincent Hennebert <vhennebert@apache.org>
+sig 0B7E6CFA 2007-05-06 Sami Siren <siren@apache.org>
+sig 3 01530235 2007-05-02 Luc Maisonobe (SpaceRoots) <luc@spaceroots.org>
+sig 40581837 2007-05-08 Nick Kew <nick@webthing.com>
+sub 1024g/24774157 2001-05-28
+sig 5F6B8B72 2001-05-28 Stefan Bodewig <bodewig@apache.org>
+
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v1.4.2 (GNU/Linux)
+
+mQGiBDsSIk4RBADSCj6rUjV64tYCGT1DYKYR7GthyWpNdGHSYLbETBcDatAe1dzQ
+5NsCgfrlybfyeY+y1lxr3T9bqf6zJWDw/718wff96qmmv1qzexSYtmIrj+h53V82
+EXwWOFuYMJisuxdT940iQzosm3GOv4MJdEg3oI2SgfEyRQQ6vO4Ob5rHDwCg5taZ
+nrHOrXx2dIGHxpxRZ0SUl30D/jmtttFjYOQ3LBMriikz5mh2sK3ZnoSRF4o5O0zW
+Ve6e2SFXOEjVjImKsH6KCbdQNelrAdgiyOoXClyQKsQ27pncbdWo6bO0E3POJZVm
+XaeW7iudHVr63rU5PViXObIQrdQl0D59j5brKj4vdlTyUw8kaHPvbKPDEOwvZq4Y
+LJQ5BACA1YilTeXRJqwFsNlpcxCHwlULD4QUVP496prQWf1B7Z6g0KvLGrQsO0Vn
+Jcn+fEqukysTJixSXCPebosltd4RalJIupVYkp4w6MJ7biaDAlLuNhDcI/AiXTmV
+dXUedVXIaM8I3Ne23gucwbAyc0Hvb+3cSAKRhl/azFQhuHBvlrQjU3RlZmFuIEJv
+ZGV3aWcgPGJvZGV3aWdAYXBhY2hlLm9yZz6IaAQTEQIAIAIXgAIZAQUCSgkegwUL
+CQgHAwQVCgkIBRYCAwEAAh4BABIHZUdQRwABAQkQohFa4V9ri3IWMwCghs0wCe4g
+GMPBq6jtBXK46e4aHKIAoNn+9NX6NlhF04qaHyDBhXK2HMmuiEYEEBECAAYFAjw+
+1Y8ACgkQgQRkT1GJhQSdkgCeM6RDHUF/E334TtiLPgw7GpmNJSkAoNCLQCW/9VHr
+V+ZHsodnXUnaD4dIiJkEEwECAAYFAj513wwACgkQPo+38viDQdknZAPlHNiMnR+L
+Uavo2yOYiJT+W9+8+qNs2grYDZ+WSYujaWT2NJrUCYXQRM6gKDyFlkcJvHI9lF2y
+YMkVetllZVN1TJkeEdtbHncNHcdq+ZUQR0NkFKTF9d1K7UI2rfWxt1y6a13TcUjp
+JXzbtw/OXX9EZSI6QQt4rSFlvci9J3mIRgQTEQIABgUCPnXawQAKCRDu0eo5ImHQ
+c0W4AJ9vuq4wlkc6TmmmZPF/gZVLluHcTgCeItrnvzyS11xkIETk6v4b7K4gaiiI
+PwMFED51qhr9b4jGIdCnGxECRAUAoOaVZW5CdZ9oYr3PwI/i8RJN+JfJAKCmd/XI
+lYOCpa9Qc4C855pM8NFw6YhGBBARAgAGBQI+d6QQAAoJEBU/oM11pnaSL+sAn1DT
+HmbhITeEw0ZSgyBLQw2ZhcM5AJ0ZrRBbZ9lbgHXBKOJQiLpWBj4XsYhGBBARAgAG
+BQI+yi6WAAoJENvSRfyzsqEsF/AAoNXq7Cp/0AwEmWvhoTjmtY6eVYB5AKCMFhBU
+dYWNXVyalPTq8ThswNUnr4hGBBMRAgAGBQI+jc4sAAoJEMppOXSBA6N+kUoAn1Nj
+6YqarQg0sL2KrFsQROM3A6fSAKCyl40SpfVJSO33fYuPci9dHp+QCIhXBBMRAgAX
+BQI7EiJOBQsHCgMEAxUDAgMWAgECF4AACgkQohFa4V9ri3IsngCfbIpJDWj6UgXY
+7rBH8To12BgB+RIAn3jw72WJzplAtShVTmuMlRFS+FUNiEYEEBECAAYFAj6sazwA
+CgkQqywx6dYpjwFkeQCeOkJrnO5r2hWDhX4ACPPLObZvXLIAnR0VHAgkEH1W/t7B
+4zdDYdBBZrd5iEYEEBECAAYFAkGS8mMACgkQ5BNhMwyqaLQs9ACgio5zJcieYLpp
+igvSYLBfubUVrXUAnRKZJ6MACpH6fpoz2vkc2dh69tbSiEYEEBECAAYFAkLFMoEA
+CgkQm/IjRS/ii88aCQCfd1cIawDqpkYU86f3JEjcN85ntFcAni0m8WR6s+bkh3fd
++EIrSRsru3uQiEYEEBECAAYFAkLfRQIACgkQQeoJoFeTSY8XxQCdFd+XEWqyDkCx
+37gaIQAG4dHpwiUAoOZ/K5OHyTJCNFaBUDtpCh7hL8TPiEYEEBECAAYFAkLfkncA
+CgkQAQVmvOQTY5L3SgCgiEi5/1vYvJrKoAdl0hRWU57ieUIAn2n08BQfMZJQ439a
+NW/CnIK8jPBPiEYEEBECAAYFAkLgNdAACgkQc84u+4QI91XdNQCgoBB1ebohIfli
+nAPlvI37pFHuu0MAoJ4yMtbKZMaq0xIBnxV9c5uu99tGiEYEEhECAAYFAkLerWMA
+CgkQi5YpQ/wkPzxD7ACgqKnyeb/fjVS8vov4FePxeLju4msAn1SCGaiF9gEf+qIa
+ZUnjcT7JDJ96iJwEEwECAAYFAkLerG8ACgkQMaY9luwUC4Ea9gP/WON+0xIWOvWP
+7mKkg/+X0ukW+mbjE426qKtG/B0vNrTKpElmz8ttR+oajqbg20LazoEUuA9ZXjLP
+fsdWA+vFkxgV6qIdtxYPMamPm7ytEBOmgMowYXUftGteqM5fxLlceHiwdUlynG2f
+mtMqvPnd2OCezSFRx3W6nvAiIjoLZpCInAQTAQIABgUCQt7H0wAKCRA34/Rf7mXj
+IcAUA/4nDlQbnToSSDOZkFj1CoGL8TjsVgzrO3r3S3x38uQQTFAE/AGBY4mtHgNc
+YmiJaC2hN1Y+mlEGu/80Rjv185ZfJsFEerU6Y/9tRJJ1So9AAe5AmvGpD9ysXae5
+geB+k+epIMSuf9WMeTRUCbQs9ufGZLV5a8jqstv+btcrzNaY9oicBBMBAgAGBQJC
+32x4AAoJEJrNPMCpn3XdRBkD/iNi0Y6A3afDG9ZL/K4JrOPgHUFWC/DgAEBme4AY
+62agUsT0uXlz+Mu1Ps2E0t26ejScuVMMvqpXg7iJ2+3yKzsnX0ySEXW6/696XEpe
+3TFn1iVOmMElPKxakn3t/jr6SDepo9jqD5P5CJR4GsDsG3iKIisWdDf81ZXpf86y
+7A5eiEYEExECAAYFAkLeuuUACgkQMsnkzjZCy0vmSQCdHGC6jOEVo96yyospTq7b
+L+EEeioAoNMKIZy5qFLXXZbSNvsj7mDRg2c8iEYEExECAAYFAkLfbHoACgkQUI6u
+xTAtpWhYhQCaAvqVBsTX5s4c+sTOo06BNMdzHIUAoIwpThAKq936Szy/3Gfv8K3g
+s5NOiEYEExECAAYFAkLfbHwACgkQ3bpkuiwxLS9z8ACfYeocOK4J204xwbXgEdUJ
+QyvHK2UAoKz2AF1I2b8Ebu7vTUZLNFV1QMtwiEYEExECAAYFAkLgyTgACgkQXP03
++sx4yJNbEgCfRcj6QKHVHQtYVXdCYKUbrj97wAoAnimqV15cvz1siDjUK9K/aTsk
+GwajiEYEExECAAYFAkLg7MsACgkQybWm7OLXdN8UoQCdFfqef8My1xhn6mLd9WTL
+LaIewTQAnRXGh/Af4hVG0KwtZcJEA464nCoJiEYEExECAAYFAkLg7TwACgkQW5aA
+EOBPmol+JwCeLxZjKNisjgP4AxV5BCKR+5SU9NoAoIwPF/7B2NmGNR0t3EZze8wp
+NhQ0iEYEExECAAYFAkLg7V8ACgkQN/aP9QFa/IqerACfafKJi4s8LYV2JxNfQKHg
+mRXzeIIAoNBHOzukDCdxIvmYJfamItnCP45giEYEExECAAYFAkLiYm8ACgkQbZiN
+F4cxXDH8HwCgq8P29CwMX7PKhRmY3T32APsOaMEAnjdd/WvzVBFtTcJFWkH6iF4L
+8EQpiEYEExECAAYFAkLjVb4ACgkQEy5J1OQe3H56DACcDPfWLO5cDkeKFCvIP8mc
+4p4KkfkAoJITROldIRxXqUiML1oTJxieuHJfiEYEExECAAYFAkLjZNoACgkQdcqi
+o/ObN1CItACgsJhqBxeZTaSrRVNk3aj6ciAJrgEAoIxPXYTvIpnWBr4/WMbN0jpV
+0TGEiEYEEBECAAYFAkLkbxIACgkQjON2uBzUhh/gZQCbBpIqkCEuIbd6tqChz3Pz
+cIGiZbgAnjluBFHl4l1/NHtP9fEYCgl8nbCviEYEEBECAAYFAkLkkr4ACgkQBJE0
+Quobo42f+QCgjtO6EOdDRiruCi6gKvwM1a2eRwcAn0XUELm5AZezL5E0rEfIM2FB
+iMi5iEYEEBECAAYFAkLlwh0ACgkQYRlqLjM+ToS9pwCfUEgO834XY/clWzkw/VLB
+fe7MLZQAmwdz0nleOHYWFBrnYgEz53d4MxUPiEYEEBECAAYFAkLqY/QACgkQsr68
+QBUpJK/oMQCfc7M9KpApCWW7eE22PlLoN1sPK+4AoJdwE8TsDM2Pmehk9K+uHIx6
+FoRviEYEExECAAYFAkLj7WcACgkQMoZOQZyFIitClACfWpH0+V/N6vuucWZ7bsMm
+2BcmM3oAn3fF5qqovlog4/PcgvKCToNEF8uWiEYEExECAAYFAkLlELcACgkQUnkv
+r5l4r4YUZwCgg7vJpDpUXnuNvgc5RHgG7UYhRQYAoIEKHsrswh6XzVn5yQRkfjdB
+/A0OiEYEExECAAYFAkLlEaQACgkQa3OhBipiP3JA4QCffb8NgQssOQXaVR0dSwPC
+eU2nQPUAn15EAjykVZsUi2tZWqEM08SNOKI9iEYEExECAAYFAkLmmWIACgkQaOuM
+dvjqKWd7AQCbBpwyitQ77kd9KIT6y95Im1vmWt8AnAnkNTBctVtMfwddYTG+xLka
+OllOiEYEExECAAYFAkLnYVAACgkQbpR1lMFSQxqIRACffQqUXTgOa4hyHYQBUwrl
+GEqmWt4AnRMXVGhd47loS27MmiEiWwDlkNjJiEYEEBECAAYFAkOHn54ACgkQZjW2
+wN6IXdOr9gCgh2fn26W0DSL5WZATvvQkwZeJNiMAnR6+0AlUK8uFSFIVhl+RZMnY
++XFwiEYEEBECAAYFAkWdnk0ACgkQIYJJVs5BnI/0SgCeKCw39INy9ISFunlAojYg
+SInHfokAn2vU8q4JNjg13qNeclZN9kmN9mbWiEYEEBECAAYFAkY44sMACgkQFUWz
+/uIi3k+qvACffppBpoY82MEvDV7c4/6cjw544CQAoJAPCdZA/LRqICJm0iFbDrwh
+sSb6iEYEEBECAAYFAkY4558ACgkQY9CtrpESA+QrAACglRB/VdEmovbyWdMDmsTd
+yw4kha4An0uKwZeKHfBR3cC2s7MvqqmMoz9jiEUEEBECAAYFAkY8kyoACgkQmHDv
+8/EvYHIkCgCYgXQZTJ8VmHwSX3pXOxnMhp7mbACeIPXwcPvmfP709nfgQ8/GpT2z
+9ISIRgQTEQIABgUCRjkasQAKCRDh4fKwmQ7UqhZKAJ9iraDBstzeXPMtst3x+ZXd
+LQm7cgCfWDDgaQOa8CoM5/+7WCtkyasP6BiIRgQTEQIABgUCRjxQRwAKCRBMBCgY
+MRo95eP4AKCuEQU6fjPy/cPEiqhGH23J2YEr7gCfS8vBTEU4sRbOomTEuINPxb96
+OZmIRgQTEQIABgUCRj2gkgAKCRAuuUaCiIF0AgOBAJ0bJmFzA9WkG5FmfaP4ieG9
++SCbXACgw+2wcOA/B94LKRtjhJT6j6zSiDmIRgQQEQIABgUCRj4VvwAKCRA+Km/C
+XymIJIvcAJ9QSE4mCQldVnpbYwLTCk+xHDqhcQCggT9P3/rHIzIvv1tJ+A1ZJPvX
+OcqIRgQQEQIABgUCRj3WeAAKCRD1wmAWTO7XXwpbAJ4mr2IxFtx0ppkefxx0l0TJ
+6cFkrQCdEFbc+aMxRKhK9SCAWi3mq1UqEWiIRgQQEQIABgUCRj31AAAKCRCgctTQ
+Q1jFhByKAJ9SIielTuD3StxPQpBkAkYP6Ld88ACgg1oPX9ryJA7YuhMD7byXQsET
+zD+IRgQQEQIABgUCRj4FxQAKCRACpaYFC35s+k/GAJ9/VDyw2vNzk1xjcu/QZCa3
+gGI2zgCfeG8klJ78bAGknzxBlK3XtmoNqASISgQQEQIACgUCRjj3hAMFAzwACgkQ
+c92MFgFTAjVJogCeL+3FTTVR5snJx9qbGQsgv23ZaT0An2Hy1CcXVklcYBF7Lbnb
+Agbe1HpfiEYEEBECAAYFAkZAtkMACgkQbQvHOkBYGDePegCbBe6rmz9/kYDV7w5p
+vwnugVsvbiEAniTfLW7NW8z1SRBWf6lMH3clGAs8iEYEEBECAAYFAkZMRFMACgkQ
+HyEjw2vYcqB22gCg1np1JYFYPqCB3ekZts3K+pn7RkwAnRWd6HmtjRolZdrZfkqQ
+DJKmd5zviEYEEBECAAYFAkZMfQEACgkQD0UKJmIQv8DJYgCfW0C9rDAToLU+0BKL
+YCiWwtFJ98MAn2HvQ3CDhv8WTm+av36lETLqhjnfiEYEEBECAAYFAkZSb1kACgkQ
+MsHW7w8UO8GGZwCg0l2T1O/OpOECXs/vYE2649wNTaYAoLrUpLKYev8uHAfc53lZ
+6LE0h1T0iEYEEBECAAYFAkZSb2AACgkQy66+OaRsTKHZbwCdFSloWJh3uuTLk87a
+St4uYeZrKToAoIrN7epZxeu9n9e6hqVOLz85zc3TiEYEEBECAAYFAkZe1aoACgkQ
+mobXzNGq6mD+cwCg3k4BRrRi6pjrY/UggHjhiHWSD1YAniDQn1MVB620Ik2cVL7h
+R1V0ZL6biEYEEBECAAYFAkalTCwACgkQOb5RoQhMkROqQwCdHhIdklVR341azVFB
+O6aGArSOP2QAn0WtSIiqaLTEQ57+ir62FxRYBQdWiEYEEBECAAYFAkatzFQACgkQ
+M81nM69exFIdRgCfSGft6KIZ+CTEPIGr8lp8oOpNaHMAn1NCXZTJOW+r0G5ply4h
+lu8UXC4AiQEcBBABAgAGBQJHwH2YAAoJEBllhVDDEQYRZ4cH/3XnLW6UAdDd4k0x
+l2lUAj9gB7ITUbejCwvnFqUyKAE9P38boBHNfc6cliQUOz4ITWDPhiinbjNnJHgl
+p9vK0o4R/tFFyGImIvbmu1C8lyO2BJPgF2yMNrBgZhx0+IkAG3R4iy9JFIDGgddj
+LQSP4TX3uRUFUXEAhHzGA//XP4tnC3CisvOsuoc6ZjyZGSt/HUzZoKf+wsdJlfab
+iK3QpD8lSOw8KEZF54JUC8uaYGuBGs7ih4FcO+Aqb52UAx4/+13eEdAognVF2Hba
+iI+G2jEekyAwD0bP3DWyg+9fGBtnwtDMj0OrHklvA8qoHxAMvXHIGhxjqZBOFehh
+8DNEB6SIRgQQEQIABgUCScqH2QAKCRDJx5JOUQR9Zj6WAJwOtRlhq45DedrYNH54
+QIJSFw3XJQCfQI9fZl6zmKWSm1nJqXRC+awKmwyIRgQQEQIABgUCSc/UtQAKCRAk
+waN4agF7F75XAJ0TyTdCMGIZGCooM/xr3w+qvyZLgACg0W8O9WOf0qwSVgynmh2v
+QggUiyKIRgQQEQIABgUCSdI2jwAKCRCusBoVO3x1sZHiAKClsXinnJfHMQYewFPq
+y16zr//f4ACgulnu+ObADHMquuGCw4BLwrvqMIK0IFN0ZWZhbiBCb2Rld2lnIDxi
+b2Rld2lnQGJvc3QuZGU+iF8EExECABcFAjsSOYEFCwcKAwQDFQMCAxYCAQIXgAAS
+CRCiEVrhX2uLcgdlR1BHAAEByboAoNoD/9Jgm/alxfAYELz05LMa/HLeAKDWTHqq
+7rMkppZoTUv2gWpVzrk5RIhGBBARAgAGBQI8PtWVAAoJEIEEZE9RiYUE0LMAn22/
+u01Lo3Bo5lDxxHSkayUkYq25AKCm20yaGFGtTDJW4Rdz50pfut1AwoiZBBMBAgAG
+BQI+dd8PAAoJED6Pt/L4g0HZWboD4gPGJi0y93+Zp37uFGgpe8PkB10HVLCe9B0l
+7R7BK0UFhnFl004td2RWeALAAnOI8ZlxCahwQdUys34zF77c5fQ8Rn7co46wBSL5
+9Oi/bG9/wRYqBf13SWL2ITK1UDgzRznZrds9MLQqSL8oBjebyg28CZPBYH10FKig
+UUMwiEYEExECAAYFAj512scACgkQ7tHqOSJh0HOu5gCcDO9Ou8NA2+gChoNAn6j/
+J2owDxkAnA0Q5AMezP7rKdsw+hCYqZSp8QhIiD8DBRA+daoh/W+IxiHQpxsRAiSn
+AJ4id/ijcLliSH/EGh1UiaunYK9zLwCgyfeZ7mnhKXauba2NXFMlm3axSvuIRgQQ
+EQIABgUCPnekGgAKCRAVP6DNdaZ2kikaAKCJMBE/oJ/4ko7FRpUWvQv0MLmhRwCg
+jEXsPmY5Ur8AVynVzE2TcEu12reIRgQQEQIABgUCPsouMgAKCRDb0kX8s7KhLABs
+AKCU2ntXY/DhTnvki6igzrvttl/ynACfZTZNwePs9imtT6phGTInelrsXLKIRgQT
+EQIABgUCPo3ONQAKCRDKaTl0gQOjflg/AJ4khT+aic33qc/iMmMC5+URcxt6ZQCg
+leruhUJi44Kpav9PdVbQMzdb52eIRgQQEQIABgUCQZLz6wAKCRDkE2EzDKpotDZH
+AJ4xwN/htv44yNFQnACTYsc322HjZACfTd9WoxRkRWY6tVd9YgumNc0swMiIRgQQ
+EQIABgUCQsUyhgAKCRCb8iNFL+KLz+ClAJ99ddEJ5l/VW/mKHvTITZleDSv+uwCg
+lgqx3HQrlqp+gTPKIEKPkjjom+GIagQwEQIAKgUCQuE4ECMdIFRoaXMgd2FzIGEg
+am9iIGFkZHJlc3MgYW5kIEkgcXVpdAAKCRCiEVrhX2uLcvEYAKCJD7CVpr2Iw657
+kO6G3Is8xKa6IgCgiStyJgU5/dUEEPQctZ8ZVZSrHNGIRgQQEQIABgUCQt9FDAAK
+CRBB6gmgV5NJj+d2AJ9QRCXhFzmee7cbhlfejg7LBsXsMQCfce2/Wz+if56L7WaZ
+Lpn893CAzu+InAQTAQIABgUCQt6scQAKCRAxpj2W7BQLgXUkA/96klgNlfh+VTSx
+rwCUW1JE5j87qDeJWrnN5ibVYPd7TE45hNeWQie2RgWGpsHNlDekVh9aZuHMJb9N
+zRGKAAJ2augQQuvDKt8sge+ydRMXsLkAvpK4VBmobqqgyO0cV3ooMyizawMRndVc
+MbVu5b6Gkdj2tZEko/Nv9KBJ61MJ64icBBMBAgAGBQJC3sfZAAoJEDfj9F/uZeMh
+rGYEAKJgLDFku3GdpF/BI4GQBKqadLygF3Igq9Np310sTcLOI2ARb4B18Tvq9CyR
+4PEvdlVC5uEpaJozgHthTadjGTgg1WmiTWqG31s3U+zL5NLdK+k8qqrxGLzFzhk8
+PB1wJwImJcvLmJHm3HeIGycdEzn4swgmD4uI6p39mcGyCCONiJwEEwECAAYFAkLf
+bHkACgkQms08wKmfdd2sxAP/e8W2cqyypPqYHs05nTxNzD5wLl72ABWvljfdf5mA
+97sEl3q48234j3sUN1Uk6c21NlK+eRBn8Lv1ihyLTJkACgdiXNFvi1eC4vLhQMGO
+PcGW8+wI4olmsqftvG+2hNt4eCMead6IjAK7LNKgDWEBjGI+WIOvC5UJBO50cNXG
+OXWIRgQTEQIABgUCQt667QAKCRAyyeTONkLLSxJgAJ9faCKziDmN6nQeMoAECTfV
+vIdTRACgjnb3h8sc54gcosIh28qb7uBUuf6IRgQTEQIABgUCQt9sewAKCRBQjq7F
+MC2laDoHAJ9VC11NFs0+BAYWoZBJSUEnjn3F9gCgsqGPrxhTBkHlWAh4iiumq31t
+ZHaIRgQTEQIABgUCQt9sfQAKCRDdumS6LDEtL3hJAKCEHj7lHAZHRk7LLbFQDh7o
+iY7plACgiORbBhF3VWn1JCglbk51Kq5hJy2IRgQTEQIABgUCQuDJOwAKCRBc/Tf6
+zHjIk6wAAJ4qjf2FNE1VXK+PnL2iFP1h7f8L4wCfbtoQqsaDE1vCrnSobEUT6nfq
+Pt+IRgQTEQIABgUCQuDszAAKCRDJtabs4td03yLQAKCz5pbjUWdyEHQr85R0He3Q
+uDiLkgCgz6XQ/LFLdcmwDAj4lsKbRpHdUDyIRgQTEQIABgUCQuDtQAAKCRBbloAQ
+4E+aiRuoAJwLeKfpT6aqNLBvrusHnNNjROFi5wCgjhXup7RcdMNTDBY6BGj83NHu
+TU6IRgQTEQIABgUCQuJibwAKCRBtmI0XhzFcMZwOAKCLkKunJnUNy7QgowvTkV+/
+DyU+FgCfScvQFzMSj1Gk1ViDbK0n5i2MpQWIRgQTEQIABgUCQuNVwAAKCRATLknU
+5B7cfur2AJ9XnFPKjlIPsbrZVJRuNh96py7FfACgoC5yGwyRq9hYK3SMGGAu5MmQ
+WpSIRgQTEQIABgUCQuNk2wAKCRB1yqKj85s3UB1kAKClSCLmqecNSlVeFOwlSijh
+TjzmxgCg5eYxuHJo4wf2D2d1gWbloc8xt/2IRgQQEQIABgUCQuRvFAAKCRCM43a4
+HNSGH1JzAKCoUQuAh01aTLbbUS4WCMrOAQblagCfdwFlsT48wWEBnJSFAiXaEcRt
+UkiIRgQQEQIABgUCQuSSxwAKCRAEkTRC6hujjcShAJ9EK1u8wehMaZLt2ZnexHIC
+PhbtagCgkN+i7LXBnm1IwlP5cGbmgW3BJRKIRgQQEQIABgUCQuXCIAAKCRBhGWou
+Mz5OhEAfAJsHEwc1jK9tiYBvWRMS3zJ0XrrShgCffOyuZlrBNeuO9s8T9WkL7/vC
+nOmIRgQQEQIABgUCQupj+AAKCRCyvrxAFSkkrxWDAJ9oJHjkm3MWfPS/iMK6iipo
+UaAfzQCfYFygT+mws9MQIZEMoTi/sk0AOcKIRgQTEQIABgUCQuPtagAKCRAyhk5B
+nIUiKxsGAJ4mMBcsZ/PlqEN2CjOoNits7PFYbwCeLuEXDDEcUAh7jb46wvrHB5EP
+jp+IRgQTEQIABgUCQuUQtwAKCRBSeS+vmXivhlvNAJ4wGMXMO8EgWYrlU0i+9wrd
+6N0M/ACgvODXK0oKDcDQ55t8xf2evmJA7HCIRgQTEQIABgUCQuURpQAKCRBrc6EG
+KmI/cl6+AJ4kaPB7Ois5KuLwhbEwmpO3e07OQQCgw1kJOjcCZwogIWG1222By45k
+1YCIRgQTEQIABgUCQuaZYgAKCRBo64x2+OopZ+DxAJ91h0aGRvukGqAWEafe4nnT
+6xj9CACfU91kJ9G1WB2T8lW/fkXt8mnlrUKIRgQTEQIABgUCQudhVwAKCRBulHWU
+wVJDGgmCAJ9DsO7lkpvuigmPoIX6d7vufFW5iACeMsXW1nX0DWf6E9pPgDaeZ+db
+a1GIRgQQEQIABgUCQ4efngAKCRBmNbbA3ohd09++AJ9GFjNIUutctozuFNreIeS2
+xATWJQCfTUwt6nd4R13f5U0+iOsTwWVX6h2IRgQQEQIABgUCQ4efngAKCRBmNbbA
+3ohd06v2AKCHZ+fbpbQNIvlZkBO+9CTBl4k2IwCdHr7QCVQry4VIUhWGX5Fkydj5
+cXCJARwEEAECAAYFAkfAfZgACgkQGWWFUMMRBhFLagf6AqFi2y+DPg+duogX5hHs
+lLpeRVXbqEqX9bB2BzzinUhTmmRpEpiVnCkTd69scXh/ZVTECfA2zBYV67gp3eit
+UB7CDSeLZwqQCIz42uF5ADq9oj+j6uf8pPmsk9qO4VZcr7mUwJ4tDy6znG7Qg5H7
+y4HRRQ8cwodDIa2jpLdQ+v9+fms4Nq5j/IJRmHjT7Ha6n78arpl8DlBtjjG0dpmK
+fBB9n68MbiFLX19yIxO98X/nEoDCk6DuLX79Ratt4jEr08YCyJ4PfAqJKUy+F5jr
+Knp3G/qj6H2N72vHZLzoZRfZjBzbpN3V9rPossxQauoRqmU5M9wFDnBoqyszMMU+
+KokBHAQQAQIABgUCR8B9mAAKCRAZZYVQwxEGEWeHB/915y1ulAHQ3eJNMZdpVAI/
+YAeyE1G3owsL5xalMigBPT9/G6ARzX3OnJYkFDs+CE1gz4Yop24zZyR4JafbytKO
+Ef7RRchiJiL25rtQvJcjtgST4BdsjDawYGYcdPiJABt0eIsvSRSAxoHXYy0Ej+E1
+97kVBVFxAIR8xgP/1z+LZwtworLzrLqHOmY8mRkrfx1M2aCn/sLHSZX2m4it0KQ/
+JUjsPChGReeCVAvLmmBrgRrO4oeBXDvgKm+dlAMeP/td3hHQKIJ1Rdh22oiPhtox
+HpMgMA9Gz9w1soPvXxgbZ8LQzI9Dqx5JbwPKqB8QDL1xyBocY6mQThXoYfAzRAek
+tCpTdGVmYW4gQm9kZXdpZyA8c3RlZmFuLmJvZGV3aWdAZnJlZW5ldC5kZT6IYAQT
+EQIAIAIbAwIeAQIXgAUCSgkeigULCQgHAwQVCgkIBRYCAwEAAAoJEKIRWuFfa4ty
+6SoAn2X4c0dOTQp0dk+ofvPDMtNWBbIXAKDdrSAnSP/iaXIouTg9ncAERnXFgoiZ
+BBMBAgAGBQI+dd8PAAoJED6Pt/L4g0HZhpID51GCXx5Q60No2CVrjw73vZ+KVfTr
+8iJZSsi3X1C47C1l8OCZvnzECYFq9hhKL9WWCMktvqxg2aW8/78WgVW4KjPEz3Yl
+88cFPABauJPhJuHyl0efAci0iY7yy82utbKTRyXp5xFBad7U6RLK+GzbrmqEWIbY
+is06jbqAvtMfiEYEExECAAYFAj512scACgkQ7tHqOSJh0HOZXACfRTqAC+LhzLqh
+1668bBFTybxCdvwAoIGjkethM4lKnKqXZv9Wctz+E9toiD8DBRA+dao4/W+IxiHQ
+pxsRAlrLAKCp5Eet21hghQweWCbX2Sfp0Kt0wACg9W8xv5CE0KSB7E9rwmNcgZpV
+mwWIRgQQEQIABgUCPnekGgAKCRAVP6DNdaZ2kvvSAJ9JBZVwMzoYbuK+X4JTFbsO
+W0wHdACgrWEV9hElP/rbBPL7l1rbDAhniOWIRgQQEQIABgUCPsouuwAKCRDb0kX8
+s7KhLEnHAKCqht/V9susaEGuep74heYgo/6ExQCcCysfRsihFG0jPX/yEOwLGT4R
+0+eIRgQTEQIABgUCPo3ONQAKCRDKaTl0gQOjfsWIAJ9R2xmpnF0w2EhY591OYpNr
+0GvJ7gCgv7lDNNYLHZ/u9RIgJJq45R+h/TCIRgQQEQIABgUCQrgKqwAKCRCBBGRP
+UYmFBNDFAJ93FhVVtNwg7jLgO00lKk3/3lgEVgCgvxo0Jz2dPoOzWw8OvGUmN5PF
+rrqIRgQQEQIABgUCQZLz+QAKCRDkE2EzDKpotBiEAJ9ZqXR8/8Ffvq0lNkJ+0d9r
+JXzXaQCgyT6qZ5nDeDFJpPdMmRHhwHSZq4SIRgQQEQIABgUCQsUyhgAKCRCb8iNF
+L+KLz92FAJ9c/C9RJy3SGLbVq09c7NBPPS8+AQCeLBc3EqtjTtzmbBEH4fRegq1H
+t1KIRgQQEQIABgUCQt9FDAAKCRBB6gmgV5NJjyFIAKDhfzgs3KPp/97Biee5tPmq
+hizsIwCfWwvOgdoUb5GmZRpv53t08woBRp6IRgQQEQIABgUCQuA10wAKCRBzzi77
+hAj3VbBKAJ9oavMNCVLXyabt0pjFJBWSwRZt/gCePKcZox146ASRqaJF8OIvQn2+
+egaImwQTAQIABgUCQt6scQAKCRAxpj2W7BQLgRg1A/d5x83A1kegLg8Q72g6dcUf
+KCWR6I3mfbFkkUH34jSShdO773Yxm8oKolm0JrUzPagZwMRIgaUqSXpgYbxkyorz
+5G/R/PCkHto6qMAztyCaKyFTE/nlBQfuKZ+XPpBSw/yIRu6IWdqwSHOOy+thRbg9
+fXrMbzHFXpawRauu2VeCiJwEEwECAAYFAkLex9kACgkQN+P0X+5l4yGPbwQA6q4L
+s5TTiRZFrxJIHVVwgh9kz9zlLj2fSULWyX25INZ59YQpzCE2qTSZRBN8sowe5BKQ
+ZJlLcir91UsDg7KX4rP6bOsyUSJ3v9kecarU9/B3/7GLnKDGVHHoqRQKAi2DqpCi
+SsE6WDNONNXVKbsadcvC6uTdEg7U1vXyjDbPY4qInAQTAQIABgUCQt9seQAKCRCa
+zTzAqZ913XpNBADS498IdhQrpMnbH0s6oIxQ6ZFY4gcW07QnqfOn5WizKxdx9InX
+JBgozFH/yaLLQbI8AqS9lZQrb4cJeWYCM5vJbnHh7qatoguYb1DdCIyriFzC22T+
+wxPi33L8PNpyrfCTT6Y6LF4jIcrEGZrNl37jT+n/xMvCeY2gdmdiQmFiQYhGBBMR
+AgAGBQJC3rrtAAoJEDLJ5M42QstLwa4AoJXwrbSMRRqlUy06v54T50RTB1/WAKDO
+GdOaE7jxcRlkuEc8Qswm976bAIhGBBMRAgAGBQJC32x7AAoJEFCOrsUwLaVoIqQA
+n0wc28m+1XNI69hWQ4lyRVEgQqBGAJ0fsklpnnZHCVhEkrakbLQ/E+9pjohGBBMR
+AgAGBQJC32x9AAoJEN26ZLosMS0v+UQAoJvPJaWA8ctG2Bff7mxW76gsOovWAJ46
+0KDi0QbUOEJiD0fk//R0XjnknIhGBBMRAgAGBQJC4Mk8AAoJEFz9N/rMeMiTV8UA
+n36HHFAVjudWCBDNJm7KqZyh7WsKAJ9sU4g4KN047W0SbJAA7sPkJwE0C4hGBBMR
+AgAGBQJC4OzMAAoJEMm1puzi13TfGz8An3irX0FipvIvirhSUyKDE7wDeuUEAJ9g
+PRtcLRDeFc4Oh35077YLrN9q0YhGBBMRAgAGBQJC4O1AAAoJEFuWgBDgT5qJwJMA
+n3hd5dZRNloo0BdAZjzH6r5MgNlHAJ0UM7nOz1sj9J8nRqCb3xFBwclbO4hGBBMR
+AgAGBQJC4mJvAAoJEG2YjReHMVwxAuoAoKiAof3Y87dYurmnSQDs7WXP88ZdAJ40
+dTmjNicUfsKit5aEkxCl9bjqQYhGBBMRAgAGBQJC41XAAAoJEBMuSdTkHtx+60cA
+niVi5i8j86YN56+uY+wMahkSXg31AJ0U9jmvOXQDNNsIHWJY9xXoz7jRc4hGBBMR
+AgAGBQJC42TbAAoJEHXKoqPzmzdQwPoAnjmnjGqxCQz22Y2jd8vz3+Twfwr9AKDB
+j4z0kxrf4hydmgK38ndDBP0edohGBBARAgAGBQJC5G8UAAoJEIzjdrgc1IYfpZ0A
+n1WzxheVFpcxW8SvsSpmNg2yl2+cAJ46aAMX30kTtT2ZUFB4FpUvjWngs4hGBBAR
+AgAGBQJC5JLHAAoJEASRNELqG6ONH2wAoKPWAiV7uR6aHP0lad6xwmJk7hDGAKCL
+dquqzy/yW25IpG0amrrBJxbLc4hGBBARAgAGBQJC5cIgAAoJEGEZai4zPk6ET/MA
+njlQCKWhvqvRu7iYFQsg2dCW443yAKCYIPjawX4TXjgbruZktT0hg87UPohGBBAR
+AgAGBQJC6mP4AAoJELK+vEAVKSSvB38An1oDZWDSwVpp/53o5cdJujbLU9grAJ0X
+YbLrL+kW3CjaFVLncRhuF5t5xohGBBMRAgAGBQJC4+1qAAoJEDKGTkGchSIr+o0A
+njIqK/E4OJrK0XPhX134+VJZ9N3eAJ90U2hylPkr+EoBHnF5VtEWJVWunohGBBMR
+AgAGBQJC5RC3AAoJEFJ5L6+ZeK+GQvYAmweV9Ky/w7aRqbYjTtdg3U0Ks7DDAKDl
+qSRYN1u8wK+2pVY6pcdLdb0uCohGBBMRAgAGBQJC5RGlAAoJEGtzoQYqYj9y2GsA
+oIrkKoVWsuxRPHtOWWuvbHkMBeAmAJwMQVTcr17v9WngLkot4gurcsLxaIhGBBMR
+AgAGBQJC5pliAAoJEGjrjHb46iln3W0AnR3w53mDPp1l0/6GDqqIWpi75PIkAJ9S
+yyYZC4gjDmvf24hduMyrfjI2h4hGBBMRAgAGBQJC52FXAAoJEG6UdZTBUkMaINAA
+oKf5u3fzXTT9MOtOVcqyVgnaIHhvAJ9hPhaRQUIMryWg+pJcw0TTWC3O9YhGBBAR
+AgAGBQJDh5+eAAoJEGY1tsDeiF3TYA4An1FTBiWVfw9UBHZ8K05EZjG9+ykeAJ0S
+w1jLCrauKil0I2G5rizXR2tREIhGBBARAgAGBQJGOOLIAAoJEBVFs/7iIt5PB/wA
+oJihHU6IgWsNcADF1yo4/vD01PPNAJ401g1Y1dn2Z4/Il2jiuzE8dNYDEYhGBBAR
+AgAGBQJGOOeiAAoJEGPQra6REgPkF3AAnAhbVLxHJk0+XswLDLFj20SQKrcKAJ4x
+XaigKAQ5D6/Of1SPPRoX7bTEXYhGBBARAgAGBQJGPJMqAAoJEJhw7/PxL2By3XsA
+oKONmq8YyhYqvpafW9dX7k6r4pg5AJ9Sjki0Wqrm1AYXxAYGc8fZIesIf4hGBBMR
+AgAGBQJGORq5AAoJEOHh8rCZDtSqiDoAnR8FA/yGXEAd6gP0AoioyMHj6e0KAKCA
+dnxXUB/eSwN98EkeVwSPpiBLG4hGBBMRAgAGBQJGPFBHAAoJEEwEKBgxGj3l+XYA
+n2Okz5W6SabKyirUGjF30lr9BP8VAKCBqsPWR50O8vcG0lDLkp1tuW+63YhGBBMR
+AgAGBQJGPaCSAAoJEC65RoKIgXQCTFkAoIq89nYh6AmxcqwQFeYiloD+FGv0AJ41
+la0vkis1JUIDM3FNO8xw5VbNZIhGBBARAgAGBQJGPdZ4AAoJEPXCYBZM7tdfcxkA
+nAsMAnhrvQNVPQJs/P5ysQTKHXZ7AKCGrxUFi5FQ93oEuWBGqw/xHcMfVIhGBBAR
+AgAGBQJGPfUFAAoJEKBy1NBDWMWESn4AnjHzaapJEaIYFhc/39hIRm5n0dl9AJ9l
+AXqmz+YQSqJKQ/cchdKbLdhSGYhGBBARAgAGBQJGPgXFAAoJEAKlpgULfmz6xg8A
+n1EFGiCeI1C+7BUDqI5xlPps6WB5AJ9cUoE8g1ipE/QtCVYcOUhD53yxY4hGBBMR
+AgAGBQJGPwYxAAoJEAP2jL3eiISgjbsAoLzdvLd5d8mADMZDFLi9ywPLk4pBAKCt
+23xxWAwNSj5W+uPGLL6R0IEb6IhKBBARAgAKBQJGOPeHAwUDPAAKCRBz3YwWAVMC
+NT3pAJ0d+kpqF2GHoIhFEisRwox0J52J2wCfc5nQgpaGmgyMqodqq+cdoybHIx2I
+RgQQEQIABgUCRkC2TAAKCRBtC8c6QFgYN2F+AJ9l6y2ms478IKVMFRI/SghwKvRW
+AQCeJIR6hCR46QY0IqKhkHy9mfzaiPaIRgQQEQIABgUCRkxEUwAKCRAfISPDa9hy
+oOhdAJ45vxMRMgaHj1548DkUttPv0cdYHQCdGlc//bHVnJwwlUFz/1O4sXwDttaI
+RgQQEQIABgUCRkx9AQAKCRAPRQomYhC/wO8fAJ44L3d9QLaMvMvcI78aMBJH2y2d
+SgCfe9xYYMuYvf9qElihil/7a/9p68CIRgQQEQIABgUCRlJvWQAKCRAywdbvDxQ7
+wRIDAJ9xo4egUgVo6h/N7A5nMBuT3dZ6jACgy2Oc2uFYYhGvBAgQpHqESZf4suOI
+RgQQEQIABgUCRlJvYAAKCRDLrr45pGxMoYJUAKC/iURBlu5JKxZJqUJ6D2kzYuo4
+tQCgxTpvpDWKqrGIM8OeA/PbdUJqTkCIRgQQEQIABgUCRl7VqgAKCRCahtfM0arq
+YMd8AKDHCkES+rZ5lM7aewuV+/ouOknGQACfePMsXa5L4OKjA3szncnZkcc6Wl6I
+RgQQEQIABgUCRqVMLgAKCRA5vlGhCEyREz3aAKCFX/1eYbphSmP2KYfgHkhg6Hf1
+UwCgtjZrJUNnuhsPGRK+Fooeds3MatGIRgQQEQIABgUCRq3MVwAKCRAzzWczr17E
+UvI9AKC1QzfFpES4rgb6+6lqzYYO2JW9SwCgtZkhqsaH5evRZiIglzjHmfgPJjeJ
+ARwEEAECAAYFAkfAfZgACgkQGWWFUMMRBhEjoAgA4cFAPqtCYVpEf0Nc7eciqxpU
+LGLaUCOuDfMZiz1kSkXi4FiDAKbSfrcGAPmLh+8AiQbID+1PKItsfWs5ZjuBzJw2
+toF7OKSWxNKUSJoT+SapGGrs3qbywZWRi82dcwqSxPyZmsQfLXONJRePwgWy4+RB
+Nvo38j1hKZclf8xMI4w1wJMUs34Xae9BGMoLhpuJ+jOCoG4JE3cUdf7hvhyJKtMh
+xrAiYVYmVlurShtNF3Czhq5tm80Jb9m1wlZRFgvUE6m/2XWwPjjS0lnZnoBFVZ0H
+lMd47b0YOu8ieS1wNgkqtpRwBqBBH2XOM4kR5p/uT7rJN9yav6z1fEEgmV5TG4hG
+BBARAgAGBQJJyofZAAoJEMnHkk5RBH1mxrcAnj6+e5JOVqw2yHEYGIL5d+z9iURf
+AKCR6Y89jMFzzv2rEPbArCxOeGmurrQkU3RlZmFuIEJvZGV3aWcgPHN0ZWZhbkBz
+YW1hZmxvc3QuZGU+iGAEExECACACGwMCHgECF4AFAkoJHooFCwkIBwMEFQoJCAUW
+AgMBAAAKCRCiEVrhX2uLcoYCAKC4KNTcBwjOEIfMOgFsF3uTQTvL5QCfQ2960jGi
+s9Jye9Ly/fI1CBMVQxiIRgQQEQIABgUCQrgKqwAKCRCBBGRPUYmFBP0VAKCPH0b7
+S+TylV1uBuYcYnWIb/RJzwCeJvRTMPnWNjVz+CVOvVzJTH4ol5mIRgQQEQIABgUC
+QsUyhgAKCRCb8iNFL+KLz3iqAKCXRZWdGjBVbj3IBFl3kvh3xF2gsgCcD3H79mbV
+DRNMxpGArFQ1hqQFzleIRgQQEQIABgUCQt9FDAAKCRBB6gmgV5NJjzHQAJ9IfkjK
+kiEuFxUhznsghAQ8bsBWnACgoT0kWSB3iUepLIDoWhhGtDIS5FSInAQTAQIABgUC
+Qt6scQAKCRAxpj2W7BQLgebOBACAFFpEKETO3ZHbjMnPogACNr6EZCQxzGTIXrXS
+yWQs68VcH54wUOA4yk3cGpfH2pgAxYjaHejTJRvDKvGrPGlKHgCZFy4+wHzo17pW
+9J1aKk2sUWlT67snDVdMun/i8WxD9yz299cXR6iCxPfP2HIMEqbsxWJaXITo7drW
+SjO35YicBBMBAgAGBQJC3sfZAAoJEDfj9F/uZeMhRawEAM9wfn9sBIsFzQRQbAO+
+ll83f8ki++A4Anj6DXQ4xRmClUxqahL1BjxxeQhE+Qomq1IebDJr0Se34XB0g3J7
+bzr/i9QmEwEqnDJfWVobv1Ugjy+1jzErlZBhm8hnCI+zPnrWKLk0n78vzJ5RrnVa
+TTV+OW5r4rdVZ86yKYHtpVSoiJwEEwECAAYFAkLfbHkACgkQms08wKmfdd0HDQP8
+DDD+1FQU8PPPe+Kuf2bJOO7Ycrej4JF1I/Gbs2HH3xXgOZsRv6WJ41M/ovxJLYrp
+VqQA2YF/Gxwguwrf4lPk+4spFdabguiJK0d2/KZAtnLsjIzdYcoY01IKGT3xkPwI
+DErNFSmxX6bKCUePcFNHYZ6dDBHFFcYVTsdo/wbAe6aIRgQTEQIABgUCQt6wsgAK
+CRD9b4jGIdCnG30UAKDCxsPZksKIcvj7tbHQEwm+PV5+DwCg7PorUCgIvTIWnID8
+zRWDBG4ACXaIRgQTEQIABgUCQt667QAKCRAyyeTONkLLS/d2AJwM7BQIQgqLA0qA
+75R2EjHFXQKZWACgo7iaANHxIRc/Nw19j8CxNbWJRJ6IRgQTEQIABgUCQt9sewAK
+CRBQjq7FMC2laIx3AJsF0Hjrm4N21EwdrmhS9PHKQL2KdgCgjlus2GyuCzafgb9J
+HVhBDrhelkmIRgQTEQIABgUCQt9sfQAKCRDdumS6LDEtL7MWAKC6rQU6ZjSS6gVn
+wswutaqBwfwtvwCgv2mMGJf2hnYVaNNqV5WIFAuycmOIRgQTEQIABgUCQuDJOwAK
+CRBc/Tf6zHjIk9TlAJ9dbM2HowI5oD6hGSnADhI2dKfBrQCg4O9WtFiRzLqC1TgC
+Asbigqy+JDiIRgQTEQIABgUCQuDszAAKCRDJtabs4td0311pAJ9L3yUe7GUeDqMz
+d3WLWatclf7ruQCeOenA9nhyKgHASeEK/ZXQXDDBW0uIRgQTEQIABgUCQuDtQAAK
+CRBbloAQ4E+aibNVAJ4wnAfcA/rtUs3+Hu9nNn8ar/2Q5wCfe6W+k9yHjd7hZWnY
+HdnCkAZkOMeIRgQTEQIABgUCQuJibwAKCRBtmI0XhzFcMezQAKCnk+So0Anm4kLD
+wl+srHvIB7b6jACgqROBN5MeEGXQm+Gan2VSt+nvTZ+IRgQTEQIABgUCQuNVwAAK
+CRATLknU5B7cflR0AKCTAlfhPFwHPXnBo+5IROopwNQnsQCgh2vHS9VRZRt5I9is
+NDaNf1biCQmIRgQTEQIABgUCQuNk2wAKCRB1yqKj85s3UK9XAKCELi7ymxtLxdwY
+fdfV3dxd63mV2wCgjgaUlQqFXjx5mXnRsgy4S6cS9yuIRgQQEQIABgUCQuRvFAAK
+CRCM43a4HNSGH5/sAJ9JVHMVwBwHD8PN3DQq8hHEumn8twCfVQSXooNY2P744K+8
+k6lLO8nOH6GIRgQQEQIABgUCQuSSxwAKCRAEkTRC6hujjb+qAJ0Z+AoGDYe122wR
+AOYAKayl9f9e0QCeKetoll6NZ+Rm/NKbFJGP6fYywIuIRgQQEQIABgUCQuXCIAAK
+CRBhGWouMz5OhDd7AJ40l37cLZcSxfPt3M7/aOPgVGpa5wCfciaEynzuHDfIQD/v
+tXrZb2m0+NeIRgQQEQIABgUCQupj+AAKCRCyvrxAFSkkrwQsAJwM8IqtXQk/TBiQ
+i6Fyq/HHm5/zvACg5atZV8F+r7jVRhT1SJ+FaVsaQDiIRgQTEQIABgUCQuPtagAK
+CRAyhk5BnIUiKwuyAJwOljL2++fVQ0BSKRvFSvS+fSu3KACeJxsOhbyCd3o3rqwa
+VeY5FFi+Fm+IRgQTEQIABgUCQuUQtwAKCRBSeS+vmXivhv0OAJ0Sg/UEnB/IAoqj
+HzKoBivCMYDtrQCfVY3IDKRHbbLNfWBSDERWCTpHXtiIRgQTEQIABgUCQuURpQAK
+CRBrc6EGKmI/cqGBAKDEgTewzt6TjmCkI9RrYjF46a9H4wCeJPh4bmTymcfwRGn6
+0h0a9Mz1mKaIRgQTEQIABgUCQuaZYgAKCRBo64x2+OopZ3lEAJ9w4EWAgRUMxf0U
+d1zoygYDQedAgQCeJPHSbk62Ej11NljNGN1zdwzRHuSIRgQTEQIABgUCQudhVwAK
+CRBulHWUwVJDGkOfAKCgQM+50dTktJDaDd8gVOGBKRiSIgCgkT9gdtDac0m9s2IH
+Aqktk0mc0U+IRgQQEQIABgUCQ4efngAKCRBmNbbA3ohd05uvAKCjMnn4GpnZhjWF
+S7iN0LIXgxm5PwCfYodjKF5zSbIROx79dJ41Gg0/VxWIRgQQEQIABgUCRjjiyAAK
+CRAVRbP+4iLeTznPAKCaIUKdiySarhu//zEVn67y9q/szACcDUob1L2ac1R1FHB9
+XE4fTf/PV1KIRgQQEQIABgUCRjjnogAKCRBj0K2ukRID5FlVAJoDhc0dijUvPmOK
+ILkX6fG5g73DugCePsOrjW+YIc5+T9qeVMzHyfm2opuIRgQQEQIABgUCRjyTKgAK
+CRCYcO/z8S9gctnJAKCc7DZ7JzXgaB4ImiwB2dyGMFUC8QCgitOFKEw1y4+V1dNN
+3kZYL4P/M/uIRgQTEQIABgUCRjkauQAKCRDh4fKwmQ7UqvVYAJ9BjHLDyGmR56xK
+lKF3qVq1+jAmgwCfQR+0qbVWaSIaVS1DCg8yUr2txOeIRgQTEQIABgUCRjxQRwAK
+CRBMBCgYMRo95VO1AKCewEwAscfj9VfTxswF6BL6zNj8rACfW/3kG7zPI2dSjWJz
+GYPQYPAa0smIRgQTEQIABgUCRj2gkgAKCRAuuUaCiIF0AjxRAKCu9kiQfvVmSrVZ
+b9HK8Mazhut+hwCfY5guSOz96KH5dJ2585cm5wPyT5mIRgQQEQIABgUCRj3WeAAK
+CRD1wmAWTO7XX04yAJ4/ZvOfsexCgIQRuoREg1/D9bniKgCfTcKh9dLFkPjlD3yI
+w/NCc1L0/ruIRgQQEQIABgUCRj31BQAKCRCgctTQQ1jFhJmBAJ0TPZlIksq1EnAY
+tTTSb/tHpXxNUACfd/m3jaTHdJljRXGI7UBsVHnL0nWIRgQQEQIABgUCRj4FxQAK
+CRACpaYFC35s+iQnAJ0eGzB7NIQtXLEgyuphyW0nBppVrQCcDj6tm1MCKXA7f4zV
+1R0u30jrUeCISgQQEQIACgUCRjj3hwMFAzwACgkQc92MFgFTAjV92QCeI+02yLkS
+qmdJlMBVfVE9joT/pBAAnjJlywot38PS8FtodliCfNvqn6VIiEYEEBECAAYFAkZA
+tkwACgkQbQvHOkBYGDcfVwCfbS6bS20V1ElnuQBAofsmi0yjbzoAn3eztrDQIrh+
+/BkXIJo7IF0Ny+gViEYEEBECAAYFAkZMRFMACgkQHyEjw2vYcqBPqACg1jy6peeP
+fEuvYJEKfJBNG7FVwPwAn3y5/eBtZdRefj90FeIiS3dr3D3siEYEEBECAAYFAkZM
+fQEACgkQD0UKJmIQv8AfLQCfeHzJB6tJdA4bjPEcJKi0sMFceCwAnAovkjdUhF2a
+JrpK2cr4bZhm5RbhiEYEEBECAAYFAkZSb1kACgkQMsHW7w8UO8FdFACfSFzmzz3l
+ZmB+qclUq7q+YVgd3hYAnRyNi3iYLUVrk746XsvzWcv8UonRiEYEEBECAAYFAkZS
+b2AACgkQy66+OaRsTKE0LgCfYZfXtB9Er7iKXoDfhNuuDIdKmqQAniGNC3piLBCg
+gMPpJ5vQp2KsptvJiEYEEBECAAYFAkZe1aoACgkQmobXzNGq6mC8pQCfeV2ib+Ym
+o/KQ+jYsr1BxYVFCOmsAoO312vLgv8Q46hucGIq9aN2isEnEiEYEEBECAAYFAkal
+TC4ACgkQOb5RoQhMkRPl4wCfebfolpLZYdGk48JuUwd2shtkicwAoMGAdNOSoXyn
+I/6/b9jsxQl8qmwZiEYEEBECAAYFAkatzFcACgkQM81nM69exFIBlgCg0CUQ1h61
+lCLBjE9+/Kvskrh1QAgAn0gXeq1NKEuepDB6hQo7fVZrSpF8iQEcBBABAgAGBQJH
+wH2YAAoJEBllhVDDEQYR8ZEIALAYFxipk7FfpDbEnUrTI237QugKjpvrX9n7CdHx
+JLnwOBr1g2/e/RMgoJHH8yqP8iQPGMfZXCVLM6ME/EoUQAVT0M0I1QsBVxTIXyPq
+QIzCv6zibLYyEXDlQDNVB4hqdhozzxyjGruqbn75zfb8mlTMoj9lElNhVIdcUOVL
+2xHkBy6g/YpmuZb/pt4HXBOUyWkmFK8zBMxhXw5bOuOP2zSJk9rZt7wdKNj3iC+/
++936yXZzqWFuUOq0RX61RtW8e3SJfowGFBd728snsiD0IFLTXor62aBfBJ5yiGKF
+UBM8LQ27FcJasfo7a8SiBbJOO/OsyQ1lRvLS85kM+XZDXZaIRgQQEQIABgUCScqH
+2QAKCRDJx5JOUQR9Zlt8AKCAMAc8652qgKVPdH0XJbzoq6ykNwCgkTboPY7d+GFy
+EwNCHk+0PAmkPru0KFN0ZWZhbiBCb2Rld2lnIDxzdGVmYW4uYm9kZXdpZ0BlcG9z
+dC5kZT6IdwQwEQIANwUCQsVK6jAdIEkgbm8gbG9uZ2VyIGhhdmUgYWNjZXNzIHRv
+IHRoYXQgZW1haWwgYWRkcmVzcy4ACgkQohFa4V9ri3LW7wCdEc6hdCr094a8LG+c
+hTd+OzGxfFUAnR3FvtuG8sv367Knk0ybMnpOM/4hiEYEEBECAAYFAj53pBoACgkQ
+FT+gzXWmdpL1ewCeOSe7lOufhc3mfTXs7eSvqECt89oAn0VM+YgQHbfdVp32YE7H
+t6N6GPf0iJkEEwECAAYFAj513w8ACgkQPo+38viDQdkP7QPmPZXPi7m6wRiLofsT
+lHCbBrR+ehWoSSqCmHQjN1DGRtamGE6X8QbMIttD+NLp+uTx8j/E0sGUdPnWkky6
+fwt1f3AYeoAgCXNvPoewsC6mZn3FMdEo6vJc43FmhsUfumOtunvGNBnXdM8GSCJ+
+RBS/ASMjRrECF12/14xwgyyIVwQTEQIAFwUCPD7aNgULBwoDBAMVAwIDFgIBAheA
+AAoJEKIRWuFfa4tys/4AoND5QhEdyVIypBvCUHv5SCaAKcd/AKDFthtZTrjF+eEY
+lktPLRtI9zjeE4hGBBMRAgAGBQI+jc41AAoJEMppOXSBA6N+jAIAoIcAeCIKt2QB
+PnAthnUk4DhlmM7FAKCA0Iz9ZutXGb2l+p8s7hhF3+Y9L4hGBBMRAgAGBQI+ddrH
+AAoJEO7R6jkiYdBzi84AnRddvByuDodl5KaCSdpe6k9aYkLqAJoC/ud28X0M478K
+lmacVVjb+PqzBIg/AwUQPnWqLv1viMYh0KcbEQJ6DwCff918LRigFUyEvYj04C12
+so87JNUAn0RNFw+P1/SR9Mr/JQmOzJVhlwdriEYEEBECAAYFAkLFMoYACgkQm/Ij
+RS/ii8+wZwCfRvfW6NyBoAp7oS9ILRHNYh2GbhsAnRYGs1hSaGK4rGxm/fmqxj+D
+vqI2iQEcBBABAgAGBQJHwH2YAAoJEBllhVDDEQYRqFAH/28B/f92MsQX9ZRJG1v9
+EDGVx1U+pcE16a7iplCP4QuUR6uA2EUe9fptzZfX2iT2nr2XgCB3x2NHf0rzNpTA
+M3OtqKQhXdvS3EWzWqR8UaDf6dxKN57B4QONRIhuImf3m9DWFNwIr3oOtO25Q+tG
+7YcZen/zbwU5O23CEakNsysxGEHn/3BPjRyA1FE7NVLrAmxFu8LXBUD9y3HNNetM
+4WlucnObqw5cBFsZMtnGcVLs3suTAsxwrnBo7jq/DbZVvzUZtEkGdV7LpSWkivSr
+q0+h9Gzug8EcYTjrdR6LFA5xGan6R9zrSe4mxe7vja10fmGEdIOQIapgO/iOWDR8
+3MG5AQ0EOxIiVBAEAM1SlkvEK5MrMnW0ybtv9eMCG89gqIvd2gBnpcAsF0sX+dCa
+WHWNy5HL3dBak/G3BJ8+NzAksfL5Srm0LVKcfVjBiG+IsbUoSyeJQGuhSZXYcnIc
+/3Z8Ujcs+TfFurG8uHU1cWnNK5aMYwDrqxmp4Ru0zLYHw4tHBBKF0cgFaCsjAAMF
+A/49aSZuDaatppSaBOzCt7wIYCsGBxX5ZibrJqr0gLUbhXU9eaWzCawOWwCvpQN0
+lTjoYVkwiLZaYUkdqsSQgHAU3jjKlIuaIRXApEkTb8Jg7R/vNAdwXoZRLBCjZPGd
+5qGtnIezsZ2+lxFx+bRieUL8fUInemXwWl8e23PMisgm+IhOBBgRAgAGBQI7EiJU
+ABIJEKIRWuFfa4tyB2VHUEcAAQENMgCgnc22kj8TfjktU6u4SUUqud25ZZcAn0B2
+b0zPjKjGuiwdKSnkFbNcFS3g
+=UxMc
+-----END PGP PUBLIC KEY BLOCK-----
+
+pub 1024D/C152431A 2005-07-18 [expires: 2010-07-17]
+uid Steve Loughran <stevel@apache.org>
+sig 3 C152431A 2005-07-18 Steve Loughran <stevel@apache.org>
+sig 2 FC243F3C 2005-07-20 Henk P. Penning <penning@cs.uu.nl>
+sig 3 302DA568 2005-07-21 Rodent of Unusual Size (DSA) <coar@Apache.Org>
+sig 3 2C312D2F 2005-07-21 Rodent of Unusual Size <coar@OpenSource.Org>
+sig 3 E04F9A89 2005-07-22 Roy T. Fielding <fielding@gbiv.com>
+sig 8103A37E 2005-07-20 Andre Malo <nd@apache.org>
+sig 5793498F 2005-07-21 Tim Ellison <tim@ellison.name>
+sig E4136392 2005-07-21 Noel J. Bergman <noel@apache.org>
+sig 1CD4861F 2005-07-25 Eran Chinthaka <chinthaka@apache.org>
+sig EA1BA38D 2005-07-25 Ajith Harshana Ranabahu (Made at Apachecon 2005) <ajith@apache.org>
+sig 3 21D0A71B 2005-07-20 Dirk-Willem van Gulik (http://www.anywi.com/ - Senior partner) <dirkx@anywi.com>
+sig 3 3642CB4B 2005-07-20 Martin Kraemer <martin@apache.org>
+sig 3 2261D073 2005-07-20 Astrid Kessler (Kess) <kess@kess-net.de>
+sig 3 E2D774DF 2005-07-22 Sylvain Wallez <sylvain@apache.org>
+sig 3 015AFC8A 2005-07-22 Bertrand Delacretaz <bdelacretaz@apache.org>
+sig 3 E41EDC7E 2005-07-24 Carsten Ziegeler <cziegeler@apache.org>
+sig 3 F39B3750 2005-07-24 Colm MacCarthaigh <colm@stdlib.net>
+sig 3 9C85222B 2005-07-24 Henning Schmiedehausen <hps@intermeta.de>
+sig 3 9978AF86 2005-07-25 Christoph Probst <chris@netzpunkt.org>
+sig 3 2A623F72 2005-07-25 Christoph Probst <chris@netzpunkt.org>
+sig 3 F8EA2967 2005-07-26 Brian McCallister <brianm@apache.org>
+sig 3 A99F75DD 2005-07-21 Rodent of Unusual Size <coar@OpenSource.Org>
+sig 3 EC140B81 2005-07-20 Dirk-Willem van Gulik (http://www.anywi.com/ - Senior partner) <dirkx@anywi.com>
+sig 3 EE65E321 2005-07-20 Martin Kraemer <martin@apache.org>
+sig 152924AF 2005-07-29 Sander Temme <sander@temme.net>
+sig 3 87315C31 2005-07-23 Raphaël Luta <raphael.luta@aptiwan.com>
+sub 2048g/59066D7B 2005-07-18 [expires: 2010-07-17]
+sig C152431A 2005-07-18 Steve Loughran <stevel@apache.org>
+
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v1.4.2 (GNU/Linux)
+
+mQGiBELb2+oRBADhgEV29jhAMg4dFJN9fjeIjN7+J0Lj3rcLBWc5RTlM33DTOCFM
+BCIE9B/RXJuVhGgi7fUuB+WsHz7XMgZRn+5nqIKGecIxwEUtZCfwsaV6Id3abt30
+wccyYDTSV95gQie+bbwWF44ao7n/CaR1WUU/Nx5b26nY2EzOrQcgP1qYEwCgynnc
+NU1N3zd1cIYr5hQVqvdazKsEAMbYAm5WsjBlLBrolxs/smx4vxZYJaA3gUqTz9WY
+D08rDsotVIMoosYF0b4b3WxcePJ68N1pkF3U+zo8bIZJThT91nAfMh29ZAcSyRqg
+Mkd25OcrrjykeF7OavuFSwhvYoDdlwsvkuijHY3weXyhpjvzi+GzvZoONo3zSl4g
+aWncA/4vu6k7XZUZ6B9DbJLJ4Xqq8uhD7uT4417uCQdozIWgKE4ThM2WffhV2IgY
+W6IXg+o6AqY1qiMLSYYdeRsVkQ/GVss+sR++cbsO5ijDGfvlWPfGxIcA+P+alAwf
+KY9M45IB8E92DUDru6ImrDHMeOrlDNPRusxRyZ4SiSJYNcgBtLQiU3RldmUgTG91
+Z2hyYW4gPHN0ZXZlbEBhcGFjaGUub3JnPohhBBMRAgAhBQJC29vqBQkJZgGABgsJ
+CAcDAgMVAgMDFgIBAh4BAheAAAoJEG6UdZTBUkMaZugAnjJVyMa1FYEm/9811Whm
+K06kGzXbAJ4rgRTBOcuyVbmbOAeYCgqloOxky4hGBBIRAgAGBQJC3rlGAAoJEIuW
+KUP8JD88RewAn3LmpnmnLlYnlQW7+byITmKLO9gwAKCi0GGQz0QUq9tFG4YeF7Rp
+UCl8ZIhGBBMRAgAGBQJC32y8AAoJEFCOrsUwLaVof1cAoLX3ROO9ufH+QXYlBuy6
+HA5SgofAAJ9aON/jC3WmrxT9Lz/DlIBKVI9TZohGBBMRAgAGBQJC32zBAAoJEN26
+ZLosMS0vCycAnjFhGc63FoWHwzpfVoocrBm8yQTHAJ47Kle1Tr+fBnlkYsAg0xY6
+12VZ9YhGBBMRAgAGBQJC4PEqAAoJEFuWgBDgT5qJY6IAnj2jxdReXh3eBRr+easP
+bboH9Lu0AKCSoT0Gt+pM+G7XM8vQbZjsyjDhrohMBBARAgAMBQJC3t+3BYMJYv2z
+AAoJEMppOXSBA6N+4VAAnRfGDGvU4qDop0EdApmHCExFDHFDAJ9/3xZDnJjEeSGr
+l2JyOPJfbv/k0YhMBBARAgAMBQJC30/tBYMJYo19AAoJEEHqCaBXk0mPRKwAoI0M
+FDyhr2PON57N4614Po16a9ZNAJ0SGKJtMOIxgoDHSf6SYuFy+8sBLYhMBBARAgAM
+BQJC35MFBYMJYkplAAoJEAEFZrzkE2OSgcsAnjKv4POPmFUYhDGH+GCcxSyM9LPo
+AJ0TPnoLf74lUroWD5+rlhTPD9eMHYhMBBARAgAMBQJC5HvtBYMJXWF9AAoJEIzj
+drgc1IYfdCAAoIKybYLGd4yGE8NcrvnGaPSXx6NXAJ4zrIPA9tQu23tOHarZxSqg
+7AWGh4hMBBARAgAMBQJC5JCBBYMJXUzpAAoJEASRNELqG6ONWZsAniJvvMiDR61N
+rV5Y7xx/3/id/ekWAJ9MNUUQAXTES1dkywQVHVp6C8QFvohMBBMRAgAMBQJC3rR1
+BYMJYyj1AAoJEP1viMYh0Kcb26oAn2JuF355Lq6PIEvnhEr+SA3noxS8AJ9msBXz
+nHsORsz8mB4WZ4DMAYEH0YhMBBMRAgAMBQJC3rvoBYMJYyGCAAoJEDLJ5M42QstL
+Cu0An2vCOimm9iyRJekvlh7IcsrXVDksAJ9S1iVXBgyRuWBkbcuRk9OLs/TnwohM
+BBMRAgAMBQJC3twlBYMJYwFFAAoJEO7R6jkiYdBz3gkAn3b48pHpjPG5DCbfp0oT
+/WN9IqYlAJ47CLk2xg7e8N53WTmYfL+F/c/ZrohMBBMRAgAMBQJC4O0jBYMJYPBH
+AAoJEMm1puzi13Tf+KgAnjviBj4kvC9ABiWR70t4BU3y8kgJAJ9qmj71qWjrek/L
+Cb3+fAmlASx82IhMBBMRAgAMBQJC4O20BYMJYO+2AAoJEDf2j/UBWvyKJywAnjSC
+smaB18utPgHthVW0qDQ+DDmNAJ9a64uKqcDI7u1cDEbi3nL5ELztCohMBBMRAgAM
+BQJC41snBYMJXoJDAAoJEBMuSdTkHtx+SyUAn19MjVdnPdxKdiXjpMRWwOs5fhTL
+AJ9AGh+TvyOt877cfLVaywPK+GhN0ohMBBMRAgAMBQJC42UQBYMJXnhaAAoJEHXK
+oqPzmzdQe9gAoL7BugDd1NniX/ZNqs0aD7Y1uUfhAJ0b4p34ZYPWFg1CyUduwYlx
+MAOqo4hMBBMRAgAMBQJC4+3gBYMJXe+KAAoJEDKGTkGchSIrHl8An0ERlWCCDHYy
+0jlbsVcQ4FOS9qe6AJ4sLF02AltG01bK1kpvnKXxHFVYoIhMBBMRAgAMBQJC5RDw
+BYMJXMx6AAoJEFJ5L6+ZeK+GWEkAoIl+GM1cgJosSMsMG0NqXog9yqeKAJ9aJ0Xr
+j7JP5abRyjROroIUCUcc4ohMBBMRAgAMBQJC5RHdBYMJXMuNAAoJEGtzoQYqYj9y
+IawAn3TzgRnJPfl4gg2kwIlJtD/a4ql5AJ43+Bbg3EWh2RVaLB7QpA1pAsRFB4hM
+BBMRAgAMBQJC5pnVBYMJW0OVAAoJEGjrjHb46ilnWz8An1WpumoYARq3Le1VG0vu
+SkQcdg8SAJ488MHNQRq2fyQFk9uIstWriQfa7YicBBMBAgAGBQJC32y2AAoJEJrN
+PMCpn3Xdsl0D/j7J+/vobH/4+pmWCWv3okqBbbd9PH/NJTC3B7KU+p8bFdIIZWYh
+n9SPXRdLoUlbKnqYw6+x0Ktn/9oWqwTM2b1bOHoMEUy/hPDM1ZK2gGDU11BFbfC4
+zkXowbq2xCHLyaQXqj5Wju01PT/wj8bw5A0E2rzv2iUA2ilXJE1vQdx+iKIEEwEC
+AAwFAkLerQ0FgwljMF0ACgkQMaY9luwUC4H6jAP+L3lvntIdecj0QlnD4gTkdLn+
+nbOPT0G9MPSjA3ML9Bqeoh/uD2TeHS0dqb67DpIzhKV/zu6vrOhsXHXNiCjR4lxR
+YHBg0PoxLJkggpjdAduk5vcM2ZgRJZQojsQ9CunxnmA/YCRCEEUPFeKj/5p1aFGm
+uPsl2zwggHxbdOBY1maIogQTAQIADAUCQt7IywWDCWMUnwAKCRA34/Rf7mXjITNS
+A/9YB8srHD2WbpZy5P/cN6WjPshYgx0lVFOifFdXgD4AUzgJ3VmtH1NI0Rkgadcw
+8PdJYAynH/Hdz4PJ8wIEkmMFEe6TKB3BCjCGY8+Ti6R/VrlkizIGL0HzAUzNc+g2
+D1NI8725Idx+XNSOSBcOBZ3mwPVo1k67X1rF8BoYAeo8TohMBBARAgAMBQJC6mYn
+BYMJV3dDAAoJELK+vEAVKSSv8BwAniQzr7l/ihVvAhvNUnpJzFWfr6tfAJ93Mama
+D+Fz4kgEVjnO5j8MrM6JtIhMBBMRAgAMBQJC4mNBBYMJX3opAAoJEG2YjReHMVwx
+Pr4AmQGWlApW3C1VbkuRgVs8pj6/ejXqAKC1z3D5mMpj83yyejnBjxDjXTLsUbkC
+DQRC29vxEAgA05PNdXcVOSTsYuizTCbdBU9i3qUBkAyqPmDE6hkWI+7fnr8KAUUo
+UghWwhxqBngpv48o3mE+bC+l/cTH+DuHIOsszpSK5ydufyitXi7piYk4RS+UNbyl
+b4BU5qGodwWwXC9wKBIjXL5rK2KjKh4Ovh0WogtZ1fwc5NzQkjcfbner9WsAmjtd
+nmVV2vZhJdDlxf3BBM9ai2R2IRvfhF61QFZcr2ehqAdsiDix8p0ugpC/oQS8h8pg
+GQebz7aNeSjh/Vb3dsdo8CaLvHp1nM5aVCDRqoCfoeKUbRfwwwKxtc1cyYzOHD1f
+KG9BuvtL4y4JQ/gDCsQVKdAAoiktu8Ks9wADBQf/fGkVYIh7w0+8xSIvez1DKirX
+rl1J3XNvOYIa1qlBk65hllXnFXeXqoOLQpvygcwNRfil3AGcpwzwlNloem3ozjnt
+IFvYJYzB6q4SMl1/a5uLrcc2frq8tbG0RhU+ZEhWR6sIEOBQhkKZ9LZbJ1tK9buJ
+M0meaIt5gVLAVbI5vf+2Lvmlv0+E/a4Zn2exl1RcBYATNZT1gC55m0z5PMzG6Bc4
+tOAhPEo3WpfNjIrFeXcB0ksk4mfDIWKlA0mc8A+faKSSMdiDpeU4H4uZy5pE/hVv
+2VyE3Ej5PoA3DajRzgQ69YlojTYnfnPyJErCBZhtZXTtRY7aDm9/xBT7FZ06RIhM
+BBgRAgAMBQJC29vxBQkJZgGAAAoJEG6UdZTBUkMakjEAoINKV6yLAdbBhXhvMsqK
+0N6XOghJAJ4mSgdwgv+sIOaPKQqCm+PL2M0lPw==
+=4TlI
+-----END PGP PUBLIC KEY BLOCK-----
+
+pub 1024D/AA0077B0 2006-06-13
+uid Kev Jackson (apache key) <kevj@apache.org>
+sig 3 AA0077B0 2006-06-13 Kev Jackson (apache key) <kevj@apache.org>
+sub 2048g/8A6DD738 2006-06-13
+sig AA0077B0 2006-06-13 Kev Jackson (apache key) <kevj@apache.org>
+
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v1.4.1 (Darwin)
+
+mQGiBESOfuoRBADiCLjvY8EG8cDrfNvPaVJr1/8d8GDoLjBCeJWl50M7j1IQDB+r
+rzBPXOzhoqiNRbZMkpjv8ofa5hVOQitVS4B69FA07RbuiQNTKg142h8ogtJeAI1g
+eXuTZtmGE47TOpj7FMG8bHOmoJdQMkzUsdOhEAyqRu4noknuuIKgsE1kYwCgnhaH
+9KBlpKaRG7Bb2BH6da+wmKUEAIaBeZ1aSQodUzDqnGjCd4hZbpzjyWg7O5BylNhK
+ogMY95BvwFRD8WFdSvhvH9VKBtSuNqg/6gIkqAljRRESVxL4QrzlYSqF513kK1ds
+lUTmqU9Dvaf7dkH+MYnkPVTP5tMZVCT7HEt4F6HcqlaZKlz5jsu3R53KBx6XZATc
+SEGbA/wOournJ64We8sXTJGHFupvSLBy3nh68mPLaplzTnH2al1DLBnoF2giC32v
+ZGG+e12kWE+fyyQ3pdAIRHgVjZ/ckPmcmxnVcYrhzbgV99fo2+JRh2SVrLrmvw+G
+CKiUtNHn0HS1klBKSj+3ML1AQQlbyfrcVSf0Fefug51BqoqU+rQqS2V2IEphY2tz
+b24gKGFwYWNoZSBrZXkpIDxrZXZqQGFwYWNoZS5vcmc+iF4EExECAB4FAkSOfuoC
+GwMGCwkIBwMCAxUCAwMWAgECHgECF4AACgkQoL/5PaoAd7BnTACff9f8Y2RFB7O7
+Wjncyb1XbEwJB/gAninrR0isW9jGx49GmSnQCjtO9k34uQINBESOfzMQCACP+GP2
+x2nE2JxjUUjj16ftOxUivbL8L9ksplx41n7yeRvu+RzOXcjlonuld0LYxprNsHGv
+mbAoZj93QozHQIMfC2kfnia+hxCcBPMbev9RPCqgogpb90BtV0f9HGyWXs2QTgWG
+R2hyjq/RpwtA3obSXw3pb1CnXW4stV65WAdd72KDc66wRR1gmjxKQx6b1dGcC+E4
+HyOgu2CDtr1ULPeI5U4BA4y8FLgDfYwkxp6vj5ViegGP7GlMa3bSgNRGsYX7VwgZ
+pmI8WY4B5k3/Pyv2Toe6/5zTmKH8WlyZd00ede/tbFTqQLg+EylAcWJ8c3asood+
+SjCwTuD8l8a0wpO3AAMHB/9GXkbBUE8cbMTaS4yj7UL5iWRVhSPo9IzMSrzaXmZN
+8ykX96ud35BCEfmYgty3USMk90Rs/PbwB4Mh3h1ZTXqRWcfOXzJ8kMabm2RANyf2
+H2DvGKoFPtpX/9I13vo9qRLRHVRENNg+3JCa1ii8cq7h8bWvTT0VxX/rOG0cl8nO
+XkHTUARR19cGPf6XkHEcl+u1pAxIJGqY/gVowjyFGZs+RXFl/q/Vrgu+lvvxmryd
+yEdeGdsBvQ9M0KKr98w1RiJnDUkSqI711xwlVk14Uu6Xke0oB3bbpe4UxD52avAC
+yEzYY7vbpe6XS2+dOcZxWE3eur6SfsucAkj4Ib72mchhiEkEGBECAAkFAkSOfzMC
+GwwACgkQoL/5PaoAd7BQAwCeJFb9yZvOWfdf73A7t2MvPXn1y6kAnRquMmA5eVdh
+HbAUXWyYuT2OHOSD
+=F2q3
+-----END PGP PUBLIC KEY BLOCK-----
+
+pub 1024D/DE8884A0 2007-04-27 Xavier Hanin <xavier.hanin@gmail.com>
+sig 3 DE8884A0 2007-04-27 Xavier Hanin <xavier.hanin@gmail.com>
+sig 5F298824 2007-05-06 Simon Pepping <spepping@leverkruid.eu>
+sig A99F75DD 2007-05-03 Rodent of Unusual Size <coar@OpenSource.Org>
+sig E222DE4F 2007-05-02 Mathias Herberts <Mathias.Herberts@iroise.net>
+sig 911203E4 2007-05-02 [User id not found]
+sig 302DA568 2007-05-03 Rodent of Unusual Size (DSA) <coar@Apache.Org>
+sig 2C312D2F 2007-05-03 Rodent of Unusual Size <coar@OpenSource.Org>
+sig F12F6072 2007-05-05 Fred Vos <fred.vos@mokolo.org>
+sig 3 311A3DE5 2007-05-05 Ruediger Pluem <rpluem@apache.org>
+sig 3 88817402 2007-05-06 Thomas Vandahl <thomas@vandahl.org>
+sig 01530235 2007-05-02 Luc Maisonobe (SpaceRoots) <luc@spaceroots.org>
+sig 5F6B8B72 2007-05-12 Stefan Bodewig <bodewig@apache.org>
+sig 9C85222B 2007-05-14 Henning Schmiedehausen <hps@intermeta.de>
+sig 4358C584 2007-05-06 Vincent Hennebert <vhennebert@apache.org>
+sig 0B7E6CFA 2007-05-06 Sami Siren <siren@apache.org>
+sig 4CEED75F 2007-05-07 Nick Burch <nick@gagravarr.org>
+sig 40581837 2007-05-08 Nick Kew <nick@webthing.com>
+sig 6BD872A0 2007-05-17 Michael Busch (Lucene Committer) <buschmi@apache.org>
+sig 6210BFC0 2007-05-17 Jean-Frederic Clere <jfclere@apache.org>
+sig 3 990ED4AA 2007-05-06 Knut Anders Hatlen <kahatlen@apache.org>
+sig 0F143BC1 2007-05-22 Matt Hogstrom <matt@hogstrom.org>
+sig A46C4CA1 2007-05-22 Matt Hogstrom <hogstrom@apache.org>
+sig 152924AF 2007-05-23 Sander Temme <sander@temme.net>
+sub 1024g/A5EB8D3D 2007-04-27
+sig DE8884A0 2007-04-27 Xavier Hanin <xavier.hanin@gmail.com>
+
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v1.2.3 (MingW32)
+
+mQGiBEYxng4RBACQpDi0ebPGdHVAdV14aK47MzFkFJEbCisBgcZ2OT/pyPjVTN+9
+Q3NtIusVuY/yEeO4+tb+YTbBiwNsx5p91Rder0prBBVPr9TGN8bV81hnSHfVCR+O
+oqrLj2Onv1qsMslOuZR2m1d/i6cFIKV0CV9EWOcEJZ6UEP9CXP29ZzjdRwCg5NgW
+YfergzvpVtON0E5UvjFnGmUD/AoWhJ0CRxw8xj/EAGS4xXO83Ydf6ucu2PwqUOSZ
+N2mMWyBpr12sQH+iMjWJW25GNobwJBKzfvrojujvlU4uyNIyD40sPeH0UrTwLbL/
+Kek9zp9NxZ9wawjzZvdp8sdrOZ54o59/7flAjL3iqJRtLQSeyQsfZaOSNRxsAUiI
+obn3A/9SEtJdF6HM6C7V57WdKIHv6uVocdZNN3zig2T9uP2Uq1VMIEYtllRNX/4V
+9Vq+2KdV72DnlMuZIA++o1n57d/LgUmbDd72AAZGNJaFq39CV9YElXziO7BVOjAg
+MH9kNxCywcjcw8EFa3NCFcOKMESBn5sHu1nw/Iu1Z9TtagnJwrQlWGF2aWVyIEhh
+bmluIDx4YXZpZXIuaGFuaW5AZ21haWwuY29tPoheBBMRAgAeBQJGMZ4OAhsDBgsJ
+CAcDAgMVAgMDFgIBAh4BAheAAAoJEAP2jL3eiISgw0gAoKcAgjjfQWlqnQNRJQ+8
+A7H5ioIZAJ9qApxb1iH8ulGHjiBOjiSgQq0SNohGBBARAgAGBQJGPhhDAAoJED4q
+b8JfKYgkB8AAn28euVJz8OQZvoSw89voHvcVzewGAJ4lm2R0FCSIRfmHCl+5aSYw
+TazeNYicBBABAgAGBQJGOgiqAAoJEJrNPMCpn3Xd8Z8D/1Z/ml/qcIf1yDiYQTu8
+O+/so0ZlfTYlEF6XrW6WjZDIhNVAAT+Rk1E3q+FvZfMq1BV1mubsCXRtcwt1Br3z
+MWIuJ7lBZl+T1Nu2sxH9H7FAvY7Bk8p5WecIaVdNyFxC98vGYAFs0aRRGSeCFbEu
+oW5XXxUAkkWpIT/aG2y3t4G3iEYEEBECAAYFAkY45CgACgkQFUWz/uIi3k/mCwCf
+WUNeKG4a3hgDhMOyZ1FGFpDnle0AnR1yXWaEazJD5wyTtnnSE/Ajk4L3iEYEEBEC
+AAYFAkY46MoACgkQY9CtrpESA+SOtgCeMIh7BKJeSezB+h1JQmUyg6EuNWMAn3pN
+aMYYEj1LL8R/2ZxBNbU9njNXiEYEEBECAAYFAkY6CKoACgkQUI6uxTAtpWhrvwCf
+c2uhmeog5475d9hTQg94MqEo8cEAoJOp95BdZ7xd9ayJwL4LmBVYaIMAiEYEEBEC
+AAYFAkY6CKoACgkQ3bpkuiwxLS9rvwCffwzrqfIJghWUoXhJsa/m/PSLiogAoM3j
+x2xt5sG1sQQbzM+U4VHhRmWAiEYEEBECAAYFAkY8xoUACgkQmHDv8/EvYHKBZgCe
+PkYoQsESFkBkVyiSVueICUvg4G0An3rqc8/Beip9a2YF+7UYsKKJ1e5OiEYEExEC
+AAYFAkY8UYgACgkQTAQoGDEaPeVNwQCdE4UB1RW+mjtYEbgxkZSjdaV3IKgAn1Sy
+hoOrn3S20OhaZht5Y0EksVVEiEYEExECAAYFAkY9o64ACgkQLrlGgoiBdAKz3ACf
+RkJXrvpQVQlk9//+O0W4BvggGxMAoPyvjRXm+Ie+nPAII74kL7croRWsiEYEEBEC
+AAYFAkY4+5AACgkQc92MFgFTAjXIMgCfXfRlxPUwlzLWotr0BGQVK39JXyEAnRht
+cgH/yscqbkvi2JvaVWkV/T9JiEYEEBECAAYFAkZGEjgACgkQohFa4V9ri3KpJwCg
+4v63DT9Ll4+mqnAC1/HWIgSfQ8sAoN+EQ15zUuI0nuSyG6UCw/UUZX82iHEEEBEC
+ADEFAkZIxWEqHEhlbm5pbmcgU2NobWllZGVoYXVzZW4gPGhwc0BpbnRlcm1ldGEu
+ZGU+AAoJEDKGTkGchSIrkUgAnjI6jBaidqIjKhusVm6ihmG6LEIdAJwJnc6YRNyY
+88MWtd0XRghD6ST174hGBBARAgAGBQJGPfdgAAoJEKBy1NBDWMWEYEYAn0RS69vJ
+1EVod7WxAecb0F4tyJcBAJsEnTiTRMoNmJmRe6w3WqhqdLQUeYhGBBARAgAGBQJG
+PhN/AAoJEAKlpgULfmz6aJIAmwcQI5XDWrLDzSFRJFuW3F1zl7P0AJ9GQYDvu4mI
+c9ZCcaLdukbY2e6FGIhGBBARAgAGBQJGPyoEAAoJEPXCYBZM7tdfbQ8AoJVSPa3g
+Cmc5ghLz1X12r/QBHPPKAJsH6g/0hcAou2ZUfVhOE7VJhpeGkohGBBARAgAGBQJG
+QLz1AAoJEG0LxzpAWBg3cXAAoI2rKauHeIDRwh05S8iNGKTtEaPMAKCMHrqbLsbl
+0P7XxTpZ4EKSvOkQ6IhGBBARAgAGBQJGTEaDAAoJEB8hI8Nr2HKgtRoAnReqmHxs
+MbATTtCEF+WbTqREe1+JAJ9pM5VmM/Apfh1hPM8i55Q96BP1h4hGBBARAgAGBQJG
+TIFwAAoJEA9FCiZiEL/A4j0AnAsAjAu6nDTd73TM3S80JtbuatX8AJ0WBRJk5ZZI
+TmnMyz2yp6k57tyeRohGBBMRAgAGBQJGPbLbAAoJEOHh8rCZDtSqCOQAn0SVan9j
+r55MJrDGk8D3M5pQvTd8AJ9uU45i0OQUP+zY5LSacNtOzSy6MIhGBBARAgAGBQJG
+Una1AAoJEDLB1u8PFDvBK+EAoMjrujpsE1XQs3YxDwz5HHSWv9E7AKCJLU0W2MbF
+OIgs9Smxz2LbuYH7lIhGBBARAgAGBQJGUnbGAAoJEMuuvjmkbEyh9uMAoJ2fBgZo
+2kl+jOzhQnXHHDHzyLyAAKCR8Z6tloKXkhPRIV/N/OjwIW0i54ipBBARAgBpBQJG
+U8qkIBxTYW5kZXIgVGVtbWUgPHNhbmRlckB0ZW1tZS5uZXQ+IhxTYW5kZXIgVGVt
+bWUgPHNjdGVtbWVAYXBhY2hlLm9yZz4eHFNhbmRlciBUZW1tZSA8c2FuZGVyQG1h
+Yy5jb20+AAoJELK+vEAVKSSveJAAniq8wB4b/DdGTK9Ygmu5Y76tqsw/AJsHGkn3
+5JyiHbXCvVujWmPtY1/OZbkBDQRGMZ4PEAQA+T0YRtd2aeXU+AOJnrhChy0dptVt
+CE6PW9LrwZGqeV4THNWhdYuWRWlyzgU4HSfuk1Svu3WKMbnwp+Fv8fU6MmidOvEJ
+p9IV1l4DidIXyhAacwpCN11hXvj5cHdF4KhJr/NG9oedin6nQoQFRQ7EfkUjAXOf
+MCZnSps9XBJdy3cAAwUEAIGrITayVmWfUgjPvQg8L+4R2i31XQ70HIELQtYDs0Ln
+iWrwZuO+aLI6Jw1RbZii6DM2QsVdZj+v36S2KJTvXeJVyb51d0uXYFxre1uCZrb2
+I1Lle8v3GVQvlrTpmZIPhOTotskKFWUCh2jqgLaEvJPpRWgIRXPF4g12nBXcLLXE
+iEkEGBECAAkFAkYxng8CGwwACgkQA/aMvd6IhKDVtQCeKdUGQS0lD0nAJsGiSbKg
+gLwEM0sAn0dUIIsbxE0fTHQVIQK4bII82UhZ
+=jwNf
+-----END PGP PUBLIC KEY BLOCK-----
+pub 1024D/B80602AE 2008-10-22
+uid Maarten Coene (CODE SIGNING KEY) <maartenc@apache.org>
+sig 3 B80602AE 2008-10-22 Maarten Coene (CODE SIGNING KEY) <maartenc@apache.org>
+sig 5F6B8B72 2009-02-02 Stefan Bodewig <bodewig@apache.org>
+sub 2048g/9C7184FE 2008-10-22
+sig B80602AE 2008-10-22 Maarten Coene (CODE SIGNING KEY) <maartenc@apache.org>
+
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v1.4.9 (Cygwin)
+
+mQGiBEj/pNYRBADN+YqWzDBLrOgiUCul5TWVLgUReY2VMaWh3Z732AMPJb1dlbtW
+B8sRqyvtQxKIPIItl6oaom5yzuqc8leXQCJBVRnnBkv8cMomhOD/AuzaA82egttI
+C+CHt/akaUPhgrzhry7TZ7lVtJZ04FJ9WaE+LKAZcnlhCWOSF330pRB8bwCg8E5k
+4TF9z2cmwfRmMwJxruRpN1cEAJ0yo22TkjSksXFmQf0eKVEPaHmrsEjNzIECcz8m
+JrggYDfXIgC2s758D7uhUTlJM7u1L2KTZmiZgiFp6WOw6DnPlBf4PRD03038fAQn
+rGtfC/B7DcgMLS4tCPlGEyeh9H8RphaVSXVCN5IgRV4x0vIhyx7kVz1ZWbAlLEQx
+KHp8BAC3/K9yVkRDa6m+HAZvRP60zxWAwIdiX1R/9CCRtI4uSaLz1Iiw0jni1YkE
+tFe+z5PNa89Dy1bgFWJKxtG1jQVfHIt6nEz2C4z3Xk02+PxmJH/Dj84EOiLfxzvp
+Hm2hA57GrNjJuvG7C7GVFy+bQh8DCkzJfGAaplSgzqyVmP/l5bQ2TWFhcnRlbiBD
+b2VuZSAoQ09ERSBTSUdOSU5HIEtFWSkgPG1hYXJ0ZW5jQGFwYWNoZS5vcmc+iGAE
+ExECACAFAkj/pNYCGwMGCwkIBwMCBBUCCAMEFgIDAQIeAQIXgAAKCRBb4LqMuAYC
+rpMmAKCNSdXDiaOex6L8UmKiGbkEah3llgCgotsI/YjRzQNSvmGfqrgkch6f0tqI
+RgQQEQIABgUCSYbTIwAKCRCiEVrhX2uLckjKAJ9f0JEsAJIJDn80SMIHaEXhJj9N
+tgCeL29JGbUoYjTq8LpoMrl3ZhDaqEy5Ag0ESP+k1hAIALRxgmE+fbedOgRhLl4w
+pZyt3A/EXiZBY/9UDRAWpviCp4S3cQ5cjhv3glj8IAHw2ntuEJ2ksjG5r/swQ38z
+quTdDY4YT/Qd5NDlSX+KOGL69mda6kFFiNeJerDcM0FPjiV3MWcNp4IwJTs45EX2
+ep17a0oUG2AhDjL8c/32elHzXtkzoMPQzBWqHdTO4gkp/2iLw/bTpfEJLtWKsWJS
+lgnLobisAnWjFBo/NgtjxaxGjwIjTn4OZNQaBi3P46PP9FEj4Hp791i1YvkBYrIg
+BaQY96Fexd/7FKyvBefUmlxZPyY7I/OI11KWifJoSj1qPxZb+90UQN2r9zySDdpQ
+h0MAAwYH/jkSE2KTx5R/vU+bnz11Kx3NRq6kxCQBGUclPGgUxk7iSWfHggQ/0U3m
+1TI8GL687dwb8AO+f2b4nov4g4umdoddu9gPlHvpBcQ1BGx8JqcWJJ+F7lWUeVw+
+bqp5Qcttm9ldw1HEbUF0l81VFpLNDV6p5z3zrXGE84fk2BEMzD23IhMwNnWDsDVu
+2S46h6BuK8sdTzgP5GTXw/7c7xG2zgfMHVUBWtuz5P6D8vl9gHu6unuLIcKspOgI
+Vl2ygZ2VsxGUscyR9soLrem7hZaaQJfJqH757X3K8SuGZY36mH69Ziwzs1gQlof6
+bgumh74P8Xu+StvFwdZn1+aFsqcoDwuISQQYEQIACQUCSP+k1gIbDAAKCRBb4LqM
+uAYCrpuxAJ9NYy3kPGHYAZuFSeygBt3aV1acGACeP9bIj81YOQn45Dvgmb7zqYBU
+g7o=
+=jpcP
+-----END PGP PUBLIC KEY BLOCK-----
+
+pub 1024D/3B7C75B1 2007-05-29
+uid Gilles Scokart (at apache) <gscokart@apache.org>
+sig 3 3B7C75B1 2007-05-29 Gilles Scokart (at apache) <gscokart@apache.org>
+sig 51047D66 2009-03-25 Tony Stevenson <pctony@apache.org>
+sig 01530235 2009-03-26 Luc Maisonobe (general purpose) <Luc.Maisonobe@free.fr>
+sig 6A017B17 2009-03-29 H.-Dirk Schmitt <dirk@computer42.org>
+sig 5F6B8B72 2009-03-30 Stefan Bodewig <bodewig@apache.org>
+sig B1313DE2 2009-03-30 Robert Burrell Donkin (CODE SIGNING KEY) <rdonkin@apache.org>
+sig 40581837 2009-03-31 Nick Kew <nicholas.kew@sun.com>
+sub 2048g/82AE20EE 2007-05-29
+sig 3B7C75B1 2007-05-29 Gilles Scokart (at apache) <gscokart@apache.org>
+
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v1.4.9 (Cygwin)
+
+mQGiBEZcIBkRBAD5fm+1xVyIldiodrRlBF+LIcyKhX/tXyn7BL82cf/8UwxHdcqm
+9/cihYQH1ywj3fiVEKdnoHWTtZyvNtA2c2JUUJfqlD81SZKi+pnRzDpnBLmliaYN
+CZNo4jlk5/Ft3fWjHe3pYISDrJkMsbfdN59CHtgor88UVaTRANIrc044RwCgv2p4
+kZjazZhUnALYfUGBKTiMnhsEALk8pYW3uVtk7Qlor7KNx5YfSmaIxi/LQnk9i8LQ
+r+N0ZA/vMPMxwA7l1hsuQA/LgElTzS5E9caqVP+n+RL0wMNDfova5tar8LgGa8Wl
+GC1A4aEF3DUTLuKwdW20ZV3ai7ROaoDwGcMzxQxJwffMVlsto0DgX+cw17g6ld2u
+/jpABADf6DfQn170yeCwA7v/iQcSau3vDquMIDGCfE7USUEWop91pi9hs7lEkoDG
+V/uDC+XpT2jFD6z4p2bhdD6CL3xXk1PbR/4W9Z/hzQQs7IeKtxb2ZPUkmTGkHa1b
+1AXBjk0COaYbFMDHC/1M7tSJVitOjJgn6SzvvpebPzZCPPJhu7QwR2lsbGVzIFNj
+b2thcnQgKGF0IGFwYWNoZSkgPGdzY29rYXJ0QGFwYWNoZS5vcmc+iGAEExECACAF
+AkZcIBkCGwMGCwkIBwMCBBUCCAMEFgIDAQIeAQIXgAAKCRCusBoVO3x1sSe3AJ42
+g9VSRlSotQF09SOUOSy+OT09HgCgjdxpDK9DePZJQqNvFiFlVHosOFiIRgQQEQIA
+BgUCScqJzQAKCRDJx5JOUQR9ZnA3AJ95e/9F+PbyG644fqHRbNRaoPK7IwCgklmM
+i91C3XHtkJIFlkIcrSDYmauIRgQQEQIABgUCScvpOwAKCRBz3YwWAVMCNefhAKCe
+NXk2pgPR+IQ5DTynLD9I3zpt5wCfSslyVN1eFyOB98cAvcQ6ZSvQ41CIRgQQEQIA
+BgUCSc/ynAAKCRAkwaN4agF7F//ZAKDlEUat3dBPe35MUAd+nLumAx0IwQCg4wsJ
+5gf8UUWQGRn9kQqoCpENhXuIRgQQEQIABgUCSdDLeQAKCRCiEVrhX2uLcs3xAJ9f
+MNVQ2cvirIAWAWBOWNVxRuBVgQCgmxIdCpUQxXCB4wJkNjjTqY5X+KGIRgQQEQIA
+BgUCSdDjEgAKCRDVM051sTE94urLAKCc1IeUJf+Mjssykz1bz9qCoN9KCQCfZ5+q
+4QJxgiOzLSjvNBSBSKrSdUmIRgQQEQIABgUCSdJ1/wAKCRBtC8c6QFgYNxLjAJsH
+jscYS54FPhD6UQrm40U4hRKD8wCeODdDmprYA+G6BBF3CM7uXK4H2Mi5Ag0ERlwg
+HxAIAJXnRz/mS9LlEoHKCvvoY58OAPIjaSqfdNLWGBSjXOsPKSRIb44PmakBGp8r
+xCZdgwIRv/qHzkBVjiYD0k4XkftCwrz2yGkzcIgXl6kW3kCkwkrNckFoDmTCGshP
+BuTKJctwIDWQW38ORfObOs5dRCzmvfI6S75JYUAi/EEHDtXuo3UjLPEWVEA9xoOn
+kUo4MehCRgOh40J3GDyeOaC9/2aXOBLOdNJpciyX/035/rxxIE+FgwYVssfnmph7
+rguczh1VXWtP9URTUHJYis71wCjil1AYxHwTHg791pwde3JifieyNYLCUK4jS0XH
+RybeIzrq68pHQGVakrV8alIf86MAAwUH/1PtIDR2YthX7Mwo08H0DLaDpU5sioAg
+rU6NytREJR6VHDgRlwFn4FT1skx0yZw4TjoOoHfs5u59pnalRjPitpWPaNRK2Se7
+HsWv83nCZVqXxgi0Zr5xsNdeohOMcKlFhJfu7Q4UgCX9RjMDFVBWdPeeU2vNDdMd
+B5XgmQIls7bq6skeX2nZCa+R1M2QK5ckd+qOYGj1Qu2eJbfq0Tgo21s3tgX5Y1nD
+wD3VnBV8oqfUNanAnp/km4XlWwI8dk6f5GliWJ7/aKFOkg5IoAjJ3CPfLBrPC+ns
+TEuMtaOLk0Bb1rIisXn7Pz4b3EpzetD/lJdVahLy5Ko2lE+OQW3sFJCISQQYEQIA
+CQUCRlwgHwIbDAAKCRCusBoVO3x1sd/FAJ9xjqbygtW21vUNcztbWJroKaL/DACe
+PEZ4/iF5mYiEb2kEZmS6aRhVxuA=
+=w8bP
+-----END PGP PUBLIC KEY BLOCK-----
+
+pub 1024D/7BF8BE8E 2008-06-18
+uid Nicolas Lalevée <nicolas.lalevee@hibnet.org>
+sig 3 7BF8BE8E 2010-01-21 Nicolas Lalevée <nicolas.lalevee@hibnet.org>
+sig 3 7BF8BE8E 2008-06-18 Nicolas Lalevée <nicolas.lalevee@hibnet.org>
+sub 2048g/64443553 2008-06-18
+sig 7BF8BE8E 2008-06-18 Nicolas Lalevée <nicolas.lalevee@hibnet.org>
+
+pub 4096R/971731FB 2010-01-29
+uid Nicolas Lalevée <nicolas.lalevee@hibnet.org>
+sig 3 971731FB 2010-01-29 Nicolas Lalevée <nicolas.lalevee@hibnet.org>
+sig 7BF8BE8E 2010-01-29 Nicolas Lalevée <nicolas.lalevee@hibnet.org>
+sig 0642FA40 2010-01-31 Lionel Porcheron <lionel@alveonet.org>
+sub 4096R/9A54153C 2010-01-29
+sig 971731FB 2010-01-29 Nicolas Lalevée <nicolas.lalevee@hibnet.org>
+
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v1.4.10 (Darwin)
+
+mQGiBEhY+uIRBACUmSXD8kBukXrvlRHNVCvo1mMNyaGhHbkf2oF1Sr8o/g10wRLF
+1zh2Ohgux/Z0gbjumhT4WG/kADsk0r8vSeuiquwyhHIg9ZXBgs4/JFtSbVrahxkG
+gWIhr1cLKYSAeFe20w/Bn3zBUtfKVN3VaDyDFJkgOsu/0mXPU+3JbcV/CwCg9M14
+Pk3MtDg2xgfoVlm3CiT1byED+wS8Rmm9+spz8oMA8vKxKtIb5vvlnnIdaSs69XtT
+1Iv2aDpCIlYh820G2mghll2f9rfTn7aiiL8ohyQ55N5tSwVdMrUKbsW2o8IreXuJ
+XvGxuSAxpWgKluuH42uHXitO06Ir55mkhHG6M06cMn3hEXU4gJRegCUQW41vrCgn
+zorKA/0ZOdFGhN0NCACB3o/bjQFINs5MpDpkPZOYkb0PSgtqto75jZQEMqk4vvlp
+Z0430MSzA66WSU9rPv9b2Ck7+/bqxFx972tSygUg3w2mSvqab2z//HVB6XQm+R1b
+3XGaEMM19nG3K8XJMKolhcrvwbT8OS1ZajEJlvEt0jpfk7rYpLQtTmljb2xhcyBM
+YWxldsOpZSA8bmljb2xhcy5sYWxldmVlQGhpYm5ldC5vcmc+iGEEExECACECGwMC
+HgECF4AFAktYr7EFCwkIBwMFFQoJCAsFFgIDAQAACgkQSDwjxnv4vo7YZQCeNnaq
+c5+4/3NSQjyPNnRBse17FS8AoL8BQSWRvCzlti3VBA7UOamcNM+eiGAEExECACAF
+AkhY+uICGwMGCwkIBwMCBBUCCAMEFgIDAQIeAQIXgAAKCRBIPCPGe/i+jhSdAJ4y
+bjviXLP22CAsOZh7hn3rkL49MQCfUnJIv8ErY+I1EH+sWMNnj91aY5K5AgwESFj6
+5hAIAKO3XJPcBZBLwpYtOcRZqyUSOQ9uHe5iRtqEFP3fqibVvIEMq7jeMa3q+Y+0
+i6wSbDEnKS3VfTv5JXyIXyK5k9bN8+BclzXGuyzFrz05b3XmkaNZuHHtyfPzj1bt
+FO0K1Bh8utejday12ZK8gfEaTZaG14027BdYtoR2YzrilXXzxc740nDOlgAU9pwk
+DqWR8gMOUf4l0mLGwG0F66CZJsIY8x580afbCUOTaXXyp9wHMK4ko9zm6+dFT/4c
+D41eovaqP+GSxyBow6A9pSD8nFI/YrcrfxvPb2DMLhkBYG5VzYYOisRY/nFot04i
+lc0v2HNV7RWrylXzlVRIo9SqC2sAAwUH+Jr/O+GDP3kOmmE7iCCg16KfP67wG/oN
+1+pYtSDTSgn4f/Ec+HO6vbkc5A+nfetMdgGnbVnFIdZl9BcNb3xqCQMkGcmEFvmJ
+YilxGfqngnu+8kPXJMEfHHTcEXGUme0YaPrJeQHiu2C75n9uuvUMtPO+kCfxfEY1
+TMPnHpDKwTGWuOLdI0hzoLSOPBuKpha7Im4SqQq5vHQ0xJmGSwYR5+l2Weob3nU0
+miyCAT4+3FMTQrQ5N6nX8tb8wqRT85sgwMXyXszz9TQ0g+Q5RLmE4jHP3sPEUhbt
+k5LBxPZyxwwzFHgDHmleHP1lzKCHi2K4ed3j/IqOVrhpMSSW8kI9/IhJBBgRAgAJ
+BQJIWPrmAhsMAAoJEEg8I8Z7+L6ODs4AnRqXRAlzNAepkDiRwtJS++ecE0sPAKDA
+OVV69v0Yz7/QqRrLRB66xTj2kZkCDQRLYwO/ARAApAAIbR+GIZgckHwL4vlPeMM4
+eG9gAina2Lkk1h8YuwkeryEKXwE6ggQOjqvv+MiqV7EhFL2EIDDL68YG8Hmih6Ml
+gzlrDwiQILvx9KGKAVRQGiknDz3thgK7rZ0FINdkB0OP04NB7vGX3i+dZfSknN5m
+WWucQDxxtN/b6QsLOnsepxdYPU6fcMLvrgXBMwhbFkWjcsv4rkwWRWcx8KUTADOJ
+vbndMnbMp24DMv5VNYISri+VJ4PKEZyFBeG4NT4KhL7/tJ104D9zERWu8mWA2bNP
+hl1hy3woX4ueBmAUdvKuzFgAEnV98ZTzIGdEPrWVz/T6RccRjwpfxKB7kNVzaPC9
+lNoOPRqK5ir3wVhPYAdE+cNJ0IZ0X37PSJlp+ZHEraR9iGI2AIG7bBwvvtcDqMLk
+r78aY8RrAY3+fXScE+yBMynTKWxQXoRJJAZhEJbwA7WVMw5ms+ooPmqYCNwEoOe+
+0KeNC3fxkbFsU9Nt7kqVKmqMAUsOonNAB161JURhzAoYbeiYStq7ln9nEQ+yuZsb
+eLs+j6vyAqw0QmuIphaFevz0oeXXPDIoSRMpDiVmrfn/T+283ilZOlYEt08YhSqJ
+68CtGhVes3vdx/m4t5Lr2GK8Y8ogOuwdM7v+JJNbhlgYu6CSp+rHsdnh6Zi8zhFG
+OMKAzPnorBE7MbzgrxcAEQEAAbQtTmljb2xhcyBMYWxldsOpZSA8bmljb2xhcy5s
+YWxldmVlQGhpYm5ldC5vcmc+iQI3BBMBCgAhBQJLYwO/AhsDBQsJCAcDBRUKCQgL
+BRYCAwEAAh4BAheAAAoJEDeg4GKXFzH73nEQAJZD8Ol1LfaD4AoA5gR7eo1VuIjT
+SkwdufYyo9PPuimMZEt8hZk0bq56Q5g6uxkJqegeBbDTarreBVx5liy4NovqWknd
+UqSMANmB5tRtlUmcTTjcz/1BJ4ynb/Ty/YqRljrFf0+yWII9Il3H/gCwHnv2cXun
+Iu+x7y1wKuJg2Dg976jIBh1949Jddqz+Hs0NzTuxs56I5yf/mMsVz3QtplgsIPXB
+0xBVK5W/HY6Jx9j4qpjWLklZ2TDftzoYdO+mj/RK4n0xxeA2HdK3+XFvJ4fn9xY/
+9l/fk2ElM/4zUAKFDeyYyAw/x34nJJF1KDcp46GaXPM3CkvTweYEsJ5rruuBTYLb
+IZxBCHSBsCZwHHCai8+aj3tQywoq7tyLtWfWdiNE03xJumv3O0Zk7XXmAAo9fhgo
+91fI4r1hkyy8GGZasXeMz6xyRFzEJyNP9O6a9iAt7w4zlf/J6WrG6n3RchAp8wPi
+tvTW6hgZdgr2pP4a7i29lzUBmLbGhOYN9sgbZxgRUiHGee/F++KNV48FG72VgNTj
+LYPnxvL7fx8YZkMiWLfEqlMyt7Dy8kyF4SnWH563kOVzfAxKdxLgNWfll4bBA99m
+Yvx7b0H/UTAvo474PvJyAPYR51P0Ekq3OSIcSreH39I4as0WNjRNOoWpO4IQP+3y
+tIaD+8bMnmhR6l/NiEYEEBEKAAYFAktjBtsACgkQSDwjxnv4vo5v2gCgyeuyy3UJ
+dJjdR7NGhGSCHIn27QkAoMQ99L7qjlYOsvkmSPdPSWwpV03qiQEcBBABAgAGBQJL
+ZXYVAAoJEGrA8Y4GQvpA8egH/A9b3bfHKLCLGtpn859V1IoLRqioze33dr3I2AaC
+CEaxQQbDQZeJWB7eKtnB8O1YuqPTFHH3H9xfyj5DtA2SzhaE1hSHPlYNgGTkfTaB
+0NncbD708yAisyilKbDilBnmcxwLbACadO7BCHE47FAbMT97qm0Y270SgN7bwh2+
+14SCjsivVAoRUtYshJxpEQAFYBNi76yi1w5ZEptPCvobI4dcabwYb3rZXVKBb+20
+OU0oeVS1wpf33A8xH1TQc3KtcXgEAwNz4opEZAgWc79km+2BCLTxidHSJylqkrPC
+QWo12Du7hPwZzeBKl5wCwOq2qzbFBfB9yVIePrE7CUrNHEq5Ag0ES2MDvwEQAMFy
+Z3VaTm01L6Lv3BSvBNydsRvnK3jeBKlWsiysI7uJrzYBIIcWcyE6lDjobmEegu3Z
+7lef3/5NmzR2QRhxro/oWXhzZqTfmnLIvUiqRLGD+e7tGrabIabWqjies55lCZaE
+vJOFLoEoIgzCPhRcPidfnHfbctq0KIkkP3jbdWmqcY8Y5na2t210jXiDRdGGwPKY
+G+2Q+4UUsfFvHS8Q9nZJdmm87hWWa0XUMYOmbE0ffewad2LF3PpT2NK/qX/7jqdX
+N/nnSoMQrAuJBmJAQBtdDfgN6Wddm5cedoc2fDcsm3rLamS9dgW7mrNfcIvt3ECw
+nlV1rReASPU3CTsuwFxB89VPHOemQ1o52IpW+zO/g/11q5ycmzjteBbL6uL4vZRB
+G7VUCi2fKpWa16FhSeZ2+8FMUW3YiS/LL5r1mtovZZdhY543nzuHUYCigqUVvzUj
+Dhn3wXgjNNmZbDLPExSacMgvbafeDAGSLtXd6Q4RkFbtxtmwwDmg8e17QW6OKQQ5
+jd5devg2UM053Bji8+SnRq3LgqgvaG90fT85JqtlnbeGjV3CiTizeHbz8ucQ+HtV
+uJewGj9HMuRM1Mgw1UHZ+k+5PVkMxmMN5M3O92a1DtYtFxXAK6bbiHb4QA8kSScN
+HljHA+lJYfYrQY1vVgbHuCkoE1aTJv0W9B28CwolABEBAAGJAh8EGAEKAAkFAktj
+A78CGwwACgkQN6DgYpcXMfvZ4w//QphYIrHnVmlEj3GUXX+DU1vhrHbpFMcqWkSA
+xHTDWgbrJdOyf9iMperYo0/3u+DnGR/vcb1LvpIeOtNgAd6SYeSmerE3CZlV/0kD
+LyA6OfyinX8vxaXxgcObxrpcB7rpvom7xVE0tUB6vJtGF9dfKQ/VVFtQ2812Xv22
+cFcAZ1jIqYsIZ/TK9aqRl2DqMTCpLWWaoR61hlTc/TeAud67hCDxHZfuQpXrQ0RW
+5dIlg5dKSlluT3dq9XZ36LctgKpy6lX3OzJts+W3YN7fkKKxHtCBqltUiUAQDZVs
+SJTbV9mheymgLJPqcK7ZUi2HDoi2w993KRUa2GSmQpU0qBaWPJQapY3CueAsSCV5
+rMb6BIfHGr96bDogi0h7vgxieG8TrZrW4J6SDvvzmiIAZhKM78kBBzQ1m8i4xqeW
+a+0ddwNcvOEM7G3uH1P3rThHdkIkcPixAGaRXjsOBRVawdNCouf/YcRZakxBIhHA
+wfDfgVHPFr/UMZC4iMEt9OdF1uWMe/9Eu9LxF6BzN8VkAmJ5F2f5izl0P6nnmQ4/
+BSG8P9yd+0IMyBAXSeMkYSJVZF2EII1qa/zpWYMx9emOkdL7m666NgwdXrcVf/bw
+9EG82hI9O6HI2jQAPMH9WPoungOiOh+TT90IKX5eI+cW0TaR8JeG5A2oYB9Yxr/q
+wepeqtU=
+=gSlB
+-----END PGP PUBLIC KEY BLOCK-----
+
+pub 4096R/9711DBFC 2010-03-11
+uid Jon Schneider <jschneider@apache.org>
+sig 3 9711DBFC 2010-03-11 Jon Schneider <jschneider@apache.org>
+sub 4096R/3DAD980A 2010-03-11
+sig 9711DBFC 2010-03-11 Jon Schneider <jschneider@apache.org>
+
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v1.4.10 (MingW32)
+
+mQINBEuY8zUBEACcQbEoZkXl296KesX/bjX1aCatSIEGIZGiWWTfABqzx55tmfsI
+BBx1HuuVcBlwMZfeTIb5Oe0IQaZ5h7wEl/ezzwQxOezHTwvAbwnZ4oZOrbs7p7D4
+5I90vsw7rn3bPMBV8xuCgV8t2YFmLH0pzX6+gwmSoVfk+RuxRWfqhHJaVzqNYk6q
+iit6NLm2O4PUEeqHWl30RaYPlKabwhoBoFfAzEGIoE3BgukSukO7JmhXGhcS6fLG
+V3/2qvzQmb62PwtuHarIHtaPq4lE0DME0+cXZtLEgMq2nMtPxSssYHk71PhaP4+0
+iu7AwgMfAUbNDFJoAc5M0gq2TAoJk3YZrtisTUhSjMIiKrLB8MvnZZ+MWK1/E+Aq
+XXocerbgK5fFpk7yeEiqvU1/h+S7WSqIDDOqZWeiKCrrIQZAJvz2f5Ak4A8eyYhv
+KXDOwty+q4FL3V76VwWsA7fS8ib9PZqahowaG34DNCflUO3Xj5F9Gk71eBbb894E
+Jboq+n7K7Ayo1jRKu8i+HF6KHiPgWcRvpIbJuQxpjxW4c8Kxqf5iGTXyP7dwRWyQ
+k+DZ2RKzzNBLXCKyQ5TJtgiHXUEwAW21nCaPijOiqjII00GdoA9oZgliX3O3jKsq
+S3llZqwldE97ycfxWenOLn5g47yiCUFqK7/UtJizwYKJC6J3pliC7Kz9UQARAQAB
+tCVKb24gU2NobmVpZGVyIDxqc2NobmVpZGVyQGFwYWNoZS5vcmc+iQI3BBMBAgAi
+BQJLmPM1AhsDBgsJCAcDAgYVCAIJCgsEFgIDAQIeAQIXgAAKCRCNbQrQlxHb/BpI
+D/iB+WagSbCHgwy+vt0ImiPMggmoxemyf8f1Uv1fz0C9gSH6mY6/ovLrXF0YIBGq
+SP8OlTtcz7eKMJPsvJ2n3GrwXyCYLNbL3QUOoHZjnTpmO/vqTtP3jNceoVzW7vle
+PwMTgp6Nme0/DQ8Hqdgjinwd/E8BY8AFpNdr2ZaWwVHT9fjKpxdGTQG0iZIesluB
+XppnqkltNwBkSdxyVpRXaLhMSjlQyx3S2sGZDJPO7ydiR0EnxzkWP8WqNyEkI80R
+n0neYL4HCnwufsCE+sDBiz4p1v6ekUil0Gv0seK+24U+LsEoc6zZatgXzwJ6XEGC
+0L6eNZ6al6TzxhKxq6byzb7XQxASV0CiZKQTTY0yh400+cgFwa3p02hFnvl7skB3
+f6u20tmnQi4xb2f7W++z215qPpbsLHTggmAIguX0oF2aTYBjNDLyu0LCMnm2uhzF
+Lf/kl77V7AUAWHKdRTDhblTsFL2G/O5i8aDGMbyG82ZieOe2LFqZ1EcqD6ODrLP5
+hhyEYmnlEcb6VSQyQwFwF0E6X4MiZbo0ieLwYEI1P6nSfjKr6Ejuk2EwvQe5TTnM
+OwB0a/4jv/U4A3NE26wJKca3LSml3eYPEsOqE7+X7225z6+YeGPGEYCUCu6HI/Wu
+0VDsZ0SjoHYlMyx6q+bvbLhwBBUJLP6aKiGeptDUHYCmuQINBEuY8zUBEADd1HYa
+7X6JLzEyPZOaddJqR6RZoBKBxmfqxcNv+jO4BehqVEEh7f+Fj/P80JwlyjLiL+1N
+tlf/ejfMXrhjqK5uNbVyKRtwwlgztWook+8zJ0xMeYth6UXdFdhrUTs41R4QSUai
+c8X+kEQex1TgjCXeDBiBJgUEpnMIc2OOIZgEHpverdOE3X0WYXqHppC0FCzYBTix
+x8gw6bsgn/Z2mGMTmzHtm1OtIp9mWJQtY+tLa6+3sWiedClrQcWtUIxPqDh68Ckh
+Lwc05TRGryqZ40zU8mF68DQ9GQB7+FUADkViT5l/cGZa1XCEyPI72IjdH4WY2Qxl
+ivXoItQgUPgVBo1aeeoVYFr43iCFMVPKp3qOJTeJGg/qezc3X1TZXNQ3E6vY5XO5
+9d4CpduJ1uOjk4NSSnfpUG+Y/LrCrx8yqO2Uhh23S6KhO5Bx7ar65YBBFhFhc2aP
+sqRfqUSACaDKmO7VvxarYcjvbqb1zzwCzXzGhb3LqIuik8ydkoBB91BDouNM5J3u
+O2KHVhRrnPncyDtL9FQ7Ru7T7NnFdtxZ17BSM6Z7DUHs+PJe+EYBzMN7UDkV7eJ8
+/2HC59QaY+NoNYPyNHOwkTNQyn5kMIwoTVBndqBlSdp5vR+8n/nJ7RNOF+pPeEfd
+hs1rzfZy/+1wP4PWWh1Cj34ZrQjpfDKBKYiXoQARAQABiQIfBBgBAgAJBQJLmPM1
+AhsMAAoJEI1tCtCXEdv8XNwQAI9dF7lvrIz/7D5t0+u43k6dSGVH76tMQXv6yo4u
+tyuKoRieR315SjjgCGZ817bHM3frxyIXLk+PMT7Brbi2DKoftVVLpmVDbSsv2Pi+
+mqez8XjJFoRZNgwbWESjtcNJY10ukwQ9VT5+73kVNIQdbizK51hK13+Etd9UGr6p
+2MZOe+nV5bbKnEdCxrRricbGTOju5x5i5DEZzWGa8W2JZKHsEF/l3qrfYbmn0AMg
+vXw5Robo38ZxxuH3l6O3GEed4aUNLJSmu3gIl32uANLE5kg/OYbupmAuvwBCn7/D
+xAB7LY38Tg4zIrWfhQCzP5IAyxYOZSFgsggpJ6foilOLCgJul8Vq19HV98FsWf/M
+sE5azSIfJI/Z5EWpbaM0xu56nbJ2O18mN0Y3ojz5/ewZo9+ODRm+buCI+Muz5Gs2
+iNoi9D8jtudc46l1OASP7n9e+WQDCd/IwwsUXHqT4+EkM/ZIj31W1+mBZtzIPBCU
+37ibGfpt4W8GC9DtsDk+r0A0+4RurzVYTR0P8iTb4uq0i/ffBPBLVTS1E9D/WcGP
+2DX7YW9e6LhY1kIbjrLR/rDHi95sx8QOCBMridpy8RlXdwWKU/kZ9s5gCYBVKBhj
+/w98LUqT07uWFU98kDugW15Ng8OCogpaueDYi6hA4A6c66EhjdKH9JzigxfxjSkD
+udvp
+=oSat
+-----END PGP PUBLIC KEY BLOCK-----
+pub 1024D/265B4C63 2003-08-18
+uid Antoine Levy-Lambert (Apache Ant Committer) <antoine@apache.org>
+sig 3 265B4C63 2003-12-06 Antoine Levy-Lambert (Apache Ant Committer) <antoine@apache.org>
+sig 3 5F6B8B72 2003-12-12 Stefan Bodewig <bodewig@apache.org>
+uid Antoine Levy-Lambert (Apache Ant Committer) <antoine@antbuild.com>
+sig 3 265B4C63 2003-08-18 Antoine Levy-Lambert (Apache Ant Committer) <antoine@apache.org>
+sig 3 5F6B8B72 2003-12-12 Stefan Bodewig <bodewig@apache.org>
+sub 1024g/A3060393 2003-08-18
+sig 265B4C63 2003-08-18 Antoine Levy-Lambert (Apache Ant Committer) <antoine@apache.org>
+
+pub 4096R/710038F5 2010-11-02
+uid Antoine Levy-Lambert (CODE SIGNING KEY) <antoine@apache.org>
+sig 3 710038F5 2010-11-02 Antoine Levy-Lambert (CODE SIGNING KEY) <antoine@apache.org>
+sub 4096R/84F32FDC 2010-11-02
+sig 710038F5 2010-11-02 Antoine Levy-Lambert (CODE SIGNING KEY) <antoine@apache.org>
+
+pub 4096R/82A7FBCD 2010-11-02
+uid Antoine Levy-Lambert (CODE SIGNING KEY) <antoine@apache.org>
+sig 3 82A7FBCD 2010-11-02 Antoine Levy-Lambert (CODE SIGNING KEY) <antoine@apache.org>
+sig 62B2963F 2010-11-04 Dan Poirier <dan@poirier.us>
+sig 7C408737 2010-11-04 Joseph Edward Bergmark (CODE SIGNING KEY) <bergmark@apache.org>
+sig 02E9F65B 2010-11-04 Luc Maisonobe <Luc.Maisonobe@c-s.fr>
+sig EFB55DF1 2010-11-05 Luciano Resende (Code Signing Key) <lresende@apache.org>
+sub 4096R/70EC4C9A 2010-11-02
+sig 82A7FBCD 2010-11-02 Antoine Levy-Lambert (CODE SIGNING KEY) <antoine@apache.org>
+
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG/MacGPG2 v2.0.16 (Darwin)
+
+mQGiBD9AzmcRBACMqgb7IFvC/nLxw7mUAgHENeZXY3JOQJ8wVBevIbbMEeFvzHE2
+diFydqUXocPexduYr0ahkf033WvWdAiNqDLfVW/HFOsc1TpjbHkqPUHtJ62Ya5tg
+nH4UGN9BYZfMbfVDOSz41lYwmfK5HYgpZN/sBQBSKf2qgoFB+LxYaae8YwCgrWlu
+fYhf7fkKbbdSf3BGS67ggNkD/0VvkXkw1SEnPaqrkKGkPKomCTb2auGxcYYI3/rP
+1m+SGRf0gE1NtocmIEitiR6WvfKUjoMAXSCp5KdnUXmO9rwzkM002KCA7K5CY+e/
+2bLDuiQ3rNiD4mFfG6M+UnmZ+GMFba1p9Cp4PqLNLsCHz67t7hEsscTZQ8mZ9xKM
++GCsA/9P+XFM7JDn9MLhYab9qo1CkceBkthUP6jWGjuAZ00elmBCkpkzNv5aIzss
+xih2GpaU/tmcMjw8FGp0dTwzqdpmbZBLjunRnuBTir4m4l5G9rwl4JbfK1PVqk4a
+VKkh9W7/yqBcEfNcsfJO9cqaQ+PzcnCoDiD9UHEBYzUhrCKwhLRCQW50b2luZSBM
+ZXZ5LUxhbWJlcnQgKEFwYWNoZSBBbnQgQ29tbWl0dGVyKSA8YW50b2luZUBhbnRi
+dWlsZC5jb20+iFsEExECABsFAj9AzmcGCwkIBwMCAxUCAwMWAgECHgECF4AACgkQ
+hhTWqyZbTGMnOgCeJV2gI+1CIxMR7dcIhXjPkiusreIAn2SGOsPS0o89l0EIVuc9
+J2F03aB+iEYEExECAAYFAj/ZwioACgkQohFa4V9ri3J8CACgiGlh+td0BAnJPq19
+ovEQR2DJ02MAoLP203EF+BLPpykeTcGp8UEWmeGQtEBBbnRvaW5lIExldnktTGFt
+YmVydCAoQXBhY2hlIEFudCBDb21taXR0ZXIpIDxhbnRvaW5lQGFwYWNoZS5vcmc+
+iF4EExECAB4FAj/SSwYCGwMGCwkIBwMCAxUCAwMWAgECHgECF4AACgkQhhTWqyZb
+TGOh/QCfbrSoipMlizyGT6c8BOPEd9zzfi0AnRRTqTDzXzsGk4CG/BJME9CCm7Ts
+iEYEExECAAYFAj/ZwiMACgkQohFa4V9ri3IOVACgh2QHS1+cVjvM4eLjls1bJwWi
+o5IAoLtAszHrwHS5qrhvr2rtnlyyyV2guQENBD9AzmkQBACNpBfqi2PweozCtxoX
+PqzKdRDKqCw7TOrDR6lbP3z/ov/1SN5Vc0XqNzBSGqwBcmGWtneABkX7n4uzJrC5
+wvX/TZ/DkMvypPyeNVMu+/ZMlzdbx06OUDKr6Fy/NtaI7cN1rw+Igyv22Q8ilhhg
+s/5Rdj84EtJkWQjVRml6wXSAZwADBwP/TqyhOC4sA5YrePYGH8i46h0SU9dXjfEF
+JijC8vXZ+BNQHQVK3fjEXedZL8Zvvp1bsMu7Muz9SMnqygM1unp2NGxLRd/9315p
+Qh0VStYKn0xq13ybOKr0Gsyx5yyl3Nzlu/1qAR0es/zN4jV7/IQi3R2GOvezcpHX
+mkbsYiZAhu2IRgQYEQIABgUCP0DOaQAKCRCGFNarJltMYxcsAKCSJJUABlXYnLBj
+b+WtmAzu0JjZNACdFJ4KIATJDK/5ajFq5+irOpodoHeZAg0ETM+HJwEQAMkzgJCo
+lSOgkvzsTcjy/4ySwS56VgyFdYpZis8QqbEGCe8xKT+d9FYi5sBTw/jGpIy4weig
+NKRRW4NLYgriWJANksBaaPOKvczGAOLWzh2aPfifaGF/puIVT8yCubH6ecxr0Wy/
+lN54Rpi7cmpp+CEbhUTR+7xNGCMt3f9brtOlC6qYN3tJ7PPcfNBjJr0Ts+fPt8lT
+RZlBhVa9iEUVYoqMnZQEBmYkg+FxSrFlLw7/WLMKaKGHAV7QbpIxhaDvQ7bMM6qW
+c4plt10+wtZtJV3MB6TIRSYaEF87hXCif7mJY8KkCN8XkAxFlQhqEY/gJTOs73DS
+Z5+LJKUOF+0+66B31tN5gQq5yNBGd55OEA9iOM87hhQb4e0IuZGvq2vxxK1OL6Q5
+apr141c0ZxHLKaG2YCqM0B42mW84V2mO/Xu25HUjmXGrkpEd61KaodffS5g7SWj3
+jb0X1w/+QGQXnWdTPWuWu/SrpnJb9kBpk/awrBbh6/gz9Uug6WVw3jBaYvfm2gEf
+eKVYXa8AtBDSDuytXSXCSNRKY6Hd27ohUKMRBLEtz6Z+WgTKS11u9ip6ewG9irtk
+cJQmloGjgaQTLmTXJaZ9UkaEh8uH/LinhIDHk+ilht7z2+CN7S3kOX094v1AnvlA
+OchoDd7Wn1KqSoiM6WO5pccPdnU/j4LSoeVDABEBAAG0PEFudG9pbmUgTGV2eS1M
+YW1iZXJ0IChDT0RFIFNJR05JTkcgS0VZKSA8YW50b2luZUBhcGFjaGUub3JnPokC
+OAQTAQIAIgUCTM+HJwIbAwYLCQgHAwIGFQgCCQoLBBYCAwECHgECF4AACgkQDmn4
+CXEAOPVsEQ//Vv4CTUrXTvuaPTNR1x08nntcF5RY+2GGNlT5Cs6EzRbiB3GmKFKu
+Qxp0Ucgr+Yg1NTa7jOP2TbMwo8/FCD6i/Q5pWTISs7CdahnqKx37a33F1Hz1bNqV
+0Jhi5oJS/sVniYG0d4ZcUl5FkD/gDXgNbUDaB1Vi3I9bU+agwrsLoXrFWDpDPxrg
+PGDV3grvqfEp7K2HvPl2B6mUQHYHbIZ9FgjRLRIjOzjMr33RkVtg2QrLaUiOlJ3r
+i0xpWf2kMKDMej6M3vFP7PTacRHwqZMxZMWZ2WaviuC943pK0gWwUyJgkkYSrfql
+LkzIq3DwKPUneuuInNS4bab8YjwuGYSd/Fnj11P8emTEHwkIIKFyH0LxO2JKw8tV
+BosgExmS39P99tGjAOp4Qg1E00exl2mxtIiKI359DS3DYhjEhb5EDH1gVAh5GL2s
+Y/NiI4VANomiuzkzCybVYaMwjRpaIkCKemXN0BXb8r7e3CLXn4BA3KHIpuZH4Yz7
+I6RpVuyTOrayM62czy9mxF64Pnwp0gRUJhWC3a2BTYXV5vAtW89BrFB7ArENUKGd
+q81lUXVocAk/1LnMxy5fveS5yuUMxPM0fRBwzgARfyv+0HdsjzVmKZZKfjKPOjB5
+YWtOFtdFSdCzYnpIGyoPuUU34v8LuzRwMdBDrODb5LfvX3lMw7YvIkq5Ag0ETM+H
+JwEQANOvLBAACFpbL82gr5fP0xfL/fG+oSrAqumUsXmxnCcxHOzDoEvExxebVnL+
+102IXIMV3eQqEaZuqcUYGBjkMt216u5btuSoSsVDrwRI8T3/9fXsB/jdvlCzsq7b
+pImEFh7VDQc/jC21pP7r1G81Tt7zWB8oWYBbGXJMGsacaNg6449Z/0Ctp+gi+T5L
+jIq1b9apD/+ucg9kGdlKFlLJ8zMwc77hG3LWkoli1cbLgYKk4RKahboFmoEVnM9S
+ypdFfDZuSCB+7PvitjfqEao+fOCYOG0b3ykdcYXSVitFSnHe9T1DLjvKBy9qMtbA
+GkdD61xEl0MtifQxKkya/n2Fg438HUeU7ltcFLlKd4XAzmsh9PXy2Gpj/lbNYpsD
+DDMZafyfFfkLYYZasN4/+Ak+f5T1OuUqByIlesAPGReFtnUI+yXM9qEImProy+R5
+gNkBPN1AnNWvy2pi+ZUUI+35NW49uee35p5LNzMiP3hd2W+rDHWhE9y3oVFkpzbL
+lXwF7AMQGtMNE6i82XfahDyiMRo9BzssTSdYc1+5OO+5buXWuZUibYmGc5yDQ6qv
+0Yhlry4uoBMLJQcVCMkFh/os0gB4hgzI/MkhuEIYIBZcjGTzIzeGnB+0hB3ODiqt
+LmrR2IiK56EkJ+UGfQ6Niankx+1M+OtSFXc9oWP4RacT8yaZABEBAAGJAh8EGAEC
+AAkFAkzPhycCGwwACgkQDmn4CXEAOPW/3w//Wd3DfhQTXa1LoenNuuALnF9zIJQr
+scLXc9HRO41x+0oCxi+ePDhCSiTWKWA4t74PsgLurdwXnQlcFU8rdSeWSalnO0gr
+f0Rs+OHl4ICK3AWAgzZjFDh4J5Pyr7fVteGlUlKRgCCy/rGMwwSnCGLQYa9W1/ZE
+KYZzLvFk0S/AoSv2iw6BxWUYVZVO7EzRzLoauLXQX6HyFyTpaH2soYbs1Xnp8t/u
+w47PDnWXpYAaM0P1pD0T6krYp3M8YdNySGiXaZTkHBP2bj0PllGQHB/RjOyUrv95
+USYZj60O430OyvjlIBDq+BBL/ZLEbMdUIFJJ6WO1F1nIr8MowpTNqeEBpEaqOY6A
+lV0j9fZWX2qJKIxQayq5OjfWL6Y7juJUuDBBZUzPtKSmcwGtg3HsCL0SWoz8JT4p
+hPOXy4Zk1NMn4F4oIwRrGrcB2lmBaQmoBWBP63g5rObADL0wsyabfYuVRTE7PoSg
+iCEN7wONrFjXrpB+WWG36d8nrETyMKALr96YL+1T4VNs0sllYbrkowRe2ioMKj9r
+t61UPOGhPekw0HA7pDS1n+nGMMU+efLKKCvcKFKq/TDdjK2jPg1JQ1Xq8O4fDwRf
+ibUXyvYwswAqOqQ0nHH5QSj9pov3tsXhJWWDVIWKMFhk+U1Sans9txHEQKJl8L5k
+KiqgPxg3Tk50+6aZAg0ETM+LbwEQAN5ZRgD4sZJ6ClxoWjlmMM1c9632/isnzXJM
+unkZeCA3gjx++uhZexCdSD36aQZ7dAFSwvrJLHRrjsszl/uc1H7FaBmkZ7E8sjNI
+/oulUtMhcLe0TYy6MRSdl8aBqll4slZNfcl7iYk4PCmk2eR4sdMPMEsQC2kcglDW
+HDeJfG0RozFgJ46QVRCktRWTrrACQcvuHLizl0+4nMZ76yexNre7Rrgo6kE5Mapl
+0UXog6qM9ngV5cVxh2/wDex5fmXvB9uNTusEQIFo8qaZPBtapAAeoIShyUWispqi
+kos5t410OzlGfBHsDb0cq4SU44bAXJmkZv/95JECEy8mZjsbywU4MCDjAf1lC4d9
+K7lcwHQS9rE2Xw1suXfD/VjQy9obpLLROk1DGLJC0aige0BbhMOa+mXgKVzSKcKv
+PdmcUHcdm0dIy/LYZhC9Ja0uv37Sc9Ri55k3DU6DgdBu2dZgy7q9bBzLpqPIyTPs
+XxUlczjhT6KxZYDeyghbwJYQ+miasY2VHeY9aZHYXXhDHIo2eEaut1y/9a7i4auA
+aYnaADj/gmryBm6rb+r/MIMbfZ5htB4l6aoI/8BJygzq38LrWwUvzQ3p/N5+jA5N
+uJWexAbG9hEc7nbbwINwp1b0P35eqSxhtr5wGdSNor5zScHazaPjPxHKP7WiATj8
+a1p0MlEHABEBAAG0PEFudG9pbmUgTGV2eS1MYW1iZXJ0IChDT0RFIFNJR05JTkcg
+S0VZKSA8YW50b2luZUBhcGFjaGUub3JnPokCKwQTAQIAFQIbAwIeAQIXgAUCTM+M
+LAUVCgkIAgAKCRBe+tn+gqf7zcwkEAC3VkVY4TGXoj3CDnjCL9nwkxAyK+JagXSw
+7g8FMjqWW7YAIU8TprZxtOJUcnSXioVtT8dhKBfaasu34EpMrUYEIPNp5BNzhxIf
+f9hXVrcuOZ1k0nJRlSc4IKSsrognoCDm340ma8AOMARVkrz7tXdqdlDPWVjMvqn/
+5/KReaIHQUNRqjypIIdM5mgaE41F1+uAyqLqcxvf4YQtu0NNGMizGZd37bH+5wMF
+BT7S6CesAVPogcfnMdoMN1wO2yOzWKlg49U91DLUY3XHGOQnqVnTnVQ/xzLEj/vf
+0PlLoY+3Yn9WEaonkMgco9un71xZ9s4DnR4WE+7QJYU2cgSPFB5DbAZ925qcNK/x
+wOpKfRyBPN4zdjWE8Vjd25EcjZLsxgPiSlPpbyIJD6Ot61uoqekinNlAo44sleg8
+rNAAYnajlD/1La+Q/grQnHcujOt/w/ya3LG/cTpz7wkUhxhnmMwmxrVlEFaM24Qk
+PwbQE/Wuwdvm/hYX5o4F1b7DQ9WepNZ4ahb/ztbsIg2my7JLN4RPDWZ++EMt5K6w
+G+34vn8RfuSu4GHT8TAoexDsAEWzFo67F+dAosrvfw+HBBm3hNEz4tRkKP4SPqmo
+dE8IXUffF+VFeFH0NLsvIwfpdW90XNxnSlnrc8aVpdvuE3qXqjQICo10LEJuxZRa
+hNggNMtUNIkCfQQQAQIAZwUCTNK+FSEcRGFuIFBvaXJpZXIgPHBvaXJpZXJAYXBh
+Y2hlLm9yZz4gHERhbiBQb2lyaWVyIDxwb2lyaWVyQHBvYm94LmNvbT4dHERhbiBQ
+b2lyaWVyIDxkYW5AcG9pcmllci51cz4ACgkQnPorAWKylj8WUxAAmxx/NESLJp0r
+A+fW8dQ08jGZ1Xf1laNCEd1eb6FXr/Z2xsKPFq6okBiiw6cm2wiwp7DBBHxQatyb
+AJNLAGVg8wpHUPgUguFOY1LyLRZ9i2SKKmWG0jzQ7svWELxssHFUnMW8dwtk3qAb
+o8pKvOKf4ol3qoKfN3Xq8ZBXAGkQaTIOJzGSfau+dH5NbhMcqZEoKGOAcOsLiIHZ
+Cnos9KqFMxqBlTMyJWO9YP8dY3mGHUWV0gsYfE32bHM3auaA2Ynzxtor/jMBATeq
+hTWjRAD1H92/HZ9vRBKwpHHpjsF+21aL9TZv5D2OmFYeN7/G1tyRcLYLrhDa7tnx
+r5S/ePdypMZ2IUaC0umMKrc8ZrAtK/2N4ZmnHKoScCJHjup66cLCVVFGXHb2hEM9
+2fPFog2//s78Cw1DAxaNE4jjmR4QWXmQZUqA8AymIfgsi+nI9rWMWnpTCC6DGG9+
+j7GbIpPdRscqoyAiPl2lBpZerLirTa1GMuDqqGuNiv6YmEvxNVleOlPYCCQr1vY5
+ltJz34zckBNJAH/7woggqoyGiLa456ruDzU77qxUCy5ulFTOWsVtltojnlxgKBML
+8f0uThQZN+0HydPb4uP3k5aLNL1ktiSo/XlIP2/AO69Bi4YZzERYsETm2zFLWx1P
+MN+R0l/BAjRskTCX+H92fG5OkGjkmR+JAlwEEAECAEcFAkzS16tAHEpvc2VwaCBF
+ZHdhcmQgQmVyZ21hcmsgKENPREUgU0lHTklORyBLRVkpIDxiZXJnbWFya0BhcGFj
+aGUub3JnPgAKCRCw2ZG0fECHN8OVD/Y8+R4R9aNkuZJ76SCHOIhxjKtMhk44muAZ
+FQwB+CG7HY4b/869+JdAOrwsOYr75h3vkz1vkU8FOr2LAu6PdiXDKpEs9wkPDGFx
+Rg9yePaX2DbAh0Ch1ucR1FZvr3QqO+L0ri1lfUUl76n/QfZtHXfuoPgsYIjsbv6g
+90mxHFJxxmowgX5gWKYaVm6OFN7xYiAC18Ia8LfReNIZO0XyaOq2/NoLuIVyguyi
+C3RuVnvAk92/6YCPgZNiH1lN1kLmkoNvGpY6CFkCI9LKZ9xRCbs7Dbkoz7I+EYla
+zfRf5mLjsrI+nVmFHvicvuw3ZtCCAImMdZ+Z53CHwd2N2v81lqnxUyCDPJf4Mxcw
+Jq7Hf9hYZUBS9Ehj3nfCmJwOVUMrXYXurKinDAcyoYmlA2iqdzUdM3d9xFGjexsl
+cUhZusggmOvBc3bK5BLZXUm009B5LYz4BGUAVsmN8vXekRgevszz5GcZBKElgRds
+9DQaO4sbgrskq2TXHzBI7e9GiEcUyErZ8fdsbea5zrPoW2/x74Kq93VtQCuWPDOJ
+Nq95l0J6bmiaVZuUTO5YIHFts7jphvA4gMf/4Lnzhzkcwftgi9OwyDBbpTyfdno+
+hsYBrBFQP4L7DLaGewHt46Iggil7Y9oMO0Yo7JtCsRnDtZYxc4rveg8vRg2xIl4y
+NJlDNzNciQIcBBABCgAGBQJM0p5uAAoJEJrilv0C6fZbqooQAOpWpMdzXdmDG2fe
+BffHiY2sabhX7B+tBRw+SIvmGw+ZvWvy3Tp2xFy7+PgCJhs/wbjyI3tCyx+DPb5C
+ybZpDjferuhbKA/PVgnJozUhYtwLFQ7bRyvlLq3ZSZZawVn2bbIHn1knjohz+0hB
+90zVX6vXhjPNZwL8vzPa3jMMNPDbd4E7w0VB63sWTKXq/pTy5SFGfscunxOsDMbj
+KcW1VtSszH68aywefZV9DbmjSDEgNRiqwtj+WxD3rp3fARBO+4o5yIsjWu1wGL+n
+59atHZJp34dAJFgOTJ2Jtykyuh3G76k4XKLemgUsu4aWFAlNIWt/f41cT5WmQe4z
+YG4yWLE/KWpIc5Jn2p3wlQpKqwl/+F3pkOpqPZmZkYjn4ORCMg1Q0eOzfiaheofv
+T78N0j8020z1lf5ojmEtGHoOzwz076Z3TGP256a4F37ZzibM7KFBn4iwjVrgqfFa
+62Q5WG+q2rdmpQ5B2eXAYNxg66DiMcfR3zHJeMz3UpOZcygIUZ63N6VK7+WgNPtO
+swBmXUxa5L35+a616/vvPtCEBlvJtDQz22BIvp/RpYaJ1k5K58uy0hj0oXZlD3q7
+BJSgPhgYOOqO79ZOwbgqGB9is5yegDXtXctV4FGuj601C+qtUHbRLmGio3XSMnmy
+FCOJpZW41tJYo9uQz7dRHIzGsBpSiIAEEBECAEAFAkzTeLE5HEx1Y2lhbm8gUmVz
+ZW5kZSAoQ29kZSBTaWduaW5nIEtleSkgPGxyZXNlbmRlQGFwYWNoZS5vcmc+AAoJ
+EPOfGH3vtV3xs08AniczpMS0xOouROjBIHLC+RlBdMwAAJ0ZiOfPrr5+C9Glo317
+omxwZ0obvbkCDQRMz4tvARAAoqAcqn4cTgkAEACgeJQJoPKYAAyZwISGNTgqnnSr
+BtN91af3XoVybrnXvlzFc6CkyWQ5T44yMaSfM/ZCYMpFCLtzssTlk3R8ASd7aIQR
+/ydoB5vaPZ424NjSfsNLiF1NR868R8iFPHphegw3P2UeFT8rw/arcdJ5lXQ/J66p
+63t9BlggU4piIMl/JPrtVawVLelYMYy3zw/RdnmrvU1qrZBGno5QkRhRlOXqQBTv
+FlWVZT0GtC+lNha/MqEqW5YkACVPYqpmYk2aoNH5+Gj/yBpWap1o8GsVZKZQUMx6
+CPAT9GcTrOlFqFbFG1kL0iOQgOlggQ0Kba5LN1VXUl7ESsu7NYEXDqDdbjduVDMR
+UsFrhTPUOf/kRNPjMPmGih0RP1s0woe3M4dsLaZEcAu88HHMCcaiOfBPAFU84upM
+fEgh0BIcmTVwAaSftD5gzmZKY3YXfaS0cD6RaZBWuzecHNDLLEgzuhNbUtmtylx1
+X57tep9Mh2tKDFrqBxlhg3M73+mGdE6zgsWhgOeAMATII8mzM90zLh4bg9RBxdp+
+PnoJEbuZVdIX2bNJPt/u4LdAV/czozPjkZtZ60VSkEYyUnZ2dNKUOv5tujkY4dm1
+V+R9uR25C4fLopnE/AN26+GYePrbBaghEUh7ugg7HlTEXPz2JsfvpjPIaao0V1+A
+bEUAEQEAAYkCHwQYAQIACQUCTM+LbwIbDAAKCRBe+tn+gqf7zYEvEACoszB5B68Z
+QrcOBSWvk4l0xWLNfZQIl0M5WoNEoNj6Vt1CzIXadRFxHu1m0gnDLW3brquRuxTe
+acho1iqinNw0pP7yODNW5p5ftKdvFlB7NNemVxzNZn1Q4cSkbI7GdYFiU9WQf7lB
+TQpzFhjJSbJEMHtQrYOqw1wGNPZThEfNXwFLwe+0RF25gEQwuTkRdnpKarBeZiax
+8zkuOmTLWmrI5Dq0dsYi6YotuHaSa3cFjGo+gp2cj+mBljaW8BXAIjzNunjMKqkV
+XNA+Eh3w8FIx7NYZfrbDz4II3naYLb3x3IEwb6g7sTnCexFyTcS2RMJOqPBG2Zh6
+UI73B3AGkWDMsUyDMPVCVOEWUsT94tPBDZCrvdOpVu99OeMqESuaIuPELEbSIrsU
+aDCyJDnIWVExk69szQl/4HOM+u9WBtSmG94WOCT7T+ypPcfFBPpUvxx6VriWKRQX
+yKUlVCJVET4UpDHIwVUpIsmFmjxZfTlhe7pny8/a03/EnvGImuLYoxhfzP3VRapr
+86fwCseMxAPW3gnl6zvGZrIM6ZS09tdyTIOiHUHMcXvWpyxdw+7EXHuncpEB5m0U
+Ci8LBeDYqitVqqakgdKGAl8pfwaIJ9DsE5Sv/IHKFmieLa9PEh/2S/4hCD31atIK
+3PimOFurhebU3wOU0wEkNb/3IYLk+MFQOA==
+=1STU
+-----END PGP PUBLIC KEY BLOCK-----
+
+pub 2048R/AAE4CBCD 2014-01-27
+uid Charles Duffy <cduffy@apache.org>
+sig 3 AAE4CBCD 2014-01-27 Charles Duffy <cduffy@apache.org>
+uid Charles Duffy <charles@dyfis.net>
+sig 3 AAE4CBCD 2014-01-27 Charles Duffy <cduffy@apache.org>
+sub 2048R/886E0B44 2014-01-27
+sig AAE4CBCD 2014-01-27 Charles Duffy <cduffy@apache.org>
+
+pub 4096R/87C39319 2014-01-27 [expires: 2024-01-25]
+uid Charles Duffy (CODE SIGNING KEY) <cduffy@apache.org>
+sig 3 87C39319 2014-01-27 Charles Duffy (CODE SIGNING KEY) <cduffy@apache.org>
+sub 4096R/CEE42EB1 2014-01-27 [expires: 2024-01-25]
+sig 87C39319 2014-01-27 Charles Duffy (CODE SIGNING KEY) <cduffy@apache.org>
+
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v1.4.14 (GNU/Linux)
+
+mQENBFLmW14BCACcK3JRugJ67/+EssTjqFd5/9AxZR5iVumLvyzAG+JVL4wd9Vb9
+kh9uHaGNHUNSHgp25RIq9k6ML3Oha7IIzw9DvYFMkTJa1m+LZvbunmC4UPe8OgDJ
+j84mFcKrl9ew9QnGzxMBI5S3bIEBOe+I3apxZh+dL0WTWz60yKsE3Fo7Tc0+fkTH
+XBMw+GfaOQDenckIAM+nWv9JqdZWo0EnkjUwCudpqAvApJd7LJlZJjEAh9wfuE+Y
+L5YGTHN5ddui/lErCVFYZH8Ojd6AhnnJZWuc6yNW44BhPtSXskmYTzGc8z413Ml6
+SSRAQ55oItfFeqml2n5OsONhAFjCyNt7ukP7ABEBAAG0IUNoYXJsZXMgRHVmZnkg
+PGNoYXJsZXNAZHlmaXMubmV0PokBNwQTAQIAIgUCUuZbXgIbAwYLCQgHAwIGFQgC
+CQoLBBYCAwECHgECF4AACgkQ4xVjcarky81lmQf499s7X5f2lEOz9xr0bIWbtWLg
+MkdwX/OZL0jJTjIvv3034x/ijuSzF2U3rfIh3AQASEIX1AGJVAAAjaum2OFdD0Ea
+VBH0shgtBIAkJXSEUqa3Jb1XmzmlS8ALMga/uiEmadIByjHyemYC5AGYo2AjTMgT
+I6ARSfwpOuTRQ+wEZaJjFaGnCd5ZI48T34laIfcLGKYRcg/bYBVh4OKol86eNgKP
+M+yAGIaFozbbgEEzSabLoiTGXwxscxefElmAZY7TNeI3rcFFxY/Sew5SrqjnzbAf
+JH3EO3GIOitK8NHCxKPD/F5p//tEs7Z0Vaor/ejhFIHnuALDghK8wCvEcwkhtCFD
+aGFybGVzIER1ZmZ5IDxjZHVmZnlAYXBhY2hlLm9yZz6JATgEEwECACIFAlLmjUoC
+GwMGCwkIBwMCBhUIAgkKCwQWAgMBAh4BAheAAAoJEOMVY3Gq5MvNmdkH/iSA78+C
+lQOwkjijvOy1Y1w9ey7ySoK2L45I/Z+FesLQlVkyHuPnfpaGrmSrBlHNEIS7Gs/X
+DvS1UBNtGXb4EiKM9nvgYp7GEniiEOWMUBpqAVPRFER8BbLkTdoNn3LBziMdaAj/
+eeASRPH6pu9wp3t/2nI1b1mj5kFg2ewRbicUBhoR57Lgv5qWAuOpBRqlSPp6lSdE
+x8pvfiW7eI31ovmzvuXMJrffxVEDyhmjwXnA8y1QLsRxiP5g6yBTqE7B29tSP0XP
+TqkH1q53rvnmfPQ4EP76c0SXURdSILsbJAWM6MxshqhcOPy8TMzvUG50/86UNAyL
+5FHE9NGR4C6rgja5AQ0EUuZbXgEIALp/M7maUGh2ODWjdDIt87j4ilMUo9xZupeO
+vsEYVB3lvDmwzfEe+FAQGm1sbcdLZ/AMiwf6blUs4/s2RZKuApWUREWqMrodu/ej
+1ozY6RUN6tXfaSmmK2ECnAu9m0hnRqdmU1eVcAsrlI95/stQzJY6xUfr948Yz/nT
+oA6WUXIIiDys6mcyvux6Lno/hbxiNw9LULK62q0Jh6g/ErxiuHzv2sXsi0M7ZYLz
+VkZdopa5Zq8/8WXl9VK4DfO0UlZsI+7Ucvzn8JOX7fmRJ571bEJkzmRaRrEXtJaY
+9g3TE5xB2Oy0DXBCeEMqqqRrJXPqmV7m9ODMmSFACGwRFmSn7p8AEQEAAYkBHwQY
+AQIACQUCUuZbXgIbDAAKCRDjFWNxquTLzXcRCACZi3ySYQdz7Qj/JD27qL/u+16x
+369z8dG+ncglQT5DWnCbnyITDnsE58Oh50V3nBT3KMFMELNpgUag8l7yPaRGRcDY
+Xwag+DpDWaOD3G4BWyqpC9+hdlSBsW013YLnnGfuvjSLv0hFV27EMA6MFnmHgcPA
++xIV6j08PhFvYsUH69yA4u93ey8CAH/Qv3tGIRxcUvp1hqWLsxnqc3LAq4kepydY
+ZX/2ppslj02OkKGPsgv6ParKGMESBjx2Td8ZwnzFc4AiYXqpvuMQx95TxC+eitBX
+UKMdQR4SRJBdZWnZLLoPvzgH08TtE9Y1UraJVVm+gIPqeYLqux+6y3ujRo3ZmQIN
+BFLmYdEBEAC+GgyACiLyLycJ54GUJanMRAhB49SLpi7oLnbfnCPqiey4sOugVZf7
+XhS01wokzjsRpOgy35qEK03T4lsMEaYcEEhJYPN90RhjY7VGPfGgVGrXjZjPJHKL
+lTH85wV1zyAGmNyI/Kcd0WiWxVifSEqDDrV8dTvJQEq/PHoEpvXwVygjEuYbbBmK
+j7LKbvFqnEbK63SLmCpq9AITQ12ysy+SysHp0dFw5haSLB2oK9CO/hXKc1fohI1H
+Kx1vn6wCHouCyo3svuXzLaUAyPJboNFL0D46uiiv29pc3bsS6NLkiWa/I6v8oxpS
+Q2bDCb8aGRl71D8dLYtx7FQvvQmtN7Mzbp7nbcw6O6EFX8BrsOWDBXw/+K+rzR4k
+Hu+wA+SSwbOsMAk/uP8cgk0p8agLvv66Y2tHXv+A3aowBZ1CPNy89Fo44QMib1Mz
+mRHMrh6UCwHznLRdA66SgfUItgO5G0glc6sjlQNdzhoO3fDg6ltD/pyW6a4S9cP3
+yv3YH0gOgAHHpVVJP0MJZi3lh1Oh9zdwqy/DFKebFdVZdbXHPWxO61jVl6m640mA
+rAQ438ro4N0nZ9afsgNT7hXms4Cx9qda6R5RVt6hA7NMo6agZE976ptgsQXttsYf
+tVJqs7acu9S6LCLrpx9elt4DMeH6KQQAwvAy0qRQcfs6uOGsgGvflQARAQABtDRD
+aGFybGVzIER1ZmZ5IChDT0RFIFNJR05JTkcgS0VZKSA8Y2R1ZmZ5QGFwYWNoZS5v
+cmc+iQI+BBMBAgAoBQJS5mHRAhsDBQkSzAMABgsJCAcDAgYVCAIJCgsEFgIDAQIe
+AQIXgAAKCRBxk7nQh8OTGehGEACF69wQMCC+yGNvQ+xV0IfTUGwKIK/vT/eHbr5p
+FiF6Hyui3JEx8L+UAecnKJVZBUz8s3AQ8wVqA5p+ttDCw0hoUSDolc3Jpp3mrcQo
+Ckx6JRpc+fDloDN8txakc2wGphQSpIwps/qe9vPy/84eqhmGo5f6GjoUY4cEWH82
+zrWQRHEoNfOTr5POPCexJy+0rTKGXvrCyIcQdSHf7a0V3AXoFQYgqFT42sn2Pj7/
+EjSe70qCZPBY+ytQykKenOLx1fq2FuORsiU8E+DhjyPpfO62pabDwPsi+ZXy6o3D
+Q/wAYSgpO0GfIcTaQM/8gkmOTLpiRnuwukUmSH/4VuAj4rz+hMBqjZtnR8FeVJvO
+gnOljNJjtXcVcHVNWT6cUr8IC1VKvJZoGbjZf5mlwyd3Cye9oGVvoEXTq5xVY8+R
+COIUcC41gOhC9RJadHXkGCN12jC6uOmCohSkrVZ3hb8n2hHxFFgPN11NYCGTu5fV
+pg3CJA00uPFSJF8+grl4cFPX7mqD4lO6yKHWGHwTCXxo9S2DuZrnAmKNAt6Z9otB
+B+c0i+6dKpV8yBy0ChUmYNOh251RPMNt1FHPFGAhiE7rdZw6iuwWO5R3/AvTy//v
+lRt5c0QJImVCf6eu18HPwcgw/f6EXQaE26DlytnuXdddjwKyY7Nv1ECT15V8w67I
+ZgrzKbkCDQRS5mHRARAAp9sydQ7GeAv+hkY694iDPSEYmLwsNrpFAdHrHe3u30XL
+8VwSHkEY2x18tmFcEKo737+3seblDkzoHMMSn1uC66RxHsfJeA3CfpxMgTr5jGy1
+emNoKrE+lEi1v3CE4rg21UD42IafZMHKnsQnnkSyyYIvcTjw81lslS/iYbn8juUN
+4u5hMjYgV+LTy06P/ZPB9koHj5DiM6iXWf45wy6OctlhyGGAzYPN8bagqBlcBZ8k
+9JnNrViKV4ZOV4ToE42ZQXPs31TOyXalcUbiZGaeKMH9iV6V0yciS5YcrnxFWLqO
+RS0yjMR6uCkEyJVAGI/l9KDPZHFtDW3hDGo7eny6qJjIVbDA6vM7Az67fcegVAC5
+v3G7fWKyc2E64ygv34OhMWtKMe0X37YRmPupmAZA/fd49Tk9sEu7BYaHpjgW3bu2
+wC5fTYcXbBx1mzhY9VWvlsqpzaZKPihqKcTHEwQiXRsFCDiog5uVJ2dY8DSpjl7y
+lEasG+pMIglZW+Dt4/U1RNzGGitcdBXZBcC6vZ8MK3D5ifQPcxRoA5OLeOHfaWLm
+fHGuIpKwdjs/SdovY7wibTbZcNjRqQmYm4TRE12B6ICvqQRdA0WtA4hZ8kXKeB7A
+VkcT5DCI86BI8zc3vq5dOql4eGVe0fZ4KBwNHv/Thi21iP04ahaBFpXVb15/8YMA
+EQEAAYkCJQQYAQIADwUCUuZh0QIbDAUJEswDAAAKCRBxk7nQh8OTGWGfD/9Ata00
+8MJ6VhD+w0kRmXAx628lE2VlYlbz6gqsUxo/uXQJ1+U3RVwGEzJGYxRSXzcCCGB4
+AhVSaUZB2XuKCXxDWA5KxBim9XgaZ55jdrtoBPk4QoYVy9rx+hiyRTkhbaBTgr4m
+SF1+GeovG6NMI1HJ526uuUw9bjbDBcixDDEc4HnuezJhvXagciRbJP7KBPrXqLR8
+LIQnfrVE9/C01SLpTfu4ibsv7C+xKQOEGbChhfvXazqgd614kYi6Akj27UpadSQw
+8YiU7kS0H9IrYZLL66Nfxlb+9DT1rP0gDA8FSuRO1iW0hqigIeMQrcLAocQS51ck
+IZ1RqzLF0TmurOBO/DOqfY70HPyb022tM4hYE4iZ1/GBS8bq7v1yYE7AWb55YQ2O
+JxV6wSUOBwLxEh8PBMhiwFLaObEOPgkubxGT/YvWEjmK0CoZKy74R7MnxgnceRoF
+QV44gC6CuttGoElueBpjULs1lnKFKA/qwv2ltITMHe81LHVjg96YgsApXOKCkK01
+KH9pznkHhcEAVA0XJ6b4c1TeCQzz7YxPlVU4nxW/fECv7ZgWCBZ1MRrXXRtEViGz
+G3GJoHIALPVs33ykG7MKFFqpbJHHc95hcOzs8eVh2/jD53CXILjbhKEGGbejFlx+
+RHkiOuu1l6jXCeh/J1R6YidjsDjKWlRkHifMmw==
+=j+uw
+-----END PGP PUBLIC KEY BLOCK-----
diff --git a/framework/src/ant/apache-ant-1.9.6/LICENSE b/framework/src/ant/apache-ant-1.9.6/LICENSE
new file mode 100644
index 00000000..cdf6ff8b
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/LICENSE
@@ -0,0 +1,272 @@
+/*
+ * Apache License
+ * Version 2.0, January 2004
+ * http://www.apache.org/licenses/
+ *
+ * TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+ *
+ * 1. Definitions.
+ *
+ * "License" shall mean the terms and conditions for use, reproduction,
+ * and distribution as defined by Sections 1 through 9 of this document.
+ *
+ * "Licensor" shall mean the copyright owner or entity authorized by
+ * the copyright owner that is granting the License.
+ *
+ * "Legal Entity" shall mean the union of the acting entity and all
+ * other entities that control, are controlled by, or are under common
+ * control with that entity. For the purposes of this definition,
+ * "control" means (i) the power, direct or indirect, to cause the
+ * direction or management of such entity, whether by contract or
+ * otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ * outstanding shares, or (iii) beneficial ownership of such entity.
+ *
+ * "You" (or "Your") shall mean an individual or Legal Entity
+ * exercising permissions granted by this License.
+ *
+ * "Source" form shall mean the preferred form for making modifications,
+ * including but not limited to software source code, documentation
+ * source, and configuration files.
+ *
+ * "Object" form shall mean any form resulting from mechanical
+ * transformation or translation of a Source form, including but
+ * not limited to compiled object code, generated documentation,
+ * and conversions to other media types.
+ *
+ * "Work" shall mean the work of authorship, whether in Source or
+ * Object form, made available under the License, as indicated by a
+ * copyright notice that is included in or attached to the work
+ * (an example is provided in the Appendix below).
+ *
+ * "Derivative Works" shall mean any work, whether in Source or Object
+ * form, that is based on (or derived from) the Work and for which the
+ * editorial revisions, annotations, elaborations, or other modifications
+ * represent, as a whole, an original work of authorship. For the purposes
+ * of this License, Derivative Works shall not include works that remain
+ * separable from, or merely link (or bind by name) to the interfaces of,
+ * the Work and Derivative Works thereof.
+ *
+ * "Contribution" shall mean any work of authorship, including
+ * the original version of the Work and any modifications or additions
+ * to that Work or Derivative Works thereof, that is intentionally
+ * submitted to Licensor for inclusion in the Work by the copyright owner
+ * or by an individual or Legal Entity authorized to submit on behalf of
+ * the copyright owner. For the purposes of this definition, "submitted"
+ * means any form of electronic, verbal, or written communication sent
+ * to the Licensor or its representatives, including but not limited to
+ * communication on electronic mailing lists, source code control systems,
+ * and issue tracking systems that are managed by, or on behalf of, the
+ * Licensor for the purpose of discussing and improving the Work, but
+ * excluding communication that is conspicuously marked or otherwise
+ * designated in writing by the copyright owner as "Not a Contribution."
+ *
+ * "Contributor" shall mean Licensor and any individual or Legal Entity
+ * on behalf of whom a Contribution has been received by Licensor and
+ * subsequently incorporated within the Work.
+ *
+ * 2. Grant of Copyright License. Subject to the terms and conditions of
+ * this License, each Contributor hereby grants to You a perpetual,
+ * worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ * copyright license to reproduce, prepare Derivative Works of,
+ * publicly display, publicly perform, sublicense, and distribute the
+ * Work and such Derivative Works in Source or Object form.
+ *
+ * 3. Grant of Patent License. Subject to the terms and conditions of
+ * this License, each Contributor hereby grants to You a perpetual,
+ * worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ * (except as stated in this section) patent license to make, have made,
+ * use, offer to sell, sell, import, and otherwise transfer the Work,
+ * where such license applies only to those patent claims licensable
+ * by such Contributor that are necessarily infringed by their
+ * Contribution(s) alone or by combination of their Contribution(s)
+ * with the Work to which such Contribution(s) was submitted. If You
+ * institute patent litigation against any entity (including a
+ * cross-claim or counterclaim in a lawsuit) alleging that the Work
+ * or a Contribution incorporated within the Work constitutes direct
+ * or contributory patent infringement, then any patent licenses
+ * granted to You under this License for that Work shall terminate
+ * as of the date such litigation is filed.
+ *
+ * 4. Redistribution. You may reproduce and distribute copies of the
+ * Work or Derivative Works thereof in any medium, with or without
+ * modifications, and in Source or Object form, provided that You
+ * meet the following conditions:
+ *
+ * (a) You must give any other recipients of the Work or
+ * Derivative Works a copy of this License; and
+ *
+ * (b) You must cause any modified files to carry prominent notices
+ * stating that You changed the files; and
+ *
+ * (c) You must retain, in the Source form of any Derivative Works
+ * that You distribute, all copyright, patent, trademark, and
+ * attribution notices from the Source form of the Work,
+ * excluding those notices that do not pertain to any part of
+ * the Derivative Works; and
+ *
+ * (d) If the Work includes a "NOTICE" text file as part of its
+ * distribution, then any Derivative Works that You distribute must
+ * include a readable copy of the attribution notices contained
+ * within such NOTICE file, excluding those notices that do not
+ * pertain to any part of the Derivative Works, in at least one
+ * of the following places: within a NOTICE text file distributed
+ * as part of the Derivative Works; within the Source form or
+ * documentation, if provided along with the Derivative Works; or,
+ * within a display generated by the Derivative Works, if and
+ * wherever such third-party notices normally appear. The contents
+ * of the NOTICE file are for informational purposes only and
+ * do not modify the License. You may add Your own attribution
+ * notices within Derivative Works that You distribute, alongside
+ * or as an addendum to the NOTICE text from the Work, provided
+ * that such additional attribution notices cannot be construed
+ * as modifying the License.
+ *
+ * You may add Your own copyright statement to Your modifications and
+ * may provide additional or different license terms and conditions
+ * for use, reproduction, or distribution of Your modifications, or
+ * for any such Derivative Works as a whole, provided Your use,
+ * reproduction, and distribution of the Work otherwise complies with
+ * the conditions stated in this License.
+ *
+ * 5. Submission of Contributions. Unless You explicitly state otherwise,
+ * any Contribution intentionally submitted for inclusion in the Work
+ * by You to the Licensor shall be under the terms and conditions of
+ * this License, without any additional terms or conditions.
+ * Notwithstanding the above, nothing herein shall supersede or modify
+ * the terms of any separate license agreement you may have executed
+ * with Licensor regarding such Contributions.
+ *
+ * 6. Trademarks. This License does not grant permission to use the trade
+ * names, trademarks, service marks, or product names of the Licensor,
+ * except as required for reasonable and customary use in describing the
+ * origin of the Work and reproducing the content of the NOTICE file.
+ *
+ * 7. Disclaimer of Warranty. Unless required by applicable law or
+ * agreed to in writing, Licensor provides the Work (and each
+ * Contributor provides its Contributions) on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied, including, without limitation, any warranties or conditions
+ * of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ * PARTICULAR PURPOSE. You are solely responsible for determining the
+ * appropriateness of using or redistributing the Work and assume any
+ * risks associated with Your exercise of permissions under this License.
+ *
+ * 8. Limitation of Liability. In no event and under no legal theory,
+ * whether in tort (including negligence), contract, or otherwise,
+ * unless required by applicable law (such as deliberate and grossly
+ * negligent acts) or agreed to in writing, shall any Contributor be
+ * liable to You for damages, including any direct, indirect, special,
+ * incidental, or consequential damages of any character arising as a
+ * result of this License or out of the use or inability to use the
+ * Work (including but not limited to damages for loss of goodwill,
+ * work stoppage, computer failure or malfunction, or any and all
+ * other commercial damages or losses), even if such Contributor
+ * has been advised of the possibility of such damages.
+ *
+ * 9. Accepting Warranty or Additional Liability. While redistributing
+ * the Work or Derivative Works thereof, You may choose to offer,
+ * and charge a fee for, acceptance of support, warranty, indemnity,
+ * or other liability obligations and/or rights consistent with this
+ * License. However, in accepting such obligations, You may act only
+ * on Your own behalf and on Your sole responsibility, not on behalf
+ * of any other Contributor, and only if You agree to indemnify,
+ * defend, and hold each Contributor harmless for any liability
+ * incurred by, or claims asserted against, such Contributor by reason
+ * of your accepting any such warranty or additional liability.
+ *
+ * END OF TERMS AND CONDITIONS
+ *
+ * APPENDIX: How to apply the Apache License to your work.
+ *
+ * To apply the Apache License to your work, attach the following
+ * boilerplate notice, with the fields enclosed by brackets "[]"
+ * replaced with your own identifying information. (Don't include
+ * the brackets!) The text should be enclosed in the appropriate
+ * comment syntax for the file format. We also recommend that a
+ * file or class name and description of purpose be included on the
+ * same "printed page" as the copyright notice for easier
+ * identification within third-party archives.
+ *
+ * Copyright [yyyy] [name of copyright owner]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+W3C® SOFTWARE NOTICE AND LICENSE
+http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231
+
+This work (and included software, documentation such as READMEs, or other
+related items) is being provided by the copyright holders under the following
+license. By obtaining, using and/or copying this work, you (the licensee) agree
+that you have read, understood, and will comply with the following terms and
+conditions.
+
+Permission to copy, modify, and distribute this software and its documentation,
+with or without modification, for any purpose and without fee or royalty is
+hereby granted, provided that you include the following on ALL copies of the
+software and documentation or portions thereof, including modifications:
+
+ 1. The full text of this NOTICE in a location viewable to users of the
+ redistributed or derivative work.
+ 2. Any pre-existing intellectual property disclaimers, notices, or terms
+ and conditions. If none exist, the W3C Software Short Notice should be
+ included (hypertext is preferred, text is permitted) within the body
+ of any redistributed or derivative code.
+ 3. Notice of any changes or modifications to the files, including the date
+ changes were made. (We recommend you provide URIs to the location from
+ which the code is derived.)
+
+THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS," AND COPYRIGHT HOLDERS MAKE
+NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+TO, WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT
+THE USE OF THE SOFTWARE OR DOCUMENTATION WILL NOT INFRINGE ANY THIRD PARTY
+PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS.
+
+COPYRIGHT HOLDERS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE SOFTWARE OR DOCUMENTATION.
+
+The name and trademarks of copyright holders may NOT be used in advertising or
+publicity pertaining to the software without specific, written prior permission.
+Title to copyright in this software and any associated documentation will at
+all times remain with copyright holders.
+
+____________________________________
+
+This formulation of W3C's notice and license became active on December 31 2002.
+This version removes the copyright ownership notice such that this license can
+be used with materials other than those owned by the W3C, reflects that ERCIM
+is now a host of the W3C, includes references to this specific dated version of
+the license, and removes the ambiguous grant of "use". Otherwise, this version
+is the same as the previous version and is written so as to preserve the Free
+Software Foundation's assessment of GPL compatibility and OSI's certification
+under the Open Source Definition. Please see our Copyright FAQ for common
+questions about using materials from our site, including specific terms and
+conditions for packages like libwww, Amaya, and Jigsaw. Other questions about
+this notice can be directed to site-policy@w3.org.
+
+Joseph Reagle <site-policy@w3.org>
+
+This license came from: http://www.megginson.com/SAX/copying.html
+ However please note future versions of SAX may be covered
+ under http://saxproject.org/?selected=pd
+
+SAX2 is Free!
+
+I hereby abandon any property rights to SAX 2.0 (the Simple API for
+XML), and release all of the SAX 2.0 source code, compiled code, and
+documentation contained in this distribution into the Public Domain.
+SAX comes with NO WARRANTY or guarantee of fitness for any
+purpose.
+
+David Megginson, david@megginson.com
+2000-05-05
diff --git a/framework/src/ant/apache-ant-1.9.6/NOTICE b/framework/src/ant/apache-ant-1.9.6/NOTICE
new file mode 100644
index 00000000..a9957fc0
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/NOTICE
@@ -0,0 +1,9 @@
+Apache Ant
+Copyright 1999-2015 The Apache Software Foundation
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
+
+The <sync> task is based on code Copyright (c) 2002, Landmark
+Graphics Corp that has been kindly donated to the Apache Software
+Foundation.
diff --git a/framework/src/ant/apache-ant-1.9.6/README b/framework/src/ant/apache-ant-1.9.6/README
new file mode 100644
index 00000000..95109410
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/README
@@ -0,0 +1,97 @@
+
+ A N T
+
+
+ What is it?
+ -----------
+
+ Ant is a Java based build tool. In theory it is kind of like "make"
+ without makes wrinkles and with the full portability of pure java code.
+
+
+ Why?
+ ----
+
+ Why another build tool when there is already make, gnumake, nmake, jam,
+ and others? Because all of those tools have limitations that its original
+ author couldn't live with when developing software across multiple platforms.
+
+ Make-like tools are inherently shell based. They evaluate a set of
+ dependencies and then execute commands not unlike what you would issue on a
+ shell. This means that you can easily extend these tools by using or writing
+ any program for the OS that you are working on. However, this also means that
+ you limit yourself to the OS, or at least the OS type such as Unix, that you
+ are working on.
+
+ Makefiles are inherently evil as well. Anybody who has worked on them for any
+ time has run into the dreaded tab problem. "Is my command not executing
+ because I have a space in front of my tab!!!" said the original author of Ant
+ way too many times. Tools like Jam took care of this to a great degree, but
+ still use yet another format to use and remember.
+
+ Ant is different. Instead a model where it is extended with shell based
+ commands, it is extended using Java classes. Instead of writing shell
+ commands, the configuration files are XML based calling out a target tree
+ where various tasks get executed. Each task is run by an object which
+ implements a particular Task interface.
+
+ Granted, this removes some of the expressive power that is inherent by being
+ able to construct a shell command such as `find . -name foo -exec rm {}` but
+ it gives you the ability to be cross platform. To work anywhere and
+ everywhere. And hey, if you really need to execute a shell command, Ant has
+ an exec rule that allows different commands to be executed based on the OS
+ that it is executing on.
+
+ The Latest Version
+ ------------------
+
+ Details of the latest version can be found on the Apache Ant
+ Project web site <http://ant.apache.org/>.
+
+
+ Documentation
+ -------------
+
+ Documentation is available in HTML format, in the docs/ directory.
+ For information about building and installing Ant, see
+ docs/manual/index.html
+
+
+ Licensing
+ ---------
+
+ This software is licensed under the terms you may find in the file
+ named "LICENSE" in this directory.
+
+ This distribution includes cryptographic software. The country in
+ which you currently reside may have restrictions on the import,
+ possession, use, and/or re-export to another country, of
+ encryption software. BEFORE using any encryption software, please
+ check your country's laws, regulations and policies concerning the
+ import, possession, or use, and re-export of encryption software, to
+ see if this is permitted. See <http://www.wassenaar.org/> for more
+ information.
+
+ The U.S. Government Department of Commerce, Bureau of Industry and
+ Security (BIS), has classified this software as Export Commodity
+ Control Number (ECCN) 5D002.C.1, which includes information security
+ software using or performing cryptographic functions with asymmetric
+ algorithms. The form and manner of this Apache Software Foundation
+ distribution makes it eligible for export under the License Exception
+ ENC Technology Software Unrestricted (TSU) exception (see the BIS
+ Export Administration Regulations, Section 740.13) for both object
+ code and source code.
+
+ The following provides more details on the included cryptographic
+ software:
+
+ For the SSH family of tasks (<sshexec> and <scp>) Ant requires the
+ JSch <http://www.jcraft.com/jsch/index.html> library as well as the
+ Java Cryptography extensions
+ <http://java.sun.com/javase/technologies/security/>. Ant does not
+ include these libraries itself, but is designed to use them.
+
+ Thanks for using Ant.
+
+ The Apache Ant Project
+ <http://ant.apache.org/>
diff --git a/framework/src/ant/apache-ant-1.9.6/WHATSNEW b/framework/src/ant/apache-ant-1.9.6/WHATSNEW
new file mode 100644
index 00000000..9a6d4782
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/WHATSNEW
@@ -0,0 +1,6263 @@
+Changes from Ant 1.9.5 TO Ant 1.9.6
+===================================
+
+Changes that could break older environments:
+-------------------------------------------
+
+Fixed bugs:
+-----------
+
+ * ArrayIndexOutOfBoundsException when ZIP extra fields are read and
+ the entry contains an UnparseableExtraField.
+ https://issues.apache.org/jira/browse/COMPRESS-317
+
+Other changes:
+--------------
+ * Hidden <javaconstant> resource is published now. It reads the
+ value of a specified java constant.
+
+
+Changes from Ant 1.9.4 TO Ant 1.9.5
+===================================
+
+Changes that could break older environments:
+-------------------------------------------
+
+ * The ReplaceTokens filter can now use token-separators longer than
+ one character. This means it can be used to replace mustache-style
+ {{patterns}} and similar templates. This is going to break code
+ that invokes the setters on ReplaceTokens via the Java API as their
+ parameters have been changed from char to String. It may also
+ break build files that specified multi character tokens and relied
+ on Ant silently ignoring all but the first character.
+ Bugzilla Report 56584
+
+ * The changes that added <get>'s support for gzip encoding
+ automatically uncompressed content that would not have been touched
+ before - like when downloading .tar.gz files. A new flag has been
+ added to control the behavior and its default will make <get> work
+ as it did in 1.9.3. I.e. if you want it to work like 1.9.4
+ you have to explicitly set tryGzipEncoding to true.
+ Bugzilla Report 57048
+
+Fixed bugs:
+-----------
+
+ * TarArchiveInputStream failed to read archives with empty gid/uid
+ fields.
+ Bugzilla Report 56641
+
+ * TarArchiveInputStream could throw IOException when reading PAX
+ headers from a "slow" InputStream.
+
+ * XMLJunitResultFormatter could throw NullPointerException if Java
+ cannot determine the local hostname.
+ Bugzilla Report 56593
+
+ * URLResource#getLastModified tried to access the connection to the
+ URL without making sure it was established, potentially leading to
+ a NullPointerException when using FTP.
+ Bugzilla Report 56873
+
+ * Long-Name and -link or PAX-header entries in TAR archives
+ always had the current time as last modfication time, creating
+ archives that are different at the byte level each time an
+ archive was built.
+
+ * runant.py should now work as well when the path of the Java executable
+ contains spaces.
+ github pull request #1
+
+ * <junitreport> now supports nested <classpath> and <factory> elements.
+ Bugzilla Report 47002
+
+ * complete-ant-cmd.pl now also knows about the -file option.
+ Bugzilla Report 57371
+
+ * the br-replace template inside the XSLT stylesheets used by
+ <junitreport> could cause stack overflows or out-of-memory errors
+ when applied to big outputs.
+ Bugzilla Report 57341
+
+ * removed spurious warning about unclosed ZipFiles when reading the
+ archive failed.
+ Port of https://issues.apache.org/jira/browse/COMPRESS-297
+
+ * FileUtils.rename which is used by several tasks can throw a
+ NullPointerException if the "normal" renameTo operation fails and
+ an exception occurs while rename falls back to copying and deleting
+ the file.
+ Bugzilla Report 57533
+
+ * complete-ant-cmd.pl would incorrectly suggest words from the build
+ file description.
+ Bugzilla Report 51931
+
+ * complete-ant-cmd.pl now also completes tasks without a description.
+ Bugzilla Report 57542
+
+ * LocalPropertyStack could run into ConcurrentModificationException
+ when tasks spawned new child threads that accessed the properties.
+ Bugzilla Report 55074
+
+ * TarEntry's constructor with a File and a String arg didn't
+ normalize the name.
+
+ * Between 1.8.4 and 1.9.0 TarInputStream started to parse file
+ names using the platform's default encoding rather than as ASCII.
+ This has been a breaking change that has never been marked as such
+ (in fact it went unnoticed). In order to allow <untar> and
+ <tarfileset> to work on platforms who's encoding doesn't match the
+ encoding of file names inside the archive, both now support
+ encoding attributes.
+ The attribute has also been added to <tar> for symmetry.
+ Bugzilla Report 57822
+
+Other changes:
+--------------
+
+ * it is now possible to provide proxy configuration to signjar
+ when using the timestamped authority.
+ Bugzilla Report 56678
+
+ * complete-ant-cmd.pl now also analyzes the ANT_ARGS environment
+ variable.
+ Bugzilla Report 57371
+
+ * ported some of the write-optimization of Commons Compress 1.10 to
+ the ZIP package
+
+ * adapted unit tests to Java9 and added "javac1.9" as valid option
+ for javac's compiler attribute.
+
+ * performance improvements for <intersect>
+ Bugzilla Report 57588
+
+ * MailLogger can now add CC and BCC addresses.
+ Bugzilla Report 57789.
+
+ * <scp>'s buffer size has been increased from 1k to 100k to match
+ <ftp> and <get>.
+ github pull requests #8 and #9
+
+ * The tar package can now deal with group and user ids bigger than
+ 0x80000000.
+ https://issues.apache.org/jira/browse/COMPRESS-314
+ https://issues.apache.org/jira/browse/COMPRESS-315
+
+ * <scp> has new attributes fileMode and dirMode that control the
+ permissions on the remote side when sending data via SSH.
+ Bugzilla Report 43271.
+
+ * New <allbutlast> and <allbutfirst> resource collections can be used
+ to select all but a given subset of a resource collection.
+ Bugzilla Report 57834.
+
+Changes from Ant 1.9.3 TO Ant 1.9.4
+===================================
+
+Changes that could break older environments:
+-------------------------------------------
+
+ * the prefixValues attribute of <property> didn't work as expected
+ when set to false (the default).
+ It is quite likely existing build files relied on the wrong
+ behavior and expect Ant to resolve the value side against the
+ properties defined in the property file itself - these build files
+ must now explicitly set the prefixValues attribute to true.
+ Bugzilla Report 54769
+
+ * when matching an entry of a zip/tarfileset against a pattern a
+ leading slash will be stripped from the entry name. Most archives
+ don't contain paths with leading slashes anyway.
+ This may cause include/exclude patterns that start with a / to stop
+ matching anything. Such patterns only used to work by accident and
+ only on platforms with multiple file system roots.
+ Bugzilla Report 53949
+
+ * DirectoryScanner and thus fileset/dirset will now silently drop all
+ filesystem objects that are neither files nor directories according
+ to java.io.File. This prevents Ant from reading named pipes which
+ might lead to blocking or other undefined behavior.
+ Bugzilla Report 56149
+
+ * BuildFileTest and BaseSelectorTest have both been deprecated in
+ favour of BuildFileRule and BaseSelectorRule respectively, and the
+ tests that previously extended these base tests have been converted to
+ JUnit 4 tests using the new "rule"s. Any external test that sub-classed
+ a test in the Ant workspace, rather than BuildFileTest, will need
+ changed to either use JUnit4's annotations, or be modified to
+ extend BuildFileTest directly. This will not affect any tests that are
+ being executed by Ant's junit or batchtest tasks that are not specifically
+ testing Ant's code.
+
+Fixed bugs:
+-----------
+
+ * <import>/<include> failed when the importing file was loaded from an
+ URI or a jar and it imported a file from the local file system via
+ an absolute path.
+ Bugzilla Report 50953
+
+ * <import> could import the same resource twice when imported via
+ different resource types.
+ Bugzilla Report 55097
+
+ * several calls to File#mkdirs could fall victim to a race condition
+ where another thread already created the same directory.
+ Bugzilla Report 55290
+
+ * <manifestclasspath> created '/' rather than './' for the parent
+ directory of the given jarfile.
+ Bugzilla Report 55049
+
+ * <concat>'s fixlastline="true" didn't work when using certain filter
+ readers.
+ Bugzilla Report 54672
+
+ * several places where resources are read from jars will now
+ explicitly disable caching to avoid problems with reloading jars.
+ Bugzilla Report 54473
+
+ * AntClassloader will now ignore files that are part of the classpath
+ but not zip files when scanning for resources. It used to throw an
+ exception.
+ Bugzilla Report 53964
+
+ * <javadoc> caused a NullPointerException when no destdir was set.
+ Bugzilla Report 55949
+
+ * <jar filesetmanifest="mergewithoutmain"> would still include the
+ Main section of the fileset manifests if there was no nested
+ manifest or manifest attribute.
+ Bugzilla Report 54171
+
+ * reading of compiler args has become more defensive
+ Bugzilla Report 53754
+
+ * <copy> without force="true" would not only fail to overwrite a
+ read-only file as expected but also remove the existing file.
+ Bugzilla Report 53095
+
+ * <delete removeNotFollowedSymlinks="true"> would remove symbolic
+ links to not-included files. It will still delete symlinks to
+ directories that would have been followed even if they are not
+ explicitly included. exclude-Patterns can still be used to
+ preserve symbolic links.
+ Bugzilla Report 53959
+
+ * Sometimes copy-operations using NIO FileChannels fail. Ant will
+ now try to use a Stream based copy operation as fallback when the
+ Channel based copy fails.
+ Bugzilla Reports 53102 and 54397
+
+ * Javadoc.postProcessGeneratedJavadocs() fails for Classes that
+ extend Javadoc
+ Bugzilla Report 56047
+
+ * TarInputStream will now read archives created by tar
+ implementations that encode big numbers by not adding a trailing
+ NUL.
+
+ * the isExists() method of URLResource returned false positives for
+ HTTP and FTP URLs.
+
+Other changes:
+--------------
+
+ * initial support for Java 1.9
+
+ * <sshexec> can optionally pass System.in to the remote process
+ Bugzilla Report 55393
+
+ * <sshexec> now supports capturing error output of the executed
+ process and setting a property from the return code.
+ Bugzilla Report 48478
+
+ * <javadoc> now has an option to fail if javadoc issues warnings.
+ Bugzilla Report 55015
+
+ * <sql> has a new outputencoding attribute.
+ Bugzilla Report 39541
+
+ * changes to JUnitTestRunner and PlainJUnitResultFormatter to make
+ OutOfMemoryErrors less likely.
+ Bugzilla Report 45536
+
+ * changes to DOMElementWriter to make OutOfMemoryErrors less likely.
+ Bugzilla Report 54147
+
+ * <redirector> has a new attribute binaryOutput that prevents Ant
+ from splitting the output into lines. This prevents binary output
+ from being corrupted but may lead to error and normal output being
+ mixed up.
+ Bugzilla Report 55667
+ Bugzilla Report 56156
+
+ * the nested <message> elements of <mail> now have an optional
+ inputEncoding attribute that can be used to specify the encoding of
+ files read that don't use the platform's default encoding.
+ Bugzilla Report 56258
+
+ * The <get> task now explicitly accepts and supports the gzip content encoding.
+ Bugzilla Report 49453
+
+ * A new resourcecollection type <multirootfileset> acts like a union
+ of <fileset>s and <dirset>s that share the same configuration but
+ have different base directories.
+ Bugzilla Report 48621
+
+ * <get> has a quiet attribute that makes the task log errors only
+ when enabled.
+ GitHub Pull Request #1
+
+* <junit> has now a threads attribute allowing to run the tests in several threads.
+ Bugzilla Report 55925
+
+* addition of a new ProcessUtil class providing the process id of the current process
+
+* changes to allow to run the JUnit testcases of Ant in parallel,
+ by making them use unique temporary directories
+
+Changes from Ant 1.9.2 TO Ant 1.9.3
+===================================
+
+Fixed bugs:
+-----------
+
+ * <parallel> swallowed the status code of nested <fail> tasks.
+ Bugzilla Report 55539.
+
+ * a race condition could make <fixcrlf> tasks of parallel builds to
+ interfere with each other.
+ Bugzilla Report 54393.
+
+ * <mail>'s mailport still didn't work properly when using smtps.
+ Bugzilla Report 49267.
+
+ * using attributes belonging to the if and unless namespaces
+ made macrodef fail.
+ Bugzilla Report 55885.
+
+ * Ant 1.8 exec task changes have slowed exec to a crawl
+ Bugzilla Report 54128.
+
+ * Apt is not available under JDK 1.8
+ Bugzilla Report 55922.
+
+
+Other changes:
+--------------
+
+ * Documentation fix for if/unless attributes. PR 55359.
+
+ * tar entries with long link names are now handled the same way as
+ entries with long names.
+
+ * Addition of 'skipNonTests' attribute to <junit> and <batchtest>
+ tasks to allow the tasks to skip classes that don't contain tests.
+
+ * <filterset> now supports a nested <propertyset> to specify filters.
+ Bugzilla Report 55794.
+
+ * <xslt>'s params can now be typed.
+ Bugzilla Report 21525.
+
+ * build of Mac OS X pkg installer
+ Bugzilla Report 55899.
+
+Changes from Ant 1.9.1 TO Ant 1.9.2
+===================================
+
+Fixed bugs:
+-----------
+
+ * Parsing of zip64 extra fields has become more lenient in order to
+ be able to read archives created by DotNetZip and maybe other
+ archivers as well.
+
+ * TarInputStream should now properly read GNU longlink entries' names.
+ Bugzilla Report 55040.
+
+ * <java> and <exec> used to be too restrictive when evaluating
+ whether a given set of options is compatible with spawning the new
+ process.
+ Bugzilla Report 55112.
+
+Other changes:
+--------------
+
+ * <javadoc> will now post-process the generated in order to mitigate
+ the frame injection attack possible in javadocs generated by Oracle
+ JDKs prior to Java7 Update 25. The vulnerability is known as
+ CVE-2013-1571.
+ There is an option to turn off the post-processing but it is only
+ recommended you do so if all your builds use a JDK that's not
+ vulnerable.
+ Bugzilla Report 55132.
+
+Changes from Ant 1.9.0 TO Ant 1.9.1
+===================================
+
+Changes that could break older environments:
+-------------------------------------------
+
+ * Users who have their own ProjectHelper implementation will need to change it because the import and include tasks
+ will now default the targetPrefix to ProjectHelper.USE_PROJECT_NAME_AS_TARGET_PREFIX.
+ Users using the default ProjectHelper2 with ant need not worry about this change done to fix Bugzilla Report 54940.
+
+
+Fixed bugs:
+-----------
+
+ * Corrected XSLTC error in <junitreport>.
+ Bugzilla Report 54641.
+
+ * Provide more control over Zip64 extensions created by <zip> and
+ related tasks. In particular no Zip64 extensions will be used at
+ all by the <jar> task family by default - this is required for jars
+ to be readably by Java5.
+ Bugzilla Report 54762.
+
+ * Fixed loading of external dependencies in JUnit task.
+ Bugzilla Report 54835.
+
+ * Target rewriting for nested "include" only works when "as" is specified.
+ See also "Changes that could break older environments"
+ Bugzilla Report 54940.
+
+
+Other changes:
+--------------
+
+ * strict attribute added to <signjar>.
+ Bugzilla Report 54889.
+
+ * simplifying Execute.getEnvironmentVariables since we are only running on Java 1.5 or higher now
+
+ * Added conditional attributes.
+ Bugzilla Report 43362
+
+ * Recommending to upgrade jsch to 0.1.50, particularly if you are using Java 1.7.
+ jsch is the library behind the sshexec and scp Ant tasks.
+ Versions of jsch older than 0.1.50 fail randomly under Java 1.7 with an error message "verify: false"
+
+Changes from Ant 1.8.4 TO Ant 1.9.0
+===================================
+
+Changes that could break older environments:
+-------------------------------------------
+
+ * Ant now requires at least Java 1.5 to compile and to run
+
+ * FixCRLF used to treat the EOL value ASIS to convert to the system property
+ line.separator. Specified was that ASIS would leave the EOL characters alone,
+ the task now really leaves the EOL characters alone. This also implies that
+ EOL ASIS will not insert a newline even if fixlast is set to true.
+ Bugzilla report 53036
+
+ * The CommandLauncher hierarchy that used to be a set of inner
+ classes of Execute has been extracted to the
+ org.apache.tools.ant.taskdefs.launcher package.
+
+ * Any FileResource whose represented File has a parent also has a basedir.
+
+ * Removing the Perforce Ant tasks replaced by tasks supplied by Perforce Inc.
+
+ * Setting the default encoding of StringResource to UTF-8 instead of null
+
+ * Upgrade JUnit 4 to JUnit 4.11
+
+Fixed bugs:
+-----------
+
+ * Made VectorSet faster.
+ Bugzilla Report 53622.
+
+ * Incorrect URLs in Ant child POMs.
+ Bugzilla Report 53617.
+
+ * Subclasses of JUnitTask did not correctly find junit.jar.
+ Bugzilla Report 53571.
+
+ * External XML catalog resolver failed to use project basedir when given an
+ unmentioned relative path like the internal resolver does.
+ Bugzilla Report 52754.
+
+ * Fixed some potential stream leaks.
+ Bugzilla Reports 52738, 52740, 52742, 52743.
+
+ * Updated documentation to fix spelling errors / broken links.
+ Bugzilla Reports 53215, 53291, 53202
+
+ * Unable to override system properties. It was not possible not to override
+ system properties from the command line (or from a property file).
+ Bugzilla Report 51792
+
+ * <javac> by default fails when run on JDK 8.
+ Bugzilla Report 53347.
+
+ * ExtensionPoint doesn't work with nested import/include
+ Bugzilla Report 53405.
+
+ * <packagemapper> failed to strip the non-matched parts with
+ handledirsep="true".
+ Bugzilla Report 53399.
+
+ * <expandproperties> filter caused a NullPointerException when input
+ was empty.
+ Bugzilla Report 53626.
+
+ * <get> now supports HTTP redirects using status code 307.
+ Bugzilla Report 54374.
+
+ * ssh tasks prompt for kerberos username/password under Java 7
+ Bugzilla Report 53437.
+
+ * Zip task on <mappedresources> that excludes certain files by way of the mapper resulted in a NullPointerException
+ Bugzilla Report 54026
+
+ * The ant launcher script should properly detect JAVA_HOME on
+ MacOS X 10.7
+ Bugzilla Report 52632
+
+ * Depend task does not handle invokeDynamic constant pool entries - java.lang.ClassFormatError: Invalid Constant Pool entry Type 18
+ Bugzilla Report 54090
+
+ * Base64Converter not properly handling bytes with MSB set (not masking byte to int conversion)
+ Bugzilla Report 54460
+
+ * The size resource comparator would return wrong results if file
+ sizes differed by more than 2 GB.
+ Bugzilla Report 54623
+
+ * Unable to encode properly into UTF-8 when the system property file.encoding is
+ set to ANSI_X3.4-1968.
+ Bugzilla Report 54606
+
+ * JUnit4 tests marked @Ignore do not appear in XML output
+ Bugzilla Report 43969
+
+Other changes:
+--------------
+
+ * merged the ZIP package from Commons Compress, it can now read
+ archives using Zip64 extensions (files and archives bigger that 4GB
+ and with more that 64k entries).
+
+ * a new task <commandlauncher> can be used to configure the
+ CommandLauncher used by Ant when forking external programs or new
+ Java VMs.
+ Bugzilla Report 52706.
+
+ * merged the TAR package from Commons Compress, it can now read
+ archives using POSIX extension headers and STAR extensions.
+
+ * merged the BZIP2 package from Commons Compress, it can now
+ optionally read files that contain multiple streams properly.
+
+ * <bunzip2> will now properly expand files created by pbzip2 and
+ similar tools that create files with multiple bzip2 streams.
+
+ * <tar> now supports a new "posix" option for longfile-mode which
+ will make it create PAX extension headers for long file names. PAX
+ extension headers are supported by all modern implementations of
+ tar including GNU tar.
+ This option should now be used in preference to "warn" or "gnu" as
+ it is more portable. For backwards compatibility reasons "warn"
+ will still create "gnu" extensions rather than "posix" extensions.
+
+ * The ProjectHelper class now exposes a method to be used by third party
+ implementations to properly resolve the binding between target extensions
+ and extension points.
+ Bugzilla Report 53549.
+
+ * Make extension point bindable to imported prefixed targets
+ Bugzilla Report 53550.
+
+ * Add the possibility to register a custom command line argument processor.
+ See org.apache.tools.ant.ArgumentProcessor and manual/argumentprocessor.html
+
+ * add the possibility to suppress stdout in the sshexec task.
+ Bugzilla Report 50270.
+
+ * add an encoding attribute to the contains selector.
+ This will be useful to use the contains selector if the encoding of the VM is different from the encoding
+ of the files being selected.
+
+ * support for GNU Classpath.
+ Bugzilla report 54760.
+
+Changes from Ant 1.8.3 TO Ant 1.8.4
+===================================
+
+Fixed bugs:
+-----------
+
+ * Ported libbzip2's fallback sort algorithm to CBZip2OutputStream to
+ speed up compression in certain edge cases. Merge from Commons
+ Compress.
+
+ Using specially crafted inputs this can be used as a denial of
+ service attack.
+ See http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-2098
+
+Changes from Ant 1.8.2 TO Ant 1.8.3
+===================================
+
+Changes that could break older environments:
+-------------------------------------------
+
+ * The Enumeration returned by AntClassLoader#getResources used to
+ return null in nextElement after hasNextElement would return false.
+ It has been changed to throw a NoSuchElementException instead so
+ that it now adheres to the contract of java.util.Enumeration.
+ Bugzilla Report 51579.
+
+Fixed bugs:
+-----------
+
+ * Removed buggy duplicate JAR list in RPM mode.
+ Bugzilla Report 52556.
+
+ * Launcher fixed to pass the right class loader parent.
+ Bugzilla Report 48633.
+
+ * <junitreport> mishandled ${line.separator}.
+ Bugzilla Report 51049.
+
+ * <junitreport> did not work in embedded environments on JDK 7.
+ Nor did <xslt> when using Xalan redirects.
+ Bugzilla Report 51668, 52382.
+
+ * Encoding of unicode escape sequences by the property file task
+ Bugzilla Report 50515.
+
+ * The code that implicitly sets the -source switch if only -target
+ has been specified in <javac> was broken for Java 5 and 6.
+ Bugzilla Report 50578.
+
+ * MailLogger ignore the Maillogger.starttls.enable property.
+ Bugzilla Report 50668.
+
+ * Delete task example does not work
+ Bugzilla Report 50816.
+
+ * <splash>'s proxy handling has been delegated to <setproxy>
+ internally so the two tasks are consistent. <splash>'s way of not
+ setting a proxy caused problems with other Java libraries.
+ Bugzilla Report 50888.
+
+ * Include task breaks dependencies or extension-points for multiple
+ files.
+ Bugzilla Report 50866.
+
+ * Read on System.in hangs for forked java task.
+ Bugzilla Report 50960.
+
+ * FileResource specified using basedir/name attributes was non-functional.
+
+ * Resource collection implementation of mapped PropertySet returned
+ unusable resources.
+
+ * The hasmethod condition failed with a NullPointerException when
+ ignoresystemclasses is true and Ant tried to load a "restricted
+ class" - i.e. a class that the Java VM will only accept when loaded
+ via the bootclassloader (a java.* class).
+ It will now fail with a more useful error message.
+ Bugzilla Report 51035.
+
+ * Exec task may mix the stderr and stdout output while logging it
+ Bugzilla Report 50507.
+
+ * Missing space between "finished" and timestamp in task/target
+ finish message from ProfileLogger.
+ Bugzilla Report 51109.
+
+ * Redirecting the output of a java, exec or apply task could print in the
+ error output stream some "Pipe broken" errors.
+ Bugzilla Report 48789.
+
+ * ZipFile failed to clean up some resources which could lead to
+ OutOfMemoryException while unzipping large archives.
+ A similar problem in ZipArchiveOutputStream has been fixed as well.
+ Bugzilla Report 42696.
+
+ * quiet attribute added to the copy and move tasks, to be used together
+ with failonerror=false, so warnings won't get logged
+ Bugzilla Report 48789.
+
+ * System.in was closed and not readable anymore by the DefaultInputHandler
+ when Ant is used via its Java API.
+ Bugzilla Report 51161
+
+ * <sync> only supported a single non-fileset resource collection even
+ though the manual said it could be multiple.
+
+ * <sync> didn't work properly when working on resource collections.
+ Bugzilla Report 51462.
+
+ * <augment> cause a NullPointerException if it was used in a target
+ that was invoked by multiple targets from the command line.
+ Bugzilla Report 50894.
+
+ * The ZipFile class could read past the start of the file if the
+ given file is not a ZIP archive and it is smaller than the size of
+ a ZIP "end of central directory record".
+
+ * <javac> would create the empty package-info.class file in the wrong
+ directory if no destdir was specified. Note it may still pick the
+ wrong directory if you specify more than one source directory but
+ no destDir. It is highly recommended that you always explicitly
+ specify the destDir attribute.
+ Bugzilla Report 51947.
+
+ * packagemapper now honors the handleDirSep attribute.
+ Bugzilla Report 51086.
+
+ * the attributes of macrodef tasks had their values run through
+ property expansion twice. Still true by default, but can be disabled.
+ Bugzilla Report 42046.
+
+ * jvc doesn't like it if source file names in argument files are
+ quoted.
+ Bugzilla Report 31667.
+
+ * ZipFile didn't work properly for archives using unicode extra
+ fields rather than UTF-8 filenames and the EFS-Flag.
+
+ * Access to DirectoryScanner's default excludes wasn't synchronized.
+ Bugzilla Report 52188.
+
+ * When a Project instance was created by a custom tasks its
+ createTask method didn't work.
+ Bugzilla Report 50788.
+
+Other changes:
+--------------
+
+ * -f/-file/-buildfile accepts a directory containing build.xml.
+
+ * The <javacc>, <jjtree> and <jjdoc> now support a new maxmemory
+ attribute.
+ Bugzilla Report 50513.
+
+ * the documented inputstring attribute of sshexec has been
+ implemented and the actually existing attribute inputproperty
+ documented.
+ Bugzilla Report 50576.
+
+ * The concat task now permits the name of its exposed resource
+ by means of its 'resourcename' attribute.
+
+ * The expandproperties filter now accepts a nested propertyset
+ which, if specified, provides the properties for expansion.
+ Bugzilla Report 51044.
+
+ * <junit filtertrace="true"/> will no longer filter out the very
+ first line of the stacktrace containing the original exception
+ message even if it matches one of the filter expressions.
+
+ * Upgraded to Apache AntUnit 1.2
+
+ * Provide read access to Mkdir.dir. Bugzilla Report 51684.
+
+ * <delete> and <move> have a new attribute performGCOnFailedDelete
+ that may - when set to true - help resolve some problems with
+ deleting empty directories on NFS shares.
+ Bugzilla Report 45786.
+
+ * <loadfile> and <loadresource> used to log at level INFO to signal a
+ property hasn't been set when the resource was empty even if the
+ quiet attribute was set to true. They will now use VERBOSE
+ instead.
+ Bugzilla Report 52107.
+
+ * <javac> has a new attribute createMissingPackageInfoClass that can
+ be set to false to prevent Ant from creating empty dummy classes
+ used for up-to-date-ness checks.
+ Bugzilla Report 52096.
+
+ * URLResources#isExists has become less noisy.
+ Bugzilla Report 51829.
+
+ * The <retry> task has a new optional attribute retryDelay that can
+ be used to make the task sleep between retry attempts.
+ Bugzilla Report 52076.
+
+ * <signjar> has new attributes that control the signature and digest
+ algorithms.
+ Bugzilla Report 52344.
+
+ * Initial support for Java 8.
+
+ * <sshexec> can optionally create a pseudo terminal (like ssh -t)
+ Bugzilla Report 52554.
+
+Changes from Ant 1.8.1 TO Ant 1.8.2
+===================================
+
+Changes that could break older environments:
+-------------------------------------------
+
+ * Prior to Ant 1.8.0 the <copy> task and several other tasks would
+ overwrite read-only destination files. Starting with 1.8.0 they
+ would only do so under special circumstances. Ant 1.8.2 now
+ consistently won't replace a read-only file by default. The same is
+ true for a number of other tasks.
+ The <copy>, <move> and <echo> tasks now have a new force attribute
+ and <concat> has a new forceReadonly attribute that can be used to
+ make the task overwrite read-only destinations.
+ Bugzilla Report 49261.
+
+ * Removed ant-nodeps.jar; it is now merged into ant.jar.
+
+ * DOMElementWriter#encode used to employ special code before encoding
+ ampersands so that &#123; remained &#123; rather than being turned
+ into &amp;#123;. This is no longer the case, ampersands will now
+ be encoded unconditionally.
+ Also DOMElementWriter#encodeData will treat CDATA sections containing a
+ literal "]]>" sequence different now - it will split the CDATA
+ section between the second "]" and ">" and create two sections.
+ This affects <echoxml> task as well as the XML logger or JUnit
+ formatter where ampersands will now always get encoded.
+ In addition DOMElementWriter will now replace the characters \t, \r
+ and \n in attribute values by entity references.
+ Bugzilla Report 49404.
+
+ * The list elements returned by ProjectHelper#getExtensionStack are
+ now String arrays of length 3 rather than 2 in order to support the
+ onMissingExtensionPoint attribute.
+ Bugzilla Report 49473.
+
+ * When using <property file="..." prefix="..."/> properties defined
+ inside the same file will only get used in expansions if the ${}
+ reference uses the same prefix. This is different from Ant 1.8.1
+ but is the same behavior Ant 1.8.0 and earlier exhibited.
+ A new attribute prefixValues can be used to re-enable the behavior
+ of Ant 1.8.1.
+ Bugzilla Report 49373.
+
+ * The files and directories used by Git, Mercurial and Bazaar to
+ store their information are now excluded by the defaultexcludes.
+ Bugzilla Report 49624.
+
+ * The <junit> task no longer generates TestListener events - which
+ have been introduced in ant 1.7.0 - by default. The task has a new
+ attribute enableTestListenerEvents and a new "magic" property
+ ant.junit.enabletestlistenerevents has been added that can be used
+ to reinstate the old behavior.
+
+Fixed bugs:
+-----------
+
+ * hostinfo now prefers addresses with a hostname over addresses without
+ a hostname, provided the addresses have the same scope.
+ For local lookup, no IP address will be put in NAME / DOMAIN anymore.
+ For remote lookup, if a host name was provided and only an IP address is
+ found, the IP address will no longer overwrite the host name provided to the
+ task.
+ Bugzilla Report 49513
+
+ * mmap-based file copy problems under JDK 1.4 on Linux.
+ Bugzilla Report 49430.
+
+ * The Sun JVM tries to mmap the entire file during a copy.
+ For large files this is not feasible.
+ We now explicitly request to copy at most 16 MiB per request.
+ Bugzilla Report 49326.
+
+ * DemuxInputStream.read() should return unsigned values
+ Bugzilla Report 49279.
+
+ * The MIME mailer ignored the port parameter when using SSL.
+ Bugzilla Report 49267.
+
+ * <xslt> ignored the classpath when using the default TraX processor.
+ Bugzilla Report 49271.
+
+ * <checksum>'s totalproperty only worked reliably if the same file
+ name didn't occur inside more than one directory.
+ Bugzilla Report 36748.
+
+ * <ftp> could fail to download files from remote subdirectories under
+ certain circumstances.
+ Bugzilla Report 49296.
+
+ * <junit> will now produce better diagnostics when it fails to delete
+ a temporary file.
+ Bugzilla Report 49419.
+
+ * Ant would often scan directories even though there were known to
+ only hold excluded files when evaluating filesets. This never
+ resulted in wrong results but degraded performance of the scan
+ itself.
+ Bugzilla Report 49420.
+
+ * <javac> failed for long command lines on OS/2.
+ Bugzilla Report 49425.
+
+ * <junitreport> did not handle encodings well for stdout/stderr.
+ Bugzilla Report 49418.
+
+ * <junit> could issue a warning about multiple versions of Ant on the
+ CLASSPATH if two CLASSPATH entries differed in case on a
+ case-insensitive file system.
+ Bugzilla Report 49041.
+
+ * The <restrict> resource collection was checking every resource even if
+ we actually just want the first one, like in the example of use of
+ resourcelist in the documentation (getting the first available resource
+ from a mirror list).
+
+ * A race condition could lead to build failures if multiple <mkdir>
+ tasks were trying to create the same directory.
+ Bugzilla Report 49572.
+
+ * the toString() method of the Resources class - and thus any
+ ${toString:} expansion of a reference to a <resources> element -
+ didn't iterate over its nested elements if it hadn't done so prior
+ to the toString invocation already.
+ Bugzilla Report 49588.
+
+ * <apply> in parallel mode didn't work together with a nested
+ <redirector> if maxparallel was <= 0 (the default) or no source
+ files matched.
+ Bugzilla Report 49594.
+
+ * <jar filesetmanifest="merge"> didn't work for manifests added via
+ <zipfileset>s that used the prefix or fullpath attributes.
+ Bugzilla Report 49605.
+
+ * <tempfile createfile="true"> would cause an error unless the prefix
+ attribute has been specified.
+ Bugzilla Report 49755.
+
+ * If forked, after finished <java> was still reading the input stream
+ for a bunch of characters, then stealing them from a following <input>.
+ Bugzilla Report 49119.
+
+ * Ant could be leaking threads for each forked process (started by
+ <exec>, <apply>, <java> or similar tasks) that didn't receive input
+ from a resource or string explicitly.
+ Bugzilla Report 49587.
+
+ * Project#setDefault threw an exception when null was passed in as
+ argument, even though the Javadoc says null is a valid value.
+ Bugzilla Report 49803.
+
+ * runant.py would swallow the first argument if CLASSPATH wasn't set.
+ Bugzilla Report 49963.
+
+ * <taskdef> failed to load resources from jar files contained in a
+ directory that has a "!" in its name.
+ Bugzilla Report 50007.
+
+ * ant.bat exit strategy improvements and issues
+ make the exit codes work in environments where 4NT or MKS are installed
+ Bugzilla Report 41039.
+
+ * <signjar> would fail if used via its Java API and the File passed
+ into the setJar method was not "normalized" (i.e. contained ".."
+ segments).
+ Bugzilla Report 50081.
+
+ * <delete> ignored <fileset>'s errorOnMissingDir attribute
+ Bugzilla Report 50124.
+
+ * <symlink> failed to close files when reading a list of symbolic
+ links from a properties file.
+ Bugzilla Report 50136.
+
+ * <parallel> could allow tasks to start executing even if a task
+ scheduled to run before them timed out.
+ Bugzilla Report 49527.
+
+ * If a <junit> batch with multiple tests times out Ant logs a message
+ about a test named Batch-With-Multiple-Tests since 1.8.0 but the
+ logic that determined the Java package of this pseudo-test has been
+ wrong.
+ Bugzilla Report 45227.
+
+ * <propertyfile> didn't preserve the original linefeed style when
+ updating a file.
+ Bugzilla Report 50049.
+
+ * <zip>'s whenEmpty behavior never consulted the non-fileset
+ resources so the task could fail even though resources have been
+ provided using non-fileset resource collections.
+ Bugzilla Issue 50115.
+
+* ftp chmod could throw a NPE.
+ Bugzilla report 50217.
+
+* The project help (-p option in the command line) will now print
+ the dependencies of the targets in debug mode (-d on the command
+ line)
+
+Other changes:
+--------------
+
+ * <concat>'s force attribute has been deprecated in favor of a new
+ overwrite attribute that is consistent with <copy>'s attribute
+ names.
+
+ * You can now specify a list of methods to run in a JUnit test case.
+ Bugzilla Report 34748.
+
+ * properties in files read because of the -propertyfile command line
+ option will now get resolved against other properties that are
+ defined before the project starts executing (those from the same or
+ earlier -propertfiles or defined via the -D option).
+ Bugzilla Report 18732.
+
+ * <pathelement>s can now contain wildcards in order to use wildcard
+ CLASSPATH entries introduced with Java6.
+ The wildcards are not expanded or even evaluated by Ant and will be
+ used literally. The resulting path may be unusable as a CLASSPATH
+ for Java versions prior to Java6 and likely doesn't mean anything
+ when used in any other way than a CLASSPATH for a forked Java VM.
+ Bugzilla Report 46842.
+
+ * A new attribute allows targets to deal with nonexistent extension
+ points, i.e. they can extend an extension-point if it has been
+ defined or silently work as plain targets if it hasn't. This is
+ useful for targets that get included/imported in different
+ scenarios where a given extension-point may or may not exist.
+ Bugzilla Report 49473.
+
+ * Ant now logs a warning message if it fails to change the file
+ modification time in for example when using <touch> or preserving
+ timestamps in various tasks.
+ Bugzilla Report 49485.
+
+ * ProjectHelpers can now be installed dynamically via the <projecthelper>
+ Ant task.
+
+ * <import> is now able to switch to the proper ProjectHelper to parse
+ the imported resource. This means that several kinds of different build
+ files can import each other.
+
+ * <copy tofile=""> now also works for non-filesystem resources.
+ Bugzilla Report 49756.
+
+ * The <linecontainsregexp> filter now supports a casesensitive
+ attribute.
+
+ * The <containsregexp> selector now supports casesensitive, multiline
+ and singleline attributes.
+ Bugzilla Report 49764.
+
+ * A new <cutdirsmapper> can be used like wget's --cut-dirs option to
+ strip leading directories from file names.
+
+ * <javah> now supports the GNU project's gcjh compiler.
+ Bugzilla Report 50149.
+
+ * <checksum> supports additional views of a file's path as elements
+ for a custom pattern.
+ Bugzilla Report 50114.
+
+ * JUnit XMLResultAggregator logs the stack trace of caught IO exceptions
+ in verbose runs.
+ Bugzilla Report 48836.
+
+ * StringUtils.parseHumanSizes() should turn parse failures into
+ BuildExceptions.
+ Bugzilla Report 48835.
+
+ * New task <bindtargets> to make a list of targets bound to some
+ specified extension point.
+
+ * Initial support for OpenJDK7 has been added.
+
+ * Ant now uses java.net.CookieStore rather than
+ java.util.ServiceLocator to detect whether the environment is a
+ Java 1.6 system. This means releases of gcj/gij at the time of
+ this release of Ant are detected as Java 1.5 and not 1.6.
+ Bugzilla Report 50256.
+
+ * It is now possible to write a compiler adapter for <javac> that
+ compiles sources with extensions other than .java (but that still
+ compile to .class files).
+ Bugzilla Report 48829.
+
+ * The performance of VectorSet#add(Object) has been improved which
+ should also benefit any operation that scans directories in Ant.
+ Bugzilla Report 50200.
+
+Changes from Ant 1.8.0 TO Ant 1.8.1
+===================================
+
+Changes that could break older environments:
+-------------------------------------------
+
+ * ant-trax.jar is no longer produced since TrAX is included in JDK 1.4+.
+
+ * Ant no longer ships with Apache Xerces-J or the XML APIs but relies
+ on the Java runtime to provide a parser and matching API versions.
+
+ * The stylebook ant task and the ant-stylebook.jar are removed.
+
+Fixed bugs:
+-----------
+
+ * Tasks that iterate over task or type definitions, references or
+ targets now iterate over copies instead of the live maps to avoid
+ ConcurrentModificationExceptions if another thread changes the
+ maps.
+ Bugzilla Report 48310.
+
+ * The filesmatch condition threw a NullPointerException when
+ comparing text files and the second file contained fewer lines than
+ the first one.
+ Bugzilla Report 48715.
+
+ * Regression: The <ear> task would allow multiple
+ META-INF/application.xml files to be added.
+ Bugzilla Report 6836.
+
+ * VectorSet#remove(Object) would fail if the size of the vector
+ equaled its capacity.
+
+ * Regression : ant -diagnostics was returning with exit code 1
+ Bugzilla Report 48782
+
+ * Fix for exec task sometimes inserts extraneous newlines
+ Bugzilla Report 48746
+
+ * SymlinkTest#testSymbolicLinkUtilsMethods failing on MacOS
+ Bugzilla Report 48785.
+
+ * If <concat>'s first resourcecollection child is a <resources>,
+ any subsequently added child resourcecollection joins the first.
+ Bugzilla Report 48816.
+
+ * <get> with an invalid URL could trigger an NPE in some JVMs.
+ Bugzilla Report 48833
+
+ * Broken Pipe issue under Ubuntu Linux
+ Bugzilla Report 48789
+
+ * Properties wrongly read from file or not update during read
+ Bugzilla Report 48768
+
+ * AntClassLoader in Ant 1.8.0 has been considerably slower than in
+ 1.7.1
+ Bugzilla Report 48853
+
+ * ANT_CMD_LINE_ARGS are rippling through lower level Ant usage
+ Bugzilla Report 48876
+
+ * email : IO error sending mail with plain mimetype
+ Bugzilla Report 48932
+
+ * the complete-ant-cmd.pl script failed to create a proper cache of
+ target if "ant -p" failed.
+ Bugzilla Report 48980
+
+ * <rmic>'s sourcebase attribute was broken.
+ Bugzilla Report 48970
+
+ * <copy>'s failonerror didn't work as expected when copying a single
+ element resource collection to a file.
+ Bugzilla Report 49070
+
+ * <get> no longer followed redirects if the redirect URL was relative
+ and not an absolute URL.
+ Bugzilla Report 48972
+
+ * fixed a performance degradation in the code that expands property
+ references.
+ Bugzilla Reports 48961 and 49079
+
+ * <jar filesetmanifest="merge"> was broken on Windows.
+ Bugzilla Report 49090
+
+ * <symlink> delete failed if the link attribute was a relative path
+ to a link inside the current directory without a leading ".".
+ Bugzilla Report 49137
+
+ * <telnet> and <rexec> failed to find the expected strings when
+ waiting for responses and thus always failed.
+ Bugzilla Report 49173
+
+Other changes:
+--------------
+
+ * Project provides new get methods that return copies instead of the
+ live maps of task and type definitions, references and targets.
+
+ * Ant is now more lenient with ZIP extra fields and will be able to
+ read archives that it failed to read in earlier versions.
+ Bugzilla Report 48781.
+
+ * The <zip> family of tasks has been sped up for bigger archives.
+ Bugzilla Report 48755.
+
+ * Add removeKeepExtension option to NetRexxC task.
+ Bugzilla Report 48788.
+
+ * Add prefix attribute to loadproperties task.
+
+ * Add resource attribute to length task.
+
+ * PropertyResource will effectively proxy another Resource if ${name}
+ evaluates to a Resource object.
+
+ * Added forcestring attribute to equals condition to force evaluation
+ of Object args as strings; previously only API-level usage of the
+ equals condition allowed Object args, but Ant 1.8.x+ property
+ evaluation may yield values of any type.
+
+ * BuildFileTest.assertPropertyUnset() fails with a slightly more
+ meaningful error message
+ Bugzilla Report 48834
+
+ * <junit> will now throw an exception if a test name is empty. This
+ used to manifest itself in unrelated errors like
+ Bugzilla Report 43586.
+
+ * A change that made <exec> more reliable on Windows (Bugzilla Report
+ 5003) strongly impacts the performance for commands that execute
+ quickly, like attrib. Basically no single execution of a command
+ could take less than a second on Windows.
+ A few timeouts have been tweaked to allow these commands to finish
+ more quickly but still they will take longer than they did with Ant
+ 1.7.1.
+ Bugzilla Report 48734.
+
+ * Added SimpleBigProjectLogger, intermediate between NoBannerLogger and
+ BigProjectLogger.
+
+ * <mappedresources> supports new attributes enablemultiplemappings
+ and cache.
+
+ * Added the augment task to manipulate existing references via Ant's basic
+ introspection mechanisms.
+
+Changes from Ant 1.8.0RC1 TO Ant 1.8.0
+======================================
+
+Changes that could break older environments:
+-------------------------------------------
+
+ * the appendtolines filter has been renamed to suffixlines.
+
+Fixed bugs:
+-----------
+
+ * stack traces were not reported at all by <junit/>
+ when filtertrace="on", which is the default.
+
+ * ant.bat can now also process the -noclasspath switch when it is
+ the first switch on a command line.
+ Bugzilla Report 48186.
+
+ * <fixcrlf> now tries to delete the created temporary files earlier.
+ Bugzilla Report 48506.
+
+ * the implementation of <zip> had been changed in a way that broke
+ the jarjar links task and protentially other third-party subclasses
+ as well.
+ Bugzilla Report 48541.
+
+ * <scp> task didn't report build file location when a remote operation failed
+ Bugzilla Report 48578.
+
+ * <propertyfile> would add the same comment and a date line each time
+ it updated an existing property file.
+ Bugzilla Report 48558.
+
+ * <sound> didn't work properly in recent Java VMs.
+ Bugzilla Report 48637.
+
+Other changes:
+--------------
+
+Changes from Ant 1.7.1 TO Ant 1.8.0RC1
+======================================
+
+Changes that could break older environments:
+-------------------------------------------
+
+ * if and unless attributes (on <target> as well as various tasks and other
+ elements) have long permitted ${property} interpolation. Now, if the result
+ evaluates to "true" or "false" (or "yes", "no", "on", "off"), that boolean
+ value will be used; otherwise the traditional behavior of treating the value
+ as a property name (defined ~ true, undefined ~ false) is used. Existing
+ scripts could be broken if they perversely defined a property named "false"
+ and expected if="false" to be true, or used if="true" expecting this to be
+ triggered only if a property named "true" were defined.
+
+ * Ant now requires Java 1.4 or later.
+
+ * Improved handling of InterruptException (lets suppose someone/thing
+ is trying to kill the thread when we receive an
+ InterruptException), when an InterruptException is received, we do
+ not wait anymore in a while loop till the end time has been
+ reached.
+ Bugzilla Report 42924.
+
+ * Refactor PropertyHelper and introspection APIs to make extension
+ more granular and support setting task/type attribute values to
+ objects decoded by custom PropertyEvaluator delegates. Also add
+ <propertyhelper> task for registering delegates and/or replacing
+ the registered PropertyHelper instance.
+ Bugzilla Report 42736.
+
+ * Added a restricted form of typedef called <componentdef>. This
+ allows definition of elements that can only be within tasks or
+ types. This method is now used to define conditions, selectors,
+ comparators and filterreaders. This means that tasks may now have
+ nested conditions just by implementing the Condition interface,
+ rather than extending ConditionBase. It also means that the use of
+ namespaces for some of the selectors introduced in Ant 1.7.0 is no
+ longer necessary. Implementing this means that the DynamicElement
+ work-around introduced in Ant 1.7.0 has been removed.
+ Bugzilla Report 40511.
+
+ * In the <touch> task when a <mapper> is used, the millis and
+ datetime attributes now override the time of the source resource if
+ provisioned.
+ Bugzilla Report 43235.
+
+ * Remove fall-back mechanism for references that are not resolved
+ during normal runtime execution.
+
+ * FileUtils.createTempFile now actually creates the file.
+ The TempFile task still does not create the file by default, can be
+ instructed to do so however using a new parameter.
+ Bugzilla Report 33969.
+
+ * A lock in Project ensured that a BuildListener's messageLogged
+ method was only ever executed by a single thread at a time, while
+ all other methods could be invoked by multiple threads
+ simultaniously (while within <parallel>, for example). This lock
+ is no longer in place, messageLogged should be made thread-safe
+ now.
+
+ * <sql>'s onError="stop" no longer fails the build if an error
+ occurs, this is the main difference between stop and error and
+ matches what the documentation implied.
+ Bugzilla Report 24668.
+
+ * Ant's configuration introspection mechanisms have been modified to prefer
+ Resource and FileProvider attributes to plain java.io.File attributes;
+ however the configuration-from-String behavior remains equivalent, rendering
+ a FileResource.
+
+ * CBZip2InputStream will now throw an IOException if
+ passed in a null or empty InputStream to read from.
+ Bugzilla Reports 32200.
+
+ * <unzip> will now fail when trying to extract certain broken
+ archives that would have been silently ignored in earlier version.
+ Bugzilla Report 35000.
+
+ * Ant's <zip> family of tasks tries to preserve the existing Unix
+ permissions when updating archives or copying entries from one
+ archive to another.
+ Since not all archiving tools support storing Unix permissions in
+ the same way that is used by Ant, sometimes the permissions read by
+ Ant seem to be 0, which means nobody is allowed to do anything to
+ the file or directory.
+ If Ant now encounters a permission set of 0 it will assume that
+ this is not the intended value and instead apply its own default
+ values. Ant used to create entries with 0 permissions itself.
+ The <zip> family of tasks has a new attribute preserve0permissions
+ that can be set to restore the old behavior.
+ Bugzilla Report 42122.
+
+ * If a batch containing multiple JUnit tests running inside a forked
+ Java VM caused the VM to crash (or caused a timeout), the
+ formatters would receive an error message for the last test in the
+ batch.
+ Ant will now pass in a test with the name "Batch-With-Multiple-Tests"
+ instead - this is supposed to show more clearly that the last test
+ may not have started at all.
+ Bugzilla Report 45227.
+
+ * If the number of minutes a build takes is bigger then 1000 Ant will
+ no longer print a thousands separator in the "elapsed time"
+ message. It used to be the thousands separator of the current
+ locale.
+ Bugzilla Report 44659.
+
+ * <symlink action="delete"> used to fail if the link was broken (i.e.
+ pointing to a file or directory that no longer existed). It will now
+ silently try to remove the link.
+ Bugzilla Report 41285.
+
+ * <delete file="..."> used to log a warning and not delete broken
+ symbolic links. <delete dir="..."/> didn't even log a warning.
+ The task will now try to delete them in both cases.
+ Bugzilla Report 41285.
+
+ * if the dir attribute of a <fileset> points to a symbolic link and
+ followsymlinks is set to false, the fileset will no longer be
+ scanned and always seem empty.
+ Bugzilla Report 45741.
+
+ * the .NET tasks that have been deprecated since Ant 1.7.0 have been
+ removed, please use the stand-alone Antlib you can find at
+ http://ant.apache.org/antlibs/dotnet/index.html
+ instead.
+
+ * the logic of closing streams connected to forked processes (read
+ the input and output of <exec> and friends) has been changed to
+ deal with cases where child processes of the forked processes live
+ longer than their parents and keep Ant from exiting.
+ It is unlikely but possible that the changed logic breaks stream
+ handling on certain Java VMs.
+ Bugzilla issue 5003.
+
+ * <checksum>'s totalproperty was platform dependent because it relied
+ on java.io.File#compareTo. It has now been made platform
+ independent, which means that totalPropery values obtained on
+ Windows (and other systems where the sort order of File is not case
+ sensitive) can be different from the values obtained with earlier
+ versions of Ant.
+ Bugzilla Report 36748.
+
+ * globmapper didn't work properly if the "to" or "from" patterns
+ didn't contain a "*". In particular it implicitly added a * to the
+ end of the pattern(s). This is no longer the case. If you relied
+ on this behavior you will now need to explicitly specify the
+ trailing "*".
+ Bugzilla Report 46506.
+
+ * <copy> silently ignored missing resources even with
+ failOnError="true". If your build tries to copy non-existent
+ resources and you relied on this behavior you must now explicitly
+ set failOnError to false.
+ Bugzilla Report 47362.
+
+ * Ant now prefers the java.runtime.version system property over
+ java.vm.version for the Created-By Manifest attribute.
+ Bugzilla Report 47632.
+
+ * The <image> task now supports a nested mapper. In order to
+ implement this, the Java API of the task had to change so any
+ custom subclass overriding the processFile method will need to
+ adapt (by overriding the new two-arg processFile method).
+ Bugzilla Report 23243.
+
+ * A new property syntax can be used to set attributes from
+ references: ${ant.ref:some-reference}
+
+ In most cases this will yield the exact same result as
+ ${toString:some-reference} - only when an attribute setter method
+ accepts an object type other than string and the project's
+ reference is an Object of matching type the new syntax will pass in
+ that object.
+
+ If your build file already contains properties whose name starts
+ with "ant.ref:" there is a potential for collision. If your
+ property has been set, normal property expansion will take
+ precedence over the new syntax. If the property has not been set
+ and a reference with the postfix of your property name exists
+ (i.e. in a very unlikely event) then the new syntax would yield a
+ different result (an expanded property) than Ant 1.7.1 did.
+
+ * A ProjectHelper implementation can now provide the default build file
+ name it is expecting, and can specify if they can support a specific build
+ file. So Ant is now capable of supporting several ProjectHelper
+ implementations, deciding on which to use depending of the input build file.
+
+ * Mapper-aware selectors (depends, different, present) now accept typedef'd
+ FileNameMappers.
+
+Fixed bugs:
+-----------
+
+ * The default logger was failing to print complete stack traces for
+ exceptions other than BuildException when inside <ant> or
+ <antcall>, thus omitting often important diagnostic
+ information.
+ Bugzilla 43398 (continued).
+
+ * Better handling of package-info.class.
+ Bugzilla Report 43114.
+
+ * RPM task needed an inserted space between the define and the value.
+ Bugzilla Report 46659.
+
+ * Got rid of deadlock between in, out and err in the Redirector.
+ Bugzilla Report 44544.
+
+ * Caused by AssertionError no longer filtered.
+ Bugzilla Report 45631.
+
+ * <zip> would sometimes recreate JARs unnecessarily.
+ Bugzilla Report 45902.
+
+ * <symlink> task couldn't overwrite existing symlinks that pointed to
+ nonexistent files
+ Bugzilla Report 38199.
+
+ * <symlink> task couldn't overwrite files that were in the way of the symlink.
+ Bugzilla Report 43426.
+
+ * <symlink> task failonerror="false" does not stop build from failing
+ when 'ln' command returns non-zero.
+ Bugzilla Report 43624
+
+ * <touch> task couldn't differentiate between "no resources
+ specified" and "no resources matched."
+ Bugzilla Report 43799.
+
+ * ManifestClassPath failed when a relative path would traverse the
+ file system root.
+ Bugzilla Report 44499.
+
+ * <globmapper> had an indexoutofbounds when the prefix and postfix
+ overlapped.
+ Bugzilla Report 44731.
+
+ * <typedef> and <taskdef> failed to accept file names with #
+ characters in them.
+ Bugzilla Report 45190
+
+ * A deadlock could occur if a BuildListener tried to access an Ant property
+ within messageLogged while a different thread also accessed one.
+ Bugzilla Report 45194
+
+ * Handle null result of system getProperty() in CommandlineJava.
+ Similar to Bugzilla Report 42334.
+
+ * Length task did not process nonexistent Resources even though these might
+ conceivably still carry file length information.
+ Bugzilla Report 45271.
+
+ * <javac>'s includeJavaRuntime="false" should work for gcj now. Note
+ that you may need to set includeAntRuntime to false in order to
+ have full control.
+ Bugzilla Report 34638.
+
+ * <sql> would fail if the executed statement didn't return a result
+ set with some JDBC driver that dissalow Statement.getResultSet to
+ be called in such a situation.
+ Bugzilla Report 36265
+
+ * if the executed statement in <sql> returned a result set and an
+ update count, the count would be lost.
+
+ * if an executed statement in <sql> mixes update count and result set
+ parts, some result sets wouldn't get printed.
+ Bugzilla Report 32168.
+
+ * XmlLogger could lose messages if <parallel> is used.
+ Bugzilla Report 25734.
+
+ * <scp> creates remoteToDir if it doesn't exist.
+ Bugzilla Report 42781
+
+ * CBZip2OutputStream threw an exception if it was closed prior to
+ writing anything.
+ Bugzilla Reports 32200, 45836
+
+ * The IPlanetDeploymentTool didn't use the configured DTD locations.
+ Bugzilla Report 31876.
+
+ * The ant shell script printed a warning under Cygwin if JAVA_HOME
+ was not set.
+ Bugzilla Report 45245.
+
+ * <filterset> sometimes incorrectly flagged infinite recursions of
+ filter tokens
+ Bugzilla Report 44226.
+
+ * failures were treated as errors in forked JUnit tests when JUnit 4
+ was used.
+ Bugzilla Report 43892.
+
+ * <jar> and <manifest> disallowed manifest attributes whose name
+ contained the character '8'.
+ Bugzilla Report 45675.
+
+ * BigProjectLogger would set the project's basedir to the current
+ working directory.
+ Bugzilla Report 45607.
+
+ * only <formatter>s that logged to a file were notified if forked VM
+ crashed or a timeout occurred in <junit>.
+ Bugzilla Report 37312.
+
+ * ant -v -version would print the version information twice.
+ Bugzilla Report 45695.
+
+ * when nested into builds that have been invoked by <ant> tasks
+ <subant> might set the wrong basedir on the called projects.
+ Bugzilla Report 30569.
+
+ * If the message of the failed assertion of a forked JUnit test
+ contained line feeds some excess output ended up in Ant's log.
+ Bugzilla Report 45411.
+
+ * <symlink action="delete"> failed to delete a link that pointed to
+ a parent directory.
+ Bugzilla Report 45743.
+
+ * <symlink action="delete"> failed if ant lacked permission to rename
+ the link's target.
+ Bugzilla Report 41525.
+
+ * when checking whether a jar is signed, <signjar> ignored the
+ sigfile attribute.
+ Bugzilla Report 44805.
+
+ * When using JavaMail all <mail> tasks used the same mail host
+ regardless of their configuration.
+ Bugzilla Report 37970.
+
+ * <signjar> and <issigned> didn't handle aliases with characters other
+ than numbers, letters, hyphen or underscore properly.
+ Bugzilla Report 45820.
+
+ * <filterset> could miss multi-character begin tokens in some cases.
+ Bugzilla Report 45094.
+
+ * <depend> didn't close JARs that were part of the classpath.
+ Bugzilla Report 45955.
+
+ * in some cases <depend> would delete class files even if it didn't
+ find the corresponding source files.
+ Bugzilla Report 45916.
+
+ * <javadoc> failed if the nested <bottom> or <head> contained line
+ breaks.
+ Bugzilla Report 43342.
+
+ * encoding="auto" has been broken in <mail> since Ant 1.7.0 and only
+ worked if JavaMail was available.
+ Bugzilla Report 42389.
+
+ * MailLogger could cause a NullPointerException.
+ Bugzilla Report 44009.
+
+ * <junit> didn't recognize failed assertions as failures if they
+ caused subclasses of AssertionError to be thrown (like
+ org.junit.ComparisonFailure that is thrown when assertEquals
+ fails).
+ Bugzilla Report 45028.
+
+ * the Unix "ant" wrapper script failed to protect wildcards in
+ command line arguments in some cases.
+ Bugzilla Report 31601.
+
+ * <cvstagdiff> crippled file names and could miss some entries if
+ multiple modules have been specified.
+ Bugzilla Report 35301.
+
+ * Tasks with a "public void add(SomeType)" method failed to work as
+ TaskContainers at the same time.
+ Bugzilla Report 41647.
+
+ * Tasks that implementes DynamicElemen or DynamicElementNS failed to
+ work as TaskContainers at the same time.
+ Bugzilla Report 41647.
+
+ * combining SSL and authentication in <mail> and MailLogger failed in
+ some setups.
+ Bugzilla Report 46063.
+
+ * if an error occurs while logging the buildFinished event, the
+ original error is now logged to System.err.
+ Bugzilla Report 25086.
+
+ * <copy> failed with a NullPointerException when copying a resource
+ without a name. It will now fail with a meaningful error message.
+ Bugzilla Report 39960.
+
+ * <xslt> now uses the configured classpath to load the factory (when
+ using TraX) before falling back to Ant's own classpath.
+ Bugzilla Report 46172.
+
+ * <dependset> complained about files being modified in the future if
+ they had been just very recently (within Ant's assumed granularity
+ of the file system).
+ Bugzilla Report 43665.
+
+ * <sshexec> didn't store the output in outputproperty if the remote
+ command failed.
+ Bugzilla Report 46340.
+
+ * DirectoryScanner's slow-scanning algorithm that is used when you
+ ask for excluded or not-included files and/or directories could
+ miss some files and directories in the presence of recursive
+ exclude patterns.
+
+ * <sort> resource collection kept only one of entries deemed equal by
+ the chosen Comparator.
+ Bugzilla Report 46527.
+
+ * the ZipFile class used by <unzip> and others could leave the
+ archive open (making it undeletable on Windows as long as the java
+ VM was running) for files with an unexpected internal structure.
+ Bugzilla Report 46559.
+
+ * The zip package now supports the extra fields invented by InfoZIP
+ in order to store Unicode file names and comments.
+
+ * The zip package detects the encoding bit set by more modern
+ archivers when they write UTF-8 filenames and optionally sets it
+ when writing zips or jars.
+ Bugzilla Report 45548
+
+ * <sync> could run into a NullPointerException when faced with broken
+ symbolic links.
+ Bugzilla Report 46747.
+
+ * The ant shell script should now support MSYS/MinGW as well.
+ Bugzilla Report 46936.
+
+ * <signjar> has a new force attribute that allows re-signing of jars
+ that are already signed.
+ Bugzilla Report 46891.
+
+ * <sshexec> now again honors failonerror in the face of connection
+ errors.
+ Bugzilla Report 46829.
+
+ * The <replacetokens> filter threw an exception if the stream to
+ filter ended with a begin token.
+ Bugzilla Report 47306.
+
+ * <scriptmapper>, <scriptfilter> and <scriptcondition> didn't support
+ the setbeans attribute.
+ Bugzilla Report 47336.
+
+ * <loadproperties>' encoding attribute didn't work.
+ Bugzilla Report 47382.
+
+ * Ant created tar archives could contain random bytes at the end
+ which confused some untar implementations.
+ Bugzilla Report 47421.
+
+ * various places where unchecked PrintWriters could hide exceptions
+ have been revisited to now check the error status or not use a
+ PrintWriter at all.
+ Bugzilla Report 43537.
+
+ * filesetmanifest="mergewithoutmain" in <jar> didn't treat inline
+ manifests as expected.
+ Bugzilla Report 29731.
+
+ * <record> didn't work properly with nested builds.
+ Bugzilla Report 41368.
+
+ * <jar> with filesetmanifest different from skip didn't work if the
+ update attribute has been set to true.
+ Bugzilla Report 30751.
+
+ * The default stylesheets for <junitreport> failed to properly escape
+ XML content in exception stack traces.
+ Bugzilla Report 39492.
+
+ * AntClassLoader didn't set the proper CodeSource for loaded classes.
+ Bugzilla Report 20174.
+
+ * AntClassLoader.getResourceAsStream would return streams to
+ resources it didn't return with getResource and to classes it
+ failed to load.
+ Bugzilla Report 44103.
+
+ * Logging exceptions without a message would cause a
+ NullPointerException.
+ Bugzilla Report 47623.
+
+ * WeblogicDeploymentTool could fail on platforms with a file
+ separator other than "/".
+ Bugzilla Report 35649.
+
+ * The update attribute of the modified selector was ignored.
+ Bugzilla Report 32597.
+
+ * <manifest> and <jar> can now merge Class-Path attributes from
+ multiple sources and optionally flatten them into a single
+ attribute.
+ The default behaviour still is to keep multiple Class-Path
+ attributes if they have been specified and to only include the
+ attributes of the last merged manifest.
+ Bugzilla Report 39655.
+
+ * <delete> didn't work correctly with a <modified> selector because
+ it was scanning the same filesets more than once.
+ Bugzilla Report 43574.
+
+ * when using custom filterreaders with the <filterreader classname="">
+ syntax Ant could leak memory.
+ The problem didn't occur when using <typedef> or <componentdef> to
+ define the filterreader which is the recommended approach.
+ Bugzilla Report 45439.
+
+ * Ant didn't set the proper "magic" value for tar entries containing
+ long file names in GNU longfile mode.
+ Bugzilla Report 47653.
+
+ * The tar task failed to recognize that the archive had to be
+ (re-)created in some cases where the sources are filesystem based
+ resources but not filesets.
+ Bugzilla Report 48035.
+
+ * <sshexec>'s outputproperty was prefixed by the executed command
+ when the command attribute has been used, breaking backwards
+ compatibility to Ant 1.7.0.
+ Bugzilla Report 48040.
+
+ * different task instances of the same <scriptdef>ed tasks could
+ overwrite each others attributes/nested elements.
+ Bugzilla Report 41602.
+
+ * The Hashvalue algortihm implementation of the modified task could
+ fail to read the file(s) completely.
+ Bugzilla Report 48313.
+
+Other changes:
+--------------
+
+ * The get task now also follows redirects from http to https
+ Bugzilla Report 47433
+
+ * A HostInfo task was added performing information on hosts, including info on
+ the host ant is running on.
+ Bugzilla Reports 45861 and 31164.
+
+ * There is now a FileProvider interface for resources that act as a source
+ of filenames. This should be used by tasks that require resources
+ to provide filenames, rather than require that all resources
+ are instances or subclasses of FileResource.
+ Bugzilla Report 43348
+
+ * There is now a URLProvider interface for resources that act as a
+ source of URLs. This should be used by tasks that require resources
+ to provide URLs, rather than require that all resources are
+ instances or subclasses of URLResource.
+
+ * Fixcrlf now gives better error messages on bad directory attributes.
+ Bugzilla Report 43936
+
+ * a new property ant.project.default-target holds the value of the
+ current <project>'s default attribute.
+
+ * a new property ant.project.invoked-targets holds a comma separated
+ list of the targets that have been specified on the command line
+ (the IDE, an <ant> task ...) when invoking the current project.
+
+ * The <type> resource selector has had an "any" type added for better
+ configurability.
+
+ * Ant should detect the OS as both a Mac and a Unix system when
+ running on OpenJDK.
+ Bugzilla Report 44889.
+
+ * new protected getConnection and getStatement methods allow
+ subclasses of SQLExec more control - or access to the cached
+ instances when overriding other methods like runStatements.
+ Bugzilla Report 27178.
+
+ * <sql> has a new failOnConnectionError attribute that can be used to
+ keep a build going even if the task failed to connect to the
+ database.
+ Bugzilla Report 36712.
+
+ * A new attribute strictDelimiterMatching can be used to ignore case
+ or whitespace differences when <sql> searches for delimiters.
+ This is useful if you execute a SQL script that has contains "GO"
+ and "go" as delimiters.
+ Bugzilla Report 26459.
+
+ * A new showWarnings attribute of <sql> allows warnings to be logged.
+ Bugzilla Report 41836.
+
+ * A new treatWarningsAsErrors attribute of <sql> can be used to fail
+ a build if a warning occurs.
+ Bugzilla Report 41836.
+
+ * Ant now supports scoped properties (see Local task).
+ Bugzilla Report 23942.
+
+ * <sql>'s CSV output can be controlled via the new attributes
+ csvColumnSeparator and csvQuoteCharacter.
+ Bugzilla Report 35627.
+
+ * <ftp>'s logging has been improved.
+ Bugzilla Reports 30932, 31743.
+
+ * It is now possible to disable <ftp>'s remote verification.
+ Bugzilla Report 35471.
+
+ * <sshexec> now supports input in a way similar to <exec>
+ Bugzilla Report 39197.
+
+ * <scp> can now preserve the file modification time when downloading
+ files.
+ Bugzilla Report 33939.
+
+ * the new task sshsession can run multiple tasks in the presence of
+ an SSH session providing (local and remote) tunnels.
+ Bugzilla Report 43083.
+
+ * ZipOutputStream has been sped up for certain usage scenarios that
+ are not used by Ant's family of zip tasks.
+ Bugzilla Report 45396.
+
+ * <echo> supports an "output" Resource attribute as an alternative to "file".
+
+ * <sql> "output" attribute now supports any Resource in addition to a file.
+
+ * <scp> no longer requires a passphrase when using key based
+ authentication.
+ Bugzilla Report 33718.
+
+ * a new failOnEmptyArchive attribute on <unzip> and <untar> can now
+ make the task fail the build if it tries to extract an empty
+ archive.
+
+ * <unzip> and <untar> have a new attribute stripAbsolutePathSpec.
+ When set to true, Ant will remove any leading path separator from
+ the archived entry's name before extracting it (making the name a
+ relative file name).
+ Bugzilla Report 28911.
+
+ * <unzip> will now detect that it was asked to extract a file that is
+ not an archive earlier if the file is big.
+ Bugzilla Report 45463.
+
+ * New file and resource selectors <readable/> and <writable/> have
+ been added that select file which the current process can read or
+ write.
+ Bugzilla Report 45081.
+
+ * The filename file selector has a new attribute regex that allows
+ files to be selected by matching their names against a regular
+ expression.
+ Bugzilla Report 45284
+
+ * The name resource selector has a new attribute regex that allows
+ resources to be selected by matching their names against a regular
+ expression.
+ Bugzilla Report 45284
+
+ * Enhanced performance of Project.fireMessageLoggedEvent and DirectoryScanner
+ Bugzilla Reports 45651 and 45665
+
+ * The package list location for offline links can now be specified as
+ an URL.
+ Bugzilla Report 28881
+
+ * <echoxml> now supports XML namespaces.
+ Bugzilla Report 36804.
+
+ * A new listener for <junit> has been added that tries to invoke the
+ tearDown method of a TestCase if that TestCase was run in a forked
+ VM and the VM crashed or a timeout occurred. See the <junit> task's
+ manual page for details.
+ Bugzilla Report 37241.
+
+ * The Jar task now supports the addition of a jar index file in update mode.
+ Previously the absence of the index was not enough to trigger the rebuild;
+ some other update was necessary.
+ Bugzilla report 45098.
+
+ * <ant> has a new attribute "useNativeBasedir" that makes the child
+ build use the same basedir it would have used if invoked from the
+ command line. No matter what other attributes/properties have been
+ set.
+ Bugzilla Report 45711.
+
+ * <patch> has a new optional failOnError attribute.
+ Bugzilla Report 44772.
+
+ * Antlib descriptors will now be parsed by the configured
+ ProjectHelper if the implementation overrides the new
+ canParseAntlibDescriptor and parseAntlibDescriptor methods. If the
+ configured helper doesn't override the methods, a new instance of
+ ProjectHelper2 will be used just like in Ant 1.7.1.
+ Bugzilla Report 42208.
+
+ * It is now possible to explicitly set the executable used by
+ <signjar>.
+ Bugzilla Report 39189.
+
+ * <compositemapper>'s order of results is now predictable.
+ Bugzilla Report 44873
+
+ * a new <firstmatchmapper> has been added, which works similar to
+ <compositemapper> but only returns the results of the first nested
+ mapper that matches.
+ Bugzilla Report 44873
+
+ * <get> has a new maxtime attribute that terminates downloads that
+ are taking too long.
+ Bugzilla Report 45181.
+
+ * <ftp> now supports selectors for remote directories as well.
+ Bugzilla Report 44726.
+
+ * In some cases Ant fails to rename files if the source or target
+ file has just recently been closed on Windows. It will now try to
+ delete the offending file once again after giving the Java VM time
+ to really close the file.
+ Bugzilla Report 45960.
+
+ * two new properties can be used to set the MIME-Type and charset
+ used by MailLogger.
+ Bugzilla Report 27211.
+
+ * a new attribute of <mail> allows the task to succeed if it can
+ reach at least one given recipient.
+ Bugzilla Report 36446.
+
+ * two new properties allow MailLogger to send a fixed text instead of
+ the log file.
+ Bugzilla Report 38029.
+
+ * <cvsversion> is supposed to support CVSNT now.
+ Bugzilla Report 31409.
+
+ * <cvs>' port attribute should now work for all clients that use the
+ environment variable CVS_PSERVER_PORT instead of the "official"
+ CVS_CLIENT_PORT.
+ Bugzilla Report 30124.
+
+ * <cvsversion> now works for local repositories as well.
+
+ * <cvstagdiff> has an option to ignore removed files now.
+ Bugzilla Report 26257.
+
+ * <cvs> and friends now support modules with spaces in their names
+ via nested <module> elements.
+
+ * A new attribute "ignoreEmpty" controls how <concat> deals when
+ there are no resources to concatenate. If it is set to false, the
+ destination file will be created regardless, which reinstates the
+ behavior of Ant 1.7.0.
+ Bugzilla Report 46010.
+
+ * If the new remote attribute is set to true, <cvschangelog> can now
+ work against a remote repository without any working copy.
+ Bugzilla Report 27419.
+
+ * start and end tags can now be used instead of dates in
+ <cvschangelog>.
+ Bugzilla Report 27419.
+
+ * MailLogger and <mail> can now optionally enable support for
+ STARTTLS.
+ Bugzilla Report 46063.
+
+ * <import> has new attributes "as" and "prefixSeparator" that can be
+ used to control the prefix prepended to the imported targets'
+ names.
+
+ * a new task <include> provides an alternative to <import> that
+ should be preferred when you don't want to override any targets.
+
+ * delete has a new attribute removeNotFollowedSymlink. If set to
+ true, symbolic links not followed (because followSymlinks was false
+ or the number of symlinks was too big) will be removed.
+ Bugzilla Report 36658.
+
+ * the os and osfamily attributes of <chown>, <chgrp>, <chmod> and
+ <attrib> can now be used to run the commands on operating systems
+ other than their "native" environment, i.e. non-Unix or non-Windows
+ operating systems respectively.
+ Bugzilla Report 7624.
+
+ * a new resource collection <mappedresources> generalizes the prefix
+ and fullpath attributes of <zipfileset> to arbitrary mappers that
+ can be applied to arbitrary resource collections.
+ Bugzilla Report 4240.
+
+ * <tarfileset> and <zipfileset> have a new attribute
+ errorOnMissingArchive that allows "optional" filesets that don't
+ break the build if the archive doesn't exist.
+ Bugzilla Report 46091.
+
+ * <javadoc> has new attributes that correspond to the
+ -docfilessubdirs and -excludedocfilessubdir command line arguments.
+ Bugzilla Report 34455.
+
+ * <xslt> now fails early if a specified stylesheet doesn't exist.
+ Bugzilla Report 34525.
+
+ * <xslt> now has an option to suppress transformer warnings. This
+ option only has an effect for processors that support this feature;
+ the "trax" processor included with Ant does support it.
+ Bugzilla Report 18897.
+
+ * <xslt> has two new attributes failOnError and
+ failOnTransformationError that can be used to not make the build
+ process proceed if an error occurs.
+ Bugzilla Report 36260.
+
+ * <xslt> has a new attribute failOnNoResources that can be used to
+ make the build fail/continue if the collection of resources to
+ transform is empty.
+ Bugzilla Report 46274.
+
+ * It is now possible to define system properties that should be set
+ during xslt's transformation. This can be used to enable XInclude
+ processing in Xerces, for example.
+ Bugzilla Report 36653.
+
+ * a new resource collection <archives> can be used to specify
+ collections of ZIP and TAR archives as sources. It extracts them on
+ the fly. This is a generalization of the <zipgroupfileset> found
+ as nested element of <zip> and friends.
+ Bugzilla Report 46257.
+
+ * <dependset> has a new verbose attribute that makes the task list
+ all deleted targets and give a hint as to why it deleted them.
+ Bugzilla Report 13681.
+
+ * <replaceregexp> now supports arbitrary filesystem based resource
+ collections.
+ Bugzilla Report 46341.
+
+ * <replace> now supports arbitrary filesystem based resource
+ collections.
+ Bugzilla Report 24062.
+
+ * token and value of <replace>'s nested <replacefilter> can now also
+ be specified as nested elements to allow multiline content more
+ easily.
+ Bugzilla Report 39568.
+
+ * <replace> and <replaceregexp> can now optionally preserve the file
+ timestamp even if the file is modified.
+ Bugzilla Report 39002.
+
+ * The <replace> child-elements <replacetoken> and <replacevalue> have
+ a new attribute that controls whether properties in nested text get
+ expanded.
+ Bugzilla Report 11585.
+
+ * <replace> has a new attribute failOnNoReplacements that makes the
+ build fail if the task didn't do anything.
+ Bugzilla Report 21064.
+
+ * <sync>'s <preserveInTarget> has a new attribute that controls
+ whether empty directories should be kept.
+ Bugzilla Report 43159.
+
+ * ant -diagnostics now checks that it can read as much from the
+ temporary directory as it has written. This may help detecting a
+ full filesystem.
+ Bugzilla Report 32676.
+
+ * <pathconvert> has a new preserveduplicates attribute--historically
+ these were eliminated in the interest of behaving in the manner
+ of a "path."
+
+ * <javac>'s source and target attributes are no longer ignored when
+ using gcj.
+ Bugzilla Issue 46617.
+
+ * ant -diagnostics now outputs information about the default XSLT
+ processor.
+ Bugzilla Issue 46612.
+
+ * the ZIP library will now ignore ZIP extra fields that don't specify
+ a size.
+ Bugzilla Report 42940.
+
+ * CBZip2OutputStream now has a finish method separate from close.
+ Bugzilla Report 42713.
+
+ * the <zip> and <unzip> family of tasks has new options to deal with
+ file name and comment encoding. Please see the zip tasks'
+ documentation for details.
+
+ * <input ...><handler type="secure" /></input> now uses previously
+ undocumented SecureInputHandler shipped with Ant 1.7.1.
+
+ * Command line arguments for <exec> and similar tasks can now have
+ optional prefix and suffix attributes.
+ Bugzilla Report 47365
+
+ * <apply>'s srcfile and targetfile child elements can now have
+ optional prefix and suffix attributes.
+ Bugzilla Report 45625
+
+ * <jar> has a new attribute to enable indexing of META-INF
+ directories which is disabled for backwards compatibility reasons.
+ Bugzilla Report 47457
+
+ * <apt>'s executable attribute can be used to specify a different
+ executable.
+ Bugzilla Report 46230.
+
+ * <rmic>'s new executable attribute can be used to specify a
+ different executable.
+ Bugzilla Report 42132.
+
+ * <javac>, <rmic>, <javah> and <native2ascii> now provide a nested
+ element to specify a classpath that will be used when loading the
+ task's (compiler) adapter class.
+ Bugzilla Report 11143.
+
+ * <javac>, <rmic>, <javah> and <native2ascii> now provide a nested
+ element to specify the task's (compiler) adapter as an instance of
+ a class that has been defined via typedef/componentdef. This
+ allows more control over the classpath and allows adapters to be
+ defined in Antlibs easily.
+
+ * A new subclass org.apache.tools.ant.loader.AntClassLoader5 of
+ AntClassLoader has been added which overrides getResources
+ which became non-final in ClassLoader with Java5+ so
+ this method now behaves as expected.
+ The new subclass will be used by Ant internally if it is available
+ and Ant is running on Java5 or more recent.
+ Bugzilla Report 46752.
+
+ * a new attributes can chose a different request method than GET for
+ the http condition.
+ Bugzilla Report 30244
+
+ * <splash> now supports a configurable display text and a regular
+ expression based way to determine progress based on logged messages.
+ Bugzilla Report 39957.
+
+ * the number of retries on error in <get> is now configurable. <get>
+ can be told to not download files that already exist locally.
+ Bugzilla Report 40058.
+
+ * Ant now builds against commons-net 2.0 as well.
+ Bugzilla Report 47669.
+
+ * A new nested element connectionProperty of <sql> allows setting of
+ arbitrary JDBC connection properties.
+ Bugzilla Report 33452.
+
+ * A new islastmodified condition can check the last modified date of
+ resources.
+
+ * <rmic> has a new destDir attribute that allows generated files to
+ be written to a different location than the original classes.
+ Bugzilla Report 20699.
+
+ * <rmic> has a new listfiles attribute similar to the existing one of
+ <javac>.
+ Bugzilla Report 24359.
+
+ * It is now possible to suppress the "FAILED" lines sent to Ant's
+ logging system via <junit>'s new logFailedTests attribute.
+ Bugzilla Report 35073.
+
+ * <propertyfile> now can delete entries.
+
+ * The <resources> resource collection can now optionally cache its
+ contents.
+
+ * A new <resourceexists> condition can check whether resources exists.
+
+ * <sql> has two new attributes errorproperty and warningproperty that
+ can be set if an error/warning occurs.
+ Bugzilla Report 38807.
+
+ * <sql> has a new attribute rowcountproperty that can be used to set
+ a property to the number of rows affected by a task execution.
+ Bugzilla Report 40923.
+
+ * when Ant copies files without filtering, it will now use NIO
+ channels.
+ Bugzilla Report 30094.
+
+ * <get> has a new attribute that can be used to disable caching on
+ HTTP connections at the HttpUrlConnection level.
+ Bugzilla Report 41891.
+
+ * <tar> and <zip> (and tasks derived from <zip>) will now create the
+ parent directory of the destination archive if it doesn't exist.
+ Bugzilla Report 45377.
+
+ * A new filterreader <sortfilter> that sorts input lines has been
+ added.
+ Bugzilla Report 40504.
+
+ * A new token filter <uniqfilter> that suppresses tokens that match
+ their ancestor token has been added.
+
+ * <rootfileset>s nested into <classfileset>s can now use a dir
+ attribute different from the <classfileset>.
+ Bugzilla Report 37763.
+
+ * <path> can now optionally cache its contents.
+
+ * <property> can now specify values as nested text.
+ Bugzilla Report 32917.
+
+ * a new parentFirst attribute on <javaresource> allows resources to
+ be loaded from the specified classpath rather than the system
+ classloader.
+ Bugzilla Report 41369.
+
+ * <property location="from" basedir="to" relative="true"/> can now
+ calculate relative paths.
+
+ * The <name> selector supports a new handleDirSep attribute that
+ makes it ignore differences between / and \ separators.
+ Bugzilla Report 47858.
+
+ * <get> now supports resource collections (as long as the resources
+ contained provide URLs) and can get multiple resources in a single
+ task.
+
+ * <import> can now import non-File resources if they provide an URL
+ - as the <url> and <javaresource> resources do.
+ Bugzilla Report 29251
+
+ * <import> can now import multiple resources specified as resource
+ collections.
+ Bugzilla Report 22269.
+
+ * a new <resourcelist> type is similar to <filelist> but can read the
+ list of resources from non-file resources and may return resources
+ that are not files.
+
+ * a new filterreader appendtolines complements prefixlines.
+
+ * a new top level element extension-point allows build files to be
+ extended with custom targets more easily.
+
+Changes from Ant 1.7.0 TO Ant 1.7.1
+=============================================
+
+Changes that could break older environments:
+-------------------------------------------
+
+* String resources only have properties single expanded. If you relied on
+ <string> resources being expanded more than once, it no longer happens.
+ Bugzilla report 42277.
+
+* A String resource's encoding attribute was only taken into account when
+ set from the resource's OutputStream; the InputStream provided the String's
+ binary content according to the platform's default encoding. Behavior has
+ been modified to encode outgoing (InputStream) content as well as encoding
+ incoming (OutputStream) content.
+
+* <java> with fork now returns gives -1 instead of 0 as result when failonerror
+ is false and some exception (including timeout) occurs. Br 42377.
+
+* ant-type attribute has been marked as deprecated and a warning has been
+ issued if it is encountered in the build file.
+
+Fixed bugs:
+-----------
+
+* The default logger was failing to print complete stack traces for exceptions
+ other than BuildException, thus omitting often important diagnostic
+ information. Bugzilla 43398.
+
+* Error in FTP task
+ Bugzilla report 41724
+
+* Regression: Locator fails with URI encoding problem when spaces in path
+ Bugzilla report 42222
+
+* Regression in Locator: running Ant off a network share does not work:
+ message "URI has authority component" appears
+ Bugzilla report 42275
+
+* Improvements in AntClassLoader Speed.
+ Bugzilla report 42259
+
+* Error in handling of some permissions, most notably the AllPermission on
+ jdk 1.5
+ Bugzilla report 41776
+
+* Replace task summary output incorrect.
+ Bugzilla report 41544
+
+* Dependset crashes ant when timestamp on files change during Dependset
+ execution.
+ Bugzilla report 41284
+
+* Bug in org.apache.tools.ant.types.resources.comparators.Date
+ Bugzilla report 41411
+
+* <junit> in Ant 1.7.0 could throw NPE if no <classpath> was defined.
+ Bugzilla report 41422.
+
+* In Ant 1.7.0, <fileset> in <javadoc> does not by default include only
+ **/*.java as the documentation claims and earlier revisions did.
+ Bugzilla report 41264.
+
+* SPI support in jar was broken.
+ Bugzilla report 41201.
+
+* jsch-0.1.30 causes SCP task to hang
+ Bugzilla report 41090.
+
+* Target from imported file listed twice in projecthelp.
+ Bugzilla report 41226.
+
+* <sql> task double-expands properties if expandproperties is true,
+ and expands properties if expandproperties is false.
+ Bugzilla report 41204.
+
+* Rolling back Bugzilla 32927 (set a default description for a javadoc tag
+ if not set) as it caused a BC problem.
+ Bugzilla report 41268.
+
+* <apt> forks properly and so memory settings are picked up.
+ Bug report 41280.
+
+* Regression: NPE was thrown when using <pathconvert> against a
+ (third-party instantiated) fileset with null Project reference.
+
+* Strip out all -J arguments to non forking rmic adapters, specifically
+ the Sun and Weblogic compilers.
+ Bug report 41349
+
+* Synchonization issues in PropertyHelper. Bugzilla 41353.
+
+* <concat binary="true" append="true"> did not append. Bugzilla 41399.
+
+* -autoproxy turns Java1.5+ automatic proxy support on. Bugzilla 41904
+
+* Handle null result of system getProperty(). Bugzilla 42334.
+
+* Regression: concat fixlastline="true" should not have applied to
+ nested text, but did in Ant 1.7.0. Bugzilla 42369.
+
+* Regression: ant.version was not passed down in <ant>, <subant>.
+ This worked in Ant 1.6.5, but not in 1.7.0.
+ ant.core.lib (added in 1.7.0) was also not being propagated.
+ Bugzilla bug 42263
+
+* Regression: bzip2 task created corrupted output files for some inputs.
+ Bugzilla bug 41596.
+
+* Regression: <available> with <filepath> did not work.
+ Bugzilla 42735.
+
+* ant script, cd may output to stdout.
+ Bugzilla 42739.
+
+* Modified selector doesn't update the cache if only one file has changed.
+ Bugzilla 42802.
+
+* Regression: Path subclasses that overrode list() stopped working in
+ resourceCollection contexts in Ant 1.7.0. Bugzilla 42967.
+
+* <property> supports loading from xml based property definition.
+ Bugzilla 42946
+
+* <junit> supports collecting and rerunning failed test cases
+ (textXXX methods). Bugzilla 42984.
+
+* War task failed with "No WEB-INF/web.xml file was added" when called
+ a second time. Bugzilla 43121.
+
+* FilterMapper could throw an NPE.
+ Bugzilla 43292.
+
+* Regession nested macrodefs with elements could cause StackOverFlow.
+ Bugzilla 43324.
+
+* Some changes to <junit> broke third party tasks that extend it (like
+ Apache Cactus' Ant task). The changes have been modified so that
+ subclases should now work again - without any changes to the
+ subclass.
+
+Other changes:
+--------------
+
+* Various small optimizations speed up common tasks such as <javac> on large
+ filesets, reducing both I/O and CPU usage.
+
+* Profiling logger has been added with basic profiling capabilities.
+
+* <script> now has basic support for JavaFX scripts
+
+* SSH task can now take a command parameter containing the commands to execute.
+ This allows you to connect to a server and execute a number of commands
+ without constantly reconnecting for each command.
+
+* Upgraded XML API to XML commons version 1.3.04.
+
+* Upgraded to Xerces 2.9.0
+
+* <script> can now work with bsf.jar and js.jar in its <classpath>.
+
+* add errorProperty and updatedProperty to <javac>
+ Bugzilla 35637 and 28941.
+
+* add classpathref attribute to <whichresource>
+ Bugzilla 41158.
+
+* reduce logging noise of <apply skipemptyfilesets="true">
+ Bugzilla 29154
+
+* Show Previous Revision in the tagdiff.xsl stylesheet
+ Bugzilla 29143
+
+* Allow <mapper refid> to refer directly to a FileNameMapper instance.
+
+* If you try and use a type in a namespace (or an antlib), and the type is not
+ recognized but there are other definitions in that namespace, Ant lists what
+ the known definitions are. This helps you find spelling errors.
+
+* Add a <last> resource collection, corresponding to <first>.
+
+* Add new <truncate> task.
+
+* <junitreport> xsl stylesheets allow setting the title used in <title> and <h1> tags by
+ using <report><param> element. Bugzilla 41742.
+
+* Add IgnoreDependenciesExecutor for weird cases when the user wants to run
+ only the targets explicitly specified.
+
+* Patternset allows nested inverted patternsets using <invert>.
+
+* <manifest> checks for validity of attribute names.
+
+* JUnitVersionHelper.getTestCaseClassName is now public. Bugzilla 42231
+
+* <string> resource supports nested text. Bugzilla bug 42276
+
+* <scriptdef> now sources scripts from nested resources/resource collections. This lets you
+ define scripts in JARs, remote URLs, or any other supported resource. Bugzilla report 41597.
+
+* <concat> is now usable as a single-element ResourceCollection.
+
+* It is now possible to provide the value of a <striplinecomments> filter's
+ <comment> nested element as nested text instead of using the 'value'
+ attribute.
+
+* A new logger, BigProjectLogger, lists the project name with every target
+
+* Default text added to macrodef. Bugzilla report 42301.
+
+* "rawblobs" attribute added to SQL task.
+
+* Add new retry task container.
+
+* <jar> has a new strict attribute that checks if the jar complies with
+ the jar packaging version specification.
+
+* <javac> has a new attribute - includeDestClasses.
+ Bugzilla 40776.
+
+* <fileset> has a new attribute - errorOnMissingDir.
+ Bugzilla 11270.
+
+* <javac> handles package-info.java files, there were repeatedly compiled.
+ Bugzilla 43114.
+
+* SecureInputHandler added to use Java 6 System.console().readPassword()
+ when available.
+
+Changes from Ant 1.6.5 to Ant 1.7.0
+===================================
+
+Changes that could break older environments:
+-------------------------------------------
+
+* Initial support for JDK 6 (JSR 223) scripting.
+ <*script*> tasks will now use javax.scripting if BSF is
+ not available, or if explicitly requested by using
+ a "manager" attribute.
+
+* Removed launcher classes from nodeps jar.
+
+* <classconstants> filter reader uses ISO-8859-1 encoding to read
+ the java class file. Bugzilla report 33604.
+
+* Defer reference process. Bugzilla 36955, 34458, 37688.
+ This may break build files in which a reference was set in a target which was
+ never executed. Historically, Ant would set the reference early on, during parse
+ time, so the datatype would be defined. Now it requires the reference to have
+ been in a bit of the build file which was actually executed. If you get
+ an error about an undefined reference, locate the reference and move it somewhere
+ where it is used, or fix the depends attribute of the target in question to
+ depend on the target which defines the reference/datatype.
+ As a result of testing on real live build scripts, a fall-back mechanism
+ was put it place to allow references that are out-of-band to be resolved. If
+ this happens a big warning message is logged. This fall-back mechanism will
+ be removed in Ant 1.8.0.
+
+* <script> and <scriptdef> now set the current thread context.
+
+* Unrestrict the dbvendor names in the websphere element of the ejbjar task.
+ Bugzilla Report 40475.
+
+* <env> nested element in <java>, <exec> and others is now case-insensitive
+ for windows OS. Bugzilla Report 28874.
+
+* Removed support for xalan1 completely. Users of Xalan1 for Ant builds will
+ have to stay at ant 1.6.5 or upgrade to xalan2.
+
+* Use org.apache.log4j.Logger instead of org.apache.log4j.Category.
+ Category has been deprecated for ~2 years and has been removed from
+ the log4j code. Logger was introduced in log4j 1.2 so users of
+ log4j 1.1 and log4j 1.0 need to upgrade to a newer version of log4j.
+ Bugzilla Report 31951.
+
+* build.sysclasspath now also affects the bootclasspath handling of
+ spawned Java VMs. If you set build.sysclasspath to anything other
+ than "ignore" (or leave it unset, since "ignore" is the default when
+ it comes to bootclasspath handling), then the bootclasspath of the
+ VM running Ant will be added to the bootclasspath you've specified.
+
+* The <java fork="false"> now as per default installs a security manager
+ using the default permissions. This is now independent of the
+ failonerror attribute. Bugzilla report 33361.
+
+* <signjar> now notices when the jar and signedjar are equal, and switches
+ to the same dependency logic as when signedjar is omitted. This may break
+ something that depended upon signing in this situation. However, since
+ invoking the JDK jarsigner program with -signedjar set to the source jar
+ actually crashes the JVM on our (Java1.5) systems, we don't think any
+ build files which actually worked will be affected by the change.
+
+* <signjar> used to ignore a nested fileset when a jar was also provided as an
+ attribute, printing a warning message; now it signs files in the fileset.
+
+* An improved method of handling timestamp granularity differences between
+ client and server was added to the <ftp> task. FTP servers typically
+ have HH:mm timestamps whereas local filesystems have HH:mm:ss timestamps.
+ Previously, this required tweaking with the timediffmillis attribute
+ which also was used to handle timezone differences. Now, there is a new
+ timestampgranularity attribute. The default value for get operations is 0
+ since the user has the more powerful preservelastmodified attribute to work
+ with. Since this is not available on put operations the default value
+ adds a minute to the server timestamp in order to account for this,
+ Scripts which previously used timediffmillis to do this compensation may
+ need to be rewritten. timediffmillis has now been deprecated.
+
+* Support for the XSL:P XML parser has been removed.
+ Bugzilla Report 23455.
+
+* Visual Age for Java optional tasks removed as the required library is no
+ longer available.
+
+* Testlet (test) optional task removed as the required library is no
+ longer available.
+
+* IContract optional task removed as the required library is no
+ longer available.
+
+* Metamata (maudit, mmetrics, and mparse tasks) removed as the required
+ library is no longer available.
+
+* Sitraka (jpcoverage, jpcovmerge, jpcovreport) tasks suppressed as the
+ required library is no longer available.
+
+* <fixcrlf> used \r (Mac) line endings on OS X, whose proper line separator
+ is \n (Unix). Bugzilla report 39585.
+
+* <scp> now optionally supports the sftp protocol, you may need a
+ newer jsch.jar. Bugzilla Report 39373.
+
+* Ant launcher program prints errors to stderr, and exits with a 2 exit code
+ value if, for any reason, it cannot actually start Ant proper. This will only
+ affect programs/scripts that called the launcher and which did not want to
+ receive an error if Ant itself would not start
+
+* All .NET tasks are now deprecated in favor of the new .NET Antlib:
+ http://ant.apache.org/antlibs/dotnet/index.html
+
+Fixed bugs:
+-----------
+* Directory deletion did not work properly.
+ Bugzilla 40972.
+
+* docletpath attribute of javadoc was ignored.
+ Bugzilla 40900.
+
+* Fixed incorrect recursion in DOMUtil.listChildNodes().
+ Bugzilla 40918.
+
+* CompressedResource.compareTo() did not
+ take comparison with another CompressedResource into account.
+ Bugzilla 40949.
+
+* Avoid possible NPE in Jar.java.
+ Bugzilla 40847.
+
+* regression in attribute prefix (+ others) for refid in zipfileset and tarfileset.
+ Bugzilla 41004, 30498.
+
+* dependset failed if the basedir of a target fileset did not exist.
+ Bugzilla 40916.
+
+* Recursive filtering encountered NullPointerExceptions under certain
+ circumstances. Bugzilla 41086.
+
+* XmlProperty overrides previously set property value when handling duplicate
+ elements. Bugzilla 41080.
+
+* Having many tasks causes OOM. Bugzilla 41049.
+
+* Regression: <path> was evaluating nested content only once, so that it could
+ not e.g. pick up files that didn't exist the first time through.
+ Bugzilla 41151.
+
+* OOM caused by IH holding on to classes and thus their classloaders.
+ Bugzilla 28283 and 33061.
+
+* <delete> doesn't delete when defaultexcludes="false" and no includes is set
+ fixed. Bugzilla 40313.
+
+* Behavior change of DirectoryScanner/AbstractFileset when conditional include
+ patterns are used. Bugzilla 40722.
+
+* <javac> fails with NPE when compiling with eclipse ecj 3.1.x.
+ Bugzilla 40839.
+
+* JUnitTestRunner had a NPE when unable to create parser, the exception
+ containing the error did not get reported. Bugzilla 36733.
+
+* <checksum> with file and todir option failed. Bugzilla report 37386.
+
+* <path location="loc"> was broken (Regression from beta1).
+ Bugzilla report 40547.
+
+* Nested fileset in <cab> did not work. Bugzilla report 39439.
+
+* The ant wrapper script should now correctly locate the java
+ executable in more recent IBM JDKs for AIX as well.
+
+* URLResource did not close jar files, and also did not disconnect HTTPConnection (s).
+
+* Error calling junitreport. Bugzilla 40595.
+
+* <junittask/> created junitvmwatcher*.properties files but did not close and delete them.
+
+* <xmlproperty> did not create properties for empty leaf elements.
+ Bugzilla report 26286.
+
+* UnknownElement.maybeConfigure always configured.
+ Bugzilla report 40641.
+
+* No check for refid when prefix attribute is set in zipfileset.
+ Bugzilla report 30498.
+
+* Fix for junit4 issue introduced since beta2.
+ Bugzilla report 40682.
+
+* Error in duplicate project name with <import> and <antcall>.
+ Bugzilla report 39920.
+
+* junit4 did not work with fork=no and junit4 in $ANT_HOME/lib.
+ Bugzilla report 40697.
+
+* PathConvert on Windows should process forward and back slashes equivalently.
+ Bugzilla report 32884.
+
+* ant.bat now looks in %USERPROFILE% and %HOMEDRIVE%%HOMEPATH% in addition to
+ %HOME% for pre/post batch files. Bugzilla report 39298.
+
+* The inheritance hierarchy of the legacy <path> type was changed; code built
+ against Ant 1.7 would therefore no longer execute on older versions of Ant.
+ Since <path> is historically heavily used this was undesirable, and since it
+ is also avoidable, the change to <path>'s taxonomy was reverted.
+
+* <zip filesonly="true"> included empty directories. Bugzilla report 40258.
+
+* Invalid hash code of Target causes XmlLogger to fail.
+ Bugzilla report 40207.
+
+* Macro element did not include top level Text. Bugzilla report 36803.
+
+* AntClassLoader did not isolate resources when isolate was set. Bugzilla report 38747.
+
+* Diagnostics broken when using java 1.4. Bugzilla report 40395.
+
+* Exception reporting in <copy> was broken. Bugzilla report 40300.
+
+* Handling of corrupt tar files, TarInputStream.read() never returns EOF.
+ Bugzilla report 39924.
+
+* Some bugs in ReaderInputStream. Bugzilla report 39635.
+
+* <antlr> did not recognise whether the target is up-to-date for html option.
+ Bugzilla report 38451.
+
+* Documented minimal version of jsch now 0.1.29.
+ Bugzilla report 40333.
+
+* <available> searched parent directories for files.
+ Bugzilla report 37148.
+
+* The build could be halted if a file path contained more ".." components than
+ the actual depth of the preceding path. Now such paths are left
+ alone (meaning they will likely be treated as nonexistent
+ files). Bugzilla Report 40281.
+
+* Converting a <dirset> to a string was broken. Bugzilla Report 39683.
+
+* Manifests have improved line length handling, taking care of encoding.
+ Bug reports 37548 / 34425.
+
+* <manifest> now closes the inputstream explicitly. Bug report 39628.
+
+* <rpm> now also correctly searches the first element of the path.
+ Bug report 39345.
+
+* ant.bat now handles classpath set to "". Bug report 38914.
+
+* <junit> now supports JUnit 4. Bugzilla Report 38811.
+
+* <junit> can now work with junit.jar in its <classpath>. Bugzilla
+ Report 38799.
+
+* Some potential NullPointerExceptions, Bugzilla Reports 37765 and 38056.
+
+* Problem when adding multiple filter files, Bugzilla Report 37341.
+
+* Problem referencing jars specified by Class-Path attribute in manifest
+ of a ant task jar file, when this ant task jar file is located in
+ a directory with space, Bugzilla Report 37085.
+
+* Backward incompatible change in ZipFileSet, Bugzilla Report 35824.
+
+* Wrong replacement of file separator chars prevens junitbatchtest
+ from running correctly on files from a zipfileset. Bugzilla Report 35499.
+
+* Calling close twice on ReaderInputStream gave a nullpointer exception.
+ Bugzilla Report 35544.
+
+* Memory leak from IntrospectionHelper.getHelper(Class) in embedded
+ environments. Bugzilla Report 30162.
+
+* Translate task does not remove tokens when a key is not found.
+ It logs a verbose message. Bugzilla Report 13936.
+
+* Incorrect task name with invalid "javac" task after a "presetdef".
+ Bugzilla reports 31389 and 29499.
+
+* <manifest> was not printing warnings about invalid manifest elements.
+ Bugzilla report 32190.
+
+* <replace> got out of memory on large files (part of report 32566).
+ <replace> can now handle files as long as there is enough disk space
+ available.
+
+* Commandline.describeCommand() methods would attempt to describe
+ arguments even when none, other than the executable name, were present.
+
+* Create signjar's helper ExecTask instance directly rather than by
+ typedef discovery mechanisms. Bugzilla report 33433.
+
+* FileUtils.resolveFile() promised to return absolute files but
+ did not always do so.
+
+* <ftp> failed to retrieve a file when the path towards the file contained
+ an element starting with . Bugzilla report 33770.
+
+* "<rmic> always compiles on Java1.5" bugzilla report=33862. Fixed default
+ stub version to always be "compat", even on Java1.5+.
+
+* The .NET compilation tasks failed if filenames given as references
+ contained spaces. Bugzilla Report 27170.
+
+* SQL task would try access result sets of statements that didn't
+ return any, causing problems with Informix IDS 9.2 and IBM DB2 8.1
+ FixPak 6 (or later). Bugzilla Reports 27162 and 29954.
+
+* Task.init() was called twice for most tasks. Bugzilla Report 34411.
+
+* JavaTest testcases sometimes fail on windows. Bugzilla Report 34502.
+
+* Targets with identical name work in imported project. Bugzilla Report 34566.
+
+* DemuxOutputStream now uses a WeakHashMap to store the thread-stream mapping,
+ to avoid holding on to thread references after they terminate.
+
+* <xmlvalidate> and <schemavalidate> create a new parser for every file in a
+ fileset, and so validate multiple files properly. Bugzilla Report 32791.
+
+* <tar> / <untar> now accepts files upto 8GB, <tar> gives an error if larger
+ files are to be included. This is the POSIX size limit.
+
+* <junitreport> removed line-breaks from stack-traces. Bugzilla
+ Report 34963.
+
+* Off-by-one error in environment setup for execution under OpenVMS fixed.
+
+* Bugzilla report 36171: -noclasspath crashes ant if no system
+ classpath is set.
+
+* <pvcs> used wrong switch for retrieving revisions by label.
+ Bugzilla Report 36359.
+
+* <sshexec> closed System.out, disabling output on second and subsequent
+ invocations. Bugzilla report 36302.
+
+* <cvschangelog> was crashing with CVS versions >= 1.12.x due to change in
+ the date format. Bugzilla report 30962.
+
+* The same IntrospectionHelper instance was continuously added as a listener
+ to project. Bugzilla report 37184.
+
+* FileUtils.toURI() was not encoding non-ASCII characters to ASCII,
+ causing impossibility to process XML entities referenced by XML
+ documents in non ASCII paths. Bugzilla report 37348.
+
+* > 1 ssh invocations to a given host would fail. Bugzilla report 36207.
+
+* EmailTask was eating SMTP error messages. Bugzilla report 37547.
+
+* PropertySet API setMapper(...) didn't properly set up the Mapper.
+ Bugzilla report 37760.
+
+* Proper return code for ant.bat. Bugzilla report 13655.
+
+* Project not set on ChainReaderHelpers used by the Redirector.
+ Bugzilla report 37958.
+
+* Copy task would fail on locked (or otherwise uncopyable) files even if
+ failonerror set to false. Bugzilla report 38175.
+
+* <junit> task did not print all the Test names when using forkmode='once'.
+ Bugzilla report 37426.
+
+* <available> could leak resources, Bugzilla Report 38260.
+
+* Redirector called Thread.sleep in a synchronized block. Bugzilla
+ report 37767.
+
+* CCUnlock's objselect attribute could exhibit unpredictable behavior;
+ standardized improperly included objselect and objsel property accessors to
+ delegate to the inherited objSelect property accessor. Bugzilla report 37766.
+
+* <unzip> and <untar> now correctly merge multiple nested patternsets.
+ Bugzilla Report 38973.
+
+* On case-insensitive filesystems, a <move> to change filename case
+ erroneously deleted the "destination" file before attempting to rename
+ the source file. Bugzilla 37701.
+
+* <scp> can now handle uris with @s other than the final one denoting the
+ domain. Bugzilla 38082.
+
+* If the class invoked by the <java> task threw a ClassNotFoundException,
+ this was misinterpreted as the specified class itself not being found.
+
+* <echoproperties> setPrefix javadoc claimed null or empty prefix would be
+ ignored; instead an error was thrown. Bugzilla report 39954.
+
+* <get> would fetch files that were up to date, because it used > in a
+ remote/local timestamp comparison, not >=. Bugzilla 35607.
+
+* <xslt> passes the current file (name + directory) to the
+ stylesheet/transformation. xsl-parameter name is configurable.
+ Bugzilla report 21042.
+
+* The <zip> API allowed creation of directories in file-only archives; a
+ habitual offender was the subclassed <jar>, which included META-INF/ in
+ the destination file regardless of whether filesonly was set to true.
+
+* <rmic> has a new adapter, xnew, to use the -XNew back end on java1.5+.
+ By forking rmic, this works on java1.6+. Bugzilla report 38732.
+
+* Copy of UnknownElement in macroinstance was not recursive.
+ Bugzilla report 40238.
+
+* Mixing of add and addConfigured methods in Mapper/ChainedMapper
+ causes incorrect chaining. Bugzilla report 40228.
+
+Other changes:
+--------------
+
+* Warn user when a reference in the form "${refid}" cannot be resolved as this
+ is a sign they probably meant "refid" (misuse of property expansion syntax).
+
+* Add dtd to javadoc for junit.
+ Bugzilla 40754.
+
+* Add quiet attribute to loadfile/resource.
+ Bugzilla 38249.
+
+* Make Locator#fromURI also append the drive letter when running under Windows
+ with JDK 1.3 or 1.2.
+
+* Do not uppercase the drive letters systematically in FileUtils#normalize.
+
+* Java 5 enumerations may now be used as values in XML attributes in place of
+ EnumeratedAttribute. Bugzilla 41058.
+
+* Create a pom file for ant-testutil and add ant-testutil.jar to the ant
+ distribution. Bugzilla 40980.
+
+* Roll back automatic proxy enabling on Java 1.5. It broke things like
+ Oracle JDBC drivers, and Ant itself on IBM's JVM on AIX, and didn't
+ seem to work to well the rest of the time.
+ To enable the feature, use the -autoproxy command line option.
+
+* Upgraded XML API and parser to Xerces 2.8.1
+
+* A code review of some threaded logic has tightened up the synchronization
+ of Watchdog, ExecuteWatchdog and ExecuteJava, which could reduce the occurrence
+ of race conditions here, especially on Java1.5+.
+
+* Allow broken reference build files. The defer reference processing would
+ break too many files - so allow them with a warning.
+
+* Removed dependency on sun.misc.UUEncoder for UUMailer.
+
+* Added regex attribute to the echoproperties task.
+ Bugzilla 40019.
+
+* <war> task now allows you to omit the web.xml file. as this is optional
+ in the servlet 2.5 and Java EE 5 APIs. set needxmlfile="false" to
+ avoid a missing web.xml file from halting the build.
+
+* Diagnostics catches and logs security exceptions when accessing system properties.
+
+* <javadoc> useexternalfile now applies to all command line arguments
+ of javadoc. Bugzilla report 40852.
+
+* javadoc/tag@description is now set to the name if description is
+ not specified. Bugzill report 32927.
+
+* Some performance improvements, including Bugzilla report 25778.
+
+* Add <matches> condition. Bugzilla report 28883.
+
+* Extending JAR-Task for SPI. Bugzilla report 31520.
+
+* Added <tokens> resource collection for convenient creation of string
+ resources from other resources' content. Inspired by Bugzilla 40504.
+
+* Added <compare> resource selector to select resources based on the
+ results of their comparison to other resources.
+
+* Added outputtoformatters attribute to <junit> to allow suppression
+ of noisey tests. Bugzilla report 12817.
+
+* Log level of message 'Overriding previous definition of reference to'
+ set to Verbose. Bugzilla report 17240.
+
+* Added setbeans attribute to <script> to allow <script>'s to be
+ run without referencing all references.
+ Bugzilla report 37688.
+
+* Added classpath attribute and nested element to <script> to allow
+ the language jars to be specified in the build script.
+ Bugzilla report 29676.
+
+* Trim the driver attribute on the <sql> task. Bugzilla report 21228.
+
+* Allow (jar) files as well as directories to be given to jdepend.
+ Bugzilla report 28865.
+
+* Convert SplashTask to use NOT sun internal classes.
+ Bugzilla report 35619.
+
+* Made PatternSet#hasPatterns public to allow custom filesets access.
+ Bugzilla report 36772.
+
+* Added searchparents attribute to <available>. Bugzilla report 39549.
+
+* Tasks that don't extend Ant's Task class will now get the build file
+ location reflected into a method of the signature void setLocation(Location)
+ - if such a method exists.
+
+* Remove needless synchronization in DirectoryScanner.
+ Bugzilla report 40237.
+
+* Improved recursion detection for lines with multiple matches of same token
+ on a single line. Bugzilla report 38456.
+
+* Task will now log correctly even if no project is set.
+ Bugzilla report 38458.
+
+* Use alternative names for the command line arguments in javac. Bugzilla
+ Report 37546.
+
+* The Reference class now has a project field that will get
+ used (if set) in preference to the passed in project, when
+ dereferencing the reference. Bugzilla Report 25777.
+
+* On DOS and Netware, filenames beginning with a drive letter
+ and followed by a colon but with no directory separator following
+ the colon are no longer (incorrectly) accepted as absolute pathnames
+ by FileUtils.normalize() and FileUtils.isAbsolutePath(). Netware
+ volumes can still be specified without an intervening separator.
+ UNC pathnames on Windows must include a server and share name, i.e.
+ "\\a\b" to be considered valid absolute paths.
+
+* A bug in SQLExec would prevent the execution of trailing,
+ non-semicolon-delimited statements. Bugzilla Report 37764.
+
+* InputHandler implementations may now call InputRequest.getDefaultValue()
+ if they wish. The default handler uses this also. Bugzilla report 28621.
+
+* Took in bugzilla report 39320, "Simple code cleanups"
+
+* Improve compatibility with GNU Classpath and java versions prior to
+ 1.5. Bugzilla 39027.
+
+* ${ant.core.lib} may now be used to refer to the library containing the
+ Ant classes, for instance useful when compiling tasks.
+
+* Minor performance improvements Bugzilla report 37777
+
+* New task <manifestclasspath> converts a path into a property
+ suitable as the value for a manifest's Class-Path attribute.
+
+* Fixed references to obsoleted CVS web site. Bugzilla Report 36854.
+
+* Log fine-grained events at verbose level from JUnit. Bugzilla report 31885.
+
+* <WsdlToDotnet> and <style> are now deprecated in favor of <wsdltodotnet> and
+ <xslt>, respectively. Bugzilla report 25832.
+
+* <echoproperties> now (alphanumerically) sorts the property list
+ before echoing. Bugzilla report 18976.
+
+* A new base class DispatchTask has been added to facilitate elegant
+ creation of tasks with multiple actions.
+
+* Major revision of <wsdltodotnet>. Supports mono wsdl and the microsoft
+ wsdl run on mono, as well as most of the .NET WSE2.0 options. Extra
+ schemas (files or urls) can be named in the <schema> element.
+ Compilers can be selected using the compiler attribute, which defaults
+ to "microsoft" on windows, and "mono" on everything else.
+
+* It is now possible to specify the pattern created/parsed by <checksum>.
+ Bugzilla Report 16539.
+
+* Added a new "failall" value for the onerror attribute of <typedef>.
+ Bugzilla report 31685.
+
+* unzip/unwar/unjar/untar now supports a nested mapper, which lets you unzip
+ in useful ways.
+
+* Junit task -- display suite first.
+ Bugzilla report 31962.
+
+* Added isSigned condition and signedselector selector
+ Bugzilla report 32126.
+
+* Added preserveLastModified attribute to signjar task.
+ Bugzilla report 30987.
+
+* Added <scriptcondition> condition, for inline scripted conditions
+
+* Added <xor> condition for exclusive-or combining of nested conditions.
+
+* Added <scriptselector> selector for scripted file selection
+
+* ant -diagnostics lists contents of ${user.home}/.ant/lib , and
+ checks that the java.io.tmpdir directory exists and is writeable.
+
+* mail task accepts nested header element. Bugzilla report 24713.
+
+* zip/jar/war/ear supports level attribute for deflate compression level.
+ Bugzilla report 25513.
+
+* Added loginputstring attribute to the redirector type.
+
+* Tighten security by sending storepass and keypass to signjar
+ via the input stream of the forked process.
+
+* New task <schemavalidate> extends <xmlvalidate> with extra support
+ for XML Schema (XSD) files.
+
+* <fixcrlf> supports a file attribute for easy fixup of a single file.
+
+* New condition <parsersupports> which can look for XML parser feature or
+ property support in the parser Ant is using.
+
+* fixcrlf can be used in a filterchain.
+
+* <sync> has a new nested element <preserveInTarget> that can be used
+ to protect extra-content in the target directory. Bugzilla Report
+ 21832.
+
+* <signjar> now supports:
+ -nested filesets at the same time as the jar attribute
+ -a destDir attribute with the appropriate dependency logic, which
+ can be used with the jar attribute or nested filesets
+ -a mapper to permit filename remapping on signing
+ -tsaurl and tsacert attributes for timestamped JAR signing
+ -nested <sysproperty> elements, which can be used for proxy setup
+ and the like
+
+* The linecontains and linecontainsregexp filterreaders now support a
+ negate attribute to select lines -not- containing specified text.
+ Bugzilla Report 34374.
+
+* <os> condition adds "winnt" as a family which can be tested. This is
+ all windows platforms other than the Win9x line or Windows CE.
+
+* <exec> (and hence, <apply> and any other derived classes) have an OsFamily
+ attribute, which can restrict execution to a single OS family.
+
+* Added "backtrace" attribute to macrodef. Bugzilla report 27219.
+
+* Ant main provides some diagnostics if it ever sees a -cp or -lib option,
+ as this is indicative of a script mismatch. Bugzilla report 34860
+
+* <junitreport> prints a special message if supplied an empty XML File. This
+ can be caused by the test JVM exiting during a test, either via a
+ System.exit() call or a JVM crash.
+
+* Project name is now used for *all* targets so one can write consistent import
+ build files. Bugzilla report 28444.
+
+* New condition <typefound> that can be used to probe for the declaration
+ and implementation of a task, type, preset, macro, scriptdef, whatever.
+ As it tests for the implementation, it can be used to check for optional
+ tasks being available.
+
+* Check for 1.5.* Ant main class. (weblogic.jar in classpath reports)
+
+* New condition <isfailure> that tests the return-code of an executable. This
+ contains platform-specific logic and is better than comparing the result with
+ "0".
+
+* Added initial support for Resource Collections, including the
+ resourcecount task.
+
+* property attribute of pathconvert is now optional. If omitted the
+ result will be written to the log.
+
+* New mapper, <scriptmapper>, supports scripted mapping of source files/strings
+ to destination strings.
+
+* Add the echoxml task. This will echo nested XML to a file, with
+ the normal <?xml ?> processor instruction. UTF-8 encoding only; no-namespace
+ support.
+
+* Try to make subprojects of custom Project subclasses instances of the
+ same type. Bugzilla report 17901.
+
+* <ssh> and <scp> support keyboard-interactive authentication now.
+
+* <javadoc> now supports -breakiterator for custom doclets if Ant is
+ running on JSE 5.0 or higher. Bugzilla Report: 34580.
+
+* New logger, TimestampedLogger, that prints the wall time that a build
+ finished/failed. Use with
+ -logger org.apache.tools.ant.listener.TimestampedLogger
+
+* <junitreport> now generates pages alltests-errors.html and
+ alltests-fails.html, that list only the errors and failures, respectively.
+ Bugzilla Report: 36226
+
+* New task <makeurl> that can turn a file reference into an absolute file://
+ url; and nested filesets/paths into a (space, comma, whatever) separated
+ list of URLs. Useful for RMI classpath setup, amongst other things.
+
+* <xslt> now accepts nested FileNameMappers e.g. <globmapper>.
+ Bugzilla report 37604.
+
+* New task <loadresource> that accompanies <loadfile> for non file resources.
+
+* <echo> now supports an encoding when saving to a file.
+
+* New GreedyInputHandler added.
+
+* Add textfile attribute to the <filesmatch> condition. When true, the text
+ contents of the two files are compared, ignoring line ending differences.
+
+* New <resourcesmatch> condition.
+
+* Added the onmissingfiltersfile attribute to filterset. Bugzilla report 19845.
+
+* Added the inline handler element to the input task.
+
+* <sql> supports property expansion if you set the expandProperties
+ attribute. By default it does not expand properties, something we
+ dare not change for fear of breaking complex SQL operations in
+ existing files.
+
+* <javadoc>'s packagenames attribute is now optional and defaults to "*".
+
+* <javac>'s source and target attributes as well as <javadoc>'s source
+ attribute will read default values from the properties
+ ant.build.javac.source and ant.build.javac.target.
+
+* Handling of ' ', '#' in CLASSPATH and '#' in -lib (cannot use ' '
+ in -lib on UNIX at the moment). Bugzilla Report 39295.
+
+* <scp> now optionally supports the sftp protocol. Bugzilla Report 39373.
+
+* Resources can now be used to indicate the location of the stylesheet to use
+ in <xslt>. Bugzilla Report 39407.
+
+* New <antversion> condition. Bugzilla report 32804.
+
+* ReplaceTokens should allow properties files. Bugzilla report 39688.
+
+* FTP Account could not be specified in ant FTP task. Bugzilla report 39720.
+
+* Minor performance updates. Bugzilla report 39565.
+
+* New deleteonexit attribute for the <tempfile> task. Bugzilla report 39842.
+ Remember that the exit of the JVM can be a long time coming,
+ especially under an IDE. Don't rely on this being called.
+
+* <scriptdef>-created scripts have support for nested text. All text
+ passed to a scripted task can be accessed via self.text.
+
+* <fixcrlf> now supports an outputencoding attribute. Bugzilla report 39697.
+
+* <junitreport> now supports nested XSL parameters. Bugzilla report 39708.
+
+* <javacc> has a jdkversion attribute to pass the desired JDK version
+ down to javacc. Bugzilla report 38715.
+
+* <cvs> prints passfile info at -verbose level instead of -info. Bugzilla
+ report 35268
+
+* When <javac> can't find the compiler class, it prints out java.home for
+ immediate diagnostics
+
+* Ant launcher now supports a -main attribute so that you can specify
+ an extension class to the built in org.apache.tools.ant.Main
+ class. This class must implement the interface AntMain
+
+Changes from Ant 1.6.4 to Ant 1.6.5
+===================================
+
+Changes that could break older environments:
+--------------------------------------------
+
+Fixed bugs:
+-----------
+
+* <move> was unable to replace existing files or write into
+ existing directories. Bugzilla report 34962.
+
+* <macrodef> with redefined default values was incorrect. (Fix for
+ 31215 had a bug). Bugzilla report 35109.
+
+* <javadoc> will convert backslashes to forwardslashes when generating file
+ list by useexternalfile. Bugzilla report 27814.
+
+Changes from Ant 1.6.3 to Ant 1.6.4
+===================================
+
+Changes that could break older environments:
+--------------------------------------------
+* <ftp> task has had a number of changes. Uptodate calculation previously
+ did not call a file uptodate if the source timestamp and the destination
+ timestamp were equal. Bugzilla report 34941. Any script that attempted
+ to compensate for this by using the timediffmillis attribute might need
+ to be tweaked.
+
+
+Fixed bugs:
+-----------
+
+* Sun javah failed with java.lang.NoClassDefFoundError.
+ Bugzilla report 34681.
+
+* DirectoryScanner.slowScan() was broken. Bugzilla report 34722.
+
+* DirectoryScanner.scan() could throw a NullPointerException on
+ case-insensitive filesystems (read Windows or MacOS X).
+
+* Get w/authentication failed with ArrayOutOfBoundsExceptions.
+ Bugzilla report 34734.
+
+* Granularity attribute for <sync> task was undocumented.
+ Bugzilla report 34871.
+
+* <unzip> and <untar> could leave file handles open on invalid
+ archives. Bugzilla report 34893.
+
+* propertyset threw NPE with nested, mapped propertysets.
+
+Other changes:
+--------------
+
+* AntXMLContext.setCurrentTargets() is now public. Bugzilla report 34680.
+
+Changes from Ant 1.6.2 to Ant 1.6.3
+===================================
+
+Changes that could break older environments:
+--------------------------------------------
+
+* The subant task used the canonical version of a file path. This
+ has been changed to use the absolute path. Bugzilla 30438.
+
+* Tar now writes two EOF blocks rather than one.
+ Bugzilla report 28776
+
+* The Reference object now has a project field which it uses in preference
+ to the project passed in. This allows composite references to be
+ handled to nested projects.
+ Bugzilla report 25777
+
+* <junit> with filtertrace="true" will now also swallow lines for the
+ sun.reflect package. If you need to see them in your stack trace,
+ you must set filtertrace to false.
+ Bugzilla Report 22758
+
+* The jikes compiler adapter now supports -bootclasspath, -extdirs and
+ -sourcepath and also uses the same logic for debug flags as javac.
+ This means, the jikes compiler adapter now requires Jikes 1.15 or later.
+ Bugzilla Reports 25868, 26404 and 32609.
+
+* The gcj compiler adapter used to include the Java runtime classes
+ even if includeJavaRuntime was set to false, unless the
+ bootclasspath has been specified as well. It will now always adhere
+ to includeJavaRuntime, you may need to set it to true explicitly now
+ if you relied on the old behavior.
+
+Other changes:
+--------------
+
+* <javadoc> can now take an attribute 'executable'. Bugzilla report 30606.
+
+* New attribute ignorecontents for <different> selector
+
+* Javadoc fixes for Location, Project, and RuntimeConfigurable
+ Bugzilla 30160.
+
+* Enable to choose the regexp implementation without system property.
+ Bugzilla Report 15390.
+
+* Expose objects and methods in IntrospectionHelper. Bugzilla Report 30794.
+
+* Allow file attribute of <move> to rename a directory.
+ Bugzilla Report 22863.
+
+* Add xmlcatalog nested element to XmlProperty. Bugzilla report 27053.
+
+* New attribute alwayslog for <redirector> type.
+
+* Added <target> nested elements to <ant> and <antcall> to allow
+ specification of multiple sub-build targets, which are executed
+ with a single dependency analysis.
+
+* Refactored Target invocation into org.apache.tools.ant.Executor
+ implementations. Bugzilla Reports 21421, 29248.
+
+* <rmic> now also supports Kaffe's rmic version shipping with Kaffe
+ 1.1.2 and above.
+
+* added casesensitive attribute to <globmapper> and <regexpmapper>
+ Bugzilla report 16686
+
+* added handledirsep attribute to <globmapper> and <regexpmapper>
+ Bugzilla report 32487
+
+* added a new mapper <filtermapper>
+
+* When a BuildListener tried to access System.err or System.out, Ant
+ would have thrown an exception - this has been changed. Ant now
+ silently ignores the message. BuildListeners still should avoid
+ accessing either stream.
+
+* Added a comment attribute to the zip task.
+ Bugzilla report 22793.
+
+* Overloaded FileUtils.createNewFile with a boolean mkdirs attribute
+ to create nonexistent parent directories.
+
+* <apply> has a new "force" attribute that, when true, disables
+ checking of target files.
+
+* Made the dest attribute of the apply task optional; mapped target
+ filenames will be interpreted as absolute pathnames when dest is omitted.
+
+* Changed default tempdir for <javac> from user.dir to java.io.tmpdir.
+
+* Added searchpath attribute to <exec> for searching path variable(s)
+ when resolveexecutable = true.
+
+* Added revision and userid attributes to <pvcs> documentation.
+
+* Added support to the touch task for a mkdirs attribute to create
+ nonexistent parent directories before touching new files.
+
+* Added support to the touch task for a pattern attribute to allow
+ alternate datetime formats.
+
+* Added support to the touch task to map touched files using a nested
+ mapper element.
+
+* Added support to the touch task for a verbose attribute to suppress
+ logging of new file creation.
+
+* bad link in docs to the enhancement page in bugzilla.
+ Bugzilla report 33252.
+
+* Added length task to get strings' and files' lengths.
+
+* <native2ascii> and <javah> now also support Kaffe's versions.
+
+* Recursive token expansion in a filterset can now be disabled by
+ setting its recurse attribute to false.
+
+* Pathconvert no longer requires that one of (targetos|pathsep|dirsep)
+ be set; platform defaults are used when this is the case.
+
+* Added preservelastmodified attribute to fixcrlf task. Bugzilla 25770.
+
+* Added isfileselected condition.
+
+* Added verbose="true|false" attribute to <subant>. When verbose is enabled,
+ the directory name is logged on entry and exit of the sub-build.
+ Bugzilla 33787.
+
+* Added -nouserlib option to allow running ant without automatically loading
+ up ${user.home}/.lib/ant. This is useful when compiling ant, and antlibs.
+ Modified the build.sh and build.bat to use the option.
+
+* Added -noclasspath option to allow running ant WITHOUT using CLASSPATH env
+ variable. Modified ant.bat to do this so that %CLASSPATH% is not looked at.
+
+* Add else attribute to the condition task, which specifies an
+ optional alternate value to set the property to if the nested
+ condition evaluates to false. Bugzilla report 33074.
+
+* Ant generated jar files should now be detected as jar files by
+ Solaris. Bugzilla Report 32649.
+
+* <rexec> with a single command should now work with unusal login
+ dialogs without special read/write pairs. Bugzilla Report 26632.
+
+* <csc>'s extraoptions can now contain multiple arguments.
+ Bugzilla Report 23599.
+
+* <macrodef> with default values set by properties would be
+ seen as new definitions when called twice with different properties.
+ This was confusing so the definitions are now treated as similar.
+ Bugzilla Report 31215.
+
+* <javadoc> has a new attribute "includenosourcepackages" that can be
+ used to document packages that don't hold source files but a
+ package.html file. Bugzilla Report 25339.
+
+* <rpm> has new attributes failonerror and quiet.
+
+* Added two tutorials
+ - beginner: introduction into Ant
+ - task developers: using path, fileset etc
+
+* a number of new attributes that allow the user to handle non-standard
+ server listing formats and time zone differences have been added in
+ the <ftp> task.
+
+
+Fixed bugs:
+-----------
+
+* Do not pass on ThreadDeath when halting <java fork="false">. Bugzilla
+ 32941.
+
+* Killing a thread running <java fork="true"> (e.g. from an IDE) would
+ not stop the forked process. Bugzilla 31928.
+
+* Programs run with <java fork="true"> can now accept standard input
+ from the Ant console. (Programs run with <java fork="false"> could
+ already do so.) Bugzilla 24918.
+
+* AbstractCvsTask prematurely closed its outputStream and errorStream.
+ Bugzilla 30097.
+
+* Impossible to use implicit classpath for <taskdef>
+ when Ant core loader != Java application loader and
+ Path.systemClassPath taken from ${java.class.path} Bugzilla 30161.
+
+* MacroInstance did not clean up nested elements correctly in the execute
+ method, causing multiple use of the same macro instance with nested
+ elements to fail.
+
+* checksum fileext property doc wrong. Bugzilla 30787.
+
+* FTP task, getTimeDiff method was returning wrong value. Bugzilla 30595.
+
+* make sure that Zip and its derivatives call the createEmptyZip method when
+ there are no resources to zip/jar/...
+
+* Zip task was not zipping when only empty directories were found.
+ Bugzilla 30365.
+
+* Jar task was not including manifest files when duplicate="preserve" was
+ chosen. Bugzilla 32802.
+
+* ant.bat was missing runAntNoClasspath label for goto.
+ Bugzilla 34510.
+
+* Classpath was treated in the same way as -lib options. Bugzilla 28046.
+
+* Manual page for cvsversion contained incorrect attributes and did not
+ say since 1.6.1. Bugzilla 31408.
+
+* Typo in definition of <cvsversion> task causing it not to be defined.
+ Bugzilla 31403.
+
+* Execution of top level tasks in imported files get delayed by targets.
+ Bugzilla report 31487.
+
+* ExecTask executes checkConfiguration() even though os does not match.
+ Bugzilla report 31805.
+
+* Concat task instance could not be run twice.
+ Bugzilla report 31814.
+
+* NPE using XmlLogger and antlib.
+ Bugzilla report 31840.
+
+* Properties.propertyNames() should be used instead of .keys().
+ Bugzilla report 27261.
+
+* Target location is not set for default target.
+ Bugzilla report 32267.
+
+* Incorrect classloader parent in junittask when using with
+ ant-junit.jar and junit.jar not in the project classloader. Bugzilla
+ report 28474.
+
+* getResources() on the classloader returned by ClasspathUtils would
+ see each resource twice - if the resource is in the project
+ classpath and if the classloader is requested with a null path.
+
+* XMLValidate used URL#getFile rather than the ant method FileUtils#fromURI
+ Bugzilla report 32508
+
+* fixed Regexp-Mapper docs which gave outdated instructions (optional.jar)
+ Bugzilla report 28584
+
+* <scp> using <fileset> didn't work with OpenSSH 3.9 and later.
+ Bugzilla report 31939
+
+* <setproxy> failed to set user/password on some JDKs.
+ Bugzilla report 32667
+
+* untar would go into infinite loop for some invalid tar files.
+ Bugzilla report 29877
+
+* forked <javac> won't pass -source to a JDK 1.1 or 1.2 javac anymore.
+ Bugzilla report 32948
+
+* propertyset references did not handle nested propertyset references.
+
+* oata.types.Description.getDescription(Project) would throw a
+ NullPointerException when the "ant.targets" reference was unset.
+
+* Wrapper scripts did not detect WINNT value of dynamic OS environment
+ variable when logged into workstations using Novell authentication.
+ Bugzilla Report 30366.
+
+* DependScanner.getResource() always returned nonexistent resources,
+ even when the resource actually existed. Bugzilla Report 30558.
+
+* <apply> was broken with classfilesets. Bugzilla Report 30567.
+
+* <available> returned false positives when checking a file
+ passed in with the current basedir leading twice:
+ e.g. ${basedir}${file.separator}${basedir}${file.separator}foo .
+
+* The first file open that took place when using input files with the
+ <exec>, <apply>, or <java> tasks was always logged to System.out
+ instead of to the managing Task.
+
+* <telnet> and <rexec> would try to disconnect from servers they never
+ connetced to, potentially leading to exceptions in commons-net.
+ Bugzilla Report 33618.
+
+* <zip> would drop files matched by defaultexcludes during updates.
+ Bugzilla Report 33412.
+
+* <zip> couldn't store files with size between 2GB and 4GB (the
+ upper limit set by the ZIP format itself). Bugzilla Report 33310.
+
+* NPE when when <presetdef> tries to configure a task that
+ cannot be instantiated. Bugzilla Report 33689.
+
+* <javac debug="false"> created an invalid command line when running
+ the Symantec Java compiler.
+
+* Get with usetimestamp did not work on Java 1.2.
+
+* Get with usetimestamp did not work when local timestamp roughly >= now.
+
+* The framed JUnit report now handles multiple reports for the same
+ testcase properly. Bugzilla Report 32745.
+
+* <cab> didn't work for files with spaces in their names on Windows.
+ Bugzilla Report 17182.
+
+* The VAJ tasks could fail if the project name contained characters
+ that need to get URL encoded. Bugzilla Report 23322.
+
+* TarInputStream#read() wasn't implemented correctly. Bugzilla Report
+ 34097.
+
+* <xslt> failed to process file-hierarchies of more than one level if
+ scanincludeddirectories was true. Bugzilla Report 24866.
+
+* forkmode="perBatch" or "once" would ignore extension attributes that
+ had been specified for <formatter>s. Bugzilla Report 32973.
+
+* The refid attribute of the I/O redirector was not functional.
+
+Changes from Ant 1.6.1 to Ant 1.6.2
+===================================
+
+Changes that could break older environments:
+--------------------------------------------
+
+* The import task used the canonical version of a file path. This
+ has been changed to use the absolute path. Bugzilla 28505.
+
+* ant-xalan2.jar has been removed since the only class contained in it
+ didn't depend on Xalan-J 2 at all. Its sole dependency has always
+ been TraX and so it has been merged into ant-trax.jar.
+
+* All exceptions thrown by tasks are now wrapped in a buildexception
+ giving the location in the buildfile of the task.
+
+* Nested elements for namespaced tasks and types may belong to the
+ Ant default namespace as well as the task's or type's namespace.
+
+* <junitreport> will very likely no longer work with Xalan-J 1.
+
+ Note that Xalan-J 1 has been deprecated for a very long time and we
+ highly recommend that you upgrade.
+
+ If you really need to continue using Xalan-J 1, please copy the
+ junit-frames-xalan1.xsl from the distribution's etc directory as
+ junit-frames.xsl into a new directory and use the task's styledir
+ attribute to point to. This is the last version of the XSLT
+ stylesheet that is expected to be compatible with Xalan-J 1.
+
+Fixed bugs:
+-----------
+
+* eliminate memory leak in AntClassLoader. Bugzilla Report 8689.
+
+* subant haltonfailure=false did not catch all failures. Bugzilla Report 27007.
+
+* macrodef @@ escaping was broken. Bugzilla Report 27069.
+
+* MacroDef did not allow attributes named 'description'. Bugzilla Report 27175.
+
+* Throw build exception if name attribute missing from patternset#NameEntry.
+ Bugzilla Report 25982.
+
+* Throw build exception if target repeated in build file, but allow targets
+ to be repeated in imported files.
+
+* <apply> didn't compare timestamps of source and targetfiles when
+ using a nested <filelist>. Bugzilla Report 26985.
+
+* tagdiff.xml was broken in ant 1.6.1. Bugzilla Report 27057.
+
+* if the basedir contained .. or . dirs, and the build file name contained
+ .. or ., the basedir was set incorrectly. Bugzilla Report 26765.
+
+* regression from ant 1.5, exec task outputted two redundant trailing newlines.
+ Bugzilla Report 27546.
+
+* NPE when running commons listener. Bugzilla Report 27373.
+
+* <java> swallowed the stack trace of exceptions thrown by the
+ executed program if run in the same VM.
+
+* -projecthelp swallowed (configuration) errors silently.
+ Bugzilla report 27732.
+
+* filterset used by filtertask doesn't respect loglevel. Bugzilla Report 27568.
+
+* wrong compare used in ProjectComponent for logging. Bugzilla Report 28070.
+
+* failOnAny attribute for <parallel> was broken. Bugzilla Report 28122.
+
+* If <javac> uses gcj and any of the nested <compilerarg>s implies
+ compilation to native code (like -o or --main), Ant will not pass
+ the -C switch to gcj. This means you can now compile to native code
+ with gcj which has been impossible in Ant < 1.6.2.
+
+* <import optional="false"> and <import optional="true">
+ behaved identically.
+
+* <xslt> now sets the context classloader if you've specified a nested
+ <classpath>. Bugzilla Report 24802.
+
+* <zip> and friends would delete the original file when trying to update
+ a read-only archive. Bugzilla Report 28419.
+
+* <junit> and <assertions> are working together. Bugzilla report 27218
+
+* AntClassLoader#getResource could return invalid URLs. Bugzilla
+ Report 28060.
+
+* Ant failed to locate tools.jar if the jre directory name wasn't all
+ lowercase. Bugzilla Report 25798.
+
+* Redirector exhibited inconsistent behavior with regard to split
+ output. When sent to file only, files would be created in all
+ cases; when split file-property, files were only created if
+ writes were performed.
+
+* fixed case handling of scriptdef attributes and elements.
+
+* UNC pathnames did not work for ANT_HOME or -lib locations on Windows.
+ Bugzilla report 27922.
+
+* replacestring tokenfilter only replaced the first occurrence.
+
+* AntLikeTasksAtTopLevelTest failed on cygwin.
+
+* I/O-intensive processes hung when executed via <exec spawn="true">.
+ Bugzilla reports 23893/26852.
+
+* JDependTask did not close an output file. Bugzilla Report 28557.
+
+* Using <macrodef> could break XmlLogger. Bugzilla Report 28993.
+
+* <genkey> no longer requires keytool to be in your PATH. Bugzilla
+ Report 29382.
+
+* <symlink> could create cyclic links. Bugzilla Report 25181.
+
+* <zip whenempty="skip"> didn't work in a common situation. Bugzilla
+ Report 22865.
+
+* <scp> now properly handles remote files and directories with spaces
+ in their names. Bugzilla Report 26097.
+
+* <scp> now has (local|remote)tofile attributes to rename files on the
+ fly. Bugzilla Report 26758.
+
+* <telnet> and <rexec> didn't close the session. Bugzilla Report 25935.
+
+* <subant> and XmlLogger didn't play nicley together.
+
+Other changes:
+--------------
+* doc fix concerning the dependencies of the ftp task
+ Bugzilla Report 29334.
+
+* <xmlvalidate> has now a property nested element,
+ allowing to set string properties for the parser
+ Bugzilla Report 23395.
+
+* Docs fixes for xmlvalidate.html, javadoc.html, starteam.
+ Bugzilla Reports 27092, 27284, 27554.
+
+* <pathconvert> now accepts nested <mapper>s. Bugzilla Report 26364.
+
+* Shipped XML parser is now Xerces-J 2.6.2.
+
+* Added nested file element to filelist.
+
+* spelling fixes, occurred. Bugzilla Report 27282.
+
+* add uid and gid to tarfileset. Bugzilla Report 19120.
+
+* <scp> has a verbose attribute to get some feedback during the
+ transfer and new [local|remote][File|Todir] alternatives to file and
+ todir that explicitly state the direction of the transfer.
+
+* The OS/2 wrapper scripts have been adapted to use the new launcher.
+ Bugzilla Report 28226.
+
+* <sshexec> now also captures stderr output. Bugzilla Report 28349.
+
+* <xslt> now supports a nested <mapper>. Bugzilla Report 11249.
+
+* <touch> has filelist support.
+
+* <nice> task lets you set the priority of the current thread; non-forking
+ <java> code will inherit this priority in their main thread.
+
+* New attribute "negate" on <propertyset> to invert selection criteria.
+
+* Target now supports a Location member. Bugzilla Report 28599.
+
+* New "pattern" attribute for <date> selector.
+
+* <junit> has a new forkmode attribute that controls the number of
+ Java VMs that get created when forking tests. This allows you to
+ run all tests in a single forked JVM reducing the overhead of VM
+ creation a lot. Bugzilla Report 24697.
+
+* <jar> can now optionally create an index for jars different than the
+ one it currently builds as well. See the new <indexjars> element
+ for details. Bugzilla Report 14255.
+
+* Permit building under JDK 1.5. Bugzilla Report 28996.
+
+* minor Javadoc changes. Bugzilla Report 28998.
+
+* Misc. corrections in SignJar.java. Bugzilla Report 28999.
+
+* Remove redundant <hr> from javah.html. Bugzilla Report 28995.
+
+* Ignore built distributions. Bugzilla Report 28997.
+
+* A new roundup attribute on <zip> and related task can be used to
+ control whether the file modification times inside the archive will
+ be rounded up or down (since zips only store modification times with
+ a granularity of two seconds). The default remains to round up.
+ Bugzilla Report 17934.
+
+* A binary option has been added to <concat>. Bugzilla Report 26312.
+
+* Added DynamicConfiguratorNS, an namespace aware version of
+ DynamicConfigurator. Bugzilla Report 28436.
+
+* Add implicit nested element to <macrodef>. Bugzilla Report 25633.
+
+* Add deleteonexit attribute to <delete>.
+
+* Added Target.getIf/Unless(). Bugzilla Report 29320.
+
+* <fail> has a status attribute that can be used to pass an exit
+ status back to the command line.
+
+* <fail> accepts a nested <condition>.
+
+* <loadproperties> supports loading from a resource.
+ Bugzilla Report 28340.
+
+* Nested file mappers and a container mapper implementation have been
+ introduced. Additionally, the <mapper> element now accepts "defined"
+ nested FileNameMapper implementations directly, allowing a usage
+ comparable to those of <condition>, <filter>, and <selector>.
+
+* New <redirector> type introduced to provide extreme I/O flexibility.
+ Initial support for <exec>, <apply>, and <java> tasks.
+
+* <apply> has a new ignoremissing attribute (default true for BC)
+ which will allow nonexistent files specified via <filelist>s to
+ be passed to the executable. Bugzilla Report 29585.
+
+* <junitreport> now also works with Xalan XSLTC and/or JDK 1.5.
+ Bugzilla Report 27541.
+
+* <jspc> doesn't work properly with Tomcat 5.x. We've implemented a
+ work-around but don't intend to support future changes in Tomcat
+ 5.x. Please use the jspc task that ships with Tomcat instead of
+ Ant's.
+
+Changes from Ant 1.6.0 to Ant 1.6.1
+=============================================
+
+Changes that could break older environments:
+--------------------------------------------
+
+* License is now Apache License 2.0
+ see http://www.apache.org/licenses/ for more information
+
+Fixed bugs:
+-----------
+* Remove a recursive template call in the junit xsls that could trigger a stack
+ overflow. It now uses Xalan extensions to call a Java class directly.
+ Bugzilla Report 19301
+
+* Fix spurious infinite loop detection for filters (introduced in ant 1.6.0).
+ Bugzilla Report 23154.
+
+* Fix handling of default ant namespace for nested elements.
+
+* Fix jboss element of ejb task (introduced in ant 1.6.0).
+
+* <whichresource> failed to load classes correctly.
+
+* Ant could fail to start with a NullPointerException if
+ ANT_HOME/lib/ant-launcher.jar was part of the system CLASSPATH.
+
+* presetdef'ed types did not work with the ant-type attribute
+
+* fixed case handling of macrodef attributes and elements. Bugzilla
+ Reports 25687 and 26225.
+
+* <java> ignored the append attribute, Bugzilla Report 26137.
+
+* The gcj compiler adapter for <javac> failed if the destination
+ directory didn't exist. Bugzilla Report 25856.
+
+* Ant now fails with a more useful message if a new process will be
+ forked in a directory and that directory doesn't exist.
+
+* <splash> used to break the build on non-GUI environments. Bugzilla
+ report 11482.
+
+* Ant 1.6.0 cannot run build scripts in directories with non-ASCII names.
+ Bugzilla Report 26642.
+
+Other changes:
+--------------
+* Shipped XML parser is now Xerces-J 2.6.1
+
+* Translate task logs a debug message specifying the number of files
+ that it processed. Bugzilla Report 13938.
+
+* <fixcrlf> has a new attribute - fixlast. Bugzilla Report 23262.
+
+* <p4submit> has 2 new attributes, needsresolveproperty and changeproperty.
+ Bugzilla Report 25711.
+
+* add description attributes to macrodef attributes and elements.
+ Bugzilla Report 24711.
+
+* Extending ClearCase Tasks :
+ - Added an extra option to 'failonerr' to each ClearCase task/command.
+ - Extended the functionality of cccheckout. It can check (notco) to see if
+ the desired element is already checked out to the current view. Thus it
+ won't attempt to check it out again.
+ - Added three new ClearCase commands: ccmkattr, ccmkdir, ccmkelem
+ Bugzilla Report 26253.
+
+* added nested text support to <macrodef>
+
+* added initial support for Java 1.5. Java 1.5 is now correctly
+ detected by Ant and treated just like Java 1.4. You can now specify
+ source="1.5" in the <javac> task.
+
+* created new task <cvsversion>
+
+* added support for branch logging via the tag attribute in <cvschangelog>
+ Bugzilla Report 13510.
+
+* added support the groovy language in the script and scriptdef tasks
+
+Changes from Ant 1.5.4 to Ant 1.6.0
+===================================
+
+Changes that could break older environments:
+--------------------------------------------
+
+* This version of Ant can not be built with JDK 1.1 and requires at
+ least Java 1.2 at runtime as well. Compiling for a 1.1 target is
+ still supported.
+
+* Targets cannot have the empty string as their name any longer.
+
+* ant.jar's manifest does no longer include a Class-Path entry, so it
+ is no longer possible to run Ant via "java -jar ant.jar" without
+ manually altering the CLASSPATH. Instead of that a file
+ ant-bootstrap.jar is included in the etc directory of the binary
+ distribution, copy this to the lib directory and use
+ "java -jar ant-bootstrap.jar" instead if you want to run Ant without
+ the wrapper script (not recommended).
+
+* The <script> task now requires Apache BSF instead of the older IBM
+ version. See <http://jakarta.apache.org/bsf/>
+
+* <xmlproperty> will no longer fail if the file to be loaded doesn't exist.
+
+* XML namespaces are now enabled in the XML parser, meaning XML namespace
+ declarations no longer cause errors. However task names containing colons
+ will cause errors unless there is a corresponding namespace uri.
+
+* The <ftp> and <telnet> tasks now require Jakarta Commons Net instead
+ of the older ORO Netcomponents version. See
+ <http://jakarta.apache.org/commons/net/index.html>.
+
+* <input> will no longer prompt the user and wait for input if the
+ addproperty attribute is set to a property that has already been
+ defined in the project. If you rely on the task waiting for input,
+ don't use the addproperty attribute.
+
+* The Class-Path attribute in manifests will no longer merge the
+ entries of all manifests found, but will be treated like all other
+ manifest attributes - the most recent attribute(s) will be used.
+
+* New Launch mechanism implemented. This moves some functionality from
+ the batch files / shell scripts into Java. This removes environment
+ limitations, for command issues, directory depth issues on Windows. Also
+ allows a per-user library location to be used if the main Ant install
+ is locked down.
+
+* The Entry nested element of PropertyFile will not any more have its value
+ attribute (actually increment) overwritten with the new value of the entry
+ after execution.
+
+* Output stored from a <java> or <exec> task is now exactly as generated. No
+ conversion to platform end-of-line characters is performed.
+
+* <translate> will now preserve line endings.
+
+* <ftp> followsymlinks="false" in nested fileset definitions is explicitly
+ required in order to exclude remote symbolic links (when doing a get, chmod,
+ delete, rmdir).
+
+* The values of the Copy#fileCopyMap variable has changed from String to
+ String[]. (In java 1.5 terms it was Hashtable<String, String> and
+ is now Hashtable<String, String[]>). This will affect third party code
+ that extend Copy and override Copy#doFileOperations.
+
+* <loadproperties> didn't expand properties while <property file="..."/>
+ does, so they were not equivalent. This has been fixed, which means
+ that propetries may get expanded twice if you use an
+ <expandproperties> filterreader. Bugzilla Report 17782.
+
+* User defined tasks and typedefs are now handled internally in the
+ same way as predefined tasks and typedefs. Also tasks and typedefs
+ are resolved at a later stage. This causes some
+ differences especially for user defined task containers.
+
+* <checksum> log message "Calculating checksum ..." has been degraded
+ from INFO to VERBOSE.
+
+Fixed bugs:
+-----------
+* Filter readers were not handling line endings properly. Bugzilla
+ Report 18476.
+
+* Filtersets were also not handling line endings properly.
+
+* Expand tasks did not behave as expected with PatternSets.
+
+* <property environment=... /> now works on OS/400.
+
+* <cab> could hang listcab on large <fileset>s.
+
+* The starteam stcheckout, stcheckin tasks now correctly compute
+ status of files against whatever local tree they are run against
+ and, optionally, will not process a file if it is current.
+ Previously you had to process everything unless you ran against the
+ default folder which wasn't the normal use-case for ant-starteam.
+ The stlist task now similarly displays that status correctly making
+ it a more generally useful tool.
+
+* entity includes would cause exceptions if path names included spaces.
+
+* addConfiguredXXX would not work for TaskAdapter wrapped tasks
+
+* Fix <ilasm> outputfile testing so that the output file does not need
+ to exist beforehand.
+
+* Ant will now exit with a return code of 1 if it encounters problems
+ with the command line arguments.
+
+* ClassLoader creation changes to use a factory method in Project. A new
+ class AntClassLoader2 implemented for 1.2+ specific features including
+ Package information and addition of classes specified in the Class-Path
+ element of a Jar's manifest.
+
+* It is now possible in <exec> to resolve the executable to a project
+ basedir or execution dir relative executable. The resolveExecutable
+ must be used to pick up such executables.
+
+* splash screen wouldn't disappear when build was finished.
+
+* <exec> output and error streams can now be redirected independently
+ to either a property or a file (or both)
+
+* TarEntry's File-arg constructor would fail with a
+ StringIndexOutOfBoundsException on all OSes where os.name is shorter
+ than seven characters. Bugzilla Report 18105.
+
+* <copy> and <move>'s failonerror didn't apply to filesets pointing to
+ non-existent directories. Bugzilla Report 18414.
+
+* The <stripjavacomments> filter sometimes removed parts of string
+ constants. Bugzilla Report 17441.
+
+* <antlr> will now recompile your grammar if the supergrammar has
+ changed. Bugzilla Report 12691.
+
+* <property env> will now work on Unices with /bin/env instead of
+ /usr/bin/env. Bugzilla Report 17642.
+
+* <jar index="on"> could include multiple index lists. Bugzilla 10262.
+
+* The index created by <jar> didn't conform to the spec as it didn't
+ include the top-level entries. Bugzilla Report 16972.
+
+* <tar> and <zip> didn't honor the defaultexcludes attribute for the
+ implicit fileset. Bugzilla Report 18637.
+
+* The <replacetokens> filter would throw an exception if the token's
+ value was an empty string. Bugzilla Report 18625.
+
+* Perforce tasks relying on output from the server such as <p4change>
+ and <p4label> were hanging. Bugzilla Reports 18129 and 18956.
+
+* Improve exception and logging behavior of Perforce tasks.
+ Bugzilla report 18154.
+
+* build.sh install had a problem on cygwin (with REALANTHOME).
+ Bugzilla Report 17257
+
+* <replaceregexp> didn't work for multi-byte encodings if byline was false.
+ Bugzilla Report 19187.
+
+* <replaceregexp> was altering unnecessarily the timestamp of the directories
+ containing the files to process
+ Bugzilla Report 22541.
+
+* file names that include spaces need to be quoted inside the @argfile
+ argument using forked <javac> and (all JDKS). Bugzilla Report 10499.
+ NB : a first correction was only introducing quotes for JDK 1.4
+ It has been changed to quote for all external compilers when paths
+ contain spaces.
+ Also the backslashes need to be converted to forward slashes
+ Bugzilla Report 17683.
+
+* Setting filesonly to true in <zip> and related tasks would cause the
+ archives to be always recreated. Bugzilla Report 19449.
+
+* file names that include spaces need to be quoted inside the @argfile
+ argument using <javadoc> and JDK 1.4. Bugzilla Report 16871.
+
+* <junit> didn't work with custom formatters that were only available
+ on the user specified classpath when a timeout occurred. Bugzilla
+ Report 19953.
+
+* <different> selector : make ignoreFileTimes effectively default to true
+ and fix a bug in the comparison of timestamps. Bugzilla Report 20205.
+
+* <different> selector can now be nested directly under a fileset
+ Bugzilla Report 20220.
+
+* <cvstagdiff> had a problem with "dd-MM-yy hh:mm:ss" formats
+ Bugzilla Report 15995.
+
+* <cvstagdiff> cvsroot and package attributes added to the root
+ element tagdiff of the xml output
+ Bugzilla Report 16081.
+
+* <cvstagdiff> had a problem with aliased modules and with requests for
+ multiple modules. Bugzilla Reports 21373 and 22877.
+
+* <cvstagdiff> could not parse properly the revision number of new files with
+ CVS 1.11.9 or higher. Bugzilla Report 24406.
+
+* <fixcrlf> make fixcrlf create its temporary files in the default directory
+ of FileUtils#createTempFile instead of the destination dir of fixcrlf.
+ Bugzilla Report 20870.
+
+* <ejbjar> implementation for Borland.
+ Prevent the task from being blocked by error messages coming from java2iiop.
+ Bugzilla Report 19385.
+
+* <unzip>'s and <untar>'s nested patternsets didn't work as documented
+ when the pattern ended in a slash or backslash. Bugzilla Report 20969.
+
+* <fixcrlf> will now create the parent directories for the destination
+ files if necessary. Bugzilla Report 20840.
+
+* <xmlproperty> now handles CDATA sections. BugZilla Report 17195
+
+* <translate> now translate tokens that are placed close together.
+ Bugzilla Report 17297
+
+* Nested websphere element for ejbjar does not support spaces in file name.
+ Bugzilla Report 21298
+
+* Don't multiply Class-Path attributes when updating jars. Bugzilla
+ Report 21170.
+
+* Do not overwrite the value (increment) attribute of PropertyFile nested
+ Entry element. Bugzilla Report 21505.
+
+* Prevent sysproperties with no key or no value from being added in <junit>.
+ Bugzilla Report 21684.
+
+* Allow references to be properly inherited via antcall
+ Bugzilla Report 21724.
+
+* ftp chmod failed when the remote system was UNIX and local system Windows
+ Bugzilla Report 21865.
+
+* ftp put with chmod failed when the remote system was UNIX and local system
+ Windows. Bugzilla Report 23143.
+
+* ftp did not set the ascii mode explicitly, causing problems with ftp servers
+ having binary as default
+
+* ftp was not able to download files when they were pointed to by symbolic
+ links. Bugzilla Report 14063.
+
+* ftp is able to download also directories pointed to by symbolic links.
+
+* replace would change \r\n into \r\r\n under Windows.
+
+* junitreport with frames did not display a link for classes without a package
+ or in the top package.
+ Bugzilla Report 21915.
+
+* Project.toBoolean(String) now handles null as argument and does not throw a
+ NullPointerException any more.
+
+* The socket condition will now close the socket created to test.
+ Bugzilla Report 23040.
+
+* <junit includeantruntime="true" fork="true"> replaced the CLASSPATH instead
+ of adding to it. Bugzilla Report 14971.
+
+* <splash> could fail on JVMs that use null to indicate the system classloader.
+ Bugzilla Report 23320.
+
+* <xmlcatalog>s only worked when defined inside of tasks. Bugzilla
+ Report 20965.
+
+* <csc> and siblings (<vbc> <jsharpc>) handle large filesets by
+automatic use of response files. Bugzilla report #19630
+
+Other changes:
+--------------
+
+* Shipped XML parser is now Xerces 2.6.0
+
+* All tasks can be used outside of <target>s. Note that some tasks
+ will not work at all outside of targets as they would cause infinite
+ loops (<antcall> as well as <ant> and <subant> if they invoke the
+ current build file).
+
+* Six new Clearcase tasks added.
+
+* A new filter reader namely tokenfilter has been added. Bugzilla
+ Report 18312.
+
+* A new attribute named skip is added to the TailFilter and
+ HeadFilter filter readers.
+
+* The filesetmanifest attribute of <jar> has been reenabled.
+
+* The start and end tokens for <translate> may now be longer than a
+ single character.
+
+* <setproxy> lets you set the username and password for proxies that
+ want authentication
+
+* <loadproperties> has a new encoding attribute.
+
+* <echoproperties> can now create XML output.
+
+* <echoproperties> has a new srcfile attribute that can make it read
+ properties files and output them instead of Ant's properties.
+
+* <filterset> will now resolve filters recursively.
+
+* <input> has a new attribute that allows you to specify a default value.
+
+* Added <image> task (requires JAI).
+
+* <image> task has now proportions attribute in the <scale/> nested element
+ instead of keepproportions (bringing in more functionality)
+
+* New condition <isreference>
+
+* <ftp> now has a preservelastmodified attribute to preserve the
+ timestamp of a downloaded file.
+
+* new rmdir action for <ftp> that removes directories from a fileset.
+
+* <ftp> has attributes timediffauto and timediffmillis to use together
+ with the newer attribute to tell ant to take into account a time difference
+ between client and remote side.
+ Bugzilla Report 19358.
+
+* <ftp> has been optimized to go directly to the include patterns.
+ This reduces scanning time under UNIX when followsymlinks="true"
+ and casesensitive="true" (the default)
+ Bugzilla Report 20103.
+
+* The SOS and VSS tasks will no longer unconditionally prepend a $ to
+ vsspath or projectpath.
+
+* OS/400 now gets detected by the os condition.
+
+* <arg> has a new attribute pathref that can be used to reference
+ previously defined paths.
+
+* <xmlproperty> has been improved, you can now expand ${properties},
+ define ids or paths and use Ant's location magic for filename resolutions
+ in the XML file.
+
+* <xmlcatalog> will now support external catalogs according to the
+ OASIS "Open Catalog" standard - if resolver.jar (newer than version
+ 1.0) from Apache's xml-commons is in your CLASSPATH.
+
+* Starteam tasks now have support for revision labels and build labels.
+ Checkouts now have the option of using repository timestamps, instead
+ of current.
+
+* new task <symlink> that creates and maintains symbolic links.
+
+* new tasks <chown> and <chgrp> which are wrappers of the Unix commands.
+
+* new task <attrib> to change file attributes on Windows systems.
+
+* <style> has a new attribute reloadstylesheet to work around a
+ bug in widespread Xalan versions.
+
+* <tarfileset> has a new dirmode attribute to specify the permissions
+ for directories.
+
+* <fixcrlf>'s eol attribute now also understands "mac", "unix" and "dos".
+
+* <classfileset> now picks up dependencies of the form MyClass.class. This
+ works for the code generated by the Sun java compiler. It may not work for
+ all compilers.
+
+* a new attribute "globalopts" can be added to all Perforce tasks.
+ You can put in it all the strings described by p4 help usage. Refer to
+ the docs for more information.
+
+* new Perforce tasks <p4integrate> , <p4resolve>, and <p4labelsync>
+
+* <p4submit> will change the property p4.change if the Perforce server
+ renumbers the change list.
+ It will set the property p4.needsresolve if the submit fails,
+ and the message says that file(s) need to be resolved.
+
+* <replaceregexp> now has an optional encoding attribute to support
+ replacing in files that are in a different encoding than the
+ platform's default.
+
+* The <exec> task may now have its input redirected from either a file
+ or a string from the build file. The error output can be separated
+ to a different file when outut is redirected. standard error may be
+ logged to the Ant log when redirecting output to a file
+
+* The <java> task also supports the input redirection and separate
+ error streams introduced to the <exec> task. In addition, it is now
+ possible to save the output into a property for use within the build
+ file as was possible with <exec> in Ant 1.5
+
+* The <javadoc> task <tag> subelement has been enhanced to allow files
+ with tag mappings to be used.
+
+* New tasks: <scp> supports file transfers, <sshexec> executes a
+ command over SSH. They require jsch, a BSD licensed SSH library that
+ can be found at http://www.jcraft.com/jsch/index.html
+
+* New filterreader <escapeunicode/>.
+
+* Support for HP's NonStop Kernel (Tandem) OS has been added.
+
+* <cab>'s basedir attribute is now optional if you specify nested
+ filesets. Bugzilla Report 18046.
+
+* New task <sync> that synchronizes two directory trees.
+
+* <apply> has new forwardslash attribute that can force filenames to
+ use forward slashes (/) as file separators even on platforms with a
+ different separator. This is useful if you want to run certain
+ ported Unix tools.
+
+* Copy has a new outputencoding attribute that can be used to change
+ the encoding while copying files. Bugzilla Report 18217.
+
+* The xml formatter for JUnit will now honor test case names set with
+ setName. Bugzilla Report 17040.
+
+* JUnit now has an attribute reloading, which, when set to false,
+ makes the task reuse the same class loader for a series of tests.
+
+* <concat> now supports filtering and can check timestamps before
+ overriding a file. Bugzilla Report 18166.
+
+* <junit> has a new attribute tempdir that controls the placement of
+ temporary files. Bugzilla Report 15454.
+
+* <jdepend> now supports a new nested element <classespath> which is
+ the same as <sourcespath> but point to compiled classes (the
+ preferred mode of operation for JDepend > 2.5). Additionally, nested
+ <exclude> elements can be used to exclude certain packages from
+ being parsed. Bugzilla Report 17134.
+
+* The JProbe tasks now also work with JProbe 4.x. Bugzilla Report 14849.
+
+* <javacc> and <jjtree> will now autodetect JavaCC 3.x and can use it.
+
+* <sql> has a new attribute to control escape processing.
+
+* <sql> is able to display properly several resultsets if you are
+ running a compound sql statement. Bugzilla Report 21594.
+
+* A new <containsregexp> selector has been added, that selects files
+ if their content matches a certain regular expression.
+
+* <antlr>'s debug attribute has been enabled. Bugzilla Report 19051.
+
+* <mail> has a new attribute charset. Bugzilla Report 15434.
+
+* <mail> has new attributes user and password for SMTP auth.
+ maillogger can also use this.
+ The implementation only works with JavaMail (encoding="MIME").
+ Implementation with plain mail remains to do.
+ Bugzilla Report 5969.
+
+* <mail> and mailloger support SMTP over TLS/SSL
+ Bugzilla Report 19180.
+
+* <mail> the attributes from, replyto ,tolist, cclist, bcclist
+ can now contain email addresses of the form name <address@xyz.com>
+ or (name) address@xyz.com
+ Bugzilla Report 22474.
+
+* <mail> (version PlainMail)
+ prevent blank headers from being sent,
+ make the order of the headers of plain mail messages predictable
+ Bugzilla Report 22088.
+
+* <zipfileset> can now be defined in the main body of a project
+ and referred to with refid="xyz". Bugzilla Report 17007.
+
+* A wrapper script for OS/2 has been added.
+
+* <unzip> will now detect and successfully extract self-extracting
+ archives. Bugzilla Report 16213.
+
+* <stcheckout> has a new attribute "converteol" that can be used to
+ control the automatic line-end conversion performed on ASCII files.
+ Bugzilla Report 18884.
+
+* Users can now modify the list of default excludes using the new
+ defaultexcludes task. Bugzilla Report 12700.
+
+* There is a new data type <propertyset> that can be used to collect
+ properties. It is supported by <ant>, <antcall>, <subant>, <java>,
+ <echoproperties> and <junit>.
+
+* <concat> can now control the encoding of the output as well and optionally
+ add new-line characters at the end of files that get concatenated but
+ don't end in newlines. Bugzilla Report 12511.
+
+* <rpm> will detect the rpmbuild executable of RedHat 8.0 and newer
+ and use that if it is on your PATH. Bugzilla Report 14650.
+
+* A new task <rexec> has been added that requires commons-net to work.
+ Bugzilla Report 19541.
+
+* <javadoc> now supports a nested <arg> element in addition to the
+ additionalparams attribute.
+
+* You can now determine the order of standard tags in <javadoc> via
+ <tag> elements - you must not use the description attribute for them.
+ Bugzilla Report 18912.
+
+* <javadoc> now supports the -noqualifier switch. Bugzilla Report 19288.
+
+* <javac>'s executable attribute can now also be used to specify the
+ executable for jikes, jvc, sj or gcj. Bugzilla Report 13814.
+
+* <javac> has a new attribute tempdir that can control the placement
+ of temporary files. Bugzilla Report 19765.
+
+* A new magic property build.compiler.jvc.extensions has been added
+ that can be used to turn of Microsoft extensions while using the jvc
+ compiler. Bugzilla Report 19826.
+
+* You can now limit the parallelism of <apply> and <chmod> by using the new
+ maxparallel attribute.
+
+* With the new addsourcefile attribute, you can make <apply> ommit the
+ source file names from the command line. Bugzilla Report 13654.
+
+* <apply> and <chmod> now support nested <filelist>s as well as <dirset>s.
+ Bugzilla Reports 15929 and 20687.
+
+* <apply> and <chmod> will display a summary if you set the new
+ verbose attribute to true. Bugzilla Report 19883.
+
+* <copy>/<move>'s failonerror attribute can now also be used to
+ continue the build if an I/O error caused a problem. Bugzilla
+ Report 12999.
+
+* new selector <type/> allowing to select only files or only directories.
+ Bugzilla Report 20222.
+
+* <java> and <junit> now support a nested <bootclasspath> element that
+ will be ignored if not forking a new VM.
+
+* <junit>'s nested <formatter> elements now support if/unless clauses.
+
+* <ejbjar>
+ cmpversion attribute added
+ jboss element will look for jbosscmp-jdbc.xml descriptor
+ if ejbjar has cmpversion="2.0" set
+ Bugzilla Reports 14707 and 14709.
+
+* <pvcs> config attribute added to set the location of a specific PVCS
+ .cfg file
+ Bugzilla Report 9752
+
+* <mapper> has an "unpackage" mapper
+ Bugzilla Report 18908
+
+* Added <scriptdef> task allowing tasks to be defined using any BSF-supported
+ scripting language.
+
+* <touch>'s datetime attribute can now accept time with a granularity
+ of seconds as well. Bugzilla Report 21014.
+
+* <checksum> has two new properties: totalproperty and todir.
+
+* FileUtils#createTempFile will now create temporary files in the
+ directory pointed to by the property java.io.tmpdir
+
+* <unzip> and friends now supports an optional encoding attribute to
+ enable it to expand archives created with filenames using an encoding
+ other than UTF8. Bugzilla Report 10504.
+
+* <patch> has a new attribute destfile that can be used to create a new
+ file instead of patching files in place.
+
+* OpenVMS is detected as a valid OS family.
+
+* DirectoryScanner has been optimized for cases where include patterns do not
+ start with wildcards. Bugzilla Report 20103.
+
+* DirectoryScanner begins to be optimized not to scan excluded directories.
+ Bugzilla Report 21941.
+
+* Added keep-going feature. Bugzilla Report 21144
+
+* The archives generated by <zip> and friends will now contain CRC and
+ size information in the "local file header", thereby providing this
+ information to applications that read the archives using
+ java.util.ZipInputStream. Bugzilla Report 19195.
+
+* <copy> and <move> can now handle mappers that return multiple
+ mappings per source path. This behaviour is enabled by using
+ an enablemultiplemapping attribute. Bugzilla Report 21320.
+
+* <exec> will now work on OpenVMS (please read the notes in
+ <exec>'s manual page). Bugzilla Report 21877.
+
+* <exec> will now have a new attribute spawn (default false).
+ If set to true, the process will be spawned. Bugzilla Report 5907.
+
+* <java> will now have a new attribute spawn (default false).
+ If set to true, the process will be spawned. Bugzilla Report 5907.
+
+* <parallel> now supports a timeout which can be used to recover
+ from deadlocks, etc in the parallel threads. <parallel> also
+ now supports a <daemons> nested element. This can be used to
+ run tasks in daemon threads which the parallel task will not
+ wait for before completing. A new attribute failonany will cause
+ <parallel> to throw an exception if any thread fails without
+ waiting for all other threads to complete.
+
+* <zip> and friends will consume far less memory than they used to
+ when run with compress="false". Bugzilla Report 21899.
+
+* <if/> and <unless/> attributes added to <param/> element of <style>
+ Bugzilla Report 22044
+
+* <zip> and friends have a new attribute "keepcompression" that can be
+ used to incrementally build an archive mixing compressed and uncompressed
+ entries.
+
+* <junit>'s XML formatter adds a new classname attribute to the <testcase>
+ elements.
+
+* new <permissions> type add permission handling to the code
+ this type can be nested in the <java> and <junit> tasks.
+ Bugzilla Report 22533.
+
+* additional shortcuts for ant options (-d --> -debug, -e --> -emacs,
+ -h --> -help, -p --> -projecthelp, -s --> -find).
+
+* new selector <modified>. "cache" was renamed to "modified".
+ Bugzilla Report 20474.
+
+* <stcheckout> and <stlist> have a new asofdate attribute that can be
+ used to checkout/list files based on a date instead of a label.
+ Bugzilla Report 20578.
+
+* New filter <concatfilter>. Adds the content of file at the beginning
+ or end of a file. Discussion started at
+ http://marc.theaimsgroup.com/?l=ant-user&m=106366791228585&w=2
+
+* New task <import>
+
+* New task <macrodef>
+
+* New task <presetdef>
+
+* Ant libraries that can make use of namespaces to avoid name
+ clashes of custom tasks
+
+* <java> and <junit> now support <assertions>, which let you enable
+ and disable Java1.4 assertions on a package or class basis. These
+ only work when fork=true, currently.
+
+* .NET tasks expanded with VB support <vbc> and J#, via <jsharp>,
+ <importtypelib> and <ilasm>. <csc> supports nested <src> types,
+ <defines> for (potentially conditional) definitions, <reference>
+ filesets for references. The executable attribute lets you switch to
+ mono or other implementations -<csc> has been tested with Mono on
+ Linux and OSX.
+
+
+Changes from Ant 1.5.3 to Ant 1.5.4
+===================================
+
+Changes that could break older environments:
+--------------------------------------------
+
+* If the Visual Age tasks used to work for you, they may stop doing so
+ now - and we'd like to know about it. The current set of tasks is
+ supposed to work with any version of VAJ starting with 3.0.
+
+Fixed bugs:
+-----------
+
+* The Visual Age for Java tasks didn't work (at least for versions 3.0
+ and higher). Bugzilla Report 10016.
+
+* URL-encoding in <vaj*port> didn't work properly.
+
+* VAJRemoteUtil called getAbsolutePath instead of getPath
+ causing problems when using a Windows VAJ server from a UNIX server.
+ Bugzilla Report 20457.
+
+* VAJImport task failed with NullPointerException when using DirectoryScanner.
+ Bugzilla Report 22080.
+
+Other changes:
+--------------
+
+* Shipped XML parser is now Xerces 2.5.0
+
+* <javah> will invoke oldjavah on JDK 1.4.2. Bugzilla Report 18667.
+
+* The VAJ tasks now support a haltonfailure attribute to conditionally
+ keep building even if they fail.
+
+* It is now possible to use the latest (versioned or unversioned) edition
+ in <vajload> by using special wildcard characters. Also fixes
+ Bugzilla Report 2236.
+
+Changes from Ant 1.5.2 to Ant 1.5.3
+===================================
+
+Changes that could break older environments:
+--------------------------------------------
+
+* The <zip> task and friends have again changed a method signature
+ (sorry, was necessary to fix bug 17780). The return type of
+ getResourcesToAdd has changed.
+
+Fixed bugs:
+-----------
+
+* <zipfileset>'s filemode would get ignored and the dirmode was used
+ for the included files as well. As a side effect, WinZIP was unable
+ to extract or display the files, so they seemed to be missing from
+ the archive. Bugzilla Report 17648.
+
+* <ftp> could use the wrong path separator when trying to change the
+ remote working directory. Bugzilla Report 17735.
+
+* <jar update="true"> would loose all original files if you didn't
+ specify any nested <(zip)fileset>s and the manifest had changed.
+ Bugzilla Report 17780.
+
+* If you used a value starting with \ on Windows for the appxml
+ attribute of <ear> or the webxml attribute of <war>, it would be
+ ignored. Bugzilla Report 17871.
+
+* Ant will no longer implicitly add Sun's rt.jar in <javac> when you
+ use jvc and don't specify a bootclasspath. Bugzilla Report 18055.
+
+* The prefix attribute of <zipfileset> would not generate directory
+ entries for the prefix itself. Bugzilla Report 18403.
+
+* starteam checkout can now handle deleted labels. Bugzilla Report 17646.
+
+* The Unix wrapper script failed if you invoked it as a relative
+ symlink and ANT_HOME has not been set. Bugzilla Report 17721.
+
+Other Changes:
+--------------
+* Added ability to specify manifest encoding for the <jar> and
+ <manifest> tasks
+
+Changes from Ant 1.5.1 to Ant 1.5.2
+=============================================
+
+Changes that could break older environments:
+--------------------------------------------
+* ANT_OPTS environment variable is now applied at the start of the
+ Java command line, allowing position specific parameters of some
+ JVMs, such as -classic to be specified.
+
+* ZipScanner#getIncludedFiles will now return the names of the ZipEntries
+ that have been matched instead of the name of the archive.
+
+* The <zip> task and friends have been heavily modified, almost every
+ method signature of the Zip class has changed. If you have subclassed
+ Zip (or one of its subclasses), your class will most likely not
+ compile against the current code base. If it still compiles, it will
+ probably not work as in Ant 1.5.1.
+
+Fixed bugs:
+-----------
+* <translate> was not ignoring comment lines.
+
+* <manifest> wouldn't update an existing manifest if only an attribute
+ of an existing section changed.
+
+* ant.bat now supports the ANT_ARGS and JAVACMD environment variables
+ again (like Ant 1.5 did).
+
+* The "plain" <junit> <formatter> could throw a NullPointerException
+ if an error occurred in setUp.
+
+* <junit> will now produce output when a test times out as well.
+
+* <replace> would count some internal character replacements when
+ reporting the number of replaced tokens.
+
+* <concat> would cause an exception if a <filelist> pointed to files
+ that do not exist.
+
+* <javadoc> will now pass -source to custom doclets as well.
+
+* <cvstagdiff> would throw a NullPointException if there had been no
+ differences.
+
+* <cvschangelog> could miss today's changes.
+
+* <concat> could append newline characters between concatenated files.
+
+* <xmlvalidate> ignored the specified encoding of the files to
+ validate.
+
+* the errorsbeginat attribute of the <http> condition didn't work.
+
+* Ant will try to force loading of certain packages like com.sun.*
+ from the system classloader. The packages are determined by the
+ version of the JVM running Ant.
+
+* Ant didn't find the runtime libraries on IBM's JDK 1.4 for Linux.
+
+* random component of temporary files is now always a positive integer.
+
+* Ant could incorrectly try to use the 1.4 regexp implementation even
+ if it isn't available if you run the JVM with -Xverify:none.
+
+* Ant would die with an exception if you used nested <reference>
+ elements in Ant and the refid attribute didn't point to an existing
+ project reference.
+
+* The <get> task can now be compiled (and Ant thus bootstrapped) using
+ Kaffee.
+
+* build.sysclasspath will now be honored by more tasks.
+
+* The signjar keystore attribute has been reverted to a String allowing
+ it to once again accept URLs. This should not affect current File based usage
+ unless you are extending the Signjar task.
+
+* <jar update="true"> would remove the original manifest.
+
+* fix up folder creation in PVCS task
+
+* <tar>'s up-to-date check didn't work for nested <(tar)fileset>s.
+
+* Corrected a problem in XMLLogger where it would not associated
+ messages with a taskdef'd task
+
+* <uptodate> now works when using attributes (i.e. not filesets) and pointing
+ to the same file
+
+* Java task (and output system) now stores output which doos not end
+ with a line feed.
+
+* splash screen wouldn't disappear when build was finished.
+
+* <exec> now supports OS/2.
+
+* <zip> and friends would only update/recreate existing archives if
+ the files to add/update have been newer than the archive.
+
+* <javadoc>'s <link> element could fail for offline="true" on some JDKs.
+
+Other changes:
+--------------
+
+* MailLogger now sets the Date header correctly.
+
+* Shipped XML parser is now Xerces 2.3.0
+
+* signjar now accepts a maxmemory attribute to allow the memory allocated to the
+ jarsigner tool to be specified. The jarsigner from the JDK's JAVA_HOME bin
+ dir is now used rather than the first jarsigner on the path.
+
+* **/.DS_Store has been added to the list of default pattern excludes.
+
+* The Created-By header in the default manifest now contains the JVM
+ vendor and version according to the jar specification. A new header,
+ Ant-Version provides the Ant version used to create the jar.
+
+* <zip> can now store Unix permissions in a way that can be
+ reconstructed by Info-Zip's unzip command.
+
+Changes from Ant 1.5.1Beta1 to 1.5.1
+====================================
+
+Fixed bugs:
+-----------
+
+* <tstamp>'s prefix attribute failed to apply to nested <format> elements.
+
+* <junitreport> created an empty junit-noframes.html if no format had
+ been specified.
+
+* <basename> would remove more than it should if the file name
+ contained more than one dot.
+
+* <filterset>s nested into <filterset>s didn't work.
+
+Other changes:
+--------------
+
+* Shipped XML parser is now Xerces 2.2.0
+
+* Filesets now support a 'file' attribute, allowing a single-file
+ fileset to be constructed without having to specify its parent
+ directory separately.
+
+* <junit> will now return the result of a call to getName instead of
+ "unknown" for Test implementations that don't extend TestCase but have
+ a public String getName() method.
+
+Changes from Ant 1.5 to 1.5.1Beta1
+==================================
+
+Fixed bugs:
+-----------
+* Date/time in CvsChangeLog was in local timezone and 12 hour format leading
+ to a problem when sorting by time. It is now UTC (GMT) and in 24-hour
+ format as per cvs 'specifications'.
+
+* CvsTagDiff now supports ampersand modules or modules that have a different
+ root directory than their name.
+
+* EjbJar threw NPEs for the Websphere element. The property 'websphere.home'
+ was not documented.
+
+* Mail example in the documentation was not correct.
+
+* Checksum was broken in the following scenario:
+ (using verifyproperty OR in a condition) AND using filesets
+ with multiple files.
+
+* The ExpandProperties filter threw NPEs when defined using
+ the <filterreader> format.
+
+* The sh wrapper script didn't work under Cygwin if ANT_HOME wasn't
+ set with a Unix style filename.
+
+* The sh wrapper script could fail if you started Ant from a directory
+ with whitespace in its name.
+
+* ant -diagnostics was not working properly when the task dependency
+ was missing and was just printing the missing dependency.
+
+* If a task got redefined via <taskdef>, it lost its child elements.
+
+* <property>'s classpathref attribute was broken.
+
+* <arg line="''" /> would result in no command line argument, will now
+ be a single empty argument. Use <arg value="''"/> if you need the
+ quotes literally.
+
+* <replaceregexp> could append a newline character at the end of the
+ file.
+
+Other changes:
+--------------
+
+* Appendix E of Java Development with Ant (Loughran/Hatcher) was
+ contributed to the docs.
+
+* <available> will only print deprecration warnings if it is actually
+ used to change the value of a property.
+
+Changes from Ant 1.5beta3 to Ant 1.5
+====================================
+
+Changes that could break older environments:
+--------------------------------------------
+
+* The filesetmanifest attribute added to <jar> after the 1.4.1
+ release has been removed for now. This change may affect only
+ the 1.5Beta/1.6Alpha users. An attempt will be made to add this
+ feature back into Ant 1.6.
+
+Fixed bugs:
+-----------
+
+* <zip> and friends would always update existing archive if you set
+ the update attribute to true.
+
+* To support backward compatibility with older versions, <pathconvert>
+ will once again set the property, even if the result is the empty
+ string, unless the new 'setonempty' attribute is set to false|no|off
+ (default is "true").
+
+* The manifest task would crash XmlLogger
+
+Other changes:
+--------------
+
+* added **/.svn and **/.svn/** to the default excludes
+
+Changes from Ant 1.5beta2 to Ant 1.5beta3
+=========================================
+
+Changes that could break older environments:
+--------------------------------------------
+
+* <pvcs> default filenameformat has been different from Ant 1.4.1.
+ Now it is different from 1.5beta1 and 1.5beta2.
+
+* <pathconvert> won't set the property if the result is the empty string.
+
+Fixed bugs:
+-----------
+
+* <available> could fail to find files or directories that happen to
+ start with the name of the project's basedir but are not children of
+ the basedir.
+
+* Nested <property>'s inside <ant> can now be overriden by subsequent
+ <ant> and <antcall> tasks.
+
+* <xslt>'s outputtype attribute wouldn't do anything.
+
+* <linecontains> filterreader could swallow lines.
+
+* <sequential> used to configure the tasks (set their attributes)
+ before the first task has been executed. This means that properties
+ that have been set by nested task seemed to be unset for the other
+ tasks in the same <sequential> element.
+
+* <javac>'s sourcepath setting has been ignored by some compiler
+ implementations.
+
+* <javadoc>'s packagelist attribute didn't work.
+
+* the plain mailer would always use port 25 in <mail>.
+
+* Ant's default logger could swallow empty lines.
+
+* ejbjar's iPlanet nested element now can process multiple descriptors.
+
+* IPlanetEjbc was looking in the wrong place for four iiop files.
+
+* <javac> would pass the -source switch to JDK 1.3's javac, even
+ though it doesn't support it.
+
+Other changes:
+--------------
+
+* <checksum> now uses a buffer (of configurable size).
+
+* The "Trying to override task definition" warning has been degraded
+ to verbose level if the two task definitions only differ in the class
+ loader instance that has loaded the definition.
+
+* Add a jvmargs to the ejbjar's weblogic element to allow additional
+ arguments to be provided to the VM runnign ejbc. Document the
+ jvmdebuglevel attribute which can be used to avoid warnings about
+ interface classess being found on the classpath. Document the new
+ <sysproperty> element which allows JVM properties to be defined.
+ Added an outputdir attribute to allow the destination to be a
+ directory into which the exploded jar is written.
+
+* ejbjar now supports Borland Enterprise Server 5 and Jonas 2.5
+
+Changes from Ant 1.5beta1 to Ant 1.5beta2
+=========================================
+
+Changes that could break older environments:
+--------------------------------------------
+
+* Properties will now be expanded in mail message bodies. This means
+ that one $ sign will be stripped if your mail message contains the text $$.
+
+* org.apache.tools.ant.taskdefs.Expand no longer extends MatchingTask.
+
+* Available#setFile now again uses a File argument as it did in 1.4,
+ this may break environments that have been adapted to the String
+ argument version present in 1.5beta1.
+
+Fixed bugs:
+-----------
+* When <move> attempts a rename, it deletes the destination file, if it
+ exists, before renaming the source file. However, <move> was not
+ checking if the destination file was actually a directory before
+ trying to delete it.
+
+* Make CVS Tasks to work under Cygwin.
+
+* Fix LineContains to handle huge files elegantly without causing
+ Stack Overflows.
+
+* if you ask for the "classic" compiler on Java1.4, you get upgraded to
+ "modern" because there is no classic compiler any more.
+
+* the <http> condition was viewing 404 'not found' exceptions as success. Now
+ it defaults to viewing any response >=400 as an error, and has an
+ errorsBeginAt attribute you can use if you want a higher or lower value.
+
+* <get> throws a build exception on an http authorization error, unless you
+ have set ignoreerrors to true.
+
+* <wsdltodotnet> was spelt in Wintel case: <WsdlToDotnet>. It is now lower
+ case, though the old spelling is retained for anyone who used it.
+
+* Merging of Manifests in jar now works as documented.
+
+* paths that have been separated by colons would be incorrectly parsed
+ on NetWare.
+
+* runant.pl now supports NetWare.
+
+* <tempfile> and <setproxy> tasks were in beta1, but not defined by
+ default; They now are. <tempfile> fills a property with the name of a
+ temporary file; <setproxy> lets you set the JVM's http, ftp and socks proxy
+ settings.
+
+* <available classname="foo" ignoresystemclasses="true"> failed for
+ JDK 1.1 and 1.2, even if the class could be found on the
+ user-specified classpath.
+
+* <property environment=... /> now works on z/OS.
+
+* forked <javac> failed for the wrong reason on JDK 1.1 - Ant would
+ use a temporary file to hold the names of the files to compile under
+ some conditons, but 1.1 doesn't support this feature. Ant will no
+ longer try this, but you may run into problems with the length of the
+ command line now.
+
+* the refid attribute for <property>s nested into <ant> or <param>s
+ nested into <antcall> didn't work.
+
+* <replaceregexp> didn't work for nested <fileset>s.
+
+* <javadoc> dropped sourcepath entries if no "interesting" .java
+ source files could be found below them. This has been backwards
+ incompatible and caused problems with custom doclets like xdoclet.
+
+* Using the doclet, docletpath or docletpathref attributes of
+ <javadoc> may have caused NullPointerExceptions.
+
+* nested <filesets> of <javadoc> would include too much.
+
+* <dependset> will no longer choke on <targetfileset>s that point to
+ non-existing directories.
+
+* <patch> didn't work at all.
+
+* <replace> and <replaceregexp> now fail if the file they are working
+ on is locked.
+
+* <javadoc> would pick up the wrong executable in the combination JDK
+ 1.2 and AIX.
+
+Other changes:
+--------------
+
+* z/OS now gets detected by the os condition.
+
+* <fileset> and <dirset> now have an optional followsymlink attribute
+ that can prevent Ant from following symbolic links on some platforms.
+
+* BeanShell is now supported in the <script> task.
+
+* <ejbjar> under Weblogic attempts to use the ejbc20 compiler for 2.0 beans
+ based on the deployment descriptor's DTD reference. Under weblogic 7.00 Beta
+ this ejbc class has been deprecated. To avoid the deprecation warning use
+ ejbcclass="weblogic.ejbc".
+
+* <ejbjar> will add a manifest to the generated jar based on the naming
+ convention in use. This overrides the manifest specified in the
+ <ejbjar> attribute
+
+
+Changes from Ant 1.4.1 to 1.5beta1
+==================================
+
+Changes that could break older environments:
+--------------------------------------------
+
+* Important: Single $ signs are no longer silently stripped!
+ Before you panic that we have broken all your build files, we have kept
+ the old "$$" -> "$" behaviour. So only build files which accidentally had
+ a $ sign in a string that was being silently stripped may break.
+ We added this fix to stop newbie confusion; if you want to write a
+ build file which works on ant versions 1.4.1 or earlier, stay with
+ the double $$ sign rule.
+
+* Project.getBuildListeners now returns a clone of the listener
+ list. Changes to the returned list will not affect the listeners
+ currently attached to the Project. It also means that it is safe to
+ iterate over the returned list if listeners are added or removed
+ during the traversal.
+
+* <pvcs> default filenameformat has been different from Ant 1.4.1.
+
+* Some messages that are printed during startup will not be
+ written to the logfile specified via -logfile as they might destroy
+ the format of the file for special BuildLoggers (like XmlLogger).
+
+* The filesetmanifest attribute added to <jar> after the 1.4.1
+ release has been removed for now. This change may affect only
+ the 1.5Beta/1.6Alpha users. An attempt will be made to add this
+ feature back into Ant 1.6.
+* Shipped XML parser is now Xerces 2.0.1 along with the XML Parser APIs.
+ XML Parser APIs is a separate jar that contains the necessary
+ JAXP/DOM/SAX classes.
+
+* <telnet> was fixed to expand properties inside nested <read> and
+ <write> elements; before this only happened when you assigned the text
+ to the string attribute. If you had $ signs in the string, they may
+ need escaping.
+
+* the RegexpMatcher interface has been extended to support case
+ insensitive matches and other options - custom implementations of
+ this interface won't work any longer. We recommend to use the new
+ Regexp interface that also supports substitution instead of the
+ RegexpMatcher interface in the future.
+
+* <gzip> will throw an exception if your src attribute points to a directory.
+
+* Unjar, Unzip and Unwar will throw an exception if the Src attribute
+ represents a directory. Support for nested filesets is provided
+ instead.
+
+* It is no longer possible to overwrite a property using tasks like
+ <condition>, <exec>, <pathconvert>, or <tstamp>. In some exceptional
+ cases it will generate a warning if you attempt to overwrite an
+ existing property.
+
+* Taskwriters please note: Whenever tasks had any overloaded set* methods,
+ Ant's introspection mechanism would select the last overloaded method
+ provided to it by the Java Runtime. A modification has now been made such
+ that when the Java Runtime provides a method with a String as its argument,
+ a check is made to see if there is another overloaded method that takes in
+ some other type of argument. If there is one such method, then the method
+ that takes in String as an argument is not selected by the Introspector.
+
+* The pattern definition **/._* has been included into the Default
+ Excludes list.
+
+* <propertyfile>'s <entry> element was modified to remove "never" as a value
+ as its behavior was undocumented and flakey.
+
+* The -projecthelp flag now only prints out targets that include the
+ 'description' attribute, unless the -verbose or -debug flag is included
+ on the Ant command line.
+
+* Ant's testcases now require JUnit 3.7 or above, as they now use the new
+ assertTrue method instead of assert.
+
+* If the 'output' attribute of <ant> is set to a simple filename or a
+ relative path, the file is created relative to ${basedir}, not ${user.dir}.
+
+* The default value for build.compiler is now javac1.x with x
+ depending on the JDK that is running Ant instead of classic/modern.
+
+Fixed bugs:
+-----------
+
+* <available> could fail to find files or directories that happen to
+ start with the name of the project's basedir but are not children of
+ the basedir.
+
+* Nested <property>'s inside <ant> can now be overriden by subsequent
+ <ant> and <antcall> tasks.
+
+* <xslt>'s outputtype attribute wouldn't do anything.
+
+* <linecontains> filterreader could swallow lines.
+
+* <sequential> used to configure the tasks (set their attributes)
+ before the first task has been executed. This means that properties
+ that have been set by nested task seemed to be unset for the other
+ tasks in the same <sequential> element.
+
+* <javac>'s sourcepath setting has been ignored by some compiler
+ implementations.
+
+* <javadoc>'s packagelist attribute didn't work.
+
+* the plain mailer would always use port 25 in <mail>.
+
+* Ant's default logger could swallow empty lines.
+
+* ejbjar's iPlanet nested element now can process multiple descriptors.
+
+* IPlanetEjbc was looking in the wrong place for four iiop files.
+
+* <javac> would pass the -source switch to JDK 1.3's javac, even
+ though it doesn't support it.
+
+* <zip> and friends would always update existing archive if you set
+ the update attribute to true.
+
+* To support backward compatibility with older versions, <pathconvert>
+ will once again set the property, even if the result is the empty
+ string, unless the new 'setonempty' attribute is set to false|no|off
+ (default is "true").
+
+* The manifest task would crash XmlLogger
+
+* A bug existed that prevented generated log files from being deleted as
+ part of the build process itself. This has now been fixed.
+
+* Fixed bug where <move> ignored <filterset>s.
+
+* Ant works properly with the combination of Java1.4/WindowsXP.
+
+* Fixed bug where <java> used to sometimes invoke class constructors twice.
+
+* Fixed bug with 4NT shell support.
+
+* Fixed bug where ant would not perform ftp without remotedir being
+ specified even though this was not mandatory.
+
+* Fixed bug where ant would not copy system properties into new Project
+ in ant/antcall tasks when inheritall="false" is set.
+
+* <propertyfile> would not close the original property file.
+
+* <ant> will no longer override a subbuild's basedir with inheritall="true".
+
+* Fixed problem with the built-in <junit> formatters which assumed
+ that only one test could be running at the same time - this is not
+ necessarily true, see junit.extensions.ActiveTestSuite.
+
+* <jar>'s whenEmpty attribute is useless as JARs are never empty, they
+ contain at least a manifest file, therefore it will now print a
+ warning and do nothing.
+
+* <typedef> hasn't been all that useful as it couldn't be used outside
+ of targets (it can now) and nested "unknown" elements have always
+ been considered to be tasks (changed as well).
+
+* <fixcrlf> would fail for files that contained lines longer than 8kB.
+
+* Some junit formatters incorrectly assumed that all testcases would
+ inherit from junit.framework.TestCase.
+
+* <fixcrlf> dropped the first characters from Mac files.
+
+Other changes:
+--------------
+
+* <checksum> now uses a buffer (of configurable size).
+
+* The "Trying to override task definition" warning has been degraded
+ to verbose level if the two task definitions only differ in the class
+ loader instance that has loaded the definition.
+
+* Add a jvmargs to the ejbjar's weblogic element to allow additional
+ arguments to be provided to the VM runnign ejbc. Document the
+ jvmdebuglevel attribute which can be used to avoid warnings about
+ interface classess being found on the classpath. Document the new
+ <sysproperty> element which allows JVM properties to be defined.
+ Added an outputdir attribute to allow the destination to be a
+ directory into which the exploded jar is written.
+
+* ejbjar now supports Borland Enterprise Server 5 and Jonas 2.5
+
+* added **/.svn and **/.svn/** to the default excludes.
+
+* Selector Elements now provide a way to create filesets based on
+ sophisticated selection criteria.
+
+* Gzip and Bzip2 files can now be constructed in the fly when using
+ the tar task without having to create the intermediate tar file on
+ disk. The Untar task can also untar GZip and BZip2 files on the fly
+ without creating the intermediate tar file.
+
+* New optional type, <classfileset> added.
+
+* <ejbjar> now allows control over which additional classes and interfaces
+ are added to the generated EJB jars. A new attribute "dependency" can be
+ defined which controls what classes are added. The addition of classes now
+ uses the Jakarta-BCEL library rather than reflection, meaning bean classes are
+ no longer loaded into Ant's JVM. The default dependency analyzer is known as
+ the ancestor analyzer. It provides the same behaviour as the 1.4.1 version of
+ <ejbjar>. If the BCEL library is not present, a warning will be issued stating
+ the ancestor analyzer is not available. In this case <ejbjar> will continue
+ to function but will not add super classes to the jar.
+
+* <available> has a new attribute named ignoreSystemClasses.
+
+* New task <cvschangelog/> generates an XML report of changes that occur
+ on CVS repository.
+
+* New filter readers: ClassConstants, ExpandProperties, HeadFilter,
+ LineContains, LineContainsRegExp, PrefixLines, ReplaceTokens,
+ StripJavaComments, StripLineBreaks, StripLineComments, TabsToSpaces,
+ TailFilter.
+
+* <copy>, <loadfile>, <loadproperties>, <move> support FilterChains
+ of FilterReaders.
+
+* New task <loadproperties> to load contents of file as Ant properties,
+ with nested <filterchain> elements.
+
+* New task <loadfile> to load a whole file into a property.
+
+* New task <echoproperties> to list your current properties to the screen
+ or a file.
+
+* New tasks <bzip2> and <bunzip2> to pack and unpack files using the
+ BZip2 algorithm.
+
+* New tasks <replaceregexp>, <checksum>, <translate>, <waitfor>,
+ <manifest>, <vsscp>, <vssadd>, <vsscreate>, <splash>, <basename>, <dirname>,
+ <concat>, <sourceoffsite>, <jarlib-available>, <jarlib-display>,
+ <jarlib-manifest>, <jarlib-resolve>.
+
+* A new combined <mail> task, which replaces the old <mail> and
+ <mimemail> tasks, has been added. The <mimemail> task, and
+ old SendEmail and MimeMail classes have been deprecated.
+
+* Mail task allows specification of port number.
+
+* Users can control what <zip> and <jar> must do when duplicate files
+ are found. A new element <zipgroupfileset> allows for multiple zip
+ files to be merged into the archive. In addition, <jar> also has
+ another new attribute: filesetmanifest. The existing manifest
+ attribute of <jar> now also accepts the name of a jar added through
+ a fileset.
+
+* gzip now checks that the zipfile is older than the source file
+ before rebuilding the zipfile.
+
+* TarFileset takes in three new attributes - fullpath, prefix
+ and preserveLeadingSlashes.
+
+* <move> attempts to rename the directory, if everything inside it is
+ included, before performing file-by-file moves. This attempt will
+ be done only if filtering is off and if mappers are not used. This
+ is a performance improvement and there is no change otherwise in
+ the functionality of this task.
+
+* Exec task has extra attribute "resultproperty" to get the return code
+ into a property.
+
+* Exec task prints a message when a timed-out process is killed.
+
+* Added optional attributes - name, arch and version to the <os> task.
+
+* Unjar, Untar, Unwar and Unzip now support patternsets to
+ select files from an archive for extraction. Filesets may be
+ used to select archived files for unarchival.
+
+* Javac task allows debug levels to be specified. Debug levels
+ will have an effect only when the modern compiler or the
+ classic compiler (version 1.2 and higher) is used and debugging
+ is enabled.
+
+* Added support for specifying CVS_RSH in the <cvs/> task
+
+* The attributes zipfile, jarfile, warfile and earfile (from the Zip,
+ Jar, War and Ear tasks) have been deprecated and superseded by a
+ new attribute "destfile".
+
+* Added new conditions <isset>, <checksum>, <http>, <socket>, <contains>,
+ <filesmatch>.
+
+* <taskdef> and <typedef> will now emit a warning if a task/type of
+ the given name already exists.
+
+* A new revision of VAJ tasks: The most important new feature
+ is the ability to execute VAJ tasks from the command line by
+ exploiting the Remote Tool Access feature of VAJ.
+
+* Improved support for Novell NetWare.
+
+* Added an optional encoding attribute to <fixcrlf>.
+
+* <apply> has a new attribute relative that allows users to pass the
+ filenames as relative instead of absolute paths on the command line.
+
+* References can now be copied into the child build by <ant> and
+ <antcall> using nested <reference> elements or the new inheritRefs
+ attribute.
+
+* <fail> now supports builds to fail based on conditions via if and
+ unless attributes.
+
+* Ant now comes with two new BuildLogger implementations - one that
+ can send emails containing a log of the build process (MailLogger),
+ and one that colorizes the output based on message levels, using
+ ANSI color code escape sequences (AnsiColorLogger).
+
+* A "package" mapper type has been added to allow package directory
+ names replaced with the dotted form.
+
+* You can now specify environment variables in the <java> and <junit> tasks
+ if the fork attribute has been set to true.
+
+* -propertyfile command-line option has been added to load an entire
+ property file just as -D properties are declared (as user properties).
+ -D properties take precedence over -propertyfile specified ones.
+
+* You can now set an ANT_ARGS environment variable to hold arguments you
+ always want passed to the 'ant' command -- for example, if you always
+ want to use a different logger or the -find flag.
+
+* <tstamp> now supports a new "prefix" attribute to prefix properties set.
+
+* You can now specify the -sourcepath for <javac> explicitly.
+
+* <javac> now supports a new "listfiles" attribute to list the source
+ files it's handing off to the compiler.
+
+* The compiler implementation for <javac> can now be chosen on a task by
+ task basis. The new "compiler" attribute of <javac> can be used to override
+ the value of the build.compiler property, if set.
+
+* <javac> has a new nested element, <compilerarg>, which allows you
+ to specify additional args for the specific compiler you're using.
+
+* <javac>'s "source" attribute is now enabled for jikes as well.
+
+* <propertyfile>'s <entry> now has a 'unit' attribute to specify the
+ increment/decrement unit on date operations.
+
+* <property> now supports a 'prefix' attribute when loading from a file
+ or resource.
+
+* In Ant 1.4, a feature has been added to the <junit> task that would
+ add ant.jar, optional.jar and junit.jar implicitly to the classpath -
+ this feature can now be disabled by setting the new includeantruntime
+ attribute to false.
+
+* <style> behaves differently from any other directory-based task, as it
+ processes all files that it finds in included directories in
+ addition to the files matched by your patterns. There is now a new
+ attribute, 'scanincludeddirectories', to suppress this behavior.
+
+* <javadoc> now supports a <tag> nested element to provide the -tag option
+ to the standard Java 1.4 doclet. The element is ignored when not running
+ on Java 1.4.
+
+* <ftp> can now chmod files on a remote server that supports
+ "site chmod", as well as set the umask before transferring files, if
+ the server supports "site umask".
+
+* New <serverdeploy> "optional" task.
+
+* <patternset> now supports nested patternsets.
+
+* Perforce tasks now support a "failonerror" attribute (defaults to "true").
+
+* Open Source application server JOnAS support:
+ EJB hot deploy and deploy with <serverdeploy> and <ejbjar>
+
+* Added new DirSet (<dirset>) datatype.
+
+* <path> now supports nested <dirset> and <filelist> elements.
+
+* <pathconvert> now supports nested <dirset> and <filelist> elements.
+
+* <pathconvert>'s "dirsep" and "pathsep" attributes now accept
+ multi-character values.
+
+* <copy> task now has a 'failonerror' attribute to allow keep-going
+ behaviour when the file to be copied is not found (defaults to "true").
+
+* <uptodate> now has a 'srcfile' attribute to allow specifying a
+ full-path filename.
+
+* <exec>, <sql> and <java> now support append attributes to allow
+ appending the output to an existing file.
+
+* <java> now supports a timeout attribute analog to <exec> - it is
+ highly recommended to only use it together with fork="true".
+
+* <javadoc> now supports a source attribute to enable javadoc to
+ handle assertions present in JDK 1.4 source code.
+
+* <replace> supports a new replacefilterfile attribute that
+ automatically turns all properties of a given file into
+ replacefilters.
+
+* An alias of <xslt> has been added to refer to the <style> task.
+
+* The compiler implementation for <rmic> can now be chosen on a task by
+ task basis. The new "compiler" attribute of <rmic> can be used to override
+ the value of the build.rmic property, if set.
+
+* <rmic> has a new nested element, <compilerarg>, which allows you
+ to specify additional args for the specific compiler you're using.
+
+* org.apache.tools.ant.XmlLogger now is a BuildLogger, rather than just
+ a BuildListener. It can operate in either mode successfully.
+
+* <junit> has a new attribute "showoutput". If set to true, output
+ generated by tests will be sent to Ant's logging system as well as
+ to the formatters (instead of sending it to the formatters
+ exclusively).
+
+* Ant has now a pluggable way to prompt users for input, which is used
+ by the new <input> task. IDE integrators can provide an
+ implementation of the InputHandler interface to decouple Ant's input
+ from the console. An implementation that gets its input from a file
+ for unattended builds is part of Ant's distribution.
+
+ For more details see docs/manual/inputhandler.html.
+
+* <patch> has a new attribute that selects the directory in which to
+ run the command.
+
+* <javadoc> now supports two new nested elements, <fileset> and <packageset>.
+
+
+Changes from Ant 1.4 to Ant 1.4.1
+===========================================
+
+Fixed bugs:
+-----------
+
+* <ant>'s antfile attribute will now also be considered an absolute path on
+ Windows systems, if it starts with a \ and no drive specifier.
+
+* The fullpath attribute of <zipfileset> has been ignored if you used
+ the src attribute at the same time.
+
+* The manifest file is now always placed as the second entry (after /META-INF)
+ in generated jars. This allows the manifest to be read by JarInputStreams
+
+* Fixed bug in depend task which would fail with a NullPointerException if no
+ dependency cache was specified.
+
+* sql task now handles REM statements correctly so that lines starying with rem
+ but which are not comments are actually processed.
+
+* XMLLogger now uses the task's name rather than the classname
+
+* <mapper>s will now work as expected if the to pattern expands to an
+ absolute pathname.
+
+* <javac> didn't ignore memory settings in non-fork mode
+
+* <cab> didn't split the options attribute into several command line
+ arguments correctly.
+
+Other changes:
+--------------
+
+* New source attribute for <javac> to enable assertion in JDK 1.4
+
+* XmlLogger and <antstructure> now add an encoding declaration to the
+ XML files they generate.
+
+* <fileset> has a new attribute "casesensitive" to make it match
+ filenames in a case insensitive way (if you set it to false) - by
+ default filesets remain case sensitive.
+
+Changes from Ant 1.3 to Ant 1.4
+===========================================
+
+Changes that could break older environments:
+--------------------------------------------
+* JUnitReport now uses the xalan redirect extension for multi-output.
+ With Xalan 1.2.2 it forces the use of bsf.jar in the classpath.
+ (Available in the xalan distribution). It is recommended to switch
+ to Xalan 2.x that do not need it.
+
+* Zip.setWhenempty() has changed its signature.
+
+* <rmic> is now implemented using a factory. This makes extending
+ rmic to use a new compiler a lot easier but may break custom
+ versions of this task that rely on the old implementation.
+
+* several Zip methods have changed their signature as we now use a Zip
+ package of our own that handles Unix permissions for directories.
+ Furthermore <zip> will now use the platform's default character
+ encoding for filenames - this is consistent with the command line
+ ZIP tools, but causes problems if you try to open them from within
+ Java and your filenames contain non US-ASCII characters. Use the new
+ encoding attribute of the task and set it to UTF8 to get the old
+ behavior.
+
+* The <pvcs> task has been moved to a package of its own.
+
+* JUnitResultFormater has two additional methods that must be
+ implemented by custom formatters.
+
+* Ant will no longer use the canonical version of a path internally -
+ this may yield different results on filesystems that support
+ symbolic links.
+
+* The output generated by the xml formatter for <junit> has changed
+ again, it doesn't format the numeric value in the time attribute anymore.
+
+* Pattern matching rules have changes slightly, the pattern foo*
+ doesn't match files contained in a directory named foo - use foo/*
+ instead.
+
+* <fixcrlf> will not remove trailing whitespace at the end of lines anymore.
+
+* The Classloader usage has been changed for the taskdef, property, available
+ and sql tasks so that it delegates to the parent classloader. This may cause
+ ClassNotFoundExceptions to be thrown if a system class attempts to load a
+ class in the taskdef's classpath (typically factory objects).
+
+* Ant now allows multithreading of tasks and the containment of tasks within
+ other tasks. This can break customer listeners which do not expect messages
+ from a task before the previous task has finished.
+
+* Ant now installs its own output stream into System.out to route output to the
+ task currently executing on the current thread. This also means that all
+ output is now routed as Ant message events. Customer listeners and loggers
+ should not call System.out at any time. This has always been true but such
+ usage now will cause problems due to possible recursion.
+
+* Invalid manifest files will now cause build failures in the <jar> task.
+
+* Ant Introspection now looks for methods with method names starting with
+ addConfigured. When called these methods are passed an argument after it has
+ been configured from the build file. Custom tasks supporting nested elements
+ starting with the name configured will no longer function.
+
+* The environment variable JAVACMD that can be used to specify the
+ java executable to Ant's wrapper scripts must not contain additional
+ command line parameters any longer - please use the environment
+ variable ANT_OPTS for such parameters now.
+
+* Ant's wrapper scripts now quote the CLASSPATH environment variable, thus
+ supporting classpaths which refer to directories containing spaces. This means
+ that the CLASSPATH environment variable cannot have quotes. Any quotes should
+ be removed. This will not affect the operation of the CLASSPATH environment
+ variable in other contexts.
+
+* A delete task like
+ <delete includeEmptyFilesets="true">
+ <fileset dir="somedir" />
+ </delete>
+ will now remove "somedir" as well, unless there are still files left
+ in it (matched by the default excludes).
+
+* The copy task will now fail if the file to be copied is not found.
+
+* Ant properties defined in properties files now behave the same way as
+ properties defined in the build file. In particular the $ character needs
+ to be escaped in property values by doubling it to $$. So, to define a
+ property with the value $hello, you need to define it in a properties file
+ as
+ test.prop=$$hello
+ This was not the case in Ant 1.3
+
+Other changes:
+--------------
+
+* New tasks: ear, p4counter, record, cvspass, vsscheckin, vsscheckout,
+ typedef, sleep, mimemail, set of tasks for Continuus/Synergy, dependset,
+ condition, maudit, mmetrics, jpcoverage, jpcovreport, jpcovmerge
+
+* Ant now uses JAXP 1.1
+
+* rmic now supports Kaffe's and Weblogic's version of rmic.
+
+* new magic property build.rmic to chose the rmic implementation
+
+* <tar> will now add empty directories as well
+
+* you can now specify a description for <p4change>
+
+* <touch> can now work on <fileset>s
+
+* <uptodate> now supports a value attribute
+
+* <fail> supports nested text
+
+* <fixcrlf> won't override files that are already in the correct
+ format.
+
+* <sql> now supports REM comments as well as // and --
+
+* <jar> now has a nested <metainf> element following the same idea as
+ <war>'s <webinf>.
+
+* <pvcs> can now handle multiple projects.
+
+* <available> now has a "type" attribute you can use in conjunction
+ with the "file" attribute to specify whether the "file" you're
+ looking for is a file or a directory.
+
+* New <junit> formatter named "brief"
+
+* <ejbjar> changes
+ * Add support for Borland Application Server to the <ejbjar> task using
+ a <borland> nested element.
+ * Add support for iPlanet Application Server to the <ejbjar> task. Also
+ includes some iPlanet utility tasks
+ * Add support for JBoss Application Server to the <ejbjar> task.
+ * Add a naming attribute to control the naming scheme that
+ ejbjar uses to name the generated EJB jars.
+ * Weblogic element now sets the compiler class for EJB 2.0 beans
+ * <dtd> elements can be specified at the <ejbjar> level for building generic
+ beans
+ * <dtd> elements can now be URLs
+ * Allow the manifest to be specified for the generated jars
+ * The weblogic element now supprts an attribte noEJBC to skip the processing
+ of the jar by ejbc. The ejbc step will then occur at deployment
+ * weblogic will tell ejbc to use Jikes compiler if build.compiler is set to
+ jikes. It can be restored to the default, javac, operation if desired.
+
+* Allow the <sql> Delimiter to be set in the so that Oracle stored procs may be
+ entered
+
+* <execon> and <apply> can now optionally skip empty filesets.
+
+* <javadoc> has a new useexternalfile attribute that makes it use a
+ temporary file for sourcefile and package names - helps to defeat
+ command line length limitations.
+
+* Data types like <path> can now be defined inside of <target>s
+
+* you can now specify a classpath for <style> - the XSLZ processor
+ will be loaded from this path
+
+* added a force attribute to <style> to support dependencies that the
+ task cannot determine itself (dependency on parameters, not file
+ modification times for example)
+
+* added vmlauncher attribute to exec tasks. This defaults to true. If
+ it is set to false, the VM's ability to launch commands in bypassed
+ and the OS shell, either directly or through the auxiliary antRun
+ scripts is used.
+
+* regexp mapper now supports the java.util.regex package of JDK 1.4.
+
+* New filesonly attribute for <zip> and friends to suppress directory
+ entries.
+
+* New update attribute for <zip> and friends - update an existing
+ archive instead of creating a new one.
+
+* <apply> and <execon> have been merged into a single task.
+
+* added vssver.scc to the default excludes
+
+* <available> has a new filepath attribute/nested element that allows
+ you top search for a file in a given path.
+
+* <junit> can now optionally set a property on test failure.
+
+* <taskdef> can now define several tasks at once, reading the
+ name/classname pairs from a property file or resource.
+
+* <unzip/unjar/unwar> and <untar> now have an overwrite attribute that
+ defaults to true. If set to false, files that are newer than the
+ files in the archive will not be replaced.
+
+* <patternset> and <fileset> now support nested <in/excludesfile>
+ elements - using these you can have more than one in/excludes file
+ per <patternset>.
+
+* Three new supported compilers for javac: kjc for kopi, gcj for the
+ gcc frontend and sj for Symantec's compiler.
+ In addition extJavac or the new fork attribute can be
+ used to run the JDK's javac in a JVM separate from Ant.
+
+* <fixrlf> can now with CR only line-ends and can use an arbitraty
+ between 2 and 80.
+
+* The .NET tasks have been adapted to the beta2 release of the framework.
+
+* <move> will now try to rename() files before copying them byte by
+ byte - only if filtering is of, of course.
+
+* <ant> and <antcall> tasks now support a new attribute inheritAll. When set to
+ false, only user properties are passed through to the target Ant instance.
+ This includes properties set on the command line and properties explicitly
+ passed
+
+* <javadoc> now skips off line links if the package list cannot be found.
+
+* <wlrun> now allows the security policy file to exist outside the weblogic
+ directory.
+
+* <java> task will set the Thread contextClassLoader under JDKs 1.2+ to the
+ classloader for the class being executed.
+
+* Introduce the concept of a TaskContainer - a task or element which can contain
+ Ant Tasks.
+
+* Add new tasks implementing the TaskContainer interface <parallel> and
+ <sequential> which allow parallel execution of tasks to be specified.
+
+* <depend> task will now take into account dependencies on jar files and class
+ files from a given classpath.
+
+* <jar> manifest entries may now be specified in the build file either
+ completely or to be merged with a manifest file.
+
+* <tstamp> task custom formats now support locales.
+
+* Added a listner which will forward events to Log4J. The log4j configuration
+ file should be in the directory from which Ant is run or passed as a system
+ property using a JVM argument.
+
+* Introduced the concept of <filtersets> to allow for more control in which
+ filters get applied in a <copy> or <move> operation.
+
+* Added nowarn attribute to javac and deprecated the Jikes-magic property
+ build.compiler.warnings.
+
+* The <depend> task cache format has changed and all dependency information is
+ now stored in a single file.
+
+Fixed bugs:
+-----------
+
+* Testcases have been made independent of current working directory.
+
+* Input ZIP-Files will be closed when using a <zipfileset>.
+
+* p4 tasks now don't fail if user, port or client have been omitted
+ (and this is acceptable for the context of the command).
+
+* <javah>'s outputfile attribute will be resolved as relative to the
+ projects basedir.
+
+* <antstructure> should create a valid DTD for propertyfile.operation.entry
+ and omit tasks it fails to load.
+
+* won't try to pass a -bootclasspath flag to javac 1.1 anymore
+
+* <style>'s style attribute no handles absolute paths correctly.
+
+* <delete includeemptydirs="true"> now deletes more than just the leaf
+ directories.
+
+* You can now specify a <fileset> for a directory that doesn't exist at
+ declaration time but will created before the fileset gets used for the
+ first time.
+
+* If the quiet attribute has been set, <delete> will handle <fileset>s
+ with non-existing directories gracefully.
+
+* Output written by testcases will now be captured by the <junit> task
+ and passed to the formatters.
+
+* Quote the -group parameter to Javadoc as per the specification
+
+* Initialise classes when loaded through the AntClassLoader - that is, run
+ static initializers
+
+* Implement getResource() and getResources() in AntClassLoader
+
+* Create the <ejbjar> weblogic command line as a set of arguments rather than
+ as a single line. Avoids problems with paths which contain spaces.
+
+* <ejbjar> now fails when the weblogic ejbc compiler reports an error.
+
+* Make the AntClassLoader load resources in the same order as it currently
+ loads classes.
+
+* Handle classpaths with spaces
+
+* Make sure XSLT processors close their output files in <style>.
+
+* perform proper uptodate check in <rmic> when compiling for IIOP.
+
+* <jjtree>'s uptodate test works even if outputdirectory is not the
+ parent dir of target
+
+* <copy> will remove target file (if it exists) before writing to it -
+ this avoids problems with links on filesystems that support them.
+
+* <ftp> now properly recurses remote directories.
+
+* <ftp> closes remote connection when it's done.
+
+* <junit> tries to include all necessary classes for the task itself
+ to the classpath when running in fork mode - doesn't work for JDK 1.1
+
+* <apply> and <execon> do now execute the command only once, if you
+ specify the parallel attribute - instead of once per fileset.
+
+* directory based tasks and fileset could miss some included files in
+ directories that have been excluded
+
+* <fixcrlf> failed for large files.
+
+* <move> removed files you tried to move to themselves.
+
+* <sql> task will not trty to print the result set unless the query succeeded.
+
+* Ant classloader will now ignore paths which are invalid relative to the
+ project base
+
+* <ejbjar> weblogic elements check for jar file changes has been fixed.
+ Previously some changes would not be included.
+
+* properties loaded from properties files are now resolved internally. This
+ removes the spurious warnings about usage of properties which have not been
+ set.
+
+* <jar> task and friends now process the JAR manifest to ensure it is valid.
+
+* The task finished event now includes any exception thrown by the task.
+
+* <java> task now supports a jvmVersion attribute so that if another JVM is
+ being used, Ant can determine which options to use for features such as the
+ VM memory limits
+
+
+Changes from Ant 1.2 to Ant 1.3
+===========================================
+
+Changes that could break older environments:
+--------------------------------------------
+
+* Ant doesn't search for the buildfile anymore, unless you use the new
+ -find argument.
+
+* <perforce> has been replaced by a number of new tasks.
+
+* <javac> is now implemented using a factory. This makes extending
+ javac to use a new compiler a lot easier but may break custom
+ versions of this task that rely on the old implementation.
+
+* The output generated by the xml formatter for <junit> has changed a
+ little, it doesn't append " sec" in the time attribute anymore.
+
+Other changes:
+--------------
+
+* A GUI Frontend: Antidote. This is currently in development. At this
+ time, this is not part of the Ant release, although the source is
+ included if you are interested.
+
+* New tasks: stylebook, propertyfile, depend, antlr, telnet, csc,
+ ilasm, apply, javah, several clearcase tasks, junitreport, sound
+
+* Added output attribute to <java>.
+
+* Added nested zipfileset element to <zip>
+
+* Changed <sql> so that printing is at the task level rather than
+ the statement level.
+
+* javadoc task will pass -d flag to any doclet if the destDir attribute is
+ given. If the doclet does not accept the -d flag then omit the destdir
+ attribute.
+
+* <cab> can work on non-Windows platforms with the help of libcabinet.
+ See http://trill.cis.fordham.edu/~barbacha/cabinet_library/.
+
+* <ftp> now supports passive mode.
+
+* New <mapper> data type that can be used to get influence on the
+ target files for some tasks like <copy> or enable new types of tasks
+ like <apply>.
+
+* <execon> provides more control over the command line now, the names
+ of the source files are no longer required to be at the end of the
+ command.
+
+* Style tasks will now support TraX compliant XSL processors if one is present
+ in your classpath.
+
+* Added a failonerror to the javac task. If set to false, the build will
+ continue even if there are compilation errors.
+
+* Added nested format elements to the tstamp task allowing additional time
+ formats to be defined for arbitrary properties.
+
+* Added classpath attribute and nested classpath element to <property>
+ to make the resource attribute more powerful.
+
+* ${} property expansion will now be performed on the patterns read
+ from files specified as includesfile or excludesfile attributes.
+
+* The <tar> and <untar> tasks now support GNU format for handling paths
+ which are greater than 100 characters in length. In addition the <tar>
+ task now supports nested filesets through which the file permissions
+ may be controlled.
+
+* wlrun, wlstop and ejbjar now support Weblogic 6.0
+
+* The MPasre task has been updated to work with MParse 2.0
+
+* The documentation has been significantly updated.
+
+
+Fixed bugs:
+-----------
+
+* <signjar> no longer uses deprecated methods.
+
+* javadoc's failonerror attribute works again
+
+* javadoc's additionalparam attribute will now be split into separate
+ parameters (on spaces) to allow for more than one parameter.
+
+* Changed <sql> task so that printing result sets works on Oracle
+
+* Changes to ddcreator and ejbc helper to respect the descriptor hierarchy
+ keppgenerated in ejbc can now be turned off
+
+* ejbjar now correctly ignores <ejb-ref> elements in the deployment descriptor.
+ CMP files are included by parsing the weblogic deployment descriptor rather
+ than relying on the naming convention used in ant 1.2
+
+* ejbjar includes super classes and super interfaces into the generated ejb
+ jar files. The <support> nested element allows support classes to be
+ included in the EJB jar. The toplink element should now correctly locate
+ the toplink descriptor.
+
+* <vssget> now correctly deals with spaces in arguments
+
+* <jar> fails early if a given manifest file doesn't exist
+
+* <rmic> doesn't search for the _Skel file anymore when stubversion is
+ set to 1.2.
+
+* <rmic> uses the the same classpath to verify a class can be rmic'd
+ as it passes to the compiler.
+
+* org.apache.tools.mail.MailMessage (and therefore <mail>) can now
+ handle SMTP servers sending multi line responses.
+
+* nested <classpath> elements of <taskdef> now work for <taskdef>s not
+ nested into <target> as well.
+
+* <property> and <available> will search for the resource "foo" instead
+ of "/org/apache/tools/ant/taskdefs/foo" when given a relative resource
+ name foo.
+
+* Handle build files in directories whose name contained a "#" character
+
+* <junit> can now log to files whose name contains a comma as well.
+
+* The AntClassLoader now refers to the loader which loaded it, any
+ requests it does not handle itself. Previously these went to the
+ primordial loader.
+
+Changes from Ant 1.1 to Ant 1.2
+===============================
+
+Changes that could break older environments:
+--------------------------------------------
+
+* Semantics of <property> has changed again in the hope to be more
+ intuitive. ${} expansion now happens at runtime and <property> tags
+ living inside of targets only take effect if they are visited at
+ runtime.
+
+ As a side effect of this change, task's attributes get set at runtime
+ not at parser time as well, which might change the results of
+ <script>s or other custom tasks that reference other tasks by their id
+ attribute.
+
+* copying of support files in <javac> has been removed - as well as
+ the filtering attribute.
+
+* the <expand> and <keysubst> tasks have been removed.
+
+* the ignore and items attributes of directory based tasks have been removed.
+
+* the command line switches _not_ starting with - have been removed.
+
+* Path and EnumeratedAttribute have been moved from
+ org.apache.tools.ant to org.apache.tools.ant.types.
+
+* the class attributes of <available>, <java>, <rmic> and <taskdef>
+ have been removed.
+
+* the src attribute of <chmod> has been removed.
+
+* <patch> and <javadoc> have lost some of their attributes.
+
+* <java> and <cvs> have lost some undocumented attributes.
+
+* the Unix antRun script would search for command.sh in the directory
+ it changed to and invoke this instead of command if present. This
+ behavior has been dropped.
+
+* <ejbjar> task syntax has been changed significantly
+
+* <exec> is no longer implemented by org.apache.tool.ant.taskdefs.Exec.
+ Custom tasks that rely on Project.createTask("exec") to return an
+ instance of this class are going to fail.
+
+* nested <include> and <exclude> elements expect the value of their
+ name attribute to be a single pattern, they don't accept multiple
+ patterns anymore. Split them into multiple elements of the same type.
+
+* <delete dir="somedir" /> will now delete the directory itself as
+ well as all included files. If you just want to clean out the
+ directory and keep the empty one, use a nested fileset.
+
+Other changes:
+--------------
+
+* New tasks: antstructure, cab, execon, fail, ftp, genkey, jlink,
+ junit, sql, javacc, jjtree, starteam, war, unwar, uptodate,
+ native2ascii, copy, move, mparse.
+
+* copydir, copyfile, deltree and rename are now deprecated. They
+ should be replaced with the new copy, delete and move tasks.
+
+* <java> uses a ClassLoader of its own in no-fork mode if a classpath is
+ specified.
+
+* <style> will create the necessary target directories and reprocess
+ all files if the stylesheet changes.
+
+* New data types fileset and patternset - expected to get a broader use.
+ They, as well as PATH like structures, can now be defined on a global
+ level and later be referenced by their id attribute.
+
+* You can specify environment variables to <exec>.
+
+* <get> can check whether a remote file is actually newer than a local
+ copy before it starts a download (HTTP only).
+
+* Added a -logger option to allow the class which performs logging to be
+ specified on the command line.
+
+* Added a -emacs option to tell the logger to leave out taskname adornments
+ on log output.
+
+* <chmod> works on all files in parallel and supports multiple filesets.
+
+* <replace> can now use tokens and/or values that cross line boundaries.
+
+* build.compiler supports now jvc as well.
+
+* project specific help can now be obtained with the -projecthelp option.
+
+* Added a -debug option to make -verbose less verbose (and more useful)
+
+* Ant will now search for a file named build.xml in the parent directory
+ and above (towards the root of the filesystem) if you didn't specify
+ -buildfile and there is no build.xml in the current directory.
+
+* <echo> can now write to a file and accepts nested text.
+
+Fixed bugs:
+-----------
+
+* <chmod> didn't work when used as a directory based task.
+
+* Path, Available, Property didn't resolve relative filenames with
+ respect to the Project's basedir.
+
+* Project didn't interpret the basedir attribute correctly in all
+ cases.
+
+* Nested <src> in <javac> caused NullPointerException.
+
+* Corrupt Zip- and Jar-files ar now deleted if the task fails.
+
+* many more fixes we've forgotten to document here ...
+
+* The packagelistloc attribute of <javadoc>'s <link> child will be
+ resolved as a file (i.e. it is either absolute or relative to
+ basedir).
diff --git a/framework/src/ant/apache-ant-1.9.6/bootstrap.bat b/framework/src/ant/apache-ant-1.9.6/bootstrap.bat
new file mode 100644
index 00000000..70decf2a
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/bootstrap.bat
@@ -0,0 +1,138 @@
+@echo off
+
+REM You will need to specify JAVA_HOME.
+REM For compiling Ant Java 1.4 or higher is required.
+
+REM Licensed to the Apache Software Foundation (ASF) under one or more
+REM contributor license agreements. See the NOTICE file distributed with
+REM this work for additional information regarding copyright ownership.
+REM The ASF licenses this file to You under the Apache License, Version 2.0
+REM (the "License"); you may not use this file except in compliance with
+REM the License. You may obtain a copy of the License at
+REM
+REM http://www.apache.org/licenses/LICENSE-2.0
+REM
+REM Unless required by applicable law or agreed to in writing, software
+REM distributed under the License is distributed on an "AS IS" BASIS,
+REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+REM See the License for the specific language governing permissions and
+REM limitations under the License.
+
+set OLDJAVA=%JAVA%
+set OLDJAVAC=%JAVAC%
+set BOOTOLDCLASSPATH=%CLASSPATH%
+set OLDANTHOME=%ANT_HOME%
+
+set ANT_HOME=.
+
+if "" == "%JAVA%" if "" == "%JAVA_HOME%" set JAVA=java
+if "" == "%JAVA%" set JAVA=%JAVA_HOME%\bin\java
+
+if "" == "%JAVAC%" if "" == "%JAVA_HOME%" set JAVAC=javac
+if "" == "%JAVAC%" set JAVAC=%JAVA_HOME%\bin\javac
+
+echo.
+echo ... Bootstrapping Ant Distribution
+
+if "%OS%" == "Windows_NT" if exist bootstrap\nul rmdir/s/q bootstrap
+if not "%OS%" == "Windows_NT" if exist bootstrap\nul deltree/y bootstrap
+if "%OS%" == "Windows_NT" if exist build\nul rmdir/s/q build
+if not "%OS%" == "Windows_NT" if exist build\nul deltree/y build
+
+SET LOCALCLASSPATH=
+for %%i in (lib\optional\*.jar) do call src\script\lcp.bat %%i
+if exist "%JAVA_HOME%\lib\tools.jar" call src\script\lcp.bat %JAVA_HOME%\lib\tools.jar
+if exist "%JAVA_HOME%\lib\classes.zip" call src\script\lcp.bat %JAVA_HOME%\lib\classes.zip
+
+set TOOLS=src\main\org\apache\tools
+set CLASSDIR=build\classes
+
+SET CLASSPATH=%LOCALCLASSPATH%;%CLASSDIR%;src\main;%CLASSPATH%
+
+echo JAVA_HOME=%JAVA_HOME%
+echo JAVA=%JAVA%
+echo JAVAC=%JAVAC%
+echo CLASSPATH=%CLASSPATH%
+
+if "%OS%" == "Windows_NT" if exist %CLASSDIR%\nul rmdir/s/q %CLASSDIR%
+if not "%OS%" == "Windows_NT" if exist %CLASSDIR%\nul deltree/y %CLASSDIR%
+
+if not exist build\nul mkdir build
+if not exist build\classes\nul mkdir build\classes
+
+echo.
+echo ... Compiling Ant Classes
+
+"%JAVAC%" %BOOTJAVAC_OPTS% -d %CLASSDIR% %TOOLS%\bzip2\*.java %TOOLS%\tar\*.java %TOOLS%\zip\*.java %TOOLS%\ant\*.java %TOOLS%\ant\types\*.java %TOOLS%\ant\taskdefs\*.java %TOOLS%\ant\util\regexp\RegexpMatcher.java %TOOLS%\ant\util\regexp\RegexpMatcherFactory.java %TOOLS%\ant\taskdefs\condition\*.java %TOOLS%\ant\taskdefs\compilers\*.java %TOOLS%\ant\types\resources\*.java %TOOLS%\ant\property\*.java
+
+if ERRORLEVEL 1 goto mainend
+
+echo.
+echo ... Copying Required Files
+
+copy %TOOLS%\ant\taskdefs\*.properties %CLASSDIR%\org\apache\tools\ant\taskdefs
+copy %TOOLS%\ant\types\*.properties %CLASSDIR%\org\apache\tools\ant\types
+
+echo.
+echo ... Building Ant Distribution
+
+if not "%OS%"=="Windows_NT" goto win9xStart
+:winNTStart
+@setlocal
+
+REM parse command line arguments
+rem Need to check if we are using the 4NT shell...
+if "%eval[2+2]" == "4" goto setup4NT
+
+rem On NT/2K grab all arguments at once
+set ANT_CMD_LINE_ARGS=%*
+goto doneStart
+
+:setup4NT
+set ANT_CMD_LINE_ARGS=%$
+goto doneStart
+
+:win9xStart
+rem Slurp the command line arguments. This loop allows for an unlimited number of
+rem arguments (up to the command line limit, anyway).
+
+set ANT_CMD_LINE_ARGS=
+
+:setupArgs
+if %1a==a goto doneStart
+set ANT_CMD_LINE_ARGS=%ANT_CMD_LINE_ARGS% %1
+shift
+goto setupArgs
+
+:doneStart
+rem This label provides a place for the argument list loop to break out
+rem and for NT handling to skip to.
+
+"%JAVA%" %ANT_OPTS% org.apache.tools.ant.Main -emacs %ANT_CMD_LINE_ARGS% bootstrap
+
+set ANT_CMD_LINE_ARGS=
+if not "%OS%"=="Windows_NT" goto mainEnd
+:winNTend
+@endlocal
+
+:mainEnd
+
+echo.
+echo ... Cleaning Up Build Directories
+
+if "%OS%" == "Windows_NT" if exist %CLASSDIR%\nul rmdir/s/q %CLASSDIR%
+if not "%OS%" == "Windows_NT" if exist %CLASSDIR%\nul deltree/y %CLASSDIR%
+
+echo.
+echo ... Done Bootstrapping Ant Distribution
+
+set JAVA=%OLDJAVA%
+set JAVAC=%OLDJAVAC%
+set CLASSPATH=%BOOTOLDCLASSPATH%
+set ANT_HOME=%OLDANTHOME%
+set OLDJAVA=
+set OLDJAVAC=
+set BOOTOLDCLASSPATH=
+set LOCALCLASSPATH=
+set OLDANTHOME=
+set TOOLS=
diff --git a/framework/src/ant/apache-ant-1.9.6/bootstrap.sh b/framework/src/ant/apache-ant-1.9.6/bootstrap.sh
new file mode 100755
index 00000000..60b6ece0
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/bootstrap.sh
@@ -0,0 +1,167 @@
+#!/bin/sh
+
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# OS specific support. $var _must_ be set to either true or false.
+cygwin=false;
+darwin=false;
+case "`uname`" in
+ CYGWIN*) cygwin=true ;;
+ Darwin*) darwin=true
+ if [ -z "$JAVA_HOME" ] ; then
+ JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Home
+ fi
+ ;;
+esac
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched
+if $cygwin ; then
+ [ -n "$JAVA_HOME" ] &&
+ JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+ [ -n "$CLASSPATH" ] &&
+ CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
+fi
+
+# You will need to specify JAVA_HOME if compiling with 1.2 or later.
+
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -f "$JAVA_HOME/lib/tools.jar" ] ; then
+ CLASSPATH=$CLASSPATH:$JAVA_HOME/lib/tools.jar
+ fi
+
+ if [ -f "$JAVA_HOME/lib/classes.zip" ] ; then
+ CLASSPATH=$CLASSPATH:$JAVA_HOME/lib/classes.zip
+ fi
+else
+ echo "Warning: JAVA_HOME environment variable not set."
+ echo " If build fails because sun.* classes could not be found"
+ echo " you will need to set the JAVA_HOME environment variable"
+ echo " to the installation directory of java."
+fi
+
+# IBM's JDK on AIX uses strange locations for the executables:
+# JAVA_HOME/jre/sh for java and rmid
+# JAVA_HOME/sh for javac and rmic
+if [ -z "$JAVAC" ] ; then
+ if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/sh/javac" ] ; then
+ JAVAC=${JAVA_HOME}/sh/javac;
+ else
+ JAVAC=${JAVA_HOME}/bin/javac;
+ fi
+ else
+ JAVAC=javac
+ fi
+fi
+if [ -z "$JAVACMD" ] ; then
+ if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ JAVACMD=$JAVA_HOME/jre/sh/java
+ else
+ JAVACMD=$JAVA_HOME/bin/java
+ fi
+ else
+ JAVACMD=java
+ fi
+fi
+
+if [ ! -x "$JAVACMD" ] ; then
+ echo "Error: JAVA_HOME is not defined correctly."
+ echo " We cannot execute $JAVACMD"
+ exit
+fi
+
+ANT_HOME=.
+export ANT_HOME
+
+echo ... Bootstrapping Ant Distribution
+
+if [ -d "bootstrap" ] ; then
+ rm -r bootstrap
+fi
+
+if [ -d "build" ] ; then
+ rm -r build
+fi
+
+DIRLIBS=lib/optional/*.jar
+for i in ${DIRLIBS}
+do
+ # if the directory is empty, then it will return the input string
+ # this is stupid, so case for it
+ if [ "$i" != "${DIRLIBS}" ] ; then
+ CLASSPATH=$CLASSPATH:"$i"
+ fi
+done
+
+TOOLS=src/main/org/apache/tools
+CLASSDIR=build/classes
+
+CLASSPATH=${CLASSDIR}:src/main:${CLASSPATH}
+
+# For Cygwin, switch to Windows format before running java
+if $cygwin; then
+ CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
+fi
+
+export CLASSPATH
+
+mkdir -p build
+mkdir -p ${CLASSDIR}
+mkdir -p bin
+
+echo ... Compiling Ant Classes
+
+"${JAVAC}" $BOOTJAVAC_OPTS -d ${CLASSDIR} ${TOOLS}/bzip2/*.java ${TOOLS}/tar/*.java ${TOOLS}/zip/*.java \
+ ${TOOLS}/ant/util/regexp/RegexpMatcher.java \
+ ${TOOLS}/ant/util/regexp/RegexpMatcherFactory.java \
+ ${TOOLS}/ant/property/*.java \
+ ${TOOLS}/ant/types/*.java \
+ ${TOOLS}/ant/types/resources/*.java \
+ ${TOOLS}/ant/*.java ${TOOLS}/ant/taskdefs/*.java \
+ ${TOOLS}/ant/taskdefs/compilers/*.java \
+ ${TOOLS}/ant/taskdefs/condition/*.java
+ret=$?
+if [ $ret != 0 ]; then
+ echo ... Failed compiling Ant classes !
+ exit $ret
+fi
+
+echo ... Copying Required Files
+
+cp src/main/org/apache/tools/ant/taskdefs/defaults.properties \
+ ${CLASSDIR}/org/apache/tools/ant/taskdefs
+cp src/main/org/apache/tools/ant/types/defaults.properties \
+ ${CLASSDIR}/org/apache/tools/ant/types
+cp src/script/antRun bin
+chmod +x bin/antRun
+
+echo ... Building Ant Distribution
+
+"${JAVACMD}" -classpath "${CLASSPATH}" -Dant.home=. $ANT_OPTS org.apache.tools.ant.Main -emacs "$@" bootstrap
+ret=$?
+if [ $ret != 0 ]; then
+ echo ... Failed Building Ant Distribution !
+ exit $ret
+fi
+
+
+echo ... Cleaning Up Build Directories
+
+rm -rf ${CLASSDIR}
+rm -rf bin
+
+echo ... Done Bootstrapping Ant Distribution
diff --git a/framework/src/ant/apache-ant-1.9.6/build.bat b/framework/src/ant/apache-ant-1.9.6/build.bat
new file mode 100644
index 00000000..254e0f66
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/build.bat
@@ -0,0 +1,40 @@
+@echo off
+
+REM Licensed to the Apache Software Foundation (ASF) under one or more
+REM contributor license agreements. See the NOTICE file distributed with
+REM this work for additional information regarding copyright ownership.
+REM The ASF licenses this file to You under the Apache License, Version 2.0
+REM (the "License"); you may not use this file except in compliance with
+REM the License. You may obtain a copy of the License at
+REM
+REM http://www.apache.org/licenses/LICENSE-2.0
+REM
+REM Unless required by applicable law or agreed to in writing, software
+REM distributed under the License is distributed on an "AS IS" BASIS,
+REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+REM See the License for the specific language governing permissions and
+REM limitations under the License.
+
+set REAL_ANT_HOME=%ANT_HOME%
+set ANT_HOME=%~dp0\bootstrap
+if exist bootstrap\lib\ant.jar if exist bootstrap\bin\ant.bat if exist bootstrap\bin\lcp.bat if exist bootstrap\bin\antRun.bat goto runAnt
+call bootstrap.bat
+if exist bootstrap\lib\ant.jar if exist bootstrap\bin\ant.bat if exist bootstrap\bin\lcp.bat if exist bootstrap\bin\antRun.bat goto runAnt
+echo Bootstrap FAILED
+REM set the error code
+color 00
+goto cleanup
+
+:runAnt
+if not "%REAL_ANT_HOME%" == "" goto install_ant
+call bootstrap\bin\ant.bat -lib lib/optional %1 %2 %3 %4 %5 %6 %7 %8 %9
+goto cleanup
+
+:install_ant
+call bootstrap\bin\ant.bat -nouserlib -lib lib/optional -Dant.install="%REAL_ANT_HOME%" %1 %2 %3 %4 %5 %6 %7 %8 %9
+
+rem clean up
+:cleanup
+set ANT_HOME=%REAL_ANT_HOME%
+set REAL_ANT_HOME=
+
diff --git a/framework/src/ant/apache-ant-1.9.6/build.sh b/framework/src/ant/apache-ant-1.9.6/build.sh
new file mode 100755
index 00000000..080562d8
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/build.sh
@@ -0,0 +1,57 @@
+#!/bin/sh
+
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# OS specific support. $var _must_ be set to either true or false.
+cygwin=false;
+darwin=false;
+case "`uname`" in
+ CYGWIN*) cygwin=true ;;
+ Darwin*) darwin=true
+ if [ -z "$JAVA_HOME" ] ; then
+ JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Home
+ fi
+ ;;
+esac
+
+REALANTHOME=$ANT_HOME
+if [ -z "$PWD" ]; then
+ ANT_HOME=./bootstrap
+else
+ ANT_HOME="$PWD"/bootstrap
+fi
+export ANT_HOME
+
+if test ! -f bootstrap/lib/ant.jar -o ! -x bootstrap/bin/ant -o ! -x bootstrap/bin/antRun ; then
+ /bin/sh ./bootstrap.sh
+fi
+
+if test ! -f bootstrap/lib/ant.jar -o ! -x bootstrap/bin/ant -o ! -x bootstrap/bin/antRun ; then
+ echo Bootstrap FAILED
+ exit 1
+fi
+
+if [ "$REALANTHOME" != "" ] ; then
+ if $cygwin; then
+ REALANTHOME=`cygpath --windows "$REALANTHOME"`
+ fi
+ ANT_INSTALL="-Dant.install=$REALANTHOME"
+else
+ ANT_INSTALL="-emacs"
+fi
+
+bootstrap/bin/ant -nouserlib -lib lib/optional "$ANT_INSTALL" $*
+
diff --git a/framework/src/ant/apache-ant-1.9.6/build.xml b/framework/src/ant/apache-ant-1.9.6/build.xml
new file mode 100644
index 00000000..b5fbfa93
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/build.xml
@@ -0,0 +1,2037 @@
+<?xml version="1.0"?>
+
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="apache-ant" default="main" basedir=".">
+
+ <!-- Give user a chance to override without editing this file
+ (and without typing -D on each invocation) -->
+ <property file=".ant.properties"/>
+ <property file="${user.home}/.ant.properties"/>
+ <property environment="env"/>
+
+
+ <!--
+ ===================================================================
+ Set the properties that control names and versions
+ ===================================================================
+ -->
+ <property name="Name" value="Apache Ant"/>
+ <property name="name" value="ant"/>
+ <!-- this is the groupId of ant in the Maven repository -->
+ <property name="groupid" value="org/apache/ant"/>
+ <property name="project.version" value="1.9.6"/>
+ <!-- pom.version is used when doing a distribution and must match with what is checked in under src/etc/poms -->
+ <property name="pom.version" value="1.9.6"/>
+ <property name="manifest-version" value="1.9.6"/>
+ <property name="bootstrap.jar" value="ant-bootstrap.jar"/>
+
+ <property name="ant.package" value="org/apache/tools/ant"/>
+ <property name="taskdefs.package" value="${ant.package}/taskdefs"/>
+ <property name="condition.package" value="${taskdefs.package}/condition"/>
+ <property name="optional.package" value="${taskdefs.package}/optional"/>
+ <property name="type.package" value="${ant.package}/types"/>
+ <property name="optional.type.package" value="${type.package}/optional"/>
+ <property name="apache.resolver.type.package" value="${ant.package}/types/resolver"/>
+ <property name="util.package" value="${ant.package}/util"/>
+ <property name="regexp.package" value="${util.package}/regexp"/>
+
+ <property name="optional.jars.prefix" value="ant"/>
+ <property name="optional.jars.whenmanifestonly" value="skip"/>
+
+ <!--
+ ===================================================================
+ Set the properties related to the source tree
+ ===================================================================
+ -->
+ <property name="src.dir" value="src"/>
+ <property name="java.dir" value="${src.dir}/main"/>
+ <property name="script.dir" value="${src.dir}/script"/>
+ <property name="lib.dir" value="lib"/>
+ <property name="manual.dir" value="manual"/>
+ <property name="etc.dir" value="${src.dir}/etc"/>
+ <property name="src.junit" value="${src.dir}/tests/junit"/>
+ <property name="src.antunit" value="${src.dir}/tests/antunit"/>
+ <property name="tests.etc.dir" value="${src.dir}/etc/testcases"/>
+ <property name="manifest" value="${src.dir}/etc/manifest"/>
+ <property name="resource.dir" value="${src.dir}/resources"/>
+
+ <!--
+ ===================================================================
+ Set the properties for the build area
+ ===================================================================
+ -->
+ <property name="build.dir" value="build"/>
+ <property name="bootstrap.dir" location="bootstrap"/>
+ <property name="build.classes" value="${build.dir}/classes"/>
+ <property name="build.lib" value="${build.dir}/lib"/>
+ <property name="build.lib-src" value="${build.dir}/lib-src"/>
+ <property name="build.javadocs" value="${build.dir}/javadocs"/>
+ <property name="build.tests" value="${build.dir}/testcases"/>
+ <property name="build.tests.javadocs" value="${build.dir}/javadocs.test/"/>
+ <property name="build.junit.xml" location="${build.tests}/xml"/>
+ <property name="build.junit.tmpdir" location="${build.tests}/tmp"/>
+ <property name="antunit.xml" location="${build.dir}/antunit/xml"/>
+ <property name="antunit.tmpdir" location="${build.dir}/antunit/tmp"/>
+ <property name="antunit.reports" location="${build.dir}/antunit/reports"/>
+ <property name="antunit.loglevel" value="none"/>
+ <property name="build.junit.reports" location="${build.tests}/reports"/>
+ <property name="manifest.tmp" value="${build.dir}/optional.manifest"/>
+ <!-- the absolute path -->
+ <property name="build.tests.value" location="${build.tests}"/>
+
+ <!--
+ ===================================================================
+ Set the properties that control various build options
+ ===================================================================
+ -->
+ <property name="debug" value="true"/>
+ <property name="chmod.fail" value="true"/>
+ <property name="chmod.maxparallel" value="250"/>
+ <property name="deprecation" value="false"/>
+ <property name="optimize" value="true"/>
+ <property name="javac.target" value="1.5"/>
+ <property name="javac.source" value="1.5"/>
+ <property name="junit.filtertrace" value="off"/>
+ <property name="junit.summary" value="no"/>
+ <property name="test.haltonfailure" value="false"/>
+ <property name="junit.fork" value="true"/>
+ <property name="junit.forkmode" value="once"/>
+ <condition property="junit.threads" value="2" else="0">
+ <and>
+ <equals arg1="${junit.fork}" arg2="true"/>
+ <equals arg1="${junit.forkmode}" arg2="perTest"/>
+ </and>
+ </condition>
+ <property name="expandproperty.files"
+ value="**/version.txt,**/defaultManifest.mf"/>
+ <property name="junit.collector.dir" value="${build.dir}/failingTests"/>
+ <property name="junit.collector.class" value="FailedTests"/>
+
+
+ <!--
+ ===================================================================
+ Set the paths used in the build
+ ===================================================================
+ -->
+ <path id="classpath">
+ <fileset dir="lib/optional" includes="*.jar"/>
+ </path>
+
+ <path id="tests-classpath">
+ <pathelement location="${build.classes}"/>
+ <path refid="classpath"/>
+ </path>
+ <path id="tests-runtime-classpath">
+ <path refid="tests-classpath"/>
+ <pathelement location="${build.tests}"/>
+ <!--
+ include the test source and test data dirs
+ so that we can pick resources via getResource(AsStream)
+ -->
+ <pathelement location="${src.junit}"/>
+ <pathelement location="${tests.etc.dir}"/>
+ <!-- Otherwise many tests fail with "com.sun.tools.javac.Main is not on the classpath.": -->
+ <pathelement location="${java.home}/../lib/tools.jar"/>
+ </path>
+
+ <!--
+ ===================================================================
+ Set up properties for the distribution area
+ ===================================================================
+ -->
+ <property name="dist.name" value="apache-${name}-${project.version}"/>
+ <property name="dist.base" value="distribution"/>
+ <property name="dist.base.source" value="${dist.base}/source"/>
+ <property name="dist.base.binaries" value="${dist.base}/binaries"/>
+ <property name="dist.base.manual" value="${dist.base}/manual"/>
+ <property name="dist.dir" location="dist"/>
+ <property name="dist.bin" value="${dist.dir}/bin"/>
+ <property name="dist.lib" value="${dist.dir}/lib"/>
+ <property name="dist.manual" value="${dist.dir}/manual"/>
+ <property name="dist.etc" value="${dist.dir}/etc"/>
+ <property name="dist.javadocs" value="${dist.dir}/manual/api"/>
+
+ <property name="src.dist.dir" value="dist-src"/>
+ <property name="src.dist.src" value="${src.dist.dir}/src"/>
+ <property name="src.dist.manual" value="${src.dist.dir}/manual"/>
+ <property name="src.dist.lib" value="${src.dist.dir}/lib"/>
+
+ <property name="java-repository.dir" value="java-repository/${groupid}"/>
+
+ <!--
+ ===================================================================
+ Set up selectors to be used by javac, junit and jar to exclude
+ files that have dependencies that are not available
+ ===================================================================
+ -->
+
+ <!-- Kaffe has some JDK 1.5 features including java.lang.Readable,
+ but not all of them -->
+ <selector id="not.in.kaffe">
+ <or>
+ <filename name="${condition.package}/IsReachable*"/>
+ </or>
+ </selector>
+
+ <selector id="needs.apache-resolver">
+ <filename name="${apache.resolver.type.package}/"/>
+ </selector>
+
+ <selector id="needs.junit">
+ <and>
+ <filename name="${optional.package}/junit/"/>
+ <not>
+ <or>
+ <filename name="${optional.package}/junit/JUnit4TestMethodAdapter*"/>
+ <filename name="${optional.package}/junit/CustomJUnit4TestAdapterCache*" />
+ </or>
+ </not>
+ </and>
+ </selector>
+
+ <selector id="needs.junit4">
+ <or>
+ <filename name="${optional.package}/junit/JUnit4TestMethodAdapter*"/>
+ <filename name="${optional.package}/junit/CustomJUnit4TestAdapterCache*" />
+ </or>
+ </selector>
+
+ <selector id="needs.apache-regexp">
+ <filename name="${regexp.package}/JakartaRegexp*"/>
+ </selector>
+
+ <selector id="needs.apache-oro">
+ <or>
+ <filename name="${regexp.package}/JakartaOro*"/>
+ </or>
+ </selector>
+
+ <selector id="needs.apache-bcel">
+ <or>
+ <filename name="${ant.package}/filters/util/JavaClassHelper*"/>
+ <filename name="${util.package}/depend/bcel/"/>
+ <filename name="${optional.type.package}/depend/ClassFileSetTest*"/>
+ </or>
+ </selector>
+
+ <selector id="needs.apache-log4j">
+ <filename name="${ant.package}/listener/Log4jListener*"/>
+ </selector>
+
+ <selector id="needs.commons-logging">
+ <filename name="${ant.package}/listener/CommonsLoggingListener*"/>
+ </selector>
+
+ <selector id="needs.apache-bsf">
+ <or>
+ <filename name="${util.package}/ScriptRunner.*"/>
+ <filename name="${util.package}/optional/ScriptRunner*"/>
+ </or>
+ </selector>
+
+ <selector id="needs.javamail">
+ <or>
+ <filename name="${ant.package}/taskdefs/email/MimeMailer*"/>
+ </or>
+ </selector>
+
+ <selector id="needs.netrexx">
+ <filename name="${optional.package}/NetRexxC*"/>
+ </selector>
+
+ <selector id="needs.commons-net">
+ <or>
+ <filename name="${optional.package}/net/FTP*"/>
+ <filename name="${optional.package}/net/RExec*"/>
+ <filename name="${optional.package}/net/TelnetTask*"/>
+ </or>
+ </selector>
+
+ <selector id="needs.antlr">
+ <filename name="${optional.package}/ANTLR*"/>
+ </selector>
+
+ <selector id="needs.jmf">
+ <filename name="${optional.package}/sound/"/>
+ </selector>
+
+ <selector id="needs.jai">
+ <or>
+ <filename name="${optional.package}/image/"/>
+ <filename name="${optional.type.package}/image/"/>
+ </or>
+ </selector>
+
+ <selector id="needs.jdepend">
+ <filename name="${optional.package}/jdepend/"/>
+ </selector>
+
+ <selector id="needs.swing">
+ <filename name="${optional.package}/splash/"/>
+ </selector>
+
+ <selector id="needs.jsch">
+ <filename name="${optional.package}/ssh/"/>
+ </selector>
+
+ <!-- needs TraceListenerEx3 interface implemented by PrintTraceListener -->
+ <selector id="needs.apache-xalan2">
+ <filename name="${optional.package}/Xalan2TraceSupport*"/>
+ </selector>
+
+ <selector id="ant.launcher">
+ <filename name="${ant.package}/launch/"/>
+ </selector>
+
+ <selector id="ant.core">
+ <not>
+ <or>
+ <selector refid="needs.antlr"/>
+ <selector refid="needs.apache-bcel"/>
+ <selector refid="needs.apache-bsf"/>
+ <selector refid="needs.apache-log4j"/>
+ <selector refid="needs.apache-oro"/>
+ <selector refid="needs.apache-regexp"/>
+ <selector refid="needs.apache-resolver"/>
+ <selector refid="needs.apache-xalan2"/>
+ <selector refid="needs.commons-logging"/>
+ <selector refid="needs.commons-net"/>
+ <selector refid="needs.jai"/>
+ <selector refid="needs.javamail"/>
+ <selector refid="needs.jdepend"/>
+ <selector refid="needs.jmf"/>
+ <selector refid="needs.jsch"/>
+ <selector refid="needs.junit"/>
+ <selector refid="needs.junit4"/>
+ <selector refid="needs.netrexx"/>
+ <selector refid="needs.swing"/>
+ <selector refid="ant.launcher"/>
+ </or>
+ </not>
+ </selector>
+
+ <patternset id="onlinetests">
+ <exclude name="**/GetTest.java" if="offline"/>
+ <exclude name="**/HttpTest.java" if="offline"/>
+ </patternset>
+
+ <patternset id="teststhatfail">
+ <!-- Property 'run.failing.tests' should force Ant to run these tests. -->
+ <!-- Because the whole patternset can not be excluded, you have to add -->
+ <!-- an unless-attribute on each exclude-element. -->
+ <exclude unless="run.failing.tests" name="${optional.package}/BeanShellScriptTest.java"/>
+ <exclude unless="run.failing.tests" name="${optional.package}/jdepend/JDependTest.java"/>
+ </patternset>
+
+ <!--tests that need an XML Schema-supporting parser to work-->
+ <selector id="needs.xmlschema">
+ <or>
+ <filename name="${optional.package}/SchemaValidateTest.*"/>
+ <filename name="${optional.package}/XmlValidateTest.*"/>
+ </or>
+ </selector>
+
+ <!--
+ ===================================================================
+ Set up a patternsets that matches the parts of our JUnit testsuite
+ that may be useful for task developers.
+ ===================================================================
+ -->
+ <patternset id="useful.tests">
+ <include name="${ant.package}/AntAssert*"/>
+ <include name="${ant.package}/BuildFileTest*"/>
+ <include name="${ant.package}/BuildFileRule*"/>
+ <include name="${ant.package}/FileUtilities*"/>
+ <include name="${regexp.package}/RegexpMatcherTest*"/>
+ <include name="${regexp.package}/RegexpTest*"/>
+ <include name="${optional.package}/AbstractXSLTLiaisonTest*"/>
+ <include name="${ant.package}/types/AbstractFileSetTest*"/>
+ </patternset>
+
+ <!--
+ ===================================================================
+ Check to see what optional dependencies are available
+ ===================================================================
+ -->
+ <target name="check_for_optional_packages">
+ <condition property="ignoresystemclasses">
+ <not>
+ <equals arg1="${build.sysclasspath}" arg2="only"/>
+ </not>
+ </condition>
+ <property name="ignoresystemclasses" value="false"/>
+ <available property="jdk1.6+" classname="java.net.CookieStore"/>
+ <available property="jdk1.7+" classname="java.nio.file.FileSystem"/>
+ <available property="jdk1.8+" classname="java.lang.reflect.Executable"/>
+ <condition property="jdk1.9+">
+ <contains string="${java.version}" substring="1.9."/>
+ </condition>
+ <available property="kaffe" classname="kaffe.util.NotImplemented"/>
+ <available property="harmony"
+ classname="org.apache.harmony.luni.util.Base64"/>
+ <available property="bsf.present"
+ classname="org.apache.bsf.BSFManager"
+ classpathref="classpath" ignoresystemclasses="${ignoresystemclasses}"/>
+ <available property="netrexx.present"
+ classname="netrexx.lang.Rexx"
+ classpathref="classpath" ignoresystemclasses="${ignoresystemclasses}"/>
+ <available property="apache.resolver.present"
+ classname="org.apache.xml.resolver.tools.CatalogResolver"
+ classpathref="classpath" ignoresystemclasses="${ignoresystemclasses}"/>
+ <available property="recent.xalan2.present"
+ classname="org.apache.xalan.trace.TraceListenerEx3"
+ classpathref="classpath" ignoresystemclasses="${ignoresystemclasses}"/>
+ <available property="junit.present"
+ classname="junit.framework.TestCase"
+ classpathref="classpath" ignoresystemclasses="${ignoresystemclasses}"/>
+ <available property="junit4.present"
+ classname="org.junit.Test"
+ classpathref="classpath" ignoresystemclasses="${ignoresystemclasses}"/>
+ <available property="antunit.present"
+ classname="org.apache.ant.antunit.AntUnit"
+ classpathref="classpath" ignoresystemclasses="${ignoresystemclasses}"/>
+ <available property="commons.net.present"
+ classname="org.apache.commons.net.ftp.FTPClient"
+ classpathref="classpath" ignoresystemclasses="${ignoresystemclasses}"/>
+ <available property="antlr.present"
+ classname="antlr.Tool"
+ classpathref="classpath" ignoresystemclasses="${ignoresystemclasses}"/>
+ <available property="apache.regexp.present"
+ classname="org.apache.regexp.RE"
+ classpathref="classpath" ignoresystemclasses="${ignoresystemclasses}"/>
+ <available property="apache.oro.present"
+ classname="org.apache.oro.text.regex.Perl5Matcher"
+ classpathref="classpath" ignoresystemclasses="${ignoresystemclasses}"/>
+ <available property="jmf.present"
+ classname="javax.sound.sampled.Clip"
+ classpathref="classpath"/>
+ <available property="jai.present"
+ classname="javax.media.jai.JAI"
+ classpathref="classpath" ignoresystemclasses="${ignoresystemclasses}"/>
+ <available property="jdepend.present"
+ classname="jdepend.framework.JDepend"
+ classpathref="classpath" ignoresystemclasses="${ignoresystemclasses}"/>
+ <available property="log4j.present"
+ classname="org.apache.log4j.Logger"
+ classpathref="classpath" ignoresystemclasses="${ignoresystemclasses}"/>
+ <available property="commons.logging.present"
+ classname="org.apache.commons.logging.LogFactory"
+ classpathref="classpath" ignoresystemclasses="${ignoresystemclasses}"/>
+ <available property="xalan.envcheck"
+ classname="org.apache.xalan.xslt.EnvironmentCheck"
+ classpathref="classpath" ignoresystemclasses="${ignoresystemclasses}"/>
+ <available property="which.present"
+ classname="org.apache.env.Which"
+ classpathref="classpath" ignoresystemclasses="${ignoresystemclasses}"/>
+
+ <available property="xerces.present"
+ classname="org.apache.xerces.parsers.SAXParser"
+ classpathref="classpath" ignoresystemclasses="${ignoresystemclasses}"/>
+ <available property="bcel.present"
+ classname="org.apache.bcel.Constants"
+ classpathref="classpath" ignoresystemclasses="${ignoresystemclasses}"/>
+
+ <condition property="javamail.complete">
+ <and>
+ <available classname="javax.activation.DataHandler"
+ classpathref="classpath"/>
+ <available classname="javax.mail.Transport"
+ classpathref="classpath" ignoresystemclasses="${ignoresystemclasses}"/>
+ </and>
+ </condition>
+
+ <condition property="tests.and.ant.share.classloader">
+ <or>
+ <equals arg1="${junit.fork}" arg2="true"/>
+ <equals arg1="${build.sysclasspath}" arg2="only"/>
+ </or>
+ </condition>
+
+ <condition property="sun.tools.present">
+ <and>
+ <available classname="sun.tools.native2ascii.Main"/>
+ <available classname="com.sun.tools.javah.Main"/>
+ </and>
+ </condition>
+
+ <condition property="tests.are.on.system.classpath">
+ <or>
+ <resourcecount count="1">
+ <intersect>
+ <path path="${java.class.path}" />
+ <file file="${build.tests}" />
+ </intersect>
+ </resourcecount>
+ <istrue value="${junit.fork}"/>
+ </or>
+ </condition>
+
+ <echo level="verbose"> tests.are.on.system.classpath=${tests.are.on.system.classpath}</echo>
+
+ <condition property="jasper.present">
+ <and>
+ <available classname="org.apache.jasper.compiler.Compiler"/>
+ <available classname="org.apache.jasper.JasperException"/>
+ </and>
+ </condition>
+
+ <condition property="swing.present">
+ <or>
+ <not>
+ <isset property="kaffe"/>
+ </not>
+ <available classname="javax.swing.ImageIcon"
+ classpathref="classpath"/>
+ </or>
+ </condition>
+
+ <!-- http client needs commons logging -->
+ <condition property="apache-httpclient.present">
+ <and>
+ <available
+ classname="org.apache.commons.httpclient.HttpClient"
+ classpathref="classpath" ignoresystemclasses="${ignoresystemclasses}"/>
+ <isset property="commons.logging.present"/>
+ </and>
+ </condition>
+
+ <available property="rhino.present"
+ classname="org.mozilla.javascript.Scriptable"
+ classpathref="classpath" ignoresystemclasses="${ignoresystemclasses}"/>
+ <available property="beanshell.present"
+ classname="bsh.StringUtil"
+ classpathref="classpath" ignoresystemclasses="${ignoresystemclasses}"/>
+ <available property="xerces1.present"
+ classname="org.apache.xerces.framework.XMLParser"
+ classpathref="classpath" ignoresystemclasses="${ignoresystemclasses}"/>
+ <available property="jsch.present"
+ classname="com.jcraft.jsch.Session"
+ classpathref="classpath" ignoresystemclasses="${ignoresystemclasses}"/>
+
+ <property name="build.compiler" value="modern"/>
+
+ <!--check for XSD support in the parser-->
+ <condition property="xmlschema.present">
+ <or>
+ <parsersupports
+ feature="http://apache.org/xml/features/validation/schema"/>
+ <parsersupports
+ feature="http://java.sun.com/xml/jaxp/properties/schemaSource"/>
+ </or>
+ </condition>
+
+ <!--
+ Java8 introduced a HTML checker 'doclint' which is very strict and breaks
+ the build if there is a HTML error in the JavaDoc.
+ -->
+ <condition
+ property="javadoc.doclint.none"
+ value="-Xdoclint:none"
+ else="">
+ <and>
+ <isset property="jdk1.8+"/>
+ <not><isset property="withDoclint"/></not>
+ </and>
+ </condition>
+ </target>
+
+
+ <!--
+ ===================================================================
+ Prepare the build
+ ===================================================================
+ -->
+ <target name="prepare">
+ <tstamp>
+ <format property="year" pattern="yyyy"/>
+ </tstamp>
+ <filterchain id="ant.filters">
+ <expandproperties/>
+ </filterchain>
+ </target>
+
+ <!--
+ ===================================================================
+ Build the code
+ ===================================================================
+ -->
+ <target name="build"
+ depends="prepare, check_for_optional_packages"
+ description="--> compiles the source code">
+ <mkdir dir="${build.dir}"/>
+ <mkdir dir="${build.classes}"/>
+ <mkdir dir="${build.lib}"/>
+
+ <javac srcdir="${java.dir}"
+ includeantruntime="false"
+ destdir="${build.classes}"
+ debug="${debug}"
+ deprecation="${deprecation}"
+ target="${javac.target}"
+ source="${javac.source}"
+ optimize="${optimize}">
+ <classpath refid="classpath"/>
+
+ <selector id="conditional-patterns">
+ <not>
+ <or>
+ <selector refid="not.in.kaffe" if="kaffe"/>
+
+ <selector refid="needs.apache-resolver" unless="apache.resolver.present"/>
+ <selector refid="needs.junit" unless="junit.present"/> <!-- TODO should perhaps use -source 1.4? -->
+ <selector refid="needs.junit4" unless="junit4.present"/>
+ <selector refid="needs.apache-regexp"
+ unless="apache.regexp.present"/>
+ <selector refid="needs.apache-oro" unless="apache.oro.present"/>
+ <selector refid="needs.apache-bcel" unless="bcel.present"/>
+ <selector refid="needs.apache-log4j" unless="log4j.present"/>
+ <selector refid="needs.commons-logging"
+ unless="commons.logging.present"/>
+ <selector refid="needs.apache-bsf" unless="bsf.present"/>
+ <selector refid="needs.javamail" unless="javamail.complete"/>
+ <selector refid="needs.netrexx" unless="netrexx.present"/>
+ <selector refid="needs.commons-net" unless="commons.net.present"/>
+ <selector refid="needs.antlr" unless="antlr.present"/>
+ <selector refid="needs.jmf" unless="jmf.present"/>
+ <selector refid="needs.jai" unless="jai.present"/>
+ <selector refid="needs.jdepend" unless="jdepend.present"/>
+ <selector refid="needs.swing" unless="swing.present"/>
+ <selector refid="needs.jsch" unless="jsch.present"/>
+ <selector refid="needs.xmlschema" unless="xmlschema.present"/>
+ <selector refid="needs.apache-xalan2"
+ unless="recent.xalan2.present"/>
+ </or>
+ </not>
+ </selector>
+ </javac>
+
+ <copy todir="${build.classes}">
+ <fileset dir="${java.dir}">
+ <include name="**/*.properties"/>
+ <include name="**/*.dtd"/>
+ <include name="**/*.xml"/>
+ </fileset>
+ <fileset dir="${resource.dir}" />
+ </copy>
+
+ <copy todir="${build.classes}"
+ overwrite="true" encoding="UTF-8">
+ <fileset dir="${java.dir}">
+ <include name="**/version.txt"/>
+ <include name="**/defaultManifest.mf"/>
+ </fileset>
+ <filterchain refid="ant.filters"/>
+ </copy>
+
+ <copy todir="${build.classes}/${optional.package}/junit/xsl">
+ <fileset dir="${etc.dir}">
+ <include name="junit-frames.xsl"/>
+ <include name="junit-noframes.xsl"/>
+ </fileset>
+ </copy>
+ </target>
+
+ <!--
+ ===================================================================
+ Create the all of the Apache Ant jars
+ ===================================================================
+ -->
+ <target name="jars"
+ depends="build"
+ description="--> creates the Apache Ant jars">
+
+ <copy todir="${build.dir}">
+ <fileset dir="${basedir}">
+ <include name="LICENSE"/>
+ <include name="LICENSE.xerces"/>
+ <include name="LICENSE.dom"/>
+ <include name="LICENSE.sax"/>
+ <include name="NOTICE"/>
+ </fileset>
+ <mapper type="glob" from="*" to="*.txt"/>
+ </copy>
+
+ <copy file="${manifest}" tofile="${manifest.tmp}"/>
+ <manifest file="${manifest.tmp}">
+ <section name="${optional.package}/">
+ <attribute name="Extension-name"
+ value="org.apache.tools.ant"/>
+ <attribute name="Specification-Title"
+ value="Apache Ant"/>
+ <attribute name="Specification-Version"
+ value="${manifest-version}"/>
+ <attribute name="Specification-Vendor"
+ value="Apache Software Foundation"/>
+ <attribute name="Implementation-Title"
+ value="org.apache.tools.ant"/>
+ <attribute name="Implementation-Version"
+ value="${manifest-version}"/>
+ <attribute name="Implementation-Vendor"
+ value="Apache Software Foundation"/>
+ </section>
+ </manifest>
+
+ <jar destfile="${build.lib}/${name}-launcher.jar"
+ basedir="${build.classes}"
+ whenmanifestonly="fail">
+ <selector refid="ant.launcher"/>
+ <metainf dir="${build.dir}">
+ <include name="LICENSE.txt"/>
+ <include name="NOTICE.txt"/>
+ </metainf>
+ <manifest>
+ <attribute name="Main-Class" value="org.apache.tools.ant.launch.Launcher"/>
+ </manifest>
+ </jar>
+
+ <jar destfile="${build.lib}/${name}.jar"
+ basedir="${build.classes}"
+ manifest="${manifest}"
+ whenmanifestonly="fail">
+ <!-- Verification: (cd dist/lib; for j in *.jar; do jar tf $j; done) | egrep -v '/$|META-INF/MANIFEST\.MF' | sort | uniq -d -->
+ <selector refid="ant.core"/>
+ <metainf dir="${build.dir}">
+ <include name="LICENSE.txt"/>
+ <include name="NOTICE.txt"/>
+ </metainf>
+
+ <manifest>
+ <section name="${ant.package}/">
+ <attribute name="Extension-name"
+ value="org.apache.tools.ant"/>
+ <attribute name="Specification-Title"
+ value="Apache Ant"/>
+ <attribute name="Specification-Version"
+ value="${manifest-version}"/>
+ <attribute name="Specification-Vendor"
+ value="Apache Software Foundation"/>
+ <attribute name="Implementation-Title"
+ value="org.apache.tools.ant"/>
+ <attribute name="Implementation-Version"
+ value="${manifest-version}"/>
+ <attribute name="Implementation-Vendor"
+ value="Apache Software Foundation"/>
+ </section>
+ </manifest>
+
+ <fileset dir="${manual.dir}">
+ <include name="images/ant_logo_large.gif"/>
+ </fileset>
+ </jar>
+
+ <jar destfile="${build.lib}/${bootstrap.jar}"
+ basedir="${build.classes}"
+ manifest="${manifest}"
+ whenmanifestonly="fail">
+ <include name="${ant.package}/Main.class"/>
+ <metainf dir="${build.dir}">
+ <include name="LICENSE.txt"/>
+ <include name="NOTICE.txt"/>
+ </metainf>
+ <manifest>
+ <attribute name="Class-Path"
+ value="ant.jar xalan.jar"/>
+ </manifest>
+ </jar>
+
+ <macrodef name="optional-jar">
+ <attribute name="dep"/>
+ <sequential>
+ <jar destfile="${build.lib}/${optional.jars.prefix}-@{dep}.jar"
+ basedir="${build.classes}"
+ manifest="${manifest.tmp}"
+ whenmanifestonly="${optional.jars.whenmanifestonly}">
+ <selector refid="needs.@{dep}"/>
+ <metainf dir="${build.dir}">
+ <include name="LICENSE.txt"/>
+ <include name="NOTICE.txt"/>
+ </metainf>
+ </jar>
+ </sequential>
+ </macrodef>
+
+ <optional-jar dep="apache-resolver"/>
+ <optional-jar dep="junit"/>
+ <optional-jar dep="junit4"/>
+ <optional-jar dep="apache-regexp"/>
+ <optional-jar dep="apache-oro"/>
+ <optional-jar dep="apache-bcel"/>
+ <optional-jar dep="apache-log4j"/>
+ <optional-jar dep="commons-logging"/>
+ <optional-jar dep="apache-bsf"/>
+ <optional-jar dep="javamail"/>
+ <optional-jar dep="netrexx"/>
+ <optional-jar dep="commons-net"/>
+ <optional-jar dep="antlr"/>
+ <optional-jar dep="jmf"/>
+ <optional-jar dep="jai"/>
+ <optional-jar dep="swing"/>
+ <optional-jar dep="jsch"/>
+ <optional-jar dep="jdepend"/>
+ <optional-jar dep="apache-xalan2"/>
+
+ </target>
+
+ <!-- Creates jar of test utility classes -->
+ <target name="test-jar"
+ depends="compile-tests"
+ description="--> creates the Apache Ant Test Utilities jar">
+
+ <fail unless="junit.present">
+ We cannot build the test jar unless JUnit is present,
+ as JUnit is needed to compile the test classes.
+ </fail>
+ <jar destfile="${build.lib}/${name}-testutil.jar"
+ basedir="${build.tests}">
+ <patternset refid="useful.tests"/>
+ <metainf dir="${build.dir}">
+ <include name="LICENSE.txt"/>
+ <include name="NOTICE.txt"/>
+ </metainf>
+ </jar>
+ </target>
+
+ <!--
+ ===================================================================
+ Create the all of the Apache Ant source jars
+ ===================================================================
+ -->
+ <target name="jars-sources" description="--> creates the Apache Ant source jars">
+ <mkdir dir="${build.lib-src}" />
+ <jar destfile="${build.lib-src}/${name}-launcher.jar"
+ basedir="${java.dir}"
+ whenmanifestonly="fail">
+ <selector refid="ant.launcher"/>
+ <metainf dir="${build.dir}">
+ <include name="LICENSE.txt"/>
+ <include name="NOTICE.txt"/>
+ </metainf>
+ </jar>
+
+ <jar destfile="${build.lib-src}/${name}.jar"
+ basedir="${java.dir}"
+ whenmanifestonly="fail">
+ <selector refid="ant.core"/>
+ <metainf dir="${build.dir}">
+ <include name="LICENSE.txt"/>
+ <include name="NOTICE.txt"/>
+ </metainf>
+ </jar>
+
+ <jar destfile="${build.lib-src}/${bootstrap.jar}"
+ basedir="${java.dir}"
+ whenmanifestonly="fail">
+ <include name="${ant.package}/Main.java"/>
+ <metainf dir="${build.dir}">
+ <include name="LICENSE.txt"/>
+ <include name="NOTICE.txt"/>
+ </metainf>
+ </jar>
+
+ <macrodef name="optional-src-jar">
+ <attribute name="dep"/>
+ <sequential>
+ <jar destfile="${build.lib-src}/${optional.jars.prefix}-@{dep}.jar"
+ basedir="${java.dir}"
+ whenmanifestonly="${optional.jars.whenmanifestonly}">
+ <selector refid="needs.@{dep}"/>
+ <metainf dir="${build.dir}">
+ <include name="LICENSE.txt"/>
+ <include name="NOTICE.txt"/>
+ </metainf>
+ </jar>
+ </sequential>
+ </macrodef>
+
+ <optional-src-jar dep="apache-resolver"/>
+ <optional-src-jar dep="junit"/>
+ <optional-src-jar dep="junit4"/>
+ <optional-src-jar dep="apache-regexp"/>
+ <optional-src-jar dep="apache-oro"/>
+ <optional-src-jar dep="apache-bcel"/>
+ <optional-src-jar dep="apache-log4j"/>
+ <optional-src-jar dep="commons-logging"/>
+ <optional-src-jar dep="apache-bsf"/>
+ <optional-src-jar dep="javamail"/>
+ <optional-src-jar dep="netrexx"/>
+ <optional-src-jar dep="commons-net"/>
+ <optional-src-jar dep="antlr"/>
+ <optional-src-jar dep="jmf"/>
+ <optional-src-jar dep="jai"/>
+ <optional-src-jar dep="swing"/>
+ <optional-src-jar dep="jsch"/>
+ <optional-src-jar dep="jdepend"/>
+ <optional-src-jar dep="apache-xalan2"/>
+
+ </target>
+
+ <target name="test-jar-source"
+ description="--> creates the Apache Ant Test Utilities source jar">
+ <mkdir dir="${build.lib-src}" />
+ <jar destfile="${build.lib-src}/${name}-testutil.jar"
+ basedir="${java.dir}">
+ <patternset refid="useful.tests" />
+ <metainf dir="${build.dir}">
+ <include name="LICENSE.txt"/>
+ <include name="NOTICE.txt"/>
+ </metainf>
+ </jar>
+ </target>
+
+ <!--
+ ===================================================================
+ Create the essential distribution that can run Apache Ant
+ ===================================================================
+ -->
+ <target name="dist-lite"
+ depends="jars,test-jar"
+ description="--> creates a minimum distribution to run Apache Ant">
+
+ <mkdir dir="${dist.dir}"/>
+ <mkdir dir="${dist.bin}"/>
+ <mkdir dir="${dist.lib}"/>
+
+ <copy todir="${dist.lib}">
+ <fileset dir="${build.lib}">
+ <exclude name="${bootstrap.jar}"/>
+ </fileset>
+ </copy>
+
+ <copy todir="${dist.lib}">
+ <fileset dir="${lib.dir}">
+ <include name="*.jar"/>
+ <include name="*.zip"/>
+ </fileset>
+ </copy>
+
+ <copy todir="${dist.bin}">
+ <fileset dir="${script.dir}"/>
+ </copy>
+
+ <fixcrlf srcdir="${dist.bin}" eol="dos" includes="*.bat,*.cmd"/>
+ <fixcrlf srcdir="${dist.bin}" eol="unix">
+ <include name="ant"/>
+ <include name="antRun"/>
+ <include name="*.pl"/>
+ </fixcrlf>
+
+ <chmod perm="ugo+rx" dir="${dist.dir}" type="dir" includes="**"
+ failonerror="${chmod.fail}"/>
+ <chmod perm="ugo+r" dir="${dist.dir}" type="file" includes="**"
+ failonerror="${chmod.fail}" maxparallel="${chmod.maxparallel}"/>
+ <chmod perm="ugo+x" type="file" failonerror="${chmod.fail}">
+ <fileset dir="${dist.bin}">
+ <include name="**/ant"/>
+ <include name="**/antRun"/>
+ <include name="**/*.pl"/>
+ <include name="**/*.py"/>
+ </fileset>
+ </chmod>
+
+ </target>
+
+ <!--
+ ===================================================================
+ Create the complete distribution
+ ===================================================================
+ -->
+ <target name="dist" description="--> creates a complete distribution">
+ <antcall inheritAll="false" target="internal_dist">
+ <param name="dist.dir" value="${dist.name}"/>
+ </antcall>
+ </target>
+
+ <target name="dist_javadocs" depends="javadocs" unless="javadoc.notrequired">
+ <mkdir dir="${dist.javadocs}"/>
+ <copy todir="${dist.javadocs}" overwrite="true">
+ <fileset dir="${build.javadocs}"/>
+ </copy>
+ </target>
+
+
+ <macrodef name="checksums-mvn" description="only md5 and sha1 are needed for the maven directory structure">
+ <element name="resources" implicit="true"/>
+ <sequential>
+ <checksum algorithm="md5">
+ <resources/>
+ </checksum>
+ <checksum algorithm="sha1">
+ <resources/>
+ </checksum>
+ </sequential>
+ </macrodef>
+ <macrodef name="checksums">
+ <element name="resources" implicit="true"/>
+ <sequential>
+ <checksums-mvn>
+ <resources/>
+ </checksums-mvn>
+ <checksum fileext=".sha512" algorithm="sha-512">
+ <resources/>
+ </checksum>
+ </sequential>
+ </macrodef>
+
+ <target name="internal_dist" depends="dist-lite,dist_javadocs">
+ <mkdir dir="${dist.manual}"/>
+ <mkdir dir="${dist.etc}"/>
+
+ <copy todir="${dist.lib}" file="${lib.dir}/README"/>
+ <copy todir="${dist.lib}" file="${lib.dir}/libraries.properties"/>
+
+ <copy todir="${dist.lib}">
+ <fileset dir="${src.dir}/etc/poms">
+ <include name="*/pom.xml"/>
+ </fileset>
+ <mapper type="regexp" from="^(.*)[/\\]pom.xml" to="\1.pom"/>
+ <filterchain>
+ <tokenfilter>
+ <replaceregex pattern="${pom.version}" replace="${project.version}"/>
+ </tokenfilter>
+ </filterchain>
+ </copy>
+ <copy todir="${dist.lib}">
+ <fileset dir="${src.dir}/etc/poms">
+ <include name="pom.xml"/>
+ </fileset>
+ <mapper type="glob" from="pom.xml" to="ant-parent.pom"/>
+ <filterchain>
+ <tokenfilter>
+ <replaceregex pattern="${pom.version}" replace="${project.version}"/>
+ </tokenfilter>
+ </filterchain>
+ </copy>
+
+
+ <copy todir="${dist.manual}">
+ <fileset dir="${manual.dir}" />
+ </copy>
+
+ <copy todir="${dist.dir}">
+ <fileset dir="${basedir}">
+ <include name="CONTRIBUTORS"/>
+ <include name="README"/>
+ <include name="INSTALL"/>
+ <include name="LICENSE"/>
+ <include name="LICENSE.xerces"/>
+ <include name="LICENSE.dom"/>
+ <include name="LICENSE.sax"/>
+ <include name="NOTICE"/>
+ <include name="TODO"/>
+ <include name="WHATSNEW"/>
+ <include name="KEYS"/>
+ <include name="contributors.xml"/>
+ <include name="fetch.xml"/>
+ <include name="get-m2.xml"/>
+ <include name="patch.xml"/>
+ </fileset>
+ </copy>
+
+ <chmod perm="ugo+rx" dir="${dist.dir}" type="dir" includes="**"
+ failonerror="${chmod.fail}"/>
+ <chmod perm="ugo+r" dir="${dist.dir}" type="file" includes="**"
+ failonerror="${chmod.fail}" maxparallel="${chmod.maxparallel}"/>
+ <chmod perm="ugo+x" type="file" failonerror="${chmod.fail}">
+ <fileset dir="${dist.bin}">
+ <include name="**/ant"/>
+ <include name="**/antRun"/>
+ <include name="**/*.pl"/>
+ <include name="**/*.py"/>
+ </fileset>
+ </chmod>
+
+ <!-- publish some useful stylesheets -->
+ <copy todir="${dist.etc}">
+ <fileset dir="${etc.dir}">
+ <include name="junit-frames.xsl"/>
+ <include name="junit-noframes.xsl"/>
+ <include name="junit-frames-xalan1.xsl"/>
+ <include name="coverage-frames.xsl"/>
+ <include name="maudit-frames.xsl"/>
+ <include name="mmetrics-frames.xsl"/>
+ <include name="changelog.xsl"/>
+ <include name="jdepend.xsl"/>
+ <include name="jdepend-frames.xsl"/>
+ <include name="checkstyle/*.xsl"/>
+ <include name="log.xsl"/>
+ <include name="tagdiff.xsl"/>
+ </fileset>
+ <fileset dir="${build.lib}">
+ <include name="${bootstrap.jar}"/>
+ </fileset>
+ </copy>
+
+ </target>
+
+
+ <!--
+ ===================================================================
+ Target to create bootstrap build
+ ===================================================================
+ -->
+ <target name="bootstrap" description="--> creates a bootstrap build">
+ <antcall inheritAll="false" target="dist-lite">
+ <param name="dist.dir" value="${bootstrap.dir}"/>
+ </antcall>
+ </target>
+
+
+ <!--
+ ===================================================================
+ Create the source distribution
+ ===================================================================
+ -->
+ <target name="src-dist"
+ description="--> creates a source distribution">
+
+ <mkdir dir="${src.dist.dir}"/>
+
+ <copy todir="${src.dist.lib}">
+ <fileset dir="${lib.dir}">
+ <include name="optional/junit*.jar"/>
+ <include name="optional/hamcrest*.jar"/>
+ <include name="README"/>
+ <include name="libraries.properties"/>
+ </fileset>
+ </copy>
+
+ <mkdir dir="${src.dist.lib}/optional"/>
+
+ <copy todir="${src.dist.src}">
+ <fileset dir="${src.dir}"/>
+ </copy>
+
+ <copy todir="${src.dist.manual}">
+ <fileset dir="${manual.dir}">
+ <exclude name="api/"/>
+ </fileset>
+ </copy>
+
+ <copy todir="${src.dist.dir}">
+ <fileset dir="${basedir}">
+ <include name="CONTRIBUTORS"/>
+ <include name="INSTALL"/>
+ <include name="KEYS"/>
+ <include name="LICENSE"/>
+ <include name="LICENSE.dom"/>
+ <include name="LICENSE.sax"/>
+ <include name="LICENSE.xerces"/>
+ <include name="NOTICE"/>
+ <include name="README"/>
+ <include name="TODO"/>
+ <include name="WHATSNEW"/>
+ <include name="bootstrap.bat"/>
+ <include name="bootstrap.sh"/>
+ <include name="build.bat"/>
+ <include name="build.sh"/>
+ <include name="build.xml"/>
+ <include name="contributors.xml"/>
+ <include name="fetch.xml"/>
+ <include name="get-m2.xml"/>
+ <include name="patch.xml"/>
+ </fileset>
+ </copy>
+
+ <fixcrlf srcdir="${src.dist.dir}" eol="dos" includes="*.bat,*.cmd"/>
+ <fixcrlf srcdir="${src.dist.dir}" eol="unix">
+ <include name="**/*.sh"/>
+ <include name="**/*.pl"/>
+ <include name="**/ant"/>
+ <include name="**/antRun"/>
+ </fixcrlf>
+ <fixcrlf srcdir="${src.dist.dir}">
+ <include name="**/*.java"/>
+ <exclude name="${tests.etc.dir}/taskdefs/fixcrlf/expected/Junk?.java"/>
+ <exclude name="${tests.etc.dir}/taskdefs/fixcrlf/input/Junk?.java"/>
+ </fixcrlf>
+
+ <chmod perm="ugo+x" dir="${src.dist.dir}" type="dir"
+ failonerror="${chmod.fail}"/>
+ <chmod perm="ugo+r" dir="${src.dist.dir}" failonerror="${chmod.fail}"/>
+ <chmod perm="ugo+x" failonerror="${chmod.fail}">
+ <fileset dir="${src.dist.dir}">
+ <include name="**/.sh"/>
+ <include name="**/.pl"/>
+ <include name="**/.py"/>
+ <include name="**/ant"/>
+ <include name="**/antRun"/>
+ </fileset>
+ </chmod>
+
+ </target>
+
+ <!--
+ ===================================================================
+ Create the binary distribution
+ ===================================================================
+ -->
+ <target name="-distribution_prep">
+ <delete dir="${dist.base}"/>
+ <delete dir="${dist.name}"/>
+ <delete dir="${java-repository.dir}"/>
+ <mkdir dir="${dist.base}"/>
+ <mkdir dir="${dist.base.source}"/>
+ <mkdir dir="${dist.base.binaries}"/>
+ <mkdir dir="${dist.base.manual}"/>
+ <mkdir dir="${java-repository.dir}"/>
+ <antcall inheritAll="false" target="internal_dist">
+ <param name="dist.dir" value="${dist.name}"/>
+ </antcall>
+ </target>
+
+ <target name="zip_distribution" depends="jars,-distribution_prep"
+ description="--> creates the zip distribution">
+ <zip destfile="${dist.base.binaries}/${dist.name}-bin.zip">
+ <zipfileset dir="${dist.name}/.." filemode="755">
+ <include name="${dist.name}/bin/ant"/>
+ <include name="${dist.name}/bin/antRun"/>
+ <include name="${dist.name}/bin/*.pl"/>
+ <include name="${dist.name}/bin/*.py"/>
+ </zipfileset>
+ <fileset dir="${dist.name}/..">
+ <include name="${dist.name}/"/>
+ <exclude name="${dist.name}/bin/ant"/>
+ <exclude name="${dist.name}/bin/antRun"/>
+ <exclude name="${dist.name}/bin/*.pl"/>
+ <exclude name="${dist.name}/bin/*.py"/>
+ </fileset>
+ </zip>
+ </target>
+
+ <condition property="buildosxpackage">
+ <and>
+ <os family="mac"/>
+ <isset property="buildosxpackage.required"/>
+ </and>
+ </condition>
+
+ <target name="pkg_distribution" depends="zip_distribution" if="buildosxpackage">
+ <exec executable="release/build-osx-pkg.py">
+ <arg value="--output-dir"/>
+ <arg value="${dist.base.binaries}"/>
+ <arg value="${dist.base.binaries}/${dist.name}-bin.zip"/>
+ </exec>
+ </target>
+
+ <target name="tar_distribution" depends="jars,-distribution_prep"
+ description="--> creates the tar distribution">
+ <tar longfile="gnu"
+ destfile="${dist.base.binaries}/${dist.name}-bin.tar">
+ <!-- removes redundant definition of permissions, but seems to
+ drop dirs (and to be slow)
+ <zipfileset src="${dist.base.binaries}/${dist.name}-bin.zip"/>
+ -->
+ <tarfileset dir="${dist.name}/.." mode="755" username="ant" group="ant">
+ <include name="${dist.name}/bin/ant"/>
+ <include name="${dist.name}/bin/antRun"/>
+ <include name="${dist.name}/bin/*.pl"/>
+ <include name="${dist.name}/bin/*.py"/>
+ </tarfileset>
+ <tarfileset dir="${dist.name}/.." username="ant" group="ant">
+ <include name="${dist.name}/"/>
+ <exclude name="${dist.name}/bin/ant"/>
+ <exclude name="${dist.name}/bin/antRun"/>
+ <exclude name="${dist.name}/bin/*.pl"/>
+ <exclude name="${dist.name}/bin/*.py"/>
+ </tarfileset>
+ </tar>
+ <gzip destfile="${dist.base.binaries}/${dist.name}-bin.tar.gz"
+ src="${dist.base.binaries}/${dist.name}-bin.tar"/>
+ <bzip2 destfile="${dist.base.binaries}/${dist.name}-bin.tar.bz2"
+ src="${dist.base.binaries}/${dist.name}-bin.tar"/>
+ <delete file="${dist.base.binaries}/${dist.name}-bin.tar"/>
+ </target>
+
+ <target name="main_distribution" depends="zip_distribution,pkg_distribution,tar_distribution,jars-sources,test-jar-source"
+ description="--> creates the zip, pkg, and tar distributions">
+
+ <copy todir="${java-repository.dir}">
+ <fileset dir="${dist.name}/lib">
+ <include name="ant*.jar"/>
+ </fileset>
+ <mapper type="regexp" from="ant(.*).jar" to="ant\1/${project.version}/ant\1-${project.version}.jar"/>
+ </copy>
+ <copy todir="${java-repository.dir}">
+ <fileset dir="${dist.name}/lib">
+ <include name="*.pom"/>
+ </fileset>
+ <mapper>
+ <mapper type="regexp" from="ant(.*).pom" to="ant\1/${project.version}/ant\1-${project.version}.pom"/>
+ </mapper>
+ </copy>
+ <copy todir="${java-repository.dir}">
+ <fileset dir="${build.lib-src}">
+ <include name="ant*.jar"/>
+ </fileset>
+ <mapper type="regexp" from="ant(.*).jar" to="ant\1/${project.version}/ant\1-${project.version}-sources.jar"/>
+ </copy>
+ <jar destfile="${java-repository.dir}/ant/${project.version}/ant-${project.version}-javadoc.jar"
+ basedir="${build.javadocs}">
+ <metainf dir="${build.dir}">
+ <include name="LICENSE.txt"/>
+ <include name="NOTICE.txt"/>
+ </metainf>
+ </jar>
+ <checksums-mvn>
+ <fileset dir="${java-repository.dir}" includes="**/*${project.version}.jar"/>
+ <fileset dir="${java-repository.dir}" includes="**/*${project.version}-sources.jar"/>
+ <fileset dir="${java-repository.dir}" includes="**/*${project.version}-javadoc.jar"/>
+ <fileset dir="${java-repository.dir}" includes="**/*${project.version}.pom"/>
+ </checksums-mvn>
+
+ <zip destfile="${dist.base.manual}/${dist.name}-manual.zip">
+ <zipfileset dir="${dist.name}/manual" prefix="${dist.name}"/>
+ <zipfileset file="NOTICE" prefix="${dist.name}"/>
+ </zip>
+ <tar longfile="gnu"
+ destfile="${dist.base.manual}/${dist.name}-manual.tar">
+ <tarfileset dir="${dist.name}/manual" prefix="${dist.name}"/>
+ <tarfileset file="NOTICE" prefix="${dist.name}"/>
+ </tar>
+ <gzip destfile="${dist.base.manual}/${dist.name}-manual.tar.gz"
+ src="${dist.base.manual}/${dist.name}-manual.tar"/>
+ <bzip2 destfile="${dist.base.manual}/${dist.name}-manual.tar.bz2"
+ src="${dist.base.manual}/${dist.name}-manual.tar"/>
+ <delete file="${dist.base.manual}/${dist.name}-manual.tar"/>
+
+ <delete dir="${dist.name}"/>
+ <checksums>
+ <fileset dir="${dist.base.binaries}/">
+ <exclude name="**/*.asc"/>
+ <exclude name="**/*.md5"/>
+ <exclude name="**/*.sha1"/>
+ <exclude name="**/*.sha512"/>
+ </fileset>
+ <fileset dir="${dist.base.manual}/">
+ <exclude name="**/*.asc"/>
+ <exclude name="**/*.md5"/>
+ <exclude name="**/*.sha1"/>
+ <exclude name="**/*.sha512"/>
+ </fileset>
+ </checksums>
+
+ <antcall inheritAll="false" target="src-dist">
+ <param name="src.dist.dir" value="${dist.name}"/>
+ </antcall>
+ <zip destfile="${dist.base.source}/${dist.name}-src.zip">
+ <zipfileset dir="${dist.name}/.." filemode="755">
+ <include name="${dist.name}/bootstrap.sh"/>
+ <include name="${dist.name}/build.sh"/>
+ </zipfileset>
+ <fileset dir="${dist.name}/..">
+ <include name="${dist.name}/"/>
+ <exclude name="${dist.name}/bootstrap.sh"/>
+ <exclude name="${dist.name}/build.sh"/>
+ </fileset>
+ </zip>
+ <tar longfile="gnu"
+ destfile="${dist.base.source}/${dist.name}-src.tar">
+ <!--
+ <zipfileset src="${dist.base.source}/${dist.name}-src.zip"/>
+ -->
+ <tarfileset dir="${dist.name}/.." mode="755" username="ant" group="ant">
+ <include name="${dist.name}/bootstrap.sh"/>
+ <include name="${dist.name}/build.sh"/>
+ </tarfileset>
+ <tarfileset dir="${dist.name}/.." username="ant" group="ant">
+ <include name="${dist.name}/"/>
+ <exclude name="${dist.name}/bootstrap.sh"/>
+ <exclude name="${dist.name}/build.sh"/>
+ </tarfileset>
+ </tar>
+ <gzip destfile="${dist.base.source}/${dist.name}-src.tar.gz"
+ src="${dist.base.source}/${dist.name}-src.tar"/>
+ <bzip2 destfile="${dist.base.source}/${dist.name}-src.tar.bz2"
+ src="${dist.base.source}/${dist.name}-src.tar"/>
+ <delete file="${dist.base.source}/${dist.name}-src.tar"/>
+ <delete dir="${dist.name}"/>
+ <checksums>
+ <fileset dir="${dist.base.source}/">
+ <exclude name="**/*.asc"/>
+ <exclude name="**/*.md5"/>
+ <exclude name="**/*.sha1"/>
+ <exclude name="**/*.sha512"/>
+ </fileset>
+ </checksums>
+ </target>
+
+ <target name="distribution" depends="main_distribution"
+ description="--> creates the full Apache Ant distribution">
+ </target>
+
+ <!--
+ ===================================================================
+ Cleans up build and distribution directories
+ ===================================================================
+ -->
+ <target name="clean"
+ description="--> cleans up build and dist directories">
+ <delete dir="${build.dir}"/>
+ <delete dir="${dist.base}"/>
+ <delete dir="${dist.dir}"/>
+ <delete>
+ <fileset dir="." includes="**/*~" defaultexcludes="no"/>
+ </delete>
+ </target>
+
+ <!--
+ ===================================================================
+ Cleans everything
+ ===================================================================
+ -->
+ <target name="allclean"
+ depends="clean"
+ description="--> cleans up everything">
+ <delete file="${bootstrap.dir}/bin/antRun"/>
+ <delete file="${bootstrap.dir}/bin/antRun.bat"/>
+ <delete file="${bootstrap.dir}/bin/*.pl"/>
+ <delete file="${bootstrap.dir}/bin/*.py"/>
+ </target>
+
+ <!--
+ ===================================================================
+ Installs Apache Ant
+ ===================================================================
+ -->
+ <target name="install">
+ <fail message="You must set the property ant.install=/where/to/install" unless="ant.install"/>
+ <antcall inheritAll="false" target="internal_dist">
+ <param name="dist.dir" value="${ant.install}"/>
+ </antcall>
+ </target>
+
+ <target name="install-lite">
+ <fail message="You must set the property ant.install=/where/to/install" unless="ant.install"/>
+ <antcall inheritAll="false" target="dist-lite">
+ <param name="dist.dir" value="${ant.install}"/>
+ </antcall>
+ </target>
+
+ <!--
+ ===================================================================
+ Creates the API documentation
+ ===================================================================
+ -->
+ <target name="javadoc_check">
+ <uptodate property="javadoc.notrequired"
+ targetfile="${build.javadocs}/packages.html">
+ <srcfiles dir="${java.dir}" includes="**/*.java"/>
+ </uptodate>
+ <uptodate property="tests.javadoc.notrequired"
+ targetfile="${build.tests.javadocs}/packages.html">
+ <srcfiles dir="${src.junit}">
+ <patternset refid="useful.tests"/>
+ </srcfiles>
+ </uptodate>
+ </target>
+
+ <target name="javadocs" depends="prepare, javadoc_check, check_for_optional_packages"
+ description="--> creates the API documentation" unless="javadoc.notrequired">
+ <mkdir dir="${build.javadocs}"/>
+ <javadoc useexternalfile="yes"
+ maxmemory="1000M"
+ destdir="${build.javadocs}"
+ author="true"
+ version="true"
+ locale="en"
+ windowtitle="${Name} API"
+ doctitle="${Name}"
+ failonerror="true"
+ verbose="${javadoc.verbose}"
+ additionalparam="${javadoc.doclint.none}">
+
+ <packageset dir="${java.dir}"/>
+
+ <!-- hide some meta information for javadoc -->
+ <tag name="todo" description="To do:" scope="all"/>
+ <tag name="ant.task" enabled="false" description="Task:" scope="types"/>
+ <tag name="ant.datatype" enabled="false" description="Data type:" scope="types"/>
+ <tag name="ant.attribute" enabled="false" description="Attribute:" scope="types"/>
+ <tag name="ant.attribute.group" enabled="false" description="Attribute group:" scope="types"/>
+ <tag name="ant.element" enabled="false" description="Nested element:" scope="types"/>
+ <group title="Apache Ant Core" packages="org.apache.tools.ant*"/>
+ <group title="Core Tasks" packages="org.apache.tools.ant.taskdefs*"/>
+ <group title="Core Types" packages="org.apache.tools.ant.types*"/>
+ <group title="Optional Tasks" packages="org.apache.tools.ant.taskdefs.optional*"/>
+ <group title="Optional Types" packages="org.apache.tools.ant.types.optional*"/>
+ <group title="Ant Utilities" packages="org.apache.tools.ant.util*"/>
+ <classpath refid="tests-classpath"/>
+ </javadoc>
+ </target>
+
+ <target name="test-javadocs" depends="prepare, javadoc_check"
+ unless="tests.javadoc.notrequired"
+ description="--> creates the API documentation for test utilities">
+ <mkdir dir="${build.tests.javadocs}"/>
+ <javadoc useexternalfile="yes"
+ destdir="${build.tests.javadocs}"
+ failonerror="true"
+ author="true"
+ version="true"
+ locale="en"
+ windowtitle="${Name} Test Utilities"
+ doctitle="${Name}"
+ additionalparam="${javadoc.doclint.none}">
+
+ <!-- hide some meta information for javadoc -->
+ <tag name="pre" description="Precondition:" scope="all"/>
+
+ <fileset dir="${src.junit}">
+ <patternset refid="useful.tests"/>
+ </fileset>
+ <classpath refid="tests-classpath"/>
+ </javadoc>
+ </target>
+
+ <!--
+ ===================================================================
+ Compile testcases
+ ===================================================================
+ -->
+ <target name="compile-tests" depends="build" if="junit.present">
+ <mkdir dir="${build.tests}"/>
+
+ <javac srcdir="${src.junit}"
+ includeantruntime="false"
+ destdir="${build.tests}"
+ debug="${debug}"
+ target="${javac.target}"
+ source="${javac.source}"
+ deprecation="${deprecation}">
+ <classpath refid="tests-classpath"/>
+
+ <selector refid="conditional-patterns"/>
+ </javac>
+
+ <!-- Used by AntlibTest.testAntlibResource: -->
+ <jar jarfile="${build.tests}/org/apache/tools/ant/taskdefs/test2-antlib.jar">
+ <manifest>
+ <attribute name="Extension-name"
+ value="org.apache.tools.ant"/>
+ <attribute name="Specification-Title"
+ value="Apache Ant"/>
+ <attribute name="Specification-Version"
+ value="${manifest-version}"/>
+ <attribute name="Specification-Vendor"
+ value="Apache Software Foundation"/>
+ <attribute name="Implementation-Title"
+ value="org.apache.tools.ant"/>
+ <attribute name="Implementation-Version"
+ value="${manifest-version}"/>
+ <attribute name="Implementation-Vendor"
+ value="Apache Software Foundation"/>
+ </manifest>
+ <zipfileset dir="${tests.etc.dir}" fullpath="taskdefs/test.antlib.xml">
+ <include name="taskdefs/test2.antlib.xml"/>
+ </zipfileset>
+ </jar>
+ </target>
+
+ <target name="dump-info" depends="dump-sys-properties,run-which"/>
+
+ <target name="dump-sys-properties" unless="which.present"
+ depends="xml-check">
+ <echo message="java.vm.info=${java.vm.info}"/>
+ <echo message="java.vm.name=${java.vm.name}"/>
+ <echo message="java.vm.vendor=${java.vm.vendor}"/>
+ <echo message="java.vm.version=${java.vm.version}"/>
+ <echo message="os.arch=${os.arch}"/>
+ <echo message="os.name=${os.name}"/>
+ <echo message="os.version=${os.version}"/>
+ <echo message="file.encoding=${file.encoding}"/>
+ <echo message="user.language=${user.language}"/>
+ <echo message="ant.version=${ant.version}"/>
+ </target>
+
+ <!-- helper class from Xalan2 to check for jar versioning of xml/xsl processors -->
+ <target name="xml-check" depends="check_for_optional_packages"
+ if="xalan.envcheck" unless="which.present">
+ <java classname="org.apache.xalan.xslt.EnvironmentCheck"/>
+ </target>
+
+ <target name="run-which" depends="check_for_optional_packages"
+ if="which.present">
+ <java classname="org.apache.env.Which" taskname="which" classpathref="classpath"/>
+ </target>
+
+ <!-- test to see if we are online or not. can take a while when we are off line, so
+ setting the property is a good shortcut-->
+ <target name="probe-offline">
+ <condition property="offline">
+ <or>
+ <isset property="offline"/>
+ <not>
+ <http url="http://www.apache.org/"/>
+ </not>
+ </or>
+ </condition>
+ <echo level="verbose"> offline=${offline}</echo>
+ </target>
+
+ <!--
+ ===================================================================
+ Run testcase
+ ===================================================================
+ -->
+
+ <target name="check-failed">
+ <condition property="tests.failed">
+ <or>
+ <isset property="junit.failed" />
+ <isset property="antunit.failed" />
+ </or>
+ </condition>
+ </target>
+
+ <target name="test" description="--> run unit tests and reports"
+ depends="dump-info,junit-report,antunit-report,check-failed">
+ <fail if="tests.failed" unless="ignore.tests.failed">Unit tests failed; see:
+${build.junit.reports}
+${antunit.reports}
+ </fail>
+ </target>
+
+ <target name="run-tests" depends="dump-info,junit-tests,antunit-tests,check-failed"
+ description="--> run unit tests without reports">
+ <fail if="tests.failed" message="Unit tests failed" />
+ </target>
+
+ <target name="test-init" depends="probe-offline,check_for_optional_packages">
+ <mkdir dir="${build.junit.tmpdir}"/>
+ <macrodef name="test-junit">
+ <element name="junit-nested" implicit="true" />
+ <sequential>
+ <!-- Delete 'old' collector classes -->
+ <delete failonerror="false">
+ <fileset dir="${junit.collector.dir}" includes="${junit.collector.class}*.class"/>
+ </delete>
+ <!-- compile the FailedTests class if present -->
+ <mkdir dir="${junit.collector.dir}"/>
+ <!-- FIXME: removed junit collector build code
+ <javac srcdir="${junit.collector.dir}" destdir="${junit.collector.dir}">
+ <classpath id="failure.cp">
+ <pathelement location="${build.classes}"/>
+ <pathelement location="${build.tests}"/>
+ </classpath>
+ </javac>
+ -->
+ <available file="${junit.collector.dir}/${junit.collector.class}.class"
+ property="hasFailingTests"/>
+ <!-- run the tests -->
+ <mkdir dir="${build.junit.xml}" />
+ <property name="test.junit.vmargs" value=""/>
+ <property name="ant.junit.failureCollector"
+ value="${junit.collector.dir}/${junit.collector.class}"/>
+ <!-- TODO includeantruntime="false" does not solve "multiple versions of ant detected in path for junit" warning -->
+ <junit printsummary="${junit.summary}"
+ haltonfailure="${test.haltonfailure}"
+ fork="${junit.fork}"
+ forkmode="${junit.forkmode}"
+ threads="${junit.threads}"
+ failureproperty="junit.failed"
+ errorproperty="junit.failed"
+ filtertrace="${junit.filtertrace}">
+ <sysproperty key="ant.home" value="${ant.home}"/>
+ <sysproperty key="build.tests" file="${build.tests}"/>
+ <sysproperty key="build.tests.value" value="${build.tests.value}"/>
+ <sysproperty key="offline" value="${offline}"/>
+ <sysproperty key="tests-classpath.value"
+ value="${toString:tests-runtime-classpath}"/>
+ <sysproperty key="root" file="${basedir}"/>
+ <sysproperty key="build.compiler" value="${build.compiler}"/>
+ <sysproperty key="tests.and.ant.share.classloader"
+ value="${tests.and.ant.share.classloader}"/>
+ <sysproperty key="java.io.tmpdir" file="${build.junit.tmpdir}"/>
+ <classpath>
+ <path refid="tests-runtime-classpath"/>
+ <pathelement location="${junit.collector.dir}"/>
+ <!-- FIXME: remove failure collector build code for the moment
+ <path refid="failure.cp"/>
+ -->
+ </classpath>
+ <!-- FIXME: remove failure collector build code for the moment
+ <formatter type="failure" usefile="false"/>
+ -->
+ <formatter type="xml"/>
+ <jvmarg line="${test.junit.vmargs}"/>
+ <!-- FIXME: remove failure collector build code for the moment
+ <test name="${junit.collector.class}" if="hasFailingTests"/>
+ -->
+ <junit-nested />
+ </junit>
+ </sequential>
+ </macrodef>
+
+ <fail>"testcase" cannot be specified with "junit.testcase" or "antunit.testcase".
+ <condition>
+ <and>
+ <isset property="testcase" />
+ <or>
+ <isset property="antunit.testcase" />
+ <isset property="junit.testcase" />
+ </or>
+ </and>
+ </condition>
+ </fail>
+
+ <condition property="antunit.testcase" value="${testcase}">
+ <available file="${src.antunit}/${testcase}" />
+ </condition>
+
+ <condition property="junit.testcase" value="${testcase}">
+ <available classname="${testcase}" classpathref="tests-runtime-classpath" ignoresystemclasses="${ignoresystemclasses}"/>
+ </condition>
+
+ <fail>Cannot locate test ${testcase}
+ <condition>
+ <and>
+ <isset property="testcase" />
+ <not>
+ <or>
+ <isset property="antunit.testcase" />
+ <isset property="junit.testcase" />
+ </or>
+ </not>
+ </and>
+ </condition>
+ </fail>
+
+ <condition property="run.junit">
+ <and>
+ <not><equals arg1="${testcase}" arg2="${antunit.testcase}" /></not>
+ <isset property="junit.present" />
+ <available file="${src.junit}" />
+ </and>
+ </condition>
+
+ <condition property="junit.single">
+ <and>
+ <isset property="junit.testcase" />
+ <isset property="run.junit" />
+ </and>
+ </condition>
+
+ <condition property="junit.batch">
+ <and>
+ <not><isset property="junit.testcase" /></not>
+ <isset property="run.junit" />
+ </and>
+ </condition>
+
+ <condition property="run.antunit">
+ <and>
+ <not><equals arg1="${testcase}" arg2="${junit.testcase}" /></not>
+ <isset property="antunit.present" />
+ <available file="${src.antunit}" />
+ </and>
+ </condition>
+
+ <condition property="run.antunit.report">
+ <isset property="run.antunit" />
+ </condition>
+
+ <condition property="run.junit.report">
+ <isset property="run.junit" />
+ </condition>
+ </target>
+
+ <target name="junit-report" depends="junit-tests,junit-report-only" />
+
+ <target name="junit-report-only" depends="test-init" if="${run.junit.report}">
+ <mkdir dir="${build.junit.reports}" />
+ <junitreport todir="${build.junit.reports}">
+ <fileset dir="${build.junit.xml}">
+ <include name="TEST-*.xml"/>
+ </fileset>
+ <report format="frames" todir="${build.junit.reports}"/>
+ </junitreport>
+ </target>
+
+ <target name="junit-tests" depends="junit-batch,junit-single-test" />
+
+ <target name="junit-batch" depends="compile-tests,test-init"
+ if="junit.batch">
+
+ <property name="junit.includes" value="**/*Test*" />
+ <property name="junit.excludes" value="" />
+
+ <test-junit>
+ <formatter type="brief" usefile="false"/>
+
+ <batchtest todir="${build.junit.xml}" unless="hasFailingTests">
+ <fileset dir="${src.junit}"
+ includes="${junit.includes}" excludes="${junit.excludes}">
+
+ <!-- abstract classes, not testcases -->
+ <exclude name="${taskdefs.package}/TaskdefsTest.java"/>
+ <exclude name="${ant.package}/BuildFileTest.java"/>
+ <exclude name="${regexp.package}/RegexpMatcherTest.java"/>
+ <exclude name="${regexp.package}/RegexpTest.java"/>
+ <exclude name="${optional.package}/AbstractXSLTLiaisonTest.java"/>
+ <exclude name="${ant.package}/types/AbstractFileSetTest.java"/>
+ <exclude name="${ant.package}/types/selectors/BaseSelectorTest.java"/>
+
+ <!-- helper classes, not testcases -->
+ <exclude name="org/example/"/>
+ <exclude name="${taskdefs.package}/TaskdefTest*Task.java"/>
+ <exclude name="${optional.package}/junit/TestFormatter.java"/>
+
+ <!-- interactive tests -->
+ <exclude name="${taskdefs.package}/TestProcess.java"/>
+ <exclude name="${optional.package}/splash/SplashScreenTest.java"/>
+
+ <!-- only run these tests if their required libraries are
+ installed -->
+ <selector refid="conditional-patterns"/>
+
+ <!-- tests excluded if the test is run in offline mode -->
+ <patternset refid="onlinetests"/>
+
+ <!-- failing tests excluded unless run.failing.tests is set -->
+ <patternset refid="teststhatfail"/>
+
+ <!-- needs BSF to work -->
+ <exclude name="${optional.package}/Rhino*.java"
+ unless="bsf.present"/>
+ <exclude name="${optional.package}/Rhino*.java"
+ unless="rhino.present"/>
+ <exclude name="${optional.package}/script/*.java"
+ unless="bsf.present"/>
+ <exclude name="${optional.package}/script/*.java"
+ unless="rhino.present"/>
+ <exclude name="${optional.package}/BeanShellScriptTest.java"
+ unless="bsf.present"/>
+ <exclude name="${optional.package}/BeanShellScriptTest.java"
+ unless="beanshell.present"/>
+ <exclude name="${optional.type.package}/Script*.java"
+ unless="bsf.present"/>
+ <exclude name="${optional.type.package}/Script*.java"
+ unless="rhino.present"/>
+
+ <!-- fail if testcases can be loaded from the system classloader -->
+ <exclude name="${ant.package}/AntClassLoaderDelegationTest.java"
+ if="tests.are.on.system.classpath"/>
+ <exclude name="${optional.package}/junit/JUnitClassLoaderTest.java"
+ if="tests.are.on.system.classpath"/>
+
+ <!-- these tests need to be localised before being ran???? -->
+ <exclude name="${optional.package}/PvcsTest.java"/>
+
+ <exclude name="${optional.package}/junit/JUnitReportTest.java"
+ unless="run.junitreport"/>
+
+ <!-- needs xerces to work -->
+ <exclude name="${ant.package}/IncludeTest.java"
+ unless="xerces1.present"/>
+ <exclude name="${type.package}/selectors/ModifiedSelectorTest.java"
+ unless="xerces1.present"/>
+
+ <!-- needs resolver.jar to work -->
+ <exclude name="${optional.package}/XmlValidateCatalogTest.java"
+ unless="apache.resolver.present"/>
+
+ <!-- needs jasperc -->
+ <exclude name="${optional.package}/JspcTest.java"
+ unless="jasper.present"/>
+
+ <!-- These tests only passes if testcases and Ant classes have
+ been loaded by the same classloader - will throw
+ IllegalAccessExceptions otherwise. -->
+ <exclude name="${taskdefs.package}/SQLExecTest.java"
+ unless="tests.and.ant.share.classloader"/>
+ <exclude name="${taskdefs.package}/cvslib/ChangeLogWriterTest.java"
+ unless="tests.and.ant.share.classloader"/>
+ <exclude name="${taskdefs.package}/cvslib/ChangeLogParserTest.java"
+ unless="tests.and.ant.share.classloader"/>
+ <exclude name="${optional.package}/sos/SOSTest.java"
+ unless="tests.and.ant.share.classloader"/>
+ <exclude name="${optional.package}/vss/MSVSSTest.java"
+ unless="tests.and.ant.share.classloader"/>
+ <exclude name="${optional.package}/TraXLiaisonTest.java"
+ unless="tests.and.ant.share.classloader"/>
+ <exclude name="${taskdefs.package}/ProcessDestroyerTest.java"
+ unless="tests.and.ant.share.classloader"/>
+ <exclude name="${taskdefs.package}/ProtectedJarMethodsTest.java"
+ unless="tests.and.ant.share.classloader"/>
+ <exclude name="${ant.package}/launch/LocatorTest.java"
+ unless="tests.and.ant.share.classloader"/>
+ <exclude name="${ant.package}/DefaultLoggerTest.java"
+ unless="tests.and.ant.share.classloader"/>
+ <exclude name="${taskdefs.package}/ZipExtraFieldTest.java"
+ unless="tests.and.ant.share.classloader"/>
+
+ <!-- can only run if cvs is installed on your machine
+ enable by setting the property have.cvs
+ -->
+ <exclude name="${taskdefs.package}/AbstractCvsTaskTest.java"
+ unless="have.cvs"/>
+
+ <!-- needs a local ftp server and the entry of a user/password combination -->
+ <exclude name="${optional.package}/net/FTPTest.java"/>
+
+ <!-- test needs special setup -->
+ <exclude name="${optional.package}/ssh/ScpTest.java"/>
+
+ <!-- test fails if build/classes and ant.jar are using the same
+ classloader -->
+ <exclude name="${ant.package}/util/ClasspathUtilsTest.java"
+ if="tests.and.ant.share.classloader"/>
+ </fileset>
+ </batchtest>
+ </test-junit>
+ </target>
+
+ <target name="junit-single-test" depends="compile-tests,junit-single-test-only"
+ description="--> runs the single unit test at $${junit.testcase}" />
+
+ <target name="junit-single-test-only" depends="test-init" if="junit.single"
+ description="--> runs the single unit test at $${junit.testcase} (no compile)">
+ <test-junit>
+ <formatter type="plain" usefile="false"/>
+ <test name="${junit.testcase}" todir="${build.junit.xml}"/>
+ </test-junit>
+ </target>
+
+ <target name="interactive-tests" description="--> runs interactive tests"
+ depends="compile-tests"
+ >
+ <java classpathref="tests-runtime-classpath"
+ classname="org.apache.tools.ant.taskdefs.TestProcess"
+ fork="true"/>
+ </target>
+
+ <target name="-antunit-check-location">
+ <condition property="antunit.recommended.location">
+ <or>
+ <equals arg1="${ant.home}" arg2="${bootstrap.dir}"/>
+ <equals arg1="${ant.home}" arg2="${dist.dir}"/>
+ </or>
+ </condition>
+ </target>
+ <target name="-antunit-warn-location" depends="-antunit-check-location" if="run.antunit" unless="${antunit.recommended.location}">
+ <echo>AntUnit tests must be run with ${bootstrap.dir} (or ${dist.dir}), not ${ant.home}. Try './build.sh antunit-tests' for example.</echo>
+ </target>
+ <target name="antunit-tests" depends="dump-info,build,test-init,-antunit-warn-location"
+ if="run.antunit" description="--> run the antunit tests">
+ <condition property="antunit.includes" value="${antunit.testcase}"
+ else="**/test.xml,**/*-test.xml">
+ <isset property="antunit.testcase" />
+ </condition>
+
+ <property name="antunit.excludes" value="" />
+
+ <mkdir dir="${antunit.xml}" />
+ <au:antunit xmlns:au="antlib:org.apache.ant.antunit"
+ failonerror="false" errorproperty="antunit.failed">
+ <fileset dir="${src.antunit}" includes="${antunit.includes}"
+ excludes="${antunit.excludes}" />
+ <au:plainlistener logLevel="${antunit.loglevel}"/>
+ <au:xmllistener todir="${antunit.xml}" />
+ <propertyset>
+ <propertyref name="antunit.tmpdir"/>
+ <propertyref name="ant.home"/>
+ </propertyset>
+ </au:antunit>
+ </target>
+
+ <target name="antunit-report" depends="antunit-tests,antunit-report-only" />
+
+ <target name="antunit-report-only" depends="test-init" if="run.antunit.report">
+ <length>
+ <fileset dir="${antunit.xml}" includes="TEST-*.xml" />
+ </length>
+ <mkdir dir="${antunit.reports}" />
+ <junitreport todir="${antunit.reports}">
+ <fileset dir="${antunit.xml}" includes="TEST-*.xml" />
+ <report styledir="${src.antunit}" format="frames"
+ todir="${antunit.reports}"/>
+ </junitreport>
+ <length>
+ <fileset dir="${antunit.xml}" includes="TEST-*.xml" />
+ </length>
+ </target>
+
+
+ <target name="printFailingTests">
+ <property name="failingtests.dir" value="${build.dir}/errors"/>
+ <mkdir dir=""/>
+ <xslt
+ style="${etc.dir}/printFailingTests.xsl"
+ destdir="${failingtests.dir}" extension=".txt"
+ basedir="${build.dir}" includes="testcases/**/TEST-*.xml,antunit/xml/TEST-*.xml"
+ />
+ <echo>+-------------------------------------------------------------------------------------</echo>
+ <echo>| FAILING TESTS:</echo>
+ <echo>+-------------------------------------------------------------------------------------</echo>
+ <concat>
+ <!-- generated message files if they arent empty -->
+ <fileset dir="${failingtests.dir}">
+ <size value="0" when="more"/>
+ </fileset>
+ <!-- 'skip' empty lines -->
+ <filterchain>
+ <linecontains>
+ <contains value="|"/>
+ </linecontains>
+ </filterchain>
+ </concat>
+ <echo>+-------------------------------------------------------------------------------------</echo>
+ </target>
+
+ <!--
+ ===================================================================
+ Main target - runs dist-lite by default
+ ===================================================================
+ -->
+ <target name="main"
+ description="--> creates a minimum distribution in ./dist"
+ depends="dist-lite"/>
+
+
+ <!--
+ ===================================================================
+ MSI target - creates an MSI installer file with the help of
+ the WiX toolset and the dotnet Antlib.
+ ===================================================================
+ -->
+ <target name="msi"
+ description="--> creates an MSI file for Ant, requires WiX and the dotnet Antlib"
+ depends="internal_dist"
+ xmlns:dn="antlib:org.apache.ant.dotnet">
+
+ <property name="msi.dir" value="${build.dir}"/>
+ <property name="msi.name" value="${name}-${project.version}.msi"/>
+ <property name="msi.file" value="${msi.dir}/${msi.name}"/>
+ <property name="wix.home" value="${user.home}/wix"/>
+ <property name="wixobj.dir" value="${build.dir}/wix"/>
+
+ <property name="dist.dir.resolved" location="${dist.dir}"/>
+
+ <mkdir dir="${wixobj.dir}"/>
+
+ <dn:wix target="${msi.file}"
+ mode="both" wixHome="${wix.home}" wixobjDestDir="${wixobj.dir}">
+ <sources dir="${etc.dir}" includes="*.wxs"/>
+ <moresources dir="${dist.dir}"/>
+
+ <candleParameter name="dist.dir" value="${dist.dir.resolved}"/>
+ <candleParameter name="version" value="${manifest-version}"/>
+ </dn:wix>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/contributors.xml b/framework/src/ant/apache-ant-1.9.6/contributors.xml
new file mode 100644
index 00000000..7ea115e3
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/contributors.xml
@@ -0,0 +1,1671 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!DOCTYPE contributors
+[
+<!ELEMENT name (first?, middle?, last)>
+<!ELEMENT contributors (introduction, name+)>
+<!ELEMENT first (#PCDATA)>
+<!ELEMENT introduction (#PCDATA)>
+<!ELEMENT middle (#PCDATA)>
+<!ELEMENT last (#PCDATA)>
+]
+>
+
+<contributors>
+ <introduction>
+ These are some of the many people who have helped Ant become so successful.
+ </introduction>
+ <name>
+ <first>Adam</first>
+ <last>Blinkinsop</last>
+ </name>
+ <name>
+ <first>Adam</first>
+ <last>Bryzak</last>
+ </name>
+ <name>
+ <first>Adam</first>
+ <last>Sotona</last>
+ </name>
+ <name>
+ <first>Adrian</first>
+ <last>Nistor</last>
+ </name>
+ <name>
+ <first>Aleksandr</first>
+ <last>Ishutin</last>
+ </name>
+ <name>
+ <first>Alex</first>
+ <last>Rosen</last>
+ </name>
+ <name>
+ <first>Alexei</first>
+ <last>Yudichev</last>
+ </name>
+ <name>
+ <first>Alexey</first>
+ <last>Panchenko</last>
+ </name>
+ <name>
+ <first>Alexey</first>
+ <last>Solofnenko</last>
+ </name>
+ <name>
+ <first>Alfred</first>
+ <last>Theorin</last>
+ </name>
+ <name>
+ <first>Alison</first>
+ <last>Winters</last>
+ </name>
+ <name>
+ <first>Andreas</first>
+ <last>Ames</last>
+ </name>
+ <name>
+ <first>Andrew</first>
+ <last>Eisenberg</last>
+ </name>
+ <name>
+ <first>Andrew</first>
+ <last>Everitt</last>
+ </name>
+ <name>
+ <first>Andrew</first>
+ <last>Stevens</last>
+ </name>
+ <name>
+ <first>Andrey</first>
+ <last>Urazov</last>
+ </name>
+ <name>
+ <first>André-John</first>
+ <last>Mas</last>
+ </name>
+ <name>
+ <first>Andy</first>
+ <last>Wood</last>
+ </name>
+ <name>
+ <first>Anil</first>
+ <middle>K.</middle>
+ <last>Vijendran</last>
+ </name>
+ <name>
+ <first>Anli</first>
+ <last>Shundi</last>
+ </name>
+ <name>
+ <first>Anthony</first>
+ <last>Green</last>
+ </name>
+ <name>
+ <first>Anthony</first>
+ <last>Wat</last>
+ </name>
+ <name>
+ <first>Antoine</first>
+ <last>Baudoux</last>
+ </name>
+ <name>
+ <first>Antoine</first>
+ <last>Levy-Lambert</last>
+ </name>
+ <name>
+ <first>Anton</first>
+ <last>Mazkovoi</last>
+ </name>
+ <name>
+ <first>Arjan</first>
+ <last>Veenstra</last>
+ </name>
+ <name>
+ <first>Arnaud</first>
+ <last>Vandyck</last>
+ </name>
+ <name>
+ <first>Arnout</first>
+ <middle>J.</middle>
+ <last>Kuiper</last>
+ </name>
+ <name>
+ <first>Aslak</first>
+ <last>Helles&#244;y</last>
+ </name>
+ <name>
+ <first>Atsuhiko</first>
+ <last>Yamanaka</last>
+ </name>
+ <name>
+ <first>Avik</first>
+ <last>Sengupta</last>
+ </name>
+ <name>
+ <first>Balazs</first>
+ <last>Fejes 2</last>
+ </name>
+ <name>
+ <first>Bart</first>
+ <last>Vanhaute</last>
+ </name>
+ <name>
+ <first>Benjamin</first>
+ <last>Burgess</last>
+ </name>
+ <name>
+ <first>Ben</first>
+ <last>Galbraith</last>
+ </name>
+ <name>
+ <first>Ben</first>
+ <last>Gertzfield</last>
+ </name>
+ <name>
+ <first>Benoit</first>
+ <last>Moussaud</last>
+ </name>
+ <name>
+ <first>Bernd</first>
+ <last>Dutkowski</last>
+ </name>
+ <name>
+ <first>Bernhard</first>
+ <last>Rosenkraenzer</last>
+ </name>
+ <name>
+ <first>Brad</first>
+ <last>Clark</last>
+ </name>
+ <name>
+ <first>Brant</first>
+ <middle>Langer</middle>
+ <last>Gurganus</last>
+ </name>
+ <name>
+ <first>Brian</first>
+ <last>Curnow</last>
+ </name>
+ <name>
+ <first>Brian</first>
+ <last>Deitte</last>
+ </name>
+ <name>
+ <first>Brian</first>
+ <last>Felder</last>
+ </name>
+ <name>
+ <first>Brian</first>
+ <last>Repko</last>
+ </name>
+ <name>
+ <first>Bruce</first>
+ <last>Atherton</last>
+ </name>
+ <name>
+ <first>Charles</first>
+ <last>Hudak</last>
+ </name>
+ <name>
+ <first>Charlie</first>
+ <last>Hubbard</last>
+ </name>
+ <name>
+ <first>Chris</first>
+ <last>Povirk</last>
+ </name>
+ <name>
+ <first>Christian</first>
+ <last>Knorr</last>
+ </name>
+ <name>
+ <first>Christian</first>
+ <last>Schmidt</last>
+ </name>
+ <name>
+ <first>Christoph</first>
+ <last>Gysin</last>
+ </name>
+ <name>
+ <first>Christoph</first>
+ <last>Wilhelms</last>
+ </name>
+ <name>
+ <first>Christophe</first>
+ <last>Labouisse</last>
+ </name>
+ <name>
+ <first>Christopher</first>
+ <middle>A.</middle>
+ <last>Longo</last>
+ </name>
+ <name>
+ <first>Christopher</first>
+ <last>Charlier</last>
+ </name>
+ <name>
+ <first>Clark</first>
+ <last>Archer</last>
+ </name>
+ <name>
+ <first>Clemens</first>
+ <last>Hammacher</last>
+ </name>
+ <name>
+ <first>Clement</first>
+ <last>OUDOT</last>
+ </name>
+ <name>
+ <first>Clive</first>
+ <last>Brettingham-Moore</last>
+ </name>
+ <name>
+ <first>Conor</first>
+ <last>MacNeill</last>
+ </name>
+ <name>
+ <first>Craeg</first>
+ <last>Strong</last>
+ </name>
+ <name>
+ <first>Craig</first>
+ <last>Cottingham</last>
+ </name>
+ <name>
+ <first>Craig</first>
+ <middle>R.</middle>
+ <last>McClanahan</last>
+ </name>
+ <name>
+ <first>Craig</first>
+ <last>Ryan</last>
+ </name>
+ <name>
+ <first>Craig</first>
+ <last>Richardson</last>
+ </name>
+ <name>
+ <first>Craig</first>
+ <last>Sandvik</last>
+ </name>
+ <name>
+ <first>Curt</first>
+ <last>Arnold</last>
+ </name>
+ <name>
+ <first>Curtis</first>
+ <last>White</last>
+ </name>
+ <name>
+ <first>Cyrille</first>
+ <last>Morvan</last>
+ </name>
+ <name>
+ <first>D'Arcy</first>
+ <last>Smith</last>
+ </name>
+ <name>
+ <first>Dale</first>
+ <last>Anson</last>
+ </name>
+ <name>
+ <first>Dale</first>
+ <last>Sherwood</last>
+ </name>
+ <name>
+ <first>Dan</first>
+ <last>Armbrust</last>
+ </name>
+ <name>
+ <first>Daniel</first>
+ <last>Henrique</last>
+ </name>
+ <name>
+ <first>Daniel</first>
+ <last>Ribagnac</last>
+ </name>
+ <name>
+ <first>Daniel</first>
+ <last>Spilker</last>
+ </name>
+ <name>
+ <first>Daniel</first>
+ <last>Trebbien</last>
+ </name>
+ <name>
+ <first>Danno</first>
+ <last>Ferrin</last>
+ </name>
+ <name>
+ <first>Danny</first>
+ <last>Yates</last>
+ </name>
+ <name>
+ <first>Dante</first>
+ <last>Briones</last>
+ </name>
+ <name>
+ <first>Davanum</first>
+ <last>Srinivas</last>
+ </name>
+ <name>
+ <first>Dave</first>
+ <last>Brondsema</last>
+ </name>
+ <name>
+ <first>Dave</first>
+ <last>Brosius</last>
+ </name>
+ <name>
+ <first>David</first>
+ <last>A.</last>
+ </name>
+ <name>
+ <first>David</first>
+ <last>Crossley</last>
+ </name>
+ <name>
+ <first>David</first>
+ <last>G&#228;rtner</last>
+ </name>
+ <name>
+ <first>David</first>
+ <middle>S.</middle>
+ <last>Johnson</last>
+ </name>
+ <name>
+ <first>David</first>
+ <last>Kavanagh</last>
+ </name>
+ <name>
+ <first>David</first>
+ <last>LeRoy</last>
+ </name>
+ <name>
+ <first>David</first>
+ <last>Leal</last>
+ </name>
+ <name>
+ <first>David</first>
+ <middle>M.</middle>
+ <last>Lloyd</last>
+ </name>
+ <name>
+ <first>David</first>
+ <last>Maclean</last>
+ </name>
+ <name>
+ <first>David</first>
+ <last>Rees</last>
+ </name>
+ <name>
+ <first>Denis</first>
+ <last>Hennessy</last>
+ </name>
+ <name>
+ <first>Derek</first>
+ <last>Slager</last>
+ </name>
+ <name>
+ <first>Devon</first>
+ <middle>C.</middle>
+ <last>Miller</last>
+ </name>
+ <name>
+ <first>Diane</first>
+ <last>Holt</last>
+ </name>
+ <name>
+ <first>dIon</first>
+ <last>Gillard</last>
+ </name>
+ <name>
+ <first>Dmitry</first>
+ <middle>A.</middle>
+ <last>Kuminov</last>
+ </name>
+ <name>
+ <first>Dominique</first>
+ <last>Devienne</last>
+ </name>
+ <name>
+ <first>Donal</first>
+ <last>Quinlan</last>
+ </name>
+ <name>
+ <first>Don</first>
+ <last>Bnamen</last>
+ </name>
+ <name>
+ <first>Don</first>
+ <last>Ferguson</last>
+ </name>
+ <name>
+ <first>Don</first>
+ <last>Jeffery</last>
+ </name>
+ <name>
+ <first>Drew</first>
+ <last>Sudell</last>
+ </name>
+ <name>
+ <first>Edison</first>
+ <last>Guo</last>
+ </name>
+ <name>
+ <first>Eduard</first>
+ <last>Wirch</last>
+ </name>
+ <name>
+ <first>Edwin</first>
+ <last>Woudt</last>
+ </name>
+ <name>
+ <first>Eli</first>
+ <last>Tucker</last>
+ </name>
+ <name>
+ <first>Emmanuel</first>
+ <last>Bourg</last>
+ </name>
+ <name>
+ <first>Eric</first>
+ <last>Olsen</last>
+ </name>
+ <name>
+ <first>Eric</first>
+ <last>Pugh</last>
+ </name>
+ <name>
+ <first>Erik</first>
+ <last>Costlow</last>
+ </name>
+ <name>
+ <first>Erik</first>
+ <last>Hatcher</last>
+ </name>
+ <name>
+ <first>Erik</first>
+ <last>Langenbach</last>
+ </name>
+ <name>
+ <first>Erik</first>
+ <last>Meade</last>
+ </name>
+ <name>
+ <first>Ernst</first>
+ <last>de Haan</last>
+ </name>
+ <name>
+ <first>Frank</first>
+ <last>Harnack</last>
+ </name>
+ <name>
+ <first>Frank</first>
+ <last>Somers</last>
+ </name>
+ <name>
+ <first>Frank</first>
+ <last>Zeyda</last>
+ </name>
+ <name>
+ <first>František</first>
+ <last>KuÄŤera</last>
+ </name>
+ <name>
+ <first>Frédéric</first>
+ <last>Bothamy</last>
+ </name>
+ <name>
+ <first>Frederic</first>
+ <last>Lavigne</last>
+ </name>
+ <name>
+ <first>Gary</first>
+ <middle>S.</middle>
+ <last>Weaver</last>
+ </name>
+ <name>
+ <first>Gautam</first>
+ <last>Guliani</last>
+ </name>
+ <name>
+ <first>Gene-Sung</first>
+ <last>Chung</last>
+ </name>
+ <name>
+ <first>Georges-Etienne</first>
+ <last>Legendre</last>
+ </name>
+ <name>
+ <first>Gero</first>
+ <last>Vermaas</last>
+ </name>
+ <name>
+ <first>Gerrit</first>
+ <last>Riessen</last>
+ </name>
+ <name>
+ <first>Gilbert</first>
+ <last>Rebhan</last>
+ </name>
+ <name>
+ <first>Gilles</first>
+ <last>Scokart</last>
+ </name>
+ <name>
+ <first>Glenn</first>
+ <last>McAllister</last>
+ </name>
+ <name>
+ <first>Glenn</first>
+ <last>Twiggs</last>
+ </name>
+ <name>
+ <first>Greg</first>
+ <last>Nelson</last>
+ </name>
+ <name>
+ <first>Greg</first>
+ <last>Roodt</last>
+ </name>
+ <name>
+ <first>Greg</first>
+ <last>Schueler</last>
+ </name>
+ <name>
+ <first>Grégoire</first>
+ <last>Vatry</last>
+ </name>
+ <name>
+ <first>GĂĽnther</first>
+ <last>Kögel</last>
+ </name>
+ <name>
+ <first>Harish</first>
+ <last>Prabandham</last>
+ </name>
+ <name>
+ <first>Haroon</first>
+ <last>Rafique</last>
+ </name>
+ <name>
+ <first>Hiroaki</first>
+ <last>Nakamura</last>
+ </name>
+ <name>
+ <first>Holger</first>
+ <last>Engels</last>
+ </name>
+ <name>
+ <first>Holger</first>
+ <last>Joest</last>
+ </name>
+ <name>
+ <first>Ignacio</first>
+ <last>Coloma</last>
+ </name>
+ <name>
+ <first>Ingenonsya</first>
+ <last>France</last>
+ </name>
+ <name>
+ <first>Ingmar</first>
+ <last>Stein</last>
+ </name>
+ <name>
+ <first>Irene</first>
+ <last>Rusman</last>
+ </name>
+ <name>
+ <first>Isaac</first>
+ <last>Shabtay</last>
+ </name>
+ <name>
+ <first>Ivan</first>
+ <last>Ivanov</last>
+ </name>
+ <name>
+ <first>J</first>
+ <last>Bleijenbergh</last>
+ </name>
+ <name>
+ <first>Jack</first>
+ <middle>J.</middle>
+ <last>Woehr</last>
+ </name>
+ <name>
+ <first>James</first>
+ <middle>Duncan</middle>
+ <last>Davidson</last>
+ </name>
+ <name>
+ <first>Jan</first>
+ <last>Cumps</last>
+ </name>
+ <name>
+ <first>Jan</first>
+ <last>Mat&#232;rne</last>
+ </name>
+ <name>
+ <first>Jan</first>
+ <last>Mynarik</last>
+ </name>
+ <name>
+ <first>Jan</first>
+ <last>Stolze</last>
+ </name>
+ <name>
+ <first>Jason</first>
+ <last>Hunter</last>
+ </name>
+ <name>
+ <first>Jason</first>
+ <last>Pettiss</last>
+ </name>
+ <name>
+ <first>Jason</first>
+ <last>Salter</last>
+ </name>
+ <name>
+ <first>Jason</first>
+ <last>Yip</last>
+ </name>
+ <name>
+ <first>Jay</first>
+ <middle>Dickon</middle>
+ <last>Glanville</last>
+ </name>
+ <name>
+ <first>Jay</first>
+ <last>Peck</last>
+ </name>
+ <name>
+ <first>Jay</first>
+ <last>van der Meer</last>
+ </name>
+ <name>
+ <first>JC</first>
+ <last>Mann</last>
+ </name>
+ <name>
+ <first>J</first>
+ <last>D</last>
+ </name>
+ <name>
+ <first>Jean-Francois</first>
+ <last>Brousseau</last>
+ </name>
+ <name>
+ <first>Jeff</first>
+ <last>Gettle</last>
+ </name>
+ <name>
+ <first>Jeff</first>
+ <last>Martin</last>
+ </name>
+ <name>
+ <first>Jeff</first>
+ <last>Tulley</last>
+ </name>
+ <name>
+ <first>Jeff</first>
+ <last>Turner</last>
+ </name>
+ <name>
+ <first>Jene</first>
+ <last>Jasper</last>
+ </name>
+ <name>
+ <first>Jeremy</first>
+ <last>Mawson</last>
+ </name>
+ <name>
+ <first>Jerome</first>
+ <last>Lacoste</last>
+ </name>
+ <name>
+ <first>Jesse</first>
+ <last>Glick</last>
+ </name>
+ <name>
+ <first>Jesse</first>
+ <last>Stockall</last>
+ </name>
+ <name>
+ <first>Jim</first>
+ <last>Allers</last>
+ </name>
+ <name>
+ <first>Joerg</first>
+ <last>Wassmer</last>
+ </name>
+ <name>
+ <first>Joel</first>
+ <last>Tucci</last>
+ </name>
+ <name>
+ <first>Joey</first>
+ <last>Richey</last>
+ </name>
+ <name>
+ <first>Johann</first>
+ <last>Herunter</last>
+ </name>
+ <name>
+ <first>John</first>
+ <last>Elion</last>
+ </name>
+ <name>
+ <first>John</first>
+ <last>Sisson</last>
+ </name>
+ <name>
+ <first>Jon</first>
+ <last>Dickinson</last>
+ </name>
+ <name>
+ <first>Jon</first>
+ <last>Skeet</last>
+ </name>
+ <name>
+ <first>Jon</first>
+ <middle>S.</middle>
+ <last>Stevens</last>
+ </name>
+ <name>
+ <first>Jose</first>
+ <middle>Alberto</middle>
+ <last>Fernandez</last>
+ </name>
+ <name>
+ <first>Josh</first>
+ <last>Lucas</last>
+ </name>
+ <name>
+ <first>Joseph</first>
+ <last>Walton</last>
+ </name>
+ <name>
+ <first>Juerg</first>
+ <last>Wanner</last>
+ </name>
+ <name>
+ <first>Julian</first>
+ <last>Simpson</last>
+ </name>
+ <name>
+ <first>Justin</first>
+ <last>Vallon</last>
+ </name>
+ <name>
+ <first>Keiron</first>
+ <last>Liddle</last>
+ </name>
+ <name>
+ <first>Keith</first>
+ <last>Visco</last>
+ </name>
+ <name>
+ <first>Kevin</first>
+ <middle>Connor</middle>
+ <last>Arpe</last>
+ </name>
+ <name>
+ <first>Kevin</first>
+ <last>Greiner</last>
+ </name>
+ <name>
+ <first>Kevin</first>
+ <last>Jackson</last>
+ </name>
+ <name>
+ <first>Kevin</first>
+ <last>Ross</last>
+ </name>
+ <name>
+ <first>Kevin</first>
+ <middle>Z</middle>
+ <last>Grey</last>
+ </name>
+ <name>
+ <first>Kim</first>
+ <last>Hansen</last>
+ </name>
+ <name>
+ <first>Kirk</first>
+ <last>Wylie</last>
+ </name>
+ <name>
+ <first>Kristian</first>
+ <last>Rosenvold</last>
+ </name>
+ <name>
+ <first>Kyle</first>
+ <last>Adams</last>
+ </name>
+ <name>
+ <first>Lajos</first>
+ <last>Veres</last>
+ </name>
+ <name>
+ <first>Larry</first>
+ <last>Shatzer</last>
+ </name>
+ <name>
+ <first>Larry</first>
+ <last>Streepy</last>
+ </name>
+ <name>
+ <first>Les</first>
+ <last>Hughes</last>
+ </name>
+ <name>
+ <first>Levi</first>
+ <last>Cook</last>
+ </name>
+ <name>
+ <last>lucas</last>
+ </name>
+ <name>
+ <first>Lucas</first>
+ <last>Werkmeister</last>
+ </name>
+ <name>
+ <first>Ludovic</first>
+ <last>Claude</last>
+ </name>
+ <name>
+ <first>Magesh</first>
+ <last>Umasankar</last>
+ </name>
+ <name>
+ <first>Maneesh</first>
+ <last>Sahu</last>
+ </name>
+ <name>
+ <first>Marcel</first>
+ <last>Schutte</last>
+ </name>
+ <name>
+ <first>Marcus</first>
+ <last>Börger</last>
+ </name>
+ <name>
+ <first>Mario</first>
+ <last>Frasca</last>
+ </name>
+ <name>
+ <first>Mariusz</first>
+ <last>Nowostawski</last>
+ </name>
+ <name>
+ <first>Mark</first>
+ <last>DeLaFranier</last>
+ </name>
+ <name>
+ <first>Mark</first>
+ <last>Hecker</last>
+ </name>
+ <name>
+ <first>Mark</first>
+ <last>Salter</last>
+ </name>
+ <name>
+ <first>Mark</first>
+ <middle>R.</middle>
+ <last>Diggory</last>
+ </name>
+ <name>
+ <first>Mark</first>
+ <middle>A.</middle>
+ <last>Ziesemer</last>
+ </name>
+ <name>
+ <first>Markus</first>
+ <last>Kahl</last>
+ </name>
+ <name>
+ <first>Martijn</first>
+ <last>Kruithof</last>
+ </name>
+ <name>
+ <first>Martin</first>
+ <last>Landers</last>
+ </name>
+ <name>
+ <first>Martin</first>
+ <last>Poeschl</last>
+ </name>
+ <name>
+ <first>Martin</first>
+ <last>van den Bemt</last>
+ </name>
+ <name>
+ <first>Martin</first>
+ <last>von Gagern</last>
+ </name>
+ <name>
+ <first>Matt</first>
+ <last>Albrecht</last>
+ </name>
+ <name>
+ <first>Matt</first>
+ <last>Benson</last>
+ </name>
+ <name>
+ <first>Matt</first>
+ <last>Bishop</last>
+ </name>
+ <name>
+ <first>Matt</first>
+ <last>Foemmel</last>
+ </name>
+ <name>
+ <first>Matt</first>
+ <last>Grosso</last>
+ </name>
+ <name>
+ <first>Matt</first>
+ <last>Humphrey</last>
+ </name>
+ <name>
+ <first>Matt</first>
+ <last>Small</last>
+ </name>
+ <name>
+ <first>Matt</first>
+ <last>Wildig</last>
+ </name>
+ <name>
+ <first>Mathieu</first>
+ <last>Champlon</last>
+ </name>
+ <name>
+ <first>Mathieu</first>
+ <last>Peltier</last>
+ </name>
+ <name>
+ <first>Matthias</first>
+ <last>Bhend</last>
+ </name>
+ <name>
+ <first>Matthew</first>
+ <last>Hawthorne</last>
+ </name>
+ <name>
+ <first>Matthew</first>
+ <last>Inger</last>
+ </name>
+ <name>
+ <first>Matthew</first>
+ <middle>Kuperus</middle>
+ <last>Heun</last>
+ </name>
+ <name>
+ <first>Matthew</first>
+ <last>Watson</last>
+ </name>
+ <name>
+ <first>Michael</first>
+ <last>Bayne</last>
+ </name>
+ <name>
+ <first>Michael</first>
+ <last>Clarke</last>
+ </name>
+ <name>
+ <first>Michael</first>
+ <last>Davey</last>
+ </name>
+ <name>
+ <first>Michael</first>
+ <middle>J.</middle>
+ <last>Sikorsky</last>
+ </name>
+ <name>
+ <first>Michael</first>
+ <last>McCallum</last>
+ </name>
+ <name>
+ <first>Michael</first>
+ <last>Newcomb</last>
+ </name>
+ <name>
+ <first>Michael</first>
+ <last>Nygard</last>
+ </name>
+ <name>
+ <first>Michael</first>
+ <last>Saunders</last>
+ </name>
+ <name>
+ <last>Miha</last>
+ </name>
+ <name>
+ <first>Mike</first>
+ <last>Davis</last>
+ </name>
+ <name>
+ <first>Mike</first>
+ <last>Roberts</last>
+ </name>
+ <name>
+ <first>Mike</first>
+ <last>Williams</last>
+ </name>
+ <name>
+ <first>Miroslav</first>
+ <last>ZaĹĄko</last>
+ </name>
+ <name>
+ <last>mnowostawski</last>
+ </name>
+ <name>
+ <first>Mounir</first>
+ <last>El Hajj</last>
+ </name>
+ <name>
+ <first>Nathan</first>
+ <last>Beyer</last>
+ </name>
+ <name>
+ <first>Nick</first>
+ <last>Chalko</last>
+ </name>
+ <name>
+ <first>Nick</first>
+ <last>Crossley</last>
+ </name>
+ <name>
+ <first>Nick</first>
+ <last>Fortescue</last>
+ </name>
+ <name>
+ <first>Nick</first>
+ <last>Pellow</last>
+ </name>
+ <name>
+ <first>Nicola</first>
+ <last>Ken</last>
+ </name>
+ <name>
+ <first>Nico</first>
+ <last>Seessle</last>
+ </name>
+ <name>
+ <first>Nigel</first>
+ <last>Magnay</last>
+ </name>
+ <name>
+ <first>Oliver</first>
+ <last>Merkel</last>
+ </name>
+ <name>
+ <first>Oliver</first>
+ <last>Rossmueller</last>
+ </name>
+ <name>
+ <first>Omer</first>
+ <last>Shapira</last>
+ </name>
+ <name>
+ <first>Ondra</first>
+ <last>Medek</last>
+ </name>
+ <name>
+ <first>&#216;ystein</first>
+ <last>Gisn&#229;s</last>
+ </name>
+ <name>
+ <first>Patrick</first>
+ <last>Altaie</last>
+ </name>
+ <name>
+ <first>Patrick</first>
+ <last>C.</last>
+ </name>
+ <name>
+ <first>Patrick</first>
+ <last>Chanezon</last>
+ </name>
+ <name>
+ <first>Patrick</first>
+ <last>Gus</last>
+ </name>
+ <name>
+ <first>Paul</first>
+ <last>Austin</last>
+ </name>
+ <name>
+ <first>Paul</first>
+ <last>Christmann</last>
+ </name>
+ <name>
+ <first>Paul</first>
+ <last>Galbraith</last>
+ </name>
+ <name>
+ <first>Paul</first>
+ <last>King</last>
+ </name>
+ <name>
+ <first>Paulo</first>
+ <last>Gaspar</last>
+ </name>
+ <name>
+ <first>Pavan</first>
+ <last>Bayyapu</last>
+ </name>
+ <name>
+ <first>Pavel</first>
+ <last>Jisl</last>
+ </name>
+ <name>
+ <first>Paweł</first>
+ <last>Zuzelski</last>
+ </name>
+ <name>
+ <first>Peter</first>
+ <middle>B.</middle>
+ <last>West</last>
+ </name>
+ <name>
+ <first>Peter</first>
+ <last>Donald</last>
+ </name>
+ <name>
+ <first>Peter</first>
+ <last>Doornbosch</last>
+ </name>
+ <name>
+ <first>Peter</first>
+ <last>Hulst</last>
+ </name>
+ <name>
+ <first>Peter</first>
+ <last>Janes</last>
+ </name>
+ <name>
+ <first>Peter</first>
+ <last>Reilly</last>
+ </name>
+ <name>
+ <first>Petr</first>
+ <last>Kureš</last>
+ </name>
+ <name>
+ <first>Phil</first>
+ <last>Hanna</last>
+ </name>
+ <name>
+ <first>Philip</first>
+ <last>Hourihane</last>
+ </name>
+ <name>
+ <first>Phillip</first>
+ <last>Wells</last>
+ </name>
+ <name>
+ <first>Pierre</first>
+ <last>Delisle</last>
+ </name>
+ <name>
+ <first>Pierre</first>
+ <last>Dittgen</last>
+ </name>
+ <name>
+ <first>R</first>
+ <last>Handerson</last>
+ </name>
+ <name>
+ <first>Ralf</first>
+ <last>Hergert</last>
+ </name>
+ <name>
+ <first>Rami</first>
+ <last>Ojares</last>
+ </name>
+ <name>
+ <first>Randy</first>
+ <last>Watler</last>
+ </name>
+ <name>
+ <first>Raphael</first>
+ <last>Pierquin</last>
+ </name>
+ <name>
+ <first>Ray</first>
+ <last>Waldin</last>
+ </name>
+ <name>
+ <first>Remie</first>
+ <last>Bolte</last>
+ </name>
+ <name>
+ <first>René</first>
+ <last>Krell</last>
+ </name>
+ <name>
+ <first>Richard</first>
+ <last>Evans</last>
+ </name>
+ <name>
+ <first>Richard</first>
+ <last>Steele</last>
+ </name>
+ <name>
+ <first>Rick</first>
+ <last>Beton</last>
+ </name>
+ <name>
+ <first>Robbie</first>
+ <last>Gibson</last>
+ </name>
+ <name>
+ <first>Robert</first>
+ <last>Anderson</last>
+ </name>
+ <name>
+ <first>Robert</first>
+ <last>Clark</last>
+ </name>
+ <name>
+ <first>Robert</first>
+ <last>Flaherty</last>
+ </name>
+ <name>
+ <first>Robert</first>
+ <last>Shaw</last>
+ </name>
+ <name>
+ <first>Robert</first>
+ <last>Streich</last>
+ </name>
+ <name>
+ <first>Robert</first>
+ <last>Watkins</last>
+ </name>
+ <name>
+ <first>Roberto</first>
+ <last>Scaramuzzi</last>
+ </name>
+ <name>
+ <first>Robin</first>
+ <last>Green</last>
+ </name>
+ <name>
+ <first>Robin</first>
+ <last>Power</last>
+ </name>
+ <name>
+ <first>Robin</first>
+ <last>Verduijn</last>
+ </name>
+ <name>
+ <first>Rob</first>
+ <last>Oxspring</last>
+ </name>
+ <name>
+ <first>Rob</first>
+ <last>van Oostrum</last>
+ </name>
+ <name>
+ <first>Rodrigo</first>
+ <last>Schmidt</last>
+ </name>
+ <name>
+ <first>Roger</first>
+ <last>Vaughn</last>
+ </name>
+ <name>
+ <first>Roman</first>
+ <last>Ivashin</last>
+ </name>
+ <name>
+ <first>Roman</first>
+ <last>Savko</last>
+ </name>
+ <name>
+ <first>Ronen</first>
+ <last>Mashal</last>
+ </name>
+ <name>
+ <first>Russell</first>
+ <last>Gold</last>
+ </name>
+ <name>
+ <first>Ryan</first>
+ <last>Bennitt</last>
+ </name>
+ <name>
+ <first>Sam</first>
+ <last>Ruby</last>
+ </name>
+ <name>
+ <first>Sandra</first>
+ <last>Metz</last>
+ </name>
+ <name>
+ <first>Scott</first>
+ <last>Carlson</last>
+ </name>
+ <name>
+ <first>Scott</first>
+ <last>Ellsworth</last>
+ </name>
+ <name>
+ <first>Scott</first>
+ <last>Johnson</last>
+ </name>
+ <name>
+ <first>Scott</first>
+ <middle>M.</middle>
+ <last>Stirling</last>
+ </name>
+ <name>
+ <first>Sean</first>
+ <last>Egan</last>
+ </name>
+ <name>
+ <first>Sean</first>
+ <middle>P.</middle>
+ <last>Kane</last>
+ </name>
+ <name>
+ <first>Sebastien</first>
+ <last>Arod</last>
+ </name>
+ <name>
+ <first>Shiraz</first>
+ <last>Kanga</last>
+ </name>
+ <name>
+ <first>Sebastian</first>
+ <last>Kantha</last>
+ </name>
+ <name>
+ <first>Simon</first>
+ <last>Law</last>
+ </name>
+ <name>
+ <first>Simone</first>
+ <last>Bordet</last>
+ </name>
+ <name>
+ <first>Stefan</first>
+ <last>Bodewig</last>
+ </name>
+ <name>
+ <first>Stefan</first>
+ <last>Heimann</last>
+ </name>
+ <name>
+ <first>Stefano</first>
+ <last>Mazzocchi</last>
+ </name>
+ <name>
+ <first>Stephan</first>
+ <last>Strittmatter</last>
+ </name>
+ <name>
+ <first>Stephane</first>
+ <last>Bailliez</last>
+ </name>
+ <name>
+ <last>stephan</last>
+ </name>
+ <name>
+ <first>Stephan</first>
+ <last>Michels</last>
+ </name>
+ <name>
+ <first>Stephen</first>
+ <last>Chin</last>
+ </name>
+ <name>
+ <first>Steve</first>
+ <last>Cohen</last>
+ </name>
+ <name>
+ <first>Steve</first>
+ <last>Langley</last>
+ </name>
+ <name>
+ <first>Steve</first>
+ <last>Loughran</last>
+ </name>
+ <name>
+ <first>Steve</first>
+ <last>Morin</last>
+ </name>
+ <name>
+ <first>Steve</first>
+ <last>Wadsworth</last>
+ </name>
+ <name>
+ <first>Steven</first>
+ <middle>E.</middle>
+ <last>Newton</last>
+ </name>
+ <name>
+ <first>Sudheer</first>
+ <last>Chigurupati</last>
+ </name>
+ <name>
+ <first>Takashi</first>
+ <last>Okamoto</last>
+ </name>
+ <name>
+ <first>TAMURA</first>
+ <last>Kent</last>
+ </name>
+ <name>
+ <first>Taoufik</first>
+ <last>Romdhane</last>
+ </name>
+ <name>
+ <first>Tariq</first>
+ <last>Master</last>
+ </name>
+ <name>
+ <first>Thomas</first>
+ <last>Aglassinger</last>
+ </name>
+ <name>
+ <first>Thomas</first>
+ <last>Butz</last>
+ </name>
+ <name>
+ <first>Thomas</first>
+ <last>Christen</last>
+ </name>
+ <name>
+ <first>Thomas</first>
+ <last>Christensen</last>
+ </name>
+ <name>
+ <first>Thomas</first>
+ <last>Haas</last>
+ </name>
+ <name>
+ <first>Thomas</first>
+ <last>Quas</last>
+ </name>
+ <name>
+ <first>Tim</first>
+ <last>Boemker</last>
+ </name>
+ <name>
+ <first>Tim</first>
+ <last>Drury</last>
+ </name>
+ <name>
+ <first>Tim</first>
+ <last>Fennell</last>
+ </name>
+ <name>
+ <first>Tim</first>
+ <last>Whittington</last>
+ </name>
+ <name>
+ <first>Timoteo</first>
+ <last>Ohara</last>
+ </name>
+ <name>
+ <first>Timothy</first>
+ <middle>Gerard</middle>
+ <last>Endres</last>
+ </name>
+ <name>
+ <first>Tim</first>
+ <last>Stephenson</last>
+ </name>
+ <name>
+ <first>Tom</first>
+ <last>Ball</last>
+ </name>
+ <name>
+ <first>Tom</first>
+ <last>Cunningham</last>
+ </name>
+ <name>
+ <first>Tom</first>
+ <last>Dimock</last>
+ </name>
+ <name>
+ <first>Tom</first>
+ <last>Eugelink</last>
+ </name>
+ <name>
+ <first>Tom</first>
+ <last>May</last>
+ </name>
+ <name>
+ <first>Tomasz</first>
+ <last>Bech</last>
+ </name>
+ <name>
+ <first>Trejkaz</first>
+ <last>Xaoz</last>
+ </name>
+ <name>
+ <first>Ulrich</first>
+ <last>Schmidt</last>
+ </name>
+ <name>
+ <first>Uwe</first>
+ <last>Schindler</last>
+ </name>
+ <name>
+ <first>Valentino</first>
+ <last>Miazzo</last>
+ </name>
+ <name>
+ <first>Victor</first>
+ <last>Toni</last>
+ </name>
+ <name>
+ <first>Vincent</first>
+ <last>Legoll</last>
+ </name>
+ <name>
+ <first>Vimil</first>
+ <last>Saju</last>
+ </name>
+ <name>
+ <first>Vitold</first>
+ <last>Sedyshev</last>
+ </name>
+ <name>
+ <first>Volker</first>
+ <last>Leidl</last>
+ </name>
+ <name>
+ <first>Wang</first>
+ <last>Weijun</last>
+ </name>
+ <name>
+ <first>Will</first>
+ <last>Wang</last>
+ </name>
+ <name>
+ <first>William</first>
+ <last>Bernardet</last>
+ </name>
+ <name>
+ <first>William</first>
+ <last>Ferguson</last>
+ </name>
+ <name>
+ <first>William</first>
+ <last>Webber</last>
+ </name>
+ <name>
+ <first>Wolf</first>
+ <last>Siberski</last>
+ </name>
+ <name>
+ <first>Wolfgang</first>
+ <last>Baer</last>
+ </name>
+ <name>
+ <first>Wolfgang</first>
+ <last>Frech</last>
+ </name>
+ <name>
+ <first>Wolfgang</first>
+ <last>Glas</last>
+ </name>
+ <name>
+ <first>Wolfgang</first>
+ <last>Werner</last>
+ </name>
+ <name>
+ <first>Xavier</first>
+ <last>Hanin</last>
+ </name>
+ <name>
+ <first>Xavier</first>
+ <last>Witdouck</last>
+ </name>
+ <name>
+ <first>Yohann</first>
+ <last>Roussel</last>
+ </name>
+ <name>
+ <first>Yuji</first>
+ <last>Yamano</last>
+ </name>
+ <name>
+ <first>Yves</first>
+ <last>Martin</last>
+ </name>
+ <name>
+ <first>Zach</first>
+ <last>Garner</last>
+ </name>
+ <name>
+ <first>Zdenek</first>
+ <last>Wagner</last>
+ </name>
+ <name>
+ <first/>
+ <last>riasol</last>
+ </name>
+</contributors>
diff --git a/framework/src/ant/apache-ant-1.9.6/fetch.xml b/framework/src/ant/apache-ant-1.9.6/fetch.xml
new file mode 100644
index 00000000..8442d2a1
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/fetch.xml
@@ -0,0 +1,335 @@
+<?xml version="1.0"?>
+
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!--
+ =======================================================================
+ Build file to fetch optional libraries for Apache Ant
+ =======================================================================
+-->
+<project name="fetch" default="all" basedir=".">
+
+<description>
+ This build file downloads JAR files that optional Ant tasks use,
+ and installs them in a location that is accessible the next time Ant runs.
+
+ You can choose three locations, by going -Ddest=LOCATION on the command line
+ -Ddest=user user lib dir ${user.home}/.ant/lib
+ -Ddest=system ant lib dir ${ant.home}/lib
+ -Ddest=optional optional dir $${basedir}/lib/optional (for Ant developers)
+
+ You may also need to set proxy settings. On Java1.5, Ant tries to get
+ this from the OS, unless you use the -noproxy option.
+
+ Proxies can be configured manually setting the JVM proxy values in the
+ ANT_OPTS environment variable.
+
+ For example, to set the proxy up in the tcsh shell, the command would be
+ something like:
+
+ For csh/tcsh:
+ setenv ANT_OPTS "-Dhttp.proxyHost=proxy -Dhttp.proxyPort=8080"
+ For bash:
+ export ANT_OPTS="-Dhttp.proxyHost=proxy -Dhttp.proxyPort=8080"
+ For Windows, set the environment variable in the appropriate dialog box
+ and open a new console. or, by hand
+ set ANT_OPTS = -Dhttp.proxyHost=proxy -Dhttp.proxyPort=8080
+</description>
+
+ <!-- Give user a chance to override without editing this file
+ (and without typing -D each time it compiles it) -->
+ <property file="${user.home}/.ant/ant.properties"/>
+ <property name="lib.dir" location="lib" />
+ <property name="optional.dir" location="${lib.dir}/optional" />
+ <property name="userlib.dir" location="${user.home}/.ant/lib" />
+
+ <!-- load in our properties table -->
+ <property file="${lib.dir}/libraries.properties"/>
+
+ <!-- Temporary cache for working files -->
+ <property name="temp.dir" location="${user.home}/.ant/tempcache" />
+ <property name="keep.temp.dir" value="true" />
+
+ <import file="get-m2.xml" />
+
+ <target name="pick-dest">
+ <fail>
+ <condition>
+ <not>
+ <isset property="dest"/>
+ </not>
+ </condition>ERROR
+Set -Ddest=LOCATION on the command line
+ -Ddest=user user lib dir ${user.home}/.ant/lib
+ -Ddest=system ant lib dir ${ant.home}/lib
+ -Ddest=optional optional dir $${basedir}/lib/optional (for Ant developers)
+ </fail>
+
+ <condition property="dest.dir"
+ value="${lib.dir}">
+ <equals arg1="${dest}" arg2="system" />
+ </condition>
+ <condition property="dest.dir"
+ value="${optional.dir}">
+ <equals arg1="${dest}" arg2="optional" />
+ </condition>
+ <condition property="dest.dir"
+ value="${userlib.dir}">
+ <equals arg1="${dest}" arg2="user" />
+ </condition>
+ <fail unless="dest.dir">Unknown destination : ${dest}</fail>
+ <echo>Downloading to ${dest.dir}</echo>
+ <property name="m2.dest.dir" value="${dest.dir}" />
+ </target>
+
+
+ <target name="macros" depends="pick-dest,get-m2"
+ xmlns:artifact="antlib:org.apache.maven.artifact.ant">
+
+ <macrodef name="f2">
+ <attribute name="project" />
+ <attribute name="archive" default="@{project}"/>
+ <attribute name="repository" default="${m2.repo}"/>
+ <sequential>
+ <fail>
+ Unknown archive @{archive} -no property @{archive}.version defined in ${lib.dir}/libraries.properties.
+ <condition>
+ <not>
+ <isset property="@{archive}.version"/>
+ </not>
+ </condition>
+ </fail>
+ <artifact:dependencies pathID="@{archive}.path">
+ <dependency groupID="@{project}"
+ artifactID="@{archive}"
+ version="${@{archive}.version}"/>
+ <remoteRepository url="@{repository}" />
+ </artifact:dependencies>
+ <!-- now we are left with the problem of getting the files
+ into our directory -->
+ <copy todir="${dest.dir}">
+ <path refid="@{archive}.path" />
+ <flattenmapper/>
+ </copy>
+ </sequential>
+ </macrodef>
+ </target>
+
+ <target name="nonm2-macros" depends="pick-dest">
+ <macrodef name="get-ftp-file">
+ <attribute name="host" />
+ <attribute name="port" default="21"/>
+ <attribute name="remotedir" />
+ <attribute name="filename" />
+ <attribute name="localdir" default="${dest.dir}" />
+ <attribute name="user" default="anonymous"/>
+ <attribute name="pw" default="anonymous"/>
+ <sequential>
+ <ftp server="@{host}" port="@{port}" userid="@{user}" password="@{pw}" passive="true"
+ remotedir="@{remotedir}" action="get" depends="true" preserveLastModified="true"
+ skipFailedTransfers="true">
+ <fileset dir="@{localdir}">
+ <include name="@{filename}" />
+ </fileset>
+ </ftp>
+ </sequential>
+ </macrodef>
+
+ </target>
+
+
+
+ <!-- any init stuff -->
+ <target name="init" depends="macros" />
+
+ <target name="init-no-m2" depends="nonm2-macros" />
+
+ <target name="init-cache">
+ <available property="temp.cache.already.exists" file="${temp.dir}" type="dir" />
+ <condition property="user.wants.temp.cache">
+ <and>
+ <isset property="keep.temp.dir" />
+ <not>
+ <or>
+ <equals arg1="${keep.temp.dir}" arg2="false" casesensitive="false" />
+ <equals arg1="${keep.temp.dir}" arg2="no" casesensitive="false" />
+ <equals arg1="${keep.temp.dir}" arg2="off" casesensitive="false" />
+ </or>
+ </not>
+ </and>
+ </condition>
+ <condition property="delete.temp.cache">
+ <and>
+ <not>
+ <isset property="temp.cache.already.exists" />
+ </not>
+ <not>
+ <isset property="user.wants.temp.cache" />
+ </not>
+ </and>
+ </condition>
+ </target>
+
+ <target name="-setup-temp-cache" depends="init-cache" unless="temp.cache.already.exists"
+ description="Setup temporary cache for downloaded files">
+ <mkdir dir="${temp.dir}" />
+ </target>
+
+ <target name="-cleanup-temp-cache" depends="init-cache" if="delete.temp.cache"
+ description="Gets rid of the temporary cache directory">
+ <delete dir="${temp.dir}" />
+ </target>
+
+
+ <target name="diag" depends="init">
+ <echoproperties />
+ </target>
+
+ <target name="logging"
+ description="load logging libraries"
+ depends="init">
+ <f2 project="log4j" />
+ <f2 project="commons-logging" archive="commons-logging-api" />
+ </target>
+
+ <target name="junit"
+ description="load junit libraries"
+ depends="init">
+ <f2 project="junit" />
+ </target>
+
+ <target name="xml"
+ description="load full XML libraries (xalan, resolver)"
+ depends="init">
+ <f2 project="xalan" />
+ <f2 project="xml-resolver" />
+ </target>
+
+ <target name="networking"
+ description="load networking libraries (commons-net; jsch)"
+ depends="init">
+ <f2 project="commons-net" />
+ <f2 project="com.jcraft" archive="jsch"/>
+ </target>
+
+ <target name="regexp"
+ description="load regexp libraries"
+ depends="init">
+ <f2 project="regexp" />
+ <f2 project="oro" />
+ </target>
+
+ <target name="antlr"
+ description="load antlr libraries"
+ depends="init">
+ <f2 project="antlr" />
+ </target>
+
+ <target name="bcel"
+ description="load bcel libraries"
+ depends="init">
+ <f2 project="bcel" />
+ </target>
+
+ <target name="jdepend"
+ description="load jdepend libraries"
+ depends="init">
+ <f2 project="jdepend" />
+ </target>
+
+ <target name="bsf"
+ description="load bsf libraries"
+ depends="init">
+ <f2 project="bsf" />
+ </target>
+
+ <target name="jruby"
+ description="load jruby"
+ depends="bsf">
+ <f2 project="org.jruby" archive="jruby"/>
+ </target>
+
+ <target name="beanshell"
+ description="load beanshell support"
+ depends="bsf">
+ <f2 project="org.beanshell" archive="bsh"/>
+ <f2 project="org.beanshell" archive="bsh-core"/>
+ </target>
+
+ <target name="jython"
+ description="load jython"
+ depends="bsf">
+ <f2 project="jython" archive="jython"/>
+ </target>
+
+ <target name="rhino"
+ description="load rhino"
+ depends="bsf">
+ <f2 project="rhino" archive="js"/>
+ </target>
+
+ <target name="script"
+ description="load script languages (except jython)"
+ depends="bsf,jruby,beanshell,rhino"/>
+
+ <target name="debugging"
+ description="internal ant debugging"
+ depends="init">
+ <f2 project="which" />
+ </target>
+
+ <target name="javamail" depends="init"
+ description="load javamail">
+ <f2 project="javax.mail" archive="mail"/>
+ </target>
+
+ <target name="jspc" depends="init" description="loads Jasper">
+ <f2 project="tomcat" archive="jasper-compiler"/>
+ <f2 project="tomcat" archive="jasper-runtime"/>
+ <f2 project="javax.servlet" archive="servlet-api"/>
+ </target>
+
+ <target name="jai" depends="init"
+ description="load java advanced imaging">
+ <f2 project="javax.media" archive="jai-core" repository="https://repository.jboss.org/nexus/content/groups/public/"/>
+ <f2 project="com.sun.media" archive="jai-codec" repository="https://repository.jboss.org/nexus/content/groups/public/"/>
+ </target>
+
+ <target name="netrexx" depends="init-no-m2,-setup-temp-cache,-fetch-netrexx,-fetch-netrexx-no-commons-net"
+ description="load NetRexx compiler">
+ <copy todir="${dest.dir}" flatten="true">
+ <zipfileset src="${temp.dir}/NetRexx.zip">
+ <include name="NetRexx\lib\NetRexxC.jar" />
+ <include name="NetRexx\browse\license.txt" />
+ </zipfileset>
+ </copy>
+ <antcall target="-cleanup-temp-cache"/>
+ </target>
+ <available property="have.commons.net" classname="org.apache.commons.net.ftp.FTPClientConfig"/>
+ <target name="-fetch-netrexx" if="have.commons.net">
+ <get-ftp-file host="ftp.software.ibm.com" remotedir="/software/awdtools/netrexx"
+ filename="NetRexx.zip" localdir="${temp.dir}" />
+ </target>
+ <target name="-fetch-netrexx-no-commons-net" unless="have.commons.net">
+ <get src="ftp://ftp.software.ibm.com/software/awdtools/netrexx/NetRexx.zip" dest="${temp.dir}/NetRexx.zip" skipexisting="true"/>
+ </target>
+
+ <target name="all"
+ description="load all the libraries (except jython)"
+ depends="logging,junit,xml,networking,regexp,antlr,bcel,jdepend,bsf,debugging,script,javamail,jspc,jai,netrexx" />
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/get-m2.xml b/framework/src/ant/apache-ant-1.9.6/get-m2.xml
new file mode 100644
index 00000000..4111e81e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/get-m2.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0"?>
+
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!--
+ =======================================================================
+ Build file to fetch maven2 tasks; extracted from (Ant's) fetch.xml
+ =======================================================================
+-->
+<project name="get-m2" default="get-m2" basedir=".">
+
+<description>
+ This build file downloads the Maven2 Ant tasks,
+ and installs them in the location specified by the m2.dest.dir property.
+
+ You may need to set proxy settings. On Java1.5, Ant tries to get
+ this from the OS, unless you use the -noproxy option.
+
+ Proxies can be configured manually setting the JVM proxy values in the
+ ANT_OPTS environment variable.
+
+ For example, to set the proxy up in the tcsh shell, the command would be
+ something like:
+
+ For csh/tcsh:
+ setenv ANT_OPTS "-Dhttp.proxyHost=proxy -Dhttp.proxyPort=8080"
+ For bash:
+ export ANT_OPTS="-Dhttp.proxyHost=proxy -Dhttp.proxyPort=8080"
+ For Windows, set the environment variable in the appropriate dialog box
+ and open a new console. or, by hand
+ set ANT_OPTS = -Dhttp.proxyHost=proxy -Dhttp.proxyPort=8080
+</description>
+
+ <property file="get-m2.properties" />
+
+ <property name="m2.antlib.resource"
+ value="org/apache/maven/artifact/ant/antlib.xml" />
+
+ <property name="m2.antlib.uri"
+ value="antlib:org.apache.maven.artifact.ant" />
+
+ <macrodef name="require">
+ <attribute name="property" />
+ <sequential>
+ <fail unless="@{property}">$${@{property}} not specified</fail>
+ </sequential>
+ </macrodef>
+
+ <target name="probe-m2">
+ <require property="m2.dest.dir" />
+ <require property="m2.jar.name" />
+
+ <!-- Look for M2 ant tasks in our classpath-->
+ <property name="m2.artifact" location="${m2.dest.dir}/${m2.jar.name}" />
+ <available property="m2.antlib.found" resource="${m2.antlib.resource}" />
+ <condition property="m2.antlib.typefound">
+ <typefound name="${m2.antlib.uri}:artifact" />
+ </condition>
+ <available property="m2.artifact.found" file="${m2.artifact}" type="file" />
+ </target>
+
+ <target name="download-m2" depends="probe-m2" unless="m2.artifact.found">
+ <require property="m2.antlib.url" />
+ <echo>Downloading to ${m2.dest.dir}</echo>
+
+ <mkdir dir="${m2.dest.dir}" />
+ <!-- fetch M2 ant tasks into our repository, if it is not there-->
+ <get src="${m2.antlib.url}"
+ dest="${m2.artifact}"
+ verbose="true"
+ usetimestamp="false" />
+ </target>
+
+ <target name="dont-validate-m2-checksum" depends="probe-m2"
+ if="m2.artifact.found">
+ <property name="checksum.equal" value="true" />
+ </target>
+
+ <target name="validate-m2-checksum"
+ depends="download-m2,dont-validate-m2-checksum"
+ if="m2.sha1.checksum" unless="m2.artifact.found">
+ <checksum file="${m2.artifact}"
+ algorithm="SHA"
+ property="${m2.sha1.checksum}"
+ verifyProperty="checksum.equal" />
+ </target>
+
+ <target name="checksum-mismatch" depends="validate-m2-checksum"
+ if="m2.sha1.checksum" unless="checksum.equal">
+ <delete file="${m2.artifact}" />
+ <fail>
+ Failed to verify the downloaded file ${m2.antlib.url}" against the checksum
+ coded into libraries.properties.
+ The local copy has been deleted, for security reasons
+ </fail>
+ </target>
+
+ <target name="checksum-match" depends="checksum-mismatch"
+ unless="m2.antlib.found">
+ <taskdef classpath="${m2.artifact}" resource="${m2.antlib.resource}"
+ uri="${m2.antlib.uri}" />
+ </target>
+
+ <target name="get-m2" depends="checksum-match"
+ description="Download the Maven2 Ant tasks" />
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/lib/README b/framework/src/ant/apache-ant-1.9.6/lib/README
new file mode 100644
index 00000000..67e37ce7
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/lib/README
@@ -0,0 +1,3 @@
+Please refer to the Ant manual under Installing Ant / Library
+Dependencies for a list of the jar requirements for various optional
+tasks and features.
diff --git a/framework/src/ant/apache-ant-1.9.6/lib/libraries.properties b/framework/src/ant/apache-ant-1.9.6/lib/libraries.properties
new file mode 100644
index 00000000..d6aee6bc
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/lib/libraries.properties
@@ -0,0 +1,65 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+#this file declares the libraries for use in
+#a given release of the components
+
+#if you change this, change the checksum to match
+m2.version=2.0.4
+m2.url=http\://repo1.maven.org/maven2
+m2.artifact-name=maven-artifact-ant
+m2.jar.name=${m2.artifact-name}-${m2.version}-dep.jar
+#this is the URL of the antlib library, that is pulled down for everything else.
+m2.antlib.url=${m2.url}/org/apache/maven/${m2.artifact-name}/${m2.version}/${m2.jar.name}
+#this is the sha1 checksum of the artifact
+m2.sha1.checksum=4e7ddfdb91600e9b59bb965ff8eef2f06015df50
+
+# Repository to use by default for fetching dependencies.
+m2.repo=http://repo1.maven.org/maven2/
+
+#versions of different libraries. Please keep in alphabetical order, except
+#when a specific dependency forces them to be out-of-order
+antlr.version=2.7.7
+bcel.version=5.1
+bsf.version=2.4.0
+bsh.version=2.0b4
+bsh-core.version=${bsh.version}
+commons-net.version=1.4.1
+commons-logging.version=1.1
+commons-logging-api.version=${commons-logging.version}
+jai-core.version=1.1.3
+jai-codec.version=1.1.3
+jasper-compiler.version=4.1.36
+jasper-runtime.version=${jasper-compiler.version}
+jdepend.version=2.9.1
+jruby.version=0.9.8
+junit.version=4.11
+jsch.version=0.1.50
+jython.version=2.1
+#log4j 1.2.15 requires JMS and a few other Sun jars that are not in the m2 repo
+log4j.version=1.2.14
+#js is the javascript implementation of the rhino project
+#17R1 is compiled with Java5 so we can't use the jar when building with JDK 1.4
+js.version=1.6R7
+oro.version=2.0.8
+regexp.version=1.3
+servlet-api.version=2.3
+which.version=1.0
+xalan.version=2.7.1
+xml-resolver.version=1.2
+mail.version=1.4
+#paired
+jacl.version=1.2.6
+tcljava.version=${jacl.version}
diff --git a/framework/src/ant/apache-ant-1.9.6/lib/optional/hamcrest-core-1.3.jar b/framework/src/ant/apache-ant-1.9.6/lib/optional/hamcrest-core-1.3.jar
new file mode 100644
index 00000000..9d5fe16e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/lib/optional/hamcrest-core-1.3.jar
Binary files differ
diff --git a/framework/src/ant/apache-ant-1.9.6/lib/optional/junit-3.8.2.jar b/framework/src/ant/apache-ant-1.9.6/lib/optional/junit-3.8.2.jar
new file mode 100644
index 00000000..c8f711d0
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/lib/optional/junit-3.8.2.jar
Binary files differ
diff --git a/framework/src/ant/apache-ant-1.9.6/lib/optional/junit-4.11.jar b/framework/src/ant/apache-ant-1.9.6/lib/optional/junit-4.11.jar
new file mode 100644
index 00000000..aaf74448
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/lib/optional/junit-4.11.jar
Binary files differ
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Integration/anttool1.gif b/framework/src/ant/apache-ant-1.9.6/manual/Integration/anttool1.gif
new file mode 100644
index 00000000..ad450ba6
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Integration/anttool1.gif
Binary files differ
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Integration/jext-plugin.html b/framework/src/ant/apache-ant-1.9.6/manual/Integration/jext-plugin.html
new file mode 100644
index 00000000..84e88c08
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Integration/jext-plugin.html
@@ -0,0 +1,56 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!DOCTYPE html PUBLIC "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta http-equiv="Content-Language" content="en-us">
+ <link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Apache AntWork Plugin for the Jext Java Text Editor</title>
+</head>
+<body>
+
+<h1>AntWork Plugin for the Jext Java Text Editor</h1>
+ <a name="authors"></a>by<ul>
+ <li>Klaus Hartlage
+ (<a href="mailto:KHartlage@t-online.de">KHartlage@t-online.de</a>)</li>
+</ul>
+<hr>
+
+<p>You can download the plugin at: <a
+href="ftp://jext.sourceforge.net/pub/jext/plugins/AntWork.zip">ftp://jext.sourceforge.net/pub/jext/plugins/AntWork.zip</a></p>
+
+<h2>Installation instructions from the Readme.txt:</h2>
+
+<p>You have to enable the Jext Console to see the Apache Ant output (menu:
+Edit-&gt;Options... - General Panel), because the Ant messages are
+redirected to the Jext console.</p>
+
+<p>You can configure the Ant call in the Jext menu: Edit-&gt;Options... -
+Plugin Options - Antwork Plugin Panel; here you can set the ant home
+directory and the path to your build file.</p>
+
+<p>You can start AntWork in the menu: Plugins-&gt;Ant-&gt;Work Now! In the
+appearing dialog box you can enter the target which you want to
+compile.</p>
+
+<p>If a javac error occurs in the ant run an error-list opens within
+Jext. With a double-click on the error-message you jump to the error
+in the specified java text file.</p>
+
+
+</body></html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Integration/remacc.gif b/framework/src/ant/apache-ant-1.9.6/manual/Integration/remacc.gif
new file mode 100644
index 00000000..e02e0488
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Integration/remacc.gif
Binary files differ
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Integration/toolmenu.gif b/framework/src/ant/apache-ant-1.9.6/manual/Integration/toolmenu.gif
new file mode 100644
index 00000000..164db44d
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Integration/toolmenu.gif
Binary files differ
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/LICENSE b/framework/src/ant/apache-ant-1.9.6/manual/LICENSE
new file mode 100644
index 00000000..f820d4bd
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/LICENSE
@@ -0,0 +1,203 @@
+/*
+ * Apache License
+ * Version 2.0, January 2004
+ * http://www.apache.org/licenses/
+ *
+ * TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+ *
+ * 1. Definitions.
+ *
+ * "License" shall mean the terms and conditions for use, reproduction,
+ * and distribution as defined by Sections 1 through 9 of this document.
+ *
+ * "Licensor" shall mean the copyright owner or entity authorized by
+ * the copyright owner that is granting the License.
+ *
+ * "Legal Entity" shall mean the union of the acting entity and all
+ * other entities that control, are controlled by, or are under common
+ * control with that entity. For the purposes of this definition,
+ * "control" means (i) the power, direct or indirect, to cause the
+ * direction or management of such entity, whether by contract or
+ * otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ * outstanding shares, or (iii) beneficial ownership of such entity.
+ *
+ * "You" (or "Your") shall mean an individual or Legal Entity
+ * exercising permissions granted by this License.
+ *
+ * "Source" form shall mean the preferred form for making modifications,
+ * including but not limited to software source code, documentation
+ * source, and configuration files.
+ *
+ * "Object" form shall mean any form resulting from mechanical
+ * transformation or translation of a Source form, including but
+ * not limited to compiled object code, generated documentation,
+ * and conversions to other media types.
+ *
+ * "Work" shall mean the work of authorship, whether in Source or
+ * Object form, made available under the License, as indicated by a
+ * copyright notice that is included in or attached to the work
+ * (an example is provided in the Appendix below).
+ *
+ * "Derivative Works" shall mean any work, whether in Source or Object
+ * form, that is based on (or derived from) the Work and for which the
+ * editorial revisions, annotations, elaborations, or other modifications
+ * represent, as a whole, an original work of authorship. For the purposes
+ * of this License, Derivative Works shall not include works that remain
+ * separable from, or merely link (or bind by name) to the interfaces of,
+ * the Work and Derivative Works thereof.
+ *
+ * "Contribution" shall mean any work of authorship, including
+ * the original version of the Work and any modifications or additions
+ * to that Work or Derivative Works thereof, that is intentionally
+ * submitted to Licensor for inclusion in the Work by the copyright owner
+ * or by an individual or Legal Entity authorized to submit on behalf of
+ * the copyright owner. For the purposes of this definition, "submitted"
+ * means any form of electronic, verbal, or written communication sent
+ * to the Licensor or its representatives, including but not limited to
+ * communication on electronic mailing lists, source code control systems,
+ * and issue tracking systems that are managed by, or on behalf of, the
+ * Licensor for the purpose of discussing and improving the Work, but
+ * excluding communication that is conspicuously marked or otherwise
+ * designated in writing by the copyright owner as "Not a Contribution."
+ *
+ * "Contributor" shall mean Licensor and any individual or Legal Entity
+ * on behalf of whom a Contribution has been received by Licensor and
+ * subsequently incorporated within the Work.
+ *
+ * 2. Grant of Copyright License. Subject to the terms and conditions of
+ * this License, each Contributor hereby grants to You a perpetual,
+ * worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ * copyright license to reproduce, prepare Derivative Works of,
+ * publicly display, publicly perform, sublicense, and distribute the
+ * Work and such Derivative Works in Source or Object form.
+ *
+ * 3. Grant of Patent License. Subject to the terms and conditions of
+ * this License, each Contributor hereby grants to You a perpetual,
+ * worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ * (except as stated in this section) patent license to make, have made,
+ * use, offer to sell, sell, import, and otherwise transfer the Work,
+ * where such license applies only to those patent claims licensable
+ * by such Contributor that are necessarily infringed by their
+ * Contribution(s) alone or by combination of their Contribution(s)
+ * with the Work to which such Contribution(s) was submitted. If You
+ * institute patent litigation against any entity (including a
+ * cross-claim or counterclaim in a lawsuit) alleging that the Work
+ * or a Contribution incorporated within the Work constitutes direct
+ * or contributory patent infringement, then any patent licenses
+ * granted to You under this License for that Work shall terminate
+ * as of the date such litigation is filed.
+ *
+ * 4. Redistribution. You may reproduce and distribute copies of the
+ * Work or Derivative Works thereof in any medium, with or without
+ * modifications, and in Source or Object form, provided that You
+ * meet the following conditions:
+ *
+ * (a) You must give any other recipients of the Work or
+ * Derivative Works a copy of this License; and
+ *
+ * (b) You must cause any modified files to carry prominent notices
+ * stating that You changed the files; and
+ *
+ * (c) You must retain, in the Source form of any Derivative Works
+ * that You distribute, all copyright, patent, trademark, and
+ * attribution notices from the Source form of the Work,
+ * excluding those notices that do not pertain to any part of
+ * the Derivative Works; and
+ *
+ * (d) If the Work includes a "NOTICE" text file as part of its
+ * distribution, then any Derivative Works that You distribute must
+ * include a readable copy of the attribution notices contained
+ * within such NOTICE file, excluding those notices that do not
+ * pertain to any part of the Derivative Works, in at least one
+ * of the following places: within a NOTICE text file distributed
+ * as part of the Derivative Works; within the Source form or
+ * documentation, if provided along with the Derivative Works; or,
+ * within a display generated by the Derivative Works, if and
+ * wherever such third-party notices normally appear. The contents
+ * of the NOTICE file are for informational purposes only and
+ * do not modify the License. You may add Your own attribution
+ * notices within Derivative Works that You distribute, alongside
+ * or as an addendum to the NOTICE text from the Work, provided
+ * that such additional attribution notices cannot be construed
+ * as modifying the License.
+ *
+ * You may add Your own copyright statement to Your modifications and
+ * may provide additional or different license terms and conditions
+ * for use, reproduction, or distribution of Your modifications, or
+ * for any such Derivative Works as a whole, provided Your use,
+ * reproduction, and distribution of the Work otherwise complies with
+ * the conditions stated in this License.
+ *
+ * 5. Submission of Contributions. Unless You explicitly state otherwise,
+ * any Contribution intentionally submitted for inclusion in the Work
+ * by You to the Licensor shall be under the terms and conditions of
+ * this License, without any additional terms or conditions.
+ * Notwithstanding the above, nothing herein shall supersede or modify
+ * the terms of any separate license agreement you may have executed
+ * with Licensor regarding such Contributions.
+ *
+ * 6. Trademarks. This License does not grant permission to use the trade
+ * names, trademarks, service marks, or product names of the Licensor,
+ * except as required for reasonable and customary use in describing the
+ * origin of the Work and reproducing the content of the NOTICE file.
+ *
+ * 7. Disclaimer of Warranty. Unless required by applicable law or
+ * agreed to in writing, Licensor provides the Work (and each
+ * Contributor provides its Contributions) on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied, including, without limitation, any warranties or conditions
+ * of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ * PARTICULAR PURPOSE. You are solely responsible for determining the
+ * appropriateness of using or redistributing the Work and assume any
+ * risks associated with Your exercise of permissions under this License.
+ *
+ * 8. Limitation of Liability. In no event and under no legal theory,
+ * whether in tort (including negligence), contract, or otherwise,
+ * unless required by applicable law (such as deliberate and grossly
+ * negligent acts) or agreed to in writing, shall any Contributor be
+ * liable to You for damages, including any direct, indirect, special,
+ * incidental, or consequential damages of any character arising as a
+ * result of this License or out of the use or inability to use the
+ * Work (including but not limited to damages for loss of goodwill,
+ * work stoppage, computer failure or malfunction, or any and all
+ * other commercial damages or losses), even if such Contributor
+ * has been advised of the possibility of such damages.
+ *
+ * 9. Accepting Warranty or Additional Liability. While redistributing
+ * the Work or Derivative Works thereof, You may choose to offer,
+ * and charge a fee for, acceptance of support, warranty, indemnity,
+ * or other liability obligations and/or rights consistent with this
+ * License. However, in accepting such obligations, You may act only
+ * on Your own behalf and on Your sole responsibility, not on behalf
+ * of any other Contributor, and only if You agree to indemnify,
+ * defend, and hold each Contributor harmless for any liability
+ * incurred by, or claims asserted against, such Contributor by reason
+ * of your accepting any such warranty or additional liability.
+ *
+ * END OF TERMS AND CONDITIONS
+ *
+ * APPENDIX: How to apply the Apache License to your work.
+ *
+ * To apply the Apache License to your work, attach the following
+ * boilerplate notice, with the fields enclosed by brackets "[]"
+ * replaced with your own identifying information. (Don't include
+ * the brackets!) The text should be enclosed in the appropriate
+ * comment syntax for the file format. We also recommend that a
+ * file or class name and description of purpose be included on the
+ * same "printed page" as the copyright notice for easier
+ * identification within third-party archives.
+ *
+ * Copyright [yyyy] [name of copyright owner]
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/BorlandEJBTasks.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/BorlandEJBTasks.html
new file mode 100644
index 00000000..126fe5c5
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/BorlandEJBTasks.html
@@ -0,0 +1,143 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Borland EJB Tasks</title>
+</head>
+
+<body>
+
+<h2><a name="log">BorlandDeploy</a>Tool</h2>
+<p>by Benoit Moussaud (<a href="mailto:benoit.moussaud@criltelecom.com">benoit.moussaud@criltelecom.com</a>)</p>
+
+
+<h3>Description</h3>
+<p>The BorlandDeployTool is a vendor specific nested element for the Ejbjar optional task.</p>
+<p>BorlandDeploymentTool is dedicated to the Borland Application Server 4.5.x and Borland
+ Enterprise Server 5.x. It generates and compiles the stubs and skeletons for all ejb described into the
+ Deployment Descriptor, builds the jar file including the support files and
+ verify whether the produced jar is valid or not.</p>
+
+<p>Benoit Moussaud maintains a separate <a
+href="http://www.moussaud.org/ejbjar.html">FAQ</a> for this task at
+his homepage.</p>
+
+<h3>Borland element</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top" width="63"><b>Attribute</b></td>
+ <td valign="top" width="915"><b>Description</b></td>
+ <td align="center" valign="top" width="62"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top" width="63">destdir</td>
+ <td valign="top" width="915">The base directory into which the generated borland
+ ready jar files are deposited</td>
+ <td align="center" valign="middle" width="62">yes</td>
+ </tr>
+ <tr>
+ <td valign="top" width="63">debug</td>
+ <td valign="top" width="915">If true, turn on the debug mode for each borland
+ tools (java2iiop, iastool ...) default = false</td>
+ <td align="center" valign="middle" width="62">no</td>
+ </tr>
+ <tr>
+ <td valign="top" width="63">verify</td>
+ <td valign="top" width="915">If true, turn on the verification at the end
+ of the jar production (default = false)</td>
+ <td align="center" valign="middle" width="62">no</td>
+ </tr>
+ <tr>
+ <td valign="top" width="63">verifyargs</td>
+ <td valign="top" width="915">extra parameter for verify command</td>
+ <td align="center" valign="middle" width="62">no</td>
+ </tr>
+ <tr>
+ <td valign="top" width="63">suffix</td>
+ <td valign="top" width="915">String value appended to the basename of the
+ deployment descriptor to create the filename of the Borland EJB jar file.</td>
+ <td align="center" valign="middle" width="62">No, defaults to '-ejb.jar'.</td>
+ </tr>
+ <tr>
+ <td valign="top" width="63">basdtd</td>
+ <td valign="top" width="915"><b>Deprecated</b>. Defines the location of the
+ DTD which covers the Borland specific deployment descriptors.
+ This should not be necessary if you have borland in your classpath. If you
+ do not, you should use a nested
+ <a href="ejb.html#ejbjar-dtd"><code>&lt;dtd&gt;</code></a> element, described
+ in the ejbjar task documentation.</td>
+ <td align="center" valign="middle" width="62">no</td>
+ </tr>
+ <tr>
+ <td valign="top" width="63">ejbdtd</td>
+ <td valign="top" width="915"><b>Deprecated</b>. Defines the location of the
+ ejb-jar DTD in the class hierarchy. This should not be necessary
+ if you have borland in your classpath. If you do not, you should use a
+ nested <a href="ejb.html#ejbjar-dtd"><code>&lt;dtd&gt;</code></a> element,
+ described in the ejbjar task
+ documentation. </td>
+ <td align="center" valign="middle" width="62">no</td>
+ </tr>
+ <tr>
+ <td valign="top" width="63">generateclient </td>
+ <td valign="top" width="915">If true, turn on the generation of the corresponding
+ ejbjar (default = false)</td>
+ <td align="center" valign="middle" width="62">no</td>
+ </tr>
+ <tr>
+ <td valign="top" width="63">version</td>
+ <td valign="top" width="915">set the Borland Application Version.
+ <ul>
+ <li>4 means B.A.S (Borland Application Server) 4.x, target will add ejb-inprise.xml file</li>
+ <li>5 means B.E.S (Borland Application Server) 5.x, target will add ejb-borland.xml file</li>
+ </ul>
+ </td>
+ <td align="center" valign="middle" width="62">No, defaults to 4</td>
+ </tr>
+ <tr>
+ <td valign="top" width="63">java2iiopParams </td>
+ <td valign="top" width="915">If filled, the params are added to the java2iiop command (ex: -no_warn_missing_define)</td>
+ <td align="center" valign="middle" width="62">no</td>
+ </tr>
+
+</table>
+
+<h3>Examples</h3>
+<p>The following build.xml snippet is an example of how to use Borland element
+ into the ejbjar task</p>
+<pre> &lt;ejbjar srcdir=&quot;${build.classes}&quot; basejarname=&quot;vsmp&quot; descriptordir=&quot;${rsc.dir}/hrmanager&quot;&gt;
+ &lt;borland destdir=&quot;lib&quot; verify=&quot;on&quot; generateclient=&quot;on&quot; version=&quot;5&quot;&gt;
+ &lt;classpath refid=&quot;classpath&quot;/&gt;
+ &lt;/borland&gt;
+ &lt;include name=&quot;**\ejb-jar.xml&quot;/&gt;
+ &lt;support dir=&quot;${build.classes}&quot;&gt;
+ &lt;include name=&quot;demo\*.class&quot;/&gt;
+ &lt;include name=&quot;demo\helper\*.class&quot;/&gt;
+ &lt;/support&gt;
+ &lt;/ejbjar&gt;</pre>
+<pre>The borland element will generate into the lib dir an ejb jar file using the deployment descriptor placed into the ${rsc.dir}/hrmanager directory.
+The verify phase is turned on and the generate client phase as well.
+</pre>
+
+<h3>&nbsp;</h3>
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/BorlandGenerateClient.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/BorlandGenerateClient.html
new file mode 100644
index 00000000..01956b25
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/BorlandGenerateClient.html
@@ -0,0 +1,90 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>BorlandGenerateClient Task</title>
+</head>
+
+<body>
+
+<h2><a name="log">BorlandGenerateClient</a></h2>
+<p>by Benoit Moussaud (<a href="mailto:benoit.moussaud@criltelecom.com">benoit.moussaud@criltelecom.com</a>)</p>
+<h3>Description</h3>
+<p>The BorlandGenerateClient is a task dedicated to Borland Application Server
+ v 4.5. It offers to generate the client jar file corresponding to an ejb jar
+ file.</p>
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top" width="63"><b>Attribute</b></td>
+ <td valign="top" width="915"><b>Description</b></td>
+ <td align="center" valign="top" width="62"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top" width="63">ejbjar</td>
+ <td valign="top" width="915">ejb jar file</td>
+ <td align="center" valign="middle" width="62">yes</td>
+ </tr>
+ <tr>
+ <td valign="top" width="63">debug</td>
+ <td valign="top" width="915">If true, turn on the debug mode for each borland
+ tools (java2iiop, iastool ...) default = false</td>
+ <td align="center" valign="middle" width="62">no</td>
+ </tr>
+ <tr>
+ <td valign="top" width="63">clientjar</td>
+ <td valign="top" width="915">client jar file name. If missing the client jar
+ file name is build using the ejbjar file name: ejbjar = hellobean-ejb.jar
+ =&gt; hellobean-ejbclient.jar</td>
+ <td align="center" valign="middle" width="62">no</td>
+ </tr>
+ <tr>
+ <td valign="top" width="63">mode</td>
+ <td valign="top" width="915">choose the command launching mode. Two values:
+ java or fork. default = fork. java is not supported for version=5.Possibility to specify a classpath.</td>
+ <td align="center" valign="middle" width="62">no</td>
+ </tr>
+ <tr>
+ <td valign="top" width="63">version</td>
+ <td valign="top" width="915">set the Borland Application Version.
+ <ul>
+ <li>4 means B.A.S (Borland Application Server 4.x)</li>
+ <li>5 means B.E.S (Borland Application Server 5.x)</li>
+ </ul>
+ </td>
+ <td align="center" valign="middle" width="62">No, defaults to 4</td>
+ </tr>
+</table>
+
+<h3>Examples</h3>
+<p>The following build.xml snippet is an example of how to use Borland element
+ into the ejbjar task using the java mode.</p>
+<pre>
+&lt;blgenclient ejbjar=&quot;lib/secutest-ejb.jar&quot; clientjar=&quot;lib/client.jar&quot; debug=&quot;true&quot; mode=&quot;fork&quot;&gt; version=&quot;5&quot;&gt;
+ &lt;classpath&gt;
+ &lt;pathelement location=&quot;mymodule.jar&quot;/&gt;
+ &lt;/classpath&gt;
+&lt;/blgenclient&gt;
+</pre>
+<pre>&nbsp;</pre>
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/ant.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/ant.html
new file mode 100644
index 00000000..87b78bb2
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/ant.html
@@ -0,0 +1,413 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Ant Task</title>
+</head>
+
+<body>
+
+<h2><a name="ant">Ant</a></h2>
+<h3>Description</h3>
+
+<p>Runs Apache Ant on a supplied buildfile. This can be used to build
+subprojects. <strong>This task must not be used outside of a
+<code>target</code> if it invokes the same build file it is part
+of.</strong></p>
+
+<p>When the <i>antfile</i> attribute is omitted, the file &quot;build.xml&quot;
+in the supplied directory (<i>dir</i> attribute) is used.</p>
+<p>If no target attribute is supplied, the default target of the new project is
+used.</p>
+<p>By default, all of the properties of the current project will be
+available in the new project. Alternatively, you can set the
+<i>inheritAll</i> attribute to <code>false</code> and only
+&quot;user&quot; properties (i.e., those passed on the command-line)
+will be passed to the new project. In either case, the set of
+properties passed to the new project will override the properties that
+are set in the new project (See also the <a
+href="property.html">property task</a>).</p>
+
+<p>You can also set properties in the new project from the old project
+by using nested property tags. These properties are always passed
+to the new project and any project created in that project
+regardless of the setting of <i>inheritAll</i>. This allows you to
+parameterize your subprojects.</p>
+
+<p>When more than one nested <code>&lt;property&gt;</code> element
+ would set a property of the same name, the one declared last will
+ win. This is for backwards compatibility reasons even so it is
+ different from the way <code>&lt;property&gt;</code> tasks in build
+ files behave.</p>
+
+<p>Properties defined on the command line cannot be overridden by
+ nested <code>&lt;property&gt;</code> elements. <em>Since Ant
+ 1.8.0.</em> the same is true for nested structures
+ of <code>&lt;ant&gt;</code> tasks: if a build file <em>A</em>
+ invokes <em>B</em> via an <code>&lt;ant&gt;</code> task setting a
+ property with a nested <code>&lt;property&gt;</code> element
+ and <em>B</em> contains an <code>&lt;ant&gt;</code> tasks
+ invoking <em>C</em>, <em>C</em> will see the value set
+ in <em>A</em>, even if <em>B</em> used a
+ nested <code>&lt;property&gt;</code> element as well.</p>
+
+<p>References to data types can also be passed to the new project, but
+by default they are not. If you set the inheritrefs attribute to
+true, all references will be copied, but they will not override
+references defined in the new project.</p>
+
+<p>Nested <a href="#reference"><i><code>&lt;reference&gt;</code></i></a> elements
+can also be used to copy references from the calling project to the
+new project, optionally under a different id. References taken from
+nested elements will override existing references that have been
+defined outside of targets in the new project - but not those defined
+inside of targets.</p>
+
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">antfile</td>
+ <td valign="top">the buildfile to use. Defaults to
+ &quot;build.xml&quot;. This file is expected to be a filename
+ relative to the dir attribute given.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">dir</td>
+ <td valign="top">the directory to use as a basedir for the new Ant
+ project (unless useNativeBasedir is set to true).
+ Defaults to the current project's basedir, unless
+ inheritall has been set to false, in which case it doesn't
+ have a default value. This will override the basedir
+ setting of the called project.<br/>
+ Also serves as the directory to resolve the antfile and output
+ attribute's values (if any).
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">target</td>
+ <td valign="top">the target of the new Ant project that should be executed.
+ Defaults to the new project's default target.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">output</td>
+ <td valign="top">Filename to write the ant output to. This is
+ relative to the value of the dir attribute if it has been set or
+ to the base directory of the current project otherwise.
+ </td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">inheritAll</td>
+ <td valign="top">If <code>true</code>, pass all properties to the
+ new Ant project. Defaults to <code>true</code>.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">inheritRefs</td>
+ <td valign="top">If <code>true</code>, pass all references to the
+ new Ant project. Defaults to <code>false</code>.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">useNativeBasedir</td>
+ <td valign="top">If set to true, the child build will use the same
+ basedir as it would have used when run from the command line
+ (i.e. the basedir one would expect when looking at the child
+ build's buildfile). Defaults to <code>false</code>. <em>since
+ Ant 1.8.0</em></td>
+ <td valign="top" align="center">No</td>
+ </tr>
+</table>
+
+<h3>Parameters specified as nested elements</h3>
+
+<h4>property</h4>
+<p>See the description of the <a href="property.html">property
+task</a>. <br>
+These properties become equivalent to properties you define on
+the command line. These are special properties and they will always get passed
+down, even through additional <code>&lt;*ant*&gt;</code> tasks with inheritall set to
+false (see above). <br>
+Note that the <code>refid</code> attribute points to a
+reference in the calling project, not in the new one.</p>
+
+<h4><a name="reference">reference</a></h4>
+<p>Used to choose references that shall be copied into the new project,
+optionally changing their id.</p>
+
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">refid</td>
+ <td valign="top">The id of the reference in the calling project.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">torefid</td>
+ <td valign="top">The id of the reference in the new project.</td>
+ <td valign="top" align="center">No, defaults to the value of refid.</td>
+ </tr>
+</table>
+
+<h4>propertyset</h4>
+
+<p>You can specify a set of properties to be copied into the new
+project with <a
+href="../Types/propertyset.html">propertyset</a>s.</p>
+
+<p><em>since Ant 1.6</em>.</p>
+
+<h4>target</h4>
+
+<p>You can specify multiple targets using nested <code>&lt;target&gt;</code> elements
+instead of using the target attribute. These will be executed as if
+Ant had been invoked with a single target whose dependencies are the
+targets so specified, in the order specified.</p>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">name</td>
+ <td valign="top">The name of the called target.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+</table>
+<p><em>since Ant 1.6.3</em>.</p>
+
+<h3>Basedir of the new project</h3>
+
+<p>If you set <code>useNativeBasedir</code> to true, the basedir of
+ the new project will be whatever the basedir attribute of
+ the <code>&lt;project&gt;</code> element of the new project says (or
+ the new project's directory if the there is no basedir attribute) -
+ no matter what any other attribute of this task says and no matter
+ how deeply nested into levels of
+ <code>&lt;ant&gt;</code> invocations this task lives.</p>
+
+<p>If you haven't set <code>useNativeBasedir</code> or set it to
+ false, the following rules apply:</p>
+
+<p>The basedir value of the new project is affected by the two
+ attributes dir and inheritall as well as
+ the <code>&lt;ant&gt;</code> task's history. The current behaviour
+ is known to be confusing but cannot be changed without breaking
+ backwards compatibility in subtle ways.</p>
+
+<p>If the <code>&lt;ant&gt;</code> task is in a "top level" build
+ file, i.e. the project containing the <code>&lt;ant&gt;</code> task
+ has not itself been invoked as part of a
+ different <code>&lt;ant&gt;</code> (or <code>&lt;antcall&gt;</code>)
+ task "higher up", the following table shows the details:</p>
+
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>dir attribute</b></td>
+ <td valign="top"><b>inheritAll attribute</b></td>
+ <td valign="top"><b>new project's basedir</b></td>
+ </tr>
+ <tr>
+ <td valign="top">value provided</td>
+ <td valign="top">true</td>
+ <td valign="top">value of dir attribute</td>
+ </tr>
+ <tr>
+ <td valign="top">value provided</td>
+ <td valign="top">false</td>
+ <td valign="top">value of dir attribute</td>
+ </tr>
+ <tr>
+ <td valign="top">omitted</td>
+ <td valign="top">true</td>
+ <td valign="top">basedir of calling project (the one whose build
+ file contains the <code>&lt;ant&gt;</code> task).</td>
+ </tr>
+ <tr>
+ <td valign="top">omitted</td>
+ <td valign="top">false</td>
+ <td valign="top">basedir attribute of the <code>&lt;project&gt;</code> element
+ of the new project</td>
+ </tr>
+</table>
+
+<p>If on the other hand the <code>&lt;ant&gt;</code> task is already
+ nested into another invocation, the parent invocation's settings
+ affect the outcome of the basedir value. The current task's dir
+ attribute will always win, but if the dir attribute has been omitted
+ an even more complex situation arises:</p>
+
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>parent dir attribute</b></td>
+ <td valign="top"><b>parent inheritAll attribute</b></td>
+ <td valign="top"><b>current inheritAll attribute</b></td>
+ <td valign="top"><b>new project's basedir</b></td>
+ </tr>
+ <tr>
+ <td valign="top">value provided</td>
+ <td valign="top">any</td>
+ <td valign="top">any</td>
+ <td valign="top">value of parent's dir attribute</td>
+ </tr>
+ <tr>
+ <td valign="top">omitted</td>
+ <td valign="top">true</td>
+ <td valign="top">true</td>
+ <td valign="top">basedir of parent project (the one whose build
+ file called the build file that contains
+ the current <code>&lt;ant&gt;</code> task).</td>
+ </tr>
+ <tr>
+ <td valign="top">omitted</td>
+ <td valign="top">true</td>
+ <td valign="top">false</td>
+ <td valign="top">basedir of parent project (the one whose build
+ file called the build file that contains
+ the current <code>&lt;ant&gt;</code> task).</td>
+ </tr>
+ <tr>
+ <td valign="top">omitted</td>
+ <td valign="top">false</td>
+ <td valign="top">true</td>
+ <td valign="top">basedir of calling project (the one whose build
+ file contains the current <code>&lt;ant&gt;</code> task).</td>
+ </tr>
+ <tr>
+ <td valign="top">omitted</td>
+ <td valign="top">false</td>
+ <td valign="top">false</td>
+ <td valign="top">basedir attribute of the <code>&lt;project&gt;</code> element
+ of the new project</td>
+ </tr>
+</table>
+
+<p>If you add even deeper levels of nesting, things get even more
+ complicated and you need to apply the above table recursively.</p>
+
+<p>If the basedir of the outer most build has been specified as a
+ property on the command line (i.e. <code>-Dbasedir=some-value</code>
+ or a <code>-propertyfile</code> argument) the value provided will
+ get an even higher priority. For any <code>&lt;ant&gt;</code> task
+ that doesn't specify a dir attribute, the new project's basedir will
+ be the value specified on the command line - no matter how deeply
+ nested into layers of build files the task may be.</p>
+
+<p>The same happens if the basedir is specified as a
+ nested <code>&lt;property&gt;</code> of an <code>&lt;ant&gt;</code>
+ task. The basedir of build files started at deeper levels will be
+ set to the specified value of the property element unless the
+ corresponding Ant tasks set the dir attribute explicitly.</p>
+
+<h3>Examples</h3>
+<blockquote><pre>
+&lt;ant antfile=&quot;subproject/subbuild.xml&quot; target=&quot;compile&quot;/&gt;
+
+&lt;ant dir=&quot;subproject&quot;/&gt;
+
+&lt;ant antfile=&quot;subproject/property_based_subbuild.xml&quot;&gt;
+ &lt;property name=&quot;param1&quot; value=&quot;version 1.x&quot;/&gt;
+ &lt;property file=&quot;config/subproject/default.properties&quot;/&gt;
+&lt;/ant&gt;
+
+&lt;ant inheritAll=&quot;false&quot; antfile=&quot;subproject/subbuild.xml&quot;&gt;
+ &lt;property name=&quot;output.type&quot; value=&quot;html&quot;/&gt;
+&lt;/ant&gt;
+</pre></blockquote>
+
+<p>These lines invoke the same build file:</p>
+<blockquote><pre>
+&lt;ant antfile=&quot;sub1/sub2/build.xml&quot; /&gt;
+&lt;ant antfile=&quot;sub2/build.xml&quot; dir=&quot;sub1&quot; /&gt;
+&lt;ant antfile=&quot;build.xml&quot; dir=&quot;sub1/sub2&quot; /&gt;
+</pre></blockquote>
+
+<p>The build file of the calling project defines some
+<code>&lt;path&gt;</code> elements like this:</p>
+
+<blockquote><pre>
+&lt;path id="path1"&gt;
+ ...
+&lt;/path&gt;
+&lt;path id="path2"&gt;
+ ...
+&lt;/path&gt;
+</pre></blockquote>
+
+<p>and the called build file (<code>subbuild.xml</code>) also defines
+a <code>&lt;path&gt;</code> with the id <code>path1</code>, but
+<code>path2</code> is not defined:</p>
+
+<blockquote><pre>
+&lt;ant antfile=&quot;subbuild.xml&quot; inheritrefs=&quot;true&quot;/&gt;
+</pre></blockquote>
+
+<p>will not override <code>subbuild</code>'s definition of
+<code>path1</code>, but make the parent's definition of
+<code>path2</code> available in the subbuild.</p>
+
+<blockquote><pre>
+&lt;ant antfile=&quot;subbuild.xml&quot;/&gt;
+</pre></blockquote>
+
+<p>as well as</p>
+
+<blockquote><pre>
+&lt;ant antfile=&quot;subbuild.xml&quot; inheritrefs=&quot;false&quot;/&gt;
+</pre></blockquote>
+
+<p>will neither override <code>path1</code> nor copy
+<code>path2</code>.</p>
+
+<blockquote><pre>
+&lt;ant antfile=&quot;subbuild.xml&quot; inheritrefs=&quot;false&quot;&gt;
+ &lt;reference refid=&quot;path1&quot;/&gt;
+&lt;/ant&gt;
+</pre></blockquote>
+
+<p>will override <code>subbuild</code>'s definition of
+<code>path1</code>.</p>
+
+<blockquote><pre>
+&lt;ant antfile=&quot;subbuild.xml&quot; inheritrefs=&quot;false&quot;&gt;
+ &lt;reference refid=&quot;path1&quot; torefid=&quot;path2&quot;/&gt;
+&lt;/ant&gt;
+</pre></blockquote>
+
+<p>will copy the parent's definition of <code>path1</code> into the
+new project using the id <code>path2</code>.</p>
+
+
+
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/antcall.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/antcall.html
new file mode 100644
index 00000000..00cf6155
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/antcall.html
@@ -0,0 +1,201 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>AntCall Task</title>
+</head>
+
+<body>
+
+<h2><a name="antcall">AntCall</a></h2>
+<h3>Description</h3>
+
+<p>Call another target within the same buildfile optionally
+specifying some properties (params in this context). <strong>This
+task must not be used outside of a <code>target</code>.</strong></p>
+
+<p>By default, all of the properties of the current project will be
+available in the new project. Alternatively, you can
+set the <i>inheritAll</i> attribute to <code>false</code> and only
+&quot;user&quot; properties (i.e., those passed on the command-line)
+will be passed to the new project. In either case, the set of
+properties passed to the new project will override the properties that
+are set in the new project (See also the <a href="property.html">property task</a>).</p>
+<p>You can also set properties in the new project from the old project
+by using nested param tags. These properties are always passed
+to the new project and any project created in that project
+regardless of the setting of <i>inheritAll</i>. This allows you to
+parameterize your subprojects. Properties defined on the command line
+can not be overridden by nested <code>&lt;param&gt;</code> elements.</p>
+
+<p>When more than one nested <code>&lt;param&gt;</code> element
+ would set a property of the same name, the one declared last will
+ win. This is for backwards compatibility reasons even so it is
+ different from the way <code>&lt;property&gt;</code> tasks in build
+ files behave.</p>
+
+<p>Nested <a href="#reference"><i><code>&lt;reference&gt</code>;</i></a> elements can
+be used to copy references from the calling project to the new
+project, optionally under a different id. References taken from
+nested elements will override existing references that have been
+defined outside of targets in the new project - but not those defined
+inside of targets.</p>
+
+<p>
+When a target is invoked by antcall, all of its dependent targets will
+also be called within the context of any new parameters. For example. if
+the target &quot;doSomethingElse&quot; depended on the target &quot;init&quot;, then the
+<i>antcall</i> of &quot;doSomethingElse&quot; will call &quot;init&quot; during the call.
+Of course, any properties defined in the antcall task or inherited from the calling target
+will be fixed and not overridable in the init task--or indeed in the &quot;doSomethingElse&quot; task.
+</p>
+
+<p>The called target(s) are run in a new project; be aware that this
+means properties, references, etc. set by called targets will not
+persist back to the calling project.</p>
+
+<p>If the build file changes after you've started the build, the
+behavior of this task is undefined.</p>
+
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">target</td>
+ <td valign="top">The target to execute.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">inheritAll</td>
+ <td valign="top">If <code>true</code>, pass all properties to the new Apache Ant
+ project. Defaults to <code>true</code>.
+ </td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">inheritRefs</td>
+ <td valign="top">If <code>true</code>, pass all references to the
+ new Ant project. Defaults to <code>false</code>.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+</table>
+
+<h3>Note on <code>inheritRefs</code></h3>
+
+<p><code>&lt;antcall&gt;</code> will not override existing references,
+even if you set <code>inheritRefs</code> to true. As the called build
+files is the same build file as the calling one, this means it will
+not override any reference set via an <code>id</code> attribute at
+all. The only references that can be inherited by the child project
+are those defined by nested <code>&lt;reference&gt;</code> elements or
+references defined by tasks directly (not using the <code>id</code>
+attribute).</p>
+
+<h3>Parameters specified as nested elements</h3>
+<h4>param</h4>
+<p>Specifies the properties to set before running the specified target. See <a
+href="property.html">property</a> for usage guidelines.<br>
+These properties become equivalent to properties you define on
+the command line. These are special properties and they will always get passed
+down, even through additional <code>&lt;*ant*&gt;</code> tasks with inheritall set to
+false (see above).
+</p>
+
+<h4><a name="reference">reference</a></h4>
+<p>Used to choose references that shall be copied into the new project,
+optionally changing their id.</p>
+
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">refid</td>
+ <td valign="top">The id of the reference in the calling project.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">torefid</td>
+ <td valign="top">The id of the reference in the new project.</td>
+ <td valign="top" align="center">No, defaults to the value of refid.</td>
+ </tr>
+</table>
+
+<h4>propertyset</h4>
+
+<p>You can specify a set of properties to be copied into the new
+project with <a
+href="../Types/propertyset.html">propertyset</a>s.</p>
+
+<p><em>since Ant 1.6</em>.</p>
+
+<h4>target</h4>
+
+<p>You can specify multiple targets using nested <code>&lt;target&gt;</code> elements
+instead of using the target attribute. These will be executed as if
+Ant had been invoked with a single target whose dependencies are the
+targets so specified, in the order specified.</p>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">name</td>
+ <td valign="top">The name of the called target.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+</table>
+<p><em>since Ant 1.6.3</em>.</p>
+
+<h3>Examples</h3>
+<blockquote><pre>
+&lt;target name=&quot;default&quot;&gt;
+ &lt;antcall target=&quot;doSomethingElse&quot;&gt;
+ &lt;param name=&quot;param1&quot; value=&quot;value&quot;/&gt;
+ &lt;/antcall&gt;
+&lt;/target&gt;
+
+&lt;target name=&quot;doSomethingElse&quot;&gt;
+ &lt;echo message=&quot;param1=${param1}&quot;/&gt;
+&lt;/target&gt;
+</pre></blockquote>
+<p>Will run the target 'doSomethingElse' and echo 'param1=value'.</p>
+
+<blockquote><pre>
+&lt;antcall ... &gt;
+ &lt;reference refid=&quot;path1&quot; torefid=&quot;path2&quot;/&gt;
+&lt;/antcall&gt;
+</pre></blockquote>
+
+<p>will copy the parent's definition of <code>path1</code> into the
+new project using the id <code>path2</code>.</p>
+
+
+
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/antlr.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/antlr.html
new file mode 100644
index 00000000..e7d4fdba
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/antlr.html
@@ -0,0 +1,200 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>ANTLR Task</title>
+</head>
+
+<body>
+
+<h2><a name="antlr">ANTLR</a></h2>
+<h3>Description</h3>
+<p>
+ Invokes the <a HREF="http://www.antlr.org/" target="_top">ANTLR</a> Translator generator
+ on a grammar file.
+</p>
+<p>
+ To use the ANTLR task, set the <i>target</i> attribute to the name of the
+ grammar file to process. Optionally, you can also set the
+ <i>outputdirectory</i> to write the generated file to a specific directory.
+ Otherwise ANTLR writes the generated files to the directory containing
+ the grammar file.
+</p>
+<p>
+ This task only invokes ANTLR if the grammar file (or the
+ supergrammar specified by the glib attribute) is newer than the
+ generated files.
+</p>
+<p>Antlr 2.7.1 Note:
+<i>
+ To successfully run ANTLR, your best option is probably to build the whole
+ jar with the provided script <b>mkalljar</b> and drop the resulting jar (about 300KB)
+ into ${ant.home}/lib. Dropping the default jar (70KB) is probably not enough
+ for most needs and your only option will be to add ANTLR home directory
+ to your classpath as described in ANTLR <tt>install.html</tt> document.
+</i>
+</p>
+<p>Antlr 2.7.2 Note:
+<i>
+ Instead of the above, you will need antlrall.jar that can be created
+ by the <b>antlr-all.jar</b> target of the Makefile provided with the
+ download.
+</i>
+</p>
+
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">target</td>
+ <td valign="top">The grammar file to process.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">outputdirectory</td>
+ <td valign="top">
+ The directory to write the generated files to. If not set, the files
+ are written to the directory containing the grammar file.
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">glib</td>
+ <td valign="top">
+ An optional super grammar file that the target grammar overrides. This
+ feature is only needed for advanced vocabularies.
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">debug</td>
+ <td valign="top">
+ When set to "yes", this flag adds code to the generated parser that will
+ launch the ParseView debugger upon invocation. The default is "no".
+ <br>
+ Note: ParseView is a separate component that needs to be installed or your
+ grammar will have compilation errors.
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">html</td>
+ <td valign="top">
+ Emit an html version of the grammar with hyperlinked actions.
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">diagnostic</td>
+ <td valign="top">
+ Generates a text file with debugging information based on the target grammar.
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">trace</td>
+ <td valign="top">
+ Forces <b>all</b> rules to call traceIn/traceOut if set to "yes".
+ The default is "no".
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">traceParser</td>
+ <td valign="top">
+ Only forces parser rules to call traceIn/traceOut if set to "yes".
+ The default is "no".
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">traceLexer</td>
+ <td valign="top">
+ Only forces lexer rules to call traceIn/traceOut if set to "yes".
+ The default is "no".
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">traceTreeWalker</td>
+ <td valign="top">
+ Only forces tree walker rules to call traceIn/traceOut if set to
+ "yes". The default is "no".
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <!--tr>
+ <td valign="top">fork</td>
+ <td valign="top">Run ANTLR in a separate VM.</td>
+ <td align="center" valign="top">No, default is &quot;off&quot;</td>
+ </tr-->
+ <tr>
+ <td valign="top">dir</td>
+ <td valign="top">The directory to invoke the VM in. <!--(ignored if
+ fork is disabled)--></td>
+ <td align="center" valign="top">No</td>
+ </tr>
+</table>
+
+<h3><a name="nested">Nested Elements</a></h3>
+
+<p><code>ANTLR</code> supports a nested <code>&lt;classpath&gt;</code>
+element, that represents a <a href="../using.html#path">PATH like
+structure</a>. It is given as a convenience if you have to specify
+the original ANTLR directory. In most cases, dropping the appropriate
+ANTLR jar in the normal Ant lib repository will be enough.</p>
+
+<h4>jvmarg</h4>
+
+<p><!--If fork is enabled, -->Additional parameters may be passed to the new
+VM via nested <code>&lt;jvmarg&gt;</code> attributes, for example:</p>
+
+<pre>
+&lt;antlr target="..."&gt;
+ &lt;jvmarg value=&quot;-Djava.compiler=NONE&quot;/&gt;
+ ...
+&lt;/antlr&gt;
+</pre>
+
+<p>would run ANTLR in a VM without JIT.</p>
+
+<p><code>&lt;jvmarg&gt;</code> allows all attributes described in <a
+href="../using.html#arg">Command line arguments</a>.</p>
+
+<h3>Example</h3>
+<blockquote><pre>
+&lt;antlr
+ target=&quot;etc/java.g&quot;
+ outputdirectory=&quot;build/src&quot;
+/&gt;
+</pre></blockquote>
+<p>
+ This invokes ANTLR on grammar file etc/java.g, writing the generated
+ files to build/src.
+</p>
+
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/antstructure.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/antstructure.html
new file mode 100644
index 00000000..ab7acc1a
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/antstructure.html
@@ -0,0 +1,100 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>AntStructure Task</title>
+</head>
+
+<body>
+
+<h2><a name="antstructure">AntStructure</a></h2>
+<h3>Description</h3>
+
+<p>Generates an DTD for Apache Ant buildfiles which contains information
+about all tasks currently known to Ant.</p>
+
+<p>Actually the DTD will not be a real DTD for buildfiles since Ant's
+usage of XML cannot be captured with a DTD. Several elements in Ant
+can have different attribute lists depending on the element that
+contains them. &quot;fail&quot; for example can be <a
+href="fail.html">the task</a> or the nested child element of the <a
+href="../Tasks/sound.html">sound</a> task. Don't consider the
+generated DTD something to rely upon.</p>
+
+<p>Also note that the DTD generated by this task is incomplete, you can
+always add XML entities using <a
+href="taskdef.html"><code>&lt;taskdef&gt;</code></a> or <a
+href="typedef.html"><code>&lt;typedef&gt;</code></a>. See <a
+href="http://www.sdv.fr/pages/casa/html/ant-dtd.en.html"
+target="_top">here</a> for a way to get around this problem.</p>
+<p>This task doesn't know about required attributes, all will be
+listed as <code>#IMPLIED</code>.</p>
+
+<p><em>Since Ant 1.7</em> custom structure printers can be used
+instead of the one that emits a DTD. In order to plug in your own
+structure, you have to implement the interface
+<code>org.apache.tools.ant.taskdefs.AntStructure.StructurePrinter</code>
+and <code>&lt;typedef&gt; your class and use the new type as a nested
+element of this task - see the example below.</code>
+
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">output</td>
+ <td valign="top">file to write the DTD to.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+</table>
+<h3>Examples</h3>
+<blockquote><pre>
+&lt;antstructure output=&quot;project.dtd&quot; /&gt;
+</pre></blockquote>
+
+<p><b>Emitting your own structure instead of a DTD</b></p>
+
+<p>First you need to implement the interface</p>
+
+<pre>
+package org.example;
+import org.apache.tools.ant.taskdefs.AntStructure;
+public class MyPrinter implements AntStructure.StructurePrinter {
+ ...
+}
+</pre>
+
+<p>and then use it via typedef</p>
+
+<pre>
+ &lt;typedef name="myprinter" classname="org.example.MyPrinter" /&gt;
+ &lt;antstructure output="project.my"&gt;
+ &lt;myprinter /&gt;
+ &lt;/antstructure&gt;
+</pre>
+
+<p>Your own StructurePrinter can accept attributes and nested elements
+just like any other Ant type or task.</p>
+
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/antversion.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/antversion.html
new file mode 100644
index 00000000..cd9f838a
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/antversion.html
@@ -0,0 +1,95 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Antversion Task</title>
+</head>
+
+<body>
+
+<h2><a name="antversion">Antversion</a></h2>
+<h3>Description</h3>
+<p>
+Stores the Apache Ant version (when used as task) or checks for a specific Ant version
+(when used as condition).
+<b>Since Ant 1.7.0</b>
+</p>
+
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required (Task)</b></td>
+ <td align="center" valign="top"><b>Required (Condition)</b></td>
+ </tr>
+ <tr>
+ <td valign="top">atleast</td>
+ <td valign="top">The version that this at least.
+ The format is major.minor.point.</td>
+ <td valign="top" align="center">No</td>
+ <td valign="top" rowspan="2" align="center">One of these.</td>
+ </tr>
+ <tr>
+ <td valign="top">exactly</td>
+ <td valign="top">The version that this ant is exactly.
+ The format is <tt>major.minor.point</tt>.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">property</td>
+ <td valign="top">The name of the property to set.</td>
+ <td valign="top" align="center">Yes</td>
+ <td valign="top" align="center">No (ignored)</td>
+ </tr>
+</table>
+
+
+<h3>Examples</h3>
+
+<blockquote><pre>
+&lt;antversion property=&quot;antversion&quot;/&gt;
+</pre></blockquote>
+<p>Stores the current Ant version in the property <i>antversion</i>.</p>
+
+<blockquote><pre>
+&lt;antversion property=&quot;antversion&quot; atleast=&quot;1.6&quot;/&gt;
+</pre></blockquote>
+<p>Stores the Ant version in the property <i>antversion</i> if the current Ant version is 1.6.0
+or higher. Otherwise the property remains unset.</p>
+
+<blockquote><pre>
+&lt;antversion property=&quot;ant-is-exact-7&quot; exactly=&quot;1.7.0&quot;/&gt;
+</pre></blockquote>
+<p>Sets the property <i>ant-is-exact-7</i> if Ant 1.7.0 is running. Neither 1.6.5 nor 1.7.0
+would match.</p>
+
+<blockquote><pre>
+&lt;condition property=&quot;Ant17isOnline&quot;&gt;
+ &lt;and&gt;
+ &lt;antversion exactly=&quot;1.7.0&quot;/&gt;
+ &lt;http url=&quot;http://ant.apache.org&quot;/&gt;
+ &lt;/and&gt;
+&lt;/condition&gt;
+</pre></blockquote>
+<p>Sets <i>Ant17isOnline</i> if Ant 1.7.0 is running and can get a non-error-response from
+the Ant homepage.</p>
+
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/apply.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/apply.html
new file mode 100644
index 00000000..6cf948fa
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/apply.html
@@ -0,0 +1,499 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+ <meta http-equiv="Content-Language" content="en-us">
+ <link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+ <title>Apply Task</title>
+</head>
+
+<body>
+
+<h2><a name="apply">Apply/<i>ExecOn</i></a></h2>
+<p><i>The name <code>execon</code> is deprecated and only kept for backwards
+compatibility.</i></p>
+<h3>Description</h3>
+<p>Executes a system command. When the <i>os</i> attribute is specified, then
+the command is only executed when Apache Ant is run on one of the specified operating
+systems.</p>
+
+<p>The files and/or directories of a number of <a
+href="../Types/resources.html#collection">Resource Collection</a>s
+&ndash; including but not restricted to
+ <a href="../Types/fileset.html">FileSet</a>s,
+ <a href="../Types/dirset.html">DirSet</a>s
+ (<em>since&nbsp;Ant&nbsp;1.6</em>) or
+ <a href="../Types/filelist.html">FileList</a>s
+ (<em>since&nbsp;Ant&nbsp;1.6</em>)
+&ndash;
+ are passed as arguments to the system command.</p>
+<p>If you specify a nested <a href="../Types/mapper.html">mapper</a>,
+the timestamp of each source file is compared to the timestamp of a
+target file which is defined by the nested mapper element and searched
+for in the given <i>dest</i>, if specified.</p>
+<p>At least one fileset or filelist is required,
+and you must not specify more than one mapper.</p>
+
+<p>Note that you cannot interact with the forked program, the only way
+to send input to it is via the input and inputstring attributes.</p>
+
+<h4><a name="background">Running Ant as a background process on
+ Unix(-like) systems</a></h4>
+
+<p>If you run Ant as a background process (like <code>ant &</code>)
+ and use the <code>&lt;apply&gt;</code> task with <code>spawn</code>
+ set to <code>false</code>, you must provide explicit input to the
+ forked process or Ant will be suspended because it tries to read
+ from the standard input.</p>
+
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">executable</td>
+ <td valign="top">the command to execute without any command line
+ arguments.</td>
+ <td align="center" valign="top">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">dest</td>
+ <td valign="top">the directory where the command is expected to place
+ target files when it is executed. This attribute is valid only when used
+ in conjunction with a nested mapper; if omitted, the target filenames
+ returned by the mapper will be interpreted as absolute paths.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">spawn</td>
+ <td valign="top">whether or not you want the commands to be spawned.<br>
+ If you spawn a command, its output will not be logged by ant.<br>
+ The input, output, error, and result property settings are not active when spawning a process.<br>
+ <em>since&nbsp;Ant&nbsp;1.6</em>
+ </td>
+ <td align="center" valign="top">No, default is <i>false</i></td>
+ </tr>
+
+ <tr>
+ <td valign="top">dir</td>
+ <td valign="top">the directory in which the command should be executed.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">relative</td>
+ <td valign="top">whether the filenames should be passed on the
+ command line as relative pathnames (relative to the base directory
+ of the corresponding fileset/list for source files or the
+ <i>dest</i> attribute for target files).</td>
+ <td align="center" valign="top">No, default is <i>false</i></td>
+ </tr>
+ <tr>
+ <td valign="top">forwardslash</td>
+ <td valign="top">whether the file names should be passed
+ with forward slashes even if the operating system requires other
+ file separator. The option is ignored if the system file separator
+ is a forward slash.</td>
+ <td align="center" valign="top">No, default is <i>false</i></td>
+ </tr>
+ <tr>
+ <td valign="top">os</td>
+ <td valign="top">list of Operating Systems on which the command may be
+ executed.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">osfamily</td>
+ <td valign="top">OS family as used in the &lt;os&gt; condition.
+ <em>since Ant 1.7</em></td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">output</td>
+ <td valign="top">the file to which the output of the command
+ should be redirected. If the error stream is not also redirected
+ to a file or property, it will appear in this output.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">error</td>
+ <td valign="top">The file to which the standard error of the
+ command should be redirected. <em>since&nbsp;Ant&nbsp;1.6</em></td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">logError</td>
+ <td valign="top">This attribute is used when you wish to see error
+ output in Ant's log and you are redirecting output to a
+ file/property. The error output will not be included in the output
+ file/property. If you redirect error with the &quot;error&quot; or
+ &quot;errorProperty&quot; attributes, this will have no effect.
+ <em>since&nbsp;Ant&nbsp;1.6</em></td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">append</td>
+ <td valign="top">whether output should be appended to or overwrite
+ an existing file. If you set parallel to false, you will probably
+ want to set this one to true.</td>
+ <td align="center" valign="top">No, default is <i>false</i></td>
+ </tr>
+ <tr>
+ <td valign="top">outputproperty</td>
+ <td valign="top">the name of a property in which the output of the
+ command should be stored. Unless the error stream is redirected
+ to a separate file or stream, this property will include the error
+ output.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">errorproperty</td>
+ <td valign="top">The name of a property in which the standard error of the
+ command should be stored. <em>since&nbsp;Ant&nbsp;1.6</em></td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">input</td>
+ <td valign="top">A file from which the executed command's standard
+ input is taken. This attribute is mutually exclusive with the
+ inputstring attribute. <em>since&nbsp;Ant&nbsp;1.6</em></td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">inputstring</td>
+ <td valign="top">A string which serves as the input stream for the
+ executed command. This attribute is mutually exclusive with the
+ input attribute. <em>since&nbsp;Ant&nbsp;1.6</em></td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">resultproperty</td>
+ <td valign="top">the name of a property in which the return code
+ of the command should be stored. Only of interest if
+ failonerror=false. If you set parallel to false, only the result
+ of the first execution will be stored.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">timeout</td>
+ <td valign="top">Stop the command if it doesn't finish within the
+ specified time (given in milliseconds).</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">failonerror</td>
+ <td valign="top">Stop the buildprocess if the command exits with a
+ returncode other than 0.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">failifexecutionfails</td>
+ <td valign="top">Stop the build if we can't start the program.
+ Defaults to true. </td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">skipemptyfilesets</td>
+ <td valign="top">Don't run the command, if no source files have
+ been found or are newer than their corresponding target
+ files. Despite its name, this attribute applies to filelists as
+ well.</td>
+ <td align="center" valign="top">No, default is <i>false</i></td>
+ </tr>
+ <tr>
+ <td valign="top">parallel</td>
+ <td valign="top">Run the command only once, appending all files as
+ arguments. If false, command will be executed once for every file.</td>
+ <td align="center" valign="top">No, default is <i>false</i></td>
+ </tr>
+ <tr>
+ <td valign="top">type</td>
+ <td valign="top">One of <i>file</i>, <i>dir</i> or
+ <i>both</i>. If set to <i>file</i>, only the names of plain
+ files will be sent to the command. If set to <i>dir</i>, only
+ the names of directories are considered.<br>
+ <strong>Note:</strong> The type attribute does not apply to
+ nested <i>dirset</i>s - <i>dirset</i>s always implicitly
+ assume type to be <i>dir</i>.</td>
+ <td align="center" valign="top">No, default is <i>file</i></td>
+ </tr>
+ <tr>
+ <td valign="top">newenvironment</td>
+ <td valign="top">Do not propagate old environment when new environment
+ variables are specified.</td>
+ <td align="center" valign="top">No, default is <i>false</i></td>
+ </tr>
+ <tr>
+ <td valign="top">vmlauncher</td>
+ <td valign="top">Run command using the Java VM's execution facilities
+ where available. If set to false the underlying OS's shell,
+ either directly or through the antRun scripts, will be used.
+ Under some operating systems, this gives access to facilities
+ not normally available through the VM including, under Windows,
+ being able to execute scripts, rather than their associated
+ interpreter. If you want to specify the name of the
+ executable as a relative path to the directory given by the
+ dir attribute, it may become necessary to set vmlauncher to
+ false as well.</td>
+ <td align="center" valign="top">No, default is <i>true</i></td>
+ </tr>
+ <tr>
+ <td valign="top">resolveExecutable</td>
+ <td valign="top">When this attribute is true, the name of the
+ executable if resolved firstly against the project basedir and if
+ that does not exist, against the execution directory if
+ specified. On Unix systems, if you only want to allow execution of
+ commands in the user's path, set this to false.
+ <em>since&nbsp;Ant&nbsp;1.6</em></td>
+ <td align="center" valign="top">No, default is <i>false</i></td>
+ </tr>
+ <tr>
+ <td valign="top">maxparallel</td>
+ <td valign="top">Limit the amount of parallelism by passing at
+ most this many sourcefiles at once. Set it to &lt;= 0 for
+ unlimited. <em>Since&nbsp;Ant&nbsp;1.6.</em></td>
+ <td align="center" valign="top">No, unlimited by default</td>
+ </tr>
+ <tr>
+ <td valign="top">addsourcefile</td>
+ <td valign="top">Whether source file names should be added to the
+ command automatically. <em>Since&nbsp;Ant&nbsp;1.6.</em></td>
+ <td align="center" valign="top">No, default is <i>true</i></td>
+ </tr>
+ <tr>
+ <td valign="top">verbose</td>
+ <td valign="top">Whether to print a summary after execution or not.
+ <em>Since&nbsp;Ant&nbsp;1.6.</em></td>
+ <td align="center" valign="top">No, default <i>false</i></td>
+ </tr>
+ <tr>
+ <td valign="top">ignoremissing</td>
+ <td valign="top">Whether to ignore nonexistent files specified
+ via filelists. <em>Since&nbsp;Ant&nbsp;1.6.2.</em></td>
+ <td align="center" valign="top">No, default is <i>true</i></td>
+ </tr>
+ <tr>
+ <td valign="top">force</td>
+ <td valign="top">Whether to bypass timestamp comparisons
+ for target files. <em>Since&nbsp;Ant&nbsp;1.6.3.</em></td>
+ <td align="center" valign="top">No, default is <i>false</i></td>
+ </tr>
+</table>
+<h3>Parameters specified as nested elements</h3>
+<h4>fileset</h4>
+<p>You can use any number of nested <code>&lt;fileset&gt;</code>
+elements to define the files for this task and refer to
+<code>&lt;fileset&gt;</code>s defined elsewhere.</p>
+<h4>filelist</h4>
+<p><em>Since&nbsp;Ant&nbsp;1.6</em></p>
+<p>You can use any number of nested <code>&lt;filelist&gt;</code>
+elements to define the files for this task and refer to
+<code>&lt;filelist&gt;</code>s defined elsewhere.</p>
+<h4>dirset</h4>
+<p><em>Since&nbsp;Ant&nbsp;1.6</em></p>
+<p>You can use any number of nested <code>&lt;dirset&gt;</code>
+elements to define the directories for this task and refer to
+<code>&lt;dirset&gt;</code>s defined elsewhere.</p>
+
+<h4>Any other <a href="../Types/resources.html#collection">Resource
+Collection</a></h4>
+<p><em>since Ant 1.7</em></p>
+<p>You can use any number of nested resource collections.</p>
+
+<h4>mapper</h4>
+<p>A single <code>&lt;mapper&gt;</code> specifies the target files relative
+to the <code>dest</code> attribute for dependency checking. If the
+<code>dest</code> attribute is specified it will be used as a base directory
+for resolving relative pathnames returned by the mapper. At least one
+<code>&lt;fileset&gt;</code> or <code>&lt;filelist&gt;</code> is required.</p>
+<h4>arg</h4>
+<p>Command line arguments should be specified as nested
+<code>&lt;arg&gt;</code> elements. See <a
+href="../using.html#arg">Command line arguments</a>.</p>
+<h4>srcfile</h4>
+<p>By default the file names of the source files will be added to the
+end of the command line (unless you set addsourcefile to
+<code>false</code>). If you need to place it somewhere different,
+use a nested <code>&lt;srcfile&gt;</code> element between your
+<code>&lt;arg&gt;</code> elements to mark the insertion point.</p>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">prefix</td>
+ <td valign="top">a prefix to place in front of the file name when
+ building the command line argument. <em>Since Ant 1.8.0</em></td>
+ <td align="center" valign="top">No.</td>
+ </tr>
+ <tr>
+ <td valign="top">suffix</td>
+ <td valign="top">a suffix to append to the file name when
+ building the command line argument. <em>Since Ant 1.8.0</em></td>
+ <td align="center" valign="top">No.</td>
+ </tr>
+</table>
+<h4>targetfile</h4>
+<p><code>&lt;targetfile&gt;</code> is similar to
+<code>&lt;srcfile&gt;</code> and marks the position of the target
+filename on the command line. If omitted, the target filenames will
+not be added to the command line at all. This element can only be
+specified if you also define a nested mapper.</p>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">prefix</td>
+ <td valign="top">a prefix to place in front of the file name when
+ building the command line argument. <em>Since Ant 1.8.0</em></td>
+ <td align="center" valign="top">No.</td>
+ </tr>
+ <tr>
+ <td valign="top">suffix</td>
+ <td valign="top">a suffix to append to the file name when
+ building the command line argument. <em>Since Ant 1.8.0</em></td>
+ <td align="center" valign="top">No.</td>
+ </tr>
+</table>
+<h4>env</h4>
+<p>It is possible to specify environment variables to pass to the
+system command via nested <code>&lt;env&gt;</code> elements. See the
+description in the section about <a href="exec.html#env">exec</a></p>
+<h4>redirector</h4>
+<i><b>Since&nbsp;Ant&nbsp;1.6.2</b></i>
+<p>A nested <a href="../Types/redirector.html">I/O Redirector</a>
+can be specified. &lt;apply&gt;'s behavior is like that of
+<a href="exec.html#redirector">exec</a> with regard to
+redirectors, with the exception that, in non-<i>parallel</i> mode,
+file mapping will take place with each iteration. This grants the
+user the capacity to receive input from, and send output to, different
+files for each sourcefile.
+</p>
+<p>In <i>parallel</i>-mode the redirector will be reset for each batch
+ of executions (with <i>maxparallel</i> &gt; 0) and null will be used
+ a source file just like it is in the case of <code>exec</code>.</p>
+<h3>Examples</h3>
+<blockquote><pre>
+&lt;apply executable=&quot;ls&quot;&gt;
+ &lt;arg value=&quot;-l&quot;/&gt;
+ &lt;fileset dir=&quot;/tmp&quot;&gt;
+ &lt;patternset&gt;
+ &lt;exclude name=&quot;**/*.txt&quot;/&gt;
+ &lt;/patternset&gt;
+ &lt;/fileset&gt;
+ &lt;fileset refid=&quot;other.files&quot;/&gt;
+&lt;/apply&gt;
+</pre></blockquote>
+<p>invokes <code>ls -l</code>, adding the absolute filenames of all
+files below <code>/tmp</code> not ending in <code>.txt</code> and all
+files of the FileSet with <code>id</code> <code>other.files</code> to
+the command line.</p>
+<blockquote><pre>
+&lt;apply executable=&quot;somecommand&quot; parallel=&quot;false&quot;&gt;
+ &lt;arg value=&quot;arg1&quot;/&gt;
+ &lt;srcfile/&gt;
+ &lt;arg value=&quot;arg2&quot;/&gt;
+ &lt;fileset dir=&quot;/tmp&quot;/&gt;
+&lt;/apply&gt;
+</pre></blockquote>
+<p>invokes <code>somecommand arg1 SOURCEFILENAME arg2</code> for each
+file in <code>/tmp</code> replacing SOURCEFILENAME with the absolute
+filename of each file in turn. If <code>parallel</code> had been set
+to true, SOURCEFILENAME would be replaced with the absolute filenames
+of all files separated by spaces.</p>
+<blockquote><pre>
+&lt;apply executable=&quot;cc&quot; dest=&quot;src/C&quot; parallel=&quot;false&quot;&gt;
+ &lt;arg value=&quot;-c&quot;/&gt;
+ &lt;arg value=&quot;-o&quot;/&gt;
+ &lt;targetfile/&gt;
+ &lt;srcfile/&gt;
+ &lt;fileset dir=&quot;src/C&quot; includes=&quot;*.c&quot;/&gt;
+ &lt;mapper type=&quot;glob&quot; from=&quot;*.c&quot; to=&quot;*.o&quot;/&gt;
+&lt;/apply&gt;
+</pre></blockquote>
+<p>invokes <code>cc -c -o TARGETFILE SOURCEFILE</code> for each
+<code>.c</code> file that is newer than the corresponding
+<code>.o</code>, replacing TARGETFILE with the absolute filename of
+the <code>.o</code> and SOURCEFILE with the absolute name of the
+<code>.c</code> file.</p>
+<blockquote><pre>
+&lt;mapper id=&quot;out&quot; type=&quot;glob&quot;
+ from=&quot;src${file.separator}*.file&quot;
+ to=&quot;dest${file.separator}*.out&quot;/&gt;
+
+&lt;apply executable=&quot;processfile&quot; dest=&quot;dest&quot;&gt;
+ &lt;fileset dir=&quot;src&quot; includes=&quot;*.file&quot;/&gt;
+ &lt;mapper refid=&quot;out&quot;/&gt;
+ &lt;redirector&gt;
+ &lt;outputmapper refid=&quot;out&quot;/&gt;
+ &lt;/redirector&gt;
+&lt;/apply&gt;
+</pre></blockquote>
+Applies the fictitious &quot;processfile&quot; executable to all
+files matching <code>*.file</code> in the <code>src</code> directory.
+The <code>out</code> <code>&lt;mapper&gt;</code> has been set up to map
+<code>*.file</code> to <code>*.out</code>, then this <code>&lt;mapper&gt;</code>
+is used to specify <code>targetfile</code>s for this &lt;apply&gt;
+task. A reference to <code>out</code> is then used as an
+<code>&lt;outputmapper&gt;</code> nested in a <code>&lt;redirector&gt;</code>, which in turn is
+nested beneath this <code>&lt;apply&gt;</code> instance. This allows us to perform
+dependency checking against output files--the target files in this case.
+<blockquote><pre>
+&lt;apply executable="ls" parallel="true"
+ force="true" dest="${basedir}" append="true" type="both"&gt;
+ &lt;path&gt;
+ &lt;pathelement path="${env.PATH}"/&gt;
+ &lt;/path&gt;
+ &lt;identitymapper/&gt;
+&lt;/apply&gt;
+</pre></blockquote>
+Applies the "ls" executable to all directories in the PATH, effectively
+listing all executables that are available on the PATH.
+
+<blockquote><pre>
+&lt;apply executable="jsmin" addsourcefile="false"&gt;
+ &lt;!-- Collect the JS-files --&gt;
+ &lt;fileset dir="src" includes="*.js"/&gt;
+ &lt;redirector&gt;
+ &lt;!-- redirect STDIN; fileset collects relative to its dir, but we need --&gt;
+ &lt;!-- relative to basedir --&gt;
+ &lt;inputmapper type="glob" from="*" to="src/*"/&gt;
+ &lt;!-- redirect STDOUT to file in dest-dir --&gt;
+ &lt;outputmapper id="out" type="glob" from="*.js" to="dest/*.js"/&gt;
+ &lt;/redirector&gt;
+&lt;/apply&gt;
+</pre></blockquote>
+Conversion of the command <code>jsmin &lt; src/a.js &gt; dest/a.js</code> but for
+all files in the src-directory. Because the filename itself should not be passed
+to the <code>jsmin</code> program, the <code>addsourcefile</code> is set to
+<code>false</code>.
+
+
+
+
+
+
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/apt.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/apt.html
new file mode 100644
index 00000000..4bdd9a90
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/apt.html
@@ -0,0 +1,179 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html lang="en-us"><head>
+<meta http-equiv="Content-Language" content="en-us"><link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Apt Task</title></head>
+
+<body>
+
+<h2><a name="Apt">Apt</a></h2>
+<h3>Description</h3>
+<p>Runs the annotation processor tool (apt), and then optionally compiles
+ the original code, and any generated source code.
+ <p>This task runs on Java 1.5 to Java 1.7.</p>
+ <p>Apt is deprecated in Java 1.6, which can run annotation
+ processors as part of javac, and removed from the distribution in Java 1.8.
+ The task will fire an exception when attempting to run under Java 1.8.</p>
+
+
+<p>This task inherits from the <a href="javac.html">Javac Task</a>, and thus
+ supports nearly all of the same attributes, and subelements.
+ There is one special case, the <tt>fork</tt> attribute, which is present
+ but which can only be set to <tt>true</tt>. That is, apt only works as
+ a forked process.
+ </p>
+ <p>
+ In addition, it supports
+ the following addition items:</p>
+
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tbody><tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">compile</td>
+ <td valign="top">After running the Apt, should the code be compiled. (see the
+ <code>-nocompile</code> flag on the Apt executable)</td>
+ <td align="center" valign="top">No, defaults to false.</td>
+ </tr>
+ <tr>
+ <td valign="top">factory</td>
+ <td valign="top">The fully qualified classname of the AnnotationProcessFactory to be used
+ to construct annotation processors. This represents the <code>-factory</code>
+ command line flag of the Apt executable.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">factorypathref</td>
+ <td valign="top">The reference id of the path used to find the classes needed by the
+ AnnotationProcessorFactory (and the location of the factory itself).
+ This represents the <code>-factorypath</code> flag on the Apt executable.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">preprocessdir</td>
+ <td valign="top">The directory used for preprocessing. This is the directory where the
+ generated source code will be place. This represents the <code>-s</code> flag on
+ the Apt executable.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+</tbody></table>
+
+<h3>Parameters specified as nested elements</h3>
+
+
+<h4>factorypath</h4>
+
+<p>You can specify the path used to find the classes needed by the AnnotationProcessorFactory
+ at runtime, using this element. It is represents as a generic path like structure. This
+ represents the <code>-factorypath</code> flag on the Apt executable.</p>
+
+
+<h4>option</h4>
+
+<p>Used to represent a generic option to pass to Apt. This represents the <code>-A</code> flag on the
+ Apt executable. You can specify zero or more <code>&lt;option&gt;</code> elements.</p>
+
+<table border="1" cellpadding="2" cellspacing="0">
+<tbody><tr>
+ <td valign="top" width="12%"><b>Attribute</b></td>
+ <td valign="top" width="78%"><b>Description</b></td>
+ <td valign="top" width="10%"><b>Required</b></td>
+</tr>
+ <tr>
+ <td valign="top">name</td>
+ <td align="center">The name of the option</td>
+ <td align="center">Yes.</td>
+ </tr>
+ <tr>
+ <td valign="top">value</td>
+ <td align="center">The value to set the option to</td>
+ <td align="center">Yes.</td>
+ </tr>
+</tbody></table>
+
+<h3>Examples</h3>
+<blockquote><pre>
+&lt;apt srcdir="${src}"
+ destdir="${build}"
+ classpath="xyz.jar"
+ debug="on"
+ compile="true"
+ factory="com.mycom.MyAnnotationProcessorFactory"
+ factorypathref="my.factorypath.id"
+ preprocessdir="${preprocess.dir}"&gt;
+&lt;/apt&gt;
+</pre></blockquote>
+<p>compiles all <code>.java</code> files under the <code>${src}</code>
+directory, and stores
+the <code>.class</code> files in the <code>${build}</code> directory.
+The classpath used includes <code>xyz.jar</code>, and compiling with
+debug information is on. It also forces the generated source code to
+be compiled. The generated source code will be placed in
+<code>${preprocess.dir}</code> directory, using the class
+<code>com.mycom.MyAnnotationProcessorFactory</code> to supply
+AnnotationProcessor instances.</p>
+
+
+<h3>Notes</h3>
+
+<p>
+The inherited "fork" attribute is set to true by default; please do not change it.
+</p>
+
+<p>
+The inherited "compiler" attribute is ignored, as it is forced to use the Apt compiler
+</p>
+
+<p>Using the Apt compiler with the "compile" option set to "true"
+ forces you to use Sun's Apt compiler, which will use the JDK's Javac compiler.
+ If you wish to use another compiler, you will first need run the Apt processor
+ with the "compile" flag set to "false", and then use a
+ <code>&lt;javac&gt;</code> task to compile first your original source code, and then the
+ generated source code:</p>
+
+<blockquote><pre>
+&lt;apt srcdir="${src}"
+ destdir="${build}"
+ classpath="xyz.jar"
+ debug="true"
+ compile="false"
+ factory="com.mycom.MyAnnotationProcessorFactory"
+ factorypathref="my.factorypath.id"
+ preprocessdir="${preprocess.dir}"&gt;
+&lt;/apt&gt;
+
+&lt;javac srcdir="${src}"
+ destdir="${build}"
+ classpath="xyz.jar"
+ debug="on"/&gt;
+
+&lt;javac srcdir="${preprocess.dir}"
+ destdir="${build}"
+ classpath="xyz.jar"
+ debug="true"/&gt;
+</pre></blockquote>
+
+This may involve more build file coding, but the speedup gained from switching
+to jikes may justify the effort.
+<p>
+</p>
+
+</body></html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/attrib.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/attrib.html
new file mode 100644
index 00000000..a26f0c55
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/attrib.html
@@ -0,0 +1,167 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Apache Ant User Manual</title>
+</head>
+
+<body>
+
+<h2><a name="attrib">Attrib</a></h2>
+<p><em>Since Apache Ant 1.6.</em></p>
+<h3>Description</h3>
+
+<p>Changes the attributes of a file or all files inside specified
+directories. Right now it has effect only under Windows. Each of the
+4 possible permissions has its own attribute, matching the arguments
+for the attrib command.</p>
+
+<p><a href="../Types/fileset.html">FileSet</a>s,
+<a href="../Types/dirset.html">DirSet</a>s or <a
+href="../Types/filelist.html">FileList</a>s can be specified using
+nested <code>&lt;fileset&gt;</code>, <code>&lt;dirset&gt;</code> and
+<code>&lt;filelist&gt;</code> elements.</p>
+
+<p>Starting with Ant 1.7, this task supports arbitrary <a
+href="../Types/resources.html#collection">Resource Collection</a>s
+as nested elements.</p>
+
+<!--p>By default this task will use a single invocation of the underlying
+attrib command. If you are working on a large number of files this
+may result in a command line that is too long for your operating
+system. If you encounter such problems, you should set the
+maxparallel attribute of this task to a non-zero value. The number to
+use highly depends on the length of your file names (the depth of your
+directory tree), so you'll have to experiment a little.</p-->
+
+<p>By default this task won't do anything unless it detects it is
+ running on a Windows system. If you know for sure that you have a
+ "attrib" executable on your PATH that is command line compatible with
+ the Windows command, you can use the task's os attribute and set its
+ value to your current os.</p>
+
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">file</td>
+ <td valign="top">the file or directory of which the permissions must be
+ changed.</td>
+ <td valign="top" valign="middle">Yes or nested
+ <code>&lt;fileset/list&gt;</code> elements.</td>
+ </tr>
+ <tr>
+ <td valign="top">readonly</td>
+ <td valign="top">the readonly permission.</td>
+ <td valign="top" rowspan="4">at least one of the four. </td>
+ </tr>
+ <tr>
+ <td valign="top">archive</td>
+ <td valign="top">the archive permission.</td>
+ </tr>
+ <tr>
+ <td valign="top">system</td>
+ <td valign="top">the system permission.</td>
+ </tr>
+ <tr>
+ <td valign="top">hidden</td>
+ <td valign="top">the hidden permission.</td>
+ </tr>
+ <tr>
+ <td valign="top">type</td>
+ <td valign="top">One of <i>file</i>, <i>dir</i> or <i>both</i>. If set to
+ <i>file</i>, only the permissions of plain files are going to be changed.
+ If set to <i>dir</i>, only the directories are considered.<br>
+ <strong>Note:</strong> The type attribute does not apply to
+ nested <i>dirset</i>s - <i>dirset</i>s always implicitly
+ assume type to be <i>dir</i>.</td>
+ <td align="center" valign="top">No, default is <i>file</i></td>
+ </tr>
+ <tr>
+ <td valign="top">verbose</td>
+ <td valign="top">Whether to print a summary after execution or not.
+ Defaults to <code>false</code>.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <!--tr>
+ <td valign="top">parallel</td>
+ <td valign="top">process all specified files using a single
+ <code>chmod</code> command. Defaults to true.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">maxparallel</td>
+ <td valign="top">Limit the amount of parallelism by passing at
+ most this many sourcefiles at once. Set it to &lt;= 0 for
+ unlimited. Defaults to unlimited. <em>Since Ant 1.6.</em></td>
+ <td align="center" valign="top">No</td>
+ </tr-->
+ <tr>
+ <td valign="top">os</td>
+ <td valign="top">list of Operating Systems on which the command may be
+ executed.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">osfamily</td>
+ <td valign="top">OS family as used in
+ the <a href="../Tasks/conditions.html#os">&lt;os&gt;</a>
+ condition.</td>
+ <td align="center" valign="top">No - defaults to "windows"</td>
+ </tr>
+</table>
+
+<h3>Examples</h3>
+ <blockquote>
+<pre>&lt;attrib file=&quot;${dist}/run.bat&quot; readonly=&quot;true&quot; hidden=&quot;true&quot;/&gt;</pre>
+</blockquote>
+<p>makes the &quot;run.bat&quot; file read-only and hidden.</p>
+
+<blockquote>
+ <pre>&lt;attrib readonly=&quot;false&quot;&gt;
+ &lt;fileset dir=&quot;${meta.inf}&quot; includes=&quot;**/*.xml&quot;/&gt;
+&lt;/attrib&gt;
+</pre>
+</blockquote>
+<p>makes all &quot;.xml&quot; files below <code>${meta.inf}</code> readable.</p>
+
+<blockquote>
+ <pre>
+&lt;attrib readonly=&quot;true&quot; archive=&quot;true&quot;&gt;
+ &lt;fileset dir=&quot;shared/sources1&quot;&gt;
+ &lt;exclude name=&quot;**/trial/**&quot;/&gt;
+ &lt;/fileset&gt;
+ &lt;fileset refid=&quot;other.shared.sources&quot;/&gt;
+&lt;/attrib&gt;
+</pre>
+</blockquote>
+<p>makes all files below <code>shared/sources1</code> (except those below any
+ directory named trial) read-only and archived. In addition all files belonging
+ to a FileSet with <code>id</code> <code>other.shared.sources</code> get the
+ same attributes.</p>
+
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/augment.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/augment.html
new file mode 100644
index 00000000..305e39a8
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/augment.html
@@ -0,0 +1,83 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Augment Task</title>
+</head>
+
+<body>
+
+<h2>Augment</h2>
+
+<h3>Description</h3>
+<p>Modify an existing reference by adding nested elements or (re-)assigning properties
+mapped as XML attributes. This is an unusual task that makes use of Ant's internal
+processing mechanisms to reload a previously declared reference by means of the 'id'
+attribute, then treats the declared <code>augment</code> element as though it were the
+original element.
+<b>Since Apache Ant 1.8.1</b></p>
+
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">id</td>
+ <td valign="top">The id of the reference to augment. If no such reference has
+ been declared a <code>BuildException</code> is generated.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+</table>
+<p>
+Additional permissible attributes are dependent on the reference to be modified.
+</p>
+
+<h3>Parameters specified as nested elements</h3>
+
+<p>
+Permissible nested elements are dependent on the reference to be modified.
+</p>
+
+<h3>Examples</h3>
+
+Given
+<pre>
+ &lt;fileset id="input-fs" dir="${basedir}" /&gt;
+</pre>
+
+<pre>
+ &lt;augment id="input-fs" excludes="foo" /&gt;
+</pre>
+
+<p>Modifies the <code>excludes</code> attribute of <code>input-fs</code>.</p>
+
+<pre>
+ &lt;augment id="input-fs"&gt;
+ &lt;filename name="bar" /&gt;
+ &lt;/augment&gt;
+</pre>
+
+<p>Adds a <code>filename</code> selector to <code>input-fs</code>.</p>
+
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/available.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/available.html
new file mode 100644
index 00000000..6e4a1718
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/available.html
@@ -0,0 +1,160 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Available Task</title>
+</head>
+
+<body>
+
+<h2><a name="available">Available</a></h2>
+<h3>Description</h3>
+<p>Sets a property if a resource is available at runtime. This resource can be a
+file, a directory, a class in the classpath, or a JVM system resource.</p>
+<p>If the resource is present, the property value is set to true by
+default; otherwise, the property is not set. You can set the value to
+something other than the default by specifying the <code>value</code> attribute.</p>
+<p>Normally, this task is used to set properties that are useful to avoid target
+execution depending on system parameters.</p>
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">property</td>
+ <td valign="top">The name of the property to set.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">value</td>
+ <td valign="top">The value to set the property to. Defaults to &quot;true&quot;.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">classname</td>
+ <td valign="top">The class to look for in the classpath.</td>
+ <td valign="middle" align="center" rowspan="3">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">file</td>
+ <td valign="top">The file to look for.</td>
+ </tr>
+ <tr>
+ <td valign="top">resource</td>
+ <td valign="top">The resource to look for in the JVM.</td>
+ </tr>
+ <tr>
+ <td valign="top">classpath</td>
+ <td valign="top">The classpath to use when looking up <code>classname</code> or <code>resource</code>.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">filepath</td>
+ <td valign="top">The path to use when looking up <code>file</code>.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">classpathref</td>
+ <td valign="top">The classpath to use, given as a <a href="../using.html#references">reference</a> to a path defined elsewhere.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">type</td>
+ <td valign="top">The type of <code>file</code> to look for, either a directory (<code>type=&quot;dir&quot;</code>) or a file
+ (<code>type=&quot;file&quot;</code>). If not set, the property will be set if the name specified in the <code>file</code>
+ attribute exists as either a file or a directory.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">ignoresystemclasses</td>
+ <td valign="top">Ignore Ant's runtime classes, using only the specified
+ classpath. Only affects the "classname" attribute. Defaults to &quot;false&quot;</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">searchparents</td>
+ <td valign="top">This contains the behaviour of the "file" type.
+ If true, the available task will, when
+ searching for a file, search not only the directories specified but
+ will also search the parent directories of those
+ specified.
+ If false, only the directories specified will be searched.
+ Defaults to "false".
+ <em>Since Ant 1.7</em>
+ </td>
+ <td align="center" valign="top">No</td>
+ </tr>
+</table>
+<h3>Parameters specified as nested elements</h3>
+<h4>classpath</h4>
+<p><code>Available</code>'s <code>classpath</code> attribute is a <a
+href="../using.html#path">path-like structure</a> and can also be set via a nested
+<code>&lt;classpath&gt;</code> element.</p>
+<h4>filepath</h4>
+<p><code>Available</code>'s <code>filepath</code> attribute is a <a
+href="../using.html#path">path-like structure</a> and can also be set via a nested
+<code>&lt;filepath&gt;</code> element.</p>
+<h3>Examples</h3>
+<blockquote><pre>
+&lt;available classname=&quot;org.whatever.Myclass&quot; property=&quot;Myclass.present&quot;/&gt;
+</pre></blockquote>
+<p>sets the <code>Myclass.present</code> property to the value &quot;true&quot;
+if the class <code>org.whatever.Myclass</code> is found in Ant's classpath.</p>
+<blockquote><pre>
+&lt;property name=&quot;jaxp.jar&quot; value=&quot;./lib/jaxp11/jaxp.jar&quot;/&gt;
+&lt;available file=&quot;${jaxp.jar}&quot; property=&quot;jaxp.jar.present&quot;/&gt;
+</pre></blockquote>
+<p>sets the <code>jaxp.jar.present</code> property to the value &quot;true&quot;
+if the file <code>./lib/jaxp11/jaxp.jar</code> is found.</p>
+<blockquote><pre>
+&lt;available file=&quot;/usr/local/lib&quot; type=&quot;dir&quot;
+ property=&quot;local.lib.present&quot;/&gt;
+</pre></blockquote>
+<p>sets the <code>local.lib.present</code> property to the value &quot;true&quot;
+if the directory <code>/usr/local/lib</code> is found.</p>
+<blockquote><pre>
+...in project ...
+&lt;property name=&quot;jaxp.jar&quot; value=&quot;./lib/jaxp11/jaxp.jar&quot;/&gt;
+&lt;path id=&quot;jaxp&quot; location=&quot;${jaxp.jar}&quot;/&gt;
+...in target ...
+&lt;available classname=&quot;javax.xml.transform.Transformer&quot;
+ classpathref=&quot;jaxp&quot; property=&quot;jaxp11.present&quot;/&gt;
+</pre></blockquote>
+<p>sets the <code>jaxp11.present</code> property to the value &quot;true&quot;
+if the class <code>javax.xml.transform.Transformer</code> is found in the classpath referenced by <code>jaxp</code> (in this case, <code>./lib/jaxp11/jaxp.jar</code>).
+</p>
+<blockquote><pre>
+&lt;available property=&quot;have.extras&quot; resource=&quot;extratasks.properties&quot;&gt;
+ &lt;classpath&gt;
+ &lt;pathelement location=&quot;/usr/local/ant/extra.jar&quot; /&gt;
+&nbsp;&nbsp;&lt;/classpath&gt;
+&lt;/available&gt;
+</pre></blockquote>
+<p>sets the <code>have.extras</code> property to the value &quot;true&quot;
+if the resource-file <code>extratasks.properties</code> is found.
+</p>
+
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/basename.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/basename.html
new file mode 100644
index 00000000..0822d8f9
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/basename.html
@@ -0,0 +1,92 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Basename Task</title>
+</head>
+
+<body>
+
+<h2><a name="echo">Basename</a></h2>
+<h3>Description</h3>
+<p>
+Task to determine the basename of a specified file, optionally minus a
+specified suffix.
+</p>
+<p>
+When this task executes, it will set the specified property to the
+value of the last path element of the specified file. If <code>file</code> is a
+directory, the basename will be the last directory element. If
+<code>file</code> is a full-path, relative-path, or simple filename,
+the basename will be the simple file name, without any directory elements.
+</p>
+<p>
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">file</td>
+ <td valign="top">The path to take the basename of.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">property</td>
+ <td valign="top">The name of the property to set.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">suffix</td>
+ <td valign="top">The suffix to remove from the resulting basename
+ (specified either with or without the &quot;<code>.</code>&quot;).</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+</table>
+
+<h3>Examples</h3>
+<blockquote><pre>
+&lt;basename property=&quot;jar.filename&quot; file=&quot;${lib.jarfile}&quot;/&gt;
+</pre></blockquote>
+will set <code>jar.filename</code> to
+<code>myjar.jar</code>, if <code>lib.jarfile</code> is defined as either a
+full-path filename (eg., <code>/usr/local/lib/myjar.jar</code>),
+a relative-path filename (eg., <code>lib/myjar.jar</code>),
+or a simple filename (eg., <code>myjar.jar</code>).
+<blockquote><pre>
+&lt;basename property=&quot;cmdname&quot; file=&quot;D:/usr/local/foo.exe&quot;
+ suffix=&quot;.exe&quot;/&gt;
+</pre></blockquote>
+will set <code>cmdname</code> to <code>foo</code>.
+<blockquote><pre>
+&lt;property environment=&quot;env&quot;/&gt;
+&lt;basename property=&quot;temp.dirname&quot; file=&quot;${env.TEMP}&quot;/&gt;
+</pre></blockquote>
+
+will set <code>temp.dirname</code> to the last directory element of
+the path defined for the <code>TEMP</code> environment variable.</p>
+
+
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/bindtargets.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/bindtargets.html
new file mode 100644
index 00000000..d8374a49
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/bindtargets.html
@@ -0,0 +1,92 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Bindtargets Task</title>
+</head>
+
+<body>
+
+<h2><a name="ant">Bindtargets</a></h2>
+<h3>Description</h3>
+
+<p>Make some target the extension of some defined
+<a href="../targets.html#extension-points">extension point</a>. It will make the
+list of targets dependencies of the extension point.</p>
+
+<p>This target is useful when you want to have a target participate to another
+build workflow, build workflow which explicitly expose an extension point for
+that kind of insertion. But the target to bind and the extension point to
+bind to are both declared in some imported build files. Modifying directly the
+target dependency graph of these external build files may have a side effect
+on some other project which import them. This task helps then to modify the
+target dependencies but only in your context.
+</p>
+
+<p>Note: this task is quite equivalent to the definition of an intermediate
+target which will be the bridge between the target to bind and the extension
+point. For instance:
+</p>
+<blockquote><pre>&lt;bindtargets targets="jar,javadoc" extensionPoint="dist" /&gt;</pre></blockquote>
+is quite equivalent to:
+<blockquote><pre>&lt;target name="bind-to-dist" depends="jar,javadoc" extensionOf="dist" /&gt;</pre></blockquote>
+<p>
+This task basically avoid the creation of a target.
+</p>
+
+<p>The bindtargets task may only be used as a top-level task. This means that
+it may not be used in a target. This is making the target dependency graph static
+and predictable as soon as every build file is loaded.</p>
+
+<p><b>Since Apache Ant 1.8.2</b></p>
+
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">targets</td>
+ <td valign="top">a comma separated list of target names to bind.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">extensionPoint</td>
+ <td valign="top">the name of the extension point to bind the targets to.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">onMissingExtensionPoint</td>
+ <td valign="top">What to do if this target tries to extend a missing
+ <a href="../targets.html#extension-points">extension-point</a>. ("fail",
+ "warn", "ignore").</td>
+ <td valign="top" align="center">No. Defaults to <code>fail</code></td>
+ </tr>
+</table>
+
+<h3>Examples</h3>
+<blockquote><pre>
+&lt;bindtargets targets=&quot;build-jar,build-src-jar&quot; extensionPoint=&quot;dist&quot; /&gt;
+</pre></blockquote>
+
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/buildnumber.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/buildnumber.html
new file mode 100644
index 00000000..aaaa14cd
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/buildnumber.html
@@ -0,0 +1,74 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>BuildNumber Task</title>
+</head>
+
+<body>
+
+<h2><a name="buildnumber">BuildNumber</a></h2>
+<h3>Description</h3>
+<p>This is a basic task that can be used to track build numbers.</p>
+<p>It will first attempt to read a build number from a file (by default,
+<code>build.number</code> in the current directory), then
+set the property <code>build.number</code> to the value that was read in
+(or to <code>0</code>, if no such value). It will then increment the
+number by one and write it back out to the file.
+(See the
+<a href="../Tasks/propertyfile.html">PropertyFile</a> task
+if you need finer control over things such as the property name or
+the number format.)
+</p>
+
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">file</td>
+ <td valign="top">The file to read and write the build number from/to.</td>
+ <td align="center" valign="top">No; defaults to &quot;build.number&quot;</td>
+ </tr>
+</table>
+
+<h3>Examples</h3>
+<blockquote><pre>
+&lt;buildnumber/&gt;
+</pre></blockquote>
+
+<p>Read, increment, and write a build number to the default file,
+<code>build.number</code>.</p>
+
+<blockquote><pre>
+&lt;buildnumber file=&quot;mybuild.number&quot;/&gt;
+</pre></blockquote>
+
+<p>Read, increment, and write a build number to the file
+<code>mybuild.number</code>.</p>
+
+
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/cab.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/cab.html
new file mode 100644
index 00000000..e981827a
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/cab.html
@@ -0,0 +1,167 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Cab Task</title>
+</head>
+
+<body>
+
+<h2><a name="cab">Cab</a></h2>
+<h3>Description</h3>
+<p>The cab task creates Microsoft cab archive files. It is invoked
+similar to the <a href="../Tasks/jar.html">jar</a> or <a href="../Tasks/zip.html">zip</a> tasks.
+This task will work on Windows using the external cabarc tool (provided by Microsoft)
+which must be located in your executable path.</p>
+<p>To use this task on other platforms you need to download and compile libcabinet from
+<a href="http://trill.cis.fordham.edu/~barbacha/cabinet_library/">
+http://trill.cis.fordham.edu/~barbacha/cabinet_library/</a>.</p>
+<p>See the section on <a href="../dirtasks.html#directorybasedtasks">directory based
+tasks</a>, on how the inclusion/exclusion of files works, and how to
+write patterns.</p>
+<p>This task forms an implicit <a href="../Types/fileset.html">FileSet</a> and
+supports most attributes of <code>&lt;fileset&gt;</code>
+(<code>dir</code> becomes <code>basedir</code>) as well as the nested
+<code>&lt;include&gt;</code>, <code>&lt;exclude&gt;</code> and
+<code>&lt;patternset&gt;</code> elements.</p>
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">cabfile</td>
+ <td valign="top">the name of the cab file to create.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">basedir</td>
+ <td valign="top">the directory to start archiving files from.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">verbose</td>
+ <td valign="top">set to &quot;yes&quot; if you want to see the output from
+ the cabarc tool. defaults to &quot;no&quot;.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">compress</td>
+ <td valign="top">set to &quot;no&quot; to store files without compressing.
+ defaults to &quot;yes&quot;.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">options</td>
+ <td valign="top">use to set additional command-line options for
+ the cabarc tool. should not normally be necessary.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">includes</td>
+ <td valign="top">comma- or space-separated list of patterns of files that
+ must be included. All files are included when omitted.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">includesfile</td>
+ <td valign="top">the name of a file. Each line of this file is
+ taken to be an include pattern</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">excludes</td>
+ <td valign="top">comma- or space-separated list of patterns of files that
+ must be excluded. No files (except default excludes) are excluded
+ when omitted.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">excludesfile</td>
+ <td valign="top">the name of a file. Each line of this file is
+ taken to be an exclude pattern</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">defaultexcludes</td>
+ <td valign="top">indicates whether default excludes should be used
+ or not (&quot;yes&quot;/&quot;no&quot;). Default excludes are used when omitted.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+</table>
+<h3>Parameters specified as nested elements</h3>
+<h4>fileset</h4>
+
+<p>The cab task supports one nested <a
+href="../Types/fileset.html"><code>&lt;fileset&gt;</code></a>
+element to specify the files to be included in the archive.
+ If this is specified, the "basedir" attribute cannot be used.
+</p>
+
+<h3>Examples</h3>
+<blockquote><pre>
+&lt;cab cabfile=&quot;${dist}/manual.cab&quot;
+ basedir=&quot;htdocs/manual&quot;
+ /&gt;
+</pre></blockquote>
+<p>cabs all files in the htdocs/manual directory into a file called
+manual.cab in the ${dist} directory.</p>
+<blockquote><pre>
+&lt;cab cabfile=&quot;${dist}/manual.cab&quot;
+ basedir=&quot;htdocs/manual&quot;
+ excludes=&quot;mydocs/**, **/todo.html&quot;
+ /&gt;
+</pre></blockquote>
+<p>cabs all files in the htdocs/manual directory into a file called
+manual.cab in the ${dist} directory. Files in the directory mydocs,
+or files with the name todo.html are excluded.</p>
+<blockquote><pre>
+&lt;cab cabfile=&quot;${dist}/manual.cab&quot;
+ basedir=&quot;htdocs/manual&quot;
+ includes=&quot;api/**/*.html&quot;
+ excludes=&quot;**/todo.html&quot;
+ verbose=&quot;yes&quot;
+ /&gt;
+</pre></blockquote>
+<p>Cab all files in the htdocs/manual directory into a file called
+manual.cab in the ${dist} directory. Only html files under the
+directory api are archived, and files with the name todo.html are
+excluded. Output from the cabarc tool is displayed in the build
+output.</p>
+
+<blockquote><pre>
+&lt;cab cabfile=&quot;${dist}/manual.cab&quot;
+ verbose=&quot;yes&quot;&gt;
+ &lt;fileset
+ dir=&quot;htdocs/manual&quot;
+ includes=&quot;api/**/*.html&quot;
+ excludes=&quot;**/todo.html&quot;
+ /&gt;
+&lt;/cab&gt;
+</pre></blockquote>
+<p>is equivalent to the example above.</p>
+
+
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/ccm.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/ccm.html
new file mode 100644
index 00000000..9f4725f7
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/ccm.html
@@ -0,0 +1,272 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Continuus Tasks</title>
+</head>
+
+<body>
+
+<h1>Continuus Support</h1>
+<ul>
+ <li><a href="#ccmcheckin">CCMCheckin</a></li>
+ <li><a href="#ccmcheckout">CCMCheckout</a></li>
+ <li><a href="#ccmcheckintask">CCMCheckinTask</a></li>
+ <li><a href="#ccmreconfigure">CCMReconfigure</a></li>
+ <li><a href="#ccmcreatetask">CCMCreateTask</a></li>
+</ul>
+
+<p>These Apache Ant tasks are wrappers around Continuus Source Manager. They have been tested
+ against versions 5.1/6.2 on Windows 2000, but should work on other platforms with ccm installed.</p>
+<hr>
+<h2><a name="ccmcheckin">CCMCheckin</a></h2>
+<h3>Description</h3>
+Task to checkin a file
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0" width="598">
+ <tr>
+ <th>Attribute</th>
+ <th>Values</th>
+ <th>Required</th>
+ </tr>
+ <tr>
+ <td>file</td>
+ <td>Path to the file that the command will operate on</td>
+ <td>Yes</td>
+ </tr>
+ <tr>
+ <td>comment</td>
+ <td>Specify a comment. Default is &quot;Checkin&quot; plus the date</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>task</td>
+ <td>Specify the task number used to check in the file (may use 'default')</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>ccmdir</td>
+ <td>path to the ccm executable file, required if it is not on the PATH</td>
+ <td>No</td>
+ </tr>
+</table>
+<h3>Examples</h3>
+<blockquote>
+ <pre>&lt;ccmcheckin file=&quot;c:/wa/com/foo/MyFile.java&quot;
+ comment=&quot;mycomment&quot;/&gt;
+</pre>
+</blockquote>
+<p>Checks in the file <i>c:/wa/com/foo/MyFile.java</i>.
+ Comment attribute <i>mycomment</i> is added as a task comment. The task
+ used is the one set as the default.</p>
+<hr>
+<h2><a name="ccmcheckout">CCMCheckout</a></h2>
+<h3>Description</h3>
+Task to perform a Checkout command to Continuus
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0" width="614">
+ <tr>
+ <th>Attribute</th>
+ <th>Values</th>
+ <th>Required</th>
+ </tr>
+ <tr>
+ <td>file</td>
+ <td>Path to the file that the command will operate on</td>
+ <td rowspan=2">Yes (file|fileset)</td>
+ </tr>
+ <tr>
+ <td>fileset</td>
+ <td>fileset containing the file to be checked out</td>
+ </tr>
+ <tr>
+ <td>comment</td>
+ <td>Specify a comment.</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>task</td>
+ <td>Specify the task number used to checkin the file (may use
+ 'default')</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>ccmdir</td>
+ <td>path to the ccm executable file, required if it is not on the PATH</td>
+ <td>No</td>
+ </tr>
+</table>
+<h3>Examples</h3>
+<blockquote>
+ <pre>&lt;ccmcheckout file=&quot;c:/wa/com/foo/MyFile.java&quot;
+ comment=&quot;mycomment&quot;/&gt;
+</pre>
+</blockquote>
+<p>Check out the file <i>c:/wa/com/foo/MyFile.java</i>.
+ Comment attribute <i>mycomment</i> is added as a task comment
+ The used task is the one set as the default.</p>
+<blockquote>
+ <pre>&lt;ccmcheckout comment=&quot;mycomment&quot;&gt;
+ &lt;fileset dir=&quot;lib&quot; &gt;
+ &lt;include name=&quot;**/*.jar&quot;/&gt;
+ &lt;/fileset&gt;
+&lt;/ccmcheckout &gt;
+ </pre>
+</blockquote>
+
+<p>Check out all the files in the <i>lib</i> directory having the <i>.jar</i> extension.
+ Comment attribute <i>mycomment</i> is added as a task comment
+ The used task is the one set as the default.</p>
+
+
+
+<hr>
+<h2><a name="ccmcheckintask">CCMCheckinTask</a></h2>
+<h3>Description</h3>
+Task to perform a check in default task command to Continuus
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <th>Attribute</th>
+ <th>Values</th>
+ <th>Required</th>
+ </tr>
+ <tr>
+ <td>comment</td>
+ <td>Specify a comment.</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>task</td>
+ <td>Specify the task number used to check in the file (may use 'default')</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>ccmdir</td>
+ <td >path to the ccm executable file, required if it is not on the PATH</td>
+ <td>No</td>
+ </tr>
+</table>
+<h3>Examples </h3>
+<blockquote>
+ <pre>&lt;ccmcheckintask comment=&quot;blahblah/&gt;
+</pre>
+</blockquote>
+<p>Does a Checkin default task on all the checked out files in the current task.</p>
+<hr>
+<h2><a name="ccmreconfigure">CCMReconfigure</a></h2>
+<h3>Description</h3>
+Task to perform an reconfigure command to Continuus.
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <th>Attribute</th>
+ <th>Values</th>
+ <th>Required</th>
+ </tr>
+ <tr>
+ <td>recurse</td>
+ <td>recurse on subproject (default false)</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>verbose</td>
+ <td>do a verbose reconfigure operation (default false)</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>ccmproject</td>
+ <td>Specifies the ccm project on which the operation is applied.</td>
+ <td>Yes</td>
+ </tr>
+ <tr>
+ <td>ccmdir</td>
+ <td >path to the ccm executable file, required if it is not on the PATH</td>
+ <td>No</td>
+ </tr>
+</table>
+<h3>Examples</h3>
+<blockquote>
+ <pre>&lt;ccmreconfigure ccmproject=&quot;ANTCCM_TEST#BMO_1&quot;
+ verbose=&quot;true&quot;/&gt;
+</pre>
+</blockquote>
+<p>Does a Continuus <i>reconfigure</i> on the project <i>ANTCCM_TEST#BMO_1</i>.
+</p>
+<hr>
+<h2><a name="ccmcreatetask">CCMCreateTask</a></h2>
+<h3>Description</h3>
+Create a Continuus task.
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <th>Attribute</th>
+ <th>Values</th>
+ <th>Required</th>
+ </tr>
+ <tr>
+ <td>comment</td>
+ <td>Specify a comment.</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>platform</td>
+ <td>Specify the target platform</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>ccmdir</td>
+ <td >path to the ccm executable file, required if it is not on the PATH</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>resolver</td>
+ <td>Specify the resolver</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>release</td>
+ <td>Specify the CCM release</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>subsystem</td>
+ <td>Specify the subsystem</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>task</td>
+ <td>Specify the task number used to checkin the file (may use 'default')</td>
+ <td>No</td>
+ </tr>
+</table>
+<h3>Examples</h3>
+<blockquote>
+ <pre>&lt;ccmcreatetask resolver=&quot;${user.name}&quot;
+ release=&quot;ANTCCM_TEST&quot; comment=&quot;blahblah&quot;/&gt;
+</pre>
+</blockquote>
+<p>Creates a task for the release <i>ANTCCM_TEST</i> with the
+ current user as the resolver for this task.</p>
+
+
+</body>
+
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/changelog.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/changelog.html
new file mode 100644
index 00000000..8d9a70b8
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/changelog.html
@@ -0,0 +1,294 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>ChangeLog Task</title>
+</head>
+
+<body>
+
+<h2><a name="changelog">CvsChangeLog</a></h2>
+<h3>Description</h3>
+<p>Generates an XML-formatted report file of the change logs recorded in a
+<a href="http://www.nongnu.org/cvs/" target="_top">CVS</a> repository. </p>
+<p><b>Important:</b> This task needs &quot;<code>cvs</code>&quot; on the path. If it isn't, you will get
+an error (such as error <code>2</code> on windows). If <code>&lt;cvs&gt;</code> doesn't work, try to execute <code>cvs.exe</code>
+from the command line in the target directory in which you are working.
+Also note that this task assumes that the cvs executable is compatible
+with the Unix version from cvshome.org, this is not completely true
+for certain other cvs clients - like CVSNT for example - and some
+operation may fail when using such an incompatible client.
+</p>
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td colspan="3">Attributes from parent Cvs task which are meaningful here<br>
+ Since Apache Ant 1.6.1</td>
+ </tr>
+ <tr>
+ <td valign="top">cvsRoot</td>
+ <td valign="top">the <code>CVSROOT</code> variable.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">cvsRsh</td>
+ <td valign="top">the <code>CVS_RSH</code> variable.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">package</td>
+ <td valign="top">the package/module to check out. <b>Note:</b>
+ multiple attributes can be split using spaces. Use a nested
+ &lt;module&gt; element if you want to specify a module with
+ spaces in its name.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">port</td>
+ <td valign="top">Port used by CVS to communicate with the server.</td>
+ <td align="center" valign="top">No, default port 2401.</td>
+ </tr>
+ <tr>
+ <td valign="top">passfile</td>
+ <td valign="top">Password file to read passwords from.</td>
+ <td align="center" valign="top">No, default file <code>~/.cvspass</code>.</td>
+ </tr>
+ <tr>
+ <td valign="top">failonerror</td>
+ <td valign="top">Stop the build process if the command exits with a
+ return code other than <code>0</code>. Defaults to false</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">tag</td>
+ <td valign="top">query the changelog for a specific branch.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td colspan="3">Specific attributes</td>
+ </tr>
+ <tr>
+ <td valign="top">dir</td>
+ <td valign="top">The directory from which to run the CVS <em>log</em>
+ command.</td>
+ <td align="center" valign="top">No; defaults to ${basedir}.</td>
+ </tr>
+ <tr>
+ <td valign="top">destfile</td>
+ <td valign="top">The file in which to write the change log report.</td>
+ <td align="center" valign="top">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">usersfile</td>
+ <td valign="top">Property file that contains name-value pairs mapping
+ user IDs and names that should be used in the report in place of
+ the user ID.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">daysinpast</td>
+ <td valign="top">Sets the number of days into the past for which the
+ change log information should be retrieved.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">start</td>
+ <td valign="top">The earliest date from which change logs are to be
+ included in the report.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">end</td>
+ <td valign="top">The latest date to which change logs are to be
+ included in the report.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">remote</td>
+ <td valign="top">If set to true, works against the repository
+ (using rlog) without a working copy. Default is
+ false. <em>Since Ant 1.8.0</em></td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">startTag</td>
+ <td valign="top">The start of a tag range. If endTag is also
+ specified, they must both be on the same branch. If endTag is not
+ specified, the end of the range will be the latest on the same
+ branch on which startTag lives. <em>Since Ant 1.8.0</em></td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">endTag</td>
+ <td valign="top">The end of a tag range. If startTag is also
+ specified, they must both be on the same branch. If startTag is
+ not specified, the start of the range will be the top of the
+ branch on which endTag lives.</td> included in the report.
+ <em>Since Ant 1.8.0</em></td>
+ <td align="center" valign="top">No</td>
+ </tr>
+</table>
+
+<h3>Parameters specified as nested elements</h3>
+<h4><a name="user">user</a></h4>
+<p>The nested <code>&lt;user&gt;</code> element allows you to specify a
+mapping between a user ID as it appears on the CVS server and a name to
+include in the formatted report.
+Anytime the specified user ID has made a change in the repository, the
+<code>&lt;author&gt;</code> tag in the report file will include
+the name specified in <code>displayname</code> rather than the user ID.
+</p>
+
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">displayname</td>
+ <td valign="top">The name to be used in the CVS change log report.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">userid</td>
+ <td valign="top">The userid of the person as it exists on the CVS server.
+ </td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+</table>
+
+<h4>module</h4>
+
+<p>Specifies a package/module to work on, unlike the package attribute
+ modules specified using this attribute can contain spaces in their
+ name.</p>
+
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">name</td>
+ <td valign="top">The module's/package's name.</td>
+ <td align="center" valign="top">Yes.</td>
+ </tr>
+</table>
+
+<h3>Examples</h3>
+<pre> &lt;cvschangelog dir=&quot;dve/network&quot;
+ destfile=&quot;changelog.xml&quot;
+ /&gt;</pre>
+
+<p>Generates a change log report for all the changes that have been made
+under the <code>dve/network</code> directory.
+It writes these changes into the file <code>changelog.xml</code>.</p>
+
+<pre> &lt;cvschangelog dir=&quot;dve/network&quot;
+ destfile=&quot;changelog.xml&quot;
+ daysinpast=&quot;10&quot;
+ /&gt;</pre>
+
+<p>Generates a change log report for any changes that were made
+under the <code>dve/network</code> directory in the past 10 days.
+It writes these changes into the file <code>changelog.xml</code>.</p>
+
+<pre> &lt;cvschangelog dir=&quot;dve/network&quot;
+ destfile=&quot;changelog.xml&quot;
+ start=&quot;20 Feb 2002&quot;
+ end=&quot;20 Mar 2002&quot;
+ /&gt;</pre>
+
+<p>Generates a change log report for any changes that were made
+between February 20, 2002 and March 20, 2002
+under the <code>dve/network</code> directory.
+It writes these changes into the file <code>changelog.xml</code>.</p>
+
+<pre> &lt;cvschangelog dir=&quot;dve/network&quot;
+ destfile=&quot;changelog.xml&quot;
+ start=&quot;20 Feb 2002&quot;
+ /&gt;</pre>
+
+<p>Generates a change log report for any changes that were made
+after February 20, 2002 under the <code>dve/network</code> directory.
+It writes these changes into the file <code>changelog.xml</code>.</p>
+
+<pre> &lt;cvschangelog dir=&quot;dve/network&quot;
+ destfile=&quot;changelog.xml&quot;&gt;
+ &lt;user displayname=&quot;Peter Donald&quot; userid=&quot;donaldp&quot;/&gt;
+ &lt;/cvschangelog&gt;</pre>
+
+<p>Generates a change log report for all the changes that were made
+under the <code>dve/network</code> directory, substituting the name
+&quot;Peter Donald&quot; in the <code>&lt;author&gt;</code> tags
+anytime it encounters a change made by the user ID &quot;donaldp&quot;.
+It writes these changes into the file <code>changelog.xml</code>.</p>
+
+<p>Generates a change log report on the <code>ANT_16_BRANCH</code>.</p>
+<pre>
+ &lt;cvschangelog dir=&quot;c:/dev/asf/ant.head&quot; passfile=&quot;c:/home/myself/.cvspass&quot;
+ destfile=&quot;changelogant.xml&quot; tag=&quot;ANT_16_BRANCH&quot;/&gt;
+</pre>
+<h4>Generate Report</h4>
+<p>Ant includes a basic XSLT stylesheet that you can use to generate
+a HTML report based on the xml output. The following example illustrates
+how to generate a HTML report from the XML report.</p>
+
+<pre>
+ &lt;style in="changelog.xml"
+ out="changelog.html"
+ style="${ant.home}/etc/changelog.xsl"&gt;
+ &lt;param name="title" expression="Ant ChangeLog"/&gt;
+ &lt;param name="module" expression="ant"/&gt;
+ &lt;param name="cvsweb" expression="http://cvs.apache.org/viewcvs/"/&gt;
+ &lt;/style&gt;
+</pre>
+
+<h4>Sample Output</h4>
+<pre>
+&lt;changelog&gt;
+ &lt;entry&gt;
+ &lt;date&gt;2002-03-06&lt;/date&gt;
+ &lt;time&gt;12:00&lt;/time&gt;
+ &lt;author&gt;Peter Donald&lt;/author&gt;
+ &lt;file&gt;
+ &lt;name&gt;org/apache/myrmidon/build/AntlibDescriptorTask.java&lt;/name&gt;
+ &lt;revision&gt;1.3&lt;/revision&gt;
+ &lt;prevrevision&gt;1.2&lt;/prevrevision&gt;
+ &lt;/file&gt;
+ &lt;msg&gt;&lt;![CDATA[Use URLs directly rather than go via a File.
+
+This allows templates to be stored inside jar]]&gt;&lt;/msg&gt;
+ &lt;/entry&gt;
+&lt;/changelog&gt;
+</pre>
+
+
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/checksum.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/checksum.html
new file mode 100644
index 00000000..29f48ddf
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/checksum.html
@@ -0,0 +1,269 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Checksum Task</title>
+</head>
+
+<body>
+
+<h2><a name="checksum">Checksum</a></h2>
+<h3>Description</h3>
+<p>
+Generates checksum for files. This task can also be used to
+perform checksum verifications.
+</p>
+
+<p>Note that many popular message digest functions - including MD5 and
+SHA-1 - have been broken recently. If you are going to use the task
+to create checksums used in an environment where security is
+important, please take some time to investigate the algorithms offered
+by your JCE provider. Note also that some JCE providers like the one
+by <a href="http://www.bouncycastle.org/">The Legion of the Bouncy
+Castle</a>, the <a href="http://www.gnu.org/software/gnu-crypto/">GNU
+project</a> or <a
+href="http://jce.iaik.tugraz.at/products/01_jce/index.php">the
+Technical University Graz</a> offer more digest algorithms than those
+built-in into your JDK.</p>
+
+<p>
+Warning: the case of the extension is that of the algorithm used.
+If you ask for "SHA1", you get a .SHA1 extension; if you ask for "sha1", you
+get a file ending in .sha1. The Java Crypto Engines are case-insensitive
+in matching algorithms, so choose a name to match your desired output extension,
+or set the <tt>fileext</tt> attribute. The names of common hashing algorithms can be located on the
+<a target="_blank" href="http://docs.oracle.com/javase/7/docs/technotes/guides/security/StandardNames.html#MessageDigest">Cryptography Architecture Standard Algorithm Name Documentation</a>
+</p>
+
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">file</td>
+ <td valign="top">The file to generate checksum for.</td>
+ <td valign="top" align="center">One of either <var>file</var> or
+ at least one nested (filesystem-only) resource collection.</td>
+ </tr>
+ <tr>
+ <td valign="top">todir</td>
+ <td valign="top">The root directory where checksums should be written.</td>
+ <td valign="top" align="center">No. If not specified, checksum files
+ will be written to the same directory as the files themselves.
+ <em>since Apache Ant 1.6</em>
+ </td>
+ </tr>
+ <tr>
+ <td valign="top">algorithm</td>
+ <td valign="top">Specifies the algorithm to be used to
+ compute the checksum. Defaults to &quot;MD5&quot;.
+ Other <a target="_blank" href="http://docs.oracle.com/javase/7/docs/technotes/guides/security/StandardNames.html#MessageDigest">popular algorithms</a> like &quot;SHA&quot; or &quot;SHA-512&quot; may be used
+ as well.
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">provider</td>
+ <td valign="top">Specifies the provider of the algorithm.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">fileext</td>
+ <td valign="top">The generated checksum file's name will be the
+ original filename with the fileext added to it.
+ Defaults to a "." and the algorithm name being used.
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">property</td>
+ <td valign="top">This attribute can mean two different things, it
+ depends on the presence of the verifyproperty attribute.<br>
+ <b>If you don't set the verifyproperty attribute</b>, property
+ specifies the name of the property to be set with the generated
+ checksum value.<br>
+ <b>If you set the verifyproperty attribute</b>, property specifies
+ the checksum you expect to be generated (the checksum itself, not
+ a name of a property containing the checksum).<br>
+ This cannot be specified when fileext is being used or when the
+ number of files for which checksums is to be generated is greater
+ than 1.
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">pattern</td>
+ <td valign="top">Specifies the pattern to use as a pattern
+ suitable
+ for <a href="http://download.oracle.com/javase/6/docs/api/java/text/MessageFormat.html">MessageFormat</a>
+ where <code>{0}</code> is replaced with the checksum and
+ <code>{1}</code> with the file name. <em>Since Ant
+ 1.7.0</em><br/>
+ <em>starting with Ant 1.8.2</em> <code>{2}</code> is replaced by
+ the path of the file relative to the checksum file being
+ written, <code>{3}</code> with tha path of the file relative to
+ the project's basedir and <code>{4}</code> with the absolute
+ path of the file.</td>
+ <td valign="top" align="center">No - default is &quot;{0}&quot;.</td>
+ </tr>
+ <tr>
+ <td valign="top">format</td>
+ <td valign="top">Specifies the pattern to use as one of a
+ well-known format. Supported values are
+ <table border="1">
+ <tr>
+ <th>name</th>
+ <th>pattern</th>
+ <th>description</th>
+ </tr>
+ <tr>
+ <td>CHECKSUM </td>
+ <td><tt>{0}</tt></td>
+ <td>only the checksum itself </td>
+ </tr>
+ <tr>
+ <td>MD5SUM </td>
+ <td><tt>{0} *{1}</tt></td>
+ <td>the format of GNU textutils md5sum</td>
+ </tr>
+ <tr>
+ <td>SVF </td>
+ <td><tt>MD5 ({1}) = {0}</tt></td>
+ <td>the format of BSDs md5 command </td>
+ </tr>
+ </table>
+ <em>Since Ant 1.7.0</em>
+ </td>
+ <td valign="top" align="center">No - default is &quot;CHECKSUM&quot;.</td>
+ </tr>
+ <tr>
+ <td valign="top">totalproperty</td>
+ <td valign="top">If specified, this attribute specifies the name of
+ the property that will hold a checksum of all the checksums and
+ file paths. The individual checksums and the relative paths to the files
+ within the resource collections in which they are defined will be used to
+ compute this checksum. (The file separators in the paths will be
+ converted to '/' before computation to ensure platform portability).
+ <em>since Ant 1.6</em>
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">forceoverwrite</td>
+ <td valign="top">Overwrite existing files even if the destination
+ files are newer. Defaults to &quot;no&quot;.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">verifyproperty</td>
+ <td valign="top">Specifies the name of the property to be set
+ with &quot;true&quot; or &quot;false&quot; depending upon whether
+ the generated checksum matches the existing checksum. When
+ this is set, the generated checksum is not written to a file or
+ property, but rather, the content of the file or property is used to
+ check against the generated checksum.
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">readbuffersize</td>
+ <td valign="top">The size of the buffer (in bytes) to use when
+ reading a file. Defaults to &quot;8192&quot; - you may get a
+ better performance on big files if you increase this value.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+</table>
+<h3>Parameters specified as nested elements</h3>
+
+<h4>resource collection</h4>
+ <p>
+ <a href="../Types/resources.html#collection">Resource collections</a> are
+ used to select files for which checksums should be generated.
+ </p>
+
+<h3>Examples</h3>
+<p><b>Example 1</b></p>
+<blockquote><pre>&lt;checksum file=&quot;foo.bar&quot;/&gt;</pre></blockquote>
+Generates a MD5 checksum for foo.bar and stores the checksum in the destination file
+foo.bar.MD5. foo.bar.MD5 is overwritten only if foo.bar is newer than itself.
+
+<p><b>Example 2</b></p>
+<blockquote><pre>&lt;checksum file=&quot;foo.bar&quot; forceOverwrite=&quot;yes&quot;/&gt;</pre></blockquote>
+Generates a MD5 checksum for foo.bar and stores the checksum in foo.bar.MD5.
+If foo.bar.MD5 already exists, it is overwritten.
+
+<p><b>Example 3</b></p>
+<blockquote><pre>&lt;checksum file=&quot;foo.bar&quot; property=&quot;foobarMD5&quot;/&gt;</pre></blockquote>
+Generates a MD5 checksum for foo.bar and stores it in the Project Property foobarMD5.
+
+<p><b>Example 4</b></p>
+<blockquote><pre>&lt;checksum file=&quot;foo.bar&quot; verifyProperty=&quot;isMD5ok&quot;/&gt;</pre></blockquote>
+Generates a MD5 checksum for foo.bar, compares it against foo.bar.MD5 and sets
+isMD5ok to either true or false, depending upon the result.
+
+<p><b>Example 5</b></p>
+<blockquote><pre>&lt;checksum file=&quot;foo.bar&quot; algorithm=&quot;SHA-512&quot; fileext=&quot;asc&quot;/&gt;</pre></blockquote>
+Generates a SHA-512 checksum for foo.bar and stores the checksum in the destination file
+foo.bar.asc. foo.bar.asc is overwritten only if foo.bar is newer than itself.
+
+<p><b>Example 6</b></p>
+<blockquote><pre>
+&lt;checksum file=&quot;foo.bar&quot; property=&quot;${md5}&quot; verifyProperty=&quot;isEqual&quot;/&gt;
+</pre></blockquote>
+Generates a MD5 checksum for foo.bar, compares it against the value of the property
+md5, and sets isEqual to either true or false, depending upon the result.
+
+<p><b>Example 7</b></p>
+<blockquote><pre>
+&lt;checksum&gt;
+ &lt;fileset dir=&quot;.&quot;&gt;
+ &lt;include name=&quot;foo*&quot;/&gt;
+ &lt;/fileset&gt;
+&lt;/checksum&gt;
+</pre></blockquote>
+Works just like Example 1, but generates a .MD5 file for every file that begins with the name foo.
+
+<p><b>Example 8</b></p>
+<blockquote><pre>
+&lt;condition property=&quot;isChecksumEqual&quot;&gt;
+ &lt;checksum&gt;
+ &lt;fileset dir=&quot;.&quot;&gt;
+ &lt;include name=&quot;foo.bar&quot;/&gt;
+ &lt;/fileset&gt;
+ &lt;/checksum&gt;
+&lt;/condition&gt;
+</pre></blockquote>
+Works like Example 4, but only sets isChecksumEqual to true, if the
+checksum matches - it will never be set to false. This example
+demonstrates use with the Condition task.
+
+
+<h3>Note:</h3>
+When working with more than one file, if condition and/or verifyproperty is used,
+the result will be true only if the checksums matched correctly for all files being
+considered.
+
+
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/chgrp.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/chgrp.html
new file mode 100644
index 00000000..2126fb74
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/chgrp.html
@@ -0,0 +1,185 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Chgrp Task</title>
+</head>
+
+<body>
+
+<h2><a name="Chgrp">Chgrp</a></h2>
+<p><em>Since Apache Ant 1.6.</em></p>
+<h3>Description</h3>
+
+<p>Changes the group of a file or all files inside specified
+directories. Right now it has effect only under Unix. The group
+attribute is equivalent to the corresponding argument for the chgrp
+command.</p>
+
+<p><a href="../Types/fileset.html">FileSet</a>s,
+<a href="../Types/dirset.html">DirSet</a>s or <a
+href="../Types/filelist.html">FileList</a>s can be specified using
+nested <code>&lt;fileset&gt;</code>, <code>&lt;dirset&gt;</code> and
+<code>&lt;filelist&gt;</code> elements.</p>
+
+<p>Starting with Ant 1.7, this task supports arbitrary <a
+href="../Types/resources.html#collection">Resource Collection</a>s
+as nested elements.</p>
+
+<p>By default this task will use a single invocation of the underlying
+chgrp command. If you are working on a large number of files this may
+result in a command line that is too long for your operating system.
+If you encounter such problems, you should set the maxparallel
+attribute of this task to a non-zero value. The number to use highly
+depends on the length of your file names (the depth of your directory
+tree) and your operating system, so you'll have to experiment a
+little. POSIX recommends command line length limits of at least 4096
+characters, this may give you an approximation for the number you
+could use as initial value for these experiments.</p>
+
+<p>By default this task won't do anything unless it detects it is
+ running on a Unix system. If you know for sure that you have a
+ "chgrp" executable on your PATH that is command line compatible with
+ the Unix command, you can use the task's os attribute and set its
+ value to your current os.</p>
+
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">file</td>
+ <td valign="top">the file or directory of which the group must be
+ changed.</td>
+ <td valign="top" valign="middle">Yes, unless nested
+ <code>&lt;fileset|filelist|dirset&gt;</code>
+ elements are specified</td>
+ </tr>
+ <tr>
+ <td valign="top">group</td>
+ <td valign="top">the new group.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">parallel</td>
+ <td valign="top">process all specified files using a single
+ <code>chgrp</code> command. Defaults to true.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">type</td>
+ <td valign="top">One of <i>file</i>, <i>dir</i> or
+ <i>both</i>. If set to <i>file</i>, only the group of
+ plain files are going to be changed. If set to <i>dir</i>, only
+ the directories are considered.<br>
+ <strong>Note:</strong> The type attribute does not apply to
+ nested <i>dirset</i>s - <i>dirset</i>s always implicitly
+ assume type to be <i>dir</i>.</td>
+ <td align="center" valign="top">No, default is <i>file</i></td>
+ </tr>
+ <tr>
+ <td valign="top">maxparallel</td>
+ <td valign="top">Limit the amount of parallelism by passing at
+ most this many sourcefiles at once. Set it to &lt;= 0 for
+ unlimited. Defaults to unlimited.</td>
+ <td align="center" valign="top">No</td>
+
+ </tr>
+ <tr>
+ <td valign="top">verbose</td>
+ <td valign="top">Whether to print a summary after execution or not.
+ Defaults to <code>false</code>.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">os</td>
+ <td valign="top">list of Operating Systems on which the command may be
+ executed.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">osfamily</td>
+ <td valign="top">OS family as used in
+ the <a href="../Tasks/conditions.html#os">&lt;os&gt;</a>
+ condition.</td>
+ <td align="center" valign="top">No - defaults to "unix"</td>
+ </tr>
+
+</table>
+<h3>Examples</h3>
+ <blockquote><pre>
+&lt;chgrp file=&quot;${dist}/start.sh&quot; group=&quot;coders&quot;/&gt;
+</pre>
+</blockquote>
+<p>makes the &quot;start.sh&quot; file belong to the coders group on a
+UNIX system.</p>
+<blockquote>
+<pre>
+&lt;chgrp group=&quot;coders&quot;&gt;
+ &lt;fileset dir=&quot;${dist}/bin&quot; includes=&quot;**/*.sh&quot;/&gt;
+&lt;/chgrp&gt;
+</pre>
+</blockquote>
+<p>makes all &quot;.sh&quot; files below <code>${dist}/bin</code>
+belong to the coders group on a UNIX system.</p>
+<blockquote>
+<pre>
+&lt;chgrp group=&quot;coders&quot;&gt;
+ &lt;fileset dir=&quot;shared/sources1&quot;&gt;
+ &lt;exclude name=&quot;**/trial/**&quot;/&gt;
+ &lt;/fileset&gt;
+ &lt;fileset refid=&quot;other.shared.sources&quot;/&gt;
+&lt;/chgrp&gt;
+</pre>
+</blockquote>
+<p>makes all files below <code>shared/sources1</code> (except those
+below any directory named trial) belong to the coders group on a UNIX
+system. In addition all files belonging to a FileSet
+with <code>id</code> <code>other.shared.sources</code> get the same
+group.</p>
+
+<blockquote>
+<pre>
+&lt;chgrp group=&quot;webdev&quot; type=&quot;file&quot;&gt;
+ &lt;fileset dir=&quot;/web&quot;&gt;
+ &lt;include name=&quot;**/*.test.jsp&quot;/&gt;
+ &lt;include name=&quot;**/*.new&quot;/&gt;
+ &lt;/fileset&gt;
+ &lt;dirset dir=&quot;/web&quot;&gt;
+ &lt;include name=&quot;**/test_*&quot;/&gt;
+ &lt;/dirset&gt;
+&lt;/chmod&gt;
+</pre>
+</blockquote>
+
+<p>makes all <code>.test.jsp</code>, and <code>.new</code> files belong to
+group webdev. Directories beginning with <code>test_</code> also will belong
+to webdev, but if there is a directory that ends in <code>.new</code> or a file
+that begins with <code>test_</code> it will be unaffected.</p>
+
+
+
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/chmod.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/chmod.html
new file mode 100644
index 00000000..74e71d0a
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/chmod.html
@@ -0,0 +1,225 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Chmod Task</title>
+</head>
+
+<body>
+
+<h2><a name="chmod">Chmod</a></h2>
+<h3>Description</h3>
+<p>Changes the permissions of a file or all files inside specified
+directories. Right now it has effect only under Unix or NonStop Kernel (Tandem).
+The permissions are also UNIX style, like the argument for the chmod command.</p>
+<p>See the section on <a href="../dirtasks.html#directorybasedtasks">directory based
+tasks</a>, on how the inclusion/exclusion of files works, and how to
+write patterns.</p>
+
+<p>This task holds an implicit <a
+href="../Types/fileset.html">FileSet</a> and supports all of
+FileSet's attributes and nested elements directly. More sets can be
+specified using nested <code>&lt;fileset&gt;</code> or
+<code>&lt;dirset&gt;</code> (<em>since Apache Ant 1.6</em>) elements. </p>
+
+<p>Starting with Ant 1.6, this task also supports nested <a
+href="../Types/filelist.html">filelist</a>s.</p>
+
+<p>Starting with Ant 1.7, this task supports arbitrary <a
+href="../Types/resources.html#collection">Resource Collection</a>s
+as nested elements.</p>
+
+<p>By default this task will use a single invocation of the underlying
+chmod command. If you are working on a large number of files this may
+result in a command line that is too long for your operating system.
+If you encounter such problems, you should set the maxparallel
+attribute of this task to a non-zero value. The number to use highly
+depends on the length of your file names (the depth of your directory
+tree) and your operating system, so you'll have to experiment a
+little. POSIX recommends command line length limits of at least 4096
+characters, this may give you an approximation for the number you
+could use as initial value for these experiments.</p>
+
+<p>By default this task won't do anything unless it detects it is
+ running on a Unix system. If you know for sure that you have a
+ "chmod" executable on your PATH that is command line compatible with
+ the Unix command, you can use the task's os attribute and set its
+ value to your current os.</p>
+
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">file</td>
+ <td valign="top">the file or single directory of which the permissions
+ must be changed.</td>
+ <td valign="top" valign="middle" rowspan="2">exactly one of the two or nested <code>&lt;fileset/list&gt;</code> elements.</td>
+ </tr>
+ <tr>
+ <td valign="top">dir</td>
+ <td valign="top">the directory which holds the files whose permissions
+ must be changed.<br/>
+ <b>Note:</b> for backwards compatibility
+ reasons <code>&lt;chmod&nbsp;dir="some-dir"/&gt;</code> will
+ only change the permissions on "some-dir" but not recurse into
+ it, unless you also specify any patterns.</td>
+ </tr>
+ <tr>
+ <td valign="top">perm</td>
+ <td valign="top">the new permissions.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">includes</td>
+ <td valign="top">comma- or space-separated list of patterns of files that must be
+ included.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">excludes</td>
+ <td valign="top">comma- or space-separated list of patterns of files that must be
+ excluded. No files (except default excludes) are excluded when omitted.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">defaultexcludes</td>
+ <td valign="top">indicates whether default excludes should be used or not
+ (&quot;yes&quot;/&quot;no&quot;). Default excludes are used when omitted.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">parallel</td>
+ <td valign="top">process all specified files using a single
+ <code>chmod</code> command. Defaults to true.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">type</td>
+ <td valign="top">One of <i>file</i>, <i>dir</i> or
+ <i>both</i>. If set to <i>file</i>, only the permissions of
+ plain files are going to be changed. If set to <i>dir</i>, only
+ the directories are considered.<br>
+ <strong>Note:</strong> The type attribute does not apply to
+ nested <i>dirset</i>s - <i>dirset</i>s always implicitly
+ assume type to be <i>dir</i>.</td>
+ <td align="center" valign="top">No, default is <i>file</i></td>
+ </tr>
+ <tr>
+ <td valign="top">maxparallel</td>
+ <td valign="top">Limit the amount of parallelism by passing at
+ most this many sourcefiles at once. Set it to &lt;= 0 for
+ unlimited. Defaults to unlimited. <em>Since Ant 1.6.</em></td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">verbose</td>
+ <td valign="top">Whether to print a summary after execution or not.
+ Defaults to <code>false</code>. <em>Since Ant 1.6.</em></td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">os</td>
+ <td valign="top">list of Operating Systems on which the command may be
+ executed.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">osfamily</td>
+ <td valign="top">OS family as used in
+ the <a href="conditions.html#os">&lt;os&gt;</a> condition.</td>
+ <td align="center" valign="top">No - defaults to "unix"</td>
+ </tr>
+</table>
+<h3>Examples</h3>
+ <blockquote><pre>
+&lt;chmod file=&quot;${dist}/start.sh&quot; perm=&quot;ugo+rx&quot;/&gt;
+</pre></blockquote>
+<p>makes the &quot;start.sh&quot; file readable and executable for anyone on a
+UNIX system.</p>
+<blockquote><pre>
+&lt;chmod file=&quot;${dist}/start.sh&quot; perm=&quot;700&quot;/&gt;
+</pre></blockquote>
+<p>makes the &quot;start.sh&quot; file readable, writable and executable only for the owner on a
+UNIX system.</p>
+<blockquote>
+<pre>
+&lt;chmod dir=&quot;${dist}/bin&quot; perm=&quot;ugo+rx&quot;
+ includes=&quot;**/*.sh&quot;/&gt;
+</pre>
+</blockquote>
+<p>makes all &quot;.sh&quot; files below <code>${dist}/bin</code>
+readable and executable for anyone on a UNIX system.</p>
+<blockquote>
+<pre>
+&lt;chmod perm=&quot;g+w&quot;&gt;
+ &lt;fileset dir=&quot;shared/sources1&quot;&gt;
+ &lt;exclude name=&quot;**/trial/**&quot;/&gt;
+ &lt;/fileset&gt;
+ &lt;fileset refid=&quot;other.shared.sources&quot;/&gt;
+&lt;/chmod&gt;
+</pre>
+</blockquote>
+<p>makes all files below <code>shared/sources1</code> (except those
+below any directory named trial) writable for members of the same
+group on a UNIX system. In addition all files belonging to a FileSet
+with <code>id</code> <code>other.shared.sources</code> get the same
+permissions.</p>
+
+<blockquote>
+<pre>
+&lt;chmod perm=&quot;go-rwx&quot; type=&quot;file&quot;&gt;
+ &lt;fileset dir=&quot;/web&quot;&gt;
+ &lt;include name=&quot;**/*.cgi&quot;/&gt;
+ &lt;include name=&quot;**/*.old&quot;/&gt;
+ &lt;/fileset&gt;
+ &lt;dirset dir=&quot;/web&quot;&gt;
+ &lt;include name=&quot;**/private_*&quot;/&gt;
+ &lt;/dirset&gt;
+&lt;/chmod&gt;
+</pre>
+</blockquote>
+
+<p>keeps non-owners from touching cgi scripts, files with a <code>.old</code>
+extension or directories beginning with <code>private_</code>. A directory
+ending in <code>.old</code> or a file beginning with private_ would remain
+unaffected.</p>
+
+
+ <h3>Note on maxparallel attribute</h3>
+ <p>
+ Some shells have a limit of the number of characters that
+ a command line may contain.
+ This maximum limit varies from shell to shell and from operating
+ system to operating system.
+ If one has a large number of files to change mode on, consider
+ using the <em>maxparallel</em> attribute. For example
+ when using AIX and the limit is reached, the system responds
+ with a warning: "Warning:
+ UNIXProcess.forkAndExec native error: The parameter or environment lists
+ are too long". A value of about 300 seems to result in a
+ command line that is acceptable.
+ </p>
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/chown.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/chown.html
new file mode 100644
index 00000000..33a9f446
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/chown.html
@@ -0,0 +1,183 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Chown Task</title>
+</head>
+
+<body>
+
+<h2><a name="Chown">Chown</a></h2>
+<p><em>Since Apache Ant 1.6.</em></p>
+<h3>Description</h3>
+
+<p>Changes the owner of a file or all files inside specified
+directories. Right now it has effect only under Unix. The owner
+attribute is equivalent to the corresponding argument for the chown
+command.</p>
+
+<p><a href="../Types/fileset.html">FileSet</a>s,
+<a href="../Types/dirset.html">DirSet</a>s or <a
+href="../Types/filelist.html">FileList</a>s can be specified using
+nested <code>&lt;fileset&gt;</code>, <code>&lt;dirset&gt;</code> and
+<code>&lt;filelist&gt;</code> elements.</p>
+
+<p>Starting with Ant 1.7, this task supports arbitrary <a
+href="../Types/resources.html#collection">Resource Collection</a>s
+as nested elements.</p>
+
+<p>By default this task will use a single invocation of the underlying
+chown command. If you are working on a large number of files this may
+result in a command line that is too long for your operating system.
+If you encounter such problems, you should set the maxparallel
+attribute of this task to a non-zero value. The number to use highly
+depends on the length of your file names (the depth of your directory
+tree) and your operating system, so you'll have to experiment a
+little. POSIX recommends command line length limits of at least 4096
+characters, this may give you an approximation for the number you
+could use as initial value for these experiments.</p>
+
+<p>By default this task won't do anything unless it detects it is
+ running on a Unix system. If you know for sure that you have a
+ "chown" executable on your PATH that is command line compatible with
+ the Unix command, you can use the task's os attribute and set its
+ value to your current os.</p>
+
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">file</td>
+ <td valign="top">the file or directory of which the owner must be
+ changed.</td>
+ <td valign="top" valign="middle">Yes or nested
+ <code>&lt;fileset/list&gt;</code> elements.</td>
+ </tr>
+ <tr>
+ <td valign="top">owner</td>
+ <td valign="top">the new owner.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">parallel</td>
+ <td valign="top">process all specified files using a single
+ <code>chown</code> command. Defaults to true.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">type</td>
+ <td valign="top">One of <i>file</i>, <i>dir</i> or
+ <i>both</i>. If set to <i>file</i>, only the owner of
+ plain files are going to be changed. If set to <i>dir</i>, only
+ the directories are considered.<br>
+ <strong>Note:</strong> The type attribute does not apply to
+ nested <i>dirset</i>s - <i>dirset</i>s always implicitly
+ assume type to be <i>dir</i>.</td>
+ <td align="center" valign="top">No, default is <i>file</i></td>
+ </tr>
+ <tr>
+ <td valign="top">maxparallel</td>
+ <td valign="top">Limit the amount of parallelism by passing at
+ most this many sourcefiles at once. Set it to &lt;= 0 for
+ unlimited. Defaults to unlimited.</td>
+ <td align="center" valign="top">No</td>
+
+ </tr>
+ <tr>
+ <td valign="top">verbose</td>
+ <td valign="top">Whether to print a summary after execution or not.
+ Defaults to <code>false</code>.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">os</td>
+ <td valign="top">list of Operating Systems on which the command may be
+ executed.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">osfamily</td>
+ <td valign="top">OS family as used in
+ the <a href="../Tasks/conditions.html#os">&lt;os&gt;</a>
+ condition.</td>
+ <td align="center" valign="top">No - defaults to "unix"</td>
+ </tr>
+
+</table>
+<h3>Examples</h3>
+<blockquote><pre>
+&lt;chown file="${dist}/start.sh" owner="coderjoe"/&gt;
+</pre>
+</blockquote>
+<p>makes the "start.sh" file belong to coderjoe on a
+UNIX system.</p>
+<blockquote>
+<pre>
+ &lt;chown owner="coderjoe"&gt;
+ &lt;fileset dir="${dist}/bin" includes="**/*.sh"/&gt;
+ &lt;/chown&gt;
+</pre>
+</blockquote>
+<p>makes all ".sh" files below <code>${dist}/bin</code>
+belong to coderjoe on a UNIX system.</p>
+<blockquote>
+<pre>
+&lt;chown owner="coderjoe"&gt;
+ &lt;fileset dir="shared/sources1"&gt;
+ &lt;exclude name="**/trial/**"/&gt;
+ &lt;/fileset&gt;
+ &lt;fileset refid="other.shared.sources"/&gt;
+&lt;/chown&gt;
+</pre>
+</blockquote>
+<p>makes all files below <code>shared/sources1</code> (except those
+below any directory named trial) belong to coderjoe on a UNIX
+system. In addition all files belonging to a FileSet
+with <code>id</code> <code>other.shared.sources</code> get the same
+owner.</p>
+
+<blockquote>
+<pre>
+&lt;chown owner="webadmin" type="file"&gt;
+ &lt;fileset dir="/web"&gt;
+ &lt;include name="**/*.cgi"/&gt;
+ &lt;include name="**/*.old"/&gt;
+ &lt;/fileset&gt;
+ &lt;dirset dir="/web"&gt;
+ &lt;include name="**/private_*"/&gt;
+ &lt;/dirset&gt;
+&lt;/chmod&gt;
+</pre>
+</blockquote>
+
+<p>makes cgi scripts, files with a <code>.old</code> extension or
+directories beginning with <code>private_</code> belong to the user named
+webadmin. A directory ending in <code>.old</code> or a file beginning with
+<code>private_</code> would remain unaffected.</p>
+
+
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/clearcase.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/clearcase.html
new file mode 100644
index 00000000..902d5efe
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/clearcase.html
@@ -0,0 +1,958 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+ <meta http-equiv="Content-Language" content="en-us">
+ <link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+ <title>Clearcase Tasks</title>
+</head>
+
+<body>
+<h1>Apache Ant ClearCase Tasks</h1>
+<p>by:<br>
+Curtis White (cwhite at aracnet dot com),<br>
+Sean P. Kane (spkane at genomatica dot com),<br>
+Rob Anderson (Anderson.Rob at vectorscm dot com), and<br>
+Sean Egan (sean at cm-logic dot com)</p>
+
+<p>Version 1.6 - 02/25/2003</p>
+
+<h1>ClearCase Support</h1>
+<h2>Table of Contents</h2>
+<ul>
+ <li><A href="#introduction">Introduction</a>
+ <li><A href="#cccheckin">CCCheckin</a>
+ <li><A href="#cccheckout">CCCheckout</a>
+ <li><A href="#ccuncheckout">CCUnCheckout</a>
+ <li><A href="#ccupdate">CCUpdate</a>
+ <li><A href="#ccmklbtype">CCMklbtype</a>
+ <li><A href="#ccmklabel">CCMklabel</a>
+ <li><A href="#ccrmtype">CCRmtype</a>
+ <li><A href="#cclock">CCLock</a>
+ <li><A href="#ccunlock">CCUnlock</a>
+ <li><A href="#ccmkbl">CCMkbl</a>
+ <li><A href="#ccmkattr">CCMkattr</a>
+ <li><A href="#ccmkdir">CCMkdir</a>
+ <li><A href="#ccmkelem">CCMkelem</a></li>
+
+</ul>
+
+<hr>
+<h2><a name="introduction">Introduction</a></h2>
+<p>Apache Ant provides several optional tasks for working with ClearCase. These tasks correspond to various
+ClearCase commands using the Cleartool program. The current tasks available for Ant correspond to only
+a few of the significant ClearCase commands.</p>
+
+<p>More tasks can be easily added by deriving from the ClearCase class and then adding
+functionality that is specific to that ClearCase command.</p>
+<p>
+ Important: these tasks all require <code>cleartool</code> on the command line.
+ If a task fails with an IOException, especially error code 2 on Windows,
+ this is your problem.
+</p>
+
+
+<hr>
+<h2><a name="cccheckin">CCCheckin</a></h2>
+<h3>Description</h3>
+Task to perform a "cleartool checkin" command to ClearCase.
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <th>Attribute</th>
+ <th>Values</th>
+ <th>Required</th>
+ </tr>
+ <tr>
+ <td>viewpath</td>
+ <td>Path to the ClearCase view file or directory that the command
+ will operate on</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>comment</td>
+ <td>Specify a comment. Only one of comment or commentfile may be used.</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>commentfile</td>
+ <td>Specify a file containing a comment. Only one of comment or commentfile
+ may be used.</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>nowarn</td>
+ <td>Suppress warning messages</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>preservetime</td>
+ <td>Preserve the modification time</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>keepcopy</td>
+ <td>Keeps a copy of the file with a .keep extension</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>identical</td>
+ <td>Allows the file to be checked in even if it is identical
+ to the original</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>failonerr</td>
+ <td>Throw an exception if the command fails. Default is true</td>
+ <td>No</td>
+ </tr>
+</table>
+<h3>Examples</h3>
+<blockquote>
+<pre>
+&lt;cccheckin viewpath="c:/views/viewdir/afile"
+ commentfile="acomment.txt"
+ nowarn="true"
+ identical="true"/&gt;
+</pre>
+</blockquote>
+<p>Does a ClearCase <i>checkin</i> on the file <i>c:/views/viewdir/afile</i>.
+Comment text from the file <i>acomment.txt</i> is added to ClearCase as a comment.
+All warning messages are suppressed. The file is checked in even if it is
+<i>identical</i> to the original.</p>
+<hr>
+<h2><a name="cccheckout">CCCheckout</a></h2>
+<h3>Description</h3>
+Task to perform a "cleartool checkout" command to ClearCase.
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <th>Attribute</th>
+ <th>Values</th>
+ <th>Required</th>
+ </tr>
+ <tr>
+ <td>viewpath</td>
+ <td>Path to the ClearCase view file or directory that the command
+ will operate on</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>reserved</td>
+ <td>Specifies whether to check out the file as reserved or not</td>
+ <td>Yes</td>
+ </tr>
+ <tr>
+ <td>out</td>
+ <td>Creates a writable file under a different filename</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>nodata</td>
+ <td>Checks out the file but does not create an editable file
+ containing its data</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>branch</td>
+ <td>Specify a branch to check out the file to</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>version</td>
+ <td>Allows checkout of a version other than main latest</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>nowarn</td>
+ <td>Suppress warning messages</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>comment</td>
+ <td>Specify a comment. Only one of comment or commentfile may be used.</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>commentfile</td>
+ <td>Specify a file containing a comment. Only one of comment or
+ commentfile may be used.</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>notco</td>
+ <td>Fail if it's already checked out to the current view. Set to false to ignore it.<br>
+ Since ant 1.6.1</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>failonerr</td>
+ <td>Throw an exception if the command fails. Default is true.<br>
+ Since ant 1.6.1</td>
+ <td>No</td>
+ </tr>
+</table>
+<h3>Examples</h3>
+<blockquote>
+<pre>
+&lt;cccheckout viewpath="c:/views/viewdir/afile"
+ reserved="true"
+ branch="abranch"
+ nowarn="true"
+ comment="Some comment text"/&gt;
+</pre>
+</blockquote>
+<p>Does a ClearCase <i>checkout</i> on the file <i>c:/views/viewdir/afile</i>.
+It is checked out as <i>reserved</i> on branch called <i>abranch</i>. All
+warning messages are suppressed. A <i>Some comment text</i> is added to
+ClearCase as a comment.</p>
+<hr>
+<h2><a name="ccuncheckout">CCUnCheckout</a></h2>
+<h3>Description</h3>
+Task to perform a UnCheckout command to ClearCase.
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <th>Attribute</th>
+ <th>Values</th>
+ <th>Required</th>
+ </tr>
+ <tr>
+ <td>viewpath</td>
+ <td>Path to the ClearCase view file or directory that the command
+ will operate on</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>keepcopy</td>
+ <td>Specifies whether to keep a copy of the file with a .keep
+ extension or not</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>failonerr</td>
+ <td>Throw an exception if the command fails. Default is true<br>
+ Since ant 1.6.1</td>
+ <td>No</td>
+ </tr>
+</table>
+<h3>Examples</h3>
+<blockquote>
+<pre>
+&lt;ccuncheckout viewpath="c:/views/viewdir/afile"
+ keepcopy="true"/&gt;
+</pre>
+</blockquote>
+<p>Does a ClearCase <i>uncheckout</i> on the file <i>c:/views/viewdir/afile</i>.
+A copy of the file called <i>c:/views/viewdir/afile.keep</i> is kept.</p>
+<hr>
+<h2><a name="ccupdate">CCUpdate</a></h2>
+<h3>Description</h3>
+Task to perform an "cleartool update" command to ClearCase.
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <th>Attribute</th>
+ <th>Values</th>
+ <th>Required</th>
+ </tr>
+ <tr>
+ <td>viewpath</td>
+ <td>Path to the ClearCase snapshot view file or directory that the command
+ will operate on</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>graphical</td>
+ <td>Displays a graphical dialog during the update</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>log</td>
+ <td>Specifies a log file for ClearCase to write to</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>overwrite</td>
+ <td>Specifies whether to overwrite hijacked files or not</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>rename</td>
+ <td>Specifies that hijacked files should be renamed with a .keep extension</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>currenttime</td>
+ <td>Specifies that modification time should be written as the
+ current time. Either currenttime or preservetime can be
+ specified.</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>preservetime</td>
+ <td>Specifies that modification time should preserved from the
+ VOB time. Either currenttime or preservetime can be
+ specified.</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>failonerr</td>
+ <td>Throw an exception if the command fails. Default is true.<br>
+ Since ant 1.6.1</td>
+ <td>No</td>
+ </tr>
+</table>
+<h3>Examples</h3>
+<blockquote>
+<pre>
+&lt;ccupdate viewpath="c:/views/viewdir"
+ graphical="false"
+ log="log.log"
+ overwrite="true"
+ currenttime="true"
+ rename="false"/&gt;
+</pre>
+</blockquote>
+<p>Does a ClearCase <i>update</i> on the snapshot view directory <i>c:/views/viewdir</i>.
+A graphical dialog will be displayed. The output will be logged to
+<i>log.log</i> and it will overwrite any hijacked files. The modified
+time will be set to the current time.</p>
+
+
+
+<hr>
+<h2><a name="ccmklbtype">CCMklbtype</a></h2>
+<h3>Description</h3>
+Task to perform a "mklbtype" command to ClearCase.
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <th>Attribute</th>
+ <th>Values</th>
+ <th>Required</th>
+ </tr>
+ <tr>
+ <td>typename</td>
+ <td>Name of the label type to create</td>
+ <td>Yes</td>
+ <tr>
+ <tr>
+ <td>vob</td>
+ <td>Name of the VOB</td>
+ <td>No</td>
+ <tr>
+ <tr>
+ <td>replace</td>
+ <td>Replace an existing label definition of the same type</td>
+ <td>No</td>
+ <tr>
+ <tr>
+ <td>global</td>
+ <td>Either global or ordinary can be specified, not both. Creates a label type that is global to the VOB or to VOBs that use this VOB</td>
+ <td>No</td>
+ <tr>
+ <tr>
+ <td>ordinary</td>
+ <td>Either global or ordinary can be specified, not both. Creates a label type that can be used only in the current VOB. <B>Default</B></td>
+ <td>No</td>
+ <tr>
+ <tr>
+ <td>pbranch</td>
+ <td>Allows the label type to be used once per branch in a given element's version tree</td>
+ <td>No</td>
+ <tr>
+ <tr>
+ <td>shared</td>
+ <td>Sets the way mastership is checked by ClearCase. See ClearCase documentation for details</td>
+ <td>No</td>
+ <tr>
+ <tr>
+ <td>comment</td>
+ <td>Specify a comment. Only one of comment or cfile may be used.</td>
+ <td>No</td>
+ <tr>
+ <tr>
+ <td>commentfile</td>
+ <td>Specify a file containing a comment. Only one of comment or cfile may be used.</td>
+ <td>No</td>
+ <tr></tr>
+ <tr>
+ <td>failonerr</td>
+ <td>Throw an exception if the command fails. Default is true<br>
+ Since ant 1.6.1</td>
+ <td>No</td>
+ </tr>
+</table>
+
+<h3>Examples</h3>
+<blockquote>
+<pre>
+&lt;ccmklbtype typename="VERSION_1"
+ ordinary="true"
+ comment="Development version 1"/&gt;
+</pre>
+</blockquote>
+<p>Does a ClearCase <i>mklbtype</i> to create a label type named <i>VERSION_1</i>.
+It is created as <i>ordinary</i> so it is available only to the current VOB.
+The text <i>Development version 1</i> is added as a comment.</p>
+
+
+<hr>
+<h2><a name="ccmklabel">CCMklabel</a></h2>
+<h3>Description</h3>
+Task to perform a "mklabel" command to ClearCase.
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <th>Attribute</th>
+ <th>Values</th>
+ <th>Required</th>
+ </tr>
+ <tr>
+ <td>typename</td>
+ <td>Name of the label type</td>
+ <td>Yes</td>
+ <tr>
+ <tr>
+ <td>viewpath</td>
+ <td>Path to the ClearCase view file or directory that the command will operate on</td>
+ <td>No</td>
+ <tr>
+ <tr>
+ <td>replace</td>
+ <td>Replace a label of the same type on the same branch</td>
+ <td>No</td>
+ <tr>
+ <tr>
+ <td>recurse</td>
+ <td>Process each subdirectory under viewpath</td>
+ <td>No</td>
+ <tr>
+ <tr>
+ <td>version</td>
+ <td>Identify a specific version to attach the label to</td>
+ <td>No</td>
+ <tr>
+ <tr>
+ <td>vob</td>
+ <td>Name of the VOB</td>
+ <td>No</td>
+ <tr>
+ <tr>
+ <td>comment</td>
+ <td>Specify a comment. Only one of comment or cfile may be used.</td>
+ <td>No</td>
+ <tr>
+ <tr>
+ <td>commentfile</td>
+ <td>Specify a file containing a comment. Only one of comment or cfile may be used.</td>
+ <td>No</td>
+ <tr></tr>
+ <tr>
+ <td>failonerr</td>
+ <td>Throw an exception if the command fails. Default is true<br>
+ Since ant 1.6.1</td>
+ <td>No</td>
+ </tr>
+</table>
+
+<h3>Examples</h3>
+<blockquote>
+<pre>
+&lt;ccmklabel viewpath="c:/views/viewdir/afile"
+ comment="Some comment text"
+ recurse="true"
+ version="\main\2"
+ typename="VERSION_1"/&gt;
+</pre>
+</blockquote>
+<p>Does a ClearCase <i>mklabel</i> on the file <i>c:/views/viewdir/afile</i> under
+the main branch for version 2 (<i>\main\2</i>). Text <i>Some comment text</i> is added
+as a comment. It will <i>recurse</i> all subdirectories.
+
+
+<hr>
+<h2><a name="ccrmtype">CCRmtype</a></h2>
+<h3>Description</h3>
+Task to perform a "rmtype" command to ClearCase.
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <th>Attribute</th>
+ <th>Values</th>
+ <th>Required</th>
+ </tr>
+ <tr>
+ <td>typekind</td>
+ <td>The kind of type to create. Valid types are:
+ <table border="0" width="40%">
+ <tr>
+ <td width="15%"> </td>
+ <td><b>attype</b><br>
+ <b>brtype</b><br>
+ <b>eltype</b><br>
+ <b>hltype</b><br>
+ <b>lbtype</b><br>
+ <b>trtype</b>
+ </td>
+ <td>- <br>
+ - <br>
+ - <br>
+ - <br>
+ - <br>
+ -
+ </td>
+ <td>attribute type<br>
+ branch type<br>
+ element type<br>
+ hyperlink type<br>
+ label type<br>
+ trigger type
+ </td>
+ </tr>
+ </table>
+ </td>
+ <td>Yes</td>
+ <tr>
+ <tr>
+ <td>typename</td>
+ <td>The name of the type to remove</td>
+ <td>Yes</td>
+ <tr>
+ <tr>
+ <td>ignore</td>
+ <td>Used with trigger types only. Forces removal of trigger type even if a pre-operation trigger would prevent its removal</td>
+ <td>No</td>
+ <tr>
+ <tr>
+ <td>rmall</td>
+ <td>Removes all instances of a type and the type object itself</td>
+ <td>No</td>
+ <tr>
+ <tr>
+ <td>comment</td>
+ <td>Specify a comment. Only one of comment or cfile may be used.</td>
+ <td>No</td>
+ <tr>
+ <tr>
+ <td>commentfile</td>
+ <td>Specify a file containing a comment. Only one of comment or cfile may be used.</td>
+ <td>No</td>
+ <tr></tr>
+ <tr>
+ <td>failonerr</td>
+ <td>Throw an exception if the command fails. Default is true
+ Since ant 1.6.1</td>
+ <td>No</td>
+ </tr>
+</table>
+
+<h3>Examples</h3>
+<blockquote>
+<pre>
+&lt;ccrmtype typekind="lbtype"
+ typename="VERSION_1"
+ commentfile="acomment.txt"
+ rmall="true"/&gt;
+</pre>
+</blockquote>
+<p>Does a ClearCase <i>rmtype</i> to remove a label type (<i>lbtype</i>) named <i>VERSION_1</i>.
+Comment text from the file <i>acomment.txt</i> is added as a comment. All instances of the type
+are removed, including the type object itself.</p>
+<hr>
+
+<h2><a name="cclock">CCLock</a></h2>
+<h3>Description</h3>
+Task to perform a "cleartool lock" command to ClearCase.
+<h3>Parameters</h3>
+ <table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <th>Attribute</th>
+ <th>Values</th>
+ <th>Required</th>
+ </tr>
+ <tr>
+ <td>replace</td>
+ <td>Specifies replacing an existing lock</td>
+ <td>No</td>
+ <tr>
+ <tr>
+ <td>nusers</td>
+ <td>Specifies user(s) who can still modify the object</td>
+ <td>No</td>
+ <tr>
+ <tr>
+ <td>obsolete</td>
+ <td>Specifies that the object should be marked obsolete</td>
+ <td>No</td>
+ <tr>
+ <tr>
+ <td>comment</td>
+ <td>Specifies how to populate comments fields</td>
+ <td>No</td>
+ <tr>
+ <tr>
+ <td>pname</td>
+ <td>Specifies the object pathname to be locked.</td>
+ <td>No</td>
+ <tr>
+ <td>objselect</td>
+ <td>This variable is obsolete. Should use <i>objsel</i> instead.</td>
+ <td>No</td>
+ <tr>
+ <tr>
+ <td>objsel</td>
+ <td>Specifies the object(s) to be locked.<br>
+ Since ant 1.6.1</td>
+ <td>No</td>
+ <tr>
+ <tr>
+ <td>failonerr</td>
+ <td>Throw an exception if the command fails. Default is true.<br>
+ Since ant 1.6.1</td>
+ <td>No</td>
+ </tr>
+
+ </table>
+<h3>Examples</h3>
+<blockquote>
+<pre>
+&lt;cclock
+ objsel="stream:Application_Integration@\MyProject_PVOB"
+ /&gt;
+</pre>
+</blockquote>
+<p>Does a ClearCase <i>lock</i> on the object <i>stream:Application_Integration@\MyProject_PVOB</i>.</p>
+<hr>
+
+<h2><a name="ccunlock">CCUnlock</a></h2>
+<h3>Description</h3>
+Task to perform a "cleartool unlock" command to ClearCase.
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <th>Attribute</th>
+ <th>Values</th>
+ <th>Required</th>
+ </tr>
+ <tr>
+ <td>comment</td>
+ <td>Specifies how to populate comments fields</td>
+ <td>No</td>
+ <tr>
+ <tr>
+ <td>pname</td>
+ <td>Specifies the object pathname to be unlocked.</td>
+ <td>No</td>
+ <tr>
+ <td>objselect</td>
+ <td>This variable is obsolete. Should use <i>objsel</i> instead.</td>
+ <td>No</td>
+ <tr>
+ <tr>
+ <td>objsel</td>
+ <td>Specifies the object(s) to be unlocked.<br>
+ Since ant 1.6.1</td>
+ <td>No</td>
+ <tr>
+ <tr>
+ <td>failonerr</td>
+ <td>Throw an exception if the command fails. Default is true.<br>
+ Since ant 1.6.1</td>
+ <td>No</td>
+ </tr>
+
+ </table>
+ <h3>Examples</h3>
+<blockquote>
+<pre>
+&lt;ccunlock
+ objsel="stream:Application_Integration@\MyProject_PVOB"
+ /&gt;
+</pre>
+</blockquote>
+<p>Does a ClearCase <i>unlock</i> on the object <i>stream:Application_Integration@\MyProject_PVOB</i>.</p>
+<hr>
+
+<h2><a name="ccmkbl">CCMkbl</a></h2>
+<h3>Description</h3>
+Task to perform a "cleartool mkbl" command to ClearCase.
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <th>Attribute</th>
+ <th>Values</th>
+ <th>Required</th>
+ </tr>
+ <tr>
+ <td>comment</td>
+ <td>Specify a comment. Only one of comment or cfile may be
+used.</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>commentfile</td>
+ <td>Specify a file containing a comment. Only one of comment or
+cfile may be used.</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>baselinerootname</td>
+ <td>Specify the name to be associated with the baseline.</td>
+ <td>Yes</td>
+ </tr>
+ <tr>
+ <td>nowarn</td>
+ <td>Suppress warning messages</td>
+ <td>No</td>
+ <tr>
+ <tr>
+ <td>identical</td>
+ <td>Allows the baseline to be created even if it is identical to the
+previous baseline.</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>full</td>
+ <td>Creates a full baseline.</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>nlabel</td>
+ <td>Allows the baseline to be created without a label.</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>failonerr</td>
+ <td>Throw an exception if the command fails. Default is true.<br>
+ Since ant 1.6.1</td>
+ <td>No</td>
+ </tr>
+ </table>
+<h3>Examples</h3>
+<blockquote>
+<pre>
+&lt;ccmkbl
+ baselinerootname="Application_Baseline_AUTO"
+ identical="yes"
+ full="no"
+ viewpath="v:\ApplicationCC"
+ /&gt;
+</pre>
+</blockquote>
+<p>Does a ClearCase <i>mkbl</i> on the Integration view at <i>v:\ApplicationCC</i>
+even if it is <i>identical</i> to a previous baseline. The new baseline with be
+incremental and named "Application_Baseline_AUTO".</p>
+<hr>
+
+<h2><a name="ccmkattr">CCMkattr</a></h2>
+<h3>Description</h3>
+Task to perform a &quot;cleartool mkattr&quot; command to ClearCase.<br>
+Since ant 1.6.1
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <th>Attribute</th>
+ <th>Values</th>
+ <th>Required</th>
+ </tr>
+ <tr>
+ <td>viewpath</td>
+ <td>Path to the ClearCase view file or directory that the command will operate on</td>
+ <td>Yes</td>
+ </tr>
+ <tr>
+ <td>replace</td>
+ <td>Replace the value of the attribute if it already exists</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>recurse</td>
+ <td>Process each subdirectory under viewpath</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>version</td>
+ <td>Identify a specific version to attach the attribute to</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>typename</td>
+ <td>Name of the attribute type</td>
+ <td>Yes</td>
+ </tr>
+ <tr>
+ <td>typevalue</td>
+ <td>Value to attach to the attribute type</td>
+ <td>Yes</td>
+ </tr>
+ <tr>
+ <td>comment</td>
+ <td>Specify a comment. Only one of comment or cfile may be used.</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>commentfile</td>
+ <td>Specify a file containing a comment. Only one of comment or cfile may be used.</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>failonerr</td>
+ <td>Throw an exception if the command fails. Default is true</td>
+ <td>No</td>
+ </tr>
+ </table>
+<h3>Examples</h3>
+<blockquote>
+<pre>
+&lt;ccmkattr viewpath=&quot;c:/views/viewdir/afile&quot;
+ typename=&quot;BugFix&quot;
+ typevalue=&quot;34445&quot;
+ /&gt;
+</pre>
+</blockquote>
+<p>Does a ClearCase <i>mkattr</i> on the file <i>c:/views/viewdir/afile</i> and
+attaches the attribute <i>BugFix</i> with a value of <i>34445</i> to it.</p>
+<hr>
+
+<h2><a name="ccmkdir">CCMkdir</a></h2>
+<h3>Description</h3>
+Task to perform a &quot;cleartool mkdir&quot; command to ClearCase.<br>
+Since ant 1.6.1
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <th>Attribute</th>
+ <th>Values</th>
+ <th>Required</th>
+ </tr>
+ <tr>
+ <td>viewpath</td>
+ <td>Path to the ClearCase view directory that the command will operate on</td>
+ <td>Yes</td>
+ </tr>
+ <tr>
+ <td>comment</td>
+ <td>Specify a comment. Only one of comment or cfile may be used.</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>commentfile</td>
+ <td>Specify a file containing a comment. Only one of comment or cfile may be used.</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>nocheckout</td>
+ <td>Do not checkout after element creation</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>failonerr</td>
+ <td>Throw an exception if the command fails. Default is true</td>
+ <td>No</td>
+ </tr>
+ </table>
+<h3>Examples</h3>
+<blockquote>
+<pre>
+&lt;ccmkdir viewpath=&quot;c:/views/viewdir/adir&quot;
+ nocheckout=&quot;true&quot;
+ comment=&quot;Some comment text&quot;/&gt;
+</pre>
+</blockquote>
+<p>Does a ClearCase <i>mkdir</i> on the dir <i>c:/views/viewdir/adir</i> and
+does not automatically check it out.</p>
+<hr>
+
+<h2><a name="ccmkelem">CCMkelem</a></h2>
+<h3>Description</h3>
+Task to perform a &quot;cleartool mkelem&quot; command to ClearCase.<br>
+Since ant 1.6.1
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <th>Attribute</th>
+ <th>Values</th>
+ <th>Required</th>
+ </tr>
+ <tr>
+ <td>viewpath</td>
+ <td>Path to the ClearCase view file or directory that the command will operate on</td>
+ <td>Yes</td>
+ <tr>
+ <tr>
+ <td>comment</td>
+ <td>Specify a comment. Only one of comment or cfile may be used.</td>
+ <td>No</td>
+ <tr>
+ <tr>
+ <td>commentfile</td>
+ <td>Specify a file containing a comment. Only one of comment or cfile may be used.</td>
+ <td>No</td>
+ <tr>
+ <tr>
+ <td>nowarn</td>
+ <td>Suppress warning messages</td>
+ <td>No</td>
+ <tr>
+ <tr>
+ <td>nocheckout</td>
+ <td>Do not checkout after element creation</td>
+ <td>No</td>
+ <tr>
+ <tr>
+ <td>checkin</td>
+ <td>Checkin element after creation</td>
+ <td>No</td>
+ <tr>
+ <tr>
+ <td>preservetime</td>
+ <td>Preserve the modification time (for checkin)</td>
+ <td>No</td>
+ <tr>
+ <tr>
+ <td>master</td>
+ <td>Assign mastership of the main branch to the current site</td>
+ <td>No</td>
+ <tr>
+ <tr>
+ <td>eltype</td>
+ <td>Element type to use during element creation</td>
+ <td>No</td>
+ <tr>
+ <tr>
+ <td>failonerr</td>
+ <td>Throw an exception if the command fails. Default is true</td>
+ <td>No</td>
+ <tr>
+ </table>
+<h3>Examples</h3>
+<blockquote>
+<pre>
+&lt;ccmkelem viewpath=&quot;c:/views/viewdir/afile&quot;
+ eltype=&quot;text_file&quot;
+ checkin=&quot;true&quot;
+ comment=&quot;Some comment text&quot;/&gt;
+</pre>
+</blockquote>
+<p>Does a ClearCase <i>mkelem</i> on the file <i>c:/views/viewdir/afile</i> with
+element type <i>text_file</i>. It also checks in the file after creation.</p>
+
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/common.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/common.html
new file mode 100644
index 00000000..6fa3418e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/common.html
@@ -0,0 +1,59 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Common</title>
+</head>
+
+<body>
+
+<h2><a name="javac">Common Attributes of all Tasks</a></h2>
+<p>All tasks share the following attributes:</p>
+
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">id</td>
+ <td valign="top">Unique identifier for this task instance, can be
+ used to reference this task in scripts.</td>
+ <td valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">taskname</td>
+ <td valign="top">A different name for this task instance - will
+ show up in the logging output.</td>
+ <td valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">description</td>
+ <td valign="top">Room for your comments</td>
+ <td valign="top">No</td>
+ </tr>
+</table>
+
+
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/componentdef.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/componentdef.html
new file mode 100644
index 00000000..e28e6813
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/componentdef.html
@@ -0,0 +1,62 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Componentdef Task</title>
+</head>
+
+<body>
+
+<h2><a name="componentdef">componentdef</a></h2>
+<h3>Description</h3>
+ <p>
+ Adds a component definition to the current project.
+ A component definition is the same as a
+ <a href="typedef.html">typedef</a> except:
+ </p>
+ <ol>
+ <li>
+ that it can only be used in other types or tasks that
+ accept components (by having an <i>add()</i> method).
+ </li>
+ <li>
+ multiple components may have the same name, provided they
+ implement different interfaces.
+ </li>
+ </ol>
+ <p>
+ The purpose of this is to allow internal Apache Ant definitions to be
+ made for tags like "and" or "or".
+ </p>
+
+ <h3>Examples</h3>
+
+<pre> &lt;componentdef name="or" onerror="ignore"
+ classname="com.apache.tools.ant.taskdefs.conditions.Or"/&gt;
+ &lt;componentdef name="or" onerror="ignore"
+ classname="com.apache.tools.ant.types.resources.selectors.Or"/&gt;</pre>
+ <p>
+ defines two components with the same name "or"; one is a condition
+ (see <a href="conditions.html">conditions</a>) and one is
+ a selector (see <a href="../Types/selectors.html">selectors</a>).
+ </p>
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/concat.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/concat.html
new file mode 100644
index 00000000..11372d07
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/concat.html
@@ -0,0 +1,337 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+ <head>
+ <meta http-equiv="Content-Language" content="en-us">
+ <link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Concat</title>
+ </head>
+
+ <body>
+
+ <h2><a name="Concat">Concat</a></h2>
+
+ <h3>Description</h3>
+
+ <p>
+ Concatenates one or more
+ <a href="../Types/resources.html">resource</a>s
+ to a single file or to the console. The destination
+ file will be created if it does not exist unless the resource
+ list is empty and ignoreempty is true.
+ </p>
+
+ <p><strong>Since Apache Ant 1.7.1</strong>, this task can be used as a
+ <a href="../Types/resources.html#collection">Resource Collection</a>
+ that will return exactly one
+ <a href="../Types/resources.html">resource</a>.
+ </p>
+
+ <p>
+ <a href="../Types/resources.html#collection">
+Resource Collection</a>s are used to
+ select which resources are to be concatenated. There is no
+ singular attribute to specify a single resource to cat.
+ </p>
+
+ <h3>Parameters</h3>
+
+ <table border="1" cellpadding="2" cellspacing="0">
+
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+
+ <tr>
+ <td valign="top">destfile</td>
+ <td valign="top">
+ The destination file for the concatenated stream.
+ If not specified the console will be used instead.
+ </td>
+ <td valign="top" align="center">
+ No
+ </td>
+ </tr>
+
+ <tr>
+ <td valign="top">append</td>
+ <td valign="top">
+ Specifies whether or not the file specified by 'destfile'
+ should be appended. Defaults to &quot;no&quot;.
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">force</td>
+ <td valign="top">
+ Specifies whether or not the file specified by 'destfile'
+ should be written to even if it is newer than all source files.
+ <strong>deprecated, use the overwrite attribute instead</strong>
+ Defaults to &quot;yes&quot;.
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">overwrite</td>
+ <td valign="top">
+ Specifies whether or not the file specified by 'destfile'
+ should be written to even if it is newer than all source files.
+ <em>since Ant 1.8.2</em>.
+ Defaults to &quot;yes&quot;.
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+
+ <tr>
+ <td valign="top">forceReadOnly</td>
+ <td valign="top">Overwrite read-only destination
+ files. <em>since Ant 1.8.2</em></td>
+ <td valign="top" align="center">No; defaults to false.</td>
+ </tr>
+
+ <tr>
+ <td valign="top">encoding</td>
+ <td valign="top">
+ Specifies the encoding for the input files. Please see <a
+ href="http://docs.oracle.com/javase/7/docs/technotes/guides/intl/encoding.doc.html">
+ Supported Encodings</a>
+ for a list of possible values. Defaults to the platform's
+ default character encoding.
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">outputencoding</td>
+ <td valign="top">
+ The encoding to use when writing the output file
+ <em>since Ant 1.6</em>.
+ Defaults to the value of the encoding attribute
+ if given or the default JVM encoding otherwise.
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">fixlastline</td>
+ <td valign="top">
+ Specifies whether or not to check if
+ each file concatenated is terminated by
+ a new line. If this attribute is &quot;yes&quot;
+ a new line will be appended to the stream if
+ the file did not end in a new line.
+ <em>since Ant 1.6</em>.
+ Defaults to &quot;no&quot;.
+ This attribute does not apply to embedded text.
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">eol</td>
+ <td valign="top">
+ Specifies what the end of line character are
+ for use by the fixlastline attribute.
+ <em>since Ant 1.6</em>
+ Valid values for this property are:
+ <ul>
+ <li>cr: a single CR</li>
+ <li>lf: a single LF</li>
+ <li>crlf: the pair CRLF</li>
+ <li>mac: a single CR</li>
+ <li>unix: a single LF</li>
+ <li>dos: the pair CRLF</li>
+ </ul>
+ The default is platform dependent.
+ For Unix platforms, the default is &quot;lf&quot;.
+ For DOS based systems (including Windows),
+ the default is &quot;crlf&quot;.
+ For Mac OS, the default is &quot;cr&quot;.
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">binary</td>
+ <td valign="top">
+ <em>since Ant 1.6.2</em>
+ If this attribute is set to true, the task concatenates the files
+ in a byte by byte fashion. If this attribute is false, concat will
+ not normally work for binary files due to character encoding
+ issues.
+ If this option is set to true, the destfile attribute must be
+ set, and the task cannot used nested text.
+ Also the attributes encoding, outputencoding, filelastline
+ cannot be used.
+ The default is &quot;false&quot;.
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">ignoreempty</td>
+ <td valign="top">
+ <em>Since Ant 1.8.0</em>
+ Specifies whether or not the file specified by 'destfile'
+ should be created if the source resource list is
+ empty. Defaults to &quot;true&quot;.
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">resourcename</td>
+ <td valign="top">
+ <em>Since Ant 1.8.3</em>
+ Specifies the name reported if this task is exposed
+ as a <a href="../Types/resources.html">resource</a>.
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+
+ </table>
+
+ <h3>Parameters specified as nested elements</h3>
+ <h4>Resource Collection</h4>
+ <p><em>since Ant 1.7</em>.</p>
+
+ <p>
+ Any of the various <a href="../Types/resources.html#collection">
+ Resource Collection</a> types can specify the resources to be
+ concatenated.
+ </p>
+
+ <h4>filterchain</h4>
+ <p><em>since Ant 1.6</em>.</p>
+ <p>The concat task supports nested
+ <a href="../Types/filterchain.html"> FilterChain</a>s.</p>
+
+ <h4>header, footer</h4>
+ <p><em>since Ant 1.6</em>.</p>
+ <p>Used to prepend or postpend text into the concatenated stream.</p>
+ <p>The text may be in-line or be in a file.</p>
+ <table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">filtering</td>
+ <td valign="top">
+ Whether to filter the text provided by this sub element,
+ default is "yes".
+ <td valign="top" align = "center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">file</td>
+ <td valign="top">A file to place at the head or tail of the
+ concatenated text.
+ <td valign="top" align = "center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">trim</td>
+ <td valign="top">Whether to trim the value, default is "no"</td>
+ <td valign="top" align = "center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">trimleading</td>
+ <td valign="top">
+ Whether to trim leading white space on each line, default is "no"
+ </td>
+ <td valign="top" align = "center">No</td>
+ </tr>
+ </table>
+
+ <h3>Examples</h3>
+
+ <p><b>Concatenate a string to a file:</b></p>
+
+ <pre>
+ &lt;concat destfile=&quot;README&quot;&gt;Hello, World!&lt;/concat&gt;
+ </pre>
+
+ <p><b>Concatenate a series of files to the console:</b></p>
+
+ <pre>
+ &lt;concat&gt;
+ &lt;fileset dir=&quot;messages&quot; includes=&quot;*important*&quot;/&gt;
+ &lt;/concat&gt;
+ </pre>
+
+ <p><b>Concatenate a single file, appending if the destination file exists:</b></p>
+
+ <pre>
+ &lt;concat destfile=&quot;NOTES&quot; append=&quot;true&quot;&gt;
+ &lt;filelist dir=&quot;notes&quot; files=&quot;note.txt&quot;/&gt;
+ &lt;/concat&gt;
+ </pre>
+
+ <p><b>Concatenate a series of files, update the destination
+ file only if is older that all the source files:</b></p>
+
+ <pre>
+ &lt;concat destfile=&quot;${docbook.dir}/all-sections.xml&quot;
+ force=&quot;no&quot;&gt;
+ &lt;filelist dir=&quot;${docbook.dir}/sections&quot;
+ files=&quot;introduction.xml,overview.xml&quot;/&gt;
+ &lt;fileset dir=&quot;${docbook.dir}&quot;
+ includes=&quot;sections/*.xml&quot;
+ excludes=&quot;introduction.xml,overview.xml&quot;/&gt;
+ &lt;/concat&gt;
+ </pre>
+
+ <p><b>Concatenate a series of files, expanding ant properties</b></p>
+ <pre>
+ &lt;concat destfile="${build.dir}/subs"&gt;
+ &lt;path&gt;
+ &lt;fileset dir="${src.dir}" includes="*.xml"/&gt;
+ &lt;pathelement location="build.xml"/&gt;
+ &lt;/path&gt;
+ &lt;filterchain&gt;
+ &lt;expandproperties/&gt;
+ &lt;/filterchain&gt;
+ &lt;/concat&gt;
+ </pre>
+
+ <p><b>Filter the lines containing project from build.xml and output
+ them to report.output, prepending with a header</b></p>
+ <pre>
+ &lt;concat destfile="${build.dir}/report.output"&gt;
+ &lt;header filtering="no" trimleading="yes"&gt;
+ Lines that contain project
+ ==========================
+ &lt;/header&gt;
+ &lt;path path="build.xml"/&gt;
+ &lt;filterchain&gt;
+ &lt;linecontains&gt;
+ &lt;contains value="project"/&gt;
+ &lt;/linecontains&gt;
+ &lt;/filterchain&gt;
+ &lt;/concat&gt;
+ </pre>
+
+ <p><b>Concatenate a number of binary files.</b></p>
+ <pre>
+ &lt;concat destfile="${build.dir}/dist.bin" binary="yes"&gt;
+ &lt;fileset file="${src.dir}/scripts/dist.sh" /&gt;
+ &lt;fileset file="${build.dir}/dist.tar.bz2" /&gt;
+ &lt;/concat&gt;
+ </pre>
+
+
+
+ </body>
+
+ </html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/condition.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/condition.html
new file mode 100644
index 00000000..405f95e7
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/condition.html
@@ -0,0 +1,110 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Condition Task</title>
+</head>
+
+<body>
+
+<h2><a name="Condition">Condition</a></h2>
+<h3>Description</h3>
+<p>Sets a property if a certain condition holds true - this is a
+generalization of <a href="available.html">Available</a> and <a
+href="uptodate.html">Uptodate</a>.</p>
+<p>If the condition holds true, the property value is set to true by
+default; otherwise, the property is not set. You can set the value to
+something other than the default by specifying the <code>value</code>
+attribute.</p>
+<p>Conditions are specified as <a href="#nested">nested elements</a>,
+you must specify exactly one condition.</p>
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">property</td>
+ <td valign="top">The name of the property to set.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">value</td>
+ <td valign="top">The value to set the property to. Defaults to
+ &quot;true&quot;.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">else</td>
+ <td valign="top">The value to set the property to if the condition
+ evaluates to <i>false</i>. By default the property will remain unset.
+ <em>Since Apache Ant 1.6.3</em>
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+</table>
+<h3><a name="nested">Parameters specified as nested elements</a></h3>
+<p>All conditions to test are specified as nested elements, for a
+complete list see <a href="conditions.html">here</a>.</p>
+
+<h3>Examples</h3>
+<pre>
+ &lt;condition property=&quot;javamail.complete&quot;&gt;
+ &lt;and&gt;
+ &lt;available classname=&quot;javax.activation.DataHandler&quot;/&gt;
+ &lt;available classname=&quot;javax.mail.Transport&quot;/&gt;
+ &lt;/and&gt;
+ &lt;/condition&gt;
+</pre>
+<p>sets the property <code>javamail.complete</code> if both the
+JavaBeans Activation Framework and JavaMail are available in the
+classpath.</p>
+
+<pre>
+ &lt;condition property=&quot;isMacOsButNotMacOsX&quot;&gt;
+ &lt;and&gt;
+ &lt;os family=&quot;mac&quot;/&gt;
+
+ &lt;not&gt;
+ &lt;os family=&quot;unix&quot;/&gt;
+
+ &lt;/not&gt;
+ &lt;/and&gt;
+ &lt;/condition&gt;
+</pre>
+<p>sets the property <code>isMacOsButNotMacOsX</code> if the current
+operating system is MacOS, but not MacOS X - which Ant considers to be
+in the Unix family as well.</p>
+
+<pre>
+ &lt;condition property=&quot;isSunOSonSparc&quot;&gt;
+ &lt;os name=&quot;SunOS&quot; arch=&quot;sparc&quot;/&gt;
+
+ &lt;/condition&gt;
+</pre>
+<p>sets the property <code>isSunOSonSparc</code> if the current
+operating system is SunOS and if it is running on a sparc architecture.</p>
+
+
+
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/conditions.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/conditions.html
new file mode 100644
index 00000000..814072ec
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/conditions.html
@@ -0,0 +1,1087 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Conditions Task</title>
+</head>
+
+<body>
+
+<h2><a name="Conditions">Conditions</a></h2>
+ <p>Conditions are nested elements of the
+<a href="condition.html"><code>&lt;condition&gt;</code></a> and
+<a href="waitfor.html"><code>&lt;waitfor&gt;</code></a> tasks.
+ There are core conditions and custom conditions. Custom
+ conditions are described in
+ <a href="../Types/custom-programming.html#customconditions">
+ Custom Conditions</a>.
+ Core Conditions are described below.
+ </p>
+ <h3><a name="coreconditions">Core Conditions</a></h3>
+
+<p>These are the nested elements that can be used as conditions in the
+<a href="condition.html"><code>&lt;condition&gt;</code></a> and
+<a href="waitfor.html"><code>&lt;waitfor&gt;</code></a> tasks.</p>
+
+<h4><a name="not">not</a></h4>
+<p>The <code>&lt;not&gt;</code> element expects exactly one other
+condition to be nested into this element, negating the result of the
+condition. It doesn't have any attributes and accepts all nested
+elements of the condition task as nested elements as well.</p>
+
+<h4><a name="and">and</a></h4> <p>
+The <code>&lt;and&gt;</code> element doesn't have any attributes and
+accepts an arbitrary number of conditions as nested elements - all
+nested elements of the condition task are supported. This condition
+is true if all of its contained conditions are, conditions will be
+evaluated in the order they have been specified in the build file.</p>
+<p>The <code>&lt;and&gt;</code> condition has the same shortcut
+semantics as the Java &amp;&amp; operator, as soon as one of the
+nested conditions is false, no other condition will be evaluated.</p>
+
+<h4><a name="or">or</a></h4> <p>
+The <code>&lt;or&gt;</code> element doesn't have any attributes and
+accepts an arbitrary number of conditions as nested elements - all
+nested elements of the condition task are supported. This condition
+is true if at least one of its contained conditions is, conditions
+will be evaluated in the order they have been specified in the build
+file.</p> <p>The <code>&lt;or&gt;</code> condition has the same
+shortcut semantics as the Java || operator, as soon as one of the
+nested conditions is true, no other condition will be evaluated.</p>
+
+<h4><a name="xor">xor</a></h4>
+<p>The <code>&lt;xor&gt;</code> element performs an exclusive
+or on all nested elements, similar to the <code>^</code> operator
+in Java. It only evaluates to true if an odd number of nested conditions
+are true. There is no shortcutting of evaluation, unlike the <code>&lt;and&gt;</code>
+and <code>&lt;or&gt;</code> tests.
+It doesn't have any attributes and accepts all nested
+elements of the condition task as nested elements as well.</p>
+
+<h4><a name="available">available</a></h4>
+<p>This condition is identical to the <a
+href="available.html">Available</a> task, all attributes and nested
+elements of that task are supported, the property and value attributes
+are redundant and will be ignored.</p>
+
+<h4><a name="uptodate">uptodate</a></h4>
+<p>This condition is identical to the <a
+href="uptodate.html">Uptodate</a> task, all attributes and nested
+elements of that task are supported, the property and value attributes
+are redundant and will be ignored.</p>
+
+<h4><a name="os">os</a></h4>
+<p>Test whether the current operating system is of a given type. Each
+defined attribute is tested and the result is true only if <i>all</i>
+the tests succeed.
+</p>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">family</td>
+ <td valign="top">The name of the operating system family to expect.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">name</td>
+ <td valign="top">The name of the operating system to expect.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">arch</td>
+ <td valign="top">The architecture of the operating system to expect.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">version</td>
+ <td valign="top">The version of the operating system to expect.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+</table>
+<p>Supported values for the family attribute are:
+<ul>
+ <li>windows (for all versions of Microsoft Windows)</li>
+ <li>dos (for all Microsoft DOS based operating systems including
+ Microsoft Windows and OS/2)</li>
+ <li>mac (for all Apple Macintosh systems)</li>
+ <li>unix (for all Unix and Unix-like operating systems)</li>
+ <li>netware (for Novell NetWare)</li>
+ <li>os/2 (for OS/2)</li>
+ <li>tandem (for HP's NonStop Kernel - formerly Tandem)</li>
+ <li>win9x for Microsoft Windows 95 and 98, ME and CE</li>
+ <li>winnt for Microsoft Windows NT-based systems, including Windows 2000, XP and
+ successors</li>
+ <li>z/os for z/OS and OS/390</li>
+ <li>os/400 for OS/400</li>
+ <li>openvms for OpenVMS</li>
+</ul>
+
+<h4><a name="equals">equals</a></h4>
+<p>Tests whether the two given values are equal.</p>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">arg1</td>
+ <td valign="top">First value to test.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">arg2</td>
+ <td valign="top">Second value to test.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">casesensitive</td>
+ <td valign="top">Perform a case sensitive comparison. Default is
+ true.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">trim</td>
+ <td valign="top">Trim whitespace from arguments before comparing
+ them. Default is false.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">forcestring</td>
+ <td valign="top">Force string comparison of <code>arg1/arg2</code>.
+ Default is false. <em>Since Apache Ant 1.8.1</em>
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+</table>
+
+<h4><a name="isset">isset</a></h4>
+<p>Test whether a given property has been set in this project.</p>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">property</td>
+ <td valign="top">The name of the property to test.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+</table>
+
+<h4><a name="checksum">checksum</a></h4>
+<p>This condition is identical to the <a href="checksum.html">Checksum</a>
+task, all attributes and nested elements of that task are supported,
+the property and overwrite attributes are redundant and will be
+ignored.</p>
+
+<h4><a name="http">http</a></h4>
+<p>The <code>http</code> condition checks for a valid response from a
+web server of the specified url. By default, HTTP responses errors
+of 400 or greater are viewed as invalid.</p>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td width="12%" valign="top"><b>Attribute</b></td>
+ <td width="78%" valign="top"><b>Description</b></td>
+ <td width="10%" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">url</td>
+ <td valign="top">The full URL of the page to request. The web server must
+ return a status code below the value of <tt>errorsBeginAt</tt></td>
+ <td align="center">Yes.</td>
+ </tr>
+ <tr>
+ <td valign="top">errorsBeginAt</td>
+ <td valign="top">The lowest HTTP response code that signals an error;
+ by default '400'; server errors, not-authorized, not-found and the like
+ are detected</td>
+ <td align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">requestMethod</td>
+ <td valign="top">The HTTP method to be used when issuing the request.
+ Any of GET, POST, HEAD, OPTIONS, PUT, DELETEm and TRACE
+ are valid, subject to protocol restrictions. The default if not
+ specified is &quot;GET&quot;.<br/>
+ <em>since Ant 1.8.0</em></td>
+ <td align="center">No</td>
+ </tr>
+</table>
+
+<h4><a name="socket">socket</a></h4>
+<p>The <code>socket</code> condition checks for the existence of a
+TCP/IP listener at the specified host and port.</p>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td width="12%" valign="top"><b>Attribute</b></td>
+ <td width="78%" valign="top"><b>Description</b></td>
+ <td width="10%" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">server</td>
+ <td valign="top">The DNS name or IP address of the server.</td>
+ <td align="center">Yes.</td>
+ </tr>
+ <tr>
+ <td valign="top">port</td>
+ <td valign="top">The port number to connect to.</td>
+ <td align="center">Yes.</td>
+ </tr>
+</table>
+
+<h4><a name="filesmatch">filesmatch</a></h4>
+<p>Test two files for matching. Nonexistence of one file results in "false",
+although if neither exists they are considered equal in terms of content.
+This test does a byte for byte comparison, so test time scales with
+byte size. NB: if the files are different sizes, one of them is missing
+or the filenames match the answer is so obvious the detailed test is omitted.
+
+</p>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td width="12%" valign="top"><b>Attribute</b></td>
+ <td width="78%" valign="top"><b>Description</b></td>
+ <td width="10%" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">file1</td>
+ <td valign="top">First file to test</td>
+ <td align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">file2</td>
+ <td valign="top">Second file to test</td>
+ <td align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">textfile</td>
+ <td valign="top">Whether to ignore line endings when comparing
+ files; defaults to <i>false</i> which triggers a binary
+ comparison. <b>Since Ant 1.7</b>
+ </td>
+ <td align="center">No</td>
+ </tr>
+</table>
+
+<h4><a name="contains">contains</a></h4>
+<p>Tests whether a string contains another one.</p>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">string</td>
+ <td valign="top">The string to search in.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">substring</td>
+ <td valign="top">The string to search for.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">casesensitive</td>
+ <td valign="top">Perform a case sensitive comparison. Default is
+ true.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+</table>
+
+<h4><a name="istrue">istrue</a></h4>
+<p>Tests whether a string equals any of the ant definitions of true,
+that is "true","yes", or "on"</p>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">value</td>
+ <td valign="top">value to test</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+</table>
+<blockquote><pre>
+&lt;istrue value=&quot;${someproperty}&quot;/&gt;
+&lt;istrue value=&quot;false&quot;/&gt;
+</pre></blockquote>
+
+<h4><a name="isfalse">isfalse</a></h4>
+<p>Tests whether a string is not true, the negation of &lt;istrue&gt;
+</p>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">value</td>
+ <td valign="top">value to test</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+</table>
+<blockquote><pre>
+&lt;isfalse value=&quot;${someproperty}&quot;/&gt;
+&lt;isfalse value=&quot;false&quot;/&gt;
+</pre></blockquote>
+
+<h4><a name="isreference">isreference</a></h4>
+
+<p>Test whether a given reference has been defined in this project and
+- optionally - is of an expected type.</p>
+
+<p>This condition has been added in Apache Ant 1.6.</p>
+
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">refid</td>
+ <td valign="top">The id of the reference to test.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">type</td>
+ <td valign="top">Name of the data type or task this reference is
+ expected to be.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+</table>
+
+<h4><a name="issigned">issigned</a></h4>
+ <p>
+ Test whether a jarfile is signed.
+ If the name of the
+ signature is passed, the file is checked for presence of that
+ particular signature; otherwise the file is checked for the
+ existence of any signature. It does not perform rigorous
+ signature validation; it only looks for the presence of a signature.
+ </p>
+ <p>
+ This condition was added in Apache Ant 1.7.
+ </p>
+ <table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">file</td>
+ <td valign="top">
+ The jarfile that is to be tested for the presence
+ of a signature.
+ </td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">name</td>
+ <td valign="top"> The signature name to check for.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ </table>
+
+<h4><a name="isfileselected">isfileselected</a></h4>
+ <p>
+ Test whether a file passes an embedded
+ <a href="../Types/selectors.html">selector</a>.
+ </p>
+ <p>
+ This condition was added in Apache Ant 1.6.3.
+ </p>
+ <table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">file</td>
+ <td valign="top">
+ The file to check if is passes the embedded selector.
+ </td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">basedir</td>
+ <td valign="top">The base directory to use for name based selectors. It this is not set,
+ the project's basedirectory will be used.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ </table>
+ <p>
+ Example usage:
+ </p>
+<blockquote><pre>
+&lt;isfileselected file="a.xml"&gt;
+ &lt;date datetime="06/28/2000 2:02 pm" when="equal"/&gt;
+&lt;/isfileselected&gt;
+</pre></blockquote>
+
+<h4><a name="typefound">typefound</a></h4>
+
+<p>Test whether a given type is defined, and that
+its implementation class can be loaded. Types include
+tasks, datatypes, scriptdefs, macrodefs and presetdefs.</p>
+
+<p>This condition was added in Apache Ant 1.7.</p>
+
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">name</td>
+ <td valign="top">name of the type</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">uri</td>
+ <td valign="top">
+ The uri that this type lives in.
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+</table>
+
+ <p>
+ Example usages:
+ </p>
+<blockquote><pre>
+&lt;typefound name="junit"/&gt;
+&lt;typefound uri="antlib:org.apache.maven.artifact.ant" name="artifact"/&gt;
+</pre></blockquote>
+
+<h4><a name="scriptcondition">scriptcondition</a></h4>
+
+<p>Evaluate a condition based on a script in any
+<a href="http://jakarta.apache.org/bsf" target="_top">Apache BSF</a>
+ or
+ <a href="https://scripting.dev.java.net">JSR 223</a>
+supported language.
+</p>
+<p>
+See the <a href="../Tasks/script.html">Script</a> task for
+an explanation of scripts and dependencies.
+</p>
+
+<p>This condition was added in Apache Ant 1.7.</p>
+
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">language</td>
+ <td valign="top">script language</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">manager</td>
+ <td valign="top">
+ The script engine manager to use.
+ See the <a href="../Tasks/script.html">script</a> task
+ for using this attribute.
+ </td>
+ <td valign="top" align="center">No - default is "auto"</td>
+ </tr>
+ <tr>
+ <td valign="top">value</td>
+ <td valign="top">default boolean value</td>
+ <td valign="top" align="center">No -default is "false"</td>
+ </tr>
+ <tr>
+ <td valign="top">src</td>
+ <td valign="top">filename of script source</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">setbeans</td>
+ <td valign="top">whether to have all properties, references and targets as
+ global variables in the script. <em>since Ant 1.8.0</em></td>
+ <td valign="top" align="center">No, default is "true".</td>
+ </tr>
+ <tr>
+ <td valign="top">classpath</td>
+ <td valign="top">
+ The classpath to pass into the script.
+ </td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">classpathref</td>
+ <td valign="top">The classpath to use, given as a
+ <a href="../using.html#references">reference</a> to a path defined elsewhere.
+ <td align="center" valign="top">No</td>
+ </tr>
+</table>
+<h5>Parameters specified as nested elements</h5>
+<h6>classpath</h6>
+ <p>
+ See the <a href="../Tasks/script.html">script</a> task
+ for using this nested element.
+ </p>
+<h5>Description</h5>
+<p>
+The script supports script language inline, this script has access to the
+same beans as the <code>&lt;script&gt;</code> task, and to the <code>self</code> bean,
+which refers back to the condition itself. If the script evaluates to a boolean result,
+this is the result of the condition's evaluation (<em>since Ant 1.7.1</em>).
+Alternatively, <code>self.value</code> can be used to set the evaluation result.
+</p>
+<p>
+Example:
+</p>
+<blockquote><pre>
+&lt;scriptcondition language=&quot;javascript&quot;
+ value=&quot;true&quot;&gt;
+ self.setValue(false);
+&lt;/scriptcondition&gt;
+</pre></blockquote>
+
+Sets the default value of the condition to true, then in the script,
+sets the value to false. This condition always evaluates to "false"
+
+<h4><a name="parsersupports">parsersupports</a></h4>
+
+<p>Tests whether Ant's XML parser supports a given
+feature or property, as per the SAX/JAXP specifications, by
+attempting to set the appropriate property/feature/</p>
+
+<p>This condition was added in Apache Ant 1.7.</p>
+
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">property</td>
+ <td valign="top">property to set</td>
+ <td valign="top" align="center">one of property or feature</td>
+ </tr>
+ <tr>
+ <td valign="top">feature</td>
+ <td valign="top">feature to set</td>
+ <td valign="top" align="center">one of property or feature</td>
+ </tr>
+ <tr>
+ <td valign="top">value</td>
+ <td valign="top">string (property) or boolean (feature)</td>
+ <td valign="top" align="center">For property tests, but not for feature tests</td>
+ </tr>
+</table>
+
+<blockquote><pre>
+&lt;parsersupports feature="http://xml.org/sax/features/namespaces"/&gt;
+</pre></blockquote>
+Check for namespace support. All SAX2 parsers should have this.
+<blockquote><pre>
+&lt;or&gt;
+ &lt;parsersupports
+ feature="http://apache.org/xml/features/validation/schema"/&gt;
+ &lt;parsersupports
+ feature="http://java.sun.com/xml/jaxp/properties/schemaSource"/&gt;
+&lt;/or&gt;
+</pre></blockquote>
+
+Check for XML Schema support.
+
+<pre>
+&lt;parsersupports
+ property="http://apache.org/xml/properties/schema/external-noNamespaceSchemaLocation"
+ value="document.xsd"/&gt;
+</pre>
+
+Check for Xerces-specific definition of the location of the no namespace schema.
+
+<h4><a name="isreachable">isreachable</a></h4>
+
+<p>Uses Java1.5+ networking APIs to probe for a (remote) system being
+reachable. Exactly what probe mechanisms are used is an implementation
+feature of the JVM. They may include ICMP "ping" packets, UDP or TCP connections
+to port 7 "echo service" or other means. On Java1.4 and earlier, being able
+to resolve the hostname is considered success. This means that if DNS is not
+working or a URL/hostname is bad, the test will fail, but otherwise succeed
+even if the remote host is actually absent.
+
+</p>
+<p>
+This condition turns unknown host exceptions into false conditions. This is
+because on a laptop, DNS is one of the first services when the network goes; you
+are implicitly offline.
+</p>
+<p>
+ If a URL is supplied instead of a host, the hostname is extracted
+ and used in the test - all other parts of the URL are discarded.
+</p>
+<p>
+The test may not work through firewalls, that is, something may be reachable
+using a protocol such as HTTP, while the lower level ICMP packets get dropped
+on the floor. Similarly, a host may detected as reachable with ICMP, but
+not reachable on other ports (i.e. port 80), because of firewalls.
+</p>
+<p>
+
+This condition was added in Apache Ant 1.7.</p>
+
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">host</td>
+ <td valign="top">host to check for</td>
+ <td valign="top" align="center">one of url or host</td>
+ </tr>
+ <tr>
+ <td valign="top">url</td>
+ <td valign="top">URL containing hostname</td>
+ <td valign="top" align="center">one of url or host</td>
+ </tr>
+ <tr>
+ <td valign="top">timeout</td>
+ <td valign="top">timeout in seconds</td>
+ <td valign="top" align="center">no, default is 30s</td>
+ </tr>
+</table>
+
+<blockquote><pre>
+&lt;condition property="offline"&gt;
+ &lt;isreachable url="http://ibiblio.org/maven/" /&gt;
+&lt;/condition&gt;
+</pre></blockquote>
+
+<p>
+Probe for the maven repository being reachable.
+</p>
+
+<blockquote><pre>
+&lt;condition property="offline"&gt;
+ &lt;isreachable host="ibiblio.org" timeout="10" /&gt;
+&lt;/condition&gt;
+</pre></blockquote>
+
+<p>
+Probe for the maven repository being reachable using the hostname, ten second timeout..
+</p>
+
+<h4><a name="length">length</a></h4>
+<p>This condition is a facet of the <a href="length.html">Length</a> task.
+ It is used to test the length of a string or one or more files.
+ <b>Since Ant 1.6.3</b>
+</p>
+
+<blockquote><pre>
+&lt;length string=" foo " trim="true" length="3" /&gt;
+</pre></blockquote>
+<p>Verify a string is of a certain length.</p>
+
+<blockquote><pre>
+&lt;length file=&quot;foo&quot; when=&quot;greater&quot; length=&quot;0&quot; /&gt;
+</pre></blockquote>
+<p>Verify that file <i>foo</i> is not empty.</p>
+
+<h4><a name="isfailure">isfailure</a></h4>
+
+<p>Test the return code of an executable (see the
+<a href="exec.html">Exec</a> task) for failure. <b>Since Ant 1.7</b></p>
+
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">code</td>
+ <td valign="top">The return code to test.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+</table>
+
+<h4><a name="resourcecount">resourcecount</a></h4>
+<p>This condition is a facet of the
+ <a href="resourcecount.html">ResourceCount</a> task.
+ It is used to test the size of a
+ <a href="../Types/resources.html#collection">resource collection</a>.
+ <b>Since Ant 1.7</b>
+</p>
+
+<blockquote><pre>
+&lt;resourcecount refid=&quot;myresourcecollection&quot; when=&quot;greater&quot; count=&quot;0&quot; /&gt;
+</pre></blockquote>
+<p>Verify that a resource collection is not empty.</p>
+
+<h4><a name="resourcesmatch">resourcesmatch</a></h4>
+<p>Test resources for matching. Nonexistence of one or more resources results in
+"false", although if none exists they are considered equal in terms of content.
+By default this test does a byte for byte comparison, so test time scales with
+byte size. NB: if the files are different sizes, one of them is missing
+or the filenames match the answer is so obvious the detailed test is omitted.
+The resources to check are specified as nested
+<a href="../Types/resources.html#collection">resource collections</a>,
+meaning that more than two resources can be checked; in this case all resources
+must match. <b>Since Ant 1.7</b>
+</p>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td width="12%" valign="top"><b>Attribute</b></td>
+ <td width="78%" valign="top"><b>Description</b></td>
+ <td width="10%" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">astext</td>
+ <td valign="top">Whether to ignore line endings
+ when comparing resource content; defaults to <i>false</i>,
+ while <i>true</i> triggers a binary comparison.
+ </td>
+ <td align="center">No</td>
+ </tr>
+</table>
+
+<h4><a name="resourcecontains">resourcecontains</a></h4>
+<p>Tests whether a resource contains a given (sub)string.</p>
+<p>The resources to check are specified via references or - in the
+ case of file resources via the resource attribute. <b>Since Ant 1.7.1</b>
+</p>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td width="12%" valign="top"><b>Attribute</b></td>
+ <td width="78%" valign="top"><b>Description</b></td>
+ <td width="10%" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">resource</td>
+ <td valign="top">Name of a file that is the resource to test.
+ </td>
+ <td align="center" rowspan="2">One of the two</td>
+ </tr>
+ <tr>
+ <td valign="top">refid</td>
+ <td valign="top">Reference to a resource defined inside the project.</td>
+ </tr>
+ <tr>
+ <td valign="top">substring</td>
+ <td valign="top">The string to search for.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">casesensitive</td>
+ <td valign="top">Perform a case sensitive comparison. Default is
+ true.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+</table>
+
+<h4><a name="hasmethod">hasmethod</a></h4>
+
+<p> Tests for a class having a method or field. If the class is not found
+ or fails to load, the build fails.
+
+ <b>Since Ant 1.7</b>
+</p>
+
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td width="12%" valign="top"><b>Attribute</b></td>
+ <td width="78%" valign="top"><b>Description</b></td>
+ <td width="10%" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">classname</td>
+ <td valign="top">name of the class to load</td>
+ <td align="center">yes</td>
+ </tr>
+ <tr>
+ <td valign="top">field</td>
+ <td valign="top">name of a field to look for</td>
+ <td align="center">one of field or method</td>
+ </tr>
+ <tr>
+ <td valign="top">method</td>
+ <td valign="top">name of a method to look for</td>
+ <td align="center">one of field or method</td>
+ </tr>
+
+ <tr>
+ <td valign="top">ignoreSystemClasses</td>
+ <td valign="top">should system classes be ignored?</td>
+ <td align="center">No -default is false</td>
+ </tr>
+ <tr>
+ <td valign="top">classpath</td>
+ <td valign="top">a class path</td>
+ <td align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">classpathref</td>
+ <td valign="top">reference to a class path</td>
+ <td align="center">No</td>
+ </tr>
+</table>
+
+<p>
+ There is also a nested &lt;classpath&gt; element, which can be used to specify
+ a classpath.
+</p>
+<blockquote><pre>
+&lt;hasmethod classname="java.util.ArrayList" method="trimToSize" /&gt;
+</pre></blockquote>
+
+<p>Looks for the method trimToSize in the ArrayList class.</p>
+
+<h4><a name="matches">matches</a></h4>
+
+<p>
+ Test if the specified string matches the specified regular
+ expression pattern.
+ <b>Since Ant 1.7</b></p>
+
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">string</td>
+ <td valign="top">The string to test.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">pattern</td>
+ <td valign="top">The regular expression pattern used to test.</td>
+ <td valign="top" align="center">Yes, unless there is a nested
+ <code>&lt;regexp&gt;</code> element.</td>
+ </tr>
+ <tr>
+ <td valign="top">casesensitive</td>
+ <td valign="top">Perform a case sensitive match. Default is
+ true.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">multiline</td>
+ <td valign="top">
+ Perform a multi line match.
+ Default is false.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">singleline</td>
+ <td valign="top">
+ This allows '.' to match new lines.
+ SingleLine is not to be confused with multiline, SingleLine is a perl
+ regex term, it corresponds to dotall in java regex.
+ Default is false.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+</table>
+
+ <p>
+ There is also an optional &lt;regexp&gt; element, which can be used to specify
+ a regular expression instead of the "pattern" attribute.
+ See <a href="../Types/regexp.html">Regexp Type</a> for the description
+ of the nested element regexp and of
+ the choice of regular expression implementation.
+ </p>
+ <p>
+ An example:
+ </p>
+<blockquote><pre>
+&lt;condition property="legal-password"&gt;
+ &lt;matches pattern="[1-9]" string="${user-input}"/&gt;
+&lt;/condition&gt;
+&lt;fail message="Your password should at least contain one number"
+ unless="legal-password"/&gt;
+</pre></blockquote>
+ <p>
+ The following example sets the property "ok" if
+ the property "input" is three characters long, starting
+ with 'a' and ending with 'b'.
+ </p>
+<blockquote><pre>
+&lt;condition property="ok"&gt;
+ &lt;matches string="${input}" pattern="^a.b$"/&gt;
+&lt;/condition&gt;
+</pre></blockquote>
+ <p>
+ The following defines a reference regular expression for
+ matching dates and then uses antunit to check if the
+ property "today" is in the correct format:
+ </p>
+<blockquote><pre>
+&lt;regexp id="date.pattern" pattern="^[0123]\d-[01]\d-[12]\d\d\d$"/&gt;
+
+&lt;au:assertTrue xmlns:au="antlib:org.apache.ant.antunit"&gt;
+ &lt;matches string="${today}"&gt;
+ &lt;regexp refid="date.pattern"/&gt;
+ &lt;/matches&gt;
+&lt;/au:assertTrue&gt;
+</pre></blockquote>
+ <p>
+ The following example shows the use of the singleline and the casesensitive
+ flags.
+ </p>
+<blockquote><pre>
+&lt;au:assertTrue&gt;
+ &lt;matches string="AB${line.separator}C" pattern="^ab.*C$"
+ casesensitive="false"
+ singleline="true"/&gt;
+&lt;/au:assertTrue&gt;
+&lt;au:assertFalse&gt;
+ &lt;matches string="AB${line.separator}C" pattern="^ab.*C$"
+ casesensitive="false"
+ singleline="false"/&gt;
+&lt;/au:assertFalse&gt;
+</pre></blockquote>
+
+<h4><a name="antversion">antversion</a></h4>
+<p>This condition is identical to the <a
+href="antversion.html">Antversion</a> task, all attributes are supported, the property attribute
+is redundant and will be ignored.</p>
+
+
+<h4><a name="hasfreespace">hasfreespace</a></h4>
+
+<p>
+ Tests a partition to see if there is enough space.
+ <b>Since Ant 1.7.0</b></p>
+ <p>Needed attribute can be specified using standard computing terms:<br/>
+ <ul>
+ <li>K : Kilobytes (1024 bytes)</li>
+ <li>M : Megabytes (1024 K)</li>
+ <li>G : Gigabytes (1024 M)</li>
+ <li>T : Terabytes (1024 G)</li>
+ <li>P : Petabytes (1024 T)</li>
+ </ul>
+ </p>
+
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">partition</td>
+ <td valign="top">The partition or filesystem to check for freespace</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">needed</td>
+ <td valign="top">The amount of freespace needed.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+</table>
+ <p>
+ An example:
+ </p>
+<blockquote><pre>
+&lt;hasfreespace partition="c:" needed="100M"/&gt;
+</pre></blockquote>
+
+<h4><a name="islastmodified">islastmodified</a></h4>
+
+<p>Tests the last modified date of a resource. <em>Since Ant
+1.8.0</em></p>
+
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td width="12%" valign="top"><b>Attribute</b></td>
+ <td width="78%" valign="top"><b>Description</b></td>
+ <td width="10%" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">millis</td>
+ <td valign="top">Specifies the expected modification time of the resource
+ in milliseconds since midnight Jan 1 1970.</td>
+ <td valign="center" align="center" rowspan="2">Exactly one of the
+ two.</td>
+ </tr>
+ <tr>
+ <td valign="top">datetime</td>
+ <td valign="top">Specifies the expected modification time of the
+ resource. The special value &quot;now&quot; indicates the
+ current time.</td>
+ </tr>
+ <tr>
+ <td valign="top">pattern</td>
+ <td valign="top">SimpleDateFormat-compatible pattern string.
+ Defaults to MM/DD/YYYY HH:MM AM_or_PM or MM/DD/YYYY HH:MM:SS AM_or_PM.
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">mode</td>
+ <td valign="top">How to compare the timestamp. Accepted values
+ are "equals", "before", "not-before", "after" and "not-after".
+ <td valign="top">No, defaults to "equals".</td>
+ </tr>
+</table>
+
+<p>The actual resource to test is specified as a nested element.</p>
+
+ <p>
+ An example:
+ </p>
+<blockquote><pre>
+&lt;islastmodified dateTime="08/18/2009 04:41:19 AM" mode="not-before"&gt;
+ &lt;file file="${file}"/&gt;
+&lt;/islastmodified&gt;
+</pre></blockquote>
+
+<h4><a name="resourceexists">resourceexists</a></h4>
+
+<p>Tests a resource for existence. <em>since Ant 1.8.0</em></p>
+
+<p>The actual resource to test is specified as a nested element.</p>
+
+ <p>
+ An example:
+ </p>
+<blockquote><pre>
+&lt;resourceexists&gt;
+ &lt;file file="${file}"/&gt;
+&lt;/resourceexists&gt;
+</pre></blockquote>
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/copy.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/copy.html
new file mode 100644
index 00000000..d1b8ff2a
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/copy.html
@@ -0,0 +1,376 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Copy Task</title>
+</head>
+
+<body>
+
+<h2><a name="copy">Copy</a></h2>
+<h3>Description</h3>
+<p>Copies a file or resource collection to a new file or directory. By default, files are
+only copied if the source file is newer than the destination file,
+or when the destination file does not exist. However, you can explicitly
+overwrite files with the <code>overwrite</code> attribute.</p>
+
+<p><a href="../Types/resources.html#collection">Resource
+Collection</a>s are used to select a group of files to copy. To use a
+resource collection, the <code>todir</code> attribute must be set.
+<strong>Note</strong> that some resources (for example
+the <a href="../Types/resources.html#file">file</a> resource)
+return absolute paths as names and the result of using them without
+using a nested mapper (or the flatten attribute) may not be what you
+expect.</p>
+
+<p>
+<strong>Note: </strong>If you employ filters in your copy operation,
+you should limit the copy to text files. Binary files will be corrupted
+by the copy operation.
+This applies whether the filters are implicitly defined by the
+<a href="filter.html">filter</a> task or explicitly provided to the copy
+operation as <a href="../Types/filterset.html">filtersets</a>.
+ <em>See <a href="#encoding">encoding note</a></em>.
+</p>
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">file</td>
+ <td valign="top">The file to copy.</td>
+ <td valign="top" align="center">Yes, unless a nested
+ resource collection element is used.</td>
+ </tr>
+ <tr>
+ <td valign="top">preservelastmodified</td>
+ <td valign="top">Give the copied files the same last modified
+ time as the original source files.</td>
+ <td valign="top" align="center">No; defaults to false.</td>
+ </tr>
+ <tr>
+ <td valign="top">tofile</td>
+ <td valign="top">The file to copy to.</td>
+ <td valign="top" align="center" rowspan="2">With the <code>file</code>
+ attribute, either <code>tofile</code> or <code>todir</code> can be used.<br/>
+
+ With nested resource collection elements, if the number of
+ included resources
+ is greater than 1, or if only the <code>dir</code> attribute is
+ specified in the <code>&lt;fileset&gt;</code>, or if the
+ <code>file</code> attribute is also specified, then only
+ <code>todir</code> is allowed.<br/>
+ <em>Prior to Apache Ant 1.8.2</em> the <code>tofile</code> attribute
+ only supported filesystem resources top copy from.</td>
+ </tr>
+ <tr>
+ <td valign="top">todir</td>
+ <td valign="top">The directory to copy to.</td>
+ </tr>
+ <tr>
+ <td valign="top">overwrite</td>
+ <td valign="top">Overwrite existing files even if the destination
+ files are newer.</td>
+ <td valign="top" align="center">No; defaults to false.</td>
+ </tr>
+ <tr>
+ <td valign="top">force</td>
+ <td valign="top">Overwrite read-only destination
+ files. <em>since Ant 1.8.2</em></td>
+ <td valign="top" align="center">No; defaults to false.</td>
+ </tr>
+ <tr>
+ <td valign="top">filtering</td>
+ <td valign="top">Indicates whether token filtering using the <a href="../using.html#filters">global
+ build-file filters</a> should take place during the copy.
+ <em>Note</em>: Nested <code>&lt;filterset&gt;</code> elements will
+ always be used, even if this attribute is not specified, or its value is
+ <code>false</code> (<code>no</code>, or <code>off</code>).</td>
+ <td valign="top" align="center">No; defaults to false.</td>
+ </tr>
+ <tr>
+ <td valign="top">flatten</td>
+ <td valign="top">Ignore the directory structure of the source files,
+ and copy all files into the directory specified by the <code>todir</code>
+ attribute. Note that you can achieve the same effect by using a
+ <a href="../Types/mapper.html#flatten-mapper">flatten mapper</a>.</td>
+ <td valign="top" align="center">No; defaults to false.</td>
+ </tr>
+ <tr>
+ <td valign="top">includeEmptyDirs</td>
+ <td valign="top">Copy any empty directories included in the FileSet(s).
+ </td>
+ <td valign="top" align="center">No; defaults to true.</td>
+ </tr>
+ <tr>
+ <td valign="top">failonerror</td>
+ <td valign="top">If false, log a warning message, but do not stop the
+ build, when the file to copy does not exist or one of the nested
+ filesets points to a directory that doesn't exist or an error occurs
+ while copying.
+ </td>
+ <td valign="top" align="center">No; defaults to true.</td>
+ </tr>
+ <tr>
+ <td valign="top">quiet</td>
+ <td valign="top">If true and failonerror is false, then do not log a
+ warning message when the file to copy does not exist or one of the nested
+ filesets points to a directory that doesn't exist or an error occurs
+ while copying. <em>since Ant 1.8.3</em>.
+ </td>
+ <td valign="top" align="center">No; defaults to false.</td>
+ </tr>
+ <tr>
+ <td valign="top">verbose</td>
+ <td valign="top">Log the files that are being copied.</td>
+ <td valign="top" align="center">No; defaults to false.</td>
+ </tr>
+ <tr>
+ <td valign="top">encoding</td>
+ <td valign="top">The encoding to assume when filter-copying the
+ files. <em>since Ant 1.5</em>.</td>
+ <td align="center">No - defaults to default JVM encoding</td>
+ </tr>
+ <tr>
+ <td valign="top">outputencoding</td>
+ <td valign="top">The encoding to use when writing the files.
+ <em>since Ant 1.6</em>.</td>
+ <td align="center">No - defaults to the value of the encoding
+ attribute if given or the default JVM encoding otherwise.</td>
+ </tr>
+ <tr>
+ <td valign="top">enablemultiplemappings</td>
+ <td valign="top">
+ If true the task will process to all the mappings for a
+ given source path. If false the task will only process
+ the first file or directory. This attribute is only relevant
+ if there is a mapper subelement.
+ <em>since Ant 1.6</em>.</td>
+ <td align="center">No - defaults to false.</td>
+ </tr>
+ <tr>
+ <td valign="top">granularity</td>
+ <td valign="top">The number of milliseconds leeway to give before
+ deciding a file is out of date. This is needed because not every
+ file system supports tracking the last modified time to the
+ millisecond level. Default is 1 second, or 2 seconds on DOS
+ systems. This can also be useful if source and target files live
+ on separate machines with clocks being out of sync. <em>since Ant
+ 1.6.2</em>.</td>
+ <td align="center">No</td>
+ </tr>
+</table>
+<h3>Parameters specified as nested elements</h3>
+
+<h4>fileset or any other resource collection</h4>
+<p><a href="../Types/resources.html#collection">Resource
+Collection</a>s are used to select groups of files to copy. To use a
+resource collection, the <code>todir</code> attribute must be set.</p>
+<p>Prior to Ant 1.7 only <code>&lt;fileset&gt;</code> has been
+supported as a nested element.</p>
+
+<h4>mapper</h4>
+ <p>You can define filename transformations by using a nested <a
+ href="../Types/mapper.html">mapper</a> element. The default mapper used by
+ <code>&lt;copy&gt;</code> is the <a
+ href="../Types/mapper.html#identity-mapper">identity mapper</a>.</p>
+ <p>
+ <em>Since Ant 1.6.3</em>,
+ one can use a filenamemapper type in place of the mapper element.
+ </p>
+
+<p>Note that the source name handed to the mapper depends on the
+resource collection you use. If you use <code>&lt;fileset&gt;</code>
+or any other collection that provides a base directory, the name
+passed to the mapper will be a relative filename, relative to the base
+directory. In any other case the absolute filename of the source will
+be used.</p>
+
+<h4>filterset</h4>
+ <p><a href="../Types/filterset.html">FilterSet</a>s are used to replace
+tokens in files that are copied.
+ To use a FilterSet, use the nested <code>&lt;filterset&gt;</code> element.</p>
+
+<p>It is possible to use more than one filterset.</p>
+
+<h4>filterchain</h4>
+<p>The Copy task supports nested <a href="../Types/filterchain.html">
+FilterChain</a>s.</p>
+
+<p>
+If <code>&lt;filterset&gt;</code> and <code>&lt;filterchain&gt;</code> elements are used inside the
+same <code>&lt;copy&gt;</code> task, all <code>&lt;filterchain&gt;</code> elements are processed first
+followed by <code>&lt;filterset&gt;</code> elements.
+</p>
+
+<h3>Examples</h3>
+<p><b>Copy a single file</b></p>
+<pre>
+ &lt;copy file=&quot;myfile.txt&quot; tofile=&quot;mycopy.txt&quot;/&gt;
+</pre>
+<p><b>Copy a single file to a directory</b></p>
+<pre>
+ &lt;copy file=&quot;myfile.txt&quot; todir=&quot;../some/other/dir&quot;/&gt;
+</pre>
+<p><b>Copy a directory to another directory</b></p>
+<pre>
+ &lt;copy todir=&quot;../new/dir&quot;&gt;
+ &lt;fileset dir=&quot;src_dir&quot;/&gt;
+ &lt;/copy&gt;
+</pre>
+<p><b>Copy a set of files to a directory</b></p>
+<pre>
+ &lt;copy todir=&quot;../dest/dir&quot;&gt;
+ &lt;fileset dir=&quot;src_dir&quot;&gt;
+ &lt;exclude name=&quot;**/*.java&quot;/&gt;
+ &lt;/fileset&gt;
+ &lt;/copy&gt;
+
+ &lt;copy todir=&quot;../dest/dir&quot;&gt;
+ &lt;fileset dir=&quot;src_dir&quot; excludes=&quot;**/*.java&quot;/&gt;
+ &lt;/copy&gt;
+</pre>
+<p><b>Copy a set of files to a directory, appending
+<code>.bak</code> to the file name on the fly</b></p>
+<pre>
+ &lt;copy todir=&quot;../backup/dir&quot;&gt;
+ &lt;fileset dir=&quot;src_dir&quot;/&gt;
+ &lt;globmapper from=&quot;*&quot; to=&quot;*.bak&quot;/&gt;
+ &lt;/copy&gt;
+</pre>
+
+<p><b>Copy a set of files to a directory, replacing @TITLE@ with Foo Bar
+in all files.</b></p>
+<pre>
+ &lt;copy todir=&quot;../backup/dir&quot;&gt;
+ &lt;fileset dir=&quot;src_dir&quot;/&gt;
+ &lt;filterset&gt;
+ &lt;filter token=&quot;TITLE&quot; value=&quot;Foo Bar&quot;/&gt;
+ &lt;/filterset&gt;
+ &lt;/copy&gt;
+</pre>
+
+<p><b>Collect all items from the current CLASSPATH setting into a
+destination directory, flattening the directory structure.</b></p>
+<pre>
+ &lt;copy todir=&quot;dest&quot; flatten=&quot;true&quot;&gt;
+ &lt;path&gt;
+ &lt;pathelement path=&quot;${java.class.path}&quot;/&gt;
+ &lt;/path&gt;
+ &lt;/copy&gt;
+</pre>
+
+<p><b>Copies some resources to a given directory.</b></p>
+<pre>
+ &lt;copy todir=&quot;dest&quot; flatten=&quot;true&quot;&gt;
+ &lt;resources&gt;
+ &lt;file file=&quot;src_dir/file1.txt&quot;/&gt;
+ &lt;url url=&quot;http://ant.apache.org/index.html&quot;/&gt;
+ &lt;/resources&gt;
+ &lt;/copy&gt;
+</pre>
+
+<p>If the example above didn't use the flatten attribute,
+ the <code>&lt;file&gt;</code> resource would have returned its full
+ path as source and target name and would not have been copied at
+ all. In general it is a good practice to use an explicit mapper
+ together with resources that use an absolute path as their
+ names.</p>
+
+<p><b>Copies the two newest resources into a destination directory.</b></p>
+<pre>
+ &lt;copy todir=&quot;dest&quot; flatten=&quot;true&quot;&gt;
+ &lt;first count=&quot;2&quot;&gt;
+ &lt;sort&gt;
+ &lt;date xmlns=&quot;antlib:org.apache.tools.ant.types.resources.comparators&quot;/&gt;
+ &lt;resources&gt;
+ &lt;file file=&quot;src_dir/file1.txt&quot;/&gt;
+ &lt;file file=&quot;src_dir/file2.txt&quot;/&gt;
+ &lt;file file=&quot;src_dir/file3.txt&quot;/&gt;
+ &lt;url url=&quot;http://ant.apache.org/index.html&quot;/&gt;
+ &lt;/resources&gt;
+ &lt;/sort&gt;
+ &lt;/first&gt;
+ &lt;/copy&gt;
+</pre>
+
+<p>The paragraph following the previous example applies to this
+ example as well.</p>
+
+<p><strong>Unix Note:</strong> File permissions are not retained when files
+are copied; they end up with the default <code>UMASK</code> permissions
+instead. This
+is caused by the lack of any means to query or set file permissions in the
+current Java runtimes. If you need a permission-preserving copy function,
+use <code>&lt;exec executable="cp" ... &gt;</code> instead.
+</p>
+
+<p><strong>Windows Note:</strong> If you copy a file to a directory
+where that file already exists, but with different casing,
+the copied file takes on the case of the original. The workaround is to
+<a href="delete.html">delete</a>
+the file in the destination directory before you copy it.
+</p>
+ <p>
+ <strong><a name="encoding">Important Encoding Note:</a></strong>
+ The reason that binary files when filtered get corrupted is that
+ filtering involves reading in the file using a Reader class. This
+ has an encoding specifying how files are encoded. There are a number
+ of different types of encoding - UTF-8, UTF-16, Cp1252, ISO-8859-1,
+ US-ASCII and (lots) others. On Windows the default character encoding
+ is Cp1252, on Unix it is usually UTF-8. For both of these encoding
+ there are illegal byte sequences (more in UTF-8 than for Cp1252).
+ </p>
+ <p>
+ How the Reader class deals with these illegal sequences is up to the
+ implementation
+ of the character decoder. The current Sun Java implementation is to
+ map them to legal characters. Previous Sun Java (1.3 and lower) threw
+ a MalformedInputException. IBM Java 1.4 also throws this exception.
+ It is the mapping of the characters that cause the corruption.
+ </p>
+ <p>
+ On Unix, where the default is normally UTF-8, this is a <em>big</em>
+ problem, as it is easy to edit a file to contain non US Ascii characters
+ from ISO-8859-1, for example the Danish oe character. When this is
+ copied (with filtering) by Ant, the character get converted to a
+ question mark (or some such thing).
+ </p>
+ <p>
+ There is not much that Ant can do. It cannot figure out which
+ files are binary - a UTF-8 version of Korean will have lots of
+ bytes with the top bit set. It is not informed about illegal
+ character sequences by current Sun Java implementions.
+ </p>
+ <p>
+ One trick for filtering containing only US-ASCII is to
+ use the ISO-8859-1 encoding. This does not seem to contain
+ illegal character sequences, and the lower 7 bits are US-ASCII.
+ Another trick is to change the LANG environment variable from
+ something like "us.utf8" to "us".
+ </p>
+
+
+
+
+</body></html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/copydir.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/copydir.html
new file mode 100644
index 00000000..9e9e60e1
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/copydir.html
@@ -0,0 +1,136 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Copydir Task</title>
+</head>
+
+<body>
+
+<h2><a name="copydir">Copydir</a></h2>
+<h3><i>Deprecated</i></h3>
+<p><i>This task has been deprecated. Use the Copy task instead.</i></p>
+<h3>Description</h3>
+<p>Copies a directory tree from the source to the destination.</p>
+<p>It is possible to refine the set of files that are being copied. This can be
+done with the <i>includes</i>, <i>includesfile</i>, <i>excludes</i>, <i>excludesfile</i> and <i>defaultexcludes</i>
+attributes. With the <i>includes</i> or <i>includesfile</i> attribute you specify the files you want to
+have included by using patterns. The <i>exclude</i> or <i>excludesfile</i> attribute is used to specify
+the files you want to have excluded. This is also done with patterns. And
+finally with the <i>defaultexcludes</i> attribute, you can specify whether you
+want to use default exclusions or not. See the section on <a
+href="../dirtasks.html#directorybasedtasks">directory based tasks</a>, on how the
+inclusion/exclusion of files works, and how to write patterns.</p>
+<p>This task forms an implicit <a href="../Types/fileset.html">FileSet</a> and
+supports most attributes of <code>&lt;fileset&gt;</code>
+(<code>dir</code> becomes <code>src</code>) as well as the nested
+<code>&lt;include&gt;</code>, <code>&lt;exclude&gt;</code> and
+<code>&lt;patternset&gt;</code> elements.</p>
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">src</td>
+ <td valign="top">the directory to copy.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">dest</td>
+ <td valign="top">the directory to copy to.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">includes</td>
+ <td valign="top">comma- or space-separated list of patterns of files that must be
+ included. All files are included when omitted.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">includesfile</td>
+ <td valign="top">the name of a file. Each line of this file is
+ taken to be an include pattern</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">excludes</td>
+ <td valign="top">comma- or space-separated list of patterns of files that must be
+ excluded. No files (except default excludes) are excluded when omitted.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">excludesfile</td>
+ <td valign="top">the name of a file. Each line of this file is
+ taken to be an exclude pattern</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">defaultexcludes</td>
+ <td valign="top">indicates whether default excludes should be used or not
+ (&quot;yes&quot;/&quot;no&quot;). Default excludes are used when omitted.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">filtering</td>
+ <td valign="top">indicates whether token filtering should take place during
+ the copy</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">flatten</td>
+ <td valign="top">ignore directory structure of source directory,
+ copy all files into a single directory, specified by the <code>dest</code>
+ attribute (default is <code>false</code>).</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">forceoverwrite</td>
+ <td valign="top">overwrite existing files even if the destination
+ files are newer (default is false).</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+</table>
+<h3>Examples</h3>
+<pre> &lt;copydir src=&quot;${src}/resources&quot;
+ dest=&quot;${dist}&quot;
+ /&gt;</pre>
+<p>copies the directory <code>${src}/resources</code> to <code>${dist}</code>.</p>
+<pre> &lt;copydir src=&quot;${src}/resources&quot;
+ dest=&quot;${dist}&quot;
+ includes=&quot;**/*.java&quot;
+ excludes=&quot;**/Test.java&quot;
+ /&gt;</pre>
+<p>copies the directory <code>${src}/resources</code> to <code>${dist}</code>
+recursively. All java files are copied, except for files with the name <code>Test.java</code>.</p>
+<pre> &lt;copydir src=&quot;${src}/resources&quot;
+ dest=&quot;${dist}&quot;
+ includes=&quot;**/*.java&quot;
+ excludes=&quot;mypackage/test/**&quot;/&gt;</pre>
+<p>copies the directory <code>${src}/resources</code> to <code>${dist}</code>
+recursively. All java files are copied, except for the files under the <code>mypackage/test</code>
+directory.</p>
+
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/copyfile.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/copyfile.html
new file mode 100644
index 00000000..e204a7e6
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/copyfile.html
@@ -0,0 +1,73 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Copyfile Task</title>
+</head>
+
+<body>
+
+<h2><a name="copyfile">Copyfile</a></h2>
+<h3><i>Deprecated</i></h3>
+<p><i>This task has been deprecated. Use the Copy task instead.</i></p>
+<h3>Description</h3>
+<p>Copies a file from the source to the destination. The file is only copied if
+the source file is newer than the destination file, or when the destination file
+does not exist.</p>
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">src</td>
+ <td valign="top">the filename of the file to copy.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">dest</td>
+ <td valign="top">the filename of the file where to copy to.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">filtering</td>
+ <td valign="top">indicates whether token filtering should take place during
+ the copy</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">forceoverwrite</td>
+ <td valign="top">overwrite existing files even if the destination
+ files are newer (default is false).</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+</table>
+<h3>Examples</h3>
+<blockquote>
+ <p><code>&lt;copyfile src=&quot;test.java&quot; dest=&quot;subdir/test.java&quot;/&gt;</code></p>
+ <p><code>&lt;copyfile src=&quot;${src}/index.html&quot; dest=&quot;${dist}/help/index.html&quot;/&gt;</code></p>
+</blockquote>
+
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/cvs.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/cvs.html
new file mode 100644
index 00000000..e941ed6d
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/cvs.html
@@ -0,0 +1,230 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+ <meta http-equiv="Content-Language" content="en-us">
+ <link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+ <title>CVS Task</title>
+</head>
+
+<body>
+
+<h2><a name="cvs">Cvs</a></h2>
+<h3>Description</h3>
+<p>Handles packages/modules retrieved from a
+<a href="http://www.nongnu.org/cvs/" target="_top">CVS</a> repository.</p>
+<p><b>Important:</b> This task needs &quot;<code>cvs</code>&quot; on the path. If it isn't, you will get
+an error (such as error <code>2</code> on windows). If <code>&lt;cvs&gt;</code> doesn't work, try to execute <code>cvs.exe</code>
+from the command line in the target directory in which you are working.
+Also note that this task assumes that the cvs executable is compatible
+with the Unix version from cvshome.org, this is not completely true
+for certain other cvs clients - like CVSNT for example - and some
+operation may fail when using such an incompatible client.
+</p>
+
+<p><b>CVSNT Note</b>: CVSNT prefers users to store the passwords
+inside the registry. If the <a href="cvspass.html">cvspass task</a>
+and the passfile attribute don't seem to work for you, the most likely
+reason is that CVSNT ignores your .cvspass file completely. See <a
+href="http://issues.apache.org/bugzilla/show_bug.cgi?id=21657#c5">bugzilla
+report 21657</a> for recommended workarounds.</p>
+
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">command</td>
+ <td valign="top">the CVS command to execute.</td>
+ <td align="center" valign="top">No, default &quot;checkout&quot;.</td>
+ </tr>
+ <tr>
+ <td valign="top">compression</td>
+ <td valign="top"><code>true</code> or <code>false</code> - if set
+ to true, this is the same as <code>compressionlevel=&quot;3&quot;</code></td>
+ <td align="center" valign="top">No. Defaults to false.</td>
+ </tr>
+ <tr>
+ <td valign="top">compressionlevel</td>
+ <td valign="top">A number between 1 and 9 (corresponding to
+ possible values for CVS' <code>-z#</code> argument). Any
+ other value is treated as <code>compression=&quot;false&quot;</code></td>
+ <td align="center" valign="top">No. Defaults to no compression.</td>
+ </tr>
+
+ <tr>
+ <td valign="top">cvsRoot</td>
+ <td valign="top">the <code>CVSROOT</code> variable.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">cvsRsh</td>
+ <td valign="top">the <code>CVS_RSH</code> variable.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">dest</td>
+ <td valign="top">the directory where the checked out files should
+ be placed. Note that this is different from CVS's <code>-d</code> command line
+ switch as Apache Ant will never shorten pathnames to avoid empty
+ directories.</td>
+ <td align="center" valign="top">No, default is project's basedir.</td>
+ </tr>
+ <tr>
+ <td valign="top">package</td>
+ <td valign="top">the package/module to check out. <b>Note:</b>
+ multiple attributes can be split using spaces. Use a nested
+ &lt;module&gt; element if you want to specify a module with
+ spaces in its name.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">tag</td>
+ <td valign="top">the tag of the package/module to check out.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">date</td>
+ <td valign="top">Use the most recent revision no later than the given date</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">quiet</td>
+ <td valign="top">suppress informational messages. This is the same as <code>-q</code> on the command line.</td>
+ <td align="center" valign="top">No, default &quot;false&quot;</td>
+ </tr>
+ <tr>
+ <td valign="top">reallyquiet</td>
+ <td valign="top">suppress all messages. This is the same as
+ <code>-Q</code> on the command line. <em>since Ant 1.6</em>.</td>
+ <td align="center" valign="top">No, default &quot;false&quot;</td>
+ </tr>
+ <tr>
+ <td valign="top">noexec</td>
+ <td valign="top">report only, don't change any files.</td>
+ <td align="center" valign="top">No, default to &quot;false&quot;</td>
+ </tr>
+ <tr>
+ <td valign="top">output</td>
+ <td valign="top">the file to direct standard output from the command.</td>
+ <td align="center" valign="top">No, default output to ANT Log as <code>MSG_INFO</code>.</td>
+ </tr>
+ <tr>
+ <td valign="top">error</td>
+ <td valign="top">the file to direct standard error from the command.</td>
+ <td align="center" valign="top">No, default error to ANT Log as <code>MSG_WARN</code>.</td>
+ </tr>
+ <tr>
+ <td valign="top">append</td>
+ <td valign="top">whether to append output/error when redirecting to a file.</td>
+ <td align="center" valign="top">No, default to &quot;false&quot;.</td>
+ </tr>
+ <tr>
+ <td valign="top">port</td>
+ <td valign="top">Port used by CVS to communicate with the server.</td>
+ <td align="center" valign="top">No, default port <code>2401</code>.</td>
+ </tr>
+ <tr>
+ <td valign="top">passfile</td>
+ <td valign="top">Password file to read passwords from.</td>
+ <td align="center" valign="top">No, default file <code>~/.cvspass</code>.</td>
+ </tr>
+ <tr>
+ <td valign="top">failonerror</td>
+ <td valign="top">Stop the build process if the command exits with a
+ return code other than <code>0</code>. Defaults to &quot;false&quot;</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+</table>
+
+<h3>Parameters specified as nested elements</h3>
+
+<h4>module</h4>
+
+<p>Specifies a package/module to work on, unlike the package attribute
+ modules specified using this attribute can contain spaces in their
+ name.</p>
+
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">name</td>
+ <td valign="top">The module's/package's name.</td>
+ <td align="center" valign="top">Yes.</td>
+ </tr>
+</table>
+
+<h3>Examples</h3>
+<pre> &lt;cvs cvsRoot=&quot;:pserver:anoncvs@cvs.apache.org:/home/cvspublic&quot;
+ package=&quot;ant&quot;
+ dest=&quot;${ws.dir}&quot;
+ /&gt;</pre>
+<p>checks out the package/module &quot;ant&quot; from the CVS
+repository pointed to by the <code>cvsRoot</code> attribute, and stores the files in &quot;<code>${ws.dir}</code>&quot;.</p>
+<pre> &lt;cvs dest=&quot;${ws.dir}&quot; command=&quot;update&quot;/&gt;</pre>
+<p>updates the package/module that has previously been checked out into
+&quot;<code>${ws.dir}</code>&quot;.</p>
+
+<pre> &lt;cvs command=&quot;-q diff -u -N&quot; output=&quot;patch.txt&quot;/&gt;</pre>
+
+<p>silently (<code>-q</code>) creates a file called <code>patch.txt</code> which contains a unified (<code>-u</code>) diff which includes new files added via &quot;cvs add&quot; (<code>-N</code>) and can be used as input to patch.
+The equivalent, using <code>&lt;commandline&gt;</code> elements, is:
+</p>
+<pre>
+&lt;cvs output=&quot;patch&quot;&gt;
+ &lt;commandline&gt;
+ &lt;argument value=&quot;-q&quot;/&gt;
+ &lt;argument value=&quot;diff&quot;/&gt;
+ &lt;argument value=&quot;-u&quot;/&gt;
+ &lt;argument value=&quot;-N&quot;/&gt;
+ &lt;/commandline&gt;
+&lt;/cvs&gt;
+</pre>
+or:
+<pre>
+&lt;cvs output=&quot;patch&quot;&gt;
+ &lt;commandline&gt;
+ &lt;argument line=&quot;-q diff -u -N&quot;/&gt;
+ &lt;/commandline&gt;
+&lt;/cvs&gt;
+</pre>
+<p>
+You may include as many <code>&lt;commandline&gt;</code> elements as you like.
+Each will inherit the <code>failonerror</code>, <code>compression</code>, and other &quot;global&quot; parameters
+from the <code>&lt;cvs&gt;</code> element.
+</p>
+
+
+<pre> &lt;cvs command=&quot;update -A -d&quot;/&gt;</pre>
+<p>Updates from the head of repository ignoring sticky bits (<code>-A</code>) and creating any new directories as necessary (<code>-d</code>).</p>
+<p>Note: the text of the command is passed to cvs &quot;as-is&quot; so any cvs options should appear
+before the command, and any command options should appear after the command as in the diff example
+above. See <a href="http://ximbiot.com/cvs/wiki/index.php?title=Category:User_Documentation" target="_top">the cvs manual</a> for details,
+specifically the <a href="http://ximbiot.com/cvs/wiki/index.php?title=CVS--Concurrent_Versions_System_v1.12.12.1:_Guide_to_CVS_commands#SEC116" target="_top">Guide to CVS commands</a></p>
+
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/cvspass.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/cvspass.html
new file mode 100644
index 00000000..185dde79
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/cvspass.html
@@ -0,0 +1,70 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>CVSPass Task</title>
+</head>
+
+<body>
+
+<h2><a name="cvs">cvspass</a></h2>
+<h3>Description</h3>
+<p>Adds entries to a .cvspass file. Adding entries to this file has the same affect as a cvs login command.</p>
+
+<p><b>CVSNT Note</b>: CVSNT prefers users to store the passwords
+inside the registry. If the task doesn't seem to work for you, the
+most likely reason is that CVSNT ignores your .cvspass file
+completely. See <a
+href="http://issues.apache.org/bugzilla/show_bug.cgi?id=21657#c5">bug
+zilla report 21657</a> for recommended workarounds.</p>
+
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">cvsroot</td>
+ <td valign="top">the CVS repository to add an entry for.</td>
+ <td align="center" valign="top">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">password</td>
+ <td valign="top">Password to be added to the password file.</td>
+ <td align="center" valign="top">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">passfile</td>
+ <td valign="top">Password file to add the entry to.</td>
+ <td align="center" valign="top">No, default is <code>~/.cvspass</code>.</td>
+ </tr>
+</table>
+<h3>Examples</h3>
+<pre> &lt;cvspass cvsroot=&quot;:pserver:anoncvs@cvs.apache.org:/home/cvspublic&quot;
+ password=&quot;anoncvs&quot;
+ /&gt;</pre>
+<p>Adds an entry into the ~/.cvspass password file.</p>
+
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/cvstagdiff.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/cvstagdiff.html
new file mode 100644
index 00000000..5350d8ef
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/cvstagdiff.html
@@ -0,0 +1,241 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>CvsTagDiff Task</title>
+</head>
+<body>
+<h2><a name="cvstagdiff">CvsTagDiff</a></h2>
+<h3>Description</h3>
+<p>Generates an XML-formatted report file of the changes between two tags or dates recorded in a
+<a href="http://www.nongnu.org/cvs/" target="_top">CVS</a> repository. </p>
+<p><b>Important:</b> This task needs &quot;<code>cvs</code>&quot; on the path. If it isn't, you will get
+an error (such as error <code>2</code> on windows). If <code>&lt;cvs&gt;</code> doesn't work, try to execute <code>cvs.exe</code>
+from the command line in the target directory in which you are working.
+Also note that this task assumes that the cvs executable is compatible
+with the Unix version from cvshome.org, this is not completely true
+for certain other cvs clients - like CVSNT for example - and some
+operation may fail when using such an incompatible client.
+</p>
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">startTag</td>
+ <td valign="top">The earliest tag from which diffs are to be
+ included in the report.</td>
+ <td align="center" valign="top" rowspan="2">exactly one of the two.</td>
+ </tr>
+ <tr>
+ <td valign="top">startDate</td>
+ <td valign="top">The earliest date from which diffs are to be
+ included in the report.<br>
+ accepts all formats accepted by the cvs command for -D date_spec arguments</td>
+ </tr>
+ <tr>
+ <td valign="top">endTag</td>
+ <td valign="top">The latest tag from which diffs are to be
+ included in the report.</td>
+ <td align="center" valign="top" rowspan="2">exactly one of the two.</td>
+ </tr>
+ <tr>
+ <td valign="top">endDate</td>
+ <td valign="top">The latest date from which diffs are to be
+ included in the report.<br>
+ accepts all formats accepted by the cvs command for -D date_spec arguments</td>
+ </tr>
+ <tr>
+ <td valign="top">destfile</td>
+ <td valign="top">The file in which to write the diff report.</td>
+ <td align="center" valign="top">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">ignoreRemoved</td>
+ <td valign="top">When set to true, the report will not include any
+ removed files. <em>Since Apache Ant 1.8.0</em></td>
+ <td align="center" valign="top">No, defaults to false.</td>
+</table>
+
+<h3>Parameters inherited from the <code>cvs</code> task</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">compression</td>
+ <td valign="top"><code>true</code>, <code>false</code>, or the number 1-9 (corresponding to possible values for CVS <code>-z#</code> argument). Any other value is treated as false</td>
+ <td align="center" valign="top">No. Defaults to no compression. if passed <code>true</code>, level 3 compression is assumed.</td>
+ </tr>
+ <tr>
+ <td valign="top">cvsRoot</td>
+ <td valign="top">the CVSROOT variable.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">cvsRsh</td>
+ <td valign="top">the CVS_RSH variable.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">package</td>
+ <td valign="top">the package/module to analyze.<br>
+ Since Ant 1.6
+ multiple packages separated by spaces are possible.
+ aliases corresponding to different modules are also possible
+ Use a nested &lt;module&gt; element if you want to specify a module with
+ spaces in its name.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <td align="center" valign="top">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">quiet</td>
+ <td valign="top">suppress informational messages.</td>
+ <td align="center" valign="top">No, default &quot;false&quot;</td>
+ </tr>
+ <tr>
+ <td valign="top">port</td>
+ <td valign="top">Port used by CVS to communicate with the server.</td>
+ <td align="center" valign="top">No, default port 2401.</td>
+ </tr>
+ <tr>
+ <td valign="top">passfile</td>
+ <td valign="top">Password file to read passwords from.</td>
+ <td align="center" valign="top">No, default file <code>~/.cvspass</code>.</td>
+ </tr>
+ <tr>
+ <td valign="top">failonerror</td>
+ <td valign="top">Stop the buildprocess if the command exits with a
+ returncode other than 0. Defaults to false</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+</table>
+
+<h3>Parameters specified as nested elements</h3>
+
+<h4>module</h4>
+
+<p>Specifies a package/module to work on, unlike the package attribute
+ modules specified using this attribute can contain spaces in their
+ name.</p>
+
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">name</td>
+ <td valign="top">The module's/package's name.</td>
+ <td align="center" valign="top">Yes.</td>
+ </tr>
+</table>
+
+<h3>Examples</h3>
+<pre> &lt;cvstagdiff cvsRoot=&quot;:pserver:anoncvs@cvs.apache.org:/home/cvspublic&quot;
+ destfile=&quot;tagdiff.xml&quot;
+ package=&quot;ant&quot;
+ startTag=&quot;ANT_14&quot;
+ endTag=&quot;ANT_141&quot;
+ /&gt;</pre>
+
+<p>Generates a tagdiff report for all the changes that have been made
+in the <code>ant</code> module between the tags <code>ANT_14</code> and <code>ANT_141</code>.
+It writes these changes into the file <code>tagdiff.xml</code>.</p>
+
+<pre> &lt;cvstagdiff
+ destfile=&quot;tagdiff.xml&quot;
+ package=&quot;ant&quot;
+ startDate=&quot;2002-01-01&quot;
+ endDate=&quot;2002-31-01&quot;
+ /&gt;</pre>
+
+<p>Generates a tagdiff report for all the changes that have been made
+in the <code>ant</code> module in january 2002. In this example <code>cvsRoot</code>
+has not been set. The current <code>cvsRoot</code> will be used (assuming the build is started
+from a folder stored in <code>cvs</code>.
+It writes these changes into the file <code>tagdiff.xml</code>.</p>
+
+<pre> &lt;cvstagdiff
+ destfile=&quot;tagdiff.xml&quot;
+ package=&quot;ant jakarta-gump&quot;
+ startDate=&quot;2003-01-01&quot;
+ endDate=&quot;2003-31-01&quot;
+ /&gt;</pre>
+
+<p>Generates a tagdiff report for all the changes that have been made
+in the <code>ant</code> and <code>jakarta-gump</code> modules in january 2003.
+In this example <code>cvsRoot</code>
+has not been set. The current <code>cvsRoot</code> will be used (assuming the build is started
+from a folder stored in <code>cvs</code>.
+It writes these changes into the file <code>tagdiff.xml</code>.</p>
+
+<h4>Generate Report</h4>
+<p>Ant includes a basic XSLT stylesheet that you can use to generate
+a HTML report based on the xml output. The following example illustrates
+how to generate a HTML report from the XML report.</p>
+
+<pre>
+ &lt;style in="tagdiff.xml"
+ out="tagdiff.html"
+ style="${ant.home}/etc/tagdiff.xsl"&gt;
+ &lt;param name="title" expression="Ant Diff"/&gt;
+ &lt;param name="module" expression="ant"/&gt;
+ &lt;param name="cvsweb" expression="http://cvs.apache.org/viewcvs/"/&gt;
+ &lt;/style&gt;
+</pre>
+
+<h4>Output</h4>
+<p>
+The cvsroot and package attributes of the tagdiff element are new in ant 1.6.<br>
+Notes on entry attributes :
+<table border="1">
+<tr><th>Attribute</th><th>Comment</th></tr>
+<tr><td>name</td><td>when reporting on one package, the package name is removed from the output</td></tr>
+<tr><td>revision</td><td>supplied for files which exist at the end of the reporting period</td></tr>
+<tr><td>prevrevision</td><td>supplied for files which exist at the beginning of the reporting period.<br>
+Old CVS servers do not supply it for deleted files. CVS 1.12.2 supplies it.</td></tr>
+</table>
+</p>
+<pre>
+&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
+&lt;tagdiff startTag=&quot;ANT_14&quot; endTag=&quot;ANT_141&quot;
+cvsroot=&quot;:pserver:anoncvs@cvs.apache.org:/home/cvspublic&quot; package=&quot;ant&quot;&gt;
+ &lt;entry&gt;
+ &lt;file&gt;
+ &lt;name&gt;src/main/org/apache/tools/ant/DirectoryScanner.java&lt;/name&gt;
+ &lt;revision&gt;1.15.2.1&lt;/revision&gt;
+ &lt;prevrevision&gt;1.15&lt;/prevrevision&gt;
+ &lt;/file&gt;
+ &lt;/entry&gt;
+&lt;/tagdiff&gt;
+</pre>
+
+
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/cvsversion.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/cvsversion.html
new file mode 100644
index 00000000..09e7cee1
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/cvsversion.html
@@ -0,0 +1,108 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+ <meta http-equiv="Content-Language" content="en-us">
+ <link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+ <title>CVSVersion Task</title>
+</head>
+
+<body>
+
+<h2><a name="cvs">CvsVersion</a></h2>
+<h3>Description</h3>
+<p>
+This task allows to retrieve a CVS client and server version.
+ <i>Since Apache Ant 1.6.1.</i>
+</p>
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td colspan="3">Attributes from parent Cvs task which are meaningful here</td>
+ </tr>
+ <tr>
+ <td valign="top">cvsRoot</td>
+ <td valign="top">the <code>CVSROOT</code> variable.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">cvsRsh</td>
+ <td valign="top">the <code>CVS_RSH</code> variable.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">dest</td>
+ <td valign="top">directory containing the checked out version of the project</td>
+ <td align="center" valign="top">No, default is project's basedir.</td>
+ </tr>
+ <tr>
+ <td valign="top">package</td>
+ <td valign="top">the package/module to check out.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">port</td>
+ <td valign="top">Port used by CVS to communicate with the server.</td>
+ <td align="center" valign="top">No, default port 2401.</td>
+ </tr>
+ <tr>
+ <td valign="top">passfile</td>
+ <td valign="top">Password file to read passwords from.</td>
+ <td align="center" valign="top">No, default file ~/.cvspass.</td>
+ </tr>
+ <tr>
+ <td valign="top">failonerror</td>
+ <td valign="top">Stop the build process if the command exits with a
+ return code other than <code>0</code>. Defaults to false</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td colspan="3">Specific attributes</td>
+ </tr>
+ <tr>
+ <td valign="top">clientversionproperty</td>
+ <td valign="top">Name of a property where the cvsclient version
+ should be stored</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">serverversionproperty</td>
+ <td valign="top">Name of a property where the cvs server version
+ should be stored</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+</table>
+<h3>Examples</h3>
+<pre> &lt;cvsversion cvsRoot=&quot;:pserver:anoncvs@cvs.apache.org:/home/cvspublic&quot;
+ passfile=&quot;/home/myself/.cvspass&quot;
+ serverversionproperty=&quot;apachecvsversion&quot;
+ clientversionproperty=&quot;localcvsversion&quot;
+ /&gt;</pre>
+<p>finds out the cvs client and server versions and stores the versions in the
+properties called apachecvsversion and localcvsversion</p>
+
+
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/defaultexcludes.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/defaultexcludes.html
new file mode 100644
index 00000000..5511b901
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/defaultexcludes.html
@@ -0,0 +1,107 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>DefaultExcludes Task</title>
+</head>
+
+<body>
+
+<h2><a name="echo">DefaultExcludes</a></h2>
+
+<p><em>since Apache Ant 1.6</em></p>
+
+<h3>Description</h3>
+<p>Alters the default excludes for all subsequent processing in the
+build, and prints out the current default excludes if desired.
+
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">echo</td>
+ <td valign="top">whether or not to print out the default excludes.(defaults to false)</td>
+ <td valign="top" align="center">attribute "true" required if no
+ other attribute specified</td>
+ </tr>
+ <tr>
+ <td valign="top">default</td>
+ <td valign="top">go back to hard wired default excludes</td>
+ <td valign="top" align="center">attribute "true" required if no
+ if no other attribute is specified</td>
+ </tr>
+ <tr>
+ <td valign="top">add</td>
+ <td valign="top">the pattern to add to the default excludes</td>
+ <td valign="top" align="center">if no other attribute is specified</td>
+ </tr>
+ <tr>
+ <td valign="top">remove</td>
+ <td valign="top">remove the specified pattern from the default excludes</td>
+ <td valign="top" align="center">if no other attribute is specified</td>
+ </tr>
+</table>
+
+<h3>Examples</h3>
+
+<p>Print out the default excludes</p>
+
+<pre> &lt;defaultexcludes echo=&quot;true&quot;/&gt;</pre>
+
+<p>Print out the default excludes and exclude all *.bak files in
+<strong>all</strong> further processing</p>
+
+<pre> &lt;defaultexcludes echo=&quot;true&quot; add=&quot;**/*.bak&quot;/&gt;</pre>
+
+<p>Silently allow several fileset based tasks to operate on emacs
+backup files and then restore normal behavior</p>
+
+<pre>
+ &lt;defaultexcludes remove=&quot;**/*~&quot;/&gt;
+
+ (do several fileset based tasks here)
+
+ &lt;defaultexcludes default=&quot;true&quot;/&gt;
+</pre>
+
+<h3>Notes</h3>
+By default the pattern <tt>**/.svn</tt> and <tt>**/.svn/**</tt> are set as default
+excludes. With version 1.3 Subversion supports the
+<a target="_blank" href="http://subversion.apache.org/docs/release-notes/1.3.html#_svn-hack">&quot;_svn hack&quot;</a>.
+That means, that the svn-libraries evaluate environment variables and use <i>.svn</i>
+or <i>_svn</i> directory regarding to that value. We had chosen not to evaluate environment variables to
+get a more reliable build. Instead you have to change the settings by yourself by changing
+the exclude patterns:
+<pre>
+ &lt;defaultexcludes remove=&quot;**/.svn&quot;/&gt;
+ &lt;defaultexcludes remove=&quot;**/.svn/**&quot;/&gt;
+ &lt;defaultexcludes add=&quot;**/_svn&quot;/&gt;
+ &lt;defaultexcludes add=&quot;**/_svn/**&quot;/&gt;
+</pre>
+
+
+
+
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/delete.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/delete.html
new file mode 100644
index 00000000..635b10f1
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/delete.html
@@ -0,0 +1,228 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Delete Task</title>
+</head>
+
+<body>
+
+<h2><a name="delete">Delete</a></h2>
+<h3>Description</h3>
+<p>Deletes a single file, a specified directory and all its files and
+subdirectories, or a set of files specified by one or more
+<a href="../Types/resources.html#collection">resource collection</a>s.
+The literal implication of <code>&lt;fileset&gt;</code> is that
+directories are not included; however the removal of empty directories can
+be triggered when using nested filesets by setting the
+<code>includeEmptyDirs</code> attribute to <i>true</i>. Note that this
+attribute is meaningless in the context of any of the various resource
+collection types that <i>do</i> include directories, but that no attempt
+will be made to delete non-empty directories in any case. Whether a
+directory is empty or not is decided by looking into the filesystem -
+include or exclude patterns don't apply here.</p>
+<p>
+If you use this task to delete temporary files created by editors
+and it doesn't seem to work, read up on the
+<a href="../dirtasks.html#defaultexcludes">default exclusion set</a>
+in <strong>Directory-based Tasks</strong>, and see the
+<code>defaultexcludes</code> attribute below.
+
+<p>For historical reasons <code>&lt;delete dir="x"/&gt;</code> is
+ different from <code>&lt;delete&gt;&lt;fileset
+ dir="x"/&gt;&lt;/delete&gt;</code>, it will try to remove everything
+ inside "x" including "x" itself, not taking default excludes into
+ account, blindly following all symbolic links. If you need more
+ control, use a nested <code>&lt;fileset&gt;</code>.</p>
+
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">file</td>
+ <td valign="top">The file to delete, specified as either the simple
+ filename (if the file exists in the current base directory), a
+ relative-path filename, or a full-path filename.</td>
+ <td align="center" valign="middle" rowspan="2">At least one of the two,
+ unless nested resource collections are specified
+ </tr>
+ <tr>
+ <td valign="top">dir</td>
+ <td valign="top">The directory to delete, including all its files and
+ subdirectories.<br>
+ <b>Note:</b> <code>dir</code> is <em>not</em> used
+ to specify a directory name for <code>file</code>; <code>file</code>
+ and <code>dir</code> are independent of each other.<br>
+ <b>WARNING:</b> Do <b>not</b> set <code>dir</code> to
+ <code>&quot;.&quot;</code>, <code>&quot;${basedir}&quot;</code>,
+ or the full-pathname equivalent unless you truly <em>intend</em> to
+ recursively remove the entire contents of the current base directory
+ (and the base directory itself, if different from the current working
+ directory).</td>
+ </tr>
+ <tr>
+ <td valign="top">verbose</td>
+ <td valign="top">Whether to show the name of each deleted file.</td>
+ <td align="center" valign="top">No, default &quot;false&quot;</i></td>
+ </tr>
+ <tr>
+ <td valign="top">quiet</td>
+ <td valign="top">If the specified file or directory does not exist,
+ do not display a diagnostic message (unless Apache Ant
+ has been invoked with the <code>-verbose</code> or
+ <code>-debug</code> switches) or modify the exit status to
+ reflect an error.
+ When set to &quot;true&quot;, if a file or directory cannot be deleted,
+ no error is reported. This setting emulates the
+ <code>-f</code> option to the Unix <em>rm</em> command.
+ Setting this to &quot;true&quot; implies setting
+ <code>failonerror</code> to &quot;false&quot;.
+ </td>
+ <td align="center" valign="top">No, default &quot;false&quot;</td>
+ </tr>
+ <tr>
+ <td valign="top">failonerror</td>
+ <td valign="top">Controls whether an error (such as a failure to
+ delete a file) stops the build or is merely reported to the screen.
+ Only relevant if <code>quiet</code> is &quot;false&quot;.</td>
+ <td align="center" valign="top">No, default &quot;true&quot;</td>
+ </tr>
+ <tr>
+ <td valign="top">includeemptydirs</td>
+ <td valign="top">Whether to delete empty directories
+ when using filesets.</td>
+ <td align="center" valign="top">No, default &quot;false&quot;</td>
+ </tr>
+ <tr>
+ <td valign="top">includes</td>
+ <td valign="top"><em>Deprecated.</em> Use resource collections.
+ Comma- or space-separated list of patterns of
+ files that must be deleted. All files are relative to the directory
+ specified in <code>dir</code>.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">includesfile</td>
+ <td valign="top"><em>Deprecated.</em> Use resource collections.
+ The name of a file. Each line of
+ this file is taken to be an include pattern.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">excludes</td>
+ <td valign="top"><em>Deprecated.</em> Use resource collections.
+ Comma- or space-separated list of patterns of
+ files that must be excluded from the deletion list.
+ All files are relative to the directory specified in <code>dir</code>.
+ No files (except default excludes) are excluded when omitted.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">excludesfile</td>
+ <td valign="top"><em>Deprecated.</em> Use resource collections.
+ The name of a file. Each line of
+ this file is taken to be an exclude pattern</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">defaultexcludes</td>
+ <td valign="top"><em>Deprecated.</em> Use resource collections.
+ Whether to use <a href="../dirtasks.html#defaultexcludes">
+ default excludes.</a></td>
+ <td align="center" valign="top">No, default &quot;true&quot;</td>
+ </tr>
+ <tr>
+ <td valign="top">deleteonexit</td>
+ <td valign="top">
+ Indicates whether to use File#deleteOnExit() if there is a
+ failure to delete a file, this causes the jvm to attempt
+ to delete the file when the jvm process is terminating.
+ <em>Since Ant 1.6.2</em></td>
+ <td align="center" valign="top">No, default &quot;false&quot;</td>
+ </tr>
+ <tr>
+ <td valign="top">removeNotFollowedSymlinks</td>
+ <td valign="top">
+ Whether symbolic links (not the files/directories they link to)
+ should be removed if they haven't been followed because
+ followSymlinks was false or the maximum number of symbolic links
+ was too big.
+ <em>Since Ant 1.8.0</em></td>
+ <td align="center" valign="top">No, default &quot;false&quot;</td>
+ </tr>
+ <tr>
+ <td valign="top">performGCOnFailedDelete</td>
+ <td valign="top">
+ If Ant fails to delete a file or directory it will retry the
+ operation once. If this flag is set to true it will perform a
+ garbage collection before retrying the delete.<br/>
+ Setting this flag to true is known to resolve some problems on
+ Windows (where it defaults to true) but also for directory trees
+ residing on an NFS share.
+ <em>Since Ant 1.8.3</em></td>
+ <td align="center" valign="top">No, default &quot;true&quot; on
+ Windows and &quot;true&quot; on any other OS.</td>
+ </tr>
+</table>
+
+<h3>Examples</h3>
+<pre> &lt;delete file=&quot;/lib/ant.jar&quot;/&gt;</pre>
+<p>deletes the file <code>/lib/ant.jar</code>.</p>
+<pre> &lt;delete dir=&quot;lib&quot;/&gt;</pre>
+<p>deletes the <code>lib</code> directory, including all files
+and subdirectories of <code>lib</code>.</p>
+
+<pre> &lt;delete&gt;
+ &lt;fileset dir=&quot;.&quot; includes=&quot;**/*.bak&quot;/&gt;
+ &lt;/delete&gt;
+</pre>
+<p>deletes all files with the extension <code>.bak</code> from the current directory
+and any subdirectories.</p>
+
+<pre> &lt;delete includeEmptyDirs=&quot;true&quot;&gt;
+ &lt;fileset dir=&quot;build&quot;/&gt;
+ &lt;/delete&gt;
+</pre>
+<p>deletes all files and subdirectories of <code>build</code>, including
+<code>build</code> itself.</p>
+
+<pre> &lt;delete includeemptydirs=&quot;true&quot;&gt;
+ &lt;fileset dir=&quot;build&quot; includes=&quot;**/*&quot;/&gt;
+ &lt;/delete&gt;
+</pre>
+<p>deletes all files and subdirectories of <code>build</code>, without
+<code>build</code> itself.</p>
+
+<pre> &lt;delete includeemptydirs=&quot;true&quot;&gt;
+ &lt;fileset dir=&quot;src&quot; includes=&quot;**/.svn/&quot; defaultexcludes=&quot;false&quot;/&gt;
+ &lt;/delete&gt;
+</pre>
+<p>deletes the subversion metadata directories under <code>src</code>. Because <code>.svn</code>
+is on of the <a href="../dirtasks.html#defaultexcludes">default excludes</a> you have to use the
+<code>defaultexcludes</code> flag, otherwise Ant wont delete these directories and the files in it.</p>
+
+
+
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/deltree.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/deltree.html
new file mode 100644
index 00000000..98adf4f5
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/deltree.html
@@ -0,0 +1,56 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Deltree Task</title>
+</head>
+
+<body>
+
+<h2><a name="deltree">Deltree</a></h2>
+<h3><i>Deprecated</i></h3>
+<p><i>This task has been deprecated. Use the Delete task instead.</i></p>
+<h3>Description</h3>
+<p>Deletes a directory with all its files and subdirectories.</p>
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">dir</td>
+ <td valign="top">the directory to delete.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+</table>
+<h3>Examples</h3>
+<pre> &lt;deltree dir=&quot;dist&quot;/&gt;</pre>
+<p>deletes the directory <code>dist</code>, including its files and
+subdirectories.</p>
+<pre> &lt;deltree dir=&quot;${dist}&quot;/&gt;</pre>
+<p>deletes the directory <code>${dist}</code>, including its files and
+subdirectories.</p>
+
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/depend.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/depend.html
new file mode 100644
index 00000000..a0943197
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/depend.html
@@ -0,0 +1,216 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Depend Task</title>
+</head>
+
+<body>
+
+<h2>Depend</h2>
+
+A task to manage Java class file dependencies.
+
+<h3>Description</h3>
+
+<p>
+The depend task works by determining which classes are out of date with
+respect to their source and then removing the class files of any other
+classes which depend on the out-of-date classes.
+</p>
+
+<p> To determine the class dependencies, the depend task analyzes the class
+files of all class files passed to it. Depend does not parse your source code in
+any way but relies upon the class references encoded into the class files by the
+compiler. This is generally faster than parsing the Java source.</p>
+
+<p>
+To learn more about how this information is obtained from the class files,
+please refer to <a href="http://docs.oracle.com/javase/specs/">the Java
+Virtual Machine Specification</a>
+</p>
+
+<p> Since a class' dependencies only change when the class itself changes, the
+depend task is able to cache dependency information. Only those class files
+which have changed will have their dependency information re-analysed. Note that
+if you change a class' dependencies by changing the source, it will be
+recompiled anyway. You can examine the dependency files created to understand
+the dependencies of your classes. Please do not rely, however, on the format of
+the information, as it may change in a later release. </p>
+
+<p> Once depend discovers all of the class dependencies, it &quot;inverts&quot;
+this relation to determine, for each class, which other classes are dependent
+upon it. This &quot;affects&quot; list is used to discover which classes are
+invalidated by the out of date class. The class files of the invalidated
+classes are removed, triggering the compilation of the affected classes. </p>
+
+<p> The depend task supports an attribute, &quot;closure&quot; which controls
+whether depend will only consider direct class-class relationships or whether it
+will also consider transitive, indirect relationships. For example, say there
+are three classes, A, which depends on B, which in-turn depend on C. Now say
+that class C is out of date. Without closure, only class B would be removed by
+depend. With closure set, class A would also be removed. Normally direct
+relationships are sufficient - it is unusual for a class to depend on another
+without having a direct relationship. With closure set, you will notice that
+depend typically removes far more class files. </p>
+
+<p>The classpath attribute for <code>&lt;depend&gt;</code> is optional. If it is present,
+depend will check class dependencies against classes and jars on this classpath.
+Any classes which depend on an element from this classpath and which are older
+than that element will be deleted. A typical example where you would use this
+facility would be where you are building a utility jar and want to make sure
+classes which are out of date with respect to this jar are rebuilt. You should
+<b>not</b> include jars in this classpath which you do not expect to change,
+such as the JDK runtime jar or third party jars, since doing so will just slow
+down the dependency check. This means that if you do use a classpath for the
+depend task it may be different from the classpath necessary to actually
+compile your code.</p>
+
+<h3>Performance</h3>
+
+<p> The performance of the depend task is dependent on a
+number of factors such as class relationship complexity and how many class files
+are out of date. The decision about whether it is cheaper to just recompile all
+classes or to use the depend task will depend on the size of your project and
+how interrelated your classes are. </p>
+
+
+<h3>Limitations</h3>
+
+<p> There are some source dependencies which depend will not detect. </p>
+
+<ul>
+<li>If the Java compiler optimizes away a class relationship,
+ there can be a source dependency without a class dependency. </li>
+
+<li>Non public classes cause two problems. Firstly depend cannot relate
+ the class file to a source file. In the future this may be addressed
+ using the source file attribute in the classfile. Secondly, neither
+ depend nor the compiler tasks can detect when a non public class is
+ missing. Inner classes are handled by the depend task.</li>
+</ul>
+
+The most obvious example of these limitations is that the task can't tell
+which classes to recompile when a constant primitive data type exported
+by other classes is changed. For example, a change in the definition of
+something like
+<pre>
+public final class Constants {
+ public final static boolean DEBUG=false;
+}
+</pre> will not be picked up by other classes.
+
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">srcDir</td>
+ <td valign="top">This is the directory where the source exists. depend
+will examine this to determine which classes are out of date. If you use multiple
+source directories you can pass this attribute a path of source directories.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">destDir</td>
+ <td valign="top">This is the root directory of the class files which
+will be analysed. If this is not present, the srcdir is used.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">cache</td>
+ <td valign="top">This is a directory in which depend can store and
+retrieve dependency information. If this is not present, depend will not
+use a cache </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">closure</td>
+ <td valign="top">This attribute controls whether depend only removes
+classes which directly depend on out of date classes. If this is set to true,
+depend will traverse the class dependency graph deleting all affected
+classes. Defaults to false</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">dump</td>
+ <td valign="top">If true the dependency information will be written to the debug level log
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">classpath</td>
+ <td valign="top">The classpath containing jars and classes for which <code>&lt;depend&gt;</code> should also
+ check dependencies</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">warnOnRmiStubs</td>
+ <td valign="top">Flag to disable warnings about files that look like rmic generated stub/skeleton
+ classes, and which have no .java source. Useful when doing rmi development. </td>
+ <td valign="top" align="center">No, default=true</td>
+ </tr>
+</table>
+
+<h3>Parameters specified as nested elements</h3>
+<p>The <code>depend</code> task's <code>classpath</code> attribute is a
+<a href="../using.html#path">PATH-like structure</a> and can also be set
+via a nested <code>&lt;classpath&gt;</code> element.</p>
+
+<p>Additionally,
+this task forms an implicit
+<a href="../Types/fileset.html">FileSet</a>
+and supports most attributes of
+<code>&lt;fileset&gt;</code> (<code>dir</code> becomes <code>srcdir</code>),
+as well as the nested <code>&lt;include&gt;</code>,
+<code>&lt;exclude&gt;</code>, and <code>&lt;patternset&gt;</code> elements.
+
+<h3>Examples</h3>
+<pre>&lt;depend srcdir=&quot;${java.dir}&quot;
+ destdir=&quot;${build.classes}&quot;
+ cache=&quot;depcache&quot;
+ closure=&quot;yes&quot;/&gt;</pre>
+
+<p>removes any classes in the <code>${build.classes}</code> directory
+that depend on out-of-date classes. Classes are considered out-of-date with
+respect to the source in the <code>${java.dir}</code> directory, using the same
+mechanism as the <code>&lt;javac&gt;</code> task. In this example, the
+<code>&lt;depend&gt;</code> task caches its dependency
+information in the <code>depcache</code> directory. </p>
+
+<pre>
+&lt;depend srcdir=&quot;${java.dir}&quot; destdir=&quot;${build.classes}&quot;
+ cache=&quot;depcache&quot; closure=&quot;yes&quot;&gt;
+ &lt;include name=&quot;**/*.java&quot;/&gt;
+ &lt;excludesfile name=&quot;${java.dir}/build_excludes&quot;/&gt;
+&lt;/depend&gt;
+</pre>
+<p>does the same as the previous example, but explicitly includes all
+<code>.java</code> files, except those that match the list given
+in <code>${java.dir}/build_excludes</code>.</p>
+
+
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/dependset.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/dependset.html
new file mode 100644
index 00000000..34ec238b
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/dependset.html
@@ -0,0 +1,171 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>DependSet Task</title>
+</head>
+
+<body>
+
+<h2>DependSet</h2>
+
+A task to manage arbitrary dependencies between resources.
+
+<h3>Description</h3>
+
+<p>
+The dependset task compares a set of sources with a set of target
+files. If any of the sources has been modified more recently than
+any of the target files, all of the target files are removed.
+</p>
+<p>
+Sources and target files are specified via nested
+<a href="../Types/resources.html#collection">Resource Collection</a>s;
+sources can be resources of any type, while targets are restricted to files
+only. At least one set of sources and one set of targets is required.
+</p>
+<p>
+Use a FileSet when you want to use wildcard include or exclude
+patterns and don't care about missing files. Use a FileList when you
+want to consider the non-existence of a file as if it were out of
+date. If there are any non-existing files in any source or target
+FileList, all target files will be removed.
+</p>
+<p>
+DependSet is useful to capture dependencies that are not or cannot be
+determined algorithmically. For example, the <code>&lt;style&gt;</code> task only
+compares the source XML file and XSLT stylesheet against the target
+file to determined whether to restyle the source. Using dependset you
+can extend this dependency checking to include a DTD or XSD file as
+well as other stylesheets imported by the main stylesheet.
+</p>
+
+<h3>Parameters</h3>
+
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td valign="top" align="center"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">verbose</td>
+ <td valign="top">Makes the task list all deleted targets files
+ and the reason why they get deleted.</td>
+ <td align="center" valign="top" rowspan="2">No</td>
+ </tr>
+</table>
+
+<h3>Parameters Specified as Nested Elements</h3>
+
+<h4>sources</h4>
+
+<p>The <code>&lt;sources&gt;</code> element is a
+<a href="../Types/resources.html#union">Union</a> into which
+arbitrary resource collections can be nested. <b>Since Apache Ant 1.7</b>
+</p>
+
+<h4>srcfileset</h4>
+
+<p>
+The nested <code>&lt;srcfileset&gt;</code> element specifies a <a
+href="../Types/fileset.html">FileSet</a>. All files included in
+this fileset will be compared against all files included in all of the
+<code>&lt;targetfileset&gt;</code> filesets and <code>&lt;targetfilelist&gt;</code>
+filelists. Multiple <code>&lt;srcfileset&gt;</code> filesets may be specified.
+</p>
+
+<h4>srcfilelist</h4>
+
+<p>
+The nested <code>&lt;srcfilelist&gt;</code> element specifies a <a
+href="../Types/filelist.html">FileList</a>. All files included in
+this filelist will be compared against all files included in all of the
+<code>&lt;targetfileset&gt;</code> filesets and <code>&lt;targetfilelist&gt;</code>
+filelists. Multiple <code>&lt;srcfilelist&gt;</code> filelists may be specified.
+</p>
+
+<h4>targets</h4>
+
+<p>The <code>&lt;targets&gt;</code> element is a
+<a href="../using.html#path">Path</a> and thus can
+include any filesystem-based resource. <b>Since Ant 1.7</b>
+</p>
+
+<h4>targetfileset</h4>
+
+<p>
+The nested <code>&lt;targetfileset&gt;</code> element specifies a <a
+href="../Types/fileset.html">FileSet</a>. All files included in
+this fileset will be compared against all files included in all of the
+<code>&lt;srcfileset&gt;</code> filesets and <code>&lt;sourcefilelist&gt;</code>
+filelists, and if any are older, they are all deleted.
+Multiple <code>&lt;targetfileset&gt;</code> filesets may be specified.
+</p>
+
+<h4>targetfilelist</h4>
+
+<p>
+The nested <code>&lt;targetfilelist&gt;</code> element specifies a <a
+href="../Types/filelist.html">FileList</a>. All files included in
+this filelist will be compared against all files included in all of the
+<code>&lt;srcfileset&gt;</code> filesets and <code>&lt;sourcefilelist&gt;</code>
+filelists, and if any are older, they are all deleted.
+Multiple <code>&lt;targetfilelist&gt;</code> filelists may be specified.
+</p>
+
+<h3>Examples</h3>
+<blockquote> <pre>
+ &lt;dependset&gt;
+ &lt;srcfilelist
+ dir = &quot;${dtd.dir}&quot;
+ files = &quot;paper.dtd,common.dtd&quot;/&gt;
+ &lt;srcfilelist
+ dir = &quot;${xsl.dir}&quot;
+ files = &quot;common.xsl&quot;/&gt;
+ &lt;srcfilelist
+ dir = &quot;${basedir}&quot;
+ files = &quot;build.xml&quot;/&gt;
+ &lt;targetfileset
+ dir = &quot;${output.dir}&quot;
+ includes = &quot;**/*.html&quot;/&gt;
+ &lt;/dependset&gt; </pre>
+</blockquote>
+
+<p>
+In this example derived HTML files in the ${output.dir} directory
+will be removed if any are out-of-date with respect to:</p>
+<ol>
+<li>the DTD of their source XML files</li>
+<li>a common DTD (imported by the main DTD)</li>
+<li>a subordinate XSLT stylesheet (imported by the main stylesheet), or</li>
+<li>the buildfile</li>
+</ol>
+
+<p>
+If any of the sources in the above example does not exist, all
+target files will also be removed. To ignore missing sources instead,
+use filesets instead of filelists for the sources.
+</p>
+
+
+
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/diagnostics.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/diagnostics.html
new file mode 100644
index 00000000..cdb16930
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/diagnostics.html
@@ -0,0 +1,49 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Diagnostics Task</title>
+</head>
+
+<body>
+
+<h2><a name="diagnostics">Diagnostics</a></h2>
+<h3>Diagnostics</h3>
+<p>
+Runs Apache Ant's <code>-diagnostics</code> code inside Ant itself. This is good for
+debugging Ant's configuration under an IDE.
+<b>Since Ant 1.7.0</b>
+</p>
+
+
+<h3>Examples</h3>
+
+<pre>
+ &lt;target name="diagnostics" description="diagnostics"&gt;
+ &lt;diagnostics/&gt;
+ &lt;/target&gt;
+</pre>
+<p>
+ Prints out the current diagnostics dump.
+</p>
+
+
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/dirname.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/dirname.html
new file mode 100644
index 00000000..03227b46
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/dirname.html
@@ -0,0 +1,74 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Dirname Task</title>
+</head>
+
+<body>
+
+<h2><a name="echo">Dirname</a></h2>
+<h3>Description</h3>
+<p>
+Task to determine the directory path of a specified file.
+</p>
+<p>
+When this task executes, it will set the specified property to the
+value of the specified file (or directory) up to, but not including,
+the last path element. If the specified file is a path that ends in a
+filename, the filename will be dropped. If the specified file is just
+a filename, the directory will be the current directory.
+</p>
+ <p>
+ <em>Note:</em> This is not the same as the UNIX dirname command, which is
+ defined as "strip non-directory suffix from filename". &lt;dirname&gt;
+ determines the full directory path of the specified file.
+ </p>
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">file</td>
+ <td valign="top">The path to take the dirname of.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">property</td>
+ <td valign="top">The name of the property to set.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+</table>
+
+<h3>Examples</h3>
+<pre> &lt;dirname property=&quot;antfile.dir&quot; file=&quot;${ant.file}&quot;/&gt;</pre>
+will set <code>antfile.dir</code> to the directory path for
+<code>${ant.file}</code>.
+<pre> &lt;dirname property=&quot;foo.dirname&quot; file=&quot;foo.txt&quot;/&gt;</pre>
+will set <code>foo.dirname</code> to the project's basedir.</p>
+
+
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/ear.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/ear.html
new file mode 100644
index 00000000..de4a9626
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/ear.html
@@ -0,0 +1,301 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>EAR Task</title>
+</head>
+
+<body>
+
+<h2><a name="ear">Ear</a></h2>
+<h3>Description</h3>
+<p>An extension of the <a href="jar.html">Jar</a> task with special
+treatment for files that should end up in an Enterprise Application archive.</p>
+<p>(The Ear task is a shortcut for specifying the particular layout of a EAR file.
+The same thing can be accomplished by using the <i>prefix</i> and <i>fullpath</i>
+attributes of zipfilesets in a Zip or Jar task.)</p>
+<p>The extended zipfileset element from the zip task (with attributes <i>prefix</i>, <i>fullpath</i>, and <i>src</i>) is available in the Ear task.</p>
+
+<p><b>Please note that the zip format allows multiple files of the same
+fully-qualified name to exist within a single archive. This has been
+documented as causing various problems for unsuspecting users. If you wish
+to avoid this behavior you must set the <code>duplicate</code> attribute
+to a value other than its default, <code>&quot;add&quot;</code>.</b></p>
+
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">destfile</td>
+ <td valign="top">the EAR file to create.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">appxml</td>
+ <td valign="top">The deployment descriptor to use (META-INF/application.xml).</td>
+ <td valign="top" align="center">Yes, unless update is set to true</td>
+ </tr>
+ <tr>
+ <td valign="top">basedir</td>
+ <td valign="top">the directory from which to jar the files.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">compress</td>
+ <td valign="top">Not only store data but also compress them,
+ defaults to true. Unless you set the <em>keepcompression</em>
+ attribute to false, this will apply to the entire archive, not
+ only the files you've added while updating.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">keepcompression</td>
+ <td valign="top">For entries coming from existing archives (like
+ nested <em>zipfileset</em>s or while updating the archive), keep
+ the compression as it has been originally instead of using the
+ <em>compress</em> attribute. Defaults false. <em>Since Apache Ant
+ 1.6</em></td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">encoding</td>
+ <td valign="top">The character encoding to use for filenames
+ inside the archive. Defaults to UTF8. <strong>It is not
+ recommended to change this value as the created archive will most
+ likely be unreadable for Java otherwise.</strong>
+ <br/>See also the <a href="zip.html#encoding">discussion in the
+ zip task page</a></td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">filesonly</td>
+ <td valign="top">Store only file entries, defaults to false</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">includes</td>
+ <td valign="top">comma- or space-separated list of patterns of files that must be
+ included. All files are included when omitted.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">includesfile</td>
+ <td valign="top">the name of a file. Each line of this file is
+ taken to be an include pattern</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">excludes</td>
+ <td valign="top">comma- or space-separated list of patterns of files that must be
+ excluded. No files (except default excludes) are excluded when omitted.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">excludesfile</td>
+ <td valign="top">the name of a file. Each line of this file is
+ taken to be an exclude pattern</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">defaultexcludes</td>
+ <td valign="top">indicates whether default excludes should be used or not
+ (&quot;yes&quot;/&quot;no&quot;). Default excludes are used when omitted.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">manifest</td>
+ <td valign="top">the manifest file to use.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">filesetmanifest</td>
+ <td valign="top">behavior when a Manifest is found in a zipfileset or zipgroupfileset file is found. Valid values are &quot;skip&quot;, &quot;merge&quot;, and &quot;mergewithoutmain&quot;. &quot;merge&quot; will merge all of the manifests together, and merge this into any other specified manifests. &quot;mergewithoutmain&quot; merges everything but the Main section of the manifests. Default value is &quot;skip&quot;.
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">whenmanifestonly</td>
+ <td valign="top">behavior when no files match. Valid values are &quot;fail&quot;, &quot;skip&quot;, and &quot;create&quot;. Default is &quot;create&quot;.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">manifestencoding</td>
+ <td valign="top">The encoding used to read the JAR manifest, when a manifest file is specified.</td>
+ <td valign="top" align="center">No, defaults to the platform encoding.</td>
+ </tr>
+ <tr>
+ <td valign="top">index</td>
+ <td valign="top">whether to create an <A
+ HREF="http://docs.oracle.com/javase/7/docs/technotes/guides/jar/jar.html#JAR_Index">index
+ list</A> to speed up classloading. This is a JDK 1.3+ specific
+ feature. Unless you specify additional jars with nested <a
+ href="jar.html#indexjars"><code>indexjars</code></a> elements, only the
+ contents of this jar will be included in the index. Defaults to
+ false.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">indexMetaInf</td>
+ <td valign="top">whether to include META-INF and its children in
+ the index. Doesn't have any effect if <em>index</em> is
+ false.<br/>
+ Oracle's jar implementation used to skip the META-INF directory and
+ Ant followed that example. The behavior has been changed with
+ <a href="https://bugs.openjdk.java.net/browse/JDK-4408526">Java
+ 5</a>. In order to avoid problems with Ant generated jars on
+ Java 1.4 or earlier Ant will not include META-INF unless
+ explicitly asked to.<br/>
+ <em>Ant 1.8.0</em> - Defaults to false.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">update</td>
+ <td valign="top">indicates whether to update or overwrite
+ the destination file if it already exists. Default is &quot;false&quot;.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">duplicate</td>
+ <td valign="top">behavior when a duplicate file is found. Valid values are &quot;add&quot;, &quot;preserve&quot;, and &quot;fail&quot;. The default value is &quot;add&quot;. </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">roundup</td>
+ <td valign="top">Whether the file modification times will be
+ rounded up to the next even number of seconds.<br>
+ Zip archives store file modification times with a granularity of
+ two seconds, so the times will either be rounded up or down. If
+ you round down, the archive will always seem out-of-date when you
+ rerun the task, so the default is to round up. Rounding up may
+ lead to a different type of problems like JSPs inside a web
+ archive that seem to be slightly more recent than precompiled
+ pages, rendering precompilation useless.<br>
+ Defaults to true. <em>Since Ant 1.6.2</em></td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">level</td>
+ <td valign="top">Non-default level at which file compression should be
+ performed. Valid values range from 0 (no compression/fastest) to 9
+ (maximum compression/slowest). <em>Since Ant 1.7</em></td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">preserve0permissions</td>
+ <td valign="top">when updating an archive or adding entries from a
+ different archive Ant will assume that a Unix permissions value of
+ 0 (nobody is allowed to do anything to the file/directory) means
+ that the permissions haven't been stored at all rather than real
+ permissions and will instead apply its own default values.<br/>
+ Set this attribute to true if you really want to preserve the
+ original permission field.<em>since Ant 1.8.0</em>
+ </td>
+ <td valign="top" align="center">No, default is false</td>
+ </tr>
+ <tr>
+ <td valign="top">useLanguageEncodingFlag</td>
+ <td valign="top">Whether to set the language encoding flag if the
+ encoding is UTF-8. This setting doesn't have any effect if the
+ encoding is not UTF-8.
+ <em>Since Ant 1.8.0</em>.
+ <br/>See also the <a href="zip.html#encoding">discussion in the
+ zip task page</a></td>
+ <td valign="top" align="center">No, default is true</td>
+ </tr>
+ <tr>
+ <td valign="top">createUnicodeExtraFields</td>
+ <td valign="top">Whether to create unicode extra fields to store
+ the file names a second time inside the entry's metadata.
+ <br>Possible values are "never", "always" and "not-encodeable"
+ which will only add Unicode extra fields if the file name cannot
+ be encoded using the specified encoding.
+ <em>Since Ant 1.8.0</em>.
+ <br/>See also the <a href="zip.html#encoding">discussion in the
+ zip task page</a></td>
+ <td align="center" valign="top">No, default is "never"</td>
+ </tr>
+ <tr>
+ <td valign="top">fallbacktoUTF8</td>
+ <td valign="top">Whether to use UTF-8 and the language encoding
+ flag instead of the specified encoding if a file name cannot be
+ encoded using the specified encoding.
+ <em>Since Ant 1.8.0</em>.
+ <br/>See also the <a href="zip.html#encoding">discussion in the
+ zip task page</a></td>
+ <td align="center" valign="top">No, default is false</td>
+ </tr>
+ <tr>
+ <td valign="top">mergeClassPathAttributes</td>
+ <td valign="top">Whether to merge the Class-Path attributes found
+ in different manifests (if merging manifests). If false, only
+ the attribute of the last merged manifest will be preserved.
+ <em>Since Ant 1.8.0</em>.
+ <br/>unless you also set flattenAttributes to true this may
+ result in manifests containing multiple Class-Path attributes
+ which violates the manifest specification.</td>
+ <td align="center" valign="top">No, default is false</td>
+ </tr>
+ <tr>
+ <td valign="top">flattenAttributes</td>
+ <td valign="top">Whether to merge attributes occurring more than
+ once in a section (this can only happen for the Class-Path
+ attribute) into a single attribute.
+ <em>Since Ant 1.8.0</em>.</td>
+ <td align="center" valign="top">No, default is false</td>
+ </tr>
+ <tr>
+ <td valign="top">zip64Mode</td>
+ <td valign="top">When to use Zip64 extensions for entries. The
+ possible values are "never", "always" and "as-needed".
+ <em>Since Ant 1.9.1</em>.
+ <br/>See also the <a href="zip.html#zip64">discussion in the
+ zip task page</a></td>
+ <td align="center" valign="top">No, default is "never"</td>
+ </tr>
+</table>
+
+<h3>Nested elements</h3>
+
+<h4>metainf</h4>
+<p>The nested <code>metainf</code> element specifies a <a
+href="../Types/fileset.html">FileSet</a>. All files included in this fileset will
+end up in the <code>META-INF</code> directory of the ear file. If this
+fileset includes a file named <code>MANIFEST.MF</code>, the file is
+ignored and you will get a warning.</p>
+
+<h4>manifest, indexjars, service</h4>
+These are inherited from <a href="jar.html">&lt;jar&gt;</a>
+
+<h2>Example</h2>
+<pre>
+ &lt;ear destfile=&quot;${build.dir}/myapp.ear&quot; appxml=&quot;${src.dir}/metadata/application.xml&quot;&gt;
+ &lt;fileset dir=&quot;${build.dir}&quot; includes=&quot;*.jar,*.war&quot;/&gt;
+ &lt;/ear&gt;
+</pre>
+
+
+</body>
+</html>
+
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/echo.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/echo.html
new file mode 100644
index 00000000..bcf804ec
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/echo.html
@@ -0,0 +1,193 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Echo Task</title>
+</head>
+
+<body>
+
+<h2><a name="echo">Echo</a></h2>
+<h3>Description</h3>
+<p>Echoes a message to the current loggers and listeners which
+means <tt>System.out</tt> unless overridden. A <tt>level</tt>
+can be specified, which controls at what logging level the message is
+filtered at.
+<p>
+The task can also echo to a file, in which case the option to append rather
+than overwrite the file is available, and the <tt>level</tt> option is
+ignored</p>
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">message</td>
+ <td valign="top">the message to echo.</td>
+ <td valign="top" align="center">No. Text may also be included in a
+ character section within this element. If neither is included a
+ blank line will be emitted in the output.</td>
+ </tr>
+ <tr>
+ <td valign="top">file</td>
+ <td valign="top">the file to write the message to.</td>
+ <td valign="top" align="center" rowspan="2">Optionally one of these may be specified.</td>
+ </tr>
+ <tr>
+ <td valign="top">output</td>
+ <td valign="top">the <a href="../Types/resources.html">Resource</a>
+ to write the message to (see <a href="../develop.html#set-magic">note</a>).
+ <b>Since Apache Ant 1.8</b></td>
+ </tr>
+ <tr>
+ <td valign="top">append</td>
+ <td valign="top">Append to an existing file (or
+ <a href="http://docs.oracle.com/javase/7/docs/api//java/io/FileWriter.html#FileWriter%28java.lang.String,%20boolean%29" target="_blank">
+ open a new file / overwrite an existing file</a>)? Default <i>false</i>.
+ </td>
+ <td valign="top" align="center">No; ignored unless <i>output</i> indicates a
+ filesystem destination.</td>
+ </tr>
+ <tr>
+ <td valign="top">level</td>
+ <td valign="top">Control the level at which this message is reported.
+ One of "error", "warning", "info", "verbose", "debug" (decreasing order)</td>
+ <td valign="top" align="center">No - default is "warning".</td>
+ </tr>
+ <tr>
+ <td valign="top">encoding</td>
+ <td valign="top">encoding to use, default is ""; the local system encoding. <em>since Ant 1.7</em></td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">force</td>
+ <td valign="top">Overwrite read-only destination
+ files. <em>since Ant 1.8.2</em></td>
+ <td valign="top" align="center">No; defaults to false.</td>
+ </tr>
+</table>
+
+<h3>Examples</h3>
+<pre>
+&lt;echo message=&quot;Hello, world&quot;/&gt;
+</pre>
+<pre>
+&lt;echo message=&quot;Embed a line break:${line.separator}&quot;/&gt;
+</pre>
+<pre>
+&lt;echo&gt;Embed another:${line.separator}&lt;/echo&gt;
+</pre>
+<pre>
+&lt;echo&gt;This is a longer message stretching over
+two lines.
+&lt;/echo&gt;
+</pre>
+<pre>
+&lt;echo&gt;
+This is a longer message stretching over
+three lines; the first line is a blank
+&lt;/echo&gt;
+</pre>
+The newline immediately following the &lt;echo&gt; tag will be part of the output.<br>
+Newlines in character data within the content of an element are not discarded by XML parsers.<br>
+See <a href="http://www.w3.org/TR/2004/REC-xml-20040204/#sec-line-ends">
+W3C Recommendation 04 February 2004 / End of Line handling
+</a> for more details.
+
+<pre>&lt;echo message=&quot;Deleting drive C:&quot; level=&quot;debug&quot;/&gt;</pre>
+A message which only appears in <tt>-debug</tt> mode.
+<pre>&lt;echo level=&quot;error&quot;&gt;
+Imminent failure in the antimatter containment facility.
+Please withdraw to safe location at least 50km away.
+&lt;/echo&gt;
+</pre>
+A message which appears even in <tt>-quiet</tt> mode.
+
+<pre>&lt;echo file="runner.csh" append="false"&gt;#\!/bin/tcsh
+java-1.3.1 -mx1024m ${project.entrypoint} $$*
+&lt;/echo&gt;</pre>
+Generate a shell script by echoing to a file.
+Note the use of a double $ symbol to stop Ant
+filtering out the single $ during variable expansion
+
+<p>Depending on the loglevel Ant runs, messages are print out or silently
+ignored:
+<table>
+<tr>
+ <th>Ant-Statement</th>
+ <th>-quiet, -q</th>
+ <th><i>no statement</th>
+ <th>-verbose, -v</th>
+ <th>-debug, -d</th>
+</tr>
+<tr>
+ <td><pre>&lt;echo message="This is error message." level="error" /&gt;</pre></td>
+ <td align="center">ok</td>
+ <td align="center">ok</td>
+ <td align="center">ok</td>
+ <td align="center">ok</td>
+</tr>
+<tr>
+ <td><pre>&lt;echo message="This is warning message." /&gt;</pre></td>
+ <td align="center">ok</td>
+ <td align="center">ok</td>
+ <td align="center">ok</td>
+ <td align="center">ok</td>
+</tr>
+<tr>
+ <td><pre>&lt;echo message="This is warning message." level="warning" /&gt;</pre></td>
+ <td align="center">ok</td>
+ <td align="center">ok</td>
+ <td align="center">ok</td>
+ <td align="center">ok</td>
+</tr>
+<tr>
+ <td><pre>&lt;echo message="This is info message." level="info" /&gt;</pre></td>
+ <td align="center">not logged</td>
+ <td align="center">ok</td>
+ <td align="center">ok</td>
+ <td align="center">ok</td>
+</tr>
+<tr>
+ <td><pre>&lt;echo message="This is verbose message." level="verbose" /&gt;</pre></td>
+ <td align="center">not logged</td>
+ <td align="center">not logged</td>
+ <td align="center">ok</td>
+ <td align="center">ok</td>
+</tr>
+<tr>
+ <td><pre>&lt;echo message="This is debug message." level="debug" /&gt;</pre></td>
+ <td align="center">not logged</td>
+ <td align="center">not logged</td>
+ <td align="center">not logged</td>
+ <td align="center">ok</td>
+</tr>
+</table>
+
+
+
+
+
+
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/echoproperties.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/echoproperties.html
new file mode 100644
index 00000000..ec1e4b44
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/echoproperties.html
@@ -0,0 +1,146 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Echoproperties Task</title>
+</head>
+
+<body>
+
+<h2><a name="echoproperties">echoproperties</a></h2>
+<h3>Description</h3>
+
+<p>Displays all the current properties (or a subset of them specified
+by a nested <code>&lt;propertyset&gt;</code>) in the project. The
+output can be sent to a file if desired. This task can be used as a
+somewhat contrived means of returning data from an
+<tt>&lt;ant&gt;</tt> invocation, but is really for debugging build
+files.</p>
+
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">destfile</td>
+ <td valign="top">If specified, the value indicates the name of the
+ file to send the output of the statement to. The generated output file
+ is compatible for loading by any Java application as a property file.
+ If not specified, then the output will go to the Apache Ant log.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">prefix</td>
+ <td valign="top">
+ a prefix which is used to filter the properties
+ only those properties starting with this prefix will be echoed.
+ <P>
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">regex</td>
+ <td valign="top">
+ a regular expression which is used to filter the
+ properties
+ only those properties whose names match it will be echoed.
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">failonerror</td>
+ <td valign="top">By default, the "failonerror" attribute is enabled.
+ If an error occurs while writing the properties to a file, and this
+ attribute is enabled, then a BuildException will be thrown, causing the
+ build to fail. If disabled, then IO errors will be reported as a log
+ statement, and the build will continue without failure from this task.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">format</td>
+ <td valign="top">One of <code>text</code> or <code>xml</code>.
+ Determines the output format. Defaults to <code>text</code>.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+</table>
+
+<h3>Parameters specified as nested elements</h3>
+
+<h4>propertyset</h4>
+
+<p>You can specify subsets of properties to be echoed with <a
+href="../Types/propertyset.html">propertyset</a>s. Using
+<tt>propertyset</tt>s gives more control on which properties will be
+picked up. The attributes <tt>prefix</tt> and <tt>regex</tt> are just
+shortcuts that use <tt>propertyset</tt>s internally.
+</p>
+
+<p><em>since Ant 1.6</em>.</p>
+
+<h3>Examples</h3>
+<blockquote><pre>
+ &lt;echoproperties/&gt;
+</pre></blockquote>
+<p>Report the current properties to the log.</p>
+<blockquote><pre>
+ &lt;echoproperties destfile="my.properties"/&gt;
+</pre></blockquote>
+<p>Report the current properties to the file "my.properties", and will
+fail the build if the file could not be created or written to.</p>
+<blockquote><pre>
+ &lt;echoproperties destfile="my.properties" failonerror="false"/&gt;
+</pre></blockquote>
+<p>Report the current properties to the file "my.properties", and will
+log a message if the file could not be created or written to, but will still
+allow the build to continue.</p>
+<blockquote><pre>
+ &lt;echoproperties prefix="java."/&gt;
+</pre></blockquote>
+<p>List all properties beginning with "java."</p>
+<blockquote><pre>
+ &lt;echoproperties&gt;
+ &lt;propertyset&gt;
+ &lt;propertyref prefix="java."/&gt;
+ &lt;/propertyset&gt;
+ &lt;/echoproperties&gt;
+</pre></blockquote>
+<p>This again lists all properties beginning with "java." using a nested
+<tt>&lt;/propertyset&gt;</tt> which is an equivalent but longer way.</p>
+<blockquote><pre>
+ &lt;echoproperties regex=".*ant.*"/&gt;
+</pre></blockquote>
+<p>Lists all properties that contain "ant" in their names.
+The equivalent snippet with <tt>&lt;/propertyset&gt;</tt> is:</p>
+<blockquote><pre>
+ &lt;echoproperties&gt;
+ &lt;propertyset&gt;
+ &lt;propertyref regex=".*ant.*"/&gt;
+ &lt;/propertyset&gt;
+ &lt;/echoproperties&gt;
+</pre></blockquote>
+
+
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/echoxml.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/echoxml.html
new file mode 100644
index 00000000..74cbf7fb
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/echoxml.html
@@ -0,0 +1,74 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>EchoXML Task</title>
+</head>
+
+<body>
+
+<h2>EchoXML</h2>
+<h3>Description</h3>
+<p>Echo nested XML to the console or a file. <b>Since Apache Ant 1.7</b></p>
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">file</td>
+ <td valign="top">The file to receive the XML. If omitted nested
+ XML will be echoed to the log.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">append</td>
+ <td valign="top">Whether to append <code>file</code>, if specified.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">namespacePolicy</td>
+ <td valign="top">Sets the namespace policy as defined
+ by <code>org.apache.tools.ant.util.DOMElementWriter.XmlNamespacePolicy</code>.
+ Valid values are <code>ignore</code>, <code>elementsOnly</code>, or <code>all</code>.
+ <strong>Since Apache Ant 1.8</strong>
+ </td>
+ <td valign="top" align="center">No, default <code>ignore</code></td>
+ </tr>
+</table>
+<h3>Parameters specified as nested elements</h3>
+Nested XML content is required.
+
+<h3>Examples</h3>
+<pre>&lt;echoxml file=&quot;subbuild.xml&quot;&gt;
+ &lt;project default=&quot;foo&quot;&gt;
+ &lt;target name=&quot;foo&quot;&gt;
+ &lt;echo&gt;foo&lt;/echo&gt;
+ &lt;/target&gt;
+ &lt;/project&gt;
+&lt;/echoxml&gt;
+</pre>
+<p>Creates an Ant buildfile, <code>subbuild.xml</code>.</p>
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/ejb.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/ejb.html
new file mode 100644
index 00000000..aa140e70
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/ejb.html
@@ -0,0 +1,1777 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>EJB Tasks</title>
+
+</head>
+
+<body>
+
+<h1>Apache Ant EJB Tasks User Manual</h1>
+<p>by</p>
+<!-- Names are in alphabetical order, on last name -->
+<ul>
+ <li>Paul Austin (<a href="mailto:p_d_austin@yahoo.com">p_d_austin@yahoo.com</a>)</li>
+ <li>Holger Engels (<a href="mailto:hengels@innovidata.com">hengels@innovidata.com</a>)</li>
+ <li>Tim Fennell (<a href="mailto:tfenne@rcn.com">tfenne@rcn.com</a>)</li>
+ <li>Martin Gee (<a href="mailto:martin.gee@icsynergy.com">martin.gee@icsynergy.com</a>)</li>
+ <li>Conor MacNeill</li>
+ <li>Cyrille Morvan (<a href="mailto:cmorvan@ingenosya.com">cmorvan@ingenosya.com</a>)</li>
+ <li>Greg Nelson (<a href="mailto:gn@sun.com">gn@sun.com</a>)</li>
+ <li>Rob van Oostrum(<a href="mailto:rob@springwellfarms.ca">rob@springwellfarms.ca</a>)</li>
+</ul>
+
+<hr>
+<h2>Table of Contents</h2>
+<ul>
+ <li><a href="#introduction">Introduction</a></li>
+ <li><a href="#ejbtasks">EJB Tasks</a></li>
+</ul>
+
+<hr>
+<h2><a name="introduction">Introduction</a></h2>
+<p>Ant provides a number of optional tasks for developing 1.x and 2.x
+<a href="http://www.oracle.com/technetwork/java/index-jsp-140203.html" target="_top">Enterprise Java Beans (EJBs)</a>.
+In general these tasks are specific to the particular vendor's EJB Server.</p>
+
+<p> The tasks support:<br>
+
+<ul>
+ <li><a href="http://www.borland.com">Borland </a>
+ Application Server 4.5</li>
+ <li><a href="http://www.iplanet.com">iPlanet </a>
+ Application Server 6.0</li>
+ <li><a href="http://www.jboss.org/" target="_top">
+ JBoss 2.1</a> and above EJB servers</li>
+ <li><a href="http://www.bea.com" target="_top">Weblogic</a>
+ 4.5.1 through to 7.0 EJB servers</li>
+ <li><a href="http://www.objectweb.org/jonas/" target="_top">JOnAS</a>
+ 2.4.x and 2.5 Open Source EJB server</li>
+ <li><a href="http://www.ibm.com/websphere">IBM WebSphere</a> 4.0</li>
+</ul>
+ Vendors such as BEA and IBM now provide custom Ant tasks to work with their
+ particular products. More importantly, EJB3.0 renders this whole process obsolete.
+ Accordingly, development of these tasks is effectively frozen. Bug reports
+ and especially patches are welcome, but there is no pressing need to add
+ support for new application servers. Nobody should be writing new EJB2.x applications
+ and definitely not new EJB2.x servers.
+</p>
+
+<hr>
+<h2><a name="ejbtasks">EJB Tasks</a></h2>
+<table border="1" cellpadding="5">
+ <tr><td>Task</td><td colspan="2">Application Servers</td></tr>
+ <tr><td><a href="BorlandGenerateClient.html">blgenclient</a></td><td colspan="2">Borland Application Server 4.5 and 5.x</td></tr>
+ <tr><td><a href="#iplanet-ejbc">iplanet-ejbc</a></td><td colspan="2">iPlanet Application Server 6.0</td></tr>
+ <tr><td rowspan="7"><a href="#ejbjar">ejbjar</a></td><td colspan="2" align="center"><b>Nested Elements</b></td></tr>
+ <tr><td><a href="BorlandEJBTasks.html">borland</a></td><td>Borland Application Server 4.5 and 5.x</td></tr>
+ <tr><td><a href="#ejbjar_iplanet">iPlanet</a></td><td>iPlanet Application Server 6.0</td></tr>
+ <tr><td><a href="#ejbjar_jboss">jboss</a></td><td>JBoss</td></tr>
+ <tr><td><a href="#ejbjar_jonas">jonas</a></td><td>JOnAS 2.4.x and 2.5</td></tr>
+ <tr><td><a href="#ejbjar_weblogic">weblogic</a></td><td>Weblogic 5.1 to 7.0</td></tr>
+ <tr><td><a href="#ejbjar_websphere">websphere</a></td><td>IBM WebSphere 4.0</td></tr>
+
+</table>
+
+<hr>
+<h2><a name="ddcreator">ddcreator</a></h2>
+<h3><b>Description:</b></h3>
+<p>ddcreator will compile a set of Weblogic text-based deployment descriptors into a serialized
+EJB deployment descriptor. The selection of which of the text-based descriptors are to be compiled
+is based on the standard Ant include and exclude selection mechanisms.
+</p>
+
+<h3>Parameters:</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">descriptors</td>
+ <td valign="top">This is the base directory from which descriptors are selected.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">dest</td>
+ <td valign="top">The directory where the serialized deployment descriptors will be written</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">classpath</td>
+ <td valign="top">This is the classpath to use to run the underlying weblogic ddcreator tool.
+ This must include the <code>weblogic.ejb.utils.DDCreator</code> class</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+</table>
+<h3>Examples</h3>
+<pre>
+&lt;ddcreator descriptors=&quot;${dd.dir}&quot;
+ dest=&quot;${gen.classes}&quot;
+ classpath=&quot;${descriptorbuild.classpath}&quot;&gt;
+ &lt;include name=&quot;*.txt&quot;/&gt;
+&lt;/ddcreator&gt;
+</pre>
+
+<hr>
+<h2><a name="ejbc">ejbc</a></h2>
+<h3><b>Description:</b></h3>
+<p>The ejbc task will run Weblogic's ejbc tool. This tool will take a serialized deployment descriptor,
+examine the various EJB interfaces and bean classes and then generate the required support classes
+necessary to deploy the bean in a Weblogic EJB container. This will include the RMI stubs and skeletons
+as well as the classes which implement the bean's home and remote interfaces.</p>
+<p>
+The ant task which runs this tool is able to compile several beans in a single operation. The beans to be
+compiled are selected by including their serialized deployment descriptors. The standard ant
+<code>include</code> and <code>exclude</code> constructs can be used to select the deployment descriptors
+to be included. </p>
+<p>
+Each descriptor is examined to determine whether the generated classes are out of date and need to be
+regenerated. The deployment descriptor is de-serialized to discover the home, remote and
+implementation classes. The corresponding source files are determined and checked to see their
+modification times. These times and the modification time of the serialized descriptor itself are
+compared with the modification time of the generated classes. If the generated classes are not present
+or are out of date, the ejbc tool is run to generate new versions.</p>
+<h3>Parameters:</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">descriptors</td>
+ <td valign="top">This is the base directory from which the serialized deployment descriptors are selected.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">dest</td>
+ <td valign="top">The base directory where the generated classes, RIM stubs and RMI skeletons are written</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">manifest</td>
+ <td valign="top">The name of a manifest file to be written. This manifest will contain an entry for each EJB processed</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">src</td>
+ <td valign="top">The base directory of the source tree containing the source files of the home interface,
+ remote interface and bean implementation classes.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">classpath</td>
+ <td valign="top">This classpath must include both the <code>weblogic.ejbc</code> class and the
+ class files of the bean, home interface, remote interface, etc of the bean being
+ processed.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">keepgenerated</td>
+ <td>Controls whether ejbc will keep the
+ intermediate Java files used to build the class files. This can be
+ useful when debugging.</td>
+ <td>No, defaults to false.</td>
+ </tr>
+</table>
+<h3>Examples</h3>
+<pre>
+&lt;ejbc descriptors=&quot;${gen.classes}&quot;
+ src=&quot;${src.dir}&quot;
+ dest=&quot;${gen.classes}&quot;
+ manifest=&quot;${build.manifest}&quot;
+ classpath=&quot;${descriptorbuild.classpath}&quot;&gt;
+ &lt;include name=&quot;*.ser&quot;/&gt;
+&lt;/ejbc&gt;
+</pre>
+
+<hr>
+<h2>
+<a NAME="iplanet-ejbc"></a>iplanet-ejbc</h2>
+
+<h3>
+<b>Description:</b></h3>
+Task to compile EJB stubs and skeletons for the iPlanet Application Server
+6.0. Given a standard EJB 1.1 XML descriptor as well as an iAS-specific
+EJB descriptor, this task will generate the stubs and skeletons required
+to deploy the EJB to iAS. Since the XML descriptors can include multiple
+EJBs, this is a convenient way of specifying many EJBs in a single Ant
+task.
+<p>For each EJB specified, the task will locate the three classes that
+comprise the EJB in the destination directory. If these class files
+cannot be located in the destination directory, the task will fail. The
+task will also attempt to locate the EJB stubs and skeletons in this directory.
+If found, the timestamps on the stubs and skeletons will be checked to
+ensure they are up to date. Only if these files cannot be found or if they
+are out of date will the iAS ejbc utility be called to generate new stubs
+and skeletons.</p>
+<h3>
+Parameters:</h3>
+
+<table border="1" cellspacing="0" cellpadding="2">
+<tr>
+<td valign="top"><b>Attribute</b></td>
+
+<td valign="top"><b>Description</b></td>
+
+<td align="center" valign="top"><b>Required</b></td>
+</tr>
+
+<tr>
+<td valign="top">ejbdescriptor</td>
+
+<td valign="top">Standard EJB 1.1 XML descriptor (typically titled "ejb-jar.xml").</td>
+
+<td align="center" valign="top">Yes</td>
+</tr>
+
+<tr>
+<td valign="top">iasdescriptor</td>
+
+<td valign="top">iAS-specific EJB XML descriptor (typically titled "ias-ejb-jar.xml").</td>
+
+<td align="center" valign="top">Yes</td>
+</tr>
+
+<tr>
+<td valign="top">dest</td>
+
+<td valign="top">The is the base directory where the RMI stubs and skeletons
+are written. In addition, the class files for each bean (home interface,
+remote interface, and EJB implementation) must be found in this directory.</td>
+
+<td align="center" valign="top">Yes</td>
+</tr>
+
+<tr>
+<td valign="top">classpath</td>
+
+<td valign="top">The classpath used when generating EJB stubs and skeletons.
+If omitted, the classpath specified when Ant was started will be used.
+Nested "classpath" elements may also be used.</td>
+
+<td align="center" valign="top">No</td>
+</tr>
+
+<tr>
+<td valign="top">keepgenerated</td>
+
+<td valign="top">Indicates whether or not the Java source files which are
+generated by ejbc will be saved or automatically deleted. If "yes", the
+source files will be retained. If omitted, it defaults to "no". </td>
+
+<td align="center" valign="top">No</td>
+</tr>
+
+<tr>
+<td valign="top">debug</td>
+
+<td>Indicates whether or not the ejbc utility should log additional debugging
+statements to the standard output. If "yes", the additional debugging statements
+will be generated. If omitted, it defaults to "no". </td>
+
+<td align="center" valign="top">
+<center>No</center>
+</td>
+</tr>
+
+<tr>
+<td valign="top">iashome</td>
+
+<td>May be used to specify the "home" directory for this iAS installation.
+This is used to find the ejbc utility if it isn't included in the user's
+system path. If specified, it should refer to the "[install-location]/iplanet/ias6/ias"
+directory. If omitted, the ejbc utility must be on the user's system path. </td>
+
+<td align="center" valign="top">No</td>
+</tr>
+</table>
+
+<h3>
+Examples</h3>
+
+<pre>
+&lt;iplanet-ejbc ejbdescriptor="ejb-jar.xml"
+ iasdescriptor="ias-ejb-jar.xml"
+ dest="${build.classesdir}"
+ classpath="${ias.ejbc.cpath}"/&gt;
+
+
+&lt;iplanet-ejbc ejbdescriptor="ejb-jar.xml"
+ iasdescriptor="ias-ejb-jar.xml"
+ dest="${build.classesdir}"
+ keepgenerated="yes"
+ debug="yes"
+ iashome="${ias.home}"&gt;
+ &lt;classpath&gt;
+ &lt;pathelement path="."/&gt;
+ &lt;pathelement path="${build.classpath}"/&gt;
+ &lt;/classpath&gt;
+&lt;/iplanet-ejbc&gt;
+
+
+</pre>
+
+<hr>
+<h2><a name="wlrun">wlrun</a></h2>
+<h3><b>Description:</b></h3>
+
+<p>The <code>wlrun</code> task is used to start a weblogic server. The task runs
+a weblogic instance in a separate Java Virtual Machine. A number of parameters
+are used to control the operation of the weblogic instance. Note that the task,
+and hence ant, will not complete until the weblogic instance is stopped.</p>
+
+<h3>Parameters:</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required for 4.5.1 and 5.1</b></td>
+ <td align="center" valign="top"><b>Required for 6.0</b></td>
+ </tr>
+ <tr>
+ <td valign="top">BEA Home</td>
+ <td valign="top">The location of the BEA Home where the server's config is defined.
+ If this attribute is present, wlrun assumes that the server will
+ be running under Weblogic 6.0</td>
+ <td valign="top" align="center">N/A</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">home</td>
+ <td valign="top">The location of the weblogic home that is to be used. This is the location
+ where weblogic is installed.</td>
+ <td valign="top" align="center">Yes</td>
+ <td valign="top" align="center">Yes. Note this is the absolute location, not relative to
+ BEA home.</td>
+ </tr>
+ <tr>
+ <td valign="top">Domain</td>
+ <td valign="top">The domain to which the server belongs.</td>
+ <td valign="top" align="center">N/A</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">classpath</td>
+ <td valign="top">The classpath to be used with the Java Virtual Machine that runs the Weblogic
+ Server. Prior to Weblogic 6.0, this is typically set to the Weblogic
+ boot classpath. Under Weblogic 6.0 this should include all the
+ weblogic jars</td>
+ <td valign="top" align="center">Yes</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">wlclasspath</td>
+ <td valign="top">The weblogic classpath used by the Weblogic Server.</td>
+ <td valign="top" align="center">No</td>
+ <td valign="top" align="center">N/A</td>
+ </tr>
+ <tr>
+ <td valign="top">properties</td>
+ <td valign="top">The name of the server's properties file within the weblogic home directory
+ used to control the weblogic instance.</td>
+ <td valign="top" align="center">Yes</td>
+ <td valign="top" align="center">N/A</td>
+ </tr>
+ <tr>
+ <td valign="top">name</td>
+ <td valign="top">The name of the weblogic server within the weblogic home which is to be run.
+ This defaults to &quot;myserver&quot;</td>
+ <td valign="top" align="center">No</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">policy</td>
+ <td valign="top">The name of the security policy file within the weblogic home directory that
+ is to be used. If not specified, the default policy file <code>weblogic.policy</code>
+ is used.</td>
+ <td valign="top" align="center">No</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">username</td>
+ <td valign="top">The management username used to manage the server</td>
+ <td valign="top" align="center">N/A</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">password</td>
+ <td valign="top">The server's management password</td>
+ <td valign="top" align="center">N/A</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">pkPassword</td>
+ <td valign="top">The private key password so the server can decrypt the SSL
+ private key file</td>
+ <td valign="top" align="center">N/A</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">jvmargs</td>
+ <td valign="top">Additional argument string passed to the Java Virtual Machine used to run the
+ Weblogic instance.</td>
+ <td valign="top" align="center">No</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">weblogicMainClass</td>
+ <td valign="top">name of the main class for weblogic</td>
+ <td valign="top" align="center">No</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+</table>
+
+<h3>Nested Elements</h3>
+
+<p>The wlrun task supports nested <code>&lt;classpath&gt;</code> and <code>&lt;wlclasspath&gt;</code>
+elements to set the respective classpaths.</p>
+
+<h3>Examples</h3>
+
+<p>This example shows the use of wlrun to run a server under Weblogic 5.1</p>
+
+<pre>
+ &lt;wlrun taskname=&quot;myserver&quot;
+ classpath=&quot;${weblogic.boot.classpath}&quot;
+ wlclasspath=&quot;${weblogic.classes}:${code.jars}&quot;
+ name=&quot;myserver&quot;
+ home=&quot;${weblogic.home}&quot;
+ properties=&quot;myserver/myserver.properties&quot;/&gt;
+</pre>
+
+<p>This example shows wlrun being used to run the petstore server under
+Weblogic 6.0</p>
+
+<pre>
+ &lt;wlrun taskname=&quot;petstore&quot;
+ classpath=&quot;${weblogic.classes}&quot;
+ name=&quot;petstoreServer&quot;
+ domain=&quot;petstore&quot;
+ home=&quot;${weblogic.home}&quot;
+ password=&quot;petstorePassword&quot;
+ beahome=&quot;${bea.home}&quot;/&gt;
+</pre>
+
+<hr>
+<h2><a name="wlstop">wlstop</a></h2>
+<h3><b>Description:</b></h3>
+
+<p>The <code>wlstop</code> task is used to stop a weblogic instance which is
+currently running. To shut down an instance you must supply both a username and
+a password. These will be stored in the clear in the build script used to stop
+the instance. For security reasons, this task is therefore only appropriate in a
+development environment. </p>
+
+<p>This task works for most version of Weblogic, including 6.0. You need to
+specify the BEA Home to have this task work correctly under 6.0</p>
+
+<h3>Parameters:</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">BEAHome</td>
+ <td valign="top">This attribute selects Weblogic 6.0 shutdown.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">classpath</td>
+ <td valign="top">The classpath to be used with the Java Virtual Machine that runs the Weblogic
+ Shutdown command.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">user</td>
+ <td valign="top">The username of the account which will be used to shutdown the server</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">password</td>
+ <td valign="top">The password for the account specified in the user parameter.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">url</td>
+ <td valign="top">The URL which describes the port to which the server is listening for T3 connections.
+ For example, t3://localhost:7001</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">delay</td>
+ <td valign="top">The delay in seconds after which the server will stop. This defaults to an
+ immediate shutdown.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+</table>
+
+<h3>Nested Element</h3>
+
+<p>The classpath of the wlstop task can be set by a <code>&lt;classpath&gt;</code> nested element.</p>
+
+<h3>Examples</h3>
+
+<p>This example show the shutdown for a Weblogic 6.0 server</p>
+
+<pre>
+ &lt;wlstop classpath=&quot;${weblogic.classes}&quot;
+ user=&quot;system&quot;
+ url=&quot;t3://localhost:7001&quot;
+ password=&quot;foobar&quot;
+ beahome=&quot;${bea.home}&quot;/&gt;
+</pre>
+
+<hr>
+
+<h2><a name="ejbjar">ejbjar</a></h2>
+<h3><b>Description:</b></h3>
+
+<p>This task is designed to support building of EJB jar files (EJB 1.1 &amp; 2.0).
+Support is currently provided for 'vanilla' EJB jar files - i.e. those containing only
+the user generated class files and the standard deployment descriptor. Nested
+elements provide support for vendor specific deployment tools. These currently
+include: </p>
+<ul>
+ <li>Borland Application Server 4.5</li>
+ <li>iPlanet Application Server 6.0</li>
+ <li>JBoss 2.1 and above</li>
+ <li>Weblogic 5.1/6.0 session/entity beans using the weblogic.ejbc tool</li>
+ <li>IBM WebSphere 4.0</li>
+ <li>TOPLink for WebLogic 2.5.1-enabled entity beans</li>
+ <li><a href="http://www.objectweb.org/jonas/">JOnAS</a> 2.4.x and 2.5 Open Source EJB server</li>
+</ul>
+
+
+<p>The task works as a directory scanning task, and performs an action for each
+deployment descriptor found. As such the includes and excludes should be set
+to ensure that all desired EJB descriptors are found, but no application
+server descriptors are found. For each descriptor found, ejbjar will parse the
+deployment descriptor to determine the necessary class files which implement the
+bean. These files are assembled along with the deployment descriptors into a
+well formed EJB jar file. Any support files which need to be included in the
+generated jar can be added with the <code>&lt;support&gt;</code> nested element. For each
+class included in the jar, ejbjar will scan for any super classes or super
+interfaces. These will be added to the generated jar.</p>
+
+<p>If no nested vendor-specific deployment elements are present, the task will
+simply generate a generic EJB jar. Such jars are typically used as the input to
+vendor-specific deployment tools. For each nested deployment element, a vendor
+specific deployment tool is run to generate a jar file ready for deployment in
+that vendor's EJB container. </p>
+
+<p>The jar files are only built if they are out of date. Each deployment tool
+element will examine its target jar file and determine if it is out of date with
+respect to the class files and deployment descriptors that make up the bean. If
+any of these files are newer than the jar file the jar will be rebuilt otherwise
+a message is logged that the jar file is up to date.</p>
+
+<p>The task uses the
+<a href="http://commons.apache.org/bcel/"> BCEL </a> framework
+to extract all dependent classes. This
+means that, in addition to the classes that are mentioned in the
+deployment descriptor, any classes that these depend on are also
+automatically included in the jar file.</p>
+
+
+<h3>Naming Convention</h3>
+
+Ejbjar handles the processing of multiple beans, and it uses a set of naming
+conventions to determine the name of the generated EJB jars. The naming convention
+that is used is controlled by the &quot;naming&quot; attribute. It supports the
+following values
+<ul>
+
+<li>descriptor</li>
+<p>This is the default naming scheme. The name of the generated bean is derived from the
+name of the deployment descriptor. For an Account bean, for example, the deployment
+descriptor would be named <code>Account-ejb-jar.xml</code>. Vendor specific descriptors are
+located using the same naming convention. The weblogic bean, for example, would be named
+<code>Account-weblogic-ejb-jar.xml</code>. Under this arrangement, the deployment descriptors
+can be separated from the code implementing the beans, which can be useful when the same bean code
+is deployed in separate beans.
+</p>
+
+<p>This scheme is useful when you are using one bean per EJB jar and where you may be
+deploying the same bean classes in different beans, with different deployment characteristics.
+
+<li>ejb-name</li>
+<p> This naming scheme uses the <code>&lt;ejb-name&gt;</code> element from the deployment descriptor to
+determine the bean name. In this situation, the descriptors normally use the generic
+descriptor names, such as <code>ejb-jar.xml</code> along with any associated vendor specific descriptor
+names. For example, If the value of the <code>&lt;ejb-name&gt;</code> were to be given in the deployment descriptor
+as follows:
+<pre>
+&lt;ejb-jar&gt;
+ &lt;enterprise-beans&gt;
+ &lt;entity&gt;
+ &lt;ejb-name&gt;Sample&lt;/ejb-name&gt;
+ &lt;home&gt;org.apache.ant.ejbsample.SampleHome&lt;/home&gt;
+</pre>
+
+then the name of the generated bean would be <code>Sample.jar</code>
+</p>
+<p> This scheme is useful where you want to use the standard deployment descriptor names, which may be more
+compatible with other EJB tools. This scheme must have one bean per jar.
+</p>
+<li>directory</li>
+<p>
+In this mode, the name of the generated bean jar is derived from the directory
+containing the deployment descriptors. Again the deployment descriptors typically use
+the standard filenames. For example, if the path to the deployment descriptor is
+<code>/home/user/dev/appserver/dd/sample</code>, then the generated
+bean will be named <code>sample.jar</code>
+</p>
+<p>
+This scheme is also useful when you want to use standard style descriptor names. It is often
+most useful when the descriptors are located in the same directory as the bean source code,
+although that is not mandatory. This scheme can handle multiple beans per jar.
+</p>
+
+<li>basejarname</li>
+<p>
+The final scheme supported by the <code>&lt;ejbjar&gt;</code> task is used when you want to specify the generated
+bean jar name directly. In this case the name of the generated jar is specified by the
+&quot;basejarname&quot; attribute. Since all generated beans will have the same name, this task should
+be only used when each descriptor is in its own directory.
+</p>
+
+<p>
+This scheme is most appropriate when you are using multiple beans per jar and only process a single
+deployment descriptor. You typically want to specify the name of the jar and not derive it from the
+beans in the jar.
+</p>
+
+</ul>
+
+<a name="ejbjar_deps"><h3>Dependencies</h3></a>
+<p>In addition to the bean classes, ejbjar is able to ad additional classes to the generated
+ejbjar. These classes are typically the support classes which are used by the bean's classes or as
+parameters to the bean's methods.</p>
+
+<p>In versions of Ant prior to 1.5, ejbjar used reflection and attempted to add the super
+classes and super interfaces of the bean classes. For this technique to work the bean
+classes had to be loaded into Ant's JVM. This was not always possible due to class dependencies.
+</p>
+
+<p>The ejbjar task in Ant releases 1.5 and later uses the
+<a href="http://commons.apache.org/bcel/"> BCEL </a> library
+to analyze the bean's class
+files directly, rather than loading them into the JVM. This also allows ejbjar to add all
+of the required support classes for a bean and not just super classes.
+</p>
+
+<p>In Ant 1.5, a new attribute, <code>dependency</code> has been introduced to allow the
+buildfile to control what additional classes are added to the generated jar. It takes three
+possible values</p>
+<ul>
+<li><code>none</code> - only the bean classes and interfaces described in the bean's
+descriptor are added to the jar.</li>
+<li><code>super</code> - this is the default value and replicates the original ejbjar
+behaviour where super classes and super interfaces are added to the jar</li>
+<li><code>full</code> - In this mode all classes used by the bean's classes and interfaces
+are added to the jar</li>
+</ul>
+<p>The <code>super</code> and <code>full</code> values require the
+<a href="http://commons.apache.org/bcel/"> BCEL </a> library
+to be available. If it is not, ejbjar will drop back to the behaviour corresponding to
+the value <code>none</code>.</p>
+
+<h3>Parameters:</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">descriptordir</td>
+ <td valign="top">The base directory under which to scan for EJB
+ deployment descriptors. If this attribute is not
+ specified, then the deployment descriptors must be
+ located in the directory specified by the 'srcdir'
+ attribute.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">srcdir</td>
+ <td valign="top">The base directory containing the .class files that
+ make up the bean. Included are the home- remote- pk-
+ and implementation- classes and all classes, that these
+ depend on. Note that this can be the same as the
+ descriptordir if all files are in the same directory
+ tree.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">destdir</td>
+ <td valign="top">The base directory into which generated jar files are
+ deposited. Jar files are deposited in directories
+ corresponding to their location within the descriptordir
+ namespace. Note that this attribute is only used if the
+ task is generating generic jars (i.e. no vendor-specific
+ deployment elements have been specified).</td>
+ <td valign="top" align="center">Yes, unless vendor-specific deployment elements
+ have been specified.</td>
+ </tr>
+ <tr>
+ <td valign="top">cmpversion</td>
+ <td valign="top">Either <code>1.0</code> or <code>2.0</code>.<br>
+ Default is <code>1.0</code>.<br>
+ A CMP 2.0 implementation exists currently only for JBoss.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">naming</td>
+ <td valign="top">Controls the naming convention used to name generated
+ EJB jars. Please refer to the description above.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">basejarname</td>
+ <td valign="top">The base name that is used for the generated jar files.
+ If this attribute is specified, the generic jar file name
+ will use this value as the prefix (followed by the value
+ specified in the 'genericjarsuffix' attribute) and the
+ resultant ejb jar file (followed by any suffix specified
+ in the nested element).</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">basenameterminator</td>
+ <td valign="top">String value used to substring out a string from the name
+ of each deployment descriptor found, which is then used to
+ locate related deployment descriptors (e.g. the WebLogic
+ descriptors). For example, a basename of '.' and a
+ deployment descriptor called 'FooBean.ejb-jar.xml' would
+ result in a basename of 'FooBean' which would then be used
+ to find FooBean.weblogic-ejb-jar.xml and
+ FooBean.weblogic-cmp-rdbms-jar.xml, as well as to create
+ the filenames of the jar files as FooBean-generic.jar and
+ FooBean-wl.jar. This attribute is not used if the
+ 'basejarname' attribute is specified.</td>
+ <td valign="top" align="center">No, defaults to '-'.</td>
+ </tr>
+ <tr>
+ <td valign="top">genericjarsuffix</td>
+ <td valign="top">String value appended to the basename of the deployment
+ descriptor to create the filename of the generic EJB jar
+ file.</td>
+ <td valign="top" align="center">No, defaults to '-generic.jar'.</td>
+ </tr>
+ <tr>
+ <td valign="top">classpath</td>
+ <td valign="top">This classpath is used when resolving classes which
+ are to be added to the jar. Typically nested deployment
+ tool elements will also support a classpath which
+ will be combined with this classpath when resolving
+ classes</td>
+ <td valign="top" align="center">No.</td>
+ </tr>
+ <tr>
+ <td valign="top">flatdestdir</td>
+ <td valign="top">Set this attribute to true if you want all generated jars
+ to be placed in the root of the destdir, rather than
+ according to the location of the deployment descriptor
+ within the descriptor dir hierarchy.</td>
+ <td valign="top" align="center">No.</td>
+ </tr>
+ <tr>
+ <td valign="top">dependency</td>
+ <td valign="top">This attribute controls which additional classes and interfaces
+ are added to the jar. Please refer to the description
+ <a href="#ejbjar_deps">above</a></td>
+ <td valign="top" align="center">No.</td>
+ </tr>
+ <tr>
+ <td valign="top">manifest</td>
+ <td valign="top">the manifest file to use, if any.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+</table>
+
+<h3>Nested Elements</h3>
+
+<p>In addition to the vendor specific nested elements, the ejbjar task provides
+three nested elements. </p>
+
+<h4>Classpath</h4>
+
+<p>The <code>&lt;classpath&gt;</code> nested element allows the classpath
+to be set. It is useful when setting the classpath from a reference path. In all
+other respects the behaviour is the same as the classpath attribute.</p>
+
+<a name="ejbjar-dtd"><h4>dtd</h4></a>
+
+<p>The <code>&lt;dtd&gt;</code> element is used to specify the local location of DTDs to be
+used when parsing the EJB deployment descriptor. Using a local DTD is much
+faster than loading the DTD across the net. If you are running ejbjar behind a
+firewall you may not even be able to access the remote DTD. The supported
+vendor-specific nested elements know the location of the required DTDs within
+the vendor class hierarchy and, in general, this means <code>&lt;dtd&gt;</code> elements are
+not required. It does mean, however, that the vendor's class hierarchy must be
+available in the classpath when Ant is started. If your want to run Ant without
+requiring the vendor classes in the classpath, you would need to use a
+<code>&lt;dtd&gt;</code> element.</p>
+
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">publicId</td>
+ <td valign="top">The public Id of the DTD for which the location is being provided</td>
+ <td align="center" valign="top">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">location</td>
+ <td valign="top">The location of the local copy of the DTD. This can either be a
+ file or a resource loadable from the classpath.</td>
+ <td align="center" valign="top">Yes</td>
+ </tr>
+</table>
+
+<h4>support</h4>
+
+<p>The <code>&lt;support&gt;</code> nested element is used to supply additional classes
+(files) to be included in the generated jars. The <code>&lt;support&gt;</code> element is a
+<a href="../Types/fileset.html">FileSet</a>, so it can either reference a fileset declared elsewhere or it can be
+defined in-place with the appropriate <code>&lt;include&gt;</code> and <code>&lt;exclude&gt;</code> nested
+elements. The files in the support fileset are added into the generated EJB jar
+in the same relative location as their location within the support fileset. Note
+that when ejbjar generates more than one jar file, the support files are added
+to each one.</p>
+
+<h3>Vendor-specific deployment elements</h3>
+
+Each vendor-specific nested element controls the generation of a deployable jar
+specific to that vendor's EJB container. The parameters for each supported
+deployment element are detailed here.
+
+
+<h3><a name="ejbjar_jboss">Jboss element</a></h3>
+
+<p>The jboss element searches for the JBoss specific deployment descriptors and adds them
+to the final ejb jar file. JBoss has two deployment descriptors:
+<ul><li>jboss.xml</li>
+<li>for container manager persistence:<br>
+<table border="1">
+<tr><td><b>CMP version</b></td><td><b>File name</b></td></tr>
+<tr><td>CMP 1.0</td><td>jaws.xml</td></tr>
+<tr><td>CMP 2.0</td><td>jbosscmp-jdbc.xml</td></tr>
+</table>
+</li>
+</ul>
+<br>
+. The JBoss server uses hot deployment and does
+not require compilation of additional stubs and skeletons.</p>
+
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">destdir</td>
+ <td valign="top">The base directory into which the generated weblogic ready
+ jar files are deposited. Jar files are deposited in
+ directories corresponding to their location within the
+ descriptordir namespace. </td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">genericjarsuffix</td>
+ <td valign="top">A generic jar is generated as an intermediate step in
+ build the weblogic deployment jar. The suffix used to
+ generate the generic jar file is not particularly
+ important unless it is desired to keep the generic
+ jar file. It should not, however, be the same
+ as the suffix setting.</td>
+ <td valign="top" align="center">No, defaults to '-generic.jar'.</td>
+ </tr>
+ <tr>
+ <td valign="top">suffix</td>
+ <td valign="top">String value appended to the basename of the deployment
+ descriptor to create the filename of the JBoss EJB
+ jar file.</td>
+ <td valign="top" align="center">No, defaults to '.jar'.</td>
+ </tr>
+ <tr>
+ <td valign="top">keepgeneric</td>
+ <td valign="top">This controls whether the generic file used as input to
+ ejbc is retained.</td>
+ <td valign="top" align="center">No, defaults to false</td>
+ </tr>
+</table>
+
+
+<h3><a name="ejbjar_weblogic">Weblogic element</a></h3>
+
+<p>The weblogic element is used to control the weblogic.ejbc compiler for
+generating weblogic EJB jars. Prior to Ant 1.3, the method of locating CMP
+descriptors was to use the ejbjar naming convention. So if your ejb-jar was
+called, Customer-ejb-jar.xml, your weblogic descriptor was called Customer-
+weblogic-ejb-jar.xml and your CMP descriptor had to be Customer-weblogic-cmp-
+rdbms-jar.xml. In addition, the <code>&lt;type-storage&gt;</code> element in the weblogic
+descriptor had to be set to the standard name META-INF/weblogic-cmp-rdbms-
+jar.xml, as that is where the CMP descriptor was mapped to in the generated
+jar.</p>
+
+<p>There are a few problems with this scheme. It does not allow for more than
+one CMP descriptor to be defined in a jar and it is not compatible with the
+deployment descriptors generated by some tools.</p>
+
+<p>In Ant 1.3, ejbjar parses the weblogic deployment descriptor to discover the
+CMP descriptors, which are then included automatically. This behaviour is
+controlled by the newCMP attribute. Note that if you move to the new method of
+determining CMP descriptors, you will need to update your weblogic deployment
+descriptor's <code>&lt;type-storage&gt;</code> element. In the above example, you would
+define this as META-INF/Customer-weblogic-cmp-rdbms-jar.xml.</p>
+
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">destdir</td>
+ <td valign="top">The base directory into which the generated weblogic ready
+ jar files are deposited. Jar files are deposited in
+ directories corresponding to their location within the
+ descriptordir namespace. </td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">genericjarsuffix</td>
+ <td valign="top">A generic jar is generated as an intermediate step in
+ build the weblogic deployment jar. The suffix used to
+ generate the generic jar file is not particularly
+ important unless it is desired to keep the generic
+ jar file. It should not, however, be the same
+ as the suffix setting.</td>
+ <td valign="top" align="center">No, defaults to '-generic.jar'.</td>
+ </tr>
+ <tr>
+ <td valign="top">suffix</td>
+ <td valign="top">String value appended to the basename of the deployment
+ descriptor to create the filename of the WebLogic EJB
+ jar file.</td>
+ <td valign="top" align="center">No, defaults to '.jar'.</td>
+ </tr>
+ <tr>
+ <td valign="top">classpath</td>
+ <td valign="top">The classpath to be used when running the weblogic ejbc
+ tool. Note that this tool typically requires the classes
+ that make up the bean to be available on the classpath.
+ Currently, however, this will cause the ejbc tool to be
+ run in a separate VM</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">wlclasspath</td>
+ <td valign="top">Weblogic 6.0 will give a warning if the home and remote interfaces
+ of a bean are on the system classpath used to run weblogic.ejbc.
+ In that case, the standard weblogic classes should be set with
+ this attribute (or equivalent nested element) and the
+ home and remote interfaces located with the standard classpath
+ attribute</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">keepgeneric</td>
+ <td valign="top">This controls whether the generic file used as input to
+ ejbc is retained.</td>
+ <td valign="top" align="center">No, defaults to false</td>
+ </tr>
+ <tr>
+ <td valign="top">compiler</td>
+ <td valign="top">This allows for the selection of a different compiler
+ to be used for the compilation of the generated Java
+ files. This could be set, for example, to Jikes to
+ compile with the Jikes compiler. If this is not set
+ and the <code>build.compiler</code> property is set
+ to jikes, the Jikes compiler will be used. If this
+ is not desired, the value &quot;<code>default</code>&quot;
+ may be given to use the default compiler</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">rebuild</td>
+ <td valign="top">This flag controls whether weblogic.ejbc is always
+ invoked to build the jar file. In certain circumstances,
+ such as when only a bean class has been changed, the jar
+ can be generated by merely replacing the changed classes
+ and not rerunning ejbc. Setting this to false will reduce
+ the time to run ejbjar.
+ </td>
+ <td valign="top" align="center">No, defaults to true.</td>
+ </tr>
+ <tr>
+ <td valign="top">keepgenerated</td>
+ <td valign="top">Controls whether weblogic will keep the generated Java
+ files used to build the class files added to the
+ jar. This can be useful when debugging
+ </td>
+ <td valign="top" align="center">No, defaults to false.</td>
+ </tr>
+ <tr>
+ <td valign="top">args</td>
+ <td valign="top">Any additional arguments to be passed to the weblogic.ejbc
+ tool.
+ </td>
+ <td valign="top" align="center">No.</td>
+ </tr>
+ <tr>
+ <td valign="top">weblogicdtd</td>
+ <td valign="top"><b>Deprecated</b>. Defines the location of the ejb-jar DTD in
+ the weblogic class hierarchy. This should not be necessary if you
+ have weblogic in your classpath. If you do not, you should use a
+ nested <code>&lt;dtd&gt;</code> element, described above. If you do choose
+ to use an attribute, you should use a
+ nested <code>&lt;dtd&gt;</code> element.
+ </td>
+ <td valign="top" align="center">No.</td>
+ </tr>
+ <tr>
+ <td valign="top">wldtd</td>
+ <td valign="top"><b>Deprecated</b>. Defines the location of the weblogic-ejb-jar
+ DTD which covers the Weblogic specific deployment descriptors.
+ This should not be necessary if you have weblogic in your
+ classpath. If you do not, you should use a nested <code>&lt;dtd&gt;</code>
+ element, described above.
+ </td>
+ <td valign="top" align="center">No.</td>
+ </tr>
+ <tr>
+ <td valign="top">ejbdtd</td>
+ <td valign="top"><b>Deprecated</b>. Defines the location of the ejb-jar DTD in
+ the weblogic class hierarchy. This should not be necessary if you
+ have weblogic in your classpath. If you do not, you should use a
+ nested <code>&lt;dtd&gt;</code> element, described above.
+ </td>
+ <td valign="top" align="center">No.</td>
+ </tr>
+ <tr>
+ <td valign="top">newCMP</td>
+ <td valign="top">If this is set to true, the new method for locating
+ CMP descriptors will be used.</td>
+ <td valign="top" align="center">No. Defaults to false</td>
+ </tr>
+ <tr>
+ <td valign="top">oldCMP</td>
+ <td valign="top"><b>Deprecated</b> This is an antonym for newCMP which should be used instead.</td>
+ <td valign="top" align="center">No.</td>
+ </tr>
+ <tr>
+ <td valign="top">noEJBC</td>
+ <td valign="top">If this attribute is set to true, Weblogic's ejbc will not be run on the EJB jar.
+ Use this if you prefer to run ejbc at deployment time.</td>
+ <td valign="top" align="center">No.</td>
+ </tr>
+ <tr>
+ <td valign="top">ejbcclass</td>
+ <td valign="top">Specifies the classname of the ejbc compiler. Normally ejbjar determines
+ the appropriate class based on the DTD used for the EJB. The EJB 2.0 compiler
+ featured in weblogic 6 has, however, been deprecated in version 7. When
+ using with version 7 this attribute should be set to
+ &quot;weblogic.ejbc&quot; to avoid the deprecation warning.</td>
+ <td valign="top" align="center">No.</td>
+ </tr>
+ <tr>
+ <td valign="top">jvmargs</td>
+ <td valign="top">Any additional arguments to be passed to the Virtual Machine
+ running weblogic.ejbc tool. For example to set the memory size,
+ this could be jvmargs=&quot;-Xmx128m&quot;
+ </td>
+ <td valign="top" align="center">No.</td>
+ </tr>
+ <tr>
+ <td valign="top">jvmdebuglevel</td>
+ <td valign="top">Sets the weblogic.StdoutSeverityLevel to use when running
+ the Virtual Machine that executes ejbc. Set to 16 to avoid
+ the warnings about EJB Home and Remotes being in the classpath
+ </td>
+ <td valign="top" align="center">No.</td>
+ </tr>
+ <tr>
+ <td valign="top">outputdir</td>
+ <td valign="top">If set ejbc will be given this directory as the output
+ destination rather than a jar file. This allows for the
+ generation of &quot;exploded&quot; jars.
+ </td>
+ <td valign="top" align="center">No.</td>
+ </tr>
+</table>
+
+<p>The weblogic nested element supports three nested elements. The
+first two, <code>&lt;classpath&gt;</code> and <code>&lt;wlclasspath&gt;</code>, are used to set the
+respective classpaths. These nested elements are useful when setting up
+class paths using reference Ids. The last, <code>&lt;sysproperty&gt;</code>, allows
+Java system properties to be set during the compiler run. This turns out
+to be necessary for supporting CMP EJB compilation in all environments.
+</p>
+
+<h3>TOPLink for Weblogic element</h3>
+
+<p><b><i>Deprecated</i></b></p>
+
+<p>The toplink element is no longer required. Toplink beans can now be built with the standard
+weblogic element, as long as the newCMP attribute is set to &quot;true&quot;
+</p>
+
+<p>The TopLink element is used to handle beans which use Toplink for the CMP operations. It
+is derived from the standard weblogic element so it supports the same set of attributes plus these
+additional attributes</p>
+
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">toplinkdescriptor</td>
+ <td valign="top">This specifies the name of the TOPLink deployment descriptor file contained in the
+ 'descriptordir' directory.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">toplinkdtd</td>
+ <td valign="top">This specifies the location of the TOPLink DTD file. This can be a file path or
+ a file URL. This attribute is not required, but using a local DTD is recommended.</td>
+ <td valign="top" align="center">No, defaults to dtd file at www.objectpeople.com.</td>
+ </tr>
+</table>
+
+
+<h3>Examples</h3>
+
+<p>This example shows ejbjar being used to generate deployment jars using a
+Weblogic EJB container. This example requires the naming standard to be used for
+the deployment descriptors. Using this format will create a ejb jar file for
+each variation of '*-ejb-jar.xml' that is found in the deployment descriptor
+directory.</p>
+
+<pre>
+ &lt;ejbjar srcdir=&quot;${build.classes}&quot;
+ descriptordir=&quot;${descriptor.dir}&quot;&gt;
+ &lt;weblogic destdir=&quot;${deploymentjars.dir}&quot;
+ classpath=&quot;${descriptorbuild.classpath}&quot;/&gt;
+ &lt;include name=&quot;**/*-ejb-jar.xml&quot;/&gt;
+ &lt;exclude name=&quot;**/*weblogic*.xml&quot;/&gt;
+ &lt;/ejbjar&gt;
+</pre>
+
+<p>If weblogic is not in the Ant classpath, the following example
+shows how to specify the location of the weblogic DTDs. This
+example also show the use of a nested classpath element.</p>
+
+<pre>
+ &lt;ejbjar descriptordir=&quot;${src.dir}&quot; srcdir=&quot;${build.classes}&quot;&gt;
+ &lt;weblogic destdir=&quot;${deployment.webshop.dir}&quot;
+ keepgeneric=&quot;true&quot;
+ args=&quot;-g -keepgenerated ${ejbc.compiler}&quot;
+ suffix=&quot;.jar&quot;
+ oldCMP=&quot;false&quot;&gt;
+ &lt;classpath&gt;
+ &lt;pathelement path=&quot;${descriptorbuild.classpath}&quot;/&gt;
+ &lt;/classpath&gt;
+ &lt;/weblogic&gt;
+ &lt;include name=&quot;**/*-ejb-jar.xml&quot;/&gt;
+ &lt;exclude name=&quot;**/*-weblogic-ejb-jar.xml&quot;/&gt;
+ &lt;dtd publicId=&quot;-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 1.1//EN&quot;
+ location=&quot;${weblogic.home}/classes/weblogic/ejb/deployment/xml/ejb-jar.dtd&quot;/&gt;
+ &lt;dtd publicId=&quot;-//BEA Systems, Inc.//DTD WebLogic 5.1.0 EJB//EN&quot;
+ location=&quot;${weblogic.home}/classes/weblogic/ejb/deployment/xml/weblogic-ejb-jar.dtd&quot;/&gt;
+ &lt;/ejbjar&gt;
+</pre>
+
+
+<p>This example shows ejbjar being used to generate a single deployment jar
+using a Weblogic EJB container. This example does not require the deployment
+descriptors to use the naming standard. This will create only one ejb jar file -
+'TheEJBJar.jar'.</p>
+
+
+<pre>
+ &lt;ejbjar srcdir=&quot;${build.classes}&quot;
+ descriptordir=&quot;${descriptor.dir}&quot;
+ basejarname=&quot;TheEJBJar&quot;&gt;
+ &lt;weblogic destdir=&quot;${deploymentjars.dir}&quot;
+ classpath=&quot;${descriptorbuild.classpath}&quot;/&gt;
+ &lt;include name=&quot;**/ejb-jar.xml&quot;/&gt;
+ &lt;exclude name=&quot;**/weblogic*.xml&quot;/&gt;
+ &lt;/ejbjar&gt;
+</pre>
+
+<p>This example shows ejbjar being used to generate deployment jars for a TOPLink-enabled entity bean using a
+Weblogic EJB container. This example does not require the deployment descriptors to use the naming standard.
+This will create only one TOPLink-enabled ejb jar file - 'Address.jar'.</p>
+
+<pre>
+ &lt;ejbjar srcdir=&quot;${build.dir}&quot;
+ destdir=&quot;${solant.ejb.dir}&quot;
+ descriptordir=&quot;${descriptor.dir}&quot;
+ basejarname=&quot;Address&quot;&gt;
+ &lt;weblogictoplink destdir=&quot;${solant.ejb.dir}&quot;
+ classpath=&quot;${java.class.path}&quot;
+ keepgeneric=&quot;false&quot;
+ toplinkdescriptor=&quot;Address.xml&quot;
+ toplinkdtd=&quot;file:///dtdfiles/toplink-cmp_2_5_1.dtd&quot;
+ suffix=&quot;.jar&quot;/&gt;
+ &lt;include name=&quot;**/ejb-jar.xml&quot;/&gt;
+ &lt;exclude name=&quot;**/weblogic-ejb-jar.xml&quot;/&gt;
+ &lt;/ejbjar&gt;
+</pre>
+
+<p>This final example shows how you would set-up ejbjar under Weblogic 6.0. It also shows the use of the
+<code>&lt;support&gt;</code> element to add support files</p>
+
+<pre>
+ &lt;ejbjar descriptordir=&quot;${dd.dir}&quot; srcdir=&quot;${build.classes.server}&quot;&gt;
+ &lt;include name=&quot;**/*-ejb-jar.xml&quot;/&gt;
+ &lt;exclude name=&quot;**/*-weblogic-ejb-jar.xml&quot;/&gt;
+ &lt;support dir=&quot;${build.classes.server}&quot;&gt;
+ &lt;include name=&quot;**/*.class&quot;/&gt;
+ &lt;/support&gt;
+ &lt;weblogic destdir=&quot;${deployment.dir}&quot;
+ keepgeneric=&quot;true&quot;
+ suffix=&quot;.jar&quot;
+ rebuild=&quot;false&quot;&gt;
+ &lt;classpath&gt;
+ &lt;pathelement path=&quot;${build.classes.server}&quot;/&gt;
+ &lt;/classpath&gt;
+ &lt;wlclasspath&gt;
+ &lt;pathelement path=&quot;${weblogic.classes}&quot;/&gt;
+ &lt;/wlclasspath&gt;
+ &lt;/weblogic&gt;
+ &lt;/ejbjar&gt;
+</pre>
+
+
+<h3><a name="ejbjar_websphere">WebSphere element</a></h3>
+
+<p>The websphere element searches for the websphere specific deployment descriptors and
+adds them to the final ejb jar file. Websphere has two specific descriptors for session
+beans:
+<ul>
+ <li>ibm-ejb-jar-bnd.xmi</li>
+ <li>ibm-ejb-jar-ext.xmi</li>
+</ul>
+and another two for container managed entity beans:
+<ul>
+ <li>Map.mapxmi</li>
+ <li>Schema.dbxmi</li>
+</ul>
+In terms of WebSphere, the generation of container code and stubs is called <code>deployment</code>.
+This step can be performed by the websphere element as part of the jar generation process. If the
+switch <code>ejbdeploy</code> is on, the ejbdeploy tool from the websphere toolset is called for
+every ejb-jar. Unfortunately, this step only works, if you use the ibm jdk. Otherwise, the rmic
+(called by ejbdeploy) throws a ClassFormatError. Be sure to switch ejbdeploy off, if run ant with
+Oracle JDK or OpenJDK.
+</p>
+
+<p>
+For the websphere element to work, you have to provide a complete classpath, that contains all
+classes, that are required to reflect the bean classes. For ejbdeploy to work, you must also provide
+the classpath of the ejbdeploy tool and set the <i>websphere.home</i> property (look at the examples below).
+</p>
+
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">destdir</td>
+ <td valign="top">The base directory into which the generated weblogic ready
+ jar files are deposited. Jar files are deposited in
+ directories corresponding to their location within the
+ descriptordir namespace. </td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">ejbdeploy</td>
+ <td valign="top">Decides whether ejbdeploy is called. When you set this to true,
+ be sure, to run ant with the ibm jdk.</td>
+ <td valign="top" align="center">No, defaults to true</td>
+ </tr>
+ <tr>
+ <td valign="top">suffix</td>
+ <td valign="top">String value appended to the basename of the deployment
+ descriptor to create the filename of the WebLogic EJB
+ jar file.</td>
+ <td valign="top" align="center">No, defaults to '.jar'.</td>
+ </tr>
+ <tr>
+ <td valign="top">keepgeneric</td>
+ <td valign="top">This controls whether the generic file used as input to
+ ejbdeploy is retained.</td>
+ <td valign="top" align="center">No, defaults to false</td>
+ </tr>
+ <tr>
+ <td valign="top">rebuild</td>
+ <td valign="top">This controls whether ejbdeploy is called although no changes
+ have occurred.</td>
+ <td valign="top" align="center">No, defaults to false</td>
+ </tr>
+ <tr>
+ <td valign="top">tempdir</td>
+ <td valign="top">A directory, where ejbdeploy will write temporary files</td>
+ <td valign="top" align="center">No, defaults to '_ejbdeploy_temp'.</td>
+ </tr>
+ <tr>
+ <td valign="top">dbName<br>dbSchema</td>
+ <td valign="top">These options are passed to ejbdeploy.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">dbVendor</td>
+ <td valign="top">This option is passed to ejbdeploy.
+ <p>
+ Valid options can be obtained by running the following command:
+ <code>
+ &lt;WAS_HOME&gt;/bin/EJBDeploy.[sh/bat] -help
+ </code>
+ </p>
+ This is also used to determine the name of the Map.mapxmi and
+ Schema.dbxmi files, for example Account-DB2UDBWIN_V71-Map.mapxmi
+ and Account-DB2UDBWIN_V71-Schema.dbxmi.
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">codegen<br>quiet<br>novalidate<br>noinform<br>trace<br>
+ use35MappingRules</td>
+ <td valign="top">These options are all passed to ejbdeploy. All options
+ except 'quiet' default to false.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">rmicOptions</td>
+ <td valign="top">This option is passed to ejbdeploy and will be passed
+ on to rmic.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+</table>
+
+<p>This example shows ejbjar being used to generate deployment jars for all deployment descriptors
+in the descriptor dir:</p>
+
+<pre>
+ &lt;property name=&quot;websphere.home&quot; value=&quot;${was4.home}&quot;/&gt;
+ &lt;ejbjar srcdir="${build.class}" descriptordir="etc/ejb"&gt;
+ &lt;include name="*-ejb-jar.xml"/&gt;
+ &lt;websphere dbvendor="DB2UDBOS390_V6"
+ ejbdeploy="true"
+ oldCMP="false"
+ tempdir="/tmp"
+ destdir="${dist.server}"&gt;
+ &lt;wasclasspath&gt;
+ &lt;pathelement location="${was4.home}/deploytool/itp/plugins/org.eclipse.core.boot/boot.jar"/&gt;
+ &lt;pathelement location="${was4.home}/deploytool/itp/plugins/com.ibm.etools.ejbdeploy/runtime/batch.jar"/&gt;
+ &lt;pathelement location="${was4.home}/lib/xerces.jar"/&gt;
+ &lt;pathelement location="${was4.home}/lib/ivjejb35.jar"/&gt;
+ &lt;pathelement location="${was4.home}/lib/j2ee.jar"/&gt;
+ &lt;pathelement location="${was4.home}/lib/vaprt.jar"/&gt;
+ &lt;/wasclasspath&gt;
+ &lt;classpath&gt;
+ &lt;path refid="build.classpath"/&gt;
+ &lt;/classpath&gt;
+ &lt;/websphere&gt;
+ &lt;dtd publicId="-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 1.1//EN"
+ location="${lib}/dtd/ejb-jar_1_1.dtd"/&gt;
+ &lt;/ejbjar&gt;
+</pre>
+
+<h3><a name="ejbjar_iplanet">iPlanet Application Server (iAS) element</a></h3>
+
+The &lt;iplanet&lt; nested element is used to build iAS-specific stubs and
+
+skeletons and construct a JAR file which may be deployed to the iPlanet
+Application Server 6.0. The build process will always determine if
+the EJB stubs/skeletons and the EJB-JAR file are up to date, and it will
+do the minimum amount of work required.
+<p>Like the WebLogic element, a naming convention for the EJB descriptors
+is most commonly used to specify the name for the completed JAR file.
+For example, if the EJB descriptor ejb/Account-ejb-jar.xml is found in
+the descriptor directory, the iplanet element will search for an iAS-specific
+EJB descriptor file named ejb/Account-ias-ejb-jar.xml (if it isn't found,
+the task will fail) and a JAR file named ejb/Account.jar will be written
+in the destination directory. Note that when the EJB descriptors
+are added to the JAR file, they are automatically renamed META-INF/ejb-jar.xml
+and META-INF/ias-ejb-jar.xml.</p>
+<p>Of course, this naming behaviour can be modified by specifying attributes
+in the ejbjar task (for example, basejarname, basenameterminator, and flatdestdir)
+as well as the iplanet element (for example, suffix). Refer to the
+appropriate documentation for more details.</p>
+<h3>
+Parameters:</h3>
+
+<table border="1" cellpadding="2" cellspacing="0">
+<tr>
+<td valign="top"><b>Attribute</b></td>
+
+<td valign="top"><b>Description</b></td>
+
+<td align="center" valign="top"><b>Required</b></td>
+</tr>
+
+<tr>
+<td valign="top">destdir</td>
+
+<td valign="top">The base directory into which the generated JAR files will
+be written. Each JAR file is written in directories which correspond to
+their location within the "descriptordir" namespace.</td>
+
+<td align="center" valign="top">Yes</td>
+</tr>
+
+<tr>
+<td valign="top">classpath</td>
+
+<td valign="top">The classpath used when generating EJB stubs and skeletons.
+If omitted, the classpath specified in the "ejbjar" parent task will be
+used. If specified, the classpath elements will be prepended to the
+classpath specified in the parent "ejbjar" task. Note that nested "classpath"
+elements may also be used.</td>
+
+<td align="center" valign="top">No</td>
+</tr>
+
+<tr>
+<td valign="top">keepgenerated</td>
+
+<td valign="top">Indicates whether or not the Java source files which are
+generated by ejbc will be saved or automatically deleted. If "yes", the
+source files will be retained. If omitted, it defaults to "no". </td>
+
+<td align="center" valign="top">No</td>
+</tr>
+
+<tr>
+<td valign="top">debug</td>
+
+<td>Indicates whether or not the ejbc utility should log additional debugging
+statements to the standard output. If "yes", the additional debugging statements
+will be generated. If omitted, it defaults to "no". </td>
+
+<td align="center" valign="top">No</td>
+</tr>
+
+<tr>
+<td valign="top">iashome</td>
+
+<td>May be used to specify the "home" directory for this iAS installation.
+This is used to find the ejbc utility if it isn't included in the user's
+system path. If specified, it should refer to the [install-location]/iplanet/ias6/ias
+directory. If omitted, the ejbc utility must be on the user's system
+path. </td>
+
+<td align="center" valign="top">No</td>
+</tr>
+
+<tr>
+<td valign="top">suffix</td>
+
+<td>String value appended to the JAR filename when creating each JAR.
+If omitted, it defaults to ".jar". </td>
+
+<td align="center" valign="top">No</td>
+</tr>
+</table>
+
+<p>As noted above, the iplanet element supports additional <code>&lt;classpath&gt;</code>
+nested elements.</p>
+<h3>
+Examples</h3>
+This example demonstrates the typical use of the <code>&lt;iplanet&gt;</code> nested element.
+It will name each EJB-JAR using the "basename" prepended to each standard
+EJB descriptor. For example, if the descriptor named "Account-ejb-jar.xml"
+is processed, the EJB-JAR will be named "Account.jar"
+<pre>
+ &lt;ejbjar srcdir="${build.classesdir}"
+ descriptordir="${src}"&gt;
+
+ &lt;iplanet destdir="${assemble.ejbjar}"
+ classpath="${ias.ejbc.cpath}"/&gt;
+ &lt;include name="**/*-ejb-jar.xml"/&gt;
+ &lt;exclude name="**/*ias-*.xml"/&gt;
+ &lt;/ejbjar&gt;</pre>
+
+This example demonstrates the use of a nested classpath element as well
+as some of the other optional attributes.
+<pre>
+ &lt;ejbjar srcdir="${build.classesdir}"
+ descriptordir="${src}"&gt;
+
+ &lt;iplanet destdir="${assemble.ejbjar}"
+ iashome="${ias.home}"
+ debug="yes"
+ keepgenerated="yes"&gt;
+ &lt;classpath&gt;
+ &lt;pathelement path="."/&gt;
+ &lt;pathelement path="${build.classpath}"/&gt;
+ &lt;/classpath&gt;
+ &lt;/iplanet&gt;
+ &lt;include name="**/*-ejb-jar.xml"/&gt;
+ &lt;exclude name="**/*ias-*.xml"/&gt;
+ &lt;/ejbjar&gt;</pre>
+
+This example demonstrates the use of basejarname attribute. In this
+case, the completed EJB-JAR will be named "HelloWorld.jar" If multiple
+EJB descriptors might be found, care must be taken to ensure that the completed
+JAR files don't overwrite each other.
+<pre>
+ &lt;ejbjar srcdir="${build.classesdir}"
+ descriptordir="${src}"
+ basejarname="HelloWorld"&gt;
+
+ &lt;iplanet destdir="${assemble.ejbjar}"
+ classpath="${ias.ejbc.cpath}"/&gt;
+ &lt;include name="**/*-ejb-jar.xml"/&gt;
+ &lt;exclude name="**/*ias-*.xml"/&gt;
+ &lt;/ejbjar&gt;</pre>
+This example demonstrates the use of the dtd nested element. If the local
+copies of the DTDs are included in the classpath, they will be automatically
+referenced without the nested elements. In iAS 6.0 SP2, these local DTDs are
+found in the [iAS-install-directory]/APPS directory. In iAS 6.0 SP3, these
+local DTDs are found in the [iAS-install-directory]/dtd directory.
+<pre>
+ &lt;ejbjar srcdir="${build.classesdir}"
+ descriptordir="${src}"&gt;
+ &lt;iplanet destdir="${assemble.ejbjar}"&gt;
+ classpath="${ias.ejbc.cpath}"/&gt;
+ &lt;include name="**/*-ejb-jar.xml"/&gt;
+ &lt;exclude name="**/*ias-*.xml"/&gt;
+
+ &lt;dtd publicId="-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 1.1//EN"
+ location="${ias.home}/APPS/ejb-jar_1_1.dtd"/&gt;
+ &lt;dtd publicId="-//Sun Microsystems, Inc.//DTD iAS Enterprise JavaBeans 1.0//EN"
+ location="${ias.home}/APPS/IASEjb_jar_1_0.dtd"/&gt;
+ &lt;/ejbjar&gt;</pre>
+
+<h3><a name="ejbjar_jonas">JOnAS (Java Open Application Server) element</a></h3>
+
+<p>The <code>&lt;jonas&gt;</code> nested element is used to build JOnAS-specific stubs and
+skeletons thanks to the <code>GenIC</code> specific tool, and construct a JAR
+file which may be deployed to the JOnAS Application Server. The build process
+will always determine if the EJB stubs/skeletons and the EJB-JAR file are up to
+date, and it will do the minimum amount of work required.</p>
+
+<p>Like the WebLogic element, a naming convention for the EJB descriptors is
+most commonly used to specify the name for the completed JAR file. For example,
+if the EJB descriptor <code>ejb/Account-ejb-jar.xml</code> is found in the
+descriptor directory, the <code>&lt;jonas&gt;</code> element will search for a JOnAS-specific
+EJB descriptor file named <code>ejb/Account-jonas-ejb-jar.xml</code> and a JAR
+file named <code>ejb/Account.jar</code> will be written in the destination
+directory. But the <code>&lt;jonas&gt;</code> element can also use the JOnAS naming
+convention. With the same example as below, the EJB descriptor can also be named
+<code>ejb/Account.xml</code> (no base name terminator here) in the descriptor
+directory. Then the <code>&lt;jonas&gt;</code> element will search for a JOnAS-specific EJB
+descriptor file called <code>ejb/jonas-Account.xml</code>. This convention do
+not follow strictly the ejb-jar naming convention recommendation but is
+supported for backward compatibility with previous version of JOnAS.</p>
+
+<p>Note that when the EJB descriptors are added to the JAR file, they are
+automatically renamed <code>META-INF/ejb-jar.xml</code> and
+<code>META-INF/jonas-ejb-jar.xml</code>.</p>
+
+<p>Of course, this naming behavior can be modified by specifying attributes in
+the ejbjar task (for example, basejarname, basenameterminator, and flatdestdir)
+as well as the iplanet element (for example, suffix). Refer to the appropriate
+documentation for more details.</p>
+
+<h3> Parameters:</h3>
+
+<table border="1" cellspacing="0" cellpadding="2">
+ <tbody>
+ <tr>
+ <td valign="Top"><b>Attribute</b></td>
+ <td valign="Top"><b>Description</b></td>
+ <td align="Center" valign="Top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="Top">destdir</td>
+ <td valign="Top">The base directory into which the generated JAR files
+ will be written. Each JAR file is written in directories which correspond
+ to their location within the "<code>descriptordir</code>" namespace.</td>
+ <td align="Center" valign="Top">Yes</td>
+ </tr>
+ <tr>
+ <td valign="Top">jonasroot</td>
+ <td valign="Top">The root directory for JOnAS.</td>
+ <td valign="Top" align="Center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="Top">classpath</td>
+ <td valign="Top">The classpath used when generating EJB stubs and
+ skeletons. If omitted, the classpath specified in the "ejbjar" parent
+ task will be used. If specified, the classpath elements will be prepended
+ to the classpath specified in the parent "ejbjar" task (see also the ORB
+ attribute documentation below). Note that nested "classpath" elements may
+ also be used.</td>
+ <td valign="Top" align="Center">No</td>
+ </tr>
+ <tr>
+ <td valign="Top">keepgenerated</td>
+ <td valign="Top"><code>true</code> if the intermediate Java
+ source files generated by GenIC must be deleted or not. If
+ omitted, it defaults to <code>false</code>.</td>
+ <td align="Center" valign="Top">No</td>
+ </tr>
+ <tr>
+ <td valign="Top">nocompil</td>
+ <td valign="Top"><code>true</code> if the generated source files
+ must not be compiled via the java and rmi compilers. If omitted,
+ it defaults to <code>false</code>.</td>
+ <td align="Center" valign="Top">No</td>
+ </tr>
+ <tr>
+ <td valign="Top">novalidation</td>
+ <td valign="Top"><code>true</code> if the XML deployment descriptors must
+ be parsed without validation. If omitted, it defaults to <code>false</code>.</td>
+ <td align="Center" valign="Top">No</td>
+ </tr>
+ <tr>
+ <td valign="Top">javac</td>
+ <td valign="Top">Java compiler to use. If omitted, it defaults
+ to the value of <code>build.compiler</code> property.</td>
+ <td align="Center" valign="Top">No</td>
+ </tr>
+ <tr>
+ <td valign="Top">javacopts</td>
+ <td valign="Top">Options to pass to the java compiler.</td>
+ <td align="Center" valign="Top">No</td>
+ </tr>
+ <tr>
+ <td valign="Top">rmicopts</td>
+ <td valign="Top">Options to pass to the rmi compiler.</td>
+ <td align="Center" valign="Top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">secpropag</td>
+ <td valign="top"><code>true</code> if the RMI Skel. and
+ Stub. must be modified to implement the implicit propagation of
+ the security context (the transactional context is always
+ provided). If omitted, it defaults to <code>false</code>.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="Top">verbose</td>
+ <td valign="Top">Indicates whether or not to use -verbose switch. If
+ omitted, it defaults to <code>false</code>.</td>
+ <td align="Center" valign="Top">No</td>
+ </tr>
+ <tr>
+ <td valign="Top">additionalargs</td>
+ <td valign="Top">Add additional args to GenIC.</td>
+ <td align="Center" valign="Top">No</td>
+ </tr>
+ <tr>
+ <td valign="Top">keepgeneric</td>
+ <td valign="Top"><code>true</code> if the generic JAR file used as input
+ to GenIC must be retained. If omitted, it defaults to <code>false</code>.</td>
+ <td align="Center" valign="Top">No</td>
+ </tr>
+ <tr>
+ <td valign="Top">jarsuffix</td>
+ <td>String value appended to the JAR filename when creating each JAR. If
+ omitted, it defaults to ".jar". </td>
+ <td align="Center" valign="Top">No</td>
+ </tr>
+ <tr>
+ <td valign="Top">orb</td>
+ <td>Choose your ORB : RMI, JEREMIE, DAVID. If omitted, it defaults to the
+ one present in classpath. If specified, the corresponding JOnAS JAR is
+ automatically added to the classpath.</td>
+ <td align="Center" valign="Top">No</td>
+ </tr>
+ <tr>
+ <td valign="Top">nogenic</td>
+ <td valign="Top">If this attribute is set to <code>true</code>,
+ JOnAS's GenIC will not be run on the EJB JAR. Use this if you
+ prefer to run GenIC at deployment time. If omitted, it defaults
+ to <code>false</code>.</td>
+ <td align="Center" valign="Top">No</td>
+ </tr>
+ <tr>
+ </tbody>
+</table>
+
+<p>As noted above, the jonas element supports additional <code>&lt;classpath&gt;</code>
+nested elements.</p>
+
+<h3>Examples</h3>
+
+<p>This example shows ejbjar being used to generate deployment jars using a
+JOnAS EJB container. This example requires the naming standard to be used for
+the deployment descriptors. Using this format will create a EJB JAR file for
+each variation of &nbsp;'*-jar.xml' that is found in the deployment descriptor
+directory.&nbsp;</p>
+
+<pre>
+ &lt;ejbjar srcdir="${build.classes}"
+ descriptordir="${descriptor.dir}"&gt;
+ &lt;jonas destdir="${deploymentjars.dir}"
+ jonasroot="${jonas.root}"
+ orb="RMI"/&gt;
+ &lt;include name="**/*.xml"/&gt;
+ &lt;exclude name="**/jonas-*.xml"/&gt;
+ &lt;support dir="${build.classes}"&gt;
+ &lt;include name="**/*.class"/&gt;
+ &lt;/support&gt;
+ &lt;/ejbjar&gt;
+</pre>
+
+<p>This example shows ejbjar being used to generate a single deployment jar
+using a JOnAS EJB container. This example does require the deployment
+descriptors to use the naming standard. This will create only one ejb jar file -
+'TheEJBJar.jar'.</p>
+
+<pre>
+ &lt;ejbjar srcdir="${build.classes}"
+ descriptordir="${descriptor.dir}"
+ basejarname="TheEJBJar"&gt;
+ &lt;jonas destdir="${deploymentjars.dir}"
+ jonasroot="${jonas.root}"
+ suffix=".jar"
+ classpath="${descriptorbuild.classpath}"/&gt;
+ &lt;include name="**/ejb-jar.xml"/&gt;
+ &lt;exclude name="**/jonas-ejb-jar.xml"/&gt;
+ &lt;/ejbjar&gt;
+</pre>
+
+
+
+
+</body>
+
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/exec.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/exec.html
new file mode 100644
index 00000000..5cef148c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/exec.html
@@ -0,0 +1,460 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+ <meta http-equiv="Content-Language" content="en-us">
+ <link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+ <title>Exec Task</title>
+</head>
+
+<body>
+
+<h2><a name="exec">Exec</a></h2>
+<h3>Description</h3>
+<p>Executes a system command. When the <i>os</i> attribute is specified, then
+the command is only executed when Apache Ant is run on one of the specified operating
+systems.</p>
+
+<p>Note that you cannot interact with the forked program, the only way
+to send input to it is via the input and inputstring attributes. Also note that
+since Ant 1.6, any attempt to read input in the forked program will receive an
+EOF (-1). This is a change from Ant 1.5, where such an attempt would block.</p>
+
+<p>If you want to execute an executable using a path relative to the
+ project's basedir, you may need to
+ use <code>vmlauncher="false"</code> on some operating systems - but
+ even this may fail (Solaris 8/9 has been reported as problematic).
+ The <code>resolveexecutable</code> attribute should be more
+ reliable, as would be something like
+<pre>
+ &lt;property name="executable-full-path"
+ location="../relative/path/to/executable"/&gt;
+ &lt;exec executable="${executable-full-path}" ...
+</pre>
+</p>
+
+<h4>Windows Users</h4>
+<p>The <code>&lt;exec&gt;</code> task delegates to <code>Runtime.exec</code> which in turn
+apparently calls <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/createprocess.asp">
+<code>::CreateProcess</code></a>. It is the latter Win32 function that defines
+the exact semantics of the call. In particular, if you do not put a file extension
+on the executable, only ".EXE" files are looked for, not ".COM", ".CMD" or other file
+types listed in the environment variable PATHEXT. That is only used by the shell.
+</p>
+ <p>
+ Note that <em>.bat</em> files cannot in general by executed directly.
+ One normally needs to execute the command shell executable <code>cmd</code>
+ using the <code>/c</code> switch.
+ </p>
+ <blockquote>
+<pre>
+&lt;target name="help"&gt;
+ &lt;exec executable="cmd"&gt;
+ &lt;arg value="/c"/&gt;
+ &lt;arg value="ant.bat"/&gt;
+ &lt;arg value="-p"/&gt;
+ &lt;/exec&gt;
+&lt;/target&gt;
+</pre></blockquote>
+
+<p>A common problem is not having the executable on the PATH. In case you get an error
+message <tt>Cannot run program "...":CreateProcess error=2. The system cannot find
+the path specified.</tt> have a look at your PATH variable. Just type the command directly on
+the command line and if Windows finds it, Ant should do it too. (Otherwise ask on the user mailinglist for help.) If Windows can not execute the program add the directory of the program
+to the PATH (<tt>set PATH=%PATH%;dirOfProgram</tt>) or specify the absolute path in the
+<tt>executable</tt> attribute in your buildfile.
+</p>
+
+
+<h4>Cygwin Users</h4>
+<p>The <code>&lt;exec&gt;</code> task will not understand paths such as /bin/sh
+for the executable parameter. This is because the Java VM in which Ant is
+running is a standard Windows executable and is not aware of the Cygwin
+environment (i.e., doesn't load <code>cygwin1.dll</code>). The only
+work-around for this is to compile a JVM under Cygwin (at your own risk).
+See for instance
+<a href="http://hg.openjdk.java.net/jdk7/build/raw-file/tip/README-builds.html#cygwin">
+OpenJDK build instructions for cygwin</a>.
+</p>
+
+<h4>OpenVMS Users</h4>
+<p>The command specified using <code>executable</code> and
+<code>&lt;arg&gt;</code> elements is executed exactly as specified
+inside a temporary DCL script. This has some implications:
+<ul>
+<li>paths have to be written in VMS style</li>
+<li>if your <code>executable</code> points to a DCL script remember to
+prefix it with an <code>@</code>-sign
+(e.g. <code>executable="@[FOO]BAR.COM"</code>), just as you would in a
+DCL script</li>
+</ul>
+For <code>&lt;exec&gt;</code> to work in an environment with a Java VM
+older than version 1.4.1-2 it is also <i>required</i> that the logical
+<code>JAVA$FORK_SUPPORT_CHDIR</code> is set to <code>TRUE</code> in
+the job table (see the <i>JDK Release Notes</i>).</p>
+
+<p>Please note that the Java VM provided by HP doesn't follow OpenVMS'
+conventions of exit codes. If you run a Java VM with this task, the
+task may falsely claim that an error occurred (or silently ignore an
+error). Don't use this task to run <code>JAVA.EXE</code>, use a
+<code>&lt;java&gt;</code> task with the <code>fork</code> attribute
+set to <code>true</code> instead as this task will follow the VM's
+interpretation of exit codes.</p>
+
+<h4>RedHat S/390 Users</h4>
+
+<p>It has been <a
+href="http://listserv.uark.edu/scripts/wa.exe?A1=ind0404&L=vmesa-l#33">reported
+on the VMESA-LISTSERV</a> that shell scripts invoked via the Ant Exec
+task must have their interpreter specified, i.e., the scripts must
+start with something like:
+
+<blockquote>
+<pre>
+#!/bin/bash
+</pre>
+</blockquote>
+
+or the task will fail as follows:
+
+<blockquote>
+<pre>
+[exec] Warning: UNIXProcess.forkAndExec native error: Exec format error
+[exec] Result: 255
+</pre>
+</blockquote>
+</p>
+
+<h4><a name="background">Running Ant as a background process on
+ Unix(-like) systems</a></h4>
+
+<p>If you run Ant as a background process (like <code>ant &</code>)
+ and use the <code>&lt;exec&gt;</code> task with <code>spawn</code>
+ set to <code>false</code>, you must provide explicit input to the
+ forked process or Ant will be suspended because it tries to read
+ from the standard input.</p>
+
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">command</td>
+ <td valign="top">the command to execute with all command line
+ arguments. <b>deprecated, use executable and nested
+ <code>&lt;arg&gt;</code> elements instead</b>.</td>
+ <td align="center" rowspan="2">Exactly one of the two.</td>
+ </tr>
+ <tr>
+ <td valign="top">executable</td>
+ <td valign="top">the command to execute without any command line
+ arguments.</td>
+ </tr>
+ <tr>
+ <td valign="top">dir</td>
+ <td valign="top">the directory in which the command should be executed.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">os</td>
+ <td valign="top">list of Operating Systems on which the command may be
+ executed. If the current OS's name is contained in this list, the command will
+ be executed. The OS's name is determined by the Java Virtual machine and is set
+ in the &quot;os.name&quot; system property.
+ </td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">osfamily</td>
+ <td valign="top">OS family as used in the &lt;os&gt; condition.
+ <em>since Ant 1.7</em></td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">spawn</td>
+ <td valign="top">whether or not you want the command to be spawned<br>
+ Default is false.<br>
+ If you spawn a command, its output will not be logged by ant.<br>
+ The input, output, error, and result property settings are not active when spawning a process.<br>
+ <em>since Ant 1.6</em>
+ </td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">output</td>
+ <td valign="top">Name of a file to which to write the output. If the error stream
+ is not also redirected to a file or property, it will appear in this output.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">error</td>
+ <td valign="top">The file to which the standard error of the
+ command should be redirected. <em>since Ant 1.6</em></td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">logError</td>
+ <td valign="top">This attribute is used when you wish to see error output in Ant's
+ log and you are redirecting output to a file/property. The error
+ output will not be included in the output file/property. If you
+ redirect error with the &quot;error&quot; or &quot;errorProperty&quot;
+ attributes, this will have no effect. <em>since Ant 1.6</em></td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">append</td>
+ <td valign="top">Whether output and error files should be appended to or overwritten.
+ Defaults to false.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">outputproperty</td>
+ <td valign="top">The name of a property in which the output of the
+ command should be stored. Unless the error stream is redirected to a separate
+ file or stream, this property will include the error output.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">errorproperty</td>
+ <td valign="top">The name of a property in which the standard error of the
+ command should be stored. <em>since Ant 1.6</em></td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">input</td>
+ <td valign="top">A file from which the executed command's standard input
+ is taken. This attribute is mutually exclusive with the
+ inputstring attribute. <em>since Ant 1.6</em></td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">inputstring</td>
+ <td valign="top">A string which serves as the input stream for the
+ executed command. This attribute is mutually exclusive with the
+ input attribute. <em>since Ant 1.6</em></td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">resultproperty</td>
+ <td valign="top">the name of a property in which the return code of the
+ command should be stored. Only of interest if failonerror=false.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">timeout</td>
+ <td valign="top">Stop the command if it doesn't finish within the
+ specified time (given in milliseconds).</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">failonerror</td>
+ <td valign="top">Stop the buildprocess if the command exits with a
+ return code signaling failure. Defaults to false.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">failifexecutionfails</td>
+ <td valign="top">Stop the build if we can't start the program.
+ Defaults to true. </td>
+ <td align="center" valign="top">No</td>
+ </tr> <tr>
+ <td valign="top">newenvironment</td>
+ <td valign="top">Do not propagate old environment when new environment
+ variables are specified.</td>
+ <td align="center" valign="top">No, default is <i>false</i></td>
+ </tr>
+ <tr>
+ <td valign="top">vmlauncher</td>
+ <td valign="top">Run command using the Java VM's execution facilities
+ where available. If set to false the underlying OS's shell,
+ either directly or through the antRun scripts, will be used.
+ Under some operating systems, this gives access to facilities
+ not normally available through the VM including, under Windows,
+ being able to execute scripts, rather than their associated
+ interpreter. If you want to specify the name of the
+ executable as a relative path to the directory given by the
+ dir attribute, it may become necessary to set vmlauncher to
+ false as well.</td>
+ <td align="center" valign="top">No, default is <i>true</i></td>
+ </tr>
+ <tr>
+ <td valign="top">resolveexecutable</td>
+ <td valign="top">When this attribute is true, the name of the executable
+ is resolved firstly against the project basedir and
+ if that does not exist, against the execution
+ directory if specified. On Unix systems, if you only
+ want to allow execution of commands in the user's path,
+ set this to false. <em>since Ant 1.6</em></td>
+ <td align="center" valign="top">No, default is <i>false</i></td>
+ </tr>
+ <tr>
+ <td valign="top">searchpath</td>
+ <td valign="top">When this attribute is true, then
+ system path environment variables will
+ be searched when resolving the location
+ of the executable. <em>since Ant 1.6.3</em></td>
+ <td align="center" valign="top">No, default is <i>false</i></td>
+ </tr>
+</table>
+<h3>Examples</h3>
+<blockquote>
+<pre>
+&lt;exec dir=&quot;${src}&quot; executable=&quot;cmd.exe&quot; os=&quot;Windows 2000&quot; output=&quot;dir.txt&quot;&gt;
+ &lt;arg line=&quot;/c dir&quot;/&gt;
+&lt;/exec&gt;</pre>
+</blockquote>
+<h3>Parameters specified as nested elements</h3>
+<h4>arg</h4>
+<p>Command line arguments should be specified as nested
+<code>&lt;arg&gt;</code> elements. See <a
+href="../using.html#arg">Command line arguments</a>.</p>
+<h4><a name="env">env</a></h4>
+<p>It is possible to specify environment variables to pass to the
+system command via nested <code>&lt;env&gt;</code> elements.</p>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">key</td>
+ <td valign="top">
+ The name of the environment variable.
+ <br/>
+ <em>Note: (Since Ant 1.7)</em>
+ For windows, the name is case-insensitive.
+ </td>
+ <td align="center" valign="top">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">value</td>
+ <td valign="top">The literal value for the environment variable.</td>
+ <td align="center" rowspan="3">Exactly one of these.</td>
+ </tr>
+ <tr>
+ <td valign="top">path</td>
+ <td valign="top">The value for a PATH like environment
+ variable. You can use ; or : as path separators and Ant will
+ convert it to the platform's local conventions.</td>
+ </tr>
+ <tr>
+ <td valign="top">file</td>
+ <td valign="top">The value for the environment variable. Will be
+ replaced by the absolute filename of the file by Ant.</td>
+ </tr>
+</table>
+<a name="redirector"><h4>redirector</h4></a>
+<i><b>Since Ant 1.6.2</b></i>
+<p>A nested <a href="../Types/redirector.html">I/O Redirector</a>
+can be specified. In general, the attributes of the redirector behave
+as the corresponding attributes available at the task level. The most
+notable peculiarity stems from the retention of the &lt;exec&gt;
+attributes for backwards compatibility. Any file mapping is done
+using a <CODE>null</CODE> sourcefile; therefore not all
+<a href="../Types/mapper.html">Mapper</a> types will return
+results. When no results are returned, redirection specifications
+will fall back to the task level attributes. In practice this means that
+defaults can be specified for input, output, and error output files.
+</p>
+<h3>Errors and return codes</h3>
+By default the return code of a <code>&lt;exec&gt;</code> is ignored; when you set
+<code>failonerror="true"</code> then any return code signaling failure
+(OS specific) causes the build to fail. Alternatively, you can set
+<code>resultproperty</code> to the name of a property and have it assigned to
+the result code (barring immutability, of course).
+<p>
+If the attempt to start the program fails with an OS dependent error code,
+then <code>&lt;exec&gt;</code> halts the build unless <code>failifexecutionfails</code>
+is set to <code>false</code>. You can use that to run a program if it exists, but
+otherwise do nothing.
+<p>
+What do those error codes mean? Well, they are OS dependent. On Windows
+boxes you have to look at
+<a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/debug/base/system_error_codes__0-499_.asp">
+the documentation</a>; error code 2 means 'no such program', which usually means
+it is not on the path. Any time you see such an error from any Ant task, it is
+usually not an Ant bug, but some configuration problem on your machine.
+
+<h3>Examples</h3>
+<blockquote><pre>
+&lt;exec executable=&quot;emacs&quot;&gt;
+ &lt;env key=&quot;DISPLAY&quot; value=&quot;:1.0&quot;/&gt;
+&lt;/exec&gt;
+</pre></blockquote>
+<p>starts <code>emacs</code> on display 1 of the X Window System.</p>
+
+<blockquote><pre>
+&lt;property environment=&quot;env&quot;/&gt;
+&lt;exec ... &gt;
+ &lt;env key=&quot;PATH&quot; path=&quot;${env.PATH}:${basedir}/bin&quot;/&gt;
+&lt;/exec&gt;
+</pre></blockquote>
+<p>adds <code>${basedir}/bin</code> to the <code>PATH</code> of the
+system command.</p>
+
+<blockquote><pre>
+&lt;property name="browser" location="C:/Program Files/Internet Explorer/iexplore.exe"/&gt;
+&lt;property name="file" location="ant/docs/manual/index.html"/&gt;
+
+&lt;exec executable="${browser}" spawn="true"&gt;
+ &lt;arg value="${file}"/&gt;
+&lt;/exec&gt;
+</pre></blockquote>
+<p>Starts the <i>${browser}</i> with the specified <i>${file}</i> and end the
+Ant process. The browser will remain.</p>
+
+<blockquote><pre>
+&lt;exec executable=&quot;cat&quot;&gt;
+ &lt;redirector outputproperty=&quot;redirector.out&quot;
+ errorproperty=&quot;redirector.err&quot;
+ inputstring=&quot;blah before blah&quot;&gt;
+ &lt;inputfilterchain&gt;
+ &lt;replacestring from=&quot;before&quot; to=&quot;after&quot;/&gt;
+ &lt;/inputfilterchain&gt;
+ &lt;outputmapper type=&quot;merge&quot; to=&quot;redirector.out&quot;/&gt;
+ &lt;errormapper type=&quot;merge&quot; to=&quot;redirector.err&quot;/&gt;
+ &lt;/redirector&gt;
+&lt;/exec&gt;
+</pre></blockquote>
+
+Sends the string &quot;blah before blah&quot; to the &quot;cat&quot; executable,
+using an <a href="../Types/filterchain.html">&lt;inputfilterchain&gt;</a>
+to replace &quot;before&quot; with &quot;after&quot; on the way in.
+Output is sent to the file &quot;redirector.out&quot; and stored
+in a property of the same name. Similarly, error output is sent to
+a file and a property, both named &quot;redirector.err&quot;.
+
+
+<p><b>Note:</b> do not try to specify arguments using
+a simple arg-element and separate them by spaces. This results in
+only a single argument containing the entire string.</p>
+<p>
+<b>Timeouts: </b> If a timeout is specified, when it is reached the
+sub process is killed and a message printed to the log. The return
+value of the execution will be "-1", which will halt the build if
+<tt>failonerror=true</tt>, but be ignored otherwise.
+
+
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/fail.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/fail.html
new file mode 100644
index 00000000..eabe30b8
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/fail.html
@@ -0,0 +1,143 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Fail Task</title>
+</head>
+
+<body>
+
+<h2><a name="fail">Fail</a></h2>
+<h3>Description</h3>
+<p>Exits the current build (just throwing a BuildException), optionally printing additional information.</p>
+<p>The message of the Exception can be set via the message attribute
+or character data nested into the element.</p>
+
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">message</td>
+ <td valign="top">A message giving further information on why the build exited</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">if</td>
+ <td valign="top">Only fail <a href="../properties.html#if+unless">if a property of the given name exists</a>
+ in the current project</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">unless</td>
+ <td valign="top">Only fail <a href="../properties.html#if+unless">if a property of the given name doesn't
+ exist</a> in the current project</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">status</td>
+ <td valign="top">Exit using the specified status code;
+ assuming the generated Exception is not caught, the
+ JVM will exit with this status. <em>Since Apache Ant 1.6.2</em></td>
+ <td align="center" valign="top">No</td>
+ </tr>
+</table>
+
+<h3>Parameters specified as nested elements</h3>
+
+<p>As an alternative to the <i>if</i>/<i>unless</i> attributes,
+ conditional failure can be achieved using a single nested
+ <code>&lt;condition&gt;</code> element, which should contain exactly one
+ core or custom condition. For information about conditions, see
+ <a href="conditions.html">here</a>.<br><b>Since Ant 1.6.2</b>
+</p>
+
+<h3>Examples</h3>
+
+<pre> &lt;fail/&gt;</pre>
+<p>will exit the current build with no further information given.</p>
+<pre>
+BUILD FAILED
+
+build.xml:4: No message
+</pre>
+
+<pre> &lt;fail message=&quot;Something wrong here.&quot;/&gt;</pre>
+<p>will exit the current build and print something
+ like the following to wherever your output goes:
+</p>
+<pre>
+BUILD FAILED
+
+build.xml:4: Something wrong here.
+</pre>
+
+<pre> &lt;fail&gt;Something wrong here.&lt;/fail&gt;</pre>
+<p>will give the same result as above.</p>
+
+<pre> &lt;fail unless=&quot;thisdoesnotexist&quot;/&gt;</pre>
+<p>will exit the current build and print something
+ like the following to wherever your output goes:
+</p>
+<pre>
+BUILD FAILED
+
+build.xml:2: unless=thisdoesnotexist
+</pre>
+
+Using a condition to achieve the same effect:
+
+<pre>
+ &lt;fail&gt;
+ &lt;condition&gt;
+ &lt;not&gt;
+ &lt;isset property=&quot;thisdoesnotexist&quot;/&gt;
+ &lt;/not&gt;
+ &lt;/condition&gt;
+ &lt;/fail&gt;
+</pre>
+
+<p>Output:</p>
+<pre>
+BUILD FAILED
+
+build.xml:2: condition satisfied
+</pre>
+
+<pre>
+&lt;fail message=&quot;Files are missing.&quot;&gt;
+ &lt;condition&gt;
+ &lt;not&gt;
+ &lt;resourcecount count=&quot;2&quot;&gt;
+ &lt;fileset id=&quot;fs&quot; dir=&quot;.&quot; includes=&quot;one.txt,two.txt&quot;/&gt;
+ &lt;/resourcecount&gt;
+ &lt;/not&gt;
+ &lt;/condition&gt;
+&lt;/fail&gt;
+</pre>
+<p>Will check that both files <i>one.txt</i> and <i>two.txt</i> are present otherwise the build
+will fail.</p>
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/filter.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/filter.html
new file mode 100644
index 00000000..16ba88c6
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/filter.html
@@ -0,0 +1,79 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Filter Task</title>
+</head>
+
+<body>
+
+<h2><a name="filter">Filter</a></h2>
+<h3>Description</h3>
+<p>Sets a token filter for this project or read multiple token filter from
+an input file and sets these as filters.
+Token filters are used by all tasks that perform file copying operations
+through the Project commodity methods. See the warning
+<a href="../using.html#filters"><em>here</em></a> before using.</p>
+<p>Note 1: the token string must not contain the separators chars (@).<br>
+Note 2: Either token and value attributes must be provided, or only the
+filtersfile attribute.</p>
+
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">token</td>
+ <td valign="top">the token string without @</td>
+ <td align="center" valign="top">Yes*</td>
+ </tr>
+ <tr>
+ <td valign="top">value</td>
+ <td valign="top">the string that should be put to replace the token when the
+ file is copied</td>
+ <td align="center" valign="top">Yes*</td>
+ </tr>
+ <tr>
+ <td valign="top">filtersfile</td>
+ <td valign="top">The file from which the filters must be read. This file must be a formatted as a property file. </td>
+ <td align="center" valign="top">Yes*</td>
+ </tr>
+</table>
+<p>* see notes 1 and 2 above parameters table.</p>
+<h3>Examples</h3>
+<pre> &lt;filter token=&quot;year&quot; value=&quot;2000&quot;/&gt;
+ &lt;copy todir=&quot;${dest.dir}&quot; filtering=&quot;true&quot;&gt;
+ &lt;fileset dir=&quot;${src.dir}&quot;/&gt;
+ &lt;/copy&gt;</pre>
+<p>will copy recursively all the files from the <i>src.dir</i> directory into
+the <i>dest.dir</i> directory replacing all the occurrences of the string <i>@year@</i>
+with <i>2000.</i></p>
+<pre> &lt;filter filtersfile=&quot;deploy_env.properties&quot;/&gt;</pre>
+will read all property entries from the <i>deploy_env.properties</i> file
+and set these as filters.
+
+
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/fixcrlf.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/fixcrlf.html
new file mode 100644
index 00000000..2637401b
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/fixcrlf.html
@@ -0,0 +1,327 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>FixCRLF Task</title>
+</head>
+
+<body>
+
+<h2><a name="fixcrlf">FixCRLF</a></h2>
+<h3>Description</h3>
+ <p>
+ Adjusts a text file to local conventions.
+ </p>
+
+ <p>
+ The set of files to be adjusted can be refined with the
+ <i>includes</i>, <i>includesfile</i>, <i>excludes</i>,
+ <i>excludesfile</i> and <i>defaultexcludes</i>
+ attributes. Patterns provided through the <i>includes</i> or
+ <i>includesfile</i> attributes specify files to be
+ included. Patterns provided through the <i>exclude</i> or
+ <i>excludesfile</i> attribute specify files to be
+ excluded. Additionally, default exclusions can be specified with
+ the <i>defaultexcludes</i> attribute. See the section on <a
+ href="../dirtasks.html#directorybasedtasks">directory-based
+ tasks</a>, for details of file inclusion/exclusion patterns
+ and their usage.
+ </p>
+
+ <p>
+ This task forms an implicit
+ <a href="../Types/fileset.html">FileSet</a> and
+ supports most attributes of <code>&lt;fileset&gt;</code>
+ (<code>dir</code> becomes <code>srcdir</code>) as well as the nested
+ <code>&lt;include&gt;</code>, <code>&lt;exclude&gt;</code> and
+ <code>&lt;patternset&gt;</code> elements.
+ </p>
+
+ <p>
+ The output file is only written if it is a new file, or if it
+ differs from the existing file. This prevents spurious
+ rebuilds based on unchanged files which have been regenerated
+ by this task.
+ </p>
+
+ <p>
+ Since <b>Apache Ant 1.7</b>, this task can be used in a
+ <a href="../Types/filterchain.html">filterchain</a>.
+ </p>
+
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="center" rowspan="2"><b>Attribute</b></td>
+ <td valign="center" rowspan="2"><b>Description</b></td>
+ <td align="center" valign="top" colspan="2"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="center"><b>As Task</b></td>
+ <td valign="center"><b>As Filter</b></td>
+ </tr>
+ <tr>
+ <td valign="top">srcDir</td>
+ <td valign="top">Where to find the files to be fixed up.</td>
+ <td valign="top" align="center" rowspan="2">One of these</td>
+ <td bgcolor="#CCCCCC">&nbsp;</td>
+ </tr>
+ <tr>
+ <td valign="top">file</td>
+ <td valign="top">Name of a single file to fix. <b>Since Ant 1.7</b></td>
+ <td bgcolor="#CCCCCC">&nbsp;</td>
+ </tr>
+ <tr>
+ <td valign="top">destDir</td>
+ <td valign="top">Where to place the corrected files. Defaults to
+ srcDir (replacing the original file).</td>
+ <td valign="top" align="center">No</td>
+ <td bgcolor="#CCCCCC">&nbsp;</td>
+ </tr>
+ <tr>
+ <td valign="top">includes</td>
+ <td valign="top">comma- or space-separated list of patterns of files that must be
+ included. All files are included when omitted.</td>
+ <td valign="top" align="center">No</td>
+ <td bgcolor="#CCCCCC">&nbsp;</td>
+ </tr>
+ <tr>
+ <td valign="top">includesfile</td>
+ <td valign="top">the name of a file. Each line of this file is
+ taken to be an include pattern.</td>
+ <td valign="top" align="center">No</td>
+ <td bgcolor="#CCCCCC">&nbsp;</td>
+ </tr>
+ <tr>
+ <td valign="top">excludes</td>
+ <td valign="top">comma- or space-separated list of patterns of files that must be
+ excluded. No files (except default excludes) are excluded when omitted.</td>
+ <td valign="top" align="center">No</td>
+ <td bgcolor="#CCCCCC">&nbsp;</td>
+ </tr>
+ <tr>
+ <td valign="top">excludesfile</td>
+ <td valign="top">the name of a file. Each line of this file is
+ taken to be an exclude pattern.</td>
+ <td valign="top" align="center">No</td>
+ <td bgcolor="#CCCCCC">&nbsp;</td>
+ </tr>
+ <tr>
+ <td valign="top">defaultexcludes</td>
+ <td valign="top">indicates whether default excludes should be used or not
+ (&quot;yes&quot;/&quot;no&quot;). Default excludes are used when omitted.
+ </td>
+ <td valign="top" align="center">No</td>
+ <td bgcolor="#CCCCCC">&nbsp;</td>
+ </tr>
+ <tr>
+ <td valign="top">encoding</td>
+ <td valign="top">The encoding of the files.</td>
+ <td align="center">No; defaults to default JVM encoding.</td>
+ <td bgcolor="#CCCCCC">&nbsp;</td>
+ </tr>
+ <tr>
+ <td valign="top">outputencoding</td>
+ <td valign="top">The encoding to use when writing the files.
+ <b>Since Ant 1.7</b></td>
+ <td align="center">No; defaults to the value of the encoding attribute.</td>
+ <td bgcolor="#CCCCCC">&nbsp;</td>
+ </tr>
+ <tr>
+ <td valign="top">preservelastmodified</td>
+ <td valign="top">Whether to preserve the last modified
+ date of source files. <b>Since Ant 1.6.3</b></td>
+ <td align="center">No; default is <i>false</i></td>
+ <td bgcolor="#CCCCCC">&nbsp;</td>
+ </tr>
+ <tr>
+ <td valign="top">eol</td>
+ <td valign="top">
+ Specifies how end-of-line (EOL) characters are to be
+ handled. The EOL characters are CR, LF and the pair CRLF.
+ Valid values for this property are:
+ <ul>
+ <li>asis: leave EOL characters alone</li>
+ <li>cr: convert all EOLs to a single CR</li>
+ <li>lf: convert all EOLs to a single LF</li>
+ <li>crlf: convert all EOLs to the pair CRLF</li>
+ <li>mac: convert all EOLs to a single CR</li>
+ <li>unix: convert all EOLs to a single LF</li>
+ <li>dos: convert all EOLs to the pair CRLF</li>
+ </ul>
+ Default is based on the platform on which you are running this task.
+ For Unix platforms (including Mac OS X), the default is &quot;lf&quot;.
+ For DOS-based systems (including Windows), the default is
+ &quot;crlf&quot;.
+ For Mac environments other than OS X, the default is &quot;cr&quot;.
+ <p>
+ This is the preferred method for specifying EOL. The
+ &quot;<i><b>cr</b></i>&quot; attribute (see below) is
+ now deprecated.
+ </p>
+ <p>
+ <i>N.B.</i>: One special case is recognized. The three
+ characters CR-CR-LF are regarded as a single EOL.
+ Unless this property is specified as &quot;asis&quot;,
+ this sequence will be converted into the specified EOL
+ type.
+ </p>
+ </td>
+ <td valign="top" align="center" colspan="2">No</td>
+ </tr>
+ <tr>
+ <td valign="top">cr</td>
+ <td valign="top">
+ <i><b>Deprecated.</b></i> Specifies how CR characters are
+ to be handled at end-of-line (EOL). Valid values for this
+ property are:
+ <ul>
+ <li>asis: leave EOL characters alone.</li>
+ <li>
+ add: add a CR before any single LF characters. The
+ intent is to convert all EOLs to the pair CRLF.
+ </li>
+ <li>
+ remove: remove all CRs from the file. The intent is
+ to convert all EOLs to a single LF.
+ </li>
+ </ul>
+ Default is based on the platform on which you are running
+ this task. For Unix platforms, the default is &quot;remove&quot;.
+ For DOS based systems (including Windows), the default is
+ &quot;add&quot;.
+ <p>
+ <i>N.B.</i>: One special case is recognized. The three
+ characters CR-CR-LF are regarded as a single EOL.
+ Unless this property is specified as &quot;asis&quot;,
+ this sequence will be converted into the specified EOL
+ type.
+ </p>
+ </td>
+ <td valign="top" align="center" colspan="2">No</td>
+ </tr>
+ <tr>
+ <td valign="top">javafiles</td>
+ <td valign="top">
+ Used only in association with the
+ &quot;<i><b>tab</b></i>&quot; attribute (see below), this
+ boolean attribute indicates whether the fileset is a set
+ of java source files
+ (&quot;yes&quot;/&quot;no&quot;). Defaults to
+ &quot;no&quot;. See notes in section on &quot;tab&quot;.
+ </td>
+ <td valign="top" align="center" colspan="2">No</td>
+ </tr>
+ <tr>
+ <td valign="top">tab</td>
+ <td valign="top">Specifies how tab characters are to be handled. Valid
+ values for this property are:
+ <ul>
+ <li>add: convert sequences of spaces which span a tab stop to tabs</li>
+ <li>asis: leave tab and space characters alone</li>
+ <li>remove: convert tabs to spaces</li>
+ </ul>
+ Default for this parameter is &quot;asis&quot;.
+ <p>
+ <i>N.B.</i>: When the attribute
+ &quot;<i><b>javafiles</b></i>&quot; (see above) is
+ &quot;true&quot;, literal TAB characters occurring
+ within Java string or character constants are never
+ modified. This functionality also requires the
+ recognition of Java-style comments.
+ </p>
+ <p>
+ <i>N.B.</i>: There is an incompatibility between this
+ and the previous version in the handling of white
+ space at the end of lines. This version does
+ <i><b>not</b></i> remove trailing whitespace on lines.
+ </p>
+ </td>
+ <td valign="top" align="center" colspan="2">No</td>
+ </tr>
+ <tr>
+ <td valign="top">tablength</td>
+ <td valign="top">TAB character interval. Valid values are between
+ 2 and 80 inclusive. The default for this parameter is 8.</td>
+ <td valign="top" align="center" colspan="2">No</td>
+ </tr>
+ <tr>
+ <td valign="top">eof</td>
+ <td valign="top">Specifies how DOS end of file (control-Z) characters are
+ to be handled. Valid values for this property are:
+ <ul>
+ <li>add: ensure that there is an EOF character at the end of the file</li>
+ <li>asis: leave EOF characters alone</li>
+ <li>remove: remove any EOF character found at the end</li>
+ </ul>
+ Default is based on the platform on which you are running this task.
+ For Unix platforms, the default is remove. For DOS based systems
+ (including Windows), the default is asis.
+ </td>
+ <td valign="top" align="center" colspan="2">No</td>
+ </tr>
+ <tr>
+ <td valign="top">fixlast</td>
+ <td valign="top">Whether to add a missing EOL to the last line
+ of a processed file.<br/>Ignored if EOL is asis.<br/><b>Since Ant 1.6.1</b></td>
+ <td align="center" colspan="2">No; default is <i>true</i></td>
+ </tr>
+</table>
+<h3>Examples</h3>
+<pre>&lt;fixcrlf srcdir=&quot;${src}&quot; includes=&quot;**/*.sh&quot;
+ eol=&quot;lf&quot; eof=&quot;remove&quot; /&gt;</pre>
+<p>Replaces EOLs with LF characters and removes eof characters from
+ the shell scripts. Tabs and spaces are left as is.</p>
+<pre>&lt;fixcrlf srcdir=&quot;${src}&quot;
+ includes=&quot;**/*.bat&quot; eol=&quot;crlf&quot; /&gt;</pre>
+<p>Replaces all EOLs with cr-lf pairs in the batch files.
+ Tabs and spaces are left as is.
+ EOF characters are left alone if run on
+ DOS systems, and are removed if run on Unix systems.</p>
+<pre>&lt;fixcrlf srcdir=&quot;${src}&quot;
+ includes=&quot;**/Makefile&quot; tab=&quot;add&quot; /&gt;</pre>
+<p>Sets EOLs according to local OS conventions, and
+ converts sequences of spaces and tabs to the minimal set of spaces and
+ tabs which will maintain spacing within the line. Tabs are
+ set at 8 character intervals. EOF characters are left alone if
+ run on DOS systems, and are removed if run on Unix systems.
+ Many versions of make require tabs prior to commands.</p>
+ <pre>&lt;fixcrlf srcdir=&quot;${src}&quot; includes=&quot;**/*.java&quot;
+ tab=&quot;remove&quot; tablength=&quot;3&quot;
+ eol=&quot;lf&quot; javafiles=&quot;yes&quot; /&gt;</pre>
+<p>
+ Converts all EOLs in the included java source files to a
+ single LF. Replace all TAB characters except those in string
+ or character constants with spaces, assuming a tab width of 3.
+ If run on a unix system, any CTRL-Z EOF characters at the end
+ of the file are removed. On DOS/Windows, any such EOF
+ characters will be left untouched.
+</p>
+<pre>&lt;fixcrlf srcdir=&quot;${src}&quot;
+ includes=&quot;**/README*&quot; tab=&quot;remove&quot; /&gt;</pre>
+<p>Sets EOLs according to local OS conventions, and
+ converts all tabs to spaces, assuming a tab width of 8.
+ EOF characters are left alone if run on
+ DOS systems, and are removed if run on Unix systems.
+ You never know what editor a user will use to browse READMEs.</p>
+
+
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/ftp.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/ftp.html
new file mode 100644
index 00000000..83c18e31
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/ftp.html
@@ -0,0 +1,724 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>FTP Task</title>
+</head>
+
+<body>
+
+<h2><a name="ftp">FTP</a></h2>
+<h3>Description</h3>
+<p>The ftp task implements a basic FTP client that can send, receive,
+list, delete files, and create directories. See below for descriptions and examples of how
+to perform each task.</p>
+<p><b>Note:</b> This task depends on external libraries not included in the Apache Ant distribution.
+See <a href="../install.html#commons-net">Library Dependencies</a> for more information.
+<i>Get the latest version of this library, for the best support in Ant</i>
+
+</p>
+<p>The ftp task attempts to determine what file system is in place on the FTP server.
+Supported server types are Unix, NT, OS2, VMS, and OS400. In addition, NT and OS400 servers
+which have been configured to display the directory in Unix style are also supported correctly.
+Otherwise, the system will default to Unix standards.
+<i>remotedir</i> must be specified in the exact syntax required by the ftp
+server. If the usual Unix conventions are not supported by the server,
+<i>separator</i> can be used to set the file separator that should be used
+instead.</p>
+<p>See the section on <a href="../dirtasks.html#directorybasedtasks">directory based
+tasks</a>, on how the inclusion/exclusion of files works, and how to
+write patterns.</p>
+<p>
+This task does not currently use the proxy information set by the
+<a href="setproxy.html"><code>&lt;setproxy&gt;</code></a> task, and cannot go through
+a firewall via socks.
+<p>
+<b>Warning: </b> there have been problems reported concerning the ftp get with the <code>newer</code> attribute.
+Problems might be due to format of ls -l differing from what is expected by commons-net,
+for instance due to specificities of language used by the ftp server in the directory listing.
+If you encounter such a problem, please send an email including a sample directory listing
+coming from your ftp server (ls -l on the ftp prompt).
+</p>
+<p>
+If you can connect but not upload or download, try setting the <code>passive</code>
+attribute to true to use the existing (open) channel, instead of having the server
+try to set up a new connection.</p>
+
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top" width="15%"><b>Attribute</b></td>
+ <td valign="top" width="65%"><b>Description</b></td>
+ <td align="center" valign="top" width="20%"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">server</td>
+ <td valign="top">the address of the remote ftp server.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">port</td>
+ <td valign="top">the port number of the remote ftp server.
+ Defaults to port 21.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">userid</td>
+ <td valign="top">the login id to use on the ftp server.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">password</td>
+ <td valign="top">the login password to use on the ftp server.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">account</td>
+ <td valign="top">the account to use on the ftp server.
+ <em>since Ant 1.7</em>.
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">remotedir</td>
+ <td valign="top">remote directory on the
+ ftp server
+ see table below for detailed usage
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">action</td>
+ <td valign="top">the ftp action to perform, defaulting to "send".
+ Currently supports "put", "get",
+ "del", "list", "chmod",
+ "mkdir", "rmdir", and "site".</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">binary</td>
+ <td valign="top">selects binary-mode ("yes") or text-mode
+ ("no") transfers.
+ Defaults to "yes"</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">passive</td>
+ <td valign="top">selects passive-mode ("yes") transfers, for
+ better through-firewall connectivity, at the price
+ of performance.
+ Defaults to "no"</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">verbose</td>
+ <td valign="top">displays information on each file transferred if set
+ to "yes". Defaults to "no".</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">depends</td>
+ <td valign="top">transfers only new or changed files if set to
+ "yes". Defaults to "no".</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">newer</td>
+ <td valign="top">a synonym for <i>depends</i>.
+ see timediffauto and timediffmillis</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">timediffauto</td>
+ <td valign="top">set to <code>"true"</code>
+ to make ant calculate the time difference between client and server.<br>
+ <em>requires write access in the remote directory</em><br>
+ Since ant 1.6</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <a name="timestampGranularity"/>
+ <tr>
+ <td valign="top">timestampGranularity</td>
+ <td valign="top">Specify either <code>MINUTE</code>, <code>NONE</code>,
+ (or you may specify <code>""</code> which is equivalent to not specifying a value,
+ useful for property-file driven scripts). Allows override of the typical situation
+ in PUT and GET where local filesystem timestamps are <code>HH:mm:ss</code>
+ and the typical FTP server's timestamps are <code>HH:mm</code>. This can throw
+ off uptodate calculations. However, the default values should suffice for most
+ applications.<br>
+ Since ant 1.7
+ </td>
+ <td valign="top" align="center">No. Only applies in "puts" and "gets" where the
+ default values are <code>MINUTE</code> for PUT and <code>NONE</code> for GET.
+ (It is not as necessary in GET because we have the <b>preservelastmodified</b> option.)</td>
+ </tr>
+ <tr>
+ <td valign="top">timediffmillis</td>
+ <td valign="top"><b>Deprecated</b>. Number of milliseconds to add to the time on
+ the remote machine to get the time on the local machine. The <b>timestampGranularity</b>
+ attribute (for which the default values should suffice in most situations), and the
+ <b>serverTimeZoneConfig</b> option, should make this unnecessary.
+ <b>serverTimeZoneConfig</b> does the math for you and also knows about
+ Daylight Savings Time.<br>
+ Since ant 1.6
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">separator</td>
+ <td valign="top">sets the file separator used on the ftp server.
+ Defaults to "/".</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">umask</td>
+ <td valign="top">sets the default file permissions for new files,
+ unix only.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">chmod</td>
+ <td valign="top">sets or changes file permissions for new or existing files,
+ unix only. If used with a put action, chmod will be issued for each file.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">listing</td>
+ <td valign="top">the file to write results of the "list" action.
+ Required for the "list" action, ignored otherwise.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">ignoreNoncriticalErrors</td>
+ <td valign="top">flag which permits the task to ignore some non-fatal error
+ codes sent by some servers during directory creation: wu-ftp in particular.
+ Default: false</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">skipFailedTransfers</td>
+ <td valign="top">flag which enables unsuccessful file put, delete
+ and get operations to be skipped with a warning and the
+ remainder of the files still transferred. Default: false</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">preservelastmodified</td>
+ <td valign="top">Give the copied files the same last modified
+ time as the original source files (applies to getting files only).
+ (<em>Note</em>: Ignored on Java 1.1)</td>
+ <td valign="top" align="center">No; defaults to false.</td>
+ </tr>
+ <tr>
+ <td valign="top">retriesAllowed</td>
+ <td valign="top">Set the number of retries allowed on an file-transfer operation.
+ If a number > 0 specified, each file transfer can fail up to that
+ many times before the operation is failed. If -1 or "forever" specified, the
+ operation will keep trying until it succeeds.</td>
+ <td valign="top" align="center">No; defaults to 0</td>
+ </tr>
+ <tr>
+ <td valign="top">siteCommand</td>
+ <td valign="top">Set the server-specific SITE command to execute if
+ the <code>action</code> attribute has been specified as <code>"site"</code>.
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">initialSiteCommand</td>
+ <td valign="top">Set a server-specific SITE command to execute immediately
+ after login.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">enableRemoteVerification</td>
+ <td valign="top">Whether data connection should be verified to
+ connect to the same host as the control connection. This is a
+ security measure that is enabled by default, but it may be useful
+ to disable it in certain firewall scenarios.
+ <em>since Ant 1.8.0</em></td>
+ <td valign="top" align="center">No, default is true</td>
+ </tr>
+
+ <tr>
+ <td colspan="3">
+ <p><b>The following attributes require <a href=
+ "http://commons.apache.org/net/download_net.cgi">
+ jakarta-commons-net-1.4.0 or greater</a>.</b></p>
+ <p>
+ Use these options when the standard options don't work, because
+ <ul><li>the server is in a different timezone and you need timestamp
+ dependency checking</li>
+ <li>the default timestamp formatting doesn't match the server display and
+ list parsing therefore fails</li></ul>
+ </p><p>
+ If none of these is specified, the default mechanism of letting the system
+ auto-detect the server OS type based on the FTP SYST command and assuming
+ standard formatting for that OS type will be used.
+ </p><p>
+ To aid in property-file-based development where a build script is configured
+ with property files, for any of these attributes, a value of <code>""</code>
+ is equivalent to not specifying it.
+ </p><p>
+ Please understand that these options are incompatible with the autodetection
+ scheme. If any of these options is specified, (other than with a value of
+ <code>""</code> ) a system type must be chosen and if systemTypeKey is not
+ specified, UNIX will be assumed. The philosophy behind this is that these
+ options are for setting non-standard formats, and a build-script author who
+ knows what system he is dealing with will know what options to need to be
+ set. Otherwise, these options should be left alone and the default
+ autodetection scheme can be used and will work in the majority of cases.
+ </p></td>
+ </tr>
+ <tr>
+ <td valign="top">systemTypeKey</td>
+ <td valign="top">Specifies the type of system in use on the server.
+ Supported values are <code>"UNIX", "VMS", "WINDOWS", "OS/2", "OS/400",
+ "MVS".</code> If not specified, (or specified as <code>""</code>) and if
+ no other xxxConfig attributes are specified, the autodetection mechanism
+ based on the FTP SYST command will be used.<br>
+ Since ant 1.7
+ </td>
+ <td valign="top" align="center">No, but if any of the following xxxConfig
+ attributes is specified, UNIX will be assumed, even if <code>""</code>
+ is specified here.
+ </td>
+ </tr>
+ <tr>
+ <td valign="top">serverTimeZoneConfig</td>
+ <td valign="top">Specify as a Java
+ <a href="http://docs.oracle.com/javase/7/docs/api//java/util/TimeZone.html">
+ TimeZone</a> identifier, (e.g. <code>GMT</code>, <code>America/Chicago</code> or
+ <code>Asia/Jakarta</code>) the timezone used by the server for timestamps. This
+ enables timestamp dependency checking even when the server is in a different
+ time zone from the client. Time Zones know, also, about daylight savings time,
+ and do not require you to calculate milliseconds of difference. If not specified,
+ (or specified as <code>""</code>), the time zone of the client is assumed.<br>
+ Since ant 1.7
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+
+ <td valign="top">defaultDateFormatConfig</td>
+ <td valign="top">Specify in Java
+ <a href="http://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html">
+ SimpleDateFormat</a> notation, (e.g.
+ <code>yyyy-MM-dd</code>), the date format generally used by the FTP server
+ to parse dates. In some cases this will be the only date format used.
+ In others, (unix for example) this will be used for dates
+ older than a year old. (See <b>recentDateFormatConfig</b>). If not specified,
+ (or specified as <code>""</code>), the default date format for the system
+ type indicated by the <b>systemTypeKey</b> attribute will be used.<br>
+ Since ant 1.7
+ </td>
+ <td valign="top" align="center">
+ No.
+ </td>
+ </tr>
+ <tr>
+ <td valign="top">recentDateFormatConfig</td>
+ <td valign="top">Specify in Java
+ <a href="http://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html">
+ SimpleDateFormat</a> notation,
+ (e.g. <code>MMM dd hh:mm</code>) the date format used by the FTP server
+ to parse dates less than a year old. If not specified (or specified as
+ <code>""</code>), and if the system type indicated by the system key uses
+ a recent date format, its standard format will be used.<br>
+ Since ant 1.7
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">serverLanguageCodeConfig</td>
+ <td valign="top">a <a href="http://www.ics.uci.edu/pub/ietf/http/related/iso639.txt">
+ two-letter ISO-639 language code</a> used to specify the
+ language used by the server to format month names. This only needs to be
+ specified when the server uses non-numeric abbreviations for months in its
+ date listings in a language other than English. This appears to be
+ becoming rarer and rarer, as commonly distributed ftp servers seem
+ increasingly to use English or all-numeric formats.
+ Languages supported are:
+ <ul>
+ <li>en - English</li>
+ <li>fr - French</li>
+ <li>de - German</li>
+ <li>it - Italian</li>
+ <li>es - Spanish</li>
+ <li>pt - Portuguese</li>
+ <li>da - Danish</li>
+ <li>sv - Swedish</li>
+ <li>no - Norwegian</li>
+ <li>nl - Dutch</li>
+ <li>ro - Romanian</li>
+ <li>sq - Albanian</li>
+ <li>sh - Serbo-croatian</li>
+ <li>sk - Slovak</li>
+ <li>sl - Slovenian</li>
+ </ul>
+ If you require a language other than the above, see also the
+ <b>shortMonthNamesConfig</b> attribute.<br>
+ Since ant 1.7
+ </td>
+
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">shortMonthNamesConfig</td>
+ <td valign="top">specify the month abbreviations used on the server in file
+ timestamp dates as a pipe-delimited string for each month. For example,
+ a set of month names used by a hypothetical
+ Icelandic FTP server might conceivably be specified as
+ <code>"jan|feb|mar|apr|ma&#xED;|j&#xFA;n|j&#xFA;l|&#xE1;g&#xFA;|sep|okt|n&#xF3;v|des"</code>.
+ This attribute exists primarily to support languages not supported by
+ the <b>serverLanguageCode</b> attribute.<br>
+ Since ant 1.7
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+</table>
+<h3>Note about remotedir attribute</h3>
+<table border="1" cellpadding="2" cellspacing="0"
+ >
+ <tbody>
+ <tr>
+ <td style="vertical-align: top;" width="20%">Action<br>
+ </td>
+ <td style="vertical-align: top;" width="40%">meaning of <code>remotedir</code><br>
+ </td>
+ <td style="vertical-align: top;">use of nested <code>fileset</code>
+(s)<br>
+ </td>
+ </tr>
+ <tr>
+ <td style="vertical-align: top;" width="20%">send/put<br>
+ </td>
+ <td style="vertical-align: top;" width="40%">base directory to
+which the files are sent<br>
+ </td>
+ <td style="vertical-align: top;">they are used normally and
+evaluated on the local machine<br>
+ </td>
+ </tr>
+ <tr>
+ <td style="vertical-align: top;" width="20%">recv/get<br>
+ </td>
+ <td style="vertical-align: top;" width="40%">base directory from
+which the files are retrieved<br>
+ </td>
+ <td style="vertical-align: top;">the remote files located under
+the <code>remotedir </code>matching the include/exclude patterns of
+the <code>fileset&nbsp;</code></td>
+ </tr>
+ <tr>
+ <td style="vertical-align: top;" width="20%">del/delete<br>
+ </td>
+ <td style="vertical-align: top;" width="40%">base directory from
+which files get deleted<br>
+ </td>
+ <td style="vertical-align: top;">the remote files located under
+the <code>remotedir </code>matching the include/exclude patterns of
+the <code>fileset <br>
+ </code></td>
+ </tr>
+ <tr>
+ <td style="vertical-align: top;" width="20%">list<br>
+ </td>
+ <td style="vertical-align: top;" width="40%">base directory from
+which files are listed<br>
+ </td>
+ <td style="vertical-align: top;">the remote files located under
+the <code>remotedir </code>matching the include/exclude patterns of
+the <code>fileset <br>
+ </code></td>
+ </tr>
+ <tr>
+ <td style="vertical-align: top;" width="20%">mkdir</td>
+ <td style="vertical-align: top;" width="40%">directory to create<br>
+ </td>
+ <td style="vertical-align: top;">not used<br>
+ </td>
+ </tr>
+ <tr>
+ <td style="vertical-align: top;" width="20%">chmod</td>
+ <td style="vertical-align: top;" width="40%">base directory from
+which the mode of files get changed<br>
+ </td>
+ <td style="vertical-align: top;">the remote files located under
+the <code>remotedir </code>matching the include/exclude patterns of
+the <code>fileset <br>
+ </code></td>
+ </tr>
+ <tr>
+ <td style="vertical-align: top;" width="20%">rmdir<br>
+ </td>
+ <td style="vertical-align: top;" width="40%">base directory from
+which directories get removed<br>
+ </td>
+ <td style="vertical-align: top;">the remote directories located
+under the <code>remotedir </code>matching the include/exclude
+patterns of the <code>fileset <br>
+ </code></td>
+ </tr>
+ </tbody>
+</table><h3>Parameters specified as nested elements</h3>
+<h4>fileset</h4>
+<p>The ftp task supports any number of nested <a
+href="../Types/fileset.html"><code>&lt;fileset&gt;</code></a> elements to specify
+the files to be retrieved, or deleted, or listed, or whose mode you want to change.</p>
+<p>
+The attribute <code>followsymlinks</code> of <code>fileset</code> is supported on
+local (put) as well as remote (get, chmod, delete) filesets.
+<em>Before ant 1.6 there was no support of symbolic links in remote filesets.
+In order to exclude symbolic links (preserve the behavior of ant 1.5.x and older),
+you need to explicitly set <code>followsymlinks</code> to <code>false</code>.</em>
+On remote filesets hidden files are not checked for being symbolic links. Hidden
+files are currently assumed to not be symbolic links.
+</p>
+
+<h3>Sending Files</h3>
+<p>The easiest way to describe how to send files is with a couple of examples:</p>
+<pre>
+ &lt;ftp server="ftp.apache.org"
+ userid="anonymous"
+ password="me@myorg.com"&gt;
+ &lt;fileset dir="htdocs/manual"/&gt;
+ &lt;/ftp&gt;
+</pre>
+<p>Logs in to <code>ftp.apache.org</code> as <code>anonymous</code> and
+uploads all files in the <code>htdocs/manual</code> directory
+to the default directory for that user.</p>
+<pre> &lt;ftp server="ftp.apache.org"
+ remotedir="incoming"
+ userid="anonymous"
+ password="me@myorg.com"
+ depends="yes"&gt;
+ &lt;fileset dir="htdocs/manual"/&gt;
+ &lt;/ftp&gt;</pre>
+<p>Logs in to <code>ftp.apache.org</code> as <code>anonymous</code> and
+uploads all new or changed files in the <code>htdocs/manual</code> directory
+to the <code>incoming</code> directory relative to the default directory
+for <code>anonymous</code>.</p>
+<pre> &lt;ftp server="ftp.apache.org"
+ port="2121"
+ remotedir="/pub/incoming"
+ userid="coder"
+ password="java1"
+ passive="yes"
+ depends="yes"
+ binary="no"&gt;
+ &lt;fileset dir="htdocs/manual"&gt;
+ &lt;include name="**/*.html"/&gt;
+ &lt;/fileset&gt;
+ &lt;/ftp&gt;</pre>
+<p>Logs in to <code>ftp.apache.org</code> at port <code>2121</code> as
+<code>coder</code> with password <code>java1</code> and uploads all new or
+changed HTML files in the <code>htdocs/manual</code> directory to the
+<code>/pub/incoming</code> directory. The files are transferred in text mode.
+Passive mode has been switched on to send files from behind a firewall.</p>
+<pre> &lt;ftp server="ftp.hypothetical.india.org"
+ port="2121"
+ remotedir="/pub/incoming"
+ userid="coder"
+ password="java1"
+ depends="yes"
+ binary="no"
+ systemTypeKey="Windows"
+ serverTimeZoneConfig="India/Calcutta"&gt;
+ &lt;fileset dir="htdocs/manual"&gt;
+ &lt;include name="**/*.html"/&gt;
+ &lt;/fileset&gt;
+ &lt;/ftp&gt;</pre>
+<p>Logs in to a Windows server at <code>ftp.hypothetical.india.org</code>
+at port <code>2121</code> as <code>coder</code> with password <code>java1</code>
+and uploads all new or changed (accounting for timezone differences)
+HTML files in the <code>htdocs/manual</code>
+directory to the <code>/pub/incoming</code> directory. The files are transferred
+in text mode.</p>
+<pre> &lt;ftp server="ftp.nt.org"
+ remotedir="c:\uploads"
+ userid="coder"
+ password="java1"
+ separator="\"
+ verbose="yes"&gt;
+ &lt;fileset dir="htdocs/manual"&gt;
+ &lt;include name="**/*.html"/&gt;
+ &lt;/fileset&gt;
+ &lt;/ftp&gt;</pre><p>Logs in to the Windows-based <code>ftp.nt.org</code> as
+<code>coder</code> with password <code>java1</code> and uploads all
+HTML files in the <code>htdocs/manual</code> directory to the
+<code>c:\uploads</code> directory. Progress messages are displayed as each
+file is uploaded.</p>
+<h3>Getting Files</h3>
+<p>Getting files from an FTP server works pretty much the same way as
+sending them does. The only difference is that the nested filesets
+use the remotedir attribute as the base directory for the files on the
+FTP server, and the dir attribute as the local directory to put the files
+into. The file structure from the FTP site is preserved on the local machine.</p>
+<pre>
+ &lt;ftp action="get"
+ server="ftp.apache.org"
+ userid="anonymous"
+ password="me@myorg.com"&gt;
+ &lt;fileset dir="htdocs/manual"&gt;
+ &lt;include name="**/*.html"/&gt;
+ &lt;/fileset&gt;
+ &lt;/ftp&gt;
+</pre>
+<p>Logs in to <code>ftp.apache.org</code> as <code>anonymous</code> and
+recursively downloads all .html files from default directory for that user
+into the <code>htdocs/manual</code> directory on the local machine.</p>
+<pre>
+ &lt;ftp action="get"
+ server="ftp.apache.org"
+ userid="anonymous"
+ password="me@myorg.com"
+ systemTypeKey="UNIX"
+ defaultDateFormatConfig="yyyy-MM-dd HH:mm"&gt;
+ &lt;fileset dir="htdocs/manual"&gt;
+ &lt;include name="**/*.html"/&gt;
+ &lt;/fileset&gt;
+ &lt;/ftp&gt;
+</pre>
+<p>If apache.org ever switches to a unix FTP server that uses the new all-numeric
+format for timestamps, this version would become necessary. It would accomplish
+the same functionality as the previous example but would successfully handle the
+numeric timestamps.
+The <code>systemTypeKey</code> is not necessary here but helps clarify what is
+going on.</p>
+<pre>
+ &lt;ftp action="get"
+ server="ftp.hypthetical.fr"
+ userid="anonymous"
+ password="me@myorg.com"
+ defaultDateFormatConfig="d MMM yyyy"
+ recentDateFormatConfig="d MMM HH:mm"
+ serverLanguageCodeConfig="fr"&gt;
+ &lt;fileset dir="htdocs/manual"&gt;
+ &lt;include name="**/*.html"/&gt;
+ &lt;/fileset&gt;
+ &lt;/ftp&gt;
+</pre>
+<p>Logs into a UNIX FTP server at <code>ftp.hypothetical.fr</code> which displays
+dates with French names in Standard European format, as <code>anonymous</code>, and
+recursively downloads all .html files from default directory for that user
+into the <code>htdocs/manual</code> directory on the local machine.</p>
+
+<h3>Deleting Files</h3>
+As you've probably guessed by now, you use nested fileset elements to
+select the files to delete from the remote FTP server. Again, the
+filesets are relative to the remote directory, not a local directory. In
+fact, the dir attribute of the fileset is ignored completely.
+
+<pre>
+ &lt;ftp action="del"
+ server="ftp.apache.org"
+ userid="anonymous"
+ password="me@myorg.com"&gt;
+ &lt;fileset&gt;
+ &lt;include name="**/*.tmp"/&gt;
+ &lt;/fileset&gt;
+ &lt;/ftp&gt;
+</pre>
+<p>Logs in to <code>ftp.apache.org</code> as <code>anonymous</code> and
+tries to delete all *.tmp files from the default directory for that user.
+If you don't have permission to delete a file, a BuildException is thrown.</p>
+<h3>Listing Files</h3>
+<pre>
+ &lt;ftp action="list"
+ server="ftp.apache.org"
+ userid="anonymous"
+ password="me@myorg.com"
+ listing="data/ftp.listing"&gt;
+ &lt;fileset&gt;
+ &lt;include name="**"/&gt;
+ &lt;/fileset&gt;
+ &lt;/ftp&gt;
+</pre>
+<p>This provides a file listing in <code>data/ftp.listing</code> of all the files on
+the FTP server relative to the default directory of the <code>anonymous</code>
+user. The listing is in whatever format the FTP server normally lists files.</p>
+
+<h3>Creating Directories</h3>
+<p>Note that with the mkdir action, the directory to create is specified using the
+remotedir attribute.</p>
+<pre>
+ &lt;ftp action="mkdir"
+ server="ftp.apache.org"
+ userid="anonymous"
+ password="me@myorg.com"
+ remotedir="some/remote/dir"/&gt;
+</pre>
+<p>This creates the directory <code>some/remote/dir</code> beneath the default root
+directory. As with all other actions, the directory separator character must be correct
+according to the desires of the FTP server.</p>
+<h3>Removing Directories</h3>
+This action uses nested fileset elements to
+select the directories to remove from the remote FTP server. The
+filesets are relative to the remote directory, not a local directory.
+The dir attribute of the fileset is ignored completely.
+The directories to be removed must be empty, or contain only
+other directories that have been also selected to be removed by the filesets
+patterns, otherwise a BuildException will be thrown.
+Also, if you don't have permission to remove a directory, a BuildException is
+thrown.
+
+<pre>
+ &lt;ftp action="rmdir"
+ server="ftp.apache.org"
+ userid="anonymous"
+ password="me@myorg.com"
+ remotedir="/somedir" &gt;
+ &lt;fileset&gt;
+ &lt;include name="dira"/&gt;
+ &lt;include name="dirb/**"/&gt;
+ &lt;/fileset&gt;
+ &lt;/ftp&gt;
+</pre>
+<p>Logs in to <code>ftp.apache.org</code> as <code>anonymous</code> and
+tries to remove <code>/somedir/dira</code> directory and
+all the directories tree starting at, and including, <code>/somedir/dirb</code>.
+When removing the <code>/somedir/dirb</code> tree,
+it will start at the leaves moving up to the root, so that when
+it tries to remove a directory it is sure all the directories under it are
+already removed.
+Obviously all the files in the tree must have been already deleted.
+</p>
+<p>As an example suppose you want to delete everything contained into
+<code>/somedir</code>, so invoke first the <code>&lt;ftp&gt;</code> task with
+<code>action="delete"</code>, then with
+<code>action="rmdir"</code> specifying in both cases
+<code>remotedir="/somedir"</code> and
+
+<pre>
+ &lt;fileset&gt;
+ &lt;include name="**"/&gt;
+ &lt;/fileset&gt;
+</pre>
+
+The directory specified in the <code>remotedir</code> parameter is never
+selected for remove, so if you need to remove it, specify its parent in
+<code>remotedir</code> parameter and include it in the
+<code>&lt;fileset&gt;</code> pattern, like <code>"somedir/**"</code>.
+</p>
+
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/genkey.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/genkey.html
new file mode 100644
index 00000000..96959c2f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/genkey.html
@@ -0,0 +1,125 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>GenKey Task</title>
+</head>
+
+<body>
+
+<h2><a name="genkey">GenKey</a></h2>
+<h3>Description</h3>
+<p>Generates a key in a keystore. </p>
+
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">alias</td>
+ <td valign="top">the alias to add under</td>
+ <td valign="top" align="center">Yes.</td>
+ </tr>
+ <tr>
+ <td valign="top">storepass</td>
+ <td valign="top">password for keystore integrity. Must
+ be at least 6 characters long</td>
+ <td valign="top" align="center">Yes.</td>
+ </tr>
+ <tr>
+ <td valign="top">keystore</td>
+ <td valign="top">keystore location</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">storetype</td>
+ <td valign="top">keystore type</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">keypass</td>
+ <td valign="top">password for private key (if different)</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">sigalg</td>
+ <td valign="top">the algorithm to use in signing</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">keyalg</td>
+ <td valign="top">the method to use when generating name-value pair</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">verbose</td>
+ <td valign="top">(true | false) verbose output when signing</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">dname</td>
+ <td valign="top">The distinguished name for entity</td>
+ <td valign="top" align="center">Yes if dname element unspecified</td>
+ </tr>
+ <tr>
+ <td valign="top">validity</td>
+ <td valign="top">(integer) indicates how many days certificate is valid</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">keysize</td>
+ <td valign="top">(integer) indicates the size of key generated</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+</table>
+
+<p>Alternatively you can specify the distinguished name by creating a
+sub-element named dname and populating it with param elements that
+have a name and a value. When using the subelement it is automatically
+encoded properly and commas (&quot;<code>,</code>&quot;) are replaced
+with &quot;<code>\,</code>&quot;.</p>
+
+<p>The following two examples are identical: </p>
+
+<h3>Examples</h3>
+<blockquote><pre>
+&lt;genkey alias=&quot;apache-group&quot; storepass=&quot;secret&quot;
+ dname=&quot;CN=Ant Group, OU=Jakarta Division, O=Apache.org, C=US&quot;/&gt;
+</pre></blockquote>
+
+<blockquote>
+ <pre>
+&lt;genkey alias=&quot;apache-group&quot; storepass=&quot;secret&quot; &gt;
+ &lt;dname&gt;
+ &lt;param name=&quot;CN&quot; value=&quot;Ant Group&quot;/&gt;
+ &lt;param name=&quot;OU&quot; value=&quot;Jakarta Division&quot;/&gt;
+ &lt;param name=&quot;O&quot; value=&quot;Apache.Org&quot;/&gt;
+ &lt;param name=&quot;C&quot; value=&quot;US&quot;/&gt;
+ &lt;/dname&gt;
+&lt;/genkey&gt;</pre>
+</blockquote>
+
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/get.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/get.html
new file mode 100644
index 00000000..04bc0e4d
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/get.html
@@ -0,0 +1,239 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Get Task</title>
+</head>
+
+<body>
+
+<h2><a name="get">Get</a></h2>
+<h3>Description</h3>
+<p>Gets files from URLs. When the verbose option is &quot;on&quot;, this task
+displays a '.' for every 100 Kb retrieved. Any URL schema supported by
+the runtime is valid here, including http:, ftp: and jar:;
+</p>
+The <i>usetimestamp</i> option enables you to control downloads so that the remote file is
+only fetched if newer than the local copy. If there is no local copy, the download always takes
+place. When a file is downloaded, the timestamp of the downloaded file is set to the remote timestamp.
+NB: This timestamp facility only works on downloads using the HTTP protocol.
+<p>
+A username and password can be specified, in which case basic 'slightly encoded
+plain text' authentication is used. This is only secure over an HTTPS link.
+</p>
+
+<p><b>Proxies</b>. Since Apache Ant 1.7.0, Ant running on Java1.5 or later can
+ <a href="../proxy.html">use the proxy settings of the operating
+ system</a> if enabled with the
+ <code>-autoproxy</code> option. There is also the
+ <a href="../Tasks/setproxy.html">&lt;setproxy&gt;</a> task
+ for earlier Java versions. With proxies turned
+ on, <code>&lt;get&gt;</code> requests against localhost may not work
+ as expected, if the request is relayed to the proxy.</p>
+
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">src</td>
+ <td valign="top">the URL from which to retrieve a file.</td>
+ <td align="center" valign="top">Yes or a nested resource collection</td>
+ </tr>
+ <tr>
+ <td valign="top">dest</td>
+ <td valign="top">the file or directory where to store the
+ retrieved file(s).</td>
+ <td align="center" valign="top">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">verbose</td>
+ <td valign="top">show verbose progress information (&quot;on&quot;/&quot;off&quot;).</td>
+ <td align="center" valign="top">No; default "false"</td>
+ </tr>
+ <tr>
+ <td valign="top">quiet</td>
+ <td valign="top">Log errors only.(&quot;true&quot;/&quot;false&quot;).</td>
+ <td align="center" valign="top">No; default "false"</td>
+ </tr>
+ <tr>
+ <td valign="top">ignoreerrors</td>
+ <td valign="top">Log errors but don't treat as fatal.</td>
+ <td align="center" valign="top">No; default "false"</td>
+ </tr>
+ <tr>
+ <td valign="top">usetimestamp</td>
+ <td valign="top">conditionally download a file based on the timestamp of the
+ local copy. HTTP only</td>
+ <td align="center" valign="top">No; default "false"</td>
+ </tr>
+ <tr>
+ <td valign="top">username</td>
+ <td valign="top">username for 'BASIC' http authentication</td>
+ <td align="center" valign="top">if password is set</td>
+ </tr>
+ <tr>
+ <td valign="top">password</td>
+ <td valign="top">password: required </td>
+ <td align="center" valign="top">if username is set</td>
+ </tr>
+ <tr>
+ <td valign="top">maxtime</td>
+ <td valign="top">Maximum time in seconds a single download may take,
+ otherwise it will be interrupted and treated like a download
+ error. <em>Since Ant 1.8.0</em></td>
+ <td align="center" valign="top">No: default 0 which means no
+ maximum time</td>
+ </tr>
+ <tr>
+ <td valign="top">retries</td>
+ <td valign="top">the per download number of retries on error<br/>
+ <em>since Ant 1.8.0</em></td>
+ <td align="center" valign="top">No; default "3"</td>
+ </tr>
+ <tr>
+ <td valign="top">skipexisting</td>
+ <td valign="top">skip files that already exist on the local filesystem<br/>
+ <em>since Ant 1.8.0</em></td>
+ <td align="center" valign="top">No; default "false"</td>
+ </tr>
+ <tr>
+ <td valign="top">httpusecaches</td>
+ <td valign="top">HTTP only - if true, allow caching at the
+ HttpUrlConnection level. if false, turn caching off.<br/>
+ <b>Note</b> this is only a hint to the underlying UrlConnection
+ class, implementations and proxies are free to ignore the
+ setting.</td>
+ <td align="center" valign="top">No; default "true"</td>
+ </tr>
+ <tr>
+ <td valign="top">useragent</td>
+ <td valign="top">User-Agent HTTP header to send, starting with Ant
+ 1.9.3 Ant will specify a User-Agent header of "Apache Ant VERSION"
+ unless overridden by this attribute<br/>
+ <em>since Ant 1.9.3</em></td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">tryGzipEncoding</td>
+ <td valign="top">When set to true Ant will tell the server it is
+ willing to accept gzip encoding to reduce the amount of data to
+ transfer and uncompress the content transparently.<br/>
+ Setting this to true also means Ant will uncompress
+ <code>.tar.gz</code> and similar files automatically.<br/>
+ <em>since Ant 1.9.5</em></td>
+ <td align="center" valign="top">No; default "false"</td>
+</table>
+<h3>Parameters specified as nested elements</h3>
+<h4>any resource collection</h4>
+
+<p><a href="../Types/resources.html#collection">Resource
+ Collection</a>s are used to select groups of URLs to download. If
+ the collection contains more than one resource, the dest attribute
+ must point to a directory if it exists or a directory will be
+ created if it doesn't exist. The destination file name use the
+ last part of the path of the source URL unless you also specify a
+ mapper.</p>
+
+<h4>mapper</h4>
+
+<p>You can define name transformations by using a
+ nested <a href="../Types/mapper.html">mapper</a> element. You
+ can also use any filenamemapper type in place of the mapper
+ element.</p>
+
+<p>The mapper will receive the resource's name as argument. Any
+ resource for which the mapper returns no or more than one mapped
+ name will be skipped. If the returned name is a relative path, it
+ will be considered relative to the <em>dest</em> attribute.</p>
+
+<h3>Examples</h3>
+<pre> &lt;get src=&quot;http://ant.apache.org/&quot; dest=&quot;help/index.html&quot;/&gt;</pre>
+<p>Gets the index page of http://ant.apache.org/, and stores it in the file <code>help/index.html</code>.</p>
+
+<pre> &lt;get src=&quot;http://www.apache.org/dist/ant/KEYS&quot;
+ dest=&quot;KEYS&quot;
+ verbose=&quot;true&quot;
+ usetimestamp=&quot;true&quot;/&gt;</pre>
+<p>
+Gets the PGP keys of Ant's (current and past) release managers, if the local copy
+is missing or out of date. Uses the verbose option
+for progress information.
+</p>
+
+<pre> &lt;get src=&quot;https://insecure-bank.org/statement/user=1214&quot;
+ dest=&quot;statement.html&quot;
+ username="1214";
+ password="secret"/&gt;</pre>
+<p>
+Fetches some file from a server with access control. Because https is being used the
+fact that basic auth sends passwords in plaintext is moot if you
+ignore the fact that it is part of your build file which may be
+readable by third parties. If you need more security, consider using
+the <a href="input.html">input task</a> to query for a password.</p>
+
+<p>Using a macro like the following</p>
+
+<pre>
+ &lt;macrodef name="get-and-checksum">
+ &lt;attribute name="url"/>
+ &lt;attribute name="dest"/>
+ &lt;sequential&gt;
+ &lt;local name="destdir"/&gt;
+ &lt;dirname property="destdir" file="@{dest}"/&gt;
+ &lt;get dest="${destdir}"&gt;
+ &lt;url url="@{url}"/&gt;
+ &lt;url url="@{url}.sha1"/&gt;
+ &lt;firstmatchmapper&gt;
+ &lt;globmapper from="@{url}.sha1" to="@{dest}.sha"/&gt;
+ &lt;globmapper from="@{url}" to="@{dest}"/&gt;
+ &lt;/firstmatchmapper&gt;
+ &lt;/get&gt;
+ &lt;local name="checksum.matches"/>
+ &lt;local name="checksum.matches.fail"/>
+ &lt;checksum file="@{dest}" algorithm="sha" fileext=".sha"
+ verifyproperty="checksum.matches"/>
+ &lt;condition property="checksum.matches.fail">
+ &lt;equals arg1="${checksum.matches}" arg2="false"/>
+ &lt;/condition>
+ &lt;fail if="checksum.matches.fail">Checksum error&lt;/fail>
+ &lt;/sequential>
+ &lt;/macrodef>
+</pre>
+
+<p>it is possible to download an artifacts together with its SHA1
+ checksum (assuming a certain naming convention for the checksum
+ file, of course) and validate the checksum on the fly.</p>
+
+<pre>
+&lt;get dest=&quot;downloads&quot;&gt;
+ &lt;url url=&quot;http://ant.apache.org/index.html&quot;/&gt;
+ &lt;url url=&quot;http://ant.apache.org/faq.html&quot;/&gt;
+&lt;/get&gt;
+</pre>
+<p>Gets the index and FAQ pages of http://ant.apache.org/, and stores
+ them in the directory <code>downloads</code> which will be created if
+ necessary.</p>
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/gunzip.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/gunzip.html
new file mode 100644
index 00000000..32e2cf21
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/gunzip.html
@@ -0,0 +1,29 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>GUnZip Task</title>
+</head>
+
+<body>
+This document's new home is <A HREF="unpack.html">here</A>
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/gzip.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/gzip.html
new file mode 100644
index 00000000..6054d319
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/gzip.html
@@ -0,0 +1,29 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>GZip Task</title>
+</head>
+
+<body>
+This document's new home is <A HREF="pack.html">here</A>
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/hostinfo.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/hostinfo.html
new file mode 100644
index 00000000..851b4036
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/hostinfo.html
@@ -0,0 +1,98 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>HostInfo Task</title>
+</head>
+
+<body>
+
+<h2><a name="hostinfo">HostInfo</a></h2>
+
+<h3>Description</h3>
+<p>Sets the <code>NAME</code>, <code>DOMAIN</code>, <code>ADDR4</code>, and <code>ADDR6</code>
+properties in the current project.</p>
+<p>
+The <code>NAME</code> contains the host part of the canonical name of the host.<br/>
+If the host is not found, the host will contain the name as provided to the task,
+or <code>localhost</code> if no host was provided, and no name for the local
+host was found.<br/>
+The <code>DOMAIN</code> contains the domain part of the canonical name of the host.<br/>
+ If the host is not found, the domain will contain the domain as provided to the task,
+ or <code>localdomain</code> if no host / domain was provided.<br/>
+The <code>ADDR4</code> contains the IPv4 address of the host with the widest meaning.<br/>
+If no IPv4 address is found and a host has been provided the address <code>0.0.0.0</code>
+is returned, when no host was provided the address <code>127.0.0.1</code> is returned.<br/>
+The <code>ADDR6</code> contains the IPv6 address of the host with the widest meaning.<br/>
+If no IPv6 address is found and a host has been provided the address <code>::</code>
+is returned, when no host was provided the address <code>::1</code> is returned.<br/>
+</p>
+
+<p>These properties can be used in the build-file, for instance, to create
+host-stamped filenames, or used to replace placeholder tags inside documents
+to indicate, for example, the host where the build was performed on.
+The best place for this task is probably in an initialization target.</p>
+
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">prefix</td>
+ <td valign="top">Prefix used for all properties set. The default is no prefix.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">host</td>
+ <td valign="top">
+ The host to retrieve the information for, default is to retrieve
+ information for the host the task is running on.
+ </td>
+ <td align="center" valign="top">No</td>
+ </tr>
+</table>
+
+<h3>Examples</h3>
+
+<pre>
+ &lt;hostinfo/&gt;
+</pre>
+
+<p>
+Sets the <code>NAME</code>, <code>DOMAIN</code>, <code>ADDR4</code>, and
+<code>ADDR6</code> for the local host, using the most &quot;global&quot; address
+available.</p>
+<pre>
+ &lt;hostinfo prefix=&quot;remotehost&quot; host=&quot;www.apache.org&quot;/&gt;
+</pre>
+<p>
+Sets the properties <code>remotehost.NAME</code> to <code>eos</code>,
+<code>remotehost.DOMAIN</code> to <code>apache.org</code>,
+<code>remotehost.ADDR4</code> to <code>140.211.11.130</code> and
+<code>remotehost.ADDR6</code> to <code>::</code>
+for the host with the name www.apache.org (provided the canonical name and ip
+addresses do not change).
+</p>
+
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/image-classdiagram.gif b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/image-classdiagram.gif
new file mode 100644
index 00000000..fa4b81e8
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/image-classdiagram.gif
Binary files differ
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/image.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/image.html
new file mode 100644
index 00000000..ed7ed7ef
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/image.html
@@ -0,0 +1,261 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Image Task</title>
+</head>
+
+<body>
+
+<h2><a name="image">Image</a></h2>
+<h3>Description</h3>
+<p>Applies a chain of image operations on a set of files.</p>
+<p>Requires Java Advanced Image API from Sun.</p>
+
+<h5>Overview of used datatypes</h5>
+<img src="image-classdiagram.gif" border="0" alt="Class-Diagram">
+
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top"> failonerror </td>
+ <td valign="top"> Boolean value. If false, note errors to the output but keep going. </td>
+ <td align="center"> no (defaults to <i>true</i>) </td>
+ </tr>
+ <tr>
+ <td valign="top"> srcdir </td>
+ <td valign="top"> Directory containing the images. </td>
+ <td align="center"> yes, unless nested fileset is used </td>
+ </tr>
+ <tr>
+ <td valign="top"> encoding </td>
+ <td valign="top"> Image encoding type. <br>
+ Valid (caseinsensitive) are: jpg, jpeg, tif, tiff
+ </td>
+ <td align="center"> no (defaults to <i>JPEG</i>) </td>
+ </tr>
+ <tr>
+ <td valign="top"> overwrite </td>
+ <td valign="top"> Boolean value. Sets whether or not to overwrite
+ a file if there is naming conflict.
+ </td>
+ <td align="center"> no (defaults to <i>false</i>) </td>
+ </tr>
+ <tr>
+ <td valign="top"> gc </td>
+ <td valign="top"> Boolean value. Enables garbage collection after
+ each image processed.
+ </td>
+ <td align="center"> no (defaults to <i>false</i>) </td>
+ </tr>
+ <tr>
+ <td valign="top"> destdir </td>
+ <td valign="top"> Directory where the result images are stored. </td>
+ <td align="center"> no (defaults to value of <i>srcdir</i>) </td>
+ </tr>
+ <!-- attributes inherited from MatchingTask -->
+ <tr>
+ <td valign="top">includes</td>
+ <td valign="top">comma- or space-separated list of patterns of files that must be
+ included. All files are included when omitted.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">includesfile</td>
+ <td valign="top">the name of a file. Each line of this file is
+ taken to be an include pattern</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top"> excludes</td>
+ <td valign="top">comma- or space-separated list of patterns of files that must be
+ excluded. No files (except default excludes) are excluded when omitted.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">excludesfile</td>
+ <td valign="top">the name of a file. Each line of this file is
+ taken to be an exclude pattern</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">defaultexcludes</td>
+ <td valign="top">indicates whether default excludes should be used or not
+ (&quot;yes&quot;/&quot;no&quot;). Default excludes are used when omitted.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top"> caseSensitive </td>
+ <td valign="top"> Boolean value. Sets case sensitivity of the file system. </td>
+ <td align="center"> no (defaults to <i>false</i>) </td>
+ </tr>
+ <tr>
+ <td valign="top"> followSymlinks </td>
+ <td valign="top"> Boolean value. Sets whether or not symbolic links should be followed. </td>
+ <td align="center"> no (defaults to <i>true</i>) </td>
+ </tr>
+</table>
+
+<h3>Parameters specified as nested elements</h3>
+<p>This task forms an implicit <a href="../Types/fileset.html">FileSet</a> and
+supports most attributes of <code>&lt;fileset&gt;</code> as well as the
+nested <code>&lt;include&gt;</code>, <code>&lt;exclude&gt;</code> and
+<code>&lt;patternset&gt;</code> elements.</p>
+
+
+<h4>ImageOperation</h4>
+<p>Adds an ImageOperation to chain.</p>
+<h5>Nested Elements</h5>
+ImageOperation can handle nested Rotate, Draw, Rectangle, Text and Scale objects.
+
+<h4>Rotate</h4>
+<p>Adds a Rotate ImageOperation to chain.</p>
+<h5>Parameters</h5>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top"> angle </td>
+ <td valign="top"> Float value. Sets the angle of rotation in degrees. </td>
+ <td align="center"> no (defaults to <i>0.0F</i>) </td>
+ </tr>
+</table>
+
+<h4>Scale</h4>
+<p>Adds a Scale ImageOperation to chain.</p>
+<h5>Parameters</h5>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <td valign="top"> proportions </td>
+ <td valign="top"> Sets which dimension to control proportions from. Valid values are:<ul>
+ <li>&quot;ignore&quot; - treat the dimensions independently.</li>
+ <li>&quot;height&quot; - keep proportions based on the width.</li>
+ <li>&quot;width&quot; - keep proportions based on the height.</li>
+ <li>&quot;cover&quot; - keep proportions and fit in the supplied dimensions.</li>
+ <li>&quot;fit&quot; - keep proportions and cover the supplied dimensions.</li>
+ </ul></td>
+ <td align="center"> no (defaults to <i>ignore</i>) </td>
+ <tr>
+ <td valign="top"> width </td>
+ <td valign="top"> Sets the width of the image, either as an integer or a %. </td>
+ <!-- todo: if integer, what kind? cm, px, inches, ... -->
+ <td align="center"> no (defaults to <i>100%</i>) </td>
+ </tr>
+ <tr>
+ <td valign="top"> height </td>
+ <td valign="top"> Sets the height of the image, either as an integer or a %. </td>
+ <!-- todo: if integer, what kind? cm, px, inches, ... -->
+ <td align="center"> no (defaults to <i>100%</i>) </td>
+ </tr>
+</table>
+
+<h4>Draw</h4>
+<p>Adds a Draw ImageOperation to chain. DrawOperation DataType objects can be
+nested inside the Draw object.</p>
+<h5>Parameters</h5>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top"> xloc </td>
+ <td valign="top"> X-Position where to draw nested image elements. </td>
+ <td align="center"> no (defaults to <i>0</i>) </td>
+ </tr>
+ <tr>
+ <td valign="top"> yloc </td>
+ <td valign="top"> Y-Position where to draw nested image elements. </td>
+ <td align="center"> no (defaults to <i>0</i>) </td>
+ </tr>
+</table>
+
+<h4>mapper</h4>
+<p><em>Since Apache Ant 1.8.0</em></p>
+
+<p>You can define filename transformations by using a
+ nested <a href="../Types/mapper.html">mapper</a> element. The
+ default mapper used by
+ <code>&lt;image&gt;</code> is
+ the <a href="../Types/mapper.html#identity-mapper">identity
+ mapper</a>.</p>
+
+<p>You can also use a filenamemapper type in place of the mapper
+ element.</p>
+
+<h3>Examples</h3>
+
+<blockquote><pre>
+&nbsp;&lt;image destdir="samples/low" overwrite="yes"&gt;
+&nbsp;&nbsp;&nbsp;&nbsp; &lt;fileset dir="samples/full"&gt;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;include name="**/*.jpg"/&gt;
+&nbsp;&nbsp;&nbsp;&nbsp; &lt;/fileset&gt;
+&nbsp;&nbsp;&nbsp;&nbsp; &lt;scale width="160" height="160" proportions="fit"/&gt;
+&nbsp;&lt;/image&gt;
+</pre></blockquote>
+<p>Create thumbnails of my images and make sure they all fit within the 160x160 size whether the
+image is portrait or landscape.</p>
+
+<blockquote><pre>
+&lt;image srcdir="src" includes="*.png"&gt;
+ &lt;scale proportions="width" width="40"/&gt;
+&lt;/image&gt;
+</pre></blockquote>
+<p>Creates a thumbnail for all PNG-files in <i>src</i> in the size of 40 pixel keeping the proportions
+and stores the <i>src</i>.</p>
+
+<blockquote><pre>
+&lt;image srcdir="src" destdir="dest" includes="*.png"&gt;
+ &lt;scale proportions="width" width="40"/&gt;
+&lt;/image&gt;
+</pre></blockquote>
+<p>Same as above but stores the result in <i>dest</i>.</p>
+
+<blockquote><pre>
+&lt;image srcdir="src" destdir="dest" includes="*.png"&gt;
+ &lt;scale proportions="width" width="40"/&gt;
+ &lt;globmapper from="*" to="scaled-*"/&gt;
+&lt;/image&gt;
+</pre></blockquote>
+<p>Same as above but stores the resulting file names will be prefixed
+ by "scaled-".</p>
+
+<blockquote><pre>
+</pre></blockquote>
+
+
+
+</body>
+</html>
+
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/import.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/import.html
new file mode 100644
index 00000000..4cf8de08
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/import.html
@@ -0,0 +1,349 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+ <meta http-equiv="Content-Language" content="en-us">
+ <link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+ <title>Import Task</title>
+</head>
+<body>
+ <h2><a name="import">Import</a></h2>
+ <h3>Description</h3>
+ <p>
+ Imports another build file into the current project.
+ </p>
+
+ <p>
+ On execution it will select the proper ProjectHelper to parse the imported
+ file, using the same algorithm as the one executed at
+ <a href="../projecthelper.html">startup</a>. The selected ProjectHelper
+ instance will then be responsible to actually parse the imported file.
+ </p>
+
+ <p>
+ <b>Note</b> as seen above, this task heavily relies on the ProjectHelper
+ implementation and doesn't really perform any work of its own. If
+ you have configured Apache Ant to use a ProjectHelper other than Ant's
+ default, this task may or may not work.
+ </p>
+
+ <p>
+ In the common use case where only Ant's default project helper is
+ used, it basically works like the
+ <a href="http://ant.apache.org/faq.html#xml-entity-include">Entity
+ Includes as explained in the Ant FAQ</a>, as if the imported file was
+ contained in the importing file, minus the top <code>&lt;project&gt;</code>
+ tag.
+ </p>
+
+ <p>
+ The import task may only be used as a top-level task. This means that
+ it may not be used in a target.
+ </p>
+ <p>
+There are two further functional aspects that pertain to this task and
+that are not possible with entity includes:
+<ul>
+ <li>target overriding</li>
+ <li>special properties</li>
+</ul>
+ </p>
+<h4>Target overriding</h4>
+
+<p>If a target in the main file is also present in at least one of the
+imported files, the one from the main file takes precedence.</p>
+
+<p>So if I import for example a <i>docsbuild.xml</i> file named <b>builddocs</b>,
+that contains a &quot;<b>docs</b>&quot; target, I can redefine it in my main
+buildfile and that is the one that will be called. This makes it easy to
+keep the same target name, so that the overriding target is still called
+by any other targets--in either the main or imported buildfile(s)--for which
+it is a dependency, with a different implementation. The target from <i>docsbuild.xml</i> is
+made available by the name &quot;<b>builddocs</b><b>.docs</b>&quot;.
+This enables the new implementation to call the old target, thus
+<i>enhancing</i> it with tasks called before or after it.</p>
+
+<p>If you use the <i>as</i> attribute of the task, its value will be
+ used to prefix the overridden target's name instead of the name
+ attribute of the project tag.</p>
+
+<h4>Special Properties</h4>
+
+<p>Imported files are treated as they are present in the main
+buildfile. This makes it easy to understand, but it makes it impossible
+for them to reference files and resources relative to their path.
+Because of this, for every imported file, Ant adds a property that
+contains the path to the imported buildfile. With this path, the
+imported buildfile can keep resources and be able to reference them
+relative to its position.</p>
+
+<p>So if I import for example a <i>docsbuild.xml</i> file named <b>builddocs</b>,
+I can get its path as <b>ant.file.builddocs</b>, similarly to the <b>ant.file</b>
+property of the main buildfile.</p>
+
+<p>Note that &quot;builddocs&quot; is not the filename, but the name attribute
+present in the imported project tag.</p>
+ <p>
+ If the imported file does not have a name attribute, the ant.file.projectname
+ property will not be set.
+ </p>
+
+<p>Since Ant 1.8.0 the task can also import resources from URLs or
+ classpath resources (which are URLs, really). If you need to know
+ whether the current build file's source has been a file or an URL
+ you can consult the
+ property <b>ant.file.type.<em>projectname</em></b> (using the same
+ example as above <b>ant.file.type.builddocs</b>) which either have
+ the value "file" or "url".</p>
+
+<h4>Resolving files against the imported file</h4>
+
+<p>Suppose your main build file called <code>importing.xml</code>
+imports a build file <code>imported.xml</code>, located anywhere on
+the file system, and <code>imported.xml</code> reads a set of
+properties from <code>imported.properties</code>:</p>
+
+<pre>&lt;!-- importing.xml --&gt;
+&lt;project name="importing" basedir="." default="..."&gt;
+&nbsp; &lt;import file="${path_to_imported}/imported.xml"/&gt;
+&lt;/project&gt;
+
+&lt;!-- imported.xml --&gt;
+&lt;project name="imported" basedir="." default="..."&gt;
+&nbsp; &lt;property file="imported.properties"/&gt;
+&lt;/project&gt;
+</pre>
+
+<p>This snippet however will resolve <code>imported.properties</code>
+against the basedir of <code>importing.xml</code>, because the basedir
+of <code>imported.xml</code> is ignored by Ant. The right way to use
+<code>imported.properties</code> is:</p>
+
+<pre>
+&lt;!-- imported.xml --&gt;
+&lt;project name="imported" basedir="." default="..."&gt;
+&nbsp; &lt;dirname property="imported.basedir" file="${ant.file.imported}"/&gt;
+&nbsp; &lt;property file="${imported.basedir}/imported.properties"/&gt;
+&lt;/project&gt;
+</pre>
+
+<p>As explained above <code>${ant.file.imported}</code> stores the
+path of the build script, that defines the project called
+<code>imported</code>, (in short it stores the path to
+<code>imported.xml</code>) and <a
+href="dirname.html"><code>&lt;dirname&gt;</code></a> takes its
+directory. This technique also allows <code>imported.xml</code> to be
+used as a standalone file (without being imported in other
+project).</p>
+
+<p>The above description only works for imported files that actually
+ are imported from files and not from URLs. For files imported from
+ URLs using resources relative to the imported file requires you to
+ use tasks that can work on non-file resources in the first place.
+ To create a relative resource you'd use something like:</p>
+
+<pre>
+ &lt;loadproperties&gt;
+ &lt;url baseUrl="${ant.file.imported}"
+ relativePath="imported.properties"/&gt;
+ &lt;/loadproperties&gt;
+</pre>
+
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tbody>
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">
+ file
+ </td>
+ <td valign="top">
+ The file to import. If this is a relative file name, the file name will be resolved
+ relative to the <i>importing</i> file. <b>Note</b>, this is unlike most other
+ ant file attributes, where relative files are resolved relative to ${basedir}.
+ </td>
+ <td valign="top" align="center">Yes or a nested resource collection</td>
+ </tr>
+ <tr>
+ <td valign="top">
+ optional
+ </td>
+ <td valign="top">
+ If true, do not stop the build if the file does not exist,
+ default is false.
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">
+ as
+ </td>
+ <td valign="top">
+ Specifies the prefix prepended to the target names. If
+ omitted, the name attribute of the project tag of the
+ imported file will be used.
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">
+ prefixSeparator
+ </td>
+ <td valign="top">
+ Specifies the separator to be used between the prefix and the
+ target name. Defaults to ".".
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ </tbody>
+</table>
+
+<h3>Parameters specified as nested elements</h3>
+
+<h4>any <a href="../Types/resources.html">resource</a> or resource
+collection</h4>
+
+<p>The specified resources will be imported. <em>Since Ant
+ 1.8.0</em></p>
+
+<h3>Examples</h3>
+<pre>&nbsp; &lt;import file=&quot;../common-targets.xml&quot;/&gt;
+</pre>
+
+<p>Imports targets from the common-targets.xml file that is in a parent
+directory.</p>
+
+<pre>&nbsp; &lt;import file=&quot;${deploy-platform}.xml&quot;/&gt;
+</pre>
+
+<p>Imports the project defined by the property deploy-platform</p>
+
+<pre>
+ &lt;import&gt;
+ &lt;javaresource name="common/targets.xml"&gt;
+ &lt;classpath location="common.jar"/&gt;
+ &lt;/javaresource&gt;
+ &lt;/import&gt;
+</pre>
+
+<p>Imports targets from the targets.xml file that is inside the
+ directory common inside the jar file common.jar.</p>
+
+<h3>How is &lt;import&gt; different
+ from <a href="include.html">&lt;include&gt;</a>?</h3>
+
+<p>The short version: Use import if you intend to override a target,
+ otherwise use include.</p>
+
+<p>When using import the imported targets are available by up to two
+ names. Their "normal" name without any prefix and potentially with
+ a prefixed name (the value of the as attribute or the imported
+ project's name attribute, if any).</p>
+
+<p>When using include the included targets are only available in the
+ prefixed form.</p>
+
+<p>When using import, the imported target's depends attribute
+ remains unchanged, i.e. it uses "normal" names and allows you to
+ override targets in the dependency list.</p>
+
+<p>When using include, the included targets cannot be overridden and
+ their depends attributes are rewritten so that prefixed names are
+ used. This allows writers of the included file to control which
+ target is invoked as part of the dependencies.</p>
+
+<p>It is possible to include the same file more than once by using
+ different prefixes, it is not possible to import the same file more
+ than once.</p>
+
+<h4>Examples</h4>
+
+<p><i>nested.xml</i> shall be:</p>
+
+<pre>
+&lt;project&gt;
+ &lt;target name="setUp"&gt;
+ &lt;property name="prop" value="in nested"/&gt;
+ &lt;/target&gt;
+
+ &lt;target name="echo" depends="setUp"&gt;
+ &lt;echo&gt;prop has the value ${prop}&lt;/echo&gt;
+ &lt;/target&gt;
+&lt;/project&gt;
+</pre>
+
+<p>When using import like in</p>
+
+<pre>
+&lt;project default="test"&gt;
+ &lt;target name="setUp"&gt;
+ &lt;property name="prop" value="in importing"/&gt;
+ &lt;/target&gt;
+
+ &lt;import file="nested.xml" as="nested"/&gt;
+
+ &lt;target name="test" depends="nested.echo"/&gt;
+&lt;/project&gt;
+</pre>
+
+<p>Running the build file will emit:
+
+<pre>
+setUp:
+
+nested.echo:
+ [echo] prop has the value in importing
+
+test:
+
+</pre>
+
+<p>When using include like in</p>
+
+<pre>
+&lt;project default="test"&gt;
+ &lt;target name="setUp"&gt;
+ &lt;property name="prop" value="in importing"/&gt;
+ &lt;/target&gt;
+
+ &lt;include file="nested.xml" as="nested"/&gt;
+
+ &lt;target name="test" depends="nested.echo"/&gt;
+&lt;/project&gt;
+</pre>
+
+<p>Running the target build file will emit:
+
+<pre>
+nested.setUp:
+
+nested.echo:
+ [echo] prop has the value in nested
+
+test:
+
+</pre>
+
+<p>and there won't be any target named "echo" on the including build file.</p>
+
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/include.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/include.html
new file mode 100644
index 00000000..e2109235
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/include.html
@@ -0,0 +1,344 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+ <meta http-equiv="Content-Language" content="en-us">
+ <link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+ <title>Include Task</title>
+</head>
+<body>
+ <h2><a name="include">Include</a></h2>
+ <h3>Description</h3>
+ <p>
+ Include another build file into the current project.
+ </p>
+
+ <p><em>since Apache Ant 1.8.0</em></p>
+
+ <p>
+ <b>Note</b> this task heavily relies on the ProjectHelper
+ implementation and doesn't really perform any work of its own. If
+ you have configured Ant to use a ProjectHelper other than Ant's
+ default, this task may or may not work.
+ </p>
+
+ <p>
+ On execution it will read another Ant file into the same Project
+ rewriting the included target names and depends lists. This is
+ different
+ from <a href="http://ant.apache.org/faq.html#xml-entity-include">Entity
+ Includes as explained in the Ant FAQ</a> insofar as the target
+ names get prefixed by the included project's name or the as
+ attribute and do not appear as if the file was contained in the
+ including file.
+ </p>
+ <p>
+ The include task may only be used as a top-level task. This means that
+ it may not be used in a target.
+ </p>
+ <p>
+There are two further functional aspects that pertain to this task and
+that are not possible with entity includes:
+<ul>
+ <li>target rewriting</li>
+ <li>special properties</li>
+</ul>
+ </p>
+<h4>Target rewriting</h4>
+
+<p>Any target in the included file will be renamed
+ to <i>prefix.name</i> where <i>name</i> is the original target's
+ name and <i>prefix</i> is either the value of the <i>as</i>
+ attribute or the <i>name</i> attribute of the <i>project</i> tag of
+ the included file.</p>
+
+<p>The depends attribute of all included targets is rewritten so that
+ all target names are prefixed as well. This makes the included file
+ self-contained.</p>
+
+<p>Note that prefixes nest, so if a build file includes a file with
+ prefix "a" and the included file includes another file with prefix
+ "b", then the targets of that last build file will be prefixed by
+ "a.b.".</p>
+
+<p><code>&lt;import&gt;</code> contribute to the prefix as well, but
+ only if their <code>as</code> attribute has been specified.
+
+<h4>Special Properties</h4>
+
+<p>Included files are treated as they are present in the main
+buildfile. This makes it easy to understand, but it makes it impossible
+for them to reference files and resources relative to their path.
+Because of this, for every included file, Ant adds a property that
+contains the path to the included buildfile. With this path, the
+included buildfile can keep resources and be able to reference them
+relative to its position.</p>
+
+<p>So if I include for example a <i>docsbuild.xml</i> file named <b>builddocs</b>,
+I can get its path as <b>ant.file.builddocs</b>, similarly to the <b>ant.file</b>
+property of the main buildfile.</p>
+
+<p>Note that &quot;builddocs&quot; is not the filename, but the name attribute
+present in the included project tag.</p>
+ <p>
+ If the included file does not have a name attribute, the ant.file.projectname
+ property will not be set.
+ </p>
+
+<p>If you need to know whether the current build file's source has
+ been a file or an URL you can consult the
+ property <b>ant.file.type.<em>projectname</em></b> (using the same
+ example as above <b>ant.file.type.builddocs</b>) which either have
+ the value "file" or "url".</p>
+
+<h4>Resolving files against the included file</h4>
+
+<p>Suppose your main build file called <code>including.xml</code>
+includes a build file <code>included.xml</code>, located anywhere on
+the file system, and <code>included.xml</code> reads a set of
+properties from <code>included.properties</code>:</p>
+
+<pre>&lt;!-- including.xml --&gt;
+&lt;project name="including" basedir="." default="..."&gt;
+&nbsp; &lt;include file="${path_to_included}/included.xml"/&gt;
+&lt;/project&gt;
+
+&lt;!-- included.xml --&gt;
+&lt;project name="included" basedir="." default="..."&gt;
+&nbsp; &lt;property file="included.properties"/&gt;
+&lt;/project&gt;
+</pre>
+
+<p>This snippet however will resolve <code>included.properties</code>
+against the basedir of <code>including.xml</code>, because the basedir
+of <code>included.xml</code> is ignored by Ant. The right way to use
+<code>included.properties</code> is:</p>
+
+<pre>
+&lt;!-- included.xml --&gt;
+&lt;project name="included" basedir="." default="..."&gt;
+&nbsp; &lt;dirname property="included.basedir" file="${ant.file.included}"/&gt;
+&nbsp; &lt;property file="${included.basedir}/included.properties"/&gt;
+&lt;/project&gt;
+</pre>
+
+<p>As explained above <code>${ant.file.included}</code> stores the
+path of the build script, that defines the project called
+<code>included</code>, (in short it stores the path to
+<code>included.xml</code>) and <a
+href="dirname.html"><code>&lt;dirname&gt;</code></a> takes its
+directory. This technique also allows <code>included.xml</code> to be
+used as a standalone file (without being included in other
+project).</p>
+
+<p>The above description only works for included files that actually
+ are included from files and not from URLs. For files included from
+ URLs using resources relative to the included file requires you to
+ use tasks that can work on non-file resources in the first place.
+ To create a relative resource you'd use something like:</p>
+
+<pre>
+ &lt;loadproperties&gt;
+ &lt;url baseUrl="${ant.file.included}"
+ relativePath="included.properties"/&gt;
+ &lt;/loadproperties&gt;
+</pre>
+
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tbody>
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">
+ file
+ </td>
+ <td valign="top">
+ The file to include. If this is a relative file name, the file name will be resolved
+ relative to the <i>including</i> file. <b>Note</b>, this is unlike most other
+ ant file attributes, where relative files are resolved relative to ${basedir}.
+ </td>
+ <td valign="top" align="center">Yes or a nested resource collection</td>
+ </tr>
+ <tr>
+ <td valign="top">
+ optional
+ </td>
+ <td valign="top">
+ If true, do not stop the build if the file does not exist,
+ default is false.
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">
+ as
+ </td>
+ <td valign="top">
+ Specifies the prefix prepended to the target names. If
+ omitted, the name attribute of the project tag of the
+ included file will be used.
+ </td>
+ <td valign="top" align="center">Yes, if the included file's
+ project tag doesn't specify a name attribute.</td>
+ </tr>
+ <tr>
+ <td valign="top">
+ prefixSeparator
+ </td>
+ <td valign="top">
+ Specifies the separator to be used between the prefix and the
+ target name. Defaults to ".".
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ </tbody>
+</table>
+
+<h3>Parameters specified as nested elements</h3>
+
+<h4>any <a href="../Types/resources.html">resource</a> or resource
+collection</h4>
+
+<p>The specified resources will be included.</p>
+
+<h3>Examples</h3>
+<pre>&nbsp; &lt;include file=&quot;../common-targets.xml&quot;/&gt;
+</pre>
+
+<p>Includes targets from the common-targets.xml file that is in a parent
+directory.</p>
+
+<pre>&nbsp; &lt;include file=&quot;${deploy-platform}.xml&quot;/&gt;
+</pre>
+
+<p>Includes the project defined by the property deploy-platform</p>
+
+<pre>
+ &lt;include&gt;
+ &lt;javaresource name="common/targets.xml"&gt;
+ &lt;classpath location="common.jar"/&gt;
+ &lt;/javaresource&gt;
+ &lt;/include&gt;
+</pre>
+
+<p>Includes targets from the targets.xml file that is inside the
+ directory common inside the jar file common.jar.</p>
+
+<h3>How is <a href="import.html">&lt;import&gt;</a> different
+ from &lt;include&gt;?</h3>
+
+<p>The short version: Use import if you intend to override a target,
+ otherwise use include.</p>
+
+<p>When using import the imported targets are available by up to two
+ names. Their "normal" name without any prefix and potentially with
+ a prefixed name (the value of the as attribute or the imported
+ project's name attribute, if any).</p>
+
+<p>When using include the included targets are only available in the
+ prefixed form.</p>
+
+<p>When using import, the imported target's depends attribute
+ remains unchanged, i.e. it uses "normal" names and allows you to
+ override targets in the dependency list.</p>
+
+<p>When using include, the included targets cannot be overridden and
+ their depends attributes are rewritten so that prefixed names are
+ used. This allows writers of the included file to control which
+ target is invoked as part of the dependencies.</p>
+
+<p>It is possible to include the same file more than once by using
+ different prefixes, it is not possible to import the same file more
+ than once.</p>
+
+<h4>Examples</h4>
+
+<p><i>nested.xml</i> shall be:</p>
+
+<pre>
+&lt;project&gt;
+ &lt;target name="setUp"&gt;
+ &lt;property name="prop" value="in nested"/&gt;
+ &lt;/target&gt;
+
+ &lt;target name="echo" depends="setUp"&gt;
+ &lt;echo&gt;prop has the value ${prop}&lt;/echo&gt;
+ &lt;/target&gt;
+&lt;/project&gt;
+</pre>
+
+<p>When using import like in</p>
+
+<pre>
+&lt;project default="test"&gt;
+ &lt;target name="setUp"&gt;
+ &lt;property name="prop" value="in importing"/&gt;
+ &lt;/target&gt;
+
+ &lt;import file="nested.xml" as="nested"/&gt;
+
+ &lt;target name="test" depends="nested.echo"/&gt;
+&lt;/project&gt;
+</pre>
+
+<p>Running the build file will emit:
+
+<pre>
+setUp:
+
+nested.echo:
+ [echo] prop has the value in importing
+
+test:
+
+</pre>
+
+<p>When using include like in</p>
+
+<pre>
+&lt;project default="test"&gt;
+ &lt;target name="setUp"&gt;
+ &lt;property name="prop" value="in importing"/&gt;
+ &lt;/target&gt;
+
+ &lt;include file="nested.xml" as="nested"/&gt;
+
+ &lt;target name="test" depends="nested.echo"/&gt;
+&lt;/project&gt;
+</pre>
+
+<p>Running the target build file will emit:
+
+<pre>
+nested.setUp:
+
+nested.echo:
+ [echo] prop has the value in nested
+
+test:
+
+</pre>
+
+<p>and there won't be any target named "echo" on the including build file.</p>
+
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/input.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/input.html
new file mode 100644
index 00000000..b04affc5
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/input.html
@@ -0,0 +1,198 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Input Task</title>
+</head>
+
+<body>
+
+<h2><a name="input">Input</a></h2>
+<h3>Description</h3>
+
+<p>Allows user interaction during the build process by prompting for
+input. To do so, it uses the configured
+<a href="../inputhandler.html">InputHandler</a>.</p>
+
+<p>The prompt can be set via the message attribute or as character
+data nested into the element.</p>
+
+<p>Optionally a set of valid input arguments can be defined via the
+validargs attribute. Input task will not accept a value that doesn't match
+one of the predefined.</p>
+
+<p>Optionally a property can be created from the value entered by the
+user. This property can then be used during the following build
+run. Input behaves according to <a href="property.html">property
+task</a> which means that existing properties cannot be overridden.
+Since Apache Ant 1.6, <code>&lt;input&gt;</code> will not prompt for input if
+a property should be set by the task that has already been set in the
+project (and the task wouldn't have any effect).</p>
+
+<p>Historically, a regular complaint about this task has been that it echoes
+characters to the console, this is a critical security defect, we must fix it
+immediately, etc, etc. This problem was due to the lack in early versions of
+Java of a (fully functional) facility for handling secure console input.
+In Java 1.6 that shortcoming in Java's API was addressed and Ant versions 1.7.1
+and 1.8 have added support for Java 1.6's secure console input feature
+(see <a href="#handler.type">handler type</a>).</p>
+
+<p>
+IDE behaviour depends upon the IDE: some hang waiting for input, some let you
+type it in. For this situation, place the password in a (secured) property
+file and load in before the input task.</p>
+
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">message</td>
+ <td valign="top">the Message which gets displayed to the user
+ during the build run.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">validargs</td>
+ <td valign="top">comma separated String containing valid input
+ arguments. If set, input task will reject any input not defined
+ here. Validargs are compared case sensitive. If you want 'a' and
+ 'A' to be accepted you will need to define both arguments within
+ validargs.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">addproperty</td>
+ <td valign="top">the name of a property to be created from
+ input. Behaviour is equal to <a href="property.html">property
+ task</a> which means that existing properties cannot be
+ overridden.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">defaultvalue</td>
+ <td valign="top">Defines the default value of the property to be
+ created from input. Property value will be set to default if no
+ input is received.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+</table>
+<h3>Parameters Specified as Nested Elements</h3>
+<h4>Handler</h4>
+<p>Since <b>Ant 1.7</b>, a nested &lt;handler&gt; element can be used to
+specify an InputHandler, so that different InputHandlers may be used
+among different Input tasks.
+
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top"><a name="handler.type" />type</td>
+ <td valign="top">one of "default","propertyfile", "greedy", or "secure" (since Ant 1.8).
+ </td>
+ <td align="center" valign="top" rowspan="3">One of these</td>
+ </tr>
+ <tr>
+ <td valign="top">refid</td>
+ <td valign="top">Reference to an <code>InputHandler</code>
+ defined elsewhere in the project.
+ </td>
+ </tr>
+ <tr>
+ <td valign="top">classname</td>
+ <td valign="top">The name of an <code>InputHandler</code> subclass.</td>
+ </tr>
+ <tr>
+ <td valign="top">classpath</td>
+ <td valign="top">The classpath to use with <i>classname</i>.</td>
+ <td valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">classpathref</td>
+ <td valign="top">The refid of a classpath to use with <i>classname</i>.</td>
+ <td valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">loaderref</td>
+ <td valign="top">The refid of a classloader to use with <i>classname</i>.
+ </td>
+ <td valign="top">No</td>
+ </tr>
+</table>
+<br />
+The classpath can also be specified by means of one or more nested
+&lt;classpath&gt; elements.</p>
+
+<h3>Examples</h3>
+<pre> &lt;input/&gt;</pre>
+<p>Will pause the build run until return key is pressed when using the
+<a href="../inputhandler.html#defaulthandler">default
+InputHandler</a>, the concrete behavior is defined by the InputHandler
+implementation you use.</p>
+<pre> &lt;input&gt;Press Return key to continue...&lt;/input&gt;</pre>
+<p>Will display the message &quot;Press Return key to
+continue...&quot; and pause the build run until return key is pressed
+(again, the concrete behavior is implementation dependent).</p>
+<pre> &lt;input
+ message=&quot;Press Return key to continue...&quot;
+ /&gt;</pre>
+<p>Will display the message &quot;Press Return key to
+continue...&quot; and pause the build run until return key is pressed
+(see above).</p>
+<pre>
+ &lt;input
+ message=&quot;All data is going to be deleted from DB continue (y/n)?&quot;
+ validargs=&quot;y,n&quot;
+ addproperty=&quot;do.delete&quot;
+ /&gt;
+ &lt;condition property=&quot;do.abort&quot;&gt;
+ &lt;equals arg1=&quot;n&quot; arg2=&quot;${do.delete}&quot;/&gt;
+ &lt;/condition&gt;
+ &lt;fail if=&quot;do.abort&quot;&gt;Build aborted by user.&lt;/fail&gt;
+</pre>
+<p>Will display the message &quot;All data is going to be deleted from
+DB continue (y/n)?&quot; and require 'y' to continue build or 'n' to
+exit build with following message &quot;Build aborted by
+user.&quot;.</p>
+<pre> &lt;input
+ message=&quot;Please enter db-username:&quot;
+ addproperty=&quot;db.user&quot;
+ /&gt;</pre>
+<p>Will display the message &quot;Please enter db-username:&quot; and set the
+property <code>db.user</code> to the value entered by the user.</p>
+
+<pre> &lt;input
+ message=&quot;Please enter db-username:&quot;
+ addproperty=&quot;db.user&quot;
+ defaultvalue=&quot;Scott-Tiger&quot;
+ /&gt;</pre>
+<p>Same as above, but will set <code>db.user</code> to the value
+<i>Scott- Tiger</i> if the user enters no value (simply types
+&lt;return&gt;).</p>
+
+
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/jar.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/jar.html
new file mode 100644
index 00000000..5d3ea38b
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/jar.html
@@ -0,0 +1,588 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Jar Task</title>
+</head>
+
+<body>
+
+<h2><a name="jar">Jar</a></h2>
+<h3>Description</h3>
+<p>Jars a set of files.</p>
+<p>The <i>basedir</i> attribute is the reference directory from where to jar.</p>
+<p>Note that file permissions will not be stored in the resulting jarfile.</p>
+<p>It is possible to refine the set of files that are being jarred. This can be
+done with the <i>includes</i>, <i>includesfile</i>, <i>excludes</i>, <i>excludesfile</i> and <i>defaultexcludes</i>
+attributes. With the <i>includes</i> or <i>includesfile</i> attribute you specify the files you want to
+have included by using patterns. The <i>exclude</i> or <i>excludesfile</i> attribute is used to specify
+the files you want to have excluded. This is also done with patterns. And
+finally with the <i>defaultexcludes</i> attribute, you can specify whether you
+want to use default exclusions or not. See the section on <a
+href="../dirtasks.html#directorybasedtasks">directory based tasks</a>, on how the
+inclusion/exclusion of files works, and how to write patterns.</p>
+<p>This task forms an implicit <a href="../Types/fileset.html">FileSet</a> and
+supports most attributes of <code>&lt;fileset&gt;</code>
+(<code>dir</code> becomes <code>basedir</code>) as well as the nested
+<code>&lt;include&gt;</code>, <code>&lt;exclude&gt;</code> and
+<code>&lt;patternset&gt;</code> elements.</p>
+<p>You can also use nested file sets for more flexibility, and specify
+multiple ones to merge together different trees of files into one JAR.
+The extended fileset and groupfileset child elements from the zip task are
+also available in the jar task.
+See the <a href="zip.html">Zip</a> task for more details and examples.</p>
+
+<p>The <code>update</code> parameter controls what happens if the JAR
+file already exists. When set to <code>yes</code>, the JAR file is
+updated with the files specified. When set to <code>no</code> (the
+default) the JAR file is overwritten. An example use of this is
+provided in the <a href="zip.html">Zip task documentation</a>. Please
+note that ZIP files store file modification times with a granularity
+of two seconds. If a file is less than two seconds newer than the
+entry in the archive, Ant will not consider it newer.</p>
+
+<p>If the manifest is omitted, a simple one will be supplied by Apache Ant.</p>
+
+<p>The <code>whenmanifestonly</code> parameter controls what happens when no
+files, apart from the manifest file, or nested services, match.
+If <code>skip</code>, the JAR is not created and a warning is issued.
+If <code>fail</code>, the JAR is not created and the build is halted with an error.
+If <code>create</code>, (default) an empty JAR file (only containing a manifest and services)
+is created.</p>
+
+<p>(The Jar task is a shortcut for specifying the manifest file of a JAR file.
+The same thing can be accomplished by using the <i>fullpath</i>
+attribute of a zipfileset in a Zip task. The one difference is that if the
+<i>manifest</i> attribute is not specified, the Jar task will
+include an empty one for you.)</p>
+
+<p>Manifests are processed by the Jar task according to the
+<a target="_blank" href="http://docs.oracle.com/javase/7/docs/technotes/guides/jar/jar.html">Jar file specification.</a>
+Note in particular that this may result in manifest lines greater than 72 bytes
+being wrapped and continued on the next line.</p>
+
+<p>The Jar task checks whether you specified package information according to the
+<a target="_blank" href="http://docs.oracle.com/javase/7/docs/technotes/guides/versioning/spec/versioning2.html#wp90779">
+versioning specification</a>.</p>
+
+<p><b>Please note that the zip format allows multiple files of the same
+fully-qualified name to exist within a single archive. This has been
+documented as causing various problems for unsuspecting users. If you wish
+to avoid this behavior you must set the <code>duplicate</code> attribute
+to a value other than its default, <code>"add"</code>.</b></p>
+
+<p>To cryptographically sign your JAR file, use the <a href="signjar.html">SignJar task</a> on the JAR that you create from this task.</p>
+
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">destfile</td>
+ <td valign="top">the JAR file to create.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">basedir</td>
+ <td valign="top">the directory from which to jar the files.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">compress</td>
+ <td valign="top">Not only store data but also compress them,
+ defaults to true. Unless you set the <em>keepcompression</em>
+ attribute to false, this will apply to the entire archive, not
+ only the files you've added while updating.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">keepcompression</td>
+ <td valign="top">For entries coming from existing archives (like
+ nested <em>zipfileset</em>s or while updating the archive), keep
+ the compression as it has been originally instead of using the
+ <em>compress</em> attribute. Defaults false. <em>Since Ant
+ 1.6</em></td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">encoding</td>
+ <td valign="top">The character encoding to use for filenames
+ inside the archive. Defaults to UTF8. <strong>It is not
+ recommended to change this value as the created archive will
+ most likely be unreadable for Java otherwise.</strong>
+ <br/>See also the <a href="zip.html#encoding">discussion in the
+ zip task page</a></td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">filesonly</td>
+ <td valign="top">Store only file entries, defaults to false</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">includes</td>
+ <td valign="top">comma- or space-separated list of patterns of files that must be
+ included. All files are included when omitted.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">includesfile</td>
+ <td valign="top">the name of a file. Each line of this file is
+ taken to be an include pattern</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">excludes</td>
+ <td valign="top">comma- or space-separated list of patterns of files that must be
+ excluded. No files (except default excludes) are excluded when omitted.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">excludesfile</td>
+ <td valign="top">the name of a file. Each line of this file is
+ taken to be an exclude pattern</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">defaultexcludes</td>
+ <td valign="top">indicates whether default excludes should be used or not
+ (&quot;yes&quot;/&quot;no&quot;). Default excludes are used when omitted.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">manifest</td>
+ <td valign="top">the manifest file to use. This can be either the location of a manifest, or the name of a jar added through a fileset. If its the name of an added jar, the task expects the manifest to be in the jar at META-INF/MANIFEST.MF</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">filesetmanifest</td>
+ <td valign="top">behavior when a Manifest is found in a zipfileset or zipgroupfileset file is found. Valid values are &quot;skip&quot;, &quot;merge&quot;, and &quot;mergewithoutmain&quot;. &quot;merge&quot; will merge all of the manifests together, and merge this into any other specified manifests. &quot;mergewithoutmain&quot; merges everything but the Main section of the manifests. Default value is &quot;skip&quot;.
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">update</td>
+ <td valign="top">indicates whether to update or overwrite
+ the destination file if it already exists. Default is &quot;false&quot;.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">whenmanifestonly</td>
+ <td valign="top">behavior when no files match. Valid values are &quot;fail&quot;, &quot;skip&quot;, and &quot;create&quot;. Default is &quot;create&quot;.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">duplicate</td>
+ <td valign="top">behavior when a duplicate file is found. Valid values are &quot;add&quot;, &quot;preserve&quot;, and &quot;fail&quot;. The default value is &quot;add&quot;. </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">index</td>
+ <td valign="top">whether to create an <A
+ HREF="http://docs.oracle.com/javase/7/docs/technotes/guides/jar/jar.html#JAR_Index">index
+ list</A> to speed up classloading. This is a JDK 1.3+ specific
+ feature. Unless you specify additional jars with nested <a
+ href="#indexjars"><code>indexjars</code></a> elements, only the
+ contents of this jar will be included in the index. Defaults to
+ false.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">indexMetaInf</td>
+ <td valign="top">whether to include META-INF and its children in
+ the index. Doesn't have any effect if <em>index</em> is
+ false.<br/>
+ Sun's jar implementation used to skip the META-INF directory and
+ Ant followed that example. The behavior has been changed with
+ <a href="https://bugs.openjdk.java.net/browse/JDK-4408526">Java
+ 5</a>. In order to avoid problems with Ant generated jars on
+ Java 1.4 or earlier Ant will not include META-INF unless
+ explicitly asked to.<br/>
+ <em>Ant 1.8.0</em> - Defaults to false.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">manifestencoding</td>
+ <td valign="top">The encoding used to read the JAR manifest, when
+ a manifest file is specified. The task will always use UTF-8
+ when writing the manifest.</td>
+ <td valign="top" align="center">No, defaults to the platform encoding.</td>
+ </tr>
+ <tr>
+ <td valign="top">roundup</td>
+ <td valign="top">Whether the file modification times will be
+ rounded up to the next even number of seconds.<br>
+ Zip archives store file modification times with a granularity of
+ two seconds, so the times will either be rounded up or down. If
+ you round down, the archive will always seem out-of-date when you
+ rerun the task, so the default is to round up. Rounding up may
+ lead to a different type of problems like JSPs inside a web
+ archive that seem to be slightly more recent than precompiled
+ pages, rendering precompilation useless.<br>
+ Defaults to true. <em>Since Ant 1.6.2</em></td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">level</td>
+ <td valign="top">Non-default level at which file compression should be
+ performed. Valid values range from 0 (no compression/fastest) to 9
+ (maximum compression/slowest). <em>Since Ant 1.7</em></td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">strict</td>
+ <td valign="top">Configures how to handle breaks of the packaging version
+ specification: <ul>
+ <li><b>fail</b> = throws a BuildException</li>
+ <li><b>warn</b> = logs a message on warn level</li>
+ <li><b>ignore</b> = logs a message on verbose level (default)</li>
+ </ul>
+ <em>Since Ant 1.7.1</em></td>
+ <td valign="top" align="center">No, defaults to <tt>ignore</tt>. </td>
+ </tr>
+ <tr>
+ <td valign="top">preserve0permissions</td>
+ <td valign="top">when updating an archive or adding entries from a
+ different archive Ant will assume that a Unix permissions value of
+ 0 (nobody is allowed to do anything to the file/directory) means
+ that the permissions haven't been stored at all rather than real
+ permissions and will instead apply its own default values.<br/>
+ Set this attribute to true if you really want to preserve the
+ original permission field.<em>since Ant 1.8.0</em>
+ </td>
+ <td valign="top" align="center">No, default is false</td>
+ </tr>
+ <tr>
+ <td valign="top">useLanguageEncodingFlag</td>
+ <td valign="top">Whether to set the language encoding flag if the
+ encoding is UTF-8. This setting doesn't have any effect if the
+ encoding is not UTF-8.
+ <em>Since Ant 1.8.0</em>.
+ <br/>See also the <a href="zip.html#encoding">discussion in the
+ zip task page</a></td>
+ <td valign="top" align="center">No, default is true</td>
+ </tr>
+ <tr>
+ <td valign="top">createUnicodeExtraFields</td>
+ <td valign="top">Whether to create unicode extra fields to store
+ the file names a second time inside the entry's metadata.
+ <br>Possible values are "never", "always" and "not-encodeable"
+ which will only add Unicode extra fields if the file name cannot
+ be encoded using the specified encoding.
+ <em>Since Ant 1.8.0</em>.
+ <br/>See also the <a href="zip.html#encoding">discussion in the
+ zip task page</a></td>
+ <td align="center" valign="top">No, default is "never"</td>
+ </tr>
+ <tr>
+ <td valign="top">fallbacktoUTF8</td>
+ <td valign="top">Whether to use UTF-8 and the language encoding
+ flag instead of the specified encoding if a file name cannot be
+ encoded using the specified encoding.
+ <em>Since Ant 1.8.0</em>.
+ <br/>See also the <a href="zip.html#encoding">discussion in the
+ zip task page</a></td>
+ <td align="center" valign="top">No, default is false</td>
+ </tr>
+ <tr>
+ <td valign="top">mergeClassPathAttributes</td>
+ <td valign="top">Whether to merge the Class-Path attributes found
+ in different manifests (if merging manifests). If false, only
+ the attribute of the last merged manifest will be preserved.
+ <em>Since Ant 1.8.0</em>.
+ <br/>unless you also set flattenAttributes to true this may
+ result in manifests containing multiple Class-Path attributes
+ which violates the manifest specification.</td>
+ <td align="center" valign="top">No, default is false</td>
+ </tr>
+ <tr>
+ <td valign="top">flattenAttributes</td>
+ <td valign="top">Whether to merge attributes occurring more than
+ once in a section (this can only happen for the Class-Path
+ attribute) into a single attribute.
+ <em>Since Ant 1.8.0</em>.</td>
+ <td align="center" valign="top">No, default is false</td>
+ </tr>
+ <tr>
+ <td valign="top">zip64Mode</td>
+ <td valign="top">When to use Zip64 extensions for entries. The
+ possible values are "never", "always" and "as-needed".
+ <em>Since Ant 1.9.1</em>.
+ <br/>See also the <a href="zip.html#zip64">discussion in the
+ zip task page</a></td>
+ <td align="center" valign="top">No, default is "never"</td>
+ </tr>
+</table>
+
+<h3>Nested elements</h3>
+<h4>metainf</h4>
+<p>The nested <code>metainf</code> element specifies a <a
+href="../Types/fileset.html">FileSet</a>. All files included in this fileset will
+end up in the <code>META-INF</code> directory of the jar file. If this
+fileset includes a file named <code>MANIFEST.MF</code>, the file is
+ignored and you will get a warning.</p>
+
+<h4>manifest</h4>
+<p>The manifest nested element allows the manifest for the Jar file to
+be provided inline in the build file rather than in an external
+file. This element is identical to the
+<a href="manifest.html">manifest</a> task, but the file and mode
+attributes must be omitted.</p>
+<p>
+If both an inline manifest and an external file are both specified, the
+manifests are merged.
+</p>
+
+<p>When using inline manifests, the Jar task will check whether the manifest
+contents have changed (i.e. the manifest as specified is different in any way
+from the manifest that exists in the Jar, if it exists.
+If the manifest values have changed the jar will be updated or rebuilt, as
+appropriate.
+</p>
+
+<a name="indexjars"><h4>indexjars</h4></a>
+
+<p><em>since ant 1.6.2</em></p>
+
+<p>The nested <code>indexjars</code> element specifies a <a
+href="../using.html#path">PATH like structure</a>. Its content is
+completely ignored unless you set the index attribute of the task to
+true.</p>
+
+<p>The index created by this task will contain indices for the
+archives contained in this path, the names used for the archives
+depend on your manifest:</p>
+<ul>
+ <li>If the generated jar's manifest contains no Class-Path
+ attribute, the file name without any leading directory path will be
+ used and all parts of the path will get indexed.</li>
+ <li>If the manifest contains a Class-Path attribute, this task will
+ try to guess which part of the Class-Path belongs to a given
+ archive. If it cannot guess a name, the archive will be skipped,
+ otherwise the name listed inside the Class-Path attribute will be
+ used.</li>
+</ul>
+
+<p>This task will not create any index entries for archives that are
+ empty or only contain files inside the META-INF directory unless
+ the <code>indexmetainf</code> attribute has been set
+ to <code>true</code>.</p>
+
+<a name="service"><h4>service</h4></a>
+
+<p><em>since ant 1.7.0</em></p>
+
+<p>
+ The nested <code>service</code> element specifies a service.
+ Services are described in the
+ <a href="http://docs.oracle.com/javase/7/docs/technotes/guides/jar/jar.html#Service_Provider">service provider overview</a>.
+ The approach is to have providers JARs include files named by the service
+ provided, for example,
+ META-INF/services/javax.script.ScriptEngineFactory
+ which can include implementation class names, one per line (usually just one per JAR).
+
+ The name of the
+ service is set by the "type" attribute. The classname implementing
+ the service is the the "provider" attribute, or it one wants to
+ specify a number of classes that implement the service, by
+ "provider" nested elements.
+</p>
+<p>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">type</td>
+ <td valign="top">The name of the service.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">provider</td>
+ <td valign="top">
+ The classname of the class implementing the service.
+ </td>
+ <td valign="top" align="center">Yes, unless there is a nested
+ <code>&lt;provider&gt;</code> element.</td>
+ </tr>
+</table>
+ <p>
+ The provider classname is specified either by the "provider" attribute, or
+ by a nested &lt;provider&gt; element, which has a single "classname" attribute.
+ If a JAR file has more that one implementation of the service, a number of
+ nested &lt;provider&gt; elements may be used.
+ </p>
+
+
+<h3>Examples</h3>
+
+<h4>Simple</h4>
+<blockquote><pre> &lt;jar destfile=&quot;${dist}/lib/app.jar&quot; basedir=&quot;${build}/classes&quot;/&gt;</pre></blockquote>
+<p>jars all files in the <code>${build}/classes</code> directory into a file
+called <code>app.jar</code> in the <code>${dist}/lib</code> directory.</p>
+
+
+<h4>With filters</h4>
+
+<blockquote><pre> &lt;jar destfile=&quot;${dist}/lib/app.jar&quot;
+ basedir=&quot;${build}/classes&quot;
+ excludes=&quot;**/Test.class&quot;
+ /&gt;</pre></blockquote>
+<p>jars all files in the <code>${build}/classes</code> directory into a file
+called <code>app.jar</code> in the <code>${dist}/lib</code> directory. Files
+with the name <code>Test.class</code> are excluded.</p>
+
+<blockquote><pre> &lt;jar destfile=&quot;${dist}/lib/app.jar&quot;
+ basedir=&quot;${build}/classes&quot;
+ includes=&quot;mypackage/test/**&quot;
+ excludes=&quot;**/Test.class&quot;
+ /&gt;</pre></blockquote>
+<p>jars all files in the <code>${build}/classes</code> directory into a file
+called <code>app.jar</code> in the <code>${dist}/lib</code> directory. Only
+files under the directory <code>mypackage/test</code> are used, and files with
+the name <code>Test.class</code> are excluded.</p>
+
+<h4>Multiple filesets</h4>
+<blockquote><pre> &lt;jar destfile=&quot;${dist}/lib/app.jar&quot;&gt;
+ &lt;fileset dir=&quot;${build}/classes&quot;
+ excludes=&quot;**/Test.class&quot;
+ /&gt;
+ &lt;fileset dir=&quot;${src}/resources&quot;/&gt;
+ &lt;/jar&gt;</pre></blockquote>
+<p>jars all files in the <code>${build}/classes</code> directory and also
+in the <code>${src}/resources</code> directory together into a file
+called <code>app.jar</code> in the <code>${dist}/lib</code> directory.
+Files with the name <code>Test.class</code> are excluded.
+If there are files such as <code>${build}/classes/mypackage/MyClass.class</code>
+and <code>${src}/resources/mypackage/image.gif</code>, they will appear
+in the same directory in the JAR (and thus be considered in the same package
+by Java).</p>
+
+<h4>Merging archives</h4>
+
+<blockquote><pre> &lt;jar destfile="build/main/checksites.jar"&gt;
+ &lt;fileset dir="build/main/classes"/&gt;
+ &lt;zipfileset includes="**/*.class" src="lib/main/some.jar"/&gt;
+ &lt;manifest&gt;
+ &lt;attribute name="Main-Class"
+ value="com.acme.checksites.Main"/&gt;
+ &lt;/manifest&gt;
+ &lt;/jar&gt;</pre></blockquote>
+<p>
+ Creates an executable jar file with a main class "com.acme.checksites.Main", and
+ embeds all the classes from the jar <code>lib/main/some.jar</code>.
+</p>
+
+<blockquote><pre> &lt;jar destfile="build/main/checksites.jar"&gt;
+ &lt;fileset dir="build/main/classes"/&gt;
+ &lt;restrict&gt;
+ &lt;name name="**/*.class"/&gt;
+ &lt;archives&gt;
+ &lt;zips&gt;
+ &lt;fileset dir="lib/main" includes="**/*.jar"/&gt;
+ &lt;/zips&gt;
+ &lt;/archives&gt;
+ &lt;/restrict&gt;
+ &lt;manifest&gt;
+ &lt;attribute name="Main-Class"
+ value="com.acme.checksites.Main"/&gt;
+ &lt;/manifest&gt;
+ &lt;/jar&gt;</pre></blockquote>
+<p>
+ Creates an executable jar file with a main class "com.acme.checksites.Main", and
+ embeds all the classes from all the jars in <code>lib/main</code>.
+</p>
+
+<h4>Inline manifest</h4>
+<blockquote><pre> &lt;jar destfile=&quot;test.jar&quot; basedir=&quot;.&quot;&gt;
+ &lt;include name=&quot;build&quot;/&gt;
+ &lt;manifest&gt;
+ &lt;!-- If this is an Applet or Web Start application, include
+ the proper attributes from <a href="http://docs.oracle.com/javase/7/docs/technotes/guides/jweb/index.html">http://docs.oracle.com/javase/7/docs/technotes/guides/jweb/index.html</a> --&gt;
+ &lt;attribute name=&quot;Permissions&quot; value=&quot;sandbox&quot;/&gt;
+ &lt;attribute name=&quot;Codebase&quot; value=&quot;example.com&quot;/&gt;
+ &lt;!-- Who is building this jar? --&gt;
+ &lt;attribute name=&quot;Built-By&quot; value=&quot;${user.name}&quot;/&gt;
+ &lt;!-- Information about the program itself --&gt;
+ &lt;attribute name=&quot;Implementation-Vendor&quot; value=&quot;ACME inc.&quot;/&gt;
+ &lt;attribute name=&quot;Implementation-Title&quot; value=&quot;GreatProduct&quot;/&gt;
+ &lt;attribute name=&quot;Implementation-Version&quot; value=&quot;1.0.0beta2&quot;/&gt;
+ &lt;!-- details --&gt;
+ &lt;section name=&quot;common/MyClass.class&quot;&gt;
+ &lt;attribute name=&quot;Sealed&quot; value=&quot;false&quot;/&gt;
+ &lt;/section&gt;
+ &lt;/manifest&gt;
+ &lt;/jar&gt;</pre></blockquote>
+<p>
+This is an example of an inline manifest specification including the version of the build
+program (Implementation-Version). Note that the Built-By attribute will take the value of the Ant
+property ${user.name}. The manifest produced by the above would look like this:
+</p>
+
+<blockquote><pre><code>Manifest-Version: 1.0
+Permissions: sandbox
+Codebase: example.com
+Built-By: conor
+Implementation-Vendor: ACME inc.
+Implementation-Title: GreatProduct
+Implementation-Version: 1.0.0beta2
+Created-By: Apache Ant 1.9.2
+
+Name: common/MyClass.class
+Sealed: false</code></pre></blockquote>
+
+<h4>Service Provider</h4>
+
+<p>
+ The following shows how to create a jar file specifying a service
+ with an implementation of the JDK6 scripting interface:
+</p>
+<blockquote><pre>&lt;jar jarfile="pinky.jar"&gt;
+ &lt;fileset dir="build/classes"/&gt;
+ &lt;service type="javax.script.ScriptEngineFactory"
+ provider="org.acme.PinkyLanguage"/&gt;
+&lt;/jar&gt;
+</pre></blockquote>
+
+
+
+<p>
+ The following shows how to create a jar file specifing a service
+ with two implementations of the JDK6 scripting interface:
+</p>
+<blockquote><pre>
+&lt;jar jarfile="pinkyandbrain.jar"&gt;
+ &lt;fileset dir="classes"/&gt;
+ &lt;service type="javax.script.ScriptEngineFactory"&gt;
+ &lt;provider classname="org.acme.PinkyLanguage"/&gt;
+ &lt;provider classname="org.acme.BrainLanguage"/&gt;
+ &lt;/service&gt;
+&lt;/jar&gt;
+</pre></blockquote>
+
+
+
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/jarlib-available.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/jarlib-available.html
new file mode 100644
index 00000000..adb732f0
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/jarlib-available.html
@@ -0,0 +1,134 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>jarlib-available Task</title>
+</head>
+
+<body>
+
+<h2><a name="jarlib-available">jarlib-available</a></h2>
+<h3>Description</h3>
+<p>Check whether an extension is present in a fileset or an extensionSet.
+If the extension is present then a property is set.</p>
+
+<p>Note that this task
+works with extensions as defined by the "Optional Package" specification.
+ For more information about optional packages, see the document
+<em>Optional Package Versioning</em> in the documentation bundle for your
+Java Standard Edition package, in file
+<code>guide/extensions/versioning.html</code> or the online
+<a target="_blank" href="http://docs.oracle.com/javase/7/docs/technotes/guides/extensions/versioning.html">
+Extension and ExtensionSet documentation</a> for further details</p>
+
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">property</td>
+ <td valign="top">The name of property to set if extensions is available.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">file</td>
+ <td valign="top">The file to check for extension</td>
+ <td valign="top" align="center">No, one of file, nested
+ ExtensionSet or nested fileset must be present.</td>
+ </tr>
+</table>
+<h3>Parameters specified as nested elements</h3>
+
+<h4>extension</h4>
+ <p><a href="../Types/extension.html">Extension</a> the extension
+ to search for.</p>
+
+<h4>fileset</h4>
+ <p><a href="../Types/fileset.html">FileSet</a>s are used to select
+sets of files to check for extension.</p>
+
+<h4>extensionSet</h4>
+ <p><a href="../Types/extensionset.html">ExtensionSet</a>s is the set
+ of extensions to search for extension in.</p>
+
+<h3>Examples</h3>
+<p><b>Search for extension in single file</b></p>
+<pre>
+ &lt;jarlib-available property=&quot;myext.present&quot; file=&quot;myfile.jar&quot;&gt;
+ &lt;extension
+ extensionName=&quot;org.apache.tools.ant&quot;
+ specificationVersion=&quot;1.4.9&quot;
+ specificationVendor=&quot;Apache Software Foundation&quot;/&gt;
+ &lt;/jarlib-available&gt;
+</pre>
+
+<p><b>Search for extension in single file referencing external Extension</b></p>
+<pre>
+ &lt;extension id=&quot;myext&quot;
+ extensionName=&quot;org.apache.tools.ant&quot;
+ specificationVersion=&quot;1.4.9&quot;
+ specificationVendor=&quot;Apache Software Foundation&quot;/&gt;
+
+ &lt;jarlib-available property=&quot;myext.present&quot; file=&quot;myfile.jar&quot;&gt;
+ &lt;extension refid=&quot;myext&quot;/&gt;
+ &lt;/jarlib-available&gt;
+</pre>
+<p><b>Search for extension in fileset</b></p>
+<pre>
+ &lt;extension id=&quot;myext&quot;
+ extensionName=&quot;org.apache.tools.ant&quot;
+ specificationVersion=&quot;1.4.9&quot;
+ specificationVendor=&quot;Apache Software Foundation&quot;/&gt;
+
+ &lt;jarlib-available property=&quot;myext.present&quot;&gt;
+ &lt;extension refid=&quot;myext&quot;/&gt;
+ &lt;fileset dir="lib"&gt;
+ &lt;include name="*.jar"/&gt;
+ &lt;/fileset&gt;
+ &lt;/jarlib-available&gt;
+</pre>
+<p><b>Search for extension in extensionSet</b></p>
+<pre>
+ &lt;extension id=&quot;myext&quot;
+ extensionName=&quot;org.apache.tools.ant&quot;
+ specificationVersion=&quot;1.4.9&quot;
+ specificationVendor=&quot;Apache Software Foundation&quot;/&gt;
+
+ &lt;jarlib-available property=&quot;myext.present&quot;&gt;
+ &lt;extension refid=&quot;myext&quot;/&gt;
+ &lt;extensionSet id=&quot;exts3&quot;&gt;
+ &lt;libfileset
+ includeUrl=&quot;false&quot;
+ includeImpl=&quot;true&quot;
+ dir=&quot;lib&quot;&gt;
+ &lt;include name=&quot;*.jar&quot;/&gt;
+ &lt;/libfileset&gt;
+ &lt;/extensionSet&gt;
+ &lt;/jarlib-available&gt;
+</pre>
+
+
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/jarlib-display.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/jarlib-display.html
new file mode 100644
index 00000000..0ddbaa34
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/jarlib-display.html
@@ -0,0 +1,80 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>jarlib-display Task</title>
+</head>
+
+<body>
+
+<h2><a name="jarlib-display">jarlib-display</a></h2>
+<h3>Description</h3>
+<p>Display the "Optional Package" and "Package Specification" information
+ contained within the specified jars.</p>
+
+<p>Note that this task
+works with extensions as defined by the "Optional Package" specification.
+ For more information about optional packages, see the document
+<em>Optional Package Versioning</em> in the documentation bundle for your
+Java Standard Edition package, in file
+<code>guide/extensions/versioning.html</code> or the online
+<a target="_blank" href="http://docs.oracle.com/javase/7/docs/technotes/guides/extensions/versioning.html">
+Extension and ExtensionSet documentation</a> for further details</p>
+
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">file</td>
+ <td valign="top">The file to display extension information about.</td>
+ <td valign="top" align="center">No, but one of file or fileset must be
+ present.</td>
+ </tr>
+</table>
+<h3>Parameters specified as nested elements</h3>
+
+<h4>fileset</h4>
+ <p><a href="../Types/fileset.html">FileSet</a>s contain list of files to
+ display Extension information about.</p>
+
+<h3>Examples</h3>
+<p><b>Display Extension info for a single file</b></p>
+<pre>
+ &lt;jarlib-display file=&quot;myfile.jar&quot;&gt;
+</pre>
+
+<p><b>Display Extension info for a fileset</b></p>
+<pre>
+ &lt;jarlib-display&gt;
+ &lt;fileset dir="lib"&gt;
+ &lt;include name="*.jar"/&gt;
+ &lt;/fileset&gt;
+ &lt;/jarlib-display&gt;
+</pre>
+
+
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/jarlib-manifest.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/jarlib-manifest.html
new file mode 100644
index 00000000..019b5545
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/jarlib-manifest.html
@@ -0,0 +1,123 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>jarlib-manifest Task</title>
+</head>
+
+<body>
+
+<h2><a name="jarlib-manifest">jarlib-manifest</a></h2>
+<h3>Description</h3>
+<p>Task to generate a manifest that declares all the dependencies
+ in manifest. The dependencies are determined by looking in the
+ specified path and searching for Extension / "Optional Package"
+ specifications in the manifests of the jars.</p>
+
+<p>Note that this task
+works with extensions as defined by the "Optional Package" specification.
+ For more information about optional packages, see the document
+<em>Optional Package Versioning</em> in the documentation bundle for your
+Java Standard Edition package, in file
+<code>guide/extensions/versioning.html</code> or the online
+<a target="_blank" href="http://docs.oracle.com/javase/7/docs/technotes/guides/extensions/versioning.html">
+Extension and ExtensionSet documentation</a> for further details</p>
+
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">destfile</td>
+ <td valign="top">The file to generate Manifest into</td>
+ <td valign="top" align="center">Yes.</td>
+ </tr>
+</table>
+<h3>Parameters specified as nested elements</h3>
+
+<h4>extension</h4>
+ <p><a href="../Types/extension.html">Extension</a> the extension
+ that this library implements.</p>
+
+<h4>depends</h4>
+ <p><a href="../Types/extensionset.html">ExtensionSet</a>s containing
+ all dependencies for jar.</p>
+
+<h4>options</h4>
+ <p><a href="../Types/extensionset.html">ExtensionSet</a>s containing
+ all optional dependencies for jar. (Optional dependencies will be used if
+ present else they will be ignored)</p>
+
+<h3>Examples</h3>
+<p><b>Basic Manifest generated for single Extension</b></p>
+<pre>
+&lt;extension id=&quot;e1&quot;
+ extensionName=&quot;MyExtensions&quot;
+ specificationVersion=&quot;1.0&quot;
+ specificationVendor=&quot;Peter Donald&quot;
+ implementationVendorID=&quot;vv&quot;
+ implementationVendor=&quot;Apache&quot;
+ implementationVersion=&quot;2.0&quot;
+ implementationURL=&quot;http://somewhere.com&quot;/&gt;
+
+&lt;jarlib-manifest destfile=&quot;myManifest.txt&quot;&gt;
+ &lt;extension refid=&quot;e1&quot;/&gt;
+&lt;/jarlib-manifest&gt;
+</pre>
+
+<p><b>Search for extension in fileset</b></p>
+<p><b>A large example with required and optional dependencies</b></p>
+<pre>
+&lt;extension id=&quot;e1&quot;
+ extensionName=&quot;MyExtensions&quot;
+ specificationVersion=&quot;1.0&quot;
+ specificationVendor=&quot;Peter Donald&quot;
+ implementationVendorID=&quot;vv&quot;
+ implementationVendor=&quot;Apache&quot;
+ implementationVersion=&quot;2.0&quot;
+ implementationURL=&quot;http://somewhere.com&quot;/&gt;
+
+&lt;extensionSet id=&quot;option.ext&quot;&gt;
+ &lt;libfileset dir=&quot;lib/option&quot;&gt;
+ &lt;include name=&quot;**/*.jar&quot;/&gt;
+ &lt;/libfileset&gt;
+&lt;/extensionSet&gt;
+
+&lt;extensionSet id=&quot;depends.ext&quot;&gt;
+ &lt;libfileset dir=&quot;lib/required&quot;&gt;
+ &lt;include name=&quot;*.jar&quot;/&gt;
+ &lt;/libfileset&gt;
+&lt;/extensionSet&gt;
+
+&lt;jarlib-manifest destfile=&quot;myManifest.txt&quot;&gt;
+ &lt;extension refid=&quot;e1&quot;/&gt;
+ &lt;depends refid=&quot;depends.ext&quot;/&gt;
+ &lt;options refid=&quot;option.ext&quot;/&gt;
+&lt;/jarlib-manifest&gt;
+</pre>
+
+
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/jarlib-resolve.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/jarlib-resolve.html
new file mode 100644
index 00000000..2ef4f87b
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/jarlib-resolve.html
@@ -0,0 +1,211 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>jarlib-resolve Task</title>
+</head>
+
+<body>
+
+<h2><a name="jarlib-resolve">jarlib-resolve</a></h2>
+<h3>Description</h3>
+<p>Try to locate a jar to satisfy an extension and place
+ location of jar into property. The task allows you to
+ add a number of resolvers that are capable of locating a
+ library for a specific extension. Each resolver will be attempted
+ in specified order until library is found or no resolvers are left.
+ If no resolvers are left and failOnError is true then a BuildException
+ will be thrown.</p>
+
+<p>Note that this task
+works with extensions as defined by the "Optional Package" specification.
+ For more information about optional packages, see the document
+<em>Optional Package Versioning</em> in the documentation bundle for your
+Java2 Standard Edition package, in file
+<code>guide/extensions/versioning.html</code> or the online
+<a target="_blank" href="http://docs.oracle.com/javase/7/docs/technotes/guides/extensions/versioning.html">
+Extension and ExtensionSet documentation</a> for further details</p>
+
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">property</td>
+ <td valign="top">The name of property to set to library location.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">failOnError</td>
+ <td valign="top">True if failure to locate library should result in build exception.</td>
+ <td valign="top" align="center">No, defaults to true.</td>
+ </tr>
+ <tr>
+ <td valign="top">checkExtension</td>
+ <td valign="top">True if libraries returned by nested resolvers should be checked to see if
+ they supply extension.</td>
+ <td valign="top" align="center">No, defaults to true.</td>
+ </tr>
+</table>
+<h3>Parameters specified as nested elements</h3>
+
+<h4>extension</h4>
+ <p><a href="../Types/extension.html">Extension</a> the extension
+ to resolve. Must be present</p>
+
+<h4>location</h4>
+ <p>The location sub element allows you to look for a library in a
+ location relative to project directory.</p>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">location</td>
+ <td valign="top">The pathname of library.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+</table>
+
+<h4>url</h4>
+ <p>The url resolver allows you to download a library from a URL to a
+ local file.</p>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">url</td>
+ <td valign="top">The URL to download.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">destfile</td>
+ <td valign="top">The file to download URL into.</td>
+ <td valign="top" align="center">No, But one of destfile or
+ destdir must be present</td>
+ </tr>
+ <tr>
+ <td valign="top">destdir</td>
+ <td valign="top">The directory in which to place downloaded file.</td>
+ <td valign="top" align="center">No, But one of destfile or
+ destdir must be present</td>
+ </tr>
+</table>
+
+<h4>ant</h4>
+ <p>The ant resolver allows you to run an Apache Ant build file to generate a library.</p>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">antfile</td>
+ <td valign="top">The build file.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">destfile</td>
+ <td valign="top">The file that the ant build creates.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">target</td>
+ <td valign="top">The target to run in build file.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+</table>
+
+<h3>Examples</h3>
+<p><b>Resolve Extension to file.</b> If file does not exist or file
+ does not implement extension then throw an exception.</p>
+<pre>
+ &lt;extension id=&quot;dve.ext&quot;
+ extensionName=&quot;org.realityforge.dve&quot;
+ specificationVersion=&quot;1.2&quot;
+ specificationVendor=&quot;Peter Donald&quot;/&gt;
+
+ &lt;jarlib-resolve property="dve.library"&gt;
+ &lt;extension refid="dve.ext"/&gt;
+ &lt;location location="/opt/jars/dve.jar"/&gt;
+ &lt;/jarlib-resolve&gt;
+</pre>
+
+<p><b>Resolve Extension to url.</b> If url does not exist or can not write
+ to destfile or files does not implement extension then throw an exception.</p>
+<pre>
+ &lt;extension id=&quot;dve.ext&quot;
+ extensionName=&quot;org.realityforge.dve&quot;
+ specificationVersion=&quot;1.2&quot;
+ specificationVendor=&quot;Peter Donald&quot;/&gt;
+
+ &lt;jarlib-resolve property="dve.library"&gt;
+ &lt;extension refid="dve.ext"/&gt;
+ &lt;url url="http://www.realityforge.net/jars/dve.jar" destfile="lib/dve.jar"/&gt;
+ &lt;/jarlib-resolve&gt;
+</pre>
+
+<p><b>Resolve Extension to file produce by ant build.</b> If file does not get produced
+ or ant file is missing or build fails then throw an exception (Note does not check
+ that library implements extension).</p>
+<pre>
+ &lt;extension id=&quot;dve.ext&quot;
+ extensionName=&quot;org.realityforge.dve&quot;
+ specificationVersion=&quot;1.2&quot;
+ specificationVendor=&quot;Peter Donald&quot;/&gt;
+
+ &lt;jarlib-resolve property="dve.library" checkExtension="false"&gt;
+ &lt;extension refid="dve.ext"/&gt;
+ &lt;ant antfile="../dve/build.xml" target="main" destfile="lib/dve.jar"/&gt;
+ &lt;/jarlib-resolve&gt;
+</pre>
+
+<p><b>Resolve Extension via multiple methods.</b> First check local file to see if it implements
+ extension. If it does not then try to build it from source in parallel directory. If that
+ fails then finally try to download it from a website. If all steps fail then throw a build
+ exception.</p>
+<pre>
+ &lt;extension id=&quot;dve.ext&quot;
+ extensionName=&quot;org.realityforge.dve&quot;
+ specificationVersion=&quot;1.2&quot;
+ specificationVendor=&quot;Peter Donald&quot;/&gt;
+
+ &lt;jarlib-resolve property="dve.library"&gt;
+ &lt;extension refid="dve.ext"/&gt;
+ &lt;location location="/opt/jars/dve.jar"/&gt;
+ &lt;ant antfile="../dve/build.xml" target="main" destfile="lib/dve.jar"/&gt;
+ &lt;url url="http://www.realityforge.net/jars/dve.jar" destfile="lib/dve.jar"/&gt;
+ &lt;/jarlib-resolve&gt;
+</pre>
+
+
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/java.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/java.html
new file mode 100644
index 00000000..a83b0aff
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/java.html
@@ -0,0 +1,405 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Java Task</title>
+</head>
+
+<body>
+
+<h2><a name="java">Java</a></h2>
+<h3>Description</h3>
+<p>Executes a Java class within the running (Apache Ant) VM or forks another VM if
+specified.</p>
+<p>
+If odd things go wrong when you run this task, set fork="true" to use a new
+JVM.
+
+<p>As of Ant 1.6.3, you can interact with a forked VM, as well as
+sending input to it via the <code>input</code> and <code>inputstring</code>
+attributes.</p>
+
+<h4><a name="background">Running Ant as a background process on
+ Unix(-like) systems</a></h4>
+
+<p>If you run Ant as a background process (like <code>ant &</code>)
+ and use the <code>&lt;java&gt;</code> task with <code>spawn</code>
+ set to <code>false</code> and <code>fork</code>
+ to <code>true</code>, you must provide explicit input to the forked
+ process or Ant will be suspended because it tries to read from the
+ standard input.</p>
+
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">classname</td>
+ <td valign="top">the Java class to execute.</td>
+ <td align="center" valign="top">Either <tt>jar</tt> or <tt>classname</tt></td>
+ </tr>
+ <tr>
+ <td valign="top">jar</td>
+ <td valign="top">the location of the jar file to execute (must have a
+ Main-Class entry in the manifest). Fork must be set to true if this option is selected.
+ See notes below for more details.
+ </td>
+ <td align="center" valign="top">Either <tt>jar</tt> or <tt>classname</tt></td>
+ </tr>
+ <tr>
+ <td valign="top">args</td>
+ <td valign="top">the arguments for the class that is
+ executed. <b>deprecated, use nested <code>&lt;arg&gt;</code>
+ elements instead.</b></td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">classpath</td>
+ <td valign="top">the classpath to use.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">classpathref</td>
+ <td valign="top">the classpath to use, given as <a
+ href="../using.html#references">reference</a> to a PATH defined elsewhere.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">fork</td>
+ <td valign="top">if enabled triggers the class execution in another VM
+ (disabled by default)</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">spawn</td>
+ <td valign="top">if enabled allows to start a process which will outlive ant.<br>
+ Requires fork=true, and not compatible
+ with timeout, input, output, error, result attributes.<br>
+ (disabled by default)</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">jvm</td>
+ <td valign="top">the command used to invoke the Java Virtual Machine,
+ default is 'java'. The command is resolved by java.lang.Runtime.exec().
+ Ignored if fork is disabled.
+ </td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">jvmargs</td>
+ <td valign="top">the arguments to pass to the forked VM (ignored
+ if fork is disabled). <b>deprecated, use nested
+ <code>&lt;jvmarg&gt;</code> elements instead.</b></td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">maxmemory</td>
+ <td valign="top">Max amount of memory to allocate to the forked VM
+ (ignored if fork is disabled)</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">failonerror</td>
+ <td valign="top">Stop the buildprocess if the command exits with a
+ returncode other than 0. Default is "false" (see <a href="#failonerror">note</a>)</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">resultproperty</td>
+ <td valign="top">The name of a property in which the return code of the
+ command should be stored. Only of interest if failonerror=false
+ and if fork=true.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">dir</td>
+ <td valign="top">The directory to invoke the VM in. (ignored if
+ fork is disabled)</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">output</td>
+ <td valign="top">Name of a file to which to write the output. If the error stream
+ is not also redirected to a file or property, it will appear in this output.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">error</td>
+ <td valign="top">The file to which the standard error of the command should be
+ redirected. </td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">logError</td>
+ <td valign="top">This attribute is used when you wish to see error output in Ant's
+ log and you are redirecting output to a file/property. The error
+ output will not be included in the output file/property. If you
+ redirect error with the &quot;error&quot; or &quot;errorProperty&quot;
+ attributes, this will have no effect.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">append</td>
+ <td valign="top">Whether output and error files should be appended to or overwritten.
+ Defaults to false.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">outputproperty</td>
+ <td valign="top">The name of a property in which the output of the
+ command should be stored. Unless the error stream is redirected to a separate
+ file or stream, this property will include the error output.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">errorproperty</td>
+ <td valign="top">The name of a property in which the standard error of the
+ command should be stored.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">input</td>
+ <td valign="top">A file from which the executed command's standard input
+ is taken. This attribute is mutually exclusive with the
+ inputstring attribute</td>
+ <td align="center" valign="top">No; default is to take standard input from console
+ (unless <code>spawn="true"</code>)</td>
+ </tr>
+ <tr>
+ <td valign="top">inputstring</td>
+ <td valign="top">A string which serves as the input stream for the
+ executed command. This attribute is mutually exclusive with the
+ input attribute.</td>
+ <td align="center" valign="top">No; default is to take standard input from console
+ (unless <code>spawn="true"</code>)</td>
+ </tr>
+ <tr>
+ <td valign="top">newenvironment</td>
+ <td valign="top">Do not propagate old environment when new
+ environment variables are specified. Default is &quot;false&quot;
+ (ignored if fork is disabled).</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">timeout</td>
+ <td valign="top">Stop the command if it doesn't finish within the
+ specified time (given in milliseconds). <strong>It is highly
+ recommended to use this feature only if fork is enabled.</strong></td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">clonevm</td>
+ <td valign="top">If set to true, then all system properties
+ and the bootclasspath of the forked Java Virtual Machine will be
+ the same as those of the Java VM running Ant. Default is
+ &quot;false&quot; (ignored if fork is disabled).
+ <em>since Ant 1.7</em></td>
+ <td align="center" valign="top">No</td>
+ </tr>
+</table>
+<h3>Parameters specified as nested elements</h3>
+<h4>arg and jvmarg</h4>
+<p>Use nested <code>&lt;arg&gt;</code> and <code>&lt;jvmarg&gt;</code>
+elements to specify arguments for the Java class and the forked VM respectively.
+See <a href="../using.html#arg">Command line arguments</a>.</p>
+<h4>sysproperty</h4>
+<p>Use nested <code>&lt;sysproperty&gt;</code>
+elements to specify system properties required by the class.
+These properties will be made available to the VM during the execution
+of the class (either ANT's VM or the forked VM). The attributes
+for this element are the same as for <a href="exec.html#env">environment
+variables</a>.</p>
+
+<h4>syspropertyset</h4>
+
+<p>You can specify a set of properties to be used as system properties
+with <a href="../Types/propertyset.html">syspropertyset</a>s.</p>
+
+<p><em>since Ant 1.6</em>.</p>
+
+<h4>classpath</h4>
+<p><code>Java</code>'s <i>classpath</i> attribute is a <a
+href="../using.html#path">PATH like structure</a> and can also be set via a nested
+<i>classpath</i> element.</p>
+
+<h4>bootclasspath</h4>
+
+<p>The location of bootstrap class files can be specified using this
+<a href="../using.html#path">PATH like structure</a> - will be ignored
+if <i>fork</i> is not <code>true</code> or the target VM doesn't
+support it (i.e. Java 1.1).</p>
+
+<p><em>since Ant 1.6</em>.</p>
+
+<h4>env</h4>
+<p>It is possible to specify environment variables to pass to the
+forked VM via nested <i>env</i> elements. See the description in the
+section about <a href="exec.html#env">exec</a></p>
+<p>Settings will be ignored if fork is disabled.</p>
+
+<h4>permissions</h4>
+<p>Security permissions can be revoked and granted during the execution of the
+class via a nested <i>permissions</i> element. For more information please
+see <a href="../Types/permissions.html">permissions</a></p>
+<p>When the permission RuntimePermission exitVM has not been granted (or has
+been revoked) the System.exit() call will be intercepted
+and treated like indicated in <i>failonerror</i>.</p>
+<p>Note:<br>
+If you do not specify permissions,
+a set of default permissions will be added to your Java invocation to make
+sure that the ant run will continue or terminated as indicated by
+<i>failonerror</i>. All permissions not granted per default will be
+checked by whatever security manager was already in place. exitVM will be
+disallowed.
+</p>
+<p>Settings will be ignored if fork is enabled.</p>
+
+<p><em>since Ant 1.6</em>.</p>
+
+<h4>assertions</h4>
+
+<p>You can control enablement of Java 1.4 assertions with an
+<a href="../Types/assertions.html"><tt>&lt;assertions&gt;</tt></a>
+subelement.</p>
+
+<p>Assertion statements are currently ignored in non-forked mode.</p>
+
+<p><em>since Ant 1.6.</em></p>
+
+<a name="redirector"><h4>redirector</h4></a>
+<i><b>Since Ant 1.6.2</b></i>
+<p>A nested <a href="../Types/redirector.html">I/O Redirector</a>
+can be specified. In general, the attributes of the redirector behave
+as the corresponding attributes available at the task level. The most
+notable peculiarity stems from the retention of the <code>&lt;java&gt;</code>
+attributes for backwards compatibility. Any file mapping is done
+using a <CODE>null</CODE> sourcefile; therefore not all
+<a href="../Types/mapper.html">Mapper</a> types will return
+results. When no results are returned, redirection specifications
+will fall back to the task level attributes. In practice this means that
+defaults can be specified for input, output, and error output files.
+</p>
+<a name="failonerror"><h3>Errors and return codes</h3></a>
+By default the return code of a <code>&lt;java&gt;</code> is ignored.
+Alternatively, you can set <code>resultproperty</code> to the name
+of a property and have it assigned to the result code (barring immutability,
+of course).
+When you set <code>failonerror="true"</code>, the only possible value for
+<code>resultproperty</code> is 0. Any non-zero response is treated as an
+error and would mean the build exits.
+<p> Similarly, if <code>failonerror="false"</code> and <code>fork="false"</code>
+, then <code>&lt;java&gt;</code> <b>must</b> return 0 otherwise the build will
+exit, as the class was run by the build JVM.</p>
+
+<h3>JAR file execution</h3>
+
+<p>The parameter of the <tt>jar</tt> attribute is of type <tt>File</tt>;
+that is, the parameter is resolved to an absolute file relative to the
+base directory of the project, <i>not</i> the directory in which the Java
+task is run. If you need to locate a JAR file relative to the directory
+the task will be run in, you need to explicitly create the full path
+to the JAR file.</p>
+<p>When using the <tt>jar</tt> attribute, all classpath settings are
+ignored according to <a href="http://docs.oracle.com/javase/7/docs/technotes/tools/windows/java.html">Oracle's
+specification</a>.
+
+
+<h3>Examples</h3>
+<pre>
+ &lt;java classname=&quot;test.Main&quot;&gt;
+ &lt;arg value=&quot;-h&quot;/&gt;
+ &lt;classpath&gt;
+ &lt;pathelement location=&quot;dist/test.jar&quot;/&gt;
+ &lt;pathelement path=&quot;${java.class.path}&quot;/&gt;
+ &lt;/classpath&gt;
+ &lt;/java&gt;
+</pre>
+Run a class in this JVM with a new jar on the classpath
+
+<pre>
+ &lt;java jar=&quot;dist/test.jar&quot;
+ fork="true"
+ failonerror="true"
+ maxmemory="128m"
+ &gt;
+ &lt;arg value=&quot;-h&quot;/&gt;
+ &lt;classpath&gt;
+ &lt;pathelement location=&quot;dist/test.jar&quot;/&gt;
+ &lt;pathelement path=&quot;${java.class.path}&quot;/&gt;
+ &lt;/classpath&gt;
+ &lt;/java&gt;
+</pre>
+Run the JAR test.jar in this project's dist/lib directory.
+using the manifest supplied entry point, forking (as required),
+and with a maximum memory of 128MB. Any non zero return code breaks the build.
+
+<pre>
+ &lt;java
+ dir="${exec.dir}"
+ jar=&quot;${exec.dir}/dist/test.jar&quot;
+ fork="true"
+ failonerror="true"
+ maxmemory="128m"
+ &gt;
+ &lt;arg value=&quot;-h&quot;/&gt;
+ &lt;classpath&gt;
+ &lt;pathelement location=&quot;dist/test.jar&quot;/&gt;
+ &lt;pathelement path=&quot;${java.class.path}&quot;/&gt;
+ &lt;/classpath&gt;
+ &lt;/java&gt;
+</pre>
+Run the JAR dist/test.jar relative to the directory
+<tt>${exec.dir}</tt>, this being the same directory into which the JVM
+is to start up.
+
+<pre> &lt;java classname=&quot;test.Main&quot;/&gt;</pre>
+Runs a given class with the current classpath.
+
+<pre>
+ &lt;java classname=&quot;test.Main&quot;
+ fork=&quot;yes&quot; &gt;
+ &lt;sysproperty key=&quot;DEBUG&quot; value=&quot;true&quot;/&gt;
+ &lt;arg value=&quot;-h&quot;/&gt;
+ &lt;jvmarg value=&quot;-Xrunhprof:cpu=samples,file=log.txt,depth=3&quot;/&gt;
+ &lt;/java&gt;
+</pre>
+Add system properties and JVM-properties to the JVM as in
+<code>java ="-Xrunhprof:cpu=samples,file=log.txt,depth=3 -DDEBUG=true test.Main</code>
+
+<pre> &lt;java classname=&quot;ShowJavaVersion&quot; classpath=&quot;.&quot;
+ jvm=&quot;path-to-java14-home/bin/java&quot; fork=&quot;true&quot;
+ taskname=&quot;java1.4&quot; &gt;
+</pre>
+Use a given Java implementation (another the one Ant is currently using) to run the class.
+For documentation in the log <code>taskname</code> is used to change the <code>[java]</code>
+log-prefix to <code>[java1.4]</code>.
+
+
+<p><strong>Note</strong>: you can not specify the (highly deprecated) MSJVM, "jview.exe" as the
+JVM, as it takes different parameters for other JVMs,
+That JVM can be started from <code>&lt;exec&gt;</code> if required.</p>
+
+
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/javac.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/javac.html
new file mode 100644
index 00000000..ce542463
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/javac.html
@@ -0,0 +1,860 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html lang="en-us">
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Javac Task</title>
+</head>
+
+<body>
+
+<h2><a name="javac">Javac</a></h2>
+<h3>Description</h3>
+<p>Compiles a Java source tree.</p>
+<p>The source and destination directory will be recursively scanned for Java
+source files to compile. Only Java files that have no corresponding
+<code>.class</code> file
+or where the class file is older than the
+<code>.java</code> file will be compiled.</p>
+<p>Note: Apache Ant uses only the names of the source and class files to find
+the classes that need a rebuild. It will not scan the source and therefore
+will have no knowledge about nested classes, classes that are named different
+from the source file, and so on. See the
+<a href="../Tasks/depend.html"><code>&lt;depend&gt;</code></a> task
+for dependency checking based on other than just
+existence/modification times.</p>
+<p>When the source files are part of a package, the directory structure of
+the source tree should follow the package
+hierarchy.</p>
+<p>It is possible to refine the set of files that are being compiled.
+This can be done with the <code>includes</code>, <code>includesfile</code>,
+<code>excludes</code>, and <code>excludesfile</code>
+attributes. With the <code>includes</code> or
+<code>includesfile</code> attribute, you specify the files you want to
+have included.
+The <code>exclude</code> or <code>excludesfile</code> attribute is used
+to specify
+the files you want to have excluded. In both cases, the list of files
+can be specified by either the filename, relative to the directory(s) specified
+in the <code>srcdir</code> attribute or nested <code>&lt;src&gt;</code>
+element(s), or by using wildcard patterns. See the section on
+<a href="../dirtasks.html#directorybasedtasks">directory-based tasks</a>,
+for information on how the
+inclusion/exclusion of files works, and how to write wildcard patterns.</p>
+<p>It is possible to use different compilers. This can be specified by
+either setting the global <code>build.compiler</code> property, which will
+affect all <code>&lt;javac&gt;</code> tasks throughout the build, by
+setting the <code>compiler</code> attribute, specific to the current
+<code>&lt;javac&gt;</code> task or by using a nested element of any
+<a href="typedef.html">typedef</a>fed or
+<a href="componentdef.html">componentdef</a>fed type that implements
+<code>org.apache.tools.ant.taskdefs.compilers.CompilerAdapter</code>.
+<a name="compilervalues">Valid values for either the
+<code>build.compiler</code> property or the <code>compiler</code>
+attribute are:</a></p>
+<ul>
+ <li><code>classic</code> (the standard compiler of JDK 1.1/1.2) &ndash;
+ <code>javac1.1</code> and
+ <code>javac1.2</code> can be used as aliases.</li>
+ <li><code>modern</code> (the standard compiler of JDK 1.3 and later) &ndash;
+ <code>javac1.3</code> and
+ <code>javac1.4</code> and
+ <code>javac1.5</code> and
+ <code>javac1.6</code> and
+ <code>javac1.7</code> (<em>since Ant 1.8.2</em>) and
+ <code>javac1.8</code> (<em>since Ant 1.8.3</em>) and</li>
+ <code>javac1.9</code> (<em>since Ant 1.9.5</em>) can be used as aliases.</li>
+ <li><code>jikes</code> (the <a
+ href="http://jikes.sourceforge.net/" target="_top">Jikes</a>
+ compiler).</li>
+ <li><code>jvc</code> (the Command-Line Compiler from Microsoft's SDK
+ for Java / Visual J++) &ndash; <code>microsoft</code> can be used
+ as an alias.</li>
+ <li><code>kjc</code> (the <a href="http://www.dms.at/kopi/" target="_top">kopi</a>
+ compiler).</li>
+ <li><code>gcj</code> (the gcj compiler from gcc).</li>
+ <li><code>sj</code> (Symantec java compiler) &ndash;
+ <code>symantec</code> can be used as an alias.</li>
+ <li><code>extJavac</code> (run either modern or classic in a JVM of
+ its own).</li>
+</ul>
+<p>The default is <code>javac1.x</code> with <code>x</code> depending
+on the JDK version you use while you are running Ant.
+If you wish to use a different compiler interface than those
+supplied, you can write a class that implements the CompilerAdapter interface
+(<code>package org.apache.tools.ant.taskdefs.compilers</code>). Supply the full
+classname in the <code>build.compiler</code> property or the
+<code>compiler</code> attribute.
+</p>
+<p>The fork attribute overrides the <code>build.compiler</code> property
+or <code>compiler</code> attribute setting and
+expects a JDK1.1 or higher to be set in <code>JAVA_HOME</code>.
+</p>
+<p>You can also use the <code>compiler</code> attribute to tell Ant
+which JDK version it shall assume when it puts together the command
+line switches - even if you set <code>fork=&quot;true&quot;</code>.
+This is useful if you want to run the compiler of JDK 1.1 while you
+current JDK is 1.2+. If you use
+<code>compiler=&quot;javac1.1&quot;</code> and (for example)
+<code>depend=&quot;true&quot;</code> Ant will use the command line
+switch <code>-depend</code> instead of <code>-Xdepend</code>.</p>
+<p>This task will drop all entries that point to non-existent
+files/directories from the classpath it passes to the compiler.</p>
+<p>The working directory for a forked executable (if any) is the
+ project's base directory.</p>
+<p><strong>Windows Note:</strong>When the modern compiler is used
+in unforked mode on Windows, it locks up the files present in the
+classpath of the <code>&lt;javac&gt;</code> task, and does not release them.
+The side effect of this is that you will not be able to delete or move
+those files later on in the build. The workaround is to fork when
+invoking the compiler.</p>
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">srcdir</td>
+ <td valign="top">Location of the java files. (See the
+ <a href="#srcdirnote">note</a> below.)</td>
+ <td align="center" valign="top">Yes, unless nested <code>&lt;src&gt;</code> elements are present.</td>
+ </tr>
+ <tr>
+ <td valign="top">destdir</td>
+ <td valign="top">Location to store the class files.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">includes</td>
+ <td valign="top">Comma- or space-separated list of files (may be specified using
+ wildcard patterns) that must be
+ included; all <code>.java</code> files are included when omitted.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">includesfile</td>
+ <td valign="top">The name of a file that contains a list of files to
+ include (may be specified using wildcard patterns).</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">excludes</td>
+ <td valign="top">Comma- or space-separated list of files (may be specified using
+ wildcard patterns) that must be excluded; no files (except default
+ excludes) are excluded when omitted.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">excludesfile</td>
+ <td valign="top">The name of a file that contains a list of files to
+ exclude (may be specified using wildcard patterns).</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">classpath</td>
+ <td valign="top">The classpath to use.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">sourcepath</td>
+ <td valign="top">The sourcepath to use; defaults to the value of the srcdir attribute (or nested <code>&lt;src&gt;</code> elements).
+ To suppress the sourcepath switch, use <code>sourcepath=&quot;&quot;</code>.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">bootclasspath</td>
+ <td valign="top">
+ Location of bootstrap class files. (See <a href="#bootstrap">below</a>
+ for using the -X and -J-X parameters for specifying
+ the bootstrap classpath).
+ </td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">classpathref</td>
+ <td valign="top">The classpath to use, given as a
+ <a href="../using.html#references">reference</a> to a path defined elsewhere.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">sourcepathref</td>
+ <td valign="top">The sourcepath to use, given as a
+ <a href="../using.html#references">reference</a> to a path defined elsewhere.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">bootclasspathref</td>
+ <td valign="top">Location of bootstrap class files, given as a
+ <a href="../using.html#references">reference</a> to a path defined elsewhere.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">extdirs</td>
+ <td valign="top">Location of installed extensions.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">encoding</td>
+ <td valign="top">Encoding of source files. (Note: gcj doesn't support
+ this option yet.)</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">nowarn</td>
+ <td valign="top">Indicates whether the <code>-nowarn</code> switch
+ should be passed to the compiler; defaults to <code>off</code>.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">debug</td>
+ <td valign="top">Indicates whether source should be compiled with
+ debug information; defaults to <code>off</code>. If set to
+ <code>off</code>, <code>-g:none</code> will be passed on the
+ command line for compilers that support it (for other compilers, no
+ command line argument will be used). If set to <code>true</code>,
+ the value of the <code>debuglevel</code> attribute determines the
+ command line argument.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">debuglevel</td>
+ <td valign="top">Keyword list to be appended to the <code>-g</code>
+ command-line switch. This will be ignored by all implementations except
+ <code>modern</code>, <code>classic(ver &gt;= 1.2)</code> and <code>jikes</code>.
+ Legal values are <code>none</code> or a comma-separated list of the
+ following keywords:
+ <code>lines</code>, <code>vars</code>, and <code>source</code>.
+ If <code>debuglevel</code> is not specified, by default,
+ nothing will be
+ appended to <code>-g</code>. If <code>debug</code> is not turned on,
+ this attribute will be ignored.
+ </td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">optimize</td>
+ <td valign="top">
+ Indicates whether source should be compiled with
+ optimization; defaults to <code>off</code>. <strong>Note</strong>
+ that this flag is just ignored by Sun's <code>javac</code> starting
+ with JDK 1.3 (since compile-time optimization is unnecessary).
+ </td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">deprecation</td>
+ <td valign="top">Indicates whether source should be compiled with
+ deprecation information; defaults to <code>off</code>.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">target</td>
+ <td valign="top">Generate class files for specific VM version
+ (e.g., <code>1.1</code> or <code>1.2</code>). <b>Note that the
+ default value depends on the JVM that is running Ant. In
+ particular, if you use JDK 1.4+ the generated classes will not be
+ usable for a 1.1 Java VM unless you explicitly set this attribute
+ to the value 1.1 (which is the default value for JDK 1.1 to
+ 1.3). We highly recommend to always specify this
+ attribute.</b><br>
+ A default value for this attribute can be provided using the magic
+ <a
+ href="../javacprops.html#target"><code>ant.build.javac.target</code></a>
+ property.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">verbose</td>
+ <td valign="top">Asks the compiler for verbose output; defaults to
+ <code>no</code>.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">depend</td> <td valign="top">Enables dependency-tracking
+ for compilers that support this (<code>jikes</code> and
+ <code>classic</code>).</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">includeAntRuntime</td>
+ <td valign="top">Whether to include the Ant run-time libraries in the
+ classpath; defaults to <code>yes</code>, unless
+ <a href="../sysclasspath.html"><code>build.sysclasspath</code></a> is set.
+ <em>It is usually best to set this to false</em> so the script's behavior is not
+ sensitive to the environment in which it is run.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">includeJavaRuntime</td>
+ <td valign="top">Whether to include the default run-time
+ libraries from the executing VM in the classpath;
+ defaults to <code>no</code>.<br/>
+ <b>Note:</b> In some setups the run-time libraries may be part
+ of the "Ant run-time libraries" so you may need to explicitly
+ set includeAntRuntime to false to ensure that the Java
+ run-time libraries are not included.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">fork</td>
+ <td valign="top">Whether to execute <code>javac</code> using the
+ JDK compiler externally; defaults to <code>no</code>.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">executable</td>
+ <td valign="top">Complete path to the <code>javac</code>
+ executable to use in case of <code>fork=&quot;yes&quot;</code>.
+ Defaults to the compiler of the Java version that is currently
+ running Ant. Ignored if <code>fork=&quot;no&quot;</code>.<br>
+ Since Ant 1.6 this attribute can also be used to specify the
+ path to the executable when using jikes, jvc, gcj or sj.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">memoryInitialSize</td>
+ <td valign="top">The initial size of the memory for the underlying VM,
+ if <code>javac</code> is run externally; ignored otherwise. Defaults
+ to the standard VM memory setting.
+ (Examples: <code>83886080</code>, <code>81920k</code>, or
+ <code>80m</code>)</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">memoryMaximumSize</td>
+ <td valign="top">The maximum size of the memory for the underlying VM,
+ if <code>javac</code> is run externally; ignored otherwise. Defaults
+ to the standard VM memory setting.
+ (Examples: <code>83886080</code>, <code>81920k</code>, or
+ <code>80m</code>)</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">failonerror</td>
+ <td valign="top">Indicates whether compilation errors
+ will fail the build; defaults to <code>true</code>.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">errorProperty</td>
+ <td valign="top">
+ The property to set (to the value "true") if compilation fails.
+ <em>Since Ant 1.7.1</em>.
+ </td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">source</td>
+
+ <td valign="top">Value of the <code>-source</code> command-line
+ switch; will be ignored by all implementations prior to
+ <code>javac1.4</code> (or <code>modern</code> when Ant is not
+ running in a 1.3 VM), <code>gcj</code> and <code>jikes</code>.<br>
+ If you use this attribute together with <code>gcj</code>
+ or <code>jikes</code>, you must make sure that your version
+ supports the <code>-source</code> (or <code>-fsource</code> for
+ gcj)
+ switch. By default, no <code>-source</code> argument will be used
+ at all.<br>
+ <b>Note that the default value depends on the JVM that is running
+ Ant. We highly recommend to always specify this
+ attribute.</b><br>
+ A default value for this attribute can be provided using the magic
+ <a
+ href="../javacprops.html#source"><code>ant.build.javac.source</code></a>
+ property.</td>
+
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">compiler</td>
+ <td valign="top">The compiler implementation to use.
+ If this attribute is not set, the value of the
+ <code>build.compiler</code> property, if set, will be used.
+ Otherwise, the default compiler for the current VM will be used.
+ (See the above <a href="#compilervalues">list</a> of valid
+ compilers.)</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">listfiles</td>
+ <td valign="top">Indicates whether the source files to be compiled will
+ be listed; defaults to <code>no</code>.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">tempdir</td>
+ <td valign="top">Where Ant should place temporary files.
+ This is only used if the task is forked and the
+ command line args length exceeds 4k.
+ <em>Since Ant 1.6</em>.</td>
+ <td align="center" valign="top">
+ No; default is <i>java.io.tmpdir</i>.
+ </td>
+ </tr>
+ <tr>
+ <td valign="top">updatedProperty</td>
+ <td valign="top">
+ The property to set (to the value "true")
+ if compilation has taken place
+ and has been successful.
+ <em>Since Ant 1.7.1</em>.
+ </td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">includeDestClasses</td>
+ <td valign="top">
+ This attribute controls whether to include the
+ destination classes directory in the classpath
+ given to the compiler.
+ The default value of this is "true" and this
+ means that previously compiled classes are on
+ the classpath for the compiler. This means that "greedy" compilers
+ will not recompile dependent classes that are already compiled.
+ In general this is a good thing as it stops the compiler
+ for doing unnecessary work. However, for some edge cases,
+ involving generics, the javac compiler
+ needs to compile the dependent classes to get the generics
+ information. One example is documented in the bug report:
+ <a href="http://issues.apache.org/bugzilla/show_bug.cgi?id=40776">
+ Bug 40776 - a problem compiling a Java 5 project with generics</a>.
+ Setting the attribute to "false" will cause the compiler
+ to recompile dependent classes.
+ <em>Since Ant 1.7.1</em>.
+ </td>
+ <td align="center" valign="top">No - default is "true"</td>
+ </tr>
+ <tr>
+ <td valign="top">createMissingPackageInfoClass</td>
+ <td valign="top">
+ Some package level annotations in <code>package-info.java</code>
+ files don't create any <code>package-info.class</code> files so
+ Ant would recompile the same file every time.<br/>
+ Starting with Ant 1.8 Ant will create an
+ empty <code>package-info.class</code> for
+ each <code>package-info.java</code> if there isn't one created
+ by the compiler.<br/>
+ In some setups this additional class causes problems and it can
+ be suppressed by setting this attribute to "false".
+ <em>Since Ant 1.8.3</em>.
+ </td>
+ <td align="center" valign="top">No - default is "true"</td>
+ </tr>
+</table>
+
+<h3>Parameters specified as nested elements</h3>
+<p>This task forms an implicit <a href="../Types/fileset.html">FileSet</a> and
+supports most attributes of <code>&lt;fileset&gt;</code>
+(<code>dir</code> becomes <code>srcdir</code>) as well as the nested
+<code>&lt;include&gt;</code>, <code>&lt;exclude&gt;</code> and
+<code>&lt;patternset&gt;</code> elements.</p>
+<h4><code>srcdir</code>, <code>classpath</code>, <code>sourcepath</code>,
+<code>bootclasspath</code> and <code>extdirs</code></h4>
+<p><code>&lt;javac&gt;</code>'s <code>srcdir</code>, <code>classpath</code>,
+<code>sourcepath</code>, <code>bootclasspath</code>, and
+<code>extdirs</code> attributes are
+<a href="../using.html#path">path-like structures</a>
+and can also be set via nested
+<code>&lt;src&gt;</code> (note the different name!),
+<code>&lt;classpath&gt;</code>,
+<code>&lt;sourcepath&gt;</code>,
+<code>&lt;bootclasspath&gt;</code> and
+<code>&lt;extdirs&gt;</code> elements, respectively.</p>
+
+<h4>compilerarg</h4>
+
+<p>You can specify additional command line arguments for the compiler
+with nested <code>&lt;compilerarg&gt;</code> elements. These elements
+are specified like <a href="../using.html#arg">Command-line
+Arguments</a> but have an additional attribute that can be used to
+enable arguments only if a given compiler implementation will be
+used.</p>
+<table border="1" cellpadding="2" cellspacing="0">
+<tr>
+ <td width="12%" valign="top"><b>Attribute</b></td>
+ <td width="78%" valign="top"><b>Description</b></td>
+ <td width="10%" valign="top"><b>Required</b></td>
+</tr>
+ <tr>
+ <td valign="top">value</td>
+ <td align="center" rowspan="4">See
+ <a href="../using.html#arg">Command-line Arguments</a>.</td>
+ <td align="center" rowspan="4">Exactly one of these.</td>
+ </tr>
+ <tr>
+ <td valign="top">line</td>
+ </tr>
+ <tr>
+ <td valign="top">file</td>
+ </tr>
+ <tr>
+ <td valign="top">path</td>
+ </tr>
+ <tr>
+ <td valign="top">prefix</td>
+ <td align="center" rowspan="2">See
+ <a href="../using.html#arg">Command-line Arguments</a>.
+ <em>Since Ant 1.8.</em></td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">suffix</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">compiler</td>
+ <td>Only pass the specified argument if the chosen
+ compiler implementation matches the value of this attribute.
+ Legal values are the
+ same as those in the above <a href="#compilervalues">list</a> of valid
+ compilers.)</td>
+ <td align="center">No</td>
+ </tr>
+</table>
+
+<h4>compilerclasspath <em>since Ant 1.8.0</em></h4>
+
+<p>A <a href="../using.html#path">PATH like structure</a> holding the
+ classpath to use when loading the compiler implementation if a
+ custom class has been specified. Doesn't have any effect when
+ using one of the built-in compilers.</p>
+
+<h4>Any nested element of a type that implements CompilerAdapter
+ <em>since Ant 1.8.0</em></h4>
+
+<p>If a defined type implements the <code>CompilerAdapter</code>
+ interface a nested element of that type can be used as an
+ alternative to the <code>compiler</code> attribute.</p>
+
+<h3>Examples</h3>
+<pre> &lt;javac srcdir=&quot;${src}&quot;
+ destdir=&quot;${build}&quot;
+ classpath=&quot;xyz.jar&quot;
+ debug=&quot;on&quot;
+ source=&quot;1.4&quot;
+ /&gt;</pre>
+<p>compiles all <code>.java</code> files under the <code>${src}</code>
+directory, and stores
+the <code>.class</code> files in the <code>${build}</code> directory.
+The classpath used includes <code>xyz.jar</code>, and compiling with
+debug information is on. The source level is 1.4,
+so you can use <code>assert</code> statements.</p>
+
+<pre> &lt;javac srcdir=&quot;${src}&quot;
+ destdir=&quot;${build}&quot;
+ fork=&quot;true&quot;
+ source=&quot;1.2&quot;
+ target=&quot;1.2&quot;
+ /&gt;</pre>
+<p>compiles all <code>.java</code> files under the <code>${src}</code>
+directory, and stores the <code>.class</code> files in the
+<code>${build}</code> directory. This will fork off the javac
+compiler using the default <code>javac</code> executable.
+The source level is 1.2 (similar to 1.1 or 1.3) and
+the class files should be runnable under JDK 1.2+ as well.</p>
+
+<pre> &lt;javac srcdir=&quot;${src}&quot;
+ destdir=&quot;${build}&quot;
+ fork=&quot;java$$javac.exe&quot;
+ source=&quot;1.5&quot;
+ /&gt;</pre>
+<p>compiles all <code>.java</code> files under the <code>${src}</code>
+directory, and stores the <code>.class</code> files in the
+<code>${build}</code> directory. This will fork off the javac
+compiler, using the executable named <code>java$javac.exe</code>. Note
+that the <code>$</code> sign needs to be escaped by a second one.
+The source level is 1.5, so you can use generics.</p>
+
+<pre> &lt;javac srcdir=&quot;${src}&quot;
+ destdir=&quot;${build}&quot;
+ includes=&quot;mypackage/p1/**,mypackage/p2/**&quot;
+ excludes=&quot;mypackage/p1/testpackage/**&quot;
+ classpath=&quot;xyz.jar&quot;
+ debug=&quot;on&quot;
+ /&gt;</pre>
+<p>compiles <code>.java</code> files under the <code>${src}</code>
+directory, and stores the
+<code>.class</code> files in the <code>${build}</code> directory.
+The classpath used includes <code>xyz.jar</code>, and debug information is on.
+Only files under <code>mypackage/p1</code> and <code>mypackage/p2</code> are
+used. All files in and below the <code>mypackage/p1/testpackage</code>
+directory are excluded from compilation.
+You didn't specify a source or target level,
+so the actual values used will depend on which JDK you ran Ant with.</p>
+
+<pre> &lt;javac srcdir=&quot;${src}:${src2}&quot;
+ destdir=&quot;${build}&quot;
+ includes=&quot;mypackage/p1/**,mypackage/p2/**&quot;
+ excludes=&quot;mypackage/p1/testpackage/**&quot;
+ classpath=&quot;xyz.jar&quot;
+ debug=&quot;on&quot;
+ /&gt;</pre>
+
+<p>is the same as the previous example, with the addition of a second
+source path, defined by
+the property <code>src2</code>. This can also be represented using nested
+<code>&lt;src&gt;</code> elements as follows:</p>
+
+<pre> &lt;javac destdir=&quot;${build}&quot;
+ classpath=&quot;xyz.jar&quot;
+ debug=&quot;on&quot;&gt;
+ &lt;src path=&quot;${src}&quot;/&gt;
+ &lt;src path=&quot;${src2}&quot;/&gt;
+ &lt;include name=&quot;mypackage/p1/**&quot;/&gt;
+ &lt;include name=&quot;mypackage/p2/**&quot;/&gt;
+ &lt;exclude name=&quot;mypackage/p1/testpackage/**&quot;/&gt;
+ &lt;/javac&gt;</pre>
+
+<p>If you want to run the javac compiler of a different JDK, you
+should tell Ant, where to find the compiler and which version of JDK
+you will be using so it can choose the correct command line switches.
+The following example executes a JDK 1.1 javac in a new process and
+uses the correct command line switches even when Ant is running in a
+Java VM of a different version:</p>
+
+<pre> &lt;javac srcdir=&quot;${src}&quot;
+ destdir=&quot;${build}&quot;
+ fork=&quot;yes&quot;
+ executable=&quot;/opt/java/jdk1.1/bin/javac&quot;
+ compiler=&quot;javac1.1&quot;
+ /&gt;</pre>
+
+<p><a name="srcdirnote"><b>Note:</b></a>
+If you wish to compile only source files located in certain packages below a
+common root, use the <code>include</code>/<code>exclude</code> attributes
+or <code>&lt;include&gt;</code>/<code>&lt;exclude&gt;</code> nested elements
+to filter for these packages. Do not include part of your package structure
+in the <code>srcdir</code> attribute
+(or nested <code>&lt;src&gt;</code> elements), or Ant will recompile your
+source files every time you run your compile target. See the
+<a href="http://ant.apache.org/faq.html#always-recompiles">Ant FAQ</a>
+for additional information.</p>
+
+<p>
+If you wish to compile only files explicitly specified and disable
+javac's default searching mechanism then you can unset the sourcepath
+attribute:
+<pre> &lt;javac sourcepath=&quot;&quot; srcdir=&quot;${src}&quot;
+ destdir=&quot;${build}&quot; &gt;
+ &lt;include name="**/*.java"/&gt;
+ &lt;exclude name="**/Example.java"/&gt;
+ &lt;/javac&gt;</pre>
+That way the javac will compile all java source files under &quot;${src}&quot;
+directory but skip the examples. The compiler will even produce errors if some of
+the non-example files refers to them.
+</p>
+
+<p>
+If you wish to compile with a special JDK (another than the one Ant is currently using),
+set the <code>executable</code> and <code>fork</code> attribute. Using <code>taskname</code>
+could show in the log, that these settings are fix.
+<pre> &lt;javac srcdir=&quot;&quot;
+ destdir=&quot;&quot;
+ executable=&quot;path-to-java14-home/bin/javac&quot;
+ fork=&quot;true&quot;
+ taskname=&quot;javac1.4&quot; /&gt;</pre>
+</p>
+
+
+<p><b>Note:</b> If you are using Ant on Windows and a new DOS window pops up
+for every use of an external compiler, this may be a problem of the JDK you are
+using. This problem may occur with all JDKs &lt; 1.2.</p>
+
+
+<p>
+If you want to activate other compiler options like <i>lint</i> you could use
+the <tt>&lt;compilerarg&gt;</tt> element:
+<pre> &lt;javac srcdir="${src.dir}"
+ destdir="${classes.dir}"
+ classpathref="libraries"&gt;
+ &lt;compilerarg value="-Xlint"/&gt;
+ &lt;/javac&gt; </pre>
+</p>
+
+<p>If you want to use a custom
+ CompilerAdapter <code>org.example.MyAdapter</code> you can either
+ use the compiler attribute:</p>
+<pre>
+&lt;javac srcdir="${src.dir}"
+ destdir="${classes.dir}"
+ compiler="org.example.MyAdapter"/&gt;
+</pre>
+<p>or a define a type and nest this into the task like in:</p>
+<pre>
+&lt;componentdef classname="org.example.MyAdapter"
+ name="myadapter"/&gt;
+&lt;javac srcdir="${src.dir}"
+ destdir="${classes.dir}"&gt;
+ &lt;myadapter/&gt;
+&lt;/javac&gt;
+</pre>
+<p>in which case your compiler adapter can support attributes and
+ nested elements of its own.</p>
+
+<h3>Jikes Notes</h3>
+
+<p>You need Jikes 1.15 or later.</p>
+
+<p>Jikes supports some extra options, which can be set be defining
+the properties shown below prior to invoking the task. The setting
+for each property will be in affect for all <code>&lt;javac&gt;</code>
+tasks throughout the build.
+The Ant developers are aware that
+this is ugly and inflexible &ndash; expect a better solution in the future.
+All the options are boolean, and must be set to <code>true</code> or
+<code>yes</code> to be
+interpreted as anything other than false. By default,
+<code>build.compiler.warnings</code> is <code>true</code>,
+while all others are <code>false</code>.</p>
+
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Property</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Default</b></td>
+ </tr>
+ <tr>
+ <td valign="top">
+ build.compiler.emacs
+ </td>
+ <td valign="top">
+ Enable emacs-compatible error messages.
+ </td>
+ <td valign="top">
+ <code>false</code>
+ </td>
+ </tr>
+ <tr>
+ <td valign="top">
+ build.compiler.fulldepend
+ </td>
+ <td valign="top">
+ Enable full dependency checking; see<br>
+ the <code>+F</code> switch in the Jikes manual.
+ </td>
+ <td valign="top">
+ <code>false</code>
+ </td>
+ </tr>
+ <tr>
+ <td valign="top">
+ build.compiler.pedantic
+ </td>
+ <td valign="top">
+ Enable pedantic warnings.
+ </td>
+ <td valign="top">
+ <code>false</code>
+ </td>
+ </tr>
+ <tr>
+ <td valign="top">
+ build.compiler.warnings<br>
+ <strong>Deprecated</strong>. Use
+ <code>&lt;javac&gt;</code>'s <code>nowarn</code>
+ attribute instead.
+ </td>
+ <td valign="top">
+ Don't disable warning messages.
+ </td>
+ <td valign="top">
+ <code>true</code>
+ </td>
+ </tr>
+</table>
+
+<h3>Jvc Notes</h3>
+
+<p>Jvc will enable Microsoft extensions unless you set the property
+<code>build.compiler.jvc.extensions</code> to false before invoking
+<code>&lt;javac&gt;</code>.</p>
+
+<h3><a name="bootstrap">Bootstrap Options</h3>
+<p>
+ The Sun javac compiler has a <em>bootclasspath</em> command
+ line option - this corresponds to the "bootclasspath" attribute/element
+ of the &lt;javac&gt; task. The Sun compiler also allows more
+ control over the boot classpath using the -X and -J-X attributes.
+ One can set these by using the &lt;compilerarg&gt;. Since Ant 1.6.0,
+ there is a shortcut to convert path references to strings that
+ can by used in an OS independent fashion (see
+ <a href="../using.html#pathshortcut">pathshortcut</a>). For example:
+</p>
+<pre>
+ &lt;path id="lib.path.ref"&gt;
+ &lt;fileset dir="lib" includes="*.jar"/&gt;
+ &lt;/path&gt;
+ &lt;javac srcdir="src" destdir="classes"&gt;
+ &lt;compilerarg arg="-Xbootclasspath/p:${toString:lib.path.ref}"/&gt;
+ &lt;/javac&gt;
+</pre>
+
+
+</p>
+
+<h3>OpenJDK Notes</h3>
+<p>
+ The <a href="https://openjdk.dev.java.net/">openjdk</a>
+ project has provided the javac
+ <a href="https://openjdk.dev.java.net/compiler/">compiler</a>
+ as an opensource project. The output of this project is a
+ <code>javac.jar</code> which contains the javac compiler.
+ This compiler may be used with the <code>&lt;javac&gt;</code> task with
+ the use of a <code>-Xbootclasspath/p</code> java argument. The argument needs
+ to be given to the runtime system of the javac executable, so it needs
+ to be prepended with a "-J". For example:
+
+<blockquote><pre>
+ &lt;property name="patched.javac.jar"
+ location="${my.patched.compiler}/dist/lib/javac.jar"/&gt;
+
+ &lt;presetdef name="patched.javac"&gt;
+ &lt;javac fork="yes"&gt;
+ &lt;compilerarg value="-J-Xbootclasspath/p:${patched.javac.jar}"/&gt;
+ &lt;/javac&gt;
+ &lt;/presetdef&gt;
+
+
+ &lt;patched.javac srcdir="src/java" destdir="build/classes"
+ debug="yes"/&gt;
+</pre></blockquote>
+
+ <h3>Note on package-info.java</h3>
+ <p>
+ <code>package-info.java</code> files were introduced in Java5 to
+ allow package level annotations. On compilation, if the java file
+ does not contain runtime annotations, there will be no .class file
+ for the java file. Up to <b>Ant 1.7.1</b>, when the &lt;javac&gt;
+ task is run again, the
+ task will try to compile the package-info java files again.
+ </p>
+ <p>With Ant 1.7.1 a different kind of logic was introduced that
+ involved the timestamp of the directory that would normally
+ contain the .class file. This logic turned out to lead to Ant not
+ recompiling <code>package-info.java</code> in certain setup.</p>
+ <p>Starting with Ant 1.8.0 Ant will create
+ "empty" <code>package-info.class</code> files if it compiles
+ a <code>package-info.java</code> and
+ no <code>package-info.class</code> file has been created by the
+ compiler itself.</p>
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/javacc.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/javacc.html
new file mode 100644
index 00000000..3c0dcfa8
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/javacc.html
@@ -0,0 +1,210 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>JavaCC Task</title>
+</head>
+
+<body>
+
+<h2><a name="javacc">JavaCC</a></h2>
+<h3>Description</h3>
+<p>
+ Invokes the <a HREF="http://javacc.dev.java.net/" target="_top">JavaCC</a> compiler
+ compiler on a grammar file.
+</p>
+<p>
+ To use the javacc task, set the <i>target</i> attribute to the name of the
+ grammar file to process. You also need to specify the directory containing
+ the JavaCC installation using the <i>javacchome</i> attribute, so that Apache Ant
+ can find the JavaCC classes. Optionally, you can also set the
+ <i>outputdirectory</i> to write the generated file to a specific directory.
+ Otherwise javacc writes the generated files to the directory containing
+ the grammar file.
+</p>
+<p>
+ This task only invokes JavaCC if the grammar file is newer than the generated
+ Java files. javacc assumes that the Java class name of the generated parser
+ is the same as the name of the grammar file, ignoring the .jj.
+ If this is not the case, the javacc task will still work, but it will always
+ generate the output files.
+</p>
+
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">target</td>
+ <td valign="top">The grammar file to process.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">javacchome</td>
+ <td valign="top">The directory containing the JavaCC distribution.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">outputdirectory</td>
+ <td valign="top">
+ The directory to write the generated files to. If not set, the files
+ are written to the directory containing the grammar file.
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">buildparser</td>
+ <td valign="top">Sets the BUILD_PARSER grammar option. This is a boolean option.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">buildtokenmanager</td>
+ <td valign="top">Sets the BUILD_TOKEN_MANAGER grammar option. This is a boolean option.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">cachetokens</td>
+ <td valign="top">Sets the CACHE_TOKENS grammar option. This is a boolean option.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">choiceambiguitycheck</td>
+ <td valign="top">Sets the CHOICE_AMBIGUITY_CHECK grammar option. This is an integer option.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">commontokenaction</td>
+ <td valign="top">Sets the COMMON_TOKEN_ACTION grammar option. This is a boolean option.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">debuglookahead</td>
+ <td valign="top">Sets the DEBUG_LOOKAHEAD grammar option. This is a boolean option.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">debugparser</td>
+ <td valign="top">Sets the DEBUG_PARSER grammar option. This is a boolean option.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">debugtokenmanager</td>
+ <td valign="top">Sets the DEBUG_TOKEN_MANAGER grammar option. This is a boolean option.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">errorreporting</td>
+ <td valign="top">Sets the ERROR_REPORTING grammar option. This is a boolean option.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">forcelacheck</td>
+ <td valign="top">Sets the FORCE_LA_CHECK grammar option. This is a boolean option.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">ignorecase</td>
+ <td valign="top">Sets the IGNORE_CASE grammar option. This is a boolean option.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">javaunicodeescape</td>
+ <td valign="top">Sets the JAVA_UNICODE_ESCAPE grammar option. This is a boolean option.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">jdkversion</td>
+ <td valign="top">Sets the JDK_VERSION option. This is a string option.</td>
+ <td valign="top" align="center">No</td>
+ </tr> <tr>
+ <td valign="top">keeplinecolumn</td>
+ <td valign="top">Sets the KEEP_LINE_COLUMN grammar option. This is a boolean option.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">lookahead</td>
+ <td valign="top">Sets the LOOKAHEAD grammar option. This is an integer option.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">optimizetokenmanager</td>
+ <td valign="top">Sets the OPTIMIZE_TOKEN_MANAGER grammar option. This is a boolean option.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">otherambiguitycheck</td>
+ <td valign="top">Sets the OTHER_AMBIGUITY_CHECK grammar option. This is an integer option.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">sanitycheck</td>
+ <td valign="top">Sets the SANITY_CHECK grammar option. This is a boolean option.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">static</td>
+ <td valign="top">Sets the STATIC grammar option. This is a boolean option.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">unicodeinput</td>
+ <td valign="top">Sets the UNICODE_INPUT grammar option. This is a boolean option.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">usercharstream</td>
+ <td valign="top">Sets the USER_CHAR_STREAM grammar option. This is a boolean option.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">usertokenmanager</td>
+ <td valign="top">Sets the USER_TOKEN_MANAGER grammar option. This is a boolean option.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">maxmemory</td>
+ <td valign="top">Max amount of memory to allocate to the forked
+ VM. <em>since Ant 1.8.3</em></td>
+ <td align="center" valign="top">No</td>
+ </tr>
+</table>
+<h3>Example</h3>
+<blockquote><pre>
+&lt;javacc
+ target=&quot;src/Parser.jj&quot;
+ outputdirectory=&quot;build/src&quot;
+ javacchome=&quot;c:/program files/JavaCC&quot;
+ static=&quot;true&quot;
+/&gt;
+</pre></blockquote>
+<p>
+ This invokes JavaCC on grammar file src/Parser.jj, writing the generated
+ files to build/src. The grammar option STATIC is set to true when
+ invoking JavaCC.
+</p>
+
+
+</body>
+</html>
+
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/javadoc.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/javadoc.html
new file mode 100644
index 00000000..430435ff
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/javadoc.html
@@ -0,0 +1,915 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Javadoc Task</title>
+</head>
+
+<body>
+
+<h2><a name="javadoc">Javadoc/<i>Javadoc2</i></a></h2>
+<h3>Description</h3>
+<p>Generates code documentation using the javadoc tool.</p>
+<p>The source directory will be recursively scanned for Java source files to process
+but only those matching the inclusion rules, and not matching the exclusions rules
+will be passed to the javadoc tool. This
+allows wildcards to be used to choose between package names, reducing verbosity
+and management costs over time. This task, however, has no notion of
+&quot;changed&quot; files, unlike the <a href="javac.html">javac</a> task. This means
+all packages will be processed each time this task is run. In general, however,
+this task is used much less frequently.</p>
+<p>NOTE: since javadoc calls System.exit(), javadoc cannot be run inside the
+same VM as Apache Ant without breaking functionality. For this reason, this task
+always forks the VM. This overhead is not significant since javadoc is normally a heavy
+application and will be called infrequently.</p>
+<p>NOTE: the packagelist attribute allows you to specify the list of packages to
+document outside of the Ant file. It's a much better practice to include everything
+inside the <code>build.xml</code> file. This option was added in order to make it easier to
+migrate from regular makefiles, where you would use this option of javadoc.
+The packages listed in packagelist are not checked, so the task performs even
+if some packages are missing or broken. Use this option if you wish to convert from
+an existing makefile. Once things are running you should then switch to the regular
+notation. </p>
+
+<p><i><b>DEPRECATION:</b> the javadoc2 task simply points to the javadoc task and it's
+there for back compatibility reasons. Since this task will be removed in future
+versions, you are strongly encouraged to use <a href="javadoc.html">javadoc</a>
+instead.</i></p>
+
+<p>In the table below, 1.2 means available if your current Java VM is
+a 1.2 VM (but not 1.3 or later), 1.4+ for any VM of at least version 1.4, otherwise
+any VM of at least version 1.2 is acceptable. JDKs &lt;1.4 are no longer supported.
+If you specify the <code>executable</code> attribute it is up to you
+to ensure that this command supports the attributes you wish to use.</p>
+
+<p><b>Note:</b><br>When generating the JavaDocs for classes which contains annotations
+you maybe get a <tt>java.lang.ClassCastException: com.sun.tools.javadoc.ClassDocImpl</tt>.
+This is due <a href="https://bugs.openjdk.java.net/browse/JDK-6442982" target="_blank">bug-6442982</a>. The cause is that JavaDoc cannot find the implementations of used annotations.
+The workaround is providing the jars with these implementations (like JAXBs <tt>@XmlType</tt>, ...)
+to &lt;javadoc&gt; using <tt>classpath</tt>, <tt>classpathref</tt> attributes or nested
+&lt;classpath&gt; element.</p>
+
+<p><b>Note:</b> many problems with running javadoc stem from command
+ lines that have become too long - even though the error message
+ doesn't give the slightest hint this may be the problem. If you
+ encounter problems with the task, try to set
+ the <code>useexternalfile</code> attribute to <code>true</code>
+ first.</p>
+
+<p>If you use multiple ways to specify where javadoc should be looking
+ for sources your result will be the union of all specified
+ documentations. If you, e.g., specify a sourcepath attribute and
+ also a nested packageset both pointing at the same directory your
+ excludepackagenames attribute won't have any effect unless it agrees
+ with the exclude patterns of the packageset (and vice versa).</p>
+
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Availability on Java</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">sourcepath</td>
+ <td valign="top">Specify where to find source files</td>
+ <td align="center" valign="top">all</td>
+ <td align="center" rowspan="3">At least one of the three or nested
+ <code>&lt;sourcepath&gt;</code>, <code>&lt;fileset&gt;</code> or
+ <code>&lt;packageset&gt;</code></td>
+ </tr>
+ <tr>
+ <td valign="top">sourcepathref</td>
+ <td valign="top">Specify where to find source files by <a
+ href="../using.html#references">reference</a> to a PATH defined elsewhere.</td>
+ <td align="center" valign="top">all</td>
+ </tr>
+ <tr>
+ <td valign="top">sourcefiles</td>
+ <td valign="top">Comma separated list of source files -- see also
+ the nested <code>source</code> element.</td>
+ <td align="center" valign="top">all</td>
+ </tr>
+ <tr>
+ <td valign="top">destdir</td>
+ <td valign="top">Destination directory for output files</td>
+ <td align="center" valign="top">all</td>
+ <td align="center" valign="top">Yes, unless a doclet has been specified.</td>
+ </tr>
+ <tr>
+ <td valign="top">maxmemory</td>
+ <td valign="top">Max amount of memory to allocate to the javadoc VM</td>
+ <td align="center" valign="top">all</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">packagenames</td>
+ <td valign="top">Comma separated list of package files (with terminating
+ wildcard) -- see also the nested <code>package</code> element.</td>
+ <td align="center" valign="top">all</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">packageList</td>
+ <td valign="top">The name of a file containing the packages to process</td>
+ <td align="center" valign="top">all</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">classpath</td>
+ <td valign="top">Specify where to find user class files</td>
+ <td align="center" valign="top">all</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">Bootclasspath</td>
+ <td valign="top">Override location of class files loaded by the bootstrap
+ class loader</td>
+ <td align="center" valign="top">all</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">classpathref</td>
+ <td valign="top">Specify where to find user class files by <a
+ href="../using.html#references">reference</a> to a PATH defined elsewhere.</td>
+ <td align="center" valign="top">all</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">bootclasspathref</td>
+ <td valign="top">Override location of class files loaded by the
+ bootstrap class loader by <a href="../using.html#references">reference</a> to a
+ PATH defined elsewhere.</td>
+ <td align="center" valign="top">all</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">Extdirs</td>
+ <td valign="top">Override location of installed extensions</td>
+ <td align="center" valign="top">all</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">Overview</td>
+ <td valign="top">Read overview documentation from HTML file</td>
+ <td align="center" valign="top">all</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">access</td>
+ <td valign="top">Access mode: one of <code>public</code>, <code>protected</code>,
+ <code>package</code>, or <code>private</code></td>
+ <td align="center" valign="top">all</td>
+ <td align="center" valign="top">No (default <code>protected</code>)</td>
+ </tr>
+ <tr>
+ <td valign="top">Public</td>
+ <td valign="top">Show only public classes and members</td>
+ <td align="center" valign="top">all</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">Protected</td>
+ <td valign="top">Show protected/public classes and members (default)</td>
+ <td align="center" valign="top">all</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">Package</td>
+ <td valign="top">Show package/protected/public classes and members</td>
+ <td align="center" valign="top">all</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">Private</td>
+ <td valign="top">Show all classes and members</td>
+ <td align="center" valign="top">all</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">Old</td>
+ <td valign="top">Generate output using JDK 1.1 emulating
+ doclet.<br>
+ <b>Note:</b> as of Ant 1.8.0 this attribute doesn't have any
+ effect since the javadoc of Java 1.4 (required by Ant 1.8.0)
+ doesn't support the -1.1 switch anymore.</td>
+ <td align="center" valign="top">1.2</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">Verbose</td>
+ <td valign="top">Output messages about what Javadoc is doing</td>
+ <td align="center" valign="top">all</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">Locale</td>
+ <td valign="top">Locale to be used, e.g. en_US or en_US_WIN</td>
+ <td align="center" valign="top">all</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">Encoding</td>
+ <td valign="top">Source file encoding name</td>
+ <td align="center" valign="top">all</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">Version</td>
+ <td valign="top">Include @version paragraphs</td>
+ <td align="center" valign="top">all</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">Use</td>
+ <td valign="top">Create class and package usage pages</td>
+ <td align="center" valign="top">all</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">Author</td>
+ <td valign="top">Include @author paragraphs</td>
+ <td align="center" valign="top">all</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">Splitindex</td>
+ <td valign="top">Split index into one file per letter</td>
+ <td align="center" valign="top">all</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">Windowtitle</td>
+ <td valign="top">Browser window title for the documentation (text)</td>
+ <td align="center" valign="top">all</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">Doctitle</td>
+ <td valign="top">Include title for the package index(first) page (html-code)</td>
+ <td align="center" valign="top">all</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">Header</td>
+ <td valign="top">Include header text for each page (html-code)</td>
+ <td align="center" valign="top">all</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">Footer</td>
+ <td valign="top">Include footer text for each page (html-code)</td>
+ <td align="center" valign="top">all</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">bottom</td>
+ <td valign="top">Include bottom text for each page (html-code)</td>
+ <td align="center" valign="top">all</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">link</td>
+ <td valign="top">Create links to javadoc output at the given URL
+ -- see also the nested <code>link</code> element.</td>
+ <td align="center" valign="top">all</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">linkoffline</td>
+ <td valign="top">Link to docs at <code>&lt;url&gt;</code> using package list at
+ <code>&lt;url2&gt;</code> - separate the URLs by using a space character -- see
+ also the nested <code>link</code> element.</td>
+ <td align="center" valign="top">all</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">group</td>
+ <td valign="top">Group specified packages together in overview
+ page. The format is as described <a
+ href="#groupattribute">below</a> -- see also the nested
+ <code>group</code> element.</td>
+ <td align="center" valign="top">all</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">nodeprecated</td>
+ <td valign="top">Do not include @deprecated information</td>
+ <td align="center" valign="top">all</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">nodeprecatedlist</td>
+ <td valign="top">Do not generate deprecated list</td>
+ <td align="center" valign="top">all</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">notree</td>
+ <td valign="top">Do not generate class hierarchy</td>
+ <td align="center" valign="top">all</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">noindex</td>
+ <td valign="top">Do not generate index</td>
+ <td align="center" valign="top">all</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">nohelp</td>
+ <td valign="top">Do not generate help link</td>
+ <td align="center" valign="top">all</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">nonavbar</td>
+ <td valign="top">Do not generate navigation bar</td>
+ <td align="center" valign="top">all</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">serialwarn</td>
+ <td valign="top">Generate warning about @serial tag</td>
+ <td align="center" valign="top">all</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">helpfile</td>
+ <td valign="top">Specifies the HTML help file to use</td>
+ <td align="center" valign="top">all</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">stylesheetfile</td>
+ <td valign="top">Specifies the CSS stylesheet to use</td>
+ <td align="center" valign="top">all</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">charset</td>
+ <td valign="top">Charset for cross-platform viewing of generated
+ documentation</td>
+ <td align="center" valign="top">all</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">docencoding</td>
+ <td valign="top">Output file encoding name</td>
+ <td align="center" valign="top">all</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">doclet</td>
+ <td valign="top">Specifies the class file that starts the doclet
+ used in generating the documentation -- see also the nested
+ <code>doclet</code> element.</td>
+ <td align="center" valign="top">all</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">docletpath</td>
+ <td valign="top">Specifies the path to the doclet class file that is specified with the -doclet option.</td>
+ <td align="center" valign="top">all</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">docletpathref</td>
+ <td valign="top">Specifies the path to the doclet class file that
+ is specified with the -doclet option by <a
+ href="../using.html#references">reference</a> to a PATH defined elsewhere.</td>
+ <td align="center" valign="top">all</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">additionalparam</td>
+ <td valign="top">Lets you add additional parameters to the javadoc
+ command line. Useful for doclets. Parameters containing spaces
+ need to be quoted using &amp;quot; -- see also the nested
+ <code>arg</code> element.</td>
+ <td align="center" valign="top">all</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">failonerror</td>
+ <td valign="top">Stop the buildprocess if the command exits with a
+ returncode other than 0.</td>
+ <td align="center" valign="top">all</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">failonwarning</td>
+ <td valign="top">Stop the buildprocess if a warning is emitted -
+ i.e. if javadoc's output contains the word "warning". <em>since
+ Ant 1.9.4</em></td>
+ <td align="center" valign="top">all</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">excludepackagenames</td>
+ <td valign="top">comma separated list of packages you don't want
+ docs for -- see also the nested <code>excludepackage</code> element.</td>
+ <td align="center" valign="top">all</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">defaultexcludes</td>
+ <td valign="top">indicates whether default excludes should be used
+ (<code>yes</code> | <code>no</code>); default excludes are used when omitted.</td>
+ <td align="center" valign="top">all</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">useexternalfile</td>
+ <td valign="top">indicates whether the sourcefile name specified
+ in srcfiles or as nested source elements should be written to a
+ temporary file to make the command line shorter. Also applies to
+ the package names specified via the packagenames attribute or
+ nested package elements. <em>Since Ant 1.7.0</em>, also applies
+ to all the other command line options.
+ (<code>yes</code> | <code>no</code>). Default is no.</td>
+ <td align="center" valign="top">all</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">source</td>
+ <td valign="top">Necessary to enable javadoc to handle assertions
+ present in J2SE v 1.4 source code. Set this to &quot;1.4&quot; to
+ documents code that compiles using <code>&quot;javac -source
+ 1.4&quot;</code>.<br>
+ A default value for this attribute can be provided using the magic
+ <a
+ href="../javacprops.html#source"><code>ant.build.javac.source</code></a>
+ property.</td>
+ <td align="center" valign="top">1.4+</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">linksource</td>
+ <td valign="top">Generate hyperlinks to source files.
+ <em>since Ant 1.6</em>.
+ (<code>yes</code> | <code>no</code>). Default is no.</td>
+ <td align="center" valign="top">1.4+</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">breakiterator</td>
+ <td valign="top">Use the new breakiterator algorithm.
+ <em>since Ant 1.6</em>.
+ (<code>yes</code> | <code>no</code>). Default is no.</td>
+ <td align="center" valign="top">1.4+</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">noqualifier</td>
+ <td valign="top">Enables the <code>-noqualifier</code> argument -
+ must be <code>all</code> or a colon separated list of packages.
+ <em>since Ant 1.6</em>.</td>
+ <td align="center" valign="top">1.4+</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">includenosourcepackages</td>
+ <td valign="top">If set to true, packages that don't contain Java
+ source but a package.html will get documented as well.
+ <em>since Ant 1.6.3</em>.</td>
+ <td align="center" valign="top">all</td>
+ <td align="center" valign="top">No (default is <code>false</code>)</td>
+ </tr>
+ <tr>
+ <td valign="top">executable</td>
+ <td valign="top">Specify a particular <code>javadoc</code> executable
+ to use in place of the default binary (found in the same JDK as Ant is running in).
+ <em>since Ant 1.6.3</em>.</td>
+ <td align="center" valign="top">all</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">docfilessubdirs</td>
+ <td valign="top">Enables deep-copying of <code>doc-files</code>
+ subdirectories. Defaults to false. <em>since Ant 1.8.0</em>.</td>
+ <td align="center" valign="top">1.4</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">excludedocfilessubdir</td>
+ <td valign="top">Colon-separated list of <code>doc-files</code>'
+ subdirectories to exclude if <code>docfilessubdirs</code> is
+ true. <em>since Ant 1.8.0</em>.</td>
+ <td align="center" valign="top">1.4</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">postProcessGeneratedJavadocs</td>
+ <td valign="top">Whether to post-process the generated javadocs in
+ order to mitigate CVE-2013-1571. Defaults to true. <em>Since Ant
+ 1.9.2</em><br>
+ There is a frame injection attack possible in javadocs generated by Oracle
+ JDKs prior to Java7 Update 25 (<a href="http://www.oracle.com/technetwork/java/javase/7u25-relnotes-1955741.html#jpi-upt" target="_blank">details</a>).
+ When this flag is set to true, Ant will check whether the docs are vulnerable
+ and will try to fix them.
+ </td>
+ <td align="center" valign="top">1.4</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+</table>
+
+<h4><a name="groupattribute">Format of the group attribute</a></h4>
+<p>The arguments are comma-delimited. Each single argument is 2
+space-delimited strings, where the first one is the group's title and
+the second one a colon delimited list of packages.</p>
+<p>If you need to specify more than one group, or a group whose title
+contains a comma or a space character, using <a
+href="#groupelement">nested group elements</a> is highly
+recommended.</p>
+<p>E.g.:</p>
+<pre> group=&quot;XSLT_Packages org.apache.xalan.xslt*,XPath_Packages org.apache.xalan.xpath*&quot;</pre>
+
+<h3>Parameters specified as nested elements</h3>
+
+<h4>packageset</h4>
+
+<p>A <a href="../Types/dirset.html">DirSet</a>. All matched
+directories that contain Java source files will be passed to javadoc
+as package names. Package names are created from the directory names
+by translating the directory separator into dots. Ant assumes the
+base directory of the packageset points to the root of a package
+hierarchy.</p>
+
+<p>The <code>packagenames</code>, <code>excludepackagenames</code> and
+<code>defaultexcludes</code> attributes of the task have no effect on
+the nested <code>&lt;packageset&gt;</code> elements.</p>
+
+<h4>fileset</h4>
+
+<p>A <a href="../Types/fileset.html">FileSet</a>. All matched
+files will be passed to javadoc as source files. Ant will
+automatically add the include pattern <code>**/*.java</code> (and
+<code>**/package.html</code> if includenosourcepackages is true) to
+these filesets.</p>
+
+<p>Nested filesets can be used to document sources that are in the
+default package or if you want to exclude certain files from
+documentation. If you want to document all source files and don't use
+the default package, packagesets should be used instead as this
+increases javadocs performance.</p>
+
+<p>The <code>packagenames</code>, <code>excludepackagenames</code> and
+<code>defaultexcludes</code> attributes of the task have no effect on
+the nested <code>&lt;fileset&gt;</code> elements.</p>
+
+<h4>sourcefiles</h4>
+
+<p>A container for arbitrary file system based <a
+href="../Types/resources.html#collection">resource
+collections</a>. All files contained in any of the nested collections
+(this includes nested filesets, filelists or paths) will be passed to
+javadoc as source files.</p>
+
+<h4>package</h4>
+<p>Same as one entry in the list given by <code>packagenames</code>.</p>
+
+<h5>Parameters</h5>
+<table width="90%" border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">name</td>
+ <td valign="top">The package name (may be a wildcard)</td>
+ <td align="center" valign="top">Yes</td>
+ </tr>
+</table>
+
+<h4>excludepackage</h4>
+<p>Same as one entry in the list given by <code>excludepackagenames</code>.</p>
+
+<h5>Parameters</h5>
+Same as for <code>package</code>.
+
+<h4>source</h4>
+<p>Same as one entry in the list given by <code>sourcefiles</code>.</p>
+
+<h5>Parameters</h5>
+<table width="90%" border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">file</td>
+ <td valign="top">The source file to document</td>
+ <td align="center" valign="top">Yes</td>
+ </tr>
+</table>
+
+<h4>doctitle</h4>
+
+<p>Same as the <code>doctitle</code> attribute, but you can nest text
+inside the element this way.</p>
+
+<p>If the nested text contains line breaks, you must use the
+ useexternalfile attribute and set it to true.</p>
+
+<h4>header</h4>
+
+<p>Similar to <code>&lt;doctitle&gt;</code>.</p>
+
+<h4>footer</h4>
+
+<p>Similar to <code>&lt;doctitle&gt;</code>.</p>
+
+<h4>bottom</h4>
+
+<p>Similar to <code>&lt;doctitle&gt;</code>.</p>
+
+<h4>link</h4>
+<p>Create link to javadoc output at the given URL. This performs the
+same role as the link and linkoffline attributes. You can use either
+syntax (or both at once), but with the nested elements you can easily
+specify multiple occurrences of the arguments.</p>
+
+<h5>Parameters</h5>
+<table width="90%" border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">href</td>
+ <td valign="top">The URL for the external documentation you wish
+ to link to. This can be an absolute URL, or a relative file
+ name.</td>
+ <td align="center" valign="top">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">offline</td>
+ <td valign="top">True if this link is not available online at the time of
+ generating the documentation</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">packagelistLoc</td>
+ <td valign="top">The location to the directory containing the package-list file for
+ the external documentation</td>
+ <td align="center" valign="top" rowspan="2">One of the two if the offline attribute is true</td>
+ </tr>
+ <tr>
+ <td valign="top">packagelistURL</td>
+ <td valign="top">The URL of the the directory containing the package-list file for
+ the external documentation</td>
+ </tr>
+ <tr>
+ <td valign="top">resolveLink</td>
+ <td valign="top">If the link attribute is a relative file name,
+ Ant will first try to locate the file relative to the current
+ project's basedir and if it finds a file there use an absolute URL
+ for the link attribute, otherwise it will pass the file name
+ verbatim to the javadoc command.</td>
+ <td align="center" valign="top">No, default is false.</td>
+ </tr>
+</table>
+
+<h4><a name="groupelement">group</a></h4>
+<p>Separates packages on the overview page into whatever groups you
+specify, one group per table. This performs the same role as the group
+attribute. You can use either syntax (or both at once), but with the
+nested elements you can easily specify multiple occurrences of the
+arguments.</p>
+
+<h5>Parameters</h5>
+<table width="90%" border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">title</td>
+ <td valign="top">Title of the group</td>
+ <td align="center" valign="top">Yes, unless nested <code>&lt;title&gt;</code> given</td>
+ </tr>
+ <tr>
+ <td valign="top">packages</td>
+ <td valign="top">List of packages to include in that group. Multiple packages are separated with ':'.</td>
+ <td align="center" valign="top">Yes, unless nested <code>&lt;package&gt;</code>s given</td>
+ </tr>
+</table>
+
+<p>The title may be specified as a nested <code>&lt;title&gt;</code> element
+with text contents, and the packages may be listed with nested
+<code>&lt;package&gt;</code> elements as for the main task.</p>
+
+<h4>doclet</h4>
+<p>The doclet nested element is used to specify the
+<a href="http://docs.oracle.com/javase/7/docs/technotes/guides/javadoc/doclet/overview.html">doclet</a>
+that javadoc will use to process the input source files. A number of the standard javadoc arguments
+are actually arguments of the standard doclet. If these are specified in the javadoc
+task's attributes, they will be passed to the doclet specified in the
+<code>&lt;doclet&gt;</code> nested element. Such attributes should only be specified,
+therefore, if they can be interpreted by the doclet in use.</p>
+
+<p>If the doclet requires additional parameters, these can be specified with
+<code>&lt;param&gt;</code> elements within the <code>&lt;doclet&gt;</code>
+element. These parameters are restricted to simple strings. An example usage
+of the doclet element is shown below:</p>
+
+<pre> &lt;javadoc ... &gt;
+ &lt;doclet name=&quot;theDoclet&quot;
+ path=&quot;path/to/theDoclet&quot;&gt;
+ &lt;param name=&quot;-foo&quot; value=&quot;foovalue&quot;/&gt;
+ &lt;param name=&quot;-bar&quot; value=&quot;barvalue&quot;/&gt;
+ &lt;/doclet&gt;
+ &lt;/javadoc&gt;
+</pre>
+
+<h4><a name="tagelement">tag</a></h4>
+
+<p>If you want to specify a standard tag using a nested tag element
+because you want to determine the order the tags are output, you must
+not set the description attribute for those tags.</p>
+
+<h5>Parameters</h5>
+<table width="90%" border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">name</td>
+ <td valign="top">Name of the tag (e.g. <code>todo</code>)</td>
+ <td align="center" valign="top">Yes, unless the <code>dir</code> attribute is specified.</td>
+ </tr>
+ <tr>
+ <td valign="top">description</td>
+ <td valign="top">Description for tag (e.g. <code>To do:</code>)</td>
+ <td align="center" valign="top">
+ No, the javadoc executable will pick a default if this is not specified.
+ </td>
+ </tr>
+ <tr>
+ <td valign="top">enabled</td>
+ <td valign="top">Whether or not the tag is enabled (defaults to <code>true</code>)</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">scope</td>
+ <td valign="top">Scope for the tag - the elements in which it can be used. This
+ is a comma separated list of some of the elements: <code>overview</code>,
+ <code>packages</code>, <code>types</code>, <code>constructors</code>,
+ <code>methods</code>, <code>fields</code> or the default, <code>all</code>.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">dir</td>
+ <td valign="top">If this attribute is specified, this element will behave as an implicit
+ <a href="../Types/fileset.html">fileset</a>. The files included by this fileset should
+ contain each tag definition on a separate line, as described in the
+ <a href="http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#javadoctags">Javadoc reference guide</a>:
+ <pre>ejb.bean:t:XDoclet EJB Tag
+todo:a:To Do</pre>
+ <b>Note:</b> The Javadoc reference quide has double quotes around
+the description part of the definition. This will not work when used in
+a file, as the definition is quoted again when given to
+the javadoc program.
+ <br/>
+ <b>Note:</b> If this attribute is specified, all the other attributes in this
+ element will be ignored.
+ </td>
+ <td align="center" valign="top">No</td>
+ </tr>
+</table>
+
+<h4><a name="tagletelement">taglet</a></h4>
+<p>The taglet nested element is used to specify custom
+ <a href="http://docs.oracle.com/javase/7/docs/technotes/guides/javadoc/taglet/overview.html">taglets</a> beyond <a href="http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#javadoctags" target="_blank">the default taglets</a>.</p>
+
+<h5>Parameters</h5>
+<table width="90%" border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">name</td>
+ <td valign="top">The name of the taglet class
+ (e.g. <a href="http://docs.oracle.com/javase/7/docs/technotes/guides/javadoc/taglet/ToDoTaglet.java">
+ <code>com.sun.tools.doclets.ToDoTaglet</code></a>)</td>
+ <td align="center" valign="top">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">path</td>
+ <td valign="top">A path specifying the search path for the taglet class
+ (e.g. <code>/home/taglets</code>).
+ The path may also be specified by a nested <code>&lt;path&gt;</code> element</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+</table>
+
+<h4>sourcepath, classpath and bootclasspath</h4>
+<p><code>Javadoc</code>'s <i>sourcepath</i>, <i>classpath</i> and
+<i>bootclasspath</i> attributes are <a href="../using.html#path">PATH like
+structure</a> and can also be set via nested <i>sourcepath</i>,
+<i>classpath</i> and <i>bootclasspath</i> elements
+respectively.</p>
+
+<h4>arg</h4>
+
+<p>Use nested <code>&lt;arg&gt;</code> to specify additional
+arguments. See <a href="../using.html#arg">Command line
+arguments</a>. <em>Since Ant 1.6</em></p>
+
+<h3>Example</h3>
+<pre> &lt;javadoc packagenames=&quot;com.dummy.test.*&quot;
+ sourcepath=&quot;src&quot;
+ excludepackagenames=&quot;com.dummy.test.doc-files.*&quot;
+ defaultexcludes=&quot;yes&quot;
+ destdir=&quot;docs/api&quot;
+ author=&quot;true&quot;
+ version=&quot;true&quot;
+ use=&quot;true&quot;
+ windowtitle=&quot;Test API&quot;&gt;
+ &lt;doctitle&gt;&lt;![CDATA[&lt;h1&gt;Test&lt;/h1&gt;]]&gt;&lt;/doctitle&gt;
+ &lt;bottom&gt;&lt;![CDATA[&lt;i&gt;Copyright &amp;#169; 2000 Dummy Corp. All Rights Reserved.&lt;/i&gt;]]&gt;&lt;/bottom&gt;
+ &lt;tag name=&quot;todo&quot; scope=&quot;all&quot; description=&quot;To do:&quot;/&gt;
+ &lt;group title=&quot;Group 1 Packages&quot; packages=&quot;com.dummy.test.a*&quot;/&gt;
+ &lt;group title=&quot;Group 2 Packages&quot; packages=&quot;com.dummy.test.b*:com.dummy.test.c*&quot;/&gt;
+ &lt;link offline=&quot;true&quot; href=&quot;http://docs.oracle.com/javase/7/docs/api/&quot; packagelistLoc=&quot;C:\tmp&quot;/&gt;
+ &lt;link href=&quot;http://docs.oracle.com/javase/7/docs/api/&quot;/&gt;
+ &lt/javadoc&gt;</pre>
+
+<p>is the same as</p>
+
+<pre> &lt;javadoc
+ destdir=&quot;docs/api&quot;
+ author=&quot;true&quot;
+ version=&quot;true&quot;
+ use=&quot;true&quot;
+ windowtitle=&quot;Test API&quot;&gt;
+
+ &lt;packageset dir=&quot;src&quot; defaultexcludes=&quot;yes&quot;&gt;
+ &lt;include name=&quot;com/dummy/test/**&quot;/&gt;
+ &lt;exclude name=&quot;com/dummy/test/doc-files/**&quot;/&gt;
+ &lt;/packageset&gt;
+
+ &lt;doctitle&gt;&lt;![CDATA[&lt;h1&gt;Test&lt;/h1&gt;]]&gt;&lt;/doctitle&gt;
+ &lt;bottom&gt;&lt;![CDATA[&lt;i&gt;Copyright &amp;#169; 2000 Dummy Corp. All Rights Reserved.&lt;/i&gt;]]&gt;&lt;/bottom&gt;
+ &lt;tag name=&quot;todo&quot; scope=&quot;all&quot; description=&quot;To do:&quot;/&gt;
+ &lt;group title=&quot;Group 1 Packages&quot; packages=&quot;com.dummy.test.a*&quot;/&gt;
+ &lt;group title=&quot;Group 2 Packages&quot; packages=&quot;com.dummy.test.b*:com.dummy.test.c*&quot;/&gt;
+ &lt;link offline=&quot;true&quot; href=&quot;http://docs.oracle.com/javase/7/docs/api/&quot; packagelistLoc=&quot;C:\tmp&quot;/&gt;
+ &lt;link href=&quot;http://docs.oracle.com/javase/7/docs/api/&quot;/&gt;
+ &lt/javadoc&gt;</pre>
+
+<p>or</p>
+
+<pre> &lt;javadoc
+ destdir=&quot;docs/api&quot;
+ author=&quot;true&quot;
+ version=&quot;true&quot;
+ use=&quot;true&quot;
+ windowtitle=&quot;Test API&quot;&gt;
+
+ &lt;fileset dir=&quot;src&quot; defaultexcludes=&quot;yes&quot;&gt;
+ &lt;include name=&quot;com/dummy/test/**&quot;/&gt;
+ &lt;exclude name=&quot;com/dummy/test/doc-files/**&quot;/&gt;
+ &lt;/fileset&gt;
+
+ &lt;doctitle&gt;&lt;![CDATA[&lt;h1&gt;Test&lt;/h1&gt;]]&gt;&lt;/doctitle&gt;
+ &lt;bottom&gt;&lt;![CDATA[&lt;i&gt;Copyright &amp;#169; 2000 Dummy Corp. All Rights Reserved.&lt;/i&gt;]]&gt;&lt;/bottom&gt;
+ &lt;tag name=&quot;todo&quot; scope=&quot;all&quot; description=&quot;To do:&quot;/&gt;
+ &lt;group title=&quot;Group 1 Packages&quot; packages=&quot;com.dummy.test.a*&quot;/&gt;
+ &lt;group title=&quot;Group 2 Packages&quot; packages=&quot;com.dummy.test.b*:com.dummy.test.c*&quot;/&gt;
+ &lt;link offline=&quot;true&quot; href=&quot;http://docs.oracle.com/javase/7/docs/api/&quot; packagelistLoc=&quot;C:\tmp&quot;/&gt;
+ &lt;link href=&quot;http://docs.oracle.com/javase/7/docs/api/&quot;/&gt;
+ &lt/javadoc&gt;</pre>
+
+
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/javah.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/javah.html
new file mode 100644
index 00000000..34a7b875
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/javah.html
@@ -0,0 +1,243 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Javah Task</title>
+</head>
+
+<body>
+
+<h2><a name="javah">Javah</a></h2>
+<h3>Description</h3>
+<p>Generates JNI headers from a Java class.</p>
+<p> When this task executes, it will generate the C header and source files that
+are needed to implement native methods. JNI operates differently depending on
+whether <a href="http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javah.html">JDK1.2+</a>
+or <a href="http://java.sun.com/products/jdk/1.1/docs/tooldocs/win32/javah.html">pre-JDK1.2</a>
+systems are used.</p>
+
+<p>It is possible to use different compilers. This can be selected
+with the <code>implementation</code> attribute or a nested element. <a
+name="implementationvalues">Here are the choices of the attribute</a>:</p>
+<ul>
+ <li>default - the default compiler (kaffeh or sun) for the platform.</li>
+ <li>sun (the standard compiler of the JDK)</li>
+ <li>kaffeh (the native standard compiler of <a href="http://www.kaffe.org" target="_top">Kaffe</a>)</li>
+ <li>gcjh (the native standard compiler
+ of <a href="http://gcc.gnu.org/java/"
+ target="_top">gcj and gij</a>) <em>since Apache Ant 1.8.2</em></li>
+</ul>
+
+<p><b>Note:</b> if you are using this task to work on multiple files
+ the command line may become too long on some operating systems.
+ Unfortunately the javah command doesn't support command argument
+ files the way javac (for example) does, so all that can be done is
+ breaking the amount of classes to compile into smaller chunks.</p>
+
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td valign="top" align="center"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">class</td>
+ <td valign="top">the fully-qualified name of the class (or classes,
+ separated by commas)</td>
+ <td align="center" valign="top">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">outputFile</td>
+ <td valign="top">concatenates the resulting header or source files for all the classes listed into this file</td>
+ <td align="center" valign="middle" rowspan="2">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">destdir</td>
+ <td valign="top">sets the directory where javah saves the header files or the
+ stub files.</td>
+ </tr>
+ <tr>
+ <td valign="top">force</td>
+ <td valign="top">specifies that output files should always be written (JDK1.2 only)</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">old</td>
+ <td valign="top">specifies that old JDK1.0-style header files should be generated
+ (otherwise output file contain JNI-style native method function prototypes) (JDK1.2 only)</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">stubs</td>
+ <td valign="top">generate C declarations from the Java object file (used with old)</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">verbose</td>
+ <td valign="top">causes Javah to print a message concerning the status of the generated files</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">classpath</td>
+ <td valign="top">the classpath to use.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">bootclasspath</td>
+ <td valign="top">location of bootstrap class files.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">extdirs</td>
+ <td valign="top"> location of installed extensions.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">implementation</td>
+ <td valign="top">The compiler implementation to use. If this
+ attribute is not set, the default compiler for the current VM
+ will be used. (See the above <a
+ href="#implementationvalues">list</a> of valid compilers.)</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+</table>
+<p>Either outputFile or destdir must be supplied, but not both.&nbsp;</p>
+
+<h3>Parameters specified as nested elements</h3>
+
+<h4>arg</h4>
+
+<p>You can specify additional command line arguments for the compiler
+with nested <code>&lt;arg&gt;</code> elements. These elements are
+specified like <a href="../using.html#arg">Command-line Arguments</a>
+but have an additional attribute that can be used to enable arguments
+only if a given compiler implementation will be used.</p>
+
+<table border="1" cellpadding="2" cellspacing="0">
+<tr>
+ <td width="12%" valign="top"><b>Attribute</b></td>
+ <td width="78%" valign="top"><b>Description</b></td>
+ <td width="10%" valign="top"><b>Required</b></td>
+</tr>
+ <tr>
+ <td valign="top">value</td>
+ <td align="center" rowspan="4">See
+ <a href="../using.html#arg">Command-line Arguments</a>.</td>
+ <td align="center" rowspan="4">Exactly one of these.</td>
+ </tr>
+ <tr>
+ <td valign="top">line</td>
+ </tr>
+ <tr>
+ <td valign="top">file</td>
+ </tr>
+ <tr>
+ <td valign="top">path</td>
+ </tr>
+ <tr>
+ <td valign="top">prefix</td>
+ <td align="center" rowspan="2">See
+ <a href="../using.html#arg">Command-line Arguments</a>.
+ <em>Since Ant 1.8.</em></td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">suffix</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">implementation</td>
+ <td>Only pass the specified argument if the chosen compiler
+ implementation matches the value of this attribute. Legal values
+ are the same as those in the above <a
+ href="#implementationvalues">list</a> of valid compilers.)</td>
+ <td align="center">No</td>
+ </tr>
+</table>
+
+<h4>implementationclasspath <em>since Ant 1.8.0</em></h4>
+
+<p>A <a href="../using.html#path">PATH like structure</a> holding the
+ classpath to use when loading the compiler implementation if a
+ custom class has been specified. Doesn't have any effect when
+ using one of the built-in compilers.</p>
+
+<h4>Any nested element of a type that implements JavahAdapter
+ <em>since Ant 1.8.0</em></h4>
+
+<p>If a defined type implements the <code>JavahAdapter</code>
+ interface a nested element of that type can be used as an
+ alternative to the <code>implementation</code> attribute.</p>
+
+<h3>Examples</h3>
+<pre> &lt;javah destdir=&quot;c&quot; class=&quot;org.foo.bar.Wibble&quot;/&gt;</pre>
+<p>makes a JNI header of the named class, using the JDK1.2 JNI model. Assuming
+the directory 'c' already exists, the file <tt>org_foo_bar_Wibble.h</tt>
+is created there. If this file already exists, it is left unchanged.</p>
+<pre> &lt;javah outputFile=&quot;wibble.h&quot;&gt;
+ &lt;class name=&quot;org.foo.bar.Wibble,org.foo.bar.Bobble&quot;/&gt;
+ &lt;/javah&gt;</pre>
+<p>is similar to the previous example, except the output is written to a file
+called <tt>wibble.h</tt>
+in the current directory.</p>
+<pre> &lt;javah destdir=&quot;c&quot; force=&quot;yes&quot;&gt;
+ &lt;class name=&quot;org.foo.bar.Wibble&quot;/&gt;
+ &lt;class name=&quot;org.foo.bar.Bobble&quot;/&gt;
+ &lt;class name=&quot;org.foo.bar.Tribble&quot;/&gt;
+ &lt;/javah&gt;</pre>
+<p>writes three header files, one for each of the classes named. Because the
+force option is set, these header files are always written when the Javah task
+is invoked, even if they already exist.</p>
+<pre> &lt;javah destdir=&quot;c&quot; verbose=&quot;yes&quot; old=&quot;yes&quot; force=&quot;yes&quot;&gt;
+ &lt;class name=&quot;org.foo.bar.Wibble&quot;/&gt;
+ &lt;class name=&quot;org.foo.bar.Bobble&quot;/&gt;
+ &lt;class name=&quot;org.foo.bar.Tribble&quot;/&gt;
+ &lt;/javah&gt;
+ &lt;javah destdir=&quot;c&quot; verbose=&quot;yes&quot; stubs=&quot;yes&quot; old=&quot;yes&quot; force=&quot;yes&quot;&gt;
+ &lt;class name=&quot;org.foo.bar.Wibble&quot;/&gt;
+ &lt;class name=&quot;org.foo.bar.Bobble&quot;/&gt;
+ &lt;class name=&quot;org.foo.bar.Tribble&quot;/&gt;
+ &lt;/javah&gt;</pre>
+<p>writes the headers for the three classes using the 'old' JNI format, then
+writes the corresponding .c stubs. The verbose option will cause Javah to
+describe its progress.</p>
+
+<p>If you want to use a custom
+ JavahAdapter <code>org.example.MyAdapter</code> you can either
+ use the implementation attribute:</p>
+<pre>
+&lt;javah destdir="c" class="org.foo.bar.Wibble"
+ implementation="org.example.MyAdapter"/&gt;
+</pre>
+<p>or a define a type and nest this into the task like in:</p>
+<pre>
+&lt;componentdef classname="org.example.MyAdapter"
+ name="myadapter"/&gt;
+&lt;javah destdir="c" class="org.foo.bar.Wibble"&gt;
+ &lt;myadapter/&gt;
+&lt;/javah&gt;
+</pre>
+<p>in which case your javah adapter can support attributes and
+ nested elements of its own.</p>
+
+</body>
+
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/jdepend.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/jdepend.html
new file mode 100644
index 00000000..7a9639da
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/jdepend.html
@@ -0,0 +1,177 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+
+<html>
+<head>
+ <link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>JDepend Task</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta http-equiv="Content-Language" content="en-us">
+</head>
+
+<body>
+
+<h2><a NAME="JDepend"></a>JDepend</h2>
+
+<h3>Description</h3>
+
+<P>Invokes the <a href="http://www.clarkware.com/software/JDepend.html">JDepend</a> parser.</P>
+
+<P>This parser &quot;traverses a set of Java source file directories and generates design quality metrics for each Java package&quot;.
+It allows to &quot;automatically measure the quality of a design in terms of its extensibility, reusability, and maintainability to
+effectively manage and control package dependencies.&quot;</P>
+
+<p>Source file directories are defined by nested
+<code>&lt;sourcespath&gt;</code>; Class file directories are defined
+by nested <code>&lt;classesespath&gt;</code>, see <a
+href="#nested">nested elements</a>.</p>
+
+<p>Optionally, you can also set the <code>outputfile</code> name where the output is stored. By default the task writes its report to the standard output.</P>
+
+<p> The task requires at least the JDepend 1.2 version. </p>
+
+<h3>Parameters</h3>
+
+<table BORDER=1 CELLSPACING=0 CELLPADDING=2 >
+ <tr>
+ <td VALIGN=TOP><b>Attribute</b></td>
+ <td VALIGN=TOP><b>Description</b></td>
+ <td ALIGN=CENTER VALIGN=TOP><b>Required</b></td>
+ </tr>
+ <tr>
+ <td VALIGN=TOP>outputfile</td>
+ <td VALIGN=TOP>The output file name. If not set, the output is printed on the standard output.</td>
+ <td ALIGN=CENTER VALIGN=TOP>No</td>
+ </tr>
+ <tr>
+ <td VALIGN=TOP>format</td>
+ <td VALIGN=TOP>The format to write the output in. The default is "text", the alternative is "xml"</td>
+ <td ALIGN=CENTER VALIGN=TOP>No</td>
+ </tr>
+ <tr>
+ <td VALIGN=TOP>fork</td>
+ <td VALIGN=TOP>Run the tests in a separate VM.</td>
+ <td ALIGN=CENTER VALIGN=TOP>No, default is "off"</td>
+ </tr>
+ <tr>
+ <td VALIGN=TOP>haltonerror</td>
+ <td VALIGN=TOP>Stop the build process if an error occurs during the jdepend analysis.</td>
+ <td ALIGN=CENTER VALIGN=TOP>No, default is "off"</td>
+ </tr>
+ <tr>
+ <td VALIGN=TOP>timeout</td>
+ <td VALIGN=TOP>Cancel the operation if it doesn't finish in the given time (measured in milliseconds). (Ignored if fork is disabled.)</td>
+ <td ALIGN=CENTER VALIGN=TOP>No</td>
+ </tr>
+ <tr>
+ <td VALIGN=TOP>jvm</td>
+ <td VALIGN=TOP>The command used to invoke the Java Virtual Machine, default is 'java'. The command is resolved by java.lang.Runtime.exec(). (Ignored if fork is disabled.)</td>
+ <td ALIGN=CENTER VALIGN=TOP>No, default "java"</td>
+ </tr>
+ <tr>
+ <td VALIGN=TOP>dir</td>
+ <td VALIGN=TOP>The directory to invoke the VM in. (Ignored if fork is disabled)</td>
+ <td ALIGN=CENTER VALIGN=TOP>No</td>
+ </tr>
+ <tr>
+ <td VALIGN=TOP>includeruntime</td>
+ <td VALIGN=TOP>Implicitly add the classes required to run jdepend
+ in forked mode. (Ignored if fork is disabled). Since Apache Ant 1.6.</td>
+ <td ALIGN=CENTER VALIGN=TOP>No, default is "no".</td>
+ </tr>
+ <tr>
+ <td VALIGN=TOP>classpathref</td>
+ <td VALIGN=TOP>the classpath to use, given as reference to a PATH defined elsewhere.</td>
+ <td ALIGN=CENTER VALIGN=TOP>No</td>
+ </tr>
+</table>
+
+<h3><a name="nested">Nested Elements</a></h3>
+
+<p><code>jdepend</code> supports four nested elements:
+<code>&lt;classpath&gt;, &lt;classespath&gt; </code> and
+<code>&lt;sourcespath&gt;</code>, that represent <a
+href="../using.html#path">PATH like structures</a>, and
+<code>&lt;exclude&gt;</code>.</p>
+
+<p><code>&lt;sourcespath&gt;</code> is used to define the paths of the
+source code to analyze, but it is deprecated. With version 2.5 of
+JDepend, only class files are analyzed. The nested element
+<code>&lt;classespath&gt;</code> replaces <code>&lt;sourcespath&gt;</code> and is used to define
+the paths of compiled class code to analyze; the <code>&lt;sourcespath&gt;</code>
+variable is still available in case you are using an earlier version
+of JDepend. The <code>&lt;exclude&gt;</code> element can be used to set packages
+to ignore (requires JDepend 2.5 or above).</p>
+
+<h3>Examples</h3>
+
+<blockquote>
+<pre>
+&lt;jdepend classpathref="base.path"&gt;
+&nbsp;&nbsp;&nbsp; &lt;classespath&gt;
+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;pathelement location="build"/&gt;
+&nbsp;&nbsp;&nbsp; &lt;/classespath&gt;
+&lt;/jdepend&gt;
+
+</pre>
+</blockquote>
+
+<p>This invokes JDepend on the <code>build</code> directory, writing
+the output on the standard output. The classpath is defined using a
+classpath reference.</p>
+
+<blockquote>
+<pre>
+&lt;jdepend outputfile="docs/jdepend.xml" fork="yes" format="xml"&gt;
+&nbsp;&nbsp;&nbsp; &lt;sourcespath&gt;
+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;pathelement location="src"/&gt;
+&nbsp;&nbsp;&nbsp; &lt;/sourcespath&gt;
+&nbsp;&nbsp;&nbsp; &lt;classpath&gt;
+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;pathelement location="classes"/&gt;
+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;pathelement location="lib/jdepend.jar"/&gt;
+&nbsp;&nbsp;&nbsp; &lt;/classpath&gt;
+&lt;/jdepend&gt;
+</pre>
+</blockquote>
+
+<p>This invokes JDepend in a separate VM on the <code>src</code> and
+<code>testsrc</code> directories, writing the output to the
+<code>&lt;docs/jdepend.xml&gt;</code> file in xml format. The
+classpath is defined using nested elements. </p>
+
+<blockquote>
+<pre>
+&lt;jdepend classpathref="base.path"&gt;
+&nbsp;&nbsp;&nbsp; &lt;exclude name="java.*&gt;
+&nbsp;&nbsp;&nbsp; &lt;exclude name="javax.*&gt;
+&nbsp;&nbsp;&nbsp; &lt;classespath&gt;
+&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;pathelement location="build"/&gt;
+&nbsp;&nbsp;&nbsp; &lt;/classespath&gt;
+&lt;/jdepend&gt;
+</pre>
+</blockquote>
+
+<p>This invokes JDepend with the build directory as the base for class
+files to analyze, and will ignore all classes in the java.* and
+javax.* packages.</p>
+
+
+</body>
+</html>
+
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/jjdoc.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/jjdoc.html
new file mode 100644
index 00000000..52b92257
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/jjdoc.html
@@ -0,0 +1,123 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta http-equiv="Content-Language" content="en-us">
+ <link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>JJDoc Task</title>
+</head>
+<body>
+
+<h2>
+<a NAME="jjtree"></a>JJDoc</h2>
+<p><em>Since Apache Ant 1.6</em></p>
+<h3>Description</h3>
+
+<p>Invokes the <a href="http://javacc.dev.java.net/">JJDoc</a> preprocessor
+for the JavaCC compiler compiler. It takes a JavaCC parser specification
+and produces documentation for the BNF grammar.
+It can operate in three modes, determined by command line options.
+<p>To use the jjdoc task, set the <i>target</i> attribute to the name
+of the JavaCC grammar file to process. You also need to specify the directory
+containing the JavaCC installation using the <i>javacchome</i> attribute,
+so that ant can find the JavaCC classes. Optionally, you can also set the
+<i>outputfile</i> to write the generated BNF documentation file to a specific (directory and) file.
+Otherwise jjdoc writes the generated BNF documentation file as the JavaCC
+grammar file with a suffix .txt or .html.</p>
+<p>This task only invokes JJDoc if the grammar file is newer than the
+generated BNF documentation file.</p>
+
+<h3>Parameters</h3>
+
+<table BORDER CELLSPACING=0 CELLPADDING=2 >
+<tr>
+<td VALIGN=TOP><b>Attribute</b></td>
+
+<td VALIGN=TOP><b>Description</b></td>
+
+<td ALIGN=CENTER VALIGN=TOP><b>Required</b></td>
+</tr>
+
+<tr>
+<td VALIGN=TOP>target</td>
+
+<td VALIGN=TOP>The javacc grammar file to process.</td>
+
+<td ALIGN=CENTER VALIGN=TOP>Yes</td>
+</tr>
+
+<tr>
+<td VALIGN=TOP>javacchome</td>
+
+<td VALIGN=TOP>The directory containing the JavaCC distribution.</td>
+
+<td ALIGN=CENTER VALIGN=TOP>Yes</td>
+</tr>
+
+<tr>
+<td VALIGN=TOP>outputfile</td>
+
+<td VALIGN=TOP>The file to write the generated BNF documentation file to. If not set,
+the file is written with the same name as the JavaCC grammar file but with a the suffix .html or .txt.&nbsp;</td>
+
+<td ALIGN=CENTER VALIGN=TOP>No</td>
+</tr>
+
+<tr>
+<td VALIGN=TOP>text</td>
+
+<td VALIGN=TOP>Sets the TEXT BNF documentation option. This is a boolean
+option.</td>
+
+<td ALIGN=CENTER VALIGN=TOP>No</td>
+</tr>
+
+<tr>
+<td VALIGN=TOP>onetable</td>
+
+<td VALIGN=TOP>Sets the ONE_TABLE BNF documentation option. This is a boolean option.</td>
+
+<td ALIGN=CENTER VALIGN=TOP>No</td>
+</tr>
+
+ <tr>
+ <td valign="top">maxmemory</td>
+ <td valign="top">Max amount of memory to allocate to the forked
+ VM. <em>since Ant 1.8.3</em></td>
+ <td align="center" valign="top">No</td>
+ </tr>
+</table>
+
+<h3>
+Example</h3>
+
+<blockquote>
+<pre>&lt;jjdoc&nbsp;
+&nbsp;&nbsp;&nbsp; target="src/Parser.jj"&nbsp;
+&nbsp;&nbsp;&nbsp; outputfile="doc/ParserBNF.html"
+&nbsp;&nbsp;&nbsp; javacchome="c:/program files/JavaCC"&nbsp;
+/&gt;</pre>
+</blockquote>
+This invokes JJDoc on grammar file src/Parser.jj, writing the generated
+BNF documentation file, ParserBNF.html, file to doc.
+<br>
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/jjtree.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/jjtree.html
new file mode 100644
index 00000000..7fbb2a9f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/jjtree.html
@@ -0,0 +1,563 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta http-equiv="Content-Language" content="en-us">
+ <link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>JJTree Task</title>
+</head>
+<body>
+
+<h2>
+<a NAME="jjtree"></a>JJTree</h2>
+
+<h3>
+Description</h3>
+<p>Invokes the <a href="http://javacc.dev.java.net/">JJTree</a> preprocessor
+for the JavaCC compiler compiler. It inserts parse tree building actions
+at various places in the JavaCC source that it generates. The output of
+JJTree is run through JavaCC to create the parser.
+<p>To use the jjtree task, set the <i>target</i> attribute to the name
+of the JJTree grammar file to process. You also need to specify the directory
+containing the JavaCC installation using the <i>javacchome</i> attribute,
+so that Ant can find the JavaCC classes. Optionally, you can also set the
+<i>outputdirectory</i>
+to write the generated JavaCC grammar and node files to a specific directory.
+Otherwise jjtree writes the generated JavaCC grammar and node files to the directory
+containing the JJTree grammar file. As an extra option, you can also set the
+<i>outputfile</i> to write the generated JavaCC grammar file to a specific (directory and) file.
+Otherwise jjtree writes the generated JavaCC grammar file as the JJTree
+grammar file with a suffix .jj.</p>
+<p>This task only invokes JJTree if the grammar file is newer than the
+generated JavaCC file.</p>
+
+<h3>Parameters</h3>
+
+<table BORDER CELLSPACING=0 CELLPADDING=2 >
+<tr>
+<td VALIGN=TOP><b>Attribute</b></td>
+
+<td VALIGN=TOP><b>Description</b></td>
+
+<td ALIGN=CENTER VALIGN=TOP><b>Required</b></td>
+</tr>
+
+<tr>
+<td VALIGN=TOP>target</td>
+
+<td VALIGN=TOP>The jjtree grammar file to process.</td>
+
+<td ALIGN=CENTER VALIGN=TOP>Yes</td>
+</tr>
+
+<tr>
+<td VALIGN=TOP>javacchome</td>
+
+<td VALIGN=TOP>The directory containing the JavaCC distribution.</td>
+
+<td ALIGN=CENTER VALIGN=TOP>Yes</td>
+</tr>
+
+<tr>
+<td VALIGN=TOP>outputdirectory</td>
+
+<td VALIGN=TOP>The directory to write the generated JavaCC grammar and node files to.
+If not set, the files are written to the directory containing the grammar file.&nbsp;</td>
+
+<td ALIGN=CENTER VALIGN=TOP>No</td>
+</tr>
+
+<tr>
+<td VALIGN=TOP>outputfile</td>
+
+<td VALIGN=TOP>The file to write the generated JavaCC grammar file
+to. If not set, the file is written with the same name as the JJTree
+grammar file but with a the suffix <code>.jj</code>. This is a
+filename relative to <em>outputdirectory</em> if specified, the
+project's basedir.</td>
+
+<td ALIGN=CENTER VALIGN=TOP>No</td>
+</tr>
+
+<tr>
+<td VALIGN=TOP>buildnodefiles</td>
+
+<td VALIGN=TOP>Sets the BUILD_NODE_FILES grammar option. This is a boolean
+option.</td>
+
+<td ALIGN=CENTER VALIGN=TOP>No</td>
+</tr>
+
+<tr>
+<td VALIGN=TOP>multi</td>
+
+<td VALIGN=TOP>Sets the MULTI grammar option. This is a boolean option.</td>
+
+<td ALIGN=CENTER VALIGN=TOP>No</td>
+</tr>
+
+<tr>
+<td VALIGN=TOP>nodedefaultvoid</td>
+
+<td VALIGN=TOP>Sets the NODE_DEFAULT_VOID grammar option. This is a boolean
+option.</td>
+
+<td ALIGN=CENTER VALIGN=TOP>No</td>
+</tr>
+
+<tr>
+<td VALIGN=TOP>nodefactory</td>
+
+<td VALIGN=TOP>Sets the NODE_FACTORY grammar option. This is boolean option.</td>
+
+<td ALIGN=CENTER VALIGN=TOP>No</td>
+</tr>
+
+<tr>
+<td VALIGN=TOP>nodescopehook</td>
+
+<td VALIGN=TOP>Sets the NODE_SCOPE_HOOK grammar option. This is a boolean
+option.</td>
+
+<td ALIGN=CENTER VALIGN=TOP>No</td>
+</tr>
+
+<tr>
+<td VALIGN=TOP>nodeusesparser</td>
+
+<td VALIGN=TOP>Sets the NODE_USES_PARSER grammar option. This is a boolean
+option.</td>
+
+<td ALIGN=CENTER VALIGN=TOP>No</td>
+</tr>
+
+<tr>
+<td VALIGN=TOP>static</td>
+
+<td VALIGN=TOP>Sets the STATIC grammar option. This is a boolean option.</td>
+
+<td ALIGN=CENTER VALIGN=TOP>No</td>
+</tr>
+
+<tr>
+<td VALIGN=TOP>visitor</td>
+
+<td VALIGN=TOP>Sets the VISITOR grammar option. This is a boolean option.</td>
+
+<td ALIGN=CENTER VALIGN=TOP>No</td>
+</tr>
+
+<tr>
+<td VALIGN=TOP>nodepackage</td>
+
+<td VALIGN=TOP>Sets the NODE_PACKAGE grammar option. This is a string option.</td>
+
+<td ALIGN=CENTER VALIGN=TOP>No</td>
+</tr>
+
+<tr>
+<td VALIGN=TOP>visitorexception</td>
+
+<td VALIGN=TOP>Sets the VISITOR_EXCEPTION grammar option. This is a string
+option.</td>
+
+<td ALIGN=CENTER VALIGN=TOP>No</td>
+</tr>
+
+<tr>
+<td VALIGN=TOP>nodeprefix</td>
+
+<td VALIGN=TOP>Sets the NODE_PREFIX grammar option. This is a string option.</td>
+
+<td ALIGN=CENTER VALIGN=TOP>No</td>
+</tr>
+
+ <tr>
+ <td valign="top">maxmemory</td>
+ <td valign="top">Max amount of memory to allocate to the forked
+ VM. <em>since Ant 1.8.3</em></td>
+ <td align="center" valign="top">No</td>
+ </tr>
+</table>
+
+<h3>
+Example</h3>
+
+<blockquote>
+<pre>&lt;jjtree&nbsp;
+&nbsp;&nbsp;&nbsp; target="src/Parser.jjt"&nbsp;
+&nbsp;&nbsp;&nbsp; outputdirectory="build/src"
+&nbsp;&nbsp;&nbsp; javacchome="c:/program files/JavaCC"&nbsp;
+&nbsp;&nbsp;&nbsp; nodeusesparser="true"
+/&gt;</pre>
+</blockquote>
+This invokes JJTree on grammar file src/Parser.jjt, writing the generated
+grammar file, Parser.jj, file to build/src. The grammar option NODE_USES_PARSER
+is set to true when invoking JJTree.
+<br>
+
+<h3>Comparison output locations between command line JJTree and different Ant taskdef versions</h3>
+
+<table cellpadding="3" border="1">
+<tr>
+ <td><b>Command Line JJTree options</b>
+ <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<i>and Generated Files</i> (working directory: <code>/tmp</code>)</td>
+ <td><b>Ant 1.5.3</b> versus command line</td>
+ <td><b>Ant 1.6</b> versus command line</td>
+</tr>
+<tr>
+ <td><pre><b>jjtree grammar.jjt</b>
+ /tmp/grammar.jj
+ /tmp/&lt;generated&gt;.java</pre>
+ </td>
+ <td>Same</td>
+ <td>Same</td>
+</tr>
+<tr>
+ <td><pre><b>jjtree relative/grammar.jjt</b>
+ /tmp/grammar.jj
+ /tmp/&lt;generated&gt;.java</pre>
+ </td>
+ <td><pre>
+/tmp/relative/grammar.jj
+/tmp/relative/&lt;generated&gt;.java</pre>
+ </td>
+ <td>Same</td>
+</tr>
+<tr>
+ <td><pre><b>jjtree /tmp/absolute/grammar.jjt</b>
+ /tmp/grammar.jj
+ /tmp/&lt;generated&gt;.java</pre>
+ </td>
+ <td><pre>
+/tmp/absolute/grammar.jj
+/tmp/absolute/&lt;generated&gt;.java</pre>
+ </td>
+ <td>Same</td>
+</tr>
+<tr>
+ <td><pre><b>jjtree -OUTPUT_DIRECTORY:relative grammar.jjt</b>
+ /tmp/relative/grammar.jj
+ /tmp/relative/&lt;generated&gt;.java</pre>
+ </td>
+ <td>Same</td>
+ <td>Same</td>
+</tr>
+<tr>
+ <td><pre><b>jjtree -OUTPUT_DIRECTORY:relative relative/grammar.jjt</b>
+ /tmp/relative/grammar.jj
+ /tmp/relative/&lt;generated&gt;.java</pre>
+ </td>
+ <td>Same</td>
+ <td>Same</td>
+</tr>
+<tr>
+ <td><pre><b>jjtree -OUTPUT_DIRECTORY:relative /tmp/absolute/grammar.jjt</b>
+ /tmp/relative/grammar.jj
+ /tmp/relative/&lt;generated&gt;.java</pre>
+ </td>
+ <td>Same</td>
+ <td>Same</td>
+</tr>
+<tr>
+ <td><pre><b>jjtree -OUTPUT_DIRECTORY:/tmp/absolute/ grammar.jjt</b>
+ /tmp/absolute/grammar.jj
+ /tmp/absolute/&lt;generated&gt;.java</pre>
+ </td>
+ <td>Same</td>
+ <td>Same</td>
+</tr>
+<tr>
+ <td><pre><b>jjtree -OUTPUT_DIRECTORY:/tmp/absolute/ relative/grammar.jjt</b>
+ /tmp/absolute/grammar.jj
+ /tmp/absolute/&lt;generated&gt;.java</pre>
+ </td>
+ <td>Same</td>
+ <td>Same</td>
+</tr>
+<tr>
+ <td><pre><b>jjtree -OUTPUT_DIRECTORY:/tmp/absolute/ /tmp/absolute/grammar.jjt</b>
+ /tmp/absolute/grammar.jj
+ /tmp/absolute/&lt;generated&gt;.java</pre>
+ </td>
+ <td>Same</td>
+ <td>Same</td>
+</tr>
+<tr>
+ <td><pre><b>jjtree -OUTPUT_FILE:output.jj grammar.jjt</b>
+ /tmp/output.jj
+ /tmp/&lt;generated&gt;.java</pre>
+ </td>
+ <td>Not Supported</td>
+ <td>Same</td>
+</tr>
+<tr>
+ <td><pre><b>jjtree -OUTPUT_FILE:output.jj relative/grammar.jjt</b>
+ /tmp/output.jj
+ /tmp/&lt;generated&gt;.java</pre>
+ </td>
+ <td>Not Supported</td>
+ <td>Same</td>
+</tr>
+<tr>
+ <td><pre><b>jjtree -OUTPUT_FILE:output.jj /tmp/absolute/grammar.jjt</b>
+ /tmp/output.jj
+ /tmp/&lt;generated&gt;.java</pre>
+ </td>
+ <td>Not Supported</td>
+ <td>Same</td>
+</tr>
+<tr>
+ <td><pre><b>jjtree -OUTPUT_FILE:output.jj -OUTPUT_DIRECTORY:relative grammar.jjt</b>
+ /tmp/relative/output.jj
+ /tmp/relative/&lt;generated&gt;.java</pre>
+ </td>
+ <td>Not Supported</td>
+ <td>Same</td>
+</tr>
+<tr>
+ <td><pre><b>jjtree -OUTPUT_FILE:output.jj -OUTPUT_DIRECTORY:relative relative/grammar.jjt</b>
+ /tmp/relative/output.jj
+ /tmp/relative/&lt;generated&gt;.java</pre>
+ </td>
+ <td>Not Supported</td>
+ <td>Same</td>
+</tr>
+<tr>
+ <td><pre><b>jjtree -OUTPUT_FILE:output.jj -OUTPUT_DIRECTORY:relative /tmp/absolute/grammar.jjt</b>
+ /tmp/relative/output.jj
+ /tmp/relative/&lt;generated&gt;.java</pre>
+ </td>
+ <td>Not Supported</td>
+ <td>Same</td>
+</tr>
+<tr>
+ <td><pre><b>jjtree -OUTPUT_FILE:output.jj -OUTPUT_DIRECTORY:/tmp/absolute/ grammar.jjt</b>
+ /tmp/absolute/output.jj
+ /tmp/absolute/&lt;generated&gt;.java</pre>
+ </td>
+ <td>Not Supported</td>
+ <td>Same</td>
+</tr>
+<tr>
+ <td><pre><b>jjtree -OUTPUT_FILE:output.jj -OUTPUT_DIRECTORY:/tmp/absolute/ relative/grammar.jjt</b>
+ /tmp/absolute/output.jj
+ /tmp/absolute/&lt;generated&gt;.java</pre>
+ </td>
+ <td>Not Supported</td>
+ <td>Same</td>
+</tr>
+<tr>
+ <td><pre><b>jjtree -OUTPUT_FILE:output.jj -OUTPUT_DIRECTORY:/tmp/absolute/ /tmp/absolute/grammar.jjt</b>
+ /tmp/absolute/output.jj
+ /tmp/absolute/&lt;generated&gt;.java</pre>
+ </td>
+ <td>Not Supported</td>
+ <td>Same</td>
+</tr>
+<tr>
+ <td><pre><b>jjtree -OUTPUT_FILE:subdir/output.jj grammar.jjt</b>
+ /tmp/subdir/output.jj
+ /tmp/&lt;generated&gt;.java</pre>
+ </td>
+ <td>Not Supported</td>
+ <td>Same</td>
+</tr>
+<tr>
+ <td><pre><b>jjtree -OUTPUT_FILE:subdir/output.jj relative/grammar.jjt</b>
+ /tmp/subdir/output.jj
+ /tmp/&lt;generated&gt;.java</pre>
+ </td>
+ <td>Not Supported</td>
+ <td>Same</td>
+</tr>
+<tr>
+ <td><pre><b>jjtree -OUTPUT_FILE:subdir/output.jj /tmp/absolute/grammar.jjt</b>
+ /tmp/subdir/output.jj
+ /tmp/&lt;generated&gt;.java</pre>
+ </td>
+ <td>Not Supported</td>
+ <td>Same</td>
+</tr>
+<tr>
+ <td><pre><b>jjtree -OUTPUT_FILE:subdir/output.jj -OUTPUT_DIRECTORY:relative grammar.jjt</b>
+ /tmp/relative/subdir/output.jj
+ /tmp/relative/&lt;generated&gt;.java</pre>
+ </td>
+ <td>Not Supported</td>
+ <td>Same</td>
+</tr>
+<tr>
+ <td><pre><b>jjtree -OUTPUT_FILE:subdir/output.jj -OUTPUT_DIRECTORY:relative relative/grammar.jjt</b>
+ /tmp/relative/subdir/output.jj
+ /tmp/relative/&lt;generated&gt;.java</pre>
+ </td>
+ <td>Not Supported</td>
+ <td>Same</td>
+</tr>
+<tr>
+ <td><pre><b>jjtree -OUTPUT_FILE:subdir/output.jj -OUTPUT_DIRECTORY:relative /tmp/absolute/grammar.jjt</b>
+ /tmp/relative/subdir/output.jj
+ /tmp/relative/&lt;generated&gt;.java</pre>
+ </td>
+ <td>Not Supported</td>
+ <td>Same</td>
+</tr>
+<tr>
+ <td><pre><b>jjtree -OUTPUT_FILE:subdir/output.jj -OUTPUT_DIRECTORY:/tmp/absolute/ grammar.jjt</b>
+ /tmp/absolute/subdir/output.jj
+ /tmp/absolute/&lt;generated&gt;.java</pre>
+ </td>
+ <td>Not Supported</td>
+ <td>Same</td>
+</tr>
+<tr>
+ <td><pre><b>jjtree -OUTPUT_FILE:subdir/output.jj -OUTPUT_DIRECTORY:/tmp/absolute/ relative/grammar.jjt</b>
+ /tmp/absolute/subdir/output.jj
+ /tmp/absolute/&lt;generated&gt;.java</pre>
+ </td>
+ <td>Not Supported</td>
+ <td>Same</td>
+</tr>
+<tr>
+ <td><pre><b>jjtree -OUTPUT_FILE:subdir/output.jj -OUTPUT_DIRECTORY:/tmp/absolute/ /tmp/absolute/grammar.jjt</b>
+ /tmp/absolute/subdir/output.jj
+ /tmp/absolute/&lt;generated&gt;.java</pre>
+ </td>
+ <td>Not Supported</td>
+ <td>Same</td>
+</tr>
+<tr>
+ <td><pre><b>jjtree -OUTPUT_FILE:/tmp/subdir/output.jj grammar.jjt</b>
+ /tmp/subdir/output.jj
+ /tmp/&lt;generated&gt;.java</pre>
+ </td>
+ <td>Not Supported</td>
+ <td>Same</td>
+</tr>
+<tr>
+ <td><pre><b>jjtree -OUTPUT_FILE:/tmp/subdir/output.jj relative/grammar.jjt</b>
+ /tmp/subdir/output.jj
+ /tmp/&lt;generated&gt;.java</pre>
+ </td>
+ <td>Not Supported</td>
+ <td>Same</td>
+</tr>
+<tr>
+ <td><pre><b>jjtree -OUTPUT_FILE:/tmp/subdir/output.jj /tmp/absolute/grammar.jjt</b>
+ /tmp/subdir/output.jj
+ /tmp/&lt;generated&gt;.java</pre>
+ </td>
+ <td>Not Supported</td>
+ <td>Same</td>
+</tr>
+<tr>
+ <td><pre><b>jjtree -OUTPUT_FILE:<i><u>D:</u></i>/tmp/subdir/output.jj grammar.jjt</b>
+ /tmp/subdir/output.jj
+ /tmp/&lt;generated&gt;.java</pre>
+ </td>
+ <td>Not Supported</td>
+ <td>Not Supported *)</td>
+</tr>
+<tr>
+ <td><pre><b>jjtree -OUTPUT_FILE:<i><u>D:</u></i>/tmp/subdir/output.jj relative/grammar.jjt</b>
+ /tmp/subdir/output.jj
+ /tmp/&lt;generated&gt;.java</pre>
+ </td>
+ <td>Not Supported</td>
+ <td>Not Supported *)</td>
+</tr>
+<tr>
+ <td><pre><b>jjtree -OUTPUT_FILE:<i><u>D:</u></i>/tmp/subdir/output.jj /tmp/absolute/grammar.jjt</b>
+ /tmp/subdir/output.jj
+ /tmp/&lt;generated&gt;.java</pre>
+ </td>
+ <td>Not Supported</td>
+ <td>Not Supported *)</td>
+</tr>
+<tr>
+ <td><pre><b>jjtree -OUTPUT_FILE:/tmp/subdir/output.jj -OUTPUT_DIRECTORY:relative grammar.jjt</b>
+ /tmp/relative/tmp/subdir/output.jj
+ /tmp/relative/&lt;generated&gt;.java</pre>
+ </td>
+ <td>Not Supported</td>
+ <td>Same</td>
+</tr>
+<tr>
+ <td><pre><b>jjtree -OUTPUT_FILE:/tmp/subdir/output.jj -OUTPUT_DIRECTORY:relative relative/grammar.jjt</b>
+ /tmp/relative/tmp/subdir/output.jj
+ /tmp/relative/&lt;generated&gt;.java</pre>
+ </td>
+ <td>Not Supported</td>
+ <td>Same</td>
+</tr>
+<tr>
+ <td><pre><b>jjtree -OUTPUT_FILE:/tmp/subdir/output.jj -OUTPUT_DIRECTORY:relative /tmp/absolute/grammar.jjt</b>
+ /tmp/relative/tmp/subdir/output.jj
+ /tmp/relative/&lt;generated&gt;.java</pre>
+ </td>
+ <td>Not Supported</td>
+ <td>Same</td>
+</tr>
+<tr>
+ <td><pre><b>jjtree -OUTPUT_FILE:/tmp/subdir/output.jj -OUTPUT_DIRECTORY:/tmp/absolute/ grammar.jjt</b>
+ /tmp/absolute/tmp/subdir/output.jj
+ /tmp/absolute/&lt;generated&gt;.java</pre>
+ </td>
+ <td>Not Supported</td>
+ <td>Same</td>
+</tr>
+<tr>
+ <td><pre><b>jjtree -OUTPUT_FILE:/tmp/subdir/output.jj -OUTPUT_DIRECTORY:/tmp/absolute/ relative/grammar.jjt</b>
+ /tmp/absolute/tmp/subdir/output.jj
+ /tmp/absolute/&lt;generated&gt;.java</pre>
+ </td>
+ <td>Not Supported</td>
+ <td>Same</td>
+</tr>
+<tr>
+ <td><pre><b>jjtree -OUTPUT_FILE:/tmp/subdir/output.jj -OUTPUT_DIRECTORY:/tmp/absolute/ /tmp/absolute/grammar.jjt</b>
+ /tmp/absolute/tmp/subdir/output.jj
+ /tmp/absolute/&lt;generated&gt;.java</pre>
+ </td>
+ <td>Not Supported</td>
+ <td>Same</td>
+</tr>
+</table>
+
+<p>*) <u>Footnote</u>: When running JJTree with the Ant taskdef <i>jjtree</i> the option <code>-OUTPUT_DIRECTORY</code> must always
+be set, because the project's basedir and the Ant working directory might differ. So even if you don't specify the jjtree taskdef
+<i>outputdirectory</i> JJTree will be called with the <code>-OUTPUT_DIRECTORY</code> set to the project's basedirectory.
+But when the <code>-OUTPUT_DIRECTORY</code> is set, the <code>-OUTPUT_FILE</code> setting is handled as if relative to this
+<code>-OUTPUT_DIRECTORY</code>. Thus when the <code>-OUTPUT_FILE</code> is absolute or contains a drive letter we have a
+problem.
+Therefore absolute <i>outputfile</i>s (when the <i>outputdirectory</i> isn't specified) are made relative to the default directory.
+And for this reason <i>outputfile</i>s that contain a drive letter can't be supported.</p>
+
+<p>By the way: specifying a drive letter in the <code>-OUTPUT_FILE</code> when the <code>-OUTPUT_DIRECTORY</code> is set, also
+results in strange behavior when running JJTree from the command line.</p>
+
+<br>
+
+
+
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/jlink.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/jlink.html
new file mode 100644
index 00000000..45ef9615
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/jlink.html
@@ -0,0 +1,177 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+<head>
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>JLink Task</title>
+</head>
+<body>
+
+<h2><a name="jlink">Jlink</a></h2>
+<h3><i>Deprecated</i></h3>
+<p><i>This task has been deprecated. Use a <a href="../Types/zipfileset.html">zipfileset</a>
+ or <a href="../Tasks/zip.html#zipgroupfileset">zipgroupfileset</a> with the
+ <a href="../Tasks/jar.html">Jar task</a> or <a href="../Tasks/zip.html">Zip task</a>
+ instead.</i></p>
+
+<h3><b>Description:</b></h3>
+<p>Links entries from sub-builds and libraries.</p>
+
+<p>The jlink task can be used to build jar and zip files, similar to
+the <i>jar</i> task.
+However, jlink provides options for controlling the way entries from
+input files
+are added to the output file. Specifically, capabilities for merging
+entries from
+multiple zip or jar files is available.</p>
+
+<p>If a mergefile is specified directly (eg. at the top level of a
+<i>mergefiles</i>
+pathelement) <i>and</i> the mergefile ends in &quot;.zip&quot; or
+&quot;.jar&quot;,
+entries in the mergefile will be merged into the outfile. A file with
+any other extension
+will be added to the output file, even if it is specified in the
+mergefiles element.
+Directories specified in either the mergefiles or addfiles element
+are added to the
+output file as you would expect: all files in subdirectories are
+recursively added to
+the output file with appropriate prefixes in the output file
+(without merging).
+</p>
+
+<p>
+In the case where duplicate entries and/or files are found among the
+files to be merged or
+added, jlink merges or adds the first entry and ignores all subsequent entries.
+</p>
+
+<p>
+jlink ignores META-INF directories in mergefiles. Users should supply their
+own manifest information for the output file.
+</p>
+
+<p>It is possible to refine the set of files that are being jlinked.
+This can be
+done with the <i>includes</i>, <i>includesfile</i>, <i>excludes</i>,
+<i>excludesfile</i>,
+and <i>defaultexcludes</i> attributes on the <i>addfiles</i> and
+<i>mergefiles</i>
+nested elements. With the <i>includes</i> or <i>includesfile</i>
+attribute you specify the files you want to have included by using patterns.
+The <i>exclude</i> or <i>excludesfile</i> attribute is used to specify
+the files you want to have excluded. This is also done with patterns. And
+finally with the <i>defaultexcludes</i> attribute, you can specify whether you
+want to use default exclusions or not. See the section on <a
+href="../dirtasks.html#directorybasedtasks">directory based tasks</a>, on how the
+inclusion/exclusion of files works, and how to write patterns. The patterns are
+relative to the <i>base</i> directory.</p>
+
+
+
+<h3>Parameters:</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">outfile</td>
+ <td valign="top">the path of the output file.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">compress</td>
+ <td valign="top">whether or not the output should be compressed.
+<i>true</i>,
+ <i>yes</i>, or <i>on</i> result in compressed output.
+ If omitted, output will be uncompressed (inflated).</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">mergefiles</td>
+ <td valign="top">files to be merged into the output, if possible.</td>
+ <td valign="middle" align="center" rowspan="2">At least one of
+mergefiles or addfiles</td>
+ </tr>
+ <tr>
+ <td valign="top">addfiles</td>
+ <td valign="top">files to be added to the output.</td>
+ </tr>
+</table>
+
+<h3>Examples</h3>
+
+<p>The following will merge the entries in mergefoo.jar and mergebar.jar
+into out.jar.
+mac.jar and pc.jar will be added as single entries to out.jar.</p>
+<pre>
+&lt;jlink compress=&quot;false&quot; outfile=&quot;out.jar&quot;&gt;
+ &lt;mergefiles&gt;
+ &lt;pathelement path=&quot;${build.dir}/mergefoo.jar&quot;/&gt;
+ &lt;pathelement path=&quot;${build.dir}/mergebar.jar&quot;/&gt;
+ &lt;/mergefiles&gt;
+ &lt;addfiles&gt;
+ &lt;pathelement path=&quot;${build.dir}/mac.jar&quot;/&gt;
+ &lt;pathelement path=&quot;${build.dir}/pc.zip&quot;/&gt;
+ &lt;/addfiles&gt;
+&lt;/jlink&gt;
+</pre>
+
+<p><b>Non-deprecated alternative to the above:</b></p>
+<pre>
+&lt;jar compress=&quot;false&quot; destfile=&quot;out.jar&quot;&gt;
+ &lt;zipgroupfileset dir=&quot;${build.dir}&quot;&gt;
+ &lt;include name=&quot;mergefoo.jar&quot;/&gt;
+ &lt;include name=&quot;mergebar.jar&quot;/&gt;
+ &lt;/zipgroupfileset&gt;
+ &lt;fileset dir=&quot;${build.dir}&quot;&gt;
+ &lt;include name=&quot;mac.jar&quot;/&gt;
+ &lt;include name=&quot;pc.jar&quot;/&gt;
+ &lt;/fileset&gt;
+&lt;/jar&gt;
+</pre>
+
+<p>Suppose the file foo.jar contains two entries: bar.class and
+barnone/myClass.zip.
+Suppose the path for file foo.jar is build/tempbuild/foo.jar. The
+following example
+will provide the entry tempbuild/foo.jar in the out.jar.</p>
+<pre>
+&lt;jlink compress=&quot;false&quot; outfile=&quot;out.jar&quot;&gt;
+ &lt;mergefiles&gt;
+ &lt;pathelement path=&quot;build/tempbuild&quot;/&gt;
+ &lt;/mergefiles&gt;
+&lt;/jlink&gt;
+</pre>
+
+<p>However, the next example would result in two top-level entries in out.jar,
+namely bar.class and barnone/myClass.zip</p>
+<pre>
+&lt;jlink compress=&quot;false&quot; outfile=&quot;out.jar&quot;&gt;
+ &lt;mergefiles&gt;
+ &lt;pathelement path=&quot;build/tempbuild/foo.jar&quot;/&gt;
+ &lt;/mergefiles&gt;
+&lt;/jlink&gt;
+</pre>
+
+
+</body>
+
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/jspc.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/jspc.html
new file mode 100644
index 00000000..88361867
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/jspc.html
@@ -0,0 +1,308 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>JSPC Task</title>
+</head>
+
+<body>
+
+<h2><a name="jspc">jspc (deprecated)</a></h2>
+<h3>Description</h3>
+
+<p> Apache Ant task to run the JSP compiler and turn JSP pages into Java source.
+
+<p><b>Deprecated</b> if you use this task with Tomcat's Jasper JSP
+compiler, you should seriously consider using the task shipping with
+Tomcat instead. This task is only tested against Tomcat 4.x. There
+are known problems with Tomcat 5.x that won't get fixed in Ant, please
+use Tomcat's jspc task instead.<br/>
+Instead of relying on container specific JSP-compilers we suggest deploying
+the raw files (*.jsp) and use the container build-in functions: after deploying run
+a test suite (e.g. with <a href="http://attic.apache.org/projects/jakarta-cactus.html">Cactus</a> or
+<a href="http://httpunit.sourceforge.net/">HttpUnit</a>) against the deployed web
+application. So you'll get the test result <i>and</i> the compiled JSPs.
+</p>
+
+<p>
+
+This task can be used to precompile JSP pages for fast initial invocation
+of JSP pages, deployment on a server without the full JDK installed,
+or simply to syntax check the pages without deploying them.
+In most cases, a javac task is usually the next stage in the build process.
+The task does basic dependency checking to prevent unnecessary recompilation -this
+checking compares source and destination timestamps, and does not factor
+in class or taglib dependencies, or <code>&lt;jsp:include&gt;</code> references.
+
+<p>
+By default the task uses the Jasper JSP compiler. This
+means the task needs jasper.jar and jasper-runtime.jar, which come with
+builds of Tomcat 4/Catalina from the
+<a href="http://tomcat.apache.org/">Apache Tomcat project</a>,
+and any other Jar files which may be needed in future versions (it changes)
+
+We recommend (in March 2003) Tomcat version 4.1.x for the most robust version
+of Jasper.
+
+<p>
+There are many limitations with this task which partially stem from the
+many versions of Jasper, others from implementation 'issues' in the task
+(i.e. nobody's willingness to radically change large bits of it to work
+around jasper). Because of this and the fact that JSP pages do not have
+to be portable across implementations -or versions of implementations-
+this task is better used for validating JSP pages before deployment,
+rather than precompiling them. For that, just deploy and run your httpunit
+junit tests after deployment to compile and test your pages, all in one
+go.
+
+</p>
+
+
+<h3>Parameters</h3>
+The Task has the following attributes:<p>
+
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">destdir</td>
+ <td valign="top">Where to place the generated files. They are located
+ under here according to the given package name.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">srcdir</td>
+ <td valign="top">Where to look for source jsp files.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">verbose</td>
+ <td valign="top">The verbosity integer to pass to the compiler. Default="0"</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">package</td>
+ <td valign="top">Name of the destination package for generated java
+ classes.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">compiler</td>
+ <td valign="top">class name of a JSP compiler adapter,
+ such as "jasper" or "jasper41"</td>
+ <td valign="top" align="center">No -defaults to "jasper"</td>
+ </tr>
+ <tr>
+ <td valign="top">ieplugin</td>
+ <td valign="top">Java Plugin classid for Internet Explorer.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">mapped</td>
+ <td valign="top">(boolean) Generate separate write() calls for each HTML
+ line in the JSP.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">classpath</td>
+ <td valign="top">The classpath to use to run the jsp compiler.
+ This can also be specified
+ by the nested element <code>classpath</code>
+ <a href="../using.html#path">Path</a>).</td>
+ <td valign="top" align="center">No, but it seems to work better when used</td>
+ </tr>
+ <tr>
+ <td valign="top">classpathref</td>
+ <td valign="top">A <a href="../using.html#references">Reference</a>. As
+ per <code>classpath</code></td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">failonerror</td>
+ <td valign="top">flag to control action on compile failures: default=yes</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">uribase</td>
+ <td valign="top">
+ The uri context of relative URI
+ references in the JSP pages. If it does not
+ exist then it is derived from the location of the file
+ relative to the declared or derived value of <tt>uriroot.</tt>
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">uriroot</td>
+ <td valign="top">
+ The root directory that uri files should be resolved
+ against.
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">compiler</td>
+ <td valign="top">
+ Class name of jsp compiler adapter to use. Defaults to
+ the standard adapter for Jasper.
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">compilerclasspath</td>
+ <td valign="top">The classpath used to find the compiler adapter specified
+ by the <code>compiler</code> attribute.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">webinc</td>
+ <td valign="top">Output file name for the fraction of web.xml that lists servlets.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">webxml</td>
+ <td valign="top">File name for web.xml to be generated</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+
+ </table>
+
+<P>The <tt>mapped</tt> option will, if set to true, split the JSP text content into a
+one line per call format. There are comments above and below the mapped
+write calls to localize where in the JSP file each line of text comes
+from. This can lead to a minor performance degradation (but it is bound
+by a linear complexity). Without this options all adjacent writes are
+concatenated into a single write.</P>
+
+<P>The <tt>ieplugin</tt> option is used by the <tt>&lt;jsp:plugin&gt;</tt> tags.
+If the Java Plug-in COM Class-ID you want to use changes then it can be
+specified here. This should not need to be altered.</P>
+
+<P><tt>uriroot</tt> specifies the root of the web
+application. This is where all absolute uris will be resolved from.
+If it is not specified then the first JSP page will be used to derive
+it. To derive it each parent directory of the first JSP page is
+searched for a <tt>WEB-INF</tt> directory, and the directory closest to
+the JSP page that has one will be used. If none can be found then the
+directory Jasperc was called from will be used. This only affects pages
+translated from an explicitly declared JSP file -including references
+to taglibs</P>
+
+<P><tt>uribase</tt> is used to establish the uri context of
+relative URI references in the JSP pages. If it does not exist then it
+is derived from the location of the file relative to the declared or
+derived value of <tt>uriroot</tt>. This only affects pages
+translated from an explicitly declared JSP file.</P>
+
+<h3>Parameters specified as nested elements</h3>
+
+This task is a <a href="../dirtasks.html">directory based task</a>, like
+<strong>javac</strong>, so the jsp files to be compiled are located as java
+files are by <strong>javac</strong>. That is, elements such as <tt>includes</tt> and
+<tt>excludes</tt> can be used directly inside the task declaration.
+
+<p>
+
+Elements specific to the jspc task are:-
+
+<h4>classpath</h4>
+
+The classpath used to compile the JSP pages, specified as for any other
+classpath.
+
+<h4>classpathref</h4>
+a reference to an existing classpath
+
+<h4>webapp</h4>
+Instructions to jasper to build an entire web application.
+The base directory must have a WEB-INF subdirectory beneath it.
+When used, the task hands off all dependency checking to the compiler.
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">basedir</td>
+ <td valign="top">the base directory of the web application</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+</table>
+<h3>Example</h3>
+<pre>
+&lt;jspc srcdir="${basedir}/src/war"
+ destdir="${basedir}/gensrc"
+ package="com.i3sp.jsp"
+ compiler="jasper41"
+ verbose="9"&gt;
+ &lt;include name="**/*.jsp"/&gt;
+&lt;/jspc&gt;
+</pre>
+Build all jsp pages under src/war into the destination /gensrc, in a
+package hierarchy beginning with com.i3sp.jsp.
+<pre>
+&lt;jspc
+ destdir="interim"
+ verbose="1"
+ srcdir="src"
+ compiler="jasper41"
+ package="com.i3sp.jsp"&gt;
+ &lt;include name="**/*.jsp"/&gt;
+&lt;/jspc&gt;
+&lt;depend
+ srcdir="interim"
+ destdir="build"
+ cache="build/dependencies"
+ classpath="lib/taglibs.jar"/&gt;
+&lt;javac
+ srcdir="interim"
+ destdir="build"
+ classpath="lib/taglibs.jar"
+ debug="on"/&gt;
+</pre>
+Generate jsp pages then javac them down to
+bytecodes. Include lib/taglib jar in the java compilation.
+ Dependency checking is used to scrub the
+java files if class dependencies indicate it is needed.
+
+<p><h4>Notes</h4>
+Using the <code>package</code> attribute it is possible to identify the resulting
+java files and thus do full dependency checking - this task should only rebuild
+java files if their jsp file has been modified. However, this only works
+with some versions of jasper. By default the checking supports tomcat 4.0.x
+with the "jasper" compiler, set the compiler to "jasper41" for the tomcat4.1.x
+dependency checking.
+Even when it does work, changes in
+.TLD imports or in compile time includes do not get picked up.
+
+<p>
+Jasper generates JSP pages against the JSP1.2 specification -a copy of
+version 2.3 of the servlet specification is needed on the classpath to
+compile the Java code.
+
+
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/junit.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/junit.html
new file mode 100644
index 00000000..76df9ced
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/junit.html
@@ -0,0 +1,802 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+<head>
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>JUnit Task</title>
+</head>
+<body>
+
+<h2><a name="junit">JUnit</a></h2>
+<h3>Description</h3>
+
+<p>This task runs tests from the JUnit testing framework. The latest
+version of the framework can be found at
+<a href="http://www.junit.org">http://www.junit.org</a>.
+This task has been tested with JUnit 3.0 up to JUnit 3.8.2; it won't
+work with versions prior to JUnit 3.0. It also works with JUnit 4.0, including
+"pure" JUnit 4 tests using only annotations and no <code>JUnit4TestAdapter</code>.</p>
+<p><strong>Note:</strong> This task depends on external libraries not included
+in the Apache Ant distribution. See <a href="../install.html#librarydependencies">
+Library Dependencies</a> for more information.
+</p>
+<p>
+<strong>Note</strong>:
+You must have <code>junit.jar</code> available.
+You can do one of:
+</p>
+<ol>
+<li>
+Put both <code>junit.jar</code> and <code>ant-junit.jar</code> in
+<code>ANT_HOME/lib</code>.
+</li>
+<li>
+Do not put either in <code>ANT_HOME/lib</code>, and instead
+include their locations in your <code>CLASSPATH</code> environment variable.
+</li>
+<li>
+Add both JARs to your classpath using <code>-lib</code>.
+</li>
+<li>
+Specify the locations of both JARs using
+a <code>&lt;classpath&gt;</code> element in a <code>&lt;taskdef&gt;</code> in the build file.
+</li>
+<li>
+Leave <code>ant-junit.jar</code> in its default location in <code>ANT_HOME/lib</code>
+but include <code>junit.jar</code> in the <code>&lt;classpath&gt;</code> passed
+to <code>&lt;junit&gt;</code>. <em>(since Ant 1.7)</em>
+</li>
+</ol>
+<p>
+See <a href="http://ant.apache.org/faq.html#delegating-classloader" target="_top">the
+FAQ</a> for details.
+</p>
+
+<p>Tests are defined by nested <code>test</code> or
+<code>batchtest</code> tags (see <a href="#nested">nested
+elements</a>).</p>
+
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+<tr>
+ <td width="12%" valign="top"><b>Attribute</b></td>
+ <td width="78%" valign="top"><b>Description</b></td>
+ <td width="10%" valign="top"><b>Required</b></td>
+</tr>
+ <tr>
+ <td valign="top">printsummary</td>
+ <td valign="top">Print one-line statistics for each testcase. Can
+ take the values <code>on</code>,
+ <code>off</code>, and
+ <code>withOutAndErr</code>.
+ <code>withOutAndErr</code> is the same
+ as <code>on</code> but also includes the output of the test
+ as written to <code>System.out</code> and <code>System.err</code>.</td>
+ <td align="center" valign="top">No; default is <code>off</code>.</td>
+ </tr>
+ <tr>
+ <td valign="top">fork</td>
+ <td valign="top">Run the tests in a separate VM.</td>
+ <td align="center" valign="top">No; default is <code>off</code>.</td>
+ </tr>
+ <tr>
+ <td valign="top">forkmode</td>
+ <td valign="top">Controls how many Java Virtual Machines get
+ created if you want to fork some tests. Possible values are
+ &quot;perTest&quot; (the default), &quot;perBatch&quot; and
+ &quot;once&quot;. &quot;once&quot; creates only a single Java VM
+ for all tests while &quot;perTest&quot; creates a new VM for each
+ TestCase class. &quot;perBatch&quot; creates a VM for each nested
+ <code>&lt;batchtest&gt;</code> and one collecting all nested
+ <code>&lt;test&gt;</code>s. Note that only tests with the same
+ settings of <code>filtertrace</code>, <code>haltonerror</code>,
+ <code>haltonfailure</code>, <code>errorproperty</code> and
+ <code>failureproperty</code> can share a VM, so even if you set
+ <code>forkmode</code> to &quot;once&quot;, Ant may have to create
+ more than a single Java VM. This attribute is ignored for tests
+ that don't get forked into a new Java VM. <em>since Ant 1.6.2</em></td>
+ <td align="center" valign="top">No; default is <code>perTest</code>.</td>
+ </tr>
+ <tr>
+ <td valign="top">haltonerror</td>
+ <td valign="top">Stop the build process if an error occurs during the test
+ run.</td>
+ <td align="center" valign="top">No; default is <code>off</code>.</td>
+ </tr>
+<tr>
+ <td valign="top">errorproperty</td>
+ <td valign="top">The name of a property to set in the event of an error.</td>
+ <td align="center" valign="top">No</td>
+</tr>
+ <tr>
+ <td valign="top">haltonfailure</td>
+ <td valign="top">Stop the build process if a test fails (errors are
+ considered failures as well).</td>
+ <td align="center" valign="top">No; default is <code>off</code>.</td>
+ </tr>
+<tr>
+ <td valign="top">failureproperty</td>
+ <td valign="top">The name of a property to set in the event of a failure
+ (errors are considered failures as well).</td>
+ <td align="center" valign="top">No.</td>
+</tr>
+ <tr>
+ <td valign="top">filtertrace</td>
+ <td valign="top">Filter out Junit and Ant stack frames from error and failure stack traces.</td>
+ <td align="center" valign="top">No; default is <code>on</code>.</td>
+ </tr>
+ <tr>
+ <td valign="top">timeout</td>
+ <td valign="top">Cancel the individual tests if they don't finish
+ in the given time (measured in milliseconds). Ignored if
+ <code>fork</code> is disabled. When running multiple tests
+ inside the same Java VM (see forkMode), timeout applies to the
+ time that all tests use together, not to an individual
+ test.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">maxmemory</td>
+ <td valign="top">Maximum amount of memory to allocate to the forked VM.
+ Ignored if <code>fork</code> is disabled. <strong>Note</strong>:
+ If you get <code>java.lang.OutOfMemoryError: Java heap space</code>
+ in some of your tests then you need to raise the size like
+ <code>maxmemory="128m"</code></td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">jvm</td>
+ <td valign="top">The command used to invoke the Java Virtual Machine,
+ default is 'java'. The command is resolved by
+ <code>java.lang.Runtime.exec()</code>.
+ Ignored if <code>fork</code> is disabled.</td>
+ <td align="center" valign="top">No; default is <code>java</code>.</td>
+ </tr>
+ <tr>
+ <td valign="top">dir</td>
+ <td valign="top">The directory in which to invoke the VM. Ignored if
+ <code>fork</code> is disabled.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">newenvironment</td>
+ <td valign="top">Do not propagate the old environment when new
+ environment variables are specified. Ignored if <code>fork</code> is
+ disabled.</td>
+ <td align="center" valign="top">No; default is <code>false</code>.</td>
+ </tr>
+ <tr>
+ <td valign="top">includeantruntime</td>
+ <td valign="top">Implicitly add the Ant classes required to run
+ the tests and JUnit to the classpath in forked mode.
+ </td>
+ <td align="center" valign="top">No; default is <code>true</code>.</td>
+ </tr>
+ <tr>
+ <td valign="top">showoutput</td>
+ <td valign="top">Send any output generated by tests to Ant's
+ logging system as well as to the formatters. By default only the
+ formatters receive the output.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">outputtoformatters</td>
+ <td valign="top">
+ <em>Since Ant 1.7.0.</em><br/>
+ Send any output generated by tests to the test formatters.
+ This is "true" by default.
+ </td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">tempdir</td>
+ <td valign="top">Where Ant should place temporary files.
+ <em>Since Ant 1.6</em>.</td>
+ <td align="center" valign="top">No; default is the project's base
+ directory.</td>
+ </tr>
+ <tr>
+ <td valign="top">reloading</td>
+ <td valign="top">Whether or not a new classloader should be instantiated for each test case.<br>
+ Ignore if <code>fork</code> is set to true.
+ <em>Since Ant 1.6</em>.</td>
+ <td align="center" valign="top">No; default is <code>true</code>.</td>
+ </tr>
+ <tr>
+ <td valign="top">clonevm</td>
+ <td valign="top">If set to true true, then all system properties
+ and the bootclasspath of the forked Java Virtual Machine will be
+ the same as those of the Java VM running Ant. Default is
+ &quot;false&quot; (ignored if fork is disabled).
+ <em>since Ant 1.7</em></td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">logfailedtests</td>
+ <td valign="top">When Ant executes multiple tests and doesn't stop
+ on errors or failures it will log a "FAILED" message for each
+ failing test to its logging system. If you set this option to
+ false, the message will not be logged and you have to rely on the
+ formatter output to find the failing tests.
+ <em>since Ant 1.8.0</em></td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">enableTestListenerEvents</td>
+ <td valign="top">Whether Ant should send fine grained information
+ about the running tests to Ant's logging system at the verbose
+ level. Such events may be used by custom test listeners to show
+ the progress of tests.<br/>
+ Defaults to <code>false</code>.<br/>
+ Can be overridden by a <a href="#enabletestlistenerevents">magic
+ property</a>.<br/>
+ <em>since Ant 1.8.2</em> - <strong>Ant 1.7.0 to 1.8.1 behave as
+ if this attribute was true by default.</strong></td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">threads</td>
+ <td valign="top">a number of threads to run the tests in.<br/>
+ When this attribute is specified the tests will be split arbitrarily among the threads.<br/>
+ requires that the tests be forked with the <code>perTest</code>
+ option to be operative.<br/>
+ <em>since Ant 1.9.4</em></td>
+ <td align="center" valign="top">No</td>
+ </tr>
+</table>
+
+<p>By using the <code>errorproperty</code> and <code>failureproperty</code>
+attributes, it is possible to
+perform setup work (such as starting an external server), execute the test,
+clean up, and still fail the build in the event of a failure.</p>
+
+<p>The <code>filtertrace</code> attribute condenses error and failure
+stack traces before reporting them.
+It works with both the plain and XML formatters. It filters out any lines
+that begin with the following string patterns:<pre>
+ "junit.framework.TestCase"
+ "junit.framework.TestResult"
+ "junit.framework.TestSuite"
+ "junit.framework.Assert."
+ "junit.swingui.TestRunner"
+ "junit.awtui.TestRunner"
+ "junit.textui.TestRunner"
+ "java.lang.reflect.Method.invoke("
+ "sun.reflect."
+ "org.apache.tools.ant."
+ "org.junit."
+ "junit.framework.JUnit4TestAdapter"
+ " more"</pre>
+
+<h3><a name="nested">Nested Elements</a></h3>
+
+<p>The <code>&lt;junit&gt;</code> task
+supports a nested <code>&lt;classpath&gt;</code>
+element that represents a <a href="../using.html#path">PATH like
+structure</a>.</p>
+
+<p>As of Ant 1.7, this classpath may be used to refer to <code>junit.jar</code>
+as well as your tests and the tested code.
+
+<h4>jvmarg</h4>
+
+<p>If <code>fork</code> is enabled, additional parameters may be passed to
+the new VM via nested <code>&lt;jvmarg&gt;</code> elements. For example:</p>
+
+<pre>
+&lt;junit fork=&quot;yes&quot;&gt;
+ &lt;jvmarg value=&quot;-Djava.compiler=NONE&quot;/&gt;
+ ...
+&lt;/junit&gt;
+</pre>
+
+<p>would run the test in a VM without JIT.</p>
+
+<p><code>&lt;jvmarg&gt;</code> allows all attributes described in <a
+href="../using.html#arg">Command-line Arguments</a>.</p>
+
+<h4>sysproperty</h4>
+
+<p>Use nested <code>&lt;sysproperty&gt;</code> elements to specify system
+properties required by the class. These properties will be made available
+to the VM during the execution of the test (either ANT's VM or the forked VM,
+if <code>fork</code> is enabled).
+The attributes for this element are the same as for <a href="../Tasks/exec.html#env">environment variables</a>.</p>
+
+<pre>
+&lt;junit fork=&quot;no&quot;&gt;
+ &lt;sysproperty key=&quot;basedir&quot; value=&quot;${basedir}&quot;/&gt;
+ ...
+&lt;/junit&gt;
+</pre>
+
+<p>would run the test in ANT's VM and make the <code>basedir</code> property
+available to the test.</p>
+
+<h4>syspropertyset</h4>
+
+<p>You can specify a set of properties to be used as system properties
+with <a href="../Types/propertyset.html">syspropertyset</a>s.</p>
+
+<p><em>since Ant 1.6</em>.</p>
+
+<h4>env</h4>
+
+<p>It is possible to specify environment variables to pass to the
+forked VM via nested <code>&lt;env&gt;</code> elements. For a description
+of the <code>&lt;env&gt;</code> element's attributes, see the
+description in the <a href="../Tasks/exec.html#env">exec</a> task.</p>
+
+<p>Settings will be ignored if <code>fork</code> is disabled.</p>
+
+<h4>bootclasspath</h4>
+
+<p>The location of bootstrap class files can be specified using this
+<a href="../using.html#path">PATH like structure</a> - will be ignored
+if <i>fork</i> is not <code>true</code> or the target VM doesn't
+support it (i.e. Java 1.1).</p>
+
+<p><em>since Ant 1.6</em>.</p>
+
+<h4>permissions</h4>
+<p>Security permissions can be revoked and granted during the execution of the
+class via a nested <i>permissions</i> element. For more information please
+see <a href="../Types/permissions.html">permissions</a></p>
+
+<p>Settings will be ignored if fork is enabled.</p>
+
+<p><em>since Ant 1.6</em>.</p>
+
+<h4>assertions</h4>
+
+<p>You can control enablement of Java 1.4 assertions with an
+<a href="../Types/assertions.html"><tt>&lt;assertions&gt;</tt></a>
+subelement.</p>
+
+<p>Assertion statements are currently ignored in non-forked mode.</p>
+
+<p><em>since Ant 1.6.</em></p>
+
+<h4>formatter</h4>
+
+<p>The results of the tests can be printed in different
+formats. Output will always be sent to a file, unless you set the
+<code>usefile</code> attribute to <code>false</code>.
+The name of the file is determined by the
+name of the test and can be set by the <code>outfile</code> attribute
+of <code>&lt;test&gt;</code>.</p>
+
+<p>There are four predefined formatters - one prints the test results
+in XML format, the other emits plain text. The formatter named
+<code>brief</code> will only print detailed information for testcases
+that failed, while <code>plain</code> gives a little statistics line
+for all test cases. Custom formatters that need to implement
+<code>org.apache.tools.ant.taskdefs.optional.junit.JUnitResultFormatter</code>
+can be specified.</p>
+
+<p>If you use the XML formatter, it may not include the same output
+that your tests have written as some characters are illegal in XML
+documents and will be dropped.</p>
+
+<p>The fourth formatter named <code>failure</code> (since Ant 1.8.0)
+collects all failing <code>testXXX()</code>
+methods and creates a new <code>TestCase</code> which delegates only these
+failing methods. The name and the location can be specified via Java System property or Ant property
+<code>ant.junit.failureCollector</code>. The value has to point to the directory and
+the name of the resulting class (without suffix). It defaults to <i>java-tmp-dir</i>/FailedTests.</p>
+
+<table border="1" cellpadding="2" cellspacing="0">
+<tr>
+ <td width="12%" valign="top"><b>Attribute</b></td>
+ <td width="78%" valign="top"><b>Description</b></td>
+ <td width="10%" valign="top"><b>Required</b></td>
+</tr>
+ <tr>
+ <td valign="top">type</td>
+ <td valign="top">Use a predefined formatter (either
+ <code>xml</code>, <code>plain</code>, <code>brief</code> or <code>failure</code>).</td>
+ <td align="center" rowspan="2">Exactly one of these.</td>
+ </tr>
+ <tr>
+ <td valign="top">classname</td>
+ <td valign="top">Name of a custom formatter class.</td>
+ </tr>
+ <tr>
+ <td valign="top">extension</td>
+ <td valign="top">Extension to append to the output filename.</td>
+ <td align="center">Yes, if <code>classname</code> has been used.</td>
+ </tr>
+ <tr>
+ <td valign="top">usefile</td>
+ <td valign="top">Boolean that determines whether output should be
+ sent to a file.</td>
+ <td align="center">No; default is <code>true</code>.</td>
+ </tr>
+ <tr>
+ <td valign="top">if</td>
+ <td valign="top">Only use formatter <a href="../properties.html#if+unless">if the named property is set</a>.</td>
+ <td align="center">No; default is <code>true</code>.</td>
+ </tr>
+ <tr>
+ <td valign="top">unless</td>
+ <td valign="top">Only use formatter <a href="../properties.html#if+unless">if the named property is <b>not</b> set</a>.</td>
+ <td align="center">No; default is <code>true</code>.</td>
+ </tr>
+</table>
+
+<h4>test</h4>
+
+<p>Defines a single test class.</p>
+
+<table border="1" cellpadding="2" cellspacing="0">
+<tr>
+ <td width="12%" valign="top"><b>Attribute</b></td>
+ <td width="78%" valign="top"><b>Description</b></td>
+ <td width="10%" valign="top"><b>Required</b></td>
+</tr>
+ <tr>
+ <td valign="top">name</td>
+ <td valign="top">Name of the test class.</td>
+ <td align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">methods</td>
+ <td valign="top">Comma-separated list of names of test case methods to execute.
+ <em>Since 1.8.2</em>
+ <p>The <code>methods</code> attribute can be useful in the following scenarios:</p>
+ <ul>
+ <li>A test method has failed and you want to re-run the test method
+ to test a fix or re-run the test under the Java debugger without
+ having to wait for the other (possibly long running) test methods
+ to complete.</li>
+ <li>One or more test methods are running slower than expected and you
+ want to re-run them under a Java profiler (without the overhead
+ of running the profiler whilst other test methods are being
+ executed).</li>
+ </ul>
+ <p>If the <code>methods</code> attribute is used but no test method
+ is specified, then no test method from the suite will be executed.</p>
+ </td>
+ <td align="center">No; default is to run all test methods in the suite.</td>
+ </tr>
+ <tr>
+ <td valign="top">fork</td>
+ <td valign="top">Run the tests in a separate VM.
+ Overrides value set in <code>&lt;junit&gt;</code>.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">haltonerror</td>
+ <td valign="top">Stop the build process if an error occurs during the test
+ run. Overrides value set in <code>&lt;junit&gt;</code>.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+<tr>
+ <td valign="top">errorproperty</td>
+ <td valign="top">The name of a property to set in the event of an error.
+ Overrides value set in <code>&lt;junit&gt;</code>.</td>
+ <td align="center" valign="top">No</td>
+</tr>
+ <tr>
+ <td valign="top">haltonfailure</td>
+ <td valign="top">Stop the build process if a test fails (errors are
+ considered failures as well). Overrides value set in
+ <code>&lt;junit&gt;</code>.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+<tr>
+ <td valign="top">failureproperty</td>
+ <td valign="top">The name of a property to set in the event of a failure
+ (errors are considered failures as well). Overrides value set in
+ <code>&lt;junit&gt;</code>.</td>
+ <td align="center" valign="top">No</td>
+</tr>
+ <tr>
+ <td valign="top">filtertrace</td>
+ <td valign="top">Filter out Junit and Ant stack frames from error and failure stack
+ traces. Overrides value set in <code>&lt;junit&gt;</code>.</td>
+ <td align="center" valign="top">No; default is <code>on</code>.</td>
+ </tr>
+ <tr>
+ <td valign="top">todir</td>
+ <td valign="top">Directory to write the reports to.</td>
+ <td align="center" valign="top">No; default is the current directory.</td>
+ </tr>
+ <tr>
+ <td valign="top">outfile</td>
+ <td valign="top">Base name of the test result. The full filename is
+ determined by this attribute and the extension of
+ <code>formatter</code>.</td>
+ <td align="center" valign="top">No; default is
+ <code>TEST-</code><em>name</em>, where <em>name</em> is the name of
+ the test specified in the <code>name</code> attribute.</td>
+ </tr>
+ <tr>
+ <td valign="top">if</td>
+ <td valign="top">Only run test <a href="../properties.html#if+unless">if the named property is set</a>.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">unless</td>
+ <td valign="top">Only run test <a href="../properties.html#if+unless">if the named property is <b>not</b> set</a>.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">skipNonTests</td>
+ <td valign="top">Do not pass any classes that do not contain JUnit tests to the test runner.
+ This prevents non tests from appearing as test errors in test results.<br />
+ Tests are identified by looking for the <code>@Test</code> annotation on any methods in concrete classes
+ that don't extend <code>junit.framework.TestCase</code>, or for public/protected methods with
+ names starting with 'test' in concrete classes that extend <code>junit.framework.TestCase</code>.
+ Classes marked with the JUnit4 <code>org.junit.runner.RunWith</code> or
+ <code>org.junit.runner.Suite.SuiteClasses</code> annotations are also passed to JUnit for execution,
+ as is any class with a public/protected no-argument <code>suite</code> method.</td>
+ <td align="center" valign="top">No. Default is false.</td>
+ </tr>
+</table>
+
+<p>Tests can define their own formatters via nested
+<code>&lt;formatter&gt;</code> elements.</p>
+
+<h4>batchtest</h4>
+
+<p>Define a number of tests based on pattern matching.</p>
+
+<p><code>batchtest</code> collects the included <a href="../Types/resources.html">resources</a> from any number
+of nested <a
+href="../Types/resources.html#collection">Resource Collection</a>s. It then
+generates a test class name for each resource that ends in
+<code>.java</code> or <code>.class</code>.</p>
+
+<p>Any type of Resource Collection is supported as a nested element,
+prior to Ant 1.7 only <code>&lt;fileset&gt;</code> has been
+supported.</p>
+
+<table border="1" cellpadding="2" cellspacing="0">
+<tr>
+ <td width="12%" valign="top"><b>Attribute</b></td>
+ <td width="78%" valign="top"><b>Description</b></td>
+ <td width="10%" valign="top"><b>Required</b></td>
+</tr>
+ <tr>
+ <td valign="top">fork</td>
+ <td valign="top">Run the tests in a separate VM.
+ Overrides value set in <code>&lt;junit&gt;</code>.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">haltonerror</td>
+ <td valign="top">Stop the build process if an error occurs during the test
+ run. Overrides value set in <code>&lt;junit&gt;</code>.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+<tr>
+ <td valign="top">errorproperty</td>
+ <td valign="top">The name of a property to set in the event of an error.
+ Overrides value set in <code>&lt;junit&gt;</code>.</td>
+ <td align="center" valign="top">No</td>
+</tr>
+ <tr>
+ <td valign="top">haltonfailure</td>
+ <td valign="top">Stop the build process if a test fails (errors are
+ considered failures as well). Overrides value set in
+ <code>&lt;junit&gt;</code>.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+<tr>
+ <td valign="top">failureproperty</td>
+ <td valign="top">The name of a property to set in the event of a failure
+ (errors are considered failures as well). Overrides value set in
+ <code>&lt;junit&gt;</code></td>
+ <td align="center" valign="top">No</td>
+</tr>
+ <tr>
+ <td valign="top">filtertrace</td>
+ <td valign="top">Filter out Junit and Ant stack frames from error and failure stack
+ traces. Overrides value set in <code>&lt;junit&gt;</code>.</td>
+ <td align="center" valign="top">No; default is <code>on</code>.</td>
+ </tr>
+ <tr>
+ <td valign="top">todir</td>
+ <td valign="top">Directory to write the reports to.</td>
+ <td align="center" valign="top">No; default is the current directory.</td>
+ </tr>
+ <tr>
+ <td valign="top">if</td>
+ <td valign="top">Only run tests <a href="../properties.html#if+unless">if the named property is set</a>.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">unless</td>
+ <td valign="top">Only run tests <a href="../properties.html#if+unless">if the named property is <strong>not</strong> set</a>.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">skipNonTests</td>
+ <td valign="top">Do not pass any classes that do not contain JUnit tests to the test runner.
+ This prevents non tests from appearing as test errors in test results.<br />
+ Tests are identified by looking for the <code>@Test</code> annotation on any methods in concrete classes
+ that don't extend <code>junit.framework.TestCase</code>, or for public/protected methods with
+ names starting with 'test' in concrete classes that extend <code>junit.framework.TestCase</code>.
+ Classes marked with the JUnit4 <code>org.junit.runner.RunWith</code> or
+ <code>org.junit.runner.Suite.SuiteClasses</code> annotations are also passed to JUnit for execution,
+ as is any class with a public/protected no-argument <code>suite</code> method.</td>
+ <td align="center" valign="top">No. Default is false.</td>
+ </tr>
+</table>
+
+<p>Batchtests can define their own formatters via nested
+<code>&lt;formatter&gt;</code> elements.</p>
+
+<h3>Forked tests and <code>tearDown</code></h3>
+
+<p>If a forked test runs into a timeout, Ant will terminate the Java
+ VM process it has created, which probably means the
+ test's <code>tearDown</code> method will never be called. The same
+ is true if the forked VM crashes for some other reason.</p>
+
+<p>Starting with Ant 1.8.0, a special formatter is distributed with
+ Ant that tries to load the testcase that was in the forked VM and
+ invoke that class' <code>tearDown</code> method. This formatter has
+ the following limitations:</p>
+
+<ul>
+ <li>It runs in the same Java VM as Ant itself, this is a different
+ Java VM than the one that was executing the test and it may see a
+ different classloader (and thus may be unable to load the test
+ class).</li>
+ <li>It cannot determine which test was run when the timeout/crash
+ occurred if the forked VM was running multiple test. I.e. the
+ formatter cannot work with any <code>forkMode</code> other
+ than <code>perTest</code> and it won't do anything if the test
+ class contains a <code>suite()</code> method.</li>
+</ul>
+
+<p>If the formatter recognizes an incompatible <code>forkMode</code>
+ or a <code>suite</code> method or fails to load the test class it
+ will silently do nothing.</p>
+
+<p>The formatter doesn't have any effect on tests that were not
+ forked or didn't cause timeouts or VM crashes.</p>
+
+<p>To enable the formatter, add a <code>formatter</code> like</p>
+
+<pre>
+&lt;formatter classname="org.apache.tools.ant.taskdefs.optional.junit.TearDownOnVmCrash"
+ usefile="false"/&gt;
+</pre>
+
+<p>to your <code>junit</code> task.</p>
+
+<h3><a name="enabletestlistenerevents"><code>ant.junit.enabletestlistenerevents</code></a>
+ magic property</h3>
+
+<p><em>Since Ant 1.8.2</em> the <code>enableTestListenerEvents</code>
+ attribute of the task controls whether fine grained logging messages
+ will be sent to the task's verbose log. In addition to this
+ attribute Ant will consult the
+ property <code>ant.junit.enabletestlistenerevents</code> and the
+ value of the property overrides the setting of the attribute.</p>
+
+<p>This property exists so that containers running Ant that depend on
+ the additional logging events can ensure they will be generated even
+ if the build file disables them.</p>
+
+<h3>Examples</h3>
+
+<pre>
+&lt;junit&gt;
+ &lt;test name="my.test.TestCase"/&gt;
+&lt;/junit&gt;
+</pre>
+
+<p>Runs the test defined in <code>my.test.TestCase</code> in the same
+VM. No output will be generated unless the test fails.</p>
+
+<pre>
+&lt;junit printsummary="yes" fork="yes" haltonfailure="yes"&gt;
+ &lt;formatter type="plain"/&gt;
+ &lt;test name="my.test.TestCase"/&gt;
+&lt;/junit&gt;
+</pre>
+
+<p>Runs the test defined in <code>my.test.TestCase</code> in a
+separate VM. At the end of the test, a one-line summary will be
+printed. A detailed report of the test can be found in
+<code>TEST-my.test.TestCase.txt</code>. The build process will be
+stopped if the test fails.</p>
+
+<pre>
+&lt;junit printsummary="yes" haltonfailure="yes"&gt;
+ &lt;classpath&gt;
+ &lt;pathelement location="${build.tests}"/&gt;
+ &lt;pathelement path="${java.class.path}"/&gt;
+ &lt;/classpath&gt;
+
+ &lt;formatter type="plain"/&gt;
+
+ &lt;test name="my.test.TestCase" haltonfailure="no" outfile="result"&gt;
+ &lt;formatter type="xml"/&gt;
+ &lt;/test&gt;
+
+ &lt;batchtest fork="yes" todir="${reports.tests}"&gt;
+ &lt;fileset dir="${src.tests}"&gt;
+ &lt;include name="**/*Test*.java"/&gt;
+ &lt;exclude name="**/AllTests.java"/&gt;
+ &lt;/fileset&gt;
+ &lt;/batchtest&gt;
+&lt;/junit&gt;
+</pre>
+
+<p>Runs <code>my.test.TestCase</code> in the same VM, ignoring the
+given CLASSPATH; only a warning is printed if this test fails. In
+addition to the plain text test results, for this test a XML result
+will be output to <code>result.xml</code>.
+Then, for each matching file in the directory defined for
+<code>${src.tests}</code> a
+test is run in a separate VM. If a test fails, the build process is
+aborted. Results are collected in files named
+<code>TEST-</code><em>name</em><code>.txt</code> and written to
+<code>${reports.tests}</code>.</p>
+
+<pre>
+&lt;target name=&quot;test&quot;&gt;
+ &lt;property name=&quot;collector.dir&quot; value=&quot;${build.dir}/failingTests&quot;/&gt;
+ &lt;property name=&quot;collector.class&quot; value=&quot;FailedTests&quot;/&gt;
+ &lt;!-- Delete 'old' collector classes --&gt;
+ &lt;delete&gt;
+ &lt;fileset dir=&quot;${collector.dir}&quot; includes=&quot;${collector.class}*.class&quot;/&gt;
+ &lt;/delete&gt;
+ &lt;!-- compile the FailedTests class if present --&gt;
+ &lt;javac srcdir=&quot;${collector.dir}&quot; destdir=&quot;${collector.dir}&quot;/&gt;
+ &lt;available file=&quot;${collector.dir}/${collector.class}.class&quot; property=&quot;hasFailingTests&quot;/&gt;
+ &lt;junit haltonerror=&quot;false&quot; haltonfailure=&quot;false&quot;&gt;
+ &lt;sysproperty key=&quot;ant.junit.failureCollector&quot; value=&quot;${collector.dir}/${collector.class}&quot;/&gt;
+ &lt;classpath&gt;
+ &lt;pathelement location=&quot;${collector.dir}&quot;/&gt;
+ &lt;/classpath&gt;
+ &lt;batchtest todir=&quot;${collector.dir}&quot; unless=&quot;hasFailingTests&quot;&gt;
+ &lt;fileset dir=&quot;${collector.dir}&quot; includes=&quot;**/*.java&quot; excludes=&quot;**/${collector.class}.*&quot;/&gt;
+ &lt;!-- for initial creation of the FailingTests.java --&gt;
+ &lt;formatter type=&quot;failure&quot;/&gt;
+ &lt;!-- I want to see something ... --&gt;
+ &lt;formatter type=&quot;plain&quot; usefile=&quot;false&quot;/&gt;
+ &lt;/batchtest&gt;
+ &lt;test name=&quot;FailedTests&quot; if=&quot;hasFailingTests&quot;&gt;
+ &lt;!-- update the FailingTests.java --&gt;
+ &lt;formatter type=&quot;failure&quot;/&gt;
+ &lt;!-- again, I want to see something --&gt;
+ &lt;formatter type=&quot;plain&quot; usefile=&quot;false&quot;/&gt;
+ &lt;/test&gt;
+ &lt;/junit&gt;
+&lt;/target&gt;
+</pre>
+<p>On the first run all tests are collected via the <code>&lt;batchtest/&gt;</code>
+element. Its <code>plain</code> formatter shows the output on the console. The
+<code>failure</code> formatter creates a java source file in
+<code>${build.dir}/failingTests/FailedTests.java</code> which extends
+<code>junit.framework.TestCase</code> and returns from a <code>suite()</code>
+method a test suite for the failing tests. <br/>
+On a second run the collector class exists and instead of the <code>&lt;batchtest/&gt;</code>
+the single <code>&lt;test/&gt;</code> will run. So only the failing test cases are re-run.
+The two nested formatters are for displaying (for the user) and for updating the collector
+class.
+</p>
+
+
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/junitreport.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/junitreport.html
new file mode 100644
index 00000000..365920b2
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/junitreport.html
@@ -0,0 +1,214 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+<head>
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>JUnitReport Task</title>
+</head>
+
+<body>
+
+<h2><a name="junitreport">JUnitReport</a></h2>
+Merge the individual XML files generated by the JUnit task and eventually apply
+a stylesheet on the resulting merged document to provide a browsable report of
+the testcases results.
+<p><strong>Note:</strong> This task depends on external libraries not included in
+the Apache Ant distribution. See <a href="../install.html#librarydependencies">
+Library Dependencies</a> for more information.</p>
+
+<h3>Requirements</h3>
+
+<p>The task needs Apache <a
+href="http://xml.apache.org/xalan-j/">Xalan 2.4.1+ or Xalan XSLTC</a>
+(JDK 1.4 contains a version of Xalan-J 2.x while JDK 1.5 ships with a
+version of XSLTC). Starting from JDK 1.4.2-01 it ships with a bundled
+Xalan-J 2.4.1+, meaning that JDK version prior to 1.4.2-01 won't work
+out of the box. The table below summarize the compatibility status.
+</p>
+<table border="1" cellpadding="2" cellspacing="0">
+<tr><th>Xalan</th><th>Sun JDK Bundle</th><th>Status<th></tr>
+<tr><td>2.4.1+</td><td>JDK 1.4.2-01+</td><td>OK</td></tr>
+<tr><td>XSLTC</td><td>JDK 1.5.x</td><td>OK</td></tr>
+<tr><td>2.x</td><td>JDK 1.4.x</td><td>DEPRECATED<br><i>Use ${ant.home}/etc/junit-frames-xalan1.xsl
+<br> Upgrade Xalan using the JDK endorsement mechanism</i></td></tr>
+</table>
+
+<p>With Ant 1.6.2 we had to decide between supporting Xalan-J 1/Xalan J 2.4.1-
+and Xalan 2.4.1+/XSLTC, since there was no way to support both couples at the same
+time.</p>
+<p>With Ant 1.7 we had to drop support Xalan-J 1, since Xalan-J 1 has not
+available anymore for quite some time.</p>
+
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td width="12%" valign="top"><b>Attribute</b></td>
+ <td width="78%" valign="top"><b>Description</b></td>
+ <td width="10%" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">tofile</td>
+ <td valign="top">The name of the XML file that will aggregate all individual
+ XML testsuite previously generated by the JUnit task.</td>
+ <td align="center" valign="top">No. Default to TESTS-TestSuites.xml</td>
+ </tr>
+ <tr>
+ <td valign="top">todir</td>
+ <td valign="top">The directory where should be written the file resulting
+ from the individual XML testsuite aggregation.</td>
+ <td align="center" valign="top">No. Default to current directory</td>
+ </tr>
+</table>
+<h3><a name="nested">Nested Elements</a></h3>
+<h4>fileset</h4>
+<p><code>junitreport</code> collects individual xml files generated by the JUnit
+task using the nested <a href="../Types/fileset.html"><code>&lt;FileSet&gt;</code></a>
+element.</p>
+<h4>report</h4>
+<p>Generate a browsable report based on the document created by the merge.</p>
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td width="12%" valign="top"><b>Attribute</b></td>
+ <td width="78%" valign="top"><b>Description</b></td>
+ <td width="10%" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">format</td>
+ <td valign="top">The format of the generated report. Must be &quot;noframes&quot;
+ or &quot;frames&quot;.</td>
+ <td align="center" valign="top">No, default to &quot;frames&quot;</td>
+ </tr>
+ <tr>
+ <td valign="top">styledir</td>
+ <td valign="top">The directory where the stylesheets are defined. They must
+ be conforming to the following conventions:
+ <ul>
+ <li>frames format: the stylesheet must be named <i>junit-frames.xsl</i>.</li>
+ <li>noframes format: the stylesheet must be named <i>junit-noframes.xsl</i>.</li>
+ </ul>
+ </td>
+ <td align="center" valign="top">No. Default to embedded stylesheets.</td>
+ </tr>
+ <tr>
+ <td valign="top">todir</td>
+ <td valign="top">The directory where the files resulting from the
+ transformation should be written to.</td>
+ <td align="center" valign="top">No. Default to current directory</td>
+ </tr>
+</table>
+<p> Ant assumes the following concerning the <tt>frames</tt> and <tt>noframes</tt> formats :</p>
+<p>The <tt>frames</tt> format uses
+a stylesheet which is generating output <em>only</em> by redirecting.</p>
+<p>The
+<tt>noframes</tt> format does not use redirecting and generates one
+file called <tt>junit-noframes.html</tt>.</p>
+<p>Custom versions of <tt>junit-frames.xsl</tt> or <tt>junit-noframes.xsl</tt> must adhere to the above conventions.</p>
+
+<h3>Nested Element of the report tag</h3>
+<h4>param</h4>
+<em>Since Ant 1.7</em>the report tag supports nested param tags.
+These tags can pass XSL parameters to the stylesheet.
+<h3>Parameters</h3>
+<table width="60%" border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">name</td>
+ <td valign="top">Name of the XSL parameter</td>
+ <td align="center" valign="top">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">expression</td>
+ <td valign="top">Text value to be placed into the param.<br>
+ Was originally intended to be an XSL expression.</td>
+ <td align="center" valign="top">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">if</td>
+ <td valign="top">The param will only be passed <a href="../properties.html#if+unless">if this property is set</a>.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">unless</td>
+ <td valign="top">The param will not be passed <a href="../properties.html#if+unless">if this property is set</a>.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+</table>
+
+<p>The built-in stylesheets support the following parameters:</p>
+<table width="60%" border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>XSL-Parameter</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">TITLE</td>
+ <td valign="top">Title used in &lt;title&gt; and &lt;h1&gt; tags</td>
+ <td align="center" valign="top">No. Defaults to <i>Unit Test Results.</i></td>
+ </tr>
+</table>
+
+<h4>classpath</h4>
+<p><em>Since Ant 1.9.5.</em>
+Like for the <a href="../CoreTasks/style.html#classpath">XSLT task</a>,
+a nested &lt;classpath&gt; will be used to load the processor.</p>
+
+<h4>factory</h4>
+<p><em>Since Ant 1.9.5.</em>
+Like for the <a href="../CoreTasks/style.html#factory">XSLT task</a>,
+a nested &lt;factory&gt; can be used to specify factory settings.</p>
+
+
+<h3>Example of report</h3>
+<blockquote>
+ <pre>&lt;junitreport todir=&quot;./reports&quot;&gt;
+ &lt;fileset dir=&quot;./reports&quot;&gt;
+ &lt;include name=&quot;TEST-*.xml&quot;/&gt;
+ &lt;/fileset&gt;
+ &lt;report format=&quot;frames&quot; todir=&quot;./report/html&quot;/&gt;
+&lt;/junitreport&gt;
+</pre>
+</blockquote>
+<p>would generate a <tt>TESTS-TestSuites.xml</tt> file in the directory <tt>reports</tt> and
+generate the default framed report in the directory <tt>report/html</tt>.</p>
+<h3>Example of report with xsl params</h3>
+<blockquote>
+ <pre>
+&lt;junitreport todir="${outputdir}"&gt;
+ &lt;fileset dir="${jrdir}"&gt;
+ &lt;include name="TEST-*.xml"/&gt;
+ &lt;/fileset&gt;
+ &lt;report todir="${outputdir}/html"
+ styledir="junitreport"
+ format="frames"&gt;
+ &lt;param name="key1" expression="value1"/&gt;
+ &lt;param name="key2" expression="value2"/&gt;
+ &lt;/report&gt;
+&lt;/junitreport&gt;
+ </pre>
+ </blockquote>
+<p>This example requires a file called <tt>junitreport/junit-frames.xsl</tt>.
+ The XSL parameters key1 and key2 will be passed to the XSL transformation.</p>
+
+</body>
+
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/length.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/length.html
new file mode 100644
index 00000000..18c62c76
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/length.html
@@ -0,0 +1,127 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Length Task</title>
+</head>
+
+<body>
+
+<h2>Length</h2>
+<h3>Description</h3>
+<p>Display or set a property containing length information for
+ a string, a file, or one or more nested
+ <a href="../Types/resources.html#collection">Resource Collection</a>s.
+ Can also be used as a condition. <b>Since Apache Ant 1.6.3</b></p>
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">property</td>
+ <td valign="top">The property to set. If omitted
+ the results are written to the log. Ignored when
+ processing as a condition.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">file</td>
+ <td valign="top">Single file whose length to report.</td>
+ <td valign="top" align="center" rowspan="3">One of these,
+ or one or more nested filesets</td>
+ </tr>
+ <tr>
+ <td valign="top">resource</td>
+ <td valign="top">Single resource whose length to report (using extended
+ <a href="../properties.html#propertyHelper">properties handling</a>).
+ <em>Since Ant 1.8.1</em>
+ </td>
+ </tr>
+ <tr>
+ <td valign="top">string</td>
+ <td valign="top">The string whose length to report.</td>
+ </tr>
+ <tr>
+ <td valign="top">mode</td>
+ <td valign="top">File length mode; when &quot;all&quot; the resulting
+ value is the sum of all included resources' lengths; when &quot;each&quot;
+ the task outputs the absolute path and length of each included resource,
+ one per line. Ignored when processing as a condition.</td>
+ <td valign="top" align="center">No; default is &quot;all&quot;</td>
+ </tr>
+ <tr>
+ <td valign="top">trim</td>
+ <td valign="top">Whether to trim when operating on a string. Default <i>false</i>.</td>
+ <td valign="top" align="center">No; only valid when string is set</td>
+ </tr>
+ <tr>
+ <td valign="top">length</td>
+ <td valign="top">Comparison length for processing as a condition.</td>
+ <td valign="top" align="center">Yes, in condition mode</td>
+ </tr>
+ <tr>
+ <td valign="top">when</td>
+ <td valign="top">Comparison type: "equal", "eq", "greater", "gt", "less",
+ "lt", "ge" (greater or equal), "ne" (not equal), "le" (less or equal)
+ for use when operating as a condition.</td>
+ <td valign="top" align="center">No; default is "equal"</td>
+ </tr>
+</table>
+
+<h3>Parameters specified as nested elements</h3>
+
+<h4>Resource Collections</h4>
+<p>You can include resources via nested
+ <a href="../Types/resources.html#collection">Resource Collection</a>s.</p>
+
+<h3>Examples</h3>
+
+<pre>&lt;length string=&quot;foo&quot; property=&quot;length.foo&quot; /&gt;
+</pre>
+<p>Stores the length of the string &quot;foo&quot; in the property named
+<i>length.foo</i>.</p>
+
+<pre>&lt;length file=&quot;bar&quot; property=&quot;length.bar&quot; /&gt;
+</pre>
+<p>Stores the length of file &quot;bar&quot; in the property named
+<i>length.bar</i>.</p>
+
+<pre>
+&lt;length property=&quot;length&quot; mode=&quot;each&quot;&gt;
+ &lt;fileset dir=&quot;.&quot; includes=&quot;foo,bar&quot;/&gt;
+&lt;/length&gt;
+</pre>
+<p>Writes the file paths of <i>foo</i> and <i>bar</i> and their length into
+the property <i>length</i>.</p>
+
+<pre>
+&lt;length property=&quot;length&quot; mode=&quot;all&quot;&gt;
+ &lt;fileset dir=&quot;.&quot; includes=&quot;foo,bar&quot;/&gt;
+&lt;/length&gt;
+</pre>
+<p>Adds the length of <i>foo</i> and <i>bar</i> and stores the result in property <i>length</i>.</p>
+
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/loadfile.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/loadfile.html
new file mode 100644
index 00000000..59291ed3
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/loadfile.html
@@ -0,0 +1,133 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+<head>
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>LoadFile Task</title>
+</head>
+
+<body>
+
+
+<h2><a name="loadfile">LoadFile</a></h2>
+<h3>Description</h3>
+<p>
+Specialization of <a href="loadresource.html">loadresource</a> that
+works on files exclusively and provides a srcFile attribute for
+convenience. Unless an encoding is specified, the encoding of the
+current locale is used.
+</p>
+<p>If the resource content is empty (maybe after processing a filterchain)
+the property is not set.</p>
+
+
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">srcFile</td>
+ <td valign="top">source file</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">property</td>
+ <td valign="top">property to save to</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">encoding</td>
+ <td valign="top">encoding to use when loading the file</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">failonerror</td>
+ <td valign="top">Whether to halt the build on failure</td>
+ <td align="center" valign="top">No, default "true"</td>
+ </tr>
+ <tr>
+ <td valign="top">quiet</td>
+ <td valign="top">Do not display a diagnostic message (unless Apache Ant has been
+ invoked with the <code>-verbose</code> or <code>-debug</code>
+ switches) or modify the exit status to reflect an error. Setting this to
+ "true" implies setting failonerror to "false".
+ <em>Since Ant 1.7.0.</em>
+ </td>
+ <td align="center" valign="top">No, default "false"</td>
+ </tr>
+
+</table>
+<p>
+The LoadFile task supports nested <a href="../Types/filterchain.html">
+FilterChain</a>s.
+
+<h3>Examples</h3>
+<pre> &lt;loadfile property="message"
+ srcFile="message.txt"/&gt;
+</pre>
+Load file message.txt into property "message"; an <tt>&lt;echo&gt;</tt>
+can print this. This is identical to
+<pre> &lt;loadresource property="message"&gt;
+ &lt;file file="message.txt"/&gt;
+ &lt;/loadresource&gt;
+</pre>
+</p>
+
+<pre> &lt;loadfile property="encoded-file"
+ srcFile="loadfile.xml"
+ encoding="ISO-8859-1"/&gt;
+</pre>
+Load a file using the latin-1 encoding
+
+<pre> &lt;loadfile
+ property="optional.value"
+ srcFile="optional.txt"
+ failonerror="false"/&gt;
+</pre>
+Load a file, don't fail if it is missing (a message is printed, though)
+
+<pre> &lt;loadfile
+ property="mail.recipients"
+ srcFile="recipientlist.txt"&gt;
+ &lt;filterchain&gt;
+ &lt;<a href="../Types/filterchain.html#striplinebreaks">striplinebreaks</a>/&gt;
+ &lt;/filterchain&gt;
+ &lt;/loadfile&gt;
+</pre>
+Load a property which can be used as a parameter for another task (in this case mail),
+merging lines to ensure this happens.
+
+<pre> &lt;loadfile
+ property="system.configuration.xml"
+ srcFile="configuration.xml"&gt;
+ &lt;filterchain&gt;
+ &lt;<a href="../Types/filterchain.html#expandproperties">expandproperties</a>/&gt;
+ &lt;/filterchain&gt;
+ &lt;/loadfile&gt;
+</pre>
+Load an XML file into a property, expanding all properties declared
+in the file in the process.
+
+
+
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/loadproperties.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/loadproperties.html
new file mode 100644
index 00000000..69fa23a6
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/loadproperties.html
@@ -0,0 +1,140 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+<head>
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>LoadProperties Task</title>
+</head>
+
+<body>
+
+
+<h2><a name="loadproperties">LoadProperties</a></h2>
+<h3>Description</h3>
+<p>
+Load a file's contents as Apache Ant properties. This is equivalent
+to <code>&lt;property file|resource=&quot;...&quot;/&gt;</code> except that it
+supports nested <code>&lt;filterchain&gt;</code> elements.
+Also if the file is missing, the build is halted with an error, rather
+than a warning being printed.
+</p>
+
+<p><strong>Note:</strong> the default value of this
+task's <code>prefixValues</code> attribute is different from the
+default value of the same attribute in
+the <a href="property.html"><code>&lt;property&gt;</code></a>
+task.</p>
+
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">srcFile</td>
+ <td valign="top">source file</td>
+ <td valign="top" rowspan="2" align="center">One of these or a
+ nested resource</td>
+ </tr>
+ <tr>
+ <td valign="top">resource</td>
+ <td valign="top">the resource name of the property file</td>
+ </tr>
+ <tr>
+ <td valign="top">encoding</td>
+ <td valign="top">encoding to use when loading the file</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">classpath</td>
+ <td valign="top">the classpath to use when looking up a resource.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">classpathref</td>
+ <td valign="top">the classpath to use when looking up a resource,
+ given as <a href="../using.html#references">reference</a>
+ to a <code>&lt;path&gt;</code> defined elsewhere..</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">prefix</td>
+ <td valign="top">Prefix to apply to loaded properties;
+ a "." is appended to the prefix if not specified. <em>Since Ant 1.8.1</em></td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">prefixValues</td>
+ <td valign="top">Whether to apply the prefix when expanding the
+ right hand side of the properties.
+ <em>Since Ant 1.8.2</em></td>
+ <td align="center" valign="top">No (default=<tt>true</tt>)</td>
+ </tr>
+</table>
+
+<h3>Parameters specified as nested elements</h3>
+
+<h4>any <a href="../Types/resources.html">resource</a> or single element
+resource collection</h4>
+
+<p>The specified resource will be used as src. <em>Since Ant 1.7</em></p>
+
+<h4><a href="../Types/filterchain.html">FilterChain</a></h4>
+
+<h4>classpath</h4>
+
+<p>for use with the <i>resource</i> attribute.</p>
+
+<h3>Examples</h3>
+<pre> &lt;loadproperties srcFile="file.properties"/&gt;
+</pre>
+or
+<pre>
+ &lt;loadproperties&gt;
+ &lt;file file="file.properties"/&gt;
+ &lt;/loadproperties&gt;
+</pre>
+Load contents of file.properties as Ant properties.
+
+<pre> &lt;loadproperties srcFile="file.properties"&gt;
+ &lt;filterchain&gt;
+ &lt;<a href="../Types/filterchain.html#linecontains">linecontains</a>&gt;
+ &lt;contains value=&quot;import.&quot;/&gt;
+ &lt;/linecontains&gt;
+ &lt;/filterchain&gt;
+ &lt;/loadproperties&gt;
+</pre>
+Read the lines that contain the string &quot;import.&quot;
+from the file &quot;file.properties&quot; and load them as
+Ant properties.
+
+<pre>
+ &lt;loadproperties&gt;
+ &lt;<a href="../Types/resources.html#gzipresource">gzipresource</a>&gt;
+ &lt;<a href="../Types/resources.html#url">url</a> url="http://example.org/url.properties.gz"/&gt;
+ &lt;/gzipresource&gt;
+ &lt;/loadproperties&gt;
+</pre>
+Load contents of http://example.org/url.properties.gz, uncompress it
+on the fly and load the contents as Ant properties.
+
+
+
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/loadresource.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/loadresource.html
new file mode 100644
index 00000000..f2b20c06
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/loadresource.html
@@ -0,0 +1,93 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+<head>
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>LoadResource Task</title>
+</head>
+
+<body>
+
+
+<h2><a name="loadresource">LoadResource</a></h2>
+
+<p><em>Since Apache Ant 1.7</em></p>
+
+<h3>Description</h3>
+<p>
+Load a text resource into a single property. Unless an encoding is
+specified, the encoding of the current locale is used. Resources to
+load are specified as nested <a
+href="../Types/resources.html">resource</a> elements or single
+element resource collections. If the resource content is empty (maybe after
+processing a filterchain) the property is not set.
+</p>
+
+<p>Since properties are immutable, the task will not change the value
+ of an existing property.</p>
+
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">property</td>
+ <td valign="top">property to save to</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">encoding</td>
+ <td valign="top">encoding to use when loading the resource</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">failonerror</td>
+ <td valign="top">Whether to halt the build on failure</td>
+ <td align="center" valign="top">No, default "true"</td>
+ </tr>
+ <tr>
+ <td valign="top">quiet</td>
+ <td valign="top">Do not display a diagnostic message (unless Ant has been
+ invoked with the <code>-verbose</code> or <code>-debug</code>
+ switches) or modify the exit status to reflect an error. Setting this to
+ "true" implies setting failonerror to "false".
+ </td>
+ <td align="center" valign="top">No, default "false"</td>
+ </tr>
+</table>
+<p>
+The LoadResource task supports nested <a href="../Types/filterchain.html">
+FilterChain</a>s.
+
+<h3>Examples</h3>
+<pre>
+&lt;loadresource property="homepage"&gt;
+ &lt;url url="http://ant.apache.org/index.html"/&gt;
+&lt;/loadresource&gt;
+</pre>
+Load the entry point of Ant's homepage into property "homepage"; an
+<tt>&lt;echo&gt;</tt> can print this.
+
+<p>For more examples see the <a href="loadfile.html">loadfile</a> task.</p>
+
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/local.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/local.html
new file mode 100644
index 00000000..c7ed8fc4
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/local.html
@@ -0,0 +1,186 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Local Task</title>
+</head>
+
+<body>
+
+<h2>Local</h2>
+<h3>Description</h3>
+<p>Adds a local property to the current scope. Property scopes exist at Apache Ant's
+various "block" levels. These include targets as well as the
+<a href="parallel.html">Parallel</a> and <a href="sequential.html">Sequential</a>
+task containers (including <a href="macrodef.html">Macrodef</a> bodies). A local
+property at a given scope "shadows" properties of the same name at higher scopes,
+including the global scope. Note that using the Local task at the global
+level effectively makes the property local to the "anonymous target" in which
+top-level operations are carried out; it will not be defined for other targets
+in the buildfile. <b>Since Ant 1.8</b></p>
+
+<p>A property is made local if the <code>&lt;local&gt;</code> task
+ precedes its definition. See the examples section.</p>
+
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">name</td>
+ <td valign="top">The property to declare in the current scope</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+</table>
+
+<h3>Examples</h3>
+
+<h4>Temporarily shadow a global property's value</h4>
+
+<pre>
+ &lt;property name="foo" value="foo"/&gt;
+
+ &lt;target name="step1"&gt;
+ &lt;echo&gt;Before local: foo is ${foo}&lt;/echo&gt;
+ &lt;local name="foo"/&gt;
+ &lt;property name="foo" value="bar"/&gt;
+ &lt;echo&gt;After local: foo is ${foo}&lt;/echo&gt;
+ &lt;/target&gt;
+
+ &lt;target name="step2" depends="step1"&gt;
+ &lt;echo&gt;In step2: foo is ${foo}&lt;/echo&gt;
+ &lt;/target&gt;
+</pre>
+
+<p>outputs</p>
+
+<pre>
+step1:
+ [echo] Before local: foo is foo
+ [echo] After local: foo is bar
+
+step2:
+ [echo] In step2: foo is foo
+</pre>
+
+<p>here the local-task shadowed the global definition
+ of <code>foo</code> for the remainder of the target step1.</p>
+
+<h4>Creating thread local properties</h4>
+
+<pre>
+ &lt;property name="foo" value="foo"/&gt;
+
+ &lt;parallel&gt;
+ &lt;echo&gt;global 1: foo is ${foo}&lt;/echo&gt;
+ &lt;sequential&gt;
+ &lt;local name="foo"/&gt;
+ &lt;property name="foo" value="bar.1"/&gt;
+ &lt;echo&gt;First sequential: foo is ${foo}&lt;/echo&gt;
+ &lt;/sequential&gt;
+ &lt;sequential&gt;
+ &lt;sleep seconds="1"/&gt;
+ &lt;echo&gt;global 2: foo is ${foo}&lt;/echo&gt;
+ &lt;/sequential&gt;
+ &lt;sequential&gt;
+ &lt;local name="foo"/&gt;
+ &lt;property name="foo" value="bar.2"/&gt;
+ &lt;echo&gt;Second sequential: foo is ${foo}&lt;/echo&gt;
+ &lt;/sequential&gt;
+ &lt;echo&gt;global 3: foo is ${foo}&lt;/echo&gt;
+ &lt;/parallel&gt;
+</pre>
+
+<p>outputs something similar to</p>
+
+<pre>
+ [echo] global 3: foo is foo
+ [echo] global 1: foo is foo
+ [echo] First sequential: foo is bar.1
+ [echo] Second sequential: foo is bar.2
+ [echo] global 2: foo is foo
+</pre>
+
+<h4>Use inside macrodef</h4>
+
+<p>This probably is where local can be applied in the most useful
+ way. If you needed a "temporary property" inside a macrodef in Ant
+ prior to Ant 1.8.0 you had to try to come up with a property name
+ that would be unique across macro invocations.</p>
+
+<p>Say you wanted to write a macro that created the parent directory
+ of a given file. A naive approach would be:</p>
+
+<pre>
+ &lt;macrodef name="makeparentdir"&gt;
+ &lt;attribute name="file"/&gt;
+ &lt;sequential&gt;
+ &lt;dirname property="parent" file="@{file}"/&gt;
+ &lt;mkdir dir="${parent}"/&gt;
+ &lt;/sequential&gt;
+ &lt;/macrodef&gt;
+ &lt;makeparentdir file="some-dir/some-file"/&gt;
+</pre>
+
+<p>but this would create a global property "parent" on the first
+ invocation - and since properties are not mutable, any subsequent
+ invocation will see the same value and try to create the same
+ directory as the first invocation.</p>
+
+<p>The recommendation prior to Ant 1.8.0 was to use a property name
+ based on one of the macro's attributes, like</p>
+
+<pre>
+ &lt;macrodef name="makeparentdir"&gt;
+ &lt;attribute name="file"/&gt;
+ &lt;sequential&gt;
+ &lt;dirname property="parent.@{file}" file="@{file}"/&gt;
+ &lt;mkdir dir="${parent.@{file}}"/&gt;
+ &lt;/sequential&gt;
+ &lt;/macrodef&gt;
+</pre>
+
+<p>Now invocations for different files will set different properties
+ and the directories will get created. Unfortunately this "pollutes"
+ the global properties space. In addition it may be hard to come up
+ with unique names in some cases.</p>
+
+<p>Enter <code>&lt;local&gt;</code>:</p>
+
+<pre>
+ &lt;macrodef name="makeparentdir"&gt;
+ &lt;attribute name="file"/&gt;
+ &lt;sequential&gt;
+ &lt;local name="parent"/&gt;
+ &lt;dirname property="parent" file="@{file}"/&gt;
+ &lt;mkdir dir="${parent}"/&gt;
+ &lt;/sequential&gt;
+ &lt;/macrodef&gt;
+</pre>
+
+<p>Each invocation gets its own property name "parent" and there will
+ be no global property of that name at all.</p>
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/macrodef.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/macrodef.html
new file mode 100644
index 00000000..60b30720
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/macrodef.html
@@ -0,0 +1,385 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+ <head>
+ <meta http-equiv="Content-Language" content="en-us"></meta>
+ <link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+ <title>MacroDef Task</title>
+ </head>
+
+ <body>
+
+ <h2><a name="macrodef">MacroDef</a></h2>
+ <h3>Description</h3>
+ <p>
+ This defines a new task using a <code>&lt;sequential&gt;</code>
+ nested task as a template. Nested elements <code>&lt;attribute&gt;</code> and
+ <code>&lt;element&gt;</code> are used to specify attributes and elements of
+ the new task. These get substituted into the <code>&lt;sequential&gt;</code>
+ task when the new task is run.
+ </p>
+ <h3>Note</h3>
+ <p>
+ You can also use <i>prior defined</i> attributes for default-values in
+ other attributes. See the examples.
+ </p>
+ <p>
+ <em>since Apache Ant 1.6</em>
+ </p>
+ <h3>Parameters</h3>
+ <table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">name</td>
+ <td valign="top">The name of the new definition.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">uri</td>
+ <td valign="top">
+ The uri that this definition should live in.
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">description</td>
+ <td valign="top">A description of the macrodef
+ (for documentation purposes only).
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">backtrace</td>
+ <td valign="top">
+ This controls the error traceback if there is an
+ error detected when running the macro. If this is
+ set to true, there will be an error trackback, if false
+ there will not be one. <em>Since Ant 1.7</em>.
+ </td>
+ <td valign="top" align="center">No; default <em>true</em></td>
+ </tr>
+ </table>
+ <h3>Parameters specified as nested elements</h3>
+ <h4>attribute</h4>
+ <p>
+ This is used to specify attributes of the new task. The values
+ of the attributes get substituted into the templated task.
+ The attributes will be required attributes unless a default
+ value has been set.
+ </p>
+ <p>
+ This attribute is placed in the body of the templated
+ task using a notation similar to the ant property notation
+ - @{attribute name}. (May be remembered as "put the substitution
+ AT this location").
+ </p>
+ <p>
+ The escape sequence @@ is used to escape @. This allows @{x} to be
+ placed in the text without substitution of x by using @@{x}.
+ This corresponds to the $$ escape sequence for properties.
+ </p>
+ <p>
+ The case of the attribute is ignored, so @{myAttribute} is treated the
+ same as @{MyAttribute}.
+ </p>
+ <h3>Parameters</h3>
+ <table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">name</td>
+ <td valign="top">The name of the new attribute</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">default</td>
+ <td valign="top">
+ The default value of the attribute.
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">description</td>
+ <td valign="top">
+ This contains a description of the attribute.
+ <em>since ant 1.6.1</em>
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">doubleexpanding</td>
+ <td valign="top">
+ Controls whether or not property references in the attribute are expanded twice or just once.
+ See the <a href="http://ant.apache.org/faq.html#macrodef-property-expansion">FAQ</a> for details.
+ <em>since Ant 1.8.3</em>
+ </td>
+ <td valign="top" align="center">No; default true</td>
+ </tr>
+ </table>
+ <h4>element</h4>
+ <p>
+ This is used to specify nested elements of the new task.
+ The contents of the nested elements of the task instance
+ are placed in the templated task at the tag name.
+ </p>
+ <p>
+ The case of the element name is ignored.
+ </p>
+ <h3>Parameters</h3>
+ <table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">name</td>
+ <td valign="top">The name of the element</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">optional</td>
+ <td valign="top">
+ If true this nested element is optional. Default is
+ false - i.e the nested element is required in
+ the new task.
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">implicit</td>
+ <td valign="top">
+ If true this nested element is implicit. This means that
+ any nested elements of the macrodef instance will be placed
+ in the element indicated by the name of this element.
+ There can only be one element if an element is implicit.
+ The default value is false. <em>since ant 1.6.2</em>
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">description</td>
+ <td valign="top">
+ This contains a description
+ informing the user what the contents of the element are expected to be.
+ <em>since ant 1.6.1</em>
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ </table>
+ <h4>text</h4>
+ <p>
+ This is used to specify the treatment of text contents of the macro invocation.
+ If this element is not present, then any nested text in the macro invocation
+ will be an error. If the text element is present, then the name
+ becomes an attribute that gets set to the nested text of the macro invocation.
+ <em>Since ant 1.6.1.</em>
+ </p>
+ <p>
+ The case of the text name is ignored.
+ </p>
+ <h3>Parameters</h3>
+ <table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">name</td>
+ <td valign="top">The name of the text attribute</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">optional</td>
+ <td valign="top">
+ If true nested text in the macro is optional, default is "false".
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">trim</td>
+ <td valign="top">
+ If true, the nested text is trimmed of white space,
+ default is "false".
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">description</td>
+ <td valign="top">
+ This contains a description
+ informing the user what the nested text of the macro is expected
+ to be.
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ </table>
+
+ <h3>Examples</h3>
+ <p>
+ The following example defined a task called testing and
+ runs it.
+ </p>
+ <blockquote>
+<pre class=code>
+&lt;macrodef name="testing"&gt;
+ &lt;attribute name="v" default="NOT SET"/&gt;
+ &lt;element name="some-tasks" optional="yes"/&gt;
+ &lt;sequential&gt;
+ &lt;echo&gt;v is @{v}&lt;/echo&gt;
+ &lt;some-tasks/&gt;
+ &lt;/sequential&gt;
+&lt;/macrodef&gt;
+
+&lt;testing v="This is v"&gt;
+ &lt;some-tasks&gt;
+ &lt;echo&gt;this is a test&lt;/echo&gt;
+ &lt;/some-tasks&gt;
+&lt;/testing&gt;
+</pre>
+ </blockquote>
+ <p>
+ The following fragment defines a task called <code>&lt;call-cc&gt;</code> which
+ take the attributes "target", "link" and "target.dir" and the
+ nested element "cc-elements". The body of the task
+ uses the <code>&lt;cc&gt;</code> task from the
+ <a href="http://ant-contrib.sourceforge.net/">ant-contrib</a> project.
+ </p>
+ <blockquote>
+<pre class="code">
+&lt;macrodef name="call-cc"&gt;
+ &lt;attribute name="target"/&gt;
+ &lt;attribute name="link"/&gt;
+ &lt;attribute name="target.dir"/&gt;
+ &lt;element name="cc-elements"/&gt;
+ &lt;sequential&gt;
+ &lt;mkdir dir="${obj.dir}/@{target}"/&gt;
+ &lt;mkdir dir="@{target.dir}"/&gt;
+ &lt;cc link="@{link}" objdir="${obj.dir}/@{target}"
+ outfile="@{target.dir}/@{target}"&gt;
+ &lt;compiler refid="compiler.options"/&gt;
+ &lt;cc-elements/&gt;
+ &lt;/cc&gt;
+ &lt;/sequential&gt;
+&lt;/macrodef&gt;
+</pre>
+ </blockquote>
+ <p>
+ This then can be used as follows:
+ </p>
+ <blockquote>
+<pre class="code">
+&lt;call-cc target="unittests" link="executable"
+ target.dir="${build.bin.dir}"&gt;
+ &lt;cc-elements&gt;
+ &lt;includepath location="${gen.dir}"/&gt;
+ &lt;includepath location="test"/&gt;
+ &lt;fileset dir="test/unittest" includes = "**/*.cpp"/&gt;
+ &lt;fileset dir="${gen.dir}" includes = "*.cpp"/&gt;
+ &lt;linker refid="linker-libs"/&gt;
+ &lt;/cc-elements&gt;
+&lt;/call-cc&gt;
+</pre>
+ </blockquote>
+ <p>
+ The following fragment shows &lt;call-cc&gt;, but this time
+ using an implicit element and with the link and target.dir arguments
+ having default values.
+ </p>
+ <blockquote>
+<pre class="code">
+&lt;macrodef name="call-cc"&gt;
+ &lt;attribute name="target"/&gt;
+ &lt;attribute name="link" default="executable"/&gt;
+ &lt;attribute name="target.dir" default="${build.bin.dir}"/&gt;
+ &lt;element name="cc-elements" implicit="yes"/&gt;
+ &lt;sequential&gt;
+ &lt;mkdir dir="${obj.dir}/@{target}"/&gt;
+ &lt;mkdir dir="@{target.dir}"/&gt;
+ &lt;cc link="@{link}" objdir="${obj.dir}/@{target}"
+ outfile="@{target.dir}/@{target}"&gt;
+ &lt;compiler refid="compiler.options"/&gt;
+ &lt;cc-elements/&gt;
+ &lt;/cc&gt;
+ &lt;/sequential&gt;
+&lt;/macrodef&gt;
+</pre>
+ </blockquote>
+ <p>
+ This then can be used as follows, note that &lt;cc-elements&gt;
+ is not specified.
+ </p>
+ <blockquote>
+<pre class="code">
+&lt;call-cc target="unittests"&gt;
+ &lt;includepath location="${gen.dir}"/&gt;
+ &lt;includepath location="test"/&gt;
+ &lt;fileset dir="test/unittest" includes = "**/*.cpp"/&gt;
+ &lt;fileset dir="${gen.dir}" includes = "*.cpp"/&gt;
+ &lt;linker refid="linker-libs"/&gt;
+&lt;/call-cc&gt;
+</pre>
+ </blockquote>
+ <p>
+ The following shows the use of the <code>text</code> element.
+ </p>
+ <blockquote>
+<pre class="code">
+&lt;macrodef name="echotest"&gt;
+ &lt;text name="text"/&gt;
+ &lt;sequential&gt;
+ &lt;echo&gt;@{text}&lt;/echo&gt;
+ &lt;/sequential&gt;
+&lt;/macrodef&gt;
+&lt;echotest&gt;
+ Hello world
+&lt;/echotest&gt;
+</pre>
+ </blockquote>
+ <p>
+ The following uses a prior defined attribute for setting the
+ default value of another. The output would be
+ <tt>one=test two=test</tt>. If you change the order of lines
+ *1 and *2 the output would be <tt>one=test two=@{one}</tt>,
+ because while processing the <i>two</i>-line the value for
+ <i>one</i> is not set.
+ </p>
+ <blockquote>
+<pre class="code">
+&lt;macrodef name="test"&gt;
+ &lt;attribute name="one"/&gt; <b>*1</b>
+ &lt;attribute name="two" default="@{one}"/&gt; <b>*2</b>
+ &lt;sequential&gt;
+ &lt;echo&gt;one=@{one} two=@{two}&lt;/echo&gt;
+ &lt;/sequential&gt;
+&lt;/macrodef&gt;
+&lt;test one="test"/&gt;
+</pre>
+ </blockquote>
+
+
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/mail.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/mail.html
new file mode 100644
index 00000000..b59633d6
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/mail.html
@@ -0,0 +1,362 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Mail Task</title>
+</head>
+
+<body>
+
+<h2><a name="mail">Mail</a></h2>
+<h3>Description</h3>
+ <p>
+ A task to send SMTP email.
+ </p>
+ <p>
+ This task can send mail using either plain
+ text, UU encoding, or MIME format mail, depending on what is available.
+ </p>
+ <p>
+ SMTP auth and SSL/TLS require JavaMail and are only available in MIME format.
+ </p>
+ <p>
+ Attachments may be sent using nested
+ <code>&lt;attachments&gt;</code> elements, which are <a
+ href="../using.html#path">path-like structures</a>. This means
+ any filesystem based <a
+ href="../Types/resources.html">resource</a> or resource
+ collection can be used to point to attachments. Prior to Apache Ant 1.7
+ only <code>&lt;fileset&gt;</code> has been supported as a nested
+ element, you can still use this directly without an
+ <code>&lt;attachments&gt;</code> container.
+ </p>
+ <p>
+ <strong>Note:</strong> This task may depend on external libraries
+ that are not included in the Ant distribution.
+ See <a href="../install.html#librarydependencies">Library Dependencies</a>
+ for more information.
+ </p>
+
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">from</td>
+ <td valign="top">Email address of sender.</td>
+ <td align="center" valign="top">Either a <code>from</code> attribute, or a <code>&lt;from&gt;</code>
+ element.</td>
+ </tr>
+ <tr>
+ <td valign="top">replyto</td>
+ <td valign="top">Replyto email address.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">tolist</td>
+ <td valign="top">Comma-separated list of recipients.</td>
+ <td align="center" valign="middle" rowspan="3">At least one of these, or the
+ equivalent elements.</td>
+ </tr>
+ <tr>
+ <td valign="top">cclist</td>
+ <td valign="top">Comma-separated list of recipients to carbon copy</td>
+ </tr>
+ <tr>
+ <td valign="top">bcclist</td>
+ <td valign="top">Comma-separated list of recipients to blind carbon copy
+ </td>
+ </tr>
+ <tr>
+ <td valign="top">message</td>
+ <td valign="top">Message to send in the body of the email.</td>
+ <td align="center" valign="middle" rowspan="2">One of these or a
+ <code>&lt;message&gt;</code> element.</td>
+ </tr>
+ <tr>
+ <td valign="top">messagefile</td>
+ <td valign="top">File to send as the body of the email. Property
+ values in the file will be expanded.</td>
+ </tr>
+ <tr>
+ <td valign="top">messagefileinputencoding</td>
+ <td valign="top">
+ Specifies the encoding of the input file. Please see
+ <a href="http://docs.oracle.com/javase/7/docs/technotes/guides/intl/encoding.doc.html">
+ Supported Encodings</a> for a list of possible
+ values. Defaults to the platform's default character
+ encoding. <em>Since Ant 1.9.4</em>
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">messagemimetype</td>
+ <td valign="top">The content type of the message. The default is
+ <code>text/plain</code>.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">files</td>
+ <td valign="top">Files to send as attachments to the email. Separate multiple
+ file names using a comma or space. You can also use <code>&lt;fileset&gt;</code>
+ elements to specify files.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">failonerror</td>
+ <td valign="top">flag to indicate whether to halt the build on
+ any error. The default value is <code>true</code>.</td>
+ <td align="center" valign="top">No.</td>
+ </tr>
+ <tr>
+ <td valign="top">includefilenames</td>
+ <td valign="top">Include filename(s) before file contents.
+ Valid only when the <code>plain</code> encoding is used. The default
+ value is <code>false</code>.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">mailhost</td>
+ <td valign="top">Host name of the SMTP server. The default value is
+ <code>localhost</code>.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">mailport</td>
+ <td valign="top">TCP port of the SMTP server. The default value is 25.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">user</td>
+ <td valign="top">user name for SMTP auth</td>
+ <td valign="center">Yes, if SMTP auth is required on your SMTP server<br></br>
+ the email message will be then sent using Mime and requires JavaMail</td>
+ </tr>
+ <tr>
+ <td valign="top">password</td>
+ <td valign="top">password for SMTP auth</td>
+ <td valign="center">Yes, if SMTP auth is required on your SMTP server<br></br>
+ the email message will be then sent using Mime and requires JavaMail</td>
+ </tr>
+ <tr>
+ <td valign="top">ssl</td>
+ <td valign="top">"true", "on" or "yes" accepted here<br></br>
+ indicates whether you need TLS/SSL</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">encoding</td>
+ <td valign="top">Specifies the encoding to use for the content of the email.
+ Values are <code>mime</code>, <code>uu</code>, <code>plain</code>, or
+ <code>auto</code>. The default value is <code>auto</code>.
+ <code>uu</code> or <code>plain</code> are not compatible with SMTP auth</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">charset</td>
+ <td valign="top">Character set of the email.<br>
+ You can also set the charset in the message nested element.<br>
+ These options are mutually exclusive.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">subject</td>
+ <td valign="top">Email subject line.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">ignoreInvalidRecipients</td>
+ <td valign="top">Boolean. Whether the task should try to send
+ the message to as many recipients as possible and should only
+ fail if neither is reachable. <em>Since Ant 1.8.0</em>.</td>
+ <td align="center" valign="top">No, default is false</td>
+ </tr>
+ <tr>
+ <td valign="top">enableStartTLS</td>
+ <td valign="top">"true", "on" or "yes" accepted here<br></br>
+ whether the STARTTLS command used to switch to an encrypted
+ connection for authentication should be supported. Requires
+ JavaMail. <em>Since Ant 1.8.0</em></td>
+ <td align="center" valign="top">No</td>
+ </tr>
+</table>
+
+<h3>Note regarding the attributes containing email addresses</h3>
+Since Ant 1.6, the attributes from, replyto, tolist, cclist, bcclist
+can contain email addresses of the form :
+<ul>
+<li>address@xyz.com</li>
+<li>name &lt;address@xyz.com&gt;</li>
+<li>&lt;address@xyz.com&gt; name</li>
+<li>(name) address@xyz.com</li>
+<li>address@xyz.com (name)</li>
+</ul>
+<p>You need to enter the angle brackets as XML entities
+<code>&amp;gt;</code> and <code>&amp;lt;</code>.</p>
+
+<h3>Parameters specified as nested elements</h3>
+
+<h4>to / cc / bcc / from/ replyto </h4>
+<p>Adds an email address element. It takes the following attributes:</p>
+
+<table width="60%" border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">name</td>
+ <td valign="top">The display name for the address.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">address</td>
+ <td valign="top">The email address.</td>
+ <td align="center" valign="top">Yes</td>
+ </tr>
+</table>
+
+<h4>message</h4>
+
+<p>Specifies the message to include in the email body. It takes the following
+attributes:</p>
+
+<table width="60%" border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">src</td>
+ <td valign="top">The file to use as the message.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">mimetype</td>
+ <td valign="top">The content type to use for the message.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">charset</td>
+ <td valign="top">Character set of the message<br>
+ You can also set the charset as attribute of the enclosing mail task.<br>
+ These options are mutually exclusive.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">inputencoding</td>
+ <td valign="top">
+ Specifies the encoding of the input file. Please see
+ <a href="http://docs.oracle.com/javase/7/docs/technotes/guides/intl/encoding.doc.html">
+ Supported Encodings</a> for a list of possible
+ values. Defaults to the platform's default character
+ encoding. <em>Since Ant 1.9.4</em>
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+</table>
+
+<p>If the <code>src</code> attribute is not specified, then text can be added
+inside the <code>&lt;message&gt;</code> element. Property expansion will occur
+in the message, whether it is specified as an external file or as text within
+the <code>&lt;message&gt;</code> element.</p>
+
+<h4>header</h4>
+<p><strong>Since Ant 1.7</strong>, arbitrary mail headers can be added by
+ specifying these attributes on one or more nested header elements:</p>
+
+<table width="60%" border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">name</td>
+ <td valign="top">The name associated with this mail header.</td>
+ <td align="center" valign="top">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">value</td>
+ <td valign="top">The value to assign to this mail header.</td>
+ <td align="center" valign="top">Yes</td>
+ </tr>
+</table>
+
+<p>It is permissible to duplicate the name attribute amongst multiple headers.
+</p>
+
+<h3>Examples</h3>
+
+<blockquote><pre>
+&lt;mail from=&quot;me&quot;
+ tolist=&quot;you&quot;
+ subject=&quot;Results of nightly build&quot;
+ files=&quot;build.log&quot;/&gt;
+</pre></blockquote>
+
+<p>Sends an email from <i>me</i> to <i>you</i> with a subject of
+<i>Results of nightly build</i> and includes the contents of the file
+<i>build.log</i> in the body of the message.</p>
+
+<blockquote><pre>
+&lt;mail mailhost=&quot;smtp.myisp.com&quot; mailport=&quot;1025&quot; subject=&quot;Test build&quot;&gt;
+ &lt;from address=&quot;config@myisp.com&quot;/&gt;
+ &lt;replyto address=&quot;me@myisp.com&quot;/&gt;
+ &lt;to address=&quot;all@xyz.com&quot;/&gt;
+ &lt;message&gt;The ${buildname} nightly build has completed&lt;/message&gt;
+ &lt;attachments&gt;
+ &lt;fileset dir=&quot;dist&quot;&gt;
+ &lt;include name=&quot;**/*.zip&quot;/&gt;
+ &lt;/fileset&gt;
+ &lt;/attachments&gt;
+&lt;/mail&gt;
+</pre></blockquote>
+
+<p>Sends an eMail from <i>config@myisp.com</i> to <i>all@xyz.com</i> with a subject of
+<i>Test Build</i>. Replies to this email will go to <i>me@myisp.com</i>.
+Any zip files from the dist directory are attached.&nbsp; The
+task will attempt to use JavaMail and fall back to UU encoding or no encoding in
+that order depending on what support classes are available. <code>${buildname}</code>
+will be replaced with the <code>buildname</code> property's value.</p>
+
+<blockquote><pre>
+&lt;property name=&quot;line2&quot; value=&quot;some_international_message&quot;/&gt;
+&lt;echo message=&quot;${line2}&quot;/&gt;
+
+&lt;mail mailhost=&quot;somehost@xyz.com&quot; mailport=&quot;25&quot; subject=&quot;Test build&quot; charset=&quot;utf-8&quot;&gt;
+ &lt;from address=&quot;me@myist.com&quot;/&gt;
+ &lt;to address=&quot;all@xyz.com&quot;/&gt;
+ &lt;message&gt;some international text:${line2}&lt;/message&gt;
+&lt;/mail&gt;
+</pre></blockquote>
+
+<p>Sends an eMail from <i>me@myisp.com</i> to <i>all@xyz.com</i> with a subject of
+<i>Test Build</i>, the message body being coded in UTF-8
+
+
+
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/makeurl.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/makeurl.html
new file mode 100644
index 00000000..b20f94a1
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/makeurl.html
@@ -0,0 +1,234 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<html>
+<head>
+ <meta http-equiv="Content-Language" content="en-us">
+ <title>Makeurl Task</title>
+</head>
+
+<body bgcolor="#ffffff" text="#000000" link="#525D76"
+ alink="#525D76" vlink="#525D76">
+
+<table border="0" width="100%" cellspacing="4">
+
+ <!-- PAGE HEADER -->
+ <tr>
+ <td>
+ <table border="0" width="100%"><tr>
+ <td valign="bottom">
+ <font size="+3" face="arial,helvetica,sanserif"><strong>Makeurl Task</strong></font>
+ </td>
+ <td>
+ <!-- PROJECT LOGO -->
+ <a href="http://ant.apache.org/">
+ <img src="../images/ant_logo_large.gif" align="right" alt="Apache Ant" border="0"/>
+ </a>
+ </td>
+ </tr></table>
+ </td>
+ </tr>
+
+ <!-- START RIGHT SIDE MAIN BODY -->
+ <tr>
+ <td valign="top" align="left">
+
+ <!-- Applying task/long-description -->
+ <!-- Start Description -->
+ <table border="0" cellspacing="0" cellpadding="2" width="100%">
+ <tr><td>&nbsp;</td></tr>
+
+ <tr><td bgcolor="#525D76">
+ <font color="#ffffff" face="arial,helvetica.sanserif">
+ <a name="description">
+ <strong>Description</strong></a></font>
+ </td></tr>
+
+ <tr><td><blockquote>
+This task takes one or more filenames and turns them into URLs, which it then assigns to a property.
+Useful when setting up RMI or JNLP codebases, for example.
+Nested filesets are supported; if present, these are turned into the URLs with the supplied separator between them (default: space).
+<p/>
+<p>Examples:</p>
+<pre>
+&lt;makeurl file="${user.home}/.m2/repository" property="m2.repository.url"/&gt;
+</pre>
+Sets the property <code>m2.repository.url</code> to the file: URL of the local Maven2 repository.
+<pre>
+&lt;makeurl property="codebase"&gt;&lt;fileset dir="lib includes="*.jar"/&gt;&lt;/makeurl&gt;
+</pre>
+Set the property <code>codebase</code> to the three URLs of the files provided as nested elements.
+ </blockquote></td></tr>
+
+ </table>
+ <!-- End Description -->
+
+ <!-- Ignore -->
+
+
+
+ <!-- Start Attributes -->
+ <table border="0" cellspacing="0" cellpadding="2" width="100%">
+ <tr><td>&nbsp;</td></tr>
+ <tr><td bgcolor="#525D76">
+ <font color="#ffffff" face="arial,helvetica.sanserif">
+ <a name="attributes">
+ <strong>Parameters</strong></a></font>
+ </td></tr>
+ <tr><td><blockquote>
+ <table>
+ <tr>
+ <td bgcolor="#cccccc" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif"><b>Attribute</b></font>
+ </td>
+ <td bgcolor="#cccccc" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif"><b>Description</b></font>
+ </td>
+ <td bgcolor="#cccccc" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif"><b>Type</b></font>
+ </td>
+ <td bgcolor="#cccccc" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif"><b>Requirement</b></font>
+ </td>
+ </tr>
+ <!-- Attribute Group -->
+
+ <!-- Attribute Group -->
+ <!-- Attribute -->
+ <tr>
+ <td bgcolor="#eeeeee" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif">file</font>
+ </td>
+ <td bgcolor="#eeeeee" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif">name of a file to be converted into a URL</font>
+ </td>
+ <td bgcolor="#eeeeee" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif">File</font>
+ </td>
+ <td bgcolor="#eeeeee" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif">optional, if a nested fileset or path is supplied</font>
+ </td>
+ </tr>
+ <!-- Attribute -->
+ <tr>
+ <td bgcolor="#eeeeee" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif">property</font>
+ </td>
+ <td bgcolor="#eeeeee" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif">name of a property to set to the URL</font>
+ </td>
+ <td bgcolor="#eeeeee" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif">String</font>
+ </td>
+ <td bgcolor="#eeeeee" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif">required</font>
+ </td>
+ </tr>
+ <!-- Attribute -->
+ <tr>
+ <td bgcolor="#eeeeee" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif">separator</font>
+ </td>
+ <td bgcolor="#eeeeee" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif">separator for the multi-URL option</font>
+ </td>
+ <td bgcolor="#eeeeee" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif">String</font>
+ </td>
+ <td bgcolor="#eeeeee" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif">optional</font>
+ </td>
+ </tr>
+ <!-- Attribute -->
+ <tr>
+ <td bgcolor="#eeeeee" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif">validate</font>
+ </td>
+ <td bgcolor="#eeeeee" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif">validate that every named file exists</font>
+ </td>
+ <td bgcolor="#eeeeee" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif">boolean</font>
+ </td>
+ <td bgcolor="#eeeeee" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif">optional; default: true</font>
+ </td>
+ </tr>
+
+
+ </table>
+ </blockquote></td></tr>
+
+ </table>
+ <!-- End Attributes -->
+
+ <!-- Start Elements -->
+ <table border="0" cellspacing="0" cellpadding="2" width="100%">
+ <tr><td>&nbsp;</td></tr>
+
+ <tr><td bgcolor="#525D76">
+ <font color="#ffffff" face="arial,helvetica.sanserif">
+ <a name="elements">
+ <strong>Parameters as nested elements</strong></a></font>
+ </td></tr>
+
+ <tr><td><blockquote>
+ <!-- Start Element -->
+ <table border="0" cellspacing="0" cellpadding="2" width="100%">
+ <tr><td>&nbsp;</td></tr>
+ <tr><td bgcolor="#828DA6">
+ <font color="#ffffff" face="arial,helvetica.sanserif" size="-1">
+ <strong>fileset</strong> (org.apache.tools.ant.types.FileSet)</font>
+ </td></tr>
+ <tr><td><blockquote>
+ A fileset of JAR files to include in the URL list, each separated by the separator.
+ <!-- Ignore -->
+ <!-- Ignore -->
+
+ </blockquote></td></tr>
+ </table>
+ <!-- End Element -->
+ <!-- Start Element -->
+ <table border="0" cellspacing="0" cellpadding="2" width="100%">
+ <tr><td>&nbsp;</td></tr>
+ <tr><td bgcolor="#828DA6">
+ <font color="#ffffff" face="arial,helvetica.sanserif" size="-1">
+ <strong>path</strong> (org.apache.tools.ant.types.Path)</font>
+ </td></tr>
+ <tr><td><blockquote>
+ Add a path to the URL. All elements in the path will be converted to individual URL entries.
+ <!-- Ignore -->
+ <!-- Ignore -->
+
+ </blockquote></td></tr>
+ </table>
+ <!-- End Element -->
+
+ </blockquote></td></tr>
+
+ </table>
+ <!-- End Elements -->
+
+
+ </td>
+ </tr>
+ <!-- END RIGHT SIDE MAIN BODY -->
+
+</table>
+
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/manifest.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/manifest.html
new file mode 100644
index 00000000..7a5b98bc
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/manifest.html
@@ -0,0 +1,197 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Manifest Task</title>
+</head>
+
+<body>
+
+<h2><a name="manifest">Manifest</a></h2>
+<h3>Description</h3>
+<p>Creates a manifest file.</p>
+
+<p>This task can be used to write a Manifest file, optionally
+replacing or updating an existing file.</p>
+
+
+
+<p>Manifests are processed according to the
+<a href="http://docs.oracle.com/javase/7/docs/technotes/guides/jar/jar.html">Jar
+file specification.</a>. Specifically, a manifest element consists of
+a set of attributes and sections. These sections in turn may contain
+attributes. Note in particular that this may result in manifest lines
+greater than 72 bytes being wrapped and continued on the next
+line.</p>
+
+<p>
+ The Apache Ant team regularly gets complaints that this task in generating invalid
+ manifests. By and large, this is not the case: we believe that we are following
+ the specification to the letter. The usual problem is that some third party
+ manifest reader is not following the same specification as well as they think
+ they should; we cannot generate invalid manifest files just because one
+ single application is broken. J2ME runtimes appear to be particularly troublesome.
+</p>
+
+<p>
+ If you find that Ant generates manifests incompatible with your runtime, take
+ a manifest it has built, fix it up however you need and switch to using the &lt;zip&gt
+ task to create the JAR, feeding in the hand-crafted manifest.
+</p>
+
+
+
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">file</td>
+ <td valign="top">the manifest-file to create/update.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">mode</td>
+ <td valign="top">One of "update" or "replace", default is "replace".</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">encoding</td>
+ <td valign="top">The encoding used to read the existing manifest
+ when updating. The task will always use UTF-8 when writing the
+ manifest.</td>
+ <td valign="top" align="center">No, defaults to UTF-8 encoding.</td>
+ </tr>
+ <tr>
+ <td valign="top">mergeClassPathAttributes</td>
+ <td valign="top">Whether to merge the Class-Path attributes found
+ in different manifests (if updating). If false, only the
+ attribute of the most recent manifest will be preserved.
+ <em>Since Ant 1.8.0</em>.
+ <br/>unless you also set flattenAttributes to true this may
+ result in manifests containing multiple Class-Path attributes
+ which violates the manifest specification.</td>
+ <td align="center" valign="top">No, default is false</td>
+ </tr>
+ <tr>
+ <td valign="top">flattenAttributes</td>
+ <td valign="top">Whether to merge attributes occurring more than
+ once in a section (this can only happen for the Class-Path
+ attribute) into a single attribute.
+ <em>Since Ant 1.8.0</em>.</td>
+ <td align="center" valign="top">No, default is false</td>
+ </tr>
+</table>
+
+<h3>Nested elements</h3>
+<h4><a name="attribute">attribute</a></h4>
+<p>One attribute for the manifest file. Those attributes that are
+not nested into a section will be added to the "Main" section.</p>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">name</td>
+ <td valign="top">the name of the attribute, <br>
+ must match the regexp <tt>[A-Za-z0-9][A-Za-z0-9-_]*</tt>.
+ </td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">value</td>
+ <td valign="top">the value of the attribute.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+</table>
+
+
+<h4>section</h4>
+<p>A manifest section - you can nest <a
+href="#attribute">attribute</a> elements into sections.</p>
+
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">name</td>
+ <td valign="top">the name of the section.</td>
+ <td valign="top" align="center">No, if omitted it will be assumed
+ to be the main section.</td>
+ </tr>
+</table>
+
+<h3>Examples</h3>
+
+<pre>
+ &lt;manifest file=&quot;MANIFEST.MF&quot;&gt;
+ &lt;attribute name=&quot;Built-By&quot; value=&quot;${user.name}&quot;/&gt;
+ &lt;section name=&quot;common&quot;&gt;
+ &lt;attribute name=&quot;Specification-Title&quot; value=&quot;Example&quot;/&gt;
+ &lt;attribute name=&quot;Specification-Version&quot; value=&quot;${version}&quot;/&gt;
+ &lt;attribute name=&quot;Specification-Vendor&quot; value=&quot;Example Organization&quot;/&gt;
+ &lt;attribute name=&quot;Implementation-Title&quot; value=&quot;common&quot;/&gt;
+ &lt;attribute name=&quot;Implementation-Version&quot; value=&quot;${version} ${TODAY}&quot;/&gt;
+ &lt;attribute name=&quot;Implementation-Vendor&quot; value=&quot;Example Corp.&quot;/&gt;
+ &lt;/section&gt;
+ &lt;section name=&quot;common/class1.class&quot;&gt;
+ &lt;attribute name=&quot;Sealed&quot; value=&quot;false&quot;/&gt;
+ &lt;/section&gt;
+ &lt;/manifest&gt;
+</pre>
+
+<p>Creates or replaces the file MANIFEST.MF. Note that the Built-By
+attribute will take the value of the Ant property ${user.name}. The
+same is true for the ${version} and ${TODAY} properties. This example
+produces a MANIFEST.MF that contains
+<a href="http://docs.oracle.com/javase/7/docs/technotes/guides/versioning/spec/versioning2.html#wp90779">package
+version identification</a> for the package <code>common</code>.</p>
+
+<p>The manifest produced by the above would look like this:</p>
+
+<pre><code>Manifest-Version: 1.0
+Built-By: bodewig
+Created-By: Apache Ant 1.9
+
+Name: common
+Specification-Title: Example
+Specification-Vendor: Example Organization
+Implementation-Vendor: Example Corp.
+Specification-Version: 1.2
+Implementation-Version: 1.2 September 10, 2013
+Implementation-Title: common
+
+Name: common/class1.class
+Sealed: false
+
+</code></pre>
+
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/manifestclasspath.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/manifestclasspath.html
new file mode 100644
index 00000000..2c193b8a
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/manifestclasspath.html
@@ -0,0 +1,117 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>ManifestClassPath Task</title>
+</head>
+
+<body>
+
+<h2><a name="manifestclasspath">Manifestclasspath</a></h2>
+
+<h3>Description</h3>
+<p>Converts a <a href="../using.html#path">Path</a> into a property
+whose value is appropriate for a <a href="manifest.html">Manifest</a>'s
+<code>Class-Path</code> attribute.</p>
+
+<p>This task is often used to work around command line limitations on Windows
+when using very long class paths when launching an application. The long class
+path normally specified on the command line is replaced by a single (possibly
+empty) jar file which an in-manifest Class-Path attribute whose value lists
+all the jar and zip files the class path should contain. The files referenced
+from this attribute must be found relatively to the jar file itself, usually
+in the same directory. The Java VM automically uses all file entries listed
+in the Class-Path attributes of a jar to locate/load classes. Note though that
+it silently ignores entries for which it cannot find any corresponding file.</p>
+
+<p>Note that the property value created may be longer than a manifest's maximum
+72 characters per line, but will be properly wrapped as per the Jar
+specification by the <code>&lt;manifest&gt;</code> element, where the
+defined property is re-referenced.</p>
+
+<p>For this task to work properly the relative path from the file
+ given in the <code>jarfile</code> attribute to the elements of the
+ nested <code>classpath</code> must be the same as you expect them to
+ be when deploying the jar.</p>
+
+<p><em>since Apache Ant 1.7</em></p>
+
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">property</td>
+ <td valign="top">the name of the property to set. This property must
+ not already be set.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">jarfile</td>
+ <td valign="top">
+ the filename for the Jar which will contain the manifest that will
+ use the property this task will set. This file need not exist yet,
+ but its parent directory must exist.
+ </td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">maxParentLevels</td>
+ <td valign="top">
+ The maximum number of parent directories one is allowed to traverse
+ to navigate from the jar file to the path entry. Put differently, the
+ maximum number of .. which is allowed in the relative path from the
+ jar file to a given class path entry. Specify 0 to enforce a path
+ entry to be in the same directory (or one of its sub-directories)
+ as the jar file itself. Defaults to 2 levels.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+</table>
+
+<h3>Parameters specified as nested elements</h3>
+<h4>classpath</h4>
+<p>A <a href="../using.html#path">Path-like</a> element, which can be
+defined in-place, or refer to a path defined elsewhere using the
+<code>&lt;classpath refid="<em>pathid</em>" /&gt;</code> syntax.
+This classpath must not be empty, and is required.</p>
+
+<h3>Examples</h3>
+<div id="example1">
+ <blockquote><pre>
+ &lt;manifestclasspath property="jar.classpath"
+ jarfile="build/acme.jar"&gt;
+ &lt;classpath refid="classpath" /&gt;
+ &lt;/manifestclasspath&gt;
+ </pre></blockquote>
+ <p>Assuming a path of id "classpath" was already defined, convert this
+ path relatively to the build/ directory that will contain acme.jar, which
+ can later be created with <code>&lt;jar&gt;</code> with a nested
+ <code>&lt;manifest&gt;</code> element that lists an
+ <code>&lt;attribute name="Class-Path" value="${jar.classpath}" /&gt;</code>.
+ </p>
+</div>
+
+
+
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/mimemail.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/mimemail.html
new file mode 100644
index 00000000..ba066a6b
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/mimemail.html
@@ -0,0 +1,115 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>MimeMail Task</title>
+</head>
+
+<body>
+
+<h2><a name="mimemail">MimeMail</a></h2>
+
+<h3><i>Deprecated</i></h3>
+<p><i>This task has been deprecated. Use the <a href="../Tasks/mail.html">mail</a> task instead.</i></p>
+
+<h3>Description</h3>
+<p>Sends SMTP mail with MIME attachments.
+<a href="http://www.oracle.com/technetwork/java/index-138643.html">JavaMail</a>
+and <a href="http://www.oracle.com/technetwork/java/javase/jaf-135115.html">Java
+Activation Framework</a> are required for this task.</p>
+<p>Multiple files can be attached using <a href="../Types/fileset.html">FileSets.</a></p>
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">message</td>
+ <td valign="top">The message body</td>
+ <td valign="top" align="center" rowspan="2">No, but only one of of 'message' or
+ 'messageFile' may be specified.&nbsp; If not specified, a fileset must be
+ provided.</td>
+ </tr>
+ <tr>
+ <td valign="top">messageFile</td>
+ <td valign="top">A filename to read and used as the message body</td>
+ </tr>
+ <tr>
+ <td valign="top">messageMimeType</td>
+ <td valign="top">MIME type to use for 'message' or 'messageFile' when
+ attached.</td>
+ <td align="center" valign="top">No, defaults to "text/plain"</td>
+ </tr>
+ <tr>
+ <td valign="top">tolist</td>
+ <td valign="top">Comma-separated list of To: recipients</td>
+ <td valign="top" align="center" rowspan="3">Yes, at least one of 'tolist', 'cclist',
+ or 'bcclist' must be specified.</td>
+ </tr>
+ <tr>
+ <td valign="top">cclist</td>
+ <td valign="top">Comma-separated list of CC: recipients</td>
+ <td valign="top" align="center">&nbsp;</td>
+ </tr>
+ <tr>
+ <td valign="top">bcclist</td>
+ <td valign="top">Comma-separated list of BCC: recipients</td>
+ <td valign="top" align="center">&nbsp;</td>
+ </tr>
+ <tr>
+ <td valign="top">mailhost</td>
+ <td valign="top">Host name of the mail server.</td>
+ <td valign="top" align="center">No, default to &quot;localhost&quot;</td>
+ </tr>
+ <tr>
+ <td valign="top">subject</td>
+ <td valign="top">Email subject line.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">from</td>
+ <td valign="top">Email address of sender.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">failonerror</td>
+ <td valign="top">Stop the build process if an error occurs sending the
+ e-mail.</td>
+ <td valign="top" align="center">No, default to &quot;true&quot;</td>
+ </tr>
+</table>
+<h3>Examples</h3>
+<p><b>Send a single HTML file as the body of a message</b></p>
+<pre> &lt;mimemail messageMimeType=&quot;text/html&quot; messageFile=&quot;overview-summary.html&quot;
+ tolist=&quot;you&quot; subject=&quot;JUnit Test Results: ${TODAY}&quot; from=&quot;me&quot;/&gt;</pre>
+<p><b>Sends all files in a directory as attachments</b></p>
+<pre> &lt;mimemail message=&quot;See attached files&quot; tolist=&quot;you&quot; subject=&quot;Attachments&quot; from=&quot;me&quot;&gt;
+ &lt;fileset dir=&quot;.&quot;&gt;
+ &lt;include name=&quot;dist/*.*&quot;/&gt;
+ &lt;/fileset&gt;
+ &lt;/mimemail&gt;
+</pre>
+
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/mkdir.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/mkdir.html
new file mode 100644
index 00000000..5d945c0f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/mkdir.html
@@ -0,0 +1,52 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Mkdir Task</title>
+</head>
+
+<body>
+
+<h2><a name="mkdir">Mkdir</a></h2>
+<h3>Description</h3>
+<p>Creates a directory. Also non-existent parent directories are created, when
+necessary. Does nothing if the directory already exist.</p>
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">dir</td>
+ <td valign="top">the directory to create.</td>
+ <td align="center" valign="top">Yes</td>
+ </tr>
+</table>
+<h3>Examples</h3>
+<pre>&lt;mkdir dir=&quot;${dist}&quot;/&gt;</pre>
+<p>creates a directory <code>${dist}</code>.</p>
+<pre>&lt;mkdir dir=&quot;${dist}/lib&quot;/&gt;</pre>
+<p>creates a directory <code>${dist}/lib</code>.</p>
+
+
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/move.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/move.html
new file mode 100644
index 00000000..c4f931ad
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/move.html
@@ -0,0 +1,258 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Move Task</title>
+</head>
+
+<body>
+
+<h2><a name="move">Move</a></h2>
+<h3>Description</h3>
+<p>Moves a file to a new file or directory, or collections of files to
+a new directory. By default, the
+destination file is overwritten if it already exists. When <var>overwrite</var> is
+turned off, then files are only moved if the source file is newer than
+the destination file, or when the destination file does not exist.</p>
+
+<p><a href="../Types/resources.html#collection">Resource
+Collection</a>s are used to select a group of files to move. Only
+file system based resource collections are supported, this includes <a
+href="../Types/fileset.html">fileset</a>s, <a
+href="../Types/filelist.html">filelist</a> and <a
+href="../using.html#path">path</a>. Prior to Apache Ant 1.7 only
+<code>&lt;fileset&gt;</code> has been supported as a nested element.
+To use a resource collection, the <code>todir</code> attribute must be
+set.</p>
+
+<p><b>Since Ant 1.6.3</b>, the <i>file</i> attribute may be used to move
+(rename) an entire directory. If <i>tofile</i> denotes an existing file, or
+there is a directory by the same name in <i>todir</i>, the action will fail.
+</p>
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">file</td>
+ <td valign="top">the file or directory to move</td>
+ <td valign="top" align="center">One of <var>file</var> or
+ at least one nested resource collection element</td>
+ </tr>
+ <tr>
+ <td valign="top">preservelastmodified</td>
+ <td valign="top">Give the moved files the same last modified
+ time as the original source files.
+ (<em>Note</em>: Ignored on Java 1.1)</td>
+ <td valign="top" align="center">No; defaults to false.</td>
+ </tr>
+ <tr>
+ <td valign="top">tofile</td>
+ <td valign="top">the file to move to</td>
+ <td valign="top" align="center" rowspan="2">With the <var>file</var> attribute,
+ either <var>tofile</var> or <var>todir</var> can be used. With nested filesets,
+ if the fileset size is greater than 1 or if the only entry in the fileset is a
+ directory or if the <var>file</var> attribute is already specified, only
+ <var>todir</var> is allowed</td>
+ </tr>
+ <tr>
+ <td valign="top">todir</td>
+ <td valign="top">the directory to move to</td>
+ </tr>
+ <tr>
+ <td valign="top">overwrite</td>
+ <td valign="top">overwrite existing files even if the destination
+ files are newer (default is &quot;true&quot;)</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">force</td>
+ <td valign="top">Overwrite read-only destination
+ files. <em>since Ant 1.8.2</em></td>
+ <td valign="top" align="center">No; defaults to false.</td>
+ </tr>
+ <tr>
+ <td valign="top">filtering</td>
+ <td valign="top">indicates whether token filtering should take place during
+ the move. See the <a href="filter.html">filter</a> task for a description of
+ how filters work.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">flatten</td>
+ <td valign="top">ignore directory structure of source directory,
+ copy all files into a single directory, specified by the <var>todir</var>
+ attribute (default is &quot;false&quot;).Note that you can achieve the
+ same effect by using a <a href="../Types/mapper.html#flatten-mapper">flatten mapper</a></td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">includeEmptyDirs</td>
+ <td valign="top">Copy empty directories included with the nested FileSet(s).
+ Defaults to &quot;yes&quot;.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">failonerror</td>
+ <td valign="top">If false, log a warning message, but do not stop the
+ build, when the file to copy does not exist or one of the nested
+ filesets points to a directory that doesn't exist or an error occurs
+ while moving.
+ </td>
+ <td valign="top" align="center">No; defaults to true.</td>
+ </tr>
+ <tr>
+ <td valign="top">quiet</td>
+ <td valign="top">If true and failonerror is false, then do not log a
+ warning message when the file to copy does not exist or one of the nested
+ filesets points to a directory that doesn't exist or an error occurs
+ while copying. <em>since Ant 1.8.3</em>.
+ </td>
+ <td valign="top" align="center">No; defaults to false.</td>
+ </tr>
+ <tr>
+ <td valign="top">verbose</td>
+ <td valign="top">Log the files that are being moved.</td>
+ <td valign="top" align="center">No; defaults to false.</td>
+ </tr>
+ <tr>
+ <td valign="top">encoding</td>
+ <td valign="top">The encoding to assume when filter-copying the
+ files. <em>since Ant 1.5</em>.</td>
+ <td align="center">No - defaults to default JVM encoding</td>
+ </tr>
+ <tr>
+ <td valign="top">outputencoding</td>
+ <td valign="top">The encoding to use when writing the files.
+ <em>since Ant 1.6</em>.</td>
+ <td align="center">No - defaults to the value of the encoding
+ attribute if given or the default JVM encoding otherwise.</td>
+ </tr>
+ <tr>
+ <td valign="top">enablemultiplemappings</td>
+ <td valign="top">
+ If true the task will process to all the mappings for a
+ given source path. If false the task will only process
+ the first file or directory. This attribute is only relevant
+ if there is a mapper subelement.
+ <em>since Ant 1.6</em>.</td>
+ <td align="center">No - defaults to false.</td>
+ </tr>
+ <tr>
+ <td valign="top">granularity</td>
+ <td valign="top">The number of milliseconds leeway to give before
+ deciding a file is out of date. This is needed because not every
+ file system supports tracking the last modified time to the
+ millisecond level. Default is 0 milliseconds, or 2 seconds on DOS
+ systems. This can also be useful if source and target files live
+ on separate machines with clocks being out of sync. <em>since Ant
+ 1.6</em>.</td>
+ </tr>
+ <tr>
+ <td valign="top">performGCOnFailedDelete</td>
+ <td valign="top">
+ If Ant fails to delete a file or directory it will retry the
+ operation once. If this flag is set to true it will perform a
+ garbage collection before retrying the delete.<br/>
+ Setting this flag to true is known to resolve some problems on
+ Windows (where it defaults to true) but also for directory trees
+ residing on an NFS share.
+ <em>Since Ant 1.8.3</em></td>
+ <td align="center" valign="top">No, default &quot;true&quot; on
+ Windows and &quot;true&quot; on any other OS.</td>
+ </tr>
+</table>
+<h3>Parameters specified as nested elements</h3>
+<h4>mapper</h4>
+<p>You can define file name transformations by using a nested <a
+href="../Types/mapper.html">mapper</a> element. The default mapper used by
+<code>&lt;move&gt;</code> is the <a
+href="../Types/mapper.html#identity-mapper">identity</a>.</p>
+<p>Note that the source name handed to the mapper depends on the
+resource collection you use. If you use <code>&lt;fileset&gt;</code>
+or any other collection that provides a base directory, the name
+passed to the mapper will be a relative filename, relative to the base
+directory. In any other case the absolute filename of the source will
+be used.</p>
+<h4>filterchain</h4>
+<p>The Move task supports nested <a href="../Types/filterchain.html">
+FilterChain</a>s.</p>
+
+<p>
+If <code>&lt;filterset&gt;</code> and <code>&lt;filterchain&gt;</code> elements are used inside the
+same <code>&lt;move&gt;</code> task, all <code>&lt;filterchain&gt;</code> elements are processed first
+followed by <code>&lt;filterset&gt;</code> elements.
+</p>
+
+<h3>Examples</h3>
+<p><b>Move a single file (rename a file)</b></p>
+<pre>
+ &lt;move file=&quot;file.orig&quot; tofile=&quot;file.moved&quot;/&gt;
+</pre>
+<p><b>Move a single file to a directory</b></p>
+<pre>
+ &lt;move file=&quot;file.orig&quot; todir=&quot;dir/to/move/to&quot;/&gt;
+</pre>
+<p><b>Move a directory to a new directory</b></p>
+<pre>
+ &lt;move todir=&quot;new/dir/to/move/to&quot;&gt;
+ &lt;fileset dir=&quot;src/dir&quot;/&gt;
+ &lt;/move&gt;
+</pre>
+ <i>or, since Ant 1.6.3:</i>
+<pre>
+ &lt;move file=&quot;src/dir&quot; tofile=&quot;new/dir/to/move/to&quot;/&gt;
+</pre>
+<p><b>Move a set of files to a new directory</b></p>
+<pre>
+ &lt;move todir=&quot;some/new/dir&quot;&gt;
+ &lt;fileset dir=&quot;my/src/dir&quot;&gt;
+ &lt;include name=&quot;**/*.jar&quot;/&gt;
+ &lt;exclude name=&quot;**/ant.jar&quot;/&gt;
+ &lt;/fileset&gt;
+ &lt;/move&gt;
+</pre>
+<p><b>Move a list of files to a new directory</b></p>
+<pre>
+ &lt;move todir=&quot;some/new/dir&quot;&gt;
+ &lt;filelist dir=&quot;my/src/dir&quot;&gt;
+ &lt;file name="file1.txt"/&gt;
+ &lt;file name="file2.txt"/&gt;
+ &lt;/filelist&gt;
+ &lt;/move&gt;
+</pre>
+<p><b>Append <code>&quot;.bak&quot;</code> to the names of all files
+in a directory.</b></p>
+<pre>
+ &lt;move todir=&quot;my/src/dir&quot; includeemptydirs=&quot;false&quot;&gt;
+ &lt;fileset dir=&quot;my/src/dir&quot;&gt;
+ &lt;exclude name=&quot;**/*.bak&quot;/&gt;
+ &lt;/fileset&gt;
+ &lt;mapper type=&quot;glob&quot; from=&quot;*&quot; to=&quot;*.bak&quot;/&gt;
+ &lt;/move&gt;
+</pre>
+
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/native2ascii.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/native2ascii.html
new file mode 100644
index 00000000..c50483b9
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/native2ascii.html
@@ -0,0 +1,246 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+ <head><link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Native2Ascii Task</title></head>
+ <body>
+ <h2>Native2Ascii</h2>
+
+ <h3>Description:</h3>
+
+ <p>
+ Converts files from native encodings to ASCII with escaped Unicode.
+ A common usage is to convert source files maintained in a native
+ operating system encoding, to ASCII prior to compilation.
+ </p>
+
+ <p>
+ Files in the directory <em>src</em>
+ are converted from a native encoding to ASCII.
+ By default, all files in the directory are converted.
+ However, conversion may be limited to selected files using
+ <em>includes</em> and <em>excludes</em> attributes.
+ For more information on file matching patterns,
+ see the section on
+ <a href="../dirtasks.html#directorybasedtasks">directory based tasks</a>.
+ If no <em>encoding</em> is specified,
+ the default encoding for the JVM is used.
+ If <em>ext</em> is specified, then output files are renamed
+ to use it as a new extension.
+ More sophisticated file name translations can be achieved using a nested
+ <em><code>&lt;mapper&gt;</code></em> element. By default an
+ <a href="../Types/mapper.html#identity-mapper">identity mapper</a> will be used.
+ If <em>dest</em> and <em>src</em> point to the same directory,
+ the <em>ext</em> attribute or a nested <em><code>&lt;mapper&gt;</code></em>
+ is required.
+ </p>
+
+ <p>
+ This task forms an implicit <a href="../Types/fileset.html">File Set</a>,
+ and supports most attributes of <code>&lt;fileset&gt;</code>
+ (<code>dir</code> becomes <code>src</code>) as well as
+ nested <code>&lt;include&gt;</code>, <code>&lt;exclude&gt;</code>,
+ and <code>&lt;patternset&gt;</code> elements.
+ </p>
+
+ <p>It is possible to use different converters. This can be selected
+ with the <code>implementation</code> attribute or a nested element.
+ <a name="implementationvalues">Here are the choices of the attribute</a>:</p>
+ <ul>
+ <li>default - the default converter (kaffe or sun) for the platform.</li>
+ <li>sun (the standard converter of the JDK)</li>
+ <li>kaffe (the standard converter of <a href="http://www.kaffe.org" target="_top">Kaffe</a>)</li>
+ </ul>
+
+ <table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td><b>Attribute</b></td>
+ <td><b>Description</b></td>
+ <td><b>Required</b></td>
+ </tr>
+ <tr>
+ <td>reverse</td>
+ <td>Reverse the sense of the conversion,
+ i.e. convert from ASCII to native <b>only supported by the
+ sun converter</b></td>
+ <td align="center">No</td>
+ </tr>
+ <tr>
+ <td>encoding</td>
+ <td>The native encoding the files are in
+ (default is the default encoding for the JVM)</td>
+ <td align="center">No</td>
+ </tr>
+ <tr>
+ <td>src</td>
+ <td>The directory to find files in (default is <em>basedir</em>)</td>
+ <td align="center">No</td>
+ </tr>
+ <tr>
+ <td>dest</td>
+ <td>The directory to output file to</td>
+ <td align="center">Yes</td>
+ </tr>
+ <tr>
+ <td>ext</td>
+ <td>File extension to use in renaming output files</td>
+ <td align="center">No</td>
+ </tr>
+ <tr>
+ <td>defaultexcludes</td>
+ <td>indicates whether default excludes should be used or not
+ (&quot;yes&quot;/&quot;no&quot;).
+ Default excludes are used when omitted.
+ </td>
+ <td align="center">No</td>
+ </tr>
+ <tr>
+ <td>includes</td>
+ <td>comma- or space-separated list of patterns of files that must be
+ included. All files are included when omitted.</td>
+ <td align="center">No</td>
+ </tr>
+ <tr>
+ <td>includesfile</td>
+ <td>the name of a file. Each line of this file is
+ taken to be an include pattern</td>
+ <td align="center">No</td>
+ </tr>
+ <tr>
+ <td>excludes</td>
+ <td>comma- or space-separated list of patterns of files that must be excluded.
+ No files (except default excludes) are excluded when omitted.</td>
+ <td align="center">No</td>
+ </tr>
+ <tr>
+ <td>excludesfile</td>
+ <td>the name of a file. Each line of this file is
+ taken to be an exclude pattern</td>
+ <td align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">implementation</td>
+ <td valign="top">The converter implementation to use.
+ If this attribute is not set, the default converter for the
+ current VM will be used. (See the above <a
+ href="#implementationvalues">list</a> of valid converters.)</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ </table>
+
+<h3>Parameters specified as nested elements</h3>
+
+<h4>arg</h4>
+
+<p>You can specify additional command line arguments for the converter
+with nested <code>&lt;arg&gt;</code> elements. These elements are
+specified like <a href="../using.html#arg">Command-line Arguments</a>
+but have an additional attribute that can be used to enable arguments
+only if a given converter implementation will be used.</p>
+
+<table border="1" cellpadding="2" cellspacing="0">
+<tr>
+ <td width="12%" valign="top"><b>Attribute</b></td>
+ <td width="78%" valign="top"><b>Description</b></td>
+ <td width="10%" valign="top"><b>Required</b></td>
+</tr>
+ <tr>
+ <td valign="top">value</td>
+ <td align="center" rowspan="4">See
+ <a href="../using.html#arg">Command-line Arguments</a>.</td>
+ <td align="center" rowspan="4">Exactly one of these.</td>
+ </tr>
+ <tr>
+ <td valign="top">line</td>
+ </tr>
+ <tr>
+ <td valign="top">file</td>
+ </tr>
+ <tr>
+ <td valign="top">path</td>
+ </tr>
+ <tr>
+ <td valign="top">implementation</td>
+ <td>Only pass the specified argument if the chosen converter
+ implementation matches the value of this attribute. Legal values
+ are the same as those in the above <a
+ href="#implementationvalues">list</a> of valid compilers.)</td>
+ <td align="center">No</td>
+ </tr>
+</table>
+
+<h4>implementationclasspath <em>since Apache Ant 1.8.0</em></h4>
+
+<p>A <a href="../using.html#path">PATH like structure</a> holding the
+ classpath to use when loading the converter implementation if a
+ custom class has been specified. Doesn't have any effect when
+ using one of the built-in converters.</p>
+
+<h4>Any nested element of a type that implements Native2AsciiAdapter
+ <em>since Ant 1.8.0</em></h4>
+
+<p>If a defined type implements the <code>Native2AsciiAdapter</code>
+ interface a nested element of that type can be used as an
+ alternative to the <code>implementation</code> attribute.</p>
+
+ <h3>Examples</h3>
+
+ <pre>
+&lt;native2ascii encoding=&quot;EUCJIS&quot; src=&quot;srcdir&quot; dest=&quot;srcdir&quot;
+ includes=&quot;**/*.eucjis&quot; ext=&quot;.java&quot;/&gt;
+ </pre>
+
+ <p>
+ Converts all files in the directory <em>srcdir</em>
+ ending in <code>.eucjis</code> from the EUCJIS encoding to ASCII
+ and renames them to end in <code>.java</code>.
+ </p>
+
+<pre>
+&lt;native2ascii encoding=&quot;EUCJIS&quot; src=&quot;native/japanese&quot; dest=&quot;src&quot;
+ includes=&quot;**/*.java&quot;/&gt;
+</pre>
+
+ <p>
+ Converts all the files ending in <code>.java</code>
+ in the directory <em>native/japanese</em> to ASCII,
+ placing the results in the directory <em>src</em>.
+ The names of the files remain the same.
+ </p>
+
+<p>If you want to use a custom
+ Native2AsciiAdapter <code>org.example.MyAdapter</code> you can either
+ use the implementation attribute:</p>
+<pre>
+&lt;native2ascii encoding="EUCJIS" src="srcdir" dest="srcdir"
+ includes="**/*.eucjis" ext=".java"
+ implementation="org.example.MyAdapter"/&gt;
+</pre>
+<p>or a define a type and nest this into the task like in:</p>
+<pre>
+&lt;componentdef classname="org.example.MyAdapter"
+ name="myadapter"/&gt;
+&lt;native2ascii encoding="EUCJIS" src="srcdir" dest="srcdir"
+ includes="**/*.eucjis" ext=".java"&gt;
+ &lt;myadapter/&gt;
+&lt;/native2ascii&gt;
+</pre>
+<p>in which case your native2ascii adapter can support attributes and
+ nested elements of its own.</p>
+ </body>
+
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/netrexxc.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/netrexxc.html
new file mode 100644
index 00000000..8102b727
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/netrexxc.html
@@ -0,0 +1,338 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>NetRexxC Task</title>
+</head>
+
+<body>
+
+<h2><a name="netrexxc">NetRexxC</a></h2>
+<h3>Description</h3>
+<p>Compiles a <a href="http://www2.hursley.ibm.com/netrexx" target="_top">NetRexx</a>
+source tree within the running (Apache Ant) VM.</p>
+<p>The source and destination directory will be recursively scanned for
+NetRexx source files to compile. Only NetRexx files that have no corresponding
+class file or where the class file is older than the java file will be compiled.</p>
+<p>Files in the source tree are copied to the destination directory,
+allowing support files to be located properly in the classpath. The source
+files are copied because the NetRexx compiler cannot produce class files in a
+specific directory via parameters</p>
+<p>The directory structure of the source tree should follow the package
+hierarchy.</p>
+<p>It is possible to refine the set of files that are being compiled/copied.
+This can be done with the <i>includes</i>, <i>includesfile</i>, <i>excludes</i>, <i>excludesfile</i> and
+<i>defaultexcludes</i> attributes. With the <i>includes</i> or <i>includesfile</i> attribute you
+specify the files you want to have included by using patterns. The
+<i>exclude</i> or <i>excludesfile</i> attribute is used to specify the files you want to have
+excluded. This is also done with patterns. And finally with the
+<i>defaultexcludes</i> attribute, you can specify whether you
+want to use default exclusions or not. See the section on <a
+href="../dirtasks.html#directorybasedtasks">directory based tasks</a>, on how the
+inclusion/exclusion of files works, and how to write patterns.</p>
+<p>This task forms an implicit <a href="../Types/fileset.html">FileSet</a> and
+supports most attributes of <code>&lt;fileset&gt;</code>
+(<code>dir</code> becomes <code>srcdir</code>) as well as the nested
+<code>&lt;include&gt;</code>, <code>&lt;exclude&gt;</code> and
+<code>&lt;patternset&gt;</code> elements.</p>
+<p>All properties except classpath, srcdir and destDir are also available as properties in the form
+<code>ant.netrexxc.<i>attributename</i></code>, eg.<br>
+<code>&lt;property name="ant.netrexxc.verbose" value="noverbose"/&gt;</code><br>
+or from the command line as<br>
+<code>ant -Dant.netrexxc.verbose=noverbose ...</code>
+</p>
+
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">binary</td>
+ <td valign="top">Whether literals are treated as the java binary
+ type rather than the NetRexx types</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">classpath</td>
+ <td valign="top">The classpath to use during compilation</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">comments</td>
+ <td valign="top">Whether comments are passed through to the
+ generated java source</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">compact</td>
+ <td valign="top">Whether error messages come out in compact or
+ verbose format. Default is the compact format.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">compile</td>
+ <td valign="top">Whether the NetRexx compiler should compile the
+ generated java code</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">console</td>
+ <td valign="top">Whether or not messages should be displayed on the
+ 'console'. Note that this task will rely on the default value for filtering compile messages.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">crossref</td>
+ <td valign="top">Whether variable cross references are generated</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">decimal</td>
+ <td valign="top">Whether decimal arithmetic should be used for the
+ NetRexx code. Setting this to off will report decimal arithmetic
+ as an error, for performance critical applications.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">defaultexcludes</td>
+ <td valign="top">indicates whether default excludes should be used or not
+ (&quot;yes&quot;/&quot;no&quot;). Default excludes are used when
+ omitted.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">destDir</td>
+ <td valign="top">the destination directory into which the NetRexx
+ source files should be copied and then compiled</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">diag</td>
+ <td valign="top">Whether diagnostic information about the compile is
+ generated</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">excludes</td>
+ <td valign="top">comma- or space-separated list of patterns of files that must be
+ excluded. No files (except default excludes) are excluded when
+ omitted.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">excludesfile</td>
+ <td valign="top">the name of a file. Each line of this file is
+ taken to be an exclude pattern</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">explicit</td>
+ <td valign="top">Whether variables must be declared explicitly
+ before use</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">format</td>
+ <td valign="top">Whether the generated java code is formatted nicely
+ or left to match NetRexx line numbers for call stack debugging</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">includes</td>
+ <td valign="top">comma- or space-separated list of patterns of files that must be
+ included. All files are included when omitted.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">includesfile</td>
+ <td valign="top">the name of a file. Each line of this file is
+ taken to be an include pattern</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">java</td>
+ <td valign="top">Whether the generated java code is produced</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">keep</td>
+ <td valign="top">Sets whether the generated java source file should be kept
+ after compilation. The generated files will have an extension of
+ .java.keep, <b>not</b> .java. Use removeKeepExtension to change that.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">logo</td>
+ <td valign="top">Whether the compiler text logo is displayed when
+ compiling</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">removeKeepExtension</td>
+ <td valign="top">Tells whether the trailing .keep in nocompile-mode should
+ be removed so that the resulting java source really ends on .java. This
+ facilitates the use of the javadoc tool lateron.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">replace</td>
+ <td valign="top">Whether the generated .java file should be replaced
+ when compiling</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">savelog</td>
+ <td valign="top">Whether the compiler messages will be written to
+ NetRexxC.log as well as to the console</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">sourcedir</td>
+ <td valign="top">Tells the NetRexx compiler to store the class files in the
+ same directory as the source files. The alternative is the working
+ directory</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">srcDir</td>
+ <td valign="top">Set the source dir to find the source NetRexx
+ files</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">strictargs</td>
+ <td valign="top">Tells the NetRexx compiler that method calls always
+ need parentheses, even if no arguments are needed, e.g.
+ <code>aStringVar.getBytes</code> vs.
+ <code>aStringVar.getBytes()</code></td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">strictassign</td>
+ <td valign="top">Tells the NetRexx compile that assignments must
+ match exactly on type</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">strictcase</td>
+ <td valign="top">Specifies whether the NetRexx compiler should be
+ case sensitive or not</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">strictimport</td>
+ <td valign="top">Whether classes need to be imported explicitly using an
+ <code>import</code> statement. By default the NetRexx compiler will
+ import certain packages automatically</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">strictprops</td>
+ <td valign="top">Whether local properties need to be qualified
+ explicitly using <code>this</code></td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">strictsignal</td>
+ <td valign="top">Whether the compiler should force catching of
+ exceptions by explicitly named types</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">symbols</td>
+ <td valign="top">Whether debug symbols should be generated into the
+ class file</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">time</td>
+ <td valign="top">Asks the NetRexx compiler to print compilation
+ times to the console</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">trace</td>
+ <td valign="top">Turns on or off tracing and directs the resultant
+ trace output</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">utf8</td>
+ <td valign="top">Tells the NetRexx compiler that the source is in UTF8</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">verbose</td>
+ <td valign="top">Whether lots of warnings and error messages should
+ be generated</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">suppressMethodArgumentNotUsed</td>
+ <td valign="top">Tells whether we should filter out the
+ &amp;Method argument not used&amp; messages in strictargs mode.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">suppressPrivatePropertyNotUsed</td>
+ <td valign="top">Tells whether we should filter out the
+ &amp;Private Property defined, but not used&amp; messages in strictargs mode.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">suppressVariableNotUsed</td>
+ <td valign="top">Tells whether we should filter out the
+ &amp;Variable set but not used&amp; messages in strictargs mode.
+ Please be careful with this one, as you can hide errors behind it!</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">suppressExceptionNotSignalled</td>
+ <td valign="top">Tells whether we should filter out the
+ &amp;Exception is declared, but not signalled within the method&amp;
+ messages in strictsignal mode.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">suppressDeprecation</td>
+ <td valign="top">Tells whether we should filter out any deprecation-messages
+ of the compiler out.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+</table>
+<h3>Examples</h3>
+<blockquote>
+ <p><code>&lt;netrexxc srcDir=&quot;/source/project&quot;
+ includes=&quot;vnr/util/*&quot;
+ destDir=&quot;/source/project/build&quot;
+ classpath=&quot;/source/project2/proj.jar&quot;
+ comments=&quot;true&quot;
+ crossref=&quot;false&quot; replace=&quot;true&quot;
+ keep=&quot;true&quot;/&gt;</code>
+ </p>
+</blockquote>
+
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/nice.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/nice.html
new file mode 100644
index 00000000..03c0eaaa
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/nice.html
@@ -0,0 +1,70 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Nice Task</title>
+</head>
+
+<body>
+
+<h2><a name="echo">Nice</a></h2>
+<h3>Description</h3>
+<p>Provide "nice-ness" to the current thread
+ and/or query the current value.</p>
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">currentpriority</td>
+ <td valign="top">the name of the property whose value should be
+ set to the current &quot;nice-ness&quot; level.
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">newpriority</td>
+ <td valign="top">the value to which the
+ &quot;nice-ness&quot; level should be set.
+ Must be a valid Java Thread priority.
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+</table>
+<h3>Examples</h3>
+<pre> &lt;nice newpriority=&quot;10&quot;/&gt;</pre>
+Set the Thread priority to 10 (highest).
+<pre> &lt;nice currentpriority=&quot;priority&quot;/&gt;</pre>
+Store the current Thread priority in the user property "priority".
+<pre>
+ &lt;nice currentpriority=&quot;currentpriority&quot; newpriority=&quot;1&quot;/&gt;
+</pre>
+<p>Set the current Thread priority to 1 (lowest), storing the original
+priority in the user property "currentpriority". This
+can be used to set the priority back to its original value later.
+</p>
+
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/pack.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/pack.html
new file mode 100644
index 00000000..60ae1e52
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/pack.html
@@ -0,0 +1,76 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>GZip/BZip2 Tasks</title>
+</head>
+
+<body>
+
+<h2><a name="pack">GZip/BZip2</a></h2>
+<h3>Description</h3>
+<p>Packs a resource using the GZip or BZip2 algorithm.
+The output file is only generated if it doesn't exist or the source
+resource is newer.</p>
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">src</td>
+ <td valign="top">the file to gzip/bzip.</td>
+ <td align="center" valign="top">Yes, or a nested resource collection.</td>
+ </tr>
+ <tr>
+ <td valign="top">destfile</td>
+ <td valign="top">the destination file to create.</td>
+ <td align="center" valign="top" rowspan="2">Exactly one of the two.</td>
+ </tr>
+ <tr>
+ <td valign="top">zipfile</td>
+ <td valign="top">the <i>deprecated</i> old name of destfile.</td>
+ </tr>
+</table>
+<h4>any <a href="../Types/resources.html">resource</a> or single element
+resource collection</h4>
+
+<p>The specified resource will be used as src. <em>Since Apache Ant 1.7</em></p>
+
+<h3>Examples</h3>
+<blockquote><pre>
+&lt;gzip src=&quot;test.tar&quot; destfile=&quot;test.tar.gz&quot;/&gt;
+</pre></blockquote>
+<blockquote><pre>
+&lt;bzip2 src=&quot;test.tar&quot; destfile=&quot;test.tar.bz2&quot;/&gt;
+</pre></blockquote>
+<blockquote><pre>
+&lt;gzip destfile=&quot;archive.tar.gz&quot;&gt;
+ &lt;url url="http://example.org/archive.tar"/&gt;
+&lt;/gzip&gt;
+</pre></blockquote>
+<p>downloads <i>http://example.org/archive.tar</i> and compresses it
+to <i>archive.tar.gz</i> in the project's basedir on the fly.</p>
+
+
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/parallel.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/parallel.html
new file mode 100644
index 00000000..362daf37
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/parallel.html
@@ -0,0 +1,235 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Parallel Task</title>
+</head>
+
+<body>
+
+<h2>Parallel</h2>
+<h3>Description</h3>
+<p>
+ Executes nested tasks in parallel with no guarantees of thread safety.
+ Every task will run in its own thread, with the likelihood of
+ concurrency problems scaling with the number of CPUs on the host system.
+</p>
+<p><b>Warning:</b> While the Apache Ant core is believed to be thread safe, no such
+ guarantees are made about tasks, which are not tested for thread safety during
+ Ant's test process.
+ Third party tasks may or may not be thread safe, and some of Ant's core tasks, such as
+ <code>&lt;javac&gt;</code> are definitely not re-entrant. This is because they use libraries that
+ were never designed to be used in a multithreaded environment.
+</p>
+<p>
+ The primary use case for <code>&lt;parallel&gt;</code> is to run external programs
+ such as an application server, and the JUnit or TestNG test suites at the
+ same time. Anyone trying to run large Ant task sequences in parallel, such
+ as javadoc and javac at the same time, is implicitly taking on the task
+ of identifying and fixing all concurrency bugs the tasks that they run.
+
+</p>
+<p>
+ Accordingly, while this task has uses, it should be considered an advanced
+ task which should be used in certain batch-processing or testing situations,
+ rather than an easy trick to speed up build times on a multiway CPU.
+</p>
+
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">threadCount</td>
+ <td valign="top">Maximum numbers of thread to use.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">threadsPerProcessor</td>
+ <td valign="top">Maximum number of threads to use per available processor
+(Java 1.4+)</td>
+ <td align="center" valign="top">No, defers to threadCount</td>
+ </tr>
+ <tr>
+ <td valign="top">timeout</td>
+ <td valign="top">Number of milliseconds before execution is terminated</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">failonany</td>
+ <td valign="top">If any of the nested tasks fails, execution of the task completes
+ at that point without waiting for any other tasks to complete.</td>
+ <td align="center" valign="top">No, default is false.</td>
+ </tr>
+ <tr>
+ <td valign="top">pollInterval</td>
+ <td valign="top">Currently has no effect</td>
+ <td align="center" valign="top">No, default is 1000</td>
+ </tr>
+</table>
+
+<p>Parallel tasks have a number of uses in an Ant build file including:</p>
+<ul>
+<li>Taking advantage of available processing resources to execute external
+ programs simultaneously.</li>
+<li>Testing servers, where the server can be run in one thread and the test
+harness is run in another thread.</li>
+</ul>
+
+<p>Any valid Ant task may be embedded within a
+parallel task, including other parallel tasks, though there is no guarantee that
+the tasks will be thread safe in such an environment.</p>
+
+<p>While the tasks within the parallel task are being run, the main
+thread will be blocked waiting for all the child threads to complete. If
+execution is terminated by a timeout or a nested task failure when the
+<code>failonany</code>
+flag is set, the parallel task will complete without waiting for other nested
+tasks to complete in other threads.
+</p>
+
+<p>If any of the tasks within the <code>&lt;parallel&gt;</code> task fails and failonany is
+not set, the remaining tasks in other threads will continue to run until
+all threads have completed. In this situation, the parallel task will also fail.</p>
+
+<p>The parallel task may be combined with the <a href="sequential.html">
+sequential</a> task to define sequences of tasks to be executed on each thread
+within the parallel block</p>
+
+<p>The <code>threadCount</code> attribute can be used to place a maximum number of available
+threads for the execution. When not present all child tasks will be executed at
+once. When present then the maximum number of concurrently executing tasks will
+not exceed the number of threads specified. Furthermore, each task will be
+started in the order they are given. But no guarantee is made as to the speed
+of execution or the order of completion of the tasks, only that each will be
+started before the next.<p>
+
+<p>If you are using Java 1.4 or later you can also use the <code>threadsPerProcessor</code>
+and the number of available threads will be the stated multiple of the number of
+processors (there is no affinity to a particular processor however). This will
+override the value in <code>threadCount</code>. If <code>threadsPerProcessor</code>
+is specified on any older JVM, then the value in <code>threadCount</code> will be used as is.</p>
+
+<p>When using <code>threadCount</code> and <code>threadsPerProcessor</code>
+ care should be taken to ensure that the build does not deadlock.
+ This can be caused by tasks such as <code>waitfor</code>
+ taking up all available threads before the tasks that would unlock the
+ <code>waitfor</code>
+would occur. This is not a replacement for Java Language level thread
+semantics and is best used for "embarassingly parallel" tasks.</p>
+
+
+<h3>Parameters specified as nested elements</h3>
+
+<h4>daemons</h4>
+<p>
+The parallel task supports a <code>&lt;daemons&gt;</code> nested element. This is a list of tasks
+which are to be run in parallel daemon threads. The parallel task will not wait for
+these tasks to complete. Being daemon threads, however, they will not prevent Ant from
+completing, whereupon the threads are terminated. Failures in daemon threads which
+occur before the parallel task itself finishes will be reported and can cause
+parallel to throw an exception. Failures which occur after parallel has completed are not
+reported.
+</p>
+
+<p>Daemon tasks can be used, for example, to start test servers which might not be easily
+terminated from Ant. By using <code>&lt;daemons&gt;</code> such servers do not halt the build.
+</p>
+
+
+<h3>Examples</h3>
+<pre>
+&lt;parallel&gt;
+ &lt;wlrun ... &gt;
+ &lt;sequential&gt;
+ &lt;sleep seconds=&quot;30&quot;/&gt;
+ &lt;junit fork="true" forkmode="once" ... &gt;
+ &lt;wlstop/&gt;
+ &lt;/sequential&gt;
+&lt;/parallel&gt;
+</pre>
+<p>This example represents a typical pattern for testing a server application.
+In one thread the server is started (the <code>&lt;wlrun&gt;</code> task).
+The other thread consists
+of a three tasks which are performed in sequence. The <code>&lt;sleep&gt;</code> task is used to
+give the server time to come up. Another task which is capable of validating
+that the server is available could be used in place of the <code>&lt;sleep&gt;</code> task. The
+<code>&lt;junit&gt;</code> test harness then runs, again in its own JVM. Once the tests are complete, the server is stopped
+(using <code>&lt;wlstop&gt;</code> in this example), allowing both threads to complete. The
+<code>&lt;parallel&gt;</code> task will also complete at this time and the build will then
+continue.</p>
+
+<pre>
+&lt;parallel&gt;
+ &lt;javac fork="true"...&gt; &lt;!-- compiler servlet code --&gt;
+ &lt;wljspc ...&gt; &lt;!-- precompile JSPs --&gt;
+&lt;/parallel&gt;
+</pre>
+
+<p>This example shows two independent tasks being run to achieve better
+resource utilization during the build. In this instance, some servlets are being
+compiled in one thead and a set of JSPs is being precompiled in another. Developers
+need to be careful that the two tasks are independent, both in
+terms of their dependencies and in terms of their potential interactions in
+Ant's external environment. Here we set <code>fork="true"</code> for the
+<code>&lt;javac&gt;</code> task, so that it runs in a new process;
+if the <code>&lt;wljspc&gt;</code> task used the javac compiler in-VM
+(it may), concurrency problems may arise.
+</p>
+
+<pre>
+ &lt;macrodef name="dbpurge"&gt;
+ &lt;attribute file="file"/&gt;
+ &lt;sequential&gt;
+ &lt;java jar="utils/dbpurge.jar" fork="true" &gt;
+ &lt;arg file="@{file} /&gt;
+ &lt;/java&gt;
+ &lt;/sequential&gt;
+&lt;/macrodef&gt;
+
+&lt;parallel threadCount="4"&gt;
+ &lt;dbpurge file="db/one" /&gt;
+ &lt;dbpurge file="db/two" /&gt;
+ &lt;dbpurge file="db/three" /&gt;
+ &lt;dbpurge file="db/four" /&gt;
+ &lt;dbpurge file="db/five" /&gt;
+ &lt;dbpurge file="db/six" /&gt;
+ &lt;dbpurge file="db/seven" /&gt;
+ &lt;dbpurge file="db/eight" /&gt;
+ &lt;!-- repeated about 40 times --&gt;
+&lt;/parallel&gt;
+</pre>
+
+<p>This example represents a typical need for use of the threadCount and
+threadsPerProcessor attributes. Spinning up all 40 of those tasks could cripple
+the system for memory and CPU time. By limiting the number of
+concurrent executions you can reduce contention for CPU, memory and disk IO,
+and so actually finish faster. This is also a good
+candidate for use of threadCount (and possibly threadsPerProcessor) because
+each task is independent (every new JVM is forked) and has no dependencies on
+the other tasks.</p>
+
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/patch.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/patch.html
new file mode 100644
index 00000000..96a5ee9a
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/patch.html
@@ -0,0 +1,111 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Patch Task</title>
+</head>
+
+<body>
+
+<h2><a name="patch">Patch</a></h2>
+<h3>Description</h3>
+<p>Applies a diff file to originals. ; requires "patch" to be
+ on the execution path. </p>
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">patchfile</td>
+ <td valign="top">the file that includes the diff output</td>
+ <td align="center" valign="top">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">originalfile</td>
+ <td valign="top">the file to patch</td>
+ <td align="center" valign="top">No, tries to guess it from the diff
+ file</td>
+ </tr>
+ <tr>
+ <td valign="top">destfile</td>
+ <td valign="top">the file to send the output to instead of
+ patching the file(s) in place. <em>since Apache Ant 1.6</em></td>
+ <td align="center" valign="top">No.</td>
+ </tr>
+ <tr>
+ <td valign="top">backups</td>
+ <td valign="top">Keep backups of the unpatched files</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">quiet</td>
+ <td valign="top">Work silently unless an error occurs</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">reverse</td>
+ <td valign="top">Assume patch was created with old and new files
+ swapped.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">ignorewhitespace</td>
+ <td valign="top">Ignore whitespace differences.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">strip</td>
+ <td valign="top">Strip the smallest prefix containing <i>num</i> leading
+ slashes from filenames.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">dir</td>
+ <td valign="top">The directory in which to run the patch command.</td>
+ <td align="center" valign="top">No, default is the project's basedir.</td>
+ </tr>
+ <tr>
+ <td valign="top">failonerror</td>
+ <td valign="top">Stop the buildprocess if the command exits with a
+ return code signaling failure. Defaults to false.
+ <em>since Ant 1.8.0</em></td>
+ <td align="center" valign="top">No</td>
+ </tr>
+</table>
+<h3>Examples</h3>
+<pre> &lt;patch patchfile=&quot;module.1.0-1.1.patch&quot;/&gt;</pre>
+<p>applies the diff included in <i>module.1.0-1.1.patch</i> to the
+files in base directory guessing the filename(s) from the diff output.</p>
+<pre> &lt;patch patchfile=&quot;module.1.0-1.1.patch&quot; strip=&quot;1&quot;/&gt;</pre>
+<p>like above but one leading directory part will be removed. i.e. if
+the diff output looked like</p>
+<pre>
+--- a/mod1.0/A Mon Jun 5 17:28:41 2000
++++ a/mod1.1/A Mon Jun 5 17:28:49 2000
+</pre>
+the leading <i>a/</i> will be stripped.
+
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/pathconvert.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/pathconvert.html
new file mode 100644
index 00000000..41f56f47
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/pathconvert.html
@@ -0,0 +1,224 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>PathConvert Task</title>
+</head>
+
+<body>
+
+<h2><a name="pathconvert">Pathconvert</a></h2>
+<h3>Description</h3>
+<p>Converts nested <a href="../Types/resources.html#collection">
+ResourceCollection</a>s, or a reference to just one, into a path
+form for a particular platform, optionally storing the result into
+a given property. It can also be used when you need
+to convert a Resource Collection into a list, separated by a given
+character, such as a comma or space, or, conversely, e.g. to convert a list
+of files in a FileList into a path.
+</p>
+<p>Nested <code>&lt;map&gt;</code> elements can be specified to map Windows
+drive letters to Unix paths, and vice-versa.</p>
+<p>More complex transformations can be achieved using a nested
+<a href="../Types/mapper.html"><code>&lt;mapper&gt;</code></a>
+(since Apache Ant 1.6.2).
+</p>
+
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">targetos</td>
+ <td valign="top">
+ The target architecture. Must be one of 'unix', 'windows',
+ 'netware', 'tandem' or 'os/2'.
+ This is a shorthand mechanism for specifying both
+ <code>pathsep</code> and <code>dirsep</code>
+ according to the specified target architecture.
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">dirsep</td>
+ <td valign="top">
+ The character(s) to use as the directory separator in the
+ generated paths.
+ </td>
+ <td valign="top" align="center">No, defaults to current JVM <tt>File.separator</tt></td>
+ </tr>
+ <tr>
+ <td valign="top">pathsep</td>
+ <td valign="top">
+ The character(s) to use as the path-element separator in the
+ generated paths.
+ </td>
+ <td valign="top" align="center">No, defaults to current JVM <tt>File.pathSeparator</tt></td>
+ </tr>
+ <tr>
+ <td valign="top">property</td>
+ <td valign="top">The name of the property in which to place the converted path.</td>
+ <td valign="top" align="center">No, result will be logged if unset</td>
+ </tr>
+ <tr>
+ <td valign="top">refid</td>
+ <td valign="top">What to convert, given as a
+ <a href="../using.html#references">reference</a> to a
+ <code>&lt;path&gt;</code>, <code>&lt;fileset&gt;</code>,
+ <code>&lt;dirset&gt;</code>, or <code>&lt;filelist&gt;</code>
+ defined elsewhere</td>
+ <td valign="top" align="center">No; if omitted, a nested
+ <code>&lt;path&gt;</code> element must be supplied.</td>
+ </tr>
+ <tr>
+ <td valign="top">setonempty</td>
+ <td valign="top">Should the property be set, even if the result
+ is the empty string?
+ <td valign="top" align="center">No; default is &quot;true&quot;.
+ </tr>
+ <tr>
+ <td valign="top">preserveduplicates</td>
+ <td valign="top">Whether to preserve duplicate resources. <b>Since Ant 1.8</b></td>
+ <td valign="top" align="center">No; default &quot;false&quot;.
+ </tr>
+</table>
+<h3>Parameters specified as nested elements</h3>
+<h4>map</h4>
+<p>Specifies the mapping of path prefixes between Unix and Windows.</p>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">from</td>
+ <td valign="top">
+ The prefix to match. Note that this value is case-insensitive when
+ the build is running on a Windows platform and case-sensitive
+ when running on a Unix platform.
+ <em>Since Ant 1.7.0</em>, on Windows this value is also insensitive
+ to the slash style used for directories, one can use '/' or '\'.
+ </td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">to</td>
+ <td valign="top">The replacement text to use when <code>from</code> is matched.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+</table>
+
+<p>Each map element specifies a single replacement map to be applied to the elements of
+ the path being processed. If no map entries are specified, then no path prefix mapping
+ is performed.
+</p>
+<p><strong>Note</strong>: The map elements are applied in the order specified,
+and only the first matching map element is applied. So, the ordering of
+your map elements can be important, if any <code>from</code> values are
+prefixes of other <code>from</code> values.</i>
+</p>
+<h4>Resource Collections</h4>
+<p>If the <code>refid</code> attribute is not specified, then one or more
+ nested <a href="../Types/resources.html#collection">Resource
+Collection</a>s must be supplied.</p>
+<h4>mapper</h4>
+<p>A single nested <a href="../Types/mapper.html">
+<code>&lt;mapper&gt;</code></a> element can be specified
+to perform any of various filename transformations (since Ant 1.6.2).
+</p>
+
+<h3>Examples</h3>
+<p>In the examples below, assume that the <code>${wl.home}</code> property
+has the value
+<code>d:\weblogic</code>, and <code>${wl.home.unix}</code> has the value
+<code>/weblogic</code>.</p>
+<h4>Example 1</h4>
+<pre>
+ &lt;path id="wl.path"&gt;
+ &lt;pathelement location=&quot;${wl.home}/lib/weblogicaux.jar&quot;/&gt;
+ &lt;pathelement location=&quot;${wl.home}/classes&quot;/&gt;
+ &lt;pathelement location=&quot;${wl.home}/mssqlserver4/classes&quot;/&gt;
+ &lt;pathelement location=&quot;c:\winnt\System32&quot;/&gt;
+ &lt;/path&gt;
+
+ &lt;pathconvert targetos=&quot;unix&quot; property=&quot;wl.path.unix&quot; refid=&quot;wl.path&quot;&gt;
+ &lt;map from=&quot;${wl.home}&quot; to=&quot;${wl.home.unix}&quot;/&gt;
+ &lt;map from=&quot;c:&quot; to=&quot;&quot;/&gt;
+ &lt;/pathconvert&gt;
+</pre>
+<p> will generate the path shown below
+and store it in the property named <code>wl.path.unix</code>.
+</p>
+<pre>
+/weblogic/lib/weblogicaux.jar:/weblogic/classes:/weblogic/mssqlserver4/classes:/WINNT/SYSTEM32
+</pre>
+
+<h4>Example 2</h4>
+Given a FileList defined as:
+<pre>
+ &lt;filelist id=&quot;custom_tasks.jars&quot;
+ dir=&quot;${env.HOME}/ant/lib&quot;
+ files=&quot;njavac.jar,xproperty.jar&quot;/&gt;
+</pre>
+then:
+<pre>
+ &lt;pathconvert targetos=&quot;unix&quot; property=&quot;custom_tasks.jars&quot; refid=&quot;custom_tasks.jars&quot;&gt;
+ &lt;map from=&quot;${env.HOME}&quot; to=&quot;/usr/local&quot;/&gt;
+ &lt;/pathconvert&gt;
+</pre>
+will convert the list of files to the following Unix path:
+<pre>
+/usr/local/ant/lib/njavac.jar:/usr/local/ant/lib/xproperty.jar
+</pre>
+
+<h4>Example 3</h4>
+<pre>
+ &lt;fileset dir=&quot;${src.dir}&quot; id=&quot;src.files&quot;&gt;
+ &lt;include name=&quot;**/*.java&quot;/&gt;
+ &lt;/fileset&gt;
+
+ &lt;pathconvert pathsep=&quot;,&quot; property=&quot;javafiles&quot; refid=&quot;src.files&quot;/&gt;
+</pre>
+<p>This example takes the set of files determined by the fileset (all files ending
+in <tt>.java</tt>), joins them together separated by commas, and places the resulting
+list into the property <tt>javafiles</tt>. The directory separator is not specified, so
+it defaults to the appropriate character for the current platform. Such a list could
+then be used in another task, like <tt>javadoc</tt>, that requires a comma separated
+list of files.
+</p>
+<h4>Example 4</h4>
+<pre>
+ &lt;pathconvert property="prop" dirsep="|"&gt;
+ &lt;map from="${basedir}/abc/" to=''/&gt;
+ &lt;path location="abc/def/ghi"/&gt;
+ &lt;/pathconvert&gt;
+</pre>
+ <p>
+ This example sets the property "prop" to "def|ghi" on
+ Windows and on Unix.
+ </p>
+</body>
+</html>
+
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/presetdef.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/presetdef.html
new file mode 100644
index 00000000..c7f381c0
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/presetdef.html
@@ -0,0 +1,184 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+ <head>
+ <meta http-equiv="Content-Language" content="en-us"></meta>
+ <link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>PreSetDef Task</title>
+ <style type="text/css">
+ <!--
+ .code { background: #EFEFEF; margin-top: }
+ -->
+ </style>
+ </head>
+
+ <body>
+
+ <h2><a name="presetdef">PreSetDef</a></h2>
+ <h3>Description</h3>
+ <p>
+ The preset definition generates a new definition
+ based on a current definition with some attributes
+ or elements preset.
+ </p>
+ <p>
+ <em>since Apache Ant 1.6</em>
+ </p>
+ <p>
+ The resolution of properties in any of the attributes or
+ nested text takes place with the definition is used and <em>not</em>
+ when the preset definition is defined.
+ </p>
+ <h3>Parameters</h3>
+ <table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">name</td>
+ <td valign="top">the name of the new definition</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">uri</td>
+ <td valign="top">
+ The uri that this definition should live in.
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ </table>
+ <h3>Parameters specified as nested elements</h3>
+ <h4>another type with attributes or elements set</h4>
+ <p>The <code>&lt;presetdef&gt;</code> task takes one nested element as a parameter.
+ This nested element can be any other type or task. The attributes
+ and elements that need to be preset are placed here.
+ </p>
+
+ <h3>Examples</h3>
+ The following fragment defines a javac task with the debug, deprecation
+ srcdir and destdir
+ attributes set. It also has a src element to source files from a generated
+ directory.
+ <blockquote>
+<pre class="code">
+&lt;presetdef name="my.javac"&gt;
+ &lt;javac debug="${debug}" deprecation="${deprecation}"
+ srcdir="${src.dir}" destdir="${classes.dir}"&gt;
+ &lt;src path="${gen.dir}"/&gt;
+ &lt;/javac&gt;
+&lt;/presetdef&gt;
+</pre>
+ </blockquote>
+ This can be used as a normal javac task - example:
+ <blockquote>
+<pre class="code">
+&lt;my.javac/&gt;
+</pre>
+ </blockquote>
+ The attributes specified in the preset task may be overridden - i.e.
+ they may be seen as optional attributes - example:
+ <blockquote>
+<pre class="code">
+&lt;my.javac srcdir="${test.src}" deprecation="no"/&gt;
+</pre>
+ </blockquote>
+ One may put a presetdef definition in an antlib.
+ For example suppose the jar file antgoodies.jar has
+ the antlib.xml as follows:
+ <blockquote>
+<pre class="code">
+&lt;antlib&gt;
+ &lt;taskdef resource="com/acme/antgoodies/tasks.properties"/&gt;
+ &lt;!-- Implement the common use of the javac command --&gt;
+ &lt;presetdef name="javac"&gt;
+ &lt;javac deprecation="${deprecation}" debug="${debug}"
+ srcdir="src" destdir="classes"/&gt;
+ &lt;/presetdef&gt;
+&lt;/antlib&gt;
+</pre>
+ </blockquote>
+ One may then use this in a build file as follows:
+ <blockquote>
+<pre class="code">
+&lt;project default="example" xmlns:antgoodies="antlib:com.acme.antgoodies"&gt;
+ &lt;target name="example"&gt;
+ &lt;!-- Compile source --&gt;
+ &lt;antgoodies:javac srcdir="src/main"/&gt;
+ &lt;!-- Compile test code --&gt;
+ &lt;antgoodies:javac srcdir="src/test"/&gt;
+ &lt;/target&gt;
+&lt;/project&gt;
+</pre>
+ </blockquote>
+ <p>
+ The following is an example of evaluation of properties when the
+ definition is used:
+ </p>
+ <blockquote>
+<pre class="code">
+&lt;target name="defineandcall"&gt;
+ &lt;presetdef name="showmessage"&gt;
+ &lt;echo&gt;message is '${message}'&lt;/echo&gt;
+ &lt;/presetdef&gt;
+ &lt;showmessage/&gt;
+ &lt;property name="message" value="Message 1"/&gt;
+ &lt;showmessage/&gt;
+ &lt;antcall target="called"&gt;
+ &lt;param name="message" value="Message 2"/&gt;
+ &lt;/antcall&gt;
+&lt;/target&gt;
+&lt;target name="called"&gt;
+ &lt;showmessage/&gt;
+&lt;/target&gt;
+</pre>
+ </blockquote>
+ <p>
+ The command ant defineandcall results in the output:
+ </p>
+ <blockquote>
+<pre class="code">
+defineandcall:
+[showmessage] message is '${message}'
+[showmessage] message is 'Message 1'
+
+called:
+[showmessage] message is 'Message 2'
+</pre>
+ </blockquote>
+<p>
+It is possible to use a trick to evaluate properties when the definition is
+<em>made</em> rather than used. This can be useful if you do not expect some
+properties to be available in child builds run with
+<code>&lt;ant ... inheritall="false"&gt;</code>:
+</p>
+<blockquote><pre class="code">
+&lt;macrodef name="showmessage-presetdef"&gt;
+ &lt;attribute name="messageval"/&gt;
+ &lt;presetdef name="showmessage"&gt;
+ &lt;echo&gt;message is '@{messageval}'&lt;/echo&gt;
+ &lt;/presetdef&gt;
+&lt;/macrodef&gt;
+&lt;showmessage-presetdef messageval="${message}"/&gt;
+</pre></blockquote>
+ <hr></hr>
+
+ </body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/projecthelper.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/projecthelper.html
new file mode 100644
index 00000000..ea78eb2e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/projecthelper.html
@@ -0,0 +1,59 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>ProjectHelper Task</title>
+</head>
+
+<body>
+
+<h2>ProjectHelper</h2>
+<h3>Description</h3>
+<p>This task is provided for the purpose of allowing the user to install a different
+ProjectHelper at runtime.
+</p>
+<p>The helpers will be added after all the already registered helpers, but before
+the default one (ProjectHelper2)
+</p>
+<p>See the description of Apache Ant's
+<a href="../projecthelper.html">Project Helper</a> for more information.
+</p>
+<p><b>Since Ant 1.8.2</b></p>
+
+<h3>Parameters specified as nested elements</h3>
+
+You may specify many configured <code>org.apache.tools.ant.ProjectHelper</code> instances.
+
+<h3>Example</h3>
+
+<p>Install a custom ProjectHelper implementation
+ (assuming <code>MyProjectHelper extends ProjectHelper</code>):</p>
+
+<pre>
+&lt;typedef classname="org.example.MyProjectHelper"
+ name="myprojecthelper"/>
+&lt;projecthelper>
+ &lt;myprojecthelper/>
+&lt;/projecthelper>
+</pre>
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/property.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/property.html
new file mode 100644
index 00000000..7dc90a75
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/property.html
@@ -0,0 +1,345 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Property Task</title>
+</head>
+
+<body>
+
+<h2><a name="property">Property</a></h2>
+<h3>Description</h3>
+<p>Sets a <a href="../using.html#properties">property</a>
+(by name and value), or set of properties (from file or
+resource) in the project. Properties are case sensitive.</p>
+ Properties are immutable: whoever sets a property first freezes it for the
+ rest of the build; they are most definitely not variables.
+<p>There are seven ways to set properties:</p>
+<ul>
+ <li>By supplying both the <i>name</i> and one of <i>value</i> or <i>location</i> attribute.</li>
+ <li>By supplying the <i>name</i> and nested text.</li>
+ <li>By supplying both the <i>name</i> and <i>refid</i> attribute.</li>
+ <li>By setting the <i>file</i> attribute with the filename of the property
+ file to load. This property file has the format as defined by the file used
+ in the class java.util.Properties, with the same rules about how
+ non-ISO8859-1 characters must be escaped.</li>
+ <li>By setting the <i>url</i> attribute with the url from which to load the
+ properties. This url must be directed to a file that has the format as defined
+ by the file used in the class java.util.Properties.</li>
+ <li>By setting the <i>resource</i> attribute with the resource name of the
+ property file to load. A resource is a property file on the current
+ classpath, or on the specified classpath.</li>
+ <li>By setting the <i>environment</i> attribute with a prefix to use.
+ Properties will be defined for every environment variable by
+ prefixing the supplied name and a period to the name of the variable.</li>
+</ul>
+<p>Although combinations of these ways are possible, only one should be used
+at a time. Problems might occur with the order in which properties are set, for
+instance.</p>
+<p>The value part of the properties being set, might contain references to other
+properties. These references are resolved at the time these properties are set.
+This also holds for properties loaded from a property file.</p>
+<p>A list of predefined properties can be found <a
+href="../properties.html#built-in-props">here</a>.</p>
+<p>Since Apache Ant 1.8.0 it is possible to load properties defined in xml
+according to <a href="http://java.sun.com/dtd/properties.dtd">Suns DTD</a>,
+if Java5+ is present. For this the name of the file, resource or url has
+to end with <tt>.xml</tt>.</p>
+
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">name</td>
+ <td valign="top">the name of the property to set.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">value</td>
+ <td valign="top">the value of the property.</td>
+ <td valign="middle" align="center" rowspan="3">One of these or
+ nested text, when using the name attribute</td>
+ </tr>
+ <tr>
+ <td valign="top">location</td>
+ <td valign="top">Sets the property to the absolute filename of the
+ given file. If the value of this attribute is an absolute path, it
+ is left unchanged (with / and \ characters converted to the
+ current platforms conventions). Otherwise it is taken as a path
+ relative to the project's basedir and expanded.</td>
+ </tr>
+ <tr>
+ <td valign="top">refid</td>
+ <td valign="top"><a href="../using.html#references">Reference</a> to an object
+ defined elsewhere. Only yields reasonable results for references
+ to <a href="../using.html#path">PATH like structures</a> or properties.</td>
+ </tr>
+ <tr>
+ <td valign="top">resource</td>
+ <td valign="top"> the name of the classpath resource containing
+ properties settings in properties file format.</td>
+ <td valign="middle" align="center" rowspan="4">One of these, when
+ <b>not</b> using the name attribute</td>
+ </tr>
+ <tr>
+ <td valign="top">file</td>
+ <td valign="top">the location of the properties file to load.</td>
+ </tr>
+ <tr>
+ <td valign="top">url</td>
+ <td valign="top">a url containing properties-format settings.</td>
+ </tr>
+ <tr>
+ <td valign="top">environment</td>
+ <td valign="top">the prefix to use when retrieving environment variables. Thus
+ if you specify environment=&quot;myenv&quot; you will be able to access OS-specific
+ environment variables via property names &quot;myenv.PATH&quot; or
+ &quot;myenv.TERM&quot;. Note that if you supply a property name with a final
+ &quot;.&quot; it will not be doubled; i.e. environment=&quot;myenv.&quot; will still
+ allow access of environment variables through &quot;myenv.PATH&quot; and
+ &quot;myenv.TERM&quot;. This functionality is currently only implemented
+ on <a href="#notes-env">select platforms</a>. Feel free to send patches to increase the
+ number of platforms on which this functionality is supported ;).<br>
+ Note also that properties are case-sensitive, even if the
+ environment variables on your operating system are not; e.g. Windows 2000's
+ system path variable is set to an Ant property named "env.Path"
+ rather than "env.PATH".</td>
+ </tr>
+ <tr>
+ <td valign="top">classpath</td>
+ <td valign="top">the classpath to use when looking up a resource.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">classpathref</td>
+ <td valign="top">the classpath to use when looking up a resource,
+ given as <a href="../using.html#references">reference</a> to a <code>&lt;path&gt;</code> defined
+ elsewhere..</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">prefix</td>
+ <td valign="top">Prefix to apply to properties loaded using <code>file</code>,
+ <code>resource</code>, or <code>url</code>.
+ A "." is appended to the prefix if not specified.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">prefixValues</td>
+ <td valign="top">Whether to apply the prefix when expanding the
+ right hand side of properties loaded using <code>file</code>,
+ <code>resource</code>, or <code>url</code>.
+ <em>Since Ant 1.8.2</em></td>
+ <td align="center" valign="top">No (default=<tt>false</tt>)</td>
+ </tr>
+ <tr>
+ <td valign="top">relative</td>
+ <td valign="top">If set to <tt>true</tt> the relative path
+ to <tt>basedir</tt> is set. <em>Since Ant 1.8.0</em></td>
+ <td align="center" valign="top">No (default=<tt>false</tt>)</td>
+ </tr>
+ <tr>
+ <td valign="top">basedir</td>
+ <td valign="top">The basedir to calculate the relative path
+ from. <em>Since Ant 1.8.0</em></td>
+ <td align="center" valign="top">No (default=<tt>${basedir}</tt>)</td>
+ </tr>
+</table>
+
+<h4>OpenVMS Users</h4>
+<p>With the <code>environment</code> attribute this task will load all defined
+logicals on an OpenVMS system. Logicals with multiple equivalence names get
+mapped to a property whose value is a comma separated list of all equivalence
+names. If a logical is defined in multiple tables, only the most local
+definition is available (the table priority order being PROCESS, JOB, GROUP,
+SYSTEM).
+</p>
+
+<h4>Any OS except OpenVMS</h4>
+<p>Starting with Ant 1.8.2 if Ant detects it is running of a Java 1.5
+ VM (or better) Ant will use <code>System.getenv</code> rather than
+ its own OS dependent native implementation. For some OSes this
+ causes minor differences when compared to older versions of Ant.
+ For a full list
+ see <a href="https://issues.apache.org/bugzilla/show_bug.cgi?id=49366">Bugzilla
+ Issue 49366</a>. In particular:</p>
+<ul>
+ <li>On Windows Ant will now return additional "environment
+ variables" that correspond to the drive specific current working
+ directories when Ant is run from the command line. The keys of
+ these variables starts with an equals sign.</li>
+ <li>Some users reported that some Cygwin specific variables (in
+ particular PROMPT) was no longer present.</li>
+ <li>On OS/2 Ant no longer returns the BEGINLIBPATH variable.</li>
+</ul>
+
+<h3>Parameters specified as nested elements</h3>
+<h4>classpath</h4>
+<p><code>Property</code>'s <i>classpath</i> attribute is a <a
+href="../using.html#path">PATH like structure</a> and can also be set via a nested
+<i>classpath</i> element.</p>
+
+<h3>Examples</h3>
+<pre> &lt;property name=&quot;foo.dist&quot; value=&quot;dist&quot;/&gt;</pre>
+<p>sets the property <code>foo.dist</code> to the value &quot;dist&quot;.</p>
+
+<pre> &lt;property name=&quot;foo.dist&quot;&gt;dist&lt;/property&gt;</pre>
+<p>sets the property <code>foo.dist</code> to the value &quot;dist&quot;.</p>
+
+<pre> &lt;property file=&quot;foo.properties&quot;/&gt;</pre>
+<p>reads a set of properties from a file called &quot;foo.properties&quot;.</p>
+
+<pre> &lt;property url=&quot;http://www.mysite.com/bla/props/foo.properties&quot;/&gt;</pre>
+<p>reads a set of properties from the address &quot;http://www.mysite.com/bla/props/foo.properties&quot;.</p>
+
+<pre> &lt;property resource=&quot;foo.properties&quot;/&gt;</pre>
+<p>reads a set of properties from a resource called &quot;foo.properties&quot;.</p>
+<p>Note that you can reference a global properties file for all of your Ant
+builds using the following:</p>
+
+<pre> &lt;property file=&quot;${user.home}/.ant-global.properties&quot;/&gt;</pre>
+<p>since the &quot;user.home&quot; property is defined by the Java virtual machine
+to be your home directory. Where the &quot;user.home&quot; property resolves to in
+the file system depends on the operating system version and the JVM implementation.
+On Unix based systems, this will map to the user's home directory. On modern Windows
+variants, this will most likely resolve to the user's directory in the &quot;Documents
+and Settings&quot; or &quot;Users&quot; folder. Older windows variants such as Windows 98/ME are less
+predictable, as are other operating system/JVM combinations.</p>
+
+<pre>
+ &lt;property environment=&quot;env&quot;/&gt;
+ &lt;echo message=&quot;Number of Processors = ${env.NUMBER_OF_PROCESSORS}&quot;/&gt;
+ &lt;echo message=&quot;ANT_HOME is set to = ${env.ANT_HOME}&quot;/&gt;
+</pre>
+<p>reads the system environment variables and stores them in properties, prefixed with &quot;env&quot;.
+Note that this only works on <em>select</em> operating systems.
+Two of the values are shown being echoed.
+</p>
+
+<pre>
+ &lt;property environment=&quot;env&quot;/&gt;
+ &lt;property file=&quot;${user.name}.properties&quot;/&gt;
+ &lt;property file=&quot;${env.STAGE}.properties&quot;/&gt;
+ &lt;property file=&quot;build.properties&quot;/&gt;
+</pre>
+<p>This buildfile uses the properties defined in <tt>build.properties</tt>. Regarding to the
+environment variable <tt>STAGE</tt> some or all values could be overwritten, e.g. having
+<tt>STAGE=test</tt> and a <tt>test.properties</tt> you have special values for that (like another
+name for the test server). Finally all these values could be overwritten by personal settings with
+a file per user.</p>
+
+<pre>
+ &lt;property name=&quot;foo&quot; location=&quot;my/file.txt&quot; relative=&quot;true&quot; basedir=&quot;..&quot;/&gt;
+</pre>
+<p>Stores the relative path in <tt>foo</tt>: projectbasedir/my/file.txt</p>
+
+<pre>
+ &lt;property name=&quot;foo&quot; location=&quot;my/file.txt&quot; relative=&quot;true&quot; basedir=&quot;cvs&quot;/&gt;
+</pre>
+<p>Stores the relative path in <tt>foo</tt>: ../my/file.txt</p>
+
+
+<h3>Property Files</h3>
+
+As stated, this task will load in a properties file stored in the file
+system, or as a resource on a classpath. Here are some interesting facts
+about this feature
+<ol>
+<li>If the file is not there, nothing is printed except at -verbose log
+level. This lets you have optional configuration files for every
+project, that team members can customize.
+<li>The rules for this format match <a href="http://docs.oracle.com/javase/7/docs/api/java/util/Properties.html#load%28java.io.InputStream%29">java.util.Properties</a>.</li>
+<li>Trailing spaces are not stripped. It may have been what you wanted.</li>
+<li>Want unusual characters? Escape them \u0456 or \&quot; style.</li>
+<li>Ant Properties are expanded in the file</li>
+<li>If you want to expand properties defined inside the same file and
+ you use the prefix attribute of the task, you must use the same
+ prefix when expanding the properties or
+ set <code>prefixValues</code> to true.</li>
+</ol>
+In-file property expansion is very cool. Learn to use it.
+<p>
+Example:
+<pre>
+build.compiler=jikes
+deploy.server=lucky
+deploy.port=8080
+deploy.url=http://${deploy.server}:${deploy.port}/
+</pre>
+
+
+<a name="notes-env"></a>
+<h3>Notes about environment variables</h3>
+<p>
+ Ant runs on Java 1.2 therefore it cannot use Java5 features for accessing environment
+ variables. So it starts a command in a new process which prints the environment variables,
+ analyzes the output and creates the properties. <br>
+ There are commands for the following operating systems implemented in
+ <a href="https://git-wip-us.apache.org/repos/asf?p=ant.git;a=blob;f=src/main/org/apache/tools/ant/taskdefs/Execute.java;hb=24e5a0e881dba01a6f012c4a271b743946412a0d">
+ Execute.java</a> (method <tt>getProcEnvCommand()</tt>):
+ <table>
+ <tr>
+ <th>OS</th>
+ <th>command</th>
+ </tr>
+ <tr>
+ <td> os/2 </td>
+ <td> cmd /c set </td>
+ </tr>
+ <tr>
+ <td colspan="2"> windows </td>
+ </tr>
+ <tr>
+ <td> * win9x </td>
+ <td> command.com /c set </td>
+ </tr>
+ <tr>
+ <td> * other </td>
+ <td> cmd /c set </td>
+ </tr>
+ <tr>
+ <td> z/os </td>
+ <td> /bin/env <b>OR</b> /usr/bin/env <b>OR</b> env <i>(depending on read rights)</i> </td>
+ </tr>
+ <tr>
+ <td> unix </td>
+ <td> /bin/env <b>OR</b> /usr/bin/env <b>OR</b> env <i>(depending on read rights)</i> </td>
+ </tr>
+ <tr>
+ <td> netware </td>
+ <td> env </td>
+ </tr>
+ <tr>
+ <td> os/400 </td>
+ <td> env </td>
+ </tr>
+ <tr>
+ <td> openvms </td>
+ <td> show logical </td>
+ </tr>
+ </table>
+</p>
+
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/propertyfile.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/propertyfile.html
new file mode 100644
index 00000000..e4030f89
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/propertyfile.html
@@ -0,0 +1,249 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>PropertyFile Task</title>
+</head>
+
+<body>
+
+<h1>PropertyFile</h1>
+
+<hr>
+<h2><a name="introduction">Introduction</a></h2>
+<p>Apache Ant provides an optional task for editing property files. This is
+very useful when wanting to make unattended modifications to
+configuration files for application servers and
+applications. Currently, the task maintains a working property file
+with the ability to add properties or make changes to existing
+ones. <em>Since Ant 1.8.0</em> comments and layout of the original properties
+file are preserved.</p>
+
+<p><em>Since Ant 1.8.2</em> the linefeed-style of the original file
+ will be preserved as well, as long as style used to be consistent.
+ In general, linefeeds of the updated file will be the same as the
+ first linefeed found when reading it.</p>
+
+<hr>
+<h2><a name="proptask">PropertyFile Task</a></h2>
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+<tr>
+ <td width="12%" valign="top"><b>Attribute</b></td>
+ <td width="78%" valign="top"><b>Description</b></td>
+ <td width="10%" valign="top"><b>Required</b></td>
+</tr>
+<tr>
+ <td width="12%" valign="top">file</td>
+ <td width="78%" valign="top">Location of the property file to be edited</td>
+ <td width="10%" valign="top">Yes</td>
+</tr>
+<tr>
+ <td width="12%" valign="top">comment</td>
+ <td width="78%" valign="top">Header for the file itself</td>
+ <td width="10%" valign="top">no</td>
+</tr>
+<tr>
+ <td width="12%" valign="top">jdkproperties</td>
+ <td width="78%" valign="top">Use java.lang.Properties, which will
+ loose comments and layout of file (default is 'false'). <em>since
+ Ant 1.8.0</em></td>
+ <td width="10%" valign="top">no</td>
+</tr>
+</table>
+
+<p>The boolean attribute 'jdkproperties' is provided to recover the
+previous behaviour of the task, in which the layout and any comments
+in the properties file were lost by the task.</p>
+
+<h3>Parameters specified as nested elements</h3>
+<h4><a name="entryElement">Entry</a></h4>
+<p>Use nested <code>&lt;entry&gt;</code>
+elements to specify actual modifications to the property file itself.</p>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">key</td>
+ <td valign="top">Name of the property name/value pair</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">value</td>
+ <td valign="top">Value to set (=), to add (+) or subtract (-)</td>
+ <td valign="top" align="center" rowspan="2">At least one must be specified, if <i>operation</i> is not <i>delete</i></td>
+ </tr>
+ <tr>
+ <td valign="top">default</td>
+ <td valign="top">Initial value to set for a property if it is not
+ already defined in the property file.<br>
+ For type date, an additional keyword is allowed: &quot;now&quot;</td>
+ </tr>
+ <tr>
+ <td valign="top">type</td>
+ <td valign="top">Regard the value as : int, date or string (default)</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">operation</td>
+ <td valign="top">One of the following operations:<br><br>
+ <b>for all datatypes:</b><ul>
+ <li>&quot;del&quot; : deletes an entry</li>
+ <li>&quot;+&quot; : adds a value to the existing value</li>
+ <li>&quot;=&quot; : sets a value instead of the existing value (default)</li>
+ </ul><br><b>for date and int only:</b><ul>
+ <li>&quot;-&quot; : subtracts a value from the existing value</li>
+ </ul>
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">pattern</td>
+ <td valign="top">For int and date type only. If present, Values will
+ be parsed and formatted accordingly.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">unit</td>
+ <td valign="top">The unit of the value to be applied to date +/- operations.
+ Valid Values are:
+ <ul>
+ <li>millisecond</li>
+ <li>second</li>
+ <li>minute</li>
+ <li>hour</li>
+ <li>day (default)</li>
+ <li>week</li>
+ <li>month</li>
+ <li>year</li>
+ </ul>
+ This only applies to date types using a +/- operation.
+ </td>
+ <td align="center" valign="top">No</td>
+ </tr>
+</table>
+<p>The rules used when setting a property value are shown below.&nbsp; The
+operation occurs <b>after</b> these rules are considered.</p>
+
+<ul>
+ <li>If only value is specified, the property is set to it regardless of its
+ previous value.</li>
+ <li>If only default is specified and the property previously existed in the
+ property file, it is unchanged.</li>
+ <li>If only default is specified and the property did not exist in the
+ property file, the property is set to default.</li>
+ <li>If value and default are both specified and the property previously
+ existed in the property file, the property is set to value.</li>
+ <li>If value and default are both specified and the property did not exist in
+ the property file, the property is set to default.</li>
+</ul>
+<p>&nbsp;</p>
+
+<h3>Examples</h3>
+
+<p>The following changes the my.properties file. Assume my.properties look like:</p>
+
+<pre># A string value
+akey=original value
+
+# The following is a counter, which will be incremented by 1 for
+# each time the build is run.
+anint=1</pre>
+
+<p>After running, the file would now look like
+</p>
+<pre>#My properties
+#Wed Aug 31 13:47:19 BST 2005
+# A string value
+akey=avalue
+
+# The following is a counter, which will be incremented by 1 for
+# each time the build is run.
+anint=2
+
+adate=2005/08/31 13\:47
+
+formated.int=0014
+
+formated.date=243 13\:47</pre>
+<p>
+The slashes conform to the expectations of the Properties class. The file will be stored in a manner so that each character is examined and escaped if necessary.
+</p>
+
+<p>
+The layout and comment of the original file is preserved. New properties are added at the end of the file. Existing properties are overwritten in place.
+</p>
+
+<blockquote><pre>&lt;propertyfile
+ file=&quot;my.properties&quot;
+ comment=&quot;My properties&quot;&gt;
+ &lt;entry key=&quot;akey&quot; value=&quot;avalue&quot;/&gt;
+ &lt;entry key=&quot;adate&quot; type=&quot;date&quot; value=&quot;now&quot;/&gt;
+ &lt;entry key=&quot;anint&quot; type=&quot;int&quot; default=&quot;0&quot; operation=&quot;+&quot;/&gt;
+ &lt;entry key=&quot;formated.int&quot; type=&quot;int&quot; default=&quot;0013&quot; operation=&quot;+&quot; pattern=&quot;0000&quot;/&gt;
+ &lt;entry key=&quot;formated.date&quot; type=&quot;date&quot; value=&quot;now&quot; pattern=&quot;DDD HH:mm&quot;/&gt;
+&lt;/propertyfile&gt;
+</pre></blockquote>
+<p>
+To produce dates relative from today :</p>
+<blockquote><pre>&lt;propertyfile
+ file=&quot;my.properties&quot;
+ comment=&quot;My properties&quot;&gt;
+ &lt;entry key=&quot;formated.date-1&quot;
+ type=&quot;date&quot; default=&quot;now&quot; pattern=&quot;DDD&quot;
+ operation=&quot;-&quot; value=&quot;1&quot;/&gt;
+ &lt;entry key=&quot;formated.tomorrow&quot;
+ type=&quot;date&quot; default=&quot;now&quot; pattern=&quot;DDD&quot;
+ operation=&quot;+&quot; value=&quot;1&quot;/&gt;
+&lt;/propertyfile&gt;
+</pre></blockquote>
+
+<p>
+Concatenation of strings :</p>
+<blockquote><pre>&lt;propertyfile
+ file=&quot;my.properties&quot;
+ comment=&quot;My properties&quot;&gt;
+ &lt;entry key=&quot;progress&quot; default=&quot;&quot; operation=&quot;+&quot; value=&quot;.&quot;/&gt;
+&lt;/propertyfile&gt;
+</pre></blockquote>
+<p>Each time called, a &quot;.&quot; will be appended to &quot;progress&quot;
+</p>
+
+<p>Pumps the project version to the next minor version (increase minor and set path=0):
+<blockquote><pre>&lt;target name="nextMinorVersion"&gt;
+ &lt;property
+ name="header"
+ value="##Generated file - do not modify!"/&gt;
+ &lt;propertyfile file="version.properties" comment="${header}"&gt;
+ &lt;entry key="product.build.major" type="int" value="3" /&gt;
+ &lt;entry key="product.build.minor" type="int" operation="+" /&gt;
+ &lt;entry key="product.build.patch" type="int" value="0" /&gt;
+ &lt;entry key="product.build.date" type="date" value="now" /&gt;
+ &lt;/propertyfile&gt;
+&lt;/target&gt;
+</pre></blockquote>
+After running this target the version changed e.g. from 3.2.2 to 3.3.0.
+</p>
+
+
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/propertyhelper.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/propertyhelper.html
new file mode 100644
index 00000000..6c73b0be
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/propertyhelper.html
@@ -0,0 +1,108 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>PropertyHelper Task</title>
+</head>
+
+<body>
+
+<h2>PropertyHelper</h2>
+<h3>Description</h3>
+<p>This task is provided for the purpose of allowing the user to
+<b>(a)</b> install a different PropertyHelper at runtime, or
+<b>(b)</b> (hopefully more often) install one or more PropertyHelper Delegates into the
+PropertyHelper active on the current Project. This is somewhat advanced Apache Ant usage and
+assumes a working familiarity with the modern Ant APIs. See the description of Ant's
+<a href="../properties.html#propertyHelper">Property Helper</a> for more information.
+<b>Since Ant 1.8.0</b></p>
+
+<h3>Parameters specified as nested elements</h3>
+
+<h4>PropertyHelper</h4>
+You may specify exactly one configured <code>org.apache.tools.ant.PropertyHelper</code> instance.
+
+<h4>PropertyHelper.Delegate</h4>
+You may specify, either in conjunction with a new <code>PropertyHelper</code> or not, one or
+more configured implementations of the <code>org.apache.tools.ant.PropertyHelper.Delegate</code>
+interface. A deeper understanding of the API is required here, however, as <code>Delegate</code>
+is a marker interface only: the nested arguments must implement a <code>Delegate</code>
+subinterface in order to do anything meaningful.
+
+<h4>delegate</h4>
+<p>A generic &lt;delegate&gt; element which can use project references
+is also provided:</p>
+
+<h5>Parameters</h5>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">refid</td>
+ <td valign="top">The <i>id</i> of a <code>PropertyHelper.Delegate</code> to install.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+</table>
+
+<h3>Examples</h3>
+
+<p>Install a completely different PropertyHelper implementation
+ (assuming <code>MyPropertyHelper extends PropertyHelper</code>):</p>
+
+<pre>
+&lt;componentdef classname="org.example.MyPropertyHelper"
+ name="mypropertyhelper"/>
+&lt;propertyhelper>
+ &lt;mypropertyhelper/>
+&lt;/propertyhelper>
+</pre>
+
+<p>Add a new PropertyEvaluator delegate
+ (assuming <code>MyPropertyEvaluator implements
+ PropertyHelper.PropertyEvaluator</code>). Note that PropertyHelper
+ uses the configured delegates in LIFO order. I.e. the delegate
+ added by this task will be consulted before any previously defined
+ delegate and in particular before the built-in ones.</p>
+
+<pre>
+&lt;componentdef classname="org.example.MyPropertyEvaluator"
+ name="mypropertyevaluator"/>
+&lt;propertyhelper>
+ &lt;mypropertyevaluator/>
+&lt;/propertyhelper>
+</pre>
+
+<p>Add a new PropertyEvaluator delegate using the refid syntax:</p>
+
+<pre>
+&lt;typedef classname="org.example.MyPropertyEvaluator"
+ name="mypropertyevaluator"/>
+&lt;mypropertyevaluator id="evaluator"/>
+&lt;propertyhelper>
+ &lt;delegate refid="evaluator"/>
+&lt;/propertyhelper>
+</pre>
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/pvcstask.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/pvcstask.html
new file mode 100644
index 00000000..a95b32ec
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/pvcstask.html
@@ -0,0 +1,295 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta http-equiv="Content-Language" content="en-us">
+ <link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>PVCS task</title>
+</head>
+<body>
+
+<h1>
+Apache Ant Pvcs Task User Manual</h1>
+
+<p><b>Note:</b>
+Before using this task, the user running Ant must have access to the
+commands of PVCS (get and pcli) and must have access to the
+repository. Note that the way to specify the repository is platform
+dependent so use property to specify location of repository.
+</p>
+
+by
+<br><!-- Names are in alphabetical order, on last name -->
+<ul>
+ <li>Thomas Christensen (<a href="mailto:tchristensen@nordija.com">tchristensen@nordija.com</a>)</li>
+ <li>Don Jeffery (<a href="mailto:donj@apogeenet.com">donj@apogeenet.com</a>)</li>
+ <li>Jon Dickinson (<a href="mailto:dickinson.j@ucles.org.uk">dickinson.j@ucles.org.uk</a>)</li>
+</ul>
+Version 1.1 - 2001/06/27<br>
+<p>Problems with UNC pathnames and the use of () in paths are fixed and an updateonly
+ argument introduced.</p>
+Version 1.0 - 2001/01/31<br>
+<p>Initial release.</p>
+<hr>
+<h2>
+Table of Contents</h2>
+<ul>
+ <li><a href="#introduction">Introduction</a></li>
+ <li><a href="#pvcs">Pvcs Task</a></li>
+</ul>
+<hr>
+
+<h2><a NAME="introduction">Introduction</a></h2>
+The pvcs task allows the user of Ant to extract the latest edition
+of the source code from a PVCS repository. PVCS is a version control system
+developed by <a href="http://www.merant.com/products/pvcs">Merant</a>.
+<br>
+This version has been tested against PVCS version 6.5 and 6.6 under Windows and Solaris.
+
+<hr>
+<h2><a NAME="pvcs">Pvcs Task</a></h2>
+<h3>Description</h3>
+The pvcs task is set to point at a PVCS repository and optionally a project
+within that repository, and can from that specification get the latest
+version of the files contained by the repository.
+<h3>
+Parameters</h3>
+
+<table BORDER CELLSPACING=0 CELLPADDING=2 >
+<tr>
+<td VALIGN=TOP WIDTH="12%"><b>Attribute</b></td>
+
+<td VALIGN=TOP WIDTH="78%"><b>Description</b></td>
+
+<td VALIGN=TOP WIDTH="10%"><b>Required</b></td>
+</tr>
+
+<tr>
+<td VALIGN=TOP WIDTH="12%">repository</td>
+
+<td VALIGN=TOP WIDTH="78%">The location of the repository (see your PVCS
+manuals)</td>
+
+<td VALIGN=TOP WIDTH="10%">Yes</td>
+</tr>
+
+<tr>
+<td VALIGN=TOP WIDTH="12%">pvcsproject</td>
+
+<td VALIGN=TOP WIDTH="78%">The project within the PVCS repository to extract
+files from (&quot;/&quot; is root project and that is default if this attribute isn't
+specified)</td>
+
+<td VALIGN=TOP WIDTH="10%">No</td>
+</tr>
+
+<tr>
+<td VALIGN=TOP WIDTH="12%">label</td>
+
+<td VALIGN=TOP WIDTH="78%">Only files marked with this label are extracted.</td>
+
+<td VALIGN=TOP WIDTH="10%">No</td>
+</tr>
+
+<tr>
+<td VALIGN=TOP WIDTH="12%">promotiongroup</td>
+
+<td VALIGN=TOP WIDTH="78%">Only files within this promotion group are extracted. Using
+both the <i>label</i> and the <i>promotiongroup</i> tag will cause the files in the
+promotion group and with that label to be extracted.
+</td>
+
+<td VALIGN=TOP WIDTH="10%">No</td>
+</tr>
+
+<tr>
+<td VALIGN=TOP WIDTH="12%">config</td>
+
+<td VALIGN=TOP WIDTH="78%">path of a non default .cfg file.
+Can be given absolute or relative to Ant's base directory.
+</td>
+
+<td VALIGN=TOP WIDTH="10%">No</td>
+</tr>
+
+<tr>
+<td VALIGN=TOP WIDTH="12%">force</td>
+
+<td VALIGN=TOP WIDTH="78%">If set to <i>yes</i> all files that exists and are writable are overwritten. Default <i>no</i> causes the files that are writable to be ignored. This stops the PVCS command <i>get</i> to stop asking questions!</td>
+
+<td VALIGN=TOP WIDTH="10%">No</td>
+</tr>
+
+<tr>
+<td VALIGN=TOP WIDTH="12%">workspace</td>
+
+<td VALIGN=TOP WIDTH="78%">By specifying a workspace, the files are extracted to that location. A PVCS workspace is a
+name for a location of the workfiles and isn't as such the location itself. You define the location for a workspace
+using the PVCS GUI clients. If this isn't specified the default workspace for the current user is used.</td>
+
+<td VALIGN=TOP WIDTH="10%">No</td>
+</tr>
+
+<tr>
+<td VALIGN=TOP WIDTH="12%">pvcsbin</td>
+
+<td VALIGN=TOP WIDTH="78%">On some systems the PVCS executables <i>pcli</i>
+and <i>get</i> are not found in the PATH. In such cases this attribute
+should be set to the bin directory of the PVCS installation containing
+the executables mentioned before. If this attribute isn't specified the
+tag expects the executables to be found using the PATH environment variable.</td>
+
+<td VALIGN=TOP WIDTH="10%">No</td>
+</tr>
+ <tr>
+ <td VALIGN=TOP WIDTH="12%">ignorereturncode</td>
+ <td VALIGN=TOP WIDTH="78%">If set to <i>true</i> the return value from executing
+ the pvcs commands are ignored.</td>
+ <td VALIGN=TOP WIDTH="10%">No</td>
+ </tr>
+ <tr>
+ <td VALIGN=TOP WIDTH="12%">updateonly</td>
+ <td VALIGN=TOP WIDTH="78%">If set to <i>true</i> files are gotten only if
+ newer than existing local files.</td>
+ <td VALIGN=TOP WIDTH="10%">No</td>
+ </tr>
+ <tr>
+ <td valign="TOP">filenameformat</td>
+ <td valign="TOP">The format of your folder names in a
+ format suitable for <code>java.text.MessageFormat</code>.
+ Defaults to <code>{0}-arc({1})</code>. Repositories where
+ the archive extension is not <code>-arc</code> should set
+ this.</td>
+ <td valign="TOP">No</td>
+ </tr>
+ <tr>
+ <td valign="TOP">linestart</td>
+ <td valign="TOP">Used to parse the output of the pcli
+ command. It defaults to <code>&quot;P:</code>. The parser already
+ knows about / and \\, this property is useful in cases where the
+ repository is accessed on a Windows platform via a drive letter
+ mapping.</td>
+ <td valign="TOP">No</td>
+ </tr>
+ <tr>
+ <td valign="TOP">revision</td>
+ <td valign="TOP">Retrieve the specified revision.</td>
+ <td valign="TOP">No</td>
+ </tr>
+ <tr>
+ <td valign="TOP">userid</td>
+ <td valign="TOP">Use the specified userid.</td>
+ <td valign="TOP">No</td>
+ </tr>
+</table>
+<h3><a name="nested">Nested Elements</a></h3>
+
+<h3>pvcsproject element</h3>
+<p><code>pvcs</code> supports a nested
+<code>&lt;pvcsproject&gt;</code> element, that represents a project
+within the PVCS repository to extract files from. By nesting multiple
+<code>&lt;pvcsproject&gt;</code> elements under the
+<code>&lt;pvcs&gt;</code> task, multiple projects can be
+specified.</p>
+
+<h3>Parameters</h3>
+
+<table BORDER CELLSPACING=0 CELLPADDING=2 >
+<tr>
+<td VALIGN=TOP WIDTH="12%"><b>Attribute</b></td>
+
+<td VALIGN=TOP WIDTH="78%"><b>Description</b></td>
+
+<td VALIGN=TOP WIDTH="10%"><b>Required</b></td>
+</tr>
+
+<tr>
+<td VALIGN=TOP WIDTH="12%">name</td>
+
+<td VALIGN=TOP WIDTH="78%">The name of the pvcs project</td>
+
+<td VALIGN=TOP WIDTH="10%">Yes</td>
+</tr>
+</table>
+
+<h3>Examples</h3>
+The following set-up extracts the latest version of the files in the pvcs repository.
+<pre>
+ &lt;!-- =================================================================== --&gt;
+ &lt;!-- Get the latest version --&gt;
+ &lt;!-- =================================================================== --&gt;
+ &lt;target name=&quot;getlatest&quot;&gt;
+ &lt;pvcs repository=&quot;/mnt/pvcs&quot; pvcsproject=&quot;/myprj&quot;/&gt;
+ &lt;/target&gt;</ul>
+</pre>
+<p>Now run:</p>
+<code>ant getlatest</code>
+<p>This will cause the following output to appear:</p>
+<pre>
+ getlatest:
+ [pvcs] PVCS Version Manager (VMGUI) v6.6.10 (Build 870) for Windows NT/80x86
+ [pvcs] Copyright 1985-2000 MERANT. All rights reserved.
+ [pvcs] PVCS Version Manager (get) v6.6.10 (Build 870) for Windows NT/80x86
+ [pvcs] Copyright 1985-2000 MERANT. All rights reserved.
+ [pvcs] c:\myws\myprj\main.java &lt;- C:\mypvcs\archives\myprj\main.java-arc
+ [pvcs] rev 1.1
+ [pvcs] c:\myws\myprj\apache\tool.java &lt;- C:\mypvcs\archives\myprj\apache\tools.java-arc
+ [pvcs] rev 1.5
+
+ BUILD SUCCESSFUL
+
+ Total time: 19 seconds</pre>
+
+This next example extracts the latest version of the files in the pvcs
+repository from two projects using nested <code>&lt;pvcsproject&gt;</code> elements.
+<pre>
+ &lt;!-- ===================================================================--&gt;
+ &lt;!-- Get latest from myprj and myprj2 --&gt;
+ &lt;!-- ===================================================================--&gt;
+ &lt;target name=&quot;getlatest2&quot;&gt;
+ &lt;pvcs repository=&quot;/mnt/pvcs&quot;&gt;
+ &lt;pvcsproject name=&quot;/myprj&quot;/&gt;
+ &lt;pvcsproject name=&quot;/myprj2&quot;/&gt;
+ &lt;/pvcs&gt;
+ &lt;/target&gt;</ul>
+</pre>
+<p>Now run:</p>
+<code>ant getlatest2</code>
+<p>This will cause the following output to appear:</p>
+<pre>
+ getlatest2:
+ [pvcs] PVCS Version Manager (VMGUI) v6.6.10 (Build 870) for Windows NT/80x86
+ [pvcs] Copyright 1985-2000 MERANT. All rights reserved.
+ [pvcs] PVCS Version Manager (get) v6.6.10 (Build 870) for Windows NT/80x86
+ [pvcs] Copyright 1985-2000 MERANT. All rights reserved.
+ [pvcs] c:\myws\myprj\main.java &lt;- C:\mypvcs\archives\myprj\main.java-arc
+ [pvcs] rev 1.1
+ [pvcs] c:\myws\myprj\apache\tool.java &lt;- C:\mypvcs\archives\myprj\apache\tool.java-arc
+ [pvcs] rev 1.5
+ [pvcs] c:\myws\myprj2\apache\tool2.java &lt;- C:\mypvcs\archives\myprj2\apache\tool2.java-arc
+ [pvcs] rev 1.2
+
+ BUILD SUCCESSFUL
+
+ Total time: 22 seconds</pre>
+
+<hr WIDTH="100%">
+<p>PVCS is a registered trademark of MERANT.</p>
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/recorder.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/recorder.html
new file mode 100644
index 00000000..dfbfc0d5
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/recorder.html
@@ -0,0 +1,172 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Recorder Task</title>
+</head>
+
+<body>
+
+<h2><a name="log">Record</a></h2>
+<h3>Description</h3>
+<p>A recorder is a listener to the current build process that records the
+output to a file.</p>
+
+<p>Several recorders can exist at the same time. Each recorder is
+associated with a file. The filename is used as a unique identifier for
+the recorders. The first call to the recorder task with an unused filename
+will create a recorder (using the parameters provided) and add it to the
+listeners of the build. All subsequent calls to the recorder task using
+this filename will modify that recorders state (recording or not) or other
+properties (like logging level).</p>
+
+<p>Some technical issues: the file's print stream is flushed for &quot;finished&quot;
+events (buildFinished, targetFinished and taskFinished), and is closed on
+a buildFinished event.</p>
+
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">name</td>
+ <td valign="top">The name of the file this logger is associated with.</td>
+ <td align="center" valign="middle">yes</td>
+ </tr>
+ <tr>
+ <td valign="top">action</td>
+ <td valign="top">This tells the logger what to do: should it start
+ recording or stop? The first time that the recorder task is called for
+ this logfile, and if this attribute is not provided, then the default
+ for this attribute is &quot;start&quot;. If this attribute is not provided on
+ subsequent calls, then the state remains as previous.
+ [Values = {start|stop}, Default = no state change]</td>
+ <td align="center" valign="middle">no</td>
+ </tr>
+ <tr>
+ <td valign="top">append</td>
+ <td valign="top">Should the recorder append to a file, or create a new
+ one? This is only applicable the first time this task is called for
+ this file. [Values = {yes|no}, Default=no]</td>
+ <td align="center" valign="middle">no</td>
+ </tr>
+ <tr>
+ <td valign="top">emacsmode</td>
+ <td valign="top">Removes <code>[task]</code> banners like Apache Ant's
+ <code>-emacs</code> command line switch if set to
+ <em>true</em>.</td>
+ <td align="center" valign="middle">no, default is <em>false</em></td>
+ </tr>
+ <tr>
+ <td valign="top">loglevel</td>
+ <td valign="top">At what logging level should this recorder instance
+ record to? This is not a once only parameter (like <code>append</code>
+ is) -- you can increase or decrease the logging level as the build process
+ continues. [Values= {error|warn|info|verbose|debug}, Default = no change]
+ </td>
+ <td align="center" valign="middle">no</td>
+ </tr>
+</table>
+
+<h3>Examples</h3>
+<p>The following build.xml snippet is an example of how to use the recorder
+to record just the <code>&lt;javac&gt;</code> task:</p>
+<pre>
+ ...
+ &lt;compile &gt;
+ &lt;record name=&quot;log.txt&quot; action=&quot;start&quot;/&gt;
+ &lt;javac ...
+ &lt;record name=&quot;log.txt&quot; action=&quot;stop&quot;/&gt;
+ &lt;compile/&gt;
+ ...
+</pre>
+
+<p>The following two calls to <code>&lt;record&gt;</code> set up two
+recorders: one to file &quot;records-simple.log&quot; at logging level <code>info</code>
+(the default) and one to file &quot;ISO.log&quot; using logging level of
+<code>verbose</code>.</p>
+<pre>
+ ...
+ &lt;record name=&quot;records-simple.log&quot;/&gt;
+ &lt;record name=&quot;ISO.log&quot; loglevel=&quot;verbose&quot;/&gt;
+ ...
+</pre>
+
+<h3>Notes</h3>
+<p>There is some functionality that I would like to be able to add in the
+future. They include things like the following:</p>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">listener</td>
+ <td valign="top">A classname of a build listener to use from this point
+ on instead of the default listener.</td>
+ <td align="center" valign="middle">no</td>
+ </tr>
+ <tr>
+ <td valign="top">includetarget</td>
+ <td valign="top" rowspan=2>A comma-separated list of targets to automatically
+ record. If this value is &quot;all&quot;, then all targets are recorded.
+ [Default = all]</td>
+ <td align="center" valign="middle">no</td>
+ </tr>
+ <tr>
+ <td valign="top">excludetarget</td>
+ <td align="center" valign="middle">no</td>
+ </tr>
+ <tr>
+ <td valign="top">includetask</td>
+ <td valign="top" rowspan=2>A comma-separated list of task to automatically
+ record or not. This could be difficult as it could conflict with the
+ <code>includetarget/excludetarget</code>. (e.g.:
+ <code>includetarget=&quot;compile&quot; excludetask=&quot;javac&quot;</code>, what should
+ happen?)</td>
+ <td align="center" valign="middle">no</td>
+ </tr>
+ <tr>
+ <td valign="top">excludetask</td>
+ <td align="center" valign="middle">no</td>
+ </tr>
+ <tr>
+ <td valign="top">action</td>
+ <td valign="top">add greater flexibility to the action attribute. Things
+ like <code>close</code> to close the print stream.</td>
+ <td align="center" valign="top">no</td>
+ </tr>
+ <tr>
+ <td valign="top"></td>
+ <td valign="top"></td>
+ <td align="center" valign="top"></td>
+ </tr>
+</table>
+
+
+
+
+
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/rename.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/rename.html
new file mode 100644
index 00000000..330fbe3a
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/rename.html
@@ -0,0 +1,64 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Rename Task</title>
+</head>
+
+<body>
+
+<h2><a name="rename">Rename</a></h2>
+<h3><i>Deprecated</i></h3>
+<p><i>This task has been deprecated. Use the Move task instead.</i></p>
+<h3>Description</h3>
+<p>Renames a given file.</p>
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">src</td>
+ <td valign="top">file to rename.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">dest</td>
+ <td valign="top">new name of the file.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">replace</td>
+ <td valign="top">Enable replacing of existing file (default: on).</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+</table>
+<h3>Examples</h3>
+<pre> &lt;rename src=&quot;foo.jar&quot; dest=&quot;${name}-${version}.jar&quot;/&gt;</pre>
+<p>Renames the file <code>foo.jar</code> to <code>${name}-${version}.jar</code> (assuming <code>name</code>
+ and <code>version</code> being predefined properties). If a file named <code>${name}-${version}.jar</code>
+ already exists, it will be removed prior to renaming <code>foo.jar</code>.</p>
+
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/renameextensions.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/renameextensions.html
new file mode 100644
index 00000000..ed3bfbba
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/renameextensions.html
@@ -0,0 +1,123 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>RenameExtensions Task</title>
+</head>
+
+<body>
+
+<h2><a name="renameexts">RenameExtensions</a></h2>
+<h3><i>Deprecated</i></h3>
+<p><i>This task has been deprecated. Use the <a href="../Tasks/move.html">move</a>
+task with a <a href="../Types/mapper.html#glob-mapper">glob mapper</a> instead.</i></p>
+<h3>Description</h3>
+<p>Renames files in the <code>srcDir</code> directory ending with the
+<code>fromExtension</code> string so that they end with the
+<code>toExtension</code> string. Files are only replaced if
+<code>replace</code> is true
+</p>
+<p>See the section on
+<a href="../dirtasks.html#directorybasedtasks">directory based tasks</a>, on how the
+inclusion/exclusion of files works, and how to write patterns.
+This task forms an implicit <a href="../Types/fileset.html">FileSet</a> and
+supports most attributes of <code>&lt;fileset&gt;</code>
+(<code>dir</code> becomes <code>srcDir</code>) as well as the nested
+<code>&lt;include&gt;</code>, <code>&lt;exclude&gt;</code> and
+<code>&lt;patternset&gt;</code> elements.</p>
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">defaultexcludes</td>
+ <td valign="top">indicates whether default excludes should be used or not
+ (&quot;yes&quot;/&quot;no&quot;). Default excludes are used when
+ omitted.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">excludes</td>
+ <td valign="top">comma- or space-separated list of patterns of files that must be
+ excluded. No files (except default excludes) are excluded when
+ omitted.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">excludesfile</td>
+ <td valign="top">the name of a file. Each line of this file is
+ taken to be an exclude pattern</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">fromExtension</td>
+ <td valign="top">The string that files must end in to be renamed</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">includes</td>
+ <td valign="top">comma- or space-separated list of patterns of files that must be
+ included. All files are included when omitted.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">includesfile</td>
+ <td valign="top">the name of a file. Each line of this file is
+ taken to be an include pattern</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">replace</td>
+ <td valign="top">Whether the file being renamed to should be
+ replaced if it already exists</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">srcDir</td>
+ <td valign="top">The starting directory for files to search in</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">toExtension</td>
+ <td valign="top">The string that renamed files will end with on
+ completion</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+</table>
+<h3>Examples</h3>
+<blockquote>
+ <p><code>&lt;renameext srcDir=&quot;/source/project1&quot;
+ includes=&quot;**&quot;
+ excludes=&quot;**/samples/*&quot;
+ fromExtension=&quot;.java.keep&quot;
+ toExtension=&quot;.java&quot;
+ replace=&quot;true&quot;/&gt;
+</code>
+ </p>
+</blockquote>
+
+
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/replace.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/replace.html
new file mode 100644
index 00000000..36204d0c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/replace.html
@@ -0,0 +1,242 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Replace Task</title>
+</head>
+
+<body>
+
+<h2><a name="replace">Replace</a></h2>
+<h3>Description</h3>
+<p>Replace is a directory based task for replacing the occurrence of a given string with another string
+in selected file.</p>
+<p>If you want to replace a text that crosses line boundaries, you
+must use a nested <code>&lt;replacetoken&gt;</code> element.</p>
+
+<p>The output file is only written if it differs from the existing
+file. This prevents spurious rebuilds based on unchanged files which
+have been regenerated by this task.</p>
+
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">file</td>
+ <td valign="top">file for which the token should be replaced.</td>
+ <td align="center" rowspan="2">Exactly one of the two.</td>
+ </tr>
+ <tr>
+ <td valign="top">dir</td>
+ <td valign="top">The base directory to use when replacing a token in
+ multiple files.</td>
+ </tr>
+ <tr>
+ <td valign="top">encoding</td>
+ <td valign="top">The encoding of the files upon which replace operates.</td>
+ <td align="center">No - defaults to default JVM encoding</td>
+ </tr>
+ <tr>
+ <td valign="top">token</td>
+ <td valign="top">the token which must be replaced.</td>
+ <td valign="top" align="center">Yes, unless a nested
+ <code>replacetoken</code> element or the replacefilterfile
+ attribute is used.</td>
+ </tr>
+ <tr>
+ <td valign="top">value</td>
+ <td valign="top">the new value for the token. When omitted, an empty string
+ (&quot;&quot;) is used.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">summary</td>
+ <td valign="top">Indicates whether a summary of the replace operation
+ should be produced, detailing how many token occurrences
+ and files were processed
+ </td>
+ <td valign="top" align="center">No, by default no summary is produced</td>
+ </tr>
+ <tr>
+ <td valign="top">propertyFile</td>
+ <td valign="top">valid property file from which properties specified using nested <code>&lt;replacefilter&gt;</code> elements are drawn.</td>
+ <td valign="top" align="center">Yes only if <i>property</i> attribute of <code>&lt;replacefilter&gt;</code> is used.</td>
+ </tr>
+ <tr>
+ <td valign="top">replacefilterfile</td>
+ <td valign="top">valid property file. Each property will be
+ treated as a replacefilter where <code>token</code> is the name of
+ the property and <code>value</code> is the properties value.
+ <td valign="top" align="center">No.</td>
+ </tr>
+ <tr>
+ <td valign="top">includes</td>
+ <td valign="top">comma- or space-separated list of patterns of files that must be
+ included. All files are included when omitted.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">includesfile</td>
+ <td valign="top">the name of a file. Each line of this file is
+ taken to be an include pattern</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">excludes</td>
+ <td valign="top">comma- or space-separated list of patterns of files that must be
+ excluded. No files (except default excludes) are excluded when omitted.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">excludesfile</td>
+ <td valign="top">the name of a file. Each line of this file is
+ taken to be an exclude pattern</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">defaultexcludes</td>
+ <td valign="top">indicates whether default excludes should be used or not
+ (&quot;yes&quot;/&quot;no&quot;). Default excludes are used when omitted.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">preserveLastModified</td>
+ <td valign="top">Keep the file timestamp(s) even if the file(s)
+ is(are) modified. <em>since Apache Ant 1.8.0.</em></td>
+ <td valign="top" align="center">No, defaults to false</td>
+ </tr>
+ <tr>
+ <td valign="top">failOnNoReplacements</td>
+ <td valign="top">Whether to fail the build if the task didn't do
+ anything. <em>since Ant 1.8.0.</em></td>
+ <td valign="top" align="center">No, defaults to false</td>
+ </tr>
+</table>
+<h3>Examples</h3>
+<pre> &lt;replace file=&quot;${src}/index.html&quot; token=&quot;@@@&quot; value=&quot;wombat&quot;/&gt;</pre>
+<p>replaces occurrences of the string &quot;@@@&quot; with the string
+&quot;wombat&quot;, in the file <code>${src}/index.html</code>.</p>
+<h3>Parameters specified as nested elements</h3>
+<p>This task forms an implicit <a href="../Types/fileset.html">FileSet</a> and
+supports most attributes of <code>&lt;fileset&gt;</code> as well as the
+nested <code>&lt;include&gt;</code>, <code>&lt;exclude&gt;</code> and
+<code>&lt;patternset&gt;</code> elements.</p>
+<p>Since Ant 1.8.0 this task supports any filesystem
+ based <a href="../Types/resources.html#collection">resource
+ collections</a> as nested elements.</p>
+<h4>replacetoken and replacevalue</h4>
+<p>If either the text you want to replace or the replacement text
+cross line boundaries, you can use nested elements to specify
+them.</p>
+<p>The elements support attributes:</p>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">expandProperties</td>
+ <td valign="top">Whether to expand properties in the nested text.
+ <em>since Ant 1.8.0.</em></td>
+ <td align="center">No, defaults to true.</td>
+ </tr>
+</table>
+<h3>Examples</h3>
+<blockquote><pre>
+&lt;replace dir=&quot;${src}&quot; value=&quot;wombat&quot;&gt;
+ &lt;include name=&quot;**/*.html&quot;/&gt;
+ &lt;replacetoken&gt;&lt;![CDATA[multi line
+token]]&gt;&lt;/replacetoken&gt;
+&lt;/replace&gt;
+</pre></blockquote>
+<p>replaces occurrences of the string &quot;multi
+line<i>\n</i>token&quot; with the string &quot;wombat&quot;, in all
+HTML files in the directory <code>${src}</code>.Where <i>\n</i> is
+the platform specific line separator.</p>
+<blockquote><pre>
+&lt;replace file=&quot;${src}/index.html&quot;&gt;
+ &lt;replacetoken&gt;&lt;![CDATA[two line
+token]]&gt;&lt;/replacetoken&gt;
+ &lt;replacevalue&gt;&lt;![CDATA[two line
+token]]&gt;&lt;/replacevalue&gt;
+&lt;/replace&gt;
+</pre></blockquote>
+<h4>replacefilter</h4>
+<p>In addition to allowing for multiple replacements, optional nested <code>&lt;replacefilter&gt;</code> elements allow replacement values to be extracted from a property file. The name of this file is specified using the <code>&lt;replace&gt;</code> attribute <i>propertyFile</i>.
+</p>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">token</td>
+ <td valign="top">The string to search for.</td>
+ <td align="center" valign="top">Yes unless a nested replacetoken
+ is specified</td>
+ </tr>
+ <tr>
+ <td valign="top">value</td>
+ <td valign="top">The replacement string.</td>
+ <td align="center" rowspan="2">Either may be specified, but not both. Both can be omitted, if desired.</td>
+ </tr>
+ <tr>
+ <td valign="top">property</td>
+ <td valign="top">Name of the property whose value is to serve as the replacement value.</td>
+ </tr>
+</table>
+<p>Since Ant 1.8.0 token and value can be specified as nested elements
+ just like in the task itself.</p>
+<p>If neither <i>value</i> nor <i>property</i> is used, the value provided using the <code>&lt;replace&gt;</code> attribute <i>value</i> and/or the <code>&lt;replacevalue&gt;</code> element is used. If no value was specified using either of these options, the token is replaced with an empty string.
+</p>
+<h3>Examples</h3>
+<blockquote><pre>
+&lt;replace
+ file=&quot;configure.sh&quot;
+ value=&quot;defaultvalue&quot;
+ propertyFile=&quot;src/name.properties&quot;&gt;
+ &lt;replacefilter
+ token=&quot;@token1@&quot;/&gt;
+ &lt;replacefilter
+ token=&quot;@token2@&quot;
+ value=&quot;value2&quot;/&gt;
+ &lt;replacefilter
+ token=&quot;@token3@&quot;
+ property=&quot;property.key&quot;/&gt;
+ &lt;replacefilter&gt;
+ &lt;replacetoken&gt;@token4@&lt;/replacetoken&gt;
+ &lt;replacevalue&gt;value4&lt;/replacevalue&gt;
+ &lt;/replacefilter&gt;
+&lt;/replace&gt;
+</pre></blockquote>
+<p>In file <code>configure.sh</code>, replace all instances of &quot;@token1@&quot; with &quot;defaultvalue&quot;, all instances of &quot;@token2@&quot; with &quot;value2&quot;, and all instances of &quot;@token3@&quot; with the value of the property &quot;property.key&quot;, as it appears in property file <code>src/name.properties</code>.</p>
+<p><b>Note:</b> It is possible to use either the <i>token</i>/<code>&lt;replacetoken&gt;</code> and <i>value</i>/<code>&lt;replacevalue&gt;</code> attributes/elements, the nested replacefilter elements, or both in the same operation.
+</p>
+
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/replaceregexp.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/replaceregexp.html
new file mode 100644
index 00000000..eed4c84c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/replaceregexp.html
@@ -0,0 +1,205 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>ReplaceRegExp Task</title>
+</head>
+<body>
+
+<h2><a name="replaceregexp">ReplaceRegExp</a></h2>
+<h3>Description</h3>
+<p>ReplaceRegExp is a directory based task for replacing the
+occurrence of a given regular expression with a substitution pattern
+in a selected file or set of files.</p>
+
+<p>The output file is only written if it differs from the existing
+file. This prevents spurious rebuilds based on unchanged files which
+have been regenerated by this task.</p>
+
+<p>Similar to <a href="../Types/mapper.html#regexp-mapper">regexp
+type mappers</a> this task needs a supporting regular expression
+library and an implementation of
+<code>org.apache.tools.ant.util.regexp.Regexp</code>.
+See details in the documentation of the <a href="../Types/regexp.html#implementation">Regexp Type</a>. </p>
+
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">file</td>
+ <td valign="top">file for which the regular expression should be replaced.</td>
+ <td align="center">Yes if no nested <code>&lt;fileset&gt;</code> is used</td>
+ </tr>
+ <tr>
+ <td valign="top">match</td>
+ <td valign="top">The regular expression pattern to match in the file(s)</td>
+ <td align="center">Yes, if no nested <code>&lt;regexp&gt;</code> is used</td>
+ </tr>
+ <tr>
+ <td valign="top">replace</td>
+ <td valign="top">The substitution pattern to place in the file(s) in place
+ of the regular expression.</td>
+ <td align="center">Yes, if no nested <code>&lt;substitution&gt;</code> is used</td>
+ </tr>
+ <tr>
+ <td valign="top">flags</td>
+ <td valign="top">The flags to use when matching the regular expression. For more
+ information, consult the Perl5 syntax<br>
+ g : Global replacement. Replace all occurrences found<br>
+ i : Case Insensitive. Do not consider case in the match<br>
+ m : Multiline. Treat the string as multiple lines of input, using "^" and "$" as the start or end of any line, respectively, rather than start or end of string.<br>
+ s : Singleline. Treat the string as a single line of input, using "." to match any character, including a newline, which normally, it would not match.<br>
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">byline</td>
+ <td valign="top">Process the file(s) one line at a time, executing the replacement
+ on one line at a time (<i>true/false</i>). This is useful if you
+ want to only replace the first occurrence of a regular expression on
+ each line, which is not easy to do when processing the file as a whole.
+ Defaults to <i>false</i>.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">encoding</td>
+ <td valign="top">The encoding of the file. <em>since Apache Ant 1.6</em></td>
+ <td align="center">No - defaults to default JVM encoding</td>
+ </tr>
+ <tr>
+ <td valign="top">preserveLastModified</td>
+ <td valign="top">Keep the file timestamp(s) even if the file(s)
+ is(are) modified. <em>since Ant 1.8.0.</em></td>
+ <td valign="top" align="center">No, defaults to false</td>
+ </tr>
+</table>
+<h3>Examples</h3>
+<pre>
+&lt;replaceregexp file=&quot;${src}/build.properties&quot;
+ match=&quot;OldProperty=(.*)&quot;
+ replace=&quot;NewProperty=\1&quot;
+ byline=&quot;true&quot;
+/&gt;
+</pre>
+<p>replaces occurrences of the property name &quot;OldProperty&quot;
+ with &quot;NewProperty&quot; in a properties file, preserving the existing
+value, in the file <code>${src}/build.properties</code></p>
+
+<h3>Parameters specified as nested elements</h3>
+<p>This task supports a nested <a href="../Types/fileset.html">FileSet</a>
+ element.</p>
+<p>Since Ant 1.8.0 this task supports any filesystem
+ based <a href="../Types/resources.html#collection">resource
+ collections</a> as nested elements.</p>
+<p>This task supports a nested <i><a href="../Types/regexp.html">Regexp</a></i> element to specify
+ the regular expression. You can use this element to refer to a previously
+ defined regular expression datatype instance.</p>
+<blockquote>
+ &lt;regexp id="id" pattern="alpha(.+)beta"/&gt;<br>
+ &lt;regexp refid="id"/&gt;
+</blockquote>
+<p>This task supports a nested <i>Substitution</i> element to specify
+ the substitution pattern. You can use this element to refer to a previously
+ defined substitution pattern datatype instance.</p>
+<blockquote>
+ &lt;substitution id="id" expression="beta\1alpha"/&gt;<br>
+ &lt;substitution refid="id"/&gt;
+</blockquote>
+
+
+<h3>Examples</h3>
+
+<blockquote>
+ <pre>
+&lt;replaceregexp byline=&quot;true&quot;&gt;
+ &lt;regexp pattern=&quot;OldProperty=(.*)&quot;/&gt;
+ &lt;substitution expression=&quot;NewProperty=\1&quot;/&gt;
+ &lt;fileset dir=&quot;.&quot;&gt;
+ &lt;include name=&quot;*.properties&quot;/&gt;
+ &lt;/fileset&gt;
+&lt;/replaceregexp&gt;
+</pre></blockquote>
+<p>replaces occurrences of the property name &quot;OldProperty&quot;
+ with &quot;NewProperty&quot; in a properties file, preserving the existing
+value, in all files ending in <code>.properties</code> in the current directory</p>
+
+<br>
+<blockquote>
+<pre>&lt;replaceregexp match="\s+" replace=" " flags="g" byline="true"&gt;
+ &lt;fileset dir="${html.dir}" includes="**/*.html"/&gt;
+&lt;/replaceregexp&gt;
+</pre></blockquote>
+<p>replaces all whitespaces (blanks, tabs, etc) by one blank remaining the
+line separator. So with input
+<blockquote>
+<pre>
+&lt;html&gt; &lt;body&gt;
+&lt;&lt;TAB&gt;&gt;&lt;h1&gt; T E S T &lt;/h1&gt; &lt;&lt;TAB&gt;&gt;
+&lt;&lt;TAB&gt;&gt; &lt;/body&gt;&lt;/html&gt;
+</pre></blockquote>
+would converted to
+<blockquote>
+<pre>
+&lt;html&gt; &lt;body&gt;
+ &lt;h1&gt; T E S T &lt;/h1&gt; &lt;/body&gt;&lt;/html&gt;
+</pre>
+</blockquote>
+</p>
+
+<br><!-- small distance from code of the previous example -->
+<blockquote>
+<pre>&lt;replaceregexp match="\\n" replace="${line.separator}" flags="g" byline="true"&gt;
+ &lt;fileset dir="${dir}"/&gt;
+&lt;/replaceregexp&gt;
+</pre></blockquote>
+<p>replaces all <tt>\n</tt> markers (beware the quoting of the backslash) by a line break.
+So with input
+<blockquote>
+<pre>
+one\ntwo\nthree
+</pre></blockquote>
+would converted to
+<blockquote>
+<pre>
+one
+two
+three
+</pre>
+</blockquote>
+Beware that inserting line breaks could break file syntax. For example in xml:
+<blockquote>
+<pre>
+&lt;root&gt;
+ &lt;text&gt;line breaks \n should work in text&lt;/text&gt;
+ &lt;attribute value=&quot;but breaks \n attributes&quot; /&gt;
+&lt;/root&gt;
+</pre>
+</blockquote>
+</p>
+
+
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/resourcecount.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/resourcecount.html
new file mode 100644
index 00000000..a34506b1
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/resourcecount.html
@@ -0,0 +1,107 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>ResourceCount Task</title>
+</head>
+
+<body>
+
+<h2>ResourceCount</h2>
+
+<h3>Description</h3>
+<p>Display or set a property containing the size of a nested
+ <a href="../Types/resources.html#collection">Resource Collection</a>.
+ Can also be used as a condition. <b>Since Apache Ant 1.7</b></p>
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">property</td>
+ <td valign="top">The property to set. If omitted the results are written
+ to the log. Ignored when processing as a condition.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">refid</td>
+ <td valign="top">A <a href="../using.html#references">reference</a>
+ to a Resource Collection.</td>
+ <td valign="top" align="center">
+ Yes, unless a nested Resource Collection is supplied
+ </td>
+ </tr>
+ <tr>
+ <td valign="top">count</td>
+ <td valign="top">Comparison count for processing as a condition.</td>
+ <td valign="top" align="center">Yes, in condition mode</td>
+ </tr>
+ <tr>
+ <td valign="top">when</td>
+ <td valign="top">Comparison type: "equal", "eq", "greater", "gt", "less",
+ "lt", "ge" (greater or equal), "ne" (not equal), "le" (less or equal)
+ for use when operating as a condition.</td>
+ <td valign="top" align="center">No; default is "equal"</td>
+ </tr>
+</table>
+
+<h3>Parameters specified as nested elements</h3>
+<h4>Resource Collection</h4>
+<p>A single
+ <a href="../Types/resources.html#collection">Resource Collection</a>
+should be specified via a nested element or the <code>refid</code> attribute.
+</p>
+
+<h3>Examples</h3>
+<pre>&lt;resourcecount property=&quot;count.foo&quot;&gt;
+ &lt;filelist dir=&quot;.&quot; files=&quot;foo,bar&quot; /&gt;
+&lt;/resourcecount&gt;
+</pre>
+<p>Stores the number of resources in the specified filelist (two)
+in the property named <i>count.foo</i>.</p>
+
+<pre>
+&lt;project&gt;
+ &lt;property name=&quot;file&quot; value=&quot;${ant.file}&quot;/&gt;
+ &lt;resourcecount property=&quot;file.lines&quot;&gt;
+ &lt;tokens&gt;
+ &lt;concat&gt;
+ &lt;filterchain&gt;
+ &lt;tokenfilter&gt;
+ &lt;linetokenizer/&gt;
+ &lt;/tokenfilter&gt;
+ &lt;/filterchain&gt;
+ &lt;fileset file=&quot;${file}&quot;/&gt;
+ &lt;/concat&gt;
+ &lt;/tokens&gt;
+ &lt;/resourcecount&gt;
+ &lt;echo&gt;The file '${file}' has ${file.lines} lines.&lt;/echo&gt;
+&lt;/project&gt;
+</pre>
+<p>Stores the number of lines of the current buildfile in the property <tt>file.lines</tt>.
+Requires Ant 1.7.1+ as &lt;concat&gt; has to be resource.</p>
+
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/retry.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/retry.html
new file mode 100644
index 00000000..af68d40a
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/retry.html
@@ -0,0 +1,61 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Retry Task</title>
+</head>
+<body>
+<h2>Retry</h2>
+<h3>Description</h3>
+<p>Retry is a container which executes a single nested task until either: there is no failure; or:
+its <em>retrycount</em> has been exceeded. If this happens a BuildException is thrown.
+<em>Since Apache Ant 1.7.1</em></p>
+
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">retrycount</td>
+ <td valign="top">number of times to attempt to execute the nested task</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">retrydelay</td>
+ <td valign="top">number of milliseconds to wait between retry attempts
+ task. <em>Since Apache Ant 1.8.3</em></td>
+ <td valign="top" align="center">No, defaults to no delay</td>
+ </tr>
+</table>
+<p>Any valid Ant task may be embedded within the retry task.</p>
+
+<h3>Example</h3>
+<pre>
+&lt;retry retrycount="3"&gt;
+ &lt;get src="http://www.unreliable-server.com/unreliable.tar.gz"
+ dest="/home/retry/unreliable.tar.gz" /&gt;
+&lt;/retry&gt;
+</pre>
+<p>This example shows how to use <code>&lt;retry&gt;</code> to wrap a task which must interact with an unreliable network resource.</p>
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/rexec.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/rexec.html
new file mode 100644
index 00000000..02f6fe23
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/rexec.html
@@ -0,0 +1,116 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>RExec Task</title>
+</head>
+
+<body>
+
+<h2><a name="rexec">RExec</a></h2>
+<h3>Description</h3>
+Task to automate a remote rexec session. Just like the Telnet task,
+it uses nested <tt>&lt;read&gt;</tt> to indicate strings to wait for, and
+<tt>&lt;write&gt;</tt> tags to specify text to send to the remote process.
+
+<p><b>Note:</b> This task depends on external libraries not included in the Apache Ant distribution.
+See <a href="../install.html#librarydependencies">Library Dependencies</a> for more information.</p>
+
+<p>You can specify the commands you want to execute as nested elements
+or via the command attribute, we recommend you use the command
+attribute. If you use the command attribute, you must use the
+username and password attributes as well.</p>
+
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <th>Attribute</th>
+ <th>Values</th>
+ <th>Required</th>
+ </tr>
+ <tr>
+ <td>userid</td>
+ <td>the login id to use on the remote server.</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>password</td>
+ <td>the login password to use on the remote server.</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>server</td>
+ <td>the address of the remote rexec server.</td>
+ <td>Yes</td>
+ </tr>
+ <tr>
+ <td>command</td>
+ <td>the command to execute on the remote server.</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>port</td>
+ <td>the port number of the remote rexec server. Defaults to port 512 in BSD Unix systems.</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>timeout</td>
+ <td>set a default timeout to wait for a response. Specified in seconds. Default is no timeout.</td>
+ <td>No</td>
+ </tr>
+</table>
+<h3><a name="nested">Nested Elements</a></h3>
+The input to send to the server, and responses to wait for, are
+described as nested elements.
+
+<h4>read</h4>
+
+<p>declare (as a text child of this element) a string to wait for.
+The element supports the timeout attribute, which overrides any
+timeout specified for the task as a whole. It also has a <tt>string</tt>
+attribute, which is an alternative to specifying the string as
+a text element.
+</p>
+<i>It is not necessary to declare a closing <code>&lt;read&gt;</code> element like for the Telnet task. The connection is not broken until the command has completed and
+the input stream (output of the command) is terminated.
+</i>
+<h4>write</h4>
+
+<p>describes the text to send to the server. The <tt>echo</tt> boolean
+attribute controls whether the string is echoed to the local log;
+this is "true" by default
+</p>
+<h3>Example</h3>
+A simple example of connecting to a server and running a command.
+
+<blockquote><pre>
+&lt;rexec userid=&quot;bob&quot; password=&quot;badpass&quot; server=&quot;localhost&quot; command=&quot;ls&quot;/&gt;
+</pre></blockquote>
+
+The task can be used with other ports as well:
+<blockquote><pre>
+&lt;rexec port=&quot;80&quot; userid=&quot;bob&quot; password=&quot;badpass&quot; server=&quot;localhost&quot; command=&quot;ls&quot;/&gt;
+</pre></blockquote>
+
+
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/rmic.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/rmic.html
new file mode 100644
index 00000000..b644c68c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/rmic.html
@@ -0,0 +1,353 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Rmic Task</title>
+</head>
+
+<body>
+
+<h2><a name="rmic">Rmic</a></h2>
+<h3>Description</h3>
+<p>Runs the rmic compiler for a certain class.</p>
+<p>Rmic can be run on a single class (as specified with the classname
+attribute) or a number of classes at once (all classes below base that
+are neither _Stub nor _Skel classes). If you want to rmic a single
+class and this class is a class nested into another class, you have to
+specify the classname in the form <code>Outer$$Inner</code> instead of
+<code>Outer.Inner</code>.</p>
+<p>It is possible to refine the set of files that are being rmiced. This can be
+done with the <i>includes</i>, <i>includesfile</i>, <i>excludes</i>, <i>excludesfile</i> and <i>defaultexcludes</i>
+attributes. With the <i>includes</i> or <i>includesfile</i> attribute you specify the files you want to
+have included by using patterns. The <i>exclude</i> or <i>excludesfile</i> attribute is used to specify
+the files you want to have excluded. This is also done with patterns. And
+finally with the <i>defaultexcludes</i> attribute, you can specify whether you
+want to use default exclusions or not. See the section on <a
+href="../dirtasks.html#directorybasedtasks">directory based tasks</a>, on how the
+inclusion/exclusion of files works, and how to write patterns.</p>
+<p>This task forms an implicit <a href="../Types/fileset.html">FileSet</a> and
+supports most attributes of <code>&lt;fileset&gt;</code>
+(<code>dir</code> becomes <code>base</code>) as well as the nested
+<code>&lt;include&gt;</code>, <code>&lt;exclude&gt;</code> and
+<code>&lt;patternset&gt;</code> elements.</p>
+<p>It is possible to use different compilers. This can be selected
+with the &quot;build.rmic&quot; property, the <code>compiler</code>
+attribute. or a nested element.
+<a name="compilervalues">Here are the choices</a>:</p>
+<ul>
+ <li>default -the default compiler (kaffe or sun) for the platform.
+ <li>sun (the standard compiler of the JDK)</li>
+ <li>kaffe (the standard compiler of <a href="http://www.kaffe.org" target="_top">Kaffe</a>)</li>
+ <li>weblogic</li>
+ <li>forking - the sun compiler forked into a separate process (since Apache Ant 1.7)</li>
+ <li>xnew - the sun compiler forked into a separate process,
+ with the -Xnew option (since Ant 1.7).
+ This is the most reliable way to use -Xnew</li>
+ <li> "" (empty string). This has the same behaviour as not setting the compiler attribute.
+ First the value of <tt>build.rmic</tt> is used if defined, and if not, the default
+ for the platform is chosen. If build.rmic is set to this, you get the default.
+
+</ul>
+
+<p>The <a href="http://dione.zcu.cz/~toman40/miniRMI/">miniRMI</a>
+project contains a compiler implementation for this task as well,
+please consult miniRMI's documentation to learn how to use it.</p>
+
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">base</td>
+ <td valign="top">the location to store the compiled files.
+ Also serves as the parent directory for any non-Fileset includes, etc.
+ (This functionality has remained unchanged.)</td>
+ <td valign="top" align="center" rowspan="2"><a href="#footnote-1">*1</a></td>
+ </tr>
+ <tr>
+ <td valign="top">destdir</td>
+ <td valign="top">the location to store the compiled files.</td>
+ </tr>
+ <tr>
+ <td valign="top">classname</td>
+ <td valign="top">the class for which to run <code>rmic</code>.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">filtering</td>
+ <td valign="top">indicates whether token filtering should take place</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">sourcebase</td>
+ <td valign="top">Pass the &quot;-keepgenerated&quot; flag to rmic and
+ move the generated source file to the given sourcebase directory.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">stubversion</td>
+ <td valign="top">Specify the JDK version for the generated stub code.
+ Specify &quot;1.1&quot; to pass the &quot;-v1.1&quot; option to rmic,
+ "1.2" for -v12, compat for -vcompat. <br>
+ Since Ant1.7, if you do not specify a version, and do not ask
+ for iiop or idl files, "compat" is selected.
+
+ </td>
+ <td align="center" valign="top">No, default="compat"</td>
+ </tr>
+ <tr>
+ <td valign="top">classpath</td>
+ <td valign="top">The classpath to use during compilation</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">classpathref</td>
+ <td valign="top">The classpath to use during compilation, given as <a
+ href="../using.html#references">reference</a> to a PATH defined elsewhere</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">includes</td>
+ <td valign="top">comma- or space-separated list of patterns of files that must be
+ included. All files are included when omitted.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">includesfile</td>
+ <td valign="top">the name of a file. Each line of this file is
+ taken to be an include pattern</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">excludes</td>
+ <td valign="top">comma- or space-separated list of patterns of files that must be
+ excluded. No files (except default excludes) are excluded when omitted.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">excludesfile</td>
+ <td valign="top">the name of a file. Each line of this file is
+ taken to be an exclude pattern</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">defaultexcludes</td>
+ <td valign="top">indicates whether default excludes should be used or not
+ (&quot;yes&quot;/&quot;no&quot;). Default excludes are used when omitted.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">verify</td>
+ <td valign="top">check that classes implement Remote before handing them
+ to rmic (default is false)</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">iiop</td>
+ <td valign="top">indicates that portable (RMI/IIOP) stubs should be generated</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">iiopopts</td>
+ <td valign="top">additional arguments for IIOP class generation</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">idl</td>
+ <td valign="top">indicates that IDL output files should be generated</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">idlopts</td>
+ <td valign="top">additional arguments for IDL file generation</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">debug</td>
+ <td valign="top">generate debug info (passes -g to rmic). Defaults to false.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">includeAntRuntime</td>
+ <td valign="top">whether to include the Ant run-time libraries;
+ defaults to <code>yes</code>.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">includeJavaRuntime</td>
+ <td valign="top">whether to include the default run-time
+ libraries from the executing VM; defaults to <code>no</code>.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">extdirs</td>
+ <td valign="top">location of installed extensions.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">compiler</td>
+ <td valign="top">The compiler implementation to use.
+ If this attribute is not set, the value of the
+ <code>build.rmic</code> property, if set, will be used.
+ Otherwise, the default compiler for the current VM will be used.
+ (See the above <a href="#compilervalues">list</a> of valid
+ compilers.)</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">executable</td>
+ <td valign="top">Complete path to the <code>rmic</code>
+ executable to use in case of the <code>forking</code>
+ or <code>xnew</code> compiler.
+ Defaults to the rmic compiler of the Java version that is currently
+ running Ant.<br/>
+ <em>Since Ant 1.8.0</em>.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">listfiles</td>
+ <td valign="top">Indicates whether the source files to be compiled will
+ be listed; defaults to <code>no</code>.<br/>
+ <em>Since Ant 1.8.0</em>.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+</table>
+
+<p><a name="footnote-1">*1</a>:
+<ul>
+ <li>Maintaining compatibility, <code>base</code>, when specified by
+ itself, serves as both the parent directory for any source files
+ AND the output directory.</li>
+ <li><code>destdir</code> can be used to specify the output
+ directory, allowing for <code>base</code> to be used as the parent
+ directory for any source files.</li>
+ <li>At least one of either <code>base</code> or <code>destdir</code>
+ must be specified and exist, or a runtime error will
+ occur.</li>
+</ul>
+</p>
+
+<h3>Parameters specified as nested elements</h3>
+<h4>classpath and extdirs</h4>
+<p><code>Rmic</code>'s <i>classpath</i> and <i>extdirs</i> attributes are <a
+href="../using.html#path">PATH like structure</a> and can also be set via a nested
+<i>classpath</i> and <i>extdirs</i> elements.</p>
+
+<h4>compilerarg</h4>
+
+<p>You can specify additional command line arguments for the compiler
+with nested <code>&lt;compilerarg&gt;</code> elements. These elements
+are specified like <a href="../using.html#arg">Command-line
+Arguments</a> but have an additional attribute that can be used to
+enable arguments only if a given compiler implementation will be
+used.</p>
+<table border="1" cellpadding="2" cellspacing="0">
+<tr>
+ <td width="12%" valign="top"><b>Attribute</b></td>
+ <td width="78%" valign="top"><b>Description</b></td>
+ <td width="10%" valign="top"><b>Required</b></td>
+</tr>
+ <tr>
+ <td valign="top">value</td>
+ <td align="center" rowspan="4">See
+ <a href="../using.html#arg">Command-line Arguments</a>.</td>
+ <td align="center" rowspan="4">Exactly one of these.</td>
+ </tr>
+ <tr>
+ <td valign="top">line</td>
+ </tr>
+ <tr>
+ <td valign="top">file</td>
+ </tr>
+ <tr>
+ <td valign="top">path</td>
+ </tr>
+ <tr>
+ <td valign="top">prefix</td>
+ <td align="center" rowspan="2">See
+ <a href="../using.html#arg">Command-line Arguments</a>.
+ <em>Since Ant 1.8.</em></td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">suffix</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">compiler</td>
+ <td>Only pass the specified argument if the chosen
+ compiler implementation matches the value of this attribute.
+ Legal values are the
+ same as those in the above <a href="#compilervalues">list</a> of valid
+ compilers.)</td>
+ <td align="center">No</td>
+ </tr>
+</table>
+
+<h4>compilerclasspath <em>since Ant 1.8.0</em></h4>
+
+<p>A <a href="../using.html#path">PATH like structure</a> holding the
+ classpath to use when loading the compiler implementation if a
+ custom class has been specified. Doesn't have any effect when
+ using one of the built-in compilers.</p>
+
+<h4>Any nested element of a type that implements RmicAdapter
+ <em>since Ant 1.8.0</em></h4>
+
+<p>If a defined type implements the <code>RmicAdapter</code>
+ interface a nested element of that type can be used as an
+ alternative to the <code>compiler</code> attribute.</p>
+
+<h3>Examples</h3>
+<pre> &lt;rmic classname=&quot;com.xyz.FooBar&quot; base=&quot;${build}/classes&quot;/&gt;</pre>
+<p>runs the rmic compiler for the class <code>com.xyz.FooBar</code>. The
+compiled files will be stored in the directory <code>${build}/classes</code>.</p>
+<pre> &lt;rmic base=&quot;${build}/classes&quot; includes=&quot;**/Remote*.class&quot;/&gt;</pre>
+<p>runs the rmic compiler for all classes with <code>.class</code>
+files below <code>${build}/classes</code> whose classname starts with
+<i>Remote</i>. The compiled files will be stored in the directory
+<code>${build}/classes</code>.</p>
+
+<p>If you want to use a custom
+ RmicAdapter <code>org.example.MyAdapter</code> you can either
+ use the compiler attribute:</p>
+<pre>
+&lt;rmic classname=&quot;com.xyz.FooBar&quot;
+ base=&quot;${build}/classes&quot;
+ compiler="org.example.MyAdapter"/&gt;
+</pre>
+<p>or a define a type and nest this into the task like in:</p>
+<pre>
+&lt;componentdef classname="org.example.MyAdapter"
+ name="myadapter"/&gt;
+&lt;rmic classname=&quot;com.xyz.FooBar&quot;
+ base=&quot;${build}/classes&quot;&gt;
+ &lt;myadapter/&gt;
+&lt;/rmic&gt;
+</pre>
+<p>in which case your compiler adapter can support attributes and
+ nested elements of its own.</p>
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/rpm.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/rpm.html
new file mode 100644
index 00000000..691d391d
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/rpm.html
@@ -0,0 +1,123 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<html>
+
+<head>
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Rpm Task</title>
+</head>
+
+<body>
+
+<h2><a name="rpm">Rpm</a></h2>
+<h3>Description</h3>
+<p>
+ A basic task for invoking the rpm executable to build a RedHat Package Manager Linux installation
+ file. The task currently only works on Linux or other Unix platforms with rpm support.
+</p>
+
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">specFile</td>
+ <td valign="top">The name of the spec file to be used. This must be relative to the SPECS directory
+ under the root of the RPM set in the topDir attribute.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">topDir</td>
+ <td valign="top">
+ This is the directory which will have the expected
+ subdirectories, SPECS, SOURCES, BUILD, SRPMS. If this isn't specified,
+ the default RPM directory of the system (or user, if ~/.rpmmacros defines it) is used (often
+ /usr/src/rpm.<br>
+ Defining a topdir will set <tt>%_topdir</tt> to the specified directory -there is no need
+ to edit your .rpmmacros file.
+ </td>
+ <td valign="top" align="center">No, but your build file is very brittle if it is not set.</td>
+ </tr>
+ <tr>
+ <td valign="top">cleanBuildDir</td>
+ <td valign="top">This will remove the generated files in the BUILD
+ directory.
+ See the the <tt>--clean</tt> option of rpmbuild.
+ </td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">removeSpec</td>
+ <td valign="top">This will remove the spec file from SPECS.
+ See the the <tt>--rmspec</tt> option of rpmbuild.
+ </td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">removeSource</td>
+ <td valign="top">Flag (optional, default=false)
+ to remove the sources after the build.
+ See the the <tt>--rmsource</tt> option of rpmbuild.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">rpmBuildCommand</td>
+ <td valign="top">The executable to use for building the RPM.
+ Defaults to <code>rpmbuild</code> if it can be found or
+ <code>rpm</code> otherwise. Set this if you don't have either on
+ your PATH or want to use a different executable. <em>Since Apache Ant
+ 1.6</em>.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">command</td>
+ <td valign="top">The command to pass to the rpmbuild program. The default is "-bb"</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">quiet</td>
+ <td valign="top">Suppress output. Defaults to false.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">output/error</td>
+ <td valign="top">Where standard output and error go</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">failOnError</td>
+ <td valign="top">Stop the buildprocess if the RPM build command exits with
+ a non-zero returncode. Defaults to false</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+</table>
+
+<h3>Examples</h3>
+<pre>
+ &lt;rpm
+ specFile="example.spec"
+ topDir="build/rpm"
+ cleanBuildDir="true"
+ failOnError="true"/&gt;
+</pre>
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/schemavalidate.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/schemavalidate.html
new file mode 100644
index 00000000..1aac2ef5
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/schemavalidate.html
@@ -0,0 +1,283 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>SchemaValidate Task</title>
+</head>
+
+<body>
+
+<h2><a name="schemavalidate">SchemaValidate</a></h2>
+<h3>Description</h3>
+
+<p>This <tt>schemavalidate</tt> task validates XML files described by an XML Schema.
+The task extends the XmlValidate task with XSD-specific features.</p>
+<ol>
+<li>The parser is created validating and namespace aware
+</li>
+<li>Validation is turned on.</li>
+<li>Schema validation is turned on.</li>
+<li>Any no-namespace schema URL or file supplied is used as the no-namespace schema
+<li>All nested schema declarations are turned into the list of namespace-url
+bindings for schema lookup.
+</ol>
+
+Note that nested catalogs are still used for lookup of the URLs given as the
+sources of schema documents, so you can still delegate lookup to a catalog, you
+just need to list all schema URIs and their URL equivalents.
+
+<p>This task supports the use of nested
+ <li><a href="../Types/xmlcatalog.html"><tt>&lt;xmlcatalog&gt;</tt></a> elements</li>
+ <li> <tt>&lt;schema&gt;</tt> elements, that bind a namespace URI to a URL or a
+ local filename.
+ <li><tt>&lt;dtd&gt;</tt> elements which are used to resolve DTDs and entities.</li>
+ <li><tt>&lt;attribute&gt;</tt> elements which are used to set features on the parser.
+ These can be any number of
+ <a href="http://www.saxproject.org/apidoc/org/xml/sax/package-summary.html#package_description"><tt>http://xml.org/sax/features/</tt></a>
+ or other features that your parser may support.</li>
+ <li><tt>&lt;property&gt;</tt> elements, containing string properties
+</p>
+
+<p>
+The task only supports SAX2 or later parsers: it is an error to specify a SAX1
+parser.
+
+
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">classname</td>
+ <td valign="top">the parser to use.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">classpathref</td>
+ <td valign="top">where to find the parser class.
+ Optionally can use an embedded <tt>&lt;classpath&gt;</tt> element.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">disableDTD</td>
+ <td valign="top">
+ Flag to disable DTD support. DTD support is needed to
+ validate XSD files themselves, amongst others.
+ </td>
+ <td valign="top" align="center">No - default false</td>
+ </tr>
+ <tr>
+ <td valign="top">failonerror</td>
+ <td valign="top">fails on a error if set to true (defaults to true).</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">file</td>
+ <td valign="top">the file(s) you want to check. (optionally can use an embedded fileset)</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">fullchecking</td>
+ <td valign="top">
+ enable full schema checking. Slow but strict.
+ </td>
+ <td valign="top" align="center">No - default true</td>
+ </tr>
+
+ <tr>
+ <td valign="top">lenient</td>
+ <td valign="top">
+ if true, only check the XML document is well formed
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">noNamespaceFile</td>
+ <td valign="top">
+ filename of a no-namespace XSD file to provide the
+ schema for no-namespace XML content.
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">noNamespaceURL</td>
+ <td valign="top">
+ URL of a no-namespace XSD file to provide the
+ schema for no-namespace XML content.
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">warn</td>
+ <td valign="top">log parser warn events.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+</table>
+
+<h3><a name="nested">Nested Elements</a></h3>
+
+
+<h4>schema</h4>
+<p>
+Identify the name and location of a schema that may be used in validating
+the document(s).
+</p>
+<table border="1" cellpadding="2" cellspacing="0">
+<tr>
+ <td width="12%" valign="top"><b>Attribute</b></td>
+ <td width="78%" valign="top"><b>Description</b></td>
+ <td width="10%" valign="top"><b>Required</b></td>
+</tr>
+ <tr>
+ <td valign="top">namespace</td>
+ <td valign="top">URI of the schema namespace</td>
+ <td align="center" valign="top">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">url</td>
+ <td valign="top">URL of the schema</td>
+ <td align="center" valign="top">One of url or file is required</td>
+ </tr>
+ <tr>
+ <td valign="top">file</td>
+ <td valign="top">file of the schema</td>
+ <td align="center" valign="top">One of url or file is required</td>
+ </tr>
+</table>
+
+<h4>dtd</h4>
+<p>
+<tt>&lt;dtd&gt;</tt> is used to specify different locations for DTD resolution.
+</p>
+<table border="1" cellpadding="2" cellspacing="0">
+<tr>
+ <td width="12%" valign="top"><b>Attribute</b></td>
+ <td width="78%" valign="top"><b>Description</b></td>
+ <td width="10%" valign="top"><b>Required</b></td>
+</tr>
+ <tr>
+ <td valign="top">publicId</td>
+ <td valign="top">Public ID of the DTD to resolve</td>
+ <td align="center" valign="top">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">location</td>
+ <td valign="top">Location of the DTD to use, which can be a file,
+ a resource, or a URL</td>
+ <td align="center" valign="top">Yes</td>
+ </tr>
+</table>
+<h4>xmlcatalog</h4>
+<p>The <a href="../Types/xmlcatalog.html"><tt>&lt;xmlcatalog&gt;</tt></a>
+element is used to perform entity resolution.</p>
+<h4>attribute</h4>
+<p>The <tt>&lt;attribute&gt;</tt> element is used to set parser features.<br>
+Features usable with the xerces parser are defined here :
+ <a href="http://xml.apache.org/xerces-j/features.html">Setting features</a><br>
+
+SAX features are defined here:
+ <a href="http://www.saxproject.org/apidoc/org/xml/sax/package-summary.html#package_description"><tt>http://xml.org/sax/features/</tt></a><br>
+ </p>
+<table border="1" cellpadding="2" cellspacing="0">
+<tr>
+ <td width="12%" valign="top"><b>Attribute</b></td>
+ <td width="78%" valign="top"><b>Description</b></td>
+ <td width="10%" valign="top"><b>Required</b></td>
+</tr>
+ <tr>
+ <td valign="top">name</td>
+ <td valign="top">The name of the feature</td>
+ <td align="center" valign="top">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">value</td>
+ <td valign="top">The boolean value of the feature</td>
+ <td align="center" valign="top">Yes</td>
+ </tr>
+</table>
+</p>
+
+<h4>property</h4>
+<p>The <tt>&lt;property&gt;</tt> element is used to set properties.
+These properties are defined here for the xerces XML parser implementation :
+ <a href="http://xml.apache.org/xerces-j/properties.html">XML Parser properties</a>
+Properties can be used to set the schema used to validate the XML file.
+</p>
+<table border="1" cellpadding="2" cellspacing="0">
+<tr>
+ <td width="12%" valign="top"><b>Attribute</b></td>
+ <td width="78%" valign="top"><b>Description</b></td>
+ <td width="10%" valign="top"><b>Required</b></td>
+</tr>
+ <tr>
+ <td valign="top">name</td>
+ <td valign="top">The name of the feature</td>
+ <td align="center" valign="top">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">value</td>
+ <td valign="top">The string value of the property</td>
+ <td align="center" valign="top">Yes</td>
+ </tr>
+</table>
+</p>
+
+
+<h3>Examples</h3>
+<pre>
+ &lt;schemavalidate
+ noNamespaceFile="document.xsd"
+ file="xml/endpiece.xml"&gt;
+ &lt;/schemavalidate&gt;
+</pre>
+Validate a document against an XML schema. The document does not declare
+any schema itself, which is why the <tt>noNamespaceFile</tt> is needed.
+<pre>
+ &lt;presetdef name="validate-soap"&gt;
+ &lt;schemavalidate&gt;
+ &lt;schema namespace="http://schemas.xmlsoap.org/ws/2003/03/addressing"
+ file="${soap.dir}/ws-addressing.xsd" /&gt;
+ &lt;schema namespace="http://www.w3.org/2003/05/soap-envelope"
+ file="${soap.dir}/soap12.xsd" /&gt;
+ &lt;schema namespace="http://schemas.xmlsoap.org/wsdl/"
+ file="${soap.dir}/wsdl.xsd" /&gt;
+ &lt;schema namespace="http://www.w3.org/2001/XMLSchema"
+ file="${soap.dir}/XMLSchema.xsd" /&gt;
+ &lt;/schemavalidate&gt;
+ &lt;/presetdef&gt;
+</pre>
+Declare a new preset task, <tt>&lt;validate-soap&gt;</tt>, that validates
+XSD and WSDL documents against the relevant specifications.
+To validate XSD documents, you also need XMLSchema.dtd and datatypes.dtd in
+the same directory as XMLSchema.xsd, or pointed to via the catalog. All
+these files can be fetched from <a href="http://www.w3.org/2001/XMLSchema">
+the W3C</a>.
+<pre>
+ &lt;validate-soap file="xml/test.xsd"/&gt;
+</pre>
+Use the preset task defined above to validate an XML Schema document.
+<br>
+
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/scp.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/scp.html
new file mode 100644
index 00000000..e8d66d0d
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/scp.html
@@ -0,0 +1,293 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>SCP Task</title>
+</head>
+
+<body>
+
+<h2><a name="scp">SCP</a></h2>
+<h3>Description</h3>
+
+<p><em>since Apache Ant 1.6</em></p>
+
+<p>Copies a file or FileSet to or from a (remote) machine running an SSH daemon.
+FileSet <i>only</i> works for copying files from the local machine to a
+remote machine.</p>
+
+<p><b>Note:</b> This task depends on external libraries not included
+in the Ant distribution. See <a
+href="../install.html#librarydependencies">Library Dependencies</a>
+for more information. This task has been tested with jsch-0.1.2 and later.</p>
+
+<p>See also the <a href="sshexec.html">sshexec task</a></p>
+
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">file</td>
+ <td valign="top">The file to copy. This can be a local path or a
+ remote path of the form <i>user[:password]@host:/directory/path</i>.
+ <i>:password</i> can be omitted if you use key based
+ authentication or specify the password attribute. The way remote
+ path is recognized is whether it contains @ character or not. This
+ will not work if your localPath contains @ character.</td>
+ <td valign="top" align="center">Yes, unless a nested
+ <code>&lt;fileset&gt;</code> element is used.</td>
+ </tr>
+ <tr>
+ <td valign="top">localFile</td>
+ <td valign="top">This is an alternative to the file attribute. But
+ this must always point to a local file. The reason this was added
+ was that when you give file attribute it is treated as remote if
+ it contains @ character. This character can exist also in local
+ paths. <em>since Ant 1.6.2</em></td>
+ <td valign="top" align="center">Alternative to file attribute.</td>
+ </tr>
+ <tr>
+ <td valign="top">remoteFile</td>
+ <td valign="top">This is an alternative to the file attribute. But
+ this must always point to a remote file. <em>since Ant 1.6.2</em></td>
+ <td valign="top" align="center">Alternative to file attribute.</td>
+ </tr>
+ <tr>
+ <td valign="top">todir</td>
+ <td valign="top">The directory to copy to. This can be a local path
+ or a remote path of the form <i>user[:password]@host:/directory/path</i>.
+ <i>:password</i> can be omitted if you use key based
+ authentication or specify the password attribute. The way remote
+ path is recognized is whether it contains @ character or not. This
+ will not work if your localPath contains @ character.</td>
+ <td valian="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">localTodir</td>
+ <td valign="top">This is an alternative to the todir
+ attribute. But this must always point to a local directory. The
+ reason this was added was that when you give todir attribute it is
+ treated as remote if it contains @ character. This character can
+ exist also in local paths. <em>since Ant 1.6.2</em></td>
+ <td valian="top" align="center">Alternative to todir attribute.</td>
+ </tr>
+ <tr>
+ <td valign="top">localTofile</td>
+ <td valign="top">Changes the file name to the given name while
+ receiving it, only useful if receiving a single file. <em>since
+ Ant 1.6.2</em></td>
+ <td valian="top" align="center">Alternative to todir attribute.</td>
+ </tr>
+ <tr>
+ <td valign="top">remoteTodir</td>
+ <td valign="top">This is an alternative to the todir
+ attribute. But this must always point to a remote directory.
+ <em>since Ant 1.6.2</em></td>
+ <td valian="top" align="center">Alternative to todir attribute.</td>
+ </tr>
+ <tr>
+ <td valign="top">remoteTofile</td>
+ <td valign="top">Changes the file name to the given name while
+ sending it, only useful if sending a single file. <em>since
+ Ant 1.6.2</em></td>
+ <td valian="top" align="center">Alternative to todir attribute.</td>
+ </tr>
+ <tr>
+ <td valign="top">port</td>
+ <td valign="top">The port to connect to on the remote host.</td>
+ <td valian="top" align="center">No, defaults to 22.</td>
+ </tr>
+ <tr>
+ <td valign="top">trust</td>
+ <td valign="top">This trusts all unknown hosts if set to yes/true.<br>
+ <strong>Note</strong> If you set this to false (the default), the
+ host you connect to must be listed in your knownhosts file, this
+ also implies that the file exists.</td>
+ <td valian="top" align="center">No, defaults to No.</td>
+ </tr>
+ <tr>
+ <td valign="top">knownhosts</td>
+ <td valign="top">This sets the known hosts file to use to validate
+ the identity of the remote host. This must be a SSH2 format file.
+ SSH1 format is not supported.</td>
+ <td valian="top" align="center">No, defaults to
+ ${user.home}/.ssh/known_hosts.</td>
+ </tr>
+ <tr>
+ <td valign="top">failonerror</td>
+ <td valign="top">Whether to halt the build if the transfer fails.
+ </td>
+ <td valign="top" align="center">No; defaults to true.</td>
+ </tr>
+ <tr>
+ <td valign="top">password</td>
+ <td valign="top">The password.</td>
+ <td valign="top" align="center">Not if you are using key based
+ authentication or the password has been given in the file or
+ todir attribute.</td>
+ </tr>
+ <tr>
+ <td valign="top">keyfile</td>
+ <td valign="top">Location of the file holding the private key.</td>
+ <td valign="top" align="center">Yes, if you are using key based
+ authentication.</td>
+ </tr>
+ <tr>
+ <td valign="top">passphrase</td>
+ <td valign="top">Passphrase for your private key.</td>
+ <td valign="top" align="center">No, defaults to an empty string.</td>
+ </tr>
+ <tr>
+ <td valign="top">verbose</td>
+ <td valign="top">Determines whether SCP outputs verbosely to the
+ user. Currently this means outputting dots/stars showing the
+ progress of a file transfer. <em>since Ant 1.6.2</em></td>
+ <td valign="top" align="center">No; defaults to false.</td>
+ </tr>
+ <tr>
+ <td valign="top">sftp</td>
+ <td valign="top">Determines whether SCP uses the sftp protocol.
+ The sftp protocol is the file transfer protocol of SSH2. It is
+ recommended that this be set to true if you are copying to/from a
+ server that doesn't support scp1. <em>since Ant 1.7</em></td>
+ <td valign="top" align="center">No; defaults to false.</td>
+ </tr>
+ <tr>
+ <td valign="top">preserveLastModified</td>
+ <td valign="top">Determines whether the last modification
+ timestamp of downloaded files is preserved. It only works when
+ transferring from a remote to a local system and probably doesn't
+ work with a server that doesn't support SSH2. <em>since Ant
+ 1.8.0</em></td>
+ <td valign="top" align="center">No; defaults to false.</td>
+ </tr>
+ <tr>
+ <td valign="top">filemode</td>
+ <td valign="top">A 3 digit octal string, specify the user, group
+ and other modes in the standard Unix fashion. Only applies to
+ uploaded files. Note the actual permissions of the remote
+ file will be governed by this setting and the UMASK on the
+ remote server. Default is 644. <em>since Ant 1.9.5</em>.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">dirmode</td>
+ <td valign="top">A 3 digit octal string, specify the user, group
+ and other modes in the standard Unix fashion. Only applies to
+ uploaded dirs. Note the actual permissions of the remote
+ dir will be governed by this setting and the UMASK on the
+ remote server. Default is 755. <em>since Ant 1.9.5</em>.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+</table>
+<h3>Parameters specified as nested elements</h3>
+
+<h4>fileset</h4>
+ <p><a href="../Types/fileset.html">FileSet</a>s are used to select
+sets of files to copy.
+ To use a fileset, the <code>todir</code> attribute must be set.</p>
+
+<h3>Examples</h3>
+<p><b>Copy a single local file to a remote machine</b></p>
+<pre>
+ &lt;scp file=&quot;myfile.txt&quot; todir=&quot;user:password@somehost:/home/chuck&quot;/&gt;
+</pre>
+
+<p><b>Copy a single local file to a remote machine with separate
+password attribute</b></p>
+<pre>
+ &lt;scp file=&quot;myfile.txt&quot; todir=&quot;user@somehost:/home/chuck&quot; password=&quot;password&quot;/&gt;
+</pre>
+
+<p><b>Copy a single local file to a remote machine using key base
+authentication.</b></p>
+<pre>
+ &lt;scp file=&quot;myfile.txt&quot;
+ todir=&quot;user@somehost:/home/chuck&quot;
+ keyfile=&quot;${user.home}/.ssh/id_dsa&quot;
+ passphrase=&quot;my extremely secret passphrase&quot;
+ /&gt;
+</pre>
+
+<p><b>Copy a single remote file to a local directory</b></p>
+<pre>
+ &lt;scp file=&quot;user:password@somehost:/home/chuck/myfile.txt&quot; todir=&quot;../some/other/dir&quot;/&gt;
+</pre>
+
+<p><b>Copy a remote directory to a local directory</b></p>
+<pre>
+ &lt;scp file=&quot;user:password@somehost:/home/chuck/*&quot; todir=&quot;/home/sara&quot;/&gt;
+</pre>
+
+<p><b>Copy a local directory to a remote directory</b></p>
+<pre>
+ &lt;scp todir=&quot;user:password@somehost:/home/chuck/&quot;&gt;
+ &lt;fileset dir=&quot;src_dir&quot;/&gt;
+ &lt;/scp&gt;
+</pre>
+<p><b>Copy a set of files to a directory</b></p>
+<pre>
+ &lt;scp todir=&quot;user:password@somehost:/home/chuck&quot;&gt;
+ &lt;fileset dir=&quot;src_dir&quot;&gt;
+ &lt;include name=&quot;**/*.java&quot;/&gt;
+ &lt;/fileset&gt;
+ &lt;/scp&gt;
+
+ &lt;scp todir=&quot;user:password@somehost:/home/chuck&quot;&gt;
+ &lt;fileset dir=&quot;src_dir&quot; excludes=&quot;**/*.java&quot;/&gt;
+ &lt;/scp&gt;
+</pre>
+
+<p><strong>Security Note:</strong> Hard coding passwords and/or usernames
+in scp task can be a serious security hole. Consider using variable
+substitution and include the password on the command line. For example:
+<p>
+<pre>
+ &lt;scp todir=&quot;${username}:${password}@host:/dir&quot; ...&gt;
+</pre>
+Invoking ant with the following command line:
+<pre>
+ ant -Dusername=me -Dpassword=mypassword target1 target2
+</pre>
+
+Is slightly better, but the username/password is exposed to all users on an Unix
+system (via the ps command). The best approach is to use the
+<code>&lt;input&gt;</code> task and/or retrieve the password from a (secured)
+.properties file.
+
+<p>
+
+<p><strong>Unix Note:</strong> File permissions are not retained when files
+are downloaded; they end up with the default <code>UMASK</code> permissions
+instead. This is caused by the lack of any means to query or set file
+permissions in the current Java runtimes. If you need a permission-
+preserving copy function, use <code>&lt;exec executable="scp" ... &gt;</code>
+instead.
+</p>
+
+
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/script.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/script.html
new file mode 100644
index 00000000..fb008224
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/script.html
@@ -0,0 +1,393 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us"></meta>
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Script Task</title>
+</head>
+
+<body>
+
+<h2><a name="script">Script</a></h2>
+<h3>Description</h3>
+ <p>Execute a script in a
+ <a href="http://jakarta.apache.org/bsf" target="_top">Apache BSF</a>
+ or
+ <a href="https://scripting.dev.java.net">JSR 223</a> supported language.
+ </p>
+ <p><b>Note:</b>
+ This task depends on external libraries not included in the Apache Ant distribution.
+ See <a href="../install.html#librarydependencies">Library Dependencies</a>
+ for more information.
+ </p>
+ <p>
+ The task may use the BSF scripting manager or the JSR 223 manager that
+ is included in JDK6 and higher. This is controlled by the <code>manager</code>
+ attribute. The JSR 223 scripting manager is indicated by "javax".
+ </p>
+ <p>All items (tasks, targets, etc) of the running project are
+ accessible from the script, using either their <code>name</code> or
+ <code>id</code> attributes (as long as their names are considered
+ valid Java identifiers, that is).
+ This is controlled by the "setbeans" attribute of the task.
+ The name "project" is a pre-defined reference to the Project, which can be
+ used instead of the project name. The name "self" is a pre-defined reference to the actual
+ <code>&lt;script&gt;</code>-Task instance.<br>From these objects you have access to the Ant Java API, see the
+<a href="../api/index.html">JavaDoc</a> (especially for
+<a href="../api/org/apache/tools/ant/Project.html">Project</a> and
+<a href="../api/org/apache/tools/ant/taskdefs/optional/Script.html">Script</a>) for more information.</p>
+<p>If you are using JavaScript under BSF, a good resource is <a target="_blank" href="http://www.mozilla.org/rhino/doc.html">
+http://www.mozilla.org/rhino/doc.html</a> as we are using their JavaScript interpreter.</p>
+<p>Scripts can do almost anything a task written in Java could do.</p>
+<p>Rhino provides a special construct - the <i>JavaAdapter</i>. With that you can
+create an object which implements several interfaces, extends classes and for which you
+can overwrite methods. Because this is an undocumented feature (yet), here is the link
+to an explanation: <a href="http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&oe=UTF-8&newwindow=1&frame=right&th=610d2db45c0756bd&seekm=391EEC3C.5236D929%40yahoo.com#link2">
+Groups@Google: "Rhino, enum.js, JavaAdapter?"</a> by Norris Boyd in the newsgroup
+<i>netscape.public.mozilla.jseng</i>.</p>
+
+<p>If you are creating Targets programmatically, make sure you set the
+Location to a useful value. In particular all targets should have
+different location values.</p>
+
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">language</td>
+ <td valign="top">The programming language the script is written in.
+ Must be a supported Apache BSF or JSR 223 language</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">manager</td>
+ <td valign="top">
+ <em>Since: Ant 1.7. </em>
+ The script engine manager to use. This can have
+ one of three values ("auto", "bsf" or "javax").
+ The default value is "auto".
+ <dl>
+ <li>"bsf" use the BSF scripting manager to run
+ the language.</li>
+ <li>"javax" use the <em>javax.scripting</em> manager
+ to run the language. (This will only work for JDK6 and higher).</li>
+ <li>"auto" use the BSF engine if it exists,
+ otherwise use the <em>javax.scripting</em> manager.</li>
+ </dl>
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">src</td>
+ <td valign="top">The location of the script as a file, if not inline</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">setbeans</td>
+ <td valign="top">
+ This attribute controls whether to set variables for
+ all properties, references and targets in the running script.
+ If this attribute is false, only the the "project" and "self" variables are set.
+ If this attribute is true all the variables are set. The default value of this
+ attribute is "true". <em>Since Ant 1.7</em>
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">classpath</td>
+ <td valign="top">
+ The classpath to pass into the script. <em>Since Ant 1.7</em>
+ </td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">classpathref</td>
+ <td valign="top">The classpath to use, given as a
+ <a href="../using.html#references">reference</a> to a path defined elsewhere.
+ <em>Since Ant 1.7</em></td>
+ <td align="center" valign="top">No</td>
+ </tr>
+</table>
+<h3>Parameters specified as nested elements</h3>
+<h4>classpath</h4>
+ <p><em>Since Ant 1.7</em></p>
+<p>
+ <code>Script</code>'s <code>classpath</code> attribute is a
+ <a href="../using.html#path">path-like structure</a> and can also be set via a nested
+ <code>&lt;classpath&gt;</code> element.
+ <p>
+ If a classpath is set, it will be used as the current thread
+ context classloader, and
+ as the classloader given to the BSF manager.
+ This means that it can be used to specify
+ the classpath containing the language implementation for BSF
+ or for JSR 223 managers.
+ This can be useful if one wants
+ to keep ${user.home}/.ant/lib free of lots of scripting language
+ specific jar files.
+ </p>
+ <p>
+ <b>NB: (Since Ant 1.7.1)</b>
+ This classpath <em>can</em> be used to
+ specify the location of
+ the BSF jar file and/or languages
+ that have engines in the BSF jar file. This includes the
+ javascript, jython, netrexx and jacl languages.
+ </p>
+</p>
+<h3>Examples</h3>
+The following snippet shows use of five different languages:
+ <blockquote><pre>
+ &lt;property name="message" value="Hello world"/&gt;
+
+ &lt;script language="groovy"&gt;
+ println("message is " + message)
+ &lt;/script&gt;
+
+ &lt;script language="beanshell"&gt;
+ System.out.println("message is " + message);
+ &lt;/script&gt;
+
+ &lt;script language="judoscript"&gt;
+ println 'message is ', message
+ &lt;/script&gt;
+
+ &lt;script language="ruby"&gt;
+ print 'message is ', $message, "\n"
+ &lt;/script&gt;
+
+ &lt;script language="jython"&gt;
+print "message is %s" % message
+ &lt;/script&gt;
+</pre>
+ </blockquote>
+ <p>
+ Note that for the <i>jython</i> example, the script contents <b>must</b>
+ start on the first column.
+ </p>
+ <p>
+ Note also that for the <i>ruby</i> example, the names of the set variables are prefixed
+ by a '$'.
+ <p>
+ The following script shows a little more complicated jruby example:
+ </p>
+ <blockquote><pre>
+&lt;script language="ruby"&gt;
+ xmlfiles = Dir.new(".").entries.delete_if { |i| ! (i =~ /\.xml$/) }
+ xmlfiles.sort.each { |i| $self.log(i) }
+&lt;/script&gt;
+</pre>
+ </blockquote>
+ <p>
+ The same example in groovy is:
+ </p>
+ <blockquote><pre>
+&lt;script language="groovy"&gt;
+ xmlfiles = new java.io.File(".").listFiles().findAll{ it =~ "\.xml$"}
+ xmlfiles.sort().each { self.log(it.toString())}
+&lt;/script&gt;
+</pre>
+ </blockquote>
+ <p>
+ The following example shows the use of classpath to specify the location
+ of the beanshell jar file.
+ </p>
+ <blockquote><pre>
+&lt;script language="beanshell" setbeans="true"&gt;
+ &lt;classpath&gt;
+ &lt;fileset dir="${user.home}/lang/beanshell" includes="*.jar" /&gt;
+ &lt;/classpath&gt;
+ System.out.println("Hello world");
+&lt;/script&gt;
+</pre>
+ </blockquote>
+ <p>
+ The following script uses javascript to create a number of
+ echo tasks and execute them.
+ </p>
+<blockquote><pre>
+&lt;project name=&quot;squares&quot; default=&quot;main&quot; basedir=&quot;.&quot;&gt;
+
+ &lt;target name=&quot;main&quot;&gt;
+
+ &lt;script language=&quot;javascript&quot;&gt; &lt;![CDATA[
+
+ for (i=1; i&lt;=10; i++) {
+ echo = squares.createTask(&quot;echo&quot;);
+ echo.setMessage(i*i);
+ echo.perform();
+ }
+
+ ]]&gt; &lt;/script&gt;
+
+ &lt;/target&gt;
+
+&lt;/project&gt;
+</pre></blockquote>
+<p>generates</p>
+<blockquote><pre>
+main:
+1
+4
+9
+16
+25
+36
+49
+64
+81
+100
+
+BUILD SUCCESSFUL
+</pre></blockquote>
+
+<p>Now a more complex example using the Java API and the Ant API. The goal is to list the
+filesizes of all files a <code>&lt;fileset/&gt;</code> caught.</p>
+<blockquote><pre>
+
+&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;
+&lt;project name="<font color=blue>MyProject</font>" basedir="." default="main"&gt;
+
+ &lt;property name="fs.dir" value="src"/&gt;
+ &lt;property name="fs.includes" value="**/*.txt"/&gt;
+ &lt;property name="fs.excludes" value="**/*.tmp"/&gt;
+
+ &lt;target name="main"&gt;
+ &lt;script language="javascript"&gt; &lt;![CDATA[
+
+ // import statements
+ <font color=blue>// importPackage(java.io)</font>;
+ <font color=blue>importClass(java.io.File)</font>;
+
+ // Access to Ant-Properties by their names
+ dir = <font color=blue>project</font>.getProperty("fs.dir");
+ includes = <font color=blue>MyProject</font>.getProperty("fs.includes");
+ excludes = <font color=blue>self.getProject()</font> .<font color=blue>getProperty("fs.excludes")</font>;
+
+ // Create a &lt;fileset dir="" includes=""/&gt;
+ fs = project.<font color=blue>createDataType("fileset")</font>;
+ fs.setDir( new File(dir) );
+ <font color=blue>fs.setIncludes(includes)</font>;
+ fs.setExcludes(excludes);
+
+ // Get the files (array) of that fileset
+ ds = fs.getDirectoryScanner(project);
+ srcFiles = ds.getIncludedFiles();
+
+ // iterate over that array
+ for (i=0; i&lt;srcFiles.length; i++) {
+
+ // get the values via Java API
+ var basedir = fs.getDir(project);
+ var filename = srcFiles[i];
+ var file = <font color=blue>new File(basedir, filename)</font>;
+ var size = file.length();
+
+ // create and use a Task via Ant API
+ echo = MyProject.<font color=blue>createTask("echo")</font>;
+ echo.setMessage(filename + ": " + size + " byte");
+ echo.<font color=blue>perform()</font>;
+ }
+ ]]&gt;&lt;/script&gt;
+ &lt;/target&gt;
+&lt;/project&gt;
+</pre></blockquote>
+<p>We want to use the Java API. Because we don't want always typing the package signature
+we do an import. Rhino knows two different methods for import statements: one for packages
+and one for a single class. By default only the <i>java</i> packages are available, so
+<i>java.lang.System</i> can be directly imported with <code>importClass/importPackage</code>.
+For other packages you have to prefix the full classified name with <i>Packages</i>.
+For example Ant's <i>FileUtils</i> class can be imported with
+<code>importClass(<b>Packages</b>.org.apache.tools.ant.util.FileUtils)</code>
+<br>
+The <code>&lt;script&gt;</code> task populates the Project instance under
+the name <i>project</i>, so we can use that reference. Another way is to use its given name
+or getting its reference from the task itself.<br>
+The Project provides methods for accessing and setting properties, creating DataTypes and
+Tasks and much more.<br>
+After creating a FileSet object we initialize that by calling its set-methods. Then we can
+use that object like a normal Ant task (<code>&lt;copy&gt;</code> for example).<br>
+For getting the size of a file we instantiate a <code>java.io.File</code>. So we are using
+normal Java API here.<br>
+Finally we use the <code>&lt;echo&gt;</code> task for producing the output. The task is not executed by
+its execute() method, because the perform() method (implemented in Task itself) does the
+appropriate logging before and after invoking execute().
+</p>
+<p>
+ Here is an example of using beanshell to create an ant
+ task. This task will add filesets and paths to a referenced
+ path. If the path does not exist, it will be created.
+</p>
+<blockquote><pre>
+&lt;!--
+ Define addtopath task
+ --&gt;
+&lt;script language="beanshell"&gt;
+ import org.apache.tools.ant.Task;
+ import org.apache.tools.ant.types.Path;
+ import org.apache.tools.ant.types.FileSet;
+ public class AddToPath extends Task {
+ private Path path;
+ public void setRefId(String id) {
+ path = getProject().getReference(id);
+ if (path == null) {
+ path = new Path(getProject());
+ getProject().addReference(id, path);
+ }
+ }
+ public void add(Path c) {
+ path.add(c);
+ }
+ public void add(FileSet c) {
+ path.add(c);
+ }
+ public void execute() {
+ // Do nothing
+ }
+ }
+ project.addTaskDefinition("addtopath", AddToPath.class);
+&lt;/script&gt;
+</pre></blockquote>
+ <p>
+ An example of using this task to create a path
+ from a list of directories (using antcontrib's
+ <a href="http://ant-contrib.sourceforge.net/tasks/tasks/for.html">
+ &lt;for&gt;</a> task) follows:
+ </p>
+<blockquote><pre>
+&lt;path id="main.path"&gt;
+ &lt;fileset dir="build/classes"/&gt;
+&lt;/path&gt;
+&lt;ac:for param="ref" list="commons,fw,lps"
+ xmlns:ac="antlib:net.sf.antcontrib"&gt;
+ &lt;sequential&gt;
+ &lt;addtopath refid="main.path"&gt;
+ &lt;fileset dir="${dist.dir}/@{ref}/main"
+ includes="**/*.jar"/&gt;
+ &lt;/addtopath&gt;
+ &lt;/sequential&gt;
+&lt;/ac:for&gt;
+</pre></blockquote>
+
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/scriptdef.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/scriptdef.html
new file mode 100644
index 00000000..38c3ffff
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/scriptdef.html
@@ -0,0 +1,332 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Scriptdef Task</title>
+</head>
+
+<body>
+
+<h2><a name="script">Scriptdef</a></h2>
+<h3>Description</h3>
+<p>Scriptdef can be used to define an Apache Ant task using a scripting language. Ant
+scripting languages supported by
+<a href="http://jakarta.apache.org/bsf" target="_top">Apache BSF</a>
+or
+ <a href="https://scripting.dev.java.net">JSR 223</a>
+may be
+used to define the script. Scriptdef provides a mechanism to encapsulate
+control logic from a build within an Ant task minimizing the need for
+providing control style tasks in Ant itself. Complex logic can be made
+available while retaining the simple structure of an Ant build file. Scriptdef
+is also useful for prototyping new custom tasks. Certainly as the complexity
+of the script increases it would be better to migrate the task definition
+into a Java based custom task.
+</p>
+
+<p><b>Note:</b> This task depends on external libraries not included in the
+Ant distribution. See
+<a href="../install.html#librarydependencies">Library Dependencies</a>
+for more information.</p>
+
+
+
+<p>The attributes and nested elements supported by the task may be defined
+using <code>&lt;attribute&gt;</code> and <code>&lt;element&gt;</code> nested elements. These are
+available to the script that implements the task as two collection style
+script variables <code>attributes</code> and <code>elements</code>. The
+elements in the <code>attributes</code> collection may be accessed by the
+attribute name. The <code>elements</code> collection is accessed by the nested
+element name. This will return a list of all instances of the nested element.
+The instances in this list may be accessed by an integer index.
+</p>
+
+<p><b>Note:</b> Ant will turn all attribute and element names into all
+lowercase names, so even if you use name="SomeAttribute", you'll have
+to use "someattribute" to retrieve the attribute's value from the
+<code>attributes</code> collection.</p>
+
+<p>The name "self" (<i>since Ant 1.6.3</i>) is a pre-defined reference to the
+ script def task instance.
+ It can be used for logging, or for integration with the rest of
+ ant. the <code>self.text attribute</code> contains
+ any nested text passed to the script</p>
+
+<p>If an attribute or element is not passed in,
+then <code>attributes.get()</code> or <code>elements.get()</code> will
+return null. It is up to the script to perform any checks and validation.
+<code>self.fail(String message)</code>can be used to raise a
+<code>BuildException</code>.
+</p>
+
+
+<p>The name "project" is a pre-defined reference to the Ant Project. For
+more information on writing scripts, please refer to the
+<a href="script.html"><code>&lt;script&gt;</code></a> task
+</p>
+
+
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">name</td>
+ <td valign="top">the name of the task to be created using the script</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">language</td>
+ <td valign="top">The programming language the script is written in.
+ Must be a supported Apache BSF or JSR 223 language</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">manager</td>
+ <td valign="top">
+ The script engine manager to use.
+ See the <a href="../Tasks/script.html">script</a> task
+ for using this attribute.
+ </td>
+ <td valign="top" align="center">No - default is "auto"</td>
+ </tr>
+ <tr>
+ <td valign="top">src</td>
+ <td valign="top">The location of the script as a file, if not inline</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">uri</td>
+ <td valign="top">
+ The XML namespace uri that this definition should live in.
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">classpath</td>
+ <td valign="top">
+ The classpath to pass into the script.
+ </td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">classpathref</td>
+ <td valign="top">The classpath to use, given as a
+ <a href="../using.html#references">reference</a> to a path defined elsewhere.
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">loaderRef</td>
+ <td valign="top">the name of the loader that is
+ used to load the script, constructed from the specified
+ classpath. This allows multiple script definitions
+ to reuse the same class loader.
+ </td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ </table>
+
+<h3>Nested elements</h3>
+<h4>attribute</h4>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">name</td>
+ <td valign="top">the name of the attribute</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+</table>
+
+<h4>element</h4>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">name</td>
+ <td valign="top">the name of the nested element to be supported by the
+ task defined by the script</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">classname</td>
+ <td valign="top">the classname of the class to be used for the nested element.
+ This specifies the class directly and is an alternative to specifying
+ the Ant type name.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">type</td>
+ <td valign="top">This is the name of an Ant task or type which is to
+ be used when this element is to be created. This is an alternative
+ to specifying the class name directly. If the type is in a namespace,
+ the URI and a : must be prefixed to the type. For example
+ <code>type="antlib:example.org:newtype"</code></td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">any resource or resource collection</td>
+ <td valign="top">Since Ant1.7.1, this task can load scripts
+ from any resource supplied as a nested element. when </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+
+</table>
+
+ <h4>classpath</h4>
+ <p>
+ See the <a href="../Tasks/script.html">script</a> task
+ for using this nested element.
+ </p>
+
+
+<h3>Examples</h3>
+
+<p>
+The following definition creates a task which supports an attribute called
+attr and two nested elements, one being a fileset and the other a path. When
+executed, the resulting task logs the value of the attribute and the basedir
+of the first fileset.
+</p>
+
+<pre>
+ &lt;scriptdef name=&quot;scripttest&quot; language=&quot;javascript&quot;&gt;
+ &lt;attribute name=&quot;attr1&quot;/&gt;
+ &lt;element name=&quot;fileset&quot; type=&quot;fileset&quot;/&gt;
+ &lt;element name=&quot;path&quot; type=&quot;path&quot;/&gt;
+ &lt;![CDATA[
+
+ self.log(&quot;Hello from script&quot;);
+ self.log(&quot;Attribute attr1 = &quot; + attributes.get(&quot;attr1&quot;));
+ self.log(&quot;First fileset basedir = &quot;
+ + elements.get(&quot;fileset&quot;).get(0).getDir(project));
+
+ ]]&gt;
+ &lt;/scriptdef&gt;
+
+ &lt;scripttest attr1=&quot;test&quot;&gt;
+ &lt;path&gt;
+ &lt;pathelement location=&quot;src&quot;/&gt;
+ &lt;/path&gt;
+ &lt;fileset dir=&quot;src&quot;/&gt;
+ &lt;fileset dir=&quot;main&quot;/&gt;
+ &lt;/scripttest&gt;
+</pre>
+
+<p>
+The following variation on the above script lists the number of fileset elements
+and iterates through them
+</p>
+<pre>
+ &lt;scriptdef name=&quot;scripttest2&quot; language=&quot;javascript&quot;&gt;
+ &lt;element name=&quot;fileset&quot; type=&quot;fileset&quot;/&gt;
+ &lt;![CDATA[
+ filesets = elements.get(&quot;fileset&quot;);
+ self.log(&quot;Number of filesets = &quot; + filesets.size());
+ for (i = 0; i &lt; filesets.size(); ++i) {
+ self.log(&quot;fileset &quot; + i + &quot; basedir = &quot;
+ + filesets.get(i).getDir(project));
+ }
+ ]]&gt;
+ &lt;/scriptdef&gt
+
+ &lt;scripttest2&gt;
+ &lt;fileset dir=&quot;src&quot;/&gt;
+ &lt;fileset dir=&quot;main&quot;/&gt;
+ &lt;/scripttest2&gt;
+</pre>
+
+<p>
+When a script has a syntax error, the scriptdef name will be listed in the
+error. For example in the above script, removing the closing curly bracket
+would result in this error
+</p>
+
+<p><code>build.xml:15: SyntaxError: missing } in compound
+statement (scriptdef <code>&lt;scripttest2&gt;</code>; line 10)</code></p>
+
+<p>
+Script errors are only detected when a script task is actually executed.
+</p>
+<p>
+ The next example does uses nested text in Jython. It also declares
+ the script in a new xml namespace, which must be used to refer to
+ the task. Declaring scripts in a new namespace guarantees that Ant will
+ not create a task of the same (namespace,localname) name pair.
+</p>
+
+<pre>
+&lt;target name="echo-task-jython"&gt;
+ &lt;scriptdef language="jython"
+ name="echo"
+ uri="http://example.org/script"&gt;
+ &lt;![CDATA[
+self.log("text: " +self.text)
+ ]]&gt;
+ &lt;/scriptdef&gt;
+&lt;/target&gt;
+
+&lt;target name="testEcho" depends="echo-task-jython"
+ xmlns:s="http://example.org/script"&gt;
+ &lt;s:echo&gt;nested text&lt;/s:echo&gt;
+&lt;/target&gt;
+</pre>
+
+The next example shows the use of &lt;classpath&gt; and
+"loaderref" to get access to the beanshell jar.
+<pre>
+ &lt;scriptdef name="b1" language="beanshell"
+ loaderref="beanshell-ref"&gt;
+ &lt;attribute name="a"/&gt;
+ &lt;classpath
+ path="${user.home}/scripting/beanshell/bsh-1.3b1.jar"/&gt;
+ self.log("attribute a is " + attributes.get("a"));
+ &lt;/scriptdef&gt;
+
+ &lt;scriptdef name="b2" language="beanshell"
+ loaderref="beanshell-ref"&gt;
+ &lt;attribute name="a2"/&gt;
+ self.log("attribute a2 is " + attributes.get("a2"));
+ &lt;/scriptdef&gt;
+
+ &lt;b1 a="this is an 'a'"/&gt;
+ &lt;b2 a2="this is an 'a2' for b2"/&gt;
+</pre>
+<h3>Testing Scripts</h3>
+
+<p>
+The easiest way to test scripts is to use the
+<a href="http://ant.apache.org/antlibs/antunit/">AntUnit</a> ant library.
+This will run all targets in a script that begin with "test" (and their dependencies). </p>
+
+
+
+
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/sequential.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/sequential.html
new file mode 100644
index 00000000..d3deda64
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/sequential.html
@@ -0,0 +1,55 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Sequential Task</title>
+</head>
+
+<body>
+
+<h2>Sequential</h2>
+<h3>Description</h3>
+<p>Sequential is a container task - it can contain other Apache Ant tasks. The nested
+tasks are simply executed in sequence. Sequential's primary use is to support
+the sequential execution of a subset of tasks within the
+<a href="parallel.html">parallel</a> task</p>
+
+<p>The sequential task has no attributes and does not support any nested
+elements apart from Ant tasks. Any valid Ant task may be embedded within the
+sequential task.</p>
+
+<h3>Example</h3>
+<pre>
+&lt;parallel&gt;
+ &lt;wlrun ... &gt;
+ &lt;sequential&gt;
+ &lt;sleep seconds=&quot;30&quot;/&gt;
+ &lt;junit ... &gt;
+ &lt;wlstop/&gt;
+ &lt;/sequential&gt;
+&lt;/parallel&gt;
+</pre>
+<p>This example shows how the sequential task is used to execute three tasks in
+sequence, while another task is being executed in a separate thread. </p>
+
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/serverdeploy.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/serverdeploy.html
new file mode 100644
index 00000000..87d0777d
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/serverdeploy.html
@@ -0,0 +1,335 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>ServerDeploy Task</title>
+
+</head>
+
+<body>
+
+<h1><a name="serverdeploy">Apache Ant ServerDeploy User Manual</a></h1>
+<p>by</p>
+<!-- Names are in alphabetical order, on last name -->
+<ul>
+<li>Christopher A. Longo (<a href="mailto:cal@cloud9.net">cal@cloud9.net</a>)</li>
+<li>Cyrille Morvan (<a href="mailto:cmorvan@ingenosya.com">cmorvan@ingenosya.com</a>)</li>
+</ul>
+
+</p>
+<hr>
+<p> At present the tasks support:<br>
+
+<ul>
+<li><a href="http://www.bea.com" target="_top">Weblogic</a> servers</li>
+<li><a href="http://www.objectweb.org/jonas/" target="_top">JOnAS</a>
+2.4 Open Source EJB server</li>
+</ul>
+Over time we expect further optional tasks to support additional J2EE Servers.
+</p>
+
+<hr>
+
+<table border="1" cellpadding="5">
+<tr><td>Task</td><td colspan="2">Application Servers</td></tr>
+<tr><td rowspan="4"><a href="#serverdeploy_element">serverdeploy</a></td><td colspan="2" align="center"><b>Nested Elements</b></td></tr>
+<tr><td><a href="#serverdeploy_generic">generic</a></td><td>Generic task</td></tr>
+<tr><td><a href="#serverdeploy_jonas">jonas</a></td><td>JOnAS 2.4</td></tr>
+<tr><td><a href="#serverdeploy_weblogic">weblogic</a></td><td>Weblogic</td></tr>
+
+</table>
+
+<a name="serverdeploy_element">
+<h2>ServerDeploy element</h2>
+
+<h3><b>Description:</b></h3>
+
+<p>The <code>serverdeploy</code> task is used to run a "hot" deployment tool for
+vendor-specific J2EE server. The task requires nested elements which define
+the attributes of the vendor-specific deployment tool being executed.
+Vendor-specific deployment tools elements may enforce rules for which
+attributes are required, depending on the tool.
+</p>
+
+<h3>Parameters:</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">action</td>
+ <td valign="top">This is the action to be performed. For most cases this
+ will be "deploy". Some tools support additional actions, such as "delete", "list",
+ "undeploy", "update"...</td>
+ <td>Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">source</td>
+ <td valign="top">A fully qualified path/filename of the component to be deployed.
+ This may be an .ear, .jar, .war, or any other type that is supported by the server.
+ </td>
+ <td>Tool dependent</td>
+ </tr>
+</table>
+
+<h3>Nested Elements</h3>
+
+<p>The serverdeploy task supports a nested <code>classpath</code> element to set the classpath.</p>
+
+<h3>Vendor-specific nested elements</h3>
+
+<h3>Parameters used for all tools:</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">classpath</td>
+ <td valign="top">The classpath to be passed to the JVM running the tool.
+ The classpath may also be supplied as a nested element.</td>
+ <td>Tool dependent</td>
+ </tr>
+ <tr>
+ <td valign="top">server</td>
+ <td valign="top">The address or URL for the server where the component will be deployed.</td>
+ <td>Tool dependent</td>
+ </tr>
+ <tr>
+ <td valign="top">username</td>
+ <td valign="top">The user with privileges to deploy applications to the server.</td>
+ <td>Tool dependent</td>
+ </tr>
+ <tr>
+ <td valign="top">password</td>
+ <td valign="top">The password of the user with privileges to deploy applications to the server.</td>
+ <td>Tool dependent</td>
+ </tr>
+</table>
+
+<p>Also supported are nested vendor-specific elements.</p>
+
+<a name="serverdeploy_generic">
+<h3>Generic element</h3>
+This element is provided for generic Java-based deployment tools.
+The generic task accepts (but does not require) nested <code>arg</code>
+and <code>jvmarg</code> elements.
+A JVM will be spawned with the provided attributes. It is recommended
+that a vendor-specific element be used over the generic one if at all
+possible.
+<p>The following attributes are supported by the generic element.</p>
+<p>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">classname</td>
+ <td valign="top">This is the fully qualified classname of the Java based
+ deployment tool to execute.</td>
+ <td>Yes</td>
+ </tr>
+</table>
+</p>
+
+<h3>Nested Elements</h3>
+<p>The generic element supports nested <code>&lt;arg&gt;</code> and <code>&lt;jvmarg&gt;</code> elements.</p>
+
+<h3>Example</h3>
+
+<p>This example shows the use of generic deploy element to deploy a component
+using a Java based deploy tool:</p>
+
+<pre>
+ &lt;serverdeploy action=&quot;deploy&quot; source=&quot;${lib.dir}/ejb_myApp.ear&quot;&gt;
+ &lt;generic classname="com.yamato.j2ee.tools.deploy.DeployTool"
+ classpath=&quot;${classpath}&quot;
+ username=&quot;${user.name}&quot;
+ password=&quot;${user.password}&quot;&gt;
+ &lt;arg value="-component=WildStar"/&gt;
+ &lt;arg value="-force"/&gt;
+ &lt;jvmarg value="-ms64m"/&gt;
+ &lt;jvmarg value="-mx128m"/&gt;
+ &lt;/generic&gt;
+ &lt;/serverdeploy&gt;
+</pre>
+
+<a name="serverdeploy_weblogic">
+<h3>WebLogic element</h3>
+<p>
+The WebLogic element contains additional attributes to run the
+<code>weblogic.deploy</code> deployment tool.
+<p>Valid actions for the tool are <code>deploy</code>, <code>undeploy</code>,
+<code>list</code>, <code>update</code>, and <code>delete</code>.
+<p>If the action is <code>deploy</code> or <code>update</code>,
+the <code>application</code> and <code>source</code> attributes must be set.
+If the action is <code>undeploy</code> or <code>delete</code>,
+the <code>application</code> attribute must be set. If the <code>username</code>
+attribute is omitted, it defaults to "system". The <code>password</code> attribute is
+required for all actions.
+<p>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">application</td>
+ <td valign="top">This is the name of the application being deployed</td>
+ <td>Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">component</td>
+ <td valign="top">This is the component string for deployment targets.
+ It is in the form <code>&lt;component&gt;:&lt;target1&gt;,&lt;target2&gt;...</code>
+ Where component is the archive name (minus the .jar, .ear, .war
+ extension). Targets are the servers where the components will be deployed</td>
+ <td>no</td>
+ </tr>
+ <tr>
+ <td valign="top">debug</td>
+ <td valign="top">If set to true, additional information will be
+ printed during the deployment process.</td>
+ <td>No</td>
+ </tr>
+</table>
+
+
+<h3>Examples</h3>
+
+<p>This example shows the use of serverdeploy to deploy a component to a WebLogic server:</p>
+
+<pre>
+ &lt;serverdeploy action=&quot;deploy&quot; source=&quot;${lib.dir}/ejb_myApp.ear&quot;&gt;
+ &lt;weblogic application=&quot;myapp&quot;
+ server=&quot;t3://myserver:7001&quot;
+ classpath=&quot;${weblogic.home}/lib/weblogic.jar&quot;
+ username=&quot;${user.name}&quot;
+ password=&quot;${user.password}&quot;
+ component=&quot;ejb_foobar:myserver,productionserver&quot;
+ debug=&quot;true&quot;/&gt;
+ &lt;/serverdeploy&gt;
+</pre>
+
+<p>This example shows serverdeploy being used to delete a component from a
+WebLogic server:</p>
+
+<pre>
+ &lt;serverdeploy action=&quot;delete&quot; source=&quot;${lib.dir}/ejb_myApp.jar&quot;/&gt
+ &lt;weblogic application=&quot;myapp&quot;
+ server=&quot;t3://myserver:7001&quot;
+ classpath=&quot;${weblogic.home}/lib/weblogic.jar&quot;
+ username=&quot;${user.name}&quot;
+ password=&quot;${user.password}&quot;/&gt;
+ &lt;/serverdeploy&gt;
+</pre>
+
+<a name="serverdeploy_jonas">
+<h3>JOnAS (Java Open Application Server) element</h3>
+<p>
+The JOnAS element contains additional attributes to run the
+<code>JonasAdmin</code> deployment tool.
+<p>Valid actions for the tool are <code>deploy</code>, <code>undeploy</code>,
+<code>list</code> and <code>update</code>.
+<p>You can't use <code>user</code> and <code>password</code> property with this
+task.
+<p>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">jonasroot</td>
+ <td valign="top">The root directory for JOnAS.</td>
+ <td>Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">orb</td>
+ <td valign="top">Choose your ORB : RMI, JEREMIE, DAVID, ... If omitted, it defaults
+ to the one present in classpath. The corresponding JOnAS JAR is
+ automatically added to the classpath. If your orb is DAVID (RMI/IIOP) you must
+ specify davidhost and davidport properties.</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td valign="top">davidhost</td>
+ <td valign="top">The value for the system property : <code>david.CosNaming.default_host</code> .</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td valign="top">davidport</td>
+ <td valign="top">The value for the system property : <code>david.CosNaming.default_port</code> .</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td valign="top">classname</td>
+ <td valign="top">This is the fully qualified classname of the Java based
+ deployment tool to execute. Default to <code>org.objectweb.jonas.adm.JonasAdmin</code></td>
+ <td>No</td>
+ </tr>
+
+</table>
+
+<h3>Nested Elements</h3>
+<p>The jonas element supports nested <code>&lt;arg&gt;</code> and <code>&lt;jvmarg&gt;</code> elements.</p>
+
+
+<h3>Examples</h3>
+
+<p>This example shows the use of serverdeploy to deploy a component to a JOnAS server:</p>
+
+<pre>
+ &lt;serverdeploy action=&quot;deploy&quot; source=&quot;${lib.dir}/ejb_myApp.jar&quot;&gt;
+ &lt;jonas server=&quot;MyJOnAS&quot; jonasroot="${jonas.root}"&gt;
+
+ &lt;classpath&gt;
+ &lt;pathelement path=&quot;${jonas.root}/lib/RMI_jonas.jar&quot;/&gt;
+ &lt;pathelement path=&quot;${jonas.root}/config/&quot;/&gt;
+ &lt;/classpath&gt;
+ &lt;/jonas&gt;
+ &lt;/serverdeploy&gt;
+</pre>
+
+<p>This example shows serverdeploy being used to list the components from a
+JOnAS server and a WebLogic server:</p>
+
+<pre>
+ &lt;serverdeploy action=&quot;list&quot;/&gt
+ &lt;jonas jonasroot=&quot;${jonas.root}&quot; orb=&quot;JEREMIE&quot;/&gt;
+ &lt;weblogic application=&quot;myapp&quot
+ server=&quot;t3://myserver:7001&quot;
+ classpath=&quot;${weblogic.home}/lib/weblogic.jar&quot;
+ username=&quot;${user.name}&quot;
+ password=&quot;${user.password}&quot;/&gt;
+ &lt;/serverdeploy&gt;
+</pre>
+
+
+
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/setproxy.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/setproxy.html
new file mode 100644
index 00000000..245924ce
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/setproxy.html
@@ -0,0 +1,220 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<html>
+<head>
+ <meta http-equiv="Content-Language" content="en-us">
+ <title>Setproxy Task</title>
+</head>
+
+<body bgcolor="#ffffff" text="#000000" link="#525D76"
+ alink="#525D76" vlink="#525D76">
+
+<table border="0" width="100%" cellspacing="4">
+
+ <!-- PAGE HEADER -->
+ <tr>
+ <td>
+ <table border="0" width="100%"><tr>
+ <td valign="bottom">
+ <font size="+3" face="arial,helvetica,sanserif"><strong>Setproxy Task</strong></font>
+ <br><font face="arial,helvetica,sanserif">Sets Java's web proxy properties, so that tasks and code run in the same JVM can have through-the-firewall access to remote web sites, and remote ftp sites.</font>
+ </td>
+ <td>
+ <!-- PROJECT LOGO -->
+ <a href="http://ant.apache.org/">
+ <img src="../images/ant_logo_large.gif" align="right" alt="Apache Ant" border="0">
+ </a>
+ </td>
+ </tr></table>
+ </td>
+ </tr>
+
+ <!-- START RIGHT SIDE MAIN BODY -->
+ <tr>
+ <td valign="top" align="left">
+
+ <!-- Applying task/long-description -->
+ <!-- Start Description -->
+ <table border="0" cellspacing="0" cellpadding="2" width="100%">
+ <tr><td>&nbsp;</td></tr>
+
+ <tr><td bgcolor="#525D76">
+ <font color="#ffffff" face="arial,helvetica.sanserif">
+ <a name="description">
+ <strong>Description</strong></a></font>
+ </td></tr>
+
+ <tr><td><blockquote>
+ Sets Java's web proxy properties, so that tasks and code run in the same JVM can have through-the-firewall access to remote web sites, and remote ftp sites. You can nominate an http and ftp proxy, or a socks server, reset the server settings, or do nothing at all. <p> Examples <pre>&lt;setproxy/&gt;</pre> do nothing <pre>&lt;setproxy proxyhost="firewall"/&gt;</pre> set the proxy to firewall:80 <pre>&lt;setproxy proxyhost="firewall" proxyport="81"/&gt;</pre> set the proxy to firewall:81 <pre>&lt;setproxy proxyhost=""/&gt;</pre> stop using the http proxy; don't change the socks settings <pre>&lt;setproxy socksproxyhost="socksy"/&gt;</pre> use socks via socksy:1080 <pre>&lt;setproxy socksproxyhost=""/&gt;</pre> stop using the socks server. <p> You can set a username and password for http with the <tt>proxyHost</tt> and <tt>proxyPassword</tt> attributes. On Java1.4 and above these can also be used against SOCKS5 servers. </p>
+ </blockquote></td></tr>
+
+ </table>
+ <!-- End Description -->
+
+ <!-- Ignore -->
+
+
+
+ <!-- Start Attributes -->
+ <table border="0" cellspacing="0" cellpadding="2" width="100%">
+ <tr><td>&nbsp;</td></tr>
+ <tr><td bgcolor="#525D76">
+ <font color="#ffffff" face="arial,helvetica.sanserif">
+ <a name="attributes">
+ <strong>Parameters</strong></a></font>
+ </td></tr>
+ <tr><td><blockquote>
+ <table>
+ <tr>
+ <td bgcolor="#cccccc" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif"><b>Attribute</b></font>
+ </td>
+ <td bgcolor="#cccccc" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif"><b>Description</b></font>
+ </td>
+ <td bgcolor="#cccccc" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif"><b>Type</b></font>
+ </td>
+ <td bgcolor="#cccccc" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif"><b>Requirement</b></font>
+ </td>
+ </tr>
+ <!-- Attribute Group -->
+
+ <!-- Attribute Group -->
+ <!-- Attribute -->
+ <tr>
+ <td bgcolor="#eeeeee" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif">nonproxyhosts</font>
+ </td>
+ <td bgcolor="#eeeeee" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif">A list of hosts to bypass the proxy on. These should be separated with the vertical bar character '|'. Only in Java 1.4 does ftp use this list. e.g. fozbot.corp.sun.com|*.eng.sun.com</font>
+ </td>
+ <td bgcolor="#eeeeee" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif">String</font>
+ </td>
+ <td bgcolor="#eeeeee" valign="top" align="left" rowspan="7">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif">Optional</font>
+ </td>
+ </tr>
+ <!-- Attribute -->
+ <tr>
+ <td bgcolor="#eeeeee" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif">proxyhost</font>
+ </td>
+ <td bgcolor="#eeeeee" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif">the HTTP/ftp proxy host. Set this to "" for the http proxy option to be disabled</font>
+ </td>
+ <td bgcolor="#eeeeee" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif">String</font>
+ </td>
+ </tr>
+ <!-- Attribute -->
+ <tr>
+ <td bgcolor="#eeeeee" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif">proxypassword</font>
+ </td>
+ <td bgcolor="#eeeeee" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif">Set the password for the proxy. Used only if the proxyUser is set.</font>
+ </td>
+ <td bgcolor="#eeeeee" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif">String</font>
+ </td>
+ </tr>
+ <!-- Attribute -->
+ <tr>
+ <td bgcolor="#eeeeee" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif">proxyport</font>
+ </td>
+ <td bgcolor="#eeeeee" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif">the HTTP/ftp proxy port number; default is 80</font>
+ </td>
+ <td bgcolor="#eeeeee" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif">int</font>
+ </td>
+ </tr>
+ <!-- Attribute -->
+ <tr>
+ <td bgcolor="#eeeeee" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif">proxyuser</font>
+ </td>
+ <td bgcolor="#eeeeee" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif">set the proxy user. Probably requires a password to accompany this setting. Default=""</font>
+ </td>
+ <td bgcolor="#eeeeee" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif">String</font>
+ </td>
+ </tr>
+ <!-- Attribute -->
+ <tr>
+ <td bgcolor="#eeeeee" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif">socksproxyhost</font>
+ </td>
+ <td bgcolor="#eeeeee" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif">The name of a Socks server. Set to "" to turn socks proxying off.</font>
+ </td>
+ <td bgcolor="#eeeeee" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif">String</font>
+ </td>
+ </tr>
+ <!-- Attribute -->
+ <tr>
+ <td bgcolor="#eeeeee" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif">socksproxyport</font>
+ </td>
+ <td bgcolor="#eeeeee" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif">Set the ProxyPort for socks connections. The default value is 1080</font>
+ </td>
+ <td bgcolor="#eeeeee" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif">int</font>
+ </td>
+ </tr>
+
+
+ </table>
+ </blockquote></td></tr>
+
+ </table>
+ <!-- End Attributes -->
+
+ <!-- Start Elements -->
+ <table border="0" cellspacing="0" cellpadding="2" width="100%">
+ <tr><td>&nbsp;</td></tr>
+
+ <tr><td bgcolor="#525D76">
+ <font color="#ffffff" face="arial,helvetica.sanserif">
+ <a name="elements">
+ <strong>Parameters as nested elements</strong></a></font>
+ </td></tr>
+
+ <tr><td><blockquote>
+
+ </blockquote></td></tr>
+
+ </table>
+ <!-- End Elements -->
+
+
+ </td>
+ </tr>
+ <!-- END RIGHT SIDE MAIN BODY -->
+
+</table>
+
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/signjar.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/signjar.html
new file mode 100644
index 00000000..0f9d7784
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/signjar.html
@@ -0,0 +1,299 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>SignJar Task</title>
+</head>
+
+<body>
+
+<h2><a name="signjar">SignJar</a></h2>
+<h3>Description</h3>
+<p>Signing a jar allows users to authenticate the publisher.</p>
+<p>Signs JAR files with the <a target="_blank" href="http://docs.oracle.com/javase/7/docs/technotes/tools/windows/jarsigner.html"><tt>jarsigner</tt> command line tool</a>.
+It will take a named file in the <tt>jar</tt> attribute, and an optional
+<tt>destDir</tt> or <tt>signedJar</tt> attribute. Nested paths are also
+supported; here only an (optional) <tt>destDir</tt> is allowed. If a destination
+directory or explicit JAR file name is not provided, JARs are signed in place.
+</p>
+<p>
+Dependency rules
+</p>
+<ul>
+<li>Nonexistent destination JARs are created/signed</li>
+<li>Out of date destination JARs are created/signed</li>
+<li>If a destination file and a source file are the same,
+and <tt>lazy</tt> is true, the JAR is only signed if it does not
+contain a signature by this alias.</li>
+<li>If a destination file and a source file are the same,
+and <tt>lazy</tt> is false, the JAR is signed.</li>
+</ul>
+
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">jar</td>
+ <td valign="top">the jar file to sign</td>
+ <td valign="top" align="center">Yes, unless nested paths have
+ been used.</td>
+ </tr>
+ <tr>
+ <td valign="top">alias</td>
+ <td valign="top">the alias to sign under</td>
+ <td valign="top" align="center">Yes.</td>
+ </tr>
+ <tr>
+ <td valign="top">storepass</td>
+ <td valign="top">password for keystore integrity.</td>
+ <td valign="top" align="center">Yes.</td>
+ </tr>
+ <tr>
+ <td valign="top">keystore</td>
+ <td valign="top">keystore location</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">storetype</td>
+ <td valign="top">keystore type</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">keypass</td>
+ <td valign="top">password for private key (if different)</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">sigfile</td>
+ <td valign="top">name of .SF/.DSA file</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">signedjar</td>
+ <td valign="top">name of signed JAR file. This can only be set when
+ the <tt>jar</tt> attribute is set.</td>
+ <td valign="top" align="center">No.</td>
+ </tr>
+ <tr>
+ <td valign="top">verbose</td>
+ <td valign="top">(true | false) verbose output when signing</td>
+ <td valign="top" align="center">No; default false</td>
+ </tr>
+ <tr>
+ <td valign="top">strict</td>
+ <td valign="top">(true | false) strict checking when signing.<br/><em>since Ant 1.9.1</em>.</td>
+ <td valign="top" align="center">No; default false</td>
+ </tr>
+ <tr>
+ <td valign="top">internalsf</td>
+ <td valign="top">(true | false) include the .SF file inside the signature
+block</td>
+ <td valign="top" align="center">No; default false</td>
+ </tr>
+ <tr>
+ <td valign="top">sectionsonly</td>
+ <td valign="top">(true | false) don't compute hash of entire manifest</td>
+ <td valign="top" align="center">No; default false</td>
+ </tr>
+ <tr>
+ <td valign="top">lazy</td>
+ <td valign="top">flag to control whether the presence of a signature
+ file means a JAR is signed. This is only used when the target JAR matches
+ the source JAR</td>
+ <td valign="top" align="center">No; default false</td>
+ </tr>
+ <tr>
+ <td valign="top">maxmemory</td>
+ <td valign="top">Specifies the maximum memory the jarsigner VM will use. Specified in the
+ style of standard java memory specs (e.g. 128m = 128 MBytes)</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">preservelastmodified</td>
+ <td valign="top">Give the signed files the same last modified
+ time as the original jar files.</td>
+ <td valign="top" align="center">No; default false.</td>
+ </tr>
+ <tr>
+ <td valign="top">tsaurl</td>
+ <td valign="top">URL for a timestamp authority for timestamped
+ JAR files in Java1.5+</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">tsacert</td>
+ <td valign="top">alias in the keystore for a timestamp authority for
+ timestamped JAR files in Java1.5+</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">tsaproxyhost</td>
+ <td valign="top">proxy host to be used when connecting to TSA server</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">tsaproxyport</td>
+ <td valign="top">proxy port to be used when connecting to TSA server</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">executable</td>
+ <td valign="top">Specify a particular <code>jarsigner</code> executable
+ to use in place of the default binary (found in the same JDK as
+ Apache Ant is running in).<br/>
+ Must support the same command line options as the Sun JDK
+ jarsigner command.
+ <em>since Ant 1.8.0</em>.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">force</td>
+ <td valign="top">Whether to force signing of the jar file even if
+ it doesn't seem to be out of date or already signed.
+ <em>since Ant 1.8.0</em>.</td>
+ <td align="center" valign="top">No; default false</td>
+ </tr>
+ <tr>
+ <td valign="top">sigalg</td>
+ <td valign="top">name of signature algorithm</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">digestalg</td>
+ <td valign="top">name of digest algorithm</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+</table>
+<h3>Parameters as nested elements</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">path</td>
+ <td valign="top">path of JAR files to sign. <em>since Ant 1.7</em></td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">fileset</td>
+ <td valign="top">fileset of JAR files to sign. </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">mapper</td>
+ <td valign="top">A mapper to rename jar files during signing</td>
+ <td valign="top" align="center">No, and only one can be supplied</td>
+ </tr>
+ <tr>
+ <td valign="top">sysproperty</td>
+ <td valign="top">JVM system properties, with the syntax of Ant
+ <a href="exec.html#env">environment variables</a> </td>
+ <td valign="top" align="center">No, and only one can be supplied</td>
+ </tr>
+ </table>
+
+
+<h3>Examples</h3>
+<p>For instructions on generating a code signing certificate, see the <a target="_blank" href="http://docs.oracle.com/javase/7/docs/technotes/tools/windows/keytool.html">keytool documentation</a> and/or instructions from your certificate authority.</p>
+ <blockquote><pre>
+&lt;signjar jar=&quot;${dist}/lib/ant.jar&quot;
+alias=&quot;apache-group&quot; storepass=&quot;secret&quot;/&gt;
+</pre></blockquote>
+<p>
+ signs the ant.jar with alias &quot;apache-group&quot; accessing the
+ keystore and private key via &quot;secret&quot; password.
+</p>
+ <blockquote><pre>
+&lt;signjar destDir="signed"
+ alias="testonly" keystore="testkeystore"
+ storepass="apacheant"
+ preservelastmodified="true"&gt;
+ &lt;path&gt;
+ &lt;fileset dir="dist" includes="**/*.jar" /&gt;
+ &lt;/path&gt;
+ &lt;flattenmapper /&gt;
+&lt;/signjar&gt;
+</pre></blockquote>
+<p>
+Sign all JAR files matching the dist/**/*.jar pattern, copying them to the
+directory "signed" afterwards. The flatten mapper means that they will
+all be copied to this directory, not to subdirectories.
+
+</p>
+ <blockquote><pre>
+&lt;signjar
+ alias="testonly" keystore="testkeystore"
+ storepass="apacheant"
+ lazy="true"
+ &gt;
+ &lt;path&gt;
+ &lt;fileset dir="dist" includes="**/*.jar" /&gt;
+ &lt;/path&gt;
+&lt;/signjar&gt;
+</pre></blockquote>
+<p>
+Sign all the JAR files in dist/**/*.jar <i>in-situ</i>. Lazy signing is used,
+so the files will only be signed if they are not already signed.
+</p>
+ <blockquote><pre>
+&lt;signjar
+ alias="testonly" keystore="testkeystore"
+ storepass="apacheant"
+ sigalg="MD5withRSA"
+ digestalg="SHA1"&gt;
+ &lt;path&gt;
+ &lt;fileset dir="dist" includes="**/*.jar" /&gt;
+ &lt;/path&gt;
+&lt;/signjar&gt;
+</pre></blockquote>
+<p>
+Sign all the JAR files in dist/**/*.jar using the digest algorithm SHA1 and the
+signature algorithm MD5withRSA. This is especially useful when you want to use
+the JDK 7 jarsigner (which uses SHA256 and SHA256withRSA as default) to create
+signed jars that will be deployed on platforms not supporting SHA256 and
+SHA256withRSA.
+</p>
+<h3>About timestamp signing</h3>
+
+<p>Timestamps record the date and time that a signature took place, allowing the signature to be verified as of that point in time.
+With trusted timestamping, users can verify that signing occurred before a certificate's expiration or revocation. Without this timestamp, users can only verify the signature as of their current date.</p>
+
+<p>
+Timestamped JAR files were introduced in Java1.5 and supported in Ant since
+Ant 1.7. Since Ant 1.9.5, Ant can use unauthenticated proxies for this signing process.
+</p>
+
+<p>Common public timestamp authorities include
+ <ul>
+ <li>http://timestamp.verisign.com</li>
+ <li>http://tsa.starfieldtech.com</li>
+ <li>https://timestamp.geotrust.com/tsa</li>
+ <li>Others (see your certificate authority)</li>
+ </ul></p>
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/sleep.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/sleep.html
new file mode 100644
index 00000000..80827b51
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/sleep.html
@@ -0,0 +1,85 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Sleep Task</title>
+</head>
+
+<body>
+
+<h2><a name="sleep">Sleep</a></h2>
+<h3>Description</h3>
+<p> A task for sleeping a short period of time, useful when a build or deployment
+ process requires an interval between tasks.</p>
+
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">hours</td>
+ <td valign="top">hours to to add to the sleep time</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">minutes</td>
+ <td valign="top"> minutes to add to the sleep time</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">seconds</td>
+ <td valign="top">seconds to add to the sleep time</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">milliseconds</td>
+ <td valign="top">milliseconds to add to the sleep time</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">failonerror</td>
+ <td valign="top">flag controlling whether to break the build on an error.
+ </td>
+ <td align="center" valign="top">No</td>
+ </tr>
+</table>
+<p>The sleep time is the sum of specified values, hours, minutes seconds and milliseconds.
+ A negative value can be supplied to any of them provided the total sleep time
+ is positive</p>
+<p>Note that sleep times are always hints to be interpred by the OS how it feels
+ - small times may either be ignored or rounded up to a minimum timeslice. Note
+ also that the system clocks often have a fairly low granularity too, which complicates
+ measuring how long a sleep actually took.</p>
+<h3>Examples</h3>
+<pre> &lt;sleep milliseconds=&quot;10&quot;/&gt;</pre>
+Sleep for about 10 mS.
+<pre> &lt;sleep seconds=&quot;2&quot;/&gt;</pre>
+Sleep for about 2 seconds.
+<pre> &lt;sleep hours=&quot;1&quot; minutes=&quot;-59&quot; seconds=&quot;-58&quot;/&gt;</pre>
+<p>Sleep for one hour less 59:58, or two seconds again </p>
+<pre> &lt;sleep/&gt;</pre>
+Sleep for no time at all. This may yield the CPU time to another thread or process.
+
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/sos.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/sos.html
new file mode 100644
index 00000000..c068263b
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/sos.html
@@ -0,0 +1,503 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+
+ <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
+ <link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>SOS Tasks</title>
+
+</head>
+<body>
+
+<div align="center">
+<h1>SourceOffSite Tasks User Manual</h1>
+
+<div align="left">by
+<ul>
+<li><a href="mailto:jesse@cryptocard.com">Jesse Stockall</a></li>
+</ul>
+Version 1.1 2002/01/23
+<br>
+<br>
+
+<hr width="100%" size="2">
+<h2>Contents</h2>
+
+<ul>
+ <li><a href="#intro">Introduction</a></li>
+ <li><a href="#tasks">The Tasks</a></li>
+
+</ul>
+<br>
+
+<h2><a name="intro">Introduction</a> </h2>
+
+<p>These tasks provide an interface to the <a href="http://msdn.microsoft.com/ssafe/default.asp" target="_top">
+Microsoft Visual SourceSafe</a> SCM via <a href="http://www.sourcegear.com">
+SourceGear's</a> <a href="http://sourcegear.com/sos/index.htm">SourceOffSite</a>
+product. SourceOffSite is an add-on to Microsoft's VSS, that allows remote
+development teams and tele-commuters that need fast and secure read/write
+access to a centralized SourceSafe database via any TCP/IP connection. SOS
+provides Linux ,Solaris &amp; Windows clients. The
+<code> org.apache.tools.ant.taskdefs.optional.sos</code>
+package consists of a simple framework to support SOS functionality as well
+as some Apache Ant tasks encapsulating frequently used SOS commands. Although it
+is possible to use these commands on the desktop, they were primarily intended
+to be used by automated build systems. These tasks have been tested with
+SourceOffSite version 3.5.1 connecting to VisualSourceSafe 6.0. The tasks
+have been tested with Linux, Solaris &amp; Windows2000.</p>
+
+<h2><a name="tasks">The Tasks</a> </h2>
+
+<table border="0" cellspacing="0" cellpadding="3">
+ <tbody>
+ <tr>
+ <td><a href="#SOSGet">sosget</a></td>
+ <td>Retrieves a read-only copy of the specified project or file.</td>
+ </tr>
+ <tr>
+ <td><a href="#SOSLabel">soslabel</a></td>
+ <td>Assigns a label to the specified project.</td>
+ </tr>
+ <tr>
+ <td><a href="#SOSCheckIn">soscheckin</a></td>
+ <td>Updates VSS with changes made to a checked out file or project,
+ and unlocks the VSS master copy.</td>
+ </tr>
+ <tr>
+ <td><a href="#SOSCheckOut">soscheckout</a></td>
+ <td>Retrieves a read-write copy of the specified project
+ or file, locking the&nbsp;VSS master copy</td>
+ </tr>
+
+ </tbody>
+</table>
+ <br>
+
+<hr width="100%" size="2">
+<h2>Task Descriptions</h2>
+
+<h2><a name="SOSGet"></a>SOSGet<br>
+ </h2>
+<h3>Description</h3>
+ Task to perform GET commands with SOS<br>
+<h3>Parameters</h3>
+ </div>
+ </div>
+
+<table border="1">
+ <tbody>
+ <tr>
+ <th>Attribute</th>
+ <th>Values</th>
+ <th>Required</th>
+ </tr>
+ <tr>
+ <td>soscmd</td>
+ <td>Directory which contains soscmd(.exe) <br>
+ soscmd(.exe) must be in the path if this is not specified</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>vssserverpath</td>
+ <td>path to the srcsafe.ini - eg. \\server\vss\srcsafe.ini</td>
+ <td>Yes</td>
+ </tr>
+ <tr>
+ <td>sosserverpath</td>
+ <td>address &amp; port of the SOS server - eg. 192.168.0.1:8888</td>
+ <td>Yes</td>
+ </tr>
+ <tr>
+ <td>projectpath</td>
+ <td>SourceSafe project path - eg. $/SourceRoot/Project1</td>
+ <td>Yes</td>
+ </tr>
+ <tr>
+ <td>file</td>
+ <td>Filename to act upon<br>
+ If no file is specified then act upon the project</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>username</td>
+ <td>SourceSafe username</td>
+ <td>Yes</td>
+ </tr>
+ <tr>
+ <td>password</td>
+ <td>SourceSafe password</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>localpath</td>
+ <td>Override the working directory and get to the specified path</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>soshome</td>
+ <td>The path to the SourceOffSite home directory</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>nocompress</td>
+ <td>true or false - disable compression</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>recursive</td>
+ <td>true or false - Only works with the GetProject command</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>version</td>
+ <td>a version number to get - Only works with the GetFile command</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>label</td>
+ <td>a label version to get - Only works with the GetProject command</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>nocache</td>
+ <td>true or false - Only needed if SOSHOME is set as an environment variable</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>verbose</td>
+ <td>true or false - Status messages are displayed</td>
+ <td>No</td>
+ </tr>
+ </tbody>
+</table>
+
+<h3>Example</h3>
+
+<pre>
+&lt;sosget verbose=&quot;true&quot;
+ recursive=&quot;true&quot;
+ username=&quot;build&quot;
+ password=&quot;build&quot;
+ localpath=&quot;tmp&quot;
+ projectpath=&quot;$/SourceRoot/project1&quot;
+ sosserverpath=&quot;192.168.10.6:8888&quot;
+ vssserverpath=&quot;d:\vss\srcsafe.ini&quot;/&gt;
+</pre>
+<small>Connects to a SourceOffsite server on 192.168.10.6:8888 with
+build,build as the username &amp; password. The SourceSafe database resides
+on the same box as the SOS server &amp; the VSS database is at
+&quot;d:\vss\srcsafe.ini&quot; Does a recursive GetProject on
+$/SourceRoot/project1, using tmp as the working
+directory. </small><br>
+<br>
+
+<hr width="100%" size="2">
+<h2><a name="SOSLabel"></a>SOSLabel</h2>
+
+<h3>Description</h3>
+ Task to perform Label commands with SOS<br>
+<h3>Parameters</h3>
+
+<table border="1">
+ <tbody><tr>
+ <th>Attribute</th>
+ <th>Values</th>
+ <th>Required</th>
+ </tr>
+ <tr>
+ <td>soscmd</td>
+ <td>Directory which contains soscmd(.exe) <br>
+ soscmd(.exe) must be in the path if this is not specified</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>vssserverpath</td>
+ <td>path to the srcsafe.ini - eg. \\server\vss\srcsafe.ini</td>
+ <td>Yes</td>
+ </tr>
+ <tr>
+ <td>sosserverpath</td>
+ <td>address and port of the SOS server - eg. 192.168.0.1:8888</td>
+ <td>Yes</td>
+ </tr>
+ <tr>
+ <td>projectpath</td>
+ <td>SourceSafe project path - eg. $/SourceRoot/Project1</td>
+ <td>Yes</td>
+ </tr>
+ <tr>
+ <td>username</td>
+ <td>SourceSafe username</td>
+ <td>Yes</td>
+ </tr>
+ <tr>
+ <td>password</td>
+ <td>SourceSafe password</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>label</td>
+ <td>The label to apply to a project</td>
+ <td>Yes</td>
+ </tr>
+ <tr>
+ <td>comment</td>
+ <td>A comment to be applied to all files being labeled</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>verbose</td>
+ <td>true or false - Status messages are displayed</td>
+ <td>No</td>
+ </tr>
+ </tbody>
+</table>
+
+<h3>Example</h3>
+<pre>
+&lt;soslabel username=&quot;build&quot;
+ password=&quot;build&quot;
+ label=&quot;test label&quot;
+ projectpath=&quot;$/SourceRoot/project1&quot;
+ sosserverpath=&quot;192.168.10.6:8888&quot;
+ vssserverpath=&quot;d:\vss\srcsafe.ini&quot;/&gt;
+</pre>
+
+<small>Connects to a SourceOffsite server on 192.168.10.6:8888 with
+build,build as the username &amp; password. The SourceSafe database resides
+on the same box as the SOS server &amp; the VSS database is at
+&quot;d:\vss\srcsafe.ini&quot;. Labels the $/SourceRoot/project1
+project with &quot;test label&quot;.</small><br>
+<br>
+
+<hr width="100%" size="2"><br>
+
+<h2><a name="SOSCheckIn"></a>SOSCheckIn</h2>
+
+<h3>Description</h3>
+ Task to perform CheckIn commands with SOS<br>
+<h3>Parameters</h3>
+<table border="1">
+ <tbody>
+ <tr>
+ <th>Attribute</th>
+ <th>Values</th>
+ <th>Required</th>
+ </tr>
+ <tr>
+ <td>soscmd</td>
+ <td>Directory which contains soscmd(.exe) <br>
+ soscmd(.exe) must be in the path if this is not specified</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>vssserverpath</td>
+ <td>path to the srcsafe.ini - eg. \\server\vss\srcsafe.ini</td>
+ <td>Yes</td>
+ </tr>
+ <tr>
+ <td>sosserverpath</td>
+ <td>address and port of the SOS server - eg. 192.168.0.1:8888</td>
+ <td>Yes</td>
+ </tr>
+ <tr>
+ <td>projectpath</td>
+ <td>SourceSafe project path - eg. $/SourceRoot/Project1</td>
+ <td>Yes</td>
+ </tr>
+ <tr>
+ <td>file</td>
+ <td>Filename to act upon<br> If no file is specified then act upon the project</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>username</td>
+ <td>SourceSafe username</td>
+ <td>Yes</td>
+ </tr>
+ <tr>
+ <td>password</td>
+ <td>SourceSafe password</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>localpath</td>
+ <td>Override the working directory and get to the specified path</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>soshome</td>
+ <td>The path to the SourceOffSite home directory</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>nocompress</td>
+ <td>true or false - disable compression</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>recursive</td>
+ <td>true or false - Only works with the CheckOutProject command</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>nocache</td>
+ <td>true or false - Only needed if SOSHOME is set as an environment variable</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>verbose</td>
+ <td>true or false - Status messages are displayed</td>
+ <td>No</td>
+ </tr>
+ <tr><td>comment</td>
+ <td>A comment to be applied to all files being checked in</td>
+ <td>No</td>
+ </tr>
+ </tbody>
+</table>
+
+<h3>Example</h3>
+<pre>
+&lt;soscheckin username=&quot;build&quot;
+ password=&quot;build&quot;
+ file=&quot;foobar.txt&quot;
+ verbose=&quot;true&quot;
+ comment=&quot;comment abc&quot;
+ projectpath=&quot;$/SourceRoot/project1&quot;
+ sosserverpath=&quot;server1:8888&quot;
+ vssserverpath=&quot;\\server2\vss\srcsafe.ini&quot;/&gt;
+</pre>
+
+<small>Connects to a SourceOffsite server on server1:8888 with build,build as
+the username &amp; password. The SourceSafe database resides on a different
+box (server2) &amp; the VSS database is on a share called
+&quot;vss&quot;. Checks-in only the &quot;foobar.txt&quot; file adding
+a comment of &quot;comment abc&quot;. Extra status messages will be
+displayed on screen.</small><br>
+<br>
+
+<hr width="100%" size="2">
+<h2><a name="SOSCheckOut"></a>SOSCheckOut</h2>
+
+<h3>Description</h3>
+ Task to perform CheckOut commands with SOS<br>
+
+<h3>Parameters</h3>
+
+<table border="1">
+ <tbody>
+ <tr>
+ <th>Attribute</th>
+ <th>Values</th>
+ <th>Required</th>
+ </tr>
+ <tr>
+ <td>soscmd</td>
+ <td>Directory which contains soscmd(.exe) <br>
+ soscmd(.exe) must be in the path if this is not specified</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>vssserverpath</td>
+ <td>path to the srcsafe.ini - eg. \\server\vss\srcsafe.ini</td>
+ <td>Yes</td>
+ </tr>
+ <tr>
+ <td>sosserverpath</td>
+ <td>address and port of the SOS server - eg. 192.168.0.1:8888</td>
+ <td>Yes</td>
+ </tr>
+ <tr>
+ <td>projectpath</td>
+ <td>SourceSafe project path - eg. $/SourceRoot/Project1</td>
+ <td>Yes</td>
+ </tr>
+ <tr>
+ <td>file</td>
+ <td>Filename to act upon<br> If no file is specified then act upon the project</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>username</td>
+ <td>SourceSafe username</td>
+ <td>Yes</td>
+ </tr>
+ <tr>
+ <td>password</td>
+ <td>SourceSafe password</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>localpath</td>
+ <td>Override the working directory and get to the specified path</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>soshome</td>
+ <td>The path to the SourceOffSite home directory</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>nocompress</td>
+ <td>true or false - disable compression</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>recursive</td>
+ <td>true or false - Only works with the CheckOutProject command</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>nocache</td>
+ <td>true or false - Only needed if SOSHOME is set as an environment variable</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>verbose</td>
+ <td>true or false - Status messages are displayed</td>
+ <td>No</td>
+ </tr>
+ </tbody>
+</table>
+ <br>
+
+<h3>Example</h3>
+<pre>
+&lt;soscheckout soscmd=&quot;/usr/local/bin&quot;
+ verbose=&quot;true&quot;
+ username=&quot;build&quot;
+ password=&quot;build&quot;
+ projectpath=&quot;$/SourceRoot/project1&quot;
+ sosserverpath=&quot;192.168.10.6:8888&quot;
+ vssserverpath=&quot;\\server2\vss\srcsafe.ini&quot;/&gt;
+</pre>
+
+<small>Connects to a SourceOffsite server on server1:8888 with build,build as
+the username &amp; password. The SourceSafe database resides on a different
+box (server2) &amp; the VSS database is on a share called
+&quot;vss&quot;. Checks-out &quot;project1&quot;, Only the
+&quot;project1&quot; directory will be locked as the recursive option
+was not set. Extra status messages will be displayed on screen. The
+soscmd(.exe) file to be used resides in /usr/local/bin.</small><br>
+<br>
+
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/sound.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/sound.html
new file mode 100644
index 00000000..1095f80c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/sound.html
@@ -0,0 +1,123 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Sound Task</title>
+</head>
+
+<body>
+
+<h2><a name="sound">Sound</a></h2>
+<h3>Description</h3>
+<p>Plays a sound-file at the end of the build, according to whether
+the build failed or succeeded. You can specify either a specific
+sound-file to play, or, if a directory is specified, the
+<code>&lt;sound&gt;</code> task will randomly select a file to play.
+Note: At this point, the random selection is based on all the files
+in the directory, not just those ending in appropriate suffixes
+for sound-files, so be sure you only have sound-files in the
+directory you specify.</p>
+<p>More precisely <code>&lt;sound&gt;</code> registers a hook that is
+triggered when the build finishes. Therefore you have to place this
+task as top level or inside a target which is always executed.</p>
+<p>
+Unless you are running on Java 1.3 or later, you need the Java Media Framework
+on the classpath (javax.sound).
+</p>
+
+
+<h3>Nested Elements</h3>
+<h4>success</h4>
+<p>Specifies the sound to be played if the build succeeded.</p>
+<h4>fail</h4>
+<p>Specifies the sound to be played if the build failed.</p>
+
+<h3>Nested Element Parameters</h3>
+<p>
+The following attributes may be used on the <code>&lt;success&gt;</code>
+and <code>&lt;fail&gt;</code> elements:</p>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">source</td>
+ <td valign="top">the path to a sound-file directory, or the name of a
+specific sound-file, to be played. If this file does not exist, an error message
+will be logged.
+ </td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">loops</td>
+ <td valign="top">the number of extra times to play the sound-file;
+ default is <code>0</code>.
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">duration</td>
+ <td valign="top">the amount of time (in milliseconds) to play
+ the sound-file.
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+</table>
+
+<h3>Examples</h3>
+<blockquote>
+<pre>
+&lt;target name=&quot;fun&quot; if=&quot;fun&quot; unless=&quot;fun.done&quot;&gt;
+ &lt;sound&gt;
+ &lt;success source=&quot;${user.home}/sounds/bell.wav&quot;/&gt;
+ &lt;fail source=&quot;${user.home}/sounds/ohno.wav&quot; loops=&quot;2&quot;/&gt;
+ &lt;/sound&gt;
+ &lt;property name=&quot;fun.done&quot; value=&quot;true&quot;/&gt;
+&lt;/target&gt;
+</pre>
+</blockquote>
+plays the <code>bell.wav</code> sound-file if the build succeeded, or
+the <code>ohno.wav</code> sound-file if the build failed, three times,
+if the <code>fun</code> property is set to <code>true</code>.
+If the target
+is a dependency of an &quot;initialization&quot; target that other
+targets depend on, the
+<code>fun.done</code> property prevents the target from being executed
+more than once.
+<blockquote>
+<pre>
+&lt;target name=&quot;fun&quot; if=&quot;fun&quot; unless=&quot;fun.done&quot;&gt;
+ &lt;sound&gt;
+ &lt;success source=&quot;//intranet/sounds/success&quot;/&gt;
+ &lt;fail source=&quot;//intranet/sounds/failure&quot;/&gt;
+ &lt;/sound&gt;
+ &lt;property name=&quot;fun.done&quot; value=&quot;true&quot;/&gt;
+&lt;/target&gt;
+</pre>
+</blockquote>
+randomly selects a sound-file to play when the build succeeds or fails.
+
+
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/splash.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/splash.html
new file mode 100644
index 00000000..e158bd29
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/splash.html
@@ -0,0 +1,154 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Apache Ant User Manual</title>
+</head>
+
+<body>
+
+<h2><a name="Splash">Splash</a></h2>
+<p>by Les Hughes (leslie.hughes@rubus.com)
+<h3>Description</h3>
+<p>This task creates a splash screen. The splash screen is displayed
+for the duration of the build and includes a handy progress bar as
+well. Use in conjunction with the sound task to provide interest
+whilst waiting for your builds to complete...</p>
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ <td align="center" valign="top"><b>Default</b></td>
+ </tr>
+ <tr>
+ <td valign="top">imageurl</td>
+ <td valign="top">A URL pointing to an image to display.</td>
+ <td valign="top" align="center">No</td>
+ <td valign="top" align="center">antlogo.gif from the classpath</td>
+ </tr>
+
+ <tr>
+ <td valign="top">showduration</td>
+ <td valign="top">Initial period to pause the build to show the
+ splash in milliseconds.</td>
+ <td valign="top" align="center">No</td>
+ <td valign="top" align="center">5000 ms</td>
+ </tr>
+ <tr>
+ <td valign="top">progressregexp</td>
+ <td valign="top">Progress regular expression which is used to
+ parse the output and dig out current progress. Exactly one group
+ pattern must exists, and it represents the progress number (0-100)
+ (i.e "Progress: (.*)%")<br/>
+ <em>since Apache Ant 1.8.0</em></td>
+ <td valign="top" align="center">No</td>
+ <td valign="top" align="center">progress is increased every action
+ and log output line</td>
+ </tr>
+ <tr>
+ <td valign="top">displaytext</td>
+ <td valign="top">display text presented in the splash window<br/>
+ <em>since Ant 1.8.0</em></td>
+ <td valign="top" align="center">No</td>
+ <td valign="top" align="center">Building ...</td>
+ </tr>
+</table>
+<h3>Deprecated properties</h3>
+
+The following properties can be used to configure the proxy settings to retrieve
+an image from behind a firewall. However, the settings apply not just to this
+task, but to all following tasks. Therefore they are now deprecated in
+preference to the <code>&lt;setproxy&gt;</code> task, that makes it clear to readers of
+the build exactly what is going on.
+
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top">useproxy</td>
+ <td valign="top">Use a proxy to access imgurl. Note: Only tested
+ on JDK 1.2.2 and above</td>
+ <td valign="top" align="center">No</td>
+ <td valign="top" align="center">None</td>
+ </tr>
+ <tr>
+ <td valign="top">proxy</td>
+ <td valign="top">IP or hostname of the proxy server</td>
+ <td valign="top" align="center">No</td>
+ <td valign="top" align="center">None</td>
+ </tr>
+ <tr>
+ <td valign="top">port</td>
+ <td valign="top">Proxy portnumber</td>
+ <td valign="top" align="center">No</td>
+ <td valign="top" align="center">None</td>
+ </tr>
+ <tr>
+ <td valign="top">user</td>
+ <td valign="top">User to authenticate to the proxy as.</td>
+ <td valign="top" align="center">No</td>
+ <td valign="top" align="center">None</td>
+
+ </tr>
+ <tr>
+ <td valign="top">password</td>
+ <td valign="top">Proxy password</td>
+ <td valign="top" align="center">No</td>
+ <td valign="top" align="center">None</td>
+ </tr>
+
+</table>
+<h3>Examples</h3>
+<blockquote><pre>
+&lt;splash/&gt;
+</pre></blockquote>
+<p>Splash <code>images/ant_logo_large.gif</code> from the classpath.</p>
+<blockquote><pre>
+&lt;splash imageurl=&quot;http://jakarta.apache.org/images/jakarta-logo.gif&quot;
+ useproxy=&quot;true&quot;
+ showduration=&quot;5000&quot;/&gt;
+
+</pre></blockquote>
+<p>Splashes the jakarta logo, for an initial period of 5 seconds.</p>
+
+<p>Splash with controlled progress and nondefault text</p>
+<blockquote><pre>
+ &lt;target name="test_new_features"&gt;
+ &lt;echo&gt;New features&lt;/echo&gt;
+ &lt;splash progressRegExp="Progress: (.*)%" showduration="0" displayText="Test text"/&gt;
+ &lt;sleep seconds="1"/&gt;
+ &lt;echo&gt;Progress: 10%&lt;/echo&gt;
+ &lt;sleep seconds="1"/&gt;
+ &lt;echo&gt;Progress: 20%&lt;/echo&gt;
+ &lt;sleep seconds="1"/&gt;
+ &lt;echo&gt;Progress: 50%&lt;/echo&gt;
+ &lt;sleep seconds="1"/&gt;
+ &lt;echo&gt;Progress: 70%&lt;/echo&gt;
+ &lt;sleep seconds="1"/&gt;
+ &lt;echo&gt;Progress: 100%&lt;/echo&gt;
+ &lt;sleep seconds="3"/&gt;
+ &lt;/target&gt;
+</pre></blockquote>
+
+
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/sql.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/sql.html
new file mode 100644
index 00000000..e5f4db83
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/sql.html
@@ -0,0 +1,511 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>SQL Task</title>
+</head>
+<body>
+
+<h2><a name="sql">Sql</a></h2>
+<h3>Description</h3>
+<p>Executes a series of SQL statements via JDBC to a database. Statements can
+either be read in from a text file using the <i>src</i> attribute or from
+between the enclosing SQL tags.</p>
+
+<p>Multiple statements can be provided, separated by semicolons (or the
+defined <i>delimiter</i>). Individual lines within the statements can be
+commented using either --, // or REM at the start of the line.</p>
+
+<p>The <i>autocommit</i> attribute specifies whether auto-commit should be
+turned on or off whilst executing the statements. If auto-commit is turned
+on each statement will be executed and committed. If it is turned off the
+statements will all be executed as one transaction.</p>
+
+<p>The <i>onerror</i> attribute specifies how to proceed when an error occurs
+during the execution of one of the statements.
+The possible values are: <b>continue</b> execution, only show the error;
+<b>stop</b> execution, log the error but don't fail the task
+and <b>abort</b> execution and transaction and fail task.</p>
+
+<p>
+<b>Proxies</b>. Some JDBC drivers (including the Oracle thin driver),
+ use the JVM's proxy settings to route their JDBC operations to the database.
+ Since Apache Ant1.7, Ant running on Java1.5 or later defaults to
+ <a href="../proxy.html">using
+ the proxy settings of the operating system</a>.
+ Accordingly, the OS proxy settings need to be valid, or Ant's proxy
+ support disabled with <code>-noproxy</code> option.
+</p>
+
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+<tr>
+ <td width="12%" valign="top"><b>Attribute</b></td>
+ <td width="78%" valign="top"><b>Description</b></td>
+ <td width="10%" valign="top"><b>Required</b></td>
+</tr>
+<tr>
+ <td width="12%" valign="top">driver</td>
+ <td width="78%" valign="top">Class name of the jdbc driver</td>
+ <td width="10%" valign="top">Yes</td>
+</tr>
+<tr>
+ <td width="12%" valign="top">url</td>
+ <td width="78%" valign="top">Database connection url</td>
+ <td width="10%" valign="top">Yes</td>
+</tr>
+<tr>
+ <td width="12%" valign="top">userid</td>
+ <td width="78%" valign="top">Database user name</td>
+ <td width="10%" valign="top">Yes</td>
+</tr>
+<tr>
+ <td width="12%" valign="top">password</td>
+ <td width="78%" valign="top">Database password</td>
+ <td width="10%" valign="top">Yes</td>
+</tr>
+<tr>
+ <td width="12%" valign="top">src</td>
+ <td width="78%" valign="top">File containing SQL statements</td>
+ <td width="10%" valign="top">Yes, unless statements enclosed within tags</td>
+</tr>
+<tr>
+ <td valign="top">encoding</td>
+ <td valign="top">The encoding of the files containing SQL statements</td>
+ <td align="center">No - defaults to default JVM encoding</td>
+</tr>
+<tr>
+ <td valign="top">outputencoding</td>
+ <td valign="top">The encoding of the files holding
+ results. <em>since 1.9.4</em</td>
+ <td align="center">No - defaults to default JVM encoding</td>
+</tr>
+<tr>
+ <td width="12%" valign="top">delimiter</td>
+ <td width="78%" valign="top">String that separates SQL statements</td>
+ <td width="10%" valign="top">No, default &quot;;&quot;</td>
+</tr>
+<tr>
+ <td width="12%" valign="top">autocommit</td>
+ <td width="78%" valign="top">Auto commit flag for database connection (default false)</td>
+ <td width="10%" valign="top">No, default &quot;false&quot;</td>
+</tr>
+<tr>
+ <td width="12%" valign="top">print</td>
+ <td width="78%" valign="top">Print result sets from the statements (default false)</td>
+ <td width="10%" valign="top">No, default &quot;false&quot;</td>
+</tr>
+<tr>
+ <td width="12%" valign="top">showheaders</td>
+ <td width="78%" valign="top">Print headers for result sets from the statements (default true)</td>
+ <td width="10%" valign="top">No, default &quot;true&quot;</td>
+</tr>
+<tr>
+ <td width="12%" valign="top">showtrailers</td>
+ <td width="78%" valign="top">Print trailer for number of rows affected (default true)</td>
+ <td width="10%" valign="top">No, default &quot;true&quot;</td>
+</tr>
+<tr>
+ <td width="12%" valign="top">output</td>
+ <td width="78%" valign="top">Output file for result sets (defaults to System.out)
+ <b>Since Ant 1.8</b> can specify any Resource that supports output (see
+ <a href="../develop.html#set-magic">note</a>).
+ </td>
+ <td width="10%" valign="top">No (print to System.out by default)</td>
+</tr>
+ <tr>
+ <td valign="top">append</td>
+ <td valign="top">whether output should be appended to or overwrite
+ an existing file. Defaults to false.</td>
+ <td align="center" valign="top">No, ignored if <i>output</i> does not
+ specify a filesystem destination.</td>
+ </tr>
+<tr>
+ <td width="12%" valign="top">classpath</td>
+ <td width="78%" valign="top">Classpath used to load driver</td>
+ <td width="10%" valign="top">No (use system classpath)</td>
+</tr>
+ <tr>
+ <td width="12%" valign="top">classpathref</td>
+ <td width="78%" valign="top">The classpath to use, given as a <a href="../using.html#references">reference</a> to a path defined elsewhere.</td>
+ <td width="10%" valign="top">No (use system classpath)</td>
+ </tr>
+<tr>
+ <td width="12%" valign="top">onerror</td>
+ <td width="78%" valign="top">Action to perform when statement fails: continue, stop, abort</td>
+ <td width="10%" valign="top">No, default &quot;abort&quot;</td>
+</tr>
+<tr>
+ <td width="12%" valign="top">rdbms</td>
+ <td width="78%" valign="top">Execute task only if this rdbms</td>
+ <td width="10%" valign="top">No (no restriction)</td>
+</tr>
+<tr>
+ <td width="12%" valign="top">version</td>
+ <td width="78%" valign="top">Execute task only if rdbms version match</td>
+ <td width="10%" valign="top">No (no restriction)</td>
+</tr>
+<tr>
+ <td width="12%" valign="top">caching</td>
+ <td width="78%" valign="top">Should the task cache loaders and the driver?</td>
+ <td width="10%" valign="top">No (default=true)</td>
+</tr>
+
+<tr>
+ <td width="12%" valign="top">delimitertype</td>
+ <td width="78%" valign="top">Control whether the delimiter will only be recognized on a line by itself.<br>
+ Can be "normal" -anywhere on the line, or "row", meaning it must be on a line by itself</td>
+ <td width="10%" valign="top">No (default:normal)</td>
+</tr>
+
+<tr>
+ <td width="12%" valign="top">keepformat</td>
+ <td width="78%" valign="top">Control whether the format of the sql will be preserved.<br>
+ Useful when loading packages and procedures.
+ <td width="10%" valign="top">No (default=false)</td>
+</tr>
+
+<tr>
+ <td width="12%" valign="top">escapeprocessing</td>
+ <td width="78%" valign="top">Control whether the Java statement
+ object will perform escape substitution.<br>
+ See <a
+ href="http://docs.oracle.com/javase/7/docs/api/java/sql/Statement.html#setEscapeProcessing%28boolean%29">Statement's
+ API docs</a> for details. <em>Since Ant 1.6</em>.
+ <td width="10%" valign="top">No (default=true)</td>
+</tr>
+
+<tr>
+ <td width="12%" valign="top">expandproperties</td>
+ <td width="78%" valign="top">Set to true to turn on property expansion in
+ nested SQL, inline in the task or nested transactions. <em>Since Ant 1.7</em>.
+ <td width="10%" valign="top">No (default=true)</td>
+</tr>
+
+<tr>
+ <td width="12%" valign="top">rawblobs</td>
+ <td width="78%" valign="top">If true, will write raw streams rather than hex encoding when
+ printing BLOB results. <em>Since Ant 1.7.1</em>.</td>
+ <td width="10%" valign="top">No, default <em>false</em></td>
+</tr>
+
+<tr>
+ <td width="12%" valign="top">failOnConnectionError</td>
+ <td width="78%" valign="top">If false, will only print a warning
+ message and not execute any statement if the task fails to connect
+ to the database. <em>Since Ant 1.8.0</em>.</td>
+ <td width="10%" valign="top">No, default <em>true</em></td>
+</tr>
+
+<tr>
+ <td width="12%" valign="top">strictDelimiterMatching</td>
+ <td width="78%" valign="top">If false, delimiters will be searched
+ for in a case-insensitive manner (i.e. delimiter="go" matches "GO")
+ and surrounding whitespace will be ignored (delimiter="go" matches
+ "GO "). <em>Since Ant 1.8.0</em>.</td>
+ <td width="10%" valign="top">No, default <em>true</em></td>
+</tr>
+
+<tr>
+ <td width="12%" valign="top">showWarnings</td>
+ <td width="78%" valign="top">If true, SQLWarnings will be logged at
+ the WARN level. <em>Since Ant 1.8.0</em>.<br/>
+ <b>Note:</b> even if the attribute is set to false, warnings that
+ apply to the connection will be logged at the verbose level.</td>
+ <td width="10%" valign="top">No, default <em>false</em></td>
+</tr>
+
+<tr>
+ <td width="12%" valign="top">treatWarningsAsErrors</td>
+ <td width="78%" valign="top">If true, SQLWarnings will be treated
+ like errors - and the logic selected via the onError attribute
+ applies.
+ <em>Since Ant 1.8.0</em>.</td>
+ <td width="10%" valign="top">No, default <em>false</em></td>
+</tr>
+
+<tr>
+ <td width="12%" valign="top">csvColumnSeparator</td>
+ <td width="78%" valign="top">The column separator used when printing
+ the results.
+ <em>Since Ant 1.8.0</em>.</td>
+ <td width="10%" valign="top">No, default <em>','</em></td>
+</tr>
+
+<tr>
+ <td width="12%" valign="top">csvQuoteCharacter</td>
+ <td width="78%" valign="top">The character used to quote column
+ values.<br/>
+ If set, columns that contain either the column separator or the
+ quote character itself will be surrounded by the quote character.
+ The quote character itself will be doubled if it appears inside of
+ the column's value.<br/>
+ <b>Note:</b> BLOB values will never be quoted.
+ <em>Since Ant 1.8.0</em>.</td>
+ <td width="10%" valign="top">No, default is not set (i.e. no quoting
+ ever occurs)</td>
+</tr>
+
+<tr>
+ <td valign="top">errorproperty</td>
+ <td valign="top">The name of a property to set in the event of an
+ error. <em>Since Ant 1.8.0</em></td>
+ <td align="center" valign="top">No</td>
+</tr>
+<tr>
+ <td valign="top">warningproperty</td>
+ <td valign="top">The name of a property to set in the event of an
+ warning. <em>Since Ant 1.8.0</em></td>
+ <td align="center" valign="top">No</td>
+</tr>
+<tr>
+ <td valign="top">rowcountproperty</td>
+ <td valign="top">The name of a property to set to the number of rows
+ updated by the first statement/transaction that actually returned
+ a row count. <em>Since Ant 1.8.0</em></td>
+ <td align="center" valign="top">No</td>
+</tr>
+</table>
+
+<h3>Parameters specified as nested elements</h3>
+<h4>transaction</h4>
+<p>Use nested <code>&lt;transaction&gt;</code>
+elements to specify multiple blocks of commands to the executed
+executed in the same connection but different transactions. This
+is particularly useful when there are multiple files to execute
+on the same schema.</p>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">src</td>
+ <td valign="top">File containing SQL statements</td>
+ <td valign="top" align="center">Yes, unless statements enclosed within tags</td>
+ </tr>
+</table>
+<p>The <code>&lt;transaction&gt;</code> element supports any <a
+href="../Types/resources.html">resource</a> or single element
+resource collection as nested element to specify the resource
+containing the SQL statements.</p>
+
+<h4>any <a href="../Types/resources.html">resource</a> or resource
+collection</h4>
+
+<p>You can specify multiple sources via nested resource collection
+elements. Each resource of the collection will be run in a
+transaction of its own. Prior to Ant 1.7 only filesets were
+supported. Use a sort resource collection to get a predictable order
+of transactions. </p>
+
+<h4>classpath</h4>
+<p><code>Sql</code>'s <em>classpath</em> attribute is a <a
+href="../using.html#path">PATH like structure</a> and can also be set via a nested
+<em>classpath</em> element. It is used to load the JDBC classes.</p>
+
+<h4>connectionProperty</h4>
+<p><em>Since Ant 1.8.0</em></p>
+<p>Use nested <code>&lt;connectionProperty&gt;</code> elements to
+ specify additional JDBC properties that need to be set when
+ connecting to the database.</p>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">name</td>
+ <td valign="top">Name of the property</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">value</td>
+ <td valign="top">Value of the property</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+</table>
+
+<h3>Examples</h3>
+<blockquote><pre>&lt;sql
+ driver=&quot;org.database.jdbcDriver&quot;
+ url=&quot;jdbc:database-url&quot;
+ userid=&quot;sa&quot;
+ password=&quot;pass&quot;
+ src=&quot;data.sql&quot;
+/&gt;
+</pre></blockquote>
+
+<p>Connects to the database given in <i>url</i> as the sa user using the
+org.database.jdbcDriver and executes the SQL statements contained within
+the file data.sql</p>
+
+<blockquote><pre>&lt;sql
+ driver=&quot;org.database.jdbcDriver&quot;
+ url=&quot;jdbc:database-url&quot;
+ userid=&quot;sa&quot;
+ password=&quot;pass&quot;
+ src=&quot;data.sql&quot;&gt;
+ &lt;connectionProperty name=&quot;internal_logon&quot; value=&quot;SYSDBA&quot;&gt;
+&lt;/sql&gt;
+</pre></blockquote>
+
+<p>Connects to the database given in <i>url</i> as the sa user using
+the org.database.jdbcDriver and executes the SQL statements contained
+within the file data.sql. Also sets the
+property <i>internal_logon</i> to the value <i>SYSDBA</i>.</p>
+
+<blockquote><pre>&lt;sql
+ driver=&quot;org.database.jdbcDriver&quot;
+ url=&quot;jdbc:database-url&quot;
+ userid=&quot;sa&quot;
+ password=&quot;pass&quot;
+ &gt;
+insert
+into table some_table
+values(1,2,3,4);
+
+truncate table some_other_table;
+&lt;/sql&gt;
+</pre></blockquote>
+
+<p>Connects to the database given in <i>url</i> as the sa
+ user using the org.database.jdbcDriver and executes the two SQL statements
+ inserting data into some_table and truncating some_other_table. Ant Properties
+ in the nested text will not be expanded.</p>
+
+<p>Note that you may want to enclose your statements in
+<code>&lt;![CDATA[</code> ... <code>]]&gt;</code> sections so you don't
+need to escape <code>&lt;</code>, <code>&gt;</code> <code>&amp;</code>
+or other special characters. For example:</p>
+
+<blockquote><pre>&lt;sql
+ driver=&quot;org.database.jdbcDriver&quot;
+ url=&quot;jdbc:database-url&quot;
+ userid=&quot;sa&quot;
+ password=&quot;pass&quot;
+ &gt;&lt;![CDATA[
+
+update some_table set column1 = column1 + 1 where column2 &lt; 42;
+
+]]&gt;&lt;/sql&gt;
+</pre></blockquote>
+
+The following command turns property expansion in nested text on (it is off purely for backwards
+compatibility), then creates a new user in the HSQLDB database using Ant properties.
+
+<blockquote><pre>&lt;sql
+ driver="org.hsqldb.jdbcDriver";
+ url="jdbc:hsqldb:file:${database.dir}"
+ userid="sa"
+ password=""
+ expandProperties="true"
+ &gt;
+ &lt;transaction&gt;
+ CREATE USER ${newuser} PASSWORD ${newpassword}
+ &lt;/transaction&gt;
+&lt;/sql&gt;
+</pre></blockquote>
+
+
+<p>The following connects to the database given in url as the sa user using
+the org.database.jdbcDriver and executes the SQL statements contained within
+the files data1.sql, data2.sql and data3.sql and then executes the truncate
+operation on <i>some_other_table</i>.</p>
+
+<blockquote><pre>&lt;sql
+ driver=&quot;org.database.jdbcDriver&quot;
+ url=&quot;jdbc:database-url&quot;
+ userid=&quot;sa&quot;
+ password=&quot;pass&quot; &gt;
+ &lt;transaction src=&quot;data1.sql&quot;/&gt;
+ &lt;transaction src=&quot;data2.sql&quot;/&gt;
+ &lt;transaction src=&quot;data3.sql&quot;/&gt;
+ &lt;transaction&gt;
+ truncate table some_other_table;
+ &lt;/transaction&gt;
+&lt;/sql&gt;
+</pre></blockquote>
+
+<p>The following example does the same as (and may execute additional
+SQL files if there are more files matching the pattern
+<code>data*.sql</code>) but doesn't guarantee that data1.sql will be
+run before <code>data2.sql</code>.</p>
+
+<blockquote><pre>&lt;sql
+ driver=&quot;org.database.jdbcDriver&quot;
+ url=&quot;jdbc:database-url&quot;
+ userid=&quot;sa&quot;
+ password=&quot;pass&quot;&gt;
+ &lt;path&gt;
+ &lt;fileset dir=&quot;.&quot;&gt;
+ &lt;include name=&quot;data*.sql&quot;/&gt;
+ &lt;/fileset&gt;
+ &lt;/path&gt;
+ &lt;transaction&gt;
+ truncate table some_other_table;
+ &lt;/transaction&gt;
+&lt;/sql&gt;
+</pre></blockquote>
+
+<p>The following connects to the database given in url as the sa user using the
+org.database.jdbcDriver and executes the SQL statements contained within the
+file data.sql, with output piped to outputfile.txt, searching /some/jdbc.jar
+as well as the system classpath for the driver class.</p>
+
+<blockquote><pre>&lt;sql
+ driver=&quot;org.database.jdbcDriver&quot;
+ url=&quot;jdbc:database-url&quot;
+ userid=&quot;sa&quot;
+ password=&quot;pass&quot;
+ src=&quot;data.sql&quot;
+ print=&quot;yes&quot;
+ output=&quot;outputfile.txt&quot;
+ &gt;
+&lt;classpath&gt;
+ &lt;pathelement location=&quot;/some/jdbc.jar&quot;/&gt;
+&lt;/classpath&gt;
+&lt;/sql&gt;
+</pre></blockquote>
+
+<p>The following will only execute if the RDBMS is &quot;oracle&quot; and the version
+starts with &quot;8.1.&quot;</p>
+
+<blockquote><pre>&lt;sql
+ driver=&quot;org.database.jdbcDriver&quot;
+ url=&quot;jdbc:database-url&quot;
+ userid=&quot;sa&quot;
+ password=&quot;pass&quot;
+ src=&quot;data.sql&quot;
+ rdbms=&quot;oracle&quot;
+ version=&quot;8.1.&quot;
+ &gt;
+insert
+into table some_table
+values(1,2,3,4);
+
+truncate table some_other_table;
+&lt;/sql&gt;
+</pre></blockquote>
+
+
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/sshexec.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/sshexec.html
new file mode 100644
index 00000000..2aab2a6b
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/sshexec.html
@@ -0,0 +1,291 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>SSHEXEC Task</title>
+</head>
+
+<body>
+
+<h2><a name="sshexec">SSHEXEC</a></h2>
+<h3>Description</h3>
+
+<p><em>since Apache Ant 1.6</em></p>
+
+<p>Runs a command on a remote machine running SSH daemon.
+</p>
+
+<p><b>Note:</b> This task depends on external libraries not included
+in the Ant distribution. See <a
+href="../install.html#librarydependencies">Library Dependencies</a>
+for more information. This task has been tested with jsch-0.1.29 and above
+and won't work with versions of jsch earlier than
+0.1.28.</p>
+
+<p>See also the <a href="scp.html">scp task</a></p>
+
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">host</td>
+ <td valign="top">The hostname or IP address of the remote host to which you wish to connect.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">username</td>
+ <td valign="top">The username on the remote host to which you are connecting.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">command</td>
+ <td valign="top">The command to run on the remote host.</td>
+ <td valian="top" align="center">Either this or commandResource must be set</td>
+ </tr>
+ <tr>
+ <td valign="top">commandResource</td>
+ <td valign="top">The resource (file) that contains the commands to run on the remote host.
+ Since Ant 1.7.1</td>
+ <td valian="top" align="center">Either this or command must be set</td>
+ </tr>
+ <tr>
+ <td valign="top">port</td>
+ <td valign="top">The port to connect to on the remote host.</td>
+ <td valian="top" align="center">No, defaults to 22.</td>
+ </tr>
+ <tr>
+ <td valign="top">trust</td>
+
+ <td valign="top">This trusts all unknown hosts if set to yes/true.<br>
+ <strong>Note</strong> If you set this to false (the default), the
+ host you connect to must be listed in your knownhosts file, this
+ also implies that the file exists.</td>
+ <td valian="top" align="center">No, defaults to No.</td>
+ </tr>
+ <tr>
+ <td valign="top">knownhosts</td>
+ <td valign="top">This sets the known hosts file to use to validate
+ the identity of the remote host. This must be a SSH2 format file.
+ SSH1 format is not supported.</td>
+ <td valian="top" align="center">No, defaults to
+ ${user.home}/.ssh/known_hosts.</td>
+ </tr>
+ <tr>
+ <td valign="top">failonerror</td>
+ <td valign="top">Whether to halt the build if the command does not complete successfully.
+ </td>
+ <td valign="top" align="center">No; defaults to true.</td>
+ </tr>
+ <tr>
+ <td valign="top">password</td>
+ <td valign="top">The password.</td>
+ <td valign="top" align="center">Not if you are using key based
+ authentication or the password has been given in the file or
+ todir attribute.</td>
+ </tr>
+ <tr>
+ <td valign="top">keyfile</td>
+ <td valign="top">Location of the file holding the private key.</td>
+ <td valign="top" align="center">Yes, if you are using key based
+ authentication.</td>
+ </tr>
+ <tr>
+ <td valign="top">passphrase</td>
+ <td valign="top">Passphrase for your private key.</td>
+ <td valign="top" align="center">No, defaults to an empty string.</td>
+ </tr>
+ <tr>
+ <td valign="top">suppresssystemout</td>
+ <td valign="top">Whether to suppress system out.
+ <em>since Ant 1.9.0</em></td>
+ <td align="center" valign="top">No, defaults to false</td>
+ </tr>
+ <tr>
+ <td valign="top">suppresssystemerr</td>
+ <td valign="top">Whether to suppress system err.
+ <em>since Ant 1.9.4</em></td>
+ <td align="center" valign="top">No, defaults to false</td>
+ </tr>
+ <tr>
+ <td valign="top">output</td>
+ <td valign="top">Name of a file to which to write the output.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">errorOutput</td>
+ <td valign="top">The file to which the standard error of the
+ command should be redirected. <em>since Ant 1.9.4</em></td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">append</td>
+ <td valign="top">Whether output file should be appended to or overwritten. Defaults to false, meaning overwrite any existing file.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">errAppend</td>
+ <td valign="top">Whether errorOutput file should be appended to or
+ overwritten. Defaults to false, meaning overwrite any existing
+ file. <em>since Ant 1.9.4</em></td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">outputproperty</td>
+ <td valign="top">The name of a property in which the output of the
+ command should be stored. If you use the commandResource
+ attribute, each command's output will be prefixed by the
+ command itself.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">errorproperty</td>
+ <td valign="top">The name of a property in which the standard error of the
+ command should be stored. <em>since Ant 1.9.4</em></td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">resultproperty</td>
+ <td valign="top">the name of a property in which the return code
+ of the command should be stored. Only of interest if
+ failonerror=false. <em>since Ant 1.9.4</em></td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">timeout</td>
+ <td valign="top">Stop the command if it doesn't finish within the
+ specified time (given in milliseconds <b>unlike telnet, which
+ expects a timeout in seconds</b>).
+ Defaults to 0 which means &quot;wait forever&quot;.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">input</td>
+ <td valign="top">A file from which the executed command's standard
+ input is taken. This attribute is mutually exclusive with the
+ inputstring and inputproperty attributes.<br/>
+ When executing more than one command via commandResource, input
+ will be read for each command.
+ <em>since Ant 1.8.0</em></td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">verbose</td>
+ <td valign="top">Determines whether sshexec outputs verbosely to the user.<br/>
+ Similar output is generated as the ssh commandline tool wit the -v option.
+ <em>since Ant 1.8.0</em></td>
+ <td align="center">No, defaults to false</td>
+ </tr>
+ <tr>
+ <td valign="top">inputproperty</td>
+ <td valign="top">Name of a property who's content serves as the
+ input stream for the executed command. This attribute is
+ mutually exclusive with the input and inputstring
+ attributes.<br/>
+ When executing more than one command via commandResource, input
+ will be read for each command.
+ <em>since Ant 1.8.0</em></td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">inputstring</td>
+ <td valign="top">A string which serves as the input stream for the
+ executed command. This attribute is mutually exclusive with the
+ input and inputproperty attributes.<br/>
+ When executing more than one command via commandResource, input
+ will be read for each command.
+ <em>since Ant 1.8.3</em></td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">usepty</td>
+ <td valign="top">Whether to allocate a pseudo-tty (like ssh -t).
+ <em>since Ant 1.8.3</em></td>
+ <td align="center" valign="top">No, defaults to false</td>
+ </tr>
+ <tr>
+ <td valign="top">useSystemIn</td>
+ <td valign="top">Whether to pass the current standard input to the
+ remote process.
+ <em>since Ant 1.9.4</em></td>
+ <td align="center" valign="top">No, defaults to false</td>
+ </tr>
+</table>
+
+<h3>Examples</h3>
+<p><b>Run a command on a remote machine using password authentication</b></p>
+<pre>
+ &lt;sshexec host=&quot;somehost&quot;
+ username=&quot;dude&quot;
+ password=&quot;yo&quot;
+ command=&quot;touch somefile&quot;/&gt;
+</pre>
+
+<p><b>Run a command on a remote machine using key authentication</b></p>
+<pre>
+ &lt;sshexec host=&quot;somehost&quot;
+ username=&quot;dude&quot;
+ keyfile=&quot;${user.home}/.ssh/id_dsa&quot;
+ passphrase=&quot;yo its a secret&quot;
+ command=&quot;touch somefile&quot;/&gt;
+</pre>
+
+<p><b>Run a command on a remote machine using key authentication with no passphrase</b></p>
+<pre>
+ &lt;sshexec host=&quot;somehost&quot;
+ username=&quot;dude&quot;
+ keyfile=&quot;${user.home}/.ssh/id_dsa&quot;
+ command=&quot;touch somefile&quot;/&gt;
+</pre>
+
+<p><b>Run a set of commands from a command resource (file) on a remote machine using key authentication with no passphrase</b></p>
+<pre>
+ &lt;sshexec host=&quot;somehost&quot;
+ username=&quot;dude&quot;
+ keyfile=&quot;${user.home}/.ssh/id_dsa&quot;
+ commandResource=&quot;to_run&quot;/&gt;
+</pre>
+
+
+<p><strong>Security Note:</strong> Hard coding passwords and/or usernames
+in sshexec task can be a serious security hole. Consider using variable
+substitution and include the password on the command line. For example:<br>
+<pre>
+ &lt;sshexec host=&quot;somehost&quot;
+ username=&quot;${username}&quot;
+ password=&quot;${password}&quot;
+ command=&quot;touch somefile&quot;/&gt;
+</pre>
+Invoking ant with the following command line:
+<pre>
+ ant -Dusername=me -Dpassword=mypassword target1 target2
+</pre>
+
+Is slightly better, but the username/password is exposed to all users
+on an Unix system (via the ps command). The best approach is to use
+the
+<code>&lt;input&gt;</code> task and/or retrieve the password from a (secured)
+.properties file.
+</p>
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/sshsession.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/sshsession.html
new file mode 100644
index 00000000..e9696d1f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/sshsession.html
@@ -0,0 +1,288 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>SSHSESSION Task</title>
+</head>
+
+<body>
+
+<h2><a name="sshsession">SSHSESSION</a></h2>
+<h3>Description</h3>
+
+<p><em>since Apache Ant 1.8.0</em></p>
+
+<p>A Task which establishes an SSH connection with a remote machine
+running SSH daemon, optionally establishes any number of local or
+remote tunnels over that connection, then executes any nested tasks
+before taking down the connection.
+</p>
+
+<p><b>Note:</b> This task depends on external libraries not included
+in the Ant
+distribution. See <a href="../install.html#librarydependencies">Library
+Dependencies</a> for more information. This task has been tested with
+jsch-0.1.33 and above and won't work with versions of jsch earlier
+than 0.1.28.</p>
+
+<p>See also the <a href="sshexec.html">sshexec</a>
+and <a href="scp.html">scp</a> tasks</p>
+
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">host</td>
+ <td valign="top">The hostname or IP address of the remote host to which you wish to connect.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">username</td>
+ <td valign="top">The username on the remote host to which you are connecting.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">port</td>
+ <td valign="top">The port to connect to on the remote host.</td>
+ <td valian="top" align="center">No, defaults to 22.</td>
+ </tr>
+ <tr>
+ <tr>
+ <td valign="top">localtunnels</td>
+ <td valign="top">A comma-delimited list of
+ colon-delimited <code>lport:rhost:rport</code> triplets defining
+ local port forwarding.<br> If
+ nested <a href="#LocalTunnel">localtunnel</a> elements are also
+ provided, both sets of tunnels will be established.</td>
+ <td valian="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">remotetunnels</td>
+ <td valign="top">A comma-delimited list of
+ colon-delimited <code>rport:lhost:lport</code> triplets defining
+ remote port forwarding.<br> If
+ nested <a href="#RemoteTunnel">remotetunnel</a> elements are
+ also provided, both sets of tunnels will be established.</td>
+ <td valian="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">trust</td>
+
+ <td valign="top">This trusts all unknown hosts if set to yes/true.<br>
+ <strong>Note</strong> If you set this to false (the default), the
+ host you connect to must be listed in your knownhosts file, this
+ also implies that the file exists.</td>
+ <td valian="top" align="center">No, defaults to No.</td>
+ </tr>
+ <tr>
+ <td valign="top">knownhosts</td>
+ <td valign="top">This sets the known hosts file to use to validate
+ the identity of the remote host. This must be a SSH2 format file.
+ SSH1 format is not supported.</td>
+ <td valian="top" align="center">No, defaults to
+ ${user.home}/.ssh/known_hosts.</td>
+ </tr>
+ <tr>
+ <td valign="top">failonerror</td>
+ <td valign="top">Whether to halt the build if the command does not complete successfully.
+ </td>
+ <td valign="top" align="center">No; defaults to true.</td>
+ </tr>
+ <tr>
+ <td valign="top">password</td>
+ <td valign="top">The password.</td>
+ <td valign="top" align="center">Not if you are using key based
+ authentication or the password has been given in the file or
+ todir attribute.</td>
+ </tr>
+ <tr>
+ <td valign="top">keyfile</td>
+ <td valign="top">Location of the file holding the private key.</td>
+ <td valign="top" align="center">Yes, if you are using key based
+ authentication.</td>
+ </tr>
+ <tr>
+ <td valign="top">passphrase</td>
+ <td valign="top">Passphrase for your private key.</td>
+ <td valign="top" align="center">No, defaults to an empty string.</td>
+ </tr>
+ <tr>
+ <td valign="top">timeout</td>
+ <td valign="top">Give up if the connection cannot be established
+ within the specified time (given in milliseconds). Defaults to 0
+ which means &quot;wait forever&quot;.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+</table>
+
+<h3>Parameters specified as nested elements</h3>
+
+<a name="LocalTunnel"><h4>localtunnel</h4></a>
+<p>Optionally, any number of localtunnel elements can be used to
+define local port forwarding over the SSH connection. If the
+localtunnels parameter was also specified, both sets of tunnels will
+be established.</p>
+
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">lport</td>
+ <td valign="top">The number of the local port to be forwarded.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">rhost</td>
+ <td valign="top">The hostname or IP address of the remote host to
+ which the local port should be forwarded.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">rport</td>
+ <td valign="top">The number of the port on the remote host to
+ which the local port should be forwarded.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+</table>
+
+<a name="RemoteTunnel"><h4>remotetunnel</h4></a>
+<p>Optionally, any number of remotetunnel elements can be used to
+define remote port forwarding over the SSH connection. If the
+remotetunnels parameter was also specified, both sets of tunnels will
+be established.</p>
+
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">rport</td>
+ <td valign="top">The number of the remote port to be forwarded.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">lhost</td>
+ <td valign="top">The hostname or IP address of the local host to
+ which the remote port should be forwarded.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">lport</td>
+ <td valign="top">The number of the port on the local host to which
+ the remote port should be forwarded.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+</table>
+
+<a name="Sequential"><h4>sequential</h4></a>
+<p>The sequential element is a required parameter. It is a container
+for nested Tasks which are to be executed once the SSH connection is
+established and all local and/or remote tunnels established.</p>
+
+<h3>Examples</h3>
+<p><b>Connect to a remote machine using password authentication,
+forward the local cvs port to the remote host, and execute a cvs
+command locally, which can use the tunnel.</b></p>
+<pre>
+ &lt;sshsession host=&quot;somehost&quot;
+ username=&quot;dude&quot;
+ password=&quot;yo&quot;
+ localtunnels=&quot;2401:localhost:2401&quot;
+ &gt;
+ &lt;sequential&gt;
+ &lt;cvs command=&quot;update ${cvs.parms} ${module}&quot;
+ cvsRoot=&quot;${cvs.root}&quot;
+ dest=&quot;${local.root}&quot;
+ failonerror=&quot;true&quot;
+ /&gt;
+ &lt;/sequential&gt;
+ &lt;/sshsession&gt;
+</pre>
+
+<p><b>Do the same thing using nested localtunnel element.</b></p>
+<pre>
+ &lt;sshsession host=&quot;somehost&quot;
+ username=&quot;dude&quot;
+ password=&quot;yo&quot;
+ &gt;
+ &lt;localtunnel lport=&quot;2401&quot; rhost=&quot;localhost&quot; rport=&quot;2401&quot;/&gt;
+ &lt;sequential&gt;
+ &lt;cvs command=&quot;update ${cvs.parms} ${module}&quot;
+ cvsRoot=&quot;${cvs.root}&quot;
+ dest=&quot;${local.root}&quot;
+ failonerror=&quot;true&quot;
+ /&gt;
+ &lt;/sequential&gt;
+ &lt;/sshsession&gt;
+</pre>
+
+<p><b>Connect to a remote machine using key authentication, forward
+port 1080 to port 80 of an intranet server which is not directly
+accessible, then run a get task using that tunnel.</b></p>
+<pre>
+ &lt;sshsession host=&quot;somehost&quot;
+ username=&quot;dude&quot;
+ keyfile=&quot;${user.home}/.ssh/id_dsa&quot;
+ passphrase=&quot;yo its a secret&quot;/&gt;
+ &lt;LocalTunnel lport=&quot;1080&quot; rhost=&quot;intranet.mycomp.com&quot; rport=&quot;80&quot;/&gt;
+ &lt;sequential&gt;
+ &lt;get src=&quot;http://localhost:1080/somefile&quot; dest=&quot;temp/somefile&quot;/&gt;
+ &lt;/sequential&gt;
+ &lt;/sshsession&gt;
+</pre>
+
+
+<p><strong>Security Note:</strong> Hard coding passwords or
+passphrases and/or usernames in sshsession task can be a serious
+security hole. Consider using variable substitution and include the
+password on the command line. For example:<br>
+<pre>
+ &lt;sshsession host=&quot;somehost&quot;
+ username=&quot;${username}&quot;
+ password=&quot;${password}&quot;
+ localtunnels=&quot;2401:localhost:2401&quot;&gt;
+ &lt;sequential&gt;
+ &lt;sometask/&gt;
+ &lt;/sequential&gt;
+ &lt;/sshsession&gt;
+</pre>
+
+Invoking ant with the following command line:
+<pre>
+ ant -Dusername=me -Dpassword=mypassword target1 target2
+</pre>
+
+Is slightly better, but the username/password is exposed to all users
+on an Unix system (via the ps command). The best approach is to use
+the
+<code>&lt;input&gt;</code> task and/or retrieve the password from a (secured)
+.properties file.
+</p>
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/style.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/style.html
new file mode 100644
index 00000000..f02b98eb
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/style.html
@@ -0,0 +1,629 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>XSLT Task</title>
+</head>
+
+<body>
+
+<h2><a name="style">XSLT</a></h2>
+<p><em>The name <code>style</code> is a deprecated name for the same task.</em></p>
+<h3>Description</h3>
+<p>Process a set of documents via XSLT.</p>
+<p>This is useful for building views of XML based documentation,
+or for generating code.</p>
+<p><b>Note:</b> If you are using JDK 1.4 or higher, this task does not require external libraries
+not supplied in the Apache Ant distribution. However, often the built in XSL engine is not as up
+to date as a fresh download, so an update is still highly recommended
+ in particular since the built-in XSLT processors of Java 5 (and to a
+ certain extent Java 6) are known to have serious issues.
+See <a href="../install.html#librarydependencies">Library Dependencies</a> for more information.</p>
+<p>It is possible to refine the set of files that are being processed. This can be
+done with the <i>includes</i>, <i>includesfile</i>, <i>excludes</i>, <i>excludesfile</i> and <i>defaultexcludes</i>
+attributes. With the <i>includes</i> or <i>includesfile</i> attribute you specify the files you want to
+have included by using patterns. The <i>exclude</i> or <i>excludesfile</i> attribute is used to specify
+the files you want to have excluded. This is also done with patterns. And
+finally with the <i>defaultexcludes</i> attribute, you can specify whether you
+want to use default exclusions or not. See the section on <a
+href="../dirtasks.html#directorybasedtasks">directory based tasks</a>, on how the
+inclusion/exclusion of files works, and how to write patterns.</p>
+<p>This task forms an implicit <a href="../Types/fileset.html">FileSet</a> and supports all
+ attributes of <code>&lt;fileset&gt;</code> (<code>dir</code> becomes <code>basedir</code>)
+ as well as the nested <code>&lt;include&gt;</code>, <code>&lt;exclude&gt;</code>
+ and <code>&lt;patternset&gt;</code> elements.</p>
+
+<p><b>Note</b>: Unlike other similar tasks, this task treats
+directories that have been matched by the include/exclude patterns of
+the implicit fileset in a special way. It will apply the stylesheets
+to all files contain in them as well. Since the default include
+pattern is <code>**</code> this means it will apply the stylesheet to
+all files. If you specify an excludes pattern, it may still work on
+the files matched by those patterns because the parent directory has
+been matched. If this behavior is not what you want, set the
+scanincludedirectories attribute to false.</p>
+
+<p>Starting with Ant 1.7 this task supports nested <a
+href="../Types/resources.html#collection">resource collection</a>s
+in addition to (or instead of, depending on the useImplicitFileset
+attribute) the implicit fileset formed by this task.</p>
+
+<p>This task supports the use of a nested <code>&lt;param&gt;</code> element which is used to pass values
+ to an <code>&lt;xsl:param&gt;</code> declaration.</p>
+<p>This task supports the use of a nested <a href="../Types/xmlcatalog.html">xmlcatalog</a>
+element which is used to perform Entity and URI resolution.</p>
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">basedir</td>
+ <td valign="top">where to find the source XML file, default is the
+ project's basedir.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">destdir</td>
+ <td valign="top">directory in which to store the results.</td>
+ <td align="center" valign="top">Yes, unless in and out have been
+ specified.</td>
+ </tr>
+ <tr>
+ <td valign="top">extension</td>
+ <td valign="top">desired file extension to be used for the targets. If not
+ specified, the default is &quot;.html&quot;. Will be ignored if
+ a nested <code>&lt;mapper&gt;</code> has been specified.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">style</td>
+ <td valign="top">name of the stylesheet to use - given either relative
+ to the project's basedir or as an absolute path.<br/>
+ <br/>
+ Alternatively, a nested element which ant can interpret as a resource
+ can be used to indicate where to find the stylesheet<br/>
+ <em>deprecated variation :</em> <br/>
+ If the stylesheet cannot be found, and if you have specified the
+ attribute basedir for the task, ant will assume that the style
+ attribute is relative to the basedir of the task.
+ </td>
+ <td align="center" valign="top">No, if the location of
+ the stylesheet is specified using a nested &lt;style&gt; element</td>
+ </tr>
+ <tr>
+ <td valign="top">classpath</td>
+ <td valign="top">the classpath to use when looking up the XSLT
+ processor.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">classpathref</td>
+ <td valign="top">the classpath to use, given as <a
+ href="../using.html#references">reference</a> to a path defined elsewhere.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">force</td>
+ <td valign="top">Recreate target files, even if they are newer
+ than their corresponding source files or the stylesheet.</td>
+ <td valign="top" align="center">No; default is false</td>
+ </tr>
+ <tr>
+ <td valign="top">processor</td>
+
+ <td valign="top">name of the XSLT processor to use.
+ Permissible value is :<ul>
+ <li>&quot;trax&quot; for a TraX compliant processor (ie JAXP interface
+ implementation such as Xalan 2 or Saxon)</li></ul>
+ Defaults to trax.
+ <br/>
+ Support for xalan1 has been removed in ant 1.7.
+ </td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">includes</td>
+ <td valign="top">comma- or space-separated list of patterns of files that must be included.
+ All files are included when omitted.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">includesfile</td>
+ <td valign="top">the name of a file. Each line of this file is taken to be
+ an include pattern</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">excludes</td>
+ <td valign="top">comma- or space-separated list of patterns of files that must be excluded.
+ No files (except default excludes) are excluded when omitted.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">excludesfile</td>
+ <td valign="top">the name of a file. Each line of this file is taken to be
+ an exclude pattern</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">defaultexcludes</td>
+ <td valign="top">indicates whether default excludes should be used or not
+ (&quot;yes&quot;/&quot;no&quot;). Default excludes are used when omitted.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">in</td>
+ <td valign="top">specifies a single XML document to be styled. Should be used
+ with the out attribute.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">out</td>
+ <td valign="top">specifies the output name for the styled result from the
+ in attribute.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">scanincludeddirectories</td>
+ <td valign="top">If any directories are matched by the
+ includes/excludes patterns, try to transform all files in these
+ directories. Default is <code>true</code></td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">reloadstylesheet</td>
+ <td valign="top">Control whether the stylesheet transformer is created
+ anew for every transform operation. If you set this to true, performance may
+ suffer, but you may work around a bug in certain Xalan-J versions.
+ Default is <code>false</code>. <em>Since Ant 1.5.2</em>.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">useImplicitFileset</td>
+ <td valign="top">Whether the implicit fileset formed by this task
+ shall be used. If you set this to false you must use nested
+ resource collections - or the in attribute, in which case this
+ attribute has no impact anyway. Default is <code>true</code>.
+ <em>Since Ant 1.7</em>.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">filenameparameter</td>
+ <td valign="top">Specifies a xsl parameter for accessing the name
+ of the current processed file. If not set, the file name is not
+ passed to the transformation.
+ <em>Since Ant 1.7</em>.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">filedirparameter</td>
+ <td valign="top">Specifies a xsl parameter for accessing the directory
+ of the current processed file. For files in the current directory a
+ value of '.' will be passed to the transformation.
+ If not set, the directory is not passed to the transformation.
+ <em>Since Ant 1.7</em>.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">suppressWarnings</td>
+ <td valign="top">Whether processor warnings shall be suppressed.
+ This option requires support by the processor, it is supported by
+ the trax processor bundled with Ant.
+ <em>Since Ant 1.8.0</em>.</td>
+ <td valign="top" align="center">No, default is false.</td>
+ </tr>
+ <tr>
+ <td valign="top">failOnError</td>
+ <td valign="top">Whether the build should fail if any error
+ occurs. Note that transformation errors can still be suppressed by
+ setting failOnTransformationError to false even if this attribute
+ is true.
+ <em>Since Ant 1.8.0</em>.</td>
+ <td valign="top" align="center">No, default is true.</td>
+ </tr>
+ <tr>
+ <td valign="top">failOnTransformationError</td>
+ <td valign="top">Whether the build should fail if an error occurs
+ while transforming the document. Note that this attribute has no
+ effect of <code>failOnError</code> is false.
+ <em>Since Ant 1.8.0</em>.</td>
+ <td valign="top" align="center">No, default is true.</td>
+ </tr>
+ <tr>
+ <td valign="top">failOnNoResources</td>
+ <td valign="top">Whether the build should fail if the nested
+ resource collection is empty. Note that this attribute has no
+ effect of <code>failOnError</code> is false.
+ <em>Since Ant 1.8.0</em>.</td>
+ <td valign="top" align="center">No, default is true.</td>
+ </tr>
+</table>
+<h3>Parameters specified as nested elements</h3>
+
+<h4>any <a href="../Types/resources.html#collection">resource
+collection</a></h4>
+
+<p><em>since Ant 1.7</em></p>
+
+<p>Use resource collections to specify resources that the stylesheet
+should be applied to. Use a nested mapper and the task's destdir
+attribute to specify the output files.</p>
+
+<h4><a name="classpath">classpath</a></h4>
+<p>The classpath to load the processor from can be specified via a
+nested <code>&lt;classpath&gt;</code>, as well - that is, a
+<a href="../using.html#path">path</a>-like structure.</p>
+
+<h4>xmlcatalog</h4>
+<p>The <a href="../Types/xmlcatalog.html">xmlcatalog</a>
+element is used to perform Entity and URI resolution.</p>
+
+<h4>param</h4>
+<p>Param is used to pass a parameter to the XSL stylesheet.</p>
+<blockquote>
+<h4>Parameters</h4>
+<table width="60%" border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">name</td>
+ <td valign="top">Name of the XSL parameter</td>
+ <td align="center" valign="top">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">expression</td>
+ <td valign="top">
+ The value to be placed into the param or an XPath expression
+ (depending on <code>type</code>).
+ </td>
+ <td align="center" valign="top">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">type</td>
+ <td valign="top">
+ Data type of the parameter. Possible values are:
+ <ul>
+ <li><code>STRING</code></li>
+ <li><code>BOOLEAN</code></li>
+ <li><code>INT</code></li>
+ <li><code>LONG</code></li>
+ <li><code>DOUBLE</code></li>
+ <li><code>XPATH_STRING</code></li>
+ <li><code>XPATH_BOOLEAN</code></li>
+ <li><code>XPATH_NUMBER</code></li>
+ <li><code>XPATH_NODE</code></li>
+ <li><code>XPATH_NODESET</code></li>
+ </ul>
+ <em>since Ant 1.9.3</em>
+ </td>
+ <td align="center" valign="top">No; default is <code>STRING</code></td>
+ </tr>
+ <tr>
+ <td valign="top">if</td>
+ <td valign="top">The param will only be passed <a href="../properties.html#if+unless">if this property is set</a>.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">unless</td>
+ <td valign="top">The param will not be passed <a href="../properties.html#if+unless">if this property is set</a>.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+
+</table>
+</blockquote>
+
+ <p>
+ The <code>XPATH_*</code> types says that the <code>expression</code> is not just a primitive-type value but an XPath expression.
+ This expression will be evaluated on an empty XML document and the result will be passed to the XSLT transformer as a parameter of given type.
+ In these expressions the declared Ant properties can be used as XPath variables e.g. <code>$someProperty</code>.
+ So you can compute something using standard XPath functions and operators.
+ </p>
+ <p>
+ If you write <code>${someProperty}</code> instead of <code>$someProperty</code>,
+ the value will be simply substituted by Ant before evaluating the XPath expression
+ (this substitution works also for primitive types).
+ </p>
+
+<h4>outputproperty ('trax' processors only)</h4>
+<p>Used to specify how you wish the result tree to be output
+as specified in the <a href="http://www.w3.org/TR/xslt#output">
+XSLT specifications</a>.
+<blockquote>
+<h4>Parameters</h4>
+<table width="60%" border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">name</td>
+ <td valign="top">Name of the property</td>
+ <td align="center" valign="top">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">value</td>
+ <td valign="top">value of the property.</td>
+ <td align="center" valign="top">Yes</td>
+ </tr>
+</table>
+</blockquote>
+
+<h4><a name="factory">factory ('trax' processors only)</a></h4>
+Used to specify factory settings.
+<blockquote>
+<h4>Parameters</h4>
+<table width="60%" border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">name</td>
+ <td valign="top">fully qualified classname of the
+ transformer factory to use. For example
+ <tt>org.apache.xalan.processor.TransformerFactoryImpl</tt>
+ or <tt>org.apache.xalan.xsltc.trax.TransformerFactoryImpl</tt>
+ or <tt>net.sf.saxon.TransformerFactoryImpl</tt>...
+ </td>
+ <td align="center" valign="top">No. Defaults to the JAXP lookup mechanism.</td>
+ </tr>
+</table>
+<h3>Parameters specified as nested elements</h3>
+<h4>attribute </h4>
+<p>Used to specify settings of the processor factory.
+The attribute names and values are entirely processor specific
+so you must be aware of the implementation to figure them out.
+Read the documentation of your processor.
+For example, in Xalan 2.x:
+<ul>
+<li>http://xml.apache.org/xalan/features/optimize (boolean)</li>
+<li>http://xml.apache.org/xalan/features/incremental (boolean)</li>
+<li>...</li>
+</ul>
+And in Saxon 7.x:
+<ul>
+<li>http://saxon.sf.net/feature/allow-external-functions (boolean)</li>
+<li>http://saxon.sf.net/feature/timing (boolean)</li>
+<li>http://saxon.sf.net/feature/traceListener (string)</li>
+<li>http://saxon.sf.net/feature/treeModel (integer)</li>
+<li>http://saxon.sf.net/feature/linenumbering (integer)</li>
+<li>...</li>
+</ul>
+<blockquote>
+<h4>Parameters</h4>
+<table width="60%" border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">name</td>
+ <td valign="top">Name of the attribute</td>
+ <td align="center" valign="top">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">value</td>
+ <td valign="top">value of the attribute.</td>
+ <td align="center" valign="top">Yes</td>
+ </tr>
+</table>
+</blockquote>
+</blockquote>
+<h4>mapper</h4>
+
+<p><em>since Ant 1.6.2</em></p>
+
+<p>You can define filename transformations by using a nested <a
+href="../Types/mapper.html">mapper</a> element. The default mapper
+used by <code>&lt;xslt&gt;</code> removes the file extension from the
+source file and adds the extension specified via the extension
+attribute.</p>
+
+<h4>style</h4>
+
+<p><em>Since Ant 1.7</em></p>
+
+<p>The nested style element can be used to specify your stylesheet in terms
+of Ant's <a href="../Types/resources.html">resource</a> types. With
+this element, the stylesheet should be specified as a nested resource or
+single-element collection. Alternatively, use the <code>refid</code> to
+specify the resource or collection as a reference.</p>
+
+<h4>sysproperty</h4>
+<p>Use nested <code>&lt;sysproperty&gt;</code> elements to specify
+system properties required by the factory or transformation. These
+properties will be made available to the VM during the execution of
+the class. The attributes for this element are the same as
+for <a href="exec.html#env">environment variables</a>.</p>
+
+<p><em>since Ant 1.8.0</em>.</p>
+
+<h4>syspropertyset</h4>
+
+<p>You can specify a set of properties to be used as system properties
+with <a href="../Types/propertyset.html">syspropertyset</a>s.</p>
+
+<p><em>since Ant 1.8.0</em>.</p>
+
+<h3>Examples</h3>
+<blockquote>
+ <pre>
+&lt;xslt basedir=&quot;doc&quot; destdir=&quot;build/doc&quot;
+ extension=&quot;.html&quot; style=&quot;style/apache.xsl&quot;/&gt;</pre>
+ <h4>Using an xmlcatalog</h4>
+ <pre>
+&lt;xslt basedir=&quot;doc&quot; destdir=&quot;build/doc&quot;
+ extension=&quot;.html&quot; style=&quot;style/apache.xsl&quot;&gt;
+ &lt;xmlcatalog refid=&quot;mycatalog&quot;/&gt;
+&lt;/xslt&gt;
+
+&lt;xslt basedir=&quot;doc&quot; destdir=&quot;build/doc&quot;
+ extension=&quot;.html&quot; style=&quot;style/apache.xsl&quot;&gt;
+ &lt;xmlcatalog&gt;
+ &lt;dtd
+ publicId=&quot;-//ArielPartners//DTD XML Article V1.0//EN&quot;
+ location=&quot;com/arielpartners/knowledgebase/dtd/article.dtd&quot;/&gt;
+ &lt;/xmlcatalog&gt;
+&lt;/xslt&gt;
+</pre>
+ <h4>Using XSL parameters</h4>
+ <p>Simple String parameter:</p>
+<pre>
+&lt;xslt basedir=&quot;doc&quot; destdir=&quot;build/doc&quot;
+ extension=&quot;.html&quot; style=&quot;style/apache.xsl&quot;&gt;
+ &lt;param name=&quot;date&quot; expression=&quot;07-01-2000&quot;/&gt;
+&lt;/xslt&gt;</pre>
+
+ <p>Then if you declare a global parameter &quot;date&quot; with the top-level
+ element &lt;xsl:param name=&quot;date&quot;/&gt;, the variable
+ <code>$date</code> will subsequently have the value 07-01-2000.
+ </p>
+
+ <p>Various data types and XPath expressions:</p>
+
+ <pre>&lt;property name="antProperty1" value="ANT_PROPERTY_1"/&gt;
+&lt;property name="antProperty2" value="ANT_PROPERTY_2"/&gt;
+&lt;property name="antProperty3" value="3"/&gt;
+&lt;property name="antProperty4" value="substring-before"/&gt;
+
+&lt;!--
+ ${this} is substituted by Ant itself
+ and $this is evaluated by XPath as a variable
+--&gt;
+
+&lt;xslt in="in.xml" out="out.xml" style="template.xsl"&gt;
+
+ &lt;!-- Simple String parameter: --&gt;
+ &lt;param name="p0" expression="some nice string" type="STRING"/&gt;
+
+ &lt;!-- A value substituted by Ant --&gt;
+ &lt;param name="p1" expression="some string with ${antProperty1} constructed by Ant" type="STRING"/&gt;
+
+ &lt;!-- XPath resulting in: and this is done in XPath: ANT_PROPERTY_2 --&gt;
+ &lt;param name="p2" expression="concat('and this is done in XPath: ', $antProperty2)" type="XPATH_STRING"/&gt;
+
+ &lt;!-- Some XPath math, result: 42 --&gt;
+ &lt;param name="p3" expression="64 * 64 div 128 + 10" type="XPATH_NUMBER"/&gt;
+
+ &lt;!-- Some numeric parameter: --&gt;
+ &lt;param name="p4" expression="123.45" type="DOUBLE"/&gt;
+
+ &lt;!-- XPath expression, result: true boolean --&gt;
+ &lt;param name="p5" expression="$antProperty1 = 'ANT_PROPERTY_1'" type="XPATH_BOOLEAN"/&gt;
+
+ &lt;!-- First one is an XPath variable, second one is a text substituted by Ant, result: true boolean --&gt;
+ &lt;param name="p6" expression="$antProperty2 = '${antProperty2}'" type="XPATH_BOOLEAN"/&gt;
+
+ &lt;!-- Some XPath math with a variable, result: 64 --&gt;
+ &lt;param name="p7" expression="$antProperty3 * 4 * 5 + 4" type="XPATH_NUMBER"/&gt;
+
+ &lt;!--
+ XPath expression with substituted function name and a variable:
+ substring-before($antProperty2, '_')
+ result: ANT
+ --&gt;
+ &lt;param name="p8" expression="${antProperty4}($antProperty2, '_')" type="XPATH_STRING"/&gt;
+
+ &lt;!-- Without type attribute: --&gt;
+ &lt;param name="p9" expression="default type is String"/&gt;
+&lt;/xslt&gt;</pre>
+
+ <h4>Using output properties</h4>
+<pre>
+&lt;xslt in=&quot;doc.xml&quot; out=&quot;build/doc/output.xml&quot;
+ style=&quot;style/apache.xsl&quot;&gt;
+ &lt;outputproperty name=&quot;method&quot; value=&quot;xml&quot;/&gt;
+ &lt;outputproperty name=&quot;standalone&quot; value=&quot;yes&quot;/&gt;
+ &lt;outputproperty name=&quot;encoding&quot; value=&quot;iso8859_1&quot;/&gt;
+ &lt;outputproperty name=&quot;indent&quot; value=&quot;yes&quot;/&gt;
+&lt;/xslt&gt;
+</pre>
+
+ <h4>Using factory settings</h4>
+<pre>
+&lt;xslt in=&quot;doc.xml&quot; out=&quot;build/doc/output.xml&quot;
+ style=&quot;style/apache.xsl&quot;&gt;
+ &lt;factory name=&quot;org.apache.xalan.processor.TransformerFactoryImpl&quot;&gt;
+ &lt;attribute name=&quot;http://xml.apache.org/xalan/features/optimize&quot; value=&quot;true&quot;/&gt;
+ &lt;/factory&gt;
+&lt;/xslt&gt;</pre>
+
+ <h4>Using a mapper</h4>
+<pre>
+&lt;xslt basedir=&quot;in&quot; destdir=&quot;out&quot;
+ style=&quot;style/apache.xsl&quot;&gt;
+ &lt;mapper type=&quot;glob&quot; from=&quot;*.xml.en&quot; to=&quot;*.html.en&quot;/&gt;
+&lt;/xslt&gt;</pre>
+
+ <h4>Using a nested resource to define the stylesheet</h4>
+ <pre>
+&lt;xslt in="data.xml" out="${out.dir}/out.xml"&gt;
+ &lt;style&gt;
+ &lt;url url="${printParams.xsl.url}"/&gt;
+ &lt;/style&gt;
+ &lt;param name="set" expression="value"/&gt;
+&lt;/xslt&gt;</pre>
+
+ <h4>Print the current processed file name</h4>
+<pre>
+&lt;project&gt;
+ &lt;xslt style=&quot;printFilename.xsl&quot; destdir=&quot;out&quot; basedir=&quot;in&quot; extension=&quot;.txt&quot;
+ filenameparameter=&quot;filename&quot;
+ filedirparameter=&quot;filedir&quot;
+ /&gt;
+&lt;/project&gt;
+
+&lt;xsl:stylesheet
+ version=&quot;1.0&quot;
+ xmlns:xsl=&quot;http://www.w3.org/1999/XSL/Transform&quot;&gt;
+
+ &lt;xsl:param name=&quot;filename&quot;&gt;&lt;/xsl:param&gt;
+ &lt;xsl:param name=&quot;filedir&quot;&gt;.&lt;/xsl:param&gt;
+
+&lt;xsl:template match=&quot;/&quot;&gt;
+ Current file is &lt;xsl:value-of select=&quot;$filename&quot;/&gt; in directory &lt;xsl:value-of select=&quot;$filedir&quot;/&gt;.
+&lt;/xsl:template&gt;
+
+&lt;/xsl:stylesheet&gt;
+</pre>
+
+<h4>Use an XInclude-aware version of Xerces while transforming</h4>
+
+<pre>
+&lt;xslt ...&gt;
+ &lt;sysproperty key="org.apache.xerces.xni.parser.XMLParserConfiguration"
+ value="org.apache.xerces.parsers.XIncludeParserConfiguration"
+ /&gt;
+&lt;xslt&gt;
+</pre>
+</blockquote>
+
+
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/subant.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/subant.html
new file mode 100644
index 00000000..424bb67e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/subant.html
@@ -0,0 +1,608 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<html>
+<head>
+ <meta http-equiv="Content-Language" content="en-us">
+ <title>Subant Task</title>
+</head>
+
+<body bgcolor="#ffffff" text="#000000" link="#525D76"
+ alink="#525D76" vlink="#525D76">
+
+<table border="0" width="100%" cellspacing="4">
+
+ <!-- PAGE HEADER -->
+ <tr>
+ <td>
+ <table border="0" width="100%"><tr>
+ <td valign="bottom">
+ <font size="+3" face="arial,helvetica,sanserif"><strong>Subant Task</strong></font>
+ <br><font face="arial,helvetica,sanserif">Calls a given target for all defined sub-builds.</font>
+ </td>
+ <td>
+ <!-- PROJECT LOGO -->
+ <a href="http://ant.apache.org/">
+ <img src="../images/ant_logo_large.gif" align="right" alt="Apache Ant" border="0">
+ </a>
+ </td>
+ </tr></table>
+ </td>
+ </tr>
+
+ <!-- START RIGHT SIDE MAIN BODY -->
+ <tr>
+ <td valign="top" align="left">
+
+ <!-- Applying task/description -->
+ <!-- Start Description -->
+ <table border="0" cellspacing="0" cellpadding="2" width="100%">
+ <tr><td>&nbsp;</td></tr>
+
+ <tr><td bgcolor="#525D76">
+ <font color="#ffffff" face="arial,helvetica.sanserif">
+ <a name="description">
+ <strong>Description</strong></a></font>
+ </td></tr>
+
+ <tr><td><blockquote>
+<p>
+ Calls a given target for all defined sub-builds.
+ This is an extension
+ of ant for bulk project execution.
+
+ <strong>This task must not be used outside of a
+ <code>target</code> if it invokes the same build file it is
+ part of.</strong>
+ </p>
+ <p><em>Since Apache Ant 1.6</em></p>
+
+<p><code>subant</code> uses <code>ant</code> internally so many things
+ said in <a href="ant.html"><code>ant</code>'s manual page</a> apply
+ here as well.</p>
+
+ <table border="0" cellspacing="0" cellpadding="2" width="100%">
+ <!-- Subsection heading -->
+ <tr><td bgcolor="#828DA6">
+ <font color="#ffffff" face="arial,helvetica.sanserif">
+ <a name="Use with directories">
+ <strong>Use with directories</strong></a></font>
+ </td></tr>
+ <!-- Subsection body -->
+ <tr><td>
+ <p>
+ subant can be used with directory sets to execute a build from different directories.
+ 2 different options are offered :
+ </p>
+<ul>
+ <li>
+ to run the same build file <code>/somepath/otherpath/mybuild.xml</code>
+ with different base directories, use the genericantfile attribute
+ </li>
+ <li>if you want to run <code>directory1/mybuild.xml</code>, <code>directory2/mybuild.xml</code>, <code>....</code>,
+ use the antfile attribute. The subant task does not set the base directory for you in this case, because you can specify it in each build file.
+ </li>
+ </ul>
+
+ </td></tr>
+ </table>
+
+ </blockquote></td></tr>
+
+ </table>
+ <!-- End Description -->
+
+ <!-- Ignore -->
+
+
+
+ <!-- Start Attributes -->
+ <table border="0" cellspacing="0" cellpadding="2" width="100%">
+ <tr><td>&nbsp;</td></tr>
+ <tr><td bgcolor="#525D76">
+ <font color="#ffffff" face="arial,helvetica.sanserif">
+ <a name="attributes">
+ <strong>Parameters</strong></a></font>
+ </td></tr>
+ <tr><td><blockquote>
+ <table>
+ <tr>
+ <td bgcolor="#cccccc" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif"><b>Attribute</b></font>
+ </td>
+ <td bgcolor="#cccccc" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif"><b>Description</b></font>
+ </td>
+ <td bgcolor="#cccccc" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif"><b>Type</b></font>
+ </td>
+ <td bgcolor="#cccccc" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif"><b>Requirement</b></font>
+ </td>
+ </tr>
+ <!-- Attribute Group -->
+
+ <!-- Attribute Group -->
+ <!-- Attribute -->
+ <tr>
+ <td bgcolor="#eeeeee" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif">antfile</font>
+ </td>
+ <td bgcolor="#eeeeee" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif">Build file name, to use in conjunction with directories.<br> Defaults to "build.xml".<br> If <code>genericantfile</code> is set, this attribute is ignored.</font>
+ </td>
+ <td bgcolor="#eeeeee" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif">String</font>
+ </td>
+ <td bgcolor="#eeeeee" valign="top" align="left" rowspan="10">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif">Optional</font>
+ </td>
+ </tr>
+ <!-- Attribute -->
+ <tr>
+ <td bgcolor="#eeeeee" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif">buildpath</font>
+ </td>
+ <td bgcolor="#eeeeee" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif">Set the buildpath to be used to find sub-projects.</font>
+ </td>
+ <td bgcolor="#eeeeee" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif">Path</font>
+ </td>
+ </tr>
+ <!-- Attribute -->
+ <tr>
+ <td bgcolor="#eeeeee" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif">buildpathref</font>
+ </td>
+ <td bgcolor="#eeeeee" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif">Buildpath to use, by reference.</font>
+ </td>
+ <td bgcolor="#eeeeee" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif">Reference</font>
+ </td>
+ </tr>
+ <!-- Attribute -->
+ <tr>
+ <td bgcolor="#eeeeee" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif">failonerror</font>
+ </td>
+ <td bgcolor="#eeeeee" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif">Sets whether to fail with a build exception on error, or go on.</font>
+ </td>
+ <td bgcolor="#eeeeee" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif">boolean</font>
+ </td>
+ </tr>
+ <!-- Attribute -->
+ <tr>
+ <td bgcolor="#eeeeee" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif">genericantfile</font>
+ </td>
+ <td bgcolor="#eeeeee" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif">Build file path, to use in conjunction with directories.<br> Use <code>genericantfile</code>, in order to run the same build file with different basedirs.<br> If this attribute is set, <code>antfile</code> is ignored.</font>
+ </td>
+ <td bgcolor="#eeeeee" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif">File</font>
+ </td>
+ </tr>
+ <!-- Attribute -->
+ <tr>
+ <td bgcolor="#eeeeee" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif">inheritall</font>
+ </td>
+ <td bgcolor="#eeeeee" valign="top" align="left">
+ <font color="#000000" size="-1"
+ face="arial,helvetica,sanserif">Corresponds to
+ <code>&lt;ant&gt;</code>'s
+ <code>inheritall</code> attribute but defaults
+ to false in this task..</font>
+ </td>
+ <td bgcolor="#eeeeee" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif">boolean</font>
+ </td>
+ </tr>
+ <!-- Attribute -->
+ <tr>
+ <td bgcolor="#eeeeee" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif">inheritrefs</font>
+ </td>
+ <td bgcolor="#eeeeee" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif">Corresponds to <code>&lt;ant&gt;</code>'s <code>inheritrefs</code> attribute.</font>
+ </td>
+ <td bgcolor="#eeeeee" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif">boolean</font>
+ </td>
+ </tr>
+ <!-- Attribute -->
+ <tr>
+ <td bgcolor="#eeeeee" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif">output</font>
+ </td>
+ <td bgcolor="#eeeeee" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif">Corresponds to <code>&lt;ant&gt;</code>'s <code>output</code> attribute.</font>
+ </td>
+ <td bgcolor="#eeeeee" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif">String</font>
+ </td>
+ </tr>
+ <!-- Attribute -->
+ <tr>
+ <td bgcolor="#eeeeee" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif">target</font>
+ </td>
+ <td bgcolor="#eeeeee" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif"></font>
+ </td>
+ <td bgcolor="#eeeeee" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif">String</font>
+ </td>
+ </tr>
+
+ <!-- Attribute -->
+ <tr>
+ <td bgcolor="#eeeeee" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif">verbose</font>
+ </td>
+ <td bgcolor="#eeeeee" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif">
+ Enable/ disable log messages showing when each sub-build path is entered/ exited.
+ The default value is false.</font>
+ </td>
+ <td bgcolor="#eeeeee" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif">boolean</font>
+ </td>
+ </tr>
+
+
+ </table>
+ </blockquote></td></tr>
+
+ </table>
+ <!-- End Attributes -->
+
+ <!-- Start Elements -->
+ <table border="0" cellspacing="0" cellpadding="2" width="100%">
+ <tr><td>&nbsp;</td></tr>
+
+ <tr><td bgcolor="#525D76">
+ <font color="#ffffff" face="arial,helvetica.sanserif">
+ <a name="elements">
+ <strong>Parameters as nested elements</strong></a></font>
+ </td></tr>
+
+ <tr><td><blockquote>
+ <!-- Start Element -->
+ <table border="0" cellspacing="0" cellpadding="2" width="100%">
+ <tr><td>&nbsp;</td></tr>
+ <tr><td bgcolor="#828DA6">
+ <font color="#ffffff" face="arial,helvetica.sanserif" size="-1">
+ <strong>any filesystem based <a href="../Types/resources.html#collection">resource collection</a></strong></font>
+ </td></tr>
+ <tr><td><blockquote>
+ This includes <code>&lt;fileset&gt;</code>,
+ <code>&lt;dirset&gt;</code> and <code>&lt;filelist&gt;</code>
+ which are the nested resource collections supported prior
+ to Ant 1.7.
+ <!-- Ignore -->
+ <!-- Ignore -->
+
+ </blockquote></td></tr>
+ </table>
+ <!-- End Element -->
+ <!-- Start Element -->
+ <table border="0" cellspacing="0" cellpadding="2" width="100%">
+ <tr><td>&nbsp;</td></tr>
+ <tr><td bgcolor="#828DA6">
+ <font color="#ffffff" face="arial,helvetica.sanserif" size="-1">
+ <strong>dirset</strong> (org.apache.tools.ant.types.DirSet)</font>
+ </td></tr>
+ <tr><td><blockquote>
+ Adds a directory set to the implicit build path. <p> <em>Note that the directories will be added to the build path in no particular order, so if order is significant, one should use a file list instead!</em>
+ <!-- Ignore -->
+ <!-- Ignore -->
+
+ </blockquote></td></tr>
+ </table>
+ <!-- End Element -->
+ <!-- Start Element -->
+ <table border="0" cellspacing="0" cellpadding="2" width="100%">
+ <tr><td>&nbsp;</td></tr>
+ <tr><td bgcolor="#828DA6">
+ <font color="#ffffff" face="arial,helvetica.sanserif" size="-1">
+ <strong>filelist</strong> (org.apache.tools.ant.types.FileList)</font>
+ </td></tr>
+ <tr><td><blockquote>
+ Adds an ordered file list to the implicit build path. <p> <em>Note that contrary to file and directory sets, file lists can reference non-existent files or directories!</em>
+ <!-- Ignore -->
+ <!-- Ignore -->
+
+ </blockquote></td></tr>
+ </table>
+ <!-- End Element -->
+ <!-- Start Element -->
+ <table border="0" cellspacing="0" cellpadding="2" width="100%">
+ <tr><td>&nbsp;</td></tr>
+ <tr><td bgcolor="#828DA6">
+ <font color="#ffffff" face="arial,helvetica.sanserif" size="-1">
+ <strong>fileset</strong> (org.apache.tools.ant.types.FileSet)</font>
+ </td></tr>
+ <tr><td><blockquote>
+ Adds a file set to the implicit build path. <p> <em>Note that the directories will be added to the build path in no particular order, so if order is significant, one should use a file list instead!</em>
+ <!-- Ignore -->
+ <!-- Ignore -->
+
+ </blockquote></td></tr>
+ </table>
+ <!-- End Element -->
+ <!-- Start Element -->
+ <table border="0" cellspacing="0" cellpadding="2" width="100%">
+ <tr><td>&nbsp;</td></tr>
+ <tr><td bgcolor="#828DA6">
+ <font color="#ffffff" face="arial,helvetica.sanserif" size="-1">
+ <strong>property</strong> (org.apache.tools.ant.taskdefs.Property)</font>
+ </td></tr>
+ <tr><td><blockquote>
+ Corresponds to <code>&lt;ant&gt;</code>'s nested <code>&lt;property&gt;</code> element.
+
+<p>When more than one nested <code>&lt;property&gt;</code> element
+ would set a property of the same name, the one declared last will
+ win. This is for backwards compatibility reasons even so it is
+ different from the way <code>&lt;property&gt;</code> tasks in build
+ files behave.</p>
+
+ <!-- Ignore -->
+ <!-- Ignore -->
+
+ </blockquote></td></tr>
+ </table>
+ <!-- End Element -->
+ <!-- Start Element -->
+ <table border="0" cellspacing="0" cellpadding="2" width="100%">
+ <tr><td>&nbsp;</td></tr>
+ <tr><td bgcolor="#828DA6">
+ <font color="#ffffff" face="arial,helvetica.sanserif" size="-1">
+ <strong>propertyset</strong> (org.apache.tools.ant.types.PropertySet)</font>
+ </td></tr>
+ <tr><td><blockquote>
+ Corresponds to <code>&lt;ant&gt;</code>'s nested <code>&lt;propertyset&gt;</code> element.
+ <!-- Ignore -->
+ <!-- Ignore -->
+
+ </blockquote></td></tr>
+ </table>
+ <!-- End Element -->
+ <!-- Start Element -->
+ <table border="0" cellspacing="0" cellpadding="2" width="100%">
+ <tr><td>&nbsp;</td></tr>
+ <tr><td bgcolor="#828DA6">
+ <font color="#ffffff" face="arial,helvetica.sanserif" size="-1">
+ <strong>buildpath</strong> (org.apache.tools.ant.types.Path)</font>
+ </td></tr>
+ <tr><td><blockquote>
+ Creates a nested build path, and add it to the implicit build path.
+ <!-- Ignore -->
+ <!-- Ignore -->
+
+ </blockquote></td></tr>
+ </table>
+ <!-- End Element -->
+ <!-- Start Element -->
+ <table border="0" cellspacing="0" cellpadding="2" width="100%">
+ <tr><td>&nbsp;</td></tr>
+ <tr><td bgcolor="#828DA6">
+ <font color="#ffffff" face="arial,helvetica.sanserif" size="-1">
+ <strong>buildpathelement</strong> (org.apache.tools.ant.types.Path.PathElement)</font>
+ </td></tr>
+ <tr><td><blockquote>
+ Creates a nested <code>&lt;buildpathelement&gt;</code>, and add it to the implicit build path.
+ <!-- Ignore -->
+ <!-- Ignore -->
+
+ </blockquote></td></tr>
+ </table>
+ <!-- End Element -->
+
+
+
+
+<!-- manually written -->
+ <!-- Start Element -->
+ <table border="0" cellspacing="0" cellpadding="2" width="100%">
+ <tr><td>&nbsp;</td></tr>
+ <tr><td bgcolor="#828DA6">
+ <font color="#ffffff" face="arial,helvetica.sanserif" size="-1">
+ <strong>target</strong> (org.apache.tools.ant.taskdefs.Ant.TargetElement)</font>
+ </td></tr>
+ <tr><td><blockquote>
+ You can specify multiple targets using nested <code>&lt;target&gt;</code> elements
+ instead of using the target attribute. These will be executed as if
+ Ant had been invoked with a single target whose dependencies are the
+ targets so specified, in the order specified.
+ <!-- Ignore -->
+ <!-- Ignore -->
+ <table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">name</td>
+ <td valign="top">The name of the called target.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ </table>
+ <p><em>since Ant 1.7</em>.</p>
+ </blockquote></td></tr>
+ </table>
+ <!-- End Element -->
+<!-- manually written end -->
+
+ </blockquote></td></tr>
+
+ </table>
+ <!-- End Elements -->
+
+
+
+ <table border="0" cellspacing="0" cellpadding="2" width="100%">
+ <tr><td>&nbsp;</td></tr>
+
+ <tr><td bgcolor="#525D76">
+ <font color="#ffffff" face="arial,helvetica.sanserif">
+ <a name="examples">
+ <strong>Examples</strong></a></font>
+ </td></tr>
+
+ <tr><td><blockquote style="">
+ <pre>
+ &lt;project name="subant" default="subant1"&gt;
+ &lt;property name="build.dir" value="subant.build"/&gt;
+ &lt;target name="subant1"&gt;
+ &lt;subant target=""&gt;
+ &lt;property name="build.dir" value="subant1.build"/&gt;
+ &lt;property name="not.overloaded" value="not.overloaded"/&gt;
+ &lt;fileset dir="." includes="*/build.xml"/&gt;
+ &lt;/subant&gt;
+ &lt;/target&gt;
+ &lt;/project&gt;
+ </pre>
+<p>
+ this snippet build file will run ant in each subdirectory of the project directory,
+ where a file called build.xml can be found.
+ The property build.dir will have the value subant1.build in the ant projects called by subant.
+ </p>
+<pre>
+ &lt;subant target=""&gt;
+ &lt;propertyset&gt;
+ &lt;propertyref prefix="toplevel"/&gt;
+ &lt;mapper type="glob" from="foo*" to="bar*"/&gt;
+ &lt;/propertyset&gt;
+ &lt;fileset dir="." includes="*/build.xml"/&gt;
+ &lt;/subant&gt;
+ </pre>
+<p>
+ this snippet build file will run ant in each subdirectory of the project directory,
+ where a file called build.xml can be found.
+ All properties whose name starts with "foo" are passed, their names are changed to start with "bar" instead
+ </p>
+<pre>
+ &lt;subant target="compile" genericantfile="/opt/project/build1.xml"&gt;
+ &lt;dirset dir="." includes="projects*"/&gt;
+ &lt;/subant&gt;
+ </pre>
+<p>
+ assuming the subdirs of the project dir are called projects1, projects2, projects3
+ this snippet will execute the compile target of /opt/project/build1.xml,
+ setting the basedir to projects1, projects2, projects3
+ </p>
+
+ <!-- manually written -->
+ <p>Now a little more complex - but useful - scenario. Assume that we have
+ a directory structure like this:</p>
+ <pre>
+ root
+ | common.xml
+ | build.xml
+ |
+ +-- modules
+ +-- modA
+ | +-- src
+ +-- modB
+ +-- src
+
+ <u><b>common.xml:</b></u><br>
+ &lt;project&gt;
+ &lt;property name="src.dir" value="src"/&gt;
+ &lt;property name="build.dir" value="build"/&gt;
+ &lt;property name="classes.dir" value="${build.dir}/classes"/&gt;
+
+ &lt;target name="compile"&gt;
+ &lt;mkdir dir="${classes.dir}"/&gt;
+ &lt;javac srcdir="${src.dir}" destdir="${classes.dir}"/&gt;
+ &lt;/target&gt;
+
+ &lt;!-- more targets --&gt;
+ &lt;/project&gt;
+
+ <u><b>build.xml:</b></u><br>
+ &lt;project&gt;
+
+ &lt;macrodef name="iterate"&gt;
+ &lt;attribute name="target"/&gt;
+ &lt;sequential&gt;
+ &lt;subant target="@{target}"&gt;
+ &lt;fileset dir="modules" includes="*/build.xml"/&gt;
+ &lt;/subant&gt;
+ &lt;/sequential&gt;
+ &lt;/macrodef&gt;
+
+
+ &lt;target name="compile"&gt;
+ &lt;iterate target="compile"/&gt;
+ &lt;/target&gt;
+
+ &lt;!-- more targets --&gt;
+ &lt;/project&gt;
+
+ <u><b>modules/modA/build.xml:</b></u><br>
+ &lt;project name="modA"&gt;
+ &lt;import file="../../common.xml"/&gt;
+ &lt;/project&gt;
+ </pre>
+
+ <p>This results in very small buildfiles in the modules, maintainable
+ buildfile (common.xml) and a clear project structure. Additionally
+ the root buildfile is capable to run the whole build over all
+ modules.
+ </p>
+
+ <pre>
+ &lt;subant failonerror="false"&gt;
+ &lt;fileset dir="." includes="**/build.xml" excludes="build.xml"/&gt;
+ &lt;target name="clean"/&gt;
+ &lt;target name="build"/&gt;
+ &lt;/subant&gt;
+ </pre>
+
+ <p>Does a &quot;clean build&quot; for each subproject.</p>
+ <p><b>Hint:</b> because buildfiles are plain xml, you could generate the
+ masterbuildfile from the common buildfile by using a XSLT transformation:
+ </p>
+
+ <pre>
+ &lt;xslt in=&quot;common.xml&quot;
+ out=&quot;master.xml&quot;
+ style=&quot;${ant.home}/etc/common2master.xsl&quot;
+ /&gt;
+ </pre>
+
+ <!-- manually written -->
+
+ </blockquote></td></tr>
+
+ </table>
+
+ </td>
+ </tr>
+ <!-- END RIGHT SIDE MAIN BODY -->
+
+</table>
+
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/symlink.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/symlink.html
new file mode 100644
index 00000000..df42abd6
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/symlink.html
@@ -0,0 +1,146 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Symlink Task</title>
+</head>
+
+<body>
+
+<h2><a name="symlink">Symlink</a></h2>
+<h3>Description</h3>
+<p> Manages symbolic links on Unix based platforms. Can be used to
+make an individual link, delete a link, create multiple links from properties files,
+or create properties files describing links in the specified directories.
+Existing links are not overwritten by default.
+
+<p><a href="../Types/fileset.html">FileSet</a>s are used to select a
+set of links to record, or a set of property files to create links from. </p>
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">action</td>
+ <td valign="top">The type of action to perform, may be "single",
+ "record", "recreate" or "delete".</td>
+ <td valign="top" align="center">No, defaults to single.</td>
+ </tr>
+ <tr>
+ <td valign="top">link</td>
+ <td valign="top">The name of the link to be created or deleted.<br/>
+ <b>Note</b> this attribute is resolved against the current
+ working directory rather than the project's basedir for
+ historical reasons. It is recommended you always use an
+ absolute path or a path like <code>${basedir}/some-path</code>
+ as its value.
+ </td>
+ <td valign="center" align="center" >required for
+ action="single" or "delete". Ignored in other actions.</td>
+ </tr>
+ <tr>
+ <td valign="top">resource</td>
+ <td valign="top">The resource the link should point to.</td>
+ <td valign="top" align="center">required for action="single". Ignored in other actions.</td>
+ </tr>
+ <tr>
+ <td valign="top">linkfilename</td>
+ <td valign="top">The name of the properties file to create in
+ each included directory.</td>
+ <td valign="top" align="center">required for action="record".
+ Ignored in other actions.</td>
+ </tr>
+ <tr>
+ <td valign="top">overwrite</td>
+ <td valign="top">Overwrite existing links or not.</td>
+ <td valign="top" align="center">No; defaults to false.</td>
+ </tr>
+ <tr>
+ <td valign="top">failonerror</td>
+ <td valign="top">Stop build if true, log a warning message, but do not stop the build,
+ when the an error occurs if false.
+ </td>
+ <td valign="top" align="center">No; defaults to true.</td>
+ </tr>
+</table>
+<h3>Parameters specified as nested elements</h3>
+
+<h4>fileset</h4>
+ <p><a href="../Types/fileset.html">FileSet</a>s
+ are used when action = "record" to select directories and linknames to be recorded.
+ They are also used when action = "recreate" to specify both the name of the property
+ files to be processed, and the directories in which they can be found. At least one
+ fileset is required for each case.</p>
+
+<h3>Examples</h3>
+
+ <p> Make a link named "foo" to a resource named "bar.foo" in subdir:</p>
+ <pre>
+ &lt;symlink link="${dir.top}/foo" resource="${dir.top}/subdir/bar.foo"/&gt;
+ </pre>
+
+ <p> Record all links in subdir and it's descendants in files named
+ "dir.links"</p>
+ <pre>
+ &lt;symlink action="record" linkfilename="dir.links"&gt;
+ &lt;fileset dir="${dir.top}" includes="subdir&#47;**"/&gt;
+ &lt;/symlink&gt;
+ </pre>
+
+ <p> Recreate the links recorded in the previous example:</p>
+ <pre>
+ &lt;symlink action="recreate"&gt;
+ &lt;fileset dir="${dir.top}" includes="subdir&#47;**&#47;dir.links"/&gt;
+ &lt;/symlink&gt;
+ </pre>
+
+ <p> Delete a link named "foo":
+ <pre>
+ &lt;symlink action="delete" link="${dir.top}/foo"/&gt;
+ </pre>
+
+ <p><strong>Java 1.2 and earlier:</strong> Due to limitations on executing system
+ level commands in Java versions earlier than 1.3 this task may have difficulty
+ operating with a relative path in ANT_HOME. The typical symptom is an
+ IOException where Apache Ant can't find /some/working/directory${ANT_HOME}/bin/antRun
+ or something similar. The workaround is to change your ANT_HOME environment
+ variable to an absolute path, which will remove the /some/working/directory portion
+ of the above path and allow ant to find the correct commandline execution script.
+
+ <p><strong>LIMITATIONS:</strong> Because Java has no direct support for
+ handling symlinks this task divines them by comparing canonical and
+ absolute paths. On non-unix systems this may cause false positives.
+ Furthermore, any operating system on which the command
+ <code>ln -s &lt;linkname&gt; &lt;resourcename&gt;</code> is not a valid
+ command on the command line will not be able to use action="single" or
+ action="recreate". Action="record" and action=delete should still work. Finally,
+ the lack of support for symlinks in Java means that all links are recorded as
+ links to the <strong>canonical</strong> resource name. Therefore the link:
+ <code>link --> subdir/dir/../foo.bar</code> will be recorded as
+ <code>link=subdir/foo.bar</code> and restored as
+ <code>link --> subdir/foo.bar</code></p>
+
+
+
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/sync.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/sync.html
new file mode 100644
index 00000000..1d34aeef
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/sync.html
@@ -0,0 +1,166 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Sync Task</title>
+</head>
+
+<body>
+
+<h2><a name="get">Sync</a></h2>
+<p><em>Since Apache Ant 1.6</em></p>
+<h3>Description</h3>
+
+<p>Synchronize a target directory from the files defined in one or
+more <a href="../Types/resources.html#collection">Resource Collection</a>s.</p>
+
+<p>Any file in the target directory that has not been matched by at
+least one of the nested resource collections gets removed. I.e. if you exclude a
+file in your sources and a file of that name is present in the target
+dir, it will get removed from the target.</p>
+
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">todir</td>
+ <td valign="top">the target directory to sync with the resource collections</td>
+ <td align="center" valign="top">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">overwrite</td>
+ <td valign="top">Overwrite existing files even if the destination
+ files are newer.</td>
+ <td valign="top" align="center">No; defaults to false.</td>
+ </tr>
+ <tr>
+ <td valign="top">includeEmptyDirs</td>
+ <td valign="top">Copy any empty directories included in the
+ resource collection(s).<br/>
+ <b>Note</b> this attribute also controls the behavior for any
+ nested &lt;preserveintarget&gt; element. If this attribute is
+ false (the default) empty directories that only exist in the
+ target directory will be removed even if they are matched by
+ the patterns of &lt;preserveintarget&gt;. This can be
+ overridden by &lt;preserveintarget&gt;'s
+ preserveEmptyDirs attribute.
+ </td>
+ <td valign="top" align="center">No; defaults to false.</td>
+ </tr>
+ <tr>
+ <td valign="top">failonerror</td>
+ <td valign="top">If is set to false, log a warning message, but do not stop the build,
+ when one of the nested filesets points to a directory that
+ doesn't exist.
+ </td>
+ <td valign="top" align="center">No; defaults to true.</td>
+ </tr>
+ <tr>
+ <td valign="top">verbose</td>
+ <td valign="top">Log the files that are being copied.</td>
+ <td valign="top" align="center">No; defaults to false.</td>
+ </tr>
+ <tr>
+ <td valign="top">granularity</td>
+ <td valign="top">The number of milliseconds leeway to give before
+ deciding a file is out of date. This is needed because not every
+ file system supports tracking the last modified time to the
+ millisecond level. Default is 0 milliseconds, or 2 seconds on DOS
+ systems. This can also be useful if source and target files live
+ on separate machines with clocks being out of sync. <em>since Ant
+ 1.6.2</em>.</td>
+ <td valign="top" align="center">No.</td>
+ </tr>
+</table>
+
+<h3>Parameters specified as nested elements</h3>
+
+<h4>fileset or any other resource collection</h4>
+<p><a href="../Types/resources.html#collection">Resource
+Collection</a>s are used to select groups of files to copy.</p>
+<p>Prior to Ant 1.7 only <code>&lt;fileset&gt;</code> has been
+supported as a nested element.</p>
+
+<h4>preserveInTarget</h4>
+
+<p><em>Since Ant 1.7.0</em></p>
+
+<p>Specifies files or directories that should be kept in the target
+directory even if they are not present in one of the source
+directories.</p>
+
+<p>This nested element is like a <a
+href="../Types/fileset.html">FileSet</a> except that it doesn't
+support the dir attribute and the usedefaultexcludes attribute
+defaults to false.</p>
+
+<h5>Additional Parameters</h5>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">preserveEmptyDirs</td>
+ <td valign="top">Overrules the includeEmptydirs setting for
+ directories matched by this element. If you want to preserve
+ empty directories that are not in your source directory you can
+ either set the task's includeemptydirs attribute or this one.
+ If the two attribute values conflict, this attribute
+ "wins".</td>
+ <td align="center" valign="top">No, defaults to the value of the
+ task's includeemptydirs attribute</td>
+ </tr>
+</table>
+
+<h3>Examples</h3>
+
+<blockquote><pre>
+&lt;sync todir=&quot;site&quot;&gt;
+ &lt;fileset dir=&quot;generated-site&quot;/&gt;
+&lt;/sync&gt;
+</pre></blockquote>
+<p>overwrites all files in <em>site</em> with newer files from
+<em>generated-site</em>, deletes files from <em>site</em> that are not
+present in <em>generated-site</em>.</p>
+
+<blockquote><pre>
+&lt;sync todir=&quot;site&quot;&gt;
+ &lt;fileset dir=&quot;generated-site&quot;/&gt;
+ &lt;preserveintarget&gt;
+ &lt;include name=&quot;**/CVS/**&quot;/&gt;
+ &lt;/preserveintarget&gt;
+&lt;/sync&gt;
+</pre></blockquote>
+<p>overwrites all files in <em>site</em> with newer files from
+<em>generated-site</em>, deletes files from <em>site</em> that are not
+present in <em>generated-site</em> but keeps all files in any
+<em>CVS</em> sub-directory.</p>
+
+
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/tar.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/tar.html
new file mode 100644
index 00000000..4794d63d
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/tar.html
@@ -0,0 +1,281 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Tar Task</title>
+</head>
+
+<body>
+
+<h2><a name="tar">Tar</a></h2>
+<h3>Description</h3>
+<p>Creates a tar archive.</p>
+<p>The <i>basedir</i> attribute is the reference directory from where to tar.</p>
+<p>This task is a <a href="../dirtasks.html#directorybasedtasks">directory based task</a>
+and, as such, forms an implicit <a href="../Types/fileset.html">Fileset</a>. This
+defines which files, relative to the <i>basedir</i>, will be included in the
+archive. The tar task supports all the attributes of Fileset to refine the
+set of files to be included in the implicit fileset.</p>
+
+<p>In addition to the implicit fileset, the tar task supports nested
+ resource collections and a special form of filesets. These
+filesets are extended to allow control over the access mode, username and groupname
+to be applied to the tar entries. This is useful, for example, when preparing archives for
+ Unix systems where some files need to have execute permission. By
+ default this task will use Unix permissions of 644 for files and 755
+ for directories.</p>
+
+<p>Early versions of tar did not support path lengths greater than 100
+ characters. Over time several incompatible extensions have been
+ developed until a new POSIX standard was created that added so
+ called PAX extension headers (as the pax utility first introduced
+ them) that among another things addressed file names longer than 100
+ characters. All modern implementations of tar support PAX extension
+ headers.</p>
+
+<p>Ant's tar support predates the standard with PAX extension headers,
+ it supports different dialects that can be enabled using the
+ <i>longfile</i> attribute.
+If the longfile attribute is set to <code>fail</code>, any long paths will
+cause the tar task to fail. If the longfile attribute is set to
+<code>truncate</code>, any long paths will be truncated to the 100 character
+maximum length prior to adding to the archive. If the value of the longfile
+attribute is set to <code>omit</code> then files containing long paths will be
+omitted from the archive. Either option ensures that the archive can be
+untarred by any compliant version of tar.</p>
+
+<p>If the loss of path or file
+information is not acceptable, and it rarely is, longfile may be set to the
+value <code>gnu</code> or <code>posix</code>. With <code>posix</code>
+ Ant will add PAX extension headers, with <code>gnu</code> it adds
+ GNU tar specific extensions that newer versions of GNU tar call
+ "oldgnu". GNU tar still creates these extensions by default but
+ supports PAX extension headers as well. Either choice will produce
+ a tar file which
+can have arbitrary length paths. Note however, that the resulting archive will
+only be able to be untarred with tar tools that support the chosen format.
+
+<p>The default for the longfile
+attribute is <code>warn</code> which behaves just like the gnu option except
+that it produces a warning for each file path encountered that does not match
+the limit. It uses gnu rather than posix for backwards compatibility
+ reasons.</p>
+
+<p>To achivieve best interoperability you should use
+ either <code>fail</code> or <code>posix</code> for the longfile attribute.</p>
+
+<p>This task can perform compression by setting the compression attribute to "gzip"
+or "bzip2".</p>
+
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td valign="top" align="center"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">destfile</td>
+ <td valign="top">the tar-file to create.</td>
+ <td align="center" valign="top">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">basedir</td>
+ <td valign="top">the directory from which to tar the files.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">longfile</td>
+ <td valign="top">Determines how long files (&gt;100 chars) are to be
+ handled. Allowable values are &quot;truncate&quot;, &quot;fail&quot;,
+ &quot;warn&quot;, &quot;omit&quot;, &quot;gnu&quot; and &quot;posix&quot;. Default is
+ &quot;warn&quot;.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">includes</td>
+ <td valign="top">comma- or space-separated list of patterns of files that must be
+ included. All files are included when omitted.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">includesfile</td>
+ <td valign="top">the name of a file. Each line of this file is
+ taken to be an include pattern</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">excludes</td>
+ <td valign="top">comma- or space-separated list of patterns of files that must be
+ excluded. No files (except default excludes) are excluded when omitted.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">excludesfile</td>
+ <td valign="top">the name of a file. Each line of this file is
+ taken to be an exclude pattern</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">defaultexcludes</td>
+ <td valign="top">indicates whether default excludes should be used or not
+ (&quot;yes&quot;/&quot;no&quot;). Default excludes are used when omitted.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">compression</td>
+ <td valign="top">compression method. Allowable values are
+ &quot;none&quot;, &quot;gzip&quot; and &quot;bzip2&quot;. Default is
+ &quot;none&quot;.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">encoding</td>
+ <td valign="top">The character encoding to use for filenames
+ inside the tar file. For a list of possible values see the <a
+ href="http://docs.oracle.com/javase/7/docs/technotes/guides/intl/encoding.doc.html">Supported Encodings</a>.<br/>
+ Defaults to the platform's default character encoding.
+ <em>Since Ant 1.9.5</em>
+ <td align="center" valign="top">No</td>
+ </tr>
+</table>
+
+<h3>Nested Elements</h3>
+
+The tar task supports nested <a
+href="../Types/tarfileset.html">tarfileset</a> elements. These are
+extended <a href="../Types/fileset.html">FileSets</a> which,
+in addition to the standard elements, support one additional
+attributes
+
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td valign="top" align="center"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">preserveLeadingSlashes</td>
+ <td valign="top">Indicates whether leading `/'s should
+ be preserved in the file names. Default is <code>false</code>.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+</table>
+
+<h4>any other resource collection</h4>
+<p><a href="../Types/resources.html#collection">Resource
+Collection</a>s are used to select groups of files to archive.</p>
+<p>Prior to Apache Ant 1.7 only <code>&lt;fileset&gt;</code> has been
+supported as a nested element.</p>
+
+<h3>Examples</h3>
+<pre>
+&lt;tar destfile=&quot;${dist}/manual.tar&quot; basedir=&quot;htdocs/manual&quot;/&gt;
+&lt;gzip destfile=&quot;${dist}/manual.tar.gz&quot; src=&quot;${dist}/manual.tar&quot;/&gt;</pre>
+<p>tars all files in the <code>htdocs/manual</code> directory into a file called <code>manual.tar</code>
+in the <code>${dist}</code> directory, then applies the gzip task to compress
+it.</p>
+
+<pre>
+&lt;tar destfile=&quot;${dist}/manual.tar&quot;
+ basedir=&quot;htdocs/manual&quot;
+ excludes=&quot;mydocs/**, **/todo.html&quot;
+/&gt;</pre>
+<p>tars all files in the <code>htdocs/manual</code> directory into a file called <code>manual.tar</code>
+in the <code>${dist}</code> directory. Files in the directory <code>mydocs</code>,
+or files with the name <code>todo.html</code> are excluded.</p>
+
+<pre>
+&lt;tar destfile=&quot;${basedir}/docs.tar&quot;&gt;
+ &lt;tarfileset dir=&quot;${dir.src}/docs&quot;
+ fullpath=&quot;/usr/doc/ant/README&quot;
+ preserveLeadingSlashes=&quot;true&quot;&gt;
+ &lt;include name=&quot;readme.txt&quot;/&gt;
+ &lt;/tarfileset&gt;
+ &lt;tarfileset dir=&quot;${dir.src}/docs&quot;
+ prefix=&quot;/usr/doc/ant&quot;
+ preserveLeadingSlashes=&quot;true&quot;&gt;
+ &lt;include name=&quot;*.html&quot;/&gt;
+ &lt;/tarfileset&gt;
+&lt;/tar&gt;</pre>
+<p>
+ Writes the file <code>docs/readme.txt</code> as
+ <code>/usr/doc/ant/README</code> into the archive. All
+ <code>*.html</code> files in the <code>docs</code> directory are
+ prefixed by <code>/usr/doc/ant</code>, so for example
+ <code>docs/index.html</code> is written as
+ <code>/usr/doc/ant/index.html</code> to the archive.
+</p>
+
+<pre>
+&lt;tar longfile=&quot;gnu&quot;
+ destfile=&quot;${dist.base}/${dist.name}-src.tar&quot;&gt;
+ &lt;tarfileset dir=&quot;${dist.name}/..&quot; filemode=&quot;755&quot; username=&quot;ant&quot; group=&quot;ant&quot;&gt;
+ &lt;include name=&quot;${dist.name}/bootstrap.sh&quot;/&gt;
+ &lt;include name=&quot;${dist.name}/build.sh&quot;/&gt;
+ &lt;/tarfileset&gt;
+ &lt;tarfileset dir=&quot;${dist.name}/..&quot; username=&quot;ant&quot; group=&quot;ant&quot;&gt;
+ &lt;include name=&quot;${dist.name}/**&quot;/&gt;
+ &lt;exclude name=&quot;${dist.name}/bootstrap.sh&quot;/&gt;
+ &lt;exclude name=&quot;${dist.name}/build.sh&quot;/&gt;
+ &lt;/tarfileset&gt;
+&lt;/tar&gt;
+</pre>
+<p>This example shows building a tar which uses the GNU extensions for long paths and
+where some files need to be marked as executable (mode 755)
+and the rest are use the default mode (read-write by owner). The first
+fileset selects just the executable files. The second fileset must exclude
+the executable files and include all others. </p>
+
+
+
+<p><strong>Note: </strong> The tar task does not ensure that a file is only selected
+by one resource collection. If the same file is selected by more than one collection, it will be included in the
+tar file twice, with the same path.</p>
+
+<p><strong>Note:</strong> The patterns in the include and exclude
+elements are considered to be relative to the corresponding dir
+attribute as with all other filesets. In the example above,
+<code>${dist.name}</code> is not an absolute path, but a simple name
+of a directory, so <code>${dist.name}</code> is a valid path relative
+to <code>${dist.name}/..</code>.</p>
+
+
+<pre>
+&lt;tar destfile="release.tar.gz" compression="gzip"&gt;
+ &lt;zipfileset src="release.zip"/&gt;
+&lt;/tar&gt;
+</pre>
+<p>Re-packages a ZIP archive as a GZip compressed tar archive. If
+Unix file permissions have been stored as part of the ZIP file, they
+will be retained in the resulting tar archive.</p>
+
+
+<p><strong>Note:</strong>
+ Please note the tar task creates a tar file, it does not append
+ to an existing tar file. The existing tar file is replaced instead.
+ As with most tasks in Ant, the task only takes action if the output
+ file (the tar file in this case) is older than the input files, or
+ if the output file does not exist.
+</p>
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/taskdef.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/taskdef.html
new file mode 100644
index 00000000..4f6f5d2b
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/taskdef.html
@@ -0,0 +1,44 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>TaskDef Task</title>
+</head>
+
+<body>
+
+<h2><a name="taskdef">Taskdef</a></h2>
+<h3>Description</h3>
+ <p>Adds a task definition to the current project, such that this new task can be
+ used in the current project.</p>
+ <p>This task is a form of <a href="typedef.html">Typedef</a> with the
+ attributes "adapter" and "adaptto" set to the values
+ "org.apache.tools.ant.TaskAdapter" and "org.apache.tools.ant.Task"
+ respectively. Anything said in the <a href="typedef.html">manual
+ page of typedef</a> applies to taskdef as well.</p>
+<h3>Examples</h3>
+<pre> &lt;taskdef name=&quot;myjavadoc&quot; classname=&quot;com.mydomain.JavadocTask&quot;/&gt;</pre>
+<p>makes a task called <code>myjavadoc</code> available to Apache Ant. The class <code>com.mydomain.JavadocTask</code>
+implements the task.</p>
+
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/telnet.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/telnet.html
new file mode 100644
index 00000000..0ac65b37
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/telnet.html
@@ -0,0 +1,155 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Telnet Task</title>
+</head>
+
+<body>
+
+<h2><a name="telnet">Telnet</a></h2>
+<h3>Description</h3>
+Task to automate a remote telnet session. The task uses
+nested <tt>&lt;read&gt;</tt> to indicate strings to wait for, and
+<tt>&lt;write&gt;</tt> tags to specify text to send.
+
+<p>If you do specify a userid and password, the system will
+assume a common unix prompt to wait on. This behavior can be easily over-ridden.</p>
+<p><b>Note:</b> This task depends on external libraries not included in the Apache Ant distribution.
+See <a href="../install.html#librarydependencies">Library Dependencies</a> for more information.</p>
+
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <th>Attribute</th>
+ <th>Values</th>
+ <th>Required</th>
+ </tr>
+ <tr>
+ <td>userid</td>
+ <td>the login id to use on the telnet server.</td>
+ <td>Only if password is specified</td>
+ </tr>
+ <tr>
+ <td>password</td>
+ <td>the login password to use on the telnet server.</td>
+ <td>Only if userid is specified</td>
+ </tr>
+ <tr>
+ <td>server</td>
+ <td>the address of the remote telnet server.</td>
+ <td>Yes</td>
+ </tr>
+ <tr>
+ <td>port</td>
+ <td>the port number of the remote telnet server. Defaults to port 23.</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>initialCR</td>
+ <td>send a cr after connecting (&quot;yes&quot;). Defaults to &quot;no&quot;.</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>timeout</td>
+ <td>set a default timeout to wait for a response. Specified in seconds. Default is no timeout.</td>
+ <td>No</td>
+ </tr>
+</table>
+<h3><a name="nested">Nested Elements</a></h3>
+The commands to send to the server, and responses to wait for, are
+described as nested elements.
+
+<h4>read</h4>
+
+<p>declare (as a text child of this element) a string to wait for.
+The element supports the timeout attribute, which overrides any
+timeout specified for the task as a whole. It also has a <tt>string</tt>
+attribute, which is an alternative to specifying the string as
+a text element.
+</p>
+<i>Always declare an opening and closing
+<code>&lt;read&gt;</code> element to ensure that statements are not sent before
+the connection is ready, and that the connection is not broken before
+the final command has completed.
+</i>
+<h4>write</h4>
+
+<p>describes the text to send to the server. The <tt>echo</tt> boolean
+attribute controls whether the string is echoed to the local log;
+this is "true" by default
+</p>
+<h3>Examples</h3>
+A simple example of connecting to a server and running a command. This assumes
+ a prompt of &quot;ogin:&quot; for the userid, and a prompt of &quot;assword:&quot;
+ for the password.
+
+<blockquote><pre>
+&lt;telnet userid=&quot;bob&quot; password=&quot;badpass&quot; server=&quot;localhost&quot;&gt;
+ &lt;read&gt;/home/bob&lt;/read&gt;
+ &lt;write&gt;ls&lt;/write&gt;
+ &lt;read string=&quot;/home/bob&quot;/&gt;
+&lt;/telnet&gt;
+</pre></blockquote>
+
+This task can be rewritten as:
+<blockquote><pre>
+&lt;telnet server=&quot;localhost&quot;&gt;
+ &lt;read&gt;ogin:&lt;/read&gt;
+ &lt;write&gt;bob&lt;/write&gt;
+ &lt;read&gt;assword:&lt;/read&gt;
+ &lt;write&gt;badpass&lt;/write&gt;
+ &lt;read&gt;/home/bob&lt;/read&gt;
+ &lt;write&gt;ls&lt;/write&gt;
+ &lt;read&gt;/home/bob&lt;/read&gt;
+&lt;/telnet&gt;
+</pre></blockquote>
+
+A timeout can be specified at the <code>&lt;telnet&gt;</code> level or at the <code>&lt;read&gt;</code> level.
+This will connect, issue a sleep command that is suppressed from displaying and wait
+10 seconds before quitting.
+<blockquote><pre>
+&lt;telnet userid=&quot;bob&quot; password=&quot;badpass&quot; server=&quot;localhost&quot; timeout=&quot;20&quot;&gt;
+ &lt;read&gt;/home/bob&lt;/read&gt;
+ &lt;write echo=&quot;false&quot;&gt;sleep 15&lt;/write&gt;
+ &lt;read timeout=&quot;10&quot;&gt;/home/bob&lt;/read&gt;
+&lt;/telnet&gt;
+</pre></blockquote>
+
+The task can be used with other ports as well:
+<blockquote><pre>
+&lt;telnet port=&quot;80&quot; server=&quot;localhost&quot; timeout=&quot;20&quot;&gt;
+ &lt;read/&gt;
+ &lt;write&gt;GET / http/0.9&lt;/write&gt;
+ &lt;write/&gt;
+ &lt;read timeout=&quot;10&quot;&gt;&amp;lt;/HTML&amp;gt;&lt;/read&gt;
+&lt;/telnet&gt;
+</pre></blockquote>
+<p>
+To use this task against the WinNT telnet service, you need to configure the service to use
+classic authentication rather than NTLM negotiated authentication.
+This can be done in the Telnet Server Admin app:
+select "display/change registry settings", then "NTLM", then set the value of NTLM to 1.
+</p>
+
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/tempfile.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/tempfile.html
new file mode 100644
index 00000000..1be00d07
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/tempfile.html
@@ -0,0 +1,229 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<html>
+<head>
+ <meta http-equiv="Content-Language" content="en-us">
+ <title>Tempfile Task</title>
+</head>
+
+<body bgcolor="#ffffff" text="#000000" link="#525D76"
+ alink="#525D76" vlink="#525D76">
+
+<table border="0" width="100%" cellspacing="4">
+
+ <!-- PAGE HEADER -->
+ <tr>
+ <td>
+ <table border="0" width="100%"><tr>
+ <td valign="bottom">
+ <font size="+3" face="arial,helvetica,sanserif"><strong>Tempfile Task</strong></font>
+ <br><font face="arial,helvetica,sanserif">This task sets a property to the name of a temporary file.</font>
+ </td>
+ <td>
+ <!-- PROJECT LOGO -->
+ <a href="http://ant.apache.org/">
+ <img src="../images/ant_logo_large.gif" align="right" alt="Apache Ant" border="0">
+ </a>
+ </td>
+ </tr></table>
+ </td>
+ </tr>
+
+ <!-- START RIGHT SIDE MAIN BODY -->
+ <tr>
+ <td valign="top" align="left">
+
+ <!-- Applying task/long-description -->
+ <!-- Start Description -->
+ <table border="0" cellspacing="0" cellpadding="2" width="100%">
+ <tr><td>&nbsp;</td></tr>
+
+ <tr><td bgcolor="#525D76">
+ <font color="#ffffff" face="arial,helvetica.sanserif">
+ <a name="description">
+ <strong>Description</strong></a></font>
+ </td></tr>
+
+ <tr><td><blockquote>
+
+ This task sets a property to the name of a temporary file.
+ Unlike <code>java.io.File.createTempFile</code>,
+ this task does not actually create the temporary file, but it does guarantee that the
+ file did not exist when the task was executed.
+
+ <p>Examples:
+
+ <pre>&lt;tempfile property="temp.file"/&gt;</pre>
+
+ create a temporary file
+
+ <pre>&lt;tempfile property="temp.file" suffix=".xml"/&gt;</pre>
+
+ create a temporary file with the <code>.xml</code> suffix
+
+ <pre>&lt;tempfile property="temp.file" destDir="build"/&gt;</pre>
+
+ create a temporary file in the <code>build</code> subdirectory
+
+ </blockquote></td></tr>
+
+ </table>
+ <!-- End Description -->
+
+ <!-- Ignore -->
+
+
+
+ <!-- Start Attributes -->
+ <table border="0" cellspacing="0" cellpadding="2" width="100%">
+ <tr><td>&nbsp;</td></tr>
+ <tr><td bgcolor="#525D76">
+ <font color="#ffffff" face="arial,helvetica.sanserif">
+ <a name="attributes">
+ <strong>Parameters</strong></a></font>
+ </td></tr>
+ <tr><td><blockquote>
+ <table>
+ <tr>
+ <td bgcolor="#cccccc" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif"><b>Attribute</b></font>
+ </td>
+ <td bgcolor="#cccccc" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif"><b>Description</b></font>
+ </td>
+ <td bgcolor="#cccccc" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif"><b>Type</b></font>
+ </td>
+ <td bgcolor="#cccccc" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif"><b>Requirement</b></font>
+ </td>
+ </tr>
+ <!-- Attribute Group -->
+ <!-- Attribute -->
+ <tr>
+ <td bgcolor="#eeeeee" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif">property</font>
+ </td>
+ <td bgcolor="#eeeeee" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif">Sets the property you wish to assign the temporary file to.</font>
+ </td>
+ <td bgcolor="#eeeeee" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif">String</font>
+ </td>
+ <td bgcolor="#eeeeee" valign="top" align="left" rowspan="1">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif">Required</font>
+ </td>
+ </tr>
+
+ <!-- Attribute Group -->
+ <!-- Attribute -->
+ <tr>
+ <td bgcolor="#eeeeee" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif">destdir</font>
+ </td>
+ <td bgcolor="#eeeeee" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif">Sets the destination directory. If not set, the basedir directory is used instead.</font>
+ </td>
+ <td bgcolor="#eeeeee" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif">File</font>
+ </td>
+ <td bgcolor="#eeeeee" valign="top" align="left" rowspan="5">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif">Optional</font>
+ </td>
+ </tr>
+ <!-- Attribute -->
+ <tr>
+ <td bgcolor="#eeeeee" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif">prefix</font>
+ </td>
+ <td bgcolor="#eeeeee" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif">Sets the optional prefix string for the temp file.</font>
+ </td>
+ <td bgcolor="#eeeeee" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif">String</font>
+ </td>
+ </tr>
+ <!-- Attribute -->
+ <tr>
+ <td bgcolor="#eeeeee" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif">suffix</font>
+ </td>
+ <td bgcolor="#eeeeee" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif">Sets the optional suffix string for the temp file.</font>
+ </td>
+ <td bgcolor="#eeeeee" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif">String</font>
+ </td>
+ </tr>
+ <!-- Attribute -->
+ <tr>
+ <td bgcolor="#eeeeee" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif">deleteonexit</font>
+ </td>
+ <td bgcolor="#eeeeee" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif">Whether the temp file will be marked for deletion on normal exit of the Java Virtual Machine (even though the file may never be created); default <em>false</em>. <strong>Since Apache Ant 1.7</strong></font>
+ </td>
+ <td bgcolor="#eeeeee" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif">boolean</font>
+ </td>
+ </tr>
+ <!-- Attribute -->
+ <tr>
+ <td bgcolor="#eeeeee" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif">createfile</font>
+ </td>
+ <td bgcolor="#eeeeee" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif">Whether the temp file should be created by this task; default <em>false</em>.<strong>Since Ant 1.8</strong></font>
+ </td>
+ <td bgcolor="#eeeeee" valign="top" align="left">
+ <font color="#000000" size="-1" face="arial,helvetica,sanserif">boolean</font>
+ </td>
+ </tr>
+
+ </table>
+ </blockquote></td></tr>
+
+ </table>
+ <!-- End Attributes -->
+
+ <!-- Start Elements -->
+ <table border="0" cellspacing="0" cellpadding="2" width="100%">
+ <tr><td>&nbsp;</td></tr>
+
+ <tr><td bgcolor="#525D76">
+ <font color="#ffffff" face="arial,helvetica.sanserif">
+ <a name="elements">
+ <strong>Parameters as nested elements</strong></a></font>
+ </td></tr>
+
+ <tr><td><blockquote>
+
+ </blockquote></td></tr>
+
+ </table>
+ <!-- End Elements -->
+
+
+ </td>
+ </tr>
+ <!-- END RIGHT SIDE MAIN BODY -->
+
+</table>
+
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/touch.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/touch.html
new file mode 100644
index 00000000..263ea707
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/touch.html
@@ -0,0 +1,157 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Touch Task</title>
+</head>
+
+<body>
+
+<h2><a name="touch">Touch</a></h2>
+<h3>Description</h3>
+
+<p>Changes the modification time of a resource and possibly creates it
+at the same time. In addition to working with a single file, this Task
+can also work on <a href="../Types/resources.html">resources</a> and
+resource collections (which also includes directories). Prior to Apache Ant
+1.7 only FileSet or <a href="../Types/filelist.html">Filelist</a>
+(since Ant 1.6) have been supported.</p>
+
+<p>Ant uses the API of <code>java.io.File</code> to set the last
+ modification time which has some limitations. For example the
+ timestamp granularity depends on the operating system and sometimes
+ the operating system may allow a granularity smaller than
+ milliseconds. If you need more control you have to fall back to
+ the <code>&lt;exec&gt;</code> task and native commands.</p>
+
+<p>Starting with Ant 1.8.2 Ant will log a warning message if it fails
+ to change the file modification time. This will happen if you try
+ to change the modification time of a file you do not own on many
+ Unix systems, for example.</p>
+
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">file</td>
+ <td valign="top">The name of the file.</td>
+ <td valign="top" align="center">Unless a nested resource collection element
+ has been specified.</td>
+ </tr>
+ <tr>
+ <td valign="top">millis</td>
+ <td valign="top">Specifies the new modification time of the file
+ in milliseconds since midnight Jan 1 1970.</td>
+ <td valign="center" align="center" rowspan="2">No--datetime takes
+ precedence, however if both are omitted the current time is assumed.</td>
+ </tr>
+ <tr>
+ <td valign="top">datetime</td>
+ <td valign="top">Specifies the new modification time of the file. The
+ special value &quot;now&quot; indicates the current time
+ (now supported since Ant 1.8).</td>
+ </tr>
+ <tr>
+ <td valign="top">pattern</td>
+ <td valign="top">SimpleDateFormat-compatible pattern string.
+ Defaults to MM/DD/YYYY HH:MM AM_or_PM or MM/DD/YYYY HH:MM:SS AM_or_PM.
+ <b>Since Ant 1.6.3</b></td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">mkdirs</td>
+ <td valign="top">Whether to create nonexistent parent
+ directories when touching new files. <b>Since Ant 1.6.3</b></td>
+ <td valign="top" align="center">No, default <i>false</i>.</td>
+ </tr>
+ <tr>
+ <td valign="top">verbose</td>
+ <td valign="top">Whether to log the creation of new files.
+ <b>Since Ant 1.6.3</b></td>
+ <td valign="top" align="center">No, default <i>true</i>.</td>
+ </tr>
+</table>
+<h3>Parameters specified as nested elements</h3>
+<h4>any resource collection</h4>
+
+<p>You can use any number of nested resource collection elements to
+define the resources for this task and refer to resources defined
+elsewhere. <b>Note:</b> resources passed to this task must implement
+the <code>org.apache.tools.ant.types.resources.Touchable</code>
+interface, this is true for all filesystem-based resources like those
+returned by path, fileset ot filelist.</p>
+
+<p>For backwards compatibility directories matched by nested filesets
+will be "touched" as well, use a &lt;type&gt; selector to suppress
+this. This only applies to filesets nested into the task directly,
+not to filesets nested into a path or any other resource
+collection.</p>
+
+<h4>mapper</h4>
+<p><em>Since Ant 1.6.3,</em> a nested <a href="../Types/mapper.html">
+ mapper</a> can be specified. Files specified via nested
+ <code>fileset</code>s, <code>filelist</code>s, or the <code>file</code>
+ attribute are mapped using the specified mapper. For each file mapped,
+ the resulting files are touched. If no time has been specified and
+ the original file exists its timestamp will be used.
+ If no time has been specified and the original file does not exist the
+ current time is used. Since Ant 1.8 the task settings (<code>millis</code>,
+ and <code>datetime</code>) have priority over the timestamp of the original
+ file.</p>
+<h3>Examples</h3>
+<pre> &lt;touch file=&quot;myfile&quot;/&gt;</pre>
+<p>creates <code>myfile</code> if it doesn't exist and changes the
+modification time to the current time.</p>
+<pre> &lt;touch file=&quot;myfile&quot; datetime=&quot;06/28/2000 2:02 pm&quot;/&gt;</pre>
+<p>creates <code>myfile</code> if it doesn't exist and changes the
+modification time to Jun, 28 2000 2:02 pm (14:02 for those used to 24
+hour times).</p>
+<pre> &lt;touch datetime=&quot;09/10/1974 4:30 pm&quot;&gt;
+ &lt;fileset dir=&quot;src_dir&quot;/&gt;
+ &lt;/touch&gt;</pre>
+<p>changes the modification time to Oct, 09 1974 4:30 pm of all files and directories
+ found in <code>src_dir</code>. </p>
+<pre> &lt;touch file=&quot;myfile&quot; datetime=&quot;06/28/2000 2:02:17 pm&quot;/&gt;</pre>
+<p>creates <code>myfile</code> if it doesn't exist and changes the
+modification time to Jun, 28 2000 2:02:17 pm (14:02:17 for those used to 24
+hour times), if the filesystem allows a precision of one second - a
+time close to it otherwise.</p>
+<pre> &lt;touch file=&quot;foo&quot;&gt;
+ &lt;mapper type=&quot;glob&quot; from=&quot;foo&quot; to=&quot;bar&quot; /&gt;
+ &lt;/touch&gt;
+</pre>
+<p>creates <code>bar</code> if it doesn't exist and changes the
+modification time to that of <code>foo</code>.</p>
+
+<pre> &lt;touch file=&quot;foo&quot; datetime=&quot;now&quot;&gt;
+ &lt;mapper type=&quot;regexp&quot; from=&quot;^src(.*)\.java&quot; to=&quot;shadow\1.empty&quot; /&gt;
+ &lt;/touch&gt;
+</pre>
+<p>creates files in the <code>shadow</code> directory for every java file in the
+ <code>src</code> directory if it doesn't exist and changes the modification
+ time of those files to the current time.</p>
+
+
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/translate.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/translate.html
new file mode 100644
index 00000000..10e812a9
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/translate.html
@@ -0,0 +1,182 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Translate Task</title>
+</head>
+
+<body>
+
+<h2><a name="translate">Translate</a></h2>
+<h3>Description</h3>
+<p>Identifies keys in files delimited by special tokens
+and translates them with values read from resource bundles.
+</p>
+<p>
+A resource bundle contains locale-specific key-value pairs.
+A resource bundle is a hierarchical set of property files.
+A bundle name makes up its base family name. Each file that
+makes up this bundle has this name plus its locale. For example,
+if the resource bundle name is MyResources, the file that contains
+German text will take the name MyResources_de. In addition to
+language, country and variant are also used to form the files in
+the bundle.
+</p>
+<p>
+The resource bundle lookup searches for resource files with various
+suffixes on the basis of (1) the desired locale and (2) the default
+locale (basebundlename), in the following order from lower-level
+(more specific) to parent-level (less specific):
+</p>
+<pre>
+basebundlename + &quot;_&quot; + language1 + &quot;_&quot; + country1 + &quot;_&quot; + variant1
+basebundlename + &quot;_&quot; + language1 + &quot;_&quot; + country1
+basebundlename + &quot;_&quot; + language1
+basebundlename
+basebundlename + &quot;_&quot; + language2 + &quot;_&quot; + country2 + &quot;_&quot; + variant2
+basebundlename + &quot;_&quot; + language2 + &quot;_&quot; + country2
+basebundlename + &quot;_&quot; + language2
+</pre>
+<p>
+The file names generated thus are appended with the string &quot;.properties&quot;
+to make up the file names that are to be used.
+</p>
+<p>
+File encoding is supported. The encoding scheme of the source files,
+destination files and the bundle files can be specified.
+
+Destination files can be explicitly overwritten using the
+<var>forceoverwrite</var> attribute. If <var>forceoverwrite</var>
+is false, the destination file is overwritten only if either the
+source file or any of the files that make up the bundle have been
+modified after the destination file was last modified.
+</p>
+<p>
+<em>New in Apache Ant 1.6:</em><br>
+Line endings of source files are preserved in the translated files.
+</p>
+<p><a href="../Types/fileset.html">FileSet</a>s are used to select files to
+translate.
+</p>
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">todir</td>
+ <td valign="top">Destination directory where destination files are
+ to be created.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">starttoken</td>
+ <td valign="top">The starting token to identify keys.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">endtoken</td>
+ <td valign="top">The ending token to identify keys.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">bundle</td>
+ <td valign="top">Family name of resource bundle.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">bundlelanguage</td>
+ <td valign="top">
+ Locale specific language of resource bundle. Defaults to
+ default locale's language.
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">bundlecountry</td>
+ <td valign="top">
+ Locale specific country of resource bundle. Defaults to
+ default locale's country.
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">bundlevariant</td>
+ <td valign="top">
+ Locale specific variant of resource bundle. Defaults to
+ the default variant of the country and language being used.
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">srcencoding</td>
+ <td valign="top">Source file encoding scheme. Defaults to
+ system default file encoding.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">destencoding</td>
+ <td valign="top">Destination file encoding scheme. Defaults to
+ source file encoding.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">bundleencoding</td>
+ <td valign="top">Resource Bundle file encoding scheme. Defaults to
+ source file encoding.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">forceoverwrite</td>
+ <td valign="top">Overwrite existing files even if the destination
+ files are newer. Defaults to &quot;no&quot;.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+</table>
+<h3>Parameters specified as nested elements</h3>
+
+<h4>fileset</h4>
+ <p><a href="../Types/fileset.html">FileSets</a> are used to select files that
+ contain keys for which value translated files are to be generated.
+</p>
+<h3>Examples</h3>
+<p><b>Translate source file encoded in english into its japanese
+equivalent using a resource bundle encoded in japanese.
+</b></p>
+<pre>
+ &lt;translate toDir=&quot;$(dest.dir}/ja&quot;
+ starttoken=&quot;#&quot;
+ endtoken=&quot;#&quot;
+ bundle=&quot;resource/BaseResource&quot;
+ bundlelanguage=&quot;ja&quot;
+ forceoverwrite=&quot;yes&quot;
+ srcencoding=&quot;ISO8859_1&quot;
+ destencoding=&quot;SJIS&quot;
+ bundleencoding=&quot;SJIS&quot;&gt;
+ &lt;fileset dir=&quot;${src.dir}&quot;&gt;
+ &lt;include name=&quot;**/*.jsp&quot;/&gt;
+ &lt;/fileset&gt;
+ &lt;/translate&gt;
+</pre>
+
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/truncate.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/truncate.html
new file mode 100644
index 00000000..b7df3f7e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/truncate.html
@@ -0,0 +1,109 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Truncate Task</title>
+</head>
+
+<body>
+
+<h2><a name="touch">Truncate</a></h2>
+<h3>Description</h3>
+
+<p>Set the length of one or more files, as the intermittently available
+<code>truncate</code> Unix utility/function. In addition to working with
+a single file, this Task can also work on
+<a href="../Types/resources.html">resources</a> and resource collections.
+<strong>Since Apache Ant 1.7.1</strong>.
+</p>
+
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">file</td>
+ <td valign="top">The name of the file.</td>
+ <td valign="top" align="center">Unless a nested resource collection element
+ has been specified.</td>
+ </tr>
+ <tr>
+ <td valign="top">length</td>
+ <td valign="top">Specifies the new file length (in bytes) to set.
+ The following suffixes are supported:
+ <ul>
+ <li>K : Kilobytes (1024 bytes)</li>
+ <li>M : Megabytes (1024 K)</li>
+ <li>G : Gigabytes (1024 M)</li>
+ <li>T : Terabytes (1024 G)</li>
+ <li>P : Petabytes (1024 T)</li>
+ </ul>
+ </td>
+ <td valign="center" align="center" rowspan="2">At most one of these.
+ Omitting both implies <code>length="0"</code>.
+ </td>
+ </tr>
+ <tr>
+ <td valign="top">adjust</td>
+ <td valign="top">Specifies the number of bytes
+ (and positive/negative direction)
+ by which to adjust file lengths. The same suffixes are supported
+ for this attribute as for the <code>length</code> attribute.
+ </td>
+ </tr>
+ <tr>
+ <td valign="top">create</td>
+ <td valign="top">Whether to create nonexistent files.</td>
+ <td valign="top" align="center">No, default <i>true</i>.</td>
+ </tr>
+ <tr>
+ <td valign="top">mkdirs</td>
+ <td valign="top">Whether to create nonexistent parent
+ directories when creating new files.</td>
+ <td valign="top" align="center">No, default <i>false</i>.</td>
+ </tr>
+</table>
+<h3>Parameters specified as nested elements</h3>
+<h4>any resource collection</h4>
+
+<p>You can use any number of nested resource collection elements to
+define the resources for this task and refer to resources defined
+elsewhere. <b>Note:</b> resources passed to this task are expected
+to be filesystem-based.</p>
+
+<h3>Examples</h3>
+
+<pre> &lt;truncate file="foo" /&gt;</pre>
+<p>Sets the length of file <code>foo</code> to zero.</p>
+
+<pre> &lt;truncate file="foo" length="1K" /&gt;</pre>
+<p>Sets the length of file <code>foo</code> to 1 kilobyte (1024 bytes).</p>
+
+<pre> &lt;truncate file="foo" adjust="1K" /&gt;</pre>
+<p>Adjusts the length of file <code>foo</code> upward by 1 kilobyte.</p>
+
+<pre> &lt;truncate file="foo" adjust="-1M" /&gt;</pre>
+<p>Adjusts the length of file <code>foo</code> downward by 1 megabyte.</p>
+
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/tstamp.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/tstamp.html
new file mode 100644
index 00000000..82812a57
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/tstamp.html
@@ -0,0 +1,161 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>TStamp Task</title>
+</head>
+
+<body>
+
+<h2><a name="tstamp">Tstamp</a></h2>
+
+<h3>Description</h3>
+<p>Sets the <code>DSTAMP</code>, <code>TSTAMP</code>, and <code>TODAY</code>
+properties in the current project. By default,
+the <code>DSTAMP</code> property is in the
+format &quot;yyyyMMdd&quot;, <code>TSTAMP</code> is in the
+format &quot;hhmm&quot;, and <code>TODAY</code> is in the
+format &quot;MMMM dd yyyy&quot;. Use the nested <code>&lt;format&gt;</code> element
+to specify a different format.</p>
+
+<p>These properties can be used in the build-file, for instance, to create
+time-stamped filenames, or used to replace placeholder tags inside documents
+to indicate, for example, the release date. The best place for this task is
+probably in an initialization target.</p>
+
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">prefix</td>
+ <td valign="top">Prefix used for all properties set. The default is no prefix.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+</table>
+
+<h3>Nested Elements</h3>
+The Tstamp task supports a <code>&lt;format&gt;</code> nested element that
+allows a property to be set to the current date and time in a given format.
+The date/time patterns are as defined in the Java
+<a href="http://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html">SimpleDateFormat</a> class.
+The format element also allows offsets to be applied to the time to generate different time values.
+<br><br>
+<table width="60%" border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">property</td>
+ <td valign="top">
+ The property to receive the date/time string in the given pattern.
+ </td>
+ <td align="center" valign="top">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">pattern</td>
+ <td valign="top">The date/time pattern to be used. The values are as defined by the Java SimpleDateFormat class.</td>
+ <td align="center" valign="top">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">timezone</td>
+ <td valign="top">The timezone to use for displaying time. The values are as defined by the Java <a href="http://docs.oracle.com/javase/7/docs/api/java/util/TimeZone.html">TimeZone</a> class.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">offset</td>
+ <td valign="top">The numeric offset to the current time</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">unit</td>
+ <td valign="top">The unit of the offset to be applied to the current time.
+ Valid Values are
+ <ul>
+ <li>millisecond</li>
+ <li>second</li>
+ <li>minute</li>
+ <li>hour</li>
+ <li>day</li>
+ <li>week</li>
+ <li>month</li>
+ <li>year</li>
+ </ul>
+ </td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">locale</td>
+ <td valign="top">The locale used to create date/time string. The general
+ form is &quot;language, country, variant&quot; but either variant or variant and
+ country may be omitted. For more information please refer to documentation
+ for the
+ <a href="http://docs.oracle.com/javase/7/docs/api/java/util/Locale.html">Locale</a>
+ class.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+</table>
+
+<h3>Examples</h3>
+
+<pre>
+ &lt;tstamp/&gt;
+</pre>
+
+<p>
+sets the standard <code>DSTAMP</code>, <code>TSTAMP</code>,
+and <code>TODAY</code> properties according to the default formats.</p>
+<pre>
+ &lt;tstamp&gt;
+ &lt;format property=&quot;TODAY_GB&quot; pattern=&quot;d-MMMM-yyyy&quot; locale=&quot;en,GB&quot;/&gt;
+ &lt;/tstamp&gt;
+</pre>
+<p>
+sets the standard properties as well as the property
+<code>TODAY_UK</code> with the date/time pattern &quot;d-MMMM-yyyy&quot;
+using English locale (eg. 21-May-2001).</p>
+
+<pre>
+ &lt;tstamp&gt;
+ &lt;format property=&quot;touch.time&quot; pattern=&quot;MM/dd/yyyy hh:mm aa&quot;
+ offset=&quot;-5&quot; unit=&quot;hour&quot;/&gt;
+ &lt;/tstamp&gt;
+</pre>
+<p>
+Creates a timestamp, in the property touch.time, 5 hours before the current time. The format in this example
+is suitable for use with the <code>&lt;touch&gt;</code> task. The standard properties are set also.</p>
+
+<pre>
+ &lt;tstamp prefix="start"/&gt;
+</pre>
+<p>
+Sets three properties with the standard formats, prefixed with "start.":
+<code>start.DSTAMP</code>, <code>start.TSTAMP</code>, and <code>start.TODAY</code>.</p>
+
+
+
+
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/typedef.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/typedef.html
new file mode 100644
index 00000000..bdd58a7f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/typedef.html
@@ -0,0 +1,269 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Typedef Task</title>
+</head>
+
+<body>
+
+<h2><a name="typedef">Typedef</a></h2>
+<h3>Description</h3>
+ <p>
+ Adds a task or a data type definition to the current project
+ such that this new type or task can be used in the current project.
+ </p>
+ <p>
+ A Task is any class that extends org.apache.tools.ant.Task or
+ can be adapted as a Task using an adapter class.
+ </p>
+ <p>
+ Data types are things like <a href="../using.html#path">paths</a> or
+ <a href="../Types/fileset.html">filesets</a> that can be defined at
+ the project level and referenced via their ID attribute.
+ Custom data types usually need custom tasks to put them to good use.
+ </p>
+ <p>
+ Two attributes are needed to make a definition: the name that
+ identifies this data type uniquely, and the full name of the class
+ (including its package name) that implements this type.
+ </p>
+ <p>
+ You can also define a group of definitions at once using the file or
+ resource attributes. These attributes point to files in the format of
+ Java property files or an xml format.
+ </p>
+ <p>
+ For property files each line defines a single data type in the
+ format:</p>
+ <pre>
+ typename=fully.qualified.java.classname
+ </pre>
+
+ <p>
+ The xml format is described in the
+ <a href="../Types/antlib.html">Antlib</a> section.
+ </p>
+
+ <p>If you are defining tasks or types that share the same classpath
+ with multiple taskdef or typedef tasks, the corresponding classes
+ will be loaded by different
+ Java <a href="http://docs.oracle.com/javase/7/docs/api/java/lang/ClassLoader.html">ClassLoaders</a>.
+ Two classes with the same name loaded via different ClassLoaders
+ are not the same class from the point of view of the Java VM, they
+ don't share static variables and instances of these classes can't
+ access private methods or attributes of instances defined by "the
+ other class" of the same name. They don't even belong to the same
+ Java package and can't access package private code, either.</p>
+
+ <p>The best way to load several tasks/types that are supposed to
+ cooperate with each other via shared Java code is to use the
+ resource attribute and an antlib descriptor. If this is not
+ possible, the second best option is to use the loaderref attribute
+ and specify the same name for each and every typedef/taskdef -
+ this way the classes will share the same ClassLoader. Note that
+ the typedef/taskdef tasks must use identical classpath definitions
+ (this includes the order of path components) for the loaderref
+ attribute to work.</p>
+
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">name</td>
+ <td valign="top">the name of the data type</td>
+ <td valign="top" align="center">Yes, unless the file or resource type
+ attributes have been specified.</td>
+ </tr>
+ <tr>
+ <td valign="top">classname</td>
+ <td valign="top">the full class name implementing the data type</td>
+ <td valign="top" align="center">Yes, unless file or resource
+ have been specified.</td>
+ </tr>
+ <tr>
+ <td valign="top">file</td>
+ <td valign="top">Name of the file to load definitions from.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">resource</td>
+ <td valign="top">
+ Name of the resource to load definitions from.
+ If multiple resources by this name are found along the classpath,
+ and the format is "properties", the first resource will be loaded;
+ otherwise all such resources will be loaded.
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">format</td>
+ <td valign="top">The format of the file or resource. The values
+ are "properties" or "xml". If the value is "properties" the file/resource
+ is a property file contains name to classname pairs. If the value
+ is "xml", the file/resource is an xml file/resource structured according
+ to <a href="../Types/antlib.html">Antlib</a>.
+ The default is "properties" unless the file/resource name ends with
+ ".xml", in which case the format attribute will have the value "xml".
+ <b>since Apache Ant 1.6</b>
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">classpath</td> <td valign="top">the classpath to
+ use when looking up <code>classname</code>.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">classpathref</td>
+ <td valign="top">
+ a reference to a classpath to use when looking up <code>classname</code>.
+ </td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">loaderRef</td>
+ <td valign="top">the name of the loader that is
+ used to load the class, constructed from the specified classpath. Use
+ this to allow multiple tasks/types to be loaded with the same loader,
+ so they can call each other. <b>since Ant 1.5</b> </td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">onerror</td>
+ <td valign="top">The action to take if there was a failure in defining the
+ type. The values are <i>fail</i>: cause a build exception; <i>report</i>:
+ output a warning, but continue; <i>ignore</i>: do nothing.
+ <b>since Ant 1.6</b>
+ An additional value is <i>failall</i>: cause all behavior of fail,
+ as well as a build exception for the resource or file attribute
+ if the resource or file is not found. <b>since Ant 1.7</b>
+ The default is <i>fail</i>.
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">adapter</td>
+ <td valign="top">A class that is used to adapt the defined class to
+ another interface/class. The adapter class must implement the interface
+ "org.apache.tools.ant.TypeAdapter". The adapter class will be used
+ to wrap the defined class unless the defined class implements/extends
+ the class defined by the attribute "adaptto".
+ If "adaptto" is not set, the defined class will always be wrapped.
+ <b>since Ant 1.6</b>
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">adaptto</td>
+ <td valign="top">This attribute is used in conjunction with the
+ adapter attribute.
+ If the defined class does not implement/extend the interface/class
+ specified by this attribute, the adaptor class will be used
+ to wrap the class. <b>since Ant 1.6</b>
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">uri</td>
+ <td valign="top">
+ The uri that this definition should live in.
+ <b>since Ant 1.6</b>
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+</table>
+ <h3>Parameters specified as nested elements</h3>
+ <h4>classpath</h4>
+ <p><code>Typedef</code>'s <i>classpath</i> attribute is a
+ <a href="../using.html#path">path-like structure</a> and can also be set
+ via a nested <i>classpath</i> element.</p>
+
+<h3>Examples</h3>
+ The following fragment defines define a type called <i>urlset</i>.
+ <pre>
+ &lt;typedef name="urlset" classname="com.mydomain.URLSet"/&gt; </pre>
+ The data type is now available to Ant. The
+ class <code>com.mydomain.URLSet</code> implements this type.</p>
+
+
+ <p>
+ Assuming a class <i>org.acme.ant.RunnableAdapter</i> that
+ extends Task and implements <i>org.apache.tools.ant.TypeAdapter</i>,
+ and in the execute method invokes <i>run</i> on the proxied object,
+ one may use a Runnable class as an Ant task. The following fragment
+ defines a task called <i>runclock</i>.
+ </p>
+ <pre>
+ &lt;typedef name="runclock"
+ classname="com.acme.ant.RunClock"
+ adapter="org.acme.ant.RunnableAdapter"/&gt;
+ </pre>
+
+
+ <p>
+ The following fragment shows the use of the classpathref and
+ loaderref to load up two definitions.
+ </p>
+ <pre>
+ &lt;path id="lib.path"&gt;
+ &lt;fileset dir="lib" includes="lib/*.jar"/&gt;
+ &lt;/path&gt;
+
+ &lt;typedef name="filter1"
+ classname="org.acme.filters.Filter1"
+ classpathref="lib.path"
+ loaderref="lib.path.loader"
+ /&gt;
+ &lt;typedef name="filter2"
+ classname="org.acme.filters.Filter2"
+ loaderref="lib.path.loader"
+ /&gt;
+ </pre>
+
+
+ <p>
+ If you want to load an antlib into a special xml-namespace, the <tt>uri</tt> attribute
+ is important:
+ </p>
+ <pre>
+ &lt;project xmlns:antcontrib="antlib:net.sf.antcontrib"&gt;
+ &lt;taskdef uri="antlib:net.sf.antcontrib"
+ resource="net/sf/antcontrib/antlib.xml"
+ classpath="path/to/ant-contrib.jar"/&gt;
+ </pre>
+
+<p>Here the namespace
+ declaration <code>xmlns:antcontrib="antlib:net.sf.antcontrib"</code>
+ allows tasks and types of the AntContrib Antlib to be used with the
+ <code>antcontrib</code> prefix
+ like <code>&lt;antcontrib:if&gt;</code>.
+ The normal rules of XML namespaces apply and you can declare the
+ prefix at any element to make it usable for the element it is
+ declared on as well as all its child elements.</p>
+
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/unpack.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/unpack.html
new file mode 100644
index 00000000..dcc88a9a
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/unpack.html
@@ -0,0 +1,117 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>GUnzip/BUnzip2 Task</title>
+</head>
+
+<body>
+
+<h2><a name="unpack">GUnzip/BUnzip2</a></h2>
+<h3>Description</h3>
+<p>Expands a resource packed using GZip or BZip2.</p>
+
+<p>If <i>dest</i> is a directory the name of the destination file is
+the same as <i>src</i> (with the &quot;.gz&quot; or &quot;.bz2&quot;
+extension removed if present). If <i>dest</i> is omitted, the parent
+dir of <i>src</i> is taken. The file is only expanded if the source
+resource is newer than the destination file, or when the destination file
+does not exist.</p>
+
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">src</td>
+ <td valign="top">the file to expand.</td>
+ <td align="center" valign="top">Yes, or a nested resource collection.</td>
+ </tr>
+ <tr>
+ <td valign="top">dest</td>
+ <td valign="top">the destination file or directory.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+</table>
+<h3>Parameters specified as nested elements</h3>
+
+<h4>any <a href="../Types/resources.html">resource</a> or single element
+resource collection</h4>
+
+<p>The specified resource will be used as src.</p>
+
+<h3>Examples</h3>
+<blockquote><pre>
+&lt;gunzip src=&quot;test.tar.gz&quot;/&gt;
+</pre></blockquote>
+<p>expands <i>test.tar.gz</i> to <i>test.tar</i></p>
+<blockquote><pre>
+&lt;bunzip2 src=&quot;test.tar.bz2&quot;/&gt;
+</pre></blockquote>
+<p>expands <i>test.tar.bz2</i> to <i>test.tar</i></p>
+<blockquote><pre>
+&lt;gunzip src=&quot;test.tar.gz&quot; dest=&quot;test2.tar&quot;/&gt;
+</pre></blockquote>
+<p>expands <i>test.tar.gz</i> to <i>test2.tar</i></p>
+<blockquote><pre>
+&lt;gunzip src=&quot;test.tar.gz&quot; dest=&quot;subdir&quot;/&gt;
+</pre></blockquote>
+<p>expands <i>test.tar.gz</i> to <i>subdir/test.tar</i> (assuming
+subdir is a directory).</p>
+<blockquote><pre>
+&lt;gunzip dest=&quot;.&quot;&gt;
+ &lt;url url="http://example.org/archive.tar.gz"/&gt;
+&lt;/gunzip&gt;
+</pre></blockquote>
+<p>downloads <i>http://example.org/archive.tar.gz</i> and expands it
+to <i>archive.tar</i> in the project's basedir on the fly.</p>
+
+<h3>Related tasks</h3>
+
+<pre>
+&lt;gunzip src="some-archive.gz" dest="some-dest-dir"/&gt;
+</pre>
+
+is identical to
+
+<pre>
+&lt;copy todir="some-dest-dir"&gt;
+ &lt;gzipresource&gt;
+ &lt;file file="some-archive.gz"/&gt;
+ &lt;/gzipresource&gt;
+ &lt;mapper type="glob" from="*.gz" to="*"/&gt;
+&lt;/copy&gt;
+</pre>
+
+<p>The same is also true for <code>&lt;bunzip2&gt;</code> and
+<code>&lt;bzip2resource&gt;</code>. <code>&lt;copy&gt;</code> offers
+additional features like <a
+href="../Types/filterchain.html">filtering files</a> on the fly,
+allowing a file to be mapped to multiple destinations, preserving the
+last modified time or a configurable file system timestamp
+granularity.</p>
+
+
+
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/untar.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/untar.html
new file mode 100644
index 00000000..bfaf28f1
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/untar.html
@@ -0,0 +1,35 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Untar Task</title>
+</head>
+
+<body>
+
+<h2><a name="untar">Untar</a></h2>
+<h3>Description</h3>
+<p>Untars a tarfile.</p>
+
+This document has moved <A HREF="unzip.html">here</A>
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/unzip.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/unzip.html
new file mode 100644
index 00000000..8d93b704
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/unzip.html
@@ -0,0 +1,244 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Unzip Task</title>
+</head>
+
+<body>
+
+<h2><a name="unzip">Unjar/Untar/Unwar/Unzip</a></h2>
+<h3>Description</h3>
+<p>Unzips a zip-, war-, or jar file.</p>
+<p><a href="../Types/patternset.html">PatternSet</a>s are used to select files to extract
+<I>from</I> the archive. If no patternset is used, all files are extracted.
+</p>
+
+<p><a href="../Types/resources.html#collection">Resource
+Collection</a>s may be used to select archived files to perform
+unarchival upon. Only file system based resource collections are
+supported by Unjar/Unwar/Unzip, this includes <a
+href="../Types/fileset.html">fileset</a>, <a
+href="../Types/filelist.html">filelist</a>, <a
+href="../using.html#path">path</a>, and <a
+href="../Types/resources.html#files">files</a>.
+Untar supports arbitrary resource collections.
+Prior to Apache Ant 1.7 only fileset has been supported as a nested element.</p>
+
+<p>You can define filename transformations by using a nested <a href="../Types/mapper.html">mapper</a> element. The default mapper is the
+<a href="../Types/mapper.html#identity-mapper">identity mapper</a>.
+</p>
+<p>File permissions will not be restored on extracted files.</p>
+<p>The untar task recognizes the long pathname entries used by GNU tar.<p>
+
+<p><b>Please note</b> that different ZIP tools handle timestamps
+differently when it comes to applying timezone offset calculations of
+files. Some ZIP libraries will store the timestamps as they've been
+read from the filesystem while others will modify the timestamps both
+when reading and writing the files to make all timestamps use the same
+timezone. A ZIP archive created by one library may extract files with
+"wrong timestamps" when extracted by another library.</p>
+
+<p>Ant's ZIP classes use the same algorithm as the InfoZIP tools and
+zlib (timestamps get adjusted), Windows' "compressed folders" function
+and WinZIP don't change the timestamps. This means that using the
+unzip task on files created by Windows' compressed folders function
+may create files with timestamps that are "wrong", the same is true if
+you use Windows' functions to extract an Ant generated ZIP
+archive.</p>
+
+
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">src</td>
+ <td valign="top">archive file to expand.</td>
+ <td align="center" valign="top">Yes, if filesets are not used.</td>
+ </tr>
+ <tr>
+ <td valign="top">dest</td>
+ <td valign="top">directory where to store the expanded files.</td>
+ <td align="center" valign="top">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">overwrite</td>
+ <td valign="top">Overwrite files, even if they are newer than the
+ corresponding entries in the archive (true or false, default is
+ true).</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">compression</td>
+ <td valign="top"><b>Note:</b> This attribute is only available for
+ the <code>untar</code> task.<br>
+ compression method. Allowable values are &quot;none&quot;,
+ &quot;gzip&quot; and &quot;bzip2&quot;. Default is
+ &quot;none&quot;.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">encoding</td>
+ <td valign="top">
+ The character encoding that has been used for filenames
+ inside the zip file. For a list of possible values see the <a
+ href="http://docs.oracle.com/javase/7/docs/technotes/guides/intl/encoding.doc.html">Supported Encodings</a>.<br/>
+ Defaults to &quot;UTF8&quot; for the <code>unzip</code> and the
+ platform's default encoding for the <code>untar</code> task. Use
+ the magic value
+ <code>native-encoding</code> for the platform's default character
+ encoding.
+ <br/>See also the <a href="zip.html#encoding">discussion in the
+ zip task page</a></td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">failOnEmptyArchive</td>
+ <td valign="top">whether trying to extract an empty archive is an
+ error. <em>since Ant 1.8.0</em></td>
+ <td valign="top" align="center">No, defaults to false</td>
+ </tr>
+ <tr>
+ <td valign="top">stripAbsolutePathSpec</td>
+ <td valign="top">whether Ant should remove leading '/' or '\'
+ characters from the extracted file name before extracting it.
+ Note that this changes the entry's name before applying
+ include/exclude patterns and before using the nested mappers (if
+ any). <em>since Ant 1.8.0</em></td>
+ <td valign="top" align="center">No, defaults to false</td>
+ </tr>
+ <tr>
+ <td valign="top">scanForUnicodeExtraFields</td>
+ <td valign="top"><b>Note:</b> This attribute is not available for
+ the <code>untar</code> task.<br>
+ If the archive contains uncode extra fields then use them to set
+ the file names, ignoring the specified encoding.
+ <br/>See also the <a href="zip.html#encoding">discussion in the
+ zip task page</a></td>
+ <td align="center" valign="top">No, defaults to true</td>
+ </tr>
+</table>
+<h3>Examples</h3>
+<pre>
+&lt;unzip src=&quot;${tomcat_src}/tools-src.zip&quot; dest=&quot;${tools.home}&quot;/&gt;
+</pre>
+<p>
+<pre>
+&lt;gunzip src=&quot;tools.tar.gz&quot;/&gt;
+&lt;untar src=&quot;tools.tar&quot; dest=&quot;${tools.home}&quot;/&gt;
+</pre>
+<pre>
+&lt;unzip src=&quot;${tomcat_src}/tools-src.zip&quot;
+ dest=&quot;${tools.home}&quot;&gt;
+ &lt;patternset&gt;
+ &lt;include name=&quot;**/*.java&quot;/&gt;
+ &lt;exclude name=&quot;**/Test*.java&quot;/&gt;
+ &lt;/patternset&gt;
+&lt;/unzip&gt;
+</pre>
+<p>
+<pre>
+&lt;unzip dest=&quot;${tools.home}&quot;&gt;
+ &lt;patternset&gt;
+ &lt;include name=&quot;**/*.java&quot;/&gt;
+ &lt;exclude name=&quot;**/Test*.java&quot;/&gt;
+ &lt;/patternset&gt;
+ &lt;fileset dir=&quot;.&quot;&gt;
+ &lt;include name=&quot;**/*.zip&quot;/&gt;
+ &lt;exclude name=&quot;**/tmp*.zip&quot;/&gt;
+ &lt;/fileset&gt;
+&lt;/unzip&gt;
+</pre>
+<p>
+<pre>
+&lt;unzip src=&quot;apache-ant-bin.zip&quot; dest=&quot;${tools.home}&quot;&gt;
+ &lt;patternset&gt;
+ &lt;include name=&quot;apache-ant/lib/ant.jar&quot;/&gt;
+ &lt;/patternset&gt;
+ &lt;mapper type=&quot;flatten&quot;/&gt;
+&lt;/unzip&gt;
+</pre>
+
+<h3>Related tasks</h3>
+
+<pre>
+&lt;unzip src="some-archive" dest="some-dir"&gt;
+ &lt;patternset&gt;
+ &lt;include name="some-pattern"/&gt;
+ &lt;/patternset&gt;
+ &lt;mapper type=&quot;some-mapper&quot;/&gt;
+&lt;/unzip&gt;
+</pre>
+
+is identical to
+
+<pre>
+&lt;copy todir="some-dir" preservelastmodified="true"&gt;
+ &lt;zipfileset src="some-archive"&gt;
+ &lt;patternset&gt;
+ &lt;include name="some-pattern"/&gt;
+ &lt;/patternset&gt;
+ &lt;/zipfileset&gt;
+ &lt;mapper type=&quot;some-mapper&quot;/&gt;
+&lt;/copy&gt;
+</pre>
+
+<p>The same is also true for <code>&lt;untar&gt;</code> and
+<code>&lt;tarfileset&gt;</code>. <code>&lt;copy&gt;</code> offers
+additional features like <a href="../Types/filterchain.html">filtering files</a> on the fly,
+allowing a file to be mapped to multiple destinations or a
+configurable file system timestamp granularity.</p>
+
+<pre>&lt;zip destfile=&quot;new.jar&quot;&gt;
+ &lt;zipfileset src=&quot;old.jar&quot;&gt;
+ &lt;exclude name=&quot;do/not/include/this/class&quot;/&gt;
+ &lt;/zipfileset&gt;
+&lt;/zip&gt;
+</pre>
+<p>&quot;Deletes&quot; files from a zipfile.</p>
+
+<pre>
+&lt;unzip src=&quot;${ant.home}/lib/ant.jar&quot; dest=&quot;...&quot;&gt;
+ &lt;patternset&gt;
+ &lt;include name=&quot;images/&quot;/&gt;
+ &lt;/patternset&gt;
+&lt;/unzip&gt;
+</pre>
+<p>This extracts all images from <tt>ant.jar</tt> which are stored in the <tt>images</tt> directory
+of the Jar (or somewhere under it). While extracting the directory structure (<tt>images</tt>)
+will be taken.</p>
+
+<pre>
+&lt;unzip src=&quot;${ant.home}/lib/ant.jar&quot; dest=&quot;...&quot;&gt;
+ &lt;patternset&gt;
+ &lt;include name=&quot;**/ant_logo_large.gif&quot;/&gt;
+ &lt;include name=&quot;**/LICENSE.txt&quot;/&gt;
+ &lt;/patternset&gt;
+&lt;/unzip&gt;
+</pre>
+<p>This extracts the two files <tt>ant_logo_large.gif</tt> and <tt>LICENSE.txt</tt> from the
+<tt>ant.jar</tt>. More exactly: it extracts all files with these names from anywhere in the source file. While extracting the directory structure will be taken.</p>
+
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/uptodate.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/uptodate.html
new file mode 100644
index 00000000..c724f206
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/uptodate.html
@@ -0,0 +1,177 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Uptodate Task</title>
+</head>
+
+<body>
+
+<h2><a name="uptodate">Uptodate</a></h2>
+<h3>Description</h3>
+<p>Sets a property if a target file or set of target files is more up-to-date
+than a source file or set of source files. A single source file is specified
+using the <code>srcfile</code> attribute. A set of source files is specified
+using the nested <code>&lt;srcfiles&gt;</code>
+elements. These are <a href="../Types/fileset.html">FileSet</a>s,
+whereas multiple target files are specified using a nested
+<a href="../Types/mapper.html"><code>&lt;mapper&gt;</code></a> element.</p>
+<p>By default, the value of the property is set to <code>true</code> if
+the timestamp of the source file(s) is not more recent than the timestamp of
+the corresponding target file(s). You can set the value to something other
+than the default by specifying the <code>value</code> attribute.</p>
+<p>If a <code>&lt;srcfiles&gt;</code> element is used, without also specifying
+a <code>&lt;mapper&gt;</code> element, the default behavior is to use a
+<a href="../Types/mapper.html#merge-mapper">merge mapper</a>, with the
+<code>to</code> attribute set to the value of the
+<code>targetfile</code> attribute.</p>
+<p>Normally, this task is used to set properties that are useful to avoid
+target execution depending on the relative age of the specified files.</p>
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">property</td>
+ <td valign="top">The name of the property to set.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">value</td>
+ <td valign="top">The value to set the property to.</td>
+ <td valign="top" align="center">No; defaults to <code>true</code>.</td>
+ </tr>
+ <tr>
+ <td valign="top">srcfile</td>
+ <td valign="top">The file to check against the target file(s).</td>
+ <td valign="top" align="center">Yes, unless a nested
+ <code>&lt;srcfiles&gt;</code> or <code>&lt;srcresources&gt;</code>
+ element is present.</td>
+ </tr>
+ <tr>
+ <td valign="top">targetfile</td>
+ <td valign="top">The file for which we want to determine the status.</td>
+ <td valign="top" align="center">Yes, unless a nested
+ <code>&lt;mapper&gt;</code> element is present.</td>
+ </tr>
+</table>
+
+<h3>Parameters specified as nested elements</h3>
+<h4><a name="srcfiles">srcfiles</a></h4>
+<p>The nested <code>&lt;srcfiles&gt;</code> element is a
+<a href="../Types/fileset.html">fileset</a> and allows you to
+specify a set of files to check against the target file(s).</p>
+
+<p><strong>Note:</strong> You can specify either the <code>srcfile</code>
+attribute or nested <code>&lt;srcfiles&gt;</code> elements, but not both.
+
+<p>Note that the task will completely ignore any directories that seem
+ to be matched by the srcfiles fileset, it will only consider normal
+ files. If you need logic that applies to directories as well, use a
+ nested srcresource and a dirset (for example).</p>
+
+<h4><a name="srcresources">srcresources</a></h4>
+<p>The nested <code>&lt;srcresources&gt;</code> element is a <a
+href="../Types/resources.html#union">union</a> and allows you to
+specify a collection of resources to check against the target file(s).
+<em>Since Apache Ant 1.7</em></p>
+
+<h4><a name="mapper">mapper</a></h4>
+<p>The nested <code>&lt;mapper&gt;</code> element allows you to specify
+a set of target files to check for being up-to-date with respect to a
+set of source files.</p>
+ <p>
+ The mapper "to" attribute is relative to the target file, or to
+ the "dir" attribute of the nested srcfiles element.
+ </p>
+ <p>
+ <em>Since Ant 1.6.3</em>,
+ one can use a filenamemapper type in place of the mapper element.
+ </p>
+<h3>Examples</h3>
+<pre> &lt;uptodate property=&quot;xmlBuild.notRequired&quot; targetfile=&quot;${deploy}\xmlClasses.jar&quot; &gt;
+ &lt;srcfiles dir= &quot;${src}/xml&quot; includes=&quot;**/*.dtd&quot;/&gt;
+ &lt;/uptodate&gt;</pre>
+<p>sets the property <code>xmlBuild.notRequired</code> to <code>true</code>
+if the <code>${deploy}/xmlClasses.jar</code> file is more up-to-date than
+any of the DTD files in the <code>${src}/xml</code> directory.</p>
+<p>This can be written as:</p>
+<pre> &lt;uptodate property=&quot;xmlBuild.notRequired&quot;&gt;
+ &lt;srcfiles dir= &quot;${src}/xml&quot; includes=&quot;**/*.dtd&quot;/&gt;
+ &lt;mapper type=&quot;merge&quot; to=&quot;${deploy}\xmlClasses.jar&quot;/&gt;
+ &lt;/uptodate&gt;</pre>
+as well.
+
+The <code>xmlBuild.notRequired</code> property can then be used in a
+<code>&lt;target&gt;</code> tag's <code>unless</code> attribute to
+conditionally run that target. For example, running the following target:</p>
+<pre>
+&lt;target name=&quot;xmlBuild&quot; depends=&quot;chkXmlBuild&quot; unless=&quot;xmlBuild.notRequired&quot;&gt;
+ ...
+&lt;/target&gt;
+</pre>
+will first run the <code>chkXmlBuild</code> target, which contains
+the <code>&lt;uptodate&gt;</code> task that determines whether
+<code>xmlBuild.notRequired</code> gets set. The property named in
+the <code>unless</code> attribute is then checked for being set/not set.
+If it did get set (ie., the jar file is up-to-date),
+then the <code>xmlBuild</code> target won't be run.
+</p>
+
+<p> The following example shows a single source file being checked
+against a single target file:</p>
+<pre> &lt;uptodate property=&quot;isUpToDate&quot;
+ srcfile=&quot;/usr/local/bin/testit&quot;
+ targetfile=&quot;${build}/.flagfile&quot;/&gt;
+</pre>
+<p>sets the property <code>isUpToDate</code> to <code>true</code>
+if <code>/usr/local/bin/testit</code> is not newer than
+<code>${build}/.flagfile</code>.</p>
+</p>
+ <p>
+ The following shows usage of a relative mapper.
+ </p>
+ <pre>
+ &lt;uptodate property="checkUptodate.uptodate"&gt;
+ &lt;srcfiles dir="src" includes="*"/&gt;
+ &lt;mapper type="merge" to="../dest/output.done"/&gt;
+ &lt;/uptodate&gt;
+ &lt;echo message="checkUptodate result: ${checkUptodate.uptodate}"/&gt;
+ </pre>
+ <p>
+ The previous example can be a bit confusing, so it may be better to
+ use absolute paths:
+ </p>
+ <pre>
+ &lt;property name="dest.dir" location="dest"/&gt;
+ &lt;uptodate property="checkUptodate.uptodate"&gt;
+ &lt;srcfiles dir="src" includes="*"/&gt;
+ &lt;mapper type="merge" to="${dest.dir}/output.done"/&gt;
+ &lt;/uptodate&gt;
+ </pre>
+
+
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/verifyjar.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/verifyjar.html
new file mode 100644
index 00000000..4be27881
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/verifyjar.html
@@ -0,0 +1,145 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>VerifyJar Task</title>
+</head>
+
+<body>
+
+<h2><a name="verifyjar">VerifyJar</a></h2>
+<h3>Description</h3>
+<p>Verifies JAR files with the <tt>jarsigner</tt> command line tool.
+It will take a named file in the <tt>jar</tt> attribute. Nested paths are also
+supported
+</p>
+
+
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">jar</td>
+ <td valign="top">the jar file to verify</td>
+ <td valign="top" align="center">Yes, unless nested paths have
+ been used.</td>
+ </tr>
+ <tr>
+ <td valign="top">alias</td>
+ <td valign="top">the alias to verify under</td>
+ <td valign="top" align="center">Yes.</td>
+ </tr>
+ <tr>
+ <td valign="top">storepass</td>
+ <td valign="top">password for keystore integrity.</td>
+ <td valign="top" align="center">Yes.</td>
+ </tr>
+ <tr>
+ <td valign="top">keystore</td>
+ <td valign="top">keystore location</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">storetype</td>
+ <td valign="top">keystore type</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">keypass</td>
+ <td valign="top">password for private key (if different)</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">certificates</td>
+ <td valign="top">(true | false) display information about certificates</td>
+ <td valign="top" align="center">No; default false</td>
+ </tr>
+ <tr>
+ <td valign="top">verbose</td>
+ <td valign="top">(true | false) verbose output when verifying</td>
+ <td valign="top" align="center">No; default false</td>
+ </tr>
+ <tr>
+ <td valign="top">strict</td>
+ <td valign="top">(true | false) strict checking when verifying.<br/><em>since Ant 1.9.1</em>.</td>
+ <td valign="top" align="center">No; default false</td>
+ </tr>
+ <tr>
+ <td valign="top">maxmemory</td>
+ <td valign="top">Specifies the maximum memory the jarsigner VM will use. Specified in the
+ style of standard java memory specs (e.g. 128m = 128 MBytes)</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">executable</td>
+ <td valign="top">Specify a particular <code>jarsigner</code> executable
+ to use in place of the default binary (found in the same JDK as
+ Apache Ant is running in).<br/>
+ Must support the same command line options as the Sun JDK
+ jarsigner command.
+ <em>since Ant 1.8.0</em>.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+</table>
+<h3>Parameters as nested elements</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">path</td>
+ <td valign="top">path of JAR files to verify. <em>since Ant 1.7</em></td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">fileset</td>
+ <td valign="top">fileset of JAR files to verify. </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">sysproperty</td>
+ <td valign="top">JVM system properties, with the syntax of Ant
+ <a href="exec.html#env">environment variables</a> </td>
+ <td valign="top" align="center">No, and only one can be supplied</td>
+ </tr>
+ </table>
+
+
+<h3>Examples</h3>
+ <blockquote><pre>
+&lt;verifyjar jar=&quot;${dist}/lib/ant.jar&quot;
+alias=&quot;apache-group&quot; storepass=&quot;secret&quot;/&gt;
+</pre></blockquote>
+<p>
+ verifies the ant.jar with alias &quot;apache-group&quot; accessing the
+ keystore and private key via &quot;secret&quot; password.
+</p>
+
+
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/vss.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/vss.html
new file mode 100644
index 00000000..2c0ed68c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/vss.html
@@ -0,0 +1,823 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+<head>
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Microsoft Visual SourceSafe(VSS) Tasks</title>
+</head>
+<body>
+<h1>Microsoft Visual SourceSafe Tasks User Manual</h1>
+<p>by</p>
+<ul>
+ <li>Craig Cottingham</li>
+ <li>Andrew Everitt</li>
+ <li>Balazs Fejes 2</li>
+ <li><a href="mailto:Glenn_Twiggs@bmc.com">Glenn_Twiggs@bmc.com</a></li>
+ <li>Martin Poeschl (<a href="mailto:mpoeschl@marmot.at">mpoeschl@marmot.at</a>)</li>
+ <li>Phillip Wells</li>
+ <li>Jon Skeet (<a href="mailto:jon.skeet@peramon.com">jon.skeet@peramon.com</a>)</li>
+ <li>Nigel Magnay (<a href="mailto:nigel.magnay@parsec.co.uk">nigel.magnay@parsec.co.uk</a>)</li>
+ <li>Gary S. Weaver</li>
+ <li>Jesse Stockall</li>
+ </ul>
+<hr>
+<h2>Contents</h2>
+<ul>
+ <li><a href="#intro">Introduction</a></li>
+ <li><a href="#tasks">The Tasks</a></li>
+</ul>
+<br>
+<h2><a name="intro">Introduction</a></h2>
+<p>These tasks provide an interface to the
+<a href="http://msdn.microsoft.com/ssafe/default.asp" target="_top">Microsoft Visual SourceSafe</a> SCM.
+The <code>org.apache.tools.ant.taskdefs.optional.vss</code> package consists of a simple framework to support
+vss functionality as well as some Apache Ant tasks encapsulating frequently used vss commands.
+Although it is possible to use these commands on the desktop,
+they were primarily intended to be used by automated build systems.</p>
+<p>
+If you get a CreateProcess IOError=2 when running these, it means
+that ss.exe was not found. Check to see if you can run it from the
+command line -you may need to alter your path, or set the <tt>ssdir</tt>
+property.
+<h2><a name="tasks">The Tasks</a></h2>
+
+<table border="0" cellspacing="0" cellpadding="3">
+ <tr>
+ <td><a href="#vssget">vssget</a></td>
+ <td>Retrieves a copy of the specified VSS file(s).</td>
+ </tr>
+ <tr>
+ <td><a href="#vsslabel">vsslabel</a></td>
+ <td>Assigns a label to the specified version or current version of a file or project.</td>
+ </tr>
+ <tr>
+ <td><a href="#vsshistory">vsshistory</a></td>
+ <td>Shows the history of a file or project in VSS.</td>
+ </tr>
+ <tr>
+ <td><a href="#vsscheckin">vsscheckin</a></td>
+ <td>Updates VSS with changes made to a checked out file, and unlocks the VSS master copy.</td>
+ </tr>
+ <tr>
+ <td><a href="#vsscheckout">vsscheckout</a></td>
+ <td>Copies a file from the current project to the current folder, for the purpose of editing.</td>
+ </tr>
+ <tr>
+ <td><a href="#vssadd">vssadd</a></td>
+ <td>Adds a new file into the VSS Archive</td>
+ </tr>
+ <tr>
+ <td><a href="#vsscp">vsscp</a></td>
+ <td>Change the current project being used in VSS</td>
+ </tr>
+ <tr>
+ <td><a href="#vsscreate">vsscreate</a></td>
+ <td>Creates a project in VSS.</td>
+ </tr>
+</table>
+
+<hr>
+<h2>Task Descriptions</h2>
+
+<!-- VSSGET -->
+
+<h2><a name="vssget">VssGet</a></h2>
+<h3>Description</h3>
+Task to perform GET commands to Microsoft Visual SourceSafe.
+<p>If you specify two or more attributes from version, date and
+label only one will be used in the order version, date, label.</p>
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <th>Attribute</th>
+ <th>Values</th>
+ <th>Required</th>
+ </tr>
+ <tr>
+ <td>vsspath</td>
+ <td>SourceSafe path which specifies the project/file(s) you wish to
+ perform the action on.</td>
+ <td>Yes</td>
+ </tr>
+ <tr>
+ <td>login</td>
+ <td>username[,password] - The username and password needed to get access
+ to VSS. Note that you may need to specify both (if you have a password) -
+ Ant/VSS will hang if you leave the password out and VSS does not accept
+ login without a password. </td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>localpath</td>
+ <td>Override the working directory and get to the specified path</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>ssdir</td>
+ <td>directory where <code>ss.exe</code> resides. By default the
+ task expects it to be in the PATH.</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>serverPath</td>
+ <td>directory where <code>srcsafe.ini</code> resides.</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>writable</td>
+ <td>true or false; default false</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>recursive</td>
+ <td>true or false; default false. Note however that in the SourceSafe UI
+ , there is a setting accessed via Tools/Options/GeneralTab called
+ &quot;Act on projects recursively&quot;. If this setting is checked,
+ then the recursive attribute is effectively ignored, and the get
+ will always be done recursively
+ </td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>version</td>
+ <td>a version number to get</td>
+ <td rowspan="3">No, only one of these allowed</td>
+ </tr>
+ <tr>
+ <td>date</td>
+ <td>a date stamp to get at</td>
+ </tr>
+ <tr>
+ <td>label</td>
+ <td>a label to get for</td>
+ </tr>
+ <tr>
+ <td>quiet</td>
+ <td>suppress output (off by default)</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>autoresponse</td>
+ <td>What to respond with (sets the -I option). By default, -I- is
+ used; values of Y or N will be appended to this.</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>writablefiles</td>
+ <td>Behavior when local files are writable. Valid options are: <code>replace</code>,
+ <code>skip</code> and <code>fail</code>; Defaults to <code>fail</code>
+ <br><code>skip</code> implies <code>failonerror=false</code></td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>failonerror</td>
+ <td>Stop the buildprocess if ss.exe exits with a returncode of 100. Defaults to true</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>filetimestamp</td>
+ <td>Set the behavior for timestamps of local files. Valid options are <code>current</code>,
+ <code>modified</code>, or <code>updated</code>. Defaults to <code>current</code>.</td>
+ <td>No</td>
+ </tr>
+</table>
+<p>Note that only one of version, date or label should be specified</p>
+<h3>Examples</h3>
+<blockquote>
+<pre>
+&lt;vssget localPath=&quot;C:\mysrc\myproject&quot;
+ recursive=&quot;true&quot;
+ label=&quot;Release1&quot;
+ login=&quot;me,mypassword&quot;
+ vsspath=&quot;$/source/aProject&quot;
+ writable=&quot;true&quot;/&gt;
+</pre>
+</blockquote>
+<p>Does a get on the VSS-Project <i>$/source/myproject</i> using the username
+<i>me</i> and the password <i>mypassword</i>. It will recursively get the files
+which are labeled <i>Release1</i> and write them to the local directory
+<i>C:\mysrc\myproject</i>. The local files will be writable.</p>
+<hr>
+
+<!-- VSSLABEL -->
+
+<h2><a name="vsslabel">VssLabel</a></h2>
+<h3>Description</h3>
+Task to perform LABEL commands to Microsoft Visual SourceSafe.
+<p>Assigns a label to the specified version or current version of a file or
+project.</p>
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <th>Attribute</th>
+ <th>Values</th>
+ <th>Required</th>
+ </tr>
+ <tr>
+ <td>vsspath</td>
+ <td>SourceSafe path which specifies the project/file(s) you wish to
+ perform the action on.</td>
+ <td>Yes</td>
+ </tr>
+ <tr>
+ <td>login</td>
+ <td>username[,password] - The username and password needed to get access
+ to VSS. Note that you may need to specify both (if you have a password) -
+ Ant/VSS will hang if you leave the password out and VSS does not accept
+ login without a password. </td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>ssdir</td>
+ <td>directory where <code>ss.exe</code> resides. By default the
+ task expects it to be in the PATH.</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>serverPath</td>
+ <td>directory where <code>srcsafe.ini</code> resides.</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>label</td>
+ <td>A label to apply to the hierarchy</td>
+ <td>Yes</td>
+ </tr>
+ <tr>
+ <td>version</td>
+ <td>An existing file or project version to label. By default the current
+ version is labeled.</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>comment</td>
+ <td>The comment to use for this label. Empty or '-' for no comment.</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>autoresponse</td>
+ <td>What to respond with (sets the -I option). By default, -I- is
+ used; values of Y or N will be appended to this.</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>failonerror</td>
+ <td>Stop the buildprocess if ss.exe exits with a returncode of 100. Defaults to true</td>
+ <td>No</td>
+ </tr>
+</table>
+<h3>Examples</h3>
+<blockquote>
+<pre>
+&lt;vsslabel vsspath=&quot;$/source/aProject&quot;
+ login=&quot;me,mypassword&quot;
+ label=&quot;Release1&quot;/&gt;
+</pre>
+</blockquote>
+<p>Labels the current version of the VSS project <i>$/source/aProject</i> with
+the label <i>Release1</i> using the username <i>me</i> and the password
+<i>mypassword</i>.
+</p>
+<blockquote>
+<pre>
+&lt;vsslabel vsspath=&quot;$/source/aProject/myfile.txt&quot;
+ version=&quot;4&quot;
+ label=&quot;1.03.004&quot;/&gt;
+</pre>
+</blockquote>
+<p>Labels version 4 of the VSS file <i>$/source/aProject/myfile.txt</i> with the
+label <i>1.03.004</i>. If this version already has a label, the operation (and
+the build) will fail.
+</p>
+<hr>
+
+<!-- VSSHISTORY -->
+
+<h2><a name="vsshistory">VssHistory</a></h2>
+<h3>Description</h3>
+Task to perform HISTORY commands to Microsoft Visual SourceSafe.
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <th>Attribute</th>
+ <th>Values</th>
+ <th>Required</th>
+ </tr>
+ <tr>
+ <td>vsspath</td>
+ <td>SourceSafe path which specifies the project/file(s) you wish to
+ perform the action on.</td>
+ <td>Yes</td>
+ </tr>
+ <tr>
+ <td>login</td>
+ <td>username[,password] - The username and password needed to get access
+ to VSS. Note that you may need to specify both (if you have a password) -
+ Ant/VSS will hang if you leave the password out and VSS does not accept
+ login without a password. </td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>ssdir</td>
+ <td>directory where <code>ss.exe</code> resides. By default the
+ task expects it to be in the PATH.</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>serverPath</td>
+ <td>directory where <code>srcsafe.ini</code> resides.</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>fromDate</td>
+ <td>Start date for comparison</td>
+ <td>See below</td>
+ </tr>
+ <tr>
+ <td>toDate</td>
+ <td>End date for comparison</td>
+ <td>See below</td>
+ </tr>
+ <tr>
+ <td>dateFormat</td>
+ <td>Format of dates in fromDate and toDate. Used when calculating dates with
+ the numdays attribute. This string uses the formatting rules of SimpleDateFormat.
+ Defaults to DateFormat.SHORT.</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>fromLabel</td>
+ <td>Start label for comparison</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>toLabel</td>
+ <td>Start label for comparison</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>numdays</td>
+ <td>The number of days for comparison.</td>
+ <td>See below</td>
+ </tr>
+ <tr>
+ <td>output</td>
+ <td>File to write the diff.</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>recursive</td>
+ <td>true or false</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>style</td>
+ <td>brief, codediff, default or nofile. The default is default.</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>user</td>
+ <td>Name the user whose changes we would like to see</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>failonerror</td>
+ <td>Stop the buildprocess if ss.exe exits with a returncode of 100. Defaults to true</td>
+ <td>No</td>
+ </tr>
+</table>
+
+<h4>Specifying the time-frame</h4>
+<p>There are different ways to specify what time-frame you wish to evaluate:</p>
+<ul>
+ <li>Changes between two dates: Specify both <code>fromDate</code> and <code>toDate</code> </li>
+ <li>Changes before a date: Specify <code>toDate</code></li>
+ <li>Changes after a date: Specify <code>fromDate</code></li>
+ <li>Changes X Days before a date: Specify <code>toDate</code> and (negative!) <code>numDays</code></li>
+ <li>Changes X Days after a date: Specify <code>fromDate</code> and <code>numDays</code></li>
+</ul>
+
+
+<h3>Examples</h3>
+<blockquote>
+ <pre>
+&lt;vsshistory vsspath=&quot;$/myProject&quot; recursive=&quot;true&quot;
+ fromLabel=&quot;Release1&quot;
+ toLabel=&quot;Release2&quot;/&gt;
+</pre>
+</blockquote>
+<p>Shows all changes between &quot;Release1&quot; and &quot;Release2&quot;.</p>
+
+<blockquote>
+ <pre>
+&lt;vsshistory vsspath=&quot;$/myProject&quot; recursive=&quot;true&quot;
+ fromDate=&quot;01.01.2001&quot;
+ toDate=&quot;31.03.2001&quot;/&gt;
+</pre>
+</blockquote>
+<p>Shows all changes between January 1st 2001 and March 31st 2001 (in Germany, date must be specified according to your locale).</p>
+
+<blockquote>
+ <pre>
+&lt;tstamp&gt;
+ &lt;format property=&quot;to.tstamp&quot; pattern=&quot;M-d-yy;h:mma&quot;/&gt;
+&lt;/tstamp&gt;
+
+&lt;vsshistory vsspath=&quot;$/myProject&quot; recursive=&quot;true&quot;
+ numDays=&quot;-14&quot;
+ dateFormat=&quot;M-d-yy;h:mma&quot;
+ toDate=&quot;${to.tstamp}&quot;/&gt;
+</pre>
+</blockquote>
+<p>Shows all changes in the 14 days before today.</p>
+<hr>
+
+<!-- VSSCHECKIN -->
+
+<h2><a name="vsscheckin">VssCheckin</a></h2>
+<h3>Description</h3>
+Task to perform CHECKIN commands to Microsoft Visual SourceSafe.
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <th>Attribute</th>
+ <th>Values</th>
+ <th>Required</th>
+ </tr>
+ <tr>
+ <td>vsspath</td>
+ <td>SourceSafe path which specifies the project/file(s) you wish to
+ perform the action on.</td>
+ <td>Yes</td>
+ </tr>
+ <tr>
+ <td>login</td>
+ <td>username[,password] - The username and password needed to get access
+ to VSS. Note that you may need to specify both (if you have a password) -
+ Ant/VSS will hang if you leave the password out and VSS does not accept
+ login without a password. </td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>localpath</td>
+ <td>Override the working directory and get to the specified path</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>ssdir</td>
+ <td>directory where <code>ss.exe</code> resides. By default the
+ task expects it to be in the PATH.</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>serverPath</td>
+ <td>directory where <code>srcsafe.ini</code> resides.</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>writable</td>
+ <td>true or false</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>recursive</td>
+ <td>true or false</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>comment</td>
+ <td>Comment to use for the files that where checked in.</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>autoresponse</td>
+ <td>'Y', 'N' or empty. Specify how to reply to questions from VSS.</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>failonerror</td>
+ <td>Stop the buildprocess if ss.exe exits with a returncode of 100. Defaults to true</td>
+ <td>No</td>
+ </tr>
+</table>
+
+<h3>Examples</h3>
+<blockquote>
+<pre>
+&lt;vsscheckin vsspath=&quot;$/test/test*&quot;
+ localpath=&quot;D:\build\&quot;
+ comment=&quot;Modified by automatic build&quot;/&gt;
+</pre>
+</blockquote>
+<p>Checks in the file(s) named <i>test*</i> in the project <i>$/test</i> using
+the local directory <i>D:\build</i>.</p>
+<hr>
+
+<!-- VSSCHECKOUT -->
+
+<h2><a name="vsscheckout">VssCheckout</a></h2>
+<h3>Description</h3>
+Task to perform CHECKOUT commands to Microsoft Visual SourceSafe.
+<p>If you specify two or more attributes from version, date and
+label only one will be used in the order version, date, label.</p>
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <th>Attribute</th>
+ <th>Values</th>
+ <th>Required</th>
+ </tr>
+ <tr>
+ <td>vsspath</td>
+ <td>SourceSafe path which specifies the project/file(s) you wish to
+ perform the action on.</td>
+ <td>Yes</td>
+ </tr>
+ <tr>
+ <td>login</td>
+ <td>username[,password] - The username and password needed to get access
+ to VSS. Note that you may need to specify both (if you have a password) -
+ Ant/VSS will hang if you leave the password out and VSS does not accept
+ login without a password. </td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>localpath</td>
+ <td>Override the working directory and get to the specified path</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>ssdir</td>
+ <td>directory where <code>ss.exe</code> resides. By default the
+ task expects it to be in the PATH.</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>serverPath</td>
+ <td>directory where <code>srcsafe.ini</code> resides.</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>writable</td>
+ <td>true or false</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>recursive</td>
+ <td>true or false</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>version</td>
+ <td>a version number to get</td>
+ <td rowspan="3">No, only one of these allowed</td>
+ </tr>
+ <tr>
+ <td>date</td>
+ <td>a date stamp to get at</td>
+ </tr>
+ <tr>
+ <td>label</td>
+ <td>a label to get for</td>
+ </tr>
+ <tr>
+ <td>writablefiles</td>
+ <td>Behavior when local files are writable. Valid options are: <code>replace</code>,
+ <code>skip</code> and <code>fail</code>; Defaults to <code>fail</code>
+ <br><code>skip</code> implies <code>failonerror=false</code></td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>failonerror</td>
+ <td>Stop the buildprocess if ss.exe exits with a returncode of 100. Defaults to true</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>filetimestamp</td>
+ <td>Set the behavior for timestamps of local files. Valid options are <code>current</code>,
+ <code>modified</code>, or <code>updated</code>. Defaults to <code>current</code>.</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>getlocalcopy</td>
+ <td>Set the behavior to retrieve local copies of the files. Defaults to true.</td>
+ <td>No</td>
+ </tr>
+</table>
+
+<h3>Examples</h3>
+<blockquote>
+<pre>
+&lt;vsscheckout vsspath=&quot;$/test&quot;
+ localpath=&quot;D:\build&quot;
+ recursive=&quot;true&quot;
+ login=&quot;me,mypass&quot;/&gt;
+</pre>
+</blockquote>
+<p>Does a recursive checkout of the project <i>$/test</i> to the directory D:\build.
+</p>
+<hr>
+
+<!-- VSSADD -->
+
+<h2><a name="vssadd">VssAdd</a></h2>
+<h3>Description</h3>
+Task to perform ADD commands to Microsoft Visual SourceSafe.
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <th>Attribute</th>
+ <th>Values</th>
+ <th>Required</th>
+ </tr>
+ <tr>
+ <td>localpath</td>
+ <td>Specify the local file(s) to add to VSS</td>
+ <td>Yes</td>
+ </tr>
+ <tr>
+ <td>login</td>
+ <td>username[,password] - The username and password needed to get access
+ to VSS. Note that you may need to specify both (if you have a password) -
+ Ant/VSS will hang if you leave the password out and VSS does not accept
+ login without a password. </td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>ssdir</td>
+ <td>directory where <code>ss.exe</code> resides. By default the
+ task expects it to be in the PATH.</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>serverPath</td>
+ <td>directory where <code>srcsafe.ini</code> resides.</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>writable</td>
+ <td>true or false</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>recursive</td>
+ <td>true or false</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>comment</td>
+ <td>Comment to use for the files that where checked in.</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>autoresponse</td>
+ <td>'Y', 'N' or empty. Specify how to reply to questions from VSS.</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>failonerror</td>
+ <td>Stop the buildprocess if ss.exe exits with a returncode of 100. Defaults to true</td>
+ <td>No</td>
+ </tr>
+</table>
+
+<h3>Examples</h3>
+<blockquote>
+<pre>
+&lt;vssadd localpath=&quot;D:\build\build.00012.zip&quot;
+ comment=&quot;Added by automatic build&quot;/&gt;
+</pre>
+</blockquote>
+<p>Add the file named build.00012.zip into the project current working
+directory (see vsscp).</p>
+<hr>
+
+<!-- VSSCP -->
+
+<h2><a name="vsscp">VssCp</a></h2>
+<h3>Description</h3>
+<p>Task to perform CP (Change Project) commands to Microsoft Visual SourceSafe.</p>
+<p>This task is typically used before a VssAdd in order to set the target project</p>
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <th>Attribute</th>
+ <th>Values</th>
+ <th>Required</th>
+ </tr>
+ <tr>
+ <td>vsspath</td>
+ <td>SourceSafe path which specifies the project you wish to
+ make the current project.</td>
+ <td>Yes</td>
+ </tr>
+ <tr>
+ <td>login</td>
+ <td>username[,password] - The username and password needed to get access
+ to VSS. Note that you may need to specify both (if you have a password) -
+ Ant/VSS will hang if you leave the password out and VSS does not accept
+ login without a password. </td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>ssdir</td>
+ <td>directory where <code>ss.exe</code> resides. By default the
+ task expects it to be in the PATH.</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>serverPath</td>
+ <td>directory where <code>srcsafe.ini</code> resides.</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>failonerror</td>
+ <td>Stop the buildprocess if ss.exe exits with a returncode of 100. Defaults to true</td>
+ <td>No</td>
+ </tr>
+</table>
+
+<h3>Examples</h3>
+<blockquote>
+<pre>
+&lt;vsscp vsspath=&quot;$/Projects/ant&quot;/&gt;
+</pre>
+</blockquote>
+<p>Sets the current VSS project to <i>$/Projects/ant</i>.</p>
+<hr>
+
+<!-- VSSCREATE -->
+
+ <h2><a name="vsscreate">VssCreate</a></h2>
+ <h3>Description</h3>
+ Task to perform CREATE commands to Microsoft Visual Source Safe.
+ <p>Creates a new project in VSS.</p>
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <th>Attribute</th>
+ <th>Values</th>
+ <th>Required</th>
+ </tr>
+ <tr>
+ <td>login</td>
+ <td>username,password</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>vsspath</td>
+ <td>SourceSafe path of project to be created</td>
+ <td>Yes</td>
+ </tr>
+ <tr>
+ <td>ssdir</td>
+ <td>directory where <code>ss.exe</code> resides. By default the task expects it to be in the PATH.</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>quiet</td>
+ <td>suppress output (off by default)</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>failOnError</td>
+ <td>fail if there is an error creating the project (true by default)</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>autoresponse</td>
+ <td>What to respond with (sets the -I option). By default, -I- is used; values of Y or N will be appended to this.</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>comment</td>
+ <td>The comment to use for this label. Empty or '-' for no comment.</td>
+ <td>No</td>
+ </tr>
+</table>
+<h3>Examples</h3>
+<blockquote>
+<pre>
+&lt;vsscreate vsspath=&quot;$/existingProject/newProject&quot;/&gt;
+</pre>
+</blockquote>
+<p>Creates the VSS-Project <i>$/existingProject/newProject</i>.</p>
+<hr>
+
+<!-- Footer -->
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/waitfor.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/waitfor.html
new file mode 100644
index 00000000..54ff8edf
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/waitfor.html
@@ -0,0 +1,133 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>WaitFor Task</title>
+</head>
+
+<body>
+
+<h2>Waitfor</h2>
+<h3>Description</h3>
+<p>Blocks execution until a set of specified conditions become true. This is intended
+ to be used with the <a href="parallel.html">parallel</a> task to
+ synchronize a set of processes.</p>
+<p>The conditions to wait for are defined in <a href="waitfor.html#nested">nested elements</a>,
+if multiple conditions are specified, then the task will wait until all conditions are true..</p>
+<p></p>
+<p>If both maxwait and maxwaitunit are not specified, the maxwait is 3 minutes (180000 milliseconds).</p>
+<p>If the <code>timeoutproperty</code> attribute has been set, a
+property of that name will be created if the condition didn't come
+true within the specified time.</p>
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">maxwait</td>
+ <td valign="top">The maximum amount of time to wait for all the required conditions
+ to become true before failing the task. Defaults to 180000 maxwaitunits.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">maxwaitunit</td>
+ <td valign="top">The unit of time that must be used to interpret the value of the
+ maxwait attribute. Defaults to millisecond.
+ Valid Values are
+ <ul>
+ <li>millisecond</li>
+ <li>second</li>
+ <li>minute</li>
+ <li>hour</li>
+ <li>day</li>
+ <li>week</li>
+ </ul>
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">checkevery</td>
+ <td valign="top">The amount of time to wait between each test of the conditions.
+ Defaults to 500 checkeveryunits.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">checkeveryunit</td>
+ <td valign="top">The unit of time that must be used to interpret the value of the
+ checkevery attribute. Defaults to millisecond.
+ Valid Values are
+ <ul>
+ <li>millisecond</li>
+ <li>second</li>
+ <li>minute</li>
+ <li>hour</li>
+ <li>day</li>
+ <li>week</li>
+ </ul>
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">timeoutproperty</td>
+ <td valign="top">the name of the property to set if maxwait has
+ been exceeded.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+</table>
+<h3><a name="nested">Nested Elements</a></h3>
+
+<p>The available conditions that satisfy the
+<code>&lt;waitfor&gt;</code> task are the same as those for the
+<a href="condition.html"><code>&lt;condition&gt;</code></a> task. See
+<a href="conditions.html">here</a> for the full list.</p>
+
+<h3>Examples</h3>
+<blockquote><pre>
+&lt;waitfor maxwait="30" maxwaitunit="second"&gt;
+ &lt;available file="errors.log"/&gt;
+&lt;/waitfor&gt;
+</pre></blockquote>
+<p>waits up to 30 seconds for a file called errors.log to appear.</p>
+<blockquote><pre>
+&lt;waitfor maxwait="3" maxwaitunit="minute" checkevery="500"&gt;
+ &lt;http url="http://localhost/myapp/index.html"/&gt;
+&lt;/waitfor&gt;
+</pre></blockquote>
+<p>waits up to 3 minutes (and checks every 500 milliseconds) for a web server on localhost
+ to serve up the specified URL.</p>
+<blockquote><pre>
+&lt;waitfor maxwait="10" maxwaitunit="second"&gt;
+ &lt;and&gt;
+ &lt;socket server="dbserver" port="1521"/&gt;
+ &lt;http url="http://webserver/mypage.html"/&gt;
+ &lt;/and&gt;
+&lt;/waitfor&gt;
+</pre></blockquote>
+<p>waits up to 10 seconds for a server on the dbserver machine to begin listening
+ on port 1521 and for the http://webserver/mypage.html web page
+ to become available.</p>
+
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/war.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/war.html
new file mode 100644
index 00000000..2c920068
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/war.html
@@ -0,0 +1,364 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>WAR Task</title>
+</head>
+
+<body>
+
+<h2><a name="war">War</a></h2>
+<h3>Description</h3>
+<p>An extension of the <a href="jar.html">Jar</a> task with special
+treatment for files that should end up in the
+<code>WEB-INF/lib</code>, <code>WEB-INF/classes</code> or
+<code>WEB-INF</code> directories of the Web Application Archive.</p>
+<p>(The War task is a shortcut for specifying the particular layout of a WAR file.
+The same thing can be accomplished by using the <i>prefix</i> and <i>fullpath</i>
+attributes of zipfilesets in a Zip or Jar task.)</p>
+<p>The extended zipfileset element from the zip task
+ (with attributes <i>prefix</i>, <i>fullpath</i>, and <i>src</i>)
+ is available in the War task. The task is also resource-enabled
+ and will add nested resources and resource collections to the archive.</p>
+
+<p>
+ Before Servlet API 2.5/Java EE 5, a WEB-INF/web.xml file was mandatory in a
+ WAR file, so this task failed if the <code>webxml</code> attribute was missing.
+ As the web.xml file is now optional, the <code>webxml</code> attribute may now
+ be made optional. However, as most real web applications do need a web.xml file,
+ it is not optional by default. The task will fail if the file is not
+ included, unless the <code>needxmlfile</code> attribute
+ is set to <code>false</code>. The task
+ will warn if more than one web.xml file is added to the JAR
+ through the filesets.
+</p>
+
+
+<p><b>Please note that the Zip format allows multiple files of the same
+fully-qualified name to exist within a single archive. This has been
+documented as causing various problems for unsuspecting users. If you wish
+to avoid this behavior you must set the <code>duplicate</code> attribute
+to a value other than its default, <code>&quot;add&quot;</code>.</b></p>
+
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">destfile</td>
+ <td valign="top">the WAR file to create.</td>
+ <td align="center" valign="top" rowspan="2">Exactly one of the two.</td>
+ </tr>
+ <tr>
+ <td valign="top">warfile</td>
+ <td valign="top"><i>Deprecated</i> name of the file to create
+ -use <tt>destfile</tt> instead.</td>
+ </tr>
+ <tr>
+ <td valign="top">webxml</td>
+ <td valign="top">The servlet configuration descriptor to use (WEB-INF/web.xml).</td>
+ <td valign="top" align="center">Yes, unless <tt>needxmlfile</tt> is true,
+ the file is pulled in via a nested fileset, or an existing WAR file is
+ being updated.</td>
+ </tr>
+ <tr>
+ <td valign="top">needxmlfile</td>
+ <td valign="top">Flag to indicate whether or not the web.xml file is needed.
+ It should be set to false when generating
+ servlet 2.5+ WAR files without a web.xml file.
+ <em>Since Apache Ant 1.7</em></td>
+ <td valign="top" align="center">No -default "true"</td>
+ </tr>
+ <tr>
+ <td valign="top">basedir</td>
+ <td valign="top">the directory from which to jar the files.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">compress</td>
+ <td valign="top">Not only store data but also compress them,
+ defaults to true. Unless you set the <em>keepcompression</em>
+ attribute to false, this will apply to the entire archive, not
+ only the files you've added while updating.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">keepcompression</td>
+ <td valign="top">For entries coming from existing archives (like
+ nested <em>zipfileset</em>s or while updating the archive), keep
+ the compression as it has been originally instead of using the
+ <em>compress</em> attribute. Defaults false. <em>Since Ant
+ 1.6</em></td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">encoding</td>
+ <td valign="top">The character encoding to use for filenames
+ inside the archive. Defaults to UTF8. <strong>It is not
+ recommended to change this value as the created archive will most
+ likely be unreadable for Java otherwise.</strong>
+ <br/>See also the <a href="zip.html#encoding">discussion in the
+ zip task page</a></td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">filesonly</td>
+ <td valign="top">Store only file entries, defaults to false</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">includes</td>
+ <td valign="top">comma- or space-separated list of patterns of files that must be
+ included. All files are included when omitted.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">includesfile</td>
+ <td valign="top">the name of a file. Each line of this file is
+ taken to be an include pattern</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">excludes</td>
+ <td valign="top">comma- or space-separated list of patterns of files that must be
+ excluded. No files (except default excludes) are excluded when omitted.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">excludesfile</td>
+ <td valign="top">the name of a file. Each line of this file is
+ taken to be an exclude pattern</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">defaultexcludes</td>
+ <td valign="top">indicates whether default excludes should be used or not
+ (&quot;yes&quot;/&quot;no&quot;). Default excludes are used when omitted.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">manifest</td>
+ <td valign="top">the manifest file to use.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">filesetmanifest</td>
+ <td valign="top">behavior when a Manifest is found in a zipfileset or zipgroupfileset file is found. Valid values are &quot;skip&quot;, &quot;merge&quot;, and &quot;mergewithoutmain&quot;. &quot;merge&quot; will merge all of the manifests together, and merge this into any other specified manifests. &quot;mergewithoutmain&quot; merges everything but the Main section of the manifests. Default value is &quot;skip&quot;.
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">whenmanifestonly</td>
+ <td valign="top">behavior when no files match. Valid values are &quot;fail&quot;, &quot;skip&quot;, and &quot;create&quot;. Default is &quot;create&quot;.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">update</td>
+ <td valign="top">indicates whether to update or overwrite
+ the destination file if it already exists. Default is &quot;false&quot;.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">duplicate</td>
+ <td valign="top">behavior when a duplicate file is found. Valid values are &quot;add&quot;, &quot;preserve&quot;, and &quot;fail&quot;. The default value is &quot;add&quot;. </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">roundup</td>
+ <td valign="top">Whether the file modification times will be
+ rounded up to the next even number of seconds.<br>
+ Zip archives store file modification times with a granularity of
+ two seconds, so the times will either be rounded up or down. If
+ you round down, the archive will always seem out-of-date when you
+ rerun the task, so the default is to round up. Rounding up may
+ lead to a different type of problems like JSPs inside a web
+ archive that seem to be slightly more recent than precompiled
+ pages, rendering precompilation useless.<br>
+ Defaults to true. <em>Since Ant 1.6.2</em></td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">level</td>
+ <td valign="top">Non-default level at which file compression should be
+ performed. Valid values range from 0 (no compression/fastest) to 9
+ (maximum compression/slowest). <em>Since Ant 1.7</em></td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">preserve0permissions</td>
+ <td valign="top">when updating an archive or adding entries from a
+ different archive Ant will assume that a Unix permissions value of
+ 0 (nobody is allowed to do anything to the file/directory) means
+ that the permissions haven't been stored at all rather than real
+ permissions and will instead apply its own default values.<br/>
+ Set this attribute to true if you really want to preserve the
+ original permission field.<em>since Ant 1.8.0</em>
+ </td>
+ <td valign="top" align="center">No, default is false</td>
+ </tr>
+ <tr>
+ <td valign="top">useLanguageEncodingFlag</td>
+ <td valign="top">Whether to set the language encoding flag if the
+ encoding is UTF-8. This setting doesn't have any effect if the
+ encoding is not UTF-8.
+ <em>Since Ant 1.8.0</em>.
+ <br/>See also the <a href="zip.html#encoding">discussion in the
+ zip task page</a></td>
+ <td valign="top" align="center">No, default is true</td>
+ </tr>
+ <tr>
+ <td valign="top">createUnicodeExtraFields</td>
+ <td valign="top">Whether to create unicode extra fields to store
+ the file names a second time inside the entry's metadata.
+ <br>Possible values are "never", "always" and "not-encodeable"
+ which will only add Unicode extra fields if the file name cannot
+ be encoded using the specified encoding.
+ <em>Since Ant 1.8.0</em>.
+ <br/>See also the <a href="zip.html#encoding">discussion in the
+ zip task page</a></td>
+ <td align="center" valign="top">No, default is "never"</td>
+ </tr>
+ <tr>
+ <td valign="top">fallbacktoUTF8</td>
+ <td valign="top">Whether to use UTF-8 and the language encoding
+ flag instead of the specified encoding if a file name cannot be
+ encoded using the specified encoding.
+ <em>Since Ant 1.8.0</em>.
+ <br/>See also the <a href="zip.html#encoding">discussion in the
+ zip task page</a></td>
+ <td align="center" valign="top">No, default is false</td>
+ </tr>
+ <tr>
+ <td valign="top">mergeClassPathAttributes</td>
+ <td valign="top">Whether to merge the Class-Path attributes found
+ in different manifests (if merging manifests). If false, only
+ the attribute of the last merged manifest will be preserved.
+ <em>Since Ant 1.8.0</em>.
+ <br/>unless you also set flattenAttributes to true this may
+ result in manifests containing multiple Class-Path attributes
+ which violates the manifest specification.</td>
+ <td align="center" valign="top">No, default is false</td>
+ </tr>
+ <tr>
+ <td valign="top">flattenAttributes</td>
+ <td valign="top">Whether to merge attributes occurring more than
+ once in a section (this can only happen for the Class-Path
+ attribute) into a single attribute.
+ <em>Since Ant 1.8.0</em>.</td>
+ <td align="center" valign="top">No, default is false</td>
+ </tr>
+ <tr>
+ <td valign="top">zip64Mode</td>
+ <td valign="top">When to use Zip64 extensions for entries. The
+ possible values are "never", "always" and "as-needed".
+ <em>Since Ant 1.9.1</em>.
+ <br/>See also the <a href="zip.html#zip64">discussion in the
+ zip task page</a></td>
+ <td align="center" valign="top">No, default is "never"</td>
+ </tr>
+</table>
+
+<h3>Nested elements</h3>
+
+<h4>lib</h4>
+<p>The nested <code>lib</code> element specifies a <a
+href="../Types/fileset.html">FileSet</a>. All files included in this fileset will
+end up in the <code>WEB-INF/lib</code> directory of the war file.</p>
+
+<h4>classes</h4>
+<p>The nested <code>classes</code> element specifies a <a
+href="../Types/fileset.html">FileSet</a>. All files included in this fileset will
+end up in the <code>WEB-INF/classes</code> directory of the war file.</p>
+
+<h4>webinf</h4>
+<p>The nested <code>webinf</code> element specifies a <a
+href="../Types/fileset.html">FileSet</a>. All files included in this fileset will
+end up in the <code>WEB-INF</code> directory of the war file. If this
+fileset includes a file named <code>web.xml</code>, the file is
+ignored and you will get a warning.</p>
+
+<h4>metainf</h4>
+<p>The nested <code>metainf</code> element specifies a <a
+href="../Types/fileset.html">FileSet</a>. All files included in this fileset will
+end up in the <code>META-INF</code> directory of the war file. If this
+fileset includes a file named <code>MANIFEST.MF</code>, the file is
+ignored and you will get a warning.</p>
+
+<h4>manifest, indexjars, service</h4>
+These are inherited from <a href="jar.html">&lt;jar&gt;</a>
+
+<h3>Examples</h3>
+
+<p>Assume the following structure in the project's base directory:</p>
+<pre>
+thirdparty/libs/jdbc1.jar
+thirdparty/libs/jdbc2.jar
+build/main/com/myco/myapp/Servlet.class
+src/metadata/myapp.xml
+src/html/myapp/index.html
+src/jsp/myapp/front.jsp
+src/graphics/images/gifs/small/logo.gif
+src/graphics/images/gifs/large/logo.gif
+</pre>
+then the war file <code>myapp.war</code> created with
+<pre>
+&lt;war destfile=&quot;myapp.war&quot; webxml=&quot;src/metadata/myapp.xml&quot;&gt;
+ &lt;fileset dir=&quot;src/html/myapp&quot;/&gt;
+ &lt;fileset dir=&quot;src/jsp/myapp&quot;/&gt;
+ &lt;lib dir=&quot;thirdparty/libs&quot;&gt;
+ &lt;exclude name=&quot;jdbc1.jar&quot;/&gt;
+ &lt;/lib&gt;
+ &lt;classes dir=&quot;build/main&quot;/&gt;
+ &lt;zipfileset dir=&quot;src/graphics/images/gifs&quot;
+ prefix=&quot;images&quot;/&gt;
+&lt;/war&gt;
+</pre>
+will consist of
+<pre>
+WEB-INF/web.xml
+WEB-INF/lib/jdbc2.jar
+WEB-INF/classes/com/myco/myapp/Servlet.class
+META-INF/MANIFEST.MF
+index.html
+front.jsp
+images/small/logo.gif
+images/large/logo.gif
+</pre>
+using Ant's default manifest file. The content of
+<code>WEB-INF/web.xml</code> is identical to
+<code>src/metadata/myapp.xml</code>.
+
+<p>We regularly receive bug reports that this task is creating the WEB-INF
+directory as web-inf (all lower case), and thus it is our fault your webapp doesn't work. The cause
+of these complaints lies in WinZip, which turns an all upper-case
+directory into an all lower case one in a fit of helpfulness. Please check that
+<code>jar xvf yourwebapp.war</code> shows the same behaviour before filing another
+report.<br/>
+Winzip has an option allowing all uppercase names (which is off by default!). It can be enabled by:
+Menu "Options" -> "Configuration", "View" property/tab page, then "General" group box has an option called "Allow all uppercase file names".
+</p>
+
+
+
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/whichresource.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/whichresource.html
new file mode 100644
index 00000000..5b2b54ea
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/whichresource.html
@@ -0,0 +1,120 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<html>
+ <head>
+ <meta http-equiv="Content-Language" content="en-us">
+ <link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+ <title>Whichresource Task</title>
+ </link>
+ </meta>
+ </head>
+
+
+ <body>
+ <h2><a name="whichresource">Whichresource</a></h2>
+ <h3>Description</h3>
+ <p>
+ Find a class or resource on the supplied classpath, or the
+ system classpath if none is supplied.
+ The named property is set if the item can be found.
+ For example:
+ </p>
+<blockquote><pre>
+ &lt;whichresource resource="/log4j.properties" property="log4j.url" &gt;
+</pre></blockquote>
+ <h3>Parameters</h3>
+ <table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">property</td>
+ <td valign="top">
+ The property to fill with the URL of the resource of class.
+ </td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">class</td>
+ <td valign="top">
+ The name of the class to look for.
+ </td>
+ <td valign="top" align="center" rowspan="2">Exactly one of these.</td>
+ </tr>
+ <tr>
+ <td valign="top">resource</td>
+ <td valign="top">
+ The name of the resource to look for.
+ </td>
+ </tr>
+ <tr>
+ <td valign="top">classpath</td>
+ <td valign="top">
+ The classpath to use when looking up <code>class</code>
+ or <code>resource</code>.
+ </td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">classpathref</td>
+ <td valign="top">
+ The classpath to use, given as a
+ <a href="../using.html#references">reference</a>
+ to a path defined elsewhere.
+ <em>Since Apache Ant 1.7.1.</em>
+ </td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ </table>
+ <h3>Parameters specified as nested elements</h3>
+ <h4>classpath</h4>
+ <p>
+ <code>Whichresource</code>'s <code>classpath</code> attribute is a
+ <a href="../using.html#path">path-like structure</a> and can also be
+ set via a nested <code>&lt;classpath&gt;</code> element.
+ </p>
+ <h3>Examples</h3>
+ <p>
+ The following shows using a classpath reference.
+ </p>
+<blockquote><pre>
+ &lt;path id="bsf.classpath"&gt;
+ &lt;fileset dir="${user.home}/lang/bsf" includes="*.jar"/&gt;
+ &lt;/path&gt;
+ &lt;whichresource property="bsf.class.location"
+ class="org.apache.bsf.BSFManager"
+ classpathref="bsf.classpath"/&gt;
+ &lt;echo&gt;${bsf.class.location}&lt;/echo&gt;
+</pre></blockquote>
+ <p>
+ The following shows using a nested classpath.
+ </p>
+<blockquote><pre>
+ &lt;whichresource
+ property="ant-contrib.antlib.location"
+ resource="net/sf/antcontrib/antlib.xml"&gt;
+ &lt;classpath&gt;
+ &lt;path path="f:/testing/ant-contrib/target/ant-contrib.jar"/&gt;
+ &lt;/classpath&gt;
+ &lt;/whichresource&gt;
+ &lt;echo&gt;${ant-contrib.antlib.location}&lt;/echo&gt;
+</pre></blockquote>
+ </body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/wljspc.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/wljspc.html
new file mode 100644
index 00000000..56634947
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/wljspc.html
@@ -0,0 +1,99 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+<head><link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>WLJSPC Task</title></head>
+<body>
+<h1>wljspc</h1>
+<h3>Description</h3>
+<p>Class to precompile JSP's using weblogic's jsp compiler (weblogic.jspc)</p>
+Tested only on Weblogic 4.5.1 - NT4.0 and Solaris 5.7,5.8<br>
+<h3>Parameters</h3>
+<table border="1" cellPadding="2" cellSpacing="0">
+ <tbody>
+ <tr>
+ <th>Attribute</th>
+ <th>Values</th>
+ <th>Required</th>
+ </tr>
+ <tr>
+ <td>src</td>
+ <td>root of source tree for JSP, ie, the document root for your weblogic server</td>
+ <td>Yes</td>
+ </tr>
+ <tr>
+ <td>
+dest</td>
+ <td> root of destination directory, what you have set as WorkingDir in the weblogic properties</td>
+ <td>Yes</td>
+ </tr>
+ <tr>
+ <td>
+package</td>
+ <td> start package name under which your JSP's would be compiled</td>
+ <td>Yes</td>
+ </tr>
+ <tr>
+ <td>
+classpath</td>
+ <td>Class path to use when compiling jsp's</td>
+ <td>Yes</td>
+ </tr>
+ </tbody>
+</table>
+<p>
+<br>
+
+A classpath should be set which contains the weblogic classes as well as all application classes<br>
+referenced by the JSP. The system classpath is also appended when the jspc is called, so you may<br>
+choose to put everything in the classpath while calling Apache Ant. However, since presumably the JSP's will reference<br>
+classes being build by Ant, it would be better to explicitly add the classpath in the task<br>
+<br>
+The task checks timestamps on the JSP's and the generated classes, and compiles<br>
+only those files that have changed.<br>
+<br>
+It follows the weblogic naming convention of putting classes in<br>
+<b> _dirName/_fileName.class for dirname/fileName.jsp </b><br>
+<br>
+</p>
+<h3><br>
+Example<br>
+</h3>
+<p>
+<pre>
+&lt;target name="jspcompile" depends="compile"&gt;
+ &lt;wljspc src="c:\\weblogic\\myserver\\public_html" dest="c:\\weblogic\\myserver\\serverclasses" package="myapp.jsp"&gt
+ &lt;classpath&gt;
+ &lt;pathelement location="${weblogic.classpath}"/&gt;
+ &lt;pathelement path="${compile.dest}"/&gt;
+ &lt;/classpath&gt;
+ &lt;/wljspc&gt;
+&lt;/target&gt;
+</pre>
+
+</p>
+
+<h3>Limitations</h3>
+<ul>
+<li>This works only on weblogic 4.5.1</li>
+<li>It compiles the files thru the Classic compiler only.</li>
+<li>Since it is my experience that weblogic jspc throws out of memory error on being given too
+many files at one go, it is called multiple times with one jsp file each.</li>
+</ul>
+
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/xmlproperty.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/xmlproperty.html
new file mode 100644
index 00000000..293cf245
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/xmlproperty.html
@@ -0,0 +1,289 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+<head>
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>XmlProperty Task</title>
+</head>
+
+<body>
+
+<h2><a name="xmlproperty">XmlProperty</a></h2>
+<h3>Description</h3>
+<p>
+Loads property values from a well-formed xml file. There are no other restrictions
+than "well-formed". You can choose the layout you want. For example this XML property file:
+<pre>
+ &lt;root&gt;
+ &lt;properties&gt;
+ &lt;foo&gt;bar&lt;/foo&gt;
+ &lt;/properties&gt;
+ &lt;/root&gt;
+</pre>
+is roughly equivalent to this Java property file:
+<pre>
+ root.properties.foo = bar
+</pre>
+
+<p>
+By default, this load
+does <em>no</em> processing of the input. In particular, unlike the
+<a href="property.html">Property task</a>, property references
+(i.e., <samp>${foo}</samp>) are not resolved.
+<p>
+<a name="semanticAttributes">
+<h3>Semantic Attributes</h3>
+</a>
+Input processing can be enabled by using the <b>semanticAttributes</b>
+attribute. If this attribute is set to <i>true</i> (its default is
+<i>false</i>), the following processing occurs as the input XML file
+is loaded:
+<ul>
+ <li>Property references are resolved.</li>
+ <li>The following attributes are treated differently:
+ <ul>
+ <li><b>id</b>: The property is associated with the given id value.</li>
+ <li><b>location</b>: The property is treated as a file location</li>
+ <li><b>refid</b>: The property is set to the value of the
+ referenced property.</li>
+ <li><b>value</b>: The property is set to the value indicated.</li>
+ </ul>
+ </li>
+ <li><a href="../using.html#path">Path-like Structures</a> can be defined
+ by use of the following attributes:
+ <ul>
+ <li><b>pathid</b>: The given id is used to identify a path. The
+ nested XML tag name is ignored. Child elements can be used
+ (XML tag names are ignored) to identify elements of the path.</li>
+ </ul>
+ </li>
+</ul>
+<p>
+For example, with semantic attribute processing enabled, this XML property
+file:
+<pre>
+ &lt;root&gt;
+ &lt;properties&gt;
+ &lt;foo location="bar"/&gt;
+ &lt;quux&gt;${root.properties.foo}&lt;/quux&gt;
+ &lt;/properties&gt;
+ &lt;/root&gt;
+</pre>
+is roughly equivalent to the following fragments in a build.xml file:
+<pre>
+ &lt;property name="root.properties.foo" location="bar"/&gt;
+ &lt;property name="root.properties.quux" value="${root.properties.foo}"/&gt;
+</pre>
+
+</p>
+
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">file</td>
+ <td valign="top">The XML file to parse.</td>
+ <td valign="top" align="center">Yes, or a nested resource collection.</td>
+ </tr>
+ <tr>
+ <td valign="top">prefix</td>
+ <td valign="top">The prefix to prepend to each property</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">keepRoot</td>
+ <td valign="top">Keep the xml root tag as the
+ first value in the property name.</td>
+ <td valign="top" align="center">No, default is <i>true</i>.</td>
+ </tr>
+ <tr>
+ <td valign="top">validate</td>
+ <td valign="top">Validate the input file (e.g. by a DTD). Otherwise the XML must only be well-formed.</td>
+ <td valign="top" align="center">No, default is <i>false</i>.</td>
+ </tr>
+ <tr>
+ <td valign="top">collapseAttributes</td>
+ <td valign="top">Treat attributes as nested elements.</td>
+ <td valign="top" align="center">No, default is <i>false</i>.</td>
+ </tr>
+ <tr>
+ <td valign="top">semanticAttributes</td>
+ <td valign="top">Enable special handling of certain attribute names.
+ See the <a href="#semanticAttributes">Semantic Attributes</a>
+ section for more information.</td>
+ <td valign="top" align="center">No, default is <i>false</i>.</td>
+ </tr>
+ <tr>
+ <td valign="top">includeSemanticAttribute</td>
+ <td valign="top">Include the semantic attribute name
+ as part of the property name. Ignored if
+ <i>semanticAttributes</i> is not set to <i>true</i>.
+ See the <a href="#semanticAttributes">Semantic Attributes</a>
+ section for more information.</td>
+ <td valign="top" align="center">No, default is <i>false</i>.</td>
+ </tr>
+ <tr>
+ <td valign="top">rootDirectory</td>
+ <td valign="top">The directory to use for resolving file references. Ignored
+ if <i>semanticAttributes</i> is not set to <i>true</i>.</td>
+ <td valign="top" align="center">No, default is <i>${basedir}</i>.</td>
+ </tr>
+ <tr>
+ <td valign="top">delimiter</td>
+ <td valign="top">Delimiter for splitting multiple values.<br><i>since Apache Ant 1.7.1</i></td>
+ <td valign="top" align="center">No, defaults to comma</td>
+ </tr>
+</table>
+
+<h3><a name="nested">Nested Elements</a></h3>
+<h4>xmlcatalog</h4>
+<p>The <a href="../Types/xmlcatalog.html"><tt>&lt;xmlcatalog&gt;</tt></a>
+element is used to perform entity resolution.</p>
+
+<h4>any <a href="../Types/resources.html">resource</a> or single element
+resource collection</h4>
+
+<p>The specified resource will be used as input.</p>
+
+<a name="examples">
+<h3>Examples</h3>
+</a>
+
+<h4>Non-semantic Attributes</h4>
+
+<p>Here is an example xml file that does not have any semantic attributes.</p>
+
+<pre>
+ &lt;root-tag myattr="true"&gt;
+ &lt;inner-tag someattr="val"&gt;Text&lt;/inner-tag&gt;
+ &lt;a2&gt;&lt;a3&gt;&lt;a4&gt;false&lt;/a4&gt;&lt;/a3&gt;&lt;/a2&gt;
+ &lt;/root-tag&gt;
+</pre>
+
+<h5>default loading</h5>
+<p>This entry in a build file:
+<pre> &lt;xmlproperty file="somefile.xml"/&gt;</pre>
+is equivalent to the following properties:
+<pre>
+ root-tag(myattr)=true
+ root-tag.inner-tag=Text
+ root-tag.inner-tag(someattr)=val
+ root-tag.a2.a3.a4=false
+</pre>
+
+<h5>collapseAttributes=false</h5>
+<p>This entry in a build file:
+<pre> &lt;xmlproperty file="somefile.xml" collapseAttributes="true"/&gt;</pre>
+is equivalent to the following properties:
+<pre>
+ root-tag.myattr=true
+ root-tag.inner-tag=Text
+ root-tag.inner-tag.someatt=val
+ root-tag.a2.a3.a4=false
+</pre>
+
+<h5>keepRoot=false</h5>
+<p>This entry in a build file:
+<pre> &lt;xmlproperty file="somefile.xml" keepRoot="false"/&gt;</pre>
+is equivalent to the following properties:
+<pre>
+ inner-tag=Text
+ inner-tag(someattr)=val
+ a2.a3.a4=false
+</pre>
+
+<h4>Semantic Attributes</h4>
+
+<p>Here is an example xml file that has semantic attributes.</p>
+<pre>
+ &lt;root-tag&gt;
+ &lt;version value="0.0.1"/&gt;
+ &lt;build folder="build"&gt;
+ &lt;classes id="build.classes" location="${build.folder}/classes"/&gt;
+ &lt;reference refid="build.classes"/&gt;
+ &lt;/build&gt;
+ &lt;compile&gt;
+ &lt;classpath pathid="compile.classpath"&gt;
+ &lt;pathelement location="${build.classes}"/&gt;
+ &lt;/classpath&gt;
+ &lt;/compile&gt;
+ &lt;run-time&gt;
+ &lt;jars&gt;*.jar&lt;/jars&gt;
+ &lt;classpath pathid="run-time.classpath"&gt;
+ &lt;path refid="compile.classpath"/&gt;
+ &lt;pathelement path="${run-time.jars}"/&gt;
+ &lt;/classpath&gt;
+ &lt;/run-time&gt;
+ &lt;/root-tag&gt;
+</pre>
+
+<h5>default loading (semanticAttributes=true)</h5>
+<p>This entry in a build file:
+<pre> &lt;xmlproperty file="somefile.xml" keepRoot="false"
+ semanticAttributes="true"/&gt;</pre>
+is equivalent to the following entries in a build file:
+<pre>
+ &lt;property name="version" value="0.0.1"/&gt;
+ &lt;property name="build.folder" value="build"/&gt;
+ &lt;property name="build.classes" location="${build.folder}/classes" id="build.classes"/&gt;
+ &lt;property name="build.reference" refid="build.classes"/&gt;
+
+ &lt;property name="run-time.jars" value="*.jar"/&gt;
+
+ &lt;path id="compile.classpath"&gt;
+ &lt;pathelement location="${build.classes}"/&gt;
+ &lt;/path&gt;
+
+ &lt;path id="run-time.classpath"&gt;
+ &lt;path refid="compile.classpath"/&gt;
+ &lt;pathelement path="${run-time.jars}"/&gt;
+ &lt;/path&gt;
+</pre>
+
+<h5>includeSemanticAttribute="true"</h5>
+<p>This entry in a build file:
+<pre> &lt;xmlproperty file="somefile.xml"
+ semanticAttributes="true" keepRoot="false"
+ includeSemanticAttribute="true"/&gt;
+</pre>
+is equivalent to the following entries in a build file:
+<pre>
+ &lt;property name="version.value" value="0.0.1"/&gt;
+ &lt;property name="build.folder" value="build"/&gt;
+ &lt;property name="build.classes.location" location="${build.folder}/classes"/&gt;
+ &lt;property name="build.reference.refid" refid="build.classes"/&gt;
+
+ &lt;property name="run-time.jars" value="*.jar"/&gt;
+
+ &lt;path id="compile.classpath"&gt;
+ &lt;pathelement location="${build.classes}"/&gt;
+ &lt;/path&gt;
+
+ &lt;path id="run-time.classpath"&gt;
+ &lt;path refid="compile.classpath"/&gt;
+ &lt;pathelement path="${run-time.jars}"/&gt;
+ &lt;/path&gt;
+</pre>
+
+
+
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/xmlvalidate.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/xmlvalidate.html
new file mode 100644
index 00000000..c362bbe3
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/xmlvalidate.html
@@ -0,0 +1,263 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>XMLValidate Task</title>
+</head>
+
+<body>
+
+<h2><a name="xmlvalidate">XMLValidate</a></h2>
+<h3>Description</h3>
+
+<p>This task checks that XML files are valid (or only well formed). The
+task uses the SAX2 parser implementation provided by JAXP by default
+(probably the one that is used by Apache Ant itself), but one can specify any
+SAX1/2 parser if needed.</p>
+
+<p>This task supports the use of nested
+ <li><a href="../Types/xmlcatalog.html"><tt>&lt;xmlcatalog&gt;</tt></a> elements</li>
+ <li><tt>&lt;dtd&gt;</tt> elements which are used to resolve DTDs and entities</li>
+ <li><tt>&lt;attribute&gt;</tt> elements which are used to set features on the parser.
+ These can be any number of
+ <a href="http://www.saxproject.org/apidoc/org/xml/sax/package-summary.html#package_description"><tt>http://xml.org/sax/features/</tt></a>
+ or other features that your parser may support.</li>
+ <li><tt>&lt;property&gt;</tt> elements, containing string properties
+</p>
+
+<p><b>Warning</b> : JAXP creates by default a non namespace aware parser.
+The <tt>"http://xml.org/sax/features/namespaces"</tt> feature is set
+by default to <tt>false</tt> by the JAXP implementation used by ant. To validate
+a document containing namespaces,
+set the namespaces feature to <tt>true</tt> explicitly by nesting the following element:
+<pre>
+ &lt;attribute name="http://xml.org/sax/features/namespaces" value="true"/&gt;
+</pre>
+If you are using for instance a <tt>xsi:noNamespaceSchemaLocation</tt> attribute in your XML files,
+you will need this namespace support feature.
+</p>
+<p>If you are using a parser not generated by JAXP, by using the <tt>classname</tt> attribute of xmlvalidate, this warning
+may not apply.</p>
+
+
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">file</td>
+ <td valign="top">the file(s) you want to check. (optionally can use an embedded fileset)</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">lenient</td>
+ <td valign="top">
+ if true, only check the XML document is well formed
+ (ignored if the specified parser is a SAX1 parser)
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">classname</td>
+ <td valign="top">the parser to use.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">classpathref</td>
+ <td valign="top">where to find the parser class. Optionally can use an embedded <tt>&lt;classpath&gt;</tt> element.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">failonerror</td>
+ <td valign="top">fails on a error if set to true (defaults to true).</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">warn</td>
+ <td valign="top">log parser warn events.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+</table>
+
+<h3><a name="nested">Nested Elements</a></h3>
+<h4>dtd</h4>
+<p>
+<tt>&lt;dtd&gt;</tt> is used to specify different locations for DTD resolution.
+</p>
+<table border="1" cellpadding="2" cellspacing="0">
+<tr>
+ <td width="12%" valign="top"><b>Attribute</b></td>
+ <td width="78%" valign="top"><b>Description</b></td>
+ <td width="10%" valign="top"><b>Required</b></td>
+</tr>
+ <tr>
+ <td valign="top">publicId</td>
+ <td valign="top">Public ID of the DTD to resolve</td>
+ <td align="center" valign="top">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">location</td>
+ <td valign="top">Location of the DTD to use, which can be a file,
+ a resource, or a URL</td>
+ <td align="center" valign="top">Yes</td>
+ </tr>
+</table>
+<h4>xmlcatalog</h4>
+<p>The <a href="../Types/xmlcatalog.html"><tt>&lt;xmlcatalog&gt;</tt></a>
+element is used to perform entity resolution.</p>
+<h4>attribute</h4>
+<p>The <tt>&lt;attribute&gt;</tt> element is used to set parser features.<br>
+Features usable with the xerces parser are defined here :
+ <a href="http://xml.apache.org/xerces-j/features.html">Setting features</a><br>
+
+SAX features are defined here:
+ <a href="http://www.saxproject.org/apidoc/org/xml/sax/package-summary.html#package_description"><tt>http://xml.org/sax/features/</tt></a><br>
+ </p>
+<table border="1" cellpadding="2" cellspacing="0">
+<tr>
+ <td width="12%" valign="top"><b>Attribute</b></td>
+ <td width="78%" valign="top"><b>Description</b></td>
+ <td width="10%" valign="top"><b>Required</b></td>
+</tr>
+ <tr>
+ <td valign="top">name</td>
+ <td valign="top">The name of the feature</td>
+ <td align="center" valign="top">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">value</td>
+ <td valign="top">The boolean value of the feature</td>
+ <td align="center" valign="top">Yes</td>
+ </tr>
+</table>
+</p>
+
+<h4>property</h4>
+<p>The <tt>&lt;property&gt;</tt> element is used to set properties.
+These properties are defined here for the xerces XML parser implementation :
+ <a href="http://xml.apache.org/xerces-j/properties.html">XML Parser properties</a>
+Properties can be used to set the schema used to validate the XML file.
+</p>
+<table border="1" cellpadding="2" cellspacing="0">
+<tr>
+ <td width="12%" valign="top"><b>Attribute</b></td>
+ <td width="78%" valign="top"><b>Description</b></td>
+ <td width="10%" valign="top"><b>Required</b></td>
+</tr>
+ <tr>
+ <td valign="top">name</td>
+ <td valign="top">The name of the feature</td>
+ <td align="center" valign="top">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">value</td>
+ <td valign="top">The string value of the property</td>
+ <td align="center" valign="top">Yes</td>
+ </tr>
+</table>
+</p>
+
+
+<h3>Examples</h3>
+<pre>
+&lt;xmlvalidate file="toto.xml"/&gt;
+</pre>
+Validate toto.xml
+<pre>
+&lt;xmlvalidate failonerror="no" lenient="yes" warn="yes"
+ classname="org.apache.xerces.parsers.SAXParser"&gt;
+ classpath="lib/xerces.jar"&gt;
+ &lt;fileset dir="src" includes="style/*.xsl"/&gt;
+&lt;/xmlvalidate&gt;
+</pre>
+Validate all .xsl files in src/style, but only warn if there is an error, rather than
+halt the build.
+<pre>
+
+&lt;xmlvalidate file="struts-config.xml" warn="false"&gt;
+ &lt;dtd publicId="-//Apache Software Foundation//DTD Struts Configuration 1.0//EN"
+ location="struts-config_1_0.dtd"/&gt;
+&lt;/xmlvalidate&gt;
+</pre>
+
+Validate a struts configuration, using a local copy of the DTD.
+<pre>
+&lt;xmlvalidate failonerror="no"&gt;
+ &lt;fileset dir="${project.dir}" includes="**/*.xml"/&gt;
+ &lt;xmlcatalog refid="mycatalog"/&gt;
+&lt;/xmlvalidate&gt;
+</pre>
+
+Scan all XML files in the project, using a predefined catalog to map URIs to local files.
+<pre>
+&lt;xmlvalidate failonerror="no"&gt;
+ &lt;fileset dir="${project.dir}" includes="**/*.xml"/&gt;
+ &lt;xmlcatalog&gt;
+ &lt;dtd
+ publicId=&quot;-//ArielPartners//DTD XML Article V1.0//EN&quot;
+ location=&quot;com/arielpartners/knowledgebase/dtd/article.dtd&quot;/&gt;
+ &lt;/xmlcatalog&gt;
+&lt;/xmlvalidate&gt;
+</pre>
+Scan all XML files in the project, using the catalog defined inline.
+
+<pre>
+&lt;xmlvalidate failonerror="yes" lenient="no" warn="yes"&gt;
+ &lt;fileset dir="xml" includes="**/*.xml"/&gt;
+ &lt;attribute name="http://xml.org/sax/features/validation" value="true"/&gt;
+ &lt;attribute name="http://apache.org/xml/features/validation/schema" value="true"/&gt;
+ &lt;attribute name="http://xml.org/sax/features/namespaces" value="true"/&gt;
+&lt;/xmlvalidate&gt;
+</pre>
+Validate all .xml files in xml directory with the parser configured to perform XSD validation.
+Note: The parser must support the feature
+<code>http://apache.org/xml/features/validation/schema</code>.
+The <a href="schemavalidate.html">schemavalidate</a> task is better for validating
+W3C XML Schemas, as it extends this task with the right options automatically enabled,
+and makes it easy to add a list of schema files/URLs to act as sources.
+
+<pre>
+<!-- Converts path to URL format -->
+&lt;pathconvert dirsep="/" property="xsd.file"&gt;
+&lt;path&gt;
+ &lt;pathelement location="xml/doc.xsd"/&gt;
+&lt;/path&gt;
+&lt;/pathconvert&gt;
+
+&lt;xmlvalidate file="xml/endpiece-noSchema.xml" lenient="false"
+ failonerror="true" warn="true"&gt;
+ &lt;attribute name="http://apache.org/xml/features/validation/schema"
+ value="true"/&gt;
+ &lt;attribute name="http://xml.org/sax/features/namespaces" value="true"/&gt;
+ &lt;property
+ name="http://apache.org/xml/properties/schema/external-noNamespaceSchemaLocation"
+ value="${xsd.file}"/&gt;
+&lt;/xmlvalidate&gt;
+</pre>
+<br>
+Validate the file xml/endpiece-noSchema.xml against the schema xml/doc.xsd.
+<br>
+
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Tasks/zip.html b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/zip.html
new file mode 100644
index 00000000..4d66851a
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Tasks/zip.html
@@ -0,0 +1,551 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Zip Task</title>
+</head>
+
+<body>
+
+<h2><a name="zip">Zip</a></h2>
+<h3>Description</h3>
+<p>Creates a zipfile.</p>
+<p>The <i>basedir</i> attribute is the reference directory from where to zip.</p>
+<p>Note that file permissions will not be stored in the resulting zipfile.</p>
+<p>It is possible to refine the set of files that are being zipped. This can be
+done with the <i>includes</i>, <i>includesfile</i>, <i>excludes</i>, <i>excludesfile</i> and <i>defaultexcludes</i>
+attributes. With the <i>includes</i> or <i>includesfile</i> attribute you specify the files you want to
+have included by using patterns. The <i>exclude</i> or <i>excludesfile</i> attribute is used to specify
+the files you want to have excluded. This is also done with patterns. And
+finally with the <i>defaultexcludes</i> attribute, you can specify whether you
+want to use default exclusions or not. See the section on <a
+href="../dirtasks.html#directorybasedtasks">directory based tasks</a>, on how the
+inclusion/exclusion of files works, and how to write patterns. </p>
+<p>This task forms an implicit <a href="../Types/fileset.html">FileSet</a> and
+supports most attributes of <code>&lt;fileset&gt;</code>
+(<code>dir</code> becomes <code>basedir</code>) as well as the nested
+<code>&lt;include&gt;</code>, <code>&lt;exclude&gt;</code> and
+<code>&lt;patternset&gt;</code> elements.</p>
+<p>Or, you may place within it nested file sets, or references to file sets.
+In this case <code>basedir</code> is optional; the implicit file set is <i>only used</i>
+if <code>basedir</code> is set. You may use any mixture of the implicit file set
+(with <code>basedir</code> set, and optional attributes like <code>includes</code>
+and optional subelements like <code>&lt;include&gt;</code>); explicit nested
+<code>&lt;fileset&gt;</code> elements so long as at least one fileset total is specified. The ZIP file will
+only reflect the relative paths of files <i>within</i> each fileset. The Zip task and its derivatives know a special form of a fileset named zipfileset that has additional attributes (described below). </p>
+<p>The Zip task also supports the merging of multiple zip files into the zip file.
+This is possible through either the <i>src</i> attribute of any nested filesets
+or by using the special nested fileset <i>zipgroupfileset</i>.</p>
+
+<p>The <code>update</code> parameter controls what happens if the ZIP
+file already exists. When set to <code>yes</code>, the ZIP file is
+updated with the files specified. (New files are added; old files are
+replaced with the new versions.) When set to <code>no</code> (the
+default) the ZIP file is overwritten if any of the files that would be
+added to the archive are newer than the entries inside the archive.
+Please note that ZIP files store file modification times with a
+granularity of two seconds. If a file is less than two seconds newer
+than the entry in the archive, Apache Ant will not consider it newer.</p>
+
+<p>The <code>whenempty</code> parameter controls what happens when no files match.
+If <code>skip</code> (the default), the ZIP is not created and a warning is issued.
+If <code>fail</code>, the ZIP is not created and the build is halted with an error.
+If <code>create</code>, an empty ZIP file (explicitly zero entries) is created,
+which should be recognized as such by compliant ZIP manipulation tools.</p>
+<p>This task will now use the platform's default character encoding
+for filenames - this is consistent with the command line ZIP tools,
+but causes problems if you try to open them from within Java and your
+filenames contain non US-ASCII characters. Use the encoding attribute
+and set it to UTF8 to create zip files that can safely be read by
+Java. For a more complete discussion,
+see <a href="#encoding">below</a></p>
+
+<p>Starting with Ant 1.5.2, <code>&lt;zip&gt;</code> can store Unix permissions
+inside the archive (see description of the filemode and dirmode
+attributes for <a href="../Types/zipfileset.html">&lt;zipfileset&gt;</a>).
+Unfortunately there is no portable way to store these permissions.
+Ant uses the algorithm used by <a href="http://www.info-zip.org">Info-Zip's</a>
+implementation of the zip and unzip commands - these are the default
+versions of zip and unzip for many Unix and Unix-like systems.</p>
+
+<p><b>Please note that the zip format allows multiple files of the same
+fully-qualified name to exist within a single archive. This has been
+documented as causing various problems for unsuspecting users. If you wish
+to avoid this behavior you must set the <code>duplicate</code> attribute
+to a value other than its default, <code>&quot;add&quot;</code>.</b></p>
+
+<p><b>Please also note</b> that different ZIP tools handle timestamps
+differently when it comes to applying timezone offset calculations of
+files. Some ZIP libraries will store the timestamps as they've been
+read from the filesystem while others will modify the timestamps both
+when reading and writing the files to make all timestamps use the same
+timezone. A ZIP archive created by one library may extract files with
+"wrong timestamps" when extracted by another library.</p>
+
+<p>Ant's ZIP classes use the same algorithm as the InfoZIP tools and
+zlib (timestamps get adjusted), Windows' "compressed folders" function
+and WinZIP don't change the timestamps. This means that using the
+unzip task on files created by Windows' compressed folders function
+may create files with timestamps that are "wrong", the same is true if
+you use Windows' functions to extract an Ant generated ZIP
+archive.</p>
+
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td valign="top" align="center"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">destfile</td>
+ <td valign="top">the zip-file to create.</td>
+ <td align="center" valign="top" rowspan="2">Exactly one of the two.</td>
+ </tr>
+ <tr>
+ <td valign="top">zipfile</td>
+ <td valign="top">the <i>deprecated</i> old name of destfile.</td>
+ </tr>
+ <tr>
+ <td valign="top">basedir</td>
+ <td valign="top">the directory from which to zip the files.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">compress</td>
+ <td valign="top">Not only store data but also compress them,
+ defaults to true. Unless you set the <em>keepcompression</em>
+ attribute to false, this will apply to the entire archive, not
+ only the files you've added while updating.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">keepcompression</td>
+ <td valign="top">For entries coming from existing archives (like
+ nested <em>zipfileset</em>s or while updating the archive), keep
+ the compression as it has been originally instead of using the
+ <em>compress</em> attribute. Defaults false. <em>Since Ant
+ 1.6</em></td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">encoding</td>
+ <td valign="top">The character encoding to use for filenames
+ inside the zip file. For a list of possible values see the <a
+ href="http://docs.oracle.com/javase/7/docs/technotes/guides/intl/encoding.doc.html">Supported Encodings</a>.<br/>
+ Defaults to the platform's default character encoding.
+ <br/>See also the <a href="#encoding">discussion below</a></td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">filesonly</td>
+ <td valign="top">Store only file entries, defaults to false</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">includes</td>
+ <td valign="top">comma- or space-separated list of patterns of files that must be
+ included. All files are included when omitted.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">includesfile</td>
+ <td valign="top">the name of a file. Each line of this file is
+ taken to be an include pattern</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">excludes</td>
+ <td valign="top">comma- or space-separated list of patterns of files that must be
+ excluded. No files (except default excludes) are excluded when omitted.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">excludesfile</td>
+ <td valign="top">the name of a file. Each line of this file is
+ taken to be an exclude pattern</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">defaultexcludes</td>
+ <td valign="top">indicates whether default excludes should be used or not
+ (&quot;yes&quot;/&quot;no&quot;). Default excludes are used when omitted.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">update</td>
+ <td valign="top">indicates whether to update or overwrite
+ the destination file if it already exists. Default is &quot;false&quot;.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">whenempty</td>
+ <td valign="top">behavior when no files match. Valid values are &quot;fail&quot;, &quot;skip&quot;, and &quot;create&quot;. Default is &quot;skip&quot;.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">duplicate</td>
+ <td valign="top">behavior when a duplicate file is found. Valid values are &quot;add&quot;, &quot;preserve&quot;, and &quot;fail&quot;. The default value is &quot;add&quot;. </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">roundup</td>
+ <td valign="top">Whether the file modification times will be
+ rounded up to the next even number of seconds.<br>
+ Zip archives store file modification times with a granularity of
+ two seconds, so the times will either be rounded up or down. If
+ you round down, the archive will always seem out-of-date when you
+ rerun the task, so the default is to round up. Rounding up may
+ lead to a different type of problems like JSPs inside a web
+ archive that seem to be slightly more recent than precompiled
+ pages, rendering precompilation useless.<br>
+ Defaults to true. <em>Since Ant 1.6.2</em></td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">comment</td>
+ <td valign="top">Comment to store in the archive. <em>Since Ant 1.6.3</em></td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">level</td>
+ <td valign="top">Non-default level at which file compression should be
+ performed. Valid values range from 0 (no compression/fastest) to 9
+ (maximum compression/slowest). <em>Since Ant 1.7</em></td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">preserve0permissions</td>
+ <td valign="top">when updating an archive or adding entries from a
+ different archive Ant will assume that a Unix permissions value of
+ 0 (nobody is allowed to do anything to the file/directory) means
+ that the permissions haven't been stored at all rather than real
+ permissions and will instead apply its own default values.<br/>
+ Set this attribute to true if you really want to preserve the
+ original permission field.<em>since Ant 1.8.0</em>
+ </td>
+ <td valign="top" align="center">No, default is false</td>
+ </tr>
+ <tr>
+ <td valign="top">useLanguageEncodingFlag</td>
+ <td valign="top">Whether to set the language encoding flag if the
+ encoding is UTF-8. This setting doesn't have any effect if the
+ encoding is not UTF-8.
+ <em>Since Ant 1.8.0</em>.
+ <br/>See also the <a href="#encoding">discussion below</a></td>
+ <td align="center" valign="top">No, default is true</td>
+ </tr>
+ <tr>
+ <td valign="top">createUnicodeExtraFields</td>
+ <td valign="top">Whether to create unicode extra fields to store
+ the file names a second time inside the entry's metadata.
+ <br>Possible values are "never", "always" and "not-encodeable"
+ which will only add Unicode extra fields if the file name cannot
+ be encoded using the specified encoding.
+ <em>Since Ant 1.8.0</em>.
+ <br/>See also the <a href="#encoding">discussion below</a></td>
+ <td align="center" valign="top">No, default is "never"</td>
+ </tr>
+ <tr>
+ <td valign="top">fallbacktoUTF8</td>
+ <td valign="top">Whether to use UTF-8 and the language encoding
+ flag instead of the specified encoding if a file name cannot be
+ encoded using the specified encoding.
+ <em>Since Ant 1.8.0</em>.
+ <br/>See also the <a href="#encoding">discussion below</a></td>
+ <td align="center" valign="top">No, default is false</td>
+ </tr>
+ <tr>
+ <td valign="top">zip64Mode</td>
+ <td valign="top">When to use Zip64 extensions for entries. The
+ possible values are "never", "always" and "as-needed".
+ <em>Since Ant 1.9.1</em>.
+ <br/>See also the <a href="#zip64">discussion below</a></td>
+ <td align="center" valign="top">No, default is "as-needed"</td>
+ </tr>
+</table>
+
+<h3><a name="encoding">Encoding of File Names</a></h3>
+
+<p>Traditionally the ZIP archive format uses CodePage 437 as encoding
+ for file name, which is not sufficient for many international
+ character sets.</p>
+
+<p>Over time different archivers have chosen different ways to work
+ around the limitation - the <code>java.util.zip</code> packages
+ simply uses UTF-8 as its encoding for example.</p>
+
+<p>Ant has been offering the encoding attribute of the zip and unzip
+ task as a way to explicitly specify the encoding to use (or expect)
+ since Ant 1.4. It defaults to the platform's default encoding for
+ zip and UTF-8 for jar and other jar-like tasks (war, ear, ...) as
+ well as the unzip family of tasks.</p>
+
+<p>More recent versions of the ZIP specification introduce something
+ called the &quot;language encoding flag&quot; which can be used to
+ signal that a file name has been encoded using UTF-8. Starting with
+ Ant 1.8.0 all zip-/jar- and similar archives written by Ant will set
+ this flag, if the encoding has been set to UTF-8. Our
+ interoperabilty tests with existing archivers didn't show any ill
+ effects (in fact, most archivers ignore the flag to date), but you
+ can turn off the "language encoding flag" by setting the attribute
+ <code>useLanguageEncodingFlag</code> to <code>false</code> on the
+ zip-task if you should encounter problems.</p>
+
+<p>The unzip (and similar tasks) -task will recognize the language
+ encoding flag and ignore the encoding set on the task if it has been
+ found.</p>
+
+<p>The InfoZIP developers have introduced new ZIP extra fields that
+ can be used to add an additional UTF-8 encoded file name to the
+ entry's metadata. Most archivers ignore these extra fields. The
+ zip family of tasks support an
+ option <code>createUnicodeExtraFields</code> since Ant 1.8.0 which
+ makes Ant write these extra fields either for all entries ("always")
+ or only those whose name cannot be encoded using the specified
+ encoding (not-encodeable), it defaults to "never" since the extra
+ fields create bigger archives.</p>
+
+<p>The fallbackToUTF8 attribute of zip can be used to create archives
+ that use the specified encoding in the majority of cases but UTF-8 and
+ the language encoding flag for filenames that cannot be encoded
+ using the specified encoding.</p>
+
+<p>The unzip-task will recognize the unicode extra fields by default
+ and read the file name information from them, unless you set the
+ optional attribute <code>scanForUnicodeExtraFields</code> to
+ false.</p>
+
+<h4>Recommendations for Interoperability</h4>
+
+<p>The optimal setting of flags depends on the archivers you expect as
+ consumers/producers of the ZIP archives. Below are some test
+ results which may be superseeded with later versions of each
+ tool.</p>
+
+<ul>
+ <li>The java.util.zip package used by the jar executable or to read
+ jars from your CLASSPATH reads and writes UTF-8 names, it doesn't
+ set or recognize any flags or unicode extra fields.</li>
+
+ <li>Starting with Java7 <code>java.util.zip</code> writes UTF-8 by
+ default and uses the language encoding flag. It is possible to
+ specify a different encoding when reading/writing ZIPs via new
+ constructors. The package now recognizes the language encoding
+ flag when reading and ignores the Unicode extra fields.</li>
+
+ <li>7Zip writes CodePage 437 by default but uses UTF-8 and the
+ language encoding flag when writing entries that cannot be encoded
+ as CodePage 437 (similar to the zip task with fallbacktoUTF8 set
+ to true). It recognizes the language encoding flag when reading
+ and ignores the unicode extra fields.</li>
+
+ <li>WinZIP writes CodePage 437 and uses unicode extra fields by
+ default. It recognizes the unicode extra field and the language
+ encoding flag when reading.</li>
+
+ <li>Windows' "compressed folder" feature doesn't recognize any flag
+ or extra field and creates archives using the platforms default
+ encoding - and expects archives to be in that encoding when reading
+ them.</li>
+
+ <li>InfoZIP based tools can recognize and write both, it is a
+ compile time option and depends on the platform so your mileage
+ may vary.</li>
+
+ <li>PKWARE zip tools recognize both and prefer the language encoding
+ flag. They create archives using CodePage 437 if possible and UTF-8
+ plus the language encoding flag for file names that cannot be
+ encoded as CodePage 437.</li>
+</ul>
+
+<p>So, what to do?</p>
+
+<p>If you are creating jars, then java.util.zip is your main
+ consumer. We recommend you set the encoding to UTF-8 and keep the
+ language encoding flag enabled. The flag won't help or hurt
+ java.util.zip prior to Java7 but archivers that support it will show
+ the correct file names.</p>
+
+<p>For maximum interop it is probably best to set the encoding to
+ UTF-8, enable the language encoding flag and create unicode extra
+ fields when writing ZIPs. Such archives should be extracted
+ correctly by java.util.zip, 7Zip, WinZIP, PKWARE tools and most
+ likely InfoZIP tools. They will be unusable with Windows'
+ "compressed folders" feature and bigger than archives without the
+ unicode extra fields, though.</p>
+
+<p>If Windows' "compressed folders" is your primary consumer, then
+ your best option is to explicitly set the encoding to the target
+ platform. You may want to enable creation of unicode extra fields
+ so the tools that support them will extract the file names
+ correctly.</p>
+
+<h3><a name="zip64">Zip64 extensions</a></h3>
+
+<p>Zip64 extensions provide a way to create archives bigger than 4GB
+ or holding more than 65535 entries - or add individual entries
+ bigger than 4GB using the ZIP extension field mechanism. These
+ extensions are supported by most modern ZIP implementations.</p>
+
+<p>When Ant writes compressed entries into the archive it creates it
+ doesn't know the compressed size of an entry before it has been
+ written. Unfortunately the decision whether a Zip64 extra field
+ will be written has to be made before writing the entry's
+ content.</p>
+
+<p>Starting with Ant 1.9.0 Ant supports Zip64 extensions but didn't
+ provide any control over their usage, starting with Ant 1.9.1 a
+ new <em>zip64mode</em> attribute was added to the <code>zip</code>
+ family of tasks. It supports three values:
+
+<ul>
+ <li><em>never</em> means no Zip64 extra fields will ever be
+ written, this is the behavior of Ant 1.8.x and earlier and the
+ default behavior of <code>jar</code>, <code>ear</code>
+ and <code>war</code> starting with Ant 1.9.1.</li>
+ <li><em>always</em> means Zip64 extra fields are written for all
+ entries.</li>
+ <li><em>as-needed</em> means Zip64 extra fields are written for all
+ compressed entries to the "local file header" (by default these
+ are all files but not the directories) but only written to the
+ central directory if the entry really required Zip64 features.
+ This is the default behavior of Ant 1.9.0 and remains the default
+ behavior of the <code>zip</code> task.</li>
+</ul>
+
+<p><em>as-needed</em> provides a good compromise if you don't know
+ whether you archive will exceed the limits of traditional zip files
+ but don't want to waste too much space (the Zip64 extensions take up
+ extra space). Unfortunately some ZIP implementations don't
+ understand Zip64 extra fields or fail to parse archives with extra
+ fields in local file headers that are not present in the central
+ directory, one such implementation is the java.util.zip package of
+ Java5, that's why the <code>jar</code> tasks default
+ to <em>never</em>. Archives created with <em>as-needed</em> can be
+ read without problems with Java6 and later.</p>
+
+<h3>Parameters specified as nested elements</h3>
+
+<h4>any resource collection</h4>
+<p><a href="../Types/resources.html#collection">Resource
+Collection</a>s are used to select groups of files to archive.</p>
+<p>Prior to Ant 1.7 only <code>&lt;fileset&gt;</code> and
+<code>&lt;zipfileset&gt;</code> have been supported as nested elements.</p>
+
+<a name="zipgroupfileset" />
+<h4>zipgroupfileset</h4>
+<p>A <code>&lt;zipgroupfileset&gt;</code> allows for multiple zip files to be
+merged into the archive. Each file found in this fileset is added to the archive
+the same way that <i>zipfileset src</i> files are added.</p>
+
+<p><code>&lt;zipgroupfileset&gt;</code> is
+ a <a href="../Types/fileset.html">fileset</a> and supports all
+ of its attributes and nested elements.</a>
+
+<h3>Examples</h3>
+<pre> &lt;zip destfile=&quot;${dist}/manual.zip&quot;
+ basedir=&quot;htdocs/manual&quot;
+ /&gt;</pre>
+<p>zips all files in the <code>htdocs/manual</code> directory into a file called <code>manual.zip</code>
+in the <code>${dist}</code> directory.</p>
+<pre> &lt;zip destfile=&quot;${dist}/manual.zip&quot;
+ basedir=&quot;htdocs/manual&quot;
+ update=&quot;true&quot;
+ /&gt;</pre>
+<p>zips all files in the <code>htdocs/manual</code> directory into a file called <code>manual.zip</code>
+in the <code>${dist}</code> directory. If <code>manual.zip</code>
+doesn't exist, it is created; otherwise it is updated with the
+new/changed files.</p>
+<pre> &lt;zip destfile=&quot;${dist}/manual.zip&quot;
+ basedir=&quot;htdocs/manual&quot;
+ excludes=&quot;mydocs/**, **/todo.html&quot;
+ /&gt;</pre>
+<p>zips all files in the <code>htdocs/manual</code> directory. Files in the directory <code>mydocs</code>,
+or files with the name <code>todo.html</code> are excluded.</p>
+<pre> &lt;zip destfile=&quot;${dist}/manual.zip&quot;
+ basedir=&quot;htdocs/manual&quot;
+ includes=&quot;api/**/*.html&quot;
+ excludes=&quot;**/todo.html&quot;
+ /&gt;</pre>
+<p>zips all files in the <code>htdocs/manual</code> directory. Only html files under the directory <code>api</code>
+are zipped, and files with the name <code>todo.html</code> are excluded.</p>
+<pre> &lt;zip destfile=&quot;${dist}/manual.zip&quot;&gt;
+ &lt;fileset dir=&quot;htdocs/manual&quot;/&gt;
+ &lt;fileset dir=&quot;.&quot; includes=&quot;ChangeLog.txt&quot;/&gt;
+ &lt;/zip&gt;</pre>
+<p>zips all files in the <code>htdocs/manual</code> directory, and also adds the file <code>ChangeLog.txt</code> in the
+current directory. <code>ChangeLog.txt</code> will be added to the top of the ZIP file, just as if
+it had been located at <code>htdocs/manual/ChangeLog.txt</code>.</p>
+<pre> &lt;zip destfile=&quot;${dist}/manual.zip&quot;&gt;
+ &lt;zipfileset dir=&quot;htdocs/manual&quot; prefix=&quot;docs/user-guide&quot;/&gt;
+ &lt;zipfileset dir=&quot;.&quot; includes=&quot;ChangeLog27.txt&quot; fullpath=&quot;docs/ChangeLog.txt&quot;/&gt;
+ &lt;zipfileset src=&quot;examples.zip&quot; includes=&quot;**/*.html&quot; prefix=&quot;docs/examples&quot;/&gt;
+ &lt;/zip&gt;</pre>
+<p>zips all files in the <code>htdocs/manual</code> directory into the <code>docs/user-guide</code> directory
+in the archive, adds the file <code>ChangeLog27.txt</code> in the
+current directory as <code>docs/ChangeLog.txt</code>, and includes all the html files in <code>examples.zip</code>
+under <code>docs/examples</code>. The archive might end up containing the files:</p>
+<pre> docs/user-guide/html/index.html
+ docs/ChangeLog.txt
+ docs/examples/index.html
+</pre>
+<p>
+The code
+<pre>
+ &lt;zip destfile=&quot;${dist}/manual.zip&quot;&gt;
+ &lt;zipfileset dir=&quot;htdocs/manual&quot; prefix=&quot;docs/user-guide&quot;/&gt;
+ &lt;zipgroupfileset dir=&quot;.&quot; includes=&quot;examples*.zip&quot;/&gt;
+ &lt;/zip&gt;
+</pre>
+<p>
+<p>zips all files in the <code>htdocs/manual</code> directory into the <code>docs/user-guide</code> directory in the archive and includes all the files in any file that matches <code>examples*.zip</code>, such as all files within <code>examples1.zip</code> or <code>examples_for_brian.zip</code>.
+The same can be achieved with
+<pre>
+ &lt;zip destfile=&quot;${dist}/manual.zip&quot;&gt;
+ &lt;mappedresources&gt;
+ &lt;fileset dir=&quot;htdocs/manual&quot;/&gt;
+ &lt;globmapper from="*" to="docs/user-guide/*"/&gt;
+ &lt;/mappedresources&gt;
+ &lt;archives&gt;
+ &lt;zips&gt;
+ &lt;fileset dir=&quot;.&quot; includes=&quot;examples*.zip&quot;/&gt;
+ &lt;/zips&gt;
+ &lt;/archives&gt;
+ &lt;/zip&gt;
+</pre>
+
+The next example
+
+<pre>
+&lt;zip destfile="release.zip"&gt;
+ &lt;tarfileset src="release.tar"/&gt;
+&lt;/zip&gt;
+</pre>
+
+<p>re-packages a TAR archive as a ZIP archive. If Unix file
+permissions have been stored as part of the TAR file, they will be
+retained in the resulting ZIP archive.</p>
+
+
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Types/antlib.html b/framework/src/ant/apache-ant-1.9.6/manual/Types/antlib.html
new file mode 100644
index 00000000..925320ae
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Types/antlib.html
@@ -0,0 +1,266 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+ <head>
+ <meta http-equiv="Content-Language" content="en-us"></meta>
+ <link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+ <title>AntLib</title>
+ </head>
+
+ <body>
+ <h2><a name="antlib">Antlib</a></h2>
+
+
+ <h3>Description</h3>
+ <p>
+ An antlib file is an xml file with a root element of "antlib".
+ Antlib's elements are Apache Ant definition tasks - like
+ <a href="../Tasks/taskdef.html">Taskdef</a>
+ or any Ant task that extends
+ <code>org.apache.tools.ant.taskdefs.AntlibDefinition</code>.
+ </p>
+ <p>
+ The current set of declarations bundled with Ant that do this are:
+ </p>
+ <ol>
+ <li><a href="../Tasks/typedef.html">Typedef</a>
+ </li>
+ <li><a href="../Tasks/taskdef.html">Taskdef</a>
+ </li>
+ <li><a href="../Tasks/macrodef.html">Macrodef</a>
+ </li>
+ <li><a href="../Tasks/presetdef.html">Presetdef</a>
+ </li>
+ <li><a href="../Tasks/scriptdef.html">Scriptdef</a>
+ </li>
+ </ol>
+ <p>
+ A group of tasks and types may be defined together in an antlib
+ file. For example the file <i>sample.xml</i> contains the following:
+ </p>
+ <blockquote>
+ <pre>
+&lt;?xml version="1.0"?&gt;
+&lt;antlib&gt;
+ &lt;typedef name="if" classname="org.acme.ant.If"/&gt;
+ &lt;typedef name="scriptpathmapper"
+ classname="org.acme.ant.ScriptPathMapper"
+ onerror="ignore"/&gt;
+ &lt;macrodef name="print"&gt;
+ &lt;attribute name="file"/&gt;
+ &lt;sequential&gt;
+ &lt;concat taskname="print"&gt;
+ &lt;fileset dir="." includes="@{file}"/&gt;
+ &lt;/concat&gt;
+ &lt;/sequential&gt;
+ &lt;/macrodef&gt;
+&lt;/antlib&gt;
+ </pre>
+ </blockquote>
+ <p>
+ It defines two types or tasks, <i>if</i> and <i>scriptpathmapper</i>.
+ This antlib file may be used in a build script as follows:
+ </p>
+ <blockquote>
+ <pre>
+&lt;typedef file="sample.xml"/&gt;
+ </pre>
+ </blockquote>
+ <p>
+ The other attributes of <code>&lt;typedef&gt;</code> may be used as well.
+ For example, assuming that the <i>sample.xml</i> is in a jar
+ file <i>sample.jar</i> also containing the classes, the
+ following build fragment will define the <i>if</i> and <i>scriptpathmapper</i>
+ tasks/types and place them in the namespace uri <i>samples:/acme.org</i>.
+ </p>
+ <blockquote>
+ <pre>
+&lt;typedef resource="org/acme/ant/sample.xml"
+ uri="samples:/acme.org"/&gt;
+ </pre>
+ </blockquote>
+ <p>
+ The definitions may then be used as follows:
+ </p>
+ <blockquote>
+ <pre>
+&lt;sample:if valuetrue="${props}" xmlns:sample="samples:/acme.org"&gt;
+ &lt;sample:scriptpathmapper language="beanshell"&gt;
+ some bean shell
+ &lt;/sample:scriptpathmapper&gt;
+&lt;/sample:if&gt;
+ </pre>
+ </blockquote>
+
+
+ <h3><a name="antlibnamespace">Antlib namespace</a></h3>
+ <p>
+ The name space URIs with the pattern <b>antlib:<i>java package</i></b>
+ are given special treatment.
+ </p>
+ <p>
+ When Ant encounters a element with a namespace URI with this pattern, it
+ will check to see if there is a resource of the name <i>antlib.xml</i> in
+ the package directory in the default classpath.
+ </p>
+ <p>
+ For example, assuming that the file <i>antcontrib.jar</i> has been placed
+ in the directory <i>${ant.home}/lib</i> and it contains the resource
+ <i>net/sf/antcontrib/antlib.xml</i> which has all antcontrib's definitions
+ defined, the following build file will automatically load the antcontrib
+ definitions at location <i>HERE</i>:
+ </p>
+ <blockquote>
+ <pre>
+&lt;project default="deletetest" xmlns:antcontrib="antlib:net.sf.antcontrib"&gt;
+ &lt;macrodef name="showdir"&gt;
+ &lt;attribute name="dir"/&gt;
+ &lt;sequential&gt;
+ &lt;antcontrib:shellscript shell="bash"&gt; &lt;!-- HERE --&gt;
+ ls -Rl @{dir}
+ &lt;/antcontrib:shellscript&gt;
+ &lt;/sequential&gt;
+ &lt;/macrodef&gt;
+
+ &lt;target name="deletetest"&gt;
+ &lt;delete dir="a" quiet="yes"/&gt;
+ &lt;mkdir dir="a/b"/&gt;
+ &lt;touch file="a/a.txt"/&gt;
+ &lt;touch file="a/b/b.txt"/&gt;
+ &lt;delete&gt;
+ &lt;fileset dir="a"/&gt;
+ &lt;/delete&gt;
+ &lt;showdir dir="a"/&gt;
+ &lt;/target&gt;
+&lt;/project&gt;
+ </pre>
+ </blockquote>
+ <p>
+ The requirement that the resource is in the default classpath
+ may be removed in future versions of Ant.</p>
+ </p>
+
+
+ <h3><a name="loadFromInside">Load antlib from inside of the buildfile</a></h3>
+ <p>
+ If you want to separate the antlib from your local Ant installation, e.g. because you
+ want to hold that jar in your projects SCM system, you have to specify a classpath, so
+ that Ant could find that jar. The best solution is loading the antlib with <tt>&lt;taskdef&gt;</tt>.
+ </p>
+ <blockquote>
+ <pre>
+&lt;project xmlns:<font color="green">antcontrib</font>="<font color="red">antlib:net.sf.antcontrib</font>"&gt;
+ &lt;taskdef uri="<font color="red">antlib:net.sf.antcontrib</font>"
+ resource="net/sf/antcontrib/antlib.xml"
+ classpath="path/to/ant-contrib.jar"/&gt;
+
+ &lt;target name="iterate"&gt;
+ &lt;<font color="green">antcontrib</font>:for param="file"&gt;
+ &lt;fileset dir="."/&gt;
+ &lt;sequential&gt;
+ &lt;echo message="- @{file}"/&gt;
+ &lt;/sequential&gt;
+ &lt;/antcontrib:for&gt;
+ &lt;/target&gt;
+&lt;/project&gt;
+ </pre>
+ </blockquote>
+
+
+
+
+ <h3><a name="currentnamespace">Current namespace</a></h3>
+ <p>
+ Definitions defined in antlibs may be used in antlibs. However
+ the namespace that definitions are placed in are dependent on
+ the <code>&lt;typedef&gt;</code> that uses the antlib. To deal with this
+ problem, the definitions are placed in the namespace URI <i>ant:current</i>
+ for the duration of the antlib execution.
+ For example the following antlib defines the task <code>&lt;if&gt;</code>, the
+ type <code>&lt;isallowed&gt;</code> and a macro
+ <code>&lt;ifallowed&gt;</code> that makes use of the task and type:
+ </p>
+ <blockquote>
+ <pre>
+&lt;antlib xmlns:current="ant:current"&gt;
+ &lt;taskdef name="if" classname="org.acme.ant.If"/&gt;
+ &lt;typedef name="isallowed" classname="org.acme.ant.Isallowed"/&gt;
+ &lt;macrodef name="ifallowed"&gt;
+ &lt;attribute name="action"/&gt;
+ &lt;element name="do"/&gt;
+ &lt;sequential&gt;
+ &lt;current:if&gt;
+ &lt;current:isallowed test="@{action}"/&gt;
+ &lt;current:then&gt;
+ &lt;do/&gt;
+ &lt;/current:then&gt;
+ &lt;/current:if&gt;
+ &lt;/sequential&gt;
+ &lt;/macrodef&gt;
+&lt;/antlib&gt;
+ </pre>
+ </blockquote>
+
+
+ <h3>Other examples and comments</h3>
+ <p>
+ Antlibs may make use of other antlibs.
+ </p>
+ <p>
+ As the names defined in the antlib are in the namespace uri as
+ specified by the calling <code>&lt;typedef&gt;</code> or by automatic element
+ resolution, one may reuse names from core ant types and tasks,
+ provided the caller uses a namespace uri. For example, the
+ following antlib may be used to define defaults for various
+ tasks:
+ </p>
+ <blockquote>
+ <pre>
+&lt;antlib xmlns:antcontrib="antlib:net.sf.antcontrib"&gt;
+ &lt;presetdef name="javac"&gt;
+ &lt;javac deprecation="${deprecation}"
+ debug="${debug}"/&gt;
+ &lt;/presetdef&gt;
+ &lt;presetdef name="delete"&gt;
+ &lt;delete quiet="yes"/&gt;
+ &lt;/presetdef&gt;
+ &lt;presetdef name="shellscript"&gt;
+ &lt;antcontrib:shellscript shell="bash"/&gt;
+ &lt;/presetdef&gt;
+&lt;/antlib&gt;
+ </pre>
+ </blockquote>
+ <p>
+ This may be used as follows:
+ </p>
+ <blockquote>
+ <pre>
+&lt;project xmlns:local="localpresets"&gt;
+ &lt;typedef file="localpresets.xml" uri="localpresets"/&gt;
+ &lt;local:shellscript&gt;
+ echo "hello world"
+ &lt;/local:shellscript&gt;
+&lt;/project&gt;
+ </pre>
+ </blockquote>
+
+
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Types/assertions.html b/framework/src/ant/apache-ant-1.9.6/manual/Types/assertions.html
new file mode 100644
index 00000000..e168969f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Types/assertions.html
@@ -0,0 +1,208 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Assertions type</title>
+</head>
+
+<body>
+
+<h2><a name="assertions">Assertions</a></h2>
+<p>
+The <tt>assertions</tt> type enables or disables the Java 1.4 assertions feature,
+on a whole Java program, or components of a program. It can be used
+in <a href="../Tasks/java.html"><code>&lt;java&gt;</code></a> and
+<a href="../Tasks/junit.html"><code>&lt;junit&gt;</code></a> to add extra validation to code.
+
+<p>
+Assertions are covered in the
+<a href="http://docs.oracle.com/javase/7/docs/technotes/guides/language/assert.html">Java SE documentation</a>,
+and the
+<a href="http://docs.oracle.com/javase/specs/jls/se7/html/jls-14.html#jls-14.10">Java Language Specification</a>.
+
+<p>
+The key points to note are that a <tt>java.lang.AssertionError</tt>
+is thrown when an assertion fails, and that the facility is only available
+on Java 1.4 and later. To enable assertions one must set <tt>source="1.4"</tt>
+(or later) in <tt>&lt;javac&gt;</tt> when the source is being compiled, and
+that the code must contain <tt>assert</tt> statements to be tested. The
+result of such an action is code that neither compiles or runs on earlier
+versions of Java. For this reason Apache Ant itself currently contains no assertions.
+<p>
+
+When assertions are enabled (or disabled) in a task through nested
+assertions elements, the class loader or command line is modified with the
+appropriate options. This means that the JVM executed must be a Java 1.4
+or later JVM, even if there are no assertions in the code. Attempting to
+enable assertions on earlier VMs will result in an "Unrecognized option"
+error and the JVM will not start.
+
+<p>
+<h4>Attributes</h4>
+<p>
+
+
+</p>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">enableSystemAssertions</td>
+ <td valign="top">Flag to turn system assertions on or off.</td>
+ <td valign="top" align="center">No; default is "unspecified"</td>
+ </tr>
+</table>
+<p>
+When system assertions have been neither enabled nor disabled, then
+the JVM is not given any assertion information - the default action of the
+ current JVMs is to disable system assertions.
+<p>
+Note also that there is no apparent documentation for what parts of the
+JRE come with useful assertions.
+
+<h3>Nested elements</h3>
+
+<h4>enable</h4>
+<p>
+Enable assertions in portions of code.
+If neither a package nor class is specified, assertions are turned on in <i>all</i> (user) code.
+</p>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">class</td>
+ <td valign="top">The name of a class on which to enable assertions.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">package</td>
+ <td valign="top">
+ The name of a package in which to enable assertions on all classes. (Includes subpackages.)
+ Use "<tt>...</tt>" for the anonymous package.
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+</table>
+
+<h4>disable</h4>
+<p>
+Disable assertions in portions of code.
+
+</p>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">class</td>
+ <td valign="top">The name of a class on which to disable assertions.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">package</td>
+ <td valign="top">
+ The name of a package in which to disable assertions on all classes. (Includes subpackages.)
+ Use "<tt>...</tt>" for the anonymous package.
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+</table>
+<p>
+
+Because assertions are disabled by default, it only makes sense to disable
+assertions where they have been enabled in a parent package.
+
+
+<h4>Examples</h4>
+
+<h5>Example: enable assertions in all user classes</h5>
+
+All classes not in the JRE (i.e. all non-system classes) will have assertions turned on.
+<pre>
+&lt;assertions&gt;
+ &lt;enable/&gt;
+&lt;/assertions&gt;
+</pre>
+
+<h5>Example: enable a single class</h5>
+
+Enable assertions in a class called Test
+<pre>
+&lt;assertions&gt;
+ &lt;enable class="Test"/&gt;
+&lt;/assertions&gt;
+</pre>
+
+<h5>Example: enable a package</h5>
+
+Enable assertions in the <tt>org.apache</tt> package
+and all packages starting with the <tt>org.apache.</tt> prefix
+<pre>
+&lt;assertions&gt;
+ &lt;enable package="org.apache"/&gt;
+&lt;/assertions&gt;
+</pre>
+
+<h5>Example: System assertions</h5>
+
+Example: enable system assertions and assertions in all <tt>org.apache</tt> packages except
+for Ant (but including <tt>org.apache.tools.ant.Main</tt>)
+<pre>
+&lt;assertions enableSystemAssertions="true"&gt;
+ &lt;enable package="org.apache"/&gt;
+ &lt;disable package="org.apache.tools.ant"/&gt;
+ &lt;enable class="org.apache.tools.ant.Main"/&gt;
+&lt;/assertions&gt;
+</pre>
+
+<h5>Example: disabled and anonymous package assertions</h5>
+
+Disable system assertions; enable those in the anonymous package
+<pre>
+&lt;assertions enableSystemAssertions="false"&gt;
+ &lt;enable package="..."/&gt;
+&lt;/assertions&gt;
+</pre>
+
+
+<h5>Example: referenced assertions</h5>
+
+This type is a datatype, so you can declare assertions and use them later
+
+<pre>
+&lt;assertions id="project.assertions"&gt;
+ &lt;enable package="org.apache.test"/&gt;
+&lt;/assertions&gt;
+
+&lt;assertions refid="project.assertions"/&gt;
+</pre>
+
+
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Types/classfileset.html b/framework/src/ant/apache-ant-1.9.6/manual/Types/classfileset.html
new file mode 100644
index 00000000..6145d979
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Types/classfileset.html
@@ -0,0 +1,119 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>ClassFileSet Type</title>
+</head>
+
+<body>
+<h2><a name="fileset">ClassFileSet</a></h2>
+<p>A classfileset is a specialized type of fileset which, given a set of
+&quot;root&quot; classes, will include all of the class files upon which the
+root classes depend. This is typically used to create a jar with all of the
+required classes for a particular application.
+</p>
+<p>
+classfilesets are typically used by reference. They are declared with an
+&quot;id&quot; value and this is then used as a reference where a normal fileset
+is expected.
+</p>
+<p>
+This type requires the <code>BCEL</code> library.
+</p>
+
+
+<h3>Attributes</h3>
+<p>The class fileset support the following attributes in addition
+to those supported by the
+<a href="../Types/fileset.html">standard fileset</a>:
+</p>
+
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">rootclass</td>
+ <td valign="top">A single root class name</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+</table>
+
+<h3>Nested Elements</h3>
+
+<h4>Root</h4>
+<p>
+When more than one root class is required, multiple nested <code>&lt;root&gt;</code> elements
+may be used
+</p>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">classname</td>
+ <td valign="top">The fully qualified name of the root class</td>
+ <td align="center" valign="top">Yes</td>
+ </tr>
+</table>
+
+<h4>RootFileSet</h4>
+<p>
+A root fileset is used to add a set of root classes from a fileset. In this case the entries in
+the fileset are expected to be Java class files. The name of the Java class is determined by the
+relative location of the classfile in the fileset. So, the file
+<code>org/apache/tools/ant/Project.class</code> corresponds to the Java class
+<code>org.apache.tools.ant.Project</code>.</p>
+
+<h4>Examples</h4>
+<blockquote><pre>
+&lt;classfileset id=&quot;reqdClasses" dir=&quot;${classes.dir}&quot;&gt;
+ &lt;root classname=&quot;org.apache.tools.ant.Project&quot;/&gt;
+&lt;/classfileset&gt;
+</pre></blockquote>
+
+<p>This example creates a fileset containing all the class files upon which the
+<code>org.apache.tools.ant.Project</code> class depends. This fileset could
+then be used to create a jar.
+</p>
+
+<blockquote><pre>
+&lt;jar destfile=&quot;minimal.jar&quot;&gt;
+ &lt;fileset refid=&quot;reqdClasses&quot;/&gt;
+&lt;/jar&gt;
+</pre></blockquote>
+
+<blockquote><pre>
+&lt;classfileset id=&quot;reqdClasses&quot; dir=&quot;${classes.dir}&quot;&gt;
+ &lt;rootfileset dir=&quot;${classes.dir}&quot; includes=&quot;org/apache/tools/ant/Project*.class&quot;/&gt;
+&lt;/classfileset&gt;
+</pre></blockquote>
+
+<p>This example constructs the classfileset using all the class with names starting with Project
+in the org.apache.tools.ant package</p>
+
+
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Types/custom-programming.html b/framework/src/ant/apache-ant-1.9.6/manual/Types/custom-programming.html
new file mode 100644
index 00000000..96bade33
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Types/custom-programming.html
@@ -0,0 +1,415 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+ <head>
+ <meta http-equiv="Content-Language" content="en-us"></meta>
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Custom Components</title>
+ </head>
+ <body>
+ <h2>Custom Components</h2>
+ <h3>Overview</h3>
+ <p>
+ Custom components are conditions, selectors, filters and other
+ objects that are defined outside Apache Ant core.
+ </p>
+ <p>
+ In Ant 1.6 custom conditions, selectors and filters has
+ been overhauled.
+ </p>
+ <p>
+ It is now possible to define custom conditions, selectors and filters
+ that behave like Ant Core components.
+ This is achieved by allowing datatypes defined in build scripts
+ to be used as custom components if the class of the datatype
+ is compatible, or has been adapted by an adapter class.
+ </p>
+ <p>
+ The old methods of defining custom components are still supported.
+ </p>
+ <h3>Definition and use</h3>
+ <p>
+ A custom component is a normal Java class that implements a particular
+ interface or extends a particular class, or has been adapted to the
+ interface or class.
+ </p>
+ <p>
+ It is exactly like writing a
+ <a href="../develop.html#writingowntask">custom task</a>.
+ One defines attributes and nested elements by writing <i>setter</i>
+ methods and <i>add</i> methods.
+ </p>
+ <p>
+ After the class has been written, it is added to the ant system
+ by using <code>&lt;typedef&gt;</code>.
+ </p>
+ <h3><a name="customconditions">Custom Conditions</a></h3>
+ <p>
+ Custom conditions are datatypes that implement
+ <code>org.apache.tools.ant.taskdefs.condition.Condition</code>.
+ For example a custom condition that returns true if a
+ string is all upper case could be written as:
+ </p>
+ <blockquote>
+ <pre>
+package com.mydomain;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.taskdefs.condition.Condition;
+
+public class AllUpperCaseCondition implements Condition {
+ private String value;
+
+ // The setter for the "value" attribute
+ public void setValue(String value) {
+ this.value = value;
+ }
+
+ // This method evaluates the condition
+ public boolean eval() {
+ if (value == null) {
+ throw new BuildException("value attribute is not set");
+ }
+ return value.toUpperCase().equals(value);
+ }
+}
+ </pre>
+ </blockquote>
+
+ <p>
+ Adding the condition to the system is achieved as follows:
+ </p>
+ <blockquote>
+ <pre>
+&lt;typedef
+ name="alluppercase"
+ classname="com.mydomain.AllUpperCaseCondition"
+ classpath="${mydomain.classes}"/&gt;
+ </pre>
+ </blockquote>
+ <p>
+ This condition can now be used wherever a Core Ant condition
+ is used.
+ </p>
+ <blockquote>
+ <pre>
+&lt;condition property="allupper"&gt;
+ &lt;alluppercase value="THIS IS ALL UPPER CASE"/&gt;
+&lt;/condition&gt;
+ </pre>
+ </blockquote>
+ <h3><a name="customselectors">Custom Selectors</a></h3>
+ <p>
+ Custom selectors are datatypes that implement
+ <code>org.apache.tools.ant.types.selectors.FileSelector</code>.
+ </p>
+ <p>There is only one method required.
+ <code>public boolean isSelected(File basedir, String filename,
+ File file)</code>.
+ It returns true
+ or false depending on whether the given file should be
+ selected or not.
+ </p>
+ <p>
+ An example of a custom selection that selects filenames ending
+ in ".java" would be:
+ </p>
+ <blockquote>
+ <pre>
+package com.mydomain;
+import java.io.File;
+import org.apache.tools.ant.types.selectors.FileSelector;
+public class JavaSelector implements FileSelector {
+ public boolean isSelected(File b, String filename, File f) {
+ return filename.toLowerCase().endsWith(".java");
+ }
+}
+ </pre>
+ </blockquote>
+ <p>
+ Adding the selector to the system is achieved as follows:
+ </p>
+ <blockquote>
+ <pre>
+&lt;typedef
+ name="javaselector"
+ classname="com.mydomain.JavaSelector"
+ classpath="${mydomain.classes}"/&gt;
+ </pre>
+ </blockquote>
+ <p>
+ This selector can now be used wherever a Core Ant selector
+ is used, for example:
+ </p>
+ <blockquote>
+ <pre>
+&lt;copy todir="to"&gt;
+ &lt;fileset dir="src"&gt;
+ &lt;javaselector/&gt;
+ &lt;/fileset&gt;
+&lt;/copy&gt;
+ </pre>
+ </blockquote>
+
+ <p>
+ One may use
+ <code>org.apache.tools.ant.types.selectors.BaseSelector</code>,
+ a convenience class that provides reasonable default
+ behaviour.
+ It has some predefined behaviours you can take advantage
+ of. Any time you encounter a problem when setting attributes or
+ adding tags, you can call setError(String errmsg) and the class
+ will know that there is a problem. Then, at the top of your
+ <code>isSelected()</code> method call <code>validate()</code> and
+ a BuildException will be thrown with the contents of your error
+ message. The <code>validate()</code> method also gives you a
+ last chance to check your settings for consistency because it
+ calls <code>verifySettings()</code>. Override this method and
+ call <code>setError()</code> within it if you detect any
+ problems in how your selector is set up.
+ </p>
+ <p>
+ To write custom selector containers one should extend
+ <code>org.apache.tools.ant.types.selectors.BaseSelectorContainer</code>.
+ Implement the
+ <code>public boolean isSelected(File baseDir, String filename, File file)</code>
+ method to do the right thing. Chances are you'll want to iterate
+ over the selectors under you, so use
+ <code>selectorElements()</code> to get an iterator that will do
+ that.
+ </p>
+ <p>
+ For example to create a selector container that will select files
+ if a certain number of contained selectors select, one could write
+ a selector as follows:
+ </p>
+ <blockquote>
+ <pre>
+public class MatchNumberSelectors extends BaseSelectorContainer {
+ private int number = -1;
+ public void setNumber(int number) {
+ this.number = number;
+ }
+ public void verifySettings() {
+ if (number &lt; 0) {
+ throw new BuildException("Number attribute should be set");
+ }
+ }
+ public boolean isSelected(File baseDir, String filename, File file) {
+ validate();
+ int numberSelected = 0;
+ for (Enumeration e = selectorElements(); e.hasNextElement();) {
+ FileSelector s = (FileSelector) e.nextElement();
+ if (s.isSelected(baseDir, filename, file)) {
+ numberSelected++;
+ }
+ }
+ return numberSelected == number;
+ }
+}
+ </pre>
+ </blockquote>
+ <p>
+ To define and use this selector one could do:
+ </p>
+ <blockquote>
+ <pre>
+&lt;typedef name="numberselected"
+ classname="com.mydomain.MatchNumberSelectors"/&gt;
+...
+&lt;fileset dir="${src.path}"&gt;
+ &lt;numberselected number="2"&gt;
+ &lt;contains text="script" casesensitive="no"/&gt;
+ &lt;size value="4" units="Ki" when="more"/&gt;
+ &lt;javaselector/&gt;
+ &lt;/numberselected&gt;
+&lt;/fileset&gt;
+ </pre>
+ </blockquote>
+ <p>
+ <i>The custom selector</i>
+ </p>
+ <p>
+ The custom selector was the pre ant 1.6 way of defining custom selectors.
+ This method is still supported for backward compatibility.
+ </p>
+ <p>You can write your own selectors and use them within the selector
+ containers by specifying them within the <code>&lt;custom&gt;</code> tag.</p>
+
+ <p>To create a new Custom Selector, you have to create a class that
+ implements
+ <code>org.apache.tools.ant.types.selectors.ExtendFileSelector</code>.
+ The easiest way to do that is through the convenience base class
+ <code>org.apache.tools.ant.types.selectors.BaseExtendSelector</code>,
+ which provides all of the methods for supporting
+ <code>&lt;param&gt;</code> tags. First, override the
+ <code>isSelected()</code> method, and optionally the
+ <code>verifySettings()</code> method. If your custom
+ selector requires parameters to be set, you can also override
+ the <code>setParameters()</code> method and interpret the
+ parameters that are passed in any way you like. Several of the
+ core selectors demonstrate how to do that because they can
+ also be used as custom selectors.</p>
+
+
+ <p>Once that is written, you include it in your build file by using
+ the <code>&lt;custom&gt;</code> tag.
+ </p>
+
+ <table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">classname</td>
+ <td valign="top">The name of your class that implements
+ <code>org.apache.tools.ant.types.selectors.FileSelector</code>.
+ </td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">classpath</td>
+ <td valign="top">The classpath to use in order to load the
+ custom selector class. If neither this classpath nor the
+ classpathref are specified, the class will be
+ loaded from the classpath that Ant uses.
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">classpathref</td>
+ <td valign="top">A reference to a classpath previously
+ defined. If neither this reference nor the
+ classpath above are specified, the class will be
+ loaded from the classpath that Ant uses.
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ </table>
+
+ <p>Here is how you use <code>&lt;custom&gt;</code> to
+ use your class as a selector:
+ </p>
+
+ <blockquote><pre>
+&lt;fileset dir="${mydir}" includes="**/*"&gt;
+ &lt;custom classname="com.mydomain.MySelector"&gt;
+ &lt;param name="myattribute" value="myvalue"/&gt;
+ &lt;/custom&gt;
+&lt;/fileset&gt;
+ </pre></blockquote>
+
+
+ <p>The core selectors that can also be used as custom selectors
+ are</p>
+
+ <ul>
+ <li><a href="selectors.html#containsselect">Contains Selector</a> with
+ classname <code>org.apache.tools.ant.types.selectors.ContainsSelector</code>
+ </li>
+ <li><a href="selectors.html#dateselect">Date Selector</a> with
+ classname <code>org.apache.tools.ant.types.selectors.DateSelector</code>
+ </li>
+ <li><a href="selectors.html#depthselect">Depth Selector</a> with
+ classname <code>org.apache.tools.ant.types.selectors.DepthSelector</code>
+ </li>
+ <li><a href="selectors.html#filenameselect">Filename Selector</a> with
+ classname <code>org.apache.tools.ant.types.selectors.FilenameSelector</code>
+ </li>
+ <li><a href="selectors.html#sizeselect">Size Selector</a> with
+ classname <code>org.apache.tools.ant.types.selectors.SizeSelector</code>
+ </li>
+ </ul>
+
+ <p>Here is the example from the Depth Selector section rewritten
+ to use the selector through <code>&lt;custom&gt;</code>.</p>
+
+ <blockquote><pre>
+&lt;fileset dir="${doc.path}" includes="**/*"&gt;
+ &lt;custom classname="org.apache.tools.ant.types.selectors.DepthSelector"&gt;
+ &lt;param name="max" value="1"/&gt;
+ &lt;/custom&gt;
+&lt;/fileset&gt;
+ </pre></blockquote>
+
+ <p>Selects all files in the base directory and one directory below
+ that.</p>
+
+ <h3><a name="filterreaders">Custom Filter Readers</a></h3>
+ <p>
+ Custom filter readers selectors are datatypes that implement
+ <code>org.apache.tools.ant.types.filters.ChainableReader</code>.
+ </p>
+ <p>There is only one method required.
+ <code>Reader chain(Reader reader)</code>.
+ This returns a reader that filters input from the specified
+ reader.
+ </p>
+ <p>
+ For example a filterreader that removes every second character
+ could be:
+ </p>
+ <blockquote>
+ <pre>
+public class RemoveOddCharacters implements ChainableReader {
+ public Reader chain(Reader reader) {
+ return new BaseFilterReader(reader) {
+ int count = 0;
+ public int read() throws IOException {
+ while (true) {
+ int c = in.read();
+ if (c == -1) {
+ return c;
+ }
+ count++;
+ if ((count % 2) == 1) {
+ return c;
+ }
+ }
+ }
+ }
+ }
+}
+ </pre>
+ </blockquote>
+ <p>
+ For line oriented filters it may be easier to extend
+ <code>ChainableFilterReader</code> an inner class of
+ <code>org.apache.tools.ant.filters.TokenFilter</code>.
+ </p>
+ <p>
+ For example a filter that appends the line number could be
+ </p>
+ <blockquote>
+ <pre>
+public class AddLineNumber extends ChainableReaderFilter {
+ private void lineNumber = 0;
+ public String filter(String string) {
+ lineNumber++;
+ return "" + lineNumber + "\t" + string;
+ }
+}
+ </pre>
+ </blockquote>
+
+
+ <hr></hr>
+ </body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Types/description.html b/framework/src/ant/apache-ant-1.9.6/manual/Types/description.html
new file mode 100644
index 00000000..85942be0
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Types/description.html
@@ -0,0 +1,46 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Apache Ant User Manual</title>
+</head>
+
+<body>
+
+<h2><a name="description">Description</a></h2>
+<h3>Description</h3>
+<p>Allows for a description of the project to be specified that
+will be included in the output of the <code>ant &#x2011;projecthelp</code>
+command.</p>
+
+<h3>Parameters</h3>
+<p>(none)</p>
+<h3>Examples</h3>
+<pre>
+&lt;description&gt;
+This buildfile is used to build the Foo subproject within
+the large, complex Bar project.
+&lt;/description&gt;
+</pre>
+
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Types/dirset.html b/framework/src/ant/apache-ant-1.9.6/manual/Types/dirset.html
new file mode 100644
index 00000000..0434e9c2
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Types/dirset.html
@@ -0,0 +1,154 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>DirSet Type</title>
+</head>
+
+<body>
+
+<h2><a name="dirset">DirSet</a></h2>
+<p>A DirSet is a group of directories. These directories can be found in a
+directory tree starting in a base directory and are matched by
+patterns taken from a number of <a href="patternset.html">PatternSets</a>
+and <a href="selectors.html">Selectors</a>.
+</p>
+<p>PatternSets can be specified as nested
+<code>&lt;patternset&gt;</code> elements. In addition, DirSet holds
+an implicit PatternSet and supports the nested
+<code>&lt;include&gt;</code>, <code>&lt;includesfile&gt;</code>,
+<code>&lt;exclude&gt;</code> and <code>&lt;excludesfile&gt;</code>
+elements of <code>&lt;patternset&gt;</code> directly, as well as
+<code>&lt;patternset&gt;</code>'s attributes.</p>
+<p>Selectors are available as nested elements within the DirSet.
+If any of the selectors within the DirSet do not select the directory, it
+is not considered part of the DirSet. This makes a DirSet
+equivalent to an <code>&lt;and&gt;</code> selector container.</p>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">dir</td>
+ <td valign="top">The root of the directory tree of this DirSet.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">includes</td>
+ <td valign="top">A comma- or space-separated list of patterns of directories that
+ must be included; all directories are included when omitted.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">includesfile</td>
+ <td valign="top">The name of a file; each line of this file is
+ taken to be an include pattern.
+ <b>Note:</b> if the file is empty and there are no other
+ patterns defined for the fileset, all directories will be included.
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">excludes</td>
+ <td valign="top">A comma- or space-separated list of patterns of directories that
+ must be excluded; no directories are excluded when omitted.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">excludesfile</td>
+ <td valign="top">The name of a file; each line of this file is
+ taken to be an exclude pattern.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">casesensitive</td>
+ <td valign="top">Specifies whether case-sensitivity should be applied
+ (<code>true</code>|<code>yes</code>|<code>on</code> or
+ <code>false</code>|<code>no</code>|<code>off</code>).</td>
+ <td valign="top" align="center">No; defaults to true.</td>
+ </tr>
+ <tr>
+ <td valign="top">followsymlinks</td>
+ <td valign="top">Shall symbolic links be followed? Defaults to
+ true. See <a href="fileset.html#symlink">fileset's documentation</a>.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">erroronmissingdir</td>
+ <td valign="top">
+ Specify what happens if the base directory does not exist.
+ If true a build error will happen, if false, the dirset
+ will be ignored/empty.
+ Defaults to true.
+ <em>Since Apache Ant 1.7.1 (default is true for backward compatibility
+ reasons.)</em>
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+</table>
+
+<h4>Examples</h4>
+
+<blockquote><pre>
+&lt;dirset dir=&quot;${build.dir}&quot;&gt;
+ &lt;include name=&quot;apps/**/classes&quot;/&gt;
+ &lt;exclude name=&quot;apps/**/*Test*&quot;/&gt;
+&lt;/dirset&gt;
+</pre></blockquote>
+<p>Groups all directories named <code>classes</code> found under the
+<code>apps</code> subdirectory of <code>${build.dir}</code>, except those
+that have the text <code>Test</code> in their name.</p>
+
+<blockquote><pre>
+&lt;dirset dir=&quot;${build.dir}&quot;&gt;
+ &lt;patternset id=&quot;non.test.classes&quot;&gt;
+ &lt;include name=&quot;apps/**/classes&quot;/&gt;
+ &lt;exclude name=&quot;apps/**/*Test*&quot;/&gt;
+ &lt;/patternset&gt;
+&lt;/dirset&gt;
+</pre></blockquote>
+<p>Groups the same directories as the above example, but also establishes
+a PatternSet that can be referenced in other
+<code>&lt;dirset&gt;</code> elements, rooted at a different directory.</p>
+
+<blockquote><pre>
+&lt;dirset dir=&quot;${debug_build.dir}&quot;&gt;
+ &lt;patternset refid=&quot;non.test.classes&quot;/&gt;
+&lt;/dirset&gt;
+</pre></blockquote>
+<p>Groups all directories in directory <code>${debug_build.dir}</code>,
+using the same patterns as the above example.</p>
+
+<blockquote><pre>
+&lt;dirset id=&quot;dirset&quot; dir=&quot;${workingdir}&quot;&gt;
+ &lt;present targetdir=&quot;${workingdir}&quot;&gt;
+ &lt;mapper type=&quot;glob&quot; from=&quot;*&quot; to=&quot;*/${markerfile}&quot; /&gt;
+ &lt;/present&gt;
+&lt;/dirset&gt;
+</pre></blockquote>
+<p>Selects all directories somewhere under <code>${workingdir}</code>
+which contain a <code>${markerfile}</code>.</p>
+
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Types/extension.html b/framework/src/ant/apache-ant-1.9.6/manual/Types/extension.html
new file mode 100644
index 00000000..b05c0a65
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Types/extension.html
@@ -0,0 +1,114 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Extension Type</title>
+</head>
+
+<body>
+<h2><a name="fileset">Extension</a></h2>
+<p>Utility type that represents either an available "Optional Package"
+ (formerly known as "Standard Extension") as described in the manifest
+ of a JAR file, or the requirement for such an optional package.</p>
+<p>Note that this type
+works with extensions as defined by the "Optional Package" specification.
+ For more information about optional packages, see the document
+<em>Optional Package Versioning</em> in the documentation bundle for your
+Java2 Standard Edition package, in file
+<code>guide/extensions/versioning.html</code> or the online
+<a href="http://docs.oracle.com/javase/7/docs/technotes/guides/versioning/spec/versioning2.html#wp90779">
+Package Versioning documentation.</p>
+
+<h3>Attributes</h3>
+<p>The extension type supports the following attributes</a>:
+</p>
+
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">extensionName</td>
+ <td valign="top">The name of extension</td>
+ <td valign="top" align="center">yes</td>
+ </tr>
+ <tr>
+ <td valign="top">specificationVersion</td>
+ <td valign="top">The version of extension specification (Must be in
+ dewey decimal aka dotted decimal notation. 3.2.4)</td>
+ <td valign="top" align="center">no</td>
+ </tr>
+ <tr>
+ <td valign="top">specificationVendor</td>
+ <td valign="top">The specification vendor</td>
+ <td valign="top" align="center">no</td>
+ </tr>
+ <tr>
+ <td valign="top">implementationVersion</td>
+ <td valign="top">The version of extension implementation (Must be in
+ dewey decimal aka dotted decimal notation. 3.2.4)</td>
+ <td valign="top" align="center">no</td>
+ </tr>
+ <tr>
+ <td valign="top">implementationVendor</td>
+ <td valign="top">The implementation vendor</td>
+ <td valign="top" align="center">no</td>
+ </tr>
+ <tr>
+ <td valign="top">implementationVendorId</td>
+ <td valign="top">The implementation vendor ID</td>
+ <td valign="top" align="center">no</td>
+ </tr>
+ <tr>
+ <td valign="top">implementationURL</td>
+ <td valign="top">The url from which to retrieve extension.</td>
+ <td valign="top" align="center">no</td>
+ </tr>
+</table>
+
+<h4>Examples</h4>
+<blockquote><pre>
+&lt;extension id=&quot;e1&quot;
+ extensionName=&quot;MyExtensions&quot;
+ specificationVersion=&quot;1.0&quot;
+ specificationVendor=&quot;Peter Donald&quot;
+ implementationVendorID=&quot;vv&quot;
+ implementationVendor=&quot;Apache&quot;
+ implementationVersion=&quot;2.0&quot;
+ implementationURL=&quot;http://somewhere.com/myExt.jar&quot;/&gt;
+</pre></blockquote>
+
+<p>Fully specific extension object.</p>
+
+<blockquote><pre>
+&lt;extension id=&quot;e1&quot;
+ extensionName=&quot;MyExtensions&quot;
+ specificationVersion=&quot;1.0&quot;
+ specificationVendor=&quot;Peter Donald&quot;/&gt;
+</pre></blockquote>
+
+<p>Extension object that just species the specification details.</p>
+
+
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Types/extensionset.html b/framework/src/ant/apache-ant-1.9.6/manual/Types/extensionset.html
new file mode 100644
index 00000000..f38c1ed1
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Types/extensionset.html
@@ -0,0 +1,83 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>ExtensionSet Type</title>
+</head>
+
+<body>
+<h2><a>ExtensionSet</a></h2>
+<p>Utility type that represents a set of Extensions.</p>
+<p>Note that this type
+works with extensions as defined by the "Optional Package" specification.
+ For more information about optional packages, see the document
+<em>Optional Package Versioning</em> in the documentation bundle for your
+Java2 Standard Edition package, in file
+<code>guide/extensions/versioning.html</code> or online at
+<a href="http://docs.oracle.com/javase/7/docs/technotes/guides/versioning/spec/versioning2.html#wp90779">
+Package Versioning documentation.</p>
+
+<h3>Nested Elements</h3>
+
+<h4>extension</h4>
+<p><a href="extension.html">Extension</a> object to add to set.</p>
+
+<h4>fileset</h4>
+ <p><a href="../Types/fileset.html">FileSet</a>s all files contained
+ contained within set that are jars and implement an extension are added
+ to extension set.</p>
+
+<h4>LibFileSet</h4>
+ <p>All files contained contained within set that are jars and implement
+ an extension are added to extension set. However the extension information
+ may be modified by attributes of libfileset</p>
+
+<h4>Examples</h4>
+<blockquote><pre>
+&lt;extension id=&quot;e1&quot;
+ extensionName=&quot;MyExtensions&quot;
+ specificationVersion=&quot;1.0&quot;
+ specificationVendor=&quot;Peter Donald&quot;
+ implementationVendorID=&quot;vv&quot;
+ implementationVendor=&quot;Apache&quot;
+ implementationVersion=&quot;2.0&quot;
+ implementationURL=&quot;http://somewhere.com/myExt.jar&quot;/&gt;
+
+&lt;libfileset id="lfs"
+ includeUrl="true"
+ includeImpl="false"
+ dir="tools/lib"&gt;
+ &lt;include name="*.jar"/&gt;
+&lt;/libfileset&gt;
+
+&lt;extensionSet id="exts"&gt;
+ &lt;libfileset dir="lib"&gt;
+ &lt;include name="*.jar"/&gt;
+ &lt;/libfileset&gt;
+ &lt;libfileset refid="lfs"/&gt;
+ &lt;extension refid="e1"/&gt;
+&lt;/extensionSet&gt;
+
+</pre></blockquote>
+
+
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Types/filelist.html b/framework/src/ant/apache-ant-1.9.6/manual/Types/filelist.html
new file mode 100644
index 00000000..57c981d3
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Types/filelist.html
@@ -0,0 +1,120 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>FileList Type</title>
+</head>
+
+<body>
+
+<h2><a name="filelist">FileList</a></h2>
+
+<p>FileLists are explicitly named lists of files. Whereas FileSets
+act as filters, returning only those files that exist in the file
+system and match specified patterns, FileLists are useful for
+specifying files that may or may not exist. Multiple files are
+specified as a list of files, relative to the specified directory,
+with no support for wildcard expansion (filenames with wildcards will be
+included in the list unchanged).
+FileLists can appear inside tasks that support this feature or as stand-alone
+types.
+</p>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">dir</td>
+ <td valign="top">The base directory of this FileList.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">files</td>
+ <td valign="top">The list of file names. This is a list of
+ file name separated by whitespace, or by commas.</td>
+ <td valign="top" align="center">
+ Yes, unless there is a nested file element</td>
+ </tr>
+</table>
+ <h4>Nested Element: file</h4>
+ <p>
+ This represents a file name. The nested element allows filenames containing
+ white space and commas.
+ </p>
+ <p><em>Since Apache Ant 1.6.2</em></p>
+ <table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">name</td>
+ <td valign="top">The name of the file.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+</table>
+<h4>Examples</h4>
+<blockquote><pre>
+&lt;filelist
+ id=&quot;docfiles&quot;
+ dir=&quot;${doc.src}&quot;
+ files=&quot;foo.xml,bar.xml&quot;/&gt;
+</pre></blockquote>
+
+<p>The files <code>${doc.src}/foo.xml</code> and
+<code>${doc.src}/bar.xml</code>. Note that these files may not (yet)
+actually exist.
+</p>
+
+<blockquote><pre>
+&lt;filelist
+ id=&quot;docfiles&quot;
+ dir=&quot;${doc.src}&quot;
+ files=&quot;foo.xml
+ bar.xml&quot;/&gt;
+</pre></blockquote>
+
+<p>Same files as the example above.</p>
+
+<blockquote><pre>
+&lt;filelist refid=&quot;docfiles&quot;/&gt;
+</pre></blockquote>
+
+<p>Same files as the example above.</p>
+
+<blockquote><pre>
+&lt;filelist
+ id=&quot;docfiles&quot;
+ dir=&quot;${doc.src}&quot;&gt;
+ &lt;file name="foo.xml"/&gt;
+ &lt;file name="bar.xml"/&gt;
+&lt;/filelist&gt;
+</pre></blockquote>
+
+<p>Same files as the example above.</p>
+
+
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Types/fileset.html b/framework/src/ant/apache-ant-1.9.6/manual/Types/fileset.html
new file mode 100644
index 00000000..9a7c7d71
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Types/fileset.html
@@ -0,0 +1,186 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>FileSet Type</title>
+</head>
+
+<body>
+
+<h2><a name="fileset">FileSet</a></h2>
+<p>A FileSet is a group of files. These files can be found in a
+directory tree starting in a base directory and are matched by
+patterns taken from a number of <a
+href="patternset.html">PatternSets</a> and
+<a href="selectors.html">Selectors</a>.
+<p>PatternSets can be specified as nested
+<code>&lt;patternset&gt;</code> elements. In addition, FileSet holds
+an implicit PatternSet and supports the nested
+<code>&lt;include&gt;</code>, <code>&lt;includesfile&gt;</code>,
+<code>&lt;exclude&gt;</code> and <code>&lt;excludesfile&gt;</code>
+elements of PatternSet directly, as well as PatternSet's
+attributes.</p>
+<p>Selectors are available as nested elements within the FileSet.
+If any of the selectors within the FileSet do not select the file, the
+file is not considered part of the FileSet. This makes a FileSet
+equivalent to an <code>&lt;and&gt;</code> selector container.</p>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">dir</td>
+ <td valign="top">the root of the directory tree of this FileSet.</td>
+ <td valign="middle" align="center" rowspan="2">Either dir or file must be specified</td>
+ </tr>
+ <tr>
+ <td valign="top">file</td>
+ <td valign="top">shortcut for specifying a single-file fileset</td>
+ </tr>
+ <tr>
+ <td valign="top">defaultexcludes</td>
+ <td valign="top">indicates whether <a href="../dirtasks.html#defaultexcludes">default excludes</a> should be used or not
+ (<code>yes | no</code>); default excludes are used when omitted.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">includes</td>
+ <td valign="top">comma- or space-separated list of patterns of files that must be
+ included; all files are included when omitted.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">includesfile</td>
+ <td valign="top">the name of a file; each line of this file is
+ taken to be an include pattern.<br/>
+ <b>Note:</b> if the file is empty and there are no other
+ patterns defined for the fileset, all files will be included.
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">excludes</td>
+ <td valign="top">comma- or space-separated list of patterns of files that must be
+ excluded; no files (except default excludes) are excluded when omitted.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">excludesfile</td>
+ <td valign="top">the name of a file; each line of this file is
+ taken to be an exclude pattern.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">casesensitive</td>
+ <td valign="top">Must the include and exclude patterns be treated in a case sensitive way?
+ Defaults to true.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">followsymlinks</td>
+ <td valign="top">Shall symbolic links be followed? Defaults to
+ true. See the note <a href="#symlink">below</a>.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">erroronmissingdir</td>
+ <td valign="top">
+ Specify what happens if the base directory does not exist.
+ If true a build error will happen, if false, the fileset
+ will be ignored/empty.
+ Defaults to true.
+ <em>Since Apache Ant 1.7.1 (default is true for backward compatibility
+ reasons.)</em>
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+</table>
+
+<p><a name="symlink"><b>Note</b></a>: All files/directories for which
+the canonical path is different from its path are considered symbolic
+links. On Unix systems this usually means the file really is a
+symbolic link but it may lead to false results on other
+platforms.</p>
+
+<h4>Examples</h4>
+<blockquote><pre>
+&lt;fileset dir=&quot;${server.src}&quot; casesensitive=&quot;yes&quot;&gt;
+ &lt;include name=&quot;**/*.java&quot;/&gt;
+ &lt;exclude name=&quot;**/*Test*&quot;/&gt;
+&lt;/fileset&gt;
+</pre></blockquote>
+<p>Groups all files in directory <code>${server.src}</code> that are Java
+source files and don't have the text <code>Test</code> in their
+name.</p>
+
+<blockquote><pre>
+&lt;fileset dir=&quot;${server.src}&quot; casesensitive=&quot;yes&quot;&gt;
+ &lt;patternset id=&quot;non.test.sources&quot;&gt;
+ &lt;include name=&quot;**/*.java&quot;/&gt;
+ &lt;exclude name=&quot;**/*Test*&quot;/&gt;
+ &lt;/patternset&gt;
+&lt;/fileset&gt;
+</pre></blockquote>
+<p>Groups the same files as the above example, but also establishes
+a PatternSet that can be referenced in other
+<code>&lt;fileset&gt;</code> elements, rooted at a different directory.</p>
+
+<blockquote><pre>
+&lt;fileset dir=&quot;${client.src}&quot; &gt;
+ &lt;patternset refid=&quot;non.test.sources&quot;/&gt;
+&lt;/fileset&gt;
+</pre></blockquote>
+<p>Groups all files in directory <code>${client.src}</code>, using the
+same patterns as the above example.</p>
+
+<blockquote><pre>
+&lt;fileset dir=&quot;${server.src}&quot; casesensitive=&quot;yes&quot;&gt;
+ &lt;filename name=&quot;**/*.java&quot;/&gt;
+ &lt;filename name=&quot;**/*Test*&quot; negate=&quot;true&quot;/&gt;
+&lt;/fileset&gt;
+</pre></blockquote>
+<p>Groups the same files as the top example, but using the
+<code>&lt;filename&gt;</code> selector.</p>
+
+<blockquote><pre>
+&lt;fileset dir=&quot;${server.src}&quot; casesensitive=&quot;yes&quot;&gt;
+ &lt;filename name=&quot;**/*.java&quot;/&gt;
+ &lt;not&gt;
+ &lt;filename name=&quot;**/*Test*&quot;/&gt;
+ &lt;/not&gt;
+&lt;/fileset&gt;
+</pre></blockquote>
+<p>Groups the same files as the previous example using a combination of the
+<code>&lt;filename&gt;</code> selector and the <code>&lt;not&gt;</code>
+selector container.</p>
+
+<blockquote><pre>
+&lt;fileset dir="src" includes="main/" /&gt;
+</pre></blockquote>
+<p>Selects all files in <i>src/main</i> (e.g. <i>src/main/Foo.java</i> or
+<i>src/main/application/Bar.java</i>).</p>
+
+
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Types/filterchain.html b/framework/src/ant/apache-ant-1.9.6/manual/Types/filterchain.html
new file mode 100644
index 00000000..4de10ea3
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Types/filterchain.html
@@ -0,0 +1,1739 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+
+<html>
+<head>
+ <link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>FilterChains and FilterReaders</title>
+</head>
+
+<body>
+
+<h2>FilterChains and FilterReaders</h2>
+Consider the flexibility of Unix pipes. If you wanted,
+for example, to copy just those lines that contained the
+string blee from the first 10 lines of a text file 'foo'
+(<em>you wouldn't want to filter a binary file</em>)
+to a file 'bar', you would do something like:<p>
+<code>
+cat foo|head -n10|grep blee &gt; bar
+</code><p>
+Apache Ant was not flexible enough. There was no way for the
+<code>&lt;copy&gt;</code> task to do something similar. If you wanted
+the <code>&lt;copy&gt;</code> task to get the first 10 lines, you would have
+had to create special attributes:<p>
+<code>
+&lt;copy file=&quot;foo&quot; tofile=&quot;bar&quot; head=&quot;10&quot; contains=&quot;blee&quot;/&gt;
+</code><p>
+The obvious problem thus surfaced: Ant tasks would not be able
+to accommodate such data transformation attributes as they would
+be endless. The task would also not know in which order these
+attributes were to be interpreted. That is, must the task execute the
+contains attribute first and then the head attribute or vice-versa?
+What Ant tasks needed was a mechanism to allow pluggable filter (data
+transformer) chains. Ant would provide a few filters for which there
+have been repeated requests. Users with special filtering needs
+would be able to easily write their own and plug them in.<p>
+
+The solution was to refactor data transformation oriented
+tasks to support FilterChains. A FilterChain is a group of
+ordered FilterReaders. Users can define their own FilterReaders
+by just extending the java.io.FilterReader class. Such custom
+FilterReaders can be easily plugged in as nested elements of
+<code>&lt;filterchain&gt;</code> by using <code>&lt;filterreader&gt;</code> elements.
+<p>
+Example:
+<blockquote><pre>
+&lt;copy file=&quot;${src.file}&quot; tofile=&quot;${dest.file}&quot;&gt;
+ &lt;filterchain&gt;
+ &lt;filterreader classname=&quot;your.extension.of.java.io.FilterReader&quot;&gt;
+ &lt;param name=&quot;foo&quot; value=&quot;bar&quot;/&gt;
+ &lt;/filterreader&gt;
+ &lt;filterreader classname=&quot;another.extension.of.java.io.FilterReader&quot;&gt;
+ &lt;classpath&gt;
+ &lt;pathelement path="${classpath}"/&gt;
+ &lt;/classpath&gt;
+ &lt;param name=&quot;blah&quot; value=&quot;blee&quot;/&gt;
+ &lt;param type=&quot;abra&quot; value=&quot;cadabra&quot;/&gt;
+ &lt;/filterreader&gt;
+ &lt;/filterchain&gt;
+&lt;/copy&gt;
+</pre></blockquote>
+
+Ant provides some built-in filter readers. These filter readers
+can also be declared using a syntax similar to the above syntax.
+However, they can be declared using some simpler syntax also.<p>
+Example:
+<blockquote><pre>
+&lt;loadfile srcfile=&quot;${src.file}&quot; property=&quot;src.file.head&quot;&gt;
+ &lt;filterchain&gt;
+ &lt;headfilter lines=&quot;15&quot;/&gt;
+ &lt;/filterchain&gt;
+&lt;/loadfile&gt;
+</pre></blockquote>
+is equivalent to:
+<blockquote><pre>
+&lt;loadfile srcfile=&quot;${src.file}&quot; property=&quot;src.file.head&quot;&gt;
+ &lt;filterchain&gt;
+ &lt;filterreader classname=&quot;org.apache.tools.ant.filters.HeadFilter&quot;&gt;
+ &lt;param name=&quot;lines&quot; value=&quot;15&quot;/&gt;
+ &lt;/filterreader&gt;
+ &lt;/filterchain&gt;
+&lt;/loadfile&gt;
+</pre></blockquote>
+
+The following built-in tasks support nested <code>&lt;filterchain&gt;</code> elements.<br>
+<a href="../Tasks/concat.html">Concat</a>,<br>
+<a href="../Tasks/copy.html">Copy</a>,<br>
+<a href="../Tasks/loadfile.html">LoadFile</a>,<br>
+<a href="../Tasks/loadproperties.html">LoadProperties</a>,<br>
+<a href="../Tasks/loadresource.html">LoadResource</a>,<br>
+<a href="../Tasks/move.html">Move</a><br><br>
+
+A FilterChain is formed by defining zero or more of the following
+nested elements.<br>
+<a href="#filterreader">FilterReader</a><br>
+<a href="#classconstants">ClassConstants</a><br>
+<a href="#escapeunicode">EscapeUnicode</a><br>
+<a href="#expandproperties">ExpandProperties</a><br>
+<a href="#headfilter">HeadFilter</a><br>
+<a href="#linecontains">LineContains</a><br>
+<a href="#linecontainsregexp">LineContainsRegExp</a><br>
+<a href="#prefixlines">PrefixLines</a><br>
+<a href="#replacetokens">ReplaceTokens</a><br>
+<a href="#stripjavacomments">StripJavaComments</a><br>
+<a href="#striplinebreaks">StripLineBreaks</a><br>
+<a href="#striplinecomments">StripLineComments</a><br>
+<a href="#suffixlines">SuffixLines</a><br>
+<a href="#tabstospaces">TabsToSpaces</a><br>
+<a href="#tailfilter">TailFilter</a><br>
+<a href="#deletecharacters">DeleteCharacters</a><br>
+<a href="#concatfilter">ConcatFilter</a><br>
+<a href="#tokenfilter">TokenFilter</a><br>
+<a href="../Tasks/fixcrlf.html">FixCRLF</a><br>
+<a href="#sortfilter">SortFilter</a><br>
+
+<h3><a name="filterreader">FilterReader</a></h3>
+
+The filterreader element is the generic way to
+define a filter. User defined filter elements are
+defined in the build file using this. Please note that
+built in filter readers can also be defined using this
+syntax.
+
+A FilterReader element must be supplied with a class name as
+an attribute value. The class resolved by this name must
+extend java.io.FilterReader. If the custom filter reader
+needs to be parameterized, it must implement
+org.apache.tools.type.Parameterizable.
+
+<table cellSpacing=0 cellPadding=2 border=1>
+ <tr>
+ <td vAlign=top><b>Attribute</b></td>
+ <td vAlign=top><b>Description</b></td>
+ <td vAlign=top align="center"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td vAlign=top>classname</td>
+ <td vAlign=top>The class name of the filter reader.</td>
+ <td vAlign=top align="center">Yes</td>
+ </tr>
+</table>
+
+<p>
+<h4>Nested Elements:</h4>
+<code>&lt;filterreader&gt;</code> supports <code>&lt;classpath&gt;</code> and <code>&lt;param&gt;</code>
+as nested elements. Each <code>&lt;param&gt;</code> element may take in the following
+attributes - name, type and value.
+<p>
+The following FilterReaders are supplied with the default
+distribution.
+
+<h3><a name="classconstants">ClassConstants</a></h3>
+<p>
+ This filters basic constants defined in a Java Class,
+ and outputs them in lines composed of the format <i>name</i>=<i>value</i>.
+ This filter uses the <em>bcel</em> library to understand the Java Class file.
+ See <a href="../install.html#librarydependencies">Library Dependencies</a>.
+<p>
+ <p>
+ <em><b>Important:</b></em>
+ This filter is different from most of the other filters.
+ Most of the filters operate on a sequence of characters.
+ This filter operates on the sequence of bytes that makes up
+ a class. However the bytes arrive to the filter as a sequence
+ of characters. This means that one must be careful on the
+ choice of character encoding to use. Most encoding lose information
+ on conversion from an arbitrary sequence of bytes to characters
+ and back again to bytes. In particular the usual default
+ character encodings (CP152 and UTF-8) do.
+ For this reason, <em>since Ant 1.7</em>, the character
+ encoding <b>ISO-8859-1</b> is used to convert from characters back to
+ bytes, so one <b>has</b> to use this encoding for reading the java
+ class file.
+<h4>Example:</h4>
+
+This loads the basic constants defined in a Java class as Ant properties.
+
+<blockquote><pre>
+&lt;loadproperties srcfile="foo.class" encoding="ISO-8859-1"&gt;
+ &lt;filterchain&gt;
+ &lt;classconstants/&gt;
+ &lt;/filterchain&gt;
+&lt;/loadproperties&gt;
+</pre></blockquote>
+
+This loads the constants from a Java class file as Ant properties,
+prepending the names with a prefix.
+
+ <blockquote><pre>
+&lt;loadproperties srcfile="build/classes/org/acme/bar.class"
+ encoding="ISO-8859-1"&gt;
+ &lt;filterchain&gt;
+ &lt;classconstants/&gt;
+ &lt;prefixlines prefix="ini."/&gt;
+ &lt;/filterchain&gt;
+&lt;/loadproperties&gt;
+</pre></blockquote>
+<h3><a name="escapeunicode">EscapeUnicode</a></h3>
+<p>
+This filter converts its input by changing all non US-ASCII characters
+into their equivalent unicode escape backslash u plus 4 digits.</p>
+
+<p><em>since Ant 1.6</em></p>
+
+<h4>Example:</h4>
+
+This loads the basic constants defined in a Java class as Ant properties.
+<blockquote><pre>
+&lt;loadproperties srcfile=&quot;non_ascii_property.properties&quot;&gt;
+ &lt;filterchain&gt;
+ &lt;filterreader classname=&quot;org.apache.tools.ant.filters.EscapeUnicode&quot;/&gt;
+ &lt;/filterchain&gt;
+&lt;/loadproperties&gt;
+</pre></blockquote>
+
+Convenience method:
+<blockquote><pre>
+&lt;loadproperties srcfile=&quot;non_ascii_property.properties&quot;&gt;
+ &lt;filterchain&gt;
+ &lt;escapeunicode/&gt;
+ &lt;/filterchain&gt;
+&lt;/loadproperties&gt;
+</pre></blockquote>
+
+<h3><a name="expandproperties">ExpandProperties</a></h3>
+<p>
+If the data contains data that represents Ant
+properties (of the form ${...}), that is substituted
+with the property's actual value.
+<p>
+<h4>Example:</h4>
+
+This results in the property modifiedmessage holding the value
+&quot;All these moments will be lost in time, like teardrops in the rain&quot;
+<blockquote><pre>
+&lt;echo
+ message=&quot;All these moments will be lost in time, like teardrops in the ${weather}&quot;
+ file=&quot;loadfile1.tmp&quot;
+ /&gt;
+&lt;property name=&quot;weather&quot; value=&quot;rain&quot;/&gt;
+&lt;loadfile property=&quot;modifiedmessage&quot; srcFile=&quot;loadfile1.tmp&quot;&gt;
+ &lt;filterchain&gt;
+ &lt;filterreader classname=&quot;org.apache.tools.ant.filters.ExpandProperties&quot;/&gt;
+ &lt;/filterchain&gt;
+&lt;/loadfile&gt;
+</pre></blockquote>
+
+Convenience method:
+<blockquote><pre>
+&lt;echo
+ message=&quot;All these moments will be lost in time, like teardrops in the ${weather}&quot;
+ file=&quot;loadfile1.tmp&quot;
+ /&gt;
+&lt;property name=&quot;weather&quot; value=&quot;rain&quot;/&gt;
+&lt;loadfile property=&quot;modifiedmessage&quot; srcFile=&quot;loadfile1.tmp&quot;&gt;
+ &lt;filterchain&gt;
+ &lt;expandproperties/&gt;
+ &lt;/filterchain&gt;
+&lt;/loadfile&gt;
+</pre></blockquote>
+
+<p>As of Ant <strong>1.8.3</strong>, a nested
+ <a href="propertyset.html">PropertySet</a> can be specified:
+
+<blockquote><pre>
+&lt;property name=&quot;weather&quot; value=&quot;rain&quot;/&gt;
+&lt;loadfile property=&quot;modifiedmessage&quot; srcFile=&quot;loadfile1.tmp&quot;&gt;
+ &lt;filterchain&gt;
+ &lt;expandproperties&gt;
+ &lt;propertyset&gt;
+ &lt;propertyref name="weather" /&gt;
+ &lt;/propertyset&gt;
+ &lt;/expandproperties&gt;
+ &lt;/filterchain&gt;
+&lt;/loadfile&gt;
+</pre></blockquote>
+
+<h3><a name="headfilter">HeadFilter</a></h3>
+
+This filter reads the first few lines from the data supplied to it.
+
+<table cellSpacing=0 cellPadding=2 border=1>
+ <tr>
+ <td vAlign=top><b>Parameter Name</b></td>
+ <td vAlign=top><b>Parameter Value</b></td>
+ <td vAlign=top align="center"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td vAlign=top>lines</td>
+ <td vAlign=top align="center">Number of lines to be read.
+ Defaults to &quot;10&quot; <br> A negative value means that all lines are
+ passed (useful with <i>skip</i>)</td>
+ <td vAlign=top align="center">No</td>
+ </tr>
+ <tr>
+ <td vAlign=top>skip</td>
+ <td vAlign=top align="center">Number of lines to be skipped (from the beginning).
+ Defaults to &quot;0&quot;</td>
+ <td vAlign=top align="center">No</td>
+ </tr>
+</table>
+<p>
+<h4>Example:</h4>
+
+This stores the first 15 lines of the supplied data in the property src.file.head
+<blockquote><pre>
+&lt;loadfile srcfile=&quot;${src.file}&quot; property=&quot;src.file.head&quot;&gt;
+ &lt;filterchain&gt;
+ &lt;filterreader classname=&quot;org.apache.tools.ant.filters.HeadFilter&quot;&gt;
+ &lt;param name=&quot;lines&quot; value=&quot;15&quot;/&gt;
+ &lt;/filterreader&gt;
+ &lt;/filterchain&gt;
+&lt;/loadfile&gt;
+</pre></blockquote>
+
+Convenience method:
+<blockquote><pre>
+&lt;loadfile srcfile=&quot;${src.file}&quot; property=&quot;src.file.head&quot;&gt;
+ &lt;filterchain&gt;
+ &lt;headfilter lines=&quot;15&quot;/&gt;
+ &lt;/filterchain&gt;
+&lt;/loadfile&gt;
+</pre></blockquote>
+
+This stores the first 15 lines, skipping the first 2 lines, of the supplied data
+in the property src.file.head. (Means: lines 3-17)
+<blockquote><pre>
+&lt;loadfile srcfile=&quot;${src.file}&quot; property=&quot;src.file.head&quot;&gt;
+ &lt;filterchain&gt;
+ &lt;headfilter lines=&quot;15&quot; skip=&quot;2&quot;/&gt;
+ &lt;/filterchain&gt;
+&lt;/loadfile&gt;
+</pre></blockquote>
+
+See the testcases for more examples (<i>src\etc\testcases\filters\head-tail.xml</i> in the
+source distribution).
+
+<h3><a name="linecontains">LineContains</a></h3>
+
+This filter includes only those lines that contain all the user-specified
+strings.
+
+<table cellSpacing=0 cellPadding=2 border=1>
+ <tr>
+ <td vAlign=top><b>Parameter Type</b></td>
+ <td vAlign=top><b>Parameter Value</b></td>
+ <td vAlign=top align="center"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td vAlign=top>contains</td>
+ <td vAlign=top align="center">Substring to be searched for.</td>
+ <td vAlign=top align="center">Yes</td>
+ </tr>
+ <tr>
+ <td vAlign=top>negate</td>
+ <td vAlign=top align="center">Whether to select
+ <i>non-</i>matching lines only. <b>Since Ant 1.7</b></td>
+ <td vAlign=top align="center">No</td>
+ </tr>
+</table>
+<p>
+<h4>Example:</h4>
+
+This will include only those lines that contain <code>foo</code> and
+<code>bar</code>.
+<blockquote><pre>
+&lt;filterreader classname=&quot;org.apache.tools.ant.filters.LineContains&quot;&gt;
+ &lt;param type=&quot;contains&quot; value=&quot;foo&quot;/&gt;
+ &lt;param type=&quot;contains&quot; value=&quot;bar&quot;/&gt;
+&lt;/filterreader&gt;
+</pre></blockquote>
+
+Convenience method:
+<blockquote><pre>
+&lt;linecontains&gt;
+ &lt;contains value=&quot;foo&quot;/&gt;
+ &lt;contains value=&quot;bar&quot;/&gt;
+&lt;/linecontains&gt;
+</pre></blockquote>
+
+Negation:
+<blockquote><pre>
+&lt;filterreader classname=&quot;org.apache.tools.ant.filters.LineContains&quot;&gt;
+ &lt;param type=&quot;negate&quot; value=&quot;true&quot;/&gt;
+ &lt;param type=&quot;contains&quot; value=&quot;foo&quot;/&gt;
+ &lt;param type=&quot;contains&quot; value=&quot;bar&quot;/&gt;
+&lt;/filterreader&gt;
+</pre></blockquote>
+<i>or</i>
+<blockquote><pre>
+&lt;linecontains negate=&quot;true&quot;&gt;
+ &lt;contains value=&quot;foo&quot;/&gt;
+ &lt;contains value=&quot;bar&quot;/&gt;
+&lt;/linecontains&gt;
+</pre></blockquote>
+
+<h3><a name="linecontainsregexp">LineContainsRegExp</a></h3>
+
+Filter which includes only those lines that contain the user-specified
+regular expression matching strings.
+
+<table cellSpacing=0 cellPadding=2 border=1>
+ <tr>
+ <td vAlign=top><b>Parameter Type</b></td>
+ <td vAlign=top><b>Parameter Value</b></td>
+ <td vAlign=top align="center"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td vAlign=top>regexp</td>
+ <td vAlign=top align="center">Regular expression to be searched for.</td>
+ <td vAlign=top align="center">Yes</td>
+ </tr>
+ <tr>
+ <td vAlign=top>negate</td>
+ <td vAlign=top align="center">Whether to select
+ <i>non-</i>matching lines only. <b>Since Ant 1.7</b></td>
+ <td vAlign=top align="center">No</td>
+ </tr>
+ <tr>
+ <td vAlign=top>casesensitive</td>
+ <td vAlign=top align="center">Perform a case sensitive
+ match. Default is true. <b>Since Ant 1.8.2</b></td>
+ <td vAlign=top align="center">No</td>
+ </tr>
+</table>
+
+See <a href="regexp.html">Regexp Type</a> for the description of the nested element regexp and of
+the choice of regular expression implementation.
+<h4>Example:</h4>
+
+This will fetch all those lines that contain the pattern <code>foo</code>
+<blockquote><pre>
+&lt;filterreader classname=&quot;org.apache.tools.ant.filters.LineContainsRegExp&quot;&gt;
+ &lt;param type=&quot;regexp&quot; value=&quot;foo*&quot;/&gt;
+&lt;/filterreader&gt;
+</pre></blockquote>
+
+Convenience method:
+<blockquote><pre>
+&lt;linecontainsregexp&gt;
+ &lt;regexp pattern=&quot;foo*&quot;/&gt;
+&lt;/linecontainsregexp&gt;
+</pre></blockquote>
+
+Negation:
+<blockquote><pre>
+&lt;filterreader classname=&quot;org.apache.tools.ant.filters.LineContainsRegExp&quot;&gt;
+ &lt;param type=&quot;negate&quot; value=&quot;true&quot;/&gt;
+ &lt;param type=&quot;regexp&quot; value=&quot;foo*&quot;/&gt;
+&lt;/filterreader&gt;
+</pre></blockquote>
+<i>or</i>
+<blockquote><pre>
+&lt;linecontainsregexp negate=&quot;true&quot;&gt;
+ &lt;regexp pattern=&quot;foo*&quot;/&gt;
+&lt;/linecontainsregexp&gt;
+</pre></blockquote>
+
+<h3><a name="prefixlines">PrefixLines</a></h3>
+
+Attaches a prefix to every line.
+
+<table cellSpacing=0 cellPadding=2 border=1>
+ <tr>
+ <td vAlign=top><b>Parameter Name</b></td>
+ <td vAlign=top><b>Parameter Value</b></td>
+ <td vAlign=top align="center"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td vAlign=top>prefix</td>
+ <td vAlign=top align="center">Prefix to be attached to lines.</td>
+ <td vAlign=top align="center">Yes</td>
+ </tr>
+</table>
+<p>
+<h4>Example:</h4>
+
+This will attach the prefix <code>Foo</code> to all lines.
+<blockquote><pre>
+&lt;filterreader classname=&quot;org.apache.tools.ant.filters.PrefixLines&quot;&gt;
+ &lt;param name=&quot;prefix&quot; value=&quot;Foo&quot;/&gt;
+&lt;/filterreader&gt;
+</pre></blockquote>
+
+Convenience method:
+<blockquote><pre>
+&lt;prefixlines prefix=&quot;Foo&quot;/&gt;
+</pre></blockquote>
+
+<h3><a name="suffixlines">SuffixLines</a></h3>
+
+Attaches a suffix to every line.
+
+<p><em>since Ant 1.8.0</em></p>
+
+<table cellSpacing=0 cellPadding=2 border=1>
+ <tr>
+ <td vAlign=top><b>Parameter Name</b></td>
+ <td vAlign=top><b>Parameter Value</b></td>
+ <td vAlign=top align="center"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td vAlign=top>suffix</td>
+ <td vAlign=top align="center">Suffix to be attached to lines.</td>
+ <td vAlign=top align="center">Yes</td>
+ </tr>
+</table>
+<p>
+<h4>Example:</h4>
+
+This will attach the suffix <code>Foo</code> to all lines.
+<blockquote><pre>
+&lt;filterreader classname=&quot;org.apache.tools.ant.filters.SuffixLines&quot;&gt;
+ &lt;param name=&quot;suffix&quot; value=&quot;Foo&quot;/&gt;
+&lt;/filterreader&gt;
+</pre></blockquote>
+
+Convenience method:
+<blockquote><pre>
+&lt;suffixlines suffix=&quot;Foo&quot;/&gt;
+</pre></blockquote>
+
+<h3><a name="replacetokens">ReplaceTokens</a></h3>
+
+This filter reader replaces all strings that are
+sandwiched between begintoken and endtoken with
+user defined values.
+
+<table cellSpacing=0 cellPadding=2 border=1>
+ <tr>
+ <td vAlign=top><b>Parameter Type</b></td>
+ <td vAlign=top><b>Parameter Name</b></td>
+ <td vAlign=top><b>Parameter Value</b></td>
+ <td vAlign=top align="center"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td vAlign=top>tokenchar</td>
+ <td vAlign=top>begintoken</td>
+ <td vAlign=top>String marking the
+ beginning of a token. Defaults to @</td>
+ <td vAlign=top align="center">No</td>
+ </tr>
+ <tr>
+ <td vAlign=top>tokenchar</td>
+ <td vAlign=top>endtoken</td>
+ <td vAlign=top>String marking the
+ end of a token. Defaults to @</td>
+ <td vAlign=top align="center">No</td>
+ </tr>
+ <tr>
+ <td vAlign=top>User defined String.</td>
+ <td vAlign=top>token</td>
+ <td vAlign=top>User defined search String.</td>
+ <td vAlign=top align="center">Yes</td>
+ </tr>
+ <tr>
+ <td vAlign=top>Not applicable.</td>
+ <td vAlign=top>propertiesfile</td>
+ <td vAlign=top>Properties file to take tokens from.</td>
+ <td vAlign=top align="center">No</td>
+ </tr>
+ <tr>
+ <td vAlign=top>Not applicable.</td>
+ <td vAlign=top>propertiesResource</td>
+ <td vAlign=top>Properties resource to take tokens from.
+ Note this only works is you use the
+ "convenience" <code>&lt;replacetokens&gt;</code> syntax.
+ <em>since Ant 1.8.0</em></td>
+ <td vAlign=top align="center">No</td>
+ </tr>
+ <tr>
+ <td vAlign=top>User defined String.</td>
+ <td vAlign=top>value</td>
+ <td vAlign=top>Replace-value for the token</td>
+ <td vAlign=top align="center">No</td>
+ </tr></table>
+<p>
+
+<h4>Example:</h4>
+
+This replaces occurrences of the string &#64;DATE&#64; in the data
+with today's date and stores it in the property ${src.file.replaced}.
+<blockquote><pre>
+&lt;tstamp/&gt;
+&lt;!-- just for explaining the use of the properties --&gt;
+&lt;property name=&quot;src.file&quot; value=&quot;orders.csv&quot;/&gt;
+&lt;property name=&quot;src.file.replaced&quot; value=&quot;orders.replaced&quot;/&gt;
+
+&lt;!-- do the loading and filtering --&gt;
+&lt;loadfile srcfile=&quot;${src.file}&quot; property=&quot;${src.file.replaced}&quot;&gt;
+ &lt;filterchain&gt;
+ &lt;filterreader classname=&quot;org.apache.tools.ant.filters.ReplaceTokens&quot;&gt;
+ &lt;param type=&quot;token&quot; name=&quot;DATE&quot; value=&quot;${TODAY}&quot;/&gt;
+ &lt;/filterreader&gt;
+ &lt;/filterchain&gt;
+&lt;/loadfile&gt;
+
+&lt;!-- just for explaining the use of the properties --&gt;
+&lt;echo message=&quot;${orders.replaced}&quot;/>
+</pre></blockquote>
+
+Convenience method:
+<blockquote><pre>
+&lt;tstamp/&gt;
+&lt;loadfile srcfile=&quot;${src.file}&quot; property=&quot;${src.file.replaced}&quot;&gt;
+ &lt;filterchain&gt;
+ &lt;replacetokens&gt;
+ &lt;token key=&quot;DATE&quot; value=&quot;${TODAY}&quot;/&gt;
+ &lt;/replacetokens&gt;
+ &lt;/filterchain&gt;
+&lt;/loadfile&gt;
+</pre></blockquote>
+
+This replaces occurrences of the string {{DATE}} in the data
+with today's date and stores it in the property ${src.file.replaced}.
+<blockquote><pre>
+&lt;loadfile srcfile=&quot;${src.file}&quot; property=&quot;${src.file.replaced}&quot;&gt;
+ &lt;filterchain&gt;
+ &lt;filterreader classname=&quot;org.apache.tools.ant.filters.ReplaceTokens&quot;&gt;
+ &lt;param type=&quot;tokenchar&quot; name=&quot;begintoken&quot; value=&quot;{{&quot;/&gt;
+ &lt;param type=&quot;tokenchar&quot; name=&quot;endtoken&quot; value=&quot;}}&quot;/&gt;
+ &lt;/filterreader&gt;
+ &lt;/filterchain&gt;
+&lt;/loadfile&gt;
+</pre></blockquote>
+
+Convenience method:
+<blockquote><pre>
+&lt;tstamp/&gt;
+&lt;loadfile srcfile=&quot;${src.file}&quot; property=&quot;${src.file.replaced}&quot;&gt;
+ &lt;filterchain&gt;
+ &lt;replacetokens begintoken=&quot;{{&quot; endtoken=&quot;}}&quot;&gt;
+ &lt;token key=&quot;DATE&quot; value=&quot;${TODAY}&quot;/&gt;
+ &lt;/replacetokens&gt;
+ &lt;/filterchain&gt;
+&lt;/loadfile&gt;
+</pre></blockquote>
+
+This will treat each properties file entry in sample.properties as a token/key pair :
+<blockquote><pre>
+&lt;loadfile srcfile=&quot;${src.file}&quot; property=&quot;${src.file.replaced}&quot;&gt;
+ &lt;filterchain&gt;
+ &lt;filterreader classname=&quot;org.apache.tools.ant.filters.ReplaceTokens&quot;&gt;
+ &lt;param type=&quot;propertiesfile&quot; value=&quot;sample.properties&quot;/&gt;
+ &lt;/filterreader&gt;
+ &lt;/filterchain&gt;
+&lt;/loadfile&gt;
+</pre></blockquote>
+
+This reads the properties from an Ant resource referenced by its id:
+<blockquote><pre>
+&lt;string id=&quot;embedded-properties&quot;&gt;
+foo=bar
+baz=xyzzy
+&lt;/string&gt;
+&lt;loadfile srcfile=&quot;${src.file}&quot; property=&quot;${src.file.replaced}&quot;&gt;
+ &lt;filterchain&gt;
+ &lt;replacetokens propertiesResource=&quot;${ant.refid:embedded-properties}&quot;/&gt;
+ &lt;/filterchain&gt;
+&lt;/loadfile&gt;
+</pre></blockquote>
+
+<h3><a name="stripjavacomments">StripJavaComments</a></h3>
+
+This filter reader strips away comments from the data,
+using Java syntax guidelines. This filter does not
+take in any parameters.
+<p>
+<h4>Example:</h4>
+
+<blockquote><pre>
+&lt;loadfile srcfile=&quot;${java.src.file}&quot; property=&quot;${java.src.file.nocomments}&quot;&gt;
+ &lt;filterchain&gt;
+ &lt;filterreader classname=&quot;org.apache.tools.ant.filters.StripJavaComments&quot;/&gt;
+ &lt;/filterchain&gt;
+&lt;/loadfile&gt;
+</pre></blockquote>
+
+Convenience method:
+<blockquote><pre>
+&lt;loadfile srcfile=&quot;${java.src.file}&quot; property=&quot;${java.src.file.nocomments}&quot;&gt;
+ &lt;filterchain&gt;
+ &lt;stripjavacomments/&gt;
+ &lt;/filterchain&gt;
+&lt;/loadfile&gt;
+</pre></blockquote>
+
+<h3><a name="striplinebreaks">StripLineBreaks</a></h3>
+
+This filter reader strips away specific characters
+from the data supplied to it.
+
+<table cellSpacing=0 cellPadding=2 border=1>
+ <tr>
+ <td vAlign=top><b>Parameter Name</b></td>
+ <td vAlign=top><b>Parameter Value</b></td>
+ <td vAlign=top align="center"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td vAlign=top>linebreaks</td>
+ <td vAlign=top align="center">Characters that are to
+ be stripped out. Defaults to &quot;\r\n&quot;</td>
+ <td vAlign=top align="center">No</td>
+ </tr>
+</table>
+<p>
+<h4>Examples:</h4>
+
+This strips the '\r' and '\n' characters.
+<blockquote><pre>
+&lt;loadfile srcfile=&quot;${src.file}&quot; property=&quot;${src.file.contents}&quot;&gt;
+ &lt;filterchain&gt;
+ &lt;filterreader classname=&quot;org.apache.tools.ant.filters.StripLineBreaks&quot;/&gt;
+ &lt;/filterchain&gt;
+&lt;/loadfile&gt;
+</pre></blockquote>
+
+Convenience method:
+<blockquote><pre>
+&lt;loadfile srcfile=&quot;${src.file}&quot; property=&quot;${src.file.contents}&quot;&gt;
+ &lt;filterchain&gt;
+ &lt;striplinebreaks/&gt;
+ &lt;/filterchain&gt;
+&lt;/loadfile&gt;
+</pre></blockquote>
+
+This treats the '(' and ')' characters as line break characters and
+strips them.
+<blockquote><pre>
+&lt;loadfile srcfile=&quot;${src.file}&quot; property=&quot;${src.file.contents}&quot;&gt;
+ &lt;filterchain&gt;
+ &lt;filterreader classname=&quot;org.apache.tools.ant.filters.StripLineBreaks&quot;&gt;
+ &lt;param name=&quot;linebreaks&quot; value=&quot;()&quot;/&gt;
+ &lt;/filterreader&gt;
+ &lt;/filterchain&gt;
+&lt;/loadfile&gt;
+</pre></blockquote>
+
+<h3><a name="striplinecomments">StripLineComments</a></h3>
+
+This filter removes all those lines that begin with strings
+that represent comments as specified by the user.
+
+<table cellSpacing=0 cellPadding=2 border=1>
+ <tr>
+ <td vAlign=top><b>Parameter Type</b></td>
+ <td vAlign=top><b>Parameter Value</b></td>
+ <td vAlign=top align="center"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td vAlign=top>comment</td>
+ <td vAlign=top align="center">Strings that identify a line as a comment
+ when they appear at the start of the line.</td>
+ <td vAlign=top align="center">Yes</td>
+ </tr>
+</table>
+<p>
+<h4>Examples:</h4>
+
+This removes all lines that begin with #, --, REM, rem and //
+<blockquote><pre>
+&lt;filterreader classname=&quot;org.apache.tools.ant.filters.StripLineComments&quot;&gt;
+ &lt;param type=&quot;comment&quot; value=&quot;#&quot;/&gt;
+ &lt;param type=&quot;comment&quot; value=&quot;--&quot;/&gt;
+ &lt;param type=&quot;comment&quot; value=&quot;REM &quot;/&gt;
+ &lt;param type=&quot;comment&quot; value=&quot;rem &quot;/&gt;
+ &lt;param type=&quot;comment&quot; value=&quot;//&quot;/&gt;
+&lt;/filterreader&gt;
+</pre></blockquote>
+
+Convenience method:
+<blockquote><pre>
+&lt;striplinecomments&gt;
+ &lt;comment value=&quot;#&quot;/&gt;
+ &lt;comment value=&quot;--&quot;/&gt;
+ &lt;comment value=&quot;REM &quot;/&gt;
+ &lt;comment value=&quot;rem &quot;/&gt;
+ &lt;comment value=&quot;//&quot;/&gt;
+&lt;/striplinecomments&gt;
+</pre></blockquote>
+
+<h3><a name="tabstospaces">TabsToSpaces</a></h3>
+
+This filter replaces tabs with spaces
+
+<table cellSpacing=0 cellPadding=2 border=1>
+ <tr>
+ <td vAlign=top><b>Parameter Name</b></td>
+ <td vAlign=top><b>Parameter Value</b></td>
+ <td vAlign=top align="center"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td vAlign=top>tablength</td>
+ <td vAlign=top align="center">Defaults to &quot;8&quot;</td>
+ <td vAlign=top align="center">No</td>
+ </tr>
+</table>
+<p>
+<h4>Examples:</h4>
+
+This replaces tabs in ${src.file} with spaces.
+<blockquote><pre>
+&lt;loadfile srcfile=&quot;${src.file}&quot; property=&quot;${src.file.notab}&quot;&gt;
+ &lt;filterchain&gt;
+ &lt;filterreader classname=&quot;org.apache.tools.ant.filters.TabsToSpaces&quot;/&gt;
+ &lt;/filterchain&gt;
+&lt;/loadfile&gt;
+</pre></blockquote>
+
+Convenience method:
+<blockquote><pre>
+&lt;loadfile srcfile=&quot;${src.file}&quot; property=&quot;${src.file.notab}&quot;&gt;
+ &lt;filterchain&gt;
+ &lt;tabstospaces/&gt;
+ &lt;/filterchain&gt;
+&lt;/loadfile&gt;
+</pre></blockquote>
+
+<h3><a name="tailfilter">TailFilter</a></h3>
+
+This filter reads the last few lines from the data supplied to it.
+
+<table cellSpacing=0 cellPadding=2 border=1>
+ <tr>
+ <td vAlign=top><b>Parameter Name</b></td>
+ <td vAlign=top><b>Parameter Value</b></td>
+ <td vAlign=top align="center"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td vAlign=top>lines</td>
+ <td vAlign=top align="center">Number of lines to be read.
+ Defaults to &quot;10&quot; <br> A negative value means that all lines are
+ passed (useful with <i>skip</i>)</td>
+ <td vAlign=top align="center">No</td>
+ </tr>
+ <tr>
+ <td vAlign=top>skip</td>
+ <td vAlign=top align="center">Number of lines to be skipped (from the end).
+ Defaults to &quot;0&quot; </td>
+ <td vAlign=top align="center">No</td>
+ </tr>
+</table>
+<p>
+
+<h4>Background:</h4>
+With HeadFilter and TailFilter you can extract each part of a text file you want.
+This graphic shows the dependencies:
+
+<table cellSpacing=0 cellPadding=2 border=1>
+<tr>
+ <th> Content </th>
+ <th></th>
+ <th></th>
+ <th></th>
+ <th> Filter </th>
+</tr>
+<tr>
+ <td> Line 1 </td>
+ <td rowspan="2" bgcolor="#C0C0C0">&nbsp;</td>
+ <td rowspan="9" bgcolor="#FF00FF">&nbsp;</td>
+ <td rowspan="4">&nbsp;</td>
+ <td rowspan="11">
+ <table>
+ <tr>
+ <td bgcolor="#C0C0C0">&nbsp;</td>
+ <td><pre>&lt;filterchain&gt;
+ &lt;headfilter lines="2"/&gt;
+&lt;/filterchain&gt;</pre></td>
+ </tr>
+ <tr>
+ <td bgcolor="#FF00FF">&nbsp;</td>
+ <td><pre>&lt;filterchain&gt;
+ &lt;tailfilter lines="-1" skip="2"/&gt;
+&lt;/filterchain&gt;</pre></td>
+ </tr>
+ <tr>
+ <td bgcolor="#008000">&nbsp;</td>
+ <td><pre>&lt;filterchain&gt;
+ &lt;headfilter lines="-1" skip="2"/&gt;
+&lt;/filterchain&gt;</pre></td>
+ </tr>
+ <tr>
+ <td bgcolor="#0000FF">&nbsp;</td>
+ <td><pre>&lt;filterchain&gt;
+ &lt;headfilter lines="-1" skip="2"/&gt;
+ &lt;tailfilter lines="-1" skip="2"/&gt;
+&lt;/filterchain&gt;</pre></td>
+ </tr>
+ <tr>
+ <td bgcolor="#00FF00">&nbsp;</td>
+ <td><pre>&lt;filterchain&gt;
+ &lt;tailfilter lines="2"/&gt;
+&lt;/filterchain&gt;</pre></td>
+ </tr>
+ </table>
+ </td>
+</tr>
+<tr>
+ <td> Line 2 </td>
+</tr>
+<tr>
+ <td> Line 3 </td>
+ <td rowspan="9" bgcolor="#008000">&nbsp;</td>
+</tr>
+<tr>
+ <td> Line 4 </td>
+</tr>
+<tr>
+ <td> Line 5 </td>
+ <td rowspan="3" bgcolor="#0000FF">&nbsp;</td>
+</tr>
+<tr>
+ <td> Lines ... </td>
+</tr>
+<tr>
+ <td> Line 95 </td>
+</tr>
+<tr>
+ <td> Line 96 </td>
+ <td rowspan="4">&nbsp;</td>
+</tr>
+<tr>
+ <td> Line 97 </td>
+</tr>
+<tr>
+ <td> Line 98 </td>
+ <td rowspan="2" bgcolor="#00FF00">&nbsp;</td>
+</tr>
+<tr>
+ <td> Line 99 </td>
+</tr>
+</table>
+
+
+
+<h4>Examples:</h4>
+
+This stores the last 15 lines of the supplied data in the property ${src.file.tail}
+<blockquote><pre>
+&lt;loadfile srcfile=&quot;${src.file}&quot; property=&quot;${src.file.tail}&quot;&gt;
+ &lt;filterchain&gt;
+ &lt;filterreader classname=&quot;org.apache.tools.ant.filters.TailFilter&quot;&gt;
+ &lt;param name=&quot;lines&quot; value=&quot;15&quot;/&gt;
+ &lt;/filterreader&gt;
+ &lt;/filterchain&gt;
+&lt;/loadfile&gt;
+</pre></blockquote>
+
+Convenience method:
+<blockquote><pre>
+&lt;loadfile srcfile=&quot;${src.file}&quot; property=&quot;${src.file.tail}&quot;&gt;
+ &lt;filterchain&gt;
+ &lt;tailfilter lines=&quot;15&quot;/&gt;
+ &lt;/filterchain&gt;
+&lt;/loadfile&gt;
+</pre></blockquote>
+
+
+This stores the last 5 lines of the first 15 lines of the supplied
+data in the property ${src.file.mid}
+<blockquote><pre>
+&lt;loadfile srcfile=&quot;${src.file}&quot; property=&quot;${src.file.mid}&quot;&gt;
+ &lt;filterchain&gt;
+ &lt;filterreader classname=&quot;org.apache.tools.ant.filters.HeadFilter&quot;&gt;
+ &lt;param name=&quot;lines&quot; value=&quot;15&quot;/&gt;
+ &lt;/filterreader&gt;
+ &lt;filterreader classname=&quot;org.apache.tools.ant.filters.TailFilter&quot;&gt;
+ &lt;param name=&quot;lines&quot; value=&quot;5&quot;/&gt;
+ &lt;/filterreader&gt;
+ &lt;/filterchain&gt;
+&lt;/loadfile&gt;
+</pre></blockquote>
+
+Convenience method:
+<blockquote><pre>
+&lt;loadfile srcfile=&quot;${src.file}&quot; property=&quot;${src.file.mid}&quot;&gt;
+ &lt;filterchain&gt;
+ &lt;headfilter lines=&quot;15&quot;/&gt;
+ &lt;tailfilter lines=&quot;5&quot;/&gt;
+ &lt;/filterchain&gt;
+&lt;/loadfile&gt;
+</pre></blockquote>
+
+
+This stores the last 10 lines, skipping the last 2 lines, of the supplied data
+in the property src.file.head. (Means: if supplied data contains 60 lines,
+lines 49-58 are extracted)
+<blockquote><pre>
+&lt;loadfile srcfile=&quot;${src.file}&quot; property=&quot;src.file.head&quot;&gt;
+ &lt;filterchain&gt;
+ &lt;tailfilter lines=&quot;10&quot; skip=&quot;2&quot;/&gt;
+ &lt;/filterchain&gt;
+&lt;/loadfile&gt;
+</pre></blockquote>
+
+<h3><a name="deletecharacters">DeleteCharacters</a></h3>
+
+ <p>This filter deletes specified characters.</p>
+ <p><em>since Ant 1.6</em></p>
+ <p>This filter is only available in the convenience form.</p>
+
+<table cellSpacing=0 cellPadding=2 border=1>
+ <tr>
+ <td vAlign=top><b>Parameter Name</b></td>
+ <td vAlign=top><b>Parameter Value</b></td>
+ <td vAlign=top align="center"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td vAlign=top>chars</td>
+ <td vAlign=top>
+ The characters to delete. This attribute is
+ <a href="#backslash">backslash enabled</a>.
+ </td>
+ <td vAlign=top align="center">Yes</td>
+ </tr>
+</table>
+<p>
+<h4>Examples:</h4>
+
+Delete tabs and returns from the data.
+<blockquote><pre>
+&lt;deletecharacters chars="\t\r"/&gt;
+</pre></blockquote>
+
+<h3><a name="concatfilter">ConcatFilter</a></h3>
+ <p>This filter prepends or appends the content file to the filtered files.</p>
+ <p><em>since Ant 1.6</em></p>
+<table cellSpacing=0 cellPadding=2 border=1>
+ <tr>
+ <td vAlign=top><b>Parameter Name</b></td>
+ <td vAlign=top><b>Parameter Value</b></td>
+ <td vAlign=top align="center"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td vAlign=top>prepend</td>
+ <td vAlign=top>
+ The name of the file which content should be prepended to the file.
+ </td>
+ <td vAlign=top align="center">No</td>
+ </tr>
+ <tr>
+ <td vAlign=top>append</td>
+ <td vAlign=top>
+ The name of the file which content should be appended to the file.
+ </td>
+ <td vAlign=top align="center">No</td>
+ </tr>
+</table>
+<p>
+
+<h4>Examples:</h4>
+
+Do nothing:
+<blockquote><pre>
+&lt;filterchain&gt;
+ &lt;concatfilter/&gt;
+&lt;/filterchain&gt;
+</pre></blockquote>
+
+Adds a license text before each java source:
+<blockquote><pre>
+&lt;filterchain&gt;
+ &lt;concatfilter prepend="apache-license-java.txt"/&gt;
+&lt;/filterchain&gt;
+</pre></blockquote>
+
+
+
+<h3><a name="tokenfilter">TokenFilter</a></h3>
+This filter tokenizes the inputstream into strings and passes these
+strings to filters of strings. Unlike the other filterreaders, this does
+not support params, only convenience methods are implemented.
+The tokenizer and the string filters are defined by nested elements.
+<p><em>since Ant 1.6</em></p>
+<p>
+Only one tokenizer element may be used, the LineTokenizer is the
+default if none are specified. A tokenizer
+splits the input into token strings and trailing delimiter strings.
+<p>
+There may be zero or more string filters. A string filter processes
+a token and either returns a string or a null.
+It the string is not null it is passed to the next filter. This
+proceeds until all the filters are called.
+If a string is returned after all the filters, the string is
+outputs with its associated token delimiter
+(if one is present).
+The trailing delimiter may be overridden by the <i>delimOutput</i>
+attribute.
+<p>
+<a name="backslash"><em>backslash interpretation</em></a>
+A number of attributes (including <i>delimOutput</i>) interpret
+backslash escapes. The following are understood: \n, \r, \f, \t
+and \\.
+
+
+<table cellSpacing=0 cellPadding=2 border=1>
+ <tr>
+ <td vAlign=top><b>Attribute</b></td>
+ <td vAlign=top><b>Description</b></td>
+ <td vAlign=top align="center"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td vAlign=top>delimOutput</td>
+ <td vAlign=top>
+ This overrides the tokendelimiter
+ returned by the tokenizer if it is not empty. This
+ attribute is backslash enabled.
+</td>
+ <td vAlign=top align="center">No</td>
+ </tr>
+</table>
+<p>
+
+ The following tokenizers are provided by the default distribution.
+ <p>
+ <a href="#linetokenizer">LineTokenizer</a><br>
+ <a href="#filetokenizer">FileTokenizer</a><br>
+ <a href="#stringtokenizer">StringTokenizer</a><br>
+ </p>
+
+ The following string filters are provided by the default distribution.
+ <p>
+ <a href="#replacestring">ReplaceString</a><br>
+ <a href="#containsstring">ContainsString</a><br>
+ <a href="#replaceregex">ReplaceRegex</a><br>
+ <a href="#containsregex">ContainsRegex</a><br>
+ <a href="#trim">Trim</a><br>
+ <a href="#ignoreblank">IgnoreBlank</a><br>
+ <a href="#filterdeletecharacters">DeleteCharacters</a><br>
+ <a href="#uniqfilter">UniqFilter</a><br>
+ </p>
+
+ The following string filters are provided by the optional distribution.
+ <p>
+ <a href="#scriptfilter">ScriptFilter</a><br>
+ </p>
+
+Some of the filters may be used directly within a filter chain. In this
+case a tokenfilter is created implicitly. An extra attribute "byline"
+is added to the filter to specify whether to use a linetokenizer
+(byline="true") or a filetokenizer (byline="false"). The default
+is "true".
+<p>
+
+<p><b><em><a name="linetokenizer">LineTokenizer</a></em></b></p>
+This tokenizer splits the input into lines.
+The tokenizer delimits lines
+by "\r", "\n" or "\r\n".
+This is the default tokenizer.
+<table cellSpacing=0 cellPadding=2 border=1>
+ <tr>
+ <td vAlign=top><b>Attribute</b></td>
+ <td vAlign=top><b>Description</b></td>
+ <td vAlign=top align="center"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td vAlign=top>includeDelims</td>
+ <td vAlign=top>
+ Include the line endings in the token.
+ Default is false.
+ </td>
+ <td vAlign=top align="center">No</td>
+ </tr>
+</table>
+<h4>Examples:</h4>
+
+Convert input current line endings to unix style line endings.
+<blockquote><pre>
+&lt;tokenfilter delimoutput=&quot;\n&quot;/&gt;
+</pre></blockquote>
+
+
+Remove blank lines.
+<blockquote><pre>
+&lt;tokenfilter&gt;
+ &lt;ignoreblank/&gt;
+&lt;/tokenfilter&gt;
+
+</pre></blockquote>
+
+<p><b><em><a name="filetokenizer">FileTokenizer</a></em></b></p>
+This tokenizer treats <b>all</b> the input as a token. So be
+careful not to use this on very large input.
+<h4>Examples:</h4>
+
+Replace the first occurrence of package with //package.
+<blockquote><pre>
+&lt;tokenfilter&gt;
+ &lt;filetokenizer/&gt;
+ &lt;replaceregex pattern="([\n\r]+[ \t]*|^[ \t]*)package"
+ flags="s"
+ replace="\1//package"/&gt;
+&lt;/tokenfilter&gt;
+</pre></blockquote>
+
+<p><b><em><a name="stringtokenizer">StringTokenizer</a></em></b></p>
+This tokenizer is based on java.util.StringTokenizer.
+It splits up the input into strings separated by white space, or
+by a specified list of delimiting characters.
+If the stream starts with delimiter characters, the first
+token will be the empty string (unless the <i>delimsaretokens</i>
+attribute is used).
+
+<table cellSpacing=0 cellPadding=2 border=1>
+ <tr>
+ <td vAlign=top><b>Attribute</b></td>
+ <td vAlign=top><b>Description</b></td>
+ <td vAlign=top align="center"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td vAlign=top>delims</td>
+ <td vAlign=top>The delimiter characters. White space
+ is used if this is not set. (White space is defined
+ in this case by java.lang.Character.isWhitespace()).
+ </td>
+ <td vAlign=top align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">delimsaretokens</td>
+ <td valign="top">If this is true,
+ each delimiter character is returned as a token.
+ Default is false.
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">suppressdelims</td>
+ <td valign="top">
+ If this is true, delimiters are not returned.
+ Default is false.
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td vAlign=top>includeDelims</td>
+ <td vAlign=top>
+ Include the delimiters in the token.
+ Default is false.
+ </td>
+ <td vAlign=top align="center">No</td>
+ </tr>
+</table>
+
+<h4>Examples:</h4>
+
+Surround each non space token with a "[]".
+
+<blockquote><pre>
+&lt;tokenfilter&gt;
+ &lt;stringtokenizer/&gt;
+ &lt;replaceregex pattern="(.+)" replace="[\1]"/&gt;
+&lt;/tokenfilter&gt;
+
+</pre></blockquote>
+
+<p><b><em><a name="replacestring">ReplaceString</a></em></b></p>
+This is a simple filter to replace strings.
+This filter may be used directly within a filterchain.
+
+<table cellSpacing=0 cellPadding=2 border=1>
+ <tr>
+ <td vAlign=top><b>Attribute</b></td>
+ <td vAlign=top><b>Description</b></td>
+ <td vAlign=top align="center"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td vAlign=top>from</td>
+ <td vAlign=top>The string that must be replaced.</td>
+ <td vAlign=top align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">to</td>
+ <td valign="top">The new value for the replaced string. When omitted
+ an empty string is used.
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+</table>
+
+<h4>Examples:</h4>
+
+Replace "sun" with "moon".
+
+<blockquote><pre>
+&lt;tokenfilter&gt;
+ &lt;replacestring from="sun" to="moon"/&gt;
+&lt;/tokenfilter&gt;
+</pre></blockquote>
+
+<p><b><em><a name="containsstring">ContainsString</a></em></b></p>
+This is a simple filter to filter tokens that contains
+a specified string.
+
+<table cellSpacing=0 cellPadding=2 border=1>
+ <tr>
+ <td vAlign=top><b>Attribute</b></td>
+ <td vAlign=top><b>Description</b></td>
+ <td vAlign=top align="center"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td vAlign=top>contains</td>
+ <td vAlign=top>The string that the token must contain.</td>
+ <td vAlign=top align="center">Yes</td>
+ </tr>
+</table>
+
+<h4>Examples:</h4>
+
+Include only lines that contain "foo";
+
+<blockquote><pre>
+&lt;tokenfilter&gt;
+ &lt;containsstring contains="foo"/&gt;
+&lt;/tokenfilter&gt;
+
+</pre></blockquote>
+
+<p><b><em><a name="replaceregex">ReplaceRegex</a></em></b></p>
+This string filter replaces regular expressions.
+This filter may be used directly within a filterchain.
+<p>
+ See <a href="regexp.html#implementation">Regexp Type</a>
+concerning the choice of the implementation.
+</p>
+
+<table cellSpacing=0 cellPadding=2 border=1>
+ <tr>
+ <td vAlign=top><b>Attribute</b></td>
+ <td vAlign=top><b>Description</b></td>
+ <td vAlign=top align="center"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td vAlign=top>pattern</td>
+ <td vAlign=top>The regular expression pattern to match in
+ the token.</td>
+ <td vAlign=top align="center">Yes</td>
+ </tr>
+ <tr>
+ <td vAlign=top>replace</td>
+ <td vAlign=top>The substitution pattern to replace the matched
+ regular expression. When omitted an empty string is used.</td>
+ <td vAlign=top align="center">No</td>
+ </tr>
+ <tr>
+ <td vAlign=top>flags</td>
+ <td vAlign=top>See
+<a href="../Tasks/replaceregexp.html">ReplaceRegexp</a>
+for an explanation of regex flags.</td>
+ <td vAlign=top align="center">No</td>
+ </tr>
+</table>
+<h4>Examples:</h4>
+
+Replace all occurrences of "hello" with "world", ignoring case.
+
+<blockquote><pre>
+&lt;tokenfilter&gt;
+ &lt;replaceregex pattern="hello" replace="world" flags="gi"/&gt;
+&lt;/tokenfilter&gt;
+
+</pre></blockquote>
+
+<p><b><em><a name="containsregex">ContainsRegex</a></em></b></p>
+This filters strings that match regular expressions.
+The filter may optionally replace the matched regular expression.
+This filter may be used directly within a filterchain.
+<p>
+See
+<a href="regexp.html#implementation">Regexp Type</a>
+concerning the choice of regular expression implementation.
+</p>
+<table cellSpacing=0 cellPadding=2 border=1>
+ <tr>
+ <td vAlign=top><b>Attribute</b></td>
+ <td vAlign=top><b>Description</b></td>
+ <td vAlign=top align="center"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td vAlign=top>pattern</td>
+ <td vAlign=top>The regular expression pattern to match in
+ the token.</td>
+ <td vAlign=top align="center">Yes</td>
+ </tr>
+ <tr>
+ <td vAlign=top>replace</td>
+ <td vAlign=top>The substitution pattern to replace the matched
+ regular expression. When omitted the original token is returned.
+ </td>
+ <td vAlign=top align="center">No</td>
+ </tr>
+ <tr>
+ <td vAlign=top>flags</td>
+ <td vAlign=top>See
+<a href="../Tasks/replaceregexp.html">ReplaceRegexp</a>
+for an explanation of regex flags.</td>
+ <td vAlign=top align="center">No</td>
+ </tr>
+</table>
+
+<h4>Examples:</h4>
+
+Filter lines that contain "hello" or "world", ignoring case.
+
+<blockquote><pre>
+&lt;tokenfilter&gt;
+ &lt;containsregex pattern="(hello|world)" flags="i"/&gt;
+&lt;/tokenfilter&gt;
+
+</pre></blockquote>
+
+This example replaces lines like "SUITE(TestSuite, bits);" with
+"void register_bits();" and removes other lines.
+
+<blockquote><pre>
+&lt;tokenfilter&gt;
+ &lt;containsregex
+ pattern="^ *SUITE\(.*,\s*(.*)\s*\).*"
+ replace="void register_\1();"/&gt;
+&lt;/tokenfilter&gt;
+</pre></blockquote>
+
+<p><b><em><a name="trim">Trim</a></em></b></p>
+This filter trims whitespace from the start and end of
+tokens.
+This filter may be used directly within a filterchain.
+<p><b><em><a name="ignoreblank">IgnoreBlank</a></em></b></p>
+This filter removes empty tokens.
+This filter may be used directly within a filterchain.
+<p><b><em><a name="filterdeletecharacters">DeleteCharacters</a></em></b></p>
+This filter deletes specified characters from tokens.
+
+<table cellSpacing=0 cellPadding=2 border=1>
+ <tr>
+ <td vAlign=top><b>Attribute</b></td>
+ <td vAlign=top><b>Description</b></td>
+ <td vAlign=top align="center"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td vAlign=top>chars</td>
+ <td vAlign=top>The characters to delete. This attribute
+ is backslash enabled.</td>
+ <td vAlign=top align="center">Yes</td>
+ </tr>
+</table>
+
+<h4>Examples:</h4>
+
+Delete tabs from lines, trim the lines and removes empty lines.
+
+<blockquote><pre>
+&lt;tokenfilter&gt;
+ &lt;deletecharacters chars="\t"/&gt;
+ &lt;trim/&gt;
+ &lt;ignoreblank/&gt;
+&lt;/tokenfilter&gt;
+
+</pre></blockquote>
+
+<p><b><em><a name="uniqfilter">UniqFilter</a></em></b></p>
+
+<p>Suppresses all tokens that match their ancestor token. It is most
+ useful if combined with a sort filter.</p>
+
+<p>This filter may be used directly within a filterchain.</p>
+
+<h4>Example:</h4>
+
+This suppresses duplicate lines.
+<blockquote><pre>
+&lt;tokenfilter&gt;
+ &lt;uniqfilter/&gt;
+&lt;/tokenfilter&gt;
+</pre></blockquote>
+
+<p><b><em><a name="scriptfilter">ScriptFilter</a></em></b></p>
+This is an optional filter that executes a script in a
+<a href="http://jakarta.apache.org/bsf" target="_top">Apache BSF</a>
+ or
+ <a href="https://scripting.dev.java.net">JSR 223</a>
+supported language.</p>
+See the <a href="../Tasks/script.html">Script</a> task for
+an explanation of scripts and dependencies.
+</p>
+<p>
+The script is provided with an object <i>self</i> that has
+getToken() and setToken(String) methods.
+The getToken() method returns the current token. The setToken(String)
+method replaces the current token.
+</p>
+
+This filter may be used directly within a filterchain.<p>
+<table cellSpacing=0 cellPadding=2 border=1>
+ <tr>
+ <td vAlign=top><b>Attribute</b></td>
+ <td vAlign=top><b>Description</b></td>
+ <td vAlign=top align="center"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td vAlign=top>language</td>
+ <td vAlign=top> The programming language the script is written in.
+Must be a supported Apache BSF or JSR 223 language</td>
+ <td vAlign=top align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">manager</td>
+ <td valign="top">
+ The script engine manager to use.
+ See the <a href="../Tasks/script.html">script</a> task
+ for using this attribute.
+ </td>
+ <td valign="top" align="center">No - default is "auto"</td>
+ </tr>
+ <tr>
+ <td vAlign=top>src</td>
+ <td vAlign=top>The location of the script as a file, if not inline
+ </td>
+ <td vAlign=top align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">setbeans</td>
+ <td valign="top">whether to have all properties, references and targets as
+ global variables in the script. <em>since Ant 1.8.0</em></td>
+ <td valign="top" align="center">No, default is "true".</td>
+ </tr>
+ <tr>
+ <td valign="top">classpath</td>
+ <td valign="top">
+ The classpath to pass into the script.
+ </td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">classpathref</td>
+ <td valign="top">The classpath to use, given as a
+ <a href="../using.html#references">reference</a> to a path defined elsewhere.
+ <td align="center" valign="top">No</td>
+ </tr>
+</table>
+ <p>
+ This filter can take a nested &lt;classpath&gt; element.
+ See the <a href="../Tasks/script.html">script</a> task
+ on how to use this element.
+ </p>
+<h4>Examples:</h4>
+
+Convert to uppercase:
+<blockquote><pre>
+&lt;tokenfilter&gt;
+ &lt;scriptfilter language="javascript"&gt;
+ self.setToken(self.getToken().toUpperCase());
+ &lt;/scriptfilter&gt;
+&lt;/tokenfilter&gt;
+</pre></blockquote>
+
+Remove lines containing the string "bad" while
+copying text files:
+ <blockquote>
+ <pre>
+&lt;copy todir="dist"&gt;
+ &lt;fileset dir="src" includes="**/*.txt"/&gt;
+ &lt;filterchain&gt;
+ &lt;scriptfilter language="beanshell"&gt;
+ if (self.getToken().indexOf("bad") != -1) {
+ self.setToken(null);
+ }
+ &lt;/scriptfilter&gt;
+ &lt;/filterchain&gt;
+&lt;/copy&gt;
+ </pre>
+ </blockquote>
+
+<h4>Custom tokenizers and string filters</h4>
+
+Custom string filters and tokenizers may be plugged in by
+extending the interfaces org.apache.tools.ant.filters.TokenFilter.Filter
+and org.apache.tools.ant.util.Tokenizer respectly.
+
+They are defined the build file using <code>&lt;typedef/&gt;</code>. For
+example a string filter that capitalizes words may be declared as:
+<blockquote><pre>
+package my.customant;
+import org.apache.tools.ant.filters.TokenFilter;
+
+public class Capitalize
+ implements TokenFilter.Filter
+{
+ public String filter(String token) {
+ if (token.length() == 0)
+ return token;
+ return token.substring(0, 1).toUpperCase() +
+ token.substring(1);
+ }
+}
+</pre></blockquote>
+
+This may be used as follows:
+<blockquote><pre>
+ &lt;typedef name="capitalize" classname="my.customant.Capitalize"
+ classpath="my.customant.path"/&gt;
+ &lt;copy file="input" tofile="output"&gt;
+ &lt;filterchain&gt;
+ &lt;tokenfilter&gt;
+ &lt;stringtokenizer/&gt;
+ &lt;capitalize/&gt;
+ &lt;/tokenfilter&gt;
+ &lt;/filterchain&gt;
+ &lt;/copy&gt;
+</pre></blockquote>
+
+
+<h3><a name="sortfilter">SortFilter</a></h3>
+ <p><em>since Ant 1.8.0</em></p>
+
+<p>The sort filter reads all lines and sorts them. The sort order can
+ be reversed and it is possible to specify a custom implementation of
+ the <code>java.util.Comparator</code> interface to get even more
+ control.</p>
+
+<table cellSpacing=0 cellPadding=2 border=1>
+ <tr>
+ <td vAlign=top><b>Parameter Name</b></td>
+ <td vAlign=top><b>Parameter Value</b></td>
+ <td vAlign=top align="center"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td vAlign=top>reverse</td>
+ <td vAlign=top align="center">whether to reverse the sort order,
+ defaults to false. <b>Note:</b> this parameter is ignored if
+ the comparator parameter is present as well.</td>
+ <td vAlign=top align="center">No</td>
+ </tr>
+ <tr>
+ <td vAlign=top>comparator</td>
+ <td vAlign=top align="center">Class name of a class that
+ implements <code>java.util.Comparator</code> for Strings. This
+ class will be used to determine the sort order of lines.</td>
+ <td vAlign=top align="center">No</td>
+ </tr>
+</table>
+
+<p>This filter is also available using the
+ name <code>sortfilter</code>. The <code>reverse</code> parameter
+ becomes an attribute, <code>comparator</code> can be specified by
+ using a nested element.</p>
+
+<h4>Examples:</h4>
+
+<blockquote><pre>
+ &lt;copy todir=&quot;build&quot;&gt;
+ &lt;fileset dir=&quot;input&quot; includes=&quot;*.txt&quot;/&gt;
+ &lt;filterchain&gt;
+ &lt;sortfilter/&gt;
+ &lt;/filterchain&gt;
+ &lt;/copy&gt;
+</pre></blockquote>
+
+<p>
+Sort all files <code>*.txt</code> from <i>src</i> location
+into <i>build</i> location. The lines of each file are sorted in
+ascendant order comparing the lines via the
+<code>String.compareTo(Object o)</code> method.
+</p>
+
+<blockquote><pre>
+ &lt;copy todir=&quot;build&quot;&gt;
+ &lt;fileset dir=&quot;input&quot; includes=&quot;*.txt&quot;/&gt;
+ &lt;filterchain&gt;
+ &lt;sortfilter reverse=&quot;true&quot;/&gt;
+ &lt;/filterchain&gt;
+ &lt;/copy&gt;
+</pre></blockquote>
+
+<p>
+Sort all files <code>*.txt</code> from <i>src</i> location into reverse
+order and copy them into <i>build</i> location.
+</p>
+
+<blockquote><pre>
+ &lt;copy todir=&quot;build&quot;&gt;
+ &lt;fileset dir=&quot;input&quot; includes=&quot;*.txt&quot;/&gt;
+ &lt;filterchain&gt;
+ &lt;filterreader classname=&quot;org.apache.tools.ant.filters.SortFilter&quot;&gt;
+ &lt;param name=&quot;comparator&quot; value=&quot;org.apache.tools.ant.filters.EvenFirstCmp&quot;/&gt;
+ &lt;/filterreader&gt;
+ &lt;/filterchain&gt;
+ &lt;/copy&gt;
+</pre></blockquote>
+
+<p>
+Sort all files <code>*.txt</code> from <i>src</i> location using as
+sorting criterium <code>EvenFirstCmp</code> class, that sorts the file
+lines putting even lines first then odd lines for example. The modified files
+are copied into <i>build</i> location. The <code>EvenFirstCmp</code>,
+has to an instanciable class via <code>Class.newInstance()</code>,
+therefore in case of inner class has to be <em>static</em>. It also has to
+implement <code>java.util.Comparator</code> interface, for example:
+</p>
+
+<pre>
+ package org.apache.tools.ant.filters;
+ ...(omitted)
+ public final class EvenFirstCmp implements &lt;b&gt;Comparator&lt;/b&gt; {
+ public int compare(Object o1, Object o2) {
+ ...(omitted)
+ }
+ }
+</pre>
+
+<p>The example above is equivalent to:</p>
+
+<blockquote><pre>
+ &lt;componentdef name="evenfirst"
+ classname="org.apache.tools.ant.filters.EvenFirstCmp&quot;/&gt;
+ &lt;copy todir=&quot;build&quot;&gt;
+ &lt;fileset dir=&quot;input&quot; includes=&quot;*.txt&quot;/&gt;
+ &lt;filterchain&gt;
+ &lt;sortfilter&gt;
+ &lt;evenfirst/&gt;
+ &lt;/sortfilter&gt;
+ &lt;/filterchain&gt;
+ &lt;/copy&gt;
+</pre></blockquote>
+
+</body></html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Types/filterset.html b/framework/src/ant/apache-ant-1.9.6/manual/Types/filterset.html
new file mode 100644
index 00000000..8b0dfe18
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Types/filterset.html
@@ -0,0 +1,200 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+
+<html>
+<head>
+ <link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>FilterSet Type</title>
+</head>
+
+<body>
+<h2><a name="filterset">FilterSet</a></h2>
+
+<p>FilterSets are groups of filters. Filters can be defined as token-value
+pairs
+or be read in from a file. FilterSets can appear inside tasks that support this
+feature or at the same level as <code>&lt;target&gt;</code> - i.e., as
+children of
+<code>&lt;project&gt;</code>.</p>
+
+<p>FilterSets support the <code>id</code> and <code>refid</code>
+attributes. You can define a FilterSet with an <code>id</code>
+attribute and then refer to that definition from another FilterSet
+with a <code>refid</code> attribute. It is also possible to nest
+filtersets into filtersets to get a set union of the contained
+filters.</p>
+
+<p>In addition, FilterSets can specify
+<code>begintoken</code> and/or
+<code>endtoken</code> attributes to define what to match.</p>
+<p>Filtersets are used for doing
+replacements in tasks such as <code>&lt;copy&gt;</code>, etc.</p>
+
+<p>Filters can also by specified by one or more nested propertysets, the
+ contents of which are applied when the filterset is created.</p>
+
+<p>If you specify multiple values for the same token, the last one
+ defined within a filterset will be used.</p>
+
+<p>
+<strong>Note: </strong>When a filterset is used in an operation, the files are
+processed in text mode and the filters applied line by line. This means that
+the copy operations will typically corrupt binary files. When applying filters
+you should ensure that the set of files being filtered are all text files.
+</p>
+
+<h2>Filterset</h2>
+
+<table cellSpacing=0 cellPadding=2 border=1>
+ <tr>
+ <td vAlign=top><b>Attribute</b></td>
+ <td vAlign=top><b>Description</b></td>
+ <td vAlign=top><b>Default</b></td>
+ <td vAlign=top align="center"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td vAlign=top>begintoken</td>
+ <td vAlign=top>The string marking the beginning of a token (eg.,
+ <code>&#64;DATE&#64;</code>).</td>
+ <td vAlign=top>@</td>
+ <td vAlign=top align="center">No</td>
+ </tr>
+ <tr>
+ <td vAlign=top>endtoken</td>
+ <td vAlign=top>The string marking the end of a token (eg.,
+ <code>&#64;DATE&#64;</code>).</td>
+ <td vAlign=top>@</td>
+ <td vAlign=top align="center">No</td>
+ </tr>
+ <tr>
+ <td vAlign=top>filtersfile</td>
+ <td vAlign=top>Specify a single filtersfile.</td>
+ <td vAlign=top><i>none</i></td>
+ <td vAlign=top align="center">No</td>
+ </tr>
+ <tr>
+ <td vAlign=top>recurse</td>
+ <td vAlign=top>Indicates whether the replacement text of tokens
+ should be searched for more tokens. <b>Since Ant 1.6.3</b></td>
+ <td vAlign=top><i>true</i></td>
+ <td vAlign=top align="center">No</td>
+ </tr>
+ <tr>
+ <td vAlign=top>onmissingfiltersfile</td>
+ <td vAlign=top>Indicate behavior when a nonexistent <i>filtersfile</i>
+ is specified. One of "fail", "warn", "ignore". <b>Since Ant 1.7</b></td>
+ <td vAlign=top>"fail"</td>
+ <td vAlign=top align="center">No</td>
+ </tr>
+</table>
+
+<h2>Filter</h2>
+<table cellSpacing=0 cellPadding=2 border=1>
+ <tr>
+ <td vAlign=top><b>Attribute</b></td>
+ <td vAlign=top><b>Description</b></td>
+ <td vAlign=top align="center"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td vAlign=top>token</td>
+ <td vAlign=top>The token to replace (eg., <code>&#64;DATE&#64;</code>)</td>
+ <td vAlign=top align="center">Yes</td>
+ </tr>
+ <tr>
+ <td vAlign=top>value</td>
+ <td vAlign=top>The value to replace it with
+ (eg., <code>Thursday, April 26, 2001</code>).</td>
+ <td vAlign=top align="center">Yes</td>
+ </tr>
+</table>
+
+<h2>Filtersfile</h2>
+<table cellSpacing=0 cellPadding=2 border=1>
+ <tr>
+ <td vAlign=top><b>Attribute</b></td>
+ <td vAlign=top><b>Description</b></td>
+ <td vAlign=top align="center"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td vAlign=top>file</td>
+ <td vAlign=top>A properties file of
+ name-value pairs from which to load the tokens.</td>
+ <td vAlign=top align="center">Yes</td>
+ </tr>
+</table>
+
+<h4>Examples</h4>
+
+<p>You are copying the <code>version.txt</code> file to the <code>dist</code>
+directory from the <code>build</code> directory
+but wish to replace the token <code>&#64;DATE&#64;</code> with today's date.</p>
+<blockquote><pre>
+&lt;copy file=&quot;${build.dir}/version.txt&quot; toFile=&quot;${dist.dir}/version.txt&quot;&gt;
+ &lt;filterset&gt;
+ &lt;filter token=&quot;DATE&quot; value=&quot;${TODAY}&quot;/&gt;
+ &lt;/filterset&gt;
+&lt;/copy&gt;
+</pre></blockquote>
+
+<p>You are copying the <code>version.txt</code> file to the <code>dist</code>
+directory from the build directory
+but wish to replace the token <code>%DATE*</code> with today's date.</p>
+<blockquote><pre>
+&lt;copy file=&quot;${build.dir}/version.txt&quot; toFile=&quot;${dist.dir}/version.txt&quot;&gt;
+ &lt;filterset begintoken=&quot;%&quot; endtoken=&quot;*&quot;&gt;
+ &lt;filter token=&quot;DATE&quot; value=&quot;${TODAY}&quot;/&gt;
+ &lt;/filterset&gt;
+&lt;/copy&gt;
+</pre></blockquote>
+
+<p>Copy all the docs but change all dates and appropriate notices as stored in a file.</p>
+<blockquote><pre>
+&lt;copy toDir=&quot;${dist.dir}/docs&quot;&gt;
+ &lt;fileset dir=&quot;${build.dir}/docs&quot;&gt;
+ &lt;include name=&quot;**/*.html&quot;&gt;
+ &lt;/fileset&gt;
+ &lt;filterset begintoken=&quot;%&quot; endtoken=&quot;*&quot;&gt;
+ &lt;filtersfile file=&quot;${user.dir}/dist.properties&quot;/&gt;
+ &lt;/filterset&gt;
+&lt;/copy&gt;
+</pre></blockquote>
+
+<p>Define a FilterSet and reference it later.</p>
+<blockquote><pre>
+&lt;filterset id=&quot;myFilterSet&quot; begintoken=&quot;%&quot; endtoken=&quot;*&quot;&gt;
+ &lt;filter token=&quot;DATE&quot; value=&quot;${TODAY}&quot;/&gt;
+&lt;/filterset&gt;
+
+&lt;copy file=&quot;${build.dir}/version.txt&quot; toFile=&quot;${dist.dir}/version.txt&quot;&gt;
+ &lt;filterset refid=&quot;myFilterSet&quot;/&gt;
+&lt;/copy&gt;
+</pre></blockquote>
+
+<p>You are copying the <code>version.txt</code> file to the <code>dist</code>
+directory from the <code>build</code> directory
+but wish to replace the token <code>&#64;project.date&#64;</code> with the property of the same name.</p>
+<blockquote><pre>
+&lt;copy file=&quot;${build.dir}/version.txt&quot; toFile=&quot;${dist.dir}/version.txt&quot;&gt;
+ &lt;filterset&gt;
+ &lt;propertyset&gt;
+ &lt;propertyref name=&quot;project.date&quot;/&gt;
+ &lt;/propertyset&gt;
+ &lt;/filterset&gt;
+&lt;/copy&gt;
+</pre></blockquote>
+</body></html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Types/mapper.html b/framework/src/ant/apache-ant-1.9.6/manual/Types/mapper.html
new file mode 100644
index 00000000..5aff311e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Types/mapper.html
@@ -0,0 +1,972 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Mapper Type</title>
+</head>
+
+<body>
+
+<h2><a name="mapper">Mapping File Names</a></h2>
+<p>Some tasks take source files and create target files. Depending on
+the task, it may be quite obvious which name a target file will have
+(using <a href="../Tasks/javac.html">javac</a>, you know there will be
+<code>.class</code> files for your <code>.java</code> files) - in
+other cases you may want to specify the target files, either to help
+Apache Ant or to get an extra bit of functionality.</p>
+<p>While source files are usually specified as <a
+href="fileset.html">fileset</a>s, you don't specify target files directly -
+instead, you tell Ant how to find the target file(s) for one source file. An
+instance of <code>org.apache.tools.ant.util.FileNameMapper</code> is
+responsible for this. It constructs target file names based on rules
+that can be parameterized with <code>from</code> and <code>to</code>
+attributes - the exact meaning of which is implementation-dependent.</p>
+<p>These instances are defined in <code>&lt;mapper&gt;</code> elements
+with the following attributes:</p>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">type</td>
+ <td valign="top">specifies one of the built-in implementations.</td>
+ <td rowspan="2" align="center" valign="middle">Exactly one of these</td>
+ </tr>
+ <tr>
+ <td valign="top">classname</td>
+ <td valign="top">specifies the implementation by class name.</td>
+ </tr>
+ <tr>
+ <td valign="top">classpath</td>
+ <td valign="top">the classpath to use when looking up
+ <code>classname</code>.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">classpathref</td>
+ <td valign="top">the classpath to use, given as <a
+ href="../using.html#references">reference</a> to a path defined elsewhere.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">from</td>
+ <td valign="top">the <code>from</code> attribute for the given
+ implementation.</td>
+ <td align="center" valign="top">Depends on implementation.</td>
+ </tr>
+ <tr>
+ <td valign="top">to</td>
+ <td valign="top">the <code>to</code> attribute for the given
+ implementation.</td>
+ <td align="center" valign="top">Depends on implementation.</td>
+ </tr>
+</table>
+<p>Note that Ant will not automatically convert / or \ characters in
+the <code>to</code> and <code>from</code> attributes to the correct
+directory separator of your current platform. If you need to specify
+this separator, use <code>${file.separator}</code> instead.
+ For the regexpmapper, <code>${file.separator}</code> will not work,
+as on windows it is the '\' character, and this is an escape character
+for regular expressions, one should use the <code>handledirsep</code> attribute
+instead.
+</p>
+<h3>Parameters specified as nested elements</h3>
+<p>The classpath can be specified via a nested
+<code>&lt;classpath&gt;</code>, as well - that is,
+a <a href="../using.html#path">path</a>-like structure.</p>
+<p><b>Since Ant 1.7.0,</b> nested File Mappers can
+be supplied via either <CODE>&lt;mapper&gt;</CODE> elements or
+<a href="../Tasks/typedef.html"><code>&lt;typedef&gt;</code></a>'d
+implementations of <CODE>org.apache.tools.ant.util.FileNameMapper</CODE>.
+If nested File Mappers are specified by either means, the mapper will be
+implicitly configured as a <a href="#composite-mapper">composite mapper</a>.
+</p>
+<hr>
+<h3>The built-in mapper types are:</h3>
+<p>All built-in mappers are case-sensitive.</p>
+<p><b>As of Ant 1.7.0,</b> each of the built-in mapper implementation
+ types is directly accessible using a specific tagname. This makes it
+ possible for filename mappers to support attributes in addition to
+ the generally available <i>to</i> and <i>from</i>.<br>
+ The <code>&lt;mapper type|classname=&quot;...&quot;&gt;</code> usage
+ form remains valid for reasons of backward compatibility.</p>
+
+ <!-- -->
+ <!-- Identity Mapper -->
+ <!-- -->
+
+<h4><a name="identity-mapper">identity</a></h4>
+<p>The target file name is identical to the source file name. Both
+<code>to</code> and <code>from</code> will be ignored.</p>
+<b>Examples:</b>
+<blockquote><pre>
+&lt;mapper type=&quot;identity&quot;/&gt;
+&lt;identitymapper/&gt;
+</pre></blockquote>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Source file name</b></td>
+ <td valign="top"><b>Target file name</b></td>
+ </tr>
+ <tr>
+ <td valign="top"><code>A.java</code></td>
+ <td valign="top"><code>A.java</code></td>
+ </tr>
+ <tr>
+ <td valign="top"><code>foo/bar/B.java</code></td>
+ <td valign="top"><code>foo/bar/B.java</code></td>
+ </tr>
+ <tr>
+ <td valign="top"><code>C.properties</code></td>
+ <td valign="top"><code>C.properties</code></td>
+ </tr>
+ <tr>
+ <td valign="top"><code>Classes/dir/dir2/A.properties</code></td>
+ <td valign="top"><code>Classes/dir/dir2/A.properties</code></td>
+ </tr>
+</table>
+
+ <!-- -->
+ <!-- Flatten Mapper -->
+ <!-- -->
+
+<h4><a name="flatten-mapper">flatten</a></h4>
+<p>The target file name is identical to the source file name, with all
+leading directory information stripped off. Both <code>to</code> and
+<code>from</code> will be ignored.</p>
+<b>Examples:</b>
+<blockquote><pre>
+&lt;mapper type=&quot;flatten&quot;/&gt;
+&lt;flattenmapper/&gt;
+</pre></blockquote>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Source file name</b></td>
+ <td valign="top"><b>Target file name</b></td>
+ </tr>
+ <tr>
+ <td valign="top"><code>A.java</code></td>
+ <td valign="top"><code>A.java</code></td>
+ </tr>
+ <tr>
+ <td valign="top"><code>foo/bar/B.java</code></td>
+ <td valign="top"><code>B.java</code></td>
+ </tr>
+ <tr>
+ <td valign="top"><code>C.properties</code></td>
+ <td valign="top"><code>C.properties</code></td>
+ </tr>
+ <tr>
+ <td valign="top"><code>Classes/dir/dir2/A.properties</code></td>
+ <td valign="top"><code>A.properties</code></td>
+ </tr>
+</table>
+
+ <!-- -->
+ <!-- Merge Mapper -->
+ <!-- -->
+
+<h4><a name="merge-mapper">merge</a></h4>
+<p>The target file name will always be the same, as defined by
+<code>to</code> - <code>from</code> will be ignored.</p>
+<h5>Examples:</h5>
+<blockquote><pre>
+&lt;mapper type=&quot;merge&quot; to=&quot;archive.tar&quot;/&gt;
+&lt;mergemapper to=&quot;archive.tar&quot;/&gt;
+</pre></blockquote>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Source file name</b></td>
+ <td valign="top"><b>Target file name</b></td>
+ </tr>
+ <tr>
+ <td valign="top"><code>A.java</code></td>
+ <td valign="top"><code>archive.tar</code></td>
+ </tr>
+ <tr>
+ <td valign="top"><code>foo/bar/B.java</code></td>
+ <td valign="top"><code>archive.tar</code></td>
+ </tr>
+ <tr>
+ <td valign="top"><code>C.properties</code></td>
+ <td valign="top"><code>archive.tar</code></td>
+ </tr>
+ <tr>
+ <td valign="top"><code>Classes/dir/dir2/A.properties</code></td>
+ <td valign="top"><code>archive.tar</code></td>
+ </tr>
+</table>
+
+ <!-- -->
+ <!-- Glob Mapper -->
+ <!-- -->
+
+<h4><a name="glob-mapper">glob</a></h4>
+<p>Both <code>to</code> and <code>from</code> are required and define patterns that may
+contain at most one <code>*</code>. For each source file that matches
+the <code>from</code> pattern, a target file name will be constructed
+from the <code>to</code> pattern by substituting the <code>*</code> in
+the <code>to</code> pattern with the text that matches the
+<code>*</code> in the <code>from</code> pattern. Source file names
+that don't match the <code>from</code> pattern will be ignored.</p>
+<b>Examples:</b>
+<blockquote><pre>
+&lt;mapper type=&quot;glob&quot; from=&quot;*.java&quot; to=&quot;*.java.bak&quot;/&gt;
+&lt;globmapper from=&quot;*.java&quot; to=&quot;*.java.bak&quot;/&gt;
+</pre></blockquote>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Source file name</b></td>
+ <td valign="top"><b>Target file name</b></td>
+ </tr>
+ <tr>
+ <td valign="top"><code>A.java</code></td>
+ <td valign="top"><code>A.java.bak</code></td>
+ </tr>
+ <tr>
+ <td valign="top"><code>foo/bar/B.java</code></td>
+ <td valign="top"><code>foo/bar/B.java.bak</code></td>
+ </tr>
+ <tr>
+ <td valign="top"><code>C.properties</code></td>
+ <td valign="top">ignored</td>
+ </tr>
+ <tr>
+ <td valign="top"><code>Classes/dir/dir2/A.properties</code></td>
+ <td valign="top">ignored</td>
+ </tr>
+</table>
+<blockquote><pre>
+&lt;mapper type=&quot;glob&quot; from=&quot;C*ies&quot; to=&quot;Q*y&quot;/&gt;
+&lt;globmapper from=&quot;C*ies&quot; to=&quot;Q*y&quot;/&gt;
+</pre></blockquote>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Source file name</b></td>
+ <td valign="top"><b>Target file name</b></td>
+ </tr>
+ <tr>
+ <td valign="top"><code>A.java</code></td>
+ <td valign="top">ignored</td>
+ </tr>
+ <tr>
+ <td valign="top"><code>foo/bar/B.java</code></td>
+ <td valign="top">ignored</td>
+ </tr>
+ <tr>
+ <td valign="top"><code>C.properties</code></td>
+ <td valign="top"><code>Q.property</code></td>
+ </tr>
+ <tr>
+ <td valign="top"><code>Classes/dir/dir2/A.properties</code></td>
+ <td valign="top"><code>Qlasses/dir/dir2/A.property</code></td>
+ </tr>
+</table>
+ <p>
+ The globmapper mapper can take the following extra attributes.
+ </p>
+ <table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">casesensitive</td>
+ <td valign="top">
+ If this is false, the mapper will ignore case when matching the glob pattern.
+ This attribute can be true or false, the default is true.
+ <em>Since Ant 1.6.3.</em>
+ </td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">handledirsep</td>
+ <td valign="top">
+ If this is specified, the mapper will ignore the difference between the normal
+ directory separator characters - \ and /.
+ This attribute can be true or false, the default is false.
+ This attribute is useful for cross-platform build files.
+ <em>Since Ant 1.6.3.</em>
+ <td align="center" valign="top">No</td>
+ </tr>
+ </table>
+ <p>
+ An example:
+ </p>
+ <pre>
+ &lt;pathconvert property="x" targetos="unix"&gt;
+ &lt;path path="Aj.Java"/&gt;
+ &lt;mapper&gt;
+ &lt;chainedmapper&gt;
+ &lt;flattenmapper/&gt;
+ &lt;globmapper from="a*.java" to="*.java.bak" casesensitive="no"/&gt;
+ &lt;/chainedmapper&gt;
+ &lt;/mapper&gt;
+ &lt;/pathconvert&gt;
+ &lt;echo&gt;x is ${x}&lt;/echo&gt;
+ </pre>
+ <p>
+ will output "x is j.java.bak".
+ </p>
+ <p>
+ and
+ </p>
+ <pre>
+ &lt;pathconvert property="x" targetos="unix"&gt;
+ &lt;path path="d/e/f/j.java"/&gt;
+ &lt;mapper&gt;
+ &lt;globmapper from="${basedir}\d/e\*" to="*" handledirsep="yes"/&gt;
+ &lt;/mapper&gt;
+ &lt;/pathconvert&gt;
+ &lt;echo&gt;x is ${x}&lt;/echo&gt;
+ </pre>
+ <p>
+ will output "x is f/j.java".
+ </p>
+
+
+ <!-- -->
+ <!-- RegExp Mapper -->
+ <!-- -->
+
+<h4><a name="regexp-mapper">regexp</a></h4>
+
+<p>Both <code>to</code> and <code>from</code> are required and define
+regular expressions. If the source file name (as a whole or in part)
+matches the <code>from</code> pattern, the target file name will be
+constructed from the
+<code>to</code> pattern, using <code>\0</code> to <code>\9</code> as
+back-references for the full match (<code>\0</code>) or the matches of
+the subexpressions in parentheses. The <code>to</code> pattern
+determines the <strong>whole</strong> file name, so if you wanted to
+replace the extension of a file you should not use <code>from="\.old$"
+to=".new"</code> but rather <code>from="(.*)\.old$" to="\1.new"</code>
+(or rather use a glob mapper in this case).</p>
+
+<p>Source files not matching the <code>from</code> pattern will be
+ignored.</p>
+
+<p>Note that you need to escape a dollar-sign (<code>$</code>) with
+another dollar-sign in Ant.</p>
+
+<p>The regexp mapper needs a supporting library and an implementation
+of <code>org.apache.tools.ant.util.regexp.RegexpMatcher</code> that
+ hides the specifics of the library. <em>Since Ant 1.8.0</em> Ant
+ requires Java 1.4 to run, so the implementation based on
+ the <code>java.util.regex</code> package will always be available.
+ You can still use the now retired Jakarta ORO or Jakarta Regex instead if your
+ provide the corresponding jar in your CLASSPATH.</p>
+
+<p>For information about using <a
+href="http://www.cacas.org/~wes/java/" target="_top">gnu.regexp</a> or <a
+href="http://www.crocodile.org/~sts/Rex/" target="_top">gnu.rex</a> with Ant, see <a
+href="http://marc.theaimsgroup.com/?l=ant-dev&m=97550753813481&w=2" target="_top">this</a>
+article.</p>
+
+<p>If you want to use one of the regular expression
+ libraries other than <code>java.util.regex</code> you need to also use
+ the corresponding <code>ant-[apache-oro, apache-regexp].jar</code>
+from the Ant release you are using.
+Make sure, both will be loaded from the same
+classpath, that is either put them into your <code>CLASSPATH</code>,
+<code>ANT_HOME/lib</code> directory or a nested
+<code>&lt;classpath&gt;</code> element of the mapper - you cannot have
+<code>ant-[apache-oro, apache-regexp].jar</code> in <code>ANT_HOME/lib</code>
+ and the library
+in a nested <code>&lt;classpath&gt;</code>.</p>
+<p>Ant will choose the regular-expression library based on the
+following algorithm:</p>
+<ul>
+<li>If the system property
+<code>ant.regexp.matcherimpl</code> has been set, it is taken as the
+name of the class implementing
+<code>org.apache.tools.ant.util.regexp.RegexpMatcher</code> that
+should be used.</li>
+<li>If it has not been set, uses the JDK 1.4 classes.</li>
+</ul>
+
+<b>Examples:</b>
+<blockquote><pre>
+&lt;mapper type=&quot;regexp&quot; from=&quot;^(.*)\.java$$&quot; to=&quot;\1.java.bak&quot;/&gt;
+&lt;regexpmapper from=&quot;^(.*)\.java$$&quot; to=&quot;\1.java.bak&quot;/&gt;
+</pre></blockquote>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Source file name</b></td>
+ <td valign="top"><b>Target file name</b></td>
+ </tr>
+ <tr>
+ <td valign="top"><code>A.java</code></td>
+ <td valign="top"><code>A.java.bak</code></td>
+ </tr>
+ <tr>
+ <td valign="top"><code>foo/bar/B.java</code></td>
+ <td valign="top"><code>foo/bar/B.java.bak</code></td>
+ </tr>
+ <tr>
+ <td valign="top"><code>C.properties</code></td>
+ <td valign="top">ignored</td>
+ </tr>
+ <tr>
+ <td valign="top"><code>Classes/dir/dir2/A.properties</code></td>
+ <td valign="top">ignored</td>
+ </tr>
+</table>
+<blockquote><pre>
+&lt;mapper type=&quot;regexp&quot; from=&quot;^(.*)/([^/]+)/([^/]*)$$&quot; to=&quot;\1/\2/\2-\3&quot;/&gt;
+&lt;regexpmapper from=&quot;^(.*)/([^/]+)/([^/]*)$$&quot; to=&quot;\1/\2/\2-\3&quot;/&gt;
+</pre></blockquote>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Source file name</b></td>
+ <td valign="top"><b>Target file name</b></td>
+ </tr>
+ <tr>
+ <td valign="top"><code>A.java</code></td>
+ <td valign="top">ignored</td>
+ </tr>
+ <tr>
+ <td valign="top"><code>foo/bar/B.java</code></td>
+ <td valign="top"><code>foo/bar/bar-B.java</code></td>
+ </tr>
+ <tr>
+ <td valign="top"><code>C.properties</code></td>
+ <td valign="top">ignored</td>
+ </tr>
+ <tr>
+ <td valign="top"><code>Classes/dir/dir2/A.properties</code></td>
+ <td valign="top"><code>Classes/dir/dir2/dir2-A.properties</code></td>
+ </tr>
+</table>
+<blockquote><pre>
+&lt;mapper type="regexp" from="^(.*)\.(.*)$$" to="\2.\1"/&gt;
+&lt;regexpmapper from="^(.*)\.(.*)$$" to="\2.\1"/&gt;
+</pre></blockquote>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Source file name</b></td>
+ <td valign="top"><b>Target file name</b></td>
+ </tr>
+ <tr>
+ <td valign="top"><code>A.java</code></td>
+ <td valign="top"><code>java.A</code></td>
+ </tr>
+ <tr>
+ <td valign="top"><code>foo/bar/B.java</code></td>
+ <td valign="top"><code>java.foo/bar/B</code></td>
+ </tr>
+ <tr>
+ <td valign="top"><code>C.properties</code></td>
+ <td valign="top"><code>properties.C</code></td>
+ </tr>
+ <tr>
+ <td valign="top"><code>Classes/dir/dir2/A.properties</code></td>
+ <td valign="top"><code>properties.Classes/dir/dir2/A</code></td>
+ </tr>
+</table>
+<blockquote><pre>
+&lt;mapper type="regexp" from="^(.*?)(\$$[^/\\\.]*)?\.class$$" to="\1.java"/&gt;
+&lt;regexpmapper from="^(.*?)(\$$[^/\\\.]*)?\.class$$" to="\1.java"/&gt;
+</pre></blockquote>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Source file name</b></td>
+ <td valign="top"><b>Target file name</b></td>
+ </tr>
+ <tr>
+ <td valign="top"><code>ClassLoader.class</code></td>
+ <td valign="top"><code>ClassLoader.java</code></td>
+ </tr>
+ <tr>
+ <td valign="top"><code>java/lang/ClassLoader.class</code></td>
+ <td valign="top"><code>java/lang/ClassLoader.java</code></td>
+ </tr>
+ <tr>
+ <td valign="top"><code>java\lang\ClassLoader$1.class</code></td>
+ <td valign="top"><code>java\lang\ClassLoader.java</code></td>
+ </tr>
+ <tr>
+ <td valign="top"><code>java/lang/ClassLoader$foo$1.class</code></td>
+ <td valign="top"><code>java/lang/ClassLoader.java</code></td>
+ </tr>
+</table>
+ <p>
+ The regexpmapper mapper can take the following extra attributes.
+ </p>
+ <table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">casesensitive</td>
+ <td valign="top">
+ If this is false, the mapper will ignore case when matching the pattern.
+ This attribute can be true or false, the default is true.
+ <em>Since Ant 1.6.3.</em>
+ </td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">handledirsep</td>
+ <td valign="top">
+ If this is specified, the mapper will treat a \ character in a filename
+ as a / for the purposes of matching.
+ This attribute can be true or false, the default is false.
+ This attribute is useful for cross-platform build files.
+ <em>Since Ant 1.6.3.</em>
+ <td align="center" valign="top">No</td>
+ </tr>
+ </table>
+ <p>
+ An example:
+ </p>
+ <pre>
+ &lt;pathconvert property="x" targetos="unix"&gt;
+ &lt;path path="Aj.Java"/&gt;
+ &lt;chainedmapper&gt;
+ &lt;flattenmapper/&gt;
+ &lt;regexpmapper from="a(.*)\.java" to="\1.java.bak" casesensitive="no"/&gt;
+ &lt;/chainedmapper&gt;
+ &lt;/pathconvert&gt;
+ &lt;echo&gt;x is ${x}&lt;/echo&gt;
+ </pre>
+ <p>
+ will output "x is j.java.bak".
+ </p>
+ <p>
+ and
+ </p>
+ <pre>
+ &lt;pathconvert property="hd.prop" targetos="windows"&gt;
+ &lt;path path="d\e/f\j.java"/&gt;
+ &lt;chainedmapper&gt;
+ &lt;regexpmapper from="${basedir}/d/e/(.*)" to="\1" handledirsep="yes"/&gt;
+ &lt;/chainedmapper&gt;
+ &lt;/pathconvert&gt;
+ </pre>
+ <p>
+ will set <code>hd.prop</code> to "f\j.java".
+ </p>
+
+ <!-- -->
+ <!-- Package Mapper -->
+ <!-- -->
+
+<h4><a name="package-mapper">package</a></h4>
+<p>Sharing the same syntax as the <a href="#glob-mapper">glob mapper</a>,
+the package mapper replaces
+directory separators found in the matched source pattern with dots in the target
+pattern placeholder. This mapper is particularly useful in combination
+with <code>&lt;uptodate&gt;</code> and <code>&lt;junit&gt;</code> output.</p>
+<p>The to and from attributes are both required.</p>
+<b>Example:</b>
+<blockquote><pre>
+&lt;mapper type="package" from="*Test.java" to="TEST-*Test.xml"/&gt;
+&lt;packagemapper from="*Test.java" to="TEST-*Test.xml"/&gt;
+</pre></blockquote>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Source file name</b></td>
+ <td valign="top"><b>Target file name</b></td>
+ </tr>
+ <tr>
+ <td valign="top"><code>org/apache/tools/ant/util/PackageMapperTest.java</code></td>
+ <td valign="top"><code>TEST-org.apache.tools.ant.util.PackageMapperTest.xml</code></td>
+ </tr>
+ <tr>
+ <td valign="top"><code>org/apache/tools/ant/util/Helper.java</code></td>
+ <td valign="top">ignored</td>
+ </tr>
+</table>
+
+ <!-- -->
+ <!-- Unpackage Mapper -->
+ <!-- -->
+
+<h4><a name="unpackage-mapper">unpackage (since Ant 1.6.0)</a></h4>
+ <p>This mapper is the inverse of the <a href="#package-mapper">package</a> mapper.
+ It replaces the dots in a package name with directory separators. This
+ is useful for matching XML formatter results against their JUnit test
+ test cases. The mapper shares the sample syntax
+ as the <a href="#glob-mapper">glob mapper</a>.
+ </p>
+<p>The to and from attributes are both required.</p>
+<b>Example:</b>
+<blockquote><pre>
+&lt;mapper type="unpackage" from="TEST-*Test.xml" to="${test.src.dir}/*Test.java"&gt;
+&lt;unpackagemapper from="TEST-*Test.xml" to="${test.src.dir}/*Test.java"&gt;
+</pre></blockquote>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Source file name</b></td>
+ <td valign="top"><b>Target file name</b></td>
+ </tr>
+ <tr>
+ <td valign="top"><code>TEST-org.acme.AcmeTest.xml</code></td>
+ <td valign="top"><code>${test.src.dir}/org/acme/AcmeTest.java</code></td>
+ </tr>
+</table>
+
+ <!-- -->
+ <!-- Composite Mapper -->
+ <!-- -->
+
+<h4><a name="composite-mapper">composite (since Ant 1.7.0)</a></h4>
+ <p>This mapper implementation can contain multiple nested mappers.
+ File mapping is performed by passing the source filename to each nested
+ <code>&lt;mapper&gt;</code> in turn, returning all results.
+ The <i>to</i> and <i>from</i> attributes are ignored.</p>
+ <p>Starting with Ant 1.8.0 the order of the mapped results is the
+ same as the order of the nested mappers; prior to Ant 1.8.0 the
+ order has been undefined.</p>
+<b>Examples:</b>
+<blockquote><pre>
+&lt;compositemapper&gt;
+ &lt;identitymapper/&gt;
+ &lt;packagemapper from="*.java" to="*"/&gt;
+&lt;/compositemapper&gt;
+</pre></blockquote>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Source file name</b></td>
+ <td valign="top"><b>Target file names</b></td>
+ </tr>
+ <tr>
+ <td valign="center" rowspan="2"><code>foo/bar/A.java</code></td>
+ <td valign="top"><code>foo/bar/A.java</code></td>
+ </tr>
+ <tr>
+ <td valign="top"><code>foo.bar.A</code></td>
+ </tr>
+</table>
+ <p>The composite mapper has no corresponding
+ <code>&lt;mapper <b>type</b>&gt;</code> attribute.
+ </p>
+
+ <!-- -->
+ <!-- Chained Mapper -->
+ <!-- -->
+
+<h4><a name="chained-mapper">chained (since Ant 1.7.0)</a></h4>
+ <p>This mapper implementation can contain multiple nested mappers.
+ File mapping is performed by passing the source filename to the first
+ nested mapper, its results to the second, and so on. The target filenames
+ generated by the last nested mapper comprise the ultimate results of the
+ mapping operation. The <i>to</i> and <i>from</i> attributes are ignored.</p>
+<b>Examples:</b>
+<blockquote><pre>
+&lt;chainedmapper&gt;
+ &lt;flattenmapper/&gt;
+ &lt;globmapper from="*" to="new/path/*"/&gt;
+ &lt;mapper&gt;
+ &lt;globmapper from="*" to="*1"/&gt;
+ &lt;globmapper from="*" to="*2"/&gt;
+ &lt;/mapper&gt;
+&lt;/chainedmapper&gt;
+</pre></blockquote>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Source file name</b></td>
+ <td valign="top"><b>Target file names</b></td>
+ </tr>
+ <tr>
+ <td valign="center" rowspan="2"><code>foo/bar/A.java</code></td>
+ <td valign="top"><code>new/path/A.java1</code></td>
+ </tr>
+ <tr>
+ <td valign="top"><code>new/path/A.java2</code></td>
+ </tr>
+ <tr>
+ <td valign="center" rowspan="2"><code>boo/far/B.java</code></td>
+ <td valign="top"><code>new/path/B.java1</code></td>
+ </tr>
+ <tr>
+ <td valign="top"><code>new/path/B.java2</code></td>
+ </tr>
+</table>
+ <p>The chained mapper has no corresponding
+ <code>&lt;mapper <b>type</b>&gt;</code> attribute.
+ </p>
+
+ <!-- -->
+ <!-- Filter Mapper -->
+ <!-- -->
+
+<h4><a name="filter-mapper">filtermapper (since Ant 1.6.3)</a></h4>
+ <p>
+ This mapper implementation applies a <a href="filterchain.html">filterchain</a>
+ to the source file name.
+ </p>
+<b>Examples:</b>
+<blockquote><pre>
+&lt;filtermapper&gt;
+ &lt;replacestring from="\" to="/"/&gt;
+&lt;/filtermapper&gt;
+</pre></blockquote>
+
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Source file name</b></td>
+ <td valign="top"><b>Target file names</b></td>
+ </tr>
+ <tr>
+ <td valign="center"><code>foo\bar\A.java</code></td>
+ <td valign="top"><code>foo/bar/A.java</code></td>
+ </tr>
+</table>
+<blockquote><pre>
+&lt;filtermapper&gt;
+ &lt;scriptfilter language="beanshell"&gt;
+ self.setToken(self.getToken().toUpperCase());
+ &lt;/scriptfilter&gt;
+&lt;/filtermapper&gt;
+</pre></blockquote>
+
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Source file name</b></td>
+ <td valign="top"><b>Target file names</b></td>
+ </tr>
+ <tr>
+ <td valign="center"><code>foo\bar\A.java</code></td>
+ <td valign="top"><code>FOO\BAR\A.JAVA</code></td>
+ </tr>
+</table>
+
+ <p>The filtermapper has no corresponding
+ <code>&lt;mapper <b>type</b>&gt;</code> attribute.
+ </p>
+
+ <!-- -->
+ <!-- Script Mapper -->
+ <!-- -->
+
+<h4><a name="script-mapper">scriptmapper (since Ant 1.7)</a></h4>
+<p>
+This mapper executes a script written in <a href="http://jakarta.apache.org/bsf" target="_top">Apache BSF</a>
+or
+ <a href="https://scripting.dev.java.net">JSR 223</a>
+supported language, once per file to map.</p>
+The script can be declared inline or in a specified file.
+</p>
+<p>
+See the <a href="../Tasks/script.html">Script</a> task for
+an explanation of scripts and dependencies.
+</p>
+
+ <table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">language</td>
+ <td valign="top">
+ Scripting language
+ </td>
+ <td align="center" valign="top">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">manager</td>
+ <td valign="top">
+ The script engine manager to use.
+ See the <a href="../Tasks/script.html">script</a> task
+ for using this attribute.
+ </td>
+ <td valign="top" align="center">No - default is "auto"</td>
+ </tr>
+ <tr>
+ <td valign="top">src</td>
+ <td valign="top">
+ File containing the script
+ </td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">setbeans</td>
+ <td valign="top">whether to have all properties, references and targets as
+ global variables in the script. <em>since Ant 1.8.0</em></td>
+ <td valign="top" align="center">No, default is "true".</td>
+ </tr>
+ <tr>
+ <td valign="top">classpath</td>
+ <td valign="top">
+ The classpath to pass into the script.
+ </td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">classpathref</td>
+ <td valign="top">The classpath to use, given as a
+ <a href="../using.html#references">reference</a> to a path defined elsewhere.
+ <td align="center" valign="top">No</td>
+ </tr>
+ </table>
+ <p>
+ This filename mapper can take a nested &lt;classpath&gt; element.
+ See the <a href="../Tasks/script.html">script</a> task
+ on how to use this element.
+ </p>
+
+<p>
+ <b>Example:</b>
+</p>
+<blockquote><pre>
+&lt;scriptmapper language="javascript"&gt;
+ self.addMappedName(source.toUpperCase());
+ self.addMappedName(source.toLowerCase());
+&lt;/scriptmapper&gt;
+</pre></blockquote>
+
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Source file name</b></td>
+ <td valign="top"><b>Target file names</b></td>
+ </tr>
+ <tr>
+ <td valign="center" rowspan="2"><code>foo\bar\A.java</code></td>
+ <td valign="top"><code>FOO\BAR\A.JAVA</code></td>
+ </tr>
+ <tr>
+ <td valign="top"><code>foo\bar\a.java</code></td>
+ </tr>
+</table>
+
+<p>
+To use this mapper, the scripts need access to the source file,
+and the ability to return multiple mappings. Here are the relevant beans and
+their methods. The script is called once for every source file, with the
+list of mapped names reset after every invocation.
+
+ <table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Script bean</b></td>
+ <td valign="top"><b>Description</b></td>
+ </tr>
+ <tr>
+ <td valign="top"><code>source: String</code></td>
+ <td valign="top">
+ The file/path to map
+ </td>
+ </tr>
+ <tr>
+ <td valign="top"><code>self</code></td>
+ <td valign="top">
+ the scriptmapper itself
+ </td>
+ </tr>
+ <tr>
+ <td valign="top"><code>self.addMappedName(String name)</code></td>
+ <td valign="top">
+ Add a new mapping
+ </td>
+ </tr>
+ <tr>
+ <td valign="top"><code>self.clear()</code></td>
+ <td valign="top">
+ Reset the list of files.
+ </td>
+ </tr>
+ </table>
+
+ <p>The scriptmapper has no corresponding
+ <code>&lt;mapper <b>type</b>&gt;</code> attribute.
+ </p>
+
+<h4><a name="firstmatch-mapper">firstmatchmapper (since Ant 1.8.0)</a></h4>
+ <p>
+ This mapper supports an arbitrary number of nested mappers and
+ returns the results of the first mapper that matches. This is
+ different from <a href="#composite-mapper">composite mapper</a>
+ which collects the results of all matching children.</p>
+<b>Examples:</b>
+<blockquote><pre>
+&lt;firstmatchmapper&gt;
+ &lt;globmapper from="*.txt" to="*.bak"/&gt;
+ &lt;globmapper from="*A.*" to="*B.*"/&gt;
+&lt;/firstmatchmapper&gt;
+</pre></blockquote>
+
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Source file name</b></td>
+ <td valign="top"><b>Target file names</b></td>
+ </tr>
+ <tr>
+ <td valign="center"><code>foo/bar/A.txt</code></td>
+ <td valign="top"><code>foo/bar/A.bak</code></td>
+ </tr>
+ <tr>
+ <td valign="center"><code>foo/bar/A.java</code></td>
+ <td valign="top"><code>foo/bar/B.java</code></td>
+ </tr>
+</table>
+
+ <p>The firstmatchmapper has no corresponding
+ <code>&lt;mapper <b>type</b>&gt;</code> attribute.
+ </p>
+
+<h4><a name="cutdirs-mapper">cutdirsmapper (since Ant 1.8.2)</a></h4>
+
+<p>This mapper strips a configured number of leading directories from
+ the source file name.</p>
+
+<b>Examples:</b>
+<blockquote><pre>
+&lt;cutdirsmapper dirs="1"/&gt;
+</pre></blockquote>
+
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Source file name</b></td>
+ <td valign="top"><b>Target file names</b></td>
+ </tr>
+ <tr>
+ <td valign="center"><code>foo/bar/A.txt</code></td>
+ <td valign="top"><code>bar/A.txt</code></td>
+ </tr>
+</table>
+
+<p>The cutdirsmapper has no
+corresponding <code>&lt;mapper <b>type</b>&gt;</code> attribute.</p>
+
+ <table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">dirs</td>
+ <td valign="top">
+ Number of directories to strip (must be a positive number).
+ </td>
+ <td align="center" valign="top">Yes</td>
+ </tr>
+ </table>
+
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Types/multirootfileset.html b/framework/src/ant/apache-ant-1.9.6/manual/Types/multirootfileset.html
new file mode 100644
index 00000000..29a4f548
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Types/multirootfileset.html
@@ -0,0 +1,173 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>MultiRootFileSet Type</title>
+</head>
+
+<body>
+
+<h2><a name="multirootfileset">MultiRootFileSet</a></h2>
+
+<p><em>Since Ant 1.9.4</em></p>
+
+<p>A MultiRootFileSet is a group of files or directories. These files
+or directories can be found in a directory forrest starting with a set
+of base directories and are matched by patterns taken from a number of
+<a href="patternset.html">PatternSets</a> and <a
+href="selectors.html">Selectors</a>.</p>
+
+<p>MultiRootFileSet acts as a union of <a
+href="fileset.html">FileSets</a> and <a href="dirset.html">DirSets</a>
+that share the same patterns and selectors.</p>
+
+<p>MultiRootFileSet supports all attributes and nested elements of
+FileSet and DirSet except for the "dir" attribute.</p>
+
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">basedirs</td>
+ <td valign="top">Comma separated list of directories that build
+ the roots of the MultiRootFileSet.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">cache</td>
+ <td valign="top">Whether to cache results; disabling
+ may seriously impact performance</td>
+ <td valign="top" align="center">No, default <i>true</i></td>
+ </tr>
+ <tr>
+ <td valign="top">type</td>
+ <td valign="top">The type of file system entities which will be
+ included in this set.
+ Acceptable values are:
+ <ul>
+ <li>file - regular files</li>
+ <li>dir - directories</li>
+ <li>both - regular files and directories</li>
+ </ul>
+ </td>
+ <td valign="top" align="center">No, defaults to <i>file</i></td>
+ </tr>
+ <tr>
+ <td valign="top">includes</td>
+ <td valign="top">A comma- or space-separated list of patterns of directories that
+ must be included; all directories are included when omitted.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">includesfile</td>
+ <td valign="top">The name of a file; each line of this file is
+ taken to be an include pattern.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">excludes</td>
+ <td valign="top">A comma- or space-separated list of patterns of directories that
+ must be excluded; no directories are excluded when omitted.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">excludesfile</td>
+ <td valign="top">The name of a file; each line of this file is
+ taken to be an exclude pattern.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">casesensitive</td>
+ <td valign="top">Specifies whether case-sensitivity should be applied
+ (<code>true</code>|<code>yes</code>|<code>on</code> or
+ <code>false</code>|<code>no</code>|<code>off</code>).</td>
+ <td valign="top" align="center">No; defaults to true.</td>
+ </tr>
+ <tr>
+ <td valign="top">followsymlinks</td>
+ <td valign="top">Shall symbolic links be followed? Defaults to
+ true. See <a href="fileset.html#symlink">fileset's documentation</a>.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">erroronmissingdir</td>
+ <td valign="top">
+ Specify what happens if one of the base directories does not exist.
+ If true a build error will happen, if false, the subtree
+ will be ignored/empty.
+ Defaults to true.
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+</table>
+
+<h3>Parameters specified as nested elements</h3>
+
+<p>PatternSets can be specified as nested
+<code>&lt;patternset&gt;</code> elements. In addition, MultiRootFileSet holds
+an implicit PatternSet and supports the nested
+<code>&lt;include&gt;</code>, <code>&lt;includesfile&gt;</code>,
+<code>&lt;exclude&gt;</code> and <code>&lt;excludesfile&gt;</code>
+elements of <code>&lt;patternset&gt;</code> directly, as well as
+<code>&lt;patternset&gt;</code>'s attributes.</p>
+
+<p>Selectors are available as nested elements within the
+MultiRootFileSet. If any of the selectors within the MultiRootFileSet
+do not select the file or directory, it is not considered part of the
+MultiRootFileSet. This makes a MultiRootFileSet equivalent to
+an <code>&lt;and&gt;</code> selector container.</p>
+
+<p>In addition basedirs for the MultiRootFileSet can be specified as
+ nested <code>basedir</code> elements that have a
+ single <code>file</code> attribute.</p>
+
+
+<h4>Examples</h4>
+
+<blockquote><pre>
+&lt;multirootfileset basedirs=&quot;${build.dir},${other.project.dir}&quot;&gt;
+ &lt;include name=&quot;apps/**/classes&quot;/&gt;
+ &lt;exclude name=&quot;apps/**/*Test*&quot;/&gt;
+&lt;/multirootfileset&gt;
+</pre></blockquote>
+<p>Groups all files inside <code>classes</code> found under the
+<code>apps</code> subdirectory of <code>${build.dir}</code> or
+<code>${other.project.dir}</code>, except those that have the text
+<code>Test</code> in their name.</p>
+
+<blockquote><pre>
+&lt;multirootfileset&gt;
+ &lt;basedir file=&quot;${build.dir}&quot;/&gt;
+ &lt;basedir file=&quot;${other.project.dir}&quot;
+ &lt;include name=&quot;apps/**/classes&quot;/&gt;
+ &lt;exclude name=&quot;apps/**/*Test*&quot;/&gt;
+&lt;/multirootfileset&gt;
+</pre></blockquote>
+<p>Is equivalent to the first example but used
+ nested <code>basedir</code> elements. The nested elements and
+ the <code>basedirs</code> attribute can be used at the same time and
+ the will be merged.</p>
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Types/namespace.html b/framework/src/ant/apache-ant-1.9.6/manual/Types/namespace.html
new file mode 100644
index 00000000..3adfa80c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Types/namespace.html
@@ -0,0 +1,224 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html><head><link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>XmlNamespaceSupport</title></head>
+ <body>
+ <h2><a name="namespace">XML Namespace Support</a></h2>
+ Apache Ant 1.6 introduces support for XML namespaces.
+ <h3>History</h3>
+
+ <p>
+ All releases of Ant prior to Ant 1.6 do not support XML namespaces.
+ No support basically implies two things here:
+ </p>
+ <ul>
+ <li> Element names correspond to the "qname" of the tags, which is
+ usually the same as the local name. But if the build file writer uses
+ colons in names of defined tasks/types, those become part of the
+ element name. Turning on namespace support gives colon-separated
+ prefixes in tag names a special meaning, and thus build files using
+ colons in user-defined tasks and types will break.
+ </li>
+ <li> Attributes with the names 'xmlns' and 'xmlns:<code>&lt;prefix&gt;</code>'
+ are not treated specially, which means that custom tasks and types have
+ actually been able to use such attributes as parameter names. Again,
+ such tasks/types are going to break when namespace support is enabled
+ on the parser.
+ </li>
+ </ul>
+ <p>Use of colons in element names has been discouraged in the past,
+ and using any attribute starting with "xml" is actually strongly
+ discouraged by the XML spec to reserve such names for future use.
+ </p>
+ <h3>Motivation</h3>
+
+ <p>In build files using a lot of custom and third-party tasks, it is
+ easy to get into name conflicts. When individual types are defined, the
+ build file writer can do some namespacing manually (for example, using
+ "tomcat-deploy" instead of just "deploy"). But when defining whole
+ libraries of types using the <code>&lt;typedef&gt;</code> 'resource' attribute, the
+ build file writer has no chance to override or even prefix the names
+ supplied by the library. </p>
+ <h3>Assigning Namespaces</h3>
+
+ <p>
+ Adding a 'prefix' attribute to <code>&lt;typedef&gt;</code> might have been enough,
+ but XML already has a well-known method for namespacing. Thus, instead
+ of adding a 'prefix' attribute, the <code>&lt;typedef&gt;</code> and <code>&lt;taskdef&gt;</code>
+ tasks get a 'uri' attribute, which stores the URI of the XML namespace
+ with which the type should be associated:
+ </p><pre> &lt;typedef resource="org/example/tasks.properties" uri="<a href="http://example.org/tasks">http://example.org/tasks</a>"/&gt;
+ &lt;my:task xmlns:my="<a href="http://example.org/tasks">http://example.org/tasks</a>"&gt;
+ ...
+ &lt;/my:task&gt;
+</pre>
+ <p>As the above example demonstrates, the namespace URI needs to be
+ specified at least twice: one time as the value of the 'uri' attribute,
+ and another time to actually map the namespace to occurrences of
+ elements from that namespace, by using the 'xmlns' attribute. This
+ mapping can happen at any level in the build file:
+ </p><pre> &lt;project name="test" xmlns:my="<a href="http://example.org/tasks">http://example.org/tasks</a>"&gt;
+ &lt;typedef resource="org/example/tasks.properties" uri="<a href="http://example.org/tasks">http://example.org/tasks</a>"/&gt;
+ &lt;my:task&gt;
+ ...
+ &lt;/my:task&gt;
+ &lt;/project&gt;
+</pre>
+ <p>
+ Use of a namespace prefix is of course optional. Therefore
+ the example could also look like this:
+ </p><pre> &lt;project name="test"&gt;
+ &lt;typedef resource="org/example/tasks.properties" uri="<a href="http://example.org/tasks">http://example.org/tasks</a>"/&gt;
+ &lt;task xmlns="<a href="http://example.org/tasks">http://example.org/tasks</a>"&gt;
+ ...
+ &lt;/task&gt;
+ &lt;/project&gt;
+</pre>
+ <p>
+ Here, the namespace is set as the default namespace for the <code>&lt;task&gt;</code>
+ element and all its descendants.
+ </p>
+ <h3>Default namespace</h3>
+ <p>
+ The default namespace used by Ant is "antlib:org.apache.tools.ant".
+ </p>
+ <pre>
+&lt;typedef resource="org/example/tasks.properties" uri="antlib:org.apache.tools.ant"/&gt;
+&lt;task&gt;
+ ....
+&lt;/task&gt;
+ </pre>
+
+
+
+ <h3>Namespaces and Nested Elements</h3>
+
+ <p>
+ Almost always in Ant 1.6, elements nested inside a namespaced
+ element have the same namespace as their parent. So if 'task' in the
+ example above allowed a nested 'config' element, the build file snippet
+ would look like this:
+ </p><pre> &lt;typedef resource="org/example/tasks.properties" uri="<a href="http://example.org/tasks">http://example.org/tasks</a>"/&gt;
+ &lt;my:task xmlns:my="<a href="http://example.org/tasks">http://example.org/tasks</a>"&gt;
+ &lt;my:config a="foo" b="bar"/&gt;
+ ...
+ &lt;/my:task&gt;
+</pre>
+ <p>If the element allows or requires a lot of nested elements, the
+ prefix needs to be used for every nested element. Making the namespace
+ the default can reduce the verbosity of the script:
+ </p><pre> &lt;typedef resource="org/example/tasks.properties" uri="<a href="http://example.org/tasks">http://example.org/tasks</a>"/&gt;
+ &lt;task xmlns="<a href="http://example.org/tasks">http://example.org/tasks</a>"&gt;
+ &lt;config a="foo" b="bar"/&gt;
+ ...
+ &lt;/task&gt;
+ </pre>
+ <p>
+ From Ant 1.6.2, elements nested inside a namespaced element may also be
+ in Ant's default namespace. This means that the following is now allowed:
+ </p>
+ </p><pre> &lt;typedef resource="org/example/tasks.properties"
+ uri="<a href="http://example.org/tasks">http://example.org/tasks</a>"/&gt;
+ &lt;my:task xmlns:my="<a href="http://example.org/tasks">http://example.org/tasks</a>"&gt;
+ &lt;config a="foo" b="bar"/&gt;
+ ...
+ &lt;/my:task&gt;
+</pre>
+
+ <h3>Namespaces and Attributes</h3>
+
+ <p>
+ Attributes are only used to configure the element they belong to if:
+ </p>
+ <ul>
+ <li> they have no namespace (note that the default namespace does *not* apply to attributes)
+ </li>
+ <li> they are in the same namespace as the element they belong to
+ </li>
+ </ul>
+ <p>
+ In Ant 1.9.1 two attribute namespaces <code>ant:if</code> and <code>ant:unless</code> were added
+ to allow you to insert elements conditionally.
+ </p>
+ <p>
+ Other attributes are simply ignored.
+ </p>
+ <p>
+ This means that both:
+ </p>
+ <p>
+ </p><pre> &lt;my:task xmlns:my="<a href="http://example.org/tasks">http://example.org/tasks</a>"&gt;
+ &lt;my:config a="foo" b="bar"/&gt;
+ ...
+ &lt;/my:task&gt;
+</pre>
+ <p>
+ and
+ </p>
+ <pre> &lt;my:task xmlns:my="<a href="http://example.org/tasks">http://example.org/tasks</a>"&gt;
+ &lt;my:config my:a="foo" my:b="bar"/&gt;
+ ...
+ &lt;/my:task&gt;
+</pre>
+ <p>
+ result in the parameters "a" and "b" being used as parameters to configure the nested "config" element.
+ </p>
+ <p>It also means that you can use attributes from other namespaces
+ to markup the build file with extra metadata, such as RDF and
+ XML-Schema (whether that's a good thing or not). The same is not true
+ for elements from unknown namespaces, which result in a error.
+ </p>
+ <h3>Mixing Elements from Different Namespaces</h3>
+
+ <p>Now comes the difficult part: elements from different namespaces can
+ be woven together under certain circumstances. This has a lot to do
+ with the Ant 1.6
+ <a href="../develop.html#nestedtype">add type introspection rules</a>:
+ Ant types and tasks are now free to accept arbitrary named types as
+ nested elements, as long as the concrete type implements the interface
+ expected by the task/type. The most obvious example for this is the
+ <code>&lt;condition&gt;</code> task, which supports various nested conditions, all
+ of which extend the interface <tt>Condition</tt>. To integrate a
+ custom condition in Ant, you can now simply <code>&lt;typedef&gt;</code> the
+ condition, and then use it anywhere nested conditions are allowed
+ (assuming the containing element has a generic <tt>add(Condition)</tt> or <tt>addConfigured(Condition)</tt> method):
+</p><pre> &lt;typedef resource="org/example/conditions.properties" uri="<a href="http://example.org/conditions">http://example.org/conditions</a>"/&gt;
+ &lt;condition property="prop" xmlns="<a href="http://example.org/conditions">http://example.org/conditions</a>"&gt;
+ &lt;and&gt;
+ &lt;available file="bla.txt"/&gt;
+ &lt;my:condition a="foo"/&gt;
+ &lt;/and&gt;
+ &lt;/condition&gt;
+</pre>
+ <p>
+ In Ant 1.6, this feature cannot be used as much as we'd all like to: a
+ lot of code has not yet been adapted to the new introspection rules,
+ and elements like Ant's built-in conditions and selectors are not
+ really types in 1.6. This is expected to change in Ant 1.7.
+ </p>
+ <h3>Namespaces and Antlib</h3>
+
+ <p>
+ The new <a href="antlib.html">AntLib</a>
+ feature is also very much integrated with the namespace support in Ant
+ 1.6. Basically, you can "import" Antlibs simply by using a special
+ scheme for the namespace URI: the <tt>antlib</tt> scheme, which expects the package name in which a special <tt>antlib.xml</tt> file is located.
+ </p>
+
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Types/patternset.html b/framework/src/ant/apache-ant-1.9.6/manual/Types/patternset.html
new file mode 100644
index 00000000..4ad433db
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Types/patternset.html
@@ -0,0 +1,192 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>PatternSet Type</title>
+</head>
+
+<body>
+
+<h2><a name="patternset">PatternSet</a></h2>
+<p><a href="../dirtasks.html#patterns">Patterns</a> can be grouped to
+sets and later be referenced by their <code>id</code> attribute. They
+are defined via a <code>patternset</code> element, which can appear
+nested into a <a href="fileset.html">FileSet</a> or a directory-based
+task that constitutes an implicit FileSet. In addition,
+<code>patternset</code>s can be defined as a stand alone element at
+the same level as <code>target</code> &#151; i.e., as children of
+<code>project</code> as well as as children of
+<code>target</code>.</p> <p>Patterns can be specified by nested
+<code>&lt;include&gt;</code>, or <code>&lt;exclude&gt;</code> elements
+or the following attributes.</p>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ </tr>
+ <tr>
+ <td valign="top">includes</td>
+ <td valign="top">comma- or space-separated list of patterns of files that must be
+ included. All files are included when omitted.</td>
+ </tr>
+ <tr>
+ <td valign="top">includesfile</td>
+ <td valign="top">the name of a file; each line of this file is
+ taken to be an include pattern. You can specify more than one
+ include file by using a nested includesfile elements.
+ <b>Note:</b> if the file is empty and there are no other
+ patterns defined for the fileset, all files will be included.
+ </td>
+ </tr>
+ <tr>
+ <td valign="top">excludes</td>
+ <td valign="top">comma- or space-separated list of patterns of files that must be
+ excluded; no files (except default excludes) are excluded when omitted.</td>
+ </tr>
+ <tr>
+ <td valign="top">excludesfile</td>
+ <td valign="top">the name of a file; each line of this file is
+ taken to be an exclude pattern. You can specify more than one
+ exclude file by using a nested excludesfile elements.</td>
+ </tr>
+</table>
+<h3>Parameters specified as nested elements</h3>
+<h4><code>include</code> and <code>exclude</code></h4>
+<p>Each such element defines a single pattern for files to include or
+exclude.</p>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">name</td>
+ <td valign="top">the <a href="../dirtasks.html#patterns">pattern</a>
+ to in/exclude.</td>
+ <td align="center" valign="top">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">if</td>
+ <td valign="top">Only use this pattern <a href="../properties.html#if+unless">if the named property is set</a>.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">unless</td>
+ <td valign="top">Only use this pattern <a href="../properties.html#if+unless">if the named property is
+ <b>not</b> set</a>.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+</table>
+<h4><code>includesfile</code> and <code>excludesfile</code></h4>
+<p>If you want to list the files to include or exclude external to
+your build file, you should use the includesfile/excludesfile
+attributes or elements. Using the attribute, you can only specify a
+single file of each type, while the nested elements can be specified
+more than once - the nested elements also support if/unless attributes
+you can use to test the existence of a property.</p>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">name</td>
+ <td valign="top">the name of the file holding the patterns to
+ in/exclude.</td>
+ <td align="center" valign="top">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">if</td>
+ <td valign="top">Only read this file <a href="../properties.html#if+unless">if the named property is set</a>.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">unless</td>
+ <td valign="top">Only read this file <a href="../properties.html#if+unless">if the named property is
+ <b>not</b> set</a>.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+</table>
+<h4><code>patternset</code></h4>
+<p>Patternsets may be nested within one another, adding the nested
+patterns to the parent patternset.</p>
+<h4><code>invert</code></h4>
+<p>A nested patternset can be inverted using the <code>&lt;invert&gt;</code>
+element. <em>Since Apache Ant 1.7.1</em></p>
+<h3>Examples</h3>
+<blockquote><pre>
+&lt;patternset id=&quot;non.test.sources&quot;&gt;
+ &lt;include name=&quot;**/*.java&quot;/&gt;
+ &lt;exclude name=&quot;**/*Test*&quot;/&gt;
+&lt;/patternset&gt;
+</pre></blockquote>
+<p>Builds a set of patterns that matches all <code>.java</code> files
+that do not contain the text <code>Test</code> in their name. This set
+can be <a href="../using.html#references">referred</a> to via
+<code>&lt;patternset refid=&quot;non.test.sources&quot;/&gt;</code>,
+by tasks that support this feature, or by FileSets.</p>
+<p>Note that while the <code>includes</code> and
+<code>excludes</code> attributes accept
+multiple elements separated by commas or spaces, the nested
+<code>&lt;include&gt;</code> and <code>&lt;exclude&gt;</code> elements expect their name
+attribute to hold a single pattern.</p>
+<p>The nested elements allow you to use if and unless arguments to
+specify that the element should only be used if a property is set, or
+that it should be used only if a property is not set.</p>
+<p>For example</p>
+<blockquote><pre>
+&lt;patternset id=&quot;sources&quot;&gt;
+ &lt;include name=&quot;std/**/*.java&quot;/&gt;
+ &lt;include name=&quot;prof/**/*.java&quot; if=&quot;professional&quot;/&gt;
+ &lt;exclude name=&quot;**/*Test*&quot;/&gt;
+&lt;/patternset&gt;
+</pre></blockquote>
+<p>will only include the files in the sub-directory <em>prof</em> if the property
+<em>professional</em> is set to some value.</p>
+<p>The two sets</p>
+<blockquote><pre>
+&lt;patternset includesfile=&quot;some-file&quot;/&gt;
+</pre></blockquote>
+<p>and</p>
+<blockquote><pre>
+&lt;patternset&gt;
+ &lt;includesfile name=&quot;some-file&quot;/&gt;
+&lt;patternset/&gt;
+</pre></blockquote>
+<p>are identical. The include patterns will be read from the file
+<code>some-file</code>, one pattern per line.</p>
+<blockquote><pre>
+&lt;patternset&gt;
+ &lt;includesfile name=&quot;some-file&quot;/&gt;
+ &lt;includesfile name=&quot;${some-other-file}&quot;
+ if=&quot;some-other-file&quot;
+ /&gt;
+&lt;patternset/&gt;
+</pre></blockquote>
+<p>will also read include patterns from the file the property
+<code>some-other-file</code> points to, if a property of that name has
+been defined.</p>
+
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Types/permissions.html b/framework/src/ant/apache-ant-1.9.6/manual/Types/permissions.html
new file mode 100644
index 00000000..f7b90b78
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Types/permissions.html
@@ -0,0 +1,164 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Permissions type</title>
+</head>
+
+<body>
+
+<h2><a name="permissions">Permissions</a></h2>
+<p>
+Permissions represents a set of security permissions granted or revoked to
+a specific part code executed in the JVM where Apache Ant is running in.
+The actual Permissions are specified via a set of nested permission items either
+<code>&lt;grant&gt;</code>ed or <code>&lt;revoke&gt;</code>d.</p>
+<p>
+In the base situation a <a href="#baseset">base set</a> of permissions granted.
+Extra permissions can be
+granted. A granted permission can be overruled by revoking a permission.
+The security manager installed by the permissions will throw an
+<code>SecurityException</code> if
+the code subject to these permissions try to use an permission that has not been
+granted or that has been revoked.</p>
+<h3>Nested elements</h3>
+<h4>grant</h4>
+<p>
+Indicates a specific permission is always granted. Its attributes indicate which
+permissions are granted.</p>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">class</td>
+ <td valign="top">The fully qualified name of the Permission class.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">name</td>
+ <td valign="top">The name of the Permission. The actual contents depends on the
+ Permission class.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">actions</td>
+ <td valign="top">The actions allowed. The actual contents depend on the
+ Permission class and name.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+</table>
+<p>
+Implied permissions are granted.
+</p>
+<p>
+Please note that some Permission classes may actually need a name and / or actions in order to function properly. The name and actions are parsed by the actual
+Permission class.
+</p>
+<h4>revoke</h4>
+<p>
+Indicates a specific permission is revoked.</p>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">class</td>
+ <td valign="top">The fully qualified name of the Permission class.</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">name</td>
+ <td valign="top">The name of the Permission. The actual contents depends on the
+ Permission class.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">actions</td>
+ <td valign="top">The actions allowed. The actual contents depend on the
+ Permission class and name.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+</table>
+<p>
+Implied permissions are not resolved and therefore also not revoked.
+</p>
+<p>
+The name can handle the * wildcard at the end of the name, in which case all
+permissions of the specified class of which the name starts with the specified name
+(excluding the *) are revoked. Note that the - wildcard often supported by the
+granted properties is not supported.
+If the name is left empty all names match, and are revoked.
+If the actions are left empty all actions match, and are revoked.
+</p>
+<h3><a name="baseset">Base set</a></h3>
+A permissions set implicitly contains the following permissions:
+<blockquote><pre>
+&lt;grant class=&quot;java.net.SocketPermission&quot; name=&quot;localhost:1024-&quot; actions=&quot;listen&quot;&gt;
+&lt;grant class=&quot;java.util.PropertyPermission&quot; name=&quot;java.version&quot; actions=&quot;read&quot;&gt;
+&lt;grant class=&quot;java.util.PropertyPermission&quot; name=&quot;java.vendor&quot; actions=&quot;read&quot;&gt;
+&lt;grant class=&quot;java.util.PropertyPermission&quot; name=&quot;java.vendor.url&quot; actions=&quot;read&quot;&gt;
+&lt;grant class=&quot;java.util.PropertyPermission&quot; name=&quot;java.class.version&quot; actions=&quot;read&quot;&gt;
+&lt;grant class=&quot;java.util.PropertyPermission&quot; name=&quot;os.name&quot; actions=&quot;read&quot;&gt;
+&lt;grant class=&quot;java.util.PropertyPermission&quot; name=&quot;os.version&quot; actions=&quot;read&quot;&gt;
+&lt;grant class=&quot;java.util.PropertyPermission&quot; name=&quot;os.arch&quot; actions=&quot;read&quot;&gt;
+&lt;grant class=&quot;java.util.PropertyPermission&quot; name=&quot;file.encoding&quot; actions=&quot;read&quot;&gt;
+&lt;grant class=&quot;java.util.PropertyPermission&quot; name=&quot;file.separator&quot; actions=&quot;read&quot;&gt;
+&lt;grant class=&quot;java.util.PropertyPermission&quot; name=&quot;path.separator&quot; actions=&quot;read&quot;&gt;
+&lt;grant class=&quot;java.util.PropertyPermission&quot; name=&quot;line.separator&quot; actions=&quot;read&quot;&gt;
+&lt;grant class=&quot;java.util.PropertyPermission&quot; name=&quot;java.specification.version&quot; actions=&quot;read&quot;&gt;
+&lt;grant class=&quot;java.util.PropertyPermission&quot; name=&quot;java.specification.vendor&quot; actions=&quot;read&quot;&gt;
+&lt;grant class=&quot;java.util.PropertyPermission&quot; name=&quot;java.specification.name&quot; actions=&quot;read&quot;&gt;
+&lt;grant class=&quot;java.util.PropertyPermission&quot; name=&quot;java.vm.specification.version&quot; actions=&quot;read&quot;&gt;
+&lt;grant class=&quot;java.util.PropertyPermission&quot; name=&quot;java.vm.specification.vendor&quot; actions=&quot;read&quot;&gt;
+&lt;grant class=&quot;java.util.PropertyPermission&quot; name=&quot;java.vm.specification.name&quot; actions=&quot;read&quot;&gt;
+&lt;grant class=&quot;java.util.PropertyPermission&quot; name=&quot;java.vm.version&quot; actions=&quot;read&quot;&gt;
+&lt;grant class=&quot;java.util.PropertyPermission&quot; name=&quot;java.vm.vendor&quot; actions=&quot;read&quot;&gt;
+&lt;grant class=&quot;java.util.PropertyPermission&quot; name=&quot;java.vm.name&quot; actions=&quot;read&quot;&gt;
+</blockquote></pre>
+These permissions can be revoked via <code>&lt;revoke&gt;</code> elements if necessary.
+
+<h3>Examples</h3>
+<blockquote><pre>
+&lt;permissions&gt;
+ &lt;grant class=&quot;java.security.AllPermission&quot;/&gt;
+ &lt;revoke class=&quot;java.util.PropertyPermission&quot;/&gt;
+&lt;/permissions&gt;
+</pre></blockquote>
+<p>
+Grants all permissions to the code except for those handling Properties.
+</p>
+<blockquote><pre>
+&lt;permissions&gt;
+ &lt;grant class=&quot;java.net.SocketPermission&quot; name=&quot;foo.bar.com&quot; action=&quot;connect&quot;/&gt;
+ &lt;grant class=&quot;java.util.PropertyPermission&quot; name=&quot;user.home&quot; action=&quot;read,write&quot;/&gt;
+&lt;/permissions&gt;
+</pre></blockquote>
+<p>
+Grants the base set of permissions with the addition of a SocketPermission to connect
+to foo.bar.com and the permission to read and write the user.home system property.
+</p>
+
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Types/propertyset.html b/framework/src/ant/apache-ant-1.9.6/manual/Types/propertyset.html
new file mode 100644
index 00000000..81d491e0
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Types/propertyset.html
@@ -0,0 +1,143 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>PropertySet Type</title>
+</head>
+
+<body>
+
+<h2><a name="propertyset">PropertySet</a></h2>
+<p><em>Since Apache Ant 1.6</em></p>
+
+<p>Groups a set of properties to be used by reference in a task that
+supports this.</p>
+
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">dynamic</td>
+ <td valign="top">Whether to reevaluate the set every time the set
+ is used. Default is &quot;<code>true</code>&quot;.</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">negate</td>
+ <td valign="top">Whether to negate results. If
+ &quot;<code>true</code>&quot;, all properties <i>not</i>
+ selected by nested elements will be returned. Default is
+ &quot;<code>false</code>&quot;. <em>Since Ant 1.6.2</em>
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+</table>
+<h3>Parameters specified as nested elements</h3>
+
+<h4>propertyref</h4>
+
+<p>Selects properties from the current project to be included in the
+set.</p>
+
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">name</td>
+ <td valign="top">Select the property with the given name.</td>
+ <td align="center" valign="top" rowspan="4">Exactly one of these.</td>
+ </tr>
+ <tr>
+ <td valign="top">prefix</td>
+ <td valign="top">Select the properties whose name starts with the
+ given string.</td>
+ </tr>
+ <tr>
+ <td valign="top">regex</td>
+ <td valign="top">Select the properties that match the given
+ regular expression. Similar to <a
+ href="mapper.html#regexp-mapper">regexp type mappers</a>, this
+ requires a supported regular expression library.</td>
+ </tr>
+ <tr>
+ <td valign="top">builtin</td>
+ <td valign="top">Selects a builtin set of properties. Valid
+ values for this attribute are <code>all</code> for all Ant
+ properties, <code>system</code> for the system properties and
+ <code>commandline</code> for all properties specified on the
+ command line when invoking Ant (plus a number of special
+ internal Ant properties).</td>
+ </tr>
+</table>
+
+<h4>propertyset</h4>
+
+<p>A <code>propertyset</code> can be used as the set union of more
+<code>propertyset</code>s.</p>
+
+<p>For example:</p>
+
+<blockquote><pre>
+&lt;propertyset id=&quot;properties-starting-with-foo&quot;&gt;
+ &lt;propertyref prefix=&quot;foo&quot;/&gt;
+&lt;/propertyset&gt;
+&lt;propertyset id=&quot;properties-starting-with-bar&quot;&gt;
+ &lt;propertyref prefix=&quot;bar&quot;/&gt;
+&lt;/propertyset&gt;
+&lt;propertyset id=&quot;my-set&quot;&gt;
+ &lt;propertyset refid=&quot;properties-starting-with-foo&quot;/&gt;
+ &lt;propertyset refid=&quot;properties-starting-with-bar&quot;/&gt;
+&lt;/propertyset&gt;
+</pre></blockquote>
+
+<p>collects all properties whose name starts with either
+&quot;foo&quot; or &quot;bar&quot; in the set named
+&quot;my-set&quot;.</p>
+
+<h4>mapper</h4>
+
+<p>A <a href="mapper.html">mapper</a> - at maximum one mapper can be
+specified. The mapper is used to change the names of the property
+keys, for example:
+
+<blockquote><pre>
+&lt;propertyset id=&quot;properties-starting-with-foo&quot;&gt;
+ &lt;propertyref prefix=&quot;foo&quot;/&gt;
+ &lt;mapper type=&quot;glob&quot; from=&quot;foo*&quot; to=&quot;bar*&quot;/&gt;
+&lt;/propertyset&gt;
+</pre></blockquote>
+
+<p>collects all properties whose name starts with &quot;foo&quot;, but
+changes the names to start with &quot;bar&quot; instead.</p>
+
+<p>If supplied, the nested mapper will be applied
+subsequent to any negation of matched properties.</p>
+
+
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Types/redirector.html b/framework/src/ant/apache-ant-1.9.6/manual/Types/redirector.html
new file mode 100644
index 00000000..d0e36838
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Types/redirector.html
@@ -0,0 +1,193 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Redirector Type</title>
+</head>
+
+<body>
+
+<h2><a name="redirector">I/O redirection</a></h2>
+<p>For many tasks, input and output can be defined in a fairly
+straightforward fashion. The <a href="../Tasks/exec.html">exec</a>
+task, used to execute an external process, stands as a very
+basic example. The executed process may accept input, produce
+output, or do either or both depending upon various circumstances.
+Output may be classified as &quot;output&quot; or as &quot;error
+output.&quot; The <code>&lt;redirector&gt;</code> type provides a concrete means
+of redirecting input and output featuring the use of
+<a href="./mapper.html">File Mapper</a>s to specify
+source (input) and destination (output/error) files. <em>Since Apache Ant 1.6.2</em>
+<p>The <code>&lt;redirector&gt;</code> element accepts the following attributes:</p>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">output</td>
+ <td valign="top">Name of a file to which output should be written.
+ If the error stream is not also redirected to a file or property,
+ it will appear in this output.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">error</td>
+ <td valign="top">The file to which the standard error of the
+ command should be redirected.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">logError</td>
+ <td valign="top">This attribute is used when you wish to see
+ error output in Ant's log and you are redirecting output to
+ a file/property. The error output will not be included in
+ the output file/property. If you redirect error with the
+ <i>error</i> or <i>errorProperty</i> attributes, this will
+ have no effect.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">append</td>
+ <td valign="top">Whether output and error files should be
+ appended to rather than overwritten. Defaults to
+ <code>false</code>.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">createemptyfiles</td>
+ <td valign="top">Whether output and error files should be
+ created even when empty. Defaults to <code>true</code>.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">outputproperty</td>
+ <td valign="top">The name of a property in which the output of the
+ command should be stored. Unless the error stream is redirected
+ to a separate file or stream, this property will include the
+ error output.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">errorproperty</td>
+ <td valign="top">The name of a property in which the standard error
+ of the command should be stored.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">input</td>
+ <td valign="top">A file from which the executed command's standard input
+ is taken. This attribute is mutually exclusive with the
+ <i>inputstring</i> attribute.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">inputstring</td>
+ <td valign="top">A string which serves as the input stream for the
+ executed command. This attribute is mutually exclusive with the
+ <i>input</i> attribute.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">inputencoding</td>
+ <td valign="top">The input encoding.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">outputencoding</td>
+ <td valign="top">The output encoding.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">errorencoding</td>
+ <td valign="top">The error encoding.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">alwayslog</td>
+ <td valign="top">Always send to the log in addition to
+ any other destination. <i>Since Ant 1.6.3</i>.
+ </td>
+ <td align="center" valign="top">No, default is <code>false</code></td>
+ </tr>
+ <tr>
+ <td valign="top">loginputstring</td>
+ <td valign="top">Controls the display of <i>inputstring</i>'s value in
+ log messages. Set to <code>false</code> when sending sensitive data
+ (e.g. passwords) to external processes. <i>Since Ant 1.6.3</i>.
+ </td>
+ <td align="center" valign="top">No, default is <code>true</code></td>
+ </tr>
+ <tr>
+ <td valign="top">binaryOutput</td>
+ <td valign="top">When set to true Ant will not try to split the
+ output into lines - which it will usually do in order to separate
+ error from normal output. This setting will not prevent binary
+ output from getting corrupted if you also specify filter chains.
+ <i>Since Ant 1.9.4</i>.
+ </td>
+ <td align="center" valign="top">No, default is <code>false</code></td>
+ </tr>
+</table>
+<h3>Parameters specified as nested elements</h3>
+<h4>inputmapper</h4>
+<p>A single <a href="./mapper.html">File Mapper</a> used to redirect process
+input. Multiple mapping results should concatenate all mapped files as input.
+Mapping will ordinarily be performed on a task-specified sourcefile;
+consult the documentation of the individual task for more details.
+A nested <code>&lt;inputmapper&gt;</code> is not compatible with either of the
+<i>input</i> or <i>inputstring</i> attributes.</p>
+<h4>outputmapper</h4>
+<p>A single <a href="./mapper.html">File Mapper</a> used to redirect process
+output. Mapping will ordinarily be performed on a task-specified sourcefile;
+consult the documentation of the individual task for more details.
+A nested <code>&lt;outputmapper&gt;</code> is not compatible with the
+<i>output</i> attribute.</p>
+<h4>errormapper</h4>
+<p>A single <a href="./mapper.html">File Mapper</a> used to redirect error
+output. Mapping will ordinarily be performed on a task-specified sourcefile;
+consult the documentation of the individual task for more details.
+A nested <code>&lt;errormapper&gt;</code> is not compatible with the
+<i>error</i> attribute.</p>
+<h4>inputfilterchain</h4>
+<p>A <a href="./filterchain.html">FilterChain</a> can be
+applied to the process input.</p>
+<h4>outputfilterchain</h4>
+<p>A <a href="./filterchain.html">FilterChain</a> can be
+applied to the process output.</p>
+<h4>errorfilterchain</h4>
+<p>A <a href="./filterchain.html">FilterChain</a> can be
+applied to the error output.</p>
+<h3>Usage</h3>
+Tasks known to support I/O redirection:
+<ul>
+<li><a href="../Tasks/exec.html">Exec</a></li>
+<li><a href="../Tasks/apply.html">Apply</a></li>
+<li><a href="../Tasks/java.html">Java</a></li>
+</ul>
+<p>The expected behavior of a <code>&lt;redirector&gt;</code> is to a great degree
+dependent on the supporting task. Any possible points of confusion
+should be noted at the task level.</p>
+
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Types/regexp.html b/framework/src/ant/apache-ant-1.9.6/manual/Types/regexp.html
new file mode 100644
index 00000000..0628bb9b
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Types/regexp.html
@@ -0,0 +1,116 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Regexp Type</title>
+</head>
+
+<body>
+
+<h2><a name="regexp">Regexp</a></h2>
+<p>
+Regexp represents a regular expression.
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">pattern</td>
+ <td valign="top">regular expression pattern</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+</table>
+
+<h3>Examples</h3>
+<blockquote><pre>
+ &lt;regexp id="myregexp" pattern="alpha(.+)beta"/&gt;<br>
+</pre></blockquote>
+<p>
+Defines a regular expression for later use with id myregexp.
+</p>
+<blockquote><pre>
+ &lt;regexp refid="myregexp"/&gt;<br>
+</pre></blockquote>
+<p>
+Use the regular expression with id myregexp.
+</p>
+<h3><a name="implementation">Choice of regular expression implementation</a></h3>
+<p>
+Apache Ant comes with
+wrappers for
+<a href="http://docs.oracle.com/javase/7/docs/api/java/util/regex/package-summary.html" target="_top">the java.util.regex package</a>,
+<a href="http://attic.apache.org/projects/jakarta-regexp.html" target="_top">jakarta-regexp</a>
+and <a href="http://attic.apache.org/projects/jakarta-oro.html" target="_top">jakarta-ORO</a>,
+See <a href="../install.html#librarydependencies">installation dependencies</a>
+ concerning the supporting libraries.</p>
+<p>
+The property <code>ant.regexp.regexpimpl</code> governs which regular expression implementation will be chosen.
+Possible values for this property are :
+<ul>
+<li>
+org.apache.tools.ant.util.regexp.Jdk14RegexpRegexp
+</li>
+<li>
+org.apache.tools.ant.util.regexp.JakartaOroRegexp
+</li>
+<li>
+org.apache.tools.ant.util.regexp.JakartaRegexpRegexp
+</li>
+</ul>
+It can also be another implementation of the interface <code>org.apache.tools.ant.util.regexp.Regexp</code>.
+If <code>ant.regexp.regexpimpl</code> is not defined, Ant uses Jdk14Regexp as this is always available.</p>
+<p>
+There are cross-platform issues for matches related to line terminator.
+For example if you use $ to anchor your regular expression on the end of a line
+the results might be very different depending on both your platform and the regular
+expression library you use. It is 'highly recommended' that you test your pattern on
+both Unix and Windows platforms before you rely on it.
+<ul>
+ <li>Jakarta Oro defines a line terminator as '\n' and is consistent with Perl.</li>
+ <li>Jakarta RegExp uses a system-dependent line terminator.</li>
+ <li>JDK 1.4 uses '\n', '\r\n', '\u0085', '\u2028', '\u2029' as a default
+ but is configured in the wrapper to use only '\n' (UNIX_LINE)</li>
+</ul>
+<em>We used to recommend that you use Jakarta ORO but since its
+ development has been retired Java's built-in regex package is likely
+ the best choice going forward.</em>
+</p>
+<h3>Usage</h3>
+The following tasks and types use the Regexp type :
+<ul>
+<li><a href="../Tasks/replaceregexp.html">ReplaceRegExp task</a></li>
+<li><a href="filterchain.html#linecontainsregexp">LineContainsRegexp filter</a></li>
+</ul>
+<p>
+These string filters also use the mechanism of regexp to choose a regular expression implementation :
+</p>
+<ul>
+<li><a href="filterchain.html#containsregex">ContainsRegex string filter</a></li>
+<li><a href="filterchain.html#replaceregex">ReplaceRegex string filter</a></li>
+<li><a href="selectors.html#filenameselect">filename selector</a></li>
+<li><a href="resources.html#rsel.name">name resource selector</a></li>
+<li><a href="selectors.html#regexpselect">containsregexp selector</a></li>
+</ul>
+
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Types/resources.html b/framework/src/ant/apache-ant-1.9.6/manual/Types/resources.html
new file mode 100644
index 00000000..58cefde1
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Types/resources.html
@@ -0,0 +1,1380 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Resources and Resource Collections</title>
+</head>
+
+<body>
+
+<h2><a name="resource">Resources</a></h2>
+<p>
+A file-like entity can be abstracted to the concept of a <i>resource</i>.
+In addition to providing access to file-like attributes, a resource
+implementation should, when possible, provide the means to read content
+from and/or write content to the underlying entity. Although the resource
+concept was introduced in <i>Apache Ant 1.5.2</i>, resources are available for
+explicit use beginning in <b>Ant 1.7</b>.
+</p>
+
+<h3>The built-in resource types are:</h3>
+
+<ul>
+ <li><a href="#basic">resource</a> - a basic resource.</li>
+ <li><a href="#bzip2resource">bzip2resource</a> - a BZip2 compressed resource.</li>
+ <li><a href="#file">file</a> - a file.</li>
+ <li><a href="#gzipresource">gzipresource</a> - a GZip compressed resource.</li>
+ <li><a href="#javaresource">javaresource</a> - a resource loadable
+ via a Java classloader.</li>
+ <li><a href="#javaconstant">javaconstant</a> - a constant in a class loadable
+ via a Java classloader.</li>
+ <li><a href="#propertyresource">propertyresource</a> - an Ant property.</li>
+ <li><a href="#string">string</a> - a text string.</li>
+ <li><a href="#tarentry">tarentry</a> - an entry in a tar file.</li>
+ <li><a href="#url">url</a> - a URL.</li>
+ <li><a href="#zipentry">zipentry</a> - an entry in a zip file.</li>
+</ul>
+
+<h4><a name="basic">resource</a></h4>
+
+<p>A basic resource. Other resource types derive from this basic
+type; as such all its attributes are available, though in most cases
+irrelevant attributes will be ignored. This and all resource
+implementations are also usable as single-element
+<a href="#collection">Resource Collections</a>.
+</p>
+
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">name</td>
+ <td valign="top">The name of this resource</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">exists</td>
+ <td valign="top">Whether this resource exists</td>
+ <td align="center" valign="top">No, default <i>true</i></td>
+ </tr>
+ <tr>
+ <td valign="top">lastmodified</td>
+ <td valign="top">The last modification time of this resource</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">directory</td>
+ <td valign="top">Whether this resource is directory-like</td>
+ <td align="center" valign="top">No, default <i>false</i></td>
+ </tr>
+ <tr>
+ <td valign="top">size</td>
+ <td valign="top">The size of this resource</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+</table>
+
+<h4><a name="file">file</a></h4>
+
+<p>Represents a file accessible via local filesystem conventions.</p>
+
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">file</td>
+ <td valign="top">The file represented by this resource</td>
+ <td align="center" valign="top">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">basedir</td>
+ <td valign="top">The base directory of this resource. When this
+ attribute is set, attempts to access the name of the resource
+ will yield a path relative to this location.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+</table>
+
+<h4><a name="javaresource">javaresource</a></h4>
+
+<p>Represents a resource loadable via a Java classloader.</p>
+
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">name</td>
+ <td valign="top">The name of the resource.</td>
+ <td align="center" valign="top">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">classpath</td>
+ <td valign="top">the classpath to use when looking up a resource.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">classpathref</td>
+ <td valign="top">the classpath to use when looking up a resource,
+ given as <a href="../using.html#references">reference</a>
+ to a <code>&lt;path&gt;</code> defined elsewhere..</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">loaderRef</td>
+ <td valign="top">the name of the loader that is
+ used to load the resource, constructed from the specified classpath.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">parentFirst</td>
+ <td valign="top">Whether to consult the parent classloader first -
+ the parent classloader most likely is the system classloader -
+ when using a nested classpath. Defaults
+ to <code>true</code>.<br/>
+ <em>Since Ant 1.8.0</em></td>
+ <td align="center" valign="top">No</td>
+ </tr>
+</table>
+
+<p>The classpath can also be specified as nested classpath element,
+where <b>&lt;classpath&gt;</b> is a <a
+href="../using.html#path">path-like structure</a>.</p>
+
+
+<h4><a name="javaconstant">javaconstant</a></h4>
+<p>Loads the value of a java constant. As a specialisation of
+<a href="#javaresource">javaresource</a> all of its attributes and nested elements are
+supported. A constant must be specified as <tt>public static</tt> otherwise it could not be loaded.</p>
+
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">name</td>
+ <td valign="top">The name of the resource. Must be specified as full qualified
+ field name.
+ </td>
+ <td align="center" valign="top">Yes</td>
+ </tr>
+</table>
+<h5>Examples</h5>
+This loads the value of the constant <tt>VERSION</tt> of the <tt>org.acme.Main</tt> class
+into the <tt>version</tt>-property. The classpath for finding that class is provided via
+nested classpath element.
+<pre><code>&lt;loadresource property=&quot;version&quot;&gt;
+ &lt;javaconstant name=&quot;org.acme.Main.VERSION&quot;&gt;
+ &lt;classpath&gt;
+ &lt;pathelement location=&quot;${acme.lib.dir}&quot;/&gt;
+ &lt;/classpath&gt;
+ &lt;/javaconstant&gt;
+ &lt;/loadresource&gt;
+</code></pre>
+
+Create a new file <tt>c:/temp/org.apache.tools.ant.Main.DEFAULT_BUILD_FILENAME</tt> with the content
+of that constant (<tt>build.xml</tt>).
+<pre><code>&lt;copy todir=&quot;c:/temp&quot;&gt;
+ &lt;javaconstant name=&quot;org.apache.tools.ant.Main.DEFAULT_BUILD_FILENAME&quot;/&gt;
+&lt;/copy&gt;</code></pre>
+
+
+<h4><a name="zipentry">zipentry</a></h4>
+
+<p>Represents an entry in a ZIP archive. The archive can be specified
+using the archive attribute or a nested single-element resource
+collection. <code>zipentry</code> only supports file system resources
+as nested elements.</p>
+
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">zipfile or its alias name archive</td>
+ <td valign="top">The zip file containing this resource</td>
+ <td align="center" valign="top">Yes, unless a nested resource
+ collection has been specified.</td>
+ </tr>
+ <tr>
+ <td valign="top">name</td>
+ <td valign="top">The name of the archived resource</td>
+ <td align="center" valign="top">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">encoding</td>
+ <td valign="top">The encoding of the zipfile</td>
+ <td align="center" valign="top">No;
+ platform default used if unspecified</td>
+ </tr>
+</table>
+
+<h4><a name="tarentry">tarentry</a></h4>
+
+<p>Represents an entry in a TAR archive. The archive can be specified
+using the archive attribute or a nested single-element resource
+collection.</p>
+
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">archive</td>
+ <td valign="top">The tar archive containing this resource</td>
+ <td align="center" valign="top">Yes, unless a nested resource
+ collection has been specified.</td>
+ </tr>
+ <tr>
+ <td valign="top">name</td>
+ <td valign="top">The name of the archived resource</td>
+ <td align="center" valign="top">Yes</td>
+ </tr>
+</table>
+
+<h4><a name="gzipresource">gzipresource</a></h4>
+
+<p>This is not a stand-alone resource, but a wrapper around another
+resource providing compression of the resource's contents on the fly.
+A single element resource collection must be specified as a nested
+element.</p>
+
+<h4><a name="bzip2resource">bzip2resource</a></h4>
+
+<p>This is not a stand-alone resource, but a wrapper around another
+resource providing compression of the resource's contents on the fly.
+A single element resource collection must be specified as a nested
+element.</p>
+
+<h4><a name="url">url</a></h4>
+
+<p>Represents a URL.</p>
+
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">url</td>
+ <td valign="top">The url to expose</td>
+ <td rowspan="3" align="center" valign="middle">Exactly one of these</td>
+ </tr>
+ <tr>
+ <td valign="top">file</td>
+ <td valign="top">The file to expose as a file: url</td>
+ </tr>
+ <tr>
+ <td valign="top">baseUrl</td>
+ <td valign="top">The base URL which must be combined with relativePath</td>
+ </tr>
+ <tr>
+ <td valign="top">relativePath</td>
+ <td valign="top">Relative path that defines the url combined with
+ baseUrl</td>
+ <td align="center" valign="top">If using baseUrl</td>
+ </tr>
+</table>
+
+<h4><a name="string">string</a></h4>
+
+<p>Represents a Java String. It can be written to, but only once, after which
+it will be an error to write to again.</p>
+
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">value</td>
+ <td valign="top">The value of this resource</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+</table>
+
+<p>The resource also supports nested text, which can only be supplied if the <code>value</code> attribute is unset:
+ </p>
+<pre>
+ &lt;string>
+ self.log("Ant version =${ant.version}");
+ &lt;/string>
+</pre>
+
+</p>
+
+<h4><a name="propertyresource">propertyresource</a></h4>
+
+<p>Represents an Ant property.</p>
+
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">name</td>
+ <td valign="top">The property name</td>
+ <td align="center" valign="top">Yes</td>
+ </tr>
+</table>
+
+<hr>
+<h2><a name="collection">Resource Collections</a></h2>
+<p>
+A Resource Collection is an abstraction of an entity that groups
+together a number of <a href="#resource">resources</a>. Several of
+Ant's "legacy" datatypes have been modified to behave as Resource Collections:
+<ul>
+ <li><a href="fileset.html">fileset</a>,
+ <a href="dirset.html">dirset</a>,
+ <a href="multirootfileset.html">multirootfileset</a>,
+ <a href="filelist.html">filelist</a>, and
+ <a href="../using.html#path">path</a>
+ (and derivative types) expose <a href="#file">file</a> resources
+ </li>
+ <li><a href="tarfileset.html">tarfileset</a>
+ can expose <a href="#file">file</a> or <a href="#tarentry">tarentry</a>
+ resources depending on configuration
+ </li>
+ <li><a href="zipfileset.html">zipfileset</a>
+ can expose <a href="#file">file</a> or <a href="#zipentry">zipentry</a>
+ resources depending on configuration
+ </li>
+ <li><a href="propertyset.html">propertyset</a>
+ exposes <a href="#propertyresource">property</a> resources
+ </li>
+</ul>
+</p>
+<p>Strangely, some tasks can even legitimately behave as resource collections:
+<ul>
+ <li><a href="../Tasks/concat.html">concat</a>
+ exposes a concatenated resource, and adds e.g.
+ <a href="filterchain.html">filtering</a>
+ to Ant's resource-related capabilities.
+ </li>
+</ul>
+</p>
+<h3>The additional built-in resource collections are:</h3>
+<ul>
+ <li><a href="#resources">resources</a> - generic resource collection</li>
+ <li><a href="#files">files</a> - collection of files similar to
+ <a href="fileset.html">fileset</a></li>
+ <li><a href="#restrict">restrict</a> - restrict a resource collection
+ to include only resources meeting specified criteria</li>
+ <li><a href="#sort">sort</a> - sorted resource collection</li>
+ <li><a href="#first">first</a> - first <i>n</i> resources from a
+ nested collection</li>
+ <li><a href="#last">last</a> - last <i>n</i> resources from a
+ nested collection</li>
+ <li><a href="#allbutfirst">allbutfirst</a> - all except the
+ first <i>n</i> resources from a nested collection</li>
+ <li><a href="#allbutlast">allbutlast</a> - all except the last <i>n</i>
+ resources from a nested collection</li>
+ <li><a href="#tokens">tokens</a> - <a href="#string">string</a> tokens
+ gathered from a nested collection</li>
+ <li><a href="#union">union</a> - set union of nested resource collections</li>
+ <li><a href="#intersect">intersect</a> - set intersection
+ of nested resource collections</li>
+ <li><a href="#difference">difference</a> - set difference
+ of nested resource collections</li>
+ <li><a href="#mappedresources">mappedresources</a> - generic
+ resource collection wrapper that maps the names of the nested
+ resources using a <a href="mapper.html">mapper</a>.</li>
+ <li><a href="#archives">archives</a> - wraps around different
+ resource collections and treats the nested resources as ZIP or TAR
+ archives that will be extracted on the fly.</li>
+ <li><a href="#resourcelist">resourcelist</a> - a collection of
+ resources whose names have been read from another resource.</li>
+</ul>
+<h4><a name="resources">resources</a></h4>
+<p>A generic resource collection, designed for use with
+ <a href="../using.html#references">references</a>.
+ For example, if a third-party Ant task generates a Resource Collection
+ of an unknown type, it can still be accessed via a
+ <code>&lt;resources&gt;</code> collection. The secondary use of this
+ collection type is as a container of other resource collections,
+ preserving the order of nested collections as well as
+ duplicate resources (contrast with <a href="#union">union</a>).
+</p>
+<blockquote>
+ <table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">cache</td>
+ <td valign="top">Whether to cache results. <em>since Ant 1.8.0</em></td>
+ <td valign="top" align="center">No, default <i>false</i></td>
+ </tr>
+ </table>
+</blockquote>
+
+<h4><a name="files">files</a></h4>
+<p>A group of files. These files are matched by <b>absolute</b> patterns
+ taken from a number of <a href="patternset.html">PatternSets</a>.
+ These can be specified as nested <code>&lt;patternset&gt;</code>
+ elements. In addition, <code>&lt;files&gt;</code> holds an implicit
+ PatternSet and supports the nested <code>&lt;include&gt;</code>,
+ <code>&lt;includesfile&gt;</code>, <code>&lt;exclude&gt;</code>
+ and <code>&lt;excludesfile&gt;</code> elements of PatternSet directly,
+ as well as PatternSet's attributes.
+</p>
+<p><a href="selectors.html">File Selectors</a> are available as nested
+ elements. A file must be selected by all selectors in order to be included;
+ <code>&lt;files&gt;</code> is thus equivalent to an
+ <code>&lt;and&gt;</code> file selector container.
+</p>
+<p><b>More simply put</b>, this type is equivalent to a
+ <a href="fileset.html">fileset</a> with no base directory.
+ <b>Please note</b> that without a base directory,
+ filesystem scanning is based entirely on include and exclude patterns.
+ A <a href="selectors.html#filenameselect">filename</a> (or any)
+ selector can <i>only</i> influence the scanning process <i>after</i>
+ the file has been included based on pattern-based selection.
+</p>
+
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">includes</td>
+ <td valign="top">comma- or space-separated list of patterns
+ of files that must be included</td>
+ <td rowspan="2" valign="middle" align="center">At least one of these</td>
+ </tr>
+ <tr>
+ <td valign="top">includesfile</td>
+ <td valign="top">the name of a file; each line of this file is
+ taken to be an include pattern.</td>
+ </tr>
+ <tr>
+ <td valign="top">excludes</td>
+ <td valign="top">comma- or space-separated list of patterns
+ of files that must be excluded</td>
+ <td rowspan="2" valign="top" align="center">No, default none
+ (except default excludes when true)</td>
+ </tr>
+ <tr>
+ <td valign="top">excludesfile</td>
+ <td valign="top">the name of a file; each line of this file is
+ taken to be an exclude pattern.</td>
+ </tr>
+ <tr>
+ <td valign="top">defaultexcludes</td>
+ <td valign="top">Whether
+ <a href="../dirtasks.html#defaultexcludes">default excludes</a>
+ should be used</td>
+ <td valign="top" align="center">No, default <i>true</i></td>
+ </tr>
+ <tr>
+ <td valign="top">casesensitive</td>
+ <td valign="top">Whether patterns are case-sensitive</td>
+ <td valign="top" align="center">No, default <i>true</i></td>
+ </tr>
+ <tr>
+ <td valign="top">followsymlinks</td>
+ <td valign="top">Whether to follow symbolic links
+ (see note <a href="#symlink">below</a>)</td>
+ <td valign="top" align="center">No, default <i>true</i></td>
+ </tr>
+</table>
+
+<p><a name="symlink"><b>Note</b></a>: All files/directories for which
+the canonical path is different from its path are considered symbolic
+links. On Unix systems this usually means the file really is a
+symbolic link but it may lead to false results on other
+platforms.
+</p>
+
+<h4><a name="restrict">restrict</a></h4>
+<p>Restricts a nested resource collection using resource selectors:
+<blockquote>
+ <table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">cache</td>
+ <td valign="top">Whether to cache results; disabling
+ may seriously impact performance</td>
+ <td valign="top" align="center">No, default <i>true</i></td>
+ </tr>
+ </table>
+ <h4>Parameters specified as nested elements</h4>
+ <p>A single resource collection is required.</p>
+ <p>Nested resource selectors are used to "narrow down" the included
+ resources, combined via a logical <i>AND</i>. These are patterned
+ after <a href="selectors.html">file selectors</a> but are,
+ unsurprisingly, targeted to resources.
+ Several built-in resource selectors are available in the internal
+ <a href="antlib.html">antlib</a>
+ <code>org.apache.tools.ant.types.resources.selectors</code>:
+ </p>
+
+ <ul>
+ <li><a href="#rsel.name">name</a> - select resources by name.</li>
+ <li><a href="#rsel.exists">exists</a> - select existing resources.</li>
+ <li><a href="#rsel.date">date</a> - select resources by date.</li>
+ <li><a href="#rsel.type">type</a> - select resources by type.</li>
+ <li><a href="#rsel.size">size</a> - select resources by size.</li>
+ <li><a href="#rsel.instanceof">instanceof</a>
+ - select resources by class or Ant datatype.</li>
+ <li><a href="#rsel.and">and</a> - "and" nested resource selectors.</li>
+ <li><a href="#rsel.or">or</a> - "or" nested resource selectors.</li>
+ <li><a href="#rsel.not">not</a> - "not" a nested resource selector.</li>
+ <li><a href="#rsel.none">none</a>
+ - select resources selected by no nested resource selectors.</li>
+ <li><a href="#rsel.majority">majority</a> - select resources selected
+ by a majority of nested resource selectors.</li>
+ <li><a href="selectors.html#modified">modified</a> - select resources which
+ content has changed.</li>
+ <li><a href="selectors.html#containsselect">contains</a> - select resources
+ containing a particular text string.</li>
+ <li><a href="selectors.html#regexpselect">containsregexp</a> - select
+ resources whose contents match a particular regular expression.</li>
+ <li><a href="#rsel.compare">compare</a> - select resources
+ based on comparison to other resources.</li>
+ <li><a href="selectors.html#readable">readable</a> -
+ Select files (resources must be files) if they are readable.</li>
+ <li><a href="selectors.html#writable">writable</a> -
+ Select files (resources must be files) if they are writable.</li>
+ </ul>
+
+ <h4><a name="rsel.name">name</a></h4>
+ <p>Selects resources by name.</p>
+ <table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">name</td>
+ <td valign="top">The name pattern to test using standard Ant
+ patterns.</td>
+ <td valign="top" align="center" rowspan="2">Exactly one of
+ the two</td>
+ </tr>
+ <tr>
+ <td valign="top">regex</td>
+ <td valign="top">The regular expression matching files to select.</td>
+ </tr>
+ <tr>
+ <td valign="top">casesensitive</td>
+ <td valign="top">Whether name comparisons are case-sensitive</td>
+ <td align="center" valign="top">No, default <i>true</i></td>
+ </tr>
+ <tr>
+ <td valign="top">handledirsep</td>
+ <td valign="top">
+ If this is specified, the mapper will treat a \ character in a
+ resource name or name attribute as a / for the purposes of
+ matching. This attribute can be true or false, the default is
+ false.
+ <em>Since Ant 1.8.0.</em>
+ <td align="center" valign="top">No</td>
+ </tr>
+ </table>
+
+ <h4><a name="rsel.exists">exists</a></h4>
+ <p>Selects existing resources.</p>
+
+ <h4><a name="rsel.date">date</a></h4>
+ <p>Selects resources by date.</p>
+ <table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">millis</td>
+ <td valign="top">The comparison date/time in ms since January 1, 1970</td>
+ <td rowspan="2" align="center" valign="middle">One of these</td>
+ </tr>
+ <tr>
+ <td valign="top">datetime</td>
+ <td valign="top">The formatted comparison date/time</td>
+ </tr>
+ <tr>
+ <td valign="top">pattern</td>
+ <td valign="top">SimpleDateFormat-compatible pattern
+ for use with the <code>datetime</code> attribute</td>
+ <td align="center" valign="top">
+ No, default is "MM/DD/YYYY HH:MM AM_or_PM"</td>
+ </tr>
+ <tr>
+ <td valign="top">granularity</td>
+ <td valign="top">The number of milliseconds leeway to use when
+ comparing file modification times. This is needed because not
+ every file system supports tracking the last modified time to
+ the millisecond level.</td>
+ <td align="center" valign="top">No; default varies by platform:
+ FAT filesystems = 2 sec; Unix = 1 sec; NTFS = 1 ms.</td>
+ </tr>
+ <tr>
+ <td valign="top">when</td>
+ <td valign="top">One of "before", "after", "equal"</td>
+ <td align="center" valign="top">No, default "equal"</td>
+ </tr>
+ </table>
+
+ <h4><a name="rsel.type">type</a></h4>
+ <p>Selects resources by type (file or directory).</p>
+ <table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">type</td>
+ <td valign="top">One of "file", "dir", "any" (since Ant 1.8)</td>
+ <td align="center" valign="top">Yes</td>
+ </tr>
+ </table>
+
+ <h4><a name="rsel.size">size</a></h4>
+ <p>Selects resources by size.</p>
+ <table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">size</td>
+ <td valign="top">The size to compare</td>
+ <td align="center" valign="top">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">when</td>
+ <td valign="top">One of "equal", "eq", "greater", "gt", "less", "lt",
+ "ge" (greater or equal), "ne" (not equal), "le" (less or equal)</td>
+ <td align="center" valign="top">No, default "equal"</td>
+ </tr>
+ </table>
+
+ <h4><a name="rsel.instanceof">instanceof</a></h4>
+ <p>Selects resources by type.</p>
+ <table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">class</td>
+ <td valign="top">The class of which the resource must be an instance</td>
+ <td rowspan="2" align="center" valign="middle">One of these</td>
+ </tr>
+ <tr>
+ <td valign="top">type</td>
+ <td valign="top">The Ant type that must
+ be assignable from the resource</td>
+ </tr>
+ <tr>
+ <td valign="top">uri</td>
+ <td valign="top">The uri in which <i>type</i> must be defined</td>
+ <td valign="top">No</td>
+ </tr>
+ </table>
+
+ <h4><a name="rsel.and">and</a></h4>
+ <p>Selects a resource if it is selected by all nested resource selectors.</p>
+
+ <h4><a name="rsel.or">or</a></h4>
+ <p>Selects a resource if it is selected
+ by at least one nested resource selector.</p>
+
+ <h4><a name="rsel.not">not</a></h4>
+ <p>Negates the selection result of the single
+ nested resource selector allowed.</p>
+
+ <h4><a name="rsel.none">none</a></h4>
+ <p>Selects a resource if it is selected
+ by no nested resource selectors.</p>
+
+ <h4><a name="rsel.majority">majority</a></h4>
+ <p>Selects a resource if it is selected
+ by the majority of nested resource selectors.</p>
+ <table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">allowtie</td>
+ <td valign="top">Whether a tie (when there is an even number
+ of nested resource selectors) is considered a majority</td>
+ <td valign="top">No, default <i>true</i></td>
+ </tr>
+ </table>
+
+ <h4><a name="rsel.compare">compare</a></h4>
+ <p>Selects a resource based on its comparison to one or more "control"
+ resources using nested <a href="#rcmp">resource comparators</a>.</p>
+ <table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">when</td>
+ <td valign="top">Comparison ("equal"/"eq", "greater"/"gt", "less"/"lt",
+ "le" (less or equal), "ge" (greater or equal), "ne" (not equal).</td>
+ <td valign="top">No, default "equal"</td>
+ </tr>
+ <tr>
+ <td valign="top">against</td>
+ <td valign="top">Quantifier ("all"/"each"/"every", "any"/"some",
+ (exactly) "one", "most"/"majority", "none".</td>
+ <td valign="top">No, default "all"</td>
+ </tr>
+ </table>
+ <h4>Parameters specified as nested elements</h4>
+ <p>The resources against which comparisons will be made must be specified
+ using the nested &lt;control&gt; element, which denotes a
+ <a href="#resources">resources</a> collection.</p>
+ <h4>Examples</h4>
+ <p>Assuming the namespace settings
+<pre><code> rsel="antlib:org.apache.tools.ant.types.resources.selectors"
+ rcmp="antlib:org.apache.tools.ant.types.resources.comparators"
+</code></pre></p>
+ <pre>
+&lt;restrict&gt;
+ &lt;fileset dir="src" includes="a,b,c,d,e,f,g" /&gt;
+ &lt;rsel:compare when="le" against="all"&gt;
+ &lt;control&gt;
+ &lt;resource name="d" /&gt;
+ &lt;/control&gt;
+ &lt;rcmp:name /&gt;
+ &lt;/rsel:compare&gt;
+&lt;/restrict&gt;
+ </pre>
+ <p>Selects files a, b, c, and d.</p>
+ <pre>
+ &lt;project rsel=&quot;antlib:org.apache.tools.ant.types.resources.selectors&quot;&gt;
+ &lt;macrodef name=&quot;copyFromPath&quot;&gt;
+ &lt;attribute name=&quot;todir&quot;/&gt;
+ &lt;attribute name=&quot;refid&quot;/&gt;
+ &lt;element name=&quot;nested-resource-selectors&quot; optional=&quot;yes&quot; implicit=&quot;true&quot;/&gt;
+ &lt;sequential&gt;
+ &lt;mkdir dir=&quot;@{todir}&quot; taskname=&quot;copyFromPath&quot;/&gt;
+ &lt;copy todir=&quot;@{todir}&quot; taskname=&quot;copyFromPath&quot;&gt;
+ &lt;restrict&gt;
+ &lt;path refid=&quot;@{refid}&quot;/&gt;
+ &lt;rsel:or&gt;
+ &lt;nested-resource-selectors/&gt;
+ &lt;/rsel:or&gt;
+ &lt;/restrict&gt;
+ &lt;flattenmapper/&gt;
+ &lt;/copy&gt;
+ &lt;/sequential&gt;
+ &lt;/macrodef&gt;
+ &lt;copyFromPath refid=&quot;classpath&quot; todir=&quot;todir&quot;&gt;
+ &lt;rsel:name name=&quot;log4j.properties&quot;/&gt;
+ &lt;rsel:name name=&quot;default.properties&quot;/&gt;
+ &lt;/copyFromPath&gt;
+ &lt;/project&gt;
+ </pre>
+ <p>Creates the <tt>todir</tt> directory and copies (if present) the
+ files <tt>log4j.properties</tt> and <tt>default.properties</tt>
+ from the Classpath (already used while compiling).
+ </p>
+
+ <pre>
+ &lt;project&gt;
+ &lt;filelist id=&quot;allfiles&quot; dir=&quot;${ant.home}/bin&quot; files=&quot;ant.cmd,foo.txt,ant.bat,bar.txt,ant&quot;/&gt;
+ &lt;restrict id=&quot;missingfiles&quot;&gt;
+ &lt;filelist refid=&quot;allfiles&quot;/&gt;
+ &lt;rsel:not xmlns:rsel=&quot;antlib:org.apache.tools.ant.types.resources.selectors&quot;&gt;
+ &lt;rsel:exists/&gt;
+ &lt;/rsel:not&gt;
+ &lt;/restrict&gt;
+ &lt;echo&gt;These files are missed: ${toString:missingfiles}&lt;/echo&gt;
+ &lt;/project&gt;
+ </pre>
+ <p>The resource collection <i>allfiles</i> defines a list of files which are expected. The restrict
+ <i>missingfiles</i> uses the <tt>&lt;not&gt;&lt;exists&gt;</tt> selector for getting all files
+ which are not present. Finally we use the <i>toString:</i> <a href="../using.html#pathshortcut">pathshortcut</a> for
+ getting them in a readable form: <tt>[echo] These files are missed: ....foo.txt;....bar.txt</tt></p>
+
+</blockquote>
+
+<h4><a name="sort">sort</a></h4>
+
+<p>Sorts a nested resource collection according to the resources'
+ natural order, or by one or more nested <a href="#rcmp">resource
+ comparators</a>:</p>
+<blockquote>
+ <table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">cache</td>
+ <td valign="top">Whether to cache results; disabling
+ may seriously impact performance</td>
+ <td valign="top" align="center">No, default <i>true</i></td>
+ </tr>
+ </table>
+ <h4>Parameters specified as nested elements</h4>
+ <p>A single resource collection is required.</p>
+ <p>The sort can be controlled and customized by specifying one or more
+ resource comparators. Resources can be sorted according to multiple
+ criteria; the first specified is the "outermost", while the last
+ specified is the "innermost". Several built-in resource comparators
+ are available in the internal <a href="antlib.html">antlib</a>
+ <code>org.apache.tools.ant.types.resources.comparators</code>:
+ </p>
+ <h4><a name="rcmp">Resource Comparators:</a></h4>
+ <ul>
+ <li><a href="#rcmp.name">name</a> - sort resources by name</li>
+ <li><a href="#rcmp.exists">exists</a> - sort resources by existence</li>
+ <li><a href="#rcmp.date">date</a> - sort resources by date</li>
+ <li><a href="#rcmp.type">type</a> - sort resources by type</li>
+ <li><a href="#rcmp.size">size</a> - sort resources by size</li>
+ <li><a href="#rcmp.content">content</a> - sort resources by content</li>
+ <li><a href="#rcmp.reverse">reverse</a> - reverse the natural sort order,
+ or that of a single nested resource comparator</li>
+ </ul>
+
+ <h4><a name="rcmp.name">name</a></h4>
+ <p>Sort resources by name.</p>
+
+ <h4><a name="rcmp.exists">exists</a></h4>
+ <p>Sort resources by existence.
+ Not existing is considered "less than" existing.</p>
+
+ <h4><a name="rcmp.date">date</a></h4>
+ <p>Sort resources by date.</p>
+
+ <h4><a name="rcmp.type">type</a></h4>
+ <p>Sort resources by type (file or directory).
+ Because directories contain files, they are considered "greater".</p>
+
+ <h4><a name="rcmp.size">size</a></h4>
+ <p>Sort resources by size.</p>
+
+ <h4><a name="rcmp.content">content</a></h4>
+ <p>Sort resources by content.</p>
+ <table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">binary</td>
+ <td valign="top">Whether content should be compared in binary mode.
+ If <i>false<i>, content will be compared without regard to
+ platform-specific line-ending conventions.</td>
+ <td valign="top">No, default <i>true</i></td>
+ </tr>
+ </table>
+
+ <h4><a name="rcmp.reverse">reverse</a></h4>
+ <p>Reverse the natural sort order, or that of a single nested comparator.</p>
+
+ <h4>Examples</h4>
+ <pre>
+ &lt;property name=&quot;eol&quot; value=&quot;${line.separator}&quot; /&gt;
+ &lt;pathconvert property=&quot;sorted&quot; pathsep=&quot;${eol}&quot;&gt;
+ &lt;sort&gt;
+ &lt;tokens&gt;
+ &lt;string value=&quot;foo bar etc baz&quot; /&gt;
+ &lt;stringtokenizer /&gt;
+ &lt;/tokens&gt;
+ &lt;/sort&gt;
+ &lt;/pathconvert&gt;</pre>
+ <p>The resource of type string &quot;foo bar etc baz&quot; is split into four tokens by
+ the stringtokenizer. These tokens are sorted and there <i>sorted</i> gets the value
+ of &quot;bar baz etc foo&quot;.</p>
+
+ <pre>
+ &lt;sort&gt;
+ &lt;fileset dir=&quot;foo&quot; /&gt;
+ &lt;reverse xmlns=&quot;antlib:org.apache.tools.ant.types.resources.comparators&quot;&gt;
+ &lt;date /&gt;
+ &lt;/reverse&gt;
+ &lt;/sort&gt;</pre>
+ <p>This takes all files from <i>foo</i>
+ and sorts them by modification date in reverse order.
+ Because the resource comparators used (<code>&lt;reverse&gt;</code>
+ and <code>&lt;date&gt;</code>) are in an internal antlib
+ their namespace must be set explicitly.
+ </p>
+
+</blockquote>
+
+<h4><a name="first">first</a></h4>
+<p>Includes the first <i>count</i> resources from a nested resource collection.
+This can be used in conjunction with the <a href="#sort">sort</a> collection,
+for example, to select the first few oldest, largest, etc. resources from a
+larger collection.</p>
+<blockquote>
+ <table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">count</td>
+ <td valign="top">The number of resources to include</td>
+ <td valign="top" align="center">No, default 1</td>
+ </tr>
+ <tr>
+ <td valign="top">cache</td>
+ <td valign="top">Whether to cache results; disabling
+ may seriously impact performance</td>
+ <td valign="top" align="center">No, default <i>true</i></td>
+ </tr>
+ </table>
+ <h4>Parameters specified as nested elements</h4>
+ <p>A single resource collection is required.</p>
+</blockquote>
+
+<h4><a name="last">last</a></h4>
+<p>Includes the last <i>count</i> resources from a nested resource collection.
+This can be used in conjunction with the <a href="#sort">sort</a> collection,
+for example, to select the last few oldest, largest, etc. resources from a
+larger collection. <strong>Since Ant 1.7.1</strong>.</p>
+<blockquote>
+ <table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">count</td>
+ <td valign="top">The number of resources to include</td>
+ <td valign="top" align="center">No, default 1</td>
+ </tr>
+ <tr>
+ <td valign="top">cache</td>
+ <td valign="top">Whether to cache results; disabling
+ may seriously impact performance</td>
+ <td valign="top" align="center">No, default <i>true</i></td>
+ </tr>
+ </table>
+ <h4>Parameters specified as nested elements</h4>
+ <p>A single resource collection is required.</p>
+</blockquote>
+
+<h4><a name="allbutfirst">allbutfirst</a></h4>
+<p>Includes all elements except for the first <i>count</i> resources
+from a nested resource collection. This can be used in conjunction
+with the <a href="#sort">sort</a> collection, for example, to select
+all but the first few oldest, largest, etc. resources from a larger
+collection. <strong>Since Ant 1.9.5</strong>.</p>
+<blockquote>
+ <table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">count</td>
+ <td valign="top">The number of resources to exclude</td>
+ <td valign="top" align="center">No, default 1</td>
+ </tr>
+ <tr>
+ <td valign="top">cache</td>
+ <td valign="top">Whether to cache results; disabling
+ may seriously impact performance</td>
+ <td valign="top" align="center">No, default <i>true</i></td>
+ </tr>
+ </table>
+ <h4>Parameters specified as nested elements</h4>
+ <p>A single resource collection is required.</p>
+</blockquote>
+
+<h4><a name="allbutlast">allbutlast</a></h4>
+<p>Includes all elements except for the last <i>count</i> resources
+from a nested resource collection. This can be used in conjunction
+with the <a href="#sort">sort</a> collection, for example, to select
+all but the last few oldest, largest, etc. resources from a larger
+collection. <strong>Since Ant 1.9.5</strong>.</p>
+<blockquote>
+ <table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">count</td>
+ <td valign="top">The number of resources to exclude</td>
+ <td valign="top" align="center">No, default 1</td>
+ </tr>
+ <tr>
+ <td valign="top">cache</td>
+ <td valign="top">Whether to cache results; disabling
+ may seriously impact performance</td>
+ <td valign="top" align="center">No, default <i>true</i></td>
+ </tr>
+ </table>
+ <h4>Parameters specified as nested elements</h4>
+ <p>A single resource collection is required.</p>
+</blockquote>
+
+<h4><a name="tokens">tokens</a></h4>
+<p>Includes the <a href="#string">string</a> tokens gathered from a nested
+ resource collection. Uses the same tokenizers supported by the
+<a href="filterchain.html#tokenfilter">TokenFilter</a>. Imaginative
+ use of this resource collection can implement equivalents for such Unix
+ functions as <code>sort</code>, <code>grep -c</code>, <code>wc</code> and
+ <code>wc -l</code>.</p>
+<blockquote>
+ <table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">encoding</td>
+ <td valign="top">The encoding of the nested resources</td>
+ <td valign="top" align="center">No, default is platform default</td>
+ </tr>
+ <tr>
+ <td valign="top">cache</td>
+ <td valign="top">Whether to cache results; disabling
+ may seriously impact performance</td>
+ <td valign="top" align="center">No, default <i>true</i></td>
+ </tr>
+ </table>
+ <h4>Parameters specified as nested elements</h4>
+ <ul>
+ <li>A single resource collection is required.</li>
+ <li>One nested tokenizer may be specified. If omitted, a
+ <a href="filterchain.html#linetokenizer">LineTokenizer</a> will be used.
+ </li>
+ </ul>
+ <h4>Examples</h4>
+ <pre>&lt;concat&gt;
+ &lt;union&gt;
+ &lt;sort&gt;
+ &lt;tokens&gt;
+ &lt;resources refid="input" /&gt;
+ &lt;linetokenizer includedelims="true" /&gt;
+ &lt;/tokens&gt;
+ &lt;/sort&gt;
+ &lt;/union&gt;
+&lt;/concat&gt;
+ </pre>
+ <p>Implements Unix <i>sort -u</i> against resource collection <i>input</i>.</p>
+</blockquote>
+
+<h4><a name="setlogic">Set operations</a></h4>
+<blockquote>
+ <p>The following resource collections implement set operations:</p>
+ <ul>
+ <li><a href="#union">union</a></li>
+ <li><a href="#intersect">intersect</a></li>
+ <li><a href="#difference">difference</a></li>
+ </ul>
+
+ <h4><a name="union">union</a></h4>
+ <p>Union of nested resource collections.</p>
+
+ <h4><a name="intersect">intersect</a></h4>
+ <p>Intersection of nested resource collections.</p>
+
+ <h4><a name="difference">difference</a></h4>
+ <p>Difference of nested resource collections.</p>
+
+ <p>The following attributes apply to all set-operation resource collections:
+ </p>
+ <table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">cache</td>
+ <td valign="top">Whether to cache results; disabling
+ may seriously impact performance</td>
+ <td valign="top" align="center">No, default <i>true</i></td>
+ </tr>
+ </table>
+
+ <h4>Examples</h4>
+ <pre>
+ &lt;resources id=&quot;A&quot;&gt;
+ &lt;string value=&quot;a&quot;/&gt;
+ &lt;string value=&quot;b&quot;/&gt;
+ &lt;/resources&gt;
+ &lt;resources id=&quot;B&quot;&gt;
+ &lt;string value=&quot;b&quot;/&gt;
+ &lt;string value=&quot;c&quot;/&gt;
+ &lt;/resources&gt;
+ &lt;union id=&quot;union&quot;&gt;&lt;resources refid=&quot;A&quot;/&gt;&lt;resources refid=&quot;B&quot;/&gt;&lt;/union&gt;
+ &lt;intersect id=&quot;intersect&quot;&gt;&lt;resources refid=&quot;A&quot;/&gt;&lt;resources refid=&quot;B&quot;/&gt;&lt;/intersect&gt;
+ &lt;difference id=&quot;difference&quot;&gt;&lt;resources refid=&quot;A&quot;/&gt;&lt;resources refid=&quot;B&quot;/&gt;&lt;/difference&gt;
+ &lt;echo&gt;
+ A: ${toString:A} = a;b
+ B: ${toString:B} = b;c
+
+ union : ${toString:union} = a;b;c
+ intersect : ${toString:intersect} = b
+ difference: ${toString:difference} = a;c
+ &lt;/echo&gt;
+ </pre>
+</blockquote>
+
+<h4><a name="mappedresources">mappedresources</a></h4>
+
+<p><em>Since Ant 1.8.0</em></p>
+
+<p>Wraps another resource collection and maps the names of the nested
+ resources using a <a href="mapper.html">mapper</a>.</p>
+
+<p>Even if <em>mappedresources</em> wraps a resource collection that
+ consists of file-system based resources, <em>mappedresources</em>
+ will not appear to be file-system based. This means you can't
+ use <em>mappedresources</em> with tasks that only allow file-system
+ based resources.</p>
+
+<blockquote>
+ <h4>Parameters specified as attributes</h4>
+
+ <table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">cache</td>
+ <td valign="top">Whether to cache results; enabling
+ may improve performance. <em>Since Ant 1.8.1</em></td>
+ <td valign="top" align="center">No, default <i>false</i></td>
+ </tr>
+ <tr>
+ <td valign="top">enablemultiplemappings</td>
+ <td valign="top">
+ If true the the collection will use all the mappings for a
+ given source path. If false the it will only process the first
+ resource.
+ <em>since Ant 1.8.1</em>.</td>
+ <td align="center">No - defaults to false.</td>
+ </tr>
+ </table>
+
+ <h4>Parameters specified as nested elements</h4>
+ <p>A single resource collection is required.</p>
+ <p>A single <a href="mapper.html">mapper</a> can be used to map
+ names. If no mapper has been given (which doesn't make any sense,
+ honestly), an identity mapper will be used.</p>
+
+ <h4>Examples</h4>
+
+ <p>Copies all files from a given directory to a target directory
+ adding ".bak" as an extension. Note this could be done with a
+ <em>mapper</em> nested into <em>copy</em> directly as well.</p>
+
+ <pre>
+ &lt;copy todir="${target}"&gt;
+ &lt;mappedresources&gt;
+ &lt;fileset dir="${src}"/&gt;
+ &lt;globmapper from="*" to="*.bak"/&gt;
+ &lt;/mappedresources&gt;
+ &lt;/copy&gt;
+ </pre>
+
+ <p>Creates a WAR archive adding all CLASSPATH entries that are files
+ to the <code>WEB-INF/lib</code> directory without keeping their
+ files-system structure.</p>
+
+ <pre>
+ &lt;war destfile="${output}"&gt;
+ &lt;mappedresources&gt;
+ &lt;restrict&gt;
+ &lt;path path="${java.class.path}"/&gt;
+ &lt;type type="file"/&gt;
+ &lt;/restrict&gt;
+ &lt;chainedmapper&gt;
+ &lt;flattenmapper/&gt;
+ &lt;globmapper from="*" to="WEB-INF/lib/*"/&gt;
+ &lt;/chainedmapper&gt;
+ &lt;/mappedresources&gt;
+ &lt;/war&gt;
+ </pre>
+</blockquote>
+
+<h4><a name="archives">archives</a></h4>
+
+<p><em>Since Ant 1.8.0</em></p>
+
+<p>This resource collection accepts an arbitrary number of nested
+ resources and assumes that all those resources must be either ZIP or
+ TAR archives. The resources returned
+ by <code>&lt;archives&gt;</code> are the contents of the nested
+ archives.</p>
+
+<p>This resource collection is a generalization
+ of <a href="../Tasks/zip.html#zipgroupfileset">zipgroupfileset</a>
+ which is only supported by the zip family of tasks.</p>
+
+<p><em>archives</em> doesn't support any attributes.</p>
+
+<blockquote>
+ <h4>Parameters specified as nested elements</h4>
+
+ <p><code>&lt;archives&gt;</code> has two nested
+ elements <code>&lt;zips&gt;</code> and
+ <code>&lt;tars&gt;</code> that are <a href="#union">unions</a>
+ themselves, i.e. they accept arbitrary many resource(collection)s
+ as nested elements.</p>
+
+ <p>The nested resources of &lt;zips&gt; are treated as ZIP archives,
+ the nested resources of &lt;tars&gt; as TAR archives.</p>
+
+ <h4>Examples</h4>
+
+ <p>Copies all files from all jars that are on the classpath
+ to <code>${target}</code>.</p>
+
+ <pre>
+ &lt;copy todir="${target}"&gt;
+ &lt;archives&gt;
+ &lt;zips&gt;
+ &lt;restrict&gt;
+ &lt;path path="${java.class.path}"/&gt;
+ &lt;name name="*.jar"/&gt;
+ &lt;/restrict&gt;
+ &lt;/zips&gt;
+ &lt;/archives&gt;
+ &lt;/copy&gt;
+ </pre>
+</blockquote>
+
+<h4><a name="resourcelist">resourcelist</a></h4>
+
+<p><em>Since Ant 1.8.0</em></p>
+
+<p>This resource collection accepts an arbitrary number of nested
+ resources, reads those resources and returns a resource for each
+ line read.</p>
+
+<p>If the line contains a colon, Ant will try to use it as an URL and
+ if that fails (or the line doesn't contain a colon) will return a
+ file resource with the line's content as its name.</p>
+
+<p>Properties will be expanded for each line. If the property
+ expansion yields a resource object rather than a string (for example
+ because of custom property helpers), the resources will be returned
+ directly.</p>
+
+<p><code>&lt;resourcelist&gt;</code> is a generalization
+ of <a href="filelist.html"><code>&lt;filelist&gt;</code></a>.</p>
+
+<blockquote>
+ <table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">encoding</td>
+ <td valign="top">The encoding of the nested resources</td>
+ <td valign="top" align="center">No, default is platform default</td>
+ </tr>
+ </table>
+</blockquote>
+
+<blockquote>
+ <h4>Parameters specified as nested elements</h4>
+
+ <p><code>&lt;resourcelist&gt;</code> accepts arbitrary many
+ resource(collection)s as nested elements.</p>
+
+ <p>In addition <code>&lt;resourcelist&gt;</code> supports
+ nested <code>&lt;filterchain&gt;</code> elements that can be used
+ to filter/modify the read resources before their lines get
+ expanded. Such a nested element corresponds to
+ a <a href="filterchain.html">filterchain</a>.</p>
+
+ <h4>Examples</h4>
+
+ <p>The following example copies a file from the first URL of
+ several alternatives that can actually be reached. It assumes
+ that the file mirrors.txt looks like</p>
+
+ <pre>
+ mirrors.txt:
+http://best.mirror.example.org/
+http://second.best.mirror.example.org/mirror/of/best/
+https://yet.another.mirror/
+http://the.original.site/
+ </pre>
+
+ <pre>
+ &lt;copy todir="${target}"&gt;
+ &lt;first&gt;
+ &lt;restrict&gt;
+ &lt;resourcelist&gt;
+ &lt;file file="mirrors.txt"/&gt;
+ &lt;/resourcelist&gt;
+ &lt;exists/&gt;
+ &lt;/restrict&gt;
+ &lt;/first&gt;
+ &lt;/copy&gt;
+ </pre>
+</blockquote>
+
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Types/selectors-program.html b/framework/src/ant/apache-ant-1.9.6/manual/Types/selectors-program.html
new file mode 100644
index 00000000..074a5426
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Types/selectors-program.html
@@ -0,0 +1,244 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+ <head>
+ <meta http-equiv="Content-Language" content="en-us">
+ <link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>Programming Selectors in Apache Ant</title>
+ </head>
+
+ <body>
+ <h2>Programming your own Selectors</h2>
+
+ <h3>Selector Programming API</h3>
+
+ <p>Want to define your own selectors? It's easy!</p>
+
+ <p>First, pick the type of selector that you want to define. There
+ are three types, and a recipe for each one follows. Chances are
+ you'll want to work with the first one, Custom Selectors.</p>
+
+ <ol>
+ <li>Custom Selectors
+
+ <p>This is the category that Apache Ant provides specifically for you to
+ define your own Selectors. Anywhere you want to use your selector
+ you use the <code>&lt;custom&gt;</code> element and specify
+ the class name of your selector within it. See the
+ <a href="selectors.html#customselect">Custom Selectors</a>
+ section of the Selector page for details. The
+ <code>&lt;custom&gt;</code> element can be used anywhere
+ the core selectors can be used. It can be contained within
+ <a href="selectors.html#selectcontainers">Selector Containers</a>,
+ for example.</p>
+
+ <p>To create a new Custom Selector, you have to create a class that
+ implements
+ <code>org.apache.tools.ant.types.selectors.ExtendFileSelector</code>.
+ The easiest way to do that is through the convenience base class
+ <code>org.apache.tools.ant.types.selectors.BaseExtendSelector</code>,
+ which provides all of the methods for supporting
+ <code>&lt;param&gt;</code> tags. First, override the
+ <code>isSelected()</code> method, and optionally the
+ <code>verifySettings()</code> method. If your custom
+ selector requires parameters to be set, you can also override
+ the <code>setParameters()</code> method and interpret the
+ parameters that are passed in any way you like. Several of the
+ core selectors demonstrate how to do that because they can
+ also be used as custom selectors.</p>
+
+ <li>Core Selectors
+
+ <p>These are the selectors used by Ant itself. To implement one of
+ these, you will have to alter some of the classes contained within
+ Ant.</p>
+
+ <ul>
+ <li><p>First, create a class that implements
+ <code>org.apache.tools.ant.types.selectors.FileSelector</code>.
+ You can either choose to implement all methods yourself from
+ scratch, or you can extend
+ <code>org.apache.tools.ant.types.selectors.BaseSelector</code>
+ instead, a convenience class that provides reasonable default
+ behaviour for many methods.</p>
+
+ <p>There is only one method required.
+ <code>public boolean isSelected(File basedir, String filename,
+ File file)</code>
+ is the real purpose of the whole exercise. It returns true
+ or false depending on whether the given file should be
+ selected from the list or not.</p>
+
+ <p>If you are using
+ <code>org.apache.tools.ant.types.selectors.BaseSelector</code>
+ there are also some predefined behaviours you can take advantage
+ of. Any time you encounter a problem when setting attributes or
+ adding tags, you can call setError(String errmsg) and the class
+ will know that there is a problem. Then, at the top of your
+ <code>isSelected()</code> method call <code>validate()</code> and
+ a BuildException will be thrown with the contents of your error
+ message. The <code>validate()</code> method also gives you a
+ last chance to check your settings for consistency because it
+ calls <code>verifySettings()</code>. Override this method and
+ call <code>setError()</code> within it if you detect any
+ problems in how your selector is set up.</p>
+
+ <p>You may also want to override <code>toString()</code>.</p>
+
+ <li><p>Put an <code>add</code> method for your selector in
+ <code>org.apache.tools.ant.types.selectors.SelectorContainer</code>.
+ This is an interface, so you will also have to add an implementation
+ for the method in the classes which implement it, namely
+ <code>org.apache.tools.ant.types.AbstractFileSet</code>,
+ <code>org.apache.tools.ant.taskdefs.MatchingTask</code> and
+ <code>org.apache.tools.ant.types.selectors.BaseSelectorContainer</code>.
+ Once it is in there, it will be available everywhere that core
+ selectors are appropriate.</p>
+ </ul>
+
+ <li>Selector Containers
+ <p>Got an idea for a new Selector Container? Creating a new one is
+ no problem:</p>
+ <ul>
+ <li><p>Create a new class that implements
+ <code>org.apache.tools.ant.types.selectors.SelectorContainer</code>.
+ This will ensure that your new
+ Container can access any new selectors that come along. Again, there
+ is a convenience class available for you called
+ <code>org.apache.tools.ant.types.selectors.BaseSelectorContainer</code>.
+ </p>
+ <li><p>Implement the
+ <code>public boolean isSelected(String filename, File file)</code>
+ method to do the right thing. Chances are you'll want to iterate
+ over the selectors under you, so use
+ <code>selectorElements()</code> to get an iterator that will do
+ that.</p>
+ <li><p>Again, put an <code>add</code> method for your container in
+ <code>org.apache.tools.ant.types.selectors.SelectorContainer</code>
+ and its implementations
+ <code>org.apache.tools.ant.types.AbstractFileSet</code> and
+ <code>org.apache.tools.ant.types.selectors.BaseSelectorContainer</code>.
+ </p>
+ </ul>
+ </ol>
+
+ <h3>Testing Selectors</h3>
+
+ <p>For a robust component (and selectors are (Project)Components) tests are
+ necessary. For testing Tasks we use JUnit TestCases - more specific
+ <tt>org.apache.tools.ant.BuildFileRule extends org.junit.rules.ExternalResource</tt>.
+ Some of its features like configure the (test) project by reading its buildfile and
+ execute targets we need for selector tests also. Therefore we use that BuildFileRule.
+ But testing selectors requires some more work: having a set of files, instantiate
+ and configure the selector, check the selection work and more. Because we usually
+ extend <tt>BaseExtendSelector</tt> its features have to be tested also (e.g. setError()).
+ </p>
+
+ <p>That's why we have a test rule for doing our selector tests:
+ <tt>org.apache.tools.ant.types.selectors.BaseSelectorRule</tt>.</p>
+
+ <p>This class extends ExternalResource and therefore can included in the set of Ant's
+ unit tests. It holds an instance of preconfigured BuildFileRule. Configuration
+ is done by parsing the src/etc/testcases/types/selectors.xml. BaseSelectorRule
+ then gives us helper methods for handling multiple selections. </p>
+
+ <p>Because the term "testcase" or "testenvironment" are so often used, this
+ special testenvironment got a new name: <i>bed</i>. The setup and cleanup of
+ the bed is all handled by the BaseSelectorRule so any test only has to handle
+ the actual test scenarios</p>
+
+ <p>A usual test scenario is:</p>
+ <ol>
+ <li>instantiate the selector</li>
+ <li>configure the selector</li>
+ <li>let the selector do some work</li>
+ <li>verify the work</li>
+ </ol>
+
+
+
+ <p>An example test would be:<pre>
+package org.apache.tools.ant.types.selectors;
+
+public class MySelectorTest {
+
+ @Rule
+ public final BaseSelectorRule selectorRule = new BaseSelectorRule();
+
+ @Test
+ public void testCase1() {
+
+
+ // Configure the selector
+ MySelector s = new MySelector();
+ s.addParam("key1", "value1");
+ s.addParam("key2", "value2");
+ s.setXX(true);
+ s.setYY("a value");
+
+ // do the tests
+ assertEquals("FTTTTTTTT", selectorRule.selectionString(s));
+ }
+}
+ </pre>
+ As an example of an error JUnit could log<pre>
+ [junit] FAILED
+ [junit] Error for files: <font color=blue>.;copy.filterset.filtered;tar/gz/asf-logo.gif.tar.gz</font>
+ [junit] expected:&lt;<font color=blue>FTTTFTTTF...</font>&gt; but was:&lt;TTTTTTTTT...&gt;
+ [junit] junit.framework.ComparisonFailure: Error for files: .;copy.filterset.filtered;tar/gz/asf-logo.gif.tar.gz
+ [junit] expected:&lt;FTTTFTTTF...&gt; but was:&lt;TTTTTTTTT...&gt;
+ [junit] at junit.framework.Assert.assertEquals(Assert.java:81)
+ [junit] at org.apache.tools.ant.types.selectors.BaseSelectorTest.performTest(BaseSelectorTest.java:194)
+ </pre></p>
+
+ <p>Described above the test class should provide a <tt>getInstance()</tt>
+ method. But that isn't used here. The used <tt>getSelector()</tt> method is
+ implemented in the base class and gives an instance of an Ant Project to
+ the selector. This is usually done inside normal build file runs, but not
+ inside this special environment, so this method gives the selector the
+ ability to use its own Project object (<tt>getProject()</tt>), for example
+ for logging.</p>
+
+
+ <h3>Logging</h3>
+
+ <p>During development and maybe later you sometimes need the output of information.
+ Therefore Logging is needed. Because the selector extends BaseExtendSelector or directly
+ BaseSelector it is an Ant <tt>DataType</tt> and therefore a <tt>ProjectComponent</tt>. <br>
+ That means that you have access to the project object and its logging capability.
+ <tt>ProjectComponent</tt> itself provides <i>log</i> methods which will do the
+ access to the project instance. Logging is therefore done simply with:
+ <pre>
+ log( "message" );
+ </pre>
+ or
+ <pre>
+ log( "message" , loglevel );
+ </pre>
+ where the <tt>loglevel</tt> is one of the values <ul>
+ <li> org.apache.tools.ant.Project.MSG_ERR </li>
+ <li> org.apache.tools.ant.Project.MSG_WARN </li>
+ <li> org.apache.tools.ant.Project.MSG_INFO (= default) </li>
+ <li> org.apache.tools.ant.Project.MSG_VERBOSE </li>
+ <li> org.apache.tools.ant.Project.MSG_DEBUG </li>
+ </ul>
+ </p>
+
+
+ </body>
+
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Types/selectors.html b/framework/src/ant/apache-ant-1.9.6/manual/Types/selectors.html
new file mode 100644
index 00000000..560b416c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Types/selectors.html
@@ -0,0 +1,1566 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+ <head>
+ <meta http-equiv="Content-Language" content="en-us">
+ <link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+ <title>Selectors in Apache Ant</title>
+ </head>
+
+ <body>
+ <h2>Selectors</h2>
+
+ <p>Selectors are a mechanism whereby the files that make up a
+ <code>&lt;fileset&gt;</code> can be selected based on criteria
+ other than filename as provided by the <code>&lt;include&gt;</code>
+ and <code>&lt;exclude&gt;</code> tags.</p>
+
+ <h3>How to use a Selector</h3>
+
+ <p>A selector is an element of FileSet, and appears within it. It can
+ also be defined outside of any target by using the <code>&lt;selector&gt;</code> tag
+ and then using it as a reference.
+ </p>
+
+ <p>Different selectors have different attributes. Some selectors can
+ contain other selectors, and these are called
+ <a href="#selectcontainers"><code>Selector Containers</code></a>.
+ There is also a category of selectors that allow
+ user-defined extensions, called
+ <a href="#customselect"><code>Custom Selectors</code></a>.
+ The ones built in to Apache Ant are called
+ <a href="#coreselect"><code>Core Selectors</code></a>.
+ </p>
+
+ <h3><a name="coreselect">Core Selectors</a></h3>
+
+ <p>Core selectors are the ones that come standard
+ with Ant. They can be used within a fileset and can be contained
+ within Selector Containers.</p>
+
+ <p>The core selectors are:</p>
+
+ <ul>
+ <li><a href="#containsselect"><code>&lt;contains&gt;</code></a> - Select
+ files that contain a particular text string</li>
+ <li><a href="#dateselect"><code>&lt;date&gt;</code></a> - Select files
+ that have been modified either before or after a particular date
+ and time</li>
+ <li><a href="#dependselect"><code>&lt;depend&gt;</code></a> - Select files
+ that have been modified more recently than equivalent files
+ elsewhere</li>
+ <li><a href="#depthselect"><code>&lt;depth&gt;</code></a> - Select files
+ that appear so many directories down in a directory tree</li>
+ <li><a href="#differentselect"><code>&lt;different&gt;</code></a> - Select files
+ that are different from those elsewhere</li>
+ <li><a href="#filenameselect"><code>&lt;filename&gt;</code></a> - Select
+ files whose name matches a particular pattern. Equivalent to
+ the include and exclude elements of a patternset.</li>
+ <li><a href="#presentselect"><code>&lt;present&gt;</code></a> - Select
+ files that either do or do not exist in some other location</li>
+ <li><a href="#regexpselect"><code>&lt;containsregexp&gt;</code></a> - Select
+ files that match a regular expression</li>
+ <li><a href="#sizeselect"><code>&lt;size&gt;</code></a> - Select files
+ that are larger or smaller than a particular number of bytes.</li>
+ <li><a href="#typeselect"><code>&lt;type&gt;</code></a> - Select files
+ that are either regular files or directories.</li>
+ <li><a href="#modified"><code>&lt;modified&gt;</code></a> - Select files if
+ the return value of the configured algorithm is different from that
+ stored in a cache.</li>
+ <li><a href="#signedselector"><code>&lt;signedselector&gt;</code></a> - Select files if
+ they are signed, and optionally if they have a signature of a certain name.
+ </li>
+ <li><a href="#scriptselector"><code>&lt;scriptselector&gt;</code></a> -
+ Use a BSF or JSR 223 scripting language to create
+ your own selector
+ </li>
+ <li><a href="#readable"><code>&lt;readable&gt;</code></a> -
+ Select files if they are readable.</li>
+ <li><a href="#writable"><code>&lt;writable&gt;</code></a> -
+ Select files if they are writable.</li>
+ </ul>
+
+ <h4><a name="containsselect">Contains Selector</a></h4>
+
+ <p>The <code>&lt;contains&gt;</code> tag in a FileSet limits
+ the files defined by that fileset to only those which contain the
+ string specified by the <code>text</code> attribute.
+ .</p>
+ <p>The <code>&lt;contains&gt;</code> selector can be used as a
+ ResourceSelector (see the
+ <a href="resources.html#restrict">&lt;restrict&gt;</a>
+ ResourceCollection).</p>
+
+ <table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">text</td>
+ <td valign="top">Specifies the text that every file must contain
+ </td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">casesensitive</td>
+ <td valign="top">Whether to pay attention to case when looking
+ for the string in the <code>text</code> attribute. Default is
+ true.
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">ignorewhitespace</td>
+ <td valign="top">Whether to eliminate whitespace before checking
+ for the string in the <code>text</code> attribute. Default is
+ false.
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">encoding</td>
+ <td valign="top">Encoding of the resources being selected.
+ Required in practice if the encoding of the files being
+ selected is different from the default encoding of the JVM
+ where Ant is running.
+ Since Ant 1.9.0
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ </table>
+
+ <p>Here is an example of how to use the Contains Selector:</p>
+
+ <blockquote><pre>
+&lt;fileset dir=&quot;${doc.path}&quot; includes=&quot;**/*.html&quot;&gt;
+ &lt;contains text=&quot;script&quot; casesensitive=&quot;no&quot;/&gt;
+&lt;/fileset&gt;
+</pre></blockquote>
+
+ <p>Selects all the HTML files that contain the string
+ <code>script</code>.</p>
+
+
+ <h4><a name="dateselect">Date Selector</a></h4>
+
+ <p>The <code>&lt;date&gt;</code> tag in a FileSet will put
+ a limit on the files specified by the include tag, so that tags
+ whose last modified date does not meet the date limits specified
+ by the selector will not end up being selected.</p>
+
+ <table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">datetime</td>
+ <td valign="top">Specifies the date and time to test for.
+ Should be in the format MM/DD/YYYY HH:MM AM_or_PM, or
+ an alternative pattern specified via the <i>pattern</i>
+ attribute.
+ </td>
+ <td valign="top" align="center" rowspan="2">At least one of the two.</td>
+ </tr>
+ <tr>
+ <td valign="top">millis</td>
+ <td valign="top">The number of milliseconds since 1970 that should
+ be tested for. It is usually much easier to use the datetime
+ attribute.
+ </td>
+ </tr>
+ <tr>
+ <td valign="top">when</td>
+ <td valign="top">Indicates how to interpret the date, whether
+ the files to be selected are those whose last modified times should
+ be before, after, or equal to the specified value. Acceptable
+ values for this attribute are:
+ <ul>
+ <li>before - select files whose last modified date is before the indicated date
+ <li>after - select files whose last modified date is after the indicated date
+ <li>equal - select files whose last modified date is this exact date
+ </ul>
+ The default is equal.
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">granularity</td>
+ <td valign="top">The number of milliseconds leeway to use when
+ comparing file modification times. This is needed because not every
+ file system supports tracking the last modified time to the
+ millisecond level. Default is 0 milliseconds, or 2 seconds on DOS systems.
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">pattern</td>
+ <td valign="top">The <CODE>SimpleDateFormat</CODE>-compatible pattern
+ to use when interpreting the <i>datetime</i> attribute.
+ <i>Since Ant 1.6.2</i>
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">checkdirs</td>
+ <td valign="top">
+ Indicates whether or not to check dates on directories.
+ </td>
+ <td valign="top" align="center">No, defaults to <i>false</i></td>
+ </tr>
+ </table>
+
+ <p>Here is an example of how to use the Date Selector:</p>
+
+ <blockquote><pre>
+&lt;fileset dir=&quot;${jar.path}&quot; includes=&quot;**/*.jar&quot;&gt;
+ &lt;date datetime=&quot;01/01/2001 12:00 AM&quot; when=&quot;before&quot;/&gt;
+&lt;/fileset&gt;
+</pre></blockquote>
+
+ <p>Selects all JAR files which were last modified before midnight
+ January 1, 2001.</p>
+
+
+ <h4><a name="dependselect">Depend Selector</a></h4>
+
+ <p>The <code>&lt;depend&gt;</code> tag selects files
+ whose last modified date is later than another, equivalent file in
+ another location.</p>
+
+ <p>The <code>&lt;depend&gt;</code> tag supports the use of a
+ contained <a href="mapper.html"><code>&lt;mapper&gt;</code></a> element
+ to define the location of the file to be compared against. If no
+ <code>&lt;mapper&gt;</code> element is specified, the
+ <code>identity</code> type mapper is used.</p>
+
+ <p>The <code>&lt;depend&gt;</code> selector is case-sensitive.</p>
+
+ <table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">targetdir</td>
+ <td valign="top">The base directory to look for the files to compare
+ against. The precise location depends on a combination of this
+ attribute and the <code>&lt;mapper&gt;</code> element, if any.
+ </td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">granularity</td>
+ <td valign="top">The number of milliseconds leeway to give before
+ deciding a file is out of date. This is needed because not every
+ file system supports tracking the last modified time to the
+ millisecond level. Default is 0 milliseconds, or 2 seconds on DOS systems.
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ </table>
+
+ <p>Here is an example of how to use the Depend Selector:</p>
+
+ <blockquote><pre>
+&lt;fileset dir=&quot;${ant.1.5}/src/main&quot; includes=&quot;**/*.java&quot;&gt;
+ &lt;depend targetdir=&quot;${ant.1.4.1}/src/main&quot;/&gt;
+&lt;/fileset&gt;
+</pre></blockquote>
+
+ <p>Selects all the Java source files which were modified in the
+ 1.5 release.
+ </p>
+
+
+ <h4><a name="depthselect">Depth Selector</a></h4>
+
+ <p>The <code>&lt;depth&gt;</code> tag selects files based on
+ how many directory levels deep they are in relation to the base
+ directory of the fileset.
+ </p>
+
+ <table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">min</td>
+ <td valign="top">The minimum number of directory levels below
+ the base directory that a file must be in order to be selected.
+ Default is no limit.
+ </td>
+ <td valign="top" align="center" rowspan="2">At least one of the two.</td>
+ </tr>
+ <tr>
+ <td valign="top">max</td>
+ <td valign="top">The maximum number of directory levels below
+ the base directory that a file can be and still be selected.
+ Default is no limit.
+ </td>
+ </tr>
+ </table>
+
+ <p>Here is an example of how to use the Depth Selector:</p>
+
+ <blockquote><pre>
+&lt;fileset dir=&quot;${doc.path}&quot; includes=&quot;**/*&quot;&gt;
+ &lt;depth max=&quot;1&quot;/&gt;
+&lt;/fileset&gt;
+</pre></blockquote>
+
+ <p>Selects all files in the base directory and one directory below
+ that.</p>
+
+
+ <h4><a name="differentselect">Different Selector</a></h4>
+
+ <p>The <code>&lt;different&gt;</code> selector will select a file
+ if it is deemed to be 'different' from an equivalent file in
+ another location. The rules for determining difference between
+ the two files are as follows:
+ <ol>
+ <li>If a file is only present in the resource collection you apply
+ the selector to but not in targetdir (or after applying the
+ mapper) the file is selected.
+ <li>If a file is only present in targetdir (or after applying the
+ mapper) it is ignored.
+ <li> Files with different lengths are different.
+ <li> If <tt>ignoreFileTimes</tt> is turned off, then differing file
+ timestamps will cause files to be regarded as different.
+ <li> Unless <tt>ignoreContents</tt> is set to true,
+ a byte-for-byte check is run against the two files.
+ </ol>
+
+ This is a useful selector to work with programs and tasks that don't handle
+ dependency checking properly; even if a predecessor task always creates its
+ output files, followup tasks can be driven off copies made with a different
+ selector, so their dependencies are driven on the absolute state of the
+ files, not just a timestamp. For example: anything fetched from a web site,
+ or the output of some program. To reduce the amount of checking, when using
+ this task inside a <code>&lt;copy&gt;</code> task, set
+ <tt>preservelastmodified</tt> to <i>true</i> to propagate the timestamp
+ from the source file to the destination file.<p>
+
+ The <code>&lt;different&gt;</code> selector supports the use of a
+ contained <a href="mapper.html"><code>&lt;mapper&gt;</code></a> element
+ to define the location of the file to be compared against. If no
+ <code>&lt;mapper&gt;</code> element is specified, the
+ <code>identity</code> type mapper is used.</p>
+
+ <table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">targetdir</td>
+ <td valign="top">The base directory to look for the files to compare
+ against. The precise location depends on a combination of this
+ attribute and the <code>&lt;mapper&gt;</code> element, if any.
+ </td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">ignoreFileTimes</td>
+ <td valign="top">Whether to use file times in the comparison or not.
+ Default is true (time differences are ignored).
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">ignoreContents</td>
+ <td valign="top">Whether to do a byte per byte compare.
+ Default is false (contents are compared).
+ Since Ant 1.6.3
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">granularity</td>
+ <td valign="top">The number of milliseconds leeway to give before
+ deciding a file is out of date. This is needed because not every
+ file system supports tracking the last modified time to the
+ millisecond level. Default is 0 milliseconds, or 2 seconds on DOS systems.
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ </table>
+
+ <p>Here is an example of how to use the Different Selector:</p>
+
+ <blockquote><pre>
+&lt;fileset dir=&quot;${ant.1.5}/src/main&quot; includes=&quot;**/*.java&quot;&gt;
+ &lt;different targetdir=&quot;${ant.1.4.1}/src/main&quot;
+ ignoreFileTimes="true"/&gt;
+&lt;/fileset&gt;
+</pre></blockquote>
+
+ <p>Compares all the Java source files between the 1.4.1 and the 1.5 release
+ and selects those who are different, disregarding file times.
+ </p>
+
+ <h4><a name="filenameselect">Filename Selector</a></h4>
+
+ <p>The <code>&lt;filename&gt;</code> tag acts like the
+ <code>&lt;include&gt;</code> and <code>&lt;exclude&gt;</code>
+ tags within a fileset. By using a selector instead, however,
+ one can combine it with all the other selectors using whatever
+ <a href="#selectcontainers">selector container</a> is desired.
+ </p>
+
+ <p>The <code>&lt;filename&gt;</code> selector is
+ case-sensitive.</p>
+
+ <table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">name</td>
+ <td valign="top">The name of files to select. The name parameter
+ can contain the standard Ant wildcard characters.
+ </td>
+ <td valign="top" align="center" rowspan="2">Exactly one of
+ the two</td>
+ </tr>
+ <tr>
+ <td valign="top">regex</td>
+ <td valign="top">The regular expression matching files to select.</td>
+ </tr>
+ <tr>
+ <td valign="top">casesensitive</td>
+ <td valign="top">Whether to pay attention to case when looking
+ at file names. Default is "true".
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">negate</td>
+ <td valign="top">Whether to reverse the effects of this filename
+ selection, therefore emulating an exclude rather than include
+ tag. Default is "false".
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ </table>
+
+ <p>Here is an example of how to use the Filename Selector:</p>
+
+ <blockquote><pre>
+&lt;fileset dir=&quot;${doc.path}&quot; includes=&quot;**/*&quot;&gt;
+ &lt;filename name=&quot;**/*.css&quot;/&gt;
+&lt;/fileset&gt;
+</pre></blockquote>
+
+ <p>Selects all the cascading style sheet files.</p>
+
+
+ <h4><a name="presentselect">Present Selector</a></h4>
+
+ <p>The <code>&lt;present&gt;</code> tag selects files
+ that have an equivalent file in another directory tree.</p>
+
+ <p>The <code>&lt;present&gt;</code> tag supports the use of a
+ contained <a href="mapper.html"><code>&lt;mapper&gt;</code></a> element
+ to define the location of the file to be tested against. If no
+ <code>&lt;mapper&gt;</code> element is specified, the
+ <code>identity</code> type mapper is used.</p>
+
+ <p>The <code>&lt;present&gt;</code> selector is case-sensitive.</p>
+
+ <table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">targetdir</td>
+ <td valign="top">The base directory to look for the files to compare
+ against. The precise location depends on a combination of this
+ attribute and the <code>&lt;mapper&gt;</code> element, if any.
+ </td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">present</td>
+ <td valign="top">Whether we are requiring that a file is present in
+ the src directory tree only, or in both the src and the target
+ directory tree. Valid values are:
+ <ul>
+ <li>srconly - select files only if they are in the src
+ directory tree but not in the target directory tree
+ <li>both - select files only if they are present both in the
+ src and target directory trees
+ </ul>
+ Default is both. Setting this attribute to &quot;srconly&quot;
+ is equivalent to wrapping the selector in the <code>&lt;not&gt;</code>
+ selector container.
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ </table>
+
+ <p>Here is an example of how to use the Present Selector:</p>
+
+ <blockquote><pre>
+&lt;fileset dir=&quot;${ant.1.5}/src/main&quot; includes=&quot;**/*.java&quot;&gt;
+ &lt;present present=&quot;srconly&quot; targetdir=&quot;${ant.1.4.1}/src/main&quot;/&gt;
+&lt;/fileset&gt;
+</pre></blockquote>
+
+ <p>Selects all the Java source files which are new in the
+ 1.5 release.
+ </p>
+
+ <h4><a name="regexpselect">Regular Expression Selector</a></h4>
+
+ <p>The <code>&lt;containsregexp&gt;</code> tag in a FileSet limits
+ the files defined by that fileset to only those which contents contain a
+ match to the regular expression specified by the <code>expression</code> attribute.
+ </p>
+ <p>The <code>&lt;containsregexp&gt;</code> selector can be used as a
+ ResourceSelector (see the
+ <a href="resources.html#restrict">&lt;restrict&gt;</a>
+ ResourceCollection).</p>
+
+ <table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">expression</td>
+ <td valign="top">Specifies the regular expression that must
+ match true in every file</td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">casesensitive</td>
+ <td valign="top">Perform a case sensitive match. Default is
+ true. <em>since Ant 1.8.2</em></td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">multiline</td>
+ <td valign="top">
+ Perform a multi line match.
+ Default is false. <em>since Ant 1.8.2</em></td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">singleline</td>
+ <td valign="top">
+ This allows '.' to match new lines.
+ SingleLine is not to be confused with multiline, SingleLine is a perl
+ regex term, it corresponds to dotall in java regex.
+ Default is false. <em>since Ant 1.8.2</em></td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ </table>
+
+ <p>Here is an example of how to use the regular expression Selector:</p>
+
+ <blockquote><pre>
+&lt;fileset dir=&quot;${doc.path}&quot; includes=&quot;*.txt&quot;&gt;
+ &lt;containsregexp expression=&quot;[4-6]\.[0-9]&quot;/&gt;
+&lt;/fileset&gt;
+</pre></blockquote>
+
+ <p>Selects all the text files that match the regular expression
+ (have a 4,5 or 6 followed by a period and a number from 0 to 9).
+
+
+ <h4><a name="sizeselect">Size Selector</a></h4>
+
+ <p>The <code>&lt;size&gt;</code> tag in a FileSet will put
+ a limit on the files specified by the include tag, so that tags
+ which do not meet the size limits specified by the selector will not
+ end up being selected.</p>
+
+ <table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">value</td>
+ <td valign="top">The size of the file which should be tested for.
+ </td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">units</td>
+ <td valign="top">The units that the <code>value</code> attribute
+ is expressed in. When using the standard single letter SI
+ designations, such as &quot;k&quot;,&quot;M&quot;, or
+ &quot;G&quot;, multiples of 1000 are used. If you want to use
+ power of 2 units, use the IEC standard: &quot;Ki&quot; for 1024,
+ &quot;Mi&quot; for 1048576, and so on. The default is no units,
+ which means the <code>value</code> attribute expresses the exact
+ number of bytes.
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">when</td>
+ <td valign="top">Indicates how to interpret the size, whether
+ the files to be selected should be larger, smaller, or equal to
+ that value. Acceptable values for this attribute are:
+ <ul>
+ <li>less - select files less than the indicated size
+ <li>more - select files greater than the indicated size
+ <li>equal - select files this exact size
+ </ul>
+ The default is equal.
+ <td valign="top" align="center">No</td>
+ </tr>
+ </table>
+
+ <p>Here is an example of how to use the Size Selector:</p>
+
+ <blockquote><pre>
+&lt;fileset dir=&quot;${jar.path}&quot;&gt;
+ &lt;patternset&gt;
+ &lt;include name=&quot;**/*.jar&quot;/&gt;
+ &lt;/patternset&gt;
+ &lt;size value=&quot;4&quot; units=&quot;Ki&quot; when=&quot;more&quot;/&gt;
+&lt;/fileset&gt;
+</pre></blockquote>
+
+ <p>Selects all JAR files that are larger than 4096 bytes.</p>
+
+ <h4><a name="typeselect">Type Selector</a></h4>
+
+ <p>The <code>&lt;type&gt;</code> tag selects files of a certain type:
+ directory or regular.</p>
+
+ <table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">type</td>
+ <td valign="top">The type of file which should be tested for.
+ Acceptable values are:
+ <ul>
+ <li>file - regular files</li>
+ <li>dir - directories</li>
+ </ul>
+ </td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ </table>
+
+ <p>Here is an example of how to use the Type Selector to select only
+ directories in <code>${src}</code></p>
+
+ <blockquote><pre>
+&lt;fileset dir=&quot;${src}&quot;&gt;
+ &lt;type type="dir"/&gt;
+&lt;/fileset&gt;
+</pre></blockquote>
+
+ <p>The Type Selector is often used in conjunction with other selectors.
+ For example, to select files that also exist in a <code>template</code>
+ directory, but avoid selecting empty directories, use:
+
+<blockquote><pre>
+&lt;fileset dir="${src}"&gt;
+ &lt;and&gt;
+ &lt;present targetdir="template"/&gt;
+ &lt;type type="file"/&gt;
+ &lt;/and&gt;
+&lt;/fileset&gt;
+</pre></blockquote>
+
+
+ <h4><a name="modified">Modified Selector</a></h4>
+ <p>The <code>&lt;modified&gt;</code> selector computes a value for a file, compares that
+ to the value stored in a cache and select the file, if these two values
+ differ.</p>
+ <p>Because this selector is highly configurable the order in which the selection is done
+ is: <ol>
+ <li> get the absolute path for the file </li>
+ <li> get the cached value from the configured cache (absolute path as key) </li>
+ <li> get the new value from the configured algorithm </li>
+ <li> compare these two values with the configured comparator </li>
+ <li> update the cache if needed and requested </li>
+ <li> do the selection according to the comparison result </li>
+ </ol>
+ <p>The comparison, computing of the hashvalue and the store is done by implementation
+ of special interfaces. Therefore they may provide additional parameters.</p>
+
+ <p>The <code>&lt;modified&gt;</code> selector can be used as a
+ ResourceSelector (see the
+ <a href="resources.html#restrict">&lt;restrict&gt;</a>
+ ResourceCollection).
+ In that case it maps simple file resources to files and does its job. If the
+ resource is from another type, the <code>&lt;modified&gt;</code> selector tries
+ to (<b>attention!</b>) copy the content into a local file for computing the
+ hashvalue.</p>
+
+ <table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top"> algorithm </td>
+ <td valign="top"> The type of algorithm should be used.
+ Acceptable values are (further information see later):
+ <ul>
+ <li> hashvalue - HashvalueAlgorithm </li>
+ <li> digest - DigestAlgorithm </li>
+ <li> checksum - ChecksumAlgorithm </li>
+ </ul>
+ </td>
+ <td valign="top" align="center"> No, defaults to <i>digest</i> </td>
+ </tr>
+ <tr>
+ <td valign="top"> cache </td>
+ <td valign="top"> The type of cache should be used.
+ Acceptable values are (further information see later):
+ <ul>
+ <li> propertyfile - PropertyfileCache </li>
+ </ul>
+ </td>
+ <td valign="top" align="center"> No, defaults to <i>propertyfile</i> </td>
+ </tr>
+ <tr>
+ <td valign="top"> comparator </td>
+ <td valign="top"> The type of comparator should be used.
+ Acceptable values are (further information see later):
+ <ul>
+ <li> equal - EqualComparator </li>
+ <li> rule - java.text.RuleBasedCollator
+ <!-- NOTE -->
+ <i>(see <a href="#ModSelNote">note</a> for restrictions)</i>
+ </li>
+ </ul>
+ </td>
+ <td valign="top" align="center"> No, defaults to <i>equal</i> </td>
+ </tr>
+ <tr>
+ <td valign="top"> algorithmclass </td>
+ <td valign="top"> Classname of custom algorithm implementation. Lower
+ priority than <i>algorithm</i>. </td>
+ <td valign="top" align="center"> No </td>
+ </tr>
+ <tr>
+ <td valign="top"> cacheclass </td>
+ <td valign="top"> Classname of custom cache implementation. Lower
+ priority than <i>cache</i>. </td>
+ <td valign="top" align="center"> No </td>
+ </tr>
+ <tr>
+ <td valign="top"> comparatorclass </td>
+ <td valign="top"> Classname of custom comparator implementation. Lower
+ priority than <i>comparator</i>. </td>
+ <td valign="top" align="center"> No </td>
+ </tr>
+ <tr>
+ <td valign="top"> update </td>
+ <td valign="top"> Should the cache be updated when values differ? (boolean) </td>
+ <td valign="top" align="center"> No, defaults to <i>true</i> </td>
+ </tr>
+ <tr>
+ <td valign="top"> seldirs </td>
+ <td valign="top"> Should directories be selected? (boolean) </td>
+ <td valign="top" align="center"> No, defaults to <i>true</i> </td>
+ </tr>
+ <tr>
+ <td valign="top"> selres </td>
+ <td valign="top"> Should Resources without an InputStream, and
+ therefore without checking, be selected? (boolean) </td>
+ <td valign="top" align="center"> No, defaults to <i>true</i>. Only relevant
+ when used as ResourceSelector. </td>
+ </tr>
+ <tr>
+ <td valign="top"> delayupdate </td>
+ <td valign="top"> If set to <i>true</i>, the storage of the cache will be delayed until the
+ next finished BuildEvent; task finished, target finished or build finished,
+ whichever comes first. This is provided for increased performance. If set
+ to <i>false</i>, the storage of the cache will happen with each change. This
+ attribute depends upon the <i>update</i> attribute. (boolean)</td>
+ <td valign="top" align="center"> No, defaults to <i>true</i> </td>
+ </tr>
+ </table>
+
+ <p>These attributes can be set with nested <code>&lt;param/&gt;</code> tags. With <code>&lt;param/&gt;</code>
+ tags you can set other values too - as long as they are named according to
+ the following rules: <ul>
+ <li> <b> algorithm </b>: same as attribute algorithm </li>
+ <li> <b> cache </b>: same as attribute cache </li>
+ <li> <b> comparator </b>: same as attribute comparator </li>
+ <li> <b> algorithmclass </b>: same as attribute algorithmclass </li>
+ <li> <b> cacheclass </b>: same as attribute cacheclass </li>
+ <li> <b> comparatorclass </b>: same as attribute comparatorclass </li>
+ <li> <b> update </b>: same as attribute update </li>
+ <li> <b> seldirs </b>: same as attribute seldirs </li>
+ <li> <b> algorithm.* </b>: Value is transferred to the algorithm via its
+ <i>set</i>XX-methods </li>
+ <li> <b> cache.* </b>: Value is transferred to the cache via its
+ <i>set</i>XX-methods </li>
+ <li> <b> comparator.* </b>: Value is transferred to the comparator via its
+ <i>set</i>XX-methods </li>
+ </ul>
+
+ <table border="1" cellpadding="2" cellspacing="0">
+ <tr><td colspan="2"><font size="+1"><b> Algorithm options</b></font></td></tr>
+ <tr>
+ <td valign="top"><b>Name</b></td>
+ <td valign="top"><b>Description</b></td>
+ </tr>
+ <tr>
+ <td valign="top"> hashvalue </td>
+ <td valign="top"> Reads the content of a file into a java.lang.String
+ and use thats hashValue(). No additional configuration required.
+ </td>
+ </tr>
+ <tr>
+ <td valign="top"> digest </td>
+ <td valign="top"> Uses java.security.MessageDigest. This Algorithm supports
+ the following attributes:
+ <ul>
+ <li><i>algorithm.algorithm</i> (optional): Name of the Digest algorithm
+ (e.g. 'MD5' or 'SHA', default = <i>MD5</i>) </li>
+ <li><i>algorithm.provider</i> (optional): Name of the Digest provider
+ (default = <i>null</i>) </li>
+ </ul>
+ </td>
+ </tr>
+ <tr>
+ <td valign="top"> checksum </td>
+ <td valign="top"> Uses java.util.zip.Checksum. This Algorithm supports
+ the following attributes:
+ <ul>
+ <li><i>algorithm.algorithm</i> (optional): Name of the algorithm
+ (e.g. 'CRC' or 'ADLER', default = <i>CRC</i>) </li>
+ </ul>
+ </td>
+ </tr>
+ <tr><td colspan="2"><font size="+1"><b> Cache options </b></font></td></tr>
+ <tr>
+ <td valign="top"> propertyfile </td>
+ <td valign="top"> Use the java.util.Properties class and its possibility
+ to load and store to file.
+ This Cache implementation supports the following attributes:
+ <ul>
+ <li><i>cache.cachefile</i> (optional): Name of the properties-file
+ (default = <i>cache.properties</i>) </li>
+ </ul>
+ </td>
+ </tr>
+ <tr><td colspan="2"><font size="+1"><b> Comparator options</b></font></td></tr>
+ <tr>
+ <td valign="top"> equal </td>
+ <td valign="top"> Very simple object comparison. </td>
+ </tr>
+ <tr>
+ <td valign="top"> rule </td>
+ <td valign="top"> Uses <i>java.text.RuleBasedCollator</i> for Object
+ comparison.
+ <!-- NOTE -->
+ <i>(see <a href="#ModSelNote">note</a> for restrictions)</i>
+ </td>
+ </tr>
+ </table>
+
+ <p>The <code>&lt;modified&gt;</code> selector supports a nested
+ <code>&lt;classpath&gt;</code> element that represents a <a href="../using.html#path">
+ PATH like structure</a> for finding custom interface implementations. </p>
+
+ <p>Here are some examples of how to use the Modified Selector:</p>
+
+ <blockquote><pre>
+ &lt;copy todir="dest"&gt;
+ &lt;fileset dir="src"&gt;
+ &lt;modified/&gt;
+ &lt;/fileset&gt;
+ &lt;/copy&gt;
+ </pre></blockquote>
+ <p>This will copy all files from <i>src</i> to <i>dest</i> which content has changed.
+ Using an updating PropertyfileCache with cache.properties and
+ MD5-DigestAlgorithm.</p>
+
+ <blockquote><pre>
+ &lt;copy todir="dest"&gt;
+ &lt;fileset dir="src"&gt;
+ &lt;modified update="true"
+ seldirs="true"
+ cache="propertyfile"
+ algorithm="digest"
+ comparator="equal"&gt;
+ &lt;param name="cache.cachefile" value="cache.properties"/&gt;
+ &lt;param name="algorithm.algorithm" value="MD5"/&gt;
+ &lt;/modified&gt;
+ &lt;/fileset&gt;
+ &lt;/copy&gt;
+ </pre></blockquote>
+ <p>This is the same example rewritten as CoreSelector with setting the all the values
+ (same as defaults are).</p>
+
+ <blockquote><pre>
+ &lt;copy todir="dest"&gt;
+ &lt;fileset dir="src"&gt;
+ &lt;custom class="org.apache.tools.ant.types.selectors.modifiedselector.ModifiedSelector"&gt;
+ &lt;param name="update" value="true"/&gt;
+ &lt;param name="seldirs" value="true"/&gt;
+ &lt;param name="cache" value="propertyfile"/&gt;
+ &lt;param name="algorithm" value="digest"/&gt;
+ &lt;param name="comparator" value="equal"/&gt;
+ &lt;param name="cache.cachefile" value="cache.properties"/&gt;
+ &lt;param name="algorithm.algorithm" value="MD5"/&gt;
+ &lt;/custom&gt;
+ &lt;/fileset&gt;
+ &lt;/copy&gt;
+ </pre></blockquote>
+ <p>And this is the same rewritten as CustomSelector.</p>
+
+ <blockquote><pre>
+ &lt;target name="generate-and-upload-site"&gt;
+ &lt;echo&gt; generate the site using forrest &lt;/echo&gt;
+ &lt;antcall target="site"/&gt;
+
+ &lt;echo&gt; upload the changed file &lt;/echo&gt;
+ &lt;ftp server="${ftp.server}" userid="${ftp.user}" password="${ftp.pwd}"&gt;
+ &lt;fileset dir="htdocs/manual"&gt;
+ &lt;modified/&gt;
+ &lt;/fileset&gt;
+ &lt;/ftp&gt;
+ &lt;/target&gt;
+ </pre></blockquote>
+ <p>A useful scenario for this selector inside a build environment
+ for homepage generation (e.g. with <a href="http://xml.apache.org/forrest/">
+ Apache Forrest</a>). Here all <b>changed</b> files are uploaded to the server. The
+ CacheSelector saves therefore much upload time.</p>
+
+ <blockquote><pre>
+ &lt;modified cacheclassname="com.mycompany.MyCache"&gt;
+ &lt;classpath&gt;
+ &lt;pathelement location="lib/mycompany-antutil.jar"/&gt;
+ &lt;/classpath&gt;
+ &lt;/modified&gt;
+ </pre></blockquote>
+ <p>Uses <tt>com.mycompany.MyCache</tt> from a jar outside of Ants own classpath
+ as cache implementation</p>
+
+ <h4><a name="ModSelNote">Note on RuleBasedCollator</a></h4>
+ <p>The RuleBasedCollator needs a format for its work, but its needed while
+ instantiation. There is a problem in the initialization algorithm for this
+ case. Therefore you should not use this (or tell me the workaround :-).</p>
+
+ <h4><a name="signedselector">Signed Selector</a></h4>
+
+ <p>
+ The <code>&lt;signedselector&gt;</code> tag selects signed files and optionally
+ signed with a certain name.
+ </p>
+ <p>
+ This selector has been added in Apache Ant 1.7.
+ </p>
+ <table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">name</td>
+ <td valign="top"> The signature name to check for.</td>
+ <td valign="top" align="center">no</td>
+ </tr>
+ </table>
+
+ <h4><a name="readable">Readable Selector</a></h4>
+
+ <p>The <code>&lt;readable&gt;</code> selector selects only files
+ that are readable. Ant only invokes
+ <code>java.io.File#canRead</code> so if a file is unreadable
+ but the Java VM cannot detect this state, this selector will
+ still select the file.</p>
+
+ <h4><a name="writable">Writable Selector</a></h4>
+
+ <p>The <code>&lt;writable&gt;</code> selector selects only files
+ that are writable. Ant only invokes
+ <code>java.io.File#canWrite</code> so if a file is unwritable
+ but the Java VM cannot detect this state, this selector will
+ still select the file.</p>
+
+ <h4><a name="scriptselector">Script Selector</a></h4>
+
+ <p>
+ The <code>&lt;scriptselector&gt;</code> element enables you
+ to write a complex selection algorithm in any
+ <a href="http://jakarta.apache.org/bsf" target="_top">Apache BSF</a>
+ or
+ <a href="https://scripting.dev.java.net">JSR 223</a>
+ supported language.
+ See the <a href="../Tasks/script.html">Script</a> task for
+ an explanation of scripts and dependencies.
+ </p>
+ <p>
+ This selector was added in Apache Ant 1.7.
+ </p>
+ <table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">language</td>
+ <td valign="top">language of the script.</td>
+ <td valign="top" align="center">yes</td>
+ </tr>
+ <tr>
+ <td valign="top">manager</td>
+ <td valign="top">
+ The script engine manager to use.
+ See the <a href="../Tasks/script.html">script</a> task
+ for using this attribute.
+ </td>
+ <td valign="top" align="center">No - default is "auto"</td>
+ </tr>
+ <tr>
+ <td valign="top">src</td>
+ <td valign="top">filename of the script</td>
+ <td valign="top" align="center">no</td>
+ </tr>
+ <tr>
+ <td valign="top">setbeans</td>
+ <td valign="top">whether to have all properties, references and targets as
+ global variables in the script.</td>
+ <td valign="top" align="center">No, default is "true".</td>
+ </tr>
+ <tr>
+ <td valign="top">classpath</td>
+ <td valign="top">
+ The classpath to pass into the script.
+ </td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">classpathref</td>
+ <td valign="top">The classpath to use, given as a
+ <a href="../using.html#references">reference</a> to a path defined elsewhere.
+ <td align="center" valign="top">No</td>
+ </tr>
+ </table>
+ <p>
+ This selector can take a nested &lt;classpath&gt; element.
+ See the <a href="../Tasks/script.html">script</a> task
+ on how to use this element.
+ </p>
+ <p>
+ If no <code>src</code> attribute is supplied, the script must be nested
+ inside the selector declaration.
+ </p>
+ <p>The embedded script is invoked for every test, with
+ the bean <code>self</code>
+ is bound to the selector. It has an attribute <code>selected</code>
+ must can be set using <code>setSelected(boolean)</code> to select that
+ file.
+
+ <p>
+
+ The following beans are configured for every script, alongside
+ the classic set of project, properties, and targets.
+
+ <table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Bean</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td valign="top"><b>Type</b></td>
+ </tr>
+ <tr>
+ <td valign="top">self</td>
+ <td valign="top">selector instance</td>
+ <td valign="top">org.apache.tools.ant.types.optional</td>
+ </tr>
+ <tr>
+ <td valign="top">filename</td>
+ <td valign="top">filename of the selection</td>
+ <td valign="top" >String</td>
+ </tr>
+ <tr>
+ <td valign="top">file</td>
+ <td valign="top">file of the selection</td>
+ <td valign="top" >java.io.File</td>
+ </tr>
+ <tr>
+ <td valign="top">basedir</td>
+ <td valign="top">Fileset base directory</td>
+ <td valign="top" >java.io.File</td>
+ </tr>
+
+ </table>
+ <p>
+ The <code>self</code> bean maps to the selector, which has the following
+ attributes. Only the <code>selected</code> flag is writable, the rest
+ are read only via their getter methods.
+
+ <table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Type</b></td>
+ </tr>
+ <tr>
+ <td valign="top">selected</td>
+ <td valign="top">writeable flag to select this file</td>
+ <td valign="top" align="center">boolean</td>
+ </tr>
+ <tr>
+ <td valign="top">filename</td>
+ <td valign="top">filename of the selection</td>
+ <td valign="top" >String</td>
+ </tr>
+ <tr>
+ <td valign="top">file</td>
+ <td valign="top">file of the selection</td>
+ <td valign="top" >java.io.File</td>
+ </tr>
+ <tr>
+ <td valign="top">basedir</td>
+ <td valign="top">Fileset base directory</td>
+ <td valign="top" >java.io.File</td>
+ </tr>
+ </table>
+
+ <p>
+ Example
+ </p>
+<pre>
+ &lt;scriptselector language=&quot;javascript&quot;&gt;
+ self.setSelected(true);
+ &lt;/scriptselector&gt;
+</pre>
+ <p>
+ Selects every file.
+ </p>
+
+<pre>
+ &lt;scriptselector language=&quot;javascript&quot;&gt;
+ self.setSelected((filename.length%2)==0);
+ &lt;/scriptselector&gt;
+</pre>
+Select files whose filename length is even.
+
+ <h3><a name="selectcontainers">Selector Containers</a></h3>
+
+ <p>To create more complex selections, a variety of selectors that
+ contain other selectors are available for your use. They combine the
+ selections of their child selectors in various ways.</p>
+
+ <p>The selector containers are:</p>
+
+ <ul>
+ <li><a href="#andselect"><code>&lt;and&gt;</code></a> - select a file only if all
+ the contained selectors select it.
+ <li><a href="#majorityselect"><code>&lt;majority&gt;</code></a> - select a file
+ if a majority of its selectors select it.
+ <li><a href="#noneselect"><code>&lt;none&gt;</code></a> - select a file only if
+ none of the contained selectors select it.
+ <li><a href="#notselect"><code>&lt;not&gt;</code></a> - can contain only one
+ selector, and reverses what it selects and doesn't select.
+ <li><a href="#orselect"><code>&lt;or&gt;</code></a> - selects a file if any one
+ of the contained selectors selects it.
+ <li><a href="#selectorselect"><code>&lt;selector&gt;</code></a> - contains only one
+ selector and forwards all requests to it without alteration, provided
+ that any <code>&quot;if&quot;</code> or
+ <code>&quot;unless&quot;</code> conditions are met. This
+ is the selector to use if you want to define a reference. It is
+ usable as an element of <code>&lt;project&gt;</code>. It is also
+ the one to use if you want selection of files to be dependent on
+ Ant property settings.
+ </ul>
+
+ <p>All selector containers can contain any other selector, including
+ other containers, as an element. Using containers, the selector tags
+ can be arbitrarily deep. Here is a complete list of allowable
+ selector elements within a container:</p>
+
+ <ul>
+ <li><code>&lt;and&gt;</code></li>
+ <li><code>&lt;contains&gt;</code></li>
+ <li><code>&lt;custom&gt;</code></li>
+ <li><code>&lt;date&gt;</code></li>
+ <li><code>&lt;depend&gt;</code></li>
+ <li><code>&lt;depth&gt;</code></li>
+ <li><code>&lt;filename&gt;</code></li>
+ <li><code>&lt;majority&gt;</code></li>
+ <li><code>&lt;none&gt;</code></li>
+ <li><code>&lt;not&gt;</code></li>
+ <li><code>&lt;or&gt;</code></li>
+ <li><code>&lt;present&gt;</code></li>
+ <li><code>&lt;selector&gt;</code></li>
+ <li><code>&lt;size&gt;</code></li>
+ </ul>
+
+ <h4><a name="andselect">And Selector</a></h4>
+
+ <p>The <code>&lt;and&gt;</code> tag selects files that are
+ selected by all of the elements it contains. It returns as
+ soon as it finds a selector that does not select the file,
+ so it is not guaranteed to check every selector.
+ </p>
+
+ <p>Here is an example of how to use the And Selector:</p>
+
+ <blockquote><pre>
+&lt;fileset dir=&quot;${dist}&quot; includes=&quot;**/*.jar&quot;&gt;
+ &lt;and&gt;
+ &lt;size value=&quot;4&quot; units=&quot;Ki&quot; when=&quot;more&quot;/&gt;
+ &lt;date datetime=&quot;01/01/2001 12:00 AM&quot; when=&quot;before&quot;/&gt;
+ &lt;/and&gt;
+&lt;/fileset&gt;
+</pre></blockquote>
+
+ <p>Selects all the JAR file larger than 4096 bytes which haven't been update
+ since the last millennium.
+ </p>
+
+
+ <h4><a name="majorityselect">Majority Selector</a></h4>
+
+ <p>The <code>&lt;majority&gt;</code> tag selects files provided
+ that a majority of the contained elements also select it. Ties are
+ dealt with as specified by the <code>allowtie</code> attribute.
+ </p>
+
+ <table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">allowtie</td>
+ <td valign="top">Whether files should be selected if there
+ are an even number of selectors selecting them as are
+ not selecting them. Default is true.
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ </table>
+
+
+ <p>Here is an example of how to use the Majority Selector:</p>
+
+ <blockquote><pre>
+&lt;fileset dir=&quot;${docs}&quot; includes=&quot;**/*.html&quot;&gt;
+ &lt;majority&gt;
+ &lt;contains text=&quot;project&quot; casesensitive="false"/&gt;
+ &lt;contains text=&quot;taskdef&quot; casesensitive="false"/&gt;
+ &lt;contains text=&quot;IntrospectionHelper&quot; casesensitive="true"/&gt;
+ &lt;/majority&gt;
+&lt;/fileset&gt;
+</pre></blockquote>
+
+ <p>Selects all the HTML files which contain at least two of the three
+ phrases "project", "taskdef", and "IntrospectionHelper" (this last phrase must
+ match case exactly).
+ </p>
+
+
+ <h4><a name="noneselect">None Selector</a></h4>
+
+ <p>The <code>&lt;none&gt;</code> tag selects files that are
+ not selected by any of the elements it contains. It returns as
+ soon as it finds a selector that selects the file,
+ so it is not guaranteed to check every selector.
+ </p>
+
+ <p>Here is an example of how to use the None Selector:</p>
+
+ <blockquote><pre>
+&lt;fileset dir=&quot;${src}&quot; includes=&quot;**/*.java&quot;&gt;
+ &lt;none&gt;
+ &lt;present targetdir=&quot;${dest}&quot;/&gt;
+ &lt;present targetdir=&quot;${dest}&quot;&gt;
+ &lt;mapper type=&quot;glob&quot; from=&quot;*.java&quot; to=&quot;*.class&quot;/&gt;
+ &lt;/present&gt;
+ &lt;/none&gt;
+&lt;/fileset&gt;
+</pre></blockquote>
+
+ <p>Selects only Java files which do not have equivalent java or
+ class files in the dest directory.
+ </p>
+
+
+ <h4><a name="notselect">Not Selector</a></h4>
+
+ <p>The <code>&lt;not&gt;</code> tag reverses the meaning of the
+ single selector it contains.
+ </p>
+
+ <p>Here is an example of how to use the Not Selector:</p>
+
+ <blockquote><pre>
+&lt;fileset dir=&quot;${src}&quot; includes=&quot;**/*.java&quot;&gt;
+ &lt;not&gt;
+ &lt;contains text=&quot;test&quot;/&gt;
+ &lt;/not&gt;
+&lt;/fileset&gt;
+</pre></blockquote>
+
+ <p>Selects all the files in the src directory that do not contain the
+ string "test".
+ </p>
+
+
+ <h4><a name="orselect">Or Selector</a></h4>
+
+ <p>The <code>&lt;or&gt;</code> tag selects files that are
+ selected by any one of the elements it contains. It returns as
+ soon as it finds a selector that selects the file,
+ so it is not guaranteed to check every selector.
+ </p>
+
+ <p>Here is an example of how to use the Or Selector:</p>
+
+ <blockquote><pre>
+&lt;fileset dir=&quot;${basedir}&quot;&gt;
+ &lt;or&gt;
+ &lt;depth max=&quot;0&quot;/&gt;
+ &lt;filename name="*.png"/&gt;
+ &lt;filename name="*.gif"/&gt;
+ &lt;filename name="*.jpg"/&gt;
+ &lt;/or&gt;
+&lt;/fileset&gt;
+</pre></blockquote>
+
+ <p>Selects all the files in the top directory along with all the
+ image files below it.
+ </p>
+
+
+ <h4><a name="selectorselect">Selector Reference</a></h4>
+
+ <p>The <code>&lt;selector&gt;</code> tag is used to create selectors
+ that can be reused through references. It is the only selector which can
+ be used outside of
+ any target, as an element of the <code>&lt;project&gt;</code> tag. It
+ can contain only one other selector, but of course that selector can
+ be a container.
+ </p>
+
+ <p>The <code>&lt;selector&gt;</code> tag can also be used to select
+ files conditionally based on whether an Ant property exists or not.
+ This functionality is realized using the <code>&quot;if&quot;</code> and
+ <code>&quot;unless&quot;</code> attributes in exactly the same way they
+ are used on targets or on the <code>&lt;include&gt;</code> and
+ <code>&lt;exclude&gt;</code> tags within a
+ <code>&lt;patternset&gt;</code>.</p>
+
+ <table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">if</td>
+ <td valign="top">Allow files to be selected only <a href="../properties.html#if+unless">if the named
+ property is set</a>.
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">unless</td>
+ <td valign="top">Allow files to be selected only <a href="../properties.html#if+unless">if the named
+ property is <b>not</b> set</a>.
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ </table>
+
+ <p>Here is an example of how to use the Selector Reference:</p>
+
+ <blockquote><pre>
+&lt;project default=&quot;all&quot; basedir=&quot;./ant&quot;&gt;
+
+ &lt;selector id=&quot;completed&quot;&gt;
+ &lt;none&gt;
+ &lt;depend targetdir=&quot;build/classes&quot;&gt;
+ &lt;mapper type=&quot;glob&quot; from=&quot;*.java&quot; to=&quot;*.class&quot;/&gt;
+ &lt;/depend&gt;
+ &lt;depend targetdir=&quot;docs/manual/api&quot;&gt;
+ &lt;mapper type=&quot;glob&quot; from=&quot;*.java&quot; to=&quot;*.html&quot;/&gt;
+ &lt;/depend&gt;
+ &lt;/none&gt;
+ &lt;/selector&gt;
+
+ &lt;target&gt;
+ &lt;zip&gt;
+ &lt;fileset dir=&quot;src/main&quot; includes=&quot;**/*.java&quot;&gt;
+ &lt;selector refid=&quot;completed&quot;/&gt;
+ &lt;/fileset&gt;
+ &lt;/zip&gt;
+ &lt;/target&gt;
+
+&lt;/project&gt;
+</pre></blockquote>
+
+ <p>Zips up all the Java files which have an up-to-date equivalent
+ class file and javadoc file associated with them.
+ </p>
+
+ <p>And an example of selecting files conditionally, based on whether
+ properties are set:</p>
+
+ <blockquote><pre>
+&lt;fileset dir=&quot;${working.copy}&quot;&gt;
+ &lt;or&gt;
+ &lt;selector if=&quot;include.tests&quot;&gt;
+ &lt;filename name=&quot;**/*Test.class&quot;&gt;
+ &lt;/selector&gt;
+ &lt;selector if=&quot;include.source&quot;&gt;
+ &lt;and&gt;
+ &lt;filename name=&quot;**/*.java&quot;&gt;
+ &lt;not&gt;
+ &lt;selector unless=&quot;include.tests&quot;&gt;
+ &lt;filename name=&quot;**/*Test.java&quot;&gt;
+ &lt;/selector&gt;
+ &lt;/not&gt;
+ &lt;/and&gt;
+ &lt;/selector&gt;
+ &lt;/or&gt;
+&lt;/fileset&gt;
+</pre></blockquote>
+
+ <p>A fileset that conditionally contains Java source files and Test
+ source and class files.</p>
+
+ <h3><a name="customselect">Custom Selectors</a></h3>
+
+ <p>You can write your own selectors and use them within the selector
+ containers by specifying them within the <code>&lt;custom&gt;</code> tag.</p>
+
+ <p>First, you have to write your selector class in Java. The only
+ requirement it must meet in order to be a selector is that it implements
+ the <code>org.apache.tools.ant.types.selectors.FileSelector</code>
+ interface, which contains a single method. See
+ <a href="selectors-program.html">Programming Selectors in Ant</a> for
+ more information.</p>
+
+ <p>Once that is written, you include it in your build file by using
+ the <code>&lt;custom&gt;</code> tag.
+ </p>
+
+ <table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">classname</td>
+ <td valign="top">The name of your class that implements
+ <code>org.apache.tools.ant.types.selectors.FileSelector</code>.
+ </td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">classpath</td>
+ <td valign="top">The classpath to use in order to load the
+ custom selector class. If neither this classpath nor the
+ classpathref are specified, the class will be
+ loaded from the classpath that Ant uses.
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">classpathref</td>
+ <td valign="top">A reference to a classpath previously
+ defined. If neither this reference nor the
+ classpath above are specified, the class will be
+ loaded from the classpath that Ant uses.
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ </table>
+
+ <p>Here is how you use <code>&lt;custom&gt;</code> to
+ use your class as a selector:
+ </p>
+
+ <blockquote><pre>
+&lt;fileset dir=&quot;${mydir}&quot; includes=&quot;**/*&quot;&gt;
+ &lt;custom classname=&quot;com.mydomain.MySelector&quot;&gt;
+ &lt;param name=&quot;myattribute&quot; value=&quot;myvalue&quot;/&gt;
+ &lt;/custom&gt;
+&lt;/fileset&gt;
+</pre></blockquote>
+
+ <p>A number of core selectors can also be used as custom selectors
+ by specifying their attributes using <code>&lt;param&gt;</code> elements. These
+ are</p>
+
+ <ul>
+ <li><a href="#containsselect">Contains Selector</a> with
+ classname <code>org.apache.tools.ant.types.selectors.ContainsSelector</code>
+ <li><a href="#dateselect">Date Selector</a> with
+ classname <code>org.apache.tools.ant.types.selectors.DateSelector</code>
+ <li><a href="#depthselect">Depth Selector</a> with
+ classname <code>org.apache.tools.ant.types.selectors.DepthSelector</code>
+ <li><a href="#filenameselect">Filename Selector</a> with
+ classname <code>org.apache.tools.ant.types.selectors.FilenameSelector</code>
+ <li><a href="#sizeselect">Size Selector</a> with
+ classname <code>org.apache.tools.ant.types.selectors.SizeSelector</code>
+ </ul>
+
+ <p>Here is the example from the Depth Selector section rewritten
+ to use the selector through <code>&lt;custom&gt;</code>.</p>
+
+ <blockquote><pre>
+&lt;fileset dir=&quot;${doc.path}&quot; includes=&quot;**/*&quot;&gt;
+ &lt;custom classname=&quot;org.apache.tools.ant.types.selectors.DepthSelector&quot;&gt;
+ &lt;param name=&quot;max&quot; value=&quot;1&quot;/&gt;
+ &lt;/custom&gt;
+&lt;/fileset&gt;
+</pre></blockquote>
+
+ <p>Selects all files in the base directory and one directory below
+ that.</p>
+
+ <p>For more details concerning writing your own selectors, consult
+ <a href="selectors-program.html">Programming Selectors in Ant</a>.</p>
+
+
+
+ </body>
+
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Types/tarfileset.html b/framework/src/ant/apache-ant-1.9.6/manual/Types/tarfileset.html
new file mode 100644
index 00000000..499ed798
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Types/tarfileset.html
@@ -0,0 +1,182 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+ <meta http-equiv="Content-Language" content="en-us">
+ <link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>TarFileSet Type</title>
+</head>
+<body>
+<h2><a name="fileset">TarFileSet</a></h2>
+
+<p><em>TarFileSet</em> has been added as a stand-alone type in Apache Ant
+1.7.</p>
+
+<p>A <code>&lt;tarfileset&gt;</code> is a special form of a <code>&lt;<a
+ href="fileset.html">fileset</a>&gt;</code> which can behave in 2
+different ways : <br>
+</p>
+<ul>
+ <li>When the <span style="font-style: italic;">src</span> attribute
+ is used - or a nested resource collection has been specified, the
+ tarfileset is populated with tar entries found in the file <span
+ style="font-style: italic;">src</span>.<br>
+ </li>
+ <li>When the <span style="font-style: italic;">dir</span> attribute
+is used, the tarfileset is populated with filesystem files found under <span
+ style="font-style: italic;">dir</span>.<br>
+ </li>
+</ul>
+<p><code>&lt;tarfileset&gt;</code> supports all attributes of <code>&lt;<a
+ href="fileset.html">fileset</a>&gt;</code>
+ in addition to those listed below. Note that tar archives in general
+ don't contain entries with leading slashes so you shouldn't use
+ include/exclude patterns that start with slashes either.
+</p>
+<p>A tarfileset can be defined with the <span style="font-style:
+italic;">id </span>attribute and referred to with the <span
+style="font-style: italic;">refid</span> attribute. This is also true
+for tarfileset which has been added in Ant 1.7.<br>
+</p>
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tbody>
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td valign="top" align="center"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">prefix</td>
+ <td valign="top">all files in the fileset are prefixed with that
+path in the archive.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">fullpath</td>
+ <td valign="top">the file described by the fileset is placed at
+that exact location in the archive.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">src</td>
+ <td valign="top">may be used in place of the <i>dir</i> attribute
+ to specify a tar file whose contents will be extracted and included
+in the archive.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">filemode</td>
+ <td valign="top">A 3 digit octal string, specify the user, group
+and other modes in the standard Unix fashion. Only applies to
+plain files. Default is 644.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">dirmode</td>
+ <td valign="top">A 3 digit octal string, specify the user, group
+and other modes in the standard Unix fashion. Only applies to
+directories. Default is 755.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">username</td>
+ <td valign="top">The username for the tar entry. This is not the same as the UID.
+ </td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">group</td>
+ <td valign="top">The groupname for the tar entry. This is not the same as the GID.
+ </td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">uid</td>
+ <td valign="top">The user identifier (UID) for the tar entry. This is an integer value
+ and is not the same as the username.
+ </td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">gid</td>
+ <td valign="top">The group identifier (GID) for the tar entry.
+ </td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">erroronmissingarchive</td>
+ <td valign="top">
+ Specify what happens if the archive does not exist.
+ If true, a build error will happen; if false, the fileset
+ will be ignored/empty.
+ Defaults to true.
+ <em>Since Ant 1.8.0</em>
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">encoding</td>
+ <td valign="top">The character encoding to use for filenames
+ inside the zip file. For a list of possible values see the <a
+ href="http://docs.oracle.com/javase/7/docs/technotes/guides/intl/encoding.doc.html">Supported Encodings</a>.
+ Defaults to the platform's default character encoding.
+ <em>Since Ant 1.9.5</em>
+ <td align="center" valign="top">No</td>
+ </tr>
+ </tbody>
+</table>
+<p>The <i>fullpath</i> attribute can only be set for filesets that
+represent a single file. The <i>prefix</i> and <i>fullpath</i>
+attributes cannot both be set on the same fileset.</p>
+<p>When using the <i>src</i> attribute, include and exclude patterns
+may be used to specify a subset of the archive for inclusion in the
+archive as with the <i>dir</i> attribute.</p>
+
+<p>Please note that currently only the <a
+href="../Tasks/tar.html">tar</a> task uses the permission and
+ownership attributes.</p>
+
+<h3>Parameters specified as nested elements</h3>
+
+<h4>any <a href="resources.html">resource</a> or single element
+resource collection</h4>
+
+<p>The specified resource will be used as src.</p>
+
+<h4>Examples</h4>
+<blockquote>
+<pre>
+ &lt;copy todir="some-dir"&gt;
+ &lt;tarfileset includes="lib/**"&gt;
+ &lt;bzip2resource&gt;
+ &lt;url url="http://example.org/dist/some-archive.tar.bz2"/&gt;
+ &lt;/bzip2resource&gt;
+ &lt;/tarfileset&gt;
+ &lt;/copy&gt;
+ </pre></blockquote>
+
+<p>downloads the archive some-archive.tar.bz2, uncompresses and
+extracts it on the fly, copies the contents of the lib directory into
+some-dir and discards the rest of the archive. File timestamps will
+be compared between the archive's entries and files inside the target
+directory, no files get overwritten unless they are out-of-date.</p>
+
+
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Types/xmlcatalog.html b/framework/src/ant/apache-ant-1.9.6/manual/Types/xmlcatalog.html
new file mode 100644
index 00000000..a0ddafc0
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Types/xmlcatalog.html
@@ -0,0 +1,306 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>XMLCatalog Type</title>
+</head>
+
+<body>
+
+<h2><a name="XMLCatalog">XMLCatalog</a></h2>
+
+<p>An XMLCatalog is a catalog of public resources such as DTDs or
+entities that are referenced in an XML document. Catalogs are
+typically used to make web references to resources point to a locally
+cached copy of the resource.</p>
+
+<p>This allows the XML Parser, XSLT Processor or other consumer of XML
+documents
+to efficiently allow a local substitution for a resource available on the
+web.
+</p>
+<p><b>Note:</b> This task <em>uses, but does not depend on</em> external
+libraries not included in the Apache Ant distribution. See <a
+ href="../install.html#librarydependencies">Library Dependencies</a> for more
+information.</p>
+<p>This data type provides a catalog of resource locations based
+on the <a
+href="http://oasis-open.org/committees/entity/spec-2001-08-06.html">
+OASIS "Open Catalog" standard</a>. The catalog entries are used
+both for Entity resolution and URI resolution, in accordance with
+the <code>org.xml.sax.EntityResolver</code> and <code>
+javax.xml.transform.URIResolver</code> interfaces as defined
+in the <a href="https://jaxp.dev.java.net/">Java API for XML
+Processing (JAXP) Specification</a>.</p>
+<p>For example, in a <code>web.xml</code> file, the DTD is referenced as:
+<pre>
+&lt;!DOCTYPE web-app PUBLIC &quot;-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN&quot;
+ &quot;http://java.sun.com/j2ee/dtds/web-app_2_2.dtd&quot;&gt;
+</pre>
+The XML processor, without XMLCatalog support, would need to retrieve the
+DTD from
+the URL specified whenever validation of the document was required.
+</p>
+<p>This can be very time consuming during the build process,
+especially where network throughput is limited. Alternatively, you
+can do the following:
+<ol>
+<li>Copy <code>web-app_2_2.dtd</code> onto your local disk somewhere (either in the
+filesystem or even embedded inside a jar or zip file on the classpath).</li>
+<li>Create an <code>&lt;xmlcatalog&gt;</code> with a <code>&lt;dtd&gt;</code>
+element whose <code>location</code> attribute points to the file.</li>
+<li>Success! The XML processor will now use the local copy instead of calling out
+to the internet.</li>
+</ol>
+</p>
+<p>XMLCatalogs can appear inside tasks
+that support this feature or at the same level as <code>target</code>
+- i.e., as children of <code>project</code> for reuse across different
+tasks,
+e.g. XML Validation and XSLT Transformation. The XML Validate task
+uses XMLCatalogs for entity resolution. The XSLT Transformation
+task uses XMLCatalogs for both entity and URI resolution.</p>
+<p>XMLCatalogs are specified as either a reference to another
+XMLCatalog, defined previously in a build file, or as a list of
+<code>dtd</code> or <code>entity</code> locations. In addition,
+external catalog files may be specified in a nested <code>catalogpath</code> ,
+but they will be ignored unless the resolver library from
+xml-commons is available in the system classpath. <b>Due to backwards
+incompatible changes in the resolver code after the release of
+resolver 1.0, Ant will not support resolver.jar in version 1.0 - we
+expect a resolver release 1.1 to happen before Ant 1.6 gets
+released.</b> A separate classpath for entity resolution may be
+specified inline via nested <code>classpath</code> elements; otherwise
+the system classpath is used for this as well.</p>
+<p>XMLCatalogs can also be nested inside other XMLCatalogs. For
+example, a "superset" XMLCatalog could be made by including several
+nested XMLCatalogs that referred to other, previously defined
+XMLCatalogs.</p>
+<p>Resource locations can be specified either in-line or in
+external catalog file(s), or both. In order to use an external
+catalog file, the xml-commons resolver library ("resolver.jar")
+must be in your path. External catalog files may be either <a
+href="http://oasis-open.org/committees/entity/background/9401.html">
+plain text format</a> or <a
+href="http://www.oasis-open.org/committees/entity/spec-2001-08-06.html">
+XML format</a>. If the xml-commons resolver library is not found in the
+classpath, external catalog files, specified in <code>catalogpath</code>,
+will be ignored and a warning
+will be logged. In this case, however, processing of inline entries will
+proceed normally.</p>
+<p>Currently, only <code>&lt;dtd&gt;</code> and
+<code>&lt;entity&gt;</code> elements may be specified inline; these
+roughly correspond to OASIS catalog entry types <code>PUBLIC</code> and
+<code>URI</code> respectively. By contrast, external catalog files
+may use any of the entry types defined in the
+<a href="http://oasis-open.org/committees/entity/spec-2001-08-06.html">
++OASIS specification</a>.</p>
+<h3><a name="ResolverAlgorithm">Entity/DTD/URI Resolution Algorithm</a></h3>
+
+When an entity, DTD, or URI is looked up by the XML processor, the
+XMLCatalog searches its list of entries to see if any match. That is,
+it attempts to match the <code>publicId</code> attribute of each entry
+with the PublicID or URI of the entity to be resolved. Assuming a
+matching entry is found, XMLCatalog then executes the following steps:
+
+<h4>1. Filesystem lookup</h4>
+
+<p>The <code>location</code> is first looked up in the filesystem. If
+the <code>location</code> is a relative path, the ant project basedir
+attribute is used as the base directory. If the <code>location</code>
+specifies an absolute path, it is used as is. Once we have an
+absolute path in hand, we check to see if a valid and readable file
+exists at that path. If so, we are done. If not, we proceed to the
+next step.</p>
+
+<h4>2. Classpath lookup</h4>
+
+<p>The <code>location</code> is next looked up in the classpath.
+Recall that jar files are merely fancy zip files. For classpath
+lookup, the <code>location</code> is used as is (no base is
+prepended). We use a Classloader to attempt to load the resource from
+the classpath. For example, if hello.jar is in the classpath and it
+contains <code>foo/bar/blat.dtd</code> it will resolve an entity whose
+<code>location</code> is <code>foo/bar/blat.dtd</code>. Of course, it
+will <em>not</em> resolve an entity whose <code>location</code> is
+<code>blat.dtd</code>.
+
+
+<h4>3a. Apache xml-commons resolver lookup</h4>
+
+<p>What happens next depends on whether the resolver library from
+xml-commons is available on the classpath. If so, we defer all
+further attempts at resolving to it. The resolver library supports
+extremely sophisticated functionality like URL rewriting and so on,
+which can be accessed by making the appropriate entries in external
+catalog files (XMLCatalog does not yet provide inline support for all
+of the entries defined in the <a
+href="http://oasis-open.org/committees/entity/spec-2001-08-06.html">OASIS
+standard</a>).</p>
+
+<h4>3. URL-space lookup</h4>
+
+<p>Finally, we attempt to make a URL out of the <code>location</code>.
+At first this may seem like this would defeat the purpose of
+XMLCatalogs -- why go back out to the internet? But in fact, this can
+be used to (in a sense) implement HTTP redirects, substituting one URL
+for another. The mapped-to URL might also be served by a local web
+server. If the URL resolves to a valid and readable resource, we are
+done. Otherwise, we give up. In this case, the XML processor will
+perform its normal resolution algorithm. Depending on the processor
+configuration, further resolution failures may or may not result in
+fatal (i.e. build-ending) errors.</p>
+
+<h3>XMLCatalog attributes</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">id</td>
+ <td valign="top">a unique name for an XMLCatalog, used for referencing
+the
+ XMLCatalog's contents from another XMLCatalog</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">refid</td>
+ <td valign="top">the <code>id</code> of another XMLCatalog whose
+contents
+ you would like to be used for this XMLCatalog</td>
+ <td valign="top" align="center">No</td>
+ </tr>
+</table>
+
+<h3>XMLCatalog nested elements</h3>
+<h4>dtd/entity</h4>
+<p>The <code>dtd</code> and <code>entity</code> elements used to specify
+XMLCatalogs are identical in their structure</p>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">publicId</td>
+ <td valign="top">The public identifier used when defining a dtd or
+entity,
+ e.g. <code>&quot;-//Sun Microsystems, Inc.//DTD Web Application
+2.2//EN&quot;</code>
+ </td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">location</td>
+ <td valign="top">The location of the local replacement to be used for
+the public identifier specified. This may be specified as a file name,
+resource name found on the classpath, or a URL. Relative paths will
+be resolved according to the base, which by default is the Ant project
+basedir.
+ </td>
+ <td valign="top" align="center">Yes</td>
+ </tr>
+</table>
+<h4>classpath</h4>
+<p>The classpath to use for <a href="#ResolverAlgorithm">entity
+resolution</a>. The nested <code>&lt;classpath&gt;</code> is a
+<a href="../using.html#path">path</a>-like structure.</p>
+<h4>catalogpath</h4>
+<p>
+The nested <code>catalogpath</code> element is a <a
+href="../using.html#path">path</a>-like structure listing catalog files to
+search. All files in this path are assumed to be OASIS catalog files, in
+either
+<a href="http://oasis-open.org/committees/entity/background/9401.html">
+plain text format</a> or <a
+href="http://www.oasis-open.org/committees/entity/spec-2001-08-06.html">
+XML format</a>. Entries specifying nonexistent files will be ignored. If the
+resolver library from xml-commons is not available in the classpath, all
+<code>catalogpaths</code> will be ignored and a warning will be logged.
+</p>
+<h3>Examples</h3>
+<p>Set up an XMLCatalog with a single dtd referenced locally in a user's
+home
+directory:</p>
+<blockquote><pre>
+ &lt;xmlcatalog&gt;
+ &lt;dtd
+ publicId=&quot;-//OASIS//DTD DocBook XML V4.1.2//EN&quot;
+ location=&quot;/home/dion/downloads/docbook/docbookx.dtd&quot;/&gt;
+ &lt;/xmlcatalog&gt;
+</pre></blockquote>
+<p>Set up an XMLCatalog with a multiple dtds to be found either in the
+filesystem (relative to the Ant project basedir) or in the classpath:
+</p>
+<blockquote><pre>
+ &lt;xmlcatalog id=&quot;commonDTDs&quot;&gt;
+ &lt;dtd
+ publicId=&quot;-//OASIS//DTD DocBook XML V4.1.2//EN&quot;
+ location=&quot;docbook/docbookx.dtd&quot;/&gt;
+ &lt;dtd
+ publicId=&quot;-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN&quot;
+ location=&quot;web-app_2_2.dtd&quot;/&gt;
+ &lt;/xmlcatalog&gt;
+</pre></blockquote>
+
+<p>Set up an XMLCatalog with a combination of DTDs and entities as
+well as a nested XMLCatalog and external catalog files in both
+formats:</p>
+
+<blockquote><pre>
+ &lt;xmlcatalog id=&quot;allcatalogs&quot;&gt;
+ &lt;dtd
+ publicId=&quot;-//ArielPartners//DTD XML Article V1.0//EN&quot;
+ location=&quot;com/arielpartners/knowledgebase/dtd/article.dtd&quot;/&gt;
+ &lt;entity
+ publicId=&quot;LargeLogo&quot;
+ location=&quot;com/arielpartners/images/ariel-logo-large.gif&quot;/&gt;
+ &lt;xmlcatalog refid="commonDTDs"/&gt;
+ &lt;catalogpath&gt;
+ &lt;pathelement location="/etc/sgml/catalog"/&gt;
+ &lt;fileset
+ dir=&quot;/anetwork/drive&quot;
+ includes=&quot;**/catalog&quot;/&gt;
+ &lt;fileset
+ dir=&quot;/my/catalogs&quot;
+ includes=&quot;**/catalog.xml&quot;/&gt;
+ &lt;/catalogpath&gt;
+ &lt;/xmlcatalog&gt;
+ &lt;/xmlcatalog&gt;
+</pre></blockquote>
+<p>To reference the above XMLCatalog in an <code>xslt</code> task:<p>
+<blockquote><pre>
+ &lt;xslt basedir="${source.doc}"
+ destdir="${dest.xdocs}"
+ extension=".xml"
+ style="${source.xsl.converter.docbook}"
+ includes="**/*.xml"
+ force="true"&gt;
+ &lt;xmlcatalog refid=&quot;allcatalogs&quot;/&gt;
+ &lt;/xslt&gt;
+</pre></blockquote>
+
+
+
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/Types/zipfileset.html b/framework/src/ant/apache-ant-1.9.6/manual/Types/zipfileset.html
new file mode 100644
index 00000000..955e2718
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/Types/zipfileset.html
@@ -0,0 +1,148 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+ <meta http-equiv="Content-Language" content="en-us">
+ <link rel="stylesheet" type="text/css" href="../stylesheets/style.css">
+<title>ZipFileSet Type</title>
+</head>
+<body>
+<h2><a name="fileset">ZipFileSet</a></h2>
+
+<p>A <code>&lt;zipfileset&gt;</code> is a special form of a <code>&lt;<a
+ href="fileset.html">fileset</a>&gt;</code> which can behave in 2
+different ways : <br>
+</p>
+<ul>
+ <li>When the <span style="font-style: italic;">src</span> attribute
+ is used - or a nested resource collection has been specified
+ (<em>since Apache Ant 1.7</em>), the zipfileset is populated with
+ zip entries found in the file <span style="font-style:
+ italic;">src</span>.<br>
+ </li>
+ <li>When the <span style="font-style: italic;">dir</span> attribute
+is used, the zipfileset is populated with filesystem files found under <span
+ style="font-style: italic;">dir</span>.<br>
+ </li>
+</ul>
+<p><code>&lt;zipfileset&gt;</code> supports all attributes of <code>&lt;<a
+ href="fileset.html">fileset</a>&gt;</code>
+ in addition to those listed below. Note that zip archives in general
+ don't contain entries with leading slashes so you shouldn't use
+ include/exclude patterns that start with slashes either.</p>
+
+<p>Since Ant 1.6, a zipfileset can be defined with the <span
+ style="font-style: italic;">id </span>attribute and referred to with
+the <span style="font-style: italic;">refid</span> attribute.<br>
+</p>
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tbody>
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td valign="top" align="center"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">prefix</td>
+ <td valign="top">all files in the fileset are prefixed with that
+path in the archive.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">fullpath</td>
+ <td valign="top">the file described by the fileset is placed at
+that exact location in the archive.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">src</td>
+ <td valign="top">may be used in place of the <i>dir</i> attribute
+ to specify a zip file whose contents will be extracted and included
+in the archive.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">filemode</td>
+ <td valign="top">A 3 digit octal string, specify the user, group
+and other modes in the standard Unix fashion. Only applies to
+plain files. Default is 644. <em>since Ant 1.5.2</em>.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">dirmode</td>
+ <td valign="top">A 3 digit octal string, specify the user, group
+and other modes in the standard Unix fashion. Only applies to
+directories. Default is 755. <em>since Ant 1.5.2</em>.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">encoding</td>
+ <td valign="top">The character encoding to use for filenames
+ inside the zip file. For a list of possible values see the <a
+ href="http://docs.oracle.com/javase/7/docs/technotes/guides/intl/encoding.doc.html">Supported Encodings</a>.
+ Defaults to the platform's default character encoding.
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">erroronmissingarchive</td>
+ <td valign="top">
+ Specify what happens if the archive does not exist.
+ If true, a build error will happen; if false, the fileset
+ will be ignored/empty.
+ Defaults to true.
+ <em>Since Ant 1.8.0</em>
+ </td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ </tbody>
+</table>
+<p>The <i>fullpath</i> attribute can only be set for filesets that
+represent a single file. The <i>prefix</i> and <i>fullpath</i>
+attributes cannot both be set on the same fileset.</p>
+<p>When using the <i>src</i> attribute, include and exclude patterns
+may be used to specify a subset of the archive for inclusion in the
+archive as with the <i>dir</i> attribute.</p>
+
+<p>Please note that currently only the <a
+href="../Tasks/tar.html">tar</a> and <a
+href="../Tasks/zip.html">zip</a> tasks use the permission.</p>
+
+<h3>Parameters specified as nested elements</h3>
+
+<h4>any file system based <a href="resources.html">resource</a> or
+single element resource collection</h4>
+
+<p>The specified resource will be used as src.</p>
+
+<h4>Examples</h4>
+<blockquote>
+ <pre> &lt;zip destfile="${dist}/manual.zip"&gt;<br> &lt;zipfileset dir="htdocs/manual" prefix="docs/user-guide"/&gt;<br> &lt;zipfileset dir="." includes="ChangeLog27.txt" fullpath="docs/ChangeLog.txt"/&gt;<br> &lt;zipfileset src="examples.zip" includes="**/*.html" prefix="docs/examples"/&gt;<br> &lt;/zip&gt;<br></pre>
+ <p>zips all files in the <code>htdocs/manual</code> directory into
+the <code>docs/user-guide</code> directory in the archive, adds the
+file <code>ChangeLog27.txt</code> in the current directory as <code>docs/ChangeLog.txt</code>,
+and includes all the html files in <code>examples.zip</code> under <code>docs/examples</code>.
+The archive might end up containing the files:</p>
+ <code> docs/user-guide/html/index.html<br>
+docs/ChangeLog.txt<br>
+docs/examples/index.html<br>
+ </code></blockquote>
+
+
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/antexternal.html b/framework/src/ant/apache-ant-1.9.6/manual/antexternal.html
new file mode 100644
index 00000000..02d2f7b5
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/antexternal.html
@@ -0,0 +1,160 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="stylesheets/style.css">
+<title>InputHandler</title>
+</head>
+
+<body>
+<h1>Using Apache Ant&trade; Tasks Outside of Ant</h1>
+
+<h2>Rationale</h2>
+
+<p>Apache Ant provides a rich set of tasks for buildfile creators and
+administrators. But what about programmers? Can the functionality
+provided by Ant tasks be used in java programs?</p>
+
+<p>Yes, and its quite easy. Before getting into the details, however,
+we should mention the pros and cons of this approach:
+
+<h3>Pros</h3>
+
+<table cellpadding="0" margin="0" border="1">
+<tr>
+<td><b>Robust</b></td>
+<td>
+Ant tasks are very robust. They have been banged on by many people.
+Ant tasks have been used in many different contexts, and have
+therefore been instrumented to take care of a great many boundary
+conditions and potentially obscure errors.
+</td>
+</tr>
+<tr>
+<td><b>Cross Platform</b></td>
+<td>
+Ant tasks are cross platform. They have been tested on all of the
+volume platforms, and several rather unusual ones (Netware and OS/390, to
+name a few).
+</td>
+</tr>
+<tr>
+<td><b>Community Support</b></td>
+<td>
+Using Ant tasks means you have less of your own code to support. Ant
+code is supported by the entire Apache Ant community.
+</td>
+</tr>
+</table>
+
+<h3>Cons</h3>
+
+<table cellpadding="0" margin="0" border="1">
+<tr>
+<td><b>Dependency on Ant Libraries</b></td>
+<td>
+Obviously, if you use an Ant task in your code, you will have to add
+"ant.jar" to your path. Of course, you could use a code optimizer to
+remove the unnecessary classes, but you will still probably require a
+chunk of the Ant core.
+</td>
+</tr>
+<tr>
+<td><b>Loss of Flexibility</b></td>
+<td>
+At some point, if you find yourself having to modify the Ant code, it
+probably makes more sense to "roll your own." Of course, you can
+still steal some code snippets and good ideas. This is the beauty of
+open source!
+</td>
+</tr>
+</table>
+
+
+<h2>Example</h2>
+
+<p>Let's say you want to unzip a zip file programmatically from java
+into a certain directory. Of course you could write your own routine
+to do this, but why not use the Ant task that has already been written?</p>
+
+<p>In my example, I wanted to be able to unzip a file from within an
+XSLT Transformation. XSLT Transformers can be extended by plugging in
+static methods in java. I therefore need a function something like
+this:</p>
+
+<pre>
+/**
+ * Unzip a zip file into a given directory.
+ *
+ * @param zipFilepath A pathname representing a local zip file
+ * @param destinationDir where to unzip the archive to
+ */
+ static public void unzip(String zipFilepath, String destinationDir)
+</pre>
+
+<p>
+The Ant task to perform this function is
+<code>org.apache.tools.ant.taskdefs.Expand</code>. All we have to do
+is create a dummy Ant <code>Project</code> and <code>Target</code>,
+set the <code>Task</code> parameters that would normally be set in a
+buildfile, and call <code>execute()</code>.</p>
+
+<p>First, let's make sure we have the proper includes:</p>
+
+<pre>
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Target;
+import org.apache.tools.ant.taskdefs.Expand;
+import java.io.File;
+</pre>
+
+<p>The function call is actually quite simple:</p>
+
+<pre>
+static public void unzip(String zipFilepath, String destinationDir) {
+
+ final class Expander extends Expand {
+ public Expander() {
+ project = new Project();
+ project.init();
+ taskType = "unzip";
+ taskName = "unzip";
+ target = new Target();
+ }
+ }
+ Expander expander = new Expander();
+ expander.setSrc(new File(zipfile));
+ expander.setDest(new File(destdir));
+ expander.execute();
+</pre>
+
+<p>In actual practice, you will probably want to add your own error
+handling code and you may not want to use a local inner class.
+However, the point of the example is to show how an Ant task can be
+called programmatically in relatively few lines of code.</p>
+
+<p>The question you are probably asking yourself at this point is:
+<i>How would I know which classes and methods have to be called in
+order to set up a dummy Project and Target?</i> The answer is: you
+don't. Ultimately, you have to be willing to get your feet wet and
+read the source code. The above example is merely designed to whet
+your appetite and get you started. Go for it!</p>
+
+
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/anttaskslist.html b/framework/src/ant/apache-ant-1.9.6/manual/anttaskslist.html
new file mode 100644
index 00000000..bd120494
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/anttaskslist.html
@@ -0,0 +1,41 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us"/>
+<link rel="stylesheet" type="text/css" href="stylesheets/style.css"/>
+<title>Apache Ant User Manual</title>
+<base target="mainFrame"/>
+</head>
+
+<body>
+
+
+<h2><a href="toc.html" target="navFrame">Table of Contents</a></h2>
+
+<h3>Apache Ant Tasks</h3>
+<ul class="inlinelist">
+<li><a href="tasksoverview.html" target="mainFrame">Overview of Ant Tasks</a></li>
+<li><a href="tasklist.html" target="navFrame">List of Tasks</a></li>
+<div style="padding-left:1em">
+ <li><a href="install.html#librarydependencies" target="mainFrame">Library Dependencies</a></li>
+</div>
+</ul>
+
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/argumentprocessor.html b/framework/src/ant/apache-ant-1.9.6/manual/argumentprocessor.html
new file mode 100644
index 00000000..2cd5202f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/argumentprocessor.html
@@ -0,0 +1,76 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="stylesheets/style.css">
+<title>The Command Line Processor Plugin: ArgumentProcessor</title>
+</head>
+
+<body>
+<h1>The Command Line Processor Plugin: ArgumentProcessor</h1>
+
+<h2><a name="definition">What is an ArgumentProcessor?</a></h2>
+
+<p>
+An <code>ArgumentProcessor</code> is a parser of command line argument which is
+then call before and after the build file is being parsed. Third party
+libraries may then be able to have custom argument line argument which modify
+Ant behaviour.
+</p>
+
+<p>
+An <code>ArgumentProcessor</code> is called each time Ant parse an unknown
+argument, an <code>ArgumentProcessor</code> doesn't take precedence over Ant to
+parse already suported options. It is then recommended to third party
+<code>ArgumentProcessor</code> implementation to chose specific 'enough'
+argument name, avoiding for instance one letter arguments.
+</p>
+
+<p>
+It is also called at the different phases so different behaviour can be
+implemented. It is called just after every arguments are parsed, just
+before the project is being configured (the build file being parsed),
+and just after. Some of the methods to be implemented return a boolean:
+if <code>true</code> is returned, Ant will terminate immediately, without
+error.
+</p>
+
+<p>
+Being called during all these phases, an <code>ArgumentProcessor</code>
+can just print some specific system properties and quit (like
+<code>-diagnose</code>), or print some specific properties of a project after
+being parsed and quit (like <code>-projectHelp</code>), or just set some
+custom properties on the project and let it run.
+</p>
+
+<h2><a name="repository">How to register it's own ArgumentProcessor</a></h2>
+
+<p>First, the <code>ArgumentProcessor</code> must be an implementation of
+<code>org.apache.tools.ant.ArgumentProcessor</code>.
+</p>
+
+<p>Then to decare it: create a file
+<code>META-INF/services/org.apache.tools.ant.ArgumentProcessor</code> which
+contains only one line the fully qualified name of the class of the
+implementation. This file together with the implementation class need then to
+be found in Ant's classpath.
+</p>
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/base_task_classes.html b/framework/src/ant/apache-ant-1.9.6/manual/base_task_classes.html
new file mode 100644
index 00000000..1b058ebb
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/base_task_classes.html
@@ -0,0 +1,114 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="stylesheets/style.css">
+<title>Tasks Designed for Extension</title>
+</head>
+
+<body>
+<h1>Tasks Designed for Extension</h1>
+
+<p>These classes are designed to be extended. Always start here when writing your own task.</p>
+
+<p><strong>The links will not work in the online version of this document.</strong></p>
+
+<table border="1">
+<thead>
+<tr>
+<th>
+Class
+</th>
+<th>
+Description
+</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td>
+<a href="api/org/apache/tools/ant/Task.html">Task</a>
+</td>
+<td>
+Base class for all tasks.
+</td>
+</tr>
+
+<tr>
+<td>
+<a href="api/org/apache/tools/ant/taskdefs/AbstractCvsTask.html">AbstractCvsTask</a>
+</td>
+<td>
+Another task can extend this with some customized output processing
+</td>
+</tr>
+
+<tr>
+<td>
+<a href="api/org/apache/tools/ant/taskdefs/JDBCTask.html">JDBCTask</a>
+</td>
+<td>
+Handles JDBC configuration needed by SQL type tasks.
+</td>
+</tr>
+
+<tr>
+<td>
+<a href="api/org/apache/tools/ant/taskdefs/MatchingTask.html">MatchingTask</a>
+</td>
+<td>
+This is an abstract task that should be used by all those tasks that require to include or exclude files based on pattern matching.
+</td>
+</tr>
+
+<tr>
+<td>
+<a href="api/org/apache/tools/ant/taskdefs/Pack.html">Pack</a>
+</td>
+<td>
+Abstract Base class for pack tasks.
+</td>
+</tr>
+
+
+<tr>
+<td>
+<a href="api/org/apache/tools/ant/taskdefs/Unpack.html">Unpack</a>
+</td>
+<td>
+Abstract Base class for unpack tasks.
+</td>
+</tr>
+
+<tr>
+<td>
+<a href="api/org/apache/tools/ant/dispatch/DispatchTask.html">DispatchTask</a>
+</td>
+<td>
+Abstract Base class for tasks that may have multiple actions.
+</td>
+</tr>
+
+</tbody>
+</table>
+
+
+
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/clonevm.html b/framework/src/ant/apache-ant-1.9.6/manual/clonevm.html
new file mode 100644
index 00000000..b0a53420
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/clonevm.html
@@ -0,0 +1,52 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="stylesheets/style.css">
+<title>ant.build.clonevm</title>
+</head>
+
+<body>
+
+<h2><a name="clonevm">ant.build.clonevm</a></h2>
+
+<p><em>Since Apache Ant 1.7</em></p>
+
+<p>The value of the ant.build.clonevm system property controls how Ant
+instruments forked Java Virtual Machines. The <a
+href="Tasks/java.html">java</a> and <a
+href="Tasks/junit.html">junit</a> tasks support clonevm
+attributes to control the VMs on a task-by-task basis while the system
+property applies to all forked Java VMs.</p>
+
+<p>If the value of the property is true, then all system properties of
+the forked Java Virtual Machine will be the same as those of the Java
+VM running Ant. In addition, if you set ant.build.clonevm to true and <a
+href="sysclasspath.html">build.sysclasspath</a> has not been set, the
+bootclasspath of forked Java VMs gets constructed as if
+build.sysclasspath had the value "last".</p>
+
+<p>Note that this has to be a system property, so it cannot be
+specified on the Ant command line. Use the ANT_OPTS environment
+variable instead.</p>
+
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/conceptstypeslist.html b/framework/src/ant/apache-ant-1.9.6/manual/conceptstypeslist.html
new file mode 100644
index 00000000..ae6ca1a8
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/conceptstypeslist.html
@@ -0,0 +1,90 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us"/>
+<link rel="stylesheet" type="text/css" href="stylesheets/style.css"/>
+<title>Apache Ant User Manual</title>
+<base target="mainFrame"/>
+</head>
+
+<body>
+
+<h2><a href="toc.html" target="navFrame">Table of Contents</a></h2>
+
+<h3>Concepts</h3>
+<ul class="inlinelist">
+<li><a href="targets.html">Targets and Extension-Points</a></li>
+<li><a href="properties.html">Properties and PropertyHelpers</a></li>
+<li><a href="clonevm.html">ant.build.clonevm</a></li>
+<li><a href="sysclasspath.html">build.sysclasspath</a></li>
+<li><a href="javacprops.html">Ant properties controlling javac</a></li>
+<li><a href="Tasks/common.html">Common Attributes</a></li>
+<li><a href="ifunless.html">If and Unless Attributes</a></li>
+</ul>
+
+<h3>List of Types</h3>
+<ul class="inlinelist">
+<li><a href="Types/classfileset.html">Class Fileset</a></li>
+<li><a href="Types/description.html">Description Type</a></li>
+<li><a href="dirtasks.html">Directory-based Tasks</a></li>
+<li><a href="Types/dirset.html">DirSet</a></li>
+<li><a href="Types/extension.html">Extension Package</a></li>
+<li><a href="Types/extensionset.html">Set of Extension Packages</a></li>
+<li><a href="Types/filelist.html">FileList</a></li>
+<li><a href="Types/fileset.html">FileSet</a></li>
+<li><a href="Types/mapper.html">File Mappers</a></li>
+<li><a href="Types/filterchain.html">FilterChains and FilterReaders</a></li>
+<li><a href="Types/filterset.html">FilterSet</a></li>
+<li><a href="Types/multirootfileset.html">MultiRootFileSet</a></li>
+<li><a href="Types/patternset.html">PatternSet</a></li>
+<li><a href="using.html#path">Path-like Structures</a></li>
+<li><a href="Types/permissions.html">Permissions</a></li>
+<li><a href="Types/propertyset.html">PropertySet</a></li>
+<li><a href="Types/redirector.html">I/O Redirectors</a></li>
+<li><a href="Types/regexp.html">Regexp</a></li>
+<li><a href="Types/resources.html">Resources</a></li>
+<li><a href="Types/resources.html#collection">Resource Collections</a></li>
+<li><a href="Types/selectors.html">Selectors</a></li>
+<li><a href="Types/tarfileset.html">TarFileSet</a></li>
+<li><a href="Types/xmlcatalog.html">XMLCatalog</a></li>
+<li><a href="Types/zipfileset.html">ZipFileSet</a></li>
+</ul>
+
+<h3>Namespace</h3>
+<ul class="inlinelist">
+<li><a href="Types/namespace.html">Namespace Support</a></li>
+</ul>
+
+<h3>Antlib</h3>
+<ul class="inlinelist">
+<li><a href="Types/antlib.html">Antlib</a></li>
+<li><a href="Types/antlib.html#antlibnamespace">Antlib namespace</a></li>
+<li><a href="Types/antlib.html#currentnamespace">Current namespace</a></li>
+</ul>
+
+<h3>Custom Components</h3>
+<ul class="inlinelist">
+<li><a href="Types/custom-programming.html">Custom Components</a></li>
+<li><a href="Types/custom-programming.html#customconditions">Conditions</a></li>
+<li><a href="Types/custom-programming.html#customselectors">Selectors</a></li>
+<li><a href="Types/custom-programming.html#filterreaders">FilterReaders</a></li>
+</ul>
+
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/cover.html b/framework/src/ant/apache-ant-1.9.6/manual/cover.html
new file mode 100644
index 00000000..75ceb842
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/cover.html
@@ -0,0 +1,53 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="stylesheets/style.css">
+<title>Apache Ant 1.9.6 User Manual</title>
+</head>
+
+<body bgcolor="#FFFFFF">
+<div align="center">
+ <h1><img src="images/ant_logo_large.gif" width="190" height="120"></h1>
+ <h1>Apache Ant&trade; 1.9.6 Manual</h1>
+ <p align="left">This is the manual for version 1.9.6 of
+ <a target="_top" href="http://ant.apache.org/index.html">Apache Ant</a>.
+ If your version
+ of Ant (as verified with <tt>ant -version</tt>) is older or newer than this
+ version then this is not the correct manual set. Please use the documentation
+ appropriate to your current version. Also, if you are using a version
+ older than the most recent release, we recommend an upgrade to fix bugs
+ as well as provide new functionality. </p>
+ <p>&nbsp;</p>
+
+ <p align="left">Ant's manual and API documentation is part of
+ the <a href="http://ant.apache.org/bindownload.cgi">binary</a>
+ distributions or available as a
+ separate <a href="http://ant.apache.org/manualdownload.cgi">archive</a>.
+ Manuals for older releases are available for
+ download
+ <a href="http://ant.apache.org/bindownload.cgi#Old Ant Releases">as
+ well</a>.</p>
+
+ <p>Apache Ant, Apache Ivy, Ant, Ivy, Apache, the Apache feather logo, and the Apache Ant project logos are trademarks of The Apache Software Foundation.</p>
+</div>
+
+
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/credits.html b/framework/src/ant/apache-ant-1.9.6/manual/credits.html
new file mode 100644
index 00000000..72916def
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/credits.html
@@ -0,0 +1,70 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<meta http-equiv="Content-Type" content="text/html;charset=ISO-8859-1">
+<title>Apache Ant User Manual - Credits</title>
+</head>
+
+<body>
+
+<div align="center">
+<h1>Apache Ant User Manual</h1>
+<p>by</p>
+</div>
+<!-- Names are in alphabetical order, on last name -->
+<ul>
+ <li>Stephane Bailliez (<a href="mailto:sbailliez@imediation.com">sbailliez@imediation.com</a>)</li>
+ <li>Nicola Ken Barozzi (<a href="mailto:nicolaken@apache.org">nicolaken@apache.org</a>)</li>
+ <li>Jacques Bergeron (<a href="mailto:jacques.bergeron@dogico.com">jacques.bergeron@dogico.com</a>)</li>
+ <li>Stefan Bodewig (<a href="mailto:stefan.bodewig@freenet.de">stefan.bodewig@freenet.de</a>)</li>
+ <li>Patrick Chanezon (<a href="mailto:chanezon@netscape.com">chanezon@netscape.com</a>)</li>
+ <li>James Duncan Davidson (<a href="mailto:duncan@x180.com">duncan@x180.com</a>)</li>
+ <li>Tom Dimock (<a href="mailto:tad1@cornell.edu">tad1@cornell.edu</a>)</li>
+ <li>Peter Donald (<a href="mailto:donaldp@apache.org">donaldp@apache.org</a>)</li>
+ <li>dIon Gillard (<a href="mailto:dion@apache.org">dion@apache.org</a>)</li>
+ <li>Erik Hatcher (<a href="mailto:ehatcher@apache.org">ehatcher@apache.org</a>)</li>
+ <li>Diane Holt (<a href="mailto:holtdl@yahoo.com">holtdl@yahoo.com</a>)</li>
+ <li>Bill Kelly (<a href="mailto:bill.kelly@softwired-inc.com">bill.kelly@softwired-inc.com</a>)</li>
+ <li>Martijn Kruithof</li>
+ <li>Arnout J. Kuiper (<a href="mailto:ajkuiper@wxs.nl">ajkuiper@wxs.nl</a>)</li>
+ <li>Antoine Lévy-Lambert</li>
+ <li>Conor MacNeill</li>
+ <li>Jan Matčrne</li>
+ <li>Stefano Mazzocchi (<a href="mailto:stefano@apache.org">stefano@apache.org</a>)</li>
+ <li>Erik Meade (<a href="mailto:emeade@geekfarm.org">emeade@geekfarm.org</a>)</li>
+ <li>Sam Ruby (<a href="mailto:rubys@us.ibm.com">rubys@us.ibm.com</a>)</li>
+ <li>Nico Seessle (<a href="mailto:nico@seessle.de">nico@seessle.de</a>)</li>
+ <li>Jon S. Stevens (<a href="mailto:jon@latchkey.com">jon@latchkey.com</a>)</li>
+ <li>Wolf Siberski</li>
+ <li>Magesh Umasankar</li>
+ <li>Roger Vaughn (<a href="mailto:rvaughn@seaconinc.com">rvaughn@seaconinc.com</a>)</li>
+ <li>Dave Walend (<a href="mailto:dwalend@cs.tufts.edu">dwalend@cs.tufts.edu</a>)</li>
+ <li>Phillip Wells (<a href="mailto:philwells@rocketmail.com">philwells@rocketmail.com</a>)</li>
+ <li>Christoph Wilhelms</li>
+ <li>Craeg Strong (<a href="mailto:cstrong@arielpartners.com">cstrong@arielpartners.com</a>)</li>
+</ul>
+
+<center>
+<p>Version: 1.9.6</p>
+</center>
+
+
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/develop.html b/framework/src/ant/apache-ant-1.9.6/manual/develop.html
new file mode 100644
index 00000000..ed06d301
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/develop.html
@@ -0,0 +1,544 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="stylesheets/style.css">
+<title>Writing Your Own Task</title>
+</head>
+
+<body>
+<h1>Developing with Apache Ant</h1>
+
+<h2><a name="writingowntask">Writing Your Own Task</a></h2>
+<p>It is very easy to write your own task:</p>
+<ol>
+ <li>Create a Java class that extends <code>org.apache.tools.ant.Task</code>
+ or <a href="base_task_classes.html">another class</a> that was designed to be extended.</li>
+
+ <li>For each attribute, write a <i>setter</i> method. The setter method must be a
+ <code>public void</code> method that takes a single argument. The
+ name of the method must begin with <code>set</code>, followed by the
+ attribute name, with the first character of the name in uppercase, and the rest in
+ lowercase<a href="#footnote-1"><sup>*</sup></a>. That is, to support an attribute named
+ <code>file</code> you create a method <code>setFile</code>.
+ Depending on the type of the argument, Ant will perform some
+ conversions for you, see <a href="#set-magic">below</a>.</li>
+
+ <li>If your task shall contain other tasks as nested elements (like
+ <a href="Tasks/parallel.html"><code>parallel</code></a>), your
+ class must implement the interface
+ <code>org.apache.tools.ant.TaskContainer</code>. If you do so, your
+ task can not support any other nested elements. See
+ <a href="#taskcontainer">below</a>.</li>
+
+ <li>If the task should support character data (text nested between the
+ start end end tags), write a <code>public void addText(String)</code>
+ method. Note that Ant does <strong>not</strong> expand properties on
+ the text it passes to the task.</li>
+
+ <li>For each nested element, write a <i>create</i>, <i>add</i> or
+ <i>addConfigured</i> method. A create method must be a
+ <code>public</code> method that takes no arguments and returns an
+ <code>Object</code> type. The name of the create method must begin
+ with <code>create</code>, followed by the element name. An add (or
+ addConfigured) method must be a <code>public void</code> method that
+ takes a single argument of an <code>Object</code> type with a
+ no-argument constructor. The name of the add (addConfigured) method
+ must begin with <code>add</code> (<code>addConfigured</code>),
+ followed by the element name. For a more complete discussion see
+ <a href="#nested-elements">below</a>.</li>
+
+ <li>Write a <code>public void execute</code> method, with no arguments, that
+ throws a <code>BuildException</code>. This method implements the task
+ itself.</li>
+</ol>
+
+<hr>
+<p><a name="footnote-1">*</a> Actually the case of the letters after
+the first one doesn't really matter to Ant, using all lower case is a
+good convention, though.</p>
+
+<h3>The Life-cycle of a Task</h3>
+<ol>
+ <li>
+ The xml element that contains the tag corresponding to the
+ task gets converted to an UnknownElement at parser time.
+ This UnknownElement gets placed in a list within a target
+ object, or recursively within another UnknownElement.
+ </li>
+ <li>
+ When the target is executed, each UnknownElement is invoked
+ using an <code>perform()</code> method. This instantiates
+ the task. This means that tasks only gets
+ instantiated at run time.
+ </li>
+
+ <li>The task gets references to its project and location inside the
+ buildfile via its inherited <code>project</code> and
+ <code>location</code> variables.</li>
+
+ <li>If the user specified an <code>id</code> attribute to this task,
+ the project
+ registers a reference to this newly created task, at run
+ time.</li>
+
+ <li>The task gets a reference to the target it belongs to via its
+ inherited <code>target</code> variable.</li>
+
+ <li><code>init()</code> is called at run time.</li>
+
+ <li>All child elements of the XML element corresponding to this task
+ are created via this task's <code>createXXX()</code> methods or
+ instantiated and added to this task via its <code>addXXX()</code>
+ methods, at run time. Child elements corresponding
+ to <code>addConfiguredXXX()</code> are created at this point but
+ the actual <code>addCondifgired</code> method is not called.</li>
+
+ <li>All attributes of this task get set via their corresponding
+ <code>setXXX</code> methods, at runtime.</li>
+
+ <li>The content character data sections inside the XML element
+ corresponding to this task is added to the task via its
+ <code>addText</code> method, at runtime.</li>
+
+ <li>All attributes of all child elements get set via their corresponding
+ <code>setXXX</code> methods, at runtime.</li>
+
+ <li>If child elements of the XML element corresponding to this task
+ have been created for <code>addConfiguredXXX()</code> methods,
+ those methods get invoked now.</li>
+
+ <li><a name="execute"><code>execute()</code></a> is called at runtime.
+ If <code>target1</code> and <code>target2</code> both depend
+ on <code>target3</code>, then running
+ <code>'ant target1 target2'</code> will run all tasks in
+ <code>target3</code> twice.</li>
+</ol>
+
+<h3><a name="set-magic">Conversions Ant will perform for attributes</a></h3>
+
+<p>Ant will always expand properties before it passes the value of an
+attribute to the corresponding setter method. <b>Since Ant 1.8</b>, it is
+possible to <a href="Tasks/propertyhelper.html">extend Ant's property handling</a>
+such that a non-string Object may be the result of the evaluation of a string
+containing a single property reference. These will be assigned directly via
+setter methods of matching type. Since it requires some beyond-the-basics
+intervention to enable this behavior, it may be a good idea to flag attributes
+intended to permit this usage paradigm.
+</p>
+
+<p>The most common way to write an attribute setter is to use a
+<code>java.lang.String</code> argument. In this case Ant will pass
+the literal value (after property expansion) to your task. But there
+is more! If the argument of you setter method is</p>
+
+<ul>
+
+ <li><code>boolean</code>, your method will be passed the value
+ <i>true</i> if the value specified in the build file is one of
+ <code>true</code>, <code>yes</code>, or <code>on</code> and
+ <i>false</i> otherwise.</li>
+
+ <li><code>char</code> or <code>java.lang.Character</code>, your
+ method will be passed the first character of the value specified in
+ the build file.</li>
+
+ <li>any other primitive type (<code>int</code>, <code>short</code>
+ and so on), Ant will convert the value of the attribute into this
+ type, thus making sure that you'll never receive input that is not a
+ number for that attribute.</li>
+
+ <li><code>java.io.File</code>, Ant will first determine whether the
+ value given in the build file represents an absolute path name. If
+ not, Ant will interpret the value as a path name relative to the
+ project's basedir.</li>
+
+ <li><code>org.apache.tools.ant.types.Resource</code>
+ <code>org.apache.tools.ant.types.Resource</code>, Ant will
+ resolve the string as a <code>java.io.File</code> as above, then
+ pass in as a <code>org.apache.tools.ant.types.resources.FileResource</code>.
+ <b>Since Ant 1.8</b>
+ </li>
+
+ <li><code>org.apache.tools.ant.types.Path</code>, Ant will tokenize
+ the value specified in the build file, accepting <code>:</code> and
+ <code>;</code> as path separators. Relative path names will be
+ interpreted as relative to the project's basedir.</li>
+
+ <li><code>java.lang.Class</code>, Ant will interpret the value
+ given in the build file as a Java class name and load the named
+ class from the system class loader.</li>
+
+ <li>any other type that has a constructor with a single
+ <code>String</code> argument, Ant will use this constructor to
+ create a new instance from the value given in the build file.</li>
+
+ <li>A subclass of
+ <code>org.apache.tools.ant.types.EnumeratedAttribute</code>, Ant
+ will invoke this classes <code>setValue</code> method. Use this if
+ your task should support enumerated attributes (attributes with
+ values that must be part of a predefined set of values). See
+ <code>org/apache/tools/ant/taskdefs/FixCRLF.java</code> and the
+ inner <code>AddAsisRemove</code> class used in <code>setCr</code>
+ for an example.</li>
+
+ <li>A (Java 5) enumeration. Ant will call the setter with the enum constant
+ matching the value given in the build file. This is easier than using
+ <code>EnumeratedAttribute</code> and can result in cleaner code, but of course
+ your task will not run on JDK 1.4 or earlier. Note that any override of
+ <code>toString()</code> in the enumeration is ignored; the build file must use
+ the declared name (see <code>Enum.getName()</code>). You may wish to use lowercase
+ enum constant names, in contrast to usual Java style, to look better in build files.
+ <em>As of Ant 1.7.0.</em></li>
+
+</ul>
+
+<p>What happens if more than one setter method is present for a given
+attribute? A method taking a <code>String</code> argument will always
+lose against the more specific methods. If there are still more
+setters Ant could chose from, only one of them will be called, but we
+don't know which, this depends on the implementation of your Java
+virtual machine.</p>
+
+<h3><a name="nested-elements">Supporting nested elements</a></h3>
+
+<p>Let's assume your task shall support nested elements with the name
+<code>inner</code>. First of all, you need a class that represents
+this nested element. Often you simply want to use one of Ant's
+classes like <code>org.apache.tools.ant.types.FileSet</code> to
+support nested <code>fileset</code> elements.</p>
+
+<p>Attributes of the nested elements or nested child elements of them
+will be handled using the same mechanism used for tasks (i.e. setter
+methods for attributes, addText for nested text and
+create/add/addConfigured methods for child elements).</p>
+
+<p>Now you have a class <code>NestedElement</code> that is supposed to
+be used for your nested <code>&lt;inner&gt;</code> elements, you have
+three options:</p>
+
+<ol>
+ <li><code>public NestedElement createInner()</code></li>
+ <li><code>public void addInner(NestedElement anInner)</code></li>
+ <li><code>public void addConfiguredInner(NestedElement anInner)</code></li>
+</ol>
+
+<p>What is the difference?</p>
+
+<p>Option 1 makes the task create the instance of
+<code>NestedElement</code>, there are no restrictions on the type.
+For the options 2 and 3, Ant has to create an instance of
+<code>NestedInner</code> before it can pass it to the task, this
+means, <code>NestedInner</code> must have a <code>public</code> no-arg
+ constructor or a <code>public</code> one-arg constructor
+ taking a Project class as a parameter.
+This is the only difference between options 1 and 2.</p>
+
+<p>The difference between 2 and 3 is what Ant has done to the object
+before it passes it to the method. <code>addInner</code> will receive
+an object directly after the constructor has been called, while
+<code>addConfiguredInner</code> gets the object <em>after</em> the
+attributes and nested children for this new object have been
+handled.</p>
+
+<p>What happens if you use more than one of the options? Only one of
+the methods will be called, but we don't know which, this depends on
+the implementation of your Java virtual machine.</p>
+
+<h3><a name="nestedtype">Nested Types</a></h3>
+If your task needs to nest an arbitrary type that has been defined
+ using <code>&lt;typedef&gt;</code> you have two options.
+ <ol>
+ <li><code>public void add(Type type)</code></li>
+ <li><code>public void addConfigured(Type type)</code></li>
+ </ol>
+ The difference between 1 and 2 is the same as between 2 and 3 in the
+ previous section.
+ <p>
+ For example suppose one wanted to handle objects object of type
+ org.apache.tools.ant.taskdefs.condition.Condition, one may
+ have a class:
+ </p>
+ <blockquote>
+ <pre>
+public class MyTask extends Task {
+ private List conditions = new ArrayList();
+ public void add(Condition c) {
+ conditions.add(c);
+ }
+ public void execute() {
+ // iterator over the conditions
+ }
+}
+ </pre>
+ </blockquote>
+ <p>
+ One may define and use this class like this:
+ </p>
+ <blockquote>
+ <pre>
+&lt;taskdef name="mytask" classname="MyTask" classpath="classes"/&gt;
+&lt;typedef name="condition.equals"
+ classname="org.apache.tools.ant.taskdefs.conditions.Equals"/&gt;
+&lt;mytask&gt;
+ &lt;condition.equals arg1="${debug}" arg2="true"/&gt;
+&lt;/mytask&gt;
+ </pre>
+ </blockquote>
+ <p>
+ A more complicated example follows:
+ </p>
+ <blockquote>
+ <pre>
+public class Sample {
+ public static class MyFileSelector implements FileSelector {
+ public void setAttrA(int a) {}
+ public void setAttrB(int b) {}
+ public void add(Path path) {}
+ public boolean isSelected(File basedir, String filename, File file) {
+ return true;
+ }
+ }
+
+ interface MyInterface {
+ void setVerbose(boolean val);
+ }
+
+ public static class BuildPath extends Path {
+ public BuildPath(Project project) {
+ super(project);
+ }
+
+ public void add(MyInterface inter) {}
+ public void setUrl(String url) {}
+ }
+
+ public static class XInterface implements MyInterface {
+ public void setVerbose(boolean x) {}
+ public void setCount(int c) {}
+ }
+}
+ </pre>
+ </blockquote>
+ <p>
+ This class defines a number of static classes that implement/extend
+ Path, MyFileSelector and MyInterface. These may be defined and used
+ as follows:
+ </p>
+ <pre>
+ <blockquote>
+&lt;typedef name="myfileselector" classname="Sample$MyFileSelector"
+ classpath="classes" loaderref="classes"/&gt;
+&lt;typedef name="buildpath" classname="Sample$BuildPath"
+ classpath="classes" loaderref="classes"/&gt;
+&lt;typedef name="xinterface" classname="Sample$XInterface"
+ classpath="classes" loaderref="classes"/&gt;
+
+&lt;copy todir="copy-classes"&gt;
+ &lt;fileset dir="classes"&gt;
+ &lt;myfileselector attra="10" attrB="-10"&gt;
+ &lt;buildpath path="." url="abc"&gt;
+ &lt;xinterface count="4"/&gt;
+ &lt;/buildpath&gt;
+ &lt;/myfileselector&gt;
+ &lt;/fileset&gt;
+&lt;/copy&gt;
+ </blockquote>
+ </pre>
+
+<h3><a name="taskcontainer">TaskContainer</a></h3>
+
+<p>The <code>TaskContainer</code> consists of a single method,
+<code>addTask</code> that basically is the same as an <a
+href="#nested-elements">add method</a> for nested elements. The task
+instances will be configured (their attributes and nested elements
+have been handled) when your task's <code>execute</code> method gets
+invoked, but not before that.</p>
+
+<p>When we <a href="#execute">said</a> <code>execute</code> would be
+called, we lied ;-). In fact, Ant will call the <code>perform</code>
+method in <code>org.apache.tools.ant.Task</code>, which in turn calls
+<code>execute</code>. This method makes sure that <a
+href="#buildevents">Build Events</a> will be triggered. If you
+execute the task instances nested into your task, you should also
+invoke <code>perform</code> on these instances instead of
+<code>execute</code>.</p>
+
+<h3>Example</h3>
+<p>Let's write our own task, which prints a message on the
+<code>System.out</code> stream.
+The task has one attribute, called <code>message</code>.</p>
+<blockquote>
+<pre>
+package com.mydomain;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Task;
+
+public class MyVeryOwnTask extends Task {
+ private String msg;
+
+ // The method executing the task
+ public void execute() throws BuildException {
+ System.out.println(msg);
+ }
+
+ // The setter for the &quot;message&quot; attribute
+ public void setMessage(String msg) {
+ this.msg = msg;
+ }
+}
+</pre>
+</blockquote>
+<p>It's really this simple ;-)</p>
+<p>Adding your task to the system is rather simple too:</p>
+<ol>
+ <li>Make sure the class that implements your task is in the classpath when
+ starting Ant.</li>
+ <li>Add a <code>&lt;taskdef&gt;</code> element to your project.
+ This actually adds your task to the system.</li>
+ <li>Use your task in the rest of the buildfile.</li>
+</ol>
+
+<h3>Example</h3>
+<blockquote>
+<pre>
+&lt;?xml version=&quot;1.0&quot;?&gt;
+
+&lt;project name=&quot;OwnTaskExample&quot; default=&quot;main&quot; basedir=&quot;.&quot;&gt;
+ &lt;taskdef name=&quot;mytask&quot; classname=&quot;com.mydomain.MyVeryOwnTask&quot;/&gt;
+
+ &lt;target name=&quot;main&quot;&gt;
+ &lt;mytask message=&quot;Hello World! MyVeryOwnTask works!&quot;/&gt;
+ &lt;/target&gt;
+&lt;/project&gt;
+</pre>
+</blockquote>
+
+<h3>Example 2</h3>
+To use a task directly from the buildfile which created it, place the
+<code>&lt;taskdef&gt;</code> declaration inside a target
+<i>after the compilation</i>. Use the <code>classpath</code> attribute of
+<code>&lt;taskdef&gt;</code> to point to where the code has just been
+compiled.
+<blockquote>
+<pre>
+&lt;?xml version=&quot;1.0&quot;?&gt;
+
+&lt;project name=&quot;OwnTaskExample2&quot; default=&quot;main&quot; basedir=&quot;.&quot;&gt;
+
+ &lt;target name=&quot;build&quot; &gt;
+ &lt;mkdir dir=&quot;build&quot;/&gt;
+ &lt;javac srcdir=&quot;source&quot; destdir=&quot;build&quot;/&gt;
+ &lt;/target&gt;
+
+ &lt;target name=&quot;declare&quot; depends=&quot;build&quot;&gt;
+ &lt;taskdef name=&quot;mytask&quot;
+ classname=&quot;com.mydomain.MyVeryOwnTask&quot;
+ classpath=&quot;build&quot;/&gt;
+ &lt;/target&gt;
+
+ &lt;target name=&quot;main&quot; depends=&quot;declare&quot;&gt;
+ &lt;mytask message=&quot;Hello World! MyVeryOwnTask works!&quot;/&gt;
+ &lt;/target&gt;
+&lt;/project&gt;
+</pre>
+</blockquote>
+
+<p>Another way to add a task (more permanently), is to add the task name and
+implementing class name to the <code>default.properties</code> file in the
+<code>org.apache.tools.ant.taskdefs</code>
+package. Then you can use it as if it were a built-in task.</p>
+
+<hr>
+<h2><a name="buildevents">Build Events</a></h2>
+<p>Ant is capable of generating build events as it performs the tasks necessary to build a project.
+Listeners can be attached to Ant to receive these events. This capability could be used, for example,
+to connect Ant to a GUI or to integrate Ant with an IDE.
+</p>
+<p>To use build events you need to create an ant <code>Project</code> object. You can then call the
+<code>addBuildListener</code> method to add your listener to the project. Your listener must implement
+the <code>org.apache.tools.antBuildListener</code> interface. The listener will receive BuildEvents
+for the following events</p>
+<ul>
+ <li>Build started</li>
+ <li>Build finished</li>
+ <li>Target started</li>
+ <li>Target finished</li>
+ <li>Task started</li>
+ <li>Task finished</li>
+ <li>Message logged</li>
+</ul>
+
+<p>If the build file invokes another build file via
+<a href="Tasks/ant.html"><code>&lt;ant&gt;</code></a> or
+<a href="Tasks/subant.html"><code>&lt;subant&gt;</code></a> or uses
+<a href="Tasks/antcall.html"><code>&lt;antcall&gt;</code></a>, you are creating a
+new Ant "project" that will send target and task level events of its
+own but never sends build started/finished events. Ant 1.6.2
+introduces an extension of the BuildListener interface named
+SubBuildListener that will receive two new events for</p>
+<ul>
+ <li>SubBuild started</li>
+ <li>SubBuild finished</li>
+</ul>
+<p>If you are interested in those events, all you need to do is to
+implement the new interface instead of BuildListener (and register the
+listener, of course).</p>
+
+<p>If you wish to attach a listener from the command line you may use the
+<code>-listener</code> option. For example:</p>
+<blockquote>
+ <pre>ant -listener org.apache.tools.ant.XmlLogger</pre>
+</blockquote>
+<p>will run Ant with a listener that generates an XML representation of the build progress. This
+listener is included with Ant, as is the default listener, which generates the logging to standard output.</p>
+
+<p><b>Note: </b>A listener must not access System.out and System.err directly since output on
+these streams is redirected by Ant's core to the build event system. Accessing these
+streams can cause an infinite loop in Ant. Depending on the version of Ant, this will
+either cause the build to terminate or the Java VM to run out of Stack space. A logger, also, may
+not access System.out and System.err directly. It must use the streams with which it has
+been configured.</p>
+
+<p><b>Note2:</b> All methods of a BuildListener except for the "Build
+ Started" and "Build Finished" events may occur on several threads
+ simultaneously - for example while Ant is executing
+ a <code>&lt;parallel&gt;</code> task.</p>
+
+<hr>
+<h2><a name="integration">Source code integration</a></h2>
+
+<p>The other way to extend Ant through Java is to make changes to existing tasks, which is positively encouraged.
+Both changes to the existing source and new tasks can be incorporated back into the Ant codebase, which
+benefits all users and spreads the maintenance load around.</p>
+
+<p>Please consult the
+<a href="http://www.apache.org/foundation/getinvolved.html">Getting Involved</a> pages on the Apache web site
+for details on how to fetch the latest source and how to submit changes for reincorporation into the
+source tree.</p>
+
+<p>Ant also has some
+<a href="http://ant.apache.org/ant_task_guidelines.html">task guidelines</a>
+which provides some advice to people developing and testing tasks. Even if you intend to
+keep your tasks to yourself, you should still read this as it should be informative.</p>
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/developlist.html b/framework/src/ant/apache-ant-1.9.6/manual/developlist.html
new file mode 100644
index 00000000..1bbdc4e2
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/developlist.html
@@ -0,0 +1,53 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us"/>
+<link rel="stylesheet" type="text/css" href="stylesheets/style.css"/>
+<title>Apache Ant User Manual</title>
+<base target="mainFrame"/>
+</head>
+
+<body>
+
+<h2><a href="toc.html" target="navFrame">Table of Contents</a></h2>
+
+<h3>Developing with Apache Ant</h3>
+
+<ul class="inlinelist">
+<li><a href="http://ant.apache.org/ant_in_anger.html">Ant in Anger</a> <small>(online)</small></li>
+<li><a href="http://ant.apache.org/ant_task_guidelines.html">Ant Task Guidelines</a> <small>(online)</small></li>
+<li><a href="develop.html#writingowntask">Writing Your Own Task</a></li>
+<li><a href="base_task_classes.html">Tasks Designed for Extension</a></li>
+<li><a href="develop.html#buildevents">Build Events</a></li>
+<li><a href="develop.html#integration">Source-code Integration</a></li>
+<li><a href="inputhandler.html">InputHandler</a></li>
+<li><a href="antexternal.html">Using Ant Tasks Outside of Ant</a></li>
+<li><a href="projecthelper.html">The Ant frontend: ProjectHelper</a></li>
+<li><a href="argumentprocessor.html">The Command Line Processor Plugin:ArgumentProcessor</a></li>
+</ul>
+
+<h3>Tutorials</h3>
+<ul class="inlinelist">
+<li><a href="tutorial-HelloWorldWithAnt.html">Hello World with Ant</a></li>
+<li><a href="tutorial-writing-tasks.html">Writing Tasks</a></li>
+<li><a href="tutorial-tasks-filesets-properties.html">Tasks using Properties, Filesets &amp; Paths</a></li>
+</ul>
+
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/dirtasks.html b/framework/src/ant/apache-ant-1.9.6/manual/dirtasks.html
new file mode 100644
index 00000000..5c232298
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/dirtasks.html
@@ -0,0 +1,314 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="stylesheets/style.css">
+<title>Directory-based Tasks</title>
+</head>
+
+<body>
+
+<h2><a name="directorybasedtasks">Directory-based Tasks</a></h2>
+<p>Some tasks use directory trees for the actions they perform.
+For example, the <a href="Tasks/javac.html">javac</a> task, which
+compiles a directory tree with <code>.java</code> files into
+<code>.class</code> files, is one of these directory-based tasks. Because
+some of these tasks do so much work with a directory tree, the task itself
+can act as an implicit <a href="Types/fileset.html">FileSet</a>.</p>
+<p>Whether the fileset is implicit or not, it can often be very useful to
+work on a subset of the directory tree. This section describes how you can
+select a subset of such a directory tree when using one of these
+directory-based tasks.</p>
+<p>Apache Ant gives you two ways to create a subset of files in a fileset, both of
+which can be used at the same time:</p>
+<ul>
+ <li>Only include files and directories that match any
+ <code>include</code> patterns and do not match any
+ <code>exclude</code> patterns in a given
+ <a href="Types/patternset.html">PatternSet</a>.</li>
+ <li>Select files based on selection criteria defined by a collection of
+ <a href="Types/selectors.html">selector</a> nested elements.</li>
+</ul>
+<h3><a name="patternset">Patternset</a></h3>
+
+<p>We said that Directory-based tasks can sometimes act as an implicit
+<a href="Types/fileset.html"><code>&lt;fileset&gt;</code></a>,
+but in addition to that, a FileSet acts as an implicit
+<a href="Types/patternset.html"><code>&lt;patternset&gt;</code></a>.</p>
+
+<p>The inclusion and exclusion elements of the implicit PatternSet can be
+specified inside the directory-based task (or explicit fileset) via
+either:</p>
+<ul>
+ <li>the attributes <code>includes</code> and
+ <code>excludes</code>.</li>
+ <li>nested elements <code>&lt;include&gt;</code> and
+ <code>&lt;exclude&gt;</code>.</li>
+ <li>external files specified with the attributes
+ <code>includesfile</code> and <code>excludesfile</code>.</li>
+ <li>external files specified with the nested elements
+ <code>&lt;includesfile&gt;</code> and <code>&lt;excludesfile&gt;</code>.
+ </li>
+</ul>
+<p>
+When dealing with an external file, each line of the file
+is taken as a pattern that is added to the list of include or exclude
+patterns.</p>
+
+<p>When both inclusion and exclusion are used, only files/directories that
+match at least one of the include patterns and don't match any of the
+exclude patterns are used. If no include pattern is given, all files
+are assumed to match the include pattern (with the possible exception of
+the default excludes).</p>
+
+<h4><a name="patterns">Patterns</a></h4>
+
+<p>As described earlier, patterns are used for the inclusion and exclusion
+of files. These patterns look very much like the patterns used in DOS and
+UNIX:</p>
+<p>'*' matches zero or more characters, '?' matches one character.</p>
+
+<p>In general, patterns are considered relative paths, relative to a
+task dependent base directory (the dir attribute in the case of
+<code>&lt;fileset&gt;</code>). Only files found below that base
+directory are considered. So while a pattern like
+<code>../foo.java</code> is possible, it will not match anything when
+applied since the base directory's parent is never scanned for
+files.</p>
+
+<p><b>Examples:</b></p>
+<p>
+<code>*.java</code>&nbsp;&nbsp;matches&nbsp;&nbsp;<code>.java</code>,
+<code>x.java</code> and <code>FooBar.java</code>, but
+not <code>FooBar.xml</code> (does not end with <code>.java</code>).</p>
+<p>
+<code>?.java</code>&nbsp;&nbsp;matches&nbsp;&nbsp;<code>x.java</code>,
+<code>A.java</code>, but not <code>.java</code> or <code>xyz.java</code>
+(both don't have one character before <code>.java</code>).</p>
+<p>
+Combinations of <code>*</code>'s and <code>?</code>'s are allowed.</p>
+<p>Matching is done per-directory. This means that first the first directory in
+the pattern is matched against the first directory in the path to match. Then
+the second directory is matched, and so on. For example, when we have the pattern
+<code>/?abc/*/*.java</code>
+and the path <code>/xabc/foobar/test.java</code>,
+the first <code>?abc</code> is matched with <code>xabc</code>,
+then <code>*</code> is matched with <code>foobar</code>,
+and finally <code>*.java</code> is matched with <code>test.java</code>.
+They all match, so the path matches the pattern.</p>
+<p>To make things a bit more flexible, we add one extra feature, which makes it
+possible to match multiple directory levels. This can be used to match a
+complete directory tree, or a file anywhere in the directory tree.
+To do this, <code>**</code>
+must be used as the name of a directory.
+When <code>**</code> is used as the name of a
+directory in the pattern, it matches zero or more directories.
+For example:
+<code>/test/**</code> matches all files/directories under <code>/test/</code>,
+such as <code>/test/x.java</code>,
+or <code>/test/foo/bar/xyz.html</code>, but not <code>/xyz.xml</code>.</p>
+<p>There is one &quot;shorthand&quot;: if a pattern ends
+with <code>/</code>
+or <code>\</code>, then <code>**</code>
+is appended.
+For example, <code>mypackage/test/</code> is interpreted as if it were
+<code>mypackage/test/**</code>.</p>
+<p><b>Example patterns:</b></p>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><code>**/CVS/*</code></td>
+ <td valign="top">Matches all files in <code>CVS</code>
+ directories that can be located
+ anywhere in the directory tree.<br>
+ Matches:
+ <pre>
+ CVS/Repository
+ org/apache/CVS/Entries
+ org/apache/jakarta/tools/ant/CVS/Entries
+ </pre>
+ But not:
+ <pre>
+ org/apache/CVS/foo/bar/Entries (<code>foo/bar/</code>
+ part does not match)
+ </pre>
+ </td>
+ </tr>
+ <tr>
+ <td valign="top"><code>org/apache/jakarta/**</code></td>
+ <td valign="top">Matches all files in the <code>org/apache/jakarta</code>
+ directory tree.<br>
+ Matches:
+ <pre>
+ org/apache/jakarta/tools/ant/docs/index.html
+ org/apache/jakarta/test.xml
+ </pre>
+ But not:
+ <pre>
+ org/apache/xyz.java
+ </pre>
+ (<code>jakarta/</code> part is missing).</td>
+ </tr>
+ <tr>
+ <td valign="top"><code>org/apache/**/CVS/*</code></td>
+ <td valign="top">Matches all files in <code>CVS</code> directories
+ that are located anywhere in the directory tree under
+ <code>org/apache</code>.<br>
+ Matches:
+ <pre>
+ org/apache/CVS/Entries
+ org/apache/jakarta/tools/ant/CVS/Entries
+ </pre>
+ But not:
+ <pre>
+ org/apache/CVS/foo/bar/Entries
+ </pre>
+ (<code>foo/bar/</code> part does not match)</td>
+ </tr>
+ <tr>
+ <td valign="top"><code>**/test/**</code></td>
+ <td valign="top">Matches all files that have a <code>test</code>
+ element in their path, including <code>test</code> as a filename.</td>
+ </tr>
+</table>
+<p>When these patterns are used in inclusion and exclusion, you have a powerful
+way to select just the files you want.</p>
+
+<h3><a name="selectors">Selectors</a></h3>
+<p>The <a href="Types/fileset.html"><code>&lt;fileset&gt;</code></a>,
+whether implicit or explicit in the
+directory-based task, also acts as an
+<a href="Types/selectors.html#andselect"><code>&lt;and&gt;</code></a>
+selector container. This can be used to create arbitrarily complicated
+selection criteria for the files the task should work with. See the
+<a href="Types/selectors.html">Selector</a> documentation for more
+information.</p>
+
+<h3><a name="tasklist">Standard Tasks/Filesets</a></h3>
+<p>Many of the standard tasks in ant take one or more filesets which follow
+the rules given here. This list, a subset of those, is a list of standard ant
+tasks that can act as an implicit fileset:</p>
+<ul>
+ <li><a href="Tasks/checksum.html"><code>&lt;checksum&gt;</code></a></li>
+ <li><a href="Tasks/copydir.html"><code>&lt;copydir&gt;</code></a> (deprecated)</li>
+ <li><a href="Tasks/delete.html"><code>&lt;delete&gt;</code></a></li>
+ <li><a href="Tasks/dependset.html"><code>&lt;dependset&gt;</code></a></li>
+ <li><a href="Tasks/fixcrlf.html"><code>&lt;fixcrlf&gt;</code></a></li>
+ <li><a href="Tasks/javac.html"><code>&lt;javac&gt;</code></a></li>
+ <li><a href="Tasks/replace.html"><code>&lt;replace&gt;</code></a></li>
+ <li><a href="Tasks/rmic.html"><code>&lt;rmic&gt;</code></a></li>
+ <li><a href="Tasks/style.html"><code>&lt;style&gt;</code> (aka <code>&lt;xslt&gt;</code>)</a></li>
+ <li><a href="Tasks/tar.html"><code>&lt;tar&gt;</code></a></li>
+ <li><a href="Tasks/zip.html"><code>&lt;zip&gt;</code></a></li>
+ <li><a href="Tasks/ejb.html#ddcreator"><code>&lt;ddcreator&gt;</code></a></li>
+ <li><a href="Tasks/ejb.html#ejbjar"><code>&lt;ejbjar&gt;</code></a></li>
+ <li><a href="Tasks/ejb.html#ejbc"><code>&lt;ejbc&gt;</code></a></li>
+ <li><a href="Tasks/cab.html"><code>&lt;cab&gt;</code></a></li>
+ <li><a href="Tasks/native2ascii.html"><code>&lt;native2ascii&gt;</code></a></li>
+ <li><a href="Tasks/netrexxc.html"><code>&lt;netrexxc&gt;</code></a></li>
+ <li>
+ <a href="Tasks/renameextensions.html"><code>&lt;renameextensions&gt;</code></a>
+ </li>
+ <li><a href="Tasks/depend.html"><code>&lt;depend&gt;</code></a></li>
+ <li><a href="Tasks/translate.html"><code>&lt;translate&gt;</code></a></li>
+ <li><a href="Tasks/image.html"><code>&lt;image&gt;</code></a></li>
+ <li><a href="Tasks/jlink.html"><code>&lt;jlink&gt;</code></a> (deprecated)</li>
+ <li><a href="Tasks/jspc.html"><code>&lt;jspc&gt;</code></a></li>
+ <li><a href="Tasks/wljspc.html"><code>&lt;wljspc&gt;</code></a></li>
+</ul>
+
+<h3><a name="examples">Examples</a></h3>
+<pre>
+&lt;copy todir=&quot;${dist}&quot;&gt;
+ &lt;fileset dir=&quot;${src}&quot;
+ includes=&quot;**/images/*&quot;
+ excludes=&quot;**/*.gif&quot;
+ /&gt;
+&lt;/copy&gt;</pre>
+<p>This copies all files in directories called <code>images</code> that are
+located in the directory tree defined by <code>${src}</code> to the
+destination directory defined by <code>${dist}</code>,
+but excludes all <code>*.gif</code> files from the copy.</p>
+<pre>
+&lt;copy todir=&quot;${dist}&quot;&gt;
+ &lt;fileset dir=&quot;${src}&quot;&gt;
+ &lt;include name=&quot;**/images/*&quot;/&gt;
+ &lt;exclude name=&quot;**/*.gif&quot;/&gt;
+ &lt;/fileset&gt;
+&lt;/copy&gt;
+</pre>
+<p> The same as the example above, but expressed using nested elements.</p>
+
+<pre>
+&lt;delete dir=&quot;${dist}&quot;&gt;
+ &lt;include name=&quot;**/images/*&quot;/&gt;
+ &lt;exclude name=&quot;**/*.gif&quot;/&gt;
+&lt;/delete&gt;
+</pre>
+<p>Deleting the original set of files, the <code>delete</code> task can act
+as an implicit fileset.</p>
+
+<h3><a name="defaultexcludes">Default Excludes</a></h3>
+<p>There are a set of definitions that are excluded by default from all
+directory-based tasks. As of Ant 1.8.1 they are:</p>
+<pre>
+ **/*~
+ **/#*#
+ **/.#*
+ **/%*%
+ **/._*
+ **/CVS
+ **/CVS/**
+ **/.cvsignore
+ **/SCCS
+ **/SCCS/**
+ **/vssver.scc
+ **/.svn
+ **/.svn/**
+ **/.DS_Store
+</pre>
+<p>Ant 1.8.2 adds the following default excludes:</p>
+<pre>
+ **/.git
+ **/.git/**
+ **/.gitattributes
+ **/.gitignore
+ **/.gitmodules
+ **/.hg
+ **/.hg/**
+ **/.hgignore
+ **/.hgsub
+ **/.hgsubstate
+ **/.hgtags
+ **/.bzr
+ **/.bzr/**
+ **/.bzrignore
+</pre>
+<p>If you do not want these default excludes applied, you may disable
+them with the <code>defaultexcludes=&quot;no&quot;</code>
+attribute.</p>
+
+<p>This is the default list; note that you can modify the list of
+default excludes by using the <a
+href="Tasks/defaultexcludes.html">defaultexcludes</a> task.</p>
+
+
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/favicon.ico b/framework/src/ant/apache-ant-1.9.6/manual/favicon.ico
new file mode 100644
index 00000000..9dbc258f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/favicon.ico
Binary files differ
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/feedback.html b/framework/src/ant/apache-ant-1.9.6/manual/feedback.html
new file mode 100644
index 00000000..70027f66
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/feedback.html
@@ -0,0 +1,72 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="stylesheets/style.css">
+<title>Apache Ant User Manual - Feedback</title>
+</head>
+
+<body>
+
+<h1><a name="feedback">Feedback</a> and Troubleshooting</h1>
+<p>If things do not work, especially simple things like <tt>ant -version</tt>,
+ then something is wrong with your configuration. Before filing bug reports and
+ emailing all the Apache Ant mailing lists</p>
+<ol>
+ <li>Check your environment variables. Are ANT_HOME and JAVA_HOME correct? If
+ they have quotes or trailing slashes, remove them.</li>
+ <li>Unset CLASSPATH; if that is wrong things go horribly wrong. Ant does not
+ need the CLASSPATH variable defined to anything to work.</li>
+ <li>Make sure there are no versions of crimson.jar or other XML parsers in JRE/ext</li>
+ <li>Is your path correct? is Ant on it? What about JDK/bin? have you tested
+ this? If you are using Jikes, is it on the path? A createProcess error (especially
+ with ID=2 on windows) usually means executable not found on the path.</li>
+ <li>Which version of ant are you running? Other applications distribute a copy
+ -it may be being picked up by accident.</li>
+ <li>If a task is failing to run is optional.jar in ANT_HOME/lib? Are there any
+ libraries which it depends on missing?</li>
+ <li>If a task doesn't do what you expect, run <tt>ant -verbose</tt> or <tt>ant
+ -debug</tt> to see what is happening</li>
+</ol>
+<p>If you can't fix your problem, start with the <a href="http://ant.apache.org/mail.html" target="_top">Ant
+ User Mailing List</a> . These are other ant users who will help you learn to
+ use ant. If they cannot fix it then someone may suggest filing a bug report,
+ which will escalate the issue. Remember of course, that support, like all open
+ source development tasks, is voluntary. If you haven't invested time in helping
+ yourself by following the steps above, it is unlikely that anyone will invest
+ the time in helping you. </p>
+<p>Also, if you don't understand something, the <a href="http://ant.apache.org/mail.html" target="_top">Ant
+ User Mailing List</a> is the place to ask questions. Not the developer list,
+ nor the individuals whose names appears in the source and documentation. If
+ they answered all such emails, nobody would have any time to improve ant. </p>
+<p>To provide feedback on this software, please subscribe to the <a href="http://ant.apache.org/mail.html" target="_top">Ant
+ User Mailing List</a> </p>
+
+<p>If you want to contribute to Ant or stay current with the latest
+development, join the
+<a href="http://ant.apache.org/mail.html" target="_top">Ant Development Mailing List</a>
+</p>
+<p>A searchable archive can be found at <a
+href="http://marc.theaimsgroup.com" target="_top">http://marc.theaimsgroup.com</a>.
+Other archives will be documented online at <a href="http://ant.apache.org/mail.html#Archives" target="_top">Mailing Lists Archives</a> </p>
+
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/ide.html b/framework/src/ant/apache-ant-1.9.6/manual/ide.html
new file mode 100644
index 00000000..7f2bc6d9
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/ide.html
@@ -0,0 +1,105 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us"/>
+<link rel="stylesheet" type="text/css" href="stylesheets/style.css"/>
+<title>IDE Integration</title>
+<base target="mainFrame"/>
+</head>
+
+<body>
+
+<h2><a href="toc.html" target="navFrame">Table of Contents</a></h2>
+
+<h3>IDE Integration</h3>
+<p>
+All the modern Java IDEs support Apache Ant almost out of the box.
+</p>
+
+<ul>
+ <li>
+ <a href="http://antrunner.sourceforge.net/">
+ AntRunner For JBuilder (unbundled)
+ </a>
+ </li>
+ <li>
+ <a href="Integration/jext-plugin.html">
+ AntWork Plugin for the Jext Java Text Editor (unbundled)
+ </a>
+ </li>
+ <li>
+ <a href="http://jdee.sunsite.dk/">
+ JDEE (Java Development Environment for Emacs)
+ </a> has built-in text ANT integration: selection of target through text
+ field, execution, hyperlink to compilation errors. Installation: built-in
+ JDEE 2.2.8 or later. Configuration: through customize menu
+ "Jde Build Function"
+ </li>
+ <li>
+ <a href="http://www.intellij.com/idea/">
+ IDEA
+ </a> has built-in GUI ANT integration: GUI selection of targets, execution,
+ hyperlink to compilation errors
+ </li>
+ <li>
+ <a href="http://ant.netbeans.org/">
+ NetBeans
+ </a>
+ NetBeans IDE uses Ant as the basis for its project system starting with the 4.0 release.
+ </li>
+ <li>
+ <a href="http://jedit.org/">
+ jEdit
+ </a>
+ jEdit is an open source java IDE with some great plugins for Java dev, a
+ good XML editor and the Antfarm plugin to execute targets in a build
+ file.
+ </li>
+ <li>
+ <a href="http://eclipse.org/">
+ Eclipse
+ </a>
+ Eclipse is IBM's counterpoint to NetBeans; an open source IDE with
+ Java and Ant support.
+ </li>
+ <li>
+ <a href="http://www.placidsystems.com/virtualant/">
+ Virtual Ant</a> GUI allows you to work on a Virtual File System without dealing with the XML. Plugs into Eclipse, Netbeans &amp; Intellij.
+ </li>
+ <li>
+ <a href="http://www7b.software.ibm.com/wsdd/library/techarticles/0203_searle/searle1.html">
+ WebSphere Studio Application Developer
+ </a>
+ </li>
+ <li>
+ <a href="http://www.borland.com/jbuilder/pdf/jb9_feamatrix.pdf">
+ JBuilder 9 Personal
+ </a>
+ JBuilder supports Ant with the following features. Add Ant nodes to
+ projects and execute Ant targets from within JBuilder. Add custom Ant-based
+ build tasks with custom Ant libraries to run Ant from within JBuilder.
+ Rapid navigation from Ant build error messages to source files.
+ Customize build menu and toolbar with custom build targets.
+ </li>
+</ul>
+
+
+
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/ifunless.html b/framework/src/ant/apache-ant-1.9.6/manual/ifunless.html
new file mode 100644
index 00000000..abbdce1b
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/ifunless.html
@@ -0,0 +1,64 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+ <meta http-equiv="Content-Language" content="en-us"/>
+ <link rel="stylesheet" type="text/css" href="stylesheets/style.css"/>
+ <title>If and Unless on all tasks/nested elements</title>
+</head>
+
+<body>
+ <h1><a name="if_and_unless">If And Unless</a></h1>
+
+ <p>Since Ant 1.9.1 it is possible to add if and unless attributes on all tasks and nested elements using special namespaces.</p>
+
+ <p>In order to use this feature you need to add the following namespace declarations</p>
+ <blockquote><pre>
+ xmlns:if=&quot;ant:if&quot;
+ xmlns:unless=&quot;ant:unless&quot;
+ </pre>
+ </blockquote>
+
+ <p>The if and unless namespaces support the following 3 conditions :
+ <ul>
+ <li>true</li>true if the value of the attribute evaluates to true
+ <li>blank</li>true if the value of the attribute is null or empty
+ <li>set</li>true if the specified property is set
+ </ul></p>
+
+<blockquote>
+<pre>
+&lt;project name=&quot;tryit&quot;
+ xmlns:if=&quot;ant:if&quot;
+ xmlns:unless=&quot;ant:unless&quot;
+&gt;
+ &lt;exec executable=&quot;java&quot;&gt;
+ &lt;arg line=&quot;-X&quot; if:true=&quot;${showextendedparams}&quot;/&gt;
+ &lt;arg line=&quot;-version&quot; unless:true=&quot;${showextendedparams}&quot;/&gt;
+ &lt;/exec&gt;
+ &lt;condition property=&quot;onmac&quot;&gt;
+ &lt;os family=&quot;mac&quot;/&gt;
+ &lt;/condition&gt;
+ &lt;echo if:set=&quot;onmac&quot;&gt;running on MacOS&lt;/echo&gt;
+ &lt;echo unless:set=&quot;onmac&quot;&gt;not running on MacOS&lt;/echo&gt;
+&lt;/project&gt;
+</pre>
+</blockquote>
+
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/images/ant_logo_large.gif b/framework/src/ant/apache-ant-1.9.6/manual/images/ant_logo_large.gif
new file mode 100644
index 00000000..a0579a2c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/images/ant_logo_large.gif
Binary files differ
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/index.html b/framework/src/ant/apache-ant-1.9.6/manual/index.html
new file mode 100644
index 00000000..9df48a04
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/index.html
@@ -0,0 +1,34 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="stylesheets/style.css">
+<title>Apache Ant&trade; User Manual</title>
+</head>
+
+<frameset cols="26%,74%">
+<frame src="toc.html" name="navFrame">
+<frame src="cover.html" name="mainFrame">
+</frameset>
+<noframes>
+<H2>Apache Ant&trade; User Manual</H2>
+
+<a href="toc.html">Apache Ant User Manual</a></noframes>
+
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/inputhandler.html b/framework/src/ant/apache-ant-1.9.6/manual/inputhandler.html
new file mode 100644
index 00000000..1333157e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/inputhandler.html
@@ -0,0 +1,116 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="stylesheets/style.css">
+<title>InputHandler</title>
+</head>
+
+<body>
+<h1>InputHandler</h1>
+
+<h2>Overview</h2>
+
+<p>When a task wants to prompt a user for input, it doesn't simply
+read the input from the console as this would make it impossible to
+embed Apache Ant in an IDE. Instead it asks an implementation of the
+<code>org.apache.tools.ant.input.InputHandler</code> interface to
+prompt the user and hand the user input back to the task.</p>
+
+<p>To do this, the task creates an <code>InputRequest</code> object
+and passes it to the <code>InputHandler</code> Such an
+<code>InputRequest</code> may know whether a given user input is valid
+and the <code>InputHandler</code> is supposed to reject all invalid
+input.</p>
+
+<p>Exactly one <code>InputHandler</code> instance is associated with
+every Ant process, users can specify the implementation using the
+<code>-inputhandler</code> command line switch.</p>
+
+<h2>InputHandler</h2>
+
+<p>The <code>InputHandler</code> interface contains exactly one
+method</p>
+
+<pre>
+ void handleInput(InputRequest request)
+ throws org.apache.tools.ant.BuildException;
+</pre>
+
+<p>with some pre- and postconditions. The main postcondition is that
+this method must not return unless the <code>request</code> considers
+the user input valid, it is allowed to throw an exception in this
+situation.</p>
+
+<p>Ant comes with three built-in implementations of this interface:</p>
+
+<h3><a name="defaulthandler">DefaultInputHandler</a></h3>
+
+<p>This is the implementation you get, when you don't use the
+<code>-inputhandler</code> command line switch at all. This
+implementation will print the prompt encapsulated in the
+<code>request</code> object to Ant's logging system and re-prompt for
+input until the user enters something that is considered valid input
+by the <code>request</code> object. Input will be read from the
+console and the user will need to press the Return key.</p>
+
+<h3>PropertyFileInputHandler</h3>
+
+<p>This implementation is useful if you want to run unattended build
+processes. It reads all input from a properties file and makes the
+build fail if it cannot find valid input in this file. The name of
+the properties file must be specified in the Java system property
+<code>ant.input.properties</code>.</p>
+
+<p>The prompt encapsulated in a <code>request</code> will be used as
+the key when looking up the input inside the properties file. If no
+input can be found, the input is considered invalid and an exception
+will be thrown.</p>
+
+<p><strong>Note</strong> that <code>ant.input.properties</code> must
+be a Java system property, not an Ant property. I.e. you cannot
+define it as a simple parameter to <code>ant</code>, but you can
+define it inside the <code>ANT_OPTS</code> environment variable.</p>
+
+<h3>GreedyInputHandler</h3>
+
+<p>Like the default implementation, this InputHandler reads from standard
+input. However, it consumes <i>all</i> available input. This behavior is
+useful for sending Ant input via an OS pipe. <b>Since Ant 1.7</b>.</p>
+
+<h3>SecureInputHandler</h3>
+
+<p>This InputHandler calls <code>System.console().readPassword()</code>,
+available since Java 1.6. On earlier platforms it falls back to the
+behavior of DefaultInputHandler. <b>Since Ant 1.7.1</b>.</p>
+
+<h2>InputRequest</h2>
+
+<p>Instances of <code>org.apache.tools.ant.input.InputRequest</code>
+encapsulate the information necessary to ask a user for input and
+validate this input.</p>
+
+<p>The instances of <code>InputRequest</code> itself will accept any
+input, but subclasses may use stricter validations.
+<code>org.apache.tools.ant.input.MultipleChoiceInputRequest</code>
+should be used if the user input must be part of a predefined set of
+choices.</p>
+
+
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/install.html b/framework/src/ant/apache-ant-1.9.6/manual/install.html
new file mode 100644
index 00000000..818b168d
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/install.html
@@ -0,0 +1,1096 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="stylesheets/style.css">
+<title>Installing Apache Ant</title>
+</head>
+
+<body>
+<h1>Installing Apache Ant</h1>
+<h2><a name="getting">Getting Apache Ant</a></h2>
+
+<h3>The Short Story</h3>
+<p>To get up and running with the binary edition of Ant quickly, follow these steps:
+<ol>
+<li>Make sure you have a Java environment installed, See <a href="#sysrequirements">System
+Requirements</a> for details.</li>
+<li>Download Ant. See <a href="#getBinary">Binary Edition</a> for details.</li>
+<li>Uncompress the downloaded file into a directory.</li>
+<li>Set environmental variables <code>JAVA_HOME</code> to your Java environment, <code>ANT_HOME</code> to
+the directory you uncompressed Ant to, and add <code>${ANT_HOME}/bin</code> (Unix) or
+<code>%ANT_HOME%/bin</code> (Windows) to your <code>PATH</code>. See <a href="#setup">Setup</a> for details.</li>
+<li>Optionally, from the <code>ANT_HOME</code> directory run <code>ant -f fetch.xml -Ddest=system</code> to get
+the library dependencies of most of the Ant tasks that require them. If you don't do this, many of the dependent
+Ant tasks will not be available. See <a href="#optionalTasks">Optional Tasks</a> for details and other options
+for the -Ddest parameter.</li>
+<li>Optionally, add any desired Antlibs. See <a href="http://ant.apache.org/antlibs/proper.html" target="_top">Ant Libraries</a> for a list.
+</ol>
+</p>
+<p>
+Note that the links in the list above will give more details about each of the steps,
+should you need them. Or you can just continue reading the rest of this document.
+</p>
+The short story for working with the Ant source code (not needed if you are working with the binary edition) is:
+<ol>
+<li>Get the source code. See <a href="#sourceEdition">Source Edition</a> for details.</li>
+<li> Build Ant. See <a href="#buildingant">Building Ant</a> for details.</li>
+</ol>
+<p>
+</p>
+<p>
+For the full story, continue reading.
+</p>
+
+<h3><a name="getBinary">Binary Edition</a></h3>
+
+<p>The latest stable version of Ant is available from the Ant web page <a
+href="http://ant.apache.org/" target="_top">http://ant.apache.org/</a>
+</p>
+
+<p>The binary edition of Ant is shipped with 3 different compression formats:
+<ol>
+<li><b>.zip</b> - Recommended compression format for Windows, can also be used on other platforms. Supported
+by many programs and some operating systems natively.</li>
+<li><b>.tar.gz</b> - Uses the tar program to gather files together, and gzip to compress and uncompress.</li>
+<li><b>.tar.bz2</b> - Uses the tar program to gather files together, and bzip2 to compress and uncompress..</li>
+</ol>
+Choose the format that is best supported for your platform.
+</p>
+
+<h3>As a binary in an RPM Package</h3>
+
+<p>Consult the <a href="#jpackage">jpackage</a> section below.</p>
+
+<h3>Bundled in IDEs</h3>
+<p>
+ All the main Java IDEs ship with Ant, products such as Eclipse, NetBeans
+ and IntelliJ IDEA. If you install Ant this way you usually get the most recent
+ release of Ant at the time the IDE was released. Some of the IDEs (Eclipse
+ and NetBeans in particular) ship with extra tasks that only work if
+ IDE-specific tools are on Ant's path. To use these on command-line versions
+ of Ant, the relevant JARs need to be added to the command-line Ant as
+ extra libraries/tasks. Note that if it is an IDE task or extension that is
+ not behaving, the Ant team is unable to field bug reports. Try the IDE mailing
+ lists first, who will cross-file bugs if appropriate.
+</p>
+<p>
+ IDE's can invariably be pointed at different Ant installations. This lets
+ developers upgrade to a new release of Ant, and eliminate inconsistencies
+ between command-line and IDE Ant.
+</p>
+
+<h3>Bundled in Java applications</h3>
+
+<p>
+ Many Java applications, most particularly application servers, ship with
+ a version of Ant. These are primarily for internal use by the application,
+ using the Java APIs to delegate tasks such as JSP page compilation to the Ant
+ runtime. Such distributions are usually unsupported by everyone. Particularly
+ troublesome are those products that not only ship with their own Ant release,
+ they add their own version of ANT.BAT or ant.sh to the PATH. If Ant starts
+ behaving weirdly after installing something, try the
+ <a href="#diagnostics">diagnostics</a> advice.
+</p>
+
+<h3><a name="sourceEdition">Source Edition</a></h3>
+
+<p>If you prefer the source edition, you can download the source for the latest
+Ant release from
+<a href="http://ant.apache.org/srcdownload.cgi" target="_top">http://ant.apache.org/srcdownload.cgi</a>.
+
+If you prefer the leading-edge code, you can access
+the code as it is being developed via git. The Ant website has details on
+<a href="http://ant.apache.org/git.html" target="_top">accessing git</a>.
+All bug fixes will go in against the HEAD of the source tree, and the first
+response to many bugreps will be "have you tried the latest version".
+Don't be afraid to download and build a prererelease edition, as everything
+other than new features are usually stable.
+ </p>
+<p>
+
+
+See the section <a href="#buildingant">Building Ant</a> on how to
+build Ant from the source code.
+You can also access the
+<a href="https://git-wip-us.apache.org/repos/asf?p=ant.git;a=summary" target="_top">
+Ant SVN repository</a> on-line. </p>
+
+<h3 name="archives">Archive Download Area Layout</h3>
+<p>
+Older versions of Ant are available in the archives at <a
+href="http://archive.apache.org/dist/ant/" target="_top">http://archive.apache.org/dist/ant/</a>. The
+files are organized as follows.
+</p>
+<table>
+<tr>
+ <th>Filename or Path</th>
+ <th>Description</th>
+</tr>
+<tr>
+ <td>KEYS</td>
+ <td>PGP-Keysfile. It contains the PGP-keys of Ant developers so you can 'trust' the distribution. </td>
+</tr>
+<tr>
+ <td>RELEASE-NOTES-{version}.html</td>
+ <td>
+ Release notes of the given version in HTML format. When upgrading your Ant installation you
+ should have a look at the <i>Changes that could break older environments</i> section.
+ </td>
+</tr>
+<tr>
+ <td>ant-current-bin.zip</td>
+ <td>
+ ZIP-Archive containing the compiled version of Ant in the last released version. It is recommended that
+ you do not download the latest version this way, as the standard way of downloading described above will
+ redirect you to a mirror closer to you, thus making the download faster for you and reducing the load
+ on Apache servers.
+ </td>
+</tr>
+<tr>
+ <td>ant-current-src.zip</td>
+ <td>
+ ZIP-Archive containing the sources of Ant. If you have this you could compile Ant itself.
+ If you do not have the <i>required</i> dependencies, the classes depending on them are just not
+ built. Again, it is preferred to use the standard way of getting the source package described above
+ to make your download quicker and to reduce the load on Apache servers.
+ </td>
+</tr>
+<tr>
+ <td>ant-current-*.asc</td>
+ <td>
+ Security file for checking the correctness of the zip file. This one is the
+ <a href="http://en.wikipedia.org/wiki/Pretty_Good_Privacy" target="_blank">PGP</a> key.
+ </td>
+</tr>
+<tr>
+ <td>ant-current-*.md5</td>
+ <td>
+ Security file for checking the correctness of the zip file. This one is the
+ <a href="http://en.wikipedia.org/wiki/Md5" target="_blank">MD5</a> key.
+ </td>
+</tr>
+<tr>
+ <td>ant-current-*.sha1</td>
+ <td>
+ Security file for checking the correctness of the zip file. This one is the
+ <a href="http://en.wikipedia.org/wiki/SHA-1" target="_blank">SHA1</a> key.
+ </td>
+</tr>
+<tr>
+ <td>antlibs/</td>
+ <td>
+ This directory holds the Antlibs that are made of available by the Apache Ant project.
+ Antlibs are bundles of Ant tasks that are not delivered as part of the Ant core but are
+ available as optional downloads.
+ </td>
+</tr>
+<tr>
+ <td>binaries/</td>
+ <td>
+ The binaries directory holds specific Ant releases bundled in both ZIP and tar.gz compression
+ formats. The named releases are in contrast to the ant-current-bin.zip file in the parent
+ directory, which is always guaranteed to be the most current release of Ant.
+ </td>
+</tr>
+<tr>
+ <td>common/</td>
+ <td>
+ The common directory holds various files, such as the Apache License file that Ant is licensed
+ under, that people may wish to examine without having to download the whole Ant distribution.
+ </td>
+</tr>
+<tr>
+ <td>source/</td>
+ <td>
+ The source directory holds the source code for specific Ant releases bundled in both ZIP and
+ tar.gz compression formats. The named releases are in contrast to the ant-current-src.zip file
+ in the parent directory, which is always guaranteed to hold the source code for the most current
+ release of Ant.
+ </td>
+</tr>
+</table>
+
+<hr>
+<h2><a name="sysrequirements">System Requirements</a></h2>
+Ant has been used successfully on many platforms, including Linux,
+commercial flavours of Unix such as Solaris and HP-UX,
+Windows NT-platforms, OS/2 Warp, Novell Netware 6, OpenVMS and MacOS X.
+The platforms used most for development are, in no particular order,
+Linux, MacOS X, Windows XP and Unix; these are therefore that platforms
+that tend to work best. As of Ant1.7, Windows 9x is no longer supported.
+
+<p>
+For the current version of Ant, you will also need a JDK installed on
+your system, version 1.4 or later required, 1.7 or later strongly recommended.
+The more up-to-date the version of Java , the more Ant tasks you get.
+</p>
+<p>
+ <strong>Note: </strong>If a JDK is not present, only the JRE runtime, then many tasks will not work.
+</p>
+<p>
+ <strong>Note: </strong>
+ Ant 1.8.* works with jdk1.4 and higher, Ant 1.7.* works with jdk1.3 and higher, Ant 1.6.* works with jdk 1.2 and higher,
+ Ant 1.2 to Ant 1.5.* work with jdk 1.1 and higher.
+</p>
+
+<h3>Open Source Java Runtimes</h3>
+<p>
+ The Ant team strongly supports users running Ant on <a target="_blank" href="http://openjdk.java.net/">OpenJDK</a> and other
+ open source Java runtimes, and so strives to have a product that works
+ well on those platforms.
+</p>
+<hr>
+<h2><a name="installing">Installing Ant</a></h2>
+<p>The binary distribution of Ant consists of the following directory layout:
+<pre>
+ ant
+ +--- README, LICENSE, fetch.xml, other text files. //basic information
+ +--- bin // contains launcher scripts
+ |
+ +--- lib // contains Ant jars plus necessary dependencies
+ |
+ +--- docs // contains documentation
+ | |
+ | +--- images // various logos for html documentation
+ | |
+ | +--- manual // Ant documentation (a must read ;-)
+ |
+ +--- etc // contains xsl goodies to:
+ // - create an enhanced report from xml output of various tasks.
+ // - migrate your build files and get rid of 'deprecated' warning
+ // - ... and more ;-)
+</pre>
+
+Only the <code>bin</code> and <code>lib</code> directories are
+required to run Ant.
+
+To install Ant, choose a directory and copy the distribution
+files there. This directory will be known as ANT_HOME.
+</p>
+
+<table width="80%">
+<tr>
+ <td colspan="2">
+ <b>Windows 95, Windows 98 &amp; Windows ME Note:</b>
+ </td>
+</tr>
+<tr>
+ <td width="5%">&nbsp;</td>
+ <td><i>
+Note that current releases of Ant no longer support these systems. If you are using an older
+version of Ant, however, the script used to launch Ant will have
+problems if ANT_HOME is a long filename (i.e. a filename which is not
+of the format known as &quot;8.3&quot;). This is due to
+limitations in the OS's handling of the <code>&quot;for&quot;</code>
+batch-file statement. It is recommended, therefore, that Ant be
+installed in a <b>short</b>, 8.3 path, such as C:\Ant. </i>
+ </td>
+</tr>
+<tr>
+ <td width="5%">&nbsp;</td>
+ <td>
+ <p>On these systems you will also need to configure more environment
+ space to cater for the environment variables used in the Ant launch script.
+ To do this, you will need to add or update the following line in
+ the <code>config.sys</code> file
+ </p>
+ <p><code>shell=c:\command.com c:\ /p /e:32768</code></p>
+ </td>
+</tr>
+</table>
+
+<h3><a name="setup">Setup</a></h3>
+<p>
+Before you can run Ant there is some additional set up you
+will need to do unless you are installing the <a href="#jpackage">RPM
+version from jpackage.org</a>:</p>
+<ul>
+<li>Add the <code>bin</code> directory to your path.</li>
+<li>Set the <code>ANT_HOME</code> environment variable to the
+directory where you installed Ant. On some operating systems, Ant's
+startup scripts can guess <code>ANT_HOME</code> (Unix dialects and
+Windows NT/2000), but it is better to not rely on this behavior.</li>
+<li>Optionally, set the <code>JAVA_HOME</code> environment variable
+(see the <a href="#advanced">Advanced</a> section below).
+This should be set to the directory where your JDK is installed.</li>
+</ul>
+<p>Operating System-specific instructions for doing this from the command
+line are in the <a href="#windows">Windows</a>, <a href="#bash">Linux/Unix (bash)</a>,
+and <a href="#tcshcsh">Linux/Unix (csh)</a> sections. Note that using this method,
+the settings will only be valid for the command line session you run them in.</p>
+<p><strong>Note:</strong> Do not install Ant's ant.jar file into the lib/ext
+directory of the JDK/JRE. Ant is an application, whilst the extension
+directory is intended for JDK extensions. In particular there are security
+restrictions on the classes which may be loaded by an extension.</p>
+
+<table width="80%">
+<tr>
+ <td colspan="2">
+ <b>Windows Note:</b>
+ </td>
+</tr>
+<tr>
+ <td width="5%">&nbsp;</td>
+ <td>
+ The ant.bat script makes use of three environment variables -
+ ANT_HOME, CLASSPATH and JAVA_HOME. <b>Ensure</b> that ANT_HOME and JAVA_HOME variables are set,
+ and that they do <b><u>not</u></b> have quotes (either
+ ' or &quot;) and they do <b><u>not</u></b> end with \ or with /. CLASSPATH should be unset or
+ empty.
+ </td>
+</tr>
+</table>
+
+<h3><a name="checkInstallation">Check Installation</a></h3>
+<p>You can check the basic installation with opening a new shell and typing <tt>ant</tt>. You
+should get a message like this
+<pre>
+Buildfile: build.xml does not exist!
+Build failed
+</pre>
+So Ant works. This message is there because you need to write an individual buildfile for your
+project. With a <tt>ant -version</tt> you should get an output like
+<pre>
+Apache Ant(TM) version 1.9.2 compiled on July 8 2013
+</pre>
+</p>
+<p>If this does not work ensure your environment variables are set right. They must resolve to:
+<ul>
+ <li>required: %ANT_HOME%\bin\ant.bat</li>
+ <li>optional: %JAVA_HOME%\bin\java.exe</li>
+ <li>required: %PATH%=...<i>maybe-other-entries</i>...;%ANT_HOME%\bin;...<i>maybe-other-entries</i>...</li>
+</ul>
+<b>ANT_HOME</b> is used by the launcher script for finding the libraries.
+<b>JAVA_HOME</b> is used by the launcher for finding the JDK/JRE to use. (JDK is recommended as some tasks
+require the java tools.) If not set, the launcher tries to find one via the %PATH% environment variable.
+<b>PATH</b> is set for user convenience. With that set you can just start <i>ant</i> instead of always typing
+<i>the/complete/path/to/your/ant/installation/bin/ant</i>.
+</p>
+
+<h3><a name="optionalTasks">Optional Tasks</a></h3>
+<p>Ant supports a number of optional tasks. An optional task is a task which
+typically requires an external library to function. The optional tasks are
+packaged together with the core Ant tasks.</p>
+
+<p>The external libraries required by each of the optional tasks is detailed
+in the <a href="#librarydependencies">Library Dependencies</a> section. These external
+libraries must be added to Ant's classpath, in any of the following ways:
+</p>
+<ul>
+ <li><p>
+ In <code><i>ANT_HOME</i>/lib</code>. This makes the JAR files available to all
+ Ant users and builds.
+ </p></li>
+
+ <li><p>
+ In <code>${user.home}/.ant/lib</code> (as of Ant 1.6). This
+ allows different users to add new libraries to Ant. All JAR files
+ added to this directory are available to command-line Ant.
+ </p></li>
+
+ <li><p>
+ On the command line with a <code>-lib</code> parameter. This lets
+ you add new JAR files on a case-by-case basis.
+ </p></li>
+
+ <li><p>
+ In the <code>CLASSPATH</code> environment variable. Avoid this; it makes
+ the JAR files visible to <i>all</i> Java applications, and causes
+ no end of support calls. See <a href="#classpath">below</a> for details.
+ </p>
+ </li>
+
+ <li><p>
+ In some <code>&lt;classpath&gt;</code> accepted by the task itself.
+ For example, as of Ant 1.7.0 you can run the <code>&lt;junit&gt;</code>
+ task without <code>junit.jar</code> in Ant's own classpath, so long as
+ it is included (along with your program and tests) in the classpath
+ passed when running the task.
+ </p><p>
+ Where possible, this option is generally
+ to be preferred, as the Ant script itself can determine the best path
+ to load the library from: via relative path from the basedir (if you
+ keep the library under version control with your project), according
+ to Ant properties, environment variables, Ivy downloads, whatever you like.
+ </p></li>
+
+</ul>
+
+<p>
+ If you are using the binary version of Ant, or if you are working from source
+ code, you can easily gather most of the dependencies and install them for use
+ with your Ant tasks. In your <code>ANT_HOME</code> directory you should see a
+ file called <code>fetch.xml</code>. This is an Ant script that you can run to
+ install almost all the dependencies the optional Ant tasks need.
+</p>
+
+<p>
+ To do so, change to the <code>ANT_HOME</code> directory and execute the command:
+</p>
+
+<blockquote>
+ <pre>ant -f fetch.xml -Ddest=<i>[option]</i></pre>
+</blockquote>
+
+<p>
+ where option is one of the following, as described above:
+ <ul>
+ <li><code>system</code> - store in Ant's lib directory <i>(Recommended)</i></li>
+ <li><code>user</code> - store in the user's home directory</li>
+ <li><code>optional</code> - store in Ant's source code lib/optional directory, used if building Ant source code</li>
+ </ul>
+</p>
+
+<p>
+ You may also need to set proxy settings. See the <a href="#proxy">Proxy Settings</a> section for details.
+</p>
+
+<p>
+Note that not all dependencies are gathered using <code>fetch.xml</code>. Tasks that depend on
+commercial software, in particular, will require you to have the commercial software installed
+in order to be used.
+</p>
+
+<p>The Apache Ant Project also provides additional tasks and types that are available as separately
+downloaded Ant Libraries. You can see the the list of available Antlibs at
+the <a href="http://ant.apache.org/antlibs/proper.html" target="_top">Ant Libraries</a> page.
+</p>
+
+<p>You can also find tasks and types provided by third-party projects at the
+<a href="http://ant.apache.org/external.html" target="_top">External Tools and Tasks</a> page.
+</p>
+
+<p>
+ IDEs have different ways of adding external JAR files and third-party tasks
+ to Ant. Usually it is done by some configuration dialog. Sometimes JAR files
+ added to a project are automatically added to ant's classpath.
+</p>
+
+<h3><a name="classpath">The <code>CLASSPATH</code> environment variable</a></h3>
+<p>
+
+The <code>CLASSPATH</code> environment variable is a source of many Ant support queries. As
+the round trip time for diagnosis on the Ant user mailing list can be slow, and
+because filing bug reports complaining about 'ant.bat' not working will be
+rejected by the developers as WORKSFORME "this is a configuration problem, not a
+bug", you can save yourself a lot of time and frustration by following some
+simple steps.
+
+</p>
+<ol>
+
+<li>Do not ever set <code>CLASSPATH</code>. Ant does not need it, it only causes confusion
+and breaks things.
+
+</li>
+
+<li>If you ignore the previous rule, do not ever, ever, put quotes in the
+<code>CLASSPATH</code>, even if there is a space in a directory. This will break Ant, and it
+is not needed. </li>
+
+<li>If you ignore the first rule, do not ever, ever, have a trailing backslash
+in a <code>CLASSPATH</code>, as it breaks Ant's ability to quote the string. Again, this is
+not needed for the correct operation of the <code>CLASSPATH</code> environment variable, even
+if a DOS directory is to be added to the path. </li>
+
+<li>You can stop Ant using the <code>CLASSPATH</code> environment variable by setting the
+<code>-noclasspath</code> option on the command line. This is an easy way
+to test for classpath-related problems.</li>
+
+</ol>
+
+<p>
+
+The usual symptom of <code>CLASSPATH</code> problems is that ant will not run with some error
+about not being able to find <code>org.apache.tools.ant.launch.Launcher</code>, or, if you have got the
+quotes/backslashes wrong, some very weird Java startup error. To see if this is
+the case, run <code>ant -noclasspath</code> or unset the <code>CLASSPATH</code> environment
+variable.
+
+</p>
+
+<p>
+You can also make your Ant script reject this environment
+variable just by placing the following at the top of the script (or in an init target):
+</p>
+<pre>
+&lt;property environment="env."/&gt;
+&lt;property name="env.CLASSPATH" value=""/&gt;
+&lt;fail message="Unset $CLASSPATH / %CLASSPATH% before running Ant!"&gt;
+ &lt;condition&gt;
+ &lt;not&gt;
+ &lt;equals arg1="${env.CLASSPATH}" arg2=""/&gt;
+ &lt;/not&gt;
+ &lt;/condition&gt;
+&lt;/fail&gt;
+</pre>
+
+<h3><a name="proxy">Proxy Configuration</a></h3>
+
+<p> Many Ant built-in and third-party tasks use network connections to retrieve
+files from HTTP servers. If you are behind a firewall with a proxy server, then
+Ant needs to be configured with the proxy. Here are the different ways to do
+this. </p>
+
+<ul>
+
+<li><b>With Java1.5 or above</b><br>
+
+<p>
+When you run Ant on Java1.5 or above, you could try to use the automatic proxy setup
+mechanism with <code>-autoproxy</code>.
+</p>
+
+</li>
+
+<li><b>With explicit JVM properties.</b><br>
+<p>
+These are documented in <a
+href="http://docs.oracle.com/javase/7/docs/technotes/guides/net/properties.html" target="_top">Java's Networking Properties</a>,
+and control the proxy behaviour of the entire JVM. To set them in Ant, declare
+them in the <code>ANT_OPTS</code> environment variable. This is the best option
+for a non-mobile system. For a laptop, you have to change these settings as you
+roam. To set ANT_OPTS:
+</p>
+<blockquote>
+<p>
+ For csh/tcsh:
+</p>
+<pre>
+ setenv ANT_OPTS "-Dhttp.proxyHost=proxy -Dhttp.proxyPort=8080"
+</pre>
+<p>
+ For bash:
+</p>
+<pre>
+ export ANT_OPTS="-Dhttp.proxyHost=proxy -Dhttp.proxyPort=8080"
+</pre>
+<p>
+ For Windows, set the environment variable in the appropriate dialog box
+ and open a new console. or, by hand
+</p>
+<pre>
+ set ANT_OPTS = -Dhttp.proxyHost=proxy -Dhttp.proxyPort=8080
+</pre>
+</p>
+</blockquote>
+</li>
+
+<li><b>In the build file itself</b><br>
+
+<p>
+If you are writing a build file that is always to be used behind the firewall,
+the &lt;setproxy&gt; task lets you configure the proxy (which it does by setting
+the JVM properties). If you do this, we strongly recommend using ant properties
+to define the proxy host, port, etc, so that individuals can override the
+defaults.</li>
+</p>
+
+</ul>
+
+<p> The Ant team acknowledges that this is unsatisfactory. Until the JVM
+automatic proxy setup works properly everywhere, explicit JVM options via
+ANT_ARGS are probably the best solution. Setting properties on Ant's
+command line do not work, because those are <i>Ant properties</i> being set, not
+JVM options. This means the following does not set up the command line:
+
+</p>
+
+<pre>ant -Dhttp.proxyHost=proxy -Dhttp.proxyPort=81</pre>
+
+<p> All it does is set up two Ant properties.</p>
+
+<p>One other troublespot with
+proxies is with authenticating proxies. Ant cannot go beyond what the JVM does
+here, and as it is very hard to remotely diagnose, test and fix proxy-related
+problems, users who work behind a secure proxy will have to spend much time
+configuring the JVM properties until they are happy. </p>
+
+
+<h3><a name="windows">Windows and OS/2</a></h3>
+<p>Assume Ant is installed in <code>c:\ant\</code>. The following sets up the
+environment:</p>
+<pre>set ANT_HOME=c:\ant
+set JAVA_HOME=c:\jdk1.7.0_51
+set PATH=%PATH%;%ANT_HOME%\bin</pre>
+
+<h3><a name="bash">Linux/Unix (bash)</a></h3>
+<p>Assume Ant is installed in <code>/usr/local/ant</code>. The following sets up
+the environment:</p>
+<pre>export ANT_HOME=/usr/local/ant
+export JAVA_HOME=/usr/local/jdk1.7.0_51
+export PATH=${PATH}:${ANT_HOME}/bin</pre>
+
+<h3><a name="tcshcsh">Linux/Unix (csh)</a></h3>
+<pre>setenv ANT_HOME /usr/local/ant
+setenv JAVA_HOME /usr/local/jdk/jdk1.7.0_51
+set path=( $path $ANT_HOME/bin )</pre>
+
+<p>
+Having a symbolic link set up to point to the JVM/JDK version makes updates more seamless. </p>
+<a name="jpackage"></a>
+<h3>RPM version from jpackage.org</h3>
+<p>
+The <a href="http://www.jpackage.org" target="_top">JPackage project</a> distributes an RPM version of Ant.
+With this version, it is not necessary to set <code> JAVA_HOME </code>or
+<code> ANT_HOME </code>environment variables and the RPM installer will correctly
+place the Ant executable on your path.
+</p>
+ <p>
+ <b>NOTE:</b> <em>Since Ant 1.7.0</em>, if the <code>ANT_HOME</code>
+ environment variable is set, the jpackage distribution will be
+ ignored.
+ </p>
+ <p>
+Optional jars for the JPackage version are handled in two ways. The easiest, and
+best way is to get these external libraries from JPackage if JPackage has them
+available. (Note: for each such library, you will have to get both the external
+package itself (e.g. <code>oro-2.0.8-2jpp.noarch.rpm</code>) and the small library that links
+ant and the external package (e.g. <code>ant-apache-oro-1.6.2-3jpp.noarch.rpm</code>).
+</p><p>
+However, JPackage does not package proprietary software, and since some of the
+optional packages depend on proprietary jars, they must be handled as follows.
+This may violate the spirit of JPackage, but it is necessary if you need these proprietary packages.
+For example, suppose you want to install support for netrexx, which jpackage does not
+support:
+<ol>
+<li>Decide where you want to deploy the extra jars. One option is in <code>$ANT_HOME/lib</code>,
+which, for JPackage is usually <code>/usr/share/ant/lib</code>. Another, less messy option
+is to create an <code>.ant/lib</code> subdirectory of your home directory and place your
+non-jpackage ant jars there, thereby avoiding mixing jpackage
+libraries with non-jpackage stuff in the same folder.
+More information on where Ant finds its libraries is available
+<a href="http://ant.apache.org/manual/running.html#libs">here</a></li>
+<li>Download a non-jpackage binary distribution from the regular
+ <a href="http://ant.apache.org/bindownload.cgi" target="_top">Apache Ant site</a></li>
+<li>Unzip or untar the distribution into a temporary directory</li>
+<li>Copy the linking jar, in this case <code>ant-jai.jar</code>, into the library directory you
+chose in step 1 above.</li>
+<li>Copy the proprietary jar itself into the same directory.</li>
+</ol>
+Finally, if for some reason you are running on a system with both the JPackage and Apache versions of Ant
+available, if you should want to run the Apache version (which will have to be specified with an absolute file name,
+not found on the path), you should use Ant's <code>--noconfig</code> command-line switch to avoid JPackage's classpath mechanism.
+
+
+<h3><a name="advanced">Advanced</a></h3>
+
+<p>There are lots of variants that can be used to run Ant. What you need is at
+least the following:</p>
+<ul>
+<li>The classpath for Ant must contain <code>ant.jar</code> and any jars/classes
+needed for your chosen JAXP-compliant XML parser.</li>
+<li>When you need JDK functionality
+(such as for the <a href="Tasks/javac.html">javac</a> task or the
+<a href="Tasks/rmic.html">rmic</a> task), then <code>tools.jar</code>
+must be added. The scripts supplied with Ant,
+in the <code>bin</code> directory, will add
+the required JDK classes automatically, if the <code>JAVA_HOME</code>
+environment variable is set.</li>
+
+<li>When you are executing platform-specific applications, such as the
+<a href="Tasks/exec.html">exec</a> task or the
+<a href="Tasks/cvs.html">cvs</a> task, the property <code>ant.home</code>
+must be set to the directory containing where you installed Ant. Again
+this is set by the Ant scripts to the value of the ANT_HOME environment
+variable.</li>
+</ul>
+The supplied ant shell scripts all support an <tt>ANT_OPTS</tt>
+environment variable which can be used to supply extra options
+to ant. Some of the scripts also read in an extra script stored
+in the users home directory, which can be used to set such options. Look
+at the source for your platform's invocation script for details.
+
+<hr>
+<h2><a name="buildingant">Building Ant</a></h2>
+<p>To build Ant from source, you can either install the Ant source distribution
+or clone the ant repository from git. See <a href="#sourceEdition">Source Edition</a> for details.</p>
+<p>Once you have installed the source, change into the installation
+directory.</p>
+
+<p>Set the <code>JAVA_HOME</code> environment variable
+to the directory where the JDK is installed.
+See <a href="#installing">Installing Ant</a>
+for examples on how to do this for your operating system. </p>
+
+<p><b>Note</b>: The bootstrap process of Ant requires a greedy
+compiler like OpenJDK or Oracle's javac. It does not work with gcj or
+kjc.</p>
+
+<p>Make sure you have downloaded any auxiliary jars required to
+build tasks you are interested in. These should be
+added to the <code>lib/optional</code>
+directory of the source tree.
+See <a href="#librarydependencies">Library Dependencies</a>
+for a list of JAR requirements for various features.
+Note that this will make the auxiliary JAR
+available for the building of Ant only. For running Ant you will
+still need to
+make the JARs available as described under
+<a href="#installing">Installing Ant</a>.</p>
+
+<p>You can also get most of the auxiliary jar files (ie. the jar files
+that various optional Ant tasks depend on) by running Ant on the
+<code>fetch.xml</code> build file. See <a href="#optionalTasks">Optional
+Tasks</a> for instructions on how to do this.
+</p>
+
+<p>As of version 1.7.0 Ant has a hard dependency on JUnit. The <code>fetch.xml</code> build
+ script will download JUnit automatically, but if you don't use this you must
+ install it manually into <code>lib/optional</code> (download it from
+ <a href="http://junit.org/" target="_top">JUnit.org</a>) if you are
+ using a source distribution of Ant.</p>
+
+<p>Your are now ready to build Ant:</p>
+<blockquote>
+ <p><code>build -Ddist.dir=&lt;<i>directory_to_contain_Ant_distribution</i>&gt; dist</code>&nbsp;&nbsp;&nbsp;&nbsp;(<i>Windows</i>)</p>
+ <p><code>sh build.sh -Ddist.dir=&lt;<i>directory_to_contain_Ant_distribution</i>&gt; dist</code>&nbsp;&nbsp;&nbsp;&nbsp;(<i>Unix</i>)</p>
+</blockquote>
+
+<p>This will create a binary distribution of Ant in the directory you specified.</p>
+
+<p>The above action does the following:</p>
+<ul>
+
+<li>If necessary it will bootstrap the Ant code. Bootstrapping involves the manual
+compilation of enough Ant code to be able to run Ant. The bootstrapped Ant is
+used for the remainder of the build steps. </li>
+
+<li>Invokes the bootstrapped Ant with the parameters passed to the build script. In
+this case, these parameters define an Ant property value and specify the &quot;dist&quot; target
+in Ant's own <code>build.xml</code> file.</li>
+
+<li>Create the ant.jar and ant-launcher.jar JAR files</li>
+
+<li>Create optional JARs for which the build had the relevant libraries. If
+a particular library is missing from ANT_HOME/lib/optional, then the matching
+ant- JAR file will not be created. For example, ant-junit.jar is only built
+if there is a junit.jar in the optional directory.</li>
+</ul>
+
+<p>On most occasions you will not need to explicitly bootstrap Ant since the build
+scripts do that for you. If however, the build file you are using makes use of features
+not yet compiled into the bootstrapped Ant, you will need to manually bootstrap.
+Run <code>bootstrap.bat</code> (Windows) or <code>bootstrap.sh</code> (UNIX)
+to build a new bootstrap version of Ant.</p>
+
+If you wish to install the build into the current <code>ANT_HOME</code>
+directory, you can use:
+<blockquote>
+ <p><code>build install</code>&nbsp;&nbsp;&nbsp;&nbsp;(<i>Windows</i>)</p>
+ <p><code>sh build.sh install</code>&nbsp;&nbsp;&nbsp;&nbsp;(<i>Unix</i>)</p>
+</blockquote>
+
+You can avoid the lengthy Javadoc step, if desired, with:
+<blockquote>
+ <p><code>build install-lite</code>&nbsp;&nbsp;&nbsp;&nbsp;(<i>Windows</i>)</p>
+ <p><code>sh build.sh install-lite</code>&nbsp;&nbsp;&nbsp;&nbsp;(<i>Unix</i>)</p>
+</blockquote>
+This will only install the <code>bin</code> and <code>lib</code> directories.
+<p>Both the <code>install</code> and
+<code>install-lite</code> targets will overwrite
+the current Ant version in <code>ANT_HOME</code>.</p>
+
+<p>Ant's build script will try to set executable flags for its shell
+ scripts on Unix-like systems. There are various reasons why the
+ chmod-task might fail (like when you are running the build script as
+ a different user than the one who installed Ant initially). In this
+ case you can set the Ant property <code>chmod.fail</code> to false
+ when starting the build like in
+<blockquote>
+ <p><code>sh build.sh install -Dchmod.fail=false</code></p>
+</blockquote>
+and any error to change permission will not result in a build failure.</p>
+
+<hr>
+<h2><a name="librarydependencies">Library Dependencies</a></h2>
+<p>The following libraries are needed in Ant's classpath
+if you are using the
+indicated feature. Note that only one of the regexp libraries is
+needed for use with the mappers
+(and Java includes a regexp implementation which
+Ant will find automatically).
+You will also need to install the particular
+Ant optional jar containing the task definitions to make these
+tasks available. Please refer to the <a href="#optionalTasks">
+Installing Ant / Optional Tasks</a> section above.</p>
+
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td><b>Jar Name</b></td>
+ <td><b>Needed For</b></td>
+ <td><b>Available At</b></td>
+ </tr>
+ <tr>
+ <td>jakarta-regexp-1.3.jar</td>
+ <td>regexp type with mappers (if you do not wish to use java.util.regex)</td>
+ <td><a href="http://attic.apache.org/projects/jakarta-regexp.html" target="_top">http://attic.apache.org/projects/jakarta-regexp.html</a></td>
+ </tr>
+ <tr>
+ <td>jakarta-oro-2.0.8.jar</td>
+ <td>regexp type with mappers (if you do not wish to use java.util.regex)<br>
+ To use the FTP task,
+you need jakarta-oro 2.0.8 or later, and <a href="#commons-net">commons-net</a></td>
+ <td><a href="http://attic.apache.org/projects/jakarta-oro.html" target="_top">http://attic.apache.org/projects/jakarta-oro.html</a></td>
+ </tr>
+ <tr>
+ <td>junit.jar</td>
+ <td><code>&lt;junit&gt;</code> task. May be in classpath passed to task rather than Ant's classpath.</td>
+ <td><a href="http://www.junit.org/" target="_top">http://www.junit.org/</a></td>
+ </tr>
+ <tr>
+ <td>xalan.jar</td>
+ <td>junitreport task</td>
+ <td><a href="http://xml.apache.org/xalan-j/" target="_top">http://xml.apache.org/xalan-j/</a></td>
+ </tr>
+ <tr>
+ <td>antlr.jar</td>
+ <td>antlr task</td>
+ <td><a href="http://www.antlr.org/" target="_top">http://www.antlr.org/</a></td>
+ </tr>
+ <tr>
+ <td>bsf.jar</td>
+ <td>script task
+ <p>
+ <strong>Note</strong>: Ant 1.6 and later require Apache BSF, not
+ the IBM version. I.e. you need BSF 2.3.0-rc1 or later.
+ </p>
+ <p>
+ <strong>Note</strong>: BSF 2.4.0 is needed to use a post 1.5R3 version
+ of rhino's javascript.
+ </p>
+ <p>
+ <strong>Note</strong>: BSF 2.4.0 uses jakarta-commons-logging
+ so it needs the commons-logging.jar.
+ </p>
+ </td>
+ <td><a href="http://jakarta.apache.org/bsf/" target="_top">http://jakarta.apache.org/bsf/</a></td>
+ </tr>
+ <tr>
+ <td>Groovy jars</td>
+ <td>Groovy with script and scriptdef tasks<br>
+ You need to get the groovy jar and two asm jars from a groovy
+ installation. The jars are groovy-[version].jar, asm-[version].jar and
+ asm-util-[version].jar and antlr-[version].jar.
+ As of groovy version 1.0-JSR-06, the jars are
+ groovy-1.0-JSR-06.jar, antlr-2.7.5.jar, asm-2.2.jar and asm-util-2.2.jar.
+ Alternatively one may use the embedded groovy jar file.
+ This is located in the embedded directory of the groovy distribution.
+ This bundles all the needed jar files into one jar file.
+ It is called groovy-all-[version].jar.
+ </td>
+ <td>
+ <a href="http://groovy.codehaus.org/" target="_top">http://groovy.codehaus.org/</a>
+ <br>
+ The asm jars are also available from the creators of asm -
+ <a href="http://asm.objectweb.org/" target="_top">http://asm.objectweb.org/</a>
+ </td>
+ </tr>
+ <tr>
+ <td>netrexx.jar</td>
+ <td>netrexx task, Rexx with the script task</td>
+ <td><a href="http://www.ibm.com/software/awdtools/netrexx/download.html" target="_top">
+ http://www.ibm.com/software/awdtools/netrexx/download.html</a></td>
+ </tr>
+ <tr>
+ <td>js.jar</td>
+ <td>Javascript with script task<br>
+ If you use Apache BSF 2.3.0-rc1, you must use rhino 1.5R3 (later
+ versions of BSF (e.g. version 2.4.0) work with 1.5R4 and higher).</td>
+ <td><a href="http://www.mozilla.org/rhino/" target="_top">http://www.mozilla.org/rhino/</a></td>
+ </tr>
+ <tr>
+ <td>jython.jar</td>
+ <td>Python with script task<br>
+ Warning : jython.jar also contains classes from jakarta-oro.
+ Remove these classes if you are also using jakarta-oro.</td>
+ <td><a href="http://jython.sourceforge.net/" target="_top">http://jython.sourceforge.net/</a></td>
+ </tr>
+ <tr>
+ <td>jpython.jar</td>
+ <td>Python with script task <b>deprecated, jython is the preferred engine</b></td>
+ <td><a href="http://www.jpython.org/" target="_top">http://www.jpython.org/</a></td>
+ </tr>
+ <tr>
+ <td>jacl.jar and tcljava.jar</td>
+ <td>TCL with script task</td>
+ <td><a href="http://www.scriptics.com/software/java/" target="_top">http://www.scriptics.com/software/java/</a></td>
+ </tr>
+ <tr>
+ <td>BeanShell JAR(s)</td>
+ <td>BeanShell with script task.
+ <br>
+ <strong>Note</strong>: Ant requires BeanShell version 1.3 or
+ later</td>
+ <td><a href="http://www.beanshell.org/" target="_top">http://www.beanshell.org/</a></td>
+ </tr>
+ <tr>
+ <td>jruby.jar</td>
+ <td>Ruby with script task</td>
+ <td><a href="http://jruby.org/" target="_top">http://jruby.org/</a></td>
+ </tr>
+ <tr>
+ <td>judo.jar</td>
+ <td>Judoscript with script task</td>
+ <td><a href="http://www.judoscript.org/" target="_top">http://www.judoscript.org/</a></td>
+ </tr>
+ <tr>
+ <td>commons-logging.jar</td>
+ <td>CommonsLoggingListener</td>
+ <td><a href="http://commons.apache.org/logging/"
+ target="_top">http://commons.apache.org/logging/</a></td>
+ </tr>
+ <tr>
+ <td>log4j.jar</td>
+ <td>Log4jListener</td>
+ <td><a href="http://logging.apache.org/log4j/"
+ target="_top">http://logging.apache.org/log4j/</a></td>
+ </tr>
+ <tr>
+ <td><a name="commons-net">commons-net.jar</a></td>
+ <td>ftp, rexec and telnet tasks<br>
+ jakarta-oro 2.0.8 or later is required together with commons-net 1.4.0.<br>
+ For all users, a minimum version of commons-net of 1.4.0 is recommended. Earlier
+ versions did not support the full range of configuration options, and 1.4.0 is needed
+ to compile Ant.
+ </td>
+ <td><a href="http://commons.apache.org/net/"
+ target="_top">http://commons.apache.org/net/</a></td>
+ </tr>
+ <tr>
+ <td>bcel.jar</td>
+ <td>classfileset data type,
+ JavaClassHelper used by the ClassConstants filter reader and
+ optionally used by ejbjar for dependency determination
+ </td>
+ <td><a href="http://commons.apache.org/bcel/" target="_top">http://commons.apache.org/bcel/</a></td>
+ </tr>
+ <tr>
+ <td>mail.jar</td>
+ <td>Mail task with Mime encoding, and the MimeMail task</td>
+ <td><a href="http://www.oracle.com/technetwork/java/index-138643.html"
+ target="_top">http://www.oracle.com/technetwork/java/index-138643.html</a></td>
+ </tr>
+ <tr>
+ <td>activation.jar</td>
+ <td>Mail task with Mime encoding, and the MimeMail task</td>
+ <td><a href="http://www.oracle.com/technetwork/java/javase/jaf-135115.html"
+ target="_top">http://www.oracle.com/technetwork/java/javase/jaf-135115.html</a></td>
+ </tr>
+ <tr>
+ <td>jdepend.jar</td>
+ <td>jdepend task</td>
+ <td><a href="http://www.clarkware.com/software/JDepend.html"
+ target="_top">http://www.clarkware.com/software/JDepend.html</a></td>
+ </tr>
+ <tr>
+ <td>resolver.jar <b>1.1beta or later</b></td>
+ <td>xmlcatalog datatype <em>only if support for external catalog files is desired</em></td>
+ <td><a href="http://xml.apache.org/commons/"
+ target="_top">http://xml.apache.org/commons/</a>.</td>
+ </tr>
+ <tr>
+ <td>jsch.jar <b>0.1.50 or later</b></td>
+ <td>sshexec and scp tasks</td>
+ <td><a href="http://www.jcraft.com/jsch/index.html"
+ target="_top">http://www.jcraft.com/jsch/index.html</a></td>
+ </tr>
+ <tr>
+ <td>JAI - Java Advanced Imaging</td>
+ <td>image task</td>
+ <td><a href="https://jai.dev.java.net/"
+ target="_top">https://jai.dev.java.net/</a></td>
+ </tr>
+</table>
+<br>
+<h2><a name="Troubleshooting">Troubleshooting</a></h2>
+
+
+<h3><a name="diagnostics">Diagnostics</a></h3>
+
+<p> Ant has a built in diagnostics feature. If you run <code>ant
+-diagnostics</code> ant will look at its internal state and print it out. This
+code will check and print the following things. </p>
+
+<ul>
+
+<li>Where Ant is running from. Sometimes you can be surprised.</li>
+
+<li>The version of ant.jar and of the ant-*.jar containing the optional tasks -
+ and whether they match</li>
+
+<li>Which JAR files are in ANT_HOME/lib
+
+<li>Which optional tasks are available. If a task is not listed as being
+available, either it is not present, or libraries that it depends on are
+absent.</li>
+
+
+<li>XML Parser information</li>
+
+<li>JVM system properties
+</li>
+
+<li>The status of the temp directory. If this is not writable, or its clock is
+horribly wrong (possible if it is on a network drive), a lot of tasks will fail
+with obscure error messages.</li>
+
+<li>The current time zone as Java sees it. If this is not what it should be for
+your location, then dependency logic may get confused.
+
+</ul>
+
+<p>
+ Running <code>ant -diagnostics</code> is a good way to check that ant is
+ installed. It is also a first step towards self-diagnosis of any problem.
+ Any configuration problem reported to the user mailing list will probably
+ result ins someone asking you to run the command and show the results, so
+ save time by using it yourself.
+</p>
+
+<p>
+ For under-IDE diagnostics, use the &lt;diagnostics&gt; task to run the same
+ tests as an ant task. This can be added to a diagnostics target in a build
+ file to see what tasks are available under the IDE, what the XML parser and
+ classpath is, etc.
+</p>
+
+<h3><a name="ant-user">user mailing list</a></h3>
+
+<p> If you cannot get Ant installed or working, the Ant user mailing list is the
+best place to start with any problem. Please do your homework first, make sure
+that it is not a <a href="#classpath"><code>CLASSPATH</code></a> problem, and run a <a
+href="#diagnostics">diagnostics check</a> to see what Ant thinks of its own
+state. Why the user list, and not the developer list?
+Because there are more users than developers, so more people who can help you. </p>
+
+<p>
+
+Please only file a bug report against Ant for a configuration/startup problem if
+there really is a fixable bug in Ant related to configuration, such as it not
+working on a particular platform, with a certain JVM version, etc, or if you are
+advised to do it by the user mailing list.
+</p>
+
+
+
+
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/installlist.html b/framework/src/ant/apache-ant-1.9.6/manual/installlist.html
new file mode 100644
index 00000000..6bbe3dd0
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/installlist.html
@@ -0,0 +1,44 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us"/>
+<link rel="stylesheet" type="text/css" href="stylesheets/style.css"/>
+<title>Apache Ant User Manual</title>
+<base target="mainFrame"/>
+</head>
+
+<body>
+
+<h2><a href="toc.html" target="navFrame">Table of Contents</a></h2>
+
+<h3>Installing Apache Ant</h3>
+<ul class="inlinelist">
+<li><a href="install.html#getting">Getting Ant</a></li>
+<li><a href="install.html#sysrequirements">System Requirements</a></li>
+<li><a href="install.html#installing">Installing Ant</a></li>
+<li><a href="install.html#checkInstallation">Check Installation</a></li>
+<li><a href="install.html#optionalTasks">Optional Tasks</a></li>
+<li><a href="install.html#buildingant">Building Ant</a></li>
+<li><a href="install.html#librarydependencies">Library Dependencies</a></li>
+<li><a href="platform.html">Platform Specific Issues</a></li>
+<li><a href="proxy.html">Proxy configuration</a></li>
+</ul>
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/intro.html b/framework/src/ant/apache-ant-1.9.6/manual/intro.html
new file mode 100644
index 00000000..e5673ed7
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/intro.html
@@ -0,0 +1,69 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="stylesheets/style.css">
+<title>Apache Ant User Manual - Introduction</title>
+</head>
+
+<body>
+<h1><a name="introduction">Introduction</a></h1>
+<p>Apache Ant is a Java-based build tool. In theory, it is kind of like
+<i>make</i>, without <i>make</i>'s wrinkles.</p>
+<h3>Why?</h3>
+<p>Why another build tool when there is already
+<i>make</i>,
+<i>gnumake</i>,
+<i>nmake</i>,
+<i>jam</i>,
+and
+others? Because all those tools have limitations that Ant's original author
+couldn't live with when developing software across multiple platforms.
+Make-like
+tools are inherently shell-based: they evaluate a set of dependencies,
+then execute commands not unlike what you would issue on a shell.
+This means that you
+can easily extend these tools by using or writing any program for the OS that
+you are working on; however, this also means that you limit yourself to the OS,
+or at least the OS type, such as Unix, that you are working on.</p>
+<p>Makefiles are inherently evil as well. Anybody who has worked on them for any
+time has run into the dreaded tab problem. &quot;Is my command not executing
+because I have a space in front of my tab?!!&quot; said the original author of
+Ant way too many times. Tools like Jam took care of this to a great degree, but
+still have yet another format to use and remember.</p>
+<p>Ant is different. Instead of a model where it is extended with shell-based
+commands, Ant is extended using Java classes. Instead of writing shell commands,
+the configuration files are XML-based, calling out a target tree where various
+tasks get executed. Each task is run by an object that implements a particular
+Task interface.</p>
+<p>Granted, this removes some of the expressive power that is inherent in being
+able to construct a shell command such as
+<nobr><code>`find . -name foo -exec rm {}`</code></nobr>, but it
+gives you the ability to be cross-platform--to work anywhere and
+everywhere. And
+hey, if you really need to execute a shell command, Ant has an
+<code>&lt;exec&gt;</code> task that
+allows different commands to be executed based on the OS it is executing
+on.</p>
+
+
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/javacprops.html b/framework/src/ant/apache-ant-1.9.6/manual/javacprops.html
new file mode 100644
index 00000000..6cab07c4
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/javacprops.html
@@ -0,0 +1,53 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="stylesheets/style.css">
+<title>Properties controlling javac</title>
+</head>
+
+<body>
+
+<p>The source and target attributes of <code>&lt;javac&gt;</code>
+don't have any default values for historical reasons. Since the
+underlying javac compiler's default depends on the JDK you use, you
+may encounter build files that don't explicitly set those attributes
+and that will no longer compile using a newer JDK. If you cannot
+change the build file, Apache Ant provides two properties that help you
+setting default values for these attributes. If the attributes have
+been set explicitly, the properties listed here will be ignored.</p>
+
+<h2><a name="source">ant.build.javac.source</a></h2>
+
+<p><em>Since Ant 1.7</em></p>
+
+<p>Provides a default value for <code>&lt;javac&gt;</code>'s and
+<code>&lt;javadoc&gt;</code>'s source attribute.</p>
+
+<h2><a name="target">ant.build.javac.target</a></h2>
+
+<p><em>Since Ant 1.7</em></p>
+
+<p>Provides a default value for <code>&lt;javac&gt;</code>'s target
+attribute.</p>
+
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/listeners.html b/framework/src/ant/apache-ant-1.9.6/manual/listeners.html
new file mode 100644
index 00000000..2015cd52
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/listeners.html
@@ -0,0 +1,623 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="stylesheets/style.css">
+<title>Listeners &amp; Loggers</title>
+</head>
+
+<body>
+<h1>Listeners &amp; Loggers</h1>
+
+<h2><a name="Overview">Overview</a></h2>
+
+<p>Apache Ant has two related features to allow the build process to be monitored:
+listeners and loggers.</p>
+
+<h3><a name="Listeners">Listeners</a></h3>
+
+<p>A listener is alerted of the following events:</p>
+
+<ul>
+ <li>build started</li>
+ <li>build finished</li>
+ <li>target started</li>
+ <li>target finished</li>
+ <li>task started</li>
+ <li>task finished</li>
+ <li>message logged</li>
+</ul>
+
+<p>
+ These are used internally for various recording and housekeeping operations,
+ however new listeners may registered on the command line through the <code>-listener</code>
+ argument.
+</p>
+
+<h3><a name="Loggers">Loggers</a></h3>
+
+<p>Loggers extend the capabilities of listeners and add the following features:</p>
+
+<ul>
+ <li>Receives a handle to the standard output and error print streams and
+ therefore can log information to the console or the <code>-logfile</code> specified file.</li>
+ <li>Logging level (-quiet, -verbose, -debug) aware</li>
+ <li>Emacs-mode aware</li>
+</ul>
+
+<h2><a name="builtin">Built-in Listeners/Loggers</a></h2>
+
+<table border="1" cellspacing="1" width="100%" id="AutoNumber1">
+ <tr>
+ <td width="33%">Classname</td>
+ <td width="33%">Description</td>
+ <td width="34%">Type</td>
+ </tr>
+ <tr>
+ <td width="33%"><code><a href="#DefaultLogger">org.apache.tools.ant.DefaultLogger</a></code></td>
+ <td width="33%">The logger used implicitly unless overridden with the
+ <code>-logger</code> command-line switch.</td>
+ <td width="34%">BuildLogger</td>
+ </tr>
+ <tr>
+ <td width="33%"><code><a href="#NoBannerLogger">
+ org.apache.tools.ant.NoBannerLogger</a></code></td>
+ <td width="33%">This logger omits output of empty target output.</td>
+ <td width="34%">BuildLogger</td>
+ </tr>
+ <tr>
+ <td width="33%"><code><a href="#MailLogger">
+ org.apache.tools.ant.listener.MailLogger</a></code></td>
+ <td width="33%">Extends DefaultLogger such that output is still generated
+ the same, and when the build is finished an e-mail can be sent.</td>
+ <td width="34%">BuildLogger</td>
+ </tr>
+ <tr>
+ <td width="33%"><code><a href="#AnsiColorLogger">
+ org.apache.tools.ant.listener.AnsiColorLogger</a></code></td>
+ <td width="33%">Colorifies the build output.</td>
+ <td width="34%">BuildLogger</td>
+ </tr>
+ <tr>
+ <td width="33%"><code><a href="#Log4jListener">
+ org.apache.tools.ant.listener.Log4jListener</a></code></td>
+ <td width="33%">Passes events to Log4j for highly customizable logging.</td>
+ <td width="34%">BuildListener</td>
+ </tr>
+ <tr>
+ <td width="33%"><code><a href="#XmlLogger">org.apache.tools.ant.XmlLogger</a></code></td>
+ <td width="33%">Writes the build information to an XML file.</td>
+ <td width="34%">BuildLogger</td>
+ </tr>
+ <tr>
+ <td width="33%"><code><a href="#TimestampedLogger">org.apache.tools.ant.TimestampedLogger</a></code></td>
+ <td width="33%">Prints the time that a build finished</td>
+ <td width="34%">BuildLogger</td>
+ </tr>
+ <tr>
+ <td width="33%"><code><a href="#BigProjectLogger">org.apache.tools.ant.listener.BigProjectLogger</a></code></td>
+ <td width="33%">Prints the project name every target</td>
+ <td width="34%">BuildLogger</td>
+ </tr>
+ <tr>
+ <td width="33%"><code><a href="#SimpleBigProjectLogger">org.apache.tools.ant.listener.SimpleBigProjectLogger</a></code></td>
+ <td width="33%">Prints the project name for subprojects only, otherwise like NoBannerLogger <em>Since Ant 1.8.1</em></td>
+ <td width="34%">BuildLogger</td>
+ </tr>
+ <tr>
+ <td width="33%"><code><a href="#ProfileLogger">org.apache.tools.ant.listener.ProfileLogger</a></code></td>
+ <td width="33%">The default logger, with start times, end times and
+ durations added for each task and target.</td>
+ <td width="34%">BuildLogger</td>
+ </tr>
+</table>
+
+
+
+<h3><a name="DefaultLogger">DefaultLogger</a></h3>
+<p>Simply run Ant normally, or:</p>
+<blockquote>
+<p><code>ant -logger org.apache.tools.ant.DefaultLogger</code></p>
+</blockquote>
+
+
+
+<h3><a name="NoBannerLogger">NoBannerLogger</a></h3>
+<p>Removes output of empty target output.</p>
+<blockquote>
+<p><code>ant -logger org.apache.tools.ant.NoBannerLogger</code></p>
+</blockquote>
+
+
+
+<h3><a name="MailLogger">MailLogger</a></h3>
+<p>The MailLogger captures all output logged through DefaultLogger (standard Ant
+output) and will send success and failure messages to unique e-mail lists, with
+control for turning off success or failure messages individually.</p>
+
+<p>Properties controlling the operation of MailLogger:</p>
+<table border="1" cellspacing="1" width="100%" id="AutoNumber2">
+ <tr>
+ <th width="337">Property</th>
+ <th width="63%">Description</th>
+ <th width="63%">Required</th>
+ </tr>
+ <tr>
+ <td width="337">MailLogger.mailhost </td>
+ <td width="63%">Mail server to use</td>
+ <td width="63%">No, default &quot;localhost&quot;</td>
+ </tr>
+ <tr>
+ <td width="337">MailLogger.port </td>
+ <td width="63%">SMTP Port for the Mail server</td>
+ <td width="63%">No, default &quot;25&quot;</td>
+ </tr>
+ <tr>
+ <td width="337">MailLogger.user</td>
+ <td width="63%">user name for SMTP auth</td>
+ <td width="63%">Yes, if SMTP auth is required on your SMTP server<br>
+ the email message will be then sent using Mime and requires JavaMail</td>
+ </tr>
+ <tr>
+ <td width="337">MailLogger.password</td>
+ <td width="63%">password for SMTP auth</td>
+ <td width="63%">Yes, if SMTP auth is required on your SMTP server<br>
+ the email message will be then sent using Mime and requires JavaMail</td>
+ </tr>
+ <tr>
+ <td width="337">MailLogger.ssl</td>
+ <td width="63%">on or true if ssl is needed<br>
+ This feature requires JavaMail</td>
+ <td width="63%">
+ no</td>
+ </tr>
+ <tr>
+ <td width="337">MailLogger.from</td>
+ <td width="63%">Mail &quot;from&quot; address</td>
+ <td width="63%">Yes, if mail needs to be sent</td>
+ </tr>
+ <tr>
+ <td width="337">MailLogger.replyto</td>
+ <td width="63%">Mail &quot;replyto&quot; address(es), comma-separated</td>
+ <td width="63%">No</td>
+ </tr>
+ <tr>
+ <td width="337">MailLogger.failure.notify </td>
+ <td width="63%">Send build failure e-mails?</td>
+ <td width="63%">No, default &quot;true&quot;</td>
+ </tr>
+ <tr>
+ <td width="337">MailLogger.success.notify </td>
+ <td width="63%">Send build success e-mails?</td>
+ <td width="63%">No, default &quot;true&quot;</td>
+ </tr>
+ <tr>
+ <td width="337">MailLogger.failure.to </td>
+ <td width="63%">Address(es) to send failure messages to, comma-separated</td>
+ <td width="63%">Yes, if failure mail is to be sent</td>
+ </tr>
+ <tr>
+ <td width="337">MailLogger.success.to </td>
+ <td width="63%">Address(es) to send success messages to, comma-separated</td>
+ <td width="63%">Yes, if success mail is to be sent</td>
+ </tr>
+ <tr>
+ <td width="337">MailLogger.failure.cc </td>
+ <td width="63%">Address(es) to send failure messages to carbon copy (cc), comma-separated</td>
+ <td width="63%">No</td>
+ </tr>
+ <tr>
+ <td width="337">MailLogger.success.cc </td>
+ <td width="63%">Address(es) to send success messages to carbon copy (cc), comma-separated</td>
+ <td width="63%">No</td>
+ </tr>
+ <tr>
+ <td width="337">MailLogger.failure.bcc </td>
+ <td width="63%">Address(es) to send failure messages to blind carbon copy (bcc), comma-separated</td>
+ <td width="63%">No</td>
+ </tr>
+ <tr>
+ <td width="337">MailLogger.success.bcc </td>
+ <td width="63%">Address(es) to send success messages to blind carbon copy (bcc), comma-separated</td>
+ <td width="63%">No</td>
+ </tr>
+ <tr>
+ <td width="337">MailLogger.failure.subject </td>
+ <td width="63%">Subject of failed build</td>
+ <td width="63%">No, default &quot;Build Failure&quot;</td>
+ </tr>
+ <tr>
+ <td width="337">MailLogger.success.subject </td>
+ <td width="63%">Subject of successful build</td>
+ <td width="63%">No, default &quot;Build Success&quot;</td>
+ </tr>
+ <tr>
+ <td width="337">MailLogger.failure.body</td>
+ <td width="63%">Fixed body of the email for a failed
+ build. <em>Since Ant 1.8.0</em></td>
+ <td width="63%">No, default is to send the full log output.</td>
+ </tr>
+ <tr>
+ <td width="337">MailLogger.success.body</td>
+ <td width="63%">Fixed body of the email for a successful
+ build. <em>Since Ant 1.8.0</em></td>
+ <td width="63%">No, default is to send the full log output.</td>
+ </tr>
+ <tr>
+ <td width="337">MailLogger.mimeType</td>
+ <td width="63%">MIME-Type of the message. <em>Since Ant 1.8.0</em></td>
+ <td width="63%">No, default is text/plain</td>
+ </tr>
+ <tr>
+ <td width="337">MailLogger.charset</td>
+ <td width="63%">Character set of the message. <em>Since Ant 1.8.0</em></td>
+ <td width="63%">No</td>
+ </tr>
+ <tr>
+ <td width="337">MailLogger.starttls.enable</td>
+ <td width="63%">on or true if STARTTLS should be supported
+ (requires JavaMail). <em>Since Ant 1.8.0</em></td>
+ <td width="63%">No, default is false</td>
+ </tr>
+ <tr>
+ <td width="337">MailLogger.properties.file </td>
+ <td width="63%">Filename of properties file that will override other values.</td>
+ <td width="63%">No</td>
+ </tr>
+</table>
+
+<blockquote>
+<p><code>ant -logger org.apache.tools.ant.listener.MailLogger</code></p>
+</blockquote>
+
+
+
+<h3><a name="AnsiColorLogger">AnsiColorLogger</a></h3>
+
+<p>The AnsiColorLogger adds color to the standard Ant output
+by prefixing and suffixing ANSI color code escape sequences to
+it. It is just an extension of <a href="#DefaultLogger">DefaultLogger</a>
+and hence provides all features that DefaultLogger does.</p>
+<p>AnsiColorLogger differentiates the output by assigning
+different colors depending upon the type of the message.</p>
+<p>If used with the -logfile option, the output file
+will contain all the necessary escape codes to
+display the text in colorized mode when displayed
+in the console using applications like cat, more, etc.</p>
+<p>This is designed to work on terminals that support ANSI
+color codes. It works on XTerm, ETerm, Win9x Console
+(with ANSI.SYS loaded.), etc.</p>
+<p><Strong>NOTE:</Strong>
+It doesn't work on WinNT and successors, even when a COMMAND.COM console loaded with
+ANSI.SYS is used.</p>
+<p>If the user wishes to override the default colors
+with custom ones, a file containing zero or more of the
+custom color key-value pairs must be created. The recognized keys
+and their default values are shown below:</p><code><pre>
+AnsiColorLogger.ERROR_COLOR=2;31
+AnsiColorLogger.WARNING_COLOR=2;35
+AnsiColorLogger.INFO_COLOR=2;36
+AnsiColorLogger.VERBOSE_COLOR=2;32
+AnsiColorLogger.DEBUG_COLOR=2;34</pre></code>
+<p>Each key takes as value a color combination defined as
+<b>Attribute;Foreground;Background</b>. In the above example, background
+value has not been used.</p>
+<p>This file must be specified as the value of a system variable
+named ant.logger.defaults and passed as an argument using the -D
+option to the <b>java</b> command that invokes the Ant application.
+An easy way to achieve this is to add -Dant.logger.defaults=
+<i>/path/to/your/file</i> to the ANT_OPTS environment variable.
+Ant's launching script recognizes this flag and will pass it to
+the java command appropriately.</p>
+<p>Format:</p><pre>
+AnsiColorLogger.*=Attribute;Foreground;Background
+
+Attribute is one of the following:
+0 -&gt; Reset All Attributes (return to normal mode)
+1 -&gt; Bright (Usually turns on BOLD)
+2 -&gt; Dim
+3 -&gt; Underline
+5 -&gt; link
+7 -&gt; Reverse
+8 -&gt; Hidden
+
+Foreground is one of the following:
+30 -&gt; Black
+31 -&gt; Red
+32 -&gt; Green
+33 -&gt; Yellow
+34 -&gt; Blue
+35 -&gt; Magenta
+36 -&gt; Cyan
+37 -&gt; White
+
+Background is one of the following:
+40 -&gt; Black
+41 -&gt; Red
+42 -&gt; Green
+43 -&gt; Yellow
+44 -&gt; Blue
+45 -&gt; Magenta
+46 -&gt; Cyan
+47 -&gt; White</pre>
+
+<blockquote>
+<p><code>ant -logger org.apache.tools.ant.listener.AnsiColorLogger</code></p>
+</blockquote>
+
+
+
+<h3><a name="Log4jListener">Log4jListener</a></h3>
+<p>Passes build events to Log4j, using the full classname's of the generator of
+each build event as the category:</p>
+<ul>
+ <li>build started / build finished - org.apache.tools.ant.Project</li>
+ <li>target started / target finished - org.apache.tools.ant.Target</li>
+ <li>task started / task finished - the fully qualified classname of the task</li>
+ <li>message logged - the classname of one of the above, so if a task logs a
+ message, its classname is the category used, and so on.</li>
+</ul>
+<p>All start events are logged as INFO.&nbsp; Finish events are either logged as
+INFO or ERROR depending on whether the build failed during that stage. Message
+events are logged according to their Ant logging level, mapping directly to a
+corresponding Log4j level.</p>
+
+<blockquote>
+<p><code>ant -listener org.apache.tools.ant.listener.Log4jListener</code></p>
+</blockquote>
+
+<p>To use Log4j you will need the Log4j JAR file and a 'log4j.properties'
+configuration file. Both should be placed somewhere in your Ant
+classpath. If the log4j.properties is in your project root folder you can
+add this with <i>-lib</i> option:</p>
+
+<blockquote>
+<pre><code>ant -listener org.apache.tools.ant.listener.Log4jListener -lib .</code></pre>
+</blockquote>
+
+<p>If, for example, you wanted to capture the same information output to the
+console by the DefaultLogger and send it to a file named 'build.log', you
+could use the following configuration:</p>
+
+<blockquote>
+<pre><code>log4j.rootLogger=ERROR, LogFile
+log4j.logger.org.apache.tools.ant.Project=INFO
+log4j.logger.org.apache.tools.ant.Target=INFO
+log4j.logger.org.apache.tools.ant.taskdefs=INFO
+log4j.logger.org.apache.tools.ant.taskdefs.Echo=WARN
+
+log4j.appender.LogFile=org.apache.log4j.FileAppender
+log4j.appender.LogFile.layout=org.apache.log4j.PatternLayout
+log4j.appender.LogFile.layout.ConversionPattern=[%6r] %8c{1} : %m%n
+log4j.appender.LogFile.file=build.log
+</code></pre>
+</blockquote>
+
+<p>For more information about configuring Log4J see <a href="http://logging.apache.org/log4j/docs/documentation.html">its
+documentation page</a>.</p>
+
+
+
+<h3><a name="XmlLogger">XmlLogger</a></h3>
+<p>Writes all build information out to an XML file named log.xml, or the value
+of the <code>XmlLogger.file</code> property if present, when used as a
+listener. When used as a logger, it writes all output to either the
+console or to the value of <code>-logfile</code>. Whether used as a listener
+or logger, the output is not generated until the build is complete, as it
+buffers the information in order to provide timing information for task,
+targets, and the project.</p>
+<p>By default the XML file creates a reference to an XSLT file "log.xsl" in the current directory;
+look in ANT_HOME/etc for one of these. You can set the property
+<code>ant.XmlLogger.stylesheet.uri</code> to provide a uri to a style sheet.
+this can be a relative or absolute file path, or an http URL.
+If you set the property to the empty string, "", no XSLT transform
+is declared at all.</p>
+
+<blockquote>
+<p><code>ant -listener org.apache.tools.ant.XmlLogger</code><br>
+<code>ant -logger org.apache.tools.ant.XmlLogger -verbose -logfile build_log.xml</code></p>
+</blockquote>
+
+
+
+
+<h3><a name="TimestampedLogger">TimestampedLogger</a></h3>
+<p>
+ Acts like the default logger, except that the final success/failure message also includes
+ the time that the build completed. For example:
+</p>
+<pre>
+ BUILD SUCCESSFUL - at 16/08/05 16:24
+</pre>
+<p>To use this listener, use the command:</p>
+
+<blockquote>
+<code>ant -logger org.apache.tools.ant.listener.TimestampedLogger</code>
+</blockquote>
+
+
+
+<h3><a name="BigProjectLogger">BigProjectLogger</a></h3>
+<p>
+ This logger is designed to make examining the logs of a big build easier,
+ especially those run under continuous integration tools. It
+</p>
+<ol>
+ <li>When entering a child project, prints its name and directory</li>
+ <li>When exiting a child project, prints its name</li>
+ <li>Includes the name of the project when printing a target</li>
+ <li>Omits logging the names of all targets that have no direct task output</li>
+ <li>Includes the build finished timestamp of the TimeStamp logger</li>
+</ol>
+<p>
+ This is useful when using &lt;subant&gt; to build a large project
+ from many smaller projects -the output shows which particular
+ project is building. Here is an example in which "clean" is being called
+ on all a number of child projects, only some of which perform work:
+</p>
+<pre>
+
+======================================================================
+Entering project "xunit"
+In /home/ant/components/xunit
+======================================================================
+
+xunit.clean:
+ [delete] Deleting directory /home/ant/components/xunit/build
+ [delete] Deleting directory /home/ant/components/xunit/dist
+
+======================================================================
+Exiting project "xunit"
+======================================================================
+
+======================================================================
+Entering project "junit"
+In /home/ant/components/junit
+======================================================================
+
+======================================================================
+Exiting project "junit"
+======================================================================
+</pre>
+
+<p>
+ The entry and exit messages are very verbose in this example, but in
+ a big project compiling or testing many child components, the messages
+ are reduced to becoming clear delimiters of where different projects
+ are in charge -or more importantly, which project is failing.
+</p>
+<p>To use this listener, use the command:</p>
+<blockquote>
+<code>ant -logger org.apache.tools.ant.listener.BigProjectLogger</code>
+</blockquote>
+
+<h3><a name="SimpleBigProjectLogger">SimpleBigProjectLogger</a></h3>
+<p>Like <code>BigProjectLogger</code>, project-qualified target names are printed,
+useful for big builds with subprojects.
+Otherwise it is as quiet as <code>NoBannerLogger</code>:</p>
+<pre>
+Buildfile: /sources/myapp/build.xml
+
+myapp-lib.compile:
+Created dir: /sources/myapp/lib/build/classes
+Compiling 1 source file to /sources/myapp/lib/build/classes
+
+myapp-lib.jar:
+Building jar: /sources/myapp/lib/build/lib.jar
+
+myapp.compile:
+Created dir: /sources/myapp/build/classes
+Compiling 2 source files to /sources/myapp/build/classes
+
+myapp.jar:
+Building jar: /sources/myapp/build/myapp.jar
+
+BUILD SUCCESSFUL
+Total time: 1 second
+</pre>
+<p><b>since Ant 1.8.1</b></p>
+<p>To use this listener, use the command:</p>
+<blockquote>
+<code>ant -logger org.apache.tools.ant.listener.SimpleBigProjectLogger</code>
+</blockquote>
+
+<h3><a name="ProfileLogger">ProfileLogger</a></h3>
+<p>This logger stores the time needed for executing a task, target and the whole build and prints
+these information. The output contains a timestamp when entering the build, target or task and a timestamp and the needed time when exiting.
+</p>
+<!-- This is the 'since' as described in the Loggers JavaDoc -->
+<p><b>since Ant 1.8.0</b></p>
+<h4>Example</h4>
+Having that buildfile
+<pre>
+&lt;project&gt;
+ &lt;target name=&quot;aTarget&quot;&gt;
+ &lt;echo&gt;echo-task&lt;/echo&gt;
+ &lt;zip destfile=&quot;my.zip&quot;&gt;
+ &lt;fileset dir=&quot;${ant.home}&quot;/&gt;
+ &lt;/zip&gt;
+ &lt;/target&gt;
+ &lt;target name=&quot;anotherTarget&quot; depends=&quot;aTarget&quot;&gt;
+ &lt;echo&gt;another-echo-task&lt;/echo&gt;
+ &lt;/target&gt;
+&lt;/project&gt;
+</pre>
+and executing with <tt>ant -logger org.apache.tools.ant.listener.ProfileLogger anotherTarget</tt> gives that output (with other timestamps and duration of course ;) :
+<pre>
+Buildfile: ...\build.xml
+
+Target aTarget: started Thu Jan 22 09:01:00 CET 2009
+
+echo: started Thu Jan 22 09:01:00 CET 2009
+ [echo] echo-task
+
+echo: finished Thu Jan 22 09:01:00 CET 2009 (250ms)
+
+zip: started Thu Jan 22 09:01:00 CET 2009
+ [zip] Building zip: ...\my.zip
+
+zip: finished Thu Jan 22 09:01:01 CET 2009 (1313ms)
+
+Target aTarget: finished Thu Jan 22 09:01:01 CET 2009 (1719ms)
+
+Target anotherTarget: started Thu Jan 22 09:01:01 CET 2009
+
+echo: started Thu Jan 22 09:01:01 CET 2009
+ [echo] another-echo-task
+
+echo: finished Thu Jan 22 09:01:01 CET 2009 (0ms)
+
+Target anotherTarget: finished Thu Jan 22 09:01:01 CET 2009 (0ms)
+
+BUILD SUCCESSFUL
+Total time: 2 seconds
+</pre>
+
+
+
+<h2><a name="dev">Writing your own</a></h2>
+
+<p>See the <a href="develop.html#buildevents">Build Events</a> section for
+developers.</p>
+
+<p>Notes:</p>
+
+<ul>
+ <li>
+ A listener or logger should not write to standard output or error in the <code>messageLogged() method</code>;
+ Ant captures these internally and it will trigger an infinite loop.
+ </li>
+ <li>
+ Logging is synchronous; all listeners and loggers are called one after the other, with the build blocking until
+ the output is processed. Slow logging means a slow build.
+ </li>
+ <li>When a build is started, and <code>BuildListener.buildStarted(BuildEvent event)</code> is called,
+ the project is not fully functional. The build has started, yes, and the event.getProject() method call
+ returns the Project instance, but that project is initialized with JVM and ant properties, nor has it
+ parsed the build file yet. You cannot call <code>Project.getProperty()</code> for property lookup, or
+ <code>Project.getName()</code> to get the project name (it will return null).
+ </li>
+ <li>
+ Classes that implement <code>org.apache.tools.ant.SubBuildListener</code> receive notifications when child projects
+ start and stop.
+ </li>
+</ul>
+
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/platform.html b/framework/src/ant/apache-ant-1.9.6/manual/platform.html
new file mode 100644
index 00000000..8b38731a
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/platform.html
@@ -0,0 +1,178 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="stylesheets/style.css">
+<title>Platform Issues</title>
+</head>
+
+<h1>Platform Issues</h1>
+
+<h2>Java versions</h2>
+<h3>Java 1.5</h3>
+
+You may need a bigger stack than default, especially if you are using the built in
+XSLT engine. We recommend you use Apache Xalan; indeed, some tasks (JUnit report in XML,
+for example) may not work against the shipping XSL engine.
+
+<h2>Unix and Linux</h2>
+
+<ul>
+<li> You should use a GNU version of <tt>tar</tt> to untar the Apache
+Ant source tree, if you have downloaded this as a tar file. If you get
+weird errors about missing files, this is the problem.
+</li>
+<li> Ant does not preserve file permissions when a file is copied, moved or
+archived, because Java does not let it read or write the permissions.
+ Use <tt>&lt;chmod&gt;</tt> to set permissions, and when creating a
+tar archive, use the <tt>mode</tt> attribute of <tt>&lt;tarfileset&gt;</tt>
+to set the permissions in the tar file, or <code>&lt;apply&gt;</code> the real tar program.
+</li>
+<li> Ant is not symbolic link aware in moves, deletes and when recursing down a tree
+of directories to build up a list of files. Unexpected things can happen.
+</li>
+<li> Linux on IA-64: apparently you need a larger heap than the default
+one (64M) to compile big projects. If you get out of heap
+errors, either increase the heap or use a forking javac. Better yet,
+use jikes for extra compilation speed.
+</li>
+
+</ul>
+
+
+<h2>Microsoft Windows</h2>
+<p>
+Windows 9x (win95, win98, win98SE and winME) are not supported in Ant1.7,
+</p>
+
+<p>
+The Ant team has retired support for these products because they are outdated and
+can expose customers to security risks. We recommend that customers who are
+still running Windows 98 or Windows Me upgrade to a newer, more secure
+operating system, as soon as possible.
+</p>
+<p>
+Customers who upgrade to Linux report improved security, richer
+functionality, and increased productivity.
+</p>
+<h2>Microsoft Windows 2K, XP and Server 2K03 </h2>
+
+<p>
+Windows 9x (win95, win98, win98SE and winME) has a batch file system which
+does not work fully with long file names, so we recommend that ant and the JDK
+are installed into directories without spaces, and with 8.3 filenames.
+The Perl and Python launcher scripts do not suffer from this limitation.
+</p>
+<p>
+All versions of windows are usually case insensitive, although mounted
+file systems (Unix drives, Clearcase views) can be case sensitive underneath,
+confusing patternsets.
+</p>
+<p>
+Ant can often not delete a directory which is open in an Explorer window.
+There is nothing we can do about this short of spawning a program to kill
+the shell before deleting directories.
+Nor can files that are in use be overwritten.
+</p>
+<p>
+ Finally, if any Ant task fails with an IOError=2, it means that whatever
+ native program Ant is trying to run, it is not on the path.
+</p>
+
+<h2>Microsoft Windows Vista</h2>
+<p>
+ There are reports of problems with Windows Vista security bringing up
+ dialog boxes asking if the user wants to run an untrusted executable
+ during an ant run, such as when the &lt;signjar&gt task runs the jarsigner.exe
+ program. This is beyond Ant's control, and stems from the OS trying to provide
+ some illusion of security by being reluctant to run unsigned native executables.
+ The latest Java versions appear to resolve this problem by having signed
+ binaries.
+</p>
+
+
+<h2>Cygwin</h2>
+
+Cygwin is not an operating system; rather it is an application suite
+running under Windows and providing some UNIX like functionality. Sun has
+not created any specific Java Development Kit or Java Runtime Environment for
+cygwin. See this link :
+<a href="http://www.inonit.com/cygwin/faq/">http://www.inonit.com/cygwin/faq/</a> .
+Only Windows path
+names are supported by JDK and JRE tools under Windows or cygwin. Relative path
+names such as "src/org/apache/tools" are supported, but Java tools do not
+understand /cygdrive/c to mean c:\.
+<p>
+The utility cygpath (used industrially in the ant script to support cygwin) can
+convert cygwin path names to Windows.
+You can use the <code>&lt;exec&gt;</code> task in ant to convert cygwin paths to Windows path, for
+instance like that :
+<pre>
+&lt;property name=&quot;some.cygwin.path&quot; value=&quot;/cygdrive/h/somepath&quot;/&gt;
+&lt;exec executable=&quot;cygpath&quot; outputproperty=&quot;windows.pathname&quot;&gt;
+ &lt;arg value=&quot;--windows&quot;/&gt;
+ &lt;arg value=&quot;${some.cygwin.path}&quot;/&gt;
+&lt;/exec&gt;
+&lt;echo message=&quot;${windows.pathname}&quot;/&gt;
+</pre>
+
+We get lots of support calls from Cygwin users. Either it is incredibly
+popular, or it is trouble. If you do use it, remember that Java is a
+Windows application, so Ant is running in a Windows process, not a
+Cygwin one. This will save us having to mark your bug reports as invalid.
+
+<h2>Apple MacOS X</h2>
+
+MacOS X is the first of the Apple platforms that Ant supports completely;
+it is treated like any other Unix.
+
+<h2>Novell Netware</h2>
+
+<p>To give the same level of sophisticated control as Ant's startup scripts on other platforms, it was decided to make the main ant startup on NetWare be via a Perl Script, "runant.pl". This is found in the bin directory (for instance - bootstrap\bin or dist\bin).</p>
+
+<p>One important item of note is that you need to set up the following to run ant:</p>
+<ul><li><code>CLASSPATH</code> - put ant.jar and any other needed jars on the system classpath.</li>
+ <li><code>ANT_OPTS</code> - On NetWare, <code>ANT_OPTS</code> needs to include a parameter of the form, <nobr>"-envCWD=<code>ANT_HOME</code>"</nobr>, with <code>ANT_HOME</code> being the fully expanded location of Ant, <b>not</b> an environment variable. This is due to the fact that the NetWare System Console has no notion of a current working directory.</li>
+</ul>
+<p>It is suggested that you create up an ant.ncf that sets up these parameters, and calls <code>perl ANT_HOME/dist/bin/runant.pl</code></p>
+<p>The following is an example of such an NCF file(assuming ant is installed in <nobr>'sys:/apache-ant/'):</nobr></p>
+<code>
+ &nbsp;&nbsp;&nbsp;envset CLASSPATH=SYS:/apache-ant/bootstrap/lib/ant.jar<br>
+ &nbsp;&nbsp;&nbsp;envset CLASSPATH=$CLASSPATH;SYS:/apache-ant/lib/optional/junit.jar <br>
+ &nbsp;&nbsp;&nbsp;envset CLASSPATH=$CLASSPATH;SYS:/apache-ant/bootstrap/lib/optional.jar <br>
+<br>
+ &nbsp;&nbsp;&nbsp;setenv ANT_OPTS=-envCWD=sys:/apache-ant <br>
+ &nbsp;&nbsp;&nbsp;envset ANT_OPTS=-envCWD=sys:/apache-ant <br>
+ &nbsp;&nbsp;&nbsp;setenv ANT_HOME=sys:/apache-ant/dist/lib <br>
+ &nbsp;&nbsp;&nbsp;envset ANT_HOME=sys:/apache-ant/dist/lib <br>
+<br>
+ &nbsp;&nbsp;&nbsp;perl sys:/apache-ant/dist/bin/runant.pl <br>
+</code>
+
+<p>Ant works on JVM version 1.3 or higher. You may have some luck running it on JVM 1.2, but serious problems have been found running Ant on JVM 1.1.7B. These problems are caused by JVM bugs that will not be fixed.</p>
+<p>JVM 1.3 is supported on Novell NetWare versions 5.1 and higher.</p>
+
+
+<h2>Other platforms</h2>
+Support for other platforms is not guaranteed to be complete, as certain
+techniques to hide platform details from build files need to be written and
+tested on every particular platform. Contributions in this area are welcome.
+
+
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/projecthelper.html b/framework/src/ant/apache-ant-1.9.6/manual/projecthelper.html
new file mode 100644
index 00000000..fa07aea4
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/projecthelper.html
@@ -0,0 +1,150 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="stylesheets/style.css">
+<title>The Apache Ant frontend: ProjectHelper</title>
+</head>
+
+<body>
+<h1>The Apache Ant frontend: ProjectHelper</h1>
+
+<h2><a name="definition">What is a ProjectHelper?</a></h2>
+
+<p>
+The <code>ProjectHelper</code> in Apache Ant is responsible for parsing the build file
+and creating java instances representing the build workflow. It also signals which
+kind of file it can parse, and which file name it expects as default input file.
+</p>
+
+<p>
+Ant' default <code>ProjectHelper</code>
+(<code>org.apache.tools.ant.helper.ProjectHelper2</code>) parses the
+usual build.xml files. And if no build file is specified on the command line, it
+will expect to find a file named <code>build.xml</code>.
+</p>
+
+<p>
+The immediate benefit of a such abstraction it that it is possible to make Ant
+understand other kind of descriptive languages than XML. Some experiments have
+been done around a pure java frontend, and a groovy one too (ask the dev mailing
+list for further info about these).
+</p>
+
+<p>Since Ant 1.8.2, the <a href="Tasks/import.html">import</a> task will also
+try to use the proper helper to parse the imported file. So it is possible to
+write different build files in different languages and have them import each
+other.
+</p>
+
+<h2><a name="repository">How is Ant is selecting the proper ProjectHelper</a></h2>
+
+<p>
+Ant knows about several implementations of <code>ProjectHelper</code>
+and has to decide which to use for each build file.
+</p>
+
+<p>At startup Ant lists the all implementations found and keeps them
+in the same order they've been found in an internal 'repository':
+<ul>
+ <li>the first to be searched for is the one declared by the system property
+ <code>org.apache.tools.ant.ProjectHelper</code> (see
+ <a href="running.html#sysprops">Java System Properties</a>);</li>
+ <li>then it searches with its class loader for a <code>ProjectHelper</code>
+ service declarations in the META-INF: it searches in the classpath for a
+ file <code>META-INF/services/org.apache.tools.ant.ProjectHelper</code>.
+ This file will just contain the fully qualified name of the
+ implementation of <code>ProjectHelper</code> to instanciate;</li>
+ <li>it will also search with the system class loader for
+ <code>ProjectHelper</code> service declarations in the META-INF;</li>
+ <li>last but not least it will add its default <code>ProjectHelper</code>
+ that can parse classical build.xml files.</li>
+</ul>
+In case of an error while trying to instanciate a <code>ProjectHelper</code>, Ant
+will log an error but won't stop. If you want further debugging
+info about the <code>ProjectHelper</code> internal 'repository', use the <b>system</b>
+property <code>ant.project-helper-repo.debug</code> and set it to
+<code>true</code>; the full stack trace will then also be printed.
+</p>
+
+<p>
+When Ant is expected to parse a file, it will ask the
+<code>ProjectHelper</code> repository to find an implementation that will be
+able to parse the input file. Actually it will just iterate over the ordered list
+and the first implementation that returns <code>true</code> to
+<code>supportsBuildFile(File buildFile)</code> will be selected.
+</p>
+
+<p>
+When Ant is started and no input file has been specified, it will search for
+a default input file. It will iterate over list of <code>ProjectHelper</code>s
+and will select the first one that expects a default file that actually exist.
+</p>
+
+<h2><a name="writing">Writing your own ProjectHelper</a></h2>
+
+<p>
+The class <code>org.apache.tools.ant.ProjectHelper</code> is the API expected to
+be implemented. So write your own <code>ProjectHelper</code> by extending that
+abstract class. You are then expected to implement at least the function
+<code>parse(Project project, Object source)</code>. Note also that your
+implementation will be instanciated by Ant, and it is expecting a default
+constructor with no arguments.
+</p>
+
+<p>
+There are some functions that will help you define what your helper is
+capable of and what is is expecting:
+<ul>
+ <li><code>getDefaultBuildFile()</code>: defines which file name is expected if
+ none provided</li>
+ <li><code>supportsBuildFile(File buildFile)</code>: defines if your parser
+ can parse the input file</li>
+
+ <li><code>canParseAntlibDescriptor(URL url)</code>: whether your
+ implementation is capable of parsing a given Antlib
+ descriptor. The base class returns <code>false</code></li>
+ <li><code>parseAntlibDescriptor(Project containingProject, URL
+ source)</code>: invoked to actually parse the Antlib
+ descriptor if your implementation returned <code>true</code>
+ for the previous method.</li>
+</ul>
+</p>
+
+<p>
+Now that you have your implementation ready, you have to declare it to Ant. Three
+solutions here:
+<ul>
+ <li>use the system property <code>org.apache.tools.ant.ProjectHelper</code>
+ (see also the <a href="running.html#sysprops">Java System Properties</a>);</li>
+ <li>use the service file in META-INF: in the jar you will build with your
+ implementation, add a file
+ <code>META-INF/services/org.apache.tools.ant.ProjectHelper</code>.
+ And then in this file just put the fully qualified name of your
+ implementation</li>
+ <li>use the <a href="Tasks/projecthelper.html">projecthelper</a> task (since
+ Ant 1.8.2) which will install dynamically an helper in the internal helper
+ 'repository'. Then your helper can be used on the next call to the
+ <a href="Tasks/import.html">import</a> task.</li>
+</ul>
+</p>
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/properties.html b/framework/src/ant/apache-ant-1.9.6/manual/properties.html
new file mode 100644
index 00000000..e42d3a2a
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/properties.html
@@ -0,0 +1,399 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+ <meta http-equiv="Content-Language" content="en-us"/>
+ <link rel="stylesheet" type="text/css" href="stylesheets/style.css"/>
+ <title>Properties and PropertyHelpers</title>
+</head>
+
+<body>
+ <h1>Properties</h1>
+
+ <p>Properties are key-value-pairs where Apache Ant tries to
+ expand <code>${key}</code> to <code>value</code> at runtime.</p>
+
+ <p>There are many tasks that can set properties, the most common one
+ is the <a href="Tasks/property.html">property</a> task. In
+ addition properties can be defined
+ via <a href="running.html">command line arguments</a> or similar
+ mechanisms from outside of Ant.</p>
+
+ <p>Normally property values can not be changed, once a property is
+ set, most tasks will not allow its value to be modified. In
+ general properties are of global scope, i.e. once they have been
+ defined they are available for any task or target invoked
+ subsequently - it is not possible to set a property in a child
+ build process created via
+ the <a href="Tasks/ant.html">ant</a>, antcall or subant tasks
+ and make it available to the calling build process, though.</p>
+
+ <p>Starting with Ant 1.8.0
+ the <a href="Tasks/local.html">local</a> task can be used to
+ create properties that are locally scoped to a target or
+ a <a href="Tasks/sequential.html">sequential</a> element like
+ the one of the <a href="Tasks/macrodef.html">macrodef</a>
+ task.</p>
+
+ <h2><a name="built-in-props">Built-in Properties</a></h2>
+
+ <p>Ant provides access to all system properties as if they had been
+ defined using a <code>&lt;property&gt;</code> task. For
+ example, <code>${os.name}</code> expands to the name of the
+ operating system.</p>
+ <p>For a list of system properties see
+ <a href="http://docs.oracle.com/javase/7/docs/api/java/lang/System.html#getProperties%28%29">the Javadoc of System.getProperties</a>.
+ </p>
+
+ <p>In addition, Ant has some built-in properties:</p>
+<pre><!-- TODO use <dl><dt><code>...</code></dt><dd>...</dd></dl> instead -->
+basedir the absolute path of the project's basedir (as set
+ with the basedir attribute of <a href="using.html#projects">&lt;project&gt;</a>).
+ant.file the absolute path of the buildfile.
+ant.version the version of Ant
+ant.project.name the name of the project that is currently executing;
+ it is set in the name attribute of &lt;project&gt;.
+ant.project.default-target
+ the name of the currently executing project's
+ default target; it is set via the default
+ attribute of &lt;project&gt;.
+ant.project.invoked-targets
+ a comma separated list of the targets that have
+ been specified on the command line (the IDE,
+ an &lt;ant&gt; task ...) when invoking the current
+ project.
+ This property is set when the first target is executed.
+ So you can't use it in the implicit target (directly
+ under the &lt;project&gt; tag).
+ant.java.version the JVM version Ant detected; currently it can hold
+ the values &quot;1.7&quot;, &quot;1.6&quot;, &quot;1.5&quot;,
+ &quot;1.4&quot;, &quot;1.3&quot; and &quot;1.2&quot;.
+ant.core.lib the absolute path of the <code>ant.jar</code> file.
+</pre>
+
+ <p>There is also another property, but this is set by the launcher
+ script and therefore maybe not set inside IDEs:</p>
+<pre>
+ant.home home directory of Ant
+</pre>
+
+ <p>The following property is only set if Ant is started via the
+ Launcher class (which means it may not be set inside IDEs
+ either):</p>
+<pre>
+ant.library.dir the directory that has been used to load Ant's
+ jars from. In most cases this is ANT_HOME/lib.
+</pre>
+
+ <h1><a name="propertyHelper">PropertyHelpers</a></h1>
+
+ <p>Ant's property handling is accomplished by an instance of
+ <code>org.apache.tools.ant.PropertyHelper</code> associated with
+ the current Project. You can learn more about this class by
+ examining Ant's Java API. In Ant 1.8 the PropertyHelper class was
+ much reworked and now itself employs a number of helper classes
+ (actually instances of
+ the <code>org.apache.tools.ant.PropertyHelper$Delegate</code>
+ marker interface) to take care of discrete tasks such as property
+ setting, retrieval, parsing, etc. This makes Ant's property
+ handling highly extensible; also of interest is the
+ new <a href="Tasks/propertyhelper.html">propertyhelper</a>
+ task used to manipulate the PropertyHelper and its delegates from
+ the context of the Ant buildfile.
+
+ <p>There are three sub-interfaces of <code>Delegate</code> that may be
+ useful to implement.</p>
+
+ <ul>
+ <li><code>org.apache.tools.ant.property.PropertyExpander</code> is
+ responsible for finding the property name inside a string in the
+ first place (the default extracts <code>foo</code>
+ from <code>${foo}</code>).
+
+ <p>This is the interface you'd implement if you wanted to invent
+ your own property syntax - or allow nested property expansions
+ since the default implementation doesn't balance braces
+ (see <a href="https://git-wip-us.apache.org/repos/asf?p=ant-antlibs-props.git;a=blob;f=src/main/org/apache/ant/props/NestedPropertyExpander.java;hb=HEAD"><code>NestedPropertyExpander</code>
+ in the "props" Antlib</a> for an example).</p>
+ </li>
+
+ <li><code>org.apache.tools.ant.PropertyHelper$PropertyEvaluator</code>
+ is used to expand <code>${some-string}</code> into
+ an <code>Object</code>.
+
+ <p>This is the interface you'd implement if you want to provide
+ your own storage independent of Ant's project instance - the
+ interface represents the reading end. An example for this
+ would
+ be <code>org.apache.tools.ant.property.LocalProperties</code>
+ which implements storage
+ for <a href="Tasks/local.html">local properties</a>.</p>
+
+ <p>Another reason to implement this interface is if you wanted
+ to provide your own "property protocol" like
+ expanding <code>toString:foo</code> by looking up the project
+ reference foo and invoking <code>toString()</code> on it
+ (which is already implemented in Ant, see below).</p>
+ </li>
+
+ <li><code>org.apache.tools.ant.PropertyHelper$PropertySetter</code>
+ is responsible for setting properties.
+
+ <p>This is the interface you'd implement if you want to provide
+ your own storage independent of Ant's project instance - the
+ interface represents the reading end. An example for this
+ would
+ be <code>org.apache.tools.ant.property.LocalProperties</code>
+ which implements storage
+ for <a href="Tasks/local.html">local properties</a>.</p>
+ </li>
+
+ </ul>
+
+ <p>The default <code>PropertyExpander</code> looks similar to:</p>
+
+<pre>
+public class DefaultExpander implements PropertyExpander {
+ public String parsePropertyName(String s, ParsePosition pos,
+ ParseNextProperty notUsed) {
+ int index = pos.getIndex();
+ if (s.indexOf("${", index) == index) {
+ int end = s.indexOf('}', index);
+ if (end < 0) {
+ throw new BuildException("Syntax error in property: " + s);
+ }
+ int start = index + 2;
+ pos.setIndex(end + 1);
+ return s.substring(start, end);
+ }
+ return null;
+ }
+}
+</pre>
+
+ <p>The logic that replaces <code>${toString:some-id}</code> with the
+ stringified representation of the object with
+ id <code>some-id</code> inside the current build is contained in a
+ PropertyEvaluator similar to the following code:</p>
+
+<pre>
+public class ToStringEvaluator implements PropertyHelper.PropertyEvaluator {
+ private static final String prefix = "toString:";
+ public Object evaluate(String property, PropertyHelper propertyHelper) {
+ Object o = null;
+ if (property.startsWith(prefix) && propertyHelper.getProject() != null) {
+ o = propertyHelper.getProject().getReference(
+ property.substring(prefix.length()));
+ }
+ return o == null ? null : o.toString();
+ }
+}
+</pre>
+
+
+ <h1>Property Expansion</h1>
+
+ <p>When Ant encounters a construct <code>${some-text}</code> the
+ exact parsing semantics are subject to the configured property
+ helper delegates.</p>
+
+ <h2><code>$$</code> Expansion</h2>
+
+ <p>In its default configuration Ant will expand the
+ text <code>$$</code> to a single <code>$</code> and suppress the
+ normal property expansion mechanism for the text immediately
+ following it, i.e. <code>$${key}</code> expands
+ to <code>${key}</code> and not <code>value</code> even though a
+ property named <code>key</code> was defined and had the
+ value <code>value</code>. This can be used to escape
+ literal <code>$</code> characters and is useful in constructs that
+ only look like property expansions or when you want to provide
+ diagnostic output like in</p>
+
+<pre> &lt;echo&gt;$${builddir}=${builddir}&lt;/echo&gt;</pre>
+
+ <p>which will echo this message:</p>
+
+<pre> ${builddir}=build/classes</pre>
+
+ <p>if the property <code>builddir</code> has the
+ value <code>build/classes</code>.</p>
+
+ <p>In order to maintain backward compatibility with older Ant
+ releases, a single '$' character encountered apart from a
+ property-like construct (including a matched pair of french
+ braces) will be interpreted literally; that is, as '$'. The
+ "correct" way to specify this literal character, however, is by
+ using the escaping mechanism unconditionally, so that "$$" is
+ obtained by specifying "$$$$". Mixing the two approaches yields
+ unpredictable results, as "$$$" results in "$$".</p>
+
+ <h2>Nesting of Braces</h2>
+
+ <p>In its default configuration Ant will not try to balance braces
+ in property expansions, it will only consume the text up to the
+ first closing brace when creating a property name. I.e. when
+ expanding something like <code>${a${b}}</code> it will be
+ translated into two parts:</p>
+
+ <ol>
+ <li>the expansion of property <code>a${b</code> - likely nothing
+ useful.</li>
+ <li>the literal text <code>}</code> resulting from the second
+ closing brace</li>
+ </ol>
+
+ <p>This means you can't use easily expand properties whose names are
+ given by properties, but there
+ are <a href="http://ant.apache.org/faq.html#propertyvalue-as-name-for-property">some
+ workarounds</a> for older versions of Ant. With Ant 1.8.0 and the
+ <a href="http://ant.apache.org/antlib/props/">the props Antlib</a>
+ you can configure Ant to use
+ the <code>NestedPropertyExpander</code> defined there if you need
+ such a feature.</p>
+
+ <h2>Expanding a "Property Name"</h2>
+
+ <p>In its most simple form <code>${key}</code> is supposed to look
+ up a property named <code>key</code> and expand to the value of
+ the property. Additional <code>PropertyEvaluator</code>s may
+ result in a different interpretation of <code>key</code>,
+ though.</p>
+
+ <p>The <a href="http://ant.apache.org/antlibs/props/">props
+ Antlib</a> provides a few interesting evaluators but there are
+ also a few built-in ones.</p>
+
+ <h3><a name="toString">Getting the value of a Reference with
+ ${toString:}</a></h3>
+
+ <p>Any Ant type which has been declared with a reference can also
+ its string value extracted by using the <code>${toString:}</code>
+ operation, with the name of the reference listed after
+ the <code>toString:</code> text. The <code>toString()</code>
+ method of the Java class instance that is referenced is invoked
+ -all built in types strive to produce useful and relevant output
+ in such an instance.</p>
+
+ <p>For example, here is how to get a listing of the files in a fileset,<p>
+
+<pre>
+&lt;fileset id=&quot;sourcefiles&quot; dir=&quot;src&quot; includes=&quot;**/*.java&quot; /&gt;
+&lt;echo&gt; sourcefiles = ${toString:sourcefiles} &lt;/echo&gt;
+</pre>
+
+ <p>There is no guarantee that external types provide meaningful
+ information in such a situation</p>
+
+ <h3><a name="ant.refid">Getting the value of a Reference with
+ ${ant.refid:}</a></h3>
+
+ <p>Any Ant type which has been declared with a reference can also be
+ used as a property by using the <code>${ant.refid:}</code>
+ operation, with the name of the reference listed after
+ the <code>ant.refid:</code> text. The difference between this
+ operation and <a href="#toString"><code>${toString:}</code></a> is
+ that <code>${ant.refid:}</code> will expand to the referenced
+ object itself. In most circumstances the toString method will be
+ invoked anyway, for example if the <code>${ant.refid:}</code> is
+ surrounded by other text.</p>
+
+ <p>This syntax is most useful when using a task with attribute
+ setters that accept objects other than String. For example if the
+ setter accepts a Resource object as in</p>
+<pre>
+public void setAttr(Resource r) { ... }
+</pre>
+
+ <p>then the syntax can be used to pass in resource subclasses
+ previously defined as references like</p>
+<pre>
+ &lt;url url="http://ant.apache.org/" id="anturl"/&gt;
+ &lt;my:task attr="${ant.refid:anturl}"/&gt;
+</pre>
+
+ <h2><a name="if+unless">If/Unless Attributes</a></h2>
+ <p>
+ The <code>&lt;target></code> element and various tasks (such as
+ <code>&lt;fail></code>) and task elements (such as <code>&lt;test></code>
+ in <code>&lt;junit></code>) support <code>if</code> and <code>unless</code>
+ attributes which can be used to control whether the item is run or otherwise
+ takes effect.
+ </p>
+ <p>
+ In Ant 1.7.1 and earlier, these attributes could only be property names.
+ The item was enabled if a property with that name was defined - even to be
+ the empty string or <tt>false</tt> - and disabled if the property was not
+ defined. For example, the following works but there is no way to override
+ the file existence check negatively (only positively):
+ </p>
+ <pre>
+&lt;target name="-check-use-file">
+ &lt;available property="file.exists" file="some-file"/>
+&lt;/target>
+&lt;target name="use-file" depends="-check-use-file" <b>if="file.exists"</b>>
+ &lt;!-- do something requiring that file... -->
+&lt;/target>
+&lt;target name="lots-of-stuff" depends="use-file,other-unconditional-stuff"/>
+ </pre>
+ <p>
+ As of Ant 1.8.0, you may instead use property expansion; a value of
+ <tt>true</tt> (or <tt>on</tt> or <tt>yes</tt>) will enable the
+ item, while <tt>false</tt> (or <tt>off</tt> or <tt>no</tt>) will
+ disable it. Other values are still assumed to be property
+ names and so the item is enabled only if the named property is defined.
+ </p>
+ <p>
+ Compared to the older style, this gives you additional flexibility, because
+ you can override the condition from the command line or parent scripts:
+ </p>
+ <pre>
+&lt;target name="-check-use-file" <b>unless="file.exists"</b>>
+ &lt;available property="file.exists" file="some-file"/>
+&lt;/target>
+&lt;target name="use-file" depends="-check-use-file" <b>if="${file.exists}"</b>>
+ &lt;!-- do something requiring that file... -->
+&lt;/target>
+&lt;target name="lots-of-stuff" depends="use-file,other-unconditional-stuff"/>
+ </pre>
+ <p>
+ Now <code>ant -Dfile.exists=false lots-of-stuff</code> will run
+ <code>other-unconditional-stuff</code> but not <code>use-file</code>,
+ as you might expect, and you can disable the condition from another script
+ too:
+ </p>
+ <pre>
+&lt;antcall target="lots-of-stuff">
+ &lt;param name="file.exists" value="false"/>
+&lt;/antcall>
+ </pre>
+ <p>
+ Similarly, an <code>unless</code> attribute disables the item if it is
+ either the name of property which is defined, or if it evaluates to a
+ <tt>true</tt>-like value. For example, the following allows you to define
+ <tt>skip.printing.message=true</tt> in <tt>my-prefs.properties</tt> with
+ the results you might expect:
+ </p>
+ <pre>
+&lt;property file="my-prefs.properties"/>
+&lt;target name="print-message" <b>unless="${skip.printing.message}"</b>>
+ &lt;echo>hello!&lt;/echo>
+&lt;/target>
+ </pre>
+
+</body>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/proxy.html b/framework/src/ant/apache-ant-1.9.6/manual/proxy.html
new file mode 100644
index 00000000..13ef6e8e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/proxy.html
@@ -0,0 +1,292 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="stylesheets/style.css">
+<title>Proxy Configuration</title>
+</head>
+
+<body>
+<h2>Proxy Configuration</h2>
+
+<p>
+This page discussing proxy issues on command-line Apache Ant.
+Consult your IDE documentation for IDE-specific information upon proxy setup.
+</p>
+
+<p>
+
+All tasks and threads running in Ant's JVM share the same HTTP/FTP/Socks
+proxy configuration.
+</p>
+
+<p>
+ When any task tries to retrieve content from an HTTP page, including the
+ <code>&lt;get&gt;</code> task, any automated URL retrieval in
+ an XML/XSL task, or any third-party task that uses the <code>java.net.URL</code>
+ classes, the proxy settings may make the difference between success and failure.
+</p>
+<p>
+ Anyone authoring a build file behind a blocking firewall will immediately appreciate
+ the problems and may want to write a build file to deal with the problem, but
+ users of third party build build files may find that the build file itself
+ does not work behind the firewall.
+</p>
+<p>
+ This is a long standing problem with Java and Ant. The only way to fix
+ it is to explicitly configure Ant with the proxy settings, either
+ by passing down the proxy details as JVM properties, or to
+ tell Ant on a Java1.5+ system to have the JVM work it out for itself.
+
+</p>
+
+
+
+<h3>Java1.5+ proxy support (new for Ant1.7)</h3>
+<p>
+ When Ant starts up, if the <code>-autoproxy</code>
+ command is supplied, Ant sets the
+ <code>java.net.useSystemProxies</code> system property. This tells
+ a Java1.5+ JVM to use the current set of property settings of the host
+ environment. Other JVMs, such as the Kaffe and Apache Harmony runtimes,
+ may also use this property in future.
+ It is ignored on the Java1.4 and earlier runtimes.
+</p>
+<p>
+ This property maybe enough to give command-line Ant
+ builds network access, although in practise the results
+ are inconsistent.
+</p>
+<p>
+ It is has also been reported a breaking the IBM Java 5 JRE on AIX,
+ and does not always work on Linux (presumably due to missing gconf settings)
+ Other odd things can go wrong, like Oracle JDBC drivers or pure Java SVN clients.
+</p>
+
+<p>
+ To make the <code>-autoproxy</code> option the default, add it to the environment variable
+ <code>ANT_ARGS</code>, which contains a list of arguments to pass to Ant on every
+ command line run.
+</p>
+
+<h4>How Autoproxy works</h4>
+<p>
+The <code>java.net.useSystemProxies</code> is checked only
+once, at startup time, the other checks (registry, gconf, system properties) are done
+dynamically whenever needed (socket connection, URL connection etc..).
+</p>
+<h5>Windows</h5>
+
+<p>
+The JVM goes straight to the registry, bypassing WinInet, as it is not
+present/consistent on all supported Windows platforms (it is part of IE,
+really). Java 7 may use the Windows APIs on the platforms when it is present.
+</p>
+
+<h5>Linux</h5>
+
+<p>
+The JVM uses the gconf library to look at specific entries.
+The GConf-2 settings used are:
+</p>
+<pre>
+ - /system/http_proxy/use_http_proxy boolean
+ - /system/http_proxy/use_authentication boolean
+ - /system/http_proxy/host string
+ - /system/http_proxy/authentication_user string
+ - /system/http_proxy/authentication_password string
+ - /system/http_proxy/port int
+ - /system/proxy/socks_host string
+ - /system/proxy/mode string
+ - /system/proxy/ftp_host string
+ - /system/proxy/secure_host string
+ - /system/proxy/socks_port int
+ - /system/proxy/ftp_port int
+ - /system/proxy/secure_port int
+ - /system/proxy/no_proxy_for list
+ - /system/proxy/gopher_host string
+ - /system/proxy/gopher_port int
+</pre>
+<p>
+If you are using KDE or another GUI than Gnome, you can still use the
+<code>gconf-editor</code> tool to add these entries.
+</p>
+
+
+<h3>Manual JVM options</h3>
+<p>
+ Any JVM can have its proxy options explicitly configured by passing
+ the appropriate <code>-D</code> system property options to the runtime.
+ Ant can be configured through all its shell scripts via the
+ <code>ANT_OPTS</code> environment variable, which is a list of options to
+ supply to Ant's JVM:
+</p>
+<p>
+ For bash:
+</p>
+<pre>
+ export ANT_OPTS="-Dhttp.proxyHost=proxy -Dhttp.proxyPort=8080"
+</pre>
+ For csh/tcsh:
+<pre>
+ setenv ANT_OPTS "-Dhttp.proxyHost=proxy -Dhttp.proxyPort=8080"
+</pre>
+<p>
+If you insert this line into the Ant shell script itself, it gets picked up
+by all continuous integration tools running on the system that call Ant via the
+command line.
+</p>
+<p>
+ For Windows, set the <code>ANT_OPTS</code> environment variable in the appropriate "My Computer"
+ properties dialog box (winXP), "Computer" properties (Vista)
+</p>
+<p>
+ This mechanism works across Java versions, is cross-platform and reliable.
+ Once set, all build files run via the command line will automatically have
+ their proxy setup correctly, without needing any build file changes. It also
+ apparently overrides Ant's automatic proxy settings options.
+</p>
+<p>
+ It is limited in the following ways:
+</p>
+ <ol>
+ <li>Does not work under IDEs. These need their own proxy settings changed</li>
+ <li>Not dynamic enough to deal with laptop configuration changes.</li>
+ </ol>
+
+
+<h3>SetProxy Task</h3>
+<p>
+ The <a href="Tasks/setproxy.html">setproxy task</a> can be used to
+ explicitly set a proxy in a build file. This manipulates the many proxy
+ configuration properties of a JVM, and controls the proxy settings for all
+ network operations in the same JVM from that moment.
+</p>
+<p>
+ If you have a build file that is only to be used in-house, behind a firewall, on
+ an older JVM, <i>and you cannot change Ant's JVM proxy settings</i>, then
+ this is your best option. It is ugly and brittle, because the build file now contains
+ system configuration information. It is also hard to get this right across
+ the many possible proxy options of different users (none, HTTP, SOCKS).
+</p>
+
+
+<p>
+ Note that proxy configurations set with this task will probably override
+ any set by other mechanisms. It can also be used with fancy tricks to
+ only set a proxy if the proxy is considered reachable:
+</p>
+
+<pre>
+ &lt;target name="probe-proxy" depends="init"&gt;
+ &lt;condition property="proxy.enabled"&gt;
+ &lt;and&gt;
+ &lt;isset property="proxy.host"/&gt;
+ &lt;isreachable host="${proxy.host}"/&gt;
+ &lt;/and&gt;
+ &lt;/condition&gt;
+ &lt;/target&gt;
+
+ &lt;target name="proxy" depends="probe-proxy" if="proxy.enabled"&gt;
+ &lt;property name="proxy.port" value="80"/&gt;
+ &lt;property name="proxy.user" value=""/&gt;
+ &lt;property name="proxy.pass" value=""/&gt;
+ &lt;setproxy proxyhost="${proxy.host}" proxyport="${proxy.port}"
+ proxyuser="${proxy.user}" proxypassword="${proxy.pass}"/&gt;
+ &lt;/target&gt;
+</pre>
+
+<h3>Custom ProxySelector implementations</h3>
+<p>
+ As Java lets developers write their own ProxySelector implementations, it
+ is theoretically possible for someone to write their own proxy selector class that uses
+ different policies to determine proxy settings. There is no explicit support
+ for this in Ant, and it has not, to the team's knowledge, been attempted.
+</p>
+<p>
+ This could be the most flexible of solutions, as one could easily imagine
+ an Ant-specific proxy selector that was driven off ant properties, rather
+ than system properties. Developers could set proxy options in their
+ custom build.properties files, and have this propagate.
+</p>
+<p>
+ One issue here is with concurrency: the default proxy selector is per-JVM,
+ not per-thread, and so the proxy settings will apply to all sockets opened
+ on all threads; we also have the problem of how to propagate options from
+ one build to the JVM-wide selector.
+</p>
+
+<h3>Configuring the Proxy settings of Java programs under Ant</h3>
+
+<p>
+ Any program that is executed with <code>&lt;java&gt;</code> without setting
+ <code>fork="true"</code> will pick up the Ant's settings. If you need
+ different values, set <code>fork="false"</code> and provide the values
+ in <code>&lt;sysproperty&gt;</code> elements.
+</p>
+ If you wish to have
+ a forked process pick up the Ant's settings, use the
+ <a href="Types/propertyset.html"><code>&lt;syspropertyset&gt;</code></a>
+ element to propagate the normal proxy settings. The following propertyset
+ is a datatype which can be referenced in a <code>&lt;java&gt;</code> task to
+ pass down the current values.
+
+</p>
+<pre>
+&lt;propertyset id="proxy.properties">
+ &lt;propertyref prefix="java.net.useSystemProxies"/>
+ &lt;propertyref prefix="http."/>
+ &lt;propertyref prefix="https."/>
+ &lt;propertyref prefix="ftp."/>
+ &lt;propertyref prefix="socksProxy"/>
+&lt;/propertyset>
+</pre>
+
+<h3>Summary and conclusions</h3>
+<p>
+There are four ways to set up proxies in Ant.
+</p>
+<ol>
+<li>With Ant1.7 and Java 1.5+ using the <code>-autoproxy</code> parameter.</li>
+<li>Via JVM system properties -set these in the ANT_ARGS environment variable.</li>
+<li>Via the &lt;setproxy&gt; task.</li>
+<li>Custom ProxySelector implementations</li>
+</ol>
+<p>
+Proxy settings are automatically shared with Java programs started under Ant <i>
+that are not forked</i>; to pass proxy settings down to subsidiary programs, use
+a propertyset.
+</p>
+<p>
+Over time, we expect the Java 5+ proxy features to stabilize, and for Java code
+to adapt to them. However, given the fact that it currently does break some
+builds, it will be some time before Ant enables the automatic proxy feature by
+default. Until then, you have to enable the <code>-autoproxy</code> option or
+use one of the alternate mechanisms to configure the JVM.
+
+<h4>Further reading</h4>
+
+<ul>
+<li><a href="http://docs.oracle.com/javase/7/docs/technotes/guides/net/properties.html">
+Java Networking Properties</a>.
+</li>
+</ul>
+
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/running.html b/framework/src/ant/apache-ant-1.9.6/manual/running.html
new file mode 100644
index 00000000..529afc7d
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/running.html
@@ -0,0 +1,622 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="stylesheets/style.css">
+<title>Running Apache Ant</title>
+</head>
+
+<body>
+
+<h1>Running Apache Ant</h1>
+<h2><a name="commandline">Command Line</a></h2>
+<p> If you've installed Apache Ant as described in the
+<a href="install.html"> Installing Ant</a> section,
+running Ant from the command-line is simple: just type
+<code>ant</code>.</p>
+<p>When no arguments are specified, Ant looks for a <code>build.xml</code>
+file in the current directory and, if found, uses that file as the
+build file and runs the target specified in the <code>default</code>
+attribute of the <code>&lt;project&gt;</code> tag.
+To make Ant use
+a build file other than <code>build.xml</code>, use the command-line
+option <nobr><code>-buildfile <i>file</i></code></nobr>,
+where <i>file</i> is the name of the build file you want to use
+(or a directory containing a <code>build.xml</code> file).</p>
+If you use the <nobr><code>-find [<i>file</i>]</code></nobr> option,
+Ant will search for a build file first in the current directory, then in
+the parent directory, and so on, until either a build file is found or the root
+of the filesystem has been reached. By default, it will look for a build file
+called <code>build.xml</code>. To have it search for a build file other
+than <code>build.xml</code>, specify a file argument.
+<strong>Note:</strong> If you include any other flags or arguments
+on the command line after
+the <nobr><code>-find</code></nobr> flag, you must include the file argument
+for the <nobr><code>-find</code></nobr> flag, even if the name of the
+build file you want to find is <code>build.xml</code>.
+
+<p>You can also set <a href="using.html#properties">properties</a> on the
+command line. This can be done with
+the <nobr><code>-D<i>property</i>=<i>value</i></code></nobr> option,
+where <i>property</i> is the name of the property,
+and <i>value</i> is the value for that property. If you specify a
+property that is also set in the build file
+(see the <a href="Tasks/property.html">property</a> task),
+the value specified on the
+command line will override the value specified in the
+build file.
+Defining properties on the command line can also be used to pass in
+the value of environment variables; just pass
+<nobr><code>-DMYVAR=%MYVAR%</code></nobr> (Windows) or
+<nobr><code>-DMYVAR=$MYVAR</code></nobr> (Unix)
+to Ant. You can then access
+these variables inside your build file as <code>${MYVAR}</code>.
+You can also access environment variables using the
+<a href="Tasks/property.html"> property</a> task's
+<code>environment</code> attribute.
+</p>
+
+<p>Options that affect the amount of logging output by Ant are:
+<nobr><code>-quiet</code></nobr>,
+which instructs Ant to print less
+information to the console;
+<nobr><code>-verbose</code></nobr>, which causes Ant to print
+additional information to the console; <nobr><code>-debug</code></nobr>,
+which causes Ant to print considerably more additional information; and
+<nobr><code>-silent</code></nobr> which makes Ant print nothing but task
+output and build failures (useful to capture Ant output by scripts).
+</p>
+
+<p>It is also possible to specify one or more targets that should be executed.
+When omitted, the target that is specified in the
+<code>default</code> attribute of the
+<a href="using.html#projects"><code>project</code></a> tag is
+used.</p>
+
+<p>The <nobr><code>-projecthelp</code></nobr> option prints out a list
+of the build file's targets. Targets that include a
+<code>description</code> attribute are listed as &quot;Main targets&quot;,
+those without a <code>description</code> are listed as
+&quot;Other targets&quot;, then the &quot;Default&quot; target is listed
+("Other targets" are only displayed if there are no main
+targets, or if Ant is invoked in -verbose or -debug mode).
+
+<h3><a name="options">Command-line Options Summary</a></h3>
+<pre>ant [options] [target [target2 [target3] ...]]
+Options:
+ -help, -h print this message and exit
+ -projecthelp, -p print project help information and exit
+ -version print the version information and exit
+ -diagnostics print information that might be helpful to
+ diagnose or report problems and exit
+ -quiet, -q be extra quiet
+ -silent, -S print nothing but task outputs and build failures
+ -verbose, -v be extra verbose
+ -debug, -d print debugging information
+ -emacs, -e produce logging information without adornments
+ -lib &lt;path&gt; specifies a path to search for jars and classes
+ -logfile &lt;file&gt; use given file for log
+ -l &lt;file&gt; ''
+ -logger &lt;classname&gt; the class which is to perform logging
+ -listener &lt;classname&gt; add an instance of class as a project listener
+ -noinput do not allow interactive input
+ -buildfile &lt;file&gt; use given buildfile
+ -file &lt;file&gt; ''
+ -f &lt;file&gt; ''
+ -D&lt;property&gt;=&lt;value&gt; use value for given property
+ -keep-going, -k execute all targets that do not depend
+ on failed target(s)
+ -propertyfile &lt;name&gt; load all properties from file with -D
+ properties taking precedence
+ -inputhandler &lt;class&gt; the class which will handle input requests
+ -find &lt;file&gt; (s)earch for buildfile towards the root of
+ -s &lt;file&gt; the filesystem and use it
+ -nice number A niceness value for the main thread:
+ 1 (lowest) to 10 (highest); 5 is the default
+ -nouserlib Run ant without using the jar files from ${user.home}/.ant/lib
+ -noclasspath Run ant without using CLASSPATH
+ -autoproxy Java 1.5+ : use the OS proxies
+ -main &lt;class&gt; override Ant's normal entry point
+</pre>
+<p>For more information about <code>-logger</code> and
+<code>-listener</code> see
+<a href="listeners.html">Loggers &amp; Listeners</a>.
+<p>For more information about <code>-inputhandler</code> see
+<a href="inputhandler.html">InputHandler</a>.
+<p>Easiest way of changing the exit-behaviour is subclassing the original main class:
+<pre>
+public class CustomExitCode extends org.apache.tools.ant.Main {
+ protected void exit(int exitCode) {
+ // implement your own behaviour, e.g. NOT exiting the JVM
+ }
+}
+</pre> and starting Ant with access (<tt>-lib path-to-class</tt>) to this class.
+</p>
+
+<h3><a name="libs">Library Directories</a></h3>
+<p>
+Prior to Ant 1.6, all jars in the ANT_HOME/lib would be added to the CLASSPATH
+used to run Ant. This was done in the scripts that started Ant. From Ant 1.6,
+two directories are scanned by default and more can be added as required. The
+default directories scanned are ANT_HOME/lib and a user specific directory,
+${user.home}/.ant/lib. This arrangement allows the Ant installation to be
+shared by many users while still allowing each user to deploy additional jars.
+Such additional jars could be support jars for Ant's optional tasks or jars
+containing third-party tasks to be used in the build. It also allows the main Ant installation to be locked down which will please system administrators.
+</p>
+
+<p>
+Additional directories to be searched may be added by using the -lib option.
+The -lib option specifies a search path. Any jars or classes in the directories
+of the path will be added to Ant's classloader. The order in which jars are
+added to the classpath is as follows:
+</p>
+
+<ul>
+ <li>-lib jars in the order specified by the -lib elements on the command line</li>
+ <li>jars from ${user.home}/.ant/lib (unless -nouserlib is set)</li>
+ <li>jars from ANT_HOME/lib</li>
+</ul>
+
+<p>
+Note that the CLASSPATH environment variable is passed to Ant using a -lib
+option. Ant itself is started with a very minimalistic classpath.
+Ant should work perfectly well with an empty CLASSPATH environment variable,
+something the the -noclasspath option actually enforces. We get many more support calls related to classpath problems (especially quoting problems) than
+we like.
+
+</p>
+
+<p>
+The location of ${user.home}/.ant/lib is somewhat dependent on the JVM. On Unix
+systems ${user.home} maps to the user's home directory whilst on recent
+versions of Windows it will be somewhere such as
+C:\Documents&nbsp;and&nbsp;Settings\username\.ant\lib. You should consult your
+JVM documentation for more details.
+</p>
+
+<h3>Examples</h3>
+<blockquote>
+ <pre>ant</pre>
+</blockquote>
+<p>runs Ant using the <code>build.xml</code> file in the current directory, on
+the default target.</p>
+
+<blockquote>
+ <pre>ant -buildfile test.xml</pre>
+</blockquote>
+<p>runs Ant using the <code>test.xml</code> file in the current directory, on
+the default target.</p>
+
+<blockquote>
+ <pre>ant -buildfile test.xml dist</pre>
+</blockquote>
+<p>runs Ant using the <code>test.xml</code> file in the current directory, on
+the target called <code>dist</code>.</p>
+
+<blockquote>
+ <pre>ant -buildfile test.xml -Dbuild=build/classes dist</pre>
+</blockquote>
+<p>runs Ant using the <code>test.xml</code> file in the current directory, on
+the target called <code>dist</code>, setting the <code>build</code> property
+to the value <code>build/classes</code>.</p>
+
+<blockquote>
+ <pre>ant -lib /home/ant/extras</pre>
+</blockquote>
+<p>runs Ant picking up additional task and support jars from the
+/home/ant/extras location</p>
+
+<blockquote>
+ <pre>ant -lib one.jar;another.jar</pre>
+ <pre>ant -lib one.jar -lib another.jar</pre>
+</blockquote>
+<p>adds two jars to Ants classpath.</p>
+
+
+
+<h3><a name="files">Files</a></h3>
+
+<p>The Ant wrapper script for Unix will source (read and evaluate) the
+file <code>~/.antrc</code> before it does anything. On Windows, the Ant
+wrapper batch-file invokes <code>%HOME%\antrc_pre.bat</code> at the start and
+<code>%HOME%\antrc_post.bat</code> at the end. You can use these
+files, for example, to set/unset environment variables that should only be
+visible during the execution of Ant. See the next section for examples.</p>
+
+<h3><a name="envvars">Environment Variables</a></h3>
+
+<p>The wrapper scripts use the following environment variables (if
+set):</p>
+
+<ul>
+ <li><code>JAVACMD</code> - full path of the Java executable. Use this
+ to invoke a different JVM than <code>JAVA_HOME/bin/java(.exe)</code>.</li>
+
+ <li><code>ANT_OPTS</code> - command-line arguments that should be
+ passed to the JVM. For example, you can define system properties or set
+ the maximum Java heap size here.</li>
+
+ <li><code>ANT_ARGS</code> - Ant command-line arguments. For example,
+ set <code>ANT_ARGS</code> to point to a different logger, include a
+ listener, and to include the <code>-find</code> flag.</li>
+ <strong>Note:</strong> If you include <code>-find</code>
+ in <code>ANT_ARGS</code>, you should include the name of the build file
+ to find, even if the file is called <code>build.xml</code>.
+</ul>
+
+<h3><a name="sysprops">Java System Properties</a></h3>
+<p>Some of Ant's core classes can be configured via system properties.</p>
+<p>Here is the result of a search through the codebase. Because system properties are
+available via Project instance, I searched for them with a
+<pre>
+ grep -r -n "getPropert" * &gt; ..\grep.txt
+</pre>
+command. After that I filtered out the often-used but not-so-important values (most of them
+read-only values): <i>path.separator, ant.home, basedir, user.dir, os.name,
+line.separator, java.home, java.version, java.version, user.home, java.class.path</i><br>
+And I filtered out the <i>getPropertyHelper</i> access.</p>
+<table border="1">
+<tr>
+ <th>property name</th>
+ <th>valid values /default value</th>
+ <th>description</th>
+</tr>
+<tr>
+ <td><code>ant.build.javac.source</code></td>
+ <td>Source-level version number</td>
+ <td>Default <em>source</em> value for &lt;javac&gt;/&lt;javadoc&gt;</td>
+</tr>
+<tr>
+ <td><code>ant.build.javac.target</code></td>
+ <td>Class-compatibility version number</td>
+ <td>Default <em>target</em> value for &lt;javac&gt;</td>
+</tr>
+<tr>
+ <td><code>ant.executor.class</code></td>
+ <td>classname; default is org. apache. tools. ant. helper. DefaultExecutor</td>
+ <td><b>Since Ant 1.6.3</b> Ant will delegate Target invocation to the
+org.apache.tools.ant.Executor implementation specified here.
+ </td>
+</tr>
+
+<tr>
+ <td><code>ant.file</code></td>
+ <td>read only: full filename of the build file</td>
+ <td>This is set to the name of the build file. In
+ <a href="Tasks/import.html">
+ &lt;import&gt;-ed</a> files, this is set to the containing build file.
+ </td>
+</tr>
+
+<tr>
+ <td><code>ant.file.*</code></td>
+ <td>read only: full filename of the build file of Ant projects
+ </td>
+ <td>This is set to the name of a file by project;
+ this lets you determine the location of <a href="Tasks/import.html">
+ &lt;import&gt;-ed</a> files,
+ </td>
+</tr>
+
+<tr>
+ <td><code>ant.input.properties</code></td>
+ <td>filename (required)</td>
+ <td>Name of the file holding the values for the
+ <a href="inputhandler.html">PropertyFileInputHandler</a>.
+ </td>
+</tr>
+<tr>
+ <td><code>ant.logger.defaults</code></td>
+ <!-- add the blank after the slash, so the browser can do a line break -->
+ <td>filename (optional, default '/org/ apache/ tools/ ant/ listener/ defaults.properties')</td>
+ <td>Name of the file holding the color mappings for the
+ <a href="listeners.html#AnsiColorLogger">AnsiColorLogger</a>.
+ </td>
+</tr>
+<tr>
+ <td><code>ant.netrexxc.*</code></td>
+ <td>several formats</td>
+ <td>Use specified values as defaults for <a href="Tasks/netrexxc.html">netrexxc</a>.
+ </td>
+</tr>
+<tr>
+ <td><code>ant.PropertyHelper</code></td>
+ <td>ant-reference-name (optional)</td>
+ <td>Specify the PropertyHelper to use. The object must be of the type
+ org.apache.tools.ant.PropertyHelper. If not defined an object of
+ org.apache.tools.ant.PropertyHelper will be used as PropertyHelper.
+ </td>
+</tr>
+<tr>
+ <td><code>ant.regexp.regexpimpl</code></td>
+ <td>classname</td>
+ <td>classname for a RegExp implementation; if not set Ant uses JDK 1.4's implementation;
+ <a href="Types/mapper.html#regexp-mapper">RegExp-Mapper</a>
+ "Choice of regular expression implementation"
+ </td>
+</tr>
+<tr>
+ <td><code>ant.reuse.loader</code></td>
+ <td>boolean</td>
+ <td>allow to reuse classloaders
+ used in org.apache.tools.ant.util.ClasspathUtil
+ </td>
+</tr>
+<tr>
+ <td><code>ant.XmlLogger.stylesheet.uri</code></td>
+ <td>filename (default 'log.xsl')</td>
+ <td>Name for the stylesheet to include in the logfile by
+ <a href="listeners.html#XmlLogger">XmlLogger</a>.
+ </td>
+</tr>
+<tr>
+ <td><code>build.compiler</code></td>
+ <td>name</td>
+ <td>Specify the default compiler to use.
+ see <a href="Tasks/javac.html">javac</a>,
+ <a href="Tasks/ejb.html#ejbjar_weblogic">EJB Tasks</a>
+ (compiler attribute),
+ <a href="Tasks/javah.html">javah</a>
+ </td>
+</tr>
+<tr>
+ <td><code>build.compiler.emacs</code></td>
+ <td>boolean (default false)</td>
+ <td>Enable emacs-compatible error messages.
+ see <a href="Tasks/javac.html">javac</a> "Jikes Notes"
+ </td>
+</tr>
+<tr>
+ <td><code>build.compiler.fulldepend</code></td>
+ <td>boolean (default false)</td>
+ <td>Enable full dependency checking
+ see <a href="Tasks/javac.html">javac</a> "Jikes Notes"
+ </td>
+</tr>
+<tr>
+ <td><code>build.compiler.jvc.extensions</code></td>
+ <td>boolean (default true)</td>
+ <td>enable Microsoft extensions of their java compiler
+ see <a href="Tasks/javac.html">javac</a> "Jvc Notes"
+ </td>
+</tr>
+<tr>
+ <td><code>build.compiler.pedantic</code></td>
+ <td>boolean (default false)</td>
+ <td>Enable pedantic warnings.
+ see <a href="Tasks/javac.html">javac</a> "Jikes Notes"
+ </td>
+</tr>
+<tr>
+ <td><code>build.compiler.warnings</code></td>
+ <td>Deprecated flag</td>
+ <td> see <a href="Tasks/javac.html">javac</a> "Jikes Notes" </td>
+</tr>
+<tr>
+ <td><code>build.rmic</code></td>
+ <td>name</td>
+ <td>control the <a href="Tasks/rmic.html">rmic</a> compiler </td>
+</tr>
+<tr>
+ <td><code>build.sysclasspath</code></td>
+ <td>see <a href="sysclasspath.html">its dedicated page</a>, no
+ default value</td>
+ <td>see <a href="sysclasspath.html">its dedicated page</a></td>
+</tr>
+<tr>
+ <td><code>file.encoding</code></td>
+ <td>name of a supported character set (e.g. UTF-8, ISO-8859-1, US-ASCII)</td>
+ <td>use as default character set of email messages; use as default for source-, dest- and bundleencoding
+ in <a href="Tasks/translate.html">translate</a> <br>
+ see JavaDoc of <a target="_blank" href="http://docs.oracle.com/javase/7/docs/api/java/nio/charset/Charset.html">java.nio.charset.Charset</a>
+ for more information about character sets (not used in Ant, but has nice docs).
+ </td>
+</tr>
+<tr>
+ <td><code>jikes.class.path</code></td>
+ <td>path</td>
+ <td>The specified path is added to the classpath if jikes is used as compiler.</td>
+</tr>
+<tr>
+ <td><code>MailLogger.properties.file, MailLogger.*</code></td>
+ <td>filename (optional, defaults derived from Project instance)</td>
+ <td>Name of the file holding properties for sending emails by the
+ <a href="listeners.html#MailLogger">MailLogger</a>. Override properties set
+ inside the buildfile or via command line.
+ </td>
+</tr>
+<tr>
+ <td><code>org.apache.tools.ant.ProjectHelper</code></td>
+ <!-- add the blank after the slash, so the browser can do a line break -->
+ <td>classname (optional, default 'org.apache.tools.ant.ProjectHelper2')</td>
+ <td>specifies the classname to use as ProjectHelper. The class must extend
+ org.apache.tools.ant.ProjectHelper.
+ </td>
+</tr>
+<tr>
+ <td><code>org.apache.tools.ant.ArgumentProcessor</code></td>
+ <td>classname (optional)</td>
+ <td>specifies the classname to use as ArgumentProcessor. The class must extend
+ org.apache.tools.ant.ArgumentProcessor.
+ </td>
+</tr>
+
+<tr>
+ <td><code>websphere.home</code></td>
+ <td>path</td>
+ <td>Points to home directory of websphere.
+ see <a href="Tasks/ejb.html#ejbjar_websphere">EJB Tasks</a>
+ </td>
+</tr>
+<tr>
+ <td><code>XmlLogger.file</code></td>
+ <td>filename (default 'log.xml')</td>
+ <td>Name for the logfile for <a href="listeners.html#MailLogger">MailLogger</a>.
+ </td>
+</tr>
+<tr>
+ <td><code>ant.project-helper-repo.debug</code></td>
+ <td>boolean (default 'false')</td>
+ <td>Set it to true to enable debugging with Ant's
+ <a href="projecthelper.html#repository">ProjectHelper internal repository</a>.
+ </td>
+</tr>
+<tr>
+ <td><code>ant.argument-processor-repo.debug</code></td>
+ <td>boolean (default 'false')</td>
+ <td>Set it to true to enable debugging with Ant's
+ <a href="argumentprocessor.html#repository">ArgumentProcessor internal repository</a>.
+ </td>
+</tr>
+</table>
+
+<p>
+If new properties get added (it happens), expect them to appear under the
+"ant." and "org.apache.tools.ant" prefixes, unless the developers have a
+very good reason to use another prefix. Accordingly, please avoid using
+properties that begin with these prefixes. This protects you from future
+Ant releases breaking your build file.
+</p>
+<h3>return code</h3>
+<p>the ant start up scripts (in their Windows and Unix version) return
+the return code of the java program. So a successful build returns 0,
+failed builds return other values.
+</p>
+
+<h2><a name="cygwin">Cygwin Users</a></h2>
+<p>The Unix launch script that come with Ant works correctly with Cygwin. You
+should not have any problems launching Ant from the Cygwin shell. It is
+important to note, however, that once Ant is running it is part of the JDK
+which operates as a native Windows application. The JDK is not a Cygwin
+executable, and it therefore has no knowledge of Cygwin paths, etc. In
+particular when using the <code>&lt;exec&gt;</code> task, executable names such
+as &quot;/bin/sh&quot; will not work, even though these work from the Cygwin
+shell from which Ant was launched. You can use an executable name such as
+&quot;sh&quot; and rely on that command being available in the Windows path.
+</p>
+
+<h2><a name="os2">OS/2 Users</a></h2>
+<p>The OS/2 launch script was developed to perform complex tasks. It has two parts:
+<code>ant.cmd</code> which calls Ant and <code>antenv.cmd</code> which sets the environment for Ant.
+Most often you will just call <code>ant.cmd</code> using the same command line options as described
+above. The behaviour can be modified by a number of ways explained below.</p>
+
+<p>Script <code>ant.cmd</code> first verifies whether the Ant environment is set correctly. The
+requirements are:</p>
+<ol>
+<li>Environment variable <code>JAVA_HOME</code> is set.</li>
+<li>Environment variable <code>ANT_HOME</code> is set.</li>
+<li>Environment variable <code>CLASSPATH</code> is set and contains at least one element from
+<code>JAVA_HOME</code> and at least one element from <code>ANT_HOME</code>.</li>
+</ol>
+
+<p>If any of these conditions is violated, script <code>antenv.cmd</code> is called. This script
+first invokes configuration scripts if there exist: the system-wide configuration
+<code>antconf.cmd</code> from the <code>%ETC%</code> directory and then the user configuration
+<code>antrc.cmd</code> from the <code>%HOME%</code> directory. At this moment both
+<code>JAVA_HOME</code> and <code>ANT_HOME</code> must be defined because <code>antenv.cmd</code>
+now adds <code>classes.zip</code> or <code>tools.jar</code> (depending on version of JVM) and
+everything from <code>%ANT_HOME%\lib</code> except <code>ant-*.jar</code> to
+<code>CLASSPATH</code>. Finally <code>ant.cmd</code> calls per-directory configuration
+<code>antrc.cmd</code>. All settings made by <code>ant.cmd</code> are local and are undone when the
+script ends. The settings made by <code>antenv.cmd</code> are persistent during the lifetime of the
+shell (of course unless called automatically from <code>ant.cmd</code>). It is thus possible to call
+<code>antenv.cmd</code> manually and modify some settings before calling <code>ant.cmd</code>.</p>
+
+<p>Scripts <code>envset.cmd</code> and <code>runrc.cmd</code> perform auxiliary tasks. All scripts
+have some documentation inside.</p>
+
+<h2><a name="background">Running Ant as a background process on
+ Unix(-like) systems</a></h2>
+
+<p>If you start Ant as a background process (like in <code>ant
+ &amp;</code>) and the build process creates another process, Ant will
+ immediately try to read from standard input, which in turn will
+ most likely suspend the process. In order to avoid this, you must
+ redirect Ant's standard input or explicitly provide input to each
+ spawned process via the input related attributes of the
+ corresponding tasks.</p>
+
+<p>Tasks that create such new processes
+ include <code>&lt;exec&gt;</code>, <code>&lt;apply&gt;</code>
+ or <code>&lt;java&gt;</code> when the <code>fork</code> attribute is
+ <code>true</code>.</p>
+
+<h2><a name="viajava">Running Ant via Java</a></h2>
+<p>If you have installed Ant in the do-it-yourself way, Ant can be started
+from one of two entry points:</p>
+<blockquote>
+ <pre>java -Dant.home=c:\ant org.apache.tools.ant.Main [options] [target]</pre>
+</blockquote>
+
+<blockquote>
+ <pre>java -Dant.home=c:\ant org.apache.tools.ant.launch.Launcher [options] [target]</pre>
+</blockquote>
+
+<p>
+The first method runs Ant's traditional entry point. The second method uses
+the Ant Launcher introduced in Ant 1.6. The former method does not support
+the -lib option and all required classes are loaded from the CLASSPATH. You must
+ensure that all required jars are available. At a minimum the CLASSPATH should
+include:
+</p>
+
+<ul>
+<li><code>ant.jar</code> and <code>ant-launcher.jar</code></li>
+<li>jars/classes for your XML parser</li>
+<li>the JDK's required jar/zip files</li>
+</ul>
+
+<p>
+The latter method supports the -lib, -nouserlib, -noclasspath options and will
+ load jars from the specified ANT_HOME. You should start the latter with the most minimal
+classpath possible, generally just the ant-launcher.jar.
+</p>
+
+<a name="viaant"/>
+
+Ant can be started in Ant via the <code>&lt;java&gt;</code> command.
+Here is an example:
+
+<pre>
+&lt;java
+ classname="org.apache.tools.ant.launch.Launcher"
+ fork="true"
+ failonerror="true"
+ dir="${sub.builddir}"
+ timeout="4000000"
+ taskname="startAnt"&gt;
+ &lt;classpath&gt;
+ &lt;pathelement location="${ant.home}/lib/ant-launcher.jar"/&gt;
+ &lt;/classpath&gt;
+ &lt;arg value="-buildfile"/&gt;
+ &lt;arg file="${sub.buildfile}"/&gt;
+ &lt;arg value="-Dthis=this"/&gt;
+ &lt;arg value="-Dthat=that"/&gt;
+ &lt;arg value="-Dbasedir=${sub.builddir}"/&gt;
+ &lt;arg value="-Dthe.other=the.other"/&gt;
+ &lt;arg value="${sub.target}"/&gt;
+&lt;/java&gt;
+</pre>
+<br>
+
+
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/runninglist.html b/framework/src/ant/apache-ant-1.9.6/manual/runninglist.html
new file mode 100644
index 00000000..e2b8010f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/runninglist.html
@@ -0,0 +1,47 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us"/>
+<link rel="stylesheet" type="text/css" href="stylesheets/style.css"/>
+<title>Apache Ant User Manual</title>
+<base target="mainFrame"/>
+</head>
+
+<body>
+
+<h2><a href="toc.html" target="navFrame">Table of Contents</a></h2>
+
+<h3>Running Apache Ant</h3>
+<ul class="inlinelist">
+<li><a href="running.html#commandline">Command Line</a></li>
+<div style="padding-left:1em">
+ <li><a href="running.html#options">Options</a></li>
+ <li><a href="running.html#libs">Library Directories</a></li>
+ <li><a href="running.html#files">Files</a></li>
+ <li><a href="running.html#envvars">Environment Variables</a></li>
+ <li><a href="running.html#sysprops">Java System Properties</a></li>
+ <li><a href="running.html#cygwin">Cygwin Users</a></li>
+ <li><a href="running.html#os2">OS/2 Users</a></li>
+ <li><a href="running.html#background">Running "in the background"</a></li>
+</div>
+<li><a href="running.html#viajava">Running Ant via Java</a></li>
+</ul>
+
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/stylesheets/style.css b/framework/src/ant/apache-ant-1.9.6/manual/stylesheets/style.css
new file mode 100644
index 00000000..cf26c60c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/stylesheets/style.css
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+h2 {
+ font-size: 200%;
+ background-color: ffffff;
+}
+
+h3 {
+ font-size: 130%;
+ color: #ffffff;
+ background-color: #525D76;
+}
+
+h4 {
+ color: #ffffff;
+ background-color: #828DA6;
+}
+
+td {
+ background-color: eeeeee;
+ color: 000000;
+}
+
+/* first row */
+table tr:first-child td {
+ background-color: cccccc;
+ color: 000000;
+}
+
+/* or th as first row */
+table th {
+ background-color: cccccc;
+ color: 000000;
+}
+
+pre {
+ background-color: efefef;
+}
+
+/* code snippets in examples and tutorials */
+.code {
+ background: #EFEFEF;
+ margin-top:
+}
+
+/* highlight console output */
+.output {
+ color: #FFFFFF;
+ background: #837A67;
+}
+
+ul.inlinelist {
+ list-style-type: none;
+ margin-left: 0;
+ padding: 0;
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/sysclasspath.html b/framework/src/ant/apache-ant-1.9.6/manual/sysclasspath.html
new file mode 100644
index 00000000..5efb2086
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/sysclasspath.html
@@ -0,0 +1,79 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="stylesheets/style.css">
+<title>build.sysclasspath</title>
+</head>
+
+<body>
+
+<h2><a name="sysclasspath">build.sysclasspath</a></h2>
+<p>The value of the build.sysclasspath property
+controls how the system classpath, i.e. the classpath in effect when
+Apache Ant is run, affects the behavior of classpaths in Ant.
+The default behavior varies from task to task.</p>
+
+The values and their meanings are:
+
+<table cellspacing="20">
+<tr><th>value</th><th>meaning</th></tr>
+<tr>
+<td align="left" valign="top">only</td>
+<td>Only the system classpath is used and classpaths specified in build files,
+etc are ignored. This situation could be considered as the person running
+the build file knows more about the environment than the person writing the
+build file.
+</td>
+</tr>
+
+<tr>
+<td align="left" valign="top">ignore</td>
+<td>
+The system classpath is ignored. This situation is the reverse of the
+above. The person running the build trusts the build file writer to get the
+build file right. This mode is recommended for portable scripts.
+</td>
+</tr>
+
+<tr>
+<td align="left" valign="top">last</td>
+<td>
+The classpath is concatenated to any specified classpaths at the end. This
+is a compromise, where the build file writer has priority.
+</td>
+</tr>
+
+<tr>
+<td align="left" valign="top">first</td>
+<td>
+Any specified classpaths are concatenated to the system classpath. This is
+the other form of compromise where the build runner has priority.
+</td>
+</tr>
+</table>
+
+<p><em>Since Ant 1.7</em> the value of this property also affects the
+bootclasspath settings--it combines the bootclasspath that has been
+specified for a task with the bootclasspath of the Java VM running
+Ant. If the property has not been set, it defaults to "ignore" in
+this case.</p>
+
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/targets.html b/framework/src/ant/apache-ant-1.9.6/manual/targets.html
new file mode 100644
index 00000000..a778c950
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/targets.html
@@ -0,0 +1,300 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+ <meta http-equiv="Content-Language" content="en-us"/>
+ <link rel="stylesheet" type="text/css" href="stylesheets/style.css"/>
+ <title>Targets and Extension-Points</title>
+</head>
+
+<body>
+ <h1><a name="targets">Targets</a></h1>
+
+ <p>A target is a container of tasks that cooperate to reach a
+ desired state during the build process.</p>
+
+ <p>Targets can depend on other targets and Apache Ant ensures that these
+ other targets have been executed before the current target. For
+ example you might have a target for compiling and a
+ target for creating a distributable. You can only build a
+ distributable when you have compiled first, so the distribute
+ target <i>depends on</i> the compile target.</p>
+
+ <p>Ant tries to execute the targets in the <code>depends</code>
+ attribute in the order they appear (from left to right). Keep in
+ mind that it is possible that a target can get executed earlier
+ when an earlier target depends on it:</p>
+
+<blockquote>
+<pre>&lt;target name=&quot;A&quot;/&gt;
+&lt;target name=&quot;B&quot; depends=&quot;A&quot;/&gt;
+&lt;target name=&quot;C&quot; depends=&quot;B&quot;/&gt;
+&lt;target name=&quot;D&quot; depends=&quot;C,B,A&quot;/&gt;</pre>
+</blockquote>
+
+ <p>Suppose we want to execute target D. From its
+ <code>depends</code> attribute, you might think that first target
+ C, then B and then A is executed. Wrong! C depends on B, and B
+ depends on A, so first A is executed, then B, then C, and finally
+ D.</p>
+
+ <blockquote><pre><b>Call-Graph:</b> A --> B --> C --> D</pre></blockquote>
+
+ <p>In a chain of dependencies stretching back from a given target
+ such as D above, each target gets executed only once, even when
+ more than one target depends on it. Thus, executing the D target
+ will first result in C being called, which in turn will first call
+ B, which in turn will first call A. After A, then B, then C have
+ executed, execution returns to the dependency list of D, which
+ will <u>not</u> call B and A, since they were already called in
+ process of dependency resolution for C and B respectively as
+ dependencies of D. Had no such dependencies been discovered in
+ processing C and B, B and A would have been executed after C in
+ processing D's dependency list.</p>
+
+ <p>A target also has the ability to perform its execution if (or
+ unless) a property has been set. This allows, for example, better
+ control on the building process depending on the state of the
+ system (java version, OS, command-line property defines, etc.).
+ To make a target <i>sense</i> this property, you should add
+ the <code>if</code> (or <code>unless</code>) attribute with the
+ name of the property that the target should react
+ to. <strong>Note:</strong> In the most simple case Ant will only
+ check whether the property has been set, the value doesn't matter,
+ but using property expansions you can build more complex
+ conditions. See
+ <a href="properties.html#if+unless">the properties page</a> for
+ more details. For example:</p>
+
+<blockquote>
+ <pre>&lt;target name=&quot;build-module-A&quot; if=&quot;module-A-present&quot;/&gt;</pre>
+ <pre>&lt;target name=&quot;build-own-fake-module-A&quot; unless=&quot;module-A-present&quot;/&gt;</pre>
+</blockquote>
+
+ <p>In the first example, if the <code>module-A-present</code>
+ property is set (to any value, e.g. <i>false</i>), the target will
+ be run. In the second example, if
+ the <code>module-A-present</code> property is set (again, to any
+ value), the target will not be run.</p>
+
+ <p>Only one propertyname can be specified in the if/unless
+ clause. If you want to check multiple conditions, you can use a
+ dependent target for computing the result for the check:</p>
+
+<blockquote><pre>
+&lt;target name="myTarget" depends="myTarget.check" if="myTarget.run"&gt;
+ &lt;echo&gt;Files foo.txt and bar.txt are present.&lt;/echo&gt;
+&lt/target&gt;
+
+&lt;target name="myTarget.check"&gt;
+ &lt;condition property="myTarget.run"&gt;
+ &lt;and&gt;
+ &lt;available file="foo.txt"/&gt;
+ &lt;available file="bar.txt"/&gt;
+ &lt;/and&gt;
+ &lt;/condition&gt;
+&lt/target&gt;
+</pre></blockquote>
+
+ <blockquote><pre><b>Call-Graph:</b> myTarget.check --> maybe(myTarget)</pre></blockquote>
+
+ <p>If no <code>if</code> and no <code>unless</code> attribute is
+ present, the target will always be executed.</p>
+
+ <p><b>Important:</b> the <code>if</code> and <code>unless</code>
+ attributes only enable or disable the target to which they are
+ attached. They do not control whether or not targets that a
+ conditional target depends upon get executed. In fact, they do
+ not even get evaluated until the target is about to be executed,
+ and all its predecessors have already run.
+
+ <p>The optional <code>description</code> attribute can be used to
+ provide a one-line description of this target, which is printed by
+ the <code>-projecthelp</code> command-line option. Targets without
+ such a description are deemed internal and will not be listed,
+ unless either the <code>-verbose</code> or <code>-debug</code>
+ option is used.</p>
+
+ <p>It is a good practice to place
+ your <a href="Tasks/tstamp.html">tstamp</a> tasks in a
+ so-called <i>initialization</i> target, on which all other targets
+ depend. Make sure that target is always the first one in the
+ depends list of the other targets. In this manual, most
+ initialization targets have the name <code>&quot;init&quot;</code>.</p>
+ <blockquote><pre>
+ &lt;project&gt;
+ &lt;target name=&quot;init&quot;&gt;
+ &lt;tstamp/&gt;
+ &lt;/target&gt;
+ &lt;target name=&quot;otherTarget&quot; depends=&quot;init&quot;&gt;
+ ...
+ &lt;/target&gt;
+ &lt;/project&gt;
+ </pre></blockquote>
+
+ <p>Especially if you only have a few tasks you also could place these
+ tasks directly under the project tag (since Ant 1.6.0):</p>
+ <blockquote><pre>
+ &lt;project&gt;
+ &lt;tstamp/&gt;
+ &lt;/project&gt;
+ </pre></blockquote>
+
+ <p>If the depends attribute and the if/unless attribute are set, the
+ depends attribute is executed first.</p>
+
+ <p>A target has the following attributes:</p>
+
+ <table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">name</td>
+ <td valign="top">the name of the target.</td>
+ <td align="center" valign="top">Yes</td>
+ </tr>
+ <tr>
+ <td valign="top">depends</td>
+ <td valign="top">a comma-separated list of names of targets on
+ which this target depends.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">if</td>
+ <td valign="top">the name of the property that must be set in
+ order for this target to execute,
+ or <a href="properties.html#if+unless">something evaluating to
+ true</a>.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">unless</td>
+ <td valign="top">the name of the property that must not be set
+ in order for this target to execute,
+ or <a href="properties.html#if+unless">something evaluating to
+ false</a>.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">description</td>
+ <td valign="top">a short description of this target's function.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">extensionOf</td>
+ <td valign="top">Adds the current target to the depends list of
+ the named <a href="#extension-points">extension-point</a>.
+ <em>since Ant 1.8.0.</em></td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">onMissingExtensionPoint</td>
+ <td valign="top">What to do if this target tries to extend a
+ missing
+ <a href="#extension-points">extension-point</a>. ("fail",
+ "warn", "ignore").
+ <em>since Ant 1.8.2.</em></td>
+ <td align="center" valign="top">No. Not allowed unless
+ <code>extensionOf</code> is present. Defaults to <code>fail</code>.
+ </td>
+ </tr>
+ </table>
+
+ <p>A target name can be any alphanumeric string valid in the
+ encoding of the XML file. The empty string &quot;&quot; is in this
+ set, as is comma &quot;,&quot; and space &quot; &quot;. Please
+ avoid using these, as they will not be supported in future Ant
+ versions because of all the confusion they cause on command line and IDE. IDE support of
+ unusual target names, or any target name containing spaces, varies
+ with the IDE.</p>
+
+ <p>Targets beginning with a hyphen such
+ as <code>&quot;-restart&quot;</code> are valid, and can be used to
+ name targets that should not be called directly from the command
+ line. <br>
+ For Ants main class every option starting with hyphen is an
+ option for Ant itself and not a target. For that reason calling these
+ target from command line is not possible. On the other hand IDEs usually
+ don't use Ants main class as entry point and calling them from the IDE
+ is usually possible.</p>
+
+ <h1><a name="extension-points">Extension-Points</a></h1>
+
+ <p><em>since Ant 1.8.0.</em></p>
+
+ <p>Extension-Points are similar to targets in that they have a name and
+ a depends list and can be executed from the command line. Just
+ like targets they represent a state during the build process.</p>
+
+ <p>Unlike targets they don't contain any tasks, their main purpose
+ is to collect targets that contribute to the desired state in
+ their depends list.</p>
+
+ <p>Targets can add themselves to an extension-points's depends list via
+ their extensionOf attribute. The targets that add themselves will be
+ added after the targets of the explicit depends-attribute of the
+ extension-point, if multiple targets add themselves, their relative
+ order is not defined.</p>
+
+ <p>The main purpose of an extension-point is to act as an extension
+ point for build files designed to
+ be <a href="Tasks/import.html">imported</a>. In the imported
+ file an extension-point defines a state that must be reached and
+ targets from other build files can join the depends list of said
+ extension-point in order to contribute to that state.</p>
+
+ <p>For example your imported build file may need to compile code, it
+ might look like:</p>
+<blockquote><pre>
+&lt;target name="create-directory-layout"&gt;
+ ...
+&lt;/target&gt;
+&lt;extension-point name="ready-to-compile"
+ depends="create-directory-layout"/&gt;
+&lt;target name="compile" depends="ready-to-compile"&gt;
+ ...
+&lt;/target&gt;
+</pre></blockquote>
+
+ <blockquote><pre><b>Call-Graph:</b> create-directory-layout --> 'empty slot' --> compile</pre></blockquote>
+
+
+ <p>And you need to generate some source before compilation, then in
+ your main build file you may use something like</p>
+<blockquote><pre>
+&lt;target name="generate-sources"
+ extensionOf="ready-to-compile"&gt;
+ ...
+&lt;/target&gt;
+</pre></blockquote>
+
+ <blockquote><pre><b>Call-Graph:</b> create-directory-layout --> generate-sources --> compile</pre></blockquote>
+
+
+ <p>This will ensure that the <em>generate-sources</em> target is
+ executed before the <em>compile</em> target.</p>
+
+ <p>Don't rely on the order of the depends list,
+ if <em>generate-sources</em> depends
+ on <em>create-directory-layout</em> then it must explicitly depend
+ on it via its own depends attribute.</p>
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/tasklist.html b/framework/src/ant/apache-ant-1.9.6/manual/tasklist.html
new file mode 100644
index 00000000..6578e55b
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/tasklist.html
@@ -0,0 +1,195 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us"/>
+<link rel="stylesheet" type="text/css" href="stylesheets/style.css"/>
+<title>Apache Ant User Manual</title>
+<base target="mainFrame"/>
+</head>
+
+<body>
+
+<h2><a href="toc.html" target="navFrame">Table of Contents</a></h2>
+
+<ul class="inlinelist">
+<li><a href="tasksoverview.html" target="mainFrame">Overview of Apache Ant Tasks</a></li>
+<li><a href="conceptstypeslist.html" target="navFrame">Concepts and Types</a></li>
+</ul>
+
+<h3>Tasks</h3>
+<ul class="inlinelist">
+<li><a href="Tasks/ant.html">Ant</a></li>
+<li><a href="Tasks/antcall.html">AntCall</a></li>
+<li><a href="Tasks/antlr.html">ANTLR</a></li>
+<li><a href="Tasks/antstructure.html">AntStructure</a></li>
+<li><a href="Tasks/antversion.html">AntVersion</a></li>
+<li><a href="Tasks/apply.html">Apply/<i>ExecOn</i></a></li>
+<li><a href="Tasks/apt.html">Apt</a></li>
+<li><a href="Tasks/attrib.html">Attrib</a></li>
+<li><a href="Tasks/augment.html">Augment</a></li>
+<li><a href="Tasks/available.html">Available</a></li>
+<li><a href="Tasks/basename.html">Basename</a></li>
+<li><a href="Tasks/bindtargets.html">Bindtargets</a></li>
+<li><a href="Tasks/buildnumber.html">BuildNumber</a></li>
+<li><a href="Tasks/unpack.html">BUnzip2</a></li>
+<li><a href="Tasks/pack.html">BZip2</a></li>
+<li><a href="Tasks/cab.html">Cab</a></li>
+<li><a href="Tasks/ccm.html">Continuus/Synergy Tasks</a></li>
+<li><a href="Tasks/changelog.html">CvsChangeLog</a></li>
+<li><a href="Tasks/checksum.html">Checksum</a></li>
+<li><a href="Tasks/chgrp.html">Chgrp</a></li>
+<li><a href="Tasks/chmod.html">Chmod</a></li>
+<li><a href="Tasks/chown.html">Chown</a></li>
+<li><a href="Tasks/clearcase.html">Clearcase Tasks</a></li>
+<li><a href="Tasks/componentdef.html">Componentdef</a></li>
+<li><a href="Tasks/concat.html">Concat</a></li>
+<li><a href="Tasks/condition.html">Condition</a></li>
+<div style="padding-left:1em">
+ <li><a href="Tasks/conditions.html">Supported conditions</a></li>
+</div>
+<li><a href="Tasks/copy.html">Copy</a></li>
+<li><a href="Tasks/copydir.html"><i>Copydir</i></a></li>
+<li><a href="Tasks/copyfile.html"><i>Copyfile</i></a></li>
+<li><a href="Tasks/cvs.html">Cvs</a></li>
+<li><a href="Tasks/cvspass.html">CVSPass</a></li>
+<li><a href="Tasks/cvstagdiff.html">CvsTagDiff</a></li>
+<li><a href="Tasks/cvsversion.html">CvsVersion</a></li>
+<li><a href="Tasks/defaultexcludes.html">Defaultexcludes</a></li>
+<li><a href="Tasks/delete.html">Delete</a></li>
+<li><a href="Tasks/deltree.html"><i>Deltree</i></a></li>
+<li><a href="Tasks/depend.html">Depend</a></li>
+<li><a href="Tasks/dependset.html">Dependset</a></li>
+<li><a href="Tasks/diagnostics.html">Diagnostics</a></li>
+<li><a href="Tasks/dirname.html">Dirname</a></li>
+<li><a href="Tasks/ear.html">Ear</a></li>
+<li><a href="Tasks/echo.html">Echo</a></li>
+<li><a href="Tasks/echoproperties.html">Echoproperties</a></li>
+<li><a href="Tasks/echoxml.html">EchoXML</a></li>
+<li><a href="Tasks/ejb.html">EJB Tasks</a></li>
+<li><a href="Tasks/exec.html">Exec</a></li>
+<li><a href="Tasks/fail.html">Fail</a></li>
+<li><a href="Tasks/filter.html">Filter</a></li>
+<li><a href="Tasks/fixcrlf.html">FixCRLF</a></li>
+<li><a href="Tasks/ftp.html">FTP</a></li>
+<li><a href="Tasks/genkey.html">GenKey</a></li>
+<li><a href="Tasks/get.html">Get</a></li>
+<li><a href="Tasks/unpack.html">GUnzip</a></li>
+<li><a href="Tasks/pack.html">GZip</a></li>
+<li><a href="Tasks/hostinfo.html">Hostinfo</a></li>
+<li><a href="Tasks/image.html">Image</a></li>
+<li><a href="Tasks/import.html">Import</a></li>
+<li><a href="Tasks/include.html">Include</a></li>
+<li><a href="Tasks/input.html">Input</a></li>
+<li><a href="Tasks/jar.html">Jar</a></li>
+<li><a href="Tasks/jarlib-available.html">Jarlib-available</a></li>
+<li><a href="Tasks/jarlib-display.html">Jarlib-display</a></li>
+<li><a href="Tasks/jarlib-manifest.html">Jarlib-manifest</a></li>
+<li><a href="Tasks/jarlib-resolve.html">Jarlib-resolve</a></li>
+<li><a href="Tasks/java.html">Java</a></li>
+<li><a href="Tasks/javac.html">Javac</a></li>
+<li><a href="Tasks/javacc.html">JavaCC</a></li>
+<li><a href="Tasks/javadoc.html">Javadoc/<i>Javadoc2</i></a></li>
+<li><a href="Tasks/javah.html">Javah</a></li>
+<li><a href="Tasks/jdepend.html">JDepend</a></li>
+<li><a href="Tasks/jjdoc.html">JJDoc</a></li>
+<li><a href="Tasks/jjtree.html">JJTree</a></li>
+<li><a href="Tasks/jlink.html"><i>Jlink</i></a></li>
+<li><a href="Tasks/jspc.html">JspC</a></li>
+<li><a href="Tasks/junit.html">JUnit</a></li>
+<li><a href="Tasks/junitreport.html">JUnitReport</a></li>
+<li><a href="Tasks/length.html">Length</a><br/></li>
+<li><a href="Tasks/loadfile.html">LoadFile</a></li>
+<li><a href="Tasks/loadproperties.html">LoadProperties</a></li>
+<li><a href="Tasks/loadresource.html">LoadResource</a></li>
+<li><a href="Tasks/local.html">Local</a></li>
+<li><a href="Tasks/macrodef.html">MacroDef</a></li>
+<li><a href="Tasks/mail.html">Mail</a></li>
+<li><a href="Tasks/makeurl.html">MakeURL</a></li>
+<li><a href="Tasks/manifest.html">Manifest</a></li>
+<li><a href="Tasks/manifestclasspath.html">ManifestClassPath</a></li>
+<li><a href="Tasks/mimemail.html"><i>MimeMail</i></a></li>
+<li><a href="Tasks/mkdir.html">Mkdir</a></li>
+<li><a href="Tasks/move.html">Move</a></li>
+<li><a href="Tasks/native2ascii.html">Native2Ascii</a></li>
+<li><a href="Tasks/netrexxc.html">NetRexxC</a></li>
+<li><a href="Tasks/nice.html">Nice</a></li>
+<li><a href="Tasks/parallel.html">Parallel</a></li>
+<li><a href="Tasks/patch.html">Patch</a></li>
+<li><a href="Tasks/pathconvert.html">PathConvert</a></li>
+<li><a href="Tasks/presetdef.html">PreSetDef</a></li>
+<li><a href="Tasks/projecthelper.html">ProjectHelper</a></li>
+<li><a href="Tasks/property.html">Property</a></li>
+<li><a href="Tasks/propertyfile.html">PropertyFile</a></li>
+<li><a href="Tasks/propertyhelper.html">PropertyHelper</a></li>
+<li><a href="Tasks/pvcstask.html">Pvcs</a></li>
+<li><a href="Tasks/recorder.html">Record</a></li>
+<li><a href="Tasks/rename.html"><i>Rename</i></a></li>
+<li><a href="Tasks/renameextensions.html"><i>RenameExtensions</i></a></li>
+<li><a href="Tasks/replace.html">Replace</a></li>
+<li><a href="Tasks/replaceregexp.html">ReplaceRegExp</a></li>
+<li><a href="Tasks/resourcecount.html">ResourceCount</a></li>
+<li><a href="Tasks/retry.html">Retry</a></li>
+<li><a href="Tasks/rexec.html">RExec</a></li>
+<li><a href="Tasks/rmic.html">Rmic</a></li>
+<li><a href="Tasks/rpm.html">Rpm</a></li>
+<li><a href="Tasks/schemavalidate.html">SchemaValidate</a></li>
+<li><a href="Tasks/scp.html">Scp</a></li>
+<li><a href="Tasks/script.html">Script</a></li>
+<li><a href="Tasks/scriptdef.html">Scriptdef</a></li>
+<li><a href="Tasks/sequential.html">Sequential</a></li>
+<li><a href="Tasks/serverdeploy.html">ServerDeploy</a></li>
+<li><a href="Tasks/setproxy.html">Setproxy</a></li>
+<li><a href="Tasks/signjar.html">SignJar</a></li>
+<li><a href="Tasks/sleep.html">Sleep</a></li>
+<li><a href="Tasks/sos.html">SourceOffSite</a></li>
+<li><a href="Tasks/sound.html">Sound</a></li>
+<li><a href="Tasks/splash.html">Splash</a></li>
+<li><a href="Tasks/sql.html">Sql</a></li>
+<li><a href="Tasks/sshexec.html">Sshexec</a></li>
+<li><a href="Tasks/sshsession.html">Sshsession</a></li>
+<li><a href="Tasks/subant.html">Subant</a></li>
+<li><a href="Tasks/symlink.html">Symlink</a></li>
+<li><a href="Tasks/sync.html">Sync</a></li>
+<li><a href="Tasks/tar.html">Tar</a></li>
+<li><a href="Tasks/taskdef.html">Taskdef</a></li>
+<li><a href="Tasks/telnet.html">Telnet</a></li>
+<li><a href="Tasks/tempfile.html">Tempfile</a></li>
+<li><a href="Tasks/touch.html">Touch</a></li>
+<li><a href="Tasks/translate.html">Translate</a></li>
+<li><a href="Tasks/truncate.html">Truncate</a></li>
+<li><a href="Tasks/tstamp.html">TStamp</a></li>
+<li><a href="Tasks/typedef.html">Typedef</a></li>
+<li><a href="Tasks/unzip.html">Unjar</a></li>
+<li><a href="Tasks/unzip.html">Untar</a></li>
+<li><a href="Tasks/unzip.html">Unwar</a></li>
+<li><a href="Tasks/unzip.html">Unzip</a></li>
+<li><a href="Tasks/uptodate.html">Uptodate</a></li>
+<li><a href="Tasks/verifyjar.html">VerifyJar</a></li>
+<li><a href="Tasks/vss.html#tasks">Microsoft Visual SourceSafe Tasks</a></li>
+<li><a href="Tasks/waitfor.html">Waitfor</a></li>
+<li><a href="Tasks/war.html">War</a></li>
+<li><a href="Tasks/whichresource.html">WhichResource</a></li>
+<li><a href="Tasks/wljspc.html">Weblogic JSP Compiler</a></li>
+<li><a href="Tasks/xmlproperty.html">XmlProperty</a></li>
+<li><a href="Tasks/xmlvalidate.html">XmlValidate</a></li>
+<li><a href="Tasks/style.html">XSLT/<i>Style</i></a></li>
+<li><a href="Tasks/zip.html">Zip</a></li>
+</ul>
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/tasksoverview.html b/framework/src/ant/apache-ant-1.9.6/manual/tasksoverview.html
new file mode 100644
index 00000000..99aa11b0
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/tasksoverview.html
@@ -0,0 +1,1198 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+<head>
+ <meta http-equiv="Content-Language" content="en-us">
+ <link rel="stylesheet" type="text/css" href="stylesheets/style.css">
+<title>Overview of Apache Ant Tasks</title>
+ <base target="mainFrame">
+</head>
+
+<body>
+<a name="top"></a>
+<h2>Overview of Apache Ant Tasks</h2>
+<p>Given the large number of tasks available with Ant, it may be
+difficult to get an overall view of what each task can do. The following
+tables provide a short description of each task and a link to the complete
+documentation.</p>
+
+<a href="#archive">Archive Tasks</a><br>
+<a href="#audit">Audit/Coverage Tasks</a><br>
+<a href="#compile">Compile Tasks</a><br>
+<a href="#deploy">Deployment Tasks</a><br>
+<a href="#doc">Documentation Tasks</a><br>
+<a href="#ejb">EJB Tasks</a><br>
+<a href="#exec">Execution Tasks</a><br>
+<a href="#file">File Tasks</a><br>
+<a href="#extensions">Java2 Extensions Tasks</a><br>
+<a href="#log">Logging Tasks</a><br>
+<a href="#mail">Mail Tasks</a><br>
+<a href="#misc">Miscellaneous Tasks</a><br>
+<a href="#preproc">Pre-process Tasks</a><br>
+<a href="#prop">Property Tasks</a><br>
+<a href="#remote">Remote Tasks</a><br>
+<a href="#scm">SCM Tasks</a><br>
+<a href="#testing">Testing Tasks</a><br>
+
+
+<p></p>
+<table width="100%" border="0" cellpadding="4" cellspacing="0">
+<th align="left">
+<font size="+0" face="arial,helvetica,sanserif">
+<a name="archive">Archive Tasks</a>
+</font>
+</th>
+<font size="-1" face="arial,helvetica,sanserif">
+<th align="right"><a href="#top">[Back to top]</a></th>
+</font>
+</table>
+<table width="100%" border="1" cellpadding="4" cellspacing="0">
+ <tr valign="top">
+ <th nowrap>Task Name</th>
+ <th nowrap>Description</th>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/unpack.html">BUnzip2</a></td>
+ <td><p>Expands a file packed using GZip or BZip2.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/pack.html">BZip2</a></td>
+ <td><p>Packs a file using the GZip or BZip2 algorithm. This task
+ does not do any dependency checking; the output file is always
+ generated</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/cab.html">Cab</a></td>
+ <td><p>Creates Microsoft CAB archive files. It is invoked
+ similar to the <a href="Tasks/jar.html">Jar</a> or
+ <a href="Tasks/zip.html">Zip</a> tasks. This task will work on
+ Windows using the external <i>cabarc</i> tool (provided by Microsoft),
+ which must be located in your executable path.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/ear.html">Ear</a></td>
+ <td><p>An extension of the <a href="Tasks/jar.html">Jar</a> task with
+ special treatment for files that should end up in an
+ Enterprise Application archive.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/gunzip.html">GUnzip</a></td>
+ <td><p>Expands a GZip file.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/gzip.html">GZip</a></td>
+ <td><p>GZips a set of files.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/jar.html">Jar</a></td>
+ <td><p>Jars a set of files.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/jlink.html">Jlink</a></td>
+ <td><p><i>Deprecated.</i> Use the <code>zipfileset</code>
+ and <code>zipgroupfileset</code> attributes of the
+ <a href="Tasks/jar.html">Jar</a> or
+ <a href="Tasks/zip.html">Zip</a> tasks instead.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/manifest.html">Manifest</a></td>
+ <td><p>Creates a manifest file.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/rpm.html">Rpm</a></td>
+ <td><p>Invokes the <i>rpm</i> executable to build a Linux installation
+ file. This task currently only works on Linux or other Unix platforms
+ with RPM support.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/signjar.html">SignJar</a></td>
+ <td><p>Signs a jar or zip file with the <i>javasign</i>
+ command-line tool.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/tar.html">Tar</a></td>
+ <td><p>Creates a tar archive.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/unzip.html">Unjar</a></td>
+ <td><p>Unzips a jarfile.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/untar.html">Untar</a></td>
+ <td><p>Untars a tarfile.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/unzip.html">Unwar</a></td>
+ <td><p>Unzips a warfile.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/unzip.html">Unzip</a></td>
+ <td><p>Unzips a zipfile.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/war.html">War</a></td>
+ <td><p>An extension of the <a href="Tasks/jar.html">Jar</a> task
+ with special treatment for files that should end up in the
+ <code>WEB-INF/lib</code>, <code>WEB-INF/classes</code>, or
+ <code>WEB-INF</code> directories of the Web Application Archive.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/zip.html">Zip</a></td>
+ <td><p>Creates a zipfile.</p></td>
+ </tr>
+</table>
+
+<p></p>
+<table width="100%" border="0" cellpadding="4" cellspacing="0">
+<th align="left">
+<font size="+0" face="arial,helvetica,sanserif">
+<a name="audit">Audit/Coverage Tasks</a>
+</font></th>
+<font size="-1" face="arial,helvetica,sanserif">
+<th align="right"><a href="#top">[Back to top]</a></th>
+</font>
+</table>
+<table width="100%" border="1" cellpadding="4" cellspacing="0">
+ <tr valign="top">
+ <th nowrap>Task Name</th>
+ <th>Description</th>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/jdepend.html">JDepend</a></td>
+ <td><p>Invokes the <a href="http://www.clarkware.com/software/JDepend.html">
+ JDepend</a> parser. This parser &quot;traverses a set of Java source-file
+ directories and generates design-quality metrics for each Java
+ package&quot;.</p></td>
+ </tr>
+
+</table>
+
+<p></p>
+<table width="100%" border="0" cellpadding="4" cellspacing="0">
+<th align="left">
+<font size="+0" face="arial,helvetica,sanserif">
+<a name="compile">Compile Tasks</a>
+</font></th>
+<font size="-1" face="arial,helvetica,sanserif">
+<th align="right"><a href="#top">[Back to top]</a></th>
+</font>
+</table>
+<table width="100%" border="1" cellpadding="4" cellspacing="0">
+ <tr valign="top">
+ <th nowrap>Task Name</th>
+ <th>Description</th>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/depend.html">Depend</a></td>
+ <td><p>Determines which classfiles are out-of-date with respect to their
+ source, removing the classfiles of any other classes that depend on the
+ out-of-date classes, forcing the re-compile of the removed classfiles.
+ Typically used in conjunction with the
+ <a href="Tasks/javac.html">Javac</a> task.</p></td>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/javac.html">Javac</a></td>
+ <td><p>Compiles the specified source file(s) within the running
+ (Ant) VM, or in another VM if the <code>fork</code> attribute is
+ specified.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/apt.html">Apt</a></td>
+ <td><p>Runs the annotation processor tool (apt), and then optionally compiles
+ the original code, and any generated source code.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/jspc.html">JspC</a></td>
+ <td><p>Runs the JSP compiler. It can be used to precompile JSP pages
+ for fast initial invocation of JSP pages, deployment on a server without
+ the full JDK installed, or simply to syntax-check the pages without
+ deploying them. The <a href="Tasks/javac.html">Javac</a> task
+ can be used to compile the generated Java source.
+ (For Weblogic JSP compiles,
+ see the <a href="Tasks/wljspc.html">Wljspc</a> task.)</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/netrexxc.html">NetRexxC</a></td>
+ <td><p>Compiles a
+ <a href="http://www2.hursley.ibm.com/netrexx" target="_top">NetRexx</a>
+ source tree within the running (Ant) VM.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/rmic.html">Rmic</a></td>
+ <td><p>Runs the <i>rmic</i> compiler on the specified file(s).</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/wljspc.html">Wljspc</a></td>
+ <td><p>Compiles JSP pages using Weblogic's JSP compiler,
+ <i>weblogic.jspc</i>. (For non-Weblogic JSP compiles, see the
+ <a href="Tasks/jspc.html">JspC</a> task.</p></td>
+ </tr>
+
+</table>
+
+<p></p>
+<table width="100%" border="0" cellpadding="4" cellspacing="0">
+<th align="left">
+<font size="+0" face="arial,helvetica,sanserif">
+<a name="deploy">Deployment Tasks</a>
+</font></th>
+<font size="-1" face="arial,helvetica,sanserif">
+<th align="right"><a href="#top">[Back to top]</a></th>
+</font>
+</table>
+<table width="100%" border="1" cellpadding="4" cellspacing="0">
+ <tr valign="top">
+ <th nowrap>Task Name</th>
+ <th>Description</th>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/serverdeploy.html">ServerDeploy</a></td>
+ <td><p>Task to run a &quot;hot&quot; deployment tool for vendor-specific
+ J2EE server.
+ </p></td>
+ </tr>
+</table>
+
+<p></p>
+<table width="100%" border="0" cellpadding="4" cellspacing="0">
+<th align="left">
+<font size="+0" face="arial,helvetica,sanserif">
+<a name="doc">Documentation Tasks</a>
+</font></th>
+<font size="-1" face="arial,helvetica,sanserif">
+<th align="right"><a href="#top">[Back to top]</a></th>
+</font>
+</table>
+<table width="100%" border="1" cellpadding="4" cellspacing="0">
+ <tr valign="top">
+ <th nowrap>Task Name</th>
+ <th>Description</th>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/javadoc.html">Javadoc/<i>Javadoc2</i></a></td>
+ <td><p>Generates code documentation using the <i>javadoc</i> tool.
+ The Javadoc2 task is deprecated; use the Javadoc task instead.</p></td>
+ </tr>
+
+</table>
+
+<p></p>
+<table width="100%" border="0" cellpadding="4" cellspacing="0">
+<th align="left">
+<font size="+0" face="arial,helvetica,sanserif">
+<a name="ejb">EJB Tasks</a>
+</font></th>
+<font size="-1" face="arial,helvetica,sanserif">
+<th align="right"><a href="#top">[Back to top]</a></th>
+</font>
+</table>
+<table width="100%" border="1" cellpadding="4" cellspacing="0">
+ <tr valign="top">
+ <th nowrap>Task Name</th>
+ <th>Description</th>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/ejb.html">EJB Tasks</a></td>
+ <td><p>(See the documentation describing the EJB tasks.)</p></td>
+ </tr>
+</table>
+
+<p></p>
+<table width="100%" border="0" cellpadding="4" cellspacing="0">
+<th align="left">
+<font size="+0" face="arial,helvetica,sanserif">
+<a name="exec">Execution Tasks</a>
+</font></th>
+<font size="-1" face="arial,helvetica,sanserif">
+<th align="right"><a href="#top">[Back to top]</a></th>
+</font>
+</table>
+<table width="100%" border="1" cellpadding="4" cellspacing="0">
+ <tr valign="top">
+ <th nowrap>Task Name</th>
+ <th>Description</th>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/ant.html">Ant</a></td>
+ <td><p>Runs Ant on a supplied buildfile, optionally
+ passing properties (with possibly new values).
+ This task can be used to build sub-projects.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/antcall.html">AntCall</a></td>
+ <td><p>Runs another target within the same buildfile, optionally
+ passing properties (with possibly new values).</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/apply.html">Apply/<i>ExecOn</i></a></td>
+ <td><p>Executes a system command. When the <code>os</code> attribute is
+ specified, the command is only executed when Ant is run on one
+ of the specified operating systems.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/dependset.html">Dependset</a></td>
+ <td><p>This task compares a set of source files with a set of target
+ files. If any of the source files is newer than any of
+ the target files, all the target files are removed. </p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/exec.html">Exec</a></td>
+ <td><p>Executes a system command. When the <code>os</code> attribute
+ is specified, the command is only executed when Ant is run on one of
+ the specified operating systems.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/java.html">Java</a></td>
+ <td><p>Executes a Java class within the running (Ant) VM, or in
+ another VM if the <code>fork</code> attribute is specified.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/parallel.html">Parallel</a></td>
+ <td><p>A container task that can contain other Ant tasks.
+ Each nested task specified within the <code>&lt;parallel&gt;</code>
+ tag will be executed in its own thread.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/sequential.html">Sequential</a></td>
+ <td><p>A container task that can contain other Ant tasks.
+ The nested tasks are simply executed in sequence. Its primary use is
+ to support the sequential execution of a subset of tasks within
+ the <code>&lt;parallel&gt;</code> tag.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/sleep.html">Sleep</a></td>
+ <td><p> A task for suspending execution for a specified period of time.
+ Useful when a build or deployment process requires an interval between
+ tasks.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/subant.html">Subant</a></td>
+ <td><p> Calls a given target for all defined sub-builds. This is an extension of ant for bulk project execution.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/waitfor.html">Waitfor</a></td>
+ <td><p>Blocks execution until a set of specified conditions become true.
+ This task is intended to be used with the
+ <a href="Tasks/parallel.html">Parallel</a> task to synchronize
+ a set of processes.</p></td>
+ </tr>
+</table>
+
+<p></p>
+<table width="100%" border="0" cellpadding="4" cellspacing="0">
+<th align="left">
+<font size="+0" face="arial,helvetica,sanserif">
+<a name="file">File Tasks</a>
+</font></th>
+<font size="-1" face="arial,helvetica,sanserif">
+<th align="right"><a href="#top">[Back to top]</a></th>
+</font>
+</table>
+<table width="100%" border="1" cellpadding="4" cellspacing="0">
+ <tr valign="top">
+ <th nowrap>Task Name</th>
+ <th>Description</th>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/attrib.html">Attrib</a></td>
+ <td><p>Changes the permissions and/or attributes of a file or all
+ files inside the specified directories. Currently, it has effect
+ only under Windows.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/checksum.html">Checksum</a></td>
+ <td><p>Generates a checksum for a file or set of files. This task can
+ also be used to perform checksum verifications.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/chgrp.html">Chgrp</a></td>
+ <td><p>Changes the group ownership of a file or all files inside
+ the specified directories. Currently, it has effect only under
+ Unix.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/chmod.html">Chmod</a></td>
+ <td><p>Changes the permissions of a file or all files inside the
+ specified directories. Currently, it has effect only under Unix.
+ The permissions are also UNIX style, like the arguments for the
+ <i>chmod</i> command.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/chown.html">Chown</a></td>
+ <td><p>Changes the owner of a file or all files inside the
+ specified directories. Currently, it has effect only under
+ Unix.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/concat.html">Concat</a></td>
+ <td><p>Concatenates multiple files into a single one or to Ant's
+ logging system.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/copy.html">Copy</a></td>
+ <td><p>Copies a file or Fileset to a new file or directory.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/copydir.html"><i>Copydir</i></a></td>
+ <td><p><i>Deprecated.</i> Use the
+ <a href="Tasks/copy.html">Copy</a> task instead.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/copyfile.html"><i>Copyfile</i></a></td>
+ <td><p><i>Deprecated.</i> Use the
+ <a href="Tasks/copy.html">Copy</a> task instead.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/delete.html">Delete</a></td>
+ <td><p>Deletes either a single file, all files and sub-directories
+ in a specified directory, or a set of files specified by one or more
+ <a href="Types/fileset.html">FileSet</a>s.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/deltree.html"><i>Deltree</i></a></td>
+ <td><p><i>Deprecated.</i> Use the
+ <a href="Tasks/delete.html">Delete</a> task instead.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/filter.html">Filter</a></td>
+ <td><p>Sets a token filter for this project, or reads multiple token
+ filters from a specified file and sets these as filters. Token filters
+ are used by all tasks that perform file-copying operations.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/fixcrlf.html">FixCRLF</a></td>
+ <td><p>Modifies a file to add or remove tabs, carriage returns, linefeeds,
+ and EOF characters.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/get.html">Get</a></td>
+ <td><p>Gets a file from a URL.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/mkdir.html">Mkdir</a></td>
+ <td><p>Creates a directory. Non-existent parent directories are created,
+ when necessary.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/move.html">Move</a></td>
+ <td><p>Moves a file to a new file or directory, or a set(s) of file(s) to
+ a new directory.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/patch.html">Patch</a></td>
+ <td><p>Applies a &quot;diff&quot; file to originals.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/rename.html"><i>Rename</i></a></td>
+ <td><p><i>Deprecated.</i> Use the <a href="Tasks/move.html">Move</a>
+ task instead.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/renameextensions.html">
+ <i>RenameExtensions</i></a></td>
+ <td><p><i>Deprecated</i>. Use the <a href="Tasks/move.html">Move</a>
+ task with a <a href="Types/mapper.html#glob-mapper">glob mapper</a>
+ instead.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/replace.html">Replace</a></td>
+ <td><p>Replace is a directory-based task for replacing the occurrence
+ of a given string with another string in selected file.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/replaceregexp.html">
+ ReplaceRegExp</a></td>
+ <td><p>Directory-based task for replacing the occurrence of a given
+ regular expression with a substitution pattern in a file or set of
+ files.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/sync.html">Sync</a></td>
+ <td><p>Synchronize two directory trees.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/tempfile.html">Tempfile</a></td>
+ <td><p>Generates a name for a new temporary file and sets the specified
+ property to that name.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/touch.html">Touch</a></td>
+ <td><p>Changes the modification time of a file and possibly creates it at
+ the same time.</p></td>
+ </tr>
+</table>
+
+<p></p>
+<table width="100%" border="0" cellpadding="4" cellspacing="0">
+<th align="left">
+<font size="+0" face="arial,helvetica,sanserif">
+<a name="extensions">Java2 Extensions Tasks</a>
+</font></th>
+<font size="-1" face="arial,helvetica,sanserif">
+<th align="right"><a href="#top">[Back to top]</a></th>
+</font>
+</table>
+<table width="100%" border="1" cellpadding="4" cellspacing="0">
+ <tr valign="top">
+ <th nowrap>Task Name</th>
+ <th>Description</th>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap>
+ <a href="Tasks/jarlib-available.html">Jarlib-available</a></td>
+ <td><p>Check whether an extension is present in a FileSet or an
+ ExtensionSet. If the extension is present, the specified property is
+ set.</p>
+ </td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap>
+ <a href="Tasks/jarlib-display.html">Jarlib-display</a></td>
+ <td><p>Display the &quot;Optional Package&quot; and
+ &quot;Package Specification&quot; information contained within the
+ specified jars.</p>
+ </td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap>
+ <a href="Tasks/jarlib-manifest.html">Jarlib-manifest</a></td>
+ <td><p>Task to generate a manifest that declares all the dependencies
+ in manifest. The dependencies are determined by looking in the
+ specified path and searching for Extension/&quot;Optional Package&quot;
+ specifications in the manifests of the jars.</p>
+ </td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap>
+ <a href="Tasks/jarlib-resolve.html">Jarlib-resolve</a></td>
+ <td><p>Try to locate a jar to satisfy an extension, and place the
+ location of the jar into the specified property.</p>
+ </td>
+ </tr>
+</table>
+
+<p></p>
+<p></p>
+<table width="100%" border="0" cellpadding="4" cellspacing="0">
+<th align="left">
+<font size="+0" face="arial,helvetica,sanserif">
+<a name="log">Logging Tasks</a>
+</font></th>
+<font size="-1" face="arial,helvetica,sanserif">
+<th align="right"><a href="#top">[Back to top]</a></th>
+</font>
+</table>
+<table width="100%" border="1" cellpadding="4" cellspacing="0">
+ <tr valign="top">
+ <th nowrap>Task Name</th>
+ <th>Description</th>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/recorder.html">Record</a></td>
+ <td><p>Runs a listener that records the logging output of the
+ build-process events to a file. Several recorders can exist
+ at the same time. Each recorder is associated with a file.</p></td>
+ </tr>
+</table>
+
+<p></p>
+<table width="100%" border="0" cellpadding="4" cellspacing="0">
+<th align="left">
+<font size="+0" face="arial,helvetica,sanserif">
+<a name="mail">Mail Tasks</a>
+</font></th>
+<font size="-1" face="arial,helvetica,sanserif">
+<th align="right"><a href="#top">[Back to top]</a></th>
+</font>
+</table>
+<table width="100%" border="1" cellpadding="4" cellspacing="0">
+ <tr valign="top">
+ <th nowrap>Task Name</th>
+ <th>Description</th>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/mail.html">Mail</a></td>
+ <td><p>A task to send SMTP email.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/mimemail.html">MimeMail</a></td>
+ <td><p><i>Deprecated</i>. Use the <a href="Tasks/mail.html">Mail</a>
+ task instead.</p></td>
+ </tr>
+
+</table>
+
+<p></p>
+<table width="100%" border="0" cellpadding="4" cellspacing="0">
+<th align="left">
+<font size="+0" face="arial,helvetica,sanserif">
+<a name="misc">Miscellaneous Tasks</a>
+</font></th>
+<font size="-1" face="arial,helvetica,sanserif">
+<th align="right"><a href="#top">[Back to top]</a></th>
+</font>
+</table>
+<table width="100%" border="1" cellpadding="4" cellspacing="0">
+ <tr valign="top">
+ <th nowrap>Task Name</th>
+ <th>Description</th>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/defaultexcludes.html">Defaultexcludes</a></td>
+ <td><p>Modify the list of default exclude patterns from within
+ your build file.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/echo.html">Echo</a></td>
+ <td><p>Echoes text to <code>System.out</code> or to a file.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/fail.html">Fail</a></td>
+ <td><p>Exits the current build by throwing a BuildException,
+ optionally printing additional information.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/genkey.html">GenKey</a></td>
+ <td><p>Generates a key in keystore.</p></td>
+ </tr>
+
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/hostinfo.html">HostInfo</a></td>
+ <td><p>Sets properties related to the provided host, or to
+ the host the process is run on.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/input.html">Input</a></td>
+ <td><p>Allows user interaction during the build process by displaying a
+ message and reading a line of input from the console.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/script.html">Script</a></td>
+ <td><p>Executes a script in a
+ <a href="http://jakarta.apache.org/bsf/"
+ target="_top">Apache BSF</a>-supported language.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/sound.html">Sound</a></td>
+ <td><p>Plays a sound file at the end of the build, according to whether
+ the build failed or succeeded.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/splash.html">Splash</a></td>
+ <td><p>Displays a splash screen.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/sql.html">Sql</a></td>
+ <td><p>Executes a series of SQL statements via JDBC to a database.
+ Statements can either be read in from a text file using the
+ <code>src</code> attribute, or from between the enclosing SQL
+ tags.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/taskdef.html">Taskdef</a></td>
+ <td><p>Adds a task definition to the current project, such that this
+ new task can be used in the current project.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/tstamp.html">TStamp</a></td>
+ <td><p>Sets the <code>DSTAMP</code>, <code>TSTAMP</code>, and
+ <code>TODAY</code> properties in the current project, based on
+ the current date and time.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/typedef.html">Typedef</a></td>
+ <td><p>Adds a data-type definition to the current project, such that this
+ new type can be used in the current project.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/xmlvalidate.html">XmlValidate</a></td>
+ <td><p>Checks that XML files are valid (or only well-formed). This task
+ uses the XML parser that is currently used by Ant by default, but any SAX1/2
+ parser can be specified, if needed.</p></td>
+ </tr>
+</table>
+
+<p></p>
+<table width="100%" border="0" cellpadding="4" cellspacing="0">
+<th align="left">
+<font size="+0" face="arial,helvetica,sanserif">
+<a name="preproc">Pre-process Tasks</a>
+</font></th>
+<font size="-1" face="arial,helvetica,sanserif">
+<th align="right"><a href="#top">[Back to top]</a></th>
+</font>
+</table>
+<table width="100%" border="1" cellpadding="4" cellspacing="0">
+ <tr valign="top">
+ <th nowrap>Task Name</th>
+ <th>Description</th>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/antlr.html">ANTLR</a></td>
+ <td><p>Invokes the <a HREF="http://www.antlr.org/" target="_top">ANTLR</a>
+ Translator generator on a grammar file.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/antstructure.html">AntStructure</a></td>
+ <td><p>Generates a DTD for Ant buildfiles that contains information
+ about all tasks currently known to Ant.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/import.html">Import</a></td>
+ <td><p>Import another build file and potentially override targets
+ in it with targets of your own.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/include.html">Include</a></td>
+ <td><p>Include another build file.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/javacc.html">JavaCC</a></td>
+ <td><p>Invokes the
+ <a HREF="http://javacc.dev.java.net/" target="_top">
+ JavaCC</a> compiler-compiler on a grammar file.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/javah.html">Javah</a></td>
+ <td><p>Generates JNI headers from a Java class.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/jjdoc.html">JJDoc</a></td>
+ <td><p>Invokes the <a href="http://javacc.dev.java.net/">
+ JJDoc</a> documentation generator for the JavaCC compiler-compiler.
+ JJDoc takes a JavaCC parser specification and produces documentation
+ for the BNF grammar. It can operate in three modes, determined by
+ command line options. This task only invokes JJDoc if the grammar file
+ is newer than the generated BNF grammar documentation.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/jjtree.html">JJTree</a></td>
+ <td><p>Invokes the <a href="http://javacc.dev.java.net/">
+ JJTree</a> preprocessor for the JavaCC compiler-compiler. It inserts
+ parse-tree building actions at various places in the JavaCC source that
+ it generates. The output of JJTree is run through JavaCC to create the
+ parser. This task only invokes JJTree if the grammar file is newer than
+ the generated JavaCC file.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/macrodef.html">Macrodef</a></td>
+ <td><p>Define a new task as a macro built-up upon other tasks.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/native2ascii.html">
+ Native2Ascii</a></td>
+ <td><p>Converts files from native encodings to ASCII with escaped Unicode.
+ A common usage is to convert source files maintained in a native
+ operating system encoding to ASCII, prior to compilation.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/presetdef.html">Presetdef</a></td>
+ <td><p>Define a new task by instrumenting an existing task with
+ default values for attributes or child elements.</p>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/translate.html">Translate</a></td>
+ <td><p>Identifies keys in files, delimited by special tokens, and
+ translates them with values read from resource bundles.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/style.html">XSLT</a></td>
+ <td><p>Processes a set of documents via XSLT.</p></td>
+ </tr>
+
+</table>
+
+<p></p>
+<table width="100%" border="0" cellpadding="4" cellspacing="0">
+<th align="left">
+<font size="+0" face="arial,helvetica,sanserif">
+<a name="prop">Property Tasks</a>
+</font></th>
+<font size="-1" face="arial,helvetica,sanserif">
+<th align="right"><a href="#top">[Back to top]</a></th>
+</font>
+</table>
+<table width="100%" border="1" cellpadding="4" cellspacing="0">
+ <tr valign="top">
+ <th nowrap>Task Name</th>
+ <th>Description</th>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/available.html">Available</a></td>
+ <td><p>Sets a property if a specified file, directory, class in the
+ classpath, or JVM system resource is available at runtime.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/basename.html">Basename</a></td>
+ <td><p>Sets a property to the last element of a specified path.
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/buildnumber.html">BuildNumber</a></td>
+ <td><p>Task that can be used to track build numbers.
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/condition.html">Condition</a></td>
+ <td><p>Sets a property if a certain condition holds true; this is a
+ generalization of <a href="Tasks/available.html">Available</a> and
+ <a href="Tasks/uptodate.html">Uptodate</a>.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/dirname.html">Dirname</a></td>
+ <td><p>Sets a property to the value of the specified file up to,
+ but not including, the last path element.
+ </tr>
+
+ <tr valign="top">
+ <td nowrap>
+ <a href="Tasks/echoproperties.html">Echoproperties</a><br>
+
+ </td>
+ <td><p>Lists the current properties.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/loadfile.html">LoadFile</a></td>
+ <td><p>Loads a file into a property.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/loadproperties.html">LoadProperties</a></td>
+ <td><p>Load a file's contents as Ant properties. This task is
+ equivalent to using <code>&lt;property file=&quot;...&quot;/&gt;</code>
+ except that it supports nested <code>&lt;filterchain&gt;</code> elements,
+ and it cannot be specified outside a target.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/makeurl.html">MakeURL</a></td>
+ <td><p>Creates a URL (list) from a file/fileset or path</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/pathconvert.html">PathConvert</a></td>
+ <td><p>Converts a nested path, path reference, filelist reference, or
+ fileset reference to the form usable on a specified platform and/or
+ to a list of items separated by the specified separator and stores
+ the result in the specified property.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/property.html">Property</a></td>
+ <td><p>Sets a property (by name and value), or set of properties
+ (from a file or resource) in the project.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/propertyfile.html">
+ PropertyFile</a></td>
+ <td><p>Creates or modifies property files. Useful when wanting to make
+ unattended modifications to configuration files for application
+ servers and applications. Typically used for things such as
+ automatically generating a build number and saving it to a build
+ properties file, or doing date manipulation.<p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/uptodate.html">Uptodate</a></td>
+ <td><p>Sets a property if a given target file is newer than a set of
+ source files.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/whichresource.html">Whichresource</a></td>
+ <td><p>Find a class or resource.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/xmlproperty.html">XmlProperty</a></td>
+ <td><p>Loads property values from a well-formed XML file.</p></td>
+ </tr>
+</table>
+
+<p></p>
+<table width="100%" border="0" cellpadding="4" cellspacing="0">
+<th align="left">
+<font size="+0" face="arial,helvetica,sanserif">
+<a name="remote">Remote Tasks</a>
+</font></th>
+<font size="-1" face="arial,helvetica,sanserif">
+<th align="right"><a href="#top">[Back to top]</a></th>
+</font>
+</table>
+<table width="100%" border="1" cellpadding="4" cellspacing="0">
+ <tr valign="top">
+ <th nowrap>Task Name</th>
+ <th>Description</th>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/ftp.html">FTP</a></td>
+ <td><p>Implements a basic FTP client that can send, receive,
+ list, and delete files, and create directories.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/rexec.html">Rexec</a></td>
+ <td><p>Task to automate a remote rexec session.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/scp.html">Scp</a></td>
+ <td><p>Copy files to or from a remote server using SSH.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/setproxy.html">setproxy</a></td>
+ <td><p>Sets Java's web proxy properties, so that tasks and code run
+ in the same JVM can have through-the-firewall access to remote web sites.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/sshexec.html">Sshexec</a></td>
+ <td><p>Execute a command on a remote server using SSH.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/telnet.html">Telnet</a></td>
+ <td><p>Task to automate a remote <i>telnet</i> session. This task uses
+ nested <code>&lt;read&gt;</code> and <code>&lt;write&gt;</code> tags
+ to indicate strings to wait for and specify text to send.</p></td>
+ </tr>
+
+</table>
+
+<p></p>
+<table width="100%" border="0" cellpadding="4" cellspacing="0">
+<th align="left">
+<font size="+0" face="arial,helvetica,sanserif">
+<a name="scm">SCM Tasks</a>
+</font></th>
+<font size="-1" face="arial,helvetica,sanserif">
+<th align="right"><a href="#top">[Back to top]</a></th>
+</font>
+</table>
+<table width="100%" border="1" cellpadding="4" cellspacing="0">
+ <tr valign="top">
+ <th nowrap>Task Name</th>
+ <th>Description</th>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/cvs.html">Cvs</a></td>
+ <td><p>Handles packages/modules retrieved from a
+ <a href="http://www.nongnu.org/cvs/" target="_top">CVS</a>
+ repository.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/changelog.html">CvsChangeLog</a></td>
+ <td><p>Generates an XML report of the changes recorded in a
+ <a href="http://www.nongnu.org/cvs/" target="_top">CVS</a>
+ repository.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/cvspass.html">CVSPass</a></td>
+ <td><p>Adds entries to a .cvspass file. Adding entries to this file
+ has the same affect as a <i>cvs login</i> command.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/cvstagdiff.html">CvsTagDiff</a></td>
+ <td><p>Generates an XML-formatted report file of the changes between
+ two tags or dates recorded in a <a href="http://www.nongnu.org/cvs/"
+ target="_top">CVS</a> repository.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/clearcase.html">ClearCase</a></td>
+ <td><p>Tasks to perform the ClearCase cleartool <i>checkin</i>, <i>checkout</i>,
+ <i>uncheckout</i>, <i>update</i>, <i>lock</i>, <i>unlock</i>, <i>mklbtype</i>, <i>rmtype</i>, <i>mklabel</i>, <i>mkattr</i>, <i>mkdir</i>, <i>mkelem</i>, and <i>mkbl</i> commands.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/ccm.html">Continuus/Synergy</a></td>
+ <td><p>Tasks to perform the Continuus <i>ccmcheckin</i>,
+ <i>ccmcheckout</i>, <i>ccmcheckintask</i>, <i>ccmreconfigure</i>, and
+ <i>ccmcreateTask</i> commands.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/vss.html">
+ Microsoft Visual SourceSafe</a></td>
+ <td><p>Tasks to perform the Visual SourceSafe <i>vssget</i>,
+ <i>vsslabel</i>, <i>vsshistory</i>, <i>vsscheckin</i>,
+ <i>vsscheckout</i>, <i>vssadd</i>, <i>vsscp</i>, and <i>vsscreate</i>
+ commands.</p></td>
+ </tr>
+
+
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/pvcstask.html">Pvcs</a></td>
+ <td><p>Allows the user extract the latest edition of the source code
+ from a PVCS repository.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/sos.html">SourceOffSite</a></td>
+ <td><p>Tasks to perform the SourceOffSite <i>sosget</i>, <i>soslabel</i>,
+ <i>soscheckin</i>, and <i>soscheckout</i> commands.</p></td>
+ </tr>
+
+</table>
+
+<p></p>
+<table width="100%" border="0" cellpadding="4" cellspacing="0">
+<th align="left">
+<font size="+0" face="arial,helvetica,sanserif">
+<a name="testing">Testing Tasks</a>
+</font></th>
+<font size="-1" face="arial,helvetica,sanserif">
+<th align="right"><a href="#top">[Back to top]</a></th>
+</font>
+</table>
+<table width="100%" border="1" cellpadding="4" cellspacing="0">
+ <tr valign="top">
+ <th nowrap>Task Name</th>
+ <th>Description</th>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/junit.html">Junit</a></td>
+ <td><p>Runs tests from the <a href="http://www.junit.org">Junit</a>
+ testing framework. This task has been tested with JUnit 3.0 up to
+ JUnit 3.7; it won't work with versions prior to JUnit 3.0.</p></td>
+ </tr>
+
+ <tr valign="top">
+ <td nowrap><a href="Tasks/junitreport.html">JunitReport</a></td>
+ <td><p>Merges the individual XML files generated by the
+ <a href="Tasks/junit.html">Junit</a> task and applies a
+ stylesheet on the resulting merged document to provide a browsable
+ report of the testcases results.</p></td>
+ </tr>
+
+</table>
+
+
+
+
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/toc.html b/framework/src/ant/apache-ant-1.9.6/manual/toc.html
new file mode 100644
index 00000000..91d98242
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/toc.html
@@ -0,0 +1,51 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us"/>
+<link rel="stylesheet" type="text/css" href="stylesheets/style.css"/>
+<title>Apache Ant User Manual</title>
+<base target="mainFrame"/>
+</head>
+
+<body>
+
+<h2>Table of Contents</h2>
+<ul class="inlinelist">
+<li><a href="intro.html">Introduction</a></li>
+<li><a href="installlist.html" target="navFrame">Installing Apache Ant</a></li>
+<li><a href="usinglist.html" target="navFrame">Using Apache Ant</a></li>
+<li><a href="runninglist.html" target="navFrame">Running Apache Ant</a></li>
+<li><a href="anttaskslist.html" target="navFrame">Ant Tasks</a></li>
+<li><a href="conceptstypeslist.html" target="navFrame">Concepts and Types</a></li>
+<li><a href="listeners.html" target="mainFrame">Loggers &amp; Listeners</a></li>
+<li><a href="ide.html" target="navFrame">Editor/IDE Integration</a></li>
+<li><a href="developlist.html" target="navFrame">Developing with Ant</a></li>
+<li><a href="tutorials.html" target="navFrame">Tutorials</a></li>
+<li><a href="api/index.html" target="_top">Ant API</a></li>
+<li><a href="LICENSE">License</a></li>
+<li><a href="feedback.html">Feedback and Troubleshooting</a></li>
+</ul>
+
+<ul class="inlinelist">
+<li><a href="credits.html">Authors</a></li>
+</ul>
+
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/tutorial-HelloWorldWithAnt.html b/framework/src/ant/apache-ant-1.9.6/manual/tutorial-HelloWorldWithAnt.html
new file mode 100644
index 00000000..babd9b43
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/tutorial-HelloWorldWithAnt.html
@@ -0,0 +1,520 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+<head>
+ <title>Tutorial: Hello World with Apache Ant</title>
+ <link rel="stylesheet" type="text/css" href="stylesheets/style.css">
+</head>
+<body>
+<h1>Tutorial: Hello World with Apache Ant</h1>
+
+<p>This document provides a step by step tutorial for starting java programming with Apache Ant.
+It does <b>not</b> contain deeper knowledge about Java or Ant. This tutorial has the goal
+to let you see, how to do the easiest steps in Ant.</p>
+
+
+
+<h2>Content</h2>
+<p><ul>
+<li><a href="#prepare">Preparing the project</a></li>
+<li><a href="#four-steps">Enhance the build file</a></li>
+<li><a href="#enhance">Enhance the build file</a></li>
+<li><a href="#ext-libs">Using external libraries</a></li>
+<li><a href="#resources">Resources</a></li>
+</ul></p>
+
+
+<a name="prepare"></a>
+<h2>Preparing the project</h2>
+<p>We want to separate the source from the generated files, so our java source files will
+be in <tt>src</tt> folder. All generated files should be under <tt>build</tt>, and there
+splitted into several subdirectories for the individual steps: <tt>classes</tt> for our compiled
+files and <tt>jar</tt> for our own JAR-file.</p>
+<p>We have to create only the <tt>src</tt> directory. (Because I am working on Windows, here is
+the win-syntax - translate to your shell):</p>
+
+<pre class="code">
+md src
+</pre>
+
+<p>The following simple Java class just prints a fixed message out to STDOUT,
+so just write this code into <tt>src\oata\HelloWorld.java</tt>.</p>
+
+<pre class="code">
+package oata;
+
+public class HelloWorld {
+ public static void main(String[] args) {
+ System.out.println("Hello World");
+ }
+}
+</pre>
+
+<p>Now just try to compile and run that:
+<pre class="code">
+md build\classes
+javac -sourcepath src -d build\classes src\oata\HelloWorld.java
+java -cp build\classes oata.HelloWorld
+</pre>
+which will result in
+<pre class="output">
+Hello World
+</pre>
+</p>
+
+<p>Creating a jar-file is not very difficult. But creating a <i>startable</i> jar-file needs more steps: create a
+manifest-file containing the start class, creating the target directory and archiving the files.</p>
+<pre class="code">
+echo Main-Class: oata.HelloWorld&gt;myManifest
+md build\jar
+jar cfm build\jar\HelloWorld.jar myManifest -C build\classes .
+java -jar build\jar\HelloWorld.jar
+</pre>
+
+<p><b>Note:</b> Do not have blanks around the &gt;-sign in the <tt>echo Main-Class</tt> instruction because it would
+falsify it!</p>
+
+
+<a name="four-steps"></a>
+<h2>Four steps to a running application</h2>
+<p>After finishing the java-only step we have to think about our build process. We <i>have</i> to compile our code, otherwise we couldn't
+start the program. Oh - "start" - yes, we could provide a target for that. We <i>should</i> package our application.
+Now it's only one class - but if you want to provide a download, no one would download several hundreds files ...
+(think about a complex Swing GUI - so let us create a jar file. A startable jar file would be nice ... And it's a
+good practise to have a "clean" target, which deletes all the generated stuff. Many failures could be solved just
+by a "clean build".</p>
+
+<p>By default Ant uses <tt>build.xml</tt> as the name for a buildfile, so our <tt>.\build.xml</tt> would be:</p>
+<pre class="code">
+&lt;project&gt;
+
+ &lt;target name="clean"&gt;
+ &lt;delete dir="build"/&gt;
+ &lt;/target&gt;
+
+ &lt;target name="compile"&gt;
+ &lt;mkdir dir="build/classes"/&gt;
+ &lt;javac srcdir="src" destdir="build/classes"/&gt;
+ &lt;/target&gt;
+
+ &lt;target name="jar"&gt;
+ &lt;mkdir dir="build/jar"/&gt;
+ &lt;jar destfile="build/jar/HelloWorld.jar" basedir="build/classes"&gt;
+ &lt;manifest&gt;
+ &lt;attribute name="Main-Class" value="oata.HelloWorld"/&gt;
+ &lt;/manifest&gt;
+ &lt;/jar&gt;
+ &lt;/target&gt;
+
+ &lt;target name="run"&gt;
+ &lt;java jar="build/jar/HelloWorld.jar" fork="true"/&gt;
+ &lt;/target&gt;
+
+&lt;/project&gt;
+</pre>
+
+<p>Now you can compile, package and run the application via</p>
+<pre class="code">
+ant compile
+ant jar
+ant run
+</pre>
+<p>Or shorter with</p>
+<pre class="code">
+ant compile jar run
+</pre>
+
+<p>While having a look at the buildfile, we will see some similar steps between Ant and the java-only commands:
+<table>
+<tr>
+ <th>java-only</th>
+ <th>Ant</th>
+</tr>
+<tr>
+ <td valign="top"><pre class="code">
+md build\classes
+javac
+ -sourcepath src
+ -d build\classes
+ src\oata\HelloWorld.java
+echo Main-Class: oata.HelloWorld>mf
+md build\jar
+jar cfm
+ build\jar\HelloWorld.jar
+ mf
+ -C build\classes
+ .
+
+
+
+java -jar build\jar\HelloWorld.jar
+ </pre></td>
+ <td valign="top"><pre class="code">
+&lt;mkdir dir="build/classes"/&gt;
+&lt;javac
+ srcdir="src"
+ destdir="build/classes"/&gt;
+<i>&lt;!-- automatically detected --&gt;</i>
+<i>&lt;!-- obsolete; done via manifest tag --&gt;</i>
+&lt;mkdir dir="build/jar"/&gt;
+&lt;jar
+ destfile="build/jar/HelloWorld.jar"
+
+ basedir="build/classes"&gt;
+ &lt;manifest&gt;
+ &lt;attribute name="Main-Class" value="oata.HelloWorld"/&gt;
+ &lt;/manifest&gt;
+&lt;/jar&gt;
+&lt;java jar="build/jar/HelloWorld.jar" fork="true"/&gt;
+ </pre></td>
+</tr></table>
+</p>
+
+
+
+<a name="enhance"></a>
+<h2>Enhance the build file</h2>
+<p>Now we have a working buildfile we could do some enhancements: many time you are referencing the
+same directories, main-class and jar-name are hard coded, and while invocation you have to remember
+the right order of build steps.</p>
+<p>The first and second point would be addressed with <i>properties</i>, the third with a special property - an attribute
+of the &lt;project&gt;-tag and the fourth problem can be solved using dependencies.</p>
+
+
+<pre class="code">
+&lt;project name="HelloWorld" basedir="." default="main"&gt;
+
+ &lt;property name="src.dir" value="src"/&gt;
+
+ &lt;property name="build.dir" value="build"/&gt;
+ &lt;property name="classes.dir" value="${build.dir}/classes"/&gt;
+ &lt;property name="jar.dir" value="${build.dir}/jar"/&gt;
+
+ &lt;property name="main-class" value="oata.HelloWorld"/&gt;
+
+
+
+ &lt;target name="clean"&gt;
+ &lt;delete dir="${build.dir}"/&gt;
+ &lt;/target&gt;
+
+ &lt;target name="compile"&gt;
+ &lt;mkdir dir="${classes.dir}"/&gt;
+ &lt;javac srcdir="${src.dir}" destdir="${classes.dir}"/&gt;
+ &lt;/target&gt;
+
+ &lt;target name="jar" depends="compile"&gt;
+ &lt;mkdir dir="${jar.dir}"/&gt;
+ &lt;jar destfile="${jar.dir}/${ant.project.name}.jar" basedir="${classes.dir}"&gt;
+ &lt;manifest&gt;
+ &lt;attribute name="Main-Class" value="${main-class}"/&gt;
+ &lt;/manifest&gt;
+ &lt;/jar&gt;
+ &lt;/target&gt;
+
+ &lt;target name="run" depends="jar"&gt;
+ &lt;java jar="${jar.dir}/${ant.project.name}.jar" fork="true"/&gt;
+ &lt;/target&gt;
+
+ &lt;target name="clean-build" depends="clean,jar"/&gt;
+
+ &lt;target name="main" depends="clean,run"/&gt;
+
+&lt;/project&gt;
+</pre>
+
+
+<p>Now it's easier, just do a <tt class="code">ant</tt> and you will get</p>
+<pre class="output">
+Buildfile: build.xml
+
+clean:
+
+compile:
+ [mkdir] Created dir: C:\...\build\classes
+ [javac] Compiling 1 source file to C:\...\build\classes
+
+jar:
+ [mkdir] Created dir: C:\...\build\jar
+ [jar] Building jar: C:\...\build\jar\HelloWorld.jar
+
+run:
+ [java] Hello World
+
+main:
+
+BUILD SUCCESSFUL
+</pre>
+
+
+<a name="ext-libs"></a>
+<h2>Using external libraries</h2>
+<p>Somehow told us not to use syso-statements. For log-Statements we should use a Logging-API - customizable on a high
+degree (including switching off during usual life (= not development) execution). We use Log4J for that, because <ul>
+<li>it is not part of the JDK (1.4+) and we want to show how to use external libs</li>
+<li>it can run under JDK 1.2 (as Ant)</li>
+<li>it's highly configurable</li>
+<li>it's from Apache ;-)</li>
+</ul></p>
+<p>We store our external libraries in a new directory <tt>lib</tt>. Log4J can be
+<a href="http://www.apache.org/dist/logging/log4j/1.2.13/logging-log4j-1.2.13.zip">downloaded [1]</a> from Logging's Homepage.
+Create the <tt>lib</tt> directory and extract the log4j-1.2.9.jar into that lib-directory. After that we have to modify
+our java source to use that library and our buildfile so that this library could be accessed during compilation and run.
+</p>
+<p>Working with Log4J is documented inside its manual. Here we use the <i>MyApp</i>-example from the
+<a href="http://logging.apache.org/log4j/docs/manual.html">Short Manual [2]</a>. First we have to modify the java source to
+use the logging framework:</p>
+
+<pre class="code">
+package oata;
+
+<b>import org.apache.log4j.Logger;</b>
+<b>import org.apache.log4j.BasicConfigurator;</b>
+
+public class HelloWorld {
+ <b>static Logger logger = Logger.getLogger(HelloWorld.class);</b>
+
+ public static void main(String[] args) {
+ <b>BasicConfigurator.configure();</b>
+ <font color="blue"><b>logger.info("Hello World");</b></font> // the old SysO-statement
+ }
+}
+</pre>
+
+<p>Most of the modifications are "framework overhead" which has to be done once. The blue line is our "old System-out"
+statement.</p>
+<p>Don't try to run <tt>ant</tt> - you will only get lot of compiler errors. Log4J is not inside the classpath so we have
+to do a little work here. But do not change the CLASSPATH environment variable! This is only for this project and maybe
+you would break other environments (this is one of the most famous mistakes when working with Ant). We introduce Log4J
+(or to be more precise: all libraries (jar-files) which are somewhere under <tt>.\lib</tt>) into our buildfile:</p>
+
+<pre class="code">
+&lt;project name="HelloWorld" basedir="." default="main"&gt;
+ ...
+ <b>&lt;property name="lib.dir" value="lib"/&gt;</b>
+
+ <b>&lt;path id="classpath"&gt;</b>
+ <b>&lt;fileset dir="${lib.dir}" includes="**/*.jar"/&gt;</b>
+ <b>&lt;/path&gt;</b>
+
+ ...
+
+ &lt;target name="compile"&gt;
+ &lt;mkdir dir="${classes.dir}"/&gt;
+ &lt;javac srcdir="${src.dir}" destdir="${classes.dir}" <b>classpathref="classpath"</b>/&gt;
+ &lt;/target&gt;
+
+ &lt;target name="run" depends="jar"&gt;
+ &lt;java fork="true" <b>classname="${main-class}"</b>&gt;
+ <b>&lt;classpath&gt;</b>
+ <b>&lt;path refid="classpath"/&gt;</b>
+ <font color="red"><b>&lt;path location="${jar.dir}/${ant.project.name}.jar"/&gt;</b></font>
+ <b>&lt;/classpath&gt;</b>
+ &lt;/java&gt;
+ &lt;/target&gt;
+
+ ...
+
+&lt;/project&gt;
+</pre>
+
+<p>In this example we start our application not via its Main-Class manifest-attribute, because we could not provide
+a jarname <i>and</i> a classpath. So add our class in the red line to the already defined path and start as usual. Running
+<tt>ant</tt> would give (after the usual compile stuff):</p>
+
+<pre class="output">
+[java] 0 [main] INFO oata.HelloWorld - Hello World
+</pre>
+
+<p>What's that? <ul>
+<li><i>[java]</i> Ant task running at the moment</li>
+<li><i>0</i> <font size="-1">sorry don't know - some Log4J stuff</font></li>
+<li><i>[main]</i> the running thread from our application </li>
+<li><i>INFO</i> log level of that statement</i>
+<li><i>oata.HelloWorld</i> source of that statement</i>
+<li><i>-</i> separator</li>
+<li><i>Hello World</i> the message</li>
+</ul>
+For another layout ... have a look inside Log4J's documentation about using other PatternLayout's.</p>
+
+
+<a name="config-files">
+<h2>Configuration files</h2>
+<p>Why we have used Log4J? "It's highly configurable"? No - all is hard coded! But that is not the debt of Log4J - it's
+ours. We had coded <tt>BasicConfigurator.configure();</tt> which implies a simple, but hard coded configuration. More
+comfortable would be using a property file. In the java source delete the BasicConfiguration-line from the main() method
+(and the related import-statement). Log4J will search then for a configuration as described in it's manual. Then create
+a new file <tt>src/log4j.properties</tt>. That's the default name for Log4J's configuration and using that name would make
+life easier - not only the framework knows what is inside, you too!</p>
+
+<pre class="code">
+log4j.rootLogger=DEBUG, <b>stdout</b>
+
+log4j.appender.<b>stdout</b>=org.apache.log4j.ConsoleAppender
+
+log4j.appender.<b>stdout</b>.layout=org.apache.log4j.PatternLayout
+log4j.appender.<b>stdout</b>.layout.ConversionPattern=<font color="blue"><b>%m%n</b></font>
+</pre>
+
+<p>This configuration creates an output channel ("Appender") to console named as <tt>stdout</tt> which prints the
+message (%m) followed by a line feed (%n) - same as the earlier System.out.println() :-) Oooh kay - but we haven't
+finished yet. We should deliver the configuration file, too. So we change the buildfile:</p>
+
+<pre class="code">
+ ...
+ &lt;target name="compile"&gt;
+ &lt;mkdir dir="${classes.dir}"/&gt;
+ &lt;javac srcdir="${src.dir}" destdir="${classes.dir}" classpathref="classpath"/&gt;
+ <b>&lt;copy todir="${classes.dir}"&gt;</b>
+ <b>&lt;fileset dir="${src.dir}" excludes="**/*.java"/&gt;</b>
+ <b>&lt;/copy&gt;</b>
+ &lt;/target&gt;
+ ...
+</pre>
+
+<p>This copies all resources (as long as they haven't the suffix ".java") to the build directory, so we could
+start the application from that directory and these files will included into the jar.</p>
+
+
+<a name="junit">
+<h2>Testing the class</h2>
+<p>In this step we will introduce the usage of the JUnit [3] testframework in combination with Ant. Because Ant
+has a built-in JUnit 3.8.2 you could start directly using it. Write a test class in <tt>src\HelloWorldTest.java</tt>: </p>
+
+<pre class="code">
+public class HelloWorldTest extends junit.framework.TestCase {
+
+ public void testNothing() {
+ }
+
+ public void testWillAlwaysFail() {
+ fail("An error message");
+ }
+
+}</pre>
+
+<p>Because we dont have real business logic to test, this test class is very small: just show how to start. For
+further information see the JUnit documentation [3] and the manual of <a href="Tasks/junit.html">junit</a> task.
+Now we add a junit instruction to our buildfile:</p>
+
+<pre class="code">
+ ...
+
+ &lt;path <b>id="application"</b> location="${jar.dir}/${ant.project.name}.jar"/&gt;
+
+ &lt;target name="run" depends="jar"&gt;
+ &lt;java fork="true" classname="${main-class}"&gt;
+ &lt;classpath&gt;
+ &lt;path refid="classpath"/&gt;
+ <b>&lt;path refid="application"/&gt;</b>
+ &lt;/classpath&gt;
+ &lt;/java&gt;
+ &lt;/target&gt;
+
+ <b>&lt;target name="junit" depends="jar"&gt;
+ &lt;junit printsummary="yes"&gt;
+ &lt;classpath&gt;
+ &lt;path refid="classpath"/&gt;
+ &lt;path refid="application"/&gt;
+ &lt;/classpath&gt;
+
+ &lt;batchtest fork="yes"&gt;
+ &lt;fileset dir="${src.dir}" includes="*Test.java"/&gt;
+ &lt;/batchtest&gt;
+ &lt;/junit&gt;
+ &lt;/target&gt;</b>
+
+ ...
+
+</pre>
+
+<p>We reuse the path to our own jar file as defined in run-target by
+ giving it an ID and making it globally available.
+The <tt>printsummary=yes</tt> lets us see more detailed information than just a "FAILED" or "PASSED" message.
+How much tests failed? Some errors? Printsummary lets us know. The classpath is set up to find our classes.
+To run tests the <tt>batchtest</tt> here is used, so you could easily add more test classes in the future just
+by naming them <tt>*Test.java</tt>. This is a common naming scheme.</p>
+
+<p>After a <tt class="code">ant junit</tt> you'll get:</p>
+
+<pre class="output">
+...
+junit:
+ [junit] Running HelloWorldTest
+ [junit] Tests run: 2, Failures: 1, Errors: 0, Time elapsed: 0,01 sec
+ [junit] Test HelloWorldTest FAILED
+
+BUILD SUCCESSFUL
+...
+</pre>
+
+<p>We can also produce a report. Something that you (and other) could read after closing the shell ....
+There are two steps: 1. let &lt;junit&gt; log the information and 2. convert these to something readable (browsable).<p>
+
+<pre class="code">
+ ...
+ <b>&lt;property name="report.dir" value="${build.dir}/junitreport"/&gt;</b>
+ ...
+ &lt;target name="junit" depends="jar"&gt;
+ <b>&lt;mkdir dir="${report.dir}"/&gt;</b>
+ &lt;junit printsummary="yes"&gt;
+ &lt;classpath&gt;
+ &lt;path refid="classpath"/&gt;
+ &lt;path refid="application"/&gt;
+ &lt;/classpath&gt;
+
+ <b>&lt;formatter type="xml"/&gt;</b>
+
+ &lt;batchtest fork="yes" <b>todir="${report.dir}"</b>&gt;
+ &lt;fileset dir="${src.dir}" includes="*Test.java"/&gt;
+ &lt;/batchtest&gt;
+ &lt;/junit&gt;
+ &lt;/target&gt;
+
+ <b>&lt;target name="junitreport"&gt;
+ &lt;junitreport todir="${report.dir}"&gt;
+ &lt;fileset dir="${report.dir}" includes="TEST-*.xml"/&gt;
+ &lt;report todir="${report.dir}"/&gt;
+ &lt;/junitreport&gt;
+ &lt;/target&gt;</b>
+</pre>
+
+<p>Because we would produce a lot of files and these files would be written to the current directory by default,
+we define a report directory, create it before running the <tt>junit</tt> and redirect the logging to it. The log format
+is XML so <tt>junitreport</tt> could parse it. In a second target <tt>junitreport</tt> should create a browsable
+HTML-report for all generated xml-log files in the report directory. Now you can open the ${report.dir}\index.html and
+see the result (looks something like JavaDoc).<br>
+Personally I use two different targets for junit and junitreport. Generating the HTML report needs some time and you dont
+need the HTML report just for testing, e.g. if you are fixing an error or a integration server is doing a job.
+</p>
+
+
+
+
+<a name="resources"></a>
+<h2>Resources</h2>
+<pre>
+ [1] <a href="http://www.apache.org/dist/logging/log4j/1.2.13/logging-log4j-1.2.13.zip">http://www.apache.org/dist/logging/log4j/1.2.13/logging-log4j-1.2.13.zip</a>
+ [2] <a href="http://logging.apache.org/log4j/docs/manual.html">http://logging.apache.org/log4j/docs/manual.html</a>
+ [3] <a href="http://www.junit.org/index.htm">http://www.junit.org/index.htm</a>
+</pre>
+
+
+
+
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/tutorial-tasks-filesets-properties.html b/framework/src/ant/apache-ant-1.9.6/manual/tutorial-tasks-filesets-properties.html
new file mode 100644
index 00000000..3a36e7ef
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/tutorial-tasks-filesets-properties.html
@@ -0,0 +1,993 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+<head>
+ <link rel="stylesheet" type="text/css" href="stylesheets/style.css">
+ <title>Tutorial: Tasks using Properties, Filesets &amp; Paths</title>
+</head>
+<body>
+<h1>Tutorial: Tasks using Properties, Filesets &amp; Paths</h1>
+
+<p>After reading the tutorial about <a href="tutorial-writing-tasks.html">writing
+tasks [1]</a> this tutorial explains how to get and set properties and how to use
+nested filesets and paths. Finally it explains how to contribute tasks to Apache Ant.</p>
+
+<h2>Content</h2>
+<p><ul>
+<li><a href="#goal">The goal</a></li>
+<li><a href="#buildenvironment">Build environment</a></li>
+<li><a href="#propertyaccess">Property access</a></li>
+<li><a href="#filesets">Using filesets</a></li>
+<li><a href="#path">Using nested paths</a></li>
+<li><a href="#returning-list">Returning a list</a></li>
+<li><a href="#documentation">Documentation</a></li>
+<li><a href="#contribute">Contribute the new task</a></li>
+<li><a href="#resources">Resources</a></li>
+</ul></p>
+
+
+<h2><a name="goal">The goal</a></h2>
+<p>The goal is to write a task, which searchs in a path for a file and saves the
+location of that file in a property.</p>
+
+
+<h2><a name="buildenvironment">Build environment</a></h2>
+<p>We can use the buildfile from the other tutorial and modify it a little bit.
+That's the advantage of using properties - we can reuse nearly the whole script. :-)</p>
+<pre class="code">
+&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;
+&lt;project name="<b>FindTask</b>" basedir="." default="test"&gt;
+ ...
+ &lt;target name="use.init" description="Taskdef's the <b>Find</b>-Task" depends="jar"&gt;
+ &lt;taskdef name="<b>find</b>" classname="<b>Find</b>" classpath="${ant.project.name}.jar"/&gt;
+ &lt;/target&gt;
+
+ <b>&lt;!-- the other use.* targets are deleted --&gt;</b>
+ ...
+&lt;/project&gt;
+</pre>
+
+<p>The buildfile is in the archive <a href="tutorial-tasks-filesets-properties.zip">
+tutorial-tasks-filesets-properties.zip [2]</a> in <tt>/build.xml.01-propertyaccess</tt>
+(future version saved as *.02..., final version as build.xml; same for sources).</p>
+
+
+<h2><a name="propertyaccess">Property access</a></h2>
+<p>Our first step is to set a property to a value and print the value of that property.
+So our scenario would be
+<pre class="code">
+ &lt;find property="test" value="test-value"/&gt;
+ &lt;find print="test"/&gt;
+</pre>
+ok, can be rewritten with the core tasks
+<pre class="code">
+ &lt;property name="test" value="test-value"/&gt;
+ &lt;echo message="${test}"/&gt;
+</pre>
+but I have to start on known ground :-)</p>
+<p>So what to do? Handling three attributes (property, value, print) and an execute method.
+Because this is only an introduction example I don't do much checking:
+
+<pre class="code">
+import org.apache.tools.ant.BuildException;
+
+public class Find extends Task {
+
+ private String property;
+ private String value;
+ private String print;
+
+ public void setProperty(String property) {
+ this.property = property;
+ }
+
+ // setter for value and print
+
+ public void execute() {
+ if (print != null) {
+ String propValue = <b>getProject().getProperty(print)</b>;
+ log(propValue);
+ } else {
+ if (property == null) throw new BuildException("property not set");
+ if (value == null) throw new BuildException("value not set");
+ <b>getProject().setNewProperty(property, value)</b>;
+ }
+ }
+}
+</pre>
+
+As said in the other tutorial, the property access is done via Project instance.
+We get this instance via the public <tt>getProject()</tt> method which we inherit from
+<tt>Task</tt> (more precise from ProjectComponent). Reading a property is done via
+<tt>getProperty(<i>propertyname</i>)</tt> (very simple, isn't it?). This property returns
+the value as String or <i>null</i> if not set.<br>
+Setting a property is ... not really difficult, but there is more than one setter. You can
+use the <tt>setProperty()</tt> method which will do the job like expected. But there is
+a golden rule in Ant: <i>properties are immutable</i>. And this method sets the property
+to the specified value - whether it has a value before that or not. So we use another
+way. <tt>setNewProperty()</tt> sets the property only if there is no property with that
+name. Otherwise a message is logged.</p>
+
+<p><i>(by the way: a short word to ants "namespaces" (don't
+be confused with xml namespaces:
+an <code>&lt;antcall&gt;</code> creates a new space for property names. All properties from the caller
+are passed to the callee, but the callee can set its own properties without notice by the
+caller.)</i></p>
+
+<p>There are some other setter, too (but I haven't used them, so I can't say something
+to them, sorry :-)</p>
+
+<p>After putting our two line example from above into a target names <tt>use.simple</tt>
+we can call that from our testcase:
+
+<pre class="code">
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.Before;
+import org.junit.Assert;
+import org.apache.tools.ant.BuildFileRule;
+
+
+public class FindTest {
+
+ @Rule
+ public final BuildFileRule buildRule = new BuildFileRule();
+
+
+ @Before
+ public void setUp() {
+ configureProject("build.xml");
+ }
+
+ @Test
+ public void testSimple() {
+ buildRule.executeTarget("useSimgle");
+ <b>Assert.assertEquals("test-value", buildRule.getLog());</b>
+ }
+}
+</pre>
+
+and all works fine.</p>
+
+
+
+<h2><a name="filesets">Using filesets</a></h2>
+<p>Ant provides a common way of bundling files: the fileset. Because you are reading
+this tutorial I think you know them and I don't have to spend more explanations about
+their usage in buildfiles. Our goal is to search a file in path. And on this step the
+path is simply a fileset (or more precise: a collection of filesets). So our usage
+would be
+<pre class="code">
+ &lt;find file="ant.jar" location="location.ant-jar"&gt;
+ &lt;fileset dir="${ant.home}" includes="**/*.jar"/&gt;
+ &lt;/find&gt;
+</pre>
+</p>
+
+<p>What do we need? A task with two attributes (file, location) and nested
+filesets. Because we had attribute handling already explained in the example above and the
+handling of nested elements is described in the other tutorial the code should be very easy:
+<pre class="code">
+public class Find extends Task {
+
+ private String file;
+ private String location;
+ private Vector filesets = new Vector();
+
+ public void setFile(String file) {
+ this.file = file;
+ }
+
+ public void setLocation(String location) {
+ this.location = location;
+ }
+
+ public void addFileset(FileSet fileset) {
+ filesets.add(fileset);
+ }
+
+ public void execute() {
+ }
+}
+</pre>
+Ok - that task wouldn't do very much, but we can use it in the described manner without
+failure. On next step we have to implement the execute method. And before that we will
+implement the appropriate testcases (TDD - test driven development).</p>
+
+<p>In the other tutorial we have reused the already written targets of our buildfile.
+Now we will configure most of the testcases via java code (sometimes it's much easier
+to write a target than doing it via java coding). What can be tested?<ul>
+<li>not valid configured task (missing file, missing location, missing fileset)</li>
+<li>don't find a present file</li>
+<li>behaviour if file can't be found</li>
+</ul>
+Maybe you find some more testcases. But this is enough for now.<br>
+For each of these points we create a <tt>testXX</tt> method.</p>
+
+<pre class="code">
+public class FindTest {
+
+ @Rule
+ public final BuildFileRule buildRule = new BuildFileRule();
+
+ ... // constructor, setUp as above
+
+ @Test
+ public void testMissingFile() {
+ <b>Find find = new Find();</b>
+ try {
+ <b>find.execute();</b>
+ fail("No 'no-file'-exception thrown.");
+ } catch (Exception e) {
+ // exception expected
+ String expected = "file not set";
+ assertEquals("Wrong exception message.", expected, e.getMessage());
+ }
+ }
+
+ @Test
+ public void testMissingLocation() {
+ Find find = new Find();
+ <b>find.setFile("ant.jar");</b>
+ try {
+ find.execute();
+ fail("No 'no-location'-exception thrown.");
+ } catch (Exception e) {
+ ... // similar to testMissingFile()
+ }
+ }
+
+ @Test
+ public void testMissingFileset() {
+ Find find = new Find();
+ find.setFile("ant.jar");
+ find.setLocation("location.ant-jar");
+ try {
+ find.execute();
+ fail("No 'no-fileset'-exception thrown.");
+ } catch (Exception e) {
+ ... // similar to testMissingFile()
+ }
+ }
+
+ @Test
+ public void testFileNotPresent() {
+ buildRule.executeTarget("testFileNotPresent");
+ String result = buildRule.getProject().getProperty("location.ant-jar");
+ assertNull("Property set to wrong value.", result);
+ }
+
+ @Test
+ public void testFilePresent() {
+ buildRule.executeTarget("testFilePresent");
+ String result = buildRule.getProject().getProperty("location.ant-jar");
+ assertNotNull("Property not set.", result);
+ assertTrue("Wrong file found.", result.endsWith("ant.jar"));
+ }
+}
+</pre>
+
+<p>If we run this test class all test cases (except <i>testFileNotPresent</i>) fail. Now we
+can implement our task, so that these test cases will pass.</p>
+
+<pre class="code">
+ protected void validate() {
+ if (file==null) throw new BuildException("file not set");
+ if (location==null) throw new BuildException("location not set");
+ if (filesets.size()&lt;1) throw new BuildException("fileset not set");
+ }
+
+ public void execute() {
+ validate(); // 1
+ String foundLocation = null;
+ for(Iterator itFSets = filesets.iterator(); itFSets.hasNext(); ) { // 2
+ FileSet fs = (FileSet)itFSets.next();
+ DirectoryScanner ds = fs.getDirectoryScanner(getProject()); // 3
+ String[] includedFiles = ds.getIncludedFiles();
+ for(int i=0; i&lt;includedFiles.length; i++) {
+ String filename = includedFiles[i].replace('\\','/'); // 4
+ filename = filename.substring(filename.lastIndexOf("/")+1);
+ if (foundLocation==null &amp;&amp; file.equals(filename)) {
+ File base = ds.getBasedir(); // 5
+ File found = new File(base, includedFiles[i]);
+ foundLocation = found.getAbsolutePath();
+ }
+ }
+ }
+ if (foundLocation!=null) // 6
+ getProject().setNewProperty(location, foundLocation);
+ }
+</pre>
+
+<p>On <b>//1</b> we check the prerequisites for our task. Doing that in a <tt>validate</tt>-method
+is a common way, because we separate the prerequisites from the real work. On <b>//2</b> we iterate
+over all nested filesets. If we don't want to handle multiple filesets, the <tt>addFileset()</tt>
+method has to reject the further calls. We can get the result of a fileset via its DirectoryScanner
+like done in <b>//3</b>. After that we create a platform independent String representation of
+the file path (<b>//4</b>, can be done in other ways of course). We have to do the <tt>replace()</tt>,
+because we work with a simple string comparison. Ant itself is platform independent and can
+therefore run on filesystems with slash (/, e.g. Linux) or backslash (\, e.g. Windows) as
+path separator. Therefore we have to unify that. If we found our file we create an absolute
+path representation on <b>//5</b>, so that we can use that information without knowing the basedir.
+(This is very important on use with multiple filesets, because they can have different basedirs
+and the return value of the directory scanner is relative to its basedir.) Finally we store the
+location of the file as property, if we had found one (<b>//6</b>).</p>
+
+<p>Ok, much more easier in this simple case would be to add the <i>file</i> as additional
+<i>include</i> element to all filesets. But I wanted to show how to handle complex situations
+without being complex :-)</p>
+
+<p>The test case uses the ant property <i>ant.home</i> as reference. This property is set by the
+<tt>Launcher</tt> class which starts ant. We can use that property in our buildfiles as a
+<a href="properties.html#built-in-props">build-in property [3]</a>. But if we create a new ant
+environment we have to set that value for our own. And we use the <code>&lt;junit&gt;</code> task in fork-mode.
+Therefore we have do modify our buildfile:
+<pre class="code">
+ &lt;target name="junit" description="Runs the unit tests" depends="jar"&gt;
+ &lt;delete dir="${junit.out.dir.xml}"/&gt;
+ &lt;mkdir dir="${junit.out.dir.xml}"/&gt;
+ &lt;junit printsummary="yes" haltonfailure="no"&gt;
+ &lt;classpath refid="classpath.test"/&gt;
+ <b>&lt;sysproperty key="ant.home" value="${ant.home}"/&gt;</b>
+ &lt;formatter type="xml"/&gt;
+ &lt;batchtest fork="yes" todir="${junit.out.dir.xml}"&gt;
+ &lt;fileset dir="${src.dir}" includes="**/*Test.java"/&gt;
+ &lt;/batchtest&gt;
+ &lt;/junit&gt;
+ &lt;/target&gt;
+</pre>
+
+
+<h2><a name="path">Using nested paths</a></h2>
+<p>A task providing support for filesets is a very comfortable one. But there is another
+possibility of bundling files: the <code>&lt;path&gt;</code>. Fileset are easy if the files are all under
+a common base directory. But if this is not the case you have a problem. Another disadvantage
+is its speed: if you have only a few files in a huge directory structure, why not use a
+<code>&lt;filelist&gt;</code> instead? <code>&lt;path&gt;</code>s combines these datatypes in that way that a path contains
+other paths, filesets, dirsets and filelists. This is why <a href="http://ant-contrib.sourceforge.net/">
+Ant-Contribs [4]</a> <code>&lt;foreach&gt;</code> task is modified to support paths instead of filesets. So we want that,
+too.</p>
+
+<p>Changing from fileset to path support is very easy:</p>
+<pre class="code">
+<i><b>Change java code from:</b></i>
+ private Vector filesets = new Vector();
+ public void addFileset(FileSet fileset) {
+ filesets.add(fileset);
+ }
+<i><b>to:</b></i>
+ private Vector paths = new Vector(); *1
+ public void add<b>Path</b>(<b>Path</b> path) { *2
+ paths.add(path);
+ }
+<i><b>and build file from:</b></i>
+ &lt;find file="ant.jar" location="location.ant-jar"&gt;
+ &lt;fileset dir="${ant.home}" includes="**/*.jar"/&gt;
+ &lt;/find&gt;
+<i><b>to:</b></i>
+ &lt;find file="ant.jar" location="location.ant-jar"&gt;
+ <b>&lt;path&gt;</b> *3
+ &lt;fileset dir="${ant.home}" includes="**/*.jar"/&gt;
+ &lt;/path&gt;
+ &lt;/find&gt;
+</pre>
+<p>On <b>*1</b> we rename only the vector. It�s just for better reading the source. On <b>*2</b>
+we have to provide the right method: an add<i>Name</i>(<i>Type</i> t). Therefore replace the
+fileset with path here. Finally we have to modify our buildfile on <b>*3</b> because our task
+doesn�t support nested filesets any longer. So we wrap the fileset inside a path.</p>
+
+<p>And now we modify the testcase. Oh, not very much to do :-) Renaming the <tt>testMissingFileset()</tt>
+(not really a <i>must-be</i> but better it�s named like the think it does) and update the
+<i>expected</i>-String in that method (now a <tt>path not set</tt> message is expected). The more complex
+test cases base on the buildscript. So the targets <tt>testFileNotPresent</tt> and <tt>testFilePresent</tt> have to be
+modified in the manner described above.</p>
+
+<p>The test are finished. Now we have to adapt the task implementation. The easiest modification is
+in the <tt>validate()</tt> method where we change le last line to <tt>if (paths.size()&lt;1) throw new
+BuildException("path not set");</tt>. In the <tt>execute()</tt> method we have a little more work.
+... mmmh ... in reality it's lesser work, because the Path class does the whole DirectoryScanner-handling
+and creating-absolute-paths stuff for us. So the execute method is just:</p>
+
+<pre class="code">
+ public void execute() {
+ validate();
+ String foundLocation = null;
+ for(Iterator itPaths = paths.iterator(); itPaths.hasNext(); ) {
+ Path path = (<b>Path</b>)itPaths.next(); // 1
+ String[] includedFiles = <b>path.list()</b>; // 2
+ for(int i=0; i&lt;includedFiles.length; i++) {
+ String filename = includedFiles[i].replace('\\','/');
+ filename = filename.substring(filename.lastIndexOf("/")+1);
+ if (foundLocation==null &amp;&amp; file.equals(filename)) {
+ <b>foundLocation = includedFiles[i];</b> // 3
+ }
+ }
+ }
+ if (foundLocation!=null)
+ getProject().setNewProperty(location, foundLocation);
+ }
+</pre>
+
+<p>Of course we have to do the typecase to Path on <b>//1</b>. On <b>//2</b> and <b>//3</b>
+we see that the Path class does the work for us: no DirectoryScanner (was at 2) and no
+creating of the absolute path (was at 3).</p>
+
+
+
+<h2><a name="returning-list">Returning a list</a></h2>
+<p>So far so good. But could a file be on more than one place in the path? - Of course.<br>
+And would it be good to get all of them? - It depends on ...<p>
+
+<p>In this section we will extend that task to support returning a list of all files.
+Lists as property values are not supported by Ant natively. So we have to see how other
+tasks use lists. The most famous task using lists is Ant-Contribs <code>&lt;foreach&gt;</code>. All list
+elements are concatenated and separated with a customizable separator (default ',').</p>
+
+<p>So we do the following:</p>
+
+<pre class="code">
+ &lt;find ... <b>delimiter=""</b>/&gt; ... &lt;/find&gt;
+</pre>
+
+<p>If the delimiter is set we will return all found files as list with that delimiter.</p>
+
+<p>Therefore we have to<ul>
+<li>provide a new attribute</li>
+<li>collect more than the first file</li>
+<li>delete duplicates</li>
+<li>create the list if necessary</li>
+<li>return that list</li>
+</ul></p>
+
+<p>So we add as testcase:</p>
+<pre class="code">
+<b><i>in the buildfile:</i></b>
+ &lt;target name="test.init"&gt;
+ &lt;mkdir dir="test1/dir11/dir111"/&gt; *1
+ &lt;mkdir dir="test1/dir11/dir112"/&gt;
+ ...
+ &lt;touch file="test1/dir11/dir111/test"/&gt;
+ &lt;touch file="test1/dir11/dir111/not"/&gt;
+ ...
+ &lt;touch file="test1/dir13/dir131/not2"/&gt;
+ &lt;touch file="test1/dir13/dir132/test"/&gt;
+ &lt;touch file="test1/dir13/dir132/not"/&gt;
+ &lt;touch file="test1/dir13/dir132/not2"/&gt;
+ &lt;mkdir dir="test2"/&gt;
+ &lt;copy todir="test2"&gt; *2
+ &lt;fileset dir="test1"/&gt;
+ &lt;/copy&gt;
+ &lt;/target&gt;
+
+ &lt;target name="testMultipleFiles" depends="use.init,<b>test.init</b>"&gt; *3
+ &lt;find file="test" location="location.test" <b>delimiter=";"</b>&gt;
+ &lt;path&gt;
+ &lt;fileset dir="test1"/&gt;
+ &lt;fileset dir="test2"/&gt;
+ &lt;/path&gt;
+ &lt;/find&gt;
+ &lt;delete&gt; *4
+ &lt;fileset dir="test1"/&gt;
+ &lt;fileset dir="test2"/&gt;
+ &lt;/delete&gt;
+ &lt;/target&gt;
+
+<b><i>in the test class:</i></b>
+ public void testMultipleFiles() {
+ executeTarget("testMultipleFiles");
+ String result = getProject().getProperty("location.test");
+ assertNotNull("Property not set.", result);
+ assertTrue("Only one file found.", result.indexOf(";") &gt; -1);
+ }
+</pre>
+
+<p>Now we need a directory structure where we CAN find files with the same
+name in different directories. Because we can't sure to have one we create
+one on <b>*1</b> and <b>*2</b>. And of course we clean up that on <b>*4</b>. The creation
+can be done inside our test target or in a separate one, which will be better
+for reuse later (<b>*3</b>).
+
+<p>The task implementation is modified as followed:</p>
+
+<pre class="code">
+ private Vector foundFiles = new Vector();
+ ...
+ private String delimiter = null;
+ ...
+ public void setDelimiter(String delim) {
+ delimiter = delim;
+ }
+ ...
+ public void execute() {
+ validate();
+ // find all files
+ for(Iterator itPaths = paths.iterator(); itPaths.hasNext(); ) {
+ Path path = (Path)itPaths.next();
+ String[] includedFiles = path.list();
+ for(int i=0; i&lt;includedFiles.length; i++) {
+ String filename = includedFiles[i].replace('\\','/');
+ filename = filename.substring(filename.lastIndexOf("/")+1);
+ if (file.equals(filename) &amp;&amp; <b>!foundFiles.contains(includedFiles[i]</b>)) { // 1
+ foundFiles.add(includedFiles[i]);
+ }
+ }
+ }
+
+ // create the return value (list/single)
+ String rv = null;
+ if (foundFiles.size() &gt; 0) { // 2
+ if (delimiter==null) {
+ // only the first
+ rv = (String)foundFiles.elementAt(0);
+ } else {
+ // create list
+ StringBuffer list = new StringBuffer();
+ for(Iterator it=foundFiles.iterator(); it.hasNext(); ) { // 3
+ list.append(it.next());
+ if (<b>it.hasNext()</b>) list.append(delimiter); // 4
+ }
+ rv = list.toString();
+ }
+ }
+
+ // create the property
+ if (rv!=null)
+ getProject().setNewProperty(location, rv);
+ }
+</pre>
+
+<p>The algorithm does: finding all files, creating the return value depending on the users
+wish, returning the value as property. On <b>//1</b> we eliminates the duplicates. <b>//2</b>
+ensures that we create the return value only if we have found one file. On <b>//3</b> we
+iterate over all found files and <b>//4</b> ensures that the last entry has no trailing
+delimiter.</p>
+
+<p>Ok, first searching for all files and then returning only the first one ... You can
+tune the performance of your own :-)</p>
+
+
+<h2><a name="documentation">Documentation</a></h2>
+<p>A task is useless if the only who is able to code the buildfile is the task developer
+(and he only the next few weeks :-). So documentation is also very important. In which
+form you do that depends on your favourite. But inside Ant there is a common format and
+it has advantages if you use that: all task users know that form, this form is requested if
+you decide to contribute your task. So we will doc our task in that form.</p>
+
+<p>If you have a look at the manual page of the <a href="Tasks/java.html">Java task [5]</a>
+ you will see that it:<ul>
+<li>is plain html</li>
+<li>starts with the name</li>
+<li>has sections: description, parameters, nested elements, (maybe return codes) and (most
+important :-) examples</li>
+<li>parameters are listed in a table with columns for attribute name, its description and whether
+ it's required (if you add a feature after an Ant release, provide a <tt>since Ant xx</tt>
+ statement when it's introduced)</li>
+<li>describe the nested elements (since-statement if necessary)</li>
+<li>provide one or more useful examples; first code, then description.</li>
+</ul>
+As a template we have:
+
+<pre class="code">
+&lt;html&gt;
+
+&lt;head&gt;
+&lt;meta http-equiv="Content-Language" content="en-us"&gt;
+&lt;title&gt;<b>Taskname</b> Task&lt;/title&gt;
+&lt;/head&gt;
+
+&lt;body&gt;
+
+&lt;h2&gt;&lt;a name="<b>taskname</b>"&gt;<b>Taskname</b>&lt;/a&gt;&lt;/h2&gt;
+&lt;h3&gt;Description&lt;/h3&gt;
+&lt;p&gt; <b>Describe the task.</b>&lt;/p&gt;
+
+&lt;h3&gt;Parameters&lt;/h3&gt;
+&lt;table border="1" cellpadding="2" cellspacing="0"&gt;
+ &lt;tr&gt;
+ &lt;td valign="top"&gt;&lt;b&gt;Attribute&lt;/b&gt;&lt;/td&gt;
+ &lt;td valign="top"&gt;&lt;b&gt;Description&lt;/b&gt;&lt;/td&gt;
+ &lt;td align="center" valign="top"&gt;&lt;b&gt;Required&lt;/b&gt;&lt;/td&gt;
+ &lt;/tr&gt;
+
+ <b>do this html row for each attribute (including inherited attributes)</b>
+ &lt;tr&gt;
+ &lt;td valign="top"&gt;classname&lt;/td&gt;
+ &lt;td valign="top"&gt;the Java class to execute.&lt;/td&gt;
+ &lt;td align="center" valign="top"&gt;Either jar or classname&lt;/td&gt;
+ &lt;/tr&gt;
+
+&lt;/table&gt;
+
+&lt;h3&gt;Parameters specified as nested elements&lt;/h3&gt;
+
+<b>Describe each nested element (including inherited)</b>
+&lt;h4&gt;<b>your nested element</b>&lt;/h4&gt;
+&lt;p&gt;<b>description</b>&lt;/p&gt;
+&lt;p&gt;&lt;em&gt;since Ant 1.6&lt;/em&gt;.&lt;/p&gt;
+
+&lt;h3&gt;Examples&lt;/h3&gt;
+&lt;pre&gt;
+ <b>A code sample; don't forget to escape the &lt; of the tags with &amp;lt;</b>
+&lt;/pre&gt;
+<b>What should that example do?</b>
+
+&lt;/body&gt;
+&lt;/html&gt;
+</pre>
+
+<p>Here is an example documentation page for our task:</p>
+<pre class="code">
+&lt;html&gt;
+
+&lt;head&gt;
+&lt;meta http-equiv="Content-Language" content="en-us"&gt;
+&lt;title&gt;Find Task&lt;/title&gt;
+&lt;/head&gt;
+
+&lt;body&gt;
+
+&lt;h2&gt;&lt;a name="find"&gt;Find&lt;/a&gt;&lt;/h2&gt;
+&lt;h3&gt;Description&lt;/h3&gt;
+&lt;p&gt;Searchs in a given path for a file and returns the absolute to it as property.
+If delimiter is set this task returns all found locations.&lt;/p&gt;
+
+&lt;h3&gt;Parameters&lt;/h3&gt;
+&lt;table border="1" cellpadding="2" cellspacing="0"&gt;
+ &lt;tr&gt;
+ &lt;td valign="top"&gt;&lt;b&gt;Attribute&lt;/b&gt;&lt;/td&gt;
+ &lt;td valign="top"&gt;&lt;b&gt;Description&lt;/b&gt;&lt;/td&gt;
+ &lt;td align="center" valign="top"&gt;&lt;b&gt;Required&lt;/b&gt;&lt;/td&gt;
+ &lt;/tr&gt;
+ &lt;tr&gt;
+ &lt;td valign="top"&gt;file&lt;/td&gt;
+ &lt;td valign="top"&gt;The name of the file to search.&lt;/td&gt;
+ &lt;td align="center" valign="top"&gt;yes&lt;/td&gt;
+ &lt;/tr&gt;
+ &lt;tr&gt;
+ &lt;td valign="top"&gt;location&lt;/td&gt;
+ &lt;td valign="top"&gt;The name of the property where to store the location&lt;/td&gt;
+ &lt;td align="center" valign="top"&gt;yes&lt;/td&gt;
+ &lt;/tr&gt;
+ &lt;tr&gt;
+ &lt;td valign="top"&gt;delimiter&lt;/td&gt;
+ &lt;td valign="top"&gt;A delimiter to use when returning the list&lt;/td&gt;
+ &lt;td align="center" valign="top"&gt;only if the list is required&lt;/td&gt;
+ &lt;/tr&gt;
+&lt;/table&gt;
+
+&lt;h3&gt;Parameters specified as nested elements&lt;/h3&gt;
+
+&lt;h4&gt;path&lt;/h4&gt;
+&lt;p&gt;The path where to search the file.&lt;/p&gt;
+
+&lt;h3&gt;Examples&lt;/h3&gt;
+&lt;pre&gt;
+ &lt;find file="ant.jar" location="loc"&gt;
+ &lt;path&gt;
+ &lt;fileset dir="${ant.home}"/&gt;
+ &lt;path&gt;
+ &lt;/find&gt;
+&lt;/pre&gt;
+Searches in Ants home directory for a file &lt;i&gt;ant.jar&lt;/i&gt; and stores its location in
+property &lt;i&gt;loc&lt;/i&gt; (should be ANT_HOME/bin/ant.jar).
+
+&lt;pre&gt;
+ &lt;find file="ant.jar" location="loc" delimiter=";"&gt;
+ &lt;path&gt;
+ &lt;fileset dir="C:/"/&gt;
+ &lt;path&gt;
+ &lt;/find&gt;
+ &lt;echo&gt;ant.jar found in: ${loc}&lt;/echo&gt;
+&lt;/pre&gt;
+Searches in Windows C: drive for all &lt;i&gt;ant.jar&lt;/i&gt; and stores their locations in
+property &lt;i&gt;loc&lt;/i&gt; delimited with &lt;i&gt;';'&lt;/i&gt;. (should need a long time :-)
+After that it prints out the result (e.g. C:/ant-1.5.4/bin/ant.jar;C:/ant-1.6/bin/ant.jar).
+
+&lt;/body&gt;
+&lt;/html&gt;
+</pre>
+
+
+<h2><a name="contribute">Contribute the new task</a></h2>
+If we decide to contribute our task, we should do some things:<ul>
+<li>is our task welcome? :-) Simply ask on the user list</li>
+<li>is the right package used? </li>
+<li>does the code conform to the styleguide?</li>
+<li>do all tests pass? </li>
+<li>does the code compile on JDK 1.2 (and passes all tests there)?</li>
+<li>code under Apache license</li>
+<li>create a patch file</li>
+<li>publishing that patch file</li>
+</ul>
+The <a href="http://ant.apache.org/ant_task_guidelines.html">Ant Task Guidelines [6]</a> support additional
+information on that.</p>
+
+<p>Now we will check the "Checklist before submitting a new task" described in that guideline.
+<ul>
+<li>Java file begins with Apache license statement. <b><i>must do that</i></b></li>
+<li>Task does not depend on GPL or LGPL code. <b><i>ok</i></b></li>
+<li>Source code complies with style guidelines <b><i>have to check (checkstyle)</i></b></li>
+<li>Code compiles and runs on Java1.2 <b><i>have to try</i></b></li>
+<li>Member variables are private, and provide public accessor methods
+ if access is actually needed. <b><i>have to check (checkstyle)</i></b></li>
+<li><i>Maybe</i> Task has failonerror attribute to control failure behaviour <b><i>hasn't</i></b></li>
+<li>New test cases written and succeed <b><i>passed on JDK 1.4, have to try on JDK 1.2</i></b></li>
+<li>Documentation page written <b><i>ok</i></b></li>
+<li>Example task declarations in the documentation tested. <b><i>ok (used in tests)</i></b></li>
+<li>Patch files generated using cvs diff -u <b><i>to do</i></b></li>
+<li>patch files include a patch to defaults.properties to register the
+tasks <b><i>to do</i></b></li>
+<li>patch files include a patch to tasklist.html to link to the new task page <b><i>to do</i></b></li>
+<li>Message to dev contains [SUBMIT] and task name in subject <b><i>to do</i></b></li>
+<li>Message body contains a rationale for the task <b><i>to do</i></b></li>
+<li>Message attachments contain the required files -source, documentation,
+test and patches zipped up to escape the HTML filter. <b><i>to do</i></b></li>
+</ul>
+
+
+<h3>Package / Directories</h3>
+<p>This task does not depend on any external library. Therefore we can use this as
+a core task. This task contains only one class. So we can use the standard package
+for core tasks: <tt>org.apache.tools.ant.taskdefs</tt>. Implementations are in the
+directory <tt>src/main</tt>, tests in <tt>src/testcases</tt> and buildfiles for
+tests in <tt>src/etc/testcases</tt>.</p>
+
+<p>Now we integrate our work into Ants distribution. So first we do an update of our
+cvs tree. If not done yet, you have to checkout the ant module from Apaches cvs server
+as described in <a href="http://ant.apache.org/cvs.html">Access the Source Tree (AnonCVS)
+[7]</a> (password is <i>anoncvs</i>):<pre class="output">
+cvs -d :pserver:anoncvs@cvs.apache.org:/home/cvspublic login //1
+cvs -d :pserver:anoncvs@cvs.apache.org:/home/cvspublic checkout ant //2
+</pre>
+If you have a local copy of Ants sources just do an update
+<pre class="output">
+cvs -d :pserver:anoncvs@cvs.apache.org:/home/cvspublic login
+cd ant //3
+cvs -d :pserver:anoncvs@cvs.apache.org:/home/cvspublic update //4
+</pre></p>
+
+<p>We use the <i>-d</i> flag on <b>//1</b> to specify the cvs directory. You can
+specify the environment variable CVSROOT with that value and after that you haven�t
+to use that flag any more. On <b>//2</b> we get the whole cvs tree of ant. (Sorry,
+but that uses a lot of time ... 10 up to 30 minutes are not unusual ... but this has
+to be done only once :-). A cvs update doesn't use a modulename but you have to be
+inside the directory. Therefore we go into that on <b>//3</b> and do the update
+on <b>//4</b>.</p>
+
+<p>Now we will build our Ant distribution and do a test. So we can see if there
+are any tests failing on our machine. (We can ignore these failing tests on later
+steps; windows syntax used here- translate to xNIX if needed):
+<pre class="output">
+ANTHOME&gt; build // 1
+ANTHOME&gt; set ANT_HOME=%CD%\dist // 2
+ANTHOME&gt; ant test -Dtest.haltonfailure=false // 3
+</pre>
+
+First we have to build our Ant distribution (<b>//1</b>). On <b>//2</b> we set the ANT_HOME
+environment variable to the directory where the new created distribution is stored
+(%CD% is expanded to the current directory on Windows 2000 and XP, on 9x and NT
+write it out). On <b>//3</b> we let Ant do all the tests (which enforced a compile
+of all tests) without stopping on first failure.</p>
+
+<p>Next we apply our work onto Ants sources. Because we haven't modified any, this is
+a relative simple step. <i>(Because I have a local copy of Ant and usually contribute my
+work, I work on the local copy just from the beginning. The advantage: this step isn't
+necessary and saves a lot of work if you modify existing source :-)</i>.
+
+<ul>
+<li>move the Find.java to ANTHOME/src/main/org/apache/tools/ant/taskdefs/Find.java </li>
+<li>move the FindTest.java to ANTHOME/src/testcases/org/apache/tools/ant/taskdefs/FindTest.java </li>
+<li>move the build.xml to ANTHOME/src/etc/testcases/taskdefs/<b>find.xml</b> (!!! renamed !!!)</li>
+<li>add a <tt>package org.apache.tools.ant.taskdefs;</tt> at the beginning of the two java files </li>
+<li>delete all stuff from find.xml keeping the targets "testFileNotPresent", "testFilePresent",
+ "test.init" and "testMultipleFiles" </li>
+<li>delete the dependency to "use.init" in the find.xml </li>
+<li>in FindTest.java change the line <tt>configureProject("build.xml");</tt> to
+ <tt>configureProject("src/etc/testcases/taskdefs/find.xml");</tt> </li>
+<li>move the find.html to ANTHOME/docs/manual/Tasks/find.html </li>
+<li>add a <tt>&lt;a href="Tasks/find.html"&gt;Find&lt;/a&gt;&lt;br&gt;</tt>
+ in the ANTHOME/docs/manual/tasklist.html </li>
+</ul>
+
+Now our modifications are done and we will retest it:
+<pre class="output">
+ANTHOME&gt; build
+ANTHOME&gt; ant run-single-test // 1
+ -Dtestcase=org.apache.tools.ant.taskdefs.FindTest // 2
+ -Dtest.haltonfailure=false
+</pre>
+Because we only want to test our new class, we use the target for single tests, specify
+the test to use and configure not to halt on the first failure - we want to see all
+failures of our own test (<b>//1 + 2</b>).</p>
+
+<p>And ... oh, all tests fail: <i>Ant could not find the task or a class this task relies upon.</i></p>
+
+<p>Ok: in the earlier steps we told Ant to use the Find class for the <code>&lt;find&gt;</code> task (remember the
+<code>&lt;taskdef&gt;</code> statement in the "use.init" target). But now we want to introduce that task as
+a core task. And nobody wants to taskdef the javac, echo, ... So what to do? The answer is the
+src/main/.../taskdefs/default.properties. Here is the mapping between taskname and implementing
+class done. So we add a <tt>find=org.apache.tools.ant.taskdefs.Find</tt> as the last core
+task (just before the <tt># optional tasks</tt> line). Now a second try:
+<pre class="output">
+ANTHOME&gt; build // 1
+ANTHOME&gt; ant run-single-test
+ -Dtestcase=org.apache.tools.ant.taskdefs.FindTest
+ -Dtest.haltonfailure=false
+</pre>
+We have to rebuild (<b>//1</b>) Ant because the test look in the %ANT_HOME%\lib\ant.jar
+(more precise: on the classpath) for the properties file. And we have only modified it in the
+source path. So we have to rebuild that jar. But now all tests pass and we check whether our class
+breaks some other tests.
+<pre class="output">
+ANTHOME&gt; ant test -Dtest.haltonfailure=false
+</pre>
+Because there are a lot of tests this step requires a little bit of time. So use the <i>run-single-test</i>
+during development and do the <i>test</i> only at the end (maybe sometimes during development too).
+We use the <i>-Dtest.haltonfailure=false</i> here because there could be other tests fail and we have
+to look into them.</p>
+
+<p>This test run should show us two things: our test will run and the number of failing tests
+is the same as directly after the cvs update (without our modifications).</p>
+
+
+
+<h3>Apache license statement</h3>
+<p>Simply copy the license text from one the other source from the Ant source tree.</p>
+
+
+<h3>Test on JDK 1.2</h3>
+<p>Until version 1.5 Ant must be able to run on a JDK 1.1. With version 1.6 this is not a
+requisite any more. But JDK 1.2 is a must-to-work-with. So we have to test that. You can download older
+JDKs from <a href="http://www.oracle.com/technetwork/java/archive-139210.html">Oracle [8]</a>.</p>
+
+<p>Clean the ANT_HOME variable, delete the <i>build, bootstrap</i> and <i>dist</i> directory
+and point JAVA_HOME to the JDK 1.2 home directory. Then do the <tt>build</tt>, set ANT_HOME
+and run <tt>ant test</tt> (like above).</p>
+
+<p>Our test should pass.</p>
+
+
+
+<h3>Checkstyle</h3>
+<p>There are many things we have to ensure. Indentation with 4 spaces, blanks here and there, ...
+(all described in the <a href="http://ant.apache.org/ant_task_guidelines.html">Ant Task Guidelines [6]</a> which
+includes the <a href="http://www.oracle.com/technetwork/java/codeconvtoc-136057.html">Sun code style
+[9]</a>). Because there are so many things we would be happy to have a tool for do the checks.
+There is one: checkstyle. Checkstyle is available at <a href="http://checkstyle.sourceforge.net/">
+Sourceforge [10]</a> and Ant provides with the <tt>check.xml</tt> a buildfile which will do the job
+for us.</p>
+
+<p>Download it and put the checkstyle-*-all.jar into your %USERPROFILE%\.ant\lib directory.
+All jar's stored there are available to Ant so you haven't to add it to you %ANT_HOME%\lib
+directory (this feature was added with Ant 1.6).</p>
+
+<p>So we will run the tests with
+<pre class="output">
+ANTHOME&gt; ant -f check.xml checkstyle htmlreport
+</pre>
+I prefer the HTML report because there are lots of messages and we can navigate faster.
+Open the ANTHOME/build/reports/checkstyle/html/index.html and navigate to the Find.java. Now we
+see that there are some errors: missing whitespaces, unused imports, missing javadocs. So we have
+to do that.</p>
+
+<p>Hint: start at the <b>buttom</b> of the file so the line numbers in the report will keep
+up to date and you will find the next error place much more easier without redoing the checkstyle.</p>
+
+<p>After cleaning up the code according to the messages we delete the reports directory and
+do a second checkstyle run. Now our task isn't listed. That's fine :-)</p>
+
+
+
+<!--
+ Couldnt create the diff that way for myself, but that should be documented.
+ But on the other hand this tutorial should not be forgotten any longer so I
+ comment that out. JHM
+<h3>Creating the diff</h3>
+<p>Creating a diff for Ant is very easy: just start <tt>ant -f patch.xml</tt> and all is done
+automatically. This step requires a cvs executable in your path and internet access (more precise:
+cvs access). As a result we get a file <i> TODO </i>.</p>
+-->
+
+
+<h3>Publish the task</h3>
+<p>Finally we publish that archive. As described in the <a href="http://ant.apache.org/ant_task_guidelines.html">
+Ant Task Guidelines [7]</a> we can post it on the developer mailinglist or we create a BugZilla
+entry. For both we need some information:</p>
+
+<table border="1">
+<tr>
+ <th>subject</th>
+ <td><i>short description</i></td>
+ <td>Task for finding files in a path</td>
+</tr>
+<tr>
+ <th>body</th>
+ <td><i>more details about the path</i></td>
+ <td>This new task looks inside a nested <code>&lt;path/&gt;</code> for occurrences of a file and stores
+ all locations as a property. See the included manual for details.</td>
+</tr>
+<tr>
+ <th>attachments</th>
+ <td><i>all files needed to apply the path</i></td>
+ <td>Archive containing a patch with the new and modified resources</td>
+</tr>
+</table>
+
+<p>Sending an email with these information is very easy and I think I haven't to show that.
+The other way - BugZilla - is slightly more difficult. But it has the advantage that entries
+will not be forgotten (once per week a report is generated). So I will show this way.</p>
+
+<p>You must have a BugZilla account for that. So open the <a href="http://issues.apache.org/bugzilla/">
+BugZilla Main Page [11]</a> and follow the link
+<a href="http://issues.apache.org/bugzilla/createaccount.cgi">Open a new Bugzilla account [12]</a>
+and the steps described there if you haven't one.</p>
+
+<ol>
+<li>From the BugZilla main page choose <a href="http://issues.apache.org/bugzilla/enter_bug.cgi">Enter
+ a new bug report [13]</a></li>
+<li>Choose "Ant" as product </li>
+<li>Version is the last "Alpha (nightly)" (at this time 1.7)</li>
+<li>Component is "Core tasks"</li>
+<li>Platform and Severity are ok with "Other" and "Normal"</li>
+<li>Initial State is ok with "New"</li>
+<li>Same with the empty "Assigned to"</li>
+<li>It is not required to add yourself as CC, because you are the reporter and therefore will be
+ informed on changes</li>
+<li>URL: no url required</li>
+<li>Summary: add the <i>subject</i> from the table</li>
+<li>Description: add the <i>body</i> from the table</li>
+<li>Then press "Commit"</li>
+<li>After redirecting to the new created bug entry click "Create a New Attachment"</li>
+<li>Enter the path to your local path file into "File" or choose it via the "File"'s
+ button.</li>
+<li>Enter a short description into "Description", so that you could guess, what the
+ path file includes. Here we could add "Initial Patch".</li>
+<li>The "Content Type" is "auto-detect". You could use the "patch" type, if you only
+ provide a single path file, but we want do upload more that one, included in our
+ patch.zip.</li>
+<li>Then press "Commit"</li>
+</ol>
+Now the new task is uploaded into the bug database.
+
+
+<h2><a name="resources">Resources</a></h2>
+&nbsp;&nbsp;[1] <a href="tutorial-writing-tasks.html">tutorial-writing-tasks.html</a><br>
+&nbsp;&nbsp;[2] <a href="tutorial-tasks-filesets-properties.zip">tutorial-tasks-filesets-properties.zip</a><br>
+&nbsp;&nbsp;[3] <a href="properties.html#built-in-props">properties.html#built-in-props</a><br>
+&nbsp;&nbsp;[4] <a href="http://ant-contrib.sourceforge.net/">http://ant-contrib.sourceforge.net/</a><br>
+&nbsp;&nbsp;[5] <a href="Tasks/java.html">Tasks/java.html</a><br>
+&nbsp;&nbsp;[6] <a href="http://ant.apache.org/ant_task_guidelines.html">http://ant.apache.org/ant_task_guidelines.html</a><br>
+&nbsp;&nbsp;[7] <a href="http://ant.apache.org/cvs.html">http://ant.apache.org/cvs.html</a><br>
+&nbsp;&nbsp;[8] <a href="http://www.oracle.com/technetwork/java/archive-139210.html">http://www.oracle.com/technetwork/java/archive-139210.html</a><br>
+&nbsp;&nbsp;[9] <a href="http://www.oracle.com/technetwork/java/codeconvtoc-136057.html">http://www.oracle.com/technetwork/java/codeconvtoc-136057.html</a><br>
+&nbsp;&nbsp;[10] <a href="http://checkstyle.sourceforge.net/">http://checkstyle.sourceforge.net/</a><br>
+&nbsp;&nbsp;[11] <a href="http://issues.apache.org/bugzilla/">http://issues.apache.org/bugzilla/</a><br>
+&nbsp;&nbsp;[12] <a href="http://issues.apache.org/bugzilla/createaccount.cgi">http://issues.apache.org/bugzilla/createaccount.cgi</a><br>
+&nbsp;&nbsp;[13] <a href="http://issues.apache.org/bugzilla/enter_bug.cgi">http://issues.apache.org/bugzilla/enter_bug.cgi</a><br>
+
+
+<!--
+ TODO:
+ - how to create a path (path.xml / command line)
+-->
+
+
+
+
+
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/tutorial-tasks-filesets-properties.zip b/framework/src/ant/apache-ant-1.9.6/manual/tutorial-tasks-filesets-properties.zip
new file mode 100644
index 00000000..94c8a10f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/tutorial-tasks-filesets-properties.zip
Binary files differ
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/tutorial-writing-tasks-src.zip b/framework/src/ant/apache-ant-1.9.6/manual/tutorial-writing-tasks-src.zip
new file mode 100644
index 00000000..3567c3bc
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/tutorial-writing-tasks-src.zip
Binary files differ
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/tutorial-writing-tasks.html b/framework/src/ant/apache-ant-1.9.6/manual/tutorial-writing-tasks.html
new file mode 100644
index 00000000..c3b8a6a8
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/tutorial-writing-tasks.html
@@ -0,0 +1,819 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+<head>
+ <title>Tutorial: Writing Tasks</title>
+ <link rel="stylesheet" type="text/css" href="stylesheets/style.css" />
+</head>
+<body>
+<h1>Tutorial: Writing Tasks</h1>
+
+<p>This document provides a step by step tutorial for writing
+tasks.</p>
+<h2>Content</h2>
+<ul>
+<li><a href="#buildenvironment">Set up the build environment</a></li>
+<li><a href="#write1">Write the Task</a></li>
+<li><a href="#use1">Use the Task</a></li>
+<li><a href="#TaskAdapter">Integration with TaskAdapter</a></li>
+<li><a href="#derivingFromTask">Deriving from Apache Ant's Task</a></li>
+<li><a href="#accessTaskProject">Accessing the Task's Project</a></li>
+<li><a href="#attributes">Attributes</a></li>
+<li><a href="#NestedText">Nested Text</a></li>
+<li><a href="#NestedElements">Nested Elements</a></li>
+<li><a href="#complex">Our task in a little more complex version</a></li>
+<li><a href="#TestingTasks">Test the Task</a></li>
+<li><a href="#Debugging">Debugging</a></li>
+<li><a href="#resources">Resources</a></li>
+</ul>
+
+<a name="buildenvironment"></a>
+<h2>Set up the build environment</h2>
+<p>Apache Ant builds itself, we are using Ant too (why we would write
+a task if not? :-) therefore we should use Ant for our build.</p>
+<p>We choose a directory as root directory. All things will be done
+here if I say nothing different. I will reference this directory
+as <i>root-directory</i> of our project. In this root-directory we
+create a text file names <i>build.xml</i>. What should Ant do for us?</p>
+<ul>
+<li>compiles my stuff</li>
+<li>make the jar, so that I can deploy it</li>
+<li>clean up everything</li>
+</ul>
+So the buildfile contains three targets.
+<pre class="code">
+&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;
+&lt;project name="MyTask" basedir="." default="jar"&gt;
+
+ &lt;target name="clean" description="Delete all generated files"&gt;
+ &lt;delete dir="classes"/&gt;
+ &lt;delete file="MyTasks.jar"/&gt;
+ &lt;/target&gt;
+
+ &lt;target name="compile" description="Compiles the Task"&gt;
+ &lt;javac srcdir="src" destdir="classes"/&gt;
+ &lt;/target&gt;
+
+ &lt;target name="jar" description="JARs the Task"&gt;
+ &lt;jar destfile="MyTask.jar" basedir="classes"/&gt;
+ &lt;/target&gt;
+
+&lt;/project&gt;
+</pre>
+
+This buildfile uses often the same value (src, classes, MyTask.jar), so we should rewrite that
+using <code>&lt;property&gt;</code>s. On second there are some handicaps: <code>&lt;javac&gt;</code> requires that the destination
+directory exists; a call of "clean" with a non existing classes directory will fail; "jar" requires
+the execution of some steps before. So the refactored code is:
+
+<pre class="code">
+&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;
+&lt;project name="MyTask" basedir="." default="jar"&gt;
+
+ <b>&lt;property name="src.dir" value="src"/&gt;</b>
+ <b>&lt;property name="classes.dir" value="classes"/&gt;</b>
+
+ &lt;target name="clean" description="Delete all generated files"&gt;
+ &lt;delete dir="<b>${classes.dir}</b>" <b>failonerror="false"</b>/&gt;
+ &lt;delete file="<b>${ant.project.name}.jar</b>"/&gt;
+ &lt;/target&gt;
+
+ &lt;target name="compile" description="Compiles the Task"&gt;
+ <b>&lt;mkdir dir="${classes.dir}"/&gt;</b>
+ &lt;javac srcdir="<b>${src.dir}</b>" destdir="${classes.dir}"/&gt;
+ &lt;/target&gt;
+
+ &lt;target name="jar" description="JARs the Task" <b>depends="compile"</b>&gt;
+ &lt;jar destfile="${ant.project.name}.jar" basedir="${classes.dir}"/&gt;
+ &lt;/target&gt;
+
+&lt;/project&gt;
+</pre>
+<i>ant.project.name</i> is one of the
+<a href="http://ant.apache.org/manual/properties.html#built-in-props" target="_blank">
+build-in properties [1]</a> of Ant.
+
+
+<a name="write1"></a>
+<h2>Write the Task</h2>
+
+Now we write the simplest Task - a HelloWorld-Task (what else?). Create a text file
+<i>HelloWorld.java</i> in the src-directory with:
+<pre class="code">
+public class HelloWorld {
+ public void execute() {
+ System.out.println("Hello World");
+ }
+}
+</pre>
+and we can compile and jar it with <tt>ant</tt> (default target is "jar" and via
+its <i>depends</i>-clause the "compile" is executed before).
+
+
+
+<a name="use1"></a>
+<h2>Use the Task</h2>
+<p>But after creating the jar we want to use our new Task. Therefore we need a
+new target "use". Before we can use our new task we have to declare it with
+<a href="http://ant.apache.org/manual/Tasks/taskdef.html" target="_blank">
+<code>&lt;taskdef&gt;</code> [2]</a>. And for easier process we change the default clause:</p>
+<pre class="code">
+&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;
+&lt;project name="MyTask" basedir="." default="<b>use</b>"&gt;
+
+ ...
+
+ <b>&lt;target name="use" description="Use the Task" depends="jar"&gt;
+ &lt;taskdef name="helloworld" classname="HelloWorld" classpath="${ant.project.name}.jar"/&gt;
+ &lt;helloworld/&gt;
+ &lt;/target&gt;</b>
+
+&lt;/project&gt;
+</pre>
+
+<p>Important is the <i>classpath</i>-attribute. Ant searches in its /lib directory for
+tasks and our task isn't there. So we have to provide the right location. </p>
+
+<p>Now we can type in <tt>ant</tt> and all should work ...</p>
+<pre class="output">
+Buildfile: build.xml
+
+compile:
+ [mkdir] Created dir: C:\tmp\anttests\MyFirstTask\classes
+ [javac] Compiling 1 source file to C:\tmp\anttests\MyFirstTask\classes
+
+jar:
+ [jar] Building jar: C:\tmp\anttests\MyFirstTask\MyTask.jar
+
+use:
+[helloworld] Hello World
+
+BUILD SUCCESSFUL
+Total time: 3 seconds
+</pre>
+
+
+
+<a name="TaskAdapter"></a>
+<h2>Integration with TaskAdapter</h2>
+<p>Our class has nothing to do with Ant. It extends no superclass and implements
+no interface. How does Ant know to integrate? Via name convention: our class provides
+a method with signature <tt>public void execute()</tt>. This class is wrapped by Ant's
+<tt>org.apache.tools.ant.TaskAdapter</tt> which is a task and uses reflection for
+setting a reference to the project and calling the <i>execute()</i> method.</p>
+
+<p><i>Setting a reference to the project</i>? Could be interesting. The Project class
+gives us some nice abilities: access to Ant's logging facilities getting and setting
+properties and much more. So we try to use that class:</p>
+<pre class="code">
+import org.apache.tools.ant.Project;
+
+public class HelloWorld {
+
+ private Project project;
+
+ public void setProject(Project proj) {
+ project = proj;
+ }
+
+ public void execute() {
+ String message = project.getProperty("ant.project.name");
+ project.log("Here is project '" + message + "'.", Project.MSG_INFO);
+ }
+}
+</pre>
+and the execution with <tt>ant</tt> will show us the expected
+<pre class="output">
+use:
+Here is project 'MyTask'.
+</pre>
+
+
+<a name="derivingFromTask"></a>
+<h2>Deriving from Ant's Task</h2>
+<p>Ok, that works ... But usually you will extend <tt>org.apache.tools.ant.Task</tt>.
+That class is integrated in Ant, get's the project-reference, provides documentation
+fields, provides easier access to the logging facility and (very useful) gives you
+the exact location where <i>in the buildfile</i> this task instance is used.</p>
+
+<p>Oki-doki - let's us use some of these:</p>
+<pre class="code">
+import org.apache.tools.ant.Task;
+
+public class HelloWorld extends Task {
+ public void execute() {
+ // use of the reference to Project-instance
+ String message = getProject().getProperty("ant.project.name");
+
+ // Task's log method
+ log("Here is project '" + message + "'.");
+
+ // where this task is used?
+ log("I am used in: " + getLocation() );
+ }
+}
+</pre>
+<p>which gives us when running</p>
+<pre class="output">
+use:
+[helloworld] Here is project 'MyTask'.
+[helloworld] I am used in: C:\tmp\anttests\MyFirstTask\build.xml:23:
+</pre>
+
+<a name="accessTaskProject"></a>
+<h2>Accessing the Task's Project</h2>
+<p>The parent project of your custom task may be accessed through method <code>getProject()</code>. However, do not call this from the custom task constructor, as the return value will be null. Later, when node attributes or text are set, or method <code>execute()</code> is called, the Project object is available.</p>
+<p>Here are two useful methods from class Project:</p>
+<ul>
+ <li><code>String getProperty(String propertyName)</code></li>
+ <li>
+ <code>String replaceProperties(String value)</code>
+ </li>
+</ul>
+
+<p>The method <code>replaceProperties()</code> is discussed further in section <a href="#NestedText">Nested Text</a>.</p>
+
+<a name="attributes"></a>
+<h2>Attributes</h2>
+<p>Now we want to specify the text of our message (it seems that we are
+rewriting the <code>&lt;echo/&gt;</code> task :-). First we well do that with an attribute.
+It is very easy - for each attribute provide a <tt>public void set<code>&lt;attributename&gt;</code>(<code>&lt;type&gt;</code>
+newValue)</tt> method and Ant will do the rest via reflection.</p>
+<pre class="code">
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.BuildException;
+
+public class HelloWorld extends Task {
+
+ String message;
+ public void setMessage(String msg) {
+ message = msg;
+ }
+
+ public void execute() {
+ if (message==null) {
+ throw new BuildException("No message set.");
+ }
+ log(message);
+ }
+
+}
+</pre>
+<p>Oh, what's that in execute()? Throw a <i>BuildException</i>? Yes, that's the usual
+way to show Ant that something important is missed and complete build should fail. The
+string provided there is written as build-failes-message. Here it's necessary because
+the log() method can't handle a <i>null</i> value as parameter and throws a NullPointerException.
+(Of course you can initialize the <i>message</i> with a default string.)</p>
+
+<p>After that we have to modify our buildfile:</p>
+<pre class="code">
+ &lt;target name="use" description="Use the Task" depends="jar"&gt;
+ &lt;taskdef name="helloworld"
+ classname="HelloWorld"
+ classpath="${ant.project.name}.jar"/&gt;
+ &lt;helloworld <b>message="Hello World"</b>/&gt;
+ &lt;/target&gt;
+</pre>
+<p>That's all.</p>
+
+<p>Some background for working with attributes: Ant supports any of these datatypes as
+arguments of the set-method:</p><ul>
+<li>elementary data type like <i>int</i>, <i>long</i>, ...</li>
+<li>its wrapper classes like <i>java.lang.Integer</i>, <i>java.lang.Long</i>, ...</li>
+<li><i>java.lang.String</i></li>
+<li>some more classes (e.g. <i>java.io.File</i>; see
+ <a href="develop.html#set-magic">Manual
+ 'Writing Your Own Task' [3]</a>)</li>
+<li>Any Java Object parsed from Ant 1.8's <a href="Tasks/propertyhelper.html">Property
+Helper</a></li>
+</ul>
+Before calling the set-method all properties are resolved. So a <tt>&lt;helloworld message="${msg}"/&gt;</tt>
+would not set the message string to "${msg}" if there is a property "msg" with a set value.
+
+
+<a name="NestedText"></a>
+<h2>Nested Text</h2>
+<p>Maybe you have used the <code>&lt;echo&gt;</code> task in a way like <tt>&lt;echo&gt;Hello World&lt;/echo&gt;</tt>.
+For that you have to provide a <tt>public void addText(String text)</tt> method.</p>
+<pre class="code">
+...
+public class HelloWorld extends Task {
+ private String message;
+ ...
+ public void addText(String text) {
+ message = text;
+ }
+ ...
+}
+</pre>
+<p>But here properties are <b>not</b> resolved! For resolving properties we have to use
+Project's <tt>replaceProperties(String propname) : String</tt> method which takes the
+property name as argument and returns its value (or ${propname} if not set).</p>
+<p>Thus, to replace properties in the nested node text, our method <code>addText()</code> can be written as:</p>
+<pre class="code">
+ public void addText(String text) {
+ message = getProject().replaceProperties(text);
+ }
+</pre>
+
+
+<a name="NestedElements"></a>
+<h2>Nested Elements</h2>
+<p>There are several ways for inserting the ability of handling nested elements. See
+the <a href="http://ant.apache.org/manual/develop.html#nested-elements">Manual [4]</a> for other.
+We use the first way of the three described ways. There are several steps for that:</p><ol>
+<li>We create a class for collecting all the info the nested element should contain.
+ This class is created by the same rules for attributes and nested elements
+ as for the task (<code>set&lt;attributename&gt;</code>() methods). </li>
+<li>The task holds multiple instances of this class in a list.</li>
+<li>A factory method instantiates an object, saves the reference in the list
+ and returns it to Ant Core.</li>
+<li>The execute() method iterates over the list and evaluates its values.</li>
+</ol>
+<pre class="code">
+import java.util.Vector;
+import java.util.Iterator;
+...
+ public void execute() {
+ if (message!=null) log(message);
+ for (Iterator it=messages.iterator(); it.hasNext(); ) { <b>// 4</b>
+ Message msg = (Message)it.next();
+ log(msg.getMsg());
+ }
+ }
+
+
+ Vector messages = new Vector(); <b>// 2</b>
+
+ public Message createMessage() { <b>// 3</b>
+ Message msg = new Message();
+ messages.add(msg);
+ return msg;
+ }
+
+ public class Message { <b>// 1</b>
+ public Message() {}
+
+ String msg;
+ public void setMsg(String msg) { this.msg = msg; }
+ public String getMsg() { return msg; }
+ }
+...
+</pre>
+<p>Then we can use the new nested element. But where is xml-name for that defined?
+The mapping XML-name : classname is defined in the factory method:
+<tt>public <i>classname</i> create<i>XML-name</i>()</tt>. Therefore we write in
+the buildfile</p>
+<pre class="code">
+ &lt;helloworld&gt;
+ &lt;message msg="Nested Element 1"/&gt;
+ &lt;message msg="Nested Element 2"/&gt;
+ &lt;/helloworld&gt;
+</pre>
+<p>Note that if you choose to use methods 2 or 3, the class that represents the nested
+element must be declared as <code>static</code></p>
+
+<a name="complex"></a>
+<h2>Our task in a little more complex version</h2>
+<p>For recapitulation now a little refactored buildfile:</p>
+<pre class="code">
+&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;
+&lt;project name="MyTask" basedir="." default="use"&gt;
+
+ &lt;property name="src.dir" value="src"/&gt;
+ &lt;property name="classes.dir" value="classes"/&gt;
+
+ &lt;target name="clean" description="Delete all generated files"&gt;
+ &lt;delete dir="${classes.dir}" failonerror="false"/&gt;
+ &lt;delete file="${ant.project.name}.jar"/&gt;
+ &lt;/target&gt;
+
+ &lt;target name="compile" description="Compiles the Task"&gt;
+ &lt;mkdir dir="${classes.dir}"/&gt;
+ &lt;javac srcdir="${src.dir}" destdir="${classes.dir}"/&gt;
+ &lt;/target&gt;
+
+ &lt;target name="jar" description="JARs the Task" depends="compile"&gt;
+ &lt;jar destfile="${ant.project.name}.jar" basedir="${classes.dir}"/&gt;
+ &lt;/target&gt;
+
+
+ &lt;target name="use.init"
+ description="Taskdef the HelloWorld-Task"
+ depends="jar"&gt;
+ &lt;taskdef name="helloworld"
+ classname="HelloWorld"
+ classpath="${ant.project.name}.jar"/&gt;
+ &lt;/target&gt;
+
+
+ &lt;target name="use.without"
+ description="Use without any"
+ depends="use.init"&gt;
+ &lt;helloworld/&gt;
+ &lt;/target&gt;
+
+ &lt;target name="use.message"
+ description="Use with attribute 'message'"
+ depends="use.init"&gt;
+ &lt;helloworld message="attribute-text"/&gt;
+ &lt;/target&gt;
+
+ &lt;target name="use.fail"
+ description="Use with attribute 'fail'"
+ depends="use.init"&gt;
+ &lt;helloworld fail="true"/&gt;
+ &lt;/target&gt;
+
+ &lt;target name="use.nestedText"
+ description="Use with nested text"
+ depends="use.init"&gt;
+ &lt;helloworld&gt;nested-text&lt;/helloworld&gt;
+ &lt;/target&gt;
+
+ &lt;target name="use.nestedElement"
+ description="Use with nested 'message'"
+ depends="use.init"&gt;
+ &lt;helloworld&gt;
+ &lt;message msg="Nested Element 1"/&gt;
+ &lt;message msg="Nested Element 2"/&gt;
+ &lt;/helloworld&gt;
+ &lt;/target&gt;
+
+
+ &lt;target name="use"
+ description="Try all (w/out use.fail)"
+ depends="use.without,use.message,use.nestedText,use.nestedElement"
+ /&gt;
+
+&lt;/project&gt;
+</pre>
+
+And the code of the task:
+<pre class="code">
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.BuildException;
+import java.util.Vector;
+import java.util.Iterator;
+
+/**
+ * The task of the tutorial.
+ * Print a message or let the build fail.
+ * @since 2003-08-19
+ */
+public class HelloWorld extends Task {
+
+
+ /** The message to print. As attribute. */
+ String message;
+ public void setMessage(String msg) {
+ message = msg;
+ }
+
+ /** Should the build fail? Defaults to <i>false</i>. As attribute. */
+ boolean fail = false;
+ public void setFail(boolean b) {
+ fail = b;
+ }
+
+ /** Support for nested text. */
+ public void addText(String text) {
+ message = text;
+ }
+
+
+ /** Do the work. */
+ public void execute() {
+ // handle attribute 'fail'
+ if (fail) throw new BuildException("Fail requested.");
+
+ // handle attribute 'message' and nested text
+ if (message!=null) log(message);
+
+ // handle nested elements
+ for (Iterator it=messages.iterator(); it.hasNext(); ) {
+ Message msg = (Message)it.next();
+ log(msg.getMsg());
+ }
+ }
+
+
+ /** Store nested 'message's. */
+ Vector messages = new Vector();
+
+ /** Factory method for creating nested 'message's. */
+ public Message createMessage() {
+ Message msg = new Message();
+ messages.add(msg);
+ return msg;
+ }
+
+ /** A nested 'message'. */
+ public class Message {
+ // Bean constructor
+ public Message() {}
+
+ /** Message to print. */
+ String msg;
+ public void setMsg(String msg) { this.msg = msg; }
+ public String getMsg() { return msg; }
+ }
+
+}
+</pre>
+
+And it works:
+<pre class="output">
+C:\tmp\anttests\MyFirstTask&gt;ant
+Buildfile: build.xml
+
+compile:
+ [mkdir] Created dir: C:\tmp\anttests\MyFirstTask\classes
+ [javac] Compiling 1 source file to C:\tmp\anttests\MyFirstTask\classes
+
+jar:
+ [jar] Building jar: C:\tmp\anttests\MyFirstTask\MyTask.jar
+
+use.init:
+
+use.without:
+
+use.message:
+[helloworld] attribute-text
+
+use.nestedText:
+[helloworld] nested-text
+
+use.nestedElement:
+[helloworld]
+[helloworld]
+[helloworld]
+[helloworld]
+[helloworld] Nested Element 1
+[helloworld] Nested Element 2
+
+use:
+
+BUILD SUCCESSFUL
+Total time: 3 seconds
+C:\tmp\anttests\MyFirstTask&gt;ant use.fail
+Buildfile: build.xml
+
+compile:
+
+jar:
+
+use.init:
+
+use.fail:
+
+BUILD FAILED
+C:\tmp\anttests\MyFirstTask\build.xml:36: Fail requested.
+
+Total time: 1 second
+C:\tmp\anttests\MyFirstTask&gt;
+</pre>
+Next step: test ...
+
+
+
+<a name="TestingTasks"></a>
+<h2>Test the Task</h2>
+<p>We have written a test already: the use.* tasks in the buildfile. But its
+difficult to test that automatically. Common (and in Ant) used is JUnit for
+that. For testing tasks Ant provides a JUnit Rule <tt>org.apache.tools.ant.BuildFileRule</tt>.
+This class provides some for testing tasks useful methods:
+initialize Ant, load a buildfile, execute targets, capturing debug and run logs ...</p>
+
+<p>In Ant it is usual that the testcase has the same name as the task with a prepending
+<i>Test</i>, therefore we will create a file <i>HelloWorldTest.java</i>. Because we
+have a very small project we can put this file into <i>src</i> directory (Ant's own
+testclasses are in /src/testcases/...). Because we have already written our tests
+for "hand-test" we can use that for automatic tests, too. But there is one little
+problem we have to solve: all test supporting classes are not part of the binary
+distribution of Ant. So you can build the special jar file from source distro with
+target "test-jar" or you can download a nightly build from
+<a href="http://gump.covalent.net/jars/latest/ant/ant-testutil.jar">
+http://gump.covalent.net/jars/latest/ant/ant-testutil.jar [5]</a>.</p>
+
+<p>For executing the test and creating a report we need the optional tasks <code>&lt;junit&gt;</code>
+and <code>&lt;junitreport&gt;</code>. So we add to the buildfile:</p>
+<pre class="code">
+...
+<font color="#9F9F9F">&lt;project name="MyTask" basedir="." </font>default="test"<font color="#9F9F9F">&gt;</font>
+...
+ &lt;property name="ant.test.lib" value="ant-testutil.jar"/&gt;
+ &lt;property name="report.dir" value="report"/&gt;
+ &lt;property name="junit.out.dir.xml" value="${report.dir}/junit/xml"/&gt;
+ &lt;property name="junit.out.dir.html" value="${report.dir}/junit/html"/&gt;
+
+ &lt;path id="classpath.run"&gt;
+ &lt;path path="${java.class.path}"/&gt;
+ &lt;path location="${ant.project.name}.jar"/&gt;
+ &lt;/path&gt;
+
+ &lt;path id="classpath.test"&gt;
+ &lt;path refid="classpath.run"/&gt;
+ &lt;path location="${ant.test.lib}"/&gt;
+ &lt;/path&gt;
+
+ &lt;target name="clean" description="Delete all generated files"&gt;
+ &lt;delete failonerror="false" includeEmptyDirs="true"&gt;
+ &lt;fileset dir="." includes="${ant.project.name}.jar"/&gt;
+ &lt;fileset dir="${classes.dir}"/&gt;
+ &lt;fileset dir="${report.dir}"/&gt;
+ &lt;/delete&gt;
+ &lt;/target&gt;
+
+ <font color="#9F9F9F">&lt;target name="compile" description="Compiles the Task"&gt;
+ &lt;mkdir dir="${classes.dir}"/&gt;
+ &lt;javac srcdir="${src.dir}" destdir="${classes.dir}" </font>classpath="${ant.test.lib}"<font color="#9F9F9F">/&gt;
+ &lt;/target&gt;</font>
+...
+ &lt;target name="junit" description="Runs the unit tests" depends="jar"&gt;
+ &lt;delete dir="${junit.out.dir.xml}"/&gt;
+ &lt;mkdir dir="${junit.out.dir.xml}"/&gt;
+ &lt;junit printsummary="yes" haltonfailure="no"&gt;
+ &lt;classpath refid="classpath.test"/&gt;
+ &lt;formatter type="xml"/&gt;
+ &lt;batchtest fork="yes" todir="${junit.out.dir.xml}"&gt;
+ &lt;fileset dir="${src.dir}" includes="**/*Test.java"/&gt;
+ &lt;/batchtest&gt;
+ &lt;/junit&gt;
+ &lt;/target&gt;
+
+ &lt;target name="junitreport" description="Create a report for the rest result"&gt;
+ &lt;mkdir dir="${junit.out.dir.html}"/&gt;
+ &lt;junitreport todir="${junit.out.dir.html}"&gt;
+ &lt;fileset dir="${junit.out.dir.xml}"&gt;
+ &lt;include name="*.xml"/&gt;
+ &lt;/fileset&gt;
+ &lt;report format="frames" todir="${junit.out.dir.html}"/&gt;
+ &lt;/junitreport&gt;
+ &lt;/target&gt;
+
+ &lt;target name="test"
+ depends="junit,junitreport"
+ description="Runs unit tests and creates a report"
+ /&gt;
+...
+</pre>
+
+<p>Back to the <i>src/HelloWorldTest.java</i>. We create a class with a public
+<i>BuildFileRule</i> field annotated with JUnit's <i>@Rule</i> annotation. As per
+conventional JUnit4 tests, this class should have no constructors, or a default no-args
+constructor, setup methods should be annotated with <i>@Before</i>, tear down methods
+annotated with <i>@After</i> and any test method annotated with <i>@Test</i>.
+<pre class="code">
+import org.apache.tools.ant.BuildFileRule;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.Before;
+import org.junit.Rule;
+import org.apache.tools.ant.AntAssert;
+import org.apache.tools.ant.BuildException;
+
+public class HelloWorldTest {
+
+ @Rule
+ public final BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ // initialize Ant
+ buildRule.configureProject("build.xml");
+ }
+
+ @Test
+ public void testWithout() {
+ buildRule.executeTarget("use.without");
+ assertEquals("Message was logged but should not.", buildRule.getLog(), "");
+ }
+
+ public void testMessage() {
+ // execute target 'use.nestedText' and expect a message
+ // 'attribute-text' in the log
+ buildRule.executeTarget("use.message");
+ Assert.assertEquals("attribute-text", buildRule.getLog());
+ }
+
+ @Test
+ public void testFail() {
+ // execute target 'use.fail' and expect a BuildException
+ // with text 'Fail requested.'
+ try {
+ buildRule.executeTarget("use.fail");
+ fail("BuildException should have been thrown as task was set to fail");
+ } catch (BuildException ex) {
+ Assert.assertEquals("fail requested", ex.getMessage());
+ }
+
+ }
+
+ @Test
+ public void testNestedText() {
+ buildRule.executeTarget("use.nestedText");
+ Assert.assertEquals("nested-text", buildRule.getLog());
+ }
+
+ @Test
+ public void testNestedElement() {
+ buildRule.executeTarget("use.nestedElement");
+ AntAssert.assertContains("Nested Element 1", buildRule.getLog());
+ AntAssert.assertContains("Nested Element 2", buildRule.getLog());
+ }
+}
+</pre>
+
+<p>When starting <tt>ant</tt> we'll get a short message to STDOUT and
+a nice HTML-report.</p>
+<pre class="output">
+C:\tmp\anttests\MyFirstTask&gt;ant
+Buildfile: build.xml
+
+compile:
+ [mkdir] Created dir: C:\tmp\anttests\MyFirstTask\classes
+ [javac] Compiling 2 source files to C:\tmp\anttests\MyFirstTask\classes
+
+jar:
+ [jar] Building jar: C:\tmp\anttests\MyFirstTask\MyTask.jar
+
+junit:
+ [mkdir] Created dir: C:\tmp\anttests\MyFirstTask\report\junit\xml
+ [junit] Running HelloWorldTest
+ [junit] Tests run: 5, Failures: 0, Errors: 0, Time elapsed: 2,334 sec
+
+
+
+junitreport:
+ [mkdir] Created dir: C:\tmp\anttests\MyFirstTask\report\junit\html
+[junitreport] Using Xalan version: Xalan Java 2.4.1
+[junitreport] Transform time: 661ms
+
+test:
+
+BUILD SUCCESSFUL
+Total time: 7 seconds
+C:\tmp\anttests\MyFirstTask&gt;
+</pre>
+
+
+<a name="Debugging"></a>
+<h2>Debugging</h2>
+
+<p>Try running Ant with the flag <code>-verbose</code>. For more information, try flag <code>-debug</code>.</p>
+<p>For deeper issues, you may need to run the custom task code in a Java debugger. First, get the source for Ant and build it with debugging information.</p>
+<p>Since Ant is a large project, it can be a little tricky to set the right breakpoints. Here are two important breakpoints for version 1.8:</p>
+<ul>
+ <li>Initial <code>main()</code> function: <code>com.apache.tools.ant.launch.Launcher.main()</code></li>
+ <li>Task entry point: <code>com.apache.tools.ant.UnknownElement.execute()</code></li>
+</ul>
+
+<p>If you need to debug when a task attribute or the text is set, begin by debugging into method <code>execute()</code> of your custom task. Then set breakpoints in other methods. This will ensure the class byte-code has been loaded by the Java VM.</p>
+
+
+
+<a name="resources"></a>
+<h2>Resources</h2>
+<p>This tutorial and its resources are available via
+<a href="http://issues.apache.org/bugzilla/show_bug.cgi?id=22570">BugZilla [6]</a>.
+The ZIP provided there contains</p><ul>
+<li>this initial version of this tutorial</li>
+<li>the buildfile (last version)</li>
+<li>the source of the task (last version)</li>
+<li>the source of the unit test (last version)</li>
+<li>the ant-testutil.jar (nightly build of 2003-08-18)</li>
+<li>generated classes</li>
+<li>generated jar</li>
+<li>generated reports</li>
+</ul>
+<p>The last sources and the buildfile are also available
+<a href="tutorial-writing-tasks-src.zip">here [7]</a> inside the manual.
+</p>
+
+<p>Used Links:<br />
+&nbsp;&nbsp;[1] <a href="http://ant.apache.org/manual/properties.html#built-in-props">http://ant.apache.org/manual/properties.html#built-in-props</a><br />
+&nbsp;&nbsp;[2] <a href="http://ant.apache.org/manual/Tasks/taskdef.html">http://ant.apache.org/manual/Tasks/taskdef.html</a><br />
+&nbsp;&nbsp;[3] <a href="http://ant.apache.org/manual/develop.html#set-magic">http://ant.apache.org/manual/develop.html#set-magic</a><br />
+&nbsp;&nbsp;[4] <a href="http://ant.apache.org/manual/develop.html#nested-elements">http://ant.apache.org/manual/develop.html#nested-elements</a><br />
+&nbsp;&nbsp;[5] <a href="http://gump.covalent.net/jars/latest/ant/ant-testutil.jar">http://gump.covalent.net/jars/latest/ant/ant-testutil.jar</a><br />
+&nbsp;&nbsp;[6] <a href="http://issues.apache.org/bugzilla/show_bug.cgi?id=22570">http://issues.apache.org/bugzilla/show_bug.cgi?id=22570</a><br />
+&nbsp;&nbsp;[7] <a href="tutorial-writing-tasks-src.zip">tutorial-writing-tasks-src.zip</a><br />
+</p>
+
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/tutorials.html b/framework/src/ant/apache-ant-1.9.6/manual/tutorials.html
new file mode 100644
index 00000000..5720473a
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/tutorials.html
@@ -0,0 +1,45 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us"/>
+<link rel="stylesheet" type="text/css" href="stylesheets/style.css"/>
+<title>Tutorials</title>
+<base target="mainFrame"/>
+</head>
+
+<body>
+
+<h2><a href="toc.html" target="navFrame">Table of Contents</a></h2>
+
+<h3>Tutorials</h3>
+
+<p><a href="tutorial-HelloWorldWithAnt.html">Hello World with Apache Ant</a><br/>
+A step by step tutorial for starting java programming with Ant.</p>
+
+<p><a href="tutorial-writing-tasks.html">Writing Tasks</a><br/>
+A step by step tutorial for writing tasks.</p>
+
+<p><a href="tutorial-tasks-filesets-properties.html">Tasks using Properties, Filesets &amp; Paths</a><br/>
+How to get and set properties and how to use nested filesets and paths
+while writing tasks. Finally it explains how to contribute tasks to Ant.</p>
+
+
+
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/using.html b/framework/src/ant/apache-ant-1.9.6/manual/using.html
new file mode 100644
index 00000000..d3b9a567
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/using.html
@@ -0,0 +1,579 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<link rel="stylesheet" type="text/css" href="stylesheets/style.css">
+<title>Writing a Simple Buildfile</title>
+</head>
+
+<body>
+<h1>Using Apache Ant</h1>
+<h2><a name="buildfile">Writing a Simple Buildfile</a></h2>
+<p>Apache Ant's buildfiles are written in XML. Each buildfile contains one project
+and at least one (default) target. Targets contain task elements.
+Each task element of the buildfile can have an <code>id</code> attribute and
+can later be referred to by the value supplied to this. The value has
+to be unique. (For additional information, see the
+<a href="#tasks"> Tasks</a> section below.)</p>
+<h3><a name="projects">Projects</a></h3>
+<p>A <i>project</i> has three attributes:</p>
+<table border="1" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top"><b>Attribute</b></td>
+ <td valign="top"><b>Description</b></td>
+ <td align="center" valign="top"><b>Required</b></td>
+ </tr>
+ <tr>
+ <td valign="top">name</td>
+ <td valign="top">the name of the project.</td>
+ <td align="center" valign="top">No</td>
+ </tr>
+ <tr>
+ <td valign="top">default</td>
+ <td valign="top">the default target to use when no target is supplied.</td>
+ <td align="center" valign="top">No; however, <b>since Ant 1.6.0</b>,
+ every project includes an implicit target that contains any and
+ all top-level tasks and/or types. This target will always be
+ executed as part of the project's initialization, even when Ant is
+ run with the <a href="running.html#options">-projecthelp</a> option.
+ </td>
+ </tr>
+ <tr>
+ <td valign="top">basedir</td>
+ <td valign="top">the base directory from which all path calculations are
+ done. This attribute might be overridden by setting
+ the &quot;basedir&quot;
+ property beforehand. When this is done, it must be omitted in the
+ project tag. If neither the attribute nor the property have
+ been set, the parent directory of the buildfile will be used.<br/>
+ A relative path is resolved relative to the directory containing
+ the build file.
+ </td>
+ <td align="center" valign="top">No</td>
+ </tr>
+</table>
+<p>Optionally, a description for the project can be provided as a
+top-level <code>&lt;description&gt;</code> element (see the <a
+href="Types/description.html">description</a> type).</p>
+
+<p>Each project defines one or more <i>targets</i>.
+A target is a set of <i>tasks</i> you want
+to be executed. When starting Ant, you can select which target(s) you
+want to have executed. When no target is given,
+the project's default is used.</p>
+
+<h3><a name="targets">Targets</a></h3>
+<p>A target can depend on other targets. You might have a target for compiling,
+for example, and a target for creating a distributable. You can only build a
+distributable when you have compiled first, so the distribute target
+<i>depends on</i> the compile target. Ant resolves these dependencies.</p>
+<p>It should be noted, however, that Ant's <code>depends</code> attribute
+only specifies the <i>order</i> in which targets should be executed - it
+does not affect whether the target that specifies the dependency(s) gets
+executed if the dependent target(s) did not (need to) run.
+</p>
+
+<p>More information can be found in the
+ dedicated <a href="targets.html">manual page</a>.</p>
+
+<h3><a name="tasks">Tasks</a></h3>
+<p>A task is a piece of code that can be executed.</p>
+<p>A task can have multiple attributes (or arguments, if you prefer). The value
+of an attribute might contain references to a property. These references will be
+resolved before the task is executed.</p>
+<p>Tasks have a common structure:</p>
+<blockquote>
+ <pre>&lt;<i>name</i> <i>attribute1</i>=&quot;<i>value1</i>&quot; <i>attribute2</i>=&quot;<i>value2</i>&quot; ... /&gt;</pre>
+</blockquote>
+<p>where <i>name</i> is the name of the task,
+<i>attributeN</i> is the attribute name, and
+<i>valueN</i> is the value for this attribute.</p>
+<p>There is a set of <a href="tasklist.html" target="navFrame">built-in tasks</a>, but it is also very
+easy to <a href="develop.html#writingowntask">write your own</a>.</p>
+<p>All tasks share a task name attribute. The value of
+this attribute will be used in the logging messages generated by
+Ant.</p>
+Tasks can be assigned an <code>id</code> attribute:
+<blockquote>
+<pre>&lt;<i>taskname</i> id="<i>taskID</i>" ... /&gt;</pre>
+</blockquote>
+where <i>taskname</i> is the name of the task, and <i>taskID</i> is
+a unique identifier for this task.
+You can refer to the
+corresponding task object in scripts or other tasks via this name.
+For example, in scripts you could do:
+<blockquote>
+<pre>
+&lt;script ... &gt;
+ task1.setFoo("bar");
+&lt;/script&gt;
+</pre>
+</blockquote>
+to set the <code>foo</code> attribute of this particular task instance.
+In another task (written in Java), you can access the instance via
+<code>project.getReference("task1")</code>.
+<p>
+Note<sup>1</sup>: If &quot;task1&quot; has not been run yet, then
+it has not been configured (ie., no attributes have been set), and if it is
+going to be configured later, anything you've done to the instance may
+be overwritten.
+</p>
+<p>
+Note<sup>2</sup>: Future versions of Ant will most likely <i>not</i>
+be backward-compatible with this behaviour, since there will likely be no
+task instances at all, only proxies.
+</p>
+
+<h3><a name="properties">Properties</a></h3>
+
+<p>Properties are an important way to customize a build process or
+ to just provide shortcuts for strings that are used repeatedly
+ inside a build file.</p>
+
+<p>In its most simple form properties are defined in the build file
+ (for example by the <a href="Tasks/property.html">property</a>
+ task) or might be set outside Ant. A property has a name and a
+ value; the name is case-sensitive. Properties may be used in the
+ value of task attributes or in the nested text of tasks that support
+ them. This is done by placing the property name between
+ &quot;<code>${</code>&quot; and &quot;<code>}</code>&quot; in the
+ attribute value. For example, if there is a &quot;builddir&quot;
+ property with the value &quot;build&quot;, then this could be used
+ in an attribute like this: <code>${builddir}/classes</code>. This
+ is resolved at run-time as <code>build/classes</code>.</p>
+
+<p>With Ant 1.8.0 property expansion has become much more powerful
+ than simple key value pairs, more details can be
+ found <a href="properties.html">in the concepts section</a> of this
+ manual.</p>
+
+<h3><a name="example">Example Buildfile</a></h3>
+<pre>
+&lt;project name=&quot;MyProject&quot; default=&quot;dist&quot; basedir=&quot;.&quot;&gt;
+ &lt;description&gt;
+ simple example build file
+ &lt;/description&gt;
+ &lt;!-- set global properties for this build --&gt;
+ &lt;property name=&quot;src&quot; location=&quot;src&quot;/&gt;
+ &lt;property name=&quot;build&quot; location=&quot;build&quot;/&gt;
+ &lt;property name=&quot;dist&quot; location=&quot;dist&quot;/&gt;
+
+ &lt;target name=&quot;init&quot;&gt;
+ &lt;!-- Create the time stamp --&gt;
+ &lt;tstamp/&gt;
+ &lt;!-- Create the build directory structure used by compile --&gt;
+ &lt;mkdir dir=&quot;${build}&quot;/&gt;
+ &lt;/target&gt;
+
+ &lt;target name=&quot;compile&quot; depends=&quot;init&quot;
+ description=&quot;compile the source&quot;&gt;
+ &lt;!-- Compile the java code from ${src} into ${build} --&gt;
+ &lt;javac srcdir=&quot;${src}&quot; destdir=&quot;${build}&quot;/&gt;
+ &lt;/target&gt;
+
+ &lt;target name=&quot;dist&quot; depends=&quot;compile&quot;
+ description=&quot;generate the distribution&quot;&gt;
+ &lt;!-- Create the distribution directory --&gt;
+ &lt;mkdir dir=&quot;${dist}/lib&quot;/&gt;
+
+ &lt;!-- Put everything in ${build} into the MyProject-${DSTAMP}.jar file --&gt;
+ &lt;jar jarfile=&quot;${dist}/lib/MyProject-${DSTAMP}.jar&quot; basedir=&quot;${build}&quot;/&gt;
+ &lt;/target&gt;
+
+ &lt;target name=&quot;clean&quot;
+ description=&quot;clean up&quot;&gt;
+ &lt;!-- Delete the ${build} and ${dist} directory trees --&gt;
+ &lt;delete dir=&quot;${build}&quot;/&gt;
+ &lt;delete dir=&quot;${dist}&quot;/&gt;
+ &lt;/target&gt;
+&lt;/project&gt;
+</pre>
+
+<p>Notice that we are declaring properties outside any target. As of
+Ant 1.6 all tasks can be declared outside targets (earlier version
+only allowed <tt>&lt;property&gt;</tt>,<tt>&lt;typedef&gt;</tt> and
+<tt>&lt;taskdef&gt;</tt>). When you do this they are evaluated before
+any targets are executed. Some tasks will generate build failures if
+they are used outside of targets as they may cause infinite loops
+otherwise (<code>&lt;antcall&gt;</code> for example).</p>
+
+<p>
+We have given some targets descriptions; this causes the <tt>projecthelp</tt>
+invocation option to list them as public targets with the descriptions; the
+other target is internal and not listed.
+<p>
+Finally, for this target to work the source in the <tt>src</tt> subdirectory
+should be stored in a directory tree which matches the package names. Check the
+<tt>&lt;javac&gt;</tt> task for details.
+
+<h3><a name="filters">Token Filters</a></h3>
+<p>A project can have a set of tokens that might be automatically expanded if
+found when a file is copied, when the filtering-copy behavior is selected in the
+tasks that support this. These might be set in the buildfile
+by the <a href="Tasks/filter.html">filter</a> task.</p>
+<p>Since this can potentially be a very harmful behavior,
+the tokens in the files <b>must</b>
+be of the form <code>@</code><i>token</i><code>@</code>, where
+<i>token</i> is the token name that is set
+in the <code>&lt;filter&gt;</code> task. This token syntax matches the syntax of other build systems
+that perform such filtering and remains sufficiently orthogonal to most
+programming and scripting languages, as well as with documentation systems.</p>
+<p>Note: If a token with the format <code>@</code><i>token</i><code>@</code>
+is found in a file, but no
+filter is associated with that token, no changes take place;
+therefore, no escaping
+method is available - but as long as you choose appropriate names for your
+tokens, this should not cause problems.</p>
+<p><b>Warning:</b> If you copy binary files with filtering turned on, you can corrupt the
+files. This feature should be used with text files <em>only</em>.</p>
+
+<h3><a name="path">Path-like Structures</a></h3>
+<p>You can specify <code>PATH</code>- and <code>CLASSPATH</code>-type
+references using both
+&quot;<code>:</code>&quot; and &quot;<code>;</code>&quot; as separator
+characters. Ant will
+convert the separator to the correct character of the current operating
+system.</p>
+<p>Wherever path-like values need to be specified, a nested element can
+be used. This takes the general form of:</p>
+<pre>
+ &lt;classpath&gt;
+ &lt;pathelement path=&quot;${classpath}&quot;/&gt;
+ &lt;pathelement location=&quot;lib/helper.jar&quot;/&gt;
+ &lt;/classpath&gt;
+</pre>
+<p>The <code>location</code> attribute specifies a single file or
+directory relative to the project's base directory (or an absolute
+filename), while the <code>path</code> attribute accepts colon-
+or semicolon-separated lists of locations. The <code>path</code>
+attribute is intended to be used with predefined paths - in any other
+case, multiple elements with <code>location</code> attributes should be
+preferred.</p>
+<p><em>Since Ant 1.8.2</em> the location attribute can also contain a
+ wildcard in its last path component (i.e. it can end in a
+ &quot;*&quot;) in order to support wildcard CLASSPATHs introduced
+ with Java6. Ant will not expand or evaluate the wildcards and the
+ resulting path may not work as anything else but a CLASSPATH - or
+ even as a CLASSPATH for a Java VM prior to Java6.</p>
+<p>As a shortcut, the <code>&lt;classpath&gt;</code> tag
+supports <code>path</code> and
+<code>location</code> attributes of its own, so:</p>
+<pre>
+ &lt;classpath&gt;
+ &lt;pathelement path=&quot;${classpath}&quot;/&gt;
+ &lt;/classpath&gt;
+</pre>
+<p>can be abbreviated to:</p>
+<pre>
+ &lt;classpath path=&quot;${classpath}&quot;/&gt;
+</pre>
+<p>In addition, one or more
+<a href="Types/resources.html#collection">Resource Collection</a>s
+can be specified as nested elements (these must consist of
+<a href="Types/resources.html#file">file</a>-type resources only).
+Additionally, it should be noted that although resource collections are
+processed in the order encountered, certain resource collection types
+such as <a href="Types/fileset.html">fileset</a>,
+<a href="Types/dirset.html">dirset</a> and
+<a href="Types/resources.html#files">files</a>
+are undefined in terms of order.</p>
+<pre>
+ &lt;classpath&gt;
+ &lt;pathelement path=&quot;${classpath}&quot;/&gt;
+ &lt;fileset dir=&quot;lib&quot;&gt;
+ &lt;include name=&quot;**/*.jar&quot;/&gt;
+ &lt;/fileset&gt;
+ &lt;pathelement location=&quot;classes&quot;/&gt;
+ &lt;dirset dir=&quot;${build.dir}&quot;&gt;
+ &lt;include name=&quot;apps/**/classes&quot;/&gt;
+ &lt;exclude name=&quot;apps/**/*Test*&quot;/&gt;
+ &lt;/dirset&gt;
+ &lt;filelist refid=&quot;third-party_jars&quot;/&gt;
+ &lt;/classpath&gt;
+</pre>
+<p>This builds a path that holds the value of <code>${classpath}</code>,
+followed by all jar files in the <code>lib</code> directory,
+the <code>classes</code> directory, all directories named
+<code>classes</code> under the <code>apps</code> subdirectory of
+<code>${build.dir}</code>, except those
+that have the text <code>Test</code> in their name, and
+the files specified in the referenced FileList.</p>
+<p>If you want to use the same path-like structure for several tasks,
+you can define them with a <code>&lt;path&gt;</code> element at the
+same level as <i>target</i>s, and reference them via their
+<i>id</i> attribute--see <a href="#references">References</a> for an
+example.</p>
+
+<p>By default a path like structure will re-evaluate all nested
+ resource collections whenever it is used, which may lead to
+ unnecessary re-scanning of the filesystem. Since Ant 1.8.0 path has
+ an optional <i>cache</i> attribute, if it is set to true, the path
+ instance will only scan its nested resource collections once and
+ assume it doesn't change during the build anymore (the default
+ for <i>cache</i> still is <i>false</i>). Even if you are using the
+ path only in a single task it may improve overall performance to set
+ <i>cache</i> to <i>true</i> if you are using complex nested
+ constructs.</p>
+
+<p>A path-like structure can include a reference to another path-like
+structure (a path being itself a resource collection)
+via nested <code>&lt;path&gt;</code> elements:</p>
+<pre>
+ &lt;path id=&quot;base.path&quot;&gt;
+ &lt;pathelement path=&quot;${classpath}&quot;/&gt;
+ &lt;fileset dir=&quot;lib&quot;&gt;
+ &lt;include name=&quot;**/*.jar&quot;/&gt;
+ &lt;/fileset&gt;
+ &lt;pathelement location=&quot;classes&quot;/&gt;
+ &lt;/path&gt;
+
+ &lt;path id=&quot;tests.path&quot; cache=&quot;true&quot;&gt;
+ &lt;path refid=&quot;base.path&quot;/&gt;
+ &lt;pathelement location=&quot;testclasses&quot;/&gt;
+ &lt;/path&gt;
+</pre>
+ The shortcuts previously mentioned for <code>&lt;classpath&gt;</code> are also valid for <code>&lt;path&gt;</code>.For example:
+<pre>
+ &lt;path id=&quot;base.path&quot;&gt;
+ &lt;pathelement path=&quot;${classpath}&quot;/&gt;
+ &lt;/path&gt;
+</pre>
+can be written as:
+<pre>
+ &lt;path id=&quot;base.path&quot; path=&quot;${classpath}&quot;/&gt;
+</pre>
+
+ <h4><a name="pathshortcut">Path Shortcut</a></h4>
+ <p>
+ In Ant 1.6 a shortcut for converting paths to OS specific strings
+ in properties has been added. One can use the expression
+ ${toString:<em>pathreference</em>} to convert a path element
+ reference to a string that can be used for a path argument.
+ For example:
+ </p>
+<pre>
+ &lt;path id="lib.path.ref"&gt;
+ &lt;fileset dir="lib" includes="*.jar"/&gt;
+ &lt;/path&gt;
+ &lt;javac srcdir="src" destdir="classes"&gt;
+ &lt;compilerarg arg="-Xbootclasspath/p:${toString:lib.path.ref}"/&gt;
+ &lt;/javac&gt;
+</pre>
+
+
+<h3><a name="arg">Command-line Arguments</a></h3>
+<p>Several tasks take arguments that will be passed to another
+process on the command line. To make it easier to specify arguments
+that contain space characters, nested <code>arg</code> elements can be used.</p>
+<table border="1" cellpadding="2" cellspacing="0">
+<tr>
+ <td width="12%" valign="top"><b>Attribute</b></td>
+ <td width="78%" valign="top"><b>Description</b></td>
+ <td width="10%" valign="top"><b>Required</b></td>
+</tr>
+ <tr>
+ <td valign="top">value</td>
+ <td valign="top">a single command-line argument; can contain space
+ characters.</td>
+ <td align="center" rowspan="5">Exactly one of these.</td>
+ </tr>
+ <tr>
+ <td valign="top">file</td>
+ <td valign="top">The name of a file as a single command-line
+ argument; will be replaced with the absolute filename of the file.</td>
+ </tr>
+ <tr>
+ <td valign="top">path</td>
+ <td valign="top">A string that will be treated as a path-like
+ string as a single command-line argument; you can use <code>;</code>
+ or <code>:</code> as
+ path separators and Ant will convert it to the platform's local
+ conventions.</td>
+ </tr>
+ <tr>
+ <td valign="top">pathref</td>
+ <td valign="top"><a href="#references">Reference</a> to a path
+ defined elsewhere. Ant will convert it to the platform's local
+ conventions.</td>
+ </tr>
+ <tr>
+ <td valign="top">line</td>
+ <td valign="top">a space-delimited list of command-line arguments.</td>
+ </tr>
+ <tr>
+ <td valign="top">prefix</td>
+ <td valign="top">A fixed string to be placed in front of the
+ argument. In the case of a line broken into parts, it will be
+ placed in front of every part. <em>Since Ant 1.8.</em></td>
+ <td valign="top" align="center">No</td>
+ </tr>
+ <tr>
+ <td valign="top">suffix</td>
+ <td valign="top">A fixed string to be placed immediately after the
+ argument. In the case of a line broken into parts, it will be
+ placed after every part. <em>Since Ant 1.8.</em></td>
+ <td valign="top" align="center">No</td>
+ </tr>
+</table>
+
+<p>It is highly recommended to avoid the <code>line</code> version
+when possible. Ant will try to split the command line in a way
+similar to what a (Unix) shell would do, but may create something that
+is very different from what you expect under some circumstances.</p>
+
+<h4>Examples</h4>
+<blockquote><pre>
+ &lt;arg value=&quot;-l -a&quot;/&gt;
+</pre></blockquote>
+<p>is a single command-line argument containing a space character,
+<i>not</i> separate commands "-l" and "-a".</p>
+<blockquote><pre>
+ &lt;arg line=&quot;-l -a&quot;/&gt;
+</pre></blockquote>
+<p>This is a command line with two separate arguments, "-l" and "-a".</p>
+<blockquote><pre>
+ &lt;arg path=&quot;/dir;/dir2:\dir3&quot;/&gt;
+</pre></blockquote>
+<p>is a single command-line argument with the value
+<code>\dir;\dir2;\dir3</code> on DOS-based systems and
+<code>/dir:/dir2:/dir3</code> on Unix-like systems.</p>
+
+<h3><a name="references">References</a></h3>
+
+<p>Any project element can be assigned an identifier using its
+<code>id</code> attribute. In most cases the element can subsequently
+be referenced by specifying the <code>refid</code> attribute on an
+element of the same type. This can be useful if you are going to
+replicate the same snippet of XML over and over again--using a
+<code>&lt;classpath&gt;</code> structure more than once, for example.</p>
+<p>The following example:</p>
+<blockquote><pre>
+&lt;project ... &gt;
+ &lt;target ... &gt;
+ &lt;rmic ...&gt;
+ &lt;classpath&gt;
+ &lt;pathelement location=&quot;lib/&quot;/&gt;
+ &lt;pathelement path=&quot;${java.class.path}/&quot;/&gt;
+ &lt;pathelement path=&quot;${additional.path}&quot;/&gt;
+ &lt;/classpath&gt;
+ &lt;/rmic&gt;
+ &lt;/target&gt;
+
+ &lt;target ... &gt;
+ &lt;javac ...&gt;
+ &lt;classpath&gt;
+ &lt;pathelement location=&quot;lib/&quot;/&gt;
+ &lt;pathelement path=&quot;${java.class.path}/&quot;/&gt;
+ &lt;pathelement path=&quot;${additional.path}&quot;/&gt;
+ &lt;/classpath&gt;
+ &lt;/javac&gt;
+ &lt;/target&gt;
+&lt;/project&gt;
+</pre></blockquote>
+<p>could be rewritten as:</p>
+<blockquote><pre>
+&lt;project ... &gt;
+ &lt;path id=&quot;project.class.path&quot;&gt;
+ &lt;pathelement location=&quot;lib/&quot;/&gt;
+ &lt;pathelement path=&quot;${java.class.path}/&quot;/&gt;
+ &lt;pathelement path=&quot;${additional.path}&quot;/&gt;
+ &lt;/path&gt;
+
+ &lt;target ... &gt;
+ &lt;rmic ...&gt;
+ &lt;classpath refid=&quot;project.class.path&quot;/&gt;
+ &lt;/rmic&gt;
+ &lt;/target&gt;
+
+ &lt;target ... &gt;
+ &lt;javac ...&gt;
+ &lt;classpath refid=&quot;project.class.path&quot;/&gt;
+ &lt;/javac&gt;
+ &lt;/target&gt;
+&lt;/project&gt;
+</pre></blockquote>
+<p>All tasks that use nested elements for
+<a href="Types/patternset.html">PatternSet</a>s,
+<a href="Types/fileset.html">FileSet</a>s,
+<a href="Types/zipfileset.html">ZipFileSet</a>s or
+<a href="#path">path-like structures</a> accept references to these structures
+as shown in the examples. Using <code>refid</code> on a task will ordinarily
+have the same effect (referencing a task already declared), but the user
+should be aware that the interpretation of this attribute is dependent on the
+implementation of the element upon which it is specified. Some tasks (the
+<a href="Tasks/property.html">property</a> task is a handy example)
+deliberately assign a different meaning to <code>refid</code>.</p>
+
+
+<h3><a name="external-tasks">Use of external tasks</a></h3>
+Ant supports a plugin mechanism for using third party tasks. For using them you
+have to do two steps:
+<ol>
+ <li>place their implementation somewhere where Ant can find them</li>
+ <li>declare them.</li>
+</ol>
+Don't add anything to the CLASSPATH environment variable - this is often the
+reason for very obscure errors. Use Ant's own <a href="install.html#optionalTasks">mechanisms</a>
+for adding libraries:
+<ul>
+ <li>via command line argument <code>-lib</code></li>
+ <li>adding to <code>${user.home}/.ant/lib</code></li>
+ <li>adding to <code>${ant.home}/lib</code></li>
+</ul>
+For the declaration there are several ways:
+<ul>
+ <li>declare a single task per using instruction using
+ <code>&lt;<a href="Tasks/taskdef.html">taskdef</a> name=&quot;taskname&quot;
+ classname=&quot;ImplementationClass&quot;/&gt;</code>
+ <br>
+ <code>&lt;taskdef name=&quot;for&quot; classname=&quot;net.sf.antcontrib.logic.For&quot; /&gt;
+ &lt;for ... /&gt;</code>
+ </li>
+ <li>declare a bundle of tasks using a properties-file holding these
+ taskname-ImplementationClass-pairs and <code>&lt;taskdef&gt;</code>
+ <br>
+ <code>&lt;taskdef resource=&quot;net/sf/antcontrib/antcontrib.properties&quot; /&gt;
+ &lt;for ... /&gt;</code>
+ </li>
+ <li>declare a bundle of tasks using a <a href="Types/antlib.html">xml-file</a> holding these
+ taskname-ImplementationClass-pairs and <code>&lt;taskdef&gt;</code>
+ <br>
+ <code>&lt;taskdef resource=&quot;net/sf/antcontrib/antlib.xml&quot; /&gt;
+ &lt;for ... /&gt;</code>
+ </li>
+ <li>declare a bundle of tasks using a xml-file named antlib.xml, XML-namespace and
+ <a href="Types/antlib.html#antlibnamespace"><code>antlib:</code> protocol handler</a>
+ <br>
+ <code>&lt;project xmlns:ac=&quot;antlib:net.sf.antcontrib&quot;/&gt;
+ &lt;ac:for ... /&gt;</code>
+ </li>
+</ul>
+
+If you need a special function, you should
+<ol>
+ <li>have a look at this manual, because Ant provides lot of tasks</li>
+ <li>have a look at the external task page <a href="http://ant.apache.org/external.html">online</a></li>
+ <li>have a look at the external task <a href="http://wiki.apache.org/ant/AntExternalTaskdefs">wiki
+ page</a></li>
+ <li>ask on the <a href="http://ant.apache.org/mail.html#User%20List">Ant user</a> list</li>
+ <li><a href="tutorial-writing-tasks.html">implement </a>(and share) your own</li>
+</ol>
+
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/manual/usinglist.html b/framework/src/ant/apache-ant-1.9.6/manual/usinglist.html
new file mode 100644
index 00000000..9169d6fd
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/manual/usinglist.html
@@ -0,0 +1,50 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us"/>
+<link rel="stylesheet" type="text/css" href="stylesheets/style.css"/>
+<title>Apache Ant User Manual</title>
+<base target="mainFrame"/>
+</head>
+
+<body>
+
+<h2><a href="toc.html" target="navFrame">Table of Contents</a></h2>
+
+<h3>Using Apache Ant</h3>
+<ul class="inlinelist">
+<li><a href="using.html#buildfile">Writing a Simple Buildfile</a></li>
+<div style="padding-left:1em">
+ <li><a href="using.html#projects">Projects</a></li>
+ <li><a href="targets.html#targets">Targets</a></li>
+ <li><a href="using.html#tasks">Tasks</a></li>
+ <li><a href="using.html#properties">Properties</a></li>
+ <li><a href="properties.html#built-in-props">Built-in Properties</a></li>
+ <li><a href="properties.html#propertyHelper">Property Helpers</a></li>
+ <li><a href="using.html#example">Example Buildfile</a></li>
+ <li><a href="using.html#filters">Token Filters</a></li>
+ <li><a href="using.html#path">Path-like Structures</a></li>
+ <li><a href="using.html#arg">Command-line Arguments</a></li>
+ <li><a href="using.html#references">References</a></li>
+ <li><a href="using.html#external-tasks">Use of external tasks</a></li>
+</div>
+</ul>
+</body>
+</html>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/patch.xml b/framework/src/ant/apache-ant-1.9.6/patch.xml
new file mode 100644
index 00000000..910b1232
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/patch.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0"?>
+
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!--
+ =======================================================================
+ Use Apache Ant to generate a patch file for Apache Ant.
+ =======================================================================
+-->
+<project name="create-patch" default="patchpackage" basedir=".">
+ <property environment="env"/>
+ <property name="patch.package" value="patch.tar.gz"/>
+ <property name="patch.file" value="patch.txt"/>
+
+ <condition property="git.found">
+ <or>
+ <available file="git" filepath="${env.PATH}"/>
+ <available file="git.exe" filepath="${env.PATH}"/>
+ <available file="git.exe" filepath="${env.Path}"/>
+ </or>
+ </condition>
+
+ <target name="createpatch">
+ <fail unless="git.found"
+ message="You need a version of git to create the patch"/>
+ <exec executable="git" output="${patch.file}">
+ <arg value="diff"/>
+ </exec>
+ </target>
+
+ <target name="patchpackage" depends="createpatch">
+ <gzip src="${patch.file}" destfile="${patch.file}.gz"/>
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/antidote/WHAT-IS-THIS-P b/framework/src/ant/apache-ant-1.9.6/src/antidote/WHAT-IS-THIS-P
new file mode 100644
index 00000000..6384ad4b
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/antidote/WHAT-IS-THIS-P
@@ -0,0 +1,6 @@
+This /used/ to be the home of Antidote, the GUI for Ant. It has moved
+(or rather, graduate) to the cvs module ant-antidote, and must
+be retrieved separately from Ant, but can be found in the same place you found
+source version of Ant.
+
+-- The Antidote Team --
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/ant-bin.wxs b/framework/src/ant/apache-ant-1.9.6/src/etc/ant-bin.wxs
new file mode 100644
index 00000000..74ed74fe
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/ant-bin.wxs
@@ -0,0 +1,454 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<!-- generated by tallow.exe
+
+ tallow.exe -d dist/lib -d dist/bin -d dist/etc -d dist/docs -dav -nologo > src/etc/ant-bin.wxs
+
+ after that I've removed the javadocs (too many directories I
+ would have had to created GUIDs for) added GUIDs, changed the
+ top-level directory reference, changed id of the manual
+ directory, removed index.html from it and finally made the File
+ entries valid by adding DiskId attributes.
+
+ Yes, we need a task to automate this.
+-->
+<Wix xmlns="http://schemas.microsoft.com/wix/2003/01/wi">
+ <Fragment>
+ <DirectoryRef Id="INSTALLDIR">
+ <Directory Id="directory0" Name="lib">
+ <Component Id="component0" DiskId="1" Guid="F0D9EDBA-4CE3-4660-A826-A197B598DE31">
+ <File DiskId="1" Id="file0" Name="ANT-AN_1.JAR" LongName="ant-antlr.jar" Vital="yes" src="$(var.dist.dir)/lib\ant-antlr.jar" />
+ <File DiskId="1" Id="file1" Name="ANFAFB_1.JAR" LongName="ant-apache-bcel.jar" Vital="yes" src="$(var.dist.dir)/lib\ant-apache-bcel.jar" />
+ <File DiskId="1" Id="file2" Name="AND873_1.JAR" LongName="ant-apache-bsf.jar" Vital="yes" src="$(var.dist.dir)/lib\ant-apache-bsf.jar" />
+ <File DiskId="1" Id="file3" Name="ANT-AP_4.JAR" LongName="ant-apache-log4j.jar" Vital="yes" src="$(var.dist.dir)/lib\ant-apache-log4j.jar" />
+ <File DiskId="1" Id="file4" Name="ANT-AP_3.JAR" LongName="ant-apache-oro.jar" Vital="yes" src="$(var.dist.dir)/lib\ant-apache-oro.jar" />
+ <File DiskId="1" Id="file5" Name="ANT-AP_1.JAR" LongName="ant-apache-regexp.jar" Vital="yes" src="$(var.dist.dir)/lib\ant-apache-regexp.jar" />
+ <File DiskId="1" Id="file6" Name="ANT-AP_2.JAR" LongName="ant-apache-resolver.jar" Vital="yes" src="$(var.dist.dir)/lib\ant-apache-resolver.jar" />
+ <File DiskId="1" Id="file7" Name="ANT-CO_1.JAR" LongName="ant-commons-logging.jar" Vital="yes" src="$(var.dist.dir)/lib\ant-commons-logging.jar" />
+ <File DiskId="1" Id="file8" Name="ANT-CO_2.JAR" LongName="ant-commons-net.jar" Vital="yes" src="$(var.dist.dir)/lib\ant-commons-net.jar" />
+ <File DiskId="1" Id="file9" Name="ant-jai.jar" Vital="yes" src="$(var.dist.dir)/lib\ant-jai.jar" />
+ <File DiskId="1" Id="file10" Name="ANT-JA_1.JAR" LongName="ant-javamail.jar" Vital="yes" src="$(var.dist.dir)/lib\ant-javamail.jar" />
+ <File DiskId="1" Id="file11" Name="ANT-JD_1.JAR" LongName="ant-jdepend.jar" Vital="yes" src="$(var.dist.dir)/lib\ant-jdepend.jar" />
+ <File DiskId="1" Id="file12" Name="ant-jmf.jar" Vital="yes" src="$(var.dist.dir)/lib\ant-jmf.jar" />
+ <File DiskId="1" Id="file13" Name="ant-jsch.jar" Vital="yes" src="$(var.dist.dir)/lib\ant-jsch.jar" />
+ <File DiskId="1" Id="file14" Name="ANT-JU_1.JAR" LongName="ant-junit.jar" Vital="yes" src="$(var.dist.dir)/lib\ant-junit.jar" />
+ <File DiskId="1" Id="file15" Name="ANT-LA_1.JAR" LongName="ant-launcher.jar" Vital="yes" src="$(var.dist.dir)/lib\ant-launcher.jar" />
+ <File DiskId="1" Id="file16" Name="ANT-NE_1.JAR" LongName="ant-netrexx.jar" Vital="yes" src="$(var.dist.dir)/lib\ant-netrexx.jar" />
+ <File DiskId="1" Id="file17" Name="ANT-NO_1.JAR" LongName="ant-nodeps.jar" Vital="yes" src="$(var.dist.dir)/lib\ant-nodeps.jar" />
+ <File DiskId="1" Id="file18" Name="ANT-ST_2.JAR" LongName="ant-starteam.jar" Vital="yes" src="$(var.dist.dir)/lib\ant-starteam.jar" />
+ <File DiskId="1" Id="file19" Name="ANT-SW_1.JAR" LongName="ant-swing.jar" Vital="yes" src="$(var.dist.dir)/lib\ant-swing.jar" />
+ <File DiskId="1" Id="file20" Name="ANT-WE_1.JAR" LongName="ant-weblogic.jar" Vital="yes" src="$(var.dist.dir)/lib\ant-weblogic.jar" />
+ <File DiskId="1" Id="file21" Name="ant.jar" Vital="yes" src="$(var.dist.dir)/lib\ant.jar" />
+ <File DiskId="1" Id="file22" Name="LIBRAR_1.PRO" LongName="libraries.properties" Vital="yes" src="$(var.dist.dir)/lib\libraries.properties" />
+ <File DiskId="1" Id="file23" Name="README" Vital="yes" src="$(var.dist.dir)/lib\README" />
+ </Component>
+ </Directory>
+ <Directory Id="directory1" Name="bin">
+ <Component Id="component1" DiskId="1" Guid="B1C93EBD-96B8-46c8-9CBD-246CB8964F89">
+ <File DiskId="1" Id="file29" Name="ant" Vital="yes" src="$(var.dist.dir)/bin\ant" />
+ <File DiskId="1" Id="file30" Name="ant.bat" Vital="yes" src="$(var.dist.dir)/bin\ant.bat" />
+ <File DiskId="1" Id="file31" Name="ant.cmd" Vital="yes" src="$(var.dist.dir)/bin\ant.cmd" />
+ <File DiskId="1" Id="file32" Name="antenv.cmd" Vital="yes" src="$(var.dist.dir)/bin\antenv.cmd" />
+ <File DiskId="1" Id="file33" Name="antRun" Vital="yes" src="$(var.dist.dir)/bin\antRun" />
+ <File DiskId="1" Id="file34" Name="antRun.bat" Vital="yes" src="$(var.dist.dir)/bin\antRun.bat" />
+ <File DiskId="1" Id="file35" Name="antRun.pl" Vital="yes" src="$(var.dist.dir)/bin\antRun.pl" />
+ <File DiskId="1" Id="file36" Name="COMPLE_1.PL" LongName="complete-ant-cmd.pl" Vital="yes" src="$(var.dist.dir)/bin\complete-ant-cmd.pl" />
+ <File DiskId="1" Id="file37" Name="envset.cmd" Vital="yes" src="$(var.dist.dir)/bin\envset.cmd" />
+ <File DiskId="1" Id="file38" Name="lcp.bat" Vital="yes" src="$(var.dist.dir)/bin\lcp.bat" />
+ <File DiskId="1" Id="file39" Name="runant.pl" Vital="yes" src="$(var.dist.dir)/bin\runant.pl" />
+ <File DiskId="1" Id="file40" Name="runant.py" Vital="yes" src="$(var.dist.dir)/bin\runant.py" />
+ <File DiskId="1" Id="file41" Name="runrc.cmd" Vital="yes" src="$(var.dist.dir)/bin\runrc.cmd" />
+ </Component>
+ </Directory>
+ <Directory Id="directory2" Name="docs">
+ <Component Id="component2" DiskId="1" Guid="3C4A5D18-7D5F-4d98-B810-83EE3EC47468">
+ <File DiskId="1" Id="file42" Name="ANTNEW_1.HTM" LongName="antnews.html" Vital="yes" src="$(var.dist.dir)/docs\antnews.html" />
+ <File DiskId="1" Id="file43" Name="ANT_IN_1.HTM" LongName="ant_in_anger.html" Vital="yes" src="$(var.dist.dir)/docs\ant_in_anger.html" />
+ <File DiskId="1" Id="file44" Name="ANT_TA_1.HTM" LongName="ant_task_guidelines.html" Vital="yes" src="$(var.dist.dir)/docs\ant_task_guidelines.html" />
+ <File DiskId="1" Id="file45" Name="APPEND_1.PDF" LongName="appendix_e.pdf" Vital="yes" src="$(var.dist.dir)/docs\appendix_e.pdf" />
+ <File DiskId="1" Id="file46" Name="BREADC_1.JS" LongName="breadcrumbs.js" Vital="yes" src="$(var.dist.dir)/docs\breadcrumbs.js" />
+ <File DiskId="1" Id="file47" Name="BUGS_1.HTM" LongName="bugs.html" Vital="yes" src="$(var.dist.dir)/docs\bugs.html" />
+ <File DiskId="1" Id="file48" Name="BYLAWS_1.HTM" LongName="bylaws.html" Vital="yes" src="$(var.dist.dir)/docs\bylaws.html" />
+ <File DiskId="1" Id="file49" Name="CONTRI_1.HTM" LongName="contributors.html" Vital="yes" src="$(var.dist.dir)/docs\contributors.html" />
+ <File DiskId="1" Id="file50" Name="EXTERN_1.HTM" LongName="external.html" Vital="yes" src="$(var.dist.dir)/docs\external.html" />
+ <File DiskId="1" Id="file51" Name="FAQ_1.HTM" LongName="faq.html" Vital="yes" src="$(var.dist.dir)/docs\faq.html" />
+ <File DiskId="1" Id="file52" Name="favicon.ico" Vital="yes" src="$(var.dist.dir)/docs\favicon.ico" />
+ <File DiskId="1" Id="file53" Name="INDEX_1.HTM" LongName="index.html" Vital="yes" src="$(var.dist.dir)/docs\index.html" />
+ <File DiskId="1" Id="file54" Name="LEGAL_1.HTM" LongName="legal.html" Vital="yes" src="$(var.dist.dir)/docs\legal.html" />
+ <File DiskId="1" Id="file55" Name="LICENSE" Vital="yes" src="$(var.dist.dir)/docs\LICENSE" />
+ <File DiskId="1" Id="file56" Name="LICENS_1.HTM" LongName="license.html" Vital="yes" src="$(var.dist.dir)/docs\license.html" />
+ <File DiskId="1" Id="file57" Name="MAIL_1.HTM" LongName="mail.html" Vital="yes" src="$(var.dist.dir)/docs\mail.html" />
+ <File DiskId="1" Id="file58" Name="MISSIO_1.HTM" LongName="mission.html" Vital="yes" src="$(var.dist.dir)/docs\mission.html" />
+ <File DiskId="1" Id="file59" Name="page.css" Vital="yes" src="$(var.dist.dir)/docs\page.css" />
+ <File DiskId="1" Id="file60" Name="PROBLE_1.HTM" LongName="problems.html" Vital="yes" src="$(var.dist.dir)/docs\problems.html" />
+ <File DiskId="1" Id="file61" Name="PROJEC_1.HTM" LongName="projects.html" Vital="yes" src="$(var.dist.dir)/docs\projects.html" />
+ <File DiskId="1" Id="file62" Name="RESOUR_1.HTM" LongName="resources.html" Vital="yes" src="$(var.dist.dir)/docs\resources.html" />
+ <File DiskId="1" Id="file63" Name="SVN_1.HTM" LongName="svn.html" Vital="yes" src="$(var.dist.dir)/docs\svn.html" />
+ </Component>
+ <Directory Id="directory3" Name="ant2">
+ <Component Id="component3" DiskId="1" Guid="B0B46EDA-078C-4042-802D-0FD43ECC51EC">
+ <File DiskId="1" Id="file64" Name="ACTION_1.HTM" LongName="actionlist.html" Vital="yes" src="$(var.dist.dir)/docs\ant2\actionlist.html" />
+ <File DiskId="1" Id="file65" Name="FEATUR_1.HTM" LongName="features.html" Vital="yes" src="$(var.dist.dir)/docs\ant2\features.html" />
+ <File DiskId="1" Id="file66" Name="FUNCTI_1.HTM" LongName="FunctionalRequirements.html" Vital="yes" src="$(var.dist.dir)/docs\ant2\FunctionalRequirements.html" />
+ <File DiskId="1" Id="file67" Name="ORIGIN_1.HTM" LongName="original-specification.html" Vital="yes" src="$(var.dist.dir)/docs\ant2\original-specification.html" />
+ <File DiskId="1" Id="file68" Name="REQUES_1.HTM" LongName="requested-features.html" Vital="yes" src="$(var.dist.dir)/docs\ant2\requested-features.html" />
+ <File DiskId="1" Id="file69" Name="REQUES_1.TXT" LongName="requested-features.txt" Vital="yes" src="$(var.dist.dir)/docs\ant2\requested-features.txt" />
+ <File DiskId="1" Id="file70" Name="VFS.txt" Vital="yes" src="$(var.dist.dir)/docs\ant2\VFS.txt" />
+ </Component>
+ </Directory>
+ <Directory Id="directory4" Name="antlibs">
+ <Component Id="component4" DiskId="1" Guid="3A955A77-B40C-4fdf-89F2-0B8ED71B3C9B">
+ <File DiskId="1" Id="file71" Name="CHARTE_1.HTM" LongName="charter.html" Vital="yes" src="$(var.dist.dir)/docs\antlibs\charter.html" />
+ <File DiskId="1" Id="file72" Name="INDEX_1.HTM" LongName="index.html" Vital="yes" src="$(var.dist.dir)/docs\antlibs\index.html" />
+ <File DiskId="1" Id="file73" Name="PROPER_1.HTM" LongName="proper.html" Vital="yes" src="$(var.dist.dir)/docs\antlibs\proper.html" />
+ <File DiskId="1" Id="file74" Name="SANDBO_1.HTM" LongName="sandbox.html" Vital="yes" src="$(var.dist.dir)/docs\antlibs\sandbox.html" />
+ </Component>
+ <Directory Id="directory5" Name="antunit">
+ <Component Id="component5" DiskId="1" Guid="001EC157-1971-4371-91D1-67438148BE4F">
+ <File DiskId="1" Id="file75" Name="INDEX_1.HTM" LongName="index.html" Vital="yes" src="$(var.dist.dir)/docs\antlibs\antunit\index.html" />
+ </Component>
+ </Directory>
+ <Directory Id="directory6" Name="dotnet">
+ <Component Id="component6" DiskId="1" Guid="946324D1-7A08-429b-9866-C88A7AFEC34B">
+ <File DiskId="1" Id="file76" Name="INDEX_1.HTM" LongName="index.html" Vital="yes" src="$(var.dist.dir)/docs\antlibs\dotnet\index.html" />
+ </Component>
+ </Directory>
+ <Directory Id="directory7" Name="svn">
+ <Component Id="component7" DiskId="1" Guid="92069BFE-0095-4570-A49F-3AFA2A37C65A">
+ <File DiskId="1" Id="file77" Name="INDEX_1.HTM" LongName="index.html" Vital="yes" src="$(var.dist.dir)/docs\antlibs\svn\index.html" />
+ </Component>
+ </Directory>
+ </Directory>
+ <Directory Id="directory8" Name="images">
+ <Component Id="component8" DiskId="1" Guid="CD77BA2D-BC86-4dfa-9DB3-ED1A13F1C742">
+ <File DiskId="1" Id="file78" Name="ant_logo.ico" Vital="yes" src="$(var.dist.dir)/docs\images\ant_logo.ico" />
+ <File DiskId="1" Id="file79" Name="ANT_LO_3.GIF" LongName="ant_logo_large.gif" Vital="yes" src="$(var.dist.dir)/docs\images\ant_logo_large.gif" />
+ <File DiskId="1" Id="file80" Name="ANT_LO_1.GIF" LongName="ant_logo_medium.gif" Vital="yes" src="$(var.dist.dir)/docs\images\ant_logo_medium.gif" />
+ <File DiskId="1" Id="file81" Name="ANT_LO_2.GIF" LongName="ant_logo_small.gif" Vital="yes" src="$(var.dist.dir)/docs\images\ant_logo_small.gif" />
+ <File DiskId="1" Id="file82" Name="beta.png" Vital="yes" src="$(var.dist.dir)/docs\images\beta.png" />
+ <File DiskId="1" Id="file83" Name="current.gif" Vital="yes" src="$(var.dist.dir)/docs\images\current.gif" />
+ <File DiskId="1" Id="file84" Name="GROUP-_1.GIF" LongName="group-logo.gif" Vital="yes" src="$(var.dist.dir)/docs\images\group-logo.gif" />
+ <File DiskId="1" Id="file85" Name="JDJEDI_1.JPG" LongName="JDJEditorsChoiceAward.jpg" Vital="yes" src="$(var.dist.dir)/docs\images\JDJEditorsChoiceAward.jpg" />
+ <File DiskId="1" Id="file86" Name="JP_RCW_1.GIF" LongName="jp_rcwinner_2003.gif" Vital="yes" src="$(var.dist.dir)/docs\images\jp_rcwinner_2003.gif" />
+ <File DiskId="1" Id="file87" Name="JW_EC__2.GIF" LongName="jw_ec_logo_winner2002.gif" Vital="yes" src="$(var.dist.dir)/docs\images\jw_ec_logo_winner2002.gif" />
+ <File DiskId="1" Id="file88" Name="JW_EC__1.GIF" LongName="jw_ec_logo_winner2003.gif" Vital="yes" src="$(var.dist.dir)/docs\images\jw_ec_logo_winner2003.gif" />
+ <File DiskId="1" Id="file89" Name="label.gif" Vital="yes" src="$(var.dist.dir)/docs\images\label.gif" />
+ <File DiskId="1" Id="file90" Name="MENU-L_1.GIF" LongName="menu-left.gif" Vital="yes" src="$(var.dist.dir)/docs\images\menu-left.gif" />
+ <File DiskId="1" Id="file91" Name="MENU-R_1.GIF" LongName="menu-right.gif" Vital="yes" src="$(var.dist.dir)/docs\images\menu-right.gif" />
+ <File DiskId="1" Id="file92" Name="page.gif" Vital="yes" src="$(var.dist.dir)/docs\images\page.gif" />
+ <File DiskId="1" Id="file93" Name="printer.gif" Vital="yes" src="$(var.dist.dir)/docs\images\printer.gif" />
+ <File DiskId="1" Id="file94" Name="PROJEC_1.GIF" LongName="project-logo.gif" Vital="yes" src="$(var.dist.dir)/docs\images\project-logo.gif" />
+ <File DiskId="1" Id="file95" Name="SDM_PR_1.GIF" LongName="sdm_productivity_award.gif" Vital="yes" src="$(var.dist.dir)/docs\images\sdm_productivity_award.gif" />
+ <File DiskId="1" Id="file96" Name="SEARCH_1.GIF" LongName="search-left.gif" Vital="yes" src="$(var.dist.dir)/docs\images\search-left.gif" />
+ <File DiskId="1" Id="file97" Name="SEARCH_2.GIF" LongName="search-right.gif" Vital="yes" src="$(var.dist.dir)/docs\images\search-right.gif" />
+ <File DiskId="1" Id="file98" Name="spacer.gif" Vital="yes" src="$(var.dist.dir)/docs\images\spacer.gif" />
+ <File DiskId="1" Id="file99" Name="tab-left.gif" Vital="yes" src="$(var.dist.dir)/docs\images\tab-left.gif" />
+ <File DiskId="1" Id="file100" Name="TAB-RI_1.GIF" LongName="tab-right.gif" Vital="yes" src="$(var.dist.dir)/docs\images\tab-right.gif" />
+ <File DiskId="1" Id="file101" Name="TABSEL_1.GIF" LongName="tabSel-left.gif" Vital="yes" src="$(var.dist.dir)/docs\images\tabSel-left.gif" />
+ <File DiskId="1" Id="file102" Name="TABSEL_2.GIF" LongName="tabSel-right.gif" Vital="yes" src="$(var.dist.dir)/docs\images\tabSel-right.gif" />
+ </Component>
+ </Directory>
+ <Directory Id="manual" Name="manual">
+ <Component Id="component9" DiskId="1" Guid="75121217-770F-4a38-97FC-8F44779ACA9C">
+ <File DiskId="1" Id="file103" Name="ANTEXT_1.HTM" LongName="antexternal.html" Vital="yes" src="$(var.dist.dir)/docs\manual\antexternal.html" />
+ <File DiskId="1" Id="file104" Name="ANTTAS_1.HTM" LongName="anttaskslist.html" Vital="yes" src="$(var.dist.dir)/docs\manual\anttaskslist.html" />
+ <File DiskId="1" Id="file105" Name="BASE_T_1.HTM" LongName="base_task_classes.html" Vital="yes" src="$(var.dist.dir)/docs\manual\base_task_classes.html" />
+ <File DiskId="1" Id="file106" Name="CLONEV_1.HTM" LongName="clonevm.html" Vital="yes" src="$(var.dist.dir)/docs\manual\clonevm.html" />
+ <File DiskId="1" Id="file107" Name="CONCEP_1.HTM" LongName="conceptstypeslist.html" Vital="yes" src="$(var.dist.dir)/docs\manual\conceptstypeslist.html" />
+ <File DiskId="1" Id="file108" Name="CORETA_1.HTM" LongName="coretasklist.html" Vital="yes" src="$(var.dist.dir)/docs\manual\coretasklist.html" />
+ <File DiskId="1" Id="file109" Name="COVER_1.HTM" LongName="cover.html" Vital="yes" src="$(var.dist.dir)/docs\manual\cover.html" />
+ <File DiskId="1" Id="file110" Name="CREDIT_1.HTM" LongName="credits.html" Vital="yes" src="$(var.dist.dir)/docs\manual\credits.html" />
+ <File DiskId="1" Id="file111" Name="DEVELO_1.HTM" LongName="develop.html" Vital="yes" src="$(var.dist.dir)/docs\manual\develop.html" />
+ <File DiskId="1" Id="file112" Name="DEVELO_2.HTM" LongName="developlist.html" Vital="yes" src="$(var.dist.dir)/docs\manual\developlist.html" />
+ <File DiskId="1" Id="file113" Name="DIRTAS_1.HTM" LongName="dirtasks.html" Vital="yes" src="$(var.dist.dir)/docs\manual\dirtasks.html" />
+ <File DiskId="1" Id="file114" Name="favicon.ico" Vital="yes" src="$(var.dist.dir)/docs\manual\favicon.ico" />
+ <File DiskId="1" Id="file115" Name="FEEDBA_1.HTM" LongName="feedback.html" Vital="yes" src="$(var.dist.dir)/docs\manual\feedback.html" />
+ <File DiskId="1" Id="file116" Name="IDE_1.HTM" LongName="ide.html" Vital="yes" src="$(var.dist.dir)/docs\manual\ide.html" />
+ <File DiskId="1" Id="file118" Name="INPUTH_1.HTM" LongName="inputhandler.html" Vital="yes" src="$(var.dist.dir)/docs\manual\inputhandler.html" />
+ <File DiskId="1" Id="file119" Name="INSTAL_1.HTM" LongName="install.html" Vital="yes" src="$(var.dist.dir)/docs\manual\install.html" />
+ <File DiskId="1" Id="file120" Name="INSTAL_2.HTM" LongName="installlist.html" Vital="yes" src="$(var.dist.dir)/docs\manual\installlist.html" />
+ <File DiskId="1" Id="file121" Name="INTRO_1.HTM" LongName="intro.html" Vital="yes" src="$(var.dist.dir)/docs\manual\intro.html" />
+ <File DiskId="1" Id="file122" Name="JAVACP_1.HTM" LongName="javacprops.html" Vital="yes" src="$(var.dist.dir)/docs\manual\javacprops.html" />
+ <File DiskId="1" Id="file123" Name="LICENSE" Vital="yes" src="$(var.dist.dir)/docs\manual\LICENSE" />
+ <File DiskId="1" Id="file124" Name="LISTEN_1.HTM" LongName="listeners.html" Vital="yes" src="$(var.dist.dir)/docs\manual\listeners.html" />
+ <File DiskId="1" Id="file125" Name="OPTION_1.HTM" LongName="optionaltasklist.html" Vital="yes" src="$(var.dist.dir)/docs\manual\optionaltasklist.html" />
+ <File DiskId="1" Id="file126" Name="PLATFO_1.HTM" LongName="platform.html" Vital="yes" src="$(var.dist.dir)/docs\manual\platform.html" />
+ <File DiskId="1" Id="file127" Name="PROXY_1.HTM" LongName="proxy.html" Vital="yes" src="$(var.dist.dir)/docs\manual\proxy.html" />
+ <File DiskId="1" Id="file128" Name="RUNNIN_2.HTM" LongName="running.html" Vital="yes" src="$(var.dist.dir)/docs\manual\running.html" />
+ <File DiskId="1" Id="file129" Name="RUNNIN_1.HTM" LongName="runninglist.html" Vital="yes" src="$(var.dist.dir)/docs\manual\runninglist.html" />
+ <File DiskId="1" Id="file130" Name="SYSCLA_1.HTM" LongName="sysclasspath.html" Vital="yes" src="$(var.dist.dir)/docs\manual\sysclasspath.html" />
+ <File DiskId="1" Id="file131" Name="TASKSO_1.HTM" LongName="tasksoverview.html" Vital="yes" src="$(var.dist.dir)/docs\manual\tasksoverview.html" />
+ <File DiskId="1" Id="file132" Name="TOC_1.HTM" LongName="toc.html" Vital="yes" src="$(var.dist.dir)/docs\manual\toc.html" />
+ <File DiskId="1" Id="file133" Name="TUTORI_1.HTM" LongName="tutorial-HelloWorldWithAnt.html" Vital="yes" src="$(var.dist.dir)/docs\manual\tutorial-HelloWorldWithAnt.html" />
+ <File DiskId="1" Id="file134" Name="TUTORI_3.HTM" LongName="tutorial-tasks-filesets-properties.html" Vital="yes" src="$(var.dist.dir)/docs\manual\tutorial-tasks-filesets-properties.html" />
+ <File DiskId="1" Id="file135" Name="TUTORI_1.ZIP" LongName="tutorial-tasks-filesets-properties.zip" Vital="yes" src="$(var.dist.dir)/docs\manual\tutorial-tasks-filesets-properties.zip" />
+ <File DiskId="1" Id="file136" Name="TUTORI_2.ZIP" LongName="tutorial-writing-tasks-src.zip" Vital="yes" src="$(var.dist.dir)/docs\manual\tutorial-writing-tasks-src.zip" />
+ <File DiskId="1" Id="file137" Name="TUTORI_2.HTM" LongName="tutorial-writing-tasks.html" Vital="yes" src="$(var.dist.dir)/docs\manual\tutorial-writing-tasks.html" />
+ <File DiskId="1" Id="file138" Name="USING_1.HTM" LongName="using.html" Vital="yes" src="$(var.dist.dir)/docs\manual\using.html" />
+ <File DiskId="1" Id="file139" Name="USINGL_1.HTM" LongName="usinglist.html" Vital="yes" src="$(var.dist.dir)/docs\manual\usinglist.html" />
+ </Component>
+ <Directory Id="directory89" Name="CORETA_1" LongName="CoreTasks">
+ <Component Id="component86" DiskId="1" Guid="5853F9CD-8B34-410d-80DD-9595C9EA9AB5">
+ <File DiskId="1" Id="file399" Name="ANT_1.HTM" LongName="ant.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTasks\ant.html" />
+ <File DiskId="1" Id="file400" Name="ANTCAL_1.HTM" LongName="antcall.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTasks\antcall.html" />
+ <File DiskId="1" Id="file401" Name="ANTSTR_1.HTM" LongName="antstructure.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTasks\antstructure.html" />
+ <File DiskId="1" Id="file402" Name="APPLY_1.HTM" LongName="apply.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTasks\apply.html" />
+ <File DiskId="1" Id="file403" Name="APT_1.HTM" LongName="apt.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTasks\apt.html" />
+ <File DiskId="1" Id="file404" Name="AVAILA_1.HTM" LongName="available.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTasks\available.html" />
+ <File DiskId="1" Id="file405" Name="BASENA_1.HTM" LongName="basename.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTasks\basename.html" />
+ <File DiskId="1" Id="file406" Name="BUILDN_1.HTM" LongName="buildnumber.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTasks\buildnumber.html" />
+ <File DiskId="1" Id="file407" Name="CHANGE_1.HTM" LongName="changelog.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTasks\changelog.html" />
+ <File DiskId="1" Id="file408" Name="CHECKS_1.HTM" LongName="checksum.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTasks\checksum.html" />
+ <File DiskId="1" Id="file409" Name="CHMOD_1.HTM" LongName="chmod.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTasks\chmod.html" />
+ <File DiskId="1" Id="file410" Name="COMMON_1.HTM" LongName="common.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTasks\common.html" />
+ <File DiskId="1" Id="file411" Name="CONCAT_1.HTM" LongName="concat.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTasks\concat.html" />
+ <File DiskId="1" Id="file412" Name="CONDIT_1.HTM" LongName="condition.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTasks\condition.html" />
+ <File DiskId="1" Id="file413" Name="CONDIT_2.HTM" LongName="conditions.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTasks\conditions.html" />
+ <File DiskId="1" Id="file414" Name="COPY_1.HTM" LongName="copy.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTasks\copy.html" />
+ <File DiskId="1" Id="file415" Name="COPYDI_1.HTM" LongName="copydir.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTasks\copydir.html" />
+ <File DiskId="1" Id="file416" Name="COPYFI_1.HTM" LongName="copyfile.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTasks\copyfile.html" />
+ <File DiskId="1" Id="file417" Name="CVS_1.HTM" LongName="cvs.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTasks\cvs.html" />
+ <File DiskId="1" Id="file418" Name="CVSPAS_1.HTM" LongName="cvspass.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTasks\cvspass.html" />
+ <File DiskId="1" Id="file419" Name="CVSTAG_1.HTM" LongName="cvstagdiff.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTasks\cvstagdiff.html" />
+ <File DiskId="1" Id="file420" Name="CVSVER_1.HTM" LongName="cvsversion.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTasks\cvsversion.html" />
+ <File DiskId="1" Id="file421" Name="DEFAUL_1.HTM" LongName="defaultexcludes.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTasks\defaultexcludes.html" />
+ <File DiskId="1" Id="file422" Name="DELETE_1.HTM" LongName="delete.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTasks\delete.html" />
+ <File DiskId="1" Id="file423" Name="DELTRE_1.HTM" LongName="deltree.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTasks\deltree.html" />
+ <File DiskId="1" Id="file424" Name="DEPEND_1.HTM" LongName="dependset.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTasks\dependset.html" />
+ <File DiskId="1" Id="file425" Name="DIRNAM_1.HTM" LongName="dirname.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTasks\dirname.html" />
+ <File DiskId="1" Id="file426" Name="EAR_1.HTM" LongName="ear.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTasks\ear.html" />
+ <File DiskId="1" Id="file427" Name="ECHO_1.HTM" LongName="echo.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTasks\echo.html" />
+ <File DiskId="1" Id="file428" Name="ECHOXM_1.HTM" LongName="echoxml.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTasks\echoxml.html" />
+ <File DiskId="1" Id="file429" Name="EXEC_1.HTM" LongName="exec.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTasks\exec.html" />
+ <File DiskId="1" Id="file430" Name="FAIL_1.HTM" LongName="fail.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTasks\fail.html" />
+ <File DiskId="1" Id="file431" Name="FILTER_1.HTM" LongName="filter.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTasks\filter.html" />
+ <File DiskId="1" Id="file432" Name="FIXCRL_1.HTM" LongName="fixcrlf.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTasks\fixcrlf.html" />
+ <File DiskId="1" Id="file433" Name="GENKEY_1.HTM" LongName="genkey.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTasks\genkey.html" />
+ <File DiskId="1" Id="file434" Name="GET_1.HTM" LongName="get.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTasks\get.html" />
+ <File DiskId="1" Id="file435" Name="GUNZIP_1.HTM" LongName="gunzip.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTasks\gunzip.html" />
+ <File DiskId="1" Id="file436" Name="GZIP_1.HTM" LongName="gzip.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTasks\gzip.html" />
+ <File DiskId="1" Id="file437" Name="IMPORT_1.HTM" LongName="import.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTasks\import.html" />
+ <File DiskId="1" Id="file438" Name="INPUT_1.HTM" LongName="input.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTasks\input.html" />
+ <File DiskId="1" Id="file439" Name="JAR_1.HTM" LongName="jar.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTasks\jar.html" />
+ <File DiskId="1" Id="file440" Name="JAVA_1.HTM" LongName="java.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTasks\java.html" />
+ <File DiskId="1" Id="file441" Name="JAVAC_1.HTM" LongName="javac.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTasks\javac.html" />
+ <File DiskId="1" Id="file442" Name="JAVADO_1.HTM" LongName="javadoc.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTasks\javadoc.html" />
+ <File DiskId="1" Id="file443" Name="LENGTH_1.HTM" LongName="length.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTasks\length.html" />
+ <File DiskId="1" Id="file444" Name="LIBRAR_1.HTM" LongName="libraries.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTasks\libraries.html" />
+ <File DiskId="1" Id="file445" Name="LOADFI_1.HTM" LongName="loadfile.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTasks\loadfile.html" />
+ <File DiskId="1" Id="file446" Name="LOADPR_1.HTM" LongName="loadproperties.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTasks\loadproperties.html" />
+ <File DiskId="1" Id="file447" Name="LOADRE_1.HTM" LongName="loadresource.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTasks\loadresource.html" />
+ <File DiskId="1" Id="file448" Name="MACROD_1.HTM" LongName="macrodef.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTasks\macrodef.html" />
+ <File DiskId="1" Id="file449" Name="MAIL_1.HTM" LongName="mail.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTasks\mail.html" />
+ <File DiskId="1" Id="file450" Name="MAKEUR_1.HTM" LongName="makeurl.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTasks\makeurl.html" />
+ <File DiskId="1" Id="file451" Name="MANIFE_1.HTM" LongName="manifest.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTasks\manifest.html" />
+ <File DiskId="1" Id="file452" Name="MANIFE_2.HTM" LongName="manifestclasspath.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTasks\manifestclasspath.html" />
+ <File DiskId="1" Id="file453" Name="MKDIR_1.HTM" LongName="mkdir.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTasks\mkdir.html" />
+ <File DiskId="1" Id="file454" Name="MOVE_1.HTM" LongName="move.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTasks\move.html" />
+ <File DiskId="1" Id="file455" Name="NICE_1.HTM" LongName="nice.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTasks\nice.html" />
+ <File DiskId="1" Id="file456" Name="PACK_1.HTM" LongName="pack.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTasks\pack.html" />
+ <File DiskId="1" Id="file457" Name="PARALL_1.HTM" LongName="parallel.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTasks\parallel.html" />
+ <File DiskId="1" Id="file458" Name="PATCH_1.HTM" LongName="patch.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTasks\patch.html" />
+ <File DiskId="1" Id="file459" Name="PATHCO_1.HTM" LongName="pathconvert.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTasks\pathconvert.html" />
+ <File DiskId="1" Id="file460" Name="PRESET_1.HTM" LongName="presetdef.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTasks\presetdef.html" />
+ <File DiskId="1" Id="file461" Name="PROPER_1.HTM" LongName="property.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTasks\property.html" />
+ <File DiskId="1" Id="file462" Name="RECORD_1.HTM" LongName="recorder.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTasks\recorder.html" />
+ <File DiskId="1" Id="file463" Name="RENAME_1.HTM" LongName="rename.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTasks\rename.html" />
+ <File DiskId="1" Id="file464" Name="REPLAC_1.HTM" LongName="replace.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTasks\replace.html" />
+ <File DiskId="1" Id="file465" Name="RESOUR_1.HTM" LongName="resourcecount.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTasks\resourcecount.html" />
+ <File DiskId="1" Id="file466" Name="RMIC_1.HTM" LongName="rmic.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTasks\rmic.html" />
+ <File DiskId="1" Id="file467" Name="SEQUEN_1.HTM" LongName="sequential.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTasks\sequential.html" />
+ <File DiskId="1" Id="file468" Name="SIGNJA_1.HTM" LongName="signjar.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTasks\signjar.html" />
+ <File DiskId="1" Id="file469" Name="SLEEP_1.HTM" LongName="sleep.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTasks\sleep.html" />
+ <File DiskId="1" Id="file470" Name="SQL_1.HTM" LongName="sql.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTasks\sql.html" />
+ <File DiskId="1" Id="file471" Name="STYLE_1.HTM" LongName="style.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTasks\style.html" />
+ <File DiskId="1" Id="file472" Name="SUBANT_1.HTM" LongName="subant.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTasks\subant.html" />
+ <File DiskId="1" Id="file473" Name="SYNC_1.HTM" LongName="sync.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTasks\sync.html" />
+ <File DiskId="1" Id="file474" Name="TAR_1.HTM" LongName="tar.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTasks\tar.html" />
+ <File DiskId="1" Id="file475" Name="TASKDE_1.HTM" LongName="taskdef.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTasks\taskdef.html" />
+ <File DiskId="1" Id="file476" Name="TEMPFI_1.HTM" LongName="tempfile.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTasks\tempfile.html" />
+ <File DiskId="1" Id="file477" Name="TOUCH_1.HTM" LongName="touch.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTasks\touch.html" />
+ <File DiskId="1" Id="file478" Name="TSTAMP_1.HTM" LongName="tstamp.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTasks\tstamp.html" />
+ <File DiskId="1" Id="file479" Name="TYPEDE_1.HTM" LongName="typedef.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTasks\typedef.html" />
+ <File DiskId="1" Id="file480" Name="UNPACK_1.HTM" LongName="unpack.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTasks\unpack.html" />
+ <File DiskId="1" Id="file481" Name="UNTAR_1.HTM" LongName="untar.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTasks\untar.html" />
+ <File DiskId="1" Id="file482" Name="UNZIP_1.HTM" LongName="unzip.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTasks\unzip.html" />
+ <File DiskId="1" Id="file483" Name="UPTODA_1.HTM" LongName="uptodate.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTasks\uptodate.html" />
+ <File DiskId="1" Id="file484" Name="WAITFO_1.HTM" LongName="waitfor.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTasks\waitfor.html" />
+ <File DiskId="1" Id="file485" Name="WAR_1.HTM" LongName="war.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTasks\war.html" />
+ <File DiskId="1" Id="file486" Name="WHICHR_1.HTM" LongName="whichresource.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTasks\whichresource.html" />
+ <File DiskId="1" Id="file487" Name="XMLPRO_1.HTM" LongName="xmlproperty.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTasks\xmlproperty.html" />
+ <File DiskId="1" Id="file488" Name="ZIP_1.HTM" LongName="zip.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTasks\zip.html" />
+ </Component>
+ </Directory>
+ <Directory Id="directory90" Name="CORETY_1" LongName="CoreTypes">
+ <Component Id="component87" DiskId="1" Guid="2BDC2593-705E-48c2-BC85-22BB4A4D242C">
+ <File DiskId="1" Id="file489" Name="ANTLIB_1.HTM" LongName="antlib.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTypes\antlib.html" />
+ <File DiskId="1" Id="file490" Name="ASSERT_1.HTM" LongName="assertions.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTypes\assertions.html" />
+ <File DiskId="1" Id="file491" Name="CUSTOM_1.HTM" LongName="custom-programming.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTypes\custom-programming.html" />
+ <File DiskId="1" Id="file492" Name="DESCRI_1.HTM" LongName="description.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTypes\description.html" />
+ <File DiskId="1" Id="file493" Name="DIRSET_1.HTM" LongName="dirset.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTypes\dirset.html" />
+ <File DiskId="1" Id="file494" Name="FILELI_1.HTM" LongName="filelist.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTypes\filelist.html" />
+ <File DiskId="1" Id="file495" Name="FILESE_1.HTM" LongName="fileset.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTypes\fileset.html" />
+ <File DiskId="1" Id="file496" Name="FILTER_1.HTM" LongName="filterchain.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTypes\filterchain.html" />
+ <File DiskId="1" Id="file497" Name="FILTER_2.HTM" LongName="filterset.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTypes\filterset.html" />
+ <File DiskId="1" Id="file498" Name="MAPPER_1.HTM" LongName="mapper.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTypes\mapper.html" />
+ <File DiskId="1" Id="file499" Name="NAMESP_1.HTM" LongName="namespace.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTypes\namespace.html" />
+ <File DiskId="1" Id="file500" Name="PATTER_1.HTM" LongName="patternset.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTypes\patternset.html" />
+ <File DiskId="1" Id="file501" Name="PERMIS_1.HTM" LongName="permissions.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTypes\permissions.html" />
+ <File DiskId="1" Id="file502" Name="PROPER_1.HTM" LongName="propertyset.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTypes\propertyset.html" />
+ <File DiskId="1" Id="file503" Name="REDIRE_1.HTM" LongName="redirector.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTypes\redirector.html" />
+ <File DiskId="1" Id="file504" Name="REGEXP_1.HTM" LongName="regexp.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTypes\regexp.html" />
+ <File DiskId="1" Id="file505" Name="RESOUR_1.HTM" LongName="resources.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTypes\resources.html" />
+ <File DiskId="1" Id="file506" Name="SELECT_1.HTM" LongName="selectors-program.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTypes\selectors-program.html" />
+ <File DiskId="1" Id="file507" Name="SELECT_2.HTM" LongName="selectors.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTypes\selectors.html" />
+ <File DiskId="1" Id="file508" Name="TARFIL_1.HTM" LongName="tarfileset.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTypes\tarfileset.html" />
+ <File DiskId="1" Id="file509" Name="XMLCAT_1.HTM" LongName="xmlcatalog.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTypes\xmlcatalog.html" />
+ <File DiskId="1" Id="file510" Name="ZIPFIL_1.HTM" LongName="zipfileset.html" Vital="yes" src="$(var.dist.dir)/docs\manual\CoreTypes\zipfileset.html" />
+ </Component>
+ </Directory>
+ <Directory Id="directory91" Name="INTEGR_1" LongName="Integration">
+ <Component Id="component88" DiskId="1" Guid="BBE81178-4985-4100-A40F-9E82CF9299B2">
+ <File DiskId="1" Id="file511" Name="ANTIDO_1.HTM" LongName="Antidote.html" Vital="yes" src="$(var.dist.dir)/docs\manual\Integration\Antidote.html" />
+ <File DiskId="1" Id="file512" Name="anttool1.gif" Vital="yes" src="$(var.dist.dir)/docs\manual\Integration\anttool1.gif" />
+ <File DiskId="1" Id="file513" Name="JEXT-P_1.HTM" LongName="jext-plugin.html" Vital="yes" src="$(var.dist.dir)/docs\manual\Integration\jext-plugin.html" />
+ <File DiskId="1" Id="file514" Name="remacc.gif" Vital="yes" src="$(var.dist.dir)/docs\manual\Integration\remacc.gif" />
+ <File DiskId="1" Id="file515" Name="toolmenu.gif" Vital="yes" src="$(var.dist.dir)/docs\manual\Integration\toolmenu.gif" />
+ </Component>
+ </Directory>
+ <Directory Id="directory92" Name="OPTION_1" LongName="OptionalTasks">
+ <Component Id="component89" DiskId="1" Guid="85A5E430-F30C-4c89-B2D4-2758DFAD681A">
+ <File DiskId="1" Id="file516" Name="ANTLR_1.HTM" LongName="antlr.html" Vital="yes" src="$(var.dist.dir)/docs\manual\OptionalTasks\antlr.html" />
+ <File DiskId="1" Id="file517" Name="ATTRIB_1.HTM" LongName="attrib.html" Vital="yes" src="$(var.dist.dir)/docs\manual\OptionalTasks\attrib.html" />
+ <File DiskId="1" Id="file518" Name="BORLAN_1.HTM" LongName="BorlandEJBTasks.html" Vital="yes" src="$(var.dist.dir)/docs\manual\OptionalTasks\BorlandEJBTasks.html" />
+ <File DiskId="1" Id="file519" Name="BORLAN_2.HTM" LongName="BorlandGenerateClient.html" Vital="yes" src="$(var.dist.dir)/docs\manual\OptionalTasks\BorlandGenerateClient.html" />
+ <File DiskId="1" Id="file520" Name="CAB_1.HTM" LongName="cab.html" Vital="yes" src="$(var.dist.dir)/docs\manual\OptionalTasks\cab.html" />
+ <File DiskId="1" Id="file521" Name="CCM_1.HTM" LongName="ccm.html" Vital="yes" src="$(var.dist.dir)/docs\manual\OptionalTasks\ccm.html" />
+ <File DiskId="1" Id="file522" Name="CHGRP_1.HTM" LongName="chgrp.html" Vital="yes" src="$(var.dist.dir)/docs\manual\OptionalTasks\chgrp.html" />
+ <File DiskId="1" Id="file523" Name="CHOWN_1.HTM" LongName="chown.html" Vital="yes" src="$(var.dist.dir)/docs\manual\OptionalTasks\chown.html" />
+ <File DiskId="1" Id="file524" Name="CLEARC_1.HTM" LongName="clearcase.html" Vital="yes" src="$(var.dist.dir)/docs\manual\OptionalTasks\clearcase.html" />
+ <File DiskId="1" Id="file525" Name="CSC_1.HTM" LongName="csc.html" Vital="yes" src="$(var.dist.dir)/docs\manual\OptionalTasks\csc.html" />
+ <File DiskId="1" Id="file526" Name="DEPEND_1.HTM" LongName="depend.html" Vital="yes" src="$(var.dist.dir)/docs\manual\OptionalTasks\depend.html" />
+ <File DiskId="1" Id="file527" Name="DOTNET_1.HTM" LongName="dotnet.html" Vital="yes" src="$(var.dist.dir)/docs\manual\OptionalTasks\dotnet.html" />
+ <File DiskId="1" Id="file528" Name="ECHOPR_1.HTM" LongName="echoproperties.html" Vital="yes" src="$(var.dist.dir)/docs\manual\OptionalTasks\echoproperties.html" />
+ <File DiskId="1" Id="file529" Name="EJB_1.HTM" LongName="ejb.html" Vital="yes" src="$(var.dist.dir)/docs\manual\OptionalTasks\ejb.html" />
+ <File DiskId="1" Id="file530" Name="FTP_1.HTM" LongName="ftp.html" Vital="yes" src="$(var.dist.dir)/docs\manual\OptionalTasks\ftp.html" />
+ <File DiskId="1" Id="file531" Name="ILASM_1.HTM" LongName="ilasm.html" Vital="yes" src="$(var.dist.dir)/docs\manual\OptionalTasks\ilasm.html" />
+ <File DiskId="1" Id="file532" Name="ILDASM_1.HTM" LongName="ildasm.html" Vital="yes" src="$(var.dist.dir)/docs\manual\OptionalTasks\ildasm.html" />
+ <File DiskId="1" Id="file533" Name="IMAGE-_1.GIF" LongName="image-classdiagram.gif" Vital="yes" src="$(var.dist.dir)/docs\manual\OptionalTasks\image-classdiagram.gif" />
+ <File DiskId="1" Id="file534" Name="IMAGE_1.HTM" LongName="image.html" Vital="yes" src="$(var.dist.dir)/docs\manual\OptionalTasks\image.html" />
+ <File DiskId="1" Id="file535" Name="IMPORT_1.HTM" LongName="importtypelib.html" Vital="yes" src="$(var.dist.dir)/docs\manual\OptionalTasks\importtypelib.html" />
+ <File DiskId="1" Id="file536" Name="JARLIB_1.HTM" LongName="jarlib-available.html" Vital="yes" src="$(var.dist.dir)/docs\manual\OptionalTasks\jarlib-available.html" />
+ <File DiskId="1" Id="file537" Name="JARLIB_2.HTM" LongName="jarlib-display.html" Vital="yes" src="$(var.dist.dir)/docs\manual\OptionalTasks\jarlib-display.html" />
+ <File DiskId="1" Id="file538" Name="JARLIB_4.HTM" LongName="jarlib-manifest.html" Vital="yes" src="$(var.dist.dir)/docs\manual\OptionalTasks\jarlib-manifest.html" />
+ <File DiskId="1" Id="file539" Name="JARLIB_3.HTM" LongName="jarlib-resolve.html" Vital="yes" src="$(var.dist.dir)/docs\manual\OptionalTasks\jarlib-resolve.html" />
+ <File DiskId="1" Id="file540" Name="JAVACC_1.HTM" LongName="javacc.html" Vital="yes" src="$(var.dist.dir)/docs\manual\OptionalTasks\javacc.html" />
+ <File DiskId="1" Id="file541" Name="JAVAH_1.HTM" LongName="javah.html" Vital="yes" src="$(var.dist.dir)/docs\manual\OptionalTasks\javah.html" />
+ <File DiskId="1" Id="file542" Name="JDEPEN_1.HTM" LongName="jdepend.html" Vital="yes" src="$(var.dist.dir)/docs\manual\OptionalTasks\jdepend.html" />
+ <File DiskId="1" Id="file543" Name="JJDOC_1.HTM" LongName="jjdoc.html" Vital="yes" src="$(var.dist.dir)/docs\manual\OptionalTasks\jjdoc.html" />
+ <File DiskId="1" Id="file544" Name="JJTREE_1.HTM" LongName="jjtree.html" Vital="yes" src="$(var.dist.dir)/docs\manual\OptionalTasks\jjtree.html" />
+ <File DiskId="1" Id="file545" Name="JLINK_1.HTM" LongName="jlink.html" Vital="yes" src="$(var.dist.dir)/docs\manual\OptionalTasks\jlink.html" />
+ <File DiskId="1" Id="file546" Name="JPCOVE_1.HTM" LongName="jpcoverage.html" Vital="yes" src="$(var.dist.dir)/docs\manual\OptionalTasks\jpcoverage.html" />
+ <File DiskId="1" Id="file547" Name="JSHARP_1.HTM" LongName="jsharpc.html" Vital="yes" src="$(var.dist.dir)/docs\manual\OptionalTasks\jsharpc.html" />
+ <File DiskId="1" Id="file548" Name="JSPC_1.HTM" LongName="jspc.html" Vital="yes" src="$(var.dist.dir)/docs\manual\OptionalTasks\jspc.html" />
+ <File DiskId="1" Id="file549" Name="JUNIT_1.HTM" LongName="junit.html" Vital="yes" src="$(var.dist.dir)/docs\manual\OptionalTasks\junit.html" />
+ <File DiskId="1" Id="file550" Name="JUNITR_1.HTM" LongName="junitreport.html" Vital="yes" src="$(var.dist.dir)/docs\manual\OptionalTasks\junitreport.html" />
+ <File DiskId="1" Id="file551" Name="MAUDIT_1.HTM" LongName="maudit.html" Vital="yes" src="$(var.dist.dir)/docs\manual\OptionalTasks\maudit.html" />
+ <File DiskId="1" Id="file552" Name="MIMEMA_1.HTM" LongName="mimemail.html" Vital="yes" src="$(var.dist.dir)/docs\manual\OptionalTasks\mimemail.html" />
+ <File DiskId="1" Id="file553" Name="MMETRI_1.HTM" LongName="mmetrics.html" Vital="yes" src="$(var.dist.dir)/docs\manual\OptionalTasks\mmetrics.html" />
+ <File DiskId="1" Id="file554" Name="MPARSE_1.HTM" LongName="mparse.html" Vital="yes" src="$(var.dist.dir)/docs\manual\OptionalTasks\mparse.html" />
+ <File DiskId="1" Id="file555" Name="NATIVE_1.HTM" LongName="native2ascii.html" Vital="yes" src="$(var.dist.dir)/docs\manual\OptionalTasks\native2ascii.html" />
+ <File DiskId="1" Id="file556" Name="NETREX_1.HTM" LongName="netrexxc.html" Vital="yes" src="$(var.dist.dir)/docs\manual\OptionalTasks\netrexxc.html" />
+ <File DiskId="1" Id="file557" Name="PROPER_1.HTM" LongName="propertyfile.html" Vital="yes" src="$(var.dist.dir)/docs\manual\OptionalTasks\propertyfile.html" />
+ <File DiskId="1" Id="file558" Name="PVCSTA_1.HTM" LongName="pvcstask.html" Vital="yes" src="$(var.dist.dir)/docs\manual\OptionalTasks\pvcstask.html" />
+ <File DiskId="1" Id="file559" Name="RENAME_1.HTM" LongName="renameextensions.html" Vital="yes" src="$(var.dist.dir)/docs\manual\OptionalTasks\renameextensions.html" />
+ <File DiskId="1" Id="file560" Name="REPLAC_1.HTM" LongName="replaceregexp.html" Vital="yes" src="$(var.dist.dir)/docs\manual\OptionalTasks\replaceregexp.html" />
+ <File DiskId="1" Id="file561" Name="REXEC_1.HTM" LongName="rexec.html" Vital="yes" src="$(var.dist.dir)/docs\manual\OptionalTasks\rexec.html" />
+ <File DiskId="1" Id="file562" Name="RPM_1.HTM" LongName="rpm.html" Vital="yes" src="$(var.dist.dir)/docs\manual\OptionalTasks\rpm.html" />
+ <File DiskId="1" Id="file563" Name="SCHEMA_1.HTM" LongName="schemavalidate.html" Vital="yes" src="$(var.dist.dir)/docs\manual\OptionalTasks\schemavalidate.html" />
+ <File DiskId="1" Id="file564" Name="SCP_1.HTM" LongName="scp.html" Vital="yes" src="$(var.dist.dir)/docs\manual\OptionalTasks\scp.html" />
+ <File DiskId="1" Id="file565" Name="SCRIPT_2.HTM" LongName="script.html" Vital="yes" src="$(var.dist.dir)/docs\manual\OptionalTasks\script.html" />
+ <File DiskId="1" Id="file566" Name="SCRIPT_1.HTM" LongName="scriptdef.html" Vital="yes" src="$(var.dist.dir)/docs\manual\OptionalTasks\scriptdef.html" />
+ <File DiskId="1" Id="file567" Name="SERVER_1.HTM" LongName="serverdeploy.html" Vital="yes" src="$(var.dist.dir)/docs\manual\OptionalTasks\serverdeploy.html" />
+ <File DiskId="1" Id="file568" Name="SETPRO_1.HTM" LongName="setproxy.html" Vital="yes" src="$(var.dist.dir)/docs\manual\OptionalTasks\setproxy.html" />
+ <File DiskId="1" Id="file569" Name="SOS_1.HTM" LongName="sos.html" Vital="yes" src="$(var.dist.dir)/docs\manual\OptionalTasks\sos.html" />
+ <File DiskId="1" Id="file570" Name="SOUND_1.HTM" LongName="sound.html" Vital="yes" src="$(var.dist.dir)/docs\manual\OptionalTasks\sound.html" />
+ <File DiskId="1" Id="file571" Name="SPLASH_1.HTM" LongName="splash.html" Vital="yes" src="$(var.dist.dir)/docs\manual\OptionalTasks\splash.html" />
+ <File DiskId="1" Id="file572" Name="SSHEXE_1.HTM" LongName="sshexec.html" Vital="yes" src="$(var.dist.dir)/docs\manual\OptionalTasks\sshexec.html" />
+ <File DiskId="1" Id="file573" Name="STARTE_1.HTM" LongName="starteam.html" Vital="yes" src="$(var.dist.dir)/docs\manual\OptionalTasks\starteam.html" />
+ <File DiskId="1" Id="file574" Name="SYMLIN_1.HTM" LongName="symlink.html" Vital="yes" src="$(var.dist.dir)/docs\manual\OptionalTasks\symlink.html" />
+ <File DiskId="1" Id="file575" Name="TELNET_1.HTM" LongName="telnet.html" Vital="yes" src="$(var.dist.dir)/docs\manual\OptionalTasks\telnet.html" />
+ <File DiskId="1" Id="file576" Name="TRANSL_1.HTM" LongName="translate.html" Vital="yes" src="$(var.dist.dir)/docs\manual\OptionalTasks\translate.html" />
+ <File DiskId="1" Id="file577" Name="VBC_1.HTM" LongName="vbc.html" Vital="yes" src="$(var.dist.dir)/docs\manual\OptionalTasks\vbc.html" />
+ <File DiskId="1" Id="file578" Name="VSS_1.HTM" LongName="vss.html" Vital="yes" src="$(var.dist.dir)/docs\manual\OptionalTasks\vss.html" />
+ <File DiskId="1" Id="file579" Name="WLJSPC_1.HTM" LongName="wljspc.html" Vital="yes" src="$(var.dist.dir)/docs\manual\OptionalTasks\wljspc.html" />
+ <File DiskId="1" Id="file580" Name="WSDLTO_1.HTM" LongName="wsdltodotnet.html" Vital="yes" src="$(var.dist.dir)/docs\manual\OptionalTasks\wsdltodotnet.html" />
+ <File DiskId="1" Id="file581" Name="XMLVAL_1.HTM" LongName="xmlvalidate.html" Vital="yes" src="$(var.dist.dir)/docs\manual\OptionalTasks\xmlvalidate.html" />
+ </Component>
+ </Directory>
+ <Directory Id="directory93" Name="OPTION_2" LongName="OptionalTypes">
+ <Component Id="component90" DiskId="1" Guid="0507ED6A-50CE-4c58-A046-B74E7CFCB3CA">
+ <File DiskId="1" Id="file582" Name="CLASSF_1.HTM" LongName="classfileset.html" Vital="yes" src="$(var.dist.dir)/docs\manual\OptionalTypes\classfileset.html" />
+ <File DiskId="1" Id="file583" Name="EXTENS_2.HTM" LongName="extension.html" Vital="yes" src="$(var.dist.dir)/docs\manual\OptionalTypes\extension.html" />
+ <File DiskId="1" Id="file584" Name="EXTENS_1.HTM" LongName="extensionset.html" Vital="yes" src="$(var.dist.dir)/docs\manual\OptionalTypes\extensionset.html" />
+ </Component>
+ </Directory>
+ <Directory Id="directory94" Name="STYLES_1" LongName="stylesheets">
+ <Component Id="component91" DiskId="1" Guid="4B25D154-CC25-4f93-8D36-BF23E4C29F06">
+ <File DiskId="1" Id="file585" Name="ANTMAN_1.CSS" LongName="antmanual.css" Vital="yes" src="$(var.dist.dir)/docs\manual\stylesheets\antmanual.css" />
+ <File DiskId="1" Id="file586" Name="style.css" Vital="yes" src="$(var.dist.dir)/docs\manual\stylesheets\style.css" />
+ </Component>
+ </Directory>
+ </Directory>
+ <Directory Id="directory95" Name="projects">
+ <Component Id="component92" DiskId="1" Guid="FB149E10-8B7F-4206-AA50-8698C06BEC6E">
+ <File DiskId="1" Id="file587" Name="INDEX_1.HTM" LongName="index.html" Vital="yes" src="$(var.dist.dir)/docs\projects\index.html" />
+ </Component>
+ </Directory>
+ <Directory Id="directory96" Name="webtest">
+ <Component Id="component93" DiskId="1" Guid="A26B499E-E57F-47e3-88B2-66C1293383BE">
+ <File DiskId="1" Id="file588" Name="TESTKE_1" LongName="testkeystore" Vital="yes" src="$(var.dist.dir)/docs\webtest\testkeystore" />
+ </Component>
+ </Directory>
+ </Directory>
+ <Directory Id="directory97" Name="etc">
+ <Component Id="component94" DiskId="1" Guid="90BD5A92-DA62-48ce-8799-868E387EC7C8">
+ <File DiskId="1" Id="file589" Name="ANT-BO_1.JAR" LongName="ant-bootstrap.jar" Vital="yes" src="$(var.dist.dir)/etc\ant-bootstrap.jar" />
+ <File DiskId="1" Id="file590" Name="CHANGE_1.XSL" LongName="changelog.xsl" Vital="yes" src="$(var.dist.dir)/etc\changelog.xsl" />
+ <File DiskId="1" Id="file591" Name="COVERA_1.XSL" LongName="coverage-frames.xsl" Vital="yes" src="$(var.dist.dir)/etc\coverage-frames.xsl" />
+ <File DiskId="1" Id="file592" Name="JDEPEN_1.XSL" LongName="jdepend-frames.xsl" Vital="yes" src="$(var.dist.dir)/etc\jdepend-frames.xsl" />
+ <File DiskId="1" Id="file593" Name="jdepend.xsl" Vital="yes" src="$(var.dist.dir)/etc\jdepend.xsl" />
+ <File DiskId="1" Id="file594" Name="JUNIT-_3.XSL" LongName="junit-frames-xalan1.xsl" Vital="yes" src="$(var.dist.dir)/etc\junit-frames-xalan1.xsl" />
+ <File DiskId="1" Id="file595" Name="JUNIT-_1.XSL" LongName="junit-frames.xsl" Vital="yes" src="$(var.dist.dir)/etc\junit-frames.xsl" />
+ <File DiskId="1" Id="file596" Name="JUNIT-_2.XSL" LongName="junit-noframes.xsl" Vital="yes" src="$(var.dist.dir)/etc\junit-noframes.xsl" />
+ <File DiskId="1" Id="file597" Name="log.xsl" Vital="yes" src="$(var.dist.dir)/etc\log.xsl" />
+ <File DiskId="1" Id="file598" Name="MAUDIT_1.XSL" LongName="maudit-frames.xsl" Vital="yes" src="$(var.dist.dir)/etc\maudit-frames.xsl" />
+ <File DiskId="1" Id="file599" Name="MMETRI_1.XSL" LongName="mmetrics-frames.xsl" Vital="yes" src="$(var.dist.dir)/etc\mmetrics-frames.xsl" />
+ <File DiskId="1" Id="file600" Name="tagdiff.xsl" Vital="yes" src="$(var.dist.dir)/etc\tagdiff.xsl" />
+ </Component>
+ <Directory Id="directory98" Name="CHECKS_1" LongName="checkstyle">
+ <Component Id="component95" DiskId="1" Guid="2AEB59C7-5CEF-401c-9AB9-911B995F00FC">
+ <File DiskId="1" Id="file601" Name="CHECKS_1.XSL" LongName="checkstyle-frames.xsl" Vital="yes" src="$(var.dist.dir)/etc\checkstyle\checkstyle-frames.xsl" />
+ <File DiskId="1" Id="file602" Name="CHECKS_3.XSL" LongName="checkstyle-text.xsl" Vital="yes" src="$(var.dist.dir)/etc\checkstyle\checkstyle-text.xsl" />
+ <File DiskId="1" Id="file603" Name="CHECKS_2.XSL" LongName="checkstyle-xdoc.xsl" Vital="yes" src="$(var.dist.dir)/etc\checkstyle\checkstyle-xdoc.xsl" />
+ </Component>
+ </Directory>
+ </Directory>
+ </DirectoryRef>
+ </Fragment>
+</Wix>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/ant-msi.wxs b/framework/src/ant/apache-ant-1.9.6/src/etc/ant-msi.wxs
new file mode 100644
index 00000000..34b59eb7
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/ant-msi.wxs
@@ -0,0 +1,122 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<!--
+ WiX File describing the MSI for Ant
+
+ XSD lives at http://wix.cvs.sourceforge.net/*checkout*/wix/wix2.0/src/wix/Xsd/wix.xsd
+-->
+<Wix xmlns='http://schemas.microsoft.com/wix/2003/01/wi'>
+
+ <Product Name="Apache Ant $(var.version)"
+ Id="61A421CE-D93F-478c-98C8-9C31FCE44C7A"
+ Version="$(var.version)" Language="1033"
+ Manufacturer="Apache Software Foundation">
+
+ <Package Id='????????-????-????-????-????????????'
+ Keywords='Installer' Languages="1033"
+ Description="Apache Ant $(var.version) installer"
+ Comments='Apache Ant is a Java based build tool'
+ Manufacturer='Apache Software Foundation'
+ InstallerVersion='200'
+ Compressed='yes'/>
+
+ <Media Id='1' Cabinet='ant.cab' EmbedCab='yes' />
+
+ <Directory Id='TARGETDIR' Name='SourceDir'>
+ <Directory Id='ProgramFilesFolder' Name='PFiles'>
+ <Directory Id='ASF' Name='Apache'
+ LongName="Apache Software Foundation">
+ <Directory Id='INSTALLDIR' Name='Ant'
+ LongName='Ant $(var.version)'>
+
+ <Component Id="licenses"
+ Guid="09346EB3-08D2-4a7f-9D64-47E4E414FE65">
+ <File DiskId="1" Id="fetch.xml" Name="fetch.xml"
+ Vital="yes" src="$(var.dist.dir)/fetch.xml"/>
+ <File DiskId="1" Id="INSTALL" Name="INSTALL"
+ Vital="yes" src="$(var.dist.dir)/INSTALL"/>
+ <File DiskId="1" Id="KEYS" Name="KEYS"
+ Vital="yes" src="$(var.dist.dir)/KEYS"/>
+ <File DiskId="1" Id="LICENSE" Name="LICENSE"
+ Vital="yes" src="$(var.dist.dir)/LICENSE"/>
+ <File DiskId="1" Id="LICENSE.dom" Name="LICENSE.dom"
+ Vital="yes" src="$(var.dist.dir)/LICENSE.dom"/>
+ <File DiskId="1" Id="LICENSE.sax" Name="LICENSE.sax"
+ Vital="yes" src="$(var.dist.dir)/LICENSE.sax"/>
+ <File DiskId="1" Id="LICENSE.xer" Name="LICENSE.xer"
+ LongName="LICENSE.xerces"
+ Vital="yes" src="$(var.dist.dir)/LICENSE.xerces"/>
+ <File DiskId="1" Id="NOTICE" Name="NOTICE"
+ Vital="yes" src="$(var.dist.dir)/NOTICE"/>
+ <File DiskId="1" Id="README" Name="README"
+ Vital="yes" src="$(var.dist.dir)/README"/>
+ <File DiskId="1" Id="WHATSNEW" Name="WHATSNEW"
+ Vital="yes" src="$(var.dist.dir)/WHATSNEW"/>
+ </Component>
+ </Directory>
+ </Directory>
+ </Directory>
+
+ <Directory Id="ProgramMenuFolder" Name="PMenu" LongName="Programs">
+ <Directory Id="ProgramMenuDir" Name='Ant'
+ LongName="Apache Ant $(var.version)" />
+ </Directory>
+
+ </Directory>
+
+ <Feature Id="Complete" Level="1">
+ <ComponentRef Id="manualIndex"/>
+ <ComponentRef Id="licenses"/>
+ <ComponentRef Id="component0"/>
+ <ComponentRef Id="component1"/>
+ <ComponentRef Id="component2"/>
+ <ComponentRef Id="component3"/>
+ <ComponentRef Id="component4"/>
+ <ComponentRef Id="component5"/>
+ <ComponentRef Id="component6"/>
+ <ComponentRef Id="component7"/>
+ <ComponentRef Id="component8"/>
+ <ComponentRef Id="component9"/>
+ <ComponentRef Id="component86"/>
+ <ComponentRef Id="component87"/>
+ <ComponentRef Id="component88"/>
+ <ComponentRef Id="component89"/>
+ <ComponentRef Id="component90"/>
+ <ComponentRef Id="component91"/>
+ <ComponentRef Id="component92"/>
+ <ComponentRef Id="component93"/>
+ <ComponentRef Id="component94"/>
+ <ComponentRef Id="component95"/>
+ </Feature>
+ </Product>
+
+ <Fragment>
+ <DirectoryRef Id="manual">
+ <Component Id="manualIndex"
+ Guid="3125AB68-1388-49aa-89F8-9F5B80EBE64B">
+ <File DiskId="1" Id="antManualIndex"
+ Name="INDEX_1.HTM" LongName="index.html"
+ Vital="yes" src="$(var.dist.dir)/docs/manual/index.html">
+ <Shortcut Id="startmenuAntDocs"
+ Directory="ProgramMenuDir" Name="Manual" />
+ </File>
+ </Component>
+ </DirectoryRef>
+ </Fragment>
+
+</Wix>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/ant-update.xsl b/framework/src/ant/apache-ant-1.9.6/src/etc/ant-update.xsl
new file mode 100644
index 00000000..c81a39f8
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/ant-update.xsl
@@ -0,0 +1,117 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+<xsl:output method="xml" indent="yes"/>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<!--
+
+ The purpose have this XSL is to provide a fast way to update a buildfile
+ from deprecated tasks.
+
+ It should particularly be useful when there is a lot of build files to migrate.
+ If you do not want to migrate to a particular task and want to keep it for
+ various reason, just comment the appropriate template.
+
+ !!!! Use at your own risk. !!!!
+
+-->
+
+
+ <!-- (zip|jar|war|ear)file attributes are replaced by destfile in their respective task -->
+ <xsl:template match="zip">
+ <zip destfile="{@zipfile}">
+ <xsl:apply-templates select="@*[not(name()='zipfile')]|node()"/>
+ </zip>
+ </xsl:template>
+ <xsl:template match="jar">
+ <jar destfile="{@jarfile}">
+ <xsl:apply-templates select="@*[not(name()='jarfile')]|node()"/>
+ </jar>
+ </xsl:template>
+ <xsl:template match="war">
+ <war destfile="{@warfile}">
+ <xsl:apply-templates select="@*[not(name()='warfile')]|node()"/>
+ </war>
+ </xsl:template>
+ <xsl:template match="ear">
+ <ear destfile="{@earfile}">
+ <xsl:apply-templates select="@*[not(name()='earfile')]|node()"/>
+ </ear>
+ </xsl:template>
+
+
+ <!-- copydir is replaced by copy -->
+ <xsl:template match="copydir">
+ <copy todir="{@dest}">
+ <xsl:apply-templates select="@flatten|@filtering"/>
+ <xsl:if test="@forceoverwrite">
+ <xsl:attribute name="overwrite"><xsl:value-of select="@forceoverwrite"/></xsl:attribute>
+ </xsl:if>
+ <fileset dir="{@src}">
+ <xsl:apply-templates select="@includes|@includesfile|@excludes|@excludesfile|node()"/>
+ </fileset>
+ </copy>
+ </xsl:template>
+
+ <!-- copyfile is replaced by copy -->
+ <xsl:template match="copyfile">
+ <copy file="{@src}" tofile="{@dest}">
+ <xsl:apply-templates select="@filtering"/>
+ <xsl:if test="@forceoverwrite">
+ <xsl:attribute name="overwrite"><xsl:value-of select="@forceoverwrite"/></xsl:attribute>
+ </xsl:if>
+ </copy>
+ </xsl:template>
+
+ <!-- deltree is replaced by delete -->
+ <xsl:template match="deltree">
+ <delete dir="{@dir}"/>
+ </xsl:template>
+
+ <!-- execon is replaced by apply -->
+ <xsl:template match="execon">
+ <apply>
+ <xsl:apply-templates select="@*|node()"/>
+ </apply>
+ </xsl:template>
+
+ <!-- rename is replaced by move -->
+ <xsl:template match="rename">
+ <move file="{@src}" tofile="{@dest}">
+ <xsl:if test="@replace">
+ <xsl:attribute name="overwrite"><xsl:value-of select="@replace"/></xsl:attribute>
+ </xsl:if>
+ </move>
+ </xsl:template>
+
+ <!-- javadoc2 is replaced by javadoc -->
+ <xsl:template match="javadoc2">
+ <javadoc>
+ <xsl:apply-templates select="@*|node()"/>
+ </javadoc>
+ </xsl:template>
+
+
+ <!-- Copy every node and attributes recursively -->
+ <xsl:template match="node()|@*">
+ <xsl:copy>
+ <xsl:apply-templates select="@*|node()"/>
+ </xsl:copy>
+ </xsl:template>
+
+</xsl:stylesheet>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/changelog.xsl b/framework/src/ant/apache-ant-1.9.6/src/etc/changelog.xsl
new file mode 100644
index 00000000..c6aef8fd
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/changelog.xsl
@@ -0,0 +1,148 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+
+<xsl:stylesheet
+ xmlns:xsl='http://www.w3.org/1999/XSL/Transform'
+ version='1.0'>
+
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+-->
+ <xsl:param name="title"/>
+ <xsl:param name="module"/>
+ <xsl:param name="cvsweb"/>
+
+ <xsl:output method="html" indent="yes" encoding="US-ASCII"
+ doctype-public="-//W3C//DTD HTML 4.01//EN"
+ doctype-system="http://www.w3.org/TR/html401/strict.dtd"/>
+
+ <!-- Copy standard document elements. Elements that
+ should be ignored must be filtered by apply-templates
+ tags. -->
+ <xsl:template match="*">
+ <xsl:copy>
+ <xsl:copy-of select="attribute::*[. != '']"/>
+ <xsl:apply-templates/>
+ </xsl:copy>
+ </xsl:template>
+
+ <xsl:template match="changelog">
+ <html>
+ <head>
+ <title><xsl:value-of select="$title"/></title>
+ <style type="text/css">
+ body, p {
+ font-family: Verdana, Arial, Helvetica, sans-serif;
+ font-size: 80%;
+ color: #000000;
+ background-color: #ffffff;
+ }
+ tr, td {
+ font-family: Verdana, Arial, Helvetica, sans-serif;
+ background: #eeeee0;
+ }
+ td {
+ padding-left: 20px;
+ }
+ .dateAndAuthor {
+ font-family: Verdana, Arial, Helvetica, sans-serif;
+ font-weight: bold;
+ text-align: left;
+ background: #a6caf0;
+ padding-left: 3px;
+ }
+ a {
+ color: #000000;
+ }
+ pre {
+ font-weight: bold;
+ }
+ </style>
+ </head>
+ <body>
+ <h1>
+ <a name="top"><xsl:value-of select="$title"/></a>
+ </h1>
+ <p style="text-align: right">Designed for use with <a href="http://ant.apache.org/">Apache Ant</a>.</p>
+ <hr/>
+ <table border="0" width="100%" cellspacing="1">
+
+ <xsl:apply-templates select=".//entry">
+ <xsl:sort select="date" data-type="text" order="descending"/>
+ <xsl:sort select="time" data-type="text" order="descending"/>
+ </xsl:apply-templates>
+
+ </table>
+
+ </body>
+ </html>
+ </xsl:template>
+
+ <xsl:template match="entry">
+ <tr>
+ <td class="dateAndAuthor">
+ <xsl:value-of select="date"/><xsl:text> </xsl:text><xsl:value-of select="time"/><xsl:text> </xsl:text><xsl:value-of select="author"/>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <pre>
+<xsl:apply-templates select="msg"/></pre>
+ <ul>
+ <xsl:apply-templates select="file"/>
+ </ul>
+ </td>
+ </tr>
+ </xsl:template>
+
+ <xsl:template match="date">
+ <i><xsl:value-of select="."/></i>
+ </xsl:template>
+
+ <xsl:template match="time">
+ <i><xsl:value-of select="."/></i>
+ </xsl:template>
+
+ <xsl:template match="author">
+ <i>
+ <a>
+ <xsl:attribute name="href">mailto:<xsl:value-of select="."/></xsl:attribute>
+ <xsl:value-of select="."/></a>
+ </i>
+ </xsl:template>
+
+ <xsl:template match="file">
+ <li>
+ <a>
+ <xsl:choose>
+ <xsl:when test="string-length(prevrevision) = 0 ">
+ <xsl:attribute name="href"><xsl:value-of select="$cvsweb"/><xsl:value-of select="$module" />/<xsl:value-of select="name" />?rev=<xsl:value-of select="revision" />&amp;content-type=text/x-cvsweb-markup</xsl:attribute>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:attribute name="href"><xsl:value-of select="$cvsweb"/><xsl:value-of select="$module" />/<xsl:value-of select="name" />?r1=<xsl:value-of select="revision" />&amp;r2=<xsl:value-of select="prevrevision"/></xsl:attribute>
+ </xsl:otherwise>
+ </xsl:choose>
+ <xsl:value-of select="name" /> (<xsl:value-of select="revision"/>)</a>
+ </li>
+ </xsl:template>
+
+ <!-- Any elements within a msg are processed,
+ so that we can preserve HTML tags. -->
+ <xsl:template match="msg">
+ <xsl:apply-templates/>
+ </xsl:template>
+
+</xsl:stylesheet>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/checkstyle/RequiredHeader.txt b/framework/src/ant/apache-ant-1.9.6/src/etc/checkstyle/RequiredHeader.txt
new file mode 100644
index 00000000..6a5bb9a1
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/checkstyle/RequiredHeader.txt
@@ -0,0 +1,17 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/checkstyle/checkstyle-config b/framework/src/ant/apache-ant-1.9.6/src/etc/checkstyle/checkstyle-config
new file mode 100644
index 00000000..b3232be7
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/checkstyle/checkstyle-config
@@ -0,0 +1,139 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!DOCTYPE module PUBLIC "-//Puppy Crawl//DTD Check Configuration 1.1//EN" "http://www.puppycrawl.com/dtds/configuration_1_1.dtd">
+
+<module name="Checker">
+
+ <!-- required licence file -->
+ <module name="Header">
+ <property name="headerFile" value="${config.dir}/RequiredHeader.txt"/>
+ <property name="ignoreLines" value="2"/>
+ </module>
+
+ <!-- size limits -->
+ <module name="FileLength"/>
+
+ <module name="FileTabCharacter"/>
+
+
+ <module name="TreeWalker">
+ <!-- Javadoc requirements -->
+ <module name="JavadocType">
+ <property name="scope" value="protected"/>
+ </module>
+ <module name="JavadocMethod">
+ <property name="scope" value="protected"/>
+ <property name="allowUndeclaredRTE" value="true"/>
+ </module>
+ <module name="JavadocVariable">
+ <property name="scope" value="public"/>
+ </module>
+
+ <!-- element naming -->
+ <module name="PackageName"/>
+ <module name="TypeName"/>
+ <module name="ConstantName"/>
+ <module name="LocalFinalVariableName"/>
+ <module name="LocalVariableName"/>
+ <module name="MemberName"/>
+ <module name="MethodName"/>
+ <module name="ParameterName"/>
+ <module name="StaticVariableName"/>
+
+ <!-- Import conventions -->
+ <module name="AvoidStarImport"/>
+ <module name="IllegalImport"/>
+ <module name="RedundantImport"/>
+ <module name="UnusedImports"/>
+
+ <!-- size limits -->
+ <module name="LineLength">
+ <property name="max" value="100"/>
+ <property name="ignorePattern" value="^ *\* *[^ ]+$"/>
+ </module>
+ <module name="MethodLength"/>
+ <module name="ParameterNumber"/>
+
+ <!-- whitespace checks -->
+ <module name="EmptyForIteratorPad"/>
+ <module name="NoWhitespaceAfter"/>
+ <module name="NoWhitespaceBefore"/>
+ <module name="OperatorWrap"/>
+ <module name="ParenPad"/>
+ <module name="WhitespaceAfter"/>
+ <module name="WhitespaceAround"/>
+
+ <!-- Modifier Checks -->
+ <module name="ModifierOrder"/>
+ <module name="RedundantModifier"/>
+
+ <!-- Checks for blocks -->
+ <module name="AvoidNestedBlocks"/>
+ <module name="EmptyBlock">
+ <property name="option" value="text"/>
+ </module>
+ <module name="LeftCurly"/>
+ <module name="NeedBraces"/>
+ <module name="RightCurly"/>
+
+ <!-- Checks for common coding problems -->
+ <!--<module name="AvoidInlineConditionals"/> -->
+ <module name="EmptyStatement"/>
+ <module name="EqualsHashCode"/>
+ <module name="IllegalInstantiation">
+ <property name="classes" value="java.lang.Boolean"/>
+ </module>
+ <!-- <module name="InnerAssignment"/> -->
+ <!-- <module name="MagicNumber"/> -->
+ <module name="MissingSwitchDefault"/>
+ <!-- Allow redundant throw declarations for doc purposes
+ <module name="RedundantThrows">
+ <property name="allowUnchecked" value="true"/>
+ </module>
+ -->
+ <module name="SimplifyBooleanExpression"/>
+ <module name="SimplifyBooleanReturn"/>
+
+ <!-- Checks for class design -->
+ <!-- <module name="DesignForExtension"/> -->
+ <module name="FinalClass"/>
+ <module name="HideUtilityClassConstructor"/>
+ <module name="InterfaceIsType"/>
+ <module name="VisibilityModifier"/>
+
+ <!-- Miscellaneous other checks. -->
+ <module name="ArrayTypeStyle"/>
+ <!-- <module name="TodoComment"/> -->
+ <module name="UpperEll"/>
+ <!-- allow comment suppression of checks -->
+ <module name="FileContentsHolder"/>
+ </module>
+
+ <module name="RegexpSingleline">
+ <!-- \s matches whitespace character, $ matches end of line. -->
+ <property name="format" value="\s+$"/>
+ </module>
+
+ <!-- <module name="au.com.redhillconsulting.simian.SimianCheck"/> -->
+ <module name="SuppressionCommentFilter">
+ <property name="offCommentFormat" value="CheckStyle\:([\w\|]+) *OFF"/>
+ <property name="onCommentFormat" value="CheckStyle\:([\w\|]+) *ON"/>
+ <property name="checkFormat" value="$1"/>
+ </module>
+
+</module>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/checkstyle/checkstyle-frames-sortby-check.xsl b/framework/src/ant/apache-ant-1.9.6/src/etc/checkstyle/checkstyle-frames-sortby-check.xsl
new file mode 100644
index 00000000..060f8788
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/checkstyle/checkstyle-frames-sortby-check.xsl
@@ -0,0 +1,367 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"
+ xmlns:lxslt="http://xml.apache.org/xslt"
+ xmlns:redirect="http://xml.apache.org/xalan/redirect"
+ extension-element-prefixes="redirect">
+
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+ <xsl:output method="html" indent="yes" encoding="US-ASCII"/>
+ <xsl:decimal-format decimal-separator="." grouping-separator="," />
+
+ <xsl:param name="output.dir" select="'.'"/>
+ <xsl:param name="basedir" select="'.'"/>
+
+
+
+ <!--
+ Matches the root element of the data and starts the generation.
+ -->
+ <xsl:template match="checkstyle">
+ <!-- create the sorted.html with the data -->
+ <redirect:write file="{$output.dir}/sorted.html">
+ <xsl:call-template name="sorted.html"/>
+ </redirect:write>
+
+ <!-- create the stylesheet.css with layout -->
+ <redirect:write file="{$output.dir}/sorted.css">
+ <xsl:call-template name="sorted.css"/>
+ </redirect:write>
+
+ <!-- create the switch.js for collepsing the data -->
+ <redirect:write file="{$output.dir}/switch.js">
+ <xsl:call-template name="switch.js"/>
+ </redirect:write>
+ </xsl:template>
+
+
+
+ <!--
+ Generates the HTML page with the data.
+ -->
+ <xsl:template name="sorted.html">
+ <html>
+ <head>
+ <title>CheckStyle Audit</title>
+ <script language="JavaScript" src="switch.js" type="text/javascript"></script>
+ <link rel="stylesheet" type="text/css" href="sorted.css"/>
+ </head>
+ <body onload="javascript:openFirst();">
+ <h1>CheckStyle Audit</h1>
+ <p>Designed for use with
+ <a href='http://checkstyle.sourceforge.net/'>CheckStyle</a> and
+ <a href='http://ant.apache.org/'>Ant</a>.
+ </p>
+ <xsl:apply-templates select="." mode="navigation"/>
+ <xsl:apply-templates select="." mode="data"/>
+ </body>
+ </html>
+ </xsl:template>
+
+
+
+ <!--
+ Key for detecting duplicate CheckModules
+ -->
+ <xsl:key name="module" match="file/error" use="@source"/>
+
+
+
+ <!--
+ Generates the navagation bar.
+ -->
+ <xsl:template match="checkstyle" mode="navigation">
+ <ul id="navigation">
+ <xsl:for-each select="file/error[generate-id() = generate-id(key('module',@source))]">
+ <xsl:sort select="@source"/>
+ <xsl:variable name="last-index">
+ <xsl:call-template name="last-index-of">
+ <xsl:with-param name="txt" select="@source"/>
+ <xsl:with-param name="delimiter" select="'.'"></xsl:with-param>
+ </xsl:call-template>
+ </xsl:variable>
+ <li><a href="javascript:change('{@source}');">
+ <xsl:value-of select="substring(@source, $last-index+1)"/>
+ </a></li>
+ </xsl:for-each>
+ </ul>
+ </xsl:template>
+
+
+
+ <!--
+ Generates the data part.
+ -->
+ <xsl:template match="checkstyle" mode="data">
+ <div id="content">
+ <xsl:for-each select="file/error[generate-id() = generate-id(key('module',@source))]">
+ <xsl:sort select="@source"/>
+ <div class="hideable" id="{@source}">
+ <xsl:variable name="module" select="@source"/>
+ <h2><xsl:value-of select="@source"/></h2>
+ <xsl:call-template name="data">
+ <xsl:with-param name="filter" select="$module"/>
+ </xsl:call-template>
+ </div>
+ </xsl:for-each>
+ </div>
+ </xsl:template>
+
+
+
+ <!--
+ Generates the content table for the given check module.
+ @param filter full qualified module name
+ -->
+ <xsl:template name="data">
+ <xsl:param name="filter"/>
+
+ <table>
+ <tr>
+ <th>file</th>
+ <th>line</th>
+ <th>severity</th>
+ <th>message</th>
+ </tr>
+ <xsl:for-each select="/checkstyle/file">
+ <xsl:choose>
+ <xsl:when test="error/@source=$filter">
+ <xsl:call-template name="data-rows">
+ <xsl:with-param name="node" select="."/>
+ <xsl:with-param name="filter" select="$filter"/>
+ </xsl:call-template>
+ </xsl:when>
+ </xsl:choose>
+ </xsl:for-each>
+ </table>
+ </xsl:template>
+
+
+
+ <!--
+ Generates the data rows for the current check module.
+ Ignores errors in the current file from other modules.
+ @param node the file with the errors
+ @param filter full qualified module name
+ -->
+ <xsl:template name="data-rows">
+ <xsl:param name="node"/>
+ <xsl:param name="filter"/>
+
+ <xsl:for-each select="$node/error">
+ <xsl:choose>
+ <xsl:when test="@source=$filter">
+ <tr>
+ <!-- Hide the basdir. First char of the result is a path separator so remove that. -->
+ <td><xsl:value-of select="substring(substring-after($node/@name, $basedir),2)"/></td>
+ <td><xsl:value-of select="@line"/></td>
+ <td><xsl:value-of select="@severity"/></td>
+ <td><xsl:value-of select="@message"/></td>
+ </tr>
+ </xsl:when>
+ </xsl:choose>
+ </xsl:for-each>
+ </xsl:template>
+
+
+
+ <!--
+ Generates the CSS with the layout instructions.
+ Generated so this XSL is the single source of the whole report.
+ -->
+ <xsl:template name="sorted.css">
+ body {
+ font:normal 80% arial,helvetica,sanserif;
+ color: black;
+ background-color: white;
+ margin: 0;
+ padding: 1em;
+ min-width: 41em;
+ }
+ h1 {
+ font-weight:bold;
+ font-size:140%;
+ margin: 0 0 0.7em;
+ padding: 0.3em;
+ text-align: center;
+ background-color: #eee;
+ border: 2px ridge silver;
+ }
+ html<xsl:text disable-output-escaping="yes">&gt;</xsl:text>body h1 {
+ border-color: gray;
+ }
+
+ ul#navigation {
+ font-size: 0.83em;
+ float: left; width: 18em;
+ margin: 0 0 1.2em; padding: 0;
+ border: 1px dashed silver;
+ }
+ ul#navigation li {
+ list-style: none;
+ margin: 0; padding: 0.2em;
+ }
+ ul#navigation a {
+ display: block;
+ padding: 0.2em;
+ font-weight: bold;
+ }
+ ul#navigation a:link {
+ color: black; background-color: #eee;
+ }
+ ul#navigation a:visited {
+ color: #666; background-color: #eee;
+ }
+ ul#navigation a:hover {
+ color: red; background-color: white;
+ }
+ ul#navigation a:active {
+ color: white; background-color: gray;
+ }
+
+ div#content {
+ margin: 0 1em 1em 16em;
+ padding: 0 1em;
+ }
+ * html div#content {
+ height: 1em; /* Workaround 3-Pixel-Bug of Internet Explorers */
+ }
+ div#content h2 {
+ font-size:100%;
+ font-weight:bold;
+ background: #525D76;
+ color: white;
+ text-decoration: none;
+ padding: 5px;
+ margin-right: 2px;
+ margin-left: 2px;
+ margin-bottom: 0;
+ }
+ div#content p {
+ font-size: 1em;
+ margin: 1em 0;
+ }
+ table {
+ width:100%;
+ border-collapse:collapse;
+ }
+ table td, table th {
+ border:1px solid #000;
+ padding:3px 7px 2px 7px;
+ }
+ table th {
+ font-weight:bold;
+ background: #ccc;
+ color: black;
+ }
+ table tr:nth-child(odd) td {
+ background: #efefef;
+ }
+ table tr:nth-child(even) td {
+ background: #fff;
+ }
+ </xsl:template>
+
+
+
+ <!--
+ Generates the JavaScript for the dynamic style.
+ Generated so this XSL is the single source of the whole report.
+ -->
+ <xsl:template name="switch.js">
+ /*
+ * Hides all "hideable" div-containers
+ */
+ function hideAll() {
+ allElements = document.getElementsByTagName("div");
+ for (i = 0; i <xsl:text disable-output-escaping="yes">&lt;</xsl:text> allElements.length; i++) {
+ if (allElements[i].className=="hideable") {
+ allElements[i].style.display="none";
+ }
+ }
+ return;
+ }
+
+ /*
+ * Shows one div-container and hides the other.
+ * @param id id of the element to show
+ */
+ function change(id) {
+ hideAll();
+ e = document.getElementById(id);
+ if (e.style.display=="none") {
+ e.style.display="";
+ }
+ window.scrollTo(0, 0);
+ return;
+ }
+
+ /*
+ * Shows only the first data row.
+ * Used in body:onload so the user could directly see some messages.
+ */
+ function openFirst() {
+ hideAll();
+ for (i = 0; i <xsl:text disable-output-escaping="yes">&lt;</xsl:text> allElements.length; i++) {
+ if (allElements[i].className=="hideable") {
+ allElements[i].style.display="";
+ return;
+ }
+ }
+ return;
+ }
+ </xsl:template>
+
+
+
+ <!--
+ Calculates the index of the last occurence of a substring in a string.
+ @param txt the whole string in which to search
+ @delimiter the substring to search
+ -->
+ <xsl:template name="last-index-of">
+ <xsl:param name="txt"/>
+ <xsl:param name="remainder" select="$txt"/>
+ <xsl:param name="delimiter" select="' '"/>
+
+ <xsl:choose>
+ <xsl:when test="contains($remainder, $delimiter)">
+ <xsl:call-template name="last-index-of">
+ <xsl:with-param name="txt" select="$txt"/>
+ <xsl:with-param name="remainder" select="substring-after($remainder, $delimiter)"/>
+ <xsl:with-param name="delimiter" select="$delimiter"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:variable name="lastIndex" select="string-length(substring($txt, 1, string-length($txt)-string-length($remainder)))+1"/>
+ <xsl:choose>
+ <xsl:when test="string-length($remainder)=0">
+ <xsl:value-of select="string-length($txt)"/>
+ </xsl:when>
+ <xsl:when test="$lastIndex>0">
+ <xsl:value-of select="($lastIndex - string-length($delimiter))"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="0"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+</xsl:stylesheet>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/checkstyle/checkstyle-frames.xsl b/framework/src/ant/apache-ant-1.9.6/src/etc/checkstyle/checkstyle-frames.xsl
new file mode 100644
index 00000000..c79c0b7b
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/checkstyle/checkstyle-frames.xsl
@@ -0,0 +1,299 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
+ xmlns:lxslt="http://xml.apache.org/xslt"
+ xmlns:redirect="http://xml.apache.org/xalan/redirect"
+ extension-element-prefixes="redirect">
+
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+ <xsl:output method="html" indent="yes" encoding="US-ASCII"/>
+ <xsl:decimal-format decimal-separator="." grouping-separator="," />
+
+ <xsl:param name="output.dir" select="'.'"/>
+ <xsl:param name="basedir" select="'.'"/>
+
+ <xsl:template match="checkstyle">
+ <!-- create the index.html -->
+ <redirect:write file="{$output.dir}/index.html">
+ <xsl:call-template name="index.html"/>
+ </redirect:write>
+
+ <!-- create the stylesheet.css -->
+ <redirect:write file="{$output.dir}/stylesheet.css">
+ <xsl:call-template name="stylesheet.css"/>
+ </redirect:write>
+
+ <!-- create the overview-summary.html at the root -->
+ <redirect:write file="{$output.dir}/overview-frame.html">
+ <xsl:apply-templates select="." mode="overview"/>
+ </redirect:write>
+
+ <!-- create the all-classes.html at the root -->
+ <redirect:write file="{$output.dir}/allclasses-frame.html">
+ <xsl:apply-templates select="." mode="all.classes"/>
+ </redirect:write>
+
+ <!-- process all files -->
+ <xsl:apply-templates select="file[count(error) != 0]"/>
+ </xsl:template>
+
+ <xsl:template name="index.html">
+ <html>
+ <head>
+ <title>CheckStyle Audit</title>
+ </head>
+ <frameset cols="20%,80%">
+ <frame src="allclasses-frame.html" name="fileListFrame"/>
+ <frame src="overview-frame.html" name="fileFrame"/>
+ </frameset>
+ <noframes>
+ <h2>Frame Alert</h2>
+ <p>
+ This document is designed to be viewed using the frames feature.
+ If you see this message, you are using a non-frame-capable web client.
+ </p>
+ </noframes>
+ </html>
+ </xsl:template>
+
+ <xsl:template name="pageHeader">
+ <table border="0" cellpadding="0" cellspacing="0" width="100%">
+ <tr>
+ <td class="text-align:right"><h2>CheckStyle Audit</h2></td>
+ </tr>
+ <tr>
+ <td class="text-align:right">Designed for use with
+ <a href='http://checkstyle.sourceforge.net/'>CheckStyle</a> and
+ <a href='http://ant.apache.org/'>Ant</a>.</td>
+ </tr>
+ </table>
+ <hr size="1"/>
+ </xsl:template>
+
+ <xsl:template match="checkstyle" mode="overview">
+ <html>
+ <head>
+ <link rel="stylesheet" type="text/css" href="stylesheet.css"/>
+ </head>
+ <body>
+ <!-- page header -->
+ <xsl:call-template name="pageHeader"/>
+
+ <!-- Summary part -->
+ <xsl:apply-templates select="." mode="summary"/>
+ <hr size="1" width="100%" align="left"/>
+
+ <!-- File list part -->
+ <xsl:apply-templates select="." mode="filelist"/>
+ </body>
+ </html>
+ </xsl:template>
+
+ <xsl:template name="stylesheet.css">
+ .bannercell {
+ border: 0px;
+ padding: 0px;
+ }
+ body {
+ margin-left: 10;
+ margin-right: 10;
+ font:normal 80% arial,helvetica,sanserif;
+ background-color:#FFFFFF;
+ color:#000000;
+ }
+ .oddrow td {
+ background: #efefef;
+ }
+ .evenrow td {
+ background: #fff;
+ }
+ th, td {
+ text-align: left;
+ vertical-align: top;
+ }
+ th {
+ font-weight:bold;
+ background: #ccc;
+ color: black;
+ }
+ table, th, td {
+ font-size:100%;
+ border: none
+ }
+ table.log tr td, tr th {
+
+ }
+ h2 {
+ font-weight:bold;
+ font-size:140%;
+ margin-bottom: 5;
+ }
+ h3 {
+ font-size:100%;
+ font-weight:bold;
+ background: #525D76;
+ color: white;
+ text-decoration: none;
+ padding: 5px;
+ margin-right: 2px;
+ margin-left: 2px;
+ margin-bottom: 0;
+ }
+ </xsl:template>
+
+ <!--
+ Creates an all-classes.html file that contains a link to all files.
+ -->
+ <xsl:template match="checkstyle" mode="all.classes">
+ <html>
+ <head>
+ <link rel="stylesheet" type="text/css" href="stylesheet.css"/>
+ </head>
+ <body>
+ <h2>Files</h2>
+ <p>
+ <table width="100%">
+ <!-- For each file create its part -->
+ <xsl:apply-templates select="file[count(error) != 0]" mode="all.classes">
+ <xsl:sort select="substring-after(@name, $basedir)"/>
+ </xsl:apply-templates>
+ </table>
+ </p>
+ </body>
+ </html>
+ </xsl:template>
+
+ <xsl:template match="checkstyle" mode="filelist">
+ <h3>Files</h3>
+ <table class="log" border="0" cellpadding="5" cellspacing="2" width="100%">
+ <tr>
+ <th>Name</th>
+ <th>Errors</th>
+ </tr>
+ <xsl:apply-templates select="file[count(error) != 0]" mode="filelist">
+ <xsl:sort select="count(error)" order="descending" data-type="number"/>
+ </xsl:apply-templates>
+ </table>
+ </xsl:template>
+
+ <xsl:template match="file" mode="filelist">
+ <tr>
+ <xsl:call-template name="alternated-row"/>
+ <td nowrap="nowrap">
+ <a>
+ <xsl:attribute name="href">
+ <xsl:text>files/</xsl:text><xsl:value-of select="substring-after(@name, $basedir)"/><xsl:text>.html</xsl:text>
+ </xsl:attribute>
+ <xsl:value-of select="substring-after(@name, $basedir)"/>
+ </a>
+ </td>
+ <td><xsl:value-of select="count(error)"/></td>
+ </tr>
+ </xsl:template>
+
+ <xsl:template match="file" mode="all.classes">
+ <tr>
+ <td nowrap="nowrap">
+ <a target="fileFrame">
+ <xsl:attribute name="href">
+ <xsl:text>files/</xsl:text><xsl:value-of select="substring-after(@name, $basedir)"/><xsl:text>.html</xsl:text>
+ </xsl:attribute>
+ <xsl:value-of select="substring-after(@name, $basedir)"/>
+ </a>
+ </td>
+ </tr>
+ </xsl:template>
+
+ <!--
+ transform string like a/b/c to ../../../
+ @param path the path to transform into a descending directory path
+ -->
+ <xsl:template name="path">
+ <xsl:param name="path"/>
+
+ <!-- Convert a windows path '\' to a unix path '/' for further processing. -->
+ <xsl:variable name="path2" select="translate($path,'\','/')"/>
+
+
+ <xsl:if test="contains($path2,'/')">
+ <xsl:text>../</xsl:text>
+ <xsl:call-template name="path">
+ <xsl:with-param name="path"><xsl:value-of select="substring-after($path2,'/')"/></xsl:with-param>
+ </xsl:call-template>
+ </xsl:if>
+ <xsl:if test="not(contains($path2,'/')) and not($path2 = '')">
+ <xsl:text>../</xsl:text>
+ </xsl:if>
+ </xsl:template>
+
+ <xsl:template match="file">
+ <redirect:write file="{$output.dir}/files/{substring-after(@name, $basedir)}.html">
+ <html>
+ <head>
+ <link rel="stylesheet" type="text/css">
+ <xsl:attribute name="href"><xsl:call-template name="path"><xsl:with-param name="path" select="substring-after(@name, $basedir)"/></xsl:call-template><xsl:text>stylesheet.css</xsl:text></xsl:attribute>
+ </link>
+ </head>
+ <body>
+ <xsl:call-template name="pageHeader"/>
+ <h3>File <xsl:value-of select="substring-after(@name, $basedir)"/></h3>
+ <table class="log" border="0" cellpadding="5" cellspacing="2" width="100%">
+ <tr>
+ <th>Error Description</th>
+ <th>Line:Column</th>
+ </tr>
+ <xsl:for-each select="error">
+ <tr>
+ <xsl:call-template name="alternated-row"/>
+ <td><a title="{@source}"><xsl:value-of select="@message"/></a></td>
+ <td align="center"><xsl:value-of select="@line"/><xsl:if test="@column">:<xsl:value-of select="@column"/></xsl:if></td>
+ </tr>
+ </xsl:for-each>
+ </table>
+ </body>
+ </html>
+ </redirect:write>
+ </xsl:template>
+
+ <xsl:template match="checkstyle" mode="summary">
+ <h3>Summary</h3>
+ <xsl:variable name="fileCount" select="count(file)"/>
+ <xsl:variable name="errorCount" select="count(file/error)"/>
+ <xsl:variable name="fileErrorCount" select="count(file[count(error) != 0])"/>
+ <table class="log" border="0" cellpadding="5" cellspacing="2" width="100%">
+ <tr>
+ <th>Total Files</th>
+ <th>Files With Errors</th>
+ <th>Errors</th>
+ </tr>
+ <tr>
+ <xsl:call-template name="alternated-row"/>
+ <td><xsl:value-of select="$fileCount"/></td>
+ <td><xsl:value-of select="$fileErrorCount"/></td>
+ <td><xsl:value-of select="$errorCount"/></td>
+ </tr>
+ </table>
+ </xsl:template>
+
+ <xsl:template name="alternated-row">
+ <xsl:attribute name="class">
+ <xsl:if test="position() mod 2 = 1">oddrow</xsl:if>
+ <xsl:if test="position() mod 2 = 0">evenrow</xsl:if>
+ </xsl:attribute>
+ </xsl:template>
+</xsl:stylesheet> \ No newline at end of file
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/checkstyle/checkstyle-text.xsl b/framework/src/ant/apache-ant-1.9.6/src/etc/checkstyle/checkstyle-text.xsl
new file mode 100644
index 00000000..7359e416
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/checkstyle/checkstyle-text.xsl
@@ -0,0 +1,34 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+ <xsl:strip-space elements="checkstyle"/>
+ <xsl:preserve-space elements="file"/>
+ <xsl:output method="text"/>
+ <xsl:template match="checkstyle/file/error">
+ <xsl:value-of select="../@name"/>
+ <xsl:text>:</xsl:text>
+ <xsl:value-of select="@line"/>
+ <xsl:text>:</xsl:text>
+ <xsl:value-of select="@column"/>
+ <xsl:text> </xsl:text>
+ <xsl:value-of select="@message"/>
+ </xsl:template>
+</xsl:stylesheet>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/checkstyle/checkstyle-xdoc.xsl b/framework/src/ant/apache-ant-1.9.6/src/etc/checkstyle/checkstyle-xdoc.xsl
new file mode 100644
index 00000000..5fc6eab3
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/checkstyle/checkstyle-xdoc.xsl
@@ -0,0 +1,130 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
+ xmlns:lxslt="http://xml.apache.org/xslt"
+ xmlns:redirect="org.apache.xalan.lib.Redirect"
+ extension-element-prefixes="redirect">
+
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+ <xsl:output method="xml" indent="yes"/>
+ <xsl:decimal-format decimal-separator="." grouping-separator="," />
+
+ <xsl:param name="output.dir" select="'.'"/>
+ <xsl:param name="basedir" select="'.'"/>
+
+ <xsl:template match="checkstyle">
+ <document>
+ <properties>
+ <title>Checkstyle Audit</title>
+ </properties>
+
+ <body>
+ <xsl:apply-templates select="." mode="summary"/>
+ <!-- File list part -->
+ <xsl:apply-templates select="." mode="filelist"/>
+ <xsl:apply-templates select="file[count(error) != 0]"/>
+ </body>
+ </document>
+ </xsl:template>
+
+ <xsl:template match="checkstyle" mode="filelist">
+ <section name="Files">
+ <table>
+ <tr>
+ <th>Name</th>
+ <th>Errors</th>
+ </tr>
+ <xsl:apply-templates select="file[count(error) != 0]" mode="filelist">
+ <xsl:sort select="count(error)" order="descending" data-type="number"/>
+ </xsl:apply-templates>
+ </table>
+ </section>
+ </xsl:template>
+
+ <xsl:template match="file" mode="filelist">
+ <tr>
+ <xsl:call-template name="alternated-row"/>
+ <td nowrap="nowrap">
+ <a>
+ <xsl:attribute name="href">
+ <xsl:text>files</xsl:text><xsl:value-of select="substring-after(@name, $basedir)"/><xsl:text>.html</xsl:text>
+ </xsl:attribute>
+ <xsl:value-of select="substring-after(@name, $basedir)"/>
+ </a>
+ </td>
+ <td><xsl:value-of select="count(error)"/></td>
+ </tr>
+ </xsl:template>
+
+ <xsl:template match="file">
+ <redirect:write file="{$output.dir}/files{substring-after(@name, $basedir)}.xml">
+ <document>
+ <properties>
+ <title>Checkstyle Audit</title>
+ </properties>
+
+ <body>
+ <section name="Details for {substring-after(@name, $basedir)}">
+ <table>
+ <tr>
+ <th>Error Description</th>
+ <th>Line</th>
+ </tr>
+ <xsl:for-each select="error">
+ <tr>
+ <xsl:call-template name="alternated-row"/>
+ <td><a title="{@source}"><xsl:value-of select="@message"/></a></td>
+ <td><xsl:value-of select="@line"/></td>
+ </tr>
+ </xsl:for-each>
+ </table>
+ </section>
+ </body>
+ </document>
+ </redirect:write>
+ </xsl:template>
+
+ <xsl:template match="checkstyle" mode="summary">
+ <section name="Summary">
+ <xsl:variable name="fileCount" select="count(file)"/>
+ <xsl:variable name="errorCount" select="count(file/error)"/>
+ <xsl:variable name="fileErrorCount" select="count(file[count(error) != 0])"/>
+ <table>
+ <tr>
+ <th>Files</th>
+ <th>Files With Errors</th>
+ <th>Errors</th>
+ </tr>
+ <tr>
+ <xsl:call-template name="alternated-row"/>
+ <td><xsl:value-of select="$fileCount"/></td>
+ <td><xsl:value-of select="$fileErrorCount"/></td>
+ <td><xsl:value-of select="$errorCount"/></td>
+ </tr>
+ </table>
+ </section>
+ </xsl:template>
+
+ <xsl:template name="alternated-row">
+ <xsl:attribute name="class">
+ <xsl:if test="position() mod 2 = 1">oddrow</xsl:if>
+ <xsl:if test="position() mod 2 = 0">evenrow</xsl:if>
+ </xsl:attribute>
+ </xsl:template>
+</xsl:stylesheet>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/common2master.xsl b/framework/src/ant/apache-ant-1.9.6/src/etc/common2master.xsl
new file mode 100644
index 00000000..da1527e9
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/common2master.xsl
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+ This stylesheet can be used to generate a master buildfile from a common
+ buildfile (see manual for <subant>).
+ Foreach <target> in the common buildfile it generates a corresponding
+ target in the master buildfile for iterating over that target.
+-->
+<xsl:stylesheet
+ version="1.0"
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+ <xsl:output indent="no" method="text" encoding="ISO-8859-1"/>
+ <xsl:strip-space elements="*"/>
+
+
+<xsl:template match="/">
+ <xsl:apply-templates/>
+</xsl:template>
+
+
+
+<xsl:template match="project">
+<![CDATA[
+<project name="master">
+
+ <macrodef name="iterate">
+ <attribute name="target"/>
+ <sequential>
+ <subant target="@{target}">
+ <fileset dir="modules" includes="*/build.xml"/>
+ </subant>
+ </sequential>
+ </macrodef>
+]]>
+
+ <xsl:apply-templates/>
+
+<![CDATA[
+</project>
+]]>
+</xsl:template>
+
+
+<xsl:template match="target">
+ &lt;target name=&quot;<xsl:value-of select="@name"/>&quot;<xsl:if test="@description"> description=&quot;<xsl:value-of select="@description"/>&quot;</xsl:if>&gt;
+ &lt;iterate target=&quot;<xsl:value-of select="@name"/>&quot;/&gt;
+ &lt;/target&gt;
+</xsl:template>
+
+
+<xsl:template match="text()"/>
+
+
+
+</xsl:stylesheet>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/coverage-frames.xsl b/framework/src/ant/apache-ant-1.9.6/src/etc/coverage-frames.xsl
new file mode 100644
index 00000000..9603597e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/coverage-frames.xsl
@@ -0,0 +1,487 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
+ xmlns:lxslt="http://xml.apache.org/xslt"
+ xmlns:redirect="org.apache.xalan.lib.Redirect"
+ extension-element-prefixes="redirect">
+<xsl:output method="html" indent="yes"/>
+<xsl:decimal-format decimal-separator="." grouping-separator="," />
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<!--
+
+ Sample stylesheet to be used with JProbe 3.0 XML output.
+
+ It creates a set of HTML files a la javadoc where you can browse easily
+ through all packages and classes.
+
+ It is best used with JProbe Coverage Ant task that gives you the benefit
+ of a reference classpath so that you have the list of classes/methods
+ that are not used at all in a given classpath.
+
+-->
+
+<!-- default output directory is current directory -->
+<xsl:param name="output.dir" select="'.'"/>
+
+<!-- ======================================================================
+ Root element
+ ======================================================================= -->
+<xsl:template match="/snapshot">
+ <!-- create the index.html -->
+ <redirect:write file="{$output.dir}/index.html">
+ <xsl:call-template name="index.html"/>
+ </redirect:write>
+
+ <!-- create the stylesheet.css -->
+ <redirect:write file="{$output.dir}/stylesheet.css">
+ <xsl:call-template name="stylesheet.css"/>
+ </redirect:write>
+
+ <!-- create the overview-packages.html at the root -->
+ <redirect:write file="{$output.dir}/overview-summary.html">
+ <xsl:apply-templates select="." mode="overview.packages"/>
+ </redirect:write>
+
+ <!-- create the all-packages.html at the root -->
+ <redirect:write file="{$output.dir}/overview-frame.html">
+ <xsl:apply-templates select="." mode="all.packages"/>
+ </redirect:write>
+
+ <!-- create the all-classes.html at the root -->
+ <redirect:write file="{$output.dir}/allclasses-frame.html">
+ <xsl:apply-templates select="." mode="all.classes"/>
+ </redirect:write>
+
+ <!-- process all packages -->
+ <xsl:apply-templates select="./package" mode="write"/>
+</xsl:template>
+
+<!-- =======================================================================
+ Frameset definition. Entry point for the report.
+ 3 frames: packageListFrame, classListFrame, classFrame
+ ======================================================================= -->
+<xsl:template name="index.html">
+<html>
+ <head><title>Coverage Results.</title></head>
+ <frameset cols="20%,80%">
+ <frameset rows="30%,70%">
+ <frame src="overview-frame.html" name="packageListFrame"/>
+ <frame src="allclasses-frame.html" name="classListFrame"/>
+ </frameset>
+ <frame src="overview-summary.html" name="classFrame"/>
+ </frameset>
+ <noframes>
+ <h2>Frame Alert</h2>
+ <p>
+ This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client.
+ </p>
+ </noframes>
+</html>
+</xsl:template>
+
+<!-- =======================================================================
+ Stylesheet CSS used
+ ======================================================================= -->
+<!-- this is the stylesheet css to use for nearly everything -->
+<xsl:template name="stylesheet.css">
+ .bannercell {
+ border: 0px;
+ padding: 0px;
+ }
+ body {
+ margin-left: 10;
+ margin-right: 10;
+ font:normal 80% arial,helvetica,sanserif;
+ background-color:#FFFFFF;
+ color:#000000;
+ }
+ .a td {
+ background: #efefef;
+ }
+ .b td {
+ background: #fff;
+ }
+ th, td {
+ text-align: left;
+ vertical-align: top;
+ }
+ th {
+ font-weight:bold;
+ background: #ccc;
+ color: black;
+ }
+ table, th, td {
+ font-size:100%;
+ border: none
+ }
+ table.log tr td, tr th {
+
+ }
+ h2 {
+ font-weight:bold;
+ font-size:140%;
+ margin-bottom: 5;
+ }
+ h3 {
+ font-size:100%;
+ font-weight:bold;
+ background: #525D76;
+ color: white;
+ text-decoration: none;
+ padding: 5px;
+ margin-right: 2px;
+ margin-left: 2px;
+ margin-bottom: 0;
+ }
+</xsl:template>
+
+<!-- =======================================================================
+ List of all classes in all packages
+ This will be the first page in the classListFrame
+ ======================================================================= -->
+<xsl:template match="snapshot" mode="all.classes">
+ <html>
+ <head>
+ <xsl:call-template name="create.stylesheet.link"/>
+ </head>
+ <body>
+ <h2>Classes</h2>
+ <table width="100%">
+ <xsl:for-each select="package/class">
+ <xsl:sort select="@name"/>
+ <xsl:variable name="package.name" select="(ancestor::package)[last()]/@name"/>
+ <xsl:variable name="link">
+ <xsl:if test="not($package.name='')">
+ <xsl:value-of select="translate($package.name,'.','/')"/><xsl:text>/</xsl:text>
+ </xsl:if><xsl:value-of select="@name"/><xsl:text>.html</xsl:text>
+ </xsl:variable>
+ <tr>
+ <td nowrap="nowrap">
+ <a target="classFrame" href="{$link}"><xsl:value-of select="@name"/></a>
+ </td>
+ </tr>
+ </xsl:for-each>
+ </table>
+ </body>
+ </html>
+</xsl:template>
+
+<!-- list of all packages -->
+<xsl:template match="snapshot" mode="all.packages">
+ <html>
+ <head>
+ <xsl:call-template name="create.stylesheet.link"/>
+ </head>
+ <body>
+ <h2><a href="overview-summary.html" target="classFrame">Home</a></h2>
+ <h2>Packages</h2>
+ <table width="100%">
+ <xsl:for-each select="package">
+ <xsl:sort select="@name" order="ascending"/>
+ <tr>
+ <td nowrap="nowrap">
+ <a href="{translate(@name,'.','/')}/package-summary.html" target="classFrame">
+ <xsl:value-of select="@name"/>
+ </a>
+ </td>
+ </tr>
+ </xsl:for-each>
+ </table>
+ </body>
+ </html>
+</xsl:template>
+
+<!-- overview of statistics in packages -->
+<xsl:template match="snapshot" mode="overview.packages">
+ <html>
+ <head>
+ <xsl:call-template name="create.stylesheet.link"/>
+ </head>
+ <body onload="open('allclasses-frame.html','classListFrame')">
+ <xsl:call-template name="pageHeader"/>
+ <h3>Summary</h3>
+ <table class="log" cellpadding="5" cellspacing="2" width="100%">
+ <tr>
+ <!--th width="10%" nowrap="nowrap">Date</th>
+ <th width="10%" nowrap="nowrap">Elapsed time</th-->
+ <th width="10%" nowrap="nowrap">Reported Classes</th>
+ <th width="10%" nowrap="nowrap">Methods Hit</th>
+ <th width="10%" nowrap="nowrap">Lines Hit</th>
+ </tr>
+ <tr class="a">
+ <!--td nowrap="nowrap"><xsl:value-of select="execution_log/@program_start"/></td>
+ <td><xsl:value-of select="format-number(execution_log/@elapsed_time div 1000,'0.0')"/>secs</td-->
+ <td><xsl:value-of select="count(package/class)"/></td>
+ <td><xsl:value-of select="format-number(cov.data/@hit_methods div cov.data/@total_methods,'0.0%')"/></td>
+ <td><xsl:value-of select="format-number(cov.data/@hit_lines div cov.data/@total_lines,'0.0%')"/></td>
+ </tr>
+ </table>
+ <table border="0" width="100%">
+ <tr>
+ <td style="text-align: justify;">
+ To ensure accurate test runs on Java applications, developers need to know how much of
+ the code has been tested, and where to find any untested code. Coverage helps you
+ locate untested code, and measure precisely how much code has been exercised.
+ The result is a higher quality application in a shorter period of time.
+ <p/>
+ </td>
+ </tr>
+ </table>
+
+ <h3>Packages</h3>
+ <table class="log" cellpadding="5" cellspacing="2" width="100%">
+ <xsl:apply-templates select="package[1]" mode="stats.header"/>
+ <!-- display packages and sort them via their coverage rate -->
+ <xsl:for-each select="package">
+ <xsl:sort data-type="number" select="cov.data/@hit_lines div cov.data/@total_lines"/>
+ <tr>
+ <xsl:call-template name="alternate-row"/>
+ <td><a href="{translate(@name,'.','/')}/package-summary.html"><xsl:value-of select="@name"/></a></td>
+ <td><xsl:value-of select="format-number(cov.data/@hit_methods div cov.data/@total_methods,'0.0%')"/></td>
+ <td><xsl:value-of select="format-number(cov.data/@hit_lines div cov.data/@total_lines,'0.0%')"/></td>
+ </tr>
+ </xsl:for-each>
+ </table>
+ <xsl:call-template name="pageFooter"/>
+ </body>
+ </html>
+</xsl:template>
+
+<!--
+ detailed info for a package. It will output the list of classes
+, the summary page, and the info for each class
+-->
+<xsl:template match="package" mode="write">
+ <xsl:variable name="package.dir">
+ <xsl:if test="not(@name = '')"><xsl:value-of select="translate(@name,'.','/')"/></xsl:if>
+ <xsl:if test="@name = ''">.</xsl:if>
+ </xsl:variable>
+
+ <!-- create a classes-list.html in the package directory -->
+ <redirect:write file="{$output.dir}/{$package.dir}/package-frame.html">
+ <xsl:apply-templates select="." mode="classes.list"/>
+ </redirect:write>
+
+ <!-- create a package-summary.html in the package directory -->
+ <redirect:write file="{$output.dir}/{$package.dir}/package-summary.html">
+ <xsl:apply-templates select="." mode="package.summary"/>
+ </redirect:write>
+
+ <!-- for each class, creates a @name.html -->
+ <xsl:for-each select="class">
+ <redirect:write file="{$output.dir}/{$package.dir}/{@name}.html">
+ <xsl:apply-templates select="." mode="class.details"/>
+ </redirect:write>
+ </xsl:for-each>
+</xsl:template>
+
+<!-- list of classes in a package -->
+<xsl:template match="package" mode="classes.list">
+ <html>
+ <HEAD>
+ <xsl:call-template name="create.stylesheet.link">
+ <xsl:with-param name="package.name" select="@name"/>
+ </xsl:call-template>
+ </HEAD>
+ <BODY>
+ <table width="100%">
+ <tr>
+ <td nowrap="nowrap">
+ <H2><a href="package-summary.html" target="classFrame"><xsl:value-of select="@name"/></a></H2>
+ </td>
+ </tr>
+ </table>
+
+ <H2>Classes</H2>
+ <TABLE WIDTH="100%">
+ <xsl:for-each select="class">
+ <xsl:sort select="@name"/>
+ <tr>
+ <td nowrap="nowrap">
+ <a href="{@name}.html" target="classFrame"><xsl:value-of select="@name"/></a>
+ </td>
+ </tr>
+ </xsl:for-each>
+ </TABLE>
+ </BODY>
+ </html>
+</xsl:template>
+
+<!-- summary of a package -->
+<xsl:template match="package" mode="package.summary">
+ <HTML>
+ <HEAD>
+ <xsl:call-template name="create.stylesheet.link">
+ <xsl:with-param name="package.name" select="@name"/>
+ </xsl:call-template>
+ </HEAD>
+ <!-- when loading this package, it will open the classes into the frame -->
+ <BODY onload="open('package-frame.html','classListFrame')">
+ <xsl:call-template name="pageHeader"/>
+ <h3>Package <xsl:value-of select="@name"/></h3>
+ <table class="log" cellpadding="5" cellspacing="2" width="100%">
+ <xsl:apply-templates select="." mode="stats.header"/>
+ <xsl:apply-templates select="." mode="stats"/>
+ </table>
+
+ <xsl:if test="count(class) &gt; 0">
+ <H3>Classes</H3>
+ <table class="log" cellpadding="5" cellspacing="2" width="100%">
+ <xsl:apply-templates select="." mode="stats.header"/>
+ <xsl:apply-templates select="class" mode="stats">
+ <xsl:sort data-type="number" select="cov.data/@hit_lines div cov.data/@total_lines"/>
+ </xsl:apply-templates>
+ </table>
+ </xsl:if>
+ <xsl:call-template name="pageFooter"/>
+ </BODY>
+ </HTML>
+</xsl:template>
+
+<!-- details of a class -->
+<xsl:template match="class" mode="class.details">
+ <xsl:variable name="package.name" select="(ancestor::package)[last()]/@name"/>
+ <HTML>
+ <HEAD>
+ <xsl:call-template name="create.stylesheet.link">
+ <xsl:with-param name="package.name" select="$package.name"/>
+ </xsl:call-template>
+ </HEAD>
+ <BODY>
+ <xsl:call-template name="pageHeader"/>
+ <H3>Class <xsl:if test="not($package.name = '')"><xsl:value-of select="$package.name"/>.</xsl:if><xsl:value-of select="@name"/></H3>
+
+ <!-- class summary -->
+ <table class="log" cellpadding="5" cellspacing="2" width="100%">
+ <xsl:apply-templates select="." mode="stats.header"/>
+ <xsl:apply-templates select="." mode="stats"/>
+ </table>
+
+ <!-- details of methods -->
+ <H3>Methods</H3>
+ <table class="log" cellpadding="5" cellspacing="2" width="100%">
+ <xsl:apply-templates select="method[1]" mode="stats.header"/>
+ <xsl:apply-templates select="method" mode="stats">
+ <xsl:sort data-type="number" select="cov.data/@hit_lines div cov.data/@total_lines"/>
+ </xsl:apply-templates>
+ </table>
+ <xsl:call-template name="pageFooter"/>
+ </BODY>
+ </HTML>
+
+</xsl:template>
+
+<!-- Page Header -->
+<xsl:template name="pageHeader">
+ <!-- jakarta logo -->
+ <table border="0" cellpadding="0" cellspacing="0" width="100%">
+ <tr>
+ <td class="bannercell" rowspan="2">
+ <a href="http://jakarta.apache.org/">
+ <img src="http://jakarta.apache.org/images/jakarta-logo.gif" alt="http://jakarta.apache.org" align="left" border="0"/>
+ </a>
+ </td>
+ <td style="text-align:right"><h2>Source Code Coverage</h2></td>
+ </tr>
+ <tr>
+ <td style="text-align:right">Designed for use with <a href='http://www.sitraka.com/jprobe'>Sitraka JProbe</a> and <a href='http://jakarta.apache.org'>Ant</a>.</td>
+ </tr>
+ </table>
+ <hr size="1"/>
+</xsl:template>
+
+<!-- Page Footer -->
+<xsl:template name="pageFooter">
+</xsl:template>
+
+
+<xsl:template name="table.header">
+ <tr>
+ <th width="80%">Name</th>
+ <th width="10%" nowrap="nowrap">Methods Hit</th>
+ <th width="10%" nowrap="nowrap">Lines Hit</th>
+ </tr>
+</xsl:template>
+
+<xsl:template match="method" mode="stats.header">
+ <tr>
+ <th width="90%">Name</th>
+ <th width="10%" nowrap="nowrap">Lines Hit</th>
+ </tr>
+</xsl:template>
+<xsl:template match="method" mode="stats">
+ <tr>
+ <xsl:call-template name="alternate-row"/>
+ <td><xsl:value-of select="@name"/></td>
+ <td>
+ <xsl:value-of select="format-number(cov.data/@hit_lines div cov.data/@total_lines,'0.0%')"/>
+ </td>
+ </tr>
+</xsl:template>
+
+<xsl:template match="package|class" mode="stats.header">
+ <tr>
+ <th width="80%">Name</th>
+ <th width="10%" nowrap="nowrap">Methods Hit</th>
+ <th width="10%" nowrap="nowrap">Lines Hit</th>
+ </tr>
+</xsl:template>
+<xsl:template match="package|class" mode="stats">
+ <tr>
+ <xsl:call-template name="alternate-row"/>
+ <td><xsl:value-of select="@name"/></td>
+ <td><xsl:value-of select="format-number(cov.data/@hit_methods div cov.data/@total_methods,'0.0%')"/></td>
+ <td><xsl:value-of select="format-number(cov.data/@hit_lines div cov.data/@total_lines,'0.0%')"/></td>
+ </tr>
+</xsl:template>
+
+<!--
+ transform string like a.b.c to ../../../
+ @param path the path to transform into a descending directory path
+-->
+<xsl:template name="path">
+ <xsl:param name="path"/>
+ <xsl:if test="contains($path,'.')">
+ <xsl:text>../</xsl:text>
+ <xsl:call-template name="path">
+ <xsl:with-param name="path"><xsl:value-of select="substring-after($path,'.')"/></xsl:with-param>
+ </xsl:call-template>
+ </xsl:if>
+ <xsl:if test="not(contains($path,'.')) and not($path = '')">
+ <xsl:text>../</xsl:text>
+ </xsl:if>
+</xsl:template>
+
+
+<!-- create the link to the stylesheet based on the package name -->
+<xsl:template name="create.stylesheet.link">
+ <xsl:param name="package.name"/>
+ <LINK REL ="stylesheet" TYPE="text/css" TITLE="Style"><xsl:attribute name="href"><xsl:if test="not($package.name = 'unnamed package')"><xsl:call-template name="path"><xsl:with-param name="path" select="$package.name"/></xsl:call-template></xsl:if>stylesheet.css</xsl:attribute></LINK>
+</xsl:template>
+
+<!-- alternated row style -->
+<xsl:template name="alternate-row">
+<xsl:attribute name="class">
+ <xsl:if test="position() mod 2 = 1">a</xsl:if>
+ <xsl:if test="position() mod 2 = 0">b</xsl:if>
+</xsl:attribute>
+</xsl:template>
+
+</xsl:stylesheet>
+
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/jdepend-frames.xsl b/framework/src/ant/apache-ant-1.9.6/src/etc/jdepend-frames.xsl
new file mode 100644
index 00000000..80287345
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/jdepend-frames.xsl
@@ -0,0 +1,485 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
+ xmlns:lxslt="http://xml.apache.org/xslt"
+ xmlns:redirect="org.apache.xalan.lib.Redirect"
+ extension-element-prefixes="redirect">
+<xsl:output method="html" indent="yes" encoding="US-ASCII"/>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+-->
+<!--
+
+ Sample stylesheet to be used with JDepend XML output.
+
+ It creates a set of HTML files a la javadoc where you can browse easily
+ through all packages and classes.
+
+ -->
+<xsl:param name="output.dir" select="'.'"/>
+
+<xsl:template match="JDepend">
+ <!-- create the index.html -->
+ <redirect:write file="{$output.dir}/index.html">
+ <xsl:call-template name="index.html"/>
+ </redirect:write>
+
+ <!-- create the stylesheet.css -->
+ <redirect:write file="{$output.dir}/stylesheet.css">
+ <xsl:call-template name="stylesheet.css"/>
+ </redirect:write>
+
+ <!-- create the overview-packages.html at the root -->
+ <redirect:write file="{$output.dir}/overview-summary.html">
+ <xsl:apply-templates select="." mode="overview.packages"/>
+ </redirect:write>
+
+ <!-- create the overview-packages.html at the root -->
+ <redirect:write file="{$output.dir}/overview-packages.html">
+ <xsl:apply-templates select="." mode="packages.details"/>
+ </redirect:write>
+
+ <!-- create the overview-cycles.html at the root -->
+ <redirect:write file="{$output.dir}/overview-cycles.html">
+ <xsl:apply-templates select="." mode="cycles.details"/>
+ </redirect:write>
+
+ <!-- create the overview-cycles.html at the root -->
+ <redirect:write file="{$output.dir}/overview-explanations.html">
+ <xsl:apply-templates select="." mode="explanations"/>
+ </redirect:write>
+
+ <!-- create the all-packages.html at the root -->
+ <redirect:write file="{$output.dir}/all-packages.html">
+ <xsl:apply-templates select="Packages" mode="all.packages"/>
+ </redirect:write>
+
+ <!-- create the all-cycles.html at the root -->
+ <redirect:write file="{$output.dir}/all-cycles.html">
+ <xsl:apply-templates select="Cycles" mode="all.cycles"/>
+ </redirect:write>
+</xsl:template>
+
+
+<xsl:template name="index.html">
+<html>
+ <head>
+ <title>JDepend Analysis</title>
+ </head>
+ <frameset cols="20%,80%">
+ <frameset rows="30%,70%">
+ <frame src="all-packages.html" name="packageListFrame"/>
+ <frame src="all-cycles.html" name="classListFrame"/>
+ </frameset>
+ <frame src="overview-summary.html" name="classFrame"/>
+ </frameset>
+ <noframes>
+ <h2>Frame Alert</h2>
+ <p>
+ This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client.
+ </p>
+ </noframes>
+</html>
+</xsl:template>
+
+<!-- this is the stylesheet css to use for nearly everything -->
+<xsl:template name="stylesheet.css">
+ <style type="text/css">
+ body {
+ font:normal 68% verdana,arial,helvetica;
+ color:#000000;
+ }
+ table tr td, tr th {
+ font-size: 68%;
+ }
+ table.details tr th{
+ font-weight: bold;
+ text-align:left;
+ background:#a6caf0;
+ }
+ table.details tr td{
+ background:#eeeee0;
+ }
+
+ p {
+ line-height:1.5em;
+ margin-top:0.5em; margin-bottom:1.0em;
+ margin-left:2em;
+ margin-right:2em;
+ }
+ h1 {
+ margin: 0px 0px 5px; font: 165% verdana,arial,helvetica
+ }
+ h2 {
+ margin-top: 1em; margin-bottom: 0.5em; font: bold 125% verdana,arial,helvetica
+ }
+ h3 {
+ margin-bottom: 0.5em; font: bold 115% verdana,arial,helvetica
+ }
+ h4 {
+ margin-bottom: 0.5em; font: bold 100% verdana,arial,helvetica
+ }
+ h5 {
+ margin-bottom: 0.5em; font: bold 100% verdana,arial,helvetica
+ }
+ h6 {
+ margin-bottom: 0.5em; font: bold 100% verdana,arial,helvetica
+ }
+ .Error {
+ font-weight:bold; color:red;
+ }
+ .Failure {
+ font-weight:bold; color:purple;
+ }
+ .Properties {
+ text-align:right;
+ }
+ </style>
+</xsl:template>
+
+<xsl:template match="JDepend" mode="overview.packages">
+ <html>
+ <head>
+ <link rel="stylesheet" type="text/css" href="stylesheet.css"/>
+ </head>
+ <body>
+ <xsl:call-template name="pageHeader"/>
+ <table width="100%"><tr align="left"><h2>Summary</h2><td>
+ </td><td align="right">
+ [summary]
+ [<a href="overview-packages.html">packages</a>]
+ [<a href="overview-cycles.html">cycles</a>]
+ [<a href="overview-explanations.html">explanations</a>]
+ </td></tr></table>
+ <table width="100%" class="details">
+ <tr>
+ <th>Package</th>
+ <th>Total Classes</th>
+ <th><a href="overview-explanations.html#EXnumber">Abstract Classes</a></th>
+ <th><a href="overview-explanations.html#EXnumber">Concrete Classes</a></th>
+ <th><a href="overview-explanations.html#EXafferent">Afferent Couplings</a></th>
+ <th><a href="overview-explanations.html#EXefferent">Efferent Couplings</a></th>
+ <th><a href="overview-explanations.html#EXabstractness">Abstractness</a></th>
+ <th><a href="overview-explanations.html#EXinstability">Instability</a></th>
+ <th><a href="overview-explanations.html#EXdistance">Distance</a></th>
+
+ </tr>
+ <xsl:for-each select="./Packages/Package">
+ <xsl:if test="count(error) = 0">
+ <tr>
+ <td align="left">
+ <a>
+ <xsl:attribute name="href">overview-packages.html#PK<xsl:value-of select="@name"/>
+ </xsl:attribute>
+ <xsl:value-of select="@name"/>
+ </a>
+ </td>
+ <td align="right"><xsl:value-of select="Stats/TotalClasses"/></td>
+ <td align="right"><xsl:value-of select="Stats/AbstractClasses"/></td>
+ <td align="right"><xsl:value-of select="Stats/ConcreteClasses"/></td>
+ <td align="right"><xsl:value-of select="Stats/Ca"/></td>
+ <td align="right"><xsl:value-of select="Stats/Ce"/></td>
+ <td align="right"><xsl:value-of select="Stats/A"/></td>
+ <td align="right"><xsl:value-of select="Stats/I"/></td>
+ <td align="right"><xsl:value-of select="Stats/D"/></td>
+ </tr>
+ </xsl:if>
+ </xsl:for-each>
+ <xsl:for-each select="./Packages/Package">
+ <xsl:if test="count(error) &gt; 0">
+ <tr>
+ <td align="left">
+ <xsl:value-of select="@name"/>
+ </td>
+ <td align="left" colspan="8"><xsl:value-of select="error"/></td>
+ </tr>
+ </xsl:if>
+ </xsl:for-each>
+ </table>
+ </body>
+ </html>
+</xsl:template>
+
+<xsl:template match="JDepend" mode="packages.details">
+ <html>
+ <head>
+ <link rel="stylesheet" type="text/css" href="stylesheet.css"/>
+ </head>
+ <body>
+ <xsl:call-template name="pageHeader"/>
+ <table width="100%"><tr align="left"><h2>Packages</h2><td>
+ </td><td align="right">
+ [<a href="overview-summary.html">summary</a>]
+ [packages]
+ [<a href="overview-cycles.html">cycles</a>]
+ [<a href="overview-explanations.html">explanations</a>]
+ </td></tr></table>
+
+ <xsl:for-each select="./Packages/Package">
+ <xsl:if test="count(error) = 0">
+ <h3><a><xsl:attribute name="name">PK<xsl:value-of select="@name"/></xsl:attribute>
+ <xsl:value-of select="@name"/></a></h3>
+
+ <table width="100%"><tr>
+ <td><a href="overview-explanations.html#EXafferent">Afferent Couplings</a>: <xsl:value-of select="Stats/Ca"/></td>
+ <td><a href="overview-explanations.html#EXefferent">Efferent Couplings</a>: <xsl:value-of select="Stats/Ce"/></td>
+ <td><a href="overview-explanations.html#EXabstractness">Abstractness</a>: <xsl:value-of select="Stats/A"/></td>
+ <td><a href="overview-explanations.html#EXinstability">Instability</a>: <xsl:value-of select="Stats/I"/></td>
+ <td><a href="overview-explanations.html#EXdistance">Distance</a>: <xsl:value-of select="Stats/D"/></td>
+ </tr></table>
+
+ <table width="100%" class="details">
+ <tr>
+ <th>Abstract Classes</th>
+ <th>Concrete Classes</th>
+ <th>Used by Packages</th>
+ <th>Uses Packages</th>
+ </tr>
+ <tr>
+ <td valign="top" width="25%">
+ <xsl:if test="count(AbstractClasses/Class)=0">
+ <i>None</i>
+ </xsl:if>
+ <xsl:for-each select="AbstractClasses/Class">
+ <xsl:value-of select="node()"/><br/>
+ </xsl:for-each>
+ </td>
+ <td valign="top" width="25%">
+ <xsl:if test="count(ConcreteClasses/Class)=0">
+ <i>None</i>
+ </xsl:if>
+ <xsl:for-each select="ConcreteClasses/Class">
+ <xsl:value-of select="node()"/><br/>
+ </xsl:for-each>
+ </td>
+ <td valign="top" width="25%">
+ <xsl:if test="count(UsedBy/Package)=0">
+ <i>None</i>
+ </xsl:if>
+ <xsl:for-each select="UsedBy/Package">
+ <a>
+ <xsl:attribute name="href">overview-packages.html#PK<xsl:value-of select="node()"/></xsl:attribute>
+ <xsl:value-of select="node()"/>
+ </a><br/>
+ </xsl:for-each>
+ </td>
+ <td valign="top" width="25%">
+ <xsl:if test="count(DependsUpon/Package)=0">
+ <i>None</i>
+ </xsl:if>
+ <xsl:for-each select="DependsUpon/Package">
+ <a>
+ <xsl:attribute name="href">overview-packages.html#PK<xsl:value-of select="node()"/></xsl:attribute>
+ <xsl:value-of select="node()"/>
+ </a><br/>
+ </xsl:for-each>
+ </td>
+ </tr>
+ </table>
+ </xsl:if>
+ </xsl:for-each>
+ <!-- this is often a long listing; provide a lower navigation table also -->
+ <table width="100%"><tr align="left"><td></td><td align="right">
+ [<a href="overview-summary.html">summary</a>]
+ [packages]
+ [<a href="overview-cycles.html">cycles</a>]
+ [<a href="overview-explanations.html">explanations</a>]
+ </td></tr></table>
+ </body>
+ </html>
+</xsl:template>
+
+<xsl:template match="JDepend" mode="cycles.details">
+ <html>
+ <head>
+ <link rel="stylesheet" type="text/css" href="stylesheet.css"/>
+ </head>
+ <body>
+ <xsl:call-template name="pageHeader"/>
+ <table width="100%"><tr align="left"><h2>Cycles</h2><td>
+ </td><td align="right">
+ [<a href="overview-summary.html">summary</a>]
+ [<a href="overview-packages.html">packages</a>]
+ [cycles]
+ [<a href="overview-explanations.html">explanations</a>]
+ </td></tr></table>
+ <!--<table width="100%"><tr><td>
+ </td><td align="right">
+ [<a href="#NVsummary">summary</a>]
+ [<a href="#NVpackages">packages</a>]
+ [<a href="#NVcycles">cycles</a>]
+ [<a href="#NVexplanations">explanations</a>]
+ </td></tr></table> -->
+
+ <xsl:if test="count(Cycles/Package) = 0">
+ <p>There are no cyclic dependancies.</p>
+ </xsl:if>
+ <xsl:for-each select="Cycles/Package">
+ <h3><a><xsl:attribute name="name">#CY<xsl:value-of select="@Name"/></xsl:attribute><xsl:value-of select="@Name"/></a></h3><p>
+ <xsl:for-each select="Package">
+ <xsl:value-of select="."/><br/>
+ </xsl:for-each></p>
+ </xsl:for-each>
+ <!-- this is often a long listing; provide a lower navigation table also -->
+ <table width="100%"><tr align="left"><td></td><td align="right">
+ [<a href="overview-summary.html">summary</a>]
+ [<a href="overview-packages.html">packages</a>]
+ [cycles]
+ [<a href="overview-explanations.html">explanations</a>]
+ </td></tr></table>
+ </body>
+ </html>
+</xsl:template>
+
+<xsl:template match="JDepend" mode="explanations">
+ <html>
+ <head>
+ <link rel="stylesheet" type="text/css" href="stylesheet.css"/>
+ </head>
+ <body>
+ <xsl:call-template name="pageHeader"/>
+
+ <table width="100%"><tr align="left"><h2>Explanations</h2><td>
+ </td><td align="right">
+ [<a href="overview-summary.html">summary</a>]
+ [<a href="overview-packages.html">packages</a>]
+ [<a href="overview-cycles.html">cycles</a>]
+ [explanations]
+ </td></tr></table>
+
+ <p>The following explanations are for quick reference and are lifted directly from the original <a href="http://www.clarkware.com/software/JDepend.html">JDepend documentation</a>.</p>
+
+ <h3><a name="EXnumber">Number of Classes</a></h3>
+ <p>The number of concrete and abstract classes (and interfaces) in the package is an indicator of the extensibility of the package.</p>
+ <h3><a name="EXafferent">Afferent Couplings</a></h3>
+ <p>The number of other packages that depend upon classes within the package is an indicator of the package's responsibility. </p>
+ <h3><a name="EXefferent">Efferent Couplings</a></h3>
+ <p>The number of other packages that the classes in the package depend upon is an indicator of the package's independence. </p>
+ <h3><a name="EXabstractness">Abstractness</a></h3>
+ <p>The ratio of the number of abstract classes (and interfaces) in the analyzed package to the total number of classes in the analyzed package. </p>
+ <p>The range for this metric is 0 to 1, with A=0 indicating a completely concrete package and A=1 indicating a completely abstract package. </p>
+ <h3><a name="EXinstability">Instability</a></h3>
+ <p>The ratio of efferent coupling (Ce) to total coupling (Ce / (Ce + Ca)). This metric is an indicator of the package's resilience to change. </p>
+ <p>The range for this metric is 0 to 1, with I=0 indicating a completely stable package and I=1 indicating a completely instable package. </p>
+ <h3><a name="EXdistance">Distance</a></h3>
+ <p>The perpendicular distance of a package from the idealized line A + I = 1. This metric is an indicator of the package's balance between abstractness and stability. </p>
+ <p>A package squarely on the main sequence is optimally balanced with respect to its abstractness and stability. Ideal packages are either completely abstract and stable (x=0, y=1) or completely concrete and instable (x=1, y=0). </p>
+ <p>The range for this metric is 0 to 1, with D=0 indicating a package that is coincident with the main sequence and D=1 indicating a package that is as far from the main sequence as possible. </p>
+
+ </body>
+ </html>
+</xsl:template>
+
+
+<!--
+Creates an html file that contains a link to all package links in overview-packages.html.
+ @bug there will be a problem here, I don't know yet how to handle unnamed package :(
+-->
+<xsl:template match="JDepend/Packages" mode="all.packages">
+ <html>
+ <head>
+ <link rel="stylesheet" type="text/css" href="stylesheet.css"/>
+ </head>
+ <body>
+ <table width="100%"><tr align="left"><td></td><td nowrap="nowrap" align="right">
+ [<a href="overview-summary.html" target="classFrame">summary</a>]
+ [<a href="overview-packages.html" target="classFrame">packages</a>]
+ [<a href="overview-cycles.html" target="classFrame">cycles</a>]
+ [<a href="overview-explanations.html" target="classFrame">explanations</a>]
+ </td></tr></table>
+ <h2>Packages</h2>
+ <table width="100%">
+ <xsl:apply-templates select="Package[count(error)=0]" mode="all.packages.link">
+ <xsl:sort select="@name"/>
+ </xsl:apply-templates>
+ <xsl:apply-templates select="Package[count(error) &gt; 0]" mode="all.packages.nolink">
+ <xsl:sort select="@name"/>
+ </xsl:apply-templates>
+ </table>
+ </body>
+ </html>
+</xsl:template>
+
+<xsl:template match="JDepend/Packages/Package" mode="all.packages.link">
+ <tr>
+ <td nowrap="nowrap">
+ <a href="overview-packages.html#PK{@name}" target="classFrame">
+ <xsl:value-of select="@name"/>
+ </a>
+ </td>
+ </tr>
+</xsl:template>
+
+<!--
+I do not know JDepend enough to know if every error results in a non-analyzed package,
+but that is how I am presenting it to the viewer. This may need to change.
+ @bug there will be a problem here, I don't know yet how to handle unnamed package :(
+-->
+<xsl:template match="JDepend/Packages/Package" mode="all.packages.nolink">
+ <tr>
+ <td nowrap="nowrap">
+ Not Analyzed: <xsl:value-of select="@name"/>
+ </td>
+ </tr>
+</xsl:template>
+
+<!--
+Creates an html file that contains a link to all package links in overview-cycles.html.
+ @bug there will be a problem here, I don't know yet how to handle unnamed package :(
+-->
+<xsl:template match="JDepend/Cycles" mode="all.cycles">
+ <html>
+ <head>
+ <link rel="stylesheet" type="text/css" href="stylesheet.css"/>
+ </head>
+ <body>
+ <table width="100%"><tr align="left"><td></td><td nowrap="nowrap" align="right">
+ [<a href="overview-summary.html" target="classFrame">summary</a>]
+ [<a href="overview-packages.html" target="classFrame">packages</a>]
+ [<a href="overview-cycles.html" target="classFrame">cycles</a>]
+ [<a href="overview-explanations.html" target="classFrame">explanations</a>]
+ </td></tr></table>
+ <h2>Cycles</h2>
+ <table width="100%">
+ <xsl:apply-templates select="Package" mode="all.cycles">
+ <xsl:sort select="@Name"/>
+ </xsl:apply-templates>
+ </table>
+ </body>
+ </html>
+</xsl:template>
+
+<xsl:template match="JDepend/Cycles/Package" mode="all.cycles">
+ <tr>
+ <td nowrap="nowrap">
+ <a href="overview-cycles.html#CY{@Name}" target="classFrame"><xsl:value-of select="@Name"/></a>
+ </td>
+ </tr>
+</xsl:template>
+
+<!-- Page HEADER -->
+<xsl:template name="pageHeader">
+ <h1>JDepend Analysis</h1>
+ <table width="100%">
+ <tr>
+ <td align="left"></td>
+ <td align="right">Designed for use with <a href="http://www.clarkware.com/software/JDepend.html">JDepend</a> and <a href="http://jakarta.apache.org">Ant</a>.</td>
+ </tr>
+ </table>
+ <hr size="1"/>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/jdepend.xsl b/framework/src/ant/apache-ant-1.9.6/src/etc/jdepend.xsl
new file mode 100644
index 00000000..f8132975
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/jdepend.xsl
@@ -0,0 +1,276 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<xsl:output method="html" indent="yes" encoding="US-ASCII"/>
+
+<xsl:template match="JDepend">
+ <html>
+ <head>
+ <title>JDepend Analysis</title>
+
+ <style type="text/css">
+ body {
+ font:normal 68% verdana,arial,helvetica;
+ color:#000000;
+ }
+ table tr td, tr th {
+ font-size: 68%;
+ }
+ table.details tr th{
+ font-weight: bold;
+ text-align:left;
+ background:#a6caf0;
+ }
+ table.details tr td{
+ background:#eeeee0;
+ }
+
+ p {
+ line-height:1.5em;
+ margin-top:0.5em; margin-bottom:1.0em;
+ margin-left:2em;
+ margin-right:2em;
+ }
+ h1 {
+ margin: 0px 0px 5px; font: 165% verdana,arial,helvetica
+ }
+ h2 {
+ margin-top: 1em; margin-bottom: 0.5em; font: bold 125% verdana,arial,helvetica
+ }
+ h3 {
+ margin-bottom: 0.5em; font: bold 115% verdana,arial,helvetica
+ }
+ h4 {
+ margin-bottom: 0.5em; font: bold 100% verdana,arial,helvetica
+ }
+ h5 {
+ margin-bottom: 0.5em; font: bold 100% verdana,arial,helvetica
+ }
+ h6 {
+ margin-bottom: 0.5em; font: bold 100% verdana,arial,helvetica
+ }
+ .Error {
+ font-weight:bold; color:red;
+ }
+ .Failure {
+ font-weight:bold; color:purple;
+ }
+ .Properties {
+ text-align:right;
+ }
+ </style>
+
+
+ </head>
+ <body>
+ <!--h1>JDepend Report</h1>
+ <ul>
+ <xsl:for-each select="./Packages/Package">
+ <xsl:sort select="@name"/>
+ <li><xsl:value-of select="@name"/></li>
+ </xsl:for-each>
+ </ul-->
+
+ <h1><a name="top">JDepend Analysis</a></h1>
+ <p align="right">Designed for use with <a href="http://www.clarkware.com/software/JDepend.html">JDepend</a> and <a href="http://jakarta.apache.org">Ant</a>.</p>
+ <hr size="2" />
+
+ <table width="100%"><tr><td>
+ <a name="NVsummary"><h2>Summary</h2></a>
+ </td><td align="right">
+ [<a href="#NVsummary">summary</a>]
+ [<a href="#NVpackages">packages</a>]
+ [<a href="#NVcycles">cycles</a>]
+ [<a href="#NVexplanations">explanations</a>]
+ </td></tr></table>
+
+ <table width="100%" class="details">
+ <tr>
+ <th>Package</th>
+ <th>Total Classes</th>
+ <th><a href="#EXnumber">Abstract Classes</a></th>
+ <th><a href="#EXnumber">Concrete Classes</a></th>
+ <th><a href="#EXafferent">Afferent Couplings</a></th>
+ <th><a href="#EXefferent">Efferent Couplings</a></th>
+ <th><a href="#EXabstractness">Abstractness</a></th>
+ <th><a href="#EXinstability">Instability</a></th>
+ <th><a href="#EXdistance">Distance</a></th>
+
+ </tr>
+ <xsl:for-each select="./Packages/Package">
+ <xsl:if test="count(error) = 0">
+ <tr>
+ <td align="left">
+ <a>
+ <xsl:attribute name="href">#PK<xsl:value-of select="@name"/>
+ </xsl:attribute>
+ <xsl:value-of select="@name"/>
+ </a>
+ </td>
+ <td align="right"><xsl:value-of select="Stats/TotalClasses"/></td>
+ <td align="right"><xsl:value-of select="Stats/AbstractClasses"/></td>
+ <td align="right"><xsl:value-of select="Stats/ConcreteClasses"/></td>
+ <td align="right"><xsl:value-of select="Stats/Ca"/></td>
+ <td align="right"><xsl:value-of select="Stats/Ce"/></td>
+ <td align="right"><xsl:value-of select="Stats/A"/></td>
+ <td align="right"><xsl:value-of select="Stats/I"/></td>
+ <td align="right"><xsl:value-of select="Stats/D"/></td>
+
+
+ </tr>
+ </xsl:if>
+ </xsl:for-each>
+ <xsl:for-each select="./Packages/Package">
+ <xsl:if test="count(error) &gt; 0">
+ <tr>
+ <td align="left">
+ <xsl:value-of select="@name"/>
+ </td>
+ <td align="left" colspan="8"><xsl:value-of select="error"/></td>
+ </tr>
+ </xsl:if>
+ </xsl:for-each>
+ </table>
+
+ <table width="100%"><tr><td>
+ <a name="NVpackages"><h2>Packages</h2></a>
+ </td><td align="right">
+ [<a href="#NVsummary">summary</a>]
+ [<a href="#NVpackages">packages</a>]
+ [<a href="#NVcycles">cycles</a>]
+ [<a href="#NVexplanations">explanations</a>]
+ </td></tr></table>
+
+ <xsl:for-each select="./Packages/Package">
+ <xsl:if test="count(error) = 0">
+ <h3><a><xsl:attribute name="name">PK<xsl:value-of select="@name"/></xsl:attribute>
+ <xsl:value-of select="@name"/></a></h3>
+
+ <table width="100%"><tr>
+ <td><a href="#EXafferent">Afferent Couplings</a>: <xsl:value-of select="Stats/Ca"/></td>
+ <td><a href="#EXefferent">Efferent Couplings</a>: <xsl:value-of select="Stats/Ce"/></td>
+ <td><a href="#EXabstractness">Abstractness</a>: <xsl:value-of select="Stats/A"/></td>
+ <td><a href="#EXinstability">Instability</a>: <xsl:value-of select="Stats/I"/></td>
+ <td><a href="#EXdistance">Distance</a>: <xsl:value-of select="Stats/D"/></td>
+ </tr></table>
+
+ <table width="100%" class="details">
+ <tr>
+ <th>Abstract Classes</th>
+ <th>Concrete Classes</th>
+ <th>Used by Packages</th>
+ <th>Uses Packages</th>
+ </tr>
+ <tr>
+ <td valign="top" width="25%">
+ <xsl:if test="count(AbstractClasses/Class)=0">
+ <i>None</i>
+ </xsl:if>
+ <xsl:for-each select="AbstractClasses/Class">
+ <xsl:value-of select="node()"/><br/>
+ </xsl:for-each>
+ </td>
+ <td valign="top" width="25%">
+ <xsl:if test="count(ConcreteClasses/Class)=0">
+ <i>None</i>
+ </xsl:if>
+ <xsl:for-each select="ConcreteClasses/Class">
+ <xsl:value-of select="node()"/><br/>
+ </xsl:for-each>
+ </td>
+ <td valign="top" width="25%">
+ <xsl:if test="count(UsedBy/Package)=0">
+ <i>None</i>
+ </xsl:if>
+ <xsl:for-each select="UsedBy/Package">
+ <a>
+ <xsl:attribute name="href">#PK<xsl:value-of select="node()"/></xsl:attribute>
+ <xsl:value-of select="node()"/>
+ </a><br/>
+ </xsl:for-each>
+ </td>
+ <td valign="top" width="25%">
+ <xsl:if test="count(DependsUpon/Package)=0">
+ <i>None</i>
+ </xsl:if>
+ <xsl:for-each select="DependsUpon/Package">
+ <a>
+ <xsl:attribute name="href">#PK<xsl:value-of select="node()"/></xsl:attribute>
+ <xsl:value-of select="node()"/>
+ </a><br/>
+ </xsl:for-each>
+ </td>
+ </tr>
+ </table>
+ </xsl:if>
+ </xsl:for-each>
+
+ <table width="100%"><tr><td>
+ <a name="NVcycles"><h2>Cycles</h2></a>
+ </td><td align="right">
+ [<a href="#NVsummary">summary</a>]
+ [<a href="#NVpackages">packages</a>]
+ [<a href="#NVcycles">cycles</a>]
+ [<a href="#NVexplanations">explanations</a>]
+ </td></tr></table>
+
+ <xsl:if test="count(Cycles/Package) = 0">
+ <p>There are no cyclic dependancies.</p>
+ </xsl:if>
+ <xsl:for-each select="Cycles/Package">
+ <h3><xsl:value-of select="@Name"/></h3><p>
+ <xsl:for-each select="Package">
+ <xsl:value-of select="."/><br/>
+ </xsl:for-each></p>
+ </xsl:for-each>
+
+ <table width="100%"><tr><td>
+ <a name="NVexplanations"><h2>Explanations</h2></a>
+ </td><td align="right">
+ [<a href="#NVsummary">summary</a>]
+ [<a href="#NVpackages">packages</a>]
+ [<a href="#NVcycles">cycles</a>]
+ [<a href="#NVexplanations">explanations</a>]
+ </td></tr></table>
+
+ <p>The following explanations are for quick reference and are lifted directly from the original <a href="http://www.clarkware.com/software/JDepend.html">JDepend documentation</a>.</p>
+
+ <h3><a name="EXnumber">Number of Classes</a></h3>
+ <p>The number of concrete and abstract classes (and interfaces) in the package is an indicator of the extensibility of the package.</p>
+ <h3><a name="EXafferent">Afferent Couplings</a></h3>
+ <p>The number of other packages that depend upon classes within the package is an indicator of the package's responsibility. </p>
+ <h3><a name="EXefferent">Efferent Couplings</a></h3>
+ <p>The number of other packages that the classes in the package depend upon is an indicator of the package's independence. </p>
+ <h3><a name="EXabstractness">Abstractness</a></h3>
+ <p>The ratio of the number of abstract classes (and interfaces) in the analyzed package to the total number of classes in the analyzed package. </p>
+ <p>The range for this metric is 0 to 1, with A=0 indicating a completely concrete package and A=1 indicating a completely abstract package. </p>
+ <h3><a name="EXinstability">Instability</a></h3>
+ <p>The ratio of efferent coupling (Ce) to total coupling (Ce / (Ce + Ca)). This metric is an indicator of the package's resilience to change. </p>
+ <p>The range for this metric is 0 to 1, with I=0 indicating a completely stable package and I=1 indicating a completely instable package. </p>
+ <h3><a name="EXdistance">Distance</a></h3>
+ <p>The perpendicular distance of a package from the idealized line A + I = 1. This metric is an indicator of the package's balance between abstractness and stability. </p>
+ <p>A package squarely on the main sequence is optimally balanced with respect to its abstractness and stability. Ideal packages are either completely abstract and stable (x=0, y=1) or completely concrete and instable (x=1, y=0). </p>
+ <p>The range for this metric is 0 to 1, with D=0 indicating a package that is coincident with the main sequence and D=1 indicating a package that is as far from the main sequence as possible. </p>
+
+ </body>
+ </html>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/junit-frames-xalan1.xsl b/framework/src/ant/apache-ant-1.9.6/src/etc/junit-frames-xalan1.xsl
new file mode 100644
index 00000000..fbc28e13
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/junit-frames-xalan1.xsl
@@ -0,0 +1,745 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
+ xmlns:lxslt="http://xml.apache.org/xslt"
+ xmlns:redirect="org.apache.xalan.lib.Redirect"
+ xmlns:string="xalan://java.lang.String"
+ extension-element-prefixes="redirect">
+<xsl:output method="html" indent="yes" encoding="UTF-8"/>
+<xsl:decimal-format decimal-separator="." grouping-separator=","/>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<!--
+
+ Sample stylesheet to be used with Ant JUnitReport output.
+
+ It creates a set of HTML files a la javadoc where you can browse easily
+ through all packages and classes.
+
+-->
+<xsl:param name="output.dir" select="'.'"/>
+
+
+<xsl:template match="testsuites">
+ <!-- create the index.html -->
+ <redirect:write file="{$output.dir}/index.html">
+ <xsl:call-template name="index.html"/>
+ </redirect:write>
+
+ <!-- create the stylesheet.css -->
+ <redirect:write file="{$output.dir}/stylesheet.css">
+ <xsl:call-template name="stylesheet.css"/>
+ </redirect:write>
+
+ <!-- create the overview-packages.html at the root -->
+ <redirect:write file="{$output.dir}/overview-summary.html">
+ <xsl:apply-templates select="." mode="overview.packages"/>
+ </redirect:write>
+
+ <!-- create the all-packages.html at the root -->
+ <redirect:write file="{$output.dir}/overview-frame.html">
+ <xsl:apply-templates select="." mode="all.packages"/>
+ </redirect:write>
+
+ <!-- create the all-classes.html at the root -->
+ <redirect:write file="{$output.dir}/allclasses-frame.html">
+ <xsl:apply-templates select="." mode="all.classes"/>
+ </redirect:write>
+
+ <!-- process all packages -->
+ <xsl:for-each select="./testsuite[not(./@package = preceding-sibling::testsuite/@package)]">
+ <xsl:call-template name="package">
+ <xsl:with-param name="name" select="@package"/>
+ </xsl:call-template>
+ </xsl:for-each>
+</xsl:template>
+
+
+<xsl:template name="package">
+ <xsl:param name="name"/>
+ <xsl:variable name="package.dir">
+ <xsl:if test="not($name = '')"><xsl:value-of select="translate($name,'.','/')"/></xsl:if>
+ <xsl:if test="$name = ''">.</xsl:if>
+ </xsl:variable>
+ <!--Processing package <xsl:value-of select="@name"/> in <xsl:value-of select="$output.dir"/> -->
+ <!-- create a classes-list.html in the package directory -->
+ <redirect:write file="{$output.dir}/{$package.dir}/package-frame.html">
+ <xsl:call-template name="classes.list">
+ <xsl:with-param name="name" select="$name"/>
+ </xsl:call-template>
+ </redirect:write>
+
+ <!-- create a package-summary.html in the package directory -->
+ <redirect:write file="{$output.dir}/{$package.dir}/package-summary.html">
+ <xsl:call-template name="package.summary">
+ <xsl:with-param name="name" select="$name"/>
+ </xsl:call-template>
+ </redirect:write>
+
+ <!-- for each class, creates a @name.html -->
+ <!-- @bug there will be a problem with inner classes having the same name, it will be overwritten -->
+ <xsl:for-each select="/testsuites/testsuite[@package = $name]">
+ <redirect:write file="{$output.dir}/{$package.dir}/{@name}.html">
+ <xsl:apply-templates select="." mode="class.details"/>
+ </redirect:write>
+ <xsl:if test="string-length(./system-out)!=0">
+ <redirect:write file="{$output.dir}/{$package.dir}/{@name}-out.html">
+ <html>
+ <head>
+ <title>Standard Output from <xsl:value-of select="@name"/></title>
+ </head>
+ <body>
+ <pre><xsl:value-of select="./system-out"/></pre>
+ </body>
+ </html>
+ </redirect:write>
+ </xsl:if>
+ <xsl:if test="string-length(./system-err)!=0">
+ <redirect:write file="{$output.dir}/{$package.dir}/{@name}-err.html">
+ <html>
+ <head>
+ <title>Standard Error from <xsl:value-of select="@name"/></title>
+ </head>
+ <body>
+ <pre><xsl:value-of select="./system-err"/></pre>
+ </body>
+ </html>
+ </redirect:write>
+ </xsl:if>
+ </xsl:for-each>
+</xsl:template>
+
+<xsl:template name="index.html">
+<html>
+ <head>
+ <title>Unit Test Results.</title>
+ </head>
+ <frameset cols="20%,80%">
+ <frameset rows="30%,70%">
+ <frame src="overview-frame.html" name="packageListFrame"/>
+ <frame src="allclasses-frame.html" name="classListFrame"/>
+ </frameset>
+ <frame src="overview-summary.html" name="classFrame"/>
+ <noframes>
+ <h2>Frame Alert</h2>
+ <p>
+ This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client.
+ </p>
+ </noframes>
+ </frameset>
+</html>
+</xsl:template>
+
+<!-- this is the stylesheet css to use for nearly everything -->
+<xsl:template name="stylesheet.css">
+body {
+ font:normal 68% verdana,arial,helvetica;
+ color:#000000;
+}
+table tr td, table tr th {
+ font-size: 68%;
+}
+table.details tr th{
+ font-weight: bold;
+ text-align:left;
+ background:#a6caf0;
+}
+table.details tr td{
+ background:#eeeee0;
+}
+
+p {
+ line-height:1.5em;
+ margin-top:0.5em; margin-bottom:1.0em;
+}
+h1 {
+ margin: 0px 0px 5px; font: 165% verdana,arial,helvetica
+}
+h2 {
+ margin-top: 1em; margin-bottom: 0.5em; font: bold 125% verdana,arial,helvetica
+}
+h3 {
+ margin-bottom: 0.5em; font: bold 115% verdana,arial,helvetica
+}
+h4 {
+ margin-bottom: 0.5em; font: bold 100% verdana,arial,helvetica
+}
+h5 {
+ margin-bottom: 0.5em; font: bold 100% verdana,arial,helvetica
+}
+h6 {
+ margin-bottom: 0.5em; font: bold 100% verdana,arial,helvetica
+}
+.Error {
+ font-weight:bold; color:red;
+}
+.Failure {
+ font-weight:bold; color:purple;
+}
+.Properties {
+ text-align:right;
+}
+</xsl:template>
+
+
+<!-- ======================================================================
+ This page is created for every testsuite class.
+ It prints a summary of the testsuite and detailed information about
+ testcase methods.
+ ====================================================================== -->
+<xsl:template match="testsuite" mode="class.details">
+ <xsl:variable name="package.name" select="@package"/>
+ <xsl:variable name="class.name"><xsl:if test="not($package.name = '')"><xsl:value-of select="$package.name"/>.</xsl:if><xsl:value-of select="@name"/></xsl:variable>
+ <html>
+ <head>
+ <title>Unit Test Results: <xsl:value-of select="$class.name"/></title>
+ <xsl:call-template name="create.stylesheet.link">
+ <xsl:with-param name="package.name" select="$package.name"/>
+ </xsl:call-template>
+ <script type="text/javascript" language="JavaScript">
+ var TestCases = new Array();
+ var cur;
+ <xsl:apply-templates select="properties"/>
+ </script>
+ <script type="text/javascript" language="JavaScript"><![CDATA[
+ function displayProperties (name) {
+ var win = window.open('','JUnitSystemProperties','scrollbars=1,resizable=1');
+ var doc = win.document;
+ doc.open();
+ doc.write("<html><head><title>Properties of " + name + "</title>");
+ doc.write("<style type=\"text/css\">");
+ doc.write("body {font:normal 68% verdana,arial,helvetica; color:#000000; }");
+ doc.write("table tr td, table tr th { font-size: 68%; }");
+ doc.write("table.properties { border-collapse:collapse; border-left:solid 1 #cccccc; border-top:solid 1 #cccccc; padding:5px; }");
+ doc.write("table.properties th { text-align:left; border-right:solid 1 #cccccc; border-bottom:solid 1 #cccccc; background-color:#eeeeee; }");
+ doc.write("table.properties td { font:normal; text-align:left; border-right:solid 1 #cccccc; border-bottom:solid 1 #cccccc; background-color:#fffffff; }");
+ doc.write("h3 { margin-bottom: 0.5em; font: bold 115% verdana,arial,helvetica }");
+ doc.write("</style>");
+ doc.write("</head><body>");
+ doc.write("<h3>Properties of " + name + "</h3>");
+ doc.write("<div align=\"right\"><a href=\"javascript:window.close();\">Close</a></div>");
+ doc.write("<table class='properties'>");
+ doc.write("<tr><th>Name</th><th>Value</th></tr>");
+ for (prop in TestCases[name]) {
+ doc.write("<tr><th>" + prop + "</th><td>" + TestCases[name][prop] + "</td></tr>");
+ }
+ doc.write("</table>");
+ doc.write("</body></html>");
+ doc.close();
+ win.focus();
+ }
+ ]]>
+ </script>
+ </head>
+ <body>
+ <xsl:call-template name="pageHeader"/>
+ <h3>Class <xsl:value-of select="$class.name"/></h3>
+
+
+ <table class="details" border="0" cellpadding="5" cellspacing="2" width="95%">
+ <xsl:call-template name="testsuite.test.header"/>
+ <xsl:apply-templates select="." mode="print.test"/>
+ </table>
+
+ <h2>Tests</h2>
+ <table class="details" border="0" cellpadding="5" cellspacing="2" width="95%">
+ <xsl:call-template name="testcase.test.header"/>
+ <!--
+ test can even not be started at all (failure to load the class)
+ so report the error directly
+ -->
+ <xsl:if test="./error">
+ <tr class="Error">
+ <td colspan="4"><xsl:apply-templates select="./error"/></td>
+ </tr>
+ </xsl:if>
+ <xsl:apply-templates select="./testcase" mode="print.test"/>
+ </table>
+ <div class="Properties">
+ <a>
+ <xsl:attribute name="href">javascript:displayProperties('<xsl:value-of select="@package"/>.<xsl:value-of select="@name"/>');</xsl:attribute>
+ Properties &#187;
+ </a>
+ </div>
+ <xsl:if test="string-length(./system-out)!=0">
+ <div class="Properties">
+ <a>
+ <xsl:attribute name="href">./<xsl:value-of select="@name"/>-out.html</xsl:attribute>
+ System.out &#187;
+ </a>
+ </div>
+ </xsl:if>
+ <xsl:if test="string-length(./system-err)!=0">
+ <div class="Properties">
+ <a>
+ <xsl:attribute name="href">./<xsl:value-of select="@name"/>-err.html</xsl:attribute>
+ System.err &#187;
+ </a>
+ </div>
+ </xsl:if>
+ </body>
+ </html>
+</xsl:template>
+
+ <!--
+ Write properties into a JavaScript data structure.
+ This is based on the original idea by Erik Hatcher (ehatcher@apache.org)
+ -->
+ <xsl:template match="properties">
+ cur = TestCases['<xsl:value-of select="../@package"/>.<xsl:value-of select="../@name"/>'] = new Array();
+ <xsl:for-each select="property">
+ <xsl:sort select="@name"/>
+ cur['<xsl:value-of select="@name"/>'] = '<xsl:call-template name="JS-escape"><xsl:with-param name="string" select="@value"/></xsl:call-template>';
+ </xsl:for-each>
+ </xsl:template>
+
+
+<!-- ======================================================================
+ This page is created for every package.
+ It prints the name of all classes that belongs to this package.
+ @param name the package name to print classes.
+ ====================================================================== -->
+<!-- list of classes in a package -->
+<xsl:template name="classes.list">
+ <xsl:param name="name"/>
+ <html>
+ <head>
+ <title>Unit Test Classes: <xsl:value-of select="$name"/></title>
+ <xsl:call-template name="create.stylesheet.link">
+ <xsl:with-param name="package.name" select="$name"/>
+ </xsl:call-template>
+ </head>
+ <body>
+ <table width="100%">
+ <tr>
+ <td nowrap="nowrap">
+ <h2><a href="package-summary.html" target="classFrame">
+ <xsl:value-of select="$name"/>
+ <xsl:if test="$name = ''">&lt;none&gt;</xsl:if>
+ </a></h2>
+ </td>
+ </tr>
+ </table>
+
+ <h2>Classes</h2>
+ <table width="100%">
+ <xsl:for-each select="/testsuites/testsuite[./@package = $name]">
+ <xsl:sort select="@name"/>
+ <tr>
+ <td nowrap="nowrap">
+ <a href="{@name}.html" target="classFrame"><xsl:value-of select="@name"/></a>
+ </td>
+ </tr>
+ </xsl:for-each>
+ </table>
+ </body>
+ </html>
+</xsl:template>
+
+
+<!--
+ Creates an all-classes.html file that contains a link to all package-summary.html
+ on each class.
+-->
+<xsl:template match="testsuites" mode="all.classes">
+ <html>
+ <head>
+ <title>All Unit Test Classes</title>
+ <xsl:call-template name="create.stylesheet.link">
+ <xsl:with-param name="package.name"/>
+ </xsl:call-template>
+ </head>
+ <body>
+ <h2>Classes</h2>
+ <table width="100%">
+ <xsl:apply-templates select="testsuite" mode="all.classes">
+ <xsl:sort select="@name"/>
+ </xsl:apply-templates>
+ </table>
+ </body>
+ </html>
+</xsl:template>
+
+<xsl:template match="testsuite" mode="all.classes">
+ <xsl:variable name="package.name" select="@package"/>
+ <tr>
+ <td nowrap="nowrap">
+ <a target="classFrame">
+ <xsl:attribute name="href">
+ <xsl:if test="not($package.name='')">
+ <xsl:value-of select="translate($package.name,'.','/')"/><xsl:text>/</xsl:text>
+ </xsl:if><xsl:value-of select="@name"/><xsl:text>.html</xsl:text>
+ </xsl:attribute>
+ <xsl:value-of select="@name"/>
+ </a>
+ </td>
+ </tr>
+</xsl:template>
+
+
+<!--
+ Creates an html file that contains a link to all package-summary.html files on
+ each package existing on testsuites.
+ @bug there will be a problem here, I don't know yet how to handle unnamed package :(
+-->
+<xsl:template match="testsuites" mode="all.packages">
+ <html>
+ <head>
+ <title>All Unit Test Packages</title>
+ <xsl:call-template name="create.stylesheet.link">
+ <xsl:with-param name="package.name"/>
+ </xsl:call-template>
+ </head>
+ <body>
+ <h2><a href="overview-summary.html" target="classFrame">Home</a></h2>
+ <h2>Packages</h2>
+ <table width="100%">
+ <xsl:apply-templates select="testsuite[not(./@package = preceding-sibling::testsuite/@package)]" mode="all.packages">
+ <xsl:sort select="@package"/>
+ </xsl:apply-templates>
+ </table>
+ </body>
+ </html>
+</xsl:template>
+
+<xsl:template match="testsuite" mode="all.packages">
+ <tr>
+ <td nowrap="nowrap">
+ <a href="./{translate(@package,'.','/')}/package-summary.html" target="classFrame">
+ <xsl:value-of select="@package"/>
+ <xsl:if test="@package = ''">&lt;none&gt;</xsl:if>
+ </a>
+ </td>
+ </tr>
+</xsl:template>
+
+
+<xsl:template match="testsuites" mode="overview.packages">
+ <html>
+ <head>
+ <title>Unit Test Results: Summary</title>
+ <xsl:call-template name="create.stylesheet.link">
+ <xsl:with-param name="package.name"/>
+ </xsl:call-template>
+ </head>
+ <body>
+ <xsl:attribute name="onload">open('allclasses-frame.html','classListFrame')</xsl:attribute>
+ <xsl:call-template name="pageHeader"/>
+ <h2>Summary</h2>
+ <xsl:variable name="testCount" select="sum(testsuite/@tests)"/>
+ <xsl:variable name="errorCount" select="sum(testsuite/@errors)"/>
+ <xsl:variable name="failureCount" select="sum(testsuite/@failures)"/>
+ <xsl:variable name="skippedCount" select="sum(testsuite/@skipped)"/>
+ <xsl:variable name="timeCount" select="sum(testsuite/@time)"/>
+ <xsl:variable name="successRate" select="($testCount - $failureCount - $errorCount) div $testCount"/>
+ <table class="details" border="0" cellpadding="5" cellspacing="2" width="95%">
+ <tr valign="top">
+ <th>Tests</th>
+ <th>Failures</th>
+ <th>Errors</th>
+ <th>Skipped</th>
+ <th>Success rate</th>
+ <th>Time</th>
+ </tr>
+ <tr valign="top">
+ <xsl:attribute name="class">
+ <xsl:choose>
+ <xsl:when test="$errorCount &gt; 0">Error</xsl:when>
+ <xsl:when test="$failureCount &gt; 0">Failure</xsl:when>
+ <xsl:otherwise>Pass</xsl:otherwise>
+ </xsl:choose>
+ </xsl:attribute>
+ <td><xsl:value-of select="$testCount"/></td>
+ <td><xsl:value-of select="$failureCount"/></td>
+ <td><xsl:value-of select="$errorCount"/></td>
+ <td><xsl:value-of select="$skipCount" /></td>
+ <td>
+ <xsl:call-template name="display-percent">
+ <xsl:with-param name="value" select="$successRate"/>
+ </xsl:call-template>
+ </td>
+ <td>
+ <xsl:call-template name="display-time">
+ <xsl:with-param name="value" select="$timeCount"/>
+ </xsl:call-template>
+ </td>
+ </tr>
+ </table>
+ <table border="0" width="95%">
+ <tr>
+ <td style="text-align: justify;">
+ Note: <em>failures</em> are anticipated and checked for with assertions while <em>errors</em> are unanticipated.
+ </td>
+ </tr>
+ </table>
+
+ <h2>Packages</h2>
+ <table class="details" border="0" cellpadding="5" cellspacing="2" width="95%">
+ <xsl:call-template name="testsuite.test.header"/>
+ <xsl:for-each select="testsuite[not(./@package = preceding-sibling::testsuite/@package)]">
+ <xsl:sort select="@package" order="ascending"/>
+ <!-- get the node set containing all testsuites that have the same package -->
+ <xsl:variable name="insamepackage" select="/testsuites/testsuite[./@package = current()/@package]"/>
+ <tr valign="top">
+ <!-- display a failure if there is any failure/error in the package -->
+ <xsl:attribute name="class">
+ <xsl:choose>
+ <xsl:when test="sum($insamepackage/@errors) &gt; 0">Error</xsl:when>
+ <xsl:when test="sum($insamepackage/@failures) &gt; 0">Failure</xsl:when>
+ <xsl:otherwise>Pass</xsl:otherwise>
+ </xsl:choose>
+ </xsl:attribute>
+ <td><a href="./{translate(@package,'.','/')}/package-summary.html">
+ <xsl:value-of select="@package"/>
+ <xsl:if test="@package = ''">&lt;none&gt;</xsl:if>
+ </a></td>
+ <td><xsl:value-of select="sum($insamepackage/@tests)"/></td>
+ <td><xsl:value-of select="sum($insamepackage/@errors)"/></td>
+ <td><xsl:value-of select="sum($insamepackage/@failures)"/></td>
+ <td><xsl:value-of select="sum($insamepackage/@skipped)" /></td>
+ <td>
+ <xsl:call-template name="display-time">
+ <xsl:with-param name="value" select="sum($insamepackage/@time)"/>
+ </xsl:call-template>
+ </td>
+ <td><xsl:value-of select="$insamepackage/@timestamp"/></td>
+ <td><xsl:value-of select="$insamepackage/@hostname"/></td>
+ </tr>
+ </xsl:for-each>
+ </table>
+ </body>
+ </html>
+</xsl:template>
+
+
+<xsl:template name="package.summary">
+ <xsl:param name="name"/>
+ <html>
+ <head>
+ <xsl:call-template name="create.stylesheet.link">
+ <xsl:with-param name="package.name" select="$name"/>
+ </xsl:call-template>
+ </head>
+ <body>
+ <xsl:attribute name="onload">open('package-frame.html','classListFrame')</xsl:attribute>
+ <xsl:call-template name="pageHeader"/>
+ <h3>Package <xsl:value-of select="$name"/></h3>
+
+ <!--table border="0" cellpadding="5" cellspacing="2" width="95%">
+ <xsl:call-template name="class.metrics.header"/>
+ <xsl:apply-templates select="." mode="print.metrics"/>
+ </table-->
+
+ <xsl:variable name="insamepackage" select="/testsuites/testsuite[./@package = $name]"/>
+ <xsl:if test="count($insamepackage) &gt; 0">
+ <h2>Classes</h2>
+ <p>
+ <table class="details" border="0" cellpadding="5" cellspacing="2" width="95%">
+ <xsl:call-template name="testsuite.test.header"/>
+ <xsl:apply-templates select="$insamepackage" mode="print.test">
+ <xsl:sort select="@name"/>
+ </xsl:apply-templates>
+ </table>
+ </p>
+ </xsl:if>
+ </body>
+ </html>
+</xsl:template>
+
+
+<!--
+ transform string like a.b.c to ../../../
+ @param path the path to transform into a descending directory path
+-->
+<xsl:template name="path">
+ <xsl:param name="path"/>
+ <xsl:if test="contains($path,'.')">
+ <xsl:text>../</xsl:text>
+ <xsl:call-template name="path">
+ <xsl:with-param name="path"><xsl:value-of select="substring-after($path,'.')"/></xsl:with-param>
+ </xsl:call-template>
+ </xsl:if>
+ <xsl:if test="not(contains($path,'.')) and not($path = '')">
+ <xsl:text>../</xsl:text>
+ </xsl:if>
+</xsl:template>
+
+
+<!-- create the link to the stylesheet based on the package name -->
+<xsl:template name="create.stylesheet.link">
+ <xsl:param name="package.name"/>
+ <link rel="stylesheet" type="text/css" title="Style"><xsl:attribute name="href"><xsl:if test="not($package.name = 'unnamed package')"><xsl:call-template name="path"><xsl:with-param name="path" select="$package.name"/></xsl:call-template></xsl:if>stylesheet.css</xsl:attribute></link>
+</xsl:template>
+
+
+<!-- Page HEADER -->
+<xsl:template name="pageHeader">
+ <h1>Unit Test Results</h1>
+ <table width="100%">
+ <tr>
+ <td align="left"></td>
+ <td align="right">Designed for use with <a href="http://www.junit.org/">JUnit</a> and <a href="http://ant.apache.org/">Ant</a>.</td>
+ </tr>
+ </table>
+ <hr size="1"/>
+</xsl:template>
+
+<!-- class header -->
+<xsl:template name="testsuite.test.header">
+ <tr valign="top">
+ <th width="80%">Name</th>
+ <th>Tests</th>
+ <th>Errors</th>
+ <th>Failures</th>
+ <th>Skipped</th>
+ <th nowrap="nowrap">Time(s)</th>
+ <th nowrap="nowrap">Time Stamp</th>
+ <th>Host</th>
+ </tr>
+</xsl:template>
+
+<!-- method header -->
+<xsl:template name="testcase.test.header">
+ <tr valign="top">
+ <th>Name</th>
+ <th>Status</th>
+ <th width="80%">Type</th>
+ <th nowrap="nowrap">Time(s)</th>
+ </tr>
+</xsl:template>
+
+
+<!-- class information -->
+<xsl:template match="testsuite" mode="print.test">
+ <tr valign="top">
+ <xsl:attribute name="class">
+ <xsl:choose>
+ <xsl:when test="@errors[.&gt; 0]">Error</xsl:when>
+ <xsl:when test="@failures[.&gt; 0]">Failure</xsl:when>
+ <xsl:otherwise>Pass</xsl:otherwise>
+ </xsl:choose>
+ </xsl:attribute>
+ <td><a href="{@name}.html"><xsl:value-of select="@name"/></a></td>
+ <td><xsl:apply-templates select="@tests"/></td>
+ <td><xsl:apply-templates select="@errors"/></td>
+ <td><xsl:apply-templates select="@failures"/></td>
+ <td><xsl:apply-templates select="@skipped" /></td>
+ <td><xsl:call-template name="display-time">
+ <xsl:with-param name="value" select="@time"/>
+ </xsl:call-template>
+ </td>
+ <td><xsl:apply-templates select="@timestamp"/></td>
+ <td><xsl:apply-templates select="@hostname"/></td>
+ </tr>
+</xsl:template>
+
+<xsl:template match="testcase" mode="print.test">
+ <tr valign="top">
+ <xsl:attribute name="class">
+ <xsl:choose>
+ <xsl:when test="error">Error</xsl:when>
+ <xsl:when test="failure">Failure</xsl:when>
+ <xsl:otherwise>TableRowColor</xsl:otherwise>
+ </xsl:choose>
+ </xsl:attribute>
+ <td><xsl:value-of select="@name"/></td>
+ <xsl:choose>
+ <xsl:when test="failure">
+ <td>Failure</td>
+ <td><xsl:apply-templates select="failure"/></td>
+ </xsl:when>
+ <xsl:when test="error">
+ <td>Error</td>
+ <td><xsl:apply-templates select="error"/></td>
+ </xsl:when>
+ <xsl:when test="skipped">
+ <td>Skipped</td>
+ <td><xsl:apply-templates select="skipped"/></td>
+ </xsl:when>
+ <xsl:otherwise>
+ <td>Success</td>
+ <td></td>
+ </xsl:otherwise>
+ </xsl:choose>
+ <td>
+ <xsl:call-template name="display-time">
+ <xsl:with-param name="value" select="@time"/>
+ </xsl:call-template>
+ </td>
+ </tr>
+</xsl:template>
+
+
+<!-- Note : the below template error and failure are the same style
+ so just call the same style store in the toolkit template -->
+<xsl:template match="failure">
+ <xsl:call-template name="display-failures"/>
+</xsl:template>
+
+<xsl:template match="error">
+ <xsl:call-template name="display-failures"/>
+</xsl:template>
+
+<!-- Style for the error and failure in the testcase template -->
+<xsl:template name="display-failures">
+ <xsl:choose>
+ <xsl:when test="not(@message)">N/A</xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="@message"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ <!-- display the stacktrace -->
+ <br/><br/>
+ <code>
+ <xsl:call-template name="br-replace">
+ <xsl:with-param name="word" select="."/>
+ </xsl:call-template>
+ </code>
+ <!-- the latter is better but might be problematic for non-21" monitors... -->
+ <!--pre><xsl:value-of select="."/></pre-->
+</xsl:template>
+
+<xsl:template name="JS-escape">
+ <xsl:param name="string"/>
+ <xsl:param name="tmp1" select="string:replaceAll(string:new(string($string)),'\\','\\\\')"/>
+ <xsl:param name="tmp2" select="string:replaceAll(string:new(string($tmp1)),&quot;'&quot;,&quot;\\&apos;&quot;)"/>
+ <xsl:param name="tmp3" select="string:replaceAll(string:new(string($tmp2)),&quot;&#10;&quot;,'\\n')"/>
+ <xsl:param name="tmp4" select="string:replaceAll(string:new(string($tmp3)),&quot;&#13;&quot;,'\\r')"/>
+ <xsl:value-of select="$tmp4"/>
+</xsl:template>
+
+
+<!--
+ template that will convert a carriage return into a br tag
+ @param word the text from which to convert CR to BR tag
+-->
+<xsl:template name="br-replace">
+ <xsl:param name="word"/>
+ <xsl:param name="br"><br/></xsl:param>
+ <xsl:value-of select='stringutils:replace(string($word),"&#xA;",$br)'/>
+</xsl:template>
+
+<xsl:template name="display-time">
+ <xsl:param name="value"/>
+ <xsl:value-of select="format-number($value,'0.000')"/>
+</xsl:template>
+
+<xsl:template name="display-percent">
+ <xsl:param name="value"/>
+ <xsl:value-of select="format-number($value,'0.00%')"/>
+</xsl:template>
+</xsl:stylesheet>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/junit-frames.xsl b/framework/src/ant/apache-ant-1.9.6/src/etc/junit-frames.xsl
new file mode 100644
index 00000000..afea6e01
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/junit-frames.xsl
@@ -0,0 +1,972 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
+ xmlns:lxslt="http://xml.apache.org/xslt"
+ xmlns:redirect="http://xml.apache.org/xalan/redirect"
+ xmlns:string="xalan://java.lang.String"
+ extension-element-prefixes="redirect">
+<xsl:output method="html" indent="yes" encoding="UTF-8"/>
+<xsl:decimal-format decimal-separator="." grouping-separator=","/>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<!--
+
+ Sample stylesheet to be used with Ant JUnitReport output.
+
+ It creates a set of HTML files a la javadoc where you can browse easily
+ through all packages and classes.
+
+-->
+<xsl:param name="output.dir" select="'.'"/>
+<xsl:param name="TITLE">Unit Test Results.</xsl:param>
+
+
+<xsl:template match="testsuites">
+ <!-- create the index.html -->
+ <redirect:write file="{$output.dir}/index.html">
+ <xsl:call-template name="index.html"/>
+ </redirect:write>
+
+ <!-- create the stylesheet.css -->
+ <redirect:write file="{$output.dir}/stylesheet.css">
+ <xsl:call-template name="stylesheet.css"/>
+ </redirect:write>
+
+ <!-- create the overview-packages.html at the root -->
+ <redirect:write file="{$output.dir}/overview-summary.html">
+ <xsl:apply-templates select="." mode="overview.packages"/>
+ </redirect:write>
+
+ <!-- create the all-packages.html at the root -->
+ <redirect:write file="{$output.dir}/overview-frame.html">
+ <xsl:apply-templates select="." mode="all.packages"/>
+ </redirect:write>
+
+ <!-- create the all-classes.html at the root -->
+ <redirect:write file="{$output.dir}/allclasses-frame.html">
+ <xsl:apply-templates select="." mode="all.classes"/>
+ </redirect:write>
+
+ <!-- create the all-tests.html at the root -->
+ <redirect:write file="{$output.dir}/all-tests.html">
+ <xsl:apply-templates select="." mode="all.tests"/>
+ </redirect:write>
+
+ <!-- create the alltests-fails.html at the root -->
+ <redirect:write file="{$output.dir}/alltests-fails.html">
+ <xsl:apply-templates select="." mode="all.tests">
+ <xsl:with-param name="type" select="'fails'"/>
+ </xsl:apply-templates>
+ </redirect:write>
+
+ <!-- create the alltests-errors.html at the root -->
+ <redirect:write file="{$output.dir}/alltests-errors.html">
+ <xsl:apply-templates select="." mode="all.tests">
+ <xsl:with-param name="type" select="'errors'"/>
+ </xsl:apply-templates>
+ </redirect:write>
+
+ <!-- create the alltests-skipped.html at the root -->
+ <redirect:write file="{$output.dir}/alltests-skipped.html">
+ <xsl:apply-templates select="." mode="all.tests">
+ <xsl:with-param name="type" select="'skipped'"/>
+ </xsl:apply-templates>
+ </redirect:write>
+
+ <!-- process all packages -->
+ <xsl:for-each select="./testsuite[not(./@package = preceding-sibling::testsuite/@package)]">
+ <xsl:call-template name="package">
+ <xsl:with-param name="name" select="@package"/>
+ </xsl:call-template>
+ </xsl:for-each>
+</xsl:template>
+
+
+<xsl:template name="package">
+ <xsl:param name="name"/>
+ <xsl:variable name="package.dir">
+ <xsl:if test="not($name = '')"><xsl:value-of select="translate($name,'.','/')"/></xsl:if>
+ <xsl:if test="$name = ''">.</xsl:if>
+ </xsl:variable>
+ <!--Processing package <xsl:value-of select="@name"/> in <xsl:value-of select="$output.dir"/> -->
+ <!-- create a classes-list.html in the package directory -->
+ <redirect:write file="{$output.dir}/{$package.dir}/package-frame.html">
+ <xsl:call-template name="classes.list">
+ <xsl:with-param name="name" select="$name"/>
+ </xsl:call-template>
+ </redirect:write>
+
+ <!-- create a package-summary.html in the package directory -->
+ <redirect:write file="{$output.dir}/{$package.dir}/package-summary.html">
+ <xsl:call-template name="package.summary">
+ <xsl:with-param name="name" select="$name"/>
+ </xsl:call-template>
+ </redirect:write>
+
+ <!-- for each class, creates a @name.html -->
+ <!-- @bug there will be a problem with inner classes having the same name, it will be overwritten -->
+ <xsl:for-each select="/testsuites/testsuite[@package = $name]">
+ <redirect:write file="{$output.dir}/{$package.dir}/{@id}_{@name}.html">
+ <xsl:apply-templates select="." mode="class.details"/>
+ </redirect:write>
+ <xsl:if test="string-length(./system-out)!=0">
+ <redirect:write file="{$output.dir}/{$package.dir}/{@id}_{@name}-out.html">
+ <html>
+ <head>
+ <title>Standard Output from <xsl:value-of select="@name"/></title>
+ </head>
+ <body>
+ <pre><xsl:value-of select="./system-out"/></pre>
+ </body>
+ </html>
+ </redirect:write>
+ </xsl:if>
+ <xsl:if test="string-length(./system-err)!=0">
+ <redirect:write file="{$output.dir}/{$package.dir}/{@id}_{@name}-err.html">
+ <html>
+ <head>
+ <title>Standard Error from <xsl:value-of select="@name"/></title>
+ </head>
+ <body>
+ <pre><xsl:value-of select="./system-err"/></pre>
+ </body>
+ </html>
+ </redirect:write>
+ </xsl:if>
+ <xsl:if test="@failures != 0">
+ <redirect:write file="{$output.dir}/{$package.dir}/{@id}_{@name}-fails.html">
+ <xsl:apply-templates select="." mode="class.details">
+ <xsl:with-param name="type" select="'fails'"/>
+ </xsl:apply-templates>
+ </redirect:write>
+ </xsl:if>
+ <xsl:if test="@errors != 0">
+ <redirect:write file="{$output.dir}/{$package.dir}/{@id}_{@name}-errors.html">
+ <xsl:apply-templates select="." mode="class.details">
+ <xsl:with-param name="type" select="'errors'"/>
+ </xsl:apply-templates>
+ </redirect:write>
+ </xsl:if>
+ <xsl:if test="@skipped != 0">
+ <redirect:write file="{$output.dir}/{$package.dir}/{@id}_{@name}-skipped.html">
+ <xsl:apply-templates select="." mode="class.details">
+ <xsl:with-param name="type" select="'skipped'"/>
+ </xsl:apply-templates>
+ </redirect:write>
+ </xsl:if>
+ </xsl:for-each>
+</xsl:template>
+
+<xsl:template name="index.html">
+<html>
+ <head>
+ <title><xsl:value-of select="$TITLE"/></title>
+ </head>
+ <frameset cols="20%,80%">
+ <frameset rows="30%,70%">
+ <frame src="overview-frame.html" name="packageListFrame"/>
+ <frame src="allclasses-frame.html" name="classListFrame"/>
+ </frameset>
+ <frame src="overview-summary.html" name="classFrame"/>
+ <noframes>
+ <h2>Frame Alert</h2>
+ <p>
+ This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client.
+ </p>
+ </noframes>
+ </frameset>
+</html>
+</xsl:template>
+
+<!-- this is the stylesheet css to use for nearly everything -->
+<xsl:template name="stylesheet.css">
+body {
+ font:normal 68% verdana,arial,helvetica;
+ color:#000000;
+}
+table tr td, table tr th {
+ font-size: 68%;
+}
+table.details tr th{
+ font-weight: bold;
+ text-align:left;
+ background:#a6caf0;
+}
+table.details tr td{
+ background:#eeeee0;
+}
+
+p {
+ line-height:1.5em;
+ margin-top:0.5em; margin-bottom:1.0em;
+}
+h1 {
+ margin: 0px 0px 5px; font: 165% verdana,arial,helvetica
+}
+h2 {
+ margin-top: 1em; margin-bottom: 0.5em; font: bold 125% verdana,arial,helvetica
+}
+h3 {
+ margin-bottom: 0.5em; font: bold 115% verdana,arial,helvetica
+}
+h4 {
+ margin-bottom: 0.5em; font: bold 100% verdana,arial,helvetica
+}
+h5 {
+ margin-bottom: 0.5em; font: bold 100% verdana,arial,helvetica
+}
+h6 {
+ margin-bottom: 0.5em; font: bold 100% verdana,arial,helvetica
+}
+.Error {
+ font-weight:bold; color:red;
+}
+.Failure {
+ font-weight:bold; color:purple;
+}
+.Properties {
+ text-align:right;
+}
+</xsl:template>
+
+<!-- Create list of all/failed/errored/skipped tests -->
+<xsl:template match="testsuites" mode="all.tests">
+ <xsl:param name="type" select="'all'"/>
+ <html>
+ <xsl:variable name="title">
+ <xsl:choose>
+ <xsl:when test="$type = 'fails'">
+ <xsl:text>All Failures</xsl:text>
+ </xsl:when>
+ <xsl:when test="$type = 'errors'">
+ <xsl:text>All Errors</xsl:text>
+ </xsl:when>
+ <xsl:when test="$type = 'skipped'">
+ <xsl:text>All Skipped</xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>All Tests</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <head>
+ <title>Unit Test Results: <xsl:value-of select="$title"/></title>
+ <xsl:call-template name="create.stylesheet.link">
+ <xsl:with-param name="package.name"/>
+ </xsl:call-template>
+ </head>
+ <body>
+ <xsl:attribute name="onload">open('allclasses-frame.html','classListFrame')</xsl:attribute>
+ <xsl:call-template name="pageHeader"/>
+ <h2><xsl:value-of select="$title"/></h2>
+
+ <table class="details" border="0" cellpadding="5" cellspacing="2" width="95%">
+ <xsl:call-template name="testcase.test.header">
+ <xsl:with-param name="show.class" select="'yes'"/>
+ </xsl:call-template>
+ <!--
+ test can even not be started at all (failure to load the class)
+ so report the error directly
+ -->
+ <xsl:if test="./error">
+ <tr class="Error">
+ <td colspan="4">
+ <xsl:apply-templates select="./error"/>
+ </td>
+ </tr>
+ </xsl:if>
+ <xsl:choose>
+ <xsl:when test="$type = 'fails'">
+ <xsl:apply-templates select=".//testcase[failure]" mode="print.test">
+ <xsl:with-param name="show.class" select="'yes'"/>
+ </xsl:apply-templates>
+ </xsl:when>
+ <xsl:when test="$type = 'errors'">
+ <xsl:apply-templates select=".//testcase[error]" mode="print.test">
+ <xsl:with-param name="show.class" select="'yes'"/>
+ </xsl:apply-templates>
+ </xsl:when>
+ <xsl:when test="$type = 'skipped'">
+ <xsl:apply-templates select=".//testcase[skipped]" mode="print.test">
+ <xsl:with-param name="show.class" select="'yes'"/>
+ </xsl:apply-templates>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:apply-templates select=".//testcase" mode="print.test">
+ <xsl:with-param name="show.class" select="'yes'"/>
+ </xsl:apply-templates>
+ </xsl:otherwise>
+ </xsl:choose>
+ </table>
+ </body>
+ </html>
+</xsl:template>
+
+
+<!-- ======================================================================
+ This page is created for every testsuite class.
+ It prints a summary of the testsuite and detailed information about
+ testcase methods.
+ ====================================================================== -->
+<xsl:template match="testsuite" mode="class.details">
+ <xsl:param name="type" select="'all'"/>
+ <xsl:variable name="package.name" select="@package"/>
+ <xsl:variable name="class.name"><xsl:if test="not($package.name = '')"><xsl:value-of select="$package.name"/>.</xsl:if><xsl:value-of select="@name"/></xsl:variable>
+ <html>
+ <head>
+ <title>Unit Test Results: <xsl:value-of select="$class.name"/></title>
+ <xsl:call-template name="create.stylesheet.link">
+ <xsl:with-param name="package.name" select="$package.name"/>
+ </xsl:call-template>
+ <script type="text/javascript" language="JavaScript">
+ var TestCases = new Array();
+ var cur;
+ <xsl:apply-templates select="properties"/>
+ </script>
+ <script type="text/javascript" language="JavaScript"><![CDATA[
+ function displayProperties (name) {
+ var win = window.open('','JUnitSystemProperties','scrollbars=1,resizable=1');
+ var doc = win.document;
+ doc.open();
+ doc.write("<html><head><title>Properties of " + name + "</title>");
+ doc.write("<style type=\"text/css\">");
+ doc.write("body {font:normal 68% verdana,arial,helvetica; color:#000000; }");
+ doc.write("table tr td, table tr th { font-size: 68%; }");
+ doc.write("table.properties { border-collapse:collapse; border-left:solid 1 #cccccc; border-top:solid 1 #cccccc; padding:5px; }");
+ doc.write("table.properties th { text-align:left; border-right:solid 1 #cccccc; border-bottom:solid 1 #cccccc; background-color:#eeeeee; }");
+ doc.write("table.properties td { font:normal; text-align:left; border-right:solid 1 #cccccc; border-bottom:solid 1 #cccccc; background-color:#fffffff; }");
+ doc.write("h3 { margin-bottom: 0.5em; font: bold 115% verdana,arial,helvetica }");
+ doc.write("</style>");
+ doc.write("</head><body>");
+ doc.write("<h3>Properties of " + name + "</h3>");
+ doc.write("<div align=\"right\"><a href=\"javascript:window.close();\">Close</a></div>");
+ doc.write("<table class='properties'>");
+ doc.write("<tr><th>Name</th><th>Value</th></tr>");
+ for (prop in TestCases[name]) {
+ doc.write("<tr><th>" + prop + "</th><td>" + TestCases[name][prop] + "</td></tr>");
+ }
+ doc.write("</table>");
+ doc.write("</body></html>");
+ doc.close();
+ win.focus();
+ }
+ ]]>
+ </script>
+ </head>
+ <body>
+ <xsl:call-template name="pageHeader"/>
+ <h3>Class <xsl:value-of select="$class.name"/></h3>
+
+
+ <table class="details" border="0" cellpadding="5" cellspacing="2" width="95%">
+ <xsl:call-template name="testsuite.test.header"/>
+ <xsl:apply-templates select="." mode="print.test"/>
+ </table>
+
+ <xsl:choose>
+ <xsl:when test="$type = 'fails'">
+ <h2>Failures</h2>
+ </xsl:when>
+ <xsl:when test="$type = 'errors'">
+ <h2>Errors</h2>
+ </xsl:when>
+ <xsl:when test="$type = 'skipped'">
+ <h2>Skipped</h2>
+ </xsl:when>
+ <xsl:otherwise>
+ <h2>Tests</h2>
+ </xsl:otherwise>
+ </xsl:choose>
+ <table class="details" border="0" cellpadding="5" cellspacing="2" width="95%">
+ <xsl:call-template name="testcase.test.header"/>
+ <!--
+ test can even not be started at all (failure to load the class)
+ so report the error directly
+ -->
+ <xsl:if test="./error">
+ <tr class="Error">
+ <td colspan="4"><xsl:apply-templates select="./error"/></td>
+ </tr>
+ </xsl:if>
+ <xsl:choose>
+ <xsl:when test="$type = 'fails'">
+ <xsl:apply-templates select="./testcase[failure]" mode="print.test"/>
+ </xsl:when>
+ <xsl:when test="$type = 'errors'">
+ <xsl:apply-templates select="./testcase[error]" mode="print.test"/>
+ </xsl:when>
+ <xsl:when test="$type = 'skipped'">
+ <xsl:apply-templates select="./testcase[skipped]" mode="print.test"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:apply-templates select="./testcase" mode="print.test"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </table>
+ <div class="Properties">
+ <a>
+ <xsl:attribute name="href">javascript:displayProperties('<xsl:value-of select="@package"/>.<xsl:value-of select="@name"/>');</xsl:attribute>
+ Properties &#187;
+ </a>
+ </div>
+ <xsl:if test="string-length(./system-out)!=0">
+ <div class="Properties">
+ <a>
+ <xsl:attribute name="href">./<xsl:value-of select="@id"/>_<xsl:value-of select="@name"/>-out.html</xsl:attribute>
+ System.out &#187;
+ </a>
+ </div>
+ </xsl:if>
+ <xsl:if test="string-length(./system-err)!=0">
+ <div class="Properties">
+ <a>
+ <xsl:attribute name="href">./<xsl:value-of select="@id"/>_<xsl:value-of select="@name"/>-err.html</xsl:attribute>
+ System.err &#187;
+ </a>
+ </div>
+ </xsl:if>
+ </body>
+ </html>
+</xsl:template>
+
+ <!--
+ Write properties into a JavaScript data structure.
+ This is based on the original idea by Erik Hatcher (ehatcher@apache.org)
+ -->
+ <xsl:template match="properties">
+ cur = TestCases['<xsl:value-of select="../@package"/>.<xsl:value-of select="../@name"/>'] = new Array();
+ <xsl:for-each select="property">
+ <xsl:sort select="@name"/>
+ cur['<xsl:value-of select="@name"/>'] = '<xsl:call-template name="JS-escape"><xsl:with-param name="string" select="@value"/></xsl:call-template>';
+ </xsl:for-each>
+ </xsl:template>
+
+
+<!-- ======================================================================
+ This page is created for every package.
+ It prints the name of all classes that belongs to this package.
+ @param name the package name to print classes.
+ ====================================================================== -->
+<!-- list of classes in a package -->
+<xsl:template name="classes.list">
+ <xsl:param name="name"/>
+ <html>
+ <head>
+ <title>Unit Test Classes: <xsl:value-of select="$name"/></title>
+ <xsl:call-template name="create.stylesheet.link">
+ <xsl:with-param name="package.name" select="$name"/>
+ </xsl:call-template>
+ </head>
+ <body>
+ <table width="100%">
+ <tr>
+ <td nowrap="nowrap">
+ <h2><a href="package-summary.html" target="classFrame">
+ <xsl:value-of select="$name"/>
+ <xsl:if test="$name = ''">&lt;none&gt;</xsl:if>
+ </a></h2>
+ </td>
+ </tr>
+ </table>
+
+ <h2>Classes</h2>
+ <table width="100%">
+ <xsl:for-each select="/testsuites/testsuite[./@package = $name]">
+ <xsl:sort select="@name"/>
+ <tr>
+ <td nowrap="nowrap">
+ <a href="{@id}_{@name}.html" target="classFrame"><xsl:value-of select="@name"/></a>
+ </td>
+ </tr>
+ </xsl:for-each>
+ </table>
+ </body>
+ </html>
+</xsl:template>
+
+
+<!--
+ Creates an all-classes.html file that contains a link to all package-summary.html
+ on each class.
+-->
+<xsl:template match="testsuites" mode="all.classes">
+ <html>
+ <head>
+ <title>All Unit Test Classes</title>
+ <xsl:call-template name="create.stylesheet.link">
+ <xsl:with-param name="package.name"/>
+ </xsl:call-template>
+ </head>
+ <body>
+ <h2>Classes</h2>
+ <table width="100%">
+ <xsl:apply-templates select="testsuite" mode="all.classes">
+ <xsl:sort select="@name"/>
+ </xsl:apply-templates>
+ </table>
+ </body>
+ </html>
+</xsl:template>
+
+<xsl:template match="testsuite" mode="all.classes">
+ <xsl:variable name="package.name" select="@package"/>
+ <tr>
+ <td nowrap="nowrap">
+ <a target="classFrame">
+ <xsl:attribute name="href">
+ <xsl:if test="not($package.name='')">
+ <xsl:value-of select="translate($package.name,'.','/')"/><xsl:text>/</xsl:text>
+ </xsl:if><xsl:value-of select="@id"/>_<xsl:value-of select="@name"/><xsl:text>.html</xsl:text>
+ </xsl:attribute>
+ <xsl:value-of select="@name"/>
+ </a>
+ </td>
+ </tr>
+</xsl:template>
+
+
+<!--
+ Creates an html file that contains a link to all package-summary.html files on
+ each package existing on testsuites.
+ @bug there will be a problem here, I don't know yet how to handle unnamed package :(
+-->
+<xsl:template match="testsuites" mode="all.packages">
+ <html>
+ <head>
+ <title>All Unit Test Packages</title>
+ <xsl:call-template name="create.stylesheet.link">
+ <xsl:with-param name="package.name"/>
+ </xsl:call-template>
+ </head>
+ <body>
+ <h2><a href="overview-summary.html" target="classFrame">Home</a></h2>
+ <h2>Packages</h2>
+ <table width="100%">
+ <xsl:apply-templates select="testsuite[not(./@package = preceding-sibling::testsuite/@package)]" mode="all.packages">
+ <xsl:sort select="@package"/>
+ </xsl:apply-templates>
+ </table>
+ </body>
+ </html>
+</xsl:template>
+
+<xsl:template match="testsuite" mode="all.packages">
+ <tr>
+ <td nowrap="nowrap">
+ <a href="./{translate(@package,'.','/')}/package-summary.html" target="classFrame">
+ <xsl:value-of select="@package"/>
+ <xsl:if test="@package = ''">&lt;none&gt;</xsl:if>
+ </a>
+ </td>
+ </tr>
+</xsl:template>
+
+
+<xsl:template match="testsuites" mode="overview.packages">
+ <html>
+ <head>
+ <title>Unit Test Results: Summary</title>
+ <xsl:call-template name="create.stylesheet.link">
+ <xsl:with-param name="package.name"/>
+ </xsl:call-template>
+ </head>
+ <body>
+ <xsl:attribute name="onload">open('allclasses-frame.html','classListFrame')</xsl:attribute>
+ <xsl:call-template name="pageHeader"/>
+ <h2>Summary</h2>
+ <xsl:variable name="testCount" select="sum(testsuite/@tests)"/>
+ <xsl:variable name="errorCount" select="sum(testsuite/@errors)"/>
+ <xsl:variable name="failureCount" select="sum(testsuite/@failures)"/>
+ <xsl:variable name="skippedCount" select="sum(testsuite/@skipped)" />
+ <xsl:variable name="timeCount" select="sum(testsuite/@time)"/>
+ <xsl:variable name="successRate" select="($testCount - $failureCount - $errorCount) div $testCount"/>
+ <table class="details" border="0" cellpadding="5" cellspacing="2" width="95%">
+ <tr valign="top">
+ <th>Tests</th>
+ <th>Failures</th>
+ <th>Errors</th>
+ <th>Skipped</th>
+ <th>Success rate</th>
+ <th>Time</th>
+ </tr>
+ <tr valign="top">
+ <xsl:attribute name="class">
+ <xsl:choose>
+ <xsl:when test="$errorCount &gt; 0">Error</xsl:when>
+ <xsl:when test="$failureCount &gt; 0">Failure</xsl:when>
+ <xsl:otherwise>Pass</xsl:otherwise>
+ </xsl:choose>
+ </xsl:attribute>
+ <td><a title="Display all tests" href="all-tests.html"><xsl:value-of select="$testCount"/></a></td>
+ <td><a title="Display all failures" href="alltests-fails.html"><xsl:value-of select="$failureCount"/></a></td>
+ <td><a title="Display all errors" href="alltests-errors.html"><xsl:value-of select="$errorCount"/></a></td>
+ <td><a title="Display all skipped test" href="alltests-skipped.html"><xsl:value-of select="$skippedCount" /></a></td>
+ <td>
+ <xsl:call-template name="display-percent">
+ <xsl:with-param name="value" select="$successRate"/>
+ </xsl:call-template>
+ </td>
+ <td>
+ <xsl:call-template name="display-time">
+ <xsl:with-param name="value" select="$timeCount"/>
+ </xsl:call-template>
+ </td>
+ </tr>
+ </table>
+ <table border="0" width="95%">
+ <tr>
+ <td style="text-align: justify;">
+ Note: <em>failures</em> are anticipated and checked for with assertions while <em>errors</em> are unanticipated.
+ </td>
+ </tr>
+ </table>
+
+ <h2>Packages</h2>
+ <table class="details" border="0" cellpadding="5" cellspacing="2" width="95%">
+ <xsl:call-template name="testsuite.test.header"/>
+ <xsl:for-each select="testsuite[not(./@package = preceding-sibling::testsuite/@package)]">
+ <xsl:sort select="@package" order="ascending"/>
+ <!-- get the node set containing all testsuites that have the same package -->
+ <xsl:variable name="insamepackage" select="/testsuites/testsuite[./@package = current()/@package]"/>
+ <tr valign="top">
+ <!-- display a failure if there is any failure/error in the package -->
+ <xsl:attribute name="class">
+ <xsl:choose>
+ <xsl:when test="sum($insamepackage/@errors) &gt; 0">Error</xsl:when>
+ <xsl:when test="sum($insamepackage/@failures) &gt; 0">Failure</xsl:when>
+ <xsl:otherwise>Pass</xsl:otherwise>
+ </xsl:choose>
+ </xsl:attribute>
+ <td><a href="./{translate(@package,'.','/')}/package-summary.html">
+ <xsl:value-of select="@package"/>
+ <xsl:if test="@package = ''">&lt;none&gt;</xsl:if>
+ </a></td>
+ <td><xsl:value-of select="sum($insamepackage/@tests)"/></td>
+ <td><xsl:value-of select="sum($insamepackage/@errors)"/></td>
+ <td><xsl:value-of select="sum($insamepackage/@failures)"/></td>
+ <td><xsl:value-of select="sum($insamepackage/@skipped)" /></td>
+ <td>
+ <xsl:call-template name="display-time">
+ <xsl:with-param name="value" select="sum($insamepackage/@time)"/>
+ </xsl:call-template>
+ </td>
+ <td><xsl:value-of select="$insamepackage/@timestamp"/></td>
+ <td><xsl:value-of select="$insamepackage/@hostname"/></td>
+ </tr>
+ </xsl:for-each>
+ </table>
+ </body>
+ </html>
+</xsl:template>
+
+
+<xsl:template name="package.summary">
+ <xsl:param name="name"/>
+ <html>
+ <head>
+ <xsl:call-template name="create.stylesheet.link">
+ <xsl:with-param name="package.name" select="$name"/>
+ </xsl:call-template>
+ </head>
+ <body>
+ <xsl:attribute name="onload">open('package-frame.html','classListFrame')</xsl:attribute>
+ <xsl:call-template name="pageHeader"/>
+ <h3>Package <xsl:value-of select="$name"/></h3>
+
+ <!--table border="0" cellpadding="5" cellspacing="2" width="95%">
+ <xsl:call-template name="class.metrics.header"/>
+ <xsl:apply-templates select="." mode="print.metrics"/>
+ </table-->
+
+ <xsl:variable name="insamepackage" select="/testsuites/testsuite[./@package = $name]"/>
+ <xsl:if test="count($insamepackage) &gt; 0">
+ <h2>Classes</h2>
+ <p>
+ <table class="details" border="0" cellpadding="5" cellspacing="2" width="95%">
+ <xsl:call-template name="testsuite.test.header"/>
+ <xsl:apply-templates select="$insamepackage" mode="print.test">
+ <xsl:sort select="@name"/>
+ </xsl:apply-templates>
+ </table>
+ </p>
+ </xsl:if>
+ </body>
+ </html>
+</xsl:template>
+
+
+<!--
+ transform string like a.b.c to ../../../
+ @param path the path to transform into a descending directory path
+-->
+<xsl:template name="path">
+ <xsl:param name="path"/>
+ <xsl:if test="contains($path,'.')">
+ <xsl:text>../</xsl:text>
+ <xsl:call-template name="path">
+ <xsl:with-param name="path"><xsl:value-of select="substring-after($path,'.')"/></xsl:with-param>
+ </xsl:call-template>
+ </xsl:if>
+ <xsl:if test="not(contains($path,'.')) and not($path = '')">
+ <xsl:text>../</xsl:text>
+ </xsl:if>
+</xsl:template>
+
+
+<!-- create the link to the stylesheet based on the package name -->
+<xsl:template name="create.stylesheet.link">
+ <xsl:param name="package.name"/>
+ <link rel="stylesheet" type="text/css" title="Style"><xsl:attribute name="href"><xsl:if test="not($package.name = 'unnamed package')"><xsl:call-template name="path"><xsl:with-param name="path" select="$package.name"/></xsl:call-template></xsl:if>stylesheet.css</xsl:attribute></link>
+</xsl:template>
+
+
+<!-- Page HEADER -->
+<xsl:template name="pageHeader">
+ <h1><xsl:value-of select="$TITLE"/></h1>
+ <table width="100%">
+ <tr>
+ <td align="left"></td>
+ <td align="right">Designed for use with <a href="http://www.junit.org/">JUnit</a> and <a href="http://ant.apache.org/">Ant</a>.</td>
+ </tr>
+ </table>
+ <hr size="1"/>
+</xsl:template>
+
+<!-- class header -->
+<xsl:template name="testsuite.test.header">
+ <tr valign="top">
+ <th width="80%">Name</th>
+ <th>Tests</th>
+ <th>Errors</th>
+ <th>Failures</th>
+ <th>Skipped</th>
+ <th nowrap="nowrap">Time(s)</th>
+ <th nowrap="nowrap">Time Stamp</th>
+ <th>Host</th>
+ </tr>
+</xsl:template>
+
+<!-- method header -->
+<xsl:template name="testcase.test.header">
+ <xsl:param name="show.class" select="''"/>
+ <tr valign="top">
+ <xsl:if test="boolean($show.class)">
+ <th>Class</th>
+ </xsl:if>
+ <th>Name</th>
+ <th>Status</th>
+ <th width="80%">Type</th>
+ <th nowrap="nowrap">Time(s)</th>
+ </tr>
+</xsl:template>
+
+
+<!-- class information -->
+<xsl:template match="testsuite" mode="print.test">
+ <tr valign="top">
+ <xsl:attribute name="class">
+ <xsl:choose>
+ <xsl:when test="@errors[.&gt; 0]">Error</xsl:when>
+ <xsl:when test="@failures[.&gt; 0]">Failure</xsl:when>
+ <xsl:otherwise>Pass</xsl:otherwise>
+ </xsl:choose>
+ </xsl:attribute>
+ <td><a title="Display all tests" href="{@id}_{@name}.html"><xsl:value-of select="@name"/></a></td>
+ <td><a title="Display all tests" href="{@id}_{@name}.html"><xsl:apply-templates select="@tests"/></a></td>
+ <td>
+ <xsl:choose>
+ <xsl:when test="@errors != 0">
+ <a title="Display only errors" href="{@id}_{@name}-errors.html"><xsl:apply-templates select="@errors"/></a>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:apply-templates select="@errors"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </td>
+ <td>
+ <xsl:choose>
+ <xsl:when test="@failures != 0">
+ <a title="Display only failures" href="{@id}_{@name}-fails.html"><xsl:apply-templates select="@failures"/></a>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:apply-templates select="@failures"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </td>
+ <td>
+ <xsl:choose>
+ <xsl:when test="@skipped != 0">
+ <a title="Display only skipped tests" href="{@id}_{@name}-skipped.html"><xsl:apply-templates select="@skipped"/></a>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:apply-templates select="@skipped"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </td>
+ <td><xsl:call-template name="display-time">
+ <xsl:with-param name="value" select="@time"/>
+ </xsl:call-template>
+ </td>
+ <td><xsl:apply-templates select="@timestamp"/></td>
+ <td><xsl:apply-templates select="@hostname"/></td>
+ </tr>
+</xsl:template>
+
+<xsl:template match="testcase" mode="print.test">
+ <xsl:param name="show.class" select="''"/>
+ <tr valign="top">
+ <xsl:attribute name="class">
+ <xsl:choose>
+ <xsl:when test="error">Error</xsl:when>
+ <xsl:when test="failure">Failure</xsl:when>
+ <xsl:otherwise>TableRowColor</xsl:otherwise>
+ </xsl:choose>
+ </xsl:attribute>
+ <xsl:variable name="class.href">
+ <xsl:value-of select="concat(translate(../@package,'.','/'), '/', ../@id, '_', ../@name, '.html')"/>
+ </xsl:variable>
+ <xsl:if test="boolean($show.class)">
+ <td><a href="{$class.href}"><xsl:value-of select="../@name"/></a></td>
+ </xsl:if>
+ <td>
+ <a name="{@name}"/>
+ <xsl:choose>
+ <xsl:when test="boolean($show.class)">
+ <a href="{concat($class.href, '#', @name)}"><xsl:value-of select="@name"/></a>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="@name"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </td>
+ <xsl:choose>
+ <xsl:when test="failure">
+ <td>Failure</td>
+ <td><xsl:apply-templates select="failure"/></td>
+ </xsl:when>
+ <xsl:when test="error">
+ <td>Error</td>
+ <td><xsl:apply-templates select="error"/></td>
+ </xsl:when>
+ <xsl:when test="skipped">
+ <td>Skipped</td>
+ <td><xsl:apply-templates select="skipped"/></td>
+ </xsl:when>
+ <xsl:otherwise>
+ <td>Success</td>
+ <td></td>
+ </xsl:otherwise>
+ </xsl:choose>
+ <td>
+ <xsl:call-template name="display-time">
+ <xsl:with-param name="value" select="@time"/>
+ </xsl:call-template>
+ </td>
+ </tr>
+</xsl:template>
+
+
+<!-- Note : the below template skipped, error and failure are the same style
+ so just call the same style store in the toolkit template -->
+<xsl:template match="failure">
+ <xsl:call-template name="display-failures"/>
+</xsl:template>
+
+<xsl:template match="error">
+ <xsl:call-template name="display-failures"/>
+</xsl:template>
+
+<xsl:template match="skipped">
+ <xsl:call-template name="display-failures"/>
+</xsl:template>
+
+<!-- Style for the error and failure in the testcase template -->
+<xsl:template name="display-failures">
+ <xsl:choose>
+ <xsl:when test="not(@message)">N/A</xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="@message"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ <!-- display the stacktrace -->
+ <br/><br/>
+ <code>
+ <xsl:call-template name="br-replace">
+ <xsl:with-param name="word" select="."/>
+ </xsl:call-template>
+ </code>
+ <!-- the latter is better but might be problematic for non-21" monitors... -->
+ <!--pre><xsl:value-of select="."/></pre-->
+</xsl:template>
+
+<xsl:template name="JS-escape">
+ <xsl:param name="string"/>
+ <xsl:param name="tmp1" select="string:replaceAll(string:new(string($string)),'\\','\\\\')"/>
+ <xsl:param name="tmp2" select="string:replaceAll(string:new(string($tmp1)),&quot;'&quot;,&quot;\\&apos;&quot;)"/>
+ <xsl:param name="tmp3" select="string:replaceAll(string:new(string($tmp2)),&quot;&#10;&quot;,'\\n')"/>
+ <xsl:param name="tmp4" select="string:replaceAll(string:new(string($tmp3)),&quot;&#13;&quot;,'\\r')"/>
+ <xsl:value-of select="$tmp4"/>
+</xsl:template>
+
+
+<!--
+ template that will convert a carriage return into a br tag
+ @param word the text from which to convert CR to BR tag
+-->
+<xsl:template name="br-replace">
+ <xsl:param name="word"/>
+ <xsl:param name="splitlimit">32</xsl:param>
+ <xsl:variable name="secondhalflen" select="(string-length($word)+(string-length($word) mod 2)) div 2"/>
+ <xsl:variable name="secondhalfword" select="substring($word, $secondhalflen)"/>
+ <!-- When word is very big, a recursive replace is very heap/stack expensive, so subdivide on line break after middle of string -->
+ <xsl:choose>
+ <xsl:when test="(string-length($word) > $splitlimit) and (contains($secondhalfword, '&#xa;'))">
+ <xsl:variable name="secondhalfend" select="substring-after($secondhalfword, '&#xa;')"/>
+ <xsl:variable name="firsthalflen" select="string-length($word) - $secondhalflen"/>
+ <xsl:variable name="firsthalfword" select="substring($word, 1, $firsthalflen)"/>
+ <xsl:variable name="firsthalfend" select="substring-before($secondhalfword, '&#xa;')"/>
+ <xsl:call-template name="br-replace">
+ <xsl:with-param name="word" select="concat($firsthalfword,$firsthalfend)"/>
+ </xsl:call-template>
+ <br/>
+ <xsl:call-template name="br-replace">
+ <xsl:with-param name="word" select="$secondhalfend"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:when test="contains($word, '&#xa;')">
+ <xsl:value-of select="substring-before($word, '&#xa;')"/>
+ <br/>
+ <xsl:call-template name="br-replace">
+ <xsl:with-param name="word" select="substring-after($word, '&#xa;')"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$word"/>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+<xsl:template name="display-time">
+ <xsl:param name="value"/>
+ <xsl:value-of select="format-number($value,'0.000')"/>
+</xsl:template>
+
+<xsl:template name="display-percent">
+ <xsl:param name="value"/>
+ <xsl:value-of select="format-number($value,'0.00%')"/>
+</xsl:template>
+</xsl:stylesheet>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/junit-noframes.xsl b/framework/src/ant/apache-ant-1.9.6/src/etc/junit-noframes.xsl
new file mode 100644
index 00000000..bd7002a9
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/junit-noframes.xsl
@@ -0,0 +1,513 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
+ xmlns:lxslt="http://xml.apache.org/xslt"
+ xmlns:string="xalan://java.lang.String">
+<xsl:output method="html" indent="yes" encoding="UTF-8"
+ doctype-public="-//W3C//DTD HTML 4.01 Transitional//EN" />
+<xsl:decimal-format decimal-separator="." grouping-separator="," />
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<xsl:param name="TITLE">Unit Test Results.</xsl:param>
+
+<!--
+
+ Sample stylesheet to be used with Ant JUnitReport output.
+
+ It creates a non-framed report that can be useful to send via
+ e-mail or such.
+
+-->
+<xsl:template match="testsuites">
+ <html>
+ <head>
+ <title><xsl:value-of select="$TITLE"/></title>
+ <style type="text/css">
+ body {
+ font:normal 68% verdana,arial,helvetica;
+ color:#000000;
+ }
+ table tr td, table tr th {
+ font-size: 68%;
+ }
+ table.details tr th{
+ font-weight: bold;
+ text-align:left;
+ background:#a6caf0;
+ }
+ table.details tr td{
+ background:#eeeee0;
+ }
+
+ p {
+ line-height:1.5em;
+ margin-top:0.5em; margin-bottom:1.0em;
+ }
+ h1 {
+ margin: 0px 0px 5px; font: 165% verdana,arial,helvetica
+ }
+ h2 {
+ margin-top: 1em; margin-bottom: 0.5em; font: bold 125% verdana,arial,helvetica
+ }
+ h3 {
+ margin-bottom: 0.5em; font: bold 115% verdana,arial,helvetica
+ }
+ h4 {
+ margin-bottom: 0.5em; font: bold 100% verdana,arial,helvetica
+ }
+ h5 {
+ margin-bottom: 0.5em; font: bold 100% verdana,arial,helvetica
+ }
+ h6 {
+ margin-bottom: 0.5em; font: bold 100% verdana,arial,helvetica
+ }
+ .Error {
+ font-weight:bold; color:red;
+ }
+ .Failure {
+ font-weight:bold; color:purple;
+ }
+ .Properties {
+ text-align:right;
+ }
+ </style>
+ <script type="text/javascript" language="JavaScript">
+ var TestCases = new Array();
+ var cur;
+ <xsl:for-each select="./testsuite">
+ <xsl:apply-templates select="properties"/>
+ </xsl:for-each>
+
+ </script>
+ <script type="text/javascript" language="JavaScript"><![CDATA[
+ function displayProperties (name) {
+ var win = window.open('','JUnitSystemProperties','scrollbars=1,resizable=1');
+ var doc = win.document;
+ doc.open();
+ doc.write("<html><head><title>Properties of " + name + "</title>");
+ doc.write("<style>")
+ doc.write("body {font:normal 68% verdana,arial,helvetica; color:#000000; }");
+ doc.write("table tr td, table tr th { font-size: 68%; }");
+ doc.write("table.properties { border-collapse:collapse; border-left:solid 1 #cccccc; border-top:solid 1 #cccccc; padding:5px; }");
+ doc.write("table.properties th { text-align:left; border-right:solid 1 #cccccc; border-bottom:solid 1 #cccccc; background-color:#eeeeee; }");
+ doc.write("table.properties td { font:normal; text-align:left; border-right:solid 1 #cccccc; border-bottom:solid 1 #cccccc; background-color:#fffffff; }");
+ doc.write("h3 { margin-bottom: 0.5em; font: bold 115% verdana,arial,helvetica }");
+ doc.write("</style>");
+ doc.write("</head><body>");
+ doc.write("<h3>Properties of " + name + "</h3>");
+ doc.write("<div align=\"right\"><a href=\"javascript:window.close();\">Close</a></div>");
+ doc.write("<table class='properties'>");
+ doc.write("<tr><th>Name</th><th>Value</th></tr>");
+ for (prop in TestCases[name]) {
+ doc.write("<tr><th>" + prop + "</th><td>" + TestCases[name][prop] + "</td></tr>");
+ }
+ doc.write("</table>");
+ doc.write("</body></html>");
+ doc.close();
+ win.focus();
+ }
+ ]]>
+ </script>
+ </head>
+ <body>
+ <a name="top"></a>
+ <xsl:call-template name="pageHeader"/>
+
+ <!-- Summary part -->
+ <xsl:call-template name="summary"/>
+ <hr size="1" width="95%" align="left"/>
+
+ <!-- Package List part -->
+ <xsl:call-template name="packagelist"/>
+ <hr size="1" width="95%" align="left"/>
+
+ <!-- For each package create its part -->
+ <xsl:call-template name="packages"/>
+ <hr size="1" width="95%" align="left"/>
+
+ <!-- For each class create the part -->
+ <xsl:call-template name="classes"/>
+
+ </body>
+ </html>
+</xsl:template>
+
+
+
+ <!-- ================================================================== -->
+ <!-- Write a list of all packages with an hyperlink to the anchor of -->
+ <!-- of the package name. -->
+ <!-- ================================================================== -->
+ <xsl:template name="packagelist">
+ <h2>Packages</h2>
+ Note: package statistics are not computed recursively, they only sum up all of its testsuites numbers.
+ <table class="details" border="0" cellpadding="5" cellspacing="2" width="95%">
+ <xsl:call-template name="testsuite.test.header"/>
+ <!-- list all packages recursively -->
+ <xsl:for-each select="./testsuite[not(./@package = preceding-sibling::testsuite/@package)]">
+ <xsl:sort select="@package"/>
+ <xsl:variable name="testsuites-in-package" select="/testsuites/testsuite[./@package = current()/@package]"/>
+ <xsl:variable name="testCount" select="sum($testsuites-in-package/@tests)"/>
+ <xsl:variable name="errorCount" select="sum($testsuites-in-package/@errors)"/>
+ <xsl:variable name="failureCount" select="sum($testsuites-in-package/@failures)"/>
+ <xsl:variable name="skippedCount" select="sum($testsuites-in-package/@skipped)" />
+ <xsl:variable name="timeCount" select="sum($testsuites-in-package/@time)"/>
+
+ <!-- write a summary for the package -->
+ <tr valign="top">
+ <!-- set a nice color depending if there is an error/failure -->
+ <xsl:attribute name="class">
+ <xsl:choose>
+ <xsl:when test="$failureCount &gt; 0">Failure</xsl:when>
+ <xsl:when test="$errorCount &gt; 0">Error</xsl:when>
+ </xsl:choose>
+ </xsl:attribute>
+ <td><a href="#{@package}"><xsl:value-of select="@package"/></a></td>
+ <td><xsl:value-of select="$testCount"/></td>
+ <td><xsl:value-of select="$errorCount"/></td>
+ <td><xsl:value-of select="$failureCount"/></td>
+ <td><xsl:value-of select="$skippedCount" /></td>
+ <td>
+ <xsl:call-template name="display-time">
+ <xsl:with-param name="value" select="$timeCount"/>
+ </xsl:call-template>
+ </td>
+ <td><xsl:value-of select="$testsuites-in-package/@timestamp"/></td>
+ <td><xsl:value-of select="$testsuites-in-package/@hostname"/></td>
+ </tr>
+ </xsl:for-each>
+ </table>
+ </xsl:template>
+
+
+ <!-- ================================================================== -->
+ <!-- Write a package level report -->
+ <!-- It creates a table with values from the document: -->
+ <!-- Name | Tests | Errors | Failures | Time -->
+ <!-- ================================================================== -->
+ <xsl:template name="packages">
+ <!-- create an anchor to this package name -->
+ <xsl:for-each select="/testsuites/testsuite[not(./@package = preceding-sibling::testsuite/@package)]">
+ <xsl:sort select="@package"/>
+ <a name="{@package}"></a>
+ <h3>Package <xsl:value-of select="@package"/></h3>
+
+ <table class="details" border="0" cellpadding="5" cellspacing="2" width="95%">
+ <xsl:call-template name="testsuite.test.header"/>
+
+ <!-- match the testsuites of this package -->
+ <xsl:apply-templates select="/testsuites/testsuite[./@package = current()/@package]" mode="print.test"/>
+ </table>
+ <a href="#top">Back to top</a>
+ <p/>
+ <p/>
+ </xsl:for-each>
+ </xsl:template>
+
+ <xsl:template name="classes">
+ <xsl:for-each select="testsuite">
+ <xsl:sort select="@name"/>
+ <!-- create an anchor to this class name -->
+ <a name="{@name}"></a>
+ <h3>TestCase <xsl:value-of select="@name"/></h3>
+
+ <table class="details" border="0" cellpadding="5" cellspacing="2" width="95%">
+ <xsl:call-template name="testcase.test.header"/>
+ <!--
+ test can even not be started at all (failure to load the class)
+ so report the error directly
+ -->
+ <xsl:if test="./error">
+ <tr class="Error">
+ <td colspan="4"><xsl:apply-templates select="./error"/></td>
+ </tr>
+ </xsl:if>
+ <xsl:apply-templates select="./testcase" mode="print.test"/>
+ </table>
+ <div class="Properties">
+ <a>
+ <xsl:attribute name="href">javascript:displayProperties('<xsl:value-of select="@package"/>.<xsl:value-of select="@name"/>');</xsl:attribute>
+ Properties &#187;
+ </a>
+ </div>
+ <p/>
+
+ <a href="#top">Back to top</a>
+ </xsl:for-each>
+ </xsl:template>
+
+ <xsl:template name="summary">
+ <h2>Summary</h2>
+ <xsl:variable name="testCount" select="sum(testsuite/@tests)"/>
+ <xsl:variable name="errorCount" select="sum(testsuite/@errors)"/>
+ <xsl:variable name="failureCount" select="sum(testsuite/@failures)"/>
+ <xsl:variable name="skippedCount" select="sum(testsuite/@skipped)" />
+ <xsl:variable name="timeCount" select="sum(testsuite/@time)"/>
+ <xsl:variable name="successRate" select="($testCount - $failureCount - $errorCount) div $testCount"/>
+ <table class="details" border="0" cellpadding="5" cellspacing="2" width="95%">
+ <tr valign="top">
+ <th>Tests</th>
+ <th>Failures</th>
+ <th>Errors</th>
+ <th>Skipped</th>
+ <th>Success rate</th>
+ <th>Time</th>
+ </tr>
+ <tr valign="top">
+ <xsl:attribute name="class">
+ <xsl:choose>
+ <xsl:when test="$failureCount &gt; 0">Failure</xsl:when>
+ <xsl:when test="$errorCount &gt; 0">Error</xsl:when>
+ </xsl:choose>
+ </xsl:attribute>
+ <td><xsl:value-of select="$testCount"/></td>
+ <td><xsl:value-of select="$failureCount"/></td>
+ <td><xsl:value-of select="$errorCount"/></td>
+ <td><xsl:value-of select="$skippedCount" /></td>
+ <td>
+ <xsl:call-template name="display-percent">
+ <xsl:with-param name="value" select="$successRate"/>
+ </xsl:call-template>
+ </td>
+ <td>
+ <xsl:call-template name="display-time">
+ <xsl:with-param name="value" select="$timeCount"/>
+ </xsl:call-template>
+ </td>
+
+ </tr>
+ </table>
+ <table border="0" width="95%">
+ <tr>
+ <td style="text-align: justify;">
+ Note: <i>failures</i> are anticipated and checked for with assertions while <i>errors</i> are unanticipated.
+ </td>
+ </tr>
+ </table>
+ </xsl:template>
+
+ <!--
+ Write properties into a JavaScript data structure.
+ This is based on the original idea by Erik Hatcher (ehatcher@apache.org)
+ -->
+ <xsl:template match="properties">
+ cur = TestCases['<xsl:value-of select="../@package"/>.<xsl:value-of select="../@name"/>'] = new Array();
+ <xsl:for-each select="property">
+ <xsl:sort select="@name"/>
+ cur['<xsl:value-of select="@name"/>'] = '<xsl:call-template name="JS-escape"><xsl:with-param name="string" select="@value"/></xsl:call-template>';
+ </xsl:for-each>
+ </xsl:template>
+
+<!-- Page HEADER -->
+<xsl:template name="pageHeader">
+ <h1><xsl:value-of select="$TITLE"/></h1>
+ <table width="100%">
+ <tr>
+ <td align="left"></td>
+ <td align="right">Designed for use with <a href='http://www.junit.org'>JUnit</a> and <a href='http://ant.apache.org/ant'>Ant</a>.</td>
+ </tr>
+ </table>
+ <hr size="1"/>
+</xsl:template>
+
+<xsl:template match="testsuite" mode="header">
+ <tr valign="top">
+ <th width="80%">Name</th>
+ <th>Tests</th>
+ <th>Errors</th>
+ <th>Failures</th>
+ <th>Skipped</th>
+ <th nowrap="nowrap">Time(s)</th>
+ </tr>
+</xsl:template>
+
+<!-- class header -->
+<xsl:template name="testsuite.test.header">
+ <tr valign="top">
+ <th width="80%">Name</th>
+ <th>Tests</th>
+ <th>Errors</th>
+ <th>Failures</th>
+ <th>Skipped</th>
+ <th nowrap="nowrap">Time(s)</th>
+ <th nowrap="nowrap">Time Stamp</th>
+ <th>Host</th>
+ </tr>
+</xsl:template>
+
+<!-- method header -->
+<xsl:template name="testcase.test.header">
+ <tr valign="top">
+ <th>Name</th>
+ <th>Status</th>
+ <th width="80%">Type</th>
+ <th nowrap="nowrap">Time(s)</th>
+ </tr>
+</xsl:template>
+
+
+<!-- class information -->
+<xsl:template match="testsuite" mode="print.test">
+ <tr valign="top">
+ <!-- set a nice color depending if there is an error/failure -->
+ <xsl:attribute name="class">
+ <xsl:choose>
+ <xsl:when test="@failures[.&gt; 0]">Failure</xsl:when>
+ <xsl:when test="@errors[.&gt; 0]">Error</xsl:when>
+ </xsl:choose>
+ </xsl:attribute>
+
+ <!-- print testsuite information -->
+ <td><a href="#{@name}"><xsl:value-of select="@name"/></a></td>
+ <td><xsl:value-of select="@tests"/></td>
+ <td><xsl:value-of select="@errors"/></td>
+ <td><xsl:value-of select="@failures"/></td>
+ <td><xsl:value-of select="@skipped" /></td>
+ <td>
+ <xsl:call-template name="display-time">
+ <xsl:with-param name="value" select="@time"/>
+ </xsl:call-template>
+ </td>
+ <td><xsl:apply-templates select="@timestamp"/></td>
+ <td><xsl:apply-templates select="@hostname"/></td>
+ </tr>
+</xsl:template>
+
+<xsl:template match="testcase" mode="print.test">
+ <tr valign="top">
+ <xsl:attribute name="class">
+ <xsl:choose>
+ <xsl:when test="failure | error">Error</xsl:when>
+ </xsl:choose>
+ </xsl:attribute>
+ <td><xsl:value-of select="@name"/></td>
+ <xsl:choose>
+ <xsl:when test="failure">
+ <td>Failure</td>
+ <td><xsl:apply-templates select="failure"/></td>
+ </xsl:when>
+ <xsl:when test="error">
+ <td>Error</td>
+ <td><xsl:apply-templates select="error"/></td>
+ </xsl:when>
+ <xsl:when test="skipped">
+ <td>Skipped</td>
+ <td><xsl:apply-templates select="skipped"/></td>
+ </xsl:when>
+ <xsl:otherwise>
+ <td>Success</td>
+ <td></td>
+ </xsl:otherwise>
+ </xsl:choose>
+ <td>
+ <xsl:call-template name="display-time">
+ <xsl:with-param name="value" select="@time"/>
+ </xsl:call-template>
+ </td>
+ </tr>
+</xsl:template>
+
+
+<xsl:template match="failure">
+ <xsl:call-template name="display-failures"/>
+</xsl:template>
+
+<xsl:template match="error">
+ <xsl:call-template name="display-failures"/>
+</xsl:template>
+
+<xsl:template match="skipped">
+ <xsl:call-template name="display-failures"/>
+</xsl:template>
+
+<!-- Style for the error, failure and skipped in the testcase template -->
+<xsl:template name="display-failures">
+ <xsl:choose>
+ <xsl:when test="not(@message)">N/A</xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="@message"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ <!-- display the stacktrace -->
+ <code>
+ <br/><br/>
+ <xsl:call-template name="br-replace">
+ <xsl:with-param name="word" select="."/>
+ </xsl:call-template>
+ </code>
+ <!-- the later is better but might be problematic for non-21" monitors... -->
+ <!--pre><xsl:value-of select="."/></pre-->
+</xsl:template>
+
+<xsl:template name="JS-escape">
+ <xsl:param name="string"/>
+ <xsl:param name="tmp1" select="string:replaceAll(string:new(string($string)),'\\','\\\\')"/>
+ <xsl:param name="tmp2" select="string:replaceAll(string:new(string($tmp1)),&quot;'&quot;,&quot;\\&apos;&quot;)"/>
+ <xsl:param name="tmp3" select="string:replaceAll(string:new(string($tmp2)),&quot;&#10;&quot;,'\\n')"/>
+ <xsl:param name="tmp4" select="string:replaceAll(string:new(string($tmp3)),&quot;&#13;&quot;,'\\r')"/>
+ <xsl:value-of select="$tmp4"/>
+</xsl:template>
+
+
+<!--
+ template that will convert a carriage return into a br tag
+ @param word the text from which to convert CR to BR tag
+-->
+<xsl:template name="br-replace">
+ <xsl:param name="word"/>
+ <xsl:param name="splitlimit">32</xsl:param>
+ <xsl:variable name="secondhalflen" select="(string-length($word)+(string-length($word) mod 2)) div 2"/>
+ <xsl:variable name="secondhalfword" select="substring($word, $secondhalflen)"/>
+ <!-- When word is very big, a recursive replace is very heap/stack expensive, so subdivide on line break after middle of string -->
+ <xsl:choose>
+ <xsl:when test="(string-length($word) > $splitlimit) and (contains($secondhalfword, '&#xa;'))">
+ <xsl:variable name="secondhalfend" select="substring-after($secondhalfword, '&#xa;')"/>
+ <xsl:variable name="firsthalflen" select="string-length($word) - $secondhalflen"/>
+ <xsl:variable name="firsthalfword" select="substring($word, 1, $firsthalflen)"/>
+ <xsl:variable name="firsthalfend" select="substring-before($secondhalfword, '&#xa;')"/>
+ <xsl:call-template name="br-replace">
+ <xsl:with-param name="word" select="concat($firsthalfword,$firsthalfend)"/>
+ </xsl:call-template>
+ <br/>
+ <xsl:call-template name="br-replace">
+ <xsl:with-param name="word" select="$secondhalfend"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:when test="contains($word, '&#xa;')">
+ <xsl:value-of select="substring-before($word, '&#xa;')"/>
+ <br/>
+ <xsl:call-template name="br-replace">
+ <xsl:with-param name="word" select="substring-after($word, '&#xa;')"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$word"/>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+<xsl:template name="display-time">
+ <xsl:param name="value"/>
+ <xsl:value-of select="format-number($value,'0.000')"/>
+</xsl:template>
+
+<xsl:template name="display-percent">
+ <xsl:param name="value"/>
+ <xsl:value-of select="format-number($value,'0.00%')"/>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/log.xsl b/framework/src/ant/apache-ant-1.9.6/src/etc/log.xsl
new file mode 100644
index 00000000..5040993b
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/log.xsl
@@ -0,0 +1,203 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+<xsl:output method="html" indent="yes" encoding="US-ASCII"/>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+-->
+
+<!--
+
+ The purpose have this XSL is to provide a nice way to look at the output
+ from the Ant XmlLogger (ie: ant -listener org.apache.tools.ant.XmlLogger )
+
+ @author <a href="mailto:sbailliez@apache.org">Stephane Bailliez</a>
+
+-->
+<xsl:decimal-format decimal-separator="." grouping-separator="," />
+
+<xsl:template match="/">
+<html>
+ <head>
+ <style type="text/css">
+ .bannercell {
+ border: 0px;
+ padding: 0px;
+ }
+ body {
+ margin: 0;
+ font:normal 100% arial,helvetica,sanserif;
+ background-color:#FFFFFF;
+ color:#000000;
+ }
+ table.status {
+ font:bold 80% arial,helvetica,sanserif;
+ background-color:#525D76;
+ color:#ffffff;
+ }
+ table.log tr td, tr th {
+ font-size: 80%;
+ }
+ .error {
+ color:red;
+ }
+ .warn {
+ color:brown;
+ }
+ .info {
+ color:gray;
+ }
+ .debug{
+ color:gray;
+ }
+ .failed {
+ font-size:80%;
+ background-color: red;
+ color:#FFFFFF;
+ font-weight: bold
+ }
+ .complete {
+ font-size:80%;
+ background-color: #525D76;
+ color:#FFFFFF;
+ font-weight: bold
+ }
+ .a td {
+ background: #efefef;
+ }
+ .b td {
+ background: #fff;
+ }
+ th, td {
+ text-align: left;
+ vertical-align: top;
+ }
+ th {
+ background: #ccc;
+ color: black;
+ }
+ table, th, td {
+ border: none
+ }
+ h3 {
+ font:bold 80% arial,helvetica,sanserif;
+ background: #525D76;
+ color: white;
+ text-decoration: none;
+ padding: 5px;
+ margin-right: 2px;
+ margin-left: 2px;
+ margin-bottom: 0;
+ }
+ </style>
+ </head>
+ <body>
+ <!-- jakarta logo -->
+ <table border="0" cellpadding="0" cellspacing="0" width="100%">
+ <tr>
+ <td valign="top" class="bannercell">
+ <a href="http://jakarta.apache.org/">
+ <img src="http://jakarta.apache.org/images/jakarta-logo.gif" alt="http://jakarta.apache.org" align="left" border="0"/>
+ </a>
+ </td>
+ <td style="text-align:right;vertical-align:bottom">
+ <a href="http://ant.apache.org/">Apache Ant</a>
+ </td>
+ </tr>
+ </table>
+
+ <table border="0" width="100%">
+ <tr><td><hr noshade="yes" size="1"/></td></tr>
+ </table>
+
+ <xsl:apply-templates select="build"/>
+
+ </body>
+</html>
+</xsl:template>
+
+<xsl:template match="build">
+ <!-- build status -->
+ <table width="100%">
+ <xsl:attribute name="class">
+ <xsl:if test="@error">failed</xsl:if>
+ <xsl:if test="not(@error)">complete</xsl:if>
+ </xsl:attribute>
+ <tr>
+ <xsl:if test="@error">
+ <td nowrap="yes">Build Failed</td>
+ </xsl:if>
+ <xsl:if test="not(@error)">
+ <td nowrap="yes">Build Complete</td>
+ </xsl:if>
+ <td style="text-align:right" nowrap="yes">Total Time: <xsl:value-of select="@time"/></td>
+ </tr>
+ <tr>
+ <td colspan="2">
+ <xsl:if test="@error">
+ <tt><xsl:value-of select="@error"/></tt><br/>
+ <i style="font-size:80%">See the <a href="#stacktrace" alt="Click for details">stacktrace</a>.</i>
+ </xsl:if>
+ </td>
+ </tr>
+ </table>
+ <table border="1" cellspacing="2" cellpadding="3" width="100%" style="font-size:80%">
+ <tr class="a"><td width="1">ant.file</td><td><xsl:value-of select="substring-after(//message[contains(text(),'ant.file')], '->')"/></td></tr>
+ <tr class="b"><td width="1">ant.version</td><td><xsl:value-of select="substring-after(//message[contains(text(),'ant.version')], '->')"/></td></tr>
+ <tr class="a"><td width="1">java.version</td><td><xsl:value-of select="substring-after(//message[contains(text(),'java.vm.version')], '->')"/></td></tr>
+ <tr class="b"><td width="1">os.name</td><td><xsl:value-of select="substring-after(//message[contains(text(),'os.name')], '->')"/></td></tr>
+ </table>
+ <!-- build information -->
+ <h3>Build events</h3>
+ <table class="log" border="1" cellspacing="2" cellpadding="3" width="100%">
+ <tr>
+ <th nowrap="yes" align="left" width="1%">target</th>
+ <th nowrap="yes" align="left" width="1%">task</th>
+ <th nowrap="yes" align="left">message</th>
+ </tr>
+ <xsl:apply-templates select=".//message[@priority != 'debug']"/>
+ </table>
+ <p>
+ <!-- stacktrace -->
+ <xsl:if test="stacktrace">
+ <a name="stacktrace"/>
+ <h3>Error details</h3>
+ <table width="100%">
+ <tr><td>
+ <pre><xsl:value-of select="stacktrace"/></pre>
+ </td></tr>
+ </table>
+ </xsl:if>
+ </p>
+</xsl:template>
+
+<!-- report every message but those with debug priority -->
+<xsl:template match="message[@priority!='debug']">
+ <tr valign="top">
+ <!-- alternated row style -->
+ <xsl:attribute name="class">
+ <xsl:if test="position() mod 2 = 1">a</xsl:if>
+ <xsl:if test="position() mod 2 = 0">b</xsl:if>
+ </xsl:attribute>
+ <td nowrap="yes" width="1%"><xsl:value-of select="../../@name"/></td>
+ <td nowrap="yes" style="text-align:right" width="1%">[ <xsl:value-of select="../@name"/> ]</td>
+ <td class="{@priority}" nowrap="yes">
+ <xsl:value-of select="text()"/>
+ </td>
+ </tr>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/manifest b/framework/src/ant/apache-ant-1.9.6/src/etc/manifest
new file mode 100644
index 00000000..758bc0f0
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/manifest
@@ -0,0 +1,4 @@
+Manifest-Version: 1.0
+Main-Class: org.apache.tools.ant.Main
+
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/maudit-frames.xsl b/framework/src/ant/apache-ant-1.9.6/src/etc/maudit-frames.xsl
new file mode 100644
index 00000000..c81f8dc3
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/maudit-frames.xsl
@@ -0,0 +1,502 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
+ xmlns:lxslt="http://xml.apache.org/xslt"
+ xmlns:redirect="org.apache.xalan.lib.Redirect"
+ extension-element-prefixes="redirect">
+<xsl:output method="html" indent="yes" encoding="US-ASCII"/>
+<xsl:decimal-format decimal-separator="." grouping-separator="," />
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!--
+
+ Stylesheet to transform an XML file generated by the Ant MAudit task into
+ a set of JavaDoc-like HTML page to make pages more convenient to be browsed.
+
+ It use the Xalan redirect extension to write to multiple output files.
+
+-->
+
+<xsl:param name="output.dir" select="'.'"/>
+
+
+<xsl:template match="classes">
+ <!-- create the index.html -->
+ <redirect:write file="{$output.dir}/index.html">
+ <xsl:call-template name="index.html"/>
+ </redirect:write>
+
+ <!-- create the stylesheet.css -->
+ <redirect:write file="{$output.dir}/stylesheet.css">
+ <xsl:call-template name="stylesheet.css"/>
+ </redirect:write>
+
+ <!-- create the overview-packages.html at the root -->
+ <redirect:write file="{$output.dir}/overview-summary.html">
+ <xsl:apply-templates select="." mode="overview.packages"/>
+ </redirect:write>
+
+ <!-- create the all-packages.html at the root -->
+ <redirect:write file="{$output.dir}/overview-frame.html">
+ <xsl:apply-templates select="." mode="all.packages"/>
+ </redirect:write>
+
+ <!-- create the all-classes.html at the root -->
+ <redirect:write file="{$output.dir}/allclasses-frame.html">
+ <xsl:apply-templates select="." mode="all.classes"/>
+ </redirect:write>
+
+ <!-- process all packages -->
+ <xsl:for-each select="./class[not(./@package = preceding-sibling::class/@package)]">
+ <xsl:call-template name="package">
+ <xsl:with-param name="name" select="@package"/>
+ </xsl:call-template>
+ </xsl:for-each>
+</xsl:template>
+
+
+<xsl:template name="package">
+ <xsl:param name="name"/>
+ <xsl:variable name="package.dir">
+ <xsl:if test="not($name = '')"><xsl:value-of select="translate($name,'.','/')"/></xsl:if>
+ <xsl:if test="$name = ''">.</xsl:if>
+ </xsl:variable>
+ <!--Processing package <xsl:value-of select="@name"/> in <xsl:value-of select="$output.dir"/> -->
+ <!-- create a classes-list.html in the package directory -->
+ <redirect:write file="{$output.dir}/{$package.dir}/package-frame.html">
+ <xsl:call-template name="classes.list">
+ <xsl:with-param name="name" select="$name"/>
+ </xsl:call-template>
+ </redirect:write>
+
+ <!-- create a package-summary.html in the package directory -->
+ <redirect:write file="{$output.dir}/{$package.dir}/package-summary.html">
+ <xsl:call-template name="package.summary">
+ <xsl:with-param name="name" select="$name"/>
+ </xsl:call-template>
+ </redirect:write>
+
+ <!-- for each class, creates a @name.html -->
+ <!-- @bug there will be a problem with inner classes having the same name, it will be overwritten -->
+ <xsl:for-each select="/classes/class[@package = $name]">
+ <redirect:write file="{$output.dir}/{$package.dir}/{@name}.html">
+ <xsl:apply-templates select="." mode="class.details"/>
+ </redirect:write>
+ </xsl:for-each>
+</xsl:template>
+
+<xsl:template name="index.html">
+<HTML>
+ <HEAD><TITLE>Audit Results.</TITLE></HEAD>
+ <FRAMESET cols="20%,80%">
+ <FRAMESET rows="30%,70%">
+ <FRAME src="overview-frame.html" name="packageListFrame"/>
+ <FRAME src="allclasses-frame.html" name="classListFrame"/>
+ </FRAMESET>
+ <FRAME src="overview-summary.html" name="classFrame"/>
+ </FRAMESET>
+ <noframes>
+ <H2>Frame Alert</H2>
+ <P>
+ This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client.
+ </P>
+ </noframes>
+</HTML>
+</xsl:template>
+
+
+<!-- this is the stylesheet css to use for nearly everything -->
+<xsl:template name="stylesheet.css">
+ .bannercell {
+ border: 0px;
+ padding: 0px;
+ }
+ body {
+ margin-left: 10;
+ margin-right: 10;
+ font:normal 80% arial,helvetica,sanserif;
+ background-color:#FFFFFF;
+ color:#000000;
+ }
+ .a td {
+ background: #efefef;
+ }
+ .b td {
+ background: #fff;
+ }
+ th, td {
+ text-align: left;
+ vertical-align: top;
+ }
+ th {
+ font-weight:bold;
+ background: #ccc;
+ color: black;
+ }
+ table, th, td {
+ font-size:100%;
+ border: none
+ }
+ table.log tr td, tr th {
+
+ }
+ h2 {
+ font-weight:bold;
+ font-size:140%;
+ margin-bottom: 5;
+ }
+ h3 {
+ font-size:100%;
+ font-weight:bold;
+ background: #525D76;
+ color: white;
+ text-decoration: none;
+ padding: 5px;
+ margin-right: 2px;
+ margin-left: 2px;
+ margin-bottom: 0;
+ }
+</xsl:template>
+
+
+<!-- print the violations of the class -->
+<xsl:template match="class" mode="class.details">
+ <xsl:variable name="package.name" select="@package"/>
+ <HTML>
+ <HEAD>
+ <xsl:call-template name="create.stylesheet.link">
+ <xsl:with-param name="package.name" select="$package.name"/>
+ </xsl:call-template>
+ </HEAD>
+ <BODY>
+ <xsl:call-template name="pageHeader"/>
+ <H3>Class <xsl:if test="not($package.name = '')"><xsl:value-of select="$package.name"/>.</xsl:if><xsl:value-of select="@name"/></H3>
+
+ <table class="log" border="0" cellpadding="5" cellspacing="2" width="100%">
+ <xsl:call-template name="class.audit.header"/>
+ <xsl:apply-templates select="." mode="print.audit"/>
+ </table>
+
+ <H3>Violations</H3>
+ <table class="log" border="0" cellpadding="5" cellspacing="2" width="100%">
+ <xsl:call-template name="violation.audit.header"/>
+ <xsl:apply-templates select="./violation" mode="print.audit">
+ <xsl:sort data-type="number" select="@line"/>
+ </xsl:apply-templates>
+ </table>
+ <xsl:call-template name="pageFooter"/>
+ </BODY>
+ </HTML>
+</xsl:template>
+
+
+<!-- list of classes in a package -->
+<xsl:template name="classes.list">
+ <xsl:param name="name"/>
+ <HTML>
+ <HEAD>
+ <xsl:call-template name="create.stylesheet.link">
+ <xsl:with-param name="package.name" select="$name"/>
+ </xsl:call-template>
+ </HEAD>
+ <BODY>
+ <table width="100%">
+ <tr>
+ <td nowrap="nowrap">
+ <H2><a href="package-summary.html" target="classFrame"><xsl:value-of select="$name"/></a></H2>
+ </td>
+ </tr>
+ </table>
+
+ <h2>Classes</h2>
+ <TABLE WIDTH="100%">
+ <xsl:apply-templates select="/classes/class[./@package = $name]" mode="classes.list">
+ <xsl:sort select="@name"/>
+ </xsl:apply-templates>
+ </TABLE>
+ </BODY>
+ </HTML>
+</xsl:template>
+<!-- the class to list -->
+<xsl:template match="class" mode="classes.list">
+ <tr>
+ <td nowrap="nowrap">
+ <!-- @bug naming to fix for inner classes -->
+ <a href="{@name}.html" target="classFrame"><xsl:value-of select="@name"/></a>
+ </td>
+ </tr>
+</xsl:template>
+
+
+<!--
+ Creates an all-classes.html file that contains a link to all package-summary.html
+ on each class.
+-->
+<xsl:template match="classes" mode="all.classes">
+ <html>
+ <head>
+ <xsl:call-template name="create.stylesheet.link">
+ <xsl:with-param name="package.name"/>
+ </xsl:call-template>
+ </head>
+ <body>
+ <h2>Classes</h2>
+ <table width="100%">
+ <xsl:apply-templates select=".//class" mode="all.classes">
+ <xsl:sort select="@name"/>
+ </xsl:apply-templates>
+ </table>
+ </body>
+ </html>
+</xsl:template>
+
+<xsl:template match="class" mode="all.classes">
+ <!-- (ancestor::package)[last()] is buggy in MSXML3 ? -->
+ <xsl:variable name="package.name" select="@package"/>
+ <tr>
+ <td nowrap="nowrap">
+ <a target="classFrame">
+ <xsl:attribute name="href">
+ <xsl:if test="not($package.name='')">
+ <xsl:value-of select="translate($package.name,'.','/')"/><xsl:text>/</xsl:text>
+ </xsl:if><xsl:value-of select="@name"/><xsl:text>.html</xsl:text>
+ </xsl:attribute>
+ <xsl:value-of select="@name"/>
+ </a>
+ </td>
+ </tr>
+</xsl:template>
+
+
+<!--
+ Creates an html file that contains a link to all package-summary.html files on
+ each package existing on testsuites.
+ @bug there will be a problem here, I don't know yet how to handle unnamed package :(
+-->
+<xsl:template match="classes" mode="all.packages">
+ <html>
+ <head>
+ <xsl:call-template name="create.stylesheet.link">
+ <xsl:with-param name="package.name"/>
+ </xsl:call-template>
+ </head>
+ <body>
+ <h2><a href="overview-summary.html" target="classFrame">Home</a></h2>
+ <h2>Packages</h2>
+ <table width="100%">
+ <xsl:apply-templates select="class[not(./@package = preceding-sibling::class/@package)]" mode="all.packages">
+ <xsl:sort select="@package" order="ascending"/>
+ </xsl:apply-templates>
+ </table>
+ </body>
+ </html>
+</xsl:template>
+
+<xsl:template match="class" mode="all.packages">
+ <tr>
+ <td nowrap="nowrap">
+ <a href="{translate(@package,'.','/')}/package-summary.html" target="classFrame">
+ <xsl:value-of select="@package"/>
+ </a>
+ </td>
+ </tr>
+</xsl:template>
+
+
+<xsl:template match="classes" mode="overview.packages">
+ <html>
+ <head>
+ <xsl:call-template name="create.stylesheet.link">
+ <xsl:with-param name="package.name"/>
+ </xsl:call-template>
+ </head>
+ <body onload="open('allclasses-frame.html','classListFrame')">
+ <xsl:call-template name="pageHeader"/>
+ <h3>Summary</h3>
+ <table class="log" border="0" cellpadding="5" cellspacing="2" width="100%">
+ <tr>
+ <th>Audited classes</th>
+ <th>Reported classes</th>
+ <th>Violations</th>
+ </tr>
+ <tr class="a">
+ <td><xsl:value-of select="@audited"/></td>
+ <td><xsl:value-of select="@reported"/></td>
+ <td><xsl:value-of select="@violations"/></td>
+ </tr>
+ </table>
+ <table border="0" width="100%">
+ <tr>
+ <td style="text-align: justify;">
+ Note: Rules checked have originated from style guidelines suggested by the language designers,
+ experience from the Java development community and insite experience. Violations are generally
+ reported with a reference to the <a href="http://java.sun.com/docs/books/jls/second_edition/html/jTOC.doc.html">Java Language Specifications</a> (JLS x.x.x)
+ and Metamata Audit rules (x.x).
+ Please consult these documents for additional information about violations.
+ <p/>
+ Rules checked also enforce adherence to <a href="http://java.sun.com/docs/codeconv/html/CodeConvTOC.doc.html">Sun Java coding guidelines</a> in use at Jakarta.
+ <p/>
+ One should note that these violations do not necessary underline errors but should be used
+ as an indication for <i>possible</i> errors. As always, use your best judgment and review
+ them carefully, it might save you hours of debugging.
+ </td>
+ </tr>
+ </table>
+
+ <h3>Packages</h3>
+ <table class="log" border="0" cellpadding="5" cellspacing="2" width="100%">
+ <xsl:call-template name="class.audit.header"/>
+ <xsl:for-each select="class[not(./@package = preceding-sibling::class/@package)]">
+ <xsl:sort select="@package" order="ascending"/>
+ <tr>
+ <xsl:call-template name="alternate-row"/>
+ <td><a href="{translate(@package,'.','/')}/package-summary.html"><xsl:value-of select="@package"/></a></td>
+ <td><xsl:value-of select="sum(/classes/class[./@package = current()/@package]/@violations)"/></td>
+ </tr>
+ </xsl:for-each>
+ </table>
+ <xsl:call-template name="pageFooter"/>
+ </body>
+ </html>
+</xsl:template>
+
+
+<xsl:template name="package.summary">
+ <xsl:param name="name"/>
+ <HTML>
+ <HEAD>
+ <xsl:call-template name="create.stylesheet.link">
+ <xsl:with-param name="package.name" select="$name"/>
+ </xsl:call-template>
+ </HEAD>
+ <BODY>
+ <xsl:attribute name="onload">open('package-frame.html','classListFrame')</xsl:attribute>
+ <xsl:call-template name="pageHeader"/>
+ <h3>Package <xsl:value-of select="$name"/></h3>
+
+ <!--table border="0" cellpadding="5" cellspacing="2" width="100%">
+ <xsl:call-template name="class.metrics.header"/>
+ <xsl:apply-templates select="." mode="print.metrics"/>
+ </table-->
+
+ <xsl:if test="count(/classes/class[./@package = $name]) &gt; 0">
+ <H3>Classes</H3>
+ <table class="log" border="0" cellpadding="5" cellspacing="2" width="100%">
+ <xsl:call-template name="class.audit.header"/>
+ <xsl:apply-templates select="/classes/class[./@package = $name]" mode="print.audit">
+ <xsl:sort select="@name"/>
+ </xsl:apply-templates>
+ </table>
+ </xsl:if>
+ <xsl:call-template name="pageFooter"/>
+ </BODY>
+ </HTML>
+</xsl:template>
+
+
+<!--
+ transform string like a.b.c to ../../../
+ @param path the path to transform into a descending directory path
+-->
+<xsl:template name="path">
+ <xsl:param name="path"/>
+ <xsl:if test="contains($path,'.')">
+ <xsl:text>../</xsl:text>
+ <xsl:call-template name="path">
+ <xsl:with-param name="path"><xsl:value-of select="substring-after($path,'.')"/></xsl:with-param>
+ </xsl:call-template>
+ </xsl:if>
+ <xsl:if test="not(contains($path,'.')) and not($path = '')">
+ <xsl:text>../</xsl:text>
+ </xsl:if>
+</xsl:template>
+
+
+<!-- create the link to the stylesheet based on the package name -->
+<xsl:template name="create.stylesheet.link">
+ <xsl:param name="package.name"/>
+ <LINK REL ="stylesheet" TYPE="text/css" TITLE="Style"><xsl:attribute name="href"><xsl:if test="not($package.name = 'unnamed package')"><xsl:call-template name="path"><xsl:with-param name="path" select="$package.name"/></xsl:call-template></xsl:if>stylesheet.css</xsl:attribute></LINK>
+</xsl:template>
+
+<!-- Page HEADER -->
+<xsl:template name="pageHeader">
+
+ <!-- jakarta logo -->
+ <table border="0" cellpadding="0" cellspacing="0" width="100%">
+ <tr>
+ <td class="bannercell" rowspan="2">
+ <a href="http://jakarta.apache.org/">
+ <img src="http://jakarta.apache.org/images/jakarta-logo.gif" alt="http://jakarta.apache.org" align="left" border="0"/>
+ </a>
+ </td>
+ <td style="text-align:right"><h2>Source Code Audit</h2></td>
+ </tr>
+ <tr>
+ <td style="text-align:right">Designed for use with <a href='http://www.webgain.com/products/quality_analyzer/'>Webgain QA/Metamata Audit</a> and <a href='http://jakarta.apache.org'>Ant</a>.</td>
+ </tr>
+ </table>
+ <hr size="1"/>
+</xsl:template>
+
+<!-- Page HEADER -->
+<xsl:template name="pageFooter">
+</xsl:template>
+
+
+<!-- class header -->
+<xsl:template name="class.audit.header">
+ <tr>
+ <th width="80%">Name</th>
+ <th>Violations</th>
+ </tr>
+</xsl:template>
+
+<!-- method header -->
+<xsl:template name="violation.audit.header">
+ <tr>
+ <th>Line</th>
+ <th>Message</th>
+ </tr>
+</xsl:template>
+
+
+<!-- class information -->
+<xsl:template match="class" mode="print.audit">
+ <tr>
+ <xsl:call-template name="alternate-row"/>
+ <td><a href="{@name}.html"><xsl:value-of select="@name"/></a></td>
+ <td><xsl:apply-templates select="@violations"/></td>
+ </tr>
+</xsl:template>
+
+<xsl:template match="violation" mode="print.audit">
+ <tr>
+ <xsl:call-template name="alternate-row"/>
+ <td><xsl:value-of select="@line"/></td>
+ <td><xsl:apply-templates select="@message"/></td>
+ </tr>
+</xsl:template>
+
+<!-- alternated row style -->
+<xsl:template name="alternate-row">
+<xsl:attribute name="class">
+ <xsl:if test="position() mod 2 = 1">a</xsl:if>
+ <xsl:if test="position() mod 2 = 0">b</xsl:if>
+</xsl:attribute>
+</xsl:template>
+
+</xsl:stylesheet>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/mmetrics-frames.xsl b/framework/src/ant/apache-ant-1.9.6/src/etc/mmetrics-frames.xsl
new file mode 100644
index 00000000..2b0f6b81
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/mmetrics-frames.xsl
@@ -0,0 +1,1023 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
+ xmlns:lxslt="http://xml.apache.org/xslt"
+ xmlns:xalan="http://xml.apache.org/xalan"
+ xmlns:redirect="org.apache.xalan.lib.Redirect"
+ exclude-result-prefixes="xalan"
+ extension-element-prefixes="redirect">
+<xsl:output method="html" indent="yes" encoding="US-ASCII"/>
+<xsl:decimal-format decimal-separator="." grouping-separator="," />
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<xsl:param name="output.dir" select="'.'"/>
+
+<!-- default max value for the metrics -->
+<xsl:param name="vg.max" select="10"/>
+<xsl:param name="loc.max" select="1000"/>
+<xsl:param name="dit.max" select="10"/>
+<xsl:param name="noa.max" select="250"/>
+<xsl:param name="nrm.max" select="50"/>
+<xsl:param name="nlm.max" select="250"/>
+<xsl:param name="wmc.max" select="250"/>
+<xsl:param name="rfc.max" select="50"/>
+<xsl:param name="dac.max" select="10"/>
+<xsl:param name="fanout.max" select="10"/>
+<xsl:param name="cbo.max" select="15"/>
+<xsl:param name="lcom.max" select="10"/>
+<xsl:param name="nocl.max" select="10"/>
+
+
+<!-- create a tree fragment to speed up processing -->
+<xsl:variable name="doctree.var">
+ <xsl:element name="classes">
+ <xsl:for-each select=".//class">
+ <xsl:element name="class">
+ <xsl:attribute name="package">
+ <xsl:value-of select="(ancestor::package)[last()]/@name"/>
+ </xsl:attribute>
+ <xsl:copy-of select="@*"/>
+ <xsl:attribute name="name">
+ <xsl:apply-templates select="." mode="class.name"/>
+ </xsl:attribute>
+ <xsl:copy-of select="method"/>
+ </xsl:element>
+ </xsl:for-each>
+ </xsl:element>
+</xsl:variable>
+
+<xsl:variable name="doctree" select="xalan:nodeset($doctree.var)"/>
+
+<xsl:template match="metrics">
+
+ <!-- create the index.html -->
+ <redirect:write file="{$output.dir}/index.html">
+ <xsl:call-template name="index.html"/>
+ </redirect:write>
+
+ <!-- create the stylesheet.css -->
+ <redirect:write file="{$output.dir}/stylesheet.css">
+ <xsl:call-template name="stylesheet.css"/>
+ </redirect:write>
+
+ <redirect:write file="{$output.dir}/metrics-reference.html">
+ <xsl:call-template name="metrics-reference.html"/>
+ </redirect:write>
+
+ <!-- create the overview-packages.html at the root -->
+ <redirect:write file="{$output.dir}/overview-summary.html">
+ <xsl:apply-templates select="." mode="overview.packages"/>
+ </redirect:write>
+
+ <!-- create the all-packages.html at the root -->
+ <redirect:write file="{$output.dir}/overview-frame.html">
+ <xsl:apply-templates select="." mode="all.packages"/>
+ </redirect:write>
+
+ <!-- create the all-classes.html at the root -->
+ <redirect:write file="{$output.dir}/allclasses-frame.html">
+ <xsl:apply-templates select="." mode="all.classes"/>
+ </redirect:write>
+
+ <!-- process all packages -->
+ <xsl:apply-templates select=".//package"/>
+</xsl:template>
+
+
+<xsl:template match="package">
+ <xsl:variable name="package.name" select="@name"/>
+ <xsl:variable name="package.dir">
+ <xsl:if test="not($package.name = 'unnamed package')"><xsl:value-of select="translate($package.name,'.','/')"/></xsl:if>
+ <xsl:if test="$package.name = 'unnamed package'">.</xsl:if>
+ </xsl:variable>
+ <!-- create a classes-list.html in the package directory -->
+ <redirect:write file="{$output.dir}/{$package.dir}/package-frame.html">
+ <xsl:apply-templates select="." mode="classes.list"/>
+ </redirect:write>
+
+ <!-- create a package-summary.html in the package directory -->
+ <redirect:write file="{$output.dir}/{$package.dir}/package-summary.html">
+ <xsl:apply-templates select="." mode="package.summary"/>
+ </redirect:write>
+
+ <!-- for each class, creates a @name.html -->
+ <!-- @bug there will be a problem with inner classes having the same name, it will be overwritten -->
+ <xsl:for-each select="$doctree/classes/class[@package = current()/@name]">
+ <!--Processing <xsl:value-of select="$class.name"/><xsl:text>&#10;</xsl:text> -->
+ <redirect:write file="{$output.dir}/{$package.dir}/{@name}.html">
+ <xsl:apply-templates select="." mode="class.details"/>
+ </redirect:write>
+ </xsl:for-each>
+</xsl:template>
+
+<!-- little trick to compute the classname for inner and non inner classes -->
+<!-- this is all in one line to avoid CRLF in the name -->
+<xsl:template match="class" mode="class.name">
+ <xsl:if test="parent::class"><xsl:apply-templates select="parent::class" mode="class.name"/>.<xsl:value-of select="@name"/></xsl:if><xsl:if test="not(parent::class)"><xsl:value-of select="@name"/></xsl:if>
+</xsl:template>
+
+
+<xsl:template name="index.html">
+<HTML>
+ <HEAD><TITLE>Metrics Results.</TITLE></HEAD>
+ <FRAMESET cols="20%,80%">
+ <FRAMESET rows="30%,70%">
+ <FRAME src="overview-frame.html" name="packageListFrame"/>
+ <FRAME src="allclasses-frame.html" name="classListFrame"/>
+ </FRAMESET>
+ <FRAME src="overview-summary.html" name="classFrame"/>
+ </FRAMESET>
+ <noframes>
+ <H2>Frame Alert</H2>
+ <P>
+ This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client.
+ </P>
+ </noframes>
+</HTML>
+</xsl:template>
+
+<!-- this is the stylesheet css to use for nearly everything -->
+<xsl:template name="metrics-reference.html">
+<html>
+<head>
+<link title="Style" type="text/css" rel="stylesheet" href="stylesheet.css"/>
+</head>
+<body style="text-align:justify;">
+<h2>Metrics Reference</h2>
+<a href="#V(G)">V(G)</a> |
+<a href="#LOC">LOC</a> |
+<a href="#DIT">DIT</a> |
+<a href="#NOA">NOA</a> |
+<a href="#NRM">NRM</a> |
+<a href="#NLM">NLM</a> |
+<a href="#WMC">WMC</a> |
+<a href="#RFC">RFC</a> |
+<a href="#DAC">DAC</a> |
+<a href="#FANOUT">FANOUT</a> |
+<a href="#CBO">CBO</a> |
+<a href="#LCOM">LCOM</a> |
+<a href="#NOC">NOC</a>
+
+<a name="V(G)"/>
+<h3>Cyclomatic Complexity - V(G)</h3>
+This metric was introduced in the 1970s to measure the amount of control
+flow complexity or branching complexity in a module such as a
+subroutine. It gives the number of paths that may be taken through the
+code, and was initially developed to give some measure of the cost of
+producing a test case for the module by executing each path.
+<p/>
+Methods with a high cyclomatic complexity tend to be more difficult to
+understand and maintain. In general the more complex the methods of an
+application, the more difficult it will be to test it, and this will adversely
+affect its reliability.
+<p/>
+V(G) is a measure of the control flow complexity of a method or
+constructor. It counts the number of branches in the body of the method,
+defined as:
+<ul>
+<li>while statements;</li>
+<li>if statements;</li>
+<li>for statements.</li>
+</ul>
+
+The metric can also be configured to count each case of a switch
+statement as well.
+
+<a name="LOC"/>
+<h3>Lines of Code - LOC</h3>
+
+This is perhaps the simplest of all the metrics to define and compute.
+Counting lines has a long history as a software metric dating from before
+the rise of structured programming, and it is still in widespread use today.
+The size of a method affects the ease with which it can be understood, its
+reusability and its maintainability. There are a variety of ways that the size
+can be calculated. These include counting all the lines of code, the number
+of statements, the blank lines of code, the lines of commentary, and the
+lines consisting only of syntax such as block delimiters.
+<p/>
+This metric can also be used for sizing other constructs as well, for
+example, the overall size of a Java class or package can be measured by
+counting the number of source lines it consists of.
+<p/>
+LOC can be used to determine the size of a compilation unit (source file),
+class or interface, method, constructor, or field. It can be configured to
+ignore:
+<ul>
+<li>blank lines;</li>
+<li>lines consisting only of comments;</li>
+<li>lines consisting only of opening and closing braces.</li>
+</ul>
+
+<a name="DIT"/>
+<h3>Depth of Inheritance Hierarchy - DIT</h3>
+
+This metric calculates how far down the inheritance hierarchy a class is
+declared. In Java all classes have java.lang.Object as their ultimate
+superclass, which is defined to have a depth of 1. So a class that
+immediately extends java.lang.Object has a metric value of 2; any of its
+subclasses will have a value of 3, and so on.
+<p/>
+A class that is deep within the tree inherits more methods and state
+variables, thereby increasing its complexity and making it difficult to
+predict its behavior. It can be harder to understand a system with many
+inheritance layers.
+<p/>
+DIT is defined for classes and interfaces:
+<ul>
+<li>all interface types have a depth of 1;</li>
+<li>the class java.lang.Object has a depth of 1;</li>
+<li>all other classes have a depth of 1 + the depth of their super class.</li>
+</ul>
+
+<a name="NOA"/>
+<h3>Number of Attributes - NOA</h3>
+
+The number of distinct state variables in a class serves as one measure of
+its complexity. The more state a class represents the more difficult it is to
+maintain invariants for it. It also hinders comprehensibility and reuse.
+<p/>
+In Java, state can be exposed to subclasses through protected fields, which
+entails that the subclass also be aware of and maintain any invariants. This
+interference with the class's data encapsulation can be a source of defects
+and hidden dependencies between the state variables.
+<p/>
+NOA is defined for classes and interfaces. It counts the number of fields
+declared in the class or interface.
+
+<a name="NRM"/>
+<h3>Number of Remote Methods - NRM</h3>
+
+NRM is defined for classes. A remote method call is defined as an
+invocation of a method that is not declared in any of:
+<ul>
+<li>the class itself;</li>
+<li>a class or interface that the class extends or implements;</li>
+<li>a class or method that extends the class.</li>
+</ul>
+
+The value is the count of all the remote method calls in all of the methods
+and constructors of the class.
+
+<a name="NLM"/>
+<h3>Number of Local Methods - NLM</h3>
+
+NLM is defined for classes and interfaces. A local method is defined as a
+method that is declared in the class or interface. NLM can be configured to
+include the local methods of all of the class's superclasses. Methods with
+public, protected, package and private visibility can be independently
+counted by setting configuration parameters.
+
+<a name="WMC"/>
+<h3>Weighted Methods per Class - WMC</h3>
+
+If the number of methods in a class can be determined during the design
+and modeling phase of a project, it can be used as a predictor of how
+much time and effort is needed to develop, debug and maintain it. This
+metric can be further refined by incorporating a weighting for the
+complexity of each method. The usual weighting is given by the cyclomatic
+complexity of the method.
+<p/>
+The subclasses of a class inherit all of its public and protected methods,
+and possibly its package methods as well, so the number of methods a
+class has directly impacts the complexity of its subclasses. Classes with
+large numbers of methods are often specific to a particular application,
+reducing the ability to reuse them.
+<p/>
+The definition of WMC is based upon NLM, and it provides the same
+configuration parameters for counting inherited methods and of varying
+visibility. The main difference is that NLM always counts each method as 1,
+whereas WMC will weight each method. There are two weighting schemes:
+<ul>
+<li>V(G) the cyclomatic complexity of the method is used as its weight.
+ Methods from class files are given a V(G) of 1.</li>
+<li>the arity, or the number of parameters of the method are used to
+ determine the weight.</li>
+</ul>
+
+<a name="RFC"/>
+<h3>Response For Class - RFC</h3>
+
+The response set of a class is the set of all methods that can be invoked as
+a result of a message sent to an object of the class. This includes methods
+in the class's inheritance hierarchy and methods that can be invoked on
+other objects. The Response For Class metric is defined to be size of the
+response set for the class. A class which provides a larger response set is
+considered to be more complex than one with a smaller response set.
+<p/>
+One reason for this is that if a method call on a class can result in a large
+number of different method calls on the target and other classes, then it
+can be harder to test the behavior of the class and debug problems. It will
+typically require a deeper understanding of the potential interactions that
+objects of the class can have with the rest of the system.
+<p/>
+RFC is defined as the sum of NLM and NRM for the class. The local methods
+include all of the public, protected, package and private methods, but not
+methods declared only in a superclass.
+
+<a name="DAC"/>
+<h3>Data Abstraction Coupling - DAC</h3>
+
+DAC is defined for classes and interfaces. It counts the number of reference
+types that are used in the field declarations of the class or interface. The
+component types of arrays are also counted. Any field with a type that is
+either a supertype or a subtype of the class is not counted.
+
+<a name="FANOUT"/>
+<h3>Fan Out - FANOUT</h3>
+
+FANOUT is defined for classes and interfaces, constructors and methods. It
+counts the number of reference types that are used in:
+<ul>
+<li>field declarations;</li>
+<li>formal parameters and return types;</li>
+<li>throws declarations;</li>
+<li>local variables.</li>
+</ul>
+
+The component types of arrays are also counted. Any type that is either a
+supertype or a subtype of the class is not counted.
+
+<a name="CBO"/>
+<h3>Coupling Between Objects - CBO</h3>
+
+When one object or class uses another object or class they are said to be
+coupled. One major source of coupling is that between a superclass and a
+subclass. A coupling is also introduced when a method or field in another
+class is accessed, or when an object of another class is passed into or out
+of a method invocation. Coupling Between Objects is a measure of the
+non-inheritance coupling between two objects.
+<p/>
+A high value of coupling reduces the modularity of the class and makes
+reuse more difficult. The more independent a class is the more likely it is
+that it will be possible to reuse it in another part of the system. When a
+class is coupled to another class it becomes sensitive to changes in that
+class, thereby making maintenance for difficult. In addition, a class that is
+overly dependent on other classes can be difficult to understand and test in
+isolation.
+<p/>
+CBO is defined for classes and interfaces, constructors and methods. It
+counts the number of reference types that are used in:
+<ul>
+<li>field declarations</li>
+<li>formal parameters and return types</li>
+<li>throws declarations</li>
+<li>local variables</li>
+</ul>
+
+It also counts:
+<ul>
+<li>types from which field and method selections are made</li>
+</ul>
+
+The component types of arrays are also counted. Any type that is either a
+supertype or a subtype of the class is not counted.
+
+<a name="LCOM"/>
+<h3>Lack of Cohesion Of Methods - LCOM</h3>
+
+The cohesion of a class is the degree to which its methods are related to
+each other. It is determined by examining the pattern of state variable
+accesses within the set of methods. If all the methods access the same state
+variables then they have high cohesion; if they access disjoint sets of
+variables then the cohesion is low. An extreme example of low cohesion
+would be if none of the methods accessed any of the state variables.
+
+If a class exhibits low method cohesion it indicates that the design of the
+class has probably been partitioned incorrectly, and could benefit by being
+split into more classes with individually higher cohesion. On the other
+hand, a high value of cohesion (a low lack of cohesion) implies that the
+class is well designed. A cohesive class will tend to provide a high degree
+of encapsulation, whereas a lack of cohesion decreases encapsulation and
+increases complexity.
+<p/>
+Another form of cohesion that is useful for Java programs is cohesion
+between nested and enclosing classes. A nested class that has very low
+cohesion with its enclosing class would probably better designed as a peer
+class rather than a nested class.
+<p/>
+LCOM is defined for classes. Operationally, LCOM takes each pair of
+methods in the class and determines the set of fields they each access. If
+they have disjoint sets of field accesses increase the count P by one. If they
+share at least one field access then increase Q by one. After considering
+each pair of methods,
+LCOM = (P > Q) ? (P - Q) : 0
+<p/>
+Indirect access to fields via local methods can be considered by setting a
+metric configuration parameter.
+
+<a name="NOC"/>
+<h3>Number Of Classes - NOC</h3>
+
+The overall size of the system can be estimated by calculating the number
+of classes it contains. A large system with more classes is more complex
+than a smaller one because the number of potential interactions between
+objects is higher. This reduces the comprehensibility of the system which
+in turn makes it harder to test, debug and maintain.
+<p/>
+If the number of classes in the system can be projected during the initial
+design phase of the project it can serve as a base for estimating the total
+effort and cost of developing, debugging and maintaining the system.
+<p/>
+The NOC metric can also usefully be applied at the package and class level
+as well as the total system.
+<p/>
+NOCL is defined for class and interfaces. It counts the number of classes or
+interfaces that are declared. This is usually 1, but nested class declarations
+will increase this number.
+</body>
+</html>
+</xsl:template>
+
+<!-- this is the stylesheet css to use for nearly everything -->
+<xsl:template name="stylesheet.css">
+ .bannercell {
+ border: 0px;
+ padding: 0px;
+ }
+ body {
+ margin-left: 10;
+ margin-right: 10;
+ font:normal 80% arial,helvetica,sanserif;
+ background-color:#FFFFFF;
+ color:#000000;
+ }
+ .a td {
+ background: #efefef;
+ }
+ .b td {
+ background: #fff;
+ }
+ th, td {
+ text-align: left;
+ vertical-align: top;
+ }
+ th {
+ font-weight:bold;
+ background: #ccc;
+ color: black;
+ }
+ table, th, td {
+ font-size:100%;
+ border: none
+ }
+ table.log tr td, tr th {
+
+ }
+ h2 {
+ font-weight:bold;
+ font-size:140%;
+ margin-bottom: 5;
+ }
+ h3 {
+ font-size:100%;
+ font-weight:bold;
+ background: #525D76;
+ color: white;
+ text-decoration: none;
+ padding: 5px;
+ margin-right: 2px;
+ margin-left: 2px;
+ margin-bottom: 0;
+ }
+ .Error {
+ font-weight:bold; color:red;
+ }
+
+</xsl:template>
+
+<!-- print the metrics of the class -->
+<xsl:template match="class" mode="class.details">
+ <!--xsl:variable name="package.name" select="(ancestor::package)[last()]/@name"/-->
+ <xsl:variable name="package.name" select="@package"/>
+ <HTML>
+ <HEAD>
+ <xsl:call-template name="create.stylesheet.link">
+ <xsl:with-param name="package.name" select="$package.name"/>
+ </xsl:call-template>
+ </HEAD>
+ <BODY>
+ <xsl:call-template name="pageHeader"/>
+
+ <H3>Class <xsl:if test="not($package.name = 'unnamed package')"><xsl:value-of select="$package.name"/>.</xsl:if><xsl:value-of select="@name"/></H3>
+ <table class="log" border="0" cellpadding="5" cellspacing="2" width="100%">
+ <xsl:call-template name="all.metrics.header"/>
+ <xsl:apply-templates select="." mode="print.metrics"/>
+ </table>
+
+ <H3>Methods</H3>
+ <table class="log" border="0" cellpadding="5" cellspacing="2" width="100%">
+ <xsl:call-template name="method.metrics.header"/>
+ <xsl:apply-templates select="method" mode="print.metrics"/>
+ </table>
+
+ <xsl:call-template name="pageFooter"/>
+ </BODY>
+ </HTML>
+</xsl:template>
+
+
+<!-- list of classes in a package -->
+<xsl:template match="package" mode="classes.list">
+ <HTML>
+ <HEAD>
+ <xsl:call-template name="create.stylesheet.link">
+ <xsl:with-param name="package.name" select="@name"/>
+ </xsl:call-template>
+ </HEAD>
+ <BODY>
+ <table width="100%">
+ <tr>
+ <td nowrap="nowrap">
+ <H2><a href="package-summary.html" target="classFrame"><xsl:value-of select="@name"/></a></H2>
+ </td>
+ </tr>
+ </table>
+
+ <H2>Classes</H2>
+ <TABLE WIDTH="100%">
+ <!-- xalan-nodeset:nodeset for Xalan 1.2.2 -->
+ <xsl:for-each select="$doctree/classes/class[@package = current()/@name]">
+ <xsl:sort select="@name"/>
+ <tr>
+ <td nowrap="nowrap">
+ <a href="{@name}.html" target="classFrame"><xsl:value-of select="@name"/></a>
+ </td>
+ </tr>
+ </xsl:for-each>
+ </TABLE>
+ </BODY>
+ </HTML>
+</xsl:template>
+
+
+<!--
+ Creates an all-classes.html file that contains a link to all package-summary.html
+ on each class.
+-->
+<xsl:template match="metrics" mode="all.classes">
+ <html>
+ <head>
+ <xsl:call-template name="create.stylesheet.link">
+ <xsl:with-param name="package.name" select="''"/>
+ </xsl:call-template>
+ </head>
+ <body>
+ <h2>Classes</h2>
+ <table width="100%">
+ <xsl:for-each select="$doctree/classes/class">
+ <xsl:sort select="@name"/>
+ <xsl:apply-templates select="." mode="all.classes"/>
+ </xsl:for-each>
+ </table>
+ </body>
+ </html>
+</xsl:template>
+
+<xsl:template match="class" mode="all.classes">
+ <xsl:variable name="package.name" select="@package"/>
+ <xsl:variable name="class.name" select="@name"/>
+ <tr>
+ <td nowrap="nowrap">
+ <a target="classFrame">
+ <xsl:attribute name="href">
+ <xsl:if test="not($package.name='unnamed package')">
+ <xsl:value-of select="translate($package.name,'.','/')"/><xsl:text>/</xsl:text>
+ </xsl:if>
+ <xsl:value-of select="$class.name"/><xsl:text>.html</xsl:text>
+ </xsl:attribute>
+ <xsl:value-of select="$class.name"/>
+ </a>
+ </td>
+ </tr>
+</xsl:template>
+
+<!--
+ Creates an html file that contains a link to all package-summary.html files on
+ each package existing on testsuites.
+ @bug there will be a problem here, I don't know yet how to handle unnamed package :(
+-->
+<xsl:template match="metrics" mode="all.packages">
+ <html>
+ <head>
+ <xsl:call-template name="create.stylesheet.link">
+ <xsl:with-param name="package.name" select="./package/@name"/>
+ </xsl:call-template>
+ </head>
+ <body>
+ <h2><a href="overview-summary.html" target="classFrame">Home</a></h2>
+ <h2>Packages</h2>
+ <table width="100%">
+ <xsl:apply-templates select=".//package[not(./@name = 'unnamed package')]" mode="all.packages">
+ <xsl:sort select="@name"/>
+ </xsl:apply-templates>
+ </table>
+ </body>
+ </html>
+</xsl:template>
+
+<xsl:template match="package" mode="all.packages">
+ <tr>
+ <td nowrap="nowrap">
+ <a href="{translate(@name,'.','/')}/package-summary.html" target="classFrame">
+ <xsl:value-of select="@name"/>
+ </a>
+ </td>
+ </tr>
+</xsl:template>
+
+
+<xsl:template match="metrics" mode="overview.packages">
+ <html>
+ <head>
+ <xsl:call-template name="create.stylesheet.link">
+ <xsl:with-param name="package.name" select="''"/>
+ </xsl:call-template>
+ </head>
+ <body onload="open('allclasses-frame.html','classListFrame')">
+ <xsl:call-template name="pageHeader"/>
+ <h3>Summary</h3>
+ <table class="log" border="0" cellpadding="5" cellspacing="2" width="100%">
+ <tr>
+ <th><a href="metrics-reference.html#V(G)">V(G)</a></th>
+ <th><a href="metrics-reference.html#LOC">LOC</a></th>
+ <th><a href="metrics-reference.html#DIT">DIT</a></th>
+ <th><a href="metrics-reference.html#NOA">NOA</a></th>
+ <th><a href="metrics-reference.html#NRM">NRM</a></th>
+ <th><a href="metrics-reference.html#NLM">NLM</a></th>
+ <th><a href="metrics-reference.html#WMC">WMC</a></th>
+ <th><a href="metrics-reference.html#RFC">RFC</a></th>
+ <th><a href="metrics-reference.html#DAC">DAC</a></th>
+ <th><a href="metrics-reference.html#FANOUT">FANOUT</a></th>
+ <th><a href="metrics-reference.html#CBO">CBO</a></th>
+ <th><a href="metrics-reference.html#LCOM">LCOM</a></th>
+ <th><a href="metrics-reference.html#NOCL">NOCL</a></th>
+ </tr>
+ <xsl:apply-templates select="." mode="print.metrics"/>
+ </table>
+ <table border="0" width="100%">
+ <tr>
+ <td style="text-align: justify;">
+ Note: Metrics evaluate the quality of software by analyzing the program source and quantifying
+ various kind of complexity. Complexity is a common source of problems and defects in software.
+ High complexity makes it more difficult to develop, understand, maintain, extend, test and debug
+ a program.
+ <p/>
+ The primary use of metrics is to focus your attention on those parts of code that potentially are
+ complexity hot spots. Once the complex areas your program have been uncovered, you can take remedial
+ actions.
+ For additional information about metrics and their meaning, please consult
+ Metamata Metrics manual.
+ </td>
+ </tr>
+ </table>
+
+ <h3>Packages</h3>
+ <table border="0" cellpadding="5" cellspacing="2" width="100%">
+ <xsl:call-template name="all.metrics.header"/>
+ <xsl:for-each select=".//package[not(@name = 'unnamed package')]">
+ <xsl:sort select="@name" order="ascending"/>
+ <xsl:apply-templates select="." mode="print.metrics"/>
+ </xsl:for-each>
+ </table>
+ <!-- @bug there could some classes at this level (classes in unnamed package) -->
+ <xsl:call-template name="pageFooter"/>
+ </body>
+ </html>
+</xsl:template>
+
+<xsl:template match="package" mode="package.summary">
+ <HTML>
+ <HEAD>
+ <xsl:call-template name="create.stylesheet.link">
+ <xsl:with-param name="package.name" select="@name"/>
+ </xsl:call-template>
+ </HEAD>
+ <body onload="open('package-frame.html','classListFrame')">
+ <xsl:call-template name="pageHeader"/>
+ <!-- create an anchor to this package name -->
+ <h3>Package <xsl:value-of select="@name"/></h3>
+
+ <table class="log" border="0" cellpadding="5" cellspacing="2" width="100%">
+ <xsl:call-template name="all.metrics.header"/>
+ <xsl:apply-templates select="." mode="print.metrics"/>
+ </table>
+
+ <table border="0" width="100%">
+ <tr>
+ <td style="text-align: justify;">
+ Note: Metrics evaluate the quality of software by analyzing the program source and quantifying
+ various kind of complexity. Complexity is a common source of problems and defects in software.
+ High complexity makes it more difficult to develop, understand, maintain, extend, test and debug
+ a program.
+ <p/>
+ The primary use of metrics is to focus your attention on those parts of code that potentially are
+ complexity hot spots. Once the complex areas your program have been uncovered, you can take remedial
+ actions.
+ For additional information about metrics and their meaning, please consult
+ Metamata Metrics manual.
+ </td>
+ </tr>
+ </table>
+
+ <xsl:variable name="classes-in-package" select="$doctree/classes/class[@package = current()/@name]"/>
+ <xsl:if test="count($classes-in-package) &gt; 0">
+ <H3>Classes</H3>
+ <table class="log" border="0" cellpadding="5" cellspacing="2" width="100%">
+ <xsl:call-template name="all.metrics.header"/>
+ <xsl:for-each select="$classes-in-package">
+ <xsl:sort select="@name"/>
+ <xsl:apply-templates select="." mode="print.metrics"/>
+ </xsl:for-each>
+ </table>
+ </xsl:if>
+
+ <xsl:call-template name="pageFooter"/>
+ </body>
+ </HTML>
+</xsl:template>
+
+
+<!--
+ transform string like a.b.c to ../../../
+ @param path the path to transform into a descending directory path
+-->
+<xsl:template name="path">
+ <xsl:param name="path"/>
+ <xsl:if test="contains($path,'.')">
+ <xsl:text>../</xsl:text>
+ <xsl:call-template name="path">
+ <xsl:with-param name="path"><xsl:value-of select="substring-after($path,'.')"/></xsl:with-param>
+ </xsl:call-template>
+ </xsl:if>
+ <xsl:if test="not(contains($path,'.')) and not($path = '')">
+ <xsl:text>../</xsl:text>
+ </xsl:if>
+</xsl:template>
+
+
+<!-- create the link to the stylesheet based on the package name -->
+<xsl:template name="create.stylesheet.link">
+ <xsl:param name="package.name"/>
+ <LINK REL ="stylesheet" TYPE="text/css" TITLE="Style"><xsl:attribute name="href"><xsl:if test="not($package.name = 'unnamed package')"><xsl:call-template name="path"><xsl:with-param name="path" select="$package.name"/></xsl:call-template></xsl:if>stylesheet.css</xsl:attribute></LINK>
+</xsl:template>
+
+
+<!-- Page Header -->
+<xsl:template name="pageHeader">
+
+ <!-- jakarta logo -->
+ <table border="0" cellpadding="0" cellspacing="0" width="100%">
+ <tr>
+ <td class="bannercell" rowspan="2">
+ <a href="http://jakarta.apache.org/">
+ <img src="http://jakarta.apache.org/images/jakarta-logo.gif" alt="http://jakarta.apache.org" align="left" border="0"/>
+ </a>
+ </td>
+ <td style="text-align:right"><h2>Source Code Metrics</h2></td>
+ </tr>
+ <tr>
+ <td style="text-align:right">Designed for use with <a href='http://www.webgain.com/products/quality_analyzer/'>Webgain QA/Metamata Metrics</a> and <a href='http://jakarta.apache.org'>Ant</a>.</td>
+ </tr>
+ </table>
+ <hr size="1"/>
+</xsl:template>
+
+<!-- Page Footer -->
+<xsl:template name="pageFooter">
+</xsl:template>
+
+<!-- class header -->
+<xsl:template name="all.metrics.header">
+ <tr>
+ <th width="80%">Name</th>
+ <th nowrap="nowrap">V(G)</th>
+ <th>LOC</th>
+ <th>DIT</th>
+ <th>NOA</th>
+ <th>NRM</th>
+ <th>NLM</th>
+ <th>WMC</th>
+ <th>RFC</th>
+ <th>DAC</th>
+ <th>FANOUT</th>
+ <th>CBO</th>
+ <th>LCOM</th>
+ <th>NOCL</th>
+ </tr>
+</xsl:template>
+
+<!-- method header -->
+<xsl:template name="method.metrics.header">
+ <tr>
+ <th width="80%">Name</th>
+ <th nowrap="nowrap">V(G)</th>
+ <th>LOC</th>
+ <th>FANOUT</th>
+ <th>CBO</th>
+ </tr>
+</xsl:template>
+
+<!-- method information -->
+<xsl:template match="method" mode="print.metrics">
+ <tr>
+ <xsl:call-template name="alternate-row"/>
+ <td><xsl:apply-templates select="@name"/></td>
+ <td><xsl:apply-templates select="@vg"/></td>
+ <td><xsl:apply-templates select="@loc"/></td>
+ <td><xsl:apply-templates select="@fanout"/></td>
+ <td><xsl:apply-templates select="@cbo"/></td>
+ </tr>
+</xsl:template>
+
+<!-- class information -->
+<xsl:template match="class" mode="print.metrics">
+ <tr>
+ <xsl:call-template name="alternate-row"/>
+ <td><a href="{@name}.html"><xsl:value-of select="@name"/></a></td>
+ <td><xsl:apply-templates select="@vg"/></td>
+ <td><xsl:apply-templates select="@loc"/></td>
+ <td><xsl:apply-templates select="@dit"/></td>
+ <td><xsl:apply-templates select="@noa"/></td>
+ <td><xsl:apply-templates select="@nrm"/></td>
+ <td><xsl:apply-templates select="@nlm"/></td>
+ <td><xsl:apply-templates select="@wmc"/></td>
+ <td><xsl:apply-templates select="@rfc"/></td>
+ <td><xsl:apply-templates select="@dac"/></td>
+ <td><xsl:apply-templates select="@fanout"/></td>
+ <td><xsl:apply-templates select="@cbo"/></td>
+ <td><xsl:apply-templates select="@lcom"/></td>
+ <td><xsl:apply-templates select="@nocl"/></td>
+ </tr>
+</xsl:template>
+
+<xsl:template match="file|package" mode="print.metrics">
+ <tr>
+ <xsl:call-template name="alternate-row"/>
+ <td>
+ <a href="{translate(@name,'.','/')}/package-summary.html" target="classFrame">
+ <xsl:value-of select="@name"/>
+ </a>
+ </td>
+ <td><xsl:apply-templates select="@vg"/></td>
+ <td><xsl:apply-templates select="@loc"/></td>
+ <td><xsl:apply-templates select="@dit"/></td>
+ <td><xsl:apply-templates select="@noa"/></td>
+ <td><xsl:apply-templates select="@nrm"/></td>
+ <td><xsl:apply-templates select="@nlm"/></td>
+ <td><xsl:apply-templates select="@wmc"/></td>
+ <td><xsl:apply-templates select="@rfc"/></td>
+ <td><xsl:apply-templates select="@dac"/></td>
+ <td><xsl:apply-templates select="@fanout"/></td>
+ <td><xsl:apply-templates select="@cbo"/></td>
+ <td><xsl:apply-templates select="@lcom"/></td>
+ <td><xsl:apply-templates select="@nocl"/></td>
+ </tr>
+</xsl:template>
+
+<xsl:template match="metrics" mode="print.metrics">
+ <tr>
+ <xsl:call-template name="alternate-row"/>
+ <!-- the global metrics is the top package metrics -->
+ <td><xsl:apply-templates select="./package/@vg"/></td>
+ <td><xsl:apply-templates select="./package/@loc"/></td>
+ <td><xsl:apply-templates select="./package/@dit"/></td>
+ <td><xsl:apply-templates select="./package/@noa"/></td>
+ <td><xsl:apply-templates select="./package/@nrm"/></td>
+ <td><xsl:apply-templates select="./package/@nlm"/></td>
+ <td><xsl:apply-templates select="./package/@wmc"/></td>
+ <td><xsl:apply-templates select="./package/@rfc"/></td>
+ <td><xsl:apply-templates select="./package/@dac"/></td>
+ <td><xsl:apply-templates select="./package/@fanout"/></td>
+ <td><xsl:apply-templates select="./package/@cbo"/></td>
+ <td><xsl:apply-templates select="./package/@lcom"/></td>
+ <td><xsl:apply-templates select="./package/@nocl"/></td>
+ </tr>
+</xsl:template>
+
+<!-- alternated row style -->
+<xsl:template name="alternate-row">
+<xsl:attribute name="class">
+ <xsl:if test="position() mod 2 = 1">a</xsl:if>
+ <xsl:if test="position() mod 2 = 0">b</xsl:if>
+</xsl:attribute>
+</xsl:template>
+
+
+<!-- how to display the metrics with their max value -->
+<!-- @todo the max values must be external to the xsl -->
+
+ <xsl:template match="@vg">
+ <xsl:call-template name="display-value">
+ <xsl:with-param name="value" select="current()"/>
+ <xsl:with-param name="max" select="$vg.max"/>
+ </xsl:call-template>
+ </xsl:template>
+
+ <xsl:template match="@loc">
+ <xsl:call-template name="display-value">
+ <xsl:with-param name="value" select="current()"/>
+ <xsl:with-param name="max" select="$loc.max"/>
+ </xsl:call-template>
+ </xsl:template>
+
+ <xsl:template match="@dit">
+ <xsl:call-template name="display-value">
+ <xsl:with-param name="value" select="current()"/>
+ <xsl:with-param name="max" select="$dit.max"/>
+ </xsl:call-template>
+ </xsl:template>
+
+ <xsl:template match="@noa">
+ <xsl:call-template name="display-value">
+ <xsl:with-param name="value" select="current()"/>
+ <xsl:with-param name="max" select="$noa.max"/>
+ </xsl:call-template>
+ </xsl:template>
+
+ <xsl:template match="@nrm">
+ <xsl:call-template name="display-value">
+ <xsl:with-param name="value" select="current()"/>
+ <xsl:with-param name="max" select="$nrm.max"/>
+ </xsl:call-template>
+ </xsl:template>
+
+ <xsl:template match="@nlm">
+ <xsl:call-template name="display-value">
+ <xsl:with-param name="value" select="current()"/>
+ <xsl:with-param name="max" select="$nlm.max"/>
+ </xsl:call-template>
+ </xsl:template>
+
+ <xsl:template match="@wmc">
+ <xsl:call-template name="display-value">
+ <xsl:with-param name="value" select="current()"/>
+ <xsl:with-param name="max" select="$wmc.max"/>
+ </xsl:call-template>
+ </xsl:template>
+
+ <xsl:template match="@rfc">
+ <xsl:call-template name="display-value">
+ <xsl:with-param name="value" select="current()"/>
+ <xsl:with-param name="max" select="$rfc.max"/>
+ </xsl:call-template>
+ </xsl:template>
+
+ <xsl:template match="@dac">
+ <xsl:call-template name="display-value">
+ <xsl:with-param name="value" select="current()"/>
+ <xsl:with-param name="max" select="$dac.max"/>
+ </xsl:call-template>
+ </xsl:template>
+
+ <xsl:template match="@fanout">
+ <xsl:call-template name="display-value">
+ <xsl:with-param name="value" select="current()"/>
+ <xsl:with-param name="max" select="$fanout.max"/>
+ </xsl:call-template>
+ </xsl:template>
+
+ <xsl:template match="@cbo">
+ <xsl:call-template name="display-value">
+ <xsl:with-param name="value" select="current()"/>
+ <xsl:with-param name="max" select="$cbo.max"/>
+ </xsl:call-template>
+ </xsl:template>
+
+ <xsl:template match="@lcom">
+ <xsl:call-template name="display-value">
+ <xsl:with-param name="value" select="current()"/>
+ <xsl:with-param name="max" select="$lcom.max"/>
+ </xsl:call-template>
+ </xsl:template>
+
+ <xsl:template match="@nocl">
+ <xsl:call-template name="display-value">
+ <xsl:with-param name="value" select="current()"/>
+ <xsl:with-param name="max" select="$nocl.max"/>
+ </xsl:call-template>
+ </xsl:template>
+
+ <xsl:template name="display-value">
+ <xsl:param name="value"/>
+ <xsl:param name="max"/>
+ <xsl:if test="$value > $max">
+ <xsl:attribute name="class">Error</xsl:attribute>
+ </xsl:if>
+ <xsl:value-of select="$value"/>
+ </xsl:template>
+
+</xsl:stylesheet>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/performance/build.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/performance/build.xml
new file mode 100644
index 00000000..c3e3ed9e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/performance/build.xml
@@ -0,0 +1,124 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="all" xmlns:ac="antlib:net.sf.antcontrib">
+ <description>
+ This build file is designed to report the performance
+ of ant from various releases.
+ to use:
+ * install ant-contrib.jar to ($ANT_HOME|$HOME/.ant)/lib
+ * install beanshell jar and bsf jar
+ * use unix (with bash) or install cygwin
+ * set the env variables {whichever needs testing}
+ ANT_HOME
+ ANT_HOME_6_5 (the directory containing ant 1.6.5)
+ ANT_HOME_6_4
+ ANT_HOME_5_4
+
+ * run ant
+ For example:
+ export ANT_HOME="c:/cygwin/home/me/svn/trunk/dist"
+ export ANT_HOME_5_4="l:/apps/apache-ant-1.5.4"
+ ant.bat
+
+ TODO: more build files.
+ </description>
+ <property environment="env"/>
+
+ <target name="all" depends="gen,do-times"/>
+
+ <target name="clean">
+ <delete quiet="yes" dir="build"/>
+ </target>
+
+ <macrodef name="run-ant-files">
+ <attribute name="env-ant"/>
+ <sequential>
+ <ac:if>
+ <isset property="@{env-ant}"/>
+ <then>
+ <ac:shellscript shell="bash">
+ export ANT_HOME=${@{env-ant}}
+ echo $ANT_HOME
+ echo -n "-- props.xml --: "
+ $ANT_HOME/bin/ant -f build/gen/props.xml | grep time
+ echo -n "-- ant-call.xml --: "
+ $ANT_HOME/bin/ant -f build/gen/ant-call.xml | grep time
+ </ac:shellscript>
+ </then>
+ </ac:if>
+ </sequential>
+ </macrodef>
+
+ <target name="do-times">
+ <run-ant-files env-ant="env.ANT_HOME"/>
+ <run-ant-files env-ant="env.ANT_HOME_6_5"/>
+ <run-ant-files env-ant="env.ANT_HOME_6_2"/>
+ <run-ant-files env-ant="env.ANT_HOME_5_4"/>
+ </target>
+
+
+ <target name="gen-dirs">
+ <mkdir dir="build/gen"/>
+ </target>
+
+ <target name="avail">
+ <available property="avail.props.xml"
+ file="props.xml" filepath="build/gen"/>
+ <available property="avail.ant-call.xml"
+ file="ant-call.xml" filepath="build/gen"/>
+ </target>
+
+ <target name="gen-props" depends="gen-dirs,avail" unless="avail.props.xml">
+ <script language="beanshell">
+ import java.io.*;
+ out = new PrintWriter(new BufferedWriter(new FileWriter(
+ "build/gen/props.xml")));
+ out.println("&lt;project name='props' default='props'&gt;");
+ out.println(" &lt;target name='props'&gt;");
+ for (int i = 0; i &lt; 20000; ++i) {
+ out.println(
+ " &lt;property name='prop" + i + "' value='val'/&gt;");
+ }
+ out.println(" &lt;/target&gt;");
+ out.println("&lt;/project&gt;");
+ out.close();
+ self.log("Created build/gen/props.xml");
+ </script>
+ </target>
+
+ <target name="gen-ant-call" depends="gen-dirs,avail"
+ unless="avail.ant-call.xml">
+ <script language="beanshell">
+ import java.io.*;
+ out = new PrintWriter(new BufferedWriter(new FileWriter(
+ "build/gen/ant-call.xml")));
+ out.println("&lt;project name='ant-call' default='call'&gt;");
+ out.println(" &lt;target name='me'/&gt;");
+ out.println(" &lt;target name='call'&gt;");
+ for (int i = 0; i &lt; 1000; ++i) {
+ out.println(" &lt;antcall target='me'/&gt;");
+ }
+ out.println(" &lt;/target&gt;");
+ out.println("&lt;/project&gt;");
+ out.close();
+ self.log("Created build/gen/ant-call.xml");
+ </script>
+ </target>
+
+ <target name="gen" depends="gen-ant-call,gen-props"/>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/performance/dirscanner.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/performance/dirscanner.xml
new file mode 100644
index 00000000..5628a46c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/performance/dirscanner.xml
@@ -0,0 +1,316 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="dirscanner">
+ <description>
+ Contains tests that measure the relative performance of Ant's
+ directory scanner. This is mainly used to compare performance
+ changes between Ant releases.
+
+ Before you run any tests, you need to set up the environment by
+ running the setup or big-setup target. Note that this will create
+ a directory tree holding 10000 (setup) or 100000 (big-setup)
+ directories and about 22000 (setup) or 222000 (big-setup) files.
+
+ The setup/big-setup targets require Ant 1.7.0 or later. It may be
+ a good idea to use the -logfile option.
+
+ Consider taking a nap if you run Ant 1.6.x or 1.7.0 against a
+ "big" setup.
+
+ If Ant 1.6.x is detected or the property ant16 has been specified
+ on the command line then the tests will use the pathconvert task
+ instead of resourcecount. So if you want to compare Ant 1.6.x
+ with later versions of you must specify ant16 on the command line
+ during your 1.[78].x tests.
+
+ The tests will use the default settings of followsymlinks="true"
+ and casesensitive="true" unless those values get overwritten by
+ the properties symlinks and/or casesensitive on the command line.
+ </description>
+
+ <property name="test.dir" location="${java.io.tmpdir}/dirscan.prf"/>
+
+ <property name="symlinks" value="true"/>
+ <property name="casesensitive" value="true"/>
+
+ <condition property="ant16">
+ <contains string="${ant.version}" substring="1.6."/>
+ </condition>
+
+ <echo>This is ${ant.version}</echo>
+
+ <target name="prepare-setup">
+ <mkdir dir="${test.dir}/src/org/apache/tools/ant"/>
+ <mkdir dir="${test.dir}/dest"/>
+ <echo file="${test.dir}/src/org/apache/tools/ant/DirscannerSetup.java"
+ ><![CDATA[
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant;
+
+import java.io.File;
+import org.apache.tools.ant.taskdefs.Mkdir;
+import org.apache.tools.ant.taskdefs.Touch;
+
+public class DirscannerSetup extends Task {
+ private boolean biggerSetup = false;
+
+ public void setBig(boolean b) {
+ biggerSetup = b;
+ }
+
+ public void execute() {
+ Mkdir mkdir = new Mkdir();
+ mkdir.bindToOwner(this);
+ Touch touch = new Touch();
+ touch.bindToOwner(this);
+ String tmp = getProject().getProperty("test.dir");
+ if (!biggerSetup) {
+ createTree(new File(tmp), mkdir, touch);
+ } else {
+ for (int i = 0; i < 10; i++) {
+ File f = new File(tmp, String.valueOf(i));
+ createTree(f, mkdir, touch);
+ mkfiles(touch, f);
+ }
+ }
+ }
+
+ private static void createTree(File root, Mkdir mkdir, Touch touch) {
+ for (int i1 = 0; i1 < 10; i1++) {
+ File f1 = new File(root, String.valueOf(i1));
+ for (int i2 = 0; i2 < 10; i2++) {
+ File f2 = new File(f1, String.valueOf(i2));
+ for (int i3 = 0; i3 < 10; i3++) {
+ File f3 = new File(f2, String.valueOf(i3));
+ for (int i4 = 0; i4 < 10; i4++) {
+ File f4 = new File(f3, String.valueOf(i4));
+ mkdir.setDir(f4);
+ mkdir.execute();
+ mkfiles(touch, f4);
+ }
+ mkfiles(touch, f3);
+ }
+ mkfiles(touch, f2);
+ }
+ mkfiles(touch, f1);
+ }
+ }
+
+ private static void mkfiles(Touch touch, File dir) {
+ touch.setFile(new File(dir, "A.txt"));
+ touch.execute();
+ touch.setFile(new File(dir, "B.xml"));
+ touch.execute();
+ }
+}]]></echo>
+ <javac srcdir="${test.dir}/src" destdir="${test.dir}/dest"/>
+ <taskdef name="setup"
+ classname="org.apache.tools.ant.DirscannerSetup">
+ <classpath>
+ <pathelement location="${test.dir}/dest"/>
+ </classpath>
+ </taskdef>
+ </target>
+
+ <target name="setup" description="Sets up the environment for tests"
+ depends="prepare-setup">
+ <setup/>
+ </target>
+
+ <target name="big-setup"
+ description="Sets up the &quot;big&quot; environment for tests"
+ depends="prepare-setup">
+ <setup big="true"/>
+ </target>
+
+ <target name="cleanup"
+ description="removes the tree generated by setup">
+ <delete dir="${test.dir}"/>
+ </target>
+
+ <target name="define-scan-16" if="ant16">
+ <macrodef name="scan">
+ <attribute name="test"/>
+ <element name="patterns" optional="true"/>
+ <sequential>
+ <pathconvert property="@{test}">
+ <path>
+ <fileset dir="${test.dir}" followSymlinks="${symlinks}"
+ casesensitive="${casesensitive}">
+ <patterns/>
+ </fileset>
+ </path>
+ </pathconvert>
+ </sequential>
+ </macrodef>
+ </target>
+
+ <target name="define-scan-17+" unless="ant16">
+ <macrodef name="scan">
+ <attribute name="test"/>
+ <element name="patterns" optional="true"/>
+ <sequential>
+ <resourcecount property="@{test}">
+ <fileset dir="${test.dir}" followSymlinks="${symlinks}"
+ casesensitive="${casesensitive}">
+ <patterns/>
+ </fileset>
+ </resourcecount>
+ </sequential>
+ </macrodef>
+ </target>
+
+ <target name="define-scan" depends="define-scan-16,define-scan-17+"/>
+
+ <target name="matchall"
+ depends="define-scan"
+ description="doesn't specify any patterns">
+ <scan test="matchall"/>
+ </target>
+
+ <target name="roots"
+ depends="define-scan"
+ description="only contains include patterns that match starts">
+ <scan test="roots">
+ <patterns>
+ <include name="1/2/3/**"/>
+ <include name="9/**"/>
+ </patterns>
+ </scan>
+ </target>
+
+ <target name="many-roots"
+ depends="define-scan"
+ description="only contains include patterns that match starts">
+ <scan test="many-roots">
+ <patterns>
+ <include name="0/"/>
+ <include name="0/0/"/>
+ <include name="0/0/0/"/>
+ <include name="0/0/0/0/"/>
+ <include name="1/"/>
+ <include name="1/1/"/>
+ <include name="1/1/1/"/>
+ <include name="1/1/1/1/"/>
+ <include name="2/"/>
+ <include name="2/2/"/>
+ <include name="2/2/2/"/>
+ <include name="2/2/2/2/"/>
+ <include name="3/"/>
+ <include name="3/3/"/>
+ <include name="3/3/3/"/>
+ <include name="3/3/3/3/"/>
+ <include name="4/"/>
+ <include name="4/4/"/>
+ <include name="4/4/4/"/>
+ <include name="4/4/4/4/"/>
+ <include name="5/"/>
+ <include name="5/5/"/>
+ <include name="5/5/5/"/>
+ <include name="5/5/5/5/"/>
+ <include name="6/"/>
+ <include name="6/6/"/>
+ <include name="6/6/6/"/>
+ <include name="6/6/6/6/"/>
+ <include name="7/"/>
+ <include name="7/7/"/>
+ <include name="7/7/7/"/>
+ <include name="7/7/7/7/"/>
+ <include name="8/"/>
+ <include name="8/8/"/>
+ <include name="8/8/8/"/>
+ <include name="8/8/8/8/"/>
+ <include name="9/"/>
+ <include name="9/9/"/>
+ <include name="9/9/9/"/>
+ <include name="9/9/9/9/"/>
+ </patterns>
+ </scan>
+ </target>
+
+ <target name="recursive-excludes"
+ depends="define-scan"
+ description="specifies include and exclude patterns with wildcards">
+ <scan test="recursive-excludes">
+ <patterns>
+ <include name="**/5/**"/>
+ <exclude name="**/6/**"/>
+ </patterns>
+ </scan>
+ </target>
+
+ <target name="name-matches"
+ depends="define-scan"
+ description="specifies include and exclude patterns matching on file names">
+ <scan test="names-matches">
+ <patterns>
+ <include name="**/*.txt"/>
+ <exclude name="**/4/**"/>
+ </patterns>
+ </scan>
+ </target>
+
+ <target name="many-patterns"
+ depends="define-scan"
+ description="specifies many include and exclude patterns">
+ <scan test="many-patterns">
+ <patterns>
+ <include name="*/1/**"/>
+ <include name="*/3/**/1/**"/>
+ <include name="6/**"/>
+ <include name="**/*.xml"/>
+ <include name="**/4/*"/>
+ <include name="**/2*/**"/>
+ <include name="**/X/**"/>
+ <include name="8/9/4/2/B.xml"/>
+ <include name="9/*"/>
+ <include name="0/*/**"/>
+ <exclude name="*/5/**"/>
+ <exclude name="*/7/**/0/**"/>
+ <exclude name="1/**"/>
+ <exclude name="**/*.txt"/>
+ <exclude name="**/0/*"/>
+ <exclude name="**/8*/**"/>
+ <exclude name="**/Y/**"/>
+ <exclude name="8/9/4/2/A.txt"/>
+ <exclude name="3/*"/>
+ <exclude name="7/*/**"/>
+ </patterns>
+ </scan>
+ </target>
+
+ <target name="all"
+ depends="define-scan,matchall, roots, recursive-excludes, name-matches, many-patterns, many-roots"/>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/poms/README.txt b/framework/src/ant/apache-ant-1.9.6/src/etc/poms/README.txt
new file mode 100644
index 00000000..086d8fa8
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/poms/README.txt
@@ -0,0 +1,53 @@
+Building Ant with Maven
+-----------------------
+
+The Ant jars can be built using Maven and the POMS present in this directory.
+
+Libs not available in the maven repository
+
+groupId artifactId version comment
+com.bea weblogic 8.1.3.0 download it
+com.bea weblogicclasses 5.1 a newer version can do.
+jai jai-core 1.1.2_01 fetch.xml
+jai jai-codec 1.1.2.1 fetch.xml
+com.ibm.netrexx netrexx 2.0.5 fetch.xml
+com.starteam starteam-sdk 5.2 the original file is called starteam-sdk.jar
+stylebook stylebook 1.0-b2 the original file is called stylebook-1.0-b2.jar
+
+to install a jar file into your local Maven cache, do this
+
+mvn install:install-file -DgroupId=foo.org -DartifactId=xx -Dversion=x.y -Dpackaging=jar -Dfile=/a/b/foo.jar
+
+HOW TO BUILD :
+
+from this directory, type
+
+mvn install (or mvn package)
+
+If you do not have all the dependencies, you can remove the modules that you will not be able to build
+from the pom.xml in this directory.
+
+You also might want to disable the tests.
+
+mvn install -Dmaven.test.skip=true
+
+
+
+TODO :
+
+ * see if the dependency to weblogicclasses.jar can be replaced by a dependency to some j2ee.jar from Sun,
+as it supplies some javax.ejb classes which are required at compile time.
+
+
+PROBLEMS :
+
+ * the unit tests cannot run properly, the maven-surefire-plugin sets a system property basedir
+which make a large part of our tests fail
+
+ * JIRA issue http://jira.codehaus.org/browse/MSUREFIRE-177 asking the Maven colleagues to fix this. :-)
+
+REFERENCES :
+
+about skipping tests :
+http://maven.apache.org/plugins/maven-surefire-plugin/examples/skipping-test.html
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/poms/ant-antlr/pom.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/poms/ant-antlr/pom.xml
new file mode 100644
index 00000000..f3aa7b33
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/poms/ant-antlr/pom.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!--
+ This POM has been created manually by the Ant Development Team.
+ Please contact us if you are not satisfied with the data contained in this POM.
+ URL : http://ant.apache.org
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <parent>
+ <groupId>org.apache.ant</groupId>
+ <artifactId>ant-parent</artifactId>
+ <relativePath>../pom.xml</relativePath>
+ <version>1.9.6</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <url>http://ant.apache.org/</url>
+ <groupId>org.apache.ant</groupId>
+ <artifactId>ant-antlr</artifactId>
+ <version>1.9.6</version>
+ <name>Apache Ant + ANTLR</name>
+ <description>antlr specific task.
+ The implementation forks a java process, therefore the antlr jar file is only needed at runtime</description>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.ant</groupId>
+ <artifactId>ant</artifactId>
+ <version>1.9.6</version>
+ <optional>true</optional>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <!-- add a dependency with antlr 2.7.2 consistent with libraries.properties antlr 2.7.6 is also available on ibiblio-->
+ <groupId>antlr</groupId>
+ <artifactId>antlr</artifactId>
+ <version>2.7.2</version>
+ <optional>true</optional>
+ <scope>runtime</scope>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <includes>
+ <include>org/apache/tools/ant/taskdefs/optional/ANTLR*</include>
+ </includes>
+ </configuration>
+ </plugin>
+ </plugins>
+ <sourceDirectory>../../../../src/main</sourceDirectory>
+ <testSourceDirectory>../../../../src/testcases</testSourceDirectory>
+ <outputDirectory>../../../../target/${project.artifactId}/classes</outputDirectory>
+ <testOutputDirectory>../../../../target/${project.artifactId}/testcases</testOutputDirectory>
+ <directory>../../../../target/${project.artifactId}</directory>
+ </build>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/poms/ant-apache-bcel/pom.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/poms/ant-apache-bcel/pom.xml
new file mode 100644
index 00000000..44c6c890
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/poms/ant-apache-bcel/pom.xml
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!--
+ This POM has been created manually by the Ant Development Team.
+ Please contact us if you are not satisfied with the data contained in this POM.
+ URL : http://ant.apache.org
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <parent>
+ <groupId>org.apache.ant</groupId>
+ <artifactId>ant-parent</artifactId>
+ <relativePath>../pom.xml</relativePath>
+ <version>1.9.6</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <url>http://ant.apache.org/</url>
+ <groupId>org.apache.ant</groupId>
+ <artifactId>ant-apache-bcel</artifactId>
+ <version>1.9.6</version>
+ <name>Apache Ant + BCEL</name>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.ant</groupId>
+ <artifactId>ant</artifactId>
+ <version>1.9.6</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>bcel</groupId>
+ <artifactId>bcel</artifactId>
+ <version>5.1</version>
+ <scope>compile</scope>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <includes>
+ <include>org/apache/tools/ant/filters/util/JavaClassHelper*</include>
+ <include>org/apache/tools/ant/util/depend/bcel/*</include>
+ </includes>
+ </configuration>
+ </plugin>
+ </plugins>
+ <sourceDirectory>../../../../src/main</sourceDirectory>
+ <testSourceDirectory>../../../../src/testcases</testSourceDirectory>
+ <outputDirectory>../../../../target/${project.artifactId}/classes</outputDirectory>
+ <testOutputDirectory>../../../../target/${project.artifactId}/testcases</testOutputDirectory>
+ <directory>../../../../target/${project.artifactId}</directory>
+ </build>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/poms/ant-apache-bsf/pom.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/poms/ant-apache-bsf/pom.xml
new file mode 100644
index 00000000..d5180290
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/poms/ant-apache-bsf/pom.xml
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!--
+ This POM has been created manually by the Ant Development Team.
+ Please contact us if you are not satisfied with the data contained in this POM.
+ URL : http://ant.apache.org
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <parent>
+ <groupId>org.apache.ant</groupId>
+ <artifactId>ant-parent</artifactId>
+ <relativePath>../pom.xml</relativePath>
+ <version>1.9.6</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <url>http://ant.apache.org/</url>
+ <groupId>org.apache.ant</groupId>
+ <artifactId>ant-apache-bsf</artifactId>
+ <version>1.9.6</version>
+ <name>Apache Ant + BSF</name>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.ant</groupId>
+ <artifactId>ant</artifactId>
+ <version>1.9.6</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>bsf</groupId>
+ <artifactId>bsf</artifactId>
+ <version>2.4.0</version>
+ <scope>compile</scope>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <includes>
+ <include>org/apache/tools/ant/taskdefs/optional/Script*</include>
+ <include>org/apache/tools/ant/taskdefs/optional/script/**</include>
+ <include>org/apache/tools/ant/types/optional/*Script*</include>
+ <include>org/apache/tools/ant/util/Script*</include>
+ <include>org/apache/tools/ant/util/optional/Script*</include>
+ </includes>
+ </configuration>
+ </plugin>
+ </plugins>
+ <sourceDirectory>../../../../src/main</sourceDirectory>
+ <testSourceDirectory>../../../../src/testcases</testSourceDirectory>
+ <outputDirectory>../../../../target/${project.artifactId}/classes</outputDirectory>
+ <testOutputDirectory>../../../../target/${project.artifactId}/testcases</testOutputDirectory>
+ <directory>../../../../target/${project.artifactId}</directory>
+ </build>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/poms/ant-apache-log4j/pom.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/poms/ant-apache-log4j/pom.xml
new file mode 100644
index 00000000..5caad403
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/poms/ant-apache-log4j/pom.xml
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!--
+ This POM has been created manually by the Ant Development Team.
+ Please contact us if you are not satisfied with the data contained in this POM.
+ URL : http://ant.apache.org
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <parent>
+ <groupId>org.apache.ant</groupId>
+ <artifactId>ant-parent</artifactId>
+ <relativePath>../pom.xml</relativePath>
+ <version>1.9.6</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <url>http://ant.apache.org/</url>
+ <groupId>org.apache.ant</groupId>
+ <artifactId>ant-apache-log4j</artifactId>
+ <version>1.9.6</version>
+ <name>Apache Ant + Log4J</name>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.ant</groupId>
+ <artifactId>ant</artifactId>
+ <version>1.9.6</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>log4j</groupId>
+ <artifactId>log4j</artifactId>
+ <version>1.2.13</version>
+ <scope>compile</scope>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <includes>
+ <include>org/apache/tools/ant/listener/Log4jListener*</include>
+ </includes>
+ </configuration>
+ </plugin>
+ </plugins>
+ <sourceDirectory>../../../../src/main</sourceDirectory>
+ <testSourceDirectory>../../../../src/testcases</testSourceDirectory>
+ <outputDirectory>../../../../target/${project.artifactId}/classes</outputDirectory>
+ <testOutputDirectory>../../../../target/${project.artifactId}/testcases</testOutputDirectory>
+ <directory>../../../../target/${project.artifactId}</directory>
+ </build>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/poms/ant-apache-oro/pom.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/poms/ant-apache-oro/pom.xml
new file mode 100644
index 00000000..b722bab3
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/poms/ant-apache-oro/pom.xml
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!--
+ This POM has been created manually by the Ant Development Team.
+ Please contact us if you are not satisfied with the data contained in this POM.
+ URL : http://ant.apache.org
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <parent>
+ <groupId>org.apache.ant</groupId>
+ <artifactId>ant-parent</artifactId>
+ <relativePath>../pom.xml</relativePath>
+ <version>1.9.6</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <url>http://ant.apache.org/</url>
+ <groupId>org.apache.ant</groupId>
+ <artifactId>ant-apache-oro</artifactId>
+ <version>1.9.6</version>
+ <name>Apache Ant + Apache Oro</name>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.ant</groupId>
+ <artifactId>ant</artifactId>
+ <version>1.9.6</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>oro</groupId>
+ <artifactId>oro</artifactId>
+ <version>2.0.8</version>
+ <scope>compile</scope>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <includes>
+ <include>org/apache/tools/ant/util/regexp/JakartaOro*</include>
+ </includes>
+ <testIncludes>
+ <include>org/apache/tools/ant/util/regexp/JakartaOro*</include>
+ <include>org/apache/tools/ant/util/regexp/Regexp*</include>
+ </testIncludes>
+ </configuration>
+ </plugin>
+ </plugins>
+ <sourceDirectory>../../../../src/main</sourceDirectory>
+ <testSourceDirectory>../../../../src/tests/junit</testSourceDirectory>
+ <outputDirectory>../../../../target/${project.artifactId}/classes</outputDirectory>
+ <testOutputDirectory>../../../../target/${project.artifactId}/testcases</testOutputDirectory>
+ <directory>../../../../target/${project.artifactId}</directory>
+ </build>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/poms/ant-apache-regexp/pom.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/poms/ant-apache-regexp/pom.xml
new file mode 100644
index 00000000..6c306210
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/poms/ant-apache-regexp/pom.xml
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!--
+ This POM has been created manually by the Ant Development Team.
+ Please contact us if you are not satisfied with the data contained in this POM.
+ URL : http://ant.apache.org
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <parent>
+ <groupId>org.apache.ant</groupId>
+ <artifactId>ant-parent</artifactId>
+ <relativePath>../pom.xml</relativePath>
+ <version>1.9.6</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <url>http://ant.apache.org/</url>
+ <groupId>org.apache.ant</groupId>
+ <artifactId>ant-apache-regexp</artifactId>
+ <version>1.9.6</version>
+ <name>Apache Ant + Apache Regexp</name>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.ant</groupId>
+ <artifactId>ant</artifactId>
+ <version>1.9.6</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>regexp</groupId>
+ <artifactId>regexp</artifactId>
+ <version>1.3</version>
+ <scope>compile</scope>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <includes>
+ <include>org/apache/tools/ant/util/regexp/JakartaRegexp*</include>
+ </includes>
+ </configuration>
+ </plugin>
+ </plugins>
+ <sourceDirectory>../../../../src/main</sourceDirectory>
+ <testSourceDirectory>../../../../src/testcases</testSourceDirectory>
+ <outputDirectory>../../../../target/${project.artifactId}/classes</outputDirectory>
+ <testOutputDirectory>../../../../target/${project.artifactId}/testcases</testOutputDirectory>
+ <directory>../../../../target/${project.artifactId}</directory>
+ </build>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/poms/ant-apache-resolver/pom.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/poms/ant-apache-resolver/pom.xml
new file mode 100644
index 00000000..bd3dfa35
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/poms/ant-apache-resolver/pom.xml
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!--
+ This POM has been created manually by the Ant Development Team.
+ Please contact us if you are not satisfied with the data contained in this POM.
+ URL : http://ant.apache.org
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <parent>
+ <groupId>org.apache.ant</groupId>
+ <artifactId>ant-parent</artifactId>
+ <relativePath>../pom.xml</relativePath>
+ <version>1.9.6</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <url>http://ant.apache.org/</url>
+ <groupId>org.apache.ant</groupId>
+ <artifactId>ant-apache-resolver</artifactId>
+ <version>1.9.6</version>
+ <name>Apache Ant + Apache Resolver</name>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.ant</groupId>
+ <artifactId>ant</artifactId>
+ <version>1.9.6</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>xml-resolver</groupId>
+ <artifactId>xml-resolver</artifactId>
+ <version>1.1</version>
+ <scope>compile</scope>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <includes>
+ <include>org/apache/tools/ant/types/resolver/**</include>
+ </includes>
+ </configuration>
+ </plugin>
+ </plugins>
+ <sourceDirectory>../../../../src/main</sourceDirectory>
+ <testSourceDirectory>../../../../src/testcases</testSourceDirectory>
+ <outputDirectory>../../../../target/${project.artifactId}/classes</outputDirectory>
+ <testOutputDirectory>../../../../target/${project.artifactId}/testcases</testOutputDirectory>
+ <directory>../../../../target/${project.artifactId}</directory>
+ </build>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/poms/ant-apache-xalan2/pom.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/poms/ant-apache-xalan2/pom.xml
new file mode 100644
index 00000000..73f8442f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/poms/ant-apache-xalan2/pom.xml
@@ -0,0 +1,94 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!--
+ This POM has been created manually by the Ant Development Team.
+ Please contact us if you are not satisfied with the data contained in this POM.
+ URL : http://ant.apache.org
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <parent>
+ <groupId>org.apache.ant</groupId>
+ <artifactId>ant-parent</artifactId>
+ <relativePath>../pom.xml</relativePath>
+ <version>1.9.6</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <url>http://ant.apache.org/</url>
+ <groupId>org.apache.ant</groupId>
+ <artifactId>ant-apache-xalan2</artifactId>
+ <version>1.9.6</version>
+ <name>Apache Ant + Xalan 2</name>
+ <description>contains Xalan2-specific features</description>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.ant</groupId>
+ <artifactId>ant</artifactId>
+ <version>1.9.6</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>xalan</groupId>
+ <artifactId>xalan</artifactId>
+ <version>2.7.1</version>
+ <scope>compile</scope>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-antrun-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>create-timestamp-file</id>
+ <phase>generate-resources</phase>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ <configuration>
+ <tasks>
+ <mkdir dir="${project.build.outputDirectory}"/>
+ <copy todir="${project.build.outputDirectory}/org/apache/tools/ant/taskdefs/optional/junit/xsl">
+ <fileset dir="${project.build.sourceDirectory}/../etc">
+ <include name="junit-frames.xsl"/>
+ <include name="junit-noframes.xsl"/>
+ </fileset>
+ </copy>
+ </tasks>
+ </configuration>
+ </execution>
+
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <includes>
+ <include>org/apache/tools/ant/taskdefs/optional/Xalan2TraceSupport*</include>
+ </includes>
+ </configuration>
+ </plugin>
+ </plugins>
+ <sourceDirectory>../../../../src/main</sourceDirectory>
+ <testSourceDirectory>../../../../src/testcases</testSourceDirectory>
+ <outputDirectory>../../../../target/${project.artifactId}/classes</outputDirectory>
+ <testOutputDirectory>../../../../target/${project.artifactId}/testcases</testOutputDirectory>
+ <directory>../../../../target/${project.artifactId}</directory>
+ </build>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/poms/ant-commons-logging/pom.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/poms/ant-commons-logging/pom.xml
new file mode 100644
index 00000000..2415823b
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/poms/ant-commons-logging/pom.xml
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!--
+ This POM has been created manually by the Ant Development Team.
+ Please contact us if you are not satisfied with the data contained in this POM.
+ URL : http://ant.apache.org
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <parent>
+ <groupId>org.apache.ant</groupId>
+ <artifactId>ant-parent</artifactId>
+ <relativePath>../pom.xml</relativePath>
+ <version>1.9.6</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <url>http://ant.apache.org/</url>
+ <groupId>org.apache.ant</groupId>
+ <artifactId>ant-commons-logging</artifactId>
+ <version>1.9.6</version>
+ <name>Apache Ant + Commons Logging</name>
+ <description>Ant Listener based on commons-logging</description>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.ant</groupId>
+ <artifactId>ant</artifactId>
+ <version>1.9.6</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging-api</artifactId>
+ <version>1.0.4</version>
+ <scope>compile</scope>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <includes>
+ <include>org/apache/tools/ant/listener/CommonsLoggingListener*</include>
+ </includes>
+ </configuration>
+ </plugin>
+ </plugins>
+ <sourceDirectory>../../../../src/main</sourceDirectory>
+ <testSourceDirectory>../../../../src/testcases</testSourceDirectory>
+ <outputDirectory>../../../../target/${project.artifactId}/classes</outputDirectory>
+ <testOutputDirectory>../../../../target/${project.artifactId}/testcases</testOutputDirectory>
+ <directory>../../../../target/${project.artifactId}</directory>
+ </build>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/poms/ant-commons-net/pom.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/poms/ant-commons-net/pom.xml
new file mode 100644
index 00000000..73144a65
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/poms/ant-commons-net/pom.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!--
+ This POM has been created manually by the Ant Development Team.
+ Please contact us if you are not satisfied with the data contained in this POM.
+ URL : http://ant.apache.org
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <parent>
+ <groupId>org.apache.ant</groupId>
+ <artifactId>ant-parent</artifactId>
+ <relativePath>../pom.xml</relativePath>
+ <version>1.9.6</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <url>http://ant.apache.org/</url>
+ <groupId>org.apache.ant</groupId>
+ <artifactId>ant-commons-net</artifactId>
+ <version>1.9.6</version>
+ <name>Apache Ant + Commons Net</name>
+ <description>ftp, rexec and telnet tasks</description>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.ant</groupId>
+ <artifactId>ant</artifactId>
+ <version>1.9.6</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>commons-net</groupId>
+ <artifactId>commons-net</artifactId>
+ <version>1.4.0</version>
+ <scope>compile</scope>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <includes>
+ <include>org/apache/tools/ant/taskdefs/optional/net/FTP*</include>
+ <include>org/apache/tools/ant/taskdefs/optional/net/RExec*</include>
+ <include>org/apache/tools/ant/taskdefs/optional/net/TelnetTask*</include>
+ </includes>
+ <testIncludes>
+ <include>org/apache/tools/ant/taskdefs/optional/net/FTP*</include>
+ </testIncludes>
+ </configuration>
+ </plugin>
+ </plugins>
+ <sourceDirectory>../../../../src/main</sourceDirectory>
+ <testSourceDirectory>../../../../src/testcases</testSourceDirectory>
+ <outputDirectory>../../../../target/${project.artifactId}/classes</outputDirectory>
+ <testOutputDirectory>../../../../target/${project.artifactId}/testcases</testOutputDirectory>
+ <directory>../../../../target/${project.artifactId}</directory>
+ </build>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/poms/ant-jai/pom.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/poms/ant-jai/pom.xml
new file mode 100644
index 00000000..1ac8f4f1
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/poms/ant-jai/pom.xml
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!--
+ This POM has been created manually by the Ant Development Team.
+ Please contact us if you are not satisfied with the data contained in this POM.
+ URL : http://ant.apache.org
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <parent>
+ <groupId>org.apache.ant</groupId>
+ <artifactId>ant-parent</artifactId>
+ <relativePath>../pom.xml</relativePath>
+ <version>1.9.6</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <url>http://ant.apache.org/</url>
+ <groupId>org.apache.ant</groupId>
+ <artifactId>ant-jai</artifactId>
+ <version>1.9.6</version>
+ <name>Apache Ant + JAI</name>
+ <description>image task and corresponding types.
+ </description>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.ant</groupId>
+ <artifactId>ant</artifactId>
+ <version>1.9.6</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>javax.media</groupId>
+ <artifactId>jai-core</artifactId>
+ <version>1.1.3</version>
+ </dependency>
+ <dependency>
+ <groupId>com.sun.media</groupId>
+ <artifactId>jai-codec</artifactId>
+ <version>1.1.3</version>
+ </dependency>
+ </dependencies>
+ <!-- Central has javax.media:jai-core:1.1.3 but only com.sun.media:jai-codec:1.1.2_01 -->
+ <repositories>
+ <repository>
+ <id>jboss</id>
+ <name>JBoss</name>
+ <url>https://repository.jboss.org/nexus/content/groups/public/</url>
+ </repository>
+ </repositories>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <includes>
+ <include>org/apache/tools/ant/taskdefs/optional/image/*</include>
+ <include>org/apache/tools/ant/types/optional/image/*</include>
+ </includes>
+ </configuration>
+ </plugin>
+ </plugins>
+ <sourceDirectory>../../../../src/main</sourceDirectory>
+ <testSourceDirectory>../../../../src/testcases</testSourceDirectory>
+ <outputDirectory>../../../../target/${project.artifactId}/classes</outputDirectory>
+ <testOutputDirectory>../../../../target/${project.artifactId}/testcases</testOutputDirectory>
+ <directory>../../../../target/${project.artifactId}</directory>
+ </build>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/poms/ant-javamail/pom.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/poms/ant-javamail/pom.xml
new file mode 100644
index 00000000..543c4977
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/poms/ant-javamail/pom.xml
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!--
+ This POM has been created manually by the Ant Development Team.
+ Please contact us if you are not satisfied with the data contained in this POM.
+ URL : http://ant.apache.org
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <parent>
+ <groupId>org.apache.ant</groupId>
+ <artifactId>ant-parent</artifactId>
+ <relativePath>../pom.xml</relativePath>
+ <version>1.9.6</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <url>http://ant.apache.org/</url>
+ <groupId>org.apache.ant</groupId>
+ <artifactId>ant-javamail</artifactId>
+ <version>1.9.6</version>
+ <name>Apache Ant + JavaMail</name>
+ <description>implementation of the mail task based on javamail.
+ Required to send emails to SMTP servers using user/password combinations
+ or to send mail over SSL</description>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.ant</groupId>
+ <artifactId>ant</artifactId>
+ <version>1.9.6</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>javax.mail</groupId>
+ <artifactId>mail</artifactId>
+ <version>1.4</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>javax.activation</groupId>
+ <artifactId>activation</artifactId>
+ <version>1.1</version>
+ <scope>compile</scope>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <includes>
+ <include>org/apache/tools/ant/taskdefs/email/MimeMailer*</include>
+ </includes>
+ </configuration>
+ </plugin>
+ </plugins>
+ <sourceDirectory>../../../../src/main</sourceDirectory>
+ <testSourceDirectory>../../../../src/testcases</testSourceDirectory>
+ <outputDirectory>../../../../target/${project.artifactId}/classes</outputDirectory>
+ <testOutputDirectory>../../../../target/${project.artifactId}/testcases</testOutputDirectory>
+ <directory>../../../../target/${project.artifactId}</directory>
+ </build>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/poms/ant-jdepend/pom.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/poms/ant-jdepend/pom.xml
new file mode 100644
index 00000000..ecbaaad6
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/poms/ant-jdepend/pom.xml
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!--
+ This POM has been created manually by the Ant Development Team.
+ Please contact us if you are not satisfied with the data contained in this POM.
+ URL : http://ant.apache.org
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <parent>
+ <groupId>org.apache.ant</groupId>
+ <artifactId>ant-parent</artifactId>
+ <relativePath>../pom.xml</relativePath>
+ <version>1.9.6</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <url>http://ant.apache.org/</url>
+ <groupId>org.apache.ant</groupId>
+ <artifactId>ant-jdepend</artifactId>
+ <version>1.9.6</version>
+ <name>Apache Ant + JDepend</name>
+ <description>task jdepend invoking the jdepend parser. There is also a version 2.9.1 of the
+ jdepend parser available on the maven repository</description>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.ant</groupId>
+ <artifactId>ant</artifactId>
+ <version>1.9.6</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>jdepend</groupId>
+ <artifactId>jdepend</artifactId>
+ <version>2.7</version>
+ <scope>compile</scope>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <includes>
+ <include>org/apache/tools/ant/taskdefs/optional/jdepend/*</include>
+ </includes>
+ </configuration>
+ </plugin>
+ </plugins>
+ <sourceDirectory>../../../../src/main</sourceDirectory>
+ <testSourceDirectory>../../../../src/testcases</testSourceDirectory>
+ <outputDirectory>../../../../target/${project.artifactId}/classes</outputDirectory>
+ <testOutputDirectory>../../../../target/${project.artifactId}/testcases</testOutputDirectory>
+ <directory>../../../../target/${project.artifactId}</directory>
+ </build>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/poms/ant-jmf/pom.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/poms/ant-jmf/pom.xml
new file mode 100644
index 00000000..278a01f2
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/poms/ant-jmf/pom.xml
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!--
+ This POM has been created manually by the Ant Development Team.
+ Please contact us if you are not satisfied with the data contained in this POM.
+ URL : http://ant.apache.org
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <parent>
+ <groupId>org.apache.ant</groupId>
+ <artifactId>ant-parent</artifactId>
+ <relativePath>../pom.xml</relativePath>
+ <version>1.9.6</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <url>http://ant.apache.org/</url>
+ <groupId>org.apache.ant</groupId>
+ <artifactId>ant-jmf</artifactId>
+ <version>1.9.6</version>
+ <name>Apache Ant + JMF</name>
+ <description>contains the sound task and a soundplayer listener
+ download the dependency from http://java.sun.com/products/java-media/jmf/</description>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.ant</groupId>
+ <artifactId>ant</artifactId>
+ <version>1.9.6</version>
+ <scope>compile</scope>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <includes>
+ <include>org/apache/tools/ant/taskdefs/optional/sound/*</include>
+ </includes>
+ </configuration>
+ </plugin>
+ </plugins>
+ <sourceDirectory>../../../../src/main</sourceDirectory>
+ <testSourceDirectory>../../../../src/testcases</testSourceDirectory>
+ <outputDirectory>../../../../target/${project.artifactId}/classes</outputDirectory>
+ <testOutputDirectory>../../../../target/${project.artifactId}/testcases</testOutputDirectory>
+ <directory>../../../../target/${project.artifactId}</directory>
+ </build>
+ </project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/poms/ant-jsch/pom.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/poms/ant-jsch/pom.xml
new file mode 100644
index 00000000..39444a3f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/poms/ant-jsch/pom.xml
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!--
+ This POM has been created manually by the Ant Development Team.
+ Please contact us if you are not satisfied with the data contained in this POM.
+ URL : http://ant.apache.org
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <parent>
+ <groupId>org.apache.ant</groupId>
+ <artifactId>ant-parent</artifactId>
+ <relativePath>../pom.xml</relativePath>
+ <version>1.9.6</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <url>http://ant.apache.org/</url>
+ <groupId>org.apache.ant</groupId>
+ <artifactId>ant-jsch</artifactId>
+ <version>1.9.6</version>
+ <name>Apache Ant + JSch</name>
+ <description>contains the sshexec and scp tasks
+ </description>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.ant</groupId>
+ <artifactId>ant</artifactId>
+ <version>1.9.6</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.jcraft</groupId>
+ <artifactId>jsch</artifactId>
+ <version>0.1.50</version>
+ <scope>compile</scope>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <includes>
+ <include>org/apache/tools/ant/taskdefs/optional/ssh/*</include>
+ </includes>
+ <testIncludes>
+ <include>org/apache/tools/ant/taskdefs/optional/ssh/*</include>
+ </testIncludes>
+ </configuration>
+ </plugin>
+ </plugins>
+ <sourceDirectory>../../../../src/main</sourceDirectory>
+ <testSourceDirectory>../../../../src/testcases</testSourceDirectory>
+ <outputDirectory>../../../../target/${project.artifactId}/classes</outputDirectory>
+ <testOutputDirectory>../../../../target/${project.artifactId}/testcases</testOutputDirectory>
+ <directory>../../../../target/${project.artifactId}</directory>
+ </build>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/poms/ant-junit/pom.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/poms/ant-junit/pom.xml
new file mode 100644
index 00000000..32926a43
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/poms/ant-junit/pom.xml
@@ -0,0 +1,101 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!--
+ This POM has been created manually by the Ant Development Team.
+ Please contact us if you are not satisfied with the data contained in this POM.
+ URL : http://ant.apache.org
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <parent>
+ <groupId>org.apache.ant</groupId>
+ <artifactId>ant-parent</artifactId>
+ <relativePath>../pom.xml</relativePath>
+ <version>1.9.6</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <url>http://ant.apache.org/</url>
+ <groupId>org.apache.ant</groupId>
+ <artifactId>ant-junit</artifactId>
+ <version>1.9.6</version>
+ <name>Apache Ant + JUnit</name>
+ <description>contains the junit and junirreport tasks</description>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.ant</groupId>
+ <artifactId>ant</artifactId>
+ <version>1.9.6</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.11</version>
+ <scope>compile</scope>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-antrun-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>create-timestamp-file</id>
+ <phase>generate-resources</phase>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ <configuration>
+ <tasks>
+ <mkdir dir="${project.build.outputDirectory}"/>
+ <copy todir="${project.build.outputDirectory}/org/apache/tools/ant/taskdefs/optional/junit/xsl">
+ <fileset dir="${project.build.sourceDirectory}/../etc">
+ <include name="junit-frames.xsl"/>
+ <include name="junit-noframes.xsl"/>
+ </fileset>
+ </copy>
+ </tasks>
+ </configuration>
+ </execution>
+
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <includes>
+ <include>org/apache/tools/ant/taskdefs/optional/junit/*</include>
+ </includes>
+ <excludes>
+ <exclude>org/apache/tools/ant/taskdefs/optional/junit/JUnit4TestMethodAdapter*</exclude>
+ <exclude>org/apache/tools/ant/taskdefs/optional/junit/CustomJUnit4TestAdapterCache*</exclude>
+ </excludes>
+ <testIncludes>
+ <include>org/apache/tools/ant/taskdefs/optional/junit/</include>
+ </testIncludes>
+ </configuration>
+ </plugin>
+ </plugins>
+ <sourceDirectory>../../../../src/main</sourceDirectory>
+ <testSourceDirectory>../../../../src/testcases</testSourceDirectory>
+ <outputDirectory>../../../../target/${project.artifactId}/classes</outputDirectory>
+ <testOutputDirectory>../../../../target/${project.artifactId}/testcases</testOutputDirectory>
+ <directory>../../../../target/${project.artifactId}</directory>
+ </build>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/poms/ant-junit4/pom.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/poms/ant-junit4/pom.xml
new file mode 100644
index 00000000..e40d984f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/poms/ant-junit4/pom.xml
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!--
+ This POM has been created manually by the Ant Development Team.
+ Please contact us if you are not satisfied with the data contained in this POM.
+ URL : http://ant.apache.org
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <parent>
+ <groupId>org.apache.ant</groupId>
+ <artifactId>ant-parent</artifactId>
+ <relativePath>../pom.xml</relativePath>
+ <version>1.9.6</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <url>http://ant.apache.org/</url>
+ <groupId>org.apache.ant</groupId>
+ <artifactId>ant-junit4</artifactId>
+ <version>1.9.6</version>
+ <name>Apache Ant + JUnit 4</name>
+ <description>contains JUnit 4.x support</description>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.ant</groupId>
+ <artifactId>ant</artifactId>
+ <version>1.9.6</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.11</version>
+ <scope>compile</scope>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <includes>
+ <include>org/apache/tools/ant/taskdefs/optional/junit/JUnit4TestMethodAdapter*</include>
+ <include>org/apache/tools/ant/taskdefs/optional/junit/CustomJUnit4TestAdapterCache*</include>
+ </includes>
+ </configuration>
+ </plugin>
+ </plugins>
+ <sourceDirectory>../../../../src/main</sourceDirectory>
+ <testSourceDirectory>../../../../src/testcases</testSourceDirectory>
+ <outputDirectory>../../../../target/${project.artifactId}/classes</outputDirectory>
+ <testOutputDirectory>../../../../target/${project.artifactId}/testcases</testOutputDirectory>
+ <directory>../../../../target/${project.artifactId}</directory>
+ </build>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/poms/ant-launcher/pom.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/poms/ant-launcher/pom.xml
new file mode 100644
index 00000000..02ecff8f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/poms/ant-launcher/pom.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!--
+ This POM has been created manually by the Ant Development Team.
+ Please contact us if you are not satisfied with the data contained in this POM.
+ URL : http://ant.apache.org
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <parent>
+ <groupId>org.apache.ant</groupId>
+ <artifactId>ant-parent</artifactId>
+ <relativePath>../pom.xml</relativePath>
+ <version>1.9.6</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <url>http://ant.apache.org/</url>
+ <groupId>org.apache.ant</groupId>
+ <artifactId>ant-launcher</artifactId>
+ <version>1.9.6</version>
+ <name>Apache Ant Launcher</name>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <includes>
+ <include>org/apache/tools/ant/launch/*.java</include>
+ </includes>
+
+ </configuration>
+ </plugin>
+ </plugins>
+ <sourceDirectory>../../../../src/main</sourceDirectory>
+ <testSourceDirectory>../../../../src/testcases</testSourceDirectory>
+ <outputDirectory>../../../../target/ant-launcher/classes</outputDirectory>
+ <testOutputDirectory>../../../../target/ant-launcher/testcases</testOutputDirectory>
+ <directory>../../../../target/ant-launcher</directory>
+ </build>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/poms/ant-netrexx/pom.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/poms/ant-netrexx/pom.xml
new file mode 100644
index 00000000..505ad929
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/poms/ant-netrexx/pom.xml
@@ -0,0 +1,98 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!--
+ This POM has been created manually by the Ant Development Team.
+ Please contact us if you are not satisfied with the data contained in this POM.
+ URL : http://ant.apache.org
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <parent>
+ <groupId>org.apache.ant</groupId>
+ <artifactId>ant-parent</artifactId>
+ <relativePath>../pom.xml</relativePath>
+ <version>1.9.6</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <url>http://ant.apache.org/</url>
+ <groupId>org.apache.ant</groupId>
+ <artifactId>ant-netrexx</artifactId>
+ <version>1.9.6</version>
+ <name>Apache Ant + NetRexx</name>
+ <description>NetRexxC task
+ dependency can be downloaded from http://www.ibm.com/software/awdtools/netrexx/download.html</description>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.ant</groupId>
+ <artifactId>ant</artifactId>
+ <version>1.9.6</version>
+ <scope>compile</scope>
+ </dependency>
+ <!-- Processed too early, before maven-antrun-plugin gets a chance to work:
+ <dependency>
+ <groupId>com.ibm.netrexx</groupId>
+ <artifactId>netrexx</artifactId>
+ <version>2.0.5</version>
+ <scope>system</scope>
+ <systemPath>${basedir}/../../../../lib/optional/NetRexxC.jar</systemPath>
+ </dependency>
+ -->
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <includes>
+ <include>org/apache/tools/ant/taskdefs/optional/NetRexxC*</include>
+ </includes>
+ <!-- Need to use this rather than system scope as above: -->
+ <compilerArguments>
+ <extdirs>${basedir}/../../../../lib/optional</extdirs>
+ </compilerArguments>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-antrun-plugin</artifactId>
+ <version>1.4</version>
+ <executions>
+ <execution>
+ <phase>validate</phase>
+ <configuration>
+ <tasks>
+ <ant dir="${basedir}/../../../.." antfile="fetch.xml" target="netrexx">
+ <property name="dest" value="optional"/>
+ </ant>
+ </tasks>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ <sourceDirectory>../../../../src/main</sourceDirectory>
+ <testSourceDirectory>../../../../src/testcases</testSourceDirectory>
+ <outputDirectory>../../../../target/${project.artifactId}/classes</outputDirectory>
+ <testOutputDirectory>../../../../target/${project.artifactId}/testcases</testOutputDirectory>
+ <directory>../../../../target/${project.artifactId}</directory>
+ </build>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/poms/ant-swing/pom.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/poms/ant-swing/pom.xml
new file mode 100644
index 00000000..1fd3e6a8
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/poms/ant-swing/pom.xml
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!--
+ This POM has been created manually by the Ant Development Team.
+ Please contact us if you are not satisfied with the data contained in this POM.
+ URL : http://ant.apache.org
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <parent>
+ <groupId>org.apache.ant</groupId>
+ <artifactId>ant-parent</artifactId>
+ <relativePath>../pom.xml</relativePath>
+ <version>1.9.6</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <url>http://ant.apache.org/</url>
+ <groupId>org.apache.ant</groupId>
+ <artifactId>ant-swing</artifactId>
+ <version>1.9.6</version>
+ <name>Apache Ant + Swing</name>
+ <description>a listener and a splash task based on Swing</description>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.ant</groupId>
+ <artifactId>ant</artifactId>
+ <version>1.9.6</version>
+ <scope>compile</scope>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <includes>
+ <include>org/apache/tools/ant/taskdefs/optional/splash/*</include>
+ </includes>
+ </configuration>
+ </plugin>
+ </plugins>
+ <sourceDirectory>../../../../src/main</sourceDirectory>
+ <testSourceDirectory>../../../../src/testcases</testSourceDirectory>
+ <outputDirectory>../../../../target/${project.artifactId}/classes</outputDirectory>
+ <testOutputDirectory>../../../../target/${project.artifactId}/testcases</testOutputDirectory>
+ <directory>../../../../target/${project.artifactId}</directory>
+ </build>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/poms/ant-testutil/pom.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/poms/ant-testutil/pom.xml
new file mode 100644
index 00000000..0b8c2d56
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/poms/ant-testutil/pom.xml
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!--
+ This POM has been created manually by the Ant Development Team.
+ Please contact us if you are not satisfied with the data contained in this POM.
+ URL : http://ant.apache.org
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <parent>
+ <groupId>org.apache.ant</groupId>
+ <artifactId>ant-parent</artifactId>
+ <relativePath>../pom.xml</relativePath>
+ <version>1.9.6</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <url>http://ant.apache.org/</url>
+ <groupId>org.apache.ant</groupId>
+ <artifactId>ant-testutil</artifactId>
+ <version>1.9.6</version>
+ <name>Apache Ant Test Utilities</name>
+ <description>test utility classes</description>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.ant</groupId>
+ <artifactId>ant</artifactId>
+ <version>1.9.6</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.11</version>
+ <scope>compile</scope>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <includes>
+ <include>org/apache/tools/ant/BuildFileTest*</include>
+ <include>org/apache/tools/ant/util/regexp/RegexpMatcherTest*</include>
+ <include>org/apache/tools/ant/util/regexp/RegexpTest*</include>
+ <include>org/apache/tools/ant/taskdefs/optional/AbstractXSLTLiaisonTest*</include>
+ <include>org/apache/tools/ant/types/AbstractFileSetTest*</include>
+ </includes>
+ </configuration>
+ </plugin>
+ </plugins>
+ <sourceDirectory>../../../../src/tests/junit</sourceDirectory>
+ <outputDirectory>../../../../target/${project.artifactId}/classes</outputDirectory>
+ <directory>../../../../target/${project.artifactId}</directory>
+ </build>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/poms/ant/pom.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/poms/ant/pom.xml
new file mode 100644
index 00000000..087c369c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/poms/ant/pom.xml
@@ -0,0 +1,225 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!--
+ This POM has been created manually by the Ant Development Team.
+ Please contact us if you are not satisfied with the data contained in this POM.
+ URL : http://ant.apache.org
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <parent>
+ <groupId>org.apache.ant</groupId>
+ <artifactId>ant-parent</artifactId>
+ <relativePath>../pom.xml</relativePath>
+ <version>1.9.6</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <url>http://ant.apache.org/</url>
+ <groupId>org.apache.ant</groupId>
+ <artifactId>ant</artifactId>
+ <version>1.9.6</version>
+ <name>Apache Ant Core</name>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.ant</groupId>
+ <artifactId>ant-launcher</artifactId>
+ <version>1.9.6</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.11</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+ <build>
+ <filters>
+ <filter>../../../../target/ant/.build.timestamp.properties</filter>
+ </filters>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <configuration> </configuration>
+ </plugin>
+ <plugin>
+ <artifactId>maven-antrun-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>create-timestamp-file</id>
+ <phase>generate-resources</phase>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ <configuration>
+ <tasks>
+ <tstamp/>
+ <mkdir dir="${project.build.directory}"/>
+ <touch file="${project.build.directory}/.build.timestamp.properties"/>
+ <echo file="${project.build.directory}/.build.timestamp.properties" append="false"
+ message="TODAY=${TODAY}"/>
+ </tasks>
+ </configuration>
+ </execution>
+ <execution>
+ <id>delete-timestamp-file</id>
+ <phase>clean</phase>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ <configuration>
+ <tasks>
+ <delete file="${project.build.directory}/.build.timestamp.properties"/>
+ </tasks>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <excludes>
+ <exclude>org/apache/tools/ant/filters/util/JavaClassHelper*</exclude>
+ <exclude>org/apache/tools/ant/types/resolver/**</exclude>
+ <exclude>org/apache/tools/ant/listener/Log4jListener*</exclude>
+ <exclude>org/apache/tools/ant/listener/CommonsLoggingListener*</exclude>
+ <exclude>org/apache/tools/ant/util/regexp/JakartaRegexp*</exclude>
+ <exclude>org/apache/tools/ant/util/regexp/JakartaOro*</exclude>
+ <exclude>org/apache/tools/ant/taskdefs/email/MimeMailer*</exclude>
+ <exclude>org/apache/tools/ant/launch/**</exclude>
+ <exclude>org/apache/tools/ant/taskdefs/optional/net/FTP*</exclude>
+ <exclude>org/apache/tools/ant/taskdefs/optional/net/RExec*</exclude>
+ <exclude>org/apache/tools/ant/taskdefs/optional/net/TelnetTask*</exclude>
+ <exclude>org/apache/tools/ant/taskdefs/optional/junit/*</exclude>
+ <exclude>org/apache/tools/ant/taskdefs/optional/ssh/*</exclude>
+ <exclude>org/apache/tools/ant/taskdefs/optional/image/*</exclude>
+ <exclude>org/apache/tools/ant/types/optional/image/*</exclude>
+ <exclude>org/apache/tools/ant/taskdefs/optional/Script*</exclude>
+ <exclude>org/apache/tools/ant/taskdefs/optional/script/**</exclude>
+ <exclude>org/apache/tools/ant/types/optional/*Script*</exclude>
+ <exclude>org/apache/tools/ant/util/ScriptRunner.java</exclude>
+ <exclude>org/apache/tools/ant/util/optional/ScriptRunner.java</exclude>
+ <exclude>org/apache/tools/ant/filters/util/JavaClassHelper*</exclude>
+ <exclude>org/apache/tools/ant/util/depend/bcel/*</exclude>
+ <exclude>org/apache/tools/ant/taskdefs/optional/NetRexxC*</exclude>
+ <exclude>org/apache/tools/ant/taskdefs/optional/Xalan2TraceSupport*</exclude>
+ <exclude>org/apache/tools/ant/taskdefs/optional/jdepend/*</exclude>
+ </excludes>
+ <testExcludes>
+ <exclude>org/apache/tools/ant/filters/util/JavaClassHelper*</exclude>
+ <exclude>org/apache/tools/ant/types/resolver/**</exclude>
+ <exclude>org/apache/tools/ant/util/Script*</exclude>
+ <exclude>org/apache/tools/ant/listener/Log4jListener*</exclude>
+ <exclude>org/apache/tools/ant/listener/CommonsLoggingListener*</exclude>
+ <exclude>org/apache/tools/ant/util/regexp/JakartaRegexp*</exclude>
+ <exclude>org/apache/tools/ant/util/regexp/JakartaOro*</exclude>
+ <exclude>org/apache/tools/ant/util/regexp/Jdk14Regexp*</exclude>
+ <exclude>org/apache/tools/ant/taskdefs/email/MimeMailer*</exclude>
+ <exclude>org/apache/tools/ant/launch/**</exclude>
+ <exclude>org/apache/tools/ant/taskdefs/StyleTest*</exclude>
+ <exclude>org/apache/tools/ant/taskdefs/optional/junit/</exclude>
+ <exclude>org/apache/tools/ant/taskdefs/optional/net/FTP*</exclude>
+ <exclude>org/apache/tools/ant/taskdefs/optional/ssh/*</exclude>
+ </testExcludes>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <omitBasedir>true</omitBasedir>
+ <systemProperties>
+ <property>
+ <name>ant.home</name>
+ <value>${env.ANT_HOME}</value>
+ </property>
+ <property>
+ <name>build.tests</name>
+ <value>../../../../target/ant/testcases</value>
+ </property>
+ <property>
+ <name>build.tests.value</name>
+ <value>../../../../target/ant/testcases</value>
+ </property>
+ <property>
+ <name>offline</name>
+ <value>true</value>
+ </property>
+ <property>
+ <name>root</name>
+ <value>../../../..</value>
+ </property>
+ </systemProperties>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-report-plugin</artifactId>
+ </plugin>
+ </plugins>
+ <resources>
+ <resource>
+ <directory>../../../../src/main</directory>
+ <filtering>true</filtering>
+ <includes>
+ <include>org/apache/tools/ant/taskdefs/default.properties</include>
+ <include>org/apache/tools/ant/types/default.properties</include>
+ <include>org/apache/tools/ant/taskdefs/default.properties</include>
+ <include>org/apache/tools/ant/types/conditions/antlib.xml</include>
+ <include>org/apache/tools/ant/defaultManifest.mf</include>
+ <include>org/apache/tools/ant/version.txt</include>
+ </includes>
+ </resource>
+ <resource>
+ <directory>../../../../src/resources</directory>
+ <filtering>true</filtering>
+ <includes>
+ <include>**/antlib.xml</include>
+ </includes>
+ </resource>
+ <resource>
+ <directory>../../../../docs</directory>
+ <filtering>false</filtering>
+ <includes>
+ <include>images/ant_logo_large.gif</include>
+ </includes>
+ </resource>
+ </resources>
+ <testResources>
+ <testResource>
+ <directory>../../../../src/etc/testcases</directory>
+ <filtering>true</filtering>
+ </testResource>
+ <testResource>
+ <directory>../../../../src/main</directory>
+ <filtering>true</filtering>
+ <excludes>
+ <exclude>**/*.java</exclude>
+ </excludes>
+ </testResource>
+ </testResources>
+ <sourceDirectory>../../../../src/main</sourceDirectory>
+ <testSourceDirectory>../../../../src/tests/junit</testSourceDirectory>
+ <outputDirectory>../../../../target/ant/classes</outputDirectory>
+ <testOutputDirectory>../../../../target/ant/testcases</testOutputDirectory>
+ <directory>../../../../target/ant</directory>
+ </build>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/poms/pom.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/poms/pom.xml
new file mode 100644
index 00000000..47a4e328
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/poms/pom.xml
@@ -0,0 +1,151 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!--
+ This POM has been created manually by the Ant Development Team.
+ Please contact us if you are not satisfied with the data contained in this POM.
+ URL : http://ant.apache.org
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.ant</groupId>
+ <artifactId>ant-parent</artifactId>
+ <version>1.9.6</version>
+ <packaging>pom</packaging>
+ <description>master POM</description>
+ <licenses>
+ <license>
+ <name>The Apache Software License, Version 2.0</name>
+ <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
+ <distribution>repo</distribution>
+ </license>
+ </licenses>
+ <name>Apache Ant</name>
+ <url>http://ant.apache.org/</url>
+ <inceptionYear>2000</inceptionYear>
+ <organization>
+ <name>The Apache Software Foundation</name>
+ <url>http://www.apache.org/</url>
+ </organization>
+ <distributionManagement>
+ <!-- Null out inherited apache distribution repo by default -->
+ <repository>
+ <id>dummy</id>
+ <name>Dummy to avoid accidental deploys</name>
+ <url>http://nowhere.net/</url>
+ </repository>
+ </distributionManagement>
+ <scm>
+ <connection>scm:git:https://git-wip-us.apache.org/repos/asf/ant.git</connection>
+ <developerConnection>scm:git:https://git-wip-us.apache.org/repos/asf/ant.git</developerConnection>
+ <url>https://git-wip-us.apache.org/repos/asf/ant.git</url>
+ </scm>
+ <ciManagement>
+ <system>hudson</system>
+ <url>https://builds.apache.org/job/Ant_BuildFromPOMs/</url>
+ </ciManagement>
+ <mailingLists>
+ <mailingList>
+ <name>Ant Developers List</name>
+ <subscribe>dev-subscribe@ant.apache.org</subscribe>
+ <unsubscribe>dev-unsubscribe@ant.apache.org</unsubscribe>
+ <post>dev@ant.apache.org</post>
+ <archive>http://mail-archives.apache.org/mod_mbox/ant-dev</archive>
+ </mailingList>
+ <mailingList>
+ <name>Ant Users List</name>
+ <subscribe>user-subscribe@ant.apache.org</subscribe>
+ <unsubscribe>user-unsubscribe@ant.apache.org</unsubscribe>
+ <post>user@ant.apache.org</post>
+ <archive>http://mail-archives.apache.org/mod_mbox/ant-user</archive>
+ </mailingList>
+ </mailingLists>
+ <issueManagement>
+ <system>bugzilla</system>
+ <url>http://issues.apache.org/bugzilla/</url>
+ </issueManagement>
+ <modules>
+ <module>ant</module>
+ <module>ant-antlr</module>
+ <module>ant-apache-bcel</module>
+ <module>ant-apache-bsf</module>
+ <module>ant-apache-log4j</module>
+ <module>ant-apache-oro</module>
+ <module>ant-apache-regexp</module>
+ <module>ant-apache-resolver</module>
+ <module>ant-apache-xalan2</module>
+ <module>ant-commons-logging</module>
+ <module>ant-commons-net</module>
+ <module>ant-jai</module>
+ <module>ant-javamail</module>
+ <module>ant-jdepend</module>
+ <module>ant-jmf</module>
+ <module>ant-jsch</module>
+ <module>ant-junit</module>
+ <module>ant-junit4</module>
+ <module>ant-launcher</module>
+ <module>ant-netrexx</module>
+ <module>ant-swing</module>
+ <module>ant-testutil</module>
+ </modules>
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>3.8.2</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+ <build>
+ <sourceDirectory>../../../src/main</sourceDirectory>
+ <testSourceDirectory>../../../src/testcases</testSourceDirectory>
+ <outputDirectory>../../../target/classes</outputDirectory>
+ <testOutputDirectory>../../../target/testcases</testOutputDirectory>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>2.3.2</version>
+ <configuration>
+ <source>1.5</source>
+ <target>1.5</target>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <version>2.4</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>2.12</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-report-plugin</artifactId>
+ <version>2.12</version>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ </properties>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/printFailingTests.xsl b/framework/src/ant/apache-ant-1.9.6/src/etc/printFailingTests.xsl
new file mode 100644
index 00000000..7d323404
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/printFailingTests.xsl
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<!--
+ This stylesheet is for work in build.xml:printFailingTests.
+ It extracts all failing tests from a given testsuite (JUnit+AntUnit XML format)
+ and writes that into a text file.
+ All text files are written to STDOUT via <concat>.
+-->
+<xsl:stylesheet
+ version="1.0"
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+
+ <!-- Output format so no XML header would be written -->
+ <xsl:output indent="no" method="text" encoding="ISO-8859-1"/>
+ <!-- What is the name of the current testsuite (JUnit class or AntUnit buildfile) -->
+ <xsl:variable name="testsuite" select="/testsuite/@name"/>
+
+
+<!-- failing tests: suitename.testname : message; Leading pipe for line break -->
+<xsl:template match="testcase[failure|error]">
+| <xsl:value-of select="$testsuite"/>.<xsl:value-of select="@name"/>() : <xsl:value-of select="failure/@message"/><xsl:value-of select="error/@message"/>
+</xsl:template>
+
+<!-- Suppress log output from the tests like stacktraces -->
+<xsl:template match="text()"/>
+
+
+</xsl:stylesheet>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/tagdiff.xsl b/framework/src/ant/apache-ant-1.9.6/src/etc/tagdiff.xsl
new file mode 100644
index 00000000..5d430a79
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/tagdiff.xsl
@@ -0,0 +1,179 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!-- a stylesheet to display changelogs ala netbeans -->
+<xsl:stylesheet
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ version="1.0">
+ <xsl:param name="title"/>
+ <xsl:param name="module"/>
+ <xsl:param name="cvsweb"/>
+
+ <xsl:output method="html" indent="yes"/>
+
+ <!-- Copy standard document elements. Elements that
+ should be ignored must be filtered by apply-templates
+ tags. -->
+ <xsl:template match="*">
+ <xsl:copy>
+ <xsl:copy-of select="attribute::*[. != '']"/>
+ <xsl:apply-templates/>
+ </xsl:copy>
+ </xsl:template>
+
+ <xsl:template match="tagdiff">
+ <html>
+ <head>
+ <title><xsl:value-of select="$title"/></title>
+ <style type="text/css">
+ body, p {
+ font-family: verdana,arial,helvetica;
+ font-size: 80%;
+ color:#000000;
+ }
+ .dateAndAuthor {
+ font-family: verdana,arial,helvetica;
+ font-size: 80%;
+ font-weight: bold;
+ text-align:left;
+ background:#a6caf0;
+ }
+ tr, td{
+ font-family: verdana,arial,helvetica;
+ font-size: 80%;
+ background:#eeeee0;
+ }
+ </style>
+ </head>
+ <body link="#000000" alink="#000000" vlink="#000000" text="#000000">
+ <h1>
+ <a name="top"><xsl:value-of select="$title"/></a>
+ </h1>
+ Tagdiff between <xsl:value-of select="@startTag"/> <xsl:value-of select="@startDate"/> and
+ <xsl:value-of select="@endTag"/> <xsl:value-of select="@endDate"/>
+ <p align="right">Designed for use with <a href="http://ant.apache.org/">Ant</a>.</p>
+ <hr size="2"/>
+ <a name="TOP"/>
+ <table width="100%">
+ <tr>
+ <td align="right">
+ <a href="#New">New Files</a> |
+ <a href="#Modified">Modified Files</a> |
+ <a href="#Removed">Removed Files</a>
+ </td>
+ </tr>
+ </table>
+ <table border="0" width="100%" cellpadding="3" cellspacing="1">
+ <xsl:call-template name="show-entries">
+ <xsl:with-param name="title">New Files</xsl:with-param>
+ <xsl:with-param name="anchor">New</xsl:with-param>
+ <xsl:with-param name="entries" select=".//entry[file/revision][not(file/prevrevision)]"/>
+ </xsl:call-template>
+
+ <xsl:call-template name="show-entries">
+ <xsl:with-param name="title">Modified Files</xsl:with-param>
+ <xsl:with-param name="anchor">Modified</xsl:with-param>
+ <xsl:with-param name="entries" select=".//entry[file/revision][file/prevrevision]"/>
+ </xsl:call-template>
+
+ <!-- change to entries select to address bug #36827 -->
+ <xsl:call-template name="show-entries">
+ <xsl:with-param name="title">Removed Files</xsl:with-param>
+ <xsl:with-param name="anchor">Removed</xsl:with-param>
+ <xsl:with-param name="entries" select=".//entry[not(file/revision)][file/prevrevision]"/>
+ </xsl:call-template>
+ </table>
+
+ </body>
+ </html>
+ </xsl:template>
+
+ <xsl:template name="show-entries">
+ <xsl:param name="title"/>
+ <xsl:param name="anchor"/>
+ <xsl:param name="entries"/>
+ <tr>
+ <td colspan="2" class="dateAndAuthor">
+ <a>
+ <xsl:attribute name="name"><xsl:value-of select="$anchor"/></xsl:attribute>
+ <xsl:value-of select="$title"/> - <xsl:value-of select="count($entries)"/> entries
+ </a>
+ <a href="#TOP">(back to top)</a>
+ </td>
+ </tr>
+ <tr>
+ <td width="20">
+ <xsl:text> </xsl:text>
+ </td>
+ <td>
+ <ul>
+ <xsl:apply-templates select="$entries"/>
+ </ul>
+ </td>
+ </tr>
+ </xsl:template>
+
+ <xsl:template match="entry">
+ <xsl:apply-templates select="file"/>
+ </xsl:template>
+
+ <xsl:template match="date">
+ <i><xsl:value-of select="."/></i>
+ </xsl:template>
+
+ <xsl:template match="time">
+ <i><xsl:value-of select="."/></i>
+ </xsl:template>
+
+ <xsl:template match="author">
+ <i>
+ <a>
+ <xsl:attribute name="href">mailto:<xsl:value-of select="."/></xsl:attribute>
+ <xsl:value-of select="."/>
+ </a>
+ </i>
+ </xsl:template>
+
+ <xsl:template match="file">
+ <li>
+ <a target="_new">
+ <xsl:attribute name="href"><xsl:value-of select="$cvsweb"/><xsl:value-of select="$module" />/<xsl:value-of select="name" /></xsl:attribute>
+ <xsl:value-of select="name" />
+ </a>
+ <xsl:if test="string-length(prevrevision) > 0 or string-length(revision) > 0">
+ <xsl:text> </xsl:text>
+ <a target="_new">
+ <xsl:choose>
+ <xsl:when test="string-length(prevrevision) = 0 ">
+ <xsl:attribute name="href"><xsl:value-of select="$cvsweb"/><xsl:value-of select="$module" />/<xsl:value-of select="name" />?rev=<xsl:value-of select="revision" />&amp;content-type=text/x-cvsweb-markup</xsl:attribute>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:attribute name="href"><xsl:value-of select="$cvsweb"/><xsl:value-of select="$module" />/<xsl:value-of select="name" />?r1=<xsl:value-of select="revision" />&amp;r2=<xsl:value-of select="prevrevision"/>&amp;diff_format=h</xsl:attribute>
+ </xsl:otherwise>
+ </xsl:choose> (<xsl:if test="count(prevrevision) &gt; 0"> <xsl:value-of select="prevrevision"/> --&gt; </xsl:if> <xsl:value-of select="revision"/>)
+ </a>
+ </xsl:if>
+ </li>
+ </xsl:template>
+
+ <!-- Any elements within a msg are processed,
+ so that we can preserve HTML tags. -->
+ <xsl:template match="msg">
+ <b><xsl:apply-templates/></b>
+ </xsl:template>
+
+</xsl:stylesheet>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/asf-logo.gif b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/asf-logo.gif
new file mode 100644
index 00000000..22eb9d73
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/asf-logo.gif
Binary files differ
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/buildfiletest-base.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/buildfiletest-base.xml
new file mode 100644
index 00000000..fc1e8b0b
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/buildfiletest-base.xml
@@ -0,0 +1,11 @@
+<project name="buildfiletest-base">
+ <property name="buildfiletest.tmpdir" location="${java.io.tmpdir}"/>
+ <property name="input" location="${buildfiletest.tmpdir}/testinput_${ant.processid}_${ant.threadname}"/>
+ <property name="output" location="${buildfiletest.tmpdir}/testoutput_${ant.processid}_${ant.threadname}"/>
+
+ <target name="tearDown">
+ <delete dir="${input}"/>
+ <delete dir="${output}"/>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/antclassloader.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/antclassloader.xml
new file mode 100644
index 00000000..cafc823b
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/antclassloader.xml
@@ -0,0 +1,80 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="antclassloader-test" basedir=".">
+ <import file="../buildfiletest-base.xml"/>
+ <property name="tmp.dir" location="${output}/tmp space"/>
+ <!-- ant for germans -->
+ <property name="tmp.dir.nonascii" value="${output}/&#0227;nt"/>
+ <property name="ext.dir.relative" value="ext"/>
+ <property name="main.jar" location="${tmp.dir}/main.jar"/>
+ <property name="ext.jar.relative" value="${ext.dir.relative}/ext.jar"/>
+ <property name="ext.jar" location="${tmp.dir}/${ext.jar.relative}"/>
+ <property name="build.sysclasspath" value="first"/>
+ <property name="main.jar.nonascii" location="${tmp.dir.nonascii}/main.jar"/>
+ <property name="ext.jar.nonascii" location="${tmp.dir.nonascii}/${ext.jar.relative}"/>
+ <target name="setUp" depends="setup.withspace,setup.nonascii"/>
+
+ <target name="setup.withspace">
+ <mkdir dir="${tmp.dir}/${ext.dir.relative}"/>
+ <jar destfile="${main.jar}" whenempty="create">
+ <manifest>
+ <attribute name="Class-Path" value="${ext.jar.relative}"/>
+ </manifest>
+ </jar>
+ <jar destfile="${ext.jar}"/>
+ </target>
+ <target name="setup.nonascii">
+ <mkdir dir="${tmp.dir.nonascii}/${ext.dir.relative}"/>
+ <jar destfile="${main.jar.nonascii}" whenempty="create">
+ <manifest>
+ <attribute name="Class-Path" value="${ext.jar.relative}"/>
+ </manifest>
+ </jar>
+ <jar destfile="${ext.jar.nonascii}"/>
+
+ </target>
+
+
+ <target name="prepareGetPackageTest" depends="setUp">
+ <mkdir dir="${tmp.dir.nonascii}/org/example"/>
+ <echo file="${tmp.dir.nonascii}/org/example/Foo.java"><![CDATA[
+package org.example;
+public class Foo {}
+]]></echo>
+ <available property="jdk1.6+" classname="java.net.CookieStore"/>
+ <condition property="source" value="6">
+ <isset property="jdk1.6+"/>
+ </condition>
+ <property name="source" value="1.4"/>
+ <javac srcdir="${tmp.dir.nonascii}"
+ destdir="${tmp.dir.nonascii}" source="${source}"/>
+ <tempfile property="test.jar" destdir="${tmp.dir}" suffix="test" prefix=".jar" deleteonexit="true"/>
+ <jar destfile="${test.jar}">
+ <fileset dir="${tmp.dir.nonascii}" includes="**/*.class"/>
+ </jar>
+ </target>
+
+ <target name="signTestJar" depends="prepareGetPackageTest">
+ <signjar alias="testonly" keystore="../testkeystore"
+ storepass="apacheant" jar="${test.jar}"/>
+ </target>
+
+ <target name="createNonJar">
+ <touch file="${tmp.dir}/foo.jar"/>
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/case.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/case.xml
new file mode 100644
index 00000000..ea4ac1d1
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/case.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<project name="parsing-test" basedir="." default="help">
+
+ <target name="help">
+ <echo>
+This build file is intended to be used for testing Ant
+ </echo>
+ </target>
+
+ <target name="case-sensitivity">
+ <concat>
+ <fileSet dir="." includes="parse.xml"/>
+ </concat>
+ </target>
+
+ <target name="taskcase">
+ <ecHO>Should fail</ecHO>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/containersrc/test/SpecialSeq.java b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/containersrc/test/SpecialSeq.java
new file mode 100644
index 00000000..ae6a3dd9
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/containersrc/test/SpecialSeq.java
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package test;
+
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.TaskContainer;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.types.FileSet;
+import org.apache.tools.ant.taskdefs.Echo;
+import java.util.*;
+
+public class SpecialSeq extends Task implements TaskContainer {
+ /** Optional Vector holding the nested tasks */
+ private Vector nestedTasks = new Vector();
+
+ private FileSet fileset;
+
+ private Echo nestedEcho;
+
+ /**
+ * Add a nested task.
+ * <p>
+ * @param nestedTask Nested task to execute
+ * <p>
+ */
+ public void addTask(Task nestedTask) {
+ nestedTasks.addElement(nestedTask);
+ }
+
+ /**
+ * Execute all nestedTasks.
+ */
+ public void execute() throws BuildException {
+ if (fileset == null || fileset.getDir(getProject()) == null) {
+ throw new BuildException("Fileset was not configured");
+ }
+ for (Enumeration e = nestedTasks.elements(); e.hasMoreElements();) {
+ Task nestedTask = (Task) e.nextElement();
+ nestedTask.perform();
+ }
+ nestedEcho.reconfigure();
+ nestedEcho.perform();
+ }
+
+ public void addFileset(FileSet fileset) {
+ this.fileset = fileset;
+ }
+
+ public void addNested(Echo nestedEcho) {
+ this.nestedEcho = nestedEcho;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/directoryscanner.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/directoryscanner.xml
new file mode 100644
index 00000000..7e8683a4
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/directoryscanner.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="directoryscanner-test" basedir=".">
+ <import file="../buildfiletest-base.xml"/>
+
+ <target name="setUp">
+ <mkdir dir="${output}/alpha/beta/gamma"/>
+ <touch file="${output}/alpha/beta/gamma/gamma.xml"/>
+ <touch file="${output}/alpha/beta/beta.xml"/>
+ </target>
+
+ <target name="extended-setup" depends="setUp">
+ <mkdir dir="${output}/delta"/>
+ <touch file="${output}/delta/delta.xml"/>
+ </target>
+
+ <target name="children-of-excluded-dir-setup" depends="extended-setup" />
+
+ <target name="symlink-setup" depends="setUp">
+ <mkdir dir="${output}/epsilon/gamma"/>
+ <delete dir="${output}/alpha/beta"/>
+ <symlink link="${output}/alpha/beta" resource="${output}/epsilon"/>
+ <touch file="${output}/alpha/beta/gamma/gamma.xml"/>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/dispatch/dispatch.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/dispatch/dispatch.xml
new file mode 100644
index 00000000..d529644d
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/dispatch/dispatch.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<project name="dispatch-test" default="disp">
+
+ <path id="testclasses">
+ <pathelement location="../../../../build/testcases" />
+ <pathelement path="${java.class.path}" />
+ </path>
+
+ <target name="disp">
+ <taskdef name="disptask"
+ classname="org.apache.tools.ant.taskdefs.PickOneTask">
+ <classpath refid="testclasses" />
+ </taskdef>
+ <disptask action="list"/>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/duplicate-target-imported.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/duplicate-target-imported.xml
new file mode 100644
index 00000000..fc945f71
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/duplicate-target-imported.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<project>
+ <target name="once">
+ <echo>once from imported</echo>
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/duplicate-target.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/duplicate-target.xml
new file mode 100644
index 00000000..0a295262
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/duplicate-target.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<project>
+ <target name="once">
+ <echo>once</echo>
+ </target>
+
+ <target name="twice">
+ <echo>twice-a</echo>
+ </target>
+
+ <target name="twice">
+ <echo>twice-b</echo>
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/duplicate-target2.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/duplicate-target2.xml
new file mode 100644
index 00000000..6d96bca4
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/duplicate-target2.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<project>
+
+ <import file="duplicate-target-imported.xml"/>
+
+ <target name="once">
+ <echo>once from buildfile</echo>
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/executor.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/executor.xml
new file mode 100644
index 00000000..080c8dc7
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/executor.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project>
+ <target name="foo">
+ <echo>foo</echo>
+ <fail if="failfoo" message="failfoo" />
+ </target>
+ <target name="a" depends="foo">
+ <echo>a</echo>
+ </target>
+ <target name="b" depends="foo">
+ <echo>b</echo>
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/extended-taskdef.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/extended-taskdef.xml
new file mode 100644
index 00000000..58ca9798
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/extended-taskdef.xml
@@ -0,0 +1,73 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="extended-taskdef" default="testRun">
+
+ <description>
+ Try and replicate a reported problem.
+
+ </description>
+ <property name="src" value="Foo.java"/>
+ <property name="taskdefs" value="tasks.properties"/>
+
+ <target name="write" >
+ <echo file="${src}">
+ import org.apache.tools.ant.BuildException;
+
+ public class Foo extends org.apache.tools.ant.taskdefs.WaitFor {
+
+ public void execute() {
+ throw new BuildException("executing the Foo task");
+ }
+ }
+ </echo>
+ <propertyfile file="${taskdefs}">
+ <entry key="foo2" value="Foo"/>
+ </propertyfile>
+ </target>
+
+ <target name="compile" depends="write">
+ <javac srcdir="${basedir}" includes="${src}"/>
+ </target>
+
+ <target name="testRun" depends="compile">
+ <taskdef name="foo" classname="Foo"
+ classpath="${basedir}"/>
+ <foo maxwait="5" maxwaitunit="second"
+ timeoutproperty="foo">
+ <or/>
+ </foo>
+ </target>
+
+ <target name="testRun2" depends="compile">
+ <taskdef resource="${taskdefs}" classpath="${basedir}"/>
+ <foo2 maxwait="5" maxwaitunit="second"
+ timeoutproperty="foo">
+ <or/>
+ </foo2>
+ </target>
+
+
+ <target name="teardown">
+ <delete>
+ <fileset dir="${basedir}"
+ includes="${src},*.class"/>
+ </delete>
+ <delete file="${taskdefs}" />
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/immutable.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/immutable.xml
new file mode 100644
index 00000000..26fda087
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/immutable.xml
@@ -0,0 +1,79 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<project name="immutable-test" basedir="." default="test1">
+
+ <target name="test1">
+ <property name="test" value="original"/>
+ <available file="immutable.xml" property="test" value="override"/>
+ </target>
+
+ <target name="test2">
+ <tstamp/>
+ <tstamp prefix="start"/>
+ </target>
+
+ <target name="test3">
+ <property name="DSTAMP" value="original"/>
+ <tstamp/>
+ </target>
+
+ <target name="test4">
+ <property name="test" value="original"/>
+ <condition property="test" value="override">
+ <equals arg1="1" arg2="1"/>
+ </condition>
+ </target>
+
+ <target name="test5">
+ <property name="test" value="original"/>
+ <checksum file="immutable.xml" verifyProperty="test"/>
+ </target>
+
+ <target name="test6">
+ <property name="test1" value="original"/>
+ <property name="test2" value="original"/>
+ <!-- How to make this cross-platform? -->
+ <exec executable="cmd.exe" os="Windows 2000" outputproperty="test1" resultProperty="test2">
+ <arg line="/c dir"/>
+ </exec>
+ </target>
+
+ <target name="test7">
+ <property name="test" value="original"/>
+ <pathconvert targetos="unix" property="test" >
+ <path>
+ <pathelement location="/lib/weblogicaux.jar" />
+ <pathelement location="/classes" />
+ <pathelement location="/mssqlserver4/classes" />
+ <pathelement location="c:\winnt\System32" />
+ </path>
+ </pathconvert>
+ </target>
+
+ <target name="test8">
+ <antcall inheritAll="false" target="echo-target">
+ <param name="echo.value" value="Meep meep!" />
+ </antcall>
+ </target>
+
+ <target name="echo-target">
+ <echo message="Value of echo=${echo.value}"/>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/include/basic/include.inc b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/include/basic/include.inc
new file mode 100644
index 00000000..960792d4
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/include/basic/include.inc
@@ -0,0 +1,20 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<target name="test1">
+ <echo message="from included entity"/>
+</target>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/include/basic/include.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/include/basic/include.xml
new file mode 100644
index 00000000..2c131b1b
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/include/basic/include.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<!DOCTYPE project [
+ <!ENTITY include SYSTEM "file:./include.inc">
+]>
+
+<project name="include-test" basedir="." default="test1">
+ &include;
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/include/basic/relative.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/include/basic/relative.xml
new file mode 100644
index 00000000..697c8417
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/include/basic/relative.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+
+<!DOCTYPE project [
+ <!ENTITY include SYSTEM "./include.inc">
+]>
+
+<project name="include-test" basedir="." default="test1">
+ &include;
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/include/frag#ment/include.inc b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/include/frag#ment/include.inc
new file mode 100644
index 00000000..960792d4
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/include/frag#ment/include.inc
@@ -0,0 +1,20 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<target name="test1">
+ <echo message="from included entity"/>
+</target>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/include/frag#ment/include.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/include/frag#ment/include.xml
new file mode 100644
index 00000000..400a15c0
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/include/frag#ment/include.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+
+<!DOCTYPE project [
+ <!ENTITY include SYSTEM "file:include.inc">
+]>
+
+<project name="include-test" basedir="." default="test1">
+ &include;
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/include/frag#ment/relative.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/include/frag#ment/relative.xml
new file mode 100644
index 00000000..05bbc9e6
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/include/frag#ment/relative.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+
+<!DOCTYPE project [
+ <!ENTITY include SYSTEM "include.inc">
+]>
+
+<project name="include-test" basedir="." default="test1">
+ &include;
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/include/frag#ment/simple.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/include/frag#ment/simple.xml
new file mode 100644
index 00000000..d337234f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/include/frag#ment/simple.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<project name="include-test" basedir="." default="test1">
+<target name="test1">
+ <echo message="from simple buildfile"/>
+</target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/include/included_file_parse_error/build.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/include/included_file_parse_error/build.xml
new file mode 100644
index 00000000..d75747c0
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/include/included_file_parse_error/build.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!DOCTYPE project [
+ <!ENTITY included_file SYSTEM "file:./included_file.xml">
+]>
+
+<project name="test" default="test" basedir=".">
+
+ <target name="setup">
+ </target>
+
+ &included_file;
+
+ <target name="test" depends="included-target">
+ <echo>test target ran.</echo>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/include/included_file_parse_error/included_file.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/include/included_file_parse_error/included_file.xml
new file mode 100644
index 00000000..5fbd3f56
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/include/included_file_parse_error/included_file.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<target name="included-target">
+ extraneous_text
+ <echo>included-target ran.</echo>
+</target>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/include/included_file_task_error/build.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/include/included_file_task_error/build.xml
new file mode 100644
index 00000000..d75747c0
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/include/included_file_task_error/build.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!DOCTYPE project [
+ <!ENTITY included_file SYSTEM "file:./included_file.xml">
+]>
+
+<project name="test" default="test" basedir=".">
+
+ <target name="setup">
+ </target>
+
+ &included_file;
+
+ <target name="test" depends="included-target">
+ <echo>test target ran.</echo>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/include/included_file_task_error/included_file.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/include/included_file_task_error/included_file.xml
new file mode 100644
index 00000000..d40d3970
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/include/included_file_task_error/included_file.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<target name="included-target">
+ <copy file="nonexistent-file" todir="/non/existent/dir"/>
+ <echo>included-target ran.</echo>
+</target>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/include/including_file_parse_error/build.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/include/including_file_parse_error/build.xml
new file mode 100644
index 00000000..7de52648
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/include/including_file_parse_error/build.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!DOCTYPE project [
+ <!ENTITY included_file SYSTEM "file:./included_file.xml">
+]>
+
+<project name="test" default="test" basedir=".">
+
+ <target name="setup">
+ </target>
+
+ &included_file;
+
+ extraneous_text
+
+ <target name="test" depends="included-target">
+ <echo>test target ran.</echo>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/include/including_file_parse_error/included_file.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/include/including_file_parse_error/included_file.xml
new file mode 100644
index 00000000..c607bbcc
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/include/including_file_parse_error/included_file.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<target name="included-target">
+ <echo>included-target ran.</echo>
+</target>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/include/including_file_task_error/build.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/include/including_file_task_error/build.xml
new file mode 100644
index 00000000..687b8cf3
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/include/including_file_task_error/build.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!DOCTYPE project [
+ <!ENTITY included_file SYSTEM "file:./included_file.xml">
+]>
+
+<project name="test" default="test" basedir=".">
+
+ <target name="setup">
+ </target>
+
+ &included_file;
+
+ <target name="test" depends="included-target">
+ <copy file="nonexistent-file" todir="/non/existent/dir"/>
+ <echo>test target ran.</echo>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/include/including_file_task_error/included_file.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/include/including_file_task_error/included_file.xml
new file mode 100644
index 00000000..c607bbcc
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/include/including_file_task_error/included_file.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<target name="included-target">
+ <echo>included-target ran.</echo>
+</target>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/include/with space/include.inc b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/include/with space/include.inc
new file mode 100644
index 00000000..d8fd638b
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/include/with space/include.inc
@@ -0,0 +1,19 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<target name="test1">
+ <echo message="from included entity in &apos;with space&apos;"/>
+</target>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/include/with space/include.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/include/with space/include.xml
new file mode 100644
index 00000000..4b693cdc
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/include/with space/include.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<!DOCTYPE project [
+ <!ENTITY include SYSTEM "file:include.inc">
+]>
+
+<project name="include-test" basedir="." default="test1">
+ &include;
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/include/with space/relative.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/include/with space/relative.xml
new file mode 100644
index 00000000..81f502a9
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/include/with space/relative.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<!DOCTYPE project [
+ <!ENTITY include SYSTEM "include.inc">
+]>
+
+<project name="include-test" basedir="." default="test1">
+ &include;
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/include/with space/simple.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/include/with space/simple.xml
new file mode 100644
index 00000000..4092ce75
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/include/with space/simple.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="include-test" basedir="." default="test1">
+ <target name="test1">
+ <echo message="from simple buildfile in &apos;with space&apos;"/>
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/loaderref/loaderref.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/loaderref/loaderref.xml
new file mode 100644
index 00000000..83974979
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/loaderref/loaderref.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<project name="loaderref-test" default="help">
+
+ <property name="src.dir" value="src"/>
+
+ <import file="../../buildfiletest-base.xml"/>
+
+ <target name="setUp">
+ <mkdir dir="${output}"/>
+ </target>
+
+ <target name="help">
+ <echo>
+This build file is intended to be used for testing Ant
+ </echo>
+ </target>
+
+ <target name="compile">
+ <javac srcdir="${src.dir}" destdir="${output}"/>
+ </target>
+
+ <target name="testbadref" depends="compile" >
+ <taskdef loaderref="loaderref-test"
+ name="test1"
+ classname="Test1"
+ classpath="${output}"/>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/loaderref/src/Task1.java b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/loaderref/src/Task1.java
new file mode 100644
index 00000000..cb374bd2
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/loaderref/src/Task1.java
@@ -0,0 +1,21 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+import org.apache.tools.ant.Task;
+
+public class Task1 extends Task {
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/location.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/location.xml
new file mode 100644
index 00000000..7e8f6394
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/location.xml
@@ -0,0 +1,74 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="location" default="all">
+ <target name="all">
+ <fail>Only use this build file from within tests</fail>
+ </target>
+
+ <target name="testPlainTask">
+ <echo id="echo">Hello</echo>
+ </target>
+
+ <target name="testStandaloneType">
+ <echo id="echo2">Hello</echo>
+ <fileset id="fs" dir="."/>
+ </target>
+
+ <target name="testConditionTask">
+ <condition property="foo" id="cond">
+ <equals arg1="bar" arg2="baz"/>
+ </condition>
+ </target>
+
+ <target name="define">
+ <property name="testclasses"
+ location="../../../../build/testcases" />
+ <taskdef name="echoloc"
+ classname="org.apache.tools.ant.LocationTest$EchoLocation">
+ <classpath>
+ <pathelement location="${testclasses}" />
+ <pathelement path="${java.class.path}"/>
+ </classpath>
+ </taskdef>
+ </target>
+
+ <target name="macrodef" depends="define">
+ <macrodef name="echoloc2" backtrace="false">
+ <sequential>
+ <echoloc/>
+ </sequential>
+ </macrodef>
+ </target>
+
+ <target name="testMacrodefWrappedTask" depends="macrodef">
+ <echo id="echo3">Hello</echo>
+ <echoloc2/>
+ </target>
+
+ <target name="presetdef" depends="define">
+ <presetdef name="echoloc3">
+ <echoloc/>
+ </presetdef>
+ </target>
+
+ <target name="testPresetdefWrappedTask" depends="presetdef">
+ <echo id="echo4">Hello</echo>
+ <echoloc3/>
+ </target>
+
+</project> \ No newline at end of file
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/taskcontainer.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/taskcontainer.xml
new file mode 100644
index 00000000..4a213730
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/taskcontainer.xml
@@ -0,0 +1,62 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="dont-run-this">
+
+ <import file="../buildfiletest-base.xml"/>
+
+ <target name="dont-run-this">
+ <fail>This build file is supposed to be run by a Unit test</fail>
+ </target>
+
+
+ <target name="testPropertyExpansion">
+ <sequential>
+ <property name="foo" value="it worked"/>
+ <echo message="As attribute: ${foo}"/>
+ <echo>As nested text: ${foo}</echo>
+ </sequential>
+ </target>
+
+ <target name="testTaskdef">
+ <mkdir dir="${output}"/>
+ <javac srcdir="containersrc" destdir="${output}" debug="on"/>
+
+ <sequential>
+ <taskdef name="sseq" classpath="${output}" classname="test.SpecialSeq"/>
+ <sseq>
+ <fileset dir="."/>
+ <property name="foo" value="it worked"/>
+ <echo message="As attribute: ${foo}"/>
+ <echo>As nested text: ${foo}</echo>
+ <nested message="As nested task: ${foo}"/>
+ </sseq>
+ </sequential>
+ </target>
+
+ <target name="testCaseInsensitive">
+ <taskdef name="Prattle" classname="org.apache.tools.ant.taskdefs.Echo"/>
+ <taskdef name="Seq"
+ classname="org.apache.tools.ant.taskdefs.Sequential"/>
+ <Prattle>hello</Prattle>
+ <Seq>
+ <Prattle> world</Prattle>
+ </Seq>
+ </target>
+
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/topleveltasks/notarget.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/topleveltasks/notarget.xml
new file mode 100644
index 00000000..25437515
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/topleveltasks/notarget.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="foo">
+ <echo message="Called" />
+ <target name="foo" />
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/topleveltasks/targetlevelant.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/topleveltasks/targetlevelant.xml
new file mode 100644
index 00000000..9b1bb1df
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/topleveltasks/targetlevelant.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project basedir="." default="foo">
+ <target name="foo">
+ <ant antfile="notarget.xml" />
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/topleveltasks/toplevelant.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/topleveltasks/toplevelant.xml
new file mode 100644
index 00000000..968ad6c1
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/topleveltasks/toplevelant.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project basedir="." default="foo">
+ <ant antfile="notarget.xml" />
+ <target name="foo" />
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/unknownelement.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/unknownelement.xml
new file mode 100644
index 00000000..b6d89394
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/core/unknownelement.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project>
+ <target name="testMaybeConfigure">
+ <taskdef name="parent"
+ classname="org.apache.tools.ant.UnknownElementTest$Parent"
+ loaderref="unknown.id">
+ <classpath>
+ <pathelement location="../../../../build/testcases"/>
+ <pathelement path="${java.class.path}"/>
+ </classpath>
+ </taskdef>
+ <taskdef name="child"
+ classname="org.apache.tools.ant.UnknownElementTest$Child"
+ loaderref="unknown.id"/>
+ <parent>
+ <child/>
+ <child/>
+ </parent>
+ </target>
+ <target name="echo">
+ <echo message="Hello, world!"/>
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/build.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/build.xml
new file mode 100644
index 00000000..b70b7786
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/build.xml
@@ -0,0 +1,147 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="tearDown" basedir=".">
+ <import file="../buildfiletest-base.xml"/>
+ <target name="setUp">
+ <mkdir dir="${output}" />
+ </target>
+
+
+ <target name="testLineContains" depends="setUp">
+ <copy todir="${output}">
+ <fileset dir="input">
+ <include name="linecontains.test"/>
+ </fileset>
+ <filterchain>
+ <filterreader classname="org.apache.tools.ant.filters.LineContains">
+ <param type="contains" value="beta"/>
+ </filterreader>
+ </filterchain>
+ </copy>
+ </target>
+
+ <target name="testNegateLineContains" depends="setUp">
+ <copy file="input/linecontains.test"
+ tofile="${output}/negatelinecontains.test">
+ <filterchain>
+ <filterreader classname="org.apache.tools.ant.filters.LineContains">
+ <param type="negate" value="true"/>
+ <param type="contains" value="beta"/>
+ </filterreader>
+ </filterchain>
+ </copy>
+ <fail>
+ <condition>
+ <not>
+ <filesmatch file1="${output}/negatelinecontains.test"
+ file2="expected/negatelinecontains.test" />
+ </not>
+ </condition>
+ </fail>
+ </target>
+
+ <target name="testEscapeUnicode" depends="setUp">
+ <copy todir="${output}" encoding="UTF-8">
+ <fileset dir="input">
+ <include name="escapeunicode.test"/>
+ </fileset>
+ <filterchain>
+ <escapeunicode/>
+ </filterchain>
+ </copy>
+ <fixcrlf srcdir="${output}" eol="crlf">
+ <include name="escapeunicode.test"/>
+ </fixcrlf>
+ </target>
+
+ <target name="testStripJavaComments" depends="setUp">
+ <copy todir="${output}">
+ <fileset dir="input" includes="stripjavacomments.test" />
+ <filterchain>
+ <filterreader classname="org.apache.tools.ant.filters.StripJavaComments" />
+ </filterchain>
+ </copy>
+ </target>
+
+ <target name="testReplaceTokens" depends="setUp">
+ <copy todir="${output}">
+ <fileset dir="input" includes="replacetokens.test" />
+ <filterchain>
+ <replacetokens>
+ <token key="foo" value=""/>
+ </replacetokens>
+ </filterchain>
+ </copy>
+ </target>
+
+ <target name="testReplaceTokensPropertyFile" depends="setUp">
+ <copy tofile="${output}/replacetokensPropertyFile.test">
+ <fileset dir="input" includes="replacetokens.test" />
+ <filterchain>
+ <filterreader classname="org.apache.tools.ant.filters.ReplaceTokens">
+ <param type="propertiesfile" value="${basedir}/input/sample.properties"/>
+ </filterreader>
+ </filterchain>
+ </copy>
+ </target>
+
+ <target name="testReplaceTokensDoubleEncoded" depends="setUp">
+ <copy todir="${output}">
+ <fileset dir="input" includes="replacetokens.double.test" />
+ <filterchain>
+ <replacetokens>
+ <token key="foo" value=""/>
+ </replacetokens>
+ </filterchain>
+ </copy>
+ </target>
+
+ <target name="testReplaceTokensDoubleEncodedToSimple" depends="setUp">
+ <copy todir="${output}">
+ <fileset dir="input" includes="replacetokens.double.test" />
+ <filterchain>
+ <replacetokens begintoken="@@" endtoken="@@">
+ <token key="foo" value=""/>
+ </replacetokens>
+ </filterchain>
+ </copy>
+ </target>
+
+ <target name="testReplaceTokensMustacheStyle" depends="setUp">
+ <copy todir="${output}">
+ <fileset dir="input" includes="replacetokens.mustache.test" />
+ <filterchain>
+ <replacetokens begintoken="{{" endtoken="}}">
+ <token key="foo" value=""/>
+ </replacetokens>
+ </filterchain>
+ </copy>
+ </target>
+
+ <target name="testNoAddNewLine" depends="setUp">
+ <concat destfile="${output}/nonl">This has no new lines</concat>
+ <copy file="${output}/nonl" tofile="${output}/nonl-copyfilter">
+ <filterchain><tokenfilter/></filterchain>
+ </copy>
+ <condition property="filterchain.files.are.same">
+ <filesmatch file1="${output}/nonl" file2="${output}/nonl-copyfilter"/>
+ </condition>
+ <fail unless="filterchain.files.are.same">File was modified</fail>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/concat.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/concat.xml
new file mode 100644
index 00000000..262dd160
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/concat.xml
@@ -0,0 +1,117 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="cleanup" basedir=".">
+
+ <import file="../buildfiletest-base.xml"/>
+
+ <target name="setUp">
+ <mkdir dir="${output}" />
+ <echo file="${output}/prepend.txt" message="this-should-be-the-first-line${line.separator}"/>
+ <echo file="${output}/append.txt" message="this-should-be-the-last-line${line.separator}"/>
+ <copy file="input/head-tail.test" tofile="${output}/concatfilter.test"/>
+ <fixcrlf srcDir="${output}" includes="concatfilter.test"/>
+ <!-- to be consistent on MacOS X. fixcrlf uses CR while line.sep is LF -->
+ <fixcrlf srcDir="${output}" includes="append.txt,prepend.txt"/>
+ </target>
+
+
+
+ <target name="testFilterReaderNoArgs" depends="setUp">
+ <copy file="${output}/concatfilter.test"
+ tofile="${output}/concat.FilterReaderNoArgs.test">
+ <filterchain>
+ <filterreader classname="org.apache.tools.ant.filters.ConcatFilter"/>
+ </filterchain>
+ </copy>
+ </target>
+
+ <target name="testFilterReaderPrepend" depends="setUp">
+ <copy file="${output}/concatfilter.test"
+ tofile="${output}/concat.FilterReaderPrepend.test">
+ <filterchain>
+ <filterreader classname="org.apache.tools.ant.filters.ConcatFilter">
+ <param name="prepend" value="${output}/prepend.txt"/>
+ </filterreader>
+ </filterchain>
+ </copy>
+ </target>
+
+ <target name="testFilterReaderAppend" depends="setUp">
+ <copy file="${output}/concatfilter.test"
+ tofile="${output}/concat.FilterReaderAppend.test">
+ <filterchain>
+ <filterreader classname="org.apache.tools.ant.filters.ConcatFilter">
+ <param name="append" value="${output}/append.txt"/>
+ </filterreader>
+ </filterchain>
+ </copy>
+ </target>
+
+ <target name="testFilterReaderPrependAppend" depends="setUp">
+ <copy file="${output}/concatfilter.test"
+ tofile="${output}/concat.FilterReaderPrependAppend.test">
+ <filterchain>
+ <filterreader classname="org.apache.tools.ant.filters.ConcatFilter">
+ <param name="prepend" value="${output}/prepend.txt"/>
+ <param name="append" value="${output}/append.txt"/>
+ </filterreader>
+ </filterchain>
+ </copy>
+ </target>
+
+ <target name="testConcatFilter" depends="setUp">
+ <typedef name="concatfilter" classname="org.apache.tools.ant.filters.ConcatFilter"/>
+ <copy file="${output}/concatfilter.test"
+ tofile="${output}/concat.ConcatFilter.test">
+ <filterchain>
+ <concatfilter/>
+ </filterchain>
+ </copy>
+ </target>
+
+ <target name="testConcatFilterPrepend" depends="setUp">
+ <typedef name="concatfilter" classname="org.apache.tools.ant.filters.ConcatFilter"/>
+ <copy file="${output}/concatfilter.test"
+ tofile="${output}/concat.ConcatFilterPrepend.test">
+ <filterchain>
+ <concatfilter prepend="${output}/prepend.txt"/>
+ </filterchain>
+ </copy>
+ </target>
+
+ <target name="testConcatFilterAppend" depends="setUp">
+ <typedef name="concatfilter" classname="org.apache.tools.ant.filters.ConcatFilter"/>
+ <copy file="${output}/concatfilter.test"
+ tofile="${output}/concat.ConcatFilterAppend.test">
+ <filterchain>
+ <concatfilter append="${output}/append.txt"/>
+ </filterchain>
+ </copy>
+ </target>
+
+ <target name="testConcatFilterPrependAppend" depends="setUp">
+ <typedef name="concatfilter" classname="org.apache.tools.ant.filters.ConcatFilter"/>
+ <copy file="${output}/concatfilter.test"
+ tofile="${output}/concat.ConcatFilterPrependAppend.test">
+ <filterchain>
+ <concatfilter prepend="${output}/prepend.txt" append="${output}/append.txt"/>
+ </filterchain>
+ </copy>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/dynamicfilter.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/dynamicfilter.xml
new file mode 100644
index 00000000..cb52d215
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/dynamicfilter.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="tearDown" basedir=".">
+
+ <import file="../buildfiletest-base.xml"/>
+
+ <target name="setUp">
+ <mkdir dir="${output}" />
+ </target>
+
+ <target name="dynamicfilter">
+ <path id="test-classes">
+ <pathelement location="../../../../build/testcases" />
+ <pathelement path="${java.class.path}" />
+ </path>
+ <typedef
+ name="customfilter"
+ classname="org.apache.tools.ant.filters.DynamicFilterTest$CustomFilter">
+ <classpath refid="test-classes"/>
+ </typedef>
+
+ <concat destfile="${output}/input">
+ hello world
+ </concat>
+
+ <copy file="${output}/input" tofile="${output}/dynamicfilter">
+ <filterchain>
+ <customfilter replace="o" with="O"/>
+ </filterchain>
+ </copy>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/expected/escapeunicode.test b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/expected/escapeunicode.test
new file mode 100644
index 00000000..ffede99d
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/expected/escapeunicode.test
@@ -0,0 +1,9 @@
+#hebrew shalom olam (hello world)
+text.hebrew=\u05e9\u05dc\u05d5\u05dd \u05e2\u05d5\u05dc\u05dd
+#goethe gingko biloba
+text.german.1=Sp\u00fcrst du nicht an meinen Liedern,
+text.german.2=Da\u00df ich eins und doppelt bin ?
+# Francois Villon Ballade des Pendus
+text.french=Fr\u00e8res humains qui apr\u00e8s nous vivez
+# Usual IT example
+text.basic.latin=Hello World
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/expected/head-tail.head.test b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/expected/head-tail.head.test
new file mode 100644
index 00000000..43d44e57
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/expected/head-tail.head.test
@@ -0,0 +1,10 @@
+Line 1
+Line 2
+Line 3
+Line 4
+Line 5
+Line 6
+Line 7
+Line 8
+Line 9
+Line 10
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/expected/head-tail.headAllSkip.test b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/expected/head-tail.headAllSkip.test
new file mode 100644
index 00000000..eeffaa30
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/expected/head-tail.headAllSkip.test
@@ -0,0 +1,58 @@
+Line 3
+Line 4
+Line 5
+Line 6
+Line 7
+Line 8
+Line 9
+Line 10
+Line 11
+Line 12
+Line 13
+Line 14
+Line 15
+Line 16
+Line 17
+Line 18
+Line 19
+Line 20
+Line 21
+Line 22
+Line 23
+Line 24
+Line 25
+Line 26
+Line 27
+Line 28
+Line 29
+Line 30
+Line 31
+Line 32
+Line 33
+Line 34
+Line 35
+Line 36
+Line 37
+Line 38
+Line 39
+Line 40
+Line 41
+Line 42
+Line 43
+Line 44
+Line 45
+Line 46
+Line 47
+Line 48
+Line 49
+Line 50
+Line 51
+Line 52
+Line 53
+Line 54
+Line 55
+Line 56
+Line 57
+Line 58
+Line 59
+Line 60
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/expected/head-tail.headLines.test b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/expected/head-tail.headLines.test
new file mode 100644
index 00000000..98fa9e8e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/expected/head-tail.headLines.test
@@ -0,0 +1,2 @@
+Line 1
+Line 2
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/expected/head-tail.headLinesSkip.test b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/expected/head-tail.headLinesSkip.test
new file mode 100644
index 00000000..13cb234b
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/expected/head-tail.headLinesSkip.test
@@ -0,0 +1,2 @@
+Line 3
+Line 4
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/expected/head-tail.headSkip.test b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/expected/head-tail.headSkip.test
new file mode 100644
index 00000000..57f17d53
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/expected/head-tail.headSkip.test
@@ -0,0 +1,10 @@
+Line 3
+Line 4
+Line 5
+Line 6
+Line 7
+Line 8
+Line 9
+Line 10
+Line 11
+Line 12
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/expected/head-tail.headtail.test b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/expected/head-tail.headtail.test
new file mode 100644
index 00000000..13cb234b
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/expected/head-tail.headtail.test
@@ -0,0 +1,2 @@
+Line 3
+Line 4
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/expected/head-tail.tail.test b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/expected/head-tail.tail.test
new file mode 100644
index 00000000..5793dc41
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/expected/head-tail.tail.test
@@ -0,0 +1,10 @@
+Line 51
+Line 52
+Line 53
+Line 54
+Line 55
+Line 56
+Line 57
+Line 58
+Line 59
+Line 60
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/expected/head-tail.tailAllSkip.test b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/expected/head-tail.tailAllSkip.test
new file mode 100644
index 00000000..532cf014
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/expected/head-tail.tailAllSkip.test
@@ -0,0 +1,58 @@
+Line 1
+Line 2
+Line 3
+Line 4
+Line 5
+Line 6
+Line 7
+Line 8
+Line 9
+Line 10
+Line 11
+Line 12
+Line 13
+Line 14
+Line 15
+Line 16
+Line 17
+Line 18
+Line 19
+Line 20
+Line 21
+Line 22
+Line 23
+Line 24
+Line 25
+Line 26
+Line 27
+Line 28
+Line 29
+Line 30
+Line 31
+Line 32
+Line 33
+Line 34
+Line 35
+Line 36
+Line 37
+Line 38
+Line 39
+Line 40
+Line 41
+Line 42
+Line 43
+Line 44
+Line 45
+Line 46
+Line 47
+Line 48
+Line 49
+Line 50
+Line 51
+Line 52
+Line 53
+Line 54
+Line 55
+Line 56
+Line 57
+Line 58
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/expected/head-tail.tailLines.test b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/expected/head-tail.tailLines.test
new file mode 100644
index 00000000..66506738
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/expected/head-tail.tailLines.test
@@ -0,0 +1,2 @@
+Line 59
+Line 60
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/expected/head-tail.tailLinesSkip.test b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/expected/head-tail.tailLinesSkip.test
new file mode 100644
index 00000000..42746d1e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/expected/head-tail.tailLinesSkip.test
@@ -0,0 +1,2 @@
+Line 57
+Line 58
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/expected/head-tail.tailSkip.test b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/expected/head-tail.tailSkip.test
new file mode 100644
index 00000000..070eeee0
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/expected/head-tail.tailSkip.test
@@ -0,0 +1,10 @@
+Line 49
+Line 50
+Line 51
+Line 52
+Line 53
+Line 54
+Line 55
+Line 56
+Line 57
+Line 58
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/expected/linecontains.test b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/expected/linecontains.test
new file mode 100644
index 00000000..aabaa03b
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/expected/linecontains.test
@@ -0,0 +1,4 @@
+This is line 2 with beta.
+This is line 3 with beta.
+This is line 5 with beta.
+This is line 7 with beta.
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/expected/negatelinecontains.test b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/expected/negatelinecontains.test
new file mode 100644
index 00000000..a1437e90
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/expected/negatelinecontains.test
@@ -0,0 +1,3 @@
+This is line 1 with alpha.
+This is line 4 with gamma.
+This is line 6 with delta.
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/expected/replacetokens.double.test b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/expected/replacetokens.double.test
new file mode 100644
index 00000000..72eaee7e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/expected/replacetokens.double.test
@@ -0,0 +1,2 @@
+1@@2
+3
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/expected/replacetokens.test b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/expected/replacetokens.test
new file mode 100644
index 00000000..e666476a
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/expected/replacetokens.test
@@ -0,0 +1,2 @@
+12
+3
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/expected/stripjavacomments.test b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/expected/stripjavacomments.test
new file mode 100644
index 00000000..c8d0672a
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/expected/stripjavacomments.test
@@ -0,0 +1,19 @@
+
+
+
+public class NormalLine {
+
+ private String withComment;
+
+
+ public void doNothing() {
+
+ int i;
+
+ int j;
+ }
+
+ private String url = "http://ant.apache.org/";
+ private String url2 = "\"http://ant.apache.org/\"";
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/head-tail.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/head-tail.xml
new file mode 100644
index 00000000..e0ffed74
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/head-tail.xml
@@ -0,0 +1,146 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="tearDown" basedir=".">
+
+ <import file="../buildfiletest-base.xml"/>
+
+ <target name="setUp">
+ <mkdir dir="${output}" />
+ </target>
+
+
+ <!-- Testcases for HeadFilter -->
+
+ <target name="testHead" depends="setUp">
+ <copy file="input/head-tail.test" tofile="${output}/head-tail.head.test">
+ <filterchain>
+ <headfilter/>
+ </filterchain>
+ </copy>
+ </target>
+
+ <target name="testHeadLines" depends="setUp">
+ <copy file="input/head-tail.test" tofile="${output}/head-tail.headLines.test">
+ <filterchain>
+ <headfilter lines="2"/>
+ </filterchain>
+ </copy>
+ </target>
+
+ <target name="testHeadSkip" depends="setUp">
+ <copy file="input/head-tail.test" tofile="${output}/head-tail.headSkip.test">
+ <filterchain>
+ <headfilter skip="2"/>
+ </filterchain>
+ </copy>
+ </target>
+
+ <target name="testHeadLinesSkip" depends="setUp">
+ <copy file="input/head-tail.test" tofile="${output}/head-tail.headLinesSkip.test">
+ <filterchain>
+ <headfilter lines="2" skip="2"/>
+ </filterchain>
+ </copy>
+ </target>
+
+ <target name="testFilterReaderHeadLinesSkip" depends="setUp">
+ <copy file="input/head-tail.test"
+ tofile="${output}/head-tail.filterReaderHeadLinesSkip.test">
+ <filterchain>
+ <filterreader classname="org.apache.tools.ant.filters.HeadFilter">
+ <param name="lines" value="2"/>
+ <param name="skip" value="2"/>
+ </filterreader>
+ </filterchain>
+ </copy>
+ </target>
+
+ <target name="testHeadAllSkip" depends="setUp">
+ <copy file="input/head-tail.test" tofile="${output}/head-tail.headAllSkip.test">
+ <filterchain>
+ <headfilter lines="-1" skip="2"/>
+ </filterchain>
+ </copy>
+ </target>
+
+ <!-- Testcases for TailFilter -->
+
+ <target name="testTail" depends="setUp">
+ <copy file="input/head-tail.test" tofile="${output}/head-tail.tail.test">
+ <filterchain>
+ <tailfilter/>
+ </filterchain>
+ </copy>
+ </target>
+
+ <target name="testTailLines" depends="setUp">
+ <copy file="input/head-tail.test" tofile="${output}/head-tail.tailLines.test">
+ <filterchain>
+ <tailfilter lines="2"/>
+ </filterchain>
+ </copy>
+ </target>
+
+ <target name="testTailSkip" depends="setUp">
+ <copy file="input/head-tail.test" tofile="${output}/head-tail.tailSkip.test">
+ <filterchain>
+ <tailfilter skip="2"/>
+ </filterchain>
+ </copy>
+ </target>
+
+ <target name="testTailLinesSkip" depends="setUp">
+ <copy file="input/head-tail.test" tofile="${output}/head-tail.tailLinesSkip.test">
+ <filterchain>
+ <tailfilter lines="2" skip="2"/>
+ </filterchain>
+ </copy>
+ </target>
+
+ <target name="testFilterReaderTailLinesSkip" depends="setUp">
+ <copy file="input/head-tail.test"
+ tofile="${output}/head-tail.filterReaderTailLinesSkip.test">
+ <filterchain>
+ <filterreader classname="org.apache.tools.ant.filters.TailFilter">
+ <param name="lines" value="2"/>
+ <param name="skip" value="2"/>
+ </filterreader>
+ </filterchain>
+ </copy>
+ </target>
+
+ <target name="testTailAllSkip" depends="setUp">
+ <copy file="input/head-tail.test" tofile="${output}/head-tail.tailAllSkip.test">
+ <filterchain>
+ <tailfilter lines="-1" skip="2"/>
+ </filterchain>
+ </copy>
+ </target>
+
+ <!-- Testcases for combined scenarios -->
+
+ <target name="testHeadTail" depends="setUp">
+ <copy file="input/head-tail.test" tofile="${output}/head-tail.headtail.test">
+ <filterchain>
+ <headfilter lines="4"/>
+ <tailfilter lines="2"/>
+ </filterchain>
+ </copy>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/input/escapeunicode.test b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/input/escapeunicode.test
new file mode 100644
index 00000000..bf861503
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/input/escapeunicode.test
@@ -0,0 +1,9 @@
+#hebrew shalom olam (hello world)
+text.hebrew=שלום עולם
+#goethe gingko biloba
+text.german.1=SpĂĽrst du nicht an meinen Liedern,
+text.german.2=DaĂź ich eins und doppelt bin ?
+# Francois Villon Ballade des Pendus
+text.french=Frères humains qui après nous vivez
+# Usual IT example
+text.basic.latin=Hello World
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/input/head-tail.small.test b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/input/head-tail.small.test
new file mode 100644
index 00000000..c91f1d7f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/input/head-tail.small.test
@@ -0,0 +1,5 @@
+Line 1
+Line 2
+Line 3
+Line 4
+Line 5 \ No newline at end of file
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/input/head-tail.test b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/input/head-tail.test
new file mode 100644
index 00000000..8fac760c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/input/head-tail.test
@@ -0,0 +1,60 @@
+Line 1
+Line 2
+Line 3
+Line 4
+Line 5
+Line 6
+Line 7
+Line 8
+Line 9
+Line 10
+Line 11
+Line 12
+Line 13
+Line 14
+Line 15
+Line 16
+Line 17
+Line 18
+Line 19
+Line 20
+Line 21
+Line 22
+Line 23
+Line 24
+Line 25
+Line 26
+Line 27
+Line 28
+Line 29
+Line 30
+Line 31
+Line 32
+Line 33
+Line 34
+Line 35
+Line 36
+Line 37
+Line 38
+Line 39
+Line 40
+Line 41
+Line 42
+Line 43
+Line 44
+Line 45
+Line 46
+Line 47
+Line 48
+Line 49
+Line 50
+Line 51
+Line 52
+Line 53
+Line 54
+Line 55
+Line 56
+Line 57
+Line 58
+Line 59
+Line 60
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/input/linecontains.test b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/input/linecontains.test
new file mode 100644
index 00000000..c95b5539
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/input/linecontains.test
@@ -0,0 +1,7 @@
+This is line 1 with alpha.
+This is line 2 with beta.
+This is line 3 with beta.
+This is line 4 with gamma.
+This is line 5 with beta.
+This is line 6 with delta.
+This is line 7 with beta.
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/input/replacetokens.double.test b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/input/replacetokens.double.test
new file mode 100644
index 00000000..163417d3
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/input/replacetokens.double.test
@@ -0,0 +1,2 @@
+1@@foo@@2
+3
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/input/replacetokens.mustache.test b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/input/replacetokens.mustache.test
new file mode 100644
index 00000000..62df4455
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/input/replacetokens.mustache.test
@@ -0,0 +1,2 @@
+1{{foo}}2
+3
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/input/replacetokens.test b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/input/replacetokens.test
new file mode 100644
index 00000000..e9208871
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/input/replacetokens.test
@@ -0,0 +1,2 @@
+1@foo@2
+3
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/input/sample.properties b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/input/sample.properties
new file mode 100644
index 00000000..572e79d3
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/input/sample.properties
@@ -0,0 +1,16 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+foo=
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/input/stripjavacomments.test b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/input/stripjavacomments.test
new file mode 100644
index 00000000..37535bcc
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/input/stripjavacomments.test
@@ -0,0 +1,30 @@
+/*
+ * Copyright text
+ * has to be removed
+ */
+
+/**
+ * JavaDoc text about the class.
+ * has to be removed
+ */
+public class NormalLine {
+
+ private String withComment; // this comment should be removed
+
+ /* this comment
+ * should be
+ * removed
+ */
+ public void doNothing() {
+ // this comment should be removed
+ int i;
+ /* this comment
+ should be removed
+ */
+ int j;
+ }
+
+ private String url = "http://ant.apache.org/"; // very difficult!
+ private String url2 = "\"http://ant.apache.org/\""; // even worse
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/tokenfilter.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/tokenfilter.xml
new file mode 100644
index 00000000..b1b5aef4
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/filters/tokenfilter.xml
@@ -0,0 +1,357 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="tearDown" basedir=".">
+
+ <import file="../buildfiletest-base.xml"/>
+
+ <target name="setUp">
+ <mkdir dir="${output}" />
+ </target>
+
+ <target name="tokenfilter">
+ <copy file="input/linecontains.test" tofile="${output}/file1">
+ <filterchain>
+ <tokenfilter/>
+ </filterchain>
+ </copy>
+ </target>
+
+ <target name="trimignore">
+ <concat destfile="${output}/input">
+ Hello
+
+ World
+ </concat>
+ <copy file="${output}/input" tofile="${output}/output" overwrite="yes">
+ <filterchain>
+ <tokenfilter delimoutput="-">
+ <trim/>
+ <ignoreblank/>
+ </tokenfilter>
+ </filterchain>
+ </copy>
+ <concat>
+ <filelist dir="${output}" files="output"/>
+ </concat>
+ </target>
+
+ <target name="trimfile">
+ <concat destfile="${output}/trimfile">
+ This is the contents of the trimmed file.
+ This is the second line.
+ <filterchain>
+ <trim byline="no"/>
+ </filterchain>
+ </concat>
+ </target>
+
+ <target name="trimfilebyline">
+ <concat destfile="${output}/trimfilebyline">
+ This is the contents of the trimmed file.
+ This is the second line.
+ <filterchain>
+ <trim/>
+ <tokenfilter delimoutput="\n"/>
+ </filterchain>
+ </concat>
+ </target>
+
+ <target name="filterreplacestring">
+ <concat destfile="${output}/filterreplacestring">
+ This is foo bar
+ <filterchain>
+ <replacestring from="foo" to="the"/>
+ <replacestring from="bar" to="moon"/>
+ </filterchain>
+ </concat>
+ </target>
+
+ <target name="filterreplacestrings">
+ <concat>
+ foo foo foo
+ <filterchain>
+ <replacestring from="foo" to="bar"/>
+ </filterchain>
+ </concat>
+ </target>
+
+ <target name="stringtokenizer">
+ <concat destfile="${output}/input">
+ This is a number
+ of words
+ </concat>
+ <copy file="${output}/input" tofile="${output}/output" overwrite="yes">
+ <filterchain>
+ <tokenfilter delimoutput="#">
+ <stringtokenizer/>
+ </tokenfilter>
+ </filterchain>
+ </copy>
+ <concat>
+ <filelist dir="${output}" files="output"/>
+ </concat>
+ </target>
+
+ <target name="unixlineoutput">
+ <concat destfile="${output}/unixlineoutput">
+ This is a number
+ of words
+ <filterchain>
+ <tokenfilter delimoutput="\n">
+ <stringtokenizer/>
+ </tokenfilter>
+ </filterchain>
+ </concat>
+ </target>
+
+ <target name="doslineoutput">
+ <concat destfile="${output}/doslineoutput">
+ This is a number
+ of words
+ <filterchain>
+ <tokenfilter delimoutput="\r\n">
+ <stringtokenizer/>
+ </tokenfilter>
+ </filterchain>
+ </concat>
+ </target>
+
+ <target name="filetokenizer">
+ <concat destfile="${output}/input">
+ This is a number
+ of words
+ </concat>
+ <copy file="${output}/input" tofile="${output}/filetokenizer">
+ <filterchain>
+ <tokenfilter>
+ <filetokenizer/>
+ <trim/>
+ </tokenfilter>
+ </filterchain>
+ </copy>
+ </target>
+
+ <target name="replacestring">
+ <concat destfile="${output}/replacestring">
+ this is the sun
+ <filterchain>
+ <tokenfilter>
+ <replacestring from="sun" to="moon"/>
+ </tokenfilter>
+ </filterchain>
+ </concat>
+ </target>
+
+ <target name="replacestrings">
+ <concat>
+ foo foo foo
+ <filterchain>
+ <tokenfilter>
+ <replacestring from="foo" to="bar"/>
+ </tokenfilter>
+ </filterchain>
+ </concat>
+ </target>
+
+ <target name="containsstring">
+ <concat destfile="${output}/input">
+ this is a line contains foo
+ this line does not
+ </concat>
+ <copy file="${output}/input" tofile="${output}/containsstring">
+ <filterchain>
+ <tokenfilter>
+ <containsstring contains="foo"/>
+ </tokenfilter>
+ </filterchain>
+ </copy>
+ </target>
+
+ <!-- need to check for existence of regex -->
+ <target name="replaceregex">
+ <concat destfile="${output}/input">
+ hello Hello HELLO hello
+ cat Cat cat
+ Sun Sun Sun
+ WhiteSpace tab
+ This is a line with digits - 1234 -- there
+ </concat>
+ <copy file="${output}/input" tofile="${output}/replaceregex">
+ <filterchain>
+ <tokenfilter>
+ <replaceregex pattern="hello" replace="world" flags="gi"/>
+ <replaceregex pattern="cat" replace="dog" flags="g"/>
+ <replaceregex pattern="sun" replace="moon" flags="i"/>
+ <replaceregex pattern="WhiteSpace[ \t]+tab"
+ replace="found WhiteSpace"/>
+ <replaceregex pattern="This is a line with dig.* ([0-9]+).*"
+ replace="Found digits [\1]"/>
+ </tokenfilter>
+ </filterchain>
+ </copy>
+ </target>
+
+ <target name="filterreplaceregex">
+ <concat destfile="${output}/filterreplaceregex">
+ hello Hello HELLO hello
+ <filterchain>
+ <replaceregex pattern="hello" replace="world" flags="gi"/>
+ </filterchain>
+ </concat>
+ </target>
+
+ <target name="dollermatch">
+ <concat>
+ @hello@
+ <filterchain>
+ <replaceregex pattern="@([^@]*)@" replace="${\1}"/>
+ </filterchain>
+ </concat>
+ </target>
+
+ <!-- need to check for existence of regex -->
+ <target name="containsregex">
+ <concat destfile="${output}/input">
+ hello world
+ this is the moon
+ World here
+ </concat>
+ <copy file="${output}/input" tofile="${output}/containsregex">
+ <filterchain>
+ <tokenfilter>
+ <containsregex pattern="(hello|world)" flags="i"/>
+ </tokenfilter>
+ </filterchain>
+ </copy>
+ </target>
+
+ <target name="filtercontainsregex">
+ <concat destfile="${output}/filtercontainsregex">
+ hello world
+ this is the moon
+ World here
+ <filterchain>
+ <tokenfilter>
+ <containsregex pattern="(hello|world)" flags="i"/>
+ </tokenfilter>
+ </filterchain>
+ </concat>
+ </target>
+
+
+ <!-- need to check for existence of regex -->
+ <target name="containsregex2">
+ <concat destfile="${output}/input">
+ SUITE(TestSuite, bits);
+ here
+ </concat>
+ <copy file="${output}/input" tofile="${output}/containsregex2">
+ <filterchain>
+ <tokenfilter>
+ <containsregex
+ pattern="^ *SUITE\(.*,\s*(.*)\s*\).*"
+ replace="void register_\1();"/>
+ </tokenfilter>
+ </filterchain>
+ </copy>
+ </target>
+
+ <target name="deletecharacters">
+ <concat destfile="${output}/deletechars">
+ This is some ### s
+ some ****
+ <filterchain>
+ <tokenfilter>
+ <deletecharacters chars="#"/>
+ </tokenfilter>
+ <deletecharacters chars="*"/>
+ </filterchain>
+ </concat>
+ </target>
+
+ <target name="scriptfilter">
+ <concat destfile="${output}/input">
+ hello world
+ </concat>
+ <copy file="${output}/input" tofile="${output}/scriptfilter">
+ <filterchain>
+ <tokenfilter>
+ <scriptfilter language="javascript">
+ self.setToken(self.getToken().toUpperCase());
+ </scriptfilter>
+ </tokenfilter>
+ </filterchain>
+ </copy>
+ </target>
+
+ <target name="scriptfilter2">
+ <concat destfile="${output}/input">
+ hello moon
+ </concat>
+ <copy file="${output}/input" tofile="${output}/scriptfilter2">
+ <filterchain>
+ <scriptfilter language="javascript">
+ self.setToken(self.getToken().toUpperCase());
+ </scriptfilter>
+ </filterchain>
+ </copy>
+ </target>
+
+ <target name="customtokenfilter">
+ <path id="test-classes">
+ <pathelement location="../../../../build/testcases" />
+ <pathelement path="${java.class.path}" />
+ </path>
+
+
+ <typedef
+ name="capitalize"
+ classname="org.apache.tools.ant.filters.TokenFilterTest$Capitalize">
+ <classpath refid="test-classes"/>
+ </typedef>
+
+ <concat destfile="${output}/input">
+ hello world
+ </concat>
+
+ <copy file="${output}/input" tofile="${output}/custom">
+ <filterchain>
+ <tokenfilter>
+ <stringtokenizer/>
+ <capitalize/>
+ </tokenfilter>
+ </filterchain>
+ </copy>
+ </target>
+
+ <target name="hasscript">
+ <script language="javascript">
+ i = 1;
+ </script>
+ </target>
+
+ <target name="hasregex">
+ <concat destfile="${output}/replaceregexp">
+ hello world
+ </concat>
+ <replaceregexp file="${output}/replaceregexp"
+ match="hello( )world"
+ replace="bye\1world"/>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/abstractcvstask.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/abstractcvstask.xml
new file mode 100644
index 00000000..5de8b5e7
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/abstractcvstask.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<project name="abstractcvstask-test" basedir="../../../../"
+ default="tearDown">
+
+ <import file="../buildfiletest-base.xml" optional="false"/>
+
+ <target name="setUp">
+ <mkdir dir="${output}"/>
+ </target>
+
+ <target name="package-attribute">
+ <cvs cvsroot="anoncvs@anoncvs.ca.openbsd.org:/cvs"
+ package="src/Makefile"
+ dest="${output}"
+ quiet="true" />
+ </target>
+
+ <target name="tag-attribute">
+ <cvs cvsroot="anoncvs@anoncvs.ca.openbsd.org:/cvs"
+ package="src/Makefile"
+ dest="${output}"
+ quiet="true"
+ tag="OPENBSD_5_3" />
+ <cvs cvsroot="anoncvs@anoncvs.ca.openbsd.org:/cvs"
+ package="src/Makefile"
+ dest="${output}"
+ command="status"/>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/ant.topleveltest.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/ant.topleveltest.xml
new file mode 100644
index 00000000..65bc7291
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/ant.topleveltest.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project>
+ <echo>Hello world</echo>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/ant.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/ant.xml
new file mode 100644
index 00000000..33ef1dab
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/ant.xml
@@ -0,0 +1,261 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<project name="ant-test" basedir="." default="test1">
+
+ <path id="inheritable">
+ <pathelement path="${java.class.path}" />
+ </path>
+
+ <target name="cleanup">
+ <delete file="test1.log" />
+ <delete file="test2.log" />
+ <delete file="ant/test3.log" />
+ <delete file="ant/test4.log" />
+ </target>
+
+ <target name="all" depends="test1,test2,test3,test4"/>
+
+ <target name="test1">
+ <ant antfile="ant.xml" dir="." target="test1"/>
+ </target>
+
+ <target name="test2">
+ <antcall/>
+ </target>
+
+ <target name="test3">
+ <antcall target="test3"/>
+ </target>
+
+ <target name="test4">
+ <antcall target=""/>
+ </target>
+
+ <target name="test4b">
+ <antcall target="does-not-exist"/>
+ </target>
+
+ <target name="test5">
+ <antcall target="dummy"/>
+ </target>
+
+ <target name="test6">
+ <ant antfile="ant.xml" dir="." target="dummy"/>
+ </target>
+
+ <target name="dummy">
+ </target>
+
+ <target name="inheritBasedir">
+ <ant antfile="ant/ant.xml" target="dummy" inheritAll="true" />
+ </target>
+
+ <target name="doNotInheritBasedir">
+ <ant antfile="ant/ant.xml" target="dummy" inheritAll="false" />
+ </target>
+
+ <target name="explicitBasedir1">
+ <ant antfile="taskdefs/ant/ant.xml" target="dummy" inheritAll="true"
+ dir=".." />
+ </target>
+
+ <target name="explicitBasedir2">
+ <ant antfile="taskdefs/ant/ant.xml" target="dummy" inheritAll="false"
+ dir=".." />
+ </target>
+
+ <target name="tripleCall">
+ <ant antfile="ant/ant.xml" target="callback" inheritAll="false" />
+ </target>
+
+ <target name="testInherit">
+ <ant antfile="ant/references.xml" inheritRefs="true" target="dummy" />
+ </target>
+
+ <target name="testNoInherit">
+ <ant antfile="ant/references.xml" inheritRefs="false" target="dummy" />
+ </target>
+
+ <target name="testRename">
+ <ant antfile="ant/references.xml" inheritRefs="false" target="dummy">
+ <reference refid="path" torefid="newpath" />
+ </ant>
+ </target>
+
+ <target name="testInheritPath" description="try to pass a reference to a path, which refers itself to a second path">
+ <property name="rootdir" location="."/>
+ <path id="project.classpath">
+ <pathelement location="../classes"/>
+ </path>
+ <path id="test.classpath">
+ <pathelement location="${rootdir}/test/testframework.jar"/>
+ <path refid="project.classpath"/>
+ </path>
+ <ant antfile="ant/references.xml" target="testInheritPath">
+ <reference refid="test.classpath"/>
+ </ant>
+ </target>
+
+ <target name="testLogfilePlacement">
+ <ant antfile="ant.xml" target="dummy" output="test1.log"
+ inheritall="false" />
+ <ant antfile="ant.xml" target="dummy" output="test2.log" />
+ <ant antfile="ant.xml" target="dummy" output="test3.log"
+ inheritall="false" dir="ant" />
+ <ant antfile="ant.xml" target="dummy" output="test4.log"
+ dir="ant" />
+ </target>
+
+ <target name="testRefid">
+ <ant antfile="ant/references.xml" inheritRefs="false" target="dummy">
+ <property name="testprop" refid="inheritable" />
+ </ant>
+ </target>
+
+ <target name="test-property-override-inheritall-start">
+ <property name="test" value="1" />
+ <ant antfile="ant.xml"
+ target="test-property-override-inheritall-level-2"
+ inheritall="true">
+ <property name="test" value="2" />
+ </ant>
+ </target>
+
+ <target name="test-property-override-inheritall-level-2">
+ <property name="test" value="3" />
+ <ant antfile="ant.xml"
+ target="test-property-override-inheritall-level-3"
+ inheritall="true">
+ <property name="test" value="4" />
+ </ant>
+ </target>
+
+ <target name="test-property-override-inheritall-level-3">
+ <property name="test" value="5" />
+ <echo message="The value of test is ${test}" />
+ </target>
+
+ <target name="test-property-override-no-inheritall-start">
+ <property name="test" value="1" />
+ <ant antfile="ant.xml"
+ target="test-property-override-no-inheritall-level-2"
+ inheritall="false">
+ <property name="test" value="2" />
+ </ant>
+ </target>
+
+ <target name="test-property-override-no-inheritall-level-2">
+ <property name="test" value="3" />
+ <ant antfile="ant.xml"
+ target="test-property-override-no-inheritall-level-3"
+ inheritall="false">
+ <property name="test" value="4" />
+ </ant>
+ </target>
+
+ <target name="test-property-override-no-inheritall-level-3">
+ <property name="test" value="5" />
+ <echo message="The value of test is ${test}" />
+ </target>
+
+ <target name="test-propertyset">
+ <property name="test1" value="1"/>
+ <property name="test2" value="2"/>
+ <propertyset id="set">
+ <propertyref name="test1"/>
+ <mapper type="glob" from="*" to="*.x"/>
+ </propertyset>
+ <ant antfile="ant.xml" target="echo-for-propertyset-test"
+ inheritall="false">
+ <propertyset refid="set"/>
+ </ant>
+ </target>
+
+ <target name="echo-for-propertyset-test">
+ <echo>test1 is ${test1}</echo>
+ <echo>test2 is ${test2}</echo>
+ <echo>test1.x is ${test1.x}</echo>
+ </target>
+
+ <target name="infinite-loop-via-depends">
+ <antcall target="dependent"/>
+ </target>
+
+ <target name="middleman" depends="infinite-loop-via-depends"/>
+ <target name="dependent" depends="middleman"/>
+
+ <target name="multi-same-property">
+ <ant antfile="ant.xml" target="echo-for-multi-same">
+ <property name="prop" value="one"/>
+ <property name="prop" value="two"/>
+ </ant>
+ </target>
+
+ <target name="echo-for-multi-same">
+ <echo>prop is ${prop}</echo>
+ </target>
+
+ <target name="topleveltarget">
+ <ant antfile="ant.topleveltest.xml"/>
+ </target>
+
+ <target name="multiple-property-file-children">
+ <ant target="dummy" antfile="ant.xml">
+ <property file="foo.properties"/>
+ <property file="bar.properties"/>
+ </ant>
+ </target>
+
+ <target name="blank-target">
+ <ant antfile="ant.topleveltest.xml">
+ <target name="" />
+ </ant>
+ </target>
+
+ <target name="multiple-targets">
+ <ant antfile="ant.xml">
+ <target name="ta" />
+ <target name="tb" />
+ <target name="tc" />
+ </ant>
+ </target>
+
+ <target name="multiple-targets-2">
+ <ant antfile="ant.xml">
+ <target name="tb" />
+ <target name="da" />
+ </ant>
+ </target>
+
+ <target name="ta"><echo>ta</echo></target>
+ <target name="tb" depends="da,dc"><echo>tb</echo></target>
+ <target name="tc" depends="db,dc"><echo>tc</echo></target>
+
+ <target name="da"><echo>da</echo></target>
+ <target name="db"><echo>db</echo></target>
+ <target name="dc"><echo>dc</echo></target>
+
+ <target name="show-ant.core.lib">
+ <echo>${ant.core.lib}</echo>
+ </target>
+ <target name="sub-show-ant.core.lib">
+ <ant antfile="${ant.file}" target="show-ant.core.lib" inheritall="false" inheritrefs="false"/>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/ant/ant.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/ant/ant.xml
new file mode 100644
index 00000000..52c9a70d
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/ant/ant.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="test" default="def" basedir=".">
+
+ <target name="def">
+ <fail>This build file should only be run from within the testcase</fail>
+ </target>
+
+ <target name="dummy">
+ <echo message="${basedir}" />
+ </target>
+
+ <target name="callback">
+ <ant antfile="../ant.xml" target="dummy" inheritAll="false" />
+ </target>
+
+
+</project> \ No newline at end of file
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/ant/references.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/ant/references.xml
new file mode 100644
index 00000000..0f3a6930
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/ant/references.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="test" default="def" basedir=".">
+
+ <path id="no-override" />
+
+ <target name="def">
+ <fail>This build file should only be run from within the testcase</fail>
+ </target>
+
+ <target name="dummy" />
+
+ <target name="testInheritPath">
+ <pathconvert refid="test.classpath" pathsep="${line.separator}" property="myprop"/>
+ <echo>${myprop}</echo>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/antlib.current-test.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/antlib.current-test.xml
new file mode 100644
index 00000000..0ad44dbd
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/antlib.current-test.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<antlib xmlns:c="ant:current">
+ <typedef name="echo2" classname="org.apache.tools.ant.taskdefs.Echo"/>
+ <presetdef name="preset.echo">
+ <typedef classname="org.apache.tools.ant.taskdefs.Echo"/>
+ </presetdef>
+ <c:preset.echo name="p"/>
+ <macrodef name="useecho2">
+ <sequential>
+ <c:echo2>Echo2 inside a macro</c:echo2>
+ </sequential>
+ </macrodef>
+</antlib>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/antlib.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/antlib.xml
new file mode 100644
index 00000000..d1c4061e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/antlib.xml
@@ -0,0 +1,72 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="test">
+
+ <property name="testcases.dir" location="../../../../build/testcases"/>
+
+ <path id="testclasses">
+ <pathelement location="${testcases.dir}" />
+ <pathelement path="${java.class.path}" />
+ </path>
+
+ <target name="antlib.file">
+ <typedef file="test.antlib.xml"
+ classpathref="testclasses"/>
+ <mytask/>
+ </target>
+
+ <target name="antlib.resource">
+ <typedef resource="taskdefs/test.antlib.xml">
+ <classpath>
+ <!-- To load the task classes: -->
+ <path refid="testclasses"/>
+ <!-- For test.antlib.xml: -->
+ <pathelement location=".."/>
+ <!-- For test2.antlib.xml: -->
+ <pathelement location="${testcases.dir}/org/apache/tools/ant/taskdefs/test2-antlib.jar"/>
+ </classpath>
+ </typedef>
+ <mytask/>
+ <echo>-and-then-</echo>
+ <mytask2/>
+ </target>
+
+ <target name="ns.current">
+ <typedef file="antlib.current-test.xml" uri="abc"/>
+ <x:useecho2 xmlns:x="abc"/>
+ <x:preset.echo xmlns:x="abc" name="p"/>
+ <x:p xmlns:x="abc">Hello from x:p</x:p>
+ </target>
+
+ <target name="antlib_uri" >
+ <typedef uri="antlib:org.example.tasks" onerror="failall"/>
+ </target>
+
+ <target name="antlib_uri_auto" xmlns:ex="antlib:org.example.tasks">
+ <ex:simple>
+ <echo message="inside simple" />
+ </ex:simple>
+ </target>
+
+ <target name="antlib_uri_auto2" xmlns:ex="antlib://org/example/tasks/antlib2.xml">
+ <ex:simple>
+ <echo message="inside simple"/>
+ </ex:simple>
+ </target>
+
+</project> \ No newline at end of file
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/antstructure.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/antstructure.xml
new file mode 100644
index 00000000..516a9735
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/antstructure.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<project name="antstructure-test" basedir="." default="test1">
+
+ <target name="test1">
+ <antstructure/>
+ </target>
+
+ <target name="testCustomPrinter">
+ <typedef name="myprinter"
+ classname="org.apache.tools.ant.taskdefs.AntStructureTest$MyPrinter">
+ <classpath>
+ <pathelement path="${tests-classpath.value}"/>
+ </classpath>
+ </typedef>
+ <antstructure output="foo.dtd">
+ <myprinter/>
+ </antstructure>
+ </target>
+
+ <target name="tearDown">
+ <delete file="foo.dtd" quiet="true"/>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/available.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/available.xml
new file mode 100644
index 00000000..324c054d
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/available.xml
@@ -0,0 +1,269 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<project name="available-test" basedir="." default="test1">
+
+ <import file="../buildfiletest-base.xml"/>
+
+ <target name="setUp">
+ <mkdir dir="${output}" />
+ </target>
+
+ <target name="test1">
+ <available/>
+ </target>
+
+ <target name="test2">
+ <available property="test"/>
+ </target>
+
+ <target name="test3">
+ <available file="test"/>
+ </target>
+
+ <target name="test4">
+ <available property="test"
+ file="src/etc/testcases/taskdefs/this_file_does_not_exist"/>
+ </target>
+
+ <target name="test5">
+ <available property="test"
+ file="available.xml"/>
+ </target>
+
+ <target name="test6">
+ <available property="test"
+ resource="org/apache/tools/ant/taskdefs/this_resource_does_not_exist"/>
+ </target>
+
+ <target name="test7">
+ <available property="test"
+ resource="org/apache/tools/ant/taskdefs/defaults.properties"/>
+ </target>
+
+ <target name="test8">
+ <available property="test"
+ classname="org.apache.tools.ant.taskdefs.this_class_does_not_exist"/>
+ </target>
+
+ <target name="test9">
+ <available property="test"
+ classname="org.apache.tools.ant.taskdefs.Ant"/>
+ </target>
+
+ <target name="test10">
+ <available property="test"
+ file="available.xml"
+ resource="org/apache/tools/ant/taskdefs/defaults.properties"
+ classname="org.apache.tools.ant.taskdefs.Ant"/>
+ </target>
+
+ <target name="test11">
+ <available property="test"
+ file="src/etc/testcases/taskdefs/available.xml"
+ resource="org/apache/tools/ant/taskdefs/defaults.properties"
+ classname="org.apache.tools.ant.taskdefs.this_class_does_not_exist"/>
+ </target>
+
+ <target name="test12">
+ <available property=""
+ file="available.xml"/>
+ </target>
+
+ <target name="test13">
+ <available property="test"
+ file="" type="file" />
+ </target>
+
+ <target name="test13b">
+ <available property="test"
+ file=""/>
+ </target>
+
+ <target name="test14">
+ <available property="test"
+ resource=""/>
+ </target>
+
+ <target name="test15">
+ <available property="test"
+ classname="org.apache.tools.ant.taskdefs.this_class_does_not_exist"/>
+ </target>
+
+ <target name="test16">
+ <available property="test"
+ file="" type="dir"/>
+ </target>
+
+ <target name="test17">
+ <available property="test"
+ file="../taskdefs" type="dir"/>
+ </target>
+
+ <target name="test18">
+ <available property="test"
+ file="../this_dir_should_never_exist" type="dir"/>
+ </target>
+
+ <target name="test19">
+ <available property="test"
+ file="available.xml" type="Foo"/>
+ </target>
+
+ <target name="test20">
+ <available property="test" ignoresystemclasses="true"
+ classname="java.awt.Graphics"/>
+ </target>
+
+ <target name="test21">
+ <available property="test" ignoresystemclasses="true"
+ classname="org.apache.tools.ant.launch.AntMain">
+ <classpath>
+ <pathelement location="${ant.home}/lib/ant-launcher.jar" />
+ </classpath>
+ </available>
+ </target>
+
+ <target name="test22">
+ <available property="test" ignoresystemclasses="false"
+ classname="java.awt.Graphics"/>
+ </target>
+
+ <target name="test23">
+ <available property="test"
+ classname="java.awt.Graphics"/>
+ </target>
+
+ <target name="test24">
+ <!-- create a dummy file and look for it -->
+ <mkdir dir="${output}/test"/>
+ <echo message="package test;public class test {}" file="${output}/test/test.java"/>
+ <javac srcdir="${output}" includes="test/test.java"/>
+ <jar destfile="${output}/test.jar" basedir="${output}" includes="test/test.class"/>
+ <available property="test"
+ classname="test.test" classpath="${output}/test.jar"/>
+ </target>
+
+ <target name="searchInPathNotThere">
+ <available file="not_there" filepath="..:optional"
+ property="test" />
+ </target>
+
+ <target name="searchInPathIsThere">
+ <available file="pvcs.xml" filepath="..:optional"
+ property="test" />
+ </target>
+
+ <target name="testDoubleBasedir">
+ <echo>testing ${basedir}${file.separator}${ant.file}</echo>
+ <fail>
+ <condition>
+ <available file="${basedir}${file.separator}${ant.file}" />
+ </condition>
+ </fail>
+ </target>
+
+ <target name="prep.parents">
+ <mkdir dir="${output}/greatgrandparent/grandparent/parent/dir"/>
+ <touch file="${output}/greatgrandparent/a.txt"/>
+ <touch file="${output}/greatgrandparent/grandparent/b.txt"/>
+ <touch file="${output}/greatgrandparent/grandparent/parent/c.txt"/>
+ <touch file="${output}/greatgrandparent/grandparent/parent/dir/d.txt"/>
+ <property name="available.test.dir"
+ value="${output}/greatgrandparent/grandparent/parent/dir"/>
+ </target>
+ <target name="search-parents" depends="prep.parents">
+ <echo>testing greatgrandparent - should see</echo>
+
+ <fail>
+ <condition>
+ <not>
+ <available file="a.txt" searchparents="yes">
+ <filepath path="${available.test.dir}"/>
+ </available>
+ </not>
+ </condition>
+ </fail>
+
+ <echo>testing grandparent - should see</echo>
+ <fail>
+ <condition>
+ <not>
+ <available file="b.txt" searchparents="yes">
+ <filepath path="${available.test.dir}"/>
+ </available>
+ </not>
+ </condition>
+ </fail>
+
+ <echo>testing parent - should see</echo>
+ <fail>
+ <condition>
+ <not>
+ <available file="c.txt" searchparents="yes">
+ <filepath path="${available.test.dir}"/>
+ </available>
+ </not>
+ </condition>
+ </fail>
+
+ <echo>testing dir - should see</echo>
+ <fail>
+ <condition>
+ <not>
+ <available file="d.txt" searchparents="yes">
+ <filepath path="${available.test.dir}"/>
+ </available>
+ </not>
+ </condition>
+ </fail>
+
+ </target>
+
+ <target name="search-parents-not" depends="prep.parents">
+ <echo>testing grandparent - should not see</echo>
+ <fail>
+ <condition>
+ <available file="b.txt">
+ <filepath path="${available.test.dir}"/>
+ </available>
+ </condition>
+ </fail>
+
+ <echo>testing parent - should not see</echo>
+ <fail>
+ <condition>
+ <available file="c.txt">
+ <filepath path="${available.test.dir}"/>
+ </available>
+ </condition>
+ </fail>
+
+ <echo>testing dir - should see</echo>
+ <fail>
+ <condition>
+ <not>
+ <available file="d.txt">
+ <filepath path="${available.test.dir}"/>
+ </available>
+ </not>
+ </condition>
+ </fail>
+
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/bar.properties b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/bar.properties
new file mode 100644
index 00000000..c64b91ea
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/bar.properties
@@ -0,0 +1,15 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+bar=Bar
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/basename.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/basename.xml
new file mode 100644
index 00000000..c5fd2abc
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/basename.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<project name="xxx-test" basedir="." default="test1">
+
+ <target name="test1">
+ <basename/>
+ </target>
+
+ <target name="test2">
+ <basename property="propname"/>
+ </target>
+
+ <target name="test3">
+ <basename file="filename"/>
+ </target>
+
+ <target name="test4">
+ <basename property="file.w.suf" file="${user.dir}/foo.txt"/>
+ </target>
+
+ <target name="test5">
+ <basename property="file.wo.suf" file="foo.txt" suffix="txt"/>
+ </target>
+
+ <target name="testMultipleDots">
+ <basename property="file.wo.suf" file="foo.bar.txt" suffix="txt"/>
+ </target>
+
+ <target name="testNoDots">
+ <basename property="file.wo.suf" file="foo.bartxt" suffix="txt"/>
+ </target>
+
+ <target name="testValueEqualsSuffixWithDot">
+ <basename property="file.wo.suf" file=".txt" suffix=".txt"/>
+ </target>
+
+ <target name="testValueEqualsSuffixWithoutDot">
+ <basename property="file.wo.suf" file=".txt" suffix="txt"/>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/bunzip2.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/bunzip2.xml
new file mode 100644
index 00000000..8ae17580
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/bunzip2.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<project basedir="." default="tearDown">
+
+ <import file="../buildfiletest-base.xml"/>
+
+ <target name="prepare">
+ <mkdir dir="${output}"/>
+ <gunzip src="expected/asf-logo-huge.tar.gz"
+ dest="${output}/asf-logo-huge-from-gzip.tar"/>
+ </target>
+
+ <target name="realTest">
+ <bunzip2 src="expected/asf-logo-huge.tar.bz2" dest="${output}/asf-logo-huge.tar" />
+ </target>
+
+ <target name="realTestWithResource">
+ <bunzip2 dest="${output}/asf-logo-huge.tar">
+ <file file="expected/asf-logo-huge.tar.bz2"/>
+ </bunzip2>
+ </target>
+
+ <target name="testDocumentationClaimsOnCopy">
+ <copy todir="${output}">
+ <bzip2resource>
+ <file file="expected/asf-logo-huge.tar.bz2"/>
+ </bzip2resource>
+ <mapper type="glob" from="*.bz2" to="*"/>
+ </copy>
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/bzip2.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/bzip2.xml
new file mode 100644
index 00000000..e133dae0
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/bzip2.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<project basedir="." default="cleanup">
+
+ <import file="../buildfiletest-base.xml"/>
+
+ <target name="realTest">
+ <bzip2 src="${output}/asf-logo-huge-from-gzip.tar"
+ zipfile="${output}/asf-logo-huge.tar.bz2" />
+ </target>
+
+ <target name="realTestWithResource">
+ <bzip2 zipfile="${output}/asf-logo-huge.tar.bz2">
+ <file file="${output}/asf-logo-huge-from-gzip.tar"/>
+ </bzip2>
+ </target>
+
+ <target name="testDateCheck">
+ <touch file="${output}/asf-logo.gif.bz2"/>
+ <bzip2 src="../asf-logo.gif" zipfile="${output}/asf-logo.gif.bz2" />
+ </target>
+
+ <target name="prepare">
+ <mkdir dir="${output}"/>
+ <gunzip src="expected/asf-logo-huge.tar.gz"
+ dest="${output}/asf-logo-huge-from-gzip.tar"/>
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/calltarget.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/calltarget.xml
new file mode 100644
index 00000000..4c3af92e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/calltarget.xml
@@ -0,0 +1,120 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="calltarget-test" default="testinheritreffileset" basedir=".">
+
+ <import file="../buildfiletest-base.xml"/>
+
+ <target name="setUp">
+ <mkdir dir="${output}"/>
+ </target>
+
+ <target name="mytarget">
+ <pathconvert property="myproperty" targetos="unix" refid="myfileset"/>
+ <echo message="myproperty=${myproperty}"/>
+ </target>
+
+ <target name="testinheritreffileset">
+ <!-- this testcase should show that the fileset defined here
+ can be read in the called target -->
+ <fileset dir="." id="myfileset">
+ <include name="calltarget.xml"/>
+ </fileset>
+ <antcall target="mytarget" inheritrefs="true"/>
+ </target>
+
+ <target name="copytest2">
+ <copy file="${output}/copytest.in" toFile="${output}/copytest1.out" overwrite="true">
+ <filterset refid="foo"/>
+ </copy>
+ </target>
+
+ <target name="testinheritreffilterset" depends="setUp">
+ <echo file="${output}/copytest.in">@@foo@@</echo>
+ <filterset id="foo" begintoken="@@" endtoken="@@">
+ <filter token="foo" value="bar"/>
+ </filterset>
+ <antcall target="copytest2" inheritrefs="true"/>
+ <copy file="${output}/copytest.in" toFile="${output}/copytest2.out" overwrite="true">
+ <filterset refid="foo"/>
+ </copy>
+ <loadfile srcFile="${output}/copytest2.out" property="copytest2"/>
+ <loadfile srcFile="${output}/copytest1.out" property="copytest1"/>
+ <condition property="success">
+ <equals arg1="${copytest1}" arg2="${copytest2}"/>
+ </condition>
+ <fail message="filterset not properly passed across by antcall" unless="success"/>
+ </target>
+
+ <property name="multi" value="DEFAULT"/>
+
+ <target name="multi">
+ <echo>multi is ${multi}</echo>
+ </target>
+
+ <target name="call-multi">
+ <antcall target="multi">
+ <param name="multi" value="SET"/>
+ </antcall>
+ </target>
+
+ <target name="blank-target">
+ <antcall>
+ <target name=""/>
+ </antcall>
+ </target>
+
+ <target name="multiple-targets">
+ <antcall>
+ <target name="ta"/>
+ <target name="tb"/>
+ <target name="tc"/>
+ </antcall>
+ </target>
+
+ <target name="multiple-targets-2">
+ <ant antfile="ant.xml">
+ <target name="tb"/>
+ <target name="da"/>
+ </ant>
+ </target>
+
+ <target name="ta">
+ <echo>ta</echo>
+ </target>
+
+ <target name="tb" depends="da,dc">
+ <echo>tb</echo>
+ </target>
+
+ <target name="tc" depends="db,dc">
+ <echo>tc</echo>
+ </target>
+
+ <target name="da">
+ <echo>da</echo>
+ </target>
+
+ <target name="db">
+ <echo>db</echo>
+ </target>
+
+ <target name="dc">
+ <echo>dc</echo>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/checksum.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/checksum.xml
new file mode 100644
index 00000000..e82fb697
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/checksum.xml
@@ -0,0 +1,266 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="cleanup" basedir=".">
+
+ <macrodef name="compare">
+ <attribute name="expected" />
+ <attribute name="output" />
+ <sequential>
+ <loadfile property="expected" srcfile="@{expected}">
+ <filterchain><striplinebreaks /></filterchain>
+ </loadfile>
+ <loadfile property="output" srcfile="@{output}">
+ <filterchain><striplinebreaks /></filterchain>
+ </loadfile>
+ <fail message="${output} not = ${expected}">
+ <condition>
+ <not>
+ <equals arg1="${output}" arg2="${expected}" />
+ </not>
+ </condition>
+ </fail>
+ </sequential>
+ </macrodef>
+
+ <macrodef name="testverify">
+ <attribute name="checknologo" default="false" />
+ <element name="stuff" implicit="true" />
+ <sequential>
+ <fail>
+ <condition>
+ <or>
+ <isset property="logo.MD5" />
+ <isset property="no.logo.MD5" />
+ </or>
+ </condition>
+ </fail>
+ <stuff />
+ <fail>
+ <condition>
+ <not>
+ <istrue value="${logo.MD5}" />
+ </not>
+ </condition>
+ </fail>
+ <fail>
+ <condition>
+ <and>
+ <istrue value="@{checknologo}" />
+ <not>
+ <isfalse value="${no.logo.MD5}" />
+ </not>
+ </and>
+ </condition>
+ </fail>
+ <fail>
+ <condition>
+ <and>
+ <isfalse value="@{checknologo}" />
+ <isset property="no.logo.MD5" />
+ </and>
+ </condition>
+ </fail>
+ </sequential>
+ </macrodef>
+
+ <target name="cleanup">
+ <delete file="../asf-logo.gif.MD5" />
+ <delete file="../asf-logo.gif.md5" />
+ <delete file="../asf-logo.gif.MD5SUM" />
+ <delete file="../asf-logo.gif.md5sum" />
+ <delete file="../asf-logo.gif.SVF" />
+ <delete file="../asf-logo.gif.svf" />
+ <delete file="../asf-logo.gif.pattern" />
+ <delete file="../asf-logo.gif.PATTERN" />
+ <delete>
+ <fileset dir="checksum">
+ <include name="**/*.MD5"/>
+ </fileset>
+ </delete>
+ <delete dir="checksum/checksums" />
+ </target>
+
+ <target name="createMd5">
+ <checksum file="../asf-logo.gif" fileext=".MD5" />
+ <compare expected="expected/asf-logo.gif.md5" output="../asf-logo.gif.MD5" />
+ </target>
+
+ <target name="createMD5SUMformat">
+ <checksum file="../asf-logo.gif" format="MD5SUM" fileext=".MD5SUM" />
+ <compare expected="expected/asf-logo.gif.md5sum" output="../asf-logo.gif.MD5SUM" />
+ </target>
+
+ <target name="createSVFformat">
+ <checksum file="../asf-logo.gif" format="SVF" fileext=".SVF" />
+ <compare expected="expected/asf-logo.gif.svf" output="../asf-logo.gif.SVF" />
+ </target>
+
+ <target name="createPattern">
+ <checksum file="../asf-logo.gif" pattern="foo{0}bar" fileext=".PATTERN" />
+ <compare expected="expected/asf-logo.gif.pattern" output="../asf-logo.gif.PATTERN" />
+ </target>
+
+ <target name="setProperty">
+ <checksum file="../asf-logo.gif" property="logo.MD5" />
+ <fail>
+ <condition>
+ <or>
+ <not>
+ <equals arg1="0541d3df42520911f268abc730f3afe0"
+ arg2="${logo.MD5}" />
+ </not>
+ <available file="../asf-logo.gif.MD5" />
+ </or>
+ </condition>
+ </fail>
+ </target>
+
+ <target name="verifyAsTask">
+ <testverify checknologo="true">
+ <copy file="expected/asf-logo.gif.md5" todir=".." />
+ <checksum file="../asf-logo.gif" fileext=".md5"
+ verifyproperty="logo.MD5" />
+
+ <copy file="checksum.xml" tofile="../asf-logo.gif.MD5"
+ overwrite="true" />
+ <checksum file="../asf-logo.gif" fileext=".MD5"
+ verifyproperty="no.logo.MD5" />
+ </testverify>
+ </target>
+
+ <target name="verifyMD5SUMAsTask">
+ <testverify checknologo="true">
+ <copy file="expected/asf-logo.gif.md5sum" todir=".." />
+ <checksum file="../asf-logo.gif" fileext=".md5sum"
+ verifyproperty="logo.MD5" format="MD5SUM"/>
+
+ <copy file="checksum.xml" tofile="../asf-logo.gif.MD5SUM"
+ overwrite="true" />
+ <checksum file="../asf-logo.gif" fileext=".MD5SUM"
+ verifyproperty="no.logo.MD5" format="MD5SUM"/>
+ </testverify>
+ </target>
+
+ <target name="verifyAsCondition">
+ <testverify>
+ <copy file="expected/asf-logo.gif.md5" todir=".." />
+ <condition property="logo.MD5">
+ <checksum file="../asf-logo.gif" fileext=".md5" />
+ </condition>
+
+ <copy file="checksum.xml" tofile="../asf-logo.gif.MD5"
+ overwrite="true" />
+ <condition property="no.logo.MD5">
+ <checksum file="../asf-logo.gif" fileext=".MD5" />
+ </condition>
+ </testverify>
+ </target>
+
+ <target name="verifyFromProperty">
+ <fail>
+ <condition>
+ <isset property="verify" />
+ </condition>
+ </fail>
+ <checksum property="checksum" file="checksum.xml"/>
+ <checksum property="${checksum}" file="checksum.xml"
+ verifyproperty="verify"/>
+ <fail>
+ <condition>
+ <not>
+ <istrue value="${verify}" />
+ </not>
+ </condition>
+ </fail>
+ </target>
+
+ <target name="verifyTotal">
+ <checksum totalproperty="total">
+ <fileset dir="${basedir}/checksum">
+ <exclude name="**/*.MD5"/>
+ </fileset>
+ </checksum>
+ <fail>
+ <condition>
+ <not>
+ <equals arg1="ef8f1477fcc9bf93832c1a74f629c626" arg2="${total}" />
+ </not>
+ </condition>
+ </fail>
+ </target>
+
+ <target name="verifyTotalRC">
+ <checksum totalproperty="total">
+ <resources>
+ <fileset dir="${basedir}/checksum">
+ <exclude name="**/*.MD5"/>
+ </fileset>
+ </resources>
+ </checksum>
+ <fail>
+ <condition>
+ <not>
+ <equals arg1="ef8f1477fcc9bf93832c1a74f629c626" arg2="${total}" />
+ </not>
+ </condition>
+ </fail>
+ </target>
+
+ <target name="verifyChecksumdir">
+ <checksum totalproperty="total" todir="${basedir}/checksum/checksums">
+ <fileset dir="${basedir}/checksum">
+ <exclude name="**/*.MD5"/>
+ </fileset>
+ </checksum>
+ <fail>
+ <condition>
+ <not>
+ <equals arg1="ef8f1477fcc9bf93832c1a74f629c626" arg2="${total}" />
+ </not>
+ </condition>
+ </fail>
+ <pathconvert property="srcdirfile">
+ <file file="checksum/foo/zap/Eenie.MD5" />
+ </pathconvert>
+ <pathconvert property="destdirfile">
+ <file file="checksum/checksums/foo/zap/Eenie.MD5" />
+ </pathconvert>
+ <fail message="Checksums should be written to ${destdirfile}">
+ <condition>
+ <not>
+ <available file="${destdirfile}" />
+ </not>
+ </condition>
+ </fail>
+ <fail message="Checksums should not be written to ${srcdirfile}">
+ <condition>
+ <available file="${srcdirfile}" />
+ </condition>
+ </fail>
+ </target>
+
+ <!-- bug report 25606 -->
+ <target name="verifyChecksumdirNoTotal">
+ <checksum todir="${basedir}/checksum/checksums">
+ <fileset dir="${basedir}/checksum">
+ <exclude name="**/*.MD5"/>
+ </fileset>
+ </checksum>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/checksum/foo/Bar b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/checksum/foo/Bar
new file mode 100644
index 00000000..c2bc8eef
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/checksum/foo/Bar
@@ -0,0 +1 @@
+Barbapapa \ No newline at end of file
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/checksum/foo/zap/Eenie b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/checksum/foo/zap/Eenie
new file mode 100644
index 00000000..d689175d
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/checksum/foo/zap/Eenie
@@ -0,0 +1 @@
+Meenie Minie Moe \ No newline at end of file
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/classloader.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/classloader.xml
new file mode 100644
index 00000000..02e47ab5
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/classloader.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="classloader-test" default="main" basedir=".">
+
+ <target name="init">
+
+ <path id="myJars" >
+ <!-- both ant-junit.jar and junit.jar must be loaded from the same path -->
+ <pathelement path="${ant.home}/lib/ant-junit.jar" />
+ <pathelement path="${junit.jar}" />
+ </path>
+
+ <classloader classpathRef="myJars"
+ reverse="true" >
+
+ </classloader>
+ <junit />
+
+ </target>
+
+ <target name="main" depends="init">
+ <echo message="Found JUNIT" />
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/concat-input/A b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/concat-input/A
new file mode 100644
index 00000000..2e65efe2
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/concat-input/A
@@ -0,0 +1 @@
+a \ No newline at end of file
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/concat-input/B b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/concat-input/B
new file mode 100644
index 00000000..63d8dbd4
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/concat-input/B
@@ -0,0 +1 @@
+b \ No newline at end of file
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/concat.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/concat.xml
new file mode 100644
index 00000000..235b1528
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/concat.xml
@@ -0,0 +1,214 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<project name="concat-test" basedir="." default="test1">
+
+ <property name="tmp.file" value="concat.tmp" />
+ <property name="tmp.file.2" value="concat.tmp.2" />
+
+ <property name="world" value="World" />
+
+ <target name="cleanup">
+ <delete file="TESTDEST"/>
+ <delete file="${tmp.file}"/>
+ <delete file="${tmp.file.2}"/>
+ <delete file="concat.line4"/>
+ <delete file="concat.noeol"/>
+ <delete file="concat.linecr"/>
+ <delete file="concat.utf8"/>
+ <delete file="concat.urls"/>
+ </target>
+
+ <target name="test1">
+ <concat>
+ </concat>
+ </target>
+
+ <target name="test2">
+ <concat destfile="">Hello, ${world}!</concat>
+ </target>
+
+ <target name="test3">
+ <concat destfile="${tmp.file}">Hello, ${world}!</concat>
+ </target>
+
+ <target name="test4">
+ <concat destfile="${tmp.file.2}">
+ <fileset dir="${basedir}" includes="${tmp.file}" />
+ <filelist dir="${basedir}" files="${tmp.file},${tmp.file}" />
+ </concat>
+ </target>
+
+ <target name="test5">
+ <concat>Hello, ${world}!</concat>
+ </target>
+
+ <target name="test6">
+ <concat destfile="TESTDEST" append="true">
+ <filelist dir="${basedir}" files="thisfiledoesnotexist"/>
+ </concat>
+ <available file="TESTDEST" property="TESTDEST.was.created"/>
+ <fail message="TESTDEST created for nonexistent files"
+ if="TESTDEST.was.created"/>
+ </target>
+
+ <target name="testConcatNoNewline">
+ <concat>
+ <fileset dir="concat-input"/>
+ </concat>
+ </target>
+
+ <target name="testConcatNoNewlineEncoding">
+ <concat encoding="ASCII">
+ <fileset dir="concat-input"/>
+ </concat>
+ </target>
+
+ <target name="testPath">
+ <concat destfile="${tmp.file.2}">
+ <path path="${tmp.file}"/>
+ </concat>
+ </target>
+
+ <target name="testAppend">
+ <concat destfile="${tmp.file.2}">
+ <path path="${tmp.file}"/>
+ </concat>
+ <concat destfile="${tmp.file.2}" append="true">
+ <path path="${tmp.file}"/>
+ </concat>
+ </target>
+
+ <target name="testfilter">
+ <concat destfile="${tmp.file}">@REPLACEME@</concat>
+ <concat>
+ <path path="${tmp.file}"/>
+ <filterchain>
+ <replacetokens>
+ <token key="REPLACEME" value="REPLACED"/>
+ </replacetokens>
+ </filterchain>
+ </concat>
+ </target>
+
+ <target name="testnooverwrite">
+ <touch file="${tmp.file.2}"/>
+ <!-- concat.xml is now older than tmp.file.2
+ so the following should not do anything -->
+ <concat destfile="${tmp.file.2}" overwrite="false">
+ <path path="concat.xml"/>
+ </concat>
+ </target>
+
+ <target name="testoverwrite">
+ <touch file="${tmp.file.2}"/>
+ <!-- concat.xml is now older than tmp.file.2
+ so the following should still overwrite it -->
+ <concat destfile="${tmp.file.2}" overwrite="true">
+ <path path="concat.xml"/>
+ </concat>
+ </target>
+
+ <target name="testheaderfooter">
+ <concat>
+ <header filtering="false" trim="yes">
+ header
+ </header>
+ <path path="${tmp.file}"/>
+ <footer filtering="no">footer</footer>
+ </concat>
+ </target>
+
+ <target name="testfileheader">
+ <concat>
+ <header file="${tmp.file}"/>
+ <path path="${tmp.file}"/>
+ </concat>
+ </target>
+
+ <target name="samefile">
+ <touch file="${tmp.file}"/>
+ <concat destfile="${tmp.file}">
+ <path path="${tmp.file}"/>
+ </concat>
+ </target>
+
+ <target name="testfilterinline">
+ <concat>
+ @REPLACEME@
+ <filterchain>
+ <replacetokens>
+ <token key="REPLACEME" value="REPLACED"/>
+ </replacetokens>
+ </filterchain>
+ </concat>
+ </target>
+
+ <target name="testmultireader">
+ <concat destfile="${tmp.file}">Hello, World
+ </concat>
+ <concat destfile="${tmp.file.2}">Bye, World
+ </concat>
+ <concat>
+ <path path="${tmp.file}"/>
+ <path path="${tmp.file}"/>
+ <path path="${tmp.file}"/>
+ <path path="${tmp.file}"/>
+ <path path="${tmp.file}"/>
+ <path path="${tmp.file}"/>
+ <path path="${tmp.file}"/>
+ <path path="${tmp.file}"/>
+ <path path="${tmp.file}"/>
+ <!-- tailfilter seems to behave a little stange, place two
+ here in case the implementation changes -->
+ <path path="${tmp.file.2}"/>
+ <path path="${tmp.file.2}"/>
+ <filterchain>
+ <tailfilter lines="2"/>
+ </filterchain>
+ </concat>
+ </target>
+
+ <target name="create-noel">
+ <concat destfile="concat.noeol">This has no end of line</concat>
+ </target>
+
+ <target name="testfixlastline" depends="create-noel">
+ <concat destfile="concat.line4" fixlastline="yes">
+ <path path="concat.noeol"/>
+ <path path="concat.noeol"/>
+ <path path="concat.noeol"/>
+ <path path="concat.noeol"/>
+ </concat>
+ </target>
+
+ <target name="testfixlastlineeol" depends="create-noel">
+ <concat destfile="concat.linecr" fixlastline="yes" eol="mac">
+ <path path="concat.noeol"/>
+ <path path="concat.noeol"/>
+ </concat>
+ </target>
+
+ <target name="testTranscoding">
+ <concat destfile="concat.utf8"
+ encoding="ISO8859_1" outputencoding="UTF8">
+ <path path="copy/input/iso8859-1"/>
+ </concat>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/condition.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/condition.xml
new file mode 100644
index 00000000..81660ae6
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/condition.xml
@@ -0,0 +1,521 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<!-- test conditioning -->
+<project name="condition-test" basedir="." default="test1">
+
+ <target name="basic">
+ <condition property="basic">
+ <equals arg1="a" arg2="a" />
+ </condition>
+ <echo>${basic}</echo>
+ </target>
+
+ <target name="condition-incomplete">
+ <condition >
+ <equals arg1="a" arg2="a" />
+ </condition>
+ </target>
+
+ <target name="condition-empty">
+ <condition property="condition-empty"/>
+ <echo>${condition-empty}</echo>
+ </target>
+
+ <target name="shortcut">
+ <property name="shortcut" value="set"/>
+ <condition property="shortcut">
+ <equals arg1="a" arg2="a" />
+ </condition>
+ <echo>${shortcut}</echo>
+ </target>
+
+ <target name="dontset">
+ <condition property="dontset">
+ <equals arg1="a" arg2="b" />
+ </condition>
+ <echo>${dontset}</echo>
+ </target>
+
+ <target name="setvalue">
+ <condition property="setvalue" value="woowoo" >
+ <equals arg1="a" arg2="a" />
+ </condition>
+ <echo>${setvalue}</echo>
+ </target>
+
+ <target name="negation">
+ <condition property="negation">
+ <not>
+ <equals arg1="a" arg2="B" />
+ </not>
+ </condition>
+ <echo>${negation}</echo>
+ </target>
+
+ <target name="negationfalse">
+ <condition property="negationfalse">
+ <not>
+ <equals arg1="a" arg2="a" />
+ </not>
+ </condition>
+ <echo>${negationfalse}</echo>
+ </target>
+
+ <target name="negationincomplete">
+ <condition property="negationincomplete">
+ <not />
+ </condition>
+ <echo>${negationincomplete}</echo>
+ </target>
+
+ <target name="and">
+ <condition property="and">
+ <and>
+ <equals arg1="a" arg2="a" />
+ <equals arg1="B" arg2="B" />
+ </and>
+ </condition>
+ <echo>${and}</echo>
+ </target>
+
+ <target name="andfails">
+ <condition property="andfails">
+ <and>
+ <equals arg1="a" arg2="B" />
+ <equals arg1="B" arg2="a" />
+ </and>
+ </condition>
+ <echo>${andfails}</echo>
+ </target>
+
+ <target name="andincomplete">
+ <condition property="andincomplete">
+ <and>
+ <equals arg1="a" arg2="B" />
+ </and>
+ </condition>
+ <echo>${andincomplete}</echo>
+ </target>
+
+ <target name="andempty">
+ <condition property="andempty">
+ <and/>
+ </condition>
+ <echo>${andempty}</echo>
+ </target>
+
+ <target name="or">
+ <condition property="or">
+ <or>
+ <equals arg1="a" arg2="B" />
+ <equals arg1="B" arg2="B" />
+ </or>
+ </condition>
+ <echo>${or}</echo>
+ </target>
+
+ <target name="orincomplete">
+ <condition property="orincomplete">
+ <or>
+ <equals arg1="a" arg2="a" />
+ </or>
+ </condition>
+ <echo>${orincomplete}</echo>
+ </target>
+
+ <target name="orempty">
+ <condition property="orempty">
+ <or/>
+ </condition>
+ <echo>${orempty}</echo>
+ </target>
+
+ <target name="orfails">
+ <condition property="orfails">
+ <or>
+ <equals arg1="a" arg2="B" />
+ <equals arg1="B" arg2="a" />
+ </or>
+ </condition>
+ <echo>${orfails}</echo>
+ </target>
+
+ <target name="orboth">
+ <condition property="orboth">
+ <or>
+ <equals arg1="a" arg2="a" />
+ <equals arg1="B" arg2="B" />
+ </or>
+ </condition>
+ <echo>${orboth}</echo>
+ </target>
+
+ <target name="filesmatch-identical" >
+ <condition property="filesmatch-identical">
+ <filesmatch
+ file1="condition.xml"
+ file2="condition.xml" />
+ </condition>
+ <echo>${filesmatch-identical}</echo>
+ </target>
+
+ <target name="filesmatch-incomplete" >
+ <condition property="filesmatch-incomplete">
+ <filesmatch
+ file1="condition.xml"/>
+ </condition>
+ <echo>${filesmatch-incomplete}</echo>
+ </target>
+
+ <target name="filesmatch-oddsizes" >
+ <condition property="filesmatch-oddsizes">
+ <filesmatch
+ file1="condition.xml"
+ file2="property.xml" />
+ </condition>
+ <echo>${filesmatch-oddsizes}</echo>
+ </target>
+
+ <target name="filesmatch-existence" >
+ <condition property="filesmatch-existence">
+ <filesmatch
+ file1="condition.xml"
+ file2="this-file-doesnt-exist.xml" />
+ </condition>
+ <echo>${filesmatch-existence}</echo>
+ </target>
+
+ <target name="filesmatch-neitherexist">
+ <fail>
+ <condition>
+ <not>
+ <filesmatch file1="idonotexist" file2="andneitherdoi" />
+ </not>
+ </condition>
+ </fail>
+ </target>
+
+ <target name="filesmatch-different">
+ <echo file="match1.txt" message="012345676890" />
+ <echo file="match2.txt" message="012345676889" />
+ <condition property="filesmatch-different">
+ <filesmatch
+ file1="match1.txt"
+ file2="match2.txt" />
+ </condition>
+ <echo>${filesmatch-different}</echo>
+ </target>
+
+ <target name="filesmatch-match" >
+ <echo file="match3.txt" message="012345676890" />
+ <echo file="match4.txt" message="012345676890" />
+ <condition property="filesmatch-match">
+ <filesmatch
+ file1="match3.txt"
+ file2="match4.txt" />
+ </condition>
+ <echo>${filesmatch-match}</echo>
+ </target>
+
+ <target name="filesmatch-different-eol" >
+ <echo file="match7.txt" message="012345676890" />
+ <echo file="match8.txt" message="012345676890" />
+ <fixcrlf file="match7.txt" eol="cr" fixlast="true" />
+ <fixcrlf file="match8.txt" eol="lf" fixlast="true" />
+ <fail>
+ <condition>
+ <filesmatch file1="match7.txt" file2="match8.txt" />
+ </condition>
+ </fail>
+ </target>
+
+ <target name="filesmatch-same-eol" >
+ <echo file="match9.txt" message="012345676890" />
+ <echo file="match10.txt" message="012345676890" />
+ <fixcrlf file="match9.txt" eol="crlf" fixlast="true" />
+ <fixcrlf file="match10.txt" eol="lf" fixlast="true" />
+ <fail>
+ <condition>
+ <not>
+ <filesmatch file1="match9.txt" file2="match10.txt" textfile="true" />
+ </not>
+ </condition>
+ </fail>
+ </target>
+
+ <target name="filesmatch-different-sizes">
+ <echo file="match5.txt" message="012345676890" />
+ <echo file="match6.txt" message="0123456768" />
+ <condition property="filesmatch-different-sizes">
+ <filesmatch
+ file1="match5.txt"
+ file2="match6.txt" />
+ </condition>
+ <echo>${filesmatch-different-sizes}</echo>
+ </target>
+
+ <target name="filesmatch-different-onemissing">
+ <condition property="filesmatch-different-sizes">
+ <filesmatch
+ file1="condition.xml"
+ file2="missing-file.txt" />
+ </condition>
+ <echo>${filesmatch-different-onemissing}</echo>
+ </target>
+
+ <target name="contains" >
+ <condition property="contains">
+ <contains
+ string="abcd"
+ substring="cd" />
+ </condition>
+ <echo>${contains}</echo>
+ </target>
+
+ <target name="contains-doesnt" >
+ <condition property="contains-doesnt">
+ <contains
+ string="abcd"
+ substring="CD" />
+ </condition>
+ <echo>${contains-doesnt}</echo>
+ </target>
+
+ <target name="contains-anycase" >
+ <condition property="contains-anycase">
+ <contains casesensitive="false"
+ string="abcd"
+ substring="CD" />
+ </condition>
+ <echo>${contains-anycase}</echo>
+ </target>
+
+ <target name="contains-incomplete1" >
+ <condition property="contains-incomplete1">
+ <contains
+ string="abcd" />
+ </condition>
+ <echo>${contains-incomplete1}</echo>
+ </target>
+
+ <target name="contains-incomplete2" >
+ <condition property="contains-incomplete2">
+ <contains
+ substring="CD" />
+ </condition>
+ <echo>${contains-incomplete2}</echo>
+ </target>
+
+ <target name="istrue" >
+ <property name="t" value="true" />
+ <property name="o" value="o" />
+ <property name="n" value="n" />
+ <condition property="istrue">
+ <and>
+ <istrue value="${t}" />
+ <istrue value="TRUE" />
+ <istrue value="yes" />
+ <istrue value="YeS" />
+ <istrue value="on" />
+ <istrue value="${o}${n}" />
+ </and>
+ </condition>
+ <echo>${istrue}</echo>
+ </target>
+
+ <target name="istrue-not" >
+ <condition property="istrue-not">
+ <istrue
+ value="this sentence is true" />
+ </condition>
+ <echo>${istrue-not}</echo>
+ </target>
+
+ <target name="istrue-false" >
+ <condition property="istrue-false">
+ <or>
+ <istrue value="false" />
+ <istrue value="" />
+ </or>
+ </condition>
+ <echo>${istrue-false}</echo>
+ </target>
+
+ <target name="istrue-incomplete" >
+ <condition property="istrue-incomplete">
+ <istrue />
+ </condition>
+ <echo>${istrue-incomplete}</echo>
+ </target>
+
+ <target name="isfalse-true" >
+ <property name="t" value="true" />
+ <condition property="isfalse-true">
+ <isfalse
+ value="${t}" />
+ </condition>
+ <echo>${isfalse-true}</echo>
+ </target>
+
+ <target name="isfalse-not" >
+ <condition property="isfalse-not">
+ <isfalse
+ value="this sentence is true" />
+ </condition>
+ <echo>${isfalse-not}</echo>
+ </target>
+
+ <target name="isfalse-false" >
+ <condition property="isfalse-false">
+ <isfalse
+ value="false" />
+ </condition>
+ <echo>${isfalse-false}</echo>
+ </target>
+
+ <target name="isfalse-incomplete" >
+ <condition property="isfalse-incomplete">
+ <isfalse />
+ </condition>
+ <echo>${isfalse-incomplete}</echo>
+ </target>
+
+ <target name="testElse">
+ <condition property="unset" value="foo">
+ <or />
+ </condition>
+ <condition property="value" value="foo" else="bar">
+ <and />
+ </condition>
+ <condition property="else" value="foo" else="bar">
+ <or />
+ </condition>
+ <fail>
+ <condition>
+ <or>
+ <isset property="unset" />
+ <not>
+ <and>
+ <equals arg1="${value}" arg2="foo" />
+ <equals arg1="${else}" arg2="bar" />
+ </and>
+ </not>
+ </or>
+ </condition>
+ </fail>
+ </target>
+
+ <target name="resourcesmatch-error">
+ <condition property="errorexpected">
+ <resourcesmatch />
+ </condition>
+ </target>
+
+ <target name="resourcesmatch-match-empty">
+ <condition property="errorexpected">
+ <resourcesmatch>
+ <resources />
+ </resourcesmatch>
+ </condition>
+ </target>
+
+ <target name="resourcesmatch-match-one">
+ <condition property="errorexpected">
+ <resourcesmatch>
+ <string value="foo" />
+ </resourcesmatch>
+ </condition>
+ </target>
+
+ <target name="resourcesmatch-match-binary">
+ <fail>
+ <condition>
+ <not>
+ <resourcesmatch>
+ <string value="foo" />
+ <string value="foo" />
+ </resourcesmatch>
+ </not>
+ </condition>
+ </fail>
+ </target>
+
+ <target name="resourcesmatch-match-multiple-binary">
+ <fail>
+ <condition>
+ <not>
+ <resourcesmatch>
+ <string value="foo" />
+ <string value="foo" />
+ <string value="foo" />
+ </resourcesmatch>
+ </not>
+ </condition>
+ </fail>
+ </target>
+
+ <target name="resourcesmatch-differ">
+ <echo file="match11.txt" message="foo" />
+ <fixcrlf file="match11.txt" eol="crlf" fixlast="true" />
+ <fail>
+ <condition>
+ <resourcesmatch>
+ <file file="match11.txt" />
+ <string value="foo" />
+ </resourcesmatch>
+ </condition>
+ </fail>
+ </target>
+
+ <target name="resourcesmatch-match-text">
+ <echo file="match11.txt" message="foo" />
+ <fixcrlf file="match11.txt" eol="crlf" />
+ <fail>
+ <condition>
+ <not>
+ <resourcesmatch astext="true">
+ <file file="match11.txt" />
+ <string value="foo" />
+ </resourcesmatch>
+ </not>
+ </condition>
+ </fail>
+ </target>
+
+ <target name="resourcesmatch-noneexist">
+ <fail>
+ <condition>
+ <not>
+ <resourcesmatch>
+ <resource name="foo" exists="false" />
+ <resource name="bar" exists="false" />
+ <resource name="baz" exists="false" />
+ </resourcesmatch>
+ </not>
+ </condition>
+ </fail>
+ </target>
+
+ <target name="cleanup" >
+ <delete>
+ <fileset dir="." includes="match?.txt,match??.txt" />
+ </delete>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/conditions/antversion.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/conditions/antversion.xml
new file mode 100644
index 00000000..8a54cb01
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/conditions/antversion.xml
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="testantversion" default="testatleast">
+
+ <target name="testatleast">
+ <fail>
+ <condition>
+ <not>
+ <antversion atleast="1.7" />
+ </not>
+ </condition>
+ Should be at least 1.7
+ </fail>
+ </target>
+
+ <target name="testexactly">
+ <fail>
+ <condition>
+ <not>
+ <antversion exactly="1.9.6" />
+ </not>
+ </condition>
+ Should be exactly 1.9.6
+
+ </fail>
+ </target>
+
+ <target name="testatleastfail">
+ <property name="version" value="1.8.9" />
+ <fail>
+ <condition>
+ <not>
+ <antversion atleast="1.9.6" />
+ </not>
+ </condition>
+ Should be at least 1.9.6
+ </fail>
+ </target>
+
+ <target name="testexactlyfail">
+ <property name="version" value="1.8.0" />
+ <fail>
+ <condition>
+ <not>
+ <antversion exactly="1.9.6" />
+ </not>
+ </condition>
+ Should be exactly 1.9.6
+ </fail>
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/conditions/http.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/conditions/http.xml
new file mode 100644
index 00000000..76e87cbe
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/conditions/http.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="nope">
+
+ <target name="nope">
+ <fail>This build file should be run by a testcase</fail>
+ </target>
+
+ <target name="basic-no-method">
+ <condition property="basic-no-method">
+ <http url="http://ant.apache.org/"/>
+ </condition>
+ <condition property="basic-no-method-bad-url">
+ <http url="http://ant.apache.org/this-page-does-not-exist"/>
+ </condition>
+ </target>
+
+ <target name="test-head-request">
+ <condition property="test-head-request">
+ <http url="http://ant.apache.org/" requestMethod="HEAD"/>
+ </condition>
+ <condition property="test-head-request-bad-url">
+ <http url="http://ant.apache.org/this-page-does-not-exist" requestMethod="HEAD"/>
+ </condition>
+ </target>
+
+ <target name="test-get-request">
+ <condition property="test-get-request">
+ <http url="http://ant.apache.org/" requestMethod="GET"/>
+ </condition>
+ <condition property="test-get-request-bad-url">
+ <http url="http://ant.apache.org/this-page-does-not-exist" requestMethod="GET"/>
+ </condition>
+ </target>
+
+ <target name="bad-request-method">
+ <condition property="bad-request-method">
+ <http url="http://ant.apache.org" requestMethod="UNKNOWN"/>
+ </condition>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/conditions/isfailure.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/conditions/isfailure.xml
new file mode 100644
index 00000000..b5d1a6a4
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/conditions/isfailure.xml
@@ -0,0 +1,65 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="testisfailure">
+
+ <target name="testisfailure">
+ <fail>
+ <condition>
+ <or>
+ <and>
+ <os family="openvms" />
+ <or>
+ <isfailure code="1" />
+ <isfailure code="3" />
+ <isfailure code="5" />
+ <isfailure code="7" />
+ <isfailure code="9" />
+ <not>
+ <and>
+ <isfailure code="0" />
+ <isfailure code="2" />
+ <isfailure code="4" />
+ <isfailure code="6" />
+ <isfailure code="8" />
+ </and>
+ </not>
+ </or>
+ </and>
+ <and>
+ <not>
+ <os family="openvms" />
+ </not>
+ <or>
+ <isfailure code="0" />
+ <not>
+ <and>
+ <isfailure code="1" />
+ <isfailure code="10" />
+ <isfailure code="50" />
+ <isfailure code="100" />
+ <isfailure code="255" />
+ </and>
+ </not>
+ </or>
+ </and>
+ </or>
+ </condition>
+ </fail>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/conditions/isfileselected.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/conditions/isfileselected.xml
new file mode 100644
index 00000000..0626eedb
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/conditions/isfileselected.xml
@@ -0,0 +1,70 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project>
+ <macrodef name="pass">
+ <element name="conditions" implicit="yes"/>
+ <attribute name="failmessage"/>
+ <sequential>
+ <fail message="@{failmessage}">
+ <condition>
+ <not>
+ <conditions/>
+ </not>
+ </condition>
+ </fail>
+ </sequential>
+ </macrodef>
+
+ <target name="simple">
+ <pass failmessage="a simple test">
+ <isfileselected file="jars/pass.jar">
+ <signedselector/>
+ </isfileselected>
+ </pass>
+ </target>
+
+ <target name="name">
+ <pass failmessage="name did not match">
+ <isfileselected file="jars/nosign.jar">
+ <filename name="jars/nosign.jar"/>
+ </isfileselected>
+ </pass>
+ </target>
+
+ <target name="basedir">
+ <pass failmessage="name did not match with a basedir change">
+ <isfileselected file="jars/nosign.jar" basedir="jars">
+ <filename name="nosign.jar"/>
+ </isfileselected>
+ </pass>
+ </target>
+
+ <target name="type">
+ <pass failmessage="type selector did not work">
+ <isfileselected file="isfileselected.xml">
+ <type type="file"/>
+ </isfileselected>
+ </pass>
+ </target>
+
+ <target name="not.selector">
+ <fileset dir=".">
+ <isfileselected file="nosigned.jar"/>
+ </fileset>
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/conditions/isreachable.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/conditions/isreachable.xml
new file mode 100644
index 00000000..3f74aef7
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/conditions/isreachable.xml
@@ -0,0 +1,105 @@
+<?xml version="1.0"?>
+<project name="isreachable">
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+
+ <macrodef name="assertHostReachable">
+ <attribute name="host"/>
+ <sequential>
+ <fail message="not reachable: @{host}">
+ <condition>
+ <not>
+ <isreachable host="@{host}"/>
+ </not>
+ </condition>
+ </fail>
+ </sequential>
+ </macrodef>
+
+ <macrodef name="assertHostNotReachable">
+ <attribute name="host"/>
+ <sequential>
+ <fail message="unexpectedly reachable: @{host}">
+ <condition>
+ <isreachable host="@{host}"/>
+ </condition>
+ </fail>
+ </sequential>
+ </macrodef>
+
+ <macrodef name="assertUrlReachable">
+ <attribute name="url"/>
+ <sequential>
+ <fail message="not reachable: @{url}">
+ <condition>
+ <not>
+ <isreachable url="@{url}"/>
+ </not>
+ </condition>
+ </fail>
+ </sequential>
+ </macrodef>
+
+ <target name="testLocalhost">
+ <assertHostReachable host="localhost"/>
+ </target>
+
+ <!-- bugs in XPSP2 mean this is the only IPv4 loopback addr allowed -->
+ <target name="testIpv4localhost">
+ <assertHostReachable host="127.0.0.1"/>
+ </target>
+
+ <target name="testBoth">
+ <condition property="both">
+ <isreachable host="localhost" url="http://localhost"/>
+ </condition>
+ <fail>Expected failure before here</fail>
+ </target>
+
+ <target name="testLocalhostURL">
+ <assertUrlReachable url="http://localhost"/>
+ </target>
+
+ <target name="testIpv4localhostURL">
+ <assertUrlReachable url="http://127.0.0.1/"/>
+ </target>
+
+ <target name="testFTPURL">
+ <assertUrlReachable url="ftp://localhost"/>
+ </target>
+
+ <target name="testFile">
+ <assertUrlReachable url="file://build.xml"/>
+ </target>
+
+ <target name="testBadURL">
+ <assertUrlReachable url="uuid:3349-4404-0ac0ddee"/>
+ </target>
+
+ <target name="testBadTimeout">
+ <condition property="testBadTimeout">
+ <isreachable host="localhost" timeout="-1"/>
+ </condition>
+ </target>
+
+ <target name="testNoTargets">
+ <condition property="none">
+ <isreachable/>
+ </condition>
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/conditions/isreference.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/conditions/isreference.xml
new file mode 100644
index 00000000..d1f86db9
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/conditions/isreference.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="nope">
+ <path id="global-path-id"/>
+ <echo id="echo-id"/>
+
+ <target name="nope">
+ <fail>This build file should be run by a testcase</fail>
+ </target>
+
+ <target name="define">
+ <path id="target-path-id"/>
+ </target>
+
+ <target name="basic" depends="define">
+ <condition property="global-path">
+ <isreference refid="global-path-id"/>
+ </condition>
+ <condition property="target-path">
+ <isreference refid="target-path-id"/>
+ </condition>
+ </target>
+
+ <target name="isreference-incomplete">
+ <condition property="foo">
+ <isreference/>
+ </condition>
+ </target>
+
+ <target name="type">
+ <condition property="global-path">
+ <isreference refid="global-path-id" type="path"/>
+ </condition>
+ <condition property="global-path-as-fileset">
+ <isreference refid="global-path-id" type="fileset"/>
+ </condition>
+ <condition property="global-path-as-foo">
+ <isreference refid="global-path-id" type="foo"/>
+ </condition>
+ <condition property="global-echo">
+ <isreference refid="echo-id" type="echo"/>
+ </condition>
+ </target>
+
+</project> \ No newline at end of file
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/conditions/issigned.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/conditions/issigned.xml
new file mode 100644
index 00000000..7cbf328f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/conditions/issigned.xml
@@ -0,0 +1,78 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="all">
+
+ <target name="pass" description="check if a name of pass is ok">
+ <fail message="name of pass not seen in the signed pass.jar">
+ <condition>
+ <not>
+ <issigned file="jars/pass.jar" name="pass"/>
+ </not>
+ </condition>
+ </fail>
+ </target>
+
+ <target name="password" description="check if a name of password is *not* ok">
+ <fail message="name of password is seen in the signed pass.jar">
+ <condition>
+ <issigned file="jars/pass.jar" name="password"/>
+ </condition>
+ </fail>
+ </target>
+
+ <target name="apassword" description="check if the 8 letter shorting works">
+ <fail message="8 letter shorting does not work 1">
+ <condition>
+ <not>
+ <issigned file="jars/apassword.jar" name="apasswor"/>
+ </not>
+ </condition>
+ </fail>
+ <fail message="8 letter shorting does not work 2">
+ <condition>
+ <not>
+ <issigned file="jars/apassword.jar" name="apassword"/>
+ </not>
+ </condition>
+ </fail>
+ </target>
+
+ <target name="allsigned" description="check the signed / not signed status">
+ <fail message="pass.jar should be signed">
+ <condition>
+ <not>
+ <issigned file="jars/pass.jar"/>
+ </not>
+ </condition>
+ </fail>
+ <fail message="nosign.jar should not be signed">
+ <condition>
+ <issigned file="jars/nosign.jar"/>
+ </condition>
+ </fail>
+
+ <fail message="apassword.jar should be signed">
+ <condition>
+ <not>
+ <issigned file="jars/apassword.jar"/>
+ </not>
+ </condition>
+ </fail>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/conditions/jars/apassword.jar b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/conditions/jars/apassword.jar
new file mode 100644
index 00000000..6bd4af1f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/conditions/jars/apassword.jar
Binary files differ
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/conditions/jars/nosign.jar b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/conditions/jars/nosign.jar
new file mode 100644
index 00000000..d1b7f8d2
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/conditions/jars/nosign.jar
Binary files differ
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/conditions/jars/pass.jar b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/conditions/jars/pass.jar
new file mode 100644
index 00000000..cd49f15d
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/conditions/jars/pass.jar
Binary files differ
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/conditions/parsersupports.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/conditions/parsersupports.xml
new file mode 100644
index 00000000..c80fd350
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/conditions/parsersupports.xml
@@ -0,0 +1,95 @@
+<?xml version="1.0"?>
+<project name="parsersupports" >
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+-->
+
+ <target name="testEmpty">
+ <condition property="empty">
+ <parsersupports />
+ </condition>
+ <fail>Expected failure before here</fail>
+ </target>
+
+ <target name="testBoth">
+ <condition property="both">
+ <parsersupports property="http://bar" feature="http://foo"/>
+ </condition>
+ <fail>Expected failure before here</fail>
+ </target>
+
+ <target name="testNamespaces">
+ <fail>
+ <condition >
+ <not>
+ <parsersupports feature="http://xml.org/sax/features/namespaces"/>
+ </not>
+ </condition>
+ Expected namespace support
+ </fail>
+ </target>
+
+ <target name="testPropertyInvalid">
+ <fail>
+ <condition>
+ <not>
+ <parsersupports
+ property="http://xml.org/sax/properties/declaration-handler"
+ value="undefined"/>
+ </not>
+ </condition>
+ Expected DTD declaration property settable.
+ </fail>
+ </target>
+
+ <target name="testPropertyNoValue">
+ <fail>
+ <condition>
+ <not>
+ <parsersupports
+ property="http://xml.org/sax/properties/declaration-handler"
+ />
+ </not>
+ </condition>
+ Expected no property
+ </fail>
+ </target>
+
+ <target name="testUnknownProperty">
+ <fail>
+ <condition>
+ <parsersupports property="http://org.apache.ant/something"
+ value="undefined"/>
+ </condition>
+ Expected unsupported property.
+ </fail>
+ </target>
+
+ <target name="testXercesProperty">
+ <fail>
+ <condition>
+ <not>
+ <parsersupports
+ property="http://apache.org/xml/properties/schema/external-noNamespaceSchemaLocation"
+ value="parsersupports.xml"/>
+ </not>
+ </condition>
+ Expected XSD support on Xerces.
+ </fail>
+ </target>
+
+</project> \ No newline at end of file
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/conditions/typefound.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/conditions/typefound.xml
new file mode 100644
index 00000000..054ca673
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/conditions/typefound.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="typefound">
+
+
+ <target name="testTask">
+ <condition property="testTask">
+ <typefound name="echo"/>
+ </condition>
+ </target>
+
+
+ <target name="testUndefined">
+ <condition property="testUndefined">
+ <typefound />
+ </condition>
+ </target>
+
+ <target name="testTaskThatIsntDefined">
+ <condition property="testTaskThatIsntDefined">
+ <typefound name="invalid-and-undefined-task-name"/>
+ </condition>
+ </target>
+
+ <target name="testTaskThatDoesntReallyExist">
+ <taskdef name="invalid-task-name" onerror="ignore"
+ classname="org.example.invalid.task.name.hopefully"/>
+ <condition property="testTaskThatDoesntReallyExist">
+ <typefound name="invalid-task-name"/>
+ </condition>
+ </target>
+
+ <target name="testType">
+ <condition property="testType">
+ <typefound name="path"/>
+ </condition>
+ </target>
+
+ <target name="testPreset">
+ <presetdef name="important-echo">
+ <echo level="error"/>
+ </presetdef>
+ <condition property="testPreset">
+ <typefound name="important-echo"/>
+ </condition>
+ </target>
+
+ <target name="testMacro">
+ <macrodef name="error-message">
+ <element name="text" optional="false"/>
+ <sequential>
+ <echo level="error">@{text}</echo>
+ </sequential>
+ </macrodef>
+ <condition property="testMacro">
+ <typefound name="error-message"/>
+ </condition>
+ </target>
+
+</project> \ No newline at end of file
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/conditions/xor.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/conditions/xor.xml
new file mode 100644
index 00000000..895dccdb
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/conditions/xor.xml
@@ -0,0 +1,112 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="all">
+
+<!--
+ Xor semantics
+
+ in out
+ == ===
+ 00 0
+ 01 1
+ 10 1
+ 00 0
+
+-->
+
+ <target name="testEmpty" >
+ <fail message="empty test">
+ <condition>
+ <xor/>
+ </condition>
+ </fail>
+ </target>
+
+ <target name="test1" >
+ <fail message="testTrue">
+ <condition>
+ <not>
+ <xor>
+ <istrue value="true" />
+ </xor>
+ </not>
+ </condition>
+ </fail>
+ </target>
+
+ <target name="test0" >
+ <fail message="testFalse">
+ <condition>
+ <xor>
+ <istrue value="" />
+ </xor>
+ </condition>
+ </fail>
+ </target>
+
+
+ <target name="test10" >
+ <fail message="test10">
+ <condition>
+ <not>
+ <xor>
+ <istrue value="true" />
+ <istrue value="" />
+ </xor>
+ </not>
+ </condition>
+ </fail>
+ </target>
+
+ <target name="test01" >
+ <fail message="test01">
+ <condition>
+ <not>
+ <xor>
+ <istrue value="" />
+ <istrue value="true" />
+ </xor>
+ </not>
+ </condition>
+ </fail>
+ </target>
+
+ <target name="test00" >
+ <fail message="test10">
+ <condition>
+ <xor>
+ <istrue value="" />
+ <istrue value="" />
+ </xor>
+ </condition>
+ </fail>
+ </target>
+
+ <target name="test11" >
+ <fail message="test11">
+ <condition>
+ <xor>
+ <istrue value="" />
+ <istrue value="" />
+ </xor>
+ </condition>
+ </fail>
+ </target>
+
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/copy.filterset b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/copy.filterset
new file mode 100644
index 00000000..5563dd95
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/copy.filterset
@@ -0,0 +1 @@
+This is the @TITLE@.
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/copy.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/copy.xml
new file mode 100644
index 00000000..bf4441c1
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/copy.xml
@@ -0,0 +1,268 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<project name="copy-test" basedir="." default="test1">
+
+ <import file="../buildfiletest-base.xml"/>
+
+ <target name="setUp">
+ <mkdir dir="${output}" />
+ </target>
+
+ <target name="test1">
+ <copy file="copy.xml" tofile="${output}/copytest1.tmp" />
+ </target>
+
+ <target name="test2">
+ <copy file="copy.xml" todir="${output}/copytest1dir" overwrite="true"/>
+ </target>
+
+ <target name="filtertest">
+ <!-- check fix for bugzilla 23154 -->
+ <concat destfile="${output}/copy.filter.inp">
+PRODUCT_VERSION=6.2.1.4
+PRODUCT_BUILD=6.5 (BLD_65036)
+PRODUCT_VERSION=6.2.1.4
+PRODUCT_BUILD=6.5 (BLD_65036)
+ </concat>
+ <copy file="${output}/copy.filter.inp" tofile="${output}/copy.filter.out">
+ <filterset begintoken="6" endtoken="4">
+ <filter token=".2.1." value="2.6.4" />
+ </filterset>
+ </copy>
+ <concat><path path="${output}/copy.filter.out"/></concat>
+ </target>
+
+ <target name="infinitetest">
+ <concat destfile="${output}/copy.filter.inp">
+a=b=
+ </concat>
+ <copy file="${output}/copy.filter.inp" tofile="${output}/copy.filter.out">
+ <filterset begintoken="=" endtoken="=">
+ <filter token="b" value="=b="/>
+ </filterset>
+ </copy>
+ <concat><path path="${output}/copy.filter.out"/></concat>
+ </target>
+
+ <target name="test3">
+ <!-- create an empty file -->
+ <touch file="${output}/copytest3.tmp"/>
+ <!-- copy a different file to two places -->
+ <copy file="copy.xml" tofile="${output}/copytest3a.tmp" overwrite="true"/>
+ <copy file="copy.xml" tofile="${output}/copytest3b.tmp" overwrite="true"/>
+ </target><target name="test3Part2">
+ <!-- copy an old file onto a newer file (should not work) -->
+ <copy file="${output}/copytest3.tmp" tofile="${output}/copytest3b.tmp" />
+ <!-- copy an older file onto a new one, should succeed -->
+ <copy file="${output}/copytest3.tmp" tofile="${output}/copytest3c.tmp"
+ overwrite="true"
+ preservelastmodified="true" />
+ <!-- copy a newer file onto an older one (should work) -->
+ <copy file="${output}/copytest3a.tmp" tofile="${output}/copytest3.tmp"
+ preservelastmodified="true" />
+ <!-- expected state :
+ 3a.tmp==3.tmp==copy.xml
+ timeof(3a.tmp)==timeof(3.tmp)==now()-4
+ sizeof(3c)==0
+ timeof(3c.tmp)<timeof(3a.tmp);
+ 3b.tmp==copy.xml
+ -->
+ </target>
+
+ <target name="test_single_file_fileset">
+ <copy tofile="${output}/copytest_single_file_fileset.tmp">
+ <fileset dir="." includes="copy.xml"/>
+ </copy>
+ </target>
+
+ <target name="test_single_file_path">
+ <copy tofile="${output}/copytest_single_file_path.tmp">
+ <path>
+ <pathelement location="copy.xml"/>
+ </path>
+ </copy>
+ </target>
+
+ <target name="testFilterSet">
+ <copy file="copy.filterset" tofile="${output}/copy.filterset.tmp">
+ <filterset>
+ <filter token="TITLE" value="Apache Ant Project"/>
+ </filterset>
+ </copy>
+ </target>
+
+ <target name="testFilterChain">
+ <copy file="copy.filterset" tofile="${output}/copy.filterchain.tmp">
+ <filterchain>
+ <replacetokens>
+ <token key="TITLE" value="Apache Ant Project"/>
+ </replacetokens>
+ </filterchain>
+ </copy>
+ </target>
+
+ <target name="testTranscoding">
+ <copy file="copy/input/iso8859-1" tofile="${output}/copytest1.tmp"
+ encoding="ISO8859_1" outputencoding="UTF8"/>
+ </target>
+
+ <target name="testMissingFileIgnore">
+ <copy file="not-there" tofile="${output}/copytest1.tmp"
+ failonerror="false"/>
+ </target>
+
+ <target name="testMissingFileBail">
+ <copy file="not-there" tofile="${output}/copytest1.tmp"
+ failonerror="true"/>
+ </target>
+
+ <target name="testMissingDirIgnore">
+ <copy todir="${output}" failonerror="false">
+ <fileset dir="not-there"/>
+ </copy>
+ </target>
+
+ <target name="testMissingDirBail">
+ <copy todir="${output}" failonerror="true">
+ <fileset dir="not-there"/>
+ </copy>
+ </target>
+
+ <property name="to.dir" value="${output}/copy-todir-tmp"/>
+ <property name="from.dir" value="${output}/copy-fromdir-tmp"/>
+
+ <target name="testResource.prepare">
+ <mkdir dir="${from.dir}"/>
+ <concat destfile="${from.dir}/file1.txt">This is file 1</concat>
+ <concat destfile="${from.dir}/file2.txt">This is file 2</concat>
+ <concat destfile="${from.dir}/file3.txt">This is file 3</concat>
+ <concat destfile="${from.dir}/fileNR.txt">This is file @NR@</concat>
+ </target>
+
+ <target name="testFileResourcePlain" depends="testResource.prepare">
+ <copy todir="${to.dir}" flatten="true">
+ <resources>
+ <file file="${from.dir}/file1.txt"/>
+ <file file="${from.dir}/file2.txt"/>
+ <file file="${from.dir}/file3.txt"/>
+ </resources>
+ </copy>
+ </target>
+
+ <target name="testFileResourceWithMapper" depends="testResource.prepare">
+ <copy todir="${to.dir}" flatten="true">
+ <resources>
+ <file file="${from.dir}/file1.txt"/>
+ <file file="${from.dir}/file2.txt"/>
+ <file file="${from.dir}/file3.txt"/>
+ </resources>
+ <regexpmapper from="^(.*)\.txt$$" to="\1.txt.bak"/>
+ </copy>
+ </target>
+
+ <target name="testFileResourceWithFilter" depends="testResource.prepare">
+ <copy todir="${to.dir}" flatten="true">
+ <resources>
+ <file file="${from.dir}/fileNR.txt"/>
+ </resources>
+ <filterset>
+ <filter token="NR" value="42"/>
+ </filterset>
+ </copy>
+ </target>
+
+ <target name="testResourcePlain">
+ </target>
+
+ <target name="testResourcePlainWithMapper">
+ </target>
+
+ <target name="testResourcePlainWithFilter">
+ </target>
+
+ <target name="testOnlineResources">
+ </target>
+
+ <target name="testPathAsResource" depends="testResource.prepare">
+ <copy todir="${to.dir}">
+ <path>
+ <fileset dir="${from.dir}"/>
+ </path>
+ </copy>
+ </target>
+
+ <target name="testZipfileset" depends="testResource.prepare">
+ <zip destfile="${from.dir}/test.zip" roundup="false">
+ <fileset dir="${from.dir}" excludes="*.zip"/>
+ </zip>
+ <copy todir="${to.dir}">
+ <zipfileset src="${from.dir}/test.zip"/>
+ </copy>
+ </target>
+
+ <target name="prepareDirset">
+ <touch mkdirs="true">
+ <filelist dir="${from.dir}/dirset">
+ <file name="a/x/foo" />
+ <file name="a/y/foo" />
+ <file name="a/z/foo" />
+ <file name="b/x/foo" />
+ <file name="b/y/foo" />
+ <file name="b/z/foo" />
+ </filelist>
+ </touch>
+ <fail>
+ <condition>
+ <or>
+ <resourcecount when="ne" count="9">
+ <dirset id="dirset" dir="${from.dir}/dirset" />
+ </resourcecount>
+ <resourcecount when="ne" count="6">
+ <fileset dir="${from.dir}/dirset" />
+ </resourcecount>
+ </or>
+ </condition>
+ </fail>
+ <delete dir="${to.dir}/dirset" />
+ <fail>
+ <condition>
+ <available file="${to.dir}/dirset" />
+ </condition>
+ </fail>
+ </target>
+
+ <target name="testDirset" depends="prepareDirset">
+ <copy todir="${to.dir}/dirset">
+ <resources refid="dirset" />
+ </copy>
+ <fail>
+ <condition>
+ <or>
+ <resourcecount when="ne" count="9">
+ <dirset dir="${to.dir}/dirset" />
+ </resourcecount>
+ <resourcecount when="ne" count="0">
+ <fileset dir="${to.dir}/dirset" />
+ </resourcecount>
+ </or>
+ </condition>
+ </fail>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/copy/expected/utf-8 b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/copy/expected/utf-8
new file mode 100644
index 00000000..c1949bc1
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/copy/expected/utf-8
@@ -0,0 +1 @@
+äöüÄÖÜß
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/copy/input/iso8859-1 b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/copy/input/iso8859-1
new file mode 100644
index 00000000..09044014
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/copy/input/iso8859-1
@@ -0,0 +1 @@
+äöüÄÖÜß
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/copydir.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/copydir.xml
new file mode 100644
index 00000000..8a8abd36
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/copydir.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<project name="copydir-test" basedir="." default="test1">
+
+ <import file="../buildfiletest-base.xml"/>
+
+ <target name="setUp">
+ <mkdir dir="${output}" />
+ </target>
+
+ <target name="test1">
+ <copydir/>
+ </target>
+
+ <target name="test2">
+ <copydir src=""/>
+ </target>
+
+ <target name="test3">
+ <copydir dest=""/>
+ </target>
+
+ <target name="test4">
+ <copydir src="."
+ dest="."/>
+ </target>
+
+ <target name="test5">
+ <mkdir dir="${output}/taskdefs.tmp" />
+ <copydir src="."
+ dest="${output}/taskdefs.tmp"/>
+ </target>
+
+ <target name="test6">
+ <copydir src="."
+ dest="template.xml"/>
+ </target>
+
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/copyfile.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/copyfile.xml
new file mode 100644
index 00000000..0f8c9ab0
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/copyfile.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<project name="copyfile-test" basedir="." default="test1">
+
+ <import file="../buildfiletest-base.xml"/>
+
+ <target name="setUp">
+ <mkdir dir="${output}" />
+ </target>
+
+ <target name="test1">
+ <copyfile/>
+ </target>
+
+ <target name="test2">
+ <copyfile src=""/>
+ </target>
+
+ <target name="test3">
+ <copyfile dest=""/>
+ </target>
+
+ <target name="test4">
+ <copyfile src="template.xml"
+ dest="template.xml"/>
+ </target>
+
+ <target name="test5">
+ <copyfile src="copyfile.xml"
+ dest="${output}/copyfile.tmp"/>
+ </target>
+
+ <target name="test6">
+ <mkdir dir="${output}/testdir"/>
+ <copyfile src="copyfile.xml"
+ dest="${output}/testdir"
+ forceoverwrite="true" />
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/cvspass.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/cvspass.xml
new file mode 100644
index 00000000..bbca110f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/cvspass.xml
@@ -0,0 +1,85 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<project name="cvspass-test" basedir="." default="test1">
+
+ <taskdef name="cvspass" classname="org.apache.tools.ant.taskdefs.CVSPass"/>
+
+ <target name="test1">
+ <cvspass />
+ </target>
+
+ <target name="test2">
+ <cvspass
+ cvsroot=":pserver:anoncvs@jakarta.apache.org:/home/cvspublic"
+ passfile="testpassfile.tmp"
+ />
+ </target>
+
+ <!-- testPassFile -->
+ <target name="test3">
+ <cvspass
+ cvsroot=":pserver:anoncvs@jakarta.apache.org:/home/cvspublic"
+ password="anoncvs"
+ passfile="testpassfile.tmp"
+ />
+ </target>
+
+ <!-- testPassFileDuplicateEntry -->
+ <target name="test4">
+ <cvspass
+ cvsroot=":pserver:anoncvs@jakarta.apache.org:/home/cvspublic"
+ password="anoncvs"
+ passfile="testpassfile.tmp"
+ />
+ <cvspass
+ cvsroot=":pserver:anoncvs@jakarta.apache.org:/home/cvspublic"
+ password="anoncvs"
+ passfile="testpassfile.tmp"
+ />
+ <cvspass
+ cvsroot=":pserver:guest@cvs.tigris.org:/cvs"
+ password="guest"
+ passfile="testpassfile.tmp"
+ />
+ </target>
+
+ <!-- testPassFileMultipleEntry -->
+ <target name="test5">
+ <cvspass
+ cvsroot=":pserver:anoncvs@jakarta.apache.org:/home/cvspublic"
+ password="anoncvs"
+ passfile="testpassfile.tmp"
+ />
+ <cvspass
+ cvsroot=":pserver:anoncvs@xml.apache.org:/home/cvspublic"
+ password="anoncvs"
+ passfile="testpassfile.tmp"
+ />
+ <cvspass
+ cvsroot=":pserver:guest@cvs.tigris.org:/cvs"
+ password="guest"
+ passfile="testpassfile.tmp"
+ />
+ </target>
+
+ <target name="cleanup">
+ <delete file="testpassfile.tmp"/>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/defaultexcludes.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/defaultexcludes.xml
new file mode 100644
index 00000000..46292501
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/defaultexcludes.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<project name="echo-test" basedir="." default="test1">
+
+ <target name="cleanup">
+ <defaultexcludes default="true"/>
+ </target>
+
+ <target name="test1">
+ <defaultexcludes echo="true"/>
+ </target>
+
+ <target name="test2">
+ <defaultexcludes default="true" add="foo" echo="true"/>
+ </target>
+
+ <target name="test3">
+ <defaultexcludes default="true" remove="**/CVS" echo="true"/>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/delete.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/delete.xml
new file mode 100644
index 00000000..d74c8bab
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/delete.xml
@@ -0,0 +1,194 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<project name="delete-test" basedir="." default="test1">
+
+ <import file="../buildfiletest-base.xml"/>
+
+
+ <property name="dir" location="${output}" />
+ <basename property="dirname" file="${output}"/>
+
+ <macrodef name="expectabsent">
+ <attribute name="target" default="${dir}"/>
+ <sequential>
+ <fileset id="detritus" dir="@{target}" erroronmissingdir="false"/>
+ <fail message="@{target} still has: ${toString:detritus}">
+ <condition>
+ <available file="@{target}" />
+ </condition>
+ </fail>
+ </sequential>
+ </macrodef>
+
+ <macrodef name="expectdirsonly">
+ <sequential>
+ <fail>
+ <condition>
+ <or>
+ <resourcecount when="greater" count="0">
+ <fileset dir="${dir}" />
+ </resourcecount>
+ <not>
+ <resourcecount count="${srcdirs}">
+ <dirset dir="${dir}" />
+ </resourcecount>
+ </not>
+ </or>
+ </condition>
+ </fail>
+ </sequential>
+ </macrodef>
+
+ <target name="init">
+ <resourcecount property="srcdirs">
+ <dirset dir="${basedir}" />
+ </resourcecount>
+
+ <resourcecount property="srcsize">
+ <files includes="${basedir}/" />
+ </resourcecount>
+
+ <mkdir dir="${dir}" />
+
+ <copy todir="${dir}">
+ <fileset dir="${basedir}" excludes="${dirname},${dirname}/**" />
+ </copy>
+ </target>
+
+ <target name="test1">
+ <delete />
+ </target>
+
+ <target name="test2" depends="init">
+ <delete file="${dir}" />
+ <fail>
+ <condition>
+ <not>
+ <resourcecount count="${srcsize}">
+ <files includes="${dir}/" />
+ </resourcecount>
+ </not>
+ </condition>
+ </fail>
+ </target>
+
+ <target name="test4" depends="init">
+ <delete dir="${dir}" />
+ <expectabsent />
+ </target>
+
+ <target name="test5" depends="init">
+ <delete dir="${dir}" includes="**" />
+ <expectdirsonly />
+ </target>
+
+ <target name="test6" depends="init">
+ <delete dir="${dir}" includes="**" includeemptydirs="true" />
+ <expectabsent />
+ </target>
+
+ <target name="test7" depends="init">
+ <delete>
+ <fileset id="fs" dir="${dir}" />
+ </delete>
+ <expectdirsonly />
+ </target>
+
+ <target name="test8" depends="init">
+ <delete includeemptydirs="true">
+ <fileset dir="${dir}" />
+ </delete>
+ <expectabsent />
+ </target>
+
+ <target name="test9" depends="init">
+ <delete>
+ <files>
+ <include name="${dir}/**"/>
+ </files>
+ </delete>
+ <expectabsent />
+ </target>
+
+ <target name="test10">
+ <delete>
+ <filelist dir="${dir}" files="test10absentfile" />
+ </delete>
+ </target>
+
+ <target name="test11">
+ <delete failonerror="false">
+ <fileset dir="thisdenotesadirectorythatwillneverexistblah" />
+ </delete>
+ </target>
+
+ <target name="test12">
+ <delete failonerror="false" includeemptydirs="true">
+ <fileset dir="thisdenotesadirectorythatwillneverexistblah" />
+ </delete>
+ </target>
+
+ <target name="test13" depends="init">
+ <delete includeemptydirs="true">
+ <fileset dir="${dir}" />
+ <fileset dir="${dir}" />
+ </delete>
+ <expectabsent />
+ </target>
+
+ <target name="test14" depends="init">
+ <delete quiet="false">
+ <fileset dir="${dir}" />
+ <fileset dir="${dir}" />
+ </delete>
+ </target>
+
+ <target name="test15" depends="init">
+ <delete quiet="true">
+ <fileset dir="${dir}" />
+ <fileset dir="${dir}" />
+ </delete>
+ </target>
+ <!-- Bugzilla 40313 -->
+ <target name="test16.init">
+ <mkdir dir="${dir}/CVS"/>
+ <touch file="${dir}/CVS/lala"/>
+ <mkdir dir="${dir}/subdir"/>
+ </target>
+
+ <target name="test16" depends="test16.init">
+ <delete defaultexcludes="false" dir="${dir}" includeemptydirs="true"/>
+ <expectabsent/>
+ </target>
+
+ <target name="test17" depends="test16.init">
+ <delete dir="${dir}" defaultexcludes="true" includeemptydirs="true"/>
+ <fail message="file in CVS dir deleted">
+ <condition>
+ <not>
+ <available file="${dir}/CVS/lala"/>
+ </not>
+ </condition>
+ </fail>
+ <expectabsent target="${dir}/subdir"/>
+ </target>
+
+
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/deltree.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/deltree.xml
new file mode 100644
index 00000000..c69d51f0
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/deltree.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<project name="deltree-test" basedir="." default="test1">
+
+ <target name="test1">
+ <deltree/>
+ </target>
+
+ <target name="test2">
+ <deltree dir="taskdefs.tmp"/>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/dirname.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/dirname.xml
new file mode 100644
index 00000000..1027db12
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/dirname.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<project name="xxx-test" basedir="." default="test1">
+
+ <target name="test1">
+ <dirname/>
+ </target>
+
+ <target name="test2">
+ <dirname property="propname"/>
+ </target>
+
+ <target name="test3">
+ <dirname file="filename"/>
+ </target>
+
+ <target name="test4">
+ <dirname property="local.dir" file="/usr/local/foo.txt"/>
+ </target>
+
+ <target name="test5">
+ <dirname property="base.dir" file="foo.txt"/>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/dynamictask.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/dynamictask.xml
new file mode 100644
index 00000000..307181f2
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/dynamictask.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<project name="dynamic-test" default="simple">
+
+ <path id="testclasses">
+ <pathelement location="../../../../build/testcases" />
+ <pathelement path="${java.class.path}" />
+ </path>
+
+ <target name="simple">
+ <taskdef name="dyna"
+ classname="org.apache.tools.ant.taskdefs.DynamicTask">
+ <classpath refid="testclasses" />
+ </taskdef>
+ <dyna prop1="1" prop2="2">
+ <sub prop3="3"/>
+ <anything prop4="4"/>
+ </dyna>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/echoxml.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/echoxml.xml
new file mode 100644
index 00000000..ec53abbb
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/echoxml.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project>
+ <property name="file" location="echoed.xml" />
+ <target name="init">
+ <echoxml file="${file}">
+ <project>
+ <property name="foo" value="bar" />
+ <fail message="$$$${foo}=$${foo}">
+ <condition>
+ <istrue value="${mustfail}" />
+ </condition>
+ </fail>
+ </project>
+ </echoxml>
+ </target>
+ <target name="tearDown">
+ <delete file="${file}" />
+ </target>
+ <target name="testPass" depends="init">
+ <ant antfile="${file}" />
+ </target>
+ <target name="testFail" depends="init">
+ <ant antfile="${file}">
+ <property name="mustfail" value="true" />
+ </ant>
+ </target>
+ <target name="testEmpty">
+ <echoxml />
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/email/mail.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/email/mail.xml
new file mode 100644
index 00000000..c56fd403
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/email/mail.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<project name="mail-test" basedir="." default="test1">
+
+ <target name="test1">
+ <!-- this test is supposed to bring a build exception because user and password is not allowed with plain encoding -->
+ <mail host="localhost" port="25" from="joe@abc.com" to="laura@xyz.com" subject="hello" encoding="plain" user="joe" password="secret">
+ <message>
+ Hi Laura, how are you doing ?
+ </message>
+ </mail>
+ </target>
+ <target name="test2">
+ <!-- this test is supposed to bring a build exception because SSL is not allowed with plain encoding -->
+ <mail host="localhost" port="465" from="joe@abc.com" to="laura@xyz.com" subject="hello" encoding="plain" ssl="true">
+ <message>
+ Hi Laura, how are you doing ?
+ </message>
+ </mail>
+ </target>
+
+
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/exec/blabla.sh b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/exec/blabla.sh
new file mode 100644
index 00000000..c996d6af
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/exec/blabla.sh
@@ -0,0 +1,24 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+echo "some blablablablablablablablablablablabla error message" err>&2
+echo "some blablablablablablablablablablablabla info message" out
+echo "some blablablablablablablablablablablabla error message" err>&2
+echo "some blablablablablablablablablablablabla info message" out
+echo "some blablablablablablablablablablablabla error message" err>&2
+echo "some blablablablablablablablablablablabla info message" out
+echo "some blablablablablablablablablablablabla error message" err>&2
+echo "some blablablablablablablablablablablabla info message" out
+echo "some blablablablablablablablablablablabla error message" err>&2
+echo "some blablablablablablablablablablablabla info message" out
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/exec/blabla.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/exec/blabla.xml
new file mode 100644
index 00000000..3b13195f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/exec/blabla.xml
@@ -0,0 +1,19 @@
+<project name="blabla" default="doit">
+ <target name="blabla">
+ <exec executable="sh">
+ <arg value="blabla.sh" />
+ </exec>
+ </target>
+ <target name="doit">
+ <antcall target="blabla"/>
+ <antcall target="blabla"/>
+ <antcall target="blabla"/>
+ <antcall target="blabla"/>
+ <antcall target="blabla"/>
+ <antcall target="blabla"/>
+ <antcall target="blabla"/>
+ <antcall target="blabla"/>
+ <antcall target="blabla"/>
+ <antcall target="blabla"/>
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/exec/exec.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/exec/exec.xml
new file mode 100644
index 00000000..20e56565
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/exec/exec.xml
@@ -0,0 +1,69 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="exec-test" default="spawn" basedir=".">
+ <import file="../../buildfiletest-base.xml"/>
+
+ <target name="setUp">
+ <mkdir dir="${output}"/>
+ <!-- this property can be overriden programatically in the Java test case -->
+ <property name="timeToWait" value="10"/>
+ <!-- this property can be overriden programatically in the Java test case -->
+ <property name="logFile" value="${output}/spawn.log"/>
+ <property environment="env"/>
+ <!-- UNIX -->
+ <available file="sh" filepath="${env.PATH}" property="sh.executable"/>
+ <!-- CYGWIN -->
+ <available file="sh.exe" filepath="${env.PATH}" property="sh.exe.executable"/>
+ <!-- WINDOWS + CYGWIN -->
+ <available file="sh.exe" filepath="${env.Path}" property="sh.exe.executable"/>
+ <condition property="test.can.run">
+ <or>
+ <isset property="sh.executable"/>
+ <isset property="sh.exe.executable"/>
+ </or>
+ </condition>
+ </target>
+
+ <target name="spawn" depends="setUp" if="test.can.run">
+ <exec executable="sh" spawn="true">
+ <arg value="spawn.sh"/>
+ <arg value="${timeToWait}"/>
+ <arg value="${logFile}"/>
+ </exec>
+ </target>
+
+ <target name="test-out-and-err" description="see https://issues.apache.org/bugzilla/show_bug.cgi?id=50507"
+ depends="setUp" if="test.can.run">
+ <mkdir dir="${output}"/>
+ <ant antfile="blabla.xml" output="${output}/test-out-and-err.txt">
+ </ant>
+ <loadfile srcfile="${output}/test-out-and-err.txt" property="test-out-and-err">
+ <filterchain>
+ <replaceregex pattern="^\s*\[exec\] some blablablablablablablablablablablabla error message err$" flags="m"/>
+ <replaceregex pattern="^\s*\[exec\] some blablablablablablablablablablablabla info message out$" flags="m"/>
+ </filterchain>
+ </loadfile>
+ <fail message="output indicates a mixup of out and err: '${test-out-and-err}'">
+ <condition>
+ <contains string="${test-out-and-err}" substring="[exec]"/>
+ </condition>
+ </fail>
+
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/exec/parrot.sh b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/exec/parrot.sh
new file mode 100644
index 00000000..2467f23a
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/exec/parrot.sh
@@ -0,0 +1,19 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+for arg in "$@" ; do
+ echo $arg out
+ sleep 1
+ echo $arg err>&2
+done
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/exec/spawn.sh b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/exec/spawn.sh
new file mode 100644
index 00000000..2cf0631d
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/exec/spawn.sh
@@ -0,0 +1,29 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+sleeptime=10
+logfile=spawn.log
+if [ $# -ge 1 ]; then
+ sleeptime=$1
+ echo $sleeptime
+fi
+if [ $# -ge 2 ]; then
+ logfile=$2
+ echo $logfile
+fi
+echo hello
+rm $logfile
+sleep $sleeptime
+echo bye bye > $logfile
+echo bye bye
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/expected/asf-logo-huge.tar.bz2 b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/expected/asf-logo-huge.tar.bz2
new file mode 100644
index 00000000..7c2d2154
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/expected/asf-logo-huge.tar.bz2
Binary files differ
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/expected/asf-logo-huge.tar.gz b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/expected/asf-logo-huge.tar.gz
new file mode 100644
index 00000000..015471e1
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/expected/asf-logo-huge.tar.gz
Binary files differ
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/expected/asf-logo.gif.bz2 b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/expected/asf-logo.gif.bz2
new file mode 100644
index 00000000..0e73d252
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/expected/asf-logo.gif.bz2
Binary files differ
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/expected/asf-logo.gif.gz b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/expected/asf-logo.gif.gz
new file mode 100644
index 00000000..decc9187
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/expected/asf-logo.gif.gz
Binary files differ
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/expected/asf-logo.gif.md5 b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/expected/asf-logo.gif.md5
new file mode 100644
index 00000000..b56119be
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/expected/asf-logo.gif.md5
@@ -0,0 +1 @@
+0541d3df42520911f268abc730f3afe0
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/expected/asf-logo.gif.md5sum b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/expected/asf-logo.gif.md5sum
new file mode 100644
index 00000000..56c49d33
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/expected/asf-logo.gif.md5sum
@@ -0,0 +1 @@
+0541d3df42520911f268abc730f3afe0 *asf-logo.gif
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/expected/asf-logo.gif.pattern b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/expected/asf-logo.gif.pattern
new file mode 100644
index 00000000..3a6eb82f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/expected/asf-logo.gif.pattern
@@ -0,0 +1 @@
+foo0541d3df42520911f268abc730f3afe0bar
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/expected/asf-logo.gif.svf b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/expected/asf-logo.gif.svf
new file mode 100644
index 00000000..c7f8ec23
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/expected/asf-logo.gif.svf
@@ -0,0 +1 @@
+MD5 (asf-logo.gif) = 0541d3df42520911f268abc730f3afe0
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/expected/asf-logo.gif.tar b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/expected/asf-logo.gif.tar
new file mode 100644
index 00000000..fc0f7902
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/expected/asf-logo.gif.tar
Binary files differ
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/expected/asf-logo.gif.tar.bz2 b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/expected/asf-logo.gif.tar.bz2
new file mode 100644
index 00000000..99a91fc4
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/expected/asf-logo.gif.tar.bz2
Binary files differ
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/expected/asf-logo.gif.tar.gz b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/expected/asf-logo.gif.tar.gz
new file mode 100644
index 00000000..ddd23a24
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/expected/asf-logo.gif.tar.gz
Binary files differ
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/expected/asf-logo.gif.zip b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/expected/asf-logo.gif.zip
new file mode 100644
index 00000000..5f970d59
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/expected/asf-logo.gif.zip
Binary files differ
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/expected/copy.filterset.filtered b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/expected/copy.filterset.filtered
new file mode 100644
index 00000000..ddbcf5d8
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/expected/copy.filterset.filtered
@@ -0,0 +1 @@
+This is the Apache Ant Project.
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/fail.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/fail.xml
new file mode 100644
index 00000000..0a6561e9
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/fail.xml
@@ -0,0 +1,130 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<project name="fail-test" basedir="." default="test1">
+
+ <target name="test1">
+ <fail/>
+ </target>
+
+ <target name="test2">
+ <fail message="test2"/>
+ </target>
+
+ <target name="testText">
+ <fail>testText</fail>
+ </target>
+
+ <target name="testIf">
+ <fail if="foo" />
+ </target>
+
+ <target name="testUnless">
+ <fail unless="foo" />
+ </target>
+
+ <target name="testIfAndUnless">
+ <fail unless="unless" if="if"/>
+ </target>
+
+ <target name="testNested1" description="should fail with default message">
+ <fail>
+ <condition>
+ <and />
+ </condition>
+ </fail>
+ </target>
+
+ <target name="testNested2" description="should pass">
+ <fail>
+ <condition>
+ <or />
+ </condition>
+ </fail>
+ </target>
+
+ <target name="testNested3" description="should fail">
+ <fail message="testNested3">
+ <condition>
+ <and />
+ </condition>
+ </fail>
+ </target>
+
+ <target name="testNested4a" description="should error">
+ <fail if="if">
+ <condition>
+ <and />
+ </condition>
+ </fail>
+ </target>
+
+ <target name="testNested4b" description="should error">
+ <fail unless="unless">
+ <condition>
+ <and />
+ </condition>
+ </fail>
+ </target>
+
+ <target name="testNested4c" description="should error">
+ <fail if="if" unless="unless">
+ <condition>
+ <and />
+ </condition>
+ </fail>
+ </target>
+
+ <target name="testNested5" description="should error">
+ <fail>
+ <condition>
+ <or />
+ </condition>
+ <condition>
+ <and />
+ </condition>
+ </fail>
+ </target>
+
+ <target name="testNested6" description="should fail with message">
+ <fail>
+ <condition>
+ <and />
+ </condition>
+testNested6
+testNested6
+testNested6
+ </fail>
+ </target>
+
+ <target name="testNested7a" description="should error">
+ <fail>
+ <condition />
+ </fail>
+ </target>
+
+ <target name="testNested7b" description="should error">
+ <fail>
+ <condition>
+ <and />
+ <and />
+ </condition>
+ </fail>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/filter.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/filter.xml
new file mode 100644
index 00000000..303efa74
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/filter.xml
@@ -0,0 +1,72 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<project name="filter-test" basedir="." default="test1">
+
+ <target name="test1">
+ <filter/>
+ </target>
+
+ <target name="test2">
+ <filter token=""/>
+ </target>
+
+ <target name="test3">
+ <filter value=""/>
+ </target>
+
+ <target name="test4">
+ <filter token="" value=""/>
+ </target>
+
+ <target name="test5">
+ <filter token="year" value="2000" />
+ <copy file="filter1.txt" tofile="filtered.tmp" filtering="yes" overwrite="yes" />
+ </target>
+
+ <target name="test6">
+ <filter token="year" value="2000" />
+ <copy todir="./taskdefs.tmp" filtering="yes" overwrite="yes">
+ <fileset dir="." includes="filter1.txt" />
+ </copy>
+ </target>
+
+ <target name="test7">
+ <filter token="ROOT" value="root" />
+ <copy file="filter2.txt" tofile="filtered.tmp" filtering="yes" overwrite="yes" />
+ </target>
+
+ <target name="test8">
+ <filter token="ROOT" value="root" />
+ <copy todir="./taskdefs.tmp" filtering="yes" overwrite="yes">
+ <fileset dir="." includes="filter2.txt"/>
+ </copy>
+ </target>
+
+ <target name="test9">
+ <filter filtersfile="filterdefs.properties" />
+ <copy todir="./taskdefs.tmp" filtering="yes" overwrite="yes">
+ <fileset dir="." includes="filter3.txt"/>
+ </copy>
+ </target>
+
+ <target name="cleanup">
+ <delete dir="taskdefs.tmp" />
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/filter1.txt b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/filter1.txt
new file mode 100644
index 00000000..4e4f9763
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/filter1.txt
@@ -0,0 +1 @@
+@year@
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/filter2.txt b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/filter2.txt
new file mode 100644
index 00000000..dccd06b8
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/filter2.txt
@@ -0,0 +1 @@
+<%@ include file="@ROOT@/some/include.jsp"%>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/filter3.txt b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/filter3.txt
new file mode 100644
index 00000000..03d7d29e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/filter3.txt
@@ -0,0 +1 @@
+@property@
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/filterdefs.properties b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/filterdefs.properties
new file mode 100644
index 00000000..f099df3b
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/filterdefs.properties
@@ -0,0 +1,15 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+property=included
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/fixcrlf/build.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/fixcrlf/build.xml
new file mode 100644
index 00000000..e2fecac3
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/fixcrlf/build.xml
@@ -0,0 +1,331 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="fixcrlf" default="cleanup" basedir=".">
+ <import file="../../buildfiletest-base.xml"/>
+
+ <target name="setUp">
+ <mkdir dir="${input}" />
+ <unzip src="input.zip" dest="${input}"/>
+ <unzip src="expected.zip" dest="${input}"/>
+ <mkdir dir="${output}" />
+ </target>
+
+
+ <macrodef name="assertequal">
+ <attribute name="junk" default="" />
+ <attribute name="name" default="Junk@{junk}.java" />
+ <attribute name="file1" default="${output}/@{name}" />
+ <attribute name="file2" default="${input}/expected/@{name}" />
+ <sequential>
+ <fail message="@{file1} and @{file2} are different">
+ <condition>
+ <not>
+ <filesmatch file1="@{file1}" file2="@{file2}" />
+ </not>
+ </condition>
+ </fail>
+ </sequential>
+ </macrodef>
+
+ <target name="test1" depends="setUp">
+ <fixcrlf srcdir="${input}/input" destdir="${output}"
+ includes="Junk1.java"
+ javafiles="true" tab="add" eol="crlf" eof="asis" />
+ <assertequal junk="1" />
+ </target>
+
+ <target name="test2" depends="setUp">
+ <fixcrlf srcdir="${input}/input" destdir="${output}"
+ includes="Junk2.java"
+ javafiles="true" tab="add" cr="add" eol="crlf" eof="asis" />
+ <assertequal junk="2" />
+ </target>
+
+ <target name="test3" depends="setUp">
+ <fixcrlf srcdir="${input}/input" destdir="${output}"
+ includes="Junk3.java"
+ javafiles="true" tab="remove" eol="lf" eof="asis" />
+ <assertequal junk="3" />
+ </target>
+
+ <target name="test4" depends="setUp">
+ <fixcrlf srcdir="${input}/input" destdir="${output}"
+ includes="Junk4.java"
+ javafiles="true" tab="remove" eol="lf" eof="asis" />
+ <assertequal junk="4" />
+ </target>
+
+ <target name="test5" depends="setUp">
+ <fixcrlf srcdir="${input}/input" destdir="${output}"
+ includes="Junk5.java"
+ tab="remove" eol="lf" eof="asis" />
+ <assertequal junk="5" />
+ </target>
+
+ <target name="test6" depends="setUp">
+ <fixcrlf srcdir="${input}/input" destdir="${output}"
+ includes="Junk6.java"
+ tab="add" cr="remove" eol="crlf" eof="asis" />
+ <assertequal junk="6" />
+ </target>
+
+ <target name="test7" depends="setUp">
+ <fixcrlf srcdir="${input}/input" destdir="${output}"
+ includes="Junk7.java"
+ tab="add" cr="add" eof="asis" />
+ <assertequal junk="7" />
+ </target>
+
+ <target name="test8" depends="setUp">
+ <fixcrlf srcdir="${input}/input" destdir="${output}"
+ includes="Junk8.java"
+ javafiles="true" tab="add" cr="add" eof="add" />
+ <assertequal junk="8" />
+ </target>
+
+ <target name="test9" depends="setUp">
+ <fixcrlf srcdir="${input}/input" destdir="${output}"
+ includes="Junk9.java"
+ javafiles="true" tab="remove" cr="remove" eof="remove" />
+ <assertequal junk="9" />
+ </target>
+
+ <target name="testMacLines" depends="setUp">
+ <fixcrlf srcdir="${input}/input" destdir="${output}"
+ includes="Mac2Unix" eol="lf" />
+ <assertequal name="Mac2Unix" />
+ </target>
+
+ <target name="testNoOverwrite" depends="test1">
+ <touch file="${output}/Junk1.java" millis="0" />
+ <fixcrlf srcdir="${input}/input" destdir="${output}"
+ includes="Junk1.java" preservelastmodified="false"
+ javafiles="true" tab="add" eol="crlf" eof="asis" />
+ <fail message="overwrote unchanged output file">Q
+ <condition>
+ <not>
+ <isfileselected file="${output}/Junk1.java">
+ <date when="equal" millis="0" />
+ </isfileselected>
+ </not>
+ </condition>
+ </fail>
+ </target>
+
+ <target name="testEncoding" depends="setUp">
+ <fixcrlf srcdir="${input}/input" destdir="${output}"
+ includes="input.crlf.utf16"
+ javafiles="false" cr="remove" encoding="UnicodeBig" />
+ <assertequal file1="${output}/input.crlf.utf16"
+ file2="${input}/expected/input.lf.utf16" />
+ </target>
+
+ <target name="testOutputEncoding" depends="setUp">
+ <fixcrlf srcdir="${input}/input" destdir="${output}"
+ includes="input.crlf.utf16"
+ javafiles="false" eol="lf" encoding="UnicodeBig"
+ outputencoding="ascii" />
+ <assertequal file1="${output}/input.crlf.utf16"
+ file2="${input}/expected/input.lf.ascii" />
+ </target>
+
+ <target name="testLongLines" depends="setUp">
+ <fixcrlf srcdir="${input}/input" destdir="${output}"
+ includes="longlines.crlf"
+ javafiles="false" cr="remove" />
+ <assertequal file1="${output}/longlines.crlf"
+ file2="${input}/expected/longlines.lf" />
+ </target>
+
+ <target name="testCrCrLfSequence-unix" depends="setUp">
+ <fixcrlf srcdir="${input}/input" destdir="${output}"
+ includes="crcrlf" eol="lf" />
+ <assertequal file1="${output}/crcrlf"
+ file2="${input}/expected/crcrlf.unix" />
+ </target>
+
+ <target name="testCrCrLfSequence-dos" depends="setUp">
+ <fixcrlf srcdir="${input}/input" destdir="${output}"
+ includes="crcrlf" eol="crlf" />
+ <assertequal file1="${output}/crcrlf"
+ file2="${input}/expected/crcrlf.dos" />
+ </target>
+
+ <target name="testCrCrLfSequence-mac" depends="setUp">
+ <fixcrlf srcdir="${input}/input" destdir="${output}"
+ includes="crcrlf" eol="cr" />
+ <assertequal file1="${output}/crcrlf"
+ file2="${input}/expected/crcrlf.mac" />
+ </target>
+
+ <target name="testFixlastDos" depends="setUp">
+ <fixcrlf srcdir="${input}/input" destdir="${output}"
+ includes="fixlastfalse.lf" eol="crlf" />
+ <assertequal file1="${output}/fixlastfalse.lf"
+ file2="${input}/expected/fixlast.dos" />
+ </target>
+
+ <target name="testFixlastFalseMac" depends="setUp">
+ <fixcrlf srcdir="${input}/input" destdir="${output}"
+ includes="fixlastfalse.lf" eol="cr" fixlast="false" />
+ <assertequal file1="${output}/fixlastfalse.lf"
+ file2="${input}/expected/fixlastfalse.mac" />
+ </target>
+
+ <!-- Bugzilla Report 20840 -->
+ <target name="createParentDirs" depends="setUp">
+ <fixcrlf srcdir="${input}" destdir="${output}" includes="input/Junk1.java" />
+ </target>
+
+ <target name="testFixFile" depends="setUp">
+ <fixcrlf file="${input}/input/longlines.crlf" destdir="${output}" />
+ <fail message="didn't create output file">
+ <condition>
+ <not>
+ <available file="${output}/longlines.crlf" />
+ </not>
+ </condition>
+ </fail>
+ </target>
+
+ <target name="testFixFileExclusive" depends="setUp">
+ <fixcrlf file="${input}/input/longlines.crlf" srcdir="${input}/input" destdir="${output}"/>
+ </target>
+
+ <target name="testPreserveLastModified" depends="setUp">
+ <fixcrlf file="${input}/input/longlines.crlf" destdir="${output}"
+ preservelastmodified="true" />
+ <fail>
+ <condition>
+ <not>
+ <uptodate srcfile="${output}/longlines.crlf"
+ targetfile="${input}/input/longlines.crlf" />
+ </not>
+ </condition>
+ </fail>
+
+ <touch file="${output}/longlines.crlf" millis="0" />
+
+ <fixcrlf file="${output}/longlines.crlf" destdir="${output}" eol="lf"
+ preservelastmodified="true" />
+
+ <fileset id="fs" file="${output}/longlines.crlf">
+ <date when="equal" millis="0" />
+ </fileset>
+ <property name="fs" refid="fs" />
+ <fail unless="fs" />
+ </target>
+
+ <target name="testFilter1" depends="setUp">
+ <copy file="${input}/input/Junk1.java" todir="${output}" overwrite="true">
+ <filterchain>
+ <fixcrlf javafiles="true" tab="add"
+ eol="crlf" eof="asis" />
+ </filterchain>
+ </copy>
+ <assertequal junk="1" />
+ </target>
+
+ <target name="testFilter2" depends="setUp">
+ <copy file="${input}/input/Junk2.java" todir="${output}" overwrite="true">
+ <filterchain>
+ <fixcrlf javafiles="true" tab="add" cr="add" eol="crlf" eof="asis" />
+ </filterchain>
+ </copy>
+ <assertequal junk="2" />
+ </target>
+
+ <target name="testFilter3" depends="setUp">
+ <copy file="${input}/input/Junk3.java" todir="${output}" overwrite="true">
+ <filterchain>
+ <fixcrlf javafiles="true" tab="remove" eol="lf" eof="asis" />
+ </filterchain>
+ </copy>
+ <assertequal junk="3" />
+ </target>
+
+ <target name="testFilter4" depends="setUp">
+ <copy file="${input}/input/Junk4.java" todir="${output}" overwrite="true">
+ <filterchain>
+ <fixcrlf javafiles="true" tab="remove" eol="lf" eof="asis" />
+ </filterchain>
+ </copy>
+ <assertequal junk="4" />
+ </target>
+
+ <target name="testFilter5" depends="setUp">
+ <copy file="${input}/input/Junk5.java" todir="${output}" overwrite="true">
+ <filterchain>
+ <fixcrlf tab="remove" eol="lf" eof="asis" />
+ </filterchain>
+ </copy>
+ <assertequal junk="5" />
+ </target>
+
+ <target name="testFilter6" depends="setUp">
+ <copy file="${input}/input/Junk6.java" todir="${output}" overwrite="true">
+ <filterchain>
+ <fixcrlf tab="add" cr="remove" eol="crlf" eof="asis" />
+ </filterchain>
+ </copy>
+ <assertequal junk="6" />
+ </target>
+
+ <target name="testFilter7" depends="setUp">
+ <copy file="${input}/input/Junk7.java" todir="${output}" overwrite="true">
+ <filterchain>
+ <fixcrlf tab="add" cr="add" eof="asis" />
+ </filterchain>
+ </copy>
+ <assertequal junk="7" />
+ </target>
+
+ <target name="testFilter8" depends="setUp">
+ <copy file="${input}/input/Junk8.java" todir="${output}" overwrite="true">
+ <filterchain>
+ <fixcrlf javafiles="true" tab="add" cr="add" eof="add" />
+ </filterchain>
+ </copy>
+ <assertequal junk="8" />
+ </target>
+
+ <target name="testFilter9" depends="setUp">
+ <copy file="${input}/input/Junk9.java" todir="${output}" overwrite="true">
+ <filterchain>
+ <fixcrlf javafiles="true" tab="remove" cr="remove" eof="remove" />
+ </filterchain>
+ </copy>
+ <assertequal junk="9" />
+ </target>
+
+ <target name="testCannotDoubleEof" depends="test8">
+ <fixcrlf file="${output}/Junk8.java"
+ javafiles="true" tab="add" cr="add" eof="add" />
+ <assertequal junk="8" />
+ </target>
+
+ <target name="testTabInLiteralInComment" depends="setUp">
+ <copy file="${input}/input/tab_in_literal_in_comment" todir="${output}"
+ overwrite="true">
+ <filterchain>
+ <fixcrlf javafiles="true" tab="remove" eol="lf" fixlast="false" />
+ </filterchain>
+ </copy>
+ <assertequal name="tab_in_literal_in_comment" />
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/fixcrlf/expected.zip b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/fixcrlf/expected.zip
new file mode 100644
index 00000000..3111502a
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/fixcrlf/expected.zip
Binary files differ
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/fixcrlf/input.zip b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/fixcrlf/input.zip
new file mode 100644
index 00000000..f65ba92d
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/fixcrlf/input.zip
Binary files differ
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/foo.properties b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/foo.properties
new file mode 100644
index 00000000..e4a8152e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/foo.properties
@@ -0,0 +1,15 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+foo=Foo
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/get.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/get.xml
new file mode 100644
index 00000000..b74e92ab
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/get.xml
@@ -0,0 +1,107 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<project name="xxx-test" basedir="." default="test1">
+
+ <target name="test1">
+ <get/>
+ </target>
+
+ <target name="test2">
+ <get src=""/>
+ </target>
+
+ <target name="test3">
+ <get src="" dest=""/>
+ </target>
+
+ <target name="test4">
+ <get src="" dest=""/>
+ </target>
+
+ <target name="test5">
+ <get src="http://www.apache.org/" dest=""/>
+ </target>
+
+ <target name="test6">
+ <get src="http://www.apache.org/" dest="get.tmp" userAgent="Apache Ant/test"/>
+
+ <fileset id="t6" file="get.tmp" />
+ <pathconvert property="t6" refid="t6" setonempty="false" />
+
+ <fail message="get failed">
+ <condition>
+ <not>
+ <isset property="t6" />
+ </not>
+ </condition>
+ </fail>
+ </target>
+
+ <target name="test7">
+ <get src="" dest="" userAgent=""/>
+ </target>
+
+ <target name="testUseTimestamp" depends="-90s,-timestamp" />
+
+ <target name="-90s">
+ <property name="off" value="-90" />
+ <property name="unit" value="second" />
+ </target>
+
+ <target name="testUseTomorrow" depends="+1d,-timestamp" />
+
+ <target name="+1d">
+ <property name="off" value="1" />
+ <property name="unit" value="day" />
+ </target>
+
+ <target name="-timestamp">
+ <property name="pat" value="yyyyMMddHHmm" />
+
+ <tstamp>
+ <format property="dt" pattern="${pat}" offset="${off}" unit="${unit}" />
+ </tstamp>
+
+ <touch file="get.tmp" datetime="${dt}" pattern="${pat}" />
+
+ <get src="http://www.w3.org/MarkUp" dest="get.tmp"
+ usetimestamp="true" verbose="true" />
+
+ <fileset id="ts" file="get.tmp">
+ <date when="equal" datetime="${dt}" pattern="${pat}" />
+ </fileset>
+
+ <pathconvert property="ts" refid="ts" setonempty="false" />
+
+ <fail message="get w/ timestamp should have failed.">
+ <condition>
+ <not>
+ <isset property="ts" />
+ </not>
+ </condition>
+ </fail>
+ </target>
+
+ <target name="cleanup">
+ <delete>
+ <fileset dir="${basedir}" includes="get.tmp" />
+ </delete>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/gunzip.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/gunzip.xml
new file mode 100644
index 00000000..ea75d54d
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/gunzip.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<project name="xxx-test" basedir="." default="test1">
+
+ <target name="test1">
+ <gunzip/>
+ </target>
+
+ <target name="test2">
+ <gunzip src=""/>
+ </target>
+
+ <target name="cleanup">
+ <delete file="asf-logo.gif" />
+ </target>
+
+ <target name="testGzipTask">
+ <ant antfile="gzip.xml" target="realTest" />
+ <gunzip src="asf-logo.gif.gz" dest="asf-logo.gif" />
+ <ant antfile="gzip.xml" target="cleanup" />
+ </target>
+
+ <target name="realTest">
+ <gunzip src="expected/asf-logo.gif.gz" dest="asf-logo.gif" />
+ </target>
+
+ <target name="realTestWithResource">
+ <gunzip dest="asf-logo.gif">
+ <file file="expected/asf-logo.gif.gz"/>
+ </gunzip>
+ </target>
+
+ <target name="testDocumentationClaimsOnCopy">
+ <copy todir=".">
+ <gzipresource>
+ <file file="expected/asf-logo.gif.gz"/>
+ </gzipresource>
+ <mapper type="glob" from="*.gz" to="*"/>
+ </copy>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/gzip.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/gzip.xml
new file mode 100644
index 00000000..f1c42623
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/gzip.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<project name="xxx-test" basedir="." default="test1">
+
+ <target name="test1">
+ <gzip/>
+ </target>
+
+ <target name="test2">
+ <gzip src=""/>
+ </target>
+
+ <target name="test3">
+ <gzip zipfile=""/>
+ </target>
+
+ <target name="test4">
+ <gzip src="gzip.xml" zipfile="." />
+ </target>
+
+ <target name="realTest">
+ <gzip src="../asf-logo.gif" zipfile="asf-logo.gif.gz" />
+ </target>
+
+ <target name="realTestWithResource">
+ <gzip zipfile="asf-logo.gif.gz">
+ <file file="../asf-logo.gif"/>
+ </gzip>
+ </target>
+
+ <target name="testDateCheck">
+ <touch file="asf-logo.gif.gz"/>
+ <gzip src="../asf-logo.gif" zipfile="asf-logo.gif.gz" />
+ </target>
+
+ <target name="cleanup">
+ <delete file="asf-logo.gif.gz" />
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/a.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/a.xml
new file mode 100644
index 00000000..cf4e7a5c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/a.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="A">
+ <target name="x"/>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/b.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/b.xml
new file mode 100644
index 00000000..f95cf010
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/b.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="B">
+ <import file="a.xml"/>
+ <target name="x" depends="A.x"/>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/bad.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/bad.xml
new file mode 100644
index 00000000..a3a06479
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/bad.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project>
+<<<
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/c.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/c.xml
new file mode 100644
index 00000000..d92fbc7f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/c.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="C">
+ <import file="a.xml"/>
+ <import file="b.xml"/>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/import.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/import.xml
new file mode 100644
index 00000000..f84d8e33
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/import.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="import-test" default="main" basedir=".">
+ <echo>Before import</echo>
+
+ <import file="imported.xml"/>
+
+ <echo message="After import"/>
+
+ <target name="import-init">
+ <echo message="In import-init" />
+ </target>
+
+ <target name="main" depends="imported">
+ <echo message="In main"/>
+ </target>
+
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/import_bad_import.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/import_bad_import.xml
new file mode 100644
index 00000000..8ff53672
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/import_bad_import.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project>
+ <import file="bad.xml"/>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/import_same_target.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/import_same_target.xml
new file mode 100644
index 00000000..f2b1933e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/import_same_target.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project>
+ <target name="t"/>
+ <target name="t"/>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/imported.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/imported.xml
new file mode 100644
index 00000000..19dfdb07
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/imported.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="imported-test" default="imported" basedir=".">
+
+ <echo message="In imported top"/>
+
+ <target name="imported" depends="import-init" >
+ <echo message="In imported target" />
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/importtargetfirst.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/importtargetfirst.xml
new file mode 100644
index 00000000..835191ba
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/importtargetfirst.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project>
+ <echo>Importing targetfirst</echo>
+ <import file="targetfirst.xml"/>
+ <echo>After importing</echo>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/recursive-selfimport.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/recursive-selfimport.xml
new file mode 100644
index 00000000..d5ae3b28
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/recursive-selfimport.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project>
+ <echo>Before import: ${foo}</echo>
+ <property name="foo" value="bar"/>
+ <import file="./recursive-selfimport.xml"/>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/same_target.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/same_target.xml
new file mode 100644
index 00000000..1a14fe59
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/same_target.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project>
+ <import file="import_same_target.xml"/>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/subdir/importinsequential-inner.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/subdir/importinsequential-inner.xml
new file mode 100644
index 00000000..cc2a6813
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/subdir/importinsequential-inner.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project>
+ <target name="within-imported">
+ <property name="foo" value="bar"/>
+ <path id="baz">
+ <pathelement location="."/>
+ </path>
+ </target>
+</project> \ No newline at end of file
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/subdir/importinsequential.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/subdir/importinsequential.xml
new file mode 100644
index 00000000..fdd68b06
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/subdir/importinsequential.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project>
+ <sequential>
+ <import file="importinsequential-inner.xml"/>
+ </sequential>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/subdir/importintarget-inner.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/subdir/importintarget-inner.xml
new file mode 100644
index 00000000..cd5086ee
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/subdir/importintarget-inner.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project>
+ <property name="foo" value="bar"/>
+ <path id="baz">
+ <pathelement location="."/>
+ </path>
+</project> \ No newline at end of file
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/subdir/importintarget.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/subdir/importintarget.xml
new file mode 100644
index 00000000..2dfa370e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/subdir/importintarget.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project>
+ <target name="do-import">
+ <import file="importintarget-inner.xml"/>
+ </target>
+
+ <target name="no-import"/>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/subdir/serial.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/subdir/serial.xml
new file mode 100644
index 00000000..360f9d16
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/subdir/serial.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="serial">
+ <import file="../unnamed1.xml"/>
+ <import file="../unnamed2.xml"/>
+</project>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/symlinks/d1/p1.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/symlinks/d1/p1.xml
new file mode 100644
index 00000000..d1b792cb
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/symlinks/d1/p1.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="p1" default="run">
+ <import file="../d2/p2.xml"/>
+ <import file="../d3b/p3.xml"/>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/symlinks/d2/p2.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/symlinks/d2/p2.xml
new file mode 100644
index 00000000..51948c9d
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/symlinks/d2/p2.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="p2"/>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/symlinks/d3a/p3.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/symlinks/d3a/p3.xml
new file mode 100644
index 00000000..31858455
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/symlinks/d3a/p3.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="p3"/>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/targetfirst.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/targetfirst.xml
new file mode 100644
index 00000000..06c1fbed
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/targetfirst.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project>
+ <target name="first"/>
+ <echo>After target first</echo>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/unnamed1.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/unnamed1.xml
new file mode 100644
index 00000000..6fc7fde5
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/unnamed1.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="test">
+ <import file="unnamed2.xml"/>
+
+ <echo message="Unnamed1.xml" level="info"/>
+</project> \ No newline at end of file
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/unnamed2.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/unnamed2.xml
new file mode 100644
index 00000000..c0fd7c65
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/unnamed2.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="test">
+ <echo message="Unnamed2.xml" level="info"/>
+</project> \ No newline at end of file
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/unnamedImport.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/unnamedImport.xml
new file mode 100644
index 00000000..13b3a85c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/import/unnamedImport.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="unnamed-import" default="test">
+
+ <import file="unnamed1.xml"/>
+
+ <target name="test">
+ <echo level="info">Tests import of unnamed projects</echo>
+ </target>
+</project> \ No newline at end of file
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/initializeclass.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/initializeclass.xml
new file mode 100644
index 00000000..6e079919
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/initializeclass.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<project name="test" default="all">
+ <target name="all"/>
+
+ <target name="forked">
+ <java fork="true" output="forkedout" failonerror="true"
+ className="org.apache.tools.ant.taskdefs.dir1.B">
+
+ <classpath>
+ <pathelement path="../../../../build/testcases"/>
+ <pathelement location="${java.home}/lib/classes.zip" />
+ </classpath>
+ </java>
+ </target>
+
+ <target name="unforked">
+ <java className="org.apache.tools.ant.taskdefs.dir1.B">
+ <classpath>
+ <pathelement path="../../../../build/testcases"/>
+ <pathelement location="${java.home}/lib/classes.zip" />
+ </classpath>
+ </java>
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/input.properties b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/input.properties
new file mode 100644
index 00000000..c0025a3f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/input.properties
@@ -0,0 +1,25 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+Press\ Return\ key\ to\ continue...=test
+All\ data\ is\ going\ to\ be\ deleted\ from\ DB\ continue?=test
+All\ data\ is\ going\ to\ be\ deleted\ from\ db\ continue\ (y/n)?=y
+Please\ enter\ db-username\:=scott
+#
+# JDK 1.1 doesn't seem to handle blanks in the property key
+#
+Press_Return_key_to_continue...=test
+All_data_is_going_to_be_deleted_from_DB_continue?=test
+All_data_is_going_to_be_deleted_from_db_continue_(y/n)?=y
+Please_enter_db_username=scott
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/input.stdin b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/input.stdin
new file mode 100644
index 00000000..3bd1f0e2
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/input.stdin
@@ -0,0 +1,2 @@
+foo
+bar
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/input.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/input.xml
new file mode 100644
index 00000000..d204b79d
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/input.xml
@@ -0,0 +1,119 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<project name="input-test" basedir="." default="test1">
+
+ <target name="test1">
+ <input>Press Return key to continue...</input>
+ </target>
+
+ <target name="test2">
+ <input message="Press Return key to continue..." />
+ </target>
+
+ <target name="test3">
+ <input message="All data is going to be deleted from DB continue?"
+ validargs="y,n"
+ />
+ </target>
+
+ <target name="test5">
+ <input message="All data is going to be deleted from db continue (y/n)?"
+ validargs="y,n"
+ />
+ </target>
+
+ <target name="test6">
+ <input message="Please enter db-username:"
+ addproperty="db.user"
+ />
+ </target>
+
+ <target name="testPropertyFileInlineHandler">
+ <input message="Press Return key to continue..." addproperty="test">
+ <handler type="propertyfile" />
+ </input>
+ <fail>
+ <condition>
+ <not>
+ <equals arg1="${test}" arg2="test" />
+ </not>
+ </condition>
+ </fail>
+ </target>
+
+ <target name="testDefaultInlineHandler">
+ <input message="Press Return key to continue..." addproperty="test">
+ <handler type="default" />
+ </input>
+ <fail message="$${test} = ${test}">
+ <condition>
+ <not>
+ <equals arg1="${test}" arg2="foo" />
+ </not>
+ </condition>
+ </fail>
+ </target>
+
+ <target name="testGreedyInlineHandler">
+ <input message="Press Return key to continue..." addproperty="test">
+ <handler type="greedy" />
+ </input>
+ <loadfile srcFile="input.stdin" property="input" />
+ <fail message="$${test} = ${test}">
+ <condition>
+ <not>
+ <equals arg1="${test}" arg2="${input}" />
+ </not>
+ </condition>
+ </fail>
+ </target>
+
+ <target name="testGreedyInlineHandlerClassname">
+ <input message="Press Return key to continue..." addproperty="test">
+ <handler classname="org.apache.tools.ant.input.GreedyInputHandler" />
+ </input>
+ <loadfile srcFile="input.stdin" property="input" />
+ <fail message="$${test} = ${test}">
+ <condition>
+ <not>
+ <equals arg1="${test}" arg2="${input}" />
+ </not>
+ </condition>
+ </fail>
+ </target>
+
+ <target name="testGreedyInlineHandlerRefid">
+ <typedef name="greedy"
+ classname="org.apache.tools.ant.input.GreedyInputHandler" />
+ <greedy id="greedy" />
+
+ <input message="Press Return key to continue..." addproperty="test">
+ <handler refid="greedy" />
+ </input>
+ <loadfile srcFile="input.stdin" property="input" />
+ <fail message="$${test} = ${test}">
+ <condition>
+ <not>
+ <equals arg1="${test}" arg2="${input}" />
+ </not>
+ </condition>
+ </fail>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/jar.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/jar.xml
new file mode 100644
index 00000000..78d1abc6
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/jar.xml
@@ -0,0 +1,285 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<project name="jar-test" basedir="." default="test1">
+
+ <import file="../buildfiletest-base.xml"/>
+
+ <target name="setUp">
+ <mkdir dir="${output}" />
+ </target>
+
+ <property name="tmp.jar" location="${output}/tmp.jar"/>
+ <property name="tmp.dir" location="${output}/jartmp"/>
+ <property name="tmp.zip" location="${output}/tmp.zip"/>
+ <property name="tmp1.dir" location="${output}/jartmp1"/>
+ <property name="tmp2.dir" location="${output}/jartmp2"/>
+
+ <target name="test1">
+ <jar/>
+ </target>
+
+ <target name="test2">
+ <jar
+ jarfile="jar.tmp"
+ manifest="none"
+ />
+ </target>
+
+ <target name="test3">
+ <jar
+ destfile="jar.tmp"
+ whenempty="format C: /y"
+ />
+ </target>
+
+ <target name="test4">
+ <jar
+ destfile="${tmp.jar}"
+ basedir="."
+ includes="jar.xml"
+ />
+ </target>
+
+ <target name="testNoRecreateWithUpdate">
+ <jar
+ destfile="${tmp.jar}"
+ basedir="."
+ includes="jar.xml"
+ update="true"
+ />
+ </target>
+
+ <target name="testRecreateNewerFileSetup" depends="test4">
+ <touch file="jar.xml"/>
+ </target>
+
+ <target name="testRecreateWithoutUpdateAdditionalFiles">
+ <jar
+ destfile="${tmp.jar}"
+ includes="*.xml"
+ basedir="."
+ />
+ </target>
+
+ <target name="testRecreateWithUpdateAdditionalFiles">
+ <jar
+ destfile="${tmp.jar}"
+ basedir="."
+ includes="*.xml"
+ update="true"
+ />
+ </target>
+
+ <target name="testRecreateWithoutUpdateNewerFile">
+ <jar
+ destfile="${tmp.jar}"
+ basedir="."
+ includes="jar.xml"
+ />
+ </target>
+
+ <target name="testRecreateWithUpdateNewerFile">
+ <jar
+ destfile="${tmp.jar}"
+ basedir="."
+ includes="jar.xml"
+ update="true"
+ />
+ </target>
+
+ <target name="testManifestStaysIntact">
+ <mkdir dir="${tmp.dir}"/>
+ <manifest file="${tmp.dir}/manifest">
+ <attribute name="Foo" value="bar"/>
+ </manifest>
+ <jar destfile="${tmp.jar}" basedir="." includes="jar.xml"
+ manifest="${tmp.dir}/manifest"/>
+ <touch file="jar.xml"/>
+ <jar destfile="${tmp.jar}" basedir="." includes="jar.xml"
+ update="true"/>
+ <unjar src="${tmp.jar}" dest="${tmp.dir}"/>
+ </target>
+
+ <target name="testNoRecreateBasedirExcludesWithUpdate">
+ <jar
+ destfile="${tmp.jar}"
+ basedir="."
+ includes="j*.xml"
+ excludes="java.xml"
+ update="true"
+ />
+ </target>
+
+ <target name="testNoRecreateBasedirExcludesWithoutUpdate">
+ <jar
+ destfile="${tmp.jar}"
+ basedir="."
+ includes="j*.xml"
+ excludes="java.xml"
+ />
+ </target>
+
+ <target name="makezip">
+ <zip destfile="${tmp.zip}"
+ basedir="." includes="j*.xml"/>
+ </target>
+
+ <target name="testNoRecreateZipfilesetExcludesWithUpdate"
+ depends="makezip">
+ <jar destfile="${tmp.jar}"
+ update="true">
+ <zipfileset src="${tmp.zip}" excludes="java.xml"/>
+ </jar>
+ </target>
+
+ <target name="testNoRecreateZipfilesetExcludesWithoutUpdate"
+ depends="makezip">
+ <jar destfile="${tmp.jar}">
+ <zipfileset src="${tmp.zip}" excludes="java.xml"/>
+ </jar>
+ </target>
+
+ <target name="testRecreateZipfilesetWithoutUpdateAdditionalFiles"
+ depends="makezip">
+ <jar destfile="${tmp.jar}">
+ <zipfileset src="${tmp.zip}"/>
+ </jar>
+ </target>
+
+ <target name="testRecreateZipfilesetWithUpdateAdditionalFiles"
+ depends="makezip">
+ <jar destfile="${tmp.jar}"
+ update="true">
+ <zipfileset src="${tmp.zip}"/>
+ </jar>
+ </target>
+
+ <target name="testRecreateZipfilesetWithoutUpdateNewerFile"
+ depends="makezip">
+ <jar destfile="${tmp.jar}">
+ <zipfileset src="${tmp.zip}" includes="jar.xml"/>
+ </jar>
+ </target>
+
+ <target name="testRecreateZipfilesetWithUpdateNewerFile"
+ depends="makezip">
+ <jar destfile="${tmp.jar}"
+ update="true">
+ <zipfileset src="${tmp.zip}" includes="jar.xml"/>
+ </jar>
+ </target>
+
+ <target name="testCreateWithEmptyFilesetSetUp">
+ <mkdir dir="${tmp1.dir}"/>
+ <mkdir dir="${tmp2.dir}"/>
+ <echo file="${tmp2.dir}/foo.txt" message="foo"/>
+ </target>
+
+ <target name="testCreateWithEmptyFileset">
+ <jar destfile="${tmp.jar}">
+ <fileset dir="${tmp1.dir}">
+ <include name="**/*.doesNotExist"/>
+ </fileset>
+ <fileset dir="${tmp2.dir}">
+ <include name="**/foo.txt"/>
+ </fileset>
+ </jar>
+ </target>
+
+ <!-- bug 17780 -->
+ <target name="testUpdateIfOnlyManifestHasChanged"
+ depends="test4">
+ <jar destfile="${tmp.jar}" update="true">
+ <manifest>
+ <attribute name="Foo" value="bar"/>
+ </manifest>
+ </jar>
+ <mkdir dir="${tmp.dir}"/>
+ <unzip src="${tmp.jar}" dest="${tmp.dir}"/>
+ </target>
+
+ <!-- bugs 10262 and 16972 -->
+ <target name="testIndexTests">
+ <mkdir dir="${tmp.dir}/META-INF"/>
+ <touch file="${tmp.dir}/META-INF/INDEX.LIST"/>
+ <touch file="${tmp.dir}/foo"/>
+ <mkdir dir="${tmp.dir}/sub"/>
+ <touch file="${tmp.dir}/sub/foo"/>
+ <jar destfile="${tmp.jar}" index="yes" basedir="${tmp.dir}"/>
+ </target>
+ <!-- bug 32802 -->
+ <target name="testManifestOnlyJar">
+ <mkdir dir="${tmp.dir}"/>
+ <jar destfile="${tmp.jar}" duplicate="preserve">
+ <manifest>
+ <attribute name="Foo" value="bar"/>
+ </manifest>
+ </jar>
+ <mkdir dir="${tmp.dir}"/>
+ <unzip src="${tmp.jar}" dest="${tmp.dir}"/>
+
+ </target>
+
+ <!-- bug 37237 -->
+ <target name="testIndexJarsPlusJarMarker">
+ <mkdir dir="${tmp.dir}/a/b/c"/>
+ <jar destfile="${tmp.jar}" basedir="${tmp.dir}"/>
+ <delete dir="${tmp.dir}/a" quiet="true"/>
+ <mkdir dir="${tmp.dir}/d/e/f"/>
+ <jar destfile="${tmp.jar}2" basedir="${tmp.dir}" index="true">
+ <indexjars>
+ <fileset file="${tmp.jar}"/>
+ </indexjars>
+ </jar>
+ </target>
+
+ <target name="testNoVersionInfoNoStrict">
+ <mkdir dir="${tmp.dir}"/>
+ <jar destfile="${tmp.jar}" basedir="${tmp.dir}"/>
+ </target>
+
+ <target name="testNoVersionInfoFail">
+ <mkdir dir="${tmp.dir}"/>
+ <jar destfile="${tmp.jar}" basedir="${tmp.dir}" strict="fail"/>
+ </target>
+
+ <target name="testNoVersionInfoIgnore">
+ <mkdir dir="${tmp.dir}"/>
+ <jar destfile="${tmp.jar}" basedir="${tmp.dir}" strict="ignore"/>
+ </target>
+
+ <target name="testNoVersionInfoWarn">
+ <mkdir dir="${tmp.dir}"/>
+ <jar destfile="${tmp.jar}" basedir="${tmp.dir}" strict="warn"/>
+ </target>
+
+ <!-- see http://java.sun.com/j2se/1.3/docs/guide/versioning/spec/VersioningSpecification.html#PackageVersioning -->
+ <target name="testHasVersionInfo">
+ <mkdir dir="${tmp.dir}"/>
+ <jar destfile="${tmp.jar}" basedir="${tmp.dir}" strict="fail">
+ <manifest>
+ <attribute name="Implementation-Title" value="Packaging Version Test"/>
+ <attribute name="Implementation-Version" value="1.0"/>
+ <attribute name="Implementation-Vendor" value="Apache Software Foundation"/>
+ </manifest>
+ </jar>
+ </target>
+
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/java.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/java.xml
new file mode 100644
index 00000000..a0c0450b
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/java.xml
@@ -0,0 +1,404 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<project name="java-test" basedir="." default="foo">
+ <property name="tests-classpath.value" value="${java.class.path}"/>
+ <fail unless="tests-classpath.value"
+ message="the property tests-classpath.value is required by this test" />
+ <import file="../buildfiletest-base.xml"/>
+
+ <target name="setUp">
+ <mkdir dir="${output}" />
+ </target>
+
+ <!-- this property gets overridden programmatically-->
+ <property name="timeToWait" value="4"/>
+ <!-- this property gets overridden programmatically-->
+ <property name="logFile" value="${output}/spawn.log"/>
+ <property name="tmp" location="${output}/ant.tmp.java-test"/>
+ <mkdir dir="${tmp}" description="The directory must exist"/>
+ <property name="app"
+ value="org.apache.tools.ant.taskdefs.JavaTest$$EntryPoint" />
+
+ <property name="app2"
+ value="org.apache.tools.ant.taskdefs.JavaTest$$ExceptingEntryPoint" />
+
+ <property name="spawnapp"
+ value="org.apache.tools.ant.taskdefs.JavaTest$$SpawnEntryPoint" />
+
+ <property name="pipeapp"
+ value="org.apache.tools.ant.taskdefs.JavaTest$$PipeEntryPoint" />
+
+ <target name="testNoJarNoClassname">
+ <java/>
+ </target>
+
+ <target name="testJarNoFork">
+ <java jar="test.jar" fork="false"/>
+ </target>
+
+
+ <target name="testJarAndClassName">
+ <java jar="test.jar" classname="${app}" />
+ </target>
+
+ <target name="testClassnameAndJar">
+ <java classname="${app}" jar="test.jar" />
+ </target>
+
+ <target name="testRun">
+ <fail unless="tests-classpath.value" />
+ <java classname="${app}"
+ classpath="${tests-classpath.value}"/>
+ </target>
+
+ <target name="testRunFail">
+ <java classname="${app}"
+ classpath="${tests-classpath.value}"
+ >
+ <arg value="2"/>
+ </java>
+ </target>
+
+ <target name="testRunFailFoe">
+ <java classname="${app}"
+ classpath="${tests-classpath.value}"
+ failonerror="true">
+ <arg value="2"/>
+ </java>
+ </target>
+
+ <target name="testRunFailFoeFork">
+ <java classname="${app}"
+ classpath="${tests-classpath.value}"
+ failonerror="true"
+ fork="true">
+ <arg value="2"/>
+ </java>
+ </target>
+
+ <target name="testExcepting">
+ <java classname="${app2}"
+ classpath="${tests-classpath.value}"
+ >
+ </java>
+ </target>
+
+ <target name="testExceptingFork">
+ <java classname="${app2}"
+ classpath="${tests-classpath.value}"
+ fork="true">
+ </java>
+ </target>
+
+ <target name="testExceptingFoe">
+ <java classname="${app2}"
+ classpath="${tests-classpath.value}"
+ failonerror="true">
+ </java>
+ </target>
+
+ <target name="testExceptingFoeFork">
+ <java classname="${app2}"
+ classpath="${tests-classpath.value}"
+ failonerror="true"
+ fork="true">
+ </java>
+ </target>
+
+ <target name="testResultPropertyZero">
+ <java classname="${app}"
+ classpath="${tests-classpath.value}"
+ resultproperty="exitcode"
+ fork="true"
+ >
+ </java>
+ <echo message="exitcode = ${exitcode}"/>
+ </target>
+
+ <target name="testResultPropertyNonZero">
+ <java classname="${app}"
+ classpath="${tests-classpath.value}"
+ resultproperty="exitcode"
+ failonerror="false"
+ fork="true"
+ >
+ <arg value="2"/>
+ </java>
+ <echo message="exitcode = ${exitcode}"/>
+ </target>
+
+ <target name="testResultPropertyZeroNoFork">
+ <java classname="${app}"
+ classpath="${tests-classpath.value}"
+ resultproperty="exitcode"
+ fork="false"
+ >
+ <permissions/>
+ </java>
+ <echo message="exitcode = ${exitcode}"/>
+ </target>
+
+ <target name="testResultPropertyNonZeroNoFork">
+ <java classname="${app}"
+ classpath="${tests-classpath.value}"
+ resultproperty="exitcode"
+ failonerror="false"
+ fork="false">
+ <arg value="-1"/>
+ <permissions/>
+ </java>
+ <echo message="exitcode = ${exitcode}"/>
+ </target>
+
+ <target name="testRunFailWithFailOnError">
+ <java classname="${app}"
+ classpath="${tests-classpath.value}"
+ failonerror="true"
+ >
+ <arg value="2"/>
+ </java>
+ </target>
+
+ <target name="testRunSuccessWithFailOnError">
+ <java classname="${app}"
+ classpath="${tests-classpath.value}"
+ failonerror="true"
+ >
+ <arg value="0"/>
+ </java>
+ </target>
+
+ <target name="testSpawn">
+ <java classname="${spawnapp}" fork="true" spawn="true" classpath="${tests-classpath.value}">
+ <arg value="${timeToWait}"/>
+ <arg value="${logFile}" />
+ </java>
+ </target>
+
+ <!--redirection testcases don't want to run under junit unless forked-->
+ <target name="redirect1">
+ <tempfile property="outfile" destdir="${tmp}" prefix="redirect" suffix=".out" deleteonexit="true"/>
+
+ <java classname="${pipeapp}"
+ classpath="${tests-classpath.value}"
+ inputstring="foo"
+ fork="true"
+ output="${outfile}"
+ errorproperty="redirect.err">
+ <arg value="out" />
+ </java>
+
+ <!-- let dumb Windows catch up -->
+ <waitfor maxwait="30000">
+ <available file="${outfile}" />
+ </waitfor>
+ <waitfor maxwait="30000">
+ <length file="${outfile}" length="1" when="greater" />
+ </waitfor>
+
+ <loadfile property="redirect.out.contents" srcfile="${outfile}" />
+
+ <condition property="r1file">
+ <equals arg1="${redirect.out.contents}" arg2="foo" />
+ </condition>
+
+ <fail unless="r1file">${outfile}:
+&quot;${redirect.out.contents}&quot; expected &quot;foo&quot;</fail>
+
+ <condition property="r1prop">
+ <equals arg1="${redirect.err}" arg2="" />
+ </condition>
+
+ <fail unless="r1prop">
+redirect.err=&quot;${redirect.err}&quot; should be empty</fail>
+
+ </target>
+
+ <target name="redirect2" depends="redirect1">
+ <tempfile property="outfile" destdir="${tmp}" prefix="redirect" suffix=".out" deleteonexit="true"/>
+
+ <java classname="${pipeapp}"
+ classpath="${tests-classpath.value}"
+ inputstring="bar"
+ append="true"
+ fork="true"
+ output="${outfile}"
+ errorproperty="redirect.err">
+ <arg value="both" />
+ </java>
+
+ <!-- let dumb Windows catch up -->
+ <waitfor maxwait="30000">
+ <available file="${outfile}" />
+ </waitfor>
+ <waitfor maxwait="30000">
+ <length file="${outfile}" length="1" when="greater" />
+ </waitfor>
+
+
+ <loadfile property="redirect.out.contents2" srcfile="${outfile}" />
+
+ <condition property="r2file">
+ <equals arg1="${redirect.out.contents2}" arg2="foobar" />
+ </condition>
+
+ <fail unless="r2file">${outfile}:
+&quot;${redirect.out.contents2}&quot; expected &quot;foobar&quot;</fail>
+
+ <condition property="r2prop">
+ <!-- property should not change -->
+ <equals arg1="${redirect.err}" arg2="" />
+ </condition>
+
+ <fail unless="r2prop">
+redirect.err=&quot;${redirect.err}&quot; should be empty</fail>
+
+ </target>
+
+ <target name="redirect3">
+ <tempfile property="outfile" destdir="${tmp}" prefix="redirect" suffix=".out" deleteonexit="true"/>
+ <tempfile property="errfile" destdir="${tmp}" prefix="redirect" suffix=".err" deleteonexit="true"/>
+
+ <java classname="${pipeapp}"
+ classpath="${tests-classpath.value}"
+ inputstring="foo"
+ fork="true"
+ output="${outfile}"
+ error="${errfile}">
+ <arg value="both" />
+ </java>
+
+ <!-- let dumb Windows catch up -->
+ <waitfor>
+ <and>
+ <available file="${outfile}" />
+ <available file="${errfile}" />
+ </and>
+ </waitfor>
+
+ <loadfile property="redirect.out.contents" srcfile="${outfile}" />
+
+ <condition property="r3file">
+ <equals arg1="${redirect.out.contents}" arg2="foo" />
+ </condition>
+
+ <fail unless="r3file">${outfile}:
+&quot;${redirect.out.contents}&quot; expected &quot;foo&quot;</fail>
+
+ <condition property="r3match">
+ <filesmatch file1="${outfile}" file2="${errfile}" />
+ </condition>
+
+ <fail unless="r3file">${errfile} differs from ${outfile}</fail>
+
+ </target>
+
+ <target name="redirector1">
+ <tempfile property="outfile" destdir="${tmp}" prefix="redirect" suffix=".out" deleteonexit="true"/>
+ <tempfile property="errfile" destdir="${tmp}" prefix="redirect" suffix=".err" deleteonexit="true"/>
+
+ <java taskname="foo" classname="${pipeapp}" fork="true"
+ classpath="${tests-classpath.value}">
+ <redirector inputstring="foo"
+ output="${outfile}"
+ error="${errfile}"
+ createemptyfiles="false" />
+ <arg value="out" />
+ </java>
+
+ <!-- let dumb Windows catch up -->
+ <waitfor>
+ <available file="${outfile}" />
+ </waitfor>
+
+ <loadfile property="redirector.out.contents" srcfile="${outfile}" />
+
+ <condition property="ror1out">
+ <equals arg1="${redirector.out.contents}" arg2="foo" />
+ </condition>
+
+ <fail unless="ror1out">${outfile}:
+&quot;${redirector.out.contents}&quot; expected &quot;foo&quot;</fail>
+
+ <condition property="ror1noerr">
+ <not>
+ <available file="${errfile}" />
+ </not>
+ </condition>
+ <fail unless="ror1noerr">${errfile} exists but should not</fail>
+ </target>
+
+ <target name="redirector2" depends="redirector1">
+ <tempfile property="outfile" destdir="${tmp}" prefix="redirect" suffix=".out" deleteonexit="true"/>
+ <tempfile property="errfile" destdir="${tmp}" prefix="redirect" suffix=".err" deleteonexit="true"/>
+
+ <!-- fork here; some VMs can be ill-behaved with files,
+ such as W!nd0ws -->
+ <java taskname="foo" classname="${pipeapp}" fork="true"
+ classpath="${tests-classpath.value}">
+ <redirector inputstring="foo"
+ append="true"
+ output="${outfile}"
+ error="${errfile}"
+ createemptyfiles="false">
+ <errorfilterchain>
+ <replacestring from="foo" to="bar" />
+ </errorfilterchain>
+ </redirector>
+ <arg value="both" />
+ </java>
+
+ <!-- let dumb Windows catch up -->
+ <waitfor>
+ <and>
+ <available file="${outfile}" />
+ <available file="${errfile}" />
+ </and>
+ </waitfor>
+
+ <loadfile property="redirector.out.contents2"
+ srcfile="${outfile}" />
+
+ <loadfile property="redirector.err.contents"
+ srcfile="${errfile}" />
+
+ <condition property="ror2out">
+ <equals arg1="${redirector.out.contents2}" arg2="foofoo" />
+ </condition>
+
+ <fail unless="ror1out">${outfile}:
+&quot;${redirector.out.contents}&quot; expected &quot;foofoo&quot;</fail>
+
+ <condition property="ror2err">
+ <equals arg1="${redirector.err.contents}" arg2="bar" />
+ </condition>
+
+ <fail unless="ror1out">${errfile}:
+&quot;${redirector.err.contents}&quot; expected &quot;bar&quot;</fail>
+
+ </target>
+
+ <target name="flushedInput">
+ <java classname="org.apache.tools.ant.taskdefs.JavaTest$$ReadPoint" fork="true"
+ classpath="${tests-classpath.value}" failonerror="true" timeout="2000" />
+ </target>
+
+ <target name="foo" />
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/javadoc/java/ClassToJavadoc.java b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/javadoc/java/ClassToJavadoc.java
new file mode 100644
index 00000000..a41bdc15
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/javadoc/java/ClassToJavadoc.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package etc.testcases.taskdefs.javadoc.java;
+
+/**
+ * This is a simple class to provide grist for the javadoc mill
+ * while testing it.
+ */
+public class ClassToJavadoc {
+ /**
+ * @param anArgument A String that is ignored
+ */
+ public void methodToJavadoc(String anArgument) { }
+
+ /**
+ * @see java.lang.Object#toString()
+ */
+ public String toString() { return this.getClass().getName(); }
+
+ /**
+ * @return An arbitrary string.
+ */
+ public String anotherString() {return "An arbitrary string.";}
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/javadoc/javadoc.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/javadoc/javadoc.xml
new file mode 100644
index 00000000..2a05ec0f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/javadoc/javadoc.xml
@@ -0,0 +1,155 @@
+<?xml version="1.0"?>
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+-->
+<project name="javadoc" basedir=".">
+ <import file="../../buildfiletest-base.xml"/>
+
+ <target name="setUp">
+ <mkdir dir="${output}"/>
+ </target>
+
+ <path id="path.dirset">
+ <dirset dir="." />
+ </path>
+
+
+ <target name="dirsetPath">
+ <javadoc sourcepathref="path.dirset" packagenames="*" destdir="${output}" />
+ </target>
+
+ <target name="dirsetPathWithoutPackagenames">
+ <javadoc sourcepathref="path.dirset" destdir="${output}" />
+ </target>
+
+ <target name="nestedDirsetPath">
+ <javadoc packagenames="*" destdir="${output}">
+ <sourcepath refid="path.dirset" />
+ </javadoc>
+ </target>
+
+ <path id="path.fileset">
+ <pathelement location="."/>
+ <fileset dir="java/" id="fileset.inpath">
+ <include name="**/*.java" />
+ </fileset>
+ </path>
+
+ <target name="filesetPath">
+ <javadoc sourcepathref="path.fileset" packagenames="*" destdir="${output}" />
+ </target>
+
+ <target name="nestedFilesetPath">
+ <javadoc packagenames="*" destdir="${output}">
+ <sourcepath refid="path.fileset" />
+ </javadoc>
+ </target>
+
+ <target name="nestedFilesetRefInPath">
+ <javadoc packagenames="*" destdir="${output}">
+ <fileset refid="fileset.inpath" />
+ </javadoc>
+ </target>
+
+ <target name="nestedFilesetNoPatterns">
+ <javadoc packagenames="*" destdir="${output}">
+ <fileset dir="java/"/>
+ </javadoc>
+ </target>
+
+ <target name="doublyNestedFileset">
+ <javadoc packagenames="*" destdir="${output}">
+ <sourcefiles>
+ <fileset dir="java/" includes="**/*.java"/>
+ </sourcefiles>
+ </javadoc>
+ </target>
+
+ <target name="doublyNestedFilesetNoPatterns">
+ <javadoc packagenames="*" destdir="${output}">
+ <sourcefiles>
+ <fileset dir="java/"/>
+ </sourcefiles>
+ </javadoc>
+ </target>
+
+ <path id="path.filelist">
+ <pathelement location="."/>
+ <filelist dir="java/">
+ <file name="ClassToJavadoc.java" />
+ </filelist>
+ </path>
+
+ <target name="filelistPath">
+ <javadoc sourcepathref="path.filelist" packagenames="*"
+ destdir="${output}" />
+ </target>
+
+ <target name="nestedFilelistPath">
+ <javadoc packagenames="*" destdir="${output}">
+ <sourcepath refid="path.filelist" />
+ </javadoc>
+ </target>
+
+ <!-- this property is set when the tests are run using ant's build.xml -->
+ <property name="root" location="../../../../.."/>
+
+ <path id="path.pathelement.path">
+ <pathelement path="${root}/src" />
+ </path>
+
+ <target name="pathelementPath">
+ <javadoc sourcepathref="path.pathelement.path"
+ packagenames="etc.testcases.taskdefs.javadoc.*" destdir="${output}" />
+ </target>
+
+ <path id="path.pathelement.location">
+ <pathelement location="."/>
+ <pathelement path="java/ClassToJavadoc.java" />
+ </path>
+
+ <target name="pathelementLocationPath">
+ <javadoc sourcepathref="path.pathelement.location"
+ packagenames="*" destdir="${output}" />
+ </target>
+
+ <target name="nestedSource">
+ <javadoc destdir="${output}">
+ <source file="java/ClassToJavadoc.java" />
+ </javadoc>
+ </target>
+
+ <fileset dir="java/" id="fileset.simple">
+ <include name="**/*.java" />
+ </fileset>
+
+ <target name="nestedFilesetRef">
+ <javadoc destdir="${output}">
+ <fileset refid="fileset.simple" />
+ </javadoc>
+ </target>
+
+ <target name="nonJavaIncludes">
+ <echo file="${output}/stuff1.java">public class stuff1 {}</echo>
+ <echo file="${output}/stuff2.java">public class stuff2 {}</echo>
+ <echo file="${output}/stuff.properties">x=4</echo>
+ <javadoc destdir="${output}" failonerror="true">
+ <fileset dir="${output}"/>
+ </javadoc>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/loadfile.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/loadfile.xml
new file mode 100644
index 00000000..66c9ce4f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/loadfile.xml
@@ -0,0 +1,163 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="loadfile-test" basedir="." default="testLoadAFile">
+
+
+ <target name="init">
+ </target>
+
+ <target name="testNoSourcefileDefined" depends="init">
+ <loadfile property="foo" />
+ </target>
+
+ <target name="testNoPropertyDefined"
+ depends="init">
+ <loadfile srcFile="somefile" />
+ </target>
+
+
+ <target name="testNoSourcefilefound"
+ depends="init">
+ <loadfile property="missing" srcFile="somefile" />
+ </target>
+
+ <target name="testFailOnError"
+ depends="init">
+ <loadfile
+ property="testFailOnError"
+ srcFile="somefile"
+ failonerror="false"/>
+ </target>
+
+ <target name="testLoadAFile"
+ depends="init">
+ <echo
+ message="What's it going to be then, eh?"
+ file="loadfile1.tmp"
+ />
+ <loadfile property="testLoadAFile" srcFile="loadfile1.tmp" />
+ <echo>${testLoadAFile}</echo>
+ </target>
+
+ <target name="testLoadAFileEnc"
+ depends="init">
+ <loadfile property="testLoadAFileEnc"
+ srcFile="loadfile.xml"
+ encoding="ISO-8859-1"/>
+ </target>
+
+ <target name="testEvalProps"
+ depends="init">
+ <property name="weather" value="rain" />
+ <echo
+ message="All these moments will be lost in time, like teardrops in the ${weather}"
+ file="loadfile1.tmp"
+ />
+ <loadfile property="testEvalProps"
+ srcFile="loadfile1.tmp">
+ <filterchain>
+ <expandproperties/>
+ </filterchain>
+ </loadfile>
+ <echo>${testEvalProps}</echo>
+ </target>
+
+ <target name="testFilterChain"
+ depends="init">
+ <echo file="loadfile1.tmp">#Line 1
+REM Line 2
+--Line 3
+Line 4
+Hello World!</echo>
+ <loadfile srcFile="loadfile1.tmp"
+ property="testFilterChain">
+ <filterchain>
+ <headfilter lines="5"/>
+ <striplinecomments>
+ <comment value="--"/>
+ <comment value="REM "/>
+ <comment value="#"/>
+ </striplinecomments>
+ <filterreader classname="org.apache.tools.ant.filters.TailFilter">
+ <param name="lines" value="1"/>
+ </filterreader>
+ <linecontains>
+ <contains value="World!"/>
+ </linecontains>
+ </filterchain>
+ </loadfile>
+ </target>
+
+ <target name="testStripJavaComments"
+ depends="init">
+ <echo file="loadfile1.tmp">
+/*
+Comment "1"
+*/
+public class test1 {
+ //Some comment
+ int x = 1/2;
+ private static final String GREETING="*/Hello/*";
+ private static final String GREETING1="/*Hello*/";
+
+ public static void main( String args[] ) {
+ }
+}</echo>
+ <echo file="nocomments.tmp">
+
+public class test1 {
+
+ int x = 1/2;
+ private static final String GREETING="*/Hello/*";
+ private static final String GREETING1="/*Hello*/";
+
+ public static void main( String args[] ) {
+ }
+}</echo>
+ <loadfile srcFile="loadfile1.tmp"
+ property="testStripJavaComments">
+ <filterchain>
+ <stripjavacomments/>
+ </filterchain>
+ </loadfile>
+ <loadfile srcFile="nocomments.tmp"
+ property="expected"/>
+ </target>
+
+ <target name="testOneLine"
+ depends="init">
+ <echo
+ message="1,&#10;2,&#13;3,&#13;&#10;4"
+ file="loadfile1.tmp"
+ />
+ <loadfile property="testOneLine"
+ srcFile="loadfile1.tmp">
+ <filterchain>
+ <striplinebreaks/>
+ </filterchain>
+ </loadfile>
+ <echo>${testOneLine}</echo>
+ </target>
+
+
+ <target name="cleanup">
+ <delete file="loadfile1.tmp"/>
+ <delete file="nocomments.tmp"/>
+ </target>
+
+ </project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/macrodef.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/macrodef.xml
new file mode 100644
index 00000000..f7a356fc
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/macrodef.xml
@@ -0,0 +1,290 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project>
+
+ <target name="simple">
+ <macrodef name="my.echo">
+ <attribute name="text"/>
+ <sequential>
+ <echo message="@{text}"/>
+ </sequential>
+ </macrodef>
+ <my.echo text="Hello World"/>
+ </target>
+
+ <target name="text">
+ <macrodef name="my.echo">
+ <attribute name="text"/>
+ <sequential>
+ <echo>@{text}</echo>
+ </sequential>
+ </macrodef>
+ <my.echo text="Inner Text"/>
+ </target>
+
+ <target name="duplicate.attribute">
+ <macrodef name="my.echo">
+ <attribute name="text"/>
+ <attribute name="text"/>
+ <sequential>
+ <echo>@{text}</echo>
+ </sequential>
+ </macrodef>
+ </target>
+
+ <target name="duplicate.element">
+ <macrodef name="my.echo">
+ <element name="text"/>
+ <element name="text"/>
+ <sequential>
+ <text/>
+ </sequential>
+ </macrodef>
+ </target>
+
+ <target name="uri">
+ <macrodef name="echo" uri="abc">
+ <attribute name="text"/>
+ <sequential>
+ <echo message="@{text}"/>
+ </sequential>
+ </macrodef>
+ <x:echo xmlns:x="abc" text="Hello World"/>
+ </target>
+
+ <target name="nested">
+ <macrodef name="nested">
+ <element name="nested"/>
+ <sequential>
+ <nested/>
+ </sequential>
+ </macrodef>
+
+ <nested>
+ <nested>
+ <echo>A nested element</echo>
+ </nested>
+ </nested>
+ </target>
+
+ <target name="double">
+ <macrodef name="double">
+ <attribute name="prop"/>
+ <sequential>
+ <echo>@@{prop} is '@{prop}', value of $${@{prop}} is '${@{prop}}'</echo>
+ </sequential>
+ </macrodef>
+ <property name="property" value="A property value"/>
+ <double prop="property"/>
+ </target>
+
+ <target name="ignorecase">
+ <macrodef name="ignore">
+ <attribute name="MyAttribute"/>
+ <sequential>
+ <echo>@{myattribute} is @{MYATTRIBUTE}</echo>
+ </sequential>
+ </macrodef>
+ <ignore myattribute="a"/>
+ <ignore Myattribute="b"/>
+ </target>
+
+ <target name="ignore-element-case">
+ <macrodef name="ignore">
+ <element name="MyElement"/>
+ <sequential>
+ <myElement/>
+ <MyElEmEnT/>
+ </sequential>
+ </macrodef>
+ <ignore>
+ <MYELEMENT>
+ <echo>nested element</echo>
+ </MYELEMENT>
+ </ignore>
+ </target>
+
+ <target name="textelement">
+ <macrodef name="echotest">
+ <text name="text" optional="yes"/>
+ <sequential>
+ <echo>@{text}</echo>
+ </sequential>
+ </macrodef>
+ <echotest>
+ Hello world
+ </echotest>
+ </target>
+
+ <target name="text.trim">
+ <macrodef name="echotest">
+ <text name="text" trim="yes"/>
+ <sequential>
+ <echo>[@{text}]</echo>
+ </sequential>
+ </macrodef>
+ <echotest>
+ Hello world
+ </echotest>
+ </target>
+
+ <target name="duplicatetextname">
+ <macrodef name="echotest">
+ <attribute name="text"/>
+ <text name="text"/>
+ <sequential>
+ <echo>@{text}</echo>
+ </sequential>
+ </macrodef>
+ </target>
+
+ <target name="duplicatetextname2">
+ <macrodef name="echotest">
+ <text name="text"/>
+ <attribute name="text"/>
+ <sequential>
+ <echo>@{text}</echo>
+ </sequential>
+ </macrodef>
+ </target>
+
+ <target name="escape">
+ <macrodef name="escape">
+ <attribute name="a"/>
+ <attribute name="b"/>
+ <sequential>
+ <echo>a@b or a@@b is @{a}@@@{b}</echo>
+ </sequential>
+ </macrodef>
+ <escape a="avalue" b="bvalue"/>
+ </target>
+
+ <target name="attribute.description">
+ <macrodef name="d">
+ <attribute name="description"/>
+ <attribute name="d" default="p"/>
+ <sequential>
+ <echo>description is @{description}</echo>
+ </sequential>
+ </macrodef>
+ <d description="hello world"/>
+ </target>
+
+ <target name="implicit">
+ <macrodef name="implicit">
+ <element name="implicit" implicit="yes"/>
+ <sequential>
+ <echo>Before implicit</echo>
+ <implicit/>
+ <echo>After implicit</echo>
+ </sequential>
+ </macrodef>
+
+ <implicit>
+ <echo>In implicit</echo>
+ </implicit>
+ </target>
+
+ <target name="implicit.notoptional">
+ <macrodef name="implicit">
+ <element name="implicit" implicit="yes"/>
+ <sequential>
+ <echo>Before implicit</echo>
+ <implicit/>
+ <echo>After implicit</echo>
+ </sequential>
+ </macrodef>
+
+ <implicit>
+ </implicit>
+ </target>
+
+ <target name="implicit.optional">
+ <macrodef name="implicit">
+ <element name="implicit" optional="yes" implicit="yes"/>
+ <sequential>
+ <echo>Before implicit</echo>
+ <implicit/>
+ <echo>After implicit</echo>
+ </sequential>
+ </macrodef>
+
+ <implicit>
+ </implicit>
+ </target>
+
+ <target name="implicit.explicit">
+ <macrodef name="implicit">
+ <element name="explicit" optional="yes"/>
+ <element name="implicit" optional="yes" implicit="yes"/>
+ <sequential>
+ <implicit/>
+ <explicit/>
+ </sequential>
+ </macrodef>
+ </target>
+
+ <property name="default.override" value="old"/>
+ <macrodef name="simple.override">
+ <attribute name="attr" default="${default.override}"/>
+ <sequential>
+ <echo>value is @{attr}</echo>
+ </sequential>
+ </macrodef>
+
+ <target name="override.default">
+ <antcall target="override.call">
+ <param name="default.override" value="new"/>
+ </antcall>
+ </target>
+
+ <target name="override.call">
+ <simple.override/>
+ </target>
+
+ <target name="backtraceoff">
+ <macrodef name="nobacktrace" backtrace="false">
+ <sequential>
+ <fail>This is a failure</fail>
+ </sequential>
+ </macrodef>
+ <nobacktrace/>
+ </target>
+ <target name="backtraceon">
+ <macrodef name="nobacktrace" backtrace="true">
+ <sequential>
+ <fail>This is a failure</fail>
+ </sequential>
+ </macrodef>
+ <nobacktrace/>
+ </target>
+
+ <target name="top-level-text">
+ <macrodef name="top">
+ <element name="em"/>
+ <sequential>
+ <echo><em/></echo>
+ </sequential>
+ </macrodef>
+ <top>
+ <em>
+ Hello World
+ </em>
+ </top>
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/makeurl.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/makeurl.xml
new file mode 100644
index 00000000..dafd00a2
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/makeurl.xml
@@ -0,0 +1,79 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="to-url" >
+
+
+ <target name="testEmpty">
+ <makeurl/>
+ </target>
+
+ <target name="testNoProperty">
+ <makeurl file="foo"/>
+ </target>
+
+ <target name="testNoFile">
+ <makeurl property="foo"/>
+ </target>
+
+ <target name="testWorks">
+ <makeurl property="testWorks" file="foo" validate="false"/>
+ <fail unless="testWorks" />
+ </target>
+
+ <target name="testIllegalChars">
+ <makeurl property="testIllegalChars" file="fo o%" validate="false"/>
+ </target>
+
+ <target name="testRoundTrip">
+ <makeurl property="testRoundTrip" file="${ant.file}"/>
+ </target>
+
+ <target name="testIllegalCombinations">
+ <makeurl property="testIllegalCombinations" file="foo" validate="false">
+ <fileset dir="." includes="*.xml" />
+ </makeurl>
+ </target>
+
+
+ <target name="testFileset">
+ <makeurl property="testFileset">
+ <fileset dir="." includes="*.xml" />
+ </makeurl>
+ </target>
+
+ <target name="testFilesetSeparator">
+ <makeurl property="testFilesetSeparator" separator='","'>
+ <fileset dir="." includes="*.xml" />
+ </makeurl>
+ </target>
+
+ <target name="testValidation">
+ <makeurl property="testValidation" file="absent" validate="true"/>
+ </target>
+
+ <target name="testPath">
+ <path id="test.path">
+ <pathelement location="." />
+ <fileset dir="." includes="*.xml"/>
+ </path>
+ <makeurl property="testPath">
+ <path refid="test.path" />
+ </makeurl>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/manifest.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/manifest.xml
new file mode 100644
index 00000000..aecaf967
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/manifest.xml
@@ -0,0 +1,267 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<!-- Manifest tests build file -->
+<project name="manifest-test" basedir="." default="test1">
+ <import file="../buildfiletest-base.xml"/>
+
+ <target name="setUp">
+ <mkdir dir="${output}/manifests"/>
+ </target>
+
+ <target name="test1" depends="setUp">
+ <jar file="${output}/mftest1.jar" manifest="manifests/test1.mf"/>
+ <unjar src="${output}/mftest1.jar" dest="${output}/manifests">
+ <patternset>
+ <include name="META-INF/MANIFEST.MF"/>
+ </patternset>
+ </unjar>
+ </target>
+
+ <target name="test2" depends="setUp">
+ <jar file="${output}/mftest2.jar" manifest="manifests/test2.mf"/>
+ <unjar src="${output}/mftest2.jar" dest="${output}/manifests">
+ <patternset>
+ <include name="META-INF/MANIFEST.MF"/>
+ </patternset>
+ </unjar>
+ </target>
+
+ <target name="test3" depends="setUp">
+ <jar file="${output}/mftest3.jar" manifest="manifests/test3.mf"/>
+ </target>
+
+ <target name="test4" depends="setUp">
+ <jar file="${output}/mftest4.jar" manifest="manifests/test4.mf"/>
+ </target>
+
+ <target name="test5" depends="setUp">
+ <jar file="${output}/mftest5.jar" manifest="manifests/test5.mf"/>
+ </target>
+
+ <target name="test6" depends="setUp">
+ <jar file="${output}/mftest6.jar" manifest="manifests/test6.mf"/>
+ </target>
+
+ <target name="test7" depends="setUp">
+ <jar file="${output}/mftest7.jar" manifest="manifests/test7.mf"/>
+ </target>
+
+ <target name="test8" depends="setUp">
+ <jar file="${output}/mftest8.jar">
+ <manifest>
+ <attribute name="Class-Path" value="fubar"/>
+ <section name="Test">
+ <attribute name="TestAttr" value="Test"/>
+ </section>
+ </manifest>
+ </jar>
+ <unjar src="${output}/mftest8.jar" dest="${output}/manifests">
+ <patternset>
+ <include name="META-INF/MANIFEST.MF"/>
+ </patternset>
+ </unjar>
+ </target>
+
+ <target name="test9" depends="setUp">
+ <jar file="${output}/mftest9.jar">
+ <manifest>
+ <attribute name="Class-Path" value="fubar"/>
+ <section name="Test">
+ <attribute name="Name" value="Test"/>
+ </section>
+ </manifest>
+ </jar>
+ </target>
+
+ <target name="test10" depends="setUp">
+ <jar file="${output}/mftest10.jar">
+ <manifest>
+ <attribute value="fubar"/>
+ </manifest>
+ </jar>
+ </target>
+
+ <target name="test11" depends="setUp">
+ <jar file="${output}/mftest11.jar">
+ <manifest>
+ <attribute name="Test"/>
+ </manifest>
+ </jar>
+ </target>
+
+ <target name="test12" depends="setUp">
+ <jar file="${output}/mftest12.jar">
+ <manifest>
+ <section>
+ <attribute name="TestAttr" value="Test"/>
+ </section>
+ </manifest>
+ </jar>
+ </target>
+
+ <target name="test13" depends="setUp">
+ <jar file="${output}/mftest13.jar">
+ <manifest>
+ <attribute name="Test" value="Test1"/>
+ <attribute name="Test" value="Test2"/>
+ </manifest>
+ </jar>
+ </target>
+
+ <target name="test14" depends="setUp">
+ <jar file="${output}/mftest14.jar">
+ <manifest>
+ <attribute name="Class-path" value="Test1"/>
+ <attribute name="Class-path" value="Test2"/>
+ <attribute name="Class-Path" value="Test3"/>
+ <attribute name="class-Path" value="Test4"/>
+ </manifest>
+ </jar>
+ <unjar src="${output}/mftest14.jar" dest="${output}/manifests">
+ <patternset>
+ <include name="META-INF/MANIFEST.MF"/>
+ </patternset>
+ </unjar>
+ </target>
+
+ <target name="testNoFile">
+ <manifest />
+ </target>
+
+ <target name="testLongLine" depends="setUp">
+ <jar file="${output}/mftestLongLine.jar">
+ <manifest>
+ <attribute name="Class-path"
+ value="${test.longline}"/>
+ <attribute name="${test.long68name}" value="${test.value}" />
+ <attribute name="${test.long70name}" value="${test.value}" />
+ <attribute name="${test.notlongname}" value="${test.value}" />
+ </manifest>
+ </jar>
+ <unjar src="${output}/mftestLongLine.jar" dest="${output}/manifests">
+ <patternset>
+ <include name="META-INF/MANIFEST.MF"/>
+ </patternset>
+ </unjar>
+ </target>
+
+ <target name="testOrder1" depends="setUp">
+ <jar file="${output}/mftestOrder1.jar">
+ <manifest>
+ <section name="Test1">
+ <attribute name="TestAttr1" value="Test1"/>
+ <attribute name="TestAttr2" value="Test2"/>
+ </section>
+ <section name="Test2">
+ <attribute name="TestAttrx" value="Testx"/>
+ </section>
+ </manifest>
+ </jar>
+ <unjar src="${output}/mftestOrder1.jar" dest="${output}/manifests">
+ <patternset>
+ <include name="META-INF/MANIFEST.MF"/>
+ </patternset>
+ </unjar>
+ </target>
+
+ <target name="testOrder2" depends="setUp">
+ <jar file="${output}/mftestOrder2.jar">
+ <manifest>
+ <section name="Test2">
+ <attribute name="TestAttrx" value="Testx"/>
+ </section>
+ <section name="Test1">
+ <attribute name="TestAttr2" value="Test2"/>
+ <attribute name="TestAttr1" value="Test1"/>
+ </section>
+ </manifest>
+ </jar>
+ <unjar src="${output}/mftestOrder2.jar" dest="${output}/manifests">
+ <patternset>
+ <include name="META-INF/MANIFEST.MF"/>
+ </patternset>
+ </unjar>
+ </target>
+
+ <target name="testReplace" depends="setUp">
+ <copy file="manifests/test2.mf" toFile="${output}/mftest.mf" />
+ <manifest file="${output}/mftest.mf" />
+ </target>
+
+ <target name="testUpdate" depends="setUp">
+ <copy file="manifests/test2.mf" toFile="${output}/mftest.mf" />
+ <manifest file="${output}/mftest.mf" mode="update">
+ <attribute name="Foo" value="Bar" />
+ </manifest>
+
+ <copy file="manifests/test2.mf" toFile="${output}/mftest2.mf" />
+ <manifest file="${output}/mftest2.mf" mode="update">
+ <section name="Test">
+ <attribute name="Foo" value="Bar" />
+ </section>
+ </manifest>
+ <manifest file="${output}/mftest2.mf" mode="update">
+ <section name="Test">
+ <attribute name="Foo" value="Baz" />
+ </section>
+ </manifest>
+ </target>
+
+ <target name="testFrom" depends="setUp">
+ <manifest file="${output}/mftestfrom.mf" >
+ <section name="Test">
+ <attribute name="before" value="before" />
+ <attribute name="From" value="illegal"/>
+ <attribute name="after" value="after" />
+ </section>
+ </manifest>
+ </target>
+
+ <target name="testIllegalName" depends="setUp">
+ <manifest file="${output}/mftestillegalname.mf">
+ <attribute name="has blank" value="value"/>
+ </manifest>
+ </target>
+
+ <target name="testIllegalNameInSection" depends="setUp">
+ <manifest file="${output}/mftestillegalnameinsection.mf">
+ <section name="s1">
+ <attribute name="has blank" value="value"/>
+ </section>
+ </manifest>
+ </target>
+
+ <target name="testIllegalNameBegin" depends="setUp">
+ <manifest file="${output}/mftestillegalnamebegin.mf">
+ <attribute name="-name" value="value"/>
+ </manifest>
+ </target>
+
+ <target name="testIllegalName2" depends="setUp">
+ <manifest file="${output}/mftestillegalnamebegin.mf">
+ <attribute name="has.point" value="value"/>
+ </manifest>
+ </target>
+
+ <target name="testIllegalName3" depends="setUp">
+ <manifest file="${output}/mftestillegalnamebegin.mf">
+ <attribute name="has*star" value="value"/>
+ </manifest>
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/manifestclasspath.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/manifestclasspath.xml
new file mode 100644
index 00000000..f8a47951
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/manifestclasspath.xml
@@ -0,0 +1,238 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<project name="manifestclasspath" default="tearDown">
+
+ <import file="../buildfiletest-base.xml"/>
+
+ <target name="setUp">
+ <mkdir dir="${output}" />
+ </target>
+
+ <!-- hebrew -->
+ <property name="jom" value="&#1501;&#1493;&#1497;"/>
+ <!-- german -->
+ <property name="aent" value="&#227;nt"/>
+ <target name="fullSetUp" depends="setUp">
+ <mkdir dir="${output}/lib" />
+ <touch file="${output}/lib/acme-core.jar" />
+ <touch file="${output}/lib/acme-pres.jar" />
+
+ <mkdir dir="${output}/classes/dsp-core/com/lgc/infra/core" />
+ <mkdir dir="${output}/classes/dsp-pres/com/lgc/infra/pres" />
+ <mkdir dir="${output}/classes/dsp-void" />
+ <mkdir dir="${output}/generated/dsp-core/com/lgc/infra/core/generated" />
+ <mkdir dir="${output}/generated/dsp-pres" />
+ <mkdir dir="${output}/generated/dsp-void" />
+ <mkdir dir="${output}/resources/dsp-core/com/lgc/infra/core" />
+ <mkdir dir="${output}/resources/dsp-pres/com/lgc/infra/pres" />
+ <mkdir dir="${output}/resources/dsp-void" />
+ </target>
+
+ <target name="test-bad-directory">
+ <manifestclasspath property="jar.classpath"
+ jarfile="${output}/classpath.jar">
+ <classpath />
+ </manifestclasspath>
+ </target>
+
+ <target name="test-bad-no-property" depends="setUp">
+ <manifestclasspath jarfile="${output}/classpath.jar">
+ <classpath />
+ </manifestclasspath>
+ </target>
+
+ <target name="test-bad-property-exists" depends="setUp">
+ <property name="jar.classpath" value="exists" />
+ <manifestclasspath property="jar.classpath"
+ jarfile="${output}/classpath.jar">
+ <classpath />
+ </manifestclasspath>
+ </target>
+
+ <target name="test-bad-no-jarfile" depends="setUp">
+ <manifestclasspath property="jar.classpath">
+ <classpath />
+ </manifestclasspath>
+ </target>
+
+ <target name="test-bad-no-classpath" depends="setUp">
+ <manifestclasspath property="jar.classpath"
+ jarfile="${output}/classpath.jar" />
+ </target>
+
+ <target name="test-pseudo-tahoe-refid" depends="fullSetUp">
+ <path id="classpath">
+ <!-- All the classes/ directories -->
+ <dirset dir="${output}/classes" includes="dsp-*" />
+
+ <!-- All the JAXB generated/ directories -->
+ <dirset dir="${output}/generated" includes="dsp-*">
+ <!-- Add only non-empty directories to the classpath -->
+ <present targetdir="${output}/generated" present="both">
+ <mapper type="regexp" from="(.*)" to="\1/com" />
+ </present>
+ </dirset>
+
+ <!-- All the resources/ directories -->
+ <dirset dir="${output}/resources" includes="dsp-*">
+ <!-- Add only non-empty directories to the classpath -->
+ <present targetdir="${output}/resources" present="both">
+ <mapper type="regexp" from="(.*)" to="\1/com" />
+ </present>
+ </dirset>
+ </path>
+
+ <manifestclasspath property="jar.classpath"
+ jarfile="${output}/classpath.jar">
+ <classpath refid="classpath" />
+ </manifestclasspath>
+ </target>
+
+ <target name="test-pseudo-tahoe-nested" depends="fullSetUp">
+ <manifestclasspath property="jar.classpath"
+ jarfile="${output}/classpath.jar">
+ <classpath>
+ <!-- All the classes/ directories -->
+ <dirset dir="${output}/classes" includes="dsp-*" />
+
+ <!-- All the JAXB generated/ directories -->
+ <dirset dir="${output}/generated" includes="dsp-*">
+ <!-- Add only non-empty directories to the classpath -->
+ <present targetdir="${output}/generated" present="both">
+ <mapper type="regexp" from="(.*)" to="\1/com" />
+ </present>
+ </dirset>
+
+ <!-- All the resources/ directories -->
+ <dirset dir="${output}/resources" includes="dsp-*">
+ <!-- Add only non-empty directories to the classpath -->
+ <present targetdir="${output}/resources" present="both">
+ <mapper type="regexp" from="(.*)" to="\1/com" />
+ </present>
+ </dirset>
+ </classpath>
+ </manifestclasspath>
+ </target>
+
+ <target name="test-parent-level1" depends="fullSetUp">
+ <manifestclasspath property="jar.classpath"
+ jarfile="${output}/classes/classpath.jar">
+ <classpath>
+ <dirset dir="${output}/classes" includes="dsp-*" />
+ <dirset dir="${output}/generated" includes="dsp-*" />
+ <dirset dir="${output}/resources" includes="dsp-*" />
+ </classpath>
+ </manifestclasspath>
+ </target>
+
+ <target name="test-parent-level2" depends="fullSetUp">
+ <mkdir dir="${output}/classes/level2" />
+ <manifestclasspath property="jar.classpath"
+ jarfile="${output}/classes/level2/classpath.jar">
+ <classpath>
+ <dirset dir="${output}/classes" includes="dsp-*" />
+ <dirset dir="${output}/generated" includes="dsp-*" />
+ <dirset dir="${output}/resources" includes="dsp-*" />
+ </classpath>
+ </manifestclasspath>
+ </target>
+
+ <target name="test-parent-level2-too-deep" depends="fullSetUp">
+ <mkdir dir="${output}/classes/level2" />
+ <manifestclasspath property="jar.classpath" maxParentLevels="1"
+ jarfile="${output}/classes/level2/classpath.jar">
+ <classpath>
+ <dirset dir="${output}/classes" includes="dsp-*" />
+ <dirset dir="${output}/generated" includes="dsp-*" />
+ <dirset dir="${output}/resources" includes="dsp-*" />
+ </classpath>
+ </manifestclasspath>
+ </target>
+
+ <target name="test-parent-level2-with-jars" depends="fullSetUp">
+ <mkdir dir="${output}/classes/level2" />
+ <manifestclasspath property="jar.classpath"
+ jarfile="${output}/classes/level2/classpath.jar">
+ <classpath>
+ <fileset dir="${output}/lib" includes="*.jar" />
+ <dirset dir="${output}/classes" includes="dsp-*" />
+ <dirset dir="${output}/generated" includes="dsp-*" />
+ <dirset dir="${output}/resources" includes="dsp-*" />
+ </classpath>
+ </manifestclasspath>
+ </target>
+
+ <target name="international-german" depends="setUp">
+ <antcall target="run-two-jars">
+ <param name="ext.dir" value="${aent}"/>
+ </antcall>
+ </target>
+ <target name="international-hebrew" depends="setUp">
+ <antcall target="run-two-jars">
+ <param name="ext.dir" value="${jom}"/>
+ </antcall>
+ </target>
+ <target name="run-two-jars">
+ <mkdir dir="${output}/${ext.dir}"/>
+ <javac srcdir="manifestclasspath" destdir="${output}" />
+ <jar destfile="${output}/${ext.dir}/alpha.jar">
+ <fileset dir="${output}">
+ <include name="Alpha.class"/>
+ </fileset>
+ </jar>
+ <manifestclasspath property="jar.classpath"
+ jarfile="${output}/beta.jar">
+ <classpath>
+ <pathelement location="${output}/beta.jar"/>
+ <pathelement location="${output}/${ext.dir}/alpha.jar"/>
+ </classpath>
+ </manifestclasspath>
+ <jar destfile="${output}/beta.jar" >
+ <fileset dir="${output}">
+ <include name="Beta.class"/>
+ </fileset>
+ <manifest>
+ <attribute name="Main-Class" value="Beta"/>
+ <attribute name="Class-Path" value="${jar.classpath}"/>
+ </manifest>
+ </jar>
+ <java fork="true" jar="${output}/beta.jar"/>
+ </target>
+
+ <target name="testSameDrive">
+ <property name="temp" location="${java.io.tmpdir}"/>
+ <manifestclasspath jarfile="${temp}\e.jar"
+ maxParentLevels="99" property="cp">
+ <classpath>
+ <pathelement location="${temp}\..\a\b\x.jar"/>
+ </classpath>
+ </manifestclasspath>
+ </target>
+
+ <target name="testDifferentDrive">
+ <property name="temp" location="${java.io.tmpdir}"/>
+ <!-- the property altDriveLetter gets defined in Java -->
+ <manifestclasspath jarfile="${temp}\e.jar"
+ maxParentLevels="99" property="cp">
+ <classpath>
+ <pathelement location="${altDriveLetter}:\a\b\x.jar"/>
+ </classpath>
+ </manifestclasspath>
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/manifestclasspath/Alpha.java b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/manifestclasspath/Alpha.java
new file mode 100644
index 00000000..96124d54
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/manifestclasspath/Alpha.java
@@ -0,0 +1,21 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+public class Alpha {
+ public String toString() {
+ return "alpha";
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/manifestclasspath/Beta.java b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/manifestclasspath/Beta.java
new file mode 100644
index 00000000..c1b446f1
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/manifestclasspath/Beta.java
@@ -0,0 +1,25 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+public class Beta extends Alpha {
+ public String toString() {
+ return "beta " + super.toString();
+ }
+ public static void main(String [] args) {
+ Beta myBeta = new Beta();
+ System.out.println(myBeta.toString());
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/manifests/test1.mf b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/manifests/test1.mf
new file mode 100644
index 00000000..8b137891
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/manifests/test1.mf
@@ -0,0 +1 @@
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/manifests/test2.mf b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/manifests/test2.mf
new file mode 100644
index 00000000..b8a88bd3
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/manifests/test2.mf
@@ -0,0 +1,2 @@
+Manifest-Version: 2.0
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/manifests/test3.mf b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/manifests/test3.mf
new file mode 100644
index 00000000..6aa82cca
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/manifests/test3.mf
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Header-without-colon maybe mistyped
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/manifests/test4.mf b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/manifests/test4.mf
new file mode 100644
index 00000000..27afb189
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/manifests/test4.mf
@@ -0,0 +1,4 @@
+Manifest-Version: 1.0
+
+ Can't start with a continuation line
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/manifests/test5.mf b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/manifests/test5.mf
new file mode 100644
index 00000000..0fb8deae
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/manifests/test5.mf
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Name: test5
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/manifests/test6.mf b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/manifests/test6.mf
new file mode 100644
index 00000000..97988c69
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/manifests/test6.mf
@@ -0,0 +1,5 @@
+Manifest-Version: 1.0
+
+Test: test6
+Class-Path: fubar
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/manifests/test7.mf b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/manifests/test7.mf
new file mode 100644
index 00000000..72aace0b
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/manifests/test7.mf
@@ -0,0 +1,4 @@
+Manifest-Version: 1.0
+Class-Path: fubar
+From: Jack
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/mkdir.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/mkdir.xml
new file mode 100644
index 00000000..1ecc274d
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/mkdir.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<project name="xxx-test" basedir="." default="test1">
+
+ <import file="../buildfiletest-base.xml"/>
+
+ <target name="setUp">
+ <mkdir dir="${output}" />
+ </target>
+
+ <target name="test1">
+ <mkdir/>
+ </target>
+
+ <target name="test2">
+ <mkdir dir="template.xml"/>
+ </target>
+
+ <target name="test3">
+ <mkdir dir="${output}/testdir.tmp"/>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/move.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/move.xml
new file mode 100644
index 00000000..8b4a6c8e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/move.xml
@@ -0,0 +1,263 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<project name="move-test" basedir="." default="testFilterSet">
+
+ <import file="../buildfiletest-base.xml"/>
+
+ <target name="setUp">
+ <mkdir dir="${output}" />
+ </target>
+
+ <target name="testFilterSet">
+ <copy file="copy.filterset" tofile="${output}/move.filterset"/>
+ <move file="${output}/move.filterset" tofile="${output}/move.filterset.tmp">
+ <filterset>
+ <filter token="TITLE" value="Apache Ant Project"/>
+ </filterset>
+ </move>
+ </target>
+
+ <target name="testFilterChain">
+ <copy file="copy.filterset" tofile="${output}/move.filterchain"/>
+ <move file="${output}/move.filterchain" tofile="${output}/move.filterchain.tmp">
+ <filterchain>
+ <replacetokens>
+ <token key="TITLE" value="Apache Ant Project"/>
+ </replacetokens>
+ </filterchain>
+ </move>
+ </target>
+
+ <!-- Bugzilla Report 11732 -->
+ <target name="testDirectoryRemoval">
+ <mkdir dir="${output}/A/B"/>
+ <mkdir dir="${output}/A/C"/>
+ <mkdir dir="${output}/A/D"/>
+ <touch file="${output}/A/B/1"/>
+ <touch file="${output}/A/C/2"/>
+ <touch file="${output}/A/D/3"/>
+ <mkdir dir="${output}/E"/>
+ <move todir="${output}/E" includeemptydirs="true">
+ <fileset dir="${output}/A">
+ <include name="C"/>
+ <include name="D"/>
+ <include name="C/**"/>
+ <include name="D/**"/>
+ </fileset>
+ </move>
+ </target>
+
+ <!-- Bugzilla Report 18886 -->
+ <target name="testDirectoryRetaining">
+ <mkdir dir="${output}/A"/>
+ <touch file="${output}/A/1"/>
+ <mkdir dir="${output}/E"/>
+ <move todir="${output}/E" includeemptydirs="true">
+ <fileset dir="${output}/A" includes="1"/>
+ </move>
+ </target>
+
+ <target name="testCompleteDirectoryMove">
+ <mkdir dir="${output}/A"/>
+ <touch file="${output}/A/1"/>
+ <move todir="${output}/E">
+ <fileset dir="${output}/A"/>
+ </move>
+ </target>
+
+ <target name="testCompleteDirectoryMove2">
+ <mkdir dir="${output}/A"/>
+ <touch file="${output}/A/1"/>
+ <move todir="${output}/E">
+ <path>
+ <fileset dir="${output}/A"/>
+ </path>
+ </move>
+ </target>
+
+ <target name="testPathElementMove">
+ <mkdir dir="${output}/A"/>
+ <touch file="${output}/A/1"/>
+ <move todir="${output}/E" flatten="true">
+ <path>
+ <pathelement location="${output}/A/1"/>
+ </path>
+ </move>
+ </target>
+
+ <target name="testMoveFileAndFileset">
+ <mkdir dir="${output}/A" />
+ <touch>
+ <filelist dir="${output}/A" files="1,2,3" />
+ </touch>
+ <move todir="${output}/E" file="${output}/A/1">
+ <fileset dir="${output}/A" includes="2,3" />
+ </move>
+ <fail message="A unavailable">
+ <condition>
+ <not>
+ <available file="${output}/A" type="dir" />
+ </not>
+ </condition>
+ </fail>
+ <fail message="${output}/A/1 not moved">
+ <condition>
+ <or>
+ <available file="${output}/A/1" type="file" />
+ <not>
+ <available file="${output}/E/1" type="file" />
+ </not>
+ </or>
+ </condition>
+ </fail>
+ <fail message="${output}/A/2 not moved">
+ <condition>
+ <or>
+ <available file="${output}/A/2" type="file" />
+ <not>
+ <available file="${output}/E/2" type="file" />
+ </not>
+ </or>
+ </condition>
+ </fail>
+ <fail message="${output}/A/3 not moved">
+ <condition>
+ <or>
+ <available file="${output}/A/3" type="file" />
+ <not>
+ <available file="${output}/E/3" type="file" />
+ </not>
+ </or>
+ </condition>
+ </fail>
+ </target>
+
+ <macrodef name="verifymove">
+ <attribute name="newfile" />
+ <attribute name="olddir" />
+ <sequential>
+ <fail message="@{newfile} not available">
+ <condition>
+ <not>
+ <available file="@{newfile}" type="file" />
+ </not>
+ </condition>
+ </fail>
+ <fail message="@{olddir} remains">
+ <condition>
+ <available file="@{olddir}" type="dir" />
+ </condition>
+ </fail>
+ </sequential>
+ </macrodef>
+
+ <target name="testCompleteDirectoryMoveToExistingDir">
+ <mkdir dir="${output}/A" />
+ <touch file="${output}/A/1" />
+ <mkdir dir="${output}/E" />
+ <touch file="${output}/E/2" />
+ <move todir="${output}/E">
+ <fileset dir="${output}/A" />
+ </move>
+ <verifymove newfile="${output}/E/1" olddir="${output}/A" />
+ <fail message="E/2 unavailable">
+ <condition>
+ <not>
+ <available file="${output}/E/2" type="file" />
+ </not>
+ </condition>
+ </fail>
+ </target>
+
+ <target name="testCompleteDirectoryMoveFileToFile">
+ <mkdir dir="${output}/A"/>
+ <touch file="${output}/A/1"/>
+ <move file="${output}/A" tofile="${output}/E" />
+ <verifymove newfile="${output}/E/1" olddir="${output}/A" />
+ </target>
+
+ <target name="testCompleteDirectoryMoveFileToDir">
+ <mkdir dir="${output}/A"/>
+ <touch file="${output}/A/1"/>
+ <move file="${output}/A" todir="${output}/E" />
+ <verifymove newfile="${output}/E/A/1" olddir="${output}/A" />
+ </target>
+
+ <target name="testCompleteDirectoryMoveFileAndFileset">
+ <mkdir dir="${output}/A/1" />
+ <touch file="${output}/A/2" />
+ <move file="${output}/A/1" todir="${output}/E">
+ <fileset dir="${output}/A" includes="2" />
+ </move>
+ <fail message="A unavailable">
+ <condition>
+ <not>
+ <available file="${output}/A" type="dir" />
+ </not>
+ </condition>
+ </fail>
+ <fail message="E/1 unavailable">
+ <condition>
+ <not>
+ <available file="${output}/E/1" type="dir" />
+ </not>
+ </condition>
+ </fail>
+ <fail message="E/2 unavailable">
+ <condition>
+ <not>
+ <available file="${output}/E/2" type="file" />
+ </not>
+ </condition>
+ </fail>
+ </target>
+
+ <target name="testCompleteDirectoryMoveFileToExistingFile">
+ <mkdir dir="${output}/A"/>
+ <touch file="${output}/A/1"/>
+ <touch file="${output}/E"/>
+ <move file="${output}/A" tofile="${output}/E" />
+ </target>
+
+ <target name="testCompleteDirectoryMoveFileToExistingDir">
+ <mkdir dir="${output}/A"/>
+ <touch file="${output}/A/1"/>
+ <mkdir dir="${output}/E"/>
+ <move file="${output}/A" tofile="${output}/E" />
+ <verifymove newfile="${output}/E/1" olddir="${output}/A" />
+ </target>
+
+ <target name="testCompleteDirectoryMoveFileToDirWithExistingFile">
+ <mkdir dir="${output}/A"/>
+ <touch file="${output}/A/1"/>
+ <mkdir dir="${output}/E"/>
+ <touch file="${output}/E/A"/>
+ <move file="${output}/A" todir="${output}/E" />
+ </target>
+
+ <target name="testCompleteDirectoryMoveFileToDirWithExistingDir">
+ <mkdir dir="${output}/A"/>
+ <touch file="${output}/A/1"/>
+ <mkdir dir="${output}/E"/>
+ <mkdir dir="${output}/E/A"/>
+ <move file="${output}/A" todir="${output}/E" />
+ <verifymove newfile="${output}/E/A/1" olddir="${output}/A" />
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/multimap.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/multimap.xml
new file mode 100644
index 00000000..ce4b1218
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/multimap.xml
@@ -0,0 +1,192 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="test" basedir=".">
+
+ <import file="../buildfiletest-base.xml"/>
+
+ <path id="testclasses">
+ <pathelement location="../../../../build/testcases" />
+ <pathelement path="${java.class.path}" />
+ </path>
+
+ <mapper id="testmapper"
+ classname="org.apache.tools.ant.taskdefs.MultiMapTest$TestMapper"
+ classpathref="testclasses"/>
+
+ <property name="map.ext" value=".copy2"/>
+ <property name="rootScratchDir" value="${output}/test_multi_mapper_scratch_area"/>
+ <property name="baseScratchSrc" value="${rootScratchDir}/src"/>
+ <property name="baseScratchDest" value="${rootScratchDir}/dest"/>
+
+ <target name="setUp">
+ <delete dir="${baseScratchSrc}"/>
+ <mkdir dir="${baseScratchSrc}"/>
+ <delete dir="${baseScratchDest}"/>
+ <mkdir dir="${baseScratchDest}"/>
+ <touch file="${baseScratchSrc}/somefile.txt"/>
+ </target>
+
+ <!-- test simple single file to multiple file move -->
+ <target name="multicopy" depends="setUp">
+ <copy todir="${baseScratchDest}" enablemultiplemappings="true">
+ <fileset dir="${baseScratchSrc}" includes="somefile.txt"/>
+ <mapper refid="testmapper"/>
+ </copy>
+ <condition property="multicopy.outcome">
+ <and>
+ <available file="${baseScratchDest}/somefile.txt"/>
+ <available file="${baseScratchDest}/somefile.txt${map.ext}"/>
+ </and>
+ </condition>
+ <fail unless="multicopy.outcome">multicopy failed</fail>
+ </target>
+
+ <target name="multimove" depends="setUp">
+ <move todir="${baseScratchDest}" enablemultiplemappings="true">
+ <fileset dir="${baseScratchSrc}" includes="somefile.txt"/>
+ <mapper refid="testmapper"/>
+ </move>
+ <condition property="test2.outcome">
+ <and>
+ <available file="${baseScratchDest}/somefile.txt"/>
+ <available file="${baseScratchDest}/somefile.txt${map.ext}"/>
+ <not>
+ <available file="${baseScratchSrc}/somefile.txt"/>
+ </not>
+ <not>
+ <available file="${baseScratchSrc}/somefile.txt${map.ext}"/>
+ </not>
+ </and>
+ </condition>
+ <fail unless="test2.outcome">mulitmove failed</fail>
+ </target>
+
+ <!--
+ test traditional single file to single file copy explicitly telling
+ task to ignore multiple mappings
+ -->
+
+ <target name="singlecopy" depends="setUp">
+ <copy todir="${baseScratchDest}" enablemultiplemappings="false">
+ <fileset dir="${baseScratchSrc}" includes="somefile.txt"/>
+ <mapper refid="testmapper"/>
+ </copy>
+ <condition property="singlecopy.outcome">
+ <and>
+ <available file="${baseScratchDest}/somefile.txt"/>
+ <not>
+ <available file="${baseScratchDest}/somefile.txt${map.ext}"/>
+ </not>
+ <available file="${baseScratchSrc}/somefile.txt"/>
+ </and>
+ </condition>
+ <fail unless="singlecopy.outcome">singlecopy failed</fail>
+ </target>
+
+ <target name="singlemove" depends="setUp">
+ <move todir="${baseScratchDest}" enablemultiplemappings="false">
+ <fileset dir="${baseScratchSrc}" includes="somefile.txt"/>
+ <mapper refid="testmapper"/>
+ </move>
+ <condition property="singlemove.outcome">
+ <and>
+ <available file="${baseScratchDest}/somefile.txt"/>
+ <not>
+ <available file="${baseScratchDest}/somefile.txt${map.ext}"/>
+ </not>
+ <not>
+ <available file="${baseScratchSrc}/somefile.txt"/>
+ </not>
+ </and>
+ </condition>
+ <fail unless="singlemove.outcome">singlemove failed</fail>
+ </target>
+
+ <!-- test dir w/ file + empty dir multimap copy -->
+ <target name="copywithempty">
+ <delete dir="${baseScratchSrc}"/>
+ <mkdir dir="${baseScratchSrc}/dirwithfile"/>
+ <mkdir dir="${baseScratchSrc}/emptydir"/>
+ <touch file="${baseScratchSrc}/dirwithfile/somefile.txt"/>
+
+ <delete dir="${baseScratchDest}"/>
+ <mkdir dir="${baseScratchDest}"/>
+
+ <copy todir="${baseScratchDest}" enablemultiplemappings="true">
+ <fileset dir="${baseScratchSrc}" includes="**/*"/>
+ <mapper refid="testmapper"/>
+ </copy>
+ <condition property="copywithempty.outcome">
+ <and>
+ <available file="${baseScratchDest}/dirwithfile"/>
+ <available file="${baseScratchDest}/dirwithfile${map.ext}"/>
+ <available file="${baseScratchDest}/dirwithfile/somefile.txt"/>
+ <available file="${baseScratchDest}/dirwithfile/somefile.txt${map.ext}"/>
+ <not>
+ <available file="${baseScratchDest}/dirwithfile${map.ext}/somefile.txt"/>
+ </not>
+ <not>
+ <available file="${baseScratchDest}/dirwithfile${map.ext}/somefile.txt${map.ext}"/>
+ </not>
+ <available file="${baseScratchDest}/emptydir"/>
+ <available file="${baseScratchDest}/emptydir${map.ext}"/>
+ </and>
+ </condition>
+ <fail unless="copywithempty.outcome">copywithempty failed</fail>
+ </target>
+ <!-- test dir w/ file + empty dir multimap move -->
+ <target name="movewithempty">
+ <delete dir="${baseScratchSrc}"/>
+ <mkdir dir="${baseScratchSrc}/dirwithfile"/>
+ <mkdir dir="${baseScratchSrc}/emptydir"/>
+ <touch file="${baseScratchSrc}/dirwithfile/somefile.txt"/>
+
+ <delete dir="${baseScratchDest}"/>
+ <mkdir dir="${baseScratchDest}"/>
+
+ <move todir="${baseScratchDest}" enablemultiplemappings="true">
+ <fileset dir="${baseScratchSrc}" includes="**/*"/>
+ <mapper refid="testmapper"/>
+ </move>
+ <condition property="movewithempty.outcome">
+ <and>
+ <available file="${baseScratchDest}/dirwithfile"/>
+ <available file="${baseScratchDest}/dirwithfile${map.ext}"/>
+ <available file="${baseScratchDest}/dirwithfile/somefile.txt"/>
+ <available file="${baseScratchDest}/dirwithfile/somefile.txt${map.ext}"/>
+ <not>
+ <available file="${baseScratchDest}/dirwithfile${map.ext}/somefile.txt"/>
+ </not>
+ <not>
+ <available file="${baseScratchDest}/dirwithfile${map.ext}/somefile.txt${map.ext}"/>
+ </not>
+ <available file="${baseScratchDest}/emptydir"/>
+ <available file="${baseScratchDest}/emptydir${map.ext}"/>
+ <not>
+ <available file="${baseScratchSrc}/dirwithfile"/>
+ </not>
+ <not>
+ <available file="${baseScratchSrc}/emptydir"/>
+ </not>
+ </and>
+ </condition>
+ <fail unless="movewithempty.outcome">movewithempty failed</fail>
+ </target>
+
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/nice.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/nice.xml
new file mode 100644
index 00000000..e67ee19c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/nice.xml
@@ -0,0 +1,66 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="nice" basedir=".">
+
+<description>
+Test nicing. To make the test more complex we may be running in a nice mode
+to start with, and we want to restore that value at the end. So every test
+that succeeds must restore the saved value.
+</description>
+ <target name="noop">
+ <nice/>
+ </target>
+
+ <target name="current">
+ <nice currentPriority="nice.now"/>
+ <fail unless="nice.now"/>
+ </target>
+
+ <target name="faster">
+ <nice newPriority="8" currentPriority="nice.old"/>
+ <nice currentPriority="nice.now"/>
+ <condition property="test.succeeded">
+ <equals arg1="${nice.now}" arg2="8" />
+ </condition>
+ <nice newPriority="${nice.old}"/>
+ <fail unless="test.succeeded"/>
+ </target>
+
+ <target name="slower">
+ <nice newPriority="3" currentPriority="nice.old"/>
+ <nice currentPriority="nice.now"/>
+ <condition property="test.succeeded">
+ <equals arg1="${nice.now}" arg2="3" />
+ </condition>
+ <nice newPriority="${nice.old}"/>
+ <fail unless="test.succeeded"/>
+ </target>
+
+ <target name="too_slow">
+ <nice currentPriority="nice.old"/>
+ <nice newPriority="0"/>
+ <nice newPriority="${nice.old}"/>
+ </target>
+
+ <target name="too_fast">
+ <nice currentPriority="nice.old"/>
+ <nice newPriority="20"/>
+ <nice newPriority="${nice.old}"/>
+ </target>
+
+</project> \ No newline at end of file
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/nopermissions.zip b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/nopermissions.zip
new file mode 100644
index 00000000..979ee68b
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/nopermissions.zip
Binary files differ
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/antlr/antlr.g b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/antlr/antlr.g
new file mode 100644
index 00000000..9f724936
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/antlr/antlr.g
@@ -0,0 +1,76 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+class CalcParser extends Parser;
+options {
+ buildAST = true; // uses CommonAST by default
+}
+
+expr
+ : mexpr (PLUS^ mexpr)* SEMI!
+ ;
+
+mexpr
+ : atom (STAR^ atom)*
+ ;
+
+atom: INT
+ ;
+
+class CalcLexer extends Lexer;
+
+WS : (' '
+ | '\t'
+ | '\n'
+ | '\r')
+ { _ttype = Token.SKIP; }
+ ;
+
+LPAREN: '('
+ ;
+
+RPAREN: ')'
+ ;
+
+STAR: '*'
+ ;
+
+PLUS: '+'
+ ;
+
+SEMI: ';'
+ ;
+
+protected
+DIGIT
+ : '0'..'9'
+ ;
+
+INT : (DIGIT)+
+ ;
+
+class CalcTreeWalker extends TreeParser;
+
+expr returns [float r]
+{
+ float a,b;
+ r=0;
+}
+ : #(PLUS a=expr b=expr) {r = a+b;}
+ | #(STAR a=expr b=expr) {r = a*b;}
+ | i:INT {r = (float)Integer.parseInt(i.getText());}
+ ;
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/antlr/antlr.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/antlr/antlr.xml
new file mode 100644
index 00000000..c136d061
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/antlr/antlr.xml
@@ -0,0 +1,128 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<project name="antlr-test" basedir="." default="test1">
+
+ <import file="../../../buildfiletest-base.xml"/>
+
+ <target name="setUp">
+ <mkdir dir="${output}" />
+ </target>
+
+ <target name="test1">
+ <antlr/>
+ </target>
+
+ <target name="test2">
+ <antlr target="antlr.g" outputdirectory="${output}"/>
+ </target>
+
+ <target name="test3" depends="setUp">
+ <antlr target="antlr.g" outputdirectory="${output}"/>
+ <fail>
+ <condition>
+ <!-- to prove each of these files exists;
+ ANTLR >= 2.7.6 leaves behind new (.smap) files as well. -->
+ <resourcecount when="ne" count="5">
+ <fileset dir="${output}">
+ <include name="CalcParserTokenTypes.txt" />
+ <include name="CalcParserTokenTypes.java" />
+ <include name="CalcLexer.java" />
+ <include name="CalcParser.java" />
+ <include name="CalcTreeWalker.java" />
+ </fileset>
+ </resourcecount>
+ </condition>
+ </fail>
+ </target>
+
+ <target name="test4" depends="setUp">
+ <antlr target="java.g" outputdirectory="${output}"/>
+ <antlr dir="${output}" target="java.tree.g" outputdirectory="${output}"/>
+ </target>
+
+ <target name="test5" depends="setUp">
+ <antlr target="java.tree.g" outputdirectory="${output}" fork="yes"/>
+ </target>
+
+ <target name="test6" depends="setUp">
+ <antlr target="java.g" outputdirectory="${output}" />
+ <antlr dir="${output}"
+ target="java.tree.g"
+ outputdirectory="${output}"
+ fork="yes"/>
+ </target>
+
+ <target name="test7">
+ <antlr target="antlr.xml"/>
+ </target>
+
+ <target name="test8" depends="setUp">
+ <antlr target="extended.calc.g" outputdirectory="${output}" glib="non-existent-file.g"/>
+ </target>
+
+ <target name="test9" depends="setUp">
+ <!-- Note that I had to copy the grammars over to the temporary directory. -->
+ <!-- This is because ANTLR expects the super grammar and its generated java -->
+ <!-- files to be in the same directory, which won't be the case if I use -->
+ <!-- the output directory option. -->
+ <copy file="antlr.g" todir="${output}"/>
+ <copy file="extended.calc.g" todir="${output}"/>
+ <antlr target="${output}/antlr.g"/>
+ <antlr target="${output}/extended.calc.g" glib="${output}/antlr.g"/>
+ </target>
+
+ <target name="test10" depends="setUp">
+ <antlr target="antlr.g" outputdirectory="${output}" html="yes"/>
+ </target>
+
+ <target name="test11" depends="setUp">
+ <antlr target="antlr.g" outputdirectory="${output}" diagnostic="yes"/>
+ </target>
+
+ <target name="test12" depends="setUp">
+ <antlr target="antlr.g" outputdirectory="${output}" trace="yes"/>
+ </target>
+
+ <target name="test13" depends="setUp">
+ <antlr target="antlr.g" outputdirectory="${output}" traceLexer="yes" traceParser="yes" traceTreeWalker="yes"/>
+ </target>
+
+ <!-- test9 will have been run before that -->
+ <target name="noRecompile">
+ <antlr target="${output}/extended.calc.g" glib="${output}/antlr.g"/>
+ </target>
+
+ <!-- test9 will have been run before that -->
+ <target name="normalRecompile">
+ <touch file="${output}/extended.calc.g"/>
+ <antlr target="${output}/extended.calc.g" glib="${output}/antlr.g"/>
+ </target>
+
+ <!-- test9 will have been run before that -->
+ <target name="supergrammarChangeRecompile">
+ <touch file="${output}/antlr.g"/>
+ <antlr target="${output}/extended.calc.g" glib="${output}/antlr.g"/>
+ </target>
+
+ <target name="tearDown">
+ <delete dir="${output}" />
+ <delete file="../../../../../../CalcParserTokenTypes.txt"/>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/antlr/extended.calc.g b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/antlr/extended.calc.g
new file mode 100644
index 00000000..00c1993f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/antlr/extended.calc.g
@@ -0,0 +1,23 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+// Not really a great extension, but it is only a test after all!
+
+class ExtendedCalcParser extends CalcParser;
+
+exprList
+ : LPAREN (expr)* RPAREN
+ ;
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/antlr/java.g b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/antlr/java.g
new file mode 100644
index 00000000..e5857502
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/antlr/java.g
@@ -0,0 +1,1162 @@
+/** Java 1.2 Recognizer
+ *
+ * Run 'java Main <directory full of java files>'
+ *
+ * Contributing authors:
+ * John Mitchell johnm@non.net
+ * Terence Parr parrt@magelang.com
+ * John Lilley jlilley@empathy.com
+ * Scott Stanchfield thetick@magelang.com
+ * Markus Mohnen mohnen@informatik.rwth-aachen.de
+ * Peter Williams pwilliams@netdynamics.com
+ *
+ * Version 1.00 December 9, 1997 -- initial release
+ * Version 1.01 December 10, 1997
+ * fixed bug in octal def (0..7 not 0..8)
+ * Version 1.10 August 1998 (parrt)
+ * added tree construction
+ * fixed definition of WS,comments for mac,pc,unix newlines
+ * added unary plus
+ * Version 1.11 (Nov 20, 1998)
+ * Added "shutup" option to turn off last ambig warning.
+ * Fixed inner class def to allow named class defs as statements
+ * synchronized requires compound not simple statement
+ * add [] after builtInType DOT class in primaryExpression
+ * "const" is reserved but not valid..removed from modifiers
+ * Version 1.12 (Feb 2, 1999)
+ * Changed LITERAL_xxx to xxx in tree grammar.
+ * Updated java.g to use tokens {...} now for 2.6.0 (new feature).
+ *
+ * Version 1.13 (Apr 23, 1999)
+ * Didn't have (stat)? for else clause in tree parser.
+ * Didn't gen ASTs for interface extends. Updated tree parser too.
+ * Updated to 2.6.0.
+ * Version 1.14 (Jun 20, 1999)
+ * Allowed final/abstract on local classes.
+ * Removed local interfaces from methods
+ * Put instanceof precedence where it belongs...in relationalExpr
+ * It also had expr not type as arg; fixed it.
+ * Missing ! on SEMI in classBlock
+ * fixed: (expr) + "string" was parsed incorrectly (+ as unary plus).
+ * fixed: didn't like Object[].class in parser or tree parser
+ * Version 1.15 (Jun 26, 1999)
+ * Screwed up rule with instanceof in it. :( Fixed.
+ * Tree parser didn't like (expr).something; fixed.
+ * Allowed multiple inheritance in tree grammar. oops.
+ * Version 1.16 (August 22, 1999)
+ * Extending an interface built a wacky tree: had extra EXTENDS.
+ * Tree grammar didn't allow multiple superinterfaces.
+ * Tree grammar didn't allow empty var initializer: {}
+ * Version 1.17 (October 12, 1999)
+ * ESC lexer rule allowed 399 max not 377 max.
+ * java.tree.g didn't handle the expression of synchronized
+ * statements.
+ *
+ * BUG:
+ * Doesn't like boolean.class!
+ *
+ * class Test {
+ * public static void main( String args[] ) {
+ * if (boolean.class.equals(boolean.class)) {
+ * System.out.println("works");
+ * }
+ * }
+ * }
+ *
+ * This grammar is in the PUBLIC DOMAIN
+ */
+class JavaRecognizer extends Parser;
+options {
+ k = 2; // two token lookahead
+ exportVocab=Java; // Call its vocabulary "Java"
+ codeGenMakeSwitchThreshold = 2; // Some optimizations
+ codeGenBitsetTestThreshold = 3;
+ defaultErrorHandler = false; // Don't generate parser error handlers
+ buildAST = true;
+}
+
+tokens {
+ BLOCK; MODIFIERS; OBJBLOCK; SLIST; CTOR_DEF; METHOD_DEF; VARIABLE_DEF;
+ INSTANCE_INIT; STATIC_INIT; TYPE; CLASS_DEF; INTERFACE_DEF;
+ PACKAGE_DEF; ARRAY_DECLARATOR; EXTENDS_CLAUSE; IMPLEMENTS_CLAUSE;
+ PARAMETERS; PARAMETER_DEF; LABELED_STAT; TYPECAST; INDEX_OP;
+ POST_INC; POST_DEC; METHOD_CALL; EXPR; ARRAY_INIT;
+ IMPORT; UNARY_MINUS; UNARY_PLUS; CASE_GROUP; ELIST; FOR_INIT; FOR_CONDITION;
+ FOR_ITERATOR; EMPTY_STAT; FINAL="final"; ABSTRACT="abstract";
+}
+
+// Compilation Unit: In Java, this is a single file. This is the start
+// rule for this parser
+compilationUnit
+ : // A compilation unit starts with an optional package definition
+ ( packageDefinition
+ | /* nothing */
+ )
+
+ // Next we have a series of zero or more import statements
+ ( importDefinition )*
+
+ // Wrapping things up with any number of class or interface
+ // definitions
+ ( typeDefinition )*
+
+ EOF!
+ ;
+
+
+// Package statement: "package" followed by an identifier.
+packageDefinition
+ options {defaultErrorHandler = true;} // let ANTLR handle errors
+ : p:"package"^ {#p.setType(PACKAGE_DEF);} identifier SEMI!
+ ;
+
+
+// Import statement: import followed by a package or class name
+importDefinition
+ options {defaultErrorHandler = true;}
+ : i:"import"^ {#i.setType(IMPORT);} identifierStar SEMI!
+ ;
+
+// A type definition in a file is either a class or interface definition.
+typeDefinition
+ options {defaultErrorHandler = true;}
+ : m:modifiers!
+ ( classDefinition[#m]
+ | interfaceDefinition[#m]
+ )
+ | SEMI!
+ ;
+
+/** A declaration is the creation of a reference or primitive-type variable
+ * Create a separate Type/Var tree for each var in the var list.
+ */
+declaration!
+ : m:modifiers t:typeSpec[false] v:variableDefinitions[#m,#t]
+ {#declaration = #v;}
+ ;
+
+// A list of zero or more modifiers. We could have used (modifier)* in
+// place of a call to modifiers, but I thought it was a good idea to keep
+// this rule separate so they can easily be collected in a Vector if
+// someone so desires
+modifiers
+ : ( modifier )*
+ {#modifiers = #([MODIFIERS, "MODIFIERS"], #modifiers);}
+ ;
+
+
+// A type specification is a type name with possible brackets afterwards
+// (which would make it an array type).
+typeSpec[boolean addImagNode]
+ : classTypeSpec[addImagNode]
+ | builtInTypeSpec[addImagNode]
+ ;
+
+// A class type specification is a class type with possible brackets afterwards
+// (which would make it an array type).
+classTypeSpec[boolean addImagNode]
+ : identifier (lb:LBRACK^ {#lb.setType(ARRAY_DECLARATOR);} RBRACK!)*
+ {
+ if ( addImagNode ) {
+ #classTypeSpec = #(#[TYPE,"TYPE"], #classTypeSpec);
+ }
+ }
+ ;
+
+// A builtin type specification is a builtin type with possible brackets
+// afterwards (which would make it an array type).
+builtInTypeSpec[boolean addImagNode]
+ : builtInType (lb:LBRACK^ {#lb.setType(ARRAY_DECLARATOR);} RBRACK!)*
+ {
+ if ( addImagNode ) {
+ #builtInTypeSpec = #(#[TYPE,"TYPE"], #builtInTypeSpec);
+ }
+ }
+ ;
+
+// A type name. which is either a (possibly qualified) class name or
+// a primitive (builtin) type
+type
+ : identifier
+ | builtInType
+ ;
+
+// The primitive types.
+builtInType
+ : "void"
+ | "boolean"
+ | "byte"
+ | "char"
+ | "short"
+ | "int"
+ | "float"
+ | "long"
+ | "double"
+ ;
+
+// A (possibly-qualified) java identifier. We start with the first IDENT
+// and expand its name by adding dots and following IDENTS
+identifier
+ : IDENT ( DOT^ IDENT )*
+ ;
+
+identifierStar
+ : IDENT
+ ( DOT^ IDENT )*
+ ( DOT^ STAR )?
+ ;
+
+
+// modifiers for Java classes, interfaces, class/instance vars and methods
+modifier
+ : "private"
+ | "public"
+ | "protected"
+ | "static"
+ | "transient"
+ | "final"
+ | "abstract"
+ | "native"
+ | "threadsafe"
+ | "synchronized"
+// | "const" // reserved word; leave out
+ | "volatile"
+ ;
+
+
+// Definition of a Java class
+classDefinition![AST modifiers]
+ : "class" IDENT
+ // it _might_ have a superclass...
+ sc:superClassClause
+ // it might implement some interfaces...
+ ic:implementsClause
+ // now parse the body of the class
+ cb:classBlock
+ {#classDefinition = #(#[CLASS_DEF,"CLASS_DEF"],
+ modifiers,IDENT,sc,ic,cb);}
+ ;
+
+superClassClause!
+ : ( "extends" id:identifier )?
+ {#superClassClause = #(#[EXTENDS_CLAUSE,"EXTENDS_CLAUSE"],id);}
+ ;
+
+// Definition of a Java Interface
+interfaceDefinition![AST modifiers]
+ : "interface" IDENT
+ // it might extend some other interfaces
+ ie:interfaceExtends
+ // now parse the body of the interface (looks like a class...)
+ cb:classBlock
+ {#interfaceDefinition = #(#[INTERFACE_DEF,"INTERFACE_DEF"],
+ modifiers,IDENT,ie,cb);}
+ ;
+
+
+// This is the body of a class. You can have fields and extra semicolons,
+// That's about it (until you see what a field is...)
+classBlock
+ : LCURLY!
+ ( field | SEMI! )*
+ RCURLY!
+ {#classBlock = #([OBJBLOCK, "OBJBLOCK"], #classBlock);}
+ ;
+
+// An interface can extend several other interfaces...
+interfaceExtends
+ : (
+ e:"extends"!
+ identifier ( COMMA! identifier )*
+ )?
+ {#interfaceExtends = #(#[EXTENDS_CLAUSE,"EXTENDS_CLAUSE"],
+ #interfaceExtends);}
+ ;
+
+// A class can implement several interfaces...
+implementsClause
+ : (
+ i:"implements"! identifier ( COMMA! identifier )*
+ )?
+ {#implementsClause = #(#[IMPLEMENTS_CLAUSE,"IMPLEMENTS_CLAUSE"],
+ #implementsClause);}
+ ;
+
+// Now the various things that can be defined inside a class or interface...
+// Note that not all of these are really valid in an interface (constructors,
+// for example), and if this grammar were used for a compiler there would
+// need to be some semantic checks to make sure we're doing the right thing...
+field!
+ : // method, constructor, or variable declaration
+ mods:modifiers
+ ( h:ctorHead s:compoundStatement // constructor
+ {#field = #(#[CTOR_DEF,"CTOR_DEF"], mods, h, s);}
+
+ | cd:classDefinition[#mods] // inner class
+ {#field = #cd;}
+
+ | id:interfaceDefinition[#mods] // inner interface
+ {#field = #id;}
+
+ | t:typeSpec[false] // method or variable declaration(s)
+ ( IDENT // the name of the method
+
+ // parse the formal parameter declarations.
+ LPAREN! param:parameterDeclarationList RPAREN!
+
+ rt:returnTypeBrackersOnEndOfMethodHead[#t]
+
+ // get the list of exceptions that this method is declared to throw
+ (tc:throwsClause)?
+
+ ( s2:compoundStatement | SEMI )
+ {#field = #(#[METHOD_DEF,"METHOD_DEF"],
+ mods,
+ #(#[TYPE,"TYPE"],rt),
+ IDENT,
+ param,
+ tc,
+ s2);}
+ | v:variableDefinitions[#mods,#t] SEMI
+// {#field = #(#[VARIABLE_DEF,"VARIABLE_DEF"], v);}
+ {#field = #v;}
+ )
+ )
+
+ // "static { ... }" class initializer
+ | "static" s3:compoundStatement
+ {#field = #(#[STATIC_INIT,"STATIC_INIT"], s3);}
+
+ // "{ ... }" instance initializer
+ | s4:compoundStatement
+ {#field = #(#[INSTANCE_INIT,"INSTANCE_INIT"], s4);}
+ ;
+
+variableDefinitions[AST mods, AST t]
+ : variableDeclarator[getASTFactory().dupTree(mods),
+ getASTFactory().dupTree(t)]
+ ( COMMA!
+ variableDeclarator[getASTFactory().dupTree(mods),
+ getASTFactory().dupTree(t)]
+ )*
+ ;
+
+/** Declaration of a variable. This can be a class/instance variable,
+ * or a local variable in a method
+ * It can also include possible initialization.
+ */
+variableDeclarator![AST mods, AST t]
+ : id:IDENT d:declaratorBrackets[t] v:varInitializer
+ {#variableDeclarator = #(#[VARIABLE_DEF,"VARIABLE_DEF"], mods, #(#[TYPE,"TYPE"],d), id, v);}
+ ;
+
+declaratorBrackets[AST typ]
+ : {#declaratorBrackets=typ;}
+ (lb:LBRACK^ {#lb.setType(ARRAY_DECLARATOR);} RBRACK!)*
+ ;
+
+varInitializer
+ : ( ASSIGN^ initializer )?
+ ;
+
+// This is an initializer used to set up an array.
+arrayInitializer
+ : lc:LCURLY^ {#lc.setType(ARRAY_INIT);}
+ ( initializer
+ (
+ // CONFLICT: does a COMMA after an initializer start a new
+ // initializer or start the option ',' at end?
+ // ANTLR generates proper code by matching
+ // the comma as soon as possible.
+ options {
+ warnWhenFollowAmbig = false;
+ }
+ :
+ COMMA! initializer
+ )*
+ (COMMA!)?
+ )?
+ RCURLY!
+ ;
+
+
+// The two "things" that can initialize an array element are an expression
+// and another (nested) array initializer.
+initializer
+ : expression
+ | arrayInitializer
+ ;
+
+// This is the header of a method. It includes the name and parameters
+// for the method.
+// This also watches for a list of exception classes in a "throws" clause.
+ctorHead
+ : IDENT // the name of the method
+
+ // parse the formal parameter declarations.
+ LPAREN! parameterDeclarationList RPAREN!
+
+ // get the list of exceptions that this method is declared to throw
+ (throwsClause)?
+ ;
+
+// This is a list of exception classes that the method is declared to throw
+throwsClause
+ : "throws"^ identifier ( COMMA! identifier )*
+ ;
+
+
+returnTypeBrackersOnEndOfMethodHead[AST typ]
+ : {#returnTypeBrackersOnEndOfMethodHead = typ;}
+ (lb:LBRACK^ {#lb.setType(ARRAY_DECLARATOR);} RBRACK!)*
+ ;
+
+// A list of formal parameters
+parameterDeclarationList
+ : ( parameterDeclaration ( COMMA! parameterDeclaration )* )?
+ {#parameterDeclarationList = #(#[PARAMETERS,"PARAMETERS"],
+ #parameterDeclarationList);}
+ ;
+
+// A formal parameter.
+parameterDeclaration!
+ : pm:parameterModifier t:typeSpec[false] id:IDENT
+ pd:parameterDeclaratorBrackets[#t]
+ {#parameterDeclaration = #(#[PARAMETER_DEF,"PARAMETER_DEF"],
+ pm, #([TYPE,"TYPE"],pd), id);}
+ ;
+
+parameterDeclaratorBrackets[AST t]
+ : {#parameterDeclaratorBrackets = t;}
+ (lb:LBRACK^ {#lb.setType(ARRAY_DECLARATOR);} RBRACK!)*
+ ;
+
+parameterModifier
+ : (f:"final")?
+ {#parameterModifier = #(#[MODIFIERS,"MODIFIERS"], f);}
+ ;
+
+// Compound statement. This is used in many contexts:
+// Inside a class definition prefixed with "static":
+// it is a class initializer
+// Inside a class definition without "static":
+// it is an instance initializer
+// As the body of a method
+// As a completely indepdent braced block of code inside a method
+// it starts a new scope for variable definitions
+
+compoundStatement
+ : lc:LCURLY^ {#lc.setType(SLIST);}
+ // include the (possibly-empty) list of statements
+ (statement)*
+ RCURLY!
+ ;
+
+
+statement
+ // A list of statements in curly braces -- start a new scope!
+ : compoundStatement
+
+ // class definition
+ | classDefinition[#[MODIFIERS, "MODIFIERS"]]
+
+ // final class definition
+ | "final"! classDefinition[#(#[MODIFIERS, "MODIFIERS"],#[FINAL,"final"])]
+
+ // abstract class definition
+ | "abstract"! classDefinition[#(#[MODIFIERS, "MODIFIERS"],#[ABSTRACT,"abstract"])]
+
+ // declarations are ambiguous with "ID DOT" relative to expression
+ // statements. Must backtrack to be sure. Could use a semantic
+ // predicate to test symbol table to see what the type was coming
+ // up, but that's pretty hard without a symbol table ;)
+ | (declaration)=> declaration SEMI!
+
+ // An expression statement. This could be a method call,
+ // assignment statement, or any other expression evaluated for
+ // side-effects.
+ | expression SEMI!
+
+ // Attach a label to the front of a statement
+ | IDENT c:COLON^ {#c.setType(LABELED_STAT);} statement
+
+ // If-else statement
+ | "if"^ LPAREN! expression RPAREN! statement
+ (
+ // CONFLICT: the old "dangling-else" problem...
+ // ANTLR generates proper code matching
+ // as soon as possible. Hush warning.
+ options {
+ warnWhenFollowAmbig = false;
+ }
+ :
+ "else"! statement
+ )?
+
+ // For statement
+ | "for"^
+ LPAREN!
+ forInit SEMI! // initializer
+ forCond SEMI! // condition test
+ forIter // updater
+ RPAREN!
+ statement // statement to loop over
+
+ // While statement
+ | "while"^ LPAREN! expression RPAREN! statement
+
+ // do-while statement
+ | "do"^ statement "while"! LPAREN! expression RPAREN! SEMI!
+
+ // get out of a loop (or switch)
+ | "break"^ (IDENT)? SEMI!
+
+ // do next iteration of a loop
+ | "continue"^ (IDENT)? SEMI!
+
+ // Return an expression
+ | "return"^ (expression)? SEMI!
+
+ // switch/case statement
+ | "switch"^ LPAREN! expression RPAREN! LCURLY!
+ ( casesGroup )*
+ RCURLY!
+
+ // exception try-catch block
+ | tryBlock
+
+ // throw an exception
+ | "throw"^ expression SEMI!
+
+ // synchronize a statement
+ | "synchronized"^ LPAREN! expression RPAREN! compoundStatement
+
+ // empty statement
+ | s:SEMI {#s.setType(EMPTY_STAT);}
+ ;
+
+
+casesGroup
+ : ( // CONFLICT: to which case group do the statements bind?
+ // ANTLR generates proper code: it groups the
+ // many "case"/"default" labels together then
+ // follows them with the statements
+ options {
+ warnWhenFollowAmbig = false;
+ }
+ :
+ aCase
+ )+
+ caseSList
+ {#casesGroup = #([CASE_GROUP, "CASE_GROUP"], #casesGroup);}
+ ;
+
+aCase
+ : ("case"^ expression | "default") COLON!
+ ;
+
+caseSList
+ : (statement)*
+ {#caseSList = #(#[SLIST,"SLIST"],#caseSList);}
+ ;
+
+// The initializer for a for loop
+forInit
+ // if it looks like a declaration, it is
+ : ( (declaration)=> declaration
+ // otherwise it could be an expression list...
+ | expressionList
+ )?
+ {#forInit = #(#[FOR_INIT,"FOR_INIT"],#forInit);}
+ ;
+
+forCond
+ : (expression)?
+ {#forCond = #(#[FOR_CONDITION,"FOR_CONDITION"],#forCond);}
+ ;
+
+forIter
+ : (expressionList)?
+ {#forIter = #(#[FOR_ITERATOR,"FOR_ITERATOR"],#forIter);}
+ ;
+
+// an exception handler try/catch block
+tryBlock
+ : "try"^ compoundStatement
+ (handler)*
+ ( "finally"^ compoundStatement )?
+ ;
+
+
+// an exception handler
+handler
+ : "catch"^ LPAREN! parameterDeclaration RPAREN! compoundStatement
+ ;
+
+
+// expressions
+// Note that most of these expressions follow the pattern
+// thisLevelExpression :
+// nextHigherPrecedenceExpression
+// (OPERATOR nextHigherPrecedenceExpression)*
+// which is a standard recursive definition for a parsing an expression.
+// The operators in java have the following precedences:
+// lowest (13) = *= /= %= += -= <<= >>= >>>= &= ^= |=
+// (12) ?:
+// (11) ||
+// (10) &&
+// ( 9) |
+// ( 8) ^
+// ( 7) &
+// ( 6) == !=
+// ( 5) < <= > >=
+// ( 4) << >>
+// ( 3) +(binary) -(binary)
+// ( 2) * / %
+// ( 1) ++ -- +(unary) -(unary) ~ ! (type)
+// [] () (method call) . (dot -- identifier qualification)
+// new () (explicit parenthesis)
+//
+// the last two are not usually on a precedence chart; I put them in
+// to point out that new has a higher precedence than '.', so you
+// can validy use
+// new Frame().show()
+//
+// Note that the above precedence levels map to the rules below...
+// Once you have a precedence chart, writing the appropriate rules as below
+// is usually very straightfoward
+
+
+
+// the mother of all expressions
+expression
+ : assignmentExpression
+ {#expression = #(#[EXPR,"EXPR"],#expression);}
+ ;
+
+
+// This is a list of expressions.
+expressionList
+ : expression (COMMA! expression)*
+ {#expressionList = #(#[ELIST,"ELIST"], expressionList);}
+ ;
+
+
+// assignment expression (level 13)
+assignmentExpression
+ : conditionalExpression
+ ( ( ASSIGN^
+ | PLUS_ASSIGN^
+ | MINUS_ASSIGN^
+ | STAR_ASSIGN^
+ | DIV_ASSIGN^
+ | MOD_ASSIGN^
+ | SR_ASSIGN^
+ | BSR_ASSIGN^
+ | SL_ASSIGN^
+ | BAND_ASSIGN^
+ | BXOR_ASSIGN^
+ | BOR_ASSIGN^
+ )
+ assignmentExpression
+ )?
+ ;
+
+
+// conditional test (level 12)
+conditionalExpression
+ : logicalOrExpression
+ ( QUESTION^ assignmentExpression COLON! conditionalExpression )?
+ ;
+
+
+// logical or (||) (level 11)
+logicalOrExpression
+ : logicalAndExpression (LOR^ logicalAndExpression)*
+ ;
+
+
+// logical and (&&) (level 10)
+logicalAndExpression
+ : inclusiveOrExpression (LAND^ inclusiveOrExpression)*
+ ;
+
+
+// bitwise or non-short-circuiting or (|) (level 9)
+inclusiveOrExpression
+ : exclusiveOrExpression (BOR^ exclusiveOrExpression)*
+ ;
+
+
+// exclusive or (^) (level 8)
+exclusiveOrExpression
+ : andExpression (BXOR^ andExpression)*
+ ;
+
+
+// bitwise or non-short-circuiting and (&) (level 7)
+andExpression
+ : equalityExpression (BAND^ equalityExpression)*
+ ;
+
+
+// equality/inequality (==/!=) (level 6)
+equalityExpression
+ : relationalExpression ((NOT_EQUAL^ | EQUAL^) relationalExpression)*
+ ;
+
+
+// boolean relational expressions (level 5)
+relationalExpression
+ : shiftExpression
+ ( ( ( LT^
+ | GT^
+ | LE^
+ | GE^
+ )
+ shiftExpression
+ )*
+ | "instanceof"^ typeSpec[true]
+ )
+ ;
+
+
+// bit shift expressions (level 4)
+shiftExpression
+ : additiveExpression ((SL^ | SR^ | BSR^) additiveExpression)*
+ ;
+
+
+// binary addition/subtraction (level 3)
+additiveExpression
+ : multiplicativeExpression ((PLUS^ | MINUS^) multiplicativeExpression)*
+ ;
+
+
+// multiplication/division/modulo (level 2)
+multiplicativeExpression
+ : unaryExpression ((STAR^ | DIV^ | MOD^ ) unaryExpression)*
+ ;
+
+unaryExpression
+ : INC^ unaryExpression
+ | DEC^ unaryExpression
+ | MINUS^ {#MINUS.setType(UNARY_MINUS);} unaryExpression
+ | PLUS^ {#PLUS.setType(UNARY_PLUS);} unaryExpression
+ | unaryExpressionNotPlusMinus
+ ;
+
+unaryExpressionNotPlusMinus
+ : BNOT^ unaryExpression
+ | LNOT^ unaryExpression
+
+ | ( // subrule allows option to shut off warnings
+ options {
+ // "(int" ambig with postfixExpr due to lack of sequence
+ // info in linear approximate LL(k). It's ok. Shut up.
+ generateAmbigWarnings=false;
+ }
+ : // If typecast is built in type, must be numeric operand
+ // Also, no reason to backtrack if type keyword like int, float...
+ lpb:LPAREN^ {#lpb.setType(TYPECAST);} builtInTypeSpec[true] RPAREN!
+ unaryExpression
+
+ // Have to backtrack to see if operator follows. If no operator
+ // follows, it's a typecast. No semantic checking needed to parse.
+ // if it _looks_ like a cast, it _is_ a cast; else it's a "(expr)"
+ | (LPAREN classTypeSpec[true] RPAREN unaryExpressionNotPlusMinus)=>
+ lp:LPAREN^ {#lp.setType(TYPECAST);} classTypeSpec[true] RPAREN!
+ unaryExpressionNotPlusMinus
+
+ | postfixExpression
+ )
+ ;
+
+// qualified names, array expressions, method invocation, post inc/dec
+postfixExpression
+ : primaryExpression // start with a primary
+
+ ( // qualified id (id.id.id.id...) -- build the name
+ DOT^ ( IDENT
+ | "this"
+ | "class"
+ | newExpression
+ | "super" LPAREN ( expressionList )? RPAREN
+ )
+ // the above line needs a semantic check to make sure "class"
+ // is the _last_ qualifier.
+
+ // allow ClassName[].class
+ | ( lbc:LBRACK^ {#lbc.setType(ARRAY_DECLARATOR);} RBRACK! )+
+ DOT^ "class"
+
+ // an array indexing operation
+ | lb:LBRACK^ {#lb.setType(INDEX_OP);} expression RBRACK!
+
+ // method invocation
+ // The next line is not strictly proper; it allows x(3)(4) or
+ // x[2](4) which are not valid in Java. If this grammar were used
+ // to validate a Java program a semantic check would be needed, or
+ // this rule would get really ugly...
+ | lp:LPAREN^ {#lp.setType(METHOD_CALL);}
+ argList
+ RPAREN!
+ )*
+
+ // possibly add on a post-increment or post-decrement.
+ // allows INC/DEC on too much, but semantics can check
+ ( in:INC^ {#in.setType(POST_INC);}
+ | de:DEC^ {#de.setType(POST_DEC);}
+ | // nothing
+ )
+
+ // look for int.class and int[].class
+ | builtInType
+ ( lbt:LBRACK^ {#lbt.setType(ARRAY_DECLARATOR);} RBRACK! )*
+ DOT^ "class"
+ ;
+
+// the basic element of an expression
+primaryExpression
+ : IDENT
+ | newExpression
+ | constant
+ | "super"
+ | "true"
+ | "false"
+ | "this"
+ | "null"
+ | LPAREN! assignmentExpression RPAREN!
+ ;
+
+/** object instantiation.
+ * Trees are built as illustrated by the following input/tree pairs:
+ *
+ * new T()
+ *
+ * new
+ * |
+ * T -- ELIST
+ * |
+ * arg1 -- arg2 -- .. -- argn
+ *
+ * new int[]
+ *
+ * new
+ * |
+ * int -- ARRAY_DECLARATOR
+ *
+ * new int[] {1,2}
+ *
+ * new
+ * |
+ * int -- ARRAY_DECLARATOR -- ARRAY_INIT
+ * |
+ * EXPR -- EXPR
+ * | |
+ * 1 2
+ *
+ * new int[3]
+ * new
+ * |
+ * int -- ARRAY_DECLARATOR
+ * |
+ * EXPR
+ * |
+ * 3
+ *
+ * new int[1][2]
+ *
+ * new
+ * |
+ * int -- ARRAY_DECLARATOR
+ * |
+ * ARRAY_DECLARATOR -- EXPR
+ * | |
+ * EXPR 1
+ * |
+ * 2
+ *
+ */
+newExpression
+ : "new"^ type
+ ( LPAREN! argList RPAREN! (classBlock)?
+
+ //java 1.1
+ // Note: This will allow bad constructs like
+ // new int[4][][3] {exp,exp}.
+ // There needs to be a semantic check here...
+ // to make sure:
+ // a) [ expr ] and [ ] are not mixed
+ // b) [ expr ] and an init are not used together
+
+ | newArrayDeclarator (arrayInitializer)?
+ )
+ ;
+
+argList
+ : ( expressionList
+ | /*nothing*/
+ {#argList = #[ELIST,"ELIST"];}
+ )
+ ;
+
+newArrayDeclarator
+ : (
+ // CONFLICT:
+ // newExpression is a primaryExpression which can be
+ // followed by an array index reference. This is ok,
+ // as the generated code will stay in this loop as
+ // long as it sees an LBRACK (proper behavior)
+ options {
+ warnWhenFollowAmbig = false;
+ }
+ :
+ lb:LBRACK^ {#lb.setType(ARRAY_DECLARATOR);}
+ (expression)?
+ RBRACK!
+ )+
+ ;
+
+constant
+ : NUM_INT
+ | CHAR_LITERAL
+ | STRING_LITERAL
+ | NUM_FLOAT
+ ;
+
+
+//----------------------------------------------------------------------------
+// The Java scanner
+//----------------------------------------------------------------------------
+class JavaLexer extends Lexer;
+
+options {
+ exportVocab=Java; // call the vocabulary "Java"
+ testLiterals=false; // don't automatically test for literals
+ k=4; // four characters of lookahead
+}
+
+
+
+// OPERATORS
+QUESTION : '?' ;
+LPAREN : '(' ;
+RPAREN : ')' ;
+LBRACK : '[' ;
+RBRACK : ']' ;
+LCURLY : '{' ;
+RCURLY : '}' ;
+COLON : ':' ;
+COMMA : ',' ;
+//DOT : '.' ;
+ASSIGN : '=' ;
+EQUAL : "==" ;
+LNOT : '!' ;
+BNOT : '~' ;
+NOT_EQUAL : "!=" ;
+DIV : '/' ;
+DIV_ASSIGN : "/=" ;
+PLUS : '+' ;
+PLUS_ASSIGN : "+=" ;
+INC : "++" ;
+MINUS : '-' ;
+MINUS_ASSIGN : "-=" ;
+DEC : "--" ;
+STAR : '*' ;
+STAR_ASSIGN : "*=" ;
+MOD : '%' ;
+MOD_ASSIGN : "%=" ;
+SR : ">>" ;
+SR_ASSIGN : ">>=" ;
+BSR : ">>>" ;
+BSR_ASSIGN : ">>>=" ;
+GE : ">=" ;
+GT : ">" ;
+SL : "<<" ;
+SL_ASSIGN : "<<=" ;
+LE : "<=" ;
+LT : '<' ;
+BXOR : '^' ;
+BXOR_ASSIGN : "^=" ;
+BOR : '|' ;
+BOR_ASSIGN : "|=" ;
+LOR : "||" ;
+BAND : '&' ;
+BAND_ASSIGN : "&=" ;
+LAND : "&&" ;
+SEMI : ';' ;
+
+
+// Whitespace -- ignored
+WS : ( ' '
+ | '\t'
+ | '\f'
+ // handle newlines
+ | ( "\r\n" // Evil DOS
+ | '\r' // Macintosh
+ | '\n' // Unix (the right way)
+ )
+ { newline(); }
+ )
+ { _ttype = Token.SKIP; }
+ ;
+
+// Single-line comments
+SL_COMMENT
+ : "//"
+ (~('\n'|'\r'))* ('\n'|'\r'('\n')?)
+ {$setType(Token.SKIP); newline();}
+ ;
+
+// multiple-line comments
+ML_COMMENT
+ : "/*"
+ ( /* '\r' '\n' can be matched in one alternative or by matching
+ '\r' in one iteration and '\n' in another. I am trying to
+ handle any flavor of newline that comes in, but the language
+ that allows both "\r\n" and "\r" and "\n" to all be valid
+ newline is ambiguous. Consequently, the resulting grammar
+ must be ambiguous. I'm shutting this warning off.
+ */
+ options {
+ generateAmbigWarnings=false;
+ }
+ :
+ { LA(2)!='/' }? '*'
+ | '\r' '\n' {newline();}
+ | '\r' {newline();}
+ | '\n' {newline();}
+ | ~('*'|'\n'|'\r')
+ )*
+ "*/"
+ {$setType(Token.SKIP);}
+ ;
+
+
+// character literals
+CHAR_LITERAL
+ : '\'' ( ESC | ~'\'' ) '\''
+ ;
+
+// string literals
+STRING_LITERAL
+ : '"' (ESC|~('"'|'\\'))* '"'
+ ;
+
+
+// escape sequence -- note that this is protected; it can only be called
+// from another lexer rule -- it will not ever directly return a token to
+// the parser
+// There are various ambiguities hushed in this rule. The optional
+// '0'...'9' digit matches should be matched here rather than letting
+// them go back to STRING_LITERAL to be matched. ANTLR does the
+// right thing by matching immediately; hence, it's ok to shut off
+// the FOLLOW ambig warnings.
+protected
+ESC
+ : '\\'
+ ( 'n'
+ | 'r'
+ | 't'
+ | 'b'
+ | 'f'
+ | '"'
+ | '\''
+ | '\\'
+ | ('u')+ HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT
+ | ('0'..'3')
+ (
+ options {
+ warnWhenFollowAmbig = false;
+ }
+ : ('0'..'7')
+ (
+ options {
+ warnWhenFollowAmbig = false;
+ }
+ : '0'..'7'
+ )?
+ )?
+ | ('4'..'7')
+ (
+ options {
+ warnWhenFollowAmbig = false;
+ }
+ : ('0'..'9')
+ )?
+ )
+ ;
+
+
+// hexadecimal digit (again, note it's protected!)
+protected
+HEX_DIGIT
+ : ('0'..'9'|'A'..'F'|'a'..'f')
+ ;
+
+
+// a dummy rule to force vocabulary to be all characters (except special
+// ones that ANTLR uses internally (0 to 2)
+protected
+VOCAB
+ : '\3'..'\377'
+ ;
+
+
+// an identifier. Note that testLiterals is set to true! This means
+// that after we match the rule, we look in the literals table to see
+// if it's a literal or really an identifer
+IDENT
+ options {testLiterals=true;}
+ : ('a'..'z'|'A'..'Z'|'_'|'$') ('a'..'z'|'A'..'Z'|'_'|'0'..'9'|'$')*
+ ;
+
+
+// a numeric literal
+NUM_INT
+ {boolean isDecimal=false;}
+ : '.' {_ttype = DOT;}
+ (('0'..'9')+ (EXPONENT)? (FLOAT_SUFFIX)? { _ttype = NUM_FLOAT; })?
+ | ( '0' {isDecimal = true;} // special case for just '0'
+ ( ('x'|'X')
+ ( // hex
+ // the 'e'|'E' and float suffix stuff look
+ // like hex digits, hence the (...)+ doesn't
+ // know when to stop: ambig. ANTLR resolves
+ // it correctly by matching immediately. It
+ // is therefor ok to hush warning.
+ options {
+ warnWhenFollowAmbig=false;
+ }
+ : HEX_DIGIT
+ )+
+ | ('0'..'7')+ // octal
+ )?
+ | ('1'..'9') ('0'..'9')* {isDecimal=true;} // non-zero decimal
+ )
+ ( ('l'|'L')
+
+ // only check to see if it's a float if looks like decimal so far
+ | {isDecimal}?
+ ( '.' ('0'..'9')* (EXPONENT)? (FLOAT_SUFFIX)?
+ | EXPONENT (FLOAT_SUFFIX)?
+ | FLOAT_SUFFIX
+ )
+ { _ttype = NUM_FLOAT; }
+ )?
+ ;
+
+
+// a couple protected methods to assist in matching floating point numbers
+protected
+EXPONENT
+ : ('e'|'E') ('+'|'-')? ('0'..'9')+
+ ;
+
+
+protected
+FLOAT_SUFFIX
+ : 'f'|'F'|'d'|'D'
+ ;
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/antlr/java.tree.g b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/antlr/java.tree.g
new file mode 100644
index 00000000..f065c356
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/antlr/java.tree.g
@@ -0,0 +1,312 @@
+/** Java 1.2 AST Recognizer Grammar
+ *
+ * Author:
+ * Terence Parr parrt@jguru.com
+ *
+ * Version tracking now done with following ID:
+ *
+ * This grammar is in the PUBLIC DOMAIN
+ *
+ * BUGS
+ */
+class JavaTreeParser extends TreeParser;
+
+options {
+ importVocab = Java;
+}
+
+compilationUnit
+ : (packageDefinition)?
+ (importDefinition)*
+ (typeDefinition)*
+ ;
+
+packageDefinition
+ : #( PACKAGE_DEF identifier )
+ ;
+
+importDefinition
+ : #( IMPORT identifierStar )
+ ;
+
+typeDefinition
+ : #(CLASS_DEF modifiers IDENT extendsClause implementsClause objBlock )
+ | #(INTERFACE_DEF modifiers IDENT extendsClause interfaceBlock )
+ ;
+
+typeSpec
+ : #(TYPE typeSpecArray)
+ ;
+
+typeSpecArray
+ : #( ARRAY_DECLARATOR typeSpecArray )
+ | type
+ ;
+
+type: identifier
+ | builtInType
+ ;
+
+builtInType
+ : "void"
+ | "boolean"
+ | "byte"
+ | "char"
+ | "short"
+ | "int"
+ | "float"
+ | "long"
+ | "double"
+ ;
+
+modifiers
+ : #( MODIFIERS (modifier)* )
+ ;
+
+modifier
+ : "private"
+ | "public"
+ | "protected"
+ | "static"
+ | "transient"
+ | "final"
+ | "abstract"
+ | "native"
+ | "threadsafe"
+ | "synchronized"
+ | "const"
+ | "volatile"
+ ;
+
+extendsClause
+ : #(EXTENDS_CLAUSE (identifier)* )
+ ;
+
+implementsClause
+ : #(IMPLEMENTS_CLAUSE (identifier)* )
+ ;
+
+
+interfaceBlock
+ : #( OBJBLOCK
+ ( methodDecl
+ | variableDef
+ )*
+ )
+ ;
+
+objBlock
+ : #( OBJBLOCK
+ ( ctorDef
+ | methodDef
+ | variableDef
+ | typeDefinition
+ | #(STATIC_INIT slist)
+ | #(INSTANCE_INIT slist)
+ )*
+ )
+ ;
+
+ctorDef
+ : #(CTOR_DEF modifiers methodHead slist)
+ ;
+
+methodDecl
+ : #(METHOD_DEF modifiers typeSpec methodHead)
+ ;
+
+methodDef
+ : #(METHOD_DEF modifiers typeSpec methodHead (slist)?)
+ ;
+
+variableDef
+ : #(VARIABLE_DEF modifiers typeSpec variableDeclarator varInitializer)
+ ;
+
+parameterDef
+ : #(PARAMETER_DEF modifiers typeSpec IDENT )
+ ;
+
+objectinitializer
+ : #(INSTANCE_INIT slist)
+ ;
+
+variableDeclarator
+ : IDENT
+ | LBRACK variableDeclarator
+ ;
+
+varInitializer
+ : #(ASSIGN initializer)
+ |
+ ;
+
+initializer
+ : expression
+ | arrayInitializer
+ ;
+
+arrayInitializer
+ : #(ARRAY_INIT (initializer)*)
+ ;
+
+methodHead
+ : IDENT #( PARAMETERS (parameterDef)* ) (throwsClause)?
+ ;
+
+throwsClause
+ : #( "throws" (identifier)* )
+ ;
+
+identifier
+ : IDENT
+ | #( DOT identifier IDENT )
+ ;
+
+identifierStar
+ : IDENT
+ | #( DOT identifier (STAR|IDENT) )
+ ;
+
+slist
+ : #( SLIST (stat)* )
+ ;
+
+stat: typeDefinition
+ | variableDef
+ | expression
+ | #(LABELED_STAT IDENT stat)
+ | #("if" expression stat (stat)? )
+ | #( "for"
+ #(FOR_INIT (variableDef | elist)?)
+ #(FOR_CONDITION (expression)?)
+ #(FOR_ITERATOR (elist)?)
+ stat
+ )
+ | #("while" expression stat)
+ | #("do" stat expression)
+ | #("break" (IDENT)? )
+ | #("continue" (IDENT)? )
+ | #("return" (expression)? )
+ | #("switch" expression (caseGroup)*)
+ | #("throw" expression)
+ | #("synchronized" expression stat)
+ | tryBlock
+ | slist // nested SLIST
+ | EMPTY_STAT
+ ;
+
+caseGroup
+ : #(CASE_GROUP (#("case" expression) | "default")+ slist)
+ ;
+
+tryBlock
+ : #( "try" slist (handler)* (#("finally" slist))? )
+ ;
+
+handler
+ : #( "catch" parameterDef slist )
+ ;
+
+elist
+ : #( ELIST (expression)* )
+ ;
+
+expression
+ : #(EXPR expr)
+ ;
+
+expr: #(QUESTION expr expr expr) // trinary operator
+ | #(ASSIGN expr expr) // binary operators...
+ | #(PLUS_ASSIGN expr expr)
+ | #(MINUS_ASSIGN expr expr)
+ | #(STAR_ASSIGN expr expr)
+ | #(DIV_ASSIGN expr expr)
+ | #(MOD_ASSIGN expr expr)
+ | #(SR_ASSIGN expr expr)
+ | #(BSR_ASSIGN expr expr)
+ | #(SL_ASSIGN expr expr)
+ | #(BAND_ASSIGN expr expr)
+ | #(BXOR_ASSIGN expr expr)
+ | #(BOR_ASSIGN expr expr)
+ | #(LOR expr expr)
+ | #(LAND expr expr)
+ | #(BOR expr expr)
+ | #(BXOR expr expr)
+ | #(BAND expr expr)
+ | #(NOT_EQUAL expr expr)
+ | #(EQUAL expr expr)
+ | #(LT expr expr)
+ | #(GT expr expr)
+ | #(LE expr expr)
+ | #(GE expr expr)
+ | #(SL expr expr)
+ | #(SR expr expr)
+ | #(BSR expr expr)
+ | #(PLUS expr expr)
+ | #(MINUS expr expr)
+ | #(DIV expr expr)
+ | #(MOD expr expr)
+ | #(STAR expr expr)
+ | #(INC expr)
+ | #(DEC expr)
+ | #(POST_INC expr)
+ | #(POST_DEC expr)
+ | #(BNOT expr)
+ | #(LNOT expr)
+ | #("instanceof" expr expr)
+ | #(UNARY_MINUS expr)
+ | #(UNARY_PLUS expr)
+ | primaryExpression
+ ;
+
+primaryExpression
+ : IDENT
+ | #( DOT
+ ( expr
+ ( IDENT
+ | arrayIndex
+ | "this"
+ | "class"
+ | #( "new" IDENT elist )
+ )
+ | #(ARRAY_DECLARATOR type)
+ | builtInType ("class")?
+ )
+ )
+ | arrayIndex
+ | #(METHOD_CALL primaryExpression elist)
+ | #(TYPECAST typeSpec expr)
+ | newExpression
+ | constant
+ | "super"
+ | "true"
+ | "false"
+ | "this"
+ | "null"
+ | typeSpec // type name used with instanceof
+ ;
+
+arrayIndex
+ : #(INDEX_OP primaryExpression expression)
+ ;
+
+constant
+ : NUM_INT
+ | CHAR_LITERAL
+ | STRING_LITERAL
+ | NUM_FLOAT
+ ;
+
+newExpression
+ : #( "new" type
+ ( newArrayDeclarator (arrayInitializer)?
+ | elist
+ )
+ )
+
+ ;
+
+newArrayDeclarator
+ : #( ARRAY_DECLARATOR (newArrayDeclarator)? (expression)? )
+ ;
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/depend/depend.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/depend/depend.xml
new file mode 100644
index 00000000..8465bb02
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/depend/depend.xml
@@ -0,0 +1,196 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<project name="depend" basedir="." default="help">
+ <import file="../../../buildfiletest-base.xml"/>
+
+ <property name="tempsrc.dir" value="${output}/tempsrc.dir"/>
+ <property name="cache.dir" value="${output}/tempsrc.dir"/>
+ <property name="classes.dir" value="${output}/classes"/>
+
+ <target name="setUp">
+ <mkdir dir="${output}" />
+
+ </target>
+
+ <property name="src1.dir" value="src1"/>
+ <property name="src2.dir" value="src2"/>
+ <property name="src3.dir" value="src3"/>
+ <property name="src4.dir" value="src4"/>
+ <property name="src5.dir" value="src5"/>
+
+ <target name="help">
+ <echo>This buildfile is used as part of Ant's test suite.</echo>
+ </target>
+
+ <target name="src1setup" depends="setUp">
+ <copy todir="${tempsrc.dir}">
+ <fileset dir="${src1.dir}"/>
+ </copy>
+ </target>
+
+ <target name="src2setup" depends="setUp">
+ <copy todir="${tempsrc.dir}">
+ <fileset dir="${src2.dir}"/>
+ </copy>
+ </target>
+
+ <target name="src3setup" depends="setUp">
+ <copy todir="${tempsrc.dir}">
+ <fileset dir="${src3.dir}"/>
+ </copy>
+ </target>
+
+ <target name="src4setup" depends="setUp">
+ <copy todir="${tempsrc.dir}">
+ <fileset dir="${src4.dir}"/>
+ </copy>
+ </target>
+
+ <target name="src5setup" depends="setUp">
+ <copy todir="${tempsrc.dir}">
+ <fileset dir="${src5.dir}"/>
+ </copy>
+ </target>
+
+ <target name="compile">
+ <mkdir dir="${classes.dir}"/>
+ <javac srcdir="${tempsrc.dir}" destdir="${classes.dir}"/>
+ </target>
+
+ <target name="testdirect">
+ <delete file="${tempsrc.dir}/C.java"/>
+ <copy file="${src1.dir}/C.java" tofile="${tempsrc.dir}/C.java"/>
+ <depend srcdir="${tempsrc.dir}" destdir="${classes.dir}"/>
+ <fileset id="result" dir="${classes.dir}"/>
+ </target>
+
+ <target name="testclosure">
+ <delete file="${tempsrc.dir}/C.java"/>
+ <copy file="${src1.dir}/C.java" tofile="${tempsrc.dir}/C.java"/>
+ <depend srcdir="${tempsrc.dir}" destdir="${classes.dir}" closure="yes"/>
+ <fileset id="result" dir="${classes.dir}"/>
+ </target>
+
+ <target name="testbasicset" depends="src1setup, compile">
+ <classfileset id="result" dir="${classes.dir}" rootclass="A"/>
+ </target>
+
+ <target name="testsmallset" depends="src1setup, compile">
+ <classfileset id="result" dir="${classes.dir}" rootclass="B"/>
+ </target>
+
+ <target name="testresourcecollection" depends="testsmallset">
+ <fail>
+ <condition>
+ <not>
+ <and>
+ <resourcecount count="2" refid="result" />
+ <resourcecount count="1">
+ <intersect>
+ <resources refid="result" />
+ <file file="${classes.dir}/B.class" />
+ </intersect>
+ </resourcecount>
+ <resourcecount count="1">
+ <intersect>
+ <resources refid="result" />
+ <file file="${classes.dir}/C.class" />
+ </intersect>
+ </resourcecount>
+ </and>
+ </not>
+ </condition>
+ </fail>
+ </target>
+
+ <target name="testcomboset" depends="src1setup, compile">
+ <classfileset id="result" dir="${classes.dir}" rootclass="B">
+ <include name="**/C.class"/>
+ </classfileset>
+ </target>
+
+ <target name="testbyreference" depends="src1setup, compile">
+ <classfileset id="classSet" dir="${classes.dir}" rootclass="A">
+ <include name="**/C.class"/>
+ </classfileset>
+ <jar destfile="${tempsrc.dir}/test.jar">
+ <fileset refid="classSet"/>
+ </jar>
+ </target>
+
+ <target name="testmethodparam" depends="src1setup, compile">
+ <classfileset id="result" dir="${classes.dir}" rootclass="E"/>
+ </target>
+
+ <target name="testinner">
+ <delete file="${tempsrc.dir}/B.java"/>
+ <copy file="${src2.dir}/B.java" tofile="${tempsrc.dir}/B.java"/>
+ <depend srcdir="${tempsrc.dir}" destdir="${classes.dir}" closure="yes"/>
+ <fileset id="result" dir="${classes.dir}"/>
+ </target>
+
+ <target name="testinnerinner">
+ <delete file="${tempsrc.dir}/B.java"/>
+ <copy file="${src3.dir}/B.java" tofile="${tempsrc.dir}/B.java"/>
+ <depend srcdir="${tempsrc.dir}" destdir="${classes.dir}" closure="yes"/>
+ <fileset id="result" dir="${classes.dir}"/>
+ </target>
+
+ <target name="testmethodparaminner" depends="src4setup, compile">
+ <classfileset id="result" dir="${classes.dir}" rootclass="test.MethodParam"/>
+ </target>
+
+ <target name="testnosource" depends="src1setup, compile">
+ <depend destdir="${classes.dir}" closure="yes"/>
+ </target>
+
+ <target name="testemptysource" depends="src1setup, compile">
+ <depend srcdir="" destdir="${classes.dir}" closure="yes"/>
+ </target>
+
+ <target name="testinnerclosure" depends="src4setup">
+ <mkdir dir="${classes.dir}"/>
+ <path id="path.compile">
+ <pathelement location="${classes.dir}"/>
+ </path>
+
+ <javac srcdir="${tempsrc.dir}" destdir="${classes.dir}"
+ classpathref="path.compile" fork="false" />
+
+ <depend srcdir="${tempsrc.dir}" destdir="${classes.dir}"
+ closure="yes" dump="yes"
+ classpathref="path.compile"/>
+
+ <fileset id="result" dir="${classes.dir}"/>
+ </target>
+
+ <target name="testcache" depends="src1setup, compile">
+ <depend cache="${cache.dir}" srcdir="${tempsrc.dir}"
+ destdir="${classes.dir}" closure="yes"/>
+ <depend cache="${cache.dir}" srcdir="${tempsrc.dir}"
+ destdir="${classes.dir}" closure="yes"/>
+ </target>
+
+ <target name="testnonpublic">
+ <delete file="${tempsrc.dir}/B.java"/>
+ <copy file="${src2.dir}/B.java" tofile="${tempsrc.dir}/B.java"/>
+ <depend srcdir="${tempsrc.dir}" destdir="${classes.dir}" closure="yes"/>
+ <fileset id="result" dir="${classes.dir}"/>
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/depend/src1/A.java b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/depend/src1/A.java
new file mode 100644
index 00000000..dc6df231
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/depend/src1/A.java
@@ -0,0 +1,20 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+public class A extends B {
+ private D d = new D();
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/depend/src1/B.java b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/depend/src1/B.java
new file mode 100644
index 00000000..4be51f78
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/depend/src1/B.java
@@ -0,0 +1,19 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+public class B extends C {
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/depend/src1/C.java b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/depend/src1/C.java
new file mode 100644
index 00000000..d2bfca9d
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/depend/src1/C.java
@@ -0,0 +1,19 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+public class C {
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/depend/src1/D.java b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/depend/src1/D.java
new file mode 100644
index 00000000..127de573
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/depend/src1/D.java
@@ -0,0 +1,19 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+public class D {
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/depend/src1/E.java b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/depend/src1/E.java
new file mode 100644
index 00000000..0efd6134
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/depend/src1/E.java
@@ -0,0 +1,22 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+public class E {
+ E() {
+ System.out.println(A.class);
+ }
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/depend/src2/A.java b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/depend/src2/A.java
new file mode 100644
index 00000000..02b35be7
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/depend/src2/A.java
@@ -0,0 +1,21 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+public class A {
+ static private class Inner extends B {
+ }
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/depend/src2/B.java b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/depend/src2/B.java
new file mode 100644
index 00000000..bc7b7d24
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/depend/src2/B.java
@@ -0,0 +1,19 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+public class B {
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/depend/src3/A.java b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/depend/src3/A.java
new file mode 100644
index 00000000..1d973b15
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/depend/src3/A.java
@@ -0,0 +1,23 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+public class A {
+ static private class Inner {
+ static private class Inner2 extends B {
+ }
+ }
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/depend/src3/B.java b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/depend/src3/B.java
new file mode 100644
index 00000000..bc7b7d24
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/depend/src3/B.java
@@ -0,0 +1,19 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+public class B {
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/depend/src4/test/ContainsOnlyInner.java b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/depend/src4/test/ContainsOnlyInner.java
new file mode 100644
index 00000000..d00254b9
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/depend/src4/test/ContainsOnlyInner.java
@@ -0,0 +1,24 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+package test;
+
+public class ContainsOnlyInner {
+ void method1() {
+ System.out.println(Outer.Inner.class);
+ }
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/depend/src4/test/MethodParam.java b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/depend/src4/test/MethodParam.java
new file mode 100644
index 00000000..276f0163
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/depend/src4/test/MethodParam.java
@@ -0,0 +1,24 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+package test;
+
+public class MethodParam {
+ void method1() {
+ System.out.print(ContainsOnlyInner.class);
+ }
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/depend/src4/test/Outer.java b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/depend/src4/test/Outer.java
new file mode 100644
index 00000000..0b709002
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/depend/src4/test/Outer.java
@@ -0,0 +1,23 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+package test;
+
+public class Outer {
+ static class Inner {
+ }
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/depend/src5/A.java b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/depend/src5/A.java
new file mode 100644
index 00000000..19521a14
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/depend/src5/A.java
@@ -0,0 +1,22 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+public class A {
+ APrivate dependency = new APrivate();
+}
+
+class APrivate extends B {
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/depend/src5/B.java b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/depend/src5/B.java
new file mode 100644
index 00000000..bc7b7d24
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/depend/src5/B.java
@@ -0,0 +1,19 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+public class B {
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/echoproperties.properties b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/echoproperties.properties
new file mode 100644
index 00000000..4c970e7e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/echoproperties.properties
@@ -0,0 +1,15 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+test.infile=true \ No newline at end of file
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/echoproperties.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/echoproperties.xml
new file mode 100644
index 00000000..7b1b8bb8
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/echoproperties.xml
@@ -0,0 +1,133 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="test" default="def" basedir=".">
+
+ <target name="def">
+ </target>
+
+ <target name="setup">
+ <property name="a.set" value="true" />
+ <property name="b.set" value="false" />
+ </target>
+
+ <target name="testEchoToLog" depends="setup">
+ <echoproperties />
+ </target>
+
+ <target name="testEchoWithEmptyPrefixToLog" depends="setup">
+ <echoproperties prefix=""/>
+ </target>
+
+ <target name="testEchoToLogXml" depends="setup">
+ <echoproperties format="xml" />
+ </target>
+
+ <target name="testReadAndEchoToLog" depends="setup">
+ <echoproperties srcfile="echoproperties.properties" />
+ </target>
+
+ <target name="testReadBadFile" depends="setup">
+ <echoproperties srcfile="." />
+ </target>
+
+ <target name="testReadBadFileFail" depends="setup">
+ <echoproperties srcfile="." failonerror="yes" />
+ </target>
+
+ <target name="testReadBadFileNoFail" depends="setup">
+ <echoproperties srcfile="." failonerror="no" />
+ </target>
+
+ <target name="testEchoToBadFile" depends="setup">
+ <echoproperties destfile="." />
+ </target>
+
+ <target name="testEchoToBadFileFail" depends="setup">
+ <echoproperties destfile="." failonerror="yes" />
+ </target>
+
+ <target name="testEchoToBadFileNoFail" depends="setup">
+ <echoproperties destfile="." failonerror="no" />
+ </target>
+
+ <target name="testEchoToGoodFile" depends="setup">
+ <echoproperties destfile="test.properties" />
+ </target>
+
+ <target name="testEchoToGoodFileXml" depends="setup">
+ <echoproperties destfile="test.xml" format="xml" />
+ </target>
+
+ <target name="testEchoToGoodFileFail" depends="setup">
+ <echoproperties destfile="test.properties" failonerror="yes" />
+ </target>
+
+ <target name="testEchoToGoodFileNoFail" depends="setup">
+ <echoproperties destfile="test.properties" failonerror="no" />
+ </target>
+
+ <target name="testEchoPrefix" depends="setup">
+ <echoproperties destfile="test-prefix.properties" prefix="a." />
+ </target>
+
+ <target name="testEchoPrefixAsPropertyset" depends="setup">
+ <echoproperties destfile="test-prefix.properties">
+ <propertyset>
+ <propertyref prefix="a."/>
+ </propertyset>
+ </echoproperties>
+ </target>
+
+ <target name="testEchoPrefixAsNegatedPropertyset" depends="setup">
+ <echoproperties destfile="test-prefix.properties">
+ <propertyset negate="true">
+ <propertyref prefix="b."/>
+ </propertyset>
+ </echoproperties>
+ </target>
+
+ <target name="testEchoPrefixAsDoublyNegatedPropertyset" depends="setup">
+ <echoproperties destfile="test-prefix.properties">
+ <propertyset negate="true">
+ <propertyset negate="true">
+ <propertyref prefix="a."/>
+ </propertyset>
+ </propertyset>
+ </echoproperties>
+ </target>
+
+ <target name="testWithPrefixAndRegex" depends="setup">
+ <echoproperties prefix="ant." regex=".*ant.*"/>
+ </target>
+
+ <target name="testWithEmptyPrefixAndRegex" depends="setup">
+ <echoproperties prefix="" regex=""/>
+ </target>
+
+ <target name="testWithRegex" depends="setup">
+ <echoproperties regex=".*ant.*"/>
+ </target>
+
+ <target name="cleanup">
+ <delete file="test.properties" failonerror="no" />
+ <delete file="test-prefix.properties" failonerror="no" />
+ <delete file="test.xml" failonerror="no" />
+ </target>
+
+</project>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/i18n/translate/expected/de/template.txt b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/i18n/translate/expected/de/template.txt
new file mode 100644
index 00000000..9a7af4e2
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/i18n/translate/expected/de/template.txt
@@ -0,0 +1 @@
+Diese ist eine Demo Datei für die translate_Aufgabe @missing_token@.
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/i18n/translate/input/resources_ger_DE.properties b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/i18n/translate/input/resources_ger_DE.properties
new file mode 100644
index 00000000..7efe9b0a
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/i18n/translate/input/resources_ger_DE.properties
@@ -0,0 +1,24 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+This=Diese
+is=ist
+a=eine
+demo=Demo
+file=Datei
+#note for people understanding german
+# \u00fc = u umlaut
+for=für
+the=die
+_task=_Aufgabe
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/i18n/translate/input/template.txt b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/i18n/translate/input/template.txt
new file mode 100644
index 00000000..cda413bd
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/i18n/translate/input/template.txt
@@ -0,0 +1 @@
+@This@ @is@ @a@ @demo@ @file@ @for@ @the@ translate@_task@ @missing_token@.
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/i18n/translate/translate.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/i18n/translate/translate.xml
new file mode 100644
index 00000000..e6debd50
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/i18n/translate/translate.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="translate-test" default="test1" basedir=".">
+ <property name="input.dir" value="input"/>
+ <property name="expected.dir" value="expected"/>
+ <import file="../../../../buildfiletest-base.xml"/>
+
+ <target name="setUp">
+ <mkdir dir="${output}/de"/>
+ </target>
+
+ <target name="test1" depends="setUp">
+ <translate toDir="${output}/de"
+ starttoken="@"
+ endtoken="@"
+ bundle="${input.dir}/resources"
+ bundlecountry="DE"
+ bundlelanguage="ger"
+ forceoverwrite="yes"
+ srcencoding="ISO8859_1"
+ destencoding="ISO8859_1"
+ bundleencoding="Cp1252">
+ <fileset dir="${input.dir}">
+ <include name="template.txt"/>
+ </fileset>
+ </translate>
+ </target>
+</project>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/image/image.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/image/image.xml
new file mode 100644
index 00000000..2fefa04c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/image/image.xml
@@ -0,0 +1,73 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<project name="image-test" default="main" basedir=".">
+
+ <import file="../../../buildfiletest-base.xml"/>
+
+ <target name="setUp">
+ <mkdir dir="${output}"/>
+ <property name="src.dir" location="${basedir}/src"/>
+ </target>
+
+ <target name="main" depends="testSimpleScale">
+ </target>
+
+ <!-- this should produce a single file in the dest dir -->
+ <target name="testSimpleScale" depends="setUp">
+ <image includes="*.jpg" srcdir="${src.dir}" destdir="${output}" overwrite="no" failonerror="no">
+ <scale width="300" proportions="width"/>
+ </image>
+ </target>
+
+ <!-- this should put some text in the log -->
+ <target name="testEchoToLog" depends="setUp">
+ <image includes="*.jpg" srcdir="${src.dir}" destdir="${output}" overwrite="no" failonerror="no">
+ <scale width="300" proportions="width"/>
+ </image>
+ </target>
+
+ <!-- this should produce a single file in the dest dir -->
+ <target name="testFailOnError" depends="setUp">
+ <image includes="*.jpg" srcdir="${src.dir}" destdir="${output}" overwrite="no" failonerror="yes">
+ <scale width="300" proportions="width"/>
+ </image>
+ </target>
+
+ <!-- this should produce a single file in the dest dir, overwriting any existing file -->
+ <target name="testOverwriteTrue" depends="setUp">
+ <image includes="*.jpg" srcdir="${src.dir}" destdir="${output}" overwrite="true" failonerror="no">
+ <scale width="300" proportions="width"/>
+ </image>
+ </target>
+
+ <!-- this should not overwrite the existing file -->
+ <target name="testOverwriteFalse" depends="setUp">
+ <image includes="*.jpg" srcdir="${src.dir}" destdir="${output}" overwrite="false" failonerror="no">
+ <scale width="300" proportions="width"/>
+ </image>
+ </target>
+
+ <target name="testSimpleScaleWithMapper" depends="setUp">
+ <image includes="*.jpg" srcdir="${src.dir}"
+ destdir="${output}" overwrite="no" failonerror="no">
+ <scale width="300" proportions="width"/>
+ <globmapper from="*" to="scaled-*"/>
+ </image>
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/image/src/badimage.jpg b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/image/src/badimage.jpg
new file mode 100644
index 00000000..43a786e1
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/image/src/badimage.jpg
Binary files differ
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/image/src/largeimage.jpg b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/image/src/largeimage.jpg
new file mode 100644
index 00000000..91040552
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/image/src/largeimage.jpg
Binary files differ
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/javah/build.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/javah/build.xml
new file mode 100644
index 00000000..ea70b9e5
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/javah/build.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0"?>
+
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="no">
+
+ <import file="../../../buildfiletest-base.xml"/>
+
+ <target name="setUp">
+ <mkdir dir="${output}"/>
+ </target>
+
+ <property name="in" location="input"/>
+
+ <target name="no">
+ <fail>For tests only</fail>
+ </target>
+
+ <target name="compile" depends="setUp">
+ <javac srcdir="${in}" destdir="${output}"/>
+ </target>
+
+ <target name="simple-compile" depends="compile">
+ <javah destdir="${output}">
+ <class name="org.example.Foo"/>
+ <classpath>
+ <pathelement location="${output}"/>
+ </classpath>
+ </javah>
+ </target>
+
+ <target name="test-fileset" depends="compile">
+ <javah destdir="${output}">
+ <fileset dir="${output}">
+ <include name="**/*.class"/>
+ </fileset>
+ <classpath>
+ <pathelement location="${output}"/>
+ </classpath>
+ </javah>
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/javah/input/org/example/Foo.java b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/javah/input/org/example/Foo.java
new file mode 100644
index 00000000..59d03f70
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/javah/input/org/example/Foo.java
@@ -0,0 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.example;
+
+public class Foo {
+
+ public Foo() {}
+
+ public native String bar(Object baz);
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/jdepend/jdepend.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/jdepend/jdepend.xml
new file mode 100644
index 00000000..8418226b
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/jdepend/jdepend.xml
@@ -0,0 +1,70 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project>
+ <property name="testclasses" location="../../../../../../build/testcases"/>
+
+ <path id="all-test-classes.id">
+ <pathelement location="../../../../build/testcases" />
+ <pathelement path="${java.class.path}" />
+ </path>
+
+ <path id="example-classes.id">
+ <pathelement location="${testclasses}/org/apache/tools/ant/util/facade" />
+ </path>
+
+ <path id="test-classes.id">
+ <pathelement location="${testclasses}" />
+ </path>
+
+ <target name="simple">
+ <jdepend>
+ <classespath refid="example-classes.id"/>
+ </jdepend>
+ </target>
+
+ <target name="xml">
+ <jdepend format="xml">
+ <classespath refid="example-classes.id"/>
+ </jdepend>
+ </target>
+
+ <target name="fork">
+ <jdepend fork="yes" includeruntime="yes">
+ <classespath refid="example-classes.id"/>
+ </jdepend>
+ </target>
+
+ <target name="fork-xml">
+ <jdepend fork="yes" format="xml" includeruntime="yes">
+ <classespath refid="example-classes.id"/>
+ </jdepend>
+ </target>
+
+ <target name="fork-timeout">
+ <jdepend fork="yes" timeout="10" includeruntime="yes">
+ <classespath refid="test-classes.id"/>
+ </jdepend>
+ </target>
+
+ <target name="fork-timeout-not">
+ <jdepend fork="yes" timeout="100000" includeruntime="yes">
+ <classespath refid="example-classes.id"/>
+ </jdepend>
+ </target>
+
+</project> \ No newline at end of file
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/jsp/1nvalid-classname.jsp b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/jsp/1nvalid-classname.jsp
new file mode 100644
index 00000000..f5b42e2b
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/jsp/1nvalid-classname.jsp
@@ -0,0 +1,25 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<%@ page language="java" %>
+<html>
+<head/>
+<body>
+
+my name is <%= this.getClass().getName() %>
+
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/jsp/WEB-INF/web.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/jsp/WEB-INF/web.xml
new file mode 100644
index 00000000..2ef199d0
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/jsp/WEB-INF/web.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN"
+ "http://java.sun.com/j2ee/dtds/web-app_2_2.dtd">
+<web-app/>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/jsp/default.jsp b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/jsp/default.jsp
new file mode 100644
index 00000000..c7296b2c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/jsp/default.jsp
@@ -0,0 +1,25 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<%@ page language="java" %>
+<html>
+<head/>
+<body>
+
+It is now <%= System.currentTimeMillis() %>
+
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/jsp/missing_tld.jsp b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/jsp/missing_tld.jsp
new file mode 100644
index 00000000..b837fb1f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/jsp/missing_tld.jsp
@@ -0,0 +1,32 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<%@ page language="java" %>
+<%@ taglib uri="/WEB-INF/tlds/struts-bean.tld" prefix="bean" %>
+<%@ taglib uri="/WEB-INF/tlds/struts-html.tld" prefix="html" %>
+<%@ taglib uri="/WEB-INF/tlds/struts-template.tld" prefix="template" %>
+<html:html locale="true">
+<head>
+<title>shouldnt compile</title>
+<html:base/>
+</head>
+<body>
+
+This page should not compile because refers to TLDs that arent around.
+
+</body>
+
+</html:html>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/jsp/simple.jsp b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/jsp/simple.jsp
new file mode 100644
index 00000000..c7296b2c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/jsp/simple.jsp
@@ -0,0 +1,25 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<%@ page language="java" %>
+<html>
+<head/>
+<body>
+
+It is now <%= System.currentTimeMillis() %>
+
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/jsp/uriroot.jsp b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/jsp/uriroot.jsp
new file mode 100644
index 00000000..c7296b2c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/jsp/uriroot.jsp
@@ -0,0 +1,25 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<%@ page language="java" %>
+<html>
+<head/>
+<body>
+
+It is now <%= System.currentTimeMillis() %>
+
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/jsp/xml.jsp b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/jsp/xml.jsp
new file mode 100644
index 00000000..7bb9e49c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/jsp/xml.jsp
@@ -0,0 +1,32 @@
+<?xml version="1.0" ?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!-- :mode=xml:indentSize=2 -->
+<!-- note the lack of a language setting here. crimson whined when ISO-8859-1 was set,
+ that it thought it was loading a file of type ISO_8859_1 and
+ so there was a mismatch, even though the mismatch is only
+ between hyphen types -->
+<jsp:root
+ xmlns:jsp="http://java.sun.com/JSP/Page"
+ version="1.2"
+ >
+<jsp:directive.page language="java" />
+<jsp:directive.page contentType="application/xml" />
+<timestamp>
+<jsp:expression>System.currentTimeMillis()</jsp:expression>
+</timestamp>
+</jsp:root>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/jspc.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/jspc.xml
new file mode 100644
index 00000000..f1207908
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/jspc.xml
@@ -0,0 +1,133 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<project name="jspc-test" default="main" basedir=".">
+
+ <import file="../../buildfiletest-base.xml"/>
+
+ <target name="setUp">
+ <mkdir dir="${output}"/>
+ <property name="jsp.dir" location="jsp"/>
+ <property name="jsp.output.dir" location="${output}"/>
+ <property name="jsp.verbosity" value="3"/>
+ <property name="jsp.compiler" value="jasper41"/>
+ <mkdir dir="${jsp.output.dir}"/>
+ </target>
+
+ <target name="main" depends="testSimple">
+ </target>
+
+
+ <!-- this should fail -->
+ <!-- it should not create an output file, but it does, which needs
+ cleanup -->
+ <target name="testNoTld" depends="setUp">
+ <jspc
+ destdir="${jsp.output.dir}"
+ srcdir="${jsp.dir}"
+ compiler="${jsp.compiler}"
+ verbose="${jsp.verbosity}">
+ <include
+ name="missing_tld.jsp"/>
+ </jspc>
+ </target>
+
+ <!-- this should compile to simple.java -->
+ <!-- also, stick to the default compiler here to ensure it still works-->
+ <target name="testSimple" depends="setUp">
+ <jspc
+ destdir="${jsp.output.dir}"
+ srcdir="${jsp.dir}"
+ verbose="${jsp.verbosity}">
+ <include
+ name="simple.jsp"/>
+ </jspc>
+ </target>
+
+ <!-- this should compile to uriroot.java -->
+ <target name="testUriroot" depends="setUp">
+ <jspc
+ destdir="${jsp.output.dir}"
+ uriroot="${jsp.dir}"
+ srcdir="${jsp.dir}"
+ compiler="${jsp.compiler}"
+ verbose="${jsp.verbosity}">
+ <include
+ name="uriroot.jsp"/>
+ </jspc>
+ </target>
+
+ <!-- this should compile an xml format jsp page to xml.java -->
+ <target name="testXml" depends="setUp">
+ <jspc
+ destdir="${jsp.output.dir}"
+ uriroot="${jsp.dir}"
+ srcdir="${jsp.dir}"
+ compiler="${jsp.compiler}"
+ verbose="${jsp.verbosity}">
+ <include name="xml.jsp"/>
+ </jspc>
+ </target>
+
+ <!-- this should compile default.jsp to mangled(%default).java -->
+ <target name="testKeyword" depends="setUp">
+ <jspc
+ destdir="${jsp.output.dir}"
+ srcdir="${jsp.dir}"
+ compiler="${jsp.compiler}"
+ verbose="${jsp.verbosity}">
+ <include
+ name="default.jsp"/>
+ </jspc>
+ </target>
+
+ <!-- this should compile default.jsp to mangled(%default).java -->
+ <target name="testInvalidClassname" depends="setUp">
+ <jspc
+ destdir="${jsp.output.dir}"
+ srcdir="${jsp.dir}"
+ compiler="${jsp.compiler}"
+ verbose="${jsp.verbosity}">
+ <include
+ name="1nvalid-classname.jsp"/>
+ </jspc>
+ </target>
+
+ <!-- non jsp pages should be ignored -->
+ <target name="testNotAJspFile" depends="setUp">
+ <jspc
+ destdir="${jsp.output.dir}"
+ srcdir="${jsp.dir}"
+ compiler="${jsp.compiler}"
+ verbose="${jsp.verbosity}">
+ <include
+ name="wrong_type.txt"/>
+ </jspc>
+ </target>
+
+ <!-- test for webapp compilation -->
+ <target name="testWebapp" depends="setUp">
+ <jspc
+ destdir="${jsp.output.dir}"
+ compiler="${jsp.compiler}"
+ verbose="${jsp.verbosity}">
+ <webapp basedir="${jsp.dir}"/>
+ </jspc>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/junit.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/junit.xml
new file mode 100644
index 00000000..cc66e20e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/junit.xml
@@ -0,0 +1,361 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<project name="junit-test" basedir="." default="outputTests">
+ <import file="../../buildfiletest-base.xml"/>
+
+ <target name="setUp">
+ <mkdir dir="${output}" />
+ </target>
+
+ <property name="showoutput" value="false" />
+ <path id="test">
+ <pathelement path="${java.class.path}" />
+ <pathelement location="../../../../../build/testcases" />
+ </path>
+
+ <target name="testForkedOutput">
+ <junit fork="yes" haltonerror="true" haltonfailure="true"
+ showoutput="${showoutput}">
+ <test name="org.example.junit.Output" />
+ <classpath refid="test" />
+ </junit>
+ </target>
+
+ <target name="testNonForkedOutput">
+ <junit fork="false" haltonerror="true" haltonfailure="true"
+ showoutput="${showoutput}">
+ <test name="org.example.junit.Output" />
+ <classpath refid="test" />
+ </junit>
+ </target>
+
+ <target name="testForkedThreadedOutput">
+ <junit fork="yes" haltonerror="true" haltonfailure="true"
+ showoutput="${showoutput}">
+ <test name="org.example.junit.ThreadedOutput" />
+ <classpath refid="test" />
+ </junit>
+ </target>
+
+ <target name="testNonForkedThreadedOutput">
+ <junit fork="false" haltonerror="true" haltonfailure="true"
+ showoutput="${showoutput}">
+ <test name="org.example.junit.ThreadedOutput" />
+ <classpath refid="test" />
+ </junit>
+ </target>
+
+ <target name="outputTests"
+ depends="testForkedOutput,testNonForkedOutput,testForkedThreadedOutput,testNonForkedThreadedOutput" />
+
+ <target name="crash">
+ <junit fork="true" errorproperty="crashed">
+ <test name="org.apache.tools.ant.taskdefs.optional.junit.VmCrash"/>
+ <classpath refid="test" />
+ </junit>
+ </target>
+
+ <target name="nocrash">
+ <junit fork="true" errorproperty="crashed">
+ <test name="org.apache.tools.ant.taskdefs.optional.junit.NoVmCrash"/>
+ <classpath refid="test" />
+ </junit>
+ </target>
+
+ <target name="timeout">
+ <junit fork="true" errorproperty="timeout" timeout="1000">
+ <test name="org.apache.tools.ant.taskdefs.optional.junit.Sleeper"/>
+ <classpath refid="test" />
+ </junit>
+ </target>
+
+ <target name="notimeout">
+ <junit fork="true" errorproperty="timeout" timeout="15000">
+ <test name="org.apache.tools.ant.taskdefs.optional.junit.Sleeper"/>
+ <classpath refid="test" />
+ </junit>
+ </target>
+
+ <target name="capture" depends="setUp">
+ <property name="fork" value="false"/>
+ <junit fork="${fork}">
+ <test
+ name="org.apache.tools.ant.taskdefs.optional.junit.Printer"
+ todir="${output}"
+ outfile="testlog"/>
+ <formatter type="plain"/>
+ <classpath refid="test"/>
+ </junit>
+ </target>
+
+ <target name="captureToSummary">
+ <property name="fork" value="true"/>
+ <property name="enableEvents" value="false"/>
+ <junit fork="${fork}" printSummary="withOutAndErr"
+ enableTestListenerEvents="${enableEvents}">
+ <test name="org.apache.tools.ant.taskdefs.optional.junit.Printer"/>
+ <classpath refid="test"/>
+ </junit>
+ </target>
+
+ <target name="testBatchTestForkOnceToDir" depends="setUp">
+ <junit fork="true" forkmode="once">
+ <formatter type="xml"/>
+ <classpath refid="test"/>
+ <batchtest todir="${output}">
+ <fileset dir="../../../../tests/junit">
+ <include
+ name="org/apache/tools/ant/taskdefs/optional/junit/*Test.java"/>
+ <!-- tests remove out-dir on tearDown -->
+ <exclude name="**/JUnitTestListenerTest.java"/>
+ <exclude name="**/JUnitTaskTest.java"/>
+ <exclude name="**/JUnitReportTest.java"/>
+ </fileset>
+ </batchtest>
+ </junit>
+ </target>
+
+ <!-- Bugzilla Report 32973 -->
+ <target name="testBatchTestForkOnceExtension">
+ <mkdir dir="${output}"/>
+ <junit fork="true" forkmode="once">
+ <formatter type="xml" extension=".foo"/>
+ <classpath refid="test"/>
+ <batchtest todir="${output}">
+ <fileset dir="../../../../tests/junit">
+ <include
+ name="org/apache/tools/ant/taskdefs/optional/junit/*Test.java"/>
+ <!-- tests remove out-dir on tearDown -->
+ <exclude name="**/JUnitTestListenerTest.java"/>
+ <exclude name="**/JUnitTaskTest.java"/>
+ <exclude name="**/JUnitReportTest.java"/>
+ </fileset>
+ </batchtest>
+ </junit>
+ </target>
+
+ <target name="testBatchTestForkOnceCustomFormatter">
+ <mkdir dir="${output}"/>
+ <junit fork="true" forkmode="once">
+ <formatter extension="foo"
+ classname="org.apache.tools.ant.taskdefs.optional.junit.TestFormatter"/>
+ <classpath refid="test"/>
+ <batchtest todir="${output}">
+ <fileset dir="../../../../tests/junit">
+ <include
+ name="org/apache/tools/ant/taskdefs/optional/junit/*Test.java"/>
+ <!-- tests remove out-dir on tearDown -->
+ <exclude name="**/JUnitTestListenerTest.java"/>
+ <exclude name="**/JUnitTaskTest.java"/>
+ <exclude name="**/JUnitReportTest.java"/>
+ </fileset>
+ </batchtest>
+ </junit>
+ </target>
+
+ <target name="failureRecorder.prepare">
+ <property name="tmp.dir" value="${output}"/>
+ <mkdir dir="${tmp.dir}/org"/>
+ <echo file="${tmp.dir}/A.java">
+ import junit.framework.*;
+ public class A extends TestCase {
+ public A(String s) { super(s); }
+ public void test01() { System.out.println("A.test01"); }
+ public void test02() { System.out.println("A.test02"); fail(); }
+ public void test03() { System.out.println("A.test03"); fail(); }
+ }
+ </echo>
+ <echo file="${tmp.dir}/B.java">
+ import junit.framework.*;
+ public class B extends TestCase {
+ public B(String s) { super(s); }
+ public void test04() { System.out.println("B.test04"); fail(); }
+ public void test05() { System.out.println("B.test05"); }
+ public void test06() { System.out.println("B.test06"); }
+ }
+ </echo>
+ <echo file="${tmp.dir}/C.java">
+ import junit.framework.*;
+ public class C extends TestCase {
+ public C(String s) { super(s); }
+ public void test07() { System.out.println("C.test07"); }
+ public void test08() { System.out.println("C.test08"); }
+ public void test09() { System.out.println("C.test09"); }
+ }
+ </echo>
+ <echo file="${tmp.dir}/org/D.java">
+ package org;
+ import junit.framework.*;
+ public class D extends TestCase {
+ public D(String s) { super(s); }
+ public void test10() { System.out.println("D.test10"); fail(); }
+ }
+ </echo>
+ <javac srcdir="${tmp.dir}" destdir="${tmp.dir}"/>
+ </target>
+
+ <target name="failureRecorder.internal">
+ <property name="tmp.dir" value="${output}"/>
+ <delete>
+ <fileset dir="${tmp.dir}" includes="FailedTests*.class"/>
+ </delete>
+ <!-- compile the FailedTests class if present -->
+ <javac srcdir="${tmp.dir}" destdir="${tmp.dir}"/>
+ <available file="${tmp.dir}/FailedTests.class" property="hasFailingTests"/>
+
+ <property name="ant.junit.failureCollector" value="${tmp.dir}/FailedTests"/>
+ <junit haltonerror="false" haltonfailure="false">
+ <classpath>
+ <pathelement location="${tmp.dir}"/>
+ </classpath>
+ <batchtest todir="${tmp.dir}" unless="hasFailingTests">
+ <fileset dir="${tmp.dir}" includes="**/*.java" excludes="**/FailedTests.*"/>
+ <!-- for initial creation of the FailingTests.java -->
+ <formatter type="failure"/>
+ <!-- I want to see something ... -->
+ <formatter type="plain" usefile="false"/>
+ </batchtest>
+ <test name="FailedTests" if="hasFailingTests" todir="${tmp.dir}">
+ <!-- update the FailingTests.java -->
+ <formatter type="failure"/>
+ <!-- again, I want to see something -->
+ <formatter type="plain" usefile="false"/>
+ </test>
+ </junit>
+ </target>
+
+ <target name="failureRecorder.runtest">
+ <ant target="failureRecorder.internal"
+ antfile="junit.xml"
+ inheritAll="false"
+ inheritRefs="false"
+ />
+ </target>
+
+ <target name="failureRecorder.fixing">
+ <property name="tmp.dir" value="${output}"/>
+ <echo file="${tmp.dir}/A.java">
+ import junit.framework.*;
+ public class A extends TestCase {
+ public A(String s) { super(s); }
+ public void test01() { System.out.println("A.test01"); }
+ public void test02() { System.out.println("A.test02"); }
+ public void test03() { System.out.println("A.test03"); }
+ }
+ </echo>
+ </target>
+
+ <!-- Bugzilla Issue 45411 -->
+ <target name="testMultilineAssertsNoFork">
+ <junit>
+ <test name="org.example.junit.MultilineAsserts"/>
+ <classpath refid="test"/>
+ </junit>
+ </target>
+
+ <!-- Bugzilla Issue 45411 -->
+ <target name="testMultilineAssertsFork">
+ <junit fork="true">
+ <test name="org.example.junit.MultilineAsserts"/>
+ <classpath refid="test"/>
+ </junit>
+ </target>
+
+ <!-- JUnit4 Ignore and Assume for skipping tests -->
+ <target name="testSkippableTests">
+ <mkdir dir="${output}"/>
+ <junit>
+ <formatter type="xml"/>
+ <classpath refid="test"/>
+ <batchtest todir="${output}">
+ <fileset dir="../../../../tests/junit">
+ <include name="org/example/junit/JUnit4Skippable.java"/>
+ <!-- tests remove out-dir on tearDown -->
+ </fileset>
+ </batchtest>
+ </junit>
+ </target>
+
+
+ <!-- Skipping classes that are not tests -->
+ <target name="testNonTests">
+ <mkdir dir="${output}"/>
+ <junit>
+ <formatter type="xml"/>
+ <classpath refid="test"/>
+ <batchtest todir="${output}" skipNonTests="true">
+ <fileset dir="../../../../tests/junit">
+ <include name="org/example/junit/*Missed.java"/>
+ <!-- tests remove out-dir on tearDown -->
+ </fileset>
+ </batchtest>
+ </junit>
+ </target>
+
+ <!-- Not skipping classes that are not tests -->
+ <target name="testNonTestsRun">
+ <mkdir dir="${output}"/>
+ <junit>
+ <formatter type="xml"/>
+ <classpath refid="test"/>
+ <batchtest todir="${output}" skipNonTests="false">
+ <fileset dir="../../../../tests/junit">
+ <include name="org/example/junit/*Missed.java"/>
+ <!-- tests remove out-dir on tearDown -->
+ </fileset>
+ </batchtest>
+ </junit>
+ </target>
+
+ <target name="testTestMethods" >
+ <property name="tmp.dir" value="${output}"/>
+ <echo file="${tmp.dir}/T1.java">public class T1 extends
+ junit.framework.TestCase {
+ public void testOK() {}
+ public void testBad() {throw new RuntimeException("failed");}
+ }</echo>
+ <echo file="${tmp.dir}/T2.java">
+ import org.junit.Test;
+ public class T2 {
+ @Test
+ public void ok() {}
+ @Test
+ public void bad() {
+ throw new RuntimeException("failed");}
+ }</echo>
+ <available property="jdk1.6+" classname="java.net.CookieStore"/>
+ <condition property="source" value="6">
+ <isset property="jdk1.6+"/>
+ </condition>
+ <property name="source" value="5"/>
+ <javac srcdir="${tmp.dir}" destdir="${tmp.dir}" includes="T1.java,T2.java"
+ source="${source}">
+
+ </javac>
+ <junit fork="false" printsummary="true" haltonerror="true">
+ <classpath>
+ <pathelement location="${tmp.dir}" />
+ <path refid="test" />
+ </classpath>
+ <test name="T1" methods="testOK" />
+ <test name="T2" methods="ok" />
+ </junit>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/junit/cdataoutput.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/junit/cdataoutput.xml
new file mode 100644
index 00000000..ab5409b3
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/junit/cdataoutput.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project basedir=".">
+ <target name="run-junit">
+ <junit fork="true">
+ <classpath path="${tests-classpath.value}"/>
+ <sysproperty key="cdata.inner" value="true"/>
+ <test
+ name="org.apache.tools.ant.taskdefs.optional.junit.XMLFormatterWithCDATAOnSystemOut"/>
+ <formatter type="xml"/>
+ </junit>
+ </target>
+</project> \ No newline at end of file
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/junit/matches.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/junit/matches.xml
new file mode 100644
index 00000000..2451cf89
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/junit/matches.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<matches>
+ <foo>
+ <abc>
+ <foo/>
+ <foo/>
+ </abc>
+ </foo>
+</matches> \ No newline at end of file
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/junit/teardownlistener.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/junit/teardownlistener.xml
new file mode 100644
index 00000000..abb6a410
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/junit/teardownlistener.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project>
+
+ <path id="test">
+ <pathelement path="${java.class.path}" />
+ <pathelement location="../../../../../../build/testcases" />
+ </path>
+
+ <target name="testNoTeardown">
+ <junit haltonerror="false" errorproperty="error" fork="true" timeout="1000">
+ <formatter type="plain" usefile="false"/>
+ <batchtest>
+ <fileset dir="../../../../../../build/testcases">
+ <include name="org/example/junit/Timeout*"/>
+ </fileset>
+ </batchtest>
+ <classpath refid="test"/>
+ </junit>
+ </target>
+
+ <target name="testTeardown">
+ <junit haltonerror="false" errorproperty="error" fork="true" timeout="1000">
+ <formatter type="plain" usefile="false"/>
+ <formatter classname="org.apache.tools.ant.taskdefs.optional.junit.TearDownOnVmCrash"
+ usefile="false"/>
+ <batchtest>
+ <fileset dir="../../../../../../build/testcases">
+ <include name="org/example/junit/Timeout*"/>
+ </fileset>
+ </batchtest>
+ <classpath refid="test"/>
+ </junit>
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/junitreport-with-include/junit-frames.xsl b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/junitreport-with-include/junit-frames.xsl
new file mode 100644
index 00000000..3c0d85aa
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/junitreport-with-include/junit-frames.xsl
@@ -0,0 +1,879 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
+ xmlns:lxslt="http://xml.apache.org/xslt"
+ xmlns:redirect="http://xml.apache.org/xalan/redirect"
+ xmlns:stringutils="xalan://org.apache.tools.ant.util.StringUtils"
+ extension-element-prefixes="redirect">
+<xsl:import href="junit-import.xsl"/>
+<xsl:output method="html" indent="yes" encoding="US-ASCII"/>
+<xsl:decimal-format decimal-separator="." grouping-separator=","/>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<!--
+
+ Sample stylesheet to be used with Ant JUnitReport output.
+
+ It creates a set of HTML files a la javadoc where you can browse easily
+ through all packages and classes.
+
+-->
+<xsl:param name="output.dir" select="'.'"/>
+<xsl:param name="key1" select="'defaultValue1'"/>
+<xsl:param name="key2" select="'defaultValue2'"/>
+
+<xsl:template match="testsuites">
+ <!-- create the index.html -->
+ <redirect:write file="{$output.dir}/index.html">
+ <xsl:call-template name="index.html"/>
+ </redirect:write>
+
+ <!-- create the stylesheet.css -->
+ <redirect:write file="{$output.dir}/stylesheet.css">
+ <xsl:call-template name="stylesheet.css"/>
+ </redirect:write>
+
+ <!-- create the overview-packages.html at the root -->
+ <redirect:write file="{$output.dir}/overview-summary.html">
+ <xsl:apply-templates select="." mode="overview.packages"/>
+ </redirect:write>
+
+ <!-- create the all-packages.html at the root -->
+ <redirect:write file="{$output.dir}/overview-frame.html">
+ <xsl:apply-templates select="." mode="all.packages"/>
+ </redirect:write>
+
+ <!-- create the all-classes.html at the root -->
+ <redirect:write file="{$output.dir}/allclasses-frame.html">
+ <xsl:apply-templates select="." mode="all.classes"/>
+ </redirect:write>
+
+ <!-- create the all-tests.html at the root -->
+ <redirect:write file="{$output.dir}/all-tests.html">
+ <xsl:apply-templates select="." mode="all.tests"/>
+ </redirect:write>
+
+ <!-- create the alltests-fails.html at the root -->
+ <redirect:write file="{$output.dir}/alltests-fails.html">
+ <xsl:apply-templates select="." mode="all.tests">
+ <xsl:with-param name="type" select="'fails'"/>
+ </xsl:apply-templates>
+ </redirect:write>
+
+ <!-- create the alltests-errors.html at the root -->
+ <redirect:write file="{$output.dir}/alltests-errors.html">
+ <xsl:apply-templates select="." mode="all.tests">
+ <xsl:with-param name="type" select="'errors'"/>
+ </xsl:apply-templates>
+ </redirect:write>
+
+ <!-- process all packages -->
+ <xsl:for-each select="./testsuite[not(./@package = preceding-sibling::testsuite/@package)]">
+ <xsl:call-template name="package">
+ <xsl:with-param name="name" select="@package"/>
+ </xsl:call-template>
+ </xsl:for-each>
+</xsl:template>
+ <xsl:template name="package">
+ <xsl:param name="name"/>
+ <xsl:variable name="package.dir">
+ <xsl:if test="not($name = '')"><xsl:value-of select="translate($name,'.','/')"/></xsl:if>
+ <xsl:if test="$name = ''">.</xsl:if>
+ </xsl:variable>
+ <!--Processing package <xsl:value-of select="@name"/> in <xsl:value-of select="$output.dir"/> -->
+ <!-- create a classes-list.html in the package directory -->
+ <redirect:write file="{$output.dir}/{$package.dir}/package-frame.html">
+ <xsl:call-template name="classes.list">
+ <xsl:with-param name="name" select="$name"/>
+ </xsl:call-template>
+ </redirect:write>
+
+ <!-- create a package-summary.html in the package directory -->
+ <redirect:write file="{$output.dir}/{$package.dir}/package-summary.html">
+ <xsl:call-template name="package.summary">
+ <xsl:with-param name="name" select="$name"/>
+ </xsl:call-template>
+ </redirect:write>
+
+ <!-- for each class, creates a @name.html -->
+ <!-- @bug there will be a problem with inner classes having the same name, it will be overwritten -->
+ <xsl:for-each select="/testsuites/testsuite[@package = $name]">
+ <redirect:write file="{$output.dir}/{$package.dir}/{@id}_{@name}.html">
+ <xsl:apply-templates select="." mode="class.details"/>
+ </redirect:write>
+ <xsl:if test="string-length(./system-out)!=0">
+ <redirect:write file="{$output.dir}/{$package.dir}/{@id}_{@name}-out.txt">
+ <xsl:value-of disable-output-escaping="yes" select="./system-out"/>
+ </redirect:write>
+ </xsl:if>
+ <xsl:if test="string-length(./system-err)!=0">
+ <redirect:write file="{$output.dir}/{$package.dir}/{@id}_{@name}-err.txt">
+ <xsl:value-of disable-output-escaping="yes" select="./system-err"/>
+ </redirect:write>
+ </xsl:if>
+ <xsl:if test="@failures != 0">
+ <redirect:write file="{$output.dir}/{$package.dir}/{@id}_{@name}-fails.html">
+ <xsl:apply-templates select="." mode="class.details">
+ <xsl:with-param name="type" select="'fails'"/>
+ </xsl:apply-templates>
+ </redirect:write>
+ </xsl:if>
+ <xsl:if test="@errors != 0">
+ <redirect:write file="{$output.dir}/{$package.dir}/{@id}_{@name}-errors.html">
+ <xsl:apply-templates select="." mode="class.details">
+ <xsl:with-param name="type" select="'errors'"/>
+ </xsl:apply-templates>
+ </redirect:write>
+ </xsl:if>
+ </xsl:for-each>
+ </xsl:template>
+
+
+<xsl:template name="index.html">
+<html>
+ <head>
+ <title>
+ Unit Test Results. key1=<xsl:value-of select="$key1"/>,key2=<xsl:value-of select="$key2"/>
+ </title>
+ </head>
+ <frameset cols="20%,80%">
+ <frameset rows="30%,70%">
+ <frame src="overview-frame.html" name="packageListFrame"/>
+ <frame src="allclasses-frame.html" name="classListFrame"/>
+ </frameset>
+ <frame src="overview-summary.html" name="classFrame"/>
+ <noframes>
+ <h2>Frame Alert</h2>
+ <p>
+ This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client.
+ </p>
+ </noframes>
+ </frameset>
+</html>
+</xsl:template>
+
+<!-- this is the stylesheet css to use for nearly everything -->
+<xsl:template name="stylesheet.css">
+body {
+ font:normal 68% verdana,arial,helvetica;
+ color:#000000;
+}
+table tr td, table tr th {
+ font-size: 68%;
+}
+table.details tr th{
+ font-weight: bold;
+ text-align:left;
+ background:#a6caf0;
+}
+table.details tr td{
+ background:#eeeee0;
+}
+
+p {
+ line-height:1.5em;
+ margin-top:0.5em; margin-bottom:1.0em;
+}
+h1 {
+ margin: 0px 0px 5px; font: 165% verdana,arial,helvetica
+}
+h2 {
+ margin-top: 1em; margin-bottom: 0.5em; font: bold 125% verdana,arial,helvetica
+}
+h3 {
+ margin-bottom: 0.5em; font: bold 115% verdana,arial,helvetica
+}
+h4 {
+ margin-bottom: 0.5em; font: bold 100% verdana,arial,helvetica
+}
+h5 {
+ margin-bottom: 0.5em; font: bold 100% verdana,arial,helvetica
+}
+h6 {
+ margin-bottom: 0.5em; font: bold 100% verdana,arial,helvetica
+}
+.Error {
+ font-weight:bold; color:red;
+}
+.Failure {
+ font-weight:bold; color:purple;
+}
+.Properties {
+ text-align:right;
+}
+</xsl:template>
+
+<!-- Create list of all/failed/errored tests -->
+<xsl:template match="testsuites" mode="all.tests">
+ <xsl:param name="type" select="'all'"/>
+ <html>
+ <xsl:variable name="title">
+ <xsl:choose>
+ <xsl:when test="$type = 'fails'">
+ <xsl:text>All Failures</xsl:text>
+ </xsl:when>
+ <xsl:when test="$type = 'errors'">
+ <xsl:text>All Errors</xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>All Tests</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <head>
+ <title>Unit Test Results: <xsl:value-of select="$title"/></title>
+ <xsl:call-template name="create.stylesheet.link">
+ <xsl:with-param name="package.name"/>
+ </xsl:call-template>
+ </head>
+ <body>
+ <xsl:attribute name="onload">open('allclasses-frame.html','classListFrame')</xsl:attribute>
+ <xsl:call-template name="pageHeader"/>
+ <h2><xsl:value-of select="$title"/></h2>
+
+ <table class="details" border="0" cellpadding="5" cellspacing="2" width="95%">
+ <xsl:call-template name="testcase.test.header">
+ <xsl:with-param name="show.class" select="'yes'"/>
+ </xsl:call-template>
+ <!--
+ test can even not be started at all (failure to load the class)
+ so report the error directly
+ -->
+ <xsl:if test="./error">
+ <tr class="Error">
+ <td colspan="4">
+ <xsl:apply-templates select="./error"/>
+ </td>
+ </tr>
+ </xsl:if>
+ <xsl:choose>
+ <xsl:when test="$type = 'fails'">
+ <xsl:apply-templates select=".//testcase[failure]" mode="print.test">
+ <xsl:with-param name="show.class" select="'yes'"/>
+ </xsl:apply-templates>
+ </xsl:when>
+ <xsl:when test="$type = 'errors'">
+ <xsl:apply-templates select=".//testcase[error]" mode="print.test">
+ <xsl:with-param name="show.class" select="'yes'"/>
+ </xsl:apply-templates>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:apply-templates select=".//testcase" mode="print.test">
+ <xsl:with-param name="show.class" select="'yes'"/>
+ </xsl:apply-templates>
+ </xsl:otherwise>
+ </xsl:choose>
+ </table>
+ </body>
+ </html>
+</xsl:template>
+
+
+<!-- ======================================================================
+ This page is created for every testsuite class.
+ It prints a summary of the testsuite and detailed information about
+ testcase methods.
+ ====================================================================== -->
+<xsl:template match="testsuite" mode="class.details">
+ <xsl:param name="type" select="'all'"/>
+ <xsl:variable name="package.name" select="@package"/>
+ <xsl:variable name="class.name"><xsl:if test="not($package.name = '')"><xsl:value-of select="$package.name"/>.</xsl:if><xsl:value-of select="@name"/></xsl:variable>
+ <html>
+ <head>
+ <title>Unit Test Results: <xsl:value-of select="$class.name"/></title>
+ <xsl:call-template name="create.stylesheet.link">
+ <xsl:with-param name="package.name" select="$package.name"/>
+ </xsl:call-template>
+ <script type="text/javascript" language="JavaScript">
+ var TestCases = new Array();
+ var cur;
+ <xsl:apply-templates select="properties"/>
+ </script>
+ <script type="text/javascript" language="JavaScript"><![CDATA[
+ function displayProperties (name) {
+ var win = window.open('','JUnitSystemProperties','scrollbars=1,resizable=1');
+ var doc = win.document;
+ doc.open();
+ doc.write("<html><head><title>Properties of " + name + "</title>");
+ doc.write("<style type=\"text/css\">");
+ doc.write("body {font:normal 68% verdana,arial,helvetica; color:#000000; }");
+ doc.write("table tr td, table tr th { font-size: 68%; }");
+ doc.write("table.properties { border-collapse:collapse; border-left:solid 1 #cccccc; border-top:solid 1 #cccccc; padding:5px; }");
+ doc.write("table.properties th { text-align:left; border-right:solid 1 #cccccc; border-bottom:solid 1 #cccccc; background-color:#eeeeee; }");
+ doc.write("table.properties td { font:normal; text-align:left; border-right:solid 1 #cccccc; border-bottom:solid 1 #cccccc; background-color:#fffffff; }");
+ doc.write("h3 { margin-bottom: 0.5em; font: bold 115% verdana,arial,helvetica }");
+ doc.write("</style>");
+ doc.write("</head><body>");
+ doc.write("<h3>Properties of " + name + "</h3>");
+ doc.write("<div align=\"right\"><a href=\"javascript:window.close();\">Close</a></div>");
+ doc.write("<table class='properties'>");
+ doc.write("<tr><th>Name</th><th>Value</th></tr>");
+ for (prop in TestCases[name]) {
+ doc.write("<tr><th>" + prop + "</th><td>" + TestCases[name][prop] + "</td></tr>");
+ }
+ doc.write("</table>");
+ doc.write("</body></html>");
+ doc.close();
+ win.focus();
+ }
+ ]]>
+ </script>
+ </head>
+ <body>
+ <xsl:call-template name="pageHeader"/>
+ <h3>Class <xsl:value-of select="$class.name"/></h3>
+
+
+ <table class="details" border="0" cellpadding="5" cellspacing="2" width="95%">
+ <xsl:call-template name="testsuite.test.header"/>
+ <xsl:apply-templates select="." mode="print.test"/>
+ </table>
+
+ <xsl:choose>
+ <xsl:when test="$type = 'fails'">
+ <h2>Failures</h2>
+ </xsl:when>
+ <xsl:when test="$type = 'errors'">
+ <h2>Errors</h2>
+ </xsl:when>
+ <xsl:otherwise>
+ <h2>Tests</h2>
+ </xsl:otherwise>
+ </xsl:choose>
+ <table class="details" border="0" cellpadding="5" cellspacing="2" width="95%">
+ <xsl:call-template name="testcase.test.header"/>
+ <!--
+ test can even not be started at all (failure to load the class)
+ so report the error directly
+ -->
+ <xsl:if test="./error">
+ <tr class="Error">
+ <td colspan="4"><xsl:apply-templates select="./error"/></td>
+ </tr>
+ </xsl:if>
+ <xsl:choose>
+ <xsl:when test="$type = 'fails'">
+ <xsl:apply-templates select="./testcase[failure]" mode="print.test"/>
+ </xsl:when>
+ <xsl:when test="$type = 'errors'">
+ <xsl:apply-templates select="./testcase[error]" mode="print.test"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:apply-templates select="./testcase" mode="print.test"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </table>
+ <div class="Properties">
+ <a>
+ <xsl:attribute name="href">javascript:displayProperties('<xsl:value-of select="@package"/>.<xsl:value-of select="@name"/>');</xsl:attribute>
+ Properties &#187;
+ </a>
+ </div>
+ <xsl:if test="string-length(./system-out)!=0">
+ <div class="Properties">
+ <a>
+ <xsl:attribute name="href">./<xsl:value-of select="@id"/>_<xsl:value-of select="@name"/>-out.txt</xsl:attribute>
+ System.out &#187;
+ </a>
+ </div>
+ </xsl:if>
+ <xsl:if test="string-length(./system-err)!=0">
+ <div class="Properties">
+ <a>
+ <xsl:attribute name="href">./<xsl:value-of select="@id"/>_<xsl:value-of select="@name"/>-err.txt</xsl:attribute>
+ System.err &#187;
+ </a>
+ </div>
+ </xsl:if>
+ </body>
+ </html>
+</xsl:template>
+
+ <!--
+ Write properties into a JavaScript data structure.
+ This is based on the original idea by Erik Hatcher (ehatcher@apache.org)
+ -->
+ <xsl:template match="properties">
+ cur = TestCases['<xsl:value-of select="../@package"/>.<xsl:value-of select="../@name"/>'] = new Array();
+ <xsl:for-each select="property">
+ <xsl:sort select="@name"/>
+ cur['<xsl:value-of select="@name"/>'] = '<xsl:call-template name="JS-escape"><xsl:with-param name="string" select="@value"/></xsl:call-template>';
+ </xsl:for-each>
+ </xsl:template>
+
+
+<!-- ======================================================================
+ This page is created for every package.
+ It prints the name of all classes that belongs to this package.
+ @param name the package name to print classes.
+ ====================================================================== -->
+<!-- list of classes in a package -->
+<xsl:template name="classes.list">
+ <xsl:param name="name"/>
+ <html>
+ <head>
+ <title>Unit Test Classes: <xsl:value-of select="$name"/></title>
+ <xsl:call-template name="create.stylesheet.link">
+ <xsl:with-param name="package.name" select="$name"/>
+ </xsl:call-template>
+ </head>
+ <body>
+ <table width="100%">
+ <tr>
+ <td nowrap="nowrap">
+ <h2><a href="package-summary.html" target="classFrame">
+ <xsl:value-of select="$name"/>
+ <xsl:if test="$name = ''">&lt;none&gt;</xsl:if>
+ </a></h2>
+ </td>
+ </tr>
+ </table>
+
+ <h2>Classes</h2>
+ <table width="100%">
+ <xsl:for-each select="/testsuites/testsuite[./@package = $name]">
+ <xsl:sort select="@name"/>
+ <tr>
+ <td nowrap="nowrap">
+ <a href="{@id}_{@name}.html" target="classFrame"><xsl:value-of select="@name"/></a>
+ </td>
+ </tr>
+ </xsl:for-each>
+ </table>
+ </body>
+ </html>
+</xsl:template>
+
+
+<!--
+ Creates an all-classes.html file that contains a link to all package-summary.html
+ on each class.
+-->
+<xsl:template match="testsuites" mode="all.classes">
+ <html>
+ <head>
+ <title>All Unit Test Classes</title>
+ <xsl:call-template name="create.stylesheet.link">
+ <xsl:with-param name="package.name"/>
+ </xsl:call-template>
+ </head>
+ <body>
+ <h2>Classes</h2>
+ <table width="100%">
+ <xsl:apply-templates select="testsuite" mode="all.classes">
+ <xsl:sort select="@name"/>
+ </xsl:apply-templates>
+ </table>
+ </body>
+ </html>
+</xsl:template>
+
+<xsl:template match="testsuite" mode="all.classes">
+ <xsl:variable name="package.name" select="@package"/>
+ <tr>
+ <td nowrap="nowrap">
+ <a target="classFrame">
+ <xsl:attribute name="href">
+ <xsl:if test="not($package.name='')">
+ <xsl:value-of select="translate($package.name,'.','/')"/><xsl:text>/</xsl:text>
+ </xsl:if><xsl:value-of select="@id"/>_<xsl:value-of select="@name"/><xsl:text>.html</xsl:text>
+ </xsl:attribute>
+ <xsl:value-of select="@name"/>
+ </a>
+ </td>
+ </tr>
+</xsl:template>
+
+
+<!--
+ Creates an html file that contains a link to all package-summary.html files on
+ each package existing on testsuites.
+ @bug there will be a problem here, I don't know yet how to handle unnamed package :(
+-->
+<xsl:template match="testsuites" mode="all.packages">
+ <html>
+ <head>
+ <title>All Unit Test Packages</title>
+ <xsl:call-template name="create.stylesheet.link">
+ <xsl:with-param name="package.name"/>
+ </xsl:call-template>
+ </head>
+ <body>
+ <h2><a href="overview-summary.html" target="classFrame">Home</a></h2>
+ <h2>Packages</h2>
+ <table width="100%">
+ <xsl:apply-templates select="testsuite[not(./@package = preceding-sibling::testsuite/@package)]" mode="all.packages">
+ <xsl:sort select="@package"/>
+ </xsl:apply-templates>
+ </table>
+ </body>
+ </html>
+</xsl:template>
+
+<xsl:template match="testsuite" mode="all.packages">
+ <tr>
+ <td nowrap="nowrap">
+ <a href="./{translate(@package,'.','/')}/package-summary.html" target="classFrame">
+ <xsl:value-of select="@package"/>
+ <xsl:if test="@package = ''">&lt;none&gt;</xsl:if>
+ </a>
+ </td>
+ </tr>
+</xsl:template>
+
+
+<xsl:template match="testsuites" mode="overview.packages">
+ <html>
+ <head>
+ <title>Unit Test Results: Summary</title>
+ <xsl:call-template name="create.stylesheet.link">
+ <xsl:with-param name="package.name"/>
+ </xsl:call-template>
+ </head>
+ <body>
+ <xsl:attribute name="onload">open('allclasses-frame.html','classListFrame')</xsl:attribute>
+ <xsl:call-template name="pageHeader"/>
+ <h2>Summary</h2>
+ <xsl:variable name="testCount" select="sum(testsuite/@tests)"/>
+ <xsl:variable name="errorCount" select="sum(testsuite/@errors)"/>
+ <xsl:variable name="failureCount" select="sum(testsuite/@failures)"/>
+ <xsl:variable name="timeCount" select="sum(testsuite/@time)"/>
+ <xsl:variable name="successRate" select="($testCount - $failureCount - $errorCount) div $testCount"/>
+ <table class="details" border="0" cellpadding="5" cellspacing="2" width="95%">
+ <tr valign="top">
+ <th>Tests</th>
+ <th>Failures</th>
+ <th>Errors</th>
+ <th>Success rate</th>
+ <th>Time</th>
+ </tr>
+ <tr valign="top">
+ <xsl:attribute name="class">
+ <xsl:choose>
+ <xsl:when test="$errorCount &gt; 0">Error</xsl:when>
+ <xsl:when test="$failureCount &gt; 0">Failure</xsl:when>
+ <xsl:otherwise>Pass</xsl:otherwise>
+ </xsl:choose>
+ </xsl:attribute>
+ <td><a title="Display all tests" href="all-tests.html"><xsl:value-of select="$testCount"/></a></td>
+ <td><a title="Display all failures" href="alltests-fails.html"><xsl:value-of select="$failureCount"/></a></td>
+ <td><a title="Display all errors" href="alltests-errors.html"><xsl:value-of select="$errorCount"/></a></td>
+ <td>
+ <xsl:call-template name="display-percent">
+ <xsl:with-param name="value" select="$successRate"/>
+ </xsl:call-template>
+ </td>
+ <td>
+ <xsl:call-template name="display-time">
+ <xsl:with-param name="value" select="$timeCount"/>
+ </xsl:call-template>
+ </td>
+ </tr>
+ </table>
+ <table border="0" width="95%">
+ <tr>
+ <td style="text-align: justify;">
+ Note: <em>failures</em> are anticipated and checked for with assertions while <em>errors</em> are unanticipated.
+ </td>
+ </tr>
+ </table>
+
+ <h2>Packages</h2>
+ <table class="details" border="0" cellpadding="5" cellspacing="2" width="95%">
+ <xsl:call-template name="testsuite.test.header"/>
+ <xsl:for-each select="testsuite[not(./@package = preceding-sibling::testsuite/@package)]">
+ <xsl:sort select="@package" order="ascending"/>
+ <!-- get the node set containing all testsuites that have the same package -->
+ <xsl:variable name="insamepackage" select="/testsuites/testsuite[./@package = current()/@package]"/>
+ <tr valign="top">
+ <!-- display a failure if there is any failure/error in the package -->
+ <xsl:attribute name="class">
+ <xsl:choose>
+ <xsl:when test="sum($insamepackage/@errors) &gt; 0">Error</xsl:when>
+ <xsl:when test="sum($insamepackage/@failures) &gt; 0">Failure</xsl:when>
+ <xsl:otherwise>Pass</xsl:otherwise>
+ </xsl:choose>
+ </xsl:attribute>
+ <td><a href="./{translate(@package,'.','/')}/package-summary.html">
+ <xsl:value-of select="@package"/>
+ <xsl:if test="@package = ''">&lt;none&gt;</xsl:if>
+ </a></td>
+ <td><xsl:value-of select="sum($insamepackage/@tests)"/></td>
+ <td><xsl:value-of select="sum($insamepackage/@errors)"/></td>
+ <td><xsl:value-of select="sum($insamepackage/@failures)"/></td>
+ <td>
+ <xsl:call-template name="display-time">
+ <xsl:with-param name="value" select="sum($insamepackage/@time)"/>
+ </xsl:call-template>
+ </td>
+ <td><xsl:value-of select="$insamepackage/@timestamp"/></td>
+ <td><xsl:value-of select="$insamepackage/@hostname"/></td>
+ </tr>
+ </xsl:for-each>
+ </table>
+ </body>
+ </html>
+</xsl:template>
+
+
+<xsl:template name="package.summary">
+ <xsl:param name="name"/>
+ <html>
+ <head>
+ <xsl:call-template name="create.stylesheet.link">
+ <xsl:with-param name="package.name" select="$name"/>
+ </xsl:call-template>
+ </head>
+ <body>
+ <xsl:attribute name="onload">open('package-frame.html','classListFrame')</xsl:attribute>
+ <xsl:call-template name="pageHeader"/>
+ <h3>Package <xsl:value-of select="$name"/></h3>
+
+ <!--table border="0" cellpadding="5" cellspacing="2" width="95%">
+ <xsl:call-template name="class.metrics.header"/>
+ <xsl:apply-templates select="." mode="print.metrics"/>
+ </table-->
+
+ <xsl:variable name="insamepackage" select="/testsuites/testsuite[./@package = $name]"/>
+ <xsl:if test="count($insamepackage) &gt; 0">
+ <h2>Classes</h2>
+ <p>
+ <table class="details" border="0" cellpadding="5" cellspacing="2" width="95%">
+ <xsl:call-template name="testsuite.test.header"/>
+ <xsl:apply-templates select="$insamepackage" mode="print.test">
+ <xsl:sort select="@name"/>
+ </xsl:apply-templates>
+ </table>
+ </p>
+ </xsl:if>
+ </body>
+ </html>
+</xsl:template>
+
+
+<!--
+ transform string like a.b.c to ../../../
+ @param path the path to transform into a descending directory path
+-->
+<xsl:template name="path">
+ <xsl:param name="path"/>
+ <xsl:if test="contains($path,'.')">
+ <xsl:text>../</xsl:text>
+ <xsl:call-template name="path">
+ <xsl:with-param name="path"><xsl:value-of select="substring-after($path,'.')"/></xsl:with-param>
+ </xsl:call-template>
+ </xsl:if>
+ <xsl:if test="not(contains($path,'.')) and not($path = '')">
+ <xsl:text>../</xsl:text>
+ </xsl:if>
+</xsl:template>
+
+
+<!-- create the link to the stylesheet based on the package name -->
+<xsl:template name="create.stylesheet.link">
+ <xsl:param name="package.name"/>
+ <link rel="stylesheet" type="text/css" title="Style"><xsl:attribute name="href"><xsl:if test="not($package.name = 'unnamed package')"><xsl:call-template name="path"><xsl:with-param name="path" select="$package.name"/></xsl:call-template></xsl:if>stylesheet.css</xsl:attribute></link>
+</xsl:template>
+
+
+<!-- Page HEADER -->
+<xsl:template name="pageHeader">
+ <h1>Unit Test Results</h1>
+ <table width="100%">
+ <tr>
+ <td align="left"></td>
+ <td align="right">Designed for use with <a href="http://www.junit.org/">JUnit</a> and <a href="http://ant.apache.org/">Ant</a>.</td>
+ </tr>
+ </table>
+ <hr size="1"/>
+</xsl:template>
+
+ <xsl:template name="testsuite.test.header">
+ <tr valign="top">
+ <th width="80%">Name</th>
+ <th>Tests</th>
+ <th>Errors</th>
+ <th>Failures</th>
+ <th nowrap="nowrap">Time(s)</th>
+ <th nowrap="nowrap">Time Stamp</th>
+ <th>Host</th>
+ </tr>
+ </xsl:template>
+<!-- method header -->
+<xsl:template name="testcase.test.header">
+ <xsl:param name="show.class" select="''"/>
+ <tr valign="top">
+ <xsl:if test="boolean($show.class)">
+ <th>Class</th>
+ </xsl:if>
+ <th>Name</th>
+ <th>Status</th>
+ <th width="80%">Type</th>
+ <th nowrap="nowrap">Time(s)</th>
+ </tr>
+</xsl:template>
+
+
+<!-- class information -->
+<xsl:template match="testsuite" mode="print.test">
+ <tr valign="top">
+ <xsl:attribute name="class">
+ <xsl:choose>
+ <xsl:when test="@errors[.&gt; 0]">Error</xsl:when>
+ <xsl:when test="@failures[.&gt; 0]">Failure</xsl:when>
+ <xsl:otherwise>Pass</xsl:otherwise>
+ </xsl:choose>
+ </xsl:attribute>
+ <td><a title="Display all tests" href="{@id}_{@name}.html"><xsl:value-of select="@name"/></a></td>
+ <td><a title="Display all tests" href="{@id}_{@name}.html"><xsl:apply-templates select="@tests"/></a></td>
+ <td>
+ <xsl:choose>
+ <xsl:when test="@errors != 0">
+ <a title="Display only errors" href="{@id}_{@name}-errors.html"><xsl:apply-templates select="@errors"/></a>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:apply-templates select="@errors"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </td>
+ <td>
+ <xsl:choose>
+ <xsl:when test="@failures != 0">
+ <a title="Display only failures" href="{@id}_{@name}-fails.html"><xsl:apply-templates select="@failures"/></a>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:apply-templates select="@failures"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </td>
+ <td><xsl:call-template name="display-time">
+ <xsl:with-param name="value" select="@time"/>
+ </xsl:call-template>
+ </td>
+ <td><xsl:apply-templates select="@timestamp"/></td>
+ <td><xsl:apply-templates select="@hostname"/></td>
+ </tr>
+</xsl:template>
+
+<xsl:template match="testcase" mode="print.test">
+ <xsl:param name="show.class" select="''"/>
+ <tr valign="top">
+ <xsl:attribute name="class">
+ <xsl:choose>
+ <xsl:when test="error">Error</xsl:when>
+ <xsl:when test="failure">Failure</xsl:when>
+ <xsl:otherwise>TableRowColor</xsl:otherwise>
+ </xsl:choose>
+ </xsl:attribute>
+ <xsl:variable name="class.href">
+ <xsl:value-of select="concat(translate(../@package,'.','/'), '/', ../@id, '_', ../@name, '.html')"/>
+ </xsl:variable>
+ <xsl:if test="boolean($show.class)">
+ <td><a href="{$class.href}"><xsl:value-of select="../@name"/></a></td>
+ </xsl:if>
+ <td>
+ <a name="{@name}"/>
+ <xsl:choose>
+ <xsl:when test="boolean($show.class)">
+ <a href="{concat($class.href, '#', @name)}"><xsl:value-of select="@name"/></a>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="@name"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </td>
+ <xsl:choose>
+ <xsl:when test="failure">
+ <td>Failure</td>
+ <td><xsl:apply-templates select="failure"/></td>
+ </xsl:when>
+ <xsl:when test="error">
+ <td>Error</td>
+ <td><xsl:apply-templates select="error"/></td>
+ </xsl:when>
+ <xsl:otherwise>
+ <td>Success</td>
+ <td></td>
+ </xsl:otherwise>
+ </xsl:choose>
+ <td>
+ <xsl:call-template name="display-time">
+ <xsl:with-param name="value" select="@time"/>
+ </xsl:call-template>
+ </td>
+ </tr>
+</xsl:template>
+
+
+<!-- Note : the below template error and failure are the same style
+ so just call the same style store in the toolkit template -->
+<xsl:template match="failure">
+ <xsl:call-template name="display-failures"/>
+</xsl:template>
+
+<xsl:template match="error">
+ <xsl:call-template name="display-failures"/>
+</xsl:template>
+
+<!-- Style for the error and failure in the testcase template -->
+<xsl:template name="display-failures">
+ <xsl:choose>
+ <xsl:when test="not(@message)">N/A</xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="@message"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ <!-- display the stacktrace -->
+ <br/><br/>
+ <code>
+ <xsl:call-template name="br-replace">
+ <xsl:with-param name="word" select="."/>
+ </xsl:call-template>
+ </code>
+ <!-- the latter is better but might be problematic for non-21" monitors... -->
+ <!--pre><xsl:value-of select="."/></pre-->
+</xsl:template>
+
+<xsl:template name="JS-escape">
+ <xsl:param name="string"/>
+ <xsl:param name="tmp1" select="stringutils:replace(string($string),'\','\\')"/>
+ <xsl:param name="tmp2" select="stringutils:replace(string($tmp1),&quot;'&quot;,&quot;\&apos;&quot;)"/>
+ <xsl:value-of select="$tmp2"/>
+</xsl:template>
+
+
+<!--
+ template that will convert a carriage return into a br tag
+ @param word the text from which to convert CR to BR tag
+-->
+<xsl:template name="br-replace">
+ <xsl:param name="word"/>
+ <xsl:value-of disable-output-escaping="yes" select='stringutils:replace(string($word),"&#xA;","&lt;br/>")'/>
+</xsl:template>
+
+<xsl:template name="display-time">
+ <xsl:param name="value"/>
+ <xsl:value-of select="format-number($value,'0.000')"/>
+</xsl:template>
+
+<xsl:template name="display-percent">
+ <xsl:param name="value"/>
+ <xsl:value-of select="format-number($value,'0.00%')"/>
+</xsl:template>
+
+
+</xsl:stylesheet>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/junitreport-with-include/junit-import.xsl b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/junitreport-with-include/junit-import.xsl
new file mode 100644
index 00000000..ecba47bb
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/junitreport-with-include/junit-import.xsl
@@ -0,0 +1,24 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
+ xmlns:lxslt="http://xml.apache.org/xslt"
+ xmlns:redirect="http://xml.apache.org/xalan/redirect"
+ xmlns:stringutils="xalan://org.apache.tools.ant.util.StringUtils"
+ extension-element-prefixes="redirect">
+ <!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+ <!-- class header -->
+</xsl:stylesheet>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/junitreport.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/junitreport.xml
new file mode 100644
index 00000000..60806625
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/junitreport.xml
@@ -0,0 +1,189 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<project name="junitreport-test" basedir="." default="reports1">
+
+ <import file="../../buildfiletest-base.xml"/>
+
+ <target name="setUp">
+ <mkdir dir="${output}" />
+ </target>
+
+
+ <property name="jrdir" location="junitreport"/>
+
+ <!-- reports1 take care of transformation of 2 test result files and
+ produce reports according to the default format (frames)
+ needed for testNoFileJUnitNoFrames -->
+ <target name="reports1">
+ <mkdir dir="${output}/html"/>
+ <junitreport todir="${output}">
+ <fileset dir="${jrdir}">
+ <include name="TEST-*.xml"/>
+ </fileset>
+ <report todir="${output}/html"/>
+ </junitreport>
+ </target>
+
+ <target name="testEmptyFile">
+ <mkdir dir="${output}/html"/>
+ <junitreport todir="${output}">
+ <fileset dir="${jrdir}">
+ <include name="ZEROBYTES-*.xml"/>
+ <include name="TEST-*.xml"/>
+ </fileset>
+ <report todir="${output}/html"/>
+ </junitreport>
+ </target>
+
+ <target name="testIncompleteFile">
+ <mkdir dir="${output}/html"/>
+ <junitreport todir="${output}">
+ <fileset dir="${jrdir}">
+ <include name="INCOMPLETE-*.xml"/>
+ <include name="TEST-*.xml"/>
+ </fileset>
+ <report todir="${output}/html"/>
+ </junitreport>
+ </target>
+
+ <target name="testWrongElement">
+ <mkdir dir="${output}/html"/>
+ <junitreport todir="${output}">
+ <fileset dir="${jrdir}">
+ <include name="WRONGELEMENT-*.xml"/>
+ <include name="TEST-*.xml"/>
+ </fileset>
+ <report todir="${output}/html"/>
+ </junitreport>
+ </target>
+
+ <target name="testNamespace">
+ <mkdir dir="${output}/html"/>
+ <junitreport todir="${output}">
+ <fileset dir="${jrdir}">
+ <include name="NAMESPACE-*.xml"/>
+ <include name="TEST-*.xml"/>
+ </fileset>
+ <report todir="${output}/html"/>
+ </junitreport>
+ </target>
+
+ <target name="testStackTraceLineBreaks">
+ <mkdir dir="${output}/html"/>
+ <junitreport todir="${output}">
+ <fileset dir="${jrdir}">
+ <include name="TEST-*.xml"/>
+ </fileset>
+ <report todir="${output}/html"/>
+ </junitreport>
+ </target>
+
+ <target name="testSpecialSignsInSrcPath">
+ <mkdir dir="${output}/html"/>
+ <mkdir dir="${output}/test# $$%§&amp;-!cases"/>
+ <copy todir="${output}/test# $$%§&amp;-!cases">
+ <fileset dir="junitreport" includes="TEST-*.xml"/>
+ </copy>
+ <junitreport todir="${output}/html">
+ <fileset dir="${output}/test# $$%§&amp;-!cases">
+ <include name="TEST-*.xml"/>
+ </fileset>
+ <report todir="${output}/html"/>
+ </junitreport>
+ </target>
+
+ <target name="testSpecialSignsInHtmlPath">
+ <mkdir dir="${output}/html# $$%§&amp;-!report"/>
+ <mkdir dir="${output}/test"/>
+ <copy todir="${output}/test">
+ <fileset dir="junitreport" includes="TEST-*.xml"/>
+ </copy>
+ <junitreport todir="${output}/html# $$%§&amp;-!report">
+ <fileset dir="${output}/test">
+ <include name="TEST-*.xml"/>
+ </fileset>
+ <report todir="${output}/html# $$%§&amp;-!report"/>
+ </junitreport>
+ </target>
+
+ <target name="testWithStyleFromClasspath">
+ <mkdir dir="${output}/html"/>
+ <junitreport todir="${output}">
+ <fileset dir="${jrdir}">
+ <include name="TEST-*.xml"/>
+ </fileset>
+ <report todir="${output}/html"/>
+ </junitreport>
+ </target>
+
+ <target name="testNoFrames">
+ <mkdir dir="${output}/html"/>
+ <junitreport todir="${output}">
+ <fileset dir="${jrdir}">
+ <include name="TEST-*.xml"/>
+ </fileset>
+ <report todir="${output}/html" format="noframes"/>
+ </junitreport>
+ </target>
+
+ <target name="testWithStyleFromDir">
+ <mkdir dir="${output}/html"/>
+ <junitreport todir="${output}">
+ <fileset dir="${jrdir}">
+ <include name="TEST-*.xml"/>
+ </fileset>
+ <report todir="${output}/html"
+ styledir="junitreport"
+ format="frames"/>
+ </junitreport>
+ </target>
+
+ <!-- bug report 40022 -->
+ <target name="testWithStyleFromDirAndXslImport">
+ <mkdir dir="${output}/html"/>
+ <junitreport todir="${output}">
+ <fileset dir="${jrdir}">
+ <include name="TEST-*.xml"/>
+ </fileset>
+ <report todir="${output}/html"
+ styledir="junitreport-with-include"
+ format="frames"/>
+ </junitreport>
+ </target>
+
+ <target name="testWithParams">
+ <mkdir dir="${output}/html"/>
+ <junitreport todir="${output}">
+ <fileset dir="${jrdir}">
+ <include name="TEST-*.xml"/>
+ </fileset>
+ <report todir="${output}/html"
+ styledir="junitreport"
+ format="frames">
+ <param name="key1" expression="value1"/>
+ <param name="key2" expression="value2"/>
+ </report>
+ </junitreport>
+ <concat>
+ <fileset file="${output}/html/index.html"/>
+ </concat>
+ </target>
+
+</project>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/junitreport/INCOMPLETE-sampleproject.incomplete.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/junitreport/INCOMPLETE-sampleproject.incomplete.xml
new file mode 100644
index 00000000..56af0146
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/junitreport/INCOMPLETE-sampleproject.incomplete.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<testsuite errors="0" failures="0" name="sampleproject.incomplete" tests="5" time="0.038">
+ </properties>
+ <testcase name="testEquals" time="0.0"></testcase>
+ <testcase name="testHashCode" time="0.0"></testcase>
+ <testcase name="testToString" time="0.0010"></testcase>
+ <testcase name="testgetUniqueString" time="0.0"></testcase>
+ <testcase name="testSerialization" time="0.024"></testcase>
+ <system-out><![CDATA[testEquals
+testHashCode
+testToString
+testgetUniqueString
+testSerialization
+]]></system-out>
+ <system-err>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/junitreport/NAMESPACE-sampleproject.namespace.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/junitreport/NAMESPACE-sampleproject.namespace.xml
new file mode 100644
index 00000000..41e7dbff
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/junitreport/NAMESPACE-sampleproject.namespace.xml
@@ -0,0 +1,116 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<ns:testsuite errors="1" failures="1" name="sampleproject.namespace" tests="11" time="0.171" xmlns:ns="funny-namespace">
+ <properties>
+ <property name="testsrc" value="test/"></property>
+ <property name="java.runtime.name" value="Java(TM) 2 Runtime Environment, Standard Edition"></property>
+ <property name="sun.boot.library.path" value="/usr/java/jdk1.3.1_03/jre/lib/i386"></property>
+ <property name="java.vm.version" value="1.3.1_03-b03"></property>
+ <property name="ant.version" value="Apache Ant version 1.5 compiled on July 9 2002"></property>
+ <property name="ant.java.version" value="1.3"></property>
+ <property name="java.vm.vendor" value="Sun Microsystems Inc."></property>
+ <property name="java.vendor.url" value="http://java.sun.com/"></property>
+ <property name="path.separator" value=":"></property>
+ <property name="java.vm.name" value="Java HotSpot(TM) Client VM"></property>
+ <property name="file.encoding.pkg" value="sun.io"></property>
+ <property name="classes" value="classes"></property>
+ <property name="java.vm.specification.name" value="Java Virtual Machine Specification"></property>
+ <property name="user.dir" value="/home/jkf/programming/gretant_sourceforge/sampleproject"></property>
+ <property name="java.runtime.version" value="1.3.1_03-b03"></property>
+ <property name="java.awt.graphicsenv" value="sun.awt.X11GraphicsEnvironment"></property>
+ <property name="basedir" value="/home/jkf/programming/gretant_sourceforge/sampleproject"></property>
+ <property name="os.arch" value="i386"></property>
+ <property name="java.io.tmpdir" value="/tmp"></property>
+ <property name="line.separator" value="
+"></property>
+ <property name="java.vm.specification.vendor" value="Sun Microsystems Inc."></property>
+ <property name="java.awt.fonts" value=""></property>
+ <property name="os.name" value="Linux"></property>
+ <property name="ant.home" value="/opt/jakarta-ant-1.5/"></property>
+ <property name="ant.project.name" value="sample"></property>
+ <property name="reportdir" value="reports"></property>
+ <property name="java.library.path" value="/usr/java/jdk1.3.1_03/jre/lib/i386:/usr/java/jdk1.3.1_03/jre/lib/i386/native_threads/:/usr/java/jdk1.3.1_03/jre/lib/i386/client:/usr/java/jdk1.3.1_03/jre/../lib/i386"></property>
+ <property name="src" value="code/"></property>
+ <property name="debug" value="on"></property>
+ <property name="java.specification.name" value="Java Platform API Specification"></property>
+ <property name="java.class.version" value="47.0"></property>
+ <property name="os.version" value="2.4.18-5"></property>
+ <property name="ant.file" value="/home/jkf/programming/gretant_sourceforge/sampleproject/build.xml"></property>
+ <property name="unitreport" value="cl-unit.xml"></property>
+ <property name="user.home" value="/home/jkf"></property>
+ <property name="user.timezone" value="Europe/Amsterdam"></property>
+ <property name="java.awt.printerjob" value="sun.awt.motif.PSPrinterJob"></property>
+ <property name="java.specification.version" value="1.3"></property>
+ <property name="file.encoding" value="ISO-8859-15"></property>
+ <property name="java.class.path" value="/opt/jakarta-ant-1.5//lib/xml-apis.jar:/opt/jakarta-ant-1.5//lib/xercesImpl.jar:/opt/jakarta-ant-1.5//lib/xalan.jar:/opt/jakarta-ant-1.5//lib/optional.jar:/opt/jakarta-ant-1.5//lib/junit.jar:/opt/jakarta-ant-1.5//lib/Gretel.jar:/opt/jakarta-ant-1.5//lib/gretant.jar:/opt/jakarta-ant-1.5//lib/cup-runtime.jar:/opt/jakarta-ant-1.5//lib/bcel.jar:/opt/jakarta-ant-1.5//lib/ant.jar:/usr/java/jdk1.3/lib/tools.jar"></property>
+ <property name="user.name" value="jkf"></property>
+ <property name="coverreport" value="cl-cover.xml"></property>
+ <property name="java.vm.specification.version" value="1.0"></property>
+ <property name="java.home" value="/usr/java/jdk1.3.1_03/jre"></property>
+ <property name="java.specification.vendor" value="Sun Microsystems Inc."></property>
+ <property name="user.language" value="en"></property>
+ <property name="java.vm.info" value="mixed mode"></property>
+ <property name="java.version" value="1.3.1_03"></property>
+ <property name="java.ext.dirs" value="/usr/java/jdk1.3.1_03/jre/lib/ext"></property>
+ <property name="sun.boot.class.path" value="/usr/java/jdk1.3.1_03/jre/lib/rt.jar:/usr/java/jdk1.3.1_03/jre/lib/i18n.jar:/usr/java/jdk1.3.1_03/jre/lib/sunrsasign.jar:/usr/java/jdk1.3.1_03/jre/classes"></property>
+ <property name="java.vendor" value="Sun Microsystems Inc."></property>
+ <property name="file.separator" value="/"></property>
+ <property name="testclasses" value="testclasses"></property>
+ <property name="java.vendor.url.bug" value="http://java.sun.com/cgi-bin/bugreport.cgi"></property>
+ <property name="sun.io.unicode.encoding" value="UnicodeLittle"></property>
+ <property name="sun.cpu.endian" value="little"></property>
+ <property name="gretclasses" value="gretclasses"></property>
+ <property name="user.region" value="US"></property>
+ <property name="sun.cpu.isalist" value=""></property>
+ </properties>
+ <testcase name="testEquals" time="0.014"></testcase>
+ <testcase name="testHashCode" time="0.0010"></testcase>
+ <testcase name="testToString" time="0.0010"></testcase>
+ <testcase name="testGetImageURL" time="0.0"></testcase>
+ <testcase name="testGetCountry" time="0.0010"></testcase>
+ <testcase name="testGetDenomination" time="0.0"></testcase>
+ <testcase name="testGetYear" time="0.0"></testcase>
+ <testcase name="testGetSubType" time="0.0"></testcase>
+ <testcase name="testFail" time="0.0080">
+ <failure message="DOEG" type="junit.framework.AssertionFailedError">junit.framework.AssertionFailedError: DOEG
+ at sampleproject.coins.CoinTest.testFail(CoinTest.java:229)
+</failure>
+ </testcase>
+ <testcase name="testException" time="0.0010">
+ <error message="RTE" type="java.lang.RuntimeException">java.lang.RuntimeException: RTE
+ at sampleproject.coins.CoinTest.testException(CoinTest.java:234)
+</error>
+ </testcase>
+ <testcase name="testSuccess" time="0.0"></testcase>
+ <system-out><![CDATA[testEquals
+testHashCode
+Hashcodes: 1434557225 1434557225 1434557226 1463186376 1434556908 1516980401 1434557225
+testToString
+<Coin=NL,1 Euro,1999,Var a/>
+<Coin=NL,1 Euro,1999,null/>
+testGetImageURL
+testGetCountry
+testGetDenomination
+testGetYear
+testGetSubType
+testFail
+testException
+testSuccess
+]]></system-out>
+ <system-err><![CDATA[]]></system-err>
+</ns:testsuite>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/junitreport/TEST-sampleproject.coins.CoinTest.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/junitreport/TEST-sampleproject.coins.CoinTest.xml
new file mode 100644
index 00000000..6bc99f29
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/junitreport/TEST-sampleproject.coins.CoinTest.xml
@@ -0,0 +1,115 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<testsuite errors="1" failures="1" name="sampleproject.coins.CoinTest" tests="11" time="0.171">
+ <properties>
+ <property name="testsrc" value="test/"></property>
+ <property name="java.runtime.name" value="Java(TM) 2 Runtime Environment, Standard Edition"></property>
+ <property name="sun.boot.library.path" value="/usr/java/jdk1.3.1_03/jre/lib/i386"></property>
+ <property name="java.vm.version" value="1.3.1_03-b03"></property>
+ <property name="ant.version" value="Apache Ant version 1.5 compiled on July 9 2002"></property>
+ <property name="ant.java.version" value="1.3"></property>
+ <property name="java.vm.vendor" value="Sun Microsystems Inc."></property>
+ <property name="java.vendor.url" value="http://java.sun.com/"></property>
+ <property name="path.separator" value=":"></property>
+ <property name="java.vm.name" value="Java HotSpot(TM) Client VM"></property>
+ <property name="file.encoding.pkg" value="sun.io"></property>
+ <property name="classes" value="classes"></property>
+ <property name="java.vm.specification.name" value="Java Virtual Machine Specification"></property>
+ <property name="user.dir" value="/home/jkf/programming/gretant_sourceforge/sampleproject"></property>
+ <property name="java.runtime.version" value="1.3.1_03-b03"></property>
+ <property name="java.awt.graphicsenv" value="sun.awt.X11GraphicsEnvironment"></property>
+ <property name="basedir" value="/home/jkf/programming/gretant_sourceforge/sampleproject"></property>
+ <property name="os.arch" value="i386"></property>
+ <property name="java.io.tmpdir" value="/tmp"></property>
+ <property name="line.separator" value="&#xd;&#xa;"></property>
+ <property name="java.vm.specification.vendor" value="Sun Microsystems Inc."></property>
+ <property name="java.awt.fonts" value=""></property>
+ <property name="os.name" value="Linux"></property>
+ <property name="ant.home" value="/opt/jakarta-ant-1.5/"></property>
+ <property name="ant.project.name" value="sample"></property>
+ <property name="reportdir" value="reports"></property>
+ <property name="java.library.path" value="/usr/java/jdk1.3.1_03/jre/lib/i386:/usr/java/jdk1.3.1_03/jre/lib/i386/native_threads/:/usr/java/jdk1.3.1_03/jre/lib/i386/client:/usr/java/jdk1.3.1_03/jre/../lib/i386"></property>
+ <property name="src" value="code/"></property>
+ <property name="debug" value="on"></property>
+ <property name="java.specification.name" value="Java Platform API Specification"></property>
+ <property name="java.class.version" value="47.0"></property>
+ <property name="os.version" value="2.4.18-5"></property>
+ <property name="ant.file" value="/home/jkf/programming/gretant_sourceforge/sampleproject/build.xml"></property>
+ <property name="unitreport" value="cl-unit.xml"></property>
+ <property name="user.home" value="/home/jkf"></property>
+ <property name="user.timezone" value="Europe/Amsterdam"></property>
+ <property name="java.awt.printerjob" value="sun.awt.motif.PSPrinterJob"></property>
+ <property name="java.specification.version" value="1.3"></property>
+ <property name="file.encoding" value="ISO-8859-15"></property>
+ <property name="java.class.path" value="/opt/jakarta-ant-1.5//lib/xml-apis.jar:/opt/jakarta-ant-1.5//lib/xercesImpl.jar:/opt/jakarta-ant-1.5//lib/xalan.jar:/opt/jakarta-ant-1.5//lib/optional.jar:/opt/jakarta-ant-1.5//lib/junit.jar:/opt/jakarta-ant-1.5//lib/Gretel.jar:/opt/jakarta-ant-1.5//lib/gretant.jar:/opt/jakarta-ant-1.5//lib/cup-runtime.jar:/opt/jakarta-ant-1.5//lib/bcel.jar:/opt/jakarta-ant-1.5//lib/ant.jar:/usr/java/jdk1.3/lib/tools.jar"></property>
+ <property name="user.name" value="jkf"></property>
+ <property name="coverreport" value="cl-cover.xml"></property>
+ <property name="java.vm.specification.version" value="1.0"></property>
+ <property name="java.home" value="/usr/java/jdk1.3.1_03/jre"></property>
+ <property name="java.specification.vendor" value="Sun Microsystems Inc."></property>
+ <property name="user.language" value="en"></property>
+ <property name="java.vm.info" value="mixed mode"></property>
+ <property name="java.version" value="1.3.1_03"></property>
+ <property name="java.ext.dirs" value="/usr/java/jdk1.3.1_03/jre/lib/ext"></property>
+ <property name="sun.boot.class.path" value="/usr/java/jdk1.3.1_03/jre/lib/rt.jar:/usr/java/jdk1.3.1_03/jre/lib/i18n.jar:/usr/java/jdk1.3.1_03/jre/lib/sunrsasign.jar:/usr/java/jdk1.3.1_03/jre/classes"></property>
+ <property name="java.vendor" value="Sun Microsystems Inc."></property>
+ <property name="file.separator" value="/"></property>
+ <property name="testclasses" value="testclasses"></property>
+ <property name="java.vendor.url.bug" value="http://java.sun.com/cgi-bin/bugreport.cgi"></property>
+ <property name="sun.io.unicode.encoding" value="UnicodeLittle"></property>
+ <property name="sun.cpu.endian" value="little"></property>
+ <property name="gretclasses" value="gretclasses"></property>
+ <property name="user.region" value="US"></property>
+ <property name="sun.cpu.isalist" value=""></property>
+ </properties>
+ <testcase name="testEquals" time="0.014"></testcase>
+ <testcase name="testHashCode" time="0.0010"></testcase>
+ <testcase name="testToString" time="0.0010"></testcase>
+ <testcase name="testGetImageURL" time="0.0"></testcase>
+ <testcase name="testGetCountry" time="0.0010"></testcase>
+ <testcase name="testGetDenomination" time="0.0"></testcase>
+ <testcase name="testGetYear" time="0.0"></testcase>
+ <testcase name="testGetSubType" time="0.0"></testcase>
+ <testcase name="testFail" time="0.0080">
+ <failure message="DOEG" type="junit.framework.AssertionFailedError">junit.framework.AssertionFailedError: DOEG
+ at sampleproject.coins.CoinTest.testFail(CoinTest.java:229)
+</failure>
+ </testcase>
+ <testcase name="testException" time="0.0010">
+ <error message="RTE" type="java.lang.RuntimeException">java.lang.RuntimeException: RTE
+ at sampleproject.coins.CoinTest.testException(CoinTest.java:234)
+</error>
+ </testcase>
+ <testcase name="testSuccess" time="0.0"></testcase>
+ <system-out><![CDATA[testEquals
+testHashCode
+Hashcodes: 1434557225 1434557225 1434557226 1463186376 1434556908 1516980401 1434557225
+testToString
+<Coin=NL,1 Euro,1999,Var a/>
+<Coin=NL,1 Euro,1999,null/>
+testGetImageURL
+testGetCountry
+testGetDenomination
+testGetYear
+testGetSubType
+testFail
+testException
+testSuccess
+]]></system-out>
+ <system-err><![CDATA[]]></system-err>
+</testsuite>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/junitreport/TEST-sampleproject.util.UniqueStringTest.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/junitreport/TEST-sampleproject.util.UniqueStringTest.xml
new file mode 100644
index 00000000..f4016c26
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/junitreport/TEST-sampleproject.util.UniqueStringTest.xml
@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<testsuite errors="0" failures="0" name="sampleproject.util.UniqueStringTest" tests="5" time="0.038">
+ <properties>
+ <property name="testsrc" value="test/"></property>
+ <property name="java.runtime.name" value="Java(TM) 2 Runtime Environment, Standard Edition"></property>
+ <property name="sun.boot.library.path" value="/usr/java/jdk1.3.1_03/jre/lib/i386"></property>
+ <property name="java.vm.version" value="1.3.1_03-b03"></property>
+ <property name="ant.version" value="Apache Ant version 1.5 compiled on July 9 2002"></property>
+ <property name="ant.java.version" value="1.3"></property>
+ <property name="java.vm.vendor" value="Sun Microsystems Inc."></property>
+ <property name="java.vendor.url" value="http://java.sun.com/"></property>
+ <property name="path.separator" value=":"></property>
+ <property name="java.vm.name" value="Java HotSpot(TM) Client VM"></property>
+ <property name="file.encoding.pkg" value="sun.io"></property>
+ <property name="classes" value="classes"></property>
+ <property name="java.vm.specification.name" value="Java Virtual Machine Specification"></property>
+ <property name="user.dir" value="/home/jkf/programming/gretant_sourceforge/sampleproject"></property>
+ <property name="java.runtime.version" value="1.3.1_03-b03"></property>
+ <property name="java.awt.graphicsenv" value="sun.awt.X11GraphicsEnvironment"></property>
+ <property name="basedir" value="/home/jkf/programming/gretant_sourceforge/sampleproject"></property>
+ <property name="os.arch" value="i386"></property>
+ <property name="java.io.tmpdir" value="/tmp"></property>
+ <property name="line.separator" value="
+"></property>
+ <property name="java.vm.specification.vendor" value="Sun Microsystems Inc."></property>
+ <property name="java.awt.fonts" value=""></property>
+ <property name="os.name" value="Linux"></property>
+ <property name="ant.home" value="/opt/jakarta-ant-1.5/"></property>
+ <property name="ant.project.name" value="sample"></property>
+ <property name="reportdir" value="reports"></property>
+ <property name="java.library.path" value="/usr/java/jdk1.3.1_03/jre/lib/i386:/usr/java/jdk1.3.1_03/jre/lib/i386/native_threads/:/usr/java/jdk1.3.1_03/jre/lib/i386/client:/usr/java/jdk1.3.1_03/jre/../lib/i386"></property>
+ <property name="src" value="code/"></property>
+ <property name="debug" value="on"></property>
+ <property name="java.specification.name" value="Java Platform API Specification"></property>
+ <property name="java.class.version" value="47.0"></property>
+ <property name="os.version" value="2.4.18-5"></property>
+ <property name="ant.file" value="/home/jkf/programming/gretant_sourceforge/sampleproject/build.xml"></property>
+ <property name="unitreport" value="cl-unit.xml"></property>
+ <property name="user.home" value="/home/jkf"></property>
+ <property name="user.timezone" value="Europe/Amsterdam"></property>
+ <property name="java.awt.printerjob" value="sun.awt.motif.PSPrinterJob"></property>
+ <property name="java.specification.version" value="1.3"></property>
+ <property name="file.encoding" value="ISO-8859-15"></property>
+ <property name="java.class.path" value="/opt/jakarta-ant-1.5//lib/xml-apis.jar:/opt/jakarta-ant-1.5//lib/xercesImpl.jar:/opt/jakarta-ant-1.5//lib/xalan.jar:/opt/jakarta-ant-1.5//lib/optional.jar:/opt/jakarta-ant-1.5//lib/junit.jar:/opt/jakarta-ant-1.5//lib/Gretel.jar:/opt/jakarta-ant-1.5//lib/gretant.jar:/opt/jakarta-ant-1.5//lib/cup-runtime.jar:/opt/jakarta-ant-1.5//lib/bcel.jar:/opt/jakarta-ant-1.5//lib/ant.jar:/usr/java/jdk1.3/lib/tools.jar"></property>
+ <property name="user.name" value="jkf"></property>
+ <property name="coverreport" value="cl-cover.xml"></property>
+ <property name="java.vm.specification.version" value="1.0"></property>
+ <property name="java.home" value="/usr/java/jdk1.3.1_03/jre"></property>
+ <property name="java.specification.vendor" value="Sun Microsystems Inc."></property>
+ <property name="user.language" value="en"></property>
+ <property name="java.vm.info" value="mixed mode"></property>
+ <property name="java.version" value="1.3.1_03"></property>
+ <property name="java.ext.dirs" value="/usr/java/jdk1.3.1_03/jre/lib/ext"></property>
+ <property name="sun.boot.class.path" value="/usr/java/jdk1.3.1_03/jre/lib/rt.jar:/usr/java/jdk1.3.1_03/jre/lib/i18n.jar:/usr/java/jdk1.3.1_03/jre/lib/sunrsasign.jar:/usr/java/jdk1.3.1_03/jre/classes"></property>
+ <property name="java.vendor" value="Sun Microsystems Inc."></property>
+ <property name="file.separator" value="/"></property>
+ <property name="testclasses" value="testclasses"></property>
+ <property name="java.vendor.url.bug" value="http://java.sun.com/cgi-bin/bugreport.cgi"></property>
+ <property name="sun.io.unicode.encoding" value="UnicodeLittle"></property>
+ <property name="sun.cpu.endian" value="little"></property>
+ <property name="gretclasses" value="gretclasses"></property>
+ <property name="user.region" value="US"></property>
+ <property name="sun.cpu.isalist" value=""></property>
+ </properties>
+ <testcase name="testEquals" time="0.0"></testcase>
+ <testcase name="testHashCode" time="0.0"></testcase>
+ <testcase name="testToString" time="0.0010"></testcase>
+ <testcase name="testgetUniqueString" time="0.0"></testcase>
+ <testcase name="testSerialization" time="0.024"></testcase>
+ <system-out><![CDATA[testEquals
+testHashCode
+testToString
+testgetUniqueString
+testSerialization
+]]></system-out>
+ <system-err><![CDATA[]]></system-err>
+</testsuite>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/junitreport/WRONGELEMENT-sampleproject.wrongelement.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/junitreport/WRONGELEMENT-sampleproject.wrongelement.xml
new file mode 100644
index 00000000..9cb5a147
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/junitreport/WRONGELEMENT-sampleproject.wrongelement.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<wildebeast/>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/junitreport/ZEROBYTES-sampleproject.package.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/junitreport/ZEROBYTES-sampleproject.package.xml
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/junitreport/ZEROBYTES-sampleproject.package.xml
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/junitreport/junit-frames.xsl b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/junitreport/junit-frames.xsl
new file mode 100644
index 00000000..ca313af9
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/junitreport/junit-frames.xsl
@@ -0,0 +1,879 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
+ xmlns:lxslt="http://xml.apache.org/xslt"
+ xmlns:redirect="http://xml.apache.org/xalan/redirect"
+ xmlns:stringutils="xalan://org.apache.tools.ant.util.StringUtils"
+ extension-element-prefixes="redirect">
+<xsl:output method="html" indent="yes" encoding="US-ASCII"/>
+<xsl:decimal-format decimal-separator="." grouping-separator=","/>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<!--
+
+ Sample stylesheet to be used with Ant JUnitReport output.
+
+ It creates a set of HTML files a la javadoc where you can browse easily
+ through all packages and classes.
+
+-->
+<xsl:param name="output.dir" select="'.'"/>
+<xsl:param name="key1" select="'defaultValue1'"/>
+<xsl:param name="key2" select="'defaultValue2'"/>
+
+<xsl:template match="testsuites">
+ <!-- create the index.html -->
+ <redirect:write file="{$output.dir}/index.html">
+ <xsl:call-template name="index.html"/>
+ </redirect:write>
+
+ <!-- create the stylesheet.css -->
+ <redirect:write file="{$output.dir}/stylesheet.css">
+ <xsl:call-template name="stylesheet.css"/>
+ </redirect:write>
+
+ <!-- create the overview-packages.html at the root -->
+ <redirect:write file="{$output.dir}/overview-summary.html">
+ <xsl:apply-templates select="." mode="overview.packages"/>
+ </redirect:write>
+
+ <!-- create the all-packages.html at the root -->
+ <redirect:write file="{$output.dir}/overview-frame.html">
+ <xsl:apply-templates select="." mode="all.packages"/>
+ </redirect:write>
+
+ <!-- create the all-classes.html at the root -->
+ <redirect:write file="{$output.dir}/allclasses-frame.html">
+ <xsl:apply-templates select="." mode="all.classes"/>
+ </redirect:write>
+
+ <!-- create the all-tests.html at the root -->
+ <redirect:write file="{$output.dir}/all-tests.html">
+ <xsl:apply-templates select="." mode="all.tests"/>
+ </redirect:write>
+
+ <!-- create the alltests-fails.html at the root -->
+ <redirect:write file="{$output.dir}/alltests-fails.html">
+ <xsl:apply-templates select="." mode="all.tests">
+ <xsl:with-param name="type" select="'fails'"/>
+ </xsl:apply-templates>
+ </redirect:write>
+
+ <!-- create the alltests-errors.html at the root -->
+ <redirect:write file="{$output.dir}/alltests-errors.html">
+ <xsl:apply-templates select="." mode="all.tests">
+ <xsl:with-param name="type" select="'errors'"/>
+ </xsl:apply-templates>
+ </redirect:write>
+
+ <!-- process all packages -->
+ <xsl:for-each select="./testsuite[not(./@package = preceding-sibling::testsuite/@package)]">
+ <xsl:call-template name="package">
+ <xsl:with-param name="name" select="@package"/>
+ </xsl:call-template>
+ </xsl:for-each>
+</xsl:template>
+
+
+<xsl:template name="package">
+ <xsl:param name="name"/>
+ <xsl:variable name="package.dir">
+ <xsl:if test="not($name = '')"><xsl:value-of select="translate($name,'.','/')"/></xsl:if>
+ <xsl:if test="$name = ''">.</xsl:if>
+ </xsl:variable>
+ <!--Processing package <xsl:value-of select="@name"/> in <xsl:value-of select="$output.dir"/> -->
+ <!-- create a classes-list.html in the package directory -->
+ <redirect:write file="{$output.dir}/{$package.dir}/package-frame.html">
+ <xsl:call-template name="classes.list">
+ <xsl:with-param name="name" select="$name"/>
+ </xsl:call-template>
+ </redirect:write>
+
+ <!-- create a package-summary.html in the package directory -->
+ <redirect:write file="{$output.dir}/{$package.dir}/package-summary.html">
+ <xsl:call-template name="package.summary">
+ <xsl:with-param name="name" select="$name"/>
+ </xsl:call-template>
+ </redirect:write>
+
+ <!-- for each class, creates a @name.html -->
+ <!-- @bug there will be a problem with inner classes having the same name, it will be overwritten -->
+ <xsl:for-each select="/testsuites/testsuite[@package = $name]">
+ <redirect:write file="{$output.dir}/{$package.dir}/{@id}_{@name}.html">
+ <xsl:apply-templates select="." mode="class.details"/>
+ </redirect:write>
+ <xsl:if test="string-length(./system-out)!=0">
+ <redirect:write file="{$output.dir}/{$package.dir}/{@id}_{@name}-out.txt">
+ <xsl:value-of disable-output-escaping="yes" select="./system-out"/>
+ </redirect:write>
+ </xsl:if>
+ <xsl:if test="string-length(./system-err)!=0">
+ <redirect:write file="{$output.dir}/{$package.dir}/{@id}_{@name}-err.txt">
+ <xsl:value-of disable-output-escaping="yes" select="./system-err"/>
+ </redirect:write>
+ </xsl:if>
+ <xsl:if test="@failures != 0">
+ <redirect:write file="{$output.dir}/{$package.dir}/{@id}_{@name}-fails.html">
+ <xsl:apply-templates select="." mode="class.details">
+ <xsl:with-param name="type" select="'fails'"/>
+ </xsl:apply-templates>
+ </redirect:write>
+ </xsl:if>
+ <xsl:if test="@errors != 0">
+ <redirect:write file="{$output.dir}/{$package.dir}/{@id}_{@name}-errors.html">
+ <xsl:apply-templates select="." mode="class.details">
+ <xsl:with-param name="type" select="'errors'"/>
+ </xsl:apply-templates>
+ </redirect:write>
+ </xsl:if>
+ </xsl:for-each>
+</xsl:template>
+
+<xsl:template name="index.html">
+<html>
+ <head>
+ <title>
+ Unit Test Results. key1=<xsl:value-of select="$key1"/>,key2=<xsl:value-of select="$key2"/>
+ </title>
+ </head>
+ <frameset cols="20%,80%">
+ <frameset rows="30%,70%">
+ <frame src="overview-frame.html" name="packageListFrame"/>
+ <frame src="allclasses-frame.html" name="classListFrame"/>
+ </frameset>
+ <frame src="overview-summary.html" name="classFrame"/>
+ <noframes>
+ <h2>Frame Alert</h2>
+ <p>
+ This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client.
+ </p>
+ </noframes>
+ </frameset>
+</html>
+</xsl:template>
+
+<!-- this is the stylesheet css to use for nearly everything -->
+<xsl:template name="stylesheet.css">
+body {
+ font:normal 68% verdana,arial,helvetica;
+ color:#000000;
+}
+table tr td, table tr th {
+ font-size: 68%;
+}
+table.details tr th{
+ font-weight: bold;
+ text-align:left;
+ background:#a6caf0;
+}
+table.details tr td{
+ background:#eeeee0;
+}
+
+p {
+ line-height:1.5em;
+ margin-top:0.5em; margin-bottom:1.0em;
+}
+h1 {
+ margin: 0px 0px 5px; font: 165% verdana,arial,helvetica
+}
+h2 {
+ margin-top: 1em; margin-bottom: 0.5em; font: bold 125% verdana,arial,helvetica
+}
+h3 {
+ margin-bottom: 0.5em; font: bold 115% verdana,arial,helvetica
+}
+h4 {
+ margin-bottom: 0.5em; font: bold 100% verdana,arial,helvetica
+}
+h5 {
+ margin-bottom: 0.5em; font: bold 100% verdana,arial,helvetica
+}
+h6 {
+ margin-bottom: 0.5em; font: bold 100% verdana,arial,helvetica
+}
+.Error {
+ font-weight:bold; color:red;
+}
+.Failure {
+ font-weight:bold; color:purple;
+}
+.Properties {
+ text-align:right;
+}
+</xsl:template>
+
+<!-- Create list of all/failed/errored tests -->
+<xsl:template match="testsuites" mode="all.tests">
+ <xsl:param name="type" select="'all'"/>
+ <html>
+ <xsl:variable name="title">
+ <xsl:choose>
+ <xsl:when test="$type = 'fails'">
+ <xsl:text>All Failures</xsl:text>
+ </xsl:when>
+ <xsl:when test="$type = 'errors'">
+ <xsl:text>All Errors</xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>All Tests</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <head>
+ <title>Unit Test Results: <xsl:value-of select="$title"/></title>
+ <xsl:call-template name="create.stylesheet.link">
+ <xsl:with-param name="package.name"/>
+ </xsl:call-template>
+ </head>
+ <body>
+ <xsl:attribute name="onload">open('allclasses-frame.html','classListFrame')</xsl:attribute>
+ <xsl:call-template name="pageHeader"/>
+ <h2><xsl:value-of select="$title"/></h2>
+
+ <table class="details" border="0" cellpadding="5" cellspacing="2" width="95%">
+ <xsl:call-template name="testcase.test.header">
+ <xsl:with-param name="show.class" select="'yes'"/>
+ </xsl:call-template>
+ <!--
+ test can even not be started at all (failure to load the class)
+ so report the error directly
+ -->
+ <xsl:if test="./error">
+ <tr class="Error">
+ <td colspan="4">
+ <xsl:apply-templates select="./error"/>
+ </td>
+ </tr>
+ </xsl:if>
+ <xsl:choose>
+ <xsl:when test="$type = 'fails'">
+ <xsl:apply-templates select=".//testcase[failure]" mode="print.test">
+ <xsl:with-param name="show.class" select="'yes'"/>
+ </xsl:apply-templates>
+ </xsl:when>
+ <xsl:when test="$type = 'errors'">
+ <xsl:apply-templates select=".//testcase[error]" mode="print.test">
+ <xsl:with-param name="show.class" select="'yes'"/>
+ </xsl:apply-templates>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:apply-templates select=".//testcase" mode="print.test">
+ <xsl:with-param name="show.class" select="'yes'"/>
+ </xsl:apply-templates>
+ </xsl:otherwise>
+ </xsl:choose>
+ </table>
+ </body>
+ </html>
+</xsl:template>
+
+
+<!-- ======================================================================
+ This page is created for every testsuite class.
+ It prints a summary of the testsuite and detailed information about
+ testcase methods.
+ ====================================================================== -->
+<xsl:template match="testsuite" mode="class.details">
+ <xsl:param name="type" select="'all'"/>
+ <xsl:variable name="package.name" select="@package"/>
+ <xsl:variable name="class.name"><xsl:if test="not($package.name = '')"><xsl:value-of select="$package.name"/>.</xsl:if><xsl:value-of select="@name"/></xsl:variable>
+ <html>
+ <head>
+ <title>Unit Test Results: <xsl:value-of select="$class.name"/></title>
+ <xsl:call-template name="create.stylesheet.link">
+ <xsl:with-param name="package.name" select="$package.name"/>
+ </xsl:call-template>
+ <script type="text/javascript" language="JavaScript">
+ var TestCases = new Array();
+ var cur;
+ <xsl:apply-templates select="properties"/>
+ </script>
+ <script type="text/javascript" language="JavaScript"><![CDATA[
+ function displayProperties (name) {
+ var win = window.open('','JUnitSystemProperties','scrollbars=1,resizable=1');
+ var doc = win.document;
+ doc.open();
+ doc.write("<html><head><title>Properties of " + name + "</title>");
+ doc.write("<style type=\"text/css\">");
+ doc.write("body {font:normal 68% verdana,arial,helvetica; color:#000000; }");
+ doc.write("table tr td, table tr th { font-size: 68%; }");
+ doc.write("table.properties { border-collapse:collapse; border-left:solid 1 #cccccc; border-top:solid 1 #cccccc; padding:5px; }");
+ doc.write("table.properties th { text-align:left; border-right:solid 1 #cccccc; border-bottom:solid 1 #cccccc; background-color:#eeeeee; }");
+ doc.write("table.properties td { font:normal; text-align:left; border-right:solid 1 #cccccc; border-bottom:solid 1 #cccccc; background-color:#fffffff; }");
+ doc.write("h3 { margin-bottom: 0.5em; font: bold 115% verdana,arial,helvetica }");
+ doc.write("</style>");
+ doc.write("</head><body>");
+ doc.write("<h3>Properties of " + name + "</h3>");
+ doc.write("<div align=\"right\"><a href=\"javascript:window.close();\">Close</a></div>");
+ doc.write("<table class='properties'>");
+ doc.write("<tr><th>Name</th><th>Value</th></tr>");
+ for (prop in TestCases[name]) {
+ doc.write("<tr><th>" + prop + "</th><td>" + TestCases[name][prop] + "</td></tr>");
+ }
+ doc.write("</table>");
+ doc.write("</body></html>");
+ doc.close();
+ win.focus();
+ }
+ ]]>
+ </script>
+ </head>
+ <body>
+ <xsl:call-template name="pageHeader"/>
+ <h3>Class <xsl:value-of select="$class.name"/></h3>
+
+
+ <table class="details" border="0" cellpadding="5" cellspacing="2" width="95%">
+ <xsl:call-template name="testsuite.test.header"/>
+ <xsl:apply-templates select="." mode="print.test"/>
+ </table>
+
+ <xsl:choose>
+ <xsl:when test="$type = 'fails'">
+ <h2>Failures</h2>
+ </xsl:when>
+ <xsl:when test="$type = 'errors'">
+ <h2>Errors</h2>
+ </xsl:when>
+ <xsl:otherwise>
+ <h2>Tests</h2>
+ </xsl:otherwise>
+ </xsl:choose>
+ <table class="details" border="0" cellpadding="5" cellspacing="2" width="95%">
+ <xsl:call-template name="testcase.test.header"/>
+ <!--
+ test can even not be started at all (failure to load the class)
+ so report the error directly
+ -->
+ <xsl:if test="./error">
+ <tr class="Error">
+ <td colspan="4"><xsl:apply-templates select="./error"/></td>
+ </tr>
+ </xsl:if>
+ <xsl:choose>
+ <xsl:when test="$type = 'fails'">
+ <xsl:apply-templates select="./testcase[failure]" mode="print.test"/>
+ </xsl:when>
+ <xsl:when test="$type = 'errors'">
+ <xsl:apply-templates select="./testcase[error]" mode="print.test"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:apply-templates select="./testcase" mode="print.test"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </table>
+ <div class="Properties">
+ <a>
+ <xsl:attribute name="href">javascript:displayProperties('<xsl:value-of select="@package"/>.<xsl:value-of select="@name"/>');</xsl:attribute>
+ Properties &#187;
+ </a>
+ </div>
+ <xsl:if test="string-length(./system-out)!=0">
+ <div class="Properties">
+ <a>
+ <xsl:attribute name="href">./<xsl:value-of select="@id"/>_<xsl:value-of select="@name"/>-out.txt</xsl:attribute>
+ System.out &#187;
+ </a>
+ </div>
+ </xsl:if>
+ <xsl:if test="string-length(./system-err)!=0">
+ <div class="Properties">
+ <a>
+ <xsl:attribute name="href">./<xsl:value-of select="@id"/>_<xsl:value-of select="@name"/>-err.txt</xsl:attribute>
+ System.err &#187;
+ </a>
+ </div>
+ </xsl:if>
+ </body>
+ </html>
+</xsl:template>
+
+ <!--
+ Write properties into a JavaScript data structure.
+ This is based on the original idea by Erik Hatcher (ehatcher@apache.org)
+ -->
+ <xsl:template match="properties">
+ cur = TestCases['<xsl:value-of select="../@package"/>.<xsl:value-of select="../@name"/>'] = new Array();
+ <xsl:for-each select="property">
+ <xsl:sort select="@name"/>
+ cur['<xsl:value-of select="@name"/>'] = '<xsl:call-template name="JS-escape"><xsl:with-param name="string" select="@value"/></xsl:call-template>';
+ </xsl:for-each>
+ </xsl:template>
+
+
+<!-- ======================================================================
+ This page is created for every package.
+ It prints the name of all classes that belongs to this package.
+ @param name the package name to print classes.
+ ====================================================================== -->
+<!-- list of classes in a package -->
+<xsl:template name="classes.list">
+ <xsl:param name="name"/>
+ <html>
+ <head>
+ <title>Unit Test Classes: <xsl:value-of select="$name"/></title>
+ <xsl:call-template name="create.stylesheet.link">
+ <xsl:with-param name="package.name" select="$name"/>
+ </xsl:call-template>
+ </head>
+ <body>
+ <table width="100%">
+ <tr>
+ <td nowrap="nowrap">
+ <h2><a href="package-summary.html" target="classFrame">
+ <xsl:value-of select="$name"/>
+ <xsl:if test="$name = ''">&lt;none&gt;</xsl:if>
+ </a></h2>
+ </td>
+ </tr>
+ </table>
+
+ <h2>Classes</h2>
+ <table width="100%">
+ <xsl:for-each select="/testsuites/testsuite[./@package = $name]">
+ <xsl:sort select="@name"/>
+ <tr>
+ <td nowrap="nowrap">
+ <a href="{@id}_{@name}.html" target="classFrame"><xsl:value-of select="@name"/></a>
+ </td>
+ </tr>
+ </xsl:for-each>
+ </table>
+ </body>
+ </html>
+</xsl:template>
+
+
+<!--
+ Creates an all-classes.html file that contains a link to all package-summary.html
+ on each class.
+-->
+<xsl:template match="testsuites" mode="all.classes">
+ <html>
+ <head>
+ <title>All Unit Test Classes</title>
+ <xsl:call-template name="create.stylesheet.link">
+ <xsl:with-param name="package.name"/>
+ </xsl:call-template>
+ </head>
+ <body>
+ <h2>Classes</h2>
+ <table width="100%">
+ <xsl:apply-templates select="testsuite" mode="all.classes">
+ <xsl:sort select="@name"/>
+ </xsl:apply-templates>
+ </table>
+ </body>
+ </html>
+</xsl:template>
+
+<xsl:template match="testsuite" mode="all.classes">
+ <xsl:variable name="package.name" select="@package"/>
+ <tr>
+ <td nowrap="nowrap">
+ <a target="classFrame">
+ <xsl:attribute name="href">
+ <xsl:if test="not($package.name='')">
+ <xsl:value-of select="translate($package.name,'.','/')"/><xsl:text>/</xsl:text>
+ </xsl:if><xsl:value-of select="@id"/>_<xsl:value-of select="@name"/><xsl:text>.html</xsl:text>
+ </xsl:attribute>
+ <xsl:value-of select="@name"/>
+ </a>
+ </td>
+ </tr>
+</xsl:template>
+
+
+<!--
+ Creates an html file that contains a link to all package-summary.html files on
+ each package existing on testsuites.
+ @bug there will be a problem here, I don't know yet how to handle unnamed package :(
+-->
+<xsl:template match="testsuites" mode="all.packages">
+ <html>
+ <head>
+ <title>All Unit Test Packages</title>
+ <xsl:call-template name="create.stylesheet.link">
+ <xsl:with-param name="package.name"/>
+ </xsl:call-template>
+ </head>
+ <body>
+ <h2><a href="overview-summary.html" target="classFrame">Home</a></h2>
+ <h2>Packages</h2>
+ <table width="100%">
+ <xsl:apply-templates select="testsuite[not(./@package = preceding-sibling::testsuite/@package)]" mode="all.packages">
+ <xsl:sort select="@package"/>
+ </xsl:apply-templates>
+ </table>
+ </body>
+ </html>
+</xsl:template>
+
+<xsl:template match="testsuite" mode="all.packages">
+ <tr>
+ <td nowrap="nowrap">
+ <a href="./{translate(@package,'.','/')}/package-summary.html" target="classFrame">
+ <xsl:value-of select="@package"/>
+ <xsl:if test="@package = ''">&lt;none&gt;</xsl:if>
+ </a>
+ </td>
+ </tr>
+</xsl:template>
+
+
+<xsl:template match="testsuites" mode="overview.packages">
+ <html>
+ <head>
+ <title>Unit Test Results: Summary</title>
+ <xsl:call-template name="create.stylesheet.link">
+ <xsl:with-param name="package.name"/>
+ </xsl:call-template>
+ </head>
+ <body>
+ <xsl:attribute name="onload">open('allclasses-frame.html','classListFrame')</xsl:attribute>
+ <xsl:call-template name="pageHeader"/>
+ <h2>Summary</h2>
+ <xsl:variable name="testCount" select="sum(testsuite/@tests)"/>
+ <xsl:variable name="errorCount" select="sum(testsuite/@errors)"/>
+ <xsl:variable name="failureCount" select="sum(testsuite/@failures)"/>
+ <xsl:variable name="timeCount" select="sum(testsuite/@time)"/>
+ <xsl:variable name="successRate" select="($testCount - $failureCount - $errorCount) div $testCount"/>
+ <table class="details" border="0" cellpadding="5" cellspacing="2" width="95%">
+ <tr valign="top">
+ <th>Tests</th>
+ <th>Failures</th>
+ <th>Errors</th>
+ <th>Success rate</th>
+ <th>Time</th>
+ </tr>
+ <tr valign="top">
+ <xsl:attribute name="class">
+ <xsl:choose>
+ <xsl:when test="$errorCount &gt; 0">Error</xsl:when>
+ <xsl:when test="$failureCount &gt; 0">Failure</xsl:when>
+ <xsl:otherwise>Pass</xsl:otherwise>
+ </xsl:choose>
+ </xsl:attribute>
+ <td><a title="Display all tests" href="all-tests.html"><xsl:value-of select="$testCount"/></a></td>
+ <td><a title="Display all failures" href="alltests-fails.html"><xsl:value-of select="$failureCount"/></a></td>
+ <td><a title="Display all errors" href="alltests-errors.html"><xsl:value-of select="$errorCount"/></a></td>
+ <td>
+ <xsl:call-template name="display-percent">
+ <xsl:with-param name="value" select="$successRate"/>
+ </xsl:call-template>
+ </td>
+ <td>
+ <xsl:call-template name="display-time">
+ <xsl:with-param name="value" select="$timeCount"/>
+ </xsl:call-template>
+ </td>
+ </tr>
+ </table>
+ <table border="0" width="95%">
+ <tr>
+ <td style="text-align: justify;">
+ Note: <em>failures</em> are anticipated and checked for with assertions while <em>errors</em> are unanticipated.
+ </td>
+ </tr>
+ </table>
+
+ <h2>Packages</h2>
+ <table class="details" border="0" cellpadding="5" cellspacing="2" width="95%">
+ <xsl:call-template name="testsuite.test.header"/>
+ <xsl:for-each select="testsuite[not(./@package = preceding-sibling::testsuite/@package)]">
+ <xsl:sort select="@package" order="ascending"/>
+ <!-- get the node set containing all testsuites that have the same package -->
+ <xsl:variable name="insamepackage" select="/testsuites/testsuite[./@package = current()/@package]"/>
+ <tr valign="top">
+ <!-- display a failure if there is any failure/error in the package -->
+ <xsl:attribute name="class">
+ <xsl:choose>
+ <xsl:when test="sum($insamepackage/@errors) &gt; 0">Error</xsl:when>
+ <xsl:when test="sum($insamepackage/@failures) &gt; 0">Failure</xsl:when>
+ <xsl:otherwise>Pass</xsl:otherwise>
+ </xsl:choose>
+ </xsl:attribute>
+ <td><a href="./{translate(@package,'.','/')}/package-summary.html">
+ <xsl:value-of select="@package"/>
+ <xsl:if test="@package = ''">&lt;none&gt;</xsl:if>
+ </a></td>
+ <td><xsl:value-of select="sum($insamepackage/@tests)"/></td>
+ <td><xsl:value-of select="sum($insamepackage/@errors)"/></td>
+ <td><xsl:value-of select="sum($insamepackage/@failures)"/></td>
+ <td>
+ <xsl:call-template name="display-time">
+ <xsl:with-param name="value" select="sum($insamepackage/@time)"/>
+ </xsl:call-template>
+ </td>
+ <td><xsl:value-of select="$insamepackage/@timestamp"/></td>
+ <td><xsl:value-of select="$insamepackage/@hostname"/></td>
+ </tr>
+ </xsl:for-each>
+ </table>
+ </body>
+ </html>
+</xsl:template>
+
+
+<xsl:template name="package.summary">
+ <xsl:param name="name"/>
+ <html>
+ <head>
+ <xsl:call-template name="create.stylesheet.link">
+ <xsl:with-param name="package.name" select="$name"/>
+ </xsl:call-template>
+ </head>
+ <body>
+ <xsl:attribute name="onload">open('package-frame.html','classListFrame')</xsl:attribute>
+ <xsl:call-template name="pageHeader"/>
+ <h3>Package <xsl:value-of select="$name"/></h3>
+
+ <!--table border="0" cellpadding="5" cellspacing="2" width="95%">
+ <xsl:call-template name="class.metrics.header"/>
+ <xsl:apply-templates select="." mode="print.metrics"/>
+ </table-->
+
+ <xsl:variable name="insamepackage" select="/testsuites/testsuite[./@package = $name]"/>
+ <xsl:if test="count($insamepackage) &gt; 0">
+ <h2>Classes</h2>
+ <p>
+ <table class="details" border="0" cellpadding="5" cellspacing="2" width="95%">
+ <xsl:call-template name="testsuite.test.header"/>
+ <xsl:apply-templates select="$insamepackage" mode="print.test">
+ <xsl:sort select="@name"/>
+ </xsl:apply-templates>
+ </table>
+ </p>
+ </xsl:if>
+ </body>
+ </html>
+</xsl:template>
+
+
+<!--
+ transform string like a.b.c to ../../../
+ @param path the path to transform into a descending directory path
+-->
+<xsl:template name="path">
+ <xsl:param name="path"/>
+ <xsl:if test="contains($path,'.')">
+ <xsl:text>../</xsl:text>
+ <xsl:call-template name="path">
+ <xsl:with-param name="path"><xsl:value-of select="substring-after($path,'.')"/></xsl:with-param>
+ </xsl:call-template>
+ </xsl:if>
+ <xsl:if test="not(contains($path,'.')) and not($path = '')">
+ <xsl:text>../</xsl:text>
+ </xsl:if>
+</xsl:template>
+
+
+<!-- create the link to the stylesheet based on the package name -->
+<xsl:template name="create.stylesheet.link">
+ <xsl:param name="package.name"/>
+ <link rel="stylesheet" type="text/css" title="Style"><xsl:attribute name="href"><xsl:if test="not($package.name = 'unnamed package')"><xsl:call-template name="path"><xsl:with-param name="path" select="$package.name"/></xsl:call-template></xsl:if>stylesheet.css</xsl:attribute></link>
+</xsl:template>
+
+
+<!-- Page HEADER -->
+<xsl:template name="pageHeader">
+ <h1>Unit Test Results</h1>
+ <table width="100%">
+ <tr>
+ <td align="left"></td>
+ <td align="right">Designed for use with <a href="http://www.junit.org/">JUnit</a> and <a href="http://ant.apache.org/">Ant</a>.</td>
+ </tr>
+ </table>
+ <hr size="1"/>
+</xsl:template>
+
+<!-- class header -->
+<xsl:template name="testsuite.test.header">
+ <tr valign="top">
+ <th width="80%">Name</th>
+ <th>Tests</th>
+ <th>Errors</th>
+ <th>Failures</th>
+ <th nowrap="nowrap">Time(s)</th>
+ <th nowrap="nowrap">Time Stamp</th>
+ <th>Host</th>
+ </tr>
+</xsl:template>
+
+<!-- method header -->
+<xsl:template name="testcase.test.header">
+ <xsl:param name="show.class" select="''"/>
+ <tr valign="top">
+ <xsl:if test="boolean($show.class)">
+ <th>Class</th>
+ </xsl:if>
+ <th>Name</th>
+ <th>Status</th>
+ <th width="80%">Type</th>
+ <th nowrap="nowrap">Time(s)</th>
+ </tr>
+</xsl:template>
+
+
+<!-- class information -->
+<xsl:template match="testsuite" mode="print.test">
+ <tr valign="top">
+ <xsl:attribute name="class">
+ <xsl:choose>
+ <xsl:when test="@errors[.&gt; 0]">Error</xsl:when>
+ <xsl:when test="@failures[.&gt; 0]">Failure</xsl:when>
+ <xsl:otherwise>Pass</xsl:otherwise>
+ </xsl:choose>
+ </xsl:attribute>
+ <td><a title="Display all tests" href="{@id}_{@name}.html"><xsl:value-of select="@name"/></a></td>
+ <td><a title="Display all tests" href="{@id}_{@name}.html"><xsl:apply-templates select="@tests"/></a></td>
+ <td>
+ <xsl:choose>
+ <xsl:when test="@errors != 0">
+ <a title="Display only errors" href="{@id}_{@name}-errors.html"><xsl:apply-templates select="@errors"/></a>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:apply-templates select="@errors"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </td>
+ <td>
+ <xsl:choose>
+ <xsl:when test="@failures != 0">
+ <a title="Display only failures" href="{@id}_{@name}-fails.html"><xsl:apply-templates select="@failures"/></a>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:apply-templates select="@failures"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </td>
+ <td><xsl:call-template name="display-time">
+ <xsl:with-param name="value" select="@time"/>
+ </xsl:call-template>
+ </td>
+ <td><xsl:apply-templates select="@timestamp"/></td>
+ <td><xsl:apply-templates select="@hostname"/></td>
+ </tr>
+</xsl:template>
+
+<xsl:template match="testcase" mode="print.test">
+ <xsl:param name="show.class" select="''"/>
+ <tr valign="top">
+ <xsl:attribute name="class">
+ <xsl:choose>
+ <xsl:when test="error">Error</xsl:when>
+ <xsl:when test="failure">Failure</xsl:when>
+ <xsl:otherwise>TableRowColor</xsl:otherwise>
+ </xsl:choose>
+ </xsl:attribute>
+ <xsl:variable name="class.href">
+ <xsl:value-of select="concat(translate(../@package,'.','/'), '/', ../@id, '_', ../@name, '.html')"/>
+ </xsl:variable>
+ <xsl:if test="boolean($show.class)">
+ <td><a href="{$class.href}"><xsl:value-of select="../@name"/></a></td>
+ </xsl:if>
+ <td>
+ <a name="{@name}"/>
+ <xsl:choose>
+ <xsl:when test="boolean($show.class)">
+ <a href="{concat($class.href, '#', @name)}"><xsl:value-of select="@name"/></a>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="@name"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </td>
+ <xsl:choose>
+ <xsl:when test="failure">
+ <td>Failure</td>
+ <td><xsl:apply-templates select="failure"/></td>
+ </xsl:when>
+ <xsl:when test="error">
+ <td>Error</td>
+ <td><xsl:apply-templates select="error"/></td>
+ </xsl:when>
+ <xsl:otherwise>
+ <td>Success</td>
+ <td></td>
+ </xsl:otherwise>
+ </xsl:choose>
+ <td>
+ <xsl:call-template name="display-time">
+ <xsl:with-param name="value" select="@time"/>
+ </xsl:call-template>
+ </td>
+ </tr>
+</xsl:template>
+
+
+<!-- Note : the below template error and failure are the same style
+ so just call the same style store in the toolkit template -->
+<xsl:template match="failure">
+ <xsl:call-template name="display-failures"/>
+</xsl:template>
+
+<xsl:template match="error">
+ <xsl:call-template name="display-failures"/>
+</xsl:template>
+
+<!-- Style for the error and failure in the testcase template -->
+<xsl:template name="display-failures">
+ <xsl:choose>
+ <xsl:when test="not(@message)">N/A</xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="@message"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ <!-- display the stacktrace -->
+ <br/><br/>
+ <code>
+ <xsl:call-template name="br-replace">
+ <xsl:with-param name="word" select="."/>
+ </xsl:call-template>
+ </code>
+ <!-- the latter is better but might be problematic for non-21" monitors... -->
+ <!--pre><xsl:value-of select="."/></pre-->
+</xsl:template>
+
+<xsl:template name="JS-escape">
+ <xsl:param name="string"/>
+ <xsl:param name="tmp1" select="stringutils:replace(string($string),'\','\\')"/>
+ <xsl:param name="tmp2" select="stringutils:replace(string($tmp1),&quot;'&quot;,&quot;\&apos;&quot;)"/>
+ <xsl:value-of select="$tmp2"/>
+</xsl:template>
+
+
+<!--
+ template that will convert a carriage return into a br tag
+ @param word the text from which to convert CR to BR tag
+-->
+<xsl:template name="br-replace">
+ <xsl:param name="word"/>
+ <xsl:value-of disable-output-escaping="yes" select='stringutils:replace(string($word),"&#xA;","&lt;br/>")'/>
+</xsl:template>
+
+<xsl:template name="display-time">
+ <xsl:param name="value"/>
+ <xsl:value-of select="format-number($value,'0.000')"/>
+</xsl:template>
+
+<xsl:template name="display-percent">
+ <xsl:param name="value"/>
+ <xsl:value-of select="format-number($value,'0.00%')"/>
+</xsl:template>
+</xsl:stylesheet>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/native2ascii/build.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/native2ascii/build.xml
new file mode 100644
index 00000000..27b40313
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/native2ascii/build.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0"?>
+
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="no">
+
+ <import file="../../../buildfiletest-base.xml"/>
+
+ <target name="setUp">
+ <mkdir dir="${output}"/>
+ </target>
+
+ <property name="in" location="input"/>
+
+ <target name="no">
+ <fail>For tests only</fail>
+ </target>
+
+ <target name="testIso8859-1" depends="setUp">
+ <native2ascii encoding="ISO8859-1" dest="${output}"
+ src="${in}" includes="iso8859-1.*"/>
+ </target>
+</project>
+ \ No newline at end of file
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/native2ascii/expected/iso8859-1.test b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/native2ascii/expected/iso8859-1.test
new file mode 100644
index 00000000..d60acc83
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/native2ascii/expected/iso8859-1.test
@@ -0,0 +1 @@
+\u00e4\u00f6\u00fc\u00c4\u00d6\u00dc\u00df
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/native2ascii/input/iso8859-1.test b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/native2ascii/input/iso8859-1.test
new file mode 100644
index 00000000..d5b3934f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/native2ascii/input/iso8859-1.test
@@ -0,0 +1 @@
+äöüÄÖÜß \ No newline at end of file
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/net/ftp.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/net/ftp.xml
new file mode 100644
index 00000000..aaf4b8e6
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/net/ftp.xml
@@ -0,0 +1,331 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="ftp-test" basedir=".">
+ <property file="../../../../../../ftp.properties"/>
+ <property environment="env"/>
+ <property file="${env.HOME}/ant-ftp.properties"/>
+ <property name="ftp.user" value="${user.name}"/>
+ <property name="ftp.host" value="localhost"/>
+ <property name="ftp.port" value="21" />
+ <property name="ftp.password" value="sunshine" />
+ <property name="ftp.filesep" value="/"/>
+ <property name="tmp.dir" location="tmp"/>
+ <property name="tmp.get.dir" location="tmp.get"/>
+ <property name="tmp.local" location="${tmp.get.dir}"/>
+ <property name="tmp.remote" location="${tmp.dir}"/>
+ <property name="tstamp.format" value="yyyy-MM-dd HH:mm"/>
+ <property name="server.timestamp.granularity.millis" value="60000"/>
+ <property name="ftp.server.timezone" value="GMT"/>
+ <property name="ftp.listing.file" value="/dev/null"/>
+ <property name="ftp.retries" value="2"/>
+
+ <fileset dir="${tmp.get.dir}" id="fileset-destination-with-selector">
+ <include name="alpha/**"/>
+ <filename name="**/alpha.xml" />
+ </fileset>
+ <fileset dir="${tmp.dir}" id="fileset-source-without-selector">
+ <include name="alpha/**"/>
+ </fileset>
+ <fileset dir="${tmp.get.dir}" id="fileset-destination-without-selector">
+ <include name="alpha/**"/>
+ </fileset>
+ <fileset dir="${tmp.get.dir}" id="fileset-destination-followsymlinks" followsymlinks="true">
+ <include name="alpha/**"/>
+ </fileset>
+ <fileset dir="${tmp.get.dir}" id="fileset-destination-nofollowsymlinks" followsymlinks="false">
+ <include name="alpha/**"/>
+ </fileset>
+
+ <filelist dir="${tmp.local}" id="timed-files" files="A.timed,B.timed,C.timed,D.timed"/>
+
+ <patternset id="timed-test-files">
+ <include name="A.timed"/>
+ <include name="B.timed"/>
+ <include name="C.timed"/>
+ <include name="D.timed"/>
+ </patternset>
+
+ <target name="setup">
+ <mkdir dir="${tmp.get.dir}"/>
+ <mkdir dir="${tmp.dir}/alpha/beta/gamma"/>
+ <touch file="${tmp.dir}/alpha/beta/gamma/gamma.xml"/>
+ <touch file="${tmp.dir}/alpha/beta/beta.xml"/>
+ </target>
+
+ <target name="ftp-get-with-selector">
+ <ftp action="get"
+ server="${ftp.host}"
+ userid="${ftp.user}"
+ password="${ftp.password}"
+ separator="${ftp.filesep}"
+ remotedir="${tmp.dir}">
+ <fileset refid="fileset-destination-with-selector"/>
+ </ftp>
+ </target>
+ <target name="children-of-excluded-dir-setup" depends="setup">
+ <mkdir dir="${tmp.dir}/delta"/>
+ <touch file="${tmp.dir}/delta/delta.xml"/>
+ </target>
+ <target name="cleanup">
+ <delete dir="${tmp.dir}" quiet="true"/>
+ <delete dir="${tmp.get.dir}" quiet="true"/>
+ </target>
+ <target name="symlink-setup" depends="setup">
+ <mkdir dir="${tmp.dir}/epsilon/gamma"/>
+ <delete dir="${tmp.dir}/alpha/beta"/>
+ <symlink link="${tmp.dir}/alpha/beta" resource="${tmp.dir}/epsilon"/>
+ <touch file="${tmp.dir}/alpha/beta/gamma/gamma.xml"/>
+ </target>
+ <target name="ftp-get-directory-symbolic-link" depends="symlink-setup">
+ <ftp action="get"
+ server="${ftp.host}"
+ userid="${ftp.user}"
+ password="${ftp.password}"
+ separator="${ftp.filesep}"
+ remotedir="${tmp.dir}"
+ >
+ <fileset refid="fileset-destination-followsymlinks"/>
+ </ftp>
+ </target>
+ <target name="ftp-get-directory-no-symbolic-link" depends="symlink-setup">
+ <ftp action="get"
+ server="${ftp.host}"
+ userid="${ftp.user}"
+ password="${ftp.password}"
+ separator="${ftp.filesep}"
+ remotedir="${tmp.dir}"
+ >
+ <fileset refid="fileset-destination-nofollowsymlinks"/>
+ </ftp>
+ </target>
+ <target name="symlink-file-setup" depends="setup">
+ <delete file="${tmp.dir}/alpha/beta/gamma/gamma.xml"/>
+ <symlink link="${tmp.dir}/alpha/beta/gamma/gamma.xml"
+ resource="${tmp.dir}/alpha/beta/beta.xml"/>
+ </target>
+ <target name="ftp-delete">
+ <!-- this target can produce an error if the rmdir does not work -->
+ <!-- there can be problems with the rmdir action if the directories are not removed in a proper order -->
+ <!-- which means beginning by the leaves of the tree, going back to the trunk -->
+ <ftp action="del"
+ server="${ftp.host}"
+ userid="${ftp.user}"
+ password="${ftp.password}"
+ remotedir="${tmp.dir}">
+ <fileset dir="${tmp.get.dir}">
+ <include name="**"/>
+ </fileset>
+ </ftp>
+ <ftp action="rmdir"
+ server="${ftp.host}"
+ userid="${ftp.user}"
+ password="${ftp.password}"
+ remotedir="${tmp.dir}">
+ <fileset dir="${tmp.get.dir}">
+ <include name="**"/>
+ </fileset>
+ </ftp>
+ </target>
+
+ <target name="timed.test.setup">
+ <touch>
+ <filelist refid="timed-files"/>
+ </touch>
+ <ftp action="put"
+ server="${ftp.host}"
+ userid="${ftp.user}"
+ password="${ftp.password}"
+ separator="${ftp.filesep}"
+ remotedir="${tmp.remote}"
+ >
+ <fileset dir="${tmp.local}">
+ <patternset refid="timed-test-files"/>
+ </fileset>
+ </ftp>
+ </target>
+
+ <target name="timed.test.put.older">
+ <tstamp>
+ <format property="one.minute.older" pattern="${tstamp.format}" offset="-60" unit="second"/>
+ </tstamp>
+
+ <touch datetime="${one.minute.older}" pattern="${tstamp.format}" verbose="true">
+ <fileset dir="${tmp.remote}">
+ <include name="A.timed"/>
+ </fileset>
+ </touch>
+ <ftp action="put"
+ server="${ftp.host}"
+ userid="${ftp.user}"
+ password="${ftp.password}"
+ separator="${ftp.filesep}"
+ remotedir="${tmp.remote}"
+ newer="true"
+ serverTimeZoneConfig="${ftp.server.timezone}"
+ >
+ <fileset dir="${tmp.local}">
+ <patternset refid="timed-test-files"/>
+ </fileset>
+ </ftp>
+ </target>
+ <target name="timed.test.get.older">
+ <tstamp>
+ <format property="five.minutes.older" pattern="${tstamp.format}" offset="-5" unit="minute"/>
+ </tstamp>
+
+ <touch datetime="${five.minutes.older}" pattern="${tstamp.format}" verbose="true">
+ <fileset dir="${tmp.local}">
+ <include name="A.timed"/>
+ <include name="C.timed"/>
+ <include name="D.timed"/>
+ </fileset>
+ </touch>
+ <ftp action="get"
+ server="${ftp.host}"
+ userid="${ftp.user}"
+ password="${ftp.password}"
+ separator="${ftp.filesep}"
+ remotedir="${tmp.remote}"
+ preservelastmodified="true"
+ newer="true"
+ serverTimeZoneConfig="${ftp.server.timezone}"
+ >
+ <fileset dir="${tmp.local}">
+ <patternset refid="timed-test-files"/>
+ </fileset>
+ </ftp>
+ </target>
+
+ <target name="configuration.1">
+ <ftp action="list"
+ server="${ftp.host}"
+ userid="${ftp.user}"
+ password="${ftp.password}"
+ separator="${ftp.filesep}"
+ remotedir="${tmp.remote}"
+ serverTimeZoneConfig="${ftp.server.timezone}"
+ listing="${ftp.listing.file}"
+ >
+ <fileset dir="${tmp.local}"/>
+ </ftp>
+ </target>
+ <target name="configuration.2">
+ <ftp action="list"
+ server="${ftp.host}"
+ userid="${ftp.user}"
+ password="${ftp.password}"
+ separator="${ftp.filesep}"
+ remotedir="${tmp.remote}"
+ serverTimeZoneConfig="${ftp.server.timezone}"
+ listing="${ftp.listing.file}"
+ systemTypeKey="WINDOWS"
+ >
+ <fileset dir="${tmp.local}"/>
+ </ftp>
+ </target>
+ <target name="configuration.3">
+ <ftp action="list"
+ server="${ftp.host}"
+ userid="${ftp.user}"
+ password="${ftp.password}"
+ separator="${ftp.filesep}"
+ remotedir="${tmp.remote}"
+ defaultDateFormatConfig="yyyy/MM/dd HH:mm"
+ listing="${ftp.listing.file}"
+ systemTypeKey="UNIX"
+ >
+ <fileset dir="${tmp.local}"/>
+ </ftp>
+ </target>
+ <target name="configuration.lang.good">
+ <ftp action="list"
+ server="${ftp.host}"
+ userid="${ftp.user}"
+ password="${ftp.password}"
+ separator="${ftp.filesep}"
+ remotedir="${tmp.remote}"
+ serverLanguageCodeConfig="de"
+ listing="${ftp.listing.file}"
+ >
+ <fileset dir="${tmp.local}"/>
+ </ftp>
+ </target>
+ <target name="configuration.lang.bad">
+ <ftp action="list"
+ server="${ftp.host}"
+ userid="${ftp.user}"
+ password="${ftp.password}"
+ separator="${ftp.filesep}"
+ remotedir="${tmp.remote}"
+ serverLanguageCodeConfig="QQ"
+ listing="${ftp.listing.file}"
+ >
+ <fileset dir="${tmp.local}"/>
+ </ftp>
+ </target>
+ <target name="configuration.none">
+ <ftp action="list"
+ server="${ftp.host}"
+ userid="${ftp.user}"
+ password="${ftp.password}"
+ separator="${ftp.filesep}"
+ remotedir="${tmp.remote}"
+ listing="${ftp.listing.file}"
+ >
+ <fileset dir="${tmp.local}"/>
+ </ftp>
+ </target>
+ <target name="ftp-get-with-selector-retryable">
+ <ftp action="get"
+ server="${ftp.host}"
+ userid="${ftp.user}"
+ password="${ftp.password}"
+ separator="${ftp.filesep}"
+ remotedir="${tmp.dir}"
+ retriesAllowed="${ftp.retries}"
+ >
+ <fileset refid="fileset-destination-with-selector"/>
+ </ftp>
+ </target>
+ <target name="test-initial-command">
+ <ftp action="put"
+ server="${ftp.host}"
+ userid="${ftp.user}"
+ password="${ftp.password}"
+ separator="${ftp.filesep}"
+ remotedir="${tmp.remote}"
+ initialSiteCommand="umask 222"
+ >
+ <fileset dir="${tmp.local}">
+ <patternset refid="timed-test-files"/>
+ </fileset>
+ </ftp>
+ </target>
+
+ <target name="test-site-action">
+ <ftp action="site"
+ server="${ftp.host}"
+ userid="${ftp.user}"
+ password="${ftp.password}"
+ separator="${ftp.filesep}"
+ remotedir="${tmp.remote}"
+ siteCommand="umask 222"
+ >
+ </ftp>
+ </target>
+</project> \ No newline at end of file
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/propertyfile.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/propertyfile.xml
new file mode 100644
index 00000000..20a17271
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/propertyfile.xml
@@ -0,0 +1,123 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<project name="propertyfile-test" default="main" basedir=".">
+
+ <import file="../../buildfiletest-base.xml"/>
+
+ <target name="setUp">
+ <mkdir dir="${output}" />
+ </target>
+
+ <property file="${output}/propertyfile.build.properties"/>
+
+ <target name="main">
+ <fail>
+ This file is for testing purposes only...
+ @see PropertyFileTest.java for more info.
+ </fail>
+ </target>
+
+ <target name="update-existing-properties">
+ <propertyfile
+ file="${output}/${test.propertyfile}"
+ comment="unit test for the property file task..." >
+ <entry key="firstname" value="${firstname}" />
+ <entry key="lastname" value="${lastname}" />
+ <entry key="email" value="${email}" />
+ <entry key="phone" default="${phone}" />
+ <entry key="age" default="${age}" type="int"/>
+ <entry key="date" default="${date}" type="date"/>
+ </propertyfile>
+ </target>
+
+ <target name="delete-properties">
+ <echoproperties/>
+ <propertyfile
+ file="${output}/${test.propertyfile}"
+ comment="unit test for the property file task..." >
+ <entry key="firstname" operation="del" />
+ </propertyfile>
+ </target>
+
+ <target name="exercise">
+ <propertyfile file="${output}/${test.propertyfile}">
+ <entry key="existing.prop"
+ type="int"
+ default="23"/>
+ <entry key="ethans.birth"
+ value="2002/01/21 12:18"
+ type="date"/>
+ <entry key="first.birthday"
+ value="1"
+ default="2002/01/21"
+ pattern="yyyy/MM/dd"
+ unit="year"
+ type="date"
+ operation="+"/>
+ <entry key="int.with.default"
+ value="1"
+ default="2"
+ operation="+"
+ type="int"/>
+ <entry key="int.without.value"
+ default="5"
+ operation="+"
+ type="int"/>
+ <entry key="int.without.default"
+ value="1"
+ operation="+"
+ type="int"/>
+ <entry key="string.with.default"
+ value="&gt;"
+ default="--"
+ operation="+"/>
+ <entry key="string.without.default"
+ value="."
+ operation="+"/>
+ <entry key="olderThanAWeek"
+ type="date"
+ default="0201"
+ operation="-"
+ value="8"
+ pattern="MMdd"/>
+ </propertyfile>
+ <property file="${output}/${test.propertyfile}"/>
+ </target>
+
+ <target name="createfile">
+ <echo file="${output}/${overwrite.test.propertyfile}">
+ foo=3
+ </echo>
+ </target>
+
+ <target name="bugDemo1" depends="createfile,bugDemoInit"/>
+
+ <target name="bugDemo2" depends="bugDemoInit">
+ <property file="${output}/${overwrite.test.propertyfile}"/>
+ </target>
+
+ <target name="bugDemoInit">
+ <propertyfile file="${output}/${overwrite.test.propertyfile}">
+ <entry key="foo" default="0" value="1" operation="+" type="int"/>
+ </propertyfile>
+ </target>
+
+</project>
+
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/pvcs.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/pvcs.xml
new file mode 100644
index 00000000..99bfcff4
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/pvcs.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<project name="pvcs-test" basedir="." default="test1">
+
+ <taskdef name="pvcs" classname="org.apache.tools.ant.taskdefs.Pvcs"/>
+
+ <target name="test1">
+ <pvcs/>
+ </target>
+
+ <target name="test2">
+ <pvcs pvcsbin="/home/tc/projects/pvcsant/src/etc/testcases/taskdefs" repository="/mnt/pvcs"/>
+ </target>
+
+ <target name="test3">
+ <pvcs pvcsbin="\home\cvs\pvcsant\src\etc\testcases\taskdefs" repository="/mnt/pvcs" pvcsproject="/qviknet"/>
+ </target>
+
+ <target name="test4">
+ <pvcs pvcsbin="\home\cvs\pvcsant\src\etc\testcases\taskdefs" repository="/mnt/pvcs" pvcsproject="/qviknet" workspace="/@/Public/buildws"/>
+ </target>
+
+ <target name="test5" description="Get the latest from PVCS">
+ <pvcs pvcsbin="/home/cvs/pvcsant/src/etc/testcases/taskdefs"
+ repository="//ct4serv2/pvcs/monitor"/>
+ </target>
+
+ <target name="test6" description="No pcli to be found">
+ <pvcs pvcsbin="/never/heard/of/a/directory/structure/like/this"
+ repository="//ct4serv2/pvcs/monitor"/>
+ </target>
+
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/replaceregexp.properties b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/replaceregexp.properties
new file mode 100644
index 00000000..d7f057e6
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/replaceregexp.properties
@@ -0,0 +1,16 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+OldAbc=Def
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/replaceregexp.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/replaceregexp.xml
new file mode 100644
index 00000000..58fdc59c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/replaceregexp.xml
@@ -0,0 +1,83 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="test" default="def" basedir=".">
+ <import file="../../buildfiletest-base.xml"/>
+
+ <property name="root" location="../../../../.."/>
+
+ <target name="setUp">
+ <mkdir dir="${output}" />
+ <copy file="replaceregexp.properties" tofile="${output}/test.properties" />
+ </target>
+
+ <target name="def">
+ <fail>This build file should only be run from within the testcase</fail>
+ </target>
+
+ <target name="setUp-nl">
+ <mkdir dir="${output}" />
+ <copy file="replaceregexp2.properties" tofile="${output}/test.properties" />
+ </target>
+
+ <target name="testReplace" depends="setUp">
+ <replaceregexp file="${output}/test.properties" byline="true">
+ <regexp pattern="Old(.*)=(.*)" />
+ <substitution expression="NewProp=\1\2" />
+ </replaceregexp>
+ </target>
+ <!-- use in conjunction with testDirectoryDateDoesNotChange to make sure something will happen -->
+ <target name="touchDirectory">
+ <copy file="replaceregexp.properties" tofile="${output}/test.properties" />
+
+ </target>
+ <target name="testDirectoryDateDoesNotChange">
+ <replaceregexp file="${output}/test.properties" byline="true">
+ <regexp pattern="foo" />
+ <substitution expression="bar"/>
+ </replaceregexp>
+ </target>
+
+ <target name="testDontAddNewline1" depends="setUp-nl">
+ <replaceregexp file="${output}/test.properties" byline="false">
+ <regexp pattern="Old(.*)=(.*)" />
+ <substitution expression="NewProp=\1\2" />
+ </replaceregexp>
+ </target>
+
+ <target name="testDontAddNewline2" depends="setUp-nl">
+ <replaceregexp file="${output}/test.properties" byline="true">
+ <regexp pattern="Old(.*)=(.*)" />
+ <substitution expression="NewProp=\1\2" />
+ </replaceregexp>
+ </target>
+
+ <target name="lastModifiedSetup">
+ <echo file="${output}/test.txt">Hello, world!</echo>
+ </target>
+
+ <target name="testNoPreserve">
+ <replaceregexp match="world" replace="Ant" file="${output}/test.txt"/>
+ </target>
+
+ <target name="testPreserve">
+ <replaceregexp match="world" replace="Ant" file="${output}/test.txt"
+ preserveLastModified="true"/>
+ </target>
+
+</project>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/replaceregexp2.properties b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/replaceregexp2.properties
new file mode 100644
index 00000000..ada77277
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/replaceregexp2.properties
@@ -0,0 +1,15 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+OldAbc=Def \ No newline at end of file
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/replaceregexp2.result.properties b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/replaceregexp2.result.properties
new file mode 100644
index 00000000..6393cd7a
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/replaceregexp2.result.properties
@@ -0,0 +1,15 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+NewProp=AbcDef \ No newline at end of file
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/schemavalidate.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/schemavalidate.xml
new file mode 100644
index 00000000..f43201e7
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/schemavalidate.xml
@@ -0,0 +1,100 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="validate" default="default" basedir=".">
+
+
+ <property name="doc.xsd" location="xml/doc.xsd"/>
+ <property name="doc-in-ns.xsd" location="xml/doc-in-ns.xsd"/>
+ <property name="namespace" value="http://apache.org/ant/doc/" />
+
+ <property name="endpiece-ns-no-location.xml"
+ location="xml/endpiece-ns-no-location.xml"/>
+
+ <target name="testNoNamespace">
+ <schemavalidate
+ noNamespaceFile="${doc.xsd}"
+ file="xml/endpiece-noSchema.xml">
+ </schemavalidate>
+ </target>
+
+ <target name="testNSMapping">
+ <schemavalidate
+ file="${endpiece-ns-no-location.xml}">
+ <schema namespace="${namespace}" file="${doc-in-ns.xsd}" />
+ <schema namespace="http://apache.org/ant/2"
+ url="http://ant.apache.org/" />
+ </schemavalidate>
+ </target>
+
+ <target name="testNoEmptySchemaNamespace">
+ <schemavalidate
+ file="${endpiece-ns-no-location.xml}">
+ <schema namespace="" file="${doc-in-ns.xsd}" />
+ </schemavalidate>
+ </target>
+
+ <target name="testNoEmptySchemaLocation">
+ <schemavalidate
+ file="${endpiece-ns-no-location.xml}">
+ <schema namespace="${namespace}" />
+ </schemavalidate>
+ </target>
+
+ <target name="testNoFile">
+ <schemavalidate
+ file="${endpiece-ns-no-location.xml}">
+ <schema namespace="${namespace}" file="${namespace}" />
+ </schemavalidate>
+ </target>
+
+ <target name="testNoDoubleSchemaLocation">
+ <schemavalidate
+ file="${endpiece-ns-no-location.xml}">
+ <schema namespace="${namespace}" file="${doc-in-ns.xsd}" url="${namespace}"/>
+ </schemavalidate>
+ </target>
+
+ <target name="testNoDuplicateSchema">
+ <schemavalidate
+ file="${endpiece-ns-no-location.xml}">
+ <schema namespace="${namespace}" file="${doc-in-ns.xsd}" />
+ <schema namespace="${namespace}"
+ url="http://ant.apache.org/" />
+ </schemavalidate>
+ </target>
+
+ <target name="testEqualsSchemasOK">
+ <schemavalidate
+ file="${endpiece-ns-no-location.xml}">
+ <schema namespace="${namespace}" file="${doc-in-ns.xsd}" />
+ <schema namespace="${namespace}" file="${doc-in-ns.xsd}" />
+ </schemavalidate>
+ </target>
+
+ <target name="testFileset">
+ <schemavalidate noNamespaceFile="${doc.xsd}"
+ >
+ <schema namespace="${namespace}" file="${doc-in-ns.xsd}" />
+ <fileset dir="xml"
+ includes="endpiece.xml, endpiece-ns-no-location.xml, endpiece-no-schema.xml" />
+ </schemavalidate>
+ </target>
+
+
+ <target name="default" depends="testNoNamespace,testNSMapping" />
+</project> \ No newline at end of file
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/script.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/script.xml
new file mode 100644
index 00000000..841f70d2
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/script.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="testproject" default="def" basedir=".">
+
+ <target name="def">
+ <fail>This build-file is intended to be run from the test cases</fail>
+ </target>
+
+ <target name="setup1">
+
+ <script language="javascript"> <![CDATA[
+
+ for (i=1; i<=10; i++) {
+ echo = testproject.createTask("echo");
+ setup1.addTask(echo);
+ echo.setMessage(i*i);
+ }
+
+ ]]> </script>
+
+ </target>
+
+ <target name="example1" depends="setup1"/>
+
+ <target name="useBeanshell">
+ <script language="beanshell"><![CDATA[
+ self.log("I'm here", org.apache.tools.ant.Project.MSG_INFO);
+ ]]></script>
+ </target>
+
+</project> \ No newline at end of file
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/script/scriptdef.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/script/scriptdef.xml
new file mode 100644
index 00000000..0d051eae
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/script/scriptdef.xml
@@ -0,0 +1,145 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="testproject" default="def" basedir=".">
+
+ <target name="def">
+ <fail>This build-file is intended to be run from the test cases</fail>
+ </target>
+
+ <target name="simple">
+ <scriptdef name="scripttest" language="javascript">
+ <attribute name="attr1"/>
+ <element name="fileset" type="fileset"/>
+ <![CDATA[
+
+ project.log("Attribute attr1 = " + attributes.get("attr1"));
+ project.log("Fileset basedir = "
+ + elements.get("fileset").get(0).getDir(project));
+
+ ]]>
+ </scriptdef>
+
+ <fileset id="testfileset" dir="."/>
+ <scripttest attr1="test">
+ <fileset refid="testfileset"/>
+ </scripttest>
+ </target>
+
+ <target name="nolang">
+ <scriptdef name="nolang">
+ <![CDATA[
+ java.lang.System.out.println("Hello");
+ ]]>
+ </scriptdef>
+ </target>
+
+ <target name="noname">
+ <scriptdef language="javascript">
+ <![CDATA[
+ java.lang.System.out.println("Hello");
+ ]]>
+ </scriptdef>
+ </target>
+
+ <target name="nestedbyclassname">
+ <scriptdef name="scripttest" language="javascript">
+ <attribute name="attr1"/>
+ <element name="fileset" classname="org.apache.tools.ant.types.FileSet"/>
+ <![CDATA[
+
+ project.log("Attribute attr1 = " + attributes.get("attr1"));
+ project.log("Fileset basedir = "
+ + elements.get("fileset").get(0).getDir(project));
+
+ ]]>
+ </scriptdef>
+
+ <fileset id="testfileset" dir="."/>
+ <scripttest attr1="test">
+ <fileset refid="testfileset"/>
+ </scripttest>
+ </target>
+
+ <target name="noelement">
+ <scriptdef name="scripttest" language="javascript">
+ <attribute name="attr1"/>
+ <element name="fileset" type="fileset"/>
+ <![CDATA[
+ java.lang.System.out.println("Attribute attr1 = " + attributes.get("attr1"));
+ ]]>
+ </scriptdef>
+
+ <scripttest attr1="test">
+ </scripttest>
+ </target>
+
+ <target name="exception">
+ <scriptdef name="scripttest" language="javascript">
+ <attribute name="attr1"/>
+ <element name="fileset" classname="org.apache.tools.ant.types.FileSet"/>
+ <![CDATA[
+
+ java.lang.System.out.println("Attribute attr1 = " + attributes.get("attr1"));
+ java.lang.System.out.println("Fileset basedir = "
+ + elements.get("fileset").get(0).getDir(project));
+
+ ]]>
+ </scriptdef>
+
+ <scripttest attr1="test">
+ </scripttest>
+ </target>
+
+ <target name="doubledef">
+ <scriptdef name="task1" language="javascript">
+ <![CDATA[
+ project.log("Task1");
+ ]]>
+ </scriptdef>
+ <scriptdef name="task2" language="javascript">
+ <![CDATA[
+ project.log("Task2");
+ ]]>
+ </scriptdef>
+ <task1/>
+ <task2/>
+ </target>
+
+ <target name="doubleAttributeDef">
+ <scriptdef name="scripttest" language="javascript">
+ <attribute name="attr1"/>
+ <attribute name="attr1"/>
+ </scriptdef>
+ </target>
+
+ <target name="property">
+ <scriptdef name="scripttest" language="javascript">
+ <attribute name="attr1"/>
+ <![CDATA[
+
+ project.log("Attribute value = " + attributes.get("attr1"));
+ ]]>
+ </scriptdef>
+
+ <property name="testproperty" value="test"/>
+ <scripttest attr1="${testproperty}">
+ </scripttest>
+ </target>
+
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/script_reference.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/script_reference.xml
new file mode 100644
index 00000000..82ccb1ff
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/script_reference.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="test-reference" default="script">
+ <target name="script">
+ <script language="javascript">
+ </script>
+ </target>
+ <target name="def">
+ <taskdef name="my.echo" classname="org.apache.tools.ant.taskdefs.Echo"/>
+ <my.echo id="my.echo.ref" message="hello world"/>
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/sos/sos.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/sos/sos.xml
new file mode 100644
index 00000000..982b47ca
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/sos/sos.xml
@@ -0,0 +1,124 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<project name="sos-test" basedir="." default="sosget.1">
+
+ <!--
+ ===========================================================================
+ Test SOSGet missing attributes
+ ===========================================================================
+ -->
+ <target name="sosget.1">
+ <sosget/>
+ </target>
+
+ <target name="sosget.2">
+ <sosget sosserverpath="192.168.0.1:8888"/>
+ </target>
+
+ <target name="sosget.3">
+ <sosget sosserverpath="192.168.0.1:8888"
+ username="ant"/>
+ </target>
+
+ <target name="sosget.4">
+ <sosget sosserverpath="192.168.0.1:8888"
+ username="ant"
+ vssserverpath="\\server\vss\srcsafe.ini"/>
+ </target>
+
+ <!--
+ ===========================================================================
+ Test SOSCheckin missing attributes
+ ===========================================================================
+ -->
+ <target name="soscheckin.1">
+ <soscheckin/>
+ </target>
+
+ <target name="soscheckin.2">
+ <soscheckin sosserverpath="192.168.0.1:8888"/>
+ </target>
+
+ <target name="soscheckin.3">
+ <soscheckin sosserverpath="192.168.0.1:8888"
+ username="ant"/>
+ </target>
+
+ <target name="soscheckin.4">
+ <soscheckin sosserverpath="192.168.0.1:8888"
+ username="ant"
+ vssserverpath="\\server\vss\srcsafe.ini"/>
+ </target>
+
+ <!--
+ ===========================================================================
+ Test SOSCheckout missing attributes
+ ===========================================================================
+ -->
+ <target name="soscheckout.1">
+ <soscheckout/>
+ </target>
+
+ <target name="soscheckout.2">
+ <soscheckout sosserverpath="192.168.0.1:8888"/>
+ </target>
+
+ <target name="soscheckout.3">
+ <soscheckout sosserverpath="192.168.0.1:8888"
+ username="ant"/>
+ </target>
+
+ <target name="soscheckout.4">
+ <soscheckout sosserverpath="192.168.0.1:8888"
+ username="ant"
+ vssserverpath="\\server\vss\srcsafe.ini"/>
+ </target>
+
+ <!--
+ ===========================================================================
+ Test SOSLabel missing attributes
+ ===========================================================================
+ -->
+ <target name="soslabel.1">
+ <soslabel/>
+ </target>
+
+ <target name="soslabel.2">
+ <soslabel sosserverpath="192.168.0.1:8888"/>
+ </target>
+
+ <target name="soslabel.3">
+ <soslabel sosserverpath="192.168.0.1:8888"
+ username="ant"/>
+ </target>
+
+ <target name="soslabel.4">
+ <soslabel sosserverpath="192.168.0.1:8888"
+ username="ant"
+ vssserverpath="\\server\vss\srcsafe.ini"/>
+ </target>
+
+ <target name="soslabel.5">
+ <soslabel sosserverpath="192.168.0.1:8888"
+ username="ant"
+ vssserverpath="\\server\vss\srcsafe.ini"
+ projectpath="$/SourceRoot/Project"/>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/splash-test.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/splash-test.xml
new file mode 100644
index 00000000..5b5bbe28
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/splash-test.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="test_new_features" name="splash-test" basedir=".">
+
+ <target name="test_old_behaviour">
+ <echo>Old behaviour</echo>
+ <splash showduration="0"/>
+ <sleep seconds="1"/>
+ <sleep seconds="1"/>
+ <sleep seconds="1"/>
+ <sleep seconds="1"/>
+ <sleep seconds="1"/>
+ </target>
+
+ <target name="test_new_features">
+ <echo>New features</echo>
+ <splash progressregexp="Progress: (.*)%" showduration="0" displayText="Test text"/>
+ <sleep seconds="1"/>
+ <echo>Progress: 10%</echo>
+ <sleep seconds="1"/>
+ <echo>Progress: 20%</echo>
+ <sleep seconds="1"/>
+ <echo>Progress: 50%</echo>
+ <sleep seconds="1"/>
+ <echo>Progress: 70%</echo>
+ <sleep seconds="1"/>
+ <echo>Progress: 100%</echo>
+ <sleep seconds="3"/>
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/unix/symlink.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/unix/symlink.xml
new file mode 100644
index 00000000..f039a622
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/unix/symlink.xml
@@ -0,0 +1,354 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<!--
+
+/*
+ * Since the initial version of this file was deveolped on the clock on
+ * an NSF grant I should say the following boilerplate:
+ *
+ * This material is based upon work supported by the National Science
+ * Foundaton under Grant No. EIA-0196404. Any opinions, findings, and
+ * conclusions or recommendations expressed in this material are those
+ * of the author and do not necessarily reflect the views of the
+ * National Science Foundation.
+ */
+
+-->
+
+<project name="symlink-test" basedir="." default="all">
+
+ <!--
+ Since the symlink task and some of these targets rely on
+ calls to exec, it may be possible for the JVM to outrun the
+ execution of the command line system calls, so this value is
+ the number of seconds we give the operating system to
+ catch up before executing a task that depends on the
+ completion of previous tasks. This delay is also added to
+ the end of each target so junit doesn't go testing things
+ before they have finnished (hopefully). Tweak if needed.
+ -->
+
+ <property name="delay" value="0"/>
+
+ <import file="../../../buildfiletest-base.xml"/>
+
+ <target name="setUp">
+ <mkdir dir="${output}" />
+ </target>
+
+
+ <target name="all"
+ depends="setUp, test-single, test-delete, test-record, test-recreate, tearDown"/>
+
+ <!-- test for action = single -->
+ <!--
+ Creates:
+ File: ${output}/symlink.test
+ Link: ${output}/singletest
+ -->
+ <target name="test-single">
+ <touch file="${output}/symlink.test"/>
+ <symlink resource="${output}/symlink.test"
+ link="${output}/singletest"
+ failonerror="yes"/>
+ <sleep seconds="${delay}"/> <!-- make sure OS has time to catch up -->
+ <available file="${output}/symlink.test"
+ property="test.single.file.created"/>
+ <available file="${output}/singletest"
+ property="test.single.link.created"/>
+ </target>
+
+
+
+ <!-- test for action = delete (no calls to command line so no sleep) -->
+
+ <!--
+ Creates:
+ (none)
+ Deletes:
+ Link: ${output}/singletest
+ -->
+
+ <target name="test-delete">
+ <touch file="${output}/symlink.test"/>
+ <symlink resource="${output}/symlink.test"
+ link="${output}/singletest"
+ failonerror="yes"/>
+ <sleep seconds="${delay}"/> <!-- make sure OS has time to catch up -->
+
+ <symlink action="delete" link="${output}/singletest" failonerror="yes"/>
+ <symlink action="delete" link="${output}/symlink.test" failonerror="no"/>
+ <sleep seconds="${delay}"/> <!-- make sure OS has time to catch up -->
+
+ <available file="${output}/symlink.test"
+ property="test.delete.file.still.there"/>
+ <available file="${output}/singletest"
+ property="test.delete.link.still.there"
+ value="ERROR: link deletion failed"/>
+
+ </target>
+
+
+
+ <!-- test for action = record -->
+
+ <!--
+ Creates:
+ Dir: ${output}/symtest1
+ Dir: ${output}/symtest1/symtest2
+ Dir: ${output}/symtest1/symtest3
+ File: ${output}/symtest1/file1
+ File: ${output}/symtest1/symtest2/file2
+ File: ${output}/symtest1/symtest3/fileA
+ File: ${output}/symtest1/symtest3/fileB
+ File: ${output}/symtest1/symtest3/fileC
+ Link: ${output}/symtest1/link1==>${output}/symtest1/file1
+ Link: ${output}/symtest1/link2==>${output}/symtest1/symtest2/file2
+ Link: ${output}/symtest1/symtest2/link3==>
+ ${output}/symtest1/symtest2/file2
+ Link: ${output}/symtest1/dirlink==>${output}/symtest1/symtest3
+ Link: ${output}/symtest1/dirlink2==>${output}/symtest1/symtest3
+ Link: ${output}/symtest1/dirlink3==>${output}/symtest1/symtest3
+ File: ${output}/symtest1/recorded.links
+ File: ${output}/symtest1/symtest2/recorded.links
+ Deletes:
+ (none)
+ -->
+
+ <target name="test-record">
+
+ <mkdir dir="${output}/symtest1"/>
+ <mkdir dir="${output}/symtest1/symtest2"/>
+ <mkdir dir="${output}/symtest1/symtest3"/>
+ <touch file="${output}/symtest1/file1"/>
+ <touch file="${output}/symtest1/symtest2/file2"/>
+
+ <touch file="${output}/symtest1/symtest3/fileA"/>
+ <touch file="${output}/symtest1/symtest3/fileB"/>
+ <touch file="${output}/symtest1/symtest3/fileC"/>
+
+ <symlink resource="${output}/symtest1/file1"
+ link="${output}/symtest1/link1"
+ failonerror="no" />
+ <symlink resource="${output}/symtest1/symtest2/file2"
+ link="${output}/symtest1/link2"
+ failonerror="no" />
+ <symlink resource="${output}/symtest1/symtest2/file2"
+ link="${output}/symtest1/symtest2/link3"
+ failonerror="no" />
+ <symlink resource="${output}/symtest1/symtest3"
+ link="${output}/symtest1/dirlink"
+ failonerror="no" />
+ <symlink resource="${output}/symtest1/symtest3"
+ link="${output}/symtest1/dirlink2"
+ failonerror="no"/>
+ <symlink resource="${output}/symtest1/symtest3"
+ link="${output}/symtest1/dirlink3"
+ failonerror="no"/>
+
+ <sleep seconds="${delay}"/> <!-- make sure OS has time to catch up -->
+
+ <symlink action="record" linkfilename="recorded.links">
+ <fileset dir="${output}/symtest1" includes="**/**"/>
+ </symlink>
+
+ <sleep seconds="${delay}"/> <!-- make sure OS has time to catch up -->
+
+ <!-- Test to see if the directories were created -->
+
+ <available file="${output}/symtest1"
+ type="dir"
+ property="test.record.dir1.created"/>
+
+ <available file="${output}/symtest1/symtest2"
+ type="dir"
+ property="test.record.dir2.created"/>
+
+ <available file="${output}/symtest1/symtest3"
+ type="dir"
+ property="test.record.dir3.created"/>
+
+ <!-- Test to see if the Files were created -->
+
+ <available file="${output}/symtest1/file1"
+ property="test.record.file1.created"/>
+
+ <available file="${output}/symtest1/symtest2/file2"
+ property="test.record.file2.created"/>
+
+ <available file="${output}/symtest1/symtest3/fileA"
+ property="test.record.fileA.created"/>
+
+ <available file="${output}/symtest1/symtest3/fileB"
+ property="test.record.fileB.created"/>
+
+ <available file="${output}/symtest1/symtest3/fileC"
+ property="test.record.fileC.created"/>
+
+ <!-- Test to see if the links were created -->
+
+ <available file="${output}/symtest1/link1"
+ property="test.record.link1.created"/>
+
+ <available file="${output}/symtest1/link2"
+ property="test.record.link2.created"/>
+
+ <available file="${output}/symtest1/symtest2/link3"
+ property="test.record.link3.created"/>
+
+ <available file="${output}/symtest1/dirlink"
+ property="test.record.dirlink.created"/>
+
+ <!-- this is redundant for this test, but used in the recreate test -->
+
+ <available file="${output}/symtest1/dirlink2"
+ property="test.record.dirlink2.created"/>
+
+ <!-- Test to see if the linkfiles were created -->
+
+ <available file="${output}/symtest1/recorded.links"
+ property="test.record.dir1.recorded"/>
+
+ <available file="${output}/symtest1/symtest2/recorded.links"
+ property="test.record.dir2.recorded"/>
+
+ <!-- THIS should not be set -->
+
+ <available file="${output}/symtest1/symtest3/recorded.links"
+ property="test.record.dir3.recorded"
+ value="ERROR: symtest3/recorded.links should not exist"/>
+
+
+ </target>
+
+ <!-- test for action = recreate -->
+
+ <!--
+ Deletes:
+ Link: ${output}/symtest1/link1==>${output}/symtest1/file1
+ Link: ${output}/symtest1/link2==>${output}/symtest1/symtest2/file2
+ Link: ${output}/symtest1/symtest2/link3==>
+ ${output}/symtest1/symtest2/file2
+ Link: ${output}/symtest1/dirlink==>${output}/symtest1/symtest3
+ Link: ${output}/symtest1/dirlink3==>${output}/symtest1/symtest3
+
+ Creates
+ Link: ${output}/symtest1/dirlink3==>${output}/symtest1/symtest2
+
+ Recreates:
+ Link: ${output}/symtest1/link1==>${output}/symtest1/file1
+ Link: ${output}/symtest1/link2==>${output}/symtest1/symtest2/file2
+ Link: ${output}/symtest1/symtest2/link3==>
+ ${output}/symtest1/symtest2/file2
+ Link: ${output}/symtest1/dirlink==>${output}/symtest1/symtest3
+
+ Should Change:
+ Link: ${output}/symtest1/dirlink3==>${output}/symtest1/symtest2
+ to
+ ${output}/symtest1/dirlink3==>${output}/symtest1/symtest3
+
+ Should Not Create (bug 25181):
+ Link: ${output}/symtest1/symtest3/dirlink2==>${output}/symtest1/symtest3
+ -->
+
+ <target name="test-recreate" depends="test-record">
+
+ <symlink action="delete" link="${output}/symtest1/link1"/>
+ <symlink action="delete" link="${output}/symtest1/link2"/>
+ <symlink action="delete" link="${output}/symtest1/symtest2/link3"/>
+ <symlink action="delete" link="${output}/symtest1/dirlink"/>
+ <!-- dirlink2 intentionally not deleted to test bug 25181 -->
+ <symlink action="delete" link="${output}/symtest1/dirlink3"/>
+
+ <sleep seconds="${delay}"/> <!-- make sure OS has time to catch up -->
+
+ <symlink resource="${output}/symtest1/symtest2"
+ link="${output}/symtest1/dirlink3"
+ failonerror="no"/>
+
+ <sleep seconds="${delay}"/> <!-- make sure OS has time to catch up -->
+
+ <available file="${output}/symtest1/link1"
+ property="test.recreate.link1.not.removed"
+ value="ERROR: rm -f symtest1/link1 failed"/>
+
+ <available file="${output}/symtest1/link2"
+ property="test.recreate.link2.not.removed"
+ value="ERROR: rm -f symtest1/link2 failed"/>
+
+ <available file="${output}/symtest1/symtest2/link3"
+ property="test.recreate.link3.not.removed"
+ value="ERROR: rm -f symtest1/symtest2/link3 failed"/>
+
+ <available file="${output}/symtest1/zdirlink"
+ property="test.recreate.zdirlink.not.removed"
+ value="ERROR: rm -f symtest1/zdirlink failed"/>
+
+ <sleep seconds="${delay}"/> <!-- make sure OS has time to do the execs -->
+
+ <symlink action="recreate">
+ <fileset dir="${output}/symtest1" includes="**/recorded.links"/>
+ </symlink>
+
+ <sleep seconds="${delay}"/> <!-- make sure OS has time to catch up -->
+
+ <available file="${output}/symtest1/link1"
+ property="test.recreate.link1.recreated"/>
+
+ <available file="${output}/symtest1/link2"
+ property="test.recreate.link2.recreated"/>
+
+ <available file="${output}/symtest1/symtest2/link3"
+ property="test.recreate.link3.recreated"/>
+
+ <available file="${output}/symtest1/dirlink"
+ property="test.recreate.dirlink.recreated"/>
+
+ <!-- this should not get set -->
+ <available file="${output}/symtest1/symtest3/symtest3"
+ property="test.recreate.dirlink2.recreated.twice"
+ value="ERROR: dirlink2 was created a second time (bug 25181)"/>
+
+ <touch file="${output}/symtest1/dirlink3/WhereAmI"/>
+
+ <sleep seconds="${delay}"/> <!-- make sure OS has time to do the execs -->
+
+ <available file="${output}/symtest1/symtest3/WhereAmI"
+ property="test.recreate.dirlink3.was.altered"/>
+ </target>
+
+
+ <!-- actually tests the symlink methods in FileUtils, but this
+ testfixture already has all the necessary envirnment in place
+ -->
+ <target name="test-fileutils" depends="setUp">
+ <mkdir dir="${output}/dir1"/>
+ <mkdir dir="${output}/dir2"/>
+ <touch file="${output}/file1"/>
+ <touch file="${output}/file2"/>
+ <symlink link="${output}/dir.there" resource="${output}/dir1"/>
+ <symlink link="${output}/dir.notthere" resource="${output}/dir2"/>
+ <symlink link="${output}/file.there" resource="${output}/file1"/>
+ <symlink link="${output}/file.notthere" resource="${output}/file2"/>
+ <delete dir="${output}/dir2"/>
+ <delete file="${output}/file2"/>
+ </target>
+
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/vss/vss.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/vss/vss.xml
new file mode 100644
index 00000000..7c6c0d39
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/vss/vss.xml
@@ -0,0 +1,68 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<project name="vss-test" basedir="." default="vssget.1">
+
+ <!--
+ ===========================================================================
+ Test required attributes
+ ===========================================================================
+ -->
+ <target name="vssget.1">
+ <vssget/>
+ </target>
+
+ <target name="vsslabel.1">
+ <vsslabel/>
+ </target>
+
+ <target name="vsslabel.2">
+ <vsslabel vsspath="$/SourceRoot/Project"/>
+ </target>
+
+ <target name="vsshistory.1">
+ <vsshistory/>
+ </target>
+
+ <target name="vsscheckin.1">
+ <vsscheckin/>
+ </target>
+
+ <target name="vsscheckout.1">
+ <vsscheckout/>
+ </target>
+
+ <target name="vsscheckout.2">
+ <vsscheckout
+ vsspath="$/SourceRoot/Project"
+ filetimestamp="blah"/>
+ </target>
+
+ <target name="vssadd.1">
+ <vssadd/>
+ </target>
+
+ <target name="vsscp.1">
+ <vsscp/>
+ </target>
+
+ <target name="vsscreate.1">
+ <vsscreate/>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xalan-redirect-in.xsl b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xalan-redirect-in.xsl
new file mode 100644
index 00000000..b9d07949
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xalan-redirect-in.xsl
@@ -0,0 +1,37 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
+ xmlns:lxslt="http://xml.apache.org/xslt"
+ xmlns:redirect="http://xml.apache.org/xalan/redirect"
+ extension-element-prefixes="redirect">
+<!--
+This is a test to ensure that systemid is set correctly
+for a xsl...the behavior might be dependent on Xalan1
+and Xalan2...this will be a problem to erase the files :(
+Can take as a systemid the base for the xsl document or
+the base or the JVM working dir just like: new File("xalan-redirect-out.tmp")
+-->
+<xsl:param name="xalan-version" select="'x'"/>
+
+<xsl:template match="/">
+<redirect:write file="./xalan{$xalan-version}-redirect-out.tmp">
+ <test>This should be written to the file</test>
+</redirect:write>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xml/about.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xml/about.xml
new file mode 100644
index 00000000..f6a9dab5
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xml/about.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!DOCTYPE doc PUBLIC
+ "-//stevo//DTD doc 1.0//EN"
+ "http://chemical/brothers"
+ >
+<doc>
+ <section title="About">
+ in the absence of technology, there is only marketing
+ </section>
+</doc>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xml/apache.xsl b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xml/apache.xsl
new file mode 100644
index 00000000..120addf8
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xml/apache.xsl
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ version="1.0">
+
+ <xsl:output method="xml"/>
+
+ <xsl:template match="/">
+ <authors>
+ <xsl:apply-templates/>
+ </authors>
+ </xsl:template>
+ <xsl:template match="author">
+ <author>
+ <xsl:attribute name="name">
+ <xsl:value-of select="@name"/>
+ </xsl:attribute>
+ </author>
+ </xsl:template>
+</xsl:stylesheet>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xml/books.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xml/books.xml
new file mode 100644
index 00000000..17923d7d
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xml/books.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<books>
+ <book name="hamlet">
+ <author name="shakespeare"/>
+ </book>
+ <book name="the lord of rings">
+ <author name="tolkien"/>
+ </book>
+ <book name="le malade imaginaire">
+ <author name="moliere"/>
+ </book>
+</books> \ No newline at end of file
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xml/catalog b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xml/catalog
new file mode 100644
index 00000000..1c9bddf2
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xml/catalog
@@ -0,0 +1,2 @@
+PUBLIC "-//stevo//DTD doc 1.0//EN" "doc.dtd"
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xml/doc-in-ns.xsd b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xml/doc-in-ns.xsd
new file mode 100644
index 00000000..b34147c4
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xml/doc-in-ns.xsd
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ targetNamespace="http://apache.org/ant/doc/"
+ xmlns:tns="http://apache.org/ant/doc/"
+ elementFormDefault="qualified">
+ <xs:element name="doc">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element ref="tns:section"/>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="section">
+ <xs:complexType>
+ <xs:simpleContent>
+ <xs:extension base="xs:string">
+ <xs:attribute name="title" type="xs:string"/>
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+ </xs:element>
+</xs:schema>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xml/doc.dtd b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xml/doc.dtd
new file mode 100644
index 00000000..51629d58
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xml/doc.dtd
@@ -0,0 +1,24 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!ELEMENT doc (section) >
+<!ELEMENT section (#PCDATA)>
+<!ATTLIST section title CDATA #IMPLIED>
+
+
+
+
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xml/doc.xsd b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xml/doc.xsd
new file mode 100644
index 00000000..eeedbcaf
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xml/doc.xsd
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<xs:schema
+ xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ elementFormDefault="qualified">
+ <xs:element name="doc">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element ref="section"/>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="section">
+ <xs:complexType>
+ <xs:simpleContent>
+ <xs:extension base="xs:string">
+ <xs:attribute name="title" type="xs:string"/>
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+ </xs:element>
+</xs:schema>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xml/doc.xsl b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xml/doc.xsl
new file mode 100644
index 00000000..3d9c2a4e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xml/doc.xsl
@@ -0,0 +1,26 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<xsl:stylesheet
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:template="struts template"
+ version="1.0">
+<xsl:output method="text"/>
+<xsl:template match="/">
+<xsl:value-of select="/doc/section"/>
+</xsl:template>
+</xsl:stylesheet>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xml/docwithentity.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xml/docwithentity.xml
new file mode 100644
index 00000000..6435c328
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xml/docwithentity.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!DOCTYPE books [
+ <!ENTITY globaldefinitions SYSTEM "entity.xml">
+]>
+<books>
+ &globaldefinitions;
+ <book name="the lord of rings">
+ <author name="tolkien"/>
+ </book>
+ <book name="le malade imaginaire">
+ <author name="moliere"/>
+ </book>
+</books> \ No newline at end of file
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xml/endpiece-noSchema-invalid.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xml/endpiece-noSchema-invalid.xml
new file mode 100644
index 00000000..ec580854
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xml/endpiece-noSchema-invalid.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<!--
+ Invalid test XML file without any schema refeferences
+-->
+<doc>
+ <section title="endpiece">
+ With a little luck, the network will pick me up.
+ This is Ripley - last survivor of The Nostromo - signing off.
+ </section>
+
+ <invalidelement/>
+
+</doc>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xml/endpiece-noSchema.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xml/endpiece-noSchema.xml
new file mode 100644
index 00000000..7ae559d9
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xml/endpiece-noSchema.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<!--
+ Test XML file without any schema refeferences
+-->
+<doc>
+ <section title="endpiece">
+ With a little luck, the network will pick me up.
+ This is Ripley - last survivor of The Nostromo - signing off.
+ </section>
+
+</doc>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xml/endpiece-ns-no-location.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xml/endpiece-ns-no-location.xml
new file mode 100644
index 00000000..3fe93c7c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xml/endpiece-ns-no-location.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<doc xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="doc-in-ns.xsd" xmlns="http://apache.org/ant/doc/">
+ <section title="endpiece">
+ With a little luck, the network will pick me up.
+ This is Ripley - last survivor of The Nostromo - signing off.
+ </section>
+</doc>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xml/endpiece.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xml/endpiece.xml
new file mode 100644
index 00000000..3fe93c7c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xml/endpiece.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<doc xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="doc-in-ns.xsd" xmlns="http://apache.org/ant/doc/">
+ <section title="endpiece">
+ With a little luck, the network will pick me up.
+ This is Ripley - last survivor of The Nostromo - signing off.
+ </section>
+</doc>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xml/endpiece2.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xml/endpiece2.xml
new file mode 100644
index 00000000..eec49f6f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xml/endpiece2.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<doc xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="doc.xsd"
+ xmlns="http://Massive/Attack+Mezzanine">
+ <section title="endpiece">
+ With a little luck, the network will pick me up.
+ This is Ripley - last survivor of The Nostromo - signing off.
+ <illegal-element/>
+ </section>
+</doc>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xml/entity.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xml/entity.xml
new file mode 100644
index 00000000..a9340e56
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xml/entity.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+ <book name="hamlet">
+ <author name="shakespeare"/>
+ </book>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xml/iso-2022-jp.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xml/iso-2022-jp.xml
new file mode 100644
index 00000000..b325e6da
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xml/iso-2022-jp.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="iso-2022-jp"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!DOCTYPE test [
+ <!ELEMENT test (#PCDATA)>
+]>
+<test>
+ISO-2022-JP $B$N%U%!%$%k!#(B
+</test>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xml/stylesheet_include.xsl b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xml/stylesheet_include.xsl
new file mode 100644
index 00000000..9c1ffad7
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xml/stylesheet_include.xsl
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ version="1.0">
+
+ <xsl:template match="author">
+ <author>
+ <xsl:attribute name="name">
+ <xsl:value-of select="@name"/>
+ </xsl:attribute>
+ </author>
+ </xsl:template>
+</xsl:stylesheet>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xml/stylesheet_with_include.xsl b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xml/stylesheet_with_include.xsl
new file mode 100644
index 00000000..b1feaca8
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xml/stylesheet_with_include.xsl
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ version="1.0">
+
+ <xsl:output method="xml"/>
+ <xsl:include href="stylesheet_include.xsl"/>
+ <xsl:template match="/">
+ <authors>
+ <xsl:apply-templates/>
+ </authors>
+ </xsl:template>
+</xsl:stylesheet>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xml/test.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xml/test.xml
new file mode 100644
index 00000000..7f2abe00
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xml/test.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<root>
+ <a>this is the first line</a>
+ <b><c>not indented</c></b>
+ <b>
+ <c>indented</c>
+ </b>
+</root>
+ \ No newline at end of file
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xml/test.xsl b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xml/test.xsl
new file mode 100644
index 00000000..8d28eb3f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xml/test.xsl
@@ -0,0 +1,25 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+<!-- Copy every node and attributes recursively -->
+ <xsl:template match="node()|@*">
+ <xsl:copy>
+ <xsl:apply-templates select="@*|node()"/>
+ </xsl:copy>
+ </xsl:template>
+</xsl:stylesheet> \ No newline at end of file
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xml/utf-8.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xml/utf-8.xml
new file mode 100644
index 00000000..db442a36
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xml/utf-8.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!DOCTYPE test [
+ <!ELEMENT test (#PCDATA)>
+]>
+<test>
+Liberté, égalité, fraternité!
+</test>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xml/validate.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xml/validate.xml
new file mode 100644
index 00000000..cade722a
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xml/validate.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="validate" default="testValidate" basedir=".">
+
+ <target name="testValidate">
+ <xmlvalidate warn="false">
+ <fileset dir="." includes="about.xml"/>
+ <dtd publicID="-//stevo//DTD doc 1.0//EN"
+ location="doc.dtd"/>
+ </xmlvalidate>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xmlvalidate.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xmlvalidate.xml
new file mode 100644
index 00000000..cd7cc45e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xmlvalidate.xml
@@ -0,0 +1,208 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="validate" default="testValidate" basedir=".">
+
+ <target name="testValidate">
+ <xmlvalidate warn="false">
+ <fileset dir="xml" includes="**/about.xml"/>
+ <dtd publicID="-//stevo//DTD doc 1.0//EN"
+ location="xml/doc.dtd"/>
+ </xmlvalidate>
+ </target>
+
+ <target name="testDeepValidate">
+ <ant dir="xml"
+ antfile="validate.xml"
+ target="testValidate"/>
+ </target>
+
+ <target name="xmlcatalog">
+ <xmlvalidate warn="false">
+ <fileset dir="xml" includes="**/about.xml"/>
+ <xmlcatalog classpath="xml">
+ <dtd publicID="-//stevo//DTD doc 1.0//EN"
+ location="doc.dtd"/>
+ </xmlcatalog>
+ </xmlvalidate>
+ </target>
+
+ <target name="xmlcatalogViaRefid">
+ <xmlcatalog classpath="xml" id="cat">
+ <dtd publicID="-//stevo//DTD doc 1.0//EN" location="doc.dtd"/>
+ </xmlcatalog>
+ <xmlvalidate warn="false">
+ <xmlcatalog refid="cat"/>
+ <fileset dir="xml" includes="**/about.xml"/>
+ </xmlvalidate>
+ </target>
+
+ <target name="xmlcatalognested">
+ <xmlvalidate warn="false">
+ <fileset dir="xml" includes="**/about.xml"/>
+ <xmlcatalog classpath="xml">
+ <entity publicID = "bogusImage"
+ location = "/i/dont/exist.jpg"/>
+ <xmlcatalog>
+ <dtd publicID="-//stevo//DTD doc 1.0//EN"
+ location="doc.dtd"/>
+ </xmlcatalog>
+ </xmlcatalog>
+ </xmlvalidate>
+ </target>
+
+ <!-- The -override tests should pass without resolver.jar -->
+ <target name="xmlcatalogfiles-override">
+ <xmlvalidate warn="false">
+ <fileset dir="xml" includes="**/about.xml"/>
+ <xmlcatalog classpath="xml">
+ <catalogpath>
+ <fileset dir="xml" includes="catalog"/>
+ </catalogpath>
+ <dtd publicID="-//stevo//DTD doc 1.0//EN"
+ location="doc.dtd"/>
+ </xmlcatalog>
+ </xmlvalidate>
+ </target>
+
+ <target name="xmlcatalogpath-override">
+ <xmlvalidate warn="false">
+ <fileset dir="xml" includes="**/about.xml"/>
+ <xmlcatalog classpath="xml">
+ <catalogpath>
+ <pathelement location="xml/catalog"/>
+ </catalogpath>
+ <dtd publicID="-//stevo//DTD doc 1.0//EN"
+ location="doc.dtd"/>
+ </xmlcatalog>
+ </xmlvalidate>
+ </target>
+
+ <target name="xmlcatalogfiles">
+ <xmlvalidate warn="false">
+ <fileset dir="xml" includes="**/about.xml"/>
+ <xmlcatalog classpath="xml">
+ <catalogpath>
+ <fileset dir="xml" includes="catalog"/>
+ </catalogpath>
+ </xmlcatalog>
+ </xmlvalidate>
+ </target>
+
+ <target name="xmlcatalogpath">
+ <xmlvalidate warn="false">
+ <fileset dir="xml" includes="**/about.xml"/>
+ <xmlcatalog classpath="xml">
+ <catalogpath>
+ <pathelement location="xml/catalog"/>
+ </catalogpath>
+ </xmlcatalog>
+ </xmlvalidate>
+ </target>
+
+ <target name="testSchemaGood">
+ <xmlvalidate warn="false" lenient="no" >
+ <fileset dir="xml" includes="endpiece.xml"/>
+
+ <attribute name="http://xml.org/sax/features/validation"
+ value="false"/>
+ <attribute name="http://apache.org/xml/features/validation/schema"
+ value="false"/>
+
+ </xmlvalidate>
+ </target>
+
+ <target name="testSchemaBad">
+ <xmlvalidate warn="false">
+ <fileset dir="xml" includes="endpiece2.xml"/>
+
+ <attribute name="http://xml.org/sax/features/validation"
+ value="true"/>
+ <attribute name="http://apache.org/xml/features/validation/schema"
+ value="true"/>
+ </xmlvalidate>
+ </target>
+
+ <target name="testIso2022Jp">
+ <xmlvalidate warn="false" file="xml/iso-2022-jp.xml"/>
+ </target>
+
+ <target name="testUtf8">
+ <xmlvalidate warn="false" file="xml/utf-8.xml"/>
+ </target>
+
+
+ <!-- Tests property element with XML file that satisfies schema -->
+ <target name="testProperty.validXML">
+
+ <!-- Converts path to URL format -->
+ <pathconvert dirsep="/" property="xsd.file">
+ <path>
+ <pathelement location="xml/doc.xsd"/>
+ </path>
+ </pathconvert>
+
+ <xmlvalidate file="xml/endpiece-noSchema.xml" lenient="false"
+ failonerror="true" warn="true">
+
+ <attribute name="http://apache.org/xml/features/validation/schema"
+ value="true"/>
+
+ <property
+ name="http://apache.org/xml/properties/schema/external-noNamespaceSchemaLocation"
+ value="${xsd.file}"/>
+ </xmlvalidate>
+ </target>
+
+
+ <!-- Tests property element with XML file that fails schema validation -->
+ <target name="testProperty.invalidXML">
+
+ <!-- Converts path to URL format -->
+ <pathconvert dirsep="/" property="xsd.file">
+ <path>
+ <pathelement location="xml/doc.xsd"/>
+ </path>
+ </pathconvert>
+
+ <xmlvalidate file="xml/endpiece-noSchema-invalid.xml" lenient="false"
+ failonerror="true" warn="true">
+
+ <attribute name="http://apache.org/xml/features/validation/schema"
+ value="true"/>
+
+ <property
+ name="http://apache.org/xml/properties/schema/external-noNamespaceSchemaLocation"
+ value="${xsd.file}"/>
+ </xmlvalidate>
+ </target>
+
+ <target name="testSchemaWithXSD">
+ <xmlvalidate warn="false" lenient="false"
+ file="xml/endpiece-noSchema.xml">
+
+ <attribute name="http://apache.org/xml/features/validation/schema"
+ value="true"/>
+ <property
+ name="http://apache.org/xml/properties/schema/external-noNamespaceSchemaLocation"
+ value="${xsd.file}"/>
+
+ </xmlvalidate>
+ </target>
+
+</project>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xslt.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xslt.xml
new file mode 100644
index 00000000..d872ea8c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xslt.xml
@@ -0,0 +1,102 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<project name="xslt" default="tearDown" basedir=".">
+
+ <import file="../../buildfiletest-base.xml"/>
+
+ <target name="setUp">
+ <mkdir dir="${output}" />
+ </target>
+
+ <target name="initNonAscii" depends="setUp">
+ <property name="nonasciidir" value="${output}/&#0227;nt"/>
+ <mkdir dir="${nonasciidir}"/>
+ <copy todir="${nonasciidir}">
+ <fileset dir="xml">
+ <include name="docwithentity.xml"/>
+ <include name="entity.xml"/>
+ </fileset>
+ </copy>
+ </target>
+
+ <target name="testCatchNoDtd" depends="setUp">
+ <xslt basedir="xml" destdir="${output}"
+ includes="about.xml"
+ extension=".txt"
+ style="xml/doc.xsl">
+ </xslt>
+ </target>
+
+ <xmlcatalog id="xdocs.catalog">
+ <dtd publicID="-//stevo//DTD doc 1.0//EN"
+ location="xml/doc.dtd"/>
+ </xmlcatalog>
+
+ <target name="testCatalog" depends="setUp">
+ <xslt destdir="${output}"
+ includes="about.xml"
+ extension=".txt"
+ style="xml/doc.xsl">
+ <xmlcatalog refid="xdocs.catalog"/>
+ </xslt>
+ </target>
+
+ <target name="testOutputProperty" depends="setUp">
+ <xslt in="xml/test.xml"
+ out="${output}/test-out.xml"
+ style="xml/test.xsl">
+ <outputproperty name="method" value="xml"/>
+ <outputproperty name="standalone" value="yes"/>
+ <outputproperty name="encoding" value="iso8859_1"/>
+ <outputproperty name="indent" value="yes"/>
+ </xslt>
+ </target>
+
+
+ <target name="testFactory" depends="setUp">
+ <xslt in="xml/test.xml"
+ out="${output}/test-out.xml"
+ style="xml/test.xsl">
+ <factory name="org.apache.xalan.processor.TransformerFactoryImpl"/>
+ </xslt>
+ </target>
+
+ <target name="testAttribute" depends="setUp">
+ <xslt in="xml/test.xml"
+ out="${output}/test-out.xml"
+ style="xml/test.xsl">
+ <factory name="org.apache.xalan.processor.TransformerFactoryImpl">
+ <attribute name="http://xml.apache.org/xalan/features/optimize" value="true"/>
+ </factory>
+ </xslt>
+ </target>
+ <!-- inspired by bug report 37348 -->
+ <target name="testXMLWithEntitiesInNonAsciiPath" depends="initNonAscii">
+ <xslt in="${nonasciidir}/docwithentity.xml"
+ out="${output}/test-out.xml"
+ style="xml/apache.xsl">
+ </xslt>
+ </target>
+ <target name="testStyleSheetWithInclude" depends="setUp">
+ <xslt in="xml/books.xml"
+ out="${output}/test-out.xml"
+ style="xml/stylesheet_with_include.xsl">
+ </xslt>
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xsltliaison-encoding-in.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xsltliaison-encoding-in.xml
new file mode 100644
index 00000000..80d93369
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xsltliaison-encoding-in.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<root>
+ <message>éŕčďů</message>
+</root>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xsltliaison-encoding-in.xsl b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xsltliaison-encoding-in.xsl
new file mode 100644
index 00000000..f19bf820
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xsltliaison-encoding-in.xsl
@@ -0,0 +1,27 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+
+<xsl:template match="/">
+ <root>
+ <xsl:for-each select="/root/message">
+ <message><xsl:value-of select="."/></message>
+ </xsl:for-each>
+ </root>
+</xsl:template>
+</xsl:stylesheet>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xsltliaison-in.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xsltliaison-in.xml
new file mode 100644
index 00000000..a4b0247b
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xsltliaison-in.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!DOCTYPE project [
+ <!ENTITY include SYSTEM "xsltliaison-include.xml">
+]>
+<project>
+ &include;
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xsltliaison-in.xsl b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xsltliaison-in.xsl
new file mode 100644
index 00000000..852d38af
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xsltliaison-in.xsl
@@ -0,0 +1,20 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+<xsl:include href="xsltliaison-include.xsl"/>
+</xsl:stylesheet>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xsltliaison-include.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xsltliaison-include.xml
new file mode 100644
index 00000000..aebef339
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xsltliaison-include.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!-- to be included by xsltliaison-include.xsl -->
+<task/>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xsltliaison-include.xsl b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xsltliaison-include.xsl
new file mode 100644
index 00000000..986f1b3e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/optional/xsltliaison-include.xsl
@@ -0,0 +1,20 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+<!-- to be included by xsltliaison-in.xsl -->
+</xsl:stylesheet>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/parallel.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/parallel.xml
new file mode 100644
index 00000000..9a3434c1
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/parallel.xml
@@ -0,0 +1,163 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<project name="parallel-test" basedir="." default="help">
+ <target name="testBasic">
+ <parallel>
+ <sequential>
+ <sleep seconds="1"/>
+ <echo message="${test.delayed}"/>
+ </sequential>
+ <echo message="${test.direct}"/>
+ </parallel>
+ </target>
+
+ <target name="testFail">
+ <parallel>
+ <sequential>
+ <sleep seconds="1"/>
+ <echo message="${test.delayed}"/>
+ </sequential>
+ <fail message="${test.failure}"/>
+ </parallel>
+ </target>
+
+ <target name="testThreadCount">
+ <echo>|1/</echo>
+ <parallel threadCount='1' pollInterval="60">
+ <sequential>
+ <echo message="+"/>
+ <sleep milliseconds="30"/>
+ <echo message="-"/>
+ </sequential>
+ <sequential>
+ <echo message="+"/>
+ <sleep milliseconds="60"/>
+ <echo message="-"/>
+ </sequential>
+ <sequential>
+ <echo message="+"/>
+ <sleep milliseconds="90"/>
+ <echo message="-"/>
+ </sequential>
+ </parallel>
+ <echo>|2/</echo>
+ <parallel threadCount='2' pollInterval="30">
+ <sequential>
+ <echo message="+"/>
+ <sleep milliseconds="30"/>
+ <echo message="-"/>
+ </sequential>
+ <sequential>
+ <echo message="+"/>
+ <sleep milliseconds="60"/>
+ <echo message="-"/>
+ </sequential>
+ <sequential>
+ <echo message="+"/>
+ <sleep milliseconds="90"/>
+ <echo message="-"/>
+ </sequential>
+ </parallel>
+ <echo>|3/</echo>
+ <parallel threadCount='3' pollInterval="30">
+ <sequential>
+ <echo message="+"/>
+ <sleep milliseconds="30"/>
+ <echo message="-"/>
+ </sequential>
+ <sequential>
+ <echo message="+"/>
+ <sleep milliseconds="60"/>
+ <echo message="-"/>
+ </sequential>
+ <sequential>
+ <echo message="+"/>
+ <sleep milliseconds="90"/>
+ <echo message="-"/>
+ </sequential>
+ </parallel>
+ <echo>|4/</echo>
+ <parallel threadCount='4' pollInterval="30">
+ <sequential>
+ <echo message="+"/>
+ <sleep milliseconds="30"/>
+ <echo message="-"/>
+ </sequential>
+ <sequential>
+ <echo message="+"/>
+ <sleep milliseconds="60"/>
+ <echo message="-"/>
+ </sequential>
+ <sequential>
+ <echo message="+"/>
+ <sleep milliseconds="90"/>
+ <echo message="-"/>
+ </sequential>
+ </parallel>
+ <echo>|4/</echo>
+ <parallel threadsPerProcessor='1' threadcount='4' pollInterval="30">
+ <sequential>
+ <echo message="+"/>
+ <sleep milliseconds="30"/>
+ <echo message="-"/>
+ </sequential>
+ <sequential>
+ <echo message="+"/>
+ <sleep milliseconds="60"/>
+ <echo message="-"/>
+ </sequential>
+ <sequential>
+ <echo message="+"/>
+ <sleep milliseconds="90"/>
+ <echo message="-"/>
+ </sequential>
+ </parallel>
+ <echo>|</echo>
+
+ </target>
+
+ <target name="testDemux">
+ <parallel>
+ <demuxtest/>
+ <demuxtest/>
+ <demuxtest/>
+ <demuxtest/>
+ <demuxtest/>
+ </parallel>
+ </target>
+
+ <target name="testSingleExit">
+ <parallel>
+ <echo message="all is well"/>
+ <fail message="no it isn't" status="42"/>
+ </parallel>
+ </target>
+
+ <target name="testExitAndOtherException">
+ <parallel>
+ <fail message="no it isn't"/>
+ <fail message="no it isn't" status="42"/>
+ </parallel>
+ </target>
+
+ <target name="help">
+ <echo>Test build file for the &lt;parallel&gt; task.</echo>
+ <echo>Use the various targets to run the tests.</echo>
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/pathconvert.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/pathconvert.xml
new file mode 100644
index 00000000..1cdcc8cd
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/pathconvert.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="pathconvert">
+
+ <path id="testpath">
+ <pathelement path="${ant.file}" />
+ </path>
+
+ <target name="testmap">
+ <pathconvert property="result" dirsep="#">
+ <path refid="testpath" />
+ <map from="${basedir}" to="test" />
+ </pathconvert>
+ </target>
+
+ <target name="testmapper">
+ <pathconvert property="result" dirsep="#">
+ <path refid="testpath" />
+ <mapper type="glob" from="${basedir}*" to="test*" />
+ </pathconvert>
+ </target>
+
+ <target name="testnotargetos">
+ <pathconvert property="result" refid="testpath" />
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/presetdef.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/presetdef.xml
new file mode 100644
index 00000000..695747eb
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/presetdef.xml
@@ -0,0 +1,147 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project>
+ <path id="test-classes">
+ <pathelement location="../../../../build/testcases" />
+ <pathelement path="${java.class.path}" />
+ </path>
+
+ <target name="simple">
+ <presetdef name="my.echo">
+ <echo message="Hello world"/>
+ </presetdef>
+ <my.echo/>
+ </target>
+
+ <target name="text">
+ <presetdef name="my.echo">
+ <echo>Inner Text</echo>
+ </presetdef>
+ <my.echo/>
+ </target>
+
+ <target name="uri">
+ <presetdef name="echo" uri="abc">
+ <echo message="Hello world"/>
+ </presetdef>
+ <x:echo xmlns:x="abc"/>
+ </target>
+
+ <target name="defaulttest">
+ <taskdef name="defaulttest"
+ classname="org.apache.tools.ant.taskdefs.PreSetDefTest$DefaultTest"
+ classpathref="test-classes"/>
+ <presetdef name="d">
+ <defaulttest attribute="true"/>
+ </presetdef>
+ <d attribute="false"/>
+ </target>
+
+ <target name="doubledefault">
+ <taskdef name="defaulttest"
+ classname="org.apache.tools.ant.taskdefs.PreSetDefTest$DefaultTest"
+ classpathref="test-classes"/>
+ <presetdef name="d">
+ <defaulttest attribute="true"/>
+ </presetdef>
+ <presetdef name="dd">
+ <d attribute="false"/>
+ </presetdef>
+ <dd/>
+ <dd attribute="true"/>
+ </target>
+
+ <target name="antTypeTest">
+ <taskdef name="anttypetest"
+ classname="org.apache.tools.ant.taskdefs.PreSetDefTest$AntTypeTest"
+ classpathref="test-classes"/>
+ <presetdef name="java.fileset">
+ <fileset>
+ <include name="**/*.java"/>
+ </fileset>
+ </presetdef>
+
+ <anttypetest>
+ <fileset ant-type="java.fileset" dir="."/>
+ <configured ant-type="java.fileset" dir="."/>
+ </anttypetest>
+ </target>
+
+ <target name="text.optional">
+ <presetdef name="echo.mytext">
+ <echo>MyText</echo>
+ </presetdef>
+ <echo.mytext/>
+ <echo.mytext>override text</echo.mytext>
+ </target>
+
+ <target name="element.order">
+ <presetdef name="el.order">
+ <sequential>
+ <echo>Line 1</echo>
+ </sequential>
+ </presetdef>
+ <el.order>
+ <echo>Line 2</echo>
+ </el.order>
+ </target>
+
+ <target name="element.order2">
+ <presetdef name="el.order">
+ <sequential>
+ <echo>Line 1</echo>
+ </sequential>
+ </presetdef>
+ <presetdef name="el.order2">
+ <el.order>
+ <echo>Line 2</echo>
+ </el.order>
+ </presetdef>
+ <el.order2>
+ <echo>Line 3</echo>
+ </el.order2>
+ </target>
+
+ <target name="correct_taskname_badattr">
+ <presetdef name="mytask">
+ <javac srcdir="whatever"/>
+ </presetdef>
+
+ <javac srcdir="whatever" badattr="whatever"/>
+ </target>
+
+ <target name="correct_taskname_badel">
+ <presetdef name="mytask">
+ <javac srcdir="whatever"/>
+ </presetdef>
+
+ <javac srcdir="whatever">
+ <badel/>
+ </javac>
+ </target>
+
+ <target name="presetdef-with-nested-element-twice">
+ <copy todir=".">
+ <fileset dir="." includes="nonexistent"/>
+ </copy>
+ <presetdef name="copy">
+ <copy verbose="true"/>
+ </presetdef>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/property.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/property.xml
new file mode 100644
index 00000000..87cda8b0
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/property.xml
@@ -0,0 +1,92 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<project name="property-test" basedir="." default="test1">
+
+ <import file="../buildfiletest-base.xml"/>
+
+ <target name="setUp">
+ <mkdir dir="${output}" />
+ </target>
+
+ <available property="java5+" classname="java.lang.Iterable"/>
+
+ <target name="test1">
+ <property environment="testenv"/>
+ </target>
+
+ <target name="test2">
+ <property name="testprop1" value="aa"/>
+ <property file="property1.properties"/>
+ <echo message="testprop1=${testprop1}, testprop3=${testprop3}, testprop4=${testprop4}"/>
+ </target>
+
+ <target name="test3">
+ <property file="property2.properties"/>
+ </target>
+
+ <target name="test4">
+ <property name="http.port" value="999" />
+ <property file="property3.properties"/>
+ <echo message="http.url is ${http.url}"/>
+ </target>
+
+ <target name="test5">
+ <property name="http.port" value="999" />
+ <property url="${test5.url}"/>
+ <echo message="http.url is ${http.url}"/>
+ </target>
+
+ <target name="prefix.success">
+ <property file="property3.properties" prefix="server1"/>
+ </target>
+
+ <target name="prefix.fail">
+ <property name="someprop" value="value" prefix="prefix"/>
+ </target>
+
+ <!-- caused an endless loop, PR 21825 -->
+ <target name="testCircularReference">
+ <property file="property4.properties"/>
+ </target>
+
+ <target name="thisIsNotACircularReference">
+ <property file="property5.properties"/>
+ <echo>b is ${b}</echo>
+ </target>
+
+ <target name="genXmlPropFile">
+ <echo file="${output}/props.xml">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
+&lt;!DOCTYPE properties SYSTEM &quot;http://java.sun.com/dtd/properties.dtd&quot;&gt;
+&lt;properties version=&quot;1.0&quot;&gt;
+ &lt;comment&gt;
+ Example of property definition according to Suns DTD as
+ specified in the Java5 docs and http://java.sun.com/dtd/properties.dtd.
+ &lt;/comment&gt;
+ &lt;entry key=&quot;xml.one&quot;&gt;ONE&lt;/entry&gt;
+ &lt;entry key=&quot;xml.two&quot;&gt;TWO&lt;/entry&gt;
+&lt;/properties&gt;
+ </echo>
+ </target>
+
+ <target name="testXmlProperty.internal" depends="genXmlPropFile" if="java5+">
+ <property file="${output}/props.xml"/>
+ </target>
+ <target name="testXmlProperty" depends="testXmlProperty.internal"/>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/property1.properties b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/property1.properties
new file mode 100644
index 00000000..ef3ebd30
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/property1.properties
@@ -0,0 +1,17 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+testprop2=xx
+testprop3=${testprop2}yy
+testprop4=${testprop1}zz
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/property2.properties b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/property2.properties
new file mode 100644
index 00000000..81253120
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/property2.properties
@@ -0,0 +1,17 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+testprop1=aa${testprop2}bb
+testprop2=cc${testprop1}dd
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/property3.properties b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/property3.properties
new file mode 100644
index 00000000..ac21612f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/property3.properties
@@ -0,0 +1,18 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+http.port = 80
+http.url = http://localhost:${http.port}
+
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/property4.properties b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/property4.properties
new file mode 100644
index 00000000..65527105
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/property4.properties
@@ -0,0 +1,16 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+a=${a}
+b=${a}/b
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/property5.properties b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/property5.properties
new file mode 100644
index 00000000..e1ebcd37
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/property5.properties
@@ -0,0 +1,17 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+a=A
+b=${a}/${c}/${a}
+c=${a}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/recorder.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/recorder.xml
new file mode 100644
index 00000000..1c073118
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/recorder.xml
@@ -0,0 +1,73 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="recorder-test" default="all" basedir=".">
+
+ <import file="../buildfiletest-base.xml"/>
+
+ <target name="setUp">
+ <mkdir dir="${output}"/>
+ </target>
+
+ <property name="recin" location="recorder"/>
+
+ <target name="all" depends="noappend,append,restart,deleterestart"/>
+
+ <target name="noappend">
+ <copy file="${recin}/rectest2.result" tofile="${output}/rectest1.log"/>
+ <record name="${output}/rectest1.log" action="start"/>
+ <echo message="some message1"/>
+ <record name="${output}/rectest1.log" action="stop"/>
+ </target>
+
+ <target name="append">
+ <copy file="${recin}/rectest1.result" tofile="${output}/rectest2.log"/>
+ <record name="${output}/rectest2.log" append="true" action="start"/>
+ <echo message="some message2"/>
+ <record name="${output}/rectest2.log" action="stop"/>
+ </target>
+
+ <target name="restart">
+ <record name="${output}/rectest3.log" action="start"/>
+ <echo message="some message1"/>
+ <record name="${output}/rectest3.log" action="stop"/>
+ <echo message="some message2"/>
+ <record name="${output}/rectest3.log" action="start"/>
+ <echo message="some message3"/>
+ <record name="${output}/rectest3.log" action="stop"/>
+ </target>
+
+ <target name="deleterestart">
+ <record name="${output}/rectest4.log" action="start"/>
+ <echo message="some message1"/>
+ <record name="${output}/rectest4.log" action="stop"/>
+ <delete file="${output}/rectest4.log"/>
+ <echo message="some message2"/>
+ <record name="${output}/rectest4.log" action="start"/>
+ <echo message="some message3"/>
+ <record name="${output}/rectest4.log" action="stop"/>
+ </target>
+
+ <target name="subbuild">
+ <record name="${output}/rectest5.log" action="start"/>
+ <echo message="some message5"/>
+ <ant antfile="recorder2.xml"/>
+ <record name="${output}/rectest5.log" action="stop"/>
+ </target>
+
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/recorder/rectest1.result b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/recorder/rectest1.result
new file mode 100644
index 00000000..0f8013f3
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/recorder/rectest1.result
@@ -0,0 +1 @@
+ [echo] some message1
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/recorder/rectest2.result b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/recorder/rectest2.result
new file mode 100644
index 00000000..80550fdd
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/recorder/rectest2.result
@@ -0,0 +1,2 @@
+ [echo] some message1
+ [echo] some message2
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/recorder/rectest3.result b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/recorder/rectest3.result
new file mode 100644
index 00000000..e4961774
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/recorder/rectest3.result
@@ -0,0 +1,2 @@
+ [echo] some message1
+ [echo] some message3
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/recorder/rectest4.result b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/recorder/rectest4.result
new file mode 100644
index 00000000..db6239e0
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/recorder/rectest4.result
@@ -0,0 +1 @@
+ [echo] some message3
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/recorder/rectest5.result b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/recorder/rectest5.result
new file mode 100644
index 00000000..7f58ebf8
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/recorder/rectest5.result
@@ -0,0 +1,5 @@
+ [echo] some message5
+
+test6:
+ [echo] some message6
+ [echo] some message8
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/recorder/rectest6.result b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/recorder/rectest6.result
new file mode 100644
index 00000000..c9ceb0b5
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/recorder/rectest6.result
@@ -0,0 +1,3 @@
+ [echo] some message6
+ [echo] some message7
+ [echo] some message8
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/recorder2.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/recorder2.xml
new file mode 100644
index 00000000..e093cf51
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/recorder2.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="recorder-test" default="test6" basedir=".">
+
+ <target name="test6">
+ <record name="${output}/rectest6.log" action="start" />
+ <echo message="some message6"/>
+ <record name="${output}/rectest5.log" action="stop" />
+ <echo message="some message7"/>
+ <record name="${output}/rectest5.log" action="start" />
+ <echo message="some message8"/>
+ <record name="${output}/rectest6.log" action="stop" />
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/rename.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/rename.xml
new file mode 100644
index 00000000..a23a81e1
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/rename.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<project name="xxx-test" basedir="." default="test1">
+
+ <target name="test1">
+ <rename/>
+ </target>
+
+ <target name="test2">
+ <rename src=""/>
+ </target>
+
+ <target name="test3">
+ <rename dest=""/>
+ </target>
+
+ <target name="test4">
+ <rename src="testdir"
+ dest="testdir"/>
+ </target>
+
+ <target name="test5">
+ <rename src="template.xml"
+ dest="."/>
+ </target>
+
+ <target name="test6">
+ <rename src="template.xml"
+ dest="template.tmp"/>
+ <rename src="template.tmp"
+ dest="template.xml"/>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/replace.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/replace.xml
new file mode 100644
index 00000000..a4039e53
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/replace.xml
@@ -0,0 +1,94 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<project name="xxx-test" basedir="." default="test1">
+
+ <import file="../buildfiletest-base.xml"/>
+
+ <target name="setUp">
+ <mkdir dir="${output}"/>
+ </target>
+
+
+ <target name="test1">
+ <replace/>
+ </target>
+
+ <target name="test2">
+ <replace file=""/>
+ </target>
+
+ <target name="test3">
+ <replace file="template.xml"/>
+ </target>
+
+ <target name="test4">
+ <replace file="template.xml" token=""/>
+ </target>
+
+ <target name="test5">
+ <replace file="template.xml"
+ token="dont_want_to_really_replace_something"/>
+ </target>
+
+ <target name="test6">
+ <replace file="template.xml">
+ <replacefilter />
+ </replace>
+ </target>
+
+ <target name="test7">
+ <replace file="template.xml">
+ <replacefilter token="" />
+ </replace>
+ </target>
+
+ <target name="test8">
+ <replace file="template.xml">
+ <replacefilter token="dont_want_to_really_replace_something" />
+ </replace>
+ </target>
+
+ <target name="test9-setup">
+ <!-- this fixing of line endings is necessary because the replace task is transforming the line endings -->
+ <!-- of the replacement tokens and values to the platform default -->
+ <!-- in certain cases (checkout done with cvs of cygwin, the line endings of the various files do not match-->
+ <!-- the system property line.separator -->
+ <copy file="replace/source.txt" tofile="${output}/output.txt"/>
+ <copy file="replace/value.txt" tofile="${output}/value.txt" />
+ <copy file="replace/result.txt" tofile="${output}/result.txt" />
+ <fixcrlf srcdir="${output}" includes="*.txt"/>
+ </target>
+ <target name="test9" depends="test9-setup">
+ <loadfile srcFile="${output}/value.txt" property="content"/>
+ <replace file="${output}/output.txt" token="@@@Replace this@@@" value="${content}"/>
+ </target>
+
+ <target name="lastModifiedSetup">
+ <mkdir dir="${output}"/>
+ <echo file="${output}/test.txt">Hello, world!</echo>
+ </target>
+ <target name="testNoPreserve">
+ <replace token="world" value="Ant" file="${output}/test.txt"/>
+ </target>
+ <target name="testPreserve">
+ <replace token="world" value="Ant" file="${output}/test.txt"
+ preserveLastModified="true"/>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/replace/result.txt b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/replace/result.txt
new file mode 100644
index 00000000..a74e06ea
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/replace/result.txt
@@ -0,0 +1,7 @@
+This is line one
+This is line two
+This is line three
+This is line four
+This is line five
+This is line six
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/replace/source.txt b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/replace/source.txt
new file mode 100644
index 00000000..8d73f317
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/replace/source.txt
@@ -0,0 +1,4 @@
+This is line one
+This is line two
+This is line three
+@@@Replace this@@@
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/replace/value.txt b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/replace/value.txt
new file mode 100644
index 00000000..c75b5529
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/replace/value.txt
@@ -0,0 +1,3 @@
+This is line four
+This is line five
+This is line six \ No newline at end of file
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/rmic/rmic.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/rmic/rmic.xml
new file mode 100644
index 00000000..757fca51
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/rmic/rmic.xml
@@ -0,0 +1,499 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="rmic" default="tearDown" basedir=".">
+
+ <property name="rmic.dir" location="." />
+ <property name="src.dir" location="${rmic.dir}/src"/>
+
+ <import file="../../buildfiletest-base.xml"/>
+
+ <target name="setUp">
+ <mkdir dir="${output}" />
+ <property name="build.dir" location="${output}/build"/>
+ <property name="dest.dir" location="${output}/dest"/>
+ </target>
+
+
+
+ <!-- init builds the java source -->
+ <target name="init" depends="probe-rmic,setUp">
+ <mkdir dir="${build.dir}"/>
+ <mkdir dir="${dest.dir}"/>
+
+ <javac
+ destdir="${build.dir}"
+ srcdir="${src.dir}"
+ includes="Remote*.java">
+ </javac>
+
+ <presetdef name="base-rmic">
+ <rmic
+ base="${build.dir}"
+ verify="true"
+ includes="**/*.class"/>
+ </presetdef>
+
+ <presetdef name="rmic-bad-class">
+ <rmic
+ base="${build.dir}"
+ verify="false"
+ classname="unimplemented.class"
+ />
+ </presetdef>
+
+ <presetdef name="dest-rmic">
+ <rmic
+ base="${build.dir}"
+ destdir="${dest.dir}"
+ verify="true"
+ includes="**/*.class"/>
+ </presetdef>
+
+ <macrodef name="assertFileCreated">
+ <attribute name="file" />
+ <sequential>
+ <fail>Not found : ${build.dir}/@{file}
+ <condition>
+ <not><available file="${build.dir}/@{file}"/></not>
+ </condition>
+ </fail>
+ </sequential>
+ </macrodef>
+
+ <macrodef name="assertFileCreatedInDest">
+ <attribute name="file" />
+ <sequential>
+ <fail>Not found : ${dest.dir}/@{file}
+ <condition>
+ <not><available file="${dest.dir}/@{file}"/></not>
+ </condition>
+ </fail>
+ </sequential>
+ </macrodef>
+
+ <macrodef name="assertFileAbsent">
+ <attribute name="file" />
+ <sequential>
+ <fail>Expected to be missing : ${build.dir}/@{file}
+ <condition>
+ <available file="${build.dir}/@{file}"/>
+ </condition>
+ </fail>
+ </sequential>
+ </macrodef>
+
+ <macrodef name="assertFileAbsentInDest">
+ <attribute name="file" />
+ <sequential>
+ <fail>Expected to be missing : ${dest.dir}/@{file}
+ <condition>
+ <available file="${dest.dir}/@{file}"/>
+ </condition>
+ </fail>
+ </sequential>
+ </macrodef>
+
+ <macrodef name="assertStubCompiled">
+ <sequential>
+ <assertFileCreated file="RemoteTimestampImpl_Stub.class" />
+ </sequential>
+ </macrodef>
+
+ <macrodef name="assertStubCompiledInDest">
+ <sequential>
+ <assertFileCreatedInDest file="RemoteTimestampImpl_Stub.class" />
+ </sequential>
+ </macrodef>
+
+ <macrodef name="assertSkelCompiled">
+ <sequential>
+ <assertFileCreated file="RemoteTimestampImpl_Skel.class" />
+ </sequential>
+ </macrodef>
+
+ <macrodef name="assertSkelCompiledInDest">
+ <sequential>
+ <assertFileCreatedInDest file="RemoteTimestampImpl_Skel.class" />
+ </sequential>
+ </macrodef>
+
+ <macrodef name="assertSkelAbsent">
+ <sequential>
+ <assertFileAbsent file="RemoteTimestampImpl_Skel.class" />
+ </sequential>
+ </macrodef>
+
+ <macrodef name="assertSkelAbsentInDest">
+ <sequential>
+ <assertFileAbsentInDest file="RemoteTimestampImpl_Skel.class" />
+ </sequential>
+ </macrodef>
+
+ <macrodef name="assertBaseCompiled">
+ <sequential>
+ <assertStubCompiled />
+ <assertSkelCompiled />
+ </sequential>
+ </macrodef>
+
+ <macrodef name="assertBaseCompiledInDest">
+ <sequential>
+ <assertStubCompiledInDest />
+ <assertSkelCompiledInDest />
+ </sequential>
+ </macrodef>
+
+ <macrodef name="assertAntStubCompiled">
+ <sequential>
+ <assertFileCreated file="AntTimestamp_Stub.class"/>
+ </sequential>
+ </macrodef>
+
+ <macrodef name="assertAntStubCompiledInDest">
+ <sequential>
+ <assertFileCreatedInDest file="AntTimestamp_Stub.class"/>
+ </sequential>
+ </macrodef>
+
+ <macrodef name="assertAntSkelCompiled">
+ <sequential>
+ <assertFileCreated file="AntTimestamp_Skel.class"/>
+ </sequential>
+ </macrodef>
+
+ <macrodef name="assertAntSkelCompiledInDest">
+ <sequential>
+ <assertFileCreatedInDest file="AntTimestamp_Skel.class"/>
+ </sequential>
+ </macrodef>
+
+ <macrodef name="assertAntCompiled">
+ <sequential>
+ <assertAntStubCompiled />
+ <assertAntSkelCompiled />
+ </sequential>
+ </macrodef>
+
+ <macrodef name="assertAntCompiledInDest">
+ <sequential>
+ <assertAntStubCompiledInDest />
+ <assertAntSkelCompiledInDest />
+ </sequential>
+ </macrodef>
+
+ </target>
+
+ <target name="probe-rmic">
+ <available property="kaffe.present" classname="jkaffe.rmi.rmic.RMIC"/>
+ <available property="rmic.present" classname="sun.rmi.rmic.Main"/>
+ <available property="wlrmic.present" classname="weblogic.rmic"/>
+ <condition property="rmic5.present">
+ <and>
+ <isset property="rmic.present"/>
+ <available classname="java.net.Proxy"/>
+ </and>
+ </condition>
+ <condition property="rmic6.present">
+ <and>
+ <isset property="rmic.present"/>
+ <available classname="java.util.ServiceLoader"/>
+ </and>
+ </condition>
+ </target>
+
+ <target name="testDefault" depends="init">
+ <base-rmic compiler="default" listfiles="true"/>
+ <assertBaseCompiled/>
+ </target>
+
+ <target name="testDefaultDest" depends="init">
+ <dest-rmic compiler="default"/>
+ <assertBaseCompiledInDest/>
+ </target>
+
+ <target name="testEmpty" depends="init">
+ <base-rmic compiler=""/>
+ <assertBaseCompiled/>
+ </target>
+
+ <target name="testEmptyDest" depends="init">
+ <dest-rmic compiler=""/>
+ <assertBaseCompiledInDest/>
+ </target>
+
+ <target name="testVersion11" depends="init">
+ <base-rmic compiler="default" stubversion="1.1" />
+ <assertBaseCompiled/>
+ </target>
+
+ <target name="testVersion11Dest" depends="init">
+ <dest-rmic compiler="default" stubversion="1.1" />
+ <assertBaseCompiledInDest/>
+ </target>
+
+ <target name="testVersion12" depends="init">
+ <base-rmic compiler="default" stubversion="1.2" />
+ <assertStubCompiled/>
+ <assertSkelAbsent/>
+ </target>
+
+ <target name="testVersion12Dest" depends="init">
+ <dest-rmic compiler="default" stubversion="1.2" />
+ <assertStubCompiledInDest/>
+ <assertSkelAbsentInDest/>
+ </target>
+
+ <target name="testVersionCompat" depends="init">
+ <base-rmic compiler="default" stubversion="compat" />
+ <assertBaseCompiled/>
+ </target>
+
+ <target name="testVersionCompatDest" depends="init">
+ <dest-rmic compiler="default" stubversion="compat" />
+ <assertBaseCompiledInDest/>
+ </target>
+
+ <target name="testRmic" if="rmic.present" depends="init">
+ <base-rmic compiler="sun"/>
+ <assertBaseCompiled/>
+ </target>
+
+ <target name="testRmicDest" if="rmic.present" depends="init">
+ <dest-rmic compiler="sun"/>
+ <assertBaseCompiledInDest/>
+ </target>
+
+ <target name="testRmicJArg" if="rmic.present" depends="init">
+ <base-rmic compiler="sun">
+ <compilerarg value="-J-mx256m" />
+ </base-rmic>
+ <assertBaseCompiled/>
+ </target>
+
+ <target name="testRmicJArgDest" if="rmic.present" depends="init">
+ <dest-rmic compiler="sun">
+ <compilerarg value="-J-mx256m" />
+ </dest-rmic>
+ <assertBaseCompiledInDest/>
+ </target>
+
+ <target name="testKaffe" if="kaffe.present" depends="init">
+ <base-rmic
+ compiler="kaffe"
+ />
+ <assertBaseCompiled/>
+ </target>
+
+ <target name="testKaffeDest" if="kaffe.present" depends="init">
+ <dest-rmic
+ compiler="kaffe"
+ />
+ <assertBaseCompiledInDest/>
+ </target>
+
+<!-- weblogic.rmic doesn't work without a global CLASSPATH
+ <target name="testWlrmic" if="wlrmic.present" depends="init">
+ <base-rmic
+ compiler="weblogic"
+ />
+ </target>
+
+ <target name="testWlrmicJArg" if="wlrmic.present" depends="init">
+ <base-rmic
+ compiler="weblogic"
+ >
+ <compilerarg value="-J-mx256m" />
+ </base-rmic>
+ </target>
+-->
+ <target name="testForking" if="rmic.present" depends="init">
+ <base-rmic
+ compiler="forking"
+ />
+ <assertBaseCompiled/>
+ </target>
+
+ <target name="testBadName" if="rmic.present" depends="init">
+ <base-rmic
+ compiler="no-such-compiler"
+ />
+ </target>
+
+ <target name="testExplicitClass" if="rmic.present" depends="init">
+ <base-rmic
+ compiler="org.apache.tools.ant.taskdefs.rmic.SunRmic"
+ />
+ <assertBaseCompiled/>
+ </target>
+
+ <target name="testWrongClass" if="rmic.present" depends="init">
+ <base-rmic
+ compiler="org.apache.tools.ant.BuildException"
+ />
+ </target>
+
+ <target name="testNoBase" depends="init">
+ <rmic
+ verify="true"
+ includes="**/*.class"/>
+ </target>
+
+ <target name="testBaseDoesntExist" depends="init">
+ <rmic
+ base="${build.dir}/classes"
+ verify="true"
+ includes="**/*.class"/>
+ </target>
+
+ <target name="testBaseIsntDir" depends="init">
+ <rmic
+ base="${ant.file}"
+ verify="true"
+ includes="**/*.class"/>
+ </target>
+
+ <target name="testFailingAdapter" depends="init">
+ <base-rmic
+ compiler="org.apache.tools.ant.taskdefs.rmic.RmicAdvancedTest$FailingRmicAdapter"
+ />
+ </target>
+
+ <target name="compileAntTimestamp" depends="init">
+ <javac
+ destdir="${build.dir}"
+ srcdir="${src.dir}"
+ includes="Ant*.java">
+ </javac>
+ </target>
+
+ <target name="testAntClasspath" depends="compileAntTimestamp">
+ <base-rmic
+ compiler="default"
+ />
+ <assertAntCompiled/>
+ </target>
+
+ <target name="testAntClasspathDest" depends="compileAntTimestamp">
+ <dest-rmic
+ compiler="default"
+ />
+ <assertAntCompiledInDest/>
+ </target>
+
+ <target name="testForkingAntClasspath" if="rmic.present" depends="compileAntTimestamp">
+ <base-rmic
+ compiler="forking"
+ />
+ <assertAntCompiled />
+ </target>
+
+ <target name="testForkingAntClasspathDest" if="rmic.present" depends="compileAntTimestamp">
+ <dest-rmic
+ compiler="forking"
+ />
+ <assertAntCompiledInDest />
+ </target>
+
+ <target name="testDefaultBadClass" depends="init">
+ <rmic-bad-class compiler="default"/>
+ </target>
+
+ <target name="testMagicProperty" depends="init">
+ <property name="build.rmic" value="no-such-adapter"/>
+ <base-rmic
+ />
+ </target>
+
+ <target name="testMagicPropertyOverridesEmptyString" depends="init">
+ <property name="build.rmic" value="no-such-adapter"/>
+ <base-rmic compiler=""
+ />
+ </target>
+
+ <target name="testMagicPropertyIsEmptyString" depends="init">
+ <property name="build.rmic" value=""/>
+ <base-rmic />
+ <assertBaseCompiled/>
+ </target>
+
+ <!--
+ This test stamps on the XML parser settings on java6, so it is disabled.
+ -->
+ <target name="testXnew" if="rmic5.present" unless="rmic6.present" depends="init">
+ <base-rmic compiler="sun">
+ <compilerarg value="-Xnew"/>
+ </base-rmic>
+ <assertBaseCompiled/>
+ </target>
+
+ <target name="testXnewDest" if="rmic5.present" unless="rmic6.present" depends="init">
+ <dest-rmic compiler="sun">
+ <compilerarg value="-Xnew"/>
+ </dest-rmic>
+ <assertBaseCompiledInDest/>
+ </target>
+
+ <target name="testXnewForked" if="rmic5.present" depends="init">
+ <base-rmic compiler="forking">
+ <compilerarg value="-Xnew"/>
+ </base-rmic>
+ <assertBaseCompiled/>
+ </target>
+
+ <target name="testXnewForkedDest" if="rmic5.present" depends="init">
+ <dest-rmic compiler="forking">
+ <compilerarg value="-Xnew"/>
+ </dest-rmic>
+ <assertBaseCompiledInDest/>
+ </target>
+
+ <target name="testXnewCompiler" if="rmic5.present" depends="init">
+ <base-rmic compiler="xnew">
+ </base-rmic>
+ <assertBaseCompiled/>
+ </target>
+
+ <target name="testXnewCompilerDest" if="rmic5.present" depends="init">
+ <dest-rmic compiler="xnew">
+ </dest-rmic>
+ <assertBaseCompiledInDest/>
+ </target>
+
+ <target name="testIDL" depends="init">
+ <base-rmic compiler="default" idl="true"/>
+ <assertFileCreated file="RemoteTimestamp.idl"/>
+ </target>
+
+ <target name="testIDLDest" depends="init">
+ <dest-rmic compiler="default" idl="true"/>
+ <assertFileCreatedInDest file="RemoteTimestamp.idl"/>
+ </target>
+
+ <target name="testIIOP" depends="init">
+ <base-rmic compiler="default" iiop="true"/>
+ <assertFileCreated file="_RemoteTimestamp_Stub.class"/>
+ <assertFileCreated file="_RemoteTimestampImpl_Tie.class"/>
+ </target>
+
+ <target name="testIIOPDest" depends="init">
+ <dest-rmic compiler="default" iiop="true"/>
+ <assertFileCreatedInDest file="_RemoteTimestamp_Stub.class"/>
+ <assertFileCreatedInDest file="_RemoteTimestampImpl_Tie.class"/>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/rmic/src/AntTimestamp.java b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/rmic/src/AntTimestamp.java
new file mode 100644
index 00000000..d9ba7854
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/rmic/src/AntTimestamp.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import java.rmi.Remote;
+import java.rmi.RemoteException;
+import java.util.Calendar;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.util.DateUtils;
+
+
+/**
+ * This class imports a dependency on the Ant runtime classes,
+ * so tests that classpath setup include them
+ */
+public class AntTimestamp implements RemoteTimestamp {
+
+
+ /**
+ * return the phase of the moon.
+ * Note the completely different semantics of the other implementation,
+ * which goes to show why signature is an inadequate way of verifying
+ * how well an interface is implemented.
+ *
+ * @return
+ * @throws RemoteException
+ */
+ public long when() throws RemoteException {
+ Calendar cal=Calendar.getInstance();
+ return DateUtils.getPhaseOfMoon(cal);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/rmic/src/RemoteTimestamp.java b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/rmic/src/RemoteTimestamp.java
new file mode 100644
index 00000000..1834e4a1
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/rmic/src/RemoteTimestamp.java
@@ -0,0 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import java.rmi.Remote;
+import java.rmi.RemoteException;
+
+/**
+ * this is the interface we remote
+ */
+public interface RemoteTimestamp extends Remote {
+ long when() throws RemoteException ;
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/rmic/src/RemoteTimestampImpl.java b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/rmic/src/RemoteTimestampImpl.java
new file mode 100644
index 00000000..f361452e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/rmic/src/RemoteTimestampImpl.java
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import java.rmi.Remote;
+import java.rmi.RemoteException;
+
+/**
+ * this is the implementation
+ */
+public class RemoteTimestampImpl implements RemoteTimestamp {
+
+ public long when() throws RemoteException {
+ return System.currentTimeMillis();
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/signjar.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/signjar.xml
new file mode 100644
index 00000000..38a13592
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/signjar.xml
@@ -0,0 +1,97 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="signjartest" default="help" basedir="..">
+
+ <import file="../buildfiletest-base.xml"/>
+
+ <target name="setUp">
+ <mkdir dir="${output}" />
+ <property name="subdir" location="${output}/subdir" />
+ <property name="classes.dir" value="../../../build/classes"/>
+ <property name="test.jar" location="${output}/signtest.jar" />
+ <property name="subdirtest.jar" location="${subdir}/signtest.jar" />
+
+ </target>
+
+
+ <macrodef name="assertSigned">
+ <attribute name="jar" default="${test.jar}" />
+ <sequential>
+ <fail message="not signed: @{jar}" >
+ <condition>
+ <not><issigned file="@{jar}" /></not>
+ </condition>
+ </fail>
+ </sequential>
+ </macrodef>
+
+ <presetdef name="sign-base">
+ <signjar alias="testonly" keystore="testkeystore"
+ storepass="apacheant"/>
+ </presetdef>
+
+ <presetdef name="verify-base">
+ <verifyjar keystore="testkeystore"
+ storepass="apacheant"/>
+ </presetdef>
+
+ <presetdef name="sign">
+ <sign-base jar="${test.jar}" />
+ </presetdef>
+
+ <target name="jar" depends="setUp">
+ <jar jarfile="${test.jar}" basedir="${classes.dir}" includes="**/Task.class"/>
+ </target>
+
+ <target name="help">
+ <echo>This build is for use with Ant's test cases</echo>
+ </target>
+
+ <target name="basic" depends="jar">
+ <sign />
+ <assertSigned/>
+ </target>
+
+ <target name="sigfile" depends="jar">
+ <sign sigfile="TEST"/>
+ <assertSigned/>
+ </target>
+
+ <target name="invalidchars" depends="jar">
+ <sign alias="test@nly"/>
+ <assertSigned/>
+ </target>
+
+ <target name="urlKeystoreFile" depends="jar">
+ <sign keystore="file://../testkeystore"
+ maxmemory="128m"/>
+ <assertSigned/>
+ </target>
+
+ <target name="urlKeystoreHTTP" depends="jar">
+ <sign
+ keystore="http://ant.apache.org/webtest/testkeystore"
+ />
+ <assertSigned/>
+ </target>
+
+ <target name="testTsaLocalhost" depends="jar">
+ <sign tsaurl="http://localhost:0/" />
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/skinconfig.dtd b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/skinconfig.dtd
new file mode 100644
index 00000000..ba1b4de6
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/skinconfig.dtd
@@ -0,0 +1,19 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!ELEMENT skinconfig (foo, bar?)>
+<!ELEMENT foo (#PCDATA)>
+<!ELEMENT bar (#PCDATA)>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/sleep.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/sleep.xml
new file mode 100644
index 00000000..e1613227
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/sleep.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="sleeptest" default="all" >
+
+ <target name="test1">
+ <sleep />
+ </target>
+
+ <target name="test2">
+ <sleep milliseconds="10"/>
+ </target>
+
+ <target name="test3">
+ <sleep seconds="2"/>
+ </target>
+
+ <target name="test4">
+ <sleep hours="1" minutes="-59" seconds="-58"/>
+ </target>
+
+ <target name="test5">
+ <sleep minutes="-59" seconds="-58"/>
+ </target>
+
+ <target name="test6">
+ <sleep minutes="-59" seconds="-58" failonerror="no"/>
+ </target>
+
+ <target name="all"
+ depends="test1,test2,test3,test4,test5" />
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/style/build.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/style/build.xml
new file mode 100644
index 00000000..c91d10f6
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/style/build.xml
@@ -0,0 +1,197 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<project name="xslt-test" basedir="." default="tearDown">
+
+ <import file="../../buildfiletest-base.xml"/>
+
+ <target name="setUp">
+ <mkdir dir="${output}" />
+ </target>
+
+
+ <target name="testStyleIsSet">
+ <xslt in="data.xml" out="${output}/out.xml"/>
+ </target>
+
+ <target name="testTransferParameterSet">
+ <property name="value" value="myvalue"/>
+ <xslt in="data.xml" out="${output}/out.xml" style="printParams.xsl">
+ <param name="set" expression="${value}"/>
+ </xslt>
+ </target>
+
+ <target name="testTransferParameterEmpty">
+ <property name="value" value=""/>
+ <xslt in="data.xml" out="${output}/out.xml" style="printParams.xsl">
+ <param name="empty" expression="${value}"/>
+ </xslt>
+ </target>
+
+ <target name="testTransferParameterUnset">
+ <xslt in="data.xml" out="${output}/out.xml" style="printParams.xsl">
+ <param name="undefined" expression="${value}"/>
+ </xslt>
+ </target>
+
+ <target name="testTransferParameterUnsetWithIf">
+ <xslt in="data.xml" out="${output}/out.xml" style="printParams.xsl">
+ <param name="undefined" expression="${value}" if="value" />
+ </xslt>
+ </target>
+
+ <target name="testDefaultMapper">
+ <property name="value" value="myvalue"/>
+ <xslt style="printParams.xsl" destDir="${output}" basedir=".">
+ <param name="set" expression="${value}"/>
+ </xslt>
+ </target>
+
+ <target name="testCustomMapper">
+ <property name="value" value="myvalue"/>
+ <xslt style="printParams.xsl" destDir="${output}" basedir=".">
+ <param name="set" expression="${value}"/>
+ <mapper type="glob" from="data.*" to="out.*"/>
+ </xslt>
+ </target>
+
+ <target name="testTypedMapper">
+ <property name="value" value="myvalue"/>
+ <xslt style="printParams.xsl" destDir="${output}" basedir=".">
+ <param name="set" expression="${value}"/>
+ <globmapper from="data.*" to="out.*"/>
+ </xslt>
+ </target>
+
+ <target name="testExplicitFileset">
+ <property name="value" value="myvalue"/>
+ <xslt style="printParams.xsl" destDir="${output}"
+ useImplicitFileset="false" basedir="..">
+ <param name="set" expression="${value}"/>
+ <fileset dir="."/>
+ </xslt>
+ </target>
+
+ <target name="testNewerStylesheet">
+ <antcall target="copyXsl">
+ <param name="xsl.value" value="old-value"/>
+ </antcall>
+ <xslt in="data.xml" out="${output}/out.xml" style="tmp.xsl"/>
+
+ <antcall target="copyXsl">
+ <param name="xsl.value" value="new-value"/>
+ </antcall>
+ <xslt in="data.xml" out="${output}/out.xml" style="tmp.xsl"/>
+ <delete file="tmp.xsl"/>
+ </target>
+
+ <target name="testDirectoryHierarchyWithDirMatching">
+ <mkdir dir="${output}/src/level1/"/>
+ <copy file="data.xml" todir="${output}/src/level1/"/>
+ <xslt basedir="${output}/src" destdir="${output}/dest"
+ style="printParams.xsl"/>
+ </target>
+
+ <target name="testDirsWithSpaces">
+ <mkdir dir="${output}/s rc/"/>
+ <copy file="data.xml" todir="${output}/s rc/"/>
+ <xslt basedir="${output}/s rc" destdir="${output}/d est"
+ style="printParams.xsl"/>
+ </target>
+
+ <target name="copyXsl" if="xsl.value">
+ <copy file="testNewerStylesheet.xsl" tofile="tmp.xsl" overwrite="true">
+ <filterchain><expandproperties/></filterchain>
+ </copy>
+ </target>
+
+ <target name="testWithStyleAttrAndResource">
+ <!-- also testing style as resources, with refid -->
+ <file id="xslFile" file="printParams.xsl"/>
+ <xslt in="data.xml" out="${output}/out.xml" style="printParams.xsl">
+ <style refid="xslFile" />
+ </xslt>
+ </target>
+
+ <target name="testWithFileResource">
+ <xslt in="data.xml" out="${output}/out.xml">
+ <style>
+ <file file="printParams.xsl"/>
+ </style>
+ <param name="set" expression="value"/>
+ </xslt>
+ </target>
+
+ <target name="testWithUrlResource">
+ <makeurl file="printParams.xsl" property="printParams.xsl.url"/>
+ <xslt in="data.xml" out="${output}/out.xml">
+ <style>
+ <url url="${printParams.xsl.url}"/>
+ </style>
+ <param name="set" expression="value"/>
+ </xslt>
+ </target>
+
+ <target name="testFilenameAndFiledirAsParam">
+ <mkdir dir="${output}/xml/dir"/>
+ <copy file="data.xml" tofile="${output}/xml/one.xml"/>
+ <copy file="data.xml" tofile="${output}/xml/two.xml"/>
+ <copy file="data.xml" tofile="${output}/xml/three.xml"/>
+ <copy file="data.xml" tofile="${output}/xml/dir/four.xml"/>
+ <xslt style="printFilename.xsl"
+ destdir="${output}"
+ basedir="${output}/xml"
+ includes="**/*.xml"
+ extension=".txt"
+
+ filenameparameter="filename"
+ filedirparameter="filedir"
+ />
+ </target>
+
+ <target name="testFilenameAsParam">
+ <mkdir dir="${output}/xml/dir"/>
+ <copy file="data.xml" tofile="${output}/xml/one.xml"/>
+ <copy file="data.xml" tofile="${output}/xml/two.xml"/>
+ <copy file="data.xml" tofile="${output}/xml/three.xml"/>
+ <copy file="data.xml" tofile="${output}/xml/dir/four.xml"/>
+ <xslt style="printFilename.xsl"
+ destdir="${output}"
+ basedir="${output}/xml"
+ includes="**/*.xml"
+ extension=".txt"
+
+ filenameparameter="filename"
+ />
+ </target>
+
+ <target name="testFilenameAsParamNoSetting">
+ <mkdir dir="${output}/xml/dir"/>
+ <copy file="data.xml" tofile="${output}/xml/one.xml"/>
+ <copy file="data.xml" tofile="${output}/xml/two.xml"/>
+ <copy file="data.xml" tofile="${output}/xml/three.xml"/>
+ <copy file="data.xml" tofile="${output}/xml/dir/four.xml"/>
+ <xslt style="printFilename.xsl"
+ destdir="${output}"
+ basedir="${output}/xml"
+ includes="**/*.xml"
+ extension=".txt"
+ /> <!-- without 'filenameparameter' to check, that the xsl:param is NOT set -->
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/style/data.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/style/data.xml
new file mode 100644
index 00000000..21e2397f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/style/data.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<data/> \ No newline at end of file
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/style/printFilename.xsl b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/style/printFilename.xsl
new file mode 100644
index 00000000..eb2cbc7d
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/style/printFilename.xsl
@@ -0,0 +1,38 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<xsl:stylesheet
+ version="1.0"
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+
+ <xsl:output indent="no" method="text"/>
+ <xsl:strip-space elements="*"/>
+
+ <xsl:param name="filename">-not-set-</xsl:param>
+ <xsl:param name="filedir">-not-set-</xsl:param>
+
+<!-- use the xsl-parameter -->
+<xsl:template match="/">
+ filename='<xsl:value-of select="$filename"/>'
+ filedir ='<xsl:value-of select="$filedir"/>'
+</xsl:template>
+
+<!-- delete the raw xml data -->
+<xsl:template match="*"/>
+
+</xsl:stylesheet>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/style/printParams.xsl b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/style/printParams.xsl
new file mode 100644
index 00000000..110e49ce
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/style/printParams.xsl
@@ -0,0 +1,36 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<xsl:stylesheet
+ version="1.0"
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:fo="http://www.w3.org/1999/XSL/Format">
+
+<!-- get the xsl-parameter -->
+<xsl:param name="set">set default value</xsl:param>
+<xsl:param name="empty">empty default value</xsl:param>
+<xsl:param name="undefined">undefined default value</xsl:param>
+
+<!-- use the xsl-parameter -->
+<xsl:template match="/">
+set='<xsl:value-of select="$set"/>'
+empty='<xsl:value-of select="$empty"/>'
+undefined='<xsl:value-of select="$undefined"/>'
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/style/testNewerStylesheet.xsl b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/style/testNewerStylesheet.xsl
new file mode 100644
index 00000000..dff81209
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/style/testNewerStylesheet.xsl
@@ -0,0 +1,28 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<xsl:stylesheet
+ version="1.0"
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+
+<xsl:output method="text"/>
+
+<xsl:template match="/">
+${xsl.value}
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/subant.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/subant.xml
new file mode 100644
index 00000000..7db547a3
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/subant.xml
@@ -0,0 +1,65 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<project name="subant-test" basedir="." default="testgenericantfile">
+ <target name="testnodirs" depends="tearDown">
+ <subant genericantfile="subant/genericsubant.xml">
+ <dirset dir="." includes="subant-test*"/>
+ </subant>
+ </target>
+
+ <target name="testgenericantfile">
+ <subant genericantfile="subant/genericsubant.xml">
+ <dirset dir="subant" includes="subant-test*"/>
+ </subant>
+ </target>
+
+ <target name="testantfile">
+ <subant antfile="mysubant.xml">
+ <dirset dir="." includes="subant/subant-test*"/>
+ </subant>
+ </target>
+
+ <target name="multipleTargets">
+ <subant antfile="mysubant.xml">
+ <dirset dir="." includes="subant/subant-test*"/>
+ <target name="one"/>
+ <target name="two"/>
+ </subant>
+ </target>
+
+ <target name="multipleTargetsOneDoesntExist_FOEfalse">
+ <subant antfile="mysubant.xml" failonerror="false">
+ <dirset dir="." includes="subant/subant-test*"/>
+ <target name="one"/>
+ <target name="three"/>
+ </subant>
+ </target>
+
+ <target name="multipleTargetsOneDoesntExist_FOEtrue">
+ <subant antfile="mysubant.xml" failonerror="true">
+ <dirset dir="." includes="subant/subant-test*"/>
+ <target name="one"/>
+ <target name="three"/>
+ </subant>
+ </target>
+
+ <target name="tearDown">
+ <!-- nothing to do -->
+ </target>
+</project> \ No newline at end of file
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/subant/genericsubant.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/subant/genericsubant.xml
new file mode 100644
index 00000000..c5bfbe2c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/subant/genericsubant.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="genericsubant" basedir=".." default="mysubant">
+ <target name="mysubant">
+ <echo message="${basedir}"/>
+ </target>
+</project> \ No newline at end of file
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/subant/subant-test1/mysubant.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/subant/subant-test1/mysubant.xml
new file mode 100644
index 00000000..ecc62883
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/subant/subant-test1/mysubant.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="mysubant" basedir="." default="mysubant">
+ <target name="mysubant">
+ <echo message="${basedir}"/>
+ </target>
+ <target name="one">
+ <echo message="test1-one"/>
+ </target>
+ <target name="two">
+ <echo message="test1-two"/>
+ </target>
+ <target name="three">
+ <echo message="test1-three"/>
+ </target>
+</project> \ No newline at end of file
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/subant/subant-test2/mysubant.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/subant/subant-test2/mysubant.xml
new file mode 100644
index 00000000..5ee875fe
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/subant/subant-test2/mysubant.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="subant" basedir=".." default="mysubant">
+ <target name="mysubant">
+ <echo message="${basedir}"/>
+ </target>
+ <target name="one">
+ <echo message="test2-one"/>
+ </target>
+ <target name="two">
+ <echo message="test2-two"/>
+ </target>
+</project> \ No newline at end of file
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/sync.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/sync.xml
new file mode 100644
index 00000000..d2eb126e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/sync.xml
@@ -0,0 +1,141 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="sync-test" default="not-me">
+ <import file="../buildfiletest-base.xml"/>
+
+ <target name="setUp">
+ <mkdir dir="${output}" />
+ <property name="src" location="${output}/source"/>
+ <property name="dest" location="${output}/target"/>
+ <mkdir dir="${src}"/>
+ <mkdir dir="${dest}"/>
+ </target>
+
+ <target name="not-me">
+ <fail>This file must be used from a test case</fail>
+ </target>
+
+ <target name="simplecopy" depends="setUp">
+ <mkdir dir="${src}/a/b/c"/>
+ <touch file="${src}/a/b/c/d"/>
+ <sync todir="${dest}">
+ <fileset dir="${src}"/>
+ </sync>
+ </target>
+
+ <target name="copyandremove" depends="setUp">
+ <mkdir dir="${src}/a/b/c"/>
+ <touch file="${src}/a/b/c/d"/>
+ <mkdir dir="${dest}/e"/>
+ <touch file="${dest}/e/f"/>
+ <sync todir="${dest}">
+ <fileset dir="${src}"/>
+ </sync>
+ </target>
+
+ <target name="copyandremove-with-filelist" depends="setUp">
+ <mkdir dir="${src}/a/b/c"/>
+ <touch file="${src}/a/b/c/d"/>
+ <mkdir dir="${dest}/e"/>
+ <touch file="${dest}/e/f"/>
+ <sync todir="${dest}">
+ <filelist dir="${src}">
+ <file name="a/b/c/d"/>
+ <file name="not-there"/>
+ </filelist>
+ </sync>
+ </target>
+
+ <target name="copyandremove-with-zipfileset" depends="setUp">
+ <mkdir dir="${src}/a/b/c"/>
+ <touch file="${src}/a/b/c/d"/>
+ <mkdir dir="${dest}/e"/>
+ <touch file="${dest}/e/f"/>
+ <zip destfile="${src}/test.zip">
+ <fileset dir="${src}" excludes="*.zip"/>
+ </zip>
+ <sync todir="${dest}">
+ <zipfileset src="${src}/test.zip"/>
+ </sync>
+ </target>
+
+ <target name="copyandremove-emptypreserve" depends="setUp">
+ <mkdir dir="${src}/a/b/c"/>
+ <touch file="${src}/a/b/c/d"/>
+ <mkdir dir="${dest}/e"/>
+ <touch file="${dest}/e/f"/>
+ <sync todir="${dest}">
+ <fileset dir="${src}"/>
+ <preserveintarget/>
+ </sync>
+ </target>
+
+ <target name="emptycopy" depends="setUp">
+ <mkdir dir="${src}/a/b/c"/>
+ <touch file="${src}/a/b/c/d"/>
+ <sync todir="${dest}">
+ <fileset dir="${src}" excludes="**/d"/>
+ </sync>
+ </target>
+
+ <target name="emptydircopy" depends="setUp">
+ <mkdir dir="${src}/a/b/c"/>
+ <touch file="${src}/a/b/c/d"/>
+ <sync todir="${dest}"
+ includeemptydirs="true">
+ <fileset dir="${src}" excludes="**/d"/>
+ </sync>
+ </target>
+
+ <target name="emptydircopyandremove" depends="setUp">
+ <mkdir dir="${src}/a/b/c"/>
+ <touch file="${src}/a/b/c/d"/>
+ <mkdir dir="${dest}/e/f"/>
+ <sync todir="${dest}"
+ includeemptydirs="true">
+ <fileset dir="${src}" excludes="**/d"/>
+ </sync>
+ </target>
+
+ <target name="copynoremove" depends="setUp">
+ <mkdir dir="${src}/a/b/c"/>
+ <touch file="${src}/a/b/c/d"/>
+ <mkdir dir="${dest}/e"/>
+ <touch file="${dest}/e/f"/>
+ <sync todir="${dest}">
+ <fileset dir="${src}"/>
+ <preserveintarget>
+ <include name="e/f"/>
+ </preserveintarget>
+ </sync>
+ </target>
+
+ <target name="copynoremove-selectors" depends="setUp">
+ <mkdir dir="${src}/a/b/c"/>
+ <touch file="${src}/a/b/c/d"/>
+ <mkdir dir="${dest}/e"/>
+ <touch file="${dest}/e/f"/>
+ <sync todir="${dest}">
+ <fileset dir="${src}"/>
+ <preserveintarget>
+ <filename name="e/f"/>
+ </preserveintarget>
+ </sync>
+ </target>
+
+</project> \ No newline at end of file
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/tar.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/tar.xml
new file mode 100644
index 00000000..2eda0b54
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/tar.xml
@@ -0,0 +1,200 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<project name="tar-test" basedir="." default="test1">
+
+ <import file="../buildfiletest-base.xml"/>
+
+ <target name="setUp">
+ <mkdir dir="${output}"/>
+ <mkdir dir="${output}/untar"/>
+ </target>
+
+ <target name="test1">
+ <tar/>
+ </target>
+
+ <target name="test2">
+ <tar tarfile=""/>
+ </target>
+
+ <target name="test3">
+ <tar basedir=""/>
+ </target>
+
+ <target name="test4">
+ <touch file="${output}/test4.tar"/>
+ <tar destfile="${output}/test4.tar"
+ basedir="${output}"/>
+ </target>
+
+ <target name="test5">
+ <mkdir dir="${output}/test5dir"/>
+ <tar destfile="${output}/test5.tar"
+ basedir="${output}"
+ includes="test5dir"/>
+ </target>
+
+ <target name="test6">
+ <tar destfile="${output}/blah" longfile="Foo"/>
+ </target>
+
+ <target name="test7">
+ <copy todir="${output}">
+ <fileset dir="."/>
+ </copy>
+ <mkdir dir="${output}/test7dir"/>
+ <tar destfile="${output}/test7.tar">
+ <tarfileset dir="${output}" prefix="test7-prefix/">
+ <include name="test7dir"/>
+ </tarfileset>
+ <tarfileset dir="${output}" prefix="">
+ <include name="test7dir"/>
+ </tarfileset>
+ </tar>
+ <untar src="${output}/test7.tar" dest="${output}/untar"/>
+ </target>
+
+ <target name="test7UsingPlainFileSet">
+ <copy todir="${output}">
+ <fileset dir="."/>
+ </copy>
+ <mkdir dir="${output}/test7dir"/>
+ <tar destfile="${output}/test7.tar">
+ <tarfileset dir="${output}" prefix="test7-prefix/">
+ <include name="test7dir"/>
+ </tarfileset>
+ <fileset dir="${output}">
+ <include name="test7dir"/>
+ </fileset>
+ </tar>
+ <untar src="${output}/test7.tar" dest="${output}/untar"/>
+ </target>
+
+ <target name="test7UsingFileList">
+ <copy todir="${output}">
+ <fileset dir="."/>
+ </copy>
+ <mkdir dir="${output}/test7dir"/>
+ <tar destfile="${output}/test7.tar">
+ <tarfileset dir="${output}" prefix="test7-prefix/">
+ <include name="test7dir"/>
+ </tarfileset>
+ <filelist dir="${output}">
+ <file name="test7dir"/>
+ </filelist>
+ </tar>
+ <untar src="${output}/test7.tar" dest="${output}/untar"/>
+ </target>
+
+ <target name="test8">
+ <tar destfile="${output}/test8.tar">
+ <tarfileset dir="." fullpath="/test8.xml">
+ <include name="tar.xml"/>
+ </tarfileset>
+ </tar>
+ <untar src="${output}/test8.tar" dest="${output}/untar"/>
+ </target>
+
+ <target name="test8UsingZipFileset">
+ <tar destfile="${output}/test8.tar">
+ <zipfileset dir="." fullpath="/test8.xml">
+ <include name="tar.xml"/>
+ </zipfileset>
+ </tar>
+ <untar src="${output}/test8.tar" dest="${output}/untar"/>
+ </target>
+
+ <target name="test8UsingZipFilesetSrc">
+ <zip destfile="${output}/test7.tar" basedir="." includes="tar.xml"/>
+ <tar destfile="${output}/test8.tar">
+ <zipfileset src="${output}/test7.tar" fullpath="/test8.xml">
+ <include name="tar.xml"/>
+ </zipfileset>
+ </tar>
+ <untar src="${output}/test8.tar" dest="${output}/untar"/>
+ </target>
+
+ <target name="test8UsingTarFilesetSrc">
+ <tar destfile="${output}/test7.tar" basedir="." includes="tar.xml"/>
+ <tar destfile="${output}/test8.tar">
+ <tarfileset src="${output}/test7.tar" fullpath="/test8.xml">
+ <include name="tar.xml"/>
+ </tarfileset>
+ </tar>
+ <untar src="${output}/test8.tar" dest="${output}/untar"/>
+ </target>
+
+ <target name="test8UsingZipEntry">
+ <zip destfile="${output}/test7.tar">
+ <zipfileset dir="." includes="tar.xml" fullpath="/test8.xml"/>
+ </zip>
+ <tar destfile="${output}/test8.tar">
+ <zipentry archive="${output}/test7.tar" name="/test8.xml"/>
+ </tar>
+ <untar src="${output}/test8.tar" dest="${output}/untar"/>
+ </target>
+
+ <target name="test9">
+ <tar destfile="${output}/blah" compression="Foo"/>
+ </target>
+
+ <target name="test10">
+ <tar destfile="${output}/test10.tar.gz" compression="gzip">
+ <tarfileset dir="." fullpath="/test10.xml">
+ <include name="tar.xml"/>
+ </tarfileset>
+ </tar>
+ <untar src="${output}/test10.tar.gz" dest="${output}/untar" compression="gzip"/>
+ </target>
+
+ <target name="test11">
+ <tar destfile="${output}/test11.tar.bz2" compression="bzip2">
+ <tarfileset dir="." fullpath="/test11.xml">
+ <include name="tar.xml"/>
+ </tarfileset>
+ </tar>
+ <untar src="${output}/test11.tar.bz2" dest="${output}/untar" compression="bzip2"/>
+ </target>
+
+
+ <target name="feather">
+ <tar destfile="${output}/asf-logo.gif.tar"
+ basedir=".."
+ includes="asf-logo.gif" />
+ <tar destfile="${output}/asf-logo.gif.tar.gz"
+ basedir=".."
+ includes="asf-logo.gif"
+ compression="gzip"/>
+ <tar destfile="${output}/asf-logo.gif.tar.bz2"
+ basedir=".."
+ includes="asf-logo.gif"
+ compression="bzip2" />
+ </target>
+
+ <target name="testGZipResource">
+ <mkdir dir="${output}/testout"/>
+ <tar destfile="${output}/testout/test.tar">
+ <gzipresource>
+ <file file="expected/asf-logo.gif.gz"/>
+ </gzipresource>
+ </tar>
+ <untar src="${output}/testout/test.tar" dest="${output}/untar"/>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/taskdef.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/taskdef.xml
new file mode 100644
index 00000000..4b0658e4
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/taskdef.xml
@@ -0,0 +1,89 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<project name="xxx-test" basedir="." default="test1">
+
+ <path id="testclasses">
+ <pathelement location="../../../../build/testcases" />
+ <pathelement path="${java.class.path}" />
+ </path>
+
+ <taskdef name="global"
+ classname="org.example.tasks.TaskdefTestContainerTask">
+ <classpath refid="testclasses" />
+ </taskdef>
+
+ <target name="test1">
+ <taskdef/>
+ </target>
+
+ <target name="test2">
+ <taskdef name=""/>
+ </target>
+
+ <target name="test3">
+ <taskdef classname=""/>
+ </target>
+
+ <target name="test4">
+ <taskdef name="" classname="oops"/>
+ </target>
+
+ <target name="test5">
+ <taskdef name="test" classname="org.apache.tools.ant.Project" />
+ </target>
+
+ <target name="test5a">
+ <taskdef name="test" classname="org.apache.tools.ant.taskdefs.Copy" />
+ </target>
+
+ <target name="test6">
+ <taskdef name="test6"
+ classname="org.example.tasks.TaskdefTestSimpleTask">
+ <classpath refid="testclasses" />
+ </taskdef>
+ <test6>
+ <echo message="worked" />
+ </test6>
+ </target>
+
+ <target name="test7">
+ <taskdef name="test7"
+ classname="org.example.tasks.TaskdefTestContainerTask">
+ <classpath refid="testclasses" />
+ </taskdef>
+ <test7>
+ <echo message="worked" />
+ </test7>
+ </target>
+
+ <target name="testGlobal">
+ <global>
+ <echo message="worked" />
+ </global>
+ </target>
+
+ <target name="testOverride">
+ <taskdef name="copy" classname="org.apache.tools.ant.taskdefs.Echo" />
+ <copy>In target</copy>
+ <sequential>
+ <copy>In TaskContainer</copy>
+ </sequential>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/template.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/template.xml
new file mode 100644
index 00000000..9f351c73
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/template.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/test.antlib.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/test.antlib.xml
new file mode 100644
index 00000000..37ff7f8e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/test.antlib.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<antlib>
+ <typedef
+ name="mytask" onerror="ignore"
+ classname="org.apache.tools.ant.taskdefs.AntlibTest$MyTask"/>
+</antlib>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/test2.antlib.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/test2.antlib.xml
new file mode 100644
index 00000000..9a2509ec
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/test2.antlib.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<antlib>
+ <typedef
+ name="mytask2" onerror="ignore"
+ classname="org.apache.tools.ant.taskdefs.AntlibTest$MyTask2"/>
+</antlib>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/toplevelant.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/toplevelant.xml
new file mode 100644
index 00000000..e6b466a6
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/toplevelant.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<project name="ant-test" basedir="." default="bar">
+ <ant antfile="toplevelant.xml" target="foo"/>
+
+ <target name="foo"/>
+ <target name="bar"/>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/toplevelantcall.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/toplevelantcall.xml
new file mode 100644
index 00000000..2ccabe7f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/toplevelantcall.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<project name="ant-test" basedir="." default="bar">
+ <antcall target="foo"/>
+
+ <target name="foo"/>
+ <target name="bar"/>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/toplevelsubant.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/toplevelsubant.xml
new file mode 100644
index 00000000..b7a3a351
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/toplevelsubant.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<project name="ant-test" basedir="." default="bar">
+ <subant target="foo">
+ <fileset dir="." includes="toplevelsubant.xml"/>
+ </subant>
+
+ <target name="foo"/>
+ <target name="bar"/>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/touch.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/touch.xml
new file mode 100644
index 00000000..3b426d90
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/touch.xml
@@ -0,0 +1,216 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="cleanup" basedir=".">
+
+ <property name="mappermillis" value="1072224000000" />
+
+ <selector id="map.selector">
+ <date millis="${mappermillis}" />
+ </selector>
+
+ <target name="cleanup">
+ <delete>
+ <fileset dir="." includes="touchtest*" />
+ </delete>
+ </target>
+
+ <target name="noSeconds">
+ <touch file="touchtest" datetime="06/24/2003 2:20 pm"/>
+ </target>
+
+ <target name="seconds">
+ <touch file="touchtest" datetime="06/24/2003 2:20:12 pm"/>
+ </target>
+
+ <target name="testNow">
+ <touch file="touchtest" />
+ </target>
+
+ <target name="testMillis">
+ <!-- this one is about 21 years after the epoch -->
+ <!-- less than 20 years after the epoch, test does not pass on my Win2K/FAT -->
+ <!-- Antoine February 8, 2004 -->
+ <!-- see http://developer.java.sun.com/developer/bugParade/bugs/4177432.html -->
+ <!-- and http://developer.java.sun.com/developer/bugParade/bugs/4697792.html -->
+ <!-- not sure why -->
+ <touch file="touchtest" millis="662256000000" />
+ </target>
+
+ <target name="test2000">
+ <!-- this number of milliseconds is 30 * 365 * 24 * 3600 * 1000 -->
+ <!-- so the corresponding time is at the end of 1999 -->
+ <touch file="touchtest" millis="946080000000" />
+ </target>
+
+ <target name="testFilelist">
+ <touch millis="662256000000" >
+ <filelist dir="." files="touchtest"/>
+ </touch>
+ </target>
+
+ <target name="testFileset" depends="testNow">
+ <touch millis="946080000000" >
+ <fileset dir="." includes="touchtest"/>
+ </touch>
+ </target>
+
+ <target name="testResourceCollection">
+ <touch millis="1662256000000">
+ <file file="touchtest"/>
+ </touch>
+ </target>
+
+ <target name="testMappedFileset">
+ <touch file="touchtest" millis="${mappermillis}" />
+ <touch>
+ <fileset file="touchtest" />
+ <compositemapper>
+ <globmapper from="*" to="*foo" />
+ <globmapper from="*" to="*bar" />
+ </compositemapper>
+ </touch>
+
+ <fileset id="touchtest" file="touchtest">
+ <selector refid="map.selector" />
+ </fileset>
+
+ <fileset id="touchtestfoo" file="touchtestfoo">
+ <selector refid="map.selector" />
+ </fileset>
+
+ <fileset id="touchtestbar" file="touchtestbar">
+ <selector refid="map.selector" />
+ </fileset>
+
+ <pathconvert property="touchtest" pathsep=" "
+ refid="touchtest" setonempty="false" />
+
+ <pathconvert property="touchtestfoo" pathsep=" "
+ refid="touchtestfoo" setonempty="false" />
+
+ <pathconvert property="touchtestbar" pathsep=" "
+ refid="touchtestbar" setonempty="false" />
+
+ <fail>
+ <condition>
+ <not>
+ <and>
+ <isset property="touchtest" />
+ <isset property="touchtestfoo" />
+ <isset property="touchtestbar" />
+ </and>
+ </not>
+ </condition>
+ </fail>
+
+ </target>
+
+ <target name="testExplicitMappedFileset">
+ <touch file="touchtest" millis="${mappermillis}" />
+ <touch>
+ <fileset file="touchtest" />
+ <mapper>
+ <compositemapper>
+ <globmapper from="*" to="*foo" />
+ <globmapper from="*" to="*bar" />
+ </compositemapper>
+ </mapper>
+ </touch>
+
+ <fileset id="touchtest" file="touchtest">
+ <selector refid="map.selector" />
+ </fileset>
+
+ <fileset id="touchtestfoo" file="touchtestfoo">
+ <selector refid="map.selector" />
+ </fileset>
+
+ <fileset id="touchtestbar" file="touchtestbar">
+ <selector refid="map.selector" />
+ </fileset>
+
+ <pathconvert property="touchtest" pathsep=" "
+ refid="touchtest" setonempty="false" />
+
+ <pathconvert property="touchtestfoo" pathsep=" "
+ refid="touchtestfoo" setonempty="false" />
+
+ <pathconvert property="touchtestbar" pathsep=" "
+ refid="touchtestbar" setonempty="false" />
+
+ <fail>
+ <condition>
+ <not>
+ <and>
+ <isset property="touchtest" />
+ <isset property="touchtestfoo" />
+ <isset property="touchtestbar" />
+ </and>
+ </not>
+ </condition>
+ </fail>
+
+ </target>
+
+ <target name="testMappedFilelist">
+ <touch millis="${mappermillis}">
+ <filelist dir="." files="idonotexist" />
+ <mergemapper to="touchtest" />
+ </touch>
+
+ <fileset id="touchtest" file="touchtest">
+ <selector refid="map.selector" />
+ </fileset>
+
+ <pathconvert property="touchtest" pathsep=" "
+ refid="touchtest" setonempty="false" />
+
+ <fail>
+ <condition>
+ <not>
+ <isset property="touchtest" />
+ </not>
+ </condition>
+ </fail>
+
+ </target>
+
+ <target name="testGoodPattern">
+ <touch file="touchtest" datetime="06242003142012GMTfoo" pattern="MMddyyyyHHmmssz'foo'" />
+
+ <fileset id="touchtest" file="touchtest">
+ <date millis="1056464412000" />
+ </fileset>
+
+ <pathconvert property="touchtest" pathsep=" "
+ refid="touchtest" setonempty="false" />
+
+ <fail>
+ <condition>
+ <not>
+ <isset property="touchtest" />
+ </not>
+ </condition>
+ </fail>
+ </target>
+
+ <target name="testBadPattern">
+ <touch file="touchtest" datetime="06242003142012GMTfoo" pattern="MMddyyyyHHmmssz'bar'" />
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/typeadapter.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/typeadapter.xml
new file mode 100644
index 00000000..c2aa70e1
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/typeadapter.xml
@@ -0,0 +1,79 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<project name="test" basedir="." default="invalid">
+ <property name="testcases.dir" location="../../../../build/testcases"/>
+ <path id="testclasses">
+ <pathelement location="${testcases.dir}" />
+ <pathelement path="${java.class.path}" />
+ </path>
+
+ <target name="taskadapter">
+ <typedef name="myexec"
+ classname="org.apache.tools.ant.taskdefs.TypeAdapterTest$MyExec"
+ classpathref="testclasses"
+ adapter="org.apache.tools.ant.TaskAdapter"/>
+ <myexec/>
+ </target>
+
+ <target name="runadapter">
+ <typedef
+ name="myrunnable"
+ classname="org.apache.tools.ant.taskdefs.TypeAdapterTest$MyRunnable"
+ classpathref="testclasses"
+ adapter="org.apache.tools.ant.taskdefs.TypeAdapterTest$RunnableAdapter"/>
+ <myrunnable/>
+ </target>
+
+ <target name="runadaptererror">
+ <typedef
+ name="myrunnable"
+ classname="org.apache.tools.ant.taskdefs.TypeAdapterTest$MyExec"
+ classpathref="testclasses"
+ adapter="org.apache.tools.ant.taskdefs.TypeAdapterTest$RunnableAdapter"/>
+ <myrunnable/>
+ </target>
+
+ <target name="delay">
+ <typedef
+ name="mytask"
+ classname="org.apache.tools.ant.taskdefs.TypeAdapterTest$MyTask"
+ classpathref="testclasses"
+ onerror="ignore"/>
+ <mytask/>
+ </target>
+
+ <target name="onerror.report">
+ <typedef
+ name="mytask"
+ classname="org.apache.tools.ant.taskdefs.TypeAdapterTest$MyTaskNotPresent"
+ classpathref="testclasses"
+ onerror="report"/>
+ </target>
+
+ <target name="onerror.ignore">
+ <typedef
+ name="mytask"
+ classname="org.apache.tools.ant.taskdefs.TypeAdapterTest$MyTaskNotPresent"
+ classpathref="testclasses"
+ onerror="ignore"/>
+ </target>
+
+
+</project>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/typedef.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/typedef.xml
new file mode 100644
index 00000000..1c7922b9
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/typedef.xml
@@ -0,0 +1,84 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<project name="test" basedir="." default="invalid">
+
+ <target name="invalid">
+ <fail>This file should only be run via a testcase</fail>
+ </target>
+
+ <target name="empty">
+ <typedef />
+ </target>
+
+ <target name="noClassname">
+ <typedef name="dummy" />
+ </target>
+
+ <target name="noName">
+ <typedef classname="org.example.types.TypedefTestType">
+ <classpath refid="testclasses" />
+ </typedef>
+ </target>
+
+ <target name="classNotFound">
+ <typedef name="" classname="oops"/>
+ </target>
+
+ <path id="testclasses">
+ <pathelement location="../../../../build/testcases" />
+ <pathelement path="${java.class.path}" />
+ </path>
+
+ <typedef name="global"
+ classname="org.example.types.TypedefTestType">
+ <classpath refid="testclasses" />
+ </typedef>
+
+ <target name="testGlobal">
+ <global id="global" />
+ </target>
+
+ <target name="testLocal">
+ <typedef name="localtype"
+ classname="org.example.types.TypedefTestType">
+ <classpath refid="testclasses" />
+ </typedef>
+ <localtype id="local" />
+ </target>
+
+ <target name="double-notpresent">
+ <typedef name="mytask" classname="notpresent" onerror="ignore"/>
+ <typedef name="mytask" classname="notpresent" onerror="ignore"/>
+ <typedef name="mytask" classname="org.apache.tools.ant.taskdefs.Echo"
+ onerror="ignore"/>
+ <mytask>hi</mytask>
+ </target>
+
+ <target name="noresourcefailall">
+ <typedef resource="somenotpresentfile.properties" onerror="failall"/>
+ </target>
+
+ <target name="noresourcefail">
+ <typedef resource="somenotpresentfile.properties" onerror="fail"/>
+ </target>
+
+ <target name="noresourcenotfail">
+ <typedef resource="somenotpresentfile.properties" />
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/untar.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/untar.xml
new file mode 100644
index 00000000..04d44b37
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/untar.xml
@@ -0,0 +1,103 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<project basedir="." default="tearDown">
+
+ <import file="../buildfiletest-base.xml"/>
+
+ <target name="setUp">
+ <mkdir dir="${output}"/>
+ <mkdir dir="${output}/untar"/>
+ </target>
+
+ <target name="testTarTask">
+ <ant antfile="tar.xml" target="feather" />
+ <untar src="${output}/asf-logo.gif.tar" dest="${output}/untar" />
+ </target>
+
+ <target name="testGzipTarTask">
+ <ant antfile="tar.xml" target="feather" />
+ <untar src="${output}/asf-logo.gif.tar.gz" dest="${output}/untar" compression="gzip" />
+ </target>
+
+ <target name="testBzip2TarTask">
+ <ant antfile="tar.xml" target="feather" />
+ <untar src="${output}/asf-logo.gif.tar.bz2" dest="${output}/untar" compression="bzip2"/>
+ </target>
+
+ <target name="realTest">
+ <untar src="expected/asf-logo.gif.tar" dest="${output}/untar" />
+ </target>
+
+ <target name="realGzipTest">
+ <untar src="expected/asf-logo.gif.tar.gz" dest="${output}/untar" compression="gzip" />
+ </target>
+
+ <target name="realBzip2Test">
+ <untar src="expected/asf-logo.gif.tar.bz2" dest="${output}/untar" compression="bzip2"/>
+ </target>
+
+
+ <target name="srcDirTest">
+ <untar src="." dest="${output}/untar" />
+ </target>
+
+ <target name="encodingTest">
+ <mkdir dir="${output}/untartestin"/>
+ <touch file="${output}/untartestin/foo"/>
+ <tar tarfile="${output}/untartest.tar" basedir="${output}/untartestin" encoding="UnicodeBig"/>
+ <mkdir dir="${output}/untartestout"/>
+ <untar src="${output}/untartest.tar" dest="${output}/untartestout" encoding="UnicodeBig"/>
+ </target>
+
+ <target name="resourceCollection">
+ <mkdir dir="${output}/untartestout"/>
+ <zip destfile="${output}/untartestout/test.zip">
+ <fileset dir="expected">
+ <include name="asf-logo.gif.tar"/>
+ </fileset>
+ </zip>
+ <untar dest="${output}/untar">
+ <zipfileset src="${output}/untartestout/test.zip">
+ <include name="*.tar"/>
+ </zipfileset>
+ </untar>
+ </target>
+
+ <target name="prepareTestTar">
+ <mkdir dir="${output}/untartestin/1"/>
+ <mkdir dir="${output}/untartestin/2"/>
+ <touch file="${output}/untartestin/1/foo"/>
+ <touch file="${output}/untartestin/2/bar"/>
+ <copy todir="${output}/untartestin/2">
+ <fileset dir="expected" includes="*md5*"/>
+ </copy>
+ <tar destfile="${output}/untartest.tar" basedir="${output}/untartestin"/>
+ </target>
+
+ <target name="testDocumentationClaimsOnCopy" depends="prepareTestTar">
+ <copy todir="${output}/untar" preservelastmodified="true">
+ <tarfileset src="${output}/untartest.tar">
+ <patternset>
+ <include name="2/"/>
+ </patternset>
+ </tarfileset>
+ </copy>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/unzip.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/unzip.xml
new file mode 100644
index 00000000..ee96ee1f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/unzip.xml
@@ -0,0 +1,184 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<project name="xxx-test" basedir="." default="test1">
+
+ <import file="../buildfiletest-base.xml"/>
+
+ <target name="setUp">
+ <mkdir dir="${output}"/>
+ </target>
+
+
+ <target name="test1">
+ <unzip/>
+ </target>
+
+ <target name="test2">
+ <unzip src=""/>
+ </target>
+
+ <target name="test3">
+ <unzip dest=""/>
+ </target>
+
+ <target name="testZipTask">
+ <ant antfile="zip.xml" target="feather" />
+ <unzip src="${output}/asf-logo.gif.zip" dest="${output}" />
+ </target>
+
+ <target name="testUncompressedZipTask">
+ <ant antfile="zip.xml" target="uncompressed-feather" />
+ <unzip src="${output}/asf-logo.gif.zip" dest="${output}" />
+ </target>
+
+ <target name="realTest">
+ <unzip src="expected/asf-logo.gif.zip" dest="${output}" />
+ </target>
+
+ <target name="prepareTestZip">
+ <mkdir dir="${output}/unziptestin/1"/>
+ <mkdir dir="${output}/unziptestin/2"/>
+ <touch file="${output}/unziptestin/1/foo"/>
+ <touch file="${output}/unziptestin/2/bar"/>
+ <zip destfile="${output}/unziptest.zip" basedir="${output}/unziptestin"/>
+ </target>
+
+ <target name="testPatternSetExcludeOnly" depends="prepareTestZip">
+ <unzip dest="${output}/unziptestout" src="${output}/unziptest.zip">
+ <patternset>
+ <exclude name="1/**"/>
+ </patternset>
+ </unzip>
+ </target>
+
+ <target name="testPatternSetIncludeOnly" depends="prepareTestZip">
+ <unzip dest="${output}/unziptestout" src="${output}/unziptest.zip">
+ <patternset>
+ <include name="2/**"/>
+ </patternset>
+ </unzip>
+ </target>
+
+ <target name="testPatternSetIncludeAndExclude" depends="prepareTestZip">
+ <unzip dest="${output}/unziptestout" src="${output}/unziptest.zip">
+ <patternset>
+ <include name="2/**"/>
+ <exclude name="2/**"/>
+ </patternset>
+ </unzip>
+ </target>
+
+ <target name="testTwoPatternSets" depends="prepareTestZip">
+ <unzip dest="${output}/unziptestout" src="${output}/unziptest.zip">
+ <patternset>
+ <include name="2/**"/>
+ </patternset>
+ <patternset>
+ <include name="3/**"/>
+ </patternset>
+ </unzip>
+ </target>
+
+ <target name="testTwoPatternSetsWithExcludes" depends="prepareTestZip">
+ <unzip dest="${output}/unziptestout" src="${output}/unziptest.zip">
+ <patternset>
+ <include name="2/**"/>
+ </patternset>
+ <patternset>
+ <exclude name="1/**"/>
+ <exclude name="2/**"/>
+ </patternset>
+ </unzip>
+ </target>
+
+ <target name="selfExtractingArchive">
+ <mkdir dir="${output}/unziptestout"/>
+ <unzip dest="${output}/unziptestout" src="zip/test.exe"/>
+ </target>
+
+ <!-- Bugzilla Report 20969 -->
+ <target name="testPatternSetSlashOnly" depends="prepareTestZip">
+ <unzip dest="${output}/unziptestout" src="${output}/unziptest.zip">
+ <patternset>
+ <include name="2/"/>
+ </patternset>
+ </unzip>
+ </target>
+
+ <!-- Bugzilla Report 10504 -->
+ <target name="encodingTest">
+ <mkdir dir="${output}/unziptestin"/>
+ <touch file="${output}/unziptestin/foo"/>
+ <zip zipfile="${output}/unziptest.zip" basedir="${output}/unziptestin" encoding="UnicodeBig"/>
+ <mkdir dir="${output}/unziptestout"/>
+ <unzip src="${output}/unziptest.zip" dest="${output}/unziptestout" encoding="UnicodeBig"/>
+ </target>
+
+ <!-- Bugzilla Report 21996 -->
+ <target name="testFlattenMapper" depends="prepareTestZip">
+ <unzip dest="${output}/unziptestout" src="${output}/unziptest.zip">
+ <patternset>
+ <include name="1/**"/>
+ </patternset>
+ <mapper type="flatten"/>
+ </unzip>
+ </target>
+
+ <!-- Bugzilla Report 21996 -->
+ <target name="testGlobMapper" depends="prepareTestZip">
+ <unzip dest="${output}/unziptestout" src="${output}/unziptest.zip">
+ <patternset>
+ <include name="1/**"/>
+ </patternset>
+ <mapper type="glob" from="*" to="*.txt"/>
+ </unzip>
+ </target>
+
+ <target name="testTwoMappers" depends="prepareTestZip">
+ <unzip dest="${output}/unziptestout" src="${output}/unziptest.zip">
+ <patternset>
+ <include name="1/**"/>
+ </patternset>
+ <mapper type="glob" from="*" to="*.txt"/>
+ <mapper type="flatten"/>
+ </unzip>
+ </target>
+
+ <target name="testResourceCollection">
+ <unzip dest="${output}/unziptestout">
+ <patternset>
+ <include name="junit/**"/>
+ </patternset>
+ <restrict>
+ <path path="${java.class.path}"/>
+ <type type="file" xmlns="antlib:org.apache.tools.ant.types.resources.selectors"/>
+ </restrict>
+ </unzip>
+ </target>
+
+ <target name="testDocumentationClaimsOnCopy" depends="prepareTestZip">
+ <copy todir="${output}/unziptestout" preservelastmodified="true">
+ <zipfileset src="${output}/unziptest.zip">
+ <patternset>
+ <include name="2/"/>
+ </patternset>
+ </zipfileset>
+ </copy>
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/uptodate.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/uptodate.xml
new file mode 100644
index 00000000..04bb3707
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/uptodate.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project basedir=".">
+
+ <target name="setUp">
+ <touch file="source"/>
+ <touch file="target"/>
+ </target>
+
+ <target name="tearDown">
+ <delete file="source"/>
+ <delete file="target"/>
+ </target>
+
+ <target name="testFilesetUpToDate">
+ <uptodate property="foo" targetfile="target">
+ <srcfiles dir="." includes="source"/>
+ </uptodate>
+ </target>
+
+ <target name="testFilesetOutOfDate">
+ <uptodate property="foo" targetfile="source">
+ <srcfiles dir="." includes="target"/>
+ </uptodate>
+ </target>
+
+ <target name="testRCUpToDate">
+ <uptodate property="foo" targetfile="target">
+ <srcresources>
+ <fileset dir="." includes="source"/>
+ </srcresources>
+ </uptodate>
+ </target>
+
+ <target name="testRCOutOfDate">
+ <uptodate property="foo" targetfile="source">
+ <srcresources>
+ <fileset dir="." includes="target"/>
+ </srcresources>
+ </uptodate>
+ </target>
+</project> \ No newline at end of file
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/war.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/war.xml
new file mode 100644
index 00000000..b000ecf5
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/war.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<project name="war-test" basedir="." default="help">
+ <import file="../buildfiletest-base.xml"/>
+
+ <target name="setUp">
+ <mkdir dir="${output}" />
+ </target>
+
+
+ <target name="help">
+ <echo message="Test file for the war task"/>
+ </target>
+
+ <target name="testlibrefs" depends="setUp">
+ <fileset id="test" dir="." includes="war.xml"/>
+ <war webxml="war.xml" destfile="${output}/test.war">
+ <lib refid="test"/>
+ </war>
+ <unzip src="${output}/test.war" dest="${output}"/>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/whichresource.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/whichresource.xml
new file mode 100644
index 00000000..352e9c0e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/whichresource.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="fail">
+ <target name="fail">
+ <fail>Run via testcases only</fail>
+ </target>
+
+ <target name="testClassname">
+ <whichresource class="org.apache.tools.ant.Main"
+ property="antmain"/>
+ </target>
+
+ <target name="testResourcename">
+ <whichresource resource="org/apache/tools/ant/taskdefs/defaults.properties"
+ property="defaults"/>
+ </target>
+
+ <target name="testResourcenameWithLeadingSlash">
+ <whichresource resource="/org/apache/tools/ant/taskdefs/defaults.properties"
+ property="defaults"/>
+ </target>
+</project> \ No newline at end of file
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlns.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlns.xml
new file mode 100644
index 00000000..e6991661
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlns.xml
@@ -0,0 +1,67 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="test" xmlns:other="this is the other uri"
+ other:attr="this should be ignored by ant">
+
+ <property name="testcases.dir" location="../../../../build/testcases"/>
+
+ <path id="testclasses">
+ <pathelement location="${testcases.dir}" />
+ <pathelement path="${java.class.path}" />
+ </path>
+
+ <target name="xmlns" xmlns:test="this.is.another.test.uri">
+ <typedef classname="org.apache.tools.ant.taskdefs.XmlnsTest$MyTask"
+ classpathref="testclasses"
+ name="mytask"
+ uri="this.is.another.test.uri" />
+ <test:mytask/>
+ </target>
+
+ <target name="other" other:a="this is another attribute">
+ <echo other:g="abc" message="a message"/>
+ </target>
+
+ <target name="ns.attributes">
+ <taskdef name="my.echo" classname="org.apache.tools.ant.taskdefs.Echo"
+ uri="x-uri"/>
+ <x:my.echo x:message="hello world" xmlns:x="x-uri"/>
+ </target>
+
+ <target name="xmlns.file" xmlns:test="this.is.a.test.uri">
+ <typedef file="test.antlib.xml"
+ classpathref="testclasses"
+ uri="this.is.a.test.uri" />
+ <test:mytask/>
+ </target>
+
+ <target name="core">
+ <typedef file="test.antlib.xml"
+ classpathref="testclasses"
+ uri="antlib:org.apache.tools.ant" />
+ <mytask/>
+ </target>
+
+ <target name="excluded">
+ <typedef file="test.antlib.xml"
+ classpathref="testclasses"
+ uri="ant:notallowed" />
+ </target>
+
+
+</project> \ No newline at end of file
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty.xml
new file mode 100644
index 00000000..a19eb6ce
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="test" default="test" basedir=".">
+
+ <target name="test">
+ <xmlproperty file="xmlproperty_data.xml"/>
+ </target>
+
+ <target name="testdtd">
+ <xmlproperty file="xmlproperty_withdtd.xml"/>
+ </target>
+
+ <target name="testResource">
+ <loadfile srcfile="xmlproperty_data.xml" property="prop"/>
+ <xmlproperty>
+ <string value="${prop}"/>
+ </xmlproperty>
+ </target>
+
+ <target name="testneedscat">
+ <xmlproperty file="xmlproperty_needscat.xml">
+ <xmlcatalog>
+ <dtd publicId="-//FOO//DTD Skin Configuration V0.1//EN"
+ location="skinconfig.dtd"/>
+ </xmlcatalog>
+ </xmlproperty>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/goldfiles/keeproot-collapse-input1.properties b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/goldfiles/keeproot-collapse-input1.properties
new file mode 100644
index 00000000..d60cbab5
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/goldfiles/keeproot-collapse-input1.properties
@@ -0,0 +1,21 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+properties.root=foo,bar
+properties.a.b.c=d
+properties.a.b=e
+properties.foo.bar=quux,quux1
+properties.foo.quux=bar
+properties.tag.value=foo
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/goldfiles/keeproot-collapse-original.properties b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/goldfiles/keeproot-collapse-original.properties
new file mode 100644
index 00000000..ce05e187
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/goldfiles/keeproot-collapse-original.properties
@@ -0,0 +1,20 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+root-tag.myattr=true
+root-tag.inner-tag=Text
+root-tag.inner-tag.someattr=val
+root-tag.a2.a3.a4=false
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/goldfiles/keeproot-collapse-override.properties b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/goldfiles/keeproot-collapse-override.properties
new file mode 100644
index 00000000..33f8611a
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/goldfiles/keeproot-collapse-override.properties
@@ -0,0 +1,17 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Match value hardwired in code, NOT in the input...
+override.property.test=foo
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/goldfiles/keeproot-nocollapse-input1.properties b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/goldfiles/keeproot-nocollapse-input1.properties
new file mode 100644
index 00000000..153ac765
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/goldfiles/keeproot-nocollapse-input1.properties
@@ -0,0 +1,8 @@
+properties.root=foo,bar
+properties.a.b(c)=d
+properties.a.b=e
+properties.foo(bar)=quux
+properties.foo.bar=quux1
+properties.foo.quux=bar
+properties.tag(value)=foo
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/goldfiles/keeproot-nocollapse-original.properties b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/goldfiles/keeproot-nocollapse-original.properties
new file mode 100644
index 00000000..47e0c2de
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/goldfiles/keeproot-nocollapse-original.properties
@@ -0,0 +1,20 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+root-tag(myattr)=true
+root-tag.inner-tag=Text
+root-tag.inner-tag(someattr)=val
+root-tag.a2.a3.a4=false
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/goldfiles/keeproot-semantic-include.properties b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/goldfiles/keeproot-semantic-include.properties
new file mode 100644
index 00000000..d60cbab5
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/goldfiles/keeproot-semantic-include.properties
@@ -0,0 +1,21 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+properties.root=foo,bar
+properties.a.b.c=d
+properties.a.b=e
+properties.foo.bar=quux,quux1
+properties.foo.quux=bar
+properties.tag.value=foo
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/goldfiles/keeproot-semantic-input1.properties b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/goldfiles/keeproot-semantic-input1.properties
new file mode 100644
index 00000000..46b807ba
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/goldfiles/keeproot-semantic-input1.properties
@@ -0,0 +1,21 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+properties.root=foo,bar
+properties.a.b.c=d
+properties.a.b=e
+properties.foo.bar=quux,quux1
+properties.foo.quux=bar
+properties.tag=foo
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/goldfiles/keeproot-semantic-override.properties b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/goldfiles/keeproot-semantic-override.properties
new file mode 100644
index 00000000..33f8611a
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/goldfiles/keeproot-semantic-override.properties
@@ -0,0 +1,17 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Match value hardwired in code, NOT in the input...
+override.property.test=foo
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/goldfiles/nokeeproot-collapse-input1.properties b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/goldfiles/nokeeproot-collapse-input1.properties
new file mode 100644
index 00000000..7cfd29e8
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/goldfiles/nokeeproot-collapse-input1.properties
@@ -0,0 +1,21 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+root=foo,bar
+a.b.c=d
+a.b=e
+foo.bar=quux,quux1
+foo.quux=bar
+tag.value=foo
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/goldfiles/nokeeproot-collapse-original.properties b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/goldfiles/nokeeproot-collapse-original.properties
new file mode 100644
index 00000000..5842c38f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/goldfiles/nokeeproot-collapse-original.properties
@@ -0,0 +1,19 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+inner-tag=Text
+inner-tag.someattr=val
+a2.a3.a4=false
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/goldfiles/nokeeproot-nocollapse-input1.properties b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/goldfiles/nokeeproot-nocollapse-input1.properties
new file mode 100644
index 00000000..3eca3683
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/goldfiles/nokeeproot-nocollapse-input1.properties
@@ -0,0 +1,7 @@
+root=foo,bar
+a.b(c)=d
+a.b=e
+foo(bar)=quux
+foo.bar=quux1
+foo.quux=bar
+tag(value)=foo
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/goldfiles/nokeeproot-nocollapse-multi.properties b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/goldfiles/nokeeproot-nocollapse-multi.properties
new file mode 100644
index 00000000..9ef90efb
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/goldfiles/nokeeproot-nocollapse-multi.properties
@@ -0,0 +1,16 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+foo.bar=1,2,3,4 \ No newline at end of file
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/goldfiles/nokeeproot-nocollapse-original.properties b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/goldfiles/nokeeproot-nocollapse-original.properties
new file mode 100644
index 00000000..550f2130
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/goldfiles/nokeeproot-nocollapse-original.properties
@@ -0,0 +1,19 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+inner-tag=Text
+inner-tag(someattr)=val
+a2.a3.a4=false
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/goldfiles/nokeeproot-semantic-include-input1.properties b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/goldfiles/nokeeproot-semantic-include-input1.properties
new file mode 100644
index 00000000..7cfd29e8
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/goldfiles/nokeeproot-semantic-include-input1.properties
@@ -0,0 +1,21 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+root=foo,bar
+a.b.c=d
+a.b=e
+foo.bar=quux,quux1
+foo.quux=bar
+tag.value=foo
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/goldfiles/nokeeproot-semantic-input1.properties b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/goldfiles/nokeeproot-semantic-input1.properties
new file mode 100644
index 00000000..5dfcfb53
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/goldfiles/nokeeproot-semantic-input1.properties
@@ -0,0 +1,21 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+root=foo,bar
+a.b.c=d
+a.b=e
+foo.bar=quux,quux1
+foo.quux=bar
+tag=foo
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/goldfiles/nokeeproot-semantic-locations.properties b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/goldfiles/nokeeproot-semantic-locations.properties
new file mode 100644
index 00000000..f945d7ca
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/goldfiles/nokeeproot-semantic-locations.properties
@@ -0,0 +1,16 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+file=FILE.foo \ No newline at end of file
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/goldfiles/nokeeproot-semantic-paths.properties b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/goldfiles/nokeeproot-semantic-paths.properties
new file mode 100644
index 00000000..1bf51de9
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/goldfiles/nokeeproot-semantic-paths.properties
@@ -0,0 +1,16 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+foo=ID.path \ No newline at end of file
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/goldfiles/nokeeproot-semantic-references.properties b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/goldfiles/nokeeproot-semantic-references.properties
new file mode 100644
index 00000000..e55913a1
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/goldfiles/nokeeproot-semantic-references.properties
@@ -0,0 +1,20 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+property=foo
+foo.bar=foo
+foo.quux=foo
+foo.thunk=foo
+foo.property=ID.foo
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/inputs/input1.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/inputs/input1.xml
new file mode 100644
index 00000000..28328c56
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/inputs/input1.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<properties>
+ <root>foo</root>
+ <root>bar</root>
+ <a><b c="d">e</b></a>
+ <foo bar="quux">
+ <bar>quux1</bar>
+ <quux>bar</quux>
+ </foo>
+ <tag value="foo"/>
+</properties>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/inputs/locations.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/inputs/locations.xml
new file mode 100644
index 00000000..d5cace80
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/inputs/locations.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<locations>
+ <file location="foo"/>
+</locations> \ No newline at end of file
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/inputs/multi.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/inputs/multi.xml
new file mode 100644
index 00000000..66904d6a
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/inputs/multi.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<properties>
+ <foo>
+ <bar>1</bar>
+ <bar>2</bar>
+ <bar>3</bar>
+ <bar>4</bar>
+ </foo>
+</properties> \ No newline at end of file
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/inputs/original.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/inputs/original.xml
new file mode 100644
index 00000000..ef2603cc
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/inputs/original.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<root-tag myattr="true">
+ <inner-tag someattr="val">Text</inner-tag>
+ <a2><a3><a4>false</a4></a3></a2>
+</root-tag>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/inputs/override.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/inputs/override.xml
new file mode 100644
index 00000000..c7da9c48
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/inputs/override.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<root>
+ <override>
+ <!-- This property should not get set. The
+ XmlPropertyTest code explicitly sets
+ override.property.test to foo to make
+ sure that attempts to reset it via
+ property file loads *fail*. -->
+ <property test="bar"/>
+ </override>
+</root> \ No newline at end of file
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/inputs/paths.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/inputs/paths.xml
new file mode 100644
index 00000000..83422d9d
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/inputs/paths.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<paths>
+ <classpath pathid="foo">
+ <path value="bar"/>
+ </classpath>
+</paths> \ No newline at end of file
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/inputs/references.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/inputs/references.xml
new file mode 100644
index 00000000..7e88b7b1
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty/inputs/references.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<references>
+ <property value="foo" id="foo.property"/>
+ <foo bar="${property}">
+ <quux refid="foo.property"/>
+ <thunk>${property}</thunk>
+ </foo>
+</references> \ No newline at end of file
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty_data.dtd b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty_data.dtd
new file mode 100644
index 00000000..5d75d6e5
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty_data.dtd
@@ -0,0 +1,30 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!ELEMENT root-tag (inner-tag, a2, cdatatag)>
+<!ATTLIST root-tag myattr CDATA "">
+
+<!ELEMENT inner-tag (#PCDATA)>
+<!ATTLIST inner-tag someattr CDATA "">
+
+<!ELEMENT a2 (a3)>
+
+<!ELEMENT a3 (a4)>
+
+<!ELEMENT a4 (#PCDATA)>
+
+<!ELEMENT cdatatag (#PCDATA)>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty_data.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty_data.xml
new file mode 100644
index 00000000..5f922214
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty_data.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+ <root-tag myattr="true">
+ <inner-tag someattr="val">Text</inner-tag>
+ <a2><a3><a4>false</a4></a3></a2>
+ <cdatatag><![CDATA[<test>]]></cdatatag>
+ </root-tag>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty_needscat.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty_needscat.xml
new file mode 100644
index 00000000..942a183f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty_needscat.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!DOCTYPE skinconfig PUBLIC "-//FOO//DTD Skin Configuration V0.1//EN" "http://example-no-dtd.com/dtd/skinconfig.dtd">
+<skinconfig>
+ <foo>true</foo>
+ <bar>false</bar>
+</skinconfig>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty_withdtd.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty_withdtd.xml
new file mode 100644
index 00000000..1e96cdb3
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/xmlproperty_withdtd.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!DOCTYPE root-tag SYSTEM "xmlproperty_data.dtd">
+
+ <root-tag myattr="true">
+ <inner-tag someattr="val">Text</inner-tag>
+ <a2><a3><a4>false</a4></a3></a2>
+ <cdatatag><![CDATA[<test>]]></cdatatag>
+ </root-tag>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/zip.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/zip.xml
new file mode 100644
index 00000000..4fa6de6c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/zip.xml
@@ -0,0 +1,287 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<project name="zip-test" basedir="." default="test1">
+
+ <import file="../buildfiletest-base.xml"/>
+
+ <target name="setUp">
+ <mkdir dir="${output}"/>
+ </target>
+
+ <target name="test1">
+ <zip/>
+ </target>
+
+ <target name="test2">
+ <zip destFile="${output}/zip.tmp"/>
+ </target>
+
+ <!-- Test when the zip file includes itself
+ when target file exists before the zip task is run -->
+ <target name="test3">
+ <touch file="${output}/test3.zip"/>
+ <zip destFile="${output}/test3.zip"
+ basedir="${output}/"/>
+ </target>
+
+ <!-- Test when the zip file includes itself
+ when target file does not exist before the zip task is run
+ <target name="test4">
+ <zip destFile="${output}/test4.zip"
+ basedir="."/>
+ </target>
+ -->
+
+ <target name="test5">
+ <zip zipfile="${output}/test5.zip" basedir="." >
+ <exclude name="test5.zip" />
+ </zip>
+ </target>
+
+ <target name="test6">
+ <zip destFile="${output}/test6.zip" basedir=".">
+ <include name="*.xml" />
+ <exclude name="zip.*" />
+ </zip>
+ </target>
+
+ <target name="test7">
+ <copy todir="${output}">
+ <fileset dir="."/>
+ </copy>
+ <zip destFile="${output}/inner7.zip" basedir="${output}" >
+ <exclude name="inner7.zip" />
+ </zip>
+ <zip destFile="${output}/test7.zip" basedir=".">
+ <exclude name="**/*.*" />
+ <zipfileset src="${output}/inner7.zip" />
+ </zip>
+ </target>
+
+ <target name="feather">
+ <zip destFile="${output}/asf-logo.gif.zip"
+ basedir=".."
+ includes="asf-logo.gif" />
+ </target>
+
+ <target name="uncompressed-feather">
+ <zip destFile="${output}/asf-logo.gif.zip"
+ basedir=".."
+ includes="asf-logo.gif" compress="false"/>
+ </target>
+
+ <!-- legacy attribute support -->
+ <target name="test8">
+ <zip zipfile="${output}/test8.zip" basedir="." >
+ <exclude name="test8.zip" />
+ </zip>
+ </target>
+
+ <target name="testZipgroupfileset">
+
+ <zip zipfile="${output}/zipgroupfileset.zip" basedir=".">
+ <zipgroupfileset dir="zip"
+ includes="zipgroupfileset*.zip"
+ excludes="zipgroupfileset3.zip" />
+ <include name="zip/zipgroupfileset3.zip" />
+ </zip>
+ </target>
+
+ <target name="testDuplicateFail">
+
+ <zip zipfile="${output}/duplicateFail.zip" basedir="." duplicate="fail">
+ <zipgroupfileset dir="duplicate" includes="duplicate*.zip" />
+ </zip>
+ </target>
+
+ <target name="testUpdateNotNecessary" depends="feather">
+ <zip destFile="${output}/asf-logo.gif.zip"
+ basedir=".."
+ includes="asf-logo.gif"
+ update="true" />
+ </target>
+
+ <target name="testUpdateIsNecessary" depends="feather">
+ <touch file="${output}/dummyfile" />
+ <copy file="../asf-logo.gif" todir="${output}"/>
+ <zip destFile="${output}/asf-logo.gif.zip"
+ basedir="${output}"
+ includes="asf-logo.gif,dummyfile"
+ update="true" />
+ </target>
+
+ <!-- Bugzilla Report 18403 -->
+ <target name="testPrefixAddsDir">
+ <zip destFile="${output}/test3.zip" filesonly="false">
+ <zipfileset dir="." prefix="test" includes="zip.xml"/>
+ </zip>
+ </target>
+
+ <!-- Bugzilla Report 19449 -->
+ <target name="testFilesOnlyDoesntCauseRecreateSetup">
+ <mkdir dir="${output}/ziptest"/>
+ <touch file="${output}/ziptest/ziptest"/>
+ <zip destFile="${output}/test3.zip" basedir="${output}"
+ includes="ziptest/**" filesonly="true"/>
+ </target>
+
+ <!-- Bugzilla Report 19449 -->
+ <target name="testFilesOnlyDoesntCauseRecreate">
+ <zip destFile="${output}/test3.zip" basedir="."
+ includes="ziptest/**" filesonly="true"/>
+ </target>
+
+ <!-- Bugzilla Report 22865 -->
+ <target name="testEmptySkip">
+ <mkdir dir="${output}/ziptest"/>
+ <zip destFile="${output}/test3.zip" basedir="${output}/ziptest" whenempty="skip"/>
+ <fail message="archive should get skipped">
+ <condition>
+ <available file="${output}/test3.zip" />
+ </condition>
+ </fail>
+ </target>
+
+ <!-- Bugzilla Report 30365 -->
+ <target name="zipEmptyDir">
+ <mkdir dir="${output}/empty/empty2"/>
+ <zip destFile="${output}/test3.zip" basedir="${output}/empty" update="true"/>
+ <fail message="single-directory archive should be created">
+ <condition>
+ <or>
+ <not>
+ <available file="${output}/test3.zip" />
+ </not>
+ <resourcecount when="gt" count="0">
+ <zipfileset src="${output}/test3.zip" />
+ </resourcecount>
+ <resourcecount when="ne" count="1">
+ <restrict>
+ <exists xmlns="antlib:org.apache.tools.ant.types.resources.selectors" />
+ <zipentry zipfile="${output}/test3.zip" name="empty2/" />
+ </restrict>
+ </resourcecount>
+ </or>
+ </condition>
+ </fail>
+ </target>
+
+ <!-- Bugzilla Report 40258 -->
+ <target name="zipEmptyDirFilesOnly">
+ <mkdir dir="${output}/empty/empty2" />
+ <zip destFile="${output}/test3.zip" basedir="${output}/empty" update="true" filesonly="true" />
+ <fail message="archive should get skipped">
+ <condition>
+ <available file="${output}/test3.zip" />
+ </condition>
+ </fail>
+ </target>
+
+ <target name="zipEmptyCreate">
+ <mkdir dir="${output}/empty"/>
+ <zip destFile="${output}/test3.zip" basedir="${output}/empty" whenempty="create" includes="*.xyz"/>
+ <fail message="empty archive should be created">
+ <condition>
+ <or>
+ <not>
+ <available file="${output}/test3.zip" />
+ </not>
+ <resourcecount when="gt" count="0">
+ <zipfileset src="${output}/test3.zip" />
+ </resourcecount>
+ </or>
+ </condition>
+ </fail>
+ </target>
+
+ <target name="testCompressionLevel" depends="test6">
+ <length property="test6.length" file="${output}/test6.zip" />
+ <copy todir="${output}">
+ <fileset dir=".">
+ <include name="*.xml"/>
+ </fileset>
+ </copy>
+ <zip destFile="${output}/testLevel.zip" basedir="${output}" level="9">
+ <include name="*.xml" />
+ <exclude name="zip.*" />
+ </zip>
+ <fail>
+ <condition>
+ <not>
+ <isfileselected file="${output}/testLevel.zip">
+ <size when="less" value="${test6.length}" />
+ </isfileselected>
+ </not>
+ </condition>
+ </fail>
+ </target>
+
+ <!-- Bugzilla Report 33412 -->
+ <target name="testDefaultExcludesAndUpdate">
+ <mkdir dir="${output}/ziptest"/>
+ <touch file="${output}/ziptest/ziptest~"/>
+ <zip destFile="${output}/test3.zip" basedir="${output}/ziptest"
+ defaultexcludes="false"/>
+ <touch file="${output}/ziptest/ziptest2"/>
+ <zip destFile="${output}/test3.zip" basedir="${output}/ziptest"
+ defaultexcludes="false"
+ update="true"/>
+ </target>
+
+ <target name="testFileResource">
+ <zip destFile="${output}/test3.zip">
+ <file file="zip.xml"/>
+ </zip>
+ </target>
+
+ <target name="testNonFileResource">
+ <zip destFile="${output}/test3.zip">
+ <javaresource name="META-INF/MANIFEST.MF"/>
+ </zip>
+ </target>
+
+ <target name="testTarFileSet">
+ <ant antfile="tar.xml" target="feather"/>
+ <zip destFile="${output}/test3.zip">
+ <tarfileset src="${output}/asf-logo.gif.tar" filemode="446"/>
+ </zip>
+ </target>
+
+ <target name="rewriteZeroPermissions">
+ <zip destFile="${output}/test3.zip">
+ <zipfileset src="nopermissions.zip"/>
+ </zip>
+ </target>
+
+ <target name="acceptZeroPermissions">
+ <zip destFile="${output}/test3.zip" preserve0permissions="true">
+ <zipfileset src="nopermissions.zip"/>
+ </zip>
+ </target>
+
+ <target name="testForBugzilla34764">
+ <mkdir dir="${output}/ziptest"/>
+ <touch file="${output}/ziptest/file1"/>
+ <zip destFile="${output}/test3.zip" basedir="${output}/ziptest"/>
+ <touch file="${output}/ziptest/file2"/>
+ <zip destFile="${output}/test3.zip" basedir="${output}/ziptest" update="true"/>
+ </target>
+
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/zip/zipgroupfileset1.zip b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/zip/zipgroupfileset1.zip
new file mode 100644
index 00000000..f3b96ffc
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/zip/zipgroupfileset1.zip
Binary files differ
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/zip/zipgroupfileset2.zip b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/zip/zipgroupfileset2.zip
new file mode 100644
index 00000000..89e09fd5
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/zip/zipgroupfileset2.zip
Binary files differ
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/zip/zipgroupfileset3.zip b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/zip/zipgroupfileset3.zip
new file mode 100644
index 00000000..dead9c12
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/taskdefs/zip/zipgroupfileset3.zip
Binary files differ
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/testkeystore b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/testkeystore
new file mode 100644
index 00000000..5aa6a27d
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/testkeystore
Binary files differ
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/addtype.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/addtype.xml
new file mode 100644
index 00000000..cc8ff24c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/addtype.xml
@@ -0,0 +1,163 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="test" basedir=".">
+
+ <target name="addpath">
+ <typedef name="mypath" classname="org.apache.tools.ant.types.Path"/>
+ <path>
+ <mypath path="build.xml"/>
+ </path>
+ </target>
+
+ <target name="addcondition">
+ <typedef name="mycondition"
+ classname="org.apache.tools.ant.taskdefs.condition.Equals"/>
+ <condition property="mycondition.set">
+ <mycondition arg1="string" arg2="string"/>
+ </condition>
+ <fail unless="mycondition.set"/>
+ </target>
+
+ <target name="addfilter">
+ <typedef name="headfilter2"
+ classname="org.apache.tools.ant.filters.HeadFilter"/>
+ <concat>This is line 1
+ This is line 2
+ This is line 3
+ <filterchain>
+ <headfilter2 lines="2"/>
+ </filterchain>
+ </concat>
+ </target>
+
+ <target name="addselector">
+ <typedef
+ name="myselector"
+ classname="org.apache.tools.ant.types.selectors.ContainsSelector"/>
+ <fileset id="myselector.test" dir="${basedir}" includes="*">
+ <myselector text="myselector"/>
+ </fileset>
+ </target>
+
+ <target name="init">
+ <property name="nested.package" value="org.apache.tools.ant.types."/>
+ <path id="test-classes">
+ <pathelement location="../../../../build/testcases" />
+ <pathelement path="${java.class.path}" />
+ </path>
+ <typedef loaderref="nested.loader" classpathref="test-classes"
+ name = "nested.a"
+ classname="${nested.package}AddTypeTest$AImpl"/>
+ <typedef loaderref="nested.loader"
+ name = "nested.b"
+ classname="${nested.package}AddTypeTest$BImpl"/>
+ <typedef loaderref="nested.loader"
+ name = "nested.c"
+ classname="${nested.package}AddTypeTest$CImpl"/>
+ <typedef loaderref="nested.loader"
+ name = "nested.ab"
+ classname="${nested.package}AddTypeTest$ABImpl"/>
+ <taskdef loaderref="nested.loader"
+ name = "nested.container"
+ classname="${nested.package}AddTypeTest$NestedContainer"/>
+ <taskdef loaderref="nested.loader"
+ name = "nested.condition.task"
+ classname="${nested.package}AddTypeTest$MyCondition"/>
+ <typedef loaderref="nested.loader"
+ name = "nested.condition.type"
+ classname="${nested.package}AddTypeTest$MyCondition"/>
+ <typedef loaderref="nested.loader"
+ name = "myaddconfigured"
+ classname="${nested.package}AddTypeTest$MyAddConfigured"/>
+ <typedef loaderref="nested.loader"
+ name = "myaddconfiguredvalue"
+ classname="${nested.package}AddTypeTest$MyAddConfiguredValue"/>
+ <typedef loaderref="nested.loader"
+ name = "myvalue"
+ classname="${nested.package}AddTypeTest$MyValue"/>
+ </target>
+
+ <target name="nested.a" depends="init">
+ <nested.container>
+ <nested.a/>
+ </nested.container>
+ </target>
+
+ <target name="nested.b" depends="init">
+ <nested.container>
+ <nested.b/>
+ </nested.container>
+ </target>
+
+ <target name="nested.c" depends="init">
+ <nested.container>
+ <nested.c/>
+ </nested.container>
+ </target>
+
+ <target name="nested.ab" depends="init">
+ <nested.container>
+ <nested.ab/>
+ </nested.container>
+ </target>
+
+ <!-- tests for task adaptor -->
+ <target name="condition.type" depends="init">
+ <echo>before</echo>
+ <nested.condition.type/>
+ <echo>after</echo>
+ </target>
+
+ <target name="condition.task" depends="init">
+ <echo>before</echo>
+ <nested.condition.task/>
+ <echo>after</echo>
+ </target>
+
+ <target name="condition.condition.type" depends="init">
+ <condition property="condition.condition.type">
+ <nested.condition.type/>
+ </condition>
+ </target>
+
+ <target name="condition.condition.task" depends="init">
+ <condition property="condition.condition.task">
+ <nested.condition.task/>
+ </condition>
+ </target>
+
+ <target name="myaddconfigured" depends="init">
+ <myaddconfigured>
+ <myvalue>Value Set</myvalue>
+ </myaddconfigured>
+ </target>
+
+ <target name="myaddconfiguredvalue" depends="init">
+ <myaddconfiguredvalue>
+ <value>Value Set</value>
+ </myaddconfiguredvalue>
+ </target>
+
+ <target name="namespacetest" xmlns:prefix="uri">
+ <typedef name="eq" uri="uri"
+ classname="org.apache.tools.ant.taskdefs.condition.Equals"/>
+ <condition property="p">
+ <prefix:eq arg1="a" arg2="b"/>
+ </condition>
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/assertions.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/assertions.xml
new file mode 100644
index 00000000..dee7ce7c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/assertions.xml
@@ -0,0 +1,205 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<project name="assertions" basedir="." default="tearDown">
+
+ <import file="../buildfiletest-base.xml"/>
+
+ <target name="setUp">
+ <available property="jdk1.6+" classname="java.net.CookieStore"/>
+ <condition property="source" value="6">
+ <isset property="jdk1.6+"/>
+ </condition>
+ <property name="source" value="1.4"/>
+ <mkdir dir="${output}"/>
+ <javac srcdir="${src.dir}"
+ includes="*.java"
+ source="${source}"
+ debug="true"
+ destdir="${output}"
+ />
+ </target>
+
+ <property name="src.dir" location="assertions"/>
+ <property name="classname" value="AssertionMain"/>
+ <property name="test.classname" value="AssertionTest"/>
+
+ <path id="assert.classpath">
+ <pathelement location="${output}"/>
+ </path>
+
+
+ <!-- if per-class assertions work, this run asserts -->
+ <target name="test-classname" depends="setUp">
+ <java fork="true" failonerror="true"
+ classname="${classname}"
+ classpathref="assert.classpath">
+ <assertions enablesystemassertions="true">
+ <enable class="${classname}" />
+ </assertions>
+ </java>
+ </target>
+
+ <!-- if package works, this run asserts -->
+ <target name="test-package" depends="setUp">
+ <java fork="true" failonerror="true"
+ classname="${classname}"
+ classpathref="assert.classpath">
+ <assertions enableSystemAssertions="false" >
+ <enable package="..." />
+ </assertions>
+ </java>
+ </target>
+
+ <!-- this test should run the app successfully -->
+ <target name="test-empty-assertions" depends="setUp">
+ <java fork="true" failonerror="true"
+ classname="${classname}"
+ classpathref="assert.classpath">
+ <assertions/>
+ </java>
+ </target>
+
+ <!-- this test should run the app successfully -->
+ <target name="test-disable" depends="setUp">
+ <java fork="true" failonerror="true"
+ classname="${classname}"
+ classpathref="assert.classpath">
+ <assertions enableSystemAssertions="false" >
+ <enable package="..." />
+ <disable class="${classname}" />
+ </assertions>
+ </java>
+ </target>
+
+ <!-- repeated settigns result in the last declaration winning
+ except that the rule 'classes win over packages takes priority
+ this run will assert -->
+ <target name="test-override" depends="setUp">
+ <java fork="true" failonerror="true"
+ classname="${classname}"
+ classpathref="assert.classpath">
+ <assertions enableSystemAssertions="false" >
+ <enable package="..." />
+ <disable class="${classname}" />
+ <enable class="${classname}" />
+ <disable package="..." />
+ </assertions>
+ </java>
+ </target>
+
+ <!-- repeated settigns result in the last declaration winning;
+ this run will not assert -->
+ <target name="test-override2" depends="setUp">
+ <java fork="true" failonerror="true"
+ classname="${classname}"
+ classpathref="assert.classpath">
+ <assertions enableSystemAssertions="false" >
+ <enable package="..." />
+ <enable class="${classname}" />
+ <disable class="${classname}" />
+ </assertions>
+ </java>
+ </target>
+
+ <!-- if references work, this run asserts -->
+ <target name="test-references">
+ <assertions id="project.assertions" >
+ <enable package="org.apache.test" />
+ <disable package="org.apache.log4j"/>
+ <enable package="..."/>
+ </assertions>
+ <java fork="true" failonerror="true"
+ classname="${classname}"
+ classpathref="assert.classpath">
+ <assertions refid="project.assertions"/>
+ </java>
+ </target>
+
+ <!-- when fork=false; we need to reject the construct -->
+ <target name="test-nofork" depends="setUp">
+ <java fork="false" failonerror="true"
+ classname="${classname}"
+ classpathref="assert.classpath">
+ <assertions enablesystemassertions="true">
+ <enable class="${classname}" />
+ </assertions>
+ </java>
+ </target>
+
+ <!-- this throws a build error -->
+ <target name="test-multiple-assertions" depends="setUp">
+ <java fork="true" failonerror="true"
+ classname="${classname}"
+ classpathref="assert.classpath">
+ <assertions enablesystemassertions="true">
+ <enable class="${classname}" />
+ </assertions>
+ <assertions/>
+ </java>
+ </target>
+
+ <!-- should throw a build exception -->
+ <target name="test-reference-abuse" depends="setUp">
+ <assertions id="project.assertions2" >
+ <enable package="org.apache.test" />
+ <disable package="org.apache.log4j"/>
+ <enable package="..."/>
+ </assertions>
+ <java fork="true" failonerror="true"
+ classname="${classname}"
+ classpathref="assert.classpath">
+ <assertions refid="project.assertions2">
+ <disable class="${classname}" />
+ </assertions>
+ </java>
+ </target>
+
+
+ <target name="test-junit" depends="setUp">
+ <junit fork="true"
+ haltonerror="true" haltonfailure="true"
+ >
+ <classpath>
+ <path refid="assert.classpath"/>
+ </classpath>
+ <formatter type="plain" usefile="false"/>
+ <assertions >
+ <enable class="${test.classname}" />
+ </assertions>
+ <test name="${test.classname}"/>
+ </junit>
+ </target>
+
+ <!-- This is here to show that setting it as a property works
+ so there is some defect in pass-on of assertions that
+ is causing the problem -->
+ <target name="test-junit-manual-setup" depends="setUp">
+ <junit fork="true"
+ haltonerror="true" haltonfailure="true"
+ >
+ <classpath>
+ <path refid="assert.classpath"/>
+ </classpath>
+ <formatter type="plain" usefile="false"/>
+ <test name="${test.classname}"/>
+ <jvmarg value="-ea:AssertionTest"/>
+ </junit>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/assertions/AssertionMain.java b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/assertions/AssertionMain.java
new file mode 100644
index 00000000..f4aa6906
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/assertions/AssertionMain.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+
+/**
+ * this is an assertion tester
+ * It has a main() entry
+ */
+public class AssertionMain {
+
+ public static void main(String args[]) {
+ assert true == false : "there exist no facts that are both true and false";
+ System.out.println("Assertions are disabled");
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/assertions/AssertionTest.java b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/assertions/AssertionTest.java
new file mode 100644
index 00000000..19ed2df1
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/assertions/AssertionTest.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+ import junit.framework.TestCase;
+
+/**
+ * this is an assertion tester for junit
+ */
+public class AssertionTest extends TestCase {
+
+ public AssertionTest(String name) {
+ super(name);
+ }
+
+ public void testAssertRaised() {
+ try {
+ assert true == false;
+ fail("expected an assertion");
+ } catch(AssertionError asserto) {
+ //if we got here, all was well
+ }
+ }
+
+
+ public void testAssertNotRaised() {
+ assert(2+2==4);
+ }
+
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/description1.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/description1.xml
new file mode 100644
index 00000000..86a2a165
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/description1.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="test" default="main" basedir=".">
+ <description>Test Project Description</description>
+ <target name="main">
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/description2.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/description2.xml
new file mode 100644
index 00000000..945bc20d
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/description2.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="test" default="main" basedir=".">
+ <description>Multi Line
+Project Description</description>
+ <target name="main">
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/description3.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/description3.xml
new file mode 100644
index 00000000..af5dda11
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/description3.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="test" default="main" basedir=".">
+ <description>Multi Instance </description>
+ <description>Project Description</description>
+ <target name="main">
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/description4.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/description4.xml
new file mode 100644
index 00000000..22df9c2d
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/description4.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="test" default="main" basedir=".">
+ <description>Multi Instance </description>
+ <target name="main">
+ <description>Nested Project Description</description>
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/filelist.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/filelist.xml
new file mode 100644
index 00000000..f854ddbb
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/filelist.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="test">
+ <target name="simple">
+ <filelist id="filelist"
+ dir="${basedir}"
+ files="a"/>
+ <pathconvert targetos="unix" refid="filelist"
+ property="property">
+ <map from="${basedir}" to="/abc"/>
+ </pathconvert>
+ <echo>${property}</echo>
+ </target>
+
+ <target name="double">
+ <filelist id="filelist"
+ dir="${basedir}"
+ files="a b"/>
+ <pathconvert targetos="unix" refid="filelist"
+ property="property">
+ <map from="${basedir}" to="/abc"/>
+ </pathconvert>
+ <echo>${property}</echo>
+ </target>
+
+ <target name="nested">
+ <filelist id="filelist"
+ dir="${basedir}">
+ <file name="a"/>
+ <file name="b"/>
+ </filelist>
+ <pathconvert targetos="unix" refid="filelist"
+ property="property">
+ <map from="${basedir}" to="/abc"/>
+ </pathconvert>
+ <echo>${property}</echo>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/filterset.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/filterset.xml
new file mode 100644
index 00000000..bf291e7d
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/filterset.xml
@@ -0,0 +1,146 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="test" default="new" basedir=".">
+ <filterset id="testset.one">
+ <filter token="aaaa" value="1111"/>
+ <filter token="bbbb" value="2222"/>
+ </filterset>
+
+ <filterset id="testset.two" beginToken="%" endToken="^">
+ <filter token="cccc" value="3333"/>
+ <filter token="dddd" value="4444"/>
+ </filterset>
+
+ <target name="test1">
+ <delete file="dest1.txt"/>
+ <copy file="filterseta.txt" tofile="dest1.txt">
+ <filterset refid="testset.one"/>
+ </copy>
+ </target>
+
+ <target name="test2">
+ <delete file="dest2.txt"/>
+ <copy file="filtersetb.txt" tofile="dest2.txt">
+ <filterset refid="testset.two"/>
+ </copy>
+ </target>
+
+ <target name="test3">
+ <delete file="dest3.txt"/>
+ <copy file="filtersetc.txt" tofile="dest3.txt">
+ <filterset refid="testset.one"/>
+ <filterset refid="testset.two"/>
+ </copy>
+ </target>
+
+ <target name="test-nested-filtersets">
+ <filterset id="1">
+ <filter token="token1" value="value1"/>
+ </filterset>
+ <filterset id="2">
+ <filterset refid="testset.one"/>
+ </filterset>
+ <filterset id="3">
+ <filterset id="4">
+ <filter token="token4" value="value4"/>
+ </filterset>
+ </filterset>
+ <filterset id="5">
+ <filterset refid="1"/>
+ </filterset>
+ </target>
+
+ <target name="testFiltersFileElement">
+ <copy file="filtersetd.txt" tofile="dest4.txt">
+ <filterset>
+ <filtersfile file="filtersfile1" />
+ </filterset>
+ </copy>
+ <fail>
+ <condition>
+ <not>
+ <resourcesmatch asText="true">
+ <file file="dest4.txt" />
+ <string value="FOO BAR @baz@ @blah@" />
+ </resourcesmatch>
+ </not>
+ </condition>
+ </fail>
+ </target>
+
+ <target name="testFiltersFileAttribute">
+ <copy file="filtersetd.txt" tofile="dest5.txt">
+ <filterset filtersfile="filtersfile1" />
+ </copy>
+ <fail>
+ <condition>
+ <not>
+ <resourcesmatch asText="true">
+ <file file="dest5.txt" />
+ <string value="FOO BAR @baz@ @blah@" />
+ </resourcesmatch>
+ </not>
+ </condition>
+ </fail>
+ </target>
+
+ <target name="testMultipleFiltersFiles">
+ <copy file="filtersetd.txt" tofile="dest6.txt">
+ <filterset filtersfile="filtersfile1">
+ <filtersfile file="filtersfile2" />
+ </filterset>
+ </copy>
+ <fail>
+ <condition>
+ <not>
+ <resourcesmatch asText="true">
+ <file file="dest6.txt" />
+ <string value="FOO BAR BAZ @blah@" />
+ </resourcesmatch>
+ </not>
+ </condition>
+ </fail>
+ </target>
+
+ <target name="testMissingFiltersFile">
+ <copy file="filtersetd.txt" tofile="dest7.txt">
+ <filterset filtersfile="nonexistentfiltersfile" />
+ </copy>
+ </target>
+
+ <target name="testAllowMissingFiltersFile">
+ <copy file="filtersetd.txt" tofile="dest8.txt">
+ <filterset filtersfile="nonexistentfiltersfile"
+ onmissingfiltersfile="ignore" />
+ </copy>
+ <fail>
+ <condition>
+ <not>
+ <filesmatch file1="filtersetd.txt" file2="dest8.txt" />
+ </not>
+ </condition>
+ </fail>
+ </target>
+
+ <target name="cleanup">
+ <delete quiet="true">
+ <fileset dir="." includes="dest?.txt" />
+ </delete>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/filterseta.txt b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/filterseta.txt
new file mode 100644
index 00000000..44049950
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/filterseta.txt
@@ -0,0 +1,2 @@
+This is a test file for filters @aaaa@
+It has two lines @bbbb@
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/filtersetb.txt b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/filtersetb.txt
new file mode 100644
index 00000000..f49640a3
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/filtersetb.txt
@@ -0,0 +1,5 @@
+This is a test file for filters with non default markers
+@cccc@ - should not change
+%cccc^ - should change
+^dddd% - should not change
+%dddd^ - should change
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/filtersetc.txt b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/filtersetc.txt
new file mode 100644
index 00000000..2522d350
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/filtersetc.txt
@@ -0,0 +1,7 @@
+Combined filter test
+@aaaa@ - should change
+@bbbb@ - should change
+@cccc@ - should not change
+%cccc^ - should change
+^dddd% - should not change
+%dddd^ - should change
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/filtersetd.txt b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/filtersetd.txt
new file mode 100644
index 00000000..45c4849e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/filtersetd.txt
@@ -0,0 +1 @@
+@foo@ @bar@ @baz@ @blah@
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/filtersfile1 b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/filtersfile1
new file mode 100644
index 00000000..20fe058f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/filtersfile1
@@ -0,0 +1,2 @@
+foo=FOO
+bar=BAR
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/filtersfile2 b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/filtersfile2
new file mode 100644
index 00000000..43c97f27
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/filtersfile2
@@ -0,0 +1 @@
+baz=BAZ
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/flexinteger.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/flexinteger.xml
new file mode 100644
index 00000000..aa10aa07
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/flexinteger.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="test" default="test" basedir=".">
+
+ <path id="testclasses">
+ <pathelement location="../../../../build/testcases" />
+ <pathelement path="${java.class.path}" />
+ </path>
+
+ <target name="test">
+ <taskdef name="flexint"
+ classname="org.apache.tools.ant.types.FlexIntegerTest"
+ classpathref="testclasses"
+ />
+
+ <flexint propname="flexint.value1" value="0xA"/>
+ <flexint propname="flexint.value2" value="010"/>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/gold/filterset1.txt b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/gold/filterset1.txt
new file mode 100644
index 00000000..975416f5
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/gold/filterset1.txt
@@ -0,0 +1,2 @@
+This is a test file for filters 1111
+It has two lines 2222
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/gold/filterset2.txt b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/gold/filterset2.txt
new file mode 100644
index 00000000..eaab0215
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/gold/filterset2.txt
@@ -0,0 +1,5 @@
+This is a test file for filters with non default markers
+@cccc@ - should not change
+3333 - should change
+^dddd% - should not change
+4444 - should change
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/gold/filterset3.txt b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/gold/filterset3.txt
new file mode 100644
index 00000000..3516e62b
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/gold/filterset3.txt
@@ -0,0 +1,7 @@
+Combined filter test
+1111 - should change
+2222 - should change
+@cccc@ - should not change
+3333 - should change
+^dddd% - should not change
+4444 - should change
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/mapper.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/mapper.xml
new file mode 100644
index 00000000..a96f10cb
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/mapper.xml
@@ -0,0 +1,67 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<project name="copy-test" basedir="." default="test1">
+
+ <import file="../buildfiletest-base.xml"/>
+
+ <target name="setUp">
+ <mkdir dir="${output}" />
+ </target>
+
+ <target name="test1" depends="setUp">
+ <union id="source.resourcecollection">
+ <fileset dir="../../../main">
+ <include name="**/taskdefs/*.java" />
+ </fileset>
+ <fileset dir="../../../tests/junit">
+ <include name="**/taskdefs/*.java" />
+ </fileset>
+ </union>
+ <copy todir="${output}">
+ <union refid="source.resourcecollection"/>
+ <mapper type="flatten" />
+ </copy>
+ <resourcecount property="sourcefiles.count">
+ <union refid="source.resourcecollection"/>
+ </resourcecount>
+ <resourcecount property="destfiles.count">
+ <fileset dir="${output}"/>
+ </resourcecount>
+ <resourcecount property="destdirs.count">
+ <dirset dir="${output}"/>
+ </resourcecount>
+ <fail message="different number of files in source and destination ${sourcefiles.count} ${destfiles.count}">
+ <condition>
+ <not>
+ <equals arg1="${sourcefiles.count}" arg2="${destfiles.count}"/>
+ </not>
+ </condition>
+ </fail>
+ <!-- one expects the output of resourcecount on a dirset which does not contain subdirectories to be 1 -->
+ <!-- it looks like the folder of the dirset itself is counted -->
+ <fail message="flatten mapper should not copy folders">
+ <condition>
+ <not>
+ <equals arg1="${destdirs.count}" arg2="1"/>
+ </not>
+ </condition>
+ </fail>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/mappers/define.mapperresult.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/mappers/define.mapperresult.xml
new file mode 100644
index 00000000..d9152a1c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/mappers/define.mapperresult.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project>
+ <typedef name="mapperresult"
+ classpath="../../../../../build/testcases"
+ classname="org.apache.tools.ant.types.mappers.MapperResult"/>
+
+ <!-- this is what you get with no result -->
+ <property name="no-results" value="&lt;NULL&gt;" />
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/mappers/globmapper.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/mappers/globmapper.xml
new file mode 100644
index 00000000..1666d810
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/mappers/globmapper.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project>
+ <import file="define.mapperresult.xml"/>
+
+ <target name="handle.dirsep">
+ <mapperresult input="d\e/f/j.java" output="f/j.java">
+ <globmapper from="d/e\*" to="*" handledirsep="yes"/>
+ </mapperresult>
+ </target>
+
+ <target name="ignore.case">
+ <mapperresult input="AbcDef.JaVa" output="bcDef.java.bak">
+ <globmapper from="a*.java" to="*.java.bak" casesensitive="no"/>
+ </mapperresult>
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/mappers/regexpmapper.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/mappers/regexpmapper.xml
new file mode 100644
index 00000000..a85c49cf
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/mappers/regexpmapper.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project>
+ <import file="define.mapperresult.xml"/>
+
+ <target name="ignore.case">
+ <mapperresult input="AbcDef.javA" output="bcDef.java.bak">
+ <regexpmapper from="a(.*).JaVa" to="\1.java.bak" casesensitive="no"/>
+ </mapperresult>
+ </target>
+
+ <target name="handle.dirsep">
+ <mapperresult input="d\e/f\j.java" output="f/j.java">
+ <regexpmapper from="d/e/(.*)" to="\1" handledirsep="yes"/>
+ </mapperresult>
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/mappers/scriptmapper.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/mappers/scriptmapper.xml
new file mode 100644
index 00000000..d3e7a8d0
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/mappers/scriptmapper.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="scriptmapper">
+ <import file="define.mapperresult.xml"/>
+
+
+ <target name="testSetSingle">
+ <mapperresult input="" output="a">
+ <scriptmapper language="javascript">
+ self.addMappedName("a");
+ </scriptmapper>
+ </mapperresult>
+ </target>
+
+ <target name="testClear">
+ <mapperresult input="" output="${no-results}">
+ <scriptmapper language="javascript">
+ self.addMappedName("a");
+ self.clear();
+ </scriptmapper>
+ </mapperresult>
+ </target>
+
+ <target name="testSetMultiple">
+ <mapperresult input="" output="a|b">
+ <scriptmapper language="javascript">
+ self.addMappedName("a");
+ self.addMappedName("b");
+ </scriptmapper>
+ </mapperresult>
+ </target>
+
+ <target name="testPassthrough">
+ <mapperresult input="a" output="A|a">
+ <scriptmapper language="javascript">
+ //relying on "a" to map to "A" on all locales.
+ self.addMappedName(source.toUpperCase());
+ self.addMappedName(source.toLowerCase());
+ </scriptmapper>
+ </mapperresult>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/poly.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/poly.xml
new file mode 100644
index 00000000..cabf9ece
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/poly.xml
@@ -0,0 +1,62 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="test" basedir=".">
+
+ <property name="c" value="org.apache.tools.ant.types.PolyTest"/>
+
+ <path id="test-c">
+ <pathelement location="../../../../build/testcases" />
+ <pathelement path="${java.class.path}" />
+ </path>
+
+ <target name="init">
+ <typedef loaderref="poly" classpathref="test-c"
+ name = "myfileset" classname="${c}$MyFileSet"/>
+
+ <typedef loaderref="poly" classpathref="test-c"
+ name = "mypath" classname="${c}$MyPath"/>
+
+ <typedef loaderref="poly" classpathref="test-c"
+ name = "mytask" classname="${c}$MyTask"/>
+ </target>
+
+ <target name="fileset" depends="init">
+ <mytask>
+ <fileset dir="."/>
+ </mytask>
+ </target>
+
+ <target name="fileset-ant-type" depends="init">
+ <mytask>
+ <fileset ant-type="myfileset" dir="."/>
+ </mytask>
+ </target>
+
+ <target name="path" depends="init">
+ <mytask>
+ <path path="."/>
+ </mytask>
+ </target>
+
+ <target name="path-ant-type" depends="init">
+ <mytask>
+ <path ant-type="mypath" path="."/>
+ </mytask>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/quote1.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/quote1.xml
new file mode 100644
index 00000000..8e77122c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/quote1.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+ <!-- I belong to:
+ org.apache.tools.ant.types.XMLCatalogBuildFileTest.java
+ -->
+
+<para>
+ A stitch in time saves nine
+</para>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/quote2.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/quote2.xml
new file mode 100644
index 00000000..ef9a3c3e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/quote2.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+ <!-- I belong to:
+ org.apache.tools.ant.types.XMLCatalogBuildFileTest.java
+ -->
+
+<para>
+ No news is good news
+</para>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/redirector.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/redirector.xml
new file mode 100644
index 00000000..4784e9f0
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/redirector.xml
@@ -0,0 +1,79 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="redirector" basedir=".">
+
+ <target name="test1" description="create ref">
+ <redirector id="test1" output="out" />
+ </target>
+
+ <target name="test2" depends="test1" description="fail">
+ <redirector refid="test1" output="out" />
+ </target>
+
+ <target name="test3" depends="test1" description="fail">
+ <redirector refid="test1">
+ <outputmapper type="flatten" />
+ </redirector>
+ </target>
+
+ <target name="test4" depends="test1" description="pass">
+ <redirector>
+ <outputmapper type="flatten" />
+ </redirector>
+ </target>
+
+ <target name="testLogInputString" depends="cat-check" if="can-cat">
+ <echo>
+ testLogInputString can-cat
+ </echo>
+ <exec executable="cat">
+ <redirector inputstring="foo" loginputstring="false" />
+ </exec>
+ </target>
+
+ <target name="testRefid" depends="cat-check" if="can-cat">
+ <fail message="Property testRefid.out is already set!">
+ <condition>
+ <isset property="testRefid.out" />
+ </condition>
+ </fail>
+ <redirector id="r" outputproperty="testRefid.out" inputstring="foo" />
+ <exec executable="cat">
+ <redirector refid="r" />
+ </exec>
+ <fail>
+ <condition>
+ <not>
+ <equals arg1="${testRefid.out}" arg2="foo" />
+ </not>
+ </condition>
+ </fail>
+ </target>
+
+ <target name="cat-check">
+ <property environment="env" />
+ <condition property="can-cat">
+ <or>
+ <available file="cat" filepath="${env.PATH}" property="can-cat" />
+ <available file="cat.exe" filepath="${env.PATH}" property="can-cat" />
+ <available file="cat.exe" filepath="${env.Path}" property="can-cat" />
+ </or>
+ </condition>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/resources/javaresource.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/resources/javaresource.xml
new file mode 100644
index 00000000..83267623
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/resources/javaresource.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project>
+ <target name="loadManifest">
+ <loadresource property="manifest">
+ <javaresource name="META-INF/MANIFEST.MF"/>
+ </loadresource>
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/resources/resourcelist.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/resources/resourcelist.xml
new file mode 100644
index 00000000..f1ac6df7
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/resources/resourcelist.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project>
+
+ <target name="tearDown">
+ </target>
+
+ <target name="setUp">
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/resources/tarentry.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/resources/tarentry.xml
new file mode 100644
index 00000000..c0fa379c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/resources/tarentry.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="not me">
+ <import file="../../buildfiletest-base.xml" optional="false"/>
+
+ <target name="setUp">
+ <mkdir dir="${output}"/>
+ </target>
+
+ <target name="not me">
+ <fail>only use from within unit tests</fail>
+ </target>
+
+ <target name="uncompressSource" depends="setUp">
+ <ant antfile="../../taskdefs/tar.xml" target="feather" />
+ <copy todir="${output}">
+ <tarentry name="asf-logo.gif">
+ <gzipresource>
+ <file file="../../taskdefs/expected/asf-logo.gif.tar.gz"/>
+ </gzipresource>
+ </tarentry>
+ </copy>
+ </target>
+
+</project> \ No newline at end of file
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/selectors.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/selectors.xml
new file mode 100644
index 00000000..5a80d04a
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/selectors.xml
@@ -0,0 +1,356 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<project name="selectors-test" basedir="." default="setupfiles">
+
+ <import file="../buildfiletest-base.xml"/>
+
+ <target name="setUp">
+ <mkdir dir="${output}"/>
+ </target>
+ <property name="etc.dir" value=".."/>
+ <property name="test.dir"
+ value="${output}/selectortest"/>
+ <property name="testregexpsrc.dir"
+ value="${output}/regexpseltestsrc"/>
+ <property name="testregexpdest.dir"
+ value="${output}/regexpseltestdest"/>
+ <property name="mirror.dir"
+ value="${output}/selectortest2"/>
+
+ <target name="setupfiles">
+ <mkdir dir="${test.dir}" />
+ <mkdir dir="${test.dir}/zip" />
+ <mkdir dir="${test.dir}/tar" />
+ <mkdir dir="${test.dir}/tar/gz" />
+ <mkdir dir="${test.dir}/tar/bz2" />
+ <copy file="${etc.dir}/taskdefs/expected/asf-logo.gif.md5"
+ tofile="${test.dir}/asf-logo.gif.md5" />
+ <copy file="${etc.dir}/taskdefs/expected/asf-logo.gif.bz2"
+ tofile="${test.dir}/asf-logo.gif.bz2" />
+ <copy file="${etc.dir}/taskdefs/expected/asf-logo.gif.gz"
+ tofile="${test.dir}/asf-logo.gif.gz" />
+ <copy file="${etc.dir}/taskdefs/expected/copy.filterset.filtered"
+ tofile="${test.dir}/copy.filterset.filtered" />
+ <copy file="${etc.dir}/taskdefs/expected/asf-logo.gif.zip"
+ tofile="${test.dir}/zip/asf-logo.gif.zip" />
+ <copy file="${etc.dir}/taskdefs/expected/asf-logo.gif.tar"
+ tofile="${test.dir}/tar/asf-logo.gif.tar" />
+ <copy file="${etc.dir}/taskdefs/expected/asf-logo-huge.tar.gz"
+ tofile="${test.dir}/tar/asf-logo-huge.tar.gz" />
+ <copy file="${etc.dir}/taskdefs/expected/asf-logo.gif.tar.gz"
+ tofile="${test.dir}/tar/gz/asf-logo.gif.tar.gz" />
+ <copy file="${etc.dir}/taskdefs/expected/asf-logo.gif.tar.bz2"
+ tofile="${test.dir}/tar/bz2/asf-logo.gif.tar.bz2" />
+ <copy file="${etc.dir}/taskdefs/expected/asf-logo-huge.tar.bz2"
+ tofile="${test.dir}/tar/bz2/asf-logo-huge.tar.bz2" />
+ <!-- Make linefeeds consistent between platforms -->
+ <fixcrlf srcdir="${test.dir}" includes="*.filtered" eol="lf"/>
+ <!-- Set a known base time for all files -->
+ <touch datetime="11/21/2001 4:55 AM">
+ <fileset dir="${test.dir}">
+ <include name="**/*"/>
+ </fileset>
+ </touch>
+ <!-- Then adjust individual ones -->
+ <touch file="${test.dir}/asf-logo.gif.bz2"
+ datetime="01/01/2001 12:00 AM"/>
+ <touch file="${test.dir}/asf-logo.gif.gz"
+ datetime="04/15/2002 2:30 PM"/>
+ <touch file="${test.dir}/zip/asf-logo.gif.zip"
+ datetime="05/10/2002 2:30 PM"/>
+ <touch file="${test.dir}/tar/asf-logo.gif.tar"
+ datetime="05/10/2002 2:29 PM"/>
+ <touch file="${test.dir}/tar/asf-logo-huge.tar.gz"
+ datetime="05/10/2002 2:29 AM"/>
+ </target>
+
+ <target name="mirrorfiles">
+ <mkdir dir="${mirror.dir}" />
+ <mkdir dir="${mirror.dir}/zip" />
+ <mkdir dir="${mirror.dir}/tar" />
+ <mkdir dir="${mirror.dir}/tar/gz" />
+ <mkdir dir="${mirror.dir}/tar/bz2" />
+ <touch file="${mirror.dir}/asf-logo.gif.md5"/>
+ <touch file="${mirror.dir}/asf-logo.gif.bz2"/>
+ <touch file="${mirror.dir}/zip/asf-logo.gif.zip"/>
+ <touch file="${mirror.dir}/tar/asf-logo.gif.tar"/>
+ <touch file="${mirror.dir}/tar/asf-logo-huge.tar.gz"/>
+ <touch file="${mirror.dir}/tar/gz/asf-logo.gif.tar.gz"/>
+ <touch file="${mirror.dir}/tar/bz2/asf-logo.gif.tar.bz2"/>
+ <touch file="${mirror.dir}/tar/bz2/asf-logo-huge.tar.bz2"/>
+ </target>
+
+ <target name="containsregexp">
+ <mkdir dir="${testregexpsrc.dir}" />
+ <mkdir dir="${testregexpdest.dir}" />
+ <!-- Make two test files, shouldcopy.txt will get selected if everything works
+ shouldnotcopy.txt will not get selected for copy. The test looks to see
+ that only one file is copied
+ -->
+ <echo message="Some testregexp text 2.0" file="${testregexpsrc.dir}/shouldcopy.txt" />
+ <echo message="Some testregexp text 20" file="${testregexpsrc.dir}/shouldnotcopy.txt" />
+ <copy todir="${testregexpdest.dir}">
+ <fileset dir="${testregexpsrc.dir}">
+ <include name="*.txt" />
+ <containsregexp expression="[0-9]\.[0,1,2]" />
+ </fileset>
+ </copy>
+ </target>
+
+ <!-- ========== Test for ModifiedSelector ========== -->
+
+ <target name="modifiedselectortest-makeDirty">
+ <!-- Load propertyfile generated by SelectorTest-class -->
+ <property file="ModifiedSelectorTest.properties"/>
+
+ <!-- Modify only timestamp -->
+ <touch file="${test.dir}/${f2name}" datetime="02/28/2003 9:55 AM"/>
+ <!-- Change content but keep timestamp -->
+ <echo file="${test.dir}/${f3name}" append="true" message="new content"/>
+ <touch file="${test.dir}/${f3name}" datetime="11/21/2001 4:55 AM"/>
+ <!-- Change content and timestamp -->
+ <echo file="${test.dir}/${f4name}" append="true" message="new content"/>
+ </target>
+
+ <target name="modifiedselectortest-scenario-clean">
+ <delete dir="${test.dir}"/>
+ </target>
+
+ <target name="modifiedselectortest-scenario-prepare">
+ <mkdir dir="${test.dir}/src"/>
+ <copy todir="${test.dir}/src">
+ <fileset dir="${ant.home}/lib" includes="ant.jar">
+ <type type="file"/>
+ </fileset>
+ <fileset dir="${ant.home}/bin">
+ <type type="file"/>
+ </fileset>
+ </copy>
+ <touch datetime="12/24/2002 4:00 pm">
+ <fileset dir="${test.dir}"/>
+ </touch>
+ <mkdir dir="${test.dir}/to-1"/>
+ <mkdir dir="${test.dir}/to-2"/>
+ <mkdir dir="${test.dir}/to-3"/>
+ </target>
+
+ <target name="modifiedselectortest-scenario-makeDirty">
+ <touch file="${test.dir}/src/ant.jar"/>
+ <echo file="${test.dir}/src/ant.bat" append="true" message="new-content"/>
+ <echo file="${test.dir}/src/antRun.pl" append="true" message="new-content"/>
+ <touch file="${test.dir}/src/antRun.pl" datetime="12/24/2002 4:00 pm"/>
+ </target>
+
+ <target name="modifiedselectortest-scenario-coreselector-defaults" depends="modifiedselectortest-scenario-prepare">
+ <!-- copy first time and create cachefile -->
+ <copy todir="${test.dir}/to-1">
+ <fileset dir="${test.dir}/src">
+ <modified/>
+ </fileset>
+ </copy>
+ <!-- copy second time: nothing should be copied -->
+ <copy todir="${test.dir}/to-2">
+ <fileset dir="${test.dir}/src">
+ <modified/>
+ </fileset>
+ </copy>
+ <!-- 'modify' the source files -->
+ <antcall target="modifiedselectortest-scenario-makeDirty"/>
+ <!-- copy third time: only the files with new CONTENT should be copied -->
+ <copy todir="${test.dir}/to-3">
+ <fileset dir="${test.dir}/src">
+ <modified/>
+ </fileset>
+ </copy>
+ </target>
+
+ <target name="modifiedselectortest-scenario-coreselector-settings" depends="modifiedselectortest-scenario-prepare">
+ <!-- copy first time and create cachefile -->
+ <copy todir="${test.dir}/to-1">
+ <fileset dir="${test.dir}/src">
+ <modified cache="propertyfile" algorithm="hashvalue" update="true">
+ <param name="cache.cachefile" value="core.cache.properties" />
+ </modified>
+ </fileset>
+ </copy>
+ <!-- copy second time: nothing should be copied -->
+ <copy todir="${test.dir}/to-2">
+ <fileset dir="${test.dir}/src">
+ <modified cache="propertyfile" algorithm="hashvalue" update="true">
+ <param name="cache.cachefile" value="core.cache.properties" />
+ </modified>
+ </fileset>
+ </copy>
+ <!-- 'modify' the source files -->
+ <antcall target="modifiedselectortest-scenario-makeDirty"/>
+ <!-- copy third time: only the files with new CONTENT should be copied -->
+ <copy todir="${test.dir}/to-3">
+ <fileset dir="${test.dir}/src">
+ <modified cache="propertyfile" algorithm="hashvalue" update="true">
+ <param name="cache.cachefile" value="core.cache.properties" />
+ </modified>
+ </fileset>
+ </copy>
+ </target>
+
+ <target name="modifiedselectortest-scenario-customselector-settings" depends="modifiedselectortest-scenario-prepare">
+ <!-- copy first time and create cachefile -->
+ <copy todir="${test.dir}/to-1">
+ <fileset dir="${test.dir}/src">
+ <custom classname="org.apache.tools.ant.types.selectors.modifiedselector.ModifiedSelector">
+ <param name="cache" value="propertyfile"/>
+ <param name="algorithm" value="hashvalue"/>
+ <param name="update" value="true"/>
+ <param name="cache.cachefile" value="core.cache.properties"/>
+ </custom>
+ </fileset>
+ </copy>
+ <!-- copy second time: nothing should be copied -->
+ <copy todir="${test.dir}/to-2">
+ <fileset dir="${test.dir}/src">
+ <custom classname="org.apache.tools.ant.types.selectors.modifiedselector.ModifiedSelector">
+ <param name="cache" value="propertyfile"/>
+ <param name="algorithm" value="hashvalue"/>
+ <param name="update" value="true"/>
+ <param name="cache.cachefile" value="core.cache.properties"/>
+ </custom>
+ </fileset>
+ </copy>
+ <!-- 'modify' the source files -->
+ <antcall target="modifiedselectortest-scenario-makeDirty"/>
+ <!-- copy third time: only the files with new CONTENT should be copied -->
+ <copy todir="${test.dir}/to-3">
+ <fileset dir="${test.dir}/src">
+ <custom classname="org.apache.tools.ant.types.selectors.modifiedselector.ModifiedSelector">
+ <param name="cache" value="propertyfile"/>
+ <param name="algorithm" value="hashvalue"/>
+ <param name="update" value="true"/>
+ <param name="cache.cachefile" value="core.cache.properties"/>
+ </custom>
+ </fileset>
+ </copy>
+ </target>
+
+ <target name="modifiedselectortest-customClasses" depends="modifiedselectortest-scenario-prepare">
+ <property name="pkg.live" value="org.apache.tools.ant.types.selectors.modifiedselector"/>
+ <property name="pkg.test" value="org.apache.tools.ant.types.selectors"/>
+ <fileset id="fs.mod" dir="${test.dir}/src">
+ <modified
+ algorithmclass="${pkg.test}.MockAlgorithm"
+ cacheclass="${pkg.test}.MockCache"
+ comparatorclass="${pkg.test}.MockComparator"
+ >
+ <classpath>
+ <pathelement location="${build.tests.value}"/>
+ </classpath>
+ </modified>
+ </fileset>
+ <fileset id="fs.full" dir="${test.dir}/src"/>
+ <property name="fs.mod.value" refid="fs.mod"/>
+ <property name="fs.full.value" refid="fs.full"/>
+ </target>
+
+ <target name="modifiedselectortest-ResourceSimple">
+ <fail message="Didnt get the required numbers of Resources.">
+ <condition>
+ <not>
+ <resourcecount when="equal" count="3">
+ <restrict>
+ <resources>
+ <file file="foo" />
+ <resource name="foo" />
+ <file file="foo" basedir="${basedir}" />
+ </resources>
+ <modified selres="true" xmlns="antlib:org.apache.tools.ant.types.resources.selectors"/>
+ </restrict>
+ </resourcecount>
+ </not>
+ </condition>
+ </fail>
+ </target>
+
+ <target name="modifiedselectortest-ResourceSelresTrue">
+ <fail message="Got the Resource, but should.">
+ <condition>
+ <not>
+ <resourcecount when="equal" count="1">
+ <restrict>
+ <resources>
+ <resource name="notExisting" />
+ </resources>
+ <modified selres="true" xmlns="antlib:org.apache.tools.ant.types.resources.selectors"/>
+ </restrict>
+ </resourcecount>
+ </not>
+ </condition>
+ </fail>
+ </target>
+
+ <target name="modifiedselectortest-ResourceSelresFalse">
+ <fail message="Got the Resource, but should not.">
+ <condition>
+ <not>
+ <resourcecount when="equal" count="0">
+ <restrict>
+ <resources>
+ <resource name="notExisting" />
+ </resources>
+ <modified selres="false" xmlns="antlib:org.apache.tools.ant.types.resources.selectors"/>
+ </restrict>
+ </resourcecount>
+ </not>
+ </condition>
+ </fail>
+ </target>
+
+ <target name="modifiedselectortest-scenario-resourceSimple" depends="modifiedselectortest-scenario-prepare">
+ <macrodef name="check">
+ <attribute name="count"/>
+ <attribute name="message"/>
+ <sequential>
+ <fail message="@{message}">
+ <condition>
+ <not>
+ <resourcecount when="equal" count="@{count}">
+ <restrict>
+ <resources>
+ <fileset dir="${test.dir}/src"/>
+ </resources>
+ <modified selres="false" xmlns="antlib:org.apache.tools.ant.types.resources.selectors"/>
+ </restrict>
+ </resourcecount>
+ </not>
+ </condition>
+ </fail>
+ </sequential>
+ </macrodef>
+ <!-- select first time and create cachefile -->
+ <check count="14" message="Initial set of files not ok."/>
+
+ <!-- check second time: nothing should be selected -->
+ <check count="0" message="Selected files but shouldnt."/>
+
+ <!-- 'modify' the source files -->
+ <antcall target="modifiedselectortest-scenario-makeDirty"/>
+
+ <!-- copy third time: only the files with new CONTENT should be copied -->
+ <check count="2" message="Didnt select the 2 modified files."/>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/selectors/scriptselector.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/selectors/scriptselector.xml
new file mode 100644
index 00000000..80afe309
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/selectors/scriptselector.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="scriptselector" default="def" basedir=".">
+
+ <property name="src.file" location="${ant.file}" />
+
+ <macrodef name="testselected">
+ <element name="selector" implicit="yes" optional="true"/>
+ <attribute name="message"/>
+ <sequential>
+ <fail message="@{message} failed: file was not selected">
+ <condition>
+ <not>
+ <isfileselected file="{src.file}">
+ <selector/>
+ </isfileselected>
+ </not>
+ </condition>
+ </fail>
+ </sequential>
+ </macrodef>
+
+ <macrodef name="testnoselected">
+ <element name="selector" implicit="yes" optional="true"/>
+ <attribute name="message"/>
+ <sequential>
+ <fail message="@{message} failed: file was selected">
+ <condition>
+ <isfileselected file="{src.file}">
+ <selector/>
+ </isfileselected>
+ </condition>
+ </fail>
+ </sequential>
+ </macrodef>
+
+ <!-- this is here to test the macro is well coded -->
+ <target name="testNoSelector">
+ <testselected message="testNoSelector" >
+ </testselected>
+ </target>
+
+ <target name="testNolanguage">
+ <testselected message="testNolanguage" >
+ <selector>
+ <scriptselector >
+ self.setSelected(true);
+ </scriptselector>
+ </selector>
+ </testselected>
+ </target>
+
+ <target name="testSelectionSetByDefault">
+ <testselected message="testSelectionSetByDefault" >
+ <selector>
+ <scriptselector language="javascript">
+ </scriptselector>
+ </selector>
+ </testselected>
+ </target>
+
+
+ <target name="testSelectionSetWorks">
+ <testselected message="testSelectionSetWorks" >
+ <selector>
+ <scriptselector language="javascript">
+ self.setSelected(false);
+ self.setSelected(true);
+ </scriptselector>
+ </selector>
+ </testselected>
+ </target>
+
+ <target name="testSelectionClearWorks">
+ <testnoselected message="testSelectionClearWorks">
+ <selector>
+ <scriptselector language="javascript">
+ self.setSelected(false);
+ </scriptselector>
+ </selector>
+ </testnoselected>
+ </target>
+
+ <target name="testFileAttribute">
+ <testselected message="testFileAttribute" >
+ <selector>
+ <scriptselector language="javascript">
+ self.setSelected(file.equals(self.getFile()));
+ </scriptselector>
+ </selector>
+ </testselected>
+ </target>
+
+ <target name="testFilenameAttribute">
+ <testselected message="testFilenameAttribute" >
+ <selector>
+ <scriptselector language="javascript">
+ self.setSelected(filename.equals(self.getFilename()));
+ </scriptselector>
+ </selector>
+ </testselected>
+ </target>
+
+ <target name="testBasedirAttribute">
+ <testselected message="testBasedirAttribute" >
+ <selector>
+ <scriptselector language="javascript">
+ self.setSelected(basedir.equals(self.getBasedir()));
+ </scriptselector>
+ </selector>
+ </testselected>
+ </target>
+
+ <target name="notestFilenameLength">
+ <testselected message="notestFilenameLength" >
+ <selector>
+ <scriptselector language="javascript">
+ self.setSelected((filename.length%2)==0);
+ </scriptselector>
+ </selector>
+ </testselected>
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/selectors/signedselector.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/selectors/signedselector.xml
new file mode 100644
index 00000000..60fe9408
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/selectors/signedselector.xml
@@ -0,0 +1,61 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project>
+ <macrodef name="pass">
+ <element name="conditions" implicit="yes"/>
+ <attribute name="failmessage"/>
+ <sequential>
+ <fail message="@{failmessage}">
+ <condition>
+ <not>
+ <conditions/>
+ </not>
+ </condition>
+ </fail>
+ </sequential>
+ </macrodef>
+
+ <property name="issigned.dir" location="../../taskdefs/conditions/jars"/>
+
+ <target name="selectsigned">
+ <pass failmessage="apassword.jar should be a signed file">
+ <isfileselected file="${issigned.dir}/apassword.jar">
+ <signedselector/>
+ </isfileselected>
+ </pass>
+ </target>
+
+ <target name="notselected">
+ <pass failmessage="nosign.jar should not be selected as a signed jar">
+ <not>
+ <isfileselected file="${issigned.dir}/nosign.jar">
+ <signedselector/>
+ </isfileselected>
+ </not>
+ </pass>
+ </target>
+
+ <target name="name">
+ <pass failmessage="apassword.jar should be a signed file with the name apassword">
+ <isfileselected file="${issigned.dir}/apassword.jar">
+ <signedselector name="apassword"/>
+ </isfileselected>
+ </pass>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/xmlcatalog.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/xmlcatalog.xml
new file mode 100644
index 00000000..63269f77
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/xmlcatalog.xml
@@ -0,0 +1,150 @@
+<?xml version='1.0'?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!DOCTYPE project>
+
+<project name="xmlcatalog" default="all" basedir=".">
+
+ <description>
+ This is to test XMLCatalog for external entity resolution from the
+ xslt task, both the simple case and using the document() function
+ to refer to a second file (which refers to the entity). This
+ buildfile is called by
+ org.apache.tools.ant.types.XMLCatalogBuildFileTest.java
+ Alternatively, you may try it out by hand by first removing the
+ comment symbols around the echo statements and then calling
+ ant -buildfile xmlcatalog.xml
+ </description>
+
+ <property name="transformer" value = "xmlcatalog.xsl"/>
+
+ <target
+ name = "all"
+ depends = "testentitynocatalog, testentitywithcatalog,
+ testdocumentnocatalog, testdocumentwithcatalog"/>
+
+ <target
+ name = "testentitynocatalog"
+ description = "Test external entity resolver for simple XML
+document without using XMLCatalog">
+ <delete
+ quiet = "yes"
+ file = "result.out"/>
+ <xslt
+ basedir = "${basedir}"
+ destdir = "${basedir}"
+ extension = ".text"
+ style = "${transformer}"
+ in = "xmlcatalog1.xml"
+ out = "result.out">
+ <param
+ name = "outprop"
+ expression = "val1"/>
+ </xslt>
+ <property file = "result.out"/>
+ <!-- <echo message = "${val1}"/> -->
+ <delete
+ quiet = "yes"
+ file = "result.out"/>
+ </target>
+
+ <target
+ name = "testentitywithcatalog"
+ description = "Test external entity resolver for simple
+XML document using XMLCatalog">
+ <delete
+ quiet = "yes"
+ file = "result.out"/>
+ <xslt
+ basedir = "${basedir}"
+ destdir = "${basedir}"
+ extension = ".text"
+ style = "${transformer}"
+ in = "xmlcatalog1.xml"
+ out = "result.out">
+ <param
+ name = "outprop"
+ expression = "val2"/>
+ <xmlcatalog>
+ <entity
+ publicId = "myquote"
+ location = "quote2.xml"/>
+ </xmlcatalog>
+ </xslt>
+ <property file = "result.out"/>
+ <!-- <echo message = "${val2}"/> -->
+ <delete
+ quiet = "yes"
+ file = "result.out"/>
+ </target>
+
+ <target
+ name = "testdocumentnocatalog"
+ description = "Test entity resolution in XML document called
+from XSLT document() function without using XMLCatalog">
+ <delete
+ quiet = "yes"
+ file = "result.out"/>
+ <xslt
+ basedir = "${basedir}"
+ destdir = "${basedir}"
+ extension = ".text"
+ style = "${transformer}"
+ in = "xmlcatalog2.xml"
+ out = "result.out">
+ <param
+ name = "outprop"
+ expression = "val3"/>
+ </xslt>
+ <property file = "result.out"/>
+ <!-- <echo message = "${val3}"/> -->
+ <delete
+ quiet = "yes"
+ file = "result.out"/>
+ </target>
+
+ <target
+ name = "testdocumentwithcatalog"
+ description = "Test entity resolution in XML document called
+from XSLT document() function using XMLCatalog">
+ <delete
+ quiet = "yes"
+ file = "result.out"/>
+ <xslt
+ basedir = "${basedir}"
+ destdir = "${basedir}"
+ extension = ".text"
+ style = "${transformer}"
+ in = "xmlcatalog2.xml"
+ out = "result.out">
+ <param
+ name = "outprop"
+ expression = "val4"/>
+ <xmlcatalog>
+ <entity
+ publicId = "myquote"
+ location = "quote2.xml"/>
+ </xmlcatalog>
+ </xslt>
+ <property file = "result.out"/>
+ <!-- <echo message = "${val4}"/> -->
+ <delete
+ quiet = "yes"
+ file = "result.out"/>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/xmlcatalog.xsl b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/xmlcatalog.xsl
new file mode 100644
index 00000000..a2c839ca
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/xmlcatalog.xsl
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<xsl:stylesheet
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ version="1.0">
+
+ <!-- I belong to:
+ org.apache.tools.ant.types.XMLCatalogBuildFileTest.java
+ -->
+
+ <xsl:output method="text"/>
+
+ <!-- name of the output parameter to write -->
+ <xsl:param name="outprop">value</xsl:param>
+
+ <xsl:strip-space elements="*"/>
+
+ <xsl:template match="/">
+ <xsl:value-of select="$outprop"/>: <xsl:apply-templates select="/fragment/para"/>
+ </xsl:template>
+
+ <!-- This will only be matched in doc2.xml -->
+ <xsl:template match="Ref">
+ <xsl:apply-templates select="document(@file)/fragment/para"/>
+ </xsl:template>
+
+ <!-- This will only be matched in doc1.xml -->
+ <xsl:template match="text()">
+ <xsl:value-of select="normalize-space(.)"/>
+ </xsl:template>
+
+</xsl:stylesheet>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/xmlcatalog1.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/xmlcatalog1.xml
new file mode 100644
index 00000000..d4b5461f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/xmlcatalog1.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!DOCTYPE fragment [
+ <!ENTITY quote PUBLIC "myquote" "quote1.xml">
+]>
+
+ <!-- I belong to:
+ org.apache.tools.ant.types.XMLCatalogBuildFileTest.java
+ -->
+
+<fragment>
+ <para>
+ &quote;
+ </para>
+</fragment>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/xmlcatalog2.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/xmlcatalog2.xml
new file mode 100644
index 00000000..9d2bed03
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/xmlcatalog2.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+ <!-- I belong to:
+ org.apache.tools.ant.types.XMLCatalogBuildFileTest.java
+ -->
+
+<fragment>
+ <para>
+ <Ref file="xmlcatalog1.xml"/>
+ </para>
+</fragment>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/xmlfragment.xml b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/xmlfragment.xml
new file mode 100644
index 00000000..75214d64
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/types/xmlfragment.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project>
+ <typedef name="fragment"
+ classname="org.apache.tools.ant.util.XMLFragment"/>
+
+ <fragment id="nested-text">foo</fragment>
+
+ <fragment id="with-children">
+ <child1>foo</child1>
+ <child2 foo="bar"/>
+ <child3>
+ <child4/>
+ </child3>
+ </fragment>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/util/simple.properties b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/util/simple.properties
new file mode 100644
index 00000000..550908ca
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/util/simple.properties
@@ -0,0 +1,24 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# a comment
+prop.alpha=first property
+
+! more comment
+prop.beta=simple
+
+# now a line wrapping one
+prop.gamma=This is a long comment which \
+ contains a line wrap.
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/util/unusual.properties b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/util/unusual.properties
new file mode 100644
index 00000000..9c370faa
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/testcases/util/unusual.properties
@@ -0,0 +1,37 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+\ prop\ one\ =\ \ leading and trailing spaces
+
+prop\ttwo=contains\ttab
+
+prop\nthree=contains\nnewline
+
+prop\rfour=contains\rcarraige return
+
+prop\ffive=contains\fform feed
+
+prop\\six=contains\\backslash
+
+prop\:seven=contains\:colon
+
+prop\=eight=contains\=equals
+
+prop\#nine=contains\#hash
+
+prop\!ten=contains\!exclamation
+
+alpha:set with a colon
+beta set with a space
diff --git a/framework/src/ant/apache-ant-1.9.6/src/etc/yearcheck.sh b/framework/src/ant/apache-ant-1.9.6/src/etc/yearcheck.sh
new file mode 100644
index 00000000..1a510ffd
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/etc/yearcheck.sh
@@ -0,0 +1,101 @@
+#!/bin/sh
+
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+#
+# Simple shell script that checks whether changed files contain a copyright
+# statement for a given year.
+#
+# Rename (or symlink) this script to the year you want to check, i.e. name it
+# 2002 if you want to check for copyright statements that do not contain
+# the year 2002.
+#
+# Use this script instead of your usual cvs update command.
+#
+# Usage YEAR [precommit]
+#
+# If the optional all argument has been omitted, the proposal directory will
+# be skipped.
+#
+
+if [ -n "$TMP" ]; then
+ TEMP_DIR="$TMP"
+else
+ if [ -n "$TEMP" ]; then
+ TEMP_DIR="$TEMP"
+ else
+ TEMP_DIR=/tmp
+ fi
+fi
+
+YEAR=`basename $0`
+
+if [ $YEAR = yearcheck.sh ]; then
+ YEAR=`date -R | cut -d ' ' -f 4`
+fi
+
+precommit_call=false
+for arg in "$@" ; do
+ if [ "$arg" = "precommit" ] ; then
+ precommit_call=true
+ fi
+done
+
+if [ -d ".svn" ]; then
+ SCM_COMMAND=svn
+ if $precommit_call ; then
+ SCM_ARGS=status
+ CUT_ARGS="-c 8-"
+ else
+ SCM_ARGS=up
+ CUT_ARGS="-c 4-"
+ fi
+else
+ SCM_COMMAND=cvs
+ SCM_ARGS="-z3 update -dP"
+ CUT_ARGS="-d ' ' -f 2"
+fi
+
+"$SCM_COMMAND" $SCM_ARGS > "$TEMP_DIR"/update-prefilter
+
+# filter out boring lines
+if [ "$SCM_COMMAND" = "svn" ]; then
+ < "$TEMP_DIR"/update-prefilter fgrep -v 'At revision' | fgrep -v 'Updated to revision' | egrep -v '^\?' > "$TEMP_DIR"/update
+else
+ cp "$TEMP_DIR"/update-prefilter "$TEMP_DIR"/update
+fi
+
+cut $CUT_ARGS < "$TEMP_DIR"/update > "$TEMP_DIR"/changed-files
+
+echo "Changed:"
+echo "========"
+cat "$TEMP_DIR"/changed-files
+echo
+
+xargs fgrep -L Copyright < "$TEMP_DIR"/changed-files > "$TEMP_DIR"/no-copyright
+
+echo "No Copyright line"
+echo "================="
+cat "$TEMP_DIR"/no-copyright
+echo
+
+xargs egrep -L "Copyright.*$YEAR" < "$TEMP_DIR"/changed-files | cut -f 1 -d : > "$TEMP_DIR"/no-$YEAR
+
+echo "No Copyright line for year $YEAR"
+echo "================================"
+cat "$TEMP_DIR"/no-$YEAR
+
+rm "$TEMP_DIR"/no-$YEAR "$TEMP_DIR"/no-copyright "$TEMP_DIR"/changed-files "$TEMP_DIR"/update "$TEMP_DIR"/update-prefilter
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/AntClassLoader.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/AntClassLoader.java
new file mode 100644
index 00000000..607ada71
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/AntClassLoader.java
@@ -0,0 +1,1622 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.Constructor;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.security.CodeSource;
+import java.security.ProtectionDomain;
+import java.security.cert.Certificate;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.StringTokenizer;
+import java.util.Vector;
+import java.util.jar.Attributes;
+import java.util.jar.Attributes.Name;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+import java.util.jar.Manifest;
+
+import org.apache.tools.ant.launch.Locator;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.util.CollectionUtils;
+import org.apache.tools.ant.util.FileUtils;
+import org.apache.tools.ant.util.JavaEnvUtils;
+import org.apache.tools.ant.util.LoaderUtils;
+import org.apache.tools.ant.util.ReflectUtil;
+import org.apache.tools.ant.util.VectorSet;
+import org.apache.tools.zip.ZipLong;
+
+/**
+ * Used to load classes within ant with a different classpath from
+ * that used to start ant. Note that it is possible to force a class
+ * into this loader even when that class is on the system classpath by
+ * using the forceLoadClass method. Any subsequent classes loaded by that
+ * class will then use this loader rather than the system class loader.
+ *
+ * <p>
+ * Note that this classloader has a feature to allow loading
+ * in reverse order and for "isolation".
+ * Due to the fact that a number of
+ * methods in java.lang.ClassLoader are final (at least
+ * in java 1.4 getResources) this means that the
+ * class has to fake the given parent.
+ * </p>
+ *
+ */
+public class AntClassLoader extends ClassLoader implements SubBuildListener {
+
+ private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+
+ /**
+ * An enumeration of all resources of a given name found within the
+ * classpath of this class loader. This enumeration is used by the
+ * ClassLoader.findResources method, which is in
+ * turn used by the ClassLoader.getResources method.
+ *
+ * @see AntClassLoader#findResources(String)
+ * @see java.lang.ClassLoader#getResources(String)
+ */
+ private class ResourceEnumeration implements Enumeration<URL> {
+ /**
+ * The name of the resource being searched for.
+ */
+ private final String resourceName;
+
+ /**
+ * The index of the next classpath element to search.
+ */
+ private int pathElementsIndex;
+
+ /**
+ * The URL of the next resource to return in the enumeration. If this
+ * field is <code>null</code> then the enumeration has been completed,
+ * i.e., there are no more elements to return.
+ */
+ private URL nextResource;
+
+ /**
+ * Constructs a new enumeration of resources of the given name found
+ * within this class loader's classpath.
+ *
+ * @param name the name of the resource to search for.
+ */
+ ResourceEnumeration(final String name) {
+ this.resourceName = name;
+ this.pathElementsIndex = 0;
+ findNextResource();
+ }
+
+ /**
+ * Indicates whether there are more elements in the enumeration to
+ * return.
+ *
+ * @return <code>true</code> if there are more elements in the
+ * enumeration; <code>false</code> otherwise.
+ */
+ public boolean hasMoreElements() {
+ return (this.nextResource != null);
+ }
+
+ /**
+ * Returns the next resource in the enumeration.
+ *
+ * @return the next resource in the enumeration
+ */
+ public URL nextElement() {
+ final URL ret = this.nextResource;
+ if (ret == null) {
+ throw new NoSuchElementException();
+ }
+ findNextResource();
+ return ret;
+ }
+
+ /**
+ * Locates the next resource of the correct name in the classpath and
+ * sets <code>nextResource</code> to the URL of that resource. If no
+ * more resources can be found, <code>nextResource</code> is set to
+ * <code>null</code>.
+ */
+ private void findNextResource() {
+ URL url = null;
+ while ((pathElementsIndex < pathComponents.size()) && (url == null)) {
+ try {
+ final File pathComponent = pathComponents.elementAt(pathElementsIndex);
+ url = getResourceURL(pathComponent, this.resourceName);
+ pathElementsIndex++;
+ } catch (final BuildException e) {
+ // ignore path elements which are not valid relative to the
+ // project
+ }
+ }
+ this.nextResource = url;
+ }
+ }
+
+ /**
+ * The size of buffers to be used in this classloader.
+ */
+ private static final int BUFFER_SIZE = 8192;
+
+ /**
+ * Number of array elements in a test array of strings
+ */
+ private static final int NUMBER_OF_STRINGS = 256;
+
+ /**
+ * The components of the classpath that the classloader searches
+ * for classes.
+ */
+ private final Vector<File> pathComponents = new VectorSet<File>();
+
+ /**
+ * The project to which this class loader belongs.
+ */
+ private Project project;
+
+ /**
+ * Indicates whether the parent class loader should be
+ * consulted before trying to load with this class loader.
+ */
+ private boolean parentFirst = true;
+
+ /**
+ * These are the package roots that are to be loaded by the parent class
+ * loader regardless of whether the parent class loader is being searched
+ * first or not.
+ */
+ private final Vector<String> systemPackages = new Vector<String>();
+
+ /**
+ * These are the package roots that are to be loaded by this class loader
+ * regardless of whether the parent class loader is being searched first
+ * or not.
+ */
+ private final Vector<String> loaderPackages = new Vector<String>();
+
+ /**
+ * Whether or not this classloader will ignore the base
+ * classloader if it can't find a class.
+ *
+ * @see #setIsolated(boolean)
+ */
+ private boolean ignoreBase = false;
+
+ /**
+ * The parent class loader, if one is given or can be determined.
+ */
+ private ClassLoader parent = null;
+
+ /**
+ * A hashtable of zip files opened by the classloader (File to JarFile).
+ */
+ private Hashtable<File, JarFile> jarFiles = new Hashtable<File, JarFile>();
+
+ /** Static map of jar file/time to manifest class-path entries */
+ private static Map<String, String> pathMap =
+ Collections.synchronizedMap(new HashMap<String, String>());
+
+ /**
+ * The context loader saved when setting the thread's current
+ * context loader.
+ */
+ private ClassLoader savedContextLoader = null;
+
+ /**
+ * Whether or not the context loader is currently saved.
+ */
+ private boolean isContextLoaderSaved = false;
+
+ /**
+ * Create an Ant ClassLoader for a given project, with
+ * a parent classloader and an initial classpath.
+ * @since Ant 1.7.
+ * @param parent the parent for this classloader.
+ * @param project The project to which this classloader is to
+ * belong.
+ * @param classpath The classpath to use to load classes.
+ */
+ public AntClassLoader(final ClassLoader parent, final Project project, final Path classpath) {
+ setParent(parent);
+ setClassPath(classpath);
+ setProject(project);
+ }
+
+ /**
+ * Create an Ant Class Loader
+ */
+ public AntClassLoader() {
+ setParent(null);
+ }
+
+ /**
+ * Creates a classloader for the given project using the classpath given.
+ *
+ * @param project The project to which this classloader is to belong.
+ * Must not be <code>null</code>.
+ * @param classpath The classpath to use to load the classes. This
+ * is combined with the system classpath in a manner
+ * determined by the value of ${build.sysclasspath}.
+ * May be <code>null</code>, in which case no path
+ * elements are set up to start with.
+ */
+ public AntClassLoader(final Project project, final Path classpath) {
+ setParent(null);
+ setProject(project);
+ setClassPath(classpath);
+ }
+
+ /**
+ * Creates a classloader for the given project using the classpath given.
+ *
+ * @param parent The parent classloader to which unsatisfied loading
+ * attempts are delegated. May be <code>null</code>,
+ * in which case the classloader which loaded this
+ * class is used as the parent.
+ * @param project The project to which this classloader is to belong.
+ * Must not be <code>null</code>.
+ * @param classpath the classpath to use to load the classes.
+ * May be <code>null</code>, in which case no path
+ * elements are set up to start with.
+ * @param parentFirst If <code>true</code>, indicates that the parent
+ * classloader should be consulted before trying to
+ * load the a class through this loader.
+ */
+ public AntClassLoader(
+ final ClassLoader parent, final Project project, final Path classpath, final boolean parentFirst) {
+ this(project, classpath);
+ if (parent != null) {
+ setParent(parent);
+ }
+ setParentFirst(parentFirst);
+ addJavaLibraries();
+ }
+
+ /**
+ * Creates a classloader for the given project using the classpath given.
+ *
+ * @param project The project to which this classloader is to belong.
+ * Must not be <code>null</code>.
+ * @param classpath The classpath to use to load the classes. May be
+ * <code>null</code>, in which case no path
+ * elements are set up to start with.
+ * @param parentFirst If <code>true</code>, indicates that the parent
+ * classloader should be consulted before trying to
+ * load the a class through this loader.
+ */
+ public AntClassLoader(final Project project, final Path classpath, final boolean parentFirst) {
+ this(null, project, classpath, parentFirst);
+ }
+
+ /**
+ * Creates an empty class loader. The classloader should be configured
+ * with path elements to specify where the loader is to look for
+ * classes.
+ *
+ * @param parent The parent classloader to which unsatisfied loading
+ * attempts are delegated. May be <code>null</code>,
+ * in which case the classloader which loaded this
+ * class is used as the parent.
+ * @param parentFirst If <code>true</code>, indicates that the parent
+ * classloader should be consulted before trying to
+ * load the a class through this loader.
+ */
+ public AntClassLoader(final ClassLoader parent, final boolean parentFirst) {
+ setParent(parent);
+ project = null;
+ this.parentFirst = parentFirst;
+ }
+
+ /**
+ * Set the project associated with this class loader
+ *
+ * @param project the project instance
+ */
+ public void setProject(final Project project) {
+ this.project = project;
+ if (project != null) {
+ project.addBuildListener(this);
+ }
+ }
+
+ /**
+ * Set the classpath to search for classes to load. This should not be
+ * changed once the classloader starts to server classes
+ *
+ * @param classpath the search classpath consisting of directories and
+ * jar/zip files.
+ */
+ public void setClassPath(final Path classpath) {
+ pathComponents.removeAllElements();
+ if (classpath != null) {
+ final Path actualClasspath = classpath.concatSystemClasspath("ignore");
+ final String[] pathElements = actualClasspath.list();
+ for (int i = 0; i < pathElements.length; ++i) {
+ try {
+ addPathElement(pathElements[i]);
+ } catch (final BuildException e) {
+ // ignore path elements which are invalid
+ // relative to the project
+ }
+ }
+ }
+ }
+
+ /**
+ * Set the parent for this class loader. This is the class loader to which
+ * this class loader will delegate to load classes
+ *
+ * @param parent the parent class loader.
+ */
+ public void setParent(final ClassLoader parent) {
+ this.parent = parent == null ? AntClassLoader.class.getClassLoader() : parent;
+ }
+
+ /**
+ * Control whether class lookup is delegated to the parent loader first
+ * or after this loader. Use with extreme caution. Setting this to
+ * false violates the class loader hierarchy and can lead to Linkage errors
+ *
+ * @param parentFirst if true, delegate initial class search to the parent
+ * classloader.
+ */
+ public void setParentFirst(final boolean parentFirst) {
+ this.parentFirst = parentFirst;
+ }
+
+ /**
+ * Logs a message through the project object if one has been provided.
+ *
+ * @param message The message to log.
+ * Should not be <code>null</code>.
+ *
+ * @param priority The logging priority of the message.
+ */
+ protected void log(final String message, final int priority) {
+ if (project != null) {
+ project.log(message, priority);
+ }
+ }
+
+ /**
+ * Sets the current thread's context loader to this classloader, storing
+ * the current loader value for later resetting.
+ */
+ public void setThreadContextLoader() {
+ if (isContextLoaderSaved) {
+ throw new BuildException("Context loader has not been reset");
+ }
+ if (LoaderUtils.isContextLoaderAvailable()) {
+ savedContextLoader = LoaderUtils.getContextClassLoader();
+ ClassLoader loader = this;
+ if (project != null && "only".equals(project.getProperty("build.sysclasspath"))) {
+ loader = this.getClass().getClassLoader();
+ }
+ LoaderUtils.setContextClassLoader(loader);
+ isContextLoaderSaved = true;
+ }
+ }
+
+ /**
+ * Resets the current thread's context loader to its original value.
+ */
+ public void resetThreadContextLoader() {
+ if (LoaderUtils.isContextLoaderAvailable() && isContextLoaderSaved) {
+ LoaderUtils.setContextClassLoader(savedContextLoader);
+ savedContextLoader = null;
+ isContextLoaderSaved = false;
+ }
+ }
+
+
+ /**
+ * Adds an element to the classpath to be searched.
+ *
+ * @param pathElement The path element to add. Must not be
+ * <code>null</code>.
+ *
+ * @exception BuildException if the given path element cannot be resolved
+ * against the project.
+ */
+ public void addPathElement(final String pathElement) throws BuildException {
+ final File pathComponent = project != null ? project.resolveFile(pathElement) : new File(
+ pathElement);
+ try {
+ addPathFile(pathComponent);
+ } catch (final IOException e) {
+ throw new BuildException(e);
+ }
+ }
+
+ /**
+ * Add a path component.
+ * This simply adds the file, unlike addPathElement
+ * it does not open jar files and load files from
+ * their CLASSPATH entry in the manifest file.
+ * @param file the jar file or directory to add.
+ */
+ public void addPathComponent(final File file) {
+ if (pathComponents.contains(file)) {
+ return;
+ }
+ pathComponents.addElement(file);
+ }
+
+ /**
+ * Add a file to the path.
+ * Reads the manifest, if available, and adds any additional class path jars
+ * specified in the manifest.
+ *
+ * @param pathComponent the file which is to be added to the path for
+ * this class loader
+ *
+ * @throws IOException if data needed from the file cannot be read.
+ */
+ protected void addPathFile(final File pathComponent) throws IOException {
+ if (!pathComponents.contains(pathComponent)) {
+ pathComponents.addElement(pathComponent);
+ }
+ if (pathComponent.isDirectory()) {
+ return;
+ }
+
+ final String absPathPlusTimeAndLength = pathComponent.getAbsolutePath()
+ + pathComponent.lastModified() + "-" + pathComponent.length();
+ String classpath = pathMap.get(absPathPlusTimeAndLength);
+ if (classpath == null) {
+ JarFile jarFile = null;
+ try {
+ jarFile = new JarFile(pathComponent);
+ final Manifest manifest = jarFile.getManifest();
+ if (manifest == null) {
+ return;
+ }
+ classpath = manifest.getMainAttributes()
+ .getValue(Attributes.Name.CLASS_PATH);
+ } finally {
+ if (jarFile != null) {
+ jarFile.close();
+ }
+ }
+ if (classpath == null) {
+ classpath = "";
+ }
+ pathMap.put(absPathPlusTimeAndLength, classpath);
+ }
+
+ if (!"".equals(classpath)) {
+ final URL baseURL = FILE_UTILS.getFileURL(pathComponent);
+ final StringTokenizer st = new StringTokenizer(classpath);
+ while (st.hasMoreTokens()) {
+ final String classpathElement = st.nextToken();
+ final URL libraryURL = new URL(baseURL, classpathElement);
+ if (!libraryURL.getProtocol().equals("file")) {
+ log("Skipping jar library " + classpathElement
+ + " since only relative URLs are supported by this" + " loader",
+ Project.MSG_VERBOSE);
+ continue;
+ }
+ final String decodedPath = Locator.decodeUri(libraryURL.getFile());
+ final File libraryFile = new File(decodedPath);
+ if (libraryFile.exists() && !isInPath(libraryFile)) {
+ addPathFile(libraryFile);
+ }
+ }
+ }
+ }
+
+ /**
+ * Returns the classpath this classloader will consult.
+ *
+ * @return the classpath used for this classloader, with elements
+ * separated by the path separator for the system.
+ */
+ public String getClasspath() {
+ final StringBuilder sb = new StringBuilder();
+ boolean firstPass = true;
+ final Enumeration<File> componentEnum = pathComponents.elements();
+ while (componentEnum.hasMoreElements()) {
+ if (!firstPass) {
+ sb.append(System.getProperty("path.separator"));
+ } else {
+ firstPass = false;
+ }
+ sb.append(componentEnum.nextElement().getAbsolutePath());
+ }
+ return sb.toString();
+ }
+
+ /**
+ * Sets whether this classloader should run in isolated mode. In
+ * isolated mode, classes not found on the given classpath will
+ * not be referred to the parent class loader but will cause a
+ * ClassNotFoundException.
+ *
+ * @param isolated Whether or not this classloader should run in
+ * isolated mode.
+ */
+ public synchronized void setIsolated(final boolean isolated) {
+ ignoreBase = isolated;
+ }
+
+ /**
+ * Forces initialization of a class in a JDK 1.1 compatible, albeit hacky
+ * way.
+ *
+ * @param theClass The class to initialize.
+ * Must not be <code>null</code>.
+ *
+ * @deprecated since 1.6.x.
+ * Use Class.forName with initialize=true instead.
+ */
+ @Deprecated
+ public static void initializeClass(final Class<?> theClass) {
+ // ***HACK*** We ask the VM to create an instance
+ // by voluntarily providing illegal arguments to force
+ // the VM to run the class' static initializer, while
+ // at the same time not running a valid constructor.
+
+ final Constructor<?>[] cons = theClass.getDeclaredConstructors();
+ //At least one constructor is guaranteed to be there, but check anyway.
+ if (cons != null) {
+ if (cons.length > 0 && cons[0] != null) {
+ final String[] strs = new String[NUMBER_OF_STRINGS];
+ try {
+ cons[0].newInstance((Object[]) strs);
+ // Expecting an exception to be thrown by this call:
+ // IllegalArgumentException: wrong number of Arguments
+ } catch (final Exception e) {
+ // Ignore - we are interested only in the side
+ // effect - that of getting the static initializers
+ // invoked. As we do not want to call a valid
+ // constructor to get this side effect, an
+ // attempt is made to call a hopefully
+ // invalid constructor - come on, nobody
+ // would have a constructor that takes in
+ // 256 String arguments ;-)
+ // (In fact, they can't - according to JVM spec
+ // section 4.10, the number of method parameters is limited
+ // to 255 by the definition of a method descriptor.
+ // Constructors count as methods here.)
+ }
+ }
+ }
+ }
+
+ /**
+ * Adds a package root to the list of packages which must be loaded on the
+ * parent loader.
+ *
+ * All subpackages are also included.
+ *
+ * @param packageRoot The root of all packages to be included.
+ * Should not be <code>null</code>.
+ */
+ public void addSystemPackageRoot(final String packageRoot) {
+ systemPackages.addElement(packageRoot + (packageRoot.endsWith(".") ? "" : "."));
+ }
+
+ /**
+ * Adds a package root to the list of packages which must be loaded using
+ * this loader.
+ *
+ * All subpackages are also included.
+ *
+ * @param packageRoot The root of all packages to be included.
+ * Should not be <code>null</code>.
+ */
+ public void addLoaderPackageRoot(final String packageRoot) {
+ loaderPackages.addElement(packageRoot + (packageRoot.endsWith(".") ? "" : "."));
+ }
+
+ /**
+ * Loads a class through this class loader even if that class is available
+ * on the parent classpath.
+ *
+ * This ensures that any classes which are loaded by the returned class
+ * will use this classloader.
+ *
+ * @param classname The name of the class to be loaded.
+ * Must not be <code>null</code>.
+ *
+ * @return the required Class object
+ *
+ * @exception ClassNotFoundException if the requested class does not exist
+ * on this loader's classpath.
+ */
+ public Class<?> forceLoadClass(final String classname) throws ClassNotFoundException {
+ log("force loading " + classname, Project.MSG_DEBUG);
+
+ Class<?> theClass = findLoadedClass(classname);
+
+ if (theClass == null) {
+ theClass = findClass(classname);
+ }
+ return theClass;
+ }
+
+ /**
+ * Loads a class through this class loader but defer to the parent class
+ * loader.
+ *
+ * This ensures that instances of the returned class will be compatible
+ * with instances which have already been loaded on the parent
+ * loader.
+ *
+ * @param classname The name of the class to be loaded.
+ * Must not be <code>null</code>.
+ *
+ * @return the required Class object
+ *
+ * @exception ClassNotFoundException if the requested class does not exist
+ * on this loader's classpath.
+ */
+ public Class<?> forceLoadSystemClass(final String classname) throws ClassNotFoundException {
+ log("force system loading " + classname, Project.MSG_DEBUG);
+
+ Class<?> theClass = findLoadedClass(classname);
+
+ if (theClass == null) {
+ theClass = findBaseClass(classname);
+ }
+ return theClass;
+ }
+
+ /**
+ * Returns a stream to read the requested resource name.
+ *
+ * @param name The name of the resource for which a stream is required.
+ * Must not be <code>null</code>.
+ *
+ * @return a stream to the required resource or <code>null</code> if the
+ * resource cannot be found on the loader's classpath.
+ */
+ @Override
+ public InputStream getResourceAsStream(final String name) {
+ InputStream resourceStream = null;
+ if (isParentFirst(name)) {
+ resourceStream = loadBaseResource(name);
+ }
+ if (resourceStream != null) {
+ log("ResourceStream for " + name
+ + " loaded from parent loader", Project.MSG_DEBUG);
+ } else {
+ resourceStream = loadResource(name);
+ if (resourceStream != null) {
+ log("ResourceStream for " + name
+ + " loaded from ant loader", Project.MSG_DEBUG);
+ }
+ }
+ if (resourceStream == null && !isParentFirst(name)) {
+ if (ignoreBase) {
+ resourceStream = getRootLoader() == null
+ ? null
+ : getRootLoader().getResourceAsStream(name);
+ } else {
+ resourceStream = loadBaseResource(name);
+ }
+ if (resourceStream != null) {
+ log("ResourceStream for " + name + " loaded from parent loader",
+ Project.MSG_DEBUG);
+ }
+ }
+ if (resourceStream == null) {
+ log("Couldn't load ResourceStream for " + name, Project.MSG_DEBUG);
+ }
+ return resourceStream;
+ }
+
+ /**
+ * Returns a stream to read the requested resource name from this loader.
+ *
+ * @param name The name of the resource for which a stream is required.
+ * Must not be <code>null</code>.
+ *
+ * @return a stream to the required resource or <code>null</code> if
+ * the resource cannot be found on the loader's classpath.
+ */
+ private InputStream loadResource(final String name) {
+ // we need to search the components of the path to see if we can
+ // find the class we want.
+ InputStream stream = null;
+
+ final Enumeration<File> e = pathComponents.elements();
+ while (e.hasMoreElements() && stream == null) {
+ final File pathComponent = e.nextElement();
+ stream = getResourceStream(pathComponent, name);
+ }
+ return stream;
+ }
+
+ /**
+ * Finds a system resource (which should be loaded from the parent
+ * classloader).
+ *
+ * @param name The name of the system resource to load.
+ * Must not be <code>null</code>.
+ *
+ * @return a stream to the named resource, or <code>null</code> if
+ * the resource cannot be found.
+ */
+ private InputStream loadBaseResource(final String name) {
+ return parent == null ? super.getResourceAsStream(name) : parent.getResourceAsStream(name);
+ }
+
+ /**
+ * Returns an inputstream to a given resource in the given file which may
+ * either be a directory or a zip file.
+ *
+ * @param file the file (directory or jar) in which to search for the
+ * resource. Must not be <code>null</code>.
+ * @param resourceName The name of the resource for which a stream is
+ * required. Must not be <code>null</code>.
+ *
+ * @return a stream to the required resource or <code>null</code> if
+ * the resource cannot be found in the given file.
+ */
+ private InputStream getResourceStream(final File file, final String resourceName) {
+ try {
+ JarFile jarFile = jarFiles.get(file);
+ if (jarFile == null && file.isDirectory()) {
+ final File resource = new File(file, resourceName);
+ if (resource.exists()) {
+ return new FileInputStream(resource);
+ }
+ } else {
+ if (jarFile == null) {
+ if (file.exists()) {
+ jarFile = new JarFile(file);
+ jarFiles.put(file, jarFile);
+ } else {
+ return null;
+ }
+ //to eliminate a race condition, retrieve the entry
+ //that is in the hash table under that filename
+ jarFile = jarFiles.get(file);
+ }
+ final JarEntry entry = jarFile.getJarEntry(resourceName);
+ if (entry != null) {
+ return jarFile.getInputStream(entry);
+ }
+ }
+ } catch (final Exception e) {
+ log("Ignoring Exception " + e.getClass().getName() + ": " + e.getMessage()
+ + " reading resource " + resourceName + " from " + file, Project.MSG_VERBOSE);
+ }
+ return null;
+ }
+
+ /**
+ * Tests whether or not the parent classloader should be checked for a
+ * resource before this one. If the resource matches both the "use parent
+ * classloader first" and the "use this classloader first" lists, the latter
+ * takes priority.
+ *
+ * @param resourceName
+ * The name of the resource to check. Must not be
+ * <code>null</code>.
+ *
+ * @return whether or not the parent classloader should be checked for a
+ * resource before this one is.
+ */
+ private boolean isParentFirst(final String resourceName) {
+ // default to the global setting and then see
+ // if this class belongs to a package which has been
+ // designated to use a specific loader first
+ // (this one or the parent one)
+
+ // TODO - shouldn't this always return false in isolated mode?
+
+ boolean useParentFirst = parentFirst;
+
+ for (final Enumeration<String> e = systemPackages.elements(); e.hasMoreElements();) {
+ final String packageName = e.nextElement();
+ if (resourceName.startsWith(packageName)) {
+ useParentFirst = true;
+ break;
+ }
+ }
+ for (final Enumeration<String> e = loaderPackages.elements(); e.hasMoreElements();) {
+ final String packageName = e.nextElement();
+ if (resourceName.startsWith(packageName)) {
+ useParentFirst = false;
+ break;
+ }
+ }
+ return useParentFirst;
+ }
+
+ /**
+ * Used for isolated resource seaching.
+ * @return the root classloader of AntClassLoader.
+ */
+ private ClassLoader getRootLoader() {
+ ClassLoader ret = getClass().getClassLoader();
+ while (ret != null && ret.getParent() != null) {
+ ret = ret.getParent();
+ }
+ return ret;
+ }
+
+ /**
+ * Finds the resource with the given name. A resource is
+ * some data (images, audio, text, etc) that can be accessed by class
+ * code in a way that is independent of the location of the code.
+ *
+ * @param name The name of the resource for which a stream is required.
+ * Must not be <code>null</code>.
+ *
+ * @return a URL for reading the resource, or <code>null</code> if the
+ * resource could not be found or the caller doesn't have
+ * adequate privileges to get the resource.
+ */
+ @Override
+ public URL getResource(final String name) {
+ // we need to search the components of the path to see if
+ // we can find the class we want.
+ URL url = null;
+ if (isParentFirst(name)) {
+ url = parent == null ? super.getResource(name) : parent.getResource(name);
+ }
+ if (url != null) {
+ log("Resource " + name + " loaded from parent loader", Project.MSG_DEBUG);
+ } else {
+ // try and load from this loader if the parent either didn't find
+ // it or wasn't consulted.
+ final Enumeration<File> e = pathComponents.elements();
+ while (e.hasMoreElements() && url == null) {
+ final File pathComponent = e.nextElement();
+ url = getResourceURL(pathComponent, name);
+ if (url != null) {
+ log("Resource " + name + " loaded from ant loader", Project.MSG_DEBUG);
+ }
+ }
+ }
+ if (url == null && !isParentFirst(name)) {
+ // this loader was first but it didn't find it - try the parent
+ if (ignoreBase) {
+ url = getRootLoader() == null ? null : getRootLoader().getResource(name);
+ } else {
+ url = parent == null ? super.getResource(name) : parent.getResource(name);
+ }
+ if (url != null) {
+ log("Resource " + name + " loaded from parent loader", Project.MSG_DEBUG);
+ }
+ }
+ if (url == null) {
+ log("Couldn't load Resource " + name, Project.MSG_DEBUG);
+ }
+ return url;
+ }
+
+ /**
+ * Finds all the resources with the given name. A resource is some
+ * data (images, audio, text, etc) that can be accessed by class
+ * code in a way that is independent of the location of the code.
+ *
+ * <p>Would override getResources if that wasn't final in Java
+ * 1.4.</p>
+ *
+ * @param name name of the resource
+ * @return possible URLs as enumeration
+ * @throws IOException
+ * @see {@link #findResources(String, boolean)}
+ * @since Ant 1.8.0
+ */
+ public Enumeration<URL> getNamedResources(final String name)
+ throws IOException {
+ return findResources(name, false);
+ }
+
+ /**
+ * Returns an enumeration of URLs representing all the resources with the
+ * given name by searching the class loader's classpath.
+ *
+ * @param name The resource name to search for.
+ * Must not be <code>null</code>.
+ * @return an enumeration of URLs for the resources
+ * @exception IOException if I/O errors occurs (can't happen)
+ */
+ @Override
+ protected Enumeration<URL> findResources(final String name) throws IOException {
+ return findResources(name, true);
+ }
+
+ /**
+ * Returns an enumeration of URLs representing all the resources with the
+ * given name by searching the class loader's classpath.
+ *
+ * @param name The resource name to search for.
+ * Must not be <code>null</code>.
+ * @param parentHasBeenSearched whether ClassLoader.this.parent
+ * has been searched - will be true if the method is (indirectly)
+ * called from ClassLoader.getResources
+ * @return an enumeration of URLs for the resources
+ * @exception IOException if I/O errors occurs (can't happen)
+ */
+ protected Enumeration<URL> findResources(final String name,
+ final boolean parentHasBeenSearched)
+ throws IOException {
+ final Enumeration<URL> mine = new ResourceEnumeration(name);
+ Enumeration<URL> base;
+ if (parent != null && (!parentHasBeenSearched || parent != getParent())) {
+ // Delegate to the parent:
+ base = parent.getResources(name);
+ // Note: could cause overlaps in case
+ // ClassLoader.this.parent has matches and
+ // parentHasBeenSearched is true
+ } else {
+ // ClassLoader.this.parent is already delegated to for example from
+ // ClassLoader.getResources, no need:
+ base = new CollectionUtils.EmptyEnumeration<URL>();
+ }
+ if (isParentFirst(name)) {
+ // Normal case.
+ return CollectionUtils.append(base, mine);
+ }
+ if (ignoreBase) {
+ return getRootLoader() == null ? mine : CollectionUtils.append(mine, getRootLoader()
+ .getResources(name));
+ }
+ // parent last:
+ return CollectionUtils.append(mine, base);
+ }
+
+ /**
+ * Returns the URL of a given resource in the given file which may
+ * either be a directory or a zip file.
+ *
+ * @param file The file (directory or jar) in which to search for
+ * the resource. Must not be <code>null</code>.
+ * @param resourceName The name of the resource for which a stream
+ * is required. Must not be <code>null</code>.
+ *
+ * @return a stream to the required resource or <code>null</code> if the
+ * resource cannot be found in the given file object.
+ */
+ protected URL getResourceURL(final File file, final String resourceName) {
+ try {
+ JarFile jarFile = jarFiles.get(file);
+ if (jarFile == null && file.isDirectory()) {
+ final File resource = new File(file, resourceName);
+
+ if (resource.exists()) {
+ try {
+ return FILE_UTILS.getFileURL(resource);
+ } catch (final MalformedURLException ex) {
+ return null;
+ }
+ }
+ } else {
+ if (jarFile == null) {
+ if (file.exists()) {
+ if (!isZip(file)) {
+ final String msg = "CLASSPATH element " + file
+ + " is not a JAR.";
+ log(msg, Project.MSG_WARN);
+ System.err.println(msg);
+ return null;
+ }
+ jarFile = new JarFile(file);
+ jarFiles.put(file, jarFile);
+ } else {
+ return null;
+ }
+ // potential race-condition
+ jarFile = jarFiles.get(file);
+ }
+ final JarEntry entry = jarFile.getJarEntry(resourceName);
+ if (entry != null) {
+ try {
+ return new URL("jar:" + FILE_UTILS.getFileURL(file) + "!/" + entry);
+ } catch (final MalformedURLException ex) {
+ return null;
+ }
+ }
+ }
+ } catch (final Exception e) {
+ final String msg = "Unable to obtain resource from " + file + ": ";
+ log(msg + e, Project.MSG_WARN);
+ System.err.println(msg);
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ /**
+ * Loads a class with this class loader.
+ *
+ * This class attempts to load the class in an order determined by whether
+ * or not the class matches the system/loader package lists, with the
+ * loader package list taking priority. If the classloader is in isolated
+ * mode, failure to load the class in this loader will result in a
+ * ClassNotFoundException.
+ *
+ * @param classname The name of the class to be loaded.
+ * Must not be <code>null</code>.
+ * @param resolve <code>true</code> if all classes upon which this class
+ * depends are to be loaded.
+ *
+ * @return the required Class object
+ *
+ * @exception ClassNotFoundException if the requested class does not exist
+ * on the system classpath (when not in isolated mode) or this loader's
+ * classpath.
+ */
+ @Override
+ protected synchronized Class<?> loadClass(final String classname, final boolean resolve)
+ throws ClassNotFoundException {
+ // 'sync' is needed - otherwise 2 threads can load the same class
+ // twice, resulting in LinkageError: duplicated class definition.
+ // findLoadedClass avoids that, but without sync it won't work.
+
+ Class<?> theClass = findLoadedClass(classname);
+ if (theClass != null) {
+ return theClass;
+ }
+ if (isParentFirst(classname)) {
+ try {
+ theClass = findBaseClass(classname);
+ log("Class " + classname + " loaded from parent loader " + "(parentFirst)",
+ Project.MSG_DEBUG);
+ } catch (final ClassNotFoundException cnfe) {
+ theClass = findClass(classname);
+ log("Class " + classname + " loaded from ant loader " + "(parentFirst)",
+ Project.MSG_DEBUG);
+ }
+ } else {
+ try {
+ theClass = findClass(classname);
+ log("Class " + classname + " loaded from ant loader", Project.MSG_DEBUG);
+ } catch (final ClassNotFoundException cnfe) {
+ if (ignoreBase) {
+ throw cnfe;
+ }
+ theClass = findBaseClass(classname);
+ log("Class " + classname + " loaded from parent loader", Project.MSG_DEBUG);
+ }
+ }
+ if (resolve) {
+ resolveClass(theClass);
+ }
+ return theClass;
+ }
+
+ /**
+ * Converts the class dot notation to a filesystem equivalent for
+ * searching purposes.
+ *
+ * @param classname The class name in dot format (eg java.lang.Integer).
+ * Must not be <code>null</code>.
+ *
+ * @return the classname in filesystem format (eg java/lang/Integer.class)
+ */
+ private String getClassFilename(final String classname) {
+ return classname.replace('.', '/') + ".class";
+ }
+
+ /**
+ * Define a class given its bytes
+ *
+ * @param container the container from which the class data has been read
+ * may be a directory or a jar/zip file.
+ *
+ * @param classData the bytecode data for the class
+ * @param classname the name of the class
+ *
+ * @return the Class instance created from the given data
+ *
+ * @throws IOException if the class data cannot be read.
+ */
+ protected Class<?> defineClassFromData(final File container, final byte[] classData, final String classname)
+ throws IOException {
+ definePackage(container, classname);
+ final ProtectionDomain currentPd = Project.class.getProtectionDomain();
+ final String classResource = getClassFilename(classname);
+ final CodeSource src = new CodeSource(FILE_UTILS.getFileURL(container),
+ getCertificates(container,
+ classResource));
+ final ProtectionDomain classesPd =
+ new ProtectionDomain(src, currentPd.getPermissions(),
+ this,
+ currentPd.getPrincipals());
+ return defineClass(classname, classData, 0, classData.length,
+ classesPd);
+ }
+
+ /**
+ * Define the package information associated with a class.
+ *
+ * @param container the file containing the class definition.
+ * @param className the class name of for which the package information
+ * is to be determined.
+ *
+ * @exception IOException if the package information cannot be read from the
+ * container.
+ */
+ protected void definePackage(final File container, final String className) throws IOException {
+ final int classIndex = className.lastIndexOf('.');
+ if (classIndex == -1) {
+ return;
+ }
+ final String packageName = className.substring(0, classIndex);
+ if (getPackage(packageName) != null) {
+ // already defined
+ return;
+ }
+ // define the package now
+ final Manifest manifest = getJarManifest(container);
+
+ if (manifest == null) {
+ definePackage(packageName, null, null, null, null, null, null, null);
+ } else {
+ definePackage(container, packageName, manifest);
+ }
+ }
+
+ /**
+ * Get the manifest from the given jar, if it is indeed a jar and it has a
+ * manifest
+ *
+ * @param container the File from which a manifest is required.
+ *
+ * @return the jar's manifest or null is the container is not a jar or it
+ * has no manifest.
+ *
+ * @exception IOException if the manifest cannot be read.
+ */
+ private Manifest getJarManifest(final File container) throws IOException {
+ if (container.isDirectory()) {
+ return null;
+ }
+ final JarFile jarFile = jarFiles.get(container);
+ if (jarFile == null) {
+ return null;
+ }
+ return jarFile.getManifest();
+ }
+
+ /**
+ * Get the certificates for a given jar entry, if it is indeed a jar.
+ *
+ * @param container the File from which to read the entry
+ * @param entry the entry of which the certificates are requested
+ *
+ * @return the entry's certificates or null is the container is
+ * not a jar or it has no certificates.
+ *
+ * @exception IOException if the manifest cannot be read.
+ */
+ private Certificate[] getCertificates(final File container, final String entry)
+ throws IOException {
+ if (container.isDirectory()) {
+ return null;
+ }
+ final JarFile jarFile = jarFiles.get(container);
+ if (jarFile == null) {
+ return null;
+ }
+ final JarEntry ent = jarFile.getJarEntry(entry);
+ return ent == null ? null : ent.getCertificates();
+ }
+
+ /**
+ * Define the package information when the class comes from a
+ * jar with a manifest
+ *
+ * @param container the jar file containing the manifest
+ * @param packageName the name of the package being defined.
+ * @param manifest the jar's manifest
+ */
+ protected void definePackage(final File container, final String packageName, final Manifest manifest) {
+ final String sectionName = packageName.replace('.', '/') + "/";
+
+ String specificationTitle = null;
+ String specificationVendor = null;
+ String specificationVersion = null;
+ String implementationTitle = null;
+ String implementationVendor = null;
+ String implementationVersion = null;
+ String sealedString = null;
+ URL sealBase = null;
+
+ final Attributes sectionAttributes = manifest.getAttributes(sectionName);
+ if (sectionAttributes != null) {
+ specificationTitle = sectionAttributes.getValue(Name.SPECIFICATION_TITLE);
+ specificationVendor = sectionAttributes.getValue(Name.SPECIFICATION_VENDOR);
+ specificationVersion = sectionAttributes.getValue(Name.SPECIFICATION_VERSION);
+ implementationTitle = sectionAttributes.getValue(Name.IMPLEMENTATION_TITLE);
+ implementationVendor = sectionAttributes.getValue(Name.IMPLEMENTATION_VENDOR);
+ implementationVersion = sectionAttributes.getValue(Name.IMPLEMENTATION_VERSION);
+ sealedString = sectionAttributes.getValue(Name.SEALED);
+ }
+ final Attributes mainAttributes = manifest.getMainAttributes();
+ if (mainAttributes != null) {
+ if (specificationTitle == null) {
+ specificationTitle = mainAttributes.getValue(Name.SPECIFICATION_TITLE);
+ }
+ if (specificationVendor == null) {
+ specificationVendor = mainAttributes.getValue(Name.SPECIFICATION_VENDOR);
+ }
+ if (specificationVersion == null) {
+ specificationVersion = mainAttributes.getValue(Name.SPECIFICATION_VERSION);
+ }
+ if (implementationTitle == null) {
+ implementationTitle = mainAttributes.getValue(Name.IMPLEMENTATION_TITLE);
+ }
+ if (implementationVendor == null) {
+ implementationVendor = mainAttributes.getValue(Name.IMPLEMENTATION_VENDOR);
+ }
+ if (implementationVersion == null) {
+ implementationVersion = mainAttributes.getValue(Name.IMPLEMENTATION_VERSION);
+ }
+ if (sealedString == null) {
+ sealedString = mainAttributes.getValue(Name.SEALED);
+ }
+ }
+ if (sealedString != null && sealedString.equalsIgnoreCase("true")) {
+ try {
+ sealBase = new URL(FileUtils.getFileUtils().toURI(container.getAbsolutePath()));
+ } catch (final MalformedURLException e) {
+ // ignore
+ }
+ }
+ definePackage(packageName, specificationTitle, specificationVersion, specificationVendor,
+ implementationTitle, implementationVersion, implementationVendor, sealBase);
+ }
+
+ /**
+ * Reads a class definition from a stream.
+ *
+ * @param stream The stream from which the class is to be read.
+ * Must not be <code>null</code>.
+ * @param classname The name of the class in the stream.
+ * Must not be <code>null</code>.
+ * @param container the file or directory containing the class.
+ *
+ * @return the Class object read from the stream.
+ *
+ * @exception IOException if there is a problem reading the class from the
+ * stream.
+ * @exception SecurityException if there is a security problem while
+ * reading the class from the stream.
+ */
+ private Class<?> getClassFromStream(final InputStream stream, final String classname, final File container)
+ throws IOException, SecurityException {
+ final ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ int bytesRead = -1;
+ final byte[] buffer = new byte[BUFFER_SIZE];
+
+ while ((bytesRead = stream.read(buffer, 0, BUFFER_SIZE)) != -1) {
+ baos.write(buffer, 0, bytesRead);
+ }
+ final byte[] classData = baos.toByteArray();
+ return defineClassFromData(container, classData, classname);
+ }
+
+ /**
+ * Searches for and load a class on the classpath of this class loader.
+ *
+ * @param name The name of the class to be loaded. Must not be
+ * <code>null</code>.
+ *
+ * @return the required Class object
+ *
+ * @exception ClassNotFoundException if the requested class does not exist
+ * on this loader's classpath.
+ */
+ @Override
+ public Class<?> findClass(final String name) throws ClassNotFoundException {
+ log("Finding class " + name, Project.MSG_DEBUG);
+ return findClassInComponents(name);
+ }
+
+ /**
+ * Indicate if the given file is in this loader's path
+ *
+ * @param component the file which is to be checked
+ *
+ * @return true if the file is in the class path
+ */
+ protected boolean isInPath(final File component) {
+ return pathComponents.contains(component);
+ }
+
+ /**
+ * Finds a class on the given classpath.
+ *
+ * @param name The name of the class to be loaded. Must not be
+ * <code>null</code>.
+ *
+ * @return the required Class object
+ *
+ * @exception ClassNotFoundException if the requested class does not exist
+ * on this loader's classpath.
+ */
+ private Class<?> findClassInComponents(final String name)
+ throws ClassNotFoundException {
+ // we need to search the components of the path to see if
+ // we can find the class we want.
+ final String classFilename = getClassFilename(name);
+ final Enumeration<File> e = pathComponents.elements();
+ while (e.hasMoreElements()) {
+ final File pathComponent = e.nextElement();
+ InputStream stream = null;
+ try {
+ stream = getResourceStream(pathComponent, classFilename);
+ if (stream != null) {
+ log("Loaded from " + pathComponent + " "
+ + classFilename, Project.MSG_DEBUG);
+ return getClassFromStream(stream, name, pathComponent);
+ }
+ } catch (final SecurityException se) {
+ throw se;
+ } catch (final IOException ioe) {
+ // ioe.printStackTrace();
+ log("Exception reading component " + pathComponent + " (reason: "
+ + ioe.getMessage() + ")", Project.MSG_VERBOSE);
+ } finally {
+ FileUtils.close(stream);
+ }
+ }
+ throw new ClassNotFoundException(name);
+ }
+
+ /**
+ * Finds a system class (which should be loaded from the same classloader
+ * as the Ant core).
+ *
+ * For JDK 1.1 compatibility, this uses the findSystemClass method if
+ * no parent classloader has been specified.
+ *
+ * @param name The name of the class to be loaded.
+ * Must not be <code>null</code>.
+ *
+ * @return the required Class object
+ *
+ * @exception ClassNotFoundException if the requested class does not exist
+ * on this loader's classpath.
+ */
+ private Class<?> findBaseClass(final String name) throws ClassNotFoundException {
+ return parent == null ? findSystemClass(name) : parent.loadClass(name);
+ }
+
+ /**
+ * Cleans up any resources held by this classloader. Any open archive
+ * files are closed.
+ */
+ public synchronized void cleanup() {
+ for (final Enumeration<JarFile> e = jarFiles.elements(); e.hasMoreElements();) {
+ final JarFile jarFile = e.nextElement();
+ try {
+ jarFile.close();
+ } catch (final IOException ioe) {
+ // ignore
+ }
+ }
+ jarFiles = new Hashtable<File, JarFile>();
+ if (project != null) {
+ project.removeBuildListener(this);
+ }
+ project = null;
+ }
+
+ /**
+ * Gets the parent as has been specified in the constructor or via
+ * setParent.
+ *
+ * @return classloader
+ * @since Ant 1.8.0
+ */
+ public ClassLoader getConfiguredParent() {
+ return parent;
+ }
+
+ /**
+ * Empty implementation to satisfy the BuildListener interface.
+ *
+ * @param event the buildStarted event
+ */
+ public void buildStarted(final BuildEvent event) {
+ // Not significant for the class loader.
+ }
+
+ /**
+ * Cleans up any resources held by this classloader at the end
+ * of a build.
+ *
+ * @param event the buildFinished event
+ */
+ public void buildFinished(final BuildEvent event) {
+ cleanup();
+ }
+
+ /**
+ * Cleans up any resources held by this classloader at the end of
+ * a subbuild if it has been created for the subbuild's project
+ * instance.
+ *
+ * @param event the buildFinished event
+ *
+ * @since Ant 1.6.2
+ */
+ public void subBuildFinished(final BuildEvent event) {
+ if (event.getProject() == project) {
+ cleanup();
+ }
+ }
+
+ /**
+ * Empty implementation to satisfy the BuildListener interface.
+ *
+ * @param event the buildStarted event
+ *
+ * @since Ant 1.6.2
+ */
+ public void subBuildStarted(final BuildEvent event) {
+ // Not significant for the class loader.
+ }
+
+ /**
+ * Empty implementation to satisfy the BuildListener interface.
+ *
+ * @param event the targetStarted event
+ */
+ public void targetStarted(final BuildEvent event) {
+ // Not significant for the class loader.
+ }
+
+ /**
+ * Empty implementation to satisfy the BuildListener interface.
+ *
+ * @param event the targetFinished event
+ */
+ public void targetFinished(final BuildEvent event) {
+ // Not significant for the class loader.
+ }
+
+ /**
+ * Empty implementation to satisfy the BuildListener interface.
+ *
+ * @param event the taskStarted event
+ */
+ public void taskStarted(final BuildEvent event) {
+ // Not significant for the class loader.
+ }
+
+ /**
+ * Empty implementation to satisfy the BuildListener interface.
+ *
+ * @param event the taskFinished event
+ */
+ public void taskFinished(final BuildEvent event) {
+ // Not significant for the class loader.
+ }
+
+ /**
+ * Empty implementation to satisfy the BuildListener interface.
+ *
+ * @param event the messageLogged event
+ */
+ public void messageLogged(final BuildEvent event) {
+ // Not significant for the class loader.
+ }
+
+ /**
+ * add any libraries that come with different java versions
+ * here
+ */
+ public void addJavaLibraries() {
+ final Vector<String> packages = JavaEnvUtils.getJrePackages();
+ final Enumeration<String> e = packages.elements();
+ while (e.hasMoreElements()) {
+ final String packageName = e.nextElement();
+ addSystemPackageRoot(packageName);
+ }
+ }
+
+ /**
+ * Returns a <code>String</code> representing this loader.
+ * @return the path that this classloader has.
+ */
+ @Override
+ public String toString() {
+ return "AntClassLoader[" + getClasspath() + "]";
+ }
+
+ private static Class<?> subClassToLoad = null;
+ private static final Class<?>[] CONSTRUCTOR_ARGS = new Class[] {
+ ClassLoader.class, Project.class, Path.class, Boolean.TYPE
+ };
+
+ static {
+ if (JavaEnvUtils.isAtLeastJavaVersion(JavaEnvUtils.JAVA_1_5)) {
+ try {
+ subClassToLoad =
+ Class.forName("org.apache.tools.ant.loader.AntClassLoader5");
+ } catch (final ClassNotFoundException e) {
+ // this is Java5 but the installation is lacking our subclass
+ }
+ }
+ }
+
+ /**
+ * Factory method
+ */
+ public static AntClassLoader newAntClassLoader(final ClassLoader parent,
+ final Project project,
+ final Path path,
+ final boolean parentFirst) {
+ if (subClassToLoad != null) {
+ return (AntClassLoader)
+ ReflectUtil.newInstance(subClassToLoad,
+ CONSTRUCTOR_ARGS,
+ new Object[] {
+ parent, project, path,
+ Boolean.valueOf(parentFirst)
+ });
+ }
+ return new AntClassLoader(parent, project, path, parentFirst);
+ }
+
+ private static final ZipLong EOCD_SIG = new ZipLong(0X06054B50L);
+ private static final ZipLong SINGLE_SEGMENT_SPLIT_MARKER =
+ new ZipLong(0X30304B50L);
+
+ private static boolean isZip(final File file) throws IOException {
+ final byte[] sig = new byte[4];
+ if (readFully(file, sig)) {
+ final ZipLong start = new ZipLong(sig);
+ return ZipLong.LFH_SIG.equals(start) // normal file
+ || EOCD_SIG.equals(start) // empty zip
+ || ZipLong.DD_SIG.equals(start) // split zip
+ || SINGLE_SEGMENT_SPLIT_MARKER.equals(start);
+ }
+ return false;
+ }
+
+ private static boolean readFully(final File f, final byte[] b) throws IOException {
+ final FileInputStream fis = new FileInputStream(f);
+ try {
+ final int len = b.length;
+ int count = 0, x = 0;
+ while (count != len) {
+ x = fis.read(b, count, len - count);
+ if (x == -1) {
+ break;
+ }
+ count += x;
+ }
+ return count == len;
+ } finally {
+ fis.close();
+ }
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/AntTypeDefinition.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/AntTypeDefinition.java
new file mode 100644
index 00000000..104820f1
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/AntTypeDefinition.java
@@ -0,0 +1,389 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+
+
+/**
+ * This class contains all the information
+ * on a particular ant type,
+ * the classname, adapter and the class
+ * it should be assignable from.
+ * This type replaces the task/datatype split
+ * of pre ant 1.6.
+ *
+ */
+public class AntTypeDefinition {
+ private String name;
+ private Class<?> clazz;
+ private Class<?> adapterClass;
+ private Class<?> adaptToClass;
+ private String className;
+ private ClassLoader classLoader;
+ private boolean restrict = false;
+
+ /**
+ * Set the restrict attribute.
+ * @param restrict the value to set.
+ */
+ public void setRestrict(boolean restrict) {
+ this.restrict = restrict;
+ }
+
+ /**
+ * Get the restrict attribute.
+ * @return the restrict attribute.
+ */
+ public boolean isRestrict() {
+ return restrict;
+ }
+
+ /**
+ * Set the definition's name.
+ * @param name the name of the definition.
+ */
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ /**
+ * Return the definition's name.
+ * @return the name of the definition.
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Set the class of the definition.
+ * As a side-effect may set the classloader and classname.
+ * @param clazz the class of this definition.
+ */
+ public void setClass(Class<?> clazz) {
+ this.clazz = clazz;
+ if (clazz == null) {
+ return;
+ }
+ this.classLoader = (classLoader == null)
+ ? clazz.getClassLoader() : classLoader;
+ this.className = (className == null) ? clazz.getName() : className;
+ }
+
+ /**
+ * Set the classname of the definition.
+ * @param className the classname of this definition.
+ */
+ public void setClassName(String className) {
+ this.className = className;
+ }
+
+ /**
+ * Get the classname of the definition.
+ * @return the name of the class of this definition.
+ */
+ public String getClassName() {
+ return className;
+ }
+
+ /**
+ * Set the adapter class for this definition.
+ * This class is used to adapt the definitions class if
+ * required.
+ * @param adapterClass the adapterClass.
+ */
+ public void setAdapterClass(Class<?> adapterClass) {
+ this.adapterClass = adapterClass;
+ }
+
+ /**
+ * Set the assignable class for this definition.
+ * @param adaptToClass the assignable class.
+ */
+
+ public void setAdaptToClass(Class<?> adaptToClass) {
+ this.adaptToClass = adaptToClass;
+ }
+
+ /**
+ * Set the classloader to use to create an instance
+ * of the definition.
+ * @param classLoader the ClassLoader.
+ */
+ public void setClassLoader(ClassLoader classLoader) {
+ this.classLoader = classLoader;
+ }
+
+ /**
+ * Get the classloader for this definition.
+ * @return the classloader for this definition.
+ */
+ public ClassLoader getClassLoader() {
+ return classLoader;
+ }
+
+ /**
+ * Get the exposed class for this
+ * definition. This will be a proxy class
+ * (adapted class) if there is an adapter
+ * class and the definition class is not
+ * assignable from the assignable class.
+ * @param project the current project.
+ * @return the exposed class - may return null if unable to load the class
+ */
+ public Class<?> getExposedClass(Project project) {
+ if (adaptToClass != null) {
+ Class<?> z = getTypeClass(project);
+ if (z == null || adaptToClass.isAssignableFrom(z)) {
+ return z;
+ }
+ }
+ return (adapterClass == null) ? getTypeClass(project) : adapterClass;
+ }
+
+ /**
+ * Get the definition class.
+ * @param project the current project.
+ * @return the type of the definition.
+ */
+ public Class<?> getTypeClass(Project project) {
+ try {
+ return innerGetTypeClass();
+ } catch (NoClassDefFoundError ncdfe) {
+ project.log("Could not load a dependent class ("
+ + ncdfe.getMessage() + ") for type "
+ + name, Project.MSG_DEBUG);
+ } catch (ClassNotFoundException cnfe) {
+ project.log("Could not load class (" + className
+ + ") for type " + name, Project.MSG_DEBUG);
+ }
+ return null;
+ }
+
+ /**
+ * Try and load a class, with no attempt to catch any fault.
+ * @return the class that implements this component
+ * @throws ClassNotFoundException if the class cannot be found.
+ * @throws NoClassDefFoundError if the there is an error
+ * finding the class.
+ */
+ public Class<?> innerGetTypeClass() throws ClassNotFoundException {
+ if (clazz != null) {
+ return clazz;
+ }
+ if (classLoader == null) {
+ clazz = Class.forName(className);
+ } else {
+ clazz = classLoader.loadClass(className);
+ }
+ return clazz;
+ }
+
+ /**
+ * Create an instance of the definition.
+ * The instance may be wrapped in a proxy class.
+ * @param project the current project.
+ * @return the created object.
+ */
+ public Object create(Project project) {
+ return icreate(project);
+ }
+
+ /**
+ * Create a component object based on
+ * its definition.
+ * @return the component as an <code>Object</code>.
+ */
+ private Object icreate(Project project) {
+ Class<?> c = getTypeClass(project);
+ if (c == null) {
+ return null;
+ }
+ Object o = createAndSet(project, c);
+ if (o == null || adapterClass == null) {
+ return o;
+ }
+ if (adaptToClass != null) {
+ if (adaptToClass.isAssignableFrom(o.getClass())) {
+ return o;
+ }
+ }
+ TypeAdapter adapterObject = (TypeAdapter) createAndSet(
+ project, adapterClass);
+ if (adapterObject == null) {
+ return null;
+ }
+ adapterObject.setProxy(o);
+ return adapterObject;
+ }
+
+ /**
+ * Checks if the attributes are correct.
+ * <ul>
+ * <li>if the class can be created.</li>
+ * <li>if an adapter class can be created</li>
+ * <li>if the type is assignable from adapter</li>
+ * <li>if the type can be used with the adapter class</li>
+ * </ul>
+ * @param project the current project.
+ */
+ public void checkClass(Project project) {
+ if (clazz == null) {
+ clazz = getTypeClass(project);
+ if (clazz == null) {
+ throw new BuildException(
+ "Unable to create class for " + getName());
+ }
+ }
+ // check adapter
+ if (adapterClass != null && (adaptToClass == null
+ || !adaptToClass.isAssignableFrom(clazz))) {
+ TypeAdapter adapter = (TypeAdapter) createAndSet(
+ project, adapterClass);
+ if (adapter == null) {
+ throw new BuildException("Unable to create adapter object");
+ }
+ adapter.checkProxyClass(clazz);
+ }
+ }
+
+ /**
+ * Get the constructor of the definition
+ * and invoke it.
+ * @return the instantiated <code>Object</code>.
+ */
+ private Object createAndSet(Project project, Class<?> c) {
+ try {
+ Object o = innerCreateAndSet(c, project);
+ return o;
+ } catch (InvocationTargetException ex) {
+ Throwable t = ex.getTargetException();
+ throw new BuildException(
+ "Could not create type " + name + " due to " + t, t);
+ } catch (NoClassDefFoundError ncdfe) {
+ String msg = "Type " + name + ": A class needed by class "
+ + c + " cannot be found: " + ncdfe.getMessage();
+ throw new BuildException(msg, ncdfe);
+ } catch (NoSuchMethodException nsme) {
+ throw new BuildException("Could not create type " + name
+ + " as the class " + c + " has no compatible constructor");
+ } catch (InstantiationException nsme) {
+ throw new BuildException("Could not create type "
+ + name + " as the class " + c + " is abstract");
+ } catch (IllegalAccessException e) {
+ throw new BuildException("Could not create type "
+ + name + " as the constructor " + c + " is not accessible");
+ } catch (Throwable t) {
+ throw new BuildException(
+ "Could not create type " + name + " due to " + t, t);
+ }
+ }
+
+ /**
+ * Inner implementation of the {@link #createAndSet(Project, Class)} logic, with no
+ * exception catching.
+ * @param <T> return type of the method
+ * @param newclass class to create
+ * @param project the project to use
+ * @return a newly constructed and bound instance.
+ * @throws NoSuchMethodException no good constructor.
+ * @throws InstantiationException cannot initialize the object.
+ * @throws IllegalAccessException cannot access the object.
+ * @throws InvocationTargetException error in invocation.
+ */
+ public <T> T innerCreateAndSet(Class<T> newclass, Project project)
+ throws NoSuchMethodException,
+ InstantiationException,
+ IllegalAccessException,
+ InvocationTargetException {
+ Constructor<T> ctor;
+ boolean noArg = false;
+ // DataType can have a "no arg" constructor or take a single
+ // Project argument.
+ try {
+ ctor = newclass.getConstructor(new Class[0]);
+ noArg = true;
+ } catch (NoSuchMethodException nse) {
+ //can throw the same exception, if there is no this(Project) ctor.
+ ctor = newclass.getConstructor(new Class[] {Project.class});
+ noArg = false;
+ }
+ //now we instantiate
+ T o = ctor.newInstance(
+ ((noArg) ? new Object[0] : new Object[] {project}));
+
+ //set up project references.
+ project.setProjectReference(o);
+ return o;
+ }
+
+ /**
+ * Equality method for this definition (assumes the names are the same).
+ *
+ * @param other another definition.
+ * @param project the project the definition.
+ * @return true if the definitions are the same.
+ */
+ public boolean sameDefinition(AntTypeDefinition other, Project project) {
+ return (other != null && other.getClass() == getClass()
+ && other.getTypeClass(project).equals(getTypeClass(project))
+ && other.getExposedClass(project).equals(getExposedClass(project))
+ && other.restrict == restrict
+ && other.adapterClass == adapterClass
+ && other.adaptToClass == adaptToClass);
+ }
+
+ /**
+ * Similar definition;
+ * used to compare two definitions defined twice with the same
+ * name and the same types.
+ * The classloader may be different but have the same
+ * path so #sameDefinition cannot
+ * be used.
+ * @param other the definition to compare to.
+ * @param project the current project.
+ * @return true if the definitions are the same.
+ */
+ public boolean similarDefinition(AntTypeDefinition other, Project project) {
+ if (other == null
+ || getClass() != other.getClass()
+ || !getClassName().equals(other.getClassName())
+ || !extractClassname(adapterClass).equals(
+ extractClassname(other.adapterClass))
+ || !extractClassname(adaptToClass).equals(
+ extractClassname(other.adaptToClass))
+ || restrict != other.restrict) {
+ return false;
+ }
+ // all the names are the same: check if the class path of the loader
+ // is the same
+ ClassLoader oldLoader = other.getClassLoader();
+ ClassLoader newLoader = getClassLoader();
+ return oldLoader == newLoader
+ || (oldLoader instanceof AntClassLoader
+ && newLoader instanceof AntClassLoader
+ && ((AntClassLoader) oldLoader).getClasspath()
+ .equals(((AntClassLoader) newLoader).getClasspath()));
+ }
+
+ private String extractClassname(Class<?> c) {
+ return (c == null) ? "<null>" : c.getClass().getName();
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/ArgumentProcessor.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/ArgumentProcessor.java
new file mode 100644
index 00000000..07812f2f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/ArgumentProcessor.java
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant;
+
+import java.io.PrintStream;
+import java.util.List;
+
+/**
+ * Processor of arguments of the command line.
+ * <p>
+ * Arguments supported by third party code should not conflict with Ant core
+ * ones. It is then recommended to chose specific 'enough' argument name,
+ * avoiding for instance one letter arguments. By the way, if there any
+ * conflict, Ant will take precedence.
+ *
+ * @since 1.9
+ */
+public interface ArgumentProcessor {
+
+ /**
+ * Read the arguments from the command line at the specified position
+ * <p>
+ * If the argument is not supported, returns -1. Else, the position of the
+ * first argument not supported.
+ */
+ int readArguments(String[] args, int pos);
+
+ /**
+ * If some arguments matched with {@link #readArguments(String[], int)},
+ * this method is called after all arguments were parsed. Returns
+ * <code>true</code> if Ant should stop there, ie the build file not parsed
+ * and the project should not be executed.
+ */
+ boolean handleArg(List<String> args);
+
+ /**
+ * If some arguments matched with {@link #readArguments(String[], int)},
+ * this method is called just before the project being configured
+ */
+ void prepareConfigure(Project project, List<String> args);
+
+ /**
+ * Handle the arguments with {@link #readArguments(String[], int)}, just
+ * after the project being configured. Returns <code>true</code> if Ant
+ * should stop there, ie the build file not parsed and the project should
+ * not be executed.
+ */
+ boolean handleArg(Project project, List<String> arg);
+
+ /**
+ * Print the usage of the supported arguments
+ *
+ * @see org.apache.tools.ant.Main#printUsage()
+ */
+ void printUsage(PrintStream writer);
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/ArgumentProcessorRegistry.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/ArgumentProcessorRegistry.java
new file mode 100644
index 00000000..bdb7c0a8
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/ArgumentProcessorRegistry.java
@@ -0,0 +1,171 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+
+import org.apache.tools.ant.util.LoaderUtils;
+
+/**
+ * The global registry for {@link ArgumentProcessor}s.
+ * <p>
+ * An {@link ArgumentProcessor} implementation can be registered via the system
+ * property <code>org.apache.tools.ant.ArgumentProcessor</code>, or via a JDK1.3
+ * 'service', by putting the fully qualified name of the implementation into the
+ * file <code>META-INF/services/org.apache.tools.ant.ArgumentProcessor</code>
+ * <p>
+ * Use the system property <code>ant.argument-processor.debug</code> to enable
+ * the print of debug log.
+ *
+ * @since 1.9
+ */
+public class ArgumentProcessorRegistry {
+
+ private static final String DEBUG_ARGUMENT_PROCESSOR_REPOSITORY = "ant.argument-processor-repo.debug";
+
+ // The message log level is not accessible here because everything
+ // is instanciated statically
+ private static final boolean DEBUG = "true".equals(System.getProperty(DEBUG_ARGUMENT_PROCESSOR_REPOSITORY));
+
+ private static final String SERVICE_ID = "META-INF/services/org.apache.tools.ant.ArgumentProcessor";
+
+ private static ArgumentProcessorRegistry instance = new ArgumentProcessorRegistry();
+
+ private List<ArgumentProcessor> processors = new ArrayList<ArgumentProcessor>();
+
+ public static ArgumentProcessorRegistry getInstance() {
+ return instance;
+ }
+
+ private ArgumentProcessorRegistry() {
+ collectArgumentProcessors();
+ }
+
+ public List<ArgumentProcessor> getProcessors() {
+ return processors;
+ }
+
+ private void collectArgumentProcessors() {
+ try {
+ ClassLoader classLoader = LoaderUtils.getContextClassLoader();
+ if (classLoader != null) {
+ Enumeration<URL> resources = classLoader.getResources(SERVICE_ID);
+ while (resources.hasMoreElements()) {
+ URL resource = resources.nextElement();
+ URLConnection conn = resource.openConnection();
+ conn.setUseCaches(false);
+ ArgumentProcessor processor = getProcessorByService(conn.getInputStream());
+ registerArgumentProcessor(processor);
+ }
+ }
+
+ InputStream systemResource = ClassLoader.getSystemResourceAsStream(SERVICE_ID);
+ if (systemResource != null) {
+ ArgumentProcessor processor = getProcessorByService(systemResource);
+ registerArgumentProcessor(processor);
+ }
+ } catch (Exception e) {
+ System.err.println("Unable to load ArgumentProcessor from service "
+ + SERVICE_ID + " (" + e.getClass().getName() + ": "
+ + e.getMessage() + ")");
+ if (DEBUG) {
+ e.printStackTrace(System.err);
+ }
+ }
+ }
+
+ public void registerArgumentProcessor(String helperClassName)
+ throws BuildException {
+ registerArgumentProcessor(getProcessor(helperClassName));
+ }
+
+ public void registerArgumentProcessor(
+ Class< ? extends ArgumentProcessor> helperClass)
+ throws BuildException {
+ registerArgumentProcessor(getProcessor(helperClass));
+ }
+
+ private ArgumentProcessor getProcessor(String helperClassName) {
+ try {
+ @SuppressWarnings("unchecked")
+ Class< ? extends ArgumentProcessor> cl = (Class< ? extends ArgumentProcessor>) Class.forName(helperClassName);
+ return getProcessor(cl);
+ } catch (ClassNotFoundException e) {
+ throw new BuildException("Argument processor class "
+ + helperClassName + " was not found", e);
+ }
+ }
+
+ private ArgumentProcessor getProcessor(
+ Class< ? extends ArgumentProcessor> processorClass) {
+ ArgumentProcessor processor;
+ try {
+ processor = processorClass.getConstructor().newInstance();
+ } catch (Exception e) {
+ throw new BuildException("The argument processor class"
+ + processorClass.getClass().getName()
+ + " could not be instanciated with a default constructor",
+ e);
+ }
+ return processor;
+ }
+
+ public void registerArgumentProcessor(ArgumentProcessor processor) {
+ if (processor == null) {
+ return;
+ }
+ processors.add(processor);
+ if (DEBUG) {
+ System.out.println("Argument processor "
+ + processor.getClass().getName() + " registered.");
+ }
+ }
+
+ private ArgumentProcessor getProcessorByService(InputStream is)
+ throws IOException {
+ InputStreamReader isr = null;
+ try {
+ try {
+ isr = new InputStreamReader(is, "UTF-8");
+ } catch (java.io.UnsupportedEncodingException e) {
+ isr = new InputStreamReader(is);
+ }
+ BufferedReader rd = new BufferedReader(isr);
+ String processorClassName = rd.readLine();
+ if (processorClassName != null && !"".equals(processorClassName)) {
+ return getProcessor(processorClassName);
+ }
+ } finally {
+ try {
+ isr.close();
+ } catch (IOException e) {
+ // ignore
+ }
+ }
+ return null;
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/BuildEvent.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/BuildEvent.java
new file mode 100644
index 00000000..623ad1e6
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/BuildEvent.java
@@ -0,0 +1,203 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant;
+
+import java.util.EventObject;
+
+/**
+ * Class representing an event occurring during a build. An
+ * event is built by specifying either a project, a task or a target.
+ * A project level event will only have a project reference;
+ * a target level event will have project and target references;
+ * a task level event will have project, target and task references.
+ *
+ */
+public class BuildEvent extends EventObject {
+
+ private static final long serialVersionUID = 4538050075952288486L;
+
+ /** Project which emitted the event. */
+ private final Project project;
+ /** Target which emitted the event, if specified. */
+ private final Target target;
+ /** Task which emitted the event, if specified. */
+ private final Task task;
+ /**
+ * Message associated with the event. This is only used for
+ * "messageLogged" events.
+ */
+ private String message;
+ /**
+ * The priority of the message, for "messageLogged" events.
+ */
+ private int priority = Project.MSG_VERBOSE;
+ /**
+ * The exception associated with this event, if any.
+ * This is only used for "messageLogged", "taskFinished", "targetFinished",
+ * and "buildFinished" events.
+ */
+ private Throwable exception;
+
+ /**
+ * Construct a BuildEvent for a project level event.
+ *
+ * @param project the project that emitted the event.
+ * Should not be <code>null</code>.
+ */
+ public BuildEvent(Project project) {
+ super(project);
+ this.project = project;
+ this.target = null;
+ this.task = null;
+ }
+
+ /**
+ * Construct a BuildEvent for a target level event.
+ * The project associated with the event is derived
+ * from the given target.
+ *
+ * @param target the target that emitted the event.
+ * Must not be <code>null</code>.
+ */
+ public BuildEvent(Target target) {
+ super(target);
+ this.project = target.getProject();
+ this.target = target;
+ this.task = null;
+ }
+
+ /**
+ * Construct a BuildEvent for a task level event.
+ * The project and target associated with the event
+ * are derived from the given task.
+ *
+ * @param task the task that emitted the event.
+ * Must not be <code>null</code>.
+ */
+ public BuildEvent(Task task) {
+ super(task);
+ this.project = task.getProject();
+ this.target = task.getOwningTarget();
+ this.task = task;
+ }
+
+ /**
+ * Sets the message and priority associated with this event.
+ * This is used for "messageLogged" events.
+ *
+ * @param message the message to be associated with this event.
+ * Should not be <code>null</code>.
+ * @param priority the priority to be associated with this event,
+ * as defined in the {@link Project Project} class.
+ *
+ * @see BuildListener#messageLogged(BuildEvent)
+ */
+ public void setMessage(String message, int priority) {
+ this.message = message;
+ this.priority = priority;
+ }
+
+ /**
+ * Sets the exception associated with this event. This is used
+ * for "messageLogged", "taskFinished", "targetFinished", and "buildFinished"
+ * events.
+ *
+ * @param exception The exception to be associated with this event.
+ * May be <code>null</code>.
+ *
+ * @see BuildListener#messageLogged(BuildEvent)
+ * @see BuildListener#taskFinished(BuildEvent)
+ * @see BuildListener#targetFinished(BuildEvent)
+ * @see BuildListener#buildFinished(BuildEvent)
+ */
+ public void setException(Throwable exception) {
+ this.exception = exception;
+ }
+
+ /**
+ * Returns the project that fired this event.
+ *
+ * @return the project that fired this event
+ */
+ public Project getProject() {
+ return project;
+ }
+
+ /**
+ * Returns the target that fired this event.
+ *
+ * @return the project that fired this event, or <code>null</code>
+ * if this event is a project level event.
+ */
+ public Target getTarget() {
+ return target;
+ }
+
+ /**
+ * Returns the task that fired this event.
+ *
+ * @return the task that fired this event, or <code>null</code>
+ * if this event is a project or target level event.
+ */
+ public Task getTask() {
+ return task;
+ }
+
+ /**
+ * Returns the logging message. This field will only be set
+ * for "messageLogged" events.
+ *
+ * @return the message associated with this event, or <code>null</code>
+ * if no message has been set.
+ *
+ * @see BuildListener#messageLogged(BuildEvent)
+ */
+ public String getMessage() {
+ return message;
+ }
+
+ /**
+ * Returns the priority of the logging message. This field will only
+ * be set for "messageLogged" events. The meaning of this priority
+ * is as specified by the constants in the {@link Project Project} class.
+ *
+ * @return the priority associated with this event.
+ *
+ * @see BuildListener#messageLogged(BuildEvent)
+ */
+ public int getPriority() {
+ return priority;
+ }
+
+ /**
+ * Returns the exception that was thrown, if any. This field will only
+ * be set for "messageLogged", "taskFinished", "targetFinished", and "buildFinished"
+ * events.
+ *
+ * @return the exception associated with this exception, or
+ * <code>null</code> if no exception has been set.
+ *
+ * @see BuildListener#messageLogged(BuildEvent)
+ * @see BuildListener#taskFinished(BuildEvent)
+ * @see BuildListener#targetFinished(BuildEvent)
+ * @see BuildListener#buildFinished(BuildEvent)
+ */
+ public Throwable getException() {
+ return exception;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/BuildException.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/BuildException.java
new file mode 100644
index 00000000..34c16051
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/BuildException.java
@@ -0,0 +1,153 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant;
+
+/**
+ * Signals an error condition during a build
+ */
+public class BuildException extends RuntimeException {
+
+ private static final long serialVersionUID = -5419014565354664240L;
+
+ /** Location in the build file where the exception occurred */
+ private Location location = Location.UNKNOWN_LOCATION;
+
+ /**
+ * Constructs a build exception with no descriptive information.
+ */
+ public BuildException() {
+ super();
+ }
+
+ /**
+ * Constructs an exception with the given descriptive message.
+ *
+ * @param message A description of or information about the exception.
+ * Should not be <code>null</code>.
+ */
+ public BuildException(String message) {
+ super(message);
+ }
+
+ /**
+ * Constructs an exception with the given message and exception as
+ * a root cause.
+ *
+ * @param message A description of or information about the exception.
+ * Should not be <code>null</code> unless a cause is specified.
+ * @param cause The exception that might have caused this one.
+ * May be <code>null</code>.
+ */
+ public BuildException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ /**
+ * Constructs an exception with the given message and exception as
+ * a root cause and a location in a file.
+ *
+ * @param msg A description of or information about the exception.
+ * Should not be <code>null</code> unless a cause is specified.
+ * @param cause The exception that might have caused this one.
+ * May be <code>null</code>.
+ * @param location The location in the project file where the error
+ * occurred. Must not be <code>null</code>.
+ */
+ public BuildException(String msg, Throwable cause, Location location) {
+ this(msg, cause);
+ this.location = location;
+ }
+
+ /**
+ * Constructs an exception with the given exception as a root cause.
+ *
+ * @param cause The exception that might have caused this one.
+ * Should not be <code>null</code>.
+ */
+ public BuildException(Throwable cause) {
+ super(cause);
+ }
+
+ /**
+ * Constructs an exception with the given descriptive message and a
+ * location in a file.
+ *
+ * @param message A description of or information about the exception.
+ * Should not be <code>null</code>.
+ * @param location The location in the project file where the error
+ * occurred. Must not be <code>null</code>.
+ */
+ public BuildException(String message, Location location) {
+ super(message);
+ this.location = location;
+ }
+
+ /**
+ * Constructs an exception with the given exception as
+ * a root cause and a location in a file.
+ *
+ * @param cause The exception that might have caused this one.
+ * Should not be <code>null</code>.
+ * @param location The location in the project file where the error
+ * occurred. Must not be <code>null</code>.
+ */
+ public BuildException(Throwable cause, Location location) {
+ this(cause);
+ this.location = location;
+ }
+
+ /**
+ * Returns the nested exception, if any.
+ *
+ * @return the nested exception, or <code>null</code> if no
+ * exception is associated with this one
+ * @deprecated Use {@link #getCause} instead.
+ */
+ public Throwable getException() {
+ return getCause();
+ }
+
+ /**
+ * Returns the location of the error and the error message.
+ *
+ * @return the location of the error and the error message
+ */
+ public String toString() {
+ return location.toString() + getMessage();
+ }
+
+ /**
+ * Sets the file location where the error occurred.
+ *
+ * @param location The file location where the error occurred.
+ * Must not be <code>null</code>.
+ */
+ public void setLocation(Location location) {
+ this.location = location;
+ }
+
+ /**
+ * Returns the file location where the error occurred.
+ *
+ * @return the file location where the error occurred.
+ */
+ public Location getLocation() {
+ return location;
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/BuildListener.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/BuildListener.java
new file mode 100644
index 00000000..ed6731cf
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/BuildListener.java
@@ -0,0 +1,110 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant;
+
+import java.util.EventListener;
+
+/**
+ * Instances of classes that implement this interface can register
+ * to be notified when things happened during a build.
+ *
+ * @see BuildEvent
+ * @see Project#addBuildListener(BuildListener)
+ *
+ */
+public interface BuildListener extends EventListener {
+
+ /**
+ * Signals that a build has started. This event
+ * is fired before any targets have started.
+ *
+ * <p>This event is fired before the project instance is fully
+ * configured. In particular no properties have been set and the
+ * project may not know its name or default target, yet.</p>
+ *
+ * @param event An event with any relevant extra information.
+ * Must not be <code>null</code>.
+ */
+ void buildStarted(BuildEvent event);
+
+ /**
+ * Signals that the last target has finished. This event
+ * will still be fired if an error occurred during the build.
+ *
+ * @param event An event with any relevant extra information.
+ * Must not be <code>null</code>.
+ *
+ * @see BuildEvent#getException()
+ */
+ void buildFinished(BuildEvent event);
+
+ /**
+ * Signals that a target is starting.
+ *
+ * @param event An event with any relevant extra information.
+ * Must not be <code>null</code>.
+ *
+ * @see BuildEvent#getTarget()
+ */
+ void targetStarted(BuildEvent event);
+
+ /**
+ * Signals that a target has finished. This event will
+ * still be fired if an error occurred during the build.
+ *
+ * @param event An event with any relevant extra information.
+ * Must not be <code>null</code>.
+ *
+ * @see BuildEvent#getException()
+ */
+ void targetFinished(BuildEvent event);
+
+ /**
+ * Signals that a task is starting.
+ *
+ * @param event An event with any relevant extra information.
+ * Must not be <code>null</code>.
+ *
+ * @see BuildEvent#getTask()
+ */
+ void taskStarted(BuildEvent event);
+
+ /**
+ * Signals that a task has finished. This event will still
+ * be fired if an error occurred during the build.
+ *
+ * @param event An event with any relevant extra information.
+ * Must not be <code>null</code>.
+ *
+ * @see BuildEvent#getException()
+ */
+ void taskFinished(BuildEvent event);
+
+ /**
+ * Signals a message logging event.
+ *
+ * @param event An event with any relevant extra information.
+ * Must not be <code>null</code>.
+ *
+ * @see BuildEvent#getMessage()
+ * @see BuildEvent#getException()
+ * @see BuildEvent#getPriority()
+ */
+ void messageLogged(BuildEvent event);
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/BuildLogger.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/BuildLogger.java
new file mode 100644
index 00000000..249d8f51
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/BuildLogger.java
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant;
+
+import java.io.PrintStream;
+
+/**
+ * Interface used by Ant to log the build output.
+ *
+ * A build logger is a build listener which has the 'right' to send output to
+ * the ant log, which is usually <code>System.out</code> unless redirected by
+ * the <code>-logfile</code> option.
+ *
+ */
+public interface BuildLogger extends BuildListener {
+
+ /**
+ * Sets the highest level of message this logger should respond to.
+ *
+ * Only messages with a message level lower than or equal to the
+ * given level should be written to the log.
+ * <P>
+ * Constants for the message levels are in the
+ * {@link Project Project} class. The order of the levels, from least
+ * to most verbose, is <code>MSG_ERR</code>, <code>MSG_WARN</code>,
+ * <code>MSG_INFO</code>, <code>MSG_VERBOSE</code>,
+ * <code>MSG_DEBUG</code>.
+ *
+ * @param level the logging level for the logger.
+ */
+ void setMessageOutputLevel(int level);
+
+ /**
+ * Sets the output stream to which this logger is to send its output.
+ *
+ * @param output The output stream for the logger.
+ * Must not be <code>null</code>.
+ */
+ void setOutputPrintStream(PrintStream output);
+
+ /**
+ * Sets this logger to produce emacs (and other editor) friendly output.
+ *
+ * @param emacsMode <code>true</code> if output is to be unadorned so that
+ * emacs and other editors can parse files names, etc.
+ */
+ void setEmacsMode(boolean emacsMode);
+
+ /**
+ * Sets the output stream to which this logger is to send error messages.
+ *
+ * @param err The error stream for the logger.
+ * Must not be <code>null</code>.
+ */
+ void setErrorPrintStream(PrintStream err);
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/ComponentHelper.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/ComponentHelper.java
new file mode 100644
index 00000000..eceedeef
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/ComponentHelper.java
@@ -0,0 +1,1101 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.Stack;
+
+import org.apache.tools.ant.launch.Launcher;
+import org.apache.tools.ant.taskdefs.Definer;
+import org.apache.tools.ant.taskdefs.Typedef;
+import org.apache.tools.ant.util.FileUtils;
+
+/**
+ * Component creation and configuration.
+ *
+ * The class is based around handing component
+ * definitions in an AntTypeTable.
+ *
+ * The old task/type methods have been kept
+ * for backward compatibly.
+ * Project will just delegate its calls to this class.
+ *
+ * A very simple hook mechanism is provided that allows users to plug
+ * in custom code. It is also possible to replace the default behavior
+ * ( for example in an app embedding ant )
+ *
+ * @since Ant1.6
+ */
+public class ComponentHelper {
+ /** Map of component name to lists of restricted definitions */
+ private Map<String, List<AntTypeDefinition>> restrictedDefinitions = new HashMap<String, List<AntTypeDefinition>>();
+
+ /** Map from component name to anttypedefinition */
+ private final Hashtable<String, AntTypeDefinition> antTypeTable = new Hashtable<String, AntTypeDefinition>();
+
+ /** Map of tasks generated from antTypeTable */
+ private final Hashtable<String, Class<?>> taskClassDefinitions = new Hashtable<String, Class<?>>();
+
+ /** flag to rebuild taskClassDefinitions */
+ private boolean rebuildTaskClassDefinitions = true;
+
+ /** Map of types generated from antTypeTable */
+ private final Hashtable<String, Class<?>> typeClassDefinitions = new Hashtable<String, Class<?>>();
+
+ /** flag to rebuild typeClassDefinitions */
+ private boolean rebuildTypeClassDefinitions = true;
+
+ /** Set of namespaces that have been checked for antlibs */
+ private final HashSet<String> checkedNamespaces = new HashSet<String>();
+
+ /**
+ * Stack of antlib contexts used to resolve definitions while
+ * processing antlib
+ */
+ private Stack<String> antLibStack = new Stack<String>();
+
+ /** current antlib uri */
+ private String antLibCurrentUri = null;
+
+ /**
+ * this does not appear to be used anywhere in the Ant codebase
+ * even via its accessors
+ */
+ private ComponentHelper next;
+
+ /**
+ * Project that owns a component helper
+ */
+ private Project project;
+
+ /**
+ * Error string when the file taskdefs/defaults.properties cannot be found
+ */
+ private static final String ERROR_NO_TASK_LIST_LOAD = "Can't load default task list";
+
+ /**
+ * Error string when the typedefs/defaults.properties cannot be found
+ */
+ private static final String ERROR_NO_TYPE_LIST_LOAD = "Can't load default type list";
+
+ /**
+ * reference under which we register ourselves with a project -{@value}
+ */
+ public static final String COMPONENT_HELPER_REFERENCE = "ant.ComponentHelper";
+
+ /**
+ * string used to control build.syspath policy {@value}
+ */
+ private static final String BUILD_SYSCLASSPATH_ONLY = "only";
+
+ /**
+ * special name of ant's property task -{@value}. There is some
+ * contrived work here to enable this early.
+ */
+ private static final String ANT_PROPERTY_TASK = "property";
+
+ // {tasks, types}
+ private static Properties[] defaultDefinitions = new Properties[2];
+
+ /**
+ * Get the project.
+ * @return the project owner of this helper.
+ */
+ public Project getProject() {
+ return project;
+ }
+
+ /**
+ * Find a project component for a specific project, creating
+ * it if it does not exist.
+ * @param project the project.
+ * @return the project component for a specific project.
+ */
+ public static ComponentHelper getComponentHelper(Project project) {
+ if (project == null) {
+ return null;
+ }
+ // Singleton for now, it may change ( per/classloader )
+ ComponentHelper ph = (ComponentHelper) project.getReference(COMPONENT_HELPER_REFERENCE);
+ if (ph != null) {
+ return ph;
+ }
+ ph = new ComponentHelper();
+ ph.setProject(project);
+
+ project.addReference(COMPONENT_HELPER_REFERENCE, ph);
+ return ph;
+ }
+
+ /**
+ * Creates a new ComponentHelper instance.
+ */
+ protected ComponentHelper() {
+ }
+
+ /**
+ * Set the next chained component helper.
+ *
+ * @param next the next chained component helper.
+ */
+ public void setNext(ComponentHelper next) {
+ this.next = next;
+ }
+
+ /**
+ * Get the next chained component helper.
+ *
+ * @return the next chained component helper.
+ */
+ public ComponentHelper getNext() {
+ return next;
+ }
+
+ /**
+ * Sets the project for this component helper.
+ *
+ * @param project the project for this helper.
+ */
+ public void setProject(Project project) {
+ this.project = project;
+// antTypeTable = new Hashtable<String, AntTypeDefinition>(project);
+ }
+
+ /**
+ * @return A copy of the CheckedNamespace.
+ */
+ private synchronized Set<String> getCheckedNamespace() {
+ @SuppressWarnings("unchecked")
+ final Set<String> result = (Set<String>) checkedNamespaces.clone();
+ return result;
+ }
+
+ /**
+ * @return A deep copy of the restrictredDefinition
+ */
+ private Map<String, List<AntTypeDefinition>> getRestrictedDefinition() {
+ final Map<String, List<AntTypeDefinition>> result = new HashMap<String, List<AntTypeDefinition>>();
+ synchronized (restrictedDefinitions) {
+ for (Map.Entry<String, List<AntTypeDefinition>> entry : restrictedDefinitions.entrySet()) {
+ List<AntTypeDefinition> entryVal = entry.getValue();
+ synchronized (entryVal) {
+ //copy the entryVal
+ entryVal = new ArrayList<AntTypeDefinition> (entryVal);
+ }
+ result.put(entry.getKey(), entryVal);
+ }
+ }
+ return result;
+ }
+
+
+ /**
+ * Used with creating child projects. Each child
+ * project inherits the component definitions
+ * from its parent.
+ * @param helper the component helper of the parent project.
+ */
+ public void initSubProject(ComponentHelper helper) {
+ // add the types of the parent project
+ @SuppressWarnings("unchecked")
+ final Hashtable<String, AntTypeDefinition> typeTable = (Hashtable<String, AntTypeDefinition>) helper.antTypeTable.clone();
+ synchronized (antTypeTable) {
+ for (AntTypeDefinition def : typeTable.values()) {
+ antTypeTable.put(def.getName(), def);
+ }
+ }
+ // add the parsed namespaces of the parent project
+ Set<String> inheritedCheckedNamespace = helper.getCheckedNamespace();
+ synchronized (this) {
+ checkedNamespaces.addAll(inheritedCheckedNamespace);
+ }
+ Map<String, List<AntTypeDefinition>> inheritedRestrictedDef = helper.getRestrictedDefinition();
+ synchronized (restrictedDefinitions) {
+ restrictedDefinitions.putAll(inheritedRestrictedDef);
+ }
+ }
+
+ /**
+ * Factory method to create the components.
+ *
+ * This should be called by UnknownElement.
+ *
+ * @param ue The Unknown Element creating this component.
+ * @param ns Namespace URI. Also available as ue.getNamespace().
+ * @param componentType The component type,
+ * Also available as ue.getComponentName().
+ * @return the created component.
+ * @throws BuildException if an error occurs.
+ */
+ public Object createComponent(UnknownElement ue, String ns, String componentType)
+ throws BuildException {
+ Object component = createComponent(componentType);
+ if (component instanceof Task) {
+ Task task = (Task) component;
+ task.setLocation(ue.getLocation());
+ task.setTaskType(componentType);
+ task.setTaskName(ue.getTaskName());
+ task.setOwningTarget(ue.getOwningTarget());
+ task.init();
+ }
+ return component;
+ }
+
+ /**
+ * Create an object for a component.
+ *
+ * @param componentName the name of the component, if
+ * the component is in a namespace, the
+ * name is prefixed with the namespace uri and ":".
+ * @return the class if found or null if not.
+ */
+ public Object createComponent(String componentName) {
+ AntTypeDefinition def = getDefinition(componentName);
+ return def == null ? null : def.create(project);
+ }
+
+ /**
+ * Return the class of the component name.
+ *
+ * @param componentName the name of the component, if
+ * the component is in a namespace, the
+ * name is prefixed with the namespace uri and ":".
+ * @return the class if found or null if not.
+ */
+ public Class<?> getComponentClass(String componentName) {
+ AntTypeDefinition def = getDefinition(componentName);
+ return def == null ? null : def.getExposedClass(project);
+ }
+
+ /**
+ * Return the antTypeDefinition for a componentName.
+ * @param componentName the name of the component.
+ * @return the ant definition or null if not present.
+ */
+ public AntTypeDefinition getDefinition(String componentName) {
+ checkNamespace(componentName);
+ return antTypeTable.get(componentName);
+ }
+
+ /**
+ * This method is initialization code implementing the original ant component
+ * loading from /org/apache/tools/ant/taskdefs/default.properties
+ * and /org/apache/tools/ant/types/default.properties.
+ */
+ public void initDefaultDefinitions() {
+ initTasks();
+ initTypes();
+ new DefaultDefinitions(this).execute();
+ }
+
+ /**
+ * Adds a new task definition to the project.
+ * Attempting to override an existing definition with an
+ * equivalent one (i.e. with the same classname) results in
+ * a verbose log message. Attempting to override an existing definition
+ * with a different one results in a warning log message.
+ *
+ * @param taskName The name of the task to add.
+ * Must not be <code>null</code>.
+ * @param taskClass The full name of the class implementing the task.
+ * Must not be <code>null</code>.
+ *
+ * @exception BuildException if the class is unsuitable for being an Ant
+ * task. An error level message is logged before
+ * this exception is thrown.
+ *
+ * @see #checkTaskClass(Class)
+ */
+ public void addTaskDefinition(String taskName, Class<?> taskClass) {
+ checkTaskClass(taskClass);
+ AntTypeDefinition def = new AntTypeDefinition();
+ def.setName(taskName);
+ def.setClassLoader(taskClass.getClassLoader());
+ def.setClass(taskClass);
+ def.setAdapterClass(TaskAdapter.class);
+ def.setClassName(taskClass.getName());
+ def.setAdaptToClass(Task.class);
+ updateDataTypeDefinition(def);
+ }
+
+ /**
+ * Checks whether or not a class is suitable for serving as Ant task.
+ * Ant task implementation classes must be public, concrete, and have
+ * a no-arg constructor.
+ *
+ * @param taskClass The class to be checked.
+ * Must not be <code>null</code>.
+ *
+ * @exception BuildException if the class is unsuitable for being an Ant
+ * task. An error level message is logged before
+ * this exception is thrown.
+ */
+ public void checkTaskClass(final Class<?> taskClass) throws BuildException {
+ if (!Modifier.isPublic(taskClass.getModifiers())) {
+ final String message = taskClass + " is not public";
+ project.log(message, Project.MSG_ERR);
+ throw new BuildException(message);
+ }
+ if (Modifier.isAbstract(taskClass.getModifiers())) {
+ final String message = taskClass + " is abstract";
+ project.log(message, Project.MSG_ERR);
+ throw new BuildException(message);
+ }
+ try {
+ taskClass.getConstructor((Class[]) null);
+ // don't have to check for public, since
+ // getConstructor finds public constructors only.
+ } catch (NoSuchMethodException e) {
+ final String message = "No public no-arg constructor in " + taskClass;
+ project.log(message, Project.MSG_ERR);
+ throw new BuildException(message);
+ }
+ if (!Task.class.isAssignableFrom(taskClass)) {
+ TaskAdapter.checkTaskClass(taskClass, project);
+ }
+ }
+
+ /**
+ * Returns the current task definition hashtable. The returned hashtable is
+ * "live" and so should not be modified. Also, the returned table may be
+ * modified asynchronously.
+ *
+ * @return a map of from task name to implementing class
+ * (String to Class).
+ */
+ public Hashtable<String, Class<?>> getTaskDefinitions() {
+ synchronized (taskClassDefinitions) {
+ synchronized (antTypeTable) {
+ if (rebuildTaskClassDefinitions) {
+ taskClassDefinitions.clear();
+ for (Map.Entry<String, AntTypeDefinition> e : antTypeTable.entrySet()) {
+ final Class<?> clazz = e.getValue().getExposedClass(project);
+ if (clazz == null) {
+ continue;
+ }
+ if (Task.class.isAssignableFrom(clazz)) {
+ taskClassDefinitions.put(e.getKey(), e.getValue().getTypeClass(project));
+ }
+ }
+ rebuildTaskClassDefinitions = false;
+ }
+ }
+ }
+ return taskClassDefinitions;
+ }
+
+ /**
+ * Returns the current type definition hashtable. The returned hashtable is
+ * "live" and so should not be modified.
+ *
+ * @return a map of from type name to implementing class
+ * (String to Class).
+ */
+ public Hashtable<String, Class<?>> getDataTypeDefinitions() {
+ synchronized (typeClassDefinitions) {
+ synchronized (antTypeTable) {
+ if (rebuildTypeClassDefinitions) {
+ typeClassDefinitions.clear();
+ for (Map.Entry<String, AntTypeDefinition> e : antTypeTable.entrySet()) {
+ final Class<?> clazz = e.getValue().getExposedClass(project);
+ if (clazz == null) {
+ continue;
+ }
+ if (!Task.class.isAssignableFrom(clazz)) {
+ typeClassDefinitions.put(e.getKey(), e.getValue().getTypeClass(project));
+ }
+ }
+ rebuildTypeClassDefinitions = false;
+ }
+ }
+ }
+ return typeClassDefinitions;
+ }
+
+ /**
+ * This returns a list of restricted definitions for a name.
+ * The returned List is "live" and so should not be modified.
+ * Also, the returned list may be modified asynchronously.
+ * Any access must be guarded with a lock on the list itself.
+ *
+ * @param componentName the name to use.
+ * @return the list of restricted definitions for a particular name.
+ */
+ public List<AntTypeDefinition> getRestrictedDefinitions(String componentName) {
+ synchronized (restrictedDefinitions) {
+ return restrictedDefinitions.get(componentName);
+ }
+ }
+
+ /**
+ * Adds a new datatype definition.
+ * Attempting to override an existing definition with an
+ * equivalent one (i.e. with the same classname) results in
+ * a verbose log message. Attempting to override an existing definition
+ * with a different one results in a warning log message, but the
+ * definition is changed.
+ *
+ * @param typeName The name of the datatype.
+ * Must not be <code>null</code>.
+ * @param typeClass The full name of the class implementing the datatype.
+ * Must not be <code>null</code>.
+ */
+ public void addDataTypeDefinition(String typeName, Class<?> typeClass) {
+ final AntTypeDefinition def = new AntTypeDefinition();
+ def.setName(typeName);
+ def.setClass(typeClass);
+ updateDataTypeDefinition(def);
+ project.log(" +User datatype: " + typeName + " " + typeClass.getName(),
+ Project.MSG_DEBUG);
+ }
+
+ /**
+ * Describe <code>addDataTypeDefinition</code> method here.
+ *
+ * @param def an <code>AntTypeDefinition</code> value.
+ */
+ public void addDataTypeDefinition(AntTypeDefinition def) {
+ if (!def.isRestrict()) {
+ updateDataTypeDefinition(def);
+ } else {
+ updateRestrictedDefinition(def);
+ }
+ }
+
+ /**
+ * Returns the current datatype definition hashtable. The returned
+ * hashtable is "live" and so should not be modified.
+ *
+ * @return a map of from datatype name to datatype definition
+ * (String to {@link AntTypeDefinition}).
+ */
+ public Hashtable<String, AntTypeDefinition> getAntTypeTable() {
+ return antTypeTable;
+ }
+
+ /**
+ * Creates a new instance of a task.
+ *
+ * Called from Project.createTask(), which can be called by tasks.
+ *
+ * @param taskType The name of the task to create an instance of.
+ * Must not be <code>null</code>.
+ *
+ * @return an instance of the specified task, or <code>null</code> if
+ * the task name is not recognised.
+ *
+ * @exception BuildException if the task name is recognised but task
+ * creation fails.
+ */
+ public Task createTask(String taskType) throws BuildException {
+ Task task = createNewTask(taskType);
+ if (task == null && taskType.equals(ANT_PROPERTY_TASK)) {
+ // quick fix for Ant.java use of property before
+ // initializing the project
+ addTaskDefinition(ANT_PROPERTY_TASK, org.apache.tools.ant.taskdefs.Property.class);
+ task = createNewTask(taskType);
+ }
+ return task;
+ }
+
+ /**
+ * Creates a new instance of a task.
+ * @since ant1.6
+ * @param taskType The name of the task to create an instance of.
+ * Must not be <code>null</code>.
+ *
+ * @return an instance of the specified task, or <code>null</code> if
+ * the task name is not recognised.
+ *
+ * @exception BuildException if the task name is recognised but task
+ * creation fails.
+ */
+ private Task createNewTask(String taskType) throws BuildException {
+ Class<?> c = getComponentClass(taskType);
+ if (c == null || !(Task.class.isAssignableFrom(c))) {
+ return null;
+ }
+ Object obj = createComponent(taskType);
+ if (obj == null) {
+ return null;
+ }
+ if (!(obj instanceof Task)) {
+ throw new BuildException("Expected a Task from '" + taskType
+ + "' but got an instance of " + obj.getClass().getName() + " instead");
+ }
+ Task task = (Task) obj;
+ task.setTaskType(taskType);
+
+ // set default value, can be changed by the user
+ task.setTaskName(taskType);
+
+ project.log(" +Task: " + taskType, Project.MSG_DEBUG);
+ return task;
+ }
+
+ /**
+ * Creates a new instance of a data type.
+ *
+ * @param typeName The name of the data type to create an instance of.
+ * Must not be <code>null</code>.
+ *
+ * @return an instance of the specified data type, or <code>null</code> if
+ * the data type name is not recognised.
+ *
+ * @exception BuildException if the data type name is recognised but
+ * instance creation fails.
+ */
+ public Object createDataType(String typeName) throws BuildException {
+ return createComponent(typeName);
+ }
+
+ /**
+ * Returns a description of the type of the given element.
+ * <p>
+ * This is useful for logging purposes.
+ *
+ * @param element The element to describe.
+ * Must not be <code>null</code>.
+ *
+ * @return a description of the element type.
+ *
+ * @since Ant 1.6
+ */
+ public String getElementName(Object element) {
+ return getElementName(element, false);
+ }
+
+ /**
+ * Returns a description of the type of the given element.
+ * <p>
+ * This is useful for logging purposes.
+ *
+ * @param o The element to describe.
+ * Must not be <code>null</code>.
+ * @param brief whether to use a brief description.
+ * @return a description of the element type.
+ *
+ * @since Ant 1.7
+ */
+ public String getElementName(Object o, boolean brief) {
+ // PR: I do not know what to do if the object class
+ // has multiple defines
+ // but this is for logging only...
+ Class<?> elementClass = o.getClass();
+ String elementClassname = elementClass.getName();
+ synchronized (antTypeTable) {
+ for (AntTypeDefinition def : antTypeTable.values()) {
+ if (elementClassname.equals(def.getClassName())
+ && (elementClass == def.getExposedClass(project))) {
+ String name = def.getName();
+ return brief ? name : "The <" + name + "> type";
+ }
+ }
+ }
+ return getUnmappedElementName(o.getClass(), brief);
+ }
+
+ /**
+ * Convenient way to get some element name even when you may not have a
+ * Project context.
+ * @param p The optional Project instance.
+ * @param o The element to describe.
+ * Must not be <code>null</code>.
+ * @param brief whether to use a brief description.
+ * @return a description of the element type.
+ * @since Ant 1.7
+ */
+ public static String getElementName(Project p, Object o, boolean brief) {
+ if (p == null) {
+ p = Project.getProject(o);
+ }
+ return p == null ? getUnmappedElementName(o.getClass(), brief) : getComponentHelper(p)
+ .getElementName(o, brief);
+ }
+
+ private static String getUnmappedElementName(Class<?> c, boolean brief) {
+ if (brief) {
+ String name = c.getName();
+ return name.substring(name.lastIndexOf('.') + 1);
+ }
+ return c.toString();
+ }
+
+ /**
+ * Check if definition is a valid definition--it may be a
+ * definition of an optional task that does not exist.
+ * @param def the definition to test.
+ * @return true if exposed type of definition is present.
+ */
+ private boolean validDefinition(AntTypeDefinition def) {
+ return !(def.getTypeClass(project) == null || def.getExposedClass(project) == null);
+ }
+
+ /**
+ * Check if two definitions are the same.
+ * @param def the new definition.
+ * @param old the old definition.
+ * @return true if the two definitions are the same.
+ */
+ private boolean sameDefinition(AntTypeDefinition def, AntTypeDefinition old) {
+ boolean defValid = validDefinition(def);
+ boolean sameValidity = (defValid == validDefinition(old));
+ //must have same validity; then if they are valid they must also be the same:
+ return sameValidity && (!defValid || def.sameDefinition(old, project));
+ }
+
+ /**
+ * update the restricted definition table with a new or
+ * modified definition.
+ */
+ private void updateRestrictedDefinition(AntTypeDefinition def) {
+ String name = def.getName();
+ List<AntTypeDefinition> list = null;
+ synchronized (restrictedDefinitions) {
+ list = restrictedDefinitions.get(name);
+ if (list == null) {
+ list = new ArrayList<AntTypeDefinition>();
+ restrictedDefinitions.put(name, list);
+ }
+ }
+ // Check if the classname is already present and remove it
+ // if it is
+ synchronized (list) {
+ for (Iterator<AntTypeDefinition> i = list.iterator(); i.hasNext();) {
+ AntTypeDefinition current = i.next();
+ if (current.getClassName().equals(def.getClassName())) {
+ i.remove();
+ break;
+ }
+ }
+ list.add(def);
+ }
+ }
+
+ /**
+ * Update the component definition table with a new or
+ * modified definition.
+ * @param def the definition to update or insert.
+ */
+ private void updateDataTypeDefinition(AntTypeDefinition def) {
+ String name = def.getName();
+ synchronized (antTypeTable) {
+ rebuildTaskClassDefinitions = true;
+ rebuildTypeClassDefinitions = true;
+ final AntTypeDefinition old = antTypeTable.get(name);
+ if (old != null) {
+ if (sameDefinition(def, old)) {
+ return;
+ }
+ Class<?> oldClass = old.getExposedClass(project);
+ boolean isTask = oldClass != null && Task.class.isAssignableFrom(oldClass);
+ project.log("Trying to override old definition of "
+ + (isTask ? "task " : "datatype ") + name, (def.similarDefinition(old,
+ project)) ? Project.MSG_VERBOSE : Project.MSG_WARN);
+ }
+ project.log(" +Datatype " + name + " " + def.getClassName(), Project.MSG_DEBUG);
+ antTypeTable.put(name, def);
+ }
+ }
+
+ /**
+ * Called at the start of processing an antlib.
+ * @param uri the uri that is associated with this antlib.
+ */
+ public void enterAntLib(String uri) {
+ antLibCurrentUri = uri;
+ antLibStack.push(uri);
+ }
+
+ /**
+ * @return the current antlib uri.
+ */
+ public String getCurrentAntlibUri() {
+ return antLibCurrentUri;
+ }
+
+ /**
+ * Called at the end of processing an antlib.
+ */
+ public void exitAntLib() {
+ antLibStack.pop();
+ antLibCurrentUri = (antLibStack.size() == 0) ? null : (String) antLibStack.peek();
+ }
+
+ /**
+ * Load ant's tasks.
+ */
+ private void initTasks() {
+ ClassLoader classLoader = getClassLoader(null);
+ Properties props = getDefaultDefinitions(false);
+ Enumeration<?> e = props.propertyNames();
+ while (e.hasMoreElements()) {
+ String name = (String) e.nextElement();
+ String className = props.getProperty(name);
+ AntTypeDefinition def = new AntTypeDefinition();
+ def.setName(name);
+ def.setClassName(className);
+ def.setClassLoader(classLoader);
+ def.setAdaptToClass(Task.class);
+ def.setAdapterClass(TaskAdapter.class);
+ antTypeTable.put(name, def);
+ }
+ }
+
+ private ClassLoader getClassLoader(ClassLoader classLoader) {
+ String buildSysclasspath = project.getProperty(MagicNames.BUILD_SYSCLASSPATH);
+ if (project.getCoreLoader() != null
+ && !(BUILD_SYSCLASSPATH_ONLY.equals(buildSysclasspath))) {
+ classLoader = project.getCoreLoader();
+ }
+ return classLoader;
+ }
+
+ /**
+ * Load default task or type definitions - just the names,
+ * no class loading.
+ * Caches results between calls to reduce overhead.
+ * @param type true for typedefs, false for taskdefs
+ * @return a mapping from definition names to class names
+ * @throws BuildException if there was some problem loading
+ * or parsing the definitions list
+ */
+ private static synchronized Properties getDefaultDefinitions(boolean type)
+ throws BuildException {
+ int idx = type ? 1 : 0;
+ if (defaultDefinitions[idx] == null) {
+ String resource = type ? MagicNames.TYPEDEFS_PROPERTIES_RESOURCE
+ : MagicNames.TASKDEF_PROPERTIES_RESOURCE;
+ String errorString = type ? ERROR_NO_TYPE_LIST_LOAD : ERROR_NO_TASK_LIST_LOAD;
+ InputStream in = null;
+ try {
+ in = ComponentHelper.class.getResourceAsStream(resource);
+ if (in == null) {
+ throw new BuildException(errorString);
+ }
+ Properties p = new Properties();
+ p.load(in);
+ defaultDefinitions[idx] = p;
+ } catch (IOException e) {
+ throw new BuildException(errorString, e);
+ } finally {
+ FileUtils.close(in);
+ }
+ }
+ return defaultDefinitions[idx];
+ }
+
+ /**
+ * Load ant's datatypes.
+ */
+ private void initTypes() {
+ ClassLoader classLoader = getClassLoader(null);
+ Properties props = getDefaultDefinitions(true);
+ Enumeration<?> e = props.propertyNames();
+ while (e.hasMoreElements()) {
+ String name = (String) e.nextElement();
+ String className = props.getProperty(name);
+ AntTypeDefinition def = new AntTypeDefinition();
+ def.setName(name);
+ def.setClassName(className);
+ def.setClassLoader(classLoader);
+ antTypeTable.put(name, def);
+ }
+ }
+
+ /**
+ * Called for each component name, check if the
+ * associated URI has been examined for antlibs.
+ * @param componentName the name of the component, which should include a URI
+ * prefix if it is in a namespace
+ */
+ private synchronized void checkNamespace(String componentName) {
+ String uri = ProjectHelper.extractUriFromComponentName(componentName);
+ if ("".equals(uri)) {
+ uri = ProjectHelper.ANT_CORE_URI;
+ }
+ if (!uri.startsWith(ProjectHelper.ANTLIB_URI)) {
+ return; // namespace that does not contain antlib
+ }
+ if (checkedNamespaces.contains(uri)) {
+ return; // Already processed
+ }
+ checkedNamespaces.add(uri);
+
+ if (antTypeTable.size() == 0) {
+ // Project instance doesn't know the tasks and types
+ // defined in defaults.properties, likely created by the
+ // user - without those definitions it cannot parse antlib
+ // files as taskdef, typedef and friends are unknown
+ initDefaultDefinitions();
+ }
+ Typedef definer = new Typedef();
+ definer.setProject(project);
+ definer.init();
+ definer.setURI(uri);
+ //there to stop error messages being "null"
+ definer.setTaskName(uri);
+ //if this is left out, bad things happen. like all build files break
+ //on the first element encountered.
+ definer.setResource(Definer.makeResourceFromURI(uri));
+ // a fishing expedition :- ignore errors if antlib not present
+ definer.setOnError(new Typedef.OnError(Typedef.OnError.POLICY_IGNORE));
+ definer.execute();
+ }
+
+ /**
+ * Handler called to do decent diagnosis on instantiation failure.
+ * @param componentName component name.
+ * @param type component type, used in error messages
+ * @return a string containing as much diagnostics info as possible.
+ */
+ public String diagnoseCreationFailure(String componentName, String type) {
+ StringWriter errorText = new StringWriter();
+ PrintWriter out = new PrintWriter(errorText);
+ out.println("Problem: failed to create " + type + " " + componentName);
+ //class of problem
+ boolean lowlevel = false;
+ boolean jars = false;
+ boolean definitions = false;
+ boolean antTask;
+ String home = System.getProperty(Launcher.USER_HOMEDIR);
+ File libDir = new File(home, Launcher.USER_LIBDIR);
+ String antHomeLib;
+ boolean probablyIDE = false;
+ String anthome = System.getProperty(MagicNames.ANT_HOME);
+ if (anthome != null) {
+ File antHomeLibDir = new File(anthome, "lib");
+ antHomeLib = antHomeLibDir.getAbsolutePath();
+ } else {
+ //running under an IDE that doesn't set ANT_HOME
+ probablyIDE = true;
+ antHomeLib = "ANT_HOME" + File.separatorChar + "lib";
+ }
+ StringBuffer dirListingText = new StringBuffer();
+ final String tab = " -";
+ dirListingText.append(tab);
+ dirListingText.append(antHomeLib);
+ dirListingText.append('\n');
+ if (probablyIDE) {
+ dirListingText.append(tab);
+ dirListingText.append("the IDE Ant configuration dialogs");
+ } else {
+ dirListingText.append(tab);
+ dirListingText.append(libDir);
+ dirListingText.append('\n');
+ dirListingText.append(tab);
+ dirListingText.append("a directory added on the command line with the -lib argument");
+ }
+ String dirListing = dirListingText.toString();
+
+ //look up the name
+ AntTypeDefinition def = getDefinition(componentName);
+ if (def == null) {
+ //not a known type
+ printUnknownDefinition(out, componentName, dirListing);
+ definitions = true;
+ } else {
+ //we are defined, so it is an instantiation problem
+ final String classname = def.getClassName();
+ antTask = classname.startsWith("org.apache.tools.ant.");
+ boolean optional = classname.startsWith("org.apache.tools.ant.taskdefs.optional");
+ optional |= classname.startsWith("org.apache.tools.ant.types.optional");
+
+ //start with instantiating the class.
+ Class<?> clazz = null;
+ try {
+ clazz = def.innerGetTypeClass();
+ } catch (ClassNotFoundException e) {
+ jars = true;
+ if (!optional) {
+ definitions = true;
+ }
+ printClassNotFound(out, classname, optional, dirListing);
+ } catch (NoClassDefFoundError ncdfe) {
+ jars = true;
+ printNotLoadDependentClass(out, optional, ncdfe, dirListing);
+ }
+ //here we successfully loaded the class or failed.
+ if (clazz != null) {
+ //success: proceed with more steps
+ try {
+ def.innerCreateAndSet(clazz, project);
+ //hey, there is nothing wrong with us
+ out.println("The component could be instantiated.");
+ } catch (NoSuchMethodException e) {
+ lowlevel = true;
+ out.println("Cause: The class " + classname
+ + " has no compatible constructor.");
+
+ } catch (InstantiationException e) {
+ lowlevel = true;
+ out.println("Cause: The class " + classname
+ + " is abstract and cannot be instantiated.");
+ } catch (IllegalAccessException e) {
+ lowlevel = true;
+ out.println("Cause: The constructor for " + classname
+ + " is private and cannot be invoked.");
+ } catch (InvocationTargetException ex) {
+ lowlevel = true;
+ Throwable t = ex.getTargetException();
+ out.println("Cause: The constructor threw the exception");
+ out.println(t.toString());
+ t.printStackTrace(out);
+ } catch (NoClassDefFoundError ncdfe) {
+ jars = true;
+ out.println("Cause: A class needed by class " + classname
+ + " cannot be found: ");
+ out.println(" " + ncdfe.getMessage());
+ out.println("Action: Determine what extra JAR files are"
+ + " needed, and place them in:");
+ out.println(dirListing);
+ }
+ }
+ out.println();
+ out.println("Do not panic, this is a common problem.");
+ if (definitions) {
+ out.println("It may just be a typographical error in the build file "
+ + "or the task/type declaration.");
+ }
+ if (jars) {
+ out.println("The commonest cause is a missing JAR.");
+ }
+ if (lowlevel) {
+ out.println("This is quite a low level problem, which may need "
+ + "consultation with the author of the task.");
+ if (antTask) {
+ out.println("This may be the Ant team. Please file a "
+ + "defect or contact the developer team.");
+ } else {
+ out.println("This does not appear to be a task bundled with Ant.");
+ out.println("Please take it up with the supplier of the third-party " + type
+ + ".");
+ out.println("If you have written it yourself, you probably have a bug to fix.");
+ }
+ } else {
+ out.println();
+ out.println("This is not a bug; it is a configuration problem");
+ }
+ }
+ out.flush();
+ out.close();
+ return errorText.toString();
+ }
+
+ /**
+ * Print unknown definition.forking
+ */
+ private void printUnknownDefinition(PrintWriter out, String componentName, String dirListing) {
+ boolean isAntlib = componentName.startsWith(MagicNames.ANTLIB_PREFIX);
+ String uri = ProjectHelper.extractUriFromComponentName(componentName);
+ out.println("Cause: The name is undefined.");
+ out.println("Action: Check the spelling.");
+ out.println("Action: Check that any custom tasks/types have been declared.");
+ out.println("Action: Check that any <presetdef>/<macrodef>"
+ + " declarations have taken place.");
+ if (uri.length() > 0) {
+ final List<AntTypeDefinition> matches = findTypeMatches(uri);
+ if (matches.size() > 0) {
+ out.println();
+ out.println("The definitions in the namespace " + uri + " are:");
+ for (AntTypeDefinition def : matches) {
+ String local = ProjectHelper.extractNameFromComponentName(def.getName());
+ out.println(" " + local);
+ }
+ } else {
+ out.println("No types or tasks have been defined in this namespace yet");
+ if (isAntlib) {
+ out.println();
+ out.println("This appears to be an antlib declaration. ");
+ out.println("Action: Check that the implementing library exists in one of:");
+ out.println(dirListing);
+ }
+ }
+ }
+ }
+
+ /**
+ * Print class not found.
+ */
+ private void printClassNotFound(PrintWriter out, String classname, boolean optional,
+ String dirListing) {
+ out.println("Cause: the class " + classname + " was not found.");
+ if (optional) {
+ out.println(" This looks like one of Ant's optional components.");
+ out.println("Action: Check that the appropriate optional JAR exists in");
+ out.println(dirListing);
+ } else {
+ out.println("Action: Check that the component has been correctly declared");
+ out.println(" and that the implementing JAR is in one of:");
+ out.println(dirListing);
+ }
+ }
+
+ /**
+ * Print could not load dependent class.
+ */
+ private void printNotLoadDependentClass(PrintWriter out, boolean optional,
+ NoClassDefFoundError ncdfe, String dirListing) {
+ out.println("Cause: Could not load a dependent class "
+ + ncdfe.getMessage());
+ if (optional) {
+ out.println(" It is not enough to have Ant's optional JARs");
+ out.println(" you need the JAR files that the" + " optional tasks depend upon.");
+ out.println(" Ant's optional task dependencies are" + " listed in the manual.");
+ } else {
+ out.println(" This class may be in a separate JAR" + " that is not installed.");
+ }
+ out.println("Action: Determine what extra JAR files are"
+ + " needed, and place them in one of:");
+ out.println(dirListing);
+ }
+
+ /**
+ * Create a list of all definitions that match a prefix, usually the URI
+ * of a library
+ * @param prefix prefix to match off
+ * @return the (possibly empty) list of definitions
+ */
+ private List<AntTypeDefinition> findTypeMatches(String prefix) {
+ final List<AntTypeDefinition> result = new ArrayList<AntTypeDefinition>();
+ synchronized (antTypeTable) {
+ for (AntTypeDefinition def : antTypeTable.values()) {
+ if (def.getName().startsWith(prefix)) {
+ result.add(def);
+ }
+ }
+ }
+ return result;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/DefaultDefinitions.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/DefaultDefinitions.java
new file mode 100644
index 00000000..062018d0
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/DefaultDefinitions.java
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant;
+
+/**
+ * Default definitions.
+ * @since Ant 1.9.1
+ */
+public final class DefaultDefinitions {
+ private static final String IF_NAMESPACE = "ant:if";
+ private static final String UNLESS_NAMESPACE = "ant:unless";
+ private static final String OATA = "org.apache.tools.ant.";
+
+ private final ComponentHelper componentHelper;
+
+ /**
+ * Create a default definitions object.
+ * @param componentHelper the componenthelper to initialize.
+ */
+ public DefaultDefinitions(ComponentHelper componentHelper) {
+ this.componentHelper = componentHelper;
+ }
+
+ /**
+ * Register the definitions.
+ */
+ public void execute() {
+ attributeNamespaceDef(IF_NAMESPACE);
+ attributeNamespaceDef(UNLESS_NAMESPACE);
+
+ ifUnlessDef("true", "IfTrueAttribute");
+ ifUnlessDef("set", "IfSetAttribute");
+ ifUnlessDef("blank", "IfBlankAttribute");
+ }
+
+ private void attributeNamespaceDef(String ns) {
+ AntTypeDefinition def = new AntTypeDefinition();
+ def.setName(ProjectHelper.nsToComponentName(ns));
+ def.setClassName(OATA + "attribute.AttributeNamespace");
+ def.setClassLoader(getClass().getClassLoader());
+ def.setRestrict(true);
+ componentHelper.addDataTypeDefinition(def);
+ }
+
+ private void ifUnlessDef(String name, String base) {
+ String classname = OATA + "attribute." + base;
+ componentDef(IF_NAMESPACE, name, classname);
+ componentDef(UNLESS_NAMESPACE, name, classname + "$Unless");
+ }
+
+ private void componentDef(String ns, String name, String classname) {
+ AntTypeDefinition def = new AntTypeDefinition();
+ String n = ProjectHelper.genComponentName(ns, name);
+ def.setName(ProjectHelper.genComponentName(ns, name));
+ def.setClassName(classname);
+ def.setClassLoader(getClass().getClassLoader());
+ def.setRestrict(true);
+ componentHelper.addDataTypeDefinition(def);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/DefaultLogger.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/DefaultLogger.java
new file mode 100644
index 00000000..dbc60486
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/DefaultLogger.java
@@ -0,0 +1,380 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.io.StringReader;
+import java.text.DateFormat;
+import java.util.Date;
+
+import org.apache.tools.ant.util.DateUtils;
+import org.apache.tools.ant.util.FileUtils;
+import org.apache.tools.ant.util.StringUtils;
+
+/**
+ * Writes build events to a PrintStream. Currently, it
+ * only writes which targets are being executed, and
+ * any messages that get logged.
+ *
+ */
+public class DefaultLogger implements BuildLogger {
+ /**
+ * Size of left-hand column for right-justified task name.
+ * @see #messageLogged(BuildEvent)
+ */
+ public static final int LEFT_COLUMN_SIZE = 12;
+
+ // CheckStyle:VisibilityModifier OFF - bc
+ /** PrintStream to write non-error messages to */
+ protected PrintStream out;
+
+ /** PrintStream to write error messages to */
+ protected PrintStream err;
+
+ /** Lowest level of message to write out */
+ protected int msgOutputLevel = Project.MSG_ERR;
+
+ /** Time of the start of the build */
+ private long startTime = System.currentTimeMillis();
+
+ // CheckStyle:ConstantNameCheck OFF - bc
+ /** Line separator */
+ protected static final String lSep = StringUtils.LINE_SEP;
+ // CheckStyle:ConstantNameCheck ON
+
+ /** Whether or not to use emacs-style output */
+ protected boolean emacsMode = false;
+ // CheckStyle:VisibilityModifier ON
+
+
+ /**
+ * Sole constructor.
+ */
+ public DefaultLogger() {
+ }
+
+ /**
+ * Sets the highest level of message this logger should respond to.
+ *
+ * Only messages with a message level lower than or equal to the
+ * given level should be written to the log.
+ * <p>
+ * Constants for the message levels are in the
+ * {@link Project Project} class. The order of the levels, from least
+ * to most verbose, is <code>MSG_ERR</code>, <code>MSG_WARN</code>,
+ * <code>MSG_INFO</code>, <code>MSG_VERBOSE</code>,
+ * <code>MSG_DEBUG</code>.
+ * <p>
+ * The default message level for DefaultLogger is Project.MSG_ERR.
+ *
+ * @param level the logging level for the logger.
+ */
+ public void setMessageOutputLevel(int level) {
+ this.msgOutputLevel = level;
+ }
+
+ /**
+ * Sets the output stream to which this logger is to send its output.
+ *
+ * @param output The output stream for the logger.
+ * Must not be <code>null</code>.
+ */
+ public void setOutputPrintStream(PrintStream output) {
+ this.out = new PrintStream(output, true);
+ }
+
+ /**
+ * Sets the output stream to which this logger is to send error messages.
+ *
+ * @param err The error stream for the logger.
+ * Must not be <code>null</code>.
+ */
+ public void setErrorPrintStream(PrintStream err) {
+ this.err = new PrintStream(err, true);
+ }
+
+ /**
+ * Sets this logger to produce emacs (and other editor) friendly output.
+ *
+ * @param emacsMode <code>true</code> if output is to be unadorned so that
+ * emacs and other editors can parse files names, etc.
+ */
+ public void setEmacsMode(boolean emacsMode) {
+ this.emacsMode = emacsMode;
+ }
+
+ /**
+ * Responds to a build being started by just remembering the current time.
+ *
+ * @param event Ignored.
+ */
+ public void buildStarted(BuildEvent event) {
+ startTime = System.currentTimeMillis();
+ }
+
+ static void throwableMessage(StringBuffer m, Throwable error, boolean verbose) {
+ while (error instanceof BuildException) { // #43398
+ Throwable cause = error.getCause();
+ if (cause == null) {
+ break;
+ }
+ String msg1 = error.toString();
+ String msg2 = cause.toString();
+ if (msg1.endsWith(msg2)) {
+ m.append(msg1.substring(0, msg1.length() - msg2.length()));
+ error = cause;
+ } else {
+ break;
+ }
+ }
+ if (verbose || !(error instanceof BuildException)) {
+ m.append(StringUtils.getStackTrace(error));
+ } else {
+ m.append(error).append(lSep);
+ }
+ }
+
+ /**
+ * Prints whether the build succeeded or failed,
+ * any errors the occurred during the build, and
+ * how long the build took.
+ *
+ * @param event An event with any relevant extra information.
+ * Must not be <code>null</code>.
+ */
+ public void buildFinished(BuildEvent event) {
+ Throwable error = event.getException();
+ StringBuffer message = new StringBuffer();
+ if (error == null) {
+ message.append(StringUtils.LINE_SEP);
+ message.append(getBuildSuccessfulMessage());
+ } else {
+ message.append(StringUtils.LINE_SEP);
+ message.append(getBuildFailedMessage());
+ message.append(StringUtils.LINE_SEP);
+ throwableMessage(message, error, Project.MSG_VERBOSE <= msgOutputLevel);
+ }
+ message.append(StringUtils.LINE_SEP);
+ message.append("Total time: ");
+ message.append(formatTime(System.currentTimeMillis() - startTime));
+
+ String msg = message.toString();
+ if (error == null) {
+ printMessage(msg, out, Project.MSG_VERBOSE);
+ } else {
+ printMessage(msg, err, Project.MSG_ERR);
+ }
+ log(msg);
+ }
+
+ /**
+ * This is an override point: the message that indicates whether a build failed.
+ * Subclasses can change/enhance the message.
+ * @return The classic "BUILD FAILED"
+ */
+ protected String getBuildFailedMessage() {
+ return "BUILD FAILED";
+ }
+
+ /**
+ * This is an override point: the message that indicates that a build succeeded.
+ * Subclasses can change/enhance the message.
+ * @return The classic "BUILD SUCCESSFUL"
+ */
+ protected String getBuildSuccessfulMessage() {
+ return "BUILD SUCCESSFUL";
+ }
+
+ /**
+ * Logs a message to say that the target has started if this
+ * logger allows information-level messages.
+ *
+ * @param event An event with any relevant extra information.
+ * Must not be <code>null</code>.
+ */
+ public void targetStarted(BuildEvent event) {
+ if (Project.MSG_INFO <= msgOutputLevel
+ && !event.getTarget().getName().equals("")) {
+ String msg = StringUtils.LINE_SEP
+ + event.getTarget().getName() + ":";
+ printMessage(msg, out, event.getPriority());
+ log(msg);
+ }
+ }
+
+ /**
+ * No-op implementation.
+ *
+ * @param event Ignored.
+ */
+ public void targetFinished(BuildEvent event) {
+ }
+
+ /**
+ * No-op implementation.
+ *
+ * @param event Ignored.
+ */
+ public void taskStarted(BuildEvent event) {
+ }
+
+ /**
+ * No-op implementation.
+ *
+ * @param event Ignored.
+ */
+ public void taskFinished(BuildEvent event) {
+ }
+
+ /**
+ * Logs a message, if the priority is suitable.
+ * In non-emacs mode, task level messages are prefixed by the
+ * task name which is right-justified.
+ *
+ * @param event A BuildEvent containing message information.
+ * Must not be <code>null</code>.
+ */
+ public void messageLogged(BuildEvent event) {
+ int priority = event.getPriority();
+ // Filter out messages based on priority
+ if (priority <= msgOutputLevel) {
+
+ StringBuffer message = new StringBuffer();
+ if (event.getTask() != null && !emacsMode) {
+ // Print out the name of the task if we're in one
+ String name = event.getTask().getTaskName();
+ String label = "[" + name + "] ";
+ int size = LEFT_COLUMN_SIZE - label.length();
+ StringBuffer tmp = new StringBuffer();
+ for (int i = 0; i < size; i++) {
+ tmp.append(" ");
+ }
+ tmp.append(label);
+ label = tmp.toString();
+
+ BufferedReader r = null;
+ try {
+ r = new BufferedReader(
+ new StringReader(event.getMessage()));
+ String line = r.readLine();
+ boolean first = true;
+ do {
+ if (first) {
+ if (line == null) {
+ message.append(label);
+ break;
+ }
+ } else {
+ message.append(StringUtils.LINE_SEP);
+ }
+ first = false;
+ message.append(label).append(line);
+ line = r.readLine();
+ } while (line != null);
+ } catch (IOException e) {
+ // shouldn't be possible
+ message.append(label).append(event.getMessage());
+ } finally {
+ if (r != null) {
+ FileUtils.close(r);
+ }
+ }
+
+ } else {
+ //emacs mode or there is no task
+ message.append(event.getMessage());
+ }
+ Throwable ex = event.getException();
+ if (Project.MSG_DEBUG <= msgOutputLevel && ex != null) {
+ message.append(StringUtils.getStackTrace(ex));
+ }
+
+ String msg = message.toString();
+ if (priority != Project.MSG_ERR) {
+ printMessage(msg, out, priority);
+ } else {
+ printMessage(msg, err, priority);
+ }
+ log(msg);
+ }
+ }
+
+ /**
+ * Convenience method to format a specified length of time.
+ *
+ * @param millis Length of time to format, in milliseconds.
+ *
+ * @return the time as a formatted string.
+ *
+ * @see DateUtils#formatElapsedTime(long)
+ */
+ protected static String formatTime(final long millis) {
+ return DateUtils.formatElapsedTime(millis);
+ }
+
+ /**
+ * Prints a message to a PrintStream.
+ *
+ * @param message The message to print.
+ * Should not be <code>null</code>.
+ * @param stream A PrintStream to print the message to.
+ * Must not be <code>null</code>.
+ * @param priority The priority of the message.
+ * (Ignored in this implementation.)
+ */
+ protected void printMessage(final String message,
+ final PrintStream stream,
+ final int priority) {
+ stream.println(message);
+ }
+
+ /**
+ * Empty implementation which allows subclasses to receive the
+ * same output that is generated here.
+ *
+ * @param message Message being logged. Should not be <code>null</code>.
+ */
+ protected void log(String message) {
+ }
+
+ /**
+ * Get the current time.
+ * @return the current time as a formatted string.
+ * @since Ant1.7.1
+ */
+ protected String getTimestamp() {
+ Date date = new Date(System.currentTimeMillis());
+ DateFormat formatter = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT);
+ String finishTime = formatter.format(date);
+ return finishTime;
+ }
+
+ /**
+ * Get the project name or null
+ * @param event the event
+ * @return the project that raised this event
+ * @since Ant1.7.1
+ */
+ protected String extractProjectName(BuildEvent event) {
+ Project project = event.getProject();
+ return (project != null) ? project.getName() : null;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/DemuxInputStream.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/DemuxInputStream.java
new file mode 100644
index 00000000..ea263ca7
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/DemuxInputStream.java
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ *
+ * Passes input requests to the project object for demuxing into
+ * individual tasks and threads.
+ *
+ * @since Ant 1.6
+ */
+public class DemuxInputStream extends InputStream {
+
+ private static final int MASK_8BIT = 0xFF;
+ /**
+ * The project to from which to get input.
+ */
+ private Project project;
+
+ /**
+ * Create a DemuxInputStream for the given project
+ *
+ * @param project the project instance
+ */
+ public DemuxInputStream(Project project) {
+ this.project = project;
+ }
+
+ /**
+ * Read a byte from the project's demuxed input.
+ * @return the next byte
+ * @throws IOException on error
+ */
+ public int read() throws IOException {
+ byte[] buffer = new byte[1];
+ if (project.demuxInput(buffer, 0, 1) == -1) {
+ return -1;
+ }
+ return buffer[0] & MASK_8BIT;
+ }
+
+
+ /**
+ * Read bytes from the project's demuxed input.
+ * @param buffer an array of bytes to read into
+ * @param offset the offset in the array of bytes
+ * @param length the number of bytes in the array
+ * @return the number of bytes read
+ * @throws IOException on error
+ */
+ public int read(byte[] buffer, int offset, int length) throws IOException {
+ return project.demuxInput(buffer, offset, length);
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/DemuxOutputStream.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/DemuxOutputStream.java
new file mode 100644
index 00000000..bd399132
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/DemuxOutputStream.java
@@ -0,0 +1,249 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.WeakHashMap;
+
+
+/**
+ * Logs content written by a thread and forwards the buffers onto the
+ * project object which will forward the content to the appropriate
+ * task.
+ *
+ * @since 1.4
+ */
+public class DemuxOutputStream extends OutputStream {
+
+ /**
+ * A data class to store information about a buffer. Such information
+ * is stored on a per-thread basis.
+ */
+ private static class BufferInfo {
+ /**
+ * The per-thread output stream.
+ */
+ private ByteArrayOutputStream buffer;
+
+ /**
+ * Indicates we have just seen a carriage return. It may be part of
+ * a crlf pair or a single cr invoking processBuffer twice.
+ */
+ private boolean crSeen = false;
+ }
+
+ /** Maximum buffer size. */
+ private static final int MAX_SIZE = 1024;
+
+ /** Initial buffer size. */
+ private static final int INITIAL_SIZE = 132;
+
+ /** Carriage return */
+ private static final int CR = 0x0d;
+
+ /** Linefeed */
+ private static final int LF = 0x0a;
+
+ /** Mapping from thread to buffer (Thread to BufferInfo). */
+ private WeakHashMap<Thread, BufferInfo> buffers = new WeakHashMap<Thread, BufferInfo>();
+
+ /**
+ * The project to send output to.
+ */
+ private Project project;
+
+ /**
+ * Whether or not this stream represents an error stream.
+ */
+ private boolean isErrorStream;
+
+ /**
+ * Creates a new instance of this class.
+ *
+ * @param project The project instance for which output is being
+ * demultiplexed. Must not be <code>null</code>.
+ * @param isErrorStream <code>true</code> if this is the error string,
+ * otherwise a normal output stream. This is
+ * passed to the project so it knows
+ * which stream it is receiving.
+ */
+ public DemuxOutputStream(Project project, boolean isErrorStream) {
+ this.project = project;
+ this.isErrorStream = isErrorStream;
+ }
+
+ /**
+ * Returns the buffer associated with the current thread.
+ *
+ * @return a BufferInfo for the current thread to write data to
+ */
+ private BufferInfo getBufferInfo() {
+ Thread current = Thread.currentThread();
+ BufferInfo bufferInfo = (BufferInfo) buffers.get(current);
+ if (bufferInfo == null) {
+ bufferInfo = new BufferInfo();
+ bufferInfo.buffer = new ByteArrayOutputStream(INITIAL_SIZE);
+ bufferInfo.crSeen = false;
+ buffers.put(current, bufferInfo);
+ }
+ return bufferInfo;
+ }
+
+ /**
+ * Resets the buffer for the current thread.
+ */
+ private void resetBufferInfo() {
+ Thread current = Thread.currentThread();
+ BufferInfo bufferInfo = (BufferInfo) buffers.get(current);
+ try {
+ bufferInfo.buffer.close();
+ } catch (IOException e) {
+ // Shouldn't happen
+ }
+ bufferInfo.buffer = new ByteArrayOutputStream();
+ bufferInfo.crSeen = false;
+ }
+
+ /**
+ * Removes the buffer for the current thread.
+ */
+ private void removeBuffer() {
+ Thread current = Thread.currentThread();
+ buffers.remove (current);
+ }
+
+ /**
+ * Writes the data to the buffer and flushes the buffer if a line
+ * separator is detected or if the buffer has reached its maximum size.
+ *
+ * @param cc data to log (byte).
+ * @exception IOException if the data cannot be written to the stream
+ */
+ public void write(int cc) throws IOException {
+ final byte c = (byte) cc;
+
+ BufferInfo bufferInfo = getBufferInfo();
+
+ if (c == '\n') {
+ // LF is always end of line (i.e. CRLF or single LF)
+ bufferInfo.buffer.write(cc);
+ processBuffer(bufferInfo.buffer);
+ } else {
+ if (bufferInfo.crSeen) {
+ // CR without LF - send buffer then add char
+ processBuffer(bufferInfo.buffer);
+ }
+ // add into buffer
+ bufferInfo.buffer.write(cc);
+ }
+ bufferInfo.crSeen = (c == '\r');
+ if (!bufferInfo.crSeen && bufferInfo.buffer.size() > MAX_SIZE) {
+ processBuffer(bufferInfo.buffer);
+ }
+ }
+
+ /**
+ * Converts the buffer to a string and sends it to the project.
+ *
+ * @param buffer the ByteArrayOutputStream used to collect the output
+ * until a line separator is seen.
+ *
+ * @see Project#demuxOutput(String,boolean)
+ */
+ protected void processBuffer(ByteArrayOutputStream buffer) {
+ String output = buffer.toString();
+ project.demuxOutput(output, isErrorStream);
+ resetBufferInfo();
+ }
+
+ /**
+ * Converts the buffer to a string and sends it to the project.
+ *
+ * @param buffer the ByteArrayOutputStream used to collect the output
+ * until a line separator is seen.
+ *
+ * @see Project#demuxOutput(String,boolean)
+ */
+ protected void processFlush(ByteArrayOutputStream buffer) {
+ String output = buffer.toString();
+ project.demuxFlush(output, isErrorStream);
+ resetBufferInfo();
+ }
+
+ /**
+ * Equivalent to flushing the stream.
+ *
+ * @exception IOException if there is a problem closing the stream.
+ *
+ * @see #flush
+ */
+ public void close() throws IOException {
+ flush();
+ removeBuffer();
+ }
+
+ /**
+ * Writes all remaining data in the buffer associated
+ * with the current thread to the project.
+ *
+ * @exception IOException if there is a problem flushing the stream.
+ */
+ public void flush() throws IOException {
+ BufferInfo bufferInfo = getBufferInfo();
+ if (bufferInfo.buffer.size() > 0) {
+ processFlush(bufferInfo.buffer);
+ }
+ }
+
+ /**
+ * Write a block of characters to the output stream
+ *
+ * @param b the array containing the data
+ * @param off the offset into the array where data starts
+ * @param len the length of block
+ *
+ * @throws IOException if the data cannot be written into the stream.
+ */
+ public void write(byte[] b, int off, int len) throws IOException {
+ // find the line breaks and pass other chars through in blocks
+ int offset = off;
+ int blockStartOffset = offset;
+ int remaining = len;
+ BufferInfo bufferInfo = getBufferInfo();
+ while (remaining > 0) {
+ while (remaining > 0 && b[offset] != LF && b[offset] != CR) {
+ offset++;
+ remaining--;
+ }
+ // either end of buffer or a line separator char
+ int blockLength = offset - blockStartOffset;
+ if (blockLength > 0) {
+ bufferInfo.buffer.write(b, blockStartOffset, blockLength);
+ }
+ while (remaining > 0 && (b[offset] == LF || b[offset] == CR)) {
+ write(b[offset]);
+ offset++;
+ remaining--;
+ }
+ blockStartOffset = offset;
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/Diagnostics.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/Diagnostics.java
new file mode 100644
index 00000000..6389f6ee
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/Diagnostics.java
@@ -0,0 +1,715 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintStream;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.net.URL;
+import java.util.Calendar;
+import java.util.Enumeration;
+import java.util.Properties;
+import java.util.TimeZone;
+
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerFactory;
+
+import org.apache.tools.ant.launch.Launcher;
+import org.apache.tools.ant.util.FileUtils;
+import org.apache.tools.ant.util.JAXPUtils;
+import org.apache.tools.ant.util.JavaEnvUtils;
+import org.apache.tools.ant.util.ProxySetup;
+import org.xml.sax.XMLReader;
+
+/**
+ * A little diagnostic helper that output some information that may help
+ * in support. It should quickly give correct information about the
+ * jar existing in ant.home/lib and the jar versions...
+ *
+ * @since Ant 1.5
+ */
+public final class Diagnostics {
+
+ /** the version number for java 1.5 returned from JavaEnvUtils */
+ private static final int JAVA_1_5_NUMBER = 15;
+
+ /**
+ * value for which a difference between clock and temp file time triggers
+ * a warning.
+ * {@value}
+ */
+ private static final int BIG_DRIFT_LIMIT = 10000;
+
+ /**
+ * How big a test file to write.
+ * {@value}
+ */
+ private static final int TEST_FILE_SIZE = 32;
+ private static final int KILOBYTE = 1024;
+ private static final int SECONDS_PER_MILLISECOND = 1000;
+ private static final int SECONDS_PER_MINUTE = 60;
+ private static final int MINUTES_PER_HOUR = 60;
+
+ /**
+ * The error text when a security manager blocks access to a property.
+ * {@value}
+ */
+ protected static final String ERROR_PROPERTY_ACCESS_BLOCKED
+ = "Access to this property blocked by a security manager";
+
+ /** utility class */
+ private Diagnostics() {
+ // hidden constructor
+ }
+
+ /**
+ * Doesn't do anything.
+ * @deprecated Obsolete since Ant 1.8.2
+ * @return <tt>true</tt>
+ */
+ public static boolean isOptionalAvailable() {
+ return true;
+ }
+
+ /**
+ * Doesn't do anything.
+ * @deprecated Obsolete since Ant 1.8.2
+ */
+ public static void validateVersion() throws BuildException {
+ }
+
+ /**
+ * return the list of jar files existing in ANT_HOME/lib
+ * and that must have been picked up by Ant script.
+ * @return the list of jar files existing in ant.home/lib or
+ * <tt>null</tt> if an error occurs.
+ */
+ public static File[] listLibraries() {
+ String home = System.getProperty(MagicNames.ANT_HOME);
+ if (home == null) {
+ return null;
+ }
+ File libDir = new File(home, "lib");
+ return listJarFiles(libDir);
+
+ }
+
+ /**
+ * get a list of all JAR files in a directory
+ * @param libDir directory
+ * @return array of files (or null for no such directory)
+ */
+ private static File[] listJarFiles(File libDir) {
+ FilenameFilter filter = new FilenameFilter() {
+ public boolean accept(File dir, String name) {
+ return name.endsWith(".jar");
+ }
+ };
+ File[] files = libDir.listFiles(filter);
+ return files;
+ }
+
+ /**
+ * main entry point for command line
+ * @param args command line arguments.
+ */
+ public static void main(String[] args) {
+ doReport(System.out);
+ }
+
+ /**
+ * Helper method to get the implementation version.
+ * @param clazz the class to get the information from.
+ * @return null if there is no package or implementation version.
+ * '?.?' for JDK 1.0 or 1.1.
+ */
+ private static String getImplementationVersion(Class<?> clazz) {
+ return clazz.getPackage().getImplementationVersion();
+ }
+
+ /**
+ * Helper method to get the location.
+ * @param clazz the class to get the information from.
+ * @since Ant 1.8.0
+ */
+ private static URL getClassLocation(Class<?> clazz) {
+ if (clazz.getProtectionDomain().getCodeSource() == null) {
+ return null;
+ }
+ return clazz.getProtectionDomain().getCodeSource().getLocation();
+ }
+
+ /**
+ * what parser are we using.
+ * @return the classname of the parser
+ */
+ private static String getXMLParserName() {
+ SAXParser saxParser = getSAXParser();
+ if (saxParser == null) {
+ return "Could not create an XML Parser";
+ }
+ // check to what is in the classname
+ String saxParserName = saxParser.getClass().getName();
+ return saxParserName;
+ }
+
+ /**
+ * what parser are we using.
+ * @return the classname of the parser
+ */
+ private static String getXSLTProcessorName() {
+ Transformer transformer = getXSLTProcessor();
+ if (transformer == null) {
+ return "Could not create an XSLT Processor";
+ }
+ // check to what is in the classname
+ String processorName = transformer.getClass().getName();
+ return processorName;
+ }
+
+ /**
+ * Create a JAXP SAXParser
+ * @return parser or null for trouble
+ */
+ private static SAXParser getSAXParser() {
+ SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
+ if (saxParserFactory == null) {
+ return null;
+ }
+ SAXParser saxParser = null;
+ try {
+ saxParser = saxParserFactory.newSAXParser();
+ } catch (Exception e) {
+ // ignore
+ ignoreThrowable(e);
+ }
+ return saxParser;
+ }
+
+ /**
+ * Create a JAXP XSLT Transformer
+ * @return parser or null for trouble
+ */
+ private static Transformer getXSLTProcessor() {
+ TransformerFactory transformerFactory = TransformerFactory.newInstance();
+ if (transformerFactory == null) {
+ return null;
+ }
+ Transformer transformer = null;
+ try {
+ transformer = transformerFactory.newTransformer();
+ } catch (Exception e) {
+ // ignore
+ ignoreThrowable(e);
+ }
+ return transformer;
+ }
+
+ /**
+ * get the location of the parser
+ * @return path or null for trouble in tracking it down
+ */
+ private static String getXMLParserLocation() {
+ SAXParser saxParser = getSAXParser();
+ if (saxParser == null) {
+ return null;
+ }
+ URL location = getClassLocation(saxParser.getClass());
+ return location != null ? location.toString() : null;
+ }
+
+ private static String getNamespaceParserName() {
+ try {
+ XMLReader reader = JAXPUtils.getNamespaceXMLReader();
+ return reader.getClass().getName();
+ } catch (BuildException e) {
+ //ignore
+ ignoreThrowable(e);
+ return null;
+ }
+ }
+
+ private static String getNamespaceParserLocation() {
+ try {
+ XMLReader reader = JAXPUtils.getNamespaceXMLReader();
+ URL location = getClassLocation(reader.getClass());
+ return location != null ? location.toString() : null;
+ } catch (BuildException e) {
+ //ignore
+ ignoreThrowable(e);
+ return null;
+ }
+ }
+
+ /**
+ * get the location of the parser
+ * @return path or null for trouble in tracking it down
+ */
+ private static String getXSLTProcessorLocation() {
+ Transformer transformer = getXSLTProcessor();
+ if (transformer == null) {
+ return null;
+ }
+ URL location = getClassLocation(transformer.getClass());
+ return location != null ? location.toString() : null;
+ }
+
+ /**
+ * ignore exceptions. This is to allow future
+ * implementations to log at a verbose level
+ * @param thrown
+ */
+ private static void ignoreThrowable(Throwable thrown) {
+ }
+
+
+ /**
+ * Print a report to the given stream.
+ * @param out the stream to print the report to.
+ */
+ public static void doReport(PrintStream out) {
+ doReport(out, Project.MSG_INFO);
+ }
+
+ /**
+ * Print a report to the given stream.
+ * @param out the stream to print the report to.
+ * @param logLevel denotes the level of detail requested as one of
+ * Project's MSG_* constants.
+ */
+ public static void doReport(PrintStream out, int logLevel) {
+ out.println("------- Ant diagnostics report -------");
+ out.println(Main.getAntVersion());
+ header(out, "Implementation Version");
+
+ out.println("core tasks : " + getImplementationVersion(Main.class)
+ + " in " + getClassLocation(Main.class));
+
+ header(out, "ANT PROPERTIES");
+ doReportAntProperties(out);
+
+ header(out, "ANT_HOME/lib jar listing");
+ doReportAntHomeLibraries(out);
+
+ header(out, "USER_HOME/.ant/lib jar listing");
+ doReportUserHomeLibraries(out);
+
+ header(out, "Tasks availability");
+ doReportTasksAvailability(out);
+
+ header(out, "org.apache.env.Which diagnostics");
+ doReportWhich(out);
+
+ header(out, "XML Parser information");
+ doReportParserInfo(out);
+
+ header(out, "XSLT Processor information");
+ doReportXSLTProcessorInfo(out);
+
+ header(out, "System properties");
+ doReportSystemProperties(out);
+
+ header(out, "Temp dir");
+ doReportTempDir(out);
+
+ header(out, "Locale information");
+ doReportLocale(out);
+
+ header(out, "Proxy information");
+ doReportProxy(out);
+
+ out.println();
+ }
+
+ private static void header(PrintStream out, String section) {
+ out.println();
+ out.println("-------------------------------------------");
+ out.print(" ");
+ out.println(section);
+ out.println("-------------------------------------------");
+ }
+
+ /**
+ * Report a listing of system properties existing in the current vm.
+ * @param out the stream to print the properties to.
+ */
+ private static void doReportSystemProperties(PrintStream out) {
+ Properties sysprops = null;
+ try {
+ sysprops = System.getProperties();
+ } catch (SecurityException e) {
+ ignoreThrowable(e);
+ out.println("Access to System.getProperties() blocked " + "by a security manager");
+ return;
+ }
+ for (Enumeration<?> keys = sysprops.propertyNames();
+ keys.hasMoreElements();) {
+ String key = (String) keys.nextElement();
+ String value = getProperty(key);
+ out.println(key + " : " + value);
+ }
+ }
+
+ /**
+ * Get the value of a system property. If a security manager
+ * blocks access to a property it fills the result in with an error
+ * @param key
+ * @return the system property's value or error text
+ * @see #ERROR_PROPERTY_ACCESS_BLOCKED
+ */
+ private static String getProperty(String key) {
+ String value;
+ try {
+ value = System.getProperty(key);
+ } catch (SecurityException e) {
+ value = ERROR_PROPERTY_ACCESS_BLOCKED;
+ }
+ return value;
+ }
+
+ /**
+ * Report the content of ANT_HOME/lib directory
+ * @param out the stream to print the content to
+ */
+ private static void doReportAntProperties(PrintStream out) {
+ Project p = new Project();
+ p.initProperties();
+ out.println(MagicNames.ANT_VERSION + ": " + p.getProperty(MagicNames.ANT_VERSION));
+ out.println(MagicNames.ANT_JAVA_VERSION + ": "
+ + p.getProperty(MagicNames.ANT_JAVA_VERSION));
+ out.println("Is this the Apache Harmony VM? "
+ + (JavaEnvUtils.isApacheHarmony() ? "yes" : "no"));
+ out.println("Is this the Kaffe VM? "
+ + (JavaEnvUtils.isKaffe() ? "yes" : "no"));
+ out.println("Is this gij/gcj? "
+ + (JavaEnvUtils.isGij() ? "yes" : "no"));
+ out.println(MagicNames.ANT_LIB + ": " + p.getProperty(MagicNames.ANT_LIB));
+ out.println(MagicNames.ANT_HOME + ": " + p.getProperty(MagicNames.ANT_HOME));
+ }
+
+ /**
+ * Report the content of ANT_HOME/lib directory
+ * @param out the stream to print the content to
+ */
+ private static void doReportAntHomeLibraries(PrintStream out) {
+ out.println(MagicNames.ANT_HOME + ": " + System.getProperty(MagicNames.ANT_HOME));
+ File[] libs = listLibraries();
+ printLibraries(libs, out);
+ }
+
+ /**
+ * Report the content of ~/.ant/lib directory
+ *
+ * @param out the stream to print the content to
+ */
+ private static void doReportUserHomeLibraries(PrintStream out) {
+ String home = System.getProperty(Launcher.USER_HOMEDIR);
+ out.println("user.home: " + home);
+ File libDir = new File(home, Launcher.USER_LIBDIR);
+ File[] libs = listJarFiles(libDir);
+ printLibraries(libs, out);
+ }
+
+ /**
+ * list the libraries
+ * @param libs array of libraries (can be null)
+ * @param out output stream
+ */
+ private static void printLibraries(File[] libs, PrintStream out) {
+ if (libs == null) {
+ out.println("No such directory.");
+ return;
+ }
+ for (int i = 0; i < libs.length; i++) {
+ out.println(libs[i].getName() + " (" + libs[i].length() + " bytes)");
+ }
+ }
+
+
+ /**
+ * Call org.apache.env.Which if available
+ * @param out the stream to print the content to.
+ */
+ private static void doReportWhich(PrintStream out) {
+ Throwable error = null;
+ try {
+ Class<?> which = Class.forName("org.apache.env.Which");
+ Method method = which.getMethod(
+ "main", new Class[] {String[].class});
+ method.invoke(null, new Object[]{new String[]{}});
+ } catch (ClassNotFoundException e) {
+ out.println("Not available.");
+ out.println("Download it at http://xml.apache.org/commons/");
+ } catch (InvocationTargetException e) {
+ error = e.getTargetException() == null ? e : e.getTargetException();
+ } catch (Throwable e) {
+ error = e;
+ }
+ // report error if something weird happens...this is diagnostic.
+ if (error != null) {
+ out.println("Error while running org.apache.env.Which");
+ error.printStackTrace();
+ }
+ }
+
+ /**
+ * Create a report about non-available tasks that are defined in the
+ * mapping but could not be found via lookup. It might generally happen
+ * because Ant requires multiple libraries to compile and one of them
+ * was missing when compiling Ant.
+ * @param out the stream to print the tasks report to
+ * <tt>null</tt> for a missing stream (ie mapping).
+ */
+ private static void doReportTasksAvailability(PrintStream out) {
+ InputStream is = Main.class.getResourceAsStream(
+ MagicNames.TASKDEF_PROPERTIES_RESOURCE);
+ if (is == null) {
+ out.println("None available");
+ } else {
+ Properties props = new Properties();
+ try {
+ props.load(is);
+ for (Enumeration<?> keys = props.keys(); keys.hasMoreElements();) {
+ String key = (String) keys.nextElement();
+ String classname = props.getProperty(key);
+ try {
+ Class.forName(classname);
+ props.remove(key);
+ } catch (ClassNotFoundException e) {
+ out.println(key + " : Not Available "
+ + "(the implementation class is not present)");
+ } catch (NoClassDefFoundError e) {
+ String pkg = e.getMessage().replace('/', '.');
+ out.println(key + " : Missing dependency " + pkg);
+ } catch (LinkageError e) {
+ out.println(key + " : Initialization error");
+ }
+ }
+ if (props.size() == 0) {
+ out.println("All defined tasks are available");
+ } else {
+ out.println("A task being missing/unavailable should only "
+ + "matter if you are trying to use it");
+ }
+ } catch (IOException e) {
+ out.println(e.getMessage());
+ }
+ }
+ }
+
+ /**
+ * tell the user about the XML parser
+ * @param out
+ */
+ private static void doReportParserInfo(PrintStream out) {
+ String parserName = getXMLParserName();
+ String parserLocation = getXMLParserLocation();
+ printParserInfo(out, "XML Parser", parserName, parserLocation);
+ printParserInfo(out, "Namespace-aware parser", getNamespaceParserName(),
+ getNamespaceParserLocation());
+ }
+
+ /**
+ * tell the user about the XSLT processor
+ * @param out
+ */
+ private static void doReportXSLTProcessorInfo(PrintStream out) {
+ String processorName = getXSLTProcessorName();
+ String processorLocation = getXSLTProcessorLocation();
+ printParserInfo(out, "XSLT Processor", processorName, processorLocation);
+ }
+
+ private static void printParserInfo(PrintStream out, String parserType, String parserName,
+ String parserLocation) {
+ if (parserName == null) {
+ parserName = "unknown";
+ }
+ if (parserLocation == null) {
+ parserLocation = "unknown";
+ }
+ out.println(parserType + " : " + parserName);
+ out.println(parserType + " Location: " + parserLocation);
+ }
+
+ /**
+ * try and create a temp file in our temp dir; this
+ * checks that it has space and access.
+ * We also do some clock reporting.
+ * @param out
+ */
+ private static void doReportTempDir(PrintStream out) {
+ String tempdir = System.getProperty("java.io.tmpdir");
+ if (tempdir == null) {
+ out.println("Warning: java.io.tmpdir is undefined");
+ return;
+ }
+ out.println("Temp dir is " + tempdir);
+ File tempDirectory = new File(tempdir);
+ if (!tempDirectory.exists()) {
+ out.println("Warning, java.io.tmpdir directory does not exist: " + tempdir);
+ return;
+ }
+ //create the file
+ long now = System.currentTimeMillis();
+ File tempFile = null;
+ FileOutputStream fileout = null;
+ FileInputStream filein = null;
+ try {
+ tempFile = File.createTempFile("diag", "txt", tempDirectory);
+ //do some writing to it
+ fileout = new FileOutputStream(tempFile);
+ byte[] buffer = new byte[KILOBYTE];
+ for (int i = 0; i < TEST_FILE_SIZE; i++) {
+ fileout.write(buffer);
+ }
+ fileout.close();
+ fileout = null;
+
+ // read to make sure the file has been written completely
+ Thread.sleep(1000);
+ filein = new FileInputStream(tempFile);
+ int total = 0;
+ int read = 0;
+ while ((read = filein.read(buffer, 0, KILOBYTE)) > 0) {
+ total += read;
+ }
+ filein.close();
+ filein = null;
+
+ long filetime = tempFile.lastModified();
+ long drift = filetime - now;
+ tempFile.delete();
+
+ out.print("Temp dir is writeable");
+ if (total != TEST_FILE_SIZE * KILOBYTE) {
+ out.println(", but seems to be full. Wrote "
+ + (TEST_FILE_SIZE * KILOBYTE)
+ + "but could only read " + total + " bytes.");
+ } else {
+ out.println();
+ }
+
+ out.println("Temp dir alignment with system clock is " + drift + " ms");
+ if (Math.abs(drift) > BIG_DRIFT_LIMIT) {
+ out.println("Warning: big clock drift -maybe a network filesystem");
+ }
+ } catch (IOException e) {
+ ignoreThrowable(e);
+ out.println("Failed to create a temporary file in the temp dir " + tempdir);
+ out.println("File " + tempFile + " could not be created/written to");
+ } catch (InterruptedException e) {
+ ignoreThrowable(e);
+ out.println("Failed to check whether tempdir is writable");
+ } finally {
+ FileUtils.close(fileout);
+ FileUtils.close(filein);
+ if (tempFile != null && tempFile.exists()) {
+ tempFile.delete();
+ }
+ }
+ }
+
+ /**
+ * Report locale information
+ * @param out stream to print to
+ */
+ private static void doReportLocale(PrintStream out) {
+ //calendar stuff.
+ Calendar cal = Calendar.getInstance();
+ TimeZone tz = cal.getTimeZone();
+ out.println("Timezone "
+ + tz.getDisplayName()
+ + " offset="
+ + tz.getOffset(cal.get(Calendar.ERA), cal.get(Calendar.YEAR), cal
+ .get(Calendar.MONTH), cal.get(Calendar.DAY_OF_MONTH), cal
+ .get(Calendar.DAY_OF_WEEK), ((cal.get(Calendar.HOUR_OF_DAY)
+ * MINUTES_PER_HOUR + cal.get(Calendar.MINUTE))
+ * SECONDS_PER_MINUTE + cal.get(Calendar.SECOND))
+ * SECONDS_PER_MILLISECOND + cal.get(Calendar.MILLISECOND)));
+ }
+
+ /**
+ * print a property name="value" pair if the property is set;
+ * print nothing if it is null
+ * @param out stream to print on
+ * @param key property name
+ */
+ private static void printProperty(PrintStream out, String key) {
+ String value = getProperty(key);
+ if (value != null) {
+ out.print(key);
+ out.print(" = ");
+ out.print('"');
+ out.print(value);
+ out.println('"');
+ }
+ }
+
+ /**
+ * Report proxy information
+ *
+ * @param out stream to print to
+ * @since Ant1.7
+ */
+ private static void doReportProxy(PrintStream out) {
+ printProperty(out, ProxySetup.HTTP_PROXY_HOST);
+ printProperty(out, ProxySetup.HTTP_PROXY_PORT);
+ printProperty(out, ProxySetup.HTTP_PROXY_USERNAME);
+ printProperty(out, ProxySetup.HTTP_PROXY_PASSWORD);
+ printProperty(out, ProxySetup.HTTP_NON_PROXY_HOSTS);
+ printProperty(out, ProxySetup.HTTPS_PROXY_HOST);
+ printProperty(out, ProxySetup.HTTPS_PROXY_PORT);
+ printProperty(out, ProxySetup.HTTPS_NON_PROXY_HOSTS);
+ printProperty(out, ProxySetup.FTP_PROXY_HOST);
+ printProperty(out, ProxySetup.FTP_PROXY_PORT);
+ printProperty(out, ProxySetup.FTP_NON_PROXY_HOSTS);
+ printProperty(out, ProxySetup.SOCKS_PROXY_HOST);
+ printProperty(out, ProxySetup.SOCKS_PROXY_PORT);
+ printProperty(out, ProxySetup.SOCKS_PROXY_USERNAME);
+ printProperty(out, ProxySetup.SOCKS_PROXY_PASSWORD);
+
+ if (JavaEnvUtils.getJavaVersionNumber() < JAVA_1_5_NUMBER) {
+ return;
+ }
+ printProperty(out, ProxySetup.USE_SYSTEM_PROXIES);
+ final String proxyDiagClassname = "org.apache.tools.ant.util.java15.ProxyDiagnostics";
+ try {
+ Class<?> proxyDiagClass = Class.forName(proxyDiagClassname);
+ Object instance = proxyDiagClass.newInstance();
+ out.println("Java1.5+ proxy settings:");
+ out.println(instance.toString());
+ } catch (ClassNotFoundException e) {
+ //not included, do nothing
+ } catch (IllegalAccessException e) {
+ //not included, do nothing
+ } catch (InstantiationException e) {
+ //not included, do nothing
+ } catch (NoClassDefFoundError e) {
+ // not included, to nothing
+ }
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/DirectoryScanner.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/DirectoryScanner.java
new file mode 100644
index 00000000..709779a7
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/DirectoryScanner.java
@@ -0,0 +1,1900 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.Set;
+import java.util.Vector;
+
+import org.apache.tools.ant.taskdefs.condition.Os;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.ResourceFactory;
+import org.apache.tools.ant.types.resources.FileResource;
+import org.apache.tools.ant.types.selectors.FileSelector;
+import org.apache.tools.ant.types.selectors.SelectorScanner;
+import org.apache.tools.ant.types.selectors.SelectorUtils;
+import org.apache.tools.ant.types.selectors.TokenizedPath;
+import org.apache.tools.ant.types.selectors.TokenizedPattern;
+import org.apache.tools.ant.util.CollectionUtils;
+import org.apache.tools.ant.util.FileUtils;
+import org.apache.tools.ant.util.SymbolicLinkUtils;
+import org.apache.tools.ant.util.VectorSet;
+
+/**
+ * Class for scanning a directory for files/directories which match certain
+ * criteria.
+ * <p>
+ * These criteria consist of selectors and patterns which have been specified.
+ * With the selectors you can select which files you want to have included.
+ * Files which are not selected are excluded. With patterns you can include
+ * or exclude files based on their filename.
+ * <p>
+ * The idea is simple. A given directory is recursively scanned for all files
+ * and directories. Each file/directory is matched against a set of selectors,
+ * including special support for matching against filenames with include and
+ * and exclude patterns. Only files/directories which match at least one
+ * pattern of the include pattern list or other file selector, and don't match
+ * any pattern of the exclude pattern list or fail to match against a required
+ * selector will be placed in the list of files/directories found.
+ * <p>
+ * When no list of include patterns is supplied, "**" will be used, which
+ * means that everything will be matched. When no list of exclude patterns is
+ * supplied, an empty list is used, such that nothing will be excluded. When
+ * no selectors are supplied, none are applied.
+ * <p>
+ * The filename pattern matching is done as follows:
+ * The name to be matched is split up in path segments. A path segment is the
+ * name of a directory or file, which is bounded by
+ * <code>File.separator</code> ('/' under UNIX, '\' under Windows).
+ * For example, "abc/def/ghi/xyz.java" is split up in the segments "abc",
+ * "def","ghi" and "xyz.java".
+ * The same is done for the pattern against which should be matched.
+ * <p>
+ * The segments of the name and the pattern are then matched against each
+ * other. When '**' is used for a path segment in the pattern, it matches
+ * zero or more path segments of the name.
+ * <p>
+ * There is a special case regarding the use of <code>File.separator</code>s
+ * at the beginning of the pattern and the string to match:<br>
+ * When a pattern starts with a <code>File.separator</code>, the string
+ * to match must also start with a <code>File.separator</code>.
+ * When a pattern does not start with a <code>File.separator</code>, the
+ * string to match may not start with a <code>File.separator</code>.
+ * When one of these rules is not obeyed, the string will not
+ * match.
+ * <p>
+ * When a name path segment is matched against a pattern path segment, the
+ * following special characters can be used:<br>
+ * '*' matches zero or more characters<br>
+ * '?' matches one character.
+ * <p>
+ * Examples:
+ * <p>
+ * "**\*.class" matches all .class files/dirs in a directory tree.
+ * <p>
+ * "test\a??.java" matches all files/dirs which start with an 'a', then two
+ * more characters and then ".java", in a directory called test.
+ * <p>
+ * "**" matches everything in a directory tree.
+ * <p>
+ * "**\test\**\XYZ*" matches all files/dirs which start with "XYZ" and where
+ * there is a parent directory called test (e.g. "abc\test\def\ghi\XYZ123").
+ * <p>
+ * Case sensitivity may be turned off if necessary. By default, it is
+ * turned on.
+ * <p>
+ * Example of usage:
+ * <pre>
+ * String[] includes = {"**\\*.class"};
+ * String[] excludes = {"modules\\*\\**"};
+ * ds.setIncludes(includes);
+ * ds.setExcludes(excludes);
+ * ds.setBasedir(new File("test"));
+ * ds.setCaseSensitive(true);
+ * ds.scan();
+ *
+ * System.out.println("FILES:");
+ * String[] files = ds.getIncludedFiles();
+ * for (int i = 0; i &lt; files.length; i++) {
+ * System.out.println(files[i]);
+ * }
+ * </pre>
+ * This will scan a directory called test for .class files, but excludes all
+ * files in all proper subdirectories of a directory called "modules".
+ *
+ */
+public class DirectoryScanner
+ implements FileScanner, SelectorScanner, ResourceFactory {
+
+ /** Is OpenVMS the operating system we're running on? */
+ private static final boolean ON_VMS = Os.isFamily("openvms");
+
+ /**
+ * Patterns which should be excluded by default.
+ *
+ * <p>Note that you can now add patterns to the list of default
+ * excludes. Added patterns will not become part of this array
+ * that has only been kept around for backwards compatibility
+ * reasons.</p>
+ *
+ * @deprecated since 1.6.x.
+ * Use the {@link #getDefaultExcludes getDefaultExcludes}
+ * method instead.
+ */
+ @Deprecated
+ protected static final String[] DEFAULTEXCLUDES = {
+ // Miscellaneous typical temporary files
+ SelectorUtils.DEEP_TREE_MATCH + "/*~",
+ SelectorUtils.DEEP_TREE_MATCH + "/#*#",
+ SelectorUtils.DEEP_TREE_MATCH + "/.#*",
+ SelectorUtils.DEEP_TREE_MATCH + "/%*%",
+ SelectorUtils.DEEP_TREE_MATCH + "/._*",
+
+ // CVS
+ SelectorUtils.DEEP_TREE_MATCH + "/CVS",
+ SelectorUtils.DEEP_TREE_MATCH + "/CVS/" + SelectorUtils.DEEP_TREE_MATCH,
+ SelectorUtils.DEEP_TREE_MATCH + "/.cvsignore",
+
+ // SCCS
+ SelectorUtils.DEEP_TREE_MATCH + "/SCCS",
+ SelectorUtils.DEEP_TREE_MATCH + "/SCCS/" + SelectorUtils.DEEP_TREE_MATCH,
+
+ // Visual SourceSafe
+ SelectorUtils.DEEP_TREE_MATCH + "/vssver.scc",
+
+ // Subversion
+ SelectorUtils.DEEP_TREE_MATCH + "/.svn",
+ SelectorUtils.DEEP_TREE_MATCH + "/.svn/" + SelectorUtils.DEEP_TREE_MATCH,
+
+ // Git
+ SelectorUtils.DEEP_TREE_MATCH + "/.git",
+ SelectorUtils.DEEP_TREE_MATCH + "/.git/" + SelectorUtils.DEEP_TREE_MATCH,
+ SelectorUtils.DEEP_TREE_MATCH + "/.gitattributes",
+ SelectorUtils.DEEP_TREE_MATCH + "/.gitignore",
+ SelectorUtils.DEEP_TREE_MATCH + "/.gitmodules",
+
+ // Mercurial
+ SelectorUtils.DEEP_TREE_MATCH + "/.hg",
+ SelectorUtils.DEEP_TREE_MATCH + "/.hg/" + SelectorUtils.DEEP_TREE_MATCH,
+ SelectorUtils.DEEP_TREE_MATCH + "/.hgignore",
+ SelectorUtils.DEEP_TREE_MATCH + "/.hgsub",
+ SelectorUtils.DEEP_TREE_MATCH + "/.hgsubstate",
+ SelectorUtils.DEEP_TREE_MATCH + "/.hgtags",
+
+ // Bazaar
+ SelectorUtils.DEEP_TREE_MATCH + "/.bzr",
+ SelectorUtils.DEEP_TREE_MATCH + "/.bzr/" + SelectorUtils.DEEP_TREE_MATCH,
+ SelectorUtils.DEEP_TREE_MATCH + "/.bzrignore",
+
+ // Mac
+ SelectorUtils.DEEP_TREE_MATCH + "/.DS_Store"
+ };
+
+ /**
+ * default value for {@link #maxLevelsOfSymlinks maxLevelsOfSymlinks}
+ * @since Ant 1.8.0
+ */
+ public static final int MAX_LEVELS_OF_SYMLINKS = 5;
+ /**
+ * The end of the exception message if something that should be
+ * there doesn't exist.
+ */
+ public static final String DOES_NOT_EXIST_POSTFIX = " does not exist.";
+
+ /** Helper. */
+ private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+
+ /** Helper. */
+ private static final SymbolicLinkUtils SYMLINK_UTILS =
+ SymbolicLinkUtils.getSymbolicLinkUtils();
+
+ /**
+ * Patterns which should be excluded by default.
+ *
+ * @see #addDefaultExcludes()
+ */
+ private static final Set<String> defaultExcludes = new HashSet<String>();
+ static {
+ resetDefaultExcludes();
+ }
+
+ // CheckStyle:VisibilityModifier OFF - bc
+
+ /** The base directory to be scanned. */
+ protected File basedir;
+
+ /** The patterns for the files to be included. */
+ protected String[] includes;
+
+ /** The patterns for the files to be excluded. */
+ protected String[] excludes;
+
+ /** Selectors that will filter which files are in our candidate list. */
+ protected FileSelector[] selectors = null;
+
+ /**
+ * The files which matched at least one include and no excludes
+ * and were selected.
+ */
+ protected Vector<String> filesIncluded;
+
+ /** The files which did not match any includes or selectors. */
+ protected Vector<String> filesNotIncluded;
+
+ /**
+ * The files which matched at least one include and at least
+ * one exclude.
+ */
+ protected Vector<String> filesExcluded;
+
+ /**
+ * The directories which matched at least one include and no excludes
+ * and were selected.
+ */
+ protected Vector<String> dirsIncluded;
+
+ /** The directories which were found and did not match any includes. */
+ protected Vector<String> dirsNotIncluded;
+
+ /**
+ * The directories which matched at least one include and at least one
+ * exclude.
+ */
+ protected Vector<String> dirsExcluded;
+
+ /**
+ * The files which matched at least one include and no excludes and
+ * which a selector discarded.
+ */
+ protected Vector<String> filesDeselected;
+
+ /**
+ * The directories which matched at least one include and no excludes
+ * but which a selector discarded.
+ */
+ protected Vector<String> dirsDeselected;
+
+ /** Whether or not our results were built by a slow scan. */
+ protected boolean haveSlowResults = false;
+
+ /**
+ * Whether or not the file system should be treated as a case sensitive
+ * one.
+ */
+ protected boolean isCaseSensitive = true;
+
+ /**
+ * Whether a missing base directory is an error.
+ * @since Ant 1.7.1
+ */
+ protected boolean errorOnMissingDir = true;
+
+ /**
+ * Whether or not symbolic links should be followed.
+ *
+ * @since Ant 1.5
+ */
+ private boolean followSymlinks = true;
+
+ /** Whether or not everything tested so far has been included. */
+ protected boolean everythingIncluded = true;
+
+ // CheckStyle:VisibilityModifier ON
+
+ /**
+ * List of all scanned directories.
+ *
+ * @since Ant 1.6
+ */
+ private final Set<String> scannedDirs = new HashSet<String>();
+
+ /**
+ * Map of all include patterns that are full file names and don't
+ * contain any wildcards.
+ *
+ * <p>Maps pattern string to TokenizedPath.</p>
+ *
+ * <p>If this instance is not case sensitive, the file names get
+ * turned to upper case.</p>
+ *
+ * <p>Gets lazily initialized on the first invocation of
+ * isIncluded or isExcluded and cleared at the end of the scan
+ * method (cleared in clearCaches, actually).</p>
+ *
+ * @since Ant 1.8.0
+ */
+ private final Map<String, TokenizedPath> includeNonPatterns = new HashMap<String, TokenizedPath>();
+
+ /**
+ * Map of all exclude patterns that are full file names and don't
+ * contain any wildcards.
+ *
+ * <p>Maps pattern string to TokenizedPath.</p>
+ *
+ * <p>If this instance is not case sensitive, the file names get
+ * turned to upper case.</p>
+ *
+ * <p>Gets lazily initialized on the first invocation of
+ * isIncluded or isExcluded and cleared at the end of the scan
+ * method (cleared in clearCaches, actually).</p>
+ *
+ * @since Ant 1.8.0
+ */
+ private final Map<String, TokenizedPath> excludeNonPatterns = new HashMap<String, TokenizedPath>();
+
+ /**
+ * Array of all include patterns that contain wildcards.
+ *
+ * <p>Gets lazily initialized on the first invocation of
+ * isIncluded or isExcluded and cleared at the end of the scan
+ * method (cleared in clearCaches, actually).</p>
+ */
+ private TokenizedPattern[] includePatterns;
+
+ /**
+ * Array of all exclude patterns that contain wildcards.
+ *
+ * <p>Gets lazily initialized on the first invocation of
+ * isIncluded or isExcluded and cleared at the end of the scan
+ * method (cleared in clearCaches, actually).</p>
+ */
+ private TokenizedPattern[] excludePatterns;
+
+ /**
+ * Have the non-pattern sets and pattern arrays for in- and
+ * excludes been initialized?
+ *
+ * @since Ant 1.6.3
+ */
+ private boolean areNonPatternSetsReady = false;
+
+ /**
+ * Scanning flag.
+ *
+ * @since Ant 1.6.3
+ */
+ private boolean scanning = false;
+
+ /**
+ * Scanning lock.
+ *
+ * @since Ant 1.6.3
+ */
+ private final Object scanLock = new Object();
+
+ /**
+ * Slow scanning flag.
+ *
+ * @since Ant 1.6.3
+ */
+ private boolean slowScanning = false;
+
+ /**
+ * Slow scanning lock.
+ *
+ * @since Ant 1.6.3
+ */
+ private final Object slowScanLock = new Object();
+
+ /**
+ * Exception thrown during scan.
+ *
+ * @since Ant 1.6.3
+ */
+ private IllegalStateException illegal = null;
+
+ /**
+ * The maximum number of times a symbolic link may be followed
+ * during a scan.
+ *
+ * @since Ant 1.8.0
+ */
+ private int maxLevelsOfSymlinks = MAX_LEVELS_OF_SYMLINKS;
+
+
+ /**
+ * Absolute paths of all symlinks that haven't been followed but
+ * would have been if followsymlinks had been true or
+ * maxLevelsOfSymlinks had been higher.
+ *
+ * @since Ant 1.8.0
+ */
+ private final Set<String> notFollowedSymlinks = new HashSet<String>();
+
+ /**
+ * Sole constructor.
+ */
+ public DirectoryScanner() {
+ }
+
+ /**
+ * Test whether or not a given path matches the start of a given
+ * pattern up to the first "**".
+ * <p>
+ * This is not a general purpose test and should only be used if you
+ * can live with false positives. For example, <code>pattern=**\a</code>
+ * and <code>str=b</code> will yield <code>true</code>.
+ *
+ * @param pattern The pattern to match against. Must not be
+ * <code>null</code>.
+ * @param str The path to match, as a String. Must not be
+ * <code>null</code>.
+ *
+ * @return whether or not a given path matches the start of a given
+ * pattern up to the first "**".
+ */
+ protected static boolean matchPatternStart(final String pattern, final String str) {
+ return SelectorUtils.matchPatternStart(pattern, str);
+ }
+
+ /**
+ * Test whether or not a given path matches the start of a given
+ * pattern up to the first "**".
+ * <p>
+ * This is not a general purpose test and should only be used if you
+ * can live with false positives. For example, <code>pattern=**\a</code>
+ * and <code>str=b</code> will yield <code>true</code>.
+ *
+ * @param pattern The pattern to match against. Must not be
+ * <code>null</code>.
+ * @param str The path to match, as a String. Must not be
+ * <code>null</code>.
+ * @param isCaseSensitive Whether or not matching should be performed
+ * case sensitively.
+ *
+ * @return whether or not a given path matches the start of a given
+ * pattern up to the first "**".
+ */
+ protected static boolean matchPatternStart(final String pattern, final String str,
+ final boolean isCaseSensitive) {
+ return SelectorUtils.matchPatternStart(pattern, str, isCaseSensitive);
+ }
+
+ /**
+ * Test whether or not a given path matches a given pattern.
+ *
+ * @param pattern The pattern to match against. Must not be
+ * <code>null</code>.
+ * @param str The path to match, as a String. Must not be
+ * <code>null</code>.
+ *
+ * @return <code>true</code> if the pattern matches against the string,
+ * or <code>false</code> otherwise.
+ */
+ protected static boolean matchPath(final String pattern, final String str) {
+ return SelectorUtils.matchPath(pattern, str);
+ }
+
+ /**
+ * Test whether or not a given path matches a given pattern.
+ *
+ * @param pattern The pattern to match against. Must not be
+ * <code>null</code>.
+ * @param str The path to match, as a String. Must not be
+ * <code>null</code>.
+ * @param isCaseSensitive Whether or not matching should be performed
+ * case sensitively.
+ *
+ * @return <code>true</code> if the pattern matches against the string,
+ * or <code>false</code> otherwise.
+ */
+ protected static boolean matchPath(final String pattern, final String str,
+ final boolean isCaseSensitive) {
+ return SelectorUtils.matchPath(pattern, str, isCaseSensitive);
+ }
+
+ /**
+ * Test whether or not a string matches against a pattern.
+ * The pattern may contain two special characters:<br>
+ * '*' means zero or more characters<br>
+ * '?' means one and only one character
+ *
+ * @param pattern The pattern to match against.
+ * Must not be <code>null</code>.
+ * @param str The string which must be matched against the pattern.
+ * Must not be <code>null</code>.
+ *
+ * @return <code>true</code> if the string matches against the pattern,
+ * or <code>false</code> otherwise.
+ */
+ public static boolean match(final String pattern, final String str) {
+ return SelectorUtils.match(pattern, str);
+ }
+
+ /**
+ * Test whether or not a string matches against a pattern.
+ * The pattern may contain two special characters:<br>
+ * '*' means zero or more characters<br>
+ * '?' means one and only one character
+ *
+ * @param pattern The pattern to match against.
+ * Must not be <code>null</code>.
+ * @param str The string which must be matched against the pattern.
+ * Must not be <code>null</code>.
+ * @param isCaseSensitive Whether or not matching should be performed
+ * case sensitively.
+ *
+ *
+ * @return <code>true</code> if the string matches against the pattern,
+ * or <code>false</code> otherwise.
+ */
+ protected static boolean match(final String pattern, final String str,
+ final boolean isCaseSensitive) {
+ return SelectorUtils.match(pattern, str, isCaseSensitive);
+ }
+
+
+ /**
+ * Get the list of patterns that should be excluded by default.
+ *
+ * @return An array of <code>String</code> based on the current
+ * contents of the <code>defaultExcludes</code>
+ * <code>Set</code>.
+ *
+ * @since Ant 1.6
+ */
+ public static String[] getDefaultExcludes() {
+ synchronized (defaultExcludes) {
+ return defaultExcludes.toArray(new String[defaultExcludes
+ .size()]);
+ }
+ }
+
+ /**
+ * Add a pattern to the default excludes unless it is already a
+ * default exclude.
+ *
+ * @param s A string to add as an exclude pattern.
+ * @return <code>true</code> if the string was added;
+ * <code>false</code> if it already existed.
+ *
+ * @since Ant 1.6
+ */
+ public static boolean addDefaultExclude(final String s) {
+ synchronized (defaultExcludes) {
+ return defaultExcludes.add(s);
+ }
+ }
+
+ /**
+ * Remove a string if it is a default exclude.
+ *
+ * @param s The string to attempt to remove.
+ * @return <code>true</code> if <code>s</code> was a default
+ * exclude (and thus was removed);
+ * <code>false</code> if <code>s</code> was not
+ * in the default excludes list to begin with.
+ *
+ * @since Ant 1.6
+ */
+ public static boolean removeDefaultExclude(final String s) {
+ synchronized (defaultExcludes) {
+ return defaultExcludes.remove(s);
+ }
+ }
+
+ /**
+ * Go back to the hardwired default exclude patterns.
+ *
+ * @since Ant 1.6
+ */
+ public static void resetDefaultExcludes() {
+ synchronized (defaultExcludes) {
+ defaultExcludes.clear();
+ for (int i = 0; i < DEFAULTEXCLUDES.length; i++) {
+ defaultExcludes.add(DEFAULTEXCLUDES[i]);
+ }
+ }
+ }
+
+ /**
+ * Set the base directory to be scanned. This is the directory which is
+ * scanned recursively. All '/' and '\' characters are replaced by
+ * <code>File.separatorChar</code>, so the separator used need not match
+ * <code>File.separatorChar</code>.
+ *
+ * @param basedir The base directory to scan.
+ */
+ public void setBasedir(final String basedir) {
+ setBasedir(basedir == null ? (File) null
+ : new File(basedir.replace('/', File.separatorChar).replace(
+ '\\', File.separatorChar)));
+ }
+
+ /**
+ * Set the base directory to be scanned. This is the directory which is
+ * scanned recursively.
+ *
+ * @param basedir The base directory for scanning.
+ */
+ public synchronized void setBasedir(final File basedir) {
+ this.basedir = basedir;
+ }
+
+ /**
+ * Return the base directory to be scanned.
+ * This is the directory which is scanned recursively.
+ *
+ * @return the base directory to be scanned.
+ */
+ public synchronized File getBasedir() {
+ return basedir;
+ }
+
+ /**
+ * Find out whether include exclude patterns are matched in a
+ * case sensitive way.
+ * @return whether or not the scanning is case sensitive.
+ * @since Ant 1.6
+ */
+ public synchronized boolean isCaseSensitive() {
+ return isCaseSensitive;
+ }
+
+ /**
+ * Set whether or not include and exclude patterns are matched
+ * in a case sensitive way.
+ *
+ * @param isCaseSensitive whether or not the file system should be
+ * regarded as a case sensitive one.
+ */
+ public synchronized void setCaseSensitive(final boolean isCaseSensitive) {
+ this.isCaseSensitive = isCaseSensitive;
+ }
+
+ /**
+ * Sets whether or not a missing base directory is an error
+ *
+ * @param errorOnMissingDir whether or not a missing base directory
+ * is an error
+ * @since Ant 1.7.1
+ */
+ public void setErrorOnMissingDir(final boolean errorOnMissingDir) {
+ this.errorOnMissingDir = errorOnMissingDir;
+ }
+
+ /**
+ * Get whether or not a DirectoryScanner follows symbolic links.
+ *
+ * @return flag indicating whether symbolic links should be followed.
+ *
+ * @since Ant 1.6
+ */
+ public synchronized boolean isFollowSymlinks() {
+ return followSymlinks;
+ }
+
+ /**
+ * Set whether or not symbolic links should be followed.
+ *
+ * @param followSymlinks whether or not symbolic links should be followed.
+ */
+ public synchronized void setFollowSymlinks(final boolean followSymlinks) {
+ this.followSymlinks = followSymlinks;
+ }
+
+ /**
+ * The maximum number of times a symbolic link may be followed
+ * during a scan.
+ *
+ * @since Ant 1.8.0
+ */
+ public void setMaxLevelsOfSymlinks(final int max) {
+ maxLevelsOfSymlinks = max;
+ }
+
+ /**
+ * Set the list of include patterns to use. All '/' and '\' characters
+ * are replaced by <code>File.separatorChar</code>, so the separator used
+ * need not match <code>File.separatorChar</code>.
+ * <p>
+ * When a pattern ends with a '/' or '\', "**" is appended.
+ *
+ * @param includes A list of include patterns.
+ * May be <code>null</code>, indicating that all files
+ * should be included. If a non-<code>null</code>
+ * list is given, all elements must be
+ * non-<code>null</code>.
+ */
+ public synchronized void setIncludes(final String[] includes) {
+ if (includes == null) {
+ this.includes = null;
+ } else {
+ this.includes = new String[includes.length];
+ for (int i = 0; i < includes.length; i++) {
+ this.includes[i] = normalizePattern(includes[i]);
+ }
+ }
+ }
+
+ /**
+ * Set the list of exclude patterns to use. All '/' and '\' characters
+ * are replaced by <code>File.separatorChar</code>, so the separator used
+ * need not match <code>File.separatorChar</code>.
+ * <p>
+ * When a pattern ends with a '/' or '\', "**" is appended.
+ *
+ * @param excludes A list of exclude patterns.
+ * May be <code>null</code>, indicating that no files
+ * should be excluded. If a non-<code>null</code> list is
+ * given, all elements must be non-<code>null</code>.
+ */
+ public synchronized void setExcludes(final String[] excludes) {
+ if (excludes == null) {
+ this.excludes = null;
+ } else {
+ this.excludes = new String[excludes.length];
+ for (int i = 0; i < excludes.length; i++) {
+ this.excludes[i] = normalizePattern(excludes[i]);
+ }
+ }
+ }
+
+ /**
+ * Add to the list of exclude patterns to use. All '/' and '\'
+ * characters are replaced by <code>File.separatorChar</code>, so
+ * the separator used need not match <code>File.separatorChar</code>.
+ * <p>
+ * When a pattern ends with a '/' or '\', "**" is appended.
+ *
+ * @param excludes A list of exclude patterns.
+ * May be <code>null</code>, in which case the
+ * exclude patterns don't get changed at all.
+ *
+ * @since Ant 1.6.3
+ */
+ public synchronized void addExcludes(final String[] excludes) {
+ if (excludes != null && excludes.length > 0) {
+ if (this.excludes != null && this.excludes.length > 0) {
+ final String[] tmp = new String[excludes.length
+ + this.excludes.length];
+ System.arraycopy(this.excludes, 0, tmp, 0,
+ this.excludes.length);
+ for (int i = 0; i < excludes.length; i++) {
+ tmp[this.excludes.length + i] =
+ normalizePattern(excludes[i]);
+ }
+ this.excludes = tmp;
+ } else {
+ setExcludes(excludes);
+ }
+ }
+ }
+
+ /**
+ * All '/' and '\' characters are replaced by
+ * <code>File.separatorChar</code>, so the separator used need not
+ * match <code>File.separatorChar</code>.
+ *
+ * <p> When a pattern ends with a '/' or '\', "**" is appended.
+ *
+ * @since Ant 1.6.3
+ */
+ private static String normalizePattern(final String p) {
+ String pattern = p.replace('/', File.separatorChar)
+ .replace('\\', File.separatorChar);
+ if (pattern.endsWith(File.separator)) {
+ pattern += SelectorUtils.DEEP_TREE_MATCH;
+ }
+ return pattern;
+ }
+
+ /**
+ * Set the selectors that will select the filelist.
+ *
+ * @param selectors specifies the selectors to be invoked on a scan.
+ */
+ public synchronized void setSelectors(final FileSelector[] selectors) {
+ this.selectors = selectors;
+ }
+
+ /**
+ * Return whether or not the scanner has included all the files or
+ * directories it has come across so far.
+ *
+ * @return <code>true</code> if all files and directories which have
+ * been found so far have been included.
+ */
+ public synchronized boolean isEverythingIncluded() {
+ return everythingIncluded;
+ }
+
+ /**
+ * Scan for files which match at least one include pattern and don't match
+ * any exclude patterns. If there are selectors then the files must pass
+ * muster there, as well. Scans under basedir, if set; otherwise the
+ * include patterns without leading wildcards specify the absolute paths of
+ * the files that may be included.
+ *
+ * @exception IllegalStateException if the base directory was set
+ * incorrectly (i.e. if it doesn't exist or isn't a directory).
+ */
+ public void scan() throws IllegalStateException {
+ synchronized (scanLock) {
+ if (scanning) {
+ while (scanning) {
+ try {
+ scanLock.wait();
+ } catch (final InterruptedException e) {
+ continue;
+ }
+ }
+ if (illegal != null) {
+ throw illegal;
+ }
+ return;
+ }
+ scanning = true;
+ }
+ final File savedBase = basedir;
+ try {
+ synchronized (this) {
+ illegal = null;
+ clearResults();
+
+ // set in/excludes to reasonable defaults if needed:
+ final boolean nullIncludes = (includes == null);
+ includes = nullIncludes
+ ? new String[] {SelectorUtils.DEEP_TREE_MATCH} : includes;
+ final boolean nullExcludes = (excludes == null);
+ excludes = nullExcludes ? new String[0] : excludes;
+
+ if (basedir != null && !followSymlinks
+ && SYMLINK_UTILS.isSymbolicLink(basedir)) {
+ notFollowedSymlinks.add(basedir.getAbsolutePath());
+ basedir = null;
+ }
+
+ if (basedir == null) {
+ // if no basedir and no includes, nothing to do:
+ if (nullIncludes) {
+ return;
+ }
+ } else {
+ if (!basedir.exists()) {
+ if (errorOnMissingDir) {
+ illegal = new IllegalStateException("basedir "
+ + basedir
+ + DOES_NOT_EXIST_POSTFIX);
+ } else {
+ // Nothing to do - basedir does not exist
+ return;
+ }
+ } else if (!basedir.isDirectory()) {
+ illegal = new IllegalStateException("basedir "
+ + basedir
+ + " is not a"
+ + " directory.");
+ }
+ if (illegal != null) {
+ throw illegal;
+ }
+ }
+ if (isIncluded(TokenizedPath.EMPTY_PATH)) {
+ if (!isExcluded(TokenizedPath.EMPTY_PATH)) {
+ if (isSelected("", basedir)) {
+ dirsIncluded.addElement("");
+ } else {
+ dirsDeselected.addElement("");
+ }
+ } else {
+ dirsExcluded.addElement("");
+ }
+ } else {
+ dirsNotIncluded.addElement("");
+ }
+ checkIncludePatterns();
+ clearCaches();
+ includes = nullIncludes ? null : includes;
+ excludes = nullExcludes ? null : excludes;
+ }
+ } catch (final IOException ex) {
+ throw new BuildException(ex);
+ } finally {
+ basedir = savedBase;
+ synchronized (scanLock) {
+ scanning = false;
+ scanLock.notifyAll();
+ }
+ }
+ }
+
+ /**
+ * This routine is actually checking all the include patterns in
+ * order to avoid scanning everything under base dir.
+ * @since Ant 1.6
+ */
+ private void checkIncludePatterns() {
+ ensureNonPatternSetsReady();
+ final Map<TokenizedPath, String> newroots = new HashMap<TokenizedPath, String>();
+
+ // put in the newroots map the include patterns without
+ // wildcard tokens
+ for (int i = 0; i < includePatterns.length; i++) {
+ final String pattern = includePatterns[i].toString();
+ if (!shouldSkipPattern(pattern)) {
+ newroots.put(includePatterns[i].rtrimWildcardTokens(),
+ pattern);
+ }
+ }
+ for (final Map.Entry<String, TokenizedPath> entry : includeNonPatterns.entrySet()) {
+ final String pattern = entry.getKey();
+ if (!shouldSkipPattern(pattern)) {
+ newroots.put(entry.getValue(), pattern);
+ }
+ }
+
+ if (newroots.containsKey(TokenizedPath.EMPTY_PATH)
+ && basedir != null) {
+ // we are going to scan everything anyway
+ scandir(basedir, "", true);
+ } else {
+ File canonBase = null;
+ if (basedir != null) {
+ try {
+ canonBase = basedir.getCanonicalFile();
+ } catch (final IOException ex) {
+ throw new BuildException(ex);
+ }
+ }
+ // only scan directories that can include matched files or
+ // directories
+ for (final Map.Entry<TokenizedPath, String> entry : newroots.entrySet()) {
+ TokenizedPath currentPath = entry.getKey();
+ String currentelement = currentPath.toString();
+ if (basedir == null
+ && !FileUtils.isAbsolutePath(currentelement)) {
+ continue;
+ }
+ File myfile = new File(basedir, currentelement);
+
+ if (myfile.exists()) {
+ // may be on a case insensitive file system. We want
+ // the results to show what's really on the disk, so
+ // we need to double check.
+ try {
+ final String path = (basedir == null)
+ ? myfile.getCanonicalPath()
+ : FILE_UTILS.removeLeadingPath(canonBase,
+ myfile.getCanonicalFile());
+ if (!path.equals(currentelement) || ON_VMS) {
+ myfile = currentPath.findFile(basedir, true);
+ if (myfile != null && basedir != null) {
+ currentelement = FILE_UTILS.removeLeadingPath(
+ basedir, myfile);
+ if (!currentPath.toString()
+ .equals(currentelement)) {
+ currentPath =
+ new TokenizedPath(currentelement);
+ }
+ }
+ }
+ } catch (final IOException ex) {
+ throw new BuildException(ex);
+ }
+ }
+
+ if ((myfile == null || !myfile.exists()) && !isCaseSensitive()) {
+ final File f = currentPath.findFile(basedir, false);
+ if (f != null && f.exists()) {
+ // adapt currentelement to the case we've
+ // actually found
+ currentelement = (basedir == null)
+ ? f.getAbsolutePath()
+ : FILE_UTILS.removeLeadingPath(basedir, f);
+ myfile = f;
+ currentPath = new TokenizedPath(currentelement);
+ }
+ }
+
+ if (myfile != null && myfile.exists()) {
+ if (!followSymlinks && currentPath.isSymlink(basedir)) {
+ accountForNotFollowedSymlink(currentPath, myfile);
+ continue;
+ }
+ if (myfile.isDirectory()) {
+ if (isIncluded(currentPath)
+ && currentelement.length() > 0) {
+ accountForIncludedDir(currentPath, myfile, true);
+ } else {
+ scandir(myfile, currentPath, true);
+ }
+ } else if (myfile.isFile()) {
+ final String originalpattern = entry.getValue();
+ final boolean included = isCaseSensitive()
+ ? originalpattern.equals(currentelement)
+ : originalpattern.equalsIgnoreCase(currentelement);
+ if (included) {
+ accountForIncludedFile(currentPath, myfile);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * true if the pattern specifies a relative path without basedir
+ * or an absolute path not inside basedir.
+ *
+ * @since Ant 1.8.0
+ */
+ private boolean shouldSkipPattern(final String pattern) {
+ if (FileUtils.isAbsolutePath(pattern)) {
+ //skip abs. paths not under basedir, if set:
+ if (basedir != null
+ && !SelectorUtils.matchPatternStart(pattern,
+ basedir.getAbsolutePath(),
+ isCaseSensitive())) {
+ return true;
+ }
+ } else if (basedir == null) {
+ //skip non-abs. paths if basedir == null:
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Clear the result caches for a scan.
+ */
+ protected synchronized void clearResults() {
+ filesIncluded = new VectorSet<String>();
+ filesNotIncluded = new VectorSet<String>();
+ filesExcluded = new VectorSet<String>();
+ filesDeselected = new VectorSet<String>();
+ dirsIncluded = new VectorSet<String>();
+ dirsNotIncluded = new VectorSet<String>();
+ dirsExcluded = new VectorSet<String>();
+ dirsDeselected = new VectorSet<String>();
+ everythingIncluded = (basedir != null);
+ scannedDirs.clear();
+ notFollowedSymlinks.clear();
+ }
+
+ /**
+ * Top level invocation for a slow scan. A slow scan builds up a full
+ * list of excluded/included files/directories, whereas a fast scan
+ * will only have full results for included files, as it ignores
+ * directories which can't possibly hold any included files/directories.
+ * <p>
+ * Returns immediately if a slow scan has already been completed.
+ */
+ protected void slowScan() {
+ synchronized (slowScanLock) {
+ if (haveSlowResults) {
+ return;
+ }
+ if (slowScanning) {
+ while (slowScanning) {
+ try {
+ slowScanLock.wait();
+ } catch (final InterruptedException e) {
+ // Empty
+ }
+ }
+ return;
+ }
+ slowScanning = true;
+ }
+ try {
+ synchronized (this) {
+
+ // set in/excludes to reasonable defaults if needed:
+ final boolean nullIncludes = (includes == null);
+ includes = nullIncludes
+ ? new String[] {SelectorUtils.DEEP_TREE_MATCH} : includes;
+ final boolean nullExcludes = (excludes == null);
+ excludes = nullExcludes ? new String[0] : excludes;
+
+ final String[] excl = new String[dirsExcluded.size()];
+ dirsExcluded.copyInto(excl);
+
+ final String[] notIncl = new String[dirsNotIncluded.size()];
+ dirsNotIncluded.copyInto(notIncl);
+
+ ensureNonPatternSetsReady();
+
+ processSlowScan(excl);
+ processSlowScan(notIncl);
+ clearCaches();
+ includes = nullIncludes ? null : includes;
+ excludes = nullExcludes ? null : excludes;
+ }
+ } finally {
+ synchronized (slowScanLock) {
+ haveSlowResults = true;
+ slowScanning = false;
+ slowScanLock.notifyAll();
+ }
+ }
+ }
+
+ private void processSlowScan(final String[] arr) {
+ for (int i = 0; i < arr.length; i++) {
+ final TokenizedPath path = new TokenizedPath(arr[i]);
+ if (!couldHoldIncluded(path) || contentsExcluded(path)) {
+ scandir(new File(basedir, arr[i]), path, false);
+ }
+ }
+ }
+
+ /**
+ * Scan the given directory for files and directories. Found files and
+ * directories are placed in their respective collections, based on the
+ * matching of includes, excludes, and the selectors. When a directory
+ * is found, it is scanned recursively.
+ *
+ * @param dir The directory to scan. Must not be <code>null</code>.
+ * @param vpath The path relative to the base directory (needed to
+ * prevent problems with an absolute path when using
+ * dir). Must not be <code>null</code>.
+ * @param fast Whether or not this call is part of a fast scan.
+ *
+ * @see #filesIncluded
+ * @see #filesNotIncluded
+ * @see #filesExcluded
+ * @see #dirsIncluded
+ * @see #dirsNotIncluded
+ * @see #dirsExcluded
+ * @see #slowScan
+ */
+ protected void scandir(final File dir, final String vpath, final boolean fast) {
+ scandir(dir, new TokenizedPath(vpath), fast);
+ }
+
+ /**
+ * Scan the given directory for files and directories. Found files and
+ * directories are placed in their respective collections, based on the
+ * matching of includes, excludes, and the selectors. When a directory
+ * is found, it is scanned recursively.
+ *
+ * @param dir The directory to scan. Must not be <code>null</code>.
+ * @param path The path relative to the base directory (needed to
+ * prevent problems with an absolute path when using
+ * dir). Must not be <code>null</code>.
+ * @param fast Whether or not this call is part of a fast scan.
+ *
+ * @see #filesIncluded
+ * @see #filesNotIncluded
+ * @see #filesExcluded
+ * @see #dirsIncluded
+ * @see #dirsNotIncluded
+ * @see #dirsExcluded
+ * @see #slowScan
+ */
+ private void scandir(final File dir, final TokenizedPath path, final boolean fast) {
+ if (dir == null) {
+ throw new BuildException("dir must not be null.");
+ }
+ final String[] newfiles = dir.list();
+ if (newfiles == null) {
+ if (!dir.exists()) {
+ throw new BuildException(dir + DOES_NOT_EXIST_POSTFIX);
+ } else if (!dir.isDirectory()) {
+ throw new BuildException(dir + " is not a directory.");
+ } else {
+ throw new BuildException("IO error scanning directory '"
+ + dir.getAbsolutePath() + "'");
+ }
+ }
+ scandir(dir, path, fast, newfiles, new LinkedList<String>());
+ }
+
+ private void scandir(final File dir, final TokenizedPath path, final boolean fast,
+ String[] newfiles, final LinkedList<String> directoryNamesFollowed) {
+ String vpath = path.toString();
+ if (vpath.length() > 0 && !vpath.endsWith(File.separator)) {
+ vpath += File.separator;
+ }
+
+ // avoid double scanning of directories, can only happen in fast mode
+ if (fast && hasBeenScanned(vpath)) {
+ return;
+ }
+ if (!followSymlinks) {
+ final ArrayList<String> noLinks = new ArrayList<String>();
+ for (int i = 0; i < newfiles.length; i++) {
+ try {
+ if (SYMLINK_UTILS.isSymbolicLink(dir, newfiles[i])) {
+ final String name = vpath + newfiles[i];
+ final File file = new File(dir, newfiles[i]);
+ if (file.isDirectory()) {
+ dirsExcluded.addElement(name);
+ } else if (file.isFile()) {
+ filesExcluded.addElement(name);
+ }
+ accountForNotFollowedSymlink(name, file);
+ } else {
+ noLinks.add(newfiles[i]);
+ }
+ } catch (final IOException ioe) {
+ final String msg = "IOException caught while checking "
+ + "for links, couldn't get canonical path!";
+ // will be caught and redirected to Ant's logging system
+ System.err.println(msg);
+ noLinks.add(newfiles[i]);
+ }
+ }
+ newfiles = (noLinks.toArray(new String[noLinks.size()]));
+ } else {
+ directoryNamesFollowed.addFirst(dir.getName());
+ }
+
+ for (int i = 0; i < newfiles.length; i++) {
+ final String name = vpath + newfiles[i];
+ final TokenizedPath newPath = new TokenizedPath(path, newfiles[i]);
+ final File file = new File(dir, newfiles[i]);
+ final String[] children = file.list();
+ if (children == null || (children.length == 0 && file.isFile())) {
+ if (isIncluded(newPath)) {
+ accountForIncludedFile(newPath, file);
+ } else {
+ everythingIncluded = false;
+ filesNotIncluded.addElement(name);
+ }
+ } else if (file.isDirectory()) { // dir
+
+ if (followSymlinks
+ && causesIllegalSymlinkLoop(newfiles[i], dir,
+ directoryNamesFollowed)) {
+ // will be caught and redirected to Ant's logging system
+ System.err.println("skipping symbolic link "
+ + file.getAbsolutePath()
+ + " -- too many levels of symbolic"
+ + " links.");
+ notFollowedSymlinks.add(file.getAbsolutePath());
+ continue;
+ }
+
+ if (isIncluded(newPath)) {
+ accountForIncludedDir(newPath, file, fast, children,
+ directoryNamesFollowed);
+ } else {
+ everythingIncluded = false;
+ dirsNotIncluded.addElement(name);
+ if (fast && couldHoldIncluded(newPath)
+ && !contentsExcluded(newPath)) {
+ scandir(file, newPath, fast, children,
+ directoryNamesFollowed);
+ }
+ }
+ if (!fast) {
+ scandir(file, newPath, fast, children, directoryNamesFollowed);
+ }
+ }
+ }
+
+ if (followSymlinks) {
+ directoryNamesFollowed.removeFirst();
+ }
+ }
+
+ /**
+ * Process included file.
+ * @param name path of the file relative to the directory of the FileSet.
+ * @param file included File.
+ */
+ private void accountForIncludedFile(final TokenizedPath name, final File file) {
+ processIncluded(name, file, filesIncluded, filesExcluded,
+ filesDeselected);
+ }
+
+ /**
+ * Process included directory.
+ * @param name path of the directory relative to the directory of
+ * the FileSet.
+ * @param file directory as File.
+ * @param fast whether to perform fast scans.
+ */
+ private void accountForIncludedDir(final TokenizedPath name, final File file,
+ final boolean fast) {
+ processIncluded(name, file, dirsIncluded, dirsExcluded, dirsDeselected);
+ if (fast && couldHoldIncluded(name) && !contentsExcluded(name)) {
+ scandir(file, name, fast);
+ }
+ }
+
+ private void accountForIncludedDir(final TokenizedPath name,
+ final File file, final boolean fast,
+ final String[] children,
+ final LinkedList<String> directoryNamesFollowed) {
+ processIncluded(name, file, dirsIncluded, dirsExcluded, dirsDeselected);
+ if (fast && couldHoldIncluded(name) && !contentsExcluded(name)) {
+ scandir(file, name, fast, children, directoryNamesFollowed);
+ }
+ }
+
+ private void accountForNotFollowedSymlink(final String name, final File file) {
+ accountForNotFollowedSymlink(new TokenizedPath(name), file);
+ }
+
+ private void accountForNotFollowedSymlink(final TokenizedPath name, final File file) {
+ if (!isExcluded(name) &&
+ (isIncluded(name)
+ || (file.isDirectory() && couldHoldIncluded(name)
+ && !contentsExcluded(name)))) {
+ notFollowedSymlinks.add(file.getAbsolutePath());
+ }
+ }
+
+ private void processIncluded(final TokenizedPath path,
+ final File file, final Vector<String> inc, final Vector<String> exc,
+ final Vector<String> des) {
+ final String name = path.toString();
+ if (inc.contains(name) || exc.contains(name) || des.contains(name)) {
+ return;
+ }
+
+ boolean included = false;
+ if (isExcluded(path)) {
+ exc.add(name);
+ } else if (isSelected(name, file)) {
+ included = true;
+ inc.add(name);
+ } else {
+ des.add(name);
+ }
+ everythingIncluded &= included;
+ }
+
+ /**
+ * Test whether or not a name matches against at least one include
+ * pattern.
+ *
+ * @param name The name to match. Must not be <code>null</code>.
+ * @return <code>true</code> when the name matches against at least one
+ * include pattern, or <code>false</code> otherwise.
+ */
+ protected boolean isIncluded(final String name) {
+ return isIncluded(new TokenizedPath(name));
+ }
+
+ /**
+ * Test whether or not a name matches against at least one include
+ * pattern.
+ *
+ * @param name The name to match. Must not be <code>null</code>.
+ * @return <code>true</code> when the name matches against at least one
+ * include pattern, or <code>false</code> otherwise.
+ */
+ private boolean isIncluded(final TokenizedPath path) {
+ ensureNonPatternSetsReady();
+
+ if (isCaseSensitive()
+ ? includeNonPatterns.containsKey(path.toString())
+ : includeNonPatterns.containsKey(path.toString().toUpperCase())) {
+ return true;
+ }
+ for (int i = 0; i < includePatterns.length; i++) {
+ if (includePatterns[i].matchPath(path, isCaseSensitive())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Test whether or not a name matches the start of at least one include
+ * pattern.
+ *
+ * @param name The name to match. Must not be <code>null</code>.
+ * @return <code>true</code> when the name matches against the start of at
+ * least one include pattern, or <code>false</code> otherwise.
+ */
+ protected boolean couldHoldIncluded(final String name) {
+ return couldHoldIncluded(new TokenizedPath(name));
+ }
+
+ /**
+ * Test whether or not a name matches the start of at least one include
+ * pattern.
+ *
+ * @param tokenizedName The name to match. Must not be <code>null</code>.
+ * @return <code>true</code> when the name matches against the start of at
+ * least one include pattern, or <code>false</code> otherwise.
+ */
+ private boolean couldHoldIncluded(final TokenizedPath tokenizedName) {
+ for (int i = 0; i < includePatterns.length; i++) {
+ if (couldHoldIncluded(tokenizedName, includePatterns[i])) {
+ return true;
+ }
+ }
+ for (final Iterator<TokenizedPath> iter = includeNonPatterns.values().iterator();
+ iter.hasNext();) {
+ if (couldHoldIncluded(tokenizedName,
+ iter.next().toPattern())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Test whether or not a name matches the start of the given
+ * include pattern.
+ *
+ * @param tokenizedName The name to match. Must not be <code>null</code>.
+ * @return <code>true</code> when the name matches against the start of the
+ * include pattern, or <code>false</code> otherwise.
+ */
+ private boolean couldHoldIncluded(final TokenizedPath tokenizedName,
+ final TokenizedPattern tokenizedInclude) {
+ return tokenizedInclude.matchStartOf(tokenizedName, isCaseSensitive())
+ && isMorePowerfulThanExcludes(tokenizedName.toString())
+ && isDeeper(tokenizedInclude, tokenizedName);
+ }
+
+ /**
+ * Verify that a pattern specifies files deeper
+ * than the level of the specified file.
+ * @param pattern the pattern to check.
+ * @param name the name to check.
+ * @return whether the pattern is deeper than the name.
+ * @since Ant 1.6.3
+ */
+ private boolean isDeeper(final TokenizedPattern pattern, final TokenizedPath name) {
+ return pattern.containsPattern(SelectorUtils.DEEP_TREE_MATCH)
+ || pattern.depth() > name.depth();
+ }
+
+ /**
+ * Find out whether one particular include pattern is more powerful
+ * than all the excludes.
+ * Note: the power comparison is based on the length of the include pattern
+ * and of the exclude patterns without the wildcards.
+ * Ideally the comparison should be done based on the depth
+ * of the match; that is to say how many file separators have been matched
+ * before the first ** or the end of the pattern.
+ *
+ * IMPORTANT : this function should return false "with care".
+ *
+ * @param name the relative path to test.
+ * @return true if there is no exclude pattern more powerful than
+ * this include pattern.
+ * @since Ant 1.6
+ */
+ private boolean isMorePowerfulThanExcludes(final String name) {
+ final String soughtexclude =
+ name + File.separatorChar + SelectorUtils.DEEP_TREE_MATCH;
+ for (int counter = 0; counter < excludePatterns.length; counter++) {
+ if (excludePatterns[counter].toString().equals(soughtexclude)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Test whether all contents of the specified directory must be excluded.
+ * @param path the path to check.
+ * @return whether all the specified directory's contents are excluded.
+ */
+ /* package */ boolean contentsExcluded(final TokenizedPath path) {
+ for (int i = 0; i < excludePatterns.length; i++) {
+ if (excludePatterns[i].endsWith(SelectorUtils.DEEP_TREE_MATCH)
+ && excludePatterns[i].withoutLastToken()
+ .matchPath(path, isCaseSensitive())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Test whether or not a name matches against at least one exclude
+ * pattern.
+ *
+ * @param name The name to match. Must not be <code>null</code>.
+ * @return <code>true</code> when the name matches against at least one
+ * exclude pattern, or <code>false</code> otherwise.
+ */
+ protected boolean isExcluded(final String name) {
+ return isExcluded(new TokenizedPath(name));
+ }
+
+ /**
+ * Test whether or not a name matches against at least one exclude
+ * pattern.
+ *
+ * @param name The name to match. Must not be <code>null</code>.
+ * @return <code>true</code> when the name matches against at least one
+ * exclude pattern, or <code>false</code> otherwise.
+ */
+ private boolean isExcluded(final TokenizedPath name) {
+ ensureNonPatternSetsReady();
+
+ if (isCaseSensitive()
+ ? excludeNonPatterns.containsKey(name.toString())
+ : excludeNonPatterns.containsKey(name.toString().toUpperCase())) {
+ return true;
+ }
+ for (int i = 0; i < excludePatterns.length; i++) {
+ if (excludePatterns[i].matchPath(name, isCaseSensitive())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Test whether a file should be selected.
+ *
+ * @param name the filename to check for selecting.
+ * @param file the java.io.File object for this filename.
+ * @return <code>false</code> when the selectors says that the file
+ * should not be selected, <code>true</code> otherwise.
+ */
+ protected boolean isSelected(final String name, final File file) {
+ if (selectors != null) {
+ for (int i = 0; i < selectors.length; i++) {
+ if (!selectors[i].isSelected(basedir, name, file)) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Return the names of the files which matched at least one of the
+ * include patterns and none of the exclude patterns.
+ * The names are relative to the base directory.
+ *
+ * @return the names of the files which matched at least one of the
+ * include patterns and none of the exclude patterns.
+ */
+ public String[] getIncludedFiles() {
+ String[] files;
+ synchronized (this) {
+ if (filesIncluded == null) {
+ throw new IllegalStateException("Must call scan() first");
+ }
+ files = new String[filesIncluded.size()];
+ filesIncluded.copyInto(files);
+ }
+ Arrays.sort(files);
+ return files;
+ }
+
+ /**
+ * Return the count of included files.
+ * @return <code>int</code>.
+ * @since Ant 1.6.3
+ */
+ public synchronized int getIncludedFilesCount() {
+ if (filesIncluded == null) {
+ throw new IllegalStateException("Must call scan() first");
+ }
+ return filesIncluded.size();
+ }
+
+ /**
+ * Return the names of the files which matched none of the include
+ * patterns. The names are relative to the base directory. This involves
+ * performing a slow scan if one has not already been completed.
+ *
+ * @return the names of the files which matched none of the include
+ * patterns.
+ *
+ * @see #slowScan
+ */
+ public synchronized String[] getNotIncludedFiles() {
+ slowScan();
+ final String[] files = new String[filesNotIncluded.size()];
+ filesNotIncluded.copyInto(files);
+ return files;
+ }
+
+ /**
+ * Return the names of the files which matched at least one of the
+ * include patterns and at least one of the exclude patterns.
+ * The names are relative to the base directory. This involves
+ * performing a slow scan if one has not already been completed.
+ *
+ * @return the names of the files which matched at least one of the
+ * include patterns and at least one of the exclude patterns.
+ *
+ * @see #slowScan
+ */
+ public synchronized String[] getExcludedFiles() {
+ slowScan();
+ final String[] files = new String[filesExcluded.size()];
+ filesExcluded.copyInto(files);
+ return files;
+ }
+
+ /**
+ * <p>Return the names of the files which were selected out and
+ * therefore not ultimately included.</p>
+ *
+ * <p>The names are relative to the base directory. This involves
+ * performing a slow scan if one has not already been completed.</p>
+ *
+ * @return the names of the files which were deselected.
+ *
+ * @see #slowScan
+ */
+ public synchronized String[] getDeselectedFiles() {
+ slowScan();
+ final String[] files = new String[filesDeselected.size()];
+ filesDeselected.copyInto(files);
+ return files;
+ }
+
+ /**
+ * Return the names of the directories which matched at least one of the
+ * include patterns and none of the exclude patterns.
+ * The names are relative to the base directory.
+ *
+ * @return the names of the directories which matched at least one of the
+ * include patterns and none of the exclude patterns.
+ */
+ public String[] getIncludedDirectories() {
+ String[] directories;
+ synchronized (this) {
+ if (dirsIncluded == null) {
+ throw new IllegalStateException("Must call scan() first");
+ }
+ directories = new String[dirsIncluded.size()];
+ dirsIncluded.copyInto(directories);
+ }
+ Arrays.sort(directories);
+ return directories;
+ }
+
+ /**
+ * Return the count of included directories.
+ * @return <code>int</code>.
+ * @since Ant 1.6.3
+ */
+ public synchronized int getIncludedDirsCount() {
+ if (dirsIncluded == null) {
+ throw new IllegalStateException("Must call scan() first");
+ }
+ return dirsIncluded.size();
+ }
+
+ /**
+ * Return the names of the directories which matched none of the include
+ * patterns. The names are relative to the base directory. This involves
+ * performing a slow scan if one has not already been completed.
+ *
+ * @return the names of the directories which matched none of the include
+ * patterns.
+ *
+ * @see #slowScan
+ */
+ public synchronized String[] getNotIncludedDirectories() {
+ slowScan();
+ final String[] directories = new String[dirsNotIncluded.size()];
+ dirsNotIncluded.copyInto(directories);
+ return directories;
+ }
+
+ /**
+ * Return the names of the directories which matched at least one of the
+ * include patterns and at least one of the exclude patterns.
+ * The names are relative to the base directory. This involves
+ * performing a slow scan if one has not already been completed.
+ *
+ * @return the names of the directories which matched at least one of the
+ * include patterns and at least one of the exclude patterns.
+ *
+ * @see #slowScan
+ */
+ public synchronized String[] getExcludedDirectories() {
+ slowScan();
+ final String[] directories = new String[dirsExcluded.size()];
+ dirsExcluded.copyInto(directories);
+ return directories;
+ }
+
+ /**
+ * <p>Return the names of the directories which were selected out and
+ * therefore not ultimately included.</p>
+ *
+ * <p>The names are relative to the base directory. This involves
+ * performing a slow scan if one has not already been completed.</p>
+ *
+ * @return the names of the directories which were deselected.
+ *
+ * @see #slowScan
+ */
+ public synchronized String[] getDeselectedDirectories() {
+ slowScan();
+ final String[] directories = new String[dirsDeselected.size()];
+ dirsDeselected.copyInto(directories);
+ return directories;
+ }
+
+ /**
+ * Absolute paths of all symbolic links that haven't been followed
+ * but would have been followed had followsymlinks been true or
+ * maxLevelsOfSymlinks been bigger.
+ *
+ * @return sorted array of not followed symlinks
+ * @since Ant 1.8.0
+ * @see #notFollowedSymlinks
+ */
+ public synchronized String[] getNotFollowedSymlinks() {
+ String[] links;
+ synchronized (this) {
+ links = notFollowedSymlinks
+ .toArray(new String[notFollowedSymlinks.size()]);
+ }
+ Arrays.sort(links);
+ return links;
+ }
+
+ /**
+ * Add default exclusions to the current exclusions set.
+ */
+ public synchronized void addDefaultExcludes() {
+ final int excludesLength = excludes == null ? 0 : excludes.length;
+ String[] newExcludes;
+ final String[] defaultExcludesTemp = getDefaultExcludes();
+ newExcludes = new String[excludesLength + defaultExcludesTemp.length];
+ if (excludesLength > 0) {
+ System.arraycopy(excludes, 0, newExcludes, 0, excludesLength);
+ }
+ for (int i = 0; i < defaultExcludesTemp.length; i++) {
+ newExcludes[i + excludesLength] =
+ defaultExcludesTemp[i].replace('/', File.separatorChar)
+ .replace('\\', File.separatorChar);
+ }
+ excludes = newExcludes;
+ }
+
+ /**
+ * Get the named resource.
+ * @param name path name of the file relative to the dir attribute.
+ *
+ * @return the resource with the given name.
+ * @since Ant 1.5.2
+ */
+ public synchronized Resource getResource(final String name) {
+ return new FileResource(basedir, name);
+ }
+
+ /**
+ * Has the directory with the given path relative to the base
+ * directory already been scanned?
+ *
+ * <p>Registers the given directory as scanned as a side effect.</p>
+ *
+ * @since Ant 1.6
+ */
+ private boolean hasBeenScanned(final String vpath) {
+ return !scannedDirs.add(vpath);
+ }
+
+ /**
+ * This method is of interest for testing purposes. The returned
+ * Set is live and should not be modified.
+ * @return the Set of relative directory names that have been scanned.
+ */
+ /* package-private */ Set<String> getScannedDirs() {
+ return scannedDirs;
+ }
+
+ /**
+ * Clear internal caches.
+ *
+ * @since Ant 1.6
+ */
+ private synchronized void clearCaches() {
+ includeNonPatterns.clear();
+ excludeNonPatterns.clear();
+ includePatterns = null;
+ excludePatterns = null;
+ areNonPatternSetsReady = false;
+ }
+
+ /**
+ * Ensure that the in|exclude &quot;patterns&quot;
+ * have been properly divided up.
+ *
+ * @since Ant 1.6.3
+ */
+ /* package */ synchronized void ensureNonPatternSetsReady() {
+ if (!areNonPatternSetsReady) {
+ includePatterns = fillNonPatternSet(includeNonPatterns, includes);
+ excludePatterns = fillNonPatternSet(excludeNonPatterns, excludes);
+ areNonPatternSetsReady = true;
+ }
+ }
+
+ /**
+ * Add all patterns that are not real patterns (do not contain
+ * wildcards) to the set and returns the real patterns.
+ *
+ * @param map Map to populate.
+ * @param patterns String[] of patterns.
+ * @since Ant 1.8.0
+ */
+ private TokenizedPattern[] fillNonPatternSet(final Map<String, TokenizedPath> map, final String[] patterns) {
+ final ArrayList<TokenizedPattern> al = new ArrayList<TokenizedPattern>(patterns.length);
+ for (int i = 0; i < patterns.length; i++) {
+ if (!SelectorUtils.hasWildcards(patterns[i])) {
+ final String s = isCaseSensitive()
+ ? patterns[i] : patterns[i].toUpperCase();
+ map.put(s, new TokenizedPath(s));
+ } else {
+ al.add(new TokenizedPattern(patterns[i]));
+ }
+ }
+ return al.toArray(new TokenizedPattern[al.size()]);
+ }
+
+ /**
+ * Would following the given directory cause a loop of symbolic
+ * links deeper than allowed?
+ *
+ * <p>Can only happen if the given directory has been seen at
+ * least more often than allowed during the current scan and it is
+ * a symbolic link and enough other occurrences of the same name
+ * higher up are symbolic links that point to the same place.</p>
+ *
+ * @since Ant 1.8.0
+ */
+ private boolean causesIllegalSymlinkLoop(final String dirName, final File parent,
+ final LinkedList<String> directoryNamesFollowed) {
+ try {
+ if (directoryNamesFollowed.size() >= maxLevelsOfSymlinks
+ && CollectionUtils.frequency(directoryNamesFollowed, dirName)
+ >= maxLevelsOfSymlinks
+ && SYMLINK_UTILS.isSymbolicLink(parent, dirName)) {
+
+ final ArrayList<String> files = new ArrayList<String>();
+ File f = FILE_UTILS.resolveFile(parent, dirName);
+ final String target = f.getCanonicalPath();
+ files.add(target);
+
+ String relPath = "";
+ for (final String dir : directoryNamesFollowed) {
+ relPath += "../";
+ if (dirName.equals(dir)) {
+ f = FILE_UTILS.resolveFile(parent, relPath + dir);
+ files.add(f.getCanonicalPath());
+ if (files.size() > maxLevelsOfSymlinks
+ && CollectionUtils.frequency(files, target)
+ > maxLevelsOfSymlinks) {
+ return true;
+ }
+ }
+ }
+
+ }
+ return false;
+ } catch (final IOException ex) {
+ throw new BuildException("Caught error while checking for"
+ + " symbolic links", ex);
+ }
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/DynamicAttribute.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/DynamicAttribute.java
new file mode 100644
index 00000000..445c33ee
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/DynamicAttribute.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant;
+
+/**
+ * Enables a task to control unknown attributes
+ *
+ * @since Ant 1.5
+ */
+public interface DynamicAttribute {
+
+ /**
+ * Set a named attribute to the given value
+ *
+ * @param name the name of the attribute
+ * @param value the new value of the attribute
+ * @throws BuildException when any error occurs
+ */
+ void setDynamicAttribute(String name, String value)
+ throws BuildException;
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/DynamicAttributeNS.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/DynamicAttributeNS.java
new file mode 100644
index 00000000..7d6e84e5
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/DynamicAttributeNS.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant;
+
+/**
+ * Enables a task to control unknown attributes.
+ *
+ * @since Ant 1.7
+ */
+public interface DynamicAttributeNS {
+
+ /**
+ * Set a named attribute to the given value
+ *
+ * @param uri The namespace uri for this attribute, "" is
+ * used if there is no namespace uri.
+ * @param localName The localname of this attribute.
+ * @param qName The qualified name for this attribute
+ * @param value The value of this attribute.
+ * @throws BuildException when any error occurs
+ */
+ void setDynamicAttribute(
+ String uri, String localName, String qName, String value)
+ throws BuildException;
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/DynamicConfigurator.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/DynamicConfigurator.java
new file mode 100644
index 00000000..e48062be
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/DynamicConfigurator.java
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant;
+
+/**
+ * Enables a task to control unknown attributes and elements.
+ *
+ * @since Ant 1.5
+ */
+public interface DynamicConfigurator
+ extends DynamicAttribute, DynamicElement {
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/DynamicConfiguratorNS.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/DynamicConfiguratorNS.java
new file mode 100644
index 00000000..40b3d656
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/DynamicConfiguratorNS.java
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant;
+
+/**
+ * Enables a task to control unknown attributes and elements.
+ *
+ * @since Ant 1.7
+ */
+public interface DynamicConfiguratorNS
+ extends DynamicAttributeNS, DynamicElementNS {
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/DynamicElement.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/DynamicElement.java
new file mode 100644
index 00000000..b9caf0c4
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/DynamicElement.java
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant;
+
+/**
+ * Enables a task to control unknown elements.
+ *
+ * @since Ant 1.5
+ */
+public interface DynamicElement {
+
+ /**
+ * Create an element with the given name
+ *
+ * @param name the element name
+ * @throws BuildException when any error occurs
+ * @return the element created
+ */
+ Object createDynamicElement(String name) throws BuildException;
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/DynamicElementNS.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/DynamicElementNS.java
new file mode 100644
index 00000000..57bfa530
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/DynamicElementNS.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant;
+
+/**
+ * Enables a task to control unknown elements.
+ *
+ * @since Ant 1.7
+ */
+public interface DynamicElementNS {
+ /**
+ * Create an element with the given name
+ *
+ * @param uri The namespace uri for this attribute.
+ * @param localName The localname of this attribute.
+ * @param qName The qualified name for this element.
+ * @throws BuildException when any error occurs
+ * @return the element created for this element.
+ */
+ Object createDynamicElement(
+ String uri, String localName, String qName) throws BuildException;
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/DynamicObjectAttribute.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/DynamicObjectAttribute.java
new file mode 100644
index 00000000..9a9aca90
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/DynamicObjectAttribute.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant;
+
+/**
+ * Enables a task to control unknown attributes.
+ * Same as {@link DynamicAttribute} but authorize arbitrary Object as value
+ * rather than String
+ *
+ * @see DynamicAttribute
+ * @since Ant 1.9
+ */
+public interface DynamicObjectAttribute {
+
+ /**
+ * Set a named attribute to the given value
+ *
+ * @param name the name of the attribute
+ * @param value the new value of the attribute
+ * @throws BuildException when any error occurs
+ */
+ void setDynamicAttribute(String name, Object value)
+ throws BuildException;
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/Evaluable.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/Evaluable.java
new file mode 100644
index 00000000..47f09c73
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/Evaluable.java
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant;
+
+/**
+ * Kind of task attribute that can be evaluated before being assigned
+ *
+ * @see RuntimeConfigurable
+ */
+public interface Evaluable {
+
+ Object eval();
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/Executor.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/Executor.java
new file mode 100644
index 00000000..9aff1487
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/Executor.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant;
+
+/**
+ * Target executor abstraction.
+ * @since Ant 1.6.3
+ */
+public interface Executor {
+
+ /**
+ * Execute the specified Targets for the specified Project.
+ * @param project the Ant Project.
+ * @param targetNames String[] of Target names as specified on the command line.
+ * @throws BuildException on error
+ */
+ void executeTargets(Project project, String[] targetNames)
+ throws BuildException;
+
+ /**
+ * Get the appropriate subproject Executor instance.
+ *
+ * This allows the top executor to control what type of executor is used to execute
+ * subprojects via &lt;ant&gt;/&lt;antcall&gt;/&lt;subant&gt; and task that extend these.
+ * All bundled Executors return a SingleCheckExecutor (running a merged set of
+ * depended targets for all targets called) to run sub-builds.
+ *
+ * @return an Executor instance.
+ */
+ Executor getSubProjectExecutor();
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/ExitException.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/ExitException.java
new file mode 100644
index 00000000..11e1bc81
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/ExitException.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant;
+
+/**
+ * Used to report exit status of classes which call System.exit().
+ *
+ * @see org.apache.tools.ant.util.optional.NoExitSecurityManager
+ * @see org.apache.tools.ant.types.Permissions
+ *
+ */
+public class ExitException extends SecurityException {
+
+ private static final long serialVersionUID = 2772487854280543363L;
+
+ /** Status code */
+ private int status;
+
+ /**
+ * Constructs an exit exception.
+ * @param status the status code returned via System.exit()
+ */
+ public ExitException(int status) {
+ super("ExitException: status " + status);
+ this.status = status;
+ }
+
+ /**
+ * Constructs an exit exception.
+ * @param msg the message to be displayed.
+ * @param status the status code returned via System.exit()
+ */
+ public ExitException(String msg, int status) {
+ super(msg);
+ this.status = status;
+ }
+
+ /**
+ * The status code returned by System.exit()
+ *
+ * @return the status code returned by System.exit()
+ */
+ public int getStatus() {
+ return status;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/ExitStatusException.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/ExitStatusException.java
new file mode 100644
index 00000000..1eb5127b
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/ExitStatusException.java
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant;
+
+/**
+ * BuildException + exit status.
+ *
+ * @since Ant 1.7
+ */
+public class ExitStatusException extends BuildException {
+
+ private static final long serialVersionUID = 7760846806886585968L;
+
+ /** Status code */
+ private int status;
+
+ /**
+ * Constructs an <code>ExitStatusException</code>.
+ * @param status the associated status code
+ */
+ public ExitStatusException(int status) {
+ super();
+ this.status = status;
+ }
+
+ /**
+ * Constructs an <code>ExitStatusException</code>.
+ * @param msg the associated message
+ * @param status the associated status code
+ */
+ public ExitStatusException(String msg, int status) {
+ super(msg);
+ this.status = status;
+ }
+
+ /**
+ * Construct an exit status exception with location information too
+ * @param message error message
+ * @param status exit status
+ * @param location exit location
+ */
+ public ExitStatusException(String message, int status, Location location) {
+ super(message, location);
+ this.status = status;
+ }
+
+ /**
+ * Get the status code.
+ * @return <code>int</code>
+ */
+ public int getStatus() {
+ return status;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/ExtensionPoint.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/ExtensionPoint.java
new file mode 100644
index 00000000..32c8c55e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/ExtensionPoint.java
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant;
+
+/**
+ * An extension point build files can provide as a place where other
+ * build files can add new dependencies.
+ *
+ * @since Ant 1.8.0
+ */
+public class ExtensionPoint extends Target {
+
+ public ExtensionPoint() {
+ }
+
+ /**
+ * Cloning constructor.
+ * @param other the Target to clone.
+ */
+ public ExtensionPoint(Target other) {
+ //Should we have a clone constructor taking an ExtensionPoint as parameter?
+ super(other);
+ }
+
+
+ private static final String NO_CHILDREN_ALLOWED
+ = "you must not nest child elements into an extension-point";
+
+ /**
+ * Throws an exception.
+ */
+ @Override
+ public final void addTask(Task task) {
+ throw new BuildException(NO_CHILDREN_ALLOWED);
+ }
+
+ /**
+ * Throws an exception.
+ */
+ @Override
+ public final void addDataType(RuntimeConfigurable r) {
+ throw new BuildException(NO_CHILDREN_ALLOWED);
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/FileScanner.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/FileScanner.java
new file mode 100644
index 00000000..a7cb9dea
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/FileScanner.java
@@ -0,0 +1,158 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant;
+
+import java.io.File;
+
+/**
+ * An interface used to describe the actions required of any type of
+ * directory scanner.
+ *
+ */
+public interface FileScanner {
+ /**
+ * Adds default exclusions to the current exclusions set.
+ */
+ void addDefaultExcludes();
+
+ /**
+ * Returns the base directory to be scanned.
+ * This is the directory which is scanned recursively.
+ *
+ * @return the base directory to be scanned
+ */
+ File getBasedir();
+
+ /**
+ * Returns the names of the directories which matched at least one of the
+ * include patterns and at least one of the exclude patterns.
+ * The names are relative to the base directory.
+ *
+ * @return the names of the directories which matched at least one of the
+ * include patterns and at least one of the exclude patterns.
+ */
+ String[] getExcludedDirectories();
+
+ /**
+ * Returns the names of the files which matched at least one of the
+ * include patterns and at least one of the exclude patterns.
+ * The names are relative to the base directory.
+ *
+ * @return the names of the files which matched at least one of the
+ * include patterns and at least one of the exclude patterns.
+ *
+ */
+ String[] getExcludedFiles();
+
+ /**
+ * Returns the names of the directories which matched at least one of the
+ * include patterns and none of the exclude patterns.
+ * The names are relative to the base directory.
+ *
+ * @return the names of the directories which matched at least one of the
+ * include patterns and none of the exclude patterns.
+ */
+ String[] getIncludedDirectories();
+
+ /**
+ * Returns the names of the files which matched at least one of the
+ * include patterns and none of the exclude patterns.
+ * The names are relative to the base directory.
+ *
+ * @return the names of the files which matched at least one of the
+ * include patterns and none of the exclude patterns.
+ */
+ String[] getIncludedFiles();
+
+ /**
+ * Returns the names of the directories which matched none of the include
+ * patterns. The names are relative to the base directory.
+ *
+ * @return the names of the directories which matched none of the include
+ * patterns.
+ */
+ String[] getNotIncludedDirectories();
+
+ /**
+ * Returns the names of the files which matched none of the include
+ * patterns. The names are relative to the base directory.
+ *
+ * @return the names of the files which matched none of the include
+ * patterns.
+ */
+ String[] getNotIncludedFiles();
+
+ /**
+ * Scans the base directory for files which match at least one include
+ * pattern and don't match any exclude patterns.
+ *
+ * @exception IllegalStateException if the base directory was set
+ * incorrectly (i.e. if it is <code>null</code>, doesn't exist,
+ * or isn't a directory).
+ */
+ void scan() throws IllegalStateException;
+
+ /**
+ * Sets the base directory to be scanned. This is the directory which is
+ * scanned recursively. All '/' and '\' characters should be replaced by
+ * <code>File.separatorChar</code>, so the separator used need not match
+ * <code>File.separatorChar</code>.
+ *
+ * @param basedir The base directory to scan.
+ * Must not be <code>null</code>.
+ */
+ void setBasedir(String basedir);
+
+ /**
+ * Sets the base directory to be scanned. This is the directory which is
+ * scanned recursively.
+ *
+ * @param basedir The base directory for scanning.
+ * Should not be <code>null</code>.
+ */
+ void setBasedir(File basedir);
+
+ /**
+ * Sets the list of exclude patterns to use.
+ *
+ * @param excludes A list of exclude patterns.
+ * May be <code>null</code>, indicating that no files
+ * should be excluded. If a non-<code>null</code> list is
+ * given, all elements must be non-<code>null</code>.
+ */
+ void setExcludes(String[] excludes);
+
+ /**
+ * Sets the list of include patterns to use.
+ *
+ * @param includes A list of include patterns.
+ * May be <code>null</code>, indicating that all files
+ * should be included. If a non-<code>null</code>
+ * list is given, all elements must be
+ * non-<code>null</code>.
+ */
+ void setIncludes(String[] includes);
+
+ /**
+ * Sets whether or not the file system should be regarded as case sensitive.
+ *
+ * @param isCaseSensitive whether or not the file system should be
+ * regarded as a case sensitive one
+ */
+ void setCaseSensitive(boolean isCaseSensitive);
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/IntrospectionHelper.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/IntrospectionHelper.java
new file mode 100644
index 00000000..30086563
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/IntrospectionHelper.java
@@ -0,0 +1,1745 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+import org.apache.tools.ant.taskdefs.PreSetDef;
+import org.apache.tools.ant.types.EnumeratedAttribute;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.resources.FileProvider;
+import org.apache.tools.ant.types.resources.FileResource;
+import org.apache.tools.ant.util.StringUtils;
+
+/**
+ * Helper class that collects the methods a task or nested element
+ * holds to set attributes, create nested elements or hold PCDATA
+ * elements.
+ *
+ * It contains hashtables containing classes that use introspection
+ * to handle all the invocation of the project-component specific methods.
+ *
+ * This class is somewhat complex, as it implements the O/X mapping between
+ * Ant XML and Java class instances. This is not the best place for someone new
+ * to Ant to start contributing to the codebase, as a change here can break the
+ * entire system in interesting ways. Always run a full test of Ant before checking
+ * in/submitting changes to this file.
+ *
+ * The class is final and has a private constructor.
+ * To get an instance for a specific (class,project) combination,
+ * use {@link #getHelper(Project,Class)}.
+ * This may return an existing version, or a new one
+ * ...do not make any assumptions about its uniqueness, or its validity after the Project
+ * instance has finished its build.
+ *
+ */
+public final class IntrospectionHelper {
+
+ /**
+ * Helper instances we've already created (Class.getName() to IntrospectionHelper).
+ */
+ private static final Map<String, IntrospectionHelper> HELPERS = new Hashtable<String, IntrospectionHelper>();
+
+ /**
+ * Map from primitive types to wrapper classes for use in
+ * createAttributeSetter (Class to Class). Note that char
+ * and boolean are in here even though they get special treatment
+ * - this way we only need to test for the wrapper class.
+ */
+ private static final Map<Class<?>, Class<?>> PRIMITIVE_TYPE_MAP = new HashMap<Class<?>, Class<?>>(8);
+
+ // Set up PRIMITIVE_TYPE_MAP
+ static {
+ final Class<?>[] primitives = {Boolean.TYPE, Byte.TYPE, Character.TYPE, Short.TYPE,
+ Integer.TYPE, Long.TYPE, Float.TYPE, Double.TYPE};
+ final Class<?>[] wrappers = {Boolean.class, Byte.class, Character.class, Short.class,
+ Integer.class, Long.class, Float.class, Double.class};
+ for (int i = 0; i < primitives.length; i++) {
+ PRIMITIVE_TYPE_MAP.put (primitives[i], wrappers[i]);
+ }
+ }
+
+ private static final int MAX_REPORT_NESTED_TEXT = 20;
+ private static final String ELLIPSIS = "...";
+
+ /**
+ * Map from attribute names to attribute types
+ * (String to Class).
+ */
+ private final Hashtable<String, Class<?>> attributeTypes = new Hashtable<String, Class<?>>();
+
+ /**
+ * Map from attribute names to attribute setter methods
+ * (String to AttributeSetter).
+ */
+ private final Hashtable<String, AttributeSetter> attributeSetters = new Hashtable<String, AttributeSetter>();
+
+ /**
+ * Map from attribute names to nested types
+ * (String to Class).
+ */
+ private final Hashtable<String, Class<?>> nestedTypes = new Hashtable<String, Class<?>>();
+
+ /**
+ * Map from attribute names to methods to create nested types
+ * (String to NestedCreator).
+ */
+ private final Hashtable<String, NestedCreator> nestedCreators = new Hashtable<String, NestedCreator>();
+
+ /**
+ * Vector of methods matching add[Configured](Class) pattern.
+ */
+ private final List<Method> addTypeMethods = new ArrayList<Method>();
+
+ /**
+ * The method to invoke to add PCDATA.
+ */
+ private final Method addText;
+
+ /**
+ * The class introspected by this instance.
+ */
+ private final Class<?> bean;
+
+ /**
+ * Sole constructor, which is private to ensure that all
+ * IntrospectionHelpers are created via {@link #getHelper(Class) getHelper}.
+ * Introspects the given class for bean-like methods.
+ * Each method is examined in turn, and the following rules are applied:
+ * <p>
+ * <ul>
+ * <li>If the method is <code>Task.setLocation(Location)</code>,
+ * <code>Task.setTaskType(String)</code>
+ * or <code>TaskContainer.addTask(Task)</code>, it is ignored. These
+ * methods are handled differently elsewhere.
+ * <li><code>void addText(String)</code> is recognised as the method for
+ * adding PCDATA to a bean.
+ * <li><code>void setFoo(Bar)</code> is recognised as a method for
+ * setting the value of attribute <code>foo</code>, so long as
+ * <code>Bar</code> is non-void and is not an array type.
+ * As of Ant 1.8, a Resource or FileProvider parameter overrides a java.io.File parameter;
+ * in practice the only effect of this is to allow objects rendered from
+ * the 1.8 PropertyHelper implementation to be used as Resource parameters,
+ * since Resources set from Strings are resolved as project-relative files
+ * to preserve backward compatibility. Beyond this, non-String
+ * parameter types always overload String parameter types; these are
+ * the only guarantees made in terms of priority.
+ * <li><code>Foo createBar()</code> is recognised as a method for
+ * creating a nested element called <code>bar</code> of type
+ * <code>Foo</code>, so long as <code>Foo</code> is not a primitive or
+ * array type.
+ * <li><code>void addConfiguredFoo(Bar)</code> is recognised as a
+ * method for storing a pre-configured element called
+ * <code>foo</code> and of type <code>Bar</code>, so long as
+ * <code>Bar</code> is not an array, primitive or String type.
+ * <code>Bar</code> must have an accessible constructor taking no
+ * arguments.
+ * <li><code>void addFoo(Bar)</code> is recognised as a method for storing
+ * an element called <code>foo</code> and of type <code>Bar</code>, so
+ * long as <code>Bar</code> is not an array, primitive or String type.
+ * <code>Bar</code> must have an accessible constructor taking no
+ * arguments. This is distinct from the 'addConfigured' idiom in that
+ * the nested element is added to the parent immediately after it is
+ * constructed; in practice this means that <code>addFoo(Bar)</code> should
+ * do little or nothing with its argument besides storing it for later use.
+ * </ul>
+ * Note that only one method is retained to create/set/addConfigured/add
+ * any element or attribute.
+ *
+ * @param bean The bean type to introspect.
+ * Must not be <code>null</code>.
+ *
+ * @see #getHelper(Class)
+ */
+ private IntrospectionHelper(final Class<?> bean) {
+ this.bean = bean;
+ final Method[] methods = bean.getMethods();
+ Method addTextMethod = null;
+ for (int i = 0; i < methods.length; i++) {
+ final Method m = methods[i];
+ final String name = m.getName();
+ final Class<?> returnType = m.getReturnType();
+ final Class<?>[] args = m.getParameterTypes();
+
+ // check of add[Configured](Class) pattern
+ if (args.length == 1 && java.lang.Void.TYPE.equals(returnType)
+ && ("add".equals(name) || "addConfigured".equals(name))) {
+ insertAddTypeMethod(m);
+ continue;
+ }
+ // not really user settable properties on tasks/project components
+ if (org.apache.tools.ant.ProjectComponent.class.isAssignableFrom(bean)
+ && args.length == 1 && isHiddenSetMethod(name, args[0])) {
+ continue;
+ }
+ // hide addTask for TaskContainers
+ if (isContainer() && args.length == 1 && "addTask".equals(name)
+ && org.apache.tools.ant.Task.class.equals(args[0])) {
+ continue;
+ }
+ if ("addText".equals(name) && java.lang.Void.TYPE.equals(returnType)
+ && args.length == 1 && java.lang.String.class.equals(args[0])) {
+ addTextMethod = methods[i];
+ } else if (name.startsWith("set") && java.lang.Void.TYPE.equals(returnType)
+ && args.length == 1 && !args[0].isArray()) {
+ final String propName = getPropertyName(name, "set");
+ AttributeSetter as = attributeSetters.get(propName);
+ if (as != null) {
+ if (java.lang.String.class.equals(args[0])) {
+ /*
+ Ignore method m, as there is an overloaded
+ form of this method that takes in a
+ non-string argument, which gains higher
+ priority.
+ */
+ continue;
+ }
+ if (java.io.File.class.equals(args[0])) {
+ // Ant Resources/FileProviders override java.io.File
+ if (Resource.class.equals(as.type) || FileProvider.class.equals(as.type)) {
+ continue;
+ }
+ }
+ /*
+ In cases other than those just explicitly covered,
+ we just override that with the new one.
+ This mechanism does not guarantee any specific order
+ in which the methods will be selected: so any code
+ that depends on the order in which "set" methods have
+ been defined, is not guaranteed to be selected in any
+ particular order.
+ */
+ }
+ as = createAttributeSetter(m, args[0], propName);
+ if (as != null) {
+ attributeTypes.put(propName, args[0]);
+ attributeSetters.put(propName, as);
+ }
+ } else if (name.startsWith("create") && !returnType.isArray()
+ && !returnType.isPrimitive() && args.length == 0) {
+
+ final String propName = getPropertyName(name, "create");
+ // Check if a create of this property is already present
+ // add takes preference over create for CB purposes
+ if (nestedCreators.get(propName) == null) {
+ nestedTypes.put(propName, returnType);
+ nestedCreators.put(propName, new CreateNestedCreator(m));
+ }
+ } else if (name.startsWith("addConfigured")
+ && java.lang.Void.TYPE.equals(returnType) && args.length == 1
+ && !java.lang.String.class.equals(args[0])
+ && !args[0].isArray() && !args[0].isPrimitive()) {
+ try {
+ Constructor<?> constructor = null;
+ try {
+ constructor = args[0].getConstructor();
+ } catch (final NoSuchMethodException ex) {
+ constructor = args[0].getConstructor(Project.class);
+ }
+ final String propName = getPropertyName(name, "addConfigured");
+ nestedTypes.put(propName, args[0]);
+ nestedCreators.put(propName, new AddNestedCreator(m,
+ constructor, AddNestedCreator.ADD_CONFIGURED));
+ } catch (final NoSuchMethodException nse) {
+ // ignore
+ }
+ } else if (name.startsWith("add")
+ && java.lang.Void.TYPE.equals(returnType) && args.length == 1
+ && !java.lang.String.class.equals(args[0])
+ && !args[0].isArray() && !args[0].isPrimitive()) {
+ try {
+ Constructor<?> constructor = null;
+ try {
+ constructor = args[0].getConstructor();
+ } catch (final NoSuchMethodException ex) {
+ constructor = args[0].getConstructor(Project.class);
+ }
+ final String propName = getPropertyName(name, "add");
+ if (nestedTypes.get(propName) != null) {
+ /*
+ * Ignore this method as there is an addConfigured
+ * form of this method that has a higher
+ * priority
+ */
+ continue;
+ }
+ nestedTypes.put(propName, args[0]);
+ nestedCreators.put(propName, new AddNestedCreator(m,
+ constructor, AddNestedCreator.ADD));
+ } catch (final NoSuchMethodException nse) {
+ // ignore
+ }
+ }
+ }
+ addText = addTextMethod;
+ }
+
+ /**
+ * Certain set methods are part of the Ant core interface to tasks and
+ * therefore not to be considered for introspection
+ *
+ * @param name the name of the set method
+ * @param type the type of the set method's parameter
+ * @return true if the given set method is to be hidden.
+ */
+ private boolean isHiddenSetMethod(final String name, final Class<?> type) {
+ if ("setLocation".equals(name) && org.apache.tools.ant.Location.class.equals(type)) {
+ return true;
+ }
+ if ("setTaskType".equals(name) && java.lang.String.class.equals(type)) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Returns a helper for the given class, either from the cache
+ * or by creating a new instance.
+ *
+ * @param c The class for which a helper is required.
+ * Must not be <code>null</code>.
+ *
+ * @return a helper for the specified class
+ */
+ public static synchronized IntrospectionHelper getHelper(final Class<?> c) {
+ return getHelper(null, c);
+ }
+
+ /**
+ * Returns a helper for the given class, either from the cache
+ * or by creating a new instance.
+ *
+ * The method will make sure the helper will be cleaned up at the end of
+ * the project, and only one instance will be created for each class.
+ *
+ * @param p the project instance. Can be null, in which case the helper is not cached.
+ * @param c The class for which a helper is required.
+ * Must not be <code>null</code>.
+ *
+ * @return a helper for the specified class
+ */
+ public static synchronized IntrospectionHelper getHelper(final Project p, final Class<?> c) {
+ IntrospectionHelper ih = HELPERS.get(c.getName());
+ // If a helper cannot be found, or if the helper is for another
+ // classloader, create a new IH
+ if (ih == null || ih.bean != c) {
+ ih = new IntrospectionHelper(c);
+ if (p != null) {
+ // #30162: do *not* cache this if there is no project, as we
+ // cannot guarantee that the cache will be cleared.
+ HELPERS.put(c.getName(), ih);
+ }
+ }
+ return ih;
+ }
+
+ /**
+ * Sets the named attribute in the given element, which is part of the
+ * given project.
+ *
+ * @param p The project containing the element. This is used when files
+ * need to be resolved. Must not be <code>null</code>.
+ * @param element The element to set the attribute in. Must not be
+ * <code>null</code>.
+ * @param attributeName The name of the attribute to set. Must not be
+ * <code>null</code>.
+ * @param value The value to set the attribute to. This may be interpreted
+ * or converted to the necessary type if the setter method
+ * doesn't accept an object of the supplied type.
+ *
+ * @exception BuildException if the introspected class doesn't support
+ * the given attribute, or if the setting
+ * method fails.
+ */
+ public void setAttribute(final Project p, final Object element, final String attributeName,
+ final Object value) throws BuildException {
+ final AttributeSetter as = attributeSetters.get(
+ attributeName.toLowerCase(Locale.ENGLISH));
+ if (as == null && value != null) {
+ if (element instanceof DynamicAttributeNS) {
+ final DynamicAttributeNS dc = (DynamicAttributeNS) element;
+ final String uriPlusPrefix = ProjectHelper.extractUriFromComponentName(attributeName);
+ final String uri = ProjectHelper.extractUriFromComponentName(uriPlusPrefix);
+ final String localName = ProjectHelper.extractNameFromComponentName(attributeName);
+ final String qName = "".equals(uri) ? localName : uri + ":" + localName;
+ dc.setDynamicAttribute(uri, localName, qName, value.toString());
+ return;
+ }
+ if (element instanceof DynamicObjectAttribute) {
+ final DynamicObjectAttribute dc = (DynamicObjectAttribute) element;
+ dc.setDynamicAttribute(attributeName.toLowerCase(Locale.ENGLISH), value);
+ return;
+ }
+ if (element instanceof DynamicAttribute) {
+ final DynamicAttribute dc = (DynamicAttribute) element;
+ dc.setDynamicAttribute(attributeName.toLowerCase(Locale.ENGLISH), value.toString());
+ return;
+ }
+ if (attributeName.indexOf(':') >= 0) {
+ return; // Ignore attribute from unknown uri's
+ }
+ final String msg = getElementName(p, element)
+ + " doesn't support the \"" + attributeName + "\" attribute.";
+ throw new UnsupportedAttributeException(msg, attributeName);
+ }
+ try {
+ as.setObject(p, element, value);
+ } catch (final IllegalAccessException ie) {
+ // impossible as getMethods should only return public methods
+ throw new BuildException(ie);
+ } catch (final InvocationTargetException ite) {
+ throw extractBuildException(ite);
+ }
+ }
+
+ /**
+ * Sets the named attribute in the given element, which is part of the
+ * given project.
+ *
+ * @param p The project containing the element. This is used when files
+ * need to be resolved. Must not be <code>null</code>.
+ * @param element The element to set the attribute in. Must not be
+ * <code>null</code>.
+ * @param attributeName The name of the attribute to set. Must not be
+ * <code>null</code>.
+ * @param value The value to set the attribute to. This may be interpreted
+ * or converted to the necessary type if the setter method
+ * doesn't just take a string. Must not be <code>null</code>.
+ *
+ * @exception BuildException if the introspected class doesn't support
+ * the given attribute, or if the setting
+ * method fails.
+ */
+ public void setAttribute(final Project p, final Object element, final String attributeName,
+ final String value) throws BuildException {
+ setAttribute(p, element, attributeName, (Object) value);
+ }
+
+ /**
+ * Adds PCDATA to an element, using the element's
+ * <code>void addText(String)</code> method, if it has one. If no
+ * such method is present, a BuildException is thrown if the
+ * given text contains non-whitespace.
+ *
+ * @param project The project which the element is part of.
+ * Must not be <code>null</code>.
+ * @param element The element to add the text to.
+ * Must not be <code>null</code>.
+ * @param text The text to add.
+ * Must not be <code>null</code>.
+ *
+ * @exception BuildException if non-whitespace text is provided and no
+ * method is available to handle it, or if
+ * the handling method fails.
+ */
+ public void addText(final Project project, final Object element, String text)
+ throws BuildException {
+ if (addText == null) {
+ text = text.trim();
+ // Element doesn't handle text content
+ if (text.length() == 0) {
+ // Only whitespace - ignore
+ return;
+ }
+ // Not whitespace - fail
+ throw new BuildException(project.getElementName(element)
+ + " doesn't support nested text data (\"" + condenseText(text) + "\").");
+ }
+ try {
+ addText.invoke(element, new Object[] {text});
+ } catch (final IllegalAccessException ie) {
+ // impossible as getMethods should only return public methods
+ throw new BuildException(ie);
+ } catch (final InvocationTargetException ite) {
+ throw extractBuildException(ite);
+ }
+ }
+
+ /**
+ * part of the error message created by {@link #throwNotSupported
+ * throwNotSupported}.
+ * @since Ant 1.8.0
+ */
+ protected static final String NOT_SUPPORTED_CHILD_PREFIX =
+ " doesn't support the nested \"";
+
+ /**
+ * part of the error message created by {@link #throwNotSupported
+ * throwNotSupported}.
+ * @since Ant 1.8.0
+ */
+ protected static final String NOT_SUPPORTED_CHILD_POSTFIX = "\" element.";
+
+ /**
+ * Utility method to throw a NotSupported exception
+ *
+ * @param project the Project instance.
+ * @param parent the object which doesn't support a requested element
+ * @param elementName the name of the Element which is trying to be created.
+ */
+ public void throwNotSupported(final Project project, final Object parent, final String elementName) {
+ final String msg = project.getElementName(parent)
+ + NOT_SUPPORTED_CHILD_PREFIX + elementName
+ + NOT_SUPPORTED_CHILD_POSTFIX;
+ throw new UnsupportedElementException(msg, elementName);
+ }
+
+ /**
+ * Get the specific NestedCreator for a given project/parent/element combination
+ * @param project ant project
+ * @param parentUri URI of the parent.
+ * @param parent the parent class
+ * @param elementName element to work with. This can contain
+ * a URI,localname tuple of of the form uri:localname
+ * @param child the bit of XML to work with
+ * @return a nested creator that can handle the child elements.
+ * @throws BuildException if the parent does not support child elements of that name
+ */
+ private NestedCreator getNestedCreator(
+ final Project project, String parentUri, final Object parent,
+ final String elementName, final UnknownElement child) throws BuildException {
+
+ String uri = ProjectHelper.extractUriFromComponentName(elementName);
+ final String name = ProjectHelper.extractNameFromComponentName(elementName);
+
+ if (uri.equals(ProjectHelper.ANT_CORE_URI)) {
+ uri = "";
+ }
+ if (parentUri.equals(ProjectHelper.ANT_CORE_URI)) {
+ parentUri = "";
+ }
+ NestedCreator nc = null;
+ if (uri.equals(parentUri) || uri.length() == 0) {
+ nc = nestedCreators.get(name.toLowerCase(Locale.ENGLISH));
+ }
+ if (nc == null) {
+ nc = createAddTypeCreator(project, parent, elementName);
+ }
+ if (nc == null &&
+ (parent instanceof DynamicElementNS
+ || parent instanceof DynamicElement)
+ ) {
+ final String qName = child == null ? name : child.getQName();
+ final Object nestedElement =
+ createDynamicElement(parent,
+ child == null ? "" : child.getNamespace(),
+ name, qName);
+ if (nestedElement != null) {
+ nc = new NestedCreator(null) {
+ @Override
+ Object create(final Project project, final Object parent, final Object ignore) {
+ return nestedElement;
+ }
+ };
+ }
+ }
+ if (nc == null) {
+ throwNotSupported(project, parent, elementName);
+ }
+ return nc;
+ }
+
+ /**
+ * Invokes the "correct" createDynamicElement method on parent in
+ * order to obtain a child element by name.
+ *
+ * @since Ant 1.8.0.
+ */
+ private Object createDynamicElement(final Object parent, final String ns,
+ final String localName, final String qName) {
+ Object nestedElement = null;
+ if (parent instanceof DynamicElementNS) {
+ final DynamicElementNS dc = (DynamicElementNS) parent;
+ nestedElement = dc.createDynamicElement(ns, localName, qName);
+ }
+ if (nestedElement == null && parent instanceof DynamicElement) {
+ final DynamicElement dc = (DynamicElement) parent;
+ nestedElement =
+ dc.createDynamicElement(localName.toLowerCase(Locale.ENGLISH));
+ }
+ return nestedElement;
+ }
+
+ /**
+ * Creates a named nested element. Depending on the results of the
+ * initial introspection, either a method in the given parent instance
+ * or a simple no-arg constructor is used to create an instance of the
+ * specified element type.
+ *
+ * @param project Project to which the parent object belongs.
+ * Must not be <code>null</code>. If the resulting
+ * object is an instance of ProjectComponent, its
+ * Project reference is set to this parameter value.
+ * @param parent Parent object used to create the instance.
+ * Must not be <code>null</code>.
+ * @param elementName Name of the element to create an instance of.
+ * Must not be <code>null</code>.
+ *
+ * @return an instance of the specified element type
+ * @deprecated since 1.6.x.
+ * This is not a namespace aware method.
+ *
+ * @exception BuildException if no method is available to create the
+ * element instance, or if the creating method fails.
+ */
+ @Deprecated
+ public Object createElement(final Project project, final Object parent, final String elementName)
+ throws BuildException {
+ final NestedCreator nc = getNestedCreator(project, "", parent, elementName, null);
+ try {
+ final Object nestedElement = nc.create(project, parent, null);
+ if (project != null) {
+ project.setProjectReference(nestedElement);
+ }
+ return nestedElement;
+ } catch (final IllegalAccessException ie) {
+ // impossible as getMethods should only return public methods
+ throw new BuildException(ie);
+ } catch (final InstantiationException ine) {
+ // impossible as getMethods should only return public methods
+ throw new BuildException(ine);
+ } catch (final InvocationTargetException ite) {
+ throw extractBuildException(ite);
+ }
+ }
+
+ /**
+ * returns an object that creates and stores an object
+ * for an element of a parent.
+ *
+ * @param project Project to which the parent object belongs.
+ * @param parentUri The namespace uri of the parent object.
+ * @param parent Parent object used to create the creator object to
+ * create and store and instance of a subelement.
+ * @param elementName Name of the element to create an instance of.
+ * @param ue The unknown element associated with the element.
+ * @return a creator object to create and store the element instance.
+ */
+ public Creator getElementCreator(
+ final Project project, final String parentUri, final Object parent, final String elementName, final UnknownElement ue) {
+ final NestedCreator nc = getNestedCreator(project, parentUri, parent, elementName, ue);
+ return new Creator(project, parent, nc);
+ }
+
+ /**
+ * Indicates whether the introspected class is a dynamic one,
+ * supporting arbitrary nested elements and/or attributes.
+ *
+ * @return <div><code>true</code> if the introspected class is dynamic;
+ * <code>false</code> otherwise.</div>
+ * @since Ant 1.6.3
+ *
+ * @see DynamicElement
+ * @see DynamicElementNS
+ */
+ public boolean isDynamic() {
+ return DynamicElement.class.isAssignableFrom(bean)
+ || DynamicElementNS.class.isAssignableFrom(bean);
+ }
+
+ /**
+ * Indicates whether the introspected class is a task container,
+ * supporting arbitrary nested tasks/types.
+ *
+ * @return <code>true</code> if the introspected class is a container;
+ * <code>false</code> otherwise.
+ * @since Ant 1.6.3
+ *
+ * @see TaskContainer
+ */
+ public boolean isContainer() {
+ return TaskContainer.class.isAssignableFrom(bean);
+ }
+
+ /**
+ * Indicates if this element supports a nested element of the
+ * given name.
+ *
+ * @param elementName the name of the nested element being checked
+ *
+ * @return true if the given nested element is supported
+ */
+ public boolean supportsNestedElement(final String elementName) {
+ return supportsNestedElement("", elementName);
+ }
+
+ /**
+ * Indicate if this element supports a nested element of the
+ * given name.
+ *
+ * <p>Note that this method will always return true if the
+ * introspected class is {@link #isDynamic dynamic} or contains a
+ * method named "add" with void return type and a single argument.
+ * To ge a more thorough answer, use the four-arg version of this
+ * method instead.</p>
+ *
+ * @param parentUri the uri of the parent
+ * @param elementName the name of the nested element being checked
+ *
+ * @return true if the given nested element is supported
+ */
+ public boolean supportsNestedElement(final String parentUri, final String elementName) {
+ if (isDynamic() || addTypeMethods.size() > 0) {
+ return true;
+ }
+ return supportsReflectElement(parentUri, elementName);
+ }
+
+ /**
+ * Indicate if this element supports a nested element of the
+ * given name.
+ *
+ * <p>Note that this method will always return true if the
+ * introspected class is {@link #isDynamic dynamic}, so be
+ * prepared to catch an exception about unsupported children when
+ * calling {@link #getElementCreator getElementCreator}.</p>
+ *
+ * @param parentUri the uri of the parent
+ * @param elementName the name of the nested element being checked
+ * @param project currently executing project instance
+ * @param parent the parent element
+ *
+ * @return true if the given nested element is supported
+ * @since Ant 1.8.0.
+ */
+ public boolean supportsNestedElement(final String parentUri, final String elementName,
+ final Project project, final Object parent) {
+ if (addTypeMethods.size() > 0
+ && createAddTypeCreator(project, parent, elementName) != null) {
+ return true;
+ }
+ return isDynamic() || supportsReflectElement(parentUri, elementName);
+ }
+
+ /**
+ * Check if this element supports a nested element from reflection.
+ *
+ * @param parentUri the uri of the parent
+ * @param elementName the name of the nested element being checked
+ *
+ * @return true if the given nested element is supported
+ * @since Ant 1.8.0
+ */
+ public boolean supportsReflectElement(
+ String parentUri, final String elementName) {
+ final String name = ProjectHelper.extractNameFromComponentName(elementName);
+ if (!nestedCreators.containsKey(name.toLowerCase(Locale.ENGLISH))) {
+ return false;
+ }
+ String uri = ProjectHelper.extractUriFromComponentName(elementName);
+ if (uri.equals(ProjectHelper.ANT_CORE_URI)) {
+ uri = "";
+ }
+ if ("".equals(uri)) {
+ return true;
+ }
+ if (parentUri.equals(ProjectHelper.ANT_CORE_URI)) {
+ parentUri = "";
+ }
+ return uri.equals(parentUri);
+ }
+
+ /**
+ * Stores a named nested element using a storage method determined
+ * by the initial introspection. If no appropriate storage method
+ * is available, this method returns immediately.
+ *
+ * @param project Ignored in this implementation.
+ * May be <code>null</code>.
+ *
+ * @param parent Parent instance to store the child in.
+ * Must not be <code>null</code>.
+ *
+ * @param child Child instance to store in the parent.
+ * Should not be <code>null</code>.
+ *
+ * @param elementName Name of the child element to store.
+ * May be <code>null</code>, in which case
+ * this method returns immediately.
+ *
+ * @exception BuildException if the storage method fails.
+ */
+ public void storeElement(final Project project, final Object parent, final Object child,
+ final String elementName) throws BuildException {
+ if (elementName == null) {
+ return;
+ }
+ final NestedCreator ns = nestedCreators.get(elementName.toLowerCase(Locale.ENGLISH));
+ if (ns == null) {
+ return;
+ }
+ try {
+ ns.store(parent, child);
+ } catch (final IllegalAccessException ie) {
+ // impossible as getMethods should only return public methods
+ throw new BuildException(ie);
+ } catch (final InstantiationException ine) {
+ // impossible as getMethods should only return public methods
+ throw new BuildException(ine);
+ } catch (final InvocationTargetException ite) {
+ throw extractBuildException(ite);
+ }
+ }
+
+ /**
+ * Helper method to extract the inner fault from an {@link InvocationTargetException}, and turn
+ * it into a BuildException. If it is already a BuildException, it is type cast and returned; if
+ * not a new BuildException is created containing the child as nested text.
+ * @param ite
+ * @return the nested exception
+ */
+ private static BuildException extractBuildException(final InvocationTargetException ite) {
+ final Throwable t = ite.getTargetException();
+ if (t instanceof BuildException) {
+ return (BuildException) t;
+ }
+ return new BuildException(t);
+ }
+
+ /**
+ * Returns the type of a named nested element.
+ *
+ * @param elementName The name of the element to find the type of.
+ * Must not be <code>null</code>.
+ *
+ * @return the type of the nested element with the specified name.
+ * This will never be <code>null</code>.
+ *
+ * @exception BuildException if the introspected class does not
+ * support the named nested element.
+ */
+ public Class<?> getElementType(final String elementName) throws BuildException {
+ final Class<?> nt = nestedTypes.get(elementName);
+ if (nt == null) {
+ throw new UnsupportedElementException("Class "
+ + bean.getName() + " doesn't support the nested \""
+ + elementName + "\" element.", elementName);
+ }
+ return nt;
+ }
+
+ /**
+ * Returns the type of a named attribute.
+ *
+ * @param attributeName The name of the attribute to find the type of.
+ * Must not be <code>null</code>.
+ *
+ * @return the type of the attribute with the specified name.
+ * This will never be <code>null</code>.
+ *
+ * @exception BuildException if the introspected class does not
+ * support the named attribute.
+ */
+ public Class<?> getAttributeType(final String attributeName) throws BuildException {
+ final Class<?> at = attributeTypes.get(attributeName);
+ if (at == null) {
+ throw new UnsupportedAttributeException("Class "
+ + bean.getName() + " doesn't support the \""
+ + attributeName + "\" attribute.", attributeName);
+ }
+ return at;
+ }
+
+ /**
+ * Returns the addText method when the introspected
+ * class supports nested text.
+ *
+ * @return the method on this introspected class that adds nested text.
+ * Cannot be <code>null</code>.
+ * @throws BuildException if the introspected class does not
+ * support the nested text.
+ * @since Ant 1.6.3
+ */
+ public Method getAddTextMethod() throws BuildException {
+ if (!supportsCharacters()) {
+ throw new BuildException("Class " + bean.getName()
+ + " doesn't support nested text data.");
+ }
+ return addText;
+ }
+
+ /**
+ * Returns the adder or creator method of a named nested element.
+ *
+ * @param elementName The name of the attribute to find the setter
+ * method of. Must not be <code>null</code>.
+ * @return the method on this introspected class that adds or creates this
+ * nested element. Can be <code>null</code> when the introspected
+ * class is a dynamic configurator!
+ * @throws BuildException if the introspected class does not
+ * support the named nested element.
+ * @since Ant 1.6.3
+ */
+ public Method getElementMethod(final String elementName) throws BuildException {
+ final Object creator = nestedCreators.get(elementName);
+ if (creator == null) {
+ throw new UnsupportedElementException("Class "
+ + bean.getName() + " doesn't support the nested \""
+ + elementName + "\" element.", elementName);
+ }
+ return ((NestedCreator) creator).method;
+ }
+
+ /**
+ * Returns the setter method of a named attribute.
+ *
+ * @param attributeName The name of the attribute to find the setter
+ * method of. Must not be <code>null</code>.
+ * @return the method on this introspected class that sets this attribute.
+ * This will never be <code>null</code>.
+ * @throws BuildException if the introspected class does not
+ * support the named attribute.
+ * @since Ant 1.6.3
+ */
+ public Method getAttributeMethod(final String attributeName) throws BuildException {
+ final Object setter = attributeSetters.get(attributeName);
+ if (setter == null) {
+ throw new UnsupportedAttributeException("Class "
+ + bean.getName() + " doesn't support the \""
+ + attributeName + "\" attribute.", attributeName);
+ }
+ return ((AttributeSetter) setter).method;
+ }
+
+ /**
+ * Returns whether or not the introspected class supports PCDATA.
+ *
+ * @return whether or not the introspected class supports PCDATA.
+ */
+ public boolean supportsCharacters() {
+ return addText != null;
+ }
+
+ /**
+ * Returns an enumeration of the names of the attributes supported by the introspected class.
+ *
+ * @return an enumeration of the names of the attributes supported by the introspected class.
+ * @see #getAttributeMap
+ */
+ public Enumeration<String> getAttributes() {
+ return attributeSetters.keys();
+ }
+
+ /**
+ * Returns a read-only map of attributes supported by the introspected class.
+ *
+ * @return an attribute name to attribute <code>Class</code>
+ * unmodifiable map. Can be empty, but never <code>null</code>.
+ * @since Ant 1.6.3
+ */
+ public Map<String, Class<?>> getAttributeMap() {
+ return attributeTypes.isEmpty()
+ ? Collections.<String, Class<?>> emptyMap() : Collections.unmodifiableMap(attributeTypes);
+ }
+
+ /**
+ * Returns an enumeration of the names of the nested elements supported
+ * by the introspected class.
+ *
+ * @return an enumeration of the names of the nested elements supported
+ * by the introspected class.
+ * @see #getNestedElementMap
+ */
+ public Enumeration<String> getNestedElements() {
+ return nestedTypes.keys();
+ }
+
+ /**
+ * Returns a read-only map of nested elements supported
+ * by the introspected class.
+ *
+ * @return a nested-element name to nested-element <code>Class</code>
+ * unmodifiable map. Can be empty, but never <code>null</code>.
+ * @since Ant 1.6.3
+ */
+ public Map<String, Class<?>> getNestedElementMap() {
+ return nestedTypes.isEmpty()
+ ? Collections.<String, Class<?>> emptyMap() : Collections.unmodifiableMap(nestedTypes);
+ }
+
+ /**
+ * Returns a read-only list of extension points supported
+ * by the introspected class.
+ * <p>
+ * A task/type or nested element with void methods named <code>add()</code>
+ * or <code>addConfigured()</code>, taking a single class or interface
+ * argument, supports extensions point. This method returns the list of
+ * all these <em>void add[Configured](type)</em> methods.
+ *
+ * @return a list of void, single argument add() or addConfigured()
+ * <code>Method</code>s of all supported extension points.
+ * These methods are sorted such that if the argument type of a
+ * method derives from another type also an argument of a method
+ * of this list, the method with the most derived argument will
+ * always appear first. Can be empty, but never <code>null</code>.
+ * @since Ant 1.6.3
+ */
+ public List<Method> getExtensionPoints() {
+ return addTypeMethods.isEmpty()
+ ? Collections.<Method> emptyList() : Collections.unmodifiableList(addTypeMethods);
+ }
+
+ /**
+ * Creates an implementation of AttributeSetter for the given
+ * attribute type. Conversions (where necessary) are automatically
+ * made for the following types:
+ * <ul>
+ * <li>String (left as it is)
+ * <li>Character/char (first character is used)
+ * <li>Boolean/boolean
+ * ({@link Project#toBoolean(String) Project.toBoolean(String)} is used)
+ * <li>Class (Class.forName is used)
+ * <li>File (resolved relative to the appropriate project)
+ * <li>Path (resolve relative to the appropriate project)
+ * <li>Resource (resolved as a FileResource relative to the appropriate project)
+ * <li>FileProvider (resolved as a FileResource relative to the appropriate project)
+ * <li>EnumeratedAttribute (uses its own
+ * {@link EnumeratedAttribute#setValue(String) setValue} method)
+ * <li>Other primitive types (wrapper classes are used with constructors
+ * taking String)
+ * </ul>
+ *
+ * If none of the above covers the given parameters, a constructor for the
+ * appropriate class taking a String parameter is used if it is available.
+ *
+ * @param m The method to invoke on the bean when the setter is invoked.
+ * Must not be <code>null</code>.
+ * @param arg The type of the single argument of the bean's method.
+ * Must not be <code>null</code>.
+ * @param attrName the name of the attribute for which the setter is being
+ * created.
+ *
+ * @return an appropriate AttributeSetter instance, or <code>null</code>
+ * if no appropriate conversion is available.
+ */
+ private AttributeSetter createAttributeSetter(final Method m,
+ final Class<?> arg,
+ final String attrName) {
+ // use wrappers for primitive classes, e.g. int and
+ // Integer are treated identically
+ final Class<?> reflectedArg = PRIMITIVE_TYPE_MAP.containsKey(arg)
+ ? PRIMITIVE_TYPE_MAP.get(arg) : arg;
+
+ // Object.class - it gets handled differently by AttributeSetter
+ if (java.lang.Object.class == reflectedArg) {
+ return new AttributeSetter(m, arg) {
+ @Override
+ public void set(final Project p, final Object parent, final String value)
+ throws InvocationTargetException,
+ IllegalAccessException {
+ throw new BuildException(
+ "Internal ant problem - this should not get called");
+ }
+ };
+ }
+ // simplest case - setAttribute expects String
+ if (java.lang.String.class.equals(reflectedArg)) {
+ return new AttributeSetter(m, arg) {
+ @Override
+ public void set(final Project p, final Object parent, final String value)
+ throws InvocationTargetException, IllegalAccessException {
+ m.invoke(parent, (Object[]) new String[] {value});
+ }
+ };
+ }
+ // char and Character get special treatment - take the first character
+ if (java.lang.Character.class.equals(reflectedArg)) {
+ return new AttributeSetter(m, arg) {
+ @Override
+ public void set(final Project p, final Object parent, final String value)
+ throws InvocationTargetException, IllegalAccessException {
+ if (value.length() == 0) {
+ throw new BuildException("The value \"\" is not a "
+ + "legal value for attribute \"" + attrName + "\"");
+ }
+ m.invoke(parent, (Object[]) new Character[] {new Character(value.charAt(0))});
+ }
+ };
+ }
+ // boolean and Boolean get special treatment because we have a nice method in Project
+ if (java.lang.Boolean.class.equals(reflectedArg)) {
+ return new AttributeSetter(m, arg) {
+ @Override
+ public void set(final Project p, final Object parent, final String value)
+ throws InvocationTargetException, IllegalAccessException {
+ m.invoke(parent, (Object[]) new Boolean[] {
+ Project.toBoolean(value) ? Boolean.TRUE : Boolean.FALSE });
+ }
+ };
+ }
+ // Class doesn't have a String constructor but a decent factory method
+ if (java.lang.Class.class.equals(reflectedArg)) {
+ return new AttributeSetter(m, arg) {
+ @Override
+ public void set(final Project p, final Object parent, final String value)
+ throws InvocationTargetException, IllegalAccessException, BuildException {
+ try {
+ m.invoke(parent, new Object[] {Class.forName(value)});
+ } catch (final ClassNotFoundException ce) {
+ throw new BuildException(ce);
+ }
+ }
+ };
+ }
+ // resolve relative paths through Project
+ if (java.io.File.class.equals(reflectedArg)) {
+ return new AttributeSetter(m, arg) {
+ @Override
+ public void set(final Project p, final Object parent, final String value)
+ throws InvocationTargetException, IllegalAccessException {
+ m.invoke(parent, new Object[] {p.resolveFile(value)});
+ }
+ };
+ }
+ // resolve Resources/FileProviders as FileResources relative to Project:
+ if (Resource.class.equals(reflectedArg) || FileProvider.class.equals(reflectedArg)) {
+ return new AttributeSetter(m, arg) {
+ @Override
+ void set(final Project p, final Object parent, final String value) throws InvocationTargetException,
+ IllegalAccessException, BuildException {
+ m.invoke(parent, new Object[] {new FileResource(p, p.resolveFile(value))});
+ };
+ };
+ }
+ // EnumeratedAttributes have their own helper class
+ if (EnumeratedAttribute.class.isAssignableFrom(reflectedArg)) {
+ return new AttributeSetter(m, arg) {
+ @Override
+ public void set(final Project p, final Object parent, final String value)
+ throws InvocationTargetException, IllegalAccessException, BuildException {
+ try {
+ final EnumeratedAttribute ea = (EnumeratedAttribute) reflectedArg.newInstance();
+ ea.setValue(value);
+ m.invoke(parent, new Object[] {ea});
+ } catch (final InstantiationException ie) {
+ throw new BuildException(ie);
+ }
+ }
+ };
+ }
+
+ final AttributeSetter setter = getEnumSetter(reflectedArg, m, arg);
+ if (setter != null) {
+ return setter;
+ }
+
+ if (java.lang.Long.class.equals(reflectedArg)) {
+ return new AttributeSetter(m, arg) {
+ @Override
+ public void set(final Project p, final Object parent, final String value)
+ throws InvocationTargetException, IllegalAccessException, BuildException {
+ try {
+ m.invoke(parent, new Object[] {
+ new Long(StringUtils.parseHumanSizes(value)) });
+ } catch (final NumberFormatException e) {
+ throw new BuildException("Can't assign non-numeric"
+ + " value '" + value + "' to"
+ + " attribute " + attrName);
+ } catch (final InvocationTargetException e) {
+ throw e;
+ } catch (final IllegalAccessException e) {
+ throw e;
+ } catch (final Exception e) {
+ throw new BuildException(e);
+ }
+ }
+ };
+ }
+ // worst case. look for a public String constructor and use it
+ // also supports new Whatever(Project, String) as for Path or Reference
+ // This is used (deliberately) for all primitives/wrappers other than
+ // char, boolean, and long.
+ boolean includeProject;
+ Constructor<?> c;
+ try {
+ // First try with Project.
+ c = reflectedArg.getConstructor(Project.class, String.class);
+ includeProject = true;
+ } catch (final NoSuchMethodException nme) {
+ // OK, try without.
+ try {
+ c = reflectedArg.getConstructor(String.class);
+ includeProject = false;
+ } catch (final NoSuchMethodException nme2) {
+ // Well, no matching constructor.
+ return null;
+ }
+ }
+ final boolean finalIncludeProject = includeProject;
+ final Constructor<?> finalConstructor = c;
+
+ return new AttributeSetter(m, arg) {
+ @Override
+ public void set(final Project p, final Object parent, final String value)
+ throws InvocationTargetException, IllegalAccessException, BuildException {
+ try {
+ final Object[] args = finalIncludeProject
+ ? new Object[] {p, value} : new Object[] {value};
+
+ final Object attribute = finalConstructor.newInstance(args);
+ if (p != null) {
+ p.setProjectReference(attribute);
+ }
+ m.invoke(parent, new Object[] {attribute});
+ } catch (final InvocationTargetException e) {
+ final Throwable cause = e.getCause();
+ if (cause instanceof IllegalArgumentException) {
+ throw new BuildException("Can't assign value '" + value
+ + "' to attribute " + attrName
+ + ", reason: "
+ + cause.getClass()
+ + " with message '"
+ + cause.getMessage() + "'");
+ }
+ throw e;
+ } catch (final InstantiationException ie) {
+ throw new BuildException(ie);
+ }
+ }
+ };
+ }
+
+ private AttributeSetter getEnumSetter(
+ final Class<?> reflectedArg, final Method m, final Class<?> arg) {
+ if (reflectedArg.isEnum()) {
+ return new AttributeSetter(m, arg) {
+ @Override
+ public void set(final Project p, final Object parent, final String value)
+ throws InvocationTargetException, IllegalAccessException,
+ BuildException {
+ Enum<?> setValue;
+ try {
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ final Enum<?> enumValue = Enum.valueOf((Class<? extends Enum>) reflectedArg,
+ value);
+ setValue = enumValue;
+ } catch (final IllegalArgumentException e) {
+ //there is specific logic here for the value
+ // being out of the allowed set of enumerations.
+ throw new BuildException("'" + value + "' is not a permitted value for "
+ + reflectedArg.getName());
+ }
+ m.invoke(parent, setValue);
+ }
+ };
+ }
+ return null;
+ }
+
+ /**
+ * Returns a description of the type of the given element in
+ * relation to a given project. This is used for logging purposes
+ * when the element is asked to cope with some data it has no way of handling.
+ *
+ * @param project The project the element is defined in. Must not be <code>null</code>.
+ *
+ * @param element The element to describe. Must not be <code>null</code>.
+ *
+ * @return a description of the element type
+ */
+ private String getElementName(final Project project, final Object element) {
+ return project.getElementName(element);
+ }
+
+ /**
+ * Extracts the name of a property from a method name by subtracting
+ * a given prefix and converting into lower case. It is up to calling
+ * code to make sure the method name does actually begin with the
+ * specified prefix - no checking is done in this method.
+ *
+ * @param methodName The name of the method in question. Must not be <code>null</code>.
+ * @param prefix The prefix to remove. Must not be <code>null</code>.
+ *
+ * @return the lower-cased method name with the prefix removed.
+ */
+ private static String getPropertyName(final String methodName, final String prefix) {
+ return methodName.substring(prefix.length()).toLowerCase(Locale.ENGLISH);
+ }
+
+ /**
+ * creator - allows use of create/store external
+ * to IntrospectionHelper.
+ * The class is final as it has a private constructor.
+ */
+ public static final class Creator {
+ private final NestedCreator nestedCreator;
+ private final Object parent;
+ private final Project project;
+ private Object nestedObject;
+ private String polyType;
+
+ /**
+ * Creates a new Creator instance.
+ * This object is given to the UnknownElement to create
+ * objects for sub-elements. UnknownElement calls
+ * create to create an object, the object then gets
+ * configured and then UnknownElement calls store.
+ * SetPolyType may be used to override the type used
+ * to create the object with. SetPolyType gets called before create.
+ *
+ * @param project the current project
+ * @param parent the parent object to create the object in
+ * @param nestedCreator the nested creator object to use
+ */
+ private Creator(final Project project, final Object parent, final NestedCreator nestedCreator) {
+ this.project = project;
+ this.parent = parent;
+ this.nestedCreator = nestedCreator;
+ }
+
+ /**
+ * Used to override the class used to create the object.
+ *
+ * @param polyType a ant component type name
+ */
+ public void setPolyType(final String polyType) {
+ this.polyType = polyType;
+ }
+
+ /**
+ * Create an object using this creator, which is determined by introspection.
+ *
+ * @return the created object
+ */
+ public Object create() {
+ if (polyType != null) {
+ if (!nestedCreator.isPolyMorphic()) {
+ throw new BuildException(
+ "Not allowed to use the polymorphic form for this element");
+ }
+ final ComponentHelper helper = ComponentHelper.getComponentHelper(project);
+ nestedObject = helper.createComponent(polyType);
+ if (nestedObject == null) {
+ throw new BuildException("Unable to create object of type " + polyType);
+ }
+ }
+ try {
+ nestedObject = nestedCreator.create(project, parent, nestedObject);
+ if (project != null) {
+ project.setProjectReference(nestedObject);
+ }
+ return nestedObject;
+ } catch (final IllegalAccessException ex) {
+ throw new BuildException(ex);
+ } catch (final InstantiationException ex) {
+ throw new BuildException(ex);
+ } catch (final IllegalArgumentException ex) {
+ if (polyType == null) {
+ throw ex;
+ }
+ throw new BuildException("Invalid type used " + polyType);
+ } catch (final InvocationTargetException ex) {
+ throw extractBuildException(ex);
+ }
+ }
+
+ /**
+ * @return the real object (used currently only for presetdef).
+ */
+ public Object getRealObject() {
+ return nestedCreator.getRealObject();
+ }
+
+ /**
+ * Stores the nested element object using a storage method determined by introspection.
+ *
+ */
+ public void store() {
+ try {
+ nestedCreator.store(parent, nestedObject);
+ } catch (final IllegalAccessException ex) {
+ throw new BuildException(ex);
+ } catch (final InstantiationException ex) {
+ throw new BuildException(ex);
+ } catch (final IllegalArgumentException ex) {
+ if (polyType == null) {
+ throw ex;
+ }
+ throw new BuildException("Invalid type used " + polyType);
+ } catch (final InvocationTargetException ex) {
+ throw extractBuildException(ex);
+ }
+ }
+ }
+
+ /**
+ * Internal interface used to create nested elements. Not documented
+ * in detail for reasons of source code readability.
+ */
+ private abstract static class NestedCreator {
+ private final Method method; // the method called to add/create the nested element
+
+ protected NestedCreator(final Method m) {
+ method = m;
+ }
+ Method getMethod() {
+ return method;
+ }
+ boolean isPolyMorphic() {
+ return false;
+ }
+ Object getRealObject() {
+ return null;
+ }
+ abstract Object create(Project project, Object parent, Object child)
+ throws InvocationTargetException, IllegalAccessException, InstantiationException;
+
+ void store(final Object parent, final Object child)
+ throws InvocationTargetException, IllegalAccessException, InstantiationException {
+ // DO NOTHING
+ }
+ }
+
+ private static class CreateNestedCreator extends NestedCreator {
+ CreateNestedCreator(final Method m) {
+ super(m);
+ }
+
+ @Override
+ Object create(final Project project, final Object parent, final Object ignore)
+ throws InvocationTargetException, IllegalAccessException {
+ return getMethod().invoke(parent, new Object[] {});
+ }
+ }
+
+ /** Version to use for addXXX and addConfiguredXXX */
+ private static class AddNestedCreator extends NestedCreator {
+
+ static final int ADD = 1;
+ static final int ADD_CONFIGURED = 2;
+
+ private final Constructor<?> constructor;
+ private final int behavior; // ADD or ADD_CONFIGURED
+
+ AddNestedCreator(final Method m, final Constructor<?> c, final int behavior) {
+ super(m);
+ this.constructor = c;
+ this.behavior = behavior;
+ }
+
+ @Override
+ boolean isPolyMorphic() {
+ return true;
+ }
+
+ @Override
+ Object create(final Project project, final Object parent, Object child)
+ throws InvocationTargetException, IllegalAccessException, InstantiationException {
+ if (child == null) {
+ child = constructor.newInstance(
+ constructor.getParameterTypes().length == 0
+ ? new Object[] {} : new Object[] {project});
+ }
+ if (child instanceof PreSetDef.PreSetDefinition) {
+ child = ((PreSetDef.PreSetDefinition) child).createObject(project);
+ }
+ if (behavior == ADD) {
+ istore(parent, child);
+ }
+ return child;
+ }
+
+ @Override
+ void store(final Object parent, final Object child)
+ throws InvocationTargetException, IllegalAccessException, InstantiationException {
+ if (behavior == ADD_CONFIGURED) {
+ istore(parent, child);
+ }
+ }
+
+ private void istore(final Object parent, final Object child)
+ throws InvocationTargetException, IllegalAccessException, InstantiationException {
+ getMethod().invoke(parent, new Object[] {child});
+ }
+ }
+
+ /**
+ * Internal interface used to setting element attributes. Not documented
+ * in detail for reasons of source code readability.
+ */
+ private abstract static class AttributeSetter {
+ private final Method method; // the method called to set the attribute
+ private final Class<?> type;
+ protected AttributeSetter(final Method m, final Class<?> type) {
+ method = m;
+ this.type = type;
+ }
+ void setObject(final Project p, final Object parent, final Object value)
+ throws InvocationTargetException, IllegalAccessException, BuildException {
+ if (type != null) {
+ Class<?> useType = type;
+ if (type.isPrimitive()) {
+ if (value == null) {
+ throw new BuildException(
+ "Attempt to set primitive "
+ + getPropertyName(method.getName(), "set")
+ + " to null on " + parent);
+ }
+ useType = PRIMITIVE_TYPE_MAP.get(type);
+ }
+ if (value == null || useType.isInstance(value)) {
+ method.invoke(parent, new Object[] {value});
+ return;
+ }
+ }
+ set(p, parent, value.toString());
+ }
+ abstract void set(Project p, Object parent, String value)
+ throws InvocationTargetException, IllegalAccessException, BuildException;
+ }
+
+ /**
+ * Clears the static cache of on build finished.
+ */
+ public static synchronized void clearCache() {
+ HELPERS.clear();
+ }
+
+ /**
+ * Create a NestedCreator for the given element.
+ * @param project owning project
+ * @param parent Parent object used to create the instance.
+ * @param elementName name of the element
+ * @return a nested creator, or null if there is no component of the given name, or it
+ * has no matching add type methods
+ * @throws BuildException
+ */
+ private NestedCreator createAddTypeCreator(
+ final Project project, final Object parent, final String elementName) throws BuildException {
+ if (addTypeMethods.size() == 0) {
+ return null;
+ }
+ final ComponentHelper helper = ComponentHelper.getComponentHelper(project);
+
+ final MethodAndObject restricted = createRestricted(
+ helper, elementName, addTypeMethods);
+ final MethodAndObject topLevel = createTopLevel(
+ helper, elementName, addTypeMethods);
+
+ if (restricted == null && topLevel == null) {
+ return null;
+ }
+
+ if (restricted != null && topLevel != null) {
+ throw new BuildException(
+ "ambiguous: type and component definitions for "
+ + elementName);
+ }
+
+ final MethodAndObject methodAndObject
+ = restricted != null ? restricted : topLevel;
+
+ Object rObject = methodAndObject.object;
+ if (methodAndObject.object instanceof PreSetDef.PreSetDefinition) {
+ rObject = ((PreSetDef.PreSetDefinition) methodAndObject.object)
+ .createObject(project);
+ }
+ final Object nestedObject = methodAndObject.object;
+ final Object realObject = rObject;
+
+ return new NestedCreator(methodAndObject.method) {
+ @Override
+ Object create(final Project project, final Object parent, final Object ignore)
+ throws InvocationTargetException, IllegalAccessException {
+ if (!getMethod().getName().endsWith("Configured")) {
+ getMethod().invoke(parent, new Object[] {realObject});
+ }
+ return nestedObject;
+ }
+
+ @Override
+ Object getRealObject() {
+ return realObject;
+ }
+
+ @Override
+ void store(final Object parent, final Object child) throws InvocationTargetException,
+ IllegalAccessException, InstantiationException {
+ if (getMethod().getName().endsWith("Configured")) {
+ getMethod().invoke(parent, new Object[] {realObject});
+ }
+ }
+ };
+ }
+
+ /**
+ * Inserts an add or addConfigured method into
+ * the addTypeMethods array. The array is
+ * ordered so that the more derived classes are first.
+ * If both add and addConfigured are present, the addConfigured will take priority.
+ * @param method the <code>Method</code> to insert.
+ */
+ private void insertAddTypeMethod(final Method method) {
+ final Class<?> argClass = method.getParameterTypes()[0];
+ final int size = addTypeMethods.size();
+ for (int c = 0; c < size; ++c) {
+ final Method current = addTypeMethods.get(c);
+ if (current.getParameterTypes()[0].equals(argClass)) {
+ if (method.getName().equals("addConfigured")) {
+ // add configured replaces the add method
+ addTypeMethods.set(c, method);
+ }
+ return; // Already present
+ }
+ if (current.getParameterTypes()[0].isAssignableFrom(argClass)) {
+ addTypeMethods.add(c, method);
+ return; // higher derived
+ }
+ }
+ addTypeMethods.add(method);
+ }
+
+ /**
+ * Search the list of methods to find the first method
+ * that has a parameter that accepts the nested element object.
+ * @param paramClass the <code>Class</code> type to search for.
+ * @param methods the <code>List</code> of methods to search.
+ * @return a matching <code>Method</code>; null if none found.
+ */
+ private Method findMatchingMethod(final Class<?> paramClass, final List<Method> methods) {
+ if (paramClass == null) {
+ return null;
+ }
+ Class<?> matchedClass = null;
+ Method matchedMethod = null;
+
+ final int size = methods.size();
+ for (int i = 0; i < size; ++i) {
+ final Method method = methods.get(i);
+ final Class<?> methodClass = method.getParameterTypes()[0];
+ if (methodClass.isAssignableFrom(paramClass)) {
+ if (matchedClass == null) {
+ matchedClass = methodClass;
+ matchedMethod = method;
+ } else if (!methodClass.isAssignableFrom(matchedClass)) {
+ throw new BuildException("ambiguous: types " + matchedClass.getName() + " and "
+ + methodClass.getName() + " match " + paramClass.getName());
+ }
+ }
+ }
+ return matchedMethod;
+ }
+
+ private String condenseText(final String text) {
+ if (text.length() <= MAX_REPORT_NESTED_TEXT) {
+ return text;
+ }
+ final int ends = (MAX_REPORT_NESTED_TEXT - ELLIPSIS.length()) / 2;
+ return new StringBuffer(text).replace(ends, text.length() - ends, ELLIPSIS).toString();
+ }
+
+
+ private static class MethodAndObject {
+ private final Method method;
+ private final Object object;
+ public MethodAndObject(final Method method, final Object object) {
+ this.method = method;
+ this.object = object;
+ }
+ }
+
+ /**
+ *
+ */
+ private AntTypeDefinition findRestrictedDefinition(
+ final ComponentHelper helper, final String componentName, final List<Method> methods) {
+ AntTypeDefinition definition = null;
+ Class<?> matchedDefinitionClass = null;
+
+ final List<AntTypeDefinition> definitions = helper.getRestrictedDefinitions(componentName);
+ if (definitions == null) {
+ return null;
+ }
+ synchronized (definitions) {
+ final int size = definitions.size();
+ for (int i = 0; i < size; ++i) {
+ final AntTypeDefinition d = definitions.get(i);
+ final Class<?> exposedClass = d.getExposedClass(helper.getProject());
+ if (exposedClass == null) {
+ continue;
+ }
+ final Method method = findMatchingMethod(exposedClass, methods);
+ if (method == null) {
+ continue;
+ }
+ if (matchedDefinitionClass != null) {
+ throw new BuildException(
+ "ambiguous: restricted definitions for "
+ + componentName + " "
+ + matchedDefinitionClass + " and " + exposedClass);
+ }
+ matchedDefinitionClass = exposedClass;
+ definition = d;
+ }
+ }
+ return definition;
+ }
+
+ private MethodAndObject createRestricted(
+ final ComponentHelper helper, final String elementName, final List<Method> addTypeMethods) {
+
+ final Project project = helper.getProject();
+
+ final AntTypeDefinition restrictedDefinition =
+ findRestrictedDefinition(helper, elementName, addTypeMethods);
+
+ if (restrictedDefinition == null) {
+ return null;
+ }
+
+ final Method addMethod = findMatchingMethod(
+ restrictedDefinition.getExposedClass(project), addTypeMethods);
+ if (addMethod == null) {
+ throw new BuildException(
+ "Ant Internal Error - contract mismatch for "
+ + elementName);
+ }
+ final Object addedObject = restrictedDefinition.create(project);
+ if (addedObject == null) {
+ throw new BuildException(
+ "Failed to create object " + elementName
+ + " of type " + restrictedDefinition.getTypeClass(project));
+ }
+ return new MethodAndObject(addMethod, addedObject);
+ }
+
+ private MethodAndObject createTopLevel(
+ final ComponentHelper helper, final String elementName, final List<Method> methods) {
+ final Class<?> clazz = helper.getComponentClass(elementName);
+ if (clazz == null) {
+ return null;
+ }
+ final Method addMethod = findMatchingMethod(clazz, addTypeMethods);
+ if (addMethod == null) {
+ return null;
+ }
+ final Object addedObject = helper.createComponent(elementName);
+ return new MethodAndObject(addMethod, addedObject);
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/Location.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/Location.java
new file mode 100644
index 00000000..8e25d107
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/Location.java
@@ -0,0 +1,179 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant;
+
+import java.io.Serializable;
+
+import org.apache.tools.ant.util.FileUtils;
+import org.xml.sax.Locator;
+
+/**
+ * Stores the location of a piece of text within a file (file name,
+ * line number and column number). Note that the column number is
+ * currently ignored.
+ *
+ */
+public class Location implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ /** Name of the file. */
+ private final String fileName;
+ /** Line number within the file. */
+ private final int lineNumber;
+ /** Column number within the file. */
+ private final int columnNumber;
+
+ /** Location to use when one is needed but no information is available */
+ public static final Location UNKNOWN_LOCATION = new Location();
+
+ private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+
+ /**
+ * Creates an "unknown" location.
+ */
+ private Location() {
+ this(null, 0, 0);
+ }
+
+ /**
+ * Creates a location consisting of a file name but no line number or
+ * column number.
+ *
+ * @param fileName The name of the file. May be <code>null</code>,
+ * in which case the location is equivalent to
+ * {@link #UNKNOWN_LOCATION UNKNOWN_LOCATION}.
+ */
+ public Location(String fileName) {
+ this(fileName, 0, 0);
+ }
+
+ /**
+ * Creates a location from the SAX locator using the system ID as
+ * the filename.
+ *
+ * @param loc Must not be <code>null</code>.
+ *
+ * @since Ant 1.6
+ */
+ public Location(Locator loc) {
+ this(loc.getSystemId(), loc.getLineNumber(), loc.getColumnNumber());
+ }
+
+ /**
+ * Creates a location consisting of a file name, line number and
+ * column number.
+ *
+ * @param fileName The name of the file. May be <code>null</code>,
+ * in which case the location is equivalent to
+ * {@link #UNKNOWN_LOCATION UNKNOWN_LOCATION}.
+ *
+ * @param lineNumber Line number within the file. Use 0 for unknown
+ * positions within a file.
+ * @param columnNumber Column number within the line.
+ */
+ public Location(String fileName, int lineNumber, int columnNumber) {
+ if (fileName != null && fileName.startsWith("file:")) {
+ this.fileName = FILE_UTILS.fromURI(fileName);
+ } else {
+ this.fileName = fileName;
+ }
+ this.lineNumber = lineNumber;
+ this.columnNumber = columnNumber;
+ }
+
+ /**
+ * @return the filename portion of the location
+ * @since Ant 1.6
+ */
+ public String getFileName() {
+ return fileName;
+ }
+
+ /**
+ * @return the line number
+ * @since Ant 1.6
+ */
+ public int getLineNumber() {
+ return lineNumber;
+ }
+
+ /**
+ * @return the column number
+ * @since Ant 1.7
+ */
+ public int getColumnNumber() {
+ return columnNumber;
+ }
+
+ /**
+ * Returns the file name, line number, a colon and a trailing space.
+ * An error message can be appended easily. For unknown locations, an
+ * empty string is returned.
+ *
+ * @return a String of the form <code>"fileName:lineNumber: "</code>
+ * if both file name and line number are known,
+ * <code>"fileName: "</code> if only the file name is known,
+ * and the empty string for unknown locations.
+ */
+ public String toString() {
+ StringBuffer buf = new StringBuffer();
+
+ if (fileName != null) {
+ buf.append(fileName);
+
+ if (lineNumber != 0) {
+ buf.append(":");
+ buf.append(lineNumber);
+ }
+
+ buf.append(": ");
+ }
+
+ return buf.toString();
+ }
+
+ /**
+ * Equality operation.
+ * @param other the object to compare to.
+ * @return true if the other object contains the same information
+ * as this object.
+ * @since Ant 1.6.3
+ */
+ public boolean equals(Object other) {
+ if (this == other) {
+ return true;
+ }
+ if (other == null) {
+ return false;
+ }
+ if (!(other.getClass() == getClass())) {
+ return false;
+ }
+ return toString().equals(other.toString());
+ }
+
+ /**
+ * Hash operation.
+ * @return a hash code value for this location.
+ * @since Ant 1.6.3
+ */
+ public int hashCode() {
+ return toString().hashCode();
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/MagicNames.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/MagicNames.java
new file mode 100644
index 00000000..bc39a257
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/MagicNames.java
@@ -0,0 +1,293 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant;
+
+import org.apache.tools.ant.launch.Launcher;
+
+/**
+ * Magic names used within Ant.
+ *
+ * Not all magic names are here yet.
+ *
+ * @since Ant 1.6
+ */
+public final class MagicNames {
+
+ private MagicNames() {
+ }
+
+ /**
+ * prefix for antlib URIs:
+ * {@value}
+ */
+ public static final String ANTLIB_PREFIX = "antlib:";
+
+ /**
+ * Ant version property.
+ * Value: {@value}
+ */
+ public static final String ANT_VERSION = "ant.version";
+
+ /**
+ * System classpath policy.
+ * Value: {@value}
+ */
+ public static final String BUILD_SYSCLASSPATH = "build.sysclasspath";
+
+ /**
+ * The name of the script repository used by the script repo task.
+ * Value {@value}
+ */
+ public static final String SCRIPT_REPOSITORY = "org.apache.ant.scriptrepo";
+
+ /**
+ * The name of the reference to the System Class Loader.
+ * Value {@value}
+ **/
+ public static final String SYSTEM_LOADER_REF = "ant.coreLoader";
+
+ /**
+ * Name of the property which can provide an override of the repository dir.
+ * for the libraries task
+ * Value {@value}
+ */
+ public static final String REPOSITORY_DIR_PROPERTY = "ant.maven.repository.dir";
+
+ /**
+ * Name of the property which can provide an override of the repository URL.
+ * for the libraries task
+ * Value {@value}
+ */
+ public static final String REPOSITORY_URL_PROPERTY = "ant.maven.repository.url";
+
+ /**
+ * name of the resource that taskdefs are stored under.
+ * Value: {@value}
+ */
+ public static final String TASKDEF_PROPERTIES_RESOURCE =
+ "/org/apache/tools/ant/taskdefs/defaults.properties";
+
+ /**
+ * name of the resource that typedefs are stored under.
+ * Value: {@value}
+ */
+ public static final String TYPEDEFS_PROPERTIES_RESOURCE =
+ "/org/apache/tools/ant/types/defaults.properties";
+
+ /**
+ * Reference to the current Ant executor.
+ * Value: {@value}
+ */
+ public static final String ANT_EXECUTOR_REFERENCE = "ant.executor";
+
+ /**
+ * Property defining the classname of an executor.
+ * Value: {@value}
+ */
+ public static final String ANT_EXECUTOR_CLASSNAME = "ant.executor.class";
+
+ /**
+ * property name for basedir of the project.
+ * Value: {@value}
+ */
+ public static final String PROJECT_BASEDIR = "basedir";
+
+ /**
+ * property for ant file name.
+ * Value: {@value}
+ */
+ public static final String ANT_FILE = "ant.file";
+
+ /**
+ * property for type of ant build file (either file or url)
+ * Value: {@value}
+ * @since Ant 1.8.0
+ */
+ public static final String ANT_FILE_TYPE = "ant.file.type";
+
+ /**
+ * ant build file of type file
+ * Value: {@value}
+ * @since Ant 1.8.0
+ */
+ public static final String ANT_FILE_TYPE_FILE = "file";
+
+ /**
+ * ant build file of type url
+ * Value: {@value}
+ * @since Ant 1.8.0
+ */
+ public static final String ANT_FILE_TYPE_URL = "url";
+
+ /**
+ * Property used to store the java version ant is running in.
+ * Value: {@value}
+ * @since Ant 1.7
+ */
+ public static final String ANT_JAVA_VERSION = "ant.java.version";
+
+ /**
+ * Property used to store the location of ant.
+ * Value: {@value}
+ * @since Ant 1.7
+ */
+ public static final String ANT_HOME = Launcher.ANTHOME_PROPERTY;
+
+ /**
+ * Property used to store the location of the ant library (typically the ant.jar file.)
+ * Value: {@value}
+ * @since Ant 1.7
+ */
+ public static final String ANT_LIB = "ant.core.lib";
+
+ /**
+ * property for regular expression implementation.
+ * Value: {@value}
+ */
+ public static final String REGEXP_IMPL = "ant.regexp.regexpimpl";
+
+ /**
+ * property that provides the default value for javac's and
+ * javadoc's source attribute.
+ * Value: {@value}
+ * @since Ant 1.7
+ */
+ public static final String BUILD_JAVAC_SOURCE = "ant.build.javac.source";
+
+ /**
+ * property that provides the default value for javac's target attribute.
+ * Value: {@value}
+ * @since Ant 1.7
+ */
+ public static final String BUILD_JAVAC_TARGET = "ant.build.javac.target";
+
+ /**
+ * Name of the magic property that controls classloader reuse.
+ * Value: {@value}
+ * @since Ant 1.4.
+ */
+ public static final String REFID_CLASSPATH_REUSE_LOADER = "ant.reuse.loader";
+
+ /**
+ * Prefix used to store classloader references.
+ * Value: {@value}
+ */
+ public static final String REFID_CLASSPATH_LOADER_PREFIX = "ant.loader.";
+
+ /**
+ * Reference used to store the property helper.
+ * Value: {@value}
+ */
+ public static final String REFID_PROPERTY_HELPER = "ant.PropertyHelper";
+
+ /**
+ * Reference used to store the local properties.
+ * Value: {@value}
+ */
+ public static final String REFID_LOCAL_PROPERTIES = "ant.LocalProperties";
+
+ /**
+ * Name of JVM system property which provides the name of the ProjectHelper class to use.
+ * Value: {@value}
+ */
+ public static final String PROJECT_HELPER_CLASS = "org.apache.tools.ant.ProjectHelper";
+
+ /**
+ * The service identifier in jars which provide ProjectHelper implementations.
+ * Value: {@value}
+ */
+ public static final String PROJECT_HELPER_SERVICE =
+ "META-INF/services/org.apache.tools.ant.ProjectHelper";
+
+ /**
+ * Name of ProjectHelper reference that we add to a project.
+ * Value: {@value}
+ */
+ public static final String REFID_PROJECT_HELPER = "ant.projectHelper";
+
+ /**
+ * Name of the property holding the name of the currently
+ * executing project, if one has been specified.
+ *
+ * Value: {@value}
+ * @since Ant 1.8.0
+ */
+ public static final String PROJECT_NAME = "ant.project.name";
+
+ /**
+ * Name of the property holding the default target of the
+ * currently executing project, if one has been specified.
+ *
+ * Value: {@value}
+ * @since Ant 1.8.0
+ */
+ public static final String PROJECT_DEFAULT_TARGET
+ = "ant.project.default-target";
+
+ /**
+ * Name of the property holding a comma separated list of targets
+ * that have been invoked (from the command line).
+ *
+ * Value: {@value}
+ * @since Ant 1.8.0
+ */
+ public static final String PROJECT_INVOKED_TARGETS
+ = "ant.project.invoked-targets";
+
+ /**
+ * Name of the project reference holding an instance of {@link
+ * org.apache.tools.ant.taskdefs.launcher.CommandLauncher} to use
+ * when executing commands with the help of an external skript.
+ *
+ * <p>Alternatively this is the name of a system property holding
+ * the fully qualified class name of a {@link
+ * org.apache.tools.ant.taskdefs.launcher.CommandLauncher}.</p>
+ *
+ * Value: {@value}
+ * @since Ant 1.9.0
+ */
+ public static final String ANT_SHELL_LAUNCHER_REF_ID = "ant.shellLauncher";
+
+ /**
+ * Name of the project reference holding an instance of {@link
+ * org.apache.tools.ant.taskdefs.launcher.CommandLauncher} to use
+ * when executing commands without the help of an external skript.
+ *
+ * <p>Alternatively this is the name of a system property holding
+ * the fully qualified class name of a {@link
+ * org.apache.tools.ant.taskdefs.launcher.CommandLauncher}.</p>
+ *
+ * Value: {@value}
+ * @since Ant 1.9.0
+ */
+ public static final String ANT_VM_LAUNCHER_REF_ID = "ant.vmLauncher";
+ /**
+ * Name of the namespace "type".
+ * (Note: cannot be used as an element.)
+ * @since Ant 1.9.1
+ */
+ public static final String ATTRIBUTE_NAMESPACE = "attribute namespace";
+
+ /**
+ * Name of the property which can provide an override of the
+ * User-Agent used in &lt;get&gt; tasks.
+ * Value {@value}
+ */
+ public static final String HTTP_AGENT_PROPERTY = "ant.http.agent";
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/Main.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/Main.java
new file mode 100644
index 00000000..a9c23a53
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/Main.java
@@ -0,0 +1,1317 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Properties;
+import java.util.Set;
+import java.util.Vector;
+
+import org.apache.tools.ant.input.DefaultInputHandler;
+import org.apache.tools.ant.input.InputHandler;
+import org.apache.tools.ant.launch.AntMain;
+import org.apache.tools.ant.listener.SilentLogger;
+import org.apache.tools.ant.property.GetProperty;
+import org.apache.tools.ant.property.ResolvePropertyMap;
+import org.apache.tools.ant.util.ClasspathUtils;
+import org.apache.tools.ant.util.FileUtils;
+import org.apache.tools.ant.util.ProxySetup;
+
+
+/**
+ * Command line entry point into Ant. This class is entered via the
+ * canonical `public static void main` entry point and reads the
+ * command line arguments. It then assembles and executes an Ant
+ * project.
+ * <p>
+ * If you integrating Ant into some other tool, this is not the class
+ * to use as an entry point. Please see the source code of this
+ * class to see how it manipulates the Ant project classes.
+ *
+ */
+public class Main implements AntMain {
+
+ /**
+ * A Set of args that are handled by the launcher and should
+ * not be seen by Main.
+ */
+ private static final Set<String> LAUNCH_COMMANDS = Collections
+ .unmodifiableSet(new HashSet<String>(Arrays.asList("-lib", "-cp", "-noclasspath",
+ "--noclasspath", "-nouserlib", "-main")));
+
+ /** The default build file name. {@value} */
+ public static final String DEFAULT_BUILD_FILENAME = "build.xml";
+
+ /** Our current message output status. Follows Project.MSG_XXX. */
+ private int msgOutputLevel = Project.MSG_INFO;
+
+ /** File that we are using for configuration. */
+ private File buildFile; /* null */
+
+ /** Stream to use for logging. */
+ private static PrintStream out = System.out;
+
+ /** Stream that we are using for logging error messages. */
+ private static PrintStream err = System.err;
+
+ /** The build targets. */
+ private final Vector<String> targets = new Vector<String>();
+
+ /** Set of properties that can be used by tasks. */
+ private final Properties definedProps = new Properties();
+
+ /** Names of classes to add as listeners to project. */
+ private final Vector<String> listeners = new Vector<String>(1);
+
+ /** File names of property files to load on startup. */
+ private final Vector<String> propertyFiles = new Vector<String>(1);
+
+ /** Indicates whether this build is to support interactive input */
+ private boolean allowInput = true;
+
+ /** keep going mode */
+ private boolean keepGoingMode = false;
+
+ /**
+ * The Ant logger class. There may be only one logger. It will have
+ * the right to use the 'out' PrintStream. The class must implements the
+ * BuildLogger interface.
+ */
+ private String loggerClassname = null;
+
+ /**
+ * The Ant InputHandler class. There may be only one input
+ * handler.
+ */
+ private String inputHandlerClassname = null;
+
+ /**
+ * Whether or not output to the log is to be unadorned.
+ */
+ private boolean emacsMode = false;
+
+ /**
+ * Whether or not log output should be reduced to the minimum
+ */
+ private boolean silent = false;
+
+ /**
+ * Whether or not this instance has successfully been
+ * constructed and is ready to run.
+ */
+ private boolean readyToRun = false;
+
+ /**
+ * Whether or not we should only parse and display the project help
+ * information.
+ */
+ private boolean projectHelp = false;
+
+ /**
+ * Whether or not a logfile is being used. This is used to
+ * check if the output streams must be closed.
+ */
+ private static boolean isLogFileUsed = false;
+
+ /**
+ * optional thread priority
+ */
+ private Integer threadPriority = null;
+
+ /**
+ * proxy flag: default is false
+ */
+ private boolean proxy = false;
+
+ private final Map<Class<?>, List<String>> extraArguments = new HashMap<Class<?>, List<String>>();
+
+ private static final GetProperty NOPROPERTIES = new GetProperty() {
+ public Object getProperty(final String aName) {
+ // No existing property takes precedence
+ return null;
+ }
+ };
+
+
+
+
+ /**
+ * Prints the message of the Throwable if it (the message) is not
+ * <code>null</code>.
+ *
+ * @param t Throwable to print the message of.
+ * Must not be <code>null</code>.
+ */
+ private static void printMessage(final Throwable t) {
+ final String message = t.getMessage();
+ if (message != null) {
+ System.err.println(message);
+ }
+ }
+
+ /**
+ * Creates a new instance of this class using the
+ * arguments specified, gives it any extra user properties which have been
+ * specified, and then runs the build using the classloader provided.
+ *
+ * @param args Command line arguments. Must not be <code>null</code>.
+ * @param additionalUserProperties Any extra properties to use in this
+ * build. May be <code>null</code>, which is the equivalent to
+ * passing in an empty set of properties.
+ * @param coreLoader Classloader used for core classes. May be
+ * <code>null</code> in which case the system classloader is used.
+ */
+ public static void start(final String[] args, final Properties additionalUserProperties,
+ final ClassLoader coreLoader) {
+ final Main m = new Main();
+ m.startAnt(args, additionalUserProperties, coreLoader);
+ }
+
+ /**
+ * Start Ant
+ * @param args command line args
+ * @param additionalUserProperties properties to set beyond those that
+ * may be specified on the args list
+ * @param coreLoader - not used
+ *
+ * @since Ant 1.6
+ */
+ public void startAnt(final String[] args, final Properties additionalUserProperties,
+ final ClassLoader coreLoader) {
+
+ try {
+ processArgs(args);
+ } catch (final Throwable exc) {
+ handleLogfile();
+ printMessage(exc);
+ exit(1);
+ return;
+ }
+
+ if (additionalUserProperties != null) {
+ for (final Enumeration<?> e = additionalUserProperties.keys();
+ e.hasMoreElements();) {
+ final String key = (String) e.nextElement();
+ final String property = additionalUserProperties.getProperty(key);
+ definedProps.put(key, property);
+ }
+ }
+
+ // expect the worst
+ int exitCode = 1;
+ try {
+ try {
+ runBuild(coreLoader);
+ exitCode = 0;
+ } catch (final ExitStatusException ese) {
+ exitCode = ese.getStatus();
+ if (exitCode != 0) {
+ throw ese;
+ }
+ }
+ } catch (final BuildException be) {
+ if (err != System.err) {
+ printMessage(be);
+ }
+ } catch (final Throwable exc) {
+ exc.printStackTrace();
+ printMessage(exc);
+ } finally {
+ handleLogfile();
+ }
+ exit(exitCode);
+ }
+
+ /**
+ * This operation is expected to call {@link System#exit(int)}, which
+ * is what the base version does.
+ * However, it is possible to do something else.
+ * @param exitCode code to exit with
+ */
+ protected void exit(final int exitCode) {
+ System.exit(exitCode);
+ }
+
+ /**
+ * Close logfiles, if we have been writing to them.
+ *
+ * @since Ant 1.6
+ */
+ private static void handleLogfile() {
+ if (isLogFileUsed) {
+ FileUtils.close(out);
+ FileUtils.close(err);
+ }
+ }
+
+ /**
+ * Command line entry point. This method kicks off the building
+ * of a project object and executes a build using either a given
+ * target or the default target.
+ *
+ * @param args Command line arguments. Must not be <code>null</code>.
+ */
+ public static void main(final String[] args) {
+ start(args, null, null);
+ }
+
+ /**
+ * Constructor used when creating Main for later arg processing
+ * and startup
+ */
+ public Main() {
+ }
+
+ /**
+ * Sole constructor, which parses and deals with command line
+ * arguments.
+ *
+ * @param args Command line arguments. Must not be <code>null</code>.
+ *
+ * @exception BuildException if the specified build file doesn't exist
+ * or is a directory.
+ *
+ * @deprecated since 1.6.x
+ */
+ @Deprecated
+ protected Main(final String[] args) throws BuildException {
+ processArgs(args);
+ }
+
+ /**
+ * Process command line arguments.
+ * When ant is started from Launcher, launcher-only arguments do not get
+ * passed through to this routine.
+ *
+ * @param args the command line arguments.
+ *
+ * @since Ant 1.6
+ */
+ private void processArgs(final String[] args) {
+ String searchForThis = null;
+ boolean searchForFile = false;
+ PrintStream logTo = null;
+
+ // cycle through given args
+
+ boolean justPrintUsage = false;
+ boolean justPrintVersion = false;
+ boolean justPrintDiagnostics = false;
+
+ final ArgumentProcessorRegistry processorRegistry = ArgumentProcessorRegistry.getInstance();
+
+ for (int i = 0; i < args.length; i++) {
+ final String arg = args[i];
+
+ if (arg.equals("-help") || arg.equals("-h")) {
+ justPrintUsage = true;
+ } else if (arg.equals("-version")) {
+ justPrintVersion = true;
+ } else if (arg.equals("-diagnostics")) {
+ justPrintDiagnostics = true;
+ } else if (arg.equals("-quiet") || arg.equals("-q")) {
+ msgOutputLevel = Project.MSG_WARN;
+ } else if (arg.equals("-verbose") || arg.equals("-v")) {
+ msgOutputLevel = Project.MSG_VERBOSE;
+ } else if (arg.equals("-debug") || arg.equals("-d")) {
+ msgOutputLevel = Project.MSG_DEBUG;
+ } else if (arg.equals("-silent") || arg.equals("-S")) {
+ silent = true;
+ } else if (arg.equals("-noinput")) {
+ allowInput = false;
+ } else if (arg.equals("-logfile") || arg.equals("-l")) {
+ try {
+ final File logFile = new File(args[i + 1]);
+ i++;
+ logTo = new PrintStream(new FileOutputStream(logFile));
+ isLogFileUsed = true;
+ } catch (final IOException ioe) {
+ final String msg = "Cannot write on the specified log file. "
+ + "Make sure the path exists and you have write "
+ + "permissions.";
+ throw new BuildException(msg);
+ } catch (final ArrayIndexOutOfBoundsException aioobe) {
+ final String msg = "You must specify a log file when "
+ + "using the -log argument";
+ throw new BuildException(msg);
+ }
+ } else if (arg.equals("-buildfile") || arg.equals("-file")
+ || arg.equals("-f")) {
+ i = handleArgBuildFile(args, i);
+ } else if (arg.equals("-listener")) {
+ i = handleArgListener(args, i);
+ } else if (arg.startsWith("-D")) {
+ i = handleArgDefine(args, i);
+ } else if (arg.equals("-logger")) {
+ i = handleArgLogger(args, i);
+ } else if (arg.equals("-inputhandler")) {
+ i = handleArgInputHandler(args, i);
+ } else if (arg.equals("-emacs") || arg.equals("-e")) {
+ emacsMode = true;
+ } else if (arg.equals("-projecthelp") || arg.equals("-p")) {
+ // set the flag to display the targets and quit
+ projectHelp = true;
+ } else if (arg.equals("-find") || arg.equals("-s")) {
+ searchForFile = true;
+ // eat up next arg if present, default to build.xml
+ if (i < args.length - 1) {
+ searchForThis = args[++i];
+ }
+ } else if (arg.startsWith("-propertyfile")) {
+ i = handleArgPropertyFile(args, i);
+ } else if (arg.equals("-k") || arg.equals("-keep-going")) {
+ keepGoingMode = true;
+ } else if (arg.equals("-nice")) {
+ i = handleArgNice(args, i);
+ } else if (LAUNCH_COMMANDS.contains(arg)) {
+ //catch script/ant mismatch with a meaningful message
+ //we could ignore it, but there are likely to be other
+ //version problems, so we stamp down on the configuration now
+ final String msg = "Ant's Main method is being handed "
+ + "an option " + arg + " that is only for the launcher class."
+ + "\nThis can be caused by a version mismatch between "
+ + "the ant script/.bat file and Ant itself.";
+ throw new BuildException(msg);
+ } else if (arg.equals("-autoproxy")) {
+ proxy = true;
+ } else if (arg.startsWith("-")) {
+ boolean processed = false;
+ for (final ArgumentProcessor processor : processorRegistry.getProcessors()) {
+ final int newI = processor.readArguments(args, i);
+ if (newI != -1) {
+ List<String> extraArgs = extraArguments.get(processor.getClass());
+ if (extraArgs == null) {
+ extraArgs = new ArrayList<String>();
+ extraArguments.put(processor.getClass(), extraArgs);
+ }
+ for (; i < newI && i < args.length; i++) {
+ extraArgs.add(args[i]);
+ }
+ processed = true;
+ break;
+ }
+ }
+ if (!processed) {
+ // we don't have any more args to recognize!
+ final String msg = "Unknown argument: " + arg;
+ System.err.println(msg);
+ printUsage();
+ throw new BuildException("");
+ }
+ } else {
+ // if it's no other arg, it may be the target
+ targets.addElement(arg);
+ }
+ }
+
+ if (msgOutputLevel >= Project.MSG_VERBOSE || justPrintVersion) {
+ printVersion(msgOutputLevel);
+ }
+
+ if (justPrintUsage || justPrintVersion || justPrintDiagnostics) {
+ if (justPrintUsage) {
+ printUsage();
+ }
+ if (justPrintDiagnostics) {
+ Diagnostics.doReport(System.out, msgOutputLevel);
+ }
+ return;
+ }
+
+ // if buildFile was not specified on the command line,
+ if (buildFile == null) {
+ // but -find then search for it
+ if (searchForFile) {
+ if (searchForThis != null) {
+ buildFile = findBuildFile(System.getProperty("user.dir"), searchForThis);
+ if (buildFile == null) {
+ throw new BuildException("Could not locate a build file!");
+ }
+ } else {
+ // no search file specified: so search an existing default file
+ final Iterator<ProjectHelper> it = ProjectHelperRepository.getInstance().getHelpers();
+ do {
+ final ProjectHelper helper = it.next();
+ searchForThis = helper.getDefaultBuildFile();
+ if (msgOutputLevel >= Project.MSG_VERBOSE) {
+ System.out.println("Searching the default build file: " + searchForThis);
+ }
+ buildFile = findBuildFile(System.getProperty("user.dir"), searchForThis);
+ } while (buildFile == null && it.hasNext());
+ if (buildFile == null) {
+ throw new BuildException("Could not locate a build file!");
+ }
+ }
+ } else {
+ // no build file specified: so search an existing default file
+ final Iterator<ProjectHelper> it = ProjectHelperRepository.getInstance().getHelpers();
+ do {
+ final ProjectHelper helper = it.next();
+ buildFile = new File(helper.getDefaultBuildFile());
+ if (msgOutputLevel >= Project.MSG_VERBOSE) {
+ System.out.println("Trying the default build file: " + buildFile);
+ }
+ } while (!buildFile.exists() && it.hasNext());
+ }
+ }
+
+ // make sure buildfile exists
+ if (!buildFile.exists()) {
+ System.out.println("Buildfile: " + buildFile + " does not exist!");
+ throw new BuildException("Build failed");
+ }
+
+ if (buildFile.isDirectory()) {
+ final File whatYouMeant = new File(buildFile, "build.xml");
+ if (whatYouMeant.isFile()) {
+ buildFile = whatYouMeant;
+ } else {
+ System.out.println("What? Buildfile: " + buildFile + " is a dir!");
+ throw new BuildException("Build failed");
+ }
+ }
+
+ // Normalize buildFile for re-import detection
+ buildFile =
+ FileUtils.getFileUtils().normalize(buildFile.getAbsolutePath());
+
+ // Load the property files specified by -propertyfile
+ loadPropertyFiles();
+
+ if (msgOutputLevel >= Project.MSG_INFO) {
+ System.out.println("Buildfile: " + buildFile);
+ }
+
+ if (logTo != null) {
+ out = logTo;
+ err = logTo;
+ System.setOut(out);
+ System.setErr(err);
+ }
+ readyToRun = true;
+ }
+
+ // --------------------------------------------------------
+ // Methods for handling the command line arguments
+ // --------------------------------------------------------
+
+ /** Handle the -buildfile, -file, -f argument */
+ private int handleArgBuildFile(final String[] args, int pos) {
+ try {
+ buildFile = new File(
+ args[++pos].replace('/', File.separatorChar));
+ } catch (final ArrayIndexOutOfBoundsException aioobe) {
+ throw new BuildException(
+ "You must specify a buildfile when using the -buildfile argument");
+ }
+ return pos;
+ }
+
+ /** Handle -listener argument */
+ private int handleArgListener(final String[] args, int pos) {
+ try {
+ listeners.addElement(args[pos + 1]);
+ pos++;
+ } catch (final ArrayIndexOutOfBoundsException aioobe) {
+ final String msg = "You must specify a classname when "
+ + "using the -listener argument";
+ throw new BuildException(msg);
+ }
+ return pos;
+ }
+
+ /** Handler -D argument */
+ private int handleArgDefine(final String[] args, int argPos) {
+ /* Interestingly enough, we get to here when a user
+ * uses -Dname=value. However, in some cases, the OS
+ * goes ahead and parses this out to args
+ * {"-Dname", "value"}
+ * so instead of parsing on "=", we just make the "-D"
+ * characters go away and skip one argument forward.
+ *
+ * I don't know how to predict when the JDK is going
+ * to help or not, so we simply look for the equals sign.
+ */
+ final String arg = args[argPos];
+ String name = arg.substring(2, arg.length());
+ String value = null;
+ final int posEq = name.indexOf("=");
+ if (posEq > 0) {
+ value = name.substring(posEq + 1);
+ name = name.substring(0, posEq);
+ } else if (argPos < args.length - 1) {
+ value = args[++argPos];
+ } else {
+ throw new BuildException("Missing value for property "
+ + name);
+ }
+ definedProps.put(name, value);
+ return argPos;
+ }
+
+ /** Handle the -logger argument. */
+ private int handleArgLogger(final String[] args, int pos) {
+ if (loggerClassname != null) {
+ throw new BuildException(
+ "Only one logger class may be specified.");
+ }
+ try {
+ loggerClassname = args[++pos];
+ } catch (final ArrayIndexOutOfBoundsException aioobe) {
+ throw new BuildException(
+ "You must specify a classname when using the -logger argument");
+ }
+ return pos;
+ }
+
+ /** Handle the -inputhandler argument. */
+ private int handleArgInputHandler(final String[] args, int pos) {
+ if (inputHandlerClassname != null) {
+ throw new BuildException("Only one input handler class may "
+ + "be specified.");
+ }
+ try {
+ inputHandlerClassname = args[++pos];
+ } catch (final ArrayIndexOutOfBoundsException aioobe) {
+ throw new BuildException("You must specify a classname when"
+ + " using the -inputhandler"
+ + " argument");
+ }
+ return pos;
+ }
+
+ /** Handle the -propertyfile argument. */
+ private int handleArgPropertyFile(final String[] args, int pos) {
+ try {
+ propertyFiles.addElement(args[++pos]);
+ } catch (final ArrayIndexOutOfBoundsException aioobe) {
+ final String msg = "You must specify a property filename when "
+ + "using the -propertyfile argument";
+ throw new BuildException(msg);
+ }
+ return pos;
+ }
+
+ /** Handle the -nice argument. */
+ private int handleArgNice(final String[] args, int pos) {
+ try {
+ threadPriority = Integer.decode(args[++pos]);
+ } catch (final ArrayIndexOutOfBoundsException aioobe) {
+ throw new BuildException(
+ "You must supply a niceness value (1-10)"
+ + " after the -nice option");
+ } catch (final NumberFormatException e) {
+ throw new BuildException("Unrecognized niceness value: "
+ + args[pos]);
+ }
+
+ if (threadPriority.intValue() < Thread.MIN_PRIORITY
+ || threadPriority.intValue() > Thread.MAX_PRIORITY) {
+ throw new BuildException(
+ "Niceness value is out of the range 1-10");
+ }
+ return pos;
+ }
+
+ // --------------------------------------------------------
+ // other methods
+ // --------------------------------------------------------
+
+ /** Load the property files specified by -propertyfile */
+ private void loadPropertyFiles() {
+ for (final String filename : propertyFiles) {
+ final Properties props = new Properties();
+ FileInputStream fis = null;
+ try {
+ fis = new FileInputStream(filename);
+ props.load(fis);
+ } catch (final IOException e) {
+ System.out.println("Could not load property file "
+ + filename + ": " + e.getMessage());
+ } finally {
+ FileUtils.close(fis);
+ }
+
+ // ensure that -D properties take precedence
+ final Enumeration<?> propertyNames = props.propertyNames();
+ while (propertyNames.hasMoreElements()) {
+ final String name = (String) propertyNames.nextElement();
+ if (definedProps.getProperty(name) == null) {
+ definedProps.put(name, props.getProperty(name));
+ }
+ }
+ }
+ }
+
+ /**
+ * Helper to get the parent file for a given file.
+ * <p>
+ * Added to simulate File.getParentFile() from JDK 1.2.
+ * @deprecated since 1.6.x
+ *
+ * @param file File to find parent of. Must not be <code>null</code>.
+ * @return Parent file or null if none
+ */
+ @Deprecated
+ private File getParentFile(final File file) {
+ final File parent = file.getParentFile();
+
+ if (parent != null && msgOutputLevel >= Project.MSG_VERBOSE) {
+ System.out.println("Searching in " + parent.getAbsolutePath());
+ }
+
+ return parent;
+ }
+
+ /**
+ * Search parent directories for the build file.
+ * <p>
+ * Takes the given target as a suffix to append to each
+ * parent directory in search of a build file. Once the
+ * root of the file-system has been reached <code>null</code>
+ * is returned.
+ *
+ * @param start Leaf directory of search.
+ * Must not be <code>null</code>.
+ * @param suffix Suffix filename to look for in parents.
+ * Must not be <code>null</code>.
+ *
+ * @return A handle to the build file if one is found, <code>null</code> if not
+ */
+ private File findBuildFile(final String start, final String suffix) {
+ if (msgOutputLevel >= Project.MSG_INFO) {
+ System.out.println("Searching for " + suffix + " ...");
+ }
+
+ File parent = new File(new File(start).getAbsolutePath());
+ File file = new File(parent, suffix);
+
+ // check if the target file exists in the current directory
+ while (!file.exists()) {
+ // change to parent directory
+ parent = getParentFile(parent);
+
+ // if parent is null, then we are at the root of the fs,
+ // complain that we can't find the build file.
+ if (parent == null) {
+ return null;
+ }
+
+ // refresh our file handle
+ file = new File(parent, suffix);
+ }
+
+ return file;
+ }
+
+ /**
+ * Executes the build. If the constructor for this instance failed
+ * (e.g. returned after issuing a warning), this method returns
+ * immediately.
+ *
+ * @param coreLoader The classloader to use to find core classes.
+ * May be <code>null</code>, in which case the
+ * system classloader is used.
+ *
+ * @exception BuildException if the build fails
+ */
+ private void runBuild(final ClassLoader coreLoader) throws BuildException {
+
+ if (!readyToRun) {
+ return;
+ }
+
+ final ArgumentProcessorRegistry processorRegistry = ArgumentProcessorRegistry.getInstance();
+
+ for (final ArgumentProcessor processor : processorRegistry.getProcessors()) {
+ final List<String> extraArgs = extraArguments.get(processor.getClass());
+ if (extraArgs != null) {
+ if (processor.handleArg(extraArgs)) {
+ return;
+ }
+ }
+ }
+
+ final Project project = new Project();
+ project.setCoreLoader(coreLoader);
+
+ Throwable error = null;
+
+ try {
+ addBuildListeners(project);
+ addInputHandler(project);
+
+ final PrintStream savedErr = System.err;
+ final PrintStream savedOut = System.out;
+ final InputStream savedIn = System.in;
+
+ // use a system manager that prevents from System.exit()
+ SecurityManager oldsm = null;
+ oldsm = System.getSecurityManager();
+
+ //SecurityManager can not be installed here for backwards
+ //compatibility reasons (PD). Needs to be loaded prior to
+ //ant class if we are going to implement it.
+ //System.setSecurityManager(new NoExitSecurityManager());
+ try {
+ if (allowInput) {
+ project.setDefaultInputStream(System.in);
+ }
+ System.setIn(new DemuxInputStream(project));
+ System.setOut(new PrintStream(new DemuxOutputStream(project, false)));
+ System.setErr(new PrintStream(new DemuxOutputStream(project, true)));
+
+
+ if (!projectHelp) {
+ project.fireBuildStarted();
+ }
+
+ // set the thread priorities
+ if (threadPriority != null) {
+ try {
+ project.log("Setting Ant's thread priority to "
+ + threadPriority, Project.MSG_VERBOSE);
+ Thread.currentThread().setPriority(threadPriority.intValue());
+ } catch (final SecurityException swallowed) {
+ //we cannot set the priority here.
+ project.log("A security manager refused to set the -nice value");
+ }
+ }
+
+ setProperties(project);
+
+ project.setKeepGoingMode(keepGoingMode);
+ if (proxy) {
+ //proxy setup if enabled
+ final ProxySetup proxySetup = new ProxySetup(project);
+ proxySetup.enableProxies();
+ }
+
+ for (final ArgumentProcessor processor : processorRegistry.getProcessors()) {
+ final List<String> extraArgs = extraArguments.get(processor.getClass());
+ if (extraArgs != null) {
+ processor.prepareConfigure(project, extraArgs);
+ }
+ }
+
+ ProjectHelper.configureProject(project, buildFile);
+
+ for (final ArgumentProcessor processor : processorRegistry.getProcessors()) {
+ final List<String> extraArgs = extraArguments.get(processor.getClass());
+ if (extraArgs != null) {
+ if (processor.handleArg(project, extraArgs)) {
+ return;
+ }
+ }
+ }
+
+ if (projectHelp) {
+ printDescription(project);
+ printTargets(project, msgOutputLevel > Project.MSG_INFO,
+ msgOutputLevel > Project.MSG_VERBOSE);
+ return;
+ }
+
+ // make sure that we have a target to execute
+ if (targets.size() == 0) {
+ if (project.getDefaultTarget() != null) {
+ targets.addElement(project.getDefaultTarget());
+ }
+ }
+
+ project.executeTargets(targets);
+ } finally {
+ // put back the original security manager
+ //The following will never eval to true. (PD)
+ if (oldsm != null) {
+ System.setSecurityManager(oldsm);
+ }
+
+ System.setOut(savedOut);
+ System.setErr(savedErr);
+ System.setIn(savedIn);
+ }
+ } catch (final RuntimeException exc) {
+ error = exc;
+ throw exc;
+ } catch (final Error e) {
+ error = e;
+ throw e;
+ } finally {
+ if (!projectHelp) {
+ try {
+ project.fireBuildFinished(error);
+ } catch (final Throwable t) {
+ // yes, I know it is bad style to catch Throwable,
+ // but if we don't, we lose valuable information
+ System.err.println("Caught an exception while logging the"
+ + " end of the build. Exception was:");
+ t.printStackTrace();
+ if (error != null) {
+ System.err.println("There has been an error prior to"
+ + " that:");
+ error.printStackTrace();
+ }
+ throw new BuildException(t);
+ }
+ } else if (error != null) {
+ project.log(error.toString(), Project.MSG_ERR);
+ }
+ }
+ }
+
+ private void setProperties(final Project project) {
+
+ project.init();
+
+ // resolve properties
+ final PropertyHelper propertyHelper = PropertyHelper.getPropertyHelper(project);
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ final Map raw = new HashMap(definedProps);
+ @SuppressWarnings("unchecked")
+ final Map<String, Object> props = raw;
+
+ final ResolvePropertyMap resolver = new ResolvePropertyMap(project,
+ NOPROPERTIES, propertyHelper.getExpanders());
+ resolver.resolveAllProperties(props, null, false);
+
+ // set user-define properties
+ for (final Entry<String, Object> ent : props.entrySet()) {
+ final String arg = ent.getKey();
+ final Object value = ent.getValue();
+ project.setUserProperty(arg, String.valueOf(value));
+ }
+
+ project.setUserProperty(MagicNames.ANT_FILE,
+ buildFile.getAbsolutePath());
+ project.setUserProperty(MagicNames.ANT_FILE_TYPE,
+ MagicNames.ANT_FILE_TYPE_FILE);
+ }
+
+ /**
+ * Adds the listeners specified in the command line arguments,
+ * along with the default listener, to the specified project.
+ *
+ * @param project The project to add listeners to.
+ * Must not be <code>null</code>.
+ */
+ protected void addBuildListeners(final Project project) {
+
+ // Add the default listener
+ project.addBuildListener(createLogger());
+
+ final int count = listeners.size();
+ for (int i = 0; i < count; i++) {
+ final String className = listeners.elementAt(i);
+ final BuildListener listener =
+ (BuildListener) ClasspathUtils.newInstance(className,
+ Main.class.getClassLoader(), BuildListener.class);
+ project.setProjectReference(listener);
+
+ project.addBuildListener(listener);
+ }
+ }
+
+ /**
+ * Creates the InputHandler and adds it to the project.
+ *
+ * @param project the project instance.
+ *
+ * @exception BuildException if a specified InputHandler
+ * implementation could not be loaded.
+ */
+ private void addInputHandler(final Project project) throws BuildException {
+ InputHandler handler = null;
+ if (inputHandlerClassname == null) {
+ handler = new DefaultInputHandler();
+ } else {
+ handler = (InputHandler) ClasspathUtils.newInstance(
+ inputHandlerClassname, Main.class.getClassLoader(),
+ InputHandler.class);
+ project.setProjectReference(handler);
+ }
+ project.setInputHandler(handler);
+ }
+
+ // TODO: (Jon Skeet) Any reason for writing a message and then using a bare
+ // RuntimeException rather than just using a BuildException here? Is it
+ // in case the message could end up being written to no loggers (as the
+ // loggers could have failed to be created due to this failure)?
+ /**
+ * Creates the default build logger for sending build events to the ant
+ * log.
+ *
+ * @return the logger instance for this build.
+ */
+ private BuildLogger createLogger() {
+ BuildLogger logger = null;
+ if (silent) {
+ logger = new SilentLogger();
+ msgOutputLevel = Project.MSG_WARN;
+ emacsMode = true;
+ } else if (loggerClassname != null) {
+ try {
+ logger = (BuildLogger) ClasspathUtils.newInstance(
+ loggerClassname, Main.class.getClassLoader(),
+ BuildLogger.class);
+ } catch (final BuildException e) {
+ System.err.println("The specified logger class "
+ + loggerClassname
+ + " could not be used because " + e.getMessage());
+ throw new RuntimeException();
+ }
+ } else {
+ logger = new DefaultLogger();
+ }
+
+ logger.setMessageOutputLevel(msgOutputLevel);
+ logger.setOutputPrintStream(out);
+ logger.setErrorPrintStream(err);
+ logger.setEmacsMode(emacsMode);
+
+ return logger;
+ }
+
+ /**
+ * Prints the usage information for this class to <code>System.out</code>.
+ */
+ private static void printUsage() {
+ System.out.println("ant [options] [target [target2 [target3] ...]]");
+ System.out.println("Options: ");
+ System.out.println(" -help, -h print this message and exit");
+ System.out.println(" -projecthelp, -p print project help information and exit");
+ System.out.println(" -version print the version information and exit");
+ System.out.println(" -diagnostics print information that might be helpful to");
+ System.out.println(" diagnose or report problems and exit");
+ System.out.println(" -quiet, -q be extra quiet");
+ System.out.println(" -silent, -S print nothing but task outputs and build failures");
+ System.out.println(" -verbose, -v be extra verbose");
+ System.out.println(" -debug, -d print debugging information");
+ System.out.println(" -emacs, -e produce logging information without adornments");
+ System.out.println(" -lib <path> specifies a path to search for jars and classes");
+ System.out.println(" -logfile <file> use given file for log");
+ System.out.println(" -l <file> ''");
+ System.out.println(" -logger <classname> the class which is to perform logging");
+ System.out.println(" -listener <classname> add an instance of class as a project listener");
+ System.out.println(" -noinput do not allow interactive input");
+ System.out.println(" -buildfile <file> use given buildfile");
+ System.out.println(" -file <file> ''");
+ System.out.println(" -f <file> ''");
+ System.out.println(" -D<property>=<value> use value for given property");
+ System.out.println(" -keep-going, -k execute all targets that do not depend");
+ System.out.println(" on failed target(s)");
+ System.out.println(" -propertyfile <name> load all properties from file with -D");
+ System.out.println(" properties taking precedence");
+ System.out.println(" -inputhandler <class> the class which will handle input requests");
+ System.out.println(" -find <file> (s)earch for buildfile towards the root of");
+ System.out.println(" -s <file> the filesystem and use it");
+ System.out.println(" -nice number A niceness value for the main thread:"
+ + " 1 (lowest) to 10 (highest); 5 is the default");
+ System.out.println(" -nouserlib Run ant without using the jar files from"
+ + " ${user.home}/.ant/lib");
+ System.out.println(" -noclasspath Run ant without using CLASSPATH");
+ System.out.println(" -autoproxy Java1.5+: use the OS proxy settings");
+ System.out.println(" -main <class> override Ant's normal entry point");
+ for (final ArgumentProcessor processor : ArgumentProcessorRegistry.getInstance().getProcessors()) {
+ processor.printUsage(System.out);
+ }
+ }
+
+ /**
+ * Prints the Ant version information to <code>System.out</code>.
+ *
+ * @exception BuildException if the version information is unavailable
+ */
+ private static void printVersion(final int logLevel) throws BuildException {
+ System.out.println(getAntVersion());
+ }
+
+ /**
+ * Cache of the Ant version information when it has been loaded.
+ */
+ private static String antVersion = null;
+
+ /**
+ * Cache of the short Ant version information when it has been loaded.
+ */
+ private static String shortAntVersion = null;
+
+ /**
+ * Returns the Ant version information, if available. Once the information
+ * has been loaded once, it's cached and returned from the cache on future
+ * calls.
+ *
+ * @return the Ant version information as a String
+ * (always non-<code>null</code>)
+ *
+ * @exception BuildException if the version information is unavailable
+ */
+ public static synchronized String getAntVersion() throws BuildException {
+ if (antVersion == null) {
+ try {
+ final Properties props = new Properties();
+ final InputStream in =
+ Main.class.getResourceAsStream("/org/apache/tools/ant/version.txt");
+ props.load(in);
+ in.close();
+ shortAntVersion = props.getProperty("VERSION");
+
+ final StringBuffer msg = new StringBuffer();
+ msg.append("Apache Ant(TM) version ");
+ msg.append(shortAntVersion);
+ msg.append(" compiled on ");
+ msg.append(props.getProperty("DATE"));
+ antVersion = msg.toString();
+ } catch (final IOException ioe) {
+ throw new BuildException("Could not load the version information:"
+ + ioe.getMessage());
+ } catch (final NullPointerException npe) {
+ throw new BuildException("Could not load the version information.");
+ }
+ }
+ return antVersion;
+ }
+
+ /**
+ * Returns the short Ant version information, if available. Once the information
+ * has been loaded once, it's cached and returned from the cache on future
+ * calls.
+ *
+ * @return the short Ant version information as a String
+ * (always non-<code>null</code>)
+ *
+ * @throws BuildException BuildException if the version information is unavailable
+ * @since Ant 1.9.3
+ */
+ public static String getShortAntVersion() throws BuildException {
+ if (shortAntVersion == null) {
+ getAntVersion();
+ }
+ return shortAntVersion;
+ }
+
+ /**
+ * Prints the description of a project (if there is one) to
+ * <code>System.out</code>.
+ *
+ * @param project The project to display a description of.
+ * Must not be <code>null</code>.
+ */
+ private static void printDescription(final Project project) {
+ if (project.getDescription() != null) {
+ project.log(project.getDescription());
+ }
+ }
+
+ /**
+ * Targets in imported files with a project name
+ * and not overloaded by the main build file will
+ * be in the target map twice. This method
+ * removes the duplicate target.
+ * @param targets the targets to filter.
+ * @return the filtered targets.
+ */
+ private static Map<String, Target> removeDuplicateTargets(final Map<String, Target> targets) {
+ final Map<Location, Target> locationMap = new HashMap<Location, Target>();
+ for (final Entry<String, Target> entry : targets.entrySet()) {
+ final String name = entry.getKey();
+ final Target target = entry.getValue();
+ final Target otherTarget = locationMap.get(target.getLocation());
+ // Place this entry in the location map if
+ // a) location is not in the map
+ // b) location is in map, but its name is longer
+ // (an imported target will have a name. prefix)
+ if (otherTarget == null
+ || otherTarget.getName().length() > name.length()) {
+ locationMap.put(
+ target.getLocation(), target); // Smallest name wins
+ }
+ }
+ final Map<String, Target> ret = new HashMap<String, Target>();
+ for (final Target target : locationMap.values()) {
+ ret.put(target.getName(), target);
+ }
+ return ret;
+ }
+
+ /**
+ * Prints a list of all targets in the specified project to
+ * <code>System.out</code>, optionally including subtargets.
+ *
+ * @param project The project to display a description of.
+ * Must not be <code>null</code>.
+ * @param printSubTargets Whether or not subtarget names should also be
+ * printed.
+ */
+ private static void printTargets(final Project project, boolean printSubTargets,
+ final boolean printDependencies) {
+ // find the target with the longest name
+ int maxLength = 0;
+ final Map<String, Target> ptargets = removeDuplicateTargets(project.getTargets());
+ // split the targets in top-level and sub-targets depending
+ // on the presence of a description
+ final Vector<String> topNames = new Vector<String>();
+ final Vector<String> topDescriptions = new Vector<String>();
+ final Vector<Enumeration<String>> topDependencies = new Vector<Enumeration<String>>();
+ final Vector<String> subNames = new Vector<String>();
+ final Vector<Enumeration<String>> subDependencies = new Vector<Enumeration<String>>();
+
+ for (final Target currentTarget : ptargets.values()) {
+ final String targetName = currentTarget.getName();
+ if (targetName.equals("")) {
+ continue;
+ }
+ final String targetDescription = currentTarget.getDescription();
+ // maintain a sorted list of targets
+ if (targetDescription == null) {
+ final int pos = findTargetPosition(subNames, targetName);
+ subNames.insertElementAt(targetName, pos);
+ if (printDependencies) {
+ subDependencies.insertElementAt(currentTarget.getDependencies(), pos);
+ }
+ } else {
+ final int pos = findTargetPosition(topNames, targetName);
+ topNames.insertElementAt(targetName, pos);
+ topDescriptions.insertElementAt(targetDescription, pos);
+ if (targetName.length() > maxLength) {
+ maxLength = targetName.length();
+ }
+ if (printDependencies) {
+ topDependencies.insertElementAt(currentTarget.getDependencies(), pos);
+ }
+ }
+ }
+
+ printTargets(project, topNames, topDescriptions, topDependencies,
+ "Main targets:", maxLength);
+ //if there were no main targets, we list all subtargets
+ //as it means nothing has a description
+ if (topNames.size() == 0) {
+ printSubTargets = true;
+ }
+ if (printSubTargets) {
+ printTargets(project, subNames, null, subDependencies, "Other targets:", 0);
+ }
+
+ final String defaultTarget = project.getDefaultTarget();
+ if (defaultTarget != null && !"".equals(defaultTarget)) {
+ // shouldn't need to check but...
+ project.log("Default target: " + defaultTarget);
+ }
+ }
+
+ /**
+ * Searches for the correct place to insert a name into a list so as
+ * to keep the list sorted alphabetically.
+ *
+ * @param names The current list of names. Must not be <code>null</code>.
+ * @param name The name to find a place for.
+ * Must not be <code>null</code>.
+ *
+ * @return the correct place in the list for the given name
+ */
+ private static int findTargetPosition(final Vector<String> names, final String name) {
+ final int size = names.size();
+ int res = size;
+ for (int i = 0; i < size && res == size; i++) {
+ if (name.compareTo(names.elementAt(i)) < 0) {
+ res = i;
+ }
+ }
+ return res;
+ }
+
+ /**
+ * Writes a formatted list of target names to <code>System.out</code>
+ * with an optional description.
+ *
+ *
+ * @param project the project instance.
+ * @param names The names to be printed.
+ * Must not be <code>null</code>.
+ * @param descriptions The associated target descriptions.
+ * May be <code>null</code>, in which case
+ * no descriptions are displayed.
+ * If non-<code>null</code>, this should have
+ * as many elements as <code>names</code>.
+ * @param topDependencies The list of dependencies for each target.
+ * The dependencies are listed as a non null
+ * enumeration of String.
+ * @param heading The heading to display.
+ * Should not be <code>null</code>.
+ * @param maxlen The maximum length of the names of the targets.
+ * If descriptions are given, they are padded to this
+ * position so they line up (so long as the names really
+ * <i>are</i> shorter than this).
+ */
+ private static void printTargets(final Project project, final Vector<String> names,
+ final Vector<String> descriptions, final Vector<Enumeration<String>> dependencies,
+ final String heading,
+ final int maxlen) {
+ // now, start printing the targets and their descriptions
+ final String lSep = System.getProperty("line.separator");
+ // got a bit annoyed that I couldn't find a pad function
+ String spaces = " ";
+ while (spaces.length() <= maxlen) {
+ spaces += spaces;
+ }
+ final StringBuilder msg = new StringBuilder();
+ msg.append(heading + lSep + lSep);
+ final int size = names.size();
+ for (int i = 0; i < size; i++) {
+ msg.append(" ");
+ msg.append(names.elementAt(i));
+ if (descriptions != null) {
+ msg.append(
+ spaces.substring(0, maxlen - names.elementAt(i).length() + 2));
+ msg.append(descriptions.elementAt(i));
+ }
+ msg.append(lSep);
+ if (!dependencies.isEmpty()) {
+ final Enumeration<String> deps = dependencies.elementAt(i);
+ if (deps.hasMoreElements()) {
+ msg.append(" depends on: ");
+ while (deps.hasMoreElements()) {
+ msg.append(deps.nextElement());
+ if (deps.hasMoreElements()) {
+ msg.append(", ");
+ }
+ }
+ msg.append(lSep);
+ }
+ }
+ }
+ project.log(msg.toString(), Project.MSG_WARN);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/NoBannerLogger.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/NoBannerLogger.java
new file mode 100644
index 00000000..a086bf5e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/NoBannerLogger.java
@@ -0,0 +1,100 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant;
+
+import org.apache.tools.ant.util.StringUtils;
+
+/**
+ * Extends DefaultLogger to strip out empty targets.
+ *
+ */
+public class NoBannerLogger extends DefaultLogger {
+
+ // CheckStyle:VisibilityModifier OFF - bc
+ /**
+ * Name of the current target, if it should
+ * be displayed on the next message. This is
+ * set when a target starts building, and reset
+ * to <code>null</code> after the first message for
+ * the target is logged.
+ */
+ protected String targetName;
+ // CheckStyle:VisibilityModifier ON
+
+ /** Sole constructor. */
+ public NoBannerLogger() {
+ }
+
+ /**
+ * Notes the name of the target so it can be logged
+ * if it generates any messages.
+ *
+ * @param event A BuildEvent containing target information.
+ * Must not be <code>null</code>.
+ */
+ public synchronized void targetStarted(BuildEvent event) {
+ targetName = extractTargetName(event);
+ }
+
+ /**
+ * Override point, extract the target name
+ * @param event the event to work on
+ * @return the target name to print
+ * @since Ant1.7.1
+ */
+ protected String extractTargetName(BuildEvent event) {
+ return event.getTarget().getName();
+ }
+
+ /**
+ * Resets the current target name to <code>null</code>.
+ *
+ * @param event Ignored in this implementation.
+ */
+ public synchronized void targetFinished(BuildEvent event) {
+ targetName = null;
+ }
+
+ /**
+ * Logs a message for a target if it is of an appropriate
+ * priority, also logging the name of the target if this
+ * is the first message which needs to be logged for the
+ * target.
+ *
+ * @param event A BuildEvent containing message information.
+ * Must not be <code>null</code>.
+ */
+ public void messageLogged(BuildEvent event) {
+
+ if (event.getPriority() > msgOutputLevel
+ || null == event.getMessage()
+ || "".equals(event.getMessage().trim())) {
+ return;
+ }
+
+ synchronized (this) {
+ if (null != targetName) {
+ out.println(StringUtils.LINE_SEP + targetName + ":");
+ targetName = null;
+ }
+ }
+
+ super.messageLogged(event);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/PathTokenizer.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/PathTokenizer.java
new file mode 100644
index 00000000..6e6bea62
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/PathTokenizer.java
@@ -0,0 +1,166 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant;
+
+import java.io.File;
+import java.util.NoSuchElementException;
+import java.util.StringTokenizer;
+
+import org.apache.tools.ant.taskdefs.condition.Os;
+
+/**
+ * A Path tokenizer takes a path and returns the components that make up
+ * that path.
+ *
+ * The path can use path separators of either ':' or ';' and file separators
+ * of either '/' or '\'.
+ *
+ */
+public class PathTokenizer {
+ /**
+ * A tokenizer to break the string up based on the ':' or ';' separators.
+ */
+ private StringTokenizer tokenizer;
+
+ /**
+ * A String which stores any path components which have been read ahead
+ * due to DOS filesystem compensation.
+ */
+ private String lookahead = null;
+
+ /**
+ * A boolean that determines if we are running on Novell NetWare, which
+ * exhibits slightly different path name characteristics (multi-character
+ * volume / drive names)
+ */
+ private boolean onNetWare = Os.isFamily("netware");
+
+ /**
+ * Flag to indicate whether or not we are running on a platform with a
+ * DOS style filesystem
+ */
+ private boolean dosStyleFilesystem;
+
+ /**
+ * Constructs a path tokenizer for the specified path.
+ *
+ * @param path The path to tokenize. Must not be <code>null</code>.
+ */
+ public PathTokenizer(String path) {
+ if (onNetWare) {
+ // For NetWare, use the boolean=true mode, so we can use delimiter
+ // information to make a better decision later.
+ tokenizer = new StringTokenizer(path, ":;", true);
+ } else {
+ // on Windows and Unix, we can ignore delimiters and still have
+ // enough information to tokenize correctly.
+ tokenizer = new StringTokenizer(path, ":;", false);
+ }
+ dosStyleFilesystem = File.pathSeparatorChar == ';';
+ }
+
+ /**
+ * Tests if there are more path elements available from this tokenizer's
+ * path. If this method returns <code>true</code>, then a subsequent call
+ * to nextToken will successfully return a token.
+ *
+ * @return <code>true</code> if and only if there is at least one token
+ * in the string after the current position; <code>false</code> otherwise.
+ */
+ public boolean hasMoreTokens() {
+ if (lookahead != null) {
+ return true;
+ }
+
+ return tokenizer.hasMoreTokens();
+ }
+
+ /**
+ * Returns the next path element from this tokenizer.
+ *
+ * @return the next path element from this tokenizer.
+ *
+ * @exception NoSuchElementException if there are no more elements in this
+ * tokenizer's path.
+ */
+ public String nextToken() throws NoSuchElementException {
+ String token = null;
+ if (lookahead != null) {
+ token = lookahead;
+ lookahead = null;
+ } else {
+ token = tokenizer.nextToken().trim();
+ }
+
+ if (!onNetWare) {
+ if (token.length() == 1 && Character.isLetter(token.charAt(0))
+ && dosStyleFilesystem
+ && tokenizer.hasMoreTokens()) {
+ // we are on a dos style system so this path could be a drive
+ // spec. We look at the next token
+ String nextToken = tokenizer.nextToken().trim();
+ if (nextToken.startsWith("\\") || nextToken.startsWith("/")) {
+ // we know we are on a DOS style platform and the next path
+ // starts with a slash or backslash, so we know this is a
+ // drive spec
+ token += ":" + nextToken;
+ } else {
+ // store the token just read for next time
+ lookahead = nextToken;
+ }
+ }
+ } else {
+ // we are on NetWare, tokenizing is handled a little differently,
+ // due to the fact that NetWare has multiple-character volume names.
+ if (token.equals(File.pathSeparator) || token.equals(":")) {
+ // ignore ";" and get the next token
+ token = tokenizer.nextToken().trim();
+ }
+
+ if (tokenizer.hasMoreTokens()) {
+ // this path could be a drive spec, so look at the next token
+ String nextToken = tokenizer.nextToken().trim();
+
+ // make sure we aren't going to get the path separator next
+ if (!nextToken.equals(File.pathSeparator)) {
+ if (nextToken.equals(":")) {
+ if (!token.startsWith("/") && !token.startsWith("\\")
+ && !token.startsWith(".")
+ && !token.startsWith("..")) {
+ // it indeed is a drive spec, get the next bit
+ String oneMore = tokenizer.nextToken().trim();
+ if (!oneMore.equals(File.pathSeparator)) {
+ token += ":" + oneMore;
+ } else {
+ token += ":";
+ lookahead = oneMore;
+ }
+ }
+ // implicit else: ignore the ':' since we have either a
+ // UNIX or a relative path
+ } else {
+ // store the token just read for next time
+ lookahead = nextToken;
+ }
+ }
+ }
+ }
+ return token;
+ }
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/Project.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/Project.java
new file mode 100644
index 00000000..3a0c4b82
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/Project.java
@@ -0,0 +1,2494 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant;
+
+import java.io.EOFException;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.Stack;
+import java.util.Vector;
+import java.util.WeakHashMap;
+
+import org.apache.tools.ant.helper.DefaultExecutor;
+import org.apache.tools.ant.input.DefaultInputHandler;
+import org.apache.tools.ant.input.InputHandler;
+import org.apache.tools.ant.types.Description;
+import org.apache.tools.ant.types.FilterSet;
+import org.apache.tools.ant.types.FilterSetCollection;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.ResourceFactory;
+import org.apache.tools.ant.types.resources.FileResource;
+import org.apache.tools.ant.util.CollectionUtils;
+import org.apache.tools.ant.util.FileUtils;
+import org.apache.tools.ant.util.JavaEnvUtils;
+import org.apache.tools.ant.util.StringUtils;
+import org.apache.tools.ant.util.VectorSet;
+
+/**
+ * Central representation of an Ant project. This class defines an
+ * Ant project with all of its targets, tasks and various other
+ * properties. It also provides the mechanism to kick off a build using
+ * a particular target name.
+ * <p>
+ * This class also encapsulates methods which allow files to be referred
+ * to using abstract path names which are translated to native system
+ * file paths at runtime.
+ *
+ */
+public class Project implements ResourceFactory {
+ /** Message priority of &quot;error&quot;. */
+ public static final int MSG_ERR = 0;
+ /** Message priority of &quot;warning&quot;. */
+ public static final int MSG_WARN = 1;
+ /** Message priority of &quot;information&quot;. */
+ public static final int MSG_INFO = 2;
+ /** Message priority of &quot;verbose&quot;. */
+ public static final int MSG_VERBOSE = 3;
+ /** Message priority of &quot;debug&quot;. */
+ public static final int MSG_DEBUG = 4;
+
+ /**
+ * Constant for the &quot;visiting&quot; state, used when
+ * traversing a DFS of target dependencies.
+ */
+ private static final String VISITING = "VISITING";
+ /**
+ * Constant for the &quot;visited&quot; state, used when
+ * traversing a DFS of target dependencies.
+ */
+ private static final String VISITED = "VISITED";
+
+ /**
+ * Version constant for Java 1.0 .
+ *
+ * @deprecated since 1.5.x.
+ * Use {@link JavaEnvUtils#JAVA_1_0} instead.
+ */
+ @Deprecated
+ public static final String JAVA_1_0 = JavaEnvUtils.JAVA_1_0;
+ /**
+ * Version constant for Java 1.1 .
+ *
+ * @deprecated since 1.5.x.
+ * Use {@link JavaEnvUtils#JAVA_1_1} instead.
+ */
+ @Deprecated
+ public static final String JAVA_1_1 = JavaEnvUtils.JAVA_1_1;
+ /**
+ * Version constant for Java 1.2 .
+ *
+ * @deprecated since 1.5.x.
+ * Use {@link JavaEnvUtils#JAVA_1_2} instead.
+ */
+ @Deprecated
+ public static final String JAVA_1_2 = JavaEnvUtils.JAVA_1_2;
+ /**
+ * Version constant for Java 1.3 .
+ *
+ * @deprecated since 1.5.x.
+ * Use {@link JavaEnvUtils#JAVA_1_3} instead.
+ */
+ @Deprecated
+ public static final String JAVA_1_3 = JavaEnvUtils.JAVA_1_3;
+ /**
+ * Version constant for Java 1.4 .
+ *
+ * @deprecated since 1.5.x.
+ * Use {@link JavaEnvUtils#JAVA_1_4} instead.
+ */
+ @Deprecated
+ public static final String JAVA_1_4 = JavaEnvUtils.JAVA_1_4;
+
+ /** Default filter start token. */
+ public static final String TOKEN_START = FilterSet.DEFAULT_TOKEN_START;
+ /** Default filter end token. */
+ public static final String TOKEN_END = FilterSet.DEFAULT_TOKEN_END;
+
+ /** Instance of a utility class to use for file operations. */
+ private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+
+ /** Name of this project. */
+ private String name;
+ /** Description for this project (if any). */
+ private String description;
+
+
+ /** Map of references within the project (paths etc) (String to Object). */
+ private final Hashtable<String, Object> references = new AntRefTable();
+
+ /** Map of id references - used for indicating broken build files */
+ private final HashMap<String, Object> idReferences = new HashMap<String, Object>();
+
+ /** Name of the project's default target. */
+ private String defaultTarget;
+
+ /** Map from target names to targets (String to Target). */
+ private final Hashtable<String, Target> targets = new Hashtable<String, Target>();
+
+ /** Set of global filters. */
+ private final FilterSet globalFilterSet = new FilterSet();
+ {
+ // Initialize the globalFileSet's project
+ globalFilterSet.setProject(this);
+ }
+
+ /**
+ * Wrapper around globalFilterSet. This collection only ever
+ * contains one FilterSet, but the wrapper is needed in order to
+ * make it easier to use the FileUtils interface.
+ */
+ private final FilterSetCollection globalFilters
+ = new FilterSetCollection(globalFilterSet);
+
+ /** Project base directory. */
+ private File baseDir;
+
+ /** lock object used when adding/removing listeners */
+ private final Object listenersLock = new Object();
+
+ /** List of listeners to notify of build events. */
+ private volatile BuildListener[] listeners = new BuildListener[0];
+
+ /** for each thread, record whether it is currently executing
+ messageLogged */
+ private final ThreadLocal<Boolean> isLoggingMessage = new ThreadLocal<Boolean>() {
+ @Override
+ protected Boolean initialValue() {
+ return Boolean.FALSE;
+ }
+ };
+
+ /**
+ * The Ant core classloader--may be <code>null</code> if using
+ * parent classloader.
+ */
+ private ClassLoader coreLoader = null;
+
+ /** Records the latest task to be executed on a thread. */
+ private final Map<Thread,Task> threadTasks =
+ Collections.synchronizedMap(new WeakHashMap<Thread, Task>());
+
+ /** Records the latest task to be executed on a thread group. */
+ private final Map<ThreadGroup,Task> threadGroupTasks
+ = Collections.synchronizedMap(new WeakHashMap<ThreadGroup,Task>());
+
+ /**
+ * Called to handle any input requests.
+ */
+ private InputHandler inputHandler = null;
+
+ /**
+ * The default input stream used to read any input.
+ */
+ private InputStream defaultInputStream = null;
+
+ /**
+ * Keep going flag.
+ */
+ private boolean keepGoingMode = false;
+
+ /**
+ * Set the input handler.
+ *
+ * @param handler the InputHandler instance to use for gathering input.
+ */
+ public void setInputHandler(final InputHandler handler) {
+ inputHandler = handler;
+ }
+
+ /**
+ * Set the default System input stream. Normally this stream is set to
+ * System.in. This inputStream is used when no task input redirection is
+ * being performed.
+ *
+ * @param defaultInputStream the default input stream to use when input
+ * is requested.
+ * @since Ant 1.6
+ */
+ public void setDefaultInputStream(final InputStream defaultInputStream) {
+ this.defaultInputStream = defaultInputStream;
+ }
+
+ /**
+ * Get this project's input stream.
+ *
+ * @return the InputStream instance in use by this Project instance to
+ * read input.
+ */
+ public InputStream getDefaultInputStream() {
+ return defaultInputStream;
+ }
+
+ /**
+ * Retrieve the current input handler.
+ *
+ * @return the InputHandler instance currently in place for the project
+ * instance.
+ */
+ public InputHandler getInputHandler() {
+ return inputHandler;
+ }
+
+ /**
+ * Create a new Ant project.
+ */
+ public Project() {
+ inputHandler = new DefaultInputHandler();
+ }
+
+ /**
+ * Create and initialize a subproject. By default the subproject will be of
+ * the same type as its parent. If a no-arg constructor is unavailable, the
+ * <code>Project</code> class will be used.
+ * @return a Project instance configured as a subproject of this Project.
+ * @since Ant 1.7
+ */
+ public Project createSubProject() {
+ Project subProject = null;
+ try {
+ subProject = (getClass().newInstance());
+ } catch (final Exception e) {
+ subProject = new Project();
+ }
+ initSubProject(subProject);
+ return subProject;
+ }
+
+ /**
+ * Initialize a subproject.
+ * @param subProject the subproject to initialize.
+ */
+ public void initSubProject(final Project subProject) {
+ ComponentHelper.getComponentHelper(subProject)
+ .initSubProject(ComponentHelper.getComponentHelper(this));
+ subProject.setDefaultInputStream(getDefaultInputStream());
+ subProject.setKeepGoingMode(this.isKeepGoingMode());
+ subProject.setExecutor(getExecutor().getSubProjectExecutor());
+ }
+
+ /**
+ * Initialise the project.
+ *
+ * This involves setting the default task definitions and loading the
+ * system properties.
+ *
+ * @exception BuildException if the default task list cannot be loaded.
+ */
+ public void init() throws BuildException {
+ initProperties();
+
+ ComponentHelper.getComponentHelper(this).initDefaultDefinitions();
+ }
+
+ /**
+ * Initializes the properties.
+ * @exception BuildException if an vital property could not be set.
+ * @since Ant 1.7
+ */
+ public void initProperties() throws BuildException {
+ setJavaVersionProperty();
+ setSystemProperties();
+ setPropertyInternal(MagicNames.ANT_VERSION, Main.getAntVersion());
+ setAntLib();
+ }
+
+ /**
+ * Set a property to the location of ant.jar.
+ * Use the locator to find the location of the Project.class, and
+ * if this is not null, set the property {@link MagicNames#ANT_LIB}
+ * to the result
+ */
+ private void setAntLib() {
+ final File antlib = org.apache.tools.ant.launch.Locator.getClassSource(
+ Project.class);
+ if (antlib != null) {
+ setPropertyInternal(MagicNames.ANT_LIB, antlib.getAbsolutePath());
+ }
+ }
+ /**
+ * Factory method to create a class loader for loading classes from
+ * a given path.
+ *
+ * @param path the path from which classes are to be loaded.
+ *
+ * @return an appropriate classloader.
+ */
+ public AntClassLoader createClassLoader(final Path path) {
+ return AntClassLoader
+ .newAntClassLoader(getClass().getClassLoader(), this, path, true);
+ }
+
+ /**
+ * Factory method to create a class loader for loading classes from
+ * a given path.
+ *
+ * @param parent the parent classloader for the new loader.
+ * @param path the path from which classes are to be loaded.
+ *
+ * @return an appropriate classloader.
+ */
+ public AntClassLoader createClassLoader(
+ final ClassLoader parent, final Path path) {
+ return AntClassLoader.newAntClassLoader(parent, this, path, true);
+ }
+
+ /**
+ * Set the core classloader for the project. If a <code>null</code>
+ * classloader is specified, the parent classloader should be used.
+ *
+ * @param coreLoader The classloader to use for the project.
+ * May be <code>null</code>.
+ */
+ public void setCoreLoader(final ClassLoader coreLoader) {
+ this.coreLoader = coreLoader;
+ }
+
+ /**
+ * Return the core classloader to use for this project.
+ * This may be <code>null</code>, indicating that
+ * the parent classloader should be used.
+ *
+ * @return the core classloader to use for this project.
+ *
+ */
+ public ClassLoader getCoreLoader() {
+ return coreLoader;
+ }
+
+ /**
+ * Add a build listener to the list. This listener will
+ * be notified of build events for this project.
+ *
+ * @param listener The listener to add to the list.
+ * Must not be <code>null</code>.
+ */
+ public void addBuildListener(final BuildListener listener) {
+ synchronized (listenersLock) {
+ // If the listeners already has this listener, do nothing
+ for (int i = 0; i < listeners.length; i++) {
+ if (listeners[i] == listener) {
+ return;
+ }
+ }
+ // copy on write semantics
+ final BuildListener[] newListeners =
+ new BuildListener[listeners.length + 1];
+ System.arraycopy(listeners, 0, newListeners, 0, listeners.length);
+ newListeners[listeners.length] = listener;
+ listeners = newListeners;
+ }
+ }
+
+ /**
+ * Remove a build listener from the list. This listener
+ * will no longer be notified of build events for this project.
+ *
+ * @param listener The listener to remove from the list.
+ * Should not be <code>null</code>.
+ */
+ public void removeBuildListener(final BuildListener listener) {
+ synchronized (listenersLock) {
+ // copy on write semantics
+ for (int i = 0; i < listeners.length; i++) {
+ if (listeners[i] == listener) {
+ final BuildListener[] newListeners =
+ new BuildListener[listeners.length - 1];
+ System.arraycopy(listeners, 0, newListeners, 0, i);
+ System.arraycopy(listeners, i + 1, newListeners, i,
+ listeners.length - i - 1);
+ listeners = newListeners;
+ break;
+ }
+ }
+ }
+ }
+
+ /**
+ * Return a copy of the list of build listeners for the project.
+ *
+ * @return a list of build listeners for the project
+ */
+ public Vector<BuildListener> getBuildListeners() {
+ synchronized (listenersLock) {
+ final Vector<BuildListener> r = new Vector<BuildListener>(listeners.length);
+ for (int i = 0; i < listeners.length; i++) {
+ r.add(listeners[i]);
+ }
+ return r;
+ }
+ }
+
+ /**
+ * Write a message to the log with the default log level
+ * of MSG_INFO .
+ * @param message The text to log. Should not be <code>null</code>.
+ */
+
+ public void log(final String message) {
+ log(message, MSG_INFO);
+ }
+
+ /**
+ * Write a project level message to the log with the given log level.
+ * @param message The text to log. Should not be <code>null</code>.
+ * @param msgLevel The log priority level to use.
+ */
+ public void log(final String message, final int msgLevel) {
+ log(message, null, msgLevel);
+ }
+
+ /**
+ * Write a project level message to the log with the given log level.
+ * @param message The text to log. Should not be <code>null</code>.
+ * @param throwable The exception causing this log, may be <code>null</code>.
+ * @param msgLevel The log priority level to use.
+ * @since 1.7
+ */
+ public void log(final String message, final Throwable throwable, final int msgLevel) {
+ fireMessageLogged(this, message, throwable, msgLevel);
+ }
+
+ /**
+ * Write a task level message to the log with the given log level.
+ * @param task The task to use in the log. Must not be <code>null</code>.
+ * @param message The text to log. Should not be <code>null</code>.
+ * @param msgLevel The log priority level to use.
+ */
+ public void log(final Task task, final String message, final int msgLevel) {
+ fireMessageLogged(task, message, null, msgLevel);
+ }
+
+ /**
+ * Write a task level message to the log with the given log level.
+ * @param task The task to use in the log. Must not be <code>null</code>.
+ * @param message The text to log. Should not be <code>null</code>.
+ * @param throwable The exception causing this log, may be <code>null</code>.
+ * @param msgLevel The log priority level to use.
+ * @since 1.7
+ */
+ public void log(final Task task, final String message, final Throwable throwable, final int msgLevel) {
+ fireMessageLogged(task, message, throwable, msgLevel);
+ }
+
+ /**
+ * Write a target level message to the log with the given log level.
+ * @param target The target to use in the log.
+ * Must not be <code>null</code>.
+ * @param message The text to log. Should not be <code>null</code>.
+ * @param msgLevel The log priority level to use.
+ */
+ public void log(final Target target, final String message, final int msgLevel) {
+ log(target, message, null, msgLevel);
+ }
+
+ /**
+ * Write a target level message to the log with the given log level.
+ * @param target The target to use in the log.
+ * Must not be <code>null</code>.
+ * @param message The text to log. Should not be <code>null</code>.
+ * @param throwable The exception causing this log, may be <code>null</code>.
+ * @param msgLevel The log priority level to use.
+ * @since 1.7
+ */
+ public void log(final Target target, final String message, final Throwable throwable,
+ final int msgLevel) {
+ fireMessageLogged(target, message, throwable, msgLevel);
+ }
+
+ /**
+ * Return the set of global filters.
+ *
+ * @return the set of global filters.
+ */
+ public FilterSet getGlobalFilterSet() {
+ return globalFilterSet;
+ }
+
+ /**
+ * Set a property. Any existing property of the same name
+ * is overwritten, unless it is a user property.
+ * @param name The name of property to set.
+ * Must not be <code>null</code>.
+ * @param value The new value of the property.
+ * Must not be <code>null</code>.
+ */
+ public void setProperty(final String name, final String value) {
+ PropertyHelper.getPropertyHelper(this).setProperty(name, value, true);
+ }
+
+ /**
+ * Set a property if no value currently exists. If the property
+ * exists already, a message is logged and the method returns with
+ * no other effect.
+ *
+ * @param name The name of property to set.
+ * Must not be <code>null</code>.
+ * @param value The new value of the property.
+ * Must not be <code>null</code>.
+ * @since 1.5
+ */
+ public void setNewProperty(final String name, final String value) {
+ PropertyHelper.getPropertyHelper(this).setNewProperty(name, value);
+ }
+
+ /**
+ * Set a user property, which cannot be overwritten by
+ * set/unset property calls. Any previous value is overwritten.
+ * @param name The name of property to set.
+ * Must not be <code>null</code>.
+ * @param value The new value of the property.
+ * Must not be <code>null</code>.
+ * @see #setProperty(String,String)
+ */
+ public void setUserProperty(final String name, final String value) {
+ PropertyHelper.getPropertyHelper(this).setUserProperty(name, value);
+ }
+
+ /**
+ * Set a user property, which cannot be overwritten by set/unset
+ * property calls. Any previous value is overwritten. Also marks
+ * these properties as properties that have not come from the
+ * command line.
+ *
+ * @param name The name of property to set.
+ * Must not be <code>null</code>.
+ * @param value The new value of the property.
+ * Must not be <code>null</code>.
+ * @see #setProperty(String,String)
+ */
+ public void setInheritedProperty(final String name, final String value) {
+ PropertyHelper.getPropertyHelper(this).setInheritedProperty(name, value);
+ }
+
+ /**
+ * Set a property unless it is already defined as a user property
+ * (in which case the method returns silently).
+ *
+ * @param name The name of the property.
+ * Must not be <code>null</code>.
+ * @param value The property value. Must not be <code>null</code>.
+ */
+ private void setPropertyInternal(final String name, final String value) {
+ PropertyHelper.getPropertyHelper(this).setProperty(name, value, false);
+ }
+
+ /**
+ * Return the value of a property, if it is set.
+ *
+ * @param propertyName The name of the property.
+ * May be <code>null</code>, in which case
+ * the return value is also <code>null</code>.
+ * @return the property value, or <code>null</code> for no match
+ * or if a <code>null</code> name is provided.
+ */
+ public String getProperty(final String propertyName) {
+ final Object value = PropertyHelper.getPropertyHelper(this).getProperty(propertyName);
+ return value == null ? null : String.valueOf(value);
+ }
+
+ /**
+ * Replace ${} style constructions in the given value with the
+ * string value of the corresponding data types.
+ *
+ * @param value The string to be scanned for property references.
+ * May be <code>null</code>.
+ *
+ * @return the given string with embedded property names replaced
+ * by values, or <code>null</code> if the given string is
+ * <code>null</code>.
+ *
+ * @exception BuildException if the given value has an unclosed
+ * property name, e.g. <code>${xxx</code>.
+ */
+ public String replaceProperties(final String value) throws BuildException {
+ return PropertyHelper.getPropertyHelper(this).replaceProperties(null, value, null);
+ }
+
+ /**
+ * Return the value of a user property, if it is set.
+ *
+ * @param propertyName The name of the property.
+ * May be <code>null</code>, in which case
+ * the return value is also <code>null</code>.
+ * @return the property value, or <code>null</code> for no match
+ * or if a <code>null</code> name is provided.
+ */
+ public String getUserProperty(final String propertyName) {
+ return (String) PropertyHelper.getPropertyHelper(this).getUserProperty(propertyName);
+ }
+
+ /**
+ * Return a copy of the properties table.
+ * @return a hashtable containing all properties
+ * (including user properties).
+ */
+ public Hashtable<String, Object> getProperties() {
+ return PropertyHelper.getPropertyHelper(this).getProperties();
+ }
+
+ /**
+ * Return a copy of the user property hashtable.
+ * @return a hashtable containing just the user properties.
+ */
+ public Hashtable<String, Object> getUserProperties() {
+ return PropertyHelper.getPropertyHelper(this).getUserProperties();
+ }
+
+ /**
+ * Return a copy of the inherited property hashtable.
+ * @return a hashtable containing just the inherited properties.
+ * @since Ant 1.8.0
+ */
+ public Hashtable<String, Object> getInheritedProperties() {
+ return PropertyHelper.getPropertyHelper(this).getInheritedProperties();
+ }
+
+ /**
+ * Copy all user properties that have been set on the command
+ * line or a GUI tool from this instance to the Project instance
+ * given as the argument.
+ *
+ * <p>To copy all &quot;user&quot; properties, you will also have to call
+ * {@link #copyInheritedProperties copyInheritedProperties}.</p>
+ *
+ * @param other the project to copy the properties to. Must not be null.
+ *
+ * @since Ant 1.5
+ */
+ public void copyUserProperties(final Project other) {
+ PropertyHelper.getPropertyHelper(this).copyUserProperties(other);
+ }
+
+ /**
+ * Copy all user properties that have not been set on the
+ * command line or a GUI tool from this instance to the Project
+ * instance given as the argument.
+ *
+ * <p>To copy all &quot;user&quot; properties, you will also have to call
+ * {@link #copyUserProperties copyUserProperties}.</p>
+ *
+ * @param other the project to copy the properties to. Must not be null.
+ *
+ * @since Ant 1.5
+ */
+ public void copyInheritedProperties(final Project other) {
+ PropertyHelper.getPropertyHelper(this).copyInheritedProperties(other);
+ }
+
+ /**
+ * Set the default target of the project.
+ *
+ * @param defaultTarget The name of the default target for this project.
+ * May be <code>null</code>, indicating that there is
+ * no default target.
+ *
+ * @deprecated since 1.5.x.
+ * Use setDefault.
+ * @see #setDefault(String)
+ */
+ @Deprecated
+ public void setDefaultTarget(final String defaultTarget) {
+ setDefault(defaultTarget);
+ }
+
+ /**
+ * Return the name of the default target of the project.
+ * @return name of the default target or
+ * <code>null</code> if no default has been set.
+ */
+ public String getDefaultTarget() {
+ return defaultTarget;
+ }
+
+ /**
+ * Set the default target of the project.
+ *
+ * @param defaultTarget The name of the default target for this project.
+ * May be <code>null</code>, indicating that there is
+ * no default target.
+ */
+ public void setDefault(final String defaultTarget) {
+ if (defaultTarget != null) {
+ setUserProperty(MagicNames.PROJECT_DEFAULT_TARGET, defaultTarget);
+ }
+ this.defaultTarget = defaultTarget;
+ }
+
+ /**
+ * Set the name of the project, also setting the user
+ * property <code>ant.project.name</code>.
+ *
+ * @param name The name of the project.
+ * Must not be <code>null</code>.
+ */
+ public void setName(final String name) {
+ setUserProperty(MagicNames.PROJECT_NAME, name);
+ this.name = name;
+ }
+
+ /**
+ * Return the project name, if one has been set.
+ *
+ * @return the project name, or <code>null</code> if it hasn't been set.
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Set the project description.
+ *
+ * @param description The description of the project.
+ * May be <code>null</code>.
+ */
+ public void setDescription(final String description) {
+ this.description = description;
+ }
+
+ /**
+ * Return the project description, if one has been set.
+ *
+ * @return the project description, or <code>null</code> if it hasn't
+ * been set.
+ */
+ public String getDescription() {
+ if (description == null) {
+ description = Description.getDescription(this);
+ }
+ return description;
+ }
+
+ /**
+ * Add a filter to the set of global filters.
+ *
+ * @param token The token to filter.
+ * Must not be <code>null</code>.
+ * @param value The replacement value.
+ * Must not be <code>null</code>.
+ * @deprecated since 1.4.x.
+ * Use getGlobalFilterSet().addFilter(token,value)
+ *
+ * @see #getGlobalFilterSet()
+ * @see FilterSet#addFilter(String,String)
+ */
+ @Deprecated
+ public void addFilter(final String token, final String value) {
+ if (token == null) {
+ return;
+ }
+ globalFilterSet.addFilter(new FilterSet.Filter(token, value));
+ }
+
+ /**
+ * Return a hashtable of global filters, mapping tokens to values.
+ *
+ * @return a hashtable of global filters, mapping tokens to values
+ * (String to String).
+ *
+ * @deprecated since 1.4.x
+ * Use getGlobalFilterSet().getFilterHash().
+ *
+ * @see #getGlobalFilterSet()
+ * @see FilterSet#getFilterHash()
+ */
+ @Deprecated
+ public Hashtable<String, String> getFilters() {
+ // we need to build the hashtable dynamically
+ return globalFilterSet.getFilterHash();
+ }
+
+ /**
+ * Set the base directory for the project, checking that
+ * the given filename exists and is a directory.
+ *
+ * @param baseD The project base directory.
+ * Must not be <code>null</code>.
+ *
+ * @exception BuildException if the directory if invalid.
+ */
+ public void setBasedir(final String baseD) throws BuildException {
+ setBaseDir(new File(baseD));
+ }
+
+ /**
+ * Set the base directory for the project, checking that
+ * the given file exists and is a directory.
+ *
+ * @param baseDir The project base directory.
+ * Must not be <code>null</code>.
+ * @exception BuildException if the specified file doesn't exist or
+ * isn't a directory.
+ */
+ public void setBaseDir(File baseDir) throws BuildException {
+ baseDir = FILE_UTILS.normalize(baseDir.getAbsolutePath());
+ if (!baseDir.exists()) {
+ throw new BuildException("Basedir " + baseDir.getAbsolutePath()
+ + " does not exist");
+ }
+ if (!baseDir.isDirectory()) {
+ throw new BuildException("Basedir " + baseDir.getAbsolutePath()
+ + " is not a directory");
+ }
+ this.baseDir = baseDir;
+ setPropertyInternal(MagicNames.PROJECT_BASEDIR, this.baseDir.getPath());
+ final String msg = "Project base dir set to: " + this.baseDir;
+ log(msg, MSG_VERBOSE);
+ }
+
+ /**
+ * Return the base directory of the project as a file object.
+ *
+ * @return the project base directory, or <code>null</code> if the
+ * base directory has not been successfully set to a valid value.
+ */
+ public File getBaseDir() {
+ if (baseDir == null) {
+ try {
+ setBasedir(".");
+ } catch (final BuildException ex) {
+ ex.printStackTrace();
+ }
+ }
+ return baseDir;
+ }
+
+ /**
+ * Set &quot;keep-going&quot; mode. In this mode Ant will try to execute
+ * as many targets as possible. All targets that do not depend
+ * on failed target(s) will be executed. If the keepGoing settor/getter
+ * methods are used in conjunction with the <code>ant.executor.class</code>
+ * property, they will have no effect.
+ * @param keepGoingMode &quot;keep-going&quot; mode
+ * @since Ant 1.6
+ */
+ public void setKeepGoingMode(final boolean keepGoingMode) {
+ this.keepGoingMode = keepGoingMode;
+ }
+
+ /**
+ * Return the keep-going mode. If the keepGoing settor/getter
+ * methods are used in conjunction with the <code>ant.executor.class</code>
+ * property, they will have no effect.
+ * @return &quot;keep-going&quot; mode
+ * @since Ant 1.6
+ */
+ public boolean isKeepGoingMode() {
+ return this.keepGoingMode;
+ }
+
+ /**
+ * Return the version of Java this class is running under.
+ * @return the version of Java as a String, e.g. "1.1" .
+ * @see org.apache.tools.ant.util.JavaEnvUtils#getJavaVersion
+ * @deprecated since 1.5.x.
+ * Use org.apache.tools.ant.util.JavaEnvUtils instead.
+ */
+ @Deprecated
+ public static String getJavaVersion() {
+ return JavaEnvUtils.getJavaVersion();
+ }
+
+ /**
+ * Set the <code>ant.java.version</code> property and tests for
+ * unsupported JVM versions. If the version is supported,
+ * verbose log messages are generated to record the Java version
+ * and operating system name.
+ *
+ * @exception BuildException if this Java version is not supported.
+ *
+ * @see org.apache.tools.ant.util.JavaEnvUtils#getJavaVersion
+ */
+ public void setJavaVersionProperty() throws BuildException {
+ final String javaVersion = JavaEnvUtils.getJavaVersion();
+ setPropertyInternal(MagicNames.ANT_JAVA_VERSION, javaVersion);
+
+ // sanity check
+ if (!JavaEnvUtils.isAtLeastJavaVersion(JavaEnvUtils.JAVA_1_5)) {
+ throw new BuildException("Ant cannot work on Java prior to 1.5");
+ }
+ log("Detected Java version: " + javaVersion + " in: "
+ + System.getProperty("java.home"), MSG_VERBOSE);
+
+ log("Detected OS: " + System.getProperty("os.name"), MSG_VERBOSE);
+ }
+
+ /**
+ * Add all system properties which aren't already defined as
+ * user properties to the project properties.
+ */
+ public void setSystemProperties() {
+ final Properties systemP = System.getProperties();
+ final Enumeration<?> e = systemP.propertyNames();
+ while (e.hasMoreElements()) {
+ final String propertyName = (String) e.nextElement();
+ final String value = systemP.getProperty(propertyName);
+ if (value != null) {
+ this.setPropertyInternal(propertyName, value);
+ }
+ }
+ }
+
+ /**
+ * Add a new task definition to the project.
+ * Attempting to override an existing definition with an
+ * equivalent one (i.e. with the same classname) results in
+ * a verbose log message. Attempting to override an existing definition
+ * with a different one results in a warning log message and
+ * invalidates any tasks which have already been created with the
+ * old definition.
+ *
+ * @param taskName The name of the task to add.
+ * Must not be <code>null</code>.
+ * @param taskClass The full name of the class implementing the task.
+ * Must not be <code>null</code>.
+ *
+ * @exception BuildException if the class is unsuitable for being an Ant
+ * task. An error level message is logged before
+ * this exception is thrown.
+ *
+ * @see #checkTaskClass(Class)
+ */
+ public void addTaskDefinition(final String taskName, final Class<?> taskClass)
+ throws BuildException {
+ ComponentHelper.getComponentHelper(this).addTaskDefinition(taskName,
+ taskClass);
+ }
+
+ /**
+ * Check whether or not a class is suitable for serving as Ant task.
+ * Ant task implementation classes must be public, concrete, and have
+ * a no-arg constructor.
+ *
+ * @param taskClass The class to be checked.
+ * Must not be <code>null</code>.
+ *
+ * @exception BuildException if the class is unsuitable for being an Ant
+ * task. An error level message is logged before
+ * this exception is thrown.
+ */
+ public void checkTaskClass(final Class<?> taskClass) throws BuildException {
+ ComponentHelper.getComponentHelper(this).checkTaskClass(taskClass);
+
+ if (!Modifier.isPublic(taskClass.getModifiers())) {
+ final String message = taskClass + " is not public";
+ log(message, Project.MSG_ERR);
+ throw new BuildException(message);
+ }
+ if (Modifier.isAbstract(taskClass.getModifiers())) {
+ final String message = taskClass + " is abstract";
+ log(message, Project.MSG_ERR);
+ throw new BuildException(message);
+ }
+ try {
+ taskClass.getConstructor();
+ // don't have to check for public, since
+ // getConstructor finds public constructors only.
+ } catch (final NoSuchMethodException e) {
+ final String message = "No public no-arg constructor in "
+ + taskClass;
+ log(message, Project.MSG_ERR);
+ throw new BuildException(message);
+ } catch (final LinkageError e) {
+ final String message = "Could not load " + taskClass + ": " + e;
+ log(message, Project.MSG_ERR);
+ throw new BuildException(message, e);
+ }
+ if (!Task.class.isAssignableFrom(taskClass)) {
+ TaskAdapter.checkTaskClass(taskClass, this);
+ }
+ }
+
+ /**
+ * Return the current task definition hashtable. The returned hashtable is
+ * &quot;live&quot; and so should not be modified.
+ *
+ * @return a map of from task name to implementing class
+ * (String to Class).
+ */
+ public Hashtable<String, Class<?>> getTaskDefinitions() {
+ return ComponentHelper.getComponentHelper(this).getTaskDefinitions();
+ }
+
+ /**
+ * Return the current task definition map. The returned map is a
+ * copy of the &quot;live&quot; definitions.
+ *
+ * @return a map of from task name to implementing class
+ * (String to Class).
+ *
+ * @since Ant 1.8.1
+ */
+ public Map<String, Class<?>> getCopyOfTaskDefinitions() {
+ return new HashMap<String, Class<?>>(getTaskDefinitions());
+ }
+
+ /**
+ * Add a new datatype definition.
+ * Attempting to override an existing definition with an
+ * equivalent one (i.e. with the same classname) results in
+ * a verbose log message. Attempting to override an existing definition
+ * with a different one results in a warning log message, but the
+ * definition is changed.
+ *
+ * @param typeName The name of the datatype.
+ * Must not be <code>null</code>.
+ * @param typeClass The full name of the class implementing the datatype.
+ * Must not be <code>null</code>.
+ */
+ public void addDataTypeDefinition(final String typeName, final Class<?> typeClass) {
+ ComponentHelper.getComponentHelper(this).addDataTypeDefinition(typeName,
+ typeClass);
+ }
+
+ /**
+ * Return the current datatype definition hashtable. The returned
+ * hashtable is &quot;live&quot; and so should not be modified.
+ *
+ * @return a map of from datatype name to implementing class
+ * (String to Class).
+ */
+ public Hashtable<String, Class<?>> getDataTypeDefinitions() {
+ return ComponentHelper.getComponentHelper(this).getDataTypeDefinitions();
+ }
+
+ /**
+ * Return the current datatype definition map. The returned
+ * map is a copy pf the &quot;live&quot; definitions.
+ *
+ * @return a map of from datatype name to implementing class
+ * (String to Class).
+ *
+ * @since Ant 1.8.1
+ */
+ public Map<String, Class<?>> getCopyOfDataTypeDefinitions() {
+ return new HashMap<String, Class<?>>(getDataTypeDefinitions());
+ }
+
+ /**
+ * Add a <em>new</em> target to the project.
+ *
+ * @param target The target to be added to the project.
+ * Must not be <code>null</code>.
+ *
+ * @exception BuildException if the target already exists in the project
+ *
+ * @see Project#addOrReplaceTarget(Target)
+ */
+ public void addTarget(final Target target) throws BuildException {
+ addTarget(target.getName(), target);
+ }
+
+ /**
+ * Add a <em>new</em> target to the project.
+ *
+ * @param targetName The name to use for the target.
+ * Must not be <code>null</code>.
+ * @param target The target to be added to the project.
+ * Must not be <code>null</code>.
+ *
+ * @exception BuildException if the target already exists in the project.
+ *
+ * @see Project#addOrReplaceTarget(String, Target)
+ */
+ public void addTarget(final String targetName, final Target target)
+ throws BuildException {
+ if (targets.get(targetName) != null) {
+ throw new BuildException("Duplicate target: `" + targetName + "'");
+ }
+ addOrReplaceTarget(targetName, target);
+ }
+
+ /**
+ * Add a target to the project, or replaces one with the same
+ * name.
+ *
+ * @param target The target to be added or replaced in the project.
+ * Must not be <code>null</code>.
+ */
+ public void addOrReplaceTarget(final Target target) {
+ addOrReplaceTarget(target.getName(), target);
+ }
+
+ /**
+ * Add a target to the project, or replaces one with the same
+ * name.
+ *
+ * @param targetName The name to use for the target.
+ * Must not be <code>null</code>.
+ * @param target The target to be added or replaced in the project.
+ * Must not be <code>null</code>.
+ */
+ public void addOrReplaceTarget(final String targetName, final Target target) {
+ final String msg = " +Target: " + targetName;
+ log(msg, MSG_DEBUG);
+ target.setProject(this);
+ targets.put(targetName, target);
+ }
+
+ /**
+ * Return the hashtable of targets. The returned hashtable
+ * is &quot;live&quot; and so should not be modified.
+ * @return a map from name to target (String to Target).
+ */
+ public Hashtable<String, Target> getTargets() {
+ return targets;
+ }
+
+ /**
+ * Return the map of targets. The returned map
+ * is a copy of the &quot;live&quot; targets.
+ * @return a map from name to target (String to Target).
+ * @since Ant 1.8.1
+ */
+ public Map<String, Target> getCopyOfTargets() {
+ return new HashMap<String, Target>(targets);
+ }
+
+ /**
+ * Create a new instance of a task, adding it to a list of
+ * created tasks for later invalidation. This causes all tasks
+ * to be remembered until the containing project is removed
+ * @param taskType The name of the task to create an instance of.
+ * Must not be <code>null</code>.
+ *
+ * @return an instance of the specified task, or <code>null</code> if
+ * the task name is not recognised.
+ *
+ * @exception BuildException if the task name is recognised but task
+ * creation fails.
+ */
+ public Task createTask(final String taskType) throws BuildException {
+ return ComponentHelper.getComponentHelper(this).createTask(taskType);
+ }
+
+ /**
+ * Create a new instance of a data type.
+ *
+ * @param typeName The name of the data type to create an instance of.
+ * Must not be <code>null</code>.
+ *
+ * @return an instance of the specified data type, or <code>null</code> if
+ * the data type name is not recognised.
+ *
+ * @exception BuildException if the data type name is recognised but
+ * instance creation fails.
+ */
+ public Object createDataType(final String typeName) throws BuildException {
+ return ComponentHelper.getComponentHelper(this).createDataType(typeName);
+ }
+
+ /**
+ * Set the Executor instance for this Project.
+ * @param e the Executor to use.
+ */
+ public void setExecutor(final Executor e) {
+ addReference(MagicNames.ANT_EXECUTOR_REFERENCE, e);
+ }
+
+ /**
+ * Get this Project's Executor (setting it if necessary).
+ * @return an Executor instance.
+ */
+ public Executor getExecutor() {
+ Object o = getReference(MagicNames.ANT_EXECUTOR_REFERENCE);
+ if (o == null) {
+ String classname = getProperty(MagicNames.ANT_EXECUTOR_CLASSNAME);
+ if (classname == null) {
+ classname = DefaultExecutor.class.getName();
+ }
+ log("Attempting to create object of type " + classname, MSG_DEBUG);
+ try {
+ o = Class.forName(classname, true, coreLoader).newInstance();
+ } catch (final ClassNotFoundException seaEnEfEx) {
+ //try the current classloader
+ try {
+ o = Class.forName(classname).newInstance();
+ } catch (final Exception ex) {
+ log(ex.toString(), MSG_ERR);
+ }
+ } catch (final Exception ex) {
+ log(ex.toString(), MSG_ERR);
+ }
+ if (o == null) {
+ throw new BuildException(
+ "Unable to obtain a Target Executor instance.");
+ }
+ setExecutor((Executor) o);
+ }
+ return (Executor) o;
+ }
+
+ /**
+ * Execute the specified sequence of targets, and the targets
+ * they depend on.
+ *
+ * @param names A vector of target name strings to execute.
+ * Must not be <code>null</code>.
+ *
+ * @exception BuildException if the build failed.
+ */
+ public void executeTargets(final Vector<String> names) throws BuildException {
+ setUserProperty(MagicNames.PROJECT_INVOKED_TARGETS,
+ CollectionUtils.flattenToString(names));
+ getExecutor().executeTargets(this, names.toArray(new String[names.size()]));
+ }
+
+ /**
+ * Demultiplex output so that each task receives the appropriate
+ * messages. If the current thread is not currently executing a task,
+ * the message is logged directly.
+ *
+ * @param output Message to handle. Should not be <code>null</code>.
+ * @param isWarning Whether the text represents an warning (<code>true</code>)
+ * or information (<code>false</code>).
+ */
+ public void demuxOutput(final String output, final boolean isWarning) {
+ final Task task = getThreadTask(Thread.currentThread());
+ if (task == null) {
+ log(output, isWarning ? MSG_WARN : MSG_INFO);
+ } else {
+ if (isWarning) {
+ task.handleErrorOutput(output);
+ } else {
+ task.handleOutput(output);
+ }
+ }
+ }
+
+ /**
+ * Read data from the default input stream. If no default has been
+ * specified, System.in is used.
+ *
+ * @param buffer the buffer into which data is to be read.
+ * @param offset the offset into the buffer at which data is stored.
+ * @param length the amount of data to read.
+ *
+ * @return the number of bytes read.
+ *
+ * @exception IOException if the data cannot be read.
+ * @since Ant 1.6
+ */
+ public int defaultInput(final byte[] buffer, final int offset, final int length)
+ throws IOException {
+ if (defaultInputStream != null) {
+ System.out.flush();
+ return defaultInputStream.read(buffer, offset, length);
+ } else {
+ throw new EOFException("No input provided for project");
+ }
+ }
+
+ /**
+ * Demux an input request to the correct task.
+ *
+ * @param buffer the buffer into which data is to be read.
+ * @param offset the offset into the buffer at which data is stored.
+ * @param length the amount of data to read.
+ *
+ * @return the number of bytes read.
+ *
+ * @exception IOException if the data cannot be read.
+ * @since Ant 1.6
+ */
+ public int demuxInput(final byte[] buffer, final int offset, final int length)
+ throws IOException {
+ final Task task = getThreadTask(Thread.currentThread());
+ if (task == null) {
+ return defaultInput(buffer, offset, length);
+ } else {
+ return task.handleInput(buffer, offset, length);
+ }
+ }
+
+ /**
+ * Demultiplex flush operations so that each task receives the appropriate
+ * messages. If the current thread is not currently executing a task,
+ * the message is logged directly.
+ *
+ * @since Ant 1.5.2
+ *
+ * @param output Message to handle. Should not be <code>null</code>.
+ * @param isError Whether the text represents an error (<code>true</code>)
+ * or information (<code>false</code>).
+ */
+ public void demuxFlush(final String output, final boolean isError) {
+ final Task task = getThreadTask(Thread.currentThread());
+ if (task == null) {
+ fireMessageLogged(this, output, isError ? MSG_ERR : MSG_INFO);
+ } else {
+ if (isError) {
+ task.handleErrorFlush(output);
+ } else {
+ task.handleFlush(output);
+ }
+ }
+ }
+
+ /**
+ * Execute the specified target and any targets it depends on.
+ *
+ * @param targetName The name of the target to execute.
+ * Must not be <code>null</code>.
+ *
+ * @exception BuildException if the build failed.
+ */
+ public void executeTarget(final String targetName) throws BuildException {
+
+ // sanity check ourselves, if we've been asked to build nothing
+ // then we should complain
+
+ if (targetName == null) {
+ final String msg = "No target specified";
+ throw new BuildException(msg);
+ }
+
+ // Sort and run the dependency tree.
+ // Sorting checks if all the targets (and dependencies)
+ // exist, and if there is any cycle in the dependency
+ // graph.
+ executeSortedTargets(topoSort(targetName, targets, false));
+ }
+
+ /**
+ * Execute a <code>Vector</code> of sorted targets.
+ * @param sortedTargets the aforementioned <code>Vector</code>.
+ * @throws BuildException on error.
+ */
+ public void executeSortedTargets(final Vector<Target> sortedTargets)
+ throws BuildException {
+ final Set<String> succeededTargets = new HashSet<String>();
+ BuildException buildException = null; // first build exception
+ for (final Target curtarget : sortedTargets) {
+ boolean canExecute = true;
+ for (final Enumeration<String> depIter = curtarget.getDependencies();
+ depIter.hasMoreElements();) {
+ final String dependencyName = depIter.nextElement();
+ if (!succeededTargets.contains(dependencyName)) {
+ canExecute = false;
+ log(curtarget,
+ "Cannot execute '" + curtarget.getName() + "' - '"
+ + dependencyName + "' failed or was not executed.",
+ MSG_ERR);
+ break;
+ }
+ }
+ if (canExecute) {
+ Throwable thrownException = null;
+ try {
+ curtarget.performTasks();
+ succeededTargets.add(curtarget.getName());
+ } catch (final RuntimeException ex) {
+ if (!(keepGoingMode)) {
+ throw ex; // throw further
+ }
+ thrownException = ex;
+ } catch (final Throwable ex) {
+ if (!(keepGoingMode)) {
+ throw new BuildException(ex);
+ }
+ thrownException = ex;
+ }
+ if (thrownException != null) {
+ if (thrownException instanceof BuildException) {
+ log(curtarget,
+ "Target '" + curtarget.getName()
+ + "' failed with message '"
+ + thrownException.getMessage() + "'.", MSG_ERR);
+ // only the first build exception is reported
+ if (buildException == null) {
+ buildException = (BuildException) thrownException;
+ }
+ } else {
+ log(curtarget,
+ "Target '" + curtarget.getName()
+ + "' failed with message '"
+ + thrownException.getMessage() + "'.", MSG_ERR);
+ thrownException.printStackTrace(System.err);
+ if (buildException == null) {
+ buildException =
+ new BuildException(thrownException);
+ }
+ }
+ }
+ }
+ }
+ if (buildException != null) {
+ throw buildException;
+ }
+ }
+
+ /**
+ * Return the canonical form of a filename.
+ * <p>
+ * If the specified file name is relative it is resolved
+ * with respect to the given root directory.
+ *
+ * @param fileName The name of the file to resolve.
+ * Must not be <code>null</code>.
+ *
+ * @param rootDir The directory respective to which relative file names
+ * are resolved. May be <code>null</code>, in which case
+ * the current directory is used.
+ *
+ * @return the resolved File.
+ *
+ * @deprecated since 1.4.x
+ */
+ @Deprecated
+ public File resolveFile(final String fileName, final File rootDir) {
+ return FILE_UTILS.resolveFile(rootDir, fileName);
+ }
+
+ /**
+ * Return the canonical form of a filename.
+ * <p>
+ * If the specified file name is relative it is resolved
+ * with respect to the project's base directory.
+ *
+ * @param fileName The name of the file to resolve.
+ * Must not be <code>null</code>.
+ *
+ * @return the resolved File.
+ *
+ */
+ public File resolveFile(final String fileName) {
+ return FILE_UTILS.resolveFile(baseDir, fileName);
+ }
+
+ /**
+ * Translate a path into its native (platform specific) format.
+ * <p>
+ * This method uses PathTokenizer to separate the input path
+ * into its components. This handles DOS style paths in a relatively
+ * sensible way. The file separators are then converted to their platform
+ * specific versions.
+ *
+ * @param toProcess The path to be translated.
+ * May be <code>null</code>.
+ *
+ * @return the native version of the specified path or
+ * an empty string if the path is <code>null</code> or empty.
+ *
+ * @deprecated since 1.7
+ * Use FileUtils.translatePath instead.
+ *
+ * @see PathTokenizer
+ */
+ @Deprecated
+ public static String translatePath(final String toProcess) {
+ return FileUtils.translatePath(toProcess);
+ }
+
+ /**
+ * Convenience method to copy a file from a source to a destination.
+ * No filtering is performed.
+ *
+ * @param sourceFile Name of file to copy from.
+ * Must not be <code>null</code>.
+ * @param destFile Name of file to copy to.
+ * Must not be <code>null</code>.
+ *
+ * @exception IOException if the copying fails.
+ *
+ * @deprecated since 1.4.x
+ */
+ @Deprecated
+ public void copyFile(final String sourceFile, final String destFile)
+ throws IOException {
+ FILE_UTILS.copyFile(sourceFile, destFile);
+ }
+
+ /**
+ * Convenience method to copy a file from a source to a destination
+ * specifying if token filtering should be used.
+ *
+ * @param sourceFile Name of file to copy from.
+ * Must not be <code>null</code>.
+ * @param destFile Name of file to copy to.
+ * Must not be <code>null</code>.
+ * @param filtering Whether or not token filtering should be used during
+ * the copy.
+ *
+ * @exception IOException if the copying fails.
+ *
+ * @deprecated since 1.4.x
+ */
+ @Deprecated
+ public void copyFile(final String sourceFile, final String destFile, final boolean filtering)
+ throws IOException {
+ FILE_UTILS.copyFile(sourceFile, destFile,
+ filtering ? globalFilters : null);
+ }
+
+ /**
+ * Convenience method to copy a file from a source to a
+ * destination specifying if token filtering should be used and if
+ * source files may overwrite newer destination files.
+ *
+ * @param sourceFile Name of file to copy from.
+ * Must not be <code>null</code>.
+ * @param destFile Name of file to copy to.
+ * Must not be <code>null</code>.
+ * @param filtering Whether or not token filtering should be used during
+ * the copy.
+ * @param overwrite Whether or not the destination file should be
+ * overwritten if it already exists.
+ *
+ * @exception IOException if the copying fails.
+ *
+ * @deprecated since 1.4.x
+ */
+ @Deprecated
+ public void copyFile(final String sourceFile, final String destFile, final boolean filtering,
+ final boolean overwrite) throws IOException {
+ FILE_UTILS.copyFile(sourceFile, destFile,
+ filtering ? globalFilters : null, overwrite);
+ }
+
+ /**
+ * Convenience method to copy a file from a source to a
+ * destination specifying if token filtering should be used, if
+ * source files may overwrite newer destination files, and if the
+ * last modified time of the resulting file should be set to
+ * that of the source file.
+ *
+ * @param sourceFile Name of file to copy from.
+ * Must not be <code>null</code>.
+ * @param destFile Name of file to copy to.
+ * Must not be <code>null</code>.
+ * @param filtering Whether or not token filtering should be used during
+ * the copy.
+ * @param overwrite Whether or not the destination file should be
+ * overwritten if it already exists.
+ * @param preserveLastModified Whether or not the last modified time of
+ * the resulting file should be set to that
+ * of the source file.
+ *
+ * @exception IOException if the copying fails.
+ *
+ * @deprecated since 1.4.x
+ */
+ @Deprecated
+ public void copyFile(final String sourceFile, final String destFile, final boolean filtering,
+ final boolean overwrite, final boolean preserveLastModified)
+ throws IOException {
+ FILE_UTILS.copyFile(sourceFile, destFile,
+ filtering ? globalFilters : null, overwrite, preserveLastModified);
+ }
+
+ /**
+ * Convenience method to copy a file from a source to a destination.
+ * No filtering is performed.
+ *
+ * @param sourceFile File to copy from.
+ * Must not be <code>null</code>.
+ * @param destFile File to copy to.
+ * Must not be <code>null</code>.
+ *
+ * @exception IOException if the copying fails.
+ *
+ * @deprecated since 1.4.x
+ */
+ @Deprecated
+ public void copyFile(final File sourceFile, final File destFile) throws IOException {
+ FILE_UTILS.copyFile(sourceFile, destFile);
+ }
+
+ /**
+ * Convenience method to copy a file from a source to a destination
+ * specifying if token filtering should be used.
+ *
+ * @param sourceFile File to copy from.
+ * Must not be <code>null</code>.
+ * @param destFile File to copy to.
+ * Must not be <code>null</code>.
+ * @param filtering Whether or not token filtering should be used during
+ * the copy.
+ *
+ * @exception IOException if the copying fails.
+ *
+ * @deprecated since 1.4.x
+ */
+ @Deprecated
+ public void copyFile(final File sourceFile, final File destFile, final boolean filtering)
+ throws IOException {
+ FILE_UTILS.copyFile(sourceFile, destFile,
+ filtering ? globalFilters : null);
+ }
+
+ /**
+ * Convenience method to copy a file from a source to a
+ * destination specifying if token filtering should be used and if
+ * source files may overwrite newer destination files.
+ *
+ * @param sourceFile File to copy from.
+ * Must not be <code>null</code>.
+ * @param destFile File to copy to.
+ * Must not be <code>null</code>.
+ * @param filtering Whether or not token filtering should be used during
+ * the copy.
+ * @param overwrite Whether or not the destination file should be
+ * overwritten if it already exists.
+ *
+ * @exception IOException if the file cannot be copied.
+ *
+ * @deprecated since 1.4.x
+ */
+ @Deprecated
+ public void copyFile(final File sourceFile, final File destFile, final boolean filtering,
+ final boolean overwrite) throws IOException {
+ FILE_UTILS.copyFile(sourceFile, destFile,
+ filtering ? globalFilters : null, overwrite);
+ }
+
+ /**
+ * Convenience method to copy a file from a source to a
+ * destination specifying if token filtering should be used, if
+ * source files may overwrite newer destination files, and if the
+ * last modified time of the resulting file should be set to
+ * that of the source file.
+ *
+ * @param sourceFile File to copy from.
+ * Must not be <code>null</code>.
+ * @param destFile File to copy to.
+ * Must not be <code>null</code>.
+ * @param filtering Whether or not token filtering should be used during
+ * the copy.
+ * @param overwrite Whether or not the destination file should be
+ * overwritten if it already exists.
+ * @param preserveLastModified Whether or not the last modified time of
+ * the resulting file should be set to that
+ * of the source file.
+ *
+ * @exception IOException if the file cannot be copied.
+ *
+ * @deprecated since 1.4.x
+ */
+ @Deprecated
+ public void copyFile(final File sourceFile, final File destFile, final boolean filtering,
+ final boolean overwrite, final boolean preserveLastModified)
+ throws IOException {
+ FILE_UTILS.copyFile(sourceFile, destFile,
+ filtering ? globalFilters : null, overwrite, preserveLastModified);
+ }
+
+ /**
+ * Call File.setLastModified(long time) on Java above 1.1, and logs
+ * a warning on Java 1.1.
+ *
+ * @param file The file to set the last modified time on.
+ * Must not be <code>null</code>.
+ *
+ * @param time the required modification time.
+ *
+ * @deprecated since 1.4.x
+ *
+ * @exception BuildException if the last modified time cannot be set
+ * despite running on a platform with a version
+ * above 1.1.
+ */
+ @Deprecated
+ public void setFileLastModified(final File file, final long time)
+ throws BuildException {
+ FILE_UTILS.setFileLastModified(file, time);
+ log("Setting modification time for " + file, MSG_VERBOSE);
+ }
+
+ /**
+ * Return the boolean equivalent of a string, which is considered
+ * <code>true</code> if either <code>"on"</code>, <code>"true"</code>,
+ * or <code>"yes"</code> is found, ignoring case.
+ *
+ * @param s The string to convert to a boolean value.
+ *
+ * @return <code>true</code> if the given string is <code>"on"</code>,
+ * <code>"true"</code> or <code>"yes"</code>, or
+ * <code>false</code> otherwise.
+ */
+ public static boolean toBoolean(final String s) {
+ return ("on".equalsIgnoreCase(s)
+ || "true".equalsIgnoreCase(s)
+ || "yes".equalsIgnoreCase(s));
+ }
+
+ /**
+ * Get the Project instance associated with the specified object.
+ * @param o the object to query.
+ * @return Project instance, if any.
+ * @since Ant 1.7.1
+ */
+ public static Project getProject(final Object o) {
+ if (o instanceof ProjectComponent) {
+ return ((ProjectComponent) o).getProject();
+ }
+ try {
+ final Method m = o.getClass().getMethod("getProject", (Class[]) null);
+ if (Project.class == m.getReturnType()) {
+ return (Project) m.invoke(o, (Object[]) null);
+ }
+ } catch (final Exception e) {
+ //too bad
+ }
+ return null;
+ }
+
+ /**
+ * Topologically sort a set of targets. Equivalent to calling
+ * <code>topoSort(new String[] {root}, targets, true)</code>.
+ *
+ * @param root The name of the root target. The sort is created in such
+ * a way that the sequence of Targets up to the root
+ * target is the minimum possible such sequence.
+ * Must not be <code>null</code>.
+ * @param targetTable A Hashtable mapping names to Targets.
+ * Must not be <code>null</code>.
+ * @return a Vector of ALL Target objects in sorted order.
+ * @exception BuildException if there is a cyclic dependency among the
+ * targets, or if a named target does not exist.
+ */
+ public final Vector<Target> topoSort(final String root, final Hashtable<String, Target> targetTable)
+ throws BuildException {
+ return topoSort(new String[] {root}, targetTable, true);
+ }
+
+ /**
+ * Topologically sort a set of targets. Equivalent to calling
+ * <code>topoSort(new String[] {root}, targets, returnAll)</code>.
+ *
+ * @param root The name of the root target. The sort is created in such
+ * a way that the sequence of Targets up to the root
+ * target is the minimum possible such sequence.
+ * Must not be <code>null</code>.
+ * @param targetTable A Hashtable mapping names to Targets.
+ * Must not be <code>null</code>.
+ * @param returnAll <code>boolean</code> indicating whether to return all
+ * targets, or the execution sequence only.
+ * @return a Vector of Target objects in sorted order.
+ * @exception BuildException if there is a cyclic dependency among the
+ * targets, or if a named target does not exist.
+ * @since Ant 1.6.3
+ */
+ public final Vector<Target> topoSort(final String root, final Hashtable<String, Target> targetTable,
+ final boolean returnAll) throws BuildException {
+ return topoSort(new String[] {root}, targetTable, returnAll);
+ }
+
+ /**
+ * Topologically sort a set of targets.
+ *
+ * @param root <code>String[]</code> containing the names of the root targets.
+ * The sort is created in such a way that the ordered sequence of
+ * Targets is the minimum possible such sequence to the specified
+ * root targets.
+ * Must not be <code>null</code>.
+ * @param targetTable A map of names to targets (String to Target).
+ * Must not be <code>null</code>.
+ * @param returnAll <code>boolean</code> indicating whether to return all
+ * targets, or the execution sequence only.
+ * @return a Vector of Target objects in sorted order.
+ * @exception BuildException if there is a cyclic dependency among the
+ * targets, or if a named target does not exist.
+ * @since Ant 1.6.3
+ */
+ public final Vector<Target> topoSort(final String[] root, final Hashtable<String, Target> targetTable,
+ final boolean returnAll) throws BuildException {
+ final Vector<Target> ret = new VectorSet<Target>();
+ final Hashtable<String, String> state = new Hashtable<String, String>();
+ final Stack<String> visiting = new Stack<String>();
+
+ // We first run a DFS based sort using each root as a starting node.
+ // This creates the minimum sequence of Targets to the root node(s).
+ // We then do a sort on any remaining unVISITED targets.
+ // This is unnecessary for doing our build, but it catches
+ // circular dependencies or missing Targets on the entire
+ // dependency tree, not just on the Targets that depend on the
+ // build Target.
+
+ for (int i = 0; i < root.length; i++) {
+ final String st = (state.get(root[i]));
+ if (st == null) {
+ tsort(root[i], targetTable, state, visiting, ret);
+ } else if (st == VISITING) {
+ throw new RuntimeException("Unexpected node in visiting state: "
+ + root[i]);
+ }
+ }
+ final StringBuffer buf = new StringBuffer("Build sequence for target(s)");
+
+ for (int j = 0; j < root.length; j++) {
+ buf.append((j == 0) ? " `" : ", `").append(root[j]).append('\'');
+ }
+ buf.append(" is " + ret);
+ log(buf.toString(), MSG_VERBOSE);
+
+ final Vector<Target> complete = (returnAll) ? ret : new Vector<Target>(ret);
+ for (final Enumeration<String> en = targetTable.keys(); en.hasMoreElements();) {
+ final String curTarget = en.nextElement();
+ final String st = state.get(curTarget);
+ if (st == null) {
+ tsort(curTarget, targetTable, state, visiting, complete);
+ } else if (st == VISITING) {
+ throw new RuntimeException("Unexpected node in visiting state: "
+ + curTarget);
+ }
+ }
+ log("Complete build sequence is " + complete, MSG_VERBOSE);
+ return ret;
+ }
+
+ /**
+ * Perform a single step in a recursive depth-first-search traversal of
+ * the target dependency tree.
+ * <p>
+ * The current target is first set to the &quot;visiting&quot; state, and
+ * pushed onto the &quot;visiting&quot; stack.
+ * <p>
+ * An exception is then thrown if any child of the current node is in the
+ * visiting state, as that implies a circular dependency. The exception
+ * contains details of the cycle, using elements of the &quot;visiting&quot;
+ * stack.
+ * <p>
+ * If any child has not already been &quot;visited&quot;, this method is
+ * called recursively on it.
+ * <p>
+ * The current target is then added to the ordered list of targets. Note
+ * that this is performed after the children have been visited in order
+ * to get the correct order. The current target is set to the
+ * &quot;visited&quot; state.
+ * <p>
+ * By the time this method returns, the ordered list contains the sequence
+ * of targets up to and including the current target.
+ *
+ * @param root The current target to inspect.
+ * Must not be <code>null</code>.
+ * @param targetTable A mapping from names to targets (String to Target).
+ * Must not be <code>null</code>.
+ * @param state A mapping from target names to states (String to String).
+ * The states in question are &quot;VISITING&quot; and
+ * &quot;VISITED&quot;. Must not be <code>null</code>.
+ * @param visiting A stack of targets which are currently being visited.
+ * Must not be <code>null</code>.
+ * @param ret The list to add target names to. This will end up
+ * containing the complete list of dependencies in
+ * dependency order.
+ * Must not be <code>null</code>.
+ *
+ * @exception BuildException if a non-existent target is specified or if
+ * a circular dependency is detected.
+ */
+ private void tsort(final String root, final Hashtable<String, Target> targetTable,
+ final Hashtable<String, String> state, final Stack<String> visiting,
+ final Vector<Target> ret)
+ throws BuildException {
+ state.put(root, VISITING);
+ visiting.push(root);
+
+ final Target target = targetTable.get(root);
+
+ // Make sure we exist
+ if (target == null) {
+ final StringBuilder sb = new StringBuilder("Target \"");
+ sb.append(root);
+ sb.append("\" does not exist in the project \"");
+ sb.append(name);
+ sb.append("\". ");
+ visiting.pop();
+ if (!visiting.empty()) {
+ final String parent = visiting.peek();
+ sb.append("It is used from target \"");
+ sb.append(parent);
+ sb.append("\".");
+ }
+ throw new BuildException(new String(sb));
+ }
+ for (final Enumeration<String> en = target.getDependencies(); en.hasMoreElements();) {
+ final String cur = en.nextElement();
+ final String m = state.get(cur);
+ if (m == null) {
+ // Not been visited
+ tsort(cur, targetTable, state, visiting, ret);
+ } else if (m == VISITING) {
+ // Currently visiting this node, so have a cycle
+ throw makeCircularException(cur, visiting);
+ }
+ }
+ final String p = visiting.pop();
+ if (root != p) {
+ throw new RuntimeException("Unexpected internal error: expected to "
+ + "pop " + root + " but got " + p);
+ }
+ state.put(root, VISITED);
+ ret.addElement(target);
+ }
+
+ /**
+ * Build an appropriate exception detailing a specified circular
+ * dependency.
+ *
+ * @param end The dependency to stop at. Must not be <code>null</code>.
+ * @param stk A stack of dependencies. Must not be <code>null</code>.
+ *
+ * @return a BuildException detailing the specified circular dependency.
+ */
+ private static BuildException makeCircularException(final String end, final Stack<String> stk) {
+ final StringBuilder sb = new StringBuilder("Circular dependency: ");
+ sb.append(end);
+ String c;
+ do {
+ c = stk.pop();
+ sb.append(" <- ");
+ sb.append(c);
+ } while (!c.equals(end));
+ return new BuildException(sb.toString());
+ }
+
+ /**
+ * Inherit the id references.
+ * @param parent the parent project of this project.
+ */
+ public void inheritIDReferences(final Project parent) {
+ }
+
+ /**
+ * Add an id reference.
+ * Used for broken build files.
+ * @param id the id to set.
+ * @param value the value to set it to (Unknown element in this case.
+ */
+ public void addIdReference(final String id, final Object value) {
+ idReferences.put(id, value);
+ }
+
+ /**
+ * Add a reference to the project.
+ *
+ * @param referenceName The name of the reference. Must not be <code>null</code>.
+ * @param value The value of the reference.
+ */
+ public void addReference(final String referenceName, final Object value) {
+ final Object old = ((AntRefTable) references).getReal(referenceName);
+ if (old == value) {
+ // no warning, this is not changing anything
+ return;
+ }
+ if (old != null && !(old instanceof UnknownElement)) {
+ log("Overriding previous definition of reference to " + referenceName,
+ MSG_VERBOSE);
+ }
+ log("Adding reference: " + referenceName, MSG_DEBUG);
+ references.put(referenceName, value);
+ }
+
+ /**
+ * Return a map of the references in the project (String to Object).
+ * The returned hashtable is &quot;live&quot; and so must not be modified.
+ *
+ * @return a map of the references in the project (String to Object).
+ */
+ public Hashtable<String, Object> getReferences() {
+ return references;
+ }
+
+ /**
+ * Does the project know this reference?
+ *
+ * @since Ant 1.8.0
+ */
+ public boolean hasReference(final String key) {
+ return references.containsKey(key);
+ }
+
+ /**
+ * Return a map of the references in the project (String to
+ * Object). The returned hashtable is a copy of the
+ * &quot;live&quot; references.
+ *
+ * @return a map of the references in the project (String to Object).
+ *
+ * @since Ant 1.8.1
+ */
+ public Map<String, Object> getCopyOfReferences() {
+ return new HashMap<String, Object>(references);
+ }
+
+ /**
+ * Look up a reference by its key (ID).
+ *
+ * @param key The key for the desired reference.
+ * Must not be <code>null</code>.
+ *
+ * @return the reference with the specified ID, or <code>null</code> if
+ * there is no such reference in the project, with type inference.
+ */
+ public <T> T getReference(final String key) {
+ @SuppressWarnings("unchecked")
+ final T ret = (T) references.get(key);
+ if (ret != null) {
+ return ret;
+ }
+ if (!key.equals(MagicNames.REFID_PROPERTY_HELPER)) {
+ try {
+ if (PropertyHelper.getPropertyHelper(this).containsProperties(key)) {
+ log("Unresolvable reference " + key
+ + " might be a misuse of property expansion syntax.", MSG_WARN);
+ }
+ } catch (final Exception e) {
+ //ignore
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Return a description of the type of the given element, with
+ * special handling for instances of tasks and data types.
+ * <p>
+ * This is useful for logging purposes.
+ *
+ * @param element The element to describe.
+ * Must not be <code>null</code>.
+ *
+ * @return a description of the element type.
+ *
+ * @since 1.95, Ant 1.5
+ */
+ public String getElementName(final Object element) {
+ return ComponentHelper.getComponentHelper(this).getElementName(element);
+ }
+
+ /**
+ * Send a &quot;build started&quot; event
+ * to the build listeners for this project.
+ */
+ public void fireBuildStarted() {
+ final BuildEvent event = new BuildEvent(this);
+ final BuildListener[] currListeners = listeners;
+ for (int i = 0; i < currListeners.length; i++) {
+ currListeners[i].buildStarted(event);
+ }
+ }
+
+ /**
+ * Send a &quot;build finished&quot; event to the build listeners
+ * for this project.
+ * @param exception an exception indicating a reason for a build
+ * failure. May be <code>null</code>, indicating
+ * a successful build.
+ */
+ public void fireBuildFinished(final Throwable exception) {
+ final BuildEvent event = new BuildEvent(this);
+ event.setException(exception);
+ final BuildListener[] currListeners = listeners;
+ for (int i = 0; i < currListeners.length; i++) {
+ currListeners[i].buildFinished(event);
+ }
+ // Inform IH to clear the cache
+ IntrospectionHelper.clearCache();
+ }
+
+ /**
+ * Send a &quot;subbuild started&quot; event to the build listeners for
+ * this project.
+ *
+ * @since Ant 1.6.2
+ */
+ public void fireSubBuildStarted() {
+ final BuildEvent event = new BuildEvent(this);
+ final BuildListener[] currListeners = listeners;
+ for (int i = 0; i < currListeners.length; i++) {
+ if (currListeners[i] instanceof SubBuildListener) {
+ ((SubBuildListener) currListeners[i]).subBuildStarted(event);
+ }
+ }
+ }
+
+ /**
+ * Send a &quot;subbuild finished&quot; event to the build listeners for
+ * this project.
+ * @param exception an exception indicating a reason for a build
+ * failure. May be <code>null</code>, indicating
+ * a successful build.
+ *
+ * @since Ant 1.6.2
+ */
+ public void fireSubBuildFinished(final Throwable exception) {
+ final BuildEvent event = new BuildEvent(this);
+ event.setException(exception);
+ final BuildListener[] currListeners = listeners;
+ for (int i = 0; i < currListeners.length; i++) {
+ if (currListeners[i] instanceof SubBuildListener) {
+ ((SubBuildListener) currListeners[i]).subBuildFinished(event);
+ }
+ }
+ }
+
+ /**
+ * Send a &quot;target started&quot; event to the build listeners
+ * for this project.
+ *
+ * @param target The target which is starting to build.
+ * Must not be <code>null</code>.
+ */
+ protected void fireTargetStarted(final Target target) {
+ final BuildEvent event = new BuildEvent(target);
+ final BuildListener[] currListeners = listeners;
+ for (int i = 0; i < currListeners.length; i++) {
+ currListeners[i].targetStarted(event);
+ }
+
+ }
+
+ /**
+ * Send a &quot;target finished&quot; event to the build listeners
+ * for this project.
+ *
+ * @param target The target which has finished building.
+ * Must not be <code>null</code>.
+ * @param exception an exception indicating a reason for a build
+ * failure. May be <code>null</code>, indicating
+ * a successful build.
+ */
+ protected void fireTargetFinished(final Target target, final Throwable exception) {
+ final BuildEvent event = new BuildEvent(target);
+ event.setException(exception);
+ final BuildListener[] currListeners = listeners;
+ for (int i = 0; i < currListeners.length; i++) {
+ currListeners[i].targetFinished(event);
+ }
+
+ }
+
+ /**
+ * Send a &quot;task started&quot; event to the build listeners
+ * for this project.
+ *
+ * @param task The target which is starting to execute.
+ * Must not be <code>null</code>.
+ */
+ protected void fireTaskStarted(final Task task) {
+ // register this as the current task on the current thread.
+ registerThreadTask(Thread.currentThread(), task);
+ final BuildEvent event = new BuildEvent(task);
+ final BuildListener[] currListeners = listeners;
+ for (int i = 0; i < currListeners.length; i++) {
+ currListeners[i].taskStarted(event);
+ }
+ }
+
+ /**
+ * Send a &quot;task finished&quot; event to the build listeners for this
+ * project.
+ *
+ * @param task The task which has finished executing.
+ * Must not be <code>null</code>.
+ * @param exception an exception indicating a reason for a build
+ * failure. May be <code>null</code>, indicating
+ * a successful build.
+ */
+ protected void fireTaskFinished(final Task task, final Throwable exception) {
+ registerThreadTask(Thread.currentThread(), null);
+ System.out.flush();
+ System.err.flush();
+ final BuildEvent event = new BuildEvent(task);
+ event.setException(exception);
+ final BuildListener[] currListeners = listeners;
+ for (int i = 0; i < currListeners.length; i++) {
+ currListeners[i].taskFinished(event);
+ }
+
+ }
+
+ /**
+ * Send a &quot;message logged&quot; event to the build listeners
+ * for this project.
+ *
+ * @param event The event to send. This should be built up with the
+ * appropriate task/target/project by the caller, so that
+ * this method can set the message and priority, then send
+ * the event. Must not be <code>null</code>.
+ * @param message The message to send. Should not be <code>null</code>.
+ * @param priority The priority of the message.
+ */
+ private void fireMessageLoggedEvent(final BuildEvent event, String message,
+ final int priority) {
+
+ if (message == null) {
+ message = String.valueOf(message);
+ }
+ if (message.endsWith(StringUtils.LINE_SEP)) {
+ final int endIndex = message.length() - StringUtils.LINE_SEP.length();
+ event.setMessage(message.substring(0, endIndex), priority);
+ } else {
+ event.setMessage(message, priority);
+ }
+ if (isLoggingMessage.get() != Boolean.FALSE) {
+ /*
+ * One of the Listeners has attempted to access
+ * System.err or System.out.
+ *
+ * We used to throw an exception in this case, but
+ * sometimes Listeners can't prevent it(like our own
+ * Log4jListener which invokes getLogger() which in
+ * turn wants to write to the console).
+ *
+ * @see http://marc.theaimsgroup.com/?t=110538624200006&r=1&w=2
+ *
+ * We now (Ant 1.6.3 and later) simply swallow the message.
+ */
+ return;
+ }
+ try {
+ isLoggingMessage.set(Boolean.TRUE);
+ final BuildListener[] currListeners = listeners;
+ for (int i = 0; i < currListeners.length; i++) {
+ currListeners[i].messageLogged(event);
+ }
+ } finally {
+ isLoggingMessage.set(Boolean.FALSE);
+ }
+ }
+
+ /**
+ * Send a &quot;message logged&quot; project level event
+ * to the build listeners for this project.
+ *
+ * @param project The project generating the event.
+ * Should not be <code>null</code>.
+ * @param message The message to send. Should not be <code>null</code>.
+ * @param priority The priority of the message.
+ */
+ protected void fireMessageLogged(final Project project, final String message,
+ final int priority) {
+ fireMessageLogged(project, message, null, priority);
+ }
+
+ /**
+ * Send a &quot;message logged&quot; project level event
+ * to the build listeners for this project.
+ *
+ * @param project The project generating the event.
+ * Should not be <code>null</code>.
+ * @param message The message to send. Should not be <code>null</code>.
+ * @param throwable The exception that caused this message. May be <code>null</code>.
+ * @param priority The priority of the message.
+ * @since 1.7
+ */
+ protected void fireMessageLogged(final Project project, final String message,
+ final Throwable throwable, final int priority) {
+ final BuildEvent event = new BuildEvent(project);
+ event.setException(throwable);
+ fireMessageLoggedEvent(event, message, priority);
+ }
+
+ /**
+ * Send a &quot;message logged&quot; target level event
+ * to the build listeners for this project.
+ *
+ * @param target The target generating the event.
+ * Must not be <code>null</code>.
+ * @param message The message to send. Should not be <code>null</code>.
+ * @param priority The priority of the message.
+ */
+ protected void fireMessageLogged(final Target target, final String message,
+ final int priority) {
+ fireMessageLogged(target, message, null, priority);
+ }
+
+ /**
+ * Send a &quot;message logged&quot; target level event
+ * to the build listeners for this project.
+ *
+ * @param target The target generating the event.
+ * Must not be <code>null</code>.
+ * @param message The message to send. Should not be <code>null</code>.
+ * @param throwable The exception that caused this message. May be <code>null</code>.
+ * @param priority The priority of the message.
+ * @since 1.7
+ */
+ protected void fireMessageLogged(final Target target, final String message,
+ final Throwable throwable, final int priority) {
+ final BuildEvent event = new BuildEvent(target);
+ event.setException(throwable);
+ fireMessageLoggedEvent(event, message, priority);
+ }
+
+ /**
+ * Send a &quot;message logged&quot; task level event
+ * to the build listeners for this project.
+ *
+ * @param task The task generating the event.
+ * Must not be <code>null</code>.
+ * @param message The message to send. Should not be <code>null</code>.
+ * @param priority The priority of the message.
+ */
+ protected void fireMessageLogged(final Task task, final String message, final int priority) {
+ fireMessageLogged(task, message, null, priority);
+ }
+
+ /**
+ * Send a &quot;message logged&quot; task level event
+ * to the build listeners for this project.
+ *
+ * @param task The task generating the event.
+ * Must not be <code>null</code>.
+ * @param message The message to send. Should not be <code>null</code>.
+ * @param throwable The exception that caused this message. May be <code>null</code>.
+ * @param priority The priority of the message.
+ * @since 1.7
+ */
+ protected void fireMessageLogged(final Task task, final String message,
+ final Throwable throwable, final int priority) {
+ final BuildEvent event = new BuildEvent(task);
+ event.setException(throwable);
+ fireMessageLoggedEvent(event, message, priority);
+ }
+
+ /**
+ * Register a task as the current task for a thread.
+ * If the task is null, the thread's entry is removed.
+ *
+ * @param thread the thread on which the task is registered.
+ * @param task the task to be registered.
+ * @since Ant 1.5
+ */
+ public void registerThreadTask(final Thread thread, final Task task) {
+ synchronized (threadTasks) {
+ if (task != null) {
+ threadTasks.put(thread, task);
+ threadGroupTasks.put(thread.getThreadGroup(), task);
+ } else {
+ threadTasks.remove(thread);
+ threadGroupTasks.remove(thread.getThreadGroup());
+ }
+ }
+ }
+
+ /**
+ * Get the current task associated with a thread, if any.
+ *
+ * @param thread the thread for which the task is required.
+ * @return the task which is currently registered for the given thread or
+ * null if no task is registered.
+ */
+ public Task getThreadTask(final Thread thread) {
+ synchronized (threadTasks) {
+ Task task = threadTasks.get(thread);
+ if (task == null) {
+ ThreadGroup group = thread.getThreadGroup();
+ while (task == null && group != null) {
+ task = threadGroupTasks.get(group);
+ group = group.getParent();
+ }
+ }
+ return task;
+ }
+ }
+
+
+ // Should move to a separate public class - and have API to add
+ // listeners, etc.
+ private static class AntRefTable extends Hashtable<String, Object> {
+ private static final long serialVersionUID = 1L;
+
+ AntRefTable() {
+ super();
+ }
+
+ /** Returns the unmodified original object.
+ * This method should be called internally to
+ * get the &quot;real&quot; object.
+ * The normal get method will do the replacement
+ * of UnknownElement (this is similar with the JDNI
+ * refs behavior).
+ */
+ private Object getReal(final Object key) {
+ return super.get(key);
+ }
+
+ /** Get method for the reference table.
+ * It can be used to hook dynamic references and to modify
+ * some references on the fly--for example for delayed
+ * evaluation.
+ *
+ * It is important to make sure that the processing that is
+ * done inside is not calling get indirectly.
+ *
+ * @param key lookup key.
+ * @return mapped value.
+ */
+ @Override
+ public Object get(final Object key) {
+ Object o = getReal(key);
+ if (o instanceof UnknownElement) {
+ // Make sure that
+ final UnknownElement ue = (UnknownElement) o;
+ ue.maybeConfigure();
+ o = ue.getRealThing();
+ }
+ return o;
+ }
+ }
+
+ /**
+ * Set a reference to this Project on the parameterized object.
+ * Need to set the project before other set/add elements
+ * are called.
+ * @param obj the object to invoke setProject(this) on.
+ */
+ public final void setProjectReference(final Object obj) {
+ if (obj instanceof ProjectComponent) {
+ ((ProjectComponent) obj).setProject(this);
+ return;
+ }
+ try {
+ final Method method =
+ obj.getClass().getMethod(
+ "setProject", new Class[] {Project.class});
+ if (method != null) {
+ method.invoke(obj, new Object[] {this});
+ }
+ } catch (final Throwable e) {
+ // ignore this if the object does not have
+ // a set project method or the method
+ // is private/protected.
+ }
+ }
+
+ /**
+ * Resolve the file relative to the project's basedir and return it as a
+ * FileResource.
+ * @param name the name of the file to resolve.
+ * @return the file resource.
+ * @since Ant 1.7
+ */
+ public Resource getResource(final String name) {
+ return new FileResource(getBaseDir(), name);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/ProjectComponent.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/ProjectComponent.java
new file mode 100644
index 00000000..ad92a317
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/ProjectComponent.java
@@ -0,0 +1,169 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant;
+
+/**
+ * Base class for components of a project, including tasks and data types.
+ * Provides common facilities.
+ *
+ */
+public abstract class ProjectComponent implements Cloneable {
+
+ // CheckStyle:VisibilityModifier OFF - bc
+ /**
+ * Project object of this component.
+ * @deprecated since 1.6.x.
+ * You should not be directly accessing this variable directly.
+ * You should access project object via the getProject()
+ * or setProject() accessor/mutators.
+ */
+ protected Project project;
+
+ /**
+ * Location within the build file of this task definition.
+ * @deprecated since 1.6.x.
+ * You should not be accessing this variable directly.
+ * Please use the {@link #getLocation()} method.
+ */
+ protected Location location = Location.UNKNOWN_LOCATION;
+
+ /**
+ * Description of this component, if any.
+ * @deprecated since 1.6.x.
+ * You should not be accessing this variable directly.
+ */
+ protected String description;
+ // CheckStyle:VisibilityModifier ON
+
+ /** Sole constructor. */
+ public ProjectComponent() {
+ }
+
+ /**
+ * Sets the project object of this component. This method is used by
+ * Project when a component is added to it so that the component has
+ * access to the functions of the project. It should not be used
+ * for any other purpose.
+ *
+ * @param project Project in whose scope this component belongs.
+ * Must not be <code>null</code>.
+ */
+ public void setProject(Project project) {
+ this.project = project;
+ }
+
+ /**
+ * Returns the project to which this component belongs.
+ *
+ * @return the components's project.
+ */
+ public Project getProject() {
+ return project;
+ }
+
+ /**
+ * Returns the file/location where this task was defined.
+ *
+ * @return the file/location where this task was defined.
+ * Should not return <code>null</code>. Location.UNKNOWN_LOCATION
+ * is used for unknown locations.
+ *
+ * @see Location#UNKNOWN_LOCATION
+ */
+ public Location getLocation() {
+ return location;
+ }
+
+ /**
+ * Sets the file/location where this task was defined.
+ *
+ * @param location The file/location where this task was defined.
+ * Should not be <code>null</code>--use
+ * Location.UNKNOWN_LOCATION if the location isn't known.
+ *
+ * @see Location#UNKNOWN_LOCATION
+ */
+ public void setLocation(Location location) {
+ this.location = location;
+ }
+
+ /**
+ * Sets a description of the current action. This may be used for logging
+ * purposes.
+ *
+ * @param desc Description of the current action.
+ * May be <code>null</code>, indicating that no description is
+ * available.
+ *
+ */
+ public void setDescription(String desc) {
+ description = desc;
+ }
+
+ /**
+ * Returns the description of the current action.
+ *
+ * @return the description of the current action, or <code>null</code> if
+ * no description is available.
+ */
+ public String getDescription() {
+ return description;
+ }
+
+ /**
+ * Logs a message with the default (INFO) priority.
+ *
+ * @param msg The message to be logged. Should not be <code>null</code>.
+ */
+ public void log(String msg) {
+ log(msg, Project.MSG_INFO);
+ }
+
+ /**
+ * Logs a message with the given priority.
+ *
+ * @param msg The message to be logged. Should not be <code>null</code>.
+ * @param msgLevel the message priority at which this message is
+ * to be logged.
+ */
+ public void log(String msg, int msgLevel) {
+ if (getProject() != null) {
+ getProject().log(msg, msgLevel);
+ } else {
+ // 'reasonable' default, if the component is used without
+ // a Project ( for example as a standalone Bean ).
+ // Most ant components can be used this way.
+ if (msgLevel <= Project.MSG_INFO) {
+ System.err.println(msg);
+ }
+ }
+ }
+
+ /**
+ * @since Ant 1.7
+ * @return a shallow copy of this projectcomponent.
+ * @throws CloneNotSupportedException does not happen,
+ * but is declared to allow subclasses to do so.
+ */
+ public Object clone() throws CloneNotSupportedException {
+ ProjectComponent pc = (ProjectComponent) super.clone();
+ pc.setLocation(getLocation());
+ pc.setProject(getProject());
+ return pc;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/ProjectHelper.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/ProjectHelper.java
new file mode 100644
index 00000000..c6eaa077
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/ProjectHelper.java
@@ -0,0 +1,698 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant;
+
+import java.io.File;
+import java.util.Hashtable;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Locale;
+import java.util.Vector;
+
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.resources.FileResource;
+import org.apache.tools.ant.util.LoaderUtils;
+import org.xml.sax.AttributeList;
+
+/**
+ * Configures a Project (complete with Targets and Tasks) based on
+ * a build file. It'll rely on a plugin to do the actual processing
+ * of the file.
+ * <p>
+ * This class also provide static wrappers for common introspection.
+ */
+public class ProjectHelper {
+ /** The URI for ant name space */
+ public static final String ANT_CORE_URI = "antlib:org.apache.tools.ant";
+
+ /** The URI for antlib current definitions */
+ public static final String ANT_CURRENT_URI = "ant:current";
+
+ /** The URI for ant specific attributes
+ * @since Ant 1.9.1
+ * */
+ public static final String ANT_ATTRIBUTE_URI = "ant:attribute";
+
+ /** The URI for defined types/tasks - the format is antlib:&lt;package&gt; */
+ public static final String ANTLIB_URI = "antlib:";
+
+ /** Polymorphic attribute */
+ public static final String ANT_TYPE = "ant-type";
+
+ /**
+ * Name of JVM system property which provides the name of the
+ * ProjectHelper class to use.
+ */
+ public static final String HELPER_PROPERTY = MagicNames.PROJECT_HELPER_CLASS;
+
+ /**
+ * The service identifier in jars which provide Project Helper
+ * implementations.
+ */
+ public static final String SERVICE_ID = MagicNames.PROJECT_HELPER_SERVICE;
+
+ /**
+ * name of project helper reference that we add to a project
+ */
+ public static final String PROJECTHELPER_REFERENCE = MagicNames.REFID_PROJECT_HELPER;
+
+ /**
+ * constant to denote use project name as target prefix
+ * @since Ant 1.9.1
+ */
+ public static final String USE_PROJECT_NAME_AS_TARGET_PREFIX = "USE_PROJECT_NAME_AS_TARGET_PREFIX";
+
+ /**
+ * Configures the project with the contents of the specified build file.
+ *
+ * @param project The project to configure. Must not be <code>null</code>.
+ * @param buildFile A build file giving the project's configuration.
+ * Must not be <code>null</code>.
+ *
+ * @exception BuildException if the configuration is invalid or cannot be read
+ */
+ public static void configureProject(Project project, File buildFile) throws BuildException {
+ FileResource resource = new FileResource(buildFile);
+ ProjectHelper helper = ProjectHelperRepository.getInstance().getProjectHelperForBuildFile(resource);
+ project.addReference(PROJECTHELPER_REFERENCE, helper);
+ helper.parse(project, buildFile);
+ }
+
+ /**
+ * Possible value for target's onMissingExtensionPoint attribute. It determines how to deal with
+ * targets that want to extend missing extension-points.
+ * <p>
+ * This class behaves like a Java 1.5 Enum class.
+ *
+ * @since 1.8.2
+ */
+ public static final class OnMissingExtensionPoint {
+
+ /** fail if the extension-point is not defined */
+ public static final OnMissingExtensionPoint FAIL = new OnMissingExtensionPoint(
+ "fail");
+
+ /** warn if the extension-point is not defined */
+ public static final OnMissingExtensionPoint WARN = new OnMissingExtensionPoint(
+ "warn");
+
+ /** ignore the extensionOf attribute if the extension-point is not defined */
+ public static final OnMissingExtensionPoint IGNORE = new OnMissingExtensionPoint(
+ "ignore");
+
+ private static final OnMissingExtensionPoint[] values = new OnMissingExtensionPoint[] {
+ FAIL, WARN, IGNORE };
+
+ private final String name;
+
+ private OnMissingExtensionPoint(String name) {
+ this.name = name;
+ }
+
+ public String name() {
+ return name;
+ }
+
+ public String toString() {
+ return name;
+ }
+
+ public static OnMissingExtensionPoint valueOf(String name) {
+ if (name == null) {
+ throw new NullPointerException();
+ }
+ for (int i = 0; i < values.length; i++) {
+ if (name.equals(values[i].name())) {
+ return values[i];
+ }
+ }
+ throw new IllegalArgumentException(
+ "Unknown onMissingExtensionPoint " + name);
+ }
+ }
+
+ /** Default constructor */
+ public ProjectHelper() {
+ }
+
+ // -------------------- Common properties --------------------
+ // The following properties are required by import ( and other tasks
+ // that read build files using ProjectHelper ).
+
+ private Vector<Object> importStack = new Vector<Object>();
+ private List<String[]> extensionStack = new LinkedList<String[]>();
+
+ /**
+ * Import stack.
+ * Used to keep track of imported files. Error reporting should
+ * display the import path.
+ *
+ * @return the stack of import source objects.
+ */
+ public Vector<Object> getImportStack() {
+ return importStack;
+ }
+
+ /**
+ * Extension stack.
+ * Used to keep track of targets that extend extension points.
+ *
+ * @return a list of three element string arrays where the first
+ * element is the name of the extensionpoint, the second the name
+ * of the target and the third the name of the enum like class
+ * {@link OnMissingExtensionPoint}.
+ */
+ public List<String[]> getExtensionStack() {
+ return extensionStack;
+ }
+
+ private static final ThreadLocal<String> targetPrefix = new ThreadLocal<String>();
+
+ /**
+ * The prefix to prepend to imported target names.
+ *
+ * <p>May be set by &lt;import&gt;'s as attribute.</p>
+ *
+ * @return the configured prefix or null
+ *
+ * @since Ant 1.8.0
+ */
+ public static String getCurrentTargetPrefix() {
+ return targetPrefix.get();
+ }
+
+ /**
+ * Sets the prefix to prepend to imported target names.
+ *
+ * @since Ant 1.8.0
+ */
+ public static void setCurrentTargetPrefix(String prefix) {
+ targetPrefix.set(prefix);
+ }
+
+ private static final ThreadLocal<String> prefixSeparator = new ThreadLocal<String>() {
+ protected String initialValue() {
+ return ".";
+ }
+ };
+
+ /**
+ * The separator between the prefix and the target name.
+ *
+ * <p>May be set by &lt;import&gt;'s prefixSeparator attribute.</p>
+ *
+ * @since Ant 1.8.0
+ */
+ public static String getCurrentPrefixSeparator() {
+ return prefixSeparator.get();
+ }
+
+ /**
+ * Sets the separator between the prefix and the target name.
+ *
+ * @since Ant 1.8.0
+ */
+ public static void setCurrentPrefixSeparator(String sep) {
+ prefixSeparator.set(sep);
+ }
+
+ private static final ThreadLocal<Boolean> inIncludeMode = new ThreadLocal<Boolean>() {
+ protected Boolean initialValue() {
+ return Boolean.FALSE;
+ }
+ };
+
+ /**
+ * Whether the current file should be read in include as opposed
+ * to import mode.
+ *
+ * <p>In include mode included targets are only known by their
+ * prefixed names and their depends lists get rewritten so that
+ * all dependencies get the prefix as well.</p>
+ *
+ * <p>In import mode imported targets are known by an adorned as
+ * well as a prefixed name and the unadorned target may be
+ * overwritten in the importing build file. The depends list of
+ * the imported targets is not modified at all.</p>
+ *
+ * @since Ant 1.8.0
+ */
+ public static boolean isInIncludeMode() {
+ return Boolean.TRUE.equals(inIncludeMode.get());
+ }
+
+ /**
+ * Sets whether the current file should be read in include as
+ * opposed to import mode.
+ *
+ * @since Ant 1.8.0
+ */
+ public static void setInIncludeMode(boolean includeMode) {
+ inIncludeMode.set(Boolean.valueOf(includeMode));
+ }
+
+ // -------------------- Parse method --------------------
+ /**
+ * Parses the project file, configuring the project as it goes.
+ *
+ * @param project The project for the resulting ProjectHelper to configure.
+ * Must not be <code>null</code>.
+ * @param source The source for XML configuration. A helper must support
+ * at least File, for backward compatibility. Helpers may
+ * support URL, InputStream, etc or specialized types.
+ *
+ * @since Ant1.5
+ * @exception BuildException if the configuration is invalid or cannot
+ * be read
+ */
+ public void parse(Project project, Object source) throws BuildException {
+ throw new BuildException("ProjectHelper.parse() must be implemented "
+ + "in a helper plugin " + this.getClass().getName());
+ }
+
+ /**
+ * Get the first project helper found in the classpath
+ *
+ * @return an project helper, never <code>null</code>
+ * @see org.apache.tools.ant.ProjectHelperRepository#getHelpers()
+ */
+ public static ProjectHelper getProjectHelper() {
+ return (ProjectHelper) ProjectHelperRepository.getInstance().getHelpers().next();
+ }
+
+ /**
+ * JDK1.1 compatible access to the context class loader. Cut &amp; paste from JAXP.
+ *
+ * @deprecated since 1.6.x.
+ * Use LoaderUtils.getContextClassLoader()
+ *
+ * @return the current context class loader, or <code>null</code>
+ * if the context class loader is unavailable.
+ */
+ public static ClassLoader getContextClassLoader() {
+ return LoaderUtils.isContextLoaderAvailable() ? LoaderUtils.getContextClassLoader() : null;
+ }
+
+ // -------------------- Static utils, used by most helpers ----------------
+
+ /**
+ * Configures an object using an introspection handler.
+ *
+ * @param target The target object to be configured.
+ * Must not be <code>null</code>.
+ * @param attrs A list of attributes to configure within the target.
+ * Must not be <code>null</code>.
+ * @param project The project containing the target.
+ * Must not be <code>null</code>.
+ *
+ * @deprecated since 1.6.x.
+ * Use IntrospectionHelper for each property.
+ *
+ * @exception BuildException if any of the attributes can't be handled by
+ * the target
+ */
+ public static void configure(Object target, AttributeList attrs,
+ Project project) throws BuildException {
+ if (target instanceof TypeAdapter) {
+ target = ((TypeAdapter) target).getProxy();
+ }
+ IntrospectionHelper ih = IntrospectionHelper.getHelper(project, target.getClass());
+
+ for (int i = 0, length = attrs.getLength(); i < length; i++) {
+ // reflect these into the target
+ String value = replaceProperties(project, attrs.getValue(i), project.getProperties());
+ try {
+ ih.setAttribute(project, target, attrs.getName(i).toLowerCase(Locale.ENGLISH), value);
+ } catch (BuildException be) {
+ // id attribute must be set externally
+ if (!attrs.getName(i).equals("id")) {
+ throw be;
+ }
+ }
+ }
+ }
+
+ /**
+ * Adds the content of #PCDATA sections to an element.
+ *
+ * @param project The project containing the target.
+ * Must not be <code>null</code>.
+ * @param target The target object to be configured.
+ * Must not be <code>null</code>.
+ * @param buf A character array of the text within the element.
+ * Will not be <code>null</code>.
+ * @param start The start element in the array.
+ * @param count The number of characters to read from the array.
+ *
+ * @exception BuildException if the target object doesn't accept text
+ */
+ public static void addText(Project project, Object target, char[] buf,
+ int start, int count) throws BuildException {
+ addText(project, target, new String(buf, start, count));
+ }
+
+ /**
+ * Adds the content of #PCDATA sections to an element.
+ *
+ * @param project The project containing the target.
+ * Must not be <code>null</code>.
+ * @param target The target object to be configured.
+ * Must not be <code>null</code>.
+ * @param text Text to add to the target.
+ * May be <code>null</code>, in which case this
+ * method call is a no-op.
+ *
+ * @exception BuildException if the target object doesn't accept text
+ */
+ public static void addText(Project project, Object target, String text)
+ throws BuildException {
+
+ if (text == null) {
+ return;
+ }
+ if (target instanceof TypeAdapter) {
+ target = ((TypeAdapter) target).getProxy();
+ }
+ IntrospectionHelper.getHelper(project, target.getClass()).addText(project, target, text);
+ }
+
+ /**
+ * Stores a configured child element within its parent object.
+ *
+ * @param project Project containing the objects.
+ * May be <code>null</code>.
+ * @param parent Parent object to add child to.
+ * Must not be <code>null</code>.
+ * @param child Child object to store in parent.
+ * Should not be <code>null</code>.
+ * @param tag Name of element which generated the child.
+ * May be <code>null</code>, in which case
+ * the child is not stored.
+ */
+ public static void storeChild(Project project, Object parent, Object child, String tag) {
+ IntrospectionHelper ih = IntrospectionHelper.getHelper(project, parent.getClass());
+ ih.storeElement(project, parent, child, tag);
+ }
+
+ /**
+ * Replaces <code>${xxx}</code> style constructions in the given value with
+ * the string value of the corresponding properties.
+ *
+ * @param project The project containing the properties to replace.
+ * Must not be <code>null</code>.
+ *
+ * @param value The string to be scanned for property references.
+ * May be <code>null</code>.
+ *
+ * @exception BuildException if the string contains an opening
+ * <code>${</code> without a closing
+ * <code>}</code>
+ * @return the original string with the properties replaced, or
+ * <code>null</code> if the original string is <code>null</code>.
+ *
+ * @deprecated since 1.6.x.
+ * Use project.replaceProperties().
+ * @since 1.5
+ */
+ public static String replaceProperties(Project project, String value) throws BuildException {
+ // needed since project properties are not accessible
+ return project.replaceProperties(value);
+ }
+
+ /**
+ * Replaces <code>${xxx}</code> style constructions in the given value
+ * with the string value of the corresponding data types.
+ *
+ * @param project The container project. This is used solely for
+ * logging purposes. Must not be <code>null</code>.
+ * @param value The string to be scanned for property references.
+ * May be <code>null</code>, in which case this
+ * method returns immediately with no effect.
+ * @param keys Mapping (String to Object) of property names to their
+ * values. Must not be <code>null</code>.
+ *
+ * @exception BuildException if the string contains an opening
+ * <code>${</code> without a closing
+ * <code>}</code>
+ * @return the original string with the properties replaced, or
+ * <code>null</code> if the original string is <code>null</code>.
+ * @deprecated since 1.6.x.
+ * Use PropertyHelper.
+ */
+ public static String replaceProperties(Project project, String value, Hashtable<String, Object> keys)
+ throws BuildException {
+ PropertyHelper ph = PropertyHelper.getPropertyHelper(project);
+ return ph.replaceProperties(null, value, keys);
+ }
+
+ /**
+ * Parses a string containing <code>${xxx}</code> style property
+ * references into two lists. The first list is a collection
+ * of text fragments, while the other is a set of string property names.
+ * <code>null</code> entries in the first list indicate a property
+ * reference from the second list.
+ *
+ * <p>As of Ant 1.8.0 this method is never invoked by any code
+ * inside of Ant itself.</p>
+ *
+ * @param value Text to parse. Must not be <code>null</code>.
+ * @param fragments List to add text fragments to.
+ * Must not be <code>null</code>.
+ * @param propertyRefs List to add property names to.
+ * Must not be <code>null</code>.
+ *
+ * @deprecated since 1.6.x.
+ * Use PropertyHelper.
+ * @exception BuildException if the string contains an opening
+ * <code>${</code> without a closing <code>}</code>
+ */
+ public static void parsePropertyString(String value, Vector<String> fragments, Vector<String> propertyRefs)
+ throws BuildException {
+ PropertyHelper.parsePropertyStringDefault(value, fragments, propertyRefs);
+ }
+
+ /**
+ * Map a namespaced {uri,name} to an internal string format.
+ * For BC purposes the names from the ant core uri will be
+ * mapped to "name", other names will be mapped to
+ * uri + ":" + name.
+ * @param uri The namespace URI
+ * @param name The localname
+ * @return The stringified form of the ns name
+ */
+ public static String genComponentName(String uri, String name) {
+ if (uri == null || uri.equals("") || uri.equals(ANT_CORE_URI)) {
+ return name;
+ }
+ return uri + ":" + name;
+ }
+
+ /**
+ * extract a uri from a component name
+ *
+ * @param componentName The stringified form for {uri, name}
+ * @return The uri or "" if not present
+ */
+ public static String extractUriFromComponentName(String componentName) {
+ if (componentName == null) {
+ return "";
+ }
+ int index = componentName.lastIndexOf(':');
+ if (index == -1) {
+ return "";
+ }
+ return componentName.substring(0, index);
+ }
+
+ /**
+ * extract the element name from a component name
+ *
+ * @param componentName The stringified form for {uri, name}
+ * @return The element name of the component
+ */
+ public static String extractNameFromComponentName(String componentName) {
+ int index = componentName.lastIndexOf(':');
+ if (index == -1) {
+ return componentName;
+ }
+ return componentName.substring(index + 1);
+ }
+
+ /**
+ * Convert an attribute namespace to a "component name".
+ * @param ns the xml namespace uri.
+ * @return the converted value.
+ * @since Ant 1.9.1
+ */
+ public static String nsToComponentName(String ns) {
+ return "attribute namespace:" + ns;
+ }
+
+ /**
+ * Add location to build exception.
+ * @param ex the build exception, if the build exception
+ * does not include
+ * @param newLocation the location of the calling task (may be null)
+ * @return a new build exception based in the build exception with
+ * location set to newLocation. If the original exception
+ * did not have a location, just return the build exception
+ */
+ public static BuildException addLocationToBuildException(
+ BuildException ex, Location newLocation) {
+ if (ex.getLocation() == null || ex.getMessage() == null) {
+ return ex;
+ }
+ String errorMessage
+ = "The following error occurred while executing this line:"
+ + System.getProperty("line.separator")
+ + ex.getLocation().toString()
+ + ex.getMessage();
+ if (newLocation == null) {
+ return new BuildException(errorMessage, ex);
+ }
+ return new BuildException(errorMessage, ex, newLocation);
+ }
+
+ /**
+ * Whether this instance of ProjectHelper can parse an Antlib
+ * descriptor given by the URL and return its content as an
+ * UnknownElement ready to be turned into an Antlib task.
+ *
+ * <p>This method should not try to parse the content of the
+ * descriptor, the URL is only given as an argument to allow
+ * subclasses to decide whether they can support a given URL
+ * scheme or not.</p>
+ *
+ * <p>Subclasses that return true in this method must also
+ * override {@link #parseAntlibDescriptor
+ * parseAntlibDescriptor}.</p>
+ *
+ * <p>This implementation returns false.</p>
+ *
+ * @since Ant 1.8.0
+ */
+ public boolean canParseAntlibDescriptor(Resource r) {
+ return false;
+ }
+
+ /**
+ * Parse the given URL as an antlib descriptor and return the
+ * content as something that can be turned into an Antlib task.
+ *
+ * @since ant 1.8.0
+ */
+ public UnknownElement parseAntlibDescriptor(Project containingProject,
+ Resource source) {
+ throw new BuildException("can't parse antlib descriptors");
+ }
+
+ /**
+ * Check if the helper supports the kind of file. Some basic check on the
+ * extension's file should be done here.
+ *
+ * @param buildFile
+ * the file expected to be parsed (never <code>null</code>)
+ * @return true if the helper supports it
+ * @since Ant 1.8.0
+ */
+ public boolean canParseBuildFile(Resource buildFile) {
+ return true;
+ }
+
+ /**
+ * The file name of the build script to be parsed if none specified on the command line
+ *
+ * @return the name of the default file (never <code>null</code>)
+ * @since Ant 1.8.0
+ */
+ public String getDefaultBuildFile() {
+ return Main.DEFAULT_BUILD_FILENAME;
+ }
+
+ /**
+ * Check extensionStack and inject all targets having extensionOf attributes
+ * into extensionPoint.
+ * <p>
+ * This method allow you to defer injection and have a powerful control of
+ * extensionPoint wiring.
+ * </p>
+ * <p>
+ * This should be invoked by each concrete implementation of ProjectHelper
+ * when the root "buildfile" and all imported/included buildfile are loaded.
+ * </p>
+ *
+ * @param project The project containing the target. Must not be
+ * <code>null</code>.
+ * @exception BuildException if OnMissingExtensionPoint.FAIL and
+ * extensionPoint does not exist
+ * @see OnMissingExtensionPoint
+ * @since 1.9
+ */
+ public void resolveExtensionOfAttributes(Project project)
+ throws BuildException {
+ for (String[] extensionInfo : getExtensionStack()) {
+ String extPointName = extensionInfo[0];
+ String targetName = extensionInfo[1];
+ OnMissingExtensionPoint missingBehaviour = OnMissingExtensionPoint.valueOf(extensionInfo[2]);
+ // if the file has been included or imported, it may have a prefix
+ // we should consider when trying to resolve the target it is
+ // extending
+ String prefixAndSep = extensionInfo.length > 3 ? extensionInfo[3] : null;
+
+ // find the target we're extending
+ Hashtable<String, Target> projectTargets = project.getTargets();
+ Target extPoint = null;
+ if (prefixAndSep == null) {
+ // no prefix - not from an imported/included build file
+ extPoint = projectTargets.get(extPointName);
+ } else {
+ // we have a prefix, which means we came from an include/import
+
+ // FIXME: here we handle no particular level of include. We try
+ // the fully prefixed name, and then the non-prefixed name. But
+ // there might be intermediate project in the import stack,
+ // which prefix should be tested before testing the non-prefix
+ // root name.
+
+ extPoint = projectTargets.get(prefixAndSep + extPointName);
+ if (extPoint == null) {
+ extPoint = projectTargets.get(extPointName);
+ }
+ }
+
+ // make sure we found a point to extend on
+ if (extPoint == null) {
+ String message = "can't add target " + targetName
+ + " to extension-point " + extPointName
+ + " because the extension-point is unknown.";
+ if (missingBehaviour == OnMissingExtensionPoint.FAIL) {
+ throw new BuildException(message);
+ } else if (missingBehaviour == OnMissingExtensionPoint.WARN) {
+ Target t = projectTargets.get(targetName);
+ project.log(t, "Warning: " + message, Project.MSG_WARN);
+ }
+ } else {
+ if (!(extPoint instanceof ExtensionPoint)) {
+ throw new BuildException("referenced target " + extPointName
+ + " is not an extension-point");
+ }
+ extPoint.addDependency(targetName);
+ }
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/ProjectHelperRepository.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/ProjectHelperRepository.java
new file mode 100644
index 00000000..1dd44124
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/ProjectHelperRepository.java
@@ -0,0 +1,337 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant;
+
+import java.io.BufferedReader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.lang.reflect.Constructor;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.tools.ant.helper.ProjectHelper2;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.util.LoaderUtils;
+
+/**
+ * Repository of {@link ProjectHelper} found in the classpath or via
+ * some System properties.
+ *
+ * <p>See the ProjectHelper documentation in the manual.</p>
+ *
+ * @since Ant 1.8.0
+ */
+public class ProjectHelperRepository {
+
+ private static final String DEBUG_PROJECT_HELPER_REPOSITORY =
+ "ant.project-helper-repo.debug";
+
+ // The message log level is not accessible here because everything
+ // is instanciated statically
+ private static final boolean DEBUG =
+ "true".equals(System.getProperty(DEBUG_PROJECT_HELPER_REPOSITORY));
+
+ private static ProjectHelperRepository instance =
+ new ProjectHelperRepository();
+
+ private List<Constructor<? extends ProjectHelper>> helpers = new ArrayList<Constructor<? extends ProjectHelper>>();
+
+ private static Constructor<ProjectHelper2> PROJECTHELPER2_CONSTRUCTOR;
+
+ static {
+ try {
+ PROJECTHELPER2_CONSTRUCTOR = ProjectHelper2.class.getConstructor();
+ } catch (Exception e) {
+ // ProjectHelper2 must be available
+ throw new RuntimeException(e);
+ }
+ }
+
+ public static ProjectHelperRepository getInstance() {
+ return instance;
+ }
+
+ private ProjectHelperRepository() {
+ collectProjectHelpers();
+ }
+
+ private void collectProjectHelpers() {
+ // First, try the system property
+ Constructor<? extends ProjectHelper> projectHelper = getProjectHelperBySystemProperty();
+ registerProjectHelper(projectHelper);
+
+ // A JDK1.3 'service' ( like in JAXP ). That will plug a helper
+ // automatically if in CLASSPATH, with the right META-INF/services.
+ try {
+ ClassLoader classLoader = LoaderUtils.getContextClassLoader();
+ if (classLoader != null) {
+ Enumeration<URL> resources =
+ classLoader.getResources(ProjectHelper.SERVICE_ID);
+ while (resources.hasMoreElements()) {
+ URL resource = resources.nextElement();
+ URLConnection conn = resource.openConnection();
+ conn.setUseCaches(false);
+ projectHelper =
+ getProjectHelperByService(conn.getInputStream());
+ registerProjectHelper(projectHelper);
+ }
+ }
+
+ InputStream systemResource =
+ ClassLoader.getSystemResourceAsStream(ProjectHelper.SERVICE_ID);
+ if (systemResource != null) {
+ projectHelper = getProjectHelperByService(systemResource);
+ registerProjectHelper(projectHelper);
+ }
+ } catch (Exception e) {
+ System.err.println("Unable to load ProjectHelper from service "
+ + ProjectHelper.SERVICE_ID + " ("
+ + e.getClass().getName()
+ + ": " + e.getMessage() + ")");
+ if (DEBUG) {
+ e.printStackTrace(System.err);
+ }
+ }
+ }
+
+ /**
+ * Register the specified project helper into the repository.
+ * <p>
+ * The helper will be added after all the already registered helpers, but
+ * before the default one (ProjectHelper2)
+ *
+ * @param helperClassName
+ * the fully qualified name of the helper
+ * @throws BuildException
+ * if the class cannot be loaded or if there is no constructor
+ * with no argument
+ * @since Ant 1.8.2
+ */
+ public void registerProjectHelper(String helperClassName)
+ throws BuildException {
+ registerProjectHelper(getHelperConstructor(helperClassName));
+ }
+
+ /**
+ * Register the specified project helper into the repository.
+ * <p>
+ * The helper will be added after all the already registered helpers, but
+ * before the default one (ProjectHelper2)
+ *
+ * @param helperClass
+ * the class of the helper
+ * @throws BuildException
+ * if there is no constructor with no argument
+ * @since Ant 1.8.2
+ */
+ public void registerProjectHelper(Class<? extends ProjectHelper> helperClass) throws BuildException {
+ try {
+ registerProjectHelper(helperClass.getConstructor());
+ } catch (NoSuchMethodException e) {
+ throw new BuildException("Couldn't find no-arg constructor in "
+ + helperClass.getName());
+ }
+ }
+
+ private void registerProjectHelper(Constructor<? extends ProjectHelper> helperConstructor) {
+ if (helperConstructor == null) {
+ return;
+ }
+ if (DEBUG) {
+ System.out.println("ProjectHelper "
+ + helperConstructor.getClass().getName() + " registered.");
+ }
+ helpers.add(helperConstructor);
+ }
+
+ private Constructor<? extends ProjectHelper> getProjectHelperBySystemProperty() {
+ String helperClass = System.getProperty(ProjectHelper.HELPER_PROPERTY);
+ try {
+ if (helperClass != null) {
+ return getHelperConstructor(helperClass);
+ }
+ } catch (SecurityException e) {
+ System.err.println("Unable to load ProjectHelper class \""
+ + helperClass + " specified in system property "
+ + ProjectHelper.HELPER_PROPERTY + " ("
+ + e.getMessage() + ")");
+ if (DEBUG) {
+ e.printStackTrace(System.err);
+ }
+ }
+ return null;
+ }
+
+ private Constructor<? extends ProjectHelper> getProjectHelperByService(InputStream is) {
+ try {
+ // This code is needed by EBCDIC and other strange systems.
+ // It's a fix for bugs reported in xerces
+ InputStreamReader isr;
+ try {
+ isr = new InputStreamReader(is, "UTF-8");
+ } catch (java.io.UnsupportedEncodingException e) {
+ isr = new InputStreamReader(is);
+ }
+ BufferedReader rd = new BufferedReader(isr);
+
+ String helperClassName = rd.readLine();
+ rd.close();
+
+ if (helperClassName != null && !"".equals(helperClassName)) {
+ return getHelperConstructor(helperClassName);
+ }
+ } catch (Exception e) {
+ System.out.println("Unable to load ProjectHelper from service "
+ + ProjectHelper.SERVICE_ID + " (" + e.getMessage() + ")");
+ if (DEBUG) {
+ e.printStackTrace(System.err);
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Get the constructor with not argument of an helper from its class name.
+ * It'll first try the thread class loader, then Class.forName() will load
+ * from the same loader that loaded this class.
+ *
+ * @param helperClass
+ * The name of the class to create an instance of. Must not be
+ * <code>null</code>.
+ *
+ * @return the constructor of the specified class.
+ *
+ * @exception BuildException
+ * if the class cannot be found or if a constructor with no
+ * argument cannot be found.
+ */
+ private Constructor<? extends ProjectHelper> getHelperConstructor(String helperClass) throws BuildException {
+ ClassLoader classLoader = LoaderUtils.getContextClassLoader();
+ try {
+ Class<?> clazz = null;
+ if (classLoader != null) {
+ try {
+ clazz = classLoader.loadClass(helperClass);
+ } catch (ClassNotFoundException ex) {
+ // try next method
+ }
+ }
+ if (clazz == null) {
+ clazz = Class.forName(helperClass);
+ }
+ return clazz.asSubclass(ProjectHelper.class).getConstructor();
+ } catch (Exception e) {
+ throw new BuildException(e);
+ }
+ }
+
+ /**
+ * Get the helper that will be able to parse the specified build file. The helper
+ * will be chosen among the ones found in the classpath
+ *
+ * @return the first ProjectHelper that fit the requirement (never <code>null</code>).
+ */
+ public ProjectHelper getProjectHelperForBuildFile(Resource buildFile) throws BuildException {
+ for (Iterator<ProjectHelper> it = getHelpers(); it.hasNext();) {
+ ProjectHelper helper = it.next();
+ if (helper.canParseBuildFile(buildFile)) {
+ if (DEBUG) {
+ System.out.println("ProjectHelper "
+ + helper.getClass().getName()
+ + " selected for the build file "
+ + buildFile);
+ }
+ return helper;
+ }
+ }
+ throw new RuntimeException("BUG: at least the ProjectHelper2 should "
+ + "have supported the file " + buildFile);
+ }
+
+ /**
+ * Get the helper that will be able to parse the specified antlib. The helper
+ * will be chosen among the ones found in the classpath
+ *
+ * @return the first ProjectHelper that fit the requirement (never <code>null</code>).
+ */
+ public ProjectHelper getProjectHelperForAntlib(Resource antlib) throws BuildException {
+ for (Iterator<ProjectHelper> it = getHelpers(); it.hasNext();) {
+ ProjectHelper helper = it.next();
+ if (helper.canParseAntlibDescriptor(antlib)) {
+ if (DEBUG) {
+ System.out.println("ProjectHelper "
+ + helper.getClass().getName()
+ + " selected for the antlib "
+ + antlib);
+ }
+ return helper;
+ }
+ }
+ throw new RuntimeException("BUG: at least the ProjectHelper2 should "
+ + "have supported the file " + antlib);
+ }
+
+ /**
+ * Get an iterator on the list of project helpers configured. The iterator
+ * will always return at least one element as there will always be the
+ * default project helper configured.
+ *
+ * @return an iterator of {@link ProjectHelper}
+ */
+ public Iterator<ProjectHelper> getHelpers() {
+ return new ConstructingIterator(helpers.iterator());
+ }
+
+ private static class ConstructingIterator implements Iterator<ProjectHelper> {
+ private final Iterator<Constructor<? extends ProjectHelper>> nested;
+ private boolean empty = false;
+
+ ConstructingIterator(Iterator<Constructor<? extends ProjectHelper>> nested) {
+ this.nested = nested;
+ }
+
+ public boolean hasNext() {
+ return nested.hasNext() || !empty;
+ }
+
+ public ProjectHelper next() {
+ Constructor<? extends ProjectHelper> c;
+ if (nested.hasNext()) {
+ c = nested.next();
+ } else {
+ // last but not least, ant default project helper
+ empty = true;
+ c = PROJECTHELPER2_CONSTRUCTOR;
+ }
+ try {
+ return c.newInstance();
+ } catch (Exception e) {
+ throw new BuildException("Failed to invoke no-arg constructor"
+ + " on " + c.getName());
+ }
+ }
+
+ public void remove() {
+ throw new UnsupportedOperationException("remove is not supported");
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/PropertyHelper.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/PropertyHelper.java
new file mode 100644
index 00000000..1dbb280c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/PropertyHelper.java
@@ -0,0 +1,1215 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant;
+
+import java.text.ParsePosition;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Set;
+import java.util.Vector;
+
+import org.apache.tools.ant.property.GetProperty;
+import org.apache.tools.ant.property.NullReturn;
+import org.apache.tools.ant.property.ParseNextProperty;
+import org.apache.tools.ant.property.ParseProperties;
+import org.apache.tools.ant.property.PropertyExpander;
+
+/* ISSUES:
+ - ns param. It could be used to provide "namespaces" for properties, which
+ may be more flexible.
+ - Object value. In ant1.5 String is used for Properties - but it would be nice
+ to support generic Objects (the property remains immutable - you can't change
+ the associated object). This will also allow JSP-EL style setting using the
+ Object if an attribute contains only the property (name="${property}" could
+ avoid Object->String->Object conversion)
+ - Currently we "chain" only for get and set property (probably most users
+ will only need that - if they need more they can replace the top helper).
+ Need to discuss this and find if we need more.
+ */
+
+/* update for impending Ant 1.8.0:
+
+ - I can't see any reason for ns and would like to deprecate it.
+ - Replacing chaining with delegates for certain behavioral aspects.
+ - Object value seems valuable as outlined.
+
+ */
+
+/**
+ * Deals with properties - substitution, dynamic properties, etc.
+ *
+ * <p>This code has been heavily restructured for Ant 1.8.0. It is
+ * expected that custom PropertyHelper implementation that used the
+ * older chaining mechanism of Ant 1.6 won't work in all cases, and
+ * its usage is deprecated. The preferred way to customize Ant's
+ * property handling is by {@link #add adding} {@link
+ * PropertyHelper.Delegate delegates} of the appropriate subinterface
+ * and have this implementation use them.</p>
+ *
+ * <p>When {@link #parseProperties expanding a string that may contain
+ * properties} this class will delegate the actual parsing to {@link
+ * org.apache.tools.ant.property.ParseProperties#parseProperties
+ * parseProperties} inside the ParseProperties class which in turn
+ * uses the {@link org.apache.tools.ant.property.PropertyExpander
+ * PropertyExpander delegates} to find properties inside the string
+ * and this class to expand the propertiy names found into the
+ * corresponding values.</p>
+ *
+ * <p>When {@link #getProperty looking up a property value} this class
+ * will first consult all {@link PropertyHelper.PropertyEvaluator
+ * PropertyEvaluator} delegates and fall back to an internal map of
+ * "project properties" if no evaluator matched the property name.</p>
+ *
+ * <p>When {@link #setProperty setting a property value} this class
+ * will first consult all {@link PropertyHelper.PropertySetter
+ * PropertySetter} delegates and fall back to an internal map of
+ * "project properties" if no setter matched the property name.</p>
+ *
+ * @since Ant 1.6
+ */
+public class PropertyHelper implements GetProperty {
+
+ // --------------------------------------------------------
+ //
+ // The property delegate interfaces
+ //
+ // --------------------------------------------------------
+
+ /**
+ * Marker interface for a PropertyHelper delegate.
+ * @since Ant 1.8.0
+ */
+ public interface Delegate {
+ }
+
+ /**
+ * Looks up a property's value based on its name.
+ *
+ * <p>Can be used to look up properties in a different storage
+ * than the project instance (like local properties for example)
+ * or to implement custom "protocols" like Ant's
+ * <code>${toString:refid}</code> syntax.</p>
+ *
+ * @since Ant 1.8.0
+ */
+ public interface PropertyEvaluator extends Delegate {
+ /**
+ * Evaluate a property.
+ *
+ * @param property the property's String "identifier".
+ * @param propertyHelper the invoking PropertyHelper.
+ * @return null if the property name could not be found, an
+ * instance of {@link org.apache.tools.ant.property.NullReturn
+ * NullReturn} to indicate a property with a name that can be
+ * matched but a value of <code>null</code> and the property's
+ * value otherwise.
+ */
+ Object evaluate(String property, PropertyHelper propertyHelper);
+ }
+
+ /**
+ * Sets or overrides a property.
+ *
+ * <p>Can be used to store properties in a different storage than
+ * the project instance (like local properties for example).</p>
+ *
+ * @since Ant 1.8.0
+ */
+ public interface PropertySetter extends Delegate {
+ /**
+ * Set a *new" property.
+ *
+ * <p>Should not replace the value of an existing property.</p>
+ *
+ * @param property the property's String "identifier".
+ * @param value the value to set.
+ * @param propertyHelper the invoking PropertyHelper.
+ * @return true if this entity 'owns' the property.
+ */
+ boolean setNew(
+ String property, Object value, PropertyHelper propertyHelper);
+
+ /**
+ * Set a property.
+ *
+ * <p>May replace the value of an existing property.</p>
+ *
+ * @param property the property's String "identifier".
+ * @param value the value to set.
+ * @param propertyHelper the invoking PropertyHelper.
+ * @return true if this entity 'owns' the property.
+ */
+ boolean set(
+ String property, Object value, PropertyHelper propertyHelper);
+ }
+
+ //TODO PropertyEnumerator Delegate type, would improve PropertySet
+
+ // --------------------------------------------------------
+ //
+ // The predefined property delegates
+ //
+ // --------------------------------------------------------
+
+ private static final PropertyEvaluator TO_STRING = new PropertyEvaluator() {
+ private final String PREFIX = "toString:";
+ private final int PREFIX_LEN = PREFIX.length();
+
+ public Object evaluate(String property, PropertyHelper propertyHelper) {
+ Object o = null;
+ if (property.startsWith(PREFIX) && propertyHelper.getProject() != null) {
+ o = propertyHelper.getProject().getReference(property.substring(PREFIX_LEN));
+ }
+ return o == null ? null : o.toString();
+ }
+ };
+
+ private static final PropertyExpander DEFAULT_EXPANDER = new PropertyExpander() {
+ public String parsePropertyName(
+ String s, ParsePosition pos, ParseNextProperty notUsed) {
+ int index = pos.getIndex();
+ //directly check near, triggering characters:
+ if (s.length() - index >= 3
+ && '$' == s.charAt(index) && '{' == s.charAt(index + 1)) {
+ int start = index + 2;
+ //defer to String.indexOf() for protracted check:
+ int end = s.indexOf('}', start);
+ if (end < 0) {
+ throw new BuildException("Syntax error in property: "
+ + s.substring(index));
+ }
+ pos.setIndex(end + 1);
+ return start == end ? "" : s.substring(start, end);
+ }
+ return null;
+ }
+ };
+
+ /** dummy */
+ private static final PropertyExpander SKIP_DOUBLE_DOLLAR
+ = new PropertyExpander() {
+ // CheckStyle:LineLengthCheck OFF see too long
+ /**
+ * {@inheritDoc}
+ * @see org.apache.tools.ant.property.PropertyExpander#parsePropertyName(java.lang.String, java.text.ParsePosition, org.apache.tools.ant.PropertyHelper)
+ */
+ // CheckStyle:LineLengthCheck ON
+ public String parsePropertyName(
+ String s, ParsePosition pos, ParseNextProperty notUsed) {
+ int index = pos.getIndex();
+ if (s.length() - index >= 2) {
+ /* check for $$; if found, advance by one--
+ * this expander is at the bottom of the stack
+ * and will thus be the last consulted,
+ * so the next thing that ParseProperties will do
+ * is advance the parse position beyond the second $
+ */
+ if ('$' == s.charAt(index) && '$' == s.charAt(++index)) {
+ pos.setIndex(index);
+ }
+ }
+ return null;
+ }
+ };
+
+ /**
+ * @since Ant 1.8.0
+ */
+ private static final PropertyEvaluator FROM_REF = new PropertyEvaluator() {
+ private final String PREFIX = "ant.refid:";
+ private final int PREFIX_LEN = PREFIX.length();
+
+ public Object evaluate(String prop, PropertyHelper helper) {
+ return prop.startsWith(PREFIX) && helper.getProject() != null
+ ? helper.getProject().getReference(prop.substring(PREFIX_LEN))
+ : null;
+ }
+ };
+
+ private Project project;
+ private PropertyHelper next;
+ private final Hashtable<Class<? extends Delegate>, List<Delegate>> delegates = new Hashtable<Class<? extends Delegate>, List<Delegate>>();
+
+ /** Project properties map (usually String to String). */
+ private Hashtable<String, Object> properties = new Hashtable<String, Object>();
+
+ /**
+ * Map of "user" properties (as created in the Ant task, for example).
+ * Note that these key/value pairs are also always put into the
+ * project properties, so only the project properties need to be queried.
+ */
+ private Hashtable<String, Object> userProperties = new Hashtable<String, Object>();
+
+ /**
+ * Map of inherited "user" properties - that are those "user"
+ * properties that have been created by tasks and not been set
+ * from the command line or a GUI tool.
+ */
+ private Hashtable<String, Object> inheritedProperties = new Hashtable<String, Object>();
+
+ /**
+ * Default constructor.
+ */
+ protected PropertyHelper() {
+ add(FROM_REF);
+ add(TO_STRING);
+ add(SKIP_DOUBLE_DOLLAR);
+ add(DEFAULT_EXPANDER);
+ }
+
+ // --------------------------------------------------------
+ //
+ // Some helper static methods to get and set properties
+ //
+ // --------------------------------------------------------
+
+ /**
+ * A helper static method to get a property
+ * from a particular project.
+ * @param project the project in question.
+ * @param name the property name
+ * @return the value of the property if present, null otherwise.
+ * @since Ant 1.8.0
+ */
+ public static Object getProperty(Project project, String name) {
+ return PropertyHelper.getPropertyHelper(project)
+ .getProperty(name);
+ }
+
+ /**
+ * A helper static method to set a property
+ * from a particular project.
+ * @param project the project in question.
+ * @param name the property name
+ * @param value the value to use.
+ * @since Ant 1.8.0
+ */
+ public static void setProperty(Project project, String name, Object value) {
+ PropertyHelper.getPropertyHelper(project)
+ .setProperty(name, value, true);
+ }
+
+ /**
+ * A helper static method to set a new property
+ * from a particular project.
+ * @param project the project in question.
+ * @param name the property name
+ * @param value the value to use.
+ * @since Ant 1.8.0
+ */
+ public static void setNewProperty(
+ Project project, String name, Object value) {
+ PropertyHelper.getPropertyHelper(project)
+ .setNewProperty(name, value);
+ }
+
+ //override facility for subclasses to put custom hashtables in
+
+ // -------------------- Hook management --------------------
+
+ /**
+ * Set the project for which this helper is performing property resolution.
+ *
+ * @param p the project instance.
+ */
+ public void setProject(Project p) {
+ this.project = p;
+ }
+
+ /**
+ * Get this PropertyHelper's Project.
+ * @return Project
+ */
+ public Project getProject() {
+ return project;
+ }
+
+ /**
+ * Prior to Ant 1.8.0 there have been 2 ways to hook into property handling:
+ *
+ * - you can replace the main PropertyHelper. The replacement is required
+ * to support the same semantics (of course :-)
+ *
+ * - you can chain a property helper capable of storing some properties.
+ * Again, you are required to respect the immutability semantics (at
+ * least for non-dynamic properties)
+ *
+ * <p>As of Ant 1.8.0 this method is never invoked by any code
+ * inside of Ant itself.</p>
+ *
+ * @param next the next property helper in the chain.
+ * @deprecated use the delegate mechanism instead
+ */
+ public void setNext(PropertyHelper next) {
+ this.next = next;
+ }
+
+ /**
+ * Get the next property helper in the chain.
+ *
+ * <p>As of Ant 1.8.0 this method is never invoked by any code
+ * inside of Ant itself except the {@link #setPropertyHook
+ * setPropertyHook} and {@link #getPropertyHook getPropertyHook}
+ * methods in this class.</p>
+ *
+ * @return the next property helper.
+ * @deprecated use the delegate mechanism instead
+ */
+ public PropertyHelper getNext() {
+ return next;
+ }
+
+ /**
+ * Factory method to create a property processor.
+ * Users can provide their own or replace it using "ant.PropertyHelper"
+ * reference. User tasks can also add themselves to the chain, and provide
+ * dynamic properties.
+ *
+ * @param project the project for which the property helper is required.
+ *
+ * @return the project's property helper.
+ */
+ public static synchronized PropertyHelper getPropertyHelper(Project project) {
+ PropertyHelper helper = null;
+ if (project != null) {
+ helper = (PropertyHelper) project.getReference(MagicNames
+ .REFID_PROPERTY_HELPER);
+ }
+ if (helper != null) {
+ return helper;
+ }
+
+ helper = new PropertyHelper();
+ helper.setProject(project);
+
+ if (project != null) {
+ project.addReference(MagicNames.REFID_PROPERTY_HELPER, helper);
+ }
+
+ return helper;
+ }
+
+ /**
+ * Get the {@link PropertyExpander expanders}.
+ * @since Ant 1.8.0
+ * @return the expanders.
+ */
+ public Collection<PropertyExpander> getExpanders() {
+ return getDelegates(PropertyExpander.class);
+ }
+
+
+ // -------------------- Methods to override --------------------
+
+ /**
+ * Sets a property. Any existing property of the same name
+ * is overwritten, unless it is a user property.
+ *
+ * If all helpers return false, the property will be saved in
+ * the default properties table by setProperty.
+ *
+ * <p>As of Ant 1.8.0 this method is never invoked by any code
+ * inside of Ant itself.</p>
+ *
+ * @param ns The namespace that the property is in (currently
+ * not used.
+ * @param name The name of property to set.
+ * Must not be <code>null</code>.
+ * @param value The new value of the property.
+ * Must not be <code>null</code>.
+ * @param inherited True if this property is inherited (an [sub]ant[call] property).
+ * @param user True if this property is a user property.
+ * @param isNew True is this is a new property.
+ * @return true if this helper has stored the property, false if it
+ * couldn't. Each helper should delegate to the next one (unless it
+ * has a good reason not to).
+ * @deprecated PropertyHelper chaining is deprecated.
+ */
+ public boolean setPropertyHook(String ns, String name,
+ Object value,
+ boolean inherited, boolean user,
+ boolean isNew) {
+ if (getNext() != null) {
+ boolean subst = getNext().setPropertyHook(ns, name, value, inherited, user, isNew);
+ // If next has handled the property
+ if (subst) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Get a property. If all hooks return null, the default
+ * tables will be used.
+ *
+ * <p>As of Ant 1.8.0 this method is never invoked by any code
+ * inside of Ant itself.</p>
+ *
+ * @param ns namespace of the sought property.
+ * @param name name of the sought property.
+ * @param user True if this is a user property.
+ * @return The property, if returned by a hook, or null if none.
+ * @deprecated PropertyHelper chaining is deprecated.
+ */
+ public Object getPropertyHook(String ns, String name, boolean user) {
+ if (getNext() != null) {
+ Object o = getNext().getPropertyHook(ns, name, user);
+ if (o != null) {
+ return o;
+ }
+ }
+ // Experimental/Testing, will be removed
+ if (project != null && name.startsWith("toString:")) {
+ name = name.substring("toString:".length());
+ Object v = project.getReference(name);
+ return (v == null) ? null : v.toString();
+ }
+ return null;
+ }
+
+ // -------------------- Optional methods --------------------
+ // You can override those methods if you want to optimize or
+ // do advanced things (like support a special syntax).
+ // The methods do not chain - you should use them when embedding ant
+ // (by replacing the main helper)
+
+ /**
+ * Parses a string containing <code>${xxx}</code> style property
+ * references into two lists. The first list is a collection
+ * of text fragments, while the other is a set of string property names.
+ * <code>null</code> entries in the first list indicate a property
+ * reference from the second list.
+ *
+ * <p>Delegates to {@link #parsePropertyStringDefault
+ * parsePropertyStringDefault}.</p>
+ *
+ * <p>As of Ant 1.8.0 this method is never invoked by any code
+ * inside of Ant itself except {ProjectHelper#parsePropertyString
+ * ProjectHelper.parsePropertyString}.</p>
+ *
+ * @param value Text to parse. Must not be <code>null</code>.
+ * @param fragments List to add text fragments to.
+ * Must not be <code>null</code>.
+ * @param propertyRefs List to add property names to.
+ * Must not be <code>null</code>.
+ *
+ * @exception BuildException if the string contains an opening
+ * <code>${</code> without a closing
+ * <code>}</code>
+ * @deprecated use the other mechanisms of this class instead
+ */
+ public void parsePropertyString(String value, Vector<String> fragments,
+ Vector<String> propertyRefs) throws BuildException {
+ parsePropertyStringDefault(value, fragments, propertyRefs);
+ }
+
+ /**
+ * Replaces <code>${xxx}</code> style constructions in the given value
+ * with the string value of the corresponding data types.
+ *
+ * <p>Delegates to the one-arg version, completely ignoring the ns
+ * and keys parameters.</p>
+ *
+ * @param ns The namespace for the property.
+ * @param value The string to be scanned for property references.
+ * May be <code>null</code>, in which case this
+ * method returns immediately with no effect.
+ * @param keys Mapping (String to Object) of property names to their
+ * values. If <code>null</code>, only project properties will
+ * be used.
+ *
+ * @exception BuildException if the string contains an opening
+ * <code>${</code> without a closing
+ * <code>}</code>
+ * @return the original string with the properties replaced, or
+ * <code>null</code> if the original string is <code>null</code>.
+ */
+ //TODO deprecate? Recall why no longer using ns/keys params
+ public String replaceProperties(String ns, String value, Hashtable<String, Object> keys) throws BuildException {
+ return replaceProperties(value);
+ }
+
+ /**
+ * Replaces <code>${xxx}</code> style constructions in the given value
+ * with the string value of the corresponding data types.
+ *
+ * @param value The string to be scanned for property references.
+ * May be <code>null</code>, in which case this
+ * method returns immediately with no effect.
+ *
+ * @exception BuildException if the string contains an opening
+ * <code>${</code> without a closing
+ * <code>}</code>
+ * @return the original string with the properties replaced, or
+ * <code>null</code> if the original string is <code>null</code>.
+ */
+ public String replaceProperties(String value) throws BuildException {
+ Object o = parseProperties(value);
+ return o == null || o instanceof String ? (String) o : o.toString();
+ }
+
+ /**
+ * Decode properties from a String representation. If the entire
+ * contents of the String resolve to a single property, that value
+ * is returned. Otherwise a String is returned.
+ *
+ * @param value The string to be scanned for property references.
+ * May be <code>null</code>, in which case this
+ * method returns immediately with no effect.
+ *
+ * @exception BuildException if the string contains an opening
+ * <code>${</code> without a closing
+ * <code>}</code>
+ * @return the original string with the properties replaced, or
+ * <code>null</code> if the original string is <code>null</code>.
+ */
+ public Object parseProperties(String value) throws BuildException {
+ return new ParseProperties(getProject(), getExpanders(), this)
+ .parseProperties(value);
+ }
+
+ /**
+ * Learn whether a String contains replaceable properties.
+ * @param value the String to check.
+ * @return <code>true</code> if <code>value</code> contains property notation.
+ */
+ public boolean containsProperties(String value) {
+ return new ParseProperties(getProject(), getExpanders(), this)
+ .containsProperties(value);
+ }
+
+ // -------------------- Default implementation --------------------
+ // Methods used to support the default behavior and provide backward
+ // compatibility. Some will be deprecated, you should avoid calling them.
+
+ /**
+ * Default implementation of setProperty. Will be called from Project.
+ * This is the original 1.5 implementation, with calls to the hook
+ * added.
+ *
+ * <p>Delegates to the three-arg version, completely ignoring the
+ * ns parameter.</p>
+ *
+ * @param ns The namespace for the property (currently not used).
+ * @param name The name of the property.
+ * @param value The value to set the property to.
+ * @param verbose If this is true output extra log messages.
+ * @return true if the property is set.
+ * @deprecated namespaces are unnecessary.
+ */
+ public boolean setProperty(String ns, String name, Object value, boolean verbose) {
+ return setProperty(name, value, verbose);
+ }
+
+ /**
+ * Default implementation of setProperty. Will be called from Project.
+ * @param name The name of the property.
+ * @param value The value to set the property to.
+ * @param verbose If this is true output extra log messages.
+ * @return true if the property is set.
+ */
+ public boolean setProperty(String name, Object value, boolean verbose) {
+ for (PropertySetter setter : getDelegates(PropertySetter.class)) {
+ if (setter.set(name, value, this)) {
+ return true;
+ }
+ }
+ synchronized (this) {
+ // user (CLI) properties take precedence
+ if (userProperties.containsKey(name)) {
+ if (project != null && verbose) {
+ project.log("Override ignored for user property \""
+ + name + "\"", Project.MSG_VERBOSE);
+ }
+ return false;
+ }
+ if (project != null && verbose) {
+ if (properties.containsKey(name)) {
+ project.log("Overriding previous definition of property \""
+ + name + "\"", Project.MSG_VERBOSE);
+ }
+ project.log("Setting project property: " + name + " -> "
+ + value, Project.MSG_DEBUG);
+ }
+ if (name != null && value != null) {
+ properties.put(name, value);
+ }
+ return true;
+ }
+ }
+
+ /**
+ * Sets a property if no value currently exists. If the property
+ * exists already, a message is logged and the method returns with
+ * no other effect.
+ *
+ * <p>Delegates to the two-arg version, completely ignoring the
+ * ns parameter.</p>
+ *
+ * @param ns The namespace for the property (currently not used).
+ * @param name The name of property to set.
+ * Must not be <code>null</code>.
+ * @param value The new value of the property.
+ * Must not be <code>null</code>.
+ * @since Ant 1.6
+ * @deprecated namespaces are unnecessary.
+ */
+ public void setNewProperty(String ns, String name, Object value) {
+ setNewProperty(name, value);
+ }
+
+ /**
+ * Sets a property if no value currently exists. If the property
+ * exists already, a message is logged and the method returns with
+ * no other effect.
+ *
+ * @param name The name of property to set.
+ * Must not be <code>null</code>.
+ * @param value The new value of the property.
+ * Must not be <code>null</code>.
+ * @since Ant 1.8.0
+ */
+ public void setNewProperty(String name, Object value) {
+ for (PropertySetter setter : getDelegates(PropertySetter.class)) {
+ if (setter.setNew(name, value, this)) {
+ return;
+ }
+ }
+ synchronized (this) {
+ if (project != null && properties.containsKey(name)) {
+ project.log("Override ignored for property \"" + name
+ + "\"", Project.MSG_VERBOSE);
+ return;
+ }
+ if (project != null) {
+ project.log("Setting project property: " + name
+ + " -> " + value, Project.MSG_DEBUG);
+ }
+ if (name != null && value != null) {
+ properties.put(name, value);
+ }
+ }
+ }
+
+ /**
+ * Sets a user property, which cannot be overwritten by
+ * set/unset property calls. Any previous value is overwritten.
+ *
+ * <p>Delegates to the two-arg version, completely ignoring the
+ * ns parameter.</p>
+ *
+ * @param ns The namespace for the property (currently not used).
+ * @param name The name of property to set.
+ * Must not be <code>null</code>.
+ * @param value The new value of the property.
+ * Must not be <code>null</code>.
+ * @deprecated namespaces are unnecessary.
+ */
+ public void setUserProperty(String ns, String name, Object value) {
+ setUserProperty(name, value);
+ }
+
+ /**
+ * Sets a user property, which cannot be overwritten by
+ * set/unset property calls. Any previous value is overwritten.
+ *
+ * <p>Does <code>not</code> consult any delegates.</p>
+ *
+ * @param name The name of property to set.
+ * Must not be <code>null</code>.
+ * @param value The new value of the property.
+ * Must not be <code>null</code>.
+ */
+ public void setUserProperty(String name, Object value) {
+ if (project != null) {
+ project.log("Setting ro project property: "
+ + name + " -> " + value, Project.MSG_DEBUG);
+ }
+ synchronized (this) {
+ userProperties.put(name, value);
+ properties.put(name, value);
+ }
+ }
+
+ /**
+ * Sets an inherited user property, which cannot be overwritten by set/unset
+ * property calls. Any previous value is overwritten. Also marks
+ * these properties as properties that have not come from the
+ * command line.
+ *
+ * <p>Delegates to the two-arg version, completely ignoring the
+ * ns parameter.</p>
+ *
+ * @param ns The namespace for the property (currently not used).
+ * @param name The name of property to set.
+ * Must not be <code>null</code>.
+ * @param value The new value of the property.
+ * Must not be <code>null</code>.
+ * @deprecated namespaces are unnecessary.
+ */
+ public void setInheritedProperty(String ns, String name, Object value) {
+ setInheritedProperty(name, value);
+ }
+
+ /**
+ * Sets an inherited user property, which cannot be overwritten by set/unset
+ * property calls. Any previous value is overwritten. Also marks
+ * these properties as properties that have not come from the
+ * command line.
+ *
+ * <p>Does <code>not</code> consult any delegates.</p>
+ *
+ * @param name The name of property to set.
+ * Must not be <code>null</code>.
+ * @param value The new value of the property.
+ * Must not be <code>null</code>.
+ */
+ public void setInheritedProperty(String name, Object value) {
+ if (project != null) {
+ project.log("Setting ro project property: " + name + " -> "
+ + value, Project.MSG_DEBUG);
+ }
+
+ synchronized (this) {
+ inheritedProperties.put(name, value);
+ userProperties.put(name, value);
+ properties.put(name, value);
+ }
+ }
+
+ // -------------------- Getting properties --------------------
+
+ /**
+ * Returns the value of a property, if it is set. You can override
+ * this method in order to plug your own storage.
+ *
+ * <p>Delegates to the one-arg version ignoring the ns parameter.</p>
+ *
+ * @param ns The namespace for the property (currently not used).
+ * @param name The name of the property.
+ * May be <code>null</code>, in which case
+ * the return value is also <code>null</code>.
+ * @return the property value, or <code>null</code> for no match
+ * or if a <code>null</code> name is provided.
+ * @deprecated namespaces are unnecessary.
+ */
+ public Object getProperty(String ns, String name) {
+ return getProperty(name);
+ }
+
+ /**
+ * Returns the value of a property, if it is set.
+ *
+ * <p>This is the method that is invoked by {Project#getProperty
+ * Project.getProperty}.</p>
+ *
+ * <p>You can override this method in order to plug your own
+ * storage but the recommended approach is to add your own
+ * implementation of {@link PropertyEvaluator PropertyEvaluator}
+ * instead.</p>
+ *
+ * @param name The name of the property.
+ * May be <code>null</code>, in which case
+ * the return value is also <code>null</code>.
+ * @return the property value, or <code>null</code> for no match
+ * or if a <code>null</code> name is provided.
+ */
+ public Object getProperty(String name) {
+ if (name == null) {
+ return null;
+ }
+ for (PropertyEvaluator evaluator : getDelegates(PropertyEvaluator.class)) {
+ final Object o = evaluator.evaluate(name, this);
+ if (o == null) {
+ continue;
+ }
+ return o instanceof NullReturn ? null : o;
+ }
+ return properties.get(name);
+ }
+
+ /**
+ * Returns the value of a user property, if it is set.
+ *
+ * <p>Delegates to the one-arg version ignoring the ns parameter.</p>
+ *
+ * @param ns The namespace for the property (currently not used).
+ * @param name The name of the property.
+ * May be <code>null</code>, in which case
+ * the return value is also <code>null</code>.
+ * @return the property value, or <code>null</code> for no match
+ * or if a <code>null</code> name is provided.
+ * @deprecated namespaces are unnecessary.
+ */
+ public Object getUserProperty(String ns, String name) {
+ return getUserProperty(name);
+ }
+
+ /**
+ * Returns the value of a user property, if it is set.
+ *
+ * <p>Does <code>not</code> consult any delegates.</p>
+ *
+ * @param name The name of the property.
+ * May be <code>null</code>, in which case
+ * the return value is also <code>null</code>.
+ * @return the property value, or <code>null</code> for no match
+ * or if a <code>null</code> name is provided.
+ */
+ public Object getUserProperty(String name) {
+ if (name == null) {
+ return null;
+ }
+ return userProperties.get(name);
+ }
+
+ // -------------------- Access to property tables --------------------
+ // This is used to support ant call and similar tasks. It should be
+ // deprecated, it is possible to use a better (more efficient)
+ // mechanism to preserve the context.
+
+ /**
+ * Returns a copy of the properties table.
+ *
+ * <p>Does not contain properties held by implementations of
+ * delegates (like local properties).</p>
+ *
+ * @return a hashtable containing all properties (including user properties).
+ */
+ public Hashtable<String, Object> getProperties() {
+ //avoid concurrent modification:
+ synchronized (properties) {
+ return new Hashtable<String, Object>(properties);
+ }
+ // There is a better way to save the context. This shouldn't
+ // delegate to next, it's for backward compatibility only.
+ }
+
+ /**
+ * Returns a copy of the user property hashtable
+ *
+ * <p>Does not contain properties held by implementations of
+ * delegates (like local properties).</p>
+ *
+ * @return a hashtable containing just the user properties
+ */
+ public Hashtable<String, Object> getUserProperties() {
+ //avoid concurrent modification:
+ synchronized (userProperties) {
+ return new Hashtable<String, Object>(userProperties);
+ }
+ }
+
+ /**
+ * Returns a copy of the inherited property hashtable
+ *
+ * <p>Does not contain properties held by implementations of
+ * delegates (like local properties).</p>
+ *
+ * @return a hashtable containing just the inherited properties
+ */
+ public Hashtable<String, Object> getInheritedProperties() {
+ //avoid concurrent modification:
+ synchronized (inheritedProperties) {
+ return new Hashtable<String, Object>(inheritedProperties);
+ }
+ }
+
+ /**
+ * special back door for subclasses, internal access to the hashtables
+ * @return the live hashtable of all properties
+ */
+ protected Hashtable<String, Object> getInternalProperties() {
+ return properties;
+ }
+
+ /**
+ * special back door for subclasses, internal access to the hashtables
+ *
+ * @return the live hashtable of user properties
+ */
+ protected Hashtable<String, Object> getInternalUserProperties() {
+ return userProperties;
+ }
+
+ /**
+ * special back door for subclasses, internal access to the hashtables
+ *
+ * @return the live hashtable inherited properties
+ */
+ protected Hashtable<String, Object> getInternalInheritedProperties() {
+ return inheritedProperties;
+ }
+
+ /**
+ * Copies all user properties that have not been set on the
+ * command line or a GUI tool from this instance to the Project
+ * instance given as the argument.
+ *
+ * <p>To copy all "user" properties, you will also have to call
+ * {@link #copyUserProperties copyUserProperties}.</p>
+ *
+ * <p>Does not copy properties held by implementations of
+ * delegates (like local properties).</p>
+ *
+ * @param other the project to copy the properties to. Must not be null.
+ *
+ * @since Ant 1.6
+ */
+ public void copyInheritedProperties(Project other) {
+ //avoid concurrent modification:
+ synchronized (inheritedProperties) {
+ Enumeration<String> e = inheritedProperties.keys();
+ while (e.hasMoreElements()) {
+ String arg = e.nextElement().toString();
+ if (other.getUserProperty(arg) != null) {
+ continue;
+ }
+ Object value = inheritedProperties.get(arg);
+ other.setInheritedProperty(arg, value.toString());
+ }
+ }
+ }
+
+ /**
+ * Copies all user properties that have been set on the command
+ * line or a GUI tool from this instance to the Project instance
+ * given as the argument.
+ *
+ * <p>To copy all "user" properties, you will also have to call
+ * {@link #copyInheritedProperties copyInheritedProperties}.</p>
+ *
+ * <p>Does not copy properties held by implementations of
+ * delegates (like local properties).</p>
+ *
+ * @param other the project to copy the properties to. Must not be null.
+ *
+ * @since Ant 1.6
+ */
+ public void copyUserProperties(Project other) {
+ //avoid concurrent modification:
+ synchronized (userProperties) {
+ Enumeration<String> e = userProperties.keys();
+ while (e.hasMoreElements()) {
+ Object arg = e.nextElement();
+ if (inheritedProperties.containsKey(arg)) {
+ continue;
+ }
+ Object value = userProperties.get(arg);
+ other.setUserProperty(arg.toString(), value.toString());
+ }
+ }
+ }
+
+ // -------------------- Property parsing --------------------
+ // Moved from ProjectHelper. You can override the static method -
+ // this is used for backward compatibility (for code that calls
+ // the parse method in ProjectHelper).
+
+ /**
+ * Default parsing method. It is here only to support backward compatibility
+ * for the static ProjectHelper.parsePropertyString().
+ */
+ static void parsePropertyStringDefault(String value, Vector<String> fragments, Vector<String> propertyRefs)
+ throws BuildException {
+ int prev = 0;
+ int pos;
+ //search for the next instance of $ from the 'prev' position
+ while ((pos = value.indexOf("$", prev)) >= 0) {
+
+ //if there was any text before this, add it as a fragment
+ //TODO, this check could be modified to go if pos>prev;
+ //seems like this current version could stick empty strings
+ //into the list
+ if (pos > 0) {
+ fragments.addElement(value.substring(prev, pos));
+ }
+ //if we are at the end of the string, we tack on a $
+ //then move past it
+ if (pos == (value.length() - 1)) {
+ fragments.addElement("$");
+ prev = pos + 1;
+ } else if (value.charAt(pos + 1) != '{') {
+ //peek ahead to see if the next char is a property or not
+ //not a property: insert the char as a literal
+ /*
+ fragments.addElement(value.substring(pos + 1, pos + 2));
+ prev = pos + 2;
+ */
+ if (value.charAt(pos + 1) == '$') {
+ //backwards compatibility two $ map to one mode
+ fragments.addElement("$");
+ prev = pos + 2;
+ } else {
+ //new behaviour: $X maps to $X for all values of X!='$'
+ fragments.addElement(value.substring(pos, pos + 2));
+ prev = pos + 2;
+ }
+ } else {
+ //property found, extract its name or bail on a typo
+ int endName = value.indexOf('}', pos);
+ if (endName < 0) {
+ throw new BuildException("Syntax error in property: " + value);
+ }
+ String propertyName = value.substring(pos + 2, endName);
+ fragments.addElement(null);
+ propertyRefs.addElement(propertyName);
+ prev = endName + 1;
+ }
+ }
+ //no more $ signs found
+ //if there is any tail to the file, append it
+ if (prev < value.length()) {
+ fragments.addElement(value.substring(prev));
+ }
+ }
+
+ /**
+ * Add the specified delegate object to this PropertyHelper.
+ * Delegates are processed in LIFO order.
+ * @param delegate the delegate to add.
+ * @since Ant 1.8.0
+ */
+ public void add(Delegate delegate) {
+ synchronized (delegates) {
+ for (Class<? extends Delegate> key : getDelegateInterfaces(delegate)) {
+ List<Delegate> list = delegates.get(key);
+ if (list == null) {
+ list = new ArrayList<Delegate>();
+ } else {
+ //copy on write, top priority
+ list = new ArrayList<Delegate>(list);
+ list.remove(delegate);
+ }
+ list.add(0, delegate);
+ delegates.put(key, Collections.unmodifiableList(list));
+ }
+ }
+ }
+
+ /**
+ * Get the Collection of delegates of the specified type.
+ *
+ * @param type
+ * delegate type.
+ * @return Collection.
+ * @since Ant 1.8.0
+ */
+ protected <D extends Delegate> List<D> getDelegates(Class<D> type) {
+ @SuppressWarnings("unchecked")
+ final List<D> result = (List<D>) delegates.get(type);
+ return result == null ? Collections.<D> emptyList() : result;
+ }
+
+ /**
+ * Get all Delegate interfaces (excluding Delegate itself) from the specified Delegate.
+ * @param d the Delegate to inspect.
+ * @return Set&lt;Class&gt;
+ * @since Ant 1.8.0
+ */
+ protected static Set<Class<? extends Delegate>> getDelegateInterfaces(Delegate d) {
+ final HashSet<Class<? extends Delegate>> result = new HashSet<Class<? extends Delegate>>();
+ Class<?> c = d.getClass();
+ while (c != null) {
+ Class<?>[] ifs = c.getInterfaces();
+ for (int i = 0; i < ifs.length; i++) {
+ if (Delegate.class.isAssignableFrom(ifs[i])) {
+ @SuppressWarnings("unchecked")
+ final Class<? extends Delegate> delegateInterface = (Class<? extends Delegate>) ifs[i];
+ result.add(delegateInterface);
+ }
+ }
+ c = c.getSuperclass();
+ }
+ result.remove(Delegate.class);
+ return result;
+ }
+
+ /**
+ * If the given object can be interpreted as a true/false value,
+ * turn it into a matching Boolean - otherwise return null.
+ * @since Ant 1.8.0
+ */
+ public static Boolean toBoolean(Object value) {
+ if (value instanceof Boolean) {
+ return (Boolean) value;
+ }
+ if (value instanceof String) {
+ String s = (String) value;
+ if (Project.toBoolean(s)) {
+ return Boolean.TRUE;
+ }
+ if ("off".equalsIgnoreCase(s)
+ || "false".equalsIgnoreCase(s)
+ || "no".equalsIgnoreCase(s)) {
+ return Boolean.FALSE;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns true if the object is null or an empty string.
+ *
+ * @since Ant 1.8.0
+ */
+ private static boolean nullOrEmpty(Object value) {
+ return value == null || "".equals(value);
+
+ }
+
+ /**
+ * Returns true if the value can be interpreted as a true value or
+ * cannot be interpreted as a false value and a property of the
+ * value's name exists.
+ * @since Ant 1.8.0
+ */
+ private boolean evalAsBooleanOrPropertyName(Object value) {
+ Boolean b = toBoolean(value);
+ if (b != null) {
+ return b.booleanValue();
+ }
+ return getProperty(String.valueOf(value)) != null;
+ }
+
+ /**
+ * Returns true if the value is null or an empty string, can be
+ * interpreted as a true value or cannot be interpreted as a false
+ * value and a property of the value's name exists.
+ * @since Ant 1.8.0
+ */
+ public boolean testIfCondition(Object value) {
+ return nullOrEmpty(value) || evalAsBooleanOrPropertyName(value);
+ }
+
+ /**
+ * Returns true if the value is null or an empty string, can be
+ * interpreted as a false value or cannot be interpreted as a true
+ * value and a property of the value's name doesn't exist.
+ * @since Ant 1.8.0
+ */
+ public boolean testUnlessCondition(Object value) {
+ return nullOrEmpty(value) || !evalAsBooleanOrPropertyName(value);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/RuntimeConfigurable.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/RuntimeConfigurable.java
new file mode 100644
index 00000000..26f68dfe
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/RuntimeConfigurable.java
@@ -0,0 +1,608 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map.Entry;
+
+import org.apache.tools.ant.attribute.EnableAttribute;
+import org.apache.tools.ant.taskdefs.MacroDef.Attribute;
+import org.apache.tools.ant.taskdefs.MacroInstance;
+import org.apache.tools.ant.util.CollectionUtils;
+import org.xml.sax.AttributeList;
+import org.xml.sax.helpers.AttributeListImpl;
+
+/**
+ * Wrapper class that holds the attributes of an element, its children, and
+ * any text within it. It then takes care of configuring that element at
+ * runtime.
+ */
+public class RuntimeConfigurable implements Serializable {
+
+ /** Serialization version */
+ private static final long serialVersionUID = 1L;
+
+ /** Empty Hashtable. */
+ private static final Hashtable<String, Object> EMPTY_HASHTABLE =
+ new Hashtable<String, Object>(0);
+
+ /** Name of the element to configure. */
+ private String elementTag = null;
+
+ /** List of child element wrappers. */
+ private List<RuntimeConfigurable> children = null;
+
+ /** The element to configure. It is only used during
+ * maybeConfigure.
+ */
+ private transient Object wrappedObject = null;
+
+ /**
+ * XML attributes for the element.
+ * @deprecated since 1.6.x
+ */
+ private transient AttributeList attributes;
+
+ // The following is set to true if any of the attributes are namespaced
+ private transient boolean namespacedAttribute = false;
+
+ /** Attribute names and values. While the XML spec doesn't require
+ * preserving the order ( AFAIK ), some ant tests do rely on the
+ * exact order.
+ * The only exception to this order is the treatment of
+ * refid. A number of datatypes check if refid is set
+ * when other attributes are set. This check will not
+ * work if the build script has the other attribute before
+ * the "refid" attribute, so now (ANT 1.7) the refid
+ * attribute will be processed first.
+ */
+ private LinkedHashMap<String, Object> attributeMap = null;
+
+ /** Text appearing within the element. */
+ private StringBuffer characters = null;
+
+ /** Indicates if the wrapped object has been configured */
+ private boolean proxyConfigured = false;
+
+ /** the polymorphic type */
+ private String polyType = null;
+
+ /** the "id" of this Element if it has one */
+ private String id = null;
+
+ /**
+ * Sole constructor creating a wrapper for the specified object.
+ *
+ * @param proxy The element to configure. Must not be <code>null</code>.
+ * @param elementTag The tag name generating this element.
+ */
+ public RuntimeConfigurable(Object proxy, String elementTag) {
+ setProxy(proxy);
+ setElementTag(elementTag);
+ // Most likely an UnknownElement
+ if (proxy instanceof Task) {
+ ((Task) proxy).setRuntimeConfigurableWrapper(this);
+ }
+ }
+
+ /**
+ * Sets the element to configure.
+ *
+ * @param proxy The element to configure. Must not be <code>null</code>.
+ */
+ public synchronized void setProxy(Object proxy) {
+ wrappedObject = proxy;
+ proxyConfigured = false;
+ }
+
+ private static class EnableAttributeConsumer {
+ public void add(EnableAttribute b) {
+ // Ignore
+ }
+ }
+
+ /**
+ * contains the attribute component name and boolean restricted set to true when
+ * the attribute is in one of the name spaces managed by ant (if and unless currently)
+ * @since Ant 1.9.3
+ */
+ private static class AttributeComponentInformation {
+ String componentName;
+ boolean restricted;
+
+ private AttributeComponentInformation(String componentName, boolean restricted) {
+ this.componentName = componentName;
+ this.restricted = restricted;
+ }
+
+ public String getComponentName() {
+ return componentName;
+ }
+
+ public boolean isRestricted() {
+ return restricted;
+ }
+ }
+
+ /**
+ *
+ * @param name the name of the attribute.
+ * @param componentHelper current component helper
+ * @return AttributeComponentInformation instance
+ */
+ private AttributeComponentInformation isRestrictedAttribute(String name, ComponentHelper componentHelper) {
+ if (name.indexOf(':') == -1) {
+ return new AttributeComponentInformation(null, false);
+ }
+ String componentName = attrToComponent(name);
+ String ns = ProjectHelper.extractUriFromComponentName(componentName);
+ if (componentHelper.getRestrictedDefinitions(
+ ProjectHelper.nsToComponentName(ns)) == null) {
+ return new AttributeComponentInformation(null, false);
+ }
+ return new AttributeComponentInformation(componentName, true);
+ }
+
+ /**
+ * Check if an UE is enabled.
+ * This looks tru the attributes and checks if there
+ * are any Ant attributes, and if so, the method calls the
+ * isEnabled() method on them.
+ * @param owner the UE that owns this RC.
+ * @return true if enabled, false if any of the ant attribures return
+ * false.
+ * @since 1.9.1
+ */
+ public boolean isEnabled(UnknownElement owner) {
+ if (!namespacedAttribute) {
+ return true;
+ }
+ ComponentHelper componentHelper = ComponentHelper
+ .getComponentHelper(owner.getProject());
+
+ IntrospectionHelper ih
+ = IntrospectionHelper.getHelper(
+ owner.getProject(), EnableAttributeConsumer.class);
+ for (int i = 0; i < attributeMap.keySet().size(); ++i) {
+ String name = (String) attributeMap.keySet().toArray()[i];
+ AttributeComponentInformation attributeComponentInformation = isRestrictedAttribute(name, componentHelper);
+ if (!attributeComponentInformation.isRestricted()) {
+ continue;
+ }
+ String value = (String) attributeMap.get(name);
+ EnableAttribute enable = null;
+ try {
+ enable = (EnableAttribute)
+ ih.createElement(
+ owner.getProject(), new EnableAttributeConsumer(),
+ attributeComponentInformation.getComponentName());
+ } catch (BuildException ex) {
+ throw new BuildException(
+ "Unsupported attribute " + attributeComponentInformation.getComponentName());
+ }
+ if (enable == null) {
+ continue;
+ }
+ value = owner.getProject().replaceProperties(value); // FixMe: need to make config
+ if (!enable.isEnabled(owner, value)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private String attrToComponent(String a) {
+ // need to remove the prefix
+ int p1 = a.lastIndexOf(':');
+ int p2 = a.lastIndexOf(':', p1 - 1);
+ return a.substring(0, p2) + a.substring(p1);
+ }
+
+ /**
+ * Sets the creator of the element to be configured
+ * used to store the element in the parent.
+ *
+ * @param creator the creator object.
+ */
+ synchronized void setCreator(IntrospectionHelper.Creator creator) {
+ }
+
+ /**
+ * Get the object for which this RuntimeConfigurable holds the configuration
+ * information.
+ *
+ * @return the object whose configure is held by this instance.
+ */
+ public synchronized Object getProxy() {
+ return wrappedObject;
+ }
+
+ /**
+ * Returns the id for this element.
+ * @return the id.
+ */
+ public synchronized String getId() {
+ return id;
+ }
+
+ /**
+ * Get the polymorphic type for this element.
+ * @return the ant component type name, null if not set.
+ */
+ public synchronized String getPolyType() {
+ return polyType;
+ }
+
+ /**
+ * Set the polymorphic type for this element.
+ * @param polyType the ant component type name, null if not set.
+ */
+ public synchronized void setPolyType(String polyType) {
+ this.polyType = polyType;
+ }
+
+ /**
+ * Sets the attributes for the wrapped element.
+ *
+ * @deprecated since 1.6.x.
+ * @param attributes List of attributes defined in the XML for this
+ * element. May be <code>null</code>.
+ */
+ public synchronized void setAttributes(AttributeList attributes) {
+ this.attributes = new AttributeListImpl(attributes);
+ for (int i = 0; i < attributes.getLength(); i++) {
+ setAttribute(attributes.getName(i), attributes.getValue(i));
+ }
+ }
+
+ /**
+ * Set an attribute to a given value.
+ *
+ * @param name the name of the attribute.
+ * @param value the attribute's value.
+ */
+ public synchronized void setAttribute(String name, String value) {
+ if (name.indexOf(':') != -1) {
+ namespacedAttribute = true;
+ }
+ setAttribute(name, (Object) value);
+ }
+
+ /**
+ * Set an attribute to a given value.
+ *
+ * @param name the name of the attribute.
+ * @param value the attribute's value.
+ * @since 1.9
+ */
+ public synchronized void setAttribute(String name, Object value) {
+ if (name.equalsIgnoreCase(ProjectHelper.ANT_TYPE)) {
+ this.polyType = value == null ? null : value.toString();
+ } else {
+ if (attributeMap == null) {
+ attributeMap = new LinkedHashMap<String, Object>();
+ }
+ if (name.equalsIgnoreCase("refid") && !attributeMap.isEmpty()) {
+ LinkedHashMap<String, Object> newAttributeMap = new LinkedHashMap<String, Object>();
+ newAttributeMap.put(name, value);
+ newAttributeMap.putAll(attributeMap);
+ attributeMap = newAttributeMap;
+ } else {
+ attributeMap.put(name, value);
+ }
+ if (name.equals("id")) {
+ this.id = value == null ? null : value.toString();
+ }
+ }
+ }
+
+ /**
+ * Delete an attribute. Not for the faint of heart.
+ * @param name the name of the attribute to be removed.
+ */
+ public synchronized void removeAttribute(String name) {
+ attributeMap.remove(name);
+ }
+
+ /**
+ * Return the attribute map.
+ *
+ * @return Attribute name to attribute value map.
+ * @since Ant 1.6
+ */
+ public synchronized Hashtable<String, Object> getAttributeMap() {
+ return (attributeMap == null)
+ ? EMPTY_HASHTABLE : new Hashtable<String, Object>(attributeMap);
+ }
+
+ /**
+ * Returns the list of attributes for the wrapped element.
+ *
+ * @deprecated Deprecated since Ant 1.6 in favor of {@link #getAttributeMap}.
+ * @return An AttributeList representing the attributes defined in the
+ * XML for this element. May be <code>null</code>.
+ */
+ public synchronized AttributeList getAttributes() {
+ return attributes;
+ }
+
+ /**
+ * Adds a child element to the wrapped element.
+ *
+ * @param child The child element wrapper to add to this one.
+ * Must not be <code>null</code>.
+ */
+ public synchronized void addChild(RuntimeConfigurable child) {
+ children = (children == null) ? new ArrayList<RuntimeConfigurable>() : children;
+ children.add(child);
+ }
+
+ /**
+ * Returns the child wrapper at the specified position within the list.
+ *
+ * @param index The index of the child to return.
+ *
+ * @return The child wrapper at position <code>index</code> within the
+ * list.
+ */
+ synchronized RuntimeConfigurable getChild(int index) {
+ return children.get(index);
+ }
+
+ /**
+ * Returns an enumeration of all child wrappers.
+ * @return an enumeration of the child wrappers.
+ * @since Ant 1.6
+ */
+ public synchronized Enumeration<RuntimeConfigurable> getChildren() {
+ return (children == null) ? new CollectionUtils.EmptyEnumeration<RuntimeConfigurable>()
+ : Collections.enumeration(children);
+ }
+
+ /**
+ * Adds characters from #PCDATA areas to the wrapped element.
+ *
+ * @param data Text to add to the wrapped element.
+ * Should not be <code>null</code>.
+ */
+ public synchronized void addText(String data) {
+ if (data.length() == 0) {
+ return;
+ }
+ characters = (characters == null)
+ ? new StringBuffer(data) : characters.append(data);
+ }
+
+ /**
+ * Adds characters from #PCDATA areas to the wrapped element.
+ *
+ * @param buf A character array of the text within the element.
+ * Must not be <code>null</code>.
+ * @param start The start element in the array.
+ * @param count The number of characters to read from the array.
+ *
+ */
+ public synchronized void addText(char[] buf, int start, int count) {
+ if (count == 0) {
+ return;
+ }
+ characters = ((characters == null)
+ ? new StringBuffer(count) : characters).append(buf, start, count);
+ }
+
+ /**
+ * Get the text content of this element. Various text chunks are
+ * concatenated, there is no way ( currently ) of keeping track of
+ * multiple fragments.
+ *
+ * @return the text content of this element.
+ * @since Ant 1.6
+ */
+ public synchronized StringBuffer getText() {
+ return (characters == null) ? new StringBuffer(0) : characters;
+ }
+
+ /**
+ * Set the element tag.
+ * @param elementTag The tag name generating this element.
+ */
+ public synchronized void setElementTag(String elementTag) {
+ this.elementTag = elementTag;
+ }
+
+ /**
+ * Returns the tag name of the wrapped element.
+ *
+ * @return The tag name of the wrapped element. This is unlikely
+ * to be <code>null</code>, but may be.
+ */
+ public synchronized String getElementTag() {
+ return elementTag;
+ }
+
+ /**
+ * Configures the wrapped element and all its children.
+ * The attributes and text for the wrapped element are configured,
+ * and then each child is configured and added. Each time the
+ * wrapper is configured, the attributes and text for it are
+ * reset.
+ *
+ * If the element has an <code>id</code> attribute, a reference
+ * is added to the project as well.
+ *
+ * @param p The project containing the wrapped element.
+ * Must not be <code>null</code>.
+ *
+ * @exception BuildException if the configuration fails, for instance due
+ * to invalid attributes or children, or text being added to
+ * an element which doesn't accept it.
+ */
+ public void maybeConfigure(Project p) throws BuildException {
+ maybeConfigure(p, true);
+ }
+
+ /**
+ * Configures the wrapped element. The attributes and text for
+ * the wrapped element are configured. Each time the wrapper is
+ * configured, the attributes and text for it are reset.
+ *
+ * If the element has an <code>id</code> attribute, a reference
+ * is added to the project as well.
+ *
+ * @param p The project containing the wrapped element.
+ * Must not be <code>null</code>.
+ *
+ * @param configureChildren ignored.
+
+ *
+ * @exception BuildException if the configuration fails, for instance due
+ * to invalid attributes , or text being added to
+ * an element which doesn't accept it.
+ */
+ public synchronized void maybeConfigure(Project p, boolean configureChildren)
+ throws BuildException {
+
+ if (proxyConfigured) {
+ return;
+ }
+
+ // Configure the object
+ Object target = (wrappedObject instanceof TypeAdapter)
+ ? ((TypeAdapter) wrappedObject).getProxy() : wrappedObject;
+
+ IntrospectionHelper ih =
+ IntrospectionHelper.getHelper(p, target.getClass());
+ ComponentHelper componentHelper = ComponentHelper.getComponentHelper(p);
+ if (attributeMap != null) {
+ for (Entry<String, Object> entry : attributeMap.entrySet()) {
+ String name = entry.getKey();
+ // skip restricted attributes such as if:set
+ AttributeComponentInformation attributeComponentInformation = isRestrictedAttribute(name, componentHelper);
+ if (attributeComponentInformation.isRestricted()) {
+ continue;
+ }
+ Object value = entry.getValue();
+ // reflect these into the target, defer for
+ // MacroInstance where properties are expanded for the
+ // nested sequential
+ Object attrValue;
+ if (value instanceof Evaluable) {
+ attrValue = ((Evaluable) value).eval();
+ } else {
+ attrValue = PropertyHelper.getPropertyHelper(p).parseProperties(value.toString());
+ }
+ if (target instanceof MacroInstance) {
+ for (Attribute attr : ((MacroInstance) target).getMacroDef().getAttributes()) {
+ if (attr.getName().equals(name)) {
+ if (!attr.isDoubleExpanding()) {
+ attrValue = value;
+ }
+ break;
+ }
+ }
+ }
+ try {
+ ih.setAttribute(p, target, name, attrValue);
+ } catch (UnsupportedAttributeException be) {
+ // id attribute must be set externally
+ if (name.equals("id")) {
+ // Do nothing
+ } else if (getElementTag() == null) {
+ throw be;
+ } else {
+ throw new BuildException(
+ getElementTag() + " doesn't support the \""
+ + be.getAttribute() + "\" attribute", be);
+ }
+ } catch (BuildException be) {
+ if (name.equals("id")) {
+ // Assume that this is an not supported attribute type
+ // thrown for example by a dymanic attribute task
+ // Do nothing
+ } else {
+ throw be;
+ }
+ }
+ }
+ }
+
+ if (characters != null) {
+ ProjectHelper.addText(p, wrappedObject, characters.substring(0));
+ }
+
+ if (id != null) {
+ p.addReference(id, wrappedObject);
+ }
+ proxyConfigured = true;
+ }
+
+ /**
+ * Reconfigure the element, even if it has already been configured.
+ *
+ * @param p the project instance for this configuration.
+ */
+ public void reconfigure(Project p) {
+ proxyConfigured = false;
+ maybeConfigure(p);
+ }
+
+ /**
+ * Apply presets, attributes and text are set if not currently set.
+ * Nested elements are prepended.
+ *
+ * @param r a <code>RuntimeConfigurable</code> value.
+ */
+ public void applyPreSet(RuntimeConfigurable r) {
+ // Attributes
+ if (r.attributeMap != null) {
+ for (String name : r.attributeMap.keySet()) {
+ if (attributeMap == null || attributeMap.get(name) == null) {
+ setAttribute(name, (String) r.attributeMap.get(name));
+ }
+ }
+ }
+ // poly type
+
+ polyType = (polyType == null) ? r.polyType : polyType;
+
+ // Children (this is a shadow of UnknownElement#children)
+ if (r.children != null) {
+ List<RuntimeConfigurable> newChildren = new ArrayList<RuntimeConfigurable>();
+ newChildren.addAll(r.children);
+ if (children != null) {
+ newChildren.addAll(children);
+ }
+ children = newChildren;
+ }
+
+ // Text
+ if (r.characters != null) {
+ if (characters == null
+ || characters.toString().trim().length() == 0) {
+ characters = new StringBuffer(r.characters.toString());
+ }
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/SubBuildListener.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/SubBuildListener.java
new file mode 100644
index 00000000..196a88b5
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/SubBuildListener.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant;
+
+/**
+ * Instances of classes that implement this interface can register
+ * to be also notified when things happened during a subbuild.
+ *
+ * <p>A subbuild is a separate project instance created by the
+ * <code>&lt;ant&gt;</code> task family. These project instances will
+ * never fire the buildStarted and buildFinished events, but they will
+ * fire subBuildStarted/ and subBuildFinished. The main project
+ * instance - the one created by running Ant in the first place - will
+ * never invoke one of the methods of this interface.</p>
+ *
+ * @see BuildEvent
+ * @see Project#addBuildListener(BuildListener)
+ *
+ * @since Ant 1.6.2
+ */
+public interface SubBuildListener extends BuildListener {
+
+ /**
+ * Signals that a subbuild has started. This event
+ * is fired before any targets have started.
+ *
+ * @param event An event with any relevant extra information.
+ * Must not be <code>null</code>.
+ */
+ void subBuildStarted(BuildEvent event);
+
+ /**
+ * Signals that the last target has finished. This event
+ * will still be fired if an error occurred during the build.
+ *
+ * @param event An event with any relevant extra information.
+ * Must not be <code>null</code>.
+ *
+ * @see BuildEvent#getException()
+ */
+ void subBuildFinished(BuildEvent event);
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/Target.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/Target.java
new file mode 100644
index 00000000..796b7e18
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/Target.java
@@ -0,0 +1,532 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.StringTokenizer;
+
+import org.apache.tools.ant.property.LocalProperties;
+import org.apache.tools.ant.taskdefs.condition.And;
+import org.apache.tools.ant.taskdefs.condition.Condition;
+import org.apache.tools.ant.taskdefs.condition.Or;
+
+/**
+ * Class to implement a target object with required parameters.
+ *
+ * <p>If you are creating Targets programmatically, make sure you set
+ * the Location to a useful value. In particular all targets should
+ * have different location values.</p>
+ */
+public class Target implements TaskContainer {
+
+ /** Name of this target. */
+ private String name;
+
+ /** The "if" condition to test on execution. */
+ private String ifString = "";
+
+ /** The "unless" condition to test on execution. */
+ private String unlessString = "";
+
+ private Condition ifCondition;
+
+ private Condition unlessCondition;
+
+ /** List of targets this target is dependent on. */
+ private List<String> dependencies = null;
+
+ /** Children of this target (tasks and data types). */
+ private List<Object> children = new ArrayList<Object>();
+
+ /** Since Ant 1.6.2 */
+ private Location location = Location.UNKNOWN_LOCATION;
+
+ /** Project this target belongs to. */
+ private Project project;
+
+ /** Description of this target, if any. */
+ private String description = null;
+
+ /** Default constructor. */
+ public Target() {
+ //empty
+ }
+
+ /**
+ * Cloning constructor.
+ * @param other the Target to clone.
+ */
+ public Target(Target other) {
+ this.name = other.name;
+ this.ifString = other.ifString;
+ this.unlessString = other.unlessString;
+ this.ifCondition = other.ifCondition;
+ this.unlessCondition = other.unlessCondition;
+ this.dependencies = other.dependencies;
+ this.location = other.location;
+ this.project = other.project;
+ this.description = other.description;
+ // The children are added to after this cloning
+ this.children = other.children;
+ }
+
+ /**
+ * Sets the project this target belongs to.
+ *
+ * @param project The project this target belongs to.
+ * Must not be <code>null</code>.
+ */
+ public void setProject(Project project) {
+ this.project = project;
+ }
+
+ /**
+ * Returns the project this target belongs to.
+ *
+ * @return The project this target belongs to, or <code>null</code> if
+ * the project has not been set yet.
+ */
+ public Project getProject() {
+ return project;
+ }
+
+ /**
+ * Sets the location of this target's definition.
+ *
+ * @param location <code>Location</code>
+ * @since 1.6.2
+ */
+ public void setLocation(Location location) {
+ this.location = location;
+ }
+
+ /**
+ * Get the location of this target's definition.
+ *
+ * @return <code>Location</code>
+ * @since 1.6.2
+ */
+ public Location getLocation() {
+ return location;
+ }
+
+ /**
+ * Sets the list of targets this target is dependent on.
+ * The targets themselves are not resolved at this time.
+ *
+ * @param depS A comma-separated list of targets this target
+ * depends on. Must not be <code>null</code>.
+ */
+ public void setDepends(String depS) {
+ for (String dep : parseDepends(depS, getName(), "depends")) {
+ addDependency(dep);
+ }
+ }
+
+ public static List<String> parseDepends(String depends,
+ String targetName,
+ String attributeName) {
+ List<String> list = new ArrayList<String>();
+ if (depends.length() > 0) {
+ StringTokenizer tok =
+ new StringTokenizer(depends, ",", true);
+ while (tok.hasMoreTokens()) {
+ String token = tok.nextToken().trim();
+
+ // Make sure the dependency is not empty string
+ if ("".equals(token) || ",".equals(token)) {
+ throw new BuildException("Syntax Error: "
+ + attributeName
+ + " attribute of target \""
+ + targetName
+ + "\" contains an empty string.");
+ }
+
+ list.add(token);
+
+ // Make sure that depends attribute does not
+ // end in a ,
+ if (tok.hasMoreTokens()) {
+ token = tok.nextToken();
+ if (!tok.hasMoreTokens() || !",".equals(token)) {
+ throw new BuildException("Syntax Error: "
+ + attributeName
+ + " attribute for target \""
+ + targetName
+ + "\" ends with a \",\" "
+ + "character");
+ }
+ }
+ }
+ }
+ return list;
+ }
+
+ /**
+ * Sets the name of this target.
+ *
+ * @param name The name of this target. Should not be <code>null</code>.
+ */
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ /**
+ * Returns the name of this target.
+ *
+ * @return the name of this target, or <code>null</code> if the
+ * name has not been set yet.
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Adds a task to this target.
+ *
+ * @param task The task to be added. Must not be <code>null</code>.
+ */
+ public void addTask(Task task) {
+ children.add(task);
+ }
+
+ /**
+ * Adds the wrapper for a data type element to this target.
+ *
+ * @param r The wrapper for the data type element to be added.
+ * Must not be <code>null</code>.
+ */
+ public void addDataType(RuntimeConfigurable r) {
+ children.add(r);
+ }
+
+ /**
+ * Returns the current set of tasks to be executed by this target.
+ *
+ * @return an array of the tasks currently within this target
+ */
+ public Task[] getTasks() {
+ List<Task> tasks = new ArrayList<Task>(children.size());
+ for (Object o : children) {
+ if (o instanceof Task) {
+ tasks.add((Task) o);
+ }
+ }
+ return tasks.toArray(new Task[tasks.size()]);
+ }
+
+ /**
+ * Adds a dependency to this target.
+ *
+ * @param dependency The name of a target this target is dependent on.
+ * Must not be <code>null</code>.
+ */
+ public void addDependency(String dependency) {
+ if (dependencies == null) {
+ dependencies = new ArrayList<String>(2);
+ }
+ dependencies.add(dependency);
+ }
+
+ /**
+ * Returns an enumeration of the dependencies of this target.
+ *
+ * @return an enumeration of the dependencies of this target (enumeration of String)
+ */
+ public Enumeration<String> getDependencies() {
+ return Collections
+ .enumeration(dependencies == null ? Collections.<String> emptyList() : dependencies);
+ }
+
+ /**
+ * Does this target depend on the named target?
+ * @param other the other named target.
+ * @return true if the target does depend on the named target
+ * @since Ant 1.6
+ */
+ public boolean dependsOn(String other) {
+ Project p = getProject();
+ Hashtable<String, Target> t = p == null ? null : p.getTargets();
+ return p != null && p.topoSort(getName(), t, false).contains(t.get(other));
+ }
+
+ /**
+ * Sets the "if" condition to test on execution. This is the
+ * name of a property to test for existence - if the property
+ * is not set, the task will not execute. The property goes
+ * through property substitution once before testing, so if
+ * property <code>foo</code> has value <code>bar</code>, setting
+ * the "if" condition to <code>${foo}_x</code> will mean that the
+ * task will only execute if property <code>bar_x</code> is set.
+ *
+ * @param property The property condition to test on execution.
+ * May be <code>null</code>, in which case
+ * no "if" test is performed.
+ */
+ public void setIf(String property) {
+ ifString = property == null ? "" : property;
+ setIf(new IfStringCondition(ifString));
+ }
+
+ /**
+ * Returns the "if" property condition of this target.
+ *
+ * @return the "if" property condition or <code>null</code> if no
+ * "if" condition had been defined.
+ * @since 1.6.2
+ */
+ public String getIf() {
+ return "".equals(ifString) ? null : ifString;
+ }
+
+ /**
+ * Same as {@link #setIf(String)} but requires a {@link Condition} instance
+ *
+ * @since 1.9
+ */
+ public void setIf(Condition condition) {
+ if (ifCondition == null) {
+ ifCondition = condition;
+ } else {
+ And andCondition = new And();
+ andCondition.setProject(getProject());
+ andCondition.setLocation(getLocation());
+ andCondition.add(ifCondition);
+ andCondition.add(condition);
+ ifCondition = andCondition;
+ }
+ }
+
+ /**
+ * Sets the "unless" condition to test on execution. This is the
+ * name of a property to test for existence - if the property
+ * is set, the task will not execute. The property goes
+ * through property substitution once before testing, so if
+ * property <code>foo</code> has value <code>bar</code>, setting
+ * the "unless" condition to <code>${foo}_x</code> will mean that the
+ * task will only execute if property <code>bar_x</code> isn't set.
+ *
+ * @param property The property condition to test on execution.
+ * May be <code>null</code>, in which case
+ * no "unless" test is performed.
+ */
+ public void setUnless(String property) {
+ unlessString = property == null ? "" : property;
+ setUnless(new UnlessStringCondition(unlessString));
+ }
+
+ /**
+ * Returns the "unless" property condition of this target.
+ *
+ * @return the "unless" property condition or <code>null</code>
+ * if no "unless" condition had been defined.
+ * @since 1.6.2
+ */
+ public String getUnless() {
+ return "".equals(unlessString) ? null : unlessString;
+ }
+
+ /**
+ * Same as {@link #setUnless(String)} but requires a {@link Condition} instance
+ *
+ * @since 1.9
+ */
+ public void setUnless(Condition condition) {
+ if (unlessCondition == null) {
+ unlessCondition = condition;
+ } else {
+ Or orCondition = new Or();
+ orCondition.setProject(getProject());
+ orCondition.setLocation(getLocation());
+ orCondition.add(unlessCondition);
+ orCondition.add(condition);
+ unlessCondition = orCondition;
+ }
+ }
+
+ /**
+ * Sets the description of this target.
+ *
+ * @param description The description for this target.
+ * May be <code>null</code>, indicating that no
+ * description is available.
+ */
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ /**
+ * Returns the description of this target.
+ *
+ * @return the description of this target, or <code>null</code> if no
+ * description is available.
+ */
+ public String getDescription() {
+ return description;
+ }
+
+ /**
+ * Returns the name of this target.
+ *
+ * @return the name of this target, or <code>null</code> if the
+ * name has not been set yet.
+ */
+ public String toString() {
+ return name;
+ }
+
+ /**
+ * Executes the target if the "if" and "unless" conditions are
+ * satisfied. Dependency checking should be done before calling this
+ * method, as it does no checking of its own. If either the "if"
+ * or "unless" test prevents this target from being executed, a verbose
+ * message is logged giving the reason. It is recommended that clients
+ * of this class call performTasks rather than this method so that
+ * appropriate build events are fired.
+ *
+ * @exception BuildException if any of the tasks fail or if a data type
+ * configuration fails.
+ *
+ * @see #performTasks()
+ * @see #setIf(String)
+ * @see #setUnless(String)
+ */
+ public void execute() throws BuildException {
+ if (ifCondition != null && !ifCondition.eval()) {
+ project.log(this, "Skipped because property '" + project.replaceProperties(ifString)
+ + "' not set.", Project.MSG_VERBOSE);
+ return;
+ }
+ if (unlessCondition != null && unlessCondition.eval()) {
+ project.log(this, "Skipped because property '"
+ + project.replaceProperties(unlessString) + "' set.", Project.MSG_VERBOSE);
+ return;
+ }
+ LocalProperties localProperties = LocalProperties.get(getProject());
+ localProperties.enterScope();
+ try {
+ // use index-based approach to avoid ConcurrentModificationExceptions;
+ // also account for growing target children
+ // do not optimize this loop by replacing children.size() by a variable
+ // as children can be added dynamically as in RhinoScriptTest where a target is adding work for itself
+ for (int i = 0; i < children.size(); i++) {
+ Object o = children.get(i);
+ if (o instanceof Task) {
+ Task task = (Task) o;
+ task.perform();
+ } else {
+ ((RuntimeConfigurable) o).maybeConfigure(project);
+ }
+ }
+ } finally {
+ localProperties.exitScope();
+ }
+ }
+
+ /**
+ * Performs the tasks within this target (if the conditions are met),
+ * firing target started/target finished messages around a call to
+ * execute.
+ *
+ * @see #execute()
+ */
+ public final void performTasks() {
+ RuntimeException thrown = null;
+ project.fireTargetStarted(this);
+ try {
+ execute();
+ } catch (RuntimeException exc) {
+ thrown = exc;
+ throw exc;
+ } finally {
+ project.fireTargetFinished(this, thrown);
+ }
+ }
+
+ /**
+ * Replaces all occurrences of the given task in the list
+ * of children with the replacement data type wrapper.
+ *
+ * @param el The task to replace.
+ * Must not be <code>null</code>.
+ * @param o The data type wrapper to replace <code>el</code> with.
+ */
+ void replaceChild(Task el, RuntimeConfigurable o) {
+ int index;
+ while ((index = children.indexOf(el)) >= 0) {
+ children.set(index, o);
+ }
+ }
+
+ /**
+ * Replaces all occurrences of the given task in the list
+ * of children with the replacement task.
+ *
+ * @param el The task to replace.
+ * Must not be <code>null</code>.
+ * @param o The task to replace <code>el</code> with.
+ */
+ void replaceChild(Task el, Task o) {
+ int index;
+ while ((index = children.indexOf(el)) >= 0) {
+ children.set(index, o);
+ }
+ }
+
+ /**
+ * Condition evaluating the 'if' attribute with the PropertyHelper.
+ */
+ private class IfStringCondition implements Condition {
+
+ private String condition;
+
+ public IfStringCondition(String condition) {
+ this.condition = condition;
+ }
+
+ public boolean eval() throws BuildException {
+ PropertyHelper propertyHelper = PropertyHelper.getPropertyHelper(getProject());
+ Object o = propertyHelper.parseProperties(condition);
+ return propertyHelper.testIfCondition(o);
+ }
+
+ }
+
+ /**
+ * Condition evaluating the 'unless' attribute with the PropertyHelper.
+ */
+ private class UnlessStringCondition implements Condition {
+
+ private String condition;
+
+ public UnlessStringCondition(String condition) {
+ this.condition = condition;
+ }
+
+ public boolean eval() throws BuildException {
+ PropertyHelper propertyHelper = PropertyHelper.getPropertyHelper(getProject());
+ Object o = propertyHelper.parseProperties(condition);
+ return !propertyHelper.testUnlessCondition(o);
+ }
+
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/Task.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/Task.java
new file mode 100644
index 00000000..0d08eb0e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/Task.java
@@ -0,0 +1,481 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant;
+
+import java.io.IOException;
+import java.util.Enumeration;
+
+import org.apache.tools.ant.dispatch.DispatchUtils;
+
+/**
+ * Base class for all tasks.
+ *
+ * Use Project.createTask to create a new task instance rather than
+ * using this class directly for construction.
+ *
+ * @see Project#createTask
+ */
+public abstract class Task extends ProjectComponent {
+ // CheckStyle:VisibilityModifier OFF - bc
+ /**
+ * Target this task belongs to, if any.
+ * @deprecated since 1.6.x.
+ * You should not be accessing this variable directly.
+ * Please use the {@link #getOwningTarget()} method.
+ */
+ protected Target target;
+
+ /**
+ * Name of this task to be used for logging purposes.
+ * This defaults to the same as the type, but may be
+ * overridden by the user. For instance, the name "java"
+ * isn't terribly descriptive for a task used within
+ * another task - the outer task code can probably
+ * provide a better one.
+ * @deprecated since 1.6.x.
+ * You should not be accessing this variable directly.
+ * Please use the {@link #getTaskName()} method.
+ */
+ protected String taskName;
+
+ /**
+ * Type of this task.
+ *
+ * @deprecated since 1.6.x.
+ * You should not be accessing this variable directly.
+ * Please use the {@link #getTaskType()} method.
+ */
+ protected String taskType;
+
+ /**
+ * Wrapper for this object, used to configure it at runtime.
+ *
+ * @deprecated since 1.6.x.
+ * You should not be accessing this variable directly.
+ * Please use the {@link #getWrapper()} method.
+ */
+ protected RuntimeConfigurable wrapper;
+
+ // CheckStyle:VisibilityModifier ON
+
+ /**
+ * Whether or not this task is invalid. A task becomes invalid
+ * if a conflicting class is specified as the implementation for
+ * its type.
+ */
+ private boolean invalid;
+
+ /** Sole constructor. */
+ public Task() {
+ }
+
+ /**
+ * Sets the target container of this task.
+ *
+ * @param target Target in whose scope this task belongs.
+ * May be <code>null</code>, indicating a top-level task.
+ */
+ public void setOwningTarget(Target target) {
+ this.target = target;
+ }
+
+ /**
+ * Returns the container target of this task.
+ *
+ * @return The target containing this task, or <code>null</code> if
+ * this task is a top-level task.
+ */
+ public Target getOwningTarget() {
+ return target;
+ }
+
+ /**
+ * Sets the name to use in logging messages.
+ *
+ * @param name The name to use in logging messages.
+ * Should not be <code>null</code>.
+ */
+ public void setTaskName(String name) {
+ this.taskName = name;
+ }
+
+ /**
+ * Returns the name to use in logging messages.
+ *
+ * @return the name to use in logging messages.
+ */
+ public String getTaskName() {
+ return taskName;
+ }
+
+ /**
+ * Sets the name with which the task has been invoked.
+ *
+ * @param type The name the task has been invoked as.
+ * Should not be <code>null</code>.
+ */
+ public void setTaskType(String type) {
+ this.taskType = type;
+ }
+
+ /**
+ * Called by the project to let the task initialize properly.
+ * The default implementation is a no-op.
+ *
+ * @exception BuildException if something goes wrong with the build
+ */
+ public void init() throws BuildException {
+ }
+
+ /**
+ * Called by the project to let the task do its work. This method may be
+ * called more than once, if the task is invoked more than once.
+ * For example,
+ * if target1 and target2 both depend on target3, then running
+ * "ant target1 target2" will run all tasks in target3 twice.
+ *
+ * @exception BuildException if something goes wrong with the build.
+ */
+ public void execute() throws BuildException {
+ }
+
+ /**
+ * Returns the wrapper used for runtime configuration.
+ *
+ * @return the wrapper used for runtime configuration. This
+ * method will generate a new wrapper (and cache it)
+ * if one isn't set already.
+ */
+ public RuntimeConfigurable getRuntimeConfigurableWrapper() {
+ if (wrapper == null) {
+ wrapper = new RuntimeConfigurable(this, getTaskName());
+ }
+ return wrapper;
+ }
+
+ /**
+ * Sets the wrapper to be used for runtime configuration.
+ *
+ * This method should be used only by the ProjectHelper and Ant internals.
+ * It is public to allow helper plugins to operate on tasks, normal tasks
+ * should never use it.
+ *
+ * @param wrapper The wrapper to be used for runtime configuration.
+ * May be <code>null</code>, in which case the next call
+ * to getRuntimeConfigurableWrapper will generate a new
+ * wrapper.
+ */
+ public void setRuntimeConfigurableWrapper(RuntimeConfigurable wrapper) {
+ this.wrapper = wrapper;
+ }
+
+ // TODO: (Jon Skeet) The comment "if it hasn't been done already" may
+ // not be strictly true. wrapper.maybeConfigure() won't configure the same
+ // attributes/text more than once, but it may well add the children again,
+ // unless I've missed something.
+ /**
+ * Configures this task - if it hasn't been done already.
+ * If the task has been invalidated, it is replaced with an
+ * UnknownElement task which uses the new definition in the project.
+ *
+ * @exception BuildException if the task cannot be configured.
+ */
+ public void maybeConfigure() throws BuildException {
+ if (!invalid) {
+ if (wrapper != null) {
+ wrapper.maybeConfigure(getProject());
+ }
+ } else {
+ getReplacement();
+ }
+ }
+
+ /**
+ * Force the task to be reconfigured from its RuntimeConfigurable.
+ */
+ public void reconfigure() {
+ if (wrapper != null) {
+ wrapper.reconfigure(getProject());
+ }
+ }
+
+ /**
+ * Handles output by logging it with the INFO priority.
+ *
+ * @param output The output to log. Should not be <code>null</code>.
+ */
+ protected void handleOutput(String output) {
+ log(output, Project.MSG_INFO);
+ }
+
+ /**
+ * Handles output by logging it with the INFO priority.
+ *
+ * @param output The output to log. Should not be <code>null</code>.
+ *
+ * @since Ant 1.5.2
+ */
+ protected void handleFlush(String output) {
+ handleOutput(output);
+ }
+
+ /**
+ * Handle an input request by this task.
+ *
+ * @param buffer the buffer into which data is to be read.
+ * @param offset the offset into the buffer at which data is stored.
+ * @param length the amount of data to read.
+ *
+ * @return the number of bytes read.
+ *
+ * @exception IOException if the data cannot be read.
+ * @since Ant 1.6
+ */
+ protected int handleInput(byte[] buffer, int offset, int length)
+ throws IOException {
+ return getProject().defaultInput(buffer, offset, length);
+ }
+
+ /**
+ * Handles an error output by logging it with the WARN priority.
+ *
+ * @param output The error output to log. Should not be <code>null</code>.
+ */
+ protected void handleErrorOutput(String output) {
+ log(output, Project.MSG_WARN);
+ }
+
+ /**
+ * Handles an error line by logging it with the WARN priority.
+ *
+ * @param output The error output to log. Should not be <code>null</code>.
+ *
+ * @since Ant 1.5.2
+ */
+ protected void handleErrorFlush(String output) {
+ handleErrorOutput(output);
+ }
+
+ /**
+ * Logs a message with the default (INFO) priority.
+ *
+ * @param msg The message to be logged. Should not be <code>null</code>.
+ */
+ public void log(String msg) {
+ log(msg, Project.MSG_INFO);
+ }
+
+ /**
+ * Logs a message with the given priority. This delegates
+ * the actual logging to the project.
+ *
+ * @param msg The message to be logged. Should not be <code>null</code>.
+ * @param msgLevel The message priority at which this message is to
+ * be logged.
+ */
+ public void log(String msg, int msgLevel) {
+ if (getProject() != null) {
+ getProject().log(this, msg, msgLevel);
+ } else {
+ super.log(msg, msgLevel);
+ }
+ }
+
+ /**
+ * Logs a message with the given priority. This delegates
+ * the actual logging to the project.
+ *
+ * @param t The exception to be logged. Should not be <code>null</code>.
+ * @param msgLevel The message priority at which this message is to
+ * be logged.
+ * @since 1.7
+ */
+ public void log(Throwable t, int msgLevel) {
+ if (t != null) {
+ log(t.getMessage(), t, msgLevel);
+ }
+ }
+
+ /**
+ * Logs a message with the given priority. This delegates
+ * the actual logging to the project.
+ *
+ * @param msg The message to be logged. Should not be <code>null</code>.
+ * @param t The exception to be logged. May be <code>null</code>.
+ * @param msgLevel The message priority at which this message is to
+ * be logged.
+ * @since 1.7
+ */
+ public void log(String msg, Throwable t, int msgLevel) {
+ if (getProject() != null) {
+ getProject().log(this, msg, t, msgLevel);
+ } else {
+ super.log(msg, msgLevel);
+ }
+ }
+
+ /**
+ * Performs this task if it's still valid, or gets a replacement
+ * version and performs that otherwise.
+ *
+ * Performing a task consists of firing a task started event,
+ * configuring the task, executing it, and then firing task finished
+ * event. If a runtime exception is thrown, the task finished event
+ * is still fired, but with the exception as the cause.
+ */
+ public final void perform() {
+ if (!invalid) {
+ getProject().fireTaskStarted(this);
+ Throwable reason = null;
+ try {
+ maybeConfigure();
+ DispatchUtils.execute(this);
+ } catch (BuildException ex) {
+ if (ex.getLocation() == Location.UNKNOWN_LOCATION) {
+ ex.setLocation(getLocation());
+ }
+ reason = ex;
+ throw ex;
+ } catch (Exception ex) {
+ reason = ex;
+ BuildException be = new BuildException(ex);
+ be.setLocation(getLocation());
+ throw be;
+ } catch (Error ex) {
+ reason = ex;
+ throw ex;
+ } finally {
+ getProject().fireTaskFinished(this, reason);
+ }
+ } else {
+ UnknownElement ue = getReplacement();
+ Task task = ue.getTask();
+ task.perform();
+ }
+ }
+
+ /**
+ * Marks this task as invalid. Any further use of this task
+ * will go through a replacement with the updated definition.
+ */
+ final void markInvalid() {
+ invalid = true;
+ }
+
+ /**
+ * Has this task been marked invalid?
+ *
+ * @return true if this task is no longer valid. A new task should be
+ * configured in this case.
+ *
+ * @since Ant 1.5
+ */
+ protected final boolean isInvalid() {
+ return invalid;
+ }
+
+ /**
+ * Replacement element used if this task is invalidated.
+ */
+ private UnknownElement replacement;
+
+ /**
+ * Creates an UnknownElement that can be used to replace this task.
+ * Once this has been created once, it is cached and returned by
+ * future calls.
+ *
+ * @return the UnknownElement instance for the new definition of this task.
+ */
+ private UnknownElement getReplacement() {
+ if (replacement == null) {
+ replacement = new UnknownElement(taskType);
+ replacement.setProject(getProject());
+ replacement.setTaskType(taskType);
+ replacement.setTaskName(taskName);
+ replacement.setLocation(getLocation());
+ replacement.setOwningTarget(target);
+ replacement.setRuntimeConfigurableWrapper(wrapper);
+ wrapper.setProxy(replacement);
+ replaceChildren(wrapper, replacement);
+ target.replaceChild(this, replacement);
+ replacement.maybeConfigure();
+ }
+ return replacement;
+ }
+
+ /**
+ * Recursively adds an UnknownElement instance for each child
+ * element of replacement.
+ *
+ * @since Ant 1.5.1
+ */
+ private void replaceChildren(RuntimeConfigurable wrapper,
+ UnknownElement parentElement) {
+ Enumeration<RuntimeConfigurable> e = wrapper.getChildren();
+ while (e.hasMoreElements()) {
+ RuntimeConfigurable childWrapper = e.nextElement();
+ UnknownElement childElement =
+ new UnknownElement(childWrapper.getElementTag());
+ parentElement.addChild(childElement);
+ childElement.setProject(getProject());
+ childElement.setRuntimeConfigurableWrapper(childWrapper);
+ childWrapper.setProxy(childElement);
+ replaceChildren(childWrapper, childElement);
+ }
+ }
+
+ /**
+ * Return the type of task.
+ *
+ * @return the type of task.
+ */
+ public String getTaskType() {
+ return taskType;
+ }
+
+ /**
+ * Return the runtime configurable structure for this task.
+ *
+ * @return the runtime structure for this task.
+ */
+ protected RuntimeConfigurable getWrapper() {
+ return wrapper;
+ }
+
+ /**
+ * Bind a task to another; use this when configuring a newly created
+ * task to do work on behalf of another.
+ * Project, OwningTarget, TaskName, Location and Description are all copied
+ *
+ * Important: this method does not call {@link Task#init()}.
+ * If you are creating a task to delegate work to, call {@link Task#init()}
+ * to initialize it.
+ *
+ * @param owner owning target
+ * @since Ant1.7
+ */
+ public final void bindToOwner(Task owner) {
+ setProject(owner.getProject());
+ setOwningTarget(owner.getOwningTarget());
+ setTaskName(owner.getTaskName());
+ setDescription(owner.getDescription());
+ setLocation(owner.getLocation());
+ setTaskType(owner.getTaskType());
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/TaskAdapter.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/TaskAdapter.java
new file mode 100644
index 00000000..3a3001f6
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/TaskAdapter.java
@@ -0,0 +1,182 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant;
+
+import java.lang.reflect.Method;
+
+import org.apache.tools.ant.dispatch.DispatchUtils;
+import org.apache.tools.ant.dispatch.Dispatchable;
+
+/**
+ * Uses introspection to "adapt" an arbitrary Bean which doesn't
+ * itself extend Task, but still contains an execute method and optionally
+ * a setProject method.
+ *
+ */
+public class TaskAdapter extends Task implements TypeAdapter {
+
+ /** Object to act as a proxy for. */
+ private Object proxy;
+
+ /**
+ * No-arg constructor for reflection.
+ */
+ public TaskAdapter() {
+ }
+
+ /**
+ * Constructor for given proxy.
+ * So you could write easier code
+ * <pre>
+ * myTaskContainer.addTask( new TaskAdapter(myProxy) );
+ * </pre>
+ *
+ * @param proxy The object which Ant should use as task.
+ */
+ public TaskAdapter(Object proxy) {
+ this();
+ setProxy(proxy);
+ }
+
+ /**
+ * Checks whether or not a class is suitable to be adapted by TaskAdapter.
+ * If the class is of type Dispatchable, the check is not performed because
+ * the method that will be executed will be determined only at runtime of
+ * the actual task and not during parse time.
+ *
+ * This only checks conditions which are additionally required for
+ * tasks adapted by TaskAdapter. Thus, this method should be called by
+ * Project.checkTaskClass.
+ *
+ * Throws a BuildException and logs as Project.MSG_ERR for
+ * conditions that will cause the task execution to fail.
+ * Logs other suspicious conditions with Project.MSG_WARN.
+ *
+ * @param taskClass Class to test for suitability.
+ * Must not be <code>null</code>.
+ * @param project Project to log warnings/errors to.
+ * Must not be <code>null</code>.
+ *
+ * @see Project#checkTaskClass(Class)
+ */
+ public static void checkTaskClass(final Class<?> taskClass,
+ final Project project) {
+ if (!Dispatchable.class.isAssignableFrom(taskClass)) {
+ // don't have to check for interface, since then
+ // taskClass would be abstract too.
+ try {
+ final Method executeM = taskClass.getMethod("execute", (Class[]) null);
+ // don't have to check for public, since
+ // getMethod finds public method only.
+ // don't have to check for abstract, since then
+ // taskClass would be abstract too.
+ if (!Void.TYPE.equals(executeM.getReturnType())) {
+ final String message = "return type of execute() should be "
+ + "void but was \"" + executeM.getReturnType() + "\" in "
+ + taskClass;
+ project.log(message, Project.MSG_WARN);
+ }
+ } catch (NoSuchMethodException e) {
+ final String message = "No public execute() in " + taskClass;
+ project.log(message, Project.MSG_ERR);
+ throw new BuildException(message);
+ } catch (LinkageError e) {
+ String message = "Could not load " + taskClass + ": " + e;
+ project.log(message, Project.MSG_ERR);
+ throw new BuildException(message, e);
+ }
+ }
+ }
+
+ /**
+ * Check if the proxy class is a valid class to use
+ * with this adapter.
+ * The class must have a public no-arg "execute()" method.
+ * @param proxyClass the class to check.
+ */
+ public void checkProxyClass(Class<?> proxyClass) {
+ checkTaskClass(proxyClass, getProject());
+ }
+
+ /**
+ * Executes the proxied task.
+ *
+ * @exception BuildException if the project could not be set
+ * or the method could not be executed.
+ */
+ public void execute() throws BuildException {
+ try {
+ Method setLocationM = proxy.getClass().getMethod(
+ "setLocation", new Class[] {Location.class});
+ if (setLocationM != null) {
+ setLocationM.invoke(proxy, new Object[] {getLocation()});
+ }
+ } catch (NoSuchMethodException e) {
+ // ignore this if the class being used as a task does not have
+ // a set location method.
+ } catch (Exception ex) {
+ log("Error setting location in " + proxy.getClass(),
+ Project.MSG_ERR);
+ throw new BuildException(ex);
+ }
+
+ try {
+ Method setProjectM = proxy.getClass().getMethod(
+ "setProject", new Class[] {Project.class});
+ if (setProjectM != null) {
+ setProjectM.invoke(proxy, new Object[] {getProject()});
+ }
+ } catch (NoSuchMethodException e) {
+ // ignore this if the class being used as a task does not have
+ // a set project method.
+ } catch (Exception ex) {
+ log("Error setting project in " + proxy.getClass(),
+ Project.MSG_ERR);
+ throw new BuildException(ex);
+ }
+
+ try {
+ DispatchUtils.execute(proxy);
+ } catch (BuildException be) {
+ throw be;
+ } catch (Exception ex) {
+ log("Error in " + proxy.getClass(), Project.MSG_VERBOSE);
+ throw new BuildException(ex);
+ }
+ }
+
+ /**
+ * Sets the target object to proxy for.
+ *
+ * @param o The target object. Must not be <code>null</code>.
+ */
+ public void setProxy(Object o) {
+ this.proxy = o;
+ }
+
+ /**
+ * Returns the target object being proxied.
+ *
+ * @return the target proxy object.
+ */
+ public Object getProxy() {
+ return proxy;
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/TaskConfigurationChecker.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/TaskConfigurationChecker.java
new file mode 100644
index 00000000..e8e74441
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/TaskConfigurationChecker.java
@@ -0,0 +1,111 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * <p>Helper class for the check of the configuration of a given task.
+ * This class provides methods for making assumptions about the task configuration.
+ * After collecting all violations with <tt>assert*</tt> and <tt>fail</tt>
+ * methods the <tt>checkErrors</tt> will throw a BuildException with all collected
+ * messages or does nothing if there wasn't any error.</p>
+ *
+ * <p>Example:</p>
+ *
+ * <pre>
+ * public class MyTask extends Task {
+ * ...
+ * public void execute() {
+ * TaskConfigurationChecker checker = TaskConfigurationChecker(this);
+ * checker.assertConfig(
+ * srcdir != null,
+ * "Attribute 'srcdir' must be set.
+ * );
+ * checker.assertConfig(
+ * srcdir.exists(),
+ * "Srcdir (" + srcdir + ") must exist."
+ * );
+ * if (someComplexCondition()) {
+ * fail("Complex condition failed.");
+ * }
+ * checker.checkErrors();
+ * }
+ * }
+ * </pre>
+ *
+ * @see <a href="http://martinfowler.com/eaaDev/Notification.html">Notification Pattern</a>
+ */
+public class TaskConfigurationChecker {
+
+ /** List of all collected error messages. */
+ private List<String> errors = new ArrayList<String>();
+
+ /** Task for which the configuration should be checked. */
+ private final Task task;
+
+ /**
+ * Constructor.
+ * @param task which task should be checked
+ */
+ public TaskConfigurationChecker(Task task) {
+ this.task = task;
+ }
+
+ /**
+ * Asserts that a condition is true.
+ * @param condition which condition to check
+ * @param errormessage errormessage to throw if a condition failed
+ */
+ public void assertConfig(boolean condition, String errormessage) {
+ if (!condition) {
+ errors.add(errormessage);
+ }
+ }
+
+ /**
+ * Registers an error.
+ * @param errormessage the message for the registered error
+ */
+ public void fail(String errormessage) {
+ errors.add(errormessage);
+ }
+
+ /**
+ * Checks if there are any collected errors and throws a BuildException
+ * with all messages if there was one or more.
+ * @throws BuildException if one or more errors were registered
+ */
+ public void checkErrors() throws BuildException {
+ if (!errors.isEmpty()) {
+ StringBuffer sb = new StringBuffer();
+ sb.append("Configurationerror on <");
+ sb.append(task.getTaskName());
+ sb.append(">:");
+ sb.append(System.getProperty("line.separator"));
+ for (String msg : errors) {
+ sb.append("- ");
+ sb.append(msg);
+ sb.append(System.getProperty("line.separator"));
+ }
+ throw new BuildException(sb.toString(), task.getLocation());
+ }
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/TaskContainer.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/TaskContainer.java
new file mode 100644
index 00000000..12e8c075
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/TaskContainer.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant;
+
+/**
+ * Interface for objects which can contain tasks.
+ * <p>
+ * It is recommended that implementations call perform rather than
+ * execute for the tasks they contain, as this method ensures that the
+ * appropriate BuildEvents will be generated.
+ *
+ * @see Task#perform
+ * @see Task#execute
+ * @see BuildEvent
+ *
+ */
+public interface TaskContainer {
+ /**
+ * Adds a task to this task container
+ *
+ * @param task The task to be added to this container.
+ * Must not be <code>null</code>.
+ */
+ void addTask(Task task);
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/TypeAdapter.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/TypeAdapter.java
new file mode 100644
index 00000000..b8520fce
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/TypeAdapter.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant;
+
+/**
+ * Used to wrap types.
+ *
+ */
+public interface TypeAdapter {
+
+ /**
+ * Sets the project
+ *
+ * @param p the project instance.
+ */
+ void setProject(Project p);
+
+ /**
+ * Gets the project
+ *
+ * @return the project instance.
+ */
+ Project getProject();
+
+ /**
+ * Sets the proxy object, whose methods are going to be
+ * invoked by ant.
+ * A proxy object is normally the object defined by
+ * a &lt;typedef/&gt; task that is adapted by the "adapter"
+ * attribute.
+ *
+ * @param o The target object. Must not be <code>null</code>.
+ */
+ void setProxy(Object o);
+
+ /**
+ * Returns the proxy object.
+ *
+ * @return the target proxy object
+ */
+ Object getProxy();
+
+ /**
+ * Check if the proxy class is compatible with this adapter - i.e.
+ * the adapter will be able to adapt instances of the give class.
+ *
+ * @param proxyClass the class to be checked.
+ */
+ void checkProxyClass(Class<?> proxyClass);
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/UnknownElement.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/UnknownElement.java
new file mode 100644
index 00000000..88cd4989
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/UnknownElement.java
@@ -0,0 +1,699 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.tools.ant.taskdefs.PreSetDef;
+
+/**
+ * Wrapper class that holds all the information necessary to create a task
+ * or data type that did not exist when Ant started, or one which
+ * has had its definition updated to use a different implementation class.
+ *
+ */
+public class UnknownElement extends Task {
+
+ /**
+ * Holds the name of the task/type or nested child element of a
+ * task/type that hasn't been defined at parser time or has
+ * been redefined since original creation.
+ */
+ private final String elementName;
+
+ /**
+ * Holds the namespace of the element.
+ */
+ private String namespace = "";
+
+ /**
+ * Holds the namespace qname of the element.
+ */
+ private String qname;
+
+ /**
+ * The real object after it has been loaded.
+ */
+ private Object realThing;
+
+ /**
+ * List of child elements (UnknownElements).
+ */
+ private List<UnknownElement> children = null;
+
+ /** Specifies if a predefined definition has been done */
+ private boolean presetDefed = false;
+
+ /**
+ * Creates an UnknownElement for the given element name.
+ *
+ * @param elementName The name of the unknown element.
+ * Must not be <code>null</code>.
+ */
+ public UnknownElement(String elementName) {
+ this.elementName = elementName;
+ }
+
+ /**
+ * @return the list of nested UnknownElements for this UnknownElement.
+ */
+ public List<UnknownElement> getChildren() {
+ return children;
+ }
+
+ /**
+ * Returns the name of the XML element which generated this unknown
+ * element.
+ *
+ * @return the name of the XML element which generated this unknown
+ * element.
+ */
+ public String getTag() {
+ return elementName;
+ }
+
+ /**
+ * Return the namespace of the XML element associated with this component.
+ *
+ * @return Namespace URI used in the xmlns declaration.
+ */
+ public String getNamespace() {
+ return namespace;
+ }
+
+ /**
+ * Set the namespace of the XML element associated with this component.
+ * This method is typically called by the XML processor.
+ * If the namespace is "ant:current", the component helper
+ * is used to get the current antlib uri.
+ *
+ * @param namespace URI used in the xmlns declaration.
+ */
+ public void setNamespace(String namespace) {
+ if (namespace.equals(ProjectHelper.ANT_CURRENT_URI)) {
+ ComponentHelper helper = ComponentHelper.getComponentHelper(
+ getProject());
+ namespace = helper.getCurrentAntlibUri();
+ }
+ this.namespace = namespace == null ? "" : namespace;
+ }
+
+ /**
+ * Return the qname of the XML element associated with this component.
+ *
+ * @return namespace Qname used in the element declaration.
+ */
+ public String getQName() {
+ return qname;
+ }
+
+ /**
+ * Set the namespace qname of the XML element.
+ * This method is typically called by the XML processor.
+ *
+ * @param qname the qualified name of the element
+ */
+ public void setQName(String qname) {
+ this.qname = qname;
+ }
+
+
+ /**
+ * Get the RuntimeConfigurable instance for this UnknownElement, containing
+ * the configuration information.
+ *
+ * @return the configuration info.
+ */
+ public RuntimeConfigurable getWrapper() {
+ return super.getWrapper();
+ }
+
+ /**
+ * Creates the real object instance and child elements, then configures
+ * the attributes and text of the real object. This unknown element
+ * is then replaced with the real object in the containing target's list
+ * of children.
+ *
+ * @exception BuildException if the configuration fails
+ */
+ public void maybeConfigure() throws BuildException {
+ if (realThing != null) {
+ return;
+ }
+ configure(makeObject(this, getWrapper()));
+ }
+
+ /**
+ * Configure the given object from this UnknownElement
+ *
+ * @param realObject the real object this UnknownElement is representing.
+ *
+ */
+ public void configure(Object realObject) {
+ if (realObject == null) {
+ return;
+ }
+ realThing = realObject;
+
+ getWrapper().setProxy(realThing);
+ Task task = null;
+ if (realThing instanceof Task) {
+ task = (Task) realThing;
+
+ task.setRuntimeConfigurableWrapper(getWrapper());
+
+ // For Script example that modifies id'ed tasks in other
+ // targets to work. *very* Ugly
+ // The reference is replaced by RuntimeConfigurable
+ if (getWrapper().getId() != null) {
+ this.getOwningTarget().replaceChild(this, (Task) realThing);
+ }
+ }
+
+
+ // configure attributes of the object and it's children. If it is
+ // a task container, defer the configuration till the task container
+ // attempts to use the task
+
+ if (task != null) {
+ task.maybeConfigure();
+ } else {
+ getWrapper().maybeConfigure(getProject());
+ }
+
+ handleChildren(realThing, getWrapper());
+ }
+
+ /**
+ * Handles output sent to System.out by this task or its real task.
+ *
+ * @param output The output to log. Should not be <code>null</code>.
+ */
+ protected void handleOutput(String output) {
+ if (realThing instanceof Task) {
+ ((Task) realThing).handleOutput(output);
+ } else {
+ super.handleOutput(output);
+ }
+ }
+
+ /**
+ * Delegate to realThing if present and if it as task.
+ * @see Task#handleInput(byte[], int, int)
+ * @param buffer the buffer into which data is to be read.
+ * @param offset the offset into the buffer at which data is stored.
+ * @param length the amount of data to read.
+ *
+ * @return the number of bytes read.
+ *
+ * @exception IOException if the data cannot be read.
+ * @since Ant 1.6
+ */
+ protected int handleInput(byte[] buffer, int offset, int length)
+ throws IOException {
+ if (realThing instanceof Task) {
+ return ((Task) realThing).handleInput(buffer, offset, length);
+ } else {
+ return super.handleInput(buffer, offset, length);
+ }
+
+ }
+
+ /**
+ * Handles output sent to System.out by this task or its real task.
+ *
+ * @param output The output to log. Should not be <code>null</code>.
+ */
+ protected void handleFlush(String output) {
+ if (realThing instanceof Task) {
+ ((Task) realThing).handleFlush(output);
+ } else {
+ super.handleFlush(output);
+ }
+ }
+
+ /**
+ * Handles error output sent to System.err by this task or its real task.
+ *
+ * @param output The error output to log. Should not be <code>null</code>.
+ */
+ protected void handleErrorOutput(String output) {
+ if (realThing instanceof Task) {
+ ((Task) realThing).handleErrorOutput(output);
+ } else {
+ super.handleErrorOutput(output);
+ }
+ }
+
+ /**
+ * Handles error output sent to System.err by this task or its real task.
+ *
+ * @param output The error output to log. Should not be <code>null</code>.
+ */
+ protected void handleErrorFlush(String output) {
+ if (realThing instanceof Task) {
+ ((Task) realThing).handleErrorFlush(output);
+ } else {
+ super.handleErrorFlush(output);
+ }
+ }
+
+ /**
+ * Executes the real object if it's a task. If it's not a task
+ * (e.g. a data type) then this method does nothing.
+ */
+ public void execute() {
+ if (realThing == null) {
+ // Got here if the runtimeconfigurable is not enabled.
+ return;
+ }
+ try {
+ if (realThing instanceof Task) {
+ ((Task) realThing).execute();
+ }
+ } finally {
+ // Finished executing the task
+ // null it (unless it has an ID) to allow
+ // GC do its job
+ // If this UE is used again, a new "realthing" will be made
+ if (getWrapper().getId() == null) {
+ realThing = null;
+ getWrapper().setProxy(null);
+ }
+ }
+ }
+
+ /**
+ * Adds a child element to this element.
+ *
+ * @param child The child element to add. Must not be <code>null</code>.
+ */
+ public void addChild(UnknownElement child) {
+ if (children == null) {
+ children = new ArrayList<UnknownElement>();
+ }
+ children.add(child);
+ }
+
+ /**
+ * Creates child elements, creates children of the children
+ * (recursively), and sets attributes of the child elements.
+ *
+ * @param parent The configured object for the parent.
+ * Must not be <code>null</code>.
+ *
+ * @param parentWrapper The wrapper containing child wrappers
+ * to be configured. Must not be <code>null</code>
+ * if there are any children.
+ *
+ * @exception BuildException if the children cannot be configured.
+ */
+ protected void handleChildren(
+ Object parent,
+ RuntimeConfigurable parentWrapper)
+ throws BuildException {
+ if (parent instanceof TypeAdapter) {
+ parent = ((TypeAdapter) parent).getProxy();
+ }
+
+ String parentUri = getNamespace();
+ Class<?> parentClass = parent.getClass();
+ IntrospectionHelper ih = IntrospectionHelper.getHelper(getProject(), parentClass);
+
+
+ if (children != null) {
+ Iterator<UnknownElement> it = children.iterator();
+ for (int i = 0; it.hasNext(); i++) {
+ RuntimeConfigurable childWrapper = parentWrapper.getChild(i);
+ UnknownElement child = it.next();
+ try {
+ if (!childWrapper.isEnabled(child)) {
+ if (ih.supportsNestedElement(
+ parentUri, ProjectHelper.genComponentName(
+ child.getNamespace(), child.getTag()))) {
+ continue;
+ }
+ // fall tru and fail in handlechild (unsupported element)
+ }
+ if (!handleChild(
+ parentUri, ih, parent, child, childWrapper)) {
+ if (!(parent instanceof TaskContainer)) {
+ ih.throwNotSupported(getProject(), parent,
+ child.getTag());
+ } else {
+ // a task container - anything could happen - just add the
+ // child to the container
+ TaskContainer container = (TaskContainer) parent;
+ container.addTask(child);
+ }
+ }
+ } catch (UnsupportedElementException ex) {
+ throw new BuildException(
+ parentWrapper.getElementTag()
+ + " doesn't support the nested \"" + ex.getElement()
+ + "\" element.", ex);
+ }
+ }
+ }
+ }
+
+ /**
+ * @return the component name - uses ProjectHelper#genComponentName()
+ */
+ protected String getComponentName() {
+ return ProjectHelper.genComponentName(getNamespace(), getTag());
+ }
+
+ /**
+ * This is used then the realobject of the UE is a PreSetDefinition.
+ * This is also used when a presetdef is used on a presetdef
+ * The attributes, elements and text are applied to this
+ * UE.
+ *
+ * @param u an UnknownElement containing the attributes, elements and text
+ */
+ public void applyPreSet(UnknownElement u) {
+ if (presetDefed) {
+ return;
+ }
+ // Do the runtime
+ getWrapper().applyPreSet(u.getWrapper());
+ if (u.children != null) {
+ List<UnknownElement> newChildren = new ArrayList<UnknownElement>();
+ newChildren.addAll(u.children);
+ if (children != null) {
+ newChildren.addAll(children);
+ }
+ children = newChildren;
+ }
+ presetDefed = true;
+ }
+
+ /**
+ * Creates a named task or data type. If the real object is a task,
+ * it is configured up to the init() stage.
+ *
+ * @param ue The unknown element to create the real object for.
+ * Must not be <code>null</code>.
+ * @param w Ignored in this implementation.
+ *
+ * @return the task or data type represented by the given unknown element.
+ */
+ protected Object makeObject(UnknownElement ue, RuntimeConfigurable w) {
+ if (!w.isEnabled(ue)) {
+ return null;
+ }
+ ComponentHelper helper = ComponentHelper.getComponentHelper(
+ getProject());
+ String name = ue.getComponentName();
+ Object o = helper.createComponent(ue, ue.getNamespace(), name);
+ if (o == null) {
+ throw getNotFoundException("task or type", name);
+ }
+ if (o instanceof PreSetDef.PreSetDefinition) {
+ PreSetDef.PreSetDefinition def = (PreSetDef.PreSetDefinition) o;
+ o = def.createObject(ue.getProject());
+ if (o == null) {
+ throw getNotFoundException(
+ "preset " + name,
+ def.getPreSets().getComponentName());
+ }
+ ue.applyPreSet(def.getPreSets());
+ if (o instanceof Task) {
+ Task task = (Task) o;
+ task.setTaskType(ue.getTaskType());
+ task.setTaskName(ue.getTaskName());
+ task.init();
+ }
+ }
+ if (o instanceof UnknownElement) {
+ o = ((UnknownElement) o).makeObject((UnknownElement) o, w);
+ }
+ if (o instanceof Task) {
+ ((Task) o).setOwningTarget(getOwningTarget());
+ }
+ if (o instanceof ProjectComponent) {
+ ((ProjectComponent) o).setLocation(getLocation());
+ }
+ return o;
+ }
+
+ /**
+ * Creates a named task and configures it up to the init() stage.
+ *
+ * @param ue The UnknownElement to create the real task for.
+ * Must not be <code>null</code>.
+ * @param w Ignored.
+ *
+ * @return the task specified by the given unknown element, or
+ * <code>null</code> if the task name is not recognised.
+ */
+ protected Task makeTask(UnknownElement ue, RuntimeConfigurable w) {
+ Task task = getProject().createTask(ue.getTag());
+
+ if (task != null) {
+ task.setLocation(getLocation());
+ // UnknownElement always has an associated target
+ task.setOwningTarget(getOwningTarget());
+ task.init();
+ }
+ return task;
+ }
+
+ /**
+ * Returns a very verbose exception for when a task/data type cannot
+ * be found.
+ *
+ * @param what The kind of thing being created. For example, when
+ * a task name could not be found, this would be
+ * <code>"task"</code>. Should not be <code>null</code>.
+ * @param name The name of the element which could not be found.
+ * Should not be <code>null</code>.
+ *
+ * @return a detailed description of what might have caused the problem.
+ */
+ protected BuildException getNotFoundException(String what,
+ String name) {
+ ComponentHelper helper = ComponentHelper.getComponentHelper(getProject());
+ String msg = helper.diagnoseCreationFailure(name, what);
+ return new BuildException(msg, getLocation());
+ }
+
+ /**
+ * Returns the name to use in logging messages.
+ *
+ * @return the name to use in logging messages.
+ */
+ public String getTaskName() {
+ //return elementName;
+ return realThing == null
+ || !(realThing instanceof Task) ? super.getTaskName()
+ : ((Task) realThing).getTaskName();
+ }
+
+ /**
+ * Returns the task instance after it has been created and if it is a task.
+ *
+ * @return a task instance or <code>null</code> if the real object is not
+ * a task.
+ */
+ public Task getTask() {
+ if (realThing instanceof Task) {
+ return (Task) realThing;
+ }
+ return null;
+ }
+
+ /**
+ * Return the configured object
+ *
+ * @return the real thing whatever it is
+ *
+ * @since ant 1.6
+ */
+ public Object getRealThing() {
+ return realThing;
+ }
+
+ /**
+ * Set the configured object
+ * @param realThing the configured object
+ * @since ant 1.7
+ */
+ public void setRealThing(Object realThing) {
+ this.realThing = realThing;
+ }
+
+ /**
+ * Try to create a nested element of <code>parent</code> for the
+ * given tag.
+ *
+ * @return whether the creation has been successful
+ */
+ private boolean handleChild(
+ String parentUri,
+ IntrospectionHelper ih,
+ Object parent, UnknownElement child,
+ RuntimeConfigurable childWrapper) {
+ String childName = ProjectHelper.genComponentName(
+ child.getNamespace(), child.getTag());
+ if (ih.supportsNestedElement(parentUri, childName, getProject(),
+ parent)) {
+ IntrospectionHelper.Creator creator = null;
+ try {
+ creator = ih.getElementCreator(getProject(), parentUri,
+ parent, childName, child);
+ } catch (UnsupportedElementException use) {
+ if (!ih.isDynamic()) {
+ throw use;
+ }
+ // can't trust supportsNestedElement for dynamic elements
+ return false;
+ }
+ creator.setPolyType(childWrapper.getPolyType());
+ Object realChild = creator.create();
+ if (realChild instanceof PreSetDef.PreSetDefinition) {
+ PreSetDef.PreSetDefinition def =
+ (PreSetDef.PreSetDefinition) realChild;
+ realChild = creator.getRealObject();
+ child.applyPreSet(def.getPreSets());
+ }
+ childWrapper.setCreator(creator);
+ childWrapper.setProxy(realChild);
+ if (realChild instanceof Task) {
+ Task childTask = (Task) realChild;
+ childTask.setRuntimeConfigurableWrapper(childWrapper);
+ childTask.setTaskName(childName);
+ childTask.setTaskType(childName);
+ }
+ if (realChild instanceof ProjectComponent) {
+ ((ProjectComponent) realChild).setLocation(child.getLocation());
+ }
+ childWrapper.maybeConfigure(getProject());
+ child.handleChildren(realChild, childWrapper);
+ creator.store();
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * like contents equals, but ignores project
+ * @param obj the object to check against
+ * @return true if this unknownelement has the same contents the other
+ */
+ public boolean similar(Object obj) {
+ if (obj == null) {
+ return false;
+ }
+ if (!getClass().getName().equals(obj.getClass().getName())) {
+ return false;
+ }
+ UnknownElement other = (UnknownElement) obj;
+ // Are the names the same ?
+ if (!equalsString(elementName, other.elementName)) {
+ return false;
+ }
+ if (!namespace.equals(other.namespace)) {
+ return false;
+ }
+ if (!qname.equals(other.qname)) {
+ return false;
+ }
+ // Are attributes the same ?
+ if (!getWrapper().getAttributeMap().equals(
+ other.getWrapper().getAttributeMap())) {
+ return false;
+ }
+ // Is the text the same?
+ // Need to use equals on the string and not
+ // on the stringbuffer as equals on the string buffer
+ // does not compare the contents.
+ if (!getWrapper().getText().toString().equals(
+ other.getWrapper().getText().toString())) {
+ return false;
+ }
+ // Are the sub elements the same ?
+ final int childrenSize = children == null ? 0 : children.size();
+ if (childrenSize == 0) {
+ return other.children == null || other.children.size() == 0;
+ }
+ if (other.children == null) {
+ return false;
+ }
+ if (childrenSize != other.children.size()) {
+ return false;
+ }
+ for (int i = 0; i < childrenSize; ++i) {
+ UnknownElement child = (UnknownElement) children.get(i);
+ if (!child.similar(other.children.get(i))) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private static boolean equalsString(String a, String b) {
+ return (a == null) ? (b == null) : a.equals(b);
+ }
+
+ /**
+ * Make a copy of the unknown element and set it in the new project.
+ * @param newProject the project to create the UE in.
+ * @return the copied UE.
+ */
+ public UnknownElement copy(Project newProject) {
+ UnknownElement ret = new UnknownElement(getTag());
+ ret.setNamespace(getNamespace());
+ ret.setProject(newProject);
+ ret.setQName(getQName());
+ ret.setTaskType(getTaskType());
+ ret.setTaskName(getTaskName());
+ ret.setLocation(getLocation());
+ if (getOwningTarget() == null) {
+ Target t = new Target();
+ t.setProject(getProject());
+ ret.setOwningTarget(t);
+ } else {
+ ret.setOwningTarget(getOwningTarget());
+ }
+ RuntimeConfigurable copyRC = new RuntimeConfigurable(
+ ret, getTaskName());
+ copyRC.setPolyType(getWrapper().getPolyType());
+ Map<String, Object> m = getWrapper().getAttributeMap();
+ for (Map.Entry<String, Object> entry : m.entrySet()) {
+ copyRC.setAttribute(entry.getKey(), (String) entry.getValue());
+ }
+ copyRC.addText(getWrapper().getText().toString());
+
+ for (Enumeration<RuntimeConfigurable> e = getWrapper().getChildren(); e.hasMoreElements();) {
+ RuntimeConfigurable r = e.nextElement();
+ UnknownElement ueChild = (UnknownElement) r.getProxy();
+ UnknownElement copyChild = ueChild.copy(newProject);
+ copyRC.addChild(copyChild.getWrapper());
+ ret.addChild(copyChild);
+ }
+ return ret;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/UnsupportedAttributeException.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/UnsupportedAttributeException.java
new file mode 100644
index 00000000..1fd9ce51
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/UnsupportedAttributeException.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant;
+
+/**
+ * Used to report attempts to set an unsupported attribute
+ *
+ * @since Ant 1.6.3
+ */
+public class UnsupportedAttributeException extends BuildException {
+ private static final long serialVersionUID = 1L;
+
+ private final String attribute;
+
+ /**
+ * Constructs an unsupported attribute exception.
+ * @param msg The string containing the message.
+ * @param attribute The unsupported attribute.
+ */
+ public UnsupportedAttributeException(String msg, String attribute) {
+ super(msg);
+ this.attribute = attribute;
+ }
+
+ /**
+ * Get the attribute that is wrong.
+ *
+ * @return the attribute name.
+ */
+ public String getAttribute() {
+ return attribute;
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/UnsupportedElementException.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/UnsupportedElementException.java
new file mode 100644
index 00000000..2a38120c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/UnsupportedElementException.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant;
+
+/**
+ * Used to report attempts to set an unsupported element
+ * When the attempt to set the element is made,
+ * the code does not not know the name of the task/type
+ * based on a mapping from the classname to the task/type.
+ * However one class may be used by a lot of task/types.
+ * This exception may be caught by code that does know
+ * the task/type and it will reset the message to the
+ * correct message.
+ * This will be done once (in the case of a recursive
+ * call to handlechildren).
+ *
+ * @since Ant 1.6.3
+ */
+public class UnsupportedElementException extends BuildException {
+ private static final long serialVersionUID = 1L;
+
+ private final String element;
+
+ /**
+ * Constructs an unsupported element exception.
+ * @param msg The string containing the message.
+ * @param element The name of the incorrect element.
+ */
+ public UnsupportedElementException(String msg, String element) {
+ super(msg);
+ this.element = element;
+ }
+
+ /**
+ * Get the element that is wrong.
+ *
+ * @return the element name.
+ */
+ public String getElement() {
+ return element;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/XmlLogger.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/XmlLogger.java
new file mode 100644
index 00000000..a67a260e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/XmlLogger.java
@@ -0,0 +1,474 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.PrintStream;
+import java.io.Writer;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Stack;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import org.apache.tools.ant.util.DOMElementWriter;
+import org.apache.tools.ant.util.FileUtils;
+import org.apache.tools.ant.util.StringUtils;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.Text;
+
+/**
+ * Generates a file in the current directory with
+ * an XML description of what happened during a build.
+ * The default filename is "log.xml", but this can be overridden
+ * with the property <code>XmlLogger.file</code>.
+ *
+ * This implementation assumes in its sanity checking that only one
+ * thread runs a particular target/task at a time. This is enforced
+ * by the way that parallel builds and antcalls are done - and
+ * indeed all but the simplest of tasks could run into problems
+ * if executed in parallel.
+ *
+ * @see Project#addBuildListener(BuildListener)
+ */
+public class XmlLogger implements BuildLogger {
+
+ private int msgOutputLevel = Project.MSG_DEBUG;
+ private PrintStream outStream;
+
+ /** DocumentBuilder to use when creating the document to start with. */
+ private static DocumentBuilder builder = getDocumentBuilder();
+
+ /**
+ * Returns a default DocumentBuilder instance or throws an
+ * ExceptionInInitializerError if it can't be created.
+ *
+ * @return a default DocumentBuilder instance.
+ */
+ private static DocumentBuilder getDocumentBuilder() {
+ try {
+ return DocumentBuilderFactory.newInstance().newDocumentBuilder();
+ } catch (Exception exc) {
+ throw new ExceptionInInitializerError(exc);
+ }
+ }
+
+ /** XML element name for a build. */
+ private static final String BUILD_TAG = "build";
+
+ /** XML element name for a target. */
+ private static final String TARGET_TAG = "target";
+
+ /** XML element name for a task. */
+ private static final String TASK_TAG = "task";
+
+ /** XML element name for a message. */
+ private static final String MESSAGE_TAG = "message";
+
+ /** XML attribute name for a name. */
+ private static final String NAME_ATTR = "name";
+
+ /** XML attribute name for a time. */
+ private static final String TIME_ATTR = "time";
+
+ /** XML attribute name for a message priority. */
+ private static final String PRIORITY_ATTR = "priority";
+
+ /** XML attribute name for a file location. */
+ private static final String LOCATION_ATTR = "location";
+
+ /** XML attribute name for an error description. */
+ private static final String ERROR_ATTR = "error";
+
+ /** XML element name for a stack trace. */
+ private static final String STACKTRACE_TAG = "stacktrace";
+
+ /** The complete log document for this build. */
+ private Document doc = builder.newDocument();
+
+ /** Mapping for when tasks started (Task to TimedElement). */
+ private Hashtable<Task, TimedElement> tasks = new Hashtable<Task, TimedElement>();
+
+ /** Mapping for when targets started (Target to TimedElement). */
+ private Hashtable<Target, TimedElement> targets = new Hashtable<Target, XmlLogger.TimedElement>();
+
+ /**
+ * Mapping of threads to stacks of elements
+ * (Thread to Stack of TimedElement).
+ */
+ private Hashtable<Thread, Stack<TimedElement>> threadStacks = new Hashtable<Thread, Stack<TimedElement>>();
+
+ /**
+ * When the build started.
+ */
+ private TimedElement buildElement = null;
+
+ /** Utility class representing the time an element started. */
+ private static class TimedElement {
+ /**
+ * Start time in milliseconds
+ * (as returned by <code>System.currentTimeMillis()</code>).
+ */
+ private long startTime;
+ /** Element created at the start time. */
+ private Element element;
+ public String toString() {
+ return element.getTagName() + ":" + element.getAttribute("name");
+ }
+ }
+
+ /**
+ * Constructs a new BuildListener that logs build events to an XML file.
+ */
+ public XmlLogger() {
+ }
+
+ /**
+ * Fired when the build starts, this builds the top-level element for the
+ * document and remembers the time of the start of the build.
+ *
+ * @param event Ignored.
+ */
+ public void buildStarted(BuildEvent event) {
+ buildElement = new TimedElement();
+ buildElement.startTime = System.currentTimeMillis();
+ buildElement.element = doc.createElement(BUILD_TAG);
+ }
+
+ /**
+ * Fired when the build finishes, this adds the time taken and any
+ * error stacktrace to the build element and writes the document to disk.
+ *
+ * @param event An event with any relevant extra information.
+ * Will not be <code>null</code>.
+ */
+ public void buildFinished(BuildEvent event) {
+ long totalTime = System.currentTimeMillis() - buildElement.startTime;
+ buildElement.element.setAttribute(TIME_ATTR, DefaultLogger.formatTime(totalTime));
+
+ if (event.getException() != null) {
+ buildElement.element.setAttribute(ERROR_ATTR, event.getException().toString());
+ // print the stacktrace in the build file it is always useful...
+ // better have too much info than not enough.
+ Throwable t = event.getException();
+ Text errText = doc.createCDATASection(StringUtils.getStackTrace(t));
+ Element stacktrace = doc.createElement(STACKTRACE_TAG);
+ stacktrace.appendChild(errText);
+ synchronizedAppend(buildElement.element, stacktrace);
+ }
+ String outFilename = getProperty(event, "XmlLogger.file", "log.xml");
+ String xslUri = getProperty(event, "ant.XmlLogger.stylesheet.uri", "log.xsl");
+ Writer out = null;
+ try {
+ // specify output in UTF8 otherwise accented characters will blow
+ // up everything
+ OutputStream stream = outStream;
+ if (stream == null) {
+ stream = new FileOutputStream(outFilename);
+ }
+ out = new OutputStreamWriter(stream, "UTF8");
+ out.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
+ if (xslUri.length() > 0) {
+ out.write("<?xml-stylesheet type=\"text/xsl\" href=\"" + xslUri + "\"?>\n\n");
+ }
+ new DOMElementWriter().write(buildElement.element, out, 0, "\t");
+ out.flush();
+ } catch (IOException exc) {
+ throw new BuildException("Unable to write log file", exc);
+ } finally {
+ FileUtils.close(out);
+ }
+ buildElement = null;
+ }
+
+ private String getProperty(BuildEvent event, String propertyName, String defaultValue) {
+ String rv = defaultValue;
+ if (event != null && event.getProject() != null && event.getProject().getProperty(propertyName) != null) {
+ rv = event.getProject().getProperty(propertyName);
+ }
+ return rv;
+ }
+
+ /**
+ * Returns the stack of timed elements for the current thread.
+ * @return the stack of timed elements for the current thread
+ */
+ private Stack<TimedElement> getStack() {
+ Stack<TimedElement> threadStack = threadStacks.get(Thread.currentThread());
+ if (threadStack == null) {
+ threadStack = new Stack<TimedElement>();
+ threadStacks.put(Thread.currentThread(), threadStack);
+ }
+ /* For debugging purposes uncomment:
+ org.w3c.dom.Comment s = doc.createComment("stack=" + threadStack);
+ buildElement.element.appendChild(s);
+ */
+ return threadStack;
+ }
+
+ /**
+ * Fired when a target starts building, this pushes a timed element
+ * for the target onto the stack of elements for the current thread,
+ * remembering the current time and the name of the target.
+ *
+ * @param event An event with any relevant extra information.
+ * Will not be <code>null</code>.
+ */
+ public void targetStarted(BuildEvent event) {
+ Target target = event.getTarget();
+ TimedElement targetElement = new TimedElement();
+ targetElement.startTime = System.currentTimeMillis();
+ targetElement.element = doc.createElement(TARGET_TAG);
+ targetElement.element.setAttribute(NAME_ATTR, target.getName());
+ targets.put(target, targetElement);
+ getStack().push(targetElement);
+ }
+
+ /**
+ * Fired when a target finishes building, this adds the time taken
+ * and any error stacktrace to the appropriate target element in the log.
+ *
+ * @param event An event with any relevant extra information.
+ * Will not be <code>null</code>.
+ */
+ public void targetFinished(BuildEvent event) {
+ Target target = event.getTarget();
+ TimedElement targetElement = targets.get(target);
+ if (targetElement != null) {
+ long totalTime = System.currentTimeMillis() - targetElement.startTime;
+ targetElement.element.setAttribute(TIME_ATTR, DefaultLogger.formatTime(totalTime));
+
+ TimedElement parentElement = null;
+ Stack<TimedElement> threadStack = getStack();
+ if (!threadStack.empty()) {
+ TimedElement poppedStack = threadStack.pop();
+ if (poppedStack != targetElement) {
+ throw new RuntimeException("Mismatch - popped element = " + poppedStack
+ + " finished target element = " + targetElement);
+ }
+ if (!threadStack.empty()) {
+ parentElement = threadStack.peek();
+ }
+ }
+ if (parentElement == null) {
+ synchronizedAppend(buildElement.element, targetElement.element);
+ } else {
+ synchronizedAppend(parentElement.element,
+ targetElement.element);
+ }
+ }
+ targets.remove(target);
+ }
+
+ /**
+ * Fired when a task starts building, this pushes a timed element
+ * for the task onto the stack of elements for the current thread,
+ * remembering the current time and the name of the task.
+ *
+ * @param event An event with any relevant extra information.
+ * Will not be <code>null</code>.
+ */
+ public void taskStarted(BuildEvent event) {
+ TimedElement taskElement = new TimedElement();
+ taskElement.startTime = System.currentTimeMillis();
+ taskElement.element = doc.createElement(TASK_TAG);
+
+ Task task = event.getTask();
+ String name = event.getTask().getTaskName();
+ if (name == null) {
+ name = "";
+ }
+ taskElement.element.setAttribute(NAME_ATTR, name);
+ taskElement.element.setAttribute(LOCATION_ATTR, event.getTask().getLocation().toString());
+ tasks.put(task, taskElement);
+ getStack().push(taskElement);
+ }
+
+ /**
+ * Fired when a task finishes building, this adds the time taken
+ * and any error stacktrace to the appropriate task element in the log.
+ *
+ * @param event An event with any relevant extra information.
+ * Will not be <code>null</code>.
+ */
+ public void taskFinished(BuildEvent event) {
+ Task task = event.getTask();
+ TimedElement taskElement = tasks.get(task);
+ if (taskElement == null) {
+ throw new RuntimeException("Unknown task " + task + " not in " + tasks);
+ }
+ long totalTime = System.currentTimeMillis() - taskElement.startTime;
+ taskElement.element.setAttribute(TIME_ATTR, DefaultLogger.formatTime(totalTime));
+ Target target = task.getOwningTarget();
+ TimedElement targetElement = null;
+ if (target != null) {
+ targetElement = targets.get(target);
+ }
+ if (targetElement == null) {
+ synchronizedAppend(buildElement.element, taskElement.element);
+ } else {
+ synchronizedAppend(targetElement.element, taskElement.element);
+ }
+ Stack<TimedElement> threadStack = getStack();
+ if (!threadStack.empty()) {
+ TimedElement poppedStack = threadStack.pop();
+ if (poppedStack != taskElement) {
+ throw new RuntimeException("Mismatch - popped element = " + poppedStack
+ + " finished task element = " + taskElement);
+ }
+ }
+ tasks.remove(task);
+ }
+
+ /**
+ * Get the TimedElement associated with a task.
+ *
+ * Where the task is not found directly, search for unknown elements which
+ * may be hiding the real task
+ */
+ private TimedElement getTaskElement(Task task) {
+ TimedElement element = tasks.get(task);
+ if (element != null) {
+ return element;
+ }
+ for (Enumeration<Task> e = tasks.keys(); e.hasMoreElements();) {
+ Task key = e.nextElement();
+ if (key instanceof UnknownElement) {
+ if (((UnknownElement) key).getTask() == task) {
+ return tasks.get(key);
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Fired when a message is logged, this adds a message element to the
+ * most appropriate parent element (task, target or build) and records
+ * the priority and text of the message.
+ *
+ * @param event An event with any relevant extra information.
+ * Will not be <code>null</code>.
+ */
+ public void messageLogged(BuildEvent event) {
+ int priority = event.getPriority();
+ if (priority > msgOutputLevel) {
+ return;
+ }
+ Element messageElement = doc.createElement(MESSAGE_TAG);
+
+ String name = "debug";
+ switch (priority) {
+ case Project.MSG_ERR:
+ name = "error";
+ break;
+ case Project.MSG_WARN:
+ name = "warn";
+ break;
+ case Project.MSG_INFO:
+ name = "info";
+ break;
+ default:
+ name = "debug";
+ break;
+ }
+ messageElement.setAttribute(PRIORITY_ATTR, name);
+
+ Throwable ex = event.getException();
+ if (Project.MSG_DEBUG <= msgOutputLevel && ex != null) {
+ Text errText = doc.createCDATASection(StringUtils.getStackTrace(ex));
+ Element stacktrace = doc.createElement(STACKTRACE_TAG);
+ stacktrace.appendChild(errText);
+ synchronizedAppend(buildElement.element, stacktrace);
+ }
+ Text messageText = doc.createCDATASection(event.getMessage());
+ messageElement.appendChild(messageText);
+
+ TimedElement parentElement = null;
+
+ Task task = event.getTask();
+
+ Target target = event.getTarget();
+ if (task != null) {
+ parentElement = getTaskElement(task);
+ }
+ if (parentElement == null && target != null) {
+ parentElement = targets.get(target);
+ }
+ if (parentElement != null) {
+ synchronizedAppend(parentElement.element, messageElement);
+ } else {
+ synchronizedAppend(buildElement.element, messageElement);
+ }
+ }
+
+ // -------------------------------------------------- BuildLogger interface
+
+ /**
+ * Set the logging level when using this as a Logger
+ *
+ * @param level the logging level -
+ * see {@link org.apache.tools.ant.Project#MSG_ERR Project}
+ * class for level definitions
+ */
+ public void setMessageOutputLevel(int level) {
+ msgOutputLevel = level;
+ }
+
+ /**
+ * Set the output stream to which logging output is sent when operating
+ * as a logger.
+ *
+ * @param output the output PrintStream.
+ */
+ public void setOutputPrintStream(PrintStream output) {
+ this.outStream = new PrintStream(output, true);
+ }
+
+ /**
+ * Ignore emacs mode, as it has no meaning in XML format
+ *
+ * @param emacsMode true if logger should produce emacs compatible
+ * output
+ */
+ public void setEmacsMode(boolean emacsMode) {
+ }
+
+ /**
+ * Ignore error print stream. All output will be written to
+ * either the XML log file or the PrintStream provided to
+ * setOutputPrintStream
+ *
+ * @param err the stream we are going to ignore.
+ */
+ public void setErrorPrintStream(PrintStream err) {
+ }
+
+ private void synchronizedAppend(Node parent, Node child) {
+ synchronized(parent) {
+ parent.appendChild(child);
+ }
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/antlib.xml b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/antlib.xml
new file mode 100644
index 00000000..b11bac52
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/antlib.xml
@@ -0,0 +1,144 @@
+<?xml version="1.0"?>
+ <!--
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+-->
+<antlib>
+ <!--
+ This is the ant lib definition for ant.
+ Currently it only contains componentdefinitions (restricted
+ types that are not allowed at the top level)
+ - conditions, selectors and comparators
+ (those that are not top-level types (taskdefs or typedefs).
+ defined in defaults.properties of taskdefs and types
+ packages).
+
+ This is currently experimental and it is most
+ likely that these definitions will be placed
+ in a Java Ant definition class.
+ -->
+ <!-- conditions -->
+ <componentdef name="and" onerror="ignore"
+ classname="org.apache.tools.ant.taskdefs.condition.And"/>
+ <componentdef name="contains" onerror="ignore"
+ classname="org.apache.tools.ant.taskdefs.condition.Contains"/>
+ <componentdef name="equals" onerror="ignore"
+ classname="org.apache.tools.ant.taskdefs.condition.Equals"/>
+ <componentdef name="filesmatch" onerror="ignore"
+ classname="org.apache.tools.ant.taskdefs.condition.FilesMatch"/>
+ <componentdef name="hasfreespace" onerror="ignore"
+ classname="org.apache.tools.ant.taskdefs.condition.HasFreeSpace"/>
+ <componentdef name="hasmethod" onerror="ignore"
+ classname="org.apache.tools.ant.taskdefs.condition.HasMethod"/>
+ <componentdef name="http" onerror="ignore"
+ classname="org.apache.tools.ant.taskdefs.condition.Http"/>
+ <componentdef name="isfailure" onerror="ignore"
+ classname="org.apache.tools.ant.taskdefs.condition.IsFailure"/>
+ <componentdef name="isfalse" onerror="ignore"
+ classname="org.apache.tools.ant.taskdefs.condition.IsFalse"/>
+ <componentdef name="islastmodified" onerror="ignore"
+ classname="org.apache.tools.ant.taskdefs.condition.IsLastModified"/>
+ <componentdef name="isreachable" onerror="ignore"
+ classname="org.apache.tools.ant.taskdefs.condition.IsReachable"/>
+ <componentdef name="isreference" onerror="ignore"
+ classname="org.apache.tools.ant.taskdefs.condition.IsReference"/>
+ <componentdef name="isset" onerror="ignore"
+ classname="org.apache.tools.ant.taskdefs.condition.IsSet"/>
+ <componentdef name="issigned" onerror="ignore"
+ classname="org.apache.tools.ant.taskdefs.condition.IsSigned"/>
+ <componentdef name="istrue" onerror="ignore"
+ classname="org.apache.tools.ant.taskdefs.condition.IsTrue"/>
+ <componentdef name="matches" onerror="ignore"
+ classname="org.apache.tools.ant.taskdefs.condition.Matches"/>
+ <componentdef name="not" onerror="ignore"
+ classname="org.apache.tools.ant.types.resources.selectors.Not"/>
+ <componentdef name="or" onerror="ignore"
+ classname="org.apache.tools.ant.taskdefs.condition.Or"/>
+ <componentdef name="os" onerror="ignore"
+ classname="org.apache.tools.ant.taskdefs.condition.Os"/>
+ <componentdef name="parsersupports" onerror="ignore"
+ classname="org.apache.tools.ant.taskdefs.condition.ParserSupports"/>
+ <componentdef name="resourcecontains" onerror="ignore"
+ classname="org.apache.tools.ant.taskdefs.condition.ResourceContains"/>
+ <componentdef name="resourceexists" onerror="ignore"
+ classname="org.apache.tools.ant.taskdefs.condition.ResourceExists"/>
+ <componentdef name="resourcesmatch" onerror="ignore"
+ classname="org.apache.tools.ant.taskdefs.condition.ResourcesMatch"/>
+ <componentdef name="socket" onerror="ignore"
+ classname="org.apache.tools.ant.taskdefs.condition.Socket"/>
+ <componentdef name="typefound" onerror="ignore"
+ classname="org.apache.tools.ant.taskdefs.condition.TypeFound"/>
+ <componentdef name="xor" onerror="ignore"
+ classname="org.apache.tools.ant.taskdefs.condition.Xor"/>
+
+ <!-- selectors -->
+ <componentdef name="and" onerror="ignore"
+ classname="org.apache.tools.ant.types.resources.selectors.And" />
+ <componentdef name="compare" onerror="ignore"
+ classname="org.apache.tools.ant.types.resources.selectors.Compare" />
+ <componentdef name="contains" onerror="ignore"
+ classname="org.apache.tools.ant.types.selectors.ContainsSelector" />
+ <componentdef name="containsregexp" onerror="ignore"
+ classname="org.apache.tools.ant.types.selectors.ContainsRegexpSelector" />
+ <componentdef name="date" onerror="ignore"
+ classname="org.apache.tools.ant.types.resources.selectors.Date" />
+ <componentdef name="exists" onerror="ignore"
+ classname="org.apache.tools.ant.types.resources.selectors.Exists" />
+ <componentdef name="instanceof" onerror="ignore"
+ classname="org.apache.tools.ant.types.resources.selectors.InstanceOf" />
+ <componentdef name="majority" onerror="ignore"
+ classname="org.apache.tools.ant.types.resources.selectors.Majority" />
+ <componentdef name="modified" onerror="ignore"
+ classname="org.apache.tools.ant.types.selectors.modifiedselector.ModifiedSelector" />
+ <componentdef name="name" onerror="ignore"
+ classname="org.apache.tools.ant.types.resources.selectors.Name" />
+ <componentdef name="none" onerror="ignore"
+ classname="org.apache.tools.ant.types.resources.selectors.None" />
+ <componentdef name="not" onerror="ignore"
+ classname="org.apache.tools.ant.types.resources.selectors.Not" />
+ <componentdef name="or" onerror="ignore"
+ classname="org.apache.tools.ant.types.resources.selectors.Or" />
+ <componentdef name="size" onerror="ignore"
+ classname="org.apache.tools.ant.types.resources.selectors.Size" />
+ <componentdef name="type" onerror="ignore"
+ classname="org.apache.tools.ant.types.resources.selectors.Type" />
+
+
+ <!-- comparators -->
+ <componentdef name="name" onerror="ignore"
+ classname="org.apache.tools.ant.types.resources.comparators.Name" />
+ <componentdef name="size" onerror="ignore"
+ classname="org.apache.tools.ant.types.resources.comparators.Size" />
+ <componentdef name="date" onerror="ignore"
+ classname="org.apache.tools.ant.types.resources.comparators.Date" />
+ <componentdef name="exists" onerror="ignore"
+ classname="org.apache.tools.ant.types.resources.comparators.Exists" />
+ <componentdef name="type" onerror="ignore"
+ classname="org.apache.tools.ant.types.resources.comparators.Type" />
+ <componentdef name="content" onerror="ignore"
+ classname="org.apache.tools.ant.types.resources.comparators.Content" />
+ <componentdef name="reverse" onerror="ignore"
+ classname="org.apache.tools.ant.types.resources.comparators.Reverse" />
+
+ <!-- filters -->
+ <componentdef name="sortfilter" onerror="ignore"
+ classname="org.apache.tools.ant.filters.SortFilter"/>
+ <componentdef name="uniqfilter" onerror="ignore"
+ classname="org.apache.tools.ant.filters.UniqFilter"/>
+</antlib>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/attribute/AttributeNamespace.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/attribute/AttributeNamespace.java
new file mode 100644
index 00000000..fba4c992
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/attribute/AttributeNamespace.java
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.attribute;
+
+/**
+ * This class is used to indicate that the XML namespace (URI)
+ * can be used to look for namespace attributes.
+ * @see org.apache.tools.ant.taskdefs.AttributeNamespaceDef
+ * @since Ant 1.9.1
+ */
+public final class AttributeNamespace {
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/attribute/BaseIfAttribute.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/attribute/BaseIfAttribute.java
new file mode 100644
index 00000000..c2ec08ab
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/attribute/BaseIfAttribute.java
@@ -0,0 +1,86 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.attribute;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.apache.tools.ant.ProjectComponent;
+import org.apache.tools.ant.RuntimeConfigurable;
+import org.apache.tools.ant.UnknownElement;
+
+
+/**
+ * An abstract class for if/unless attributes.
+ * This contains a boolean flag to specify whether this is an
+ * if or unless attribute.
+ * @since Ant 1.9.1
+ */
+public abstract class BaseIfAttribute
+ extends ProjectComponent implements EnableAttribute {
+ private boolean positive = true;
+ /**
+ * Set the positive flag.
+ * @param positive the value to use.
+ */
+ protected void setPositive(boolean positive) {
+ this.positive = positive;
+ }
+
+ /**
+ * Get the positive flag.
+ * @return the flag.
+ */
+ protected boolean isPositive() {
+ return positive;
+ }
+
+ /**
+ * convert the result.
+ * @param val the result to convert
+ * @return val if positive or !val if not.
+ */
+ protected boolean convertResult(boolean val) {
+ return positive ? val : !val;
+ }
+
+ /**
+ * Get all the attributes in the ant-attribute:param
+ * namespace and place them in a map.
+ * @param el the element this attribute is in.
+ * @return a map of attributes.
+ */
+ protected Map getParams(UnknownElement el) {
+ Map ret = new HashMap();
+ RuntimeConfigurable rc = el.getWrapper();
+ Map attributes = rc.getAttributeMap(); // This does a copy!
+ for (Iterator i = attributes.entrySet().iterator(); i.hasNext();) {
+ Map.Entry entry = (Map.Entry) i.next();
+ String key = (String) entry.getKey();
+ String value = (String) entry.getValue();
+ if (key.startsWith("ant-attribute:param")) {
+ int pos = key.lastIndexOf(':');
+ ret.put(key.substring(pos + 1),
+ el.getProject().replaceProperties(value));
+ }
+ }
+ return ret;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/attribute/EnableAttribute.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/attribute/EnableAttribute.java
new file mode 100644
index 00000000..06c1186f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/attribute/EnableAttribute.java
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.attribute;
+
+import org.apache.tools.ant.UnknownElement;
+
+/**
+ * This interface is used by Ant attributes.
+ * @since Ant 1.9.1
+ */
+public interface EnableAttribute {
+ /**
+ * is enabled.
+ * @param el the unknown element this attribute is in.
+ * @param value the value of the attribute.
+ * @return true if the attribute enables the element, false otherwise.
+ */
+ boolean isEnabled(UnknownElement el, String value);
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/attribute/IfBlankAttribute.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/attribute/IfBlankAttribute.java
new file mode 100644
index 00000000..384476c8
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/attribute/IfBlankAttribute.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.attribute;
+
+import org.apache.tools.ant.UnknownElement;
+
+/**
+ * Check if an attribute is blank or not.
+ * @since Ant 1.9.1
+ */
+public class IfBlankAttribute extends BaseIfAttribute {
+ /** The unless version */
+ public static class Unless extends IfBlankAttribute {
+ { setPositive(false); }
+ }
+ /**
+ * check if the attribute value is blank or not
+ * {@inheritDoc}
+ */
+ public boolean isEnabled(UnknownElement el, String value) {
+ return convertResult((value == null || "".equals(value)));
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/attribute/IfSetAttribute.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/attribute/IfSetAttribute.java
new file mode 100644
index 00000000..d4531c59
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/attribute/IfSetAttribute.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.attribute;
+
+import org.apache.tools.ant.UnknownElement;
+
+/**
+ * Check if an attribute value as a property is set or not
+ * @since Ant 1.9.1
+ */
+public class IfSetAttribute extends BaseIfAttribute {
+ /** The unless version */
+ public static class Unless extends IfSetAttribute {
+ { setPositive(false); }
+ }
+ /**
+ * check if the attribute value is blank or not
+ * {@inheritDoc}
+ */
+ public boolean isEnabled(UnknownElement el, String value) {
+ return convertResult(getProject().getProperty(value) != null);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/attribute/IfTrueAttribute.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/attribute/IfTrueAttribute.java
new file mode 100644
index 00000000..5c10ea2f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/attribute/IfTrueAttribute.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.attribute;
+
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.UnknownElement;
+
+/**
+ * Check if an attribute value is true or not.
+ * @since Ant 1.9.1
+ */
+public class IfTrueAttribute extends BaseIfAttribute {
+ /** The unless version */
+ public static class Unless extends IfTrueAttribute {
+ { setPositive(false); }
+ }
+
+ /**
+ * check if the attribute value is true or not
+ * {@inheritDoc}
+ */
+ public boolean isEnabled(UnknownElement el, String value) {
+ return convertResult(Project.toBoolean(value));
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/defaultManifest.mf b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/defaultManifest.mf
new file mode 100644
index 00000000..fd30a23a
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/defaultManifest.mf
@@ -0,0 +1,4 @@
+Manifest-Version: 1.0
+Ant-Version: Apache Ant ${project.version}
+
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/dispatch/DispatchTask.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/dispatch/DispatchTask.java
new file mode 100644
index 00000000..a848ed13
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/dispatch/DispatchTask.java
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.dispatch;
+
+import org.apache.tools.ant.Task;
+
+/**
+ * Tasks extending this class may contain multiple actions.
+ * The method that is invoked for execution depends upon the
+ * value of the action attribute of the task.
+ * <br>
+ * Example:<br>
+ * &lt;mytask action=&quot;list&quot;/&gt; will invoke the method
+ * with the signature public void list() in mytask's class.
+ * If the action attribute is not defined in the task or is empty,
+ * the execute() method will be called.
+ */
+public abstract class DispatchTask extends Task implements Dispatchable {
+ private String action;
+
+ /**
+ * Get the action parameter name.
+ * @return the <code>String</code> "action" by default (can be overridden).
+ */
+ public String getActionParameterName() {
+ return "action";
+ }
+
+ /**
+ * Set the action.
+ * @param action the method name.
+ */
+ public void setAction(String action) {
+ this.action = action;
+ }
+
+ /**
+ * Get the action.
+ * @return the action.
+ */
+ public String getAction() {
+ return action;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/dispatch/DispatchUtils.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/dispatch/DispatchUtils.java
new file mode 100644
index 00000000..1a7c1f98
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/dispatch/DispatchUtils.java
@@ -0,0 +1,124 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.dispatch;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.UnknownElement;
+
+/**
+ * Determines and Executes the action method for the task.
+ */
+// CheckStyle:HideUtilityClassConstructorCheck OFF - (bc)
+public class DispatchUtils {
+ /**
+ * Determines and Executes the action method for the task.
+ * @param task the task to execute.
+ * @throws BuildException on error.
+ */
+ public static final void execute(Object task) throws BuildException {
+ String methodName = "execute";
+ Dispatchable dispatchable = null;
+ try {
+ if (task instanceof Dispatchable) {
+ dispatchable = (Dispatchable) task;
+ } else if (task instanceof UnknownElement) {
+ UnknownElement ue = (UnknownElement) task;
+ Object realThing = ue.getRealThing();
+ if (realThing != null
+ && realThing instanceof Dispatchable
+ && realThing instanceof Task) {
+ dispatchable = (Dispatchable) realThing;
+ }
+ }
+ if (dispatchable != null) {
+ String mName = null;
+ try {
+ final String name = dispatchable.getActionParameterName();
+ if (name != null && name.trim().length() > 0) {
+ mName = "get" + name.trim().substring(0, 1).toUpperCase();
+ if (name.length() > 1) {
+ mName += name.substring(1);
+ }
+ final Class<? extends Dispatchable> c = dispatchable.getClass();
+ final Method actionM = c.getMethod(mName, new Class[0]);
+ if (actionM != null) {
+ final Object o = actionM.invoke(dispatchable, (Object[]) null);
+ if (o != null) {
+ final String s = o.toString();
+ if (s != null && s.trim().length() > 0) {
+ methodName = s.trim();
+ Method executeM = null;
+ executeM = dispatchable.getClass().getMethod(
+ methodName, new Class[0]);
+ if (executeM == null) {
+ throw new BuildException(
+ "No public " + methodName + "() in "
+ + dispatchable.getClass());
+ }
+ executeM.invoke(dispatchable, (Object[]) null);
+ if (task instanceof UnknownElement) {
+ ((UnknownElement) task).setRealThing(null);
+ }
+ } else {
+ throw new BuildException(
+ "Dispatchable Task attribute '" + name.trim()
+ + "' not set or value is empty.");
+ }
+ } else {
+ throw new BuildException(
+ "Dispatchable Task attribute '" + name.trim()
+ + "' not set or value is empty.");
+ }
+ }
+ } else {
+ throw new BuildException(
+ "Action Parameter Name must not be empty for Dispatchable Task.");
+ }
+ } catch (NoSuchMethodException nsme) {
+ throw new BuildException("No public " + mName + "() in " + task.getClass());
+ }
+ } else {
+ Method executeM = null;
+ executeM = task.getClass().getMethod(methodName, new Class[0]);
+ if (executeM == null) {
+ throw new BuildException("No public " + methodName + "() in "
+ + task.getClass());
+ }
+ executeM.invoke(task, (Object[]) null);
+ if (task instanceof UnknownElement) {
+ ((UnknownElement) task).setRealThing(null);
+ }
+ }
+ } catch (InvocationTargetException ie) {
+ Throwable t = ie.getTargetException();
+ if (t instanceof BuildException) {
+ throw ((BuildException) t);
+ } else {
+ throw new BuildException(t);
+ }
+ } catch (NoSuchMethodException e) {
+ throw new BuildException(e);
+ } catch (IllegalAccessException e) {
+ throw new BuildException(e);
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/dispatch/Dispatchable.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/dispatch/Dispatchable.java
new file mode 100644
index 00000000..41684f48
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/dispatch/Dispatchable.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.dispatch;
+
+/**
+ * Classes implementing this interface specify the
+ * name of the parameter that contains the name
+ * of the task's method to execute.
+ */
+public interface Dispatchable {
+ /**
+ * Get the name of the parameter.
+ * @return the name of the parameter that contains the name of the method.
+ */
+ String getActionParameterName();
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/BaseFilterReader.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/BaseFilterReader.java
new file mode 100644
index 00000000..3b3b0270
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/BaseFilterReader.java
@@ -0,0 +1,199 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.filters;
+
+import java.io.FilterReader;
+import java.io.IOException;
+import java.io.Reader;
+import java.io.StringReader;
+
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.util.FileUtils;
+
+/**
+ * Base class for core filter readers.
+ *
+ */
+public abstract class BaseFilterReader extends FilterReader {
+ /** Buffer size used when reading */
+ private static final int BUFFER_SIZE = 8192;
+
+ /** Have the parameters passed been interpreted? */
+ private boolean initialized = false;
+
+ /** The Ant project this filter is part of. */
+ private Project project = null;
+
+ /**
+ * Constructor used by Ant's introspection mechanism.
+ * The original filter reader is only used for chaining
+ * purposes, never for filtering purposes (and indeed
+ * it would be useless for filtering purposes, as it has
+ * no real data to filter). ChainedReaderHelper uses
+ * this placeholder instance to create a chain of real filters.
+ */
+ public BaseFilterReader() {
+ super(new StringReader(""));
+ FileUtils.close(this);
+ }
+
+ /**
+ * Creates a new filtered reader.
+ *
+ * @param in A Reader object providing the underlying stream.
+ * Must not be <code>null</code>.
+ *
+ */
+ public BaseFilterReader(final Reader in) {
+ super(in);
+ }
+
+ /**
+ * Reads characters into a portion of an array. This method will block
+ * until some input is available, an I/O error occurs, or the end of the
+ * stream is reached.
+ *
+ * @param cbuf Destination buffer to write characters to.
+ * Must not be <code>null</code>.
+ * @param off Offset at which to start storing characters.
+ * @param len Maximum number of characters to read.
+ *
+ * @return the number of characters read, or -1 if the end of the
+ * stream has been reached
+ *
+ * @exception IOException If an I/O error occurs
+ */
+ public final int read(final char[] cbuf, final int off,
+ final int len) throws IOException {
+ for (int i = 0; i < len; i++) {
+ final int ch = read();
+ if (ch == -1) {
+ if (i == 0) {
+ return -1;
+ } else {
+ return i;
+ }
+ }
+ cbuf[off + i] = (char) ch;
+ }
+ return len;
+ }
+
+ /**
+ * Skips characters. This method will block until some characters are
+ * available, an I/O error occurs, or the end of the stream is reached.
+ *
+ * @param n The number of characters to skip
+ *
+ * @return the number of characters actually skipped
+ *
+ * @exception IllegalArgumentException If <code>n</code> is negative.
+ * @exception IOException If an I/O error occurs
+ */
+ public final long skip(final long n)
+ throws IOException, IllegalArgumentException {
+ if (n < 0L) {
+ throw new IllegalArgumentException("skip value is negative");
+ }
+
+ for (long i = 0; i < n; i++) {
+ if (read() == -1) {
+ return i;
+ }
+ }
+ return n;
+ }
+
+ /**
+ * Sets the initialized status.
+ *
+ * @param initialized Whether or not the filter is initialized.
+ */
+ protected final void setInitialized(final boolean initialized) {
+ this.initialized = initialized;
+ }
+
+ /**
+ * Returns the initialized status.
+ *
+ * @return whether or not the filter is initialized
+ */
+ protected final boolean getInitialized() {
+ return initialized;
+ }
+
+ /**
+ * Sets the project to work with.
+ *
+ * @param project The project this filter is part of.
+ * Should not be <code>null</code>.
+ */
+ public final void setProject(final Project project) {
+ this.project = project;
+ }
+
+ /**
+ * Returns the project this filter is part of.
+ *
+ * @return the project this filter is part of
+ */
+ protected final Project getProject() {
+ return project;
+ }
+
+ /**
+ * Reads a line of text ending with '\n' (or until the end of the stream).
+ * The returned String retains the '\n'.
+ *
+ * @return the line read, or <code>null</code> if the end of the stream
+ * has already been reached
+ *
+ * @exception IOException if the underlying reader throws one during
+ * reading
+ */
+ protected final String readLine() throws IOException {
+ int ch = in.read();
+
+ if (ch == -1) {
+ return null;
+ }
+
+ StringBuffer line = new StringBuffer();
+
+ while (ch != -1) {
+ line.append ((char) ch);
+ if (ch == '\n') {
+ break;
+ }
+ ch = in.read();
+ }
+ return line.toString();
+ }
+
+ /**
+ * Reads to the end of the stream, returning the contents as a String.
+ *
+ * @return the remaining contents of the reader, as a String
+ *
+ * @exception IOException if the underlying reader throws one during
+ * reading
+ */
+ protected final String readFully() throws IOException {
+ return FileUtils.readFully(in, BUFFER_SIZE);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/BaseParamFilterReader.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/BaseParamFilterReader.java
new file mode 100644
index 00000000..54bc9ff9
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/BaseParamFilterReader.java
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.filters;
+
+import java.io.Reader;
+
+import org.apache.tools.ant.types.Parameter;
+import org.apache.tools.ant.types.Parameterizable;
+
+/**
+ * Parameterized base class for core filter readers.
+ *
+ */
+public abstract class BaseParamFilterReader
+ extends BaseFilterReader
+ implements Parameterizable {
+ /** The passed in parameter array. */
+ private Parameter[] parameters;
+
+ /**
+ * Constructor for "dummy" instances.
+ *
+ * @see BaseFilterReader#BaseFilterReader()
+ */
+ public BaseParamFilterReader() {
+ super();
+ }
+
+ /**
+ * Creates a new filtered reader.
+ *
+ * @param in A Reader object providing the underlying stream.
+ * Must not be <code>null</code>.
+ */
+ public BaseParamFilterReader(final Reader in) {
+ super(in);
+ }
+
+ /**
+ * Sets the parameters used by this filter, and sets
+ * the filter to an uninitialized status.
+ *
+ * @param parameters The parameters to be used by this filter.
+ * Should not be <code>null</code>.
+ */
+ public final void setParameters(final Parameter[] parameters) {
+ this.parameters = parameters;
+ setInitialized(false);
+ }
+
+ /**
+ * Returns the parameters to be used by this filter.
+ *
+ * @return the parameters to be used by this filter
+ */
+ protected final Parameter[] getParameters() {
+ return parameters;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/ChainableReader.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/ChainableReader.java
new file mode 100644
index 00000000..67060393
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/ChainableReader.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.filters;
+
+import java.io.Reader;
+
+/**
+ * Interface indicating that a reader may be chained to another one.
+ *
+ */
+public interface ChainableReader {
+ /**
+ * Returns a reader with the same configuration as this one,
+ * but filtering input from the specified reader.
+ *
+ * @param rdr the reader which the returned reader should be filtering
+ *
+ * @return a reader with the same configuration as this one, but
+ * filtering input from the specified reader
+ */
+ Reader chain(Reader rdr);
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/ClassConstants.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/ClassConstants.java
new file mode 100644
index 00000000..35443012
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/ClassConstants.java
@@ -0,0 +1,165 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.filters;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.util.ResourceUtils;
+
+/**
+ * Assembles the constants declared in a Java class in
+ * <code>key1=value1(line separator)key2=value2</code>
+ * format.
+ *<p>
+ * Notes:
+ * <ol>
+ * <li>This filter uses the BCEL external toolkit.
+ * <li>This assembles only those constants that are not created
+ * using the syntax <code>new whatever()</code>
+ * <li>This assembles constants declared using the basic datatypes
+ * and String only.</li>
+ * <li>The access modifiers of the declared constants do not matter.</li>
+ *</ol>
+ * Example:<br>
+ * <pre>&lt;classconstants/&gt;</pre>
+ * Or:
+ * <pre>&lt;filterreader
+ * classname=&quot;org.apache.tools.ant.filters.ClassConstants&quot;/&gt;</pre>
+ */
+public final class ClassConstants
+ extends BaseFilterReader
+ implements ChainableReader {
+ /** Data that must be read from, if not null. */
+ private String queuedData = null;
+
+ /** Helper Class to be invoked via reflection. */
+ private static final String JAVA_CLASS_HELPER =
+ "org.apache.tools.ant.filters.util.JavaClassHelper";
+
+ /**
+ * Constructor for "dummy" instances.
+ *
+ * @see BaseFilterReader#BaseFilterReader()
+ */
+ public ClassConstants() {
+ super();
+ }
+
+ /**
+ * Creates a new filtered reader. The contents of the passed-in reader
+ * are expected to be the name of the class from which to produce a
+ * list of constants.
+ *
+ * @param in A Reader object providing the underlying stream.
+ * Must not be <code>null</code>.
+ */
+ public ClassConstants(final Reader in) {
+ super(in);
+ }
+
+ /**
+ * Reads and assembles the constants declared in a class file.
+ *
+ * @return the next character in the list of constants, or -1
+ * if the end of the resulting stream has been reached
+ *
+ * @exception IOException if the underlying stream throws an IOException
+ * during reading, or if the constants for the specified class cannot
+ * be read (for example due to the class not being found).
+ */
+ public int read() throws IOException {
+
+ int ch = -1;
+
+ if (queuedData != null && queuedData.length() == 0) {
+ queuedData = null;
+ }
+
+ if (queuedData != null) {
+ ch = queuedData.charAt(0);
+ queuedData = queuedData.substring(1);
+ if (queuedData.length() == 0) {
+ queuedData = null;
+ }
+ } else {
+ final String clazz = readFully();
+ if (clazz == null || clazz.length() == 0) {
+ ch = -1;
+ } else {
+ final byte[] bytes = clazz.getBytes(ResourceUtils.ISO_8859_1);
+ try {
+ final Class<?> javaClassHelper =
+ Class.forName(JAVA_CLASS_HELPER);
+ if (javaClassHelper != null) {
+ final Class<?>[] params = {
+ byte[].class
+ };
+ final Method getConstants =
+ javaClassHelper.getMethod("getConstants", params);
+ final Object[] args = {
+ bytes
+ };
+ // getConstants is a static method, no need to
+ // pass in the object
+ final StringBuffer sb = (StringBuffer)
+ getConstants.invoke(null, args);
+ if (sb.length() > 0) {
+ queuedData = sb.toString();
+ return read();
+ }
+ }
+ } catch (NoClassDefFoundError ex) {
+ throw ex;
+ } catch (RuntimeException ex) {
+ throw ex;
+ } catch (InvocationTargetException ex) {
+ Throwable t = ex.getTargetException();
+ if (t instanceof NoClassDefFoundError) {
+ throw (NoClassDefFoundError) t;
+ }
+ if (t instanceof RuntimeException) {
+ throw (RuntimeException) t;
+ }
+ throw new BuildException(t);
+ } catch (Exception ex) {
+ throw new BuildException(ex);
+ }
+ }
+ }
+ return ch;
+ }
+
+ /**
+ * Creates a new ClassConstants using the passed in
+ * Reader for instantiation.
+ *
+ * @param rdr A Reader object providing the underlying stream.
+ * Must not be <code>null</code>.
+ *
+ * @return a new filter based on this configuration, but filtering
+ * the specified reader
+ */
+ public Reader chain(final Reader rdr) {
+ ClassConstants newFilter = new ClassConstants(rdr);
+ return newFilter;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/ConcatFilter.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/ConcatFilter.java
new file mode 100644
index 00000000..0ac6024b
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/ConcatFilter.java
@@ -0,0 +1,218 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.filters;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.Reader;
+
+import org.apache.tools.ant.types.Parameter;
+
+/**
+ * Concats a file before and/or after the file.
+ *
+ * <p>Example:</p><pre>
+ * &lt;copy todir="build"&gt;
+ * &lt;fileset dir="src" includes="*.java"/&gt;
+ * &lt;filterchain&gt;
+ * &lt;concatfilter prepend="apache-license-java.txt"/&gt;
+ * &lt;/filterchain&gt;
+ * &lt;/copy&gt;
+ * </pre>
+ *
+ * <p>Copies all java sources from <i>src</i> to <i>build</i> and adds the
+ * content of <i>apache-license-java.txt</i> add the beginning of each
+ * file.</p>
+ *
+ * @since 1.6
+ * @version 2003-09-23
+ */
+public final class ConcatFilter extends BaseParamFilterReader
+ implements ChainableReader {
+
+ /** File to add before the content. */
+ private File prepend;
+
+ /** File to add after the content. */
+ private File append;
+
+ /** Reader for prepend-file. */
+ private Reader prependReader = null;
+
+ /** Reader for append-file. */
+ private Reader appendReader = null;
+
+ /**
+ * Constructor for "dummy" instances.
+ *
+ * @see BaseFilterReader#BaseFilterReader()
+ */
+ public ConcatFilter() {
+ super();
+ }
+
+ /**
+ * Creates a new filtered reader.
+ *
+ * @param in A Reader object providing the underlying stream.
+ * Must not be <code>null</code>.
+ */
+ public ConcatFilter(final Reader in) {
+ super(in);
+ }
+
+ /**
+ * Returns the next character in the filtered stream. If the desired
+ * number of lines have already been read, the resulting stream is
+ * effectively at an end. Otherwise, the next character from the
+ * underlying stream is read and returned.
+ *
+ * @return the next character in the resulting stream, or -1
+ * if the end of the resulting stream has been reached
+ *
+ * @exception IOException if the underlying stream throws an IOException
+ * during reading
+ */
+ @Override
+ public int read() throws IOException {
+ // do the "singleton" initialization
+ if (!getInitialized()) {
+ initialize();
+ setInitialized(true);
+ }
+
+ int ch = -1;
+
+ // The readers return -1 if they end. So simply read the "prepend"
+ // after that the "content" and at the end the "append" file.
+ if (prependReader != null) {
+ ch = prependReader.read();
+ if (ch == -1) {
+ // I am the only one so I have to close the reader
+ prependReader.close();
+ prependReader = null;
+ }
+ }
+ if (ch == -1) {
+ ch = super.read();
+ }
+ if (ch == -1) {
+ // don't call super.close() because that reader is used
+ // on other places ...
+ if (appendReader != null) {
+ ch = appendReader.read();
+ if (ch == -1) {
+ // I am the only one so I have to close the reader
+ appendReader.close();
+ appendReader = null;
+ }
+ }
+ }
+
+ return ch;
+ }
+
+ /**
+ * Sets <i>prepend</i> attribute.
+ * @param prepend new value
+ */
+ public void setPrepend(final File prepend) {
+ this.prepend = prepend;
+ }
+
+ /**
+ * Returns <i>prepend</i> attribute.
+ * @return prepend attribute
+ */
+ public File getPrepend() {
+ return prepend;
+ }
+
+ /**
+ * Sets <i>append</i> attribute.
+ * @param append new value
+ */
+ public void setAppend(final File append) {
+ this.append = append;
+ }
+
+ /**
+ * Returns <i>append</i> attribute.
+ * @return append attribute
+ */
+ public File getAppend() {
+ return append;
+ }
+
+ /**
+ * Creates a new ConcatReader using the passed in
+ * Reader for instantiation.
+ *
+ * @param rdr A Reader object providing the underlying stream.
+ * Must not be <code>null</code>.
+ *
+ * @return a new filter based on this configuration, but filtering
+ * the specified reader
+ */
+ public Reader chain(final Reader rdr) {
+ final ConcatFilter newFilter = new ConcatFilter(rdr);
+ newFilter.setPrepend(getPrepend());
+ newFilter.setAppend(getAppend());
+ // Usually the initialized is set to true. But here it must not.
+ // Because the prepend and append readers have to be instantiated
+ // on runtime
+ //newFilter.setInitialized(true);
+ return newFilter;
+ }
+
+ /**
+ * Scans the parameters list for the "lines" parameter and uses
+ * it to set the number of lines to be returned in the filtered stream.
+ * also scan for skip parameter.
+ */
+ private void initialize() throws IOException {
+ // get parameters
+ final Parameter[] params = getParameters();
+ if (params != null) {
+ for (int i = 0; i < params.length; i++) {
+ if ("prepend".equals(params[i].getName())) {
+ setPrepend(new File(params[i].getValue()));
+ continue;
+ }
+ if ("append".equals(params[i].getName())) {
+ setAppend(new File(params[i].getValue()));
+ continue;
+ }
+ }
+ }
+ if (prepend != null) {
+ if (!prepend.isAbsolute()) {
+ prepend = new File(getProject().getBaseDir(), prepend.getPath());
+ }
+ prependReader = new BufferedReader(new FileReader(prepend));
+ }
+ if (append != null) {
+ if (!append.isAbsolute()) {
+ append = new File(getProject().getBaseDir(), append.getPath());
+ }
+ appendReader = new BufferedReader(new FileReader(append));
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/EscapeUnicode.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/EscapeUnicode.java
new file mode 100644
index 00000000..dd454395
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/EscapeUnicode.java
@@ -0,0 +1,123 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.filters;
+
+import java.io.IOException;
+import java.io.Reader;
+
+import org.apache.tools.ant.util.UnicodeUtil;
+
+/**
+ * This method converts non-latin characters to unicode escapes.
+ * Useful to load properties containing non latin
+ * Example:
+ *
+ * <pre>&lt;escapeunicode&gt;</pre>
+ *
+ * Or:
+ *
+ * <pre>&lt;filterreader
+ classname=&quot;org.apache.tools.ant.filters.EscapeUnicode&quot;/&gt;
+ * </pre>
+ *
+ * @since Ant 1.6
+ */
+public class EscapeUnicode
+ extends BaseParamFilterReader
+ implements ChainableReader {
+ //this field will hold unnnn right after reading a non latin character
+ //afterwards it will be truncated of one char every call to read
+ private StringBuffer unicodeBuf;
+
+ /**
+ * Constructor for "dummy" instances.
+ *
+ * @see BaseFilterReader#BaseFilterReader()
+ */
+ public EscapeUnicode() {
+ super();
+ unicodeBuf = new StringBuffer();
+ }
+
+ /**
+ * Creates a new filtered reader.
+ *
+ * @param in A Reader object providing the underlying stream.
+ * Must not be <code>null</code>.
+ */
+ public EscapeUnicode(final Reader in) {
+ super(in);
+ unicodeBuf = new StringBuffer();
+ }
+
+ /**
+ * Returns the next character in the filtered stream, converting non latin
+ * characters to unicode escapes.
+ *
+ * @return the next character in the resulting stream, or -1
+ * if the end of the resulting stream has been reached
+ *
+ * @exception IOException if the underlying stream throws
+ * an IOException during reading
+ */
+ public final int read() throws IOException {
+ if (!getInitialized()) {
+ initialize();
+ setInitialized(true);
+ }
+
+ int ch = -1;
+ if (unicodeBuf.length() == 0) {
+ ch = in.read();
+ if (ch != -1) {
+ char achar = (char) ch;
+ if (achar >= '\u0080') {
+ unicodeBuf = UnicodeUtil.EscapeUnicode(achar);
+ ch = '\\';
+ }
+ }
+ } else {
+ ch = (int) unicodeBuf.charAt(0);
+ unicodeBuf.deleteCharAt(0);
+ }
+ return ch;
+ }
+
+ /**
+ * Creates a new EscapeUnicode using the passed in
+ * Reader for instantiation.
+ *
+ * @param rdr A Reader object providing the underlying stream.
+ * Must not be <code>null</code>.
+ *
+ * @return a new filter based on this configuration, but filtering
+ * the specified reader
+ */
+ public final Reader chain(final Reader rdr) {
+ EscapeUnicode newFilter = new EscapeUnicode(rdr);
+ newFilter.setInitialized(true);
+ return newFilter;
+ }
+
+ /**
+ * Parses the parameters (currently unused)
+ */
+ private void initialize() {
+ }
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/ExpandProperties.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/ExpandProperties.java
new file mode 100644
index 00000000..524a799b
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/ExpandProperties.java
@@ -0,0 +1,142 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.filters;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.util.Properties;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.PropertyHelper;
+import org.apache.tools.ant.property.GetProperty;
+import org.apache.tools.ant.property.ParseProperties;
+import org.apache.tools.ant.types.PropertySet;
+
+/**
+ * Expands Ant properties, if any, in the data.
+ * <p>
+ * Example:<br>
+ * <pre>&lt;expandproperties/&gt;</pre>
+ * Or:
+ * <pre>&lt;filterreader
+ * classname=&quot;org.apache.tools.ant.filters.ExpandProperties&quot;/&gt;</pre>
+ *
+ */
+public final class ExpandProperties
+ extends BaseFilterReader
+ implements ChainableReader {
+
+ private static final int EOF = -1;
+
+ private char[] buffer;
+ private int index;
+ private PropertySet propertySet;
+
+ /**
+ * Constructor for "dummy" instances.
+ *
+ * @see BaseFilterReader#BaseFilterReader()
+ */
+ public ExpandProperties() {
+ super();
+ }
+
+ /**
+ * Creates a new filtered reader.
+ *
+ * @param in A Reader object providing the underlying stream.
+ * Must not be <code>null</code>.
+ */
+ public ExpandProperties(final Reader in) {
+ super(in);
+ }
+
+ /**
+ * Restrict the expanded properties using a PropertySet.
+ * @param propertySet replacement lookup
+ */
+ public void add(PropertySet propertySet) {
+ if (this.propertySet != null) {
+ throw new BuildException("expandproperties filter accepts only one propertyset");
+ }
+ this.propertySet = propertySet;
+ }
+
+ /**
+ * Returns the next character in the filtered stream. The original
+ * stream is first read in fully, and the Ant properties are expanded.
+ * The results of this expansion are then queued so they can be read
+ * character-by-character.
+ *
+ * @return the next character in the resulting stream, or -1
+ * if the end of the resulting stream has been reached
+ *
+ * @exception IOException if the underlying stream throws an IOException
+ * during reading
+ */
+ public int read() throws IOException {
+ if (index > EOF) {
+ if (buffer == null) {
+ String data = readFully();
+ Project project = getProject();
+ GetProperty getProperty;
+ if (propertySet == null) {
+ getProperty = PropertyHelper.getPropertyHelper(project);
+ } else {
+ final Properties props = propertySet.getProperties();
+ getProperty = new GetProperty() {
+
+ public Object getProperty(String name) {
+ return props.getProperty(name);
+ }
+ };
+ }
+ Object expanded = new ParseProperties(project, PropertyHelper
+ .getPropertyHelper(project)
+ .getExpanders(),
+ getProperty)
+ .parseProperties(data);
+ buffer = expanded == null ? new char[0]
+ : expanded.toString().toCharArray();
+ }
+ if (index < buffer.length) {
+ return buffer[index++];
+ }
+ index = EOF;
+ }
+ return EOF;
+ }
+
+ /**
+ * Creates a new ExpandProperties filter using the passed in
+ * Reader for instantiation.
+ *
+ * @param rdr A Reader object providing the underlying stream.
+ * Must not be <code>null</code>.
+ *
+ * @return a new filter based on this configuration, but filtering
+ * the specified reader
+ */
+ public Reader chain(final Reader rdr) {
+ ExpandProperties newFilter = new ExpandProperties(rdr);
+ newFilter.setProject(getProject());
+ newFilter.add(propertySet);
+ return newFilter;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/FixCrLfFilter.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/FixCrLfFilter.java
new file mode 100644
index 00000000..8a37924c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/FixCrLfFilter.java
@@ -0,0 +1,1004 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.filters;
+
+import java.io.IOException;
+import java.io.Reader;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.taskdefs.condition.Os;
+import org.apache.tools.ant.types.EnumeratedAttribute;
+
+/**
+ * Converts text to local OS formatting conventions, as well as repair text
+ * damaged by misconfigured or misguided editors or file transfer programs.
+ * <p>
+ * This filter can take the following arguments:
+ * <ul>
+ * <li>eof
+ * <li>eol
+ * <li>fixlast
+ * <li>javafiles
+ * <li>tab
+ * <li>tablength
+ * </ul>
+ * None of which are required.
+ * <p>
+ * This version generalises the handling of EOL characters, and allows for
+ * CR-only line endings (the standard on Mac systems prior to OS X). Tab
+ * handling has also been generalised to accommodate any tabwidth from 2 to 80,
+ * inclusive. Importantly, it can leave untouched any literal TAB characters
+ * embedded within Java string or character constants.
+ * <p>
+ * <em>Caution:</em> run with care on carefully formatted files. This may
+ * sound obvious, but if you don't specify asis, presume that your files are
+ * going to be modified. If "tabs" is "add" or "remove", whitespace characters
+ * may be added or removed as necessary. Similarly, for EOLs, eol="asis"
+ * actually means convert to your native O/S EOL convention while eol="crlf" or
+ * cr="add" can result in CR characters being removed in one special case
+ * accommodated, i.e., CRCRLF is regarded as a single EOL to handle cases where
+ * other programs have converted CRLF into CRCRLF.
+ *
+ * <P>
+ * Example:
+ *
+ * <pre>
+ * &lt;&lt;fixcrlf tab=&quot;add&quot; eol=&quot;crlf&quot; eof=&quot;asis&quot;/&gt;
+ * </pre>
+ *
+ * Or:
+ *
+ * <pre>
+ * &lt;filterreader classname=&quot;org.apache.tools.ant.filters.FixCrLfFilter&quot;&gt;
+ * &lt;param eol=&quot;crlf&quot; tab=&quot;asis&quot;/&gt;
+ * &lt;/filterreader&gt;
+ * </pre>
+ *
+ */
+public final class FixCrLfFilter extends BaseParamFilterReader implements ChainableReader {
+ private static final int DEFAULT_TAB_LENGTH = 8;
+ private static final int MIN_TAB_LENGTH = 2;
+ private static final int MAX_TAB_LENGTH = 80;
+ private static final char CTRLZ = '\u001A';
+
+ private int tabLength = DEFAULT_TAB_LENGTH;
+
+ private CrLf eol;
+
+ private AddAsisRemove ctrlz;
+
+ private AddAsisRemove tabs;
+
+ private boolean javafiles = false;
+
+ private boolean fixlast = true;
+
+ private boolean initialized = false;
+
+ /**
+ * Constructor for "dummy" instances.
+ *
+ * @see BaseFilterReader#BaseFilterReader()
+ */
+ public FixCrLfFilter() {
+ super();
+ }
+
+ /**
+ * Create a new filtered reader.
+ *
+ * @param in
+ * A Reader object providing the underlying stream. Must not be
+ * <code>null</code>.
+ * @throws IOException on error.
+ */
+ public FixCrLfFilter(final Reader in) throws IOException {
+ super(in);
+ }
+
+ // Instance initializer: Executes just after the super() call in this
+ // class's constructor.
+ {
+ tabs = AddAsisRemove.ASIS;
+ if (Os.isFamily("mac") && !Os.isFamily("unix")) {
+ ctrlz = AddAsisRemove.REMOVE;
+ setEol(CrLf.MAC);
+ } else if (Os.isFamily("dos")) {
+ ctrlz = AddAsisRemove.ASIS;
+ setEol(CrLf.DOS);
+ } else {
+ ctrlz = AddAsisRemove.REMOVE;
+ setEol(CrLf.UNIX);
+ }
+ }
+
+ /**
+ * Create a new FixCrLfFilter using the passed in Reader for instantiation.
+ *
+ * @param rdr
+ * A Reader object providing the underlying stream. Must not be
+ * <code>null</code>.
+ *
+ * @return a new filter based on this configuration, but filtering the
+ * specified reader.
+ */
+ public Reader chain(final Reader rdr) {
+ try {
+ FixCrLfFilter newFilter = new FixCrLfFilter(rdr);
+
+ newFilter.setJavafiles(getJavafiles());
+ newFilter.setEol(getEol());
+ newFilter.setTab(getTab());
+ newFilter.setTablength(getTablength());
+ newFilter.setEof(getEof());
+ newFilter.setFixlast(getFixlast());
+ newFilter.initInternalFilters();
+
+ return newFilter;
+ } catch (IOException e) {
+ throw new BuildException(e);
+ }
+ }
+
+ /**
+ * Get how DOS EOF (control-z) characters are being handled.
+ *
+ * @return values:
+ * <ul>
+ * <li>add: ensure that there is an eof at the end of the file
+ * <li>asis: leave eof characters alone
+ * <li>remove: remove any eof character found at the end
+ * </ul>
+ */
+ public AddAsisRemove getEof() {
+ // Return copy so that the call must call setEof() to change the state
+ // of fixCRLF
+ return ctrlz.newInstance();
+ }
+
+ /**
+ * Get how EndOfLine characters are being handled.
+ *
+ * @return values:
+ * <ul>
+ * <li>asis: convert line endings to your O/S convention
+ * <li>cr: convert line endings to CR
+ * <li>lf: convert line endings to LF
+ * <li>crlf: convert line endings to CRLF
+ * </ul>
+ */
+ public CrLf getEol() {
+ // Return copy so that the call must call setEol() to change the state
+ // of fixCRLF
+ return eol.newInstance();
+ }
+
+ /**
+ * Get whether a missing EOL be added to the final line of the stream.
+ *
+ * @return true if a filtered file will always end with an EOL
+ */
+ public boolean getFixlast() {
+ return fixlast;
+ }
+
+ /**
+ * Get whether the stream is to be treated as though it contains Java
+ * source.
+ * <P>
+ * This attribute is only used in association with the &quot;<i><b>tab</b></i>&quot;
+ * attribute. Tabs found in Java literals are protected from changes by this
+ * filter.
+ *
+ * @return true if whitespace in Java character and string literals is
+ * ignored.
+ */
+ public boolean getJavafiles() {
+ return javafiles;
+ }
+
+ /**
+ * Return how tab characters are being handled.
+ *
+ * @return values:
+ * <ul>
+ * <li>add: convert sequences of spaces which span a tab stop to
+ * tabs
+ * <li>asis: leave tab and space characters alone
+ * <li>remove: convert tabs to spaces
+ * </ul>
+ */
+ public AddAsisRemove getTab() {
+ // Return copy so that the caller must call setTab() to change the state
+ // of fixCRLF.
+ return tabs.newInstance();
+ }
+
+ /**
+ * Get the tab length to use.
+ *
+ * @return the length of tab in spaces
+ */
+ public int getTablength() {
+ return tabLength;
+ }
+
+ private static String calculateEolString(CrLf eol) {
+ // Calculate the EOL string per the current config
+ if (eol == CrLf.CR || eol == CrLf.MAC) {
+ return "\r";
+ }
+ if (eol == CrLf.CRLF || eol == CrLf.DOS) {
+ return "\r\n";
+ }
+ // assume (eol == CrLf.LF || eol == CrLf.UNIX)
+ return "\n";
+ }
+
+ /**
+ * Wrap the input stream with the internal filters necessary to perform the
+ * configuration settings.
+ */
+ private void initInternalFilters() {
+
+ // If I'm removing an EOF character, do so first so that the other
+ // filters don't see that character.
+ in = (ctrlz == AddAsisRemove.REMOVE) ? new RemoveEofFilter(in) : in;
+
+ // Change all EOL characters to match the calculated EOL string. If
+ // configured to do so, append a trailing EOL so that the file ends on
+ // a EOL.
+ if (eol != CrLf.ASIS) {
+ in = new NormalizeEolFilter(in, calculateEolString(eol), getFixlast());
+ }
+
+ if (tabs != AddAsisRemove.ASIS) {
+ // If filtering Java source, prevent changes to whitespace in
+ // character and string literals.
+ if (getJavafiles()) {
+ in = new MaskJavaTabLiteralsFilter(in);
+ }
+ // Add/Remove tabs
+ in = (tabs == AddAsisRemove.ADD) ? (Reader) new AddTabFilter(in, getTablength())
+ : (Reader) new RemoveTabFilter(in, getTablength());
+ }
+ // Add missing EOF character
+ in = (ctrlz == AddAsisRemove.ADD) ? new AddEofFilter(in) : in;
+ initialized = true;
+ }
+
+ /**
+ * Return the next character in the filtered stream.
+ *
+ * @return the next character in the resulting stream, or -1 if the end of
+ * the resulting stream has been reached.
+ *
+ * @exception IOException
+ * if the underlying stream throws an IOException during
+ * reading.
+ */
+ public synchronized int read() throws IOException {
+ if (!initialized) {
+ initInternalFilters();
+ }
+ return in.read();
+ }
+
+ /**
+ * Specify how DOS EOF (control-z) characters are to be handled.
+ *
+ * @param attr
+ * valid values:
+ * <ul>
+ * <li>add: ensure that there is an eof at the end of the file
+ * <li>asis: leave eof characters alone
+ * <li>remove: remove any eof character found at the end
+ * </ul>
+ */
+ public void setEof(AddAsisRemove attr) {
+ ctrlz = attr.resolve();
+ }
+
+ /**
+ * Specify how end of line (EOL) characters are to be handled.
+ *
+ * @param attr
+ * valid values:
+ * <ul>
+ * <li>asis: convert line endings to your O/S convention
+ * <li>cr: convert line endings to CR
+ * <li>lf: convert line endings to LF
+ * <li>crlf: convert line endings to CRLF
+ * </ul>
+ */
+ public void setEol(CrLf attr) {
+ eol = attr.resolve();
+ }
+
+ /**
+ * Specify whether a missing EOL will be added to the final line of input.
+ *
+ * @param fixlast
+ * if true a missing EOL will be appended.
+ */
+ public void setFixlast(boolean fixlast) {
+ this.fixlast = fixlast;
+ }
+
+ /**
+ * Indicate whether this stream contains Java source.
+ *
+ * This attribute is only used in association with the &quot;<i><b>tab</b></i>&quot;
+ * attribute.
+ *
+ * @param javafiles
+ * set to true to prevent this filter from changing tabs found in
+ * Java literals.
+ */
+ public void setJavafiles(boolean javafiles) {
+ this.javafiles = javafiles;
+ }
+
+ /**
+ * Specify how tab characters are to be handled.
+ *
+ * @param attr
+ * valid values:
+ * <ul>
+ * <li>add: convert sequences of spaces which span a tab stop to
+ * tabs
+ * <li>asis: leave tab and space characters alone
+ * <li>remove: convert tabs to spaces
+ * </ul>
+ */
+ public void setTab(AddAsisRemove attr) {
+ tabs = attr.resolve();
+ }
+
+ /**
+ * Specify tab length in characters.
+ *
+ * @param tabLength
+ * specify the length of tab in spaces. Valid values are between
+ * 2 and 80 inclusive. The default for this parameter is 8.
+ * @throws IOException on error.
+ */
+ public void setTablength(int tabLength) throws IOException {
+ if (tabLength < MIN_TAB_LENGTH
+ || tabLength > MAX_TAB_LENGTH) {
+ throw new IOException(
+ "tablength must be between " + MIN_TAB_LENGTH
+ + " and " + MAX_TAB_LENGTH);
+ }
+ this.tabLength = tabLength;
+ }
+
+ /**
+ * This filter reader redirects all read I/O methods through its own read()
+ * method.
+ *
+ * <P>
+ * The input stream is already buffered by the copy task so this doesn't
+ * significantly impact performance while it makes writing the individual
+ * fix filters much easier.
+ * </P>
+ */
+ private static class SimpleFilterReader extends Reader {
+ private static final int PREEMPT_BUFFER_LENGTH = 16;
+ private Reader in;
+
+ private int[] preempt = new int[PREEMPT_BUFFER_LENGTH];
+
+ private int preemptIndex = 0;
+
+ public SimpleFilterReader(Reader in) {
+ this.in = in;
+ }
+
+ public void push(char c) {
+ push((int) c);
+ }
+
+ public void push(int c) {
+ try {
+ preempt[preemptIndex++] = c;
+ } catch (ArrayIndexOutOfBoundsException e) {
+ int[] p2 = new int[preempt.length * 2];
+ System.arraycopy(preempt, 0, p2, 0, preempt.length);
+ preempt = p2;
+ push(c);
+ }
+ }
+
+ public void push(char[] cs, int start, int length) {
+ for (int i = start + length - 1; i >= start;) {
+ push(cs[i--]);
+ }
+ }
+
+ public void push(char[] cs) {
+ push(cs, 0, cs.length);
+ }
+
+ /**
+ * Does this filter want to block edits on the last character returned
+ * by read()?
+ */
+ public boolean editsBlocked() {
+ return in instanceof SimpleFilterReader && ((SimpleFilterReader) in).editsBlocked();
+ }
+
+ public int read() throws java.io.IOException {
+ return preemptIndex > 0 ? preempt[--preemptIndex] : in.read();
+ }
+
+ public void close() throws java.io.IOException {
+ in.close();
+ }
+
+ public void reset() throws IOException {
+ in.reset();
+ }
+
+ public boolean markSupported() {
+ return in.markSupported();
+ }
+
+ public boolean ready() throws java.io.IOException {
+ return in.ready();
+ }
+
+ public void mark(int i) throws java.io.IOException {
+ in.mark(i);
+ }
+
+ public long skip(long i) throws java.io.IOException {
+ return in.skip(i);
+ }
+
+ public int read(char[] buf) throws java.io.IOException {
+ return read(buf, 0, buf.length);
+ }
+
+ public int read(char[] buf, int start, int length) throws java.io.IOException {
+ int count = 0;
+ int c = 0;
+
+ // CheckStyle:InnerAssignment OFF - leave alone
+ while (length-- > 0 && (c = this.read()) != -1) {
+ buf[start++] = (char) c;
+ count++;
+ }
+ // if at EOF with no characters in the buffer, return EOF
+ return (count == 0 && c == -1) ? -1 : count;
+ }
+ }
+
+ private static class MaskJavaTabLiteralsFilter extends SimpleFilterReader {
+ private boolean editsBlocked = false;
+
+ private static final int JAVA = 1;
+
+ private static final int IN_CHAR_CONST = 2;
+
+ private static final int IN_STR_CONST = 3;
+
+ private static final int IN_SINGLE_COMMENT = 4;
+
+ private static final int IN_MULTI_COMMENT = 5;
+
+ private static final int TRANS_TO_COMMENT = 6;
+
+ private static final int TRANS_FROM_MULTI = 8;
+
+ private int state;
+
+ public MaskJavaTabLiteralsFilter(Reader in) {
+ super(in);
+ state = JAVA;
+ }
+
+ public boolean editsBlocked() {
+ return editsBlocked || super.editsBlocked();
+ }
+
+ public int read() throws IOException {
+ int thisChar = super.read();
+ // Mask, block from being edited, all characters in constants.
+ editsBlocked = (state == IN_CHAR_CONST || state == IN_STR_CONST);
+
+ switch (state) {
+ case JAVA:
+ // The current character is always emitted.
+ switch (thisChar) {
+ case '\'':
+ state = IN_CHAR_CONST;
+ break;
+ case '"':
+ state = IN_STR_CONST;
+ break;
+ case '/':
+ state = TRANS_TO_COMMENT;
+ break;
+ default:
+ // Fall tru
+ }
+ break;
+ case IN_CHAR_CONST:
+ switch (thisChar) {
+ case '\'':
+ state = JAVA;
+ break;
+ default:
+ // Fall tru
+ }
+ break;
+ case IN_STR_CONST:
+ switch (thisChar) {
+ case '"':
+ state = JAVA;
+ break;
+ default:
+ // Fall tru
+ }
+ break;
+ case IN_SINGLE_COMMENT:
+ // The current character is always emitted.
+ switch (thisChar) {
+ case '\n':
+ case '\r': // EOL
+ state = JAVA;
+ break;
+ default:
+ // Fall tru
+ }
+ break;
+ case IN_MULTI_COMMENT:
+ // The current character is always emitted.
+ switch (thisChar) {
+ case '*':
+ state = TRANS_FROM_MULTI;
+ break;
+ default:
+ // Fall tru
+ }
+ break;
+ case TRANS_TO_COMMENT:
+ // The current character is always emitted.
+ switch (thisChar) {
+ case '*':
+ state = IN_MULTI_COMMENT;
+ break;
+ case '/':
+ state = IN_SINGLE_COMMENT;
+ break;
+ case '\'':
+ state = IN_CHAR_CONST;
+ break;
+ case '"':
+ state = IN_STR_CONST;
+ break;
+ default:
+ state = JAVA;
+ }
+ break;
+ case TRANS_FROM_MULTI:
+ // The current character is always emitted.
+ switch (thisChar) {
+ case '/':
+ state = JAVA;
+ break;
+ default:
+ // Fall tru
+ }
+ break;
+ default:
+ // Fall tru
+ }
+ return thisChar;
+ }
+ }
+
+ private static class NormalizeEolFilter extends SimpleFilterReader {
+ private boolean previousWasEOL;
+
+ private boolean fixLast;
+
+ private int normalizedEOL = 0;
+
+ private char[] eol = null;
+
+ public NormalizeEolFilter(Reader in, String eolString, boolean fixLast) {
+ super(in);
+ eol = eolString.toCharArray();
+ this.fixLast = fixLast;
+ }
+
+ public int read() throws IOException {
+ int thisChar = super.read();
+
+ if (normalizedEOL == 0) {
+ int numEOL = 0;
+ boolean atEnd = false;
+ switch (thisChar) {
+ case CTRLZ:
+ int c = super.read();
+ if (c == -1) {
+ atEnd = true;
+ if (fixLast && !previousWasEOL) {
+ numEOL = 1;
+ push(thisChar);
+ }
+ } else {
+ push(c);
+ }
+ break;
+ case -1:
+ atEnd = true;
+ if (fixLast && !previousWasEOL) {
+ numEOL = 1;
+ }
+ break;
+ case '\n':
+ // EOL was "\n"
+ numEOL = 1;
+ break;
+ case '\r':
+ numEOL = 1;
+ int c1 = super.read();
+ int c2 = super.read();
+
+ if (c1 == '\r' && c2 == '\n') {
+ // EOL was "\r\r\n"
+ } else if (c1 == '\r') {
+ // EOL was "\r\r" - handle as two consecutive "\r" and
+ // "\r"
+ numEOL = 2;
+ push(c2);
+ } else if (c1 == '\n') {
+ // EOL was "\r\n"
+ push(c2);
+ } else {
+ // EOL was "\r"
+ push(c2);
+ push(c1);
+ }
+ default:
+ // Fall tru
+ }
+ if (numEOL > 0) {
+ while (numEOL-- > 0) {
+ push(eol);
+ normalizedEOL += eol.length;
+ }
+ previousWasEOL = true;
+ thisChar = read();
+ } else if (!atEnd) {
+ previousWasEOL = false;
+ }
+ } else {
+ normalizedEOL--;
+ }
+ return thisChar;
+ }
+ }
+
+ private static class AddEofFilter extends SimpleFilterReader {
+ private int lastChar = -1;
+
+ public AddEofFilter(Reader in) {
+ super(in);
+ }
+
+ public int read() throws IOException {
+ int thisChar = super.read();
+
+ // if source is EOF but last character was NOT ctrl-z, return ctrl-z
+ if (thisChar == -1) {
+ if (lastChar != CTRLZ) {
+ lastChar = CTRLZ;
+ return lastChar;
+ }
+ } else {
+ lastChar = thisChar;
+ }
+ return thisChar;
+ }
+ }
+
+ private static class RemoveEofFilter extends SimpleFilterReader {
+ private int lookAhead = -1;
+
+ public RemoveEofFilter(Reader in) {
+ super(in);
+
+ try {
+ lookAhead = in.read();
+ } catch (IOException e) {
+ lookAhead = -1;
+ }
+ }
+
+ public int read() throws IOException {
+ int lookAhead2 = super.read();
+
+ // If source at EOF and lookAhead is ctrl-z, return EOF (NOT ctrl-z)
+ if (lookAhead2 == -1 && lookAhead == CTRLZ) {
+ return -1;
+ }
+ // Return current look-ahead
+ int i = lookAhead;
+ lookAhead = lookAhead2;
+ return i;
+ }
+ }
+
+ private static class AddTabFilter extends SimpleFilterReader {
+ private int columnNumber = 0;
+
+ private int tabLength = 0;
+
+ public AddTabFilter(Reader in, int tabLength) {
+ super(in);
+ this.tabLength = tabLength;
+ }
+
+ public int read() throws IOException {
+ int c = super.read();
+
+ switch (c) {
+ case '\r':
+ case '\n':
+ columnNumber = 0;
+ break;
+ case ' ':
+ columnNumber++;
+ if (!editsBlocked()) {
+ int colNextTab = ((columnNumber + tabLength - 1) / tabLength) * tabLength;
+ int countSpaces = 1;
+ int numTabs = 0;
+
+ scanWhitespace: while ((c = super.read()) != -1) {
+ switch (c) {
+ case ' ':
+ if (++columnNumber == colNextTab) {
+ numTabs++;
+ countSpaces = 0;
+ colNextTab += tabLength;
+ } else {
+ countSpaces++;
+ }
+ break;
+ case '\t':
+ columnNumber = colNextTab;
+ numTabs++;
+ countSpaces = 0;
+ colNextTab += tabLength;
+ break;
+ default:
+ push(c);
+ break scanWhitespace;
+ }
+ }
+ while (countSpaces-- > 0) {
+ push(' ');
+ columnNumber--;
+ }
+ while (numTabs-- > 0) {
+ push('\t');
+ columnNumber -= tabLength;
+ }
+ c = super.read();
+ switch (c) {
+ case ' ':
+ columnNumber++;
+ break;
+ case '\t':
+ columnNumber += tabLength;
+ break;
+ default:
+ // Fall tru
+ }
+ }
+ break;
+ case '\t':
+ columnNumber = ((columnNumber + tabLength - 1) / tabLength) * tabLength;
+ break;
+ default:
+ columnNumber++;
+ }
+ return c;
+ }
+ }
+
+ private static class RemoveTabFilter extends SimpleFilterReader {
+ private int columnNumber = 0;
+
+ private int tabLength = 0;
+
+ public RemoveTabFilter(Reader in, int tabLength) {
+ super(in);
+
+ this.tabLength = tabLength;
+ }
+
+ public int read() throws IOException {
+ int c = super.read();
+
+ switch (c) {
+ case '\r':
+ case '\n':
+ columnNumber = 0;
+ break;
+ case '\t':
+ int width = tabLength - columnNumber % tabLength;
+
+ if (!editsBlocked()) {
+ for (; width > 1; width--) {
+ push(' ');
+ }
+ c = ' ';
+ }
+ columnNumber += width;
+ break;
+ default:
+ columnNumber++;
+ }
+ return c;
+ }
+ }
+
+ /**
+ * Enumerated attribute with the values "asis", "add" and "remove".
+ */
+ public static class AddAsisRemove extends EnumeratedAttribute {
+ private static final AddAsisRemove ASIS = newInstance("asis");
+
+ private static final AddAsisRemove ADD = newInstance("add");
+
+ private static final AddAsisRemove REMOVE = newInstance("remove");
+
+ /** {@inheritDoc}. */
+ public String[] getValues() {
+ return new String[] {"add", "asis", "remove"};
+ }
+
+ /**
+ * Equality depending in the index.
+ * @param other the object to test equality against.
+ * @return true if the object has the same index as this.
+ */
+ public boolean equals(Object other) {
+ return other instanceof AddAsisRemove
+ && getIndex() == ((AddAsisRemove) other).getIndex();
+ }
+
+ /**
+ * Hashcode depending on the index.
+ * @return the index as the hashcode.
+ */
+ public int hashCode() {
+ return getIndex();
+ }
+
+ AddAsisRemove resolve() throws IllegalStateException {
+ if (this.equals(ASIS)) {
+ return ASIS;
+ }
+ if (this.equals(ADD)) {
+ return ADD;
+ }
+ if (this.equals(REMOVE)) {
+ return REMOVE;
+ }
+ throw new IllegalStateException("No replacement for " + this);
+ }
+
+ // Works like clone() but doesn't show up in the Javadocs
+ private AddAsisRemove newInstance() {
+ return newInstance(getValue());
+ }
+
+ /**
+ * Create an instance of this enumerated value based on the string value.
+ * @param value the value to use.
+ * @return an enumerated instance.
+ */
+ public static AddAsisRemove newInstance(String value) {
+ AddAsisRemove a = new AddAsisRemove();
+ a.setValue(value);
+ return a;
+ }
+ }
+
+ /**
+ * Enumerated attribute with the values "asis", "cr", "lf" and "crlf".
+ */
+ public static class CrLf extends EnumeratedAttribute {
+ private static final CrLf ASIS = newInstance("asis");
+
+ private static final CrLf CR = newInstance("cr");
+
+ private static final CrLf CRLF = newInstance("crlf");
+
+ private static final CrLf DOS = newInstance("dos");
+
+ private static final CrLf LF = newInstance("lf");
+
+ private static final CrLf MAC = newInstance("mac");
+
+ private static final CrLf UNIX = newInstance("unix");
+
+ /**
+ * @see EnumeratedAttribute#getValues
+ */
+ /** {@inheritDoc}. */
+ public String[] getValues() {
+ return new String[] {"asis", "cr", "lf", "crlf", "mac", "unix", "dos"};
+ }
+
+ /**
+ * Equality depending in the index.
+ * @param other the object to test equality against.
+ * @return true if the object has the same index as this.
+ */
+ public boolean equals(Object other) {
+ return other instanceof CrLf && getIndex() == ((CrLf) other).getIndex();
+ }
+
+ /**
+ * Hashcode depending on the index.
+ * @return the index as the hashcode.
+ */
+ public int hashCode() {
+ return getIndex();
+ }
+
+ CrLf resolve() {
+ if (this.equals(ASIS)) {
+ return ASIS;
+ }
+ if (this.equals(CR) || this.equals(MAC)) {
+ return CR;
+ }
+ if (this.equals(CRLF) || this.equals(DOS)) {
+ return CRLF;
+ }
+ if (this.equals(LF) || this.equals(UNIX)) {
+ return LF;
+ }
+ throw new IllegalStateException("No replacement for " + this);
+ }
+
+ // Works like clone() but doesn't show up in the Javadocs
+ private CrLf newInstance() {
+ return newInstance(getValue());
+ }
+
+ /**
+ * Create an instance of this enumerated value based on the string value.
+ * @param value the value to use.
+ * @return an enumerated instance.
+ */
+ public static CrLf newInstance(String value) {
+ CrLf c = new CrLf();
+ c.setValue(value);
+ return c;
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/HeadFilter.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/HeadFilter.java
new file mode 100644
index 00000000..522fe57b
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/HeadFilter.java
@@ -0,0 +1,222 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.filters;
+
+import java.io.IOException;
+import java.io.Reader;
+
+import org.apache.tools.ant.types.Parameter;
+import org.apache.tools.ant.util.LineTokenizer;
+
+/**
+ * Reads the first <code>n</code> lines of a stream.
+ * (Default is first 10 lines.)
+ * <p>
+ * Example:
+ * <pre>&lt;headfilter lines=&quot;3&quot;/&gt;</pre>
+ * Or:
+ * <pre>&lt;filterreader classname=&quot;org.apache.tools.ant.filters.HeadFilter&quot;&gt;
+ * &lt;param name=&quot;lines&quot; value=&quot;3&quot;/&gt;
+ * &lt;/filterreader&gt;</pre>
+ *
+ */
+public final class HeadFilter extends BaseParamFilterReader
+ implements ChainableReader {
+ /** Parameter name for the number of lines to be returned. */
+ private static final String LINES_KEY = "lines";
+
+ /** Parameter name for the number of lines to be skipped. */
+ private static final String SKIP_KEY = "skip";
+
+ /** Number of lines currently read in. */
+ private long linesRead = 0;
+
+ /** Default number of lines to show */
+ private static final int DEFAULT_NUM_LINES = 10;
+
+ /** Number of lines to be returned in the filtered stream. */
+ private long lines = DEFAULT_NUM_LINES;
+
+ /** Number of lines to be skipped. */
+ private long skip = 0;
+
+ /** A line tokenizer */
+ private LineTokenizer lineTokenizer = null;
+
+ /** the current line from the input stream */
+ private String line = null;
+ /** the position in the current line */
+ private int linePos = 0;
+
+ /** Whether this filter is finished */
+ private boolean eof;
+
+ /**
+ * Constructor for "dummy" instances.
+ *
+ * @see BaseFilterReader#BaseFilterReader()
+ */
+ public HeadFilter() {
+ super();
+ }
+
+ /**
+ * Creates a new filtered reader.
+ *
+ * @param in A Reader object providing the underlying stream.
+ * Must not be <code>null</code>.
+ */
+ public HeadFilter(final Reader in) {
+ super(in);
+ lineTokenizer = new LineTokenizer();
+ lineTokenizer.setIncludeDelims(true);
+ }
+
+ /**
+ * Returns the next character in the filtered stream. If the desired
+ * number of lines have already been read, the resulting stream is
+ * effectively at an end. Otherwise, the next character from the
+ * underlying stream is read and returned.
+ *
+ * @return the next character in the resulting stream, or -1
+ * if the end of the resulting stream has been reached
+ *
+ * @exception IOException if the underlying stream throws an IOException
+ * during reading
+ */
+ public int read() throws IOException {
+ if (!getInitialized()) {
+ initialize();
+ setInitialized(true);
+ }
+
+ while (line == null || line.length() == 0) {
+ line = lineTokenizer.getToken(in);
+ if (line == null) {
+ return -1;
+ }
+ line = headFilter(line);
+ if (eof) {
+ return -1;
+ }
+ linePos = 0;
+ }
+
+ int ch = line.charAt(linePos);
+ linePos++;
+ if (linePos == line.length()) {
+ line = null;
+ }
+ return ch;
+ }
+
+ /**
+ * Sets the number of lines to be returned in the filtered stream.
+ *
+ * @param lines the number of lines to be returned in the filtered stream
+ */
+ public void setLines(final long lines) {
+ this.lines = lines;
+ }
+
+ /**
+ * Returns the number of lines to be returned in the filtered stream.
+ *
+ * @return the number of lines to be returned in the filtered stream
+ */
+ private long getLines() {
+ return lines;
+ }
+
+ /**
+ * Sets the number of lines to be skipped in the filtered stream.
+ *
+ * @param skip the number of lines to be skipped in the filtered stream
+ */
+ public void setSkip(final long skip) {
+ this.skip = skip;
+ }
+
+ /**
+ * Returns the number of lines to be skipped in the filtered stream.
+ *
+ * @return the number of lines to be skipped in the filtered stream
+ */
+ private long getSkip() {
+ return skip;
+ }
+
+ /**
+ * Creates a new HeadFilter using the passed in
+ * Reader for instantiation.
+ *
+ * @param rdr A Reader object providing the underlying stream.
+ * Must not be <code>null</code>.
+ *
+ * @return a new filter based on this configuration, but filtering
+ * the specified reader
+ */
+ public Reader chain(final Reader rdr) {
+ HeadFilter newFilter = new HeadFilter(rdr);
+ newFilter.setLines(getLines());
+ newFilter.setSkip(getSkip());
+ newFilter.setInitialized(true);
+ return newFilter;
+ }
+
+ /**
+ * Scans the parameters list for the "lines" parameter and uses
+ * it to set the number of lines to be returned in the filtered stream.
+ * also scan for skip parameter.
+ */
+ private void initialize() {
+ Parameter[] params = getParameters();
+ if (params != null) {
+ for (int i = 0; i < params.length; i++) {
+ if (LINES_KEY.equals(params[i].getName())) {
+ lines = Long.parseLong(params[i].getValue());
+ continue;
+ }
+ if (SKIP_KEY.equals(params[i].getName())) {
+ skip = Long.parseLong(params[i].getValue());
+ continue;
+ }
+ }
+ }
+ }
+
+ /**
+ * implements a head filter on the input stream
+ */
+ private String headFilter(String line) {
+ linesRead++;
+ if (skip > 0) {
+ if ((linesRead - 1) < skip) {
+ return null;
+ }
+ }
+
+ if (lines > 0) {
+ if (linesRead > (lines + skip)) {
+ eof = true;
+ return null;
+ }
+ }
+ return line;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/LineContains.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/LineContains.java
new file mode 100644
index 00000000..c83cae28
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/LineContains.java
@@ -0,0 +1,244 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.filters;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.util.Vector;
+
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.Parameter;
+
+/**
+ * Filter which includes only those lines that contain all the user-specified
+ * strings.
+ *
+ * Example:
+ *
+ * <pre>&lt;linecontains&gt;
+ * &lt;contains value=&quot;foo&quot;&gt;
+ * &lt;contains value=&quot;bar&quot;&gt;
+ * &lt;/linecontains&gt;</pre>
+ *
+ * Or:
+ *
+ * <pre>&lt;filterreader classname=&quot;org.apache.tools.ant.filters.LineContains&quot;&gt;
+ * &lt;param type=&quot;contains&quot; value=&quot;foo&quot;/&gt;
+ * &lt;param type=&quot;contains&quot; value=&quot;bar&quot;/&gt;
+ * &lt;/filterreader&gt;</pre>
+ *
+ * This will include only those lines that contain <code>foo</code> and
+ * <code>bar</code>.
+ *
+ */
+public final class LineContains
+ extends BaseParamFilterReader
+ implements ChainableReader {
+ /** Parameter name for the words to filter on. */
+ private static final String CONTAINS_KEY = "contains";
+
+ /** Parameter name for the words to filter on. */
+ private static final String NEGATE_KEY = "negate";
+
+ /** Vector that holds the strings that input lines must contain. */
+ private Vector<String> contains = new Vector<String>();
+
+ /**
+ * Remaining line to be read from this filter, or <code>null</code> if
+ * the next call to <code>read()</code> should read the original stream
+ * to find the next matching line.
+ */
+ private String line = null;
+
+ private boolean negate = false;
+
+ /**
+ * Constructor for "dummy" instances.
+ *
+ * @see BaseFilterReader#BaseFilterReader()
+ */
+ public LineContains() {
+ super();
+ }
+
+ /**
+ * Creates a new filtered reader.
+ *
+ * @param in A Reader object providing the underlying stream.
+ * Must not be <code>null</code>.
+ */
+ public LineContains(final Reader in) {
+ super(in);
+ }
+
+ /**
+ * Returns the next character in the filtered stream, only including
+ * lines from the original stream which contain all of the specified words.
+ *
+ * @return the next character in the resulting stream, or -1
+ * if the end of the resulting stream has been reached
+ *
+ * @exception IOException if the underlying stream throws an IOException
+ * during reading
+ */
+ public int read() throws IOException {
+ if (!getInitialized()) {
+ initialize();
+ setInitialized(true);
+ }
+
+ int ch = -1;
+
+ if (line != null) {
+ ch = line.charAt(0);
+ if (line.length() == 1) {
+ line = null;
+ } else {
+ line = line.substring(1);
+ }
+ } else {
+ final int containsSize = contains.size();
+
+ for (line = readLine(); line != null; line = readLine()) {
+ boolean matches = true;
+ for (int i = 0; matches && i < containsSize; i++) {
+ String containsStr = (String) contains.elementAt(i);
+ matches = line.indexOf(containsStr) >= 0;
+ }
+ if (matches ^ isNegated()) {
+ break;
+ }
+ }
+ if (line != null) {
+ return read();
+ }
+ }
+ return ch;
+ }
+
+ /**
+ * Adds a <code>contains</code> element.
+ *
+ * @param contains The <code>contains</code> element to add.
+ * Must not be <code>null</code>.
+ */
+ public void addConfiguredContains(final Contains contains) {
+ this.contains.addElement(contains.getValue());
+ }
+
+ /**
+ * Set the negation mode. Default false (no negation).
+ * @param b the boolean negation mode to set.
+ */
+ public void setNegate(boolean b) {
+ negate = b;
+ }
+
+ /**
+ * Find out whether we have been negated.
+ * @return boolean negation flag.
+ */
+ public boolean isNegated() {
+ return negate;
+ }
+
+ /**
+ * Sets the vector of words which must be contained within a line read
+ * from the original stream in order for it to match this filter.
+ *
+ * @param contains A vector of words which must be contained within a line
+ * in order for it to match in this filter. Must not be <code>null</code>.
+ */
+ private void setContains(final Vector<String> contains) {
+ this.contains = contains;
+ }
+
+ /**
+ * Returns the vector of words which must be contained within a line read
+ * from the original stream in order for it to match this filter.
+ *
+ * @return the vector of words which must be contained within a line read
+ * from the original stream in order for it to match this filter. The
+ * returned object is "live" - in other words, changes made to the
+ * returned object are mirrored in the filter.
+ */
+ private Vector<String> getContains() {
+ return contains;
+ }
+
+ /**
+ * Creates a new LineContains using the passed in
+ * Reader for instantiation.
+ *
+ * @param rdr A Reader object providing the underlying stream.
+ * Must not be <code>null</code>.
+ *
+ * @return a new filter based on this configuration, but filtering
+ * the specified reader
+ */
+ public Reader chain(final Reader rdr) {
+ LineContains newFilter = new LineContains(rdr);
+ newFilter.setContains(getContains());
+ newFilter.setNegate(isNegated());
+ return newFilter;
+ }
+
+ /**
+ * Parses the parameters to add user-defined contains strings.
+ */
+ private void initialize() {
+ Parameter[] params = getParameters();
+ if (params != null) {
+ for (int i = 0; i < params.length; i++) {
+ if (CONTAINS_KEY.equals(params[i].getType())) {
+ contains.addElement(params[i].getValue());
+ } else if (NEGATE_KEY.equals(params[i].getType())) {
+ setNegate(Project.toBoolean(params[i].getValue()));
+ }
+ }
+ }
+ }
+
+ /**
+ * Holds a contains element
+ */
+ public static class Contains {
+
+ /** User defined contains string */
+ private String value;
+
+ /**
+ * Sets the contains string
+ *
+ * @param contains The contains string to set.
+ * Must not be <code>null</code>.
+ */
+ public final void setValue(String contains) {
+ value = contains;
+ }
+
+ /**
+ * Returns the contains string.
+ *
+ * @return the contains string for this element
+ */
+ public final String getValue() {
+ return value;
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/LineContainsRegExp.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/LineContainsRegExp.java
new file mode 100644
index 00000000..23a2005d
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/LineContainsRegExp.java
@@ -0,0 +1,242 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.filters;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.util.Vector;
+
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.Parameter;
+import org.apache.tools.ant.types.RegularExpression;
+import org.apache.tools.ant.util.regexp.Regexp;
+import org.apache.tools.ant.util.regexp.RegexpUtil;
+
+/**
+ * Filter which includes only those lines that contain the user-specified
+ * regular expression matching strings.
+ *
+ * Example:
+ * <pre>&lt;linecontainsregexp&gt;
+ * &lt;regexp pattern=&quot;foo*&quot;&gt;
+ * &lt;/linecontainsregexp&gt;</pre>
+ *
+ * Or:
+ *
+ * <pre>&lt;filterreader classname=&quot;org.apache.tools.ant.filters.LineContainsRegExp&quot;&gt;
+ * &lt;param type=&quot;regexp&quot; value=&quot;foo*&quot;/&gt;
+ * &lt;/filterreader&gt;</pre>
+ *
+ * This will fetch all those lines that contain the pattern <code>foo</code>
+ *
+ */
+public final class LineContainsRegExp
+ extends BaseParamFilterReader
+ implements ChainableReader {
+ /** Parameter name for the regular expression to filter on. */
+ private static final String REGEXP_KEY = "regexp";
+
+ /** Parameter name for the negate attribute. */
+ private static final String NEGATE_KEY = "negate";
+
+ /** Parameter name for the casesensitive attribute. */
+ private static final String CS_KEY = "casesensitive";
+
+ /** Vector that holds the expressions that input lines must contain. */
+ private Vector<RegularExpression> regexps = new Vector<RegularExpression>();
+
+ /**
+ * Remaining line to be read from this filter, or <code>null</code> if
+ * the next call to <code>read()</code> should read the original stream
+ * to find the next matching line.
+ */
+ private String line = null;
+
+ private boolean negate = false;
+ private int regexpOptions = Regexp.MATCH_DEFAULT;
+
+ /**
+ * Constructor for "dummy" instances.
+ *
+ * @see BaseFilterReader#BaseFilterReader()
+ */
+ public LineContainsRegExp() {
+ super();
+ }
+
+ /**
+ * Creates a new filtered reader.
+ *
+ * @param in A Reader object providing the underlying stream.
+ * Must not be <code>null</code>.
+ */
+ public LineContainsRegExp(final Reader in) {
+ super(in);
+ }
+
+ /**
+ * Returns the next character in the filtered stream, only including
+ * lines from the original stream which match all of the specified
+ * regular expressions.
+ *
+ * @return the next character in the resulting stream, or -1
+ * if the end of the resulting stream has been reached
+ *
+ * @exception IOException if the underlying stream throws an IOException
+ * during reading
+ */
+ public int read() throws IOException {
+ if (!getInitialized()) {
+ initialize();
+ setInitialized(true);
+ }
+
+ int ch = -1;
+
+ if (line != null) {
+ ch = line.charAt(0);
+ if (line.length() == 1) {
+ line = null;
+ } else {
+ line = line.substring(1);
+ }
+ } else {
+ final int regexpsSize = regexps.size();
+
+ for (line = readLine(); line != null; line = readLine()) {
+ boolean matches = true;
+ for (int i = 0; matches && i < regexpsSize; i++) {
+ RegularExpression regexp
+ = (RegularExpression) regexps.elementAt(i);
+ Regexp re = regexp.getRegexp(getProject());
+ matches = re.matches(line, regexpOptions);
+ }
+ if (matches ^ isNegated()) {
+ break;
+ }
+ }
+ if (line != null) {
+ return read();
+ }
+ }
+ return ch;
+ }
+
+ /**
+ * Adds a <code>regexp</code> element.
+ *
+ * @param regExp The <code>regexp</code> element to add.
+ * Must not be <code>null</code>.
+ */
+ public void addConfiguredRegexp(final RegularExpression regExp) {
+ this.regexps.addElement(regExp);
+ }
+
+ /**
+ * Sets the vector of regular expressions which must be contained within
+ * a line read from the original stream in order for it to match this
+ * filter.
+ *
+ * @param regexps A vector of regular expressions which must be contained
+ * within a line in order for it to match in this filter. Must not be
+ * <code>null</code>.
+ */
+ private void setRegexps(final Vector<RegularExpression> regexps) {
+ this.regexps = regexps;
+ }
+
+ /**
+ * Returns the vector of regular expressions which must be contained within
+ * a line read from the original stream in order for it to match this
+ * filter.
+ *
+ * @return the vector of regular expressions which must be contained within
+ * a line read from the original stream in order for it to match this
+ * filter. The returned object is "live" - in other words, changes made to
+ * the returned object are mirrored in the filter.
+ */
+ private Vector<RegularExpression> getRegexps() {
+ return regexps;
+ }
+
+ /**
+ * Creates a new LineContainsRegExp using the passed in
+ * Reader for instantiation.
+ *
+ * @param rdr A Reader object providing the underlying stream.
+ * Must not be <code>null</code>.
+ *
+ * @return a new filter based on this configuration, but filtering
+ * the specified reader
+ */
+ public Reader chain(final Reader rdr) {
+ LineContainsRegExp newFilter = new LineContainsRegExp(rdr);
+ newFilter.setRegexps(getRegexps());
+ newFilter.setNegate(isNegated());
+ newFilter
+ .setCaseSensitive(!RegexpUtil.hasFlag(regexpOptions,
+ Regexp.MATCH_CASE_INSENSITIVE)
+ );
+ return newFilter;
+ }
+
+ /**
+ * Set the negation mode. Default false (no negation).
+ * @param b the boolean negation mode to set.
+ */
+ public void setNegate(boolean b) {
+ negate = b;
+ }
+
+ /**
+ * Whether to match casesensitevly.
+ * @since Ant 1.8.2
+ */
+ public void setCaseSensitive(boolean b) {
+ regexpOptions = RegexpUtil.asOptions(b);
+ }
+
+ /**
+ * Find out whether we have been negated.
+ * @return boolean negation flag.
+ */
+ public boolean isNegated() {
+ return negate;
+ }
+
+ /**
+ * Parses parameters to add user defined regular expressions.
+ */
+ private void initialize() {
+ Parameter[] params = getParameters();
+ if (params != null) {
+ for (int i = 0; i < params.length; i++) {
+ if (REGEXP_KEY.equals(params[i].getType())) {
+ String pattern = params[i].getValue();
+ RegularExpression regexp = new RegularExpression();
+ regexp.setPattern(pattern);
+ regexps.addElement(regexp);
+ } else if (NEGATE_KEY.equals(params[i].getType())) {
+ setNegate(Project.toBoolean(params[i].getValue()));
+ } else if (CS_KEY.equals(params[i].getType())) {
+ setCaseSensitive(Project.toBoolean(params[i].getValue()));
+ }
+ }
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/PrefixLines.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/PrefixLines.java
new file mode 100644
index 00000000..324397e8
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/PrefixLines.java
@@ -0,0 +1,164 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.filters;
+
+import java.io.IOException;
+import java.io.Reader;
+
+import org.apache.tools.ant.types.Parameter;
+
+/**
+ * Attaches a prefix to every line.
+ *
+ * Example:
+ * <pre>&lt;prefixlines prefix=&quot;Foo&quot;/&gt;</pre>
+ *
+ * Or:
+ *
+ * <pre>&lt;filterreader classname=&quot;org.apache.tools.ant.filters.PrefixLines&quot;&gt;
+ * &lt;param name=&quot;prefix&quot; value=&quot;Foo&quot;/&gt;
+ * &lt;/filterreader&gt;</pre>
+ *
+ */
+public final class PrefixLines
+ extends BaseParamFilterReader
+ implements ChainableReader {
+ /** Parameter name for the prefix. */
+ private static final String PREFIX_KEY = "prefix";
+
+ /** The prefix to be used. */
+ private String prefix = null;
+
+ /** Data that must be read from, if not null. */
+ private String queuedData = null;
+
+ /**
+ * Constructor for "dummy" instances.
+ *
+ * @see BaseFilterReader#BaseFilterReader()
+ */
+ public PrefixLines() {
+ super();
+ }
+
+ /**
+ * Creates a new filtered reader.
+ *
+ * @param in A Reader object providing the underlying stream.
+ * Must not be <code>null</code>.
+ */
+ public PrefixLines(final Reader in) {
+ super(in);
+ }
+
+ /**
+ * Returns the next character in the filtered stream. One line is read
+ * from the original input, and the prefix added. The resulting
+ * line is then used until it ends, at which point the next original line
+ * is read, etc.
+ *
+ * @return the next character in the resulting stream, or -1
+ * if the end of the resulting stream has been reached
+ *
+ * @exception IOException if the underlying stream throws an IOException
+ * during reading
+ */
+ public int read() throws IOException {
+ if (!getInitialized()) {
+ initialize();
+ setInitialized(true);
+ }
+
+ int ch = -1;
+
+ if (queuedData != null && queuedData.length() == 0) {
+ queuedData = null;
+ }
+
+ if (queuedData != null) {
+ ch = queuedData.charAt(0);
+ queuedData = queuedData.substring(1);
+ if (queuedData.length() == 0) {
+ queuedData = null;
+ }
+ } else {
+ queuedData = readLine();
+ if (queuedData == null) {
+ ch = -1;
+ } else {
+ if (prefix != null) {
+ queuedData = prefix + queuedData;
+ }
+ return read();
+ }
+ }
+ return ch;
+ }
+
+ /**
+ * Sets the prefix to add at the start of each input line.
+ *
+ * @param prefix The prefix to add at the start of each input line.
+ * May be <code>null</code>, in which case no prefix
+ * is added.
+ */
+ public void setPrefix(final String prefix) {
+ this.prefix = prefix;
+ }
+
+ /**
+ * Returns the prefix which will be added at the start of each input line.
+ *
+ * @return the prefix which will be added at the start of each input line
+ */
+ private String getPrefix() {
+ return prefix;
+ }
+
+ /**
+ * Creates a new PrefixLines filter using the passed in
+ * Reader for instantiation.
+ *
+ * @param rdr A Reader object providing the underlying stream.
+ * Must not be <code>null</code>.
+ *
+ * @return a new filter based on this configuration, but filtering
+ * the specified reader
+ */
+ public Reader chain(final Reader rdr) {
+ PrefixLines newFilter = new PrefixLines(rdr);
+ newFilter.setPrefix(getPrefix());
+ newFilter.setInitialized(true);
+ return newFilter;
+ }
+
+ /**
+ * Initializes the prefix if it is available from the parameters.
+ */
+ private void initialize() {
+ Parameter[] params = getParameters();
+ if (params != null) {
+ for (int i = 0; i < params.length; i++) {
+ if (PREFIX_KEY.equals(params[i].getName())) {
+ prefix = params[i].getValue();
+ break;
+ }
+ }
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/ReplaceTokens.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/ReplaceTokens.java
new file mode 100644
index 00000000..21ca3bc9
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/ReplaceTokens.java
@@ -0,0 +1,379 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.filters;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Properties;
+import java.util.SortedMap;
+import java.util.TreeMap;
+
+import org.apache.tools.ant.types.Parameter;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.resources.FileResource;
+import org.apache.tools.ant.util.FileUtils;
+
+/**
+ * Replaces tokens in the original input with user-supplied values.
+ *
+ * Example:
+ *
+ * <pre>&lt;replacetokens begintoken=&quot;#&quot; endtoken=&quot;#&quot;&gt;
+ * &lt;token key=&quot;DATE&quot; value=&quot;${TODAY}&quot;/&gt;
+ * &lt;/replacetokens&gt;</pre>
+ *
+ * Or:
+ *
+ * <pre>&lt;filterreader classname="org.apache.tools.ant.filters.ReplaceTokens"&gt;
+ * &lt;param type="tokenchar" name="begintoken" value="#"/&gt;
+ * &lt;param type="tokenchar" name="endtoken" value="#"/&gt;
+ * &lt;param type="token" name="DATE" value="${TODAY}"/&gt;
+ * &lt;/filterreader&gt;</pre>
+ *
+ */
+public final class ReplaceTokens
+ extends BaseParamFilterReader
+ implements ChainableReader {
+ /** Default "begin token" character. */
+ private static final String DEFAULT_BEGIN_TOKEN = "@";
+
+ /** Default "end token" character. */
+ private static final String DEFAULT_END_TOKEN = "@";
+
+ /** Hashtable to holds the original replacee-replacer pairs (String to String). */
+ private Hashtable<String, String> hash = new Hashtable<String, String>();
+
+ /** This map holds the "resolved" tokens (begin- and end-tokens are added to make searching simpler) */
+ private final TreeMap<String, String> resolvedTokens = new TreeMap<String, String>();
+ private boolean resolvedTokensBuilt = false;
+ /** Used for comparisons and lookup into the resolvedTokens map. */
+ private String readBuffer = "";
+
+ /** replacement test from a token */
+ private String replaceData = null;
+
+ /** Index into replacement data */
+ private int replaceIndex = -1;
+
+ /** Character marking the beginning of a token. */
+ private String beginToken = DEFAULT_BEGIN_TOKEN;
+
+ /** Character marking the end of a token. */
+ private String endToken = DEFAULT_END_TOKEN;
+
+ /**
+ * Constructor for "dummy" instances.
+ *
+ * @see BaseFilterReader#BaseFilterReader()
+ */
+ public ReplaceTokens() {}
+
+ /**
+ * Creates a new filtered reader.
+ *
+ * @param in A Reader object providing the underlying stream.
+ * Must not be <code>null</code>.
+ */
+ public ReplaceTokens(final Reader in) {
+ super(in);
+ }
+
+ /**
+ * Returns the next character in the filtered stream, replacing tokens
+ * from the original stream.
+ *
+ * @return the next character in the resulting stream, or -1
+ * if the end of the resulting stream has been reached
+ *
+ * @exception IOException if the underlying stream throws an IOException
+ * during reading
+ */
+ public int read() throws IOException {
+ if (!getInitialized()) {
+ initialize();
+ setInitialized(true);
+ }
+
+ if (!resolvedTokensBuilt) {
+ // build the resolved tokens tree map.
+ for (String key : hash.keySet()) {
+ resolvedTokens.put(beginToken + key + endToken, hash.get(key));
+ }
+ resolvedTokensBuilt = true;
+ }
+
+ // are we currently serving replace data?
+ if (replaceData != null) {
+ if (replaceIndex < replaceData.length()) {
+ return replaceData.charAt(replaceIndex++);
+ } else {
+ replaceData = null;
+ }
+ }
+
+ // is the read buffer empty?
+ if (readBuffer.length() == 0) {
+ int next = in.read();
+ if (next == -1) {
+ return next; // end of stream. all buffers empty.
+ }
+ readBuffer += (char)next;
+ }
+
+ for (;;) {
+ // get the closest tokens
+ SortedMap<String,String> possibleTokens = resolvedTokens.tailMap(readBuffer);
+ if (possibleTokens.isEmpty() || !possibleTokens.firstKey().startsWith(readBuffer)) { // if there is none, then deliver the first char from the buffer.
+ return getFirstCharacterFromReadBuffer();
+ } else if (readBuffer.equals(possibleTokens.firstKey())) { // there exists a nearest token - is it an exact match?
+ // we have found a token. prepare the replaceData buffer.
+ replaceData = resolvedTokens.get(readBuffer);
+ replaceIndex = 0;
+ readBuffer = ""; // destroy the readBuffer - it's contents are being replaced entirely.
+ // get the first character via recursive call.
+ return read();
+ } else { // nearest token is not matching exactly - read one character more.
+ int next = in.read();
+ if (next != -1) {
+ readBuffer += (char)next;
+ } else {
+ return getFirstCharacterFromReadBuffer(); // end of stream. deliver remaining characters from buffer.
+ }
+ }
+ }
+ }
+
+ /**
+ * @return the first character from the read buffer or -1 if read buffer is empty.
+ */
+ private int getFirstCharacterFromReadBuffer() {
+ if (readBuffer.length() > 0) {
+ int chr = readBuffer.charAt(0);
+ readBuffer = readBuffer.substring(1);
+ return chr;
+ } else {
+ return -1;
+ }
+ }
+
+ /**
+ * Sets the "begin token" character.
+ *
+ * @param beginToken the character used to denote the beginning of a token
+ */
+ public void setBeginToken(final String beginToken) {
+ this.beginToken = beginToken;
+ }
+
+ /**
+ * Returns the "begin token" character.
+ *
+ * @return the character used to denote the beginning of a token
+ */
+ private String getBeginToken() {
+ return beginToken;
+ }
+
+ /**
+ * Sets the "end token" character.
+ *
+ * @param endToken the character used to denote the end of a token
+ */
+ public void setEndToken(final String endToken) {
+ this.endToken = endToken;
+ }
+
+ /**
+ * Returns the "end token" character.
+ *
+ * @return the character used to denote the end of a token
+ */
+ private String getEndToken() {
+ return endToken;
+ }
+
+ /**
+ * A resource containing properties, each of which is interpreted
+ * as a token/value pair.
+ *
+ * @since Ant 1.8.0
+ */
+ public void setPropertiesResource(Resource r) {
+ makeTokensFromProperties(r);
+ }
+
+ /**
+ * Adds a token element to the map of tokens to replace.
+ *
+ * @param token The token to add to the map of replacements.
+ * Must not be <code>null</code>.
+ */
+ public void addConfiguredToken(final Token token) {
+ hash.put(token.getKey(), token.getValue());
+ resolvedTokensBuilt = false; // invalidate to build them again if they have been built already.
+ }
+
+ /**
+ * Returns properties from a specified properties file.
+ *
+ * @param resource The resource to load properties from.
+ */
+ private Properties getProperties(Resource resource) {
+ InputStream in = null;
+ Properties props = new Properties();
+ try {
+ in = resource.getInputStream();
+ props.load(in);
+ } catch (IOException ioe) {
+ ioe.printStackTrace();
+ } finally {
+ FileUtils.close(in);
+ }
+
+ return props;
+ }
+
+ /**
+ * Sets the map of tokens to replace.
+ *
+ * @param hash A map (String->String) of token keys to replacement
+ * values. Must not be <code>null</code>.
+ */
+ private void setTokens(final Hashtable<String, String> hash) {
+ this.hash = hash;
+ }
+
+ /**
+ * Returns the map of tokens which will be replaced.
+ *
+ * @return a map (String->String) of token keys to replacement
+ * values
+ */
+ private Hashtable<String, String> getTokens() {
+ return hash;
+ }
+
+ /**
+ * Creates a new ReplaceTokens using the passed in
+ * Reader for instantiation.
+ *
+ * @param rdr A Reader object providing the underlying stream.
+ * Must not be <code>null</code>.
+ *
+ * @return a new filter based on this configuration, but filtering
+ * the specified reader
+ */
+ public Reader chain(final Reader rdr) {
+ ReplaceTokens newFilter = new ReplaceTokens(rdr);
+ newFilter.setBeginToken(getBeginToken());
+ newFilter.setEndToken(getEndToken());
+ newFilter.setTokens(getTokens());
+ newFilter.setInitialized(true);
+ return newFilter;
+ }
+
+ /**
+ * Initializes tokens and loads the replacee-replacer hashtable.
+ */
+ private void initialize() {
+ Parameter[] params = getParameters();
+ if (params != null) {
+ for (Parameter param : params) {
+ if (param != null) {
+ final String type = param.getType();
+ if ("tokenchar".equals(type)) {
+ final String name = param.getName();
+ if ("begintoken".equals(name)) {
+ beginToken = param.getValue();
+ } else if ("endtoken".equals(name)) {
+ endToken = param.getValue();
+ }
+ } else if ("token".equals(type)) {
+ final String name = param.getName();
+ final String value = param.getValue();
+ hash.put(name, value);
+ } else if ("propertiesfile".equals(type)) {
+ makeTokensFromProperties(
+ new FileResource(new File(param.getValue())));
+ }
+ }
+ }
+ }
+ }
+
+ private void makeTokensFromProperties(Resource r) {
+ Properties props = getProperties(r);
+ for (Enumeration<?> e = props.keys(); e.hasMoreElements();) {
+ String key = (String) e.nextElement();
+ String value = props.getProperty(key);
+ hash.put(key, value);
+ }
+ }
+
+ /**
+ * Holds a token
+ */
+ public static class Token {
+
+ /** Token key */
+ private String key;
+
+ /** Token value */
+ private String value;
+
+ /**
+ * Sets the token key
+ *
+ * @param key The key for this token. Must not be <code>null</code>.
+ */
+ public final void setKey(String key) {
+ this.key = key;
+ }
+
+ /**
+ * Sets the token value
+ *
+ * @param value The value for this token. Must not be <code>null</code>.
+ */
+ public final void setValue(String value) {
+ this.value = value;
+ }
+
+ /**
+ * Returns the key for this token.
+ *
+ * @return the key for this token
+ */
+ public final String getKey() {
+ return key;
+ }
+
+ /**
+ * Returns the value for this token.
+ *
+ * @return the value for this token
+ */
+ public final String getValue() {
+ return value;
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/SortFilter.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/SortFilter.java
new file mode 100644
index 00000000..471660c3
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/SortFilter.java
@@ -0,0 +1,375 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.filters;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.types.Parameter;
+
+/**
+ * <p>
+ * Sort a file before and/or after the file.
+ * </p>
+ *
+ * <p>
+ * Examples:
+ * </p>
+ *
+ * <pre>
+ * &lt;copy todir=&quot;build&quot;&gt;
+ * &lt;fileset dir=&quot;input&quot; includes=&quot;*.txt&quot;/&gt;
+ * &lt;filterchain&gt;
+ * &lt;sortfilter/&gt;
+ * &lt;/filterchain&gt;
+ * &lt;/copy&gt;
+ * </pre>
+ *
+ * <p>
+ * Sort all files <code>*.txt</code> from <i>src</i> location and copy
+ * them into <i>build</i> location. The lines of each file are sorted
+ * in ascendant order comparing the lines via the
+ * <code>String.compareTo(Object o)</code> method.
+ * </p>
+ *
+ * <pre>
+ * &lt;copy todir=&quot;build&quot;&gt;
+ * &lt;fileset dir=&quot;input&quot; includes=&quot;*.txt&quot;/&gt;
+ * &lt;filterchain&gt;
+ * &lt;sortfilter reverse=&quot;true&quot;/&gt;
+ * &lt;/filterchain&gt;
+ * &lt;/copy&gt;
+ * </pre>
+ *
+ * <p>
+ * Sort all files <code>*.txt</code> from <i>src</i> location into reverse
+ * order and copy them into <i>build</i> location. If reverse parameter has
+ * value <code>true</code> (default value), then the output line of the files
+ * will be in ascendant order.
+ * </p>
+ *
+ * <pre>
+ * &lt;copy todir=&quot;build&quot;&gt;
+ * &lt;fileset dir=&quot;input&quot; includes=&quot;*.txt&quot;/&gt;
+ * &lt;filterchain&gt;
+ * &lt;filterreader classname=&quot;org.apache.tools.ant.filters.SortFilter&quot;&gt;
+ * &lt;param name=&quot;comparator&quot; value=&quot;org.apache.tools.ant.filters.EvenFirstCmp&quot;/&gt;
+ * &lt;/filterreader&gt;
+ * &lt;/filterchain&gt;
+ * &lt;/copy&gt;
+ * </pre>
+ *
+ * <p>
+ * Sort all files <code>*.txt</code> from <i>src</i> location using as
+ * sorting criterium <code>EvenFirstCmp</code> class, that sorts the file
+ * lines putting even lines first then odd lines for example. The modified files
+ * are copied into <i>build</i> location. The <code>EvenFirstCmp</code>,
+ * has to an instanciable class via <code>Class.newInstance()</code>,
+ * therefore in case of inner class has to be <em>static</em>. It also has to
+ * implement <code>java.util.Comparator</code> interface, for example:
+ * </p>
+ *
+ * <pre>
+ * package org.apache.tools.ant.filters;
+ * ...(omitted)
+ * public final class EvenFirstCmp implements &lt;b&gt;Comparator&lt;/b&gt; {
+ * public int compare(Object o1, Object o2) {
+ * ...(omitted)
+ * }
+ * }
+ * </pre>
+ *
+ * <p>The example above is equivalent to:</p>
+ *
+ * <blockquote><pre>
+ * &lt;componentdef name="evenfirst"
+ * classname="org.apache.tools.ant.filters.EvenFirstCmp&quot;/&gt;
+ * &lt;copy todir=&quot;build&quot;&gt;
+ * &lt;fileset dir=&quot;input&quot; includes=&quot;*.txt&quot;/&gt;
+ * &lt;filterchain&gt;
+ * &lt;sortfilter&gt;
+ * &lt;evenfirst/&gt;
+ * &lt;/sortfilter&gt;
+ * &lt;/filterchain&gt;
+ * &lt;/copy&gt;
+ * </pre></blockquote>
+ *
+ * <p> If parameter <code>comparator</code> is present, then
+ * <code>reverse</code> parameter will not be taken into account. </p>
+ *
+ * @since Ant 1.8.0
+ */
+public final class SortFilter extends BaseParamFilterReader
+ implements ChainableReader {
+
+ /** Parameter name for reverse order. */
+ private static final String REVERSE_KEY = "reverse";
+
+ /**
+ * Parameter name for specifying the comparator criteria via class that
+ * implement <code>java.util.Comparator</code> interface.
+ */
+ private static final String COMPARATOR_KEY = "comparator";
+
+ /**
+ * Instance of comparator class to be used for sorting.
+ */
+ private Comparator<? super String> comparator = null;
+
+ /**
+ * Controls if the sorting process will be in ascendant/descendant order. If
+ * If has value <code>true</code>, then the line of the file will be
+ * sorted on descendant order. Default value: <code>false</code>. It will
+ * be considered only if <code>comparator</code> is <code>null</code>.
+ */
+ private boolean reverse;
+
+ /**
+ * Stores the lines to be sorted.
+ */
+ private List<String> lines;
+
+ /**
+ * Remaining line to be read from this filter, or <code>null</code> if the
+ * next call to <code>read()</code> should read the original stream to
+ * find the next matching line.
+ */
+ private String line = null;
+
+ private Iterator<String> iterator = null;
+
+ /**
+ * Constructor for "dummy" instances.
+ *
+ * @see BaseFilterReader#BaseFilterReader()
+ */
+ public SortFilter() {
+ super();
+ }
+
+ /**
+ * Creates a new filtered reader.
+ *
+ * @param in
+ * A Reader object providing the underlying stream. Must not be
+ * <code>null</code>.
+ */
+ public SortFilter(final Reader in) {
+ super(in);
+ }
+
+ /**
+ * Returns the next character in the filtered stream. If the desired number
+ * of lines have already been read, the resulting stream is effectively at
+ * an end. Otherwise, the next character from the underlying stream is read
+ * and returned.
+ *
+ * @return the next character in the resulting stream, or -1 if the end of
+ * the resulting stream has been reached
+ *
+ * @exception IOException
+ * if the underlying stream throws an IOException during
+ * reading
+ */
+ public int read() throws IOException {
+ if (!getInitialized()) {
+ initialize();
+ setInitialized(true);
+ }
+
+ int ch = -1;
+ if (line != null) {
+ /*
+ * We are on the state: "reading the current line", lines are
+ * already sorted
+ */
+ ch = line.charAt(0);
+ if (line.length() == 1) {
+ line = null;
+ } else {
+ line = line.substring(1);
+ }
+ } else {
+ if (lines == null) {
+ // We read all lines and sort them
+ lines = new ArrayList<String>();
+ for (line = readLine(); line != null; line = readLine()) {
+ lines.add(line);
+ }
+ sort();
+ iterator = lines.iterator();
+ }
+
+ if (iterator.hasNext()) {
+ line = (String) iterator.next();
+ } else {
+ line = null;
+ lines = null;
+ iterator = null;
+ }
+ if (line != null) {
+ return read();
+ }
+ }
+ return ch;
+ }
+
+ /**
+ * Creates a new SortReader using the passed in Reader for instantiation.
+ *
+ * @param rdr
+ * A Reader object providing the underlying stream. Must not be
+ * <code>null</code>.
+ *
+ * @return a new filter based on this configuration, but filtering the
+ * specified reader
+ */
+ public Reader chain(final Reader rdr) {
+ SortFilter newFilter = new SortFilter(rdr);
+ newFilter.setReverse(isReverse());
+ newFilter.setComparator(getComparator());
+ newFilter.setInitialized(true);
+ return newFilter;
+ }
+
+ /**
+ * Returns <code>true</code> if the sorting process will be in reverse
+ * order, otherwise the sorting process will be in ascendant order.
+ *
+ * @return <code>true</code> if the sorting process will be in reverse
+ * order, otherwise the sorting process will be in ascendant order.
+ */
+ public boolean isReverse() {
+ return reverse;
+ }
+
+ /**
+ * Sets the sorting process will be in ascendant (<code>reverse=false</code>)
+ * or to descendant (<code>reverse=true</code>).
+ *
+ * @param reverse
+ * Boolean representing reverse ordering process.
+ */
+ public void setReverse(boolean reverse) {
+ this.reverse = reverse;
+ }
+
+ /**
+ * Returns the comparator to be used for sorting.
+ *
+ * @return the comparator
+ */
+ public Comparator<? super String> getComparator() {
+ return comparator;
+ }
+
+ /**
+ * Set the comparator to be used as sorting criterium.
+ *
+ * @param comparator
+ * the comparator to set
+ */
+ public void setComparator(Comparator<? super String> comparator) {
+ this.comparator = comparator;
+ }
+
+ /**
+ * Set the comparator to be used as sorting criterion as nested element.
+ *
+ * @param comparator
+ * the comparator to set
+ */
+ public void add(Comparator<? super String> comparator) {
+ if (this.comparator != null && comparator != null) {
+ throw new BuildException("can't have more than one comparator");
+ }
+ setComparator(comparator);
+ }
+
+ /**
+ * Scans the parameters list
+ */
+ private void initialize() throws IOException {
+ // get parameters
+ Parameter[] params = getParameters();
+ if (params != null) {
+ for (int i = 0; i < params.length; i++) {
+ final String paramName = params[i].getName();
+ if (REVERSE_KEY.equals(paramName)) {
+ setReverse(Boolean.valueOf(params[i].getValue())
+ .booleanValue());
+ continue;
+ }
+ if (COMPARATOR_KEY.equals(paramName)) {
+ try {
+ String className = (String) params[i].getValue();
+ @SuppressWarnings("unchecked")
+ final Comparator<? super String> comparatorInstance = (Comparator<? super String>) (Class
+ .forName(className).newInstance());
+ setComparator(comparatorInstance);
+ continue;
+ } catch (InstantiationException e) {
+ throw new BuildException(e);
+ } catch (IllegalAccessException e) {
+ /*
+ * Probably a inner non-static class, this this case is
+ * not considered
+ */
+ throw new BuildException(e);
+ } catch (ClassNotFoundException e) {
+ throw new BuildException(e);
+ } catch (ClassCastException e) {
+ throw new BuildException("Value of comparator attribute"
+ + " should implement"
+ + " java.util.Comparator"
+ + " interface");
+ } catch (Exception e) {
+ throw new BuildException(e);
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Sorts the read lines (<code>lines</code>) according to the sorting
+ * criteria defined by the user.
+ *
+ */
+ private void sort() {
+ if (comparator == null) {
+ if (reverse) {
+ Collections.sort(lines, new Comparator<String>() {
+ public int compare(String s1, String s2) {
+ return (-s1.compareTo(s2));
+ }
+ });
+ } else {
+ Collections.sort(lines);
+ }
+ } else {
+ Collections.sort(lines, comparator);
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/StringInputStream.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/StringInputStream.java
new file mode 100644
index 00000000..e150e965
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/StringInputStream.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.filters;
+
+import java.io.StringReader;
+
+import org.apache.tools.ant.util.ReaderInputStream;
+
+/**
+ * Wraps a String as an InputStream.
+ *
+ */
+public class StringInputStream extends ReaderInputStream {
+
+ /**
+ * Composes a stream from a String
+ *
+ * @param source The string to read from. Must not be <code>null</code>.
+ */
+ public StringInputStream(String source) {
+ super(new StringReader(source));
+ }
+
+ /**
+ * Composes a stream from a String with the specified encoding
+ *
+ * @param source The string to read from. Must not be <code>null</code>.
+ * @param encoding The encoding scheme. Also must not be <code>null</code>.
+ */
+ public StringInputStream(String source, String encoding) {
+ super(new StringReader(source), encoding);
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/StripJavaComments.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/StripJavaComments.java
new file mode 100644
index 00000000..65bccd70
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/StripJavaComments.java
@@ -0,0 +1,145 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.filters;
+
+import java.io.IOException;
+import java.io.Reader;
+
+/**
+ * This is a Java comment and string stripper reader that filters
+ * those lexical tokens out for purposes of simple Java parsing.
+ * (if you have more complex Java parsing needs, use a real lexer).
+ * Since this class heavily relies on the single char read function,
+ * you are recommended to make it work on top of a buffered reader.
+ *
+ */
+public final class StripJavaComments
+ extends BaseFilterReader
+ implements ChainableReader {
+
+ /**
+ * The read-ahead character, used for effectively pushing a single
+ * character back. A value of -1 indicates that no character is in the
+ * buffer.
+ */
+ private int readAheadCh = -1;
+
+ /**
+ * Whether or not the parser is currently in the middle of a string
+ * literal.
+ */
+ private boolean inString = false;
+
+ /**
+ * Whether or not the last char has been a backslash.
+ */
+ private boolean quoted = false;
+
+ /**
+ * Constructor for "dummy" instances.
+ *
+ * @see BaseFilterReader#BaseFilterReader()
+ */
+ public StripJavaComments() {
+ super();
+ }
+
+ /**
+ * Creates a new filtered reader.
+ *
+ * @param in A Reader object providing the underlying stream.
+ * Must not be <code>null</code>.
+ */
+ public StripJavaComments(final Reader in) {
+ super(in);
+ }
+
+ /**
+ * Returns the next character in the filtered stream, not including
+ * Java comments.
+ *
+ * @return the next character in the resulting stream, or -1
+ * if the end of the resulting stream has been reached
+ *
+ * @exception IOException if the underlying stream throws an IOException
+ * during reading
+ */
+ public int read() throws IOException {
+ int ch = -1;
+ if (readAheadCh != -1) {
+ ch = readAheadCh;
+ readAheadCh = -1;
+ } else {
+ ch = in.read();
+ if (ch == '"' && !quoted) {
+ inString = !inString;
+ quoted = false;
+ } else if (ch == '\\') {
+ quoted = !quoted;
+ } else {
+ quoted = false;
+ if (!inString) {
+ if (ch == '/') {
+ ch = in.read();
+ if (ch == '/') {
+ while (ch != '\n' && ch != -1 && ch != '\r') {
+ ch = in.read();
+ }
+ } else if (ch == '*') {
+ while (ch != -1) {
+ ch = in.read();
+ if (ch == '*') {
+ ch = in.read();
+ while (ch == '*') {
+ ch = in.read();
+ }
+
+ if (ch == '/') {
+ ch = read();
+ break;
+ }
+ }
+ }
+ } else {
+ readAheadCh = ch;
+ ch = '/';
+ }
+ }
+ }
+ }
+ }
+
+ return ch;
+ }
+
+ /**
+ * Creates a new StripJavaComments using the passed in
+ * Reader for instantiation.
+ *
+ * @param rdr A Reader object providing the underlying stream.
+ * Must not be <code>null</code>.
+ *
+ * @return a new filter based on this configuration, but filtering
+ * the specified reader
+ */
+
+ public Reader chain(final Reader rdr) {
+ StripJavaComments newFilter = new StripJavaComments(rdr);
+ return newFilter;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/StripLineBreaks.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/StripLineBreaks.java
new file mode 100644
index 00000000..9a97940a
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/StripLineBreaks.java
@@ -0,0 +1,154 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.filters;
+
+import java.io.IOException;
+import java.io.Reader;
+
+import org.apache.tools.ant.types.Parameter;
+
+/**
+ * Filter to flatten the stream to a single line.
+ *
+ * Example:
+ *
+ * <pre>&lt;striplinebreaks/&gt;</pre>
+ *
+ * Or:
+ *
+ * <pre>&lt;filterreader
+ * classname=&quot;org.apache.tools.ant.filters.StripLineBreaks&quot;/&gt;</pre>
+ *
+ */
+public final class StripLineBreaks
+ extends BaseParamFilterReader
+ implements ChainableReader {
+ /**
+ * Line-breaking characters.
+ * What should we do on funny IBM mainframes with odd line endings?
+ */
+ private static final String DEFAULT_LINE_BREAKS = "\r\n";
+
+ /** Parameter name for the line-breaking characters parameter. */
+ private static final String LINE_BREAKS_KEY = "linebreaks";
+
+ /** The characters that are recognized as line breaks. */
+ private String lineBreaks = DEFAULT_LINE_BREAKS;
+
+ /**
+ * Constructor for "dummy" instances.
+ *
+ * @see BaseFilterReader#BaseFilterReader()
+ */
+ public StripLineBreaks() {
+ super();
+ }
+
+ /**
+ * Creates a new filtered reader.
+ *
+ * @param in A Reader object providing the underlying stream.
+ * Must not be <code>null</code>.
+ */
+ public StripLineBreaks(final Reader in) {
+ super(in);
+ }
+
+ /**
+ * Returns the next character in the filtered stream, only including
+ * characters not in the set of line-breaking characters.
+ *
+ * @return the next character in the resulting stream, or -1
+ * if the end of the resulting stream has been reached
+ *
+ * @exception IOException if the underlying stream throws an IOException
+ * during reading
+ */
+ public int read() throws IOException {
+ if (!getInitialized()) {
+ initialize();
+ setInitialized(true);
+ }
+
+ int ch = in.read();
+ while (ch != -1) {
+ if (lineBreaks.indexOf(ch) == -1) {
+ break;
+ } else {
+ ch = in.read();
+ }
+ }
+ return ch;
+ }
+
+ /**
+ * Sets the line-breaking characters.
+ *
+ * @param lineBreaks A String containing all the characters to be
+ * considered as line-breaking.
+ */
+ public void setLineBreaks(final String lineBreaks) {
+ this.lineBreaks = lineBreaks;
+ }
+
+ /**
+ * Returns the line-breaking characters as a String.
+ *
+ * @return a String containing all the characters considered as
+ * line-breaking
+ */
+ private String getLineBreaks() {
+ return lineBreaks;
+ }
+
+ /**
+ * Creates a new StripLineBreaks using the passed in
+ * Reader for instantiation.
+ *
+ * @param rdr A Reader object providing the underlying stream.
+ * Must not be <code>null</code>.
+ *
+ * @return a new filter based on this configuration, but filtering
+ * the specified reader
+ */
+ public Reader chain(final Reader rdr) {
+ StripLineBreaks newFilter = new StripLineBreaks(rdr);
+ newFilter.setLineBreaks(getLineBreaks());
+ newFilter.setInitialized(true);
+ return newFilter;
+ }
+
+ /**
+ * Parses the parameters to set the line-breaking characters.
+ */
+ private void initialize() {
+ String userDefinedLineBreaks = null;
+ Parameter[] params = getParameters();
+ if (params != null) {
+ for (int i = 0; i < params.length; i++) {
+ if (LINE_BREAKS_KEY.equals(params[i].getName())) {
+ userDefinedLineBreaks = params[i].getValue();
+ break;
+ }
+ }
+ }
+ if (userDefinedLineBreaks != null) {
+ lineBreaks = userDefinedLineBreaks;
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/StripLineComments.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/StripLineComments.java
new file mode 100644
index 00000000..e3d240ba
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/StripLineComments.java
@@ -0,0 +1,237 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.filters;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.util.Vector;
+
+import org.apache.tools.ant.types.Parameter;
+
+/**
+ * This filter strips line comments.
+ *
+ * Example:
+ *
+ * <pre>&lt;striplinecomments&gt;
+ * &lt;comment value=&quot;#&quot;/&gt;
+ * &lt;comment value=&quot;--&quot;/&gt;
+ * &lt;comment value=&quot;REM &quot;/&gt;
+ * &lt;comment value=&quot;rem &quot;/&gt;
+ * &lt;comment value=&quot;//&quot;/&gt;
+ * &lt;/striplinecomments&gt;</pre>
+ *
+ * Or:
+ *
+ * <pre>&lt;filterreader
+ * classname=&quot;org.apache.tools.ant.filters.StripLineComments&quot;&gt;
+ * &lt;param type=&quot;comment&quot; value="#&quot;/&gt;
+ * &lt;param type=&quot;comment&quot; value=&quot;--&quot;/&gt;
+ * &lt;param type=&quot;comment&quot; value=&quot;REM &quot;/&gt;
+ * &lt;param type=&quot;comment&quot; value=&quot;rem &quot;/&gt;
+ * &lt;param type=&quot;comment&quot; value=&quot;//&quot;/&gt;
+ * &lt;/filterreader&gt;</pre>
+ *
+ */
+public final class StripLineComments
+ extends BaseParamFilterReader
+ implements ChainableReader {
+ /** Parameter name for the comment prefix. */
+ private static final String COMMENTS_KEY = "comment";
+
+ /** Vector that holds the comment prefixes. */
+ private Vector<String> comments = new Vector<String>();
+
+ /** The line that has been read ahead. */
+ private String line = null;
+
+ /**
+ * Constructor for "dummy" instances.
+ *
+ * @see BaseFilterReader#BaseFilterReader()
+ */
+ public StripLineComments() {
+ super();
+ }
+
+ /**
+ * Creates a new filtered reader.
+ *
+ * @param in A Reader object providing the underlying stream.
+ * Must not be <code>null</code>.
+ */
+ public StripLineComments(final Reader in) {
+ super(in);
+ }
+
+ /**
+ * Returns the next character in the filtered stream, only including
+ * lines from the original stream which don't start with any of the
+ * specified comment prefixes.
+ *
+ * @return the next character in the resulting stream, or -1
+ * if the end of the resulting stream has been reached
+ *
+ * @exception IOException if the underlying stream throws an IOException
+ * during reading
+ */
+ public int read() throws IOException {
+ if (!getInitialized()) {
+ initialize();
+ setInitialized(true);
+ }
+
+ int ch = -1;
+
+ if (line != null) {
+ ch = line.charAt(0);
+ if (line.length() == 1) {
+ line = null;
+ } else {
+ line = line.substring(1);
+ }
+ } else {
+ line = readLine();
+ final int commentsSize = comments.size();
+
+ while (line != null) {
+ for (int i = 0; i < commentsSize; i++) {
+ String comment = comments.elementAt(i);
+ if (line.startsWith(comment)) {
+ line = null;
+ break;
+ }
+ }
+
+ if (line == null) {
+ // line started with comment
+ line = readLine();
+ } else {
+ break;
+ }
+ }
+
+ if (line != null) {
+ return read();
+ }
+ }
+
+ return ch;
+ }
+
+ /**
+ * Adds a <code>comment</code> element to the list of prefixes.
+ *
+ * @param comment The <code>comment</code> element to add to the
+ * list of comment prefixes to strip. Must not be <code>null</code>.
+ */
+ public void addConfiguredComment(final Comment comment) {
+ comments.addElement(comment.getValue());
+ }
+
+ /**
+ * Sets the list of comment prefixes to strip.
+ *
+ * @param comments A list of strings, each of which is a prefix
+ * for a comment line. Must not be <code>null</code>.
+ */
+ private void setComments(final Vector<String> comments) {
+ this.comments = comments;
+ }
+
+ /**
+ * Returns the list of comment prefixes to strip.
+ *
+ * @return the list of comment prefixes to strip.
+ */
+ private Vector<String> getComments() {
+ return comments;
+ }
+
+ /**
+ * Creates a new StripLineComments using the passed in
+ * Reader for instantiation.
+ *
+ * @param rdr A Reader object providing the underlying stream.
+ * Must not be <code>null</code>.
+ *
+ * @return a new filter based on this configuration, but filtering
+ * the specified reader
+ */
+ public Reader chain(final Reader rdr) {
+ StripLineComments newFilter = new StripLineComments(rdr);
+ newFilter.setComments(getComments());
+ newFilter.setInitialized(true);
+ return newFilter;
+ }
+
+ /**
+ * Parses the parameters to set the comment prefixes.
+ */
+ private void initialize() {
+ Parameter[] params = getParameters();
+ if (params != null) {
+ for (int i = 0; i < params.length; i++) {
+ if (COMMENTS_KEY.equals(params[i].getType())) {
+ comments.addElement(params[i].getValue());
+ }
+ }
+ }
+ }
+
+ /**
+ * The class that holds a comment representation.
+ */
+ public static class Comment {
+
+ /** The prefix for a line comment. */
+ private String value;
+
+ /**
+ * Sets the prefix for this type of line comment.
+ *
+ * @param comment The prefix for a line comment of this type.
+ * Must not be <code>null</code>.
+ */
+ public final void setValue(String comment) {
+ if (value != null) {
+ throw new IllegalStateException("Comment value already set.");
+ }
+ value = comment;
+ }
+
+ /**
+ * Returns the prefix for this type of line comment.
+ *
+ * @return the prefix for this type of line comment.
+ */
+ public final String getValue() {
+ return value;
+ }
+
+ /**
+ * Alt. syntax to set the prefix for this type of line comment.
+ *
+ * @param comment The prefix for a line comment of this type.
+ * Must not be <code>null</code>.
+ */
+ public void addText(String comment) {
+ setValue(comment);
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/SuffixLines.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/SuffixLines.java
new file mode 100644
index 00000000..23d9b534
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/SuffixLines.java
@@ -0,0 +1,174 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.filters;
+
+import java.io.IOException;
+import java.io.Reader;
+
+import org.apache.tools.ant.types.Parameter;
+
+/**
+ * Attaches a suffix to every line.
+ *
+ * Example:
+ * <pre>&lt;suffixlines suffix=&quot;Foo&quot;/&gt;</pre>
+ *
+ * Or:
+ *
+ * <pre>&lt;filterreader classname=&quot;org.apache.tools.ant.filters.SuffixLines&quot;&gt;
+ * &lt;param name=&quot;suffix&quot; value=&quot;Foo&quot;/&gt;
+ * &lt;/filterreader&gt;</pre>
+ *
+ * @since Ant 1.8.0
+ */
+public final class SuffixLines
+ extends BaseParamFilterReader
+ implements ChainableReader {
+ /** Parameter name for the prefix. */
+ private static final String SUFFIX_KEY = "suffix";
+
+ /** The suffix to be used. */
+ private String suffix = null;
+
+ /** Data that must be read from, if not null. */
+ private String queuedData = null;
+
+ /**
+ * Constructor for "dummy" instances.
+ *
+ * @see BaseFilterReader#BaseFilterReader()
+ */
+ public SuffixLines() {
+ super();
+ }
+
+ /**
+ * Creates a new filtered reader.
+ *
+ * @param in A Reader object providing the underlying stream.
+ * Must not be <code>null</code>.
+ */
+ public SuffixLines(final Reader in) {
+ super(in);
+ }
+
+ /**
+ * Returns the next character in the filtered stream. One line is read
+ * from the original input, and the suffix added. The resulting
+ * line is then used until it ends, at which point the next original line
+ * is read, etc.
+ *
+ * @return the next character in the resulting stream, or -1
+ * if the end of the resulting stream has been reached
+ *
+ * @exception IOException if the underlying stream throws an IOException
+ * during reading
+ */
+ public int read() throws IOException {
+ if (!getInitialized()) {
+ initialize();
+ setInitialized(true);
+ }
+
+ int ch = -1;
+
+ if (queuedData != null && queuedData.length() == 0) {
+ queuedData = null;
+ }
+
+ if (queuedData != null) {
+ ch = queuedData.charAt(0);
+ queuedData = queuedData.substring(1);
+ if (queuedData.length() == 0) {
+ queuedData = null;
+ }
+ } else {
+ queuedData = readLine();
+ if (queuedData == null) {
+ ch = -1;
+ } else {
+ if (suffix != null) {
+ String lf = "";
+ if (queuedData.endsWith("\r\n")) {
+ lf = "\r\n";
+ } else if (queuedData.endsWith("\n")) {
+ lf = "\n";
+ }
+ queuedData =
+ queuedData.substring(0,
+ queuedData.length() - lf.length())
+ + suffix + lf;
+ }
+ return read();
+ }
+ }
+ return ch;
+ }
+
+ /**
+ * Sets the suffix to add at the end of each input line.
+ *
+ * @param suffix The suffix to add at the end of each input line.
+ * May be <code>null</code>, in which case no suffix
+ * is added.
+ */
+ public void setSuffix(final String suffix) {
+ this.suffix = suffix;
+ }
+
+ /**
+ * Returns the suffix which will be added at the end of each input line.
+ *
+ * @return the suffix which will be added at the end of each input line
+ */
+ private String getSuffix() {
+ return suffix;
+ }
+
+ /**
+ * Creates a new SuffixLines filter using the passed in
+ * Reader for instantiation.
+ *
+ * @param rdr A Reader object providing the underlying stream.
+ * Must not be <code>null</code>.
+ *
+ * @return a new filter based on this configuration, but filtering
+ * the specified reader
+ */
+ public Reader chain(final Reader rdr) {
+ SuffixLines newFilter = new SuffixLines(rdr);
+ newFilter.setSuffix(getSuffix());
+ newFilter.setInitialized(true);
+ return newFilter;
+ }
+
+ /**
+ * Initializes the suffix if it is available from the parameters.
+ */
+ private void initialize() {
+ Parameter[] params = getParameters();
+ if (params != null) {
+ for (int i = 0; i < params.length; i++) {
+ if (SUFFIX_KEY.equals(params[i].getName())) {
+ suffix = params[i].getValue();
+ break;
+ }
+ }
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/TabsToSpaces.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/TabsToSpaces.java
new file mode 100644
index 00000000..adaaa7af
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/TabsToSpaces.java
@@ -0,0 +1,155 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.filters;
+
+import java.io.IOException;
+import java.io.Reader;
+
+import org.apache.tools.ant.types.Parameter;
+
+/**
+ * Converts tabs to spaces.
+ *
+ * Example:
+ *
+ * <pre>&lt;tabstospaces tablength=&quot;8&quot;/&gt;</pre>
+ *
+ * Or:
+ *
+ * <pre>&lt;filterreader classname=&quot;org.apache.tools.ant.filters.TabsToSpaces&quot;&gt;
+ * &lt;param name=&quot;tablength&quot; value=&quot;8&quot;/&gt;
+ * &lt;/filterreader&gt;</pre>
+ *
+ */
+public final class TabsToSpaces
+ extends BaseParamFilterReader
+ implements ChainableReader {
+ /** The default tab length. */
+ private static final int DEFAULT_TAB_LENGTH = 8;
+
+ /** Parameter name for the length of a tab. */
+ private static final String TAB_LENGTH_KEY = "tablength";
+
+ /** Tab length in this filter. */
+ private int tabLength = DEFAULT_TAB_LENGTH;
+
+ /** The number of spaces still to be read to represent the last-read tab. */
+ private int spacesRemaining = 0;
+
+ /**
+ * Constructor for "dummy" instances.
+ *
+ * @see BaseFilterReader#BaseFilterReader()
+ */
+ public TabsToSpaces() {
+ super();
+ }
+
+ /**
+ * Creates a new filtered reader.
+ *
+ * @param in A Reader object providing the underlying stream.
+ * Must not be <code>null</code>.
+ */
+ public TabsToSpaces(final Reader in) {
+ super(in);
+ }
+
+ /**
+ * Returns the next character in the filtered stream, converting tabs
+ * to the specified number of spaces.
+ *
+ * @return the next character in the resulting stream, or -1
+ * if the end of the resulting stream has been reached
+ *
+ * @exception IOException if the underlying stream throws an IOException
+ * during reading
+ */
+ public int read() throws IOException {
+ if (!getInitialized()) {
+ initialize();
+ setInitialized(true);
+ }
+
+ int ch = -1;
+
+ if (spacesRemaining > 0) {
+ spacesRemaining--;
+ ch = ' ';
+ } else {
+ ch = in.read();
+ if (ch == '\t') {
+ spacesRemaining = tabLength - 1;
+ ch = ' ';
+ }
+ }
+ return ch;
+ }
+
+ /**
+ * Sets the tab length.
+ *
+ * @param tabLength the number of spaces to be used when converting a tab.
+ */
+ public void setTablength(final int tabLength) {
+ this.tabLength = tabLength;
+ }
+
+ /**
+ * Returns the tab length.
+ *
+ * @return the number of spaces used when converting a tab
+ */
+ private int getTablength() {
+ return tabLength;
+ }
+
+ /**
+ * Creates a new TabsToSpaces using the passed in
+ * Reader for instantiation.
+ *
+ * @param rdr A Reader object providing the underlying stream.
+ * Must not be <code>null</code>.
+ *
+ * @return a new filter based on this configuration, but filtering
+ * the specified reader
+ */
+ public Reader chain(final Reader rdr) {
+ TabsToSpaces newFilter = new TabsToSpaces(rdr);
+ newFilter.setTablength(getTablength());
+ newFilter.setInitialized(true);
+ return newFilter;
+ }
+
+ /**
+ * Parses the parameters to set the tab length.
+ */
+ private void initialize() {
+ Parameter[] params = getParameters();
+ if (params != null) {
+ for (int i = 0; i < params.length; i++) {
+ if (params[i] != null) {
+ if (TAB_LENGTH_KEY.equals(params[i].getName())) {
+ tabLength = Integer.parseInt(params[i].getValue());
+ break;
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/TailFilter.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/TailFilter.java
new file mode 100644
index 00000000..fcc84d16
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/TailFilter.java
@@ -0,0 +1,243 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.filters;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.util.LinkedList;
+
+import org.apache.tools.ant.types.Parameter;
+import org.apache.tools.ant.util.LineTokenizer;
+
+/**
+ * Reads the last <code>n</code> lines of a stream. (Default is last10 lines.)
+ *
+ * Example:
+ *
+ * <pre>&lt;tailfilter lines=&quot;3&quot;/&gt;</pre>
+ *
+ * Or:
+ *
+ * <pre>&lt;filterreader classname=&quot;org.apache.tools.ant.filters.TailFilter&quot;&gt;
+ * &lt;param name=&quot;lines&quot; value=&quot;3&quot;/&gt;
+ * &lt;/filterreader&gt;</pre>
+ *
+ */
+public final class TailFilter extends BaseParamFilterReader
+ implements ChainableReader {
+ /** Parameter name for the number of lines to be returned. */
+ private static final String LINES_KEY = "lines";
+
+ /** Parameter name for the number of lines to be skipped. */
+ private static final String SKIP_KEY = "skip";
+
+ /** Default number of lines to show */
+ private static final int DEFAULT_NUM_LINES = 10;
+
+ /** Number of lines to be returned in the filtered stream. */
+ private long lines = DEFAULT_NUM_LINES;
+
+ /** Number of lines to be skipped. */
+ private long skip = 0;
+
+ /** Whether or not read-ahead been completed. */
+ private boolean completedReadAhead = false;
+
+ /** A line tokenizer */
+ private LineTokenizer lineTokenizer = null;
+
+ /** the current line from the input stream */
+ private String line = null;
+ /** the position in the current line */
+ private int linePos = 0;
+
+ private LinkedList<String> lineList = new LinkedList<String>();
+
+ /**
+ * Constructor for "dummy" instances.
+ *
+ * @see BaseFilterReader#BaseFilterReader()
+ */
+ public TailFilter() {
+ super();
+ }
+
+ /**
+ * Creates a new filtered reader.
+ *
+ * @param in A Reader object providing the underlying stream.
+ * Must not be <code>null</code>.
+ */
+ public TailFilter(final Reader in) {
+ super(in);
+ lineTokenizer = new LineTokenizer();
+ lineTokenizer.setIncludeDelims(true);
+ }
+
+ /**
+ * Returns the next character in the filtered stream. If the read-ahead
+ * has been completed, the next character in the buffer is returned.
+ * Otherwise, the stream is read to the end and buffered (with the buffer
+ * growing as necessary), then the appropriate position in the buffer is
+ * set to read from.
+ *
+ * @return the next character in the resulting stream, or -1
+ * if the end of the resulting stream has been reached
+ *
+ * @exception IOException if the underlying stream throws an IOException
+ * during reading
+ */
+ public int read() throws IOException {
+ if (!getInitialized()) {
+ initialize();
+ setInitialized(true);
+ }
+
+ while (line == null || line.length() == 0) {
+ line = lineTokenizer.getToken(in);
+ line = tailFilter(line);
+ if (line == null) {
+ return -1;
+ }
+ linePos = 0;
+ }
+
+ int ch = line.charAt(linePos);
+ linePos++;
+ if (linePos == line.length()) {
+ line = null;
+ }
+ return ch;
+ }
+
+ /**
+ * Sets the number of lines to be returned in the filtered stream.
+ *
+ * @param lines the number of lines to be returned in the filtered stream
+ */
+ public void setLines(final long lines) {
+ this.lines = lines;
+ }
+
+ /**
+ * Returns the number of lines to be returned in the filtered stream.
+ *
+ * @return the number of lines to be returned in the filtered stream
+ */
+ private long getLines() {
+ return lines;
+ }
+
+ /**
+ * Sets the number of lines to be skipped in the filtered stream.
+ *
+ * @param skip the number of lines to be skipped in the filtered stream
+ */
+ public void setSkip(final long skip) {
+ this.skip = skip;
+ }
+
+ /**
+ * Returns the number of lines to be skipped in the filtered stream.
+ *
+ * @return the number of lines to be skipped in the filtered stream
+ */
+ private long getSkip() {
+ return skip;
+ }
+
+ /**
+ * Creates a new TailFilter using the passed in
+ * Reader for instantiation.
+ *
+ * @param rdr A Reader object providing the underlying stream.
+ * Must not be <code>null</code>.
+ *
+ * @return a new filter based on this configuration, but filtering
+ * the specified reader
+ */
+ public Reader chain(final Reader rdr) {
+ TailFilter newFilter = new TailFilter(rdr);
+ newFilter.setLines(getLines());
+ newFilter.setSkip(getSkip());
+ newFilter.setInitialized(true);
+ return newFilter;
+ }
+
+ /**
+ * Scans the parameters list for the "lines" parameter and uses
+ * it to set the number of lines to be returned in the filtered stream.
+ * also scan for "skip" parameter.
+ */
+ private void initialize() {
+ Parameter[] params = getParameters();
+ if (params != null) {
+ for (int i = 0; i < params.length; i++) {
+ if (LINES_KEY.equals(params[i].getName())) {
+ setLines(Long.parseLong(params[i].getValue()));
+ continue;
+ }
+ if (SKIP_KEY.equals(params[i].getName())) {
+ skip = Long.parseLong(params[i].getValue());
+ continue;
+ }
+ }
+ }
+ }
+
+ /**
+ * implement a tail filter on a stream of lines.
+ * line = null is the end of the stream.
+ * @return "" while reading in the lines,
+ * line while outputting the lines
+ * null at the end of outputting the lines
+ */
+ private String tailFilter(String line) {
+ if (!completedReadAhead) {
+ if (line != null) {
+ lineList.add(line);
+ if (lines == -1) {
+ if (lineList.size() > skip) {
+ return lineList.removeFirst();
+ }
+ } else {
+ long linesToKeep = lines + (skip > 0 ? skip : 0);
+ if (linesToKeep < lineList.size()) {
+ lineList.removeFirst();
+ }
+ }
+ return "";
+ }
+ completedReadAhead = true;
+ if (skip > 0) {
+ for (int i = 0; i < skip; ++i) {
+ lineList.removeLast();
+ }
+ }
+ if (lines > -1) {
+ while (lineList.size() > lines) {
+ lineList.removeFirst();
+ }
+ }
+ }
+ if (lineList.size() > 0) {
+ return lineList.removeFirst();
+ }
+ return null;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/TokenFilter.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/TokenFilter.java
new file mode 100644
index 00000000..ebad7602
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/TokenFilter.java
@@ -0,0 +1,712 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.filters;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.ProjectComponent;
+import org.apache.tools.ant.types.RegularExpression;
+import org.apache.tools.ant.types.Substitution;
+import org.apache.tools.ant.util.LineTokenizer;
+import org.apache.tools.ant.util.StringUtils;
+import org.apache.tools.ant.util.Tokenizer;
+import org.apache.tools.ant.util.regexp.Regexp;
+import org.apache.tools.ant.util.regexp.RegexpUtil;
+
+/**
+ * This splits up input into tokens and passes
+ * the tokens to a sequence of filters.
+ *
+ * @since Ant 1.6
+ * @see BaseFilterReader
+ * @see ChainableReader
+ * @see org.apache.tools.ant.DynamicConfigurator
+ */
+public class TokenFilter extends BaseFilterReader
+ implements ChainableReader {
+ /**
+ * string filters implement this interface
+ */
+ public interface Filter {
+ /**
+ * filter and/of modify a string
+ *
+ * @param string the string to filter
+ * @return the modified string or null if the
+ * string did not pass the filter
+ */
+ String filter(String string);
+ }
+
+
+ /** string filters */
+ private Vector<Filter> filters = new Vector<Filter>();
+ /** the tokenizer to use on the input stream */
+ private Tokenizer tokenizer = null;
+ /** the output token termination */
+ private String delimOutput = null;
+ /** the current string token from the input stream */
+ private String line = null;
+ /** the position in the current string token */
+ private int linePos = 0;
+
+ /**
+ * Constructor for "dummy" instances.
+ *
+ * @see BaseFilterReader#BaseFilterReader()
+ */
+ public TokenFilter() {
+ super();
+ }
+
+ /**
+ * Creates a new filtered reader.
+ *
+ * @param in A Reader object providing the underlying stream.
+ * Must not be <code>null</code>.
+ */
+ public TokenFilter(final Reader in) {
+ super(in);
+ }
+
+
+ /**
+ * Returns the next character in the filtered stream, only including
+ * lines from the original stream which match all of the specified
+ * regular expressions.
+ *
+ * @return the next character in the resulting stream, or -1
+ * if the end of the resulting stream has been reached
+ *
+ * @exception IOException if the underlying stream throws an IOException
+ * during reading
+ */
+
+ public int read() throws IOException {
+ if (tokenizer == null) {
+ tokenizer = new LineTokenizer();
+ }
+ while (line == null || line.length() == 0) {
+ line = tokenizer.getToken(in);
+ if (line == null) {
+ return -1;
+ }
+ for (Enumeration<Filter> e = filters.elements(); e.hasMoreElements();) {
+ Filter filter = e.nextElement();
+ line = filter.filter(line);
+ if (line == null) {
+ break;
+ }
+ }
+ linePos = 0;
+ if (line != null) {
+ if (tokenizer.getPostToken().length() != 0) {
+ if (delimOutput != null) {
+ line = line + delimOutput;
+ } else {
+ line = line + tokenizer.getPostToken();
+ }
+ }
+ }
+ }
+ int ch = line.charAt(linePos);
+ linePos++;
+ if (linePos == line.length()) {
+ line = null;
+ }
+ return ch;
+ }
+
+ /**
+ * Creates a new TokenFilter using the passed in
+ * Reader for instantiation.
+ *
+ * @param reader A Reader object providing the underlying stream.
+ *
+ * @return a new filter based on this configuration
+ */
+
+ public final Reader chain(final Reader reader) {
+ TokenFilter newFilter = new TokenFilter(reader);
+ newFilter.filters = filters;
+ newFilter.tokenizer = tokenizer;
+ newFilter.delimOutput = delimOutput;
+ newFilter.setProject(getProject());
+ return newFilter;
+ }
+
+ /**
+ * set the output delimiter.
+ * @param delimOutput replaces the delim string returned by the
+ * tokenizer, if present.
+ */
+
+ public void setDelimOutput(String delimOutput) {
+ this.delimOutput = resolveBackSlash(delimOutput);
+ }
+
+ // -----------------------------------------
+ // Predefined tokenizers
+ // -----------------------------------------
+
+ /**
+ * add a line tokenizer - this is the default.
+ * @param tokenizer the line tokenizer
+ */
+
+ public void addLineTokenizer(LineTokenizer tokenizer) {
+ add(tokenizer);
+ }
+
+ /**
+ * add a string tokenizer
+ * @param tokenizer the string tokenizer
+ */
+
+ public void addStringTokenizer(StringTokenizer tokenizer) {
+ add(tokenizer);
+ }
+
+ /**
+ * add a file tokenizer
+ * @param tokenizer the file tokenizer
+ */
+ public void addFileTokenizer(FileTokenizer tokenizer) {
+ add(tokenizer);
+ }
+
+ /**
+ * add an arbitrary tokenizer
+ * @param tokenizer the tokenizer to all, only one allowed
+ */
+
+ public void add(Tokenizer tokenizer) {
+ if (this.tokenizer != null) {
+ throw new BuildException("Only one tokenizer allowed");
+ }
+ this.tokenizer = tokenizer;
+ }
+
+ // -----------------------------------------
+ // Predefined filters
+ // -----------------------------------------
+
+ /**
+ * replace string filter
+ * @param filter the replace string filter
+ */
+ public void addReplaceString(ReplaceString filter) {
+ filters.addElement(filter);
+ }
+
+ /**
+ * contains string filter
+ * @param filter the contains string filter
+ */
+ public void addContainsString(ContainsString filter) {
+ filters.addElement(filter);
+ }
+
+ /**
+ * replace regex filter
+ * @param filter the replace regex filter
+ */
+ public void addReplaceRegex(ReplaceRegex filter) {
+ filters.addElement(filter);
+ }
+
+ /**
+ * contains regex filter
+ * @param filter the contains regex filter
+ */
+ public void addContainsRegex(ContainsRegex filter) {
+ filters.addElement(filter);
+ }
+
+ /**
+ * trim filter
+ * @param filter the trim filter
+ */
+ public void addTrim(Trim filter) {
+ filters.addElement(filter);
+ }
+
+ /**
+ * ignore blank filter
+ * @param filter the ignore blank filter
+ */
+ public void addIgnoreBlank(IgnoreBlank filter) {
+ filters.addElement(filter);
+ }
+
+ /**
+ * delete chars
+ * @param filter the delete characters filter
+ */
+ public void addDeleteCharacters(DeleteCharacters filter) {
+ filters.addElement(filter);
+ }
+
+ /**
+ * Add an arbitrary filter
+ * @param filter the filter to add
+ */
+ public void add(Filter filter) {
+ filters.addElement(filter);
+ }
+
+
+ // --------------------------------------------
+ //
+ // Tokenizer Classes (impls moved to oata.util)
+ //
+ // --------------------------------------------
+
+ /**
+ * class to read the complete input into a string
+ */
+ public static class FileTokenizer
+ extends org.apache.tools.ant.util.FileTokenizer {
+ }
+
+ /**
+ * class to tokenize the input as areas separated
+ * by white space, or by a specified list of
+ * delim characters. Behaves like java.util.StringTokenizer.
+ * if the stream starts with delim characters, the first
+ * token will be an empty string (unless the treat delims
+ * as tokens flag is set).
+ */
+ public static class StringTokenizer
+ extends org.apache.tools.ant.util.StringTokenizer {
+ }
+
+ // --------------------------------------------
+ //
+ // Filter classes
+ //
+ // --------------------------------------------
+
+ /**
+ * Abstract class that converts derived filter classes into
+ * ChainableReaderFilter's
+ */
+ public abstract static class ChainableReaderFilter extends ProjectComponent
+ implements ChainableReader, Filter {
+ private boolean byLine = true;
+
+ /**
+ * set whether to use filetokenizer or line tokenizer
+ * @param byLine if true use a linetokenizer (default) otherwise
+ * use a filetokenizer
+ */
+ public void setByLine(boolean byLine) {
+ this.byLine = byLine;
+ }
+
+ /**
+ * Chain a tokenfilter reader to a reader,
+ *
+ * @param reader the input reader object
+ * @return the chained reader object
+ */
+ public Reader chain(Reader reader) {
+ TokenFilter tokenFilter = new TokenFilter(reader);
+ if (!byLine) {
+ tokenFilter.add(new FileTokenizer());
+ }
+ tokenFilter.add(this);
+ return tokenFilter;
+ }
+ }
+
+ /**
+ * Simple replace string filter.
+ */
+ public static class ReplaceString extends ChainableReaderFilter {
+ private String from;
+ private String to;
+
+ /**
+ * the from attribute
+ *
+ * @param from the string to replace
+ */
+ public void setFrom(String from) {
+ this.from = from;
+ }
+
+ /**
+ * the to attribute
+ *
+ * @param to the string to replace 'from' with
+ */
+ public void setTo(String to) {
+ this.to = to;
+ }
+
+ /**
+ * Filter a string 'line' replacing from with to
+ * (Copy&amp;Paste from the Replace task)
+ * @param line the string to be filtered
+ * @return the filtered line
+ */
+ public String filter(String line) {
+ if (from == null) {
+ throw new BuildException("Missing from in stringreplace");
+ }
+ StringBuffer ret = new StringBuffer();
+ int start = 0;
+ int found = line.indexOf(from);
+ while (found >= 0) {
+ // write everything up to the from
+ if (found > start) {
+ ret.append(line.substring(start, found));
+ }
+
+ // write the replacement to
+ if (to != null) {
+ ret.append(to);
+ }
+
+ // search again
+ start = found + from.length();
+ found = line.indexOf(from, start);
+ }
+
+ // write the remaining characters
+ if (line.length() > start) {
+ ret.append(line.substring(start, line.length()));
+ }
+
+ return ret.toString();
+ }
+ }
+
+ /**
+ * Simple filter to filter lines contains strings
+ */
+ public static class ContainsString extends ProjectComponent
+ implements Filter {
+ private String contains;
+
+ /**
+ * the contains attribute
+ * @param contains the string that the token should contain
+ */
+ public void setContains(String contains) {
+ this.contains = contains;
+ }
+
+ /**
+ * Filter strings that contain the contains attribute
+ *
+ * @param string the string to be filtered
+ * @return null if the string does not contain "contains",
+ * string otherwise
+ */
+ public String filter(String string) {
+ if (contains == null) {
+ throw new BuildException("Missing contains in containsstring");
+ }
+ if (string.indexOf(contains) > -1) {
+ return string;
+ }
+ return null;
+ }
+ }
+
+ /**
+ * filter to replace regex.
+ */
+ public static class ReplaceRegex extends ChainableReaderFilter {
+ private String from;
+ private String to;
+ private RegularExpression regularExpression;
+ private Substitution substitution;
+ private boolean initialized = false;
+ private String flags = "";
+ private int options;
+ private Regexp regexp;
+
+ /**
+ * the from attribute
+ * @param from the regex string
+ */
+ public void setPattern(String from) {
+ this.from = from;
+ }
+ /**
+ * the to attribute
+ * @param to the replacement string
+ */
+ public void setReplace(String to) {
+ this.to = to;
+ }
+
+ /**
+ * @param flags the regex flags
+ */
+ public void setFlags(String flags) {
+ this.flags = flags;
+ }
+
+ private void initialize() {
+ if (initialized) {
+ return;
+ }
+ options = convertRegexOptions(flags);
+ if (from == null) {
+ throw new BuildException("Missing pattern in replaceregex");
+ }
+ regularExpression = new RegularExpression();
+ regularExpression.setPattern(from);
+ regexp = regularExpression.getRegexp(getProject());
+ if (to == null) {
+ to = "";
+ }
+ substitution = new Substitution();
+ substitution.setExpression(to);
+ }
+
+ /**
+ * @param line the string to modify
+ * @return the modified string
+ */
+ public String filter(String line) {
+ initialize();
+
+ if (!regexp.matches(line, options)) {
+ return line;
+ }
+ return regexp.substitute(
+ line, substitution.getExpression(getProject()), options);
+ }
+ }
+
+ /**
+ * filter to filter tokens matching regular expressions.
+ */
+ public static class ContainsRegex extends ChainableReaderFilter {
+ private String from;
+ private String to;
+ private RegularExpression regularExpression;
+ private Substitution substitution;
+ private boolean initialized = false;
+ private String flags = "";
+ private int options;
+ private Regexp regexp;
+
+
+ /**
+ * @param from the regex pattern
+ */
+ public void setPattern(String from) {
+ this.from = from;
+ }
+
+ /**
+ * @param to the replacement string
+ */
+ public void setReplace(String to) {
+ this.to = to;
+ }
+
+ /**
+ * @param flags the regex flags
+ */
+ public void setFlags(String flags) {
+ this.flags = flags;
+ }
+
+ private void initialize() {
+ if (initialized) {
+ return;
+ }
+ options = convertRegexOptions(flags);
+ if (from == null) {
+ throw new BuildException("Missing from in containsregex");
+ }
+ regularExpression = new RegularExpression();
+ regularExpression.setPattern(from);
+ regexp = regularExpression.getRegexp(getProject());
+ if (to == null) {
+ return;
+ }
+ substitution = new Substitution();
+ substitution.setExpression(to);
+ }
+
+ /**
+ * apply regex and substitution on a string
+ * @param string the string to apply filter on
+ * @return the filtered string
+ */
+ public String filter(String string) {
+ initialize();
+ if (!regexp.matches(string, options)) {
+ return null;
+ }
+ if (substitution == null) {
+ return string;
+ }
+ return regexp.substitute(
+ string, substitution.getExpression(getProject()), options);
+ }
+ }
+
+ /** Filter to trim white space */
+ public static class Trim extends ChainableReaderFilter {
+ /**
+ * @param line the string to be trimmed
+ * @return the trimmed string
+ */
+ public String filter(String line) {
+ return line.trim();
+ }
+ }
+
+
+
+ /** Filter remove empty tokens */
+ public static class IgnoreBlank extends ChainableReaderFilter {
+ /**
+ * @param line the line to modify
+ * @return the trimmed line
+ */
+ public String filter(String line) {
+ if (line.trim().length() == 0) {
+ return null;
+ }
+ return line;
+ }
+ }
+
+ /**
+ * Filter to delete characters
+ */
+ public static class DeleteCharacters extends ProjectComponent
+ implements Filter, ChainableReader {
+ // Attributes
+ /** the list of characters to remove from the input */
+ private String deleteChars = "";
+
+ /**
+ * Set the list of characters to delete
+ * @param deleteChars the list of characters
+ */
+ public void setChars(String deleteChars) {
+ this.deleteChars = resolveBackSlash(deleteChars);
+ }
+
+ /**
+ * remove characters from a string
+ * @param string the string to remove the characters from
+ * @return the converted string
+ */
+ public String filter(String string) {
+ StringBuffer output = new StringBuffer(string.length());
+ for (int i = 0; i < string.length(); ++i) {
+ char ch = string.charAt(i);
+ if (!(isDeleteCharacter(ch))) {
+ output.append(ch);
+ }
+ }
+ return output.toString();
+ }
+
+ /**
+ * factory method to provide a reader that removes
+ * the characters from a reader as part of a filter
+ * chain
+ * @param reader the reader object
+ * @return the chained reader object
+ */
+ public Reader chain(Reader reader) {
+ return new BaseFilterReader(reader) {
+ /**
+ * @return the next non delete character
+ */
+ public int read()
+ throws IOException {
+ while (true) {
+ int c = in.read();
+ if (c == -1) {
+ return c;
+ }
+ if (!(isDeleteCharacter((char) c))) {
+ return c;
+ }
+ }
+ }
+ };
+ }
+
+ /**
+ * check if the character c is to be deleted
+ *
+ * @param c char to test
+ * @return true if the supplied char is in the list to be stripped.
+ */
+ private boolean isDeleteCharacter(char c) {
+ for (int d = 0; d < deleteChars.length(); ++d) {
+ if (deleteChars.charAt(d) == c) {
+ return true;
+ }
+ }
+ return false;
+ }
+ }
+
+ // --------------------------------------------------------
+ // static utility methods - could be placed somewhere else
+ // --------------------------------------------------------
+
+ /**
+ * xml does not do "c" like interpretation of strings.
+ * i.e. \n\r\t etc.
+ * this method processes \n, \r, \t, \f, \\
+ * also subs \s with " \n\r\t\f"
+ * a trailing '\' will be ignored
+ *
+ * @param input raw string with possible embedded '\'s
+ * @return converted string
+ */
+ public static String resolveBackSlash(String input) {
+ return StringUtils.resolveBackSlash(input);
+ }
+
+ /**
+ * convert regex option flag characters to regex options
+ * <ul>
+ * <li>g - Regexp.REPLACE_ALL</li>
+ * <li>i - Regexp.MATCH_CASE_INSENSITIVE</li>
+ * <li>m - Regexp.MATCH_MULTILINE</li>
+ * <li>s - Regexp.MATCH_SINGLELINE</li>
+ * </ul>
+ * @param flags the string containing the flags
+ * @return the Regexp option bits
+ */
+ public static int convertRegexOptions(String flags) {
+ return RegexpUtil.asOptions(flags);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/UniqFilter.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/UniqFilter.java
new file mode 100644
index 00000000..e72d5f58
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/UniqFilter.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.filters;
+
+/**
+ * Like the Unix uniq(1) command, only returns tokens that are
+ * different from their ancestor token.
+ *
+ * <p>This filter is probably most useful if used together with a
+ * sortfilter.</p>
+ *
+ * @since Ant 1.8.0
+ */
+public class UniqFilter extends TokenFilter.ChainableReaderFilter {
+
+ private String lastLine = null;
+
+ public String filter(String string) {
+ return lastLine == null || !lastLine.equals(string)
+ ? (lastLine = string) : null;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/util/ChainReaderHelper.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/util/ChainReaderHelper.java
new file mode 100644
index 00000000..f176c331
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/util/ChainReaderHelper.java
@@ -0,0 +1,288 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.filters.util;
+
+import java.io.FilterReader;
+import java.io.IOException;
+import java.io.Reader;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Vector;
+
+import org.apache.tools.ant.AntClassLoader;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.filters.BaseFilterReader;
+import org.apache.tools.ant.filters.ChainableReader;
+import org.apache.tools.ant.types.AntFilterReader;
+import org.apache.tools.ant.types.FilterChain;
+import org.apache.tools.ant.types.Parameter;
+import org.apache.tools.ant.types.Parameterizable;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.util.FileUtils;
+
+/**
+ * Process a FilterReader chain.
+ *
+ */
+public final class ChainReaderHelper {
+
+ // default buffer size
+ private static final int DEFAULT_BUFFER_SIZE = 8192;
+ // CheckStyle:VisibilityModifier OFF - bc
+ /**
+ * The primary reader to which the reader chain is to be attached.
+ */
+ public Reader primaryReader;
+
+ /**
+ * The size of the buffer to be used.
+ */
+ public int bufferSize = DEFAULT_BUFFER_SIZE;
+
+ /**
+ * Chain of filters
+ */
+ public Vector<FilterChain> filterChains = new Vector<FilterChain>();
+
+ /** The Ant project */
+ private Project project = null;
+
+ // CheckStyle:VisibilityModifier ON
+
+ /**
+ * Sets the primary reader
+ * @param rdr the reader object
+ */
+ public void setPrimaryReader(Reader rdr) {
+ primaryReader = rdr;
+ }
+
+ /**
+ * Set the project to work with
+ * @param project the current project
+ */
+ public void setProject(final Project project) {
+ this.project = project;
+ }
+
+ /**
+ * Get the project
+ *
+ * @return the current project
+ */
+ public Project getProject() {
+ return project;
+ }
+
+ /**
+ * Sets the buffer size to be used. Defaults to 8192,
+ * if this method is not invoked.
+ * @param size the buffer size to use
+ */
+ public void setBufferSize(int size) {
+ bufferSize = size;
+ }
+
+ /**
+ * Sets the collection of filter reader sets
+ *
+ * @param fchain the filter chains collection
+ */
+ public void setFilterChains(Vector<FilterChain> fchain) {
+ filterChains = fchain;
+ }
+
+ /**
+ * Assemble the reader
+ * @return the assembled reader
+ * @exception BuildException if an error occurs
+ */
+ public Reader getAssembledReader() throws BuildException {
+ if (primaryReader == null) {
+ throw new BuildException("primaryReader must not be null.");
+ }
+
+ Reader instream = primaryReader;
+ final int filterReadersCount = filterChains.size();
+ final Vector<Object> finalFilters = new Vector<Object>();
+ final ArrayList<AntClassLoader> classLoadersToCleanUp =
+ new ArrayList<AntClassLoader>();
+
+ for (int i = 0; i < filterReadersCount; i++) {
+ final FilterChain filterchain =
+ filterChains.elementAt(i);
+ final Vector<Object> filterReaders = filterchain.getFilterReaders();
+ final int readerCount = filterReaders.size();
+ for (int j = 0; j < readerCount; j++) {
+ finalFilters.addElement(filterReaders.elementAt(j));
+ }
+ }
+
+ final int filtersCount = finalFilters.size();
+
+ if (filtersCount > 0) {
+ boolean success = false;
+ try {
+ for (int i = 0; i < filtersCount; i++) {
+ Object o = finalFilters.elementAt(i);
+
+ if (o instanceof AntFilterReader) {
+ instream =
+ expandReader((AntFilterReader) finalFilters.elementAt(i),
+ instream, classLoadersToCleanUp);
+ } else if (o instanceof ChainableReader) {
+ setProjectOnObject(o);
+ instream = ((ChainableReader) o).chain(instream);
+ setProjectOnObject(instream);
+ }
+ }
+ success = true;
+ } finally {
+ if (!success && classLoadersToCleanUp.size() > 0) {
+ cleanUpClassLoaders(classLoadersToCleanUp);
+ }
+ }
+ }
+ final Reader finalReader = instream;
+ return classLoadersToCleanUp.size() == 0 ? finalReader
+ : new FilterReader(finalReader) {
+ public void close() throws IOException {
+ FileUtils.close(in);
+ cleanUpClassLoaders(classLoadersToCleanUp);
+ }
+ protected void finalize() throws Throwable {
+ try {
+ close();
+ } finally {
+ super.finalize();
+ }
+ }
+ };
+ }
+
+ /**
+ * helper method to set the project on an object.
+ * the reflection setProject does not work for anonymous/protected/private
+ * classes, even if they have public methods.
+ */
+ private void setProjectOnObject(Object obj) {
+ if (project == null) {
+ return;
+ }
+ if (obj instanceof BaseFilterReader) {
+ ((BaseFilterReader) obj).setProject(project);
+ return;
+ }
+ project.setProjectReference(obj);
+ }
+
+ /**
+ * Deregisters Classloaders from the project so GC can remove them later.
+ */
+ private static void cleanUpClassLoaders(List<AntClassLoader> loaders) {
+ for (Iterator<AntClassLoader> it = loaders.iterator(); it.hasNext();) {
+ it.next().cleanup();
+ }
+ }
+
+ /**
+ * Read data from the reader and return the
+ * contents as a string.
+ * @param rdr the reader object
+ * @return the contents of the file as a string
+ * @exception IOException if an error occurs
+ */
+ public String readFully(Reader rdr)
+ throws IOException {
+ return FileUtils.readFully(rdr, bufferSize);
+ }
+
+ /**
+ * Creates and parameterizes a new FilterReader from a
+ * &lt;filterreader&gt; element.
+ *
+ * @since Ant 1.8.0
+ */
+ private Reader expandReader(final AntFilterReader filter,
+ final Reader ancestor,
+ final List<AntClassLoader> classLoadersToCleanUp) {
+ final String className = filter.getClassName();
+ final Path classpath = filter.getClasspath();
+ final Project pro = filter.getProject();
+ if (className != null) {
+ try {
+ Class<?> clazz = null;
+ if (classpath == null) {
+ clazz = Class.forName(className);
+ } else {
+ AntClassLoader al = pro.createClassLoader(classpath);
+ classLoadersToCleanUp.add(al);
+ clazz = Class.forName(className, true, al);
+ }
+ if (clazz != null) {
+ if (!FilterReader.class.isAssignableFrom(clazz)) {
+ throw new BuildException(className + " does not extend"
+ + " java.io.FilterReader");
+ }
+ final Constructor<?>[] constructors = clazz.getConstructors();
+ int j = 0;
+ boolean consPresent = false;
+ for (; j < constructors.length; j++) {
+ Class<?>[] types = constructors[j].getParameterTypes();
+ if (types.length == 1
+ && types[0].isAssignableFrom(Reader.class)) {
+ consPresent = true;
+ break;
+ }
+ }
+ if (!consPresent) {
+ throw new BuildException(className + " does not define"
+ + " a public constructor"
+ + " that takes in a Reader"
+ + " as its single argument.");
+ }
+ final Reader[] rdr = {ancestor};
+ Reader instream =
+ (Reader) constructors[j].newInstance((Object[]) rdr);
+ setProjectOnObject(instream);
+ if (Parameterizable.class.isAssignableFrom(clazz)) {
+ final Parameter[] params = filter.getParams();
+ ((Parameterizable) instream).setParameters(params);
+ }
+ return instream;
+ }
+ } catch (final ClassNotFoundException cnfe) {
+ throw new BuildException(cnfe);
+ } catch (final InstantiationException ie) {
+ throw new BuildException(ie);
+ } catch (final IllegalAccessException iae) {
+ throw new BuildException(iae);
+ } catch (final InvocationTargetException ite) {
+ throw new BuildException(ite);
+ }
+ }
+ // Ant 1.7.1 and earlier ignore <filterreader> without a
+ // classname attribute, not sure this is a good idea -
+ // backwards compatibility makes it hard to change, though.
+ return ancestor;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/util/JavaClassHelper.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/util/JavaClassHelper.java
new file mode 100644
index 00000000..b0c67ce2
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/filters/util/JavaClassHelper.java
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.filters.util;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+
+import org.apache.bcel.classfile.ClassParser;
+import org.apache.bcel.classfile.ConstantValue;
+import org.apache.bcel.classfile.Field;
+import org.apache.bcel.classfile.JavaClass;
+
+// CheckStyle:HideUtilityClassConstructorCheck OFF - bc
+/**
+ * Helper class that filters constants from a Java Class
+ *
+ */
+public final class JavaClassHelper {
+ /** System specific line separator. */
+ private static final String LS = System.getProperty("line.separator");
+
+ /**
+ * Get the constants declared in a file as name=value
+ *
+ * @param bytes the class as a array of bytes
+ * @return a StringBuffer contains the name=value pairs
+ * @exception IOException if an error occurs
+ */
+ public static StringBuffer getConstants(final byte[] bytes)
+ throws IOException {
+ final StringBuffer sb = new StringBuffer();
+ final ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
+ final ClassParser parser = new ClassParser(bis, "");
+ final JavaClass javaClass = parser.parse();
+ final Field[] fields = javaClass.getFields();
+ for (int i = 0; i < fields.length; i++) {
+ final Field field = fields[i];
+ if (field != null) {
+ final ConstantValue cv = field.getConstantValue();
+ if (cv != null) {
+ String cvs = cv.toString();
+ //Remove start and end quotes if field is a String
+ if (cvs.startsWith("\"") && cvs.endsWith("\"")) {
+ cvs = cvs.substring(1, cvs.length() - 1);
+ }
+ sb.append(field.getName());
+ sb.append('=');
+ sb.append(cvs);
+ sb.append(LS);
+ }
+ }
+ }
+ return sb;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/helper/AntXMLContext.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/helper/AntXMLContext.java
new file mode 100644
index 00000000..99e3d1a1
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/helper/AntXMLContext.java
@@ -0,0 +1,417 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.helper;
+
+import java.io.File;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Location;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.RuntimeConfigurable;
+import org.apache.tools.ant.Target;
+import org.apache.tools.ant.util.FileUtils;
+import org.xml.sax.Attributes;
+import org.xml.sax.Locator;
+
+/**
+ * Context information for the ant processing.
+ *
+ */
+public class AntXMLContext {
+ /** The project to configure. */
+ private Project project;
+
+ /** The configuration file to parse. */
+ private File buildFile;
+
+ /** The configuration file to parse. */
+ private URL buildFileURL;
+
+ /** Vector with all the targets, in the order they are
+ * defined. Project maintains a Hashtable, which is not ordered.
+ * This will allow description to know the original order.
+ */
+ private Vector<Target> targetVector = new Vector<Target>();
+
+ /**
+ * Parent directory of the build file. Used for resolving entities
+ * and setting the project's base directory.
+ */
+ private File buildFileParent;
+
+ /**
+ * Parent directory of the build file. Used for resolving entities
+ * and setting the project's base directory.
+ */
+ private URL buildFileParentURL;
+
+ /** Name of the current project */
+ private String currentProjectName;
+
+ /**
+ * Locator for the configuration file parser.
+ * Used for giving locations of errors etc.
+ */
+ private Locator locator;
+
+ /**
+ * Target that all other targets will depend upon implicitly.
+ *
+ * <p>This holds all tasks and data type definitions that have
+ * been placed outside of targets.</p>
+ */
+ private Target implicitTarget = new Target();
+
+ /** Current target ( no need for a stack as the processing model
+ allows only one level of target ) */
+ private Target currentTarget = null;
+
+ /** The stack of RuntimeConfigurable2 wrapping the
+ objects.
+ */
+ private Vector<RuntimeConfigurable> wStack = new Vector<RuntimeConfigurable>();
+
+ /**
+ * Indicates whether the project tag attributes are to be ignored
+ * when processing a particular build file.
+ */
+ private boolean ignoreProjectTag = false;
+
+ /** Keeps track of prefix -> uri mapping during parsing */
+ private Map<String, List<String>> prefixMapping = new HashMap<String, List<String>>();
+
+
+ /** Keeps track of targets in files */
+ private Map<String, Target> currentTargets = null;
+
+ /**
+ * constructor
+ * @param project the project to which this antxml context belongs to
+ */
+ public AntXMLContext(Project project) {
+ this.project = project;
+ implicitTarget.setProject(project);
+ implicitTarget.setName("");
+ targetVector.addElement(implicitTarget);
+ }
+
+ /**
+ * sets the build file to which the XML context belongs
+ * @param buildFile ant build file
+ */
+ public void setBuildFile(File buildFile) {
+ this.buildFile = buildFile;
+ if (buildFile != null) {
+ this.buildFileParent = new File(buildFile.getParent());
+ implicitTarget.setLocation(new Location(buildFile.getAbsolutePath()));
+ try {
+ setBuildFile(FileUtils.getFileUtils().getFileURL(buildFile));
+ } catch (MalformedURLException ex) {
+ throw new BuildException(ex);
+ }
+ } else {
+ this.buildFileParent = null;
+ }
+ }
+
+ /**
+ * sets the build file to which the XML context belongs
+ * @param buildFile ant build file
+ * @since Ant 1.8.0
+ */
+ public void setBuildFile(URL buildFile) throws MalformedURLException {
+ this.buildFileURL = buildFile;
+ this.buildFileParentURL = new URL(buildFile, ".");
+ if (implicitTarget.getLocation() == null) {
+ implicitTarget.setLocation(new Location(buildFile.toString()));
+ }
+ }
+
+ /**
+ * find out the build file
+ * @return the build file to which the xml context belongs
+ */
+ public File getBuildFile() {
+ return buildFile;
+ }
+
+ /**
+ * find out the parent build file of this build file
+ * @return the parent build file of this build file
+ */
+ public File getBuildFileParent() {
+ return buildFileParent;
+ }
+
+ /**
+ * find out the build file
+ * @return the build file to which the xml context belongs
+ * @since Ant 1.8.0
+ */
+ public URL getBuildFileURL() {
+ return buildFileURL;
+ }
+
+ /**
+ * find out the parent build file of this build file
+ * @return the parent build file of this build file
+ * @since Ant 1.8.0
+ */
+ public URL getBuildFileParentURL() {
+ return buildFileParentURL;
+ }
+
+ /**
+ * find out the project to which this antxml context belongs
+ * @return project
+ */
+ public Project getProject() {
+ return project;
+ }
+
+ /**
+ * find out the current project name
+ * @return current project name
+ */
+ public String getCurrentProjectName() {
+ return currentProjectName;
+ }
+
+ /**
+ * set the name of the current project
+ * @param name name of the current project
+ */
+ public void setCurrentProjectName(String name) {
+ this.currentProjectName = name;
+ }
+
+ /**
+ * get the current runtime configurable wrapper
+ * can return null
+ * @return runtime configurable wrapper
+ */
+ public RuntimeConfigurable currentWrapper() {
+ if (wStack.size() < 1) {
+ return null;
+ }
+ return (RuntimeConfigurable) wStack.elementAt(wStack.size() - 1);
+ }
+
+ /**
+ * get the runtime configurable wrapper of the parent project
+ * can return null
+ * @return runtime configurable wrapper of the parent project
+ */
+ public RuntimeConfigurable parentWrapper() {
+ if (wStack.size() < 2) {
+ return null;
+ }
+ return (RuntimeConfigurable) wStack.elementAt(wStack.size() - 2);
+ }
+
+ /**
+ * add a runtime configurable wrapper to the internal stack
+ * @param wrapper runtime configurable wrapper
+ */
+ public void pushWrapper(RuntimeConfigurable wrapper) {
+ wStack.addElement(wrapper);
+ }
+
+ /**
+ * remove a runtime configurable wrapper from the stack
+ */
+ public void popWrapper() {
+ if (wStack.size() > 0) {
+ wStack.removeElementAt(wStack.size() - 1);
+ }
+ }
+
+ /**
+ * access the stack of wrappers
+ * @return the stack of wrappers
+ */
+ public Vector<RuntimeConfigurable> getWrapperStack() {
+ return wStack;
+ }
+
+ /**
+ * add a new target
+ * @param target target to add
+ */
+ public void addTarget(Target target) {
+ targetVector.addElement(target);
+ currentTarget = target;
+ }
+
+ /**
+ * get the current target
+ * @return current target
+ */
+ public Target getCurrentTarget() {
+ return currentTarget;
+ }
+
+ /**
+ * get the implicit target
+ * @return implicit target
+ */
+ public Target getImplicitTarget() {
+ return implicitTarget;
+ }
+
+ /**
+ * sets the current target
+ * @param target current target
+ */
+ public void setCurrentTarget(Target target) {
+ this.currentTarget = target;
+ }
+
+ /**
+ * sets the implicit target
+ * @param target the implicit target
+ */
+ public void setImplicitTarget(Target target) {
+ this.implicitTarget = target;
+ }
+
+ /**
+ * access the vector of targets
+ * @return vector of targets
+ */
+ public Vector<Target> getTargets() {
+ return targetVector;
+ }
+
+ /**
+ * Scans an attribute list for the <code>id</code> attribute and
+ * stores a reference to the target object in the project if an
+ * id is found.
+ * <p>
+ * This method was moved out of the configure method to allow
+ * it to be executed at parse time.
+ * @param element the current element
+ * @param attr attributes of the current element
+ */
+ public void configureId(Object element, Attributes attr) {
+ String id = attr.getValue("id");
+ if (id != null) {
+ project.addIdReference(id, element);
+ }
+ }
+
+ /**
+ * access the locator
+ * @return locator
+ */
+ public Locator getLocator() {
+ return locator;
+ }
+
+ /**
+ * sets the locator
+ * @param locator locator
+ */
+ public void setLocator(Locator locator) {
+ this.locator = locator;
+ }
+
+ /**
+ * tells whether the project tag is being ignored
+ * @return whether the project tag is being ignored
+ */
+ public boolean isIgnoringProjectTag() {
+ return ignoreProjectTag;
+ }
+
+ /**
+ * sets the flag to ignore the project tag
+ * @param flag to ignore the project tag
+ */
+ public void setIgnoreProjectTag(boolean flag) {
+ this.ignoreProjectTag = flag;
+ }
+
+ /**
+ * Called during parsing, stores the prefix to uri mapping.
+ *
+ * @param prefix a namespace prefix
+ * @param uri a namespace uri
+ */
+ public void startPrefixMapping(String prefix, String uri) {
+ List<String> list = prefixMapping.get(prefix);
+ if (list == null) {
+ list = new ArrayList<String>();
+ prefixMapping.put(prefix, list);
+ }
+ list.add(uri);
+ }
+
+ /**
+ * End of prefix to uri mapping.
+ *
+ * @param prefix the namespace prefix
+ */
+ public void endPrefixMapping(String prefix) {
+ List<String> list = prefixMapping.get(prefix);
+ if (list == null || list.size() == 0) {
+ return; // Should not happen
+ }
+ list.remove(list.size() - 1);
+ }
+
+ /**
+ * prefix to namespace uri mapping
+ *
+ * @param prefix the prefix to map
+ * @return the uri for this prefix, null if not present
+ */
+ public String getPrefixMapping(String prefix) {
+ List<String> list = prefixMapping.get(prefix);
+ if (list == null || list.size() == 0) {
+ return null;
+ }
+ return (String) list.get(list.size() - 1);
+ }
+
+ /**
+ * Get the targets in the current source file.
+ * @return the current targets.
+ */
+ public Map<String, Target> getCurrentTargets() {
+ return currentTargets;
+ }
+
+ /**
+ * Set the map of the targets in the current source file.
+ * @param currentTargets a map of targets.
+ */
+ public void setCurrentTargets(Map<String, Target> currentTargets) {
+ this.currentTargets = currentTargets;
+ }
+
+}
+
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/helper/DefaultExecutor.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/helper/DefaultExecutor.java
new file mode 100644
index 00000000..cdbc587c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/helper/DefaultExecutor.java
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.helper;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Executor;
+import org.apache.tools.ant.Project;
+
+/**
+ * Default Target executor implementation. Runs each target individually
+ * (including all of its dependencies). If an error occurs, behavior is
+ * determined by the Project's "keep-going" mode.
+ * @since Ant 1.6.3
+ */
+public class DefaultExecutor implements Executor {
+
+ private static final SingleCheckExecutor SUB_EXECUTOR = new SingleCheckExecutor();
+
+ /** {@inheritDoc}. */
+ public void executeTargets(Project project, String[] targetNames)
+ throws BuildException {
+ BuildException thrownException = null;
+ for (int i = 0; i < targetNames.length; i++) {
+ try {
+ project.executeTarget(targetNames[i]);
+ } catch (BuildException ex) {
+ if (project.isKeepGoingMode()) {
+ thrownException = ex;
+ } else {
+ throw ex;
+ }
+ }
+ }
+ if (thrownException != null) {
+ throw thrownException;
+ }
+ }
+
+ /** {@inheritDoc}. */
+ public Executor getSubProjectExecutor() {
+ return SUB_EXECUTOR;
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/helper/IgnoreDependenciesExecutor.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/helper/IgnoreDependenciesExecutor.java
new file mode 100644
index 00000000..da85dba7
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/helper/IgnoreDependenciesExecutor.java
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.helper;
+
+import java.util.Hashtable;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Executor;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Target;
+
+/**
+ * Target executor implementation that ignores dependencies. Runs each
+ * target by calling <code>target.performTasks()</code> directly. If an
+ * error occurs, behavior is determined by the Project's "keep-going" mode.
+ * To be used when you know what you're doing.
+ *
+ * @since Ant 1.7.1
+ */
+public class IgnoreDependenciesExecutor implements Executor {
+
+ private static final SingleCheckExecutor SUB_EXECUTOR = new SingleCheckExecutor();
+
+ /** {@inheritDoc}. */
+ public void executeTargets(Project project, String[] targetNames)
+ throws BuildException {
+ Hashtable<String, Target> targets = project.getTargets();
+ BuildException thrownException = null;
+ for (int i = 0; i < targetNames.length; i++) {
+ try {
+ Target t = targets.get(targetNames[i]);
+ if (t == null) {
+ throw new BuildException("Unknown target " + targetNames[i]);
+ }
+ t.performTasks();
+ } catch (BuildException ex) {
+ if (project.isKeepGoingMode()) {
+ thrownException = ex;
+ } else {
+ throw ex;
+ }
+ }
+ }
+ if (thrownException != null) {
+ throw thrownException;
+ }
+ }
+
+ /** {@inheritDoc}. */
+ public Executor getSubProjectExecutor() {
+ return SUB_EXECUTOR;
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/helper/ProjectHelper2.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/helper/ProjectHelper2.java
new file mode 100644
index 00000000..67e1decb
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/helper/ProjectHelper2.java
@@ -0,0 +1,1238 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.helper;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Map;
+import java.util.Stack;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.ExtensionPoint;
+import org.apache.tools.ant.Location;
+import org.apache.tools.ant.MagicNames;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.ProjectHelper;
+import org.apache.tools.ant.RuntimeConfigurable;
+import org.apache.tools.ant.Target;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.UnknownElement;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.resources.FileProvider;
+import org.apache.tools.ant.types.resources.URLProvider;
+import org.apache.tools.ant.util.FileUtils;
+import org.apache.tools.ant.util.JAXPUtils;
+import org.apache.tools.zip.ZipFile;
+import org.xml.sax.Attributes;
+import org.xml.sax.InputSource;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+import org.xml.sax.XMLReader;
+import org.xml.sax.helpers.DefaultHandler;
+
+/**
+ * Sax2 based project reader
+ *
+ */
+public class ProjectHelper2 extends ProjectHelper {
+
+ /** Reference holding the (ordered) target Vector */
+ public static final String REFID_TARGETS = "ant.targets";
+
+ /* Stateless */
+
+ // singletons - since all state is in the context
+ private static AntHandler elementHandler = new ElementHandler();
+ private static AntHandler targetHandler = new TargetHandler();
+ private static AntHandler mainHandler = new MainHandler();
+ private static AntHandler projectHandler = new ProjectHandler();
+
+ /** Specific to ProjectHelper2 so not a true Ant "magic name:" */
+ private static final String REFID_CONTEXT = "ant.parsing.context";
+
+ /**
+ * helper for path -> URI and URI -> path conversions.
+ */
+ private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+
+ /**
+ * Whether this instance of ProjectHelper can parse an Antlib
+ * descriptor given by the URL and return its content as an
+ * UnknownElement ready to be turned into an Antlib task.
+ *
+ * <p>This implementation returns true.</p>
+ *
+ * @since Ant 1.8.0
+ */
+ public boolean canParseAntlibDescriptor(Resource resource) {
+ return true;
+ }
+
+ /**
+ * Parse the given URL as an antlib descriptor and return the
+ * content as something that can be turned into an Antlib task.
+ *
+ * <p>simply delegates to {@link #parseUnknownElement
+ * parseUnknownElement} if the resource provides an URL and throws
+ * an exception otherwise.</p>
+ *
+ * @since Ant 1.8.0
+ */
+ public UnknownElement parseAntlibDescriptor(Project containingProject,
+ Resource resource) {
+ URLProvider up = resource.as(URLProvider.class);
+ if (up == null) {
+ throw new BuildException("Unsupported resource type: " + resource);
+ }
+ return parseUnknownElement(containingProject, up.getURL());
+ }
+
+ /**
+ * Parse an unknown element from a url
+ *
+ * @param project the current project
+ * @param source the url containing the task
+ * @return a configured task
+ * @exception BuildException if an error occurs
+ */
+ public UnknownElement parseUnknownElement(Project project, URL source)
+ throws BuildException {
+ Target dummyTarget = new Target();
+ dummyTarget.setProject(project);
+
+ AntXMLContext context = new AntXMLContext(project);
+ context.addTarget(dummyTarget);
+ context.setImplicitTarget(dummyTarget);
+
+ parse(context.getProject(), source, new RootHandler(context, elementHandler));
+ Task[] tasks = dummyTarget.getTasks();
+ if (tasks.length != 1) {
+ throw new BuildException("No tasks defined");
+ }
+ return (UnknownElement) tasks[0];
+ }
+
+ /**
+ * Parse a source xml input.
+ *
+ * @param project the current project
+ * @param source the xml source
+ * @exception BuildException if an error occurs
+ */
+ public void parse(Project project, Object source) throws BuildException {
+ getImportStack().addElement(source);
+ AntXMLContext context = null;
+ context = (AntXMLContext) project.getReference(REFID_CONTEXT);
+ if (context == null) {
+ context = new AntXMLContext(project);
+ project.addReference(REFID_CONTEXT, context);
+ project.addReference(REFID_TARGETS, context.getTargets());
+ }
+ if (getImportStack().size() > 1) {
+ // we are in an imported file.
+ context.setIgnoreProjectTag(true);
+ Target currentTarget = context.getCurrentTarget();
+ Target currentImplicit = context.getImplicitTarget();
+ Map<String, Target> currentTargets = context.getCurrentTargets();
+ try {
+ Target newCurrent = new Target();
+ newCurrent.setProject(project);
+ newCurrent.setName("");
+ context.setCurrentTarget(newCurrent);
+ context.setCurrentTargets(new HashMap<String, Target>());
+ context.setImplicitTarget(newCurrent);
+ parse(project, source, new RootHandler(context, mainHandler));
+ newCurrent.execute();
+ } finally {
+ context.setCurrentTarget(currentTarget);
+ context.setImplicitTarget(currentImplicit);
+ context.setCurrentTargets(currentTargets);
+ }
+ } else {
+ // top level file
+ context.setCurrentTargets(new HashMap<String, Target>());
+ parse(project, source, new RootHandler(context, mainHandler));
+ // Execute the top-level target
+ context.getImplicitTarget().execute();
+
+ // resolve extensionOf attributes
+ resolveExtensionOfAttributes(project);
+ }
+ }
+
+ /**
+ * Parses the project file, configuring the project as it goes.
+ *
+ * @param project the current project
+ * @param source the xml source
+ * @param handler the root handler to use (contains the current context)
+ * @exception BuildException if the configuration is invalid or cannot
+ * be read
+ */
+ public void parse(Project project, Object source, RootHandler handler) throws BuildException {
+
+ AntXMLContext context = handler.context;
+
+ File buildFile = null;
+ URL url = null;
+ String buildFileName = null;
+
+ if (source instanceof File) {
+ buildFile = (File) source;
+ } else if (source instanceof URL) {
+ url = (URL) source;
+ } else if (source instanceof Resource) {
+ FileProvider fp =
+ ((Resource) source).as(FileProvider.class);
+ if (fp != null) {
+ buildFile = fp.getFile();
+ } else {
+ URLProvider up =
+ ((Resource) source).as(URLProvider.class);
+ if (up != null) {
+ url = up.getURL();
+ }
+ }
+ }
+ if (buildFile != null) {
+ buildFile = FILE_UTILS.normalize(buildFile.getAbsolutePath());
+ context.setBuildFile(buildFile);
+ buildFileName = buildFile.toString();
+ } else if (url != null) {
+ try {
+ context.setBuildFile((File) null);
+ context.setBuildFile(url);
+ } catch (java.net.MalformedURLException ex) {
+ throw new BuildException(ex);
+ }
+ buildFileName = url.toString();
+ } else {
+ throw new BuildException("Source " + source.getClass().getName()
+ + " not supported by this plugin");
+ }
+ InputStream inputStream = null;
+ InputSource inputSource = null;
+ ZipFile zf = null;
+
+ try {
+ /**
+ * SAX 2 style parser used to parse the given file.
+ */
+ XMLReader parser = JAXPUtils.getNamespaceXMLReader();
+
+ String uri = null;
+ if (buildFile != null) {
+ uri = FILE_UTILS.toURI(buildFile.getAbsolutePath());
+ inputStream = new FileInputStream(buildFile);
+ } else {
+ uri = url.toString();
+ int pling = -1;
+ if (uri.startsWith("jar:file")
+ && (pling = uri.indexOf("!/")) > -1) {
+ zf = new ZipFile(org.apache.tools.ant.launch.Locator
+ .fromJarURI(uri), "UTF-8");
+ inputStream =
+ zf.getInputStream(zf.getEntry(uri.substring(pling + 1)));
+ } else {
+ URLConnection conn = url.openConnection();
+ conn.setUseCaches(false);
+ inputStream = conn.getInputStream();
+ }
+ }
+
+ inputSource = new InputSource(inputStream);
+ if (uri != null) {
+ inputSource.setSystemId(uri);
+ }
+ project.log("parsing buildfile " + buildFileName + " with URI = "
+ + uri + (zf != null ? " from a zip file" : ""),
+ Project.MSG_VERBOSE);
+
+ DefaultHandler hb = handler;
+
+ parser.setContentHandler(hb);
+ parser.setEntityResolver(hb);
+ parser.setErrorHandler(hb);
+ parser.setDTDHandler(hb);
+ parser.parse(inputSource);
+ } catch (SAXParseException exc) {
+ Location location = new Location(exc.getSystemId(), exc.getLineNumber(), exc
+ .getColumnNumber());
+
+ Throwable t = exc.getException();
+ if (t instanceof BuildException) {
+ BuildException be = (BuildException) t;
+ if (be.getLocation() == Location.UNKNOWN_LOCATION) {
+ be.setLocation(location);
+ }
+ throw be;
+ }
+ throw new BuildException(exc.getMessage(), t == null ? exc : t, location);
+ } catch (SAXException exc) {
+ Throwable t = exc.getException();
+ if (t instanceof BuildException) {
+ throw (BuildException) t;
+ }
+ throw new BuildException(exc.getMessage(), t == null ? exc : t);
+ } catch (FileNotFoundException exc) {
+ throw new BuildException(exc);
+ } catch (UnsupportedEncodingException exc) {
+ throw new BuildException("Encoding of project file " + buildFileName + " is invalid.",
+ exc);
+ } catch (IOException exc) {
+ throw new BuildException("Error reading project file " + buildFileName + ": "
+ + exc.getMessage(), exc);
+ } finally {
+ FileUtils.close(inputStream);
+ ZipFile.closeQuietly(zf);
+ }
+ }
+
+ /**
+ * Returns main handler
+ * @return main handler
+ */
+ protected static AntHandler getMainHandler() {
+ return mainHandler;
+ }
+
+ /**
+ * Sets main handler
+ * @param handler new main handler
+ */
+ protected static void setMainHandler(AntHandler handler) {
+ mainHandler = handler;
+ }
+
+ /**
+ * Returns project handler
+ * @return project handler
+ */
+ protected static AntHandler getProjectHandler() {
+ return projectHandler;
+ }
+
+ /**
+ * Sets project handler
+ * @param handler new project handler
+ */
+ protected static void setProjectHandler(AntHandler handler) {
+ projectHandler = handler;
+ }
+
+ /**
+ * Returns target handler
+ * @return target handler
+ */
+ protected static AntHandler getTargetHandler() {
+ return targetHandler;
+ }
+
+ /**
+ * Sets target handler
+ * @param handler new target handler
+ */
+ protected static void setTargetHandler(AntHandler handler) {
+ targetHandler = handler;
+ }
+
+ /**
+ * Returns element handler
+ * @return element handler
+ */
+ protected static AntHandler getElementHandler() {
+ return elementHandler;
+ }
+
+ /**
+ * Sets element handler
+ * @param handler new element handler
+ */
+ protected static void setElementHandler(AntHandler handler) {
+ elementHandler = handler;
+ }
+
+ /**
+ * The common superclass for all SAX event handlers used to parse
+ * the configuration file.
+ *
+ * The context will hold all state information. At each time
+ * there is one active handler for the current element. It can
+ * use onStartChild() to set an alternate handler for the child.
+ */
+ public static class AntHandler {
+ /**
+ * Handles the start of an element. This base implementation does
+ * nothing.
+ *
+ * @param uri the namespace URI for the tag
+ * @param tag The name of the element being started.
+ * Will not be <code>null</code>.
+ * @param qname The qualified name of the element.
+ * @param attrs Attributes of the element being started.
+ * Will not be <code>null</code>.
+ * @param context The context that this element is in.
+ *
+ * @exception SAXParseException if this method is not overridden, or in
+ * case of error in an overridden version
+ */
+ public void onStartElement(String uri, String tag, String qname, Attributes attrs,
+ AntXMLContext context) throws SAXParseException {
+ }
+
+ /**
+ * Handles the start of an element. This base implementation just
+ * throws an exception - you must override this method if you expect
+ * child elements.
+ *
+ * @param uri The namespace uri for this element.
+ * @param tag The name of the element being started.
+ * Will not be <code>null</code>.
+ * @param qname The qualified name for this element.
+ * @param attrs Attributes of the element being started.
+ * Will not be <code>null</code>.
+ * @param context The current context.
+ * @return a handler (in the derived classes)
+ *
+ * @exception SAXParseException if this method is not overridden, or in
+ * case of error in an overridden version
+ */
+ public AntHandler onStartChild(String uri, String tag, String qname, Attributes attrs,
+ AntXMLContext context) throws SAXParseException {
+ throw new SAXParseException("Unexpected element \"" + qname + " \"", context
+ .getLocator());
+ }
+
+ /**
+ * Handle the end of a element.
+ *
+ * @param uri the namespace uri of the element
+ * @param tag the tag of the element
+ * @param qname the qualified name of the element
+ * @param context the current context
+ * @exception SAXParseException if an error occurs
+ */
+ public void onEndChild(String uri, String tag, String qname, AntXMLContext context)
+ throws SAXParseException {
+ }
+
+ /**
+ * This method is called when this element and all elements nested into it have been
+ * handled. I.e., this happens at the &lt;/end_tag_of_the_element&gt;.
+ * @param uri the namespace uri for this element
+ * @param tag the element name
+ * @param context the current context
+ */
+ public void onEndElement(String uri, String tag, AntXMLContext context) {
+ }
+
+ /**
+ * Handles text within an element. This base implementation just
+ * throws an exception, you must override it if you expect content.
+ *
+ * @param buf A character array of the text within the element.
+ * Will not be <code>null</code>.
+ * @param start The start element in the array.
+ * @param count The number of characters to read from the array.
+ * @param context The current context.
+ *
+ * @exception SAXParseException if this method is not overridden, or in
+ * case of error in an overridden version
+ */
+ public void characters(char[] buf, int start, int count, AntXMLContext context)
+ throws SAXParseException {
+ String s = new String(buf, start, count).trim();
+
+ if (s.length() > 0) {
+ throw new SAXParseException("Unexpected text \"" + s + "\"", context.getLocator());
+ }
+ }
+
+ /**
+ * Will be called every time a namespace is reached.
+ * It'll verify if the ns was processed, and if not load the task definitions.
+ * @param uri The namespace uri.
+ */
+ protected void checkNamespace(String uri) {
+ }
+ }
+
+ /**
+ * Handler for ant processing. Uses a stack of AntHandlers to
+ * implement each element ( the original parser used a recursive behavior,
+ * with the implicit execution stack )
+ */
+ public static class RootHandler extends DefaultHandler {
+ private Stack<AntHandler> antHandlers = new Stack<AntHandler>();
+ private AntHandler currentHandler = null;
+ private AntXMLContext context;
+
+ /**
+ * Creates a new RootHandler instance.
+ *
+ * @param context The context for the handler.
+ * @param rootHandler The handler for the root element.
+ */
+ public RootHandler(AntXMLContext context, AntHandler rootHandler) {
+ currentHandler = rootHandler;
+ antHandlers.push(currentHandler);
+ this.context = context;
+ }
+
+ /**
+ * Returns the current ant handler object.
+ * @return the current ant handler.
+ */
+ public AntHandler getCurrentAntHandler() {
+ return currentHandler;
+ }
+
+ /**
+ * Resolves file: URIs relative to the build file.
+ *
+ * @param publicId The public identifier, or <code>null</code>
+ * if none is available. Ignored in this
+ * implementation.
+ * @param systemId The system identifier provided in the XML
+ * document. Will not be <code>null</code>.
+ * @return an inputsource for this identifier
+ */
+ public InputSource resolveEntity(String publicId, String systemId) {
+
+ context.getProject().log("resolving systemId: " + systemId, Project.MSG_VERBOSE);
+
+ if (systemId.startsWith("file:")) {
+ String path = FILE_UTILS.fromURI(systemId);
+
+ File file = new File(path);
+ if (!file.isAbsolute()) {
+ file = FILE_UTILS.resolveFile(context.getBuildFileParent(), path);
+ context.getProject().log(
+ "Warning: '" + systemId + "' in " + context.getBuildFile()
+ + " should be expressed simply as '" + path.replace('\\', '/')
+ + "' for compliance with other XML tools", Project.MSG_WARN);
+ }
+ context.getProject().log("file=" + file, Project.MSG_DEBUG);
+ try {
+ InputSource inputSource = new InputSource(new FileInputStream(file));
+ inputSource.setSystemId(FILE_UTILS.toURI(file.getAbsolutePath()));
+ return inputSource;
+ } catch (FileNotFoundException fne) {
+ context.getProject().log(file.getAbsolutePath() + " could not be found",
+ Project.MSG_WARN);
+ }
+
+ }
+ // use default if not file or file not found
+ context.getProject().log("could not resolve systemId", Project.MSG_DEBUG);
+ return null;
+ }
+
+ /**
+ * Handles the start of a project element. A project handler is created
+ * and initialised with the element name and attributes.
+ *
+ * @param uri The namespace uri for this element.
+ * @param tag The name of the element being started.
+ * Will not be <code>null</code>.
+ * @param qname The qualified name for this element.
+ * @param attrs Attributes of the element being started.
+ * Will not be <code>null</code>.
+ *
+ * @exception org.xml.sax.SAXParseException if the tag given is not
+ * <code>"project"</code>
+ */
+ public void startElement(String uri, String tag, String qname, Attributes attrs)
+ throws SAXParseException {
+ AntHandler next = currentHandler.onStartChild(uri, tag, qname, attrs, context);
+ antHandlers.push(currentHandler);
+ currentHandler = next;
+ currentHandler.onStartElement(uri, tag, qname, attrs, context);
+ }
+
+ /**
+ * Sets the locator in the project helper for future reference.
+ *
+ * @param locator The locator used by the parser.
+ * Will not be <code>null</code>.
+ */
+ public void setDocumentLocator(Locator locator) {
+ context.setLocator(locator);
+ }
+
+ /**
+ * Handles the end of an element. Any required clean-up is performed
+ * by the onEndElement() method and then the original handler is restored to the parser.
+ *
+ * @param uri The namespace URI for this element.
+ * @param name The name of the element which is ending.
+ * Will not be <code>null</code>.
+ * @param qName The qualified name for this element.
+ *
+ * @exception SAXException in case of error (not thrown in this implementation)
+ */
+ public void endElement(String uri, String name, String qName) throws SAXException {
+ currentHandler.onEndElement(uri, name, context);
+ AntHandler prev = (AntHandler) antHandlers.pop();
+ currentHandler = prev;
+ if (currentHandler != null) {
+ currentHandler.onEndChild(uri, name, qName, context);
+ }
+ }
+
+ /**
+ * Handle text within an element, calls currentHandler.characters.
+ *
+ * @param buf A character array of the test.
+ * @param start The start offset in the array.
+ * @param count The number of characters to read.
+ * @exception SAXParseException if an error occurs
+ */
+ public void characters(char[] buf, int start, int count) throws SAXParseException {
+ currentHandler.characters(buf, start, count, context);
+ }
+
+ /**
+ * Start a namespace prefix to uri mapping
+ *
+ * @param prefix the namespace prefix
+ * @param uri the namespace uri
+ */
+ public void startPrefixMapping(String prefix, String uri) {
+ context.startPrefixMapping(prefix, uri);
+ }
+
+ /**
+ * End a namespace prefix to uri mapping
+ *
+ * @param prefix the prefix that is not mapped anymore
+ */
+ public void endPrefixMapping(String prefix) {
+ context.endPrefixMapping(prefix);
+ }
+ }
+
+ /**
+ * The main handler - it handles the &lt;project&gt; tag.
+ *
+ * @see org.apache.tools.ant.helper.ProjectHelper2.AntHandler
+ */
+ public static class MainHandler extends AntHandler {
+
+ /**
+ * Handle the project tag
+ *
+ * @param uri The namespace uri.
+ * @param name The element tag.
+ * @param qname The element qualified name.
+ * @param attrs The attributes of the element.
+ * @param context The current context.
+ * @return The project handler that handles subelements of project
+ * @exception SAXParseException if the qualified name is not "project".
+ */
+ public AntHandler onStartChild(String uri, String name, String qname, Attributes attrs,
+ AntXMLContext context) throws SAXParseException {
+ if (name.equals("project")
+ && (uri.equals("") || uri.equals(ANT_CORE_URI))) {
+ return ProjectHelper2.projectHandler;
+ }
+ if (name.equals(qname)) {
+ throw new SAXParseException("Unexpected element \"{" + uri
+ + "}" + name + "\" {" + ANT_CORE_URI + "}" + name, context.getLocator());
+ }
+ throw new SAXParseException("Unexpected element \"" + qname
+ + "\" " + name, context.getLocator());
+ }
+ }
+
+ /**
+ * Handler for the top level "project" element.
+ */
+ public static class ProjectHandler extends AntHandler {
+
+ /**
+ * Initialisation routine called after handler creation
+ * with the element name and attributes. The attributes which
+ * this handler can deal with are: <code>"default"</code>,
+ * <code>"name"</code>, <code>"id"</code> and <code>"basedir"</code>.
+ *
+ * @param uri The namespace URI for this element.
+ * @param tag Name of the element which caused this handler
+ * to be created. Should not be <code>null</code>.
+ * Ignored in this implementation.
+ * @param qname The qualified name for this element.
+ * @param attrs Attributes of the element which caused this
+ * handler to be created. Must not be <code>null</code>.
+ * @param context The current context.
+ *
+ * @exception SAXParseException if an unexpected attribute is
+ * encountered or if the <code>"default"</code> attribute
+ * is missing.
+ */
+ public void onStartElement(String uri, String tag, String qname, Attributes attrs,
+ AntXMLContext context) throws SAXParseException {
+ String baseDir = null;
+ boolean nameAttributeSet = false;
+
+ Project project = context.getProject();
+ // Set the location of the implicit target associated with the project tag
+ context.getImplicitTarget().setLocation(new Location(context.getLocator()));
+
+ /** TODO I really don't like this - the XML processor is still
+ * too 'involved' in the processing. A better solution (IMO)
+ * would be to create UE for Project and Target too, and
+ * then process the tree and have Project/Target deal with
+ * its attributes ( similar with Description ).
+ *
+ * If we eventually switch to ( or add support for ) DOM,
+ * things will work smoothly - UE can be avoided almost completely
+ * ( it could still be created on demand, for backward compatibility )
+ */
+
+ for (int i = 0; i < attrs.getLength(); i++) {
+ String attrUri = attrs.getURI(i);
+ if (attrUri != null && !attrUri.equals("") && !attrUri.equals(uri)) {
+ continue; // Ignore attributes from unknown uris
+ }
+ String key = attrs.getLocalName(i);
+ String value = attrs.getValue(i);
+
+ if (key.equals("default")) {
+ if (value != null && !value.equals("")) {
+ if (!context.isIgnoringProjectTag()) {
+ project.setDefault(value);
+ }
+ }
+ } else if (key.equals("name")) {
+ if (value != null) {
+ context.setCurrentProjectName(value);
+ nameAttributeSet = true;
+ if (!context.isIgnoringProjectTag()) {
+ project.setName(value);
+ project.addReference(value, project);
+ } else if (isInIncludeMode()) {
+ if (!"".equals(value) && getCurrentTargetPrefix()!= null && getCurrentTargetPrefix().endsWith(ProjectHelper.USE_PROJECT_NAME_AS_TARGET_PREFIX)) {
+ String newTargetPrefix = getCurrentTargetPrefix().replace(ProjectHelper.USE_PROJECT_NAME_AS_TARGET_PREFIX, value);
+ // help nested include tasks
+ setCurrentTargetPrefix(newTargetPrefix);
+ }
+ }
+ }
+ } else if (key.equals("id")) {
+ if (value != null) {
+ // What's the difference between id and name ?
+ if (!context.isIgnoringProjectTag()) {
+ project.addReference(value, project);
+ }
+ }
+ } else if (key.equals("basedir")) {
+ if (!context.isIgnoringProjectTag()) {
+ baseDir = value;
+ }
+ } else {
+ // TODO ignore attributes in a different NS ( maybe store them ? )
+ throw new SAXParseException("Unexpected attribute \"" + attrs.getQName(i)
+ + "\"", context.getLocator());
+ }
+ }
+
+ // TODO Move to Project ( so it is shared by all helpers )
+ String antFileProp =
+ MagicNames.ANT_FILE + "." + context.getCurrentProjectName();
+ String dup = project.getProperty(antFileProp);
+ String typeProp =
+ MagicNames.ANT_FILE_TYPE + "." + context.getCurrentProjectName();
+ String dupType = project.getProperty(typeProp);
+ if (dup != null && nameAttributeSet) {
+ Object dupFile = null;
+ Object contextFile = null;
+ if (MagicNames.ANT_FILE_TYPE_URL.equals(dupType)) {
+ try {
+ dupFile = new URL(dup);
+ } catch (java.net.MalformedURLException mue) {
+ throw new BuildException("failed to parse "
+ + dup + " as URL while looking"
+ + " at a duplicate project"
+ + " name.", mue);
+ }
+ contextFile = context.getBuildFileURL();
+ } else {
+ dupFile = new File(dup);
+ contextFile = context.getBuildFile();
+ }
+
+ if (context.isIgnoringProjectTag() && !dupFile.equals(contextFile)) {
+ project.log("Duplicated project name in import. Project "
+ + context.getCurrentProjectName() + " defined first in " + dup
+ + " and again in " + contextFile, Project.MSG_WARN);
+ }
+ }
+ if (nameAttributeSet) {
+ if (context.getBuildFile() != null) {
+ project.setUserProperty(antFileProp,
+ context.getBuildFile().toString());
+ project.setUserProperty(typeProp,
+ MagicNames.ANT_FILE_TYPE_FILE);
+ } else if (context.getBuildFileURL() != null) {
+ project.setUserProperty(antFileProp,
+ context.getBuildFileURL().toString());
+ project.setUserProperty(typeProp,
+ MagicNames.ANT_FILE_TYPE_URL);
+ }
+ }
+ if (context.isIgnoringProjectTag()) {
+ // no further processing
+ return;
+ }
+ // set explicitly before starting ?
+ if (project.getProperty("basedir") != null) {
+ project.setBasedir(project.getProperty("basedir"));
+ } else {
+ // Default for baseDir is the location of the build file.
+ if (baseDir == null) {
+ project.setBasedir(context.getBuildFileParent().getAbsolutePath());
+ } else {
+ // check whether the user has specified an absolute path
+ if ((new File(baseDir)).isAbsolute()) {
+ project.setBasedir(baseDir);
+ } else {
+ project.setBaseDir(FILE_UTILS.resolveFile(context.getBuildFileParent(),
+ baseDir));
+ }
+ }
+ }
+ project.addTarget("", context.getImplicitTarget());
+ context.setCurrentTarget(context.getImplicitTarget());
+ }
+
+ /**
+ * Handles the start of a top-level element within the project. An
+ * appropriate handler is created and initialised with the details
+ * of the element.
+ *
+ * @param uri The namespace URI for this element.
+ * @param name The name of the element being started.
+ * Will not be <code>null</code>.
+ * @param qname The qualified name for this element.
+ * @param attrs Attributes of the element being started.
+ * Will not be <code>null</code>.
+ * @param context The context for this element.
+ * @return a target or an element handler.
+ *
+ * @exception org.xml.sax.SAXParseException if the tag given is not
+ * <code>"taskdef"</code>, <code>"typedef"</code>,
+ * <code>"property"</code>, <code>"target"</code>,
+ * <code>"extension-point"</code>
+ * or a data type definition
+ */
+ public AntHandler onStartChild(String uri, String name, String qname, Attributes attrs,
+ AntXMLContext context) throws SAXParseException {
+ return (name.equals("target") || name.equals("extension-point"))
+ && (uri.equals("") || uri.equals(ANT_CORE_URI))
+ ? ProjectHelper2.targetHandler : ProjectHelper2.elementHandler;
+ }
+ }
+
+ /**
+ * Handler for "target" and "extension-point" elements.
+ */
+ public static class TargetHandler extends AntHandler {
+
+ /**
+ * Initialisation routine called after handler creation
+ * with the element name and attributes. The attributes which
+ * this handler can deal with are: <code>"name"</code>,
+ * <code>"depends"</code>, <code>"if"</code>,
+ * <code>"unless"</code>, <code>"id"</code> and
+ * <code>"description"</code>.
+ *
+ * @param uri The namespace URI for this element.
+ * @param tag Name of the element which caused this handler
+ * to be created. Should not be <code>null</code>.
+ * Ignored in this implementation.
+ * @param qname The qualified name for this element.
+ * @param attrs Attributes of the element which caused this
+ * handler to be created. Must not be <code>null</code>.
+ * @param context The current context.
+ *
+ * @exception SAXParseException if an unexpected attribute is encountered
+ * or if the <code>"name"</code> attribute is missing.
+ */
+ public void onStartElement(String uri, String tag, String qname, Attributes attrs,
+ AntXMLContext context) throws SAXParseException {
+ String name = null;
+ String depends = "";
+ String extensionPoint = null;
+ OnMissingExtensionPoint extensionPointMissing = null;
+
+ Project project = context.getProject();
+ Target target = "target".equals(tag)
+ ? new Target() : new ExtensionPoint();
+ target.setProject(project);
+ target.setLocation(new Location(context.getLocator()));
+ context.addTarget(target);
+
+ for (int i = 0; i < attrs.getLength(); i++) {
+ String attrUri = attrs.getURI(i);
+ if (attrUri != null && !attrUri.equals("") && !attrUri.equals(uri)) {
+ continue; // Ignore attributes from unknown uris
+ }
+ String key = attrs.getLocalName(i);
+ String value = attrs.getValue(i);
+
+ if (key.equals("name")) {
+ name = value;
+ if ("".equals(name)) {
+ throw new BuildException("name attribute must " + "not be empty");
+ }
+ } else if (key.equals("depends")) {
+ depends = value;
+ } else if (key.equals("if")) {
+ target.setIf(value);
+ } else if (key.equals("unless")) {
+ target.setUnless(value);
+ } else if (key.equals("id")) {
+ if (value != null && !value.equals("")) {
+ context.getProject().addReference(value, target);
+ }
+ } else if (key.equals("description")) {
+ target.setDescription(value);
+ } else if (key.equals("extensionOf")) {
+ extensionPoint = value;
+ } else if (key.equals("onMissingExtensionPoint")) {
+ try {
+ extensionPointMissing = OnMissingExtensionPoint.valueOf(value);
+ } catch (IllegalArgumentException e) {
+ throw new BuildException("Invalid onMissingExtensionPoint " + value);
+ }
+ } else {
+ throw new SAXParseException("Unexpected attribute \"" + key + "\"", context
+ .getLocator());
+ }
+ }
+
+ if (name == null) {
+ throw new SAXParseException("target element appears without a name attribute",
+ context.getLocator());
+ }
+
+ String prefix = null;
+ boolean isInIncludeMode =
+ context.isIgnoringProjectTag() && isInIncludeMode();
+ String sep = getCurrentPrefixSeparator();
+
+ if (isInIncludeMode) {
+ prefix = getTargetPrefix(context);
+ if (prefix == null) {
+ throw new BuildException("can't include build file "
+ + context.getBuildFileURL()
+ + ", no as attribute has been given"
+ + " and the project tag doesn't"
+ + " specify a name attribute");
+ }
+ name = prefix + sep + name;
+ }
+
+ // Check if this target is in the current build file
+ if (context.getCurrentTargets().get(name) != null) {
+ throw new BuildException("Duplicate target '" + name + "'",
+ target.getLocation());
+ }
+ Hashtable<String, Target> projectTargets = project.getTargets();
+ boolean usedTarget = false;
+ // If the name has not already been defined define it
+ if (projectTargets.containsKey(name)) {
+ project.log("Already defined in main or a previous import, ignore " + name,
+ Project.MSG_VERBOSE);
+ } else {
+ target.setName(name);
+ context.getCurrentTargets().put(name, target);
+ project.addOrReplaceTarget(name, target);
+ usedTarget = true;
+ }
+
+ if (depends.length() > 0) {
+ if (!isInIncludeMode) {
+ target.setDepends(depends);
+ } else {
+ for (String string : Target.parseDepends(depends, name, "depends")) {
+ target.addDependency(prefix + sep + string);
+ }
+ }
+ }
+ if (!isInIncludeMode && context.isIgnoringProjectTag()
+ && (prefix = getTargetPrefix(context)) != null) {
+ // In an imported file (and not completely
+ // ignoring the project tag or having a preconfigured prefix)
+ String newName = prefix + sep + name;
+ Target newTarget = target;
+ if (usedTarget) {
+ newTarget = "target".equals(tag)
+ ? new Target(target) : new ExtensionPoint(target);
+ }
+ newTarget.setName(newName);
+ context.getCurrentTargets().put(newName, newTarget);
+ project.addOrReplaceTarget(newName, newTarget);
+ }
+ if (extensionPointMissing != null && extensionPoint == null) {
+ throw new BuildException("onMissingExtensionPoint attribute cannot " +
+ "be specified unless extensionOf is specified",
+ target.getLocation());
+
+ }
+ if (extensionPoint != null) {
+ ProjectHelper helper =
+ (ProjectHelper) context.getProject().
+ getReference(ProjectHelper.PROJECTHELPER_REFERENCE);
+ for (String extPointName : Target.parseDepends(extensionPoint, name, "extensionOf")) {
+ if (extensionPointMissing == null) {
+ extensionPointMissing = OnMissingExtensionPoint.FAIL;
+ }
+ // defer extensionpoint resolution until the full
+ // import stack has been processed
+ if (isInIncludeMode()) {
+ // if in include mode, provide prefix we're including by
+ // so that we can try and resolve extension point from
+ // the local file first
+ helper.getExtensionStack().add(
+ new String[] {extPointName, target.getName(),
+ extensionPointMissing.name(), prefix + sep});
+ } else {
+ helper.getExtensionStack().add(
+ new String[] {extPointName, target.getName(),
+ extensionPointMissing.name()});
+ }
+ }
+ }
+ }
+
+ private String getTargetPrefix(AntXMLContext context) {
+ String configuredValue = getCurrentTargetPrefix();
+ if (configuredValue != null && configuredValue.length() == 0) {
+ configuredValue = null;
+ }
+ if (configuredValue != null) {
+ return configuredValue;
+ }
+
+ String projectName = context.getCurrentProjectName();
+ if ("".equals(projectName)) {
+ projectName = null;
+ }
+
+ return projectName;
+ }
+
+ /**
+ * Handles the start of an element within a target.
+ *
+ * @param uri The namespace URI for this element.
+ * @param name The name of the element being started.
+ * Will not be <code>null</code>.
+ * @param qname The qualified name for this element.
+ * @param attrs Attributes of the element being started.
+ * Will not be <code>null</code>.
+ * @param context The current context.
+ * @return an element handler.
+ *
+ * @exception SAXParseException if an error occurs when initialising
+ * the appropriate child handler
+ */
+ public AntHandler onStartChild(String uri, String name, String qname, Attributes attrs,
+ AntXMLContext context) throws SAXParseException {
+ return ProjectHelper2.elementHandler;
+ }
+
+ /**
+ * Handle the end of the project, sets the current target of the
+ * context to be the implicit target.
+ *
+ * @param uri The namespace URI of the element.
+ * @param tag The name of the element.
+ * @param context The current context.
+ */
+ public void onEndElement(String uri, String tag, AntXMLContext context) {
+ context.setCurrentTarget(context.getImplicitTarget());
+ }
+ }
+
+ /**
+ * Handler for all project elements ( tasks, data types )
+ */
+ public static class ElementHandler extends AntHandler {
+
+ /**
+ * Constructor.
+ */
+ public ElementHandler() {
+ }
+
+ /**
+ * Initialisation routine called after handler creation
+ * with the element name and attributes. This configures
+ * the element with its attributes and sets it up with
+ * its parent container (if any). Nested elements are then
+ * added later as the parser encounters them.
+ *
+ * @param uri The namespace URI for this element.
+ * @param tag Name of the element which caused this handler
+ * to be created. Must not be <code>null</code>.
+ * @param qname The qualified name for this element.
+ * @param attrs Attributes of the element which caused this
+ * handler to be created. Must not be <code>null</code>.
+ * @param context The current context.
+ *
+ * @exception SAXParseException in case of error (not thrown in
+ * this implementation)
+ */
+ public void onStartElement(String uri, String tag, String qname, Attributes attrs,
+ AntXMLContext context) throws SAXParseException {
+ RuntimeConfigurable parentWrapper = context.currentWrapper();
+ Object parent = null;
+
+ if (parentWrapper != null) {
+ parent = parentWrapper.getProxy();
+ }
+
+ /* UnknownElement is used for tasks and data types - with
+ delayed eval */
+ UnknownElement task = new UnknownElement(tag);
+ task.setProject(context.getProject());
+ task.setNamespace(uri);
+ task.setQName(qname);
+ task.setTaskType(ProjectHelper.genComponentName(task.getNamespace(), tag));
+ task.setTaskName(qname);
+
+ Location location = new Location(context.getLocator().getSystemId(), context
+ .getLocator().getLineNumber(), context.getLocator().getColumnNumber());
+ task.setLocation(location);
+ task.setOwningTarget(context.getCurrentTarget());
+
+ if (parent != null) {
+ // Nested element
+ ((UnknownElement) parent).addChild(task);
+ } else {
+ // Task included in a target ( including the default one ).
+ context.getCurrentTarget().addTask(task);
+ }
+
+ context.configureId(task, attrs);
+
+ // container.addTask(task);
+ // This is a nop in UE: task.init();
+
+ RuntimeConfigurable wrapper = new RuntimeConfigurable(task, task.getTaskName());
+
+ for (int i = 0; i < attrs.getLength(); i++) {
+ String name = attrs.getLocalName(i);
+ String attrUri = attrs.getURI(i);
+ if (attrUri != null && !attrUri.equals("") && !attrUri.equals(uri)) {
+ name = attrUri + ":" + attrs.getQName(i);
+ }
+ String value = attrs.getValue(i);
+ // PR: Hack for ant-type value
+ // an ant-type is a component name which can
+ // be namespaced, need to extract the name
+ // and convert from qualified name to uri/name
+ if (ANT_TYPE.equals(name)
+ || (ANT_CORE_URI.equals(attrUri)
+ && ANT_TYPE.equals(attrs.getLocalName(i)))) {
+ name = ANT_TYPE;
+ int index = value.indexOf(":");
+ if (index >= 0) {
+ String prefix = value.substring(0, index);
+ String mappedUri = context.getPrefixMapping(prefix);
+ if (mappedUri == null) {
+ throw new BuildException("Unable to find XML NS prefix \"" + prefix
+ + "\"");
+ }
+ value = ProjectHelper.genComponentName(mappedUri, value
+ .substring(index + 1));
+ }
+ }
+ wrapper.setAttribute(name, value);
+ }
+ if (parentWrapper != null) {
+ parentWrapper.addChild(wrapper);
+ }
+ context.pushWrapper(wrapper);
+ }
+
+ /**
+ * Adds text to the task, using the wrapper
+ *
+ * @param buf A character array of the text within the element.
+ * Will not be <code>null</code>.
+ * @param start The start element in the array.
+ * @param count The number of characters to read from the array.
+ * @param context The current context.
+ *
+ * @exception SAXParseException if the element doesn't support text
+ *
+ * @see ProjectHelper#addText(Project,java.lang.Object,char[],int,int)
+ */
+ public void characters(char[] buf, int start, int count,
+ AntXMLContext context) throws SAXParseException {
+ RuntimeConfigurable wrapper = context.currentWrapper();
+ wrapper.addText(buf, start, count);
+ }
+
+ /**
+ * Handles the start of an element within a target. Task containers
+ * will always use another task handler, and all other tasks
+ * will always use a nested element handler.
+ *
+ * @param uri The namespace URI for this element.
+ * @param tag The name of the element being started.
+ * Will not be <code>null</code>.
+ * @param qname The qualified name for this element.
+ * @param attrs Attributes of the element being started.
+ * Will not be <code>null</code>.
+ * @param context The current context.
+ * @return The handler for elements.
+ *
+ * @exception SAXParseException if an error occurs when initialising
+ * the appropriate child handler
+ */
+ public AntHandler onStartChild(String uri, String tag, String qname, Attributes attrs,
+ AntXMLContext context) throws SAXParseException {
+ return ProjectHelper2.elementHandler;
+ }
+
+ /**
+ * Handles the end of the element. This pops the wrapper from
+ * the context.
+ *
+ * @param uri The namespace URI for the element.
+ * @param tag The name of the element.
+ * @param context The current context.
+ */
+ public void onEndElement(String uri, String tag, AntXMLContext context) {
+ context.popWrapper();
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/helper/ProjectHelperImpl.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/helper/ProjectHelperImpl.java
new file mode 100644
index 00000000..f828d292
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/helper/ProjectHelperImpl.java
@@ -0,0 +1,1026 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.helper;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.util.Locale;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.IntrospectionHelper;
+import org.apache.tools.ant.Location;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.ProjectHelper;
+import org.apache.tools.ant.RuntimeConfigurable;
+import org.apache.tools.ant.Target;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.TaskContainer;
+import org.apache.tools.ant.TypeAdapter;
+import org.apache.tools.ant.UnknownElement;
+import org.apache.tools.ant.util.FileUtils;
+import org.apache.tools.ant.util.JAXPUtils;
+import org.xml.sax.AttributeList;
+import org.xml.sax.DocumentHandler;
+import org.xml.sax.HandlerBase;
+import org.xml.sax.InputSource;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+import org.xml.sax.helpers.XMLReaderAdapter;
+
+/**
+ * Original helper.
+ *
+ */
+public class ProjectHelperImpl extends ProjectHelper {
+
+ /**
+ * helper for path -> URI and URI -> path conversions.
+ */
+ private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+
+ /**
+ * SAX 1 style parser used to parse the given file. This may
+ * in fact be a SAX 2 XMLReader wrapped in an XMLReaderAdapter.
+ */
+ private org.xml.sax.Parser parser;
+
+ /** The project to configure. */
+ private Project project;
+
+ /** The configuration file to parse. */
+ private File buildFile;
+
+ /**
+ * Parent directory of the build file. Used for resolving entities
+ * and setting the project's base directory.
+ */
+ private File buildFileParent;
+
+ /**
+ * Locator for the configuration file parser.
+ * Used for giving locations of errors etc.
+ */
+ private Locator locator;
+
+ /**
+ * Target that all other targets will depend upon implicitly.
+ *
+ * <p>This holds all tasks and data type definitions that have
+ * been placed outside of targets.</p>
+ */
+ private Target implicitTarget = new Target();
+
+ /**
+ * default constructor
+ */
+ public ProjectHelperImpl() {
+ implicitTarget.setName("");
+ }
+
+ /**
+ * Parses the project file, configuring the project as it goes.
+ *
+ * @param project project instance to be configured.
+ * @param source the source from which the project is read.
+ * @exception BuildException if the configuration is invalid or cannot
+ * be read.
+ */
+ public void parse(Project project, Object source) throws BuildException {
+ if (!(source instanceof File)) {
+ throw new BuildException("Only File source supported by "
+ + "default plugin");
+ }
+ File bFile = (File) source;
+ FileInputStream inputStream = null;
+ InputSource inputSource = null;
+
+ this.project = project;
+ this.buildFile = new File(bFile.getAbsolutePath());
+ buildFileParent = new File(this.buildFile.getParent());
+
+ try {
+ try {
+ parser = JAXPUtils.getParser();
+ } catch (BuildException e) {
+ parser = new XMLReaderAdapter(JAXPUtils.getXMLReader());
+ }
+ String uri = FILE_UTILS.toURI(bFile.getAbsolutePath());
+ inputStream = new FileInputStream(bFile);
+ inputSource = new InputSource(inputStream);
+ inputSource.setSystemId(uri);
+ project.log("parsing buildfile " + bFile + " with URI = " + uri, Project.MSG_VERBOSE);
+ HandlerBase hb = new RootHandler(this);
+ parser.setDocumentHandler(hb);
+ parser.setEntityResolver(hb);
+ parser.setErrorHandler(hb);
+ parser.setDTDHandler(hb);
+ parser.parse(inputSource);
+ } catch (SAXParseException exc) {
+ Location location = new Location(exc.getSystemId(), exc.getLineNumber(), exc
+ .getColumnNumber());
+
+ Throwable t = exc.getException();
+ if (t instanceof BuildException) {
+ BuildException be = (BuildException) t;
+ if (be.getLocation() == Location.UNKNOWN_LOCATION) {
+ be.setLocation(location);
+ }
+ throw be;
+ }
+ throw new BuildException(exc.getMessage(), t, location);
+ } catch (SAXException exc) {
+ Throwable t = exc.getException();
+ if (t instanceof BuildException) {
+ throw (BuildException) t;
+ }
+ throw new BuildException(exc.getMessage(), t);
+ } catch (FileNotFoundException exc) {
+ throw new BuildException(exc);
+ } catch (UnsupportedEncodingException exc) {
+ throw new BuildException("Encoding of project file is invalid.", exc);
+ } catch (IOException exc) {
+ throw new BuildException("Error reading project file: " + exc.getMessage(), exc);
+ } finally {
+ FileUtils.close(inputStream);
+ }
+ }
+
+ /**
+ * The common superclass for all SAX event handlers used to parse
+ * the configuration file. Each method just throws an exception,
+ * so subclasses should override what they can handle.
+ *
+ * Each type of XML element (task, target, etc.) in Ant has
+ * a specific subclass.
+ *
+ * In the constructor, this class takes over the handling of SAX
+ * events from the parent handler and returns
+ * control back to the parent in the endElement method.
+ */
+ static class AbstractHandler extends HandlerBase {
+ // CheckStyle:VisibilityModifier OFF - bc
+
+ /**
+ * Previous handler for the document.
+ * When the next element is finished, control returns
+ * to this handler.
+ */
+ protected DocumentHandler parentHandler;
+
+ /** Helper impl. With non-static internal classes, the compiler will generate
+ this automatically - but this will fail with some compilers ( reporting
+ "Expecting to find object/array on stack" ). If we pass it
+ explicitly it'll work with more compilers.
+ */
+ ProjectHelperImpl helperImpl;
+ // CheckStyle:VisibilityModifier ON
+
+ /**
+ * Creates a handler and sets the parser to use it
+ * for the current element.
+ *
+ * @param helperImpl the ProjectHelperImpl instance associated
+ * with this handler.
+ *
+ * @param parentHandler The handler which should be restored to the
+ * parser at the end of the element.
+ * Must not be <code>null</code>.
+ */
+ public AbstractHandler(ProjectHelperImpl helperImpl, DocumentHandler parentHandler) {
+ this.parentHandler = parentHandler;
+ this.helperImpl = helperImpl;
+
+ // Start handling SAX events
+ helperImpl.parser.setDocumentHandler(this);
+ }
+
+ /**
+ * Handles the start of an element. This base implementation just
+ * throws an exception.
+ *
+ * @param tag The name of the element being started.
+ * Will not be <code>null</code>.
+ * @param attrs Attributes of the element being started.
+ * Will not be <code>null</code>.
+ *
+ * @exception SAXParseException if this method is not overridden, or in
+ * case of error in an overridden version
+ */
+ public void startElement(String tag, AttributeList attrs) throws SAXParseException {
+ throw new SAXParseException("Unexpected element \"" + tag + "\"", helperImpl.locator);
+ }
+
+ /**
+ * Handles text within an element. This base implementation just
+ * throws an exception.
+ *
+ * @param buf A character array of the text within the element.
+ * Will not be <code>null</code>.
+ * @param start The start element in the array.
+ * @param count The number of characters to read from the array.
+ *
+ * @exception SAXParseException if this method is not overridden, or in
+ * case of error in an overridden version
+ */
+ public void characters(char[] buf, int start, int count) throws SAXParseException {
+ String s = new String(buf, start, count).trim();
+
+ if (s.length() > 0) {
+ throw new SAXParseException("Unexpected text \"" + s + "\"", helperImpl.locator);
+ }
+ }
+
+ /**
+ * Handles the end of an element. Any required clean-up is performed
+ * by the finished() method and then the original handler is restored to
+ * the parser.
+ *
+ * @param name The name of the element which is ending.
+ * Will not be <code>null</code>.
+ *
+ * @exception SAXException in case of error (not thrown in
+ * this implementation)
+ */
+ public void endElement(String name) throws SAXException {
+ // Let parent resume handling SAX events
+ helperImpl.parser.setDocumentHandler(parentHandler);
+ }
+ }
+
+ /**
+ * Handler for the root element. Its only child must be the "project" element.
+ */
+ static class RootHandler extends HandlerBase {
+ // CheckStyle:VisibilityModifier OFF - bc
+ ProjectHelperImpl helperImpl;
+ // CheckStyle:VisibilityModifier ON
+
+ public RootHandler(ProjectHelperImpl helperImpl) {
+ this.helperImpl = helperImpl;
+ }
+
+ /**
+ * Resolves file: URIs relative to the build file.
+ *
+ * @param publicId The public identifier, or <code>null</code>
+ * if none is available. Ignored in this
+ * implementation.
+ * @param systemId The system identifier provided in the XML
+ * document. Will not be <code>null</code>.
+ */
+ public InputSource resolveEntity(String publicId, String systemId) {
+
+ helperImpl.project.log("resolving systemId: " + systemId, Project.MSG_VERBOSE);
+
+ if (systemId.startsWith("file:")) {
+ String path = FILE_UTILS.fromURI(systemId);
+
+ File file = new File(path);
+ if (!file.isAbsolute()) {
+ file = FILE_UTILS.resolveFile(helperImpl.buildFileParent, path);
+ helperImpl.project.log("Warning: '" + systemId + "' in " + helperImpl.buildFile
+ + " should be expressed simply as '" + path.replace('\\', '/')
+ + "' for compliance with other XML tools", Project.MSG_WARN);
+ }
+ try {
+ InputSource inputSource = new InputSource(new FileInputStream(file));
+ inputSource.setSystemId(FILE_UTILS.toURI(file.getAbsolutePath()));
+ return inputSource;
+ } catch (FileNotFoundException fne) {
+ helperImpl.project.log(file.getAbsolutePath() + " could not be found",
+ Project.MSG_WARN);
+ }
+ }
+ // use default if not file or file not found
+ return null;
+ }
+
+ /**
+ * Handles the start of a project element. A project handler is created
+ * and initialised with the element name and attributes.
+ *
+ * @param tag The name of the element being started.
+ * Will not be <code>null</code>.
+ * @param attrs Attributes of the element being started.
+ * Will not be <code>null</code>.
+ *
+ * @exception SAXParseException if the tag given is not
+ * <code>"project"</code>
+ */
+ public void startElement(String tag, AttributeList attrs) throws SAXParseException {
+ if (tag.equals("project")) {
+ new ProjectHandler(helperImpl, this).init(tag, attrs);
+ } else {
+ throw new SAXParseException("Config file is not of expected " + "XML type",
+ helperImpl.locator);
+ }
+ }
+
+ /**
+ * Sets the locator in the project helper for future reference.
+ *
+ * @param locator The locator used by the parser.
+ * Will not be <code>null</code>.
+ */
+ public void setDocumentLocator(Locator locator) {
+ helperImpl.locator = locator;
+ }
+ }
+
+ /**
+ * Handler for the top level "project" element.
+ */
+ static class ProjectHandler extends AbstractHandler {
+
+ /**
+ * Constructor which just delegates to the superconstructor.
+ *
+ * @param parentHandler The handler which should be restored to the
+ * parser at the end of the element.
+ * Must not be <code>null</code>.
+ */
+ public ProjectHandler(ProjectHelperImpl helperImpl, DocumentHandler parentHandler) {
+ super(helperImpl, parentHandler);
+ }
+
+ /**
+ * Initialisation routine called after handler creation
+ * with the element name and attributes. The attributes which
+ * this handler can deal with are: <code>"default"</code>,
+ * <code>"name"</code>, <code>"id"</code> and <code>"basedir"</code>.
+ *
+ * @param tag Name of the element which caused this handler
+ * to be created. Should not be <code>null</code>.
+ * Ignored in this implementation.
+ * @param attrs Attributes of the element which caused this
+ * handler to be created. Must not be <code>null</code>.
+ *
+ * @exception SAXParseException if an unexpected attribute is
+ * encountered or if the <code>"default"</code> attribute
+ * is missing.
+ */
+ public void init(String tag, AttributeList attrs) throws SAXParseException {
+ String def = null;
+ String name = null;
+ String id = null;
+ String baseDir = null;
+
+ for (int i = 0; i < attrs.getLength(); i++) {
+ String key = attrs.getName(i);
+ String value = attrs.getValue(i);
+
+ if (key.equals("default")) {
+ def = value;
+ } else if (key.equals("name")) {
+ name = value;
+ } else if (key.equals("id")) {
+ id = value;
+ } else if (key.equals("basedir")) {
+ baseDir = value;
+ } else {
+ throw new SAXParseException(
+ "Unexpected attribute \"" + attrs.getName(i)
+ + "\"", helperImpl.locator);
+ }
+ }
+
+ if (def != null && !def.equals("")) {
+ helperImpl.project.setDefault(def);
+ } else {
+ throw new BuildException("The default attribute is required");
+ }
+
+ if (name != null) {
+ helperImpl.project.setName(name);
+ helperImpl.project.addReference(name, helperImpl.project);
+ }
+
+ if (id != null) {
+ helperImpl.project.addReference(id, helperImpl.project);
+ }
+
+ if (helperImpl.project.getProperty("basedir") != null) {
+ helperImpl.project.setBasedir(helperImpl.project.getProperty("basedir"));
+ } else {
+ if (baseDir == null) {
+ helperImpl.project.setBasedir(helperImpl.buildFileParent.getAbsolutePath());
+ } else {
+ // check whether the user has specified an absolute path
+ if ((new File(baseDir)).isAbsolute()) {
+ helperImpl.project.setBasedir(baseDir);
+ } else {
+ File resolvedBaseDir = FILE_UTILS.resolveFile(helperImpl.buildFileParent,
+ baseDir);
+ helperImpl.project.setBaseDir(resolvedBaseDir);
+ }
+ }
+ }
+
+ helperImpl.project.addTarget("", helperImpl.implicitTarget);
+ }
+
+ /**
+ * Handles the start of a top-level element within the project. An
+ * appropriate handler is created and initialised with the details
+ * of the element.
+ *
+ * @param name The name of the element being started.
+ * Will not be <code>null</code>.
+ * @param attrs Attributes of the element being started.
+ * Will not be <code>null</code>.
+ *
+ * @exception SAXParseException if the tag given is not
+ * <code>"taskdef"</code>, <code>"typedef"</code>,
+ * <code>"property"</code>, <code>"target"</code>
+ * or a data type definition
+ */
+ public void startElement(String name, AttributeList attrs) throws SAXParseException {
+ if (name.equals("target")) {
+ handleTarget(name, attrs);
+ } else {
+ handleElement(helperImpl, this, helperImpl.implicitTarget, name, attrs);
+ }
+ }
+
+ /**
+ * Handles a target definition element by creating a target handler
+ * and initialising is with the details of the element.
+ *
+ * @param tag The name of the element to be handled.
+ * Will not be <code>null</code>.
+ * @param attrs Attributes of the element to be handled.
+ * Will not be <code>null</code>.
+ *
+ * @exception SAXParseException if an error occurs initialising
+ * the handler
+ */
+ private void handleTarget(String tag, AttributeList attrs) throws SAXParseException {
+ new TargetHandler(helperImpl, this).init(tag, attrs);
+ }
+ }
+
+ /**
+ * Handler for "target" elements.
+ */
+ static class TargetHandler extends AbstractHandler {
+ private Target target;
+
+ /**
+ * Constructor which just delegates to the superconstructor.
+ *
+ * @param parentHandler The handler which should be restored to the
+ * parser at the end of the element.
+ * Must not be <code>null</code>.
+ */
+ public TargetHandler(ProjectHelperImpl helperImpl, DocumentHandler parentHandler) {
+ super(helperImpl, parentHandler);
+ }
+
+ /**
+ * Initialisation routine called after handler creation
+ * with the element name and attributes. The attributes which
+ * this handler can deal with are: <code>"name"</code>,
+ * <code>"depends"</code>, <code>"if"</code>,
+ * <code>"unless"</code>, <code>"id"</code> and
+ * <code>"description"</code>.
+ *
+ * @param tag Name of the element which caused this handler
+ * to be created. Should not be <code>null</code>.
+ * Ignored in this implementation.
+ * @param attrs Attributes of the element which caused this
+ * handler to be created. Must not be <code>null</code>.
+ *
+ * @exception SAXParseException if an unexpected attribute is encountered
+ * or if the <code>"name"</code> attribute is missing.
+ */
+ public void init(String tag, AttributeList attrs) throws SAXParseException {
+ String name = null;
+ String depends = "";
+ String ifCond = null;
+ String unlessCond = null;
+ String id = null;
+ String description = null;
+
+ for (int i = 0; i < attrs.getLength(); i++) {
+ String key = attrs.getName(i);
+ String value = attrs.getValue(i);
+
+ if (key.equals("name")) {
+ name = value;
+ if (name.equals("")) {
+ throw new BuildException("name attribute must not" + " be empty",
+ new Location(helperImpl.locator));
+ }
+ } else if (key.equals("depends")) {
+ depends = value;
+ } else if (key.equals("if")) {
+ ifCond = value;
+ } else if (key.equals("unless")) {
+ unlessCond = value;
+ } else if (key.equals("id")) {
+ id = value;
+ } else if (key.equals("description")) {
+ description = value;
+ } else {
+ throw new SAXParseException("Unexpected attribute \"" + key + "\"",
+ helperImpl.locator);
+ }
+ }
+
+ if (name == null) {
+ throw new SAXParseException("target element appears without a name attribute",
+ helperImpl.locator);
+ }
+
+ target = new Target();
+
+ // implicit target must be first on dependency list
+ target.addDependency("");
+
+ target.setName(name);
+ target.setIf(ifCond);
+ target.setUnless(unlessCond);
+ target.setDescription(description);
+ helperImpl.project.addTarget(name, target);
+
+ if (id != null && !id.equals("")) {
+ helperImpl.project.addReference(id, target);
+ }
+
+ // take care of dependencies
+
+ if (depends.length() > 0) {
+ target.setDepends(depends);
+ }
+ }
+
+ /**
+ * Handles the start of an element within a target.
+ *
+ * @param name The name of the element being started.
+ * Will not be <code>null</code>.
+ * @param attrs Attributes of the element being started.
+ * Will not be <code>null</code>.
+ *
+ * @exception SAXParseException if an error occurs when initialising
+ * the appropriate child handler
+ */
+ public void startElement(String name, AttributeList attrs) throws SAXParseException {
+ handleElement(helperImpl, this, target, name, attrs);
+ }
+ }
+
+ /**
+ * Start a new DataTypeHandler if element is known to be a
+ * data-type and a TaskHandler otherwise.
+ *
+ * <p>Factored out of TargetHandler.</p>
+ *
+ * @since Ant 1.6
+ */
+ private static void handleElement(ProjectHelperImpl helperImpl, DocumentHandler parent,
+ Target target, String elementName, AttributeList attrs) throws SAXParseException {
+ if (elementName.equals("description")) {
+ new DescriptionHandler(helperImpl, parent);
+ } else if (helperImpl.project.getDataTypeDefinitions().get(elementName) != null) {
+ new DataTypeHandler(helperImpl, parent, target).init(elementName, attrs);
+ } else {
+ new TaskHandler(helperImpl, parent, target, null, target).init(elementName, attrs);
+ }
+ }
+
+ /**
+ * Handler for "description" elements.
+ */
+ static class DescriptionHandler extends AbstractHandler {
+
+ /**
+ * Constructor which just delegates to the superconstructor.
+ *
+ * @param parentHandler The handler which should be restored to the
+ * parser at the end of the element.
+ * Must not be <code>null</code>.
+ */
+ public DescriptionHandler(ProjectHelperImpl helperImpl,
+ DocumentHandler parentHandler) {
+ super(helperImpl, parentHandler);
+ }
+
+ /**
+ * Adds the text as description to the project.
+ *
+ * @param buf A character array of the text within the element.
+ * Will not be <code>null</code>.
+ * @param start The start element in the array.
+ * @param count The number of characters to read from the array.
+ */
+ public void characters(char[] buf, int start, int count) {
+ String text = new String(buf, start, count);
+ String currentDescription = helperImpl.project.getDescription();
+ if (currentDescription == null) {
+ helperImpl.project.setDescription(text);
+ } else {
+ helperImpl.project.setDescription(currentDescription + text);
+ }
+ }
+
+ }
+
+ /**
+ * Handler for all task elements.
+ */
+ static class TaskHandler extends AbstractHandler {
+ /** Containing target, if any. */
+ private Target target;
+
+ /**
+ * Container for the task, if any. If target is
+ * non-<code>null</code>, this must be too.
+ */
+ private TaskContainer container;
+
+ /**
+ * Task created by this handler.
+ */
+ private Task task;
+
+ /**
+ * Wrapper for the parent element, if any. The wrapper for this
+ * element will be added to this wrapper as a child.
+ */
+ private RuntimeConfigurable parentWrapper;
+
+ /**
+ * Wrapper for this element which takes care of actually configuring
+ * the element, if this element is contained within a target.
+ * Otherwise the configuration is performed with the configure method.
+ * @see ProjectHelper#configure(Object,AttributeList,Project)
+ */
+ private RuntimeConfigurable wrapper = null;
+
+ /**
+ * Constructor.
+ *
+ * @param parentHandler The handler which should be restored to the
+ * parser at the end of the element.
+ * Must not be <code>null</code>.
+ *
+ * @param container Container for the element.
+ * Must not be <code>null</code>.
+ *
+ * @param parentWrapper Wrapper for the parent element, if any.
+ * May be <code>null</code>.
+ *
+ * @param target Target this element is part of.
+ * Must not be <code>null</code>.
+ */
+ public TaskHandler(ProjectHelperImpl helperImpl, DocumentHandler parentHandler,
+ TaskContainer container,
+ RuntimeConfigurable parentWrapper, Target target) {
+ super(helperImpl, parentHandler);
+ this.container = container;
+ this.parentWrapper = parentWrapper;
+ this.target = target;
+ }
+
+ /**
+ * Initialisation routine called after handler creation
+ * with the element name and attributes. This configures
+ * the element with its attributes and sets it up with
+ * its parent container (if any). Nested elements are then
+ * added later as the parser encounters them.
+ *
+ * @param tag Name of the element which caused this handler
+ * to be created. Must not be <code>null</code>.
+ *
+ * @param attrs Attributes of the element which caused this
+ * handler to be created. Must not be <code>null</code>.
+ *
+ * @exception SAXParseException in case of error (not thrown in
+ * this implementation)
+ */
+ public void init(String tag, AttributeList attrs) throws SAXParseException {
+ try {
+ task = helperImpl.project.createTask(tag);
+ } catch (BuildException e) {
+ // swallow here, will be thrown again in
+ // UnknownElement.maybeConfigure if the problem persists.
+ }
+ if (task == null) {
+ task = new UnknownElement(tag);
+ task.setProject(helperImpl.project);
+ //TODO task.setTaskType(tag);
+ task.setTaskName(tag);
+ }
+ task.setLocation(new Location(helperImpl.locator));
+ helperImpl.configureId(task, attrs);
+
+ task.setOwningTarget(target);
+ container.addTask(task);
+ task.init();
+ wrapper = task.getRuntimeConfigurableWrapper();
+ wrapper.setAttributes(attrs);
+ if (parentWrapper != null) {
+ parentWrapper.addChild(wrapper);
+ }
+ }
+
+ /**
+ * Adds text to the task, using the wrapper.
+ *
+ * @param buf A character array of the text within the element.
+ * Will not be <code>null</code>.
+ * @param start The start element in the array.
+ * @param count The number of characters to read from the array.
+ */
+ public void characters(char[] buf, int start, int count) {
+ wrapper.addText(buf, start, count);
+ }
+
+ /**
+ * Handles the start of an element within a target. Task containers
+ * will always use another task handler, and all other tasks
+ * will always use a nested element handler.
+ *
+ * @param name The name of the element being started.
+ * Will not be <code>null</code>.
+ * @param attrs Attributes of the element being started.
+ * Will not be <code>null</code>.
+ *
+ * @exception SAXParseException if an error occurs when initialising
+ * the appropriate child handler
+ */
+ public void startElement(String name, AttributeList attrs) throws SAXParseException {
+ if (task instanceof TaskContainer) {
+ // task can contain other tasks - no other nested elements possible
+ new TaskHandler(helperImpl, this, (TaskContainer) task, wrapper, target).init(name,
+ attrs);
+ } else {
+ new NestedElementHandler(helperImpl, this, task, wrapper, target).init(name, attrs);
+ }
+ }
+ }
+
+ /**
+ * Handler for all nested properties.
+ */
+ static class NestedElementHandler extends AbstractHandler {
+ /** Parent object (task/data type/etc). */
+ private Object parent;
+
+ /** The nested element itself. */
+ private Object child;
+
+ /**
+ * Wrapper for the parent element, if any. The wrapper for this
+ * element will be added to this wrapper as a child.
+ */
+ private RuntimeConfigurable parentWrapper;
+
+ /**
+ * Wrapper for this element which takes care of actually configuring
+ * the element, if a parent wrapper is provided.
+ * Otherwise the configuration is performed with the configure method.
+ * @see ProjectHelper#configure(Object,AttributeList,Project)
+ */
+ private RuntimeConfigurable childWrapper = null;
+
+ /** Target this element is part of, if any. */
+ private Target target;
+
+ /**
+ * Constructor.
+ *
+ * @param parentHandler The handler which should be restored to the
+ * parser at the end of the element.
+ * Must not be <code>null</code>.
+ *
+ * @param parent Parent of this element (task/data type/etc).
+ * Must not be <code>null</code>.
+ *
+ * @param parentWrapper Wrapper for the parent element, if any.
+ * Must not be <code>null</code>.
+ *
+ * @param target Target this element is part of.
+ * Must not be <code>null</code>.
+ */
+ public NestedElementHandler(ProjectHelperImpl helperImpl,
+ DocumentHandler parentHandler,
+ Object parent,
+ RuntimeConfigurable parentWrapper,
+ Target target) {
+ super(helperImpl, parentHandler);
+
+ if (parent instanceof TypeAdapter) {
+ this.parent = ((TypeAdapter) parent).getProxy();
+ } else {
+ this.parent = parent;
+ }
+ this.parentWrapper = parentWrapper;
+ this.target = target;
+ }
+
+ /**
+ * Initialisation routine called after handler creation
+ * with the element name and attributes. This configures
+ * the element with its attributes and sets it up with
+ * its parent container (if any). Nested elements are then
+ * added later as the parser encounters them.
+ *
+ * @param propType Name of the element which caused this handler
+ * to be created. Must not be <code>null</code>.
+ *
+ * @param attrs Attributes of the element which caused this
+ * handler to be created. Must not be <code>null</code>.
+ *
+ * @exception SAXParseException in case of error, such as a
+ * BuildException being thrown during configuration.
+ */
+ public void init(String propType, AttributeList attrs) throws SAXParseException {
+ Class<?> parentClass = parent.getClass();
+ IntrospectionHelper ih = IntrospectionHelper.getHelper(helperImpl.project, parentClass);
+
+ try {
+ String elementName = propType.toLowerCase(Locale.ENGLISH);
+ if (parent instanceof UnknownElement) {
+ UnknownElement uc = new UnknownElement(elementName);
+ uc.setProject(helperImpl.project);
+ ((UnknownElement) parent).addChild(uc);
+ child = uc;
+ } else {
+ child = ih.createElement(helperImpl.project, parent, elementName);
+ }
+ helperImpl.configureId(child, attrs);
+
+ childWrapper = new RuntimeConfigurable(child, propType);
+ childWrapper.setAttributes(attrs);
+ parentWrapper.addChild(childWrapper);
+ } catch (BuildException exc) {
+ throw new SAXParseException(exc.getMessage(), helperImpl.locator, exc);
+ }
+ }
+
+ /**
+ * Adds text to the element, using the wrapper.
+ *
+ * @param buf A character array of the text within the element.
+ * Will not be <code>null</code>.
+ * @param start The start element in the array.
+ * @param count The number of characters to read from the array.
+ */
+ public void characters(char[] buf, int start, int count) {
+ childWrapper.addText(buf, start, count);
+ }
+
+ /**
+ * Handles the start of an element within this one. Task containers
+ * will always use a task handler, and all other elements
+ * will always use another nested element handler.
+ *
+ * @param name The name of the element being started.
+ * Will not be <code>null</code>.
+ * @param attrs Attributes of the element being started.
+ * Will not be <code>null</code>.
+ *
+ * @exception SAXParseException if an error occurs when initialising
+ * the appropriate child handler
+ */
+ public void startElement(String name, AttributeList attrs) throws SAXParseException {
+ if (child instanceof TaskContainer) {
+ // taskcontainer nested element can contain other tasks - no other
+ // nested elements possible
+ new TaskHandler(helperImpl, this, (TaskContainer) child, childWrapper, target)
+ .init(name, attrs);
+ } else {
+ new NestedElementHandler(helperImpl, this, child, childWrapper, target).init(name,
+ attrs);
+ }
+ }
+ }
+
+ /**
+ * Handler for all data types directly subordinate to project or target.
+ */
+ static class DataTypeHandler extends AbstractHandler {
+ /** Parent target, if any. */
+ private Target target;
+
+ /** The element being configured. */
+ private Object element;
+
+ /** Wrapper for this element, if it's part of a target. */
+ private RuntimeConfigurable wrapper = null;
+
+ /**
+ * Constructor with a target specified.
+ *
+ * @param parentHandler The handler which should be restored to the
+ * parser at the end of the element.
+ * Must not be <code>null</code>.
+ *
+ * @param target The parent target of this element.
+ * Must not be <code>null</code>.
+ */
+ public DataTypeHandler(ProjectHelperImpl helperImpl, DocumentHandler parentHandler,
+ Target target) {
+ super(helperImpl, parentHandler);
+ this.target = target;
+ }
+
+ /**
+ * Initialisation routine called after handler creation
+ * with the element name and attributes. This configures
+ * the element with its attributes and sets it up with
+ * its parent container (if any). Nested elements are then
+ * added later as the parser encounters them.
+ *
+ * @param propType Name of the element which caused this handler
+ * to be created. Must not be <code>null</code>.
+ *
+ * @param attrs Attributes of the element which caused this
+ * handler to be created. Must not be <code>null</code>.
+ *
+ * @exception SAXParseException in case of error, such as a
+ * BuildException being thrown during configuration.
+ */
+ public void init(String propType, AttributeList attrs) throws SAXParseException {
+ try {
+ element = helperImpl.project.createDataType(propType);
+ if (element == null) {
+ throw new BuildException("Unknown data type " + propType);
+ }
+ wrapper = new RuntimeConfigurable(element, propType);
+ wrapper.setAttributes(attrs);
+ target.addDataType(wrapper);
+ } catch (BuildException exc) {
+ throw new SAXParseException(exc.getMessage(), helperImpl.locator, exc);
+ }
+ }
+
+ /**
+ * Adds text to the using the wrapper.
+ *
+ * @param buf A character array of the text within the element.
+ * Will not be <code>null</code>.
+ * @param start The start element in the array.
+ * @param count The number of characters to read from the array.
+ *
+ * @see ProjectHelper#addText(Project,Object,char[],int,int)
+ */
+ public void characters(char[] buf, int start, int count) {
+ wrapper.addText(buf, start, count);
+ }
+
+ /**
+ * Handles the start of an element within this one.
+ * This will always use a nested element handler.
+ *
+ * @param name The name of the element being started.
+ * Will not be <code>null</code>.
+ * @param attrs Attributes of the element being started.
+ * Will not be <code>null</code>.
+ *
+ * @exception SAXParseException if an error occurs when initialising
+ * the child handler
+ */
+ public void startElement(String name, AttributeList attrs) throws SAXParseException {
+ new NestedElementHandler(helperImpl, this, element, wrapper, target).init(name, attrs);
+ }
+ }
+
+ /**
+ * Scans an attribute list for the <code>id</code> attribute and
+ * stores a reference to the target object in the project if an
+ * id is found.
+ * <p>
+ * This method was moved out of the configure method to allow
+ * it to be executed at parse time.
+ *
+ * @see #configure(Object,AttributeList,Project)
+ */
+ private void configureId(Object target, AttributeList attr) {
+ String id = attr.getValue("id");
+ if (id != null) {
+ project.addReference(id, target);
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/helper/SingleCheckExecutor.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/helper/SingleCheckExecutor.java
new file mode 100644
index 00000000..1960ed03
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/helper/SingleCheckExecutor.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.helper;
+
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Executor;
+import org.apache.tools.ant.Project;
+
+
+/**
+ * "Single-check" Target executor implementation.
+ * Differs from {@link DefaultExecutor} in that the dependencies for all
+ * targets are computed together, so that shared dependencies are run just once.
+ * @since Ant 1.6.3
+ */
+public class SingleCheckExecutor implements Executor {
+
+ /** {@inheritDoc}. */
+ public void executeTargets(Project project, String[] targetNames)
+ throws BuildException {
+ project.executeSortedTargets(
+ project.topoSort(targetNames, project.getTargets(), false));
+ }
+
+ /** {@inheritDoc}. */
+ public Executor getSubProjectExecutor() {
+ return this;
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/input/DefaultInputHandler.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/input/DefaultInputHandler.java
new file mode 100644
index 00000000..8268d5e7
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/input/DefaultInputHandler.java
@@ -0,0 +1,120 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.input;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.util.KeepAliveInputStream;
+
+/**
+ * Prompts on System.err, reads input from System.in
+ *
+ * @since Ant 1.5
+ */
+public class DefaultInputHandler implements InputHandler {
+
+ /**
+ * Empty no-arg constructor
+ */
+ public DefaultInputHandler() {
+ }
+
+ /**
+ * Prompts and requests input. May loop until a valid input has
+ * been entered.
+ * @param request the request to handle
+ * @throws BuildException if not possible to read from console
+ */
+ public void handleInput(InputRequest request) throws BuildException {
+ String prompt = getPrompt(request);
+ BufferedReader r = null;
+ try {
+ r = new BufferedReader(new InputStreamReader(getInputStream()));
+ do {
+ System.err.println(prompt);
+ System.err.flush();
+ try {
+ String input = r.readLine();
+ request.setInput(input);
+ } catch (IOException e) {
+ throw new BuildException("Failed to read input from"
+ + " Console.", e);
+ }
+ } while (!request.isInputValid());
+ } finally {
+ if (r != null) {
+ try {
+ r.close();
+ } catch (IOException e) {
+ throw new BuildException("Failed to close input.", e);
+ }
+ }
+ }
+ }
+
+ /**
+ * Constructs user prompt from a request.
+ *
+ * <p>This implementation adds (choice1,choice2,choice3,...) to the
+ * prompt for <code>MultipleChoiceInputRequest</code>s.</p>
+ *
+ * @param request the request to construct the prompt for.
+ * Must not be <code>null</code>.
+ * @return the prompt to ask the user
+ */
+ protected String getPrompt(InputRequest request) {
+ String prompt = request.getPrompt();
+ String def = request.getDefaultValue();
+ if (request instanceof MultipleChoiceInputRequest) {
+ StringBuilder sb = new StringBuilder(prompt).append(" (");
+ boolean first = true;
+ for (String next : ((MultipleChoiceInputRequest) request).getChoices()) {
+ if (!first) {
+ sb.append(", ");
+ }
+ if (next.equals(def)) {
+ sb.append('[');
+ }
+ sb.append(next);
+ if (next.equals(def)) {
+ sb.append(']');
+ }
+ first = false;
+ }
+ sb.append(")");
+ return sb.toString();
+ } else if (def != null) {
+ return prompt + " [" + def + "]";
+ } else {
+ return prompt;
+ }
+ }
+
+ /**
+ * Returns the input stream from which the user input should be read.
+ * @return the input stream from which the user input should be read.
+ */
+ protected InputStream getInputStream() {
+ return KeepAliveInputStream.wrapSystemIn();
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/input/GreedyInputHandler.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/input/GreedyInputHandler.java
new file mode 100644
index 00000000..cb52f4f0
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/input/GreedyInputHandler.java
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.input;
+
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.taskdefs.StreamPumper;
+import org.apache.tools.ant.util.FileUtils;
+
+/**
+ * Prompts on System.err, reads input from System.in until EOF
+ *
+ * @since Ant 1.7
+ */
+public class GreedyInputHandler extends DefaultInputHandler {
+
+ /**
+ * Empty no-arg constructor
+ */
+ public GreedyInputHandler() {
+ }
+
+ /**
+ * Prompts and requests input.
+ * @param request the request to handle
+ * @throws BuildException if not possible to read from console,
+ * or if input is invalid.
+ */
+ public void handleInput(InputRequest request) throws BuildException {
+ String prompt = getPrompt(request);
+ InputStream in = null;
+ try {
+ in = getInputStream();
+ System.err.println(prompt);
+ System.err.flush();
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ StreamPumper p = new StreamPumper(in, baos);
+ Thread t = new Thread(p);
+ t.start();
+ try {
+ t.join();
+ } catch (InterruptedException e) {
+ try {
+ t.join();
+ } catch (InterruptedException e2) {
+ // Ignore
+ }
+ }
+ request.setInput(new String(baos.toByteArray()));
+ if (!(request.isInputValid())) {
+ throw new BuildException(
+ "Received invalid console input");
+ }
+ if (p.getException() != null) {
+ throw new BuildException(
+ "Failed to read input from console", p.getException());
+ }
+ } finally {
+ FileUtils.close(in);
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/input/InputHandler.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/input/InputHandler.java
new file mode 100644
index 00000000..aea60fcc
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/input/InputHandler.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.input;
+
+/**
+ * Plugin to Ant to handle requests for user input.
+ *
+ * @since Ant 1.5
+ */
+public interface InputHandler {
+
+ /**
+ * Handle the request encapsulated in the argument.
+ *
+ * <p>Precondition: the request.getPrompt will return a non-null
+ * value.</p>
+ *
+ * <p>Postcondition: request.getInput will return a non-null
+ * value, request.isInputValid will return true.</p>
+ * @param request the request to be processed
+ * @throws org.apache.tools.ant.BuildException if the input cannot be read from the console
+ */
+ void handleInput(InputRequest request)
+ throws org.apache.tools.ant.BuildException;
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/input/InputRequest.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/input/InputRequest.java
new file mode 100644
index 00000000..57a77da2
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/input/InputRequest.java
@@ -0,0 +1,93 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.input;
+
+/**
+ * Encapsulates an input request.
+ *
+ * @since Ant 1.5
+ */
+public class InputRequest {
+ private final String prompt;
+ private String input;
+ private String defaultValue;
+
+ /**
+ * Construct an InputRequest.
+ * @param prompt The prompt to show to the user. Must not be null.
+ */
+ public InputRequest(String prompt) {
+ if (prompt == null) {
+ throw new IllegalArgumentException("prompt must not be null");
+ }
+
+ this.prompt = prompt;
+ }
+
+ /**
+ * Retrieves the prompt text.
+ * @return the prompt.
+ */
+ public String getPrompt() {
+ return prompt;
+ }
+
+ /**
+ * Sets the user provided input.
+ * @param input the string to be used for input.
+ */
+ public void setInput(String input) {
+ this.input = input;
+ }
+
+ /**
+ * Is the user input valid?
+ * @return true if it is.
+ */
+ public boolean isInputValid() {
+ return true;
+ }
+
+ /**
+ * Retrieves the user input.
+ * @return the user input.
+ */
+ public String getInput() {
+ return input;
+ }
+
+ /**
+ * Gets a configured default value.
+ * @return the default value.
+ * @since Ant 1.7.0
+ */
+ public String getDefaultValue() {
+ return defaultValue;
+ }
+
+ /**
+ * Configures a default value.
+ * @param d the value to set.
+ * @since Ant 1.7.0
+ */
+ public void setDefaultValue(String d) {
+ defaultValue = d;
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/input/MultipleChoiceInputRequest.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/input/MultipleChoiceInputRequest.java
new file mode 100644
index 00000000..4baab8f5
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/input/MultipleChoiceInputRequest.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.input;
+
+import java.util.LinkedHashSet;
+import java.util.Vector;
+
+/**
+ * Encapsulates an input request.
+ *
+ * @since Ant 1.5
+ */
+public class MultipleChoiceInputRequest extends InputRequest {
+ private final LinkedHashSet<String> choices;
+
+ /**
+ * @param prompt The prompt to show to the user. Must not be null.
+ * @param choices holds all input values that are allowed.
+ * Must not be null.
+ */
+ public MultipleChoiceInputRequest(String prompt, Vector<String> choices) {
+ super(prompt);
+ if (choices == null) {
+ throw new IllegalArgumentException("choices must not be null");
+ }
+ this.choices = new LinkedHashSet<String>(choices);
+ }
+
+ /**
+ * @return The possible values.
+ */
+ public Vector<String> getChoices() {
+ return new Vector<String>(choices);
+ }
+
+ /**
+ * @return true if the input is one of the allowed values.
+ */
+ public boolean isInputValid() {
+ return choices.contains(getInput()) || ("".equals(getInput()) && getDefaultValue() != null);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/input/PropertyFileInputHandler.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/input/PropertyFileInputHandler.java
new file mode 100644
index 00000000..e1e3cf11
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/input/PropertyFileInputHandler.java
@@ -0,0 +1,92 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.input;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.Properties;
+
+import org.apache.tools.ant.BuildException;
+
+/**
+ * Reads input from a property file, the file name is read from the
+ * system property ant.input.properties, the prompt is the key for input.
+ *
+ * @since Ant 1.5
+ */
+public class PropertyFileInputHandler implements InputHandler {
+ private Properties props = null;
+
+ /**
+ * Name of the system property we expect to hold the file name.
+ */
+ public static final String FILE_NAME_KEY = "ant.input.properties";
+
+ /**
+ * Empty no-arg constructor.
+ */
+ public PropertyFileInputHandler() {
+ }
+
+ /**
+ * Picks up the input from a property, using the prompt as the
+ * name of the property.
+ * @param request an input request.
+ *
+ * @exception BuildException if no property of that name can be found.
+ */
+ public void handleInput(InputRequest request) throws BuildException {
+ readProps();
+
+ Object o = props.get(request.getPrompt());
+ if (o == null) {
+ throw new BuildException("Unable to find input for \'"
+ + request.getPrompt() + "\'");
+ }
+ request.setInput(o.toString());
+ if (!request.isInputValid()) {
+ throw new BuildException("Found invalid input " + o
+ + " for \'" + request.getPrompt() + "\'");
+ }
+ }
+
+ /**
+ * Reads the properties file if it hasn't already been read.
+ */
+ private synchronized void readProps() throws BuildException {
+ if (props == null) {
+ String propsFile = System.getProperty(FILE_NAME_KEY);
+ if (propsFile == null) {
+ throw new BuildException("System property "
+ + FILE_NAME_KEY
+ + " for PropertyFileInputHandler not"
+ + " set");
+ }
+
+ props = new Properties();
+
+ try {
+ props.load(new FileInputStream(propsFile));
+ } catch (IOException e) {
+ throw new BuildException("Couldn't load " + propsFile, e);
+ }
+ }
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/input/SecureInputHandler.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/input/SecureInputHandler.java
new file mode 100644
index 00000000..d5aecff7
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/input/SecureInputHandler.java
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.input;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.util.ReflectUtil;
+
+/**
+ * Prompts and requests input. May loop until a valid input has
+ * been entered. Doesn't echo input (requires Java6). If Java6 is not
+ * available, falls back to the DefaultHandler (insecure).
+ * @since Ant 1.7.1
+ */
+public class SecureInputHandler extends DefaultInputHandler {
+
+ /**
+ * Default no-args constructor
+ */
+ public SecureInputHandler() {
+ }
+
+ /**
+ * Handle the input
+ * @param request the request to handle
+ * @throws BuildException if not possible to read from console
+ */
+ public void handleInput(InputRequest request) throws BuildException {
+ String prompt = getPrompt(request);
+ try {
+ Object console = ReflectUtil.invokeStatic(System.class, "console");
+ do {
+ char[] input = (char[]) ReflectUtil.invoke(
+ console, "readPassword", String.class, prompt,
+ Object[].class, (Object[]) null);
+ request.setInput(new String(input));
+ /* for security zero char array after retrieving value */
+ java.util.Arrays.fill(input, ' ');
+ } while (!request.isInputValid());
+ } catch (Exception e) {
+ /* Java6 not present use default handler */
+ super.handleInput(request);
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/launch/AntMain.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/launch/AntMain.java
new file mode 100644
index 00000000..4703eaa6
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/launch/AntMain.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.launch;
+
+import java.util.Properties;
+
+/**
+ * Interface used to bridge to the actual Main class without any
+ * messy reflection
+ *
+ * @since Ant 1.6
+ */
+public interface AntMain {
+ /**
+ * Start Ant.
+ *
+ * @param args command line args
+ * @param additionalUserProperties properties to set beyond those that
+ * may be specified on the args list
+ * @param coreLoader - not used
+ *
+ * @since Ant 1.6
+ */
+ void startAnt(String[] args, Properties additionalUserProperties,
+ ClassLoader coreLoader);
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/launch/LaunchException.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/launch/LaunchException.java
new file mode 100644
index 00000000..1bb37f8f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/launch/LaunchException.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.launch;
+
+/**
+ * Signals an error condition during launching
+ *
+ * @since Ant 1.6
+ */
+public class LaunchException extends Exception {
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Constructs an exception with the given descriptive message.
+ *
+ * @param message A description of or information about the exception.
+ * Should not be <code>null</code>.
+ */
+ public LaunchException(String message) {
+ super(message);
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/launch/Launcher.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/launch/Launcher.java
new file mode 100644
index 00000000..bf881db8
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/launch/Launcher.java
@@ -0,0 +1,412 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.launch;
+
+import java.io.File;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.StringTokenizer;
+
+
+
+
+/**
+ * This is a launcher for Ant.
+ *
+ * @since Ant 1.6
+ */
+public class Launcher {
+
+ private Launcher() {
+ }
+
+ /**
+ * The Ant Home (installation) Directory property.
+ * {@value}
+ */
+ public static final String ANTHOME_PROPERTY = "ant.home";
+
+ /**
+ * The Ant Library Directory property.
+ * {@value}
+ */
+ public static final String ANTLIBDIR_PROPERTY = "ant.library.dir";
+
+ /**
+ * The directory name of the per-user ant directory.
+ * {@value}
+ */
+ public static final String ANT_PRIVATEDIR = ".ant";
+
+ /**
+ * The name of a per-user library directory.
+ * {@value}
+ */
+ public static final String ANT_PRIVATELIB = "lib";
+
+ /**
+ * launch diagnostics flag; for debugging trouble at launch time.
+ */
+ public static boolean launchDiag = false;
+
+ /**
+ * The location of a per-user library directory.
+ * <p>
+ * It's value is the concatenation of {@link #ANT_PRIVATEDIR}
+ * with {@link #ANT_PRIVATELIB}, with an appropriate file separator
+ * in between. For example, on Unix, it's <code>.ant/lib</code>.
+ */
+ public static final String USER_LIBDIR =
+ ANT_PRIVATEDIR + File.separatorChar + ANT_PRIVATELIB;
+
+ /**
+ * The startup class that is to be run.
+ * {@value}
+ */
+ public static final String MAIN_CLASS = "org.apache.tools.ant.Main";
+
+ /**
+ * System property with user home directory.
+ * {@value}
+ */
+ public static final String USER_HOMEDIR = "user.home";
+
+ /**
+ * System property with application classpath.
+ * {@value}
+ */
+ private static final String JAVA_CLASS_PATH = "java.class.path";
+
+ /**
+ * Exit code on trouble
+ */
+ protected static final int EXIT_CODE_ERROR = 2;
+
+ /**
+ * Entry point for starting command line Ant.
+ *
+ * @param args commandline arguments
+ */
+ public static void main(final String[] args) {
+ int exitCode;
+ try {
+ final Launcher launcher = new Launcher();
+ exitCode = launcher.run(args);
+ } catch (final LaunchException e) {
+ exitCode = EXIT_CODE_ERROR;
+ System.err.println(e.getMessage());
+ } catch (final Throwable t) {
+ exitCode = EXIT_CODE_ERROR;
+ t.printStackTrace(System.err);
+ }
+ if (exitCode != 0) {
+ if (launchDiag) {
+ System.out.println("Exit code: "+exitCode);
+ }
+ System.exit(exitCode);
+ }
+ }
+
+
+ /**
+ * Add a CLASSPATH or -lib to lib path urls.
+ * Only filesystem resources are supported.
+ *
+ * @param path the classpath or lib path to add to the libPathULRLs
+ * @param getJars if true and a path is a directory, add the jars in
+ * the directory to the path urls
+ * @param libPathURLs the list of paths to add to
+ * @throws MalformedURLException if we can't create a URL
+ */
+ private void addPath(final String path, final boolean getJars, final List<URL> libPathURLs)
+ throws MalformedURLException {
+ final StringTokenizer tokenizer = new StringTokenizer(path, File.pathSeparator);
+ while (tokenizer.hasMoreElements()) {
+ final String elementName = tokenizer.nextToken();
+ final File element = new File(elementName);
+ if (elementName.indexOf('%') != -1 && !element.exists()) {
+ continue;
+ }
+ if (getJars && element.isDirectory()) {
+ // add any jars in the directory
+ final URL[] dirURLs = Locator.getLocationURLs(element);
+ for (int j = 0; j < dirURLs.length; ++j) {
+ if (launchDiag) { System.out.println("adding library JAR: " + dirURLs[j]);}
+ libPathURLs.add(dirURLs[j]);
+ }
+ }
+
+ final URL url = Locator.fileToURL(element);
+ if (launchDiag) {
+ System.out.println("adding library URL: " + url);
+ }
+ libPathURLs.add(url);
+ }
+ }
+
+ /**
+ * Run the launcher to launch Ant.
+ *
+ * @param args the command line arguments
+ * @return an exit code. As the normal ant main calls exit when it ends,
+ * this is for handling failures at bind-time
+ * @throws MalformedURLException if the URLs required for the classloader
+ * cannot be created.
+ * @throws LaunchException for launching problems
+ */
+ private int run(final String[] args)
+ throws LaunchException, MalformedURLException {
+ final String antHomeProperty = System.getProperty(ANTHOME_PROPERTY);
+ File antHome = null;
+
+ final File sourceJar = Locator.getClassSource(getClass());
+ final File jarDir = sourceJar.getParentFile();
+ String mainClassname = MAIN_CLASS;
+
+ if (antHomeProperty != null) {
+ antHome = new File(antHomeProperty);
+ }
+
+ if (antHome == null || !antHome.exists()) {
+ antHome = jarDir.getParentFile();
+ setProperty(ANTHOME_PROPERTY, antHome.getAbsolutePath());
+ }
+
+ if (!antHome.exists()) {
+ throw new LaunchException("Ant home is set incorrectly or "
+ + "ant could not be located (estimated value="+antHome.getAbsolutePath()+")");
+ }
+
+ final List<String> libPaths = new ArrayList<String>();
+ String cpString = null;
+ final List<String> argList = new ArrayList<String>();
+ String[] newArgs;
+ boolean noUserLib = false;
+ boolean noClassPath = false;
+
+ for (int i = 0; i < args.length; ++i) {
+ if (args[i].equals("-lib")) {
+ if (i == args.length - 1) {
+ throw new LaunchException("The -lib argument must "
+ + "be followed by a library location");
+ }
+ libPaths.add(args[++i]);
+ } else if (args[i].equals("-cp")) {
+ if (i == args.length - 1) {
+ throw new LaunchException("The -cp argument must "
+ + "be followed by a classpath expression");
+ }
+ if (cpString != null) {
+ throw new LaunchException("The -cp argument must "
+ + "not be repeated");
+ }
+ cpString = args[++i];
+ } else if (args[i].equals("--nouserlib") || args[i].equals("-nouserlib")) {
+ noUserLib = true;
+ } else if (args[i].equals("--launchdiag")) {
+ launchDiag = true;
+ } else if (args[i].equals("--noclasspath") || args[i].equals("-noclasspath")) {
+ noClassPath = true;
+ } else if (args[i].equals("-main")) {
+ if (i == args.length - 1) {
+ throw new LaunchException("The -main argument must "
+ + "be followed by a library location");
+ }
+ mainClassname = args[++i];
+ } else {
+ argList.add(args[i]);
+ }
+ }
+
+ logPath("Launcher JAR",sourceJar);
+ logPath("Launcher JAR directory", sourceJar.getParentFile());
+ logPath("java.home", new File(System.getProperty("java.home")));
+
+ //decide whether to copy the existing arg set, or
+ //build a new one from the list of all args excluding the special
+ //operations that only we handle
+ if (argList.size() == args.length) {
+ newArgs = args;
+ } else {
+ newArgs = argList.toArray(new String[argList.size()]);
+ }
+
+ final URL[] libURLs = getLibPathURLs(
+ noClassPath ? null : cpString, libPaths);
+ final URL[] systemURLs = getSystemURLs(jarDir);
+ final URL[] userURLs = noUserLib ? new URL[0] : getUserURLs();
+
+ final File toolsJAR = Locator.getToolsJar();
+ logPath("tools.jar",toolsJAR);
+ final URL[] jars = getJarArray(
+ libURLs, userURLs, systemURLs, toolsJAR);
+
+ // now update the class.path property
+ final StringBuffer baseClassPath
+ = new StringBuffer(System.getProperty(JAVA_CLASS_PATH));
+ if (baseClassPath.charAt(baseClassPath.length() - 1)
+ == File.pathSeparatorChar) {
+ baseClassPath.setLength(baseClassPath.length() - 1);
+ }
+
+ for (int i = 0; i < jars.length; ++i) {
+ baseClassPath.append(File.pathSeparatorChar);
+ baseClassPath.append(Locator.fromURI(jars[i].toString()));
+ }
+
+ setProperty(JAVA_CLASS_PATH, baseClassPath.toString());
+
+ final URLClassLoader loader = new URLClassLoader(jars, Launcher.class.getClassLoader());
+ Thread.currentThread().setContextClassLoader(loader);
+ Class<?> mainClass = null;
+ int exitCode = 0;
+ Throwable thrown=null;
+ try {
+ mainClass = loader.loadClass(mainClassname);
+ final AntMain main = (AntMain) mainClass.newInstance();
+ main.startAnt(newArgs, null, null);
+ } catch (final InstantiationException ex) {
+ System.err.println(
+ "Incompatible version of " + mainClassname + " detected");
+ final File mainJar = Locator.getClassSource(mainClass);
+ System.err.println(
+ "Location of this class " + mainJar);
+ thrown = ex;
+ } catch (final ClassNotFoundException cnfe) {
+ System.err.println(
+ "Failed to locate" + mainClassname);
+ thrown = cnfe;
+ } catch (final Throwable t) {
+ t.printStackTrace(System.err);
+ thrown=t;
+ }
+ if(thrown!=null) {
+ System.err.println(ANTHOME_PROPERTY+": "+antHome.getAbsolutePath());
+ System.err.println("Classpath: " + baseClassPath.toString());
+ System.err.println("Launcher JAR: " + sourceJar.getAbsolutePath());
+ System.err.println("Launcher Directory: " + jarDir.getAbsolutePath());
+ exitCode = EXIT_CODE_ERROR;
+ }
+ return exitCode;
+ }
+
+ /**
+ * Get the list of -lib entries and -cp entry into
+ * a URL array.
+ * @param cpString the classpath string
+ * @param libPaths the list of -lib entries.
+ * @return an array of URLs.
+ * @throws MalformedURLException if the URLs cannot be created.
+ */
+ private URL[] getLibPathURLs(final String cpString, final List<String> libPaths)
+ throws MalformedURLException {
+ final List<URL> libPathURLs = new ArrayList<URL>();
+
+ if (cpString != null) {
+ addPath(cpString, false, libPathURLs);
+ }
+
+ for (final String libPath : libPaths) {
+ addPath(libPath, true, libPathURLs);
+ }
+
+ return libPathURLs.toArray(new URL[libPathURLs.size()]);
+ }
+
+ /**
+ * Get the jar files in ANT_HOME/lib.
+ * determine ant library directory for system jars: use property
+ * or default using location of ant-launcher.jar
+ * @param antLauncherDir the dir that ant-launcher ran from
+ * @return the URLs
+ * @throws MalformedURLException if the URLs cannot be created.
+ */
+ private URL[] getSystemURLs(final File antLauncherDir) throws MalformedURLException {
+ File antLibDir = null;
+ final String antLibDirProperty = System.getProperty(ANTLIBDIR_PROPERTY);
+ if (antLibDirProperty != null) {
+ antLibDir = new File(antLibDirProperty);
+ }
+ if ((antLibDir == null) || !antLibDir.exists()) {
+ antLibDir = antLauncherDir;
+ setProperty(ANTLIBDIR_PROPERTY, antLibDir.getAbsolutePath());
+ }
+ return Locator.getLocationURLs(antLibDir);
+ }
+
+ /**
+ * Get the jar files in user.home/.ant/lib
+ * @return the URLS from the user's lib dir
+ * @throws MalformedURLException if the URLs cannot be created.
+ */
+ private URL[] getUserURLs() throws MalformedURLException {
+ final File userLibDir
+ = new File(System.getProperty(USER_HOMEDIR), USER_LIBDIR);
+
+ return Locator.getLocationURLs(userLibDir);
+ }
+
+ /**
+ * Combine the various jar sources into a single array of jars.
+ * @param libJars the jars specified in -lib command line options
+ * @param userJars the jars in ~/.ant/lib
+ * @param systemJars the jars in $ANT_HOME/lib
+ * @param toolsJar the tools.jar file
+ * @return a combined array
+ * @throws MalformedURLException if there is a problem.
+ */
+ private URL[] getJarArray (
+ final URL[] libJars, final URL[] userJars, final URL[] systemJars, final File toolsJar)
+ throws MalformedURLException {
+ int numJars = libJars.length + userJars.length + systemJars.length;
+ if (toolsJar != null) {
+ numJars++;
+ }
+ final URL[] jars = new URL[numJars];
+ System.arraycopy(libJars, 0, jars, 0, libJars.length);
+ System.arraycopy(userJars, 0, jars, libJars.length, userJars.length);
+ System.arraycopy(systemJars, 0, jars, userJars.length + libJars.length,
+ systemJars.length);
+
+ if (toolsJar != null) {
+ jars[jars.length - 1] = Locator.fileToURL(toolsJar);
+ }
+ return jars;
+ }
+
+ /**
+ * set a system property, optionally log what is going on
+ * @param name property name
+ * @param value value
+ */
+ private void setProperty(final String name, final String value) {
+ if (launchDiag) {
+ System.out.println("Setting \"" + name + "\" to \"" + value + "\"");
+ }
+ System.setProperty(name, value);
+ }
+
+ private void logPath(final String name,final File path) {
+ if(launchDiag) {
+ System.out.println(name+"= \""+path+"\"");
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/launch/Locator.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/launch/Locator.java
new file mode 100644
index 00000000..4640e700
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/launch/Locator.java
@@ -0,0 +1,528 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.launch;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FilenameFilter;
+import java.io.UnsupportedEncodingException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.text.CharacterIterator;
+import java.text.StringCharacterIterator;
+import java.util.Locale;
+
+// CheckStyle:LineLengthCheck OFF - urls are long!
+/**
+ * The Locator is a utility class which is used to find certain items
+ * in the environment.
+ * <p>
+ * It is used at boot time in the launcher, and cannot make use of any of Ant's other classes.
+ * <p>
+ * This is a surprisingly brittle piece of code, and has had lots of bugs filed against it:
+ * <a href="http://issues.apache.org/bugzilla/show_bug.cgi?id=42275">running ant off a network share can cause Ant to fail</a>,
+ * <a href="http://issues.apache.org/bugzilla/show_bug.cgi?id=8031">use File.toURI().toURL().toExternalForm()</a>,
+ * <a href="http://issues.apache.org/bugzilla/show_bug.cgi?id=42222">Locator implementation not encoding URI strings properly: spaces in paths</a>.
+ * It also breaks Eclipse 3.3 Betas:
+ * <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=183283">Exception if installation path has spaces</a>.
+ * <p>
+ * Be very careful when making changes to this class, as a break will upset a lot of people.
+ * @since Ant 1.6
+ */
+// CheckStyle:LineLengthCheck ON - urls are long!
+public final class Locator {
+
+ private static final int NIBBLE = 4;
+ private static final int NIBBLE_MASK = 0xF;
+
+ private static final int ASCII_SIZE = 128;
+
+ private static final int BYTE_SIZE = 256;
+
+ private static final int WORD = 16;
+
+ private static final int SPACE = 0x20;
+ private static final int DEL = 0x7F;
+
+ /**
+ * encoding used to represent URIs
+ */
+ public static final String URI_ENCODING = "UTF-8";
+ // stolen from org.apache.xerces.impl.XMLEntityManager#getUserDir()
+ // of the Xerces-J team
+ // which ASCII characters need to be escaped
+ private static boolean[] gNeedEscaping = new boolean[ASCII_SIZE];
+ // the first hex character if a character needs to be escaped
+ private static char[] gAfterEscaping1 = new char[ASCII_SIZE];
+ // the second hex character if a character needs to be escaped
+ private static char[] gAfterEscaping2 = new char[ASCII_SIZE];
+ private static char[] gHexChs = {'0', '1', '2', '3', '4', '5', '6', '7',
+ '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
+ /** Error string used when an invalid uri is seen */
+ public static final String ERROR_NOT_FILE_URI
+ = "Can only handle valid file: URIs, not ";
+
+ // initialize the above 3 arrays
+ static {
+ for (int i = 0; i < SPACE; i++) {
+ gNeedEscaping[i] = true;
+ gAfterEscaping1[i] = gHexChs[i >> NIBBLE];
+ gAfterEscaping2[i] = gHexChs[i & NIBBLE_MASK];
+ }
+ gNeedEscaping[DEL] = true;
+ gAfterEscaping1[DEL] = '7';
+ gAfterEscaping2[DEL] = 'F';
+ char[] escChs = {' ', '<', '>', '#', '%', '"', '{', '}',
+ '|', '\\', '^', '~', '[', ']', '`'};
+ int len = escChs.length;
+ char ch;
+ for (int i = 0; i < len; i++) {
+ ch = escChs[i];
+ gNeedEscaping[ch] = true;
+ gAfterEscaping1[ch] = gHexChs[ch >> NIBBLE];
+ gAfterEscaping2[ch] = gHexChs[ch & NIBBLE_MASK];
+ }
+ }
+ /**
+ * Not instantiable
+ */
+ private Locator() {
+ }
+
+ /**
+ * Find the directory or jar file the class has been loaded from.
+ *
+ * @param c the class whose location is required.
+ * @return the file or jar with the class or null if we cannot
+ * determine the location.
+ *
+ * @since Ant 1.6
+ */
+ public static File getClassSource(Class<?> c) {
+ String classResource = c.getName().replace('.', '/') + ".class";
+ return getResourceSource(c.getClassLoader(), classResource);
+ }
+
+ /**
+ * Find the directory or jar a given resource has been loaded from.
+ *
+ * @param c the classloader to be consulted for the source.
+ * @param resource the resource whose location is required.
+ *
+ * @return the file with the resource source or null if
+ * we cannot determine the location.
+ *
+ * @since Ant 1.6
+ */
+ public static File getResourceSource(ClassLoader c, String resource) {
+ if (c == null) {
+ c = Locator.class.getClassLoader();
+ }
+ URL url = null;
+ if (c == null) {
+ url = ClassLoader.getSystemResource(resource);
+ } else {
+ url = c.getResource(resource);
+ }
+ if (url != null) {
+ String u = url.toString();
+ try {
+ if (u.startsWith("jar:file:")) {
+ return new File(fromJarURI(u));
+ } else if (u.startsWith("file:")) {
+ int tail = u.indexOf(resource);
+ String dirName = u.substring(0, tail);
+ return new File(fromURI(dirName));
+ }
+ } catch (IllegalArgumentException e) {
+ //unable to determine the URI for reasons unknown.
+ return null;
+ }
+ }
+ return null;
+ }
+
+
+
+ /**
+ * Constructs a file path from a <code>file:</code> URI.
+ *
+ * <p>Will be an absolute path if the given URI is absolute.</p>
+ *
+ * <p>Prior to Java 1.4,<!-- TODO is JDK version actually relevant? -->
+ * swallows '%' that are not followed by two characters.</p>
+ *
+ * See <a href="http://www.w3.org/TR/xml11/#dt-sysid">dt-sysid</a>
+ * which makes some mention of how
+ * characters not supported by URI Reference syntax should be escaped.
+ *
+ * @param uri the URI designating a file in the local filesystem.
+ * @return the local file system path for the file.
+ * @throws IllegalArgumentException if the URI is malformed or not a legal file: URL
+ * @since Ant 1.6
+ */
+ public static String fromURI(String uri) {
+ return fromURIJava13(uri);
+ // #buzilla8031: first try Java 1.4.
+ // TODO should use java.net.URI now that we can rely on 1.4...
+ // but check for UNC-related regressions, e.g. #42275
+ // (and remember that \\server\share\file -> file:////server/share/file
+ // rather than -> file://server/share/file as it should;
+ // fixed only in JDK 7's java.nio.file.Path.toUri)
+ // return fromUriJava14(uri);
+ }
+
+ /**
+ * Java1.4+ code to extract the path from the URI.
+ * @param uri
+ * @return null if a conversion was not possible
+ */
+ /* currently unused:
+ private static String fromUriJava14(String uri) {
+ // Also check for properly formed URIs. Ant formerly recommended using
+ // nonsense URIs such as "file:./foo.xml" in XML includes. You shouldn't
+ // do that (just "foo.xml" is correct) but for compatibility we special-case
+ // things when the path is not absolute, and fall back to the old parsing behavior.
+ if (uri.startsWith("file:/")) {
+ try {
+ File f = new File(URI.create(encodeURI(uri)));
+ //bug #42227 forgot to decode before returning
+ return decodeUri(f.getAbsolutePath());
+ } catch (IllegalArgumentException e) {
+ // Bad URI, pass this on.
+ // no, this is downgraded to a warning after various
+ // JRE bugs surfaced. Hand off
+ // to our built in code on a failure
+ //throw new IllegalArgumentException(
+ // "Bad URI " + uri + ":" + e.getMessage(), e);
+ e.printStackTrace();
+ } catch (Exception e) {
+ // Unexpected exception? Should not happen.
+ e.printStackTrace();
+ }
+ }
+ return null;
+ }
+ */
+
+ /**
+ * @param uri uri to expand
+ * @return the decoded URI
+ * @since Ant1.7.1
+ */
+ private static String fromURIJava13(String uri) {
+ // Fallback method for Java 1.3 or earlier.
+
+ URL url = null;
+ try {
+ url = new URL(uri);
+ } catch (MalformedURLException emYouEarlEx) {
+ // Ignore malformed exception
+ }
+ if (url == null || !("file".equals(url.getProtocol()))) {
+ throw new IllegalArgumentException(ERROR_NOT_FILE_URI + uri);
+ }
+ StringBuffer buf = new StringBuffer(url.getHost());
+ if (buf.length() > 0) {
+ buf.insert(0, File.separatorChar).insert(0, File.separatorChar);
+ }
+ String file = url.getFile();
+ int queryPos = file.indexOf('?');
+ buf.append((queryPos < 0) ? file : file.substring(0, queryPos));
+
+ uri = buf.toString().replace('/', File.separatorChar);
+
+ if (File.pathSeparatorChar == ';' && uri.startsWith("\\") && uri.length() > 2
+ && Character.isLetter(uri.charAt(1)) && uri.lastIndexOf(':') > -1) {
+ uri = uri.substring(1);
+ }
+ String path = null;
+ try {
+ path = decodeUri(uri);
+ //consider adding the current directory. This is not done when
+ //the path is a UNC name
+ String cwd = System.getProperty("user.dir");
+ int posi = cwd.indexOf(':');
+ boolean pathStartsWithFileSeparator = path.startsWith(File.separator);
+ boolean pathStartsWithUNC = path.startsWith("" + File.separator + File.separator);
+ if ((posi > 0) && pathStartsWithFileSeparator && !pathStartsWithUNC) {
+ path = cwd.substring(0, posi + 1) + path;
+ }
+ } catch (UnsupportedEncodingException exc) {
+ // not sure whether this is clean, but this method is
+ // declared not to throw exceptions.
+ throw new IllegalStateException(
+ "Could not convert URI " + uri + " to path: "
+ + exc.getMessage());
+ }
+ return path;
+ }
+
+ /**
+ * Crack a JAR URI.
+ * This method is public for testing; we may delete it without any warning -it is not part of Ant's stable API.
+ * @param uri uri to expand; contains jar: somewhere in it
+ * @return the decoded URI
+ * @since Ant1.7.1
+ */
+ public static String fromJarURI(String uri) {
+ int pling = uri.indexOf("!/");
+ String jarName = uri.substring("jar:".length(), pling);
+ return fromURI(jarName);
+ }
+
+ /**
+ * Decodes an Uri with % characters.
+ * The URI is escaped
+ * @param uri String with the uri possibly containing % characters.
+ * @return The decoded Uri
+ * @throws UnsupportedEncodingException if UTF-8 is not available
+ * @since Ant 1.7
+ */
+ public static String decodeUri(String uri) throws UnsupportedEncodingException {
+ if (uri.indexOf('%') == -1) {
+ return uri;
+ }
+ ByteArrayOutputStream sb = new ByteArrayOutputStream(uri.length());
+ CharacterIterator iter = new StringCharacterIterator(uri);
+ for (char c = iter.first(); c != CharacterIterator.DONE;
+ c = iter.next()) {
+ if (c == '%') {
+ char c1 = iter.next();
+ if (c1 != CharacterIterator.DONE) {
+ int i1 = Character.digit(c1, WORD);
+ char c2 = iter.next();
+ if (c2 != CharacterIterator.DONE) {
+ int i2 = Character.digit(c2, WORD);
+ sb.write((char) ((i1 << NIBBLE) + i2));
+ }
+ }
+ } else if (c >= 0x0000 && c < 0x0080) {
+ sb.write(c);
+ } else { // #50543
+ byte[] bytes = String.valueOf(c).getBytes(URI_ENCODING);
+ sb.write(bytes, 0, bytes.length);
+ }
+ }
+ return sb.toString(URI_ENCODING);
+ }
+
+ /**
+ * Encodes an Uri with % characters.
+ * The URI is escaped
+ * @param path String to encode.
+ * @return The encoded string, according to URI norms
+ * @throws UnsupportedEncodingException if UTF-8 is not available
+ * @since Ant 1.7
+ */
+ public static String encodeURI(String path) throws UnsupportedEncodingException {
+ int i = 0;
+ int len = path.length();
+ int ch = 0;
+ StringBuffer sb = null;
+ for (; i < len; i++) {
+ ch = path.charAt(i);
+ // if it's not an ASCII character, break here, and use UTF-8 encoding
+ if (ch >= ASCII_SIZE) {
+ break;
+ }
+ if (gNeedEscaping[ch]) {
+ if (sb == null) {
+ sb = new StringBuffer(path.substring(0, i));
+ }
+ sb.append('%');
+ sb.append(gAfterEscaping1[ch]);
+ sb.append(gAfterEscaping2[ch]);
+ // record the fact that it's escaped
+ } else if (sb != null) {
+ sb.append((char) ch);
+ }
+ }
+
+ // we saw some non-ascii character
+ if (i < len) {
+ if (sb == null) {
+ sb = new StringBuffer(path.substring(0, i));
+ }
+ // get UTF-8 bytes for the remaining sub-string
+ byte[] bytes = null;
+ byte b;
+ bytes = path.substring(i).getBytes(URI_ENCODING);
+ len = bytes.length;
+
+ // for each byte
+ for (i = 0; i < len; i++) {
+ b = bytes[i];
+ // for non-ascii character: make it positive, then escape
+ if (b < 0) {
+ ch = b + BYTE_SIZE;
+ sb.append('%');
+ sb.append(gHexChs[ch >> NIBBLE]);
+ sb.append(gHexChs[ch & NIBBLE_MASK]);
+ } else if (gNeedEscaping[b]) {
+ sb.append('%');
+ sb.append(gAfterEscaping1[b]);
+ sb.append(gAfterEscaping2[b]);
+ } else {
+ sb.append((char) b);
+ }
+ }
+ }
+ return sb == null ? path : sb.toString();
+ }
+
+ /**
+ * Convert a File to a URL.
+ * File.toURL() does not encode characters like #.
+ * File.toURI() has been introduced in java 1.4, so
+ * Ant cannot use it (except by reflection) <!-- TODO no longer true -->
+ * FileUtils.toURI() cannot be used by Locator.java
+ * Implemented this way.
+ * File.toURL() adds file: and changes '\' to '/' for dos OSes
+ * encodeURI converts characters like ' ' and '#' to %DD
+ * @param file the file to convert
+ * @return URL the converted File
+ * @throws MalformedURLException on error
+ * @deprecated since 1.9, use {@link FileUtils#getFileURL(File)}
+ */
+ @Deprecated
+ public static URL fileToURL(File file)
+ throws MalformedURLException {
+ return new URL(file.toURI().toASCIIString());
+ }
+
+ /**
+ * Get the File necessary to load the Sun compiler tools. If the classes
+ * are available to this class, then no additional URL is required and
+ * null is returned. This may be because the classes are explicitly in the
+ * class path or provided by the JVM directly.
+ *
+ * @return the tools jar as a File if required, null otherwise.
+ */
+ public static File getToolsJar() {
+ // firstly check if the tools jar is already in the classpath
+ boolean toolsJarAvailable = false;
+ try {
+ // just check whether this throws an exception
+ Class.forName("com.sun.tools.javac.Main");
+ toolsJarAvailable = true;
+ } catch (Exception e) {
+ try {
+ Class.forName("sun.tools.javac.Main");
+ toolsJarAvailable = true;
+ } catch (Exception e2) {
+ // ignore
+ }
+ }
+ if (toolsJarAvailable) {
+ return null;
+ }
+ // couldn't find compiler - try to find tools.jar
+ // based on java.home setting
+ String libToolsJar
+ = File.separator + "lib" + File.separator + "tools.jar";
+ String javaHome = System.getProperty("java.home");
+ File toolsJar = new File(javaHome + libToolsJar);
+ if (toolsJar.exists()) {
+ // Found in java.home as given
+ return toolsJar;
+ }
+ if (javaHome.toLowerCase(Locale.ENGLISH).endsWith(File.separator + "jre")) {
+ javaHome = javaHome.substring(
+ 0, javaHome.length() - "/jre".length());
+ toolsJar = new File(javaHome + libToolsJar);
+ }
+ if (!toolsJar.exists()) {
+ System.out.println("Unable to locate tools.jar. "
+ + "Expected to find it in " + toolsJar.getPath());
+ return null;
+ }
+ return toolsJar;
+ }
+
+ /**
+ * Get an array of URLs representing all of the jar files in the
+ * given location. If the location is a file, it is returned as the only
+ * element of the array. If the location is a directory, it is scanned for
+ * jar files.
+ *
+ * @param location the location to scan for Jars.
+ *
+ * @return an array of URLs for all jars in the given location.
+ *
+ * @exception MalformedURLException if the URLs for the jars cannot be
+ * formed.
+ */
+ public static URL[] getLocationURLs(File location)
+ throws MalformedURLException {
+ return getLocationURLs(location, new String[]{".jar"});
+ }
+
+ /**
+ * Get an array of URLs representing all of the files of a given set of
+ * extensions in the given location. If the location is a file, it is
+ * returned as the only element of the array. If the location is a
+ * directory, it is scanned for matching files.
+ *
+ * @param location the location to scan for files.
+ * @param extensions an array of extension that are to match in the
+ * directory search.
+ *
+ * @return an array of URLs of matching files.
+ * @exception MalformedURLException if the URLs for the files cannot be
+ * formed.
+ */
+ public static URL[] getLocationURLs(File location,
+ final String[] extensions)
+ throws MalformedURLException {
+ URL[] urls = new URL[0];
+
+ if (!location.exists()) {
+ return urls;
+ }
+ if (!location.isDirectory()) {
+ urls = new URL[1];
+ String path = location.getPath();
+ String littlePath = path.toLowerCase(Locale.ENGLISH);
+ for (int i = 0; i < extensions.length; ++i) {
+ if (littlePath.endsWith(extensions[i])) {
+ urls[0] = fileToURL(location);
+ break;
+ }
+ }
+ return urls;
+ }
+ File[] matches = location.listFiles(
+ new FilenameFilter() {
+ public boolean accept(File dir, String name) {
+ String littleName = name.toLowerCase(Locale.ENGLISH);
+ for (int i = 0; i < extensions.length; ++i) {
+ if (littleName.endsWith(extensions[i])) {
+ return true;
+ }
+ }
+ return false;
+ }
+ });
+ urls = new URL[matches.length];
+ for (int i = 0; i < matches.length; ++i) {
+ urls[i] = fileToURL(matches[i]);
+ }
+ return urls;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/listener/AnsiColorLogger.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/listener/AnsiColorLogger.java
new file mode 100644
index 00000000..2e695005
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/listener/AnsiColorLogger.java
@@ -0,0 +1,249 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.listener;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintStream;
+import java.util.Properties;
+
+import org.apache.tools.ant.DefaultLogger;
+import org.apache.tools.ant.Project;
+
+/**
+ * Uses ANSI Color Code Sequences to colorize messages
+ * sent to the console.
+ *
+ * <p>If used with the -logfile option, the output file
+ * will contain all the necessary escape codes to
+ * display the text in colorized mode when displayed
+ * in the console using applications like cat, more,
+ * etc.</p>
+ *
+ * <p>This is designed to work on terminals that support ANSI
+ * color codes. It works on XTerm, ETerm, Mindterm, etc.
+ * It also works on Win9x (with ANSI.SYS loaded.)</p>
+ *
+ * <p>NOTE:
+ * It doesn't work on WinNT's COMMAND.COM even with
+ * ANSI.SYS loaded.</p>
+ *
+ * <p>The default colors used for differentiating
+ * the message levels can be changed by editing the
+ * /org/apache/tools/ant/listener/defaults.properties
+ * file.
+ * This file contains 5 key/value pairs:</p>
+ * <pre>
+ * AnsiColorLogger.ERROR_COLOR=2;31
+ * AnsiColorLogger.WARNING_COLOR=2;35
+ * AnsiColorLogger.INFO_COLOR=2;36
+ * AnsiColorLogger.VERBOSE_COLOR=2;32
+ * AnsiColorLogger.DEBUG_COLOR=2;34
+ * </pre>
+ *
+ * <p>Another option is to pass a system variable named
+ * ant.logger.defaults, with value set to the path of
+ * the file that contains user defined Ansi Color
+ * Codes, to the <B>java</B> command using -D option.</p>
+ *
+ * To change these colors use the following chart:
+ *
+ * <h2>ANSI COLOR LOGGER CONFIGURATION</h2>
+ *
+ * Format for AnsiColorLogger.*=
+ * Attribute;Foreground;Background
+ *
+ * Attribute is one of the following: <pre>
+ * 0 -&gt; Reset All Attributes (return to normal mode)
+ * 1 -&gt; Bright (Usually turns on BOLD)
+ * 2 -&gt; Dim
+ * 3 -&gt; Underline
+ * 5 -&gt; link
+ * 7 -&gt; Reverse
+ * 8 -&gt; Hidden
+ * </pre>
+ *
+ * Foreground is one of the following:<pre>
+ * 30 -&gt; Black
+ * 31 -&gt; Red
+ * 32 -&gt; Green
+ * 33 -&gt; Yellow
+ * 34 -&gt; Blue
+ * 35 -&gt; Magenta
+ * 36 -&gt; Cyan
+ * 37 -&gt; White
+ * </pre>
+ *
+ * Background is one of the following:<pre>
+ * 40 -&gt; Black
+ * 41 -&gt; Red
+ * 42 -&gt; Green
+ * 43 -&gt; Yellow
+ * 44 -&gt; Blue
+ * 45 -&gt; Magenta
+ * 46 -&gt; Cyan
+ * 47 -&gt; White
+ * </pre>
+ */
+public class AnsiColorLogger extends DefaultLogger {
+ // private static final int ATTR_NORMAL = 0;
+ // private static final int ATTR_BRIGHT = 1;
+ private static final int ATTR_DIM = 2;
+ // private static final int ATTR_UNDERLINE = 3;
+ // private static final int ATTR_BLINK = 5;
+ // private static final int ATTR_REVERSE = 7;
+ // private static final int ATTR_HIDDEN = 8;
+
+ // private static final int FG_BLACK = 30;
+ private static final int FG_RED = 31;
+ private static final int FG_GREEN = 32;
+ // private static final int FG_YELLOW = 33;
+ private static final int FG_BLUE = 34;
+ private static final int FG_MAGENTA = 35;
+ private static final int FG_CYAN = 36;
+ // private static final int FG_WHITE = 37;
+
+ // private static final int BG_BLACK = 40;
+ // private static final int BG_RED = 41;
+ // private static final int BG_GREEN = 42;
+ // private static final int BG_YELLOW = 44;
+ // private static final int BG_BLUE = 44;
+ // private static final int BG_MAGENTA = 45;
+ // private static final int BG_CYAN = 46;
+ // private static final int BG_WHITE = 47;
+
+ private static final String PREFIX = "\u001b[";
+ private static final String SUFFIX = "m";
+ private static final char SEPARATOR = ';';
+ private static final String END_COLOR = PREFIX + SUFFIX;
+
+ private String errColor
+ = PREFIX + ATTR_DIM + SEPARATOR + FG_RED + SUFFIX;
+ private String warnColor
+ = PREFIX + ATTR_DIM + SEPARATOR + FG_MAGENTA + SUFFIX;
+ private String infoColor
+ = PREFIX + ATTR_DIM + SEPARATOR + FG_CYAN + SUFFIX;
+ private String verboseColor
+ = PREFIX + ATTR_DIM + SEPARATOR + FG_GREEN + SUFFIX;
+ private String debugColor
+ = PREFIX + ATTR_DIM + SEPARATOR + FG_BLUE + SUFFIX;
+
+ private boolean colorsSet = false;
+
+ /**
+ * Set the colors to use from a property file specified by the
+ * special ant property ant.logger.defaults
+ */
+ private void setColors() {
+ String userColorFile = System.getProperty("ant.logger.defaults");
+ String systemColorFile =
+ "/org/apache/tools/ant/listener/defaults.properties";
+
+ InputStream in = null;
+
+ try {
+ Properties prop = new Properties();
+
+ if (userColorFile != null) {
+ in = new FileInputStream(userColorFile);
+ } else {
+ in = getClass().getResourceAsStream(systemColorFile);
+ }
+
+ if (in != null) {
+ prop.load(in);
+ }
+
+ String errC = prop.getProperty("AnsiColorLogger.ERROR_COLOR");
+ String warn = prop.getProperty("AnsiColorLogger.WARNING_COLOR");
+ String info = prop.getProperty("AnsiColorLogger.INFO_COLOR");
+ String verbose = prop.getProperty("AnsiColorLogger.VERBOSE_COLOR");
+ String debug = prop.getProperty("AnsiColorLogger.DEBUG_COLOR");
+ if (errC != null) {
+ errColor = PREFIX + errC + SUFFIX;
+ }
+ if (warn != null) {
+ warnColor = PREFIX + warn + SUFFIX;
+ }
+ if (info != null) {
+ infoColor = PREFIX + info + SUFFIX;
+ }
+ if (verbose != null) {
+ verboseColor = PREFIX + verbose + SUFFIX;
+ }
+ if (debug != null) {
+ debugColor = PREFIX + debug + SUFFIX;
+ }
+ } catch (IOException ioe) {
+ //Ignore - we will use the defaults.
+ } finally {
+ if (in != null) {
+ try {
+ in.close();
+ } catch (IOException e) {
+ //Ignore - We do not want this to stop the build.
+ }
+ }
+ }
+ }
+
+ /**
+ * @see DefaultLogger#printMessage
+ */
+ /** {@inheritDoc}. */
+ @Override
+ protected void printMessage(final String message,
+ final PrintStream stream,
+ final int priority) {
+ if (message != null && stream != null) {
+ if (!colorsSet) {
+ setColors();
+ colorsSet = true;
+ }
+
+ final StringBuffer msg = new StringBuffer(message);
+ switch (priority) {
+ case Project.MSG_ERR:
+ msg.insert(0, errColor);
+ msg.append(END_COLOR);
+ break;
+ case Project.MSG_WARN:
+ msg.insert(0, warnColor);
+ msg.append(END_COLOR);
+ break;
+ case Project.MSG_INFO:
+ msg.insert(0, infoColor);
+ msg.append(END_COLOR);
+ break;
+ case Project.MSG_VERBOSE:
+ msg.insert(0, verboseColor);
+ msg.append(END_COLOR);
+ break;
+ case Project.MSG_DEBUG:
+ // Fall through
+ default:
+ msg.insert(0, debugColor);
+ msg.append(END_COLOR);
+ break;
+ }
+ final String strmessage = msg.toString();
+ stream.println(strmessage);
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/listener/BigProjectLogger.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/listener/BigProjectLogger.java
new file mode 100644
index 00000000..865127d2
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/listener/BigProjectLogger.java
@@ -0,0 +1,194 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.listener;
+
+import java.io.File;
+
+import org.apache.tools.ant.BuildEvent;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.SubBuildListener;
+import org.apache.tools.ant.util.StringUtils;
+
+/**
+ * This is a special logger that is designed to make it easier to work
+ * with big projects, those that use imports and
+ * subant to build complex systems.
+ *
+ * @since Ant1.7.1
+ */
+
+public class BigProjectLogger extends SimpleBigProjectLogger
+ implements SubBuildListener {
+
+ private volatile boolean subBuildStartedRaised = false;
+ private final Object subBuildLock = new Object();
+
+ /**
+ * Header string for the log.
+ * {@value}
+ */
+ public static final String HEADER
+ = "======================================================================";
+ /**
+ * Footer string for the log.
+ * {@value}
+ */
+ public static final String FOOTER = HEADER;
+
+ /**
+ * This is an override point: the message that indicates whether
+ * a build failed. Subclasses can change/enhance the
+ * message.
+ *
+ * @return The classic "BUILD FAILED" plus a timestamp
+ */
+ protected String getBuildFailedMessage() {
+ return super.getBuildFailedMessage() + TimestampedLogger.SPACER + getTimestamp();
+ }
+
+ /**
+ * This is an override point: the message that indicates that
+ * a build succeeded. Subclasses can change/enhance the
+ * message.
+ *
+ * @return The classic "BUILD SUCCESSFUL" plus a timestamp
+ */
+ protected String getBuildSuccessfulMessage() {
+ return super.getBuildSuccessfulMessage() + TimestampedLogger.SPACER + getTimestamp();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @param event
+ */
+ public void targetStarted(BuildEvent event) {
+ maybeRaiseSubBuildStarted(event);
+ super.targetStarted(event);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @param event
+ */
+ public void taskStarted(BuildEvent event) {
+ maybeRaiseSubBuildStarted(event);
+ super.taskStarted(event);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @param event
+ */
+ public void buildFinished(BuildEvent event) {
+ maybeRaiseSubBuildStarted(event);
+ subBuildFinished(event);
+ super.buildFinished(event);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @param event
+ */
+ public void messageLogged(BuildEvent event) {
+ maybeRaiseSubBuildStarted(event);
+ super.messageLogged(event);
+ }
+
+
+ /**
+ * {@inheritDoc}
+ *
+ * @param event An event with any relevant extra information. Must not be <code>null</code>.
+ */
+ public void subBuildStarted(BuildEvent event) {
+ String name = extractNameOrDefault(event);
+ Project project = event.getProject();
+
+ File base = project == null ? null : project.getBaseDir();
+ String path =
+ (base == null)
+ ? "With no base directory"
+ : "In " + base.getAbsolutePath();
+ printMessage(StringUtils.LINE_SEP + getHeader()
+ + StringUtils.LINE_SEP + "Entering project " + name
+ + StringUtils.LINE_SEP + path
+ + StringUtils.LINE_SEP + getFooter(),
+ out,
+ event.getPriority());
+ }
+
+ /**
+ * Get the name of an event
+ *
+ * @param event the event name
+ * @return the name or a default string
+ */
+ protected String extractNameOrDefault(BuildEvent event) {
+ String name = extractProjectName(event);
+ if (name == null) {
+ name = "";
+ } else {
+ name = '"' + name + '"';
+ }
+ return name;
+ }
+
+ /** {@inheritDoc} */
+ public void subBuildFinished(BuildEvent event) {
+ String name = extractNameOrDefault(event);
+ String failed = event.getException() != null ? "failing " : "";
+ printMessage(StringUtils.LINE_SEP + getHeader()
+ + StringUtils.LINE_SEP + "Exiting " + failed + "project "
+ + name
+ + StringUtils.LINE_SEP + getFooter(),
+ out,
+ event.getPriority());
+ }
+
+ /**
+ * Override point: return the header string for the entry/exit message
+ * @return the header string
+ */
+ protected String getHeader() {
+ return HEADER;
+ }
+
+ /**
+ * Override point: return the footer string for the entry/exit message
+ * @return the footer string
+ */
+ protected String getFooter() {
+ return FOOTER;
+ }
+
+ private void maybeRaiseSubBuildStarted(BuildEvent event) {
+ // double checked locking should be OK since the flag is write-once
+ if (!subBuildStartedRaised) {
+ synchronized (subBuildLock) {
+ if (!subBuildStartedRaised) {
+ subBuildStartedRaised = true;
+ subBuildStarted(event);
+ }
+ }
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/listener/CommonsLoggingListener.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/listener/CommonsLoggingListener.java
new file mode 100644
index 00000000..32474eea
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/listener/CommonsLoggingListener.java
@@ -0,0 +1,332 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.listener;
+
+import java.io.PrintStream;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogConfigurationException;
+import org.apache.commons.logging.LogFactory;
+import org.apache.tools.ant.BuildEvent;
+import org.apache.tools.ant.BuildListener;
+import org.apache.tools.ant.BuildLogger;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.UnknownElement;
+
+
+/**
+ * Jakarta Commons Logging listener.
+ * Note: do not use the SimpleLog as your logger implementation as it
+ * causes an infinite loop since it writes to System.err, which Ant traps
+ * and reroutes to the logger/listener layer.
+ *
+ * The following names are used for the log:
+ * org.apache.tools.ant.Project.PROJECT_NAME - for project events
+ * org.apache.tools.ant.Target.TARGET_NAME - for target events
+ * TASK_CLASS_NAME.TARGET_NAME - for events in individual targets.
+ *
+ * In all target and project names we replace "." and " " with "-".
+ *
+ * TODO: we should use the advanced context logging features (and expose them
+ * in c-l first :-)
+ * TODO: this is _very_ inefficient. Switching the out and tracking the logs
+ * can be optimized a lot - but may require few more changes to the core.
+ *
+ * @since Ant 1.5
+ */
+public class CommonsLoggingListener implements BuildListener, BuildLogger {
+
+ /** Indicates if the listener was initialized. */
+ private boolean initialized = false;
+
+ private LogFactory logFactory;
+
+ /**
+ * name of the category under which target events are logged
+ */
+ public static final String TARGET_LOG = "org.apache.tools.ant.Target";
+ /**
+ * name of the category under which project events are logged
+ */
+ public static final String PROJECT_LOG = "org.apache.tools.ant.Project";
+
+ /**
+ * Construct the listener and make sure that a LogFactory
+ * can be obtained.
+ */
+ public CommonsLoggingListener() {
+ }
+
+ private Log getLog(String cat, String suffix) {
+ if (suffix != null) {
+ suffix = suffix.replace('.', '-');
+ suffix = suffix.replace(' ', '-');
+ cat = cat + "." + suffix;
+ }
+ final PrintStream tmpOut = System.out;
+ final PrintStream tmpErr = System.err;
+ System.setOut(out);
+ System.setErr(err);
+
+ if (!initialized) {
+ try {
+ logFactory = LogFactory.getFactory();
+ } catch (final LogConfigurationException e) {
+ e.printStackTrace(System.err);
+ return null;
+ }
+ }
+
+ initialized = true;
+ final Log log = logFactory.getInstance(cat);
+ System.setOut(tmpOut);
+ System.setErr(tmpErr);
+ return log;
+ }
+
+ /** {@inheritDoc}. */
+ public void buildStarted(final BuildEvent event) {
+ final String categoryString = PROJECT_LOG;
+ final Log log = getLog(categoryString, null);
+
+ if (initialized) {
+ realLog(log, "Build started.", Project.MSG_INFO, null);
+ }
+ }
+
+ /** {@inheritDoc}. */
+ public void buildFinished(final BuildEvent event) {
+ if (initialized) {
+ final String categoryString = PROJECT_LOG;
+ final Log log = getLog(categoryString, event.getProject().getName());
+
+ if (event.getException() == null) {
+ realLog(log, "Build finished.", Project.MSG_INFO, null);
+ } else {
+ realLog(log, "Build finished with error.", Project.MSG_ERR,
+ event.getException());
+ }
+ }
+ }
+
+ /**
+ * @see BuildListener#targetStarted
+ */
+ /** {@inheritDoc}. */
+ public void targetStarted(final BuildEvent event) {
+ if (initialized) {
+ final Log log = getLog(TARGET_LOG,
+ event.getTarget().getName());
+ // Since task log category includes target, we don't really
+ // need this message
+ realLog(log, "Start: " + event.getTarget().getName(),
+ Project.MSG_VERBOSE, null);
+ }
+ }
+
+ /**
+ * @see BuildListener#targetFinished
+ */
+ /** {@inheritDoc}. */
+ public void targetFinished(final BuildEvent event) {
+ if (initialized) {
+ final String targetName = event.getTarget().getName();
+ final Log log = getLog(TARGET_LOG,
+ event.getTarget().getName());
+ if (event.getException() == null) {
+ realLog(log, "Target end: " + targetName, Project.MSG_DEBUG, null);
+ } else {
+ realLog(log, "Target \"" + targetName
+ + "\" finished with error.", Project.MSG_ERR,
+ event.getException());
+ }
+ }
+ }
+
+ /**
+ * @see BuildListener#taskStarted
+ */
+ /** {@inheritDoc}. */
+ public void taskStarted(final BuildEvent event) {
+ if (initialized) {
+ final Task task = event.getTask();
+ Object real = task;
+ if (task instanceof UnknownElement) {
+ final Object realObj = ((UnknownElement) task).getTask();
+ if (realObj != null) {
+ real = realObj;
+ }
+ }
+ final Log log = getLog(real.getClass().getName(), null);
+ if (log.isTraceEnabled()) {
+ realLog(log, "Task \"" + task.getTaskName() + "\" started ",
+ Project.MSG_VERBOSE, null);
+ }
+ }
+ }
+
+ /**
+ * @see BuildListener#taskFinished
+ */
+ /** {@inheritDoc}. */
+ public void taskFinished(final BuildEvent event) {
+ if (initialized) {
+ final Task task = event.getTask();
+ Object real = task;
+ if (task instanceof UnknownElement) {
+ final Object realObj = ((UnknownElement) task).getTask();
+ if (realObj != null) {
+ real = realObj;
+ }
+ }
+ final Log log = getLog(real.getClass().getName(), null);
+ if (event.getException() == null) {
+ if (log.isTraceEnabled()) {
+ realLog(log, "Task \"" + task.getTaskName() + "\" finished.",
+ Project.MSG_VERBOSE, null);
+ }
+ } else {
+ realLog(log, "Task \"" + task.getTaskName()
+ + "\" finished with error.", Project.MSG_ERR,
+ event.getException());
+ }
+ }
+ }
+
+
+ /**
+ * @see BuildListener#messageLogged
+ */
+ /** {@inheritDoc}. */
+ public void messageLogged(final BuildEvent event) {
+ if (initialized) {
+ Object categoryObject = event.getTask();
+ String categoryString = null;
+ String categoryDetail = null;
+
+ if (categoryObject == null) {
+ categoryObject = event.getTarget();
+ if (categoryObject == null) {
+ categoryObject = event.getProject();
+ categoryString = PROJECT_LOG;
+ categoryDetail = event.getProject().getName();
+ } else {
+ categoryString = TARGET_LOG;
+ categoryDetail = event.getTarget().getName();
+ }
+ } else {
+ // It's a task - append the target
+ if (event.getTarget() != null) {
+ categoryString = categoryObject.getClass().getName();
+ categoryDetail = event.getTarget().getName();
+ } else {
+ categoryString = categoryObject.getClass().getName();
+ }
+
+ }
+
+ final Log log = getLog(categoryString, categoryDetail);
+ final int priority = event.getPriority();
+ final String message = event.getMessage();
+ realLog(log, message, priority , null);
+ }
+ }
+
+ private void realLog(final Log log, final String message, final int priority, final Throwable t) {
+ final PrintStream tmpOut = System.out;
+ final PrintStream tmpErr = System.err;
+ System.setOut(out);
+ System.setErr(err);
+ switch (priority) {
+ case Project.MSG_ERR:
+ if (t == null) {
+ log.error(message);
+ } else {
+ log.error(message, t);
+ }
+ break;
+ case Project.MSG_WARN:
+ if (t == null) {
+ log.warn(message);
+ } else {
+ log.warn(message, t);
+ }
+ break;
+ case Project.MSG_INFO:
+ if (t == null) {
+ log.info(message);
+ } else {
+ log.info(message, t);
+ }
+ break;
+ case Project.MSG_VERBOSE:
+ log.debug(message);
+ break;
+ case Project.MSG_DEBUG:
+ log.debug(message);
+ break;
+ default:
+ log.error(message);
+ break;
+ }
+ System.setOut(tmpOut);
+ System.setErr(tmpErr);
+ }
+
+ // CheckStyle:VisibilityModifier OFF - bc
+ PrintStream out = System.out;
+ PrintStream err = System.err;
+ // CheckStyle:VisibilityModifier ON
+
+ /**
+ * Set the the output level.
+ * This is not used, the logger config is used instead.
+ * @param level ignored
+ */
+ public void setMessageOutputLevel(final int level) {
+ // Use the logger config
+ }
+
+ /**
+ * Set the output print stream.
+ * @param output the output stream
+ */
+ public void setOutputPrintStream(final PrintStream output) {
+ this.out = output;
+ }
+
+ /**
+ * Set emacs mode.
+ * This is ignored.
+ * @param emacsMode ignored
+ */
+ public void setEmacsMode(final boolean emacsMode) {
+ // Doesn't make sense for c-l. Use the logger config
+ }
+
+ /**
+ * Set the error print stream.
+ * @param err the error stream
+ */
+ public void setErrorPrintStream(final PrintStream err) {
+ this.err = err;
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/listener/Log4jListener.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/listener/Log4jListener.java
new file mode 100644
index 00000000..829f1183
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/listener/Log4jListener.java
@@ -0,0 +1,177 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.listener;
+
+import org.apache.log4j.Logger;
+import org.apache.log4j.helpers.NullEnumeration;
+import org.apache.tools.ant.BuildEvent;
+import org.apache.tools.ant.BuildListener;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Target;
+import org.apache.tools.ant.Task;
+
+
+/**
+ * Listener which sends events to Log4j logging system
+ *
+ */
+public class Log4jListener implements BuildListener {
+
+ /** Indicates if the listener was initialized. */
+ private final boolean initialized;
+
+ /**
+ * log category we log into
+ */
+ public static final String LOG_ANT = "org.apache.tools.ant";
+
+ /**
+ * Construct the listener and make sure there is a valid appender.
+ */
+ public Log4jListener() {
+ final Logger log = Logger.getLogger(LOG_ANT);
+ final Logger rootLog = Logger.getRootLogger();
+ initialized = !(rootLog.getAllAppenders() instanceof NullEnumeration);
+ if (!initialized) {
+ log.error("No log4j.properties in build area");
+ }
+ }
+
+ /**
+ * @see BuildListener#buildStarted
+ */
+ /** {@inheritDoc}. */
+ public void buildStarted(final BuildEvent event) {
+ if (initialized) {
+ final Logger log = Logger.getLogger(Project.class.getName());
+ log.info("Build started.");
+ }
+ }
+
+ /**
+ * @see BuildListener#buildFinished
+ */
+ /** {@inheritDoc}. */
+ public void buildFinished(final BuildEvent event) {
+ if (initialized) {
+ final Logger log = Logger.getLogger(Project.class.getName());
+ if (event.getException() == null) {
+ log.info("Build finished.");
+ } else {
+ log.error("Build finished with error.", event.getException());
+ }
+ }
+ }
+
+ /**
+ * @see BuildListener#targetStarted
+ */
+ /** {@inheritDoc}. */
+ public void targetStarted(final BuildEvent event) {
+ if (initialized) {
+ final Logger log = Logger.getLogger(Target.class.getName());
+ log.info("Target \"" + event.getTarget().getName() + "\" started.");
+ }
+ }
+
+ /**
+ * @see BuildListener#targetFinished
+ */
+ /** {@inheritDoc}. */
+ public void targetFinished(final BuildEvent event) {
+ if (initialized) {
+ final String targetName = event.getTarget().getName();
+ final Logger cat = Logger.getLogger(Target.class.getName());
+ if (event.getException() == null) {
+ cat.info("Target \"" + targetName + "\" finished.");
+ } else {
+ cat.error("Target \"" + targetName
+ + "\" finished with error.", event.getException());
+ }
+ }
+ }
+
+ /**
+ * @see BuildListener#taskStarted
+ */
+ /** {@inheritDoc}. */
+ public void taskStarted(final BuildEvent event) {
+ if (initialized) {
+ final Task task = event.getTask();
+ final Logger log = Logger.getLogger(task.getClass().getName());
+ log.info("Task \"" + task.getTaskName() + "\" started.");
+ }
+ }
+
+ /**
+ * @see BuildListener#taskFinished
+ */
+ /** {@inheritDoc}. */
+ public void taskFinished(final BuildEvent event) {
+ if (initialized) {
+ final Task task = event.getTask();
+ final Logger log = Logger.getLogger(task.getClass().getName());
+ if (event.getException() == null) {
+ log.info("Task \"" + task.getTaskName() + "\" finished.");
+ } else {
+ log.error("Task \"" + task.getTaskName()
+ + "\" finished with error.", event.getException());
+ }
+ }
+ }
+
+ /**
+ * @see BuildListener#messageLogged
+ */
+ /** {@inheritDoc}. */
+ public void messageLogged(final BuildEvent event) {
+ if (initialized) {
+ Object categoryObject = event.getTask();
+ if (categoryObject == null) {
+ categoryObject = event.getTarget();
+ if (categoryObject == null) {
+ categoryObject = event.getProject();
+ }
+ }
+
+ final Logger log
+ = Logger.getLogger(categoryObject.getClass().getName());
+ switch (event.getPriority()) {
+ case Project.MSG_ERR:
+ log.error(event.getMessage());
+ break;
+ case Project.MSG_WARN:
+ log.warn(event.getMessage());
+ break;
+ case Project.MSG_INFO:
+ log.info(event.getMessage());
+ break;
+ case Project.MSG_VERBOSE:
+ log.debug(event.getMessage());
+ break;
+ case Project.MSG_DEBUG:
+ log.debug(event.getMessage());
+ break;
+ default:
+ log.error(event.getMessage());
+ break;
+ }
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/listener/MailLogger.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/listener/MailLogger.java
new file mode 100644
index 00000000..4b50547f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/listener/MailLogger.java
@@ -0,0 +1,440 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.listener;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintStream;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Properties;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildEvent;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.DefaultLogger;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.email.EmailAddress;
+import org.apache.tools.ant.taskdefs.email.Header;
+import org.apache.tools.ant.taskdefs.email.Mailer;
+import org.apache.tools.ant.taskdefs.email.Message;
+import org.apache.tools.ant.util.ClasspathUtils;
+import org.apache.tools.ant.util.DateUtils;
+import org.apache.tools.ant.util.FileUtils;
+import org.apache.tools.ant.util.StringUtils;
+import org.apache.tools.mail.MailMessage;
+
+/**
+ * Buffers log messages from DefaultLogger, and sends an e-mail with the
+ * results. The following Project properties are used to send the mail.
+ * <ul>
+ * <li> MailLogger.mailhost [default: localhost] - Mail server to use</li>
+ * <li> MailLogger.port [default: 25] - Default port for SMTP </li>
+ * <li> Maillogger.user [no default] - user name for SMTP auth
+ * (requires JavaMail)</li>
+ * <li> Maillogger.password [no default] - password for SMTP auth
+ * (requires JavaMail)</li>
+ * <li> Maillogger.ssl [default: false] - on or true if ssl is
+ * needed (requires JavaMail)</li>
+ * <li> MailLogger.from [required] - Mail "from" address</li>
+ * <li> MailLogger.from [no default] - Mail "replyto" address(es),
+ * comma-separated</li>
+ * <li> MailLogger.failure.notify [default: true] - Send build failure
+ * e-mails?</li>
+ * <li> MailLogger.success.notify [default: true] - Send build success
+ * e-mails?</li>
+ * <li> MailLogger.failure.to [required if failure mail to be sent] - Address
+ * to send failure messages to</li>
+ * <li> MailLogger.success.to [required if success mail to be sent] - Address
+ * to send success messages to</li>
+ * <li> MailLogger.failure.cc [no default] - Address
+ * to send failure messages to carbon copy (cc)</li>
+ * <li> MailLogger.success.to [no default] - Address
+ * to send success messages to carbon copy (cc)</li>
+ * <li> MailLogger.failure.bcc [no default] - Address
+ * to send failure messages to blind carbon copy (bcc)</li>
+ * <li> MailLogger.success.bcc [no default] - Address
+ * to send success messages to blind carbon copy (bcc)</li>
+ * <li> MailLogger.failure.subject [default: "Build Failure"] - Subject of
+ * failed build</li>
+ * <li> MailLogger.success.subject [default: "Build Success"] - Subject of
+ * successful build</li>
+ * <li> MailLogger.failure.body [default: none] - fixed text of
+ * mail body for a failed build, default is to send the logfile</li>
+ * <li> MailLogger.success.body [default: none] - fixed text of
+ * mail body for a successful build, default is to send the logfile</li>
+ * <li> MailLogger.mimeType [default: text/plain] - MIME-Type of email</li>
+ * <li> MailLogger.charset [no default] - character set of email</li>
+ * <li> Maillogger.starttls.enable [default: false] - on or true if
+ * STARTTLS should be supported (requires JavaMail)</li>
+ * <li> MailLogger.properties.file [no default] - Filename of
+ * properties file that will override other values.</li>
+ * </ul>
+ * These properties are set using standard Ant property setting mechanisms
+ * (&lt;property&gt;, command-line -D, etc). Ant properties can be overridden
+ * by specifying the filename of a properties file in the <i>
+ * MailLogger.properties.file property</i> . Any properties defined in that
+ * file will override Ant properties.
+ *
+ */
+public class MailLogger extends DefaultLogger {
+ /** Buffer in which the message is constructed prior to sending */
+ private StringBuffer buffer = new StringBuffer();
+
+ private static final String DEFAULT_MIME_TYPE = "text/plain";
+
+ /**
+ * Sends an e-mail with the log results.
+ *
+ * @param event the build finished event
+ */
+ public void buildFinished(BuildEvent event) {
+ super.buildFinished(event);
+
+ Project project = event.getProject();
+ Hashtable<String, Object> properties = project.getProperties();
+
+ // overlay specified properties file (if any), which overrides project
+ // settings
+ Properties fileProperties = new Properties();
+ String filename = (String) properties.get("MailLogger.properties.file");
+ if (filename != null) {
+ InputStream is = null;
+ try {
+ is = new FileInputStream(filename);
+ fileProperties.load(is);
+ } catch (IOException ioe) {
+ // ignore because properties file is not required
+ } finally {
+ FileUtils.close(is);
+ }
+ }
+
+ for (Enumeration<?> e = fileProperties.keys(); e.hasMoreElements();) {
+ String key = (String) e.nextElement();
+ String value = fileProperties.getProperty(key);
+ properties.put(key, project.replaceProperties(value));
+ }
+
+ boolean success = (event.getException() == null);
+ String prefix = success ? "success" : "failure";
+
+ try {
+ boolean notify = Project.toBoolean(getValue(properties,
+ prefix + ".notify", "on"));
+
+ if (!notify) {
+ return;
+ }
+ Values values = new Values()
+ .mailhost(getValue(properties, "mailhost", "localhost"))
+ .port(Integer.parseInt(
+ getValue(
+ properties, "port",
+ String.valueOf(MailMessage.DEFAULT_PORT))))
+ .user(getValue(properties, "user", ""))
+ .password(getValue(properties, "password", ""))
+ .ssl(Project.toBoolean(getValue(properties,
+ "ssl", "off")))
+ .starttls(Project.toBoolean(getValue(properties,
+ "starttls.enable", "off")))
+ .from(getValue(properties, "from", null))
+ .replytoList(getValue(properties, "replyto", ""))
+ .toList(getValue(properties, prefix + ".to", null))
+ .toCcList(getValue(properties, prefix + ".cc", ""))
+ .toBccList(getValue(properties, prefix + ".bcc", ""))
+ .mimeType(getValue(properties, "mimeType", DEFAULT_MIME_TYPE))
+ .charset(getValue(properties, "charset", ""))
+ .body(getValue(properties, prefix + ".body", ""))
+ .subject(getValue(
+ properties, prefix + ".subject",
+ (success) ? "Build Success" : "Build Failure"));
+ if (values.user().equals("")
+ && values.password().equals("")
+ && !values.ssl() && !values.starttls()) {
+ sendMail(values, buffer.substring(0));
+ } else {
+ sendMimeMail(
+ event.getProject(), values, buffer.substring(0));
+ }
+ } catch (Exception e) {
+ System.out.println("MailLogger failed to send e-mail!");
+ e.printStackTrace(System.err);
+ }
+ }
+
+ private static class Values {
+ private String mailhost;
+ public String mailhost() {
+ return mailhost;
+ }
+ public Values mailhost(String mailhost) {
+ this.mailhost = mailhost;
+ return this;
+ }
+ private int port;
+ public int port() {
+ return port;
+ }
+ public Values port(int port) {
+ this.port = port;
+ return this;
+ }
+ private String user;
+ public String user() {
+ return user;
+ }
+ public Values user(String user) {
+ this.user = user;
+ return this;
+ }
+ private String password;
+ public String password() {
+ return password;
+ }
+ public Values password(String password) {
+ this.password = password;
+ return this;
+ }
+ private boolean ssl;
+ public boolean ssl() {
+ return ssl;
+ }
+ public Values ssl(boolean ssl) {
+ this.ssl = ssl;
+ return this;
+ }
+ private String from;
+ public String from() {
+ return from;
+ }
+ public Values from(String from) {
+ this.from = from;
+ return this;
+ }
+ private String replytoList;
+ public String replytoList() {
+ return replytoList;
+ }
+ public Values replytoList(String replytoList) {
+ this.replytoList = replytoList;
+ return this;
+ }
+ private String toList;
+ public String toList() {
+ return toList;
+ }
+ public Values toList(String toList) {
+ this.toList = toList;
+ return this;
+ }
+ private String toCcList;
+ public String toCcList() {
+ return toCcList;
+ }
+ public Values toCcList(String toCcList) {
+ this.toCcList = toCcList;
+ return this;
+ }
+ private String toBccList;
+ public String toBccList() {
+ return toBccList;
+ }
+ public Values toBccList(String toBccList) {
+ this.toBccList = toBccList;
+ return this;
+ }
+ private String subject;
+ public String subject() {
+ return subject;
+ }
+ public Values subject(String subject) {
+ this.subject = subject;
+ return this;
+ }
+ private String charset;
+ public String charset() {
+ return charset;
+ }
+ public Values charset(String charset) {
+ this.charset = charset;
+ return this;
+ }
+ private String mimeType;
+ public String mimeType() {
+ return mimeType;
+ }
+ public Values mimeType(String mimeType) {
+ this.mimeType = mimeType;
+ return this;
+ }
+ private String body;
+ public String body() {
+ return body;
+ }
+ public Values body(String body) {
+ this.body = body;
+ return this;
+ }
+ private boolean starttls;
+ public boolean starttls() {
+ return starttls;
+ }
+ public Values starttls(boolean starttls) {
+ this.starttls = starttls;
+ return this;
+ }
+ }
+
+ /**
+ * Receives and buffers log messages.
+ *
+ * @param message the message being logger
+ */
+ protected void log(String message) {
+ buffer.append(message).append(StringUtils.LINE_SEP);
+ }
+
+
+ /**
+ * Gets the value of a property.
+ *
+ * @param properties Properties to obtain value from
+ * @param name suffix of property name. "MailLogger." will be
+ * prepended internally.
+ * @param defaultValue value returned if not present in the properties.
+ * Set to null to make required.
+ * @return The value of the property, or default value.
+ * @exception Exception thrown if no default value is specified and the
+ * property is not present in properties.
+ */
+ private String getValue(Hashtable<String, Object> properties, String name,
+ String defaultValue) throws Exception {
+ String propertyName = "MailLogger." + name;
+ String value = (String) properties.get(propertyName);
+
+ if (value == null) {
+ value = defaultValue;
+ }
+
+ if (value == null) {
+ throw new Exception("Missing required parameter: " + propertyName);
+ }
+
+ return value;
+ }
+
+
+ /**
+ * Send the mail
+ * @param values the various values.
+ * @param message mail body
+ * @exception IOException thrown if sending message fails
+ */
+ private void sendMail(Values values, String message) throws IOException {
+ MailMessage mailMessage = new MailMessage(
+ values.mailhost(), values.port());
+ mailMessage.setHeader("Date", DateUtils.getDateForHeader());
+
+ mailMessage.from(values.from());
+ if (!values.replytoList().equals("")) {
+ StringTokenizer t = new StringTokenizer(
+ values.replytoList(), ", ", false);
+ while (t.hasMoreTokens()) {
+ mailMessage.replyto(t.nextToken());
+ }
+ }
+ StringTokenizer t = new StringTokenizer(values.toList(), ", ", false);
+ while (t.hasMoreTokens()) {
+ mailMessage.to(t.nextToken());
+ }
+
+ mailMessage.setSubject(values.subject());
+
+ if (values.charset().length() > 0) {
+ mailMessage.setHeader("Content-Type", values.mimeType()
+ + "; charset=\"" + values.charset() + "\"");
+ } else {
+ mailMessage.setHeader("Content-Type", values.mimeType());
+ }
+
+ PrintStream ps = mailMessage.getPrintStream();
+ ps.println(values.body().length() > 0 ? values.body() : message);
+
+ mailMessage.sendAndClose();
+ }
+ /**
+ * Send the mail (MimeMail)
+ * @param project current ant project
+ * @param values various values
+ * @param message mail body
+ */
+ private void sendMimeMail(Project project, Values values, String message) {
+ Mailer mailer = null;
+ try {
+ mailer = (Mailer) ClasspathUtils.newInstance(
+ "org.apache.tools.ant.taskdefs.email.MimeMailer",
+ MailLogger.class.getClassLoader(), Mailer.class);
+ } catch (BuildException e) {
+ Throwable t = e.getCause() == null ? e : e.getCause();
+ log("Failed to initialise MIME mail: " + t.getMessage());
+ return;
+ }
+ // convert the replyTo string into a vector of emailaddresses
+ Vector<EmailAddress> replyToList = vectorizeEmailAddresses(values.replytoList());
+ mailer.setHost(values.mailhost());
+ mailer.setPort(values.port());
+ mailer.setUser(values.user());
+ mailer.setPassword(values.password());
+ mailer.setSSL(values.ssl());
+ mailer.setEnableStartTLS(values.starttls());
+ Message mymessage =
+ new Message(values.body().length() > 0 ? values.body() : message);
+ mymessage.setProject(project);
+ mymessage.setMimeType(values.mimeType());
+ if (values.charset().length() > 0) {
+ mymessage.setCharset(values.charset());
+ }
+ mailer.setMessage(mymessage);
+ mailer.setFrom(new EmailAddress(values.from()));
+ mailer.setReplyToList(replyToList);
+ Vector<EmailAddress> toList = vectorizeEmailAddresses(values.toList());
+ mailer.setToList(toList);
+ Vector<EmailAddress> toCcList = vectorizeEmailAddresses(values.toCcList());
+ mailer.setCcList(toCcList);
+ Vector<EmailAddress> toBccList = vectorizeEmailAddresses(values.toBccList());
+ mailer.setBccList(toBccList);
+ mailer.setFiles(new Vector<File>());
+ mailer.setSubject(values.subject());
+ mailer.setHeaders(new Vector<Header>());
+ mailer.send();
+ }
+ private Vector<EmailAddress> vectorizeEmailAddresses(String listString) {
+ Vector<EmailAddress> emailList = new Vector<EmailAddress>();
+ StringTokenizer tokens = new StringTokenizer(listString, ",");
+ while (tokens.hasMoreTokens()) {
+ emailList.addElement(new EmailAddress(tokens.nextToken()));
+ }
+ return emailList;
+ }
+}
+
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/listener/ProfileLogger.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/listener/ProfileLogger.java
new file mode 100644
index 00000000..bbf5bb4f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/listener/ProfileLogger.java
@@ -0,0 +1,112 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.listener;
+
+import java.util.Date;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.tools.ant.BuildEvent;
+import org.apache.tools.ant.DefaultLogger;
+import org.apache.tools.ant.util.StringUtils;
+
+/**
+ * This is a special logger that is designed to profile builds.
+ *
+ * @since Ant1.8
+ */
+public class ProfileLogger extends DefaultLogger {
+
+ private Map<Object, Date> profileData = new ConcurrentHashMap<Object, Date>();
+
+ /**
+ * Logs a message to say that the target has started.
+ *
+ * @param event
+ * An event with any relevant extra information. Must not be
+ * <code>null</code>.
+ */
+ public void targetStarted(BuildEvent event) {
+ Date now = new Date();
+ String name = "Target " + event.getTarget().getName();
+ logStart(event, now, name);
+ profileData.put(event.getTarget(), now);
+ }
+
+ /**
+ * Logs a message to say that the target has finished.
+ *
+ * @param event
+ * An event with any relevant extra information. Must not be
+ * <code>null</code>.
+ */
+ public void targetFinished(BuildEvent event) {
+ Date start = (Date) profileData.remove(event.getTarget());
+ String name = "Target " + event.getTarget().getName();
+ logFinish(event, start, name);
+ }
+
+ /**
+ * Logs a message to say that the task has started.
+ *
+ * @param event
+ * An event with any relevant extra information. Must not be
+ * <code>null</code>.
+ */
+ public void taskStarted(BuildEvent event) {
+ String name = event.getTask().getTaskName();
+ Date now = new Date();
+ logStart(event, now, name);
+ profileData.put(event.getTask(), now);
+ }
+
+ /**
+ * Logs a message to say that the task has finished.
+ *
+ * @param event
+ * An event with any relevant extra information. Must not be
+ * <code>null</code>.
+ */
+ public void taskFinished(BuildEvent event) {
+ Date start = (Date) profileData.remove(event.getTask());
+ String name = event.getTask().getTaskName();
+ logFinish(event, start, name);
+ }
+
+ private void logFinish(BuildEvent event, Date start, String name) {
+ Date now = new Date();
+ String msg = null;
+ if (start != null) {
+ long diff = now.getTime() - start.getTime();
+ msg = StringUtils.LINE_SEP + name + ": finished " + now + " ("
+ + diff + "ms)";
+ } else {
+ msg = StringUtils.LINE_SEP + name + ": finished " + now
+ + " (unknown duration, start not detected)";
+ }
+ printMessage(msg, out, event.getPriority());
+ log(msg);
+ }
+
+ private void logStart(BuildEvent event, Date start, String name) {
+ String msg = StringUtils.LINE_SEP + name + ": started " + start;
+ printMessage(msg, out, event.getPriority());
+ log(msg);
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/listener/SilentLogger.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/listener/SilentLogger.java
new file mode 100644
index 00000000..6ddfd7f9
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/listener/SilentLogger.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.listener;
+
+import org.apache.tools.ant.BuildEvent;
+import org.apache.tools.ant.DefaultLogger;
+
+/**
+ * A logger which logs nothing but build failure and what task might output
+ *
+ * @since 1.9.0
+ */
+public class SilentLogger extends DefaultLogger {
+
+ @Override
+ public void buildStarted(BuildEvent event) {
+ // log nothing
+ }
+
+ @Override
+ public void buildFinished(BuildEvent event) {
+ if (event.getException() != null) {
+ super.buildFinished(event);
+ }
+ }
+
+ @Override
+ public void targetStarted(BuildEvent event) {
+ // log nothing
+ }
+
+ @Override
+ public void targetFinished(BuildEvent event) {
+ // log nothing
+ }
+
+ @Override
+ public void taskStarted(BuildEvent event) {
+ // log nothing
+ }
+
+ @Override
+ public void taskFinished(BuildEvent event) {
+ // log nothing
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/listener/SimpleBigProjectLogger.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/listener/SimpleBigProjectLogger.java
new file mode 100644
index 00000000..18f8dc68
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/listener/SimpleBigProjectLogger.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.listener;
+
+import org.apache.tools.ant.BuildEvent;
+import org.apache.tools.ant.NoBannerLogger;
+
+/**
+ * Displays subproject names like {@link BigProjectLogger}
+ * but is otherwise as quiet as {@link NoBannerLogger}.
+ * @since Ant1.8.1
+ */
+public class SimpleBigProjectLogger extends NoBannerLogger {
+
+ /**
+ * Override point, extract the target name
+ *
+ * @param event the event to work on
+ * @return the target name -including the owning project name (if non-null)
+ */
+ protected String extractTargetName(BuildEvent event) {
+ String targetName = super.extractTargetName(event);
+ String projectName = extractProjectName(event);
+ if (projectName != null && targetName != null) {
+ return projectName + '.' + targetName;
+ } else {
+ return targetName;
+ }
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/listener/TimestampedLogger.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/listener/TimestampedLogger.java
new file mode 100644
index 00000000..91296e32
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/listener/TimestampedLogger.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.listener;
+
+import org.apache.tools.ant.DefaultLogger;
+
+/**
+ * Like a normal logger, except with timed outputs
+ */
+public class TimestampedLogger extends DefaultLogger {
+
+ /**
+ * what appears between the old message and the new
+ */
+ public static final String SPACER = " - at ";
+
+
+ /**
+ * This is an override point: the message that indicates whether a build failed.
+ * Subclasses can change/enhance the message.
+ *
+ * @return The classic "BUILD FAILED" plus a timestamp
+ */
+ protected String getBuildFailedMessage() {
+ return super.getBuildFailedMessage() + SPACER + getTimestamp();
+ }
+
+ /**
+ * This is an override point: the message that indicates that a build succeeded.
+ * Subclasses can change/enhance the message.
+ *
+ * @return The classic "BUILD SUCCESSFUL" plus a timestamp
+ */
+ protected String getBuildSuccessfulMessage() {
+ return super.getBuildSuccessfulMessage() + SPACER + getTimestamp();
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/listener/defaults.properties b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/listener/defaults.properties
new file mode 100644
index 00000000..2994382e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/listener/defaults.properties
@@ -0,0 +1,58 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+####################################################
+#
+# ANSI COLOR LOGGER CONFIGURATION
+#
+# Format for AnsiColorLogger.*=
+# Attribute;Foreground;Background
+#
+# Attribute is one of the following:
+# 0 -> Reset All Attributes (return to normal mode)
+# 1 -> Bright (Usually turns on BOLD)
+# 2 -> Dim
+# 3 -> Underline
+# 5 -> link
+# 7 -> Reverse
+# 8 -> Hidden
+#
+# Foreground is one of the following:
+# 30 -> Black
+# 31 -> Red
+# 32 -> Green
+# 33 -> Yellow
+# 34 -> Blue
+# 35 -> Magenta
+# 36 -> Cyan
+# 37 -> White
+#
+# Background is one of the following:
+# 40 -> Black
+# 41 -> Red
+# 42 -> Green
+# 43 -> Yellow
+# 44 -> Blue
+# 45 -> Magenta
+# 46 -> Cyan
+# 47 -> White
+#
+####################################################
+
+AnsiColorLogger.ERROR_COLOR=2;31
+AnsiColorLogger.WARNING_COLOR=2;35
+AnsiColorLogger.INFO_COLOR=2;36
+AnsiColorLogger.VERBOSE_COLOR=2;32
+AnsiColorLogger.DEBUG_COLOR=2;34
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/loader/AntClassLoader2.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/loader/AntClassLoader2.java
new file mode 100644
index 00000000..1a4cac62
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/loader/AntClassLoader2.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.loader;
+
+import org.apache.tools.ant.AntClassLoader;
+
+/**
+ * @deprecated since 1.7
+ * Just use {@link AntClassLoader} itself.
+ */
+public class AntClassLoader2 extends AntClassLoader {
+ /** No args constructor. */
+ public AntClassLoader2() {
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/loader/AntClassLoader5.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/loader/AntClassLoader5.java
new file mode 100644
index 00000000..a91ed41e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/loader/AntClassLoader5.java
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.loader;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.net.URL;
+import java.util.Enumeration;
+
+import org.apache.tools.ant.AntClassLoader;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.Path;
+
+/**
+ * Overrides getResources which became non-final in Java5 and
+ * implements Closeable
+ */
+public class AntClassLoader5 extends AntClassLoader implements Closeable {
+ /**
+ * Creates a classloader for the given project using the classpath given.
+ *
+ * @param parent The parent classloader to which unsatisfied loading
+ * attempts are delegated. May be <code>null</code>,
+ * in which case the classloader which loaded this
+ * class is used as the parent.
+ * @param project The project to which this classloader is to belong.
+ * Must not be <code>null</code>.
+ * @param classpath the classpath to use to load the classes.
+ * May be <code>null</code>, in which case no path
+ * elements are set up to start with.
+ * @param parentFirst If <code>true</code>, indicates that the parent
+ * classloader should be consulted before trying to
+ * load the a class through this loader.
+ */
+ public AntClassLoader5(ClassLoader parent, Project project,
+ Path classpath, boolean parentFirst) {
+ super(parent, project, classpath, parentFirst);
+ }
+
+ /** {@inheritDoc} */
+ public Enumeration<URL> getResources(String name) throws IOException {
+ return getNamedResources(name);
+ }
+
+ /** {@inheritDoc} */
+ public void close() {
+ cleanup();
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/property/GetProperty.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/property/GetProperty.java
new file mode 100644
index 00000000..c08808aa
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/property/GetProperty.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.property;
+
+/**
+ * Interface to a class (normally PropertyHelper) to get a property.
+ * @since Ant 1.8.0
+ */
+public interface GetProperty {
+ /**
+ * Returns the value of a property if it is set.
+ * @param name name of the property.
+ * @return the property value, or null for no match or for name being null.
+ */
+ Object getProperty(String name);
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/property/LocalProperties.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/property/LocalProperties.java
new file mode 100644
index 00000000..c9ce3af0
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/property/LocalProperties.java
@@ -0,0 +1,152 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.property;
+
+import org.apache.tools.ant.MagicNames;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.PropertyHelper;
+
+/**
+ * Thread local class containing local properties.
+ * @since Ant 1.8.0
+ */
+public class LocalProperties
+ extends InheritableThreadLocal<LocalPropertyStack>
+ implements PropertyHelper.PropertyEvaluator,
+ PropertyHelper.PropertySetter {
+
+ /**
+ * Get a localproperties for the given project.
+ * @param project the project to retrieve the localproperties for.
+ * @return the localproperties.
+ */
+ public static synchronized LocalProperties get(Project project) {
+ LocalProperties l = (LocalProperties) project.getReference(
+ MagicNames.REFID_LOCAL_PROPERTIES);
+ if (l == null) {
+ l = new LocalProperties();
+ project.addReference(MagicNames.REFID_LOCAL_PROPERTIES, l);
+ PropertyHelper.getPropertyHelper(project).add(l);
+ }
+ return l;
+ }
+
+ // --------------------------------------------------
+ //
+ // Thread stuff
+ //
+ // --------------------------------------------------
+
+ /**
+ * Construct a new LocalProperties object.
+ */
+ private LocalProperties() {
+ }
+
+ /**
+ * Get the initial value.
+ * @return a new localproperties stack.
+ */
+ protected synchronized LocalPropertyStack initialValue() {
+ return new LocalPropertyStack();
+ }
+
+ private LocalPropertyStack current() {
+ return (LocalPropertyStack) get();
+ }
+
+ // --------------------------------------------------
+ //
+ // Local property adding and scoping
+ //
+ // --------------------------------------------------
+
+ /**
+ * Add a local property to the current scope.
+ * @param property the property name to add.
+ */
+ public void addLocal(String property) {
+ current().addLocal(property);
+ }
+
+ /** enter the scope */
+ public void enterScope() {
+ current().enterScope();
+ }
+
+ /** exit the scope */
+ public void exitScope() {
+ current().exitScope();
+ }
+
+ // --------------------------------------------------
+ //
+ // Copy - used in parallel to make a new stack
+ //
+ // --------------------------------------------------
+
+ /**
+ * Copy the stack for a parallel thread.
+ * To be called from the parallel thread itself.
+ */
+ public void copy() {
+ set(current().copy());
+ }
+
+ // --------------------------------------------------
+ //
+ // PropertyHelper delegate methods
+ //
+ // --------------------------------------------------
+
+ /**
+ * Evaluate a property.
+ * @param property the property's String "identifier".
+ * @param helper the invoking PropertyHelper.
+ * @return Object value.
+ */
+ public Object evaluate(String property, PropertyHelper helper) {
+ return current().evaluate(property, helper);
+ }
+
+ /**
+ * Set a *new" property.
+ * @param property the property's String "identifier".
+ * @param value the value to set.
+ * @param propertyHelper the invoking PropertyHelper.
+ * @return true if this entity 'owns' the property.
+ */
+ public boolean setNew(
+ String property, Object value, PropertyHelper propertyHelper) {
+ return current().setNew(property, value, propertyHelper);
+ }
+
+ /**
+ * Set a property.
+ * @param property the property's String "identifier".
+ * @param value the value to set.
+ * @param propertyHelper the invoking PropertyHelper.
+ * @return true if this entity 'owns' the property.
+ */
+ public boolean set(
+ String property, Object value, PropertyHelper propertyHelper) {
+ return current().set(property, value, propertyHelper);
+ }
+}
+
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/property/LocalPropertyStack.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/property/LocalPropertyStack.java
new file mode 100644
index 00000000..482f28cd
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/property/LocalPropertyStack.java
@@ -0,0 +1,161 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.property;
+
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.tools.ant.PropertyHelper;
+
+/**
+ * A stack of local property maps.
+ * There is a map for each scope (target, sequential, macro).
+ * @since Ant 1.8.0
+ */
+public class LocalPropertyStack {
+ private final LinkedList<Map<String, Object>> stack = new LinkedList<Map<String, Object>>();
+ private final Object LOCK = new Object();
+
+ // --------------------------------------------------
+ //
+ // Local property adding and scoping
+ //
+ // --------------------------------------------------
+
+ /**
+ * Add a local property.
+ * @param property the name of the local property.
+ */
+ public void addLocal(String property) {
+ synchronized (LOCK) {
+ Map<String, Object> map = stack.peek();
+ if (map != null) {
+ map.put(property, NullReturn.NULL);
+ }
+ }
+ }
+
+ /**
+ * Enter the local scope.
+ */
+ public void enterScope() {
+ synchronized (LOCK) {
+ stack.addFirst(new ConcurrentHashMap<String, Object>());
+ }
+ }
+
+ /**
+ * Exit the local scope.
+ */
+ public void exitScope() {
+ synchronized (LOCK) {
+ stack.removeFirst().clear();
+ }
+ }
+
+ // --------------------------------------------------
+ //
+ // Copy - used in parallel to make a new stack
+ //
+ // --------------------------------------------------
+
+ /**
+ * Copy the stack for a parallel thread.
+ * @return a copy.
+ */
+ public LocalPropertyStack copy() {
+ synchronized (LOCK) {
+ LocalPropertyStack ret = new LocalPropertyStack();
+ ret.stack.addAll(stack);
+ return ret;
+ }
+ }
+
+ // --------------------------------------------------
+ //
+ // PropertyHelper delegate methods
+ //
+ // --------------------------------------------------
+
+ /**
+ * Evaluate a property.
+ * @param property the property's String "identifier".
+ * @param helper the invoking PropertyHelper.
+ * @return Object value.
+ */
+ public Object evaluate(String property, PropertyHelper helper) {
+ synchronized (LOCK) {
+ for (Map<String, Object> map : stack) {
+ Object ret = map.get(property);
+ if (ret != null) {
+ return ret;
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Set a *new" property.
+ * @param property the property's String "identifier".
+ * @param value the value to set.
+ * @param propertyHelper the invoking PropertyHelper.
+ * @return true if this entity 'owns' the property.
+ */
+ public boolean setNew(
+ String property, Object value, PropertyHelper propertyHelper) {
+ Map<String, Object> map = getMapForProperty(property);
+ if (map == null) {
+ return false;
+ }
+ Object currValue = map.get(property);
+ if (currValue == NullReturn.NULL) {
+ map.put(property, value);
+ }
+ return true;
+ }
+
+ /**
+ * Set a property.
+ * @param property the property's String "identifier".
+ * @param value the value to set.
+ * @param propertyHelper the invoking PropertyHelper.
+ * @return true if this entity 'owns' the property.
+ */
+ public boolean set(String property, Object value, PropertyHelper propertyHelper) {
+ Map<String, Object> map = getMapForProperty(property);
+ if (map == null) {
+ return false;
+ }
+ map.put(property, value);
+ return true;
+ }
+
+ private Map<String, Object> getMapForProperty(String property) {
+ synchronized (LOCK) {
+ for (Map<String, Object> map : stack) {
+ if (map.get(property) != null) {
+ return map;
+ }
+ }
+ }
+ return null;
+ }
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/property/NullReturn.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/property/NullReturn.java
new file mode 100644
index 00000000..067aa9f1
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/property/NullReturn.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.property;
+
+/**
+ * Class to represent a null and to stop the chain of lookups.
+ * @since Ant 1.8.0
+ */
+public final class NullReturn {
+ /** a value to use in a property helper to stop looking properties */
+ public static final NullReturn NULL = new NullReturn();
+
+ /** Private constructor */
+ private NullReturn() {
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String toString() {
+ return "null";
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/property/ParseNextProperty.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/property/ParseNextProperty.java
new file mode 100644
index 00000000..5e5dfc07
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/property/ParseNextProperty.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.property;
+
+import java.text.ParsePosition;
+
+import org.apache.tools.ant.Project;
+
+/**
+ * Helper for {@link PropertyExpander PropertyExpander} that can be
+ * used to expand property references to values.
+ * @since Ant 1.8.0
+ */
+public interface ParseNextProperty {
+ /**
+ * Get the current project.
+ * @return the current ant project.
+ */
+ Project getProject();
+
+ /**
+ * Return any property that can be parsed from the specified position
+ * in the specified String.
+ * @param value String to parse
+ * @param pos ParsePosition
+ * @return Object or null if no property is at the current location.
+ */
+ Object parseNextProperty(String value, ParsePosition pos);
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/property/ParseProperties.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/property/ParseProperties.java
new file mode 100644
index 00000000..f03f966e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/property/ParseProperties.java
@@ -0,0 +1,199 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.property;
+
+import java.text.ParsePosition;
+import java.util.Collection;
+
+import org.apache.tools.ant.Project;
+
+/**
+ * Parse properties using a collection of expanders.
+ *
+ * @since Ant 1.8.0
+ */
+public class ParseProperties implements ParseNextProperty {
+
+ private final Project project;
+ private final GetProperty getProperty;
+ private final Collection<PropertyExpander> expanders;
+
+ /**
+ * Constructor with a getProperty.
+ * @param project the current Ant project.
+ * @param expanders a sequence of expanders
+ * @param getProperty property resolver.
+ */
+ public ParseProperties(Project project, Collection<PropertyExpander> expanders, GetProperty getProperty) {
+ this.project = project;
+ this.expanders = expanders;
+ this.getProperty = getProperty;
+ }
+
+ /**
+ * Get the project.
+ * @return the current Ant project.
+ */
+ public Project getProject() {
+ return project;
+ }
+
+ /**
+ * Decode properties from a String representation.
+ *
+ * <ul>
+ *
+ * <li>This implementation starts parsing the <code>value</code>
+ * parameter (unsurprisingly) at the beginning and asks each
+ * {@link PropertyExpander PropertyExpander} whether there is a
+ * property reference at that point. PropertyExpanders return
+ * the name of a property they may find and may advance the parse
+ * position.</li>
+ *
+ * <li>If the PropertyExpander returns <code>null</code> the
+ * method continues with the next PropertyExpander, otherwise it
+ * tries to look up the property's value using the configured
+ * {@link GetProperty GetProperty} instance.</li>
+ *
+ * <li>Once all PropertyExpanders have been consulted, the parse
+ * position is advanced by one character and the process repeated
+ * until <code>value</code> is exhausted.</li>
+ *
+ * </ul>
+ *
+ * <p>If the entire contents of <code>value</code> resolves to a
+ * single property, the looked up property value is returned.
+ * Otherwise a String is returned that concatenates the
+ * non-property parts of <code>value</code> and the expanded
+ * values of the properties that have been found.</p>
+ *
+ * @param value The string to be scanned for property references.
+ * May be <code>null</code>, in which case this
+ * method returns immediately with no effect.
+ *
+ * @return the original string with the properties replaced, or
+ * <code>null</code> if the original string is <code>null</code>.
+ */
+ public Object parseProperties(String value) {
+ if (value == null || "".equals(value)) {
+ return value;
+ }
+ final int len = value.length();
+ ParsePosition pos = new ParsePosition(0);
+ Object o = parseNextProperty(value, pos);
+ if (o != null && pos.getIndex() >= len) {
+ return o;
+ }
+ StringBuffer sb = new StringBuffer(len * 2);
+ if (o == null) {
+ sb.append(value.charAt(pos.getIndex()));
+ pos.setIndex(pos.getIndex() + 1);
+ } else {
+ sb.append(o);
+ }
+ while (pos.getIndex() < len) {
+ o = parseNextProperty(value, pos);
+ if (o == null) {
+ sb.append(value.charAt(pos.getIndex()));
+ pos.setIndex(pos.getIndex() + 1);
+ } else {
+ sb.append(o);
+ }
+ }
+ return sb.toString();
+ }
+
+ /**
+ * Learn whether a String contains replaceable properties.
+ *
+ * <p>Uses the configured {@link PropertyExpander
+ * PropertyExpanders} and scans through the string. Returns true
+ * as soon as any expander finds a property.</p>
+ *
+ * @param value the String to check.
+ * @return <code>true</code> if <code>value</code> contains property notation.
+ */
+ public boolean containsProperties(String value) {
+ if (value == null) {
+ return false;
+ }
+ final int len = value.length();
+ for (ParsePosition pos = new ParsePosition(0); pos.getIndex() < len;) {
+ if (parsePropertyName(value, pos) != null) {
+ return true;
+ }
+ pos.setIndex(pos.getIndex() + 1);
+ }
+ return false;
+ }
+
+ /**
+ * Return any property that can be parsed from the specified position
+ * in the specified String.
+ *
+ * <p>Uses the configured {@link PropertyExpander
+ * PropertyExpanders} and {@link GetProperty GetProperty}
+ * instance .</p>
+ *
+ * @param value String to parse
+ * @param pos ParsePosition
+ * @return Object or null if no property is at the current
+ * location. If a property reference has been found but the
+ * property doesn't expand to a value, the property's name is
+ * returned.
+ */
+ public Object parseNextProperty(String value, ParsePosition pos) {
+ final int start = pos.getIndex();
+
+ if (start > value.length()) {
+ // early exit, can't find any property here, no need to
+ // consult all the delegates.
+ return null;
+ }
+
+ String propertyName = parsePropertyName(value, pos);
+ if (propertyName != null) {
+ Object result = getProperty(propertyName);
+ if (result != null) {
+ return result;
+ }
+ if (project != null) {
+ project.log(
+ "Property \"" + propertyName
+ + "\" has not been set", Project.MSG_VERBOSE);
+ }
+ return value.substring(start, pos.getIndex());
+ }
+ return null;
+ }
+
+ private String parsePropertyName(String value, ParsePosition pos) {
+ for (PropertyExpander propertyExpander : expanders) {
+ String propertyName = propertyExpander.parsePropertyName(value, pos, this);
+ if (propertyName == null) {
+ continue;
+ }
+ return propertyName;
+ }
+ return null;
+ }
+
+ private Object getProperty(String propertyName) {
+ return getProperty.getProperty(propertyName);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/property/PropertyExpander.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/property/PropertyExpander.java
new file mode 100644
index 00000000..a2b4d633
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/property/PropertyExpander.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.property;
+
+import java.text.ParsePosition;
+
+import org.apache.tools.ant.PropertyHelper;
+
+/**
+ * Responsible for locating a property reference inside a String.
+ * @since Ant 1.8.0
+ */
+public interface PropertyExpander extends PropertyHelper.Delegate {
+
+ /**
+ * Determine whether there is a property reference at the current
+ * ParsePosition and return its name (or null if there is none).
+ *
+ * <p>Implementations should advance the ParsePosition to the last
+ * character that makes up the property reference. E.g. the
+ * default implementation would return <code>"foo"</code> for
+ * <code>${foo}</code> and advance the ParsePosition to the
+ * <code>}</code> character.</p>
+ *
+ * @param s the String to parse.
+ * @param pos the ParsePosition in use, the location is expected
+ * to be modified if a property reference has been found (and may
+ * even be modified if no reference has been found).
+ * @param parseNextProperty provides access to the Project and may
+ * be used to look up property values.
+ * @return property name if any, else <code>null</code>.
+ */
+ String parsePropertyName(String s, ParsePosition pos,
+ ParseNextProperty parseNextProperty);
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/property/ResolvePropertyMap.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/property/ResolvePropertyMap.java
new file mode 100644
index 00000000..5bdd3545
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/property/ResolvePropertyMap.java
@@ -0,0 +1,151 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.property;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+
+/**
+ * Class to resolve properties in a map. This class is explicitly not threadsafe.
+ * @since Ant 1.8.0
+ */
+public class ResolvePropertyMap implements GetProperty {
+ private final Set<String> seen = new HashSet<String>();
+ private final ParseProperties parseProperties;
+ private final GetProperty master;
+ private Map<String, Object> map;
+ private String prefix;
+ // whether properties of the value side of the map should be
+ // expanded
+ private boolean prefixValues = false;
+ // whether the current getProperty call is expanding the key side
+ // of the map
+ private boolean expandingLHS = true;
+
+ /**
+ * Constructor with a master getproperty and a collection of expanders.
+ * @param project the current ant project.
+ * @param master the master property holder (usually PropertyHelper)
+ * @param expanders a collection of expanders (usually from PropertyHelper).
+ */
+ public ResolvePropertyMap(Project project, GetProperty master, Collection<PropertyExpander> expanders) {
+ this.master = master;
+ this.parseProperties = new ParseProperties(project, expanders, this);
+ }
+
+ /**
+ * Returns the value of a property if it is set.
+ * @param name name of the property.
+ * @return the property value, or null for no match or for name being null.
+ */
+ public Object getProperty(String name) {
+ if (seen.contains(name)) {
+ throw new BuildException(
+ "Property " + name + " was circularly " + "defined.");
+ }
+
+ try {
+
+ // If the property we are looking up is a key in the map
+ // (first call into this method from resolveAllProperties)
+ // or we've been asked to prefix the value side (later
+ // recursive calls via the GetProperty interface) the
+ // prefix must be prepended when looking up the property
+ // outside of the map.
+ String fullKey = name;
+ if (prefix != null && (expandingLHS || prefixValues)) {
+ fullKey = prefix + name;
+ }
+
+ Object masterValue = master.getProperty(fullKey);
+ if (masterValue != null) {
+ // If the property already has a value outside of the
+ // map, use that value to enforce property
+ // immutability.
+
+ return masterValue;
+ }
+
+ seen.add(name);
+
+ String recursiveCallKey = name;
+ if (prefix != null && !expandingLHS && !prefixValues) {
+ // only look up unprefixed properties inside the map
+ // if prefixValues is true or we are expanding the key
+ // itself
+ recursiveCallKey = prefix + name;
+ }
+
+ expandingLHS = false;
+ // will recurse into this method for each property
+ // reference found in the map's value
+ return parseProperties.parseProperties((String) map.get(recursiveCallKey));
+ } finally {
+ seen.remove(name);
+ }
+ }
+
+ /**
+ * The action method - resolves all the properties in a map.
+ * @param map the map to resolve properties in.
+ * @deprecated since Ant 1.8.2, use the three-arg method instead.
+ */
+ public void resolveAllProperties(Map<String, Object> map) {
+ resolveAllProperties(map, null, false);
+ }
+
+ /**
+ * The action method - resolves all the properties in a map.
+ * @param map the map to resolve properties in.
+ * @param prefix the prefix the properties defined inside the map
+ * will finally receive - may be null.
+ * @deprecated since Ant 1.8.2, use the three-arg method instead.
+ */
+ public void resolveAllProperties(Map<String, Object> map, String prefix) {
+ resolveAllProperties(map, null, false);
+ }
+
+ /**
+ * The action method - resolves all the properties in a map.
+ * @param map the map to resolve properties in.
+ * @param prefix the prefix the properties defined inside the map
+ * will finally receive - may be null.
+ * @param prefixValues - whether the prefix will be applied
+ * to properties on the value side of the map as well.
+ */
+ public void resolveAllProperties(Map<String, Object> map, String prefix,
+ boolean prefixValues) {
+ // The map, prefix and prefixValues flag get used in the
+ // getProperty callback
+ this.map = map;
+ this.prefix = prefix;
+ this.prefixValues = prefixValues;
+
+ for (String key : map.keySet()) {
+ expandingLHS = true;
+ Object result = getProperty(key);
+ String value = result == null ? "" : result.toString();
+ map.put(key, value);
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/property/package.html b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/property/package.html
new file mode 100644
index 00000000..7a497ecf
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/property/package.html
@@ -0,0 +1,19 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<body>
+ Contains helper classes for ant properties.
+</body>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/AbstractCvsTask.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/AbstractCvsTask.java
new file mode 100644
index 00000000..1ce81166
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/AbstractCvsTask.java
@@ -0,0 +1,873 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.types.Commandline;
+import org.apache.tools.ant.types.Environment;
+import org.apache.tools.ant.util.FileUtils;
+import org.apache.tools.ant.util.StringUtils;
+
+/**
+ * original Cvs.java 1.20
+ *
+ * NOTE: This implementation has been moved here from Cvs.java with
+ * the addition of some accessors for extensibility. Another task
+ * can extend this with some customized output processing.
+ *
+ * @since Ant 1.5
+ */
+public abstract class AbstractCvsTask extends Task {
+ /**
+ * Default compression level to use, if compression is enabled via
+ * setCompression( true ).
+ */
+ public static final int DEFAULT_COMPRESSION_LEVEL = 3;
+ private static final int MAXIMUM_COMRESSION_LEVEL = 9;
+
+ private Commandline cmd = new Commandline();
+
+ private ArrayList<Module> modules = new ArrayList<Module>();
+
+ /** list of Commandline children */
+ private Vector<Commandline> vecCommandlines = new Vector<Commandline>();
+
+ /**
+ * the CVSROOT variable.
+ */
+ private String cvsRoot;
+
+ /**
+ * the CVS_RSH variable.
+ */
+ private String cvsRsh;
+
+ /**
+ * the package/module to check out.
+ */
+ private String cvsPackage;
+ /**
+ * the tag
+ */
+ private String tag;
+ /**
+ * the default command.
+ */
+ private static final String DEFAULT_COMMAND = "checkout";
+ /**
+ * the CVS command to execute.
+ */
+ private String command = null;
+
+ /**
+ * suppress information messages.
+ */
+ private boolean quiet = false;
+
+ /**
+ * suppress all messages.
+ */
+ private boolean reallyquiet = false;
+
+ /**
+ * compression level to use.
+ */
+ private int compression = 0;
+
+ /**
+ * report only, don't change any files.
+ */
+ private boolean noexec = false;
+
+ /**
+ * CVS port
+ */
+ private int port = 0;
+
+ /**
+ * CVS password file
+ */
+ private File passFile = null;
+
+ /**
+ * the directory where the checked out files should be placed.
+ */
+ private File dest;
+
+ /** whether or not to append stdout/stderr to existing files */
+ private boolean append = false;
+
+ /**
+ * the file to direct standard output from the command.
+ */
+ private File output;
+
+ /**
+ * the file to direct standard error from the command.
+ */
+ private File error;
+
+ /**
+ * If true it will stop the build if cvs exits with error.
+ * Default is false. (Iulian)
+ */
+ private boolean failOnError = false;
+
+ /**
+ * Create accessors for the following, to allow different handling of
+ * the output.
+ */
+ private ExecuteStreamHandler executeStreamHandler;
+ private OutputStream outputStream;
+ private OutputStream errorStream;
+
+ /** empty no-arg constructor*/
+ public AbstractCvsTask() {
+ super();
+ }
+
+ /**
+ * sets the handler
+ * @param handler a handler able of processing the output and error streams from the cvs exe
+ */
+ public void setExecuteStreamHandler(ExecuteStreamHandler handler) {
+ this.executeStreamHandler = handler;
+ }
+
+ /**
+ * find the handler and instantiate it if it does not exist yet
+ * @return handler for output and error streams
+ */
+ protected ExecuteStreamHandler getExecuteStreamHandler() {
+
+ if (this.executeStreamHandler == null) {
+ setExecuteStreamHandler(new PumpStreamHandler(getOutputStream(),
+ getErrorStream()));
+ }
+
+ return this.executeStreamHandler;
+ }
+
+ /**
+ * sets a stream to which the output from the cvs executable should be sent
+ * @param outputStream stream to which the stdout from cvs should go
+ */
+ protected void setOutputStream(OutputStream outputStream) {
+
+ this.outputStream = outputStream;
+ }
+
+ /**
+ * access the stream to which the stdout from cvs should go
+ * if this stream has already been set, it will be returned
+ * if the stream has not yet been set, if the attribute output
+ * has been set, the output stream will go to the output file
+ * otherwise the output will go to ant's logging system
+ * @return output stream to which cvs' stdout should go to
+ */
+ protected OutputStream getOutputStream() {
+
+ if (this.outputStream == null) {
+
+ if (output != null) {
+ try {
+ setOutputStream(new PrintStream(
+ new BufferedOutputStream(
+ new FileOutputStream(output
+ .getPath(),
+ append))));
+ } catch (IOException e) {
+ throw new BuildException(e, getLocation());
+ }
+ } else {
+ setOutputStream(new LogOutputStream(this, Project.MSG_INFO));
+ }
+ }
+
+ return this.outputStream;
+ }
+
+ /**
+ * sets a stream to which the stderr from the cvs exe should go
+ * @param errorStream an output stream willing to process stderr
+ */
+ protected void setErrorStream(OutputStream errorStream) {
+
+ this.errorStream = errorStream;
+ }
+
+ /**
+ * access the stream to which the stderr from cvs should go
+ * if this stream has already been set, it will be returned
+ * if the stream has not yet been set, if the attribute error
+ * has been set, the output stream will go to the file denoted by the error attribute
+ * otherwise the stderr output will go to ant's logging system
+ * @return output stream to which cvs' stderr should go to
+ */
+ protected OutputStream getErrorStream() {
+
+ if (this.errorStream == null) {
+
+ if (error != null) {
+
+ try {
+ setErrorStream(new PrintStream(
+ new BufferedOutputStream(
+ new FileOutputStream(error.getPath(),
+ append))));
+ } catch (IOException e) {
+ throw new BuildException(e, getLocation());
+ }
+ } else {
+ setErrorStream(new LogOutputStream(this, Project.MSG_WARN));
+ }
+ }
+
+ return this.errorStream;
+ }
+
+ /**
+ * Sets up the environment for toExecute and then runs it.
+ * @param toExecute the command line to execute
+ * @throws BuildException if failonError is set to true and the cvs command fails
+ */
+ protected void runCommand(Commandline toExecute) throws BuildException {
+ // TODO: we should use JCVS (www.ice.com/JCVS) instead of
+ // command line execution so that we don't rely on having
+ // native CVS stuff around (SM)
+
+ // We can't do it ourselves as jCVS is GPLed, a third party task
+ // outside of Apache repositories would be possible though (SB).
+
+ Environment env = new Environment();
+
+ if (port > 0) {
+ Environment.Variable var = new Environment.Variable();
+ var.setKey("CVS_CLIENT_PORT");
+ var.setValue(String.valueOf(port));
+ env.addVariable(var);
+
+ // non-standard environment variable used by CVSNT, WinCVS
+ // and others
+ var = new Environment.Variable();
+ var.setKey("CVS_PSERVER_PORT");
+ var.setValue(String.valueOf(port));
+ env.addVariable(var);
+ }
+
+ /**
+ * Need a better cross platform integration with <cvspass>, so
+ * use the same filename.
+ */
+ if (passFile == null) {
+
+ File defaultPassFile = new File(
+ System.getProperty("cygwin.user.home",
+ System.getProperty("user.home"))
+ + File.separatorChar + ".cvspass");
+
+ if (defaultPassFile.exists()) {
+ this.setPassfile(defaultPassFile);
+ }
+ }
+
+ if (passFile != null) {
+ if (passFile.isFile() && passFile.canRead()) {
+ Environment.Variable var = new Environment.Variable();
+ var.setKey("CVS_PASSFILE");
+ var.setValue(String.valueOf(passFile));
+ env.addVariable(var);
+ log("Using cvs passfile: " + String.valueOf(passFile),
+ Project.MSG_VERBOSE);
+ } else if (!passFile.canRead()) {
+ log("cvs passfile: " + String.valueOf(passFile)
+ + " ignored as it is not readable",
+ Project.MSG_WARN);
+ } else {
+ log("cvs passfile: " + String.valueOf(passFile)
+ + " ignored as it is not a file",
+ Project.MSG_WARN);
+ }
+ }
+
+ if (cvsRsh != null) {
+ Environment.Variable var = new Environment.Variable();
+ var.setKey("CVS_RSH");
+ var.setValue(String.valueOf(cvsRsh));
+ env.addVariable(var);
+ }
+
+ //
+ // Just call the getExecuteStreamHandler() and let it handle
+ // the semantics of instantiation or retrieval.
+ //
+ Execute exe = new Execute(getExecuteStreamHandler(), null);
+
+ exe.setAntRun(getProject());
+ if (dest == null) {
+ dest = getProject().getBaseDir();
+ }
+
+ if (!dest.exists()) {
+ dest.mkdirs();
+ }
+
+ exe.setWorkingDirectory(dest);
+ exe.setCommandline(toExecute.getCommandline());
+ exe.setEnvironment(env.getVariables());
+
+ try {
+ String actualCommandLine = executeToString(exe);
+
+ log(actualCommandLine, Project.MSG_VERBOSE);
+ int retCode = exe.execute();
+ log("retCode=" + retCode, Project.MSG_DEBUG);
+
+ if (failOnError && Execute.isFailure(retCode)) {
+ throw new BuildException("cvs exited with error code "
+ + retCode
+ + StringUtils.LINE_SEP
+ + "Command line was ["
+ + actualCommandLine + "]",
+ getLocation());
+ }
+ } catch (IOException e) {
+ if (failOnError) {
+ throw new BuildException(e, getLocation());
+ }
+ log("Caught exception: " + e.getMessage(), Project.MSG_WARN);
+ } catch (BuildException e) {
+ if (failOnError) {
+ throw(e);
+ }
+ Throwable t = e.getCause();
+ if (t == null) {
+ t = e;
+ }
+ log("Caught exception: " + t.getMessage(), Project.MSG_WARN);
+ } catch (Exception e) {
+ if (failOnError) {
+ throw new BuildException(e, getLocation());
+ }
+ log("Caught exception: " + e.getMessage(), Project.MSG_WARN);
+ }
+ }
+
+ /**
+ * do the work
+ * @throws BuildException if failonerror is set to true and the
+ * cvs command fails.
+ */
+ public void execute() throws BuildException {
+
+ String savedCommand = getCommand();
+
+ if (this.getCommand() == null && vecCommandlines.size() == 0) {
+ // re-implement legacy behaviour:
+ this.setCommand(AbstractCvsTask.DEFAULT_COMMAND);
+ }
+
+ String c = this.getCommand();
+ Commandline cloned = null;
+ if (c != null) {
+ cloned = (Commandline) cmd.clone();
+ cloned.createArgument(true).setLine(c);
+ this.addConfiguredCommandline(cloned, true);
+ }
+
+ try {
+ final int size = vecCommandlines.size();
+ for (int i = 0; i < size; i++) {
+ this.runCommand((Commandline) vecCommandlines.elementAt(i));
+ }
+ } finally {
+ if (cloned != null) {
+ removeCommandline(cloned);
+ }
+ setCommand(savedCommand);
+ FileUtils.close(outputStream);
+ FileUtils.close(errorStream);
+ }
+ }
+
+ private String executeToString(Execute execute) {
+
+ String cmdLine = Commandline.describeCommand(execute
+ .getCommandline());
+ StringBuffer stringBuffer = removeCvsPassword(cmdLine);
+
+ String newLine = StringUtils.LINE_SEP;
+ String[] variableArray = execute.getEnvironment();
+
+ if (variableArray != null) {
+ stringBuffer.append(newLine);
+ stringBuffer.append(newLine);
+ stringBuffer.append("environment:");
+ stringBuffer.append(newLine);
+ for (int z = 0; z < variableArray.length; z++) {
+ stringBuffer.append(newLine);
+ stringBuffer.append("\t");
+ stringBuffer.append(variableArray[z]);
+ }
+ }
+
+ return stringBuffer.toString();
+ }
+
+ /**
+ * Removes the cvs password from the command line, if given on the command
+ * line. This password can be given on the command line in the cvsRoot
+ * -d:pserver:user:password@server:path
+ * It has to be noted that the password may be omitted altogether.
+ * @param cmdLine the CVS command line
+ * @return a StringBuffer where the password has been removed (if available)
+ */
+ private StringBuffer removeCvsPassword(String cmdLine) {
+ StringBuffer stringBuffer = new StringBuffer(cmdLine);
+
+ int start = cmdLine.indexOf("-d:");
+
+ if (start >= 0) {
+ int stop = cmdLine.indexOf("@", start);
+ int startproto = cmdLine.indexOf(":", start);
+ int startuser = cmdLine.indexOf(":", startproto + 1);
+ int startpass = cmdLine.indexOf(":", startuser + 1);
+ stop = cmdLine.indexOf("@", start);
+ if (stop >= 0 && startpass > startproto && startpass < stop) {
+ for (int i = startpass + 1; i < stop; i++) {
+ stringBuffer.replace(i, i + 1, "*");
+ }
+ }
+ }
+ return stringBuffer;
+ }
+
+ /**
+ * The CVSROOT variable.
+ *
+ * @param root
+ * the CVSROOT variable
+ */
+ public void setCvsRoot(String root) {
+
+ // Check if not real cvsroot => set it to null
+ if (root != null) {
+ if (root.trim().equals("")) {
+ root = null;
+ }
+ }
+
+ this.cvsRoot = root;
+ }
+
+ /**
+ * access the CVSROOT variable
+ * @return CVSROOT
+ */
+ public String getCvsRoot() {
+
+ return this.cvsRoot;
+ }
+
+ /**
+ * The CVS_RSH variable.
+ *
+ * @param rsh the CVS_RSH variable
+ */
+ public void setCvsRsh(String rsh) {
+ // Check if not real cvsrsh => set it to null
+ if (rsh != null) {
+ if (rsh.trim().equals("")) {
+ rsh = null;
+ }
+ }
+
+ this.cvsRsh = rsh;
+ }
+
+ /**
+ * access the CVS_RSH variable
+ * @return the CVS_RSH variable
+ */
+ public String getCvsRsh() {
+
+ return this.cvsRsh;
+ }
+
+ /**
+ * Port used by CVS to communicate with the server.
+ *
+ * @param port port of CVS
+ */
+ public void setPort(int port) {
+ this.port = port;
+ }
+
+ /**
+ * access the port of CVS
+ * @return the port of CVS
+ */
+ public int getPort() {
+
+ return this.port;
+ }
+
+ /**
+ * Password file to read passwords from.
+ *
+ * @param passFile password file to read passwords from
+ */
+ public void setPassfile(File passFile) {
+ this.passFile = passFile;
+ }
+
+ /**
+ * find the password file
+ * @return password file
+ */
+ public File getPassFile() {
+
+ return this.passFile;
+ }
+
+ /**
+ * The directory where the checked out files should be placed.
+ *
+ * <p>Note that this is different from CVS's -d command line
+ * switch as Ant will never shorten pathnames to avoid empty
+ * directories.</p>
+ *
+ * @param dest directory where the checked out files should be placed
+ */
+ public void setDest(File dest) {
+ this.dest = dest;
+ }
+
+ /**
+ * get the file where the checked out files should be placed
+ *
+ * @return directory where the checked out files should be placed
+ */
+ public File getDest() {
+
+ return this.dest;
+ }
+
+ /**
+ * The package/module to operate upon.
+ *
+ * @param p package or module to operate upon
+ */
+ public void setPackage(String p) {
+ this.cvsPackage = p;
+ }
+
+ /**
+ * access the package or module to operate upon
+ *
+ * @return package/module
+ */
+ public String getPackage() {
+
+ return this.cvsPackage;
+ }
+ /**
+ * tag or branch
+ * @return tag or branch
+ * @since ant 1.6.1
+ */
+ public String getTag() {
+ return tag;
+ }
+
+ /**
+ * The tag of the package/module to operate upon.
+ * @param p tag
+ */
+ public void setTag(String p) {
+ // Check if not real tag => set it to null
+ if (p != null && p.trim().length() > 0) {
+ tag = p;
+ addCommandArgument("-r" + p);
+ }
+ }
+
+ /**
+ * This needs to be public to allow configuration
+ * of commands externally.
+ * @param arg command argument
+ */
+ public void addCommandArgument(String arg) {
+ this.addCommandArgument(cmd, arg);
+ }
+
+ /**
+ * This method adds a command line argument to an external command.
+ *
+ * I do not understand what this method does in this class ???
+ * particularly not why it is public ????
+ * AntoineLL July 23d 2003
+ *
+ * @param c command line to which one argument should be added
+ * @param arg argument to add
+ */
+ public void addCommandArgument(Commandline c, String arg) {
+ c.createArgument().setValue(arg);
+ }
+
+
+ /**
+ * Use the most recent revision no later than the given date.
+ * @param p a date as string in a format that the CVS executable
+ * can understand see man cvs
+ */
+ public void setDate(String p) {
+ if (p != null && p.trim().length() > 0) {
+ addCommandArgument("-D");
+ addCommandArgument(p);
+ }
+ }
+
+ /**
+ * The CVS command to execute.
+ *
+ * This should be deprecated, it is better to use the Commandline class ?
+ * AntoineLL July 23d 2003
+ *
+ * @param c a command as string
+ */
+ public void setCommand(String c) {
+ this.command = c;
+ }
+ /**
+ * accessor to a command line as string
+ *
+ * This should be deprecated
+ * AntoineLL July 23d 2003
+ *
+ * @return command line as string
+ */
+ public String getCommand() {
+ return this.command;
+ }
+
+ /**
+ * If true, suppress informational messages.
+ * @param q if true, suppress informational messages
+ */
+ public void setQuiet(boolean q) {
+ quiet = q;
+ }
+
+ /**
+ * If true, suppress all messages.
+ * @param q if true, suppress all messages
+ * @since Ant 1.6
+ */
+ public void setReallyquiet(boolean q) {
+ reallyquiet = q;
+ }
+
+
+ /**
+ * If true, report only and don't change any files.
+ *
+ * @param ne if true, report only and do not change any files.
+ */
+ public void setNoexec(boolean ne) {
+ noexec = ne;
+ }
+
+ /**
+ * The file to direct standard output from the command.
+ * @param output a file to which stdout should go
+ */
+ public void setOutput(File output) {
+ this.output = output;
+ }
+
+ /**
+ * The file to direct standard error from the command.
+ *
+ * @param error a file to which stderr should go
+ */
+ public void setError(File error) {
+ this.error = error;
+ }
+
+ /**
+ * Whether to append output/error when redirecting to a file.
+ * @param value true indicated you want to append
+ */
+ public void setAppend(boolean value) {
+ this.append = value;
+ }
+
+ /**
+ * Stop the build process if the command exits with
+ * a return code other than 0.
+ * Defaults to false.
+ * @param failOnError stop the build process if the command exits with
+ * a return code other than 0
+ */
+ public void setFailOnError(boolean failOnError) {
+ this.failOnError = failOnError;
+ }
+
+ /**
+ * Configure a commandline element for things like cvsRoot, quiet, etc.
+ * @param c the command line which will be configured
+ * if the commandline is initially null, the function is a noop
+ * otherwise the function append to the commandline arguments concerning
+ * <ul>
+ * <li>
+ * cvs package
+ * </li>
+ * <li>
+ * compression
+ * </li>
+ * <li>
+ * quiet or reallyquiet
+ * </li>
+ * <li>cvsroot</li>
+ * <li>noexec</li>
+ * </ul>
+ */
+ protected void configureCommandline(Commandline c) {
+ if (c == null) {
+ return;
+ }
+ c.setExecutable("cvs");
+ if (cvsPackage != null) {
+ c.createArgument().setLine(cvsPackage);
+ }
+ for (Module m : modules) {
+ c.createArgument().setValue(m.getName());
+ }
+ if (this.compression > 0
+ && this.compression <= MAXIMUM_COMRESSION_LEVEL) {
+ c.createArgument(true).setValue("-z" + this.compression);
+ }
+ if (quiet && !reallyquiet) {
+ c.createArgument(true).setValue("-q");
+ }
+ if (reallyquiet) {
+ c.createArgument(true).setValue("-Q");
+ }
+ if (noexec) {
+ c.createArgument(true).setValue("-n");
+ }
+ if (cvsRoot != null) {
+ c.createArgument(true).setLine("-d" + cvsRoot);
+ }
+ }
+
+ /**
+ * remove a particular command from a vector of command lines
+ * @param c command line which should be removed
+ */
+ protected void removeCommandline(Commandline c) {
+ vecCommandlines.removeElement(c);
+ }
+
+ /**
+ * Adds direct command-line to execute.
+ * @param c command line to execute
+ */
+ public void addConfiguredCommandline(Commandline c) {
+ this.addConfiguredCommandline(c, false);
+ }
+
+ /**
+ * Configures and adds the given Commandline.
+ * @param c commandline to insert
+ * @param insertAtStart If true, c is
+ * inserted at the beginning of the vector of command lines
+ */
+ public void addConfiguredCommandline(Commandline c,
+ boolean insertAtStart) {
+ if (c == null) {
+ return;
+ }
+ this.configureCommandline(c);
+ if (insertAtStart) {
+ vecCommandlines.insertElementAt(c, 0);
+ } else {
+ vecCommandlines.addElement(c);
+ }
+ }
+
+ /**
+ * If set to a value 1-9 it adds -zN to the cvs command line, else
+ * it disables compression.
+ * @param level compression level 1 to 9
+ */
+ public void setCompressionLevel(int level) {
+ this.compression = level;
+ }
+
+ /**
+ * If true, this is the same as compressionlevel="3".
+ *
+ * @param usecomp If true, turns on compression using default
+ * level, AbstractCvsTask.DEFAULT_COMPRESSION_LEVEL.
+ */
+ public void setCompression(boolean usecomp) {
+ setCompressionLevel(usecomp
+ ? AbstractCvsTask.DEFAULT_COMPRESSION_LEVEL : 0);
+ }
+
+ /**
+ * add a named module/package.
+ *
+ * @since Ant 1.8.0
+ */
+ public void addModule(Module m) {
+ modules.add(m);
+ }
+
+ protected List<Module> getModules() {
+ @SuppressWarnings("unchecked")
+ final List<Module> clone = (List<Module>) modules.clone();
+ return clone;
+ }
+
+ public static final class Module {
+ private String name;
+ public void setName(String s) {
+ name = s;
+ }
+ public String getName() {
+ return name;
+ }
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/AbstractJarSignerTask.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/AbstractJarSignerTask.java
new file mode 100644
index 00000000..bc8c0319
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/AbstractJarSignerTask.java
@@ -0,0 +1,423 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.io.File;
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.filters.LineContainsRegExp;
+import org.apache.tools.ant.types.Environment;
+import org.apache.tools.ant.types.FileSet;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.types.RedirectorElement;
+import org.apache.tools.ant.types.RegularExpression;
+import org.apache.tools.ant.util.JavaEnvUtils;
+
+/**
+ * This is factored out from {@link SignJar}; a base class that can be used
+ * for both signing and verifying JAR files using jarsigner
+ */
+
+public abstract class AbstractJarSignerTask extends Task {
+ // CheckStyle:VisibilityModifier OFF - bc
+ /**
+ * The name of the jar file.
+ */
+ protected File jar;
+ /**
+ * The alias of signer.
+ */
+ protected String alias;
+ /**
+ * The url or path of keystore file.
+ */
+ protected String keystore;
+ /**
+ * password for the store
+ */
+ protected String storepass;
+ /**
+ * type of store,-storetype param
+ */
+ protected String storetype;
+ /**
+ * password for the key in the store
+ */
+ protected String keypass;
+ /**
+ * verbose output
+ */
+ protected boolean verbose;
+ /**
+ * strict checking
+ * @since Ant 1.9.1
+ */
+ protected boolean strict = false;
+ /**
+ * The maximum amount of memory to use for Jar signer
+ */
+ protected String maxMemory;
+ /**
+ * the filesets of the jars to sign
+ */
+ protected Vector<FileSet> filesets = new Vector<FileSet>();
+ /**
+ * name of JDK program we are looking for
+ */
+ protected static final String JARSIGNER_COMMAND = "jarsigner";
+
+ // CheckStyle:VisibilityModifier ON
+
+ /**
+ * redirector used to talk to the jarsigner program
+ */
+ private RedirectorElement redirector;
+
+ /**
+ * Java declarations -J-Dname=value
+ */
+ private Environment sysProperties = new Environment();
+
+ /**
+ * error string for unit test verification: {@value}
+ */
+ public static final String ERROR_NO_SOURCE = "jar must be set through jar attribute "
+ + "or nested filesets";
+
+ /**
+ * Path holding all non-filesets of filesystem resources we want to sign.
+ *
+ * @since Ant 1.7
+ */
+ private Path path = null;
+
+ /**
+ * The executable to use instead of jarsigner.
+ *
+ * @since Ant 1.8.0
+ */
+ private String executable;
+
+ /**
+ * Set the maximum memory to be used by the jarsigner process
+ *
+ * @param max a string indicating the maximum memory according to the JVM
+ * conventions (e.g. 128m is 128 Megabytes)
+ */
+ public void setMaxmemory(String max) {
+ maxMemory = max;
+ }
+
+ /**
+ * the jar file to sign; required
+ *
+ * @param jar the jar file to sign
+ */
+ public void setJar(final File jar) {
+ this.jar = jar;
+ }
+
+ /**
+ * the alias to sign under; required
+ *
+ * @param alias the alias to sign under
+ */
+ public void setAlias(final String alias) {
+ this.alias = alias;
+ }
+
+ /**
+ * keystore location; required
+ *
+ * @param keystore the keystore location
+ */
+ public void setKeystore(final String keystore) {
+ this.keystore = keystore;
+ }
+
+ /**
+ * password for keystore integrity; required
+ *
+ * @param storepass the password for the keystore
+ */
+ public void setStorepass(final String storepass) {
+ this.storepass = storepass;
+ }
+
+ /**
+ * keystore type; optional
+ *
+ * @param storetype the keystore type
+ */
+ public void setStoretype(final String storetype) {
+ this.storetype = storetype;
+ }
+
+ /**
+ * password for private key (if different); optional
+ *
+ * @param keypass the password for the key (if different)
+ */
+ public void setKeypass(final String keypass) {
+ this.keypass = keypass;
+ }
+
+ /**
+ * Enable verbose output when signing ; optional: default false
+ *
+ * @param verbose if true enable verbose output
+ */
+ public void setVerbose(final boolean verbose) {
+ this.verbose = verbose;
+ }
+
+ /**
+ * do strict checking
+ * @since Ant 1.9.1
+ * @param strict
+ */
+ public void setStrict(boolean strict) {
+ this.strict = strict;
+ }
+
+ /**
+ * Adds a set of files to sign
+ *
+ * @param set a set of files to sign
+ * @since Ant 1.4
+ */
+ public void addFileset(final FileSet set) {
+ filesets.addElement(set);
+ }
+
+ /**
+ * Add a system property.
+ *
+ * @param sysp system property.
+ */
+ public void addSysproperty(Environment.Variable sysp) {
+ sysProperties.addVariable(sysp);
+ }
+
+ /**
+ * Adds a path of files to sign.
+ *
+ * @return a path of files to sign.
+ * @since Ant 1.7
+ */
+ public Path createPath() {
+ if (path == null) {
+ path = new Path(getProject());
+ }
+ return path.createPath();
+ }
+
+ /**
+ * init processing logic; this is retained through our execution(s)
+ */
+ protected void beginExecution() {
+
+ redirector = createRedirector();
+ }
+
+ /**
+ * any cleanup logic
+ */
+ protected void endExecution() {
+ redirector = null;
+ }
+
+ /**
+ * Create the redirector to use, if any.
+ *
+ * @return a configured RedirectorElement.
+ */
+ private RedirectorElement createRedirector() {
+ RedirectorElement result = new RedirectorElement();
+ if (storepass != null) {
+ StringBuffer input = new StringBuffer(storepass).append('\n');
+ if (keypass != null) {
+ input.append(keypass).append('\n');
+ }
+ result.setInputString(input.toString());
+ result.setLogInputString(false);
+ // Try to avoid showing password prompts on log output, as they would be confusing.
+ LineContainsRegExp filter = new LineContainsRegExp();
+ RegularExpression rx = new RegularExpression();
+ // TODO only handles English locale, not ja or zh_CN
+ rx.setPattern("^(Enter Passphrase for keystore: |Enter key password for .+: )$");
+ filter.addConfiguredRegexp(rx);
+ filter.setNegate(true);
+ result.createErrorFilterChain().addLineContainsRegExp(filter);
+ }
+ return result;
+ }
+
+ /**
+ * get the redirector. Non-null between invocations of
+ * {@link #beginExecution()} and {@link #endExecution()}
+ * @return a redirector or null
+ */
+ public RedirectorElement getRedirector() {
+ return redirector;
+ }
+
+ /**
+ * Sets the actual executable command to invoke, instead of the binary
+ * <code>jarsigner</code> found in Ant's JDK.
+ * @param executable the command to invoke.
+ * @since Ant 1.8.0
+ */
+ public void setExecutable(String executable) {
+ this.executable = executable;
+ }
+
+ /**
+ * these are options common to signing and verifying
+ * @param cmd command to configure
+ */
+ protected void setCommonOptions(final ExecTask cmd) {
+ if (maxMemory != null) {
+ addValue(cmd, "-J-Xmx" + maxMemory);
+ }
+
+ if (verbose) {
+ addValue(cmd, "-verbose");
+ }
+
+ if (strict) {
+ addValue(cmd, "-strict");
+ }
+
+ //now patch in all system properties
+ for (Environment.Variable variable : sysProperties.getVariablesVector()) {
+ declareSysProperty(cmd, variable);
+ }
+ }
+
+ /**
+ *
+ * @param cmd command to configure
+ * @param property property to set
+ * @throws BuildException if the property is not correctly defined.
+ */
+ protected void declareSysProperty(
+ ExecTask cmd, Environment.Variable property) throws BuildException {
+ addValue(cmd, "-J-D" + property.getContent());
+ }
+
+
+ /**
+ * bind to a keystore if the attributes are there
+ * @param cmd command to configure
+ */
+ protected void bindToKeystore(final ExecTask cmd) {
+ if (null != keystore) {
+ // is the keystore a file
+ addValue(cmd, "-keystore");
+ String loc;
+ File keystoreFile = getProject().resolveFile(keystore);
+ if (keystoreFile.exists()) {
+ loc = keystoreFile.getPath();
+ } else {
+ // must be a URL - just pass as is
+ loc = keystore;
+ }
+ addValue(cmd, loc);
+ }
+ if (null != storetype) {
+ addValue(cmd, "-storetype");
+ addValue(cmd, storetype);
+ }
+ }
+
+ /**
+ * create the jarsigner executable task
+ * @return a task set up with the executable of jarsigner, failonerror=true
+ * and bound to our redirector
+ */
+ protected ExecTask createJarSigner() {
+ final ExecTask cmd = new ExecTask(this);
+ if (executable == null) {
+ cmd.setExecutable(JavaEnvUtils.getJdkExecutable(JARSIGNER_COMMAND));
+ } else {
+ cmd.setExecutable(executable);
+ }
+ cmd.setTaskType(JARSIGNER_COMMAND);
+ cmd.setFailonerror(true);
+ cmd.addConfiguredRedirector(redirector);
+ return cmd;
+ }
+
+ /**
+ * clone our filesets vector, and patch in the jar attribute as a new
+ * fileset, if is defined
+ * @return a vector of FileSet instances
+ */
+ protected Vector<FileSet> createUnifiedSources() {
+ @SuppressWarnings("unchecked")
+ Vector<FileSet> sources = (Vector<FileSet>) filesets.clone();
+ if (jar != null) {
+ //we create a fileset with the source file.
+ //this lets us combine our logic for handling output directories,
+ //mapping etc.
+ FileSet sourceJar = new FileSet();
+ sourceJar.setProject(getProject());
+ sourceJar.setFile(jar);
+ sourceJar.setDir(jar.getParentFile());
+ sources.add(sourceJar);
+ }
+ return sources;
+ }
+
+ /**
+ * clone our path and add all explicitly specified FileSets as
+ * well, patch in the jar attribute as a new fileset if it is
+ * defined.
+ * @return a path that contains all files to sign
+ * @since Ant 1.7
+ */
+ protected Path createUnifiedSourcePath() {
+ Path p = path == null ? new Path(getProject()) : (Path) path.clone();
+ for (FileSet fileSet : createUnifiedSources()) {
+ p.add(fileSet);
+ }
+ return p;
+ }
+
+ /**
+ * Has either a path or a fileset been specified?
+ * @return true if a path or fileset has been specified.
+ * @since Ant 1.7
+ */
+ protected boolean hasResources() {
+ return path != null || filesets.size() > 0;
+ }
+
+ /**
+ * add a value argument to a command
+ * @param cmd command to manipulate
+ * @param value value to add
+ */
+ protected void addValue(final ExecTask cmd, String value) {
+ cmd.createArg().setValue(value);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Ant.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Ant.java
new file mode 100644
index 00000000..eba4731a
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Ant.java
@@ -0,0 +1,836 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.lang.reflect.Method;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.BuildListener;
+import org.apache.tools.ant.DefaultLogger;
+import org.apache.tools.ant.MagicNames;
+import org.apache.tools.ant.Main;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.ProjectComponent;
+import org.apache.tools.ant.ProjectHelper;
+import org.apache.tools.ant.Target;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.types.PropertySet;
+import org.apache.tools.ant.util.FileUtils;
+import org.apache.tools.ant.util.VectorSet;
+
+/**
+ * Build a sub-project.
+ *
+ * <pre>
+ * &lt;target name=&quot;foo&quot; depends=&quot;init&quot;&gt;
+ * &lt;ant antfile=&quot;build.xml&quot; target=&quot;bar&quot; &gt;
+ * &lt;property name=&quot;property1&quot; value=&quot;aaaaa&quot; /&gt;
+ * &lt;property name=&quot;foo&quot; value=&quot;baz&quot; /&gt;
+ * &lt;/ant&gt;
+ * &lt;/target&gt;
+ *
+ * &lt;target name=&quot;bar&quot; depends=&quot;init&quot;&gt;
+ * &lt;echo message=&quot;prop is ${property1} ${foo}&quot; /&gt;
+ * &lt;/target&gt;
+ * </pre>
+ *
+ *
+ * @since Ant 1.1
+ *
+ * @ant.task category="control"
+ */
+public class Ant extends Task {
+
+ private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+
+ /** the basedir where is executed the build file */
+ private File dir = null;
+
+ /**
+ * the build.xml file (can be absolute) in this case dir will be
+ * ignored
+ */
+ private String antFile = null;
+
+ /** the output */
+ private String output = null;
+
+ /** should we inherit properties from the parent ? */
+ private boolean inheritAll = true;
+
+ /** should we inherit references from the parent ? */
+ private boolean inheritRefs = false;
+
+ /** the properties to pass to the new project */
+ private Vector<Property> properties = new Vector<Property>();
+
+ /** the references to pass to the new project */
+ private Vector<Reference> references = new Vector<Reference>();
+
+ /** the temporary project created to run the build file */
+ private Project newProject;
+
+ /** The stream to which output is to be written. */
+ private PrintStream out = null;
+
+ /** the sets of properties to pass to the new project */
+ private Vector<PropertySet> propertySets = new Vector<PropertySet>();
+
+ /** the targets to call on the new project */
+ private Vector<String> targets = new Vector<String>();
+
+ /** whether the target attribute was specified **/
+ private boolean targetAttributeSet = false;
+
+ /**
+ * Whether the basedir of the new project should be the same one
+ * as it would be when running the build file directly -
+ * independent of dir and/or inheritAll settings.
+ *
+ * @since Ant 1.8.0
+ */
+ private boolean useNativeBasedir = false;
+
+ /**
+ * simple constructor
+ */
+ public Ant() {
+ //default
+ }
+
+ /**
+ * create a task bound to its creator
+ * @param owner owning task
+ */
+ public Ant(Task owner) {
+ bindToOwner(owner);
+ }
+
+ /**
+ * Whether the basedir of the new project should be the same one
+ * as it would be when running the build file directly -
+ * independent of dir and/or inheritAll settings.
+ *
+ * @since Ant 1.8.0
+ */
+ public void setUseNativeBasedir(boolean b) {
+ useNativeBasedir = b;
+ }
+
+ /**
+ * If true, pass all properties to the new Ant project.
+ * Defaults to true.
+ * @param value if true pass all properties to the new Ant project.
+ */
+ public void setInheritAll(boolean value) {
+ inheritAll = value;
+ }
+
+ /**
+ * If true, pass all references to the new Ant project.
+ * Defaults to false.
+ * @param value if true, pass all references to the new Ant project
+ */
+ public void setInheritRefs(boolean value) {
+ inheritRefs = value;
+ }
+
+ /**
+ * Creates a Project instance for the project to call.
+ */
+ public void init() {
+ newProject = getProject().createSubProject();
+ newProject.setJavaVersionProperty();
+ }
+
+ /**
+ * Called in execute or createProperty (via getNewProject())
+ * if newProject is null.
+ *
+ * <p>This can happen if the same instance of this task is run
+ * twice as newProject is set to null at the end of execute (to
+ * save memory and help the GC).</p>
+ * <p>calls init() again</p>
+ *
+ */
+ private void reinit() {
+ init();
+ }
+
+ /**
+ * Attaches the build listeners of the current project to the new
+ * project, configures a possible logfile, transfers task and
+ * data-type definitions, transfers properties (either all or just
+ * the ones specified as user properties to the current project,
+ * depending on inheritall), transfers the input handler.
+ */
+ private void initializeProject() {
+ newProject.setInputHandler(getProject().getInputHandler());
+
+ Iterator<BuildListener> iter = getBuildListeners();
+ while (iter.hasNext()) {
+ newProject.addBuildListener((BuildListener) iter.next());
+ }
+
+ if (output != null) {
+ File outfile = null;
+ if (dir != null) {
+ outfile = FILE_UTILS.resolveFile(dir, output);
+ } else {
+ outfile = getProject().resolveFile(output);
+ }
+ try {
+ out = new PrintStream(new FileOutputStream(outfile));
+ DefaultLogger logger = new DefaultLogger();
+ logger.setMessageOutputLevel(Project.MSG_INFO);
+ logger.setOutputPrintStream(out);
+ logger.setErrorPrintStream(out);
+ newProject.addBuildListener(logger);
+ } catch (IOException ex) {
+ log("Ant: Can't set output to " + output);
+ }
+ }
+ // set user-defined properties
+ if (useNativeBasedir) {
+ addAlmostAll(getProject().getUserProperties(), PropertyType.USER);
+ } else {
+ getProject().copyUserProperties(newProject);
+ }
+
+ if (!inheritAll) {
+ // set Ant's built-in properties separately,
+ // because they are not being inherited.
+ newProject.initProperties();
+
+ } else {
+ // set all properties from calling project
+ addAlmostAll(getProject().getProperties(), PropertyType.PLAIN);
+ }
+
+ for (PropertySet ps : propertySets) {
+ addAlmostAll(ps.getProperties(), PropertyType.PLAIN);
+ }
+ }
+
+ /**
+ * Handles output.
+ * Send it the the new project if is present, otherwise
+ * call the super class.
+ * @param outputToHandle The string output to output.
+ * @see Task#handleOutput(String)
+ * @since Ant 1.5
+ */
+ public void handleOutput(String outputToHandle) {
+ if (newProject != null) {
+ newProject.demuxOutput(outputToHandle, false);
+ } else {
+ super.handleOutput(outputToHandle);
+ }
+ }
+
+ /**
+ * Handles input.
+ * Delegate to the created project, if present, otherwise
+ * call the super class.
+ * @param buffer the buffer into which data is to be read.
+ * @param offset the offset into the buffer at which data is stored.
+ * @param length the amount of data to read.
+ *
+ * @return the number of bytes read.
+ *
+ * @exception IOException if the data cannot be read.
+ * @see Task#handleInput(byte[], int, int)
+ * @since Ant 1.6
+ */
+ public int handleInput(byte[] buffer, int offset, int length)
+ throws IOException {
+ if (newProject != null) {
+ return newProject.demuxInput(buffer, offset, length);
+ }
+ return super.handleInput(buffer, offset, length);
+ }
+
+ /**
+ * Handles output.
+ * Send it the the new project if is present, otherwise
+ * call the super class.
+ * @param toFlush The string to output.
+ * @see Task#handleFlush(String)
+ * @since Ant 1.5.2
+ */
+ public void handleFlush(String toFlush) {
+ if (newProject != null) {
+ newProject.demuxFlush(toFlush, false);
+ } else {
+ super.handleFlush(toFlush);
+ }
+ }
+
+ /**
+ * Handle error output.
+ * Send it the the new project if is present, otherwise
+ * call the super class.
+ * @param errorOutputToHandle The string to output.
+ *
+ * @see Task#handleErrorOutput(String)
+ * @since Ant 1.5
+ */
+ public void handleErrorOutput(String errorOutputToHandle) {
+ if (newProject != null) {
+ newProject.demuxOutput(errorOutputToHandle, true);
+ } else {
+ super.handleErrorOutput(errorOutputToHandle);
+ }
+ }
+
+ /**
+ * Handle error output.
+ * Send it the the new project if is present, otherwise
+ * call the super class.
+ * @param errorOutputToFlush The string to output.
+ * @see Task#handleErrorFlush(String)
+ * @since Ant 1.5.2
+ */
+ public void handleErrorFlush(String errorOutputToFlush) {
+ if (newProject != null) {
+ newProject.demuxFlush(errorOutputToFlush, true);
+ } else {
+ super.handleErrorFlush(errorOutputToFlush);
+ }
+ }
+
+ /**
+ * Do the execution.
+ * @throws BuildException if a target tries to call itself;
+ * probably also if a BuildException is thrown by the new project.
+ */
+ public void execute() throws BuildException {
+ File savedDir = dir;
+ String savedAntFile = antFile;
+ Vector<String> locals = new VectorSet<String>(targets);
+ try {
+ getNewProject();
+
+ if (dir == null && inheritAll) {
+ dir = getProject().getBaseDir();
+ }
+
+ initializeProject();
+
+ if (dir != null) {
+ if (!useNativeBasedir) {
+ newProject.setBaseDir(dir);
+ if (savedDir != null) {
+ // has been set explicitly
+ newProject.setInheritedProperty(MagicNames.PROJECT_BASEDIR,
+ dir.getAbsolutePath());
+ }
+ }
+ } else {
+ dir = getProject().getBaseDir();
+ }
+
+ overrideProperties();
+
+ if (antFile == null) {
+ antFile = getDefaultBuildFile();
+ }
+
+ File file = FILE_UTILS.resolveFile(dir, antFile);
+ antFile = file.getAbsolutePath();
+
+ log("calling target(s) "
+ + ((locals.size() > 0) ? locals.toString() : "[default]")
+ + " in build file " + antFile, Project.MSG_VERBOSE);
+ newProject.setUserProperty(MagicNames.ANT_FILE , antFile);
+
+ String thisAntFile = getProject().getProperty(MagicNames.ANT_FILE);
+ // Are we trying to call the target in which we are defined (or
+ // the build file if this is a top level task)?
+ if (thisAntFile != null
+ && file.equals(getProject().resolveFile(thisAntFile))
+ && getOwningTarget() != null) {
+
+ if (getOwningTarget().getName().equals("")) {
+ if (getTaskName().equals("antcall")) {
+ throw new BuildException("antcall must not be used at"
+ + " the top level.");
+ }
+ throw new BuildException(getTaskName() + " task at the"
+ + " top level must not invoke"
+ + " its own build file.");
+ }
+ }
+
+ try {
+ ProjectHelper.configureProject(newProject, file);
+ } catch (BuildException ex) {
+ throw ProjectHelper.addLocationToBuildException(
+ ex, getLocation());
+ }
+
+ if (locals.size() == 0) {
+ String defaultTarget = newProject.getDefaultTarget();
+ if (defaultTarget != null) {
+ locals.add(defaultTarget);
+ }
+ }
+
+ if (newProject.getProperty(MagicNames.ANT_FILE)
+ .equals(getProject().getProperty(MagicNames.ANT_FILE))
+ && getOwningTarget() != null) {
+
+ String owningTargetName = getOwningTarget().getName();
+
+ if (locals.contains(owningTargetName)) {
+ throw new BuildException(getTaskName() + " task calling "
+ + "its own parent target.");
+ }
+ boolean circular = false;
+ for (Iterator<String> it = locals.iterator();
+ !circular && it.hasNext();) {
+ Target other =
+ getProject().getTargets().get(it.next());
+ circular |= (other != null
+ && other.dependsOn(owningTargetName));
+ }
+ if (circular) {
+ throw new BuildException(getTaskName()
+ + " task calling a target"
+ + " that depends on"
+ + " its parent target \'"
+ + owningTargetName
+ + "\'.");
+ }
+ }
+
+ addReferences();
+
+ if (locals.size() > 0 && !(locals.size() == 1
+ && "".equals(locals.get(0)))) {
+ BuildException be = null;
+ try {
+ log("Entering " + antFile + "...", Project.MSG_VERBOSE);
+ newProject.fireSubBuildStarted();
+ newProject.executeTargets(locals);
+ } catch (BuildException ex) {
+ be = ProjectHelper
+ .addLocationToBuildException(ex, getLocation());
+ throw be;
+ } finally {
+ log("Exiting " + antFile + ".", Project.MSG_VERBOSE);
+ newProject.fireSubBuildFinished(be);
+ }
+ }
+ } finally {
+ // help the gc
+ newProject = null;
+ for (Property p : properties) {
+ p.setProject(null);
+ }
+
+ if (output != null && out != null) {
+ try {
+ out.close();
+ } catch (final Exception ex) {
+ //ignore
+ }
+ }
+ dir = savedDir;
+ antFile = savedAntFile;
+ }
+ }
+
+ /**
+ * Get the default build file name to use when launching the task.
+ * <p>
+ * This function may be overrided by providers of custom ProjectHelper so they can implement easily their sub
+ * launcher.
+ *
+ * @return the name of the default file
+ * @since Ant 1.8.0
+ */
+ protected String getDefaultBuildFile() {
+ return Main.DEFAULT_BUILD_FILENAME;
+ }
+
+ /**
+ * Override the properties in the new project with the one
+ * explicitly defined as nested elements here.
+ * @throws BuildException under unknown circumstances.
+ */
+ private void overrideProperties() throws BuildException {
+ // remove duplicate properties - last property wins
+ // Needed for backward compatibility
+ Set<String> set = new HashSet<String>();
+ for (int i = properties.size() - 1; i >= 0; --i) {
+ Property p = properties.get(i);
+ if (p.getName() != null && !p.getName().equals("")) {
+ if (set.contains(p.getName())) {
+ properties.remove(i);
+ } else {
+ set.add(p.getName());
+ }
+ }
+ }
+ Enumeration<Property> e = properties.elements();
+ while (e.hasMoreElements()) {
+ Property p = e.nextElement();
+ p.setProject(newProject);
+ p.execute();
+ }
+ if (useNativeBasedir) {
+ addAlmostAll(getProject().getInheritedProperties(),
+ PropertyType.INHERITED);
+ } else {
+ getProject().copyInheritedProperties(newProject);
+ }
+ }
+
+ /**
+ * Add the references explicitly defined as nested elements to the
+ * new project. Also copy over all references that don't override
+ * existing references in the new project if inheritrefs has been
+ * requested.
+ * @throws BuildException if a reference does not have a refid.
+ */
+ private void addReferences() throws BuildException {
+ @SuppressWarnings("unchecked")
+ Hashtable<String, Object> thisReferences
+ = (Hashtable<String, Object>) getProject().getReferences().clone();
+ for (Reference ref : references) {
+ String refid = ref.getRefId();
+ if (refid == null) {
+ throw new BuildException("the refid attribute is required"
+ + " for reference elements");
+ }
+ if (!thisReferences.containsKey(refid)) {
+ log("Parent project doesn't contain any reference '"
+ + refid + "'",
+ Project.MSG_WARN);
+ continue;
+ }
+
+ thisReferences.remove(refid);
+ String toRefid = ref.getToRefid();
+ if (toRefid == null) {
+ toRefid = refid;
+ }
+ copyReference(refid, toRefid);
+ }
+
+ // Now add all references that are not defined in the
+ // subproject, if inheritRefs is true
+ if (inheritRefs) {
+ Hashtable<String, Object> newReferences = newProject.getReferences();
+ for (String key : thisReferences.keySet()) {
+ if (newReferences.containsKey(key)) {
+ continue;
+ }
+ copyReference(key, key);
+ newProject.inheritIDReferences(getProject());
+ }
+ }
+ }
+
+ /**
+ * Try to clone and reconfigure the object referenced by oldkey in
+ * the parent project and add it to the new project with the key newkey.
+ *
+ * <p>If we cannot clone it, copy the referenced object itself and
+ * keep our fingers crossed.</p>
+ * @param oldKey the reference id in the current project.
+ * @param newKey the reference id in the new project.
+ */
+ private void copyReference(String oldKey, String newKey) {
+ Object orig = getProject().getReference(oldKey);
+ if (orig == null) {
+ log("No object referenced by " + oldKey + ". Can't copy to "
+ + newKey,
+ Project.MSG_WARN);
+ return;
+ }
+
+ Class<?> c = orig.getClass();
+ Object copy = orig;
+ try {
+ Method cloneM = c.getMethod("clone", new Class[0]);
+ if (cloneM != null) {
+ copy = cloneM.invoke(orig, new Object[0]);
+ log("Adding clone of reference " + oldKey, Project.MSG_DEBUG);
+ }
+ } catch (Exception e) {
+ // not Clonable
+ }
+
+
+ if (copy instanceof ProjectComponent) {
+ ((ProjectComponent) copy).setProject(newProject);
+ } else {
+ try {
+ Method setProjectM =
+ c.getMethod("setProject", new Class[] {Project.class});
+ if (setProjectM != null) {
+ setProjectM.invoke(copy, new Object[] {newProject});
+ }
+ } catch (NoSuchMethodException e) {
+ // ignore this if the class being referenced does not have
+ // a set project method.
+ } catch (Exception e2) {
+ String msg = "Error setting new project instance for "
+ + "reference with id " + oldKey;
+ throw new BuildException(msg, e2, getLocation());
+ }
+ }
+ newProject.addReference(newKey, copy);
+ }
+
+ /**
+ * Copies all properties from the given table to the new project -
+ * omitting those that have already been set in the new project as
+ * well as properties named basedir or ant.file.
+ * @param props properties <code>Hashtable</code> to copy to the
+ * new project.
+ * @param the type of property to set (a plain Ant property, a
+ * user property or an inherited property).
+ * @since Ant 1.8.0
+ */
+ private void addAlmostAll(Hashtable<?, ?> props, PropertyType type) {
+ Enumeration<?> e = props.keys();
+ while (e.hasMoreElements()) {
+ String key = e.nextElement().toString();
+ if (MagicNames.PROJECT_BASEDIR.equals(key)
+ || MagicNames.ANT_FILE.equals(key)) {
+ // basedir and ant.file get special treatment in execute()
+ continue;
+ }
+
+ String value = props.get(key).toString();
+ if (type == PropertyType.PLAIN) {
+ // don't re-set user properties, avoid the warning message
+ if (newProject.getProperty(key) == null) {
+ // no user property
+ newProject.setNewProperty(key, value);
+ }
+ } else if (type == PropertyType.USER) {
+ newProject.setUserProperty(key, value);
+ } else if (type == PropertyType.INHERITED) {
+ newProject.setInheritedProperty(key, value);
+ }
+ }
+ }
+
+ /**
+ * The directory to use as a base directory for the new Ant project.
+ * Defaults to the current project's basedir, unless inheritall
+ * has been set to false, in which case it doesn't have a default
+ * value. This will override the basedir setting of the called project.
+ * @param dir new directory as <code>File</code>.
+ */
+ public void setDir(File dir) {
+ this.dir = dir;
+ }
+
+ /**
+ * The build file to use. Defaults to "build.xml". This file is expected
+ * to be a filename relative to the dir attribute given.
+ * @param antFile the <code>String</code> build file name.
+ */
+ public void setAntfile(String antFile) {
+ // @note: it is a string and not a file to handle relative/absolute
+ // otherwise a relative file will be resolved based on the current
+ // basedir.
+ this.antFile = antFile;
+ }
+
+ /**
+ * The target of the new Ant project to execute.
+ * Defaults to the new project's default target.
+ * @param targetToAdd the name of the target to invoke.
+ */
+ public void setTarget(String targetToAdd) {
+ if (targetToAdd.equals("")) {
+ throw new BuildException("target attribute must not be empty");
+ }
+ targets.add(targetToAdd);
+ targetAttributeSet = true;
+ }
+
+ /**
+ * Set the filename to write the output to. This is relative to the value
+ * of the dir attribute if it has been set or to the base directory of the
+ * current project otherwise.
+ * @param outputFile the name of the file to which the output should go.
+ */
+ public void setOutput(String outputFile) {
+ this.output = outputFile;
+ }
+
+ /**
+ * Property to pass to the new project.
+ * The property is passed as a 'user property'.
+ * @return the created <code>Property</code> object.
+ */
+ public Property createProperty() {
+ Property p = new Property(true, getProject());
+ p.setProject(getNewProject());
+ p.setTaskName("property");
+ properties.addElement(p);
+ return p;
+ }
+
+ /**
+ * Add a Reference element identifying a data type to carry
+ * over to the new project.
+ * @param ref <code>Reference</code> to add.
+ */
+ public void addReference(Reference ref) {
+ references.addElement(ref);
+ }
+
+ /**
+ * Add a target to this Ant invocation.
+ * @param t the <code>TargetElement</code> to add.
+ * @since Ant 1.6.3
+ */
+ public void addConfiguredTarget(TargetElement t) {
+ if (targetAttributeSet) {
+ throw new BuildException(
+ "nested target is incompatible with the target attribute");
+ }
+ String name = t.getName();
+ if (name.equals("")) {
+ throw new BuildException("target name must not be empty");
+ }
+ targets.add(name);
+ }
+
+ /**
+ * Add a set of properties to pass to the new project.
+ *
+ * @param ps <code>PropertySet</code> to add.
+ * @since Ant 1.6
+ */
+ public void addPropertyset(PropertySet ps) {
+ propertySets.addElement(ps);
+ }
+
+ /**
+ * Get the (sub)-Project instance currently in use.
+ * @return Project
+ * @since Ant 1.7
+ */
+ protected Project getNewProject() {
+ if (newProject == null) {
+ reinit();
+ }
+ return newProject;
+ }
+
+ /**
+ * @since Ant 1.6.2
+ */
+ private Iterator<BuildListener> getBuildListeners() {
+ return getProject().getBuildListeners().iterator();
+ }
+
+ /**
+ * Helper class that implements the nested &lt;reference&gt;
+ * element of &lt;ant&gt; and &lt;antcall&gt;.
+ */
+ public static class Reference
+ extends org.apache.tools.ant.types.Reference {
+
+ /** Creates a reference to be configured by Ant. */
+ public Reference() {
+ super();
+ }
+
+ private String targetid = null;
+
+ /**
+ * Set the id that this reference to be stored under in the
+ * new project.
+ *
+ * @param targetid the id under which this reference will be passed to
+ * the new project. */
+ public void setToRefid(String targetid) {
+ this.targetid = targetid;
+ }
+
+ /**
+ * Get the id under which this reference will be stored in the new
+ * project.
+ *
+ * @return the id of the reference in the new project.
+ */
+ public String getToRefid() {
+ return targetid;
+ }
+ }
+
+ /**
+ * Helper class that implements the nested &lt;target&gt;
+ * element of &lt;ant&gt; and &lt;antcall&gt;.
+ * @since Ant 1.6.3
+ */
+ public static class TargetElement {
+ private String name;
+
+ /**
+ * Default constructor.
+ */
+ public TargetElement() {
+ //default
+ }
+
+ /**
+ * Set the name of this TargetElement.
+ * @param name the <code>String</code> target name.
+ */
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ /**
+ * Get the name of this TargetElement.
+ * @return <code>String</code>.
+ */
+ public String getName() {
+ return name;
+ }
+ }
+
+ private static final class PropertyType {
+ private PropertyType() {}
+ private static final PropertyType PLAIN = new PropertyType();
+ private static final PropertyType INHERITED = new PropertyType();
+ private static final PropertyType USER = new PropertyType();
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/AntStructure.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/AntStructure.java
new file mode 100644
index 00000000..20f811a8
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/AntStructure.java
@@ -0,0 +1,485 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.io.UnsupportedEncodingException;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.IntrospectionHelper;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.TaskContainer;
+import org.apache.tools.ant.types.EnumeratedAttribute;
+import org.apache.tools.ant.types.Reference;
+
+/**
+ * Creates a partial DTD for Ant from the currently known tasks.
+ *
+ *
+ * @since Ant 1.1
+ *
+ * @ant.task category="xml"
+ */
+public class AntStructure extends Task {
+
+ private static final String LINE_SEP
+ = System.getProperty("line.separator");
+
+ private File output;
+ private StructurePrinter printer = new DTDPrinter();
+
+ /**
+ * The output file.
+ * @param output the output file
+ */
+ public void setOutput(final File output) {
+ this.output = output;
+ }
+
+ /**
+ * The StructurePrinter to use.
+ * @param p the printer to use.
+ * @since Ant 1.7
+ */
+ public void add(final StructurePrinter p) {
+ printer = p;
+ }
+
+ /**
+ * Build the antstructure DTD.
+ *
+ * @exception BuildException if the DTD cannot be written.
+ */
+ @Override
+ public void execute() throws BuildException {
+
+ if (output == null) {
+ throw new BuildException("output attribute is required", getLocation());
+ }
+
+ PrintWriter out = null;
+ try {
+ try {
+ out = new PrintWriter(new OutputStreamWriter(new FileOutputStream(output), "UTF8"));
+ } catch (final UnsupportedEncodingException ue) {
+ /*
+ * Plain impossible with UTF8, see
+ * http://java.sun.com/j2se/1.5.0/docs/guide/intl/encoding.doc.html
+ *
+ * fallback to platform specific anyway.
+ */
+ out = new PrintWriter(new FileWriter(output));
+ }
+
+ printer.printHead(out, getProject(),
+ new Hashtable<String, Class<?>>(getProject().getTaskDefinitions()),
+ new Hashtable<String, Class<?>>(getProject().getDataTypeDefinitions()));
+
+ printer.printTargetDecl(out);
+
+ for (final String typeName : getProject().getCopyOfDataTypeDefinitions()
+ .keySet()) {
+ printer.printElementDecl(
+ out, getProject(), typeName,
+ getProject().getDataTypeDefinitions().get(typeName));
+ }
+
+ for (final String tName : getProject().getCopyOfTaskDefinitions().keySet()) {
+ printer.printElementDecl(out, getProject(), tName,
+ getProject().getTaskDefinitions().get(tName));
+ }
+
+ printer.printTail(out);
+
+ if (out.checkError()) {
+ throw new IOException("Encountered an error writing Ant"
+ + " structure");
+ }
+ } catch (final IOException ioe) {
+ throw new BuildException("Error writing "
+ + output.getAbsolutePath(), ioe, getLocation());
+ } finally {
+ if (out != null) {
+ out.close();
+ }
+ }
+ }
+
+ /**
+ * Writes the actual structure information.
+ *
+ * <p>{@link #printHead}, {@link #printTargetDecl} and {@link #printTail}
+ * are called exactly once, {@link #printElementDecl} once for
+ * each declared task and type.</p>
+ */
+ public interface StructurePrinter {
+ /**
+ * Prints the header of the generated output.
+ *
+ * @param out PrintWriter to write to.
+ * @param p Project instance for the current task
+ * @param tasks map (name to implementing class)
+ * @param types map (name to implementing class)
+ * data types.
+ */
+ void printHead(PrintWriter out, Project p, Hashtable<String, Class<?>> tasks,
+ Hashtable<String, Class<?>> types);
+
+ /**
+ * Prints the definition for the target element.
+ * @param out PrintWriter to write to.
+ */
+ void printTargetDecl(PrintWriter out);
+
+ /**
+ * Print the definition for a given element.
+ *
+ * @param out PrintWriter to write to.
+ * @param p Project instance for the current task
+ * @param name element name.
+ * @param element class of the defined element.
+ */
+ void printElementDecl(PrintWriter out, Project p, String name,
+ Class<?> element);
+
+ /**
+ * Prints the trailer.
+ * @param out PrintWriter to write to.
+ */
+ void printTail(PrintWriter out);
+ }
+
+ private static class DTDPrinter implements StructurePrinter {
+
+ private static final String BOOLEAN = "%boolean;";
+ private static final String TASKS = "%tasks;";
+ private static final String TYPES = "%types;";
+
+ private final Hashtable<String, String> visited = new Hashtable<String, String>();
+
+ public void printTail(final PrintWriter out) {
+ visited.clear();
+ }
+
+ public void printHead(final PrintWriter out, final Project p, final Hashtable<String, Class<?>> tasks,
+ final Hashtable<String, Class<?>> types) {
+ printHead(out, tasks.keys(), types.keys());
+ }
+
+
+ /**
+ * Prints the header of the generated output.
+ *
+ * <p>Basically this prints the XML declaration, defines some
+ * entities and the project element.</p>
+ */
+ private void printHead(final PrintWriter out, final Enumeration<String> tasks,
+ final Enumeration<String> types) {
+ out.println("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>");
+ out.println("<!ENTITY % boolean \"(true|false|on|off|yes|no)\">");
+ out.print("<!ENTITY % tasks \"");
+ boolean first = true;
+ while (tasks.hasMoreElements()) {
+ final String tName = tasks.nextElement();
+ if (!first) {
+ out.print(" | ");
+ } else {
+ first = false;
+ }
+ out.print(tName);
+ }
+ out.println("\">");
+ out.print("<!ENTITY % types \"");
+ first = true;
+ while (types.hasMoreElements()) {
+ final String typeName = types.nextElement();
+ if (!first) {
+ out.print(" | ");
+ } else {
+ first = false;
+ }
+ out.print(typeName);
+ }
+ out.println("\">");
+
+ out.println("");
+
+ out.print("<!ELEMENT project (target | extension-point | ");
+ out.print(TASKS);
+ out.print(" | ");
+ out.print(TYPES);
+ out.println(")*>");
+ out.println("<!ATTLIST project");
+ out.println(" name CDATA #IMPLIED");
+ out.println(" default CDATA #IMPLIED");
+ out.println(" basedir CDATA #IMPLIED>");
+ out.println("");
+ }
+
+ /**
+ * Prints the definition for the target element.
+ */
+ public void printTargetDecl(final PrintWriter out) {
+ out.print("<!ELEMENT target (");
+ out.print(TASKS);
+ out.print(" | ");
+ out.print(TYPES);
+ out.println(")*>");
+ out.println("");
+ printTargetAttrs(out, "target");
+ out.println("<!ELEMENT extension-point EMPTY>");
+ out.println("");
+ printTargetAttrs(out, "extension-point");
+ }
+
+ /**
+ * Prints the definition for the target element.
+ */
+ private void printTargetAttrs(final PrintWriter out, final String tag) {
+ out.print("<!ATTLIST ");
+ out.println(tag);
+ out.println(" id ID #IMPLIED");
+ out.println(" name CDATA #REQUIRED");
+ out.println(" if CDATA #IMPLIED");
+ out.println(" unless CDATA #IMPLIED");
+ out.println(" depends CDATA #IMPLIED");
+ out.println(" extensionOf CDATA #IMPLIED");
+ out.println(" onMissingExtensionPoint CDATA #IMPLIED");
+ out.println(" description CDATA #IMPLIED>");
+ out.println("");
+ }
+
+ /**
+ * Print the definition for a given element.
+ */
+ public void printElementDecl(final PrintWriter out, final Project p,
+ final String name, final Class<?> element) {
+
+ if (visited.containsKey(name)) {
+ return;
+ }
+ visited.put(name, "");
+
+ IntrospectionHelper ih = null;
+ try {
+ ih = IntrospectionHelper.getHelper(p, element);
+ } catch (final Throwable t) {
+ /*
+ * TODO - failed to load the class properly.
+ *
+ * should we print a warning here?
+ */
+ return;
+ }
+
+ StringBuffer sb = new StringBuffer("<!ELEMENT ");
+ sb.append(name).append(" ");
+
+ if (org.apache.tools.ant.types.Reference.class.equals(element)) {
+ sb.append("EMPTY>").append(LINE_SEP);
+ sb.append("<!ATTLIST ").append(name);
+ sb.append(LINE_SEP).append(" id ID #IMPLIED");
+ sb.append(LINE_SEP).append(" refid IDREF #IMPLIED");
+ sb.append(">").append(LINE_SEP);
+ out.println(sb);
+ return;
+ }
+
+ final Vector<String> v = new Vector<String>();
+ if (ih.supportsCharacters()) {
+ v.addElement("#PCDATA");
+ }
+
+ if (TaskContainer.class.isAssignableFrom(element)) {
+ v.addElement(TASKS);
+ }
+
+ Enumeration<String> e = ih.getNestedElements();
+ while (e.hasMoreElements()) {
+ v.addElement(e.nextElement());
+ }
+
+ if (v.isEmpty()) {
+ sb.append("EMPTY");
+ } else {
+ sb.append("(");
+ final int count = v.size();
+ for (int i = 0; i < count; i++) {
+ if (i != 0) {
+ sb.append(" | ");
+ }
+ sb.append(v.elementAt(i));
+ }
+ sb.append(")");
+ if (count > 1 || !v.elementAt(0).equals("#PCDATA")) {
+ sb.append("*");
+ }
+ }
+ sb.append(">");
+ out.println(sb);
+
+ sb = new StringBuffer("<!ATTLIST ");
+ sb.append(name);
+ sb.append(LINE_SEP).append(" id ID #IMPLIED");
+
+ e = ih.getAttributes();
+ while (e.hasMoreElements()) {
+ final String attrName = e.nextElement();
+ if ("id".equals(attrName)) {
+ continue;
+ }
+
+ sb.append(LINE_SEP).append(" ")
+ .append(attrName).append(" ");
+ final Class<?> type = ih.getAttributeType(attrName);
+ if (type.equals(java.lang.Boolean.class)
+ || type.equals(java.lang.Boolean.TYPE)) {
+ sb.append(BOOLEAN).append(" ");
+ } else if (Reference.class.isAssignableFrom(type)) {
+ sb.append("IDREF ");
+ } else if (EnumeratedAttribute.class.isAssignableFrom(type)) {
+ try {
+ final EnumeratedAttribute ea =
+ (EnumeratedAttribute) type.newInstance();
+ final String[] values = ea.getValues();
+ if (values == null
+ || values.length == 0
+ || !areNmtokens(values)) {
+ sb.append("CDATA ");
+ } else {
+ sb.append("(");
+ for (int i = 0; i < values.length; i++) {
+ if (i != 0) {
+ sb.append(" | ");
+ }
+ sb.append(values[i]);
+ }
+ sb.append(") ");
+ }
+ } catch (final InstantiationException ie) {
+ sb.append("CDATA ");
+ } catch (final IllegalAccessException ie) {
+ sb.append("CDATA ");
+ }
+ } else if (type.getSuperclass() != null
+ && type.getSuperclass().getName().equals("java.lang.Enum")) {
+ try {
+ final Object[] values = (Object[]) type.getMethod("values", (Class[]) null)
+ .invoke(null, (Object[]) null);
+ if (values.length == 0) {
+ sb.append("CDATA ");
+ } else {
+ sb.append('(');
+ for (int i = 0; i < values.length; i++) {
+ if (i != 0) {
+ sb.append(" | ");
+ }
+ sb.append(type.getMethod("name", (Class[]) null)
+ .invoke(values[i], (Object[]) null));
+ }
+ sb.append(") ");
+ }
+ } catch (final Exception x) {
+ sb.append("CDATA ");
+ }
+ } else {
+ sb.append("CDATA ");
+ }
+ sb.append("#IMPLIED");
+ }
+ sb.append(">").append(LINE_SEP);
+ out.println(sb);
+
+ final int count = v.size();
+ for (int i = 0; i < count; i++) {
+ final String nestedName = v.elementAt(i);
+ if (!"#PCDATA".equals(nestedName)
+ && !TASKS.equals(nestedName)
+ && !TYPES.equals(nestedName)) {
+ printElementDecl(out, p, nestedName, ih.getElementType(nestedName));
+ }
+ }
+ }
+
+ /**
+ * Does this String match the XML-NMTOKEN production?
+ * @param s the string to test
+ * @return true if the string matches the XML-NMTOKEN
+ */
+ public static final boolean isNmtoken(final String s) {
+ final int length = s.length();
+ for (int i = 0; i < length; i++) {
+ final char c = s.charAt(i);
+ // TODO - we are committing CombiningChar and Extender here
+ if (!Character.isLetterOrDigit(c)
+ && c != '.' && c != '-' && c != '_' && c != ':') {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Do the Strings all match the XML-NMTOKEN production?
+ *
+ * <p>Otherwise they are not suitable as an enumerated attribute,
+ * for example.</p>
+ * @param s the array of string to test
+ * @return true if all the strings in the array math XML-NMTOKEN
+ */
+ public static final boolean areNmtokens(final String[] s) {
+ for (int i = 0; i < s.length; i++) {
+ if (!isNmtoken(s[i])) {
+ return false;
+ }
+ }
+ return true;
+ }
+ }
+
+ /**
+ * Does this String match the XML-NMTOKEN production?
+ * @param s the string to test
+ * @return true if the string matches the XML-NMTOKEN
+ */
+ protected boolean isNmtoken(final String s) {
+ return DTDPrinter.isNmtoken(s);
+ }
+
+ /**
+ * Do the Strings all match the XML-NMTOKEN production?
+ *
+ * <p>Otherwise they are not suitable as an enumerated attribute,
+ * for example.</p>
+ * @param s the array of string to test
+ * @return true if all the strings in the array math XML-NMTOKEN
+ */
+ protected boolean areNmtokens(final String[] s) {
+ return DTDPrinter.areNmtokens(s);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Antlib.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Antlib.java
new file mode 100644
index 00000000..8ff836a3
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Antlib.java
@@ -0,0 +1,184 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.io.IOException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.ComponentHelper;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.ProjectHelper;
+import org.apache.tools.ant.ProjectHelperRepository;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.TaskContainer;
+import org.apache.tools.ant.UnknownElement;
+import org.apache.tools.ant.types.resources.URLResource;
+
+
+/**
+ * Antlib task. It does not
+ * occur in an ant build file. It is the root element
+ * an antlib xml file.
+ *
+ * @since Ant 1.6
+ */
+public class Antlib extends Task implements TaskContainer {
+ //
+ // Static
+ //
+
+ /** The name of this task */
+ public static final String TAG = "antlib";
+
+ /**
+ * Static method to read an ant lib definition from
+ * a url.
+ *
+ * @param project the current project
+ * @param antlibUrl the url to read the definitions from
+ * @param uri the uri that the antlib is to be placed in
+ * @return the ant lib task
+ */
+ public static Antlib createAntlib(Project project, URL antlibUrl,
+ String uri) {
+ // Check if we can contact the URL
+ try {
+ URLConnection conn = antlibUrl.openConnection();
+ conn.setUseCaches(false);
+ conn.connect();
+ } catch (IOException ex) {
+ throw new BuildException(
+ "Unable to find " + antlibUrl, ex);
+ }
+ ComponentHelper helper =
+ ComponentHelper.getComponentHelper(project);
+ helper.enterAntLib(uri);
+ URLResource antlibResource = new URLResource(antlibUrl);
+ try {
+ // Should be safe to parse
+ ProjectHelper parser = null;
+ Object p =
+ project.getReference(ProjectHelper.PROJECTHELPER_REFERENCE);
+ if (p instanceof ProjectHelper) {
+ parser = (ProjectHelper) p;
+ if (!parser.canParseAntlibDescriptor(antlibResource)) {
+ parser = null;
+ }
+ }
+ if (parser == null) {
+ ProjectHelperRepository helperRepository =
+ ProjectHelperRepository.getInstance();
+ parser = helperRepository.getProjectHelperForAntlib(antlibResource);
+ }
+ UnknownElement ue =
+ parser.parseAntlibDescriptor(project, antlibResource);
+ // Check name is "antlib"
+ if (!(ue.getTag().equals(TAG))) {
+ throw new BuildException(
+ "Unexpected tag " + ue.getTag() + " expecting "
+ + TAG, ue.getLocation());
+ }
+ Antlib antlib = new Antlib();
+ antlib.setProject(project);
+ antlib.setLocation(ue.getLocation());
+ antlib.setTaskName("antlib");
+ antlib.init();
+ ue.configure(antlib);
+ return antlib;
+ } finally {
+ helper.exitAntLib();
+ }
+ }
+
+ //
+ // Instance
+ //
+ private ClassLoader classLoader;
+ private String uri = "";
+ private List<Object> tasks = new ArrayList<Object>();
+
+ /**
+ * Set the class loader for this antlib.
+ * This class loader is used for any tasks that
+ * derive from Definer.
+ *
+ * @param classLoader the class loader
+ */
+ protected void setClassLoader(ClassLoader classLoader) {
+ this.classLoader = classLoader;
+ }
+
+ /**
+ * Set the URI for this antlib.
+ * @param uri the namespace uri
+ */
+ protected void setURI(String uri) {
+ this.uri = uri;
+ }
+
+ private ClassLoader getClassLoader() {
+ if (classLoader == null) {
+ classLoader = Antlib.class.getClassLoader();
+ }
+ return classLoader;
+ }
+
+ /**
+ * add a task to the list of tasks
+ *
+ * @param nestedTask Nested task to execute in antlib
+ */
+ public void addTask(Task nestedTask) {
+ tasks.add(nestedTask);
+ }
+
+ /**
+ * Execute the nested tasks, setting the classloader for
+ * any tasks that derive from Definer.
+ */
+ public void execute() {
+ //TODO handle tasks added via #addTask()
+ for (Iterator<Object> i = tasks.iterator(); i.hasNext();) {
+ UnknownElement ue = (UnknownElement) i.next();
+ setLocation(ue.getLocation());
+ ue.maybeConfigure();
+ Object configuredObject = ue.getRealThing();
+ if (configuredObject == null) {
+ continue;
+ }
+ if (!(configuredObject instanceof AntlibDefinition)) {
+ throw new BuildException(
+ "Invalid task in antlib " + ue.getTag()
+ + " " + configuredObject.getClass() + " does not "
+ + "extend org.apache.tools.ant.taskdefs.AntlibDefinition");
+ }
+ AntlibDefinition def = (AntlibDefinition) configuredObject;
+ def.setURI(uri);
+ def.setAntlibClassLoader(getClassLoader());
+ def.init();
+ def.execute();
+ }
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/AntlibDefinition.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/AntlibDefinition.java
new file mode 100644
index 00000000..eef33345
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/AntlibDefinition.java
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.ProjectHelper;
+import org.apache.tools.ant.Task;
+
+/**
+ * Base class for tasks that that can be used in antlibs.
+ * For handling uri and class loading.
+ *
+ * @since Ant 1.6
+ */
+public class AntlibDefinition extends Task {
+
+ private String uri = "";
+ private ClassLoader antlibClassLoader;
+
+ /**
+ * The URI for this definition.
+ * If the URI is "antlib:org.apache.tools.ant",
+ * (this is the default uri)
+ * the uri will be set to "".
+ * URIs that start with "ant:" are reserved
+ * and are not allowed in this context.
+ * @param uri the namespace URI
+ * @throws BuildException if a reserved URI is used
+ */
+ public void setURI(String uri) throws BuildException {
+ if (uri.equals(ProjectHelper.ANT_CORE_URI)) {
+ uri = "";
+ }
+ if (uri.startsWith("ant:")) {
+ throw new BuildException("Attempt to use a reserved URI " + uri);
+ }
+ this.uri = uri;
+ }
+
+ /**
+ * The URI for this definition.
+ * @return The URI for this definition.
+ */
+ public String getURI() {
+ return uri;
+ }
+
+ /**
+ * Set the class loader of the loading object
+ *
+ * @param classLoader a <code>ClassLoader</code> value
+ */
+ public void setAntlibClassLoader(ClassLoader classLoader) {
+ this.antlibClassLoader = classLoader;
+ }
+
+ /**
+ * The current antlib classloader
+ * @return the antlib classloader for the definition, this
+ * is null if the definition is not used in an antlib.
+ */
+ public ClassLoader getAntlibClassLoader() {
+ return antlibClassLoader;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Apt.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Apt.java
new file mode 100644
index 00000000..52154a8c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Apt.java
@@ -0,0 +1,270 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs;
+
+import java.io.File;
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.compilers.AptExternalCompilerAdapter;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.types.Reference;
+import org.apache.tools.ant.util.JavaEnvUtils;
+
+/**
+ * Apt Task for running the Annotation processing tool for JDK 1.5. It derives
+ * from the existing Javac task, and forces the compiler based on whether we're
+ * executing internally, or externally.
+ *
+ * @since Ant 1.7
+ */
+
+
+public class Apt
+ extends Javac {
+ private boolean compile = true;
+ private String factory;
+ private Path factoryPath;
+ private Vector<Option> options = new Vector<Option>();
+ private File preprocessDir;
+ /** The name of the apt tool. */
+ public static final String EXECUTABLE_NAME = "apt";
+ /** An warning message when ignoring compiler attribute. */
+ public static final String ERROR_IGNORING_COMPILER_OPTION
+ = "Ignoring compiler attribute for the APT task, as it is fixed";
+ /** A warning message if used with java &lt; 1.5. */
+ public static final String ERROR_WRONG_JAVA_VERSION
+ = "Apt task requires Java 1.5+";
+
+ /**
+ * exposed for debug messages
+ */
+ public static final String WARNING_IGNORING_FORK =
+ "Apt only runs in its own JVM; fork=false option ignored";
+
+ /**
+ * The nested option element.
+ */
+ public static final class Option {
+ private String name;
+ private String value;
+
+ /** Constructor for Option */
+ public Option() {
+ //default
+ }
+
+ /**
+ * Get the name attribute.
+ * @return the name attribute.
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Set the name attribute.
+ * @param name the name of the option.
+ */
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ /**
+ * Get the value attribute.
+ * @return the value attribute.
+ */
+ public String getValue() {
+ return value;
+ }
+
+ /**
+ * Set the value attribute.
+ * @param value the value of the option.
+ */
+ public void setValue(String value) {
+ this.value = value;
+ }
+ }
+
+ /**
+ * Constructor for Apt task.
+ * This sets the apt compiler adapter as the compiler in the super class.
+ */
+ public Apt() {
+ super();
+ super.setCompiler(AptExternalCompilerAdapter.class.getName());
+ super.setFork(true);
+ }
+
+ /**
+ * Get the name of the apt executable.
+ *
+ * @return the name of the executable.
+ */
+ public String getAptExecutable() {
+ String exe = getExecutable();
+ return exe != null ? exe :
+ JavaEnvUtils.getJdkExecutable(EXECUTABLE_NAME);
+ }
+
+ /**
+ * Set the compiler.
+ * This is not allowed and a warning log message is made.
+ * @param compiler not used.
+ */
+ public void setCompiler(String compiler) {
+ log(ERROR_IGNORING_COMPILER_OPTION, Project.MSG_WARN);
+ }
+
+ /**
+ * Set the fork attribute.
+ * Non-forking APT is highly classpath dependent and appears to be too
+ * brittle to work. The sole reason this attribute is retained
+ * is the superclass does it
+ * @param fork if false; warn the option is ignored.
+ */
+ public void setFork(boolean fork) {
+ if (!fork) {
+ log(WARNING_IGNORING_FORK, Project.MSG_WARN);
+ }
+ }
+
+ /**
+ * Get the compiler class name.
+ * @return the compiler class name.
+ */
+ public String getCompiler() {
+ return super.getCompiler();
+ }
+
+ /**
+ * Get the compile option for the apt compiler.
+ * If this is false the "-nocompile" argument will be used.
+ * @return the value of the compile option.
+ */
+ public boolean isCompile() {
+ return compile;
+ }
+
+ /**
+ * Set the compile option for the apt compiler.
+ * Default value is true.
+ * @param compile if true set the compile option.
+ */
+ public void setCompile(boolean compile) {
+ this.compile = compile;
+ }
+
+ /**
+ * Get the factory option for the apt compiler.
+ * If this is non-null the "-factory" argument will be used.
+ * @return the value of the factory option.
+ */
+ public String getFactory() {
+ return factory;
+ }
+
+ /**
+ * Set the factory option for the apt compiler.
+ * Default value is null.
+ * @param factory the classname of the factory.
+ */
+ public void setFactory(String factory) {
+ this.factory = factory;
+ }
+
+ /**
+ * Add a reference to a path to the factoryPath attribute.
+ * @param ref a reference to a path.
+ */
+ public void setFactoryPathRef(Reference ref) {
+ createFactoryPath().setRefid(ref);
+ }
+
+ /**
+ * Add a path to the factoryPath attribute.
+ * @return a path to be configured.
+ */
+ public Path createFactoryPath() {
+ if (factoryPath == null) {
+ factoryPath = new Path(getProject());
+ }
+ return factoryPath.createPath();
+ }
+
+ /**
+ * Get the factory path attribute.
+ * If this is not null, the "-factorypath" argument will be used.
+ * The default value is null.
+ * @return the factory path attribute.
+ */
+ public Path getFactoryPath() {
+ return factoryPath;
+ }
+
+ /**
+ * Create a nested option.
+ * @return an option to be configured.
+ */
+ public Option createOption() {
+ Option opt = new Option();
+ options.add(opt);
+ return opt;
+ }
+
+ /**
+ * Get the options to the compiler.
+ * Each option will use '"-E" name ["=" value]' argument.
+ * @return the options.
+ */
+ public Vector<Option> getOptions() {
+ return options;
+ }
+
+ /**
+ * Get the preprocessdir attribute.
+ * This corresponds to the "-s" argument.
+ * The default value is null.
+ * @return the preprocessdir attribute.
+ */
+ public File getPreprocessDir() {
+ return preprocessDir;
+ }
+
+ /**
+ * Set the preprocessdir attribute.
+ * @param preprocessDir where to place processor generated source files.
+ */
+ public void setPreprocessDir(File preprocessDir) {
+ this.preprocessDir = preprocessDir;
+ }
+
+ /**
+ * Do the compilation.
+ * @throws BuildException on error.
+ */
+ public void execute()
+ throws BuildException {
+ if (JavaEnvUtils.getJavaVersionNumber() >= 18) {
+ throw new BuildException("apt does not exist under Java 1.8 and higher");
+ }
+ super.execute();
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/AttributeNamespaceDef.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/AttributeNamespaceDef.java
new file mode 100644
index 00000000..150b7288
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/AttributeNamespaceDef.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.AntTypeDefinition;
+import org.apache.tools.ant.ComponentHelper;
+import org.apache.tools.ant.ProjectHelper;
+import org.apache.tools.ant.attribute.AttributeNamespace;
+
+/**
+ * Definition to allow the URI to be considered for
+ * Ant attributes.
+ *
+ * @since Ant 1.9.1
+ */
+public final class AttributeNamespaceDef extends AntlibDefinition {
+
+ /**
+ * Run the definition.
+ * This registers the XML namespace (URI) as a namepace for
+ * attributes.
+ */
+ public void execute() {
+ String componentName = ProjectHelper.nsToComponentName(
+ getURI());
+ AntTypeDefinition def = new AntTypeDefinition();
+ def.setName(componentName);
+ def.setClassName(AttributeNamespace.class.getName());
+ def.setClass(AttributeNamespace.class);
+ def.setRestrict(true);
+ def.setClassLoader(AttributeNamespace.class.getClassLoader());
+ ComponentHelper.getComponentHelper(getProject())
+ .addDataTypeDefinition(def);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/AugmentReference.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/AugmentReference.java
new file mode 100644
index 00000000..637795f3
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/AugmentReference.java
@@ -0,0 +1,96 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.RuntimeConfigurable;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.TypeAdapter;
+
+/**
+ * Ant task to dynamically augment a previously declared reference.
+ * @since Ant 1.8.1
+ */
+public class AugmentReference extends Task implements TypeAdapter {
+ private String id;
+
+ /**
+ * {@inheritDoc}
+ */
+ public void checkProxyClass(Class<?> proxyClass) {
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public synchronized Object getProxy() {
+ if (getProject() == null) {
+ throw new IllegalStateException(getTaskName() + "Project owner unset");
+ }
+ hijackId();
+ if (getProject().hasReference(id)) {
+ Object result = getProject().getReference(id);
+ log("project reference " + id + "=" + String.valueOf(result), Project.MSG_DEBUG);
+ return result;
+ }
+ throw new IllegalStateException("Unknown reference \"" + id + "\"");
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setProxy(Object o) {
+ throw new UnsupportedOperationException();
+ }
+
+ private synchronized void hijackId() {
+ if (id == null) {
+ RuntimeConfigurable wrapper = getWrapper();
+ id = wrapper.getId();
+ if (id == null) {
+ throw new IllegalStateException(getTaskName() + " attribute 'id' unset");
+ }
+ wrapper.setAttribute("id", null);
+ wrapper.removeAttribute("id");
+ wrapper.setElementTag("augmented reference \"" + id + "\"");
+ }
+ }
+
+ /**
+ * Overridden to restore the wrapper once it is no longer needed.
+ * @since Ant 1.8.3
+ */
+ public void execute() {
+ restoreWrapperId();
+ }
+
+ /**
+ * Needed if two different targets reuse the same instance.
+ * @see "https://issues.apache.org/bugzilla/show_bug.cgi?id=50894"
+ */
+ private synchronized void restoreWrapperId() {
+ if (id != null) {
+ log("restoring augment wrapper " + id, Project.MSG_DEBUG);
+ RuntimeConfigurable wrapper = getWrapper();
+ wrapper.setAttribute("id", id);
+ wrapper.setElementTag(getTaskName());
+ id = null;
+ }
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Available.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Available.java
new file mode 100644
index 00000000..816568e0
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Available.java
@@ -0,0 +1,514 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.io.File;
+
+import org.apache.tools.ant.AntClassLoader;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.PropertyHelper;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.taskdefs.condition.Condition;
+import org.apache.tools.ant.types.EnumeratedAttribute;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.types.Reference;
+import org.apache.tools.ant.util.FileUtils;
+import org.apache.tools.ant.util.StringUtils;
+
+/**
+ * Will set the given property if the requested resource is available at
+ * runtime. This task may also be used as a condition by the condition task.
+ *
+ * @since Ant 1.1
+ *
+ * @ant.task category="control"
+ */
+public class Available extends Task implements Condition {
+ private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+
+ private String property;
+ private String classname;
+ private String filename;
+ private File file;
+ private Path filepath;
+ private String resource;
+ private FileDir type;
+ private Path classpath;
+ private AntClassLoader loader;
+ private Object value = "true";
+ private boolean isTask = false;
+ private boolean ignoreSystemclasses = false;
+ private boolean searchParents = false;
+
+ /**
+ * Set the searchParents attribute.
+ * This controls the behaviour of the the "file" type.
+ * If true, the path, parent path and grandparent path are
+ * searched for the file. If false, only the path is searched.
+ * The default value is false.
+ * @param searchParents the value to set.
+ */
+ public void setSearchParents(boolean searchParents) {
+ this.searchParents = searchParents;
+ }
+
+ /**
+ * Set the classpath to be used when searching for classes and resources.
+ *
+ * @param classpath an Ant Path object containing the search path.
+ */
+ public void setClasspath(Path classpath) {
+ createClasspath().append(classpath);
+ }
+
+ /**
+ * Classpath to be used when searching for classes and resources.
+ *
+ * @return an empty Path instance to be configured by Ant.
+ */
+ public Path createClasspath() {
+ if (this.classpath == null) {
+ this.classpath = new Path(getProject());
+ }
+ return this.classpath.createPath();
+ }
+
+ /**
+ * Set the classpath by reference.
+ *
+ * @param r a Reference to a Path instance to be used as the classpath
+ * value.
+ */
+ public void setClasspathRef(Reference r) {
+ createClasspath().setRefid(r);
+ }
+
+ /**
+ * Set the path to use when looking for a file.
+ *
+ * @param filepath a Path instance containing the search path for files.
+ */
+ public void setFilepath(Path filepath) {
+ createFilepath().append(filepath);
+ }
+
+ /**
+ * Path to search for file resources.
+ *
+ * @return a new Path instance which Ant will configure with a file search
+ * path.
+ */
+ public Path createFilepath() {
+ if (this.filepath == null) {
+ this.filepath = new Path(getProject());
+ }
+ return this.filepath.createPath();
+ }
+
+ /**
+ * Set the name of the property which will be set if the particular resource
+ * is available.
+ *
+ * @param property the name of the property to set.
+ */
+ public void setProperty(String property) {
+ this.property = property;
+ }
+
+ /**
+ * Set the value to be given to the property if the desired resource is
+ * available.
+ *
+ * @param value the value to be given.
+ */
+ public void setValue(Object value) {
+ this.value = value;
+ }
+
+ /**
+ * Set the value to be given to the property if the desired resource is
+ * available.
+ *
+ * @param value the value to be given.
+ */
+ public void setValue(String value) {
+ setValue((Object) value);
+ }
+
+ /**
+ * Set a classname of a class which must be available to set the given
+ * property.
+ *
+ * @param classname the name of the class required.
+ */
+ public void setClassname(String classname) {
+ if (!"".equals(classname)) {
+ this.classname = classname;
+ }
+ }
+
+ /**
+ * Set the file which must be present in the file system to set the given
+ * property.
+ *
+ * @param file the name of the file which is required.
+ */
+ public void setFile(File file) {
+ this.file = file;
+ this.filename = FILE_UTILS.removeLeadingPath(getProject().getBaseDir(), file);
+ }
+
+ /**
+ * Set the name of a Java resource which is required to set the property.
+ *
+ * @param resource the name of a resource which is required to be available.
+ */
+ public void setResource(String resource) {
+ this.resource = resource;
+ }
+
+ /**
+ * @deprecated since 1.5.x.
+ * setType(String) is deprecated and is replaced with
+ * setType(Available.FileDir) to make Ant's Introspection
+ * mechanism do the work and also to encapsulate operations on
+ * the type in its own class.
+ * @param type the type of resource
+ */
+ public void setType(String type) {
+ log("DEPRECATED - The setType(String) method has been deprecated."
+ + " Use setType(Available.FileDir) instead.",
+ Project.MSG_WARN);
+ this.type = new FileDir();
+ this.type.setValue(type);
+ }
+
+ /**
+ * Set what type of file is required - either directory or file.
+ *
+ * @param type an instance of the FileDir enumeratedAttribute indicating
+ * whether the file required is to be a directory or a plain
+ * file.
+ */
+ public void setType(FileDir type) {
+ this.type = type;
+ }
+
+ /**
+ * Set whether the search for classes should ignore the runtime classes and
+ * just use the given classpath.
+ *
+ * @param ignore true if system classes are to be ignored.
+ */
+ public void setIgnoresystemclasses(boolean ignore) {
+ this.ignoreSystemclasses = ignore;
+ }
+
+ /**
+ * Entry point when operating as a task.
+ *
+ * @exception BuildException if the task is not configured correctly.
+ */
+ public void execute() throws BuildException {
+ if (property == null) {
+ throw new BuildException("property attribute is required",
+ getLocation());
+ }
+
+ isTask = true;
+ try {
+ if (eval()) {
+ PropertyHelper ph = PropertyHelper.getPropertyHelper(getProject());
+ Object oldvalue = ph.getProperty(property);
+ if (null != oldvalue && !oldvalue.equals(value)) {
+ log("DEPRECATED - <available> used to override an existing"
+ + " property."
+ + StringUtils.LINE_SEP
+ + " Build file should not reuse the same property"
+ + " name for different values.",
+ Project.MSG_WARN);
+ }
+ // NB: this makes use of Project#setProperty rather than Project#setNewProperty
+ // due to backwards compatibility reasons
+ ph.setProperty(property, value, true);
+ }
+ } finally {
+ isTask = false;
+ }
+ }
+
+ /**
+ * Evaluate the availability of a resource.
+ *
+ * @return boolean is the resource is available.
+ * @exception BuildException if the condition is not configured correctly
+ */
+ public boolean eval() throws BuildException {
+ try {
+ if (classname == null && file == null && resource == null) {
+ throw new BuildException("At least one of (classname|file|"
+ + "resource) is required", getLocation());
+ }
+ if (type != null) {
+ if (file == null) {
+ throw new BuildException("The type attribute is only valid "
+ + "when specifying the file "
+ + "attribute.", getLocation());
+ }
+ }
+ if (classpath != null) {
+ classpath.setProject(getProject());
+ this.loader = getProject().createClassLoader(classpath);
+ }
+ String appendix = "";
+ if (isTask) {
+ appendix = " to set property " + property;
+ } else {
+ setTaskName("available");
+ }
+ if ((classname != null) && !checkClass(classname)) {
+ log("Unable to load class " + classname + appendix,
+ Project.MSG_VERBOSE);
+ return false;
+ }
+ if ((file != null) && !checkFile()) {
+ StringBuffer buf = new StringBuffer("Unable to find ");
+ if (type != null) {
+ buf.append(type).append(' ');
+ }
+ buf.append(filename).append(appendix);
+ log(buf.toString(), Project.MSG_VERBOSE);
+ return false;
+ }
+ if ((resource != null) && !checkResource(resource)) {
+ log("Unable to load resource " + resource + appendix,
+ Project.MSG_VERBOSE);
+ return false;
+ }
+ } finally {
+ if (loader != null) {
+ loader.cleanup();
+ loader = null;
+ }
+ if (!isTask) {
+ setTaskName(null);
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Search for file/directory either relative to project's
+ * basedir or in the path given as filepath.
+ *
+ * <p>filepath can be a list of directory and/or file names (gen'd
+ * via <fileset>)</p>
+ *
+ * <p>look for:</p><ul>
+ * <li>full-pathname specified == path in list</li>
+ * <li>full-pathname specified == parent dir of path in list</li>
+ * <li>simple name specified == path in list</li>
+ * <li>simple name specified == path in list + name</li>
+ * <li>simple name specified == parent dir + name</li>
+ * <li>simple name specified == parent of parent dir + name</li>
+ * </ul>
+ */
+ private boolean checkFile() {
+ if (filepath == null) {
+ return checkFile(file, filename);
+ } else {
+ String[] paths = filepath.list();
+ for (int i = 0; i < paths.length; ++i) {
+ log("Searching " + paths[i], Project.MSG_VERBOSE);
+ File path = new File(paths[i]);
+
+ // ** full-pathname specified == path in list
+ // ** simple name specified == path in list
+ if (path.exists()
+ && (filename.equals(paths[i])
+ || filename.equals(path.getName()))) {
+ if (type == null) {
+ log("Found: " + path, Project.MSG_VERBOSE);
+ return true;
+ } else if (type.isDir()
+ && path.isDirectory()) {
+ log("Found directory: " + path, Project.MSG_VERBOSE);
+ return true;
+ } else if (type.isFile()
+ && path.isFile()) {
+ log("Found file: " + path, Project.MSG_VERBOSE);
+ return true;
+ }
+ // not the requested type
+ return false;
+ }
+ File parent = path.getParentFile();
+ // ** full-pathname specified == parent dir of path in list
+ if (parent != null && parent.exists()
+ && filename.equals(parent.getAbsolutePath())) {
+ if (type == null) {
+ log("Found: " + parent, Project.MSG_VERBOSE);
+ return true;
+ } else if (type.isDir()) {
+ log("Found directory: " + parent, Project.MSG_VERBOSE);
+ return true;
+ }
+ // not the requested type
+ return false;
+ }
+ // ** simple name specified == path in list + name
+ if (path.exists() && path.isDirectory()) {
+ if (checkFile(new File(path, filename),
+ filename + " in " + path)) {
+ return true;
+ }
+ }
+
+ // ** simple name specified == parent dir + name
+ while (searchParents && parent != null && parent.exists()) {
+ if (checkFile(new File(parent, filename),
+ filename + " in " + parent)) {
+ return true;
+ }
+ parent = parent.getParentFile();
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Check if a given file exists and matches the required type.
+ */
+ private boolean checkFile(File f, String text) {
+ if (type != null) {
+ if (type.isDir()) {
+ if (f.isDirectory()) {
+ log("Found directory: " + text, Project.MSG_VERBOSE);
+ }
+ return f.isDirectory();
+ } else if (type.isFile()) {
+ if (f.isFile()) {
+ log("Found file: " + text, Project.MSG_VERBOSE);
+ }
+ return f.isFile();
+ }
+ }
+ if (f.exists()) {
+ log("Found: " + text, Project.MSG_VERBOSE);
+ }
+ return f.exists();
+ }
+
+ /**
+ * Check if a given resource can be loaded.
+ */
+ private boolean checkResource(String resource) {
+ if (loader != null) {
+ return (loader.getResourceAsStream(resource) != null);
+ } else {
+ ClassLoader cL = this.getClass().getClassLoader();
+ if (cL != null) {
+ return (cL.getResourceAsStream(resource) != null);
+ } else {
+ return
+ (ClassLoader.getSystemResourceAsStream(resource) != null);
+ }
+ }
+ }
+
+ /**
+ * Check if a given class can be loaded.
+ */
+ private boolean checkClass(String classname) {
+ try {
+ if (ignoreSystemclasses) {
+ loader = getProject().createClassLoader(classpath);
+ loader.setParentFirst(false);
+ loader.addJavaLibraries();
+ try {
+ loader.findClass(classname);
+ } catch (SecurityException se) {
+ // class found but restricted name; this is
+ // actually the case we're looking for in JDK 1.3+,
+ // so catch the exception and return
+ return true;
+ }
+ } else if (loader != null) {
+ loader.loadClass(classname);
+ } else {
+ ClassLoader l = this.getClass().getClassLoader();
+ // Can return null to represent the bootstrap class loader.
+ // see API docs of Class.getClassLoader.
+ if (l != null) {
+ Class.forName(classname, true, l);
+ } else {
+ Class.forName(classname);
+ }
+ }
+ return true;
+ } catch (ClassNotFoundException e) {
+ log("class \"" + classname + "\" was not found",
+ Project.MSG_DEBUG);
+ return false;
+ } catch (NoClassDefFoundError e) {
+ log("Could not load dependent class \"" + e.getMessage()
+ + "\" for class \"" + classname + "\"",
+ Project.MSG_DEBUG);
+ return false;
+ }
+ }
+
+ /**
+ * EnumeratedAttribute covering the file types to be checked for, either
+ * file or dir.
+ */
+ public static class FileDir extends EnumeratedAttribute {
+
+ private static final String[] VALUES = {"file", "dir"};
+
+ /**
+ * @see EnumeratedAttribute#getValues
+ */
+ /** {@inheritDoc}. */
+ public String[] getValues() {
+ return VALUES;
+ }
+
+ /**
+ * Indicate if the value specifies a directory.
+ *
+ * @return true if the value specifies a directory.
+ */
+ public boolean isDir() {
+ return "dir".equalsIgnoreCase(getValue());
+ }
+
+ /**
+ * Indicate if the value specifies a file.
+ *
+ * @return true if the value specifies a file.
+ */
+ public boolean isFile() {
+ return "file".equalsIgnoreCase(getValue());
+ }
+
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/BUnzip2.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/BUnzip2.java
new file mode 100644
index 00000000..323b738c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/BUnzip2.java
@@ -0,0 +1,112 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+
+import java.io.BufferedInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.util.FileUtils;
+import org.apache.tools.bzip2.CBZip2InputStream;
+
+/**
+ * Expands a file that has been compressed with the BZIP2
+ * algorithm. Normally used to compress non-compressed archives such
+ * as TAR files.
+ *
+ * @since Ant 1.5
+ *
+ * @ant.task category="packaging"
+ */
+
+public class BUnzip2 extends Unpack {
+
+ private static final int BUFFER_SIZE = 8 * 1024;
+
+ private static final String DEFAULT_EXTENSION = ".bz2";
+
+ /**
+ * Get the default extension.
+ * @return the string ".bz2"
+ */
+ protected String getDefaultExtension() {
+ return DEFAULT_EXTENSION;
+ }
+
+ /**
+ * Do the unbzipping.
+ */
+ protected void extract() {
+ if (source.lastModified() > dest.lastModified()) {
+ log("Expanding " + source.getAbsolutePath() + " to "
+ + dest.getAbsolutePath());
+
+ FileOutputStream out = null;
+ CBZip2InputStream zIn = null;
+ InputStream fis = null;
+ BufferedInputStream bis = null;
+ try {
+ out = new FileOutputStream(dest);
+ fis = srcResource.getInputStream();
+ bis = new BufferedInputStream(fis);
+ int b = bis.read();
+ if (b != 'B') {
+ throw new BuildException("Invalid bz2 file.", getLocation());
+ }
+ b = bis.read();
+ if (b != 'Z') {
+ throw new BuildException("Invalid bz2 file.", getLocation());
+ }
+ zIn = new CBZip2InputStream(bis, true);
+ byte[] buffer = new byte[BUFFER_SIZE];
+ int count = 0;
+ do {
+ out.write(buffer, 0, count);
+ count = zIn.read(buffer, 0, buffer.length);
+ } while (count != -1);
+ } catch (IOException ioe) {
+ String msg = "Problem expanding bzip2 " + ioe.getMessage();
+ throw new BuildException(msg, ioe, getLocation());
+ } finally {
+ FileUtils.close(bis);
+ FileUtils.close(fis);
+ FileUtils.close(out);
+ FileUtils.close(zIn);
+ }
+ }
+ }
+
+ /**
+ * Whether this task can deal with non-file resources.
+ *
+ * <p>This implementation returns true only if this task is
+ * &lt;gunzip&gt;. Any subclass of this class that also wants to
+ * support non-file resources needs to override this method. We
+ * need to do so for backwards compatibility reasons since we
+ * can't expect subclasses to support resources.</p>
+ * @return true if this class supports non file resources.
+ * @since Ant 1.7
+ */
+ protected boolean supportsNonFileResources() {
+ return getClass().equals(BUnzip2.class);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/BZip2.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/BZip2.java
new file mode 100644
index 00000000..f5944df5
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/BZip2.java
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+
+import java.io.BufferedOutputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.util.FileUtils;
+import org.apache.tools.bzip2.CBZip2OutputStream;
+
+/**
+ * Compresses a file with the BZIP2 algorithm. Normally used to compress
+ * non-compressed archives such as TAR files.
+ *
+ * @since Ant 1.5
+ *
+ * @ant.task category="packaging"
+ */
+
+public class BZip2 extends Pack {
+ /**
+ * Compress the zipFile.
+ */
+ protected void pack() {
+ CBZip2OutputStream zOut = null;
+ try {
+ BufferedOutputStream bos =
+ new BufferedOutputStream(new FileOutputStream(zipFile));
+ bos.write('B');
+ bos.write('Z');
+ zOut = new CBZip2OutputStream(bos);
+ zipResource(getSrcResource(), zOut);
+ } catch (IOException ioe) {
+ String msg = "Problem creating bzip2 " + ioe.getMessage();
+ throw new BuildException(msg, ioe, getLocation());
+ } finally {
+ FileUtils.close(zOut);
+ }
+ }
+
+ /**
+ * Whether this task can deal with non-file resources.
+ *
+ * <p>This implementation returns true only if this task is
+ * &lt;bzip2&gt;. Any subclass of this class that also wants to
+ * support non-file resources needs to override this method. We
+ * need to do so for backwards compatibility reasons since we
+ * can't expect subclasses to support resources.</p>
+ * @return true if this task support non file resources.
+ * @since Ant 1.7
+ */
+ protected boolean supportsNonFileResources() {
+ return getClass().equals(BZip2.class);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Basename.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Basename.java
new file mode 100644
index 00000000..0415af70
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Basename.java
@@ -0,0 +1,110 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.io.File;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Task;
+
+/**
+ * Sets a property to the base name of a specified file, optionally minus a
+ * suffix.
+ *
+ * This task can accept the following attributes:
+ * <ul>
+ * <li>file
+ * <li>property
+ * <li>suffix
+ * </ul>
+ * The <b>file</b> and <b>property</b> attributes are required. The
+ * <b>suffix</b> attribute can be specified either with or without
+ * the &quot;.&quot;, and the result will be the same (ie., the
+ * returned file name will be minus the .suffix).
+ * <p>
+ * When this task executes, it will set the specified property to the
+ * value of the last element in the specified file. If file is a
+ * directory, the basename will be the last directory element. If file
+ * is a full-path filename, the basename will be the simple file name.
+ * If a suffix is specified, and the specified file ends in that suffix,
+ * the basename will be the simple file name without the suffix.
+ *
+ *
+ * @since Ant 1.5
+ *
+ * @ant.task category="property"
+ */
+
+public class Basename extends Task {
+ private File file;
+ private String property;
+ private String suffix;
+
+ /**
+ * file or directory to get base name from
+ * @param file file or directory to get base name from
+ */
+ public void setFile(File file) {
+ this.file = file;
+ }
+
+ /**
+ * Property to set base name to.
+ * @param property name of property
+ */
+ public void setProperty(String property) {
+ this.property = property;
+ }
+
+ /**
+ * Optional suffix to remove from base name.
+ * @param suffix suffix to remove from base name
+ */
+ public void setSuffix(String suffix) {
+ this.suffix = suffix;
+ }
+
+ /**
+ * do the work
+ * @throws BuildException if required attributes are not supplied
+ * property and attribute are required attributes
+ */
+ public void execute() throws BuildException {
+ if (property == null) {
+ throw new BuildException("property attribute required", getLocation());
+ }
+ if (file == null) {
+ throw new BuildException("file attribute required", getLocation());
+ }
+ String value = file.getName();
+ if (suffix != null && value.endsWith(suffix)) {
+ // if the suffix does not starts with a '.' and the
+ // char preceding the suffix is a '.', we assume the user
+ // wants to remove the '.' as well (see docs)
+ int pos = value.length() - suffix.length();
+ if (pos > 0 && suffix.charAt(0) != '.'
+ && value.charAt(pos - 1) == '.') {
+ pos--;
+ }
+ value = value.substring(0, pos);
+ }
+ getProject().setNewProperty(property, value);
+ }
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/BindTargets.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/BindTargets.java
new file mode 100644
index 00000000..45ad9ae7
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/BindTargets.java
@@ -0,0 +1,91 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.ProjectHelper;
+import org.apache.tools.ant.ProjectHelper.OnMissingExtensionPoint;
+import org.apache.tools.ant.Task;
+
+/**
+ * Simple task which bind some targets to some defined extension point
+ */
+public class BindTargets extends Task {
+
+ private String extensionPoint;
+
+ private final List<String> targets = new ArrayList<String>();
+
+ private OnMissingExtensionPoint onMissingExtensionPoint;
+
+ public void setExtensionPoint(final String extensionPoint) {
+ this.extensionPoint = extensionPoint;
+ }
+
+ public void setOnMissingExtensionPoint(final String onMissingExtensionPoint) {
+ try {
+ this.onMissingExtensionPoint = OnMissingExtensionPoint.valueOf(onMissingExtensionPoint);
+ } catch (final IllegalArgumentException e) {
+ throw new BuildException("Invalid onMissingExtensionPoint: " + onMissingExtensionPoint);
+ }
+ }
+
+ public void setOnMissingExtensionPoint(final OnMissingExtensionPoint onMissingExtensionPoint) {
+ this.onMissingExtensionPoint = onMissingExtensionPoint;
+ }
+
+ public void setTargets(final String target) {
+ final String[] inputs = target.split(",");
+ for (int i = 0; i < inputs.length; i++) {
+ final String input = inputs[i].trim();
+ if (input.length() > 0) {
+ targets.add(input);
+ }
+ }
+ }
+
+ @Override
+ public void execute() throws BuildException {
+ if (extensionPoint == null) {
+ throw new BuildException("extensionPoint required", getLocation());
+ }
+
+ if (getOwningTarget() == null
+ || !"".equals(getOwningTarget().getName())) {
+ throw new BuildException(
+ "bindtargets only allowed as a top-level task");
+ }
+
+ if (onMissingExtensionPoint == null) {
+ onMissingExtensionPoint = OnMissingExtensionPoint.FAIL;
+ }
+ final ProjectHelper helper = (ProjectHelper) getProject().getReference(
+ ProjectHelper.PROJECTHELPER_REFERENCE);
+
+ for (final Iterator<String> itTarget = targets.iterator(); itTarget.hasNext();) {
+ helper.getExtensionStack().add(
+ new String[] {extensionPoint, itTarget.next(),
+ onMissingExtensionPoint.name()});
+ }
+
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/BuildNumber.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/BuildNumber.java
new file mode 100644
index 00000000..aee071d3
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/BuildNumber.java
@@ -0,0 +1,201 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.Properties;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.util.FileUtils;
+
+/**
+ * Read, increment, and write a build number in a file
+ * It will first
+ * attempt to read a build number from a file, then set the property
+ * "build.number" to the value that was read in (or 0 if no such value). Then
+ * it will increment the build number by one and write it back out into the
+ * file.
+ *
+ * @since Ant 1.5
+ * @ant.task name="buildnumber"
+ */
+public class BuildNumber
+ extends Task {
+ /**
+ * The name of the property in which the build number is stored.
+ */
+ private static final String DEFAULT_PROPERTY_NAME = "build.number";
+
+ /** The default filename to use if no file specified. */
+ private static final String DEFAULT_FILENAME = DEFAULT_PROPERTY_NAME;
+
+ private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+
+ /** The File in which the build number is stored. */
+ private File myFile;
+
+
+ /**
+ * The file in which the build number is stored. Defaults to
+ * "build.number" if not specified.
+ *
+ * @param file the file in which build number is stored.
+ */
+ public void setFile(final File file) {
+ myFile = file;
+ }
+
+
+ /**
+ * Run task.
+ *
+ * @exception BuildException if an error occurs
+ */
+ public void execute()
+ throws BuildException {
+ File savedFile = myFile; // may be altered in validate
+
+ validate();
+
+ final Properties properties = loadProperties();
+ final int buildNumber = getBuildNumber(properties);
+
+ properties.put(DEFAULT_PROPERTY_NAME,
+ String.valueOf(buildNumber + 1));
+
+ // Write the properties file back out
+ FileOutputStream output = null;
+
+ try {
+ output = new FileOutputStream(myFile);
+
+ final String header = "Build Number for ANT. Do not edit!";
+
+ properties.store(output, header);
+ } catch (final IOException ioe) {
+ final String message = "Error while writing " + myFile;
+
+ throw new BuildException(message, ioe);
+ } finally {
+ if (null != output) {
+ try {
+ output.close();
+ } catch (final IOException ioe) {
+ log("error closing output stream " + ioe, Project.MSG_ERR);
+ }
+ }
+ myFile = savedFile;
+ }
+
+ //Finally set the property
+ getProject().setNewProperty(DEFAULT_PROPERTY_NAME,
+ String.valueOf(buildNumber));
+ }
+
+
+ /**
+ * Utility method to retrieve build number from properties object.
+ *
+ * @param properties the properties to retrieve build number from
+ * @return the build number or if no number in properties object
+ * @throws BuildException if build.number property is not an integer
+ */
+ private int getBuildNumber(final Properties properties)
+ throws BuildException {
+ final String buildNumber =
+ properties.getProperty(DEFAULT_PROPERTY_NAME, "0").trim();
+
+ // Try parsing the line into an integer.
+ try {
+ return Integer.parseInt(buildNumber);
+ } catch (final NumberFormatException nfe) {
+ final String message =
+ myFile + " contains a non integer build number: " + buildNumber;
+ throw new BuildException(message, nfe);
+ }
+ }
+
+
+ /**
+ * Utility method to load properties from file.
+ *
+ * @return the loaded properties
+ * @throws BuildException
+ */
+ private Properties loadProperties()
+ throws BuildException {
+ FileInputStream input = null;
+
+ try {
+ final Properties properties = new Properties();
+
+ input = new FileInputStream(myFile);
+ properties.load(input);
+ return properties;
+ } catch (final IOException ioe) {
+ throw new BuildException(ioe);
+ } finally {
+ if (null != input) {
+ try {
+ input.close();
+ } catch (final IOException ioe) {
+ log("error closing input stream " + ioe, Project.MSG_ERR);
+ }
+ }
+ }
+ }
+
+
+ /**
+ * Validate that the task parameters are valid.
+ *
+ * @throws BuildException if parameters are invalid
+ */
+ private void validate()
+ throws BuildException {
+ if (null == myFile) {
+ myFile = FILE_UTILS.resolveFile(getProject().getBaseDir(), DEFAULT_FILENAME);
+ }
+
+ if (!myFile.exists()) {
+ try {
+ FILE_UTILS.createNewFile(myFile);
+ } catch (final IOException ioe) {
+ final String message =
+ myFile + " doesn't exist and new file can't be created.";
+ throw new BuildException(message, ioe);
+ }
+ }
+
+ if (!myFile.canRead()) {
+ final String message = "Unable to read from " + myFile + ".";
+ throw new BuildException(message);
+ }
+
+ if (!myFile.canWrite()) {
+ final String message = "Unable to write to " + myFile + ".";
+ throw new BuildException(message);
+ }
+ }
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/CVSPass.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/CVSPass.java
new file mode 100644
index 00000000..53f5d3e0
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/CVSPass.java
@@ -0,0 +1,172 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.util.FileUtils;
+import org.apache.tools.ant.util.StringUtils;
+
+/**
+ * Adds an new entry to a CVS password file.
+ *
+ *
+ * @since Ant 1.4
+ *
+ * @ant.task category="scm"
+ */
+public class CVSPass extends Task {
+ /** CVS Root */
+ private String cvsRoot = null;
+ /** Password file to add password to */
+ private File passFile = null;
+ /** Password to add to file */
+ private String password = null;
+
+ /** Array contain char conversion data */
+ private final char[] shifts = {
+ 0, 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,
+ 114, 120, 53, 79, 96, 109, 72, 108, 70, 64, 76, 67, 116, 74, 68, 87,
+ 111, 52, 75, 119, 49, 34, 82, 81, 95, 65, 112, 86, 118, 110, 122, 105,
+ 41, 57, 83, 43, 46, 102, 40, 89, 38, 103, 45, 50, 42, 123, 91, 35,
+ 125, 55, 54, 66, 124, 126, 59, 47, 92, 71, 115, 78, 88, 107, 106, 56,
+ 36, 121, 117, 104, 101, 100, 69, 73, 99, 63, 94, 93, 39, 37, 61, 48,
+ 58, 113, 32, 90, 44, 98, 60, 51, 33, 97, 62, 77, 84, 80, 85, 223,
+ 225, 216, 187, 166, 229, 189, 222, 188, 141, 249, 148, 200, 184, 136, 248, 190,
+ 199, 170, 181, 204, 138, 232, 218, 183, 255, 234, 220, 247, 213, 203, 226, 193,
+ 174, 172, 228, 252, 217, 201, 131, 230, 197, 211, 145, 238, 161, 179, 160, 212,
+ 207, 221, 254, 173, 202, 146, 224, 151, 140, 196, 205, 130, 135, 133, 143, 246,
+ 192, 159, 244, 239, 185, 168, 215, 144, 139, 165, 180, 157, 147, 186, 214, 176,
+ 227, 231, 219, 169, 175, 156, 206, 198, 129, 164, 150, 210, 154, 177, 134, 127,
+ 182, 128, 158, 208, 162, 132, 167, 209, 149, 241, 153, 251, 237, 236, 171, 195,
+ 243, 233, 253, 240, 194, 250, 191, 155, 142, 137, 245, 235, 163, 242, 178, 152
+ };
+
+ /**
+ * Create a CVS task using the default cvspass file location.
+ */
+ public CVSPass() {
+ passFile = new File(
+ System.getProperty("cygwin.user.home",
+ System.getProperty("user.home"))
+ + File.separatorChar + ".cvspass");
+ }
+
+ /**
+ * Does the work.
+ *
+ * @exception BuildException if something goes wrong with the build
+ */
+ public final void execute() throws BuildException {
+ if (cvsRoot == null) {
+ throw new BuildException("cvsroot is required");
+ }
+ if (password == null) {
+ throw new BuildException("password is required");
+ }
+
+ log("cvsRoot: " + cvsRoot, Project.MSG_DEBUG);
+ log("password: " + password, Project.MSG_DEBUG);
+ log("passFile: " + passFile, Project.MSG_DEBUG);
+
+ BufferedReader reader = null;
+ BufferedWriter writer = null;
+ try {
+ StringBuffer buf = new StringBuffer();
+
+ if (passFile.exists()) {
+ reader = new BufferedReader(new FileReader(passFile));
+
+ String line = null;
+
+ while ((line = reader.readLine()) != null) {
+ if (!line.startsWith(cvsRoot)) {
+ buf.append(line).append(StringUtils.LINE_SEP);
+ }
+ }
+ }
+
+ String pwdfile = buf.toString() + cvsRoot + " A"
+ + mangle(password);
+
+ log("Writing -> " + pwdfile , Project.MSG_DEBUG);
+
+ writer = new BufferedWriter(new FileWriter(passFile));
+
+ writer.write(pwdfile);
+ writer.newLine();
+ } catch (IOException e) {
+ throw new BuildException(e);
+ } finally {
+ if (reader != null) {
+ try {
+ reader.close();
+ } catch (IOException e) {
+ // ignore
+ }
+ }
+ FileUtils.close(writer);
+ }
+ }
+
+ private final String mangle(String password) {
+ StringBuffer buf = new StringBuffer();
+ for (int i = 0; i < password.length(); i++) {
+ buf.append(shifts[password.charAt(i)]);
+ }
+ return buf.toString();
+ }
+
+ /**
+ * The CVS repository to add an entry for.
+ *
+ * @param cvsRoot the CVS repository
+ */
+ public void setCvsroot(String cvsRoot) {
+ this.cvsRoot = cvsRoot;
+ }
+
+ /**
+ * Password file to add the entry to.
+ *
+ * @param passFile the password file.
+ */
+ public void setPassfile(File passFile) {
+ this.passFile = passFile;
+ }
+
+ /**
+ * Password to be added to the password file.
+ *
+ * @param password the password.
+ */
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/CallTarget.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/CallTarget.java
new file mode 100644
index 00000000..d8a0e8c8
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/CallTarget.java
@@ -0,0 +1,255 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.io.IOException;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.types.PropertySet;
+
+/**
+ * Call another target in the same project.
+ *
+ * <pre>
+ * &lt;target name="foo"&gt;
+ * &lt;antcall target="bar"&gt;
+ * &lt;param name="property1" value="aaaaa" /&gt;
+ * &lt;param name="foo" value="baz" /&gt;
+ * &lt;/antcall&gt;
+ * &lt;/target&gt;
+ *
+ * &lt;target name="bar" depends="init"&gt;
+ * &lt;echo message="prop is ${property1} ${foo}" /&gt;
+ * &lt;/target&gt;
+ * </pre>
+ *
+ * <p>This only works as expected if neither property1 nor foo are
+ * defined in the project itself.
+ *
+ *
+ * @since Ant 1.2
+ *
+ * @ant.task name="antcall" category="control"
+ */
+public class CallTarget extends Task {
+
+ private Ant callee;
+ // must match the default value of Ant#inheritAll
+ private boolean inheritAll = true;
+ // must match the default value of Ant#inheritRefs
+ private boolean inheritRefs = false;
+
+ private boolean targetSet = false;
+
+ /**
+ * If true, pass all properties to the new Ant project.
+ * Defaults to true.
+ * @param inherit <code>boolean</code> flag.
+ */
+ public void setInheritAll(boolean inherit) {
+ inheritAll = inherit;
+ }
+
+ /**
+ * If true, pass all references to the new Ant project.
+ * Defaults to false.
+ * @param inheritRefs <code>boolean</code> flag.
+ */
+ public void setInheritRefs(boolean inheritRefs) {
+ this.inheritRefs = inheritRefs;
+ }
+
+ /**
+ * Initialize this task by creating new instance of the ant task and
+ * configuring it by calling its own init method.
+ */
+ public void init() {
+ callee = new Ant(this);
+ callee.init();
+ }
+
+ /**
+ * Delegate the work to the ant task instance, after setting it up.
+ * @throws BuildException on validation failure or if the target didn't
+ * execute.
+ */
+ public void execute() throws BuildException {
+ if (callee == null) {
+ init();
+ }
+ if (!targetSet) {
+ throw new BuildException(
+ "Attribute target or at least one nested target is required.",
+ getLocation());
+ }
+ callee.setAntfile(getProject().getProperty("ant.file"));
+ callee.setInheritAll(inheritAll);
+ callee.setInheritRefs(inheritRefs);
+ callee.execute();
+ }
+
+ /**
+ * Create a new Property to pass to the invoked target(s).
+ * @return a <code>Property</code> object.
+ */
+ public Property createParam() {
+ if (callee == null) {
+ init();
+ }
+ return callee.createProperty();
+ }
+
+ /**
+ * Reference element identifying a data type to carry
+ * over to the invoked target.
+ * @param r the specified <code>Ant.Reference</code>.
+ * @since Ant 1.5
+ */
+ public void addReference(Ant.Reference r) {
+ if (callee == null) {
+ init();
+ }
+ callee.addReference(r);
+ }
+
+ /**
+ * Set of properties to pass to the new project.
+ * @param ps the <code>PropertySet</code> to pass.
+ * @since Ant 1.6
+ */
+ public void addPropertyset(PropertySet ps) {
+ if (callee == null) {
+ init();
+ }
+ callee.addPropertyset(ps);
+ }
+
+ /**
+ * Set target to execute.
+ * @param target the name of the target to execute.
+ */
+ public void setTarget(String target) {
+ if (callee == null) {
+ init();
+ }
+ callee.setTarget(target);
+ targetSet = true;
+ }
+
+ /**
+ * Add a target to the list of targets to invoke.
+ * @param t <code>Ant.TargetElement</code> representing the target.
+ * @since Ant 1.6.3
+ */
+ public void addConfiguredTarget(Ant.TargetElement t) {
+ if (callee == null) {
+ init();
+ }
+ callee.addConfiguredTarget(t);
+ targetSet = true;
+ }
+
+ /**
+ * Handles output.
+ * Send it the the new project if is present, otherwise
+ * call the super class.
+ * @param output The string output to output.
+ * @see Task#handleOutput(String)
+ * @since Ant 1.5
+ */
+ public void handleOutput(String output) {
+ if (callee != null) {
+ callee.handleOutput(output);
+ } else {
+ super.handleOutput(output);
+ }
+ }
+
+ /**
+ * Handles input.
+ * Delegate to the created project, if present, otherwise
+ * call the super class.
+ * @param buffer the buffer into which data is to be read.
+ * @param offset the offset into the buffer at which data is stored.
+ * @param length the amount of data to read.
+ *
+ * @return the number of bytes read.
+ *
+ * @exception IOException if the data cannot be read.
+ * @see Task#handleInput(byte[], int, int)
+ * @since Ant 1.6
+ */
+ public int handleInput(byte[] buffer, int offset, int length)
+ throws IOException {
+ if (callee != null) {
+ return callee.handleInput(buffer, offset, length);
+ }
+ return super.handleInput(buffer, offset, length);
+ }
+
+ /**
+ * Handles output.
+ * Send it the the new project if is present, otherwise
+ * call the super class.
+ * @param output The string to output.
+ * @see Task#handleFlush(String)
+ * @since Ant 1.5.2
+ */
+ public void handleFlush(String output) {
+ if (callee != null) {
+ callee.handleFlush(output);
+ } else {
+ super.handleFlush(output);
+ }
+ }
+
+ /**
+ * Handle error output.
+ * Send it the the new project if is present, otherwise
+ * call the super class.
+ * @param output The string to output.
+ *
+ * @see Task#handleErrorOutput(String)
+ * @since Ant 1.5
+ */
+ public void handleErrorOutput(String output) {
+ if (callee != null) {
+ callee.handleErrorOutput(output);
+ } else {
+ super.handleErrorOutput(output);
+ }
+ }
+
+ /**
+ * Handle error output.
+ * Send it the the new project if is present, otherwise
+ * call the super class.
+ * @param output The string to output.
+ * @see Task#handleErrorFlush(String)
+ * @since Ant 1.5.2
+ */
+ public void handleErrorFlush(String output) {
+ if (callee != null) {
+ callee.handleErrorFlush(output);
+ } else {
+ super.handleErrorFlush(output);
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Checksum.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Checksum.java
new file mode 100644
index 00000000..7a94ca09
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Checksum.java
@@ -0,0 +1,712 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.io.IOException;
+import java.security.DigestInputStream;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.text.MessageFormat;
+import java.text.ParseException;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Map;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.condition.Condition;
+import org.apache.tools.ant.types.EnumeratedAttribute;
+import org.apache.tools.ant.types.FileSet;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.ResourceCollection;
+import org.apache.tools.ant.types.resources.FileProvider;
+import org.apache.tools.ant.types.resources.Restrict;
+import org.apache.tools.ant.types.resources.Union;
+import org.apache.tools.ant.types.resources.selectors.Type;
+import org.apache.tools.ant.util.FileUtils;
+import org.apache.tools.ant.util.StringUtils;
+
+/**
+ * Used to create or verify file checksums.
+ *
+ * @since Ant 1.5
+ *
+ * @ant.task category="control"
+ */
+public class Checksum extends MatchingTask implements Condition {
+
+ private static final int NIBBLE = 4;
+ private static final int WORD = 16;
+ private static final int BUFFER_SIZE = 8 * 1024;
+ private static final int BYTE_MASK = 0xFF;
+
+ private static class FileUnion extends Restrict {
+ private Union u;
+ FileUnion() {
+ u = new Union();
+ super.add(u);
+ super.add(Type.FILE);
+ }
+ public void add(ResourceCollection rc) {
+ u.add(rc);
+ }
+ }
+
+ /**
+ * File for which checksum is to be calculated.
+ */
+ private File file = null;
+
+ /**
+ * Root directory in which the checksum files will be written.
+ * If not specified, the checksum files will be written
+ * in the same directory as each file.
+ */
+ private File todir;
+
+ /**
+ * MessageDigest algorithm to be used.
+ */
+ private String algorithm = "MD5";
+ /**
+ * MessageDigest Algorithm provider
+ */
+ private String provider = null;
+ /**
+ * File Extension that is be to used to create or identify
+ * destination file
+ */
+ private String fileext;
+ /**
+ * Holds generated checksum and gets set as a Project Property.
+ */
+ private String property;
+ /**
+ * Holds checksums for all files (both calculated and cached on disk).
+ * Key: java.util.File (source file)
+ * Value: java.lang.String (digest)
+ */
+ private Map<File, byte[]> allDigests = new HashMap<File, byte[]>();
+ /**
+ * Holds relative file names for all files (always with a forward slash).
+ * This is used to calculate the total hash.
+ * Key: java.util.File (source file)
+ * Value: java.lang.String (relative file name)
+ */
+ private Map<File, String> relativeFilePaths = new HashMap<File, String>();
+ /**
+ * Property where totalChecksum gets set.
+ */
+ private String totalproperty;
+ /**
+ * Whether or not to create a new file.
+ * Defaults to <code>false</code>.
+ */
+ private boolean forceOverwrite;
+ /**
+ * Contains the result of a checksum verification. ("true" or "false")
+ */
+ private String verifyProperty;
+ /**
+ * Resource Collection.
+ */
+ private FileUnion resources = null;
+ /**
+ * Stores SourceFile, DestFile pairs and SourceFile, Property String pairs.
+ */
+ private Hashtable<File, Object> includeFileMap = new Hashtable<File, Object>();
+ /**
+ * Message Digest instance
+ */
+ private MessageDigest messageDigest;
+ /**
+ * is this task being used as a nested condition element?
+ */
+ private boolean isCondition;
+ /**
+ * Size of the read buffer to use.
+ */
+ private int readBufferSize = BUFFER_SIZE;
+
+ /**
+ * Formater for the checksum file.
+ */
+ private MessageFormat format = FormatElement.getDefault().getFormat();
+
+ /**
+ * Sets the file for which the checksum is to be calculated.
+ * @param file a <code>File</code> value
+ */
+ public void setFile(File file) {
+ this.file = file;
+ }
+
+ /**
+ * Sets the root directory where checksum files will be
+ * written/read
+ * @param todir the directory to write to
+ * @since Ant 1.6
+ */
+ public void setTodir(File todir) {
+ this.todir = todir;
+ }
+
+ /**
+ * Specifies the algorithm to be used to compute the checksum.
+ * Defaults to "MD5". Other popular algorithms like "SHA" may be used as well.
+ * @param algorithm a <code>String</code> value
+ */
+ public void setAlgorithm(String algorithm) {
+ this.algorithm = algorithm;
+ }
+
+ /**
+ * Sets the MessageDigest algorithm provider to be used
+ * to calculate the checksum.
+ * @param provider a <code>String</code> value
+ */
+ public void setProvider(String provider) {
+ this.provider = provider;
+ }
+
+ /**
+ * Sets the file extension that is be to used to
+ * create or identify destination file.
+ * @param fileext a <code>String</code> value
+ */
+ public void setFileext(String fileext) {
+ this.fileext = fileext;
+ }
+
+ /**
+ * Sets the property to hold the generated checksum.
+ * @param property a <code>String</code> value
+ */
+ public void setProperty(String property) {
+ this.property = property;
+ }
+
+ /**
+ * Sets the property to hold the generated total checksum
+ * for all files.
+ * @param totalproperty a <code>String</code> value
+ *
+ * @since Ant 1.6
+ */
+ public void setTotalproperty(String totalproperty) {
+ this.totalproperty = totalproperty;
+ }
+
+ /**
+ * Sets the verify property. This project property holds
+ * the result of a checksum verification - "true" or "false"
+ * @param verifyProperty a <code>String</code> value
+ */
+ public void setVerifyproperty(String verifyProperty) {
+ this.verifyProperty = verifyProperty;
+ }
+
+ /**
+ * Whether or not to overwrite existing file irrespective of
+ * whether it is newer than
+ * the source file. Defaults to false.
+ * @param forceOverwrite a <code>boolean</code> value
+ */
+ public void setForceOverwrite(boolean forceOverwrite) {
+ this.forceOverwrite = forceOverwrite;
+ }
+
+ /**
+ * The size of the read buffer to use.
+ * @param size an <code>int</code> value
+ */
+ public void setReadBufferSize(int size) {
+ this.readBufferSize = size;
+ }
+
+ /**
+ * Select the in/output pattern via a well know format name.
+ * @param e an <code>enumerated</code> value
+ *
+ * @since 1.7.0
+ */
+ public void setFormat(FormatElement e) {
+ format = e.getFormat();
+ }
+
+ /**
+ * Specify the pattern to use as a MessageFormat pattern.
+ *
+ * <p>{0} gets replaced by the checksum, {1} by the filename.</p>
+ * @param p a <code>String</code> value
+ *
+ * @since 1.7.0
+ */
+ public void setPattern(String p) {
+ format = new MessageFormat(p);
+ }
+
+ /**
+ * Files to generate checksums for.
+ * @param set a fileset of files to generate checksums for.
+ */
+ public void addFileset(FileSet set) {
+ add(set);
+ }
+
+ /**
+ * Add a resource collection.
+ * @param rc the ResourceCollection to add.
+ */
+ public void add(ResourceCollection rc) {
+ if (rc == null) {
+ return;
+ }
+ resources = (resources == null) ? new FileUnion() : resources;
+ resources.add(rc);
+ }
+
+ /**
+ * Calculate the checksum(s).
+ * @throws BuildException on error
+ */
+ public void execute() throws BuildException {
+ isCondition = false;
+ boolean value = validateAndExecute();
+ if (verifyProperty != null) {
+ getProject().setNewProperty(
+ verifyProperty,
+ (value ? Boolean.TRUE.toString() : Boolean.FALSE.toString()));
+ }
+ }
+
+ /**
+ * Calculate the checksum(s)
+ *
+ * @return Returns true if the checksum verification test passed,
+ * false otherwise.
+ * @throws BuildException on error
+ */
+ public boolean eval() throws BuildException {
+ isCondition = true;
+ return validateAndExecute();
+ }
+
+ /**
+ * Validate attributes and get down to business.
+ */
+ private boolean validateAndExecute() throws BuildException {
+ String savedFileExt = fileext;
+
+ if (file == null && (resources == null || resources.size() == 0)) {
+ throw new BuildException(
+ "Specify at least one source - a file or a resource collection.");
+ }
+ if (!(resources == null || resources.isFilesystemOnly())) {
+ throw new BuildException("Can only calculate checksums for file-based resources.");
+ }
+ if (file != null && file.exists() && file.isDirectory()) {
+ throw new BuildException("Checksum cannot be generated for directories");
+ }
+ if (file != null && totalproperty != null) {
+ throw new BuildException("File and Totalproperty cannot co-exist.");
+ }
+ if (property != null && fileext != null) {
+ throw new BuildException("Property and FileExt cannot co-exist.");
+ }
+ if (property != null) {
+ if (forceOverwrite) {
+ throw new BuildException(
+ "ForceOverwrite cannot be used when Property is specified");
+ }
+ int ct = 0;
+ if (resources != null) {
+ ct += resources.size();
+ }
+ if (file != null) {
+ ct++;
+ }
+ if (ct > 1) {
+ throw new BuildException(
+ "Multiple files cannot be used when Property is specified");
+ }
+ }
+ if (verifyProperty != null) {
+ isCondition = true;
+ }
+ if (verifyProperty != null && forceOverwrite) {
+ throw new BuildException("VerifyProperty and ForceOverwrite cannot co-exist.");
+ }
+ if (isCondition && forceOverwrite) {
+ throw new BuildException(
+ "ForceOverwrite cannot be used when conditions are being used.");
+ }
+ messageDigest = null;
+ if (provider != null) {
+ try {
+ messageDigest = MessageDigest.getInstance(algorithm, provider);
+ } catch (NoSuchAlgorithmException noalgo) {
+ throw new BuildException(noalgo, getLocation());
+ } catch (NoSuchProviderException noprovider) {
+ throw new BuildException(noprovider, getLocation());
+ }
+ } else {
+ try {
+ messageDigest = MessageDigest.getInstance(algorithm);
+ } catch (NoSuchAlgorithmException noalgo) {
+ throw new BuildException(noalgo, getLocation());
+ }
+ }
+ if (messageDigest == null) {
+ throw new BuildException("Unable to create Message Digest", getLocation());
+ }
+ if (fileext == null) {
+ fileext = "." + algorithm;
+ } else if (fileext.trim().length() == 0) {
+ throw new BuildException("File extension when specified must not be an empty string");
+ }
+ try {
+ if (resources != null) {
+ for (Resource r : resources) {
+ File src = r.as(FileProvider.class)
+ .getFile();
+ if (totalproperty != null || todir != null) {
+ // Use '/' to calculate digest based on file name.
+ // This is required in order to get the same result
+ // on different platforms.
+ relativeFilePaths.put(src, r.getName().replace(File.separatorChar, '/'));
+ }
+ addToIncludeFileMap(src);
+ }
+ }
+ if (file != null) {
+ if (totalproperty != null || todir != null) {
+ relativeFilePaths.put(
+ file, file.getName().replace(File.separatorChar, '/'));
+ }
+ addToIncludeFileMap(file);
+ }
+ return generateChecksums();
+ } finally {
+ fileext = savedFileExt;
+ includeFileMap.clear();
+ }
+ }
+
+ /**
+ * Add key-value pair to the hashtable upon which
+ * to later operate upon.
+ */
+ private void addToIncludeFileMap(File file) throws BuildException {
+ if (file.exists()) {
+ if (property == null) {
+ File checksumFile = getChecksumFile(file);
+ if (forceOverwrite || isCondition
+ || (file.lastModified() > checksumFile.lastModified())) {
+ includeFileMap.put(file, checksumFile);
+ } else {
+ log(file + " omitted as " + checksumFile + " is up to date.",
+ Project.MSG_VERBOSE);
+ if (totalproperty != null) {
+ // Read the checksum from disk.
+ String checksum = readChecksum(checksumFile);
+ byte[] digest = decodeHex(checksum.toCharArray());
+ allDigests.put(file, digest);
+ }
+ }
+ } else {
+ includeFileMap.put(file, property);
+ }
+ } else {
+ String message = "Could not find file "
+ + file.getAbsolutePath()
+ + " to generate checksum for.";
+ log(message);
+ throw new BuildException(message, getLocation());
+ }
+ }
+
+ private File getChecksumFile(File file) {
+ File directory;
+ if (todir != null) {
+ // A separate directory was explicitly declared
+ String path = getRelativeFilePath(file);
+ directory = new File(todir, path).getParentFile();
+ // Create the directory, as it might not exist.
+ directory.mkdirs();
+ } else {
+ // Just use the same directory as the file itself.
+ // This directory will exist
+ directory = file.getParentFile();
+ }
+ File checksumFile = new File(directory, file.getName() + fileext);
+ return checksumFile;
+ }
+
+ /**
+ * Generate checksum(s) using the message digest created earlier.
+ */
+ private boolean generateChecksums() throws BuildException {
+ boolean checksumMatches = true;
+ FileInputStream fis = null;
+ FileOutputStream fos = null;
+ byte[] buf = new byte[readBufferSize];
+ try {
+ for (Map.Entry<File, Object> e : includeFileMap.entrySet()) {
+ messageDigest.reset();
+ File src = e.getKey();
+ if (!isCondition) {
+ log("Calculating " + algorithm + " checksum for " + src, Project.MSG_VERBOSE);
+ }
+ fis = new FileInputStream(src);
+ DigestInputStream dis = new DigestInputStream(fis,
+ messageDigest);
+ while (dis.read(buf, 0, readBufferSize) != -1) {
+ // Empty statement
+ }
+ dis.close();
+ fis.close();
+ fis = null;
+ byte[] fileDigest = messageDigest.digest ();
+ if (totalproperty != null) {
+ allDigests.put(src, fileDigest);
+ }
+ String checksum = createDigestString(fileDigest);
+ //can either be a property name string or a file
+ Object destination = e.getValue();
+ if (destination instanceof java.lang.String) {
+ String prop = (String) destination;
+ if (isCondition) {
+ checksumMatches
+ = checksumMatches && checksum.equals(property);
+ } else {
+ getProject().setNewProperty(prop, checksum);
+ }
+ } else if (destination instanceof java.io.File) {
+ if (isCondition) {
+ File existingFile = (File) destination;
+ if (existingFile.exists()) {
+ try {
+ String suppliedChecksum =
+ readChecksum(existingFile);
+ checksumMatches = checksumMatches
+ && checksum.equals(suppliedChecksum);
+ } catch (BuildException be) {
+ // file is on wrong format, swallow
+ checksumMatches = false;
+ }
+ } else {
+ checksumMatches = false;
+ }
+ } else {
+ File dest = (File) destination;
+ fos = new FileOutputStream(dest);
+ fos.write(format.format(new Object[] {
+ checksum,
+ src.getName(),
+ FileUtils
+ .getRelativePath(dest
+ .getParentFile(),
+ src),
+ FileUtils
+ .getRelativePath(getProject()
+ .getBaseDir(),
+ src),
+ src.getAbsolutePath()
+ }).getBytes());
+ fos.write(StringUtils.LINE_SEP.getBytes());
+ fos.close();
+ fos = null;
+ }
+ }
+ }
+ if (totalproperty != null) {
+ // Calculate the total checksum
+ // Convert the keys (source files) into a sorted array.
+ File[] keyArray = allDigests.keySet().toArray(new File[allDigests.size()]);
+ // File is Comparable, but sort-order is platform
+ // dependent (case-insensitive on Windows)
+ Arrays.sort(keyArray, new Comparator<File>() {
+ public int compare(File f1, File f2) {
+ return f1 == null ? (f2 == null ? 0 : -1)
+ : (f2 == null ? 1
+ : getRelativeFilePath(f1)
+ .compareTo(getRelativeFilePath(f2)));
+ }
+ });
+ // Loop over the checksums and generate a total hash.
+ messageDigest.reset();
+ for (File src : keyArray) {
+ // Add the digest for the file content
+ byte[] digest = allDigests.get(src);
+ messageDigest.update(digest);
+
+ // Add the file path
+ String fileName = getRelativeFilePath(src);
+ messageDigest.update(fileName.getBytes());
+ }
+ String totalChecksum = createDigestString(messageDigest.digest());
+ getProject().setNewProperty(totalproperty, totalChecksum);
+ }
+ } catch (Exception e) {
+ throw new BuildException(e, getLocation());
+ } finally {
+ FileUtils.close(fis);
+ FileUtils.close(fos);
+ }
+ return checksumMatches;
+ }
+
+ private String createDigestString(byte[] fileDigest) {
+ StringBuffer checksumSb = new StringBuffer();
+ for (int i = 0; i < fileDigest.length; i++) {
+ String hexStr = Integer.toHexString(BYTE_MASK & fileDigest[i]);
+ if (hexStr.length() < 2) {
+ checksumSb.append("0");
+ }
+ checksumSb.append(hexStr);
+ }
+ return checksumSb.toString();
+ }
+
+ /**
+ * Converts an array of characters representing hexadecimal values into an
+ * array of bytes of those same values. The returned array will be half the
+ * length of the passed array, as it takes two characters to represent any
+ * given byte. An exception is thrown if the passed char array has an odd
+ * number of elements.
+ *
+ * NOTE: This code is copied from jakarta-commons codec.
+ * @param data an array of characters representing hexadecimal values
+ * @return the converted array of bytes
+ * @throws BuildException on error
+ */
+ public static byte[] decodeHex(char[] data) throws BuildException {
+ int l = data.length;
+
+ if ((l & 0x01) != 0) {
+ throw new BuildException("odd number of characters.");
+ }
+
+ byte[] out = new byte[l >> 1];
+
+ // two characters form the hex value.
+ for (int i = 0, j = 0; j < l; i++) {
+ int f = Character.digit(data[j++], WORD) << NIBBLE;
+ f = f | Character.digit(data[j++], WORD);
+ out[i] = (byte) (f & BYTE_MASK);
+ }
+
+ return out;
+ }
+
+ /**
+ * reads the checksum from a file using the specified format.
+ *
+ * @since 1.7
+ */
+ private String readChecksum(File f) {
+ BufferedReader diskChecksumReader = null;
+ try {
+ diskChecksumReader = new BufferedReader(new FileReader(f));
+ Object[] result = format.parse(diskChecksumReader.readLine());
+ if (result == null || result.length == 0 || result[0] == null) {
+ throw new BuildException("failed to find a checksum");
+ }
+ return (String) result[0];
+ } catch (IOException e) {
+ throw new BuildException("Couldn't read checksum file " + f, e);
+ } catch (ParseException e) {
+ throw new BuildException("Couldn't read checksum file " + f, e);
+ } finally {
+ FileUtils.close(diskChecksumReader);
+ }
+ }
+
+ /**
+ * @since Ant 1.8.2
+ */
+ private String getRelativeFilePath(File f) {
+ String path = (String) relativeFilePaths.get(f);
+ if (path == null) {
+ //bug 37386. this should not occur, but it has, once.
+ throw new BuildException("Internal error: "
+ + "relativeFilePaths could not match file "
+ + f + "\n"
+ + "please file a bug report on this");
+ }
+ return path;
+ }
+
+ /**
+ * Helper class for the format attribute.
+ *
+ * @since 1.7
+ */
+ public static class FormatElement extends EnumeratedAttribute {
+ private static HashMap<String, MessageFormat> formatMap = new HashMap<String, MessageFormat>();
+ private static final String CHECKSUM = "CHECKSUM";
+ private static final String MD5SUM = "MD5SUM";
+ private static final String SVF = "SVF";
+
+ static {
+ formatMap.put(CHECKSUM, new MessageFormat("{0}"));
+ formatMap.put(MD5SUM, new MessageFormat("{0} *{1}"));
+ formatMap.put(SVF, new MessageFormat("MD5 ({1}) = {0}"));
+ }
+
+ /** Constructor for FormatElement */
+ public FormatElement() {
+ super();
+ }
+
+ /**
+ * Get the default value - CHECKSUM.
+ * @return the defaul value.
+ */
+ public static FormatElement getDefault() {
+ FormatElement e = new FormatElement();
+ e.setValue(CHECKSUM);
+ return e;
+ }
+
+ /**
+ * Convert this enumerated type to a <code>MessageFormat</code>.
+ * @return a <code>MessageFormat</code> object.
+ */
+ public MessageFormat getFormat() {
+ return (MessageFormat) formatMap.get(getValue());
+ }
+
+ /**
+ * Get the valid values.
+ * @return an array of values.
+ */
+ public String[] getValues() {
+ return new String[] {CHECKSUM, MD5SUM, SVF};
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Chmod.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Chmod.java
new file mode 100644
index 00000000..ac0c3d8d
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Chmod.java
@@ -0,0 +1,261 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.condition.Os;
+import org.apache.tools.ant.types.Commandline;
+import org.apache.tools.ant.types.FileSet;
+import org.apache.tools.ant.types.PatternSet;
+
+/**
+ * Chmod equivalent for unix-like environments.
+ *
+ * @since Ant 1.1
+ *
+ * @ant.task category="filesystem"
+ * @todo Refactor so it does not extend from ExecuteOn and then turn around
+ * and unsupport several attributes.
+ */
+public class Chmod extends ExecuteOn {
+
+ private FileSet defaultSet = new FileSet();
+ private boolean defaultSetDefined = false;
+ private boolean havePerm = false;
+
+ /**
+ * Chmod task for setting file and directory permissions.
+ */
+ public Chmod() {
+ super.setExecutable("chmod");
+ super.setParallel(true);
+ super.setSkipEmptyFilesets(true);
+ }
+
+ /**
+ * Set the project of this task.
+ * Calls the super class and sets the project on dhe default FileSet.
+ * @param project the project for this task.
+ * @see org.apache.tools.ant.ProjectComponent#setProject
+ */
+ public void setProject(Project project) {
+ super.setProject(project);
+ defaultSet.setProject(project);
+ }
+
+ /**
+ * The file or single directory of which the permissions must be changed.
+ * @param src the source file or directory.
+ */
+ public void setFile(File src) {
+ FileSet fs = new FileSet();
+ fs.setFile(src);
+ addFileset(fs);
+ }
+
+ /**
+ * The directory which holds the files whose permissions must be changed.
+ * @param src the directory.
+ */
+ public void setDir(File src) {
+ defaultSet.setDir(src);
+ }
+
+ /**
+ * Set the new permissions.
+ * @param perm the new permissions.
+ */
+ public void setPerm(String perm) {
+ createArg().setValue(perm);
+ havePerm = true;
+ }
+
+ /**
+ * Add a name entry on the include list.
+ * @return a NameEntry to be configured.
+ */
+ public PatternSet.NameEntry createInclude() {
+ defaultSetDefined = true;
+ return defaultSet.createInclude();
+ }
+
+ /**
+ * Add a name entry on the exclude list.
+ * @return a nameentry to be configured.
+ */
+ public PatternSet.NameEntry createExclude() {
+ defaultSetDefined = true;
+ return defaultSet.createExclude();
+ }
+
+ /**
+ * Add a set of patterns.
+ * @return a patternset to be configured.
+ */
+ public PatternSet createPatternSet() {
+ defaultSetDefined = true;
+ return defaultSet.createPatternSet();
+ }
+
+ /**
+ * Sets the set of include patterns. Patterns may be separated by a comma
+ * or a space.
+ *
+ * @param includes the string containing the include patterns.
+ */
+ public void setIncludes(String includes) {
+ defaultSetDefined = true;
+ defaultSet.setIncludes(includes);
+ }
+
+ /**
+ * Sets the set of exclude patterns. Patterns may be separated by a comma
+ * or a space.
+ *
+ * @param excludes the string containing the exclude patterns.
+ */
+ public void setExcludes(String excludes) {
+ defaultSetDefined = true;
+ defaultSet.setExcludes(excludes);
+ }
+
+ /**
+ * Sets whether default exclusions should be used or not.
+ *
+ * @param useDefaultExcludes "true"|"on"|"yes" when default exclusions
+ * should be used, "false"|"off"|"no" when they
+ * shouldn't be used.
+ */
+ public void setDefaultexcludes(boolean useDefaultExcludes) {
+ defaultSetDefined = true;
+ defaultSet.setDefaultexcludes(useDefaultExcludes);
+ }
+
+ /**
+ * Check the attributes and nested elements.
+ */
+ protected void checkConfiguration() {
+ if (!havePerm) {
+ throw new BuildException("Required attribute perm not set in chmod",
+ getLocation());
+ }
+
+ if (defaultSetDefined && defaultSet.getDir(getProject()) != null) {
+ addFileset(defaultSet);
+ }
+ super.checkConfiguration();
+ }
+
+ /**
+ * Carry out the chmoding.
+ * @throws BuildException on error.
+ */
+ public void execute() throws BuildException {
+ /*
+ * In Ant 1.1, <chmod dir="foo" /> means, change the permissions
+ * of directory foo, not anything inside of it. This is the case the
+ * second branch of the if statement below catches for backwards
+ * compatibility.
+ */
+ if (defaultSetDefined || defaultSet.getDir(getProject()) == null) {
+ try {
+ super.execute();
+ } finally {
+ if (defaultSetDefined && defaultSet.getDir(getProject()) != null) {
+ filesets.removeElement(defaultSet);
+ }
+ }
+ } else if (isValidOs()) {
+ // we are chmodding the given directory
+ Execute execute = prepareExec();
+ Commandline cloned = (Commandline) cmdl.clone();
+ cloned.createArgument().setValue(defaultSet.getDir(getProject())
+ .getPath());
+ try {
+ execute.setCommandline(cloned.getCommandline());
+ runExecute(execute);
+ } catch (IOException e) {
+ throw new BuildException("Execute failed: " + e, e, getLocation());
+ } finally {
+ // close the output file if required
+ logFlush();
+ }
+ }
+ }
+
+ /**
+ * Set the executable.
+ * This is not allowed for Chmod.
+ * @param e ignored.
+ * @throws BuildException always.
+ * @ant.attribute ignore="true"
+ */
+ public void setExecutable(String e) {
+ throw new BuildException(getTaskType()
+ + " doesn\'t support the executable attribute", getLocation());
+ }
+
+ /**
+ * Set the command.
+ * This is not allowed for Chmod.
+ * @param cmdl ignored.
+ * @throws BuildException always.
+ * @ant.attribute ignore="true"
+ */
+ public void setCommand(Commandline cmdl) {
+ throw new BuildException(getTaskType()
+ + " doesn\'t support the command attribute", getLocation());
+ }
+
+ /**
+ * This is not allowed for Chmod.
+ * @param skip ignored.
+ * @throws BuildException always.
+ * @ant.attribute ignore="true"
+ */
+ public void setSkipEmptyFilesets(boolean skip) {
+ throw new BuildException(getTaskType()
+ + " doesn\'t support the skipemptyfileset attribute", getLocation());
+ }
+
+ /**
+ * This is not allowed for Chmod.
+ * @param b ignored.
+ * @throws BuildException always.
+ * @ant.attribute ignore="true"
+ */
+ public void setAddsourcefile(boolean b) {
+ throw new BuildException(getTaskType()
+ + " doesn\'t support the addsourcefile attribute", getLocation());
+ }
+
+ /**
+ * Check if the os is valid.
+ * Always include unix.
+ * @return true if the os is valid.
+ */
+ protected boolean isValidOs() {
+ return getOs() == null && getOsFamily() == null
+ ? Os.isFamily(Os.FAMILY_UNIX) : super.isValidOs();
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Classloader.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Classloader.java
new file mode 100644
index 00000000..8a5967c7
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Classloader.java
@@ -0,0 +1,244 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.io.File;
+
+import org.apache.tools.ant.AntClassLoader;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.MagicNames;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.types.Reference;
+
+/**
+ * EXPERIMENTAL
+ * Create or modifies ClassLoader. The required pathRef parameter
+ * will be used to add classpath elements.
+ *
+ * The classpath is a regular path. Currently only file components are
+ * supported (future extensions may allow URLs).
+ *
+ * You can modify the core loader by not specifying any name or using
+ * "ant.coreLoader". (the core loader is used to load system ant
+ * tasks and for taskdefs that don't specify an explicit path).
+ *
+ * Taskdef and typedef can use the loader you create if the name follows
+ * the "ant.loader.NAME" pattern. NAME will be used as a pathref when
+ * calling taskdef.
+ *
+ * This tasks will not modify the core loader if "build.sysclasspath=only"
+ *
+ * The typical use is:
+ * <pre>
+ * &lt;path id="ant.deps" &gt;
+ * &lt;fileset dir="myDir" &gt;
+ * &lt;include name="junit.jar, bsf.jar, js.jar, etc"/&gt;
+ * &lt;/fileset&gt;
+ * &lt;/path&gt;
+ *
+ * &lt;classloader pathRef="ant.deps" /&gt;
+ *
+ * </pre>
+ *
+ */
+public class Classloader extends Task {
+ /** @see MagicNames#SYSTEM_LOADER_REF */
+ public static final String SYSTEM_LOADER_REF = MagicNames.SYSTEM_LOADER_REF;
+
+ private String name = null;
+ private Path classpath;
+ private boolean reset = false;
+ private boolean parentFirst = true;
+ private String parentName = null;
+
+ /**
+ * Default constructor
+ */
+ public Classloader() {
+ }
+
+ /** Name of the loader. If none, the default loader will be modified
+ *
+ * @param name the name of this loader
+ */
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ /**
+ * Reset the classloader, if it already exists. A new loader will
+ * be created and all the references to the old one will be removed.
+ * (it is not possible to remove paths from a loader). The new
+ * path will be used.
+ *
+ * @param b true if the loader is to be reset.
+ */
+ public void setReset(boolean b) {
+ this.reset = b;
+ }
+
+ /**
+ * Set reverse attribute.
+ * @param b if true reverse the normal classloader lookup.
+ * @deprecated use setParentFirst with a negated argument instead
+ */
+ public void setReverse(boolean b) {
+ this.parentFirst = !b;
+ }
+
+ /**
+ * Set reverse attribute.
+ * @param b if true reverse the normal classloader lookup.
+ */
+ public void setParentFirst(boolean b) {
+ this.parentFirst = b;
+ }
+
+ /**
+ * Set the name of the parent.
+ * @param name the parent name.
+ */
+ public void setParentName(String name) {
+ this.parentName = name;
+ }
+
+
+ /** Specify which path will be used. If the loader already exists
+ * and is an AntClassLoader (or any other loader we can extend),
+ * the path will be added to the loader.
+ * @param pathRef a reference to a path.
+ * @throws BuildException if there is a problem.
+ */
+ public void setClasspathRef(Reference pathRef) throws BuildException {
+ classpath = (Path) pathRef.getReferencedObject(getProject());
+ }
+
+ /**
+ * Set the classpath to be used when searching for component being defined
+ *
+ * @param classpath an Ant Path object containing the classpath.
+ */
+ public void setClasspath(Path classpath) {
+ if (this.classpath == null) {
+ this.classpath = classpath;
+ } else {
+ this.classpath.append(classpath);
+ }
+ }
+
+ /**
+ * Create a classpath.
+ * @return a path for configuration.
+ */
+ public Path createClasspath() {
+ if (this.classpath == null) {
+ this.classpath = new Path(null);
+ }
+ return this.classpath.createPath();
+ }
+
+
+ /**
+ * do the classloader manipulation.
+ */
+ public void execute() {
+ try {
+ // Gump friendly - don't mess with the core loader if only classpath
+ if ("only".equals(getProject().getProperty("build.sysclasspath"))
+ && (name == null || SYSTEM_LOADER_REF.equals(name))) {
+ log("Changing the system loader is disabled "
+ + "by build.sysclasspath=only", Project.MSG_WARN);
+ return;
+ }
+
+ String loaderName = (name == null) ? SYSTEM_LOADER_REF : name;
+
+ Object obj = getProject().getReference(loaderName);
+ if (reset) {
+ // Are any other references held ? Can we 'close' the loader
+ // so it removes the locks on jars ?
+ obj = null; // a new one will be created.
+ }
+
+ // TODO maybe use reflection to addPathElement (other patterns ?)
+ if (obj != null && !(obj instanceof AntClassLoader)) {
+ log("Referenced object is not an AntClassLoader",
+ Project.MSG_ERR);
+ return;
+ }
+
+ AntClassLoader acl = (AntClassLoader) obj;
+ boolean existingLoader = acl != null;
+
+ if (acl == null) {
+ // Construct a new class loader
+ Object parent = null;
+ if (parentName != null) {
+ parent = getProject().getReference(parentName);
+ if (!(parent instanceof ClassLoader)) {
+ parent = null;
+ }
+ }
+ // TODO: allow user to request the system or no parent
+ if (parent == null) {
+ parent = this.getClass().getClassLoader();
+ }
+
+ if (name == null) {
+ // The core loader must be reverse
+ //reverse=true;
+ }
+ getProject().log("Setting parent loader " + name + " "
+ + parent + " " + parentFirst, Project.MSG_DEBUG);
+
+ // The param is "parentFirst"
+ acl = AntClassLoader.newAntClassLoader((ClassLoader) parent,
+ getProject(), classpath, parentFirst);
+
+ getProject().addReference(loaderName, acl);
+
+ if (name == null) {
+ // This allows the core loader to load optional tasks
+ // without delegating
+ acl.addLoaderPackageRoot("org.apache.tools.ant.taskdefs.optional");
+ getProject().setCoreLoader(acl);
+ }
+ }
+
+ if (existingLoader && classpath != null) {
+ String[] list = classpath.list();
+ for (int i = 0; i < list.length; i++) {
+ File f = new File(list[i]);
+ if (f.exists()) {
+ log("Adding to class loader " + acl + " " + f.getAbsolutePath(),
+ Project.MSG_DEBUG);
+ acl.addPathElement(f.getAbsolutePath());
+ }
+ }
+ }
+
+ // TODO add exceptions
+
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/CloseResources.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/CloseResources.java
new file mode 100644
index 00000000..71a94559
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/CloseResources.java
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.io.IOException;
+import java.net.URL;
+
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.ResourceCollection;
+import org.apache.tools.ant.types.resources.URLProvider;
+import org.apache.tools.ant.types.resources.Union;
+import org.apache.tools.ant.util.FileUtils;
+
+/**
+ * Not a real task but used during tests.
+ *
+ * Closes the resources associated with an URL. In particular this is
+ * going to close the jars associated with a jar:file: URL - and it
+ * does so in a way that the Java VM still thinks it is open, so use
+ * it at your own risk.
+ */
+public class CloseResources extends Task {
+ private Union resources = new Union();
+
+ public void add(ResourceCollection rc) {
+ resources.add(rc);
+ }
+
+ public void execute() {
+ for (Resource r : resources) {
+ URLProvider up = r.as(URLProvider.class);
+ if (up != null) {
+ URL u = up.getURL();
+ try {
+ FileUtils.close(u.openConnection());
+ } catch (IOException ex) {
+ // ignore
+ }
+ }
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/CommandLauncherTask.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/CommandLauncherTask.java
new file mode 100644
index 00000000..1e1bf948
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/CommandLauncherTask.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.taskdefs.launcher.CommandLauncher;
+
+/**
+ * Task that configures the {@link
+ * org.apache.tools.ant.taskdefs.launcher.CommandLauncher} to used
+ * when starting external processes.
+ * @since Ant 1.9.0
+ */
+public class CommandLauncherTask extends Task {
+ private boolean vmLauncher;
+ private CommandLauncher commandLauncher;
+
+ public synchronized void addConfigured(CommandLauncher commandLauncher) {
+ if (this.commandLauncher != null) {
+ throw new BuildException("Only one CommandLauncher can be installed");
+ }
+ this.commandLauncher = commandLauncher;
+ }
+
+ @Override
+ public void execute() {
+ if (commandLauncher != null) {
+ if (vmLauncher) {
+ CommandLauncher.setVMLauncher(getProject(), commandLauncher);
+ } else {
+ CommandLauncher.setShellLauncher(getProject(), commandLauncher);
+ }
+ }
+ }
+
+ public void setVmLauncher(boolean vmLauncher) {
+ this.vmLauncher = vmLauncher;
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Componentdef.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Componentdef.java
new file mode 100644
index 00000000..1c5590cd
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Componentdef.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+/**
+ * Adds a component definition to the current project.
+ * <p>Used in the current project two attributes are needed, the name that identifies
+ * this component uniquely, and the full name of the class (including the packages) that
+ * implements this component.</p>
+ *
+ * @since Ant 1.8
+ * @ant.task category="internal"
+ */
+public class Componentdef extends Definer {
+
+ /**
+ * Default constructor.
+ * Creates a new Componentdef instance.
+ * Sets the restrict attribute to true.
+ */
+ public Componentdef() {
+ setRestrict(true);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Concat.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Concat.java
new file mode 100644
index 00000000..1338f2a4
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Concat.java
@@ -0,0 +1,955 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.io.StringReader;
+import java.io.Writer;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.ProjectComponent;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.filters.util.ChainReaderHelper;
+import org.apache.tools.ant.types.FileList;
+import org.apache.tools.ant.types.FileSet;
+import org.apache.tools.ant.types.FilterChain;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.ResourceCollection;
+import org.apache.tools.ant.types.resources.FileResource;
+import org.apache.tools.ant.types.resources.Intersect;
+import org.apache.tools.ant.types.resources.LogOutputResource;
+import org.apache.tools.ant.types.resources.Resources;
+import org.apache.tools.ant.types.resources.Restrict;
+import org.apache.tools.ant.types.resources.StringResource;
+import org.apache.tools.ant.types.resources.selectors.Exists;
+import org.apache.tools.ant.types.resources.selectors.Not;
+import org.apache.tools.ant.types.resources.selectors.ResourceSelector;
+import org.apache.tools.ant.types.selectors.SelectorUtils;
+import org.apache.tools.ant.util.ConcatResourceInputStream;
+import org.apache.tools.ant.util.FileUtils;
+import org.apache.tools.ant.util.ReaderInputStream;
+import org.apache.tools.ant.util.ResourceUtils;
+import org.apache.tools.ant.util.StringUtils;
+
+/**
+ * This class contains the 'concat' task, used to concatenate a series
+ * of files into a single stream. The destination of this stream may
+ * be the system console, or a file. The following is a sample
+ * invocation:
+ *
+ * <pre>
+ * &lt;concat destfile=&quot;${build.dir}/index.xml&quot;
+ * append=&quot;false&quot;&gt;
+ *
+ * &lt;fileset dir=&quot;${xml.root.dir}&quot;
+ * includes=&quot;*.xml&quot; /&gt;
+ *
+ * &lt;/concat&gt;
+ * </pre>
+ *
+ */
+public class Concat extends Task implements ResourceCollection {
+
+ // The size of buffers to be used
+ private static final int BUFFER_SIZE = 8192;
+
+ private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+
+ private static final ResourceSelector EXISTS = new Exists();
+ private static final ResourceSelector NOT_EXISTS = new Not(EXISTS);
+
+ /**
+ * sub element points to a file or contains text
+ */
+ public static class TextElement extends ProjectComponent {
+ private String value = "";
+ private boolean trimLeading = false;
+ private boolean trim = false;
+ private boolean filtering = true;
+ private String encoding = null;
+
+ /**
+ * whether to filter the text in this element
+ * or not.
+ *
+ * @param filtering true if the text should be filtered.
+ * the default value is true.
+ */
+ public void setFiltering(boolean filtering) {
+ this.filtering = filtering;
+ }
+
+ /** return the filtering attribute */
+ private boolean getFiltering() {
+ return filtering;
+ }
+
+ /**
+ * The encoding of the text element
+ *
+ * @param encoding the name of the charset used to encode
+ */
+ public void setEncoding(String encoding) {
+ this.encoding = encoding;
+ }
+
+ /**
+ * set the text using a file
+ * @param file the file to use
+ * @throws BuildException if the file does not exist, or cannot be
+ * read
+ */
+ public void setFile(File file) throws BuildException {
+ // non-existing files are not allowed
+ if (!file.exists()) {
+ throw new BuildException("File " + file + " does not exist.");
+ }
+
+ BufferedReader reader = null;
+ try {
+ if (this.encoding == null) {
+ reader = new BufferedReader(new FileReader(file));
+ } else {
+ reader = new BufferedReader(
+ new InputStreamReader(new FileInputStream(file),
+ this.encoding));
+ }
+ value = FileUtils.safeReadFully(reader);
+ } catch (IOException ex) {
+ throw new BuildException(ex);
+ } finally {
+ FileUtils.close(reader);
+ }
+ }
+
+ /**
+ * set the text using inline
+ * @param value the text to place inline
+ */
+ public void addText(String value) {
+ this.value += getProject().replaceProperties(value);
+ }
+
+ /**
+ * s:^\s*:: on each line of input
+ * @param strip if true do the trim
+ */
+ public void setTrimLeading(boolean strip) {
+ this.trimLeading = strip;
+ }
+
+ /**
+ * whether to call text.trim()
+ * @param trim if true trim the text
+ */
+ public void setTrim(boolean trim) {
+ this.trim = trim;
+ }
+
+ /**
+ * @return the text, after possible trimming
+ */
+ public String getValue() {
+ if (value == null) {
+ value = "";
+ }
+ if (value.trim().length() == 0) {
+ value = "";
+ }
+ if (trimLeading) {
+ char[] current = value.toCharArray();
+ StringBuffer b = new StringBuffer(current.length);
+ boolean startOfLine = true;
+ int pos = 0;
+ while (pos < current.length) {
+ char ch = current[pos++];
+ if (startOfLine) {
+ if (ch == ' ' || ch == '\t') {
+ continue;
+ }
+ startOfLine = false;
+ }
+ b.append(ch);
+ if (ch == '\n' || ch == '\r') {
+ startOfLine = true;
+ }
+ }
+ value = b.toString();
+ }
+ if (trim) {
+ value = value.trim();
+ }
+ return value;
+ }
+ }
+
+ private interface ReaderFactory<S> {
+ Reader getReader(S s) throws IOException;
+ }
+
+ /**
+ * This class reads from each of the source files in turn.
+ * The concatentated result can then be filtered as
+ * a single stream.
+ */
+ private final class MultiReader<S> extends Reader {
+ private Reader reader = null;
+ private int lastPos = 0;
+ private char[] lastChars = new char[eolString.length()];
+ private boolean needAddSeparator = false;
+ private Iterator<S> readerSources;
+ private ReaderFactory<S> factory;
+
+ private MultiReader(Iterator<S> readerSources, ReaderFactory<S> factory) {
+ this.readerSources = readerSources;
+ this.factory = factory;
+ }
+
+ private Reader getReader() throws IOException {
+ if (reader == null && readerSources.hasNext()) {
+ reader = factory.getReader(readerSources.next());
+ Arrays.fill(lastChars, (char) 0);
+ }
+ return reader;
+ }
+
+ private void nextReader() throws IOException {
+ close();
+ reader = null;
+ }
+
+ /**
+ * Read a character from the current reader object. Advance
+ * to the next if the reader is finished.
+ * @return the character read, -1 for EOF on the last reader.
+ * @exception IOException - possibly thrown by the read for a reader
+ * object.
+ */
+ public int read() throws IOException {
+ if (needAddSeparator) {
+ if (lastPos >= eolString.length()) {
+ lastPos = 0;
+ needAddSeparator = false;
+ } else {
+ return eolString.charAt(lastPos++);
+ }
+ }
+ while (getReader() != null) {
+ int ch = getReader().read();
+ if (ch == -1) {
+ nextReader();
+ if (isFixLastLine() && isMissingEndOfLine()) {
+ needAddSeparator = true;
+ lastPos = 1;
+ return eolString.charAt(0);
+ }
+ } else {
+ addLastChar((char) ch);
+ return ch;
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * Read into the buffer <code>cbuf</code>.
+ * @param cbuf The array to be read into.
+ * @param off The offset.
+ * @param len The length to read.
+ * @exception IOException - possibly thrown by the reads to the
+ * reader objects.
+ */
+ public int read(char[] cbuf, int off, int len)
+ throws IOException {
+
+ int amountRead = 0;
+ while (getReader() != null || needAddSeparator) {
+ if (needAddSeparator) {
+ cbuf[off] = eolString.charAt(lastPos++);
+ if (lastPos >= eolString.length()) {
+ lastPos = 0;
+ needAddSeparator = false;
+ }
+ len--;
+ off++;
+ amountRead++;
+ if (len == 0) {
+ return amountRead;
+ }
+ continue;
+ }
+ int nRead = getReader().read(cbuf, off, len);
+ if (nRead == -1 || nRead == 0) {
+ nextReader();
+ if (isFixLastLine() && isMissingEndOfLine()) {
+ needAddSeparator = true;
+ lastPos = 0;
+ }
+ } else {
+ if (isFixLastLine()) {
+ for (int i = nRead;
+ i > (nRead - lastChars.length);
+ --i) {
+ if (i <= 0) {
+ break;
+ }
+ addLastChar(cbuf[off + i - 1]);
+ }
+ }
+ len -= nRead;
+ off += nRead;
+ amountRead += nRead;
+ if (len == 0) {
+ return amountRead;
+ }
+ }
+ }
+ if (amountRead == 0) {
+ return -1;
+ } else {
+ return amountRead;
+ }
+ }
+
+ /**
+ * Close the current reader
+ */
+ public void close() throws IOException {
+ if (reader != null) {
+ reader.close();
+ }
+ }
+
+ /**
+ * if checking for end of line at end of file
+ * add a character to the lastchars buffer
+ */
+ private void addLastChar(char ch) {
+ for (int i = lastChars.length - 2; i >= 0; --i) {
+ lastChars[i] = lastChars[i + 1];
+ }
+ lastChars[lastChars.length - 1] = ch;
+ }
+
+ /**
+ * return true if the lastchars buffer does
+ * not contain the lineseparator
+ */
+ private boolean isMissingEndOfLine() {
+ for (int i = 0; i < lastChars.length; ++i) {
+ if (lastChars[i] != eolString.charAt(i)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private boolean isFixLastLine() {
+ return fixLastLine && textBuffer == null;
+ }
+ }
+
+ private final class ConcatResource extends Resource {
+ private ResourceCollection c;
+
+ private ConcatResource(ResourceCollection c) {
+ this.c = c;
+ }
+ public InputStream getInputStream() throws IOException {
+ if (binary) {
+ ConcatResourceInputStream result = new ConcatResourceInputStream(c);
+ result.setManagingComponent(this);
+ return result;
+ }
+ Reader resourceReader = getFilteredReader(
+ new MultiReader<Resource>(c.iterator(), resourceReaderFactory));
+ Reader rdr;
+ if (header == null && footer == null) {
+ rdr = resourceReader;
+ } else {
+ int readerCount = 1;
+ if (header != null) {
+ readerCount++;
+ }
+ if (footer != null) {
+ readerCount++;
+ }
+ Reader[] readers = new Reader[readerCount];
+ int pos = 0;
+ if (header != null) {
+ readers[pos] = new StringReader(header.getValue());
+ if (header.getFiltering()) {
+ readers[pos] = getFilteredReader(readers[pos]);
+ }
+ pos++;
+ }
+ readers[pos++] = resourceReader;
+ if (footer != null) {
+ readers[pos] = new StringReader(footer.getValue());
+ if (footer.getFiltering()) {
+ readers[pos] = getFilteredReader(readers[pos]);
+ }
+ }
+ rdr = new MultiReader<Reader>(Arrays.asList(readers).iterator(),
+ identityReaderFactory);
+ }
+ return outputEncoding == null ? new ReaderInputStream(rdr)
+ : new ReaderInputStream(rdr, outputEncoding);
+ }
+ public String getName() {
+ return resourceName == null
+ ? "concat (" + String.valueOf(c) + ")" : resourceName;
+ }
+ }
+
+ // Attributes.
+
+ /**
+ * The destination of the stream. If <code>null</code>, the system
+ * console is used.
+ */
+ private Resource dest;
+
+ /**
+ * Whether or not the stream should be appended if the destination file
+ * exists.
+ * Defaults to <code>false</code>.
+ */
+ private boolean append;
+
+ /**
+ * Stores the input file encoding.
+ */
+ private String encoding;
+
+ /** Stores the output file encoding. */
+ private String outputEncoding;
+
+ /** Stores the binary attribute */
+ private boolean binary;
+
+ // Child elements.
+
+ /**
+ * This buffer stores the text within the 'concat' element.
+ */
+ private StringBuffer textBuffer;
+
+ /**
+ * Stores a collection of file sets and/or file lists, used to
+ * select multiple files for concatenation.
+ */
+ private Resources rc;
+
+ /** for filtering the concatenated */
+ private Vector<FilterChain> filterChains;
+ /** ignore dates on input files */
+ private boolean forceOverwrite = true;
+ /** overwrite read-only files */
+ private boolean force = false;
+ /** String to place at the start of the concatenated stream */
+ private TextElement footer;
+ /** String to place at the end of the concatenated stream */
+ private TextElement header;
+ /** add missing line.separator to files **/
+ private boolean fixLastLine = false;
+ /** endofline for fixlast line */
+ private String eolString;
+ /** outputwriter */
+ private Writer outputWriter = null;
+ /** whether to not create dest if no source files are
+ * available */
+ private boolean ignoreEmpty = true;
+ /** exposed resource name */
+ private String resourceName;
+
+ private ReaderFactory<Resource> resourceReaderFactory = new ReaderFactory<Resource>() {
+ public Reader getReader(Resource o) throws IOException {
+ InputStream is = o.getInputStream();
+ return new BufferedReader(encoding == null
+ ? new InputStreamReader(is)
+ : new InputStreamReader(is, encoding));
+ }
+ };
+
+ private ReaderFactory<Reader> identityReaderFactory = new ReaderFactory<Reader>() {
+ public Reader getReader(Reader o) {
+ return o;
+ }
+ };
+
+ /**
+ * Construct a new Concat task.
+ */
+ public Concat() {
+ reset();
+ }
+
+ /**
+ * Reset state to default.
+ */
+ public void reset() {
+ append = false;
+ forceOverwrite = true;
+ dest = null;
+ encoding = null;
+ outputEncoding = null;
+ fixLastLine = false;
+ filterChains = null;
+ footer = null;
+ header = null;
+ binary = false;
+ outputWriter = null;
+ textBuffer = null;
+ eolString = StringUtils.LINE_SEP;
+ rc = null;
+ ignoreEmpty = true;
+ force = false;
+ }
+
+ // Attribute setters.
+
+ /**
+ * Sets the destination file, or uses the console if not specified.
+ * @param destinationFile the destination file
+ */
+ public void setDestfile(File destinationFile) {
+ setDest(new FileResource(destinationFile));
+ }
+
+ /**
+ * Set the resource to write to.
+ * @param dest the Resource to write to.
+ * @since Ant 1.8
+ */
+ public void setDest(Resource dest) {
+ this.dest = dest;
+ }
+
+ /**
+ * Sets the behavior when the destination exists. If set to
+ * <code>true</code> the task will append the stream data an
+ * {@link Appendable} resource; otherwise existing content will be
+ * overwritten. Defaults to <code>false</code>.
+ * @param append if true append output.
+ */
+ public void setAppend(boolean append) {
+ this.append = append;
+ }
+
+ /**
+ * Sets the character encoding
+ * @param encoding the encoding of the input stream and unless
+ * outputencoding is set, the outputstream.
+ */
+ public void setEncoding(String encoding) {
+ this.encoding = encoding;
+ if (outputEncoding == null) {
+ outputEncoding = encoding;
+ }
+ }
+
+ /**
+ * Sets the character encoding for outputting
+ * @param outputEncoding the encoding for the output file
+ * @since Ant 1.6
+ */
+ public void setOutputEncoding(String outputEncoding) {
+ this.outputEncoding = outputEncoding;
+ }
+
+ /**
+ * Force overwrite existing destination file
+ * @param forceOverwrite if true always overwrite, otherwise only
+ * overwrite if the output file is older any of the
+ * input files.
+ * @since Ant 1.6
+ * @deprecated use #setOverwrite instead
+ */
+ public void setForce(boolean forceOverwrite) {
+ this.forceOverwrite = forceOverwrite;
+ }
+
+ /**
+ * Force overwrite existing destination file
+ * @param forceOverwrite if true always overwrite, otherwise only
+ * overwrite if the output file is older any of the
+ * input files.
+ * @since Ant 1.8.2
+ */
+ public void setOverwrite(boolean forceOverwrite) {
+ setForce(forceOverwrite);
+ }
+
+ /**
+ * Whether read-only destinations will be overwritten.
+ *
+ * <p>Defaults to false</p>
+ *
+ * @since Ant 1.8.2
+ */
+ public void setForceReadOnly(boolean f) {
+ force = f;
+ }
+
+ /**
+ * Sets the behavior when no source resource files are available. If set to
+ * <code>false</code> the destination file will always be created.
+ * Defaults to <code>true</code>.
+ * @param ignoreEmpty if false honour destinationfile creation.
+ * @since Ant 1.8.0
+ */
+ public void setIgnoreEmpty(boolean ignoreEmpty) {
+ this.ignoreEmpty = ignoreEmpty;
+ }
+
+ /**
+ * Set the name that will be reported by the exposed {@link Resource}.
+ * @param resourceName to set
+ * @since Ant 1.8.3
+ */
+ public void setResourceName(String resourceName) {
+ this.resourceName = resourceName;
+ }
+
+ // Nested element creators.
+
+ /**
+ * Path of files to concatenate.
+ * @return the path used for concatenating
+ * @since Ant 1.6
+ */
+ public Path createPath() {
+ Path path = new Path(getProject());
+ add(path);
+ return path;
+ }
+
+ /**
+ * Set of files to concatenate.
+ * @param set the set of files
+ */
+ public void addFileset(FileSet set) {
+ add(set);
+ }
+
+ /**
+ * List of files to concatenate.
+ * @param list the list of files
+ */
+ public void addFilelist(FileList list) {
+ add(list);
+ }
+
+ /**
+ * Add an arbitrary ResourceCollection.
+ * @param c the ResourceCollection to add.
+ * @since Ant 1.7
+ */
+ public void add(ResourceCollection c) {
+ synchronized (this) {
+ if (rc == null) {
+ rc = new Resources();
+ rc.setProject(getProject());
+ rc.setCache(true);
+ }
+ }
+ rc.add(c);
+ }
+
+ /**
+ * Adds a FilterChain.
+ * @param filterChain a filterchain to filter the concatenated input
+ * @since Ant 1.6
+ */
+ public void addFilterChain(FilterChain filterChain) {
+ if (filterChains == null) {
+ filterChains = new Vector<FilterChain>();
+ }
+ filterChains.addElement(filterChain);
+ }
+
+ /**
+ * This method adds text which appears in the 'concat' element.
+ * @param text the text to be concated.
+ */
+ public void addText(String text) {
+ if (textBuffer == null) {
+ // Initialize to the size of the first text fragment, with
+ // the hopes that it's the only one.
+ textBuffer = new StringBuffer(text.length());
+ }
+
+ // Append the fragment -- we defer property replacement until
+ // later just in case we get a partial property in a fragment.
+ textBuffer.append(text);
+ }
+
+ /**
+ * Add a header to the concatenated output
+ * @param headerToAdd the header
+ * @since Ant 1.6
+ */
+ public void addHeader(TextElement headerToAdd) {
+ this.header = headerToAdd;
+ }
+
+ /**
+ * Add a footer to the concatenated output
+ * @param footerToAdd the footer
+ * @since Ant 1.6
+ */
+ public void addFooter(TextElement footerToAdd) {
+ this.footer = footerToAdd;
+ }
+
+ /**
+ * Append line.separator to files that do not end
+ * with a line.separator, default false.
+ * @param fixLastLine if true make sure each input file has
+ * new line on the concatenated stream
+ * @since Ant 1.6
+ */
+ public void setFixLastLine(boolean fixLastLine) {
+ this.fixLastLine = fixLastLine;
+ }
+
+ /**
+ * Specify the end of line to find and to add if
+ * not present at end of each input file. This attribute
+ * is used in conjunction with fixlastline.
+ * @param crlf the type of new line to add -
+ * cr, mac, lf, unix, crlf, or dos
+ * @since Ant 1.6
+ */
+ public void setEol(FixCRLF.CrLf crlf) {
+ String s = crlf.getValue();
+ if (s.equals("cr") || s.equals("mac")) {
+ eolString = "\r";
+ } else if (s.equals("lf") || s.equals("unix")) {
+ eolString = "\n";
+ } else if (s.equals("crlf") || s.equals("dos")) {
+ eolString = "\r\n";
+ }
+ }
+
+ /**
+ * Set the output writer. This is to allow
+ * concat to be used as a nested element.
+ * @param outputWriter the output writer.
+ * @since Ant 1.6
+ */
+ public void setWriter(Writer outputWriter) {
+ this.outputWriter = outputWriter;
+ }
+
+ /**
+ * Set the binary attribute. If true, concat will concatenate the files
+ * byte for byte. This mode does not allow any filtering or other
+ * modifications to the input streams. The default value is false.
+ * @since Ant 1.6.2
+ * @param binary if true, enable binary mode.
+ */
+ public void setBinary(boolean binary) {
+ this.binary = binary;
+ }
+
+ /**
+ * Execute the concat task.
+ */
+ public void execute() {
+ validate();
+ if (binary && dest == null) {
+ throw new BuildException(
+ "dest|destfile attribute is required for binary concatenation");
+ }
+ ResourceCollection c = getResources();
+ if (isUpToDate(c)) {
+ log(dest + " is up-to-date.", Project.MSG_VERBOSE);
+ return;
+ }
+ if (c.size() == 0 && ignoreEmpty) {
+ return;
+ }
+ try {
+ //most of these are defaulted because the concat-as-a-resource code hijacks a lot:
+ ResourceUtils.copyResource(new ConcatResource(c), dest == null
+ ? new LogOutputResource(this, Project.MSG_WARN)
+ : dest,
+ null, null, true, false, append, null,
+ null, getProject(), force);
+ } catch (IOException e) {
+ throw new BuildException("error concatenating content to " + dest, e);
+ }
+ }
+
+ /**
+ * Implement ResourceCollection.
+ * @return Iterator&lt;Resource&gt;.
+ */
+ public Iterator<Resource> iterator() {
+ validate();
+ return Collections.<Resource>singletonList(new ConcatResource(getResources())).iterator();
+ }
+
+ /**
+ * Implement ResourceCollection.
+ * @return 1.
+ */
+ public int size() {
+ return 1;
+ }
+
+ /**
+ * Implement ResourceCollection.
+ * @return false.
+ */
+ public boolean isFilesystemOnly() {
+ return false;
+ }
+
+ /**
+ * Validate configuration options.
+ */
+ private void validate() {
+
+ // treat empty nested text as no text
+ sanitizeText();
+
+ // if binary check if incompatible attributes are used
+ if (binary) {
+ if (textBuffer != null) {
+ throw new BuildException(
+ "Nested text is incompatible with binary concatenation");
+ }
+ if (encoding != null || outputEncoding != null) {
+ throw new BuildException(
+ "Setting input or output encoding is incompatible with binary"
+ + " concatenation");
+ }
+ if (filterChains != null) {
+ throw new BuildException(
+ "Setting filters is incompatible with binary concatenation");
+ }
+ if (fixLastLine) {
+ throw new BuildException(
+ "Setting fixlastline is incompatible with binary concatenation");
+ }
+ if (header != null || footer != null) {
+ throw new BuildException(
+ "Nested header or footer is incompatible with binary concatenation");
+ }
+ }
+ if (dest != null && outputWriter != null) {
+ throw new BuildException(
+ "Cannot specify both a destination resource and an output writer");
+ }
+ // Sanity check our inputs.
+ if (rc == null && textBuffer == null) {
+ // Nothing to concatenate!
+ throw new BuildException(
+ "At least one resource must be provided, or some text.");
+ }
+ if (rc != null && textBuffer != null) {
+ // If using resources, disallow inline text. This is similar to
+ // using GNU 'cat' with file arguments--stdin is simply ignored.
+ throw new BuildException(
+ "Cannot include inline text when using resources.");
+ }
+ }
+
+ /**
+ * Get the resources to concatenate.
+ */
+ private ResourceCollection getResources() {
+ if (rc == null) {
+ return new StringResource(getProject(), textBuffer.toString());
+ }
+ if (dest != null) {
+ Intersect checkDestNotInSources = new Intersect();
+ checkDestNotInSources.setProject(getProject());
+ checkDestNotInSources.add(rc);
+ checkDestNotInSources.add(dest);
+ if (checkDestNotInSources.size() > 0) {
+ throw new BuildException("Destination resource " + dest
+ + " was specified as an input resource.");
+ }
+ }
+ Restrict noexistRc = new Restrict();
+ noexistRc.add(NOT_EXISTS);
+ noexistRc.add(rc);
+ for (Resource r : noexistRc) {
+ log(r + " does not exist.", Project.MSG_ERR);
+ }
+ Restrict result = new Restrict();
+ result.add(EXISTS);
+ result.add(rc);
+ return result;
+ }
+
+ private boolean isUpToDate(ResourceCollection c) {
+ if (dest == null || forceOverwrite) {
+ return false;
+ }
+ for (Resource r : c) {
+ if (SelectorUtils.isOutOfDate(r, dest, FILE_UTILS.getFileTimestampGranularity())) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Treat empty nested text as no text.
+ *
+ * <p>Depending on the XML parser, addText may have been called
+ * for &quot;ignorable whitespace&quot; as well.</p>
+ */
+ private void sanitizeText() {
+ if (textBuffer != null && "".equals(textBuffer.toString().trim())) {
+ textBuffer = null;
+ }
+ }
+
+ private Reader getFilteredReader(Reader r) {
+ if (filterChains == null) {
+ return r;
+ }
+ ChainReaderHelper helper = new ChainReaderHelper();
+ helper.setBufferSize(BUFFER_SIZE);
+ helper.setPrimaryReader(r);
+ helper.setFilterChains(filterChains);
+ helper.setProject(getProject());
+ //used to be a BufferedReader here, but we should be buffering lower:
+ return helper.getAssembledReader();
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/ConditionTask.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/ConditionTask.java
new file mode 100644
index 00000000..60904e03
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/ConditionTask.java
@@ -0,0 +1,130 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.PropertyHelper;
+import org.apache.tools.ant.taskdefs.condition.Condition;
+import org.apache.tools.ant.taskdefs.condition.ConditionBase;
+
+/**
+ * Task to set a property conditionally using &lt;uptodate&gt;, &lt;available&gt;,
+ * and many other supported conditions.
+ *
+ * <p>This task supports boolean logic as well as pluggable conditions
+ * to decide, whether a property should be set.</p>
+ *
+ * <p>This task does not extend Task to take advantage of
+ * ConditionBase.</p>
+ *
+ * @since Ant 1.4
+ *
+ * @ant.task category="control"
+ */
+public class ConditionTask extends ConditionBase {
+
+ private String property = null;
+ private Object value = "true";
+ private Object alternative = null;
+
+ /**
+ * Constructor, names this task "condition".
+ */
+ public ConditionTask() {
+ super("condition");
+ }
+
+ /**
+ * The name of the property to set. Required.
+ * @param p the name of the property
+ * @since Ant 1.4
+ */
+ public void setProperty(String p) {
+ property = p;
+ }
+
+ /**
+ * The value for the property to set, if condition evaluates to true.
+ * Defaults to "true".
+ * @param value the (Object) value of the property
+ * @since Ant 1.8
+ */
+ public void setValue(Object value) {
+ this.value = value;
+ }
+
+ /**
+ * The value for the property to set, if condition evaluates to true.
+ * Defaults to "true".
+ * @param v the value of the property
+ * @since Ant 1.4
+ */
+ public void setValue(String v) {
+ setValue((Object) v);
+ }
+
+ /**
+ * The value for the property to set, if condition evaluates to false.
+ * If this attribute is not specified, the property will not be set.
+ * @param alt the alternate value of the property.
+ * @since Ant 1.8
+ */
+ public void setElse(Object alt) {
+ alternative = alt;
+ }
+
+ /**
+ * The value for the property to set, if condition evaluates to false.
+ * If this attribute is not specified, the property will not be set.
+ * @param e the alternate value of the property.
+ * @since Ant 1.6.3
+ */
+ public void setElse(String e) {
+ setElse((Object) e);
+ }
+
+ /**
+ * See whether our nested condition holds and set the property.
+ *
+ * @since Ant 1.4
+ * @exception BuildException if an error occurs
+ */
+ public void execute() throws BuildException {
+ if (countConditions() > 1) {
+ throw new BuildException("You must not nest more than one condition into <"
+ + getTaskName() + ">");
+ }
+ if (countConditions() < 1) {
+ throw new BuildException("You must nest a condition into <" + getTaskName() + ">");
+ }
+ if (property == null) {
+ throw new BuildException("The property attribute is required.");
+ }
+ Condition c = (Condition) getConditions().nextElement();
+ if (c.eval()) {
+ log("Condition true; setting " + property + " to " + value, Project.MSG_DEBUG);
+ PropertyHelper.getPropertyHelper(getProject()).setNewProperty(property, value);
+ } else if (alternative != null) {
+ log("Condition false; setting " + property + " to " + alternative, Project.MSG_DEBUG);
+ PropertyHelper.getPropertyHelper(getProject()).setNewProperty(property, alternative);
+ } else {
+ log("Condition false; not setting " + property, Project.MSG_DEBUG);
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Copy.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Copy.java
new file mode 100644
index 00000000..2394b8f4
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Copy.java
@@ -0,0 +1,1111 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Map;
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.DirectoryScanner;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.types.FileSet;
+import org.apache.tools.ant.types.FilterChain;
+import org.apache.tools.ant.types.FilterSet;
+import org.apache.tools.ant.types.FilterSetCollection;
+import org.apache.tools.ant.types.Mapper;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.ResourceCollection;
+import org.apache.tools.ant.types.ResourceFactory;
+import org.apache.tools.ant.types.resources.FileProvider;
+import org.apache.tools.ant.types.resources.FileResource;
+import org.apache.tools.ant.util.FileNameMapper;
+import org.apache.tools.ant.util.FileUtils;
+import org.apache.tools.ant.util.FlatFileNameMapper;
+import org.apache.tools.ant.util.IdentityMapper;
+import org.apache.tools.ant.util.LinkedHashtable;
+import org.apache.tools.ant.util.ResourceUtils;
+import org.apache.tools.ant.util.SourceFileScanner;
+
+/**
+ * <p>Copies a file or directory to a new file
+ * or directory. Files are only copied if the source file is newer
+ * than the destination file, or when the destination file does not
+ * exist. It is possible to explicitly overwrite existing files.</p>
+ *
+ * <p>This implementation is based on Arnout Kuiper's initial design
+ * document, the following mailing list discussions, and the
+ * copyfile/copydir tasks.</p>
+ *
+ *
+ * @since Ant 1.2
+ *
+ * @ant.task category="filesystem"
+ */
+public class Copy extends Task {
+ private static final String MSG_WHEN_COPYING_EMPTY_RC_TO_FILE =
+ "Cannot perform operation from directory to file.";
+
+ static final File NULL_FILE_PLACEHOLDER = new File("/NULL_FILE");
+ static final String LINE_SEPARATOR = System.getProperty("line.separator");
+ // CheckStyle:VisibilityModifier OFF - bc
+ protected File file = null; // the source file
+ protected File destFile = null; // the destination file
+ protected File destDir = null; // the destination directory
+ protected Vector<ResourceCollection> rcs = new Vector<ResourceCollection>();
+ // here to provide API backwards compatibility
+ protected Vector<ResourceCollection> filesets = rcs;
+
+ private boolean enableMultipleMappings = false;
+ protected boolean filtering = false;
+ protected boolean preserveLastModified = false;
+ protected boolean forceOverwrite = false;
+ protected boolean flatten = false;
+ protected int verbosity = Project.MSG_VERBOSE;
+ protected boolean includeEmpty = true;
+ protected boolean failonerror = true;
+
+ protected Hashtable<String, String[]> fileCopyMap = new LinkedHashtable<String, String[]>();
+ protected Hashtable<String, String[]> dirCopyMap = new LinkedHashtable<String, String[]>();
+ protected Hashtable<File, File> completeDirMap = new LinkedHashtable<File, File>();
+
+ protected Mapper mapperElement = null;
+ protected FileUtils fileUtils;
+ //CheckStyle:VisibilityModifier ON
+ private final Vector<FilterChain> filterChains = new Vector<FilterChain>();
+ private final Vector<FilterSet> filterSets = new Vector<FilterSet>();
+ private String inputEncoding = null;
+ private String outputEncoding = null;
+ private long granularity = 0;
+ private boolean force = false;
+ private boolean quiet = false;
+
+ // used to store the single non-file resource to copy when the
+ // tofile attribute has been used
+ private Resource singleResource = null;
+
+ /**
+ * Copy task constructor.
+ */
+ public Copy() {
+ fileUtils = FileUtils.getFileUtils();
+ granularity = fileUtils.getFileTimestampGranularity();
+ }
+
+ /**
+ * Get the FileUtils for this task.
+ * @return the fileutils object.
+ */
+ protected FileUtils getFileUtils() {
+ return fileUtils;
+ }
+
+ /**
+ * Set a single source file to copy.
+ * @param file the file to copy.
+ */
+ public void setFile(final File file) {
+ this.file = file;
+ }
+
+ /**
+ * Set the destination file.
+ * @param destFile the file to copy to.
+ */
+ public void setTofile(final File destFile) {
+ this.destFile = destFile;
+ }
+
+ /**
+ * Set the destination directory.
+ * @param destDir the destination directory.
+ */
+ public void setTodir(final File destDir) {
+ this.destDir = destDir;
+ }
+
+ /**
+ * Add a FilterChain.
+ * @return a filter chain object.
+ */
+ public FilterChain createFilterChain() {
+ final FilterChain filterChain = new FilterChain();
+ filterChains.addElement(filterChain);
+ return filterChain;
+ }
+
+ /**
+ * Add a filterset.
+ * @return a filter set object.
+ */
+ public FilterSet createFilterSet() {
+ final FilterSet filterSet = new FilterSet();
+ filterSets.addElement(filterSet);
+ return filterSet;
+ }
+
+ /**
+ * Give the copied files the same last modified time as the original files.
+ * @param preserve a boolean string.
+ * @deprecated since 1.5.x.
+ * setPreserveLastModified(String) has been deprecated and
+ * replaced with setPreserveLastModified(boolean) to
+ * consistently let the Introspection mechanism work.
+ */
+ @Deprecated
+ public void setPreserveLastModified(final String preserve) {
+ setPreserveLastModified(Project.toBoolean(preserve));
+ }
+
+ /**
+ * Give the copied files the same last modified time as the original files.
+ * @param preserve if true preserve the modified time; default is false.
+ */
+ public void setPreserveLastModified(final boolean preserve) {
+ preserveLastModified = preserve;
+ }
+
+ /**
+ * Get whether to give the copied files the same last modified time as
+ * the original files.
+ * @return the whether destination files will inherit the modification
+ * times of the corresponding source files.
+ * @since 1.32, Ant 1.5
+ */
+ public boolean getPreserveLastModified() {
+ return preserveLastModified;
+ }
+
+ /**
+ * Get the filtersets being applied to this operation.
+ *
+ * @return a vector of FilterSet objects.
+ */
+ protected Vector<FilterSet> getFilterSets() {
+ return filterSets;
+ }
+
+ /**
+ * Get the filterchains being applied to this operation.
+ *
+ * @return a vector of FilterChain objects.
+ */
+ protected Vector<FilterChain> getFilterChains() {
+ return filterChains;
+ }
+
+ /**
+ * Set filtering mode.
+ * @param filtering if true enable filtering; default is false.
+ */
+ public void setFiltering(final boolean filtering) {
+ this.filtering = filtering;
+ }
+
+ /**
+ * Set overwrite mode regarding existing destination file(s).
+ * @param overwrite if true force overwriting of destination file(s)
+ * even if the destination file(s) are younger than
+ * the corresponding source file. Default is false.
+ */
+ public void setOverwrite(final boolean overwrite) {
+ this.forceOverwrite = overwrite;
+ }
+
+ /**
+ * Whether read-only destinations will be overwritten.
+ *
+ * <p>Defaults to false</p>
+ *
+ * @since Ant 1.8.2
+ */
+ public void setForce(final boolean f) {
+ force = f;
+ }
+
+ /**
+ * Whether read-only destinations will be overwritten.
+ *
+ * @since Ant 1.8.2
+ */
+ public boolean getForce() {
+ return force;
+ }
+
+ /**
+ * Set whether files copied from directory trees will be "flattened"
+ * into a single directory. If there are multiple files with
+ * the same name in the source directory tree, only the first
+ * file will be copied into the "flattened" directory, unless
+ * the forceoverwrite attribute is true.
+ * @param flatten if true flatten the destination directory. Default
+ * is false.
+ */
+ public void setFlatten(final boolean flatten) {
+ this.flatten = flatten;
+ }
+
+ /**
+ * Set verbose mode. Used to force listing of all names of copied files.
+ * @param verbose whether to output the names of copied files.
+ * Default is false.
+ */
+ public void setVerbose(final boolean verbose) {
+ this.verbosity = verbose ? Project.MSG_INFO : Project.MSG_VERBOSE;
+ }
+
+ /**
+ * Set whether to copy empty directories.
+ * @param includeEmpty if true copy empty directories. Default is true.
+ */
+ public void setIncludeEmptyDirs(final boolean includeEmpty) {
+ this.includeEmpty = includeEmpty;
+ }
+
+ /**
+ * Set quiet mode. Used to hide messages when a file or directory to be
+ * copied does not exist.
+ *
+ * @param quiet
+ * whether or not to display error messages when a file or
+ * directory does not exist. Default is false.
+ */
+ public void setQuiet(final boolean quiet) {
+ this.quiet = quiet;
+ }
+
+ /**
+ * Set method of handling mappers that return multiple
+ * mappings for a given source path.
+ * @param enableMultipleMappings If true the task will
+ * copy to all the mappings for a given source path, if
+ * false, only the first file or directory is
+ * processed.
+ * By default, this setting is false to provide backward
+ * compatibility with earlier releases.
+ * @since Ant 1.6
+ */
+ public void setEnableMultipleMappings(final boolean enableMultipleMappings) {
+ this.enableMultipleMappings = enableMultipleMappings;
+ }
+
+ /**
+ * Get whether multiple mapping is enabled.
+ * @return true if multiple mapping is enabled; false otherwise.
+ */
+ public boolean isEnableMultipleMapping() {
+ return enableMultipleMappings;
+ }
+
+ /**
+ * Set whether to fail when errors are encountered. If false, note errors
+ * to the output but keep going. Default is true.
+ * @param failonerror true or false.
+ */
+ public void setFailOnError(final boolean failonerror) {
+ this.failonerror = failonerror;
+ }
+
+ /**
+ * Add a set of files to copy.
+ * @param set a set of files to copy.
+ */
+ public void addFileset(final FileSet set) {
+ add(set);
+ }
+
+ /**
+ * Add a collection of files to copy.
+ * @param res a resource collection to copy.
+ * @since Ant 1.7
+ */
+ public void add(final ResourceCollection res) {
+ rcs.add(res);
+ }
+
+ /**
+ * Define the mapper to map source to destination files.
+ * @return a mapper to be configured.
+ * @exception BuildException if more than one mapper is defined.
+ */
+ public Mapper createMapper() throws BuildException {
+ if (mapperElement != null) {
+ throw new BuildException("Cannot define more than one mapper",
+ getLocation());
+ }
+ mapperElement = new Mapper(getProject());
+ return mapperElement;
+ }
+
+ /**
+ * Add a nested filenamemapper.
+ * @param fileNameMapper the mapper to add.
+ * @since Ant 1.6.3
+ */
+ public void add(final FileNameMapper fileNameMapper) {
+ createMapper().add(fileNameMapper);
+ }
+
+ /**
+ * Set the character encoding.
+ * @param encoding the character encoding.
+ * @since 1.32, Ant 1.5
+ */
+ public void setEncoding(final String encoding) {
+ this.inputEncoding = encoding;
+ if (outputEncoding == null) {
+ outputEncoding = encoding;
+ }
+ }
+
+ /**
+ * Get the character encoding to be used.
+ * @return the character encoding, <code>null</code> if not set.
+ *
+ * @since 1.32, Ant 1.5
+ */
+ public String getEncoding() {
+ return inputEncoding;
+ }
+
+ /**
+ * Set the character encoding for output files.
+ * @param encoding the output character encoding.
+ * @since Ant 1.6
+ */
+ public void setOutputEncoding(final String encoding) {
+ this.outputEncoding = encoding;
+ }
+
+ /**
+ * Get the character encoding for output files.
+ * @return the character encoding for output files,
+ * <code>null</code> if not set.
+ *
+ * @since Ant 1.6
+ */
+ public String getOutputEncoding() {
+ return outputEncoding;
+ }
+
+ /**
+ * Set the number of milliseconds leeway to give before deciding a
+ * target is out of date.
+ *
+ * <p>Default is 1 second, or 2 seconds on DOS systems.</p>
+ * @param granularity the granularity used to decide if a target is out of
+ * date.
+ * @since Ant 1.6.2
+ */
+ public void setGranularity(final long granularity) {
+ this.granularity = granularity;
+ }
+
+ /**
+ * Perform the copy operation.
+ * @exception BuildException if an error occurs.
+ */
+ @Override
+ public void execute() throws BuildException {
+ final File savedFile = file; // may be altered in validateAttributes
+ final File savedDestFile = destFile;
+ final File savedDestDir = destDir;
+ ResourceCollection savedRc = null;
+ if (file == null && destFile != null && rcs.size() == 1) {
+ // will be removed in validateAttributes
+ savedRc = rcs.elementAt(0);
+ }
+
+ try {
+ // make sure we don't have an illegal set of options
+ try {
+ validateAttributes();
+ } catch (final BuildException e) {
+ if (failonerror
+ || !getMessage(e)
+ .equals(MSG_WHEN_COPYING_EMPTY_RC_TO_FILE)) {
+ throw e;
+ } else {
+ log("Warning: " + getMessage(e), Project.MSG_ERR);
+ return;
+ }
+ }
+
+ // deal with the single file
+ copySingleFile();
+
+ // deal with the ResourceCollections
+
+ /* for historical and performance reasons we have to do
+ things in a rather complex way.
+
+ (1) Move is optimized to move directories if a fileset
+ has been included completely, therefore FileSets need a
+ special treatment. This is also required to support
+ the failOnError semantice (skip filesets with broken
+ basedir but handle the remaining collections).
+
+ (2) We carry around a few protected methods that work
+ on basedirs and arrays of names. To optimize stuff, all
+ resources with the same basedir get collected in
+ separate lists and then each list is handled in one go.
+ */
+
+ final HashMap<File, List<String>> filesByBasedir = new HashMap<File, List<String>>();
+ final HashMap<File, List<String>> dirsByBasedir = new HashMap<File, List<String>>();
+ final HashSet<File> baseDirs = new HashSet<File>();
+ final ArrayList<Resource> nonFileResources = new ArrayList<Resource>();
+ final int size = rcs.size();
+ for (int i = 0; i < size; i++) {
+ final ResourceCollection rc = rcs.elementAt(i);
+
+ // Step (1) - beware of the ZipFileSet
+ if (rc instanceof FileSet && rc.isFilesystemOnly()) {
+ final FileSet fs = (FileSet) rc;
+ DirectoryScanner ds = null;
+ try {
+ ds = fs.getDirectoryScanner(getProject());
+ } catch (final BuildException e) {
+ if (failonerror
+ || !getMessage(e).endsWith(DirectoryScanner
+ .DOES_NOT_EXIST_POSTFIX)) {
+ throw e;
+ } else {
+ if (!quiet) {
+ log("Warning: " + getMessage(e), Project.MSG_ERR);
+ }
+ continue;
+ }
+ }
+ final File fromDir = fs.getDir(getProject());
+
+ final String[] srcFiles = ds.getIncludedFiles();
+ final String[] srcDirs = ds.getIncludedDirectories();
+ if (!flatten && mapperElement == null
+ && ds.isEverythingIncluded() && !fs.hasPatterns()) {
+ completeDirMap.put(fromDir, destDir);
+ }
+ add(fromDir, srcFiles, filesByBasedir);
+ add(fromDir, srcDirs, dirsByBasedir);
+ baseDirs.add(fromDir);
+ } else { // not a fileset or contains non-file resources
+
+ if (!rc.isFilesystemOnly() && !supportsNonFileResources()) {
+ throw new BuildException(
+ "Only FileSystem resources are supported.");
+ }
+
+ for (final Resource r : rc) {
+ if (!r.isExists()) {
+ final String message = "Warning: Could not find resource "
+ + r.toLongString() + " to copy.";
+ if (!failonerror) {
+ if (!quiet) {
+ log(message, Project.MSG_ERR);
+ }
+ } else {
+ throw new BuildException(message);
+ }
+ continue;
+ }
+
+ File baseDir = NULL_FILE_PLACEHOLDER;
+ String name = r.getName();
+ final FileProvider fp = r.as(FileProvider.class);
+ if (fp != null) {
+ final FileResource fr = ResourceUtils.asFileResource(fp);
+ baseDir = getKeyFile(fr.getBaseDir());
+ if (fr.getBaseDir() == null) {
+ name = fr.getFile().getAbsolutePath();
+ }
+ }
+
+ // copying of dirs is trivial and can be done
+ // for non-file resources as well as for real
+ // files.
+ if (r.isDirectory() || fp != null) {
+ add(baseDir, name,
+ r.isDirectory() ? dirsByBasedir
+ : filesByBasedir);
+ baseDirs.add(baseDir);
+ } else { // a not-directory file resource
+ // needs special treatment
+ nonFileResources.add(r);
+ }
+ }
+ }
+ }
+
+ iterateOverBaseDirs(baseDirs, dirsByBasedir, filesByBasedir);
+
+ // do all the copy operations now...
+ try {
+ doFileOperations();
+ } catch (final BuildException e) {
+ if (!failonerror) {
+ if (!quiet) {
+ log("Warning: " + getMessage(e), Project.MSG_ERR);
+ }
+ } else {
+ throw e;
+ }
+ }
+
+ if (nonFileResources.size() > 0 || singleResource != null) {
+ final Resource[] nonFiles =
+ nonFileResources.toArray(new Resource[nonFileResources.size()]);
+ // restrict to out-of-date resources
+ final Map<Resource, String[]> map = scan(nonFiles, destDir);
+ if (singleResource != null) {
+ map.put(singleResource,
+ new String[] {destFile.getAbsolutePath()});
+ }
+ try {
+ doResourceOperations(map);
+ } catch (final BuildException e) {
+ if (!failonerror) {
+ if (!quiet) {
+ log("Warning: " + getMessage(e), Project.MSG_ERR);
+ }
+ } else {
+ throw e;
+ }
+ }
+ }
+ } finally {
+ // clean up again, so this instance can be used a second
+ // time
+ singleResource = null;
+ file = savedFile;
+ destFile = savedDestFile;
+ destDir = savedDestDir;
+ if (savedRc != null) {
+ rcs.insertElementAt(savedRc, 0);
+ }
+ fileCopyMap.clear();
+ dirCopyMap.clear();
+ completeDirMap.clear();
+ }
+ }
+
+ /************************************************************************
+ ** protected and private methods
+ ************************************************************************/
+
+ private void copySingleFile() {
+ // deal with the single file
+ if (file != null) {
+ if (file.exists()) {
+ if (destFile == null) {
+ destFile = new File(destDir, file.getName());
+ }
+ if (forceOverwrite || !destFile.exists()
+ || (file.lastModified() - granularity
+ > destFile.lastModified())) {
+ fileCopyMap.put(file.getAbsolutePath(),
+ new String[] {destFile.getAbsolutePath()});
+ } else {
+ log(file + " omitted as " + destFile
+ + " is up to date.", Project.MSG_VERBOSE);
+ }
+ } else {
+ final String message = "Warning: Could not find file "
+ + file.getAbsolutePath() + " to copy.";
+ if (!failonerror) {
+ if (!quiet) {
+ log(message, Project.MSG_ERR);
+ }
+ } else {
+ throw new BuildException(message);
+ }
+ }
+ }
+ }
+
+ private void iterateOverBaseDirs(
+ final HashSet<File> baseDirs, final HashMap<File, List<String>> dirsByBasedir, final HashMap<File, List<String>> filesByBasedir) {
+
+ for (final File f : baseDirs) {
+ final List<String> files = filesByBasedir.get(f);
+ final List<String> dirs = dirsByBasedir.get(f);
+
+ String[] srcFiles = new String[0];
+ if (files != null) {
+ srcFiles = files.toArray(srcFiles);
+ }
+ String[] srcDirs = new String[0];
+ if (dirs != null) {
+ srcDirs = dirs.toArray(srcDirs);
+ }
+ scan(f == NULL_FILE_PLACEHOLDER ? null : f, destDir, srcFiles,
+ srcDirs);
+ }
+ }
+
+ /**
+ * Ensure we have a consistent and legal set of attributes, and set
+ * any internal flags necessary based on different combinations
+ * of attributes.
+ * @exception BuildException if an error occurs.
+ */
+ protected void validateAttributes() throws BuildException {
+ if (file == null && rcs.size() == 0) {
+ throw new BuildException(
+ "Specify at least one source--a file or a resource collection.");
+ }
+ if (destFile != null && destDir != null) {
+ throw new BuildException(
+ "Only one of tofile and todir may be set.");
+ }
+ if (destFile == null && destDir == null) {
+ throw new BuildException("One of tofile or todir must be set.");
+ }
+ if (file != null && file.isDirectory()) {
+ throw new BuildException("Use a resource collection to copy directories.");
+ }
+ if (destFile != null && rcs.size() > 0) {
+ if (rcs.size() > 1) {
+ throw new BuildException(
+ "Cannot concatenate multiple files into a single file.");
+ } else {
+ final ResourceCollection rc = rcs.elementAt(0);
+ if (!rc.isFilesystemOnly() && !supportsNonFileResources()) {
+ throw new BuildException("Only FileSystem resources are"
+ + " supported.");
+ }
+ if (rc.size() == 0) {
+ throw new BuildException(MSG_WHEN_COPYING_EMPTY_RC_TO_FILE);
+ } else if (rc.size() == 1) {
+ final Resource res = rc.iterator().next();
+ final FileProvider r = res.as(FileProvider.class);
+ if (file == null) {
+ if (r != null) {
+ file = r.getFile();
+ } else {
+ singleResource = res;
+ }
+ rcs.removeElementAt(0);
+ } else {
+ throw new BuildException(
+ "Cannot concatenate multiple files into a single file.");
+ }
+ } else {
+ throw new BuildException(
+ "Cannot concatenate multiple files into a single file.");
+ }
+ }
+ }
+ if (destFile != null) {
+ destDir = destFile.getParentFile();
+ }
+ }
+
+ /**
+ * Compares source files to destination files to see if they should be
+ * copied.
+ *
+ * @param fromDir The source directory.
+ * @param toDir The destination directory.
+ * @param files A list of files to copy.
+ * @param dirs A list of directories to copy.
+ */
+ protected void scan(final File fromDir, final File toDir, final String[] files,
+ final String[] dirs) {
+ final FileNameMapper mapper = getMapper();
+ buildMap(fromDir, toDir, files, mapper, fileCopyMap);
+
+ if (includeEmpty) {
+ buildMap(fromDir, toDir, dirs, mapper, dirCopyMap);
+ }
+ }
+
+ /**
+ * Compares source resources to destination files to see if they
+ * should be copied.
+ *
+ * @param fromResources The source resources.
+ * @param toDir The destination directory.
+ *
+ * @return a Map with the out-of-date resources as keys and an
+ * array of target file names as values.
+ *
+ * @since Ant 1.7
+ */
+ protected Map<Resource, String[]> scan(final Resource[] fromResources, final File toDir) {
+ return buildMap(fromResources, toDir, getMapper());
+ }
+
+ /**
+ * Add to a map of files/directories to copy.
+ *
+ * @param fromDir the source directory.
+ * @param toDir the destination directory.
+ * @param names a list of filenames.
+ * @param mapper a <code>FileNameMapper</code> value.
+ * @param map a map of source file to array of destination files.
+ */
+ protected void buildMap(final File fromDir, final File toDir, final String[] names,
+ final FileNameMapper mapper, final Hashtable<String, String[]> map) {
+ String[] toCopy = null;
+ if (forceOverwrite) {
+ final Vector<String> v = new Vector<String>();
+ for (int i = 0; i < names.length; i++) {
+ if (mapper.mapFileName(names[i]) != null) {
+ v.addElement(names[i]);
+ }
+ }
+ toCopy = new String[v.size()];
+ v.copyInto(toCopy);
+ } else {
+ final SourceFileScanner ds = new SourceFileScanner(this);
+ toCopy = ds.restrict(names, fromDir, toDir, mapper, granularity);
+ }
+ for (int i = 0; i < toCopy.length; i++) {
+ final File src = new File(fromDir, toCopy[i]);
+ final String[] mappedFiles = mapper.mapFileName(toCopy[i]);
+
+ if (!enableMultipleMappings) {
+ map.put(src.getAbsolutePath(),
+ new String[] {new File(toDir, mappedFiles[0]).getAbsolutePath()});
+ } else {
+ // reuse the array created by the mapper
+ for (int k = 0; k < mappedFiles.length; k++) {
+ mappedFiles[k] = new File(toDir, mappedFiles[k]).getAbsolutePath();
+ }
+ map.put(src.getAbsolutePath(), mappedFiles);
+ }
+ }
+ }
+
+ /**
+ * Create a map of resources to copy.
+ *
+ * @param fromResources The source resources.
+ * @param toDir the destination directory.
+ * @param mapper a <code>FileNameMapper</code> value.
+ * @return a map of source resource to array of destination files.
+ * @since Ant 1.7
+ */
+ protected Map<Resource, String[]> buildMap(final Resource[] fromResources, final File toDir,
+ final FileNameMapper mapper) {
+ final HashMap<Resource, String[]> map = new HashMap<Resource, String[]>();
+ Resource[] toCopy = null;
+ if (forceOverwrite) {
+ final Vector<Resource> v = new Vector<Resource>();
+ for (int i = 0; i < fromResources.length; i++) {
+ if (mapper.mapFileName(fromResources[i].getName()) != null) {
+ v.addElement(fromResources[i]);
+ }
+ }
+ toCopy = new Resource[v.size()];
+ v.copyInto(toCopy);
+ } else {
+ toCopy = ResourceUtils.selectOutOfDateSources(this, fromResources,
+ mapper,
+ new ResourceFactory() {
+ public Resource getResource(final String name) {
+ return new FileResource(toDir, name);
+ }
+ },
+ granularity);
+ }
+ for (int i = 0; i < toCopy.length; i++) {
+ final String[] mappedFiles = mapper.mapFileName(toCopy[i].getName());
+ for (int j = 0; j < mappedFiles.length; j++) {
+ if (mappedFiles[j] == null) {
+ throw new BuildException("Can't copy a resource without a"
+ + " name if the mapper doesn't"
+ + " provide one.");
+ }
+ }
+
+ if (!enableMultipleMappings) {
+ map.put(toCopy[i],
+ new String[] {new File(toDir, mappedFiles[0]).getAbsolutePath()});
+ } else {
+ // reuse the array created by the mapper
+ for (int k = 0; k < mappedFiles.length; k++) {
+ mappedFiles[k] = new File(toDir, mappedFiles[k]).getAbsolutePath();
+ }
+ map.put(toCopy[i], mappedFiles);
+ }
+ }
+ return map;
+ }
+
+ /**
+ * Actually does the file (and possibly empty directory) copies.
+ * This is a good method for subclasses to override.
+ */
+ protected void doFileOperations() {
+ if (fileCopyMap.size() > 0) {
+ log("Copying " + fileCopyMap.size()
+ + " file" + (fileCopyMap.size() == 1 ? "" : "s")
+ + " to " + destDir.getAbsolutePath());
+
+ for (final Map.Entry<String, String[]> e : fileCopyMap.entrySet()) {
+ final String fromFile = e.getKey();
+ final String[] toFiles = e.getValue();
+
+ for (int i = 0; i < toFiles.length; i++) {
+ final String toFile = toFiles[i];
+
+ if (fromFile.equals(toFile)) {
+ log("Skipping self-copy of " + fromFile, verbosity);
+ continue;
+ }
+ try {
+ log("Copying " + fromFile + " to " + toFile, verbosity);
+
+ final FilterSetCollection executionFilters =
+ new FilterSetCollection();
+ if (filtering) {
+ executionFilters
+ .addFilterSet(getProject().getGlobalFilterSet());
+ }
+ for (final FilterSet filterSet : filterSets) {
+ executionFilters.addFilterSet(filterSet);
+ }
+ fileUtils.copyFile(new File(fromFile), new File(toFile),
+ executionFilters,
+ filterChains, forceOverwrite,
+ preserveLastModified,
+ /* append: */ false, inputEncoding,
+ outputEncoding, getProject(),
+ getForce());
+ } catch (final IOException ioe) {
+ String msg = "Failed to copy " + fromFile + " to " + toFile
+ + " due to " + getDueTo(ioe);
+ final File targetFile = new File(toFile);
+ if (!(ioe instanceof
+ ResourceUtils.ReadOnlyTargetFileException)
+ && targetFile.exists() && !targetFile.delete()) {
+ msg += " and I couldn't delete the corrupt " + toFile;
+ }
+ if (failonerror) {
+ throw new BuildException(msg, ioe, getLocation());
+ }
+ log(msg, Project.MSG_ERR);
+ }
+ }
+ }
+ }
+ if (includeEmpty) {
+ int createCount = 0;
+ for (final String[] dirs : dirCopyMap.values()) {
+ for (int i = 0; i < dirs.length; i++) {
+ final File d = new File(dirs[i]);
+ if (!d.exists()) {
+ if (!(d.mkdirs() || d.isDirectory())) {
+ log("Unable to create directory "
+ + d.getAbsolutePath(), Project.MSG_ERR);
+ } else {
+ createCount++;
+ }
+ }
+ }
+ }
+ if (createCount > 0) {
+ log("Copied " + dirCopyMap.size()
+ + " empty director"
+ + (dirCopyMap.size() == 1 ? "y" : "ies")
+ + " to " + createCount
+ + " empty director"
+ + (createCount == 1 ? "y" : "ies") + " under "
+ + destDir.getAbsolutePath());
+ }
+ }
+ }
+
+ /**
+ * Actually does the resource copies.
+ * This is a good method for subclasses to override.
+ * @param map a map of source resource to array of destination files.
+ * @since Ant 1.7
+ */
+ protected void doResourceOperations(final Map<Resource, String[]> map) {
+ if (map.size() > 0) {
+ log("Copying " + map.size()
+ + " resource" + (map.size() == 1 ? "" : "s")
+ + " to " + destDir.getAbsolutePath());
+
+ for (final Map.Entry<Resource, String[]> e : map.entrySet()) {
+ final Resource fromResource = e.getKey();
+ for (final String toFile : e.getValue()) {
+ try {
+ log("Copying " + fromResource + " to " + toFile,
+ verbosity);
+
+ final FilterSetCollection executionFilters = new FilterSetCollection();
+ if (filtering) {
+ executionFilters
+ .addFilterSet(getProject().getGlobalFilterSet());
+ }
+ for (final FilterSet filterSet : filterSets) {
+ executionFilters.addFilterSet(filterSet);
+ }
+ ResourceUtils.copyResource(fromResource,
+ new FileResource(destDir,
+ toFile),
+ executionFilters,
+ filterChains,
+ forceOverwrite,
+ preserveLastModified,
+ /* append: */ false,
+ inputEncoding,
+ outputEncoding,
+ getProject(),
+ getForce());
+ } catch (final IOException ioe) {
+ String msg = "Failed to copy " + fromResource
+ + " to " + toFile
+ + " due to " + getDueTo(ioe);
+ final File targetFile = new File(toFile);
+ if (!(ioe instanceof
+ ResourceUtils.ReadOnlyTargetFileException)
+ && targetFile.exists() && !targetFile.delete()) {
+ msg += " and I couldn't delete the corrupt " + toFile;
+ }
+ if (failonerror) {
+ throw new BuildException(msg, ioe, getLocation());
+ }
+ log(msg, Project.MSG_ERR);
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Whether this task can deal with non-file resources.
+ *
+ * <p>&lt;copy&gt; can while &lt;move&gt; can't since we don't
+ * know how to remove non-file resources.</p>
+ *
+ * <p>This implementation returns true only if this task is
+ * &lt;copy&gt;. Any subclass of this class that also wants to
+ * support non-file resources needs to override this method. We
+ * need to do so for backwards compatibility reasons since we
+ * can't expect subclasses to support resources.</p>
+ * @return true if this task supports non file resources.
+ * @since Ant 1.7
+ */
+ protected boolean supportsNonFileResources() {
+ return getClass().equals(Copy.class);
+ }
+
+ /**
+ * Adds the given strings to a list contained in the given map.
+ * The file is the key into the map.
+ */
+ private static void add(File baseDir, final String[] names, final Map<File, List<String>> m) {
+ if (names != null) {
+ baseDir = getKeyFile(baseDir);
+ List<String> l = m.get(baseDir);
+ if (l == null) {
+ l = new ArrayList<String>(names.length);
+ m.put(baseDir, l);
+ }
+ l.addAll(java.util.Arrays.asList(names));
+ }
+ }
+
+ /**
+ * Adds the given string to a list contained in the given map.
+ * The file is the key into the map.
+ */
+ private static void add(final File baseDir, final String name, final Map<File, List<String>> m) {
+ if (name != null) {
+ add(baseDir, new String[] {name}, m);
+ }
+ }
+
+ /**
+ * Either returns its argument or a plaeholder if the argument is null.
+ */
+ private static File getKeyFile(final File f) {
+ return f == null ? NULL_FILE_PLACEHOLDER : f;
+ }
+
+ /**
+ * returns the mapper to use based on nested elements or the
+ * flatten attribute.
+ */
+ private FileNameMapper getMapper() {
+ FileNameMapper mapper = null;
+ if (mapperElement != null) {
+ mapper = mapperElement.getImplementation();
+ } else if (flatten) {
+ mapper = new FlatFileNameMapper();
+ } else {
+ mapper = new IdentityMapper();
+ }
+ return mapper;
+ }
+
+ /**
+ * Handle getMessage() for exceptions.
+ * @param ex the exception to handle
+ * @return ex.getMessage() if ex.getMessage() is not null
+ * otherwise return ex.toString()
+ */
+ private String getMessage(final Exception ex) {
+ return ex.getMessage() == null ? ex.toString() : ex.getMessage();
+ }
+
+ /**
+ * Returns a reason for failure based on
+ * the exception thrown.
+ * If the exception is not IOException output the class name,
+ * output the message
+ * if the exception is MalformedInput add a little note.
+ */
+ private String getDueTo(final Exception ex) {
+ final boolean baseIOException = ex.getClass() == IOException.class;
+ final StringBuffer message = new StringBuffer();
+ if (!baseIOException || ex.getMessage() == null) {
+ message.append(ex.getClass().getName());
+ }
+ if (ex.getMessage() != null) {
+ if (!baseIOException) {
+ message.append(" ");
+ }
+ message.append(ex.getMessage());
+ }
+ if (ex.getClass().getName().indexOf("MalformedInput") != -1) {
+ message.append(LINE_SEPARATOR);
+ message.append(
+ "This is normally due to the input file containing invalid");
+ message.append(LINE_SEPARATOR);
+ message.append("bytes for the character encoding used : ");
+ message.append(
+ (inputEncoding == null
+ ? fileUtils.getDefaultEncoding() : inputEncoding));
+ message.append(LINE_SEPARATOR);
+ }
+ return message.toString();
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/CopyPath.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/CopyPath.java
new file mode 100644
index 00000000..53596fd9
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/CopyPath.java
@@ -0,0 +1,214 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.types.Reference;
+import org.apache.tools.ant.util.FileNameMapper;
+import org.apache.tools.ant.util.FileUtils;
+
+/**
+ * Copy the contents of a path to a destination, using the mapper of choice
+ *
+ * @since Ant 1.7.0
+ *
+ * @ant.task category="filesystem"
+ * @deprecated this task should have never been released and was
+ * obsoleted by ResourceCollection support in Copy available since Ant
+ * 1.7.0. Don't use it.
+ */
+
+public class CopyPath extends Task {
+
+ // Error messages
+ /** No destdir attribute */
+ public static final String ERROR_NO_DESTDIR = "No destDir specified";
+
+ /** No path */
+ public static final String ERROR_NO_PATH = "No path specified";
+
+ /** No mapper */
+ public static final String ERROR_NO_MAPPER = "No mapper specified";
+
+ // fileutils
+ private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+
+ // --- Fields --
+ private FileNameMapper mapper;
+
+ private Path path;
+
+ private File destDir;
+
+ // TODO not read, yet in a public setter
+ private long granularity = FILE_UTILS.getFileTimestampGranularity();
+
+ private boolean preserveLastModified = false;
+
+ /**
+ * The dest dir attribute.
+ * @param destDir the value of the destdir attribute.
+ */
+ public void setDestDir(File destDir) {
+ this.destDir = destDir;
+ }
+
+ /**
+ * add a mapper
+ *
+ * @param newmapper the mapper to add.
+ */
+ public void add(FileNameMapper newmapper) {
+ if (mapper != null) {
+ throw new BuildException("Only one mapper allowed");
+ }
+ mapper = newmapper;
+ }
+
+ /**
+ * Set the path to be used when running the Java class.
+ *
+ * @param s
+ * an Ant Path object containing the path.
+ */
+ public void setPath(Path s) {
+ createPath().append(s);
+ }
+
+ /**
+ * Set the path to use by reference.
+ *
+ * @param r
+ * a reference to an existing path.
+ */
+ public void setPathRef(Reference r) {
+ createPath().setRefid(r);
+ }
+
+ /**
+ * Create a path.
+ *
+ * @return a path to be configured.
+ */
+ public Path createPath() {
+ if (path == null) {
+ path = new Path(getProject());
+ }
+ return path;
+ }
+
+ /**
+ * Set the number of milliseconds leeway to give before deciding a
+ * target is out of date.
+ * TODO: This is not yet used.
+ * @param granularity the granularity used to decide if a target is out of
+ * date.
+ */
+ public void setGranularity(long granularity) {
+ this.granularity = granularity;
+ }
+
+ /**
+ * Give the copied files the same last modified time as the original files.
+ * @param preserveLastModified if true preserve the modified time;
+ * default is false.
+ */
+ public void setPreserveLastModified(boolean preserveLastModified) {
+ this.preserveLastModified = preserveLastModified;
+ }
+
+ /**
+ * Ensure we have a consistent and legal set of attributes, and set any
+ * internal flags necessary based on different combinations of attributes.
+ *
+ * @throws BuildException
+ * if an error occurs.
+ */
+ protected void validateAttributes() throws BuildException {
+ if (destDir == null) {
+ throw new BuildException(ERROR_NO_DESTDIR);
+ }
+ if (mapper == null) {
+ throw new BuildException(ERROR_NO_MAPPER);
+ }
+ if (path == null) {
+ throw new BuildException(ERROR_NO_PATH);
+ }
+ }
+
+ /**
+ * This is a very minimal derivative of the normal copy logic.
+ *
+ * @throws BuildException
+ * if something goes wrong with the build.
+ */
+ public void execute() throws BuildException {
+ log("This task should have never been released and was"
+ + " obsoleted by ResourceCollection support in <copy> available"
+ + " since Ant 1.7.0. Don't use it.",
+ Project.MSG_ERR);
+
+ validateAttributes();
+ String[] sourceFiles = path.list();
+ if (sourceFiles.length == 0) {
+ log("Path is empty", Project.MSG_VERBOSE);
+ return;
+ }
+
+ for (int sources = 0; sources < sourceFiles.length; sources++) {
+
+ String sourceFileName = sourceFiles[sources];
+ File sourceFile = new File(sourceFileName);
+ String[] toFiles = (String[]) mapper.mapFileName(sourceFileName);
+
+ for (int i = 0; i < toFiles.length; i++) {
+ String destFileName = toFiles[i];
+ File destFile = new File(destDir, destFileName);
+
+ if (sourceFile.equals(destFile)) {
+ log("Skipping self-copy of " + sourceFileName, Project.MSG_VERBOSE);
+ continue;
+ }
+ if (sourceFile.isDirectory()) {
+ log("Skipping directory " + sourceFileName);
+ continue;
+ }
+ try {
+ log("Copying " + sourceFile + " to " + destFile, Project.MSG_VERBOSE);
+
+ FILE_UTILS.copyFile(sourceFile, destFile, null, null, false,
+ preserveLastModified, null, null, getProject());
+ } catch (IOException ioe) {
+ String msg = "Failed to copy " + sourceFile + " to " + destFile + " due to "
+ + ioe.getMessage();
+ if (destFile.exists() && !destFile.delete()) {
+ msg += " and I couldn't delete the corrupt " + destFile;
+ }
+ throw new BuildException(msg, ioe, getLocation());
+ }
+ }
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Copydir.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Copydir.java
new file mode 100644
index 00000000..8b4efc3b
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Copydir.java
@@ -0,0 +1,163 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Hashtable;
+import java.util.Map;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.DirectoryScanner;
+import org.apache.tools.ant.Project;
+
+/**
+ * Copies a directory.
+ *
+ * @since Ant 1.1
+ *
+ * @deprecated The copydir task is deprecated since Ant 1.2. Use copy instead.
+ */
+
+public class Copydir extends MatchingTask {
+
+ private File srcDir;
+ private File destDir;
+ private boolean filtering = false;
+ private boolean flatten = false;
+ private boolean forceOverwrite = false;
+ private Hashtable<String, String> filecopyList = new Hashtable<String, String>();
+
+ /**
+ * The src attribute
+ *
+ * @param src the source file
+ */
+ public void setSrc(File src) {
+ srcDir = src;
+ }
+
+ /**
+ * The dest attribute
+ *
+ * @param dest the destination file
+ */
+ public void setDest(File dest) {
+ destDir = dest;
+ }
+
+ /**
+ * The filtering attribute.
+ * Default is false.
+ * @param filter if true use filtering
+ */
+ public void setFiltering(boolean filter) {
+ filtering = filter;
+ }
+
+ /**
+ * The flattening attribute.
+ * Default is false.
+ * @param flatten if true use flattening
+ */
+ public void setFlatten(boolean flatten) {
+ this.flatten = flatten;
+ }
+
+ /**
+ * The forceoverwrite attribute.
+ * Default is false.
+ * @param force if true overwrite even if the destination file
+ * is newer that the source file
+ */
+ public void setForceoverwrite(boolean force) {
+ forceOverwrite = force;
+ }
+
+ /**
+ * Execute the task.
+ * @throws BuildException on error
+ */
+ public void execute() throws BuildException {
+ log("DEPRECATED - The copydir task is deprecated. Use copy instead.");
+
+ if (srcDir == null) {
+ throw new BuildException("src attribute must be set!",
+ getLocation());
+ }
+
+ if (!srcDir.exists()) {
+ throw new BuildException("srcdir " + srcDir.toString()
+ + " does not exist!", getLocation());
+ }
+
+ if (destDir == null) {
+ throw new BuildException("The dest attribute must be set.",
+ getLocation());
+ }
+
+ if (srcDir.equals(destDir)) {
+ log("Warning: src == dest", Project.MSG_WARN);
+ }
+
+ DirectoryScanner ds = super.getDirectoryScanner(srcDir);
+
+ try {
+ String[] files = ds.getIncludedFiles();
+ scanDir(srcDir, destDir, files);
+ if (filecopyList.size() > 0) {
+ log("Copying " + filecopyList.size() + " file"
+ + (filecopyList.size() == 1 ? "" : "s")
+ + " to " + destDir.getAbsolutePath());
+ for (Map.Entry<String, String> e : filecopyList.entrySet()) {
+ String fromFile = e.getKey();
+ String toFile = e.getValue();
+ try {
+ getProject().copyFile(fromFile, toFile, filtering,
+ forceOverwrite);
+ } catch (IOException ioe) {
+ String msg = "Failed to copy " + fromFile + " to "
+ + toFile + " due to " + ioe.getMessage();
+ throw new BuildException(msg, ioe, getLocation());
+ }
+ }
+ }
+ } finally {
+ filecopyList.clear();
+ }
+ }
+
+ private void scanDir(File from, File to, String[] files) {
+ for (int i = 0; i < files.length; i++) {
+ String filename = files[i];
+ File srcFile = new File(from, filename);
+ File destFile;
+ if (flatten) {
+ destFile = new File(to, new File(filename).getName());
+ } else {
+ destFile = new File(to, filename);
+ }
+ if (forceOverwrite
+ || (srcFile.lastModified() > destFile.lastModified())) {
+ filecopyList.put(srcFile.getAbsolutePath(),
+ destFile.getAbsolutePath());
+ }
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Copyfile.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Copyfile.java
new file mode 100644
index 00000000..e9acb1d6
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Copyfile.java
@@ -0,0 +1,116 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+
+/**
+ * Copies a file.
+ *
+ * @since Ant 1.1
+ *
+ * @deprecated The copyfile task is deprecated since Ant 1.2. Use
+ * copy instead.
+ */
+
+public class Copyfile extends Task {
+
+ private File srcFile;
+ private File destFile;
+ private boolean filtering = false;
+ private boolean forceOverwrite = false;
+
+ /**
+ * Set the source file.
+ * @param src the source file.
+ */
+ public void setSrc(File src) {
+ srcFile = src;
+ }
+
+ /**
+ * The forceoverwrite attribute.
+ * Default is false.
+ * @param force if true overwrite even if the destination file
+ * is newer that the source file
+ */
+ public void setForceoverwrite(boolean force) {
+ forceOverwrite = force;
+ }
+
+ /**
+ * Set the destination file.
+ * @param dest the destination file.
+ */
+ public void setDest(File dest) {
+ destFile = dest;
+ }
+
+ /**
+ * The filtering attribute.
+ * Default is false.
+ * @param filter if true use filtering
+ */
+ public void setFiltering(String filter) {
+ filtering = Project.toBoolean(filter);
+ }
+
+ /**
+ * Execute the task.
+ * @throws BuildException on error
+ */
+ public void execute() throws BuildException {
+ log("DEPRECATED - The copyfile task is deprecated. Use copy instead.");
+
+ if (srcFile == null) {
+ throw new BuildException("The src attribute must be present.",
+ getLocation());
+ }
+
+ if (!srcFile.exists()) {
+ throw new BuildException("src " + srcFile.toString()
+ + " does not exist.", getLocation());
+ }
+
+ if (destFile == null) {
+ throw new BuildException("The dest attribute must be present.",
+ getLocation());
+ }
+
+ if (srcFile.equals(destFile)) {
+ log("Warning: src == dest", Project.MSG_WARN);
+ }
+
+ if (forceOverwrite
+ || srcFile.lastModified() > destFile.lastModified()) {
+ try {
+ getProject().copyFile(srcFile, destFile, filtering, forceOverwrite);
+ } catch (IOException ioe) {
+ String msg = "Error copying file: " + srcFile.getAbsolutePath()
+ + " due to " + ioe.getMessage();
+ throw new BuildException(msg);
+ }
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Cvs.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Cvs.java
new file mode 100644
index 00000000..822a4ea9
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Cvs.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+/**
+ * Performs operations on a CVS repository.
+ *
+ * original 1.20
+ *
+ * NOTE: This implementation has been moved to AbstractCvsTask with
+ * the addition of some accessors for extensibility.
+ *
+ *
+ * @since Ant 1.1
+ *
+ * @ant.task category="scm"
+ */
+public class Cvs extends AbstractCvsTask {
+
+ /**
+ * CVS Task - now implemented by the Abstract CVS Task base class
+ */
+ public Cvs() {
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/DefBase.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/DefBase.java
new file mode 100644
index 00000000..b52bbb72
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/DefBase.java
@@ -0,0 +1,167 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.AntClassLoader;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.types.Reference;
+import org.apache.tools.ant.util.ClasspathUtils;
+
+/**
+ * Base class for Definitions handling uri and class loading.
+ * (This was part of Definer)
+ *
+ * @since Ant 1.6
+ */
+public abstract class DefBase extends AntlibDefinition {
+ private ClassLoader createdLoader;
+ private ClasspathUtils.Delegate cpDelegate;
+
+ /**
+ * Check if classpath attributes have been set.
+ * (to be called before getCpDelegate() is used.
+ * @return true if cpDelegate has been created.
+ */
+ protected boolean hasCpDelegate() {
+ return cpDelegate != null;
+ }
+
+ /**
+ * @param reverseLoader if true a delegated loader will take precedence over
+ * the parent
+ * @deprecated since 1.6.x.
+ * stop using this attribute
+ * @ant.attribute ignore="true"
+ */
+ public void setReverseLoader(boolean reverseLoader) {
+ getDelegate().setReverseLoader(reverseLoader);
+ log("The reverseloader attribute is DEPRECATED. It will be removed",
+ Project.MSG_WARN);
+ }
+
+ /**
+ * @return the classpath for this definition
+ */
+ public Path getClasspath() {
+ return getDelegate().getClasspath();
+ }
+
+ /**
+ * @return the reverse loader attribute of the classpath delegate.
+ */
+ public boolean isReverseLoader() {
+ return getDelegate().isReverseLoader();
+ }
+
+ /**
+ * Returns the loader id of the class path Delegate.
+ * @return the loader id
+ */
+ public String getLoaderId() {
+ return getDelegate().getClassLoadId();
+ }
+
+ /**
+ * Returns the class path id of the class path delegate.
+ * @return the class path id
+ */
+ public String getClasspathId() {
+ return getDelegate().getClassLoadId();
+ }
+
+ /**
+ * Set the classpath to be used when searching for component being defined.
+ *
+ * @param classpath an Ant Path object containing the classpath.
+ */
+ public void setClasspath(Path classpath) {
+ getDelegate().setClasspath(classpath);
+ }
+
+ /**
+ * Create the classpath to be used when searching for component being
+ * defined.
+ * @return the classpath of the this definition
+ */
+ public Path createClasspath() {
+ return getDelegate().createClasspath();
+ }
+
+ /**
+ * Set a reference to a classpath to use when loading the files.
+ * To actually share the same loader, set loaderref as well
+ * @param r the reference to the classpath
+ */
+ public void setClasspathRef(Reference r) {
+ getDelegate().setClasspathref(r);
+ }
+
+ /**
+ * Use the reference to locate the loader. If the loader is not
+ * found, the specified classpath will be used and registered
+ * with the specified name.
+ *
+ * This allows multiple taskdef/typedef to use the same class loader,
+ * so they can be used together, eliminating the need to
+ * put them in the CLASSPATH.
+ *
+ * @param r the reference to locate the loader.
+ * @since Ant 1.5
+ */
+ public void setLoaderRef(Reference r) {
+ getDelegate().setLoaderRef(r);
+ }
+
+ /**
+ * create a classloader for this definition
+ * @return the classloader from the cpDelegate
+ */
+ protected ClassLoader createLoader() {
+ if (getAntlibClassLoader() != null && cpDelegate == null) {
+ return getAntlibClassLoader();
+ }
+ if (createdLoader == null) {
+ createdLoader = getDelegate().getClassLoader();
+ // need to load Task via system classloader or the new
+ // task we want to define will never be a Task but always
+ // be wrapped into a TaskAdapter.
+ ((AntClassLoader) createdLoader)
+ .addSystemPackageRoot("org.apache.tools.ant");
+ }
+ return createdLoader;
+ }
+
+ /**
+ * @see org.apache.tools.ant.Task#init()
+ * @throws BuildException on error.
+ * @since Ant 1.6
+ */
+ public void init() throws BuildException {
+ super.init();
+ }
+
+ private ClasspathUtils.Delegate getDelegate() {
+ if (cpDelegate == null) {
+ cpDelegate = ClasspathUtils.getDelegate(this);
+ }
+ return cpDelegate;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/DefaultExcludes.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/DefaultExcludes.java
new file mode 100644
index 00000000..6b912e2f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/DefaultExcludes.java
@@ -0,0 +1,115 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.DirectoryScanner;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.util.StringUtils;
+
+/**
+ * Alters the default excludes for the <strong>entire</strong> build..
+ *
+ * @since Ant 1.6
+ *
+ * @ant.task category="utility"
+ */
+public class DefaultExcludes extends Task {
+ private String add = "";
+ private String remove = "";
+ private boolean defaultrequested = false;
+ private boolean echo = false;
+
+ // by default, messages are always displayed
+ private int logLevel = Project.MSG_WARN;
+
+ /**
+ * Does the work.
+ *
+ * @exception BuildException if something goes wrong with the build
+ */
+ public void execute() throws BuildException {
+ if (!defaultrequested && add.equals("") && remove.equals("") && !echo) {
+ throw new BuildException("<defaultexcludes> task must set "
+ + "at least one attribute (echo=\"false\""
+ + " doesn't count since that is the default");
+ }
+ if (defaultrequested) {
+ DirectoryScanner.resetDefaultExcludes();
+ }
+ if (!add.equals("")) {
+ DirectoryScanner.addDefaultExclude(add);
+ }
+ if (!remove.equals("")) {
+ DirectoryScanner.removeDefaultExclude(remove);
+ }
+ if (echo) {
+ StringBuffer message
+ = new StringBuffer("Current Default Excludes:");
+ message.append(StringUtils.LINE_SEP);
+ String[] excludes = DirectoryScanner.getDefaultExcludes();
+ for (int i = 0; i < excludes.length; i++) {
+ message.append(" ");
+ message.append(excludes[i]);
+ message.append(StringUtils.LINE_SEP);
+ }
+ log(message.toString(), logLevel);
+ }
+ }
+
+ /**
+ * go back to standard default patterns
+ *
+ * @param def if true go back to default patterns
+ */
+ public void setDefault(boolean def) {
+ defaultrequested = def;
+ }
+ /**
+ * Pattern to add to the default excludes
+ *
+ * @param add Sets the value for the pattern to exclude.
+ */
+ public void setAdd(String add) {
+ this.add = add;
+ }
+
+ /**
+ * Pattern to remove from the default excludes.
+ *
+ * @param remove Sets the value for the pattern that
+ * should no longer be excluded.
+ */
+ public void setRemove(String remove) {
+ this.remove = remove;
+ }
+
+ /**
+ * If true, echo the default excludes.
+ *
+ * @param echo whether or not to echo the contents of
+ * the default excludes.
+ */
+ public void setEcho(boolean echo) {
+ this.echo = echo;
+ }
+
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Definer.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Definer.java
new file mode 100644
index 00000000..8196fa51
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Definer.java
@@ -0,0 +1,639 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.tools.ant.AntTypeDefinition;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.ComponentHelper;
+import org.apache.tools.ant.Location;
+import org.apache.tools.ant.MagicNames;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.ProjectHelper;
+import org.apache.tools.ant.types.EnumeratedAttribute;
+import org.apache.tools.ant.util.FileUtils;
+
+/**
+ * Base class for Taskdef and Typedef - handles all
+ * the attributes for Typedef. The uri and class
+ * handling is handled by DefBase
+ *
+ * @since Ant 1.4
+ */
+public abstract class Definer extends DefBase {
+
+ /**
+ * the extension of an antlib file for autoloading.
+ * {@value[
+ */
+ private static final String ANTLIB_XML = "/antlib.xml";
+
+ private static final ThreadLocal<Map<URL, Location>> RESOURCE_STACK = new ThreadLocal<Map<URL, Location>>() {
+ protected Map<URL, Location> initialValue() {
+ return new HashMap<URL, Location>();
+ }
+ };
+
+ private String name;
+ private String classname;
+ private File file;
+ private String resource;
+ private boolean restrict = false;
+
+ private int format = Format.PROPERTIES;
+ private boolean definerSet = false;
+ private int onError = OnError.FAIL;
+ private String adapter;
+ private String adaptTo;
+
+ private Class<?> adapterClass;
+ private Class<?> adaptToClass;
+
+ /**
+ * Enumerated type for onError attribute
+ *
+ * @see EnumeratedAttribute
+ */
+ public static class OnError extends EnumeratedAttribute {
+ /** Enumerated values */
+ public static final int FAIL = 0, REPORT = 1, IGNORE = 2, FAIL_ALL = 3;
+
+ /**
+ * text value of onerror option {@value}
+ */
+ public static final String POLICY_FAIL = "fail";
+ /**
+ * text value of onerror option {@value}
+ */
+ public static final String POLICY_REPORT = "report";
+ /**
+ * text value of onerror option {@value}
+ */
+ public static final String POLICY_IGNORE = "ignore";
+ /**
+ * text value of onerror option {@value}
+ */
+ public static final String POLICY_FAILALL = "failall";
+
+ /**
+ * Constructor
+ */
+ public OnError() {
+ super();
+ }
+
+ /**
+ * Constructor using a string.
+ * @param value the value of the attribute
+ */
+ public OnError(String value) {
+ setValue(value);
+ }
+
+ /**
+ * get the values
+ * @return an array of the allowed values for this attribute.
+ */
+ public String[] getValues() {
+ return new String[] {POLICY_FAIL, POLICY_REPORT, POLICY_IGNORE, POLICY_FAILALL};
+ }
+ }
+
+ /**
+ * Enumerated type for format attribute
+ *
+ * @see EnumeratedAttribute
+ */
+ public static class Format extends EnumeratedAttribute {
+ /** Enumerated values */
+ public static final int PROPERTIES = 0, XML = 1;
+
+ /**
+ * get the values
+ * @return an array of the allowed values for this attribute.
+ */
+ public String[] getValues() {
+ return new String[] {"properties", "xml"};
+ }
+ }
+
+ /**
+ * The restrict attribute.
+ * If this is true, only use this definition in add(X).
+ * @param restrict the value to set.
+ */
+ protected void setRestrict(boolean restrict) {
+ this.restrict = restrict;
+ }
+
+
+ /**
+ * What to do if there is an error in loading the class.
+ * <ul>
+ * <li>error - throw build exception</li>
+ * <li>report - output at warning level</li>
+ * <li>ignore - output at debug level</li>
+ * </ul>
+ *
+ * @param onError an <code>OnError</code> value
+ */
+ public void setOnError(OnError onError) {
+ this.onError = onError.getIndex();
+ }
+
+ /**
+ * Sets the format of the file or resource
+ * @param format the enumerated value - xml or properties
+ */
+ public void setFormat(Format format) {
+ this.format = format.getIndex();
+ }
+
+ /**
+ * @return the name for this definition
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * @return the file containing definitions
+ */
+ public File getFile() {
+ return file;
+ }
+
+ /**
+ * @return the resource containing definitions
+ */
+ public String getResource() {
+ return resource;
+ }
+
+
+ /**
+ * Run the definition.
+ *
+ * @exception BuildException if an error occurs
+ */
+ public void execute() throws BuildException {
+ ClassLoader al = createLoader();
+
+ if (!definerSet) {
+ //we arent fully defined yet. this is an error unless
+ //we are in an antlib, in which case the resource name is determined
+ //automatically.
+ //NB: URIs in the ant core package will be "" at this point.
+ if (getURI() == null) {
+ throw new BuildException(
+ "name, file or resource attribute of "
+ + getTaskName() + " is undefined",
+ getLocation());
+ }
+
+ if (getURI().startsWith(MagicNames.ANTLIB_PREFIX)) {
+ //convert the URI to a resource
+ String uri1 = getURI();
+ setResource(makeResourceFromURI(uri1));
+ } else {
+ throw new BuildException(
+ "Only antlib URIs can be located from the URI alone,"
+ + " not the URI '" + getURI() + "'");
+ }
+ }
+
+ if (name != null) {
+ if (classname == null) {
+ throw new BuildException(
+ "classname attribute of " + getTaskName() + " element "
+ + "is undefined", getLocation());
+ }
+ addDefinition(al, name, classname);
+ } else {
+ if (classname != null) {
+ String msg = "You must not specify classname "
+ + "together with file or resource.";
+ throw new BuildException(msg, getLocation());
+ }
+ final Enumeration<URL> urls;
+ if (file == null) {
+ urls = resourceToURLs(al);
+ } else {
+ final URL url = fileToURL();
+ if (url == null) {
+ return;
+ }
+ urls = Collections.enumeration(Collections.singleton(url));
+ }
+
+ while (urls.hasMoreElements()) {
+ URL url = urls.nextElement();
+
+ int fmt = this.format;
+ if (url.toString().toLowerCase(Locale.ENGLISH).endsWith(".xml")) {
+ fmt = Format.XML;
+ }
+
+ if (fmt == Format.PROPERTIES) {
+ loadProperties(al, url);
+ break;
+ } else {
+ if (RESOURCE_STACK.get().get(url) != null) {
+ log("Warning: Recursive loading of " + url
+ + " ignored"
+ + " at " + getLocation()
+ + " originally loaded at "
+ + RESOURCE_STACK.get().get(url),
+ Project.MSG_WARN);
+ } else {
+ try {
+ RESOURCE_STACK.get().put(url, getLocation());
+ loadAntlib(al, url);
+ } finally {
+ RESOURCE_STACK.get().remove(url);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * This is where the logic to map from a URI to an antlib resource
+ * is kept.
+ * @param uri the xml namespace uri that to convert.
+ * @return the name of a resource. It may not exist
+ */
+
+ public static String makeResourceFromURI(String uri) {
+ String path = uri.substring(MagicNames.ANTLIB_PREFIX.length());
+ String resource;
+ if (path.startsWith("//")) {
+ //handle new style full paths to an antlib, in which
+ //all but the forward slashes are allowed.
+ resource = path.substring("//".length());
+ if (!resource.endsWith(".xml")) {
+ //if we haven't already named an XML file, it gets antlib.xml
+ resource = resource + ANTLIB_XML;
+ }
+ } else {
+ //convert from a package to a path
+ resource = path.replace('.', '/') + ANTLIB_XML;
+ }
+ return resource;
+ }
+
+ /**
+ * Convert a file to a file: URL.
+ *
+ * @return the URL, or null if it isn't valid and the active error policy
+ * is not to raise a fault
+ * @throws BuildException if the file is missing/not a file and the
+ * policy requires failure at this point.
+ */
+ private URL fileToURL() {
+ String message = null;
+ if (!(file.exists())) {
+ message = "File " + file + " does not exist";
+ }
+ if (message == null && !(file.isFile())) {
+ message = "File " + file + " is not a file";
+ }
+ if (message == null) {
+ try {
+ return FileUtils.getFileUtils().getFileURL(file);
+ } catch (Exception ex) {
+ message =
+ "File " + file + " cannot use as URL: "
+ + ex.toString();
+ }
+ }
+ // Here if there is an error
+ switch (onError) {
+ case OnError.FAIL_ALL:
+ throw new BuildException(message);
+ case OnError.FAIL:
+ // Fall Through
+ case OnError.REPORT:
+ log(message, Project.MSG_WARN);
+ break;
+ case OnError.IGNORE:
+ // log at a lower level
+ log(message, Project.MSG_VERBOSE);
+ break;
+ default:
+ // Ignore the problem
+ break;
+ }
+ return null;
+ }
+
+ private Enumeration<URL> resourceToURLs(ClassLoader classLoader) {
+ Enumeration<URL> ret;
+ try {
+ ret = classLoader.getResources(resource);
+ } catch (IOException e) {
+ throw new BuildException(
+ "Could not fetch resources named " + resource,
+ e, getLocation());
+ }
+ if (!ret.hasMoreElements()) {
+ String message = "Could not load definitions from resource "
+ + resource + ". It could not be found.";
+ switch (onError) {
+ case OnError.FAIL_ALL:
+ throw new BuildException(message);
+ case OnError.FAIL:
+ case OnError.REPORT:
+ log(message, Project.MSG_WARN);
+ break;
+ case OnError.IGNORE:
+ log(message, Project.MSG_VERBOSE);
+ break;
+ default:
+ // Ignore the problem
+ break;
+ }
+ }
+ return ret;
+ }
+
+ /**
+ * Load type definitions as properties from a URL.
+ *
+ * @param al the classloader to use
+ * @param url the url to get the definitions from
+ */
+ protected void loadProperties(ClassLoader al, URL url) {
+ InputStream is = null;
+ try {
+ is = url.openStream();
+ if (is == null) {
+ log("Could not load definitions from " + url,
+ Project.MSG_WARN);
+ return;
+ }
+ Properties props = new Properties();
+ props.load(is);
+ Enumeration<?> keys = props.keys();
+ while (keys.hasMoreElements()) {
+ name = ((String) keys.nextElement());
+ classname = props.getProperty(name);
+ addDefinition(al, name, classname);
+ }
+ } catch (IOException ex) {
+ throw new BuildException(ex, getLocation());
+ } finally {
+ FileUtils.close(is);
+ }
+ }
+
+ /**
+ * Load an antlib from a URL.
+ *
+ * @param classLoader the classloader to use.
+ * @param url the url to load the definitions from.
+ */
+ private void loadAntlib(ClassLoader classLoader, URL url) {
+ try {
+ Antlib antlib = Antlib.createAntlib(getProject(), url, getURI());
+ antlib.setClassLoader(classLoader);
+ antlib.setURI(getURI());
+ antlib.execute();
+ } catch (BuildException ex) {
+ throw ProjectHelper.addLocationToBuildException(
+ ex, getLocation());
+ }
+ }
+
+ /**
+ * Name of the property file to load
+ * ant name/classname pairs from.
+ * @param file the file
+ */
+ public void setFile(File file) {
+ if (definerSet) {
+ tooManyDefinitions();
+ }
+ definerSet = true;
+ this.file = file;
+ }
+
+ /**
+ * Name of the property resource to load
+ * ant name/classname pairs from.
+ * @param res the resource to use
+ */
+ public void setResource(String res) {
+ if (definerSet) {
+ tooManyDefinitions();
+ }
+ definerSet = true;
+ this.resource = res;
+ }
+
+ /**
+ * Antlib attribute, sets resource and uri.
+ * uri is set the antlib value and, resource is set
+ * to the antlib.xml resource in the classpath.
+ * For example antlib="antlib:org.acme.bland.cola"
+ * corresponds to uri="antlib:org.acme.bland.cola"
+ * resource="org/acme/bland/cola/antlib.xml".
+ * ASF Bugzilla Bug 31999
+ * @param antlib the value to set.
+ */
+ public void setAntlib(String antlib) {
+ if (definerSet) {
+ tooManyDefinitions();
+ }
+ if (!antlib.startsWith("antlib:")) {
+ throw new BuildException(
+ "Invalid antlib attribute - it must start with antlib:");
+ }
+ setURI(antlib);
+ this.resource = antlib.substring("antlib:".length()).replace('.', '/')
+ + "/antlib.xml";
+ definerSet = true;
+ }
+
+ /**
+ * Name of the definition
+ * @param name the name of the definition
+ */
+ public void setName(String name) {
+ if (definerSet) {
+ tooManyDefinitions();
+ }
+ definerSet = true;
+ this.name = name;
+ }
+
+ /**
+ * Returns the classname of the object we are defining.
+ * May be <code>null</code>.
+ * @return the class name
+ */
+ public String getClassname() {
+ return classname;
+ }
+
+ /**
+ * The full class name of the object being defined.
+ * Required, unless file or resource have
+ * been specified.
+ * @param classname the name of the class
+ */
+ public void setClassname(String classname) {
+ this.classname = classname;
+ }
+
+ /**
+ * Set the class name of the adapter class.
+ * An adapter class is used to proxy the
+ * definition class. It is used if the
+ * definition class is not assignable to
+ * the adaptto class, or if the adaptto
+ * class is not present.
+ *
+ * @param adapter the name of the adapter class
+ */
+
+ public void setAdapter(String adapter) {
+ this.adapter = adapter;
+ }
+
+ /**
+ * Set the adapter class.
+ *
+ * @param adapterClass the class to use to adapt the definition class
+ */
+ protected void setAdapterClass(Class<?> adapterClass) {
+ this.adapterClass = adapterClass;
+ }
+
+ /**
+ * Set the classname of the class that the definition
+ * must be compatible with, either directly or
+ * by use of the adapter class.
+ *
+ * @param adaptTo the name of the adaptto class
+ */
+ public void setAdaptTo(String adaptTo) {
+ this.adaptTo = adaptTo;
+ }
+
+ /**
+ * Set the class for adaptToClass, to be
+ * used by derived classes, used instead of
+ * the adaptTo attribute.
+ *
+ * @param adaptToClass the class for adaptor.
+ */
+ protected void setAdaptToClass(Class<?> adaptToClass) {
+ this.adaptToClass = adaptToClass;
+ }
+
+
+ /**
+ * Add a definition using the attributes of Definer
+ *
+ * @param al the ClassLoader to use
+ * @param name the name of the definition
+ * @param classname the classname of the definition
+ * @exception BuildException if an error occurs
+ */
+ protected void addDefinition(ClassLoader al, String name, String classname)
+ throws BuildException {
+ Class<?> cl = null;
+ try {
+ try {
+ name = ProjectHelper.genComponentName(getURI(), name);
+
+ if (onError != OnError.IGNORE) {
+ cl = Class.forName(classname, true, al);
+ }
+
+ if (adapter != null) {
+ adapterClass = Class.forName(adapter, true, al);
+ }
+
+ if (adaptTo != null) {
+ adaptToClass = Class.forName(adaptTo, true, al);
+ }
+
+ AntTypeDefinition def = new AntTypeDefinition();
+ def.setName(name);
+ def.setClassName(classname);
+ def.setClass(cl);
+ def.setAdapterClass(adapterClass);
+ def.setAdaptToClass(adaptToClass);
+ def.setRestrict(restrict);
+ def.setClassLoader(al);
+ if (cl != null) {
+ def.checkClass(getProject());
+ }
+ ComponentHelper.getComponentHelper(getProject())
+ .addDataTypeDefinition(def);
+ } catch (ClassNotFoundException cnfe) {
+ String msg = getTaskName() + " class " + classname
+ + " cannot be found"
+ + "\n using the classloader " + al;
+ throw new BuildException(msg, cnfe, getLocation());
+ } catch (NoClassDefFoundError ncdfe) {
+ String msg = getTaskName() + " A class needed by class "
+ + classname + " cannot be found: " + ncdfe.getMessage()
+ + "\n using the classloader " + al;
+ throw new BuildException(msg, ncdfe, getLocation());
+ }
+ } catch (BuildException ex) {
+ switch (onError) {
+ case OnError.FAIL_ALL:
+ case OnError.FAIL:
+ throw ex;
+ case OnError.REPORT:
+ log(ex.getLocation() + "Warning: " + ex.getMessage(),
+ Project.MSG_WARN);
+ break;
+ default:
+ log(ex.getLocation() + ex.getMessage(),
+ Project.MSG_DEBUG);
+ }
+ }
+ }
+
+ /**
+ * handle too many definitions by raising an exception.
+ * @throws BuildException always.
+ */
+ private void tooManyDefinitions() {
+ throw new BuildException(
+ "Only one of the attributes name, file and resource"
+ + " can be set", getLocation());
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Delete.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Delete.java
new file mode 100644
index 00000000..6c34ccf2
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Delete.java
@@ -0,0 +1,836 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.io.File;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.DirectoryScanner;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.condition.Os;
+import org.apache.tools.ant.types.FileSet;
+import org.apache.tools.ant.types.PatternSet;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.ResourceCollection;
+import org.apache.tools.ant.types.resources.FileProvider;
+import org.apache.tools.ant.types.resources.FileResourceIterator;
+import org.apache.tools.ant.types.resources.Resources;
+import org.apache.tools.ant.types.resources.Restrict;
+import org.apache.tools.ant.types.resources.Sort;
+import org.apache.tools.ant.types.resources.comparators.FileSystem;
+import org.apache.tools.ant.types.resources.comparators.ResourceComparator;
+import org.apache.tools.ant.types.resources.comparators.Reverse;
+import org.apache.tools.ant.types.resources.selectors.Exists;
+import org.apache.tools.ant.types.resources.selectors.ResourceSelector;
+import org.apache.tools.ant.types.selectors.AndSelector;
+import org.apache.tools.ant.types.selectors.ContainsRegexpSelector;
+import org.apache.tools.ant.types.selectors.ContainsSelector;
+import org.apache.tools.ant.types.selectors.DateSelector;
+import org.apache.tools.ant.types.selectors.DependSelector;
+import org.apache.tools.ant.types.selectors.DepthSelector;
+import org.apache.tools.ant.types.selectors.ExtendSelector;
+import org.apache.tools.ant.types.selectors.FileSelector;
+import org.apache.tools.ant.types.selectors.FilenameSelector;
+import org.apache.tools.ant.types.selectors.MajoritySelector;
+import org.apache.tools.ant.types.selectors.NoneSelector;
+import org.apache.tools.ant.types.selectors.NotSelector;
+import org.apache.tools.ant.types.selectors.OrSelector;
+import org.apache.tools.ant.types.selectors.PresentSelector;
+import org.apache.tools.ant.types.selectors.SelectSelector;
+import org.apache.tools.ant.types.selectors.SizeSelector;
+import org.apache.tools.ant.types.selectors.modifiedselector.ModifiedSelector;
+import org.apache.tools.ant.util.FileUtils;
+import org.apache.tools.ant.util.SymbolicLinkUtils;
+
+/**
+ * Deletes a file or directory, or set of files defined by a fileset.
+ * The original delete task would delete a file, or a set of files
+ * using the include/exclude syntax. The deltree task would delete a
+ * directory tree. This task combines the functionality of these two
+ * originally distinct tasks.
+ * <p>Currently Delete extends MatchingTask. This is intended <i>only</i>
+ * to provide backwards compatibility for a release. The future position
+ * is to use nested filesets exclusively.</p>
+ *
+ * @since Ant 1.2
+ *
+ * @ant.task category="filesystem"
+ */
+public class Delete extends MatchingTask {
+ private static final ResourceComparator REVERSE_FILESYSTEM = new Reverse(new FileSystem());
+ private static final ResourceSelector EXISTS = new Exists();
+
+ private static class ReverseDirs implements ResourceCollection {
+ static final Comparator<Comparable<?>> REVERSE = new Comparator<Comparable<?>>() {
+ public int compare(Comparable<?> foo, Comparable<?> bar) {
+ return ((Comparable) foo).compareTo(bar) * -1;
+ }
+ };
+ private Project project;
+ private File basedir;
+ private String[] dirs;
+ ReverseDirs(Project project, File basedir, String[] dirs) {
+ this.project = project;
+ this.basedir = basedir;
+ this.dirs = dirs;
+ Arrays.sort(this.dirs, REVERSE);
+ }
+ public Iterator<Resource> iterator() {
+ return new FileResourceIterator(project, basedir, dirs);
+ }
+ public boolean isFilesystemOnly() { return true; }
+ public int size() { return dirs.length; }
+ }
+
+ // CheckStyle:VisibilityModifier OFF - bc
+ protected File file = null;
+ protected File dir = null;
+ protected Vector<FileSet> filesets = new Vector<FileSet>();
+ protected boolean usedMatchingTask = false;
+ // by default, remove matching empty dirs
+ protected boolean includeEmpty = false;
+ // CheckStyle:VisibilityModifier ON
+
+ private int verbosity = Project.MSG_VERBOSE;
+ private boolean quiet = false;
+ private boolean failonerror = true;
+ private boolean deleteOnExit = false;
+ private boolean removeNotFollowedSymlinks = false;
+ private Resources rcs = null;
+ private static FileUtils FILE_UTILS = FileUtils.getFileUtils();
+ private static SymbolicLinkUtils SYMLINK_UTILS =
+ SymbolicLinkUtils.getSymbolicLinkUtils();
+ private boolean performGc = Os.isFamily("windows");
+
+ /**
+ * Set the name of a single file to be removed.
+ *
+ * @param file the file to be deleted
+ */
+ public void setFile(File file) {
+ this.file = file;
+ }
+
+ /**
+ * Set the directory from which files are to be deleted
+ *
+ * @param dir the directory path.
+ */
+ public void setDir(File dir) {
+ this.dir = dir;
+ getImplicitFileSet().setDir(dir);
+ }
+
+ /**
+ * If true, list all names of deleted files.
+ *
+ * @param verbose "true" or "on"
+ */
+ public void setVerbose(boolean verbose) {
+ if (verbose) {
+ this.verbosity = Project.MSG_INFO;
+ } else {
+ this.verbosity = Project.MSG_VERBOSE;
+ }
+ }
+
+ /**
+ * If true and the file does not exist, do not display a diagnostic
+ * message or modify the exit status to reflect an error.
+ * This means that if a file or directory cannot be deleted,
+ * then no error is reported. This setting emulates the
+ * -f option to the Unix &quot;rm&quot; command.
+ * Default is false meaning things are &quot;noisy&quot;
+ * @param quiet "true" or "on"
+ */
+ public void setQuiet(boolean quiet) {
+ this.quiet = quiet;
+ if (quiet) {
+ this.failonerror = false;
+ }
+ }
+
+ /**
+ * If false, note errors but continue.
+ *
+ * @param failonerror true or false
+ */
+ public void setFailOnError(boolean failonerror) {
+ this.failonerror = failonerror;
+ }
+
+ /**
+ * If true, on failure to delete, note the error and set
+ * the deleteonexit flag, and continue
+ *
+ * @param deleteOnExit true or false
+ */
+ public void setDeleteOnExit(boolean deleteOnExit) {
+ this.deleteOnExit = deleteOnExit;
+ }
+
+
+ /**
+ * If true, delete empty directories.
+ * @param includeEmpty if true delete empty directories (only
+ * for filesets). Default is false.
+ */
+ public void setIncludeEmptyDirs(boolean includeEmpty) {
+ this.includeEmpty = includeEmpty;
+ }
+
+ /**
+ * Whether to perform a garbage collection before retrying a failed delete.
+ *
+ * <p>This may be required on Windows (where it is set to true by
+ * default) but also on other operating systems, for example when
+ * deleting directories from an NFS share.</p>
+ *
+ * @since Ant 1.8.3
+ */
+ public void setPerformGcOnFailedDelete(boolean b) {
+ performGc = b;
+ }
+
+ /**
+ * Adds a set of files to be deleted.
+ * @param set the set of files to be deleted
+ */
+ public void addFileset(FileSet set) {
+ filesets.addElement(set);
+ }
+
+ /**
+ * Add an arbitrary ResourceCollection to be deleted.
+ * @param rc the filesystem-only ResourceCollection.
+ */
+ public void add(ResourceCollection rc) {
+ if (rc == null) {
+ return;
+ }
+ if (rcs == null) {
+ rcs = new Resources();
+ rcs.setCache(true);
+ }
+ rcs.add(rc);
+ }
+
+ /**
+ * add a name entry on the include list
+ * @return a NameEntry object to be configured
+ */
+ public PatternSet.NameEntry createInclude() {
+ usedMatchingTask = true;
+ return super.createInclude();
+ }
+
+ /**
+ * add a name entry on the include files list
+ * @return an NameEntry object to be configured
+ */
+ public PatternSet.NameEntry createIncludesFile() {
+ usedMatchingTask = true;
+ return super.createIncludesFile();
+ }
+
+ /**
+ * add a name entry on the exclude list
+ * @return an NameEntry object to be configured
+ */
+ public PatternSet.NameEntry createExclude() {
+ usedMatchingTask = true;
+ return super.createExclude();
+ }
+
+ /**
+ * add a name entry on the include files list
+ * @return an NameEntry object to be configured
+ */
+ public PatternSet.NameEntry createExcludesFile() {
+ usedMatchingTask = true;
+ return super.createExcludesFile();
+ }
+
+ /**
+ * add a set of patterns
+ * @return PatternSet object to be configured
+ */
+ public PatternSet createPatternSet() {
+ usedMatchingTask = true;
+ return super.createPatternSet();
+ }
+
+ /**
+ * Sets the set of include patterns. Patterns may be separated by a comma
+ * or a space.
+ *
+ * @param includes the string containing the include patterns
+ */
+ public void setIncludes(String includes) {
+ usedMatchingTask = true;
+ super.setIncludes(includes);
+ }
+
+ /**
+ * Sets the set of exclude patterns. Patterns may be separated by a comma
+ * or a space.
+ *
+ * @param excludes the string containing the exclude patterns
+ */
+ public void setExcludes(String excludes) {
+ usedMatchingTask = true;
+ super.setExcludes(excludes);
+ }
+
+ /**
+ * Sets whether default exclusions should be used or not.
+ *
+ * @param useDefaultExcludes "true"|"on"|"yes" when default exclusions
+ * should be used, "false"|"off"|"no" when they
+ * shouldn't be used.
+ */
+ public void setDefaultexcludes(boolean useDefaultExcludes) {
+ usedMatchingTask = true;
+ super.setDefaultexcludes(useDefaultExcludes);
+ }
+
+ /**
+ * Sets the name of the file containing the includes patterns.
+ *
+ * @param includesfile A string containing the filename to fetch
+ * the include patterns from.
+ */
+ public void setIncludesfile(File includesfile) {
+ usedMatchingTask = true;
+ super.setIncludesfile(includesfile);
+ }
+
+ /**
+ * Sets the name of the file containing the includes patterns.
+ *
+ * @param excludesfile A string containing the filename to fetch
+ * the include patterns from.
+ */
+ public void setExcludesfile(File excludesfile) {
+ usedMatchingTask = true;
+ super.setExcludesfile(excludesfile);
+ }
+
+ /**
+ * Sets case sensitivity of the file system
+ *
+ * @param isCaseSensitive "true"|"on"|"yes" if file system is case
+ * sensitive, "false"|"off"|"no" when not.
+ */
+ public void setCaseSensitive(boolean isCaseSensitive) {
+ usedMatchingTask = true;
+ super.setCaseSensitive(isCaseSensitive);
+ }
+
+ /**
+ * Sets whether or not symbolic links should be followed.
+ *
+ * @param followSymlinks whether or not symbolic links should be followed
+ */
+ public void setFollowSymlinks(boolean followSymlinks) {
+ usedMatchingTask = true;
+ super.setFollowSymlinks(followSymlinks);
+ }
+
+ /**
+ * Sets whether the symbolic links that have not been followed
+ * shall be removed (the links, not the locations they point at).
+ *
+ * @since Ant 1.8.0
+ */
+ public void setRemoveNotFollowedSymlinks(boolean b) {
+ removeNotFollowedSymlinks = b;
+ }
+
+ /**
+ * add a "Select" selector entry on the selector list
+ * @param selector the selector to be added
+ */
+ public void addSelector(SelectSelector selector) {
+ usedMatchingTask = true;
+ super.addSelector(selector);
+ }
+
+ /**
+ * add an "And" selector entry on the selector list
+ * @param selector the selector to be added
+ */
+ public void addAnd(AndSelector selector) {
+ usedMatchingTask = true;
+ super.addAnd(selector);
+ }
+
+ /**
+ * add an "Or" selector entry on the selector list
+ * @param selector the selector to be added
+ */
+ public void addOr(OrSelector selector) {
+ usedMatchingTask = true;
+ super.addOr(selector);
+ }
+
+ /**
+ * add a "Not" selector entry on the selector list
+ * @param selector the selector to be added
+ */
+ public void addNot(NotSelector selector) {
+ usedMatchingTask = true;
+ super.addNot(selector);
+ }
+
+ /**
+ * add a "None" selector entry on the selector list
+ * @param selector the selector to be added
+ */
+ public void addNone(NoneSelector selector) {
+ usedMatchingTask = true;
+ super.addNone(selector);
+ }
+
+ /**
+ * add a majority selector entry on the selector list
+ * @param selector the selector to be added
+ */
+ public void addMajority(MajoritySelector selector) {
+ usedMatchingTask = true;
+ super.addMajority(selector);
+ }
+
+ /**
+ * add a selector date entry on the selector list
+ * @param selector the selector to be added
+ */
+ public void addDate(DateSelector selector) {
+ usedMatchingTask = true;
+ super.addDate(selector);
+ }
+
+ /**
+ * add a selector size entry on the selector list
+ * @param selector the selector to be added
+ */
+ public void addSize(SizeSelector selector) {
+ usedMatchingTask = true;
+ super.addSize(selector);
+ }
+
+ /**
+ * add a selector filename entry on the selector list
+ * @param selector the selector to be added
+ */
+ public void addFilename(FilenameSelector selector) {
+ usedMatchingTask = true;
+ super.addFilename(selector);
+ }
+
+ /**
+ * add an extended selector entry on the selector list
+ * @param selector the selector to be added
+ */
+ public void addCustom(ExtendSelector selector) {
+ usedMatchingTask = true;
+ super.addCustom(selector);
+ }
+
+ /**
+ * add a contains selector entry on the selector list
+ * @param selector the selector to be added
+ */
+ public void addContains(ContainsSelector selector) {
+ usedMatchingTask = true;
+ super.addContains(selector);
+ }
+
+ /**
+ * add a present selector entry on the selector list
+ * @param selector the selector to be added
+ */
+ public void addPresent(PresentSelector selector) {
+ usedMatchingTask = true;
+ super.addPresent(selector);
+ }
+
+ /**
+ * add a depth selector entry on the selector list
+ * @param selector the selector to be added
+ */
+ public void addDepth(DepthSelector selector) {
+ usedMatchingTask = true;
+ super.addDepth(selector);
+ }
+
+ /**
+ * add a depends selector entry on the selector list
+ * @param selector the selector to be added
+ */
+ public void addDepend(DependSelector selector) {
+ usedMatchingTask = true;
+ super.addDepend(selector);
+ }
+
+ /**
+ * add a regular expression selector entry on the selector list
+ * @param selector the selector to be added
+ */
+ public void addContainsRegexp(ContainsRegexpSelector selector) {
+ usedMatchingTask = true;
+ super.addContainsRegexp(selector);
+ }
+
+ /**
+ * add the modified selector
+ * @param selector the selector to add
+ * @since ant 1.6
+ */
+ public void addModified(ModifiedSelector selector) {
+ usedMatchingTask = true;
+ super.addModified(selector);
+ }
+
+ /**
+ * add an arbitrary selector
+ * @param selector the selector to be added
+ * @since Ant 1.6
+ */
+ public void add(FileSelector selector) {
+ usedMatchingTask = true;
+ super.add(selector);
+ }
+
+ /**
+ * Delete the file(s).
+ * @exception BuildException if an error occurs
+ */
+ public void execute() throws BuildException {
+ if (usedMatchingTask) {
+ log("DEPRECATED - Use of the implicit FileSet is deprecated. "
+ + "Use a nested fileset element instead.", quiet ? Project.MSG_VERBOSE : verbosity);
+ }
+
+ if (file == null && dir == null && filesets.size() == 0 && rcs == null) {
+ throw new BuildException("At least one of the file or dir "
+ + "attributes, or a nested resource collection, "
+ + "must be set.");
+ }
+
+ if (quiet && failonerror) {
+ throw new BuildException("quiet and failonerror cannot both be "
+ + "set to true", getLocation());
+ }
+
+ // delete the single file
+ if (file != null) {
+ if (file.exists()) {
+ if (file.isDirectory()) {
+ log("Directory " + file.getAbsolutePath()
+ + " cannot be removed using the file attribute. "
+ + "Use dir instead.", quiet ? Project.MSG_VERBOSE : verbosity);
+ } else {
+ log("Deleting: " + file.getAbsolutePath());
+
+ if (!delete(file)) {
+ handle("Unable to delete file " + file.getAbsolutePath());
+ }
+ }
+ } else if (isDanglingSymlink(file)) {
+ log("Trying to delete file " + file.getAbsolutePath()
+ + " which looks like a broken symlink.",
+ quiet ? Project.MSG_VERBOSE : verbosity);
+ if (!delete(file)) {
+ handle("Unable to delete file " + file.getAbsolutePath());
+ }
+ } else {
+ log("Could not find file " + file.getAbsolutePath()
+ + " to delete.", quiet ? Project.MSG_VERBOSE : verbosity);
+ }
+ }
+
+ // delete the directory
+ if (dir != null && !usedMatchingTask) {
+ if (dir.exists() && dir.isDirectory()) {
+ /*
+ If verbosity is MSG_VERBOSE, that mean we are doing
+ regular logging (backwards as that sounds). In that
+ case, we want to print one message about deleting the
+ top of the directory tree. Otherwise, the removeDir
+ method will handle messages for _all_ directories.
+ */
+ if (verbosity == Project.MSG_VERBOSE) {
+ log("Deleting directory " + dir.getAbsolutePath());
+ }
+ removeDir(dir);
+ } else if (isDanglingSymlink(dir)) {
+ log("Trying to delete directory " + dir.getAbsolutePath()
+ + " which looks like a broken symlink.",
+ quiet ? Project.MSG_VERBOSE : verbosity);
+ if (!delete(dir)) {
+ handle("Unable to delete directory "
+ + dir.getAbsolutePath());
+ }
+ }
+ }
+ Resources resourcesToDelete = new Resources();
+ resourcesToDelete.setProject(getProject());
+ resourcesToDelete.setCache(true);
+ Resources filesetDirs = new Resources();
+ filesetDirs.setProject(getProject());
+ filesetDirs.setCache(true);
+ FileSet implicit = null;
+ if (usedMatchingTask && dir != null && dir.isDirectory()) {
+ //add the files from the default fileset:
+ implicit = getImplicitFileSet();
+ implicit.setProject(getProject());
+ filesets.add(implicit);
+ }
+
+ final int size = filesets.size();
+ for (int i = 0; i < size; i++) {
+ FileSet fs = (FileSet) filesets.get(i);
+ if (fs.getProject() == null) {
+ log("Deleting fileset with no project specified;"
+ + " assuming executing project", Project.MSG_VERBOSE);
+ fs = (FileSet) fs.clone();
+ fs.setProject(getProject());
+ }
+ final File fsDir = fs.getDir();
+ if (!fs.getErrorOnMissingDir() &&
+ (fsDir == null || !fsDir.exists())) {
+ continue;
+ }
+ if (fsDir == null) {
+ throw new BuildException(
+ "File or Resource without directory or file specified");
+ } else if (!fsDir.isDirectory()) {
+ handle("Directory does not exist: " + fsDir);
+ } else {
+ DirectoryScanner ds = fs.getDirectoryScanner();
+ // the previous line has already scanned the
+ // filesystem, in order to avoid a rescan when later
+ // iterating, capture the results now and store them
+ final String[] files = ds.getIncludedFiles();
+ resourcesToDelete.add(new ResourceCollection() {
+ public boolean isFilesystemOnly() {
+ return true;
+ }
+ public int size() {
+ return files.length;
+ }
+ public Iterator<Resource> iterator() {
+ return new FileResourceIterator(getProject(),
+ fsDir, files);
+ }
+ });
+ if (includeEmpty) {
+ filesetDirs.add(new ReverseDirs(getProject(), fsDir,
+ ds
+ .getIncludedDirectories()));
+ }
+
+ if (removeNotFollowedSymlinks) {
+ String[] n = ds.getNotFollowedSymlinks();
+ if (n.length > 0) {
+ String[] links = new String[n.length];
+ System.arraycopy(n, 0, links, 0, n.length);
+ Arrays.sort(links, ReverseDirs.REVERSE);
+ for (int l = 0; l < links.length; l++) {
+ try {
+ SYMLINK_UTILS
+ .deleteSymbolicLink(new File(links[l]),
+ this);
+ } catch (java.io.IOException ex) {
+ handle(ex);
+ }
+ }
+ }
+ }
+ }
+ }
+ resourcesToDelete.add(filesetDirs);
+ if (rcs != null) {
+ // sort first to files, then dirs
+ Restrict exists = new Restrict();
+ exists.add(EXISTS);
+ exists.add(rcs);
+ Sort s = new Sort();
+ s.add(REVERSE_FILESYSTEM);
+ s.add(exists);
+ resourcesToDelete.add(s);
+ }
+ try {
+ if (resourcesToDelete.isFilesystemOnly()) {
+ for (Resource r : resourcesToDelete) {
+ // nonexistent resources could only occur if we already
+ // deleted something from a fileset:
+ File f = r.as(FileProvider.class)
+ .getFile();
+ if (!f.exists()) {
+ continue;
+ }
+ if (!(f.isDirectory()) || f.list().length == 0) {
+ log("Deleting " + f, verbosity);
+ if (!delete(f) && failonerror) {
+ handle("Unable to delete "
+ + (f.isDirectory() ? "directory " : "file ") + f);
+ }
+ }
+ }
+ } else {
+ handle(getTaskName() + " handles only filesystem resources");
+ }
+ } catch (Exception e) {
+ handle(e);
+ } finally {
+ if (implicit != null) {
+ filesets.remove(implicit);
+ }
+ }
+ }
+
+//************************************************************************
+// protected and private methods
+//************************************************************************
+
+ private void handle(String msg) {
+ handle(new BuildException(msg));
+ }
+
+ private void handle(Exception e) {
+ if (failonerror) {
+ throw (e instanceof BuildException)
+ ? (BuildException) e : new BuildException(e);
+ }
+ log(e, quiet ? Project.MSG_VERBOSE : verbosity);
+ }
+
+ /**
+ * Accommodate Windows bug encountered in both Sun and IBM JDKs.
+ * Others possible. If the delete does not work, call System.gc(),
+ * wait a little and try again.
+ */
+ private boolean delete(File f) {
+ if (!FILE_UTILS.tryHardToDelete(f, performGc)) {
+ if (deleteOnExit) {
+ int level = quiet ? Project.MSG_VERBOSE : Project.MSG_INFO;
+ log("Failed to delete " + f + ", calling deleteOnExit."
+ + " This attempts to delete the file when the Ant jvm"
+ + " has exited and might not succeed.", level);
+ f.deleteOnExit();
+ return true;
+ }
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Delete a directory
+ *
+ * @param d the directory to delete
+ */
+ protected void removeDir(File d) {
+ String[] list = d.list();
+ if (list == null) {
+ list = new String[0];
+ }
+ for (int i = 0; i < list.length; i++) {
+ String s = list[i];
+ File f = new File(d, s);
+ if (f.isDirectory()) {
+ removeDir(f);
+ } else {
+ log("Deleting " + f.getAbsolutePath(), quiet ? Project.MSG_VERBOSE : verbosity);
+ if (!delete(f)) {
+ handle("Unable to delete file " + f.getAbsolutePath());
+ }
+ }
+ }
+ log("Deleting directory " + d.getAbsolutePath(), verbosity);
+ if (!delete(d)) {
+ handle("Unable to delete directory " + d.getAbsolutePath());
+ }
+ }
+
+ /**
+ * remove an array of files in a directory, and a list of subdirectories
+ * which will only be deleted if 'includeEmpty' is true
+ * @param d directory to work from
+ * @param files array of files to delete; can be of zero length
+ * @param dirs array of directories to delete; can of zero length
+ */
+ protected void removeFiles(File d, String[] files, String[] dirs) {
+ if (files.length > 0) {
+ log("Deleting " + files.length + " files from "
+ + d.getAbsolutePath(), quiet ? Project.MSG_VERBOSE : verbosity);
+ for (int j = 0; j < files.length; j++) {
+ File f = new File(d, files[j]);
+ log("Deleting " + f.getAbsolutePath(),
+ quiet ? Project.MSG_VERBOSE : verbosity);
+ if (!delete(f)) {
+ handle("Unable to delete file " + f.getAbsolutePath());
+ }
+ }
+ }
+
+ if (dirs.length > 0 && includeEmpty) {
+ int dirCount = 0;
+ for (int j = dirs.length - 1; j >= 0; j--) {
+ File currDir = new File(d, dirs[j]);
+ String[] dirFiles = currDir.list();
+ if (dirFiles == null || dirFiles.length == 0) {
+ log("Deleting " + currDir.getAbsolutePath(),
+ quiet ? Project.MSG_VERBOSE : verbosity);
+ if (!delete(currDir)) {
+ handle("Unable to delete directory "
+ + currDir.getAbsolutePath());
+ } else {
+ dirCount++;
+ }
+ }
+ }
+
+ if (dirCount > 0) {
+ log("Deleted "
+ + dirCount
+ + " director" + (dirCount == 1 ? "y" : "ies")
+ + " form " + d.getAbsolutePath(),
+ quiet ? Project.MSG_VERBOSE : verbosity);
+ }
+ }
+ }
+
+ private boolean isDanglingSymlink(File f) {
+ try {
+ return SYMLINK_UTILS.isDanglingSymbolicLink(f);
+ } catch (java.io.IOException e) {
+ log("Error while trying to detect " + f.getAbsolutePath()
+ + " as broken symbolic link. " + e.getMessage(),
+ quiet ? Project.MSG_VERBOSE : verbosity);
+ return false;
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Deltree.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Deltree.java
new file mode 100644
index 00000000..098d6e5f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Deltree.java
@@ -0,0 +1,112 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Task;
+
+/**
+ *
+ *
+ * @since Ant 1.1
+ *
+ * @deprecated The deltree task is deprecated since Ant 1.2. Use
+ * delete instead.
+ */
+
+public class Deltree extends Task {
+
+ private File dir;
+
+ /**
+ * Set the directory to be deleted
+ *
+ * @param dir the root of the tree to be removed.
+ */
+ public void setDir(File dir) {
+ this.dir = dir;
+ }
+
+ /**
+ * Do the work.
+ *
+ * @exception BuildException if the task is not configured correctly or
+ * the tree cannot be removed.
+ */
+ public void execute() throws BuildException {
+ log("DEPRECATED - The deltree task is deprecated. "
+ + "Use delete instead.");
+
+ if (dir == null) {
+ throw new BuildException("dir attribute must be set!", getLocation());
+ }
+
+ if (dir.exists()) {
+ if (!dir.isDirectory()) {
+ if (!dir.delete()) {
+ throw new BuildException("Unable to delete directory "
+ + dir.getAbsolutePath(),
+ getLocation());
+ }
+ return;
+ }
+
+ log("Deleting: " + dir.getAbsolutePath());
+
+ try {
+ removeDir(dir);
+ } catch (IOException ioe) {
+ String msg = "Unable to delete " + dir.getAbsolutePath();
+ throw new BuildException(msg, getLocation());
+ }
+ }
+ }
+
+ private void removeDir(File dir) throws IOException {
+
+ // check to make sure that the given dir isn't a symlink
+ // the comparison of absolute path and canonical path
+ // catches this
+
+ // if (dir.getCanonicalPath().equals(dir.getAbsolutePath())) {
+ // (costin) It will not work if /home/costin is symlink to
+ // /da0/home/costin ( taz for example )
+ String[] list = dir.list();
+ for (int i = 0; i < list.length; i++) {
+ String s = list[i];
+ File f = new File(dir, s);
+ if (f.isDirectory()) {
+ removeDir(f);
+ } else {
+ if (!f.delete()) {
+ throw new BuildException("Unable to delete file "
+ + f.getAbsolutePath());
+ }
+ }
+ }
+ if (!dir.delete()) {
+ throw new BuildException("Unable to delete directory "
+ + dir.getAbsolutePath());
+ }
+ }
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/DependSet.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/DependSet.java
new file mode 100644
index 00000000..dc42beb1
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/DependSet.java
@@ -0,0 +1,299 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.io.File;
+import java.util.Date;
+import java.util.Iterator;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.FileList;
+import org.apache.tools.ant.types.FileSet;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.ResourceCollection;
+import org.apache.tools.ant.types.TimeComparison;
+import org.apache.tools.ant.types.resources.Resources;
+import org.apache.tools.ant.types.resources.Restrict;
+import org.apache.tools.ant.types.resources.Union;
+import org.apache.tools.ant.types.resources.comparators.ResourceComparator;
+import org.apache.tools.ant.types.resources.comparators.Reverse;
+import org.apache.tools.ant.types.resources.selectors.Exists;
+import org.apache.tools.ant.types.resources.selectors.Not;
+import org.apache.tools.ant.types.resources.selectors.ResourceSelector;
+
+/**
+ * Examines and removes out of date target files. If any of the target files
+ * are out of date with respect to any of the source files, all target
+ * files are removed. This is useful where dependencies cannot be
+ * computed (for example, dynamically interpreted parameters or files
+ * that need to stay in synch but are not directly linked) or where
+ * the ant task in question could compute them but does not (for
+ * example, the linked DTD for an XML file using the XSLT task).
+ *
+ * nested arguments:
+ * <ul>
+ * <li>sources (resource union describing the source resources to examine)
+ * <li>srcfileset (fileset describing the source files to examine)
+ * <li>srcfilelist (filelist describing the source files to examine)
+ * <li>targets (path describing the target files to examine)
+ * <li>targetfileset (fileset describing the target files to examine)
+ * <li>targetfilelist (filelist describing the target files to examine)
+ * </ul>
+ * At least one of both source and target entities is required.
+ * <p>
+ * This task will examine each of the sources against each of the target files. If
+ * any target files are out of date with respect to any of the sources, all targets
+ * are removed. If any sources or targets do not exist, all targets are removed.
+ * Hint: If missing files should be ignored, specify them as include patterns
+ * in filesets, rather than using filelists.
+ * </p><p>
+ * This task attempts to optimize speed of dependency checking
+ * by comparing only the dates of the oldest target file and the newest source.
+ * </p><p>
+ * Example uses:
+ * <ul><li>
+ * Record the fact that an XML file must be up to date with respect to its XSD
+ * (Schema file), even though the XML file itself includes no reference to its XSD.
+ * </li><li>
+ * Record the fact that an XSL stylesheet includes other sub-stylesheets
+ * </li><li>
+ * Record the fact that java files must be recompiled if the ant build file changes
+ * </li></ul>
+ *
+ * @ant.task category="filesystem"
+ * @since Ant 1.4
+ */
+public class DependSet extends MatchingTask {
+
+ private static final ResourceSelector NOT_EXISTS = new Not(new Exists());
+ private static final ResourceComparator DATE
+ = new org.apache.tools.ant.types.resources.comparators.Date();
+ private static final ResourceComparator REVERSE_DATE = new Reverse(DATE);
+
+ private static final class NonExistent extends Restrict {
+ private NonExistent(ResourceCollection rc) {
+ super.add(rc);
+ super.add(NOT_EXISTS);
+ }
+ }
+
+ private static final class HideMissingBasedir
+ implements ResourceCollection {
+ private FileSet fs;
+
+ private HideMissingBasedir(FileSet fs) {
+ this.fs = fs;
+ }
+ public Iterator<Resource> iterator() {
+ return basedirExists() ? fs.iterator() : Resources.EMPTY_ITERATOR;
+ }
+ public int size() {
+ return basedirExists() ? fs.size() : 0;
+ }
+ public boolean isFilesystemOnly() {
+ return true;
+ }
+ private boolean basedirExists() {
+ File basedir = fs.getDir();
+ //trick to evoke "basedir not set" if null:
+ return basedir == null || basedir.exists();
+ }
+ }
+
+ private Union sources = null;
+ private Path targets = null;
+
+ private boolean verbose;
+
+ /**
+ * Create a nested sources element.
+ * @return a Union instance.
+ */
+ public synchronized Union createSources() {
+ sources = (sources == null) ? new Union() : sources;
+ return sources;
+ }
+
+ /**
+ * Add a set of source files.
+ * @param fs the FileSet to add.
+ */
+ public void addSrcfileset(FileSet fs) {
+ createSources().add(fs);
+ }
+
+ /**
+ * Add a list of source files.
+ * @param fl the FileList to add.
+ */
+ public void addSrcfilelist(FileList fl) {
+ createSources().add(fl);
+ }
+
+ /**
+ * Create a nested targets element.
+ * @return a Union instance.
+ */
+ public synchronized Path createTargets() {
+ targets = (targets == null) ? new Path(getProject()) : targets;
+ return targets;
+ }
+
+ /**
+ * Add a set of target files.
+ * @param fs the FileSet to add.
+ */
+ public void addTargetfileset(FileSet fs) {
+ createTargets().add(new HideMissingBasedir(fs));
+ }
+
+ /**
+ * Add a list of target files.
+ * @param fl the FileList to add.
+ */
+ public void addTargetfilelist(FileList fl) {
+ createTargets().add(fl);
+ }
+
+ /**
+ * In verbose mode missing targets and sources as well as the
+ * modification times of the newest source and latest target will
+ * be logged as info.
+ *
+ * <p>All deleted files will be logged as well.</p>
+ *
+ * @since Ant 1.8.0
+ */
+ public void setVerbose(boolean b) {
+ verbose = b;
+ }
+
+ /**
+ * Execute the task.
+ * @throws BuildException if errors occur.
+ */
+ public void execute() throws BuildException {
+ if (sources == null) {
+ throw new BuildException(
+ "At least one set of source resources must be specified");
+ }
+ if (targets == null) {
+ throw new BuildException(
+ "At least one set of target files must be specified");
+ }
+ //no sources = nothing to compare; no targets = nothing to delete:
+ if (sources.size() > 0 && targets.size() > 0 && !uptodate(sources, targets)) {
+ log("Deleting all target files.", Project.MSG_VERBOSE);
+ if (verbose) {
+ String[] t = targets.list();
+ for (int i = 0; i < t.length; i++) {
+ log("Deleting " + t[i]);
+ }
+ }
+ Delete delete = new Delete();
+ delete.bindToOwner(this);
+ delete.add(targets);
+ delete.perform();
+ }
+ }
+
+ private boolean uptodate(ResourceCollection src, ResourceCollection target) {
+ org.apache.tools.ant.types.resources.selectors.Date datesel
+ = new org.apache.tools.ant.types.resources.selectors.Date();
+ datesel.setMillis(System.currentTimeMillis());
+ datesel.setWhen(TimeComparison.AFTER);
+ // don't whine because a file has changed during the last
+ // second (or whathever our current granularity may be)
+ datesel.setGranularity(0);
+ logFuture(targets, datesel);
+
+ NonExistent missingTargets = new NonExistent(targets);
+ int neTargets = missingTargets.size();
+ if (neTargets > 0) {
+ log(neTargets + " nonexistent targets", Project.MSG_VERBOSE);
+ logMissing(missingTargets, "target");
+ return false;
+ }
+ Resource oldestTarget = getOldest(targets);
+ logWithModificationTime(oldestTarget, "oldest target file");
+
+ logFuture(sources, datesel);
+
+ NonExistent missingSources = new NonExistent(sources);
+ int neSources = missingSources.size();
+ if (neSources > 0) {
+ log(neSources + " nonexistent sources", Project.MSG_VERBOSE);
+ logMissing(missingSources, "source");
+ return false;
+ }
+ Resource newestSource = (Resource) getNewest(sources);
+ logWithModificationTime(newestSource, "newest source");
+ return oldestTarget.getLastModified() >= newestSource.getLastModified();
+ }
+
+ private void logFuture(ResourceCollection rc, ResourceSelector rsel) {
+ Restrict r = new Restrict();
+ r.add(rsel);
+ r.add(rc);
+ for (Resource res : r) {
+ log("Warning: " + res + " modified in the future.", Project.MSG_WARN);
+ }
+ }
+
+ private Resource getXest(ResourceCollection rc, ResourceComparator c) {
+ Iterator<Resource> i = rc.iterator();
+ if (!i.hasNext()) {
+ return null;
+
+ }
+ Resource xest = i.next();
+ while (i.hasNext()) {
+ Resource next = i.next();
+ if (c.compare(xest, next) < 0) {
+ xest = next;
+ }
+ }
+ return xest;
+ }
+
+ private Resource getOldest(ResourceCollection rc) {
+ return getXest(rc, REVERSE_DATE);
+ }
+
+ private Resource getNewest(ResourceCollection rc) {
+ return getXest(rc, DATE);
+ }
+
+ private void logWithModificationTime(Resource r, String what) {
+ log(r.toLongString() + " is " + what + ", modified at "
+ + new Date(r.getLastModified()),
+ verbose ? Project.MSG_INFO : Project.MSG_VERBOSE);
+ }
+
+ private void logMissing(ResourceCollection missing, String what) {
+ if (verbose) {
+ for (Resource r : missing) {
+ log("Expected " + what + " " + r.toLongString()
+ + " is missing.");
+ }
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/DiagnosticsTask.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/DiagnosticsTask.java
new file mode 100644
index 00000000..c745cfb5
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/DiagnosticsTask.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Diagnostics;
+import org.apache.tools.ant.Task;
+
+/**
+ * This is a task that hands off work to the Diagnostics module.
+ * It lets you run diagnostics in an IDE.
+ */
+public class DiagnosticsTask extends Task {
+
+ private static final String[] ARGS = new String[0];
+
+ /**
+ * Execute the task.
+ * This delegates to the Diagnostics class.
+ * @throws BuildException on error.
+ */
+ public void execute() throws BuildException {
+ Diagnostics.main(ARGS);
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Dirname.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Dirname.java
new file mode 100644
index 00000000..c4c5d5f2
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Dirname.java
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.io.File;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Task;
+
+/**
+ * Determines the directory name of the specified file.
+ *
+ * This task can accept the following attributes:
+ * <ul>
+ * <li>file
+ * <li>property
+ * </ul>
+ * Both <b>file</b> and <b>property</b> are required.
+ * <p>
+ * When this task executes, it will set the specified property to the
+ * value of the specified file up to, but not including, the last path
+ * element. If file is a file, the directory will be the current
+ * directory.
+ *
+ *
+ * @since Ant 1.5
+ *
+ * @ant.task category="property"
+ */
+
+public class Dirname extends Task {
+ private File file;
+ private String property;
+
+ /**
+ * Path to take the dirname of.
+ * @param file a <code>File</code> value
+ */
+ public void setFile(File file) {
+ this.file = file;
+ }
+
+ /**
+ * The name of the property to set.
+ * @param property the name of the property
+ */
+ public void setProperty(String property) {
+ this.property = property;
+ }
+
+ /**
+ * Execute this task.
+ * @throws BuildException on error
+ */
+ public void execute() throws BuildException {
+ if (property == null) {
+ throw new BuildException("property attribute required", getLocation());
+ }
+ if (file == null) {
+ throw new BuildException("file attribute required", getLocation());
+ } else {
+ String value = file.getParent();
+ getProject().setNewProperty(property, value);
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Ear.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Ear.java
new file mode 100644
index 00000000..6e08ecda
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Ear.java
@@ -0,0 +1,154 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.ZipFileSet;
+import org.apache.tools.ant.util.FileUtils;
+import org.apache.tools.zip.ZipOutputStream;
+
+/**
+ * Creates a EAR archive. Based on WAR task
+ *
+ * @since Ant 1.4
+ *
+ * @ant.task category="packaging"
+ */
+public class Ear extends Jar {
+ private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+
+ private File deploymentDescriptor;
+ private boolean descriptorAdded;
+ private static final String XML_DESCRIPTOR_PATH = "META-INF/application.xml";
+
+ /**
+ * Create an Ear task.
+ */
+ public Ear() {
+ super();
+ archiveType = "ear";
+ emptyBehavior = "create";
+ }
+
+ /**
+ * Set the destination file.
+ * @param earFile the destination file
+ * @deprecated since 1.5.x.
+ * Use setDestFile(destfile) instead.
+ */
+ public void setEarfile(File earFile) {
+ setDestFile(earFile);
+ }
+
+ /**
+ * File to incorporate as application.xml.
+ * @param descr the descriptor file
+ */
+ public void setAppxml(File descr) {
+ deploymentDescriptor = descr;
+ if (!deploymentDescriptor.exists()) {
+ throw new BuildException("Deployment descriptor: "
+ + deploymentDescriptor
+ + " does not exist.");
+ }
+
+ // Create a ZipFileSet for this file, and pass it up.
+ ZipFileSet fs = new ZipFileSet();
+ fs.setFile(deploymentDescriptor);
+ fs.setFullpath(XML_DESCRIPTOR_PATH);
+ super.addFileset(fs);
+ }
+
+
+ /**
+ * Adds zipfileset.
+ *
+ * @param fs zipfileset to add
+ */
+ public void addArchives(ZipFileSet fs) {
+ // We just set the prefix for this fileset, and pass it up.
+ // Do we need to do this? LH
+ fs.setPrefix("/");
+ super.addFileset(fs);
+ }
+
+
+ /**
+ * Initialize the output stream.
+ * @param zOut the zip output stream.
+ * @throws IOException on I/O errors
+ * @throws BuildException on other errors
+ */
+ protected void initZipOutputStream(ZipOutputStream zOut)
+ throws IOException, BuildException {
+ // If no webxml file is specified, it's an error.
+ if (deploymentDescriptor == null && !isInUpdateMode()) {
+ throw new BuildException("appxml attribute is required", getLocation());
+ }
+
+ super.initZipOutputStream(zOut);
+ }
+
+ /**
+ * Overridden from Zip class to deal with application.xml
+ * @param file the file to add to the archive
+ * @param zOut the stream to write to
+ * @param vPath the name this entry shall have in the archive
+ * @param mode the Unix permissions to set.
+ * @throws IOException on error
+ */
+ protected void zipFile(File file, ZipOutputStream zOut, String vPath,
+ int mode)
+ throws IOException {
+ // If the file being added is META-INF/application.xml, we
+ // warn if it's not the one specified in the "appxml"
+ // attribute - or if it's being added twice, meaning the same
+ // file is specified by the "appxml" attribute and in a
+ // <fileset> element.
+ if (XML_DESCRIPTOR_PATH.equalsIgnoreCase(vPath)) {
+ if (deploymentDescriptor == null
+ || !FILE_UTILS.fileNameEquals(deploymentDescriptor, file)
+ || descriptorAdded) {
+ logWhenWriting("Warning: selected " + archiveType
+ + " files include a " + XML_DESCRIPTOR_PATH
+ + " which will"
+ + " be ignored (please use appxml attribute to "
+ + archiveType + " task)",
+ Project.MSG_WARN);
+ } else {
+ super.zipFile(file, zOut, vPath, mode);
+ descriptorAdded = true;
+ }
+ } else {
+ super.zipFile(file, zOut, vPath, mode);
+ }
+ }
+
+ /**
+ * Make sure we don't think we already have a application.xml next
+ * time this task gets executed.
+ */
+ protected void cleanUp() {
+ descriptorAdded = false;
+ super.cleanUp();
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Echo.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Echo.java
new file mode 100644
index 00000000..ac31ee32
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Echo.java
@@ -0,0 +1,170 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.types.LogLevel;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.resources.FileProvider;
+import org.apache.tools.ant.types.resources.FileResource;
+import org.apache.tools.ant.types.resources.LogOutputResource;
+import org.apache.tools.ant.types.resources.StringResource;
+import org.apache.tools.ant.util.ResourceUtils;
+import org.apache.tools.ant.util.StringUtils;
+
+/**
+ * Writes a message to the Ant logging facilities.
+ *
+ * @since Ant 1.1
+ *
+ * @ant.task category="utility"
+ */
+public class Echo extends Task {
+ // CheckStyle:VisibilityModifier OFF - bc
+ protected String message = "";
+ protected File file = null;
+ protected boolean append = false;
+ /** encoding; set to null or empty means 'default' */
+ private String encoding = "";
+ private boolean force = false;
+
+ // by default, messages are always displayed
+ protected int logLevel = Project.MSG_WARN;
+ // CheckStyle:VisibilityModifier ON
+
+ private Resource output;
+
+ /**
+ * Does the work.
+ *
+ * @exception BuildException if something goes wrong with the build
+ */
+ public void execute() throws BuildException {
+ final String msg = "".equals(message) ? StringUtils.LINE_SEP : message;
+ try {
+ ResourceUtils
+ .copyResource(new StringResource(msg), output == null
+ ? new LogOutputResource(this, logLevel)
+ : output,
+ null, null, false, false, append, null,
+ "".equals(encoding) ? null : encoding,
+ getProject(), force);
+ } catch (IOException ioe) {
+ throw new BuildException(ioe, getLocation());
+ }
+ }
+
+ /**
+ * Message to write.
+ *
+ * @param msg Sets the value for the message variable.
+ */
+ public void setMessage(String msg) {
+ this.message = msg == null ? "" : msg;
+ }
+
+ /**
+ * File to write to.
+ * @param file the file to write to, if not set, echo to
+ * standard output
+ */
+ public void setFile(File file) {
+ setOutput(new FileResource(getProject(), file));
+ }
+
+ /**
+ * Resource to write to.
+ * @param output the Resource to write to.
+ * @since Ant 1.8
+ */
+ public void setOutput(Resource output) {
+ if (this.output != null) {
+ throw new BuildException("Cannot set > 1 output target");
+ }
+ this.output = output;
+ FileProvider fp = output.as(FileProvider.class);
+ this.file = fp != null ? fp.getFile() : null;
+ }
+
+ /**
+ * If true, append to existing file.
+ * @param append if true, append to existing file, default
+ * is false.
+ */
+ public void setAppend(boolean append) {
+ this.append = append;
+ }
+
+ /**
+ * Set a multiline message.
+ * @param msg the CDATA text to append to the output text
+ */
+ public void addText(String msg) {
+ message += getProject().replaceProperties(msg);
+ }
+
+ /**
+ * Set the logging level. Level should be one of
+ * <ul>
+ * <li>error</li>
+ * <li>warning</li>
+ * <li>info</li>
+ * <li>verbose</li>
+ * <li>debug</li>
+ * </ul>
+ * <p>The default is &quot;warning&quot; to ensure that messages are
+ * displayed by default when using the -quiet command line option.</p>
+ * @param echoLevel the logging level
+ */
+ public void setLevel(EchoLevel echoLevel) {
+ logLevel = echoLevel.getLevel();
+ }
+
+ /**
+ * Declare the encoding to use when outputting to a file;
+ * Use "" for the platform's default encoding.
+ * @param encoding the character encoding to use.
+ * @since 1.7
+ */
+ public void setEncoding(String encoding) {
+ this.encoding = encoding;
+ }
+
+ /**
+ * Whether read-only destinations will be overwritten.
+ *
+ * <p>Defaults to false</p>
+ *
+ * @since Ant 1.8.2
+ */
+ public void setForce(boolean f) {
+ force = f;
+ }
+
+ /**
+ * The enumerated values for the level attribute.
+ */
+ public static class EchoLevel extends LogLevel {
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/EchoXML.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/EchoXML.java
new file mode 100644
index 00000000..4a4fda29
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/EchoXML.java
@@ -0,0 +1,137 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.OutputStream;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.EnumeratedAttribute;
+import org.apache.tools.ant.util.DOMElementWriter;
+import org.apache.tools.ant.util.FileUtils;
+import org.apache.tools.ant.util.XMLFragment;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+/**
+ * Echo XML.
+ *
+ * Known limitations:
+ * <ol>
+ * <li>Processing Instructions get ignored</li>
+ * <li>Encoding is always UTF-8</li>
+ * </ol>
+ *
+ * @since Ant 1.7
+ */
+public class EchoXML extends XMLFragment {
+
+ private File file;
+ private boolean append;
+ private NamespacePolicy namespacePolicy = NamespacePolicy.DEFAULT;
+ private static final String ERROR_NO_XML = "No nested XML specified";
+
+ /**
+ * Set the output file.
+ * @param f the output file.
+ */
+ public void setFile(File f) {
+ file = f;
+ }
+
+ /**
+ * Set the namespace policy for the xml file
+ * @param n namespace policy: "ignore," "elementsOnly," or "all"
+ * @see
+ * org.apache.tools.ant.util.DOMElementWriter.XmlNamespacePolicy
+ */
+ public void setNamespacePolicy(NamespacePolicy n) {
+ namespacePolicy = n;
+ }
+
+ /**
+ * Set whether to append the output file.
+ * @param b boolean append flag.
+ */
+ public void setAppend(boolean b) {
+ append = b;
+ }
+
+ /**
+ * Execute the task.
+ */
+ public void execute() {
+ DOMElementWriter writer =
+ new DOMElementWriter(!append, namespacePolicy.getPolicy());
+ OutputStream os = null;
+ try {
+ if (file != null) {
+ os = new FileOutputStream(file.getAbsolutePath(), append);
+ } else {
+ os = new LogOutputStream(this, Project.MSG_INFO);
+ }
+ Node n = getFragment().getFirstChild();
+ if (n == null) {
+ throw new BuildException(ERROR_NO_XML);
+ }
+ writer.write((Element) n, os);
+ } catch (BuildException e) {
+ throw e;
+ } catch (Exception e) {
+ throw new BuildException(e);
+ } finally {
+ FileUtils.close(os);
+ }
+ }
+
+ public static class NamespacePolicy extends EnumeratedAttribute {
+ private static final String IGNORE = "ignore";
+ private static final String ELEMENTS = "elementsOnly";
+ private static final String ALL = "all";
+
+ public static final NamespacePolicy DEFAULT
+ = new NamespacePolicy(IGNORE);
+
+ public NamespacePolicy() {}
+
+ public NamespacePolicy(String s) {
+ setValue(s);
+ }
+ /** {@inheritDoc}. */
+ @Override
+ public String[] getValues() {
+ return new String[] {IGNORE, ELEMENTS, ALL};
+ }
+
+ public DOMElementWriter.XmlNamespacePolicy getPolicy() {
+ String s = getValue();
+ if (IGNORE.equalsIgnoreCase(s)) {
+ return DOMElementWriter.XmlNamespacePolicy.IGNORE;
+ } else if (ELEMENTS.equalsIgnoreCase(s)) {
+ return
+ DOMElementWriter.XmlNamespacePolicy.ONLY_QUALIFY_ELEMENTS;
+ } else if (ALL.equalsIgnoreCase(s)) {
+ return DOMElementWriter.XmlNamespacePolicy.QUALIFY_ALL;
+ } else {
+ throw new BuildException("Invalid namespace policy: " + s);
+ }
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Exec.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Exec.java
new file mode 100644
index 00000000..cfc6b76c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Exec.java
@@ -0,0 +1,281 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.util.Locale;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.MagicNames;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+
+/**
+ * Executes a given command if the os platform is appropriate.
+ *
+ * <p><strong>As of Ant 1.2, this class is no longer the
+ * implementation of Ant's &lt;exec&gt; task - it is considered to be
+ * dead code by the Ant developers and is unmaintained. Don't use
+ * it.</strong></p>
+ *
+ * @deprecated since 1.2.
+ * delegate to {@link org.apache.tools.ant.taskdefs.Execute Execute}
+ * instead.
+ */
+public class Exec extends Task {
+ private String os;
+ private String out;
+ private File dir;
+ private String command;
+ // CheckStyle:VisibilityModifier OFF - bc
+ protected PrintWriter fos = null;
+ // CheckStyle:VisibilityModifier ON
+ private boolean failOnError = false;
+
+ /**
+ * Constructor for Exec.
+ * Prints a warning message to std error.
+ */
+ public Exec() {
+ System.err.println("As of Ant 1.2 released in October 2000, "
+ + "the Exec class");
+ System.err.println("is considered to be dead code by the Ant "
+ + "developers and is unmaintained.");
+ System.err.println("Don\'t use it!");
+ }
+
+ /**
+ * Execute the task.
+ * @throws BuildException on error
+ */
+ public void execute() throws BuildException {
+ run(command);
+ }
+
+ /**
+ * Execute the command.
+ * @param command the command to exec
+ * @return the exit value of the command
+ * @throws BuildException on error
+ */
+ protected int run(String command) throws BuildException {
+
+ int err = -1; // assume the worst
+
+ // test if os match
+ String myos = System.getProperty("os.name");
+ log("Myos = " + myos, Project.MSG_VERBOSE);
+ if ((os != null) && (os.indexOf(myos) < 0)) {
+ // this command will be executed only on the specified OS
+ log("Not found in " + os, Project.MSG_VERBOSE);
+ return 0;
+ }
+
+ // default directory to the project's base directory
+ if (dir == null) {
+ dir = getProject().getBaseDir();
+ }
+
+ if (myos.toLowerCase(Locale.ENGLISH).indexOf("windows") >= 0) {
+ if (!dir.equals(getProject().resolveFile("."))) {
+ if (myos.toLowerCase(Locale.ENGLISH).indexOf("nt") >= 0) {
+ command = "cmd /c cd " + dir + " && " + command;
+ } else {
+ String ant = getProject().getProperty(MagicNames.ANT_HOME);
+ if (ant == null) {
+ throw new BuildException("Property '" + MagicNames.ANT_HOME + "' not "
+ + "found", getLocation());
+ }
+
+ String antRun = getProject().resolveFile(ant + "/bin/antRun.bat").toString();
+ command = antRun + " " + dir + " " + command;
+ }
+ }
+ } else {
+ String ant = getProject().getProperty(MagicNames.ANT_HOME);
+ if (ant == null) {
+ throw new BuildException("Property '" + MagicNames.ANT_HOME + "' not found",
+ getLocation());
+ }
+ String antRun = getProject().resolveFile(ant + "/bin/antRun").toString();
+
+ command = antRun + " " + dir + " " + command;
+ }
+
+ try {
+ // show the command
+ log(command, Project.MSG_VERBOSE);
+
+ // exec command on system runtime
+ Process proc = Runtime.getRuntime().exec(command);
+
+ if (out != null) {
+ fos = new PrintWriter(new FileWriter(out));
+ log("Output redirected to " + out, Project.MSG_VERBOSE);
+ }
+
+ // copy input and error to the output stream
+ StreamPumper inputPumper =
+ new StreamPumper(proc.getInputStream(), Project.MSG_INFO);
+ StreamPumper errorPumper =
+ new StreamPumper(proc.getErrorStream(), Project.MSG_WARN);
+
+ // starts pumping away the generated output/error
+ inputPumper.start();
+ errorPumper.start();
+
+ // Wait for everything to finish
+ proc.waitFor();
+ inputPumper.join();
+ errorPumper.join();
+ proc.destroy();
+
+ // close the output file if required
+ logFlush();
+
+ // check its exit value
+ err = proc.exitValue();
+ if (err != 0) {
+ if (failOnError) {
+ throw new BuildException("Exec returned: " + err, getLocation());
+ } else {
+ log("Result: " + err, Project.MSG_ERR);
+ }
+ }
+ } catch (IOException ioe) {
+ throw new BuildException("Error exec: " + command, ioe, getLocation());
+ } catch (InterruptedException ex) {
+ //ignore
+ }
+
+ return err;
+ }
+
+ /**
+ * Set the directory.
+ * @param d a <code>String</code> value
+ */
+ public void setDir(String d) {
+ this.dir = getProject().resolveFile(d);
+ }
+
+ /**
+ * Set the Operating System that this exec is to run in.
+ * @param os a <code>String</code> value
+ */
+ public void setOs(String os) {
+ this.os = os;
+ }
+
+ /**
+ * Set the command to exec.
+ * @param command a <code>String</code> value
+ */
+ public void setCommand(String command) {
+ this.command = command;
+ }
+
+ /**
+ * Set the output filename.
+ * @param out a <code>String</code> value
+ */
+ public void setOutput(String out) {
+ this.out = out;
+ }
+
+ /**
+ * Set the failOnError attribute.
+ * Default is false.
+ * @param fail a <code>boolean</code> value
+ */
+ public void setFailonerror(boolean fail) {
+ failOnError = fail;
+ }
+
+ /**
+ * Log an output message.
+ * @param line the line to putput
+ * @param messageLevel the level of logging - ignored
+ * if output is going to a file
+ */
+ protected void outputLog(String line, int messageLevel) {
+ if (fos == null) {
+ log(line, messageLevel);
+ } else {
+ fos.println(line);
+ }
+ }
+
+ /**
+ * Close output.
+ */
+ protected void logFlush() {
+ if (fos != null) {
+ fos.close();
+ }
+ }
+
+ // Inner class for continually pumping the input stream during
+ // Process's runtime.
+ class StreamPumper extends Thread {
+ private BufferedReader din;
+ private int messageLevel;
+ private boolean endOfStream = false;
+ private static final int SLEEP_TIME = 5;
+
+ public StreamPumper(InputStream is, int messageLevel) {
+ this.din = new BufferedReader(new InputStreamReader(is));
+ this.messageLevel = messageLevel;
+ }
+
+ public void pumpStream() throws IOException {
+ if (!endOfStream) {
+ String line = din.readLine();
+
+ if (line != null) {
+ outputLog(line, messageLevel);
+ } else {
+ endOfStream = true;
+ }
+ }
+ }
+
+ public void run() {
+ try {
+ try {
+ while (!endOfStream) {
+ pumpStream();
+ sleep(SLEEP_TIME);
+ }
+ } catch (InterruptedException ie) {
+ //ignore
+ }
+ din.close();
+ } catch (IOException ioe) {
+ // ignore
+ }
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/ExecTask.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/ExecTask.java
new file mode 100644
index 00000000..dd93978f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/ExecTask.java
@@ -0,0 +1,726 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Locale;
+import java.util.Map;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.taskdefs.condition.Os;
+import org.apache.tools.ant.types.Commandline;
+import org.apache.tools.ant.types.Environment;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.types.RedirectorElement;
+import org.apache.tools.ant.util.FileUtils;
+
+/**
+ * Executes a given command if the os platform is appropriate.
+ *
+ * @since Ant 1.2
+ *
+ * @ant.task category="control"
+ */
+public class ExecTask extends Task {
+
+ private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+
+ private String os;
+ private String osFamily;
+
+ private File dir;
+ // CheckStyle:VisibilityModifier OFF - bc
+ protected boolean failOnError = false;
+ protected boolean newEnvironment = false;
+ private Long timeout = null;
+ private Environment env = new Environment();
+ protected Commandline cmdl = new Commandline();
+ private String resultProperty;
+ private boolean failIfExecFails = true;
+ private String executable;
+ private boolean resolveExecutable = false;
+ private boolean searchPath = false;
+ private boolean spawn = false;
+ private boolean incompatibleWithSpawn = false;
+
+ //include locally for screening purposes
+ private String inputString;
+ private File input;
+ private File output;
+ private File error;
+
+ protected Redirector redirector = new Redirector(this);
+ protected RedirectorElement redirectorElement;
+ // CheckStyle:VisibilityModifier ON
+
+ /**
+ * Controls whether the VM (1.3 and above) is used to execute the
+ * command
+ */
+ private boolean vmLauncher = true;
+
+
+ /**
+ * Create an instance.
+ * Needs to be configured by binding to a project.
+ */
+ public ExecTask() {
+ }
+
+ /**
+ * create an instance that is helping another task.
+ * Project, OwningTarget, TaskName and description are all
+ * pulled out
+ * @param owner task that we belong to
+ */
+ public ExecTask(Task owner) {
+ bindToOwner(owner);
+ }
+
+ /**
+ * Set whether or not you want the process to be spawned.
+ * Default is false.
+ * @param spawn if true you do not want Ant to wait for the end of the process.
+ * @since Ant 1.6
+ */
+ public void setSpawn(boolean spawn) {
+ this.spawn = spawn;
+ }
+
+ /**
+ * Set the timeout in milliseconds after which the process will be killed.
+ *
+ * @param value timeout in milliseconds.
+ *
+ * @since Ant 1.5
+ */
+ public void setTimeout(Long value) {
+ timeout = value;
+ incompatibleWithSpawn |= timeout != null;
+ }
+
+ /**
+ * Set the timeout in milliseconds after which the process will be killed.
+ *
+ * @param value timeout in milliseconds.
+ */
+ public void setTimeout(Integer value) {
+ setTimeout(
+ (Long) ((value == null) ? null : new Long(value.intValue())));
+ }
+
+ /**
+ * Set the name of the executable program.
+ * @param value the name of the executable program.
+ */
+ public void setExecutable(String value) {
+ this.executable = value;
+ cmdl.setExecutable(value);
+ }
+
+ /**
+ * Set the working directory of the process.
+ * @param d the working directory of the process.
+ */
+ public void setDir(File d) {
+ this.dir = d;
+ }
+
+ /**
+ * List of operating systems on which the command may be executed.
+ * @param os list of operating systems on which the command may be executed.
+ */
+ public void setOs(String os) {
+ this.os = os;
+ }
+
+ /**
+ * List of operating systems on which the command may be executed.
+ * @since Ant 1.8.0
+ */
+ public final String getOs() {
+ return os;
+ }
+
+ /**
+ * Sets a command line.
+ * @param cmdl command line.
+ * @ant.attribute ignore="true"
+ */
+ public void setCommand(Commandline cmdl) {
+ log("The command attribute is deprecated.\n"
+ + "Please use the executable attribute and nested arg elements.",
+ Project.MSG_WARN);
+ this.cmdl = cmdl;
+ }
+
+ /**
+ * File the output of the process is redirected to. If error is not
+ * redirected, it too will appear in the output.
+ *
+ * @param out name of a file to which output should be sent.
+ */
+ public void setOutput(File out) {
+ this.output = out;
+ incompatibleWithSpawn = true;
+ }
+
+ /**
+ * Set the input file to use for the task.
+ *
+ * @param input name of a file from which to get input.
+ */
+ public void setInput(File input) {
+ if (inputString != null) {
+ throw new BuildException("The \"input\" and \"inputstring\" "
+ + "attributes cannot both be specified");
+ }
+ this.input = input;
+ incompatibleWithSpawn = true;
+ }
+
+ /**
+ * Set the string to use as input.
+ *
+ * @param inputString the string which is used as the input source.
+ */
+ public void setInputString(String inputString) {
+ if (input != null) {
+ throw new BuildException("The \"input\" and \"inputstring\" "
+ + "attributes cannot both be specified");
+ }
+ this.inputString = inputString;
+ incompatibleWithSpawn = true;
+ }
+
+ /**
+ * Controls whether error output of exec is logged. This is only useful when
+ * output is being redirected and error output is desired in the Ant log.
+ *
+ * @param logError set to true to log error output in the normal ant log.
+ */
+ public void setLogError(boolean logError) {
+ redirector.setLogError(logError);
+ incompatibleWithSpawn |= logError;
+ }
+
+ /**
+ * Set the File to which the error stream of the process should be redirected.
+ *
+ * @param error a file to which stderr should be sent.
+ *
+ * @since Ant 1.6
+ */
+ public void setError(File error) {
+ this.error = error;
+ incompatibleWithSpawn = true;
+ }
+
+ /**
+ * Sets the property name whose value should be set to the output of
+ * the process.
+ *
+ * @param outputProp name of property.
+ */
+ public void setOutputproperty(String outputProp) {
+ redirector.setOutputProperty(outputProp);
+ incompatibleWithSpawn = true;
+ }
+
+ /**
+ * Sets the name of the property whose value should be set to the error of
+ * the process.
+ *
+ * @param errorProperty name of property.
+ *
+ * @since Ant 1.6
+ */
+ public void setErrorProperty(String errorProperty) {
+ redirector.setErrorProperty(errorProperty);
+ incompatibleWithSpawn = true;
+ }
+
+ /**
+ * Fail if the command exits with a non-zero return code.
+ *
+ * @param fail if true fail the command on non-zero return code.
+ */
+ public void setFailonerror(boolean fail) {
+ failOnError = fail;
+ incompatibleWithSpawn |= fail;
+ }
+
+ /**
+ * Do not propagate old environment when new environment variables are specified.
+ *
+ * @param newenv if true, do not propagate old environment
+ * when new environment variables are specified.
+ */
+ public void setNewenvironment(boolean newenv) {
+ newEnvironment = newenv;
+ }
+
+ /**
+ * Set whether to attempt to resolve the executable to a file.
+ *
+ * @param resolveExecutable if true, attempt to resolve the
+ * path of the executable.
+ */
+ public void setResolveExecutable(boolean resolveExecutable) {
+ this.resolveExecutable = resolveExecutable;
+ }
+
+ /**
+ * Set whether to search nested, then
+ * system PATH environment variables for the executable.
+ *
+ * @param searchPath if true, search PATHs.
+ */
+ public void setSearchPath(boolean searchPath) {
+ this.searchPath = searchPath;
+ }
+
+ /**
+ * Indicates whether to attempt to resolve the executable to a
+ * file.
+ * @return the resolveExecutable flag
+ *
+ * @since Ant 1.6
+ */
+ public boolean getResolveExecutable() {
+ return resolveExecutable;
+ }
+
+ /**
+ * Add an environment variable to the launched process.
+ *
+ * @param var new environment variable.
+ */
+ public void addEnv(Environment.Variable var) {
+ env.addVariable(var);
+ }
+
+ /**
+ * Adds a command-line argument.
+ *
+ * @return new command line argument created.
+ */
+ public Commandline.Argument createArg() {
+ return cmdl.createArgument();
+ }
+
+ /**
+ * Sets the name of a property in which the return code of the
+ * command should be stored. Only of interest if failonerror=false.
+ *
+ * @since Ant 1.5
+ *
+ * @param resultProperty name of property.
+ */
+ public void setResultProperty(String resultProperty) {
+ this.resultProperty = resultProperty;
+ incompatibleWithSpawn = true;
+ }
+
+ /**
+ * Helper method to set result property to the
+ * passed in value if appropriate.
+ *
+ * @param result value desired for the result property value.
+ */
+ protected void maybeSetResultPropertyValue(int result) {
+ if (resultProperty != null) {
+ String res = Integer.toString(result);
+ getProject().setNewProperty(resultProperty, res);
+ }
+ }
+
+ /**
+ * Set whether to stop the build if program cannot be started.
+ * Defaults to true.
+ *
+ * @param flag stop the build if program cannot be started.
+ *
+ * @since Ant 1.5
+ */
+ public void setFailIfExecutionFails(boolean flag) {
+ failIfExecFails = flag;
+ incompatibleWithSpawn |= flag;
+ }
+
+ /**
+ * Set whether output should be appended to or overwrite an existing file.
+ * Defaults to false.
+ *
+ * @param append if true append is desired.
+ *
+ * @since 1.30, Ant 1.5
+ */
+ public void setAppend(boolean append) {
+ redirector.setAppend(append);
+ incompatibleWithSpawn |= append;
+ }
+
+ /**
+ * Add a <code>RedirectorElement</code> to this task.
+ *
+ * @param redirectorElement <code>RedirectorElement</code>.
+ * @since Ant 1.6.2
+ */
+ public void addConfiguredRedirector(RedirectorElement redirectorElement) {
+ if (this.redirectorElement != null) {
+ throw new BuildException("cannot have > 1 nested <redirector>s");
+ }
+ this.redirectorElement = redirectorElement;
+ incompatibleWithSpawn = true;
+ }
+
+
+ /**
+ * Restrict this execution to a single OS Family
+ * @param osFamily the family to restrict to.
+ */
+ public void setOsFamily(String osFamily) {
+ this.osFamily = osFamily.toLowerCase(Locale.ENGLISH);
+ }
+
+ /**
+ * Restrict this execution to a single OS Family
+ * @since Ant 1.8.0
+ */
+ public final String getOsFamily() {
+ return osFamily;
+ }
+
+ /**
+ * The method attempts to figure out where the executable is so that we can feed
+ * the full path. We first try basedir, then the exec dir, and then
+ * fallback to the straight executable name (i.e. on the path).
+ *
+ * @param exec the name of the executable.
+ * @param mustSearchPath if true, the executable will be looked up in
+ * the PATH environment and the absolute path is returned.
+ *
+ * @return the executable as a full path if it can be determined.
+ *
+ * @since Ant 1.6
+ */
+ protected String resolveExecutable(String exec, boolean mustSearchPath) {
+ if (!resolveExecutable) {
+ return exec;
+ }
+ // try to find the executable
+ File executableFile = getProject().resolveFile(exec);
+ if (executableFile.exists()) {
+ return executableFile.getAbsolutePath();
+ }
+ // now try to resolve against the dir if given
+ if (dir != null) {
+ executableFile = FILE_UTILS.resolveFile(dir, exec);
+ if (executableFile.exists()) {
+ return executableFile.getAbsolutePath();
+ }
+ }
+ // couldn't find it - must be on path
+ if (mustSearchPath) {
+ Path p = null;
+ String[] environment = env.getVariables();
+ if (environment != null) {
+ for (int i = 0; i < environment.length; i++) {
+ if (isPath(environment[i])) {
+ p = new Path(getProject(), getPath(environment[i]));
+ break;
+ }
+ }
+ }
+ if (p == null) {
+ String path = getPath(Execute.getEnvironmentVariables());
+ if (path != null) {
+ p = new Path(getProject(), path);
+ }
+ }
+ if (p != null) {
+ String[] dirs = p.list();
+ for (int i = 0; i < dirs.length; i++) {
+ executableFile
+ = FILE_UTILS.resolveFile(new File(dirs[i]), exec);
+ if (executableFile.exists()) {
+ return executableFile.getAbsolutePath();
+ }
+ }
+ }
+ }
+ // mustSearchPath is false, or no PATH or not found - keep our
+ // fingers crossed.
+ return exec;
+ }
+
+ /**
+ * Do the work.
+ *
+ * @throws BuildException in a number of circumstances:
+ * <ul>
+ * <li>if failIfExecFails is set to true and the process cannot be started</li>
+ * <li>the java13command launcher can send build exceptions</li>
+ * <li>this list is not exhaustive or limitative</li>
+ * </ul>
+ */
+ public void execute() throws BuildException {
+ // Quick fail if this is not a valid OS for the command
+ if (!isValidOs()) {
+ return;
+ }
+ File savedDir = dir; // possibly altered in prepareExec
+ cmdl.setExecutable(resolveExecutable(executable, searchPath));
+ checkConfiguration();
+ try {
+ runExec(prepareExec());
+ } finally {
+ dir = savedDir;
+ }
+ }
+
+ /**
+ * Has the user set all necessary attributes?
+ * @throws BuildException if there are missing required parameters.
+ */
+ protected void checkConfiguration() throws BuildException {
+ if (cmdl.getExecutable() == null) {
+ throw new BuildException("no executable specified", getLocation());
+ }
+ if (dir != null && !dir.exists()) {
+ throw new BuildException("The directory " + dir + " does not exist");
+ }
+ if (dir != null && !dir.isDirectory()) {
+ throw new BuildException(dir + " is not a directory");
+ }
+ if (spawn && incompatibleWithSpawn) {
+ getProject().log("spawn does not allow attributes related to input, "
+ + "output, error, result", Project.MSG_ERR);
+ getProject().log("spawn also does not allow timeout", Project.MSG_ERR);
+ getProject().log("finally, spawn is not compatible "
+ + "with a nested I/O <redirector>", Project.MSG_ERR);
+ throw new BuildException("You have used an attribute "
+ + "or nested element which is not compatible with spawn");
+ }
+ setupRedirector();
+ }
+
+ /**
+ * Set up properties on the redirector that we needed to store locally.
+ */
+ protected void setupRedirector() {
+ redirector.setInput(input);
+ redirector.setInputString(inputString);
+ redirector.setOutput(output);
+ redirector.setError(error);
+ }
+
+ /**
+ * Is this the OS the user wanted?
+ * @return boolean.
+ * <ul>
+ * <li>
+ * <li><code>true</code> if the os and osfamily attributes are null.</li>
+ * <li><code>true</code> if osfamily is set, and the os family and must match
+ * that of the current OS, according to the logic of
+ * {@link Os#isOs(String, String, String, String)}, and the result of the
+ * <code>os</code> attribute must also evaluate true.
+ * </li>
+ * <li>
+ * <code>true</code> if os is set, and the system.property os.name
+ * is found in the os attribute,</li>
+ * <li><code>false</code> otherwise.</li>
+ * </ul>
+ */
+ protected boolean isValidOs() {
+ //hand osfamily off to Os class, if set
+ if (osFamily != null && !Os.isFamily(osFamily)) {
+ return false;
+ }
+ //the Exec OS check is different from Os.isOs(), which
+ //probes for a specific OS. Instead it searches the os field
+ //for the current os.name
+ String myos = System.getProperty("os.name");
+ log("Current OS is " + myos, Project.MSG_VERBOSE);
+ if ((os != null) && (os.indexOf(myos) < 0)) {
+ // this command will be executed only on the specified OS
+ log("This OS, " + myos
+ + " was not found in the specified list of valid OSes: " + os,
+ Project.MSG_VERBOSE);
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Set whether to launch new process with VM, otherwise use the OS's shell.
+ * Default value is true.
+ * @param vmLauncher true if we want to launch new process with VM,
+ * false if we want to use the OS's shell.
+ */
+ public void setVMLauncher(boolean vmLauncher) {
+ this.vmLauncher = vmLauncher;
+ }
+
+ /**
+ * Create an Execute instance with the correct working directory set.
+ *
+ * @return an instance of the Execute class.
+ *
+ * @throws BuildException under unknown circumstances.
+ */
+ protected Execute prepareExec() throws BuildException {
+ // default directory to the project's base directory
+ if (dir == null) {
+ dir = getProject().getBaseDir();
+ }
+ if (redirectorElement != null) {
+ redirectorElement.configure(redirector);
+ }
+ Execute exe = new Execute(createHandler(), createWatchdog());
+ exe.setAntRun(getProject());
+ exe.setWorkingDirectory(dir);
+ exe.setVMLauncher(vmLauncher);
+ String[] environment = env.getVariables();
+ if (environment != null) {
+ for (int i = 0; i < environment.length; i++) {
+ log("Setting environment variable: " + environment[i],
+ Project.MSG_VERBOSE);
+ }
+ }
+ exe.setNewenvironment(newEnvironment);
+ exe.setEnvironment(environment);
+ return exe;
+ }
+
+ /**
+ * A Utility method for this classes and subclasses to run an
+ * Execute instance (an external command).
+ *
+ * @param exe instance of the execute class.
+ *
+ * @throws IOException in case of problem to attach to the stdin/stdout/stderr
+ * streams of the process.
+ */
+ protected final void runExecute(Execute exe) throws IOException {
+ int returnCode = -1; // assume the worst
+
+ if (!spawn) {
+ returnCode = exe.execute();
+
+ //test for and handle a forced process death
+ if (exe.killedProcess()) {
+ String msg = "Timeout: killed the sub-process";
+ if (failOnError) {
+ throw new BuildException(msg);
+ } else {
+ log(msg, Project.MSG_WARN);
+ }
+ }
+ maybeSetResultPropertyValue(returnCode);
+ redirector.complete();
+ if (Execute.isFailure(returnCode)) {
+ if (failOnError) {
+ throw new BuildException(getTaskType() + " returned: "
+ + returnCode, getLocation());
+ } else {
+ log("Result: " + returnCode, Project.MSG_ERR);
+ }
+ }
+ } else {
+ exe.spawn();
+ }
+ }
+
+ /**
+ * Run the command using the given Execute instance. This may be
+ * overridden by subclasses.
+ *
+ * @param exe instance of Execute to run.
+ *
+ * @throws BuildException if the new process could not be started
+ * only if failIfExecFails is set to true (the default).
+ */
+ protected void runExec(Execute exe) throws BuildException {
+ // show the command
+ log(cmdl.describeCommand(), Project.MSG_VERBOSE);
+
+ exe.setCommandline(cmdl.getCommandline());
+ try {
+ runExecute(exe);
+ } catch (IOException e) {
+ if (failIfExecFails) {
+ throw new BuildException("Execute failed: " + e.toString(), e,
+ getLocation());
+ } else {
+ log("Execute failed: " + e.toString(), Project.MSG_ERR);
+ }
+ } finally {
+ // close the output file if required
+ logFlush();
+ }
+ }
+
+ /**
+ * Create the StreamHandler to use with our Execute instance.
+ *
+ * @return instance of ExecuteStreamHandler.
+ *
+ * @throws BuildException under unknown circumstances.
+ */
+ protected ExecuteStreamHandler createHandler() throws BuildException {
+ return redirector.createHandler();
+ }
+
+ /**
+ * Create the Watchdog to kill a runaway process.
+ *
+ * @return instance of ExecuteWatchdog.
+ *
+ * @throws BuildException under unknown circumstances.
+ */
+ protected ExecuteWatchdog createWatchdog() throws BuildException {
+ return (timeout == null)
+ ? null : new ExecuteWatchdog(timeout.longValue());
+ }
+
+ /**
+ * Flush the output stream - if there is one.
+ */
+ protected void logFlush() {
+ }
+
+ private boolean isPath(String line) {
+ return line.startsWith("PATH=")
+ || line.startsWith("Path=");
+ }
+
+ private String getPath(String line) {
+ return line.substring("PATH=".length());
+ }
+
+ private String getPath(Map<String, String> map) {
+ String p = map.get("PATH");
+ return p != null ? p : map.get("Path");
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Execute.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Execute.java
new file mode 100644
index 00000000..9523f453
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Execute.java
@@ -0,0 +1,734 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.taskdefs.condition.Os;
+import org.apache.tools.ant.taskdefs.launcher.CommandLauncher;
+import org.apache.tools.ant.types.Commandline;
+import org.apache.tools.ant.util.FileUtils;
+import org.apache.tools.ant.util.StringUtils;
+
+/**
+ * Runs an external program.
+ *
+ * @since Ant 1.2
+ */
+public class Execute {
+
+ private static final int ONE_SECOND = 1000;
+
+ /**
+ * Invalid exit code. set to {@link Integer#MAX_VALUE}
+ */
+ public static final int INVALID = Integer.MAX_VALUE;
+
+ private String[] cmdl = null;
+ private String[] env = null;
+ private int exitValue = INVALID;
+ private ExecuteStreamHandler streamHandler;
+ private final ExecuteWatchdog watchdog;
+ private File workingDirectory = null;
+ private Project project = null;
+ private boolean newEnvironment = false;
+
+ /** Controls whether the VM is used to launch commands, where possible. */
+ private boolean useVMLauncher = true;
+
+ private static String antWorkingDirectory = System.getProperty("user.dir");
+ private static Map<String, String> procEnvironment = null;
+
+ /** Used to destroy processes when the VM exits. */
+ private static ProcessDestroyer processDestroyer = new ProcessDestroyer();
+
+ /** Used for replacing env variables */
+ private static boolean environmentCaseInSensitive = false;
+
+ static {
+ if (Os.isFamily("windows")) {
+ environmentCaseInSensitive = true;
+ }
+ }
+
+ /**
+ * Set whether or not you want the process to be spawned.
+ * Default is not spawned.
+ *
+ * @param spawn if true you do not want Ant
+ * to wait for the end of the process.
+ * Has no influence in here, the calling task contains
+ * and acts accordingly
+ *
+ * @since Ant 1.6
+ * @deprecated
+ */
+ @Deprecated
+ public void setSpawn(boolean spawn) {
+ // Method did not do anything to begin with
+ }
+
+ /**
+ * Find the list of environment variables for this process.
+ *
+ * @return a map containing the environment variables.
+ * @since Ant 1.8.2
+ */
+ public static synchronized Map<String,String> getEnvironmentVariables() {
+ if (procEnvironment != null) {
+ return procEnvironment;
+ }
+ if (!Os.isFamily("openvms")) {
+ try {
+ procEnvironment = System.getenv();
+ return procEnvironment;
+ } catch (Exception x) {
+ x.printStackTrace();
+ }
+ }
+
+ procEnvironment = new LinkedHashMap<String, String>();
+ try {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ Execute exe = new Execute(new PumpStreamHandler(out));
+ exe.setCommandline(getProcEnvCommand());
+ // Make sure we do not recurse forever
+ exe.setNewenvironment(true);
+ int retval = exe.execute();
+ if (retval != 0) {
+ // Just try to use what we got
+ }
+ BufferedReader in =
+ new BufferedReader(new StringReader(toString(out)));
+
+ if (Os.isFamily("openvms")) {
+ procEnvironment = getVMSLogicals(in);
+ return procEnvironment;
+ }
+ String var = null;
+ String line, lineSep = StringUtils.LINE_SEP;
+ while ((line = in.readLine()) != null) {
+ if (line.indexOf('=') == -1) {
+ // Chunk part of previous env var (UNIX env vars can
+ // contain embedded new lines).
+ if (var == null) {
+ var = lineSep + line;
+ } else {
+ var += lineSep + line;
+ }
+ } else {
+ // New env var...append the previous one if we have it.
+ if (var != null) {
+ int eq = var.indexOf("=");
+ procEnvironment.put(var.substring(0, eq),
+ var.substring(eq + 1));
+ }
+ var = line;
+ }
+ }
+ // Since we "look ahead" before adding, there's one last env var.
+ if (var != null) {
+ int eq = var.indexOf("=");
+ procEnvironment.put(var.substring(0, eq), var.substring(eq + 1));
+ }
+ } catch (java.io.IOException exc) {
+ exc.printStackTrace();
+ // Just try to see how much we got
+ }
+ return procEnvironment;
+ }
+
+ /**
+ * Find the list of environment variables for this process.
+ *
+ * @return a vector containing the environment variables.
+ * The vector elements are strings formatted like variable = value.
+ * @deprecated use #getEnvironmentVariables instead
+ */
+ @Deprecated
+ public static synchronized Vector<String> getProcEnvironment() {
+ Vector<String> v = new Vector<String>();
+ for (Entry<String, String> entry : getEnvironmentVariables().entrySet()) {
+ v.add(entry.getKey() + "=" + entry.getValue());
+ }
+ return v;
+ }
+
+ /**
+ * This is the operation to get our environment.
+ * It is a notorious troublespot pre-Java1.5, and should be approached
+ * with extreme caution.
+ *
+ * @return command and arguments to get our environment
+ */
+ private static String[] getProcEnvCommand() {
+ if (Os.isFamily("os/2")) {
+ // OS/2 - use same mechanism as Windows 2000
+ return new String[] {"cmd", "/c", "set"};
+ } else if (Os.isFamily("windows")) {
+ // Determine if we're running under XP/2000/NT or 98/95
+ if (Os.isFamily("win9x")) {
+ // Windows 98/95
+ return new String[] {"command.com", "/c", "set"};
+ } else {
+ // Windows XP/2000/NT/2003
+ return new String[] {"cmd", "/c", "set"};
+ }
+ } else if (Os.isFamily("z/os") || Os.isFamily("unix")) {
+ // On most systems one could use: /bin/sh -c env
+
+ // Some systems have /bin/env, others /usr/bin/env, just try
+ String[] cmd = new String[1];
+ if (new File("/bin/env").canRead()) {
+ cmd[0] = "/bin/env";
+ } else if (new File("/usr/bin/env").canRead()) {
+ cmd[0] = "/usr/bin/env";
+ } else {
+ // rely on PATH
+ cmd[0] = "env";
+ }
+ return cmd;
+ } else if (Os.isFamily("netware") || Os.isFamily("os/400")) {
+ // rely on PATH
+ return new String[] {"env"};
+ } else if (Os.isFamily("openvms")) {
+ return new String[] {"show", "logical"};
+ } else {
+ // MAC OS 9 and previous
+ // TODO: I have no idea how to get it, someone must fix it
+ return null;
+ }
+ }
+
+ /**
+ * ByteArrayOutputStream#toString doesn't seem to work reliably on
+ * OS/390, at least not the way we use it in the execution
+ * context.
+ *
+ * @param bos the output stream that one wants to read.
+ * @return the output stream as a string, read with
+ * special encodings in the case of z/os and os/400.
+ * @since Ant 1.5
+ */
+ public static String toString(ByteArrayOutputStream bos) {
+ if (Os.isFamily("z/os")) {
+ try {
+ return bos.toString("Cp1047");
+ } catch (java.io.UnsupportedEncodingException e) {
+ // noop default encoding used
+ }
+ } else if (Os.isFamily("os/400")) {
+ try {
+ return bos.toString("Cp500");
+ } catch (java.io.UnsupportedEncodingException e) {
+ // noop default encoding used
+ }
+ }
+ return bos.toString();
+ }
+
+ /**
+ * Creates a new execute object using <code>PumpStreamHandler</code> for
+ * stream handling.
+ */
+ public Execute() {
+ this(new PumpStreamHandler(), null);
+ }
+
+ /**
+ * Creates a new execute object.
+ *
+ * @param streamHandler the stream handler used to handle the input and
+ * output streams of the subprocess.
+ */
+ public Execute(ExecuteStreamHandler streamHandler) {
+ this(streamHandler, null);
+ }
+
+ /**
+ * Creates a new execute object.
+ *
+ * @param streamHandler the stream handler used to handle the input and
+ * output streams of the subprocess.
+ * @param watchdog a watchdog for the subprocess or <code>null</code>
+ * to disable a timeout for the subprocess.
+ */
+ public Execute(ExecuteStreamHandler streamHandler,
+ ExecuteWatchdog watchdog) {
+ setStreamHandler(streamHandler);
+ this.watchdog = watchdog;
+ // By default, use the shell launcher for VMS
+ //
+ if (Os.isFamily("openvms")) {
+ useVMLauncher = false;
+ }
+ }
+
+ /**
+ * Set the stream handler to use.
+ *
+ * @param streamHandler ExecuteStreamHandler.
+ * @since Ant 1.6
+ */
+ public void setStreamHandler(ExecuteStreamHandler streamHandler) {
+ this.streamHandler = streamHandler;
+ }
+
+ /**
+ * Returns the commandline used to create a subprocess.
+ *
+ * @return the commandline used to create a subprocess.
+ */
+ public String[] getCommandline() {
+ return cmdl;
+ }
+
+ /**
+ * Sets the commandline of the subprocess to launch.
+ *
+ * @param commandline the commandline of the subprocess to launch.
+ */
+ public void setCommandline(String[] commandline) {
+ cmdl = commandline;
+ }
+
+ /**
+ * Set whether to propagate the default environment or not.
+ *
+ * @param newenv whether to propagate the process environment.
+ */
+ public void setNewenvironment(boolean newenv) {
+ newEnvironment = newenv;
+ }
+
+ /**
+ * Returns the environment used to create a subprocess.
+ *
+ * @return the environment used to create a subprocess.
+ */
+ public String[] getEnvironment() {
+ return (env == null || newEnvironment)
+ ? env : patchEnvironment();
+ }
+
+ /**
+ * Sets the environment variables for the subprocess to launch.
+ *
+ * @param env array of Strings, each element of which has
+ * an environment variable settings in format <em>key=value</em>.
+ */
+ public void setEnvironment(String[] env) {
+ this.env = env;
+ }
+
+ /**
+ * Sets the working directory of the process to execute.
+ *
+ * <p>This is emulated using the antRun scripts unless the OS is
+ * Windows NT in which case a cmd.exe is spawned,
+ * or MRJ and setting user.dir works, or JDK 1.3 and there is
+ * official support in java.lang.Runtime.
+ *
+ * @param wd the working directory of the process.
+ */
+ public void setWorkingDirectory(File wd) {
+ workingDirectory =
+ (wd == null || wd.getAbsolutePath().equals(antWorkingDirectory))
+ ? null : wd;
+ }
+
+ /**
+ * Return the working directory.
+ *
+ * @return the directory as a File.
+ * @since Ant 1.7
+ */
+ public File getWorkingDirectory() {
+ return workingDirectory == null ? new File(antWorkingDirectory)
+ : workingDirectory;
+ }
+
+ /**
+ * Set the name of the antRun script using the project's value.
+ *
+ * @param project the current project.
+ * @throws BuildException not clear when it is going to throw an exception, but
+ * it is the method's signature.
+ */
+ public void setAntRun(Project project) throws BuildException {
+ this.project = project;
+ }
+
+ /**
+ * Launch this execution through the VM, where possible, rather than through
+ * the OS's shell. In some cases and operating systems using the shell will
+ * allow the shell to perform additional processing such as associating an
+ * executable with a script, etc.
+ *
+ * @param useVMLauncher true if exec should launch through the VM,
+ * false if the shell should be used to launch the
+ * command.
+ */
+ public void setVMLauncher(boolean useVMLauncher) {
+ this.useVMLauncher = useVMLauncher;
+ }
+
+ /**
+ * Creates a process that runs a command.
+ *
+ * @param project the Project, only used for logging purposes, may be null.
+ * @param command the command to run.
+ * @param env the environment for the command.
+ * @param dir the working directory for the command.
+ * @param useVM use the built-in exec command for JDK 1.3 if available.
+ * @return the process started.
+ * @throws IOException forwarded from the particular launcher used.
+ * @since Ant 1.5
+ */
+ public static Process launch(Project project, String[] command,
+ String[] env, File dir, boolean useVM)
+ throws IOException {
+ if (dir != null && !dir.exists()) {
+ throw new BuildException(dir + " doesn't exist.");
+ }
+
+ CommandLauncher vmLauncher = CommandLauncher.getVMLauncher(project);
+ CommandLauncher launcher = (useVM && vmLauncher != null)
+ ? vmLauncher : CommandLauncher.getShellLauncher(project);
+ return launcher.exec(project, command, env, dir);
+ }
+
+ /**
+ * Runs a process defined by the command line and returns its exit status.
+ *
+ * @return the exit status of the subprocess or <code>INVALID</code>.
+ * @exception java.io.IOException The exception is thrown, if launching
+ * of the subprocess failed.
+ */
+ public int execute() throws IOException {
+ if (workingDirectory != null && !workingDirectory.exists()) {
+ throw new BuildException(workingDirectory + " doesn't exist.");
+ }
+ final Process process = launch(project, getCommandline(),
+ getEnvironment(), workingDirectory,
+ useVMLauncher);
+ try {
+ streamHandler.setProcessInputStream(process.getOutputStream());
+ streamHandler.setProcessOutputStream(process.getInputStream());
+ streamHandler.setProcessErrorStream(process.getErrorStream());
+ } catch (IOException e) {
+ process.destroy();
+ throw e;
+ }
+ streamHandler.start();
+
+ try {
+ // add the process to the list of those to destroy if the VM exits
+ //
+ processDestroyer.add(process);
+
+ if (watchdog != null) {
+ watchdog.start(process);
+ }
+ waitFor(process);
+
+ if (watchdog != null) {
+ watchdog.stop();
+ }
+ streamHandler.stop();
+ closeStreams(process);
+
+ if (watchdog != null) {
+ watchdog.checkException();
+ }
+ return getExitValue();
+ } catch (ThreadDeath t) {
+ // #31928: forcibly kill it before continuing.
+ process.destroy();
+ throw t;
+ } finally {
+ // remove the process to the list of those to destroy if
+ // the VM exits
+ //
+ processDestroyer.remove(process);
+ }
+ }
+
+ /**
+ * Starts a process defined by the command line.
+ * Ant will not wait for this process, nor log its output.
+ *
+ * @throws java.io.IOException The exception is thrown, if launching
+ * of the subprocess failed.
+ * @since Ant 1.6
+ */
+ public void spawn() throws IOException {
+ if (workingDirectory != null && !workingDirectory.exists()) {
+ throw new BuildException(workingDirectory + " doesn't exist.");
+ }
+ final Process process = launch(project, getCommandline(),
+ getEnvironment(), workingDirectory,
+ useVMLauncher);
+ if (Os.isFamily("windows")) {
+ try {
+ Thread.sleep(ONE_SECOND);
+ } catch (InterruptedException e) {
+ project.log("interruption in the sleep after having spawned a"
+ + " process", Project.MSG_VERBOSE);
+ }
+ }
+ OutputStream dummyOut = new OutputStream() {
+ @Override
+ public void write(int b) throws IOException {
+ // Method intended to swallow whatever comes at it
+ }
+ };
+
+ ExecuteStreamHandler handler = new PumpStreamHandler(dummyOut);
+ handler.setProcessErrorStream(process.getErrorStream());
+ handler.setProcessOutputStream(process.getInputStream());
+ handler.start();
+ process.getOutputStream().close();
+
+ project.log("spawned process " + process.toString(),
+ Project.MSG_VERBOSE);
+ }
+
+ /**
+ * Wait for a given process.
+ *
+ * @param process the process one wants to wait for.
+ */
+ protected void waitFor(Process process) {
+ try {
+ process.waitFor();
+ setExitValue(process.exitValue());
+ } catch (InterruptedException e) {
+ process.destroy();
+ }
+ }
+
+ /**
+ * Set the exit value.
+ *
+ * @param value exit value of the process.
+ */
+ protected void setExitValue(int value) {
+ exitValue = value;
+ }
+
+ /**
+ * Query the exit value of the process.
+ *
+ * @return the exit value or Execute.INVALID if no exit value has
+ * been received.
+ */
+ public int getExitValue() {
+ return exitValue;
+ }
+
+ /**
+ * Checks whether <code>exitValue</code> signals a failure on the current
+ * system (OS specific).
+ *
+ * <p><b>Note</b> that this method relies on the conventions of
+ * the OS, it will return false results if the application you are
+ * running doesn't follow these conventions. One notable
+ * exception is the Java VM provided by HP for OpenVMS - it will
+ * return 0 if successful (like on any other platform), but this
+ * signals a failure on OpenVMS. So if you execute a new Java VM
+ * on OpenVMS, you cannot trust this method.</p>
+ *
+ * @param exitValue the exit value (return code) to be checked.
+ * @return <code>true</code> if <code>exitValue</code> signals a failure.
+ */
+ public static boolean isFailure(int exitValue) {
+ // on openvms even exit value signals failure;
+ // for other platforms nonzero exit value signals failure
+ return Os.isFamily("openvms")
+ ? (exitValue % 2 == 0) : (exitValue != 0);
+ }
+
+ /**
+ * Did this execute return in a failure.
+ *
+ * @see #isFailure(int)
+ * @return true if and only if the exit code is interpreted as a failure
+ * @since Ant1.7
+ */
+ public boolean isFailure() {
+ return isFailure(getExitValue());
+ }
+
+ /**
+ * Test for an untimely death of the process.
+ *
+ * @return true if a watchdog had to kill the process.
+ * @since Ant 1.5
+ */
+ public boolean killedProcess() {
+ return watchdog != null && watchdog.killedProcess();
+ }
+
+ /**
+ * Patch the current environment with the new values from the user.
+ *
+ * @return the patched environment.
+ */
+ private String[] patchEnvironment() {
+ // On OpenVMS Runtime#exec() doesn't support the environment array,
+ // so we only return the new values which then will be set in
+ // the generated DCL script, inheriting the parent process environment
+ if (Os.isFamily("openvms")) {
+ return env;
+ }
+ Map<String, String> osEnv =
+ new LinkedHashMap<String, String>(getEnvironmentVariables());
+ for (int i = 0; i < env.length; i++) {
+ String keyValue = env[i];
+ String key = keyValue.substring(0, keyValue.indexOf('='));
+ // Find the key in the current environment copy
+ // and remove it.
+
+ // Try without changing case first
+ if (osEnv.remove(key) == null && environmentCaseInSensitive) {
+ // not found, maybe perform a case insensitive search
+
+ for (String osEnvItem : osEnv.keySet()) {
+ // Nb: using default locale as key is a env name
+ if (osEnvItem.toLowerCase().equals(key.toLowerCase())) {
+ // Use the original casiness of the key
+ key = osEnvItem;
+ break;
+ }
+ }
+ }
+
+ // Add the key to the enviromnent copy
+ osEnv.put(key, keyValue.substring(key.length() + 1));
+ }
+
+ ArrayList<String> l = new ArrayList<String>();
+ for (Entry<String, String> entry : osEnv.entrySet()) {
+ l.add(entry.getKey() + "=" + entry.getValue());
+ }
+ return l.toArray(new String[osEnv.size()]);
+ }
+
+ /**
+ * A utility method that runs an external command. Writes the output and
+ * error streams of the command to the project log.
+ *
+ * @param task The task that the command is part of. Used for logging
+ * @param cmdline The command to execute.
+ * @throws BuildException if the command does not exit successfully.
+ */
+ public static void runCommand(Task task, String[] cmdline)
+ throws BuildException {
+ try {
+ task.log(Commandline.describeCommand(cmdline),
+ Project.MSG_VERBOSE);
+ Execute exe = new Execute(
+ new LogStreamHandler(task, Project.MSG_INFO, Project.MSG_ERR));
+ exe.setAntRun(task.getProject());
+ exe.setCommandline(cmdline);
+ int retval = exe.execute();
+ if (isFailure(retval)) {
+ throw new BuildException(cmdline[0]
+ + " failed with return code " + retval, task.getLocation());
+ }
+ } catch (java.io.IOException exc) {
+ throw new BuildException("Could not launch " + cmdline[0] + ": "
+ + exc, task.getLocation());
+ }
+ }
+
+ /**
+ * Close the streams belonging to the given Process.
+ *
+ * @param process the <code>Process</code>.
+ */
+ public static void closeStreams(Process process) {
+ FileUtils.close(process.getInputStream());
+ FileUtils.close(process.getOutputStream());
+ FileUtils.close(process.getErrorStream());
+ }
+
+ /**
+ * This method is VMS specific and used by getEnvironmentVariables().
+ *
+ * Parses VMS logicals from <code>in</code> and returns them as a Map.
+ * <code>in</code> is expected to be the
+ * output of "SHOW LOGICAL". The method takes care of parsing the output
+ * correctly as well as making sure that a logical defined in multiple
+ * tables only gets added from the highest order table. Logicals with
+ * multiple equivalence names are mapped to a variable with multiple
+ * values separated by a comma (,).
+ */
+ private static Map<String, String> getVMSLogicals(BufferedReader in)
+ throws IOException {
+ HashMap<String, String> logicals = new HashMap<String, String>();
+ String logName = null, logValue = null, newLogName;
+ String line = null;
+ // CheckStyle:MagicNumber OFF
+ while ((line = in.readLine()) != null) {
+ // parse the VMS logicals into required format ("VAR=VAL[,VAL2]")
+ if (line.startsWith("\t=")) {
+ // further equivalence name of previous logical
+ if (logName != null) {
+ logValue += "," + line.substring(4, line.length() - 1);
+ }
+ } else if (line.startsWith(" \"")) {
+ // new logical?
+ if (logName != null) {
+ logicals.put(logName, logValue);
+ }
+ int eqIndex = line.indexOf('=');
+ newLogName = line.substring(3, eqIndex - 2);
+ if (logicals.containsKey(newLogName)) {
+ // already got this logical from a higher order table
+ logName = null;
+ } else {
+ logName = newLogName;
+ logValue = line.substring(eqIndex + 3, line.length() - 1);
+ }
+ }
+ }
+ // CheckStyle:MagicNumber ON
+ // Since we "look ahead" before adding, there's one last env var.
+ if (logName != null) {
+ logicals.put(logName, logValue);
+ }
+ return logicals;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/ExecuteJava.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/ExecuteJava.java
new file mode 100644
index 00000000..b78b9a6a
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/ExecuteJava.java
@@ -0,0 +1,331 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+
+import org.apache.tools.ant.AntClassLoader;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.ProjectComponent;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.taskdefs.condition.Os;
+import org.apache.tools.ant.types.Commandline;
+import org.apache.tools.ant.types.CommandlineJava;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.types.Permissions;
+import org.apache.tools.ant.util.JavaEnvUtils;
+import org.apache.tools.ant.util.TimeoutObserver;
+import org.apache.tools.ant.util.Watchdog;
+
+/**
+ * Execute a Java class.
+ * @since Ant 1.2
+ */
+public class ExecuteJava implements Runnable, TimeoutObserver {
+
+ private Commandline javaCommand = null;
+ private Path classpath = null;
+ private CommandlineJava.SysProperties sysProperties = null;
+ private Permissions perm = null;
+ private Method main = null;
+ private Long timeout = null;
+ private volatile Throwable caught = null;
+ private volatile boolean timedOut = false;
+ private Thread thread = null;
+
+ /**
+ * Set the Java "command" for this ExecuteJava.
+ * @param javaCommand the classname and arguments in a Commandline.
+ */
+ public void setJavaCommand(Commandline javaCommand) {
+ this.javaCommand = javaCommand;
+ }
+
+ /**
+ * Set the classpath to be used when running the Java class.
+ *
+ * @param p an Ant Path object containing the classpath.
+ */
+ public void setClasspath(Path p) {
+ classpath = p;
+ }
+
+ /**
+ * Set the system properties to use when running the Java class.
+ * @param s CommandlineJava system properties.
+ */
+ public void setSystemProperties(CommandlineJava.SysProperties s) {
+ sysProperties = s;
+ }
+
+ /**
+ * Set the permissions for the application run.
+ * @param permissions the Permissions to use.
+ * @since Ant 1.6
+ */
+ public void setPermissions(Permissions permissions) {
+ perm = permissions;
+ }
+
+ /**
+ * Set the stream to which all output (System.out as well as System.err)
+ * will be written.
+ * @param out the PrintStream where output should be sent.
+ * @deprecated since 1.4.x.
+ * manage output at the task level.
+ */
+ public void setOutput(PrintStream out) {
+ }
+
+ /**
+ * Set the timeout for this ExecuteJava.
+ * @param timeout timeout as Long.
+ * @since Ant 1.5
+ */
+ public void setTimeout(Long timeout) {
+ this.timeout = timeout;
+ }
+
+ /**
+ * Execute the Java class against the specified Ant Project.
+ * @param project the Project to use.
+ * @throws BuildException on error.
+ */
+ public void execute(Project project) throws BuildException {
+ final String classname = javaCommand.getExecutable();
+
+ AntClassLoader loader = null;
+ try {
+ if (sysProperties != null) {
+ sysProperties.setSystem();
+ }
+ Class<?> target = null;
+ try {
+ if (classpath == null) {
+ target = Class.forName(classname);
+ } else {
+ loader = project.createClassLoader(classpath);
+ loader.setParent(project.getCoreLoader());
+ loader.setParentFirst(false);
+ loader.addJavaLibraries();
+ loader.setIsolated(true);
+ loader.setThreadContextLoader();
+ loader.forceLoadClass(classname);
+ target = Class.forName(classname, true, loader);
+ }
+ } catch (ClassNotFoundException e) {
+ throw new BuildException("Could not find " + classname + "."
+ + " Make sure you have it in your"
+ + " classpath");
+ }
+ main = target.getMethod("main", new Class[] {String[].class});
+ if (main == null) {
+ throw new BuildException("Could not find main() method in "
+ + classname);
+ }
+ if ((main.getModifiers() & Modifier.STATIC) == 0) {
+ throw new BuildException("main() method in " + classname
+ + " is not declared static");
+ }
+ if (timeout == null) {
+ run();
+ } else {
+ thread = new Thread(this, "ExecuteJava");
+ Task currentThreadTask
+ = project.getThreadTask(Thread.currentThread());
+ // TODO is the following really necessary? it is in the same thread group...
+ project.registerThreadTask(thread, currentThreadTask);
+ // if we run into a timeout, the run-away thread shall not
+ // make the VM run forever - if no timeout occurs, Ant's
+ // main thread will still be there to let the new thread
+ // finish
+ thread.setDaemon(true);
+ Watchdog w = new Watchdog(timeout.longValue());
+ w.addTimeoutObserver(this);
+ synchronized (this) {
+ thread.start();
+ w.start();
+ try {
+ wait();
+ } catch (InterruptedException e) {
+ // ignore
+ }
+ if (timedOut) {
+ project.log("Timeout: sub-process interrupted",
+ Project.MSG_WARN);
+ } else {
+ thread = null;
+ w.stop();
+ }
+ }
+ }
+ if (caught != null) {
+ throw caught;
+ }
+ } catch (BuildException e) {
+ throw e;
+ } catch (SecurityException e) {
+ throw e;
+ } catch (ThreadDeath e) {
+ // TODO could perhaps also call thread.stop(); not sure if anyone cares
+ throw e;
+ } catch (Throwable e) {
+ throw new BuildException(e);
+ } finally {
+ if (loader != null) {
+ loader.resetThreadContextLoader();
+ loader.cleanup();
+ loader = null;
+ }
+ if (sysProperties != null) {
+ sysProperties.restoreSystem();
+ }
+ }
+ }
+
+ /**
+ * Run this ExecuteJava in a Thread.
+ * @since Ant 1.5
+ */
+ public void run() {
+ final Object[] argument = {javaCommand.getArguments()};
+ try {
+ if (perm != null) {
+ perm.setSecurityManager();
+ }
+ main.invoke(null, argument);
+ } catch (InvocationTargetException e) {
+ Throwable t = e.getTargetException();
+ if (!(t instanceof InterruptedException)) {
+ caught = t;
+ } /* else { swallow, probably due to timeout } */
+ } catch (Throwable t) {
+ caught = t;
+ } finally {
+ if (perm != null) {
+ perm.restoreSecurityManager();
+ }
+ synchronized (this) {
+ notifyAll();
+ }
+ }
+ }
+
+ /**
+ * Mark timeout as having occurred.
+ * @param w the responsible Watchdog.
+ * @since Ant 1.5
+ */
+ public synchronized void timeoutOccured(Watchdog w) {
+ if (thread != null) {
+ timedOut = true;
+ thread.interrupt();
+ }
+ notifyAll();
+ }
+
+ /**
+ * Get whether the process was killed.
+ * @return <code>true</code> if the process was killed, false otherwise.
+ * @since 1.19, Ant 1.5
+ */
+ public synchronized boolean killedProcess() {
+ return timedOut;
+ }
+
+ /**
+ * Run the Java command in a separate VM, this does not give you
+ * the full flexibility of the Java task, but may be enough for
+ * simple needs.
+ * @param pc the ProjectComponent to use for logging, etc.
+ * @return the exit status of the subprocess.
+ * @throws BuildException on error.
+ * @since Ant 1.6.3
+ */
+ public int fork(ProjectComponent pc) throws BuildException {
+ CommandlineJava cmdl = new CommandlineJava();
+ cmdl.setClassname(javaCommand.getExecutable());
+ String[] args = javaCommand.getArguments();
+ for (int i = 0; i < args.length; i++) {
+ cmdl.createArgument().setValue(args[i]);
+ }
+ if (classpath != null) {
+ cmdl.createClasspath(pc.getProject()).append(classpath);
+ }
+ if (sysProperties != null) {
+ cmdl.addSysproperties(sysProperties);
+ }
+ Redirector redirector = new Redirector(pc);
+ Execute exe
+ = new Execute(redirector.createHandler(),
+ timeout == null
+ ? null
+ : new ExecuteWatchdog(timeout.longValue()));
+ exe.setAntRun(pc.getProject());
+ if (Os.isFamily("openvms")) {
+ setupCommandLineForVMS(exe, cmdl.getCommandline());
+ } else {
+ exe.setCommandline(cmdl.getCommandline());
+ }
+ try {
+ int rc = exe.execute();
+ redirector.complete();
+ return rc;
+ } catch (IOException e) {
+ throw new BuildException(e);
+ } finally {
+ timedOut = exe.killedProcess();
+ }
+ }
+
+ /**
+ * On VMS platform, we need to create a special java options file
+ * containing the arguments and classpath for the java command.
+ * The special file is supported by the "-V" switch on the VMS JVM.
+ *
+ * @param exe the Execute instance to alter.
+ * @param command the command-line.
+ */
+ public static void setupCommandLineForVMS(Execute exe, String[] command) {
+ //Use the VM launcher instead of shell launcher on VMS
+ exe.setVMLauncher(true);
+ File vmsJavaOptionFile = null;
+ try {
+ String [] args = new String[command.length - 1];
+ System.arraycopy(command, 1, args, 0, command.length - 1);
+ vmsJavaOptionFile = JavaEnvUtils.createVmsJavaOptionFile(args);
+ //we mark the file to be deleted on exit.
+ //the alternative would be to cache the filename and delete
+ //after execution finished, which is much better for long-lived runtimes
+ //though spawning complicates things...
+ vmsJavaOptionFile.deleteOnExit();
+ String [] vmsCmd = {command[0], "-V", vmsJavaOptionFile.getPath()};
+ exe.setCommandline(vmsCmd);
+ } catch (IOException e) {
+ throw new BuildException("Failed to create a temporary file for \"-V\" switch");
+ }
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/ExecuteOn.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/ExecuteOn.java
new file mode 100644
index 00000000..18cbd29d
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/ExecuteOn.java
@@ -0,0 +1,784 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.DirectoryScanner;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.AbstractFileSet;
+import org.apache.tools.ant.types.Commandline;
+import org.apache.tools.ant.types.DirSet;
+import org.apache.tools.ant.types.EnumeratedAttribute;
+import org.apache.tools.ant.types.FileList;
+import org.apache.tools.ant.types.FileSet;
+import org.apache.tools.ant.types.Mapper;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.ResourceCollection;
+import org.apache.tools.ant.types.resources.FileProvider;
+import org.apache.tools.ant.types.resources.FileResource;
+import org.apache.tools.ant.types.resources.Union;
+import org.apache.tools.ant.util.FileNameMapper;
+import org.apache.tools.ant.util.ResourceUtils;
+import org.apache.tools.ant.util.SourceFileScanner;
+
+/**
+ * Executes a given command, supplying a set of files as arguments.
+ *
+ * @since Ant 1.2
+ *
+ * @ant.task category="control" name="apply"
+ */
+public class ExecuteOn extends ExecTask {
+
+ // CheckStyle:VisibilityModifier OFF - bc
+
+ // filesets has been protected so we need to keep that even after
+ // switching to resource collections. In fact, they will still
+ // get a different treatment form the other resource collections
+ // even in execute since we have some subtle special features like
+ // switching type to "dir" when we encounter a DirSet that would
+ // be more difficult to achieve otherwise.
+
+ protected Vector<AbstractFileSet> filesets = new Vector<AbstractFileSet>(); // contains AbstractFileSet
+ // (both DirSet and FileSet)
+ private Union resources = null;
+ private boolean relative = false;
+ private boolean parallel = false;
+ private boolean forwardSlash = false;
+ protected String type = FileDirBoth.FILE;
+ protected Commandline.Marker srcFilePos = null;
+ private boolean skipEmpty = false;
+ protected Commandline.Marker targetFilePos = null;
+ protected Mapper mapperElement = null;
+ protected FileNameMapper mapper = null;
+ protected File destDir = null;
+ private int maxParallel = -1;
+ private boolean addSourceFile = true;
+ private boolean verbose = false;
+ private boolean ignoreMissing = true;
+ private boolean force = false;
+
+ /**
+ * Has &lt;srcfile&gt; been specified before &lt;targetfile&gt;
+ */
+ protected boolean srcIsFirst = true;
+
+ // CheckStyle:VisibilityModifier ON
+ /**
+ * Add a set of files upon which to operate.
+ * @param set the FileSet to add.
+ */
+ public void addFileset(FileSet set) {
+ filesets.addElement(set);
+ }
+
+ /**
+ * Add a set of directories upon which to operate.
+ *
+ * @param set the DirSet to add.
+ *
+ * @since Ant 1.6
+ */
+ public void addDirset(DirSet set) {
+ filesets.addElement(set);
+ }
+
+ /**
+ * Add a list of source files upon which to operate.
+ * @param list the FileList to add.
+ */
+ public void addFilelist(FileList list) {
+ add(list);
+ }
+
+ /**
+ * Add a collection of resources upon which to operate.
+ * @param rc resource collection to add.
+ * @since Ant 1.7
+ */
+ public void add(ResourceCollection rc) {
+ if (resources == null) {
+ resources = new Union();
+ }
+ resources.add(rc);
+ }
+
+ /**
+ * Set whether the filenames should be passed on the command line as
+ * absolute or relative pathnames. Paths are relative to the base
+ * directory of the corresponding fileset for source files or the
+ * dest attribute for target files.
+ * @param relative whether to pass relative pathnames.
+ */
+ public void setRelative(boolean relative) {
+ this.relative = relative;
+ }
+
+
+ /**
+ * Set whether to execute in parallel mode.
+ * If true, run the command only once, appending all files as arguments.
+ * If false, command will be executed once for every file. Defaults to false.
+ * @param parallel whether to run in parallel.
+ */
+ public void setParallel(boolean parallel) {
+ this.parallel = parallel;
+ }
+
+ /**
+ * Set whether the command works only on files, directories or both.
+ * @param type a FileDirBoth EnumeratedAttribute.
+ */
+ public void setType(FileDirBoth type) {
+ this.type = type.getValue();
+ }
+
+ /**
+ * Set whether empty filesets will be skipped. If true and
+ * no source files have been found or are newer than their
+ * corresponding target files, the command will not be run.
+ * @param skip whether to skip empty filesets.
+ */
+ public void setSkipEmptyFilesets(boolean skip) {
+ skipEmpty = skip;
+ }
+
+ /**
+ * Specify the directory where target files are to be placed.
+ * @param destDir the File object representing the destination directory.
+ */
+ public void setDest(File destDir) {
+ this.destDir = destDir;
+ }
+
+ /**
+ * Set whether the source and target file names on Windows and OS/2
+ * must use the forward slash as file separator.
+ * @param forwardSlash whether the forward slash will be forced.
+ */
+ public void setForwardslash(boolean forwardSlash) {
+ this.forwardSlash = forwardSlash;
+ }
+
+ /**
+ * Limit the command line length by passing at maximum this many
+ * sourcefiles at once to the command.
+ *
+ * <p>Set to &lt;= 0 for unlimited - this is the default.</p>
+ *
+ * @param max <code>int</code> maximum number of sourcefiles
+ * passed to the executable.
+ *
+ * @since Ant 1.6
+ */
+ public void setMaxParallel(int max) {
+ maxParallel = max;
+ }
+
+ /**
+ * Set whether to send the source file name on the command line.
+ *
+ * <p>Defaults to <code>true</code>.
+ *
+ * @param b whether to add the source file to the command line.
+ *
+ * @since Ant 1.6
+ */
+ public void setAddsourcefile(boolean b) {
+ addSourceFile = b;
+ }
+
+ /**
+ * Set whether to operate in verbose mode.
+ * If true, a verbose summary will be printed after execution.
+ * @param b whether to operate in verbose mode.
+ *
+ * @since Ant 1.6
+ */
+ public void setVerbose(boolean b) {
+ verbose = b;
+ }
+
+ /**
+ * Set whether to ignore nonexistent files from filelists.
+ * @param b whether to ignore missing files.
+ *
+ * @since Ant 1.6.2
+ */
+ public void setIgnoremissing(boolean b) {
+ ignoreMissing = b;
+ }
+
+ /**
+ * Set whether to bypass timestamp comparisons for target files.
+ * @param b whether to bypass timestamp comparisons.
+ *
+ * @since Ant 1.6.3
+ */
+ public void setForce(boolean b) {
+ force = b;
+ }
+
+ /**
+ * Create a placeholder indicating where on the command line
+ * the name of the source file should be inserted.
+ * @return <code>Commandline.Marker</code>.
+ */
+ public Commandline.Marker createSrcfile() {
+ if (srcFilePos != null) {
+ throw new BuildException(getTaskType() + " doesn\'t support multiple "
+ + "srcfile elements.", getLocation());
+ }
+ srcFilePos = cmdl.createMarker();
+ return srcFilePos;
+ }
+
+ /**
+ * Create a placeholder indicating where on the command line
+ * the name of the target file should be inserted.
+ * @return <code>Commandline.Marker</code>.
+ */
+ public Commandline.Marker createTargetfile() {
+ if (targetFilePos != null) {
+ throw new BuildException(getTaskType() + " doesn\'t support multiple "
+ + "targetfile elements.", getLocation());
+ }
+ targetFilePos = cmdl.createMarker();
+ srcIsFirst = (srcFilePos != null);
+ return targetFilePos;
+ }
+
+ /**
+ * Create a nested Mapper element to use for mapping
+ * source files to target files.
+ * @return <code>Mapper</code>.
+ * @throws BuildException if more than one mapper is defined.
+ */
+ public Mapper createMapper() throws BuildException {
+ if (mapperElement != null) {
+ throw new BuildException("Cannot define more than one mapper",
+ getLocation());
+ }
+ mapperElement = new Mapper(getProject());
+ return mapperElement;
+ }
+
+ /**
+ * Add a nested FileNameMapper.
+ * @param fileNameMapper the mapper to add.
+ * @since Ant 1.6.3
+ */
+ public void add(FileNameMapper fileNameMapper) {
+ createMapper().add(fileNameMapper);
+ }
+
+ /**
+ * Check the configuration of this ExecuteOn instance.
+ */
+ protected void checkConfiguration() {
+// * @TODO using taskName here is brittle, as a user could override it.
+// * this should probably be modified to use the classname instead.
+ if ("execon".equals(getTaskName())) {
+ log("!! execon is deprecated. Use apply instead. !!");
+ }
+ super.checkConfiguration();
+ if (filesets.size() == 0 && resources == null) {
+ throw new BuildException("no resources specified",
+ getLocation());
+ }
+ if (targetFilePos != null && mapperElement == null) {
+ throw new BuildException("targetfile specified without mapper",
+ getLocation());
+ }
+ if (destDir != null && mapperElement == null) {
+ throw new BuildException("dest specified without mapper",
+ getLocation());
+ }
+ if (mapperElement != null) {
+ mapper = mapperElement.getImplementation();
+ }
+ }
+
+ /**
+ * Create the ExecuteStreamHandler instance that will be used
+ * during execution.
+ * @return <code>ExecuteStreamHandler</code>.
+ * @throws BuildException on error.
+ */
+ protected ExecuteStreamHandler createHandler() throws BuildException {
+ //if we have a RedirectorElement, return a decoy
+ return (redirectorElement == null)
+ ? super.createHandler() : new PumpStreamHandler();
+ }
+
+ /**
+ * Set up the I/O Redirector.
+ */
+ protected void setupRedirector() {
+ super.setupRedirector();
+ redirector.setAppendProperties(true);
+ }
+
+ /**
+ * Run the specified Execute object.
+ * @param exe the Execute instance representing the external process.
+ * @throws BuildException on error
+ */
+ protected void runExec(Execute exe) throws BuildException {
+ int totalFiles = 0;
+ int totalDirs = 0;
+ boolean haveExecuted = false;
+ try {
+ Vector<String> fileNames = new Vector<String>();
+ Vector<File> baseDirs = new Vector<File>();
+ final int size = filesets.size();
+ for (int i = 0; i < size; i++) {
+ String currentType = type;
+ AbstractFileSet fs = filesets.elementAt(i);
+ if (fs instanceof DirSet) {
+ if (!FileDirBoth.DIR.equals(type)) {
+ log("Found a nested dirset but type is " + type + ". "
+ + "Temporarily switching to type=\"dir\" on the"
+ + " assumption that you really did mean"
+ + " <dirset> not <fileset>.", Project.MSG_DEBUG);
+ currentType = FileDirBoth.DIR;
+ }
+ }
+ File base = fs.getDir(getProject());
+
+ DirectoryScanner ds = fs.getDirectoryScanner(getProject());
+
+ if (!FileDirBoth.DIR.equals(currentType)) {
+ String[] s = getFiles(base, ds);
+ for (int j = 0; j < s.length; j++) {
+ totalFiles++;
+ fileNames.addElement(s[j]);
+ baseDirs.addElement(base);
+ }
+ }
+ if (!FileDirBoth.FILE.equals(currentType)) {
+ String[] s = getDirs(base, ds);
+ for (int j = 0; j < s.length; j++) {
+ totalDirs++;
+ fileNames.addElement(s[j]);
+ baseDirs.addElement(base);
+ }
+ }
+ if (fileNames.size() == 0 && skipEmpty) {
+ logSkippingFileset(currentType, ds, base);
+ continue;
+ }
+ if (!parallel) {
+ String[] s = new String[fileNames.size()];
+ fileNames.copyInto(s);
+ for (int j = 0; j < s.length; j++) {
+ String[] command = getCommandline(s[j], base);
+ log(Commandline.describeCommand(command),
+ Project.MSG_VERBOSE);
+ exe.setCommandline(command);
+
+ if (redirectorElement != null) {
+ setupRedirector();
+ redirectorElement.configure(redirector, s[j]);
+ }
+ if (redirectorElement != null || haveExecuted) {
+ // need to reset the stream handler to restart
+ // reading of pipes;
+ // go ahead and do it always w/ nested redirectors
+ exe.setStreamHandler(redirector.createHandler());
+ }
+ runExecute(exe);
+ haveExecuted = true;
+ }
+ fileNames.removeAllElements();
+ baseDirs.removeAllElements();
+ }
+ }
+
+ if (resources != null) {
+ for (Resource res : resources) {
+
+ if (!res.isExists() && ignoreMissing) {
+ continue;
+ }
+
+ File base = null;
+ String name = res.getName();
+ FileProvider fp = res.as(FileProvider.class);
+ if (fp != null) {
+ FileResource fr = ResourceUtils.asFileResource(fp);
+ base = fr.getBaseDir();
+ if (base == null) {
+ name = fr.getFile().getAbsolutePath();
+ }
+ }
+
+ if (restrict(new String[] {name}, base).length == 0) {
+ continue;
+ }
+
+ if ((!res.isDirectory() || !res.isExists())
+ && !FileDirBoth.DIR.equals(type)) {
+ totalFiles++;
+ } else if (res.isDirectory()
+ && !FileDirBoth.FILE.equals(type)) {
+ totalDirs++;
+ } else {
+ continue;
+ }
+
+ baseDirs.add(base);
+ fileNames.add(name);
+
+ if (!parallel) {
+ String[] command = getCommandline(name, base);
+ log(Commandline.describeCommand(command),
+ Project.MSG_VERBOSE);
+ exe.setCommandline(command);
+
+ if (redirectorElement != null) {
+ setupRedirector();
+ redirectorElement.configure(redirector, name);
+ }
+ if (redirectorElement != null || haveExecuted) {
+ // need to reset the stream handler to restart
+ // reading of pipes;
+ // go ahead and do it always w/ nested redirectors
+ exe.setStreamHandler(redirector.createHandler());
+ }
+ runExecute(exe);
+ haveExecuted = true;
+ fileNames.removeAllElements();
+ baseDirs.removeAllElements();
+ }
+ }
+ }
+ if (parallel && (fileNames.size() > 0 || !skipEmpty)) {
+ runParallel(exe, fileNames, baseDirs);
+ haveExecuted = true;
+ }
+ if (haveExecuted) {
+ log("Applied " + cmdl.getExecutable() + " to "
+ + totalFiles + " file"
+ + (totalFiles != 1 ? "s" : "") + " and "
+ + totalDirs + " director"
+ + (totalDirs != 1 ? "ies" : "y") + ".",
+ verbose ? Project.MSG_INFO : Project.MSG_VERBOSE);
+ }
+ } catch (IOException e) {
+ throw new BuildException("Execute failed: " + e, e, getLocation());
+ } finally {
+ // close the output file if required
+ logFlush();
+ redirector.setAppendProperties(false);
+ redirector.setProperties();
+ }
+ }
+
+ /**
+ * log a message for skipping a fileset.
+ * @param currentType the current type.
+ * @param ds the directory scanner.
+ * @param base the dir base
+ */
+ private void logSkippingFileset(
+ String currentType, DirectoryScanner ds, File base) {
+ int includedCount
+ = ((!FileDirBoth.DIR.equals(currentType))
+ ? ds.getIncludedFilesCount() : 0)
+ + ((!FileDirBoth.FILE.equals(currentType))
+ ? ds.getIncludedDirsCount() : 0);
+
+ log("Skipping fileset for directory " + base + ". It is "
+ + ((includedCount > 0) ? "up to date." : "empty."),
+ verbose ? Project.MSG_INFO : Project.MSG_VERBOSE);
+ }
+
+ /**
+ * Construct the command line for parallel execution.
+ *
+ * @param srcFiles The filenames to add to the commandline.
+ * @param baseDirs filenames are relative to this dir.
+ * @return the command line in the form of a String[].
+ */
+ protected String[] getCommandline(String[] srcFiles, File[] baseDirs) {
+ final char fileSeparator = File.separatorChar;
+ Vector<String> targets = new Vector<String>();
+ if (targetFilePos != null) {
+ HashSet<String> addedFiles = new HashSet<String>();
+ for (int i = 0; i < srcFiles.length; i++) {
+ String[] subTargets = mapper.mapFileName(srcFiles[i]);
+ if (subTargets != null) {
+ for (int j = 0; j < subTargets.length; j++) {
+ String name = null;
+ if (!relative) {
+ name = new File(destDir, subTargets[j]).getAbsolutePath();
+ } else {
+ name = subTargets[j];
+ }
+ if (forwardSlash && fileSeparator != '/') {
+ name = name.replace(fileSeparator, '/');
+ }
+ if (!addedFiles.contains(name)) {
+ targets.addElement(name);
+ addedFiles.add(name);
+ }
+ }
+ }
+ }
+ }
+ String[] targetFiles = (String[]) targets.toArray(new String[targets.size()]);
+
+ if (!addSourceFile) {
+ srcFiles = new String[0];
+ }
+ String[] orig = cmdl.getCommandline();
+ String[] result
+ = new String[orig.length + srcFiles.length + targetFiles.length];
+
+ int srcIndex = orig.length;
+ if (srcFilePos != null) {
+ srcIndex = srcFilePos.getPosition();
+ }
+ if (targetFilePos != null) {
+ int targetIndex = targetFilePos.getPosition();
+
+ if (srcIndex < targetIndex
+ || (srcIndex == targetIndex && srcIsFirst)) {
+
+ // 0 --> srcIndex
+ System.arraycopy(orig, 0, result, 0, srcIndex);
+
+ // srcIndex --> targetIndex
+ System.arraycopy(orig, srcIndex, result,
+ srcIndex + srcFiles.length,
+ targetIndex - srcIndex);
+
+ insertTargetFiles(targetFiles, result,
+ targetIndex + srcFiles.length,
+ targetFilePos.getPrefix(),
+ targetFilePos.getSuffix());
+
+ // targetIndex --> end
+ System.arraycopy(orig, targetIndex, result,
+ targetIndex + srcFiles.length + targetFiles.length,
+ orig.length - targetIndex);
+ } else {
+ // 0 --> targetIndex
+ System.arraycopy(orig, 0, result, 0, targetIndex);
+
+ insertTargetFiles(targetFiles, result, targetIndex,
+ targetFilePos.getPrefix(),
+ targetFilePos.getSuffix());
+
+ // targetIndex --> srcIndex
+ System.arraycopy(orig, targetIndex, result,
+ targetIndex + targetFiles.length,
+ srcIndex - targetIndex);
+
+ // srcIndex --> end
+ System.arraycopy(orig, srcIndex, result,
+ srcIndex + srcFiles.length + targetFiles.length,
+ orig.length - srcIndex);
+ srcIndex += targetFiles.length;
+ }
+
+ } else { // no targetFilePos
+
+ // 0 --> srcIndex
+ System.arraycopy(orig, 0, result, 0, srcIndex);
+ // srcIndex --> end
+ System.arraycopy(orig, srcIndex, result,
+ srcIndex + srcFiles.length,
+ orig.length - srcIndex);
+ }
+ // fill in source file names
+ for (int i = 0; i < srcFiles.length; i++) {
+ String src;
+ if (relative) {
+ src = srcFiles[i];
+ } else {
+ src = new File(baseDirs[i], srcFiles[i]).getAbsolutePath();
+ }
+ if (forwardSlash && fileSeparator != '/') {
+ src = src.replace(fileSeparator, '/');
+ }
+ if (srcFilePos != null &&
+ (srcFilePos.getPrefix().length() > 0
+ || srcFilePos.getSuffix().length() > 0)) {
+ src = srcFilePos.getPrefix() + src + srcFilePos.getSuffix();
+ }
+ result[srcIndex + i] = src;
+ }
+ return result;
+ }
+
+ /**
+ * Construct the command line for serial execution.
+ *
+ * @param srcFile The filename to add to the commandline.
+ * @param baseDir filename is relative to this dir.
+ * @return the command line in the form of a String[].
+ */
+ protected String[] getCommandline(String srcFile, File baseDir) {
+ return getCommandline(new String[] {srcFile}, new File[] {baseDir});
+ }
+
+ /**
+ * Return the list of files from this DirectoryScanner that should
+ * be included on the command line.
+ * @param baseDir the File base directory.
+ * @param ds the DirectoryScanner to use for file scanning.
+ * @return a String[] containing the filenames.
+ */
+ protected String[] getFiles(File baseDir, DirectoryScanner ds) {
+ return restrict(ds.getIncludedFiles(), baseDir);
+ }
+
+ /**
+ * Return the list of Directories from this DirectoryScanner that
+ * should be included on the command line.
+ * @param baseDir the File base directory.
+ * @param ds the DirectoryScanner to use for file scanning.
+ * @return a String[] containing the directory names.
+ */
+ protected String[] getDirs(File baseDir, DirectoryScanner ds) {
+ return restrict(ds.getIncludedDirectories(), baseDir);
+ }
+
+ /**
+ * Return the list of files or directories from this FileList that
+ * should be included on the command line.
+ * @param list the FileList to check.
+ * @return a String[] containing the directory names.
+ *
+ * @since Ant 1.6.2
+ */
+ protected String[] getFilesAndDirs(FileList list) {
+ return restrict(list.getFiles(getProject()), list.getDir(getProject()));
+ }
+
+ private String[] restrict(String[] s, File baseDir) {
+ return (mapper == null || force) ? s
+ : new SourceFileScanner(this).restrict(s, baseDir, destDir, mapper);
+ }
+
+ /**
+ * Run the command in "parallel" mode, making sure that at most
+ * maxParallel sourcefiles get passed on the command line.
+ * @param exe the Executable to use.
+ * @param fileNames the Vector of filenames.
+ * @param baseDirs the Vector of base directories corresponding to fileNames.
+ * @throws IOException on I/O errors.
+ * @throws BuildException on other errors.
+ * @since Ant 1.6
+ */
+ protected void runParallel(Execute exe, Vector<String> fileNames,
+ Vector<File> baseDirs)
+ throws IOException, BuildException {
+ String[] s = new String[fileNames.size()];
+ fileNames.copyInto(s);
+ File[] b = new File[baseDirs.size()];
+ baseDirs.copyInto(b);
+
+ if (maxParallel <= 0
+ || s.length == 0 /* this is skipEmpty == false */) {
+ String[] command = getCommandline(s, b);
+ log(Commandline.describeCommand(command), Project.MSG_VERBOSE);
+ exe.setCommandline(command);
+ if (redirectorElement != null) {
+ setupRedirector();
+ redirectorElement.configure(redirector, null);
+ exe.setStreamHandler(redirector.createHandler());
+ }
+ runExecute(exe);
+ } else {
+ int stillToDo = fileNames.size();
+ int currentOffset = 0;
+ while (stillToDo > 0) {
+ int currentAmount = Math.min(stillToDo, maxParallel);
+ String[] cs = new String[currentAmount];
+ System.arraycopy(s, currentOffset, cs, 0, currentAmount);
+ File[] cb = new File[currentAmount];
+ System.arraycopy(b, currentOffset, cb, 0, currentAmount);
+ String[] command = getCommandline(cs, cb);
+ log(Commandline.describeCommand(command), Project.MSG_VERBOSE);
+ exe.setCommandline(command);
+ if (redirectorElement != null) {
+ setupRedirector();
+ redirectorElement.configure(redirector, null);
+ }
+ if (redirectorElement != null || currentOffset > 0) {
+ // need to reset the stream handler to restart
+ // reading of pipes;
+ // go ahead and do it always w/ nested redirectors
+ exe.setStreamHandler(redirector.createHandler());
+ }
+ runExecute(exe);
+
+ stillToDo -= currentAmount;
+ currentOffset += currentAmount;
+ }
+ }
+ }
+
+ /**
+ * Inserts target file names (which are already absolute paths)
+ * into the list of arguments, taking prefix and postfix into
+ * account.
+ */
+ private static void insertTargetFiles(String[] targetFiles,
+ String[] arguments,
+ int insertPosition,
+ String prefix, String suffix) {
+ if (prefix.length() == 0 && suffix.length() == 0) {
+ System.arraycopy(targetFiles, 0, arguments, insertPosition,
+ targetFiles.length);
+ } else {
+ for (int i = 0; i < targetFiles.length; i++) {
+ arguments[insertPosition + i] =
+ prefix + targetFiles[i] + suffix;
+ }
+ }
+ }
+
+ /**
+ * Enumerated attribute with the values "file", "dir" and "both"
+ * for the type attribute.
+ */
+ public static class FileDirBoth extends EnumeratedAttribute {
+ /** File value */
+ public static final String FILE = "file";
+ /** Dir value */
+ public static final String DIR = "dir";
+ /**
+ * @see EnumeratedAttribute#getValues
+ */
+ /** {@inheritDoc}. */
+ public String[] getValues() {
+ return new String[] {FILE, DIR, "both"};
+ }
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/ExecuteStreamHandler.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/ExecuteStreamHandler.java
new file mode 100644
index 00000000..1c5f9739
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/ExecuteStreamHandler.java
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+/**
+ * Used by <code>Execute</code> to handle input and output stream of
+ * subprocesses.
+ *
+ * @since Ant 1.2
+ */
+public interface ExecuteStreamHandler {
+
+ /**
+ * Install a handler for the input stream of the subprocess.
+ *
+ * @param os output stream to write to the standard input stream of the
+ * subprocess
+ * @throws IOException on error
+ */
+ void setProcessInputStream(OutputStream os) throws IOException;
+
+ /**
+ * Install a handler for the error stream of the subprocess.
+ *
+ * @param is input stream to read from the error stream from the subprocess
+ * @throws IOException on error
+ */
+ void setProcessErrorStream(InputStream is) throws IOException;
+
+ /**
+ * Install a handler for the output stream of the subprocess.
+ *
+ * @param is input stream to read from the error stream from the subprocess
+ * @throws IOException on error
+ */
+ void setProcessOutputStream(InputStream is) throws IOException;
+
+ /**
+ * Start handling of the streams.
+ * @throws IOException on error
+ */
+ void start() throws IOException;
+
+ /**
+ * Stop handling of the streams - will not be restarted.
+ */
+ void stop();
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/ExecuteWatchdog.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/ExecuteWatchdog.java
new file mode 100644
index 00000000..cc3933e5
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/ExecuteWatchdog.java
@@ -0,0 +1,177 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.util.TimeoutObserver;
+import org.apache.tools.ant.util.Watchdog;
+
+/**
+ * Destroys a process running for too long.
+ * For example:
+ * <pre>
+ * ExecuteWatchdog watchdog = new ExecuteWatchdog(30000);
+ * Execute exec = new Execute(myloghandler, watchdog);
+ * exec.setCommandLine(mycmdline);
+ * int exitvalue = exec.execute();
+ * if (Execute.isFailure(exitvalue) &amp;&amp; watchdog.killedProcess()) {
+ * // it was killed on purpose by the watchdog
+ * }
+ * </pre>
+
+ * @see Execute
+ * @see org.apache.tools.ant.util.Watchdog
+ * @since Ant 1.2
+ */
+public class ExecuteWatchdog implements TimeoutObserver {
+
+ /** the process to execute and watch for duration */
+ private Process process;
+
+ /** say whether or not the watchdog is currently monitoring a process */
+ private volatile boolean watch = false;
+
+ /** exception that might be thrown during the process execution */
+ private Exception caught = null;
+
+ /** say whether or not the process was killed due to running overtime */
+ private volatile boolean killedProcess = false;
+
+ /** will tell us whether timeout has occurred */
+ private Watchdog watchdog;
+
+ /**
+ * Creates a new watchdog with a given timeout.
+ *
+ * @param timeout the timeout for the process in milliseconds.
+ * It must be greater than 0.
+ */
+ public ExecuteWatchdog(long timeout) {
+ watchdog = new Watchdog(timeout);
+ watchdog.addTimeoutObserver(this);
+ }
+
+ /**
+ * @param timeout the timeout value to use in milliseconds.
+ * @see #ExecuteWatchdog(long)
+ * @deprecated since 1.5.x.
+ * Use constructor with a long type instead.
+ * (1.4.x compatibility)
+ */
+ public ExecuteWatchdog(int timeout) {
+ this((long) timeout);
+ }
+
+ /**
+ * Watches the given process and terminates it, if it runs for too long.
+ * All information from the previous run are reset.
+ * @param process the process to monitor. It cannot be <tt>null</tt>
+ * @throws IllegalStateException if a process is still being monitored.
+ */
+ public synchronized void start(Process process) {
+ if (process == null) {
+ throw new NullPointerException("process is null.");
+ }
+ if (this.process != null) {
+ throw new IllegalStateException("Already running.");
+ }
+ this.caught = null;
+ this.killedProcess = false;
+ this.watch = true;
+ this.process = process;
+ watchdog.start();
+ }
+
+ /**
+ * Stops the watcher. It will notify all threads possibly waiting
+ * on this object.
+ */
+ public synchronized void stop() {
+ watchdog.stop();
+ cleanUp();
+ }
+
+ /**
+ * Called after watchdog has finished.
+ * This can be called in the watchdog thread
+ * @param w the watchdog
+ */
+ public synchronized void timeoutOccured(Watchdog w) {
+ try {
+ try {
+ // We must check if the process was not stopped
+ // before being here
+ process.exitValue();
+ } catch (IllegalThreadStateException itse) {
+ // the process is not terminated, if this is really
+ // a timeout and not a manual stop then kill it.
+ if (watch) {
+ killedProcess = true;
+ process.destroy();
+ }
+ }
+ } catch (Exception e) {
+ caught = e;
+ } finally {
+ cleanUp();
+ }
+ }
+
+ /**
+ * reset the monitor flag and the process.
+ */
+ protected synchronized void cleanUp() {
+ watch = false;
+ process = null;
+ }
+
+ /**
+ * This method will rethrow the exception that was possibly caught during
+ * the run of the process. It will only remains valid once the process has
+ * been terminated either by 'error', timeout or manual intervention.
+ * Information will be discarded once a new process is ran.
+ * @throws BuildException a wrapped exception over the one that was
+ * silently swallowed and stored during the process run.
+ */
+ public synchronized void checkException() throws BuildException {
+ if (caught != null) {
+ throw new BuildException("Exception in ExecuteWatchdog.run: "
+ + caught.getMessage(), caught);
+ }
+ }
+
+ /**
+ * Indicates whether or not the watchdog is still monitoring the process.
+ * @return <tt>true</tt> if the process is still running, otherwise
+ * <tt>false</tt>.
+ */
+ public boolean isWatching() {
+ return watch;
+ }
+
+ /**
+ * Indicates whether the last process run was killed on timeout or not.
+ * @return <tt>true</tt> if the process was killed otherwise
+ * <tt>false</tt>.
+ */
+ public boolean killedProcess() {
+ return killedProcess;
+ }
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Exit.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Exit.java
new file mode 100644
index 00000000..f48f2484
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Exit.java
@@ -0,0 +1,235 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.ExitStatusException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.PropertyHelper;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.taskdefs.condition.Condition;
+import org.apache.tools.ant.taskdefs.condition.ConditionBase;
+
+/**
+ * Exits the active build, giving an additional message
+ * if available.
+ *
+ * The <code>if</code> and <code>unless</code> attributes make the
+ * failure conditional -both probe for the named property being defined.
+ * The <code>if</code> tests for the property being defined, the
+ * <code>unless</code> for a property being undefined.
+ *
+ * If both attributes are set, then the test fails only if both tests
+ * are true. i.e.
+ * <pre>fail := defined(ifProperty) &amp;&amp; !defined(unlessProperty)</pre>
+ *
+ * A single nested<code>&lt;condition&gt;</code> element can be specified
+ * instead of using <code>if</code>/<code>unless</code> (a combined
+ * effect can be achieved using <code>isset</code> conditions).
+ *
+ * @since Ant 1.2
+ *
+ * @ant.task name="fail" category="control"
+ */
+public class Exit extends Task {
+
+ private static class NestedCondition extends ConditionBase implements Condition {
+ public boolean eval() {
+ if (countConditions() != 1) {
+ throw new BuildException(
+ "A single nested condition is required.");
+ }
+ return ((Condition) (getConditions().nextElement())).eval();
+ }
+ }
+
+ private String message;
+ private Object ifCondition, unlessCondition;
+ private NestedCondition nestedCondition;
+ private Integer status;
+
+ /**
+ * A message giving further information on why the build exited.
+ *
+ * @param value message to output
+ */
+ public void setMessage(String value) {
+ this.message = value;
+ }
+
+ /**
+ * Only fail if the given expression evaluates to true or the name
+ * of an existing property.
+ * @param c property name or evaluated expression
+ * @since Ant 1.8.0
+ */
+ public void setIf(Object c) {
+ ifCondition = c;
+ }
+
+ /**
+ * Only fail if the given expression evaluates to true or the name
+ * of an existing property.
+ * @param c property name or evaluated expression
+ */
+ public void setIf(String c) {
+ setIf((Object) c);
+ }
+
+ /**
+ * Only fail if the given expression evaluates to false or tno
+ * property of the given name exists.
+ * @param c property name or evaluated expression
+ * @since Ant 1.8.0
+ */
+ public void setUnless(Object c) {
+ unlessCondition = c;
+ }
+
+ /**
+ * Only fail if the given expression evaluates to false or tno
+ * property of the given name exists.
+ * @param c property name or evaluated expression
+ */
+ public void setUnless(String c) {
+ setUnless((Object) c);
+ }
+
+ /**
+ * Set the status code to associate with the thrown Exception.
+ * @param i the <code>int</code> status
+ */
+ public void setStatus(int i) {
+ status = new Integer(i);
+ }
+
+ /**
+ * Throw a <code>BuildException</code> to exit (fail) the build.
+ * If specified, evaluate conditions:
+ * A single nested condition is accepted, but requires that the
+ * <code>if</code>/<code>unless</code> attributes be omitted.
+ * If the nested condition evaluates to true, or the
+ * ifCondition is true or unlessCondition is false, the build will exit.
+ * The error message is constructed from the text fields, from
+ * the nested condition (if specified), or finally from
+ * the if and unless parameters (if present).
+ * @throws BuildException on error
+ */
+ public void execute() throws BuildException {
+ boolean fail = (nestedConditionPresent()) ? testNestedCondition()
+ : (testIfCondition() && testUnlessCondition());
+ if (fail) {
+ String text = null;
+ if (message != null && message.trim().length() > 0) {
+ text = message.trim();
+ } else {
+ if (ifCondition != null && !"".equals(ifCondition)
+ && testIfCondition()) {
+ text = "if=" + ifCondition;
+ }
+ if (unlessCondition != null && !"".equals(unlessCondition)
+ && testUnlessCondition()) {
+ if (text == null) {
+ text = "";
+ } else {
+ text += " and ";
+ }
+ text += "unless=" + unlessCondition;
+ }
+ if (nestedConditionPresent()) {
+ text = "condition satisfied";
+ } else {
+ if (text == null) {
+ text = "No message";
+ }
+ }
+ }
+ log("failing due to " + text, Project.MSG_DEBUG);
+ throw ((status == null) ? new BuildException(text)
+ : new ExitStatusException(text, status.intValue()));
+ }
+ }
+
+ /**
+ * Set a multiline message.
+ * @param msg the message to display
+ */
+ public void addText(String msg) {
+ if (message == null) {
+ message = "";
+ }
+ message += getProject().replaceProperties(msg);
+ }
+
+ /**
+ * Add a condition element.
+ * @return <code>ConditionBase</code>.
+ * @since Ant 1.6.2
+ */
+ public ConditionBase createCondition() {
+ if (nestedCondition != null) {
+ throw new BuildException("Only one nested condition is allowed.");
+ }
+ nestedCondition = new NestedCondition();
+ return nestedCondition;
+ }
+
+ /**
+ * test the if condition
+ * @return true if there is no if condition, or the named property exists
+ */
+ private boolean testIfCondition() {
+ return PropertyHelper.getPropertyHelper(getProject())
+ .testIfCondition(ifCondition);
+ }
+
+ /**
+ * test the unless condition
+ * @return true if there is no unless condition,
+ * or there is a named property but it doesn't exist
+ */
+ private boolean testUnlessCondition() {
+ return PropertyHelper.getPropertyHelper(getProject())
+ .testUnlessCondition(unlessCondition);
+ }
+
+ /**
+ * test the nested condition
+ * @return true if there is none, or it evaluates to true
+ */
+ private boolean testNestedCondition() {
+ boolean result = nestedConditionPresent();
+
+ if (result && ifCondition != null || unlessCondition != null) {
+ throw new BuildException("Nested conditions "
+ + "not permitted in conjunction with if/unless attributes");
+ }
+
+ return result && nestedCondition.eval();
+ }
+
+ /**
+ * test whether there is a nested condition.
+ * @return <code>boolean</code>.
+ */
+ private boolean nestedConditionPresent() {
+ return (nestedCondition != null);
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Expand.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Expand.java
new file mode 100644
index 00000000..cb0c958d
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Expand.java
@@ -0,0 +1,527 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.types.FileSet;
+import org.apache.tools.ant.types.Mapper;
+import org.apache.tools.ant.types.PatternSet;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.ResourceCollection;
+import org.apache.tools.ant.types.resources.FileProvider;
+import org.apache.tools.ant.types.resources.Union;
+import org.apache.tools.ant.types.selectors.SelectorUtils;
+import org.apache.tools.ant.util.FileNameMapper;
+import org.apache.tools.ant.util.FileUtils;
+import org.apache.tools.ant.util.IdentityMapper;
+import org.apache.tools.zip.ZipEntry;
+import org.apache.tools.zip.ZipFile;
+
+/**
+ * Unzip a file.
+ *
+ * @since Ant 1.1
+ *
+ * @ant.task category="packaging"
+ * name="unzip"
+ * name="unjar"
+ * name="unwar"
+ */
+public class Expand extends Task {
+ private static final int BUFFER_SIZE = 1024;
+ private File dest; //req
+ private File source; // req
+ private boolean overwrite = true;
+ private Mapper mapperElement = null;
+ private Vector<PatternSet> patternsets = new Vector<PatternSet>();
+ private Union resources = new Union();
+ private boolean resourcesSpecified = false;
+ private boolean failOnEmptyArchive = false;
+ private boolean stripAbsolutePathSpec = false;
+ private boolean scanForUnicodeExtraFields = true;
+
+ public static final String NATIVE_ENCODING = "native-encoding";
+
+ private String encoding;
+ /** Error message when more that one mapper is defined */
+ public static final String ERROR_MULTIPLE_MAPPERS = "Cannot define more than one mapper";
+
+ private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+
+ /**
+ * Creates an Expand instance and sets encoding to UTF-8.
+ */
+ public Expand() {
+ this("UTF8");
+ }
+
+ /**
+ * Creates an Expand instance and sets the given encoding.
+ *
+ * @since Ant 1.9.5
+ */
+ protected Expand(String encoding) {
+ this.encoding = encoding;
+ }
+
+ /**
+ * Whether try ing to expand an empty archive would be an error.
+ *
+ * @since Ant 1.8.0
+ */
+ public void setFailOnEmptyArchive(boolean b) {
+ failOnEmptyArchive = b;
+ }
+
+ /**
+ * Whether try ing to expand an empty archive would be an error.
+ *
+ * @since Ant 1.8.0
+ */
+ public boolean getFailOnEmptyArchive() {
+ return failOnEmptyArchive;
+ }
+
+ /**
+ * Do the work.
+ *
+ * @exception BuildException Thrown in unrecoverable error.
+ */
+ public void execute() throws BuildException {
+ if ("expand".equals(getTaskType())) {
+ log("!! expand is deprecated. Use unzip instead. !!");
+ }
+
+ if (source == null && !resourcesSpecified) {
+ throw new BuildException("src attribute and/or resources must be "
+ + "specified");
+ }
+
+ if (dest == null) {
+ throw new BuildException(
+ "Dest attribute must be specified");
+ }
+
+ if (dest.exists() && !dest.isDirectory()) {
+ throw new BuildException("Dest must be a directory.", getLocation());
+ }
+
+ if (source != null) {
+ if (source.isDirectory()) {
+ throw new BuildException("Src must not be a directory."
+ + " Use nested filesets instead.", getLocation());
+ } else if (!source.exists()) {
+ throw new BuildException("src '" + source + "' doesn't exist.");
+ } else if (!source.canRead()) {
+ throw new BuildException("src '" + source + "' cannot be read.");
+ } else {
+ expandFile(FILE_UTILS, source, dest);
+ }
+ }
+ for (Resource r : resources) {
+ if (!r.isExists()) {
+ log("Skipping '" + r.getName() + "' because it doesn't exist.");
+ continue;
+ }
+
+ FileProvider fp = r.as(FileProvider.class);
+ if (fp != null) {
+ expandFile(FILE_UTILS, fp.getFile(), dest);
+ } else {
+ expandResource(r, dest);
+ }
+ }
+ }
+
+ /**
+ * This method is to be overridden by extending unarchival tasks.
+ *
+ * @param fileUtils the fileUtils
+ * @param srcF the source file
+ * @param dir the destination directory
+ */
+ protected void expandFile(FileUtils fileUtils, File srcF, File dir) {
+ log("Expanding: " + srcF + " into " + dir, Project.MSG_INFO);
+ ZipFile zf = null;
+ FileNameMapper mapper = getMapper();
+ if (!srcF.exists()) {
+ throw new BuildException("Unable to expand "
+ + srcF
+ + " as the file does not exist",
+ getLocation());
+ }
+ try {
+ zf = new ZipFile(srcF, encoding, scanForUnicodeExtraFields);
+ boolean empty = true;
+ Enumeration<ZipEntry> e = zf.getEntries();
+ while (e.hasMoreElements()) {
+ empty = false;
+ ZipEntry ze = e.nextElement();
+ InputStream is = null;
+ log("extracting " + ze.getName(), Project.MSG_DEBUG);
+ try {
+ extractFile(fileUtils, srcF, dir,
+ is = zf.getInputStream(ze),
+ ze.getName(), new Date(ze.getTime()),
+ ze.isDirectory(), mapper);
+ } finally {
+ FileUtils.close(is);
+ }
+ }
+ if (empty && getFailOnEmptyArchive()) {
+ throw new BuildException("archive '" + srcF + "' is empty");
+ }
+ log("expand complete", Project.MSG_VERBOSE);
+ } catch (IOException ioe) {
+ throw new BuildException(
+ "Error while expanding " + srcF.getPath()
+ + "\n" + ioe.toString(),
+ ioe);
+ } finally {
+ ZipFile.closeQuietly(zf);
+ }
+ }
+
+ /**
+ * This method is to be overridden by extending unarchival tasks.
+ *
+ * @param srcR the source resource
+ * @param dir the destination directory
+ */
+ protected void expandResource(Resource srcR, File dir) {
+ throw new BuildException("only filesystem based resources are"
+ + " supported by this task.");
+ }
+
+ /**
+ * get a mapper for a file
+ * @return a filenamemapper for a file
+ */
+ protected FileNameMapper getMapper() {
+ FileNameMapper mapper = null;
+ if (mapperElement != null) {
+ mapper = mapperElement.getImplementation();
+ } else {
+ mapper = new IdentityMapper();
+ }
+ return mapper;
+ }
+
+ // CheckStyle:ParameterNumberCheck OFF - bc
+ /**
+ * extract a file to a directory
+ * @param fileUtils a fileUtils object
+ * @param srcF the source file
+ * @param dir the destination directory
+ * @param compressedInputStream the input stream
+ * @param entryName the name of the entry
+ * @param entryDate the date of the entry
+ * @param isDirectory if this is true the entry is a directory
+ * @param mapper the filename mapper to use
+ * @throws IOException on error
+ */
+ protected void extractFile(FileUtils fileUtils, File srcF, File dir,
+ InputStream compressedInputStream,
+ String entryName, Date entryDate,
+ boolean isDirectory, FileNameMapper mapper)
+ throws IOException {
+
+ if (stripAbsolutePathSpec && entryName.length() > 0
+ && (entryName.charAt(0) == File.separatorChar
+ || entryName.charAt(0) == '/'
+ || entryName.charAt(0) == '\\')) {
+ log("stripped absolute path spec from " + entryName,
+ Project.MSG_VERBOSE);
+ entryName = entryName.substring(1);
+ }
+
+ if (patternsets != null && patternsets.size() > 0) {
+ String name = entryName.replace('/', File.separatorChar)
+ .replace('\\', File.separatorChar);
+
+ boolean included = false;
+ Set<String> includePatterns = new HashSet<String>();
+ Set<String> excludePatterns = new HashSet<String>();
+ final int size = patternsets.size();
+ for (int v = 0; v < size; v++) {
+ PatternSet p = patternsets.elementAt(v);
+ String[] incls = p.getIncludePatterns(getProject());
+ if (incls == null || incls.length == 0) {
+ // no include pattern implicitly means includes="**"
+ incls = new String[] {"**"};
+ }
+
+ for (int w = 0; w < incls.length; w++) {
+ String pattern = incls[w].replace('/', File.separatorChar)
+ .replace('\\', File.separatorChar);
+ if (pattern.endsWith(File.separator)) {
+ pattern += "**";
+ }
+ includePatterns.add(pattern);
+ }
+
+ String[] excls = p.getExcludePatterns(getProject());
+ if (excls != null) {
+ for (int w = 0; w < excls.length; w++) {
+ String pattern = excls[w]
+ .replace('/', File.separatorChar)
+ .replace('\\', File.separatorChar);
+ if (pattern.endsWith(File.separator)) {
+ pattern += "**";
+ }
+ excludePatterns.add(pattern);
+ }
+ }
+ }
+
+ for (Iterator<String> iter = includePatterns.iterator();
+ !included && iter.hasNext();) {
+ String pattern = iter.next();
+ included = SelectorUtils.matchPath(pattern, name);
+ }
+
+ for (Iterator<String> iter = excludePatterns.iterator();
+ included && iter.hasNext();) {
+ String pattern = iter.next();
+ included = !SelectorUtils.matchPath(pattern, name);
+ }
+
+ if (!included) {
+ //Do not process this file
+ log("skipping " + entryName
+ + " as it is excluded or not included.",
+ Project.MSG_VERBOSE);
+ return;
+ }
+ }
+ String[] mappedNames = mapper.mapFileName(entryName);
+ if (mappedNames == null || mappedNames.length == 0) {
+ mappedNames = new String[] {entryName};
+ }
+ File f = fileUtils.resolveFile(dir, mappedNames[0]);
+ try {
+ if (!overwrite && f.exists()
+ && f.lastModified() >= entryDate.getTime()) {
+ log("Skipping " + f + " as it is up-to-date",
+ Project.MSG_DEBUG);
+ return;
+ }
+
+ log("expanding " + entryName + " to " + f,
+ Project.MSG_VERBOSE);
+ // create intermediary directories - sometimes zip don't add them
+ File dirF = f.getParentFile();
+ if (dirF != null) {
+ dirF.mkdirs();
+ }
+
+ if (isDirectory) {
+ f.mkdirs();
+ } else {
+ byte[] buffer = new byte[BUFFER_SIZE];
+ int length = 0;
+ FileOutputStream fos = null;
+ try {
+ fos = new FileOutputStream(f);
+
+ while ((length =
+ compressedInputStream.read(buffer)) >= 0) {
+ fos.write(buffer, 0, length);
+ }
+
+ fos.close();
+ fos = null;
+ } finally {
+ FileUtils.close(fos);
+ }
+ }
+
+ fileUtils.setFileLastModified(f, entryDate.getTime());
+ } catch (FileNotFoundException ex) {
+ log("Unable to expand to file " + f.getPath(),
+ ex,
+ Project.MSG_WARN);
+ }
+
+ }
+ // CheckStyle:ParameterNumberCheck ON
+
+ /**
+ * Set the destination directory. File will be unzipped into the
+ * destination directory.
+ *
+ * @param d Path to the directory.
+ */
+ public void setDest(File d) {
+ this.dest = d;
+ }
+
+ /**
+ * Set the path to zip-file.
+ *
+ * @param s Path to zip-file.
+ */
+ public void setSrc(File s) {
+ this.source = s;
+ }
+
+ /**
+ * Should we overwrite files in dest, even if they are newer than
+ * the corresponding entries in the archive?
+ * @param b a <code>boolean</code> value
+ */
+ public void setOverwrite(boolean b) {
+ overwrite = b;
+ }
+
+ /**
+ * Add a patternset.
+ * @param set a pattern set
+ */
+ public void addPatternset(PatternSet set) {
+ patternsets.addElement(set);
+ }
+
+ /**
+ * Add a fileset
+ * @param set a file set
+ */
+ public void addFileset(FileSet set) {
+ add(set);
+ }
+
+ /**
+ * Add a resource collection.
+ * @param rc a resource collection.
+ * @since Ant 1.7
+ */
+ public void add(ResourceCollection rc) {
+ resourcesSpecified = true;
+ resources.add(rc);
+ }
+
+ /**
+ * Defines the mapper to map source entries to destination files.
+ * @return a mapper to be configured
+ * @exception BuildException if more than one mapper is defined
+ * @since Ant1.7
+ */
+ public Mapper createMapper() throws BuildException {
+ if (mapperElement != null) {
+ throw new BuildException(ERROR_MULTIPLE_MAPPERS,
+ getLocation());
+ }
+ mapperElement = new Mapper(getProject());
+ return mapperElement;
+ }
+
+ /**
+ * A nested filenamemapper
+ * @param fileNameMapper the mapper to add
+ * @since Ant 1.6.3
+ */
+ public void add(FileNameMapper fileNameMapper) {
+ createMapper().add(fileNameMapper);
+ }
+
+
+ /**
+ * Sets the encoding to assume for file names and comments.
+ *
+ * <p>Set to <code>native-encoding</code> if you want your
+ * platform's native encoding, defaults to UTF8.</p>
+ * @param encoding the name of the character encoding
+ * @since Ant 1.6
+ */
+ public void setEncoding(String encoding) {
+ internalSetEncoding(encoding);
+ }
+
+ /**
+ * Supports grand-children that want to support the attribute
+ * where the child-class doesn't (i.e. Unzip in the compress
+ * Antlib).
+ *
+ * @since Ant 1.8.0
+ */
+ protected void internalSetEncoding(String encoding) {
+ if (NATIVE_ENCODING.equals(encoding)) {
+ encoding = null;
+ }
+ this.encoding = encoding;
+ }
+
+ /**
+ * @since Ant 1.8.0
+ */
+ public String getEncoding() {
+ return encoding;
+ }
+
+ /**
+ * Whether leading path separators should be stripped.
+ *
+ * @since Ant 1.8.0
+ */
+ public void setStripAbsolutePathSpec(boolean b) {
+ stripAbsolutePathSpec = b;
+ }
+
+ /**
+ * Whether unicode extra fields will be used if present.
+ *
+ * @since Ant 1.8.0
+ */
+ public void setScanForUnicodeExtraFields(boolean b) {
+ internalSetScanForUnicodeExtraFields(b);
+ }
+
+ /**
+ * Supports grand-children that want to support the attribute
+ * where the child-class doesn't (i.e. Unzip in the compress
+ * Antlib).
+ *
+ * @since Ant 1.8.0
+ */
+ protected void internalSetScanForUnicodeExtraFields(boolean b) {
+ scanForUnicodeExtraFields = b;
+ }
+
+ /**
+ * @since Ant 1.8.0
+ */
+ public boolean getScanForUnicodeExtraFields() {
+ return scanForUnicodeExtraFields;
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Filter.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Filter.java
new file mode 100644
index 00000000..390ba5bf
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Filter.java
@@ -0,0 +1,101 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.io.File;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+
+/**
+ * Sets a token filter that is used by the file copy tasks
+ * to do token substitution. Sets multiple tokens by
+ * reading these from a file.
+ *
+ * @since Ant 1.1
+ *
+ * @ant.task category="filesystem"
+ */
+public class Filter extends Task {
+
+ private String token;
+ private String value;
+ private File filtersFile;
+
+ /**
+ * The token string without @ delimiters.
+ * @param token token to set
+ */
+ public void setToken(String token) {
+ this.token = token;
+ }
+
+ /**
+ * The string that should replace the token during filtered copies.
+ * @param value token replace value
+ */
+ public void setValue(String value) {
+ this.value = value;
+ }
+
+ /**
+ * The file from which the filters must be read.
+ * This file must be a formatted as a property file.
+ *
+ * @param filtersFile filter file
+ */
+ public void setFiltersfile(File filtersFile) {
+ this.filtersFile = filtersFile;
+ }
+
+ /**
+ * Execute the task.
+ * @throws BuildException on error
+ */
+ public void execute() throws BuildException {
+ boolean isFiltersFromFile =
+ filtersFile != null && token == null && value == null;
+ boolean isSingleFilter =
+ filtersFile == null && token != null && value != null;
+
+ if (!isFiltersFromFile && !isSingleFilter) {
+ throw new BuildException("both token and value parameters, or "
+ + "only a filtersFile parameter is "
+ + "required", getLocation());
+ }
+
+ if (isSingleFilter) {
+ getProject().getGlobalFilterSet().addFilter(token, value);
+ }
+
+ if (isFiltersFromFile) {
+ readFilters();
+ }
+ }
+
+ /**
+ * Read the filters.
+ * @throws BuildException on error
+ */
+ protected void readFilters() throws BuildException {
+ log("Reading filters from " + filtersFile, Project.MSG_VERBOSE);
+ getProject().getGlobalFilterSet().readFiltersFromFile(filtersFile);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/FixCRLF.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/FixCRLF.java
new file mode 100644
index 00000000..465bf462
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/FixCRLF.java
@@ -0,0 +1,696 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.util.Enumeration;
+import java.util.NoSuchElementException;
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.DirectoryScanner;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.filters.ChainableReader;
+import org.apache.tools.ant.filters.FixCrLfFilter;
+import org.apache.tools.ant.types.EnumeratedAttribute;
+import org.apache.tools.ant.types.FilterChain;
+import org.apache.tools.ant.util.FileUtils;
+
+/**
+ * Converts text source files to local OS formatting conventions, as
+ * well as repair text files damaged by misconfigured or misguided editors or
+ * file transfer programs.
+ * <p>
+ * This task can take the following arguments:
+ * <ul>
+ * <li>srcdir
+ * <li>destdir
+ * <li>include
+ * <li>exclude
+ * <li>cr
+ * <li>eol
+ * <li>tab
+ * <li>eof
+ * <li>encoding
+ * <li>targetencoding
+ * </ul>
+ * Of these arguments, only <b>sourcedir</b> is required.
+ * <p>
+ * When this task executes, it will scan the srcdir based on the include
+ * and exclude properties.
+ * <p>
+ * This version generalises the handling of EOL characters, and allows
+ * for CR-only line endings (the standard on Mac systems prior to OS X).
+ * Tab handling has also been generalised to accommodate any tabwidth
+ * from 2 to 80, inclusive. Importantly, it will leave untouched any
+ * literal TAB characters embedded within string or character constants.
+ * <p>
+ * <em>Warning:</em> do not run on binary files.
+ * <em>Caution:</em> run with care on carefully formatted files.
+ * This may sound obvious, but if you don't specify asis, presume that
+ * your files are going to be modified. If "tabs" is "add" or "remove",
+ * whitespace characters may be added or removed as necessary. Similarly,
+ * for CR's - in fact "eol"="crlf" or cr="add" can result in cr
+ * characters being removed in one special case accommodated, i.e.,
+ * CRCRLF is regarded as a single EOL to handle cases where other
+ * programs have converted CRLF into CRCRLF.
+ *
+ * @since Ant 1.1
+ *
+ * @ant.task category="filesystem"
+ */
+
+public class FixCRLF extends MatchingTask implements ChainableReader {
+
+ private static final String FIXCRLF_ERROR = "<fixcrlf> error: ";
+ /** error string for using srcdir and file */
+ public static final String ERROR_FILE_AND_SRCDIR
+ = FIXCRLF_ERROR + "srcdir and file are mutually exclusive";
+
+ private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+
+ private boolean preserveLastModified = false;
+ private File srcDir;
+ private File destDir = null;
+ private File file;
+ private FixCrLfFilter filter = new FixCrLfFilter();
+ private Vector<FilterChain> fcv = null;
+
+ /**
+ * Encoding to assume for the files
+ */
+ private String encoding = null;
+
+ /**
+ * Encoding to use for output files
+ */
+ private String outputEncoding = null;
+
+
+ /**
+ * Chain this task as a reader.
+ * @param rdr Reader to chain.
+ * @return a Reader.
+ * @since Ant 1.7?
+ */
+ public final Reader chain(final Reader rdr) {
+ return filter.chain(rdr);
+ }
+
+ /**
+ * Set the source dir to find the source text files.
+ * @param srcDir the source directory.
+ */
+ public void setSrcdir(File srcDir) {
+ this.srcDir = srcDir;
+ }
+
+ /**
+ * Set the destination where the fixed files should be placed.
+ * Default is to replace the original file.
+ * @param destDir the destination directory.
+ */
+ public void setDestdir(File destDir) {
+ this.destDir = destDir;
+ }
+
+ /**
+ * Set to true if modifying Java source files.
+ * @param javafiles whether modifying Java files.
+ */
+ public void setJavafiles(boolean javafiles) {
+ filter.setJavafiles(javafiles);
+ }
+
+ /**
+ * Set a single file to convert.
+ * @since Ant 1.6.3
+ * @param file the file to convert.
+ */
+ public void setFile(File file) {
+ this.file = file;
+ }
+
+ /**
+ * Specify how EndOfLine characters are to be handled.
+ *
+ * @param attr valid values:
+ * <ul>
+ * <li>asis: leave line endings alone
+ * <li>cr: convert line endings to CR
+ * <li>lf: convert line endings to LF
+ * <li>crlf: convert line endings to CRLF
+ * </ul>
+ */
+ public void setEol(CrLf attr) {
+ filter.setEol(FixCrLfFilter.CrLf.newInstance(attr.getValue()));
+ }
+
+ /**
+ * Specify how carriage return (CR) characters are to be handled.
+ *
+ * @param attr valid values:
+ * <ul>
+ * <li>add: ensure that there is a CR before every LF
+ * <li>asis: leave CR characters alone
+ * <li>remove: remove all CR characters
+ * </ul>
+ *
+ * @deprecated since 1.4.x.
+ * Use {@link #setEol setEol} instead.
+ */
+ public void setCr(AddAsisRemove attr) {
+ log("DEPRECATED: The cr attribute has been deprecated,",
+ Project.MSG_WARN);
+ log("Please use the eol attribute instead", Project.MSG_WARN);
+ String option = attr.getValue();
+ CrLf c = new CrLf();
+ if (option.equals("remove")) {
+ c.setValue("lf");
+ } else if (option.equals("asis")) {
+ c.setValue("asis");
+ } else {
+ // must be "add"
+ c.setValue("crlf");
+ }
+ setEol(c);
+ }
+
+ /**
+ * Specify how tab characters are to be handled.
+ *
+ * @param attr valid values:
+ * <ul>
+ * <li>add: convert sequences of spaces which span a tab stop to tabs
+ * <li>asis: leave tab and space characters alone
+ * <li>remove: convert tabs to spaces
+ * </ul>
+ */
+ public void setTab(AddAsisRemove attr) {
+ filter.setTab(FixCrLfFilter.AddAsisRemove.newInstance(attr.getValue()));
+ }
+
+ /**
+ * Specify tab length in characters.
+ *
+ * @param tlength specify the length of tab in spaces.
+ * @throws BuildException on error.
+ */
+ public void setTablength(int tlength) throws BuildException {
+ try {
+ filter.setTablength(tlength);
+ } catch (IOException e) {
+ // filter.setTablength throws IOException that would better be
+ // a BuildException
+ throw new BuildException(e.getMessage(), e);
+ }
+ }
+
+ /**
+ * Specify how DOS EOF (control-z) characters are to be handled.
+ *
+ * @param attr valid values:
+ * <ul>
+ * <li>add: ensure that there is an eof at the end of the file
+ * <li>asis: leave eof characters alone
+ * <li>remove: remove any eof character found at the end
+ * </ul>
+ */
+ public void setEof(AddAsisRemove attr) {
+ filter.setEof(FixCrLfFilter.AddAsisRemove.newInstance(attr.getValue()));
+ }
+
+ /**
+ * Specifies the encoding Ant expects the files to be
+ * in--defaults to the platforms default encoding.
+ * @param encoding String encoding name.
+ */
+ public void setEncoding(String encoding) {
+ this.encoding = encoding;
+ }
+
+ /**
+ * Specifies the encoding that the files are
+ * to be written in--same as input encoding by default.
+ * @param outputEncoding String outputEncoding name.
+ */
+ public void setOutputEncoding(String outputEncoding) {
+ this.outputEncoding = outputEncoding;
+ }
+
+ /**
+ * Specify whether a missing EOL will be added
+ * to the final line of a file.
+ * @param fixlast whether to fix the last line.
+ */
+ public void setFixlast(boolean fixlast) {
+ filter.setFixlast(fixlast);
+ }
+
+ /**
+ * Set whether to preserve the last modified time as the original files.
+ * @param preserve true if timestamps should be preserved.
+ * @since Ant 1.6.3
+ */
+ public void setPreserveLastModified(boolean preserve) {
+ preserveLastModified = preserve;
+ }
+
+ /**
+ * Executes the task.
+ * @throws BuildException on error.
+ */
+ public void execute() throws BuildException {
+ // first off, make sure that we've got a srcdir and destdir
+ validate();
+
+ // log options used
+ String enc = encoding == null ? "default" : encoding;
+ log("options:"
+ + " eol=" + filter.getEol().getValue()
+ + " tab=" + filter.getTab().getValue()
+ + " eof=" + filter.getEof().getValue()
+ + " tablength=" + filter.getTablength()
+ + " encoding=" + enc
+ + " outputencoding="
+ + (outputEncoding == null ? enc : outputEncoding),
+ Project.MSG_VERBOSE);
+
+ DirectoryScanner ds = super.getDirectoryScanner(srcDir);
+ String[] files = ds.getIncludedFiles();
+
+ for (int i = 0; i < files.length; i++) {
+ processFile(files[i]);
+ }
+ }
+
+ private void validate() throws BuildException {
+ if (file != null) {
+ if (srcDir != null) {
+ throw new BuildException(ERROR_FILE_AND_SRCDIR);
+ }
+ //patch file into the fileset
+ fileset.setFile(file);
+ //set our parent dir
+ srcDir = file.getParentFile();
+ }
+ if (srcDir == null) {
+ throw new BuildException(
+ FIXCRLF_ERROR + "srcdir attribute must be set!");
+ }
+ if (!srcDir.exists()) {
+ throw new BuildException(
+ FIXCRLF_ERROR + "srcdir does not exist: '" + srcDir + "'");
+ }
+ if (!srcDir.isDirectory()) {
+ throw new BuildException(
+ FIXCRLF_ERROR + "srcdir is not a directory: '" + srcDir + "'");
+ }
+ if (destDir != null) {
+ if (!destDir.exists()) {
+ throw new BuildException(
+ FIXCRLF_ERROR + "destdir does not exist: '"
+ + destDir + "'");
+ }
+ if (!destDir.isDirectory()) {
+ throw new BuildException(
+ FIXCRLF_ERROR + "destdir is not a directory: '"
+ + destDir + "'");
+ }
+ }
+ }
+
+ private void processFile(String file) throws BuildException {
+ File srcFile = new File(srcDir, file);
+ long lastModified = srcFile.lastModified();
+ File destD = destDir == null ? srcDir : destDir;
+
+ if (fcv == null) {
+ FilterChain fc = new FilterChain();
+ fc.add(filter);
+ fcv = new Vector<FilterChain>(1);
+ fcv.add(fc);
+ }
+ File tmpFile = FILE_UTILS.createTempFile("fixcrlf", "", null, true, true);
+ try {
+ FILE_UTILS.copyFile(srcFile, tmpFile, null, fcv, true, false,
+ encoding, outputEncoding == null ? encoding : outputEncoding,
+ getProject());
+
+ File destFile = new File(destD, file);
+
+ boolean destIsWrong = true;
+ if (destFile.exists()) {
+ // Compare the destination with the temp file
+ log("destFile " + destFile + " exists", Project.MSG_DEBUG);
+ destIsWrong = !FILE_UTILS.contentEquals(destFile, tmpFile);
+ log(destFile + (destIsWrong ? " is being written"
+ : " is not written, as the contents are identical"),
+ Project.MSG_DEBUG);
+ }
+ if (destIsWrong) {
+ FILE_UTILS.rename(tmpFile, destFile);
+ if (preserveLastModified) {
+ log("preserved lastModified for " + destFile,
+ Project.MSG_DEBUG);
+ FILE_UTILS.setFileLastModified(destFile, lastModified);
+ }
+ }
+ } catch (IOException e) {
+ throw new BuildException("error running fixcrlf on file " + srcFile, e);
+ } finally {
+ if (tmpFile != null && tmpFile.exists()) {
+ FILE_UTILS.tryHardToDelete(tmpFile);
+ }
+ }
+ }
+
+ /**
+ * Deprecated, the functionality has been moved to filters.FixCrLfFilter.
+ * @deprecated since 1.7.0.
+ */
+ protected class OneLiner implements Enumeration<Object> {
+ private static final int UNDEF = -1;
+ private static final int NOTJAVA = 0;
+ private static final int LOOKING = 1;
+ private static final int INBUFLEN = 8192;
+ private static final int LINEBUFLEN = 200;
+ private static final char CTRLZ = '\u001A';
+
+ private int state = filter.getJavafiles() ? LOOKING : NOTJAVA;
+
+ private StringBuffer eolStr = new StringBuffer(LINEBUFLEN);
+ private StringBuffer eofStr = new StringBuffer();
+
+ private BufferedReader reader;
+ private StringBuffer line = new StringBuffer();
+ private boolean reachedEof = false;
+ private File srcFile;
+
+ /**
+ * Constructor.
+ * @param srcFile the file to read.
+ * @throws BuildException if there is an error.
+ */
+ public OneLiner(File srcFile)
+ throws BuildException {
+ this.srcFile = srcFile;
+ try {
+ reader = new BufferedReader(
+ ((encoding == null) ? new FileReader(srcFile)
+ : new InputStreamReader(
+ new FileInputStream(srcFile), encoding)), INBUFLEN);
+
+ nextLine();
+ } catch (IOException e) {
+ throw new BuildException(srcFile + ": " + e.getMessage(),
+ e, getLocation());
+ }
+ }
+
+ /**
+ * Move to the next line.
+ * @throws BuildException if there is an error.
+ */
+ protected void nextLine()
+ throws BuildException {
+ int ch = -1;
+ int eolcount = 0;
+
+ eolStr = new StringBuffer();
+ line = new StringBuffer();
+
+ try {
+ ch = reader.read();
+ while (ch != -1 && ch != '\r' && ch != '\n') {
+ line.append((char) ch);
+ ch = reader.read();
+ }
+
+ if (ch == -1 && line.length() == 0) {
+ // Eof has been reached
+ reachedEof = true;
+ return;
+ }
+
+ switch ((char) ch) {
+ case '\r':
+ // Check for \r, \r\n and \r\r\n
+ // Regard \r\r not followed by \n as two lines
+ ++eolcount;
+ eolStr.append('\r');
+ reader.mark(2);
+ ch = reader.read();
+ switch (ch) {
+ case '\r':
+ ch = reader.read();
+ if ((char) (ch) == '\n') {
+ eolcount += 2;
+ eolStr.append("\r\n");
+ } else {
+ reader.reset();
+ }
+ break;
+ case '\n':
+ ++eolcount;
+ eolStr.append('\n');
+ break;
+ case -1:
+ // don't reposition when we've reached the end
+ // of the stream
+ break;
+ default:
+ reader.reset();
+ break;
+ } // end of switch ((char)(ch = reader.read()))
+ break;
+
+ case '\n':
+ ++eolcount;
+ eolStr.append('\n');
+ break;
+ default:
+ // Fall tru
+ } // end of switch ((char) ch)
+
+ // if at eolcount == 0 and trailing characters of string
+ // are CTRL-Zs, set eofStr
+ if (eolcount == 0) {
+ int i = line.length();
+ while (--i >= 0 && line.charAt(i) == CTRLZ) {
+ // keep searching for the first ^Z
+ }
+ if (i < line.length() - 1) {
+ // Trailing characters are ^Zs
+ // Construct new line and eofStr
+ eofStr.append(line.toString().substring(i + 1));
+ if (i < 0) {
+ line.setLength(0);
+ reachedEof = true;
+ } else {
+ line.setLength(i + 1);
+ }
+ }
+
+ } // end of if (eolcount == 0)
+
+ } catch (IOException e) {
+ throw new BuildException(srcFile + ": " + e.getMessage(),
+ e, getLocation());
+ }
+ }
+
+ /**
+ * get the eof string.
+ * @return the eof string.
+ */
+ public String getEofStr() {
+ return eofStr.substring(0);
+ }
+
+ /**
+ * get the state.
+ * @return the state.
+ */
+ public int getState() {
+ return state;
+ }
+
+ /**
+ * Set the state.
+ * @param state the value to use.
+ */
+ public void setState(int state) {
+ this.state = state;
+ }
+
+ /**
+ * @return true if there is more elements.
+ */
+ public boolean hasMoreElements() {
+ return !reachedEof;
+ }
+
+ /**
+ * get the next element.
+ * @return the next element.
+ * @throws NoSuchElementException if there is no more.
+ */
+ public Object nextElement()
+ throws NoSuchElementException {
+ if (!hasMoreElements()) {
+ throw new NoSuchElementException("OneLiner");
+ }
+ BufferLine tmpLine =
+ new BufferLine(line.toString(), eolStr.substring(0));
+ nextLine();
+ return tmpLine;
+ }
+
+ /**
+ * Close the reader.
+ * @throws IOException if there is an error.
+ */
+ public void close() throws IOException {
+ if (reader != null) {
+ reader.close();
+ }
+ }
+
+ class BufferLine {
+ private int next = 0;
+ private int column = 0;
+ private int lookahead = UNDEF;
+ private String line;
+ private String eolStr;
+
+ public BufferLine(String line, String eolStr)
+ throws BuildException {
+ next = 0;
+ column = 0;
+ this.line = line;
+ this.eolStr = eolStr;
+ }
+
+ public int getNext() {
+ return next;
+ }
+
+ public void setNext(int next) {
+ this.next = next;
+ }
+
+ public int getLookahead() {
+ return lookahead;
+ }
+
+ public void setLookahead(int lookahead) {
+ this.lookahead = lookahead;
+ }
+
+ public char getChar(int i) {
+ return line.charAt(i);
+ }
+
+ public char getNextChar() {
+ return getChar(next);
+ }
+
+ public char getNextCharInc() {
+ return getChar(next++);
+ }
+
+ public int getColumn() {
+ return column;
+ }
+
+ public void setColumn(int col) {
+ column = col;
+ }
+
+ public int incColumn() {
+ return column++;
+ }
+
+ public int length() {
+ return line.length();
+ }
+
+ public int getEolLength() {
+ return eolStr.length();
+ }
+
+ public String getLineString() {
+ return line;
+ }
+
+ public String getEol() {
+ return eolStr;
+ }
+
+ public String substring(int begin) {
+ return line.substring(begin);
+ }
+
+ public String substring(int begin, int end) {
+ return line.substring(begin, end);
+ }
+
+ public void setState(int state) {
+ OneLiner.this.setState(state);
+ }
+
+ public int getState() {
+ return OneLiner.this.getState();
+ }
+ }
+ }
+
+ /**
+ * Enumerated attribute with the values "asis", "add" and "remove".
+ */
+ public static class AddAsisRemove extends EnumeratedAttribute {
+ /** {@inheritDoc}. */
+ public String[] getValues() {
+ return new String[] {"add", "asis", "remove"};
+ }
+ }
+
+ /**
+ * Enumerated attribute with the values "asis", "cr", "lf" and "crlf".
+ */
+ public static class CrLf extends EnumeratedAttribute {
+ /**
+ * @see EnumeratedAttribute#getValues
+ */
+ /** {@inheritDoc}. */
+ public String[] getValues() {
+ return new String[] {"asis", "cr", "lf", "crlf",
+ "mac", "unix", "dos"};
+ }
+ }
+
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/GUnzip.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/GUnzip.java
new file mode 100644
index 00000000..13e88034
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/GUnzip.java
@@ -0,0 +1,97 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.zip.GZIPInputStream;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.util.FileUtils;
+
+/**
+ * Expands a file that has been compressed with the GZIP
+ * algorithm. Normally used to compress non-compressed archives such
+ * as TAR files.
+ *
+ * @since Ant 1.1
+ *
+ * @ant.task category="packaging"
+ */
+
+public class GUnzip extends Unpack {
+ private static final int BUFFER_SIZE = 8 * 1024;
+ private static final String DEFAULT_EXTENSION = ".gz";
+
+ /**
+ * Get the default extension.
+ * @return the value ".gz"
+ */
+ protected String getDefaultExtension() {
+ return DEFAULT_EXTENSION;
+ }
+
+ /**
+ * Implement the gunzipping.
+ */
+ protected void extract() {
+ if (source.lastModified() > dest.lastModified()) {
+ log("Expanding " + source.getAbsolutePath() + " to "
+ + dest.getAbsolutePath());
+
+ FileOutputStream out = null;
+ GZIPInputStream zIn = null;
+ InputStream fis = null;
+ try {
+ out = new FileOutputStream(dest);
+ fis = srcResource.getInputStream();
+ zIn = new GZIPInputStream(fis);
+ byte[] buffer = new byte[BUFFER_SIZE];
+ int count = 0;
+ do {
+ out.write(buffer, 0, count);
+ count = zIn.read(buffer, 0, buffer.length);
+ } while (count != -1);
+ } catch (IOException ioe) {
+ String msg = "Problem expanding gzip " + ioe.getMessage();
+ throw new BuildException(msg, ioe, getLocation());
+ } finally {
+ FileUtils.close(fis);
+ FileUtils.close(out);
+ FileUtils.close(zIn);
+ }
+ }
+ }
+
+ /**
+ * Whether this task can deal with non-file resources.
+ *
+ * <p>This implementation returns true only if this task is
+ * &lt;gunzip&gt;. Any subclass of this class that also wants to
+ * support non-file resources needs to override this method. We
+ * need to do so for backwards compatibility reasons since we
+ * can't expect subclasses to support resources.</p>
+ * @return true if this task supports non file resources.
+ * @since Ant 1.7
+ */
+ protected boolean supportsNonFileResources() {
+ return getClass().equals(GUnzip.class);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/GZip.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/GZip.java
new file mode 100644
index 00000000..029f414d
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/GZip.java
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.zip.GZIPOutputStream;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.util.FileUtils;
+
+/**
+ * Compresses a file with the GZIP algorithm. Normally used to compress
+ * non-compressed archives such as TAR files.
+ *
+ * @since Ant 1.1
+ *
+ * @ant.task category="packaging"
+ */
+
+public class GZip extends Pack {
+ /**
+ * perform the GZip compression operation.
+ */
+ protected void pack() {
+ GZIPOutputStream zOut = null;
+ try {
+ zOut = new GZIPOutputStream(new FileOutputStream(zipFile));
+ zipResource(getSrcResource(), zOut);
+ } catch (IOException ioe) {
+ String msg = "Problem creating gzip " + ioe.getMessage();
+ throw new BuildException(msg, ioe, getLocation());
+ } finally {
+ FileUtils.close(zOut);
+ }
+ }
+
+ /**
+ * Whether this task can deal with non-file resources.
+ *
+ * <p>This implementation returns true only if this task is
+ * &lt;gzip&gt;. Any subclass of this class that also wants to
+ * support non-file resources needs to override this method. We
+ * need to do so for backwards compatibility reasons since we
+ * can't expect subclasses to support resources.</p>
+ * @return true if this case supports non file resources.
+ * @since Ant 1.7
+ */
+ protected boolean supportsNonFileResources() {
+ return getClass().equals(GZip.class);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/GenerateKey.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/GenerateKey.java
new file mode 100644
index 00000000..69e719ce
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/GenerateKey.java
@@ -0,0 +1,420 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs;
+
+import java.util.Enumeration;
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.types.Commandline;
+import org.apache.tools.ant.util.JavaEnvUtils;
+
+/**
+ * Generates a key in a keystore.
+ *
+ * @since Ant 1.2
+ *
+ * @ant.task name="genkey" category="java"
+ */
+public class GenerateKey extends Task {
+
+ /**
+ * A DistinguishedName parameter.
+ * This is a nested element in a dname nested element.
+ */
+ public static class DnameParam {
+ private String name;
+ private String value;
+
+ /**
+ * Set the name attribute.
+ * @param name a <code>String</code> value
+ */
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ /**
+ * Get the name attribute.
+ * @return the name.
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Set the value attribute.
+ * @param value a <code>String</code> value
+ */
+ public void setValue(String value) {
+ this.value = value;
+ }
+
+ /**
+ * Get the value attribute.
+ * @return the value.
+ */
+ public String getValue() {
+ return value;
+ }
+ }
+
+ /**
+ * A class corresponding to the dname nested element.
+ */
+ public static class DistinguishedName {
+ private Vector<DnameParam> params = new Vector<DnameParam>();
+
+ /**
+ * Create a param nested element.
+ * @return a DnameParam object to be configured.
+ */
+ public Object createParam() {
+ DnameParam param = new DnameParam();
+ params.addElement(param);
+
+ return param;
+ }
+
+ /**
+ * Get the nested parameters.
+ * @return an enumeration of the nested parameters.
+ */
+ public Enumeration<DnameParam> getParams() {
+ return params.elements();
+ }
+
+ /**
+ * Generate a string rep of this distinguished name.
+ * The format is each of the parameters (name = value)
+ * separated by ','.
+ * This is used on the command line.
+ * @return a string rep of this name
+ */
+ public String toString() {
+ final int size = params.size();
+ final StringBuffer sb = new StringBuffer();
+ boolean firstPass = true;
+
+ for (int i = 0; i < size; i++) {
+ if (!firstPass) {
+ sb.append(" ,");
+ }
+ firstPass = false;
+
+ final DnameParam param = (DnameParam) params.elementAt(i);
+ sb.append(encode(param.getName()));
+ sb.append('=');
+ sb.append(encode(param.getValue()));
+ }
+
+ return sb.toString();
+ }
+
+ /**
+ * Encode a name or value.
+ * The encoded result is the same as the input string
+ * except that each ',' is replaced by a '\,'.
+ * @param string the value to be encoded
+ * @return the encoded value.
+ */
+ public String encode(final String string) {
+ int end = string.indexOf(',');
+
+ if (-1 == end) {
+ return string;
+ }
+
+ final StringBuffer sb = new StringBuffer();
+
+ int start = 0;
+
+ while (-1 != end) {
+ sb.append(string.substring(start, end));
+ sb.append("\\,");
+ start = end + 1;
+ end = string.indexOf(',', start);
+ }
+
+ sb.append(string.substring(start));
+
+ return sb.toString();
+ }
+ }
+
+ // CheckStyle:VisibilityModifier OFF - bc
+
+ /**
+ * The alias of signer.
+ */
+ protected String alias;
+
+ /**
+ * The name of keystore file.
+ */
+ protected String keystore;
+ protected String storepass;
+ protected String storetype;
+ protected String keypass;
+
+ protected String sigalg;
+ protected String keyalg;
+ protected String dname;
+ protected DistinguishedName expandedDname;
+ protected int keysize;
+ protected int validity;
+ protected boolean verbose;
+ // CheckStyle:VisibilityModifier ON
+
+ /**
+ * Distinguished name list.
+ *
+ * @return Distinguished name container.
+ * @throws BuildException If specified more than once or dname
+ * attribute is used.
+ */
+ public DistinguishedName createDname() throws BuildException {
+ if (null != expandedDname) {
+ throw new BuildException("DName sub-element can only be "
+ + "specified once.");
+ }
+ if (null != dname) {
+ throw new BuildException("It is not possible to specify dname "
+ + " both as attribute and element.");
+ }
+ expandedDname = new DistinguishedName();
+ return expandedDname;
+ }
+
+ /**
+ * The distinguished name for entity.
+ *
+ * @param dname distinguished name
+ */
+ public void setDname(final String dname) {
+ if (null != expandedDname) {
+ throw new BuildException("It is not possible to specify dname "
+ + " both as attribute and element.");
+ }
+ this.dname = dname;
+ }
+
+ /**
+ * The alias to add under.
+ *
+ * @param alias alias to add under
+ */
+ public void setAlias(final String alias) {
+ this.alias = alias;
+ }
+
+ /**
+ * Keystore location.
+ *
+ * @param keystore location
+ */
+ public void setKeystore(final String keystore) {
+ this.keystore = keystore;
+ }
+
+ /**
+ * Password for keystore integrity.
+ * Must be at least 6 characters long.
+ * @param storepass password
+ */
+ public void setStorepass(final String storepass) {
+ this.storepass = storepass;
+ }
+
+ /**
+ * Keystore type.
+ *
+ * @param storetype type
+ */
+ public void setStoretype(final String storetype) {
+ this.storetype = storetype;
+ }
+
+ /**
+ * Password for private key (if different).
+ *
+ * @param keypass password
+ */
+ public void setKeypass(final String keypass) {
+ this.keypass = keypass;
+ }
+
+ /**
+ * The algorithm to use in signing.
+ *
+ * @param sigalg algorithm
+ */
+ public void setSigalg(final String sigalg) {
+ this.sigalg = sigalg;
+ }
+
+ /**
+ * The method to use when generating name-value pair.
+ * @param keyalg algorithm
+ */
+ public void setKeyalg(final String keyalg) {
+ this.keyalg = keyalg;
+ }
+
+ /**
+ * Indicates the size of key generated.
+ *
+ * @param keysize size of key
+ * @throws BuildException If not an Integer
+ * @todo Could convert this to a plain Integer setter.
+ */
+ public void setKeysize(final String keysize) throws BuildException {
+ try {
+ this.keysize = Integer.parseInt(keysize);
+ } catch (final NumberFormatException nfe) {
+ throw new BuildException("KeySize attribute should be a integer");
+ }
+ }
+
+ /**
+ * Indicates how many days certificate is valid.
+ *
+ * @param validity days valid
+ * @throws BuildException If not an Integer
+ */
+ public void setValidity(final String validity) throws BuildException {
+ try {
+ this.validity = Integer.parseInt(validity);
+ } catch (final NumberFormatException nfe) {
+ throw new BuildException("Validity attribute should be a integer");
+ }
+ }
+
+ /**
+ * If true, verbose output when signing.
+ * @param verbose verbose or not
+ */
+ public void setVerbose(final boolean verbose) {
+ this.verbose = verbose;
+ }
+
+ /**
+ * Execute the task.
+ * @throws BuildException on error
+ */
+ public void execute() throws BuildException {
+
+ if (null == alias) {
+ throw new BuildException("alias attribute must be set");
+ }
+
+ if (null == storepass) {
+ throw new BuildException("storepass attribute must be set");
+ }
+
+ if (null == dname && null == expandedDname) {
+ throw new BuildException("dname must be set");
+ }
+
+ final StringBuffer sb = new StringBuffer();
+
+ sb.append("-genkey ");
+
+ if (verbose) {
+ sb.append("-v ");
+ }
+
+ sb.append("-alias \"");
+ sb.append(alias);
+ sb.append("\" ");
+
+ if (null != dname) {
+ sb.append("-dname \"");
+ sb.append(dname);
+ sb.append("\" ");
+ }
+
+ if (null != expandedDname) {
+ sb.append("-dname \"");
+ sb.append(expandedDname);
+ sb.append("\" ");
+ }
+
+ if (null != keystore) {
+ sb.append("-keystore \"");
+ sb.append(keystore);
+ sb.append("\" ");
+ }
+
+ if (null != storepass) {
+ sb.append("-storepass \"");
+ sb.append(storepass);
+ sb.append("\" ");
+ }
+
+ if (null != storetype) {
+ sb.append("-storetype \"");
+ sb.append(storetype);
+ sb.append("\" ");
+ }
+
+ sb.append("-keypass \"");
+ if (null != keypass) {
+ sb.append(keypass);
+ } else {
+ sb.append(storepass);
+ }
+ sb.append("\" ");
+
+ if (null != sigalg) {
+ sb.append("-sigalg \"");
+ sb.append(sigalg);
+ sb.append("\" ");
+ }
+
+ if (null != keyalg) {
+ sb.append("-keyalg \"");
+ sb.append(keyalg);
+ sb.append("\" ");
+ }
+
+
+ if (0 < keysize) {
+ sb.append("-keysize \"");
+ sb.append(keysize);
+ sb.append("\" ");
+ }
+
+ if (0 < validity) {
+ sb.append("-validity \"");
+ sb.append(validity);
+ sb.append("\" ");
+ }
+
+ log("Generating Key for " + alias);
+ final ExecTask cmd = new ExecTask(this);
+ cmd.setExecutable(JavaEnvUtils.getJdkExecutable("keytool"));
+ Commandline.Argument arg = cmd.createArg();
+ arg.setLine(sb.toString());
+ cmd.setFailonerror(true);
+ cmd.setTaskName(getTaskName());
+ cmd.execute();
+ }
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Get.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Get.java
new file mode 100644
index 00000000..c636ab54
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Get.java
@@ -0,0 +1,883 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.Date;
+import java.util.zip.GZIPInputStream;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.MagicNames;
+import org.apache.tools.ant.Main;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.types.Mapper;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.ResourceCollection;
+import org.apache.tools.ant.types.resources.Resources;
+import org.apache.tools.ant.types.resources.URLProvider;
+import org.apache.tools.ant.types.resources.URLResource;
+import org.apache.tools.ant.util.FileNameMapper;
+import org.apache.tools.ant.util.FileUtils;
+
+/**
+ * Gets a particular file from a URL source.
+ * Options include verbose reporting, timestamp based fetches and controlling
+ * actions on failures. NB: access through a firewall only works if the whole
+ * Java runtime is correctly configured.
+ *
+ * @since Ant 1.1
+ *
+ * @ant.task category="network"
+ */
+public class Get extends Task {
+ private static final int NUMBER_RETRIES = 3;
+ private static final int DOTS_PER_LINE = 50;
+ private static final int BIG_BUFFER_SIZE = 100 * 1024;
+ private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+ private static final int REDIRECT_LIMIT = 25;
+ // HttpURLConnection doesn't have a constant for this in Java5 and
+ // what it calls HTTP_MOVED_TEMP would better be FOUND
+ private static final int HTTP_MOVED_TEMP = 307;
+
+ private static final String HTTP = "http";
+ private static final String HTTPS = "https";
+
+ private static final String DEFAULT_AGENT_PREFIX = "Apache Ant";
+ private static final String GZIP_CONTENT_ENCODING = "gzip";
+
+ private final Resources sources = new Resources();
+ private File destination; // required
+ private boolean verbose = false;
+ private boolean quiet = false;
+ private boolean useTimestamp = false; //off by default
+ private boolean ignoreErrors = false;
+ private String uname = null;
+ private String pword = null;
+ private long maxTime = 0;
+ private int numberRetries = NUMBER_RETRIES;
+ private boolean skipExisting = false;
+ private boolean httpUseCaches = true; // on by default
+ private boolean tryGzipEncoding = false;
+ private Mapper mapperElement = null;
+ private String userAgent =
+ System.getProperty(MagicNames.HTTP_AGENT_PROPERTY,
+ DEFAULT_AGENT_PREFIX + "/"
+ + Main.getShortAntVersion());
+
+ /**
+ * Does the work.
+ *
+ * @exception BuildException Thrown in unrecoverable error.
+ */
+ @Override
+ public void execute() throws BuildException {
+ checkAttributes();
+
+ for (final Resource r : sources) {
+ final URLProvider up = r.as(URLProvider.class);
+ final URL source = up.getURL();
+
+ File dest = destination;
+ if (destination.isDirectory()) {
+ if (mapperElement == null) {
+ String path = source.getPath();
+ if (path.endsWith("/")) {
+ path = path.substring(0, path.length() - 1);
+ }
+ final int slash = path.lastIndexOf("/");
+ if (slash > -1) {
+ path = path.substring(slash + 1);
+ }
+ dest = new File(destination, path);
+ } else {
+ final FileNameMapper mapper = mapperElement.getImplementation();
+ final String[] d = mapper.mapFileName(source.toString());
+ if (d == null) {
+ log("skipping " + r + " - mapper can't handle it",
+ Project.MSG_WARN);
+ continue;
+ } else if (d.length == 0) {
+ log("skipping " + r + " - mapper returns no file name",
+ Project.MSG_WARN);
+ continue;
+ } else if (d.length > 1) {
+ log("skipping " + r + " - mapper returns multiple file"
+ + " names", Project.MSG_WARN);
+ continue;
+ }
+ dest = new File(destination, d[0]);
+ }
+ }
+
+ //set up logging
+ final int logLevel = Project.MSG_INFO;
+ DownloadProgress progress = null;
+ if (verbose) {
+ progress = new VerboseProgress(System.out);
+ }
+
+ //execute the get
+ try {
+ doGet(source, dest, logLevel, progress);
+ } catch (final IOException ioe) {
+ log("Error getting " + source + " to " + dest);
+ if (!ignoreErrors) {
+ throw new BuildException(ioe, getLocation());
+ }
+ }
+ }
+ }
+
+ /**
+ * make a get request, with the supplied progress and logging info.
+ * All the other config parameters are set at the task level,
+ * source, dest, ignoreErrors, etc.
+ * @param logLevel level to log at, see {@link Project#log(String, int)}
+ * @param progress progress callback; null for no-callbacks
+ * @return true for a successful download, false otherwise.
+ * The return value is only relevant when {@link #ignoreErrors} is true, as
+ * when false all failures raise BuildExceptions.
+ * @throws IOException for network trouble
+ * @throws BuildException for argument errors, or other trouble when ignoreErrors
+ * is false.
+ * @deprecated only gets the first configured resource
+ */
+ @Deprecated
+ public boolean doGet(final int logLevel, final DownloadProgress progress)
+ throws IOException {
+ checkAttributes();
+ for (final Resource r : sources) {
+ final URLProvider up = r.as(URLProvider.class);
+ final URL source = up.getURL();
+ return doGet(source, destination, logLevel, progress);
+ }
+ /*NOTREACHED*/
+ return false;
+ }
+
+ /**
+ * make a get request, with the supplied progress and logging info.
+ *
+ * All the other config parameters like ignoreErrors are set at
+ * the task level.
+ * @param source the URL to get
+ * @param dest the target file
+ * @param logLevel level to log at, see {@link Project#log(String, int)}
+ * @param progress progress callback; null for no-callbacks
+ * @return true for a successful download, false otherwise.
+ * The return value is only relevant when {@link #ignoreErrors} is true, as
+ * when false all failures raise BuildExceptions.
+ * @throws IOException for network trouble
+ * @throws BuildException for argument errors, or other trouble when ignoreErrors
+ * is false.
+ * @since Ant 1.8.0
+ */
+ public boolean doGet(final URL source, final File dest, final int logLevel,
+ DownloadProgress progress)
+ throws IOException {
+
+ if (dest.exists() && skipExisting) {
+ log("Destination already exists (skipping): "
+ + dest.getAbsolutePath(), logLevel);
+ return true;
+ }
+
+ //dont do any progress, unless asked
+ if (progress == null) {
+ progress = new NullProgress();
+ }
+ log("Getting: " + source, logLevel);
+ log("To: " + dest.getAbsolutePath(), logLevel);
+
+ //set the timestamp to the file date.
+ long timestamp = 0;
+
+ boolean hasTimestamp = false;
+ if (useTimestamp && dest.exists()) {
+ timestamp = dest.lastModified();
+ if (verbose) {
+ final Date t = new Date(timestamp);
+ log("local file date : " + t.toString(), logLevel);
+ }
+ hasTimestamp = true;
+ }
+
+ final GetThread getThread = new GetThread(source, dest,
+ hasTimestamp, timestamp, progress,
+ logLevel, userAgent);
+ getThread.setDaemon(true);
+ getProject().registerThreadTask(getThread, this);
+ getThread.start();
+ try {
+ getThread.join(maxTime * 1000);
+ } catch (final InterruptedException ie) {
+ log("interrupted waiting for GET to finish",
+ Project.MSG_VERBOSE);
+ }
+
+ if (getThread.isAlive()) {
+ final String msg = "The GET operation took longer than " + maxTime
+ + " seconds, stopping it.";
+ if (ignoreErrors) {
+ log(msg);
+ }
+ getThread.closeStreams();
+ if (!ignoreErrors) {
+ throw new BuildException(msg);
+ }
+ return false;
+ }
+
+ return getThread.wasSuccessful();
+ }
+
+ @Override
+ public void log(final String msg, final int msgLevel) {
+ if (!quiet || msgLevel >= Project.MSG_ERR) {
+ super.log(msg, msgLevel);
+ }
+ }
+
+ /**
+ * Check the attributes.
+ */
+ private void checkAttributes() {
+
+ if (userAgent == null || userAgent.trim().length() == 0) {
+ throw new BuildException("userAgent may not be null or empty");
+ }
+
+ if (sources.size() == 0) {
+ throw new BuildException("at least one source is required",
+ getLocation());
+ }
+ for (final Resource r : sources) {
+ final URLProvider up = r.as(URLProvider.class);
+ if (up == null) {
+ throw new BuildException("Only URLProvider resources are"
+ + " supported", getLocation());
+ }
+ }
+
+ if (destination == null) {
+ throw new BuildException("dest attribute is required", getLocation());
+ }
+
+ if (destination.exists() && sources.size() > 1
+ && !destination.isDirectory()) {
+ throw new BuildException("The specified destination is not a"
+ + " directory",
+ getLocation());
+ }
+
+ if (destination.exists() && !destination.canWrite()) {
+ throw new BuildException("Can't write to "
+ + destination.getAbsolutePath(),
+ getLocation());
+ }
+
+ if (sources.size() > 1 && !destination.exists()) {
+ destination.mkdirs();
+ }
+ }
+
+ /**
+ * Set an URL to get.
+ *
+ * @param u URL for the file.
+ */
+ public void setSrc(final URL u) {
+ add(new URLResource(u));
+ }
+
+ /**
+ * Adds URLs to get.
+ * @since Ant 1.8.0
+ */
+ public void add(final ResourceCollection rc) {
+ sources.add(rc);
+ }
+
+ /**
+ * Where to copy the source file.
+ *
+ * @param dest Path to file.
+ */
+ public void setDest(final File dest) {
+ this.destination = dest;
+ }
+
+ /**
+ * If true, show verbose progress information.
+ *
+ * @param v if "true" then be verbose
+ */
+ public void setVerbose(final boolean v) {
+ verbose = v;
+ }
+
+ /**
+ * If true, set default log level to Project.MSG_ERR.
+ *
+ * @param v if "true" then be quiet
+ * @since Ant 1.9.4
+ */
+ public void setQuiet(final boolean v){
+ this.quiet = v;
+ }
+
+ /**
+ * If true, log errors but do not treat as fatal.
+ *
+ * @param v if "true" then don't report download errors up to ant
+ */
+ public void setIgnoreErrors(final boolean v) {
+ ignoreErrors = v;
+ }
+
+ /**
+ * If true, conditionally download a file based on the timestamp
+ * of the local copy.
+ *
+ * <p>In this situation, the if-modified-since header is set so
+ * that the file is only fetched if it is newer than the local
+ * file (or there is no local file) This flag is only valid on
+ * HTTP connections, it is ignored in other cases. When the flag
+ * is set, the local copy of the downloaded file will also have
+ * its timestamp set to the remote file time.</p>
+ *
+ * <p>Note that remote files of date 1/1/1970 (GMT) are treated as
+ * 'no timestamp', and web servers often serve files with a
+ * timestamp in the future by replacing their timestamp with that
+ * of the current time. Also, inter-computer clock differences can
+ * cause no end of grief.</p>
+ * @param v "true" to enable file time fetching
+ */
+ public void setUseTimestamp(final boolean v) {
+ useTimestamp = v;
+ }
+
+
+ /**
+ * Username for basic auth.
+ *
+ * @param u username for authentication
+ */
+ public void setUsername(final String u) {
+ this.uname = u;
+ }
+
+ /**
+ * password for the basic authentication.
+ *
+ * @param p password for authentication
+ */
+ public void setPassword(final String p) {
+ this.pword = p;
+ }
+
+ /**
+ * The time in seconds the download is allowed to take before
+ * being terminated.
+ *
+ * @since Ant 1.8.0
+ */
+ public void setMaxTime(final long maxTime) {
+ this.maxTime = maxTime;
+ }
+
+ /**
+ * The number of retries to attempt upon error, defaults to 3.
+ *
+ * @param r retry count
+ *
+ * @since Ant 1.8.0
+ */
+ public void setRetries(final int r) {
+ this.numberRetries = r;
+ }
+
+ /**
+ * Skip files that already exist locally.
+ *
+ * @param s "true" to skip existing destination files
+ *
+ * @since Ant 1.8.0
+ */
+ public void setSkipExisting(final boolean s) {
+ this.skipExisting = s;
+ }
+
+ /**
+ * HTTP connections only - set the user-agent to be used
+ * when communicating with remote server. if null, then
+ * the value is considered unset and the behaviour falls
+ * back to the default of the http API.
+ *
+ * @since Ant 1.9.3
+ */
+ public void setUserAgent(final String userAgent) {
+ this.userAgent = userAgent;
+ }
+
+ /**
+ * HTTP connections only - control caching on the
+ * HttpUrlConnection: httpConnection.setUseCaches(); if false, do
+ * not allow caching on the HttpUrlConnection.
+ *
+ * <p>Defaults to true (allow caching, which is also the
+ * HttpUrlConnection default value.</p>
+ *
+ * @since Ant 1.8.0
+ */
+ public void setHttpUseCaches(final boolean httpUseCache) {
+ this.httpUseCaches = httpUseCache;
+ }
+
+ /**
+ * Whether to transparently try to reduce bandwidth by telling the
+ * server ant would support gzip encoding.
+ *
+ * <p>Setting this to true also means Ant will uncompress
+ * <code>.tar.gz</code> and similar files automatically.</p>
+ *
+ * @since Ant 1.9.5
+ */
+ public void setTryGzipEncoding(boolean b) {
+ tryGzipEncoding = b;
+ }
+
+ /**
+ * Define the mapper to map source to destination files.
+ * @return a mapper to be configured.
+ * @exception BuildException if more than one mapper is defined.
+ * @since Ant 1.8.0
+ */
+ public Mapper createMapper() throws BuildException {
+ if (mapperElement != null) {
+ throw new BuildException("Cannot define more than one mapper",
+ getLocation());
+ }
+ mapperElement = new Mapper(getProject());
+ return mapperElement;
+ }
+
+ /**
+ * Add a nested filenamemapper.
+ * @param fileNameMapper the mapper to add.
+ * @since Ant 1.8.0
+ */
+ public void add(final FileNameMapper fileNameMapper) {
+ createMapper().add(fileNameMapper);
+ }
+
+ /**
+ * Provide this for Backward Compatibility.
+ */
+ protected static class Base64Converter
+ extends org.apache.tools.ant.util.Base64Converter {
+ }
+
+ /**
+ * Interface implemented for reporting
+ * progress of downloading.
+ */
+ public interface DownloadProgress {
+ /**
+ * begin a download
+ */
+ void beginDownload();
+
+ /**
+ * tick handler
+ *
+ */
+ void onTick();
+
+ /**
+ * end a download
+ */
+ void endDownload();
+ }
+
+ /**
+ * do nothing with progress info
+ */
+ public static class NullProgress implements DownloadProgress {
+
+ /**
+ * begin a download
+ */
+ public void beginDownload() {
+ }
+
+ /**
+ * tick handler
+ *
+ */
+ public void onTick() {
+ }
+
+ /**
+ * end a download
+ */
+ public void endDownload() {
+ }
+ }
+
+ /**
+ * verbose progress system prints to some output stream
+ */
+ public static class VerboseProgress implements DownloadProgress {
+ private int dots = 0;
+ // CheckStyle:VisibilityModifier OFF - bc
+ PrintStream out;
+ // CheckStyle:VisibilityModifier ON
+
+ /**
+ * Construct a verbose progress reporter.
+ * @param out the output stream.
+ */
+ public VerboseProgress(final PrintStream out) {
+ this.out = out;
+ }
+
+ /**
+ * begin a download
+ */
+ public void beginDownload() {
+ dots = 0;
+ }
+
+ /**
+ * tick handler
+ *
+ */
+ public void onTick() {
+ out.print(".");
+ if (dots++ > DOTS_PER_LINE) {
+ out.flush();
+ dots = 0;
+ }
+ }
+
+ /**
+ * end a download
+ */
+ public void endDownload() {
+ out.println();
+ out.flush();
+ }
+ }
+
+ private class GetThread extends Thread {
+
+ private final URL source;
+ private final File dest;
+ private final boolean hasTimestamp;
+ private final long timestamp;
+ private final DownloadProgress progress;
+ private final int logLevel;
+
+ private boolean success = false;
+ private IOException ioexception = null;
+ private BuildException exception = null;
+ private InputStream is = null;
+ private OutputStream os = null;
+ private URLConnection connection;
+ private int redirections = 0;
+ private String userAgent = null;
+
+ GetThread(final URL source, final File dest,
+ final boolean h, final long t, final DownloadProgress p, final int l, final String userAgent) {
+ this.source = source;
+ this.dest = dest;
+ hasTimestamp = h;
+ timestamp = t;
+ progress = p;
+ logLevel = l;
+ this.userAgent = userAgent;
+ }
+
+ @Override
+ public void run() {
+ try {
+ success = get();
+ } catch (final IOException ioex) {
+ ioexception = ioex;
+ } catch (final BuildException bex) {
+ exception = bex;
+ }
+ }
+
+ private boolean get() throws IOException, BuildException {
+
+ connection = openConnection(source);
+
+ if (connection == null) {
+ return false;
+ }
+
+ final boolean downloadSucceeded = downloadFile();
+
+ //if (and only if) the use file time option is set, then
+ //the saved file now has its timestamp set to that of the
+ //downloaded file
+ if (downloadSucceeded && useTimestamp) {
+ updateTimeStamp();
+ }
+
+ return downloadSucceeded;
+ }
+
+
+ private boolean redirectionAllowed(final URL aSource, final URL aDest) {
+ if (!(aSource.getProtocol().equals(aDest.getProtocol()) || (HTTP
+ .equals(aSource.getProtocol()) && HTTPS.equals(aDest
+ .getProtocol())))) {
+ final String message = "Redirection detected from "
+ + aSource.getProtocol() + " to " + aDest.getProtocol()
+ + ". Protocol switch unsafe, not allowed.";
+ if (ignoreErrors) {
+ log(message, logLevel);
+ return false;
+ } else {
+ throw new BuildException(message);
+ }
+ }
+
+ redirections++;
+ if (redirections > REDIRECT_LIMIT) {
+ final String message = "More than " + REDIRECT_LIMIT
+ + " times redirected, giving up";
+ if (ignoreErrors) {
+ log(message, logLevel);
+ return false;
+ } else {
+ throw new BuildException(message);
+ }
+ }
+
+
+ return true;
+ }
+
+ private URLConnection openConnection(final URL aSource) throws IOException {
+
+ // set up the URL connection
+ final URLConnection connection = aSource.openConnection();
+ // modify the headers
+ // NB: things like user authentication could go in here too.
+ if (hasTimestamp) {
+ connection.setIfModifiedSince(timestamp);
+ }
+ // Set the user agent
+ connection.addRequestProperty("User-Agent", this.userAgent);
+
+ // prepare Java 1.1 style credentials
+ if (uname != null || pword != null) {
+ final String up = uname + ":" + pword;
+ String encoding;
+ // we do not use the sun impl for portability,
+ // and always use our own implementation for consistent
+ // testing
+ final Base64Converter encoder = new Base64Converter();
+ encoding = encoder.encode(up.getBytes());
+ connection.setRequestProperty("Authorization", "Basic "
+ + encoding);
+ }
+
+ if (tryGzipEncoding) {
+ connection.setRequestProperty("Accept-Encoding", GZIP_CONTENT_ENCODING);
+ }
+
+ if (connection instanceof HttpURLConnection) {
+ ((HttpURLConnection) connection)
+ .setInstanceFollowRedirects(false);
+ ((HttpURLConnection) connection)
+ .setUseCaches(httpUseCaches);
+ }
+ // connect to the remote site (may take some time)
+ try {
+ connection.connect();
+ } catch (final NullPointerException e) {
+ //bad URLs can trigger NPEs in some JVMs
+ throw new BuildException("Failed to parse " + source.toString(), e);
+ }
+
+ // First check on a 301 / 302 (moved) response (HTTP only)
+ if (connection instanceof HttpURLConnection) {
+ final HttpURLConnection httpConnection = (HttpURLConnection) connection;
+ final int responseCode = httpConnection.getResponseCode();
+ if (isMoved(responseCode)) {
+ final String newLocation = httpConnection.getHeaderField("Location");
+ final String message = aSource
+ + (responseCode == HttpURLConnection.HTTP_MOVED_PERM ? " permanently"
+ : "") + " moved to " + newLocation;
+ log(message, logLevel);
+ final URL newURL = new URL(aSource, newLocation);
+ if (!redirectionAllowed(aSource, newURL)) {
+ return null;
+ }
+ return openConnection(newURL);
+ }
+ // next test for a 304 result (HTTP only)
+ final long lastModified = httpConnection.getLastModified();
+ if (responseCode == HttpURLConnection.HTTP_NOT_MODIFIED
+ || (lastModified != 0 && hasTimestamp && timestamp >= lastModified)) {
+ // not modified so no file download. just return
+ // instead and trace out something so the user
+ // doesn't think that the download happened when it
+ // didn't
+ log("Not modified - so not downloaded", logLevel);
+ return null;
+ }
+ // test for 401 result (HTTP only)
+ if (responseCode == HttpURLConnection.HTTP_UNAUTHORIZED) {
+ final String message = "HTTP Authorization failure";
+ if (ignoreErrors) {
+ log(message, logLevel);
+ return null;
+ } else {
+ throw new BuildException(message);
+ }
+ }
+ }
+
+ //REVISIT: at this point even non HTTP connections may
+ //support the if-modified-since behaviour -we just check
+ //the date of the content and skip the write if it is not
+ //newer. Some protocols (FTP) don't include dates, of
+ //course.
+ return connection;
+ }
+
+ private boolean isMoved(final int responseCode) {
+ return responseCode == HttpURLConnection.HTTP_MOVED_PERM ||
+ responseCode == HttpURLConnection.HTTP_MOVED_TEMP ||
+ responseCode == HttpURLConnection.HTTP_SEE_OTHER ||
+ responseCode == HTTP_MOVED_TEMP;
+ }
+
+ private boolean downloadFile()
+ throws FileNotFoundException, IOException {
+ for (int i = 0; i < numberRetries; i++) {
+ // this three attempt trick is to get round quirks in different
+ // Java implementations. Some of them take a few goes to bind
+ // properly; we ignore the first couple of such failures.
+ try {
+ is = connection.getInputStream();
+ break;
+ } catch (final IOException ex) {
+ log("Error opening connection " + ex, logLevel);
+ }
+ }
+ if (is == null) {
+ log("Can't get " + source + " to " + dest, logLevel);
+ if (ignoreErrors) {
+ return false;
+ }
+ throw new BuildException("Can't get " + source + " to " + dest,
+ getLocation());
+ }
+
+ if (tryGzipEncoding
+ && GZIP_CONTENT_ENCODING.equals(connection.getContentEncoding())) {
+ is = new GZIPInputStream(is);
+ }
+
+ os = new FileOutputStream(dest);
+ progress.beginDownload();
+ boolean finished = false;
+ try {
+ final byte[] buffer = new byte[BIG_BUFFER_SIZE];
+ int length;
+ while (!isInterrupted() && (length = is.read(buffer)) >= 0) {
+ os.write(buffer, 0, length);
+ progress.onTick();
+ }
+ finished = !isInterrupted();
+ } finally {
+ FileUtils.close(os);
+ FileUtils.close(is);
+
+ // we have started to (over)write dest, but failed.
+ // Try to delete the garbage we'd otherwise leave
+ // behind.
+ if (!finished) {
+ dest.delete();
+ }
+ }
+ progress.endDownload();
+ return true;
+ }
+
+ private void updateTimeStamp() {
+ final long remoteTimestamp = connection.getLastModified();
+ if (verbose) {
+ final Date t = new Date(remoteTimestamp);
+ log("last modified = " + t.toString()
+ + ((remoteTimestamp == 0)
+ ? " - using current time instead"
+ : ""), logLevel);
+ }
+ if (remoteTimestamp != 0) {
+ FILE_UTILS.setFileLastModified(dest, remoteTimestamp);
+ }
+ }
+
+ /**
+ * Has the download completed successfully?
+ *
+ * <p>Re-throws any exception caught during executaion.</p>
+ */
+ boolean wasSuccessful() throws IOException, BuildException {
+ if (ioexception != null) {
+ throw ioexception;
+ }
+ if (exception != null) {
+ throw exception;
+ }
+ return success;
+ }
+
+ /**
+ * Closes streams, interrupts the download, may delete the
+ * output file.
+ */
+ void closeStreams() {
+ interrupt();
+ FileUtils.close(os);
+ FileUtils.close(is);
+ if (!success && dest.exists()) {
+ dest.delete();
+ }
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/HostInfo.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/HostInfo.java
new file mode 100644
index 00000000..5cd433ca
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/HostInfo.java
@@ -0,0 +1,256 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.net.Inet4Address;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.net.NetworkInterface;
+import java.util.Arrays;
+import java.util.Enumeration;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+
+/**
+ * Sets properties to the host provided, or localhost if no information is
+ * provided. The default properties are NAME, FQDN, ADDR4, ADDR6;
+ *
+ * @since Ant 1.8
+ * @ant.task category="utility"
+ */
+
+
+public class HostInfo extends Task {
+ private static final String DEF_REM_ADDR6 = "::";
+
+ private static final String DEF_REM_ADDR4 = "0.0.0.0";
+
+ private static final String DEF_LOCAL_ADDR6 = "::1";
+
+ private static final String DEF_LOCAL_ADDR4 = "127.0.0.1";
+
+ private static final String DEF_LOCAL_NAME = "localhost";
+ private static final String DEF_DOMAIN = "localdomain";
+
+ private static final String DOMAIN = "DOMAIN";
+
+ private static final String NAME = "NAME";
+
+ private static final String ADDR4 = "ADDR4";
+
+ private static final String ADDR6 = "ADDR6";
+
+ private String prefix = "";
+
+ private String host;
+
+ private InetAddress nameAddr;
+
+ private InetAddress best6;
+
+ private InetAddress best4;
+
+ private List<InetAddress> inetAddrs;
+
+ /**
+ * Set a prefix for the properties. If the prefix does not end with a "."
+ * one is automatically added.
+ *
+ * @param aPrefix
+ * the prefix to use.
+ * @since Ant 1.8
+ */
+ public void setPrefix(String aPrefix) {
+ prefix = aPrefix;
+ if (!prefix.endsWith(".")) {
+ prefix += ".";
+ }
+ }
+
+ /**
+ * Set the host to be retrieved.
+ *
+ * @param aHost
+ * the name or the address of the host, data for the local host
+ * will be retrieved if omitted.
+ * @since Ant 1.8
+ */
+ public void setHost(String aHost) {
+ host = aHost;
+ }
+
+ /**
+ * set the properties.
+ *
+ * @throws BuildException
+ * on error.
+ */
+ public void execute() throws BuildException {
+ if (host == null || "".equals(host)) {
+ executeLocal();
+ } else {
+ executeRemote();
+ }
+ }
+
+ private void executeLocal() {
+ try {
+ inetAddrs = new LinkedList<InetAddress>();
+ Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
+ while (interfaces.hasMoreElements()) {
+ NetworkInterface currentif = interfaces.nextElement();
+ Enumeration<InetAddress> addrs = currentif.getInetAddresses();
+ while (addrs.hasMoreElements()) {
+ inetAddrs.add(addrs.nextElement());
+ }
+ }
+ selectAddresses();
+
+ if (nameAddr != null && hasHostName(nameAddr)) {
+ setDomainAndName(nameAddr.getCanonicalHostName());
+ } else {
+ setProperty(DOMAIN, DEF_DOMAIN);
+ setProperty(NAME, DEF_LOCAL_NAME);
+ }
+ if (best4 != null) {
+ setProperty(ADDR4, best4.getHostAddress());
+ } else {
+ setProperty(ADDR4, DEF_LOCAL_ADDR4);
+ }
+ if (best6 != null) {
+ setProperty(ADDR6, best6.getHostAddress());
+ } else {
+ setProperty(ADDR6, DEF_LOCAL_ADDR6);
+ }
+ } catch (Exception e) {
+ log("Error retrieving local host information", e, Project.MSG_WARN);
+ setProperty(DOMAIN, DEF_DOMAIN);
+ setProperty(NAME, DEF_LOCAL_NAME);
+ setProperty(ADDR4, DEF_LOCAL_ADDR4);
+ setProperty(ADDR6, DEF_LOCAL_ADDR6);
+ }
+ }
+
+ private boolean hasHostName(InetAddress addr) {
+ return !addr.getHostAddress().equals(addr.getCanonicalHostName());
+ }
+
+ private void selectAddresses() {
+ for (InetAddress current : inetAddrs) {
+ if (!current.isMulticastAddress()) {
+ if (current instanceof Inet4Address) {
+ best4 = selectBestAddress(best4, current);
+ } else if (current instanceof Inet6Address) {
+ best6 = selectBestAddress(best6, current);
+ }
+ }
+ }
+
+ nameAddr = selectBestAddress(best4, best6);
+ }
+
+ private InetAddress selectBestAddress(InetAddress bestSoFar,
+ InetAddress current) {
+ InetAddress best = bestSoFar;
+ if (best == null) {
+ // none selected so far, so this one is better.
+ best = current;
+ } else {
+ if (current == null || current.isLoopbackAddress()) {
+ // definitely not better than the previously selected address.
+ } else if (current.isLinkLocalAddress()) {
+ // link local considered better than loopback
+ if (best.isLoopbackAddress()) {
+ best = current;
+ }
+ } else if (current.isSiteLocalAddress()) {
+ // site local considered better than link local (and loopback)
+ // address with hostname resolved considered better than
+ // address without hostname
+ if (best.isLoopbackAddress()
+ || best.isLinkLocalAddress()
+ || (best.isSiteLocalAddress() && !hasHostName(best))) {
+ best = current;
+ }
+ } else {
+ // current is a "Global address", considered better than
+ // site local (and better than link local, loopback)
+ // address with hostname resolved considered better than
+ // address without hostname
+ if (best.isLoopbackAddress()
+ || best.isLinkLocalAddress()
+ || best.isSiteLocalAddress()
+ || !hasHostName(best)) {
+ best = current;
+ }
+ }
+ }
+ return best;
+ }
+
+ private void executeRemote() {
+ try {
+ inetAddrs = Arrays.asList(InetAddress.getAllByName(host));
+
+ selectAddresses();
+
+ if (nameAddr != null && hasHostName(nameAddr)) {
+ setDomainAndName(nameAddr.getCanonicalHostName());
+ } else {
+ setDomainAndName(host);
+ }
+ if (best4 != null) {
+ setProperty(ADDR4, best4.getHostAddress());
+ } else {
+ setProperty(ADDR4, DEF_REM_ADDR4);
+ }
+ if (best6 != null) {
+ setProperty(ADDR6, best6.getHostAddress());
+ } else {
+ setProperty(ADDR6, DEF_REM_ADDR6);
+ }
+ } catch (Exception e) {
+ log("Error retrieving remote host information for host:" + host
+ + ".", e, Project.MSG_WARN);
+ setDomainAndName(host);
+ setProperty(ADDR4, DEF_REM_ADDR4);
+ setProperty(ADDR6, DEF_REM_ADDR6);
+ }
+ }
+
+ private void setDomainAndName(String fqdn) {
+ int idx = fqdn.indexOf('.');
+ if (idx > 0) {
+ setProperty(NAME, fqdn.substring(0, idx));
+ setProperty(DOMAIN, fqdn.substring(idx+1));
+ } else {
+ setProperty(NAME, fqdn);
+ setProperty(DOMAIN, DEF_DOMAIN);
+ }
+ }
+
+ private void setProperty(String name, String value) {
+ getProject().setNewProperty(prefix + name, value);
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/ImportTask.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/ImportTask.java
new file mode 100644
index 00000000..6b82a364
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/ImportTask.java
@@ -0,0 +1,348 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.io.File;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.ProjectHelper;
+import org.apache.tools.ant.ProjectHelperRepository;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.ResourceCollection;
+import org.apache.tools.ant.types.resources.FileProvider;
+import org.apache.tools.ant.types.resources.FileResource;
+import org.apache.tools.ant.types.resources.URLProvider;
+import org.apache.tools.ant.types.resources.URLResource;
+import org.apache.tools.ant.types.resources.Union;
+import org.apache.tools.ant.util.FileUtils;
+
+/**
+ * Task to import another build file into the current project.
+ * <p>
+ * It must be 'top level'. On execution it will read another Ant file
+ * into the same Project.
+ * </p>
+ * <p>
+ * <b>Important</b>: Trying to understand how relative file references
+ * resolved in deep/complex build hierarchies - such as what happens
+ * when an imported file imports another file can be difficult. Use absolute references for
+ * enhanced build file stability, especially in the imported files.
+ * </p>
+ * <p>Examples:</p>
+ * <pre>
+ * &lt;import file="../common-targets.xml"/&gt;
+ * </pre>
+ * <p>Import targets from a file in a parent directory.</p>
+ * <pre>
+ * &lt;import file="${deploy-platform}.xml"/&gt;
+ * </pre>
+ * <p>Import the project defined by the property <code>deploy-platform</code>.</p>
+ *
+ * @since Ant1.6
+ * @ant.task category="control"
+ */
+public class ImportTask extends Task {
+ private String file;
+ private boolean optional;
+ private String targetPrefix = ProjectHelper.USE_PROJECT_NAME_AS_TARGET_PREFIX;
+ private String prefixSeparator = ".";
+ private final Union resources = new Union();
+ private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+
+ public ImportTask() {
+ resources.setCache(true);
+ }
+
+ /**
+ * sets the optional attribute
+ *
+ * @param optional if true ignore files that are not present,
+ * default is false
+ */
+ public void setOptional(boolean optional) {
+ this.optional = optional;
+ }
+
+ /**
+ * the name of the file to import. How relative paths are resolved is still
+ * in flux: use absolute paths for safety.
+ * @param file the name of the file
+ */
+ public void setFile(String file) {
+ // I don't think we can use File - different rules
+ // for relative paths.
+ this.file = file;
+ }
+
+ /**
+ * The prefix to use when prefixing the imported target names.
+ *
+ * @since Ant 1.8.0
+ */
+ public void setAs(String prefix) {
+ targetPrefix = prefix;
+ }
+
+ /**
+ * The separator to use between prefix and target name, default is
+ * ".".
+ *
+ * @since Ant 1.8.0
+ */
+ public void setPrefixSeparator(String s) {
+ prefixSeparator = s;
+ }
+
+ /**
+ * The resource to import.
+ *
+ * @since Ant 1.8.0
+ */
+ public void add(ResourceCollection r) {
+ resources.add(r);
+ }
+
+ public void execute() {
+ if (file == null && resources.size() == 0) {
+ throw new BuildException("import requires file attribute or"
+ + " at least one nested resource");
+ }
+ if (getOwningTarget() == null
+ || !"".equals(getOwningTarget().getName())) {
+ throw new BuildException("import only allowed as a top-level task");
+ }
+
+ ProjectHelper helper =
+ (ProjectHelper) getProject().
+ getReference(ProjectHelper.PROJECTHELPER_REFERENCE);
+
+ if (helper == null) {
+ // this happens if the projecthelper was not registered with the project.
+ throw new BuildException("import requires support in ProjectHelper");
+ }
+
+ Vector<Object> importStack = helper.getImportStack();
+
+ if (importStack.size() == 0) {
+ // this happens if ant is used with a project
+ // helper that doesn't set the import.
+ throw new BuildException("import requires support in ProjectHelper");
+ }
+
+ if (getLocation() == null || getLocation().getFileName() == null) {
+ throw new BuildException("Unable to get location of import task");
+ }
+
+ Union resourcesToImport = new Union(getProject(), resources);
+ Resource fromFileAttribute = getFileAttributeResource();
+ if (fromFileAttribute != null) {
+ resources.add(fromFileAttribute);
+ }
+ for (Resource r : resourcesToImport) {
+ importResource(helper, r);
+ }
+ }
+
+ private void importResource(ProjectHelper helper,
+ Resource importedResource) {
+ Vector<Object> importStack = helper.getImportStack();
+
+ getProject().log("Importing file " + importedResource + " from "
+ + getLocation().getFileName(), Project.MSG_VERBOSE);
+
+ if (!importedResource.isExists()) {
+ String message =
+ "Cannot find " + importedResource + " imported from "
+ + getLocation().getFileName();
+ if (optional) {
+ getProject().log(message, Project.MSG_VERBOSE);
+ return;
+ } else {
+ throw new BuildException(message);
+ }
+ }
+
+ if (!isInIncludeMode() &&
+ hasAlreadyBeenImported(importedResource, importStack)) {
+ getProject().log(
+ "Skipped already imported file:\n "
+ + importedResource + "\n", Project.MSG_VERBOSE);
+ return;
+ }
+
+ // nested invocations are possible like an imported file
+ // importing another one
+ String oldPrefix = ProjectHelper.getCurrentTargetPrefix();
+ boolean oldIncludeMode = ProjectHelper.isInIncludeMode();
+ String oldSep = ProjectHelper.getCurrentPrefixSeparator();
+ try {
+ String prefix;
+ if (isInIncludeMode() && oldPrefix != null
+ && targetPrefix != null) {
+ prefix = oldPrefix + oldSep + targetPrefix;
+ } else if (isInIncludeMode()) {
+ prefix = targetPrefix;
+ } else if (!ProjectHelper.USE_PROJECT_NAME_AS_TARGET_PREFIX.equals(targetPrefix)) {
+ prefix = targetPrefix;
+ } else {
+ prefix = oldPrefix;
+ }
+ setProjectHelperProps(prefix, prefixSeparator,
+ isInIncludeMode());
+
+ ProjectHelper subHelper = ProjectHelperRepository.getInstance().getProjectHelperForBuildFile(
+ importedResource);
+
+ // push current stacks into the sub helper
+ subHelper.getImportStack().addAll(helper.getImportStack());
+ subHelper.getExtensionStack().addAll(helper.getExtensionStack());
+ getProject().addReference(ProjectHelper.PROJECTHELPER_REFERENCE, subHelper);
+
+ subHelper.parse(getProject(), importedResource);
+
+ // push back the stack from the sub helper to the main one
+ getProject().addReference(ProjectHelper.PROJECTHELPER_REFERENCE, helper);
+ helper.getImportStack().clear();
+ helper.getImportStack().addAll(subHelper.getImportStack());
+ helper.getExtensionStack().clear();
+ helper.getExtensionStack().addAll(subHelper.getExtensionStack());
+ } catch (BuildException ex) {
+ throw ProjectHelper.addLocationToBuildException(
+ ex, getLocation());
+ } finally {
+ setProjectHelperProps(oldPrefix, oldSep, oldIncludeMode);
+ }
+ }
+
+ private Resource getFileAttributeResource() {
+ // Paths are relative to the build file they're imported from,
+ // *not* the current directory (same as entity includes).
+
+ if (file != null) {
+ if (isExistingAbsoluteFile(file)) {
+ return new FileResource(new File(file));
+ }
+
+ File buildFile =
+ new File(getLocation().getFileName()).getAbsoluteFile();
+ if (buildFile.exists()) {
+ File buildFileParent = new File(buildFile.getParent());
+ File importedFile =
+ FILE_UTILS.resolveFile(buildFileParent, file);
+ return new FileResource(importedFile);
+ }
+ // maybe this import tasks is inside an imported URL?
+ try {
+ URL buildFileURL = new URL(getLocation().getFileName());
+ URL importedFile = new URL(buildFileURL, file);
+ return new URLResource(importedFile);
+ } catch (MalformedURLException ex) {
+ log(ex.toString(), Project.MSG_VERBOSE);
+ }
+ throw new BuildException("failed to resolve " + file
+ + " relative to "
+ + getLocation().getFileName());
+ }
+ return null;
+ }
+
+ private boolean isExistingAbsoluteFile(String name) {
+ File f = new File(name);
+ return f.isAbsolute() && f.exists();
+ }
+
+ private boolean hasAlreadyBeenImported(Resource importedResource,
+ Vector<Object> importStack) {
+ File importedFile = null;
+ FileProvider fp = importedResource.as(FileProvider.class);
+ if (fp != null) {
+ importedFile = fp.getFile();
+ }
+ URL importedURL = null;
+ URLProvider up = importedResource.as(URLProvider.class);
+ if (up != null) {
+ importedURL = up.getURL();
+ }
+ for (Object o : importStack) {
+ if (isOneOf(o, importedResource, importedFile, importedURL)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private boolean isOneOf(Object o, Resource importedResource,
+ File importedFile, URL importedURL) {
+ if (o.equals(importedResource) || o.equals(importedFile)
+ || o.equals(importedURL)) {
+ return true;
+ }
+ if (o instanceof Resource) {
+ if (importedFile != null) {
+ FileProvider fp = ((Resource) o).as(FileProvider.class);
+ if (fp != null && fp.getFile().equals(importedFile)) {
+ return true;
+ }
+ }
+ if (importedURL != null) {
+ URLProvider up = ((Resource) o).as(URLProvider.class);
+ if (up != null && up.getURL().equals(importedURL)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Whether the task is in include (as opposed to import) mode.
+ *
+ * <p>In include mode included targets are only known by their
+ * prefixed names and their depends lists get rewritten so that
+ * all dependencies get the prefix as well.</p>
+ *
+ * <p>In import mode imported targets are known by an adorned as
+ * well as a prefixed name and the unadorned target may be
+ * overwritten in the importing build file. The depends list of
+ * the imported targets is not modified at all.</p>
+ *
+ * @since Ant 1.8.0
+ */
+ protected final boolean isInIncludeMode() {
+ return "include".equals(getTaskType());
+ }
+
+ /**
+ * Sets a bunch of Thread-local ProjectHelper properties.
+ *
+ * @since Ant 1.8.0
+ */
+ private static void setProjectHelperProps(String prefix,
+ String prefixSep,
+ boolean inIncludeMode) {
+ ProjectHelper.setCurrentTargetPrefix(prefix);
+ ProjectHelper.setCurrentPrefixSeparator(prefixSep);
+ ProjectHelper.setInIncludeMode(inIncludeMode);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Input.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Input.java
new file mode 100644
index 00000000..ed051318
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Input.java
@@ -0,0 +1,259 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.input.DefaultInputHandler;
+import org.apache.tools.ant.input.GreedyInputHandler;
+import org.apache.tools.ant.input.InputHandler;
+import org.apache.tools.ant.input.InputRequest;
+import org.apache.tools.ant.input.MultipleChoiceInputRequest;
+import org.apache.tools.ant.input.PropertyFileInputHandler;
+import org.apache.tools.ant.input.SecureInputHandler;
+import org.apache.tools.ant.types.EnumeratedAttribute;
+import org.apache.tools.ant.util.ClasspathUtils;
+import org.apache.tools.ant.util.StringUtils;
+
+/**
+ * Reads an input line from the console.
+ *
+ * @since Ant 1.5
+ *
+ * @ant.task category="control"
+ */
+public class Input extends Task {
+
+ /**
+ * Represents an InputHandler.
+ */
+ public class Handler extends DefBase {
+
+ private String refid = null;
+ private HandlerType type = null;
+ private String classname = null;
+
+ /**
+ * Specify that the handler is a reference on the project;
+ * this allows the use of a custom inputhandler.
+ * @param refid the String refid.
+ */
+ public void setRefid(final String refid) {
+ this.refid = refid;
+ }
+ /**
+ * Get the refid of this Handler.
+ * @return String refid.
+ */
+ public String getRefid() {
+ return refid;
+ }
+ /**
+ * Set the InputHandler classname.
+ * @param classname the String classname.
+ */
+ public void setClassname(final String classname) {
+ this.classname = classname;
+ }
+ /**
+ * Get the classname of the InputHandler.
+ * @return String classname.
+ */
+ public String getClassname() {
+ return classname;
+ }
+ /**
+ * Set the handler type.
+ * @param type a HandlerType.
+ */
+ public void setType(final HandlerType type) {
+ this.type = type;
+ }
+ /**
+ * Get the handler type.
+ * @return a HandlerType object.
+ */
+ public HandlerType getType() {
+ return type;
+ }
+ private InputHandler getInputHandler() {
+ if (type != null) {
+ return type.getInputHandler();
+ }
+ if (refid != null) {
+ try {
+ return (InputHandler) (getProject().getReference(refid));
+ } catch (final ClassCastException e) {
+ throw new BuildException(
+ refid + " does not denote an InputHandler", e);
+ }
+ }
+ if (classname != null) {
+ return (InputHandler) (ClasspathUtils.newInstance(classname,
+ createLoader(), InputHandler.class));
+ }
+ throw new BuildException(
+ "Must specify refid, classname or type");
+ }
+ }
+
+ /**
+ * EnumeratedAttribute representing the built-in input handler types:
+ * "default", "propertyfile", "greedy", "secure" (since Ant 1.8).
+ */
+ public static class HandlerType extends EnumeratedAttribute {
+ private static final String[] VALUES = {"default", "propertyfile", "greedy", "secure"};
+
+ private static final InputHandler[] HANDLERS
+ = {new DefaultInputHandler(),
+ new PropertyFileInputHandler(),
+ new GreedyInputHandler(),
+ new SecureInputHandler()};
+
+ /** {@inheritDoc} */
+ @Override
+ public String[] getValues() {
+ return VALUES;
+ }
+ private InputHandler getInputHandler() {
+ return HANDLERS[getIndex()];
+ }
+ }
+
+ private String validargs = null;
+ private String message = "";
+ private String addproperty = null;
+ private String defaultvalue = null;
+ private Handler handler = null;
+ private boolean messageAttribute;
+
+ /**
+ * Defines valid input parameters as comma separated strings. If set, input
+ * task will reject any input not defined as accepted and requires the user
+ * to reenter it. Validargs are case sensitive. If you want 'a' and 'A' to
+ * be accepted you need to define both values as accepted arguments.
+ *
+ * @param validargs A comma separated String defining valid input args.
+ */
+ public void setValidargs (final String validargs) {
+ this.validargs = validargs;
+ }
+
+ /**
+ * Defines the name of a property to be created from input. Behaviour is
+ * according to property task which means that existing properties
+ * cannot be overridden.
+ *
+ * @param addproperty Name for the property to be created from input
+ */
+ public void setAddproperty (final String addproperty) {
+ this.addproperty = addproperty;
+ }
+
+ /**
+ * Sets the Message which gets displayed to the user during the build run.
+ * @param message The message to be displayed.
+ */
+ public void setMessage (final String message) {
+ this.message = message;
+ messageAttribute = true;
+ }
+
+ /**
+ * Defines the default value of the property to be created from input.
+ * Property value will be set to default if not input is received.
+ *
+ * @param defaultvalue Default value for the property if no input
+ * is received
+ */
+ public void setDefaultvalue (final String defaultvalue) {
+ this.defaultvalue = defaultvalue;
+ }
+
+ /**
+ * Set a multiline message.
+ * @param msg The message to be displayed.
+ */
+ public void addText(final String msg) {
+ if (messageAttribute && "".equals(msg.trim())) {
+ return;
+ }
+ message += getProject().replaceProperties(msg);
+ }
+
+ /**
+ * No arg constructor.
+ */
+ public Input () {
+ }
+
+ /**
+ * Actual method executed by ant.
+ * @throws BuildException on error
+ */
+ @Override
+ public void execute () throws BuildException {
+ if (addproperty != null
+ && getProject().getProperty(addproperty) != null) {
+ log("skipping " + getTaskName() + " as property " + addproperty
+ + " has already been set.");
+ return;
+ }
+
+ InputRequest request = null;
+ if (validargs != null) {
+ final Vector<String> accept = StringUtils.split(validargs, ',');
+ request = new MultipleChoiceInputRequest(message, accept);
+ } else {
+ request = new InputRequest(message);
+ }
+ request.setDefaultValue(defaultvalue);
+
+ final InputHandler h = handler == null
+ ? getProject().getInputHandler()
+ : handler.getInputHandler();
+
+ h.handleInput(request);
+
+ String value = request.getInput();
+ if ((value == null || value.trim().length() == 0)
+ && defaultvalue != null) {
+ value = defaultvalue;
+ }
+ if (addproperty != null && value != null) {
+ getProject().setNewProperty(addproperty, value);
+ }
+ }
+
+ /**
+ * Create a nested handler element.
+ * @return a Handler for this Input task.
+ */
+ public Handler createHandler() {
+ if (handler != null) {
+ throw new BuildException(
+ "Cannot define > 1 nested input handler");
+ }
+ handler = new Handler();
+ return handler;
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/JDBCTask.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/JDBCTask.java
new file mode 100644
index 00000000..2ca6e22a
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/JDBCTask.java
@@ -0,0 +1,525 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.Driver;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+import java.util.Properties;
+
+import org.apache.tools.ant.AntClassLoader;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.types.Reference;
+
+/**
+ * Handles JDBC configuration needed by SQL type tasks.
+ * <p>
+ * The following example class prints the contents of the first column of each row in TableName.
+ *</p>
+ *<pre>
+package examples;
+
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.taskdefs.JDBCTask;
+
+public class SQLExampleTask extends JDBCTask {
+
+ private String tableName;
+
+ public void execute() throws BuildException {
+ Connection conn = getConnection();
+ Statement stmt=null;
+ try {
+ if (tableName == null) {
+ throw new BuildException("TableName must be specified",location);
+ }
+ String sql = "SELECT * FROM "+tableName;
+ stmt= conn.createStatement();
+ ResultSet rs = stmt.executeQuery(sql);
+ while (rs.next()) {
+ log(rs.getObject(1).toString());
+ }
+ } catch (SQLException e) {
+
+ } finally {
+ if (stmt != null) {
+ try {stmt.close();}catch (SQLException ignore) {}
+ }
+ if (conn != null) {
+ try {conn.close();}catch (SQLException ignore) {}
+ }
+ }
+ }
+ public void setTableName(String tableName) {
+ this.tableName = tableName;
+ }
+
+}
+</pre>
+ *
+ * @since Ant 1.5
+ *
+ */
+public abstract class JDBCTask extends Task {
+ private static final int HASH_TABLE_SIZE = 3;
+
+ /**
+ * Used for caching loaders / driver. This is to avoid
+ * getting an OutOfMemoryError when calling this task
+ * multiple times in a row.
+ */
+ private static Hashtable<String, AntClassLoader> LOADER_MAP = new Hashtable<String, AntClassLoader>(HASH_TABLE_SIZE);
+
+ private boolean caching = true;
+
+ private Path classpath;
+
+ private AntClassLoader loader;
+
+ /**
+ * Autocommit flag. Default value is false
+ */
+ private boolean autocommit = false;
+
+ /**
+ * DB driver.
+ */
+ private String driver = null;
+
+ /**
+ * DB url.
+ */
+ private String url = null;
+
+ /**
+ * User name.
+ */
+ private String userId = null;
+
+ /**
+ * Password
+ */
+ private String password = null;
+
+ /**
+ * RDBMS Product needed for this SQL.
+ **/
+ private String rdbms = null;
+
+ /**
+ * RDBMS Version needed for this SQL.
+ **/
+ private String version = null;
+
+ /**
+ * whether the task fails when ant fails to connect to the database.
+ * @since Ant 1.8.0
+ */
+ private boolean failOnConnectionError = true;
+
+ /**
+ * Additional properties to put into the JDBC connection string.
+ *
+ * @since Ant 1.8.0
+ */
+ private List<Property> connectionProperties = new ArrayList<Property>();
+
+ /**
+ * Sets the classpath for loading the driver.
+ * @param classpath The classpath to set
+ */
+ public void setClasspath(Path classpath) {
+ this.classpath = classpath;
+ }
+
+ /**
+ * Caching loaders / driver. This is to avoid
+ * getting an OutOfMemoryError when calling this task
+ * multiple times in a row; default: true
+ * @param enable a <code>boolean</code> value
+ */
+ public void setCaching(boolean enable) {
+ caching = enable;
+ }
+
+ /**
+ * Add a path to the classpath for loading the driver.
+ * @return a path to be configured
+ */
+ public Path createClasspath() {
+ if (this.classpath == null) {
+ this.classpath = new Path(getProject());
+ }
+ return this.classpath.createPath();
+ }
+
+ /**
+ * Set the classpath for loading the driver
+ * using the classpath reference.
+ * @param r a reference to a classpath
+ */
+ public void setClasspathRef(Reference r) {
+ createClasspath().setRefid(r);
+ }
+
+ /**
+ * Class name of the JDBC driver; required.
+ * @param driver The driver to set
+ */
+ public void setDriver(String driver) {
+ this.driver = driver.trim();
+ }
+
+ /**
+ * Sets the database connection URL; required.
+ * @param url The url to set
+ */
+ public void setUrl(String url) {
+ this.url = url;
+ }
+
+ /**
+ * Sets the password; required.
+ * @param password The password to set
+ */
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ /**
+ * Auto commit flag for database connection;
+ * optional, default false.
+ * @param autocommit The autocommit to set
+ */
+ public void setAutocommit(boolean autocommit) {
+ this.autocommit = autocommit;
+ }
+
+ /**
+ * Execute task only if the lower case product name
+ * of the DB matches this
+ * @param rdbms The rdbms to set
+ */
+ public void setRdbms(String rdbms) {
+ this.rdbms = rdbms;
+ }
+
+ /**
+ * Sets the version string, execute task only if
+ * rdbms version match; optional.
+ * @param version The version to set
+ */
+ public void setVersion(String version) {
+ this.version = version;
+ }
+
+ /**
+ * whether the task should cause the build to fail if it cannot
+ * connect to the database.
+ * @since Ant 1.8.0
+ */
+ public void setFailOnConnectionError(boolean b) {
+ failOnConnectionError = b;
+ }
+
+ /**
+ * Verify we are connected to the correct RDBMS
+ * @param conn the jdbc connection
+ * @return true if we are connected to the correct RDBMS
+ */
+ protected boolean isValidRdbms(Connection conn) {
+ if (rdbms == null && version == null) {
+ return true;
+ }
+
+ try {
+ DatabaseMetaData dmd = conn.getMetaData();
+
+ if (rdbms != null) {
+ String theVendor = dmd.getDatabaseProductName().toLowerCase();
+
+ log("RDBMS = " + theVendor, Project.MSG_VERBOSE);
+ if (theVendor == null || theVendor.indexOf(rdbms) < 0) {
+ log("Not the required RDBMS: " + rdbms, Project.MSG_VERBOSE);
+ return false;
+ }
+ }
+
+ if (version != null) {
+ String theVersion = dmd.getDatabaseProductVersion().toLowerCase(Locale.ENGLISH);
+
+ log("Version = " + theVersion, Project.MSG_VERBOSE);
+ if (theVersion == null
+ || !(theVersion.startsWith(version)
+ || theVersion.indexOf(" " + version) >= 0)) {
+ log("Not the required version: \"" + version + "\"", Project.MSG_VERBOSE);
+ return false;
+ }
+ }
+ } catch (SQLException e) {
+ // Could not get the required information
+ log("Failed to obtain required RDBMS information", Project.MSG_ERR);
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Get the cache of loaders and drivers.
+ * @return a hashtable
+ */
+ protected static Hashtable<String, AntClassLoader> getLoaderMap() {
+ return LOADER_MAP;
+ }
+
+ /**
+ * Get the classloader used to create a driver.
+ * @return the classloader
+ */
+ protected AntClassLoader getLoader() {
+ return loader;
+ }
+
+ /**
+ * Additional properties to put into the JDBC connection string.
+ *
+ * @since Ant 1.8.0
+ */
+ public void addConnectionProperty(Property var) {
+ connectionProperties.add(var);
+ }
+
+ /**
+ * Creates a new Connection as using the driver, url, userid and password
+ * specified.
+ *
+ * The calling method is responsible for closing the connection.
+ *
+ * @return Connection the newly created connection or null if the
+ * connection failed and failOnConnectionError is false.
+ * @throws BuildException if the UserId/Password/Url is not set or there
+ * is no suitable driver or the driver fails to load.
+ */
+ protected Connection getConnection() throws BuildException {
+ if (userId == null) {
+ throw new BuildException("UserId attribute must be set!", getLocation());
+ }
+ if (password == null) {
+ throw new BuildException("Password attribute must be set!", getLocation());
+ }
+ if (url == null) {
+ throw new BuildException("Url attribute must be set!", getLocation());
+ }
+ try {
+
+ log("connecting to " + getUrl(), Project.MSG_VERBOSE);
+ Properties info = new Properties();
+ info.put("user", getUserId());
+ info.put("password", getPassword());
+
+ for (Iterator<Property> props = connectionProperties.iterator();
+ props.hasNext();) {
+ Property p = props.next();
+ String name = p.getName();
+ String value = p.getValue();
+ if (name == null || value == null) {
+ log("Only name/value pairs are supported as connection"
+ + " properties.", Project.MSG_WARN);
+ } else {
+ log("Setting connection property " + name + " to " + value,
+ Project.MSG_VERBOSE);
+ info.put(name, value);
+ }
+ }
+
+ Connection conn = getDriver().connect(getUrl(), info);
+
+ if (conn == null) {
+ // Driver doesn't understand the URL
+ throw new SQLException("No suitable Driver for " + url);
+ }
+
+ conn.setAutoCommit(autocommit);
+ return conn;
+ } catch (SQLException e) {
+ // failed to connect
+ if (!failOnConnectionError) {
+ log("Failed to connect: " + e.getMessage(), Project.MSG_WARN);
+ return null;
+ } else {
+ throw new BuildException(e, getLocation());
+ }
+ }
+
+ }
+
+ /**
+ * Gets an instance of the required driver.
+ * Uses the ant class loader and the optionally the provided classpath.
+ * @return Driver
+ * @throws BuildException
+ */
+ private Driver getDriver() throws BuildException {
+ if (driver == null) {
+ throw new BuildException("Driver attribute must be set!", getLocation());
+ }
+
+ Driver driverInstance = null;
+ try {
+ Class<?> dc;
+ if (classpath != null) {
+ // check first that it is not already loaded otherwise
+ // consecutive runs seems to end into an OutOfMemoryError
+ // or it fails when there is a native library to load
+ // several times.
+ // this is far from being perfect but should work
+ // in most cases.
+ synchronized (LOADER_MAP) {
+ if (caching) {
+ loader = LOADER_MAP.get(driver);
+ }
+ if (loader == null) {
+ log("Loading " + driver
+ + " using AntClassLoader with classpath "
+ + classpath, Project.MSG_VERBOSE);
+ loader = getProject().createClassLoader(classpath);
+ if (caching) {
+ LOADER_MAP.put(driver, loader);
+ }
+ } else {
+ log("Loading " + driver
+ + " using a cached AntClassLoader.",
+ Project.MSG_VERBOSE);
+ }
+ }
+ dc = loader.loadClass(driver);
+ } else {
+ log("Loading " + driver + " using system loader.",
+ Project.MSG_VERBOSE);
+ dc = Class.forName(driver);
+ }
+ driverInstance = (Driver) dc.newInstance();
+ } catch (ClassNotFoundException e) {
+ throw new BuildException(
+ "Class Not Found: JDBC driver " + driver + " could not be loaded",
+ e,
+ getLocation());
+ } catch (IllegalAccessException e) {
+ throw new BuildException(
+ "Illegal Access: JDBC driver " + driver + " could not be loaded",
+ e,
+ getLocation());
+ } catch (InstantiationException e) {
+ throw new BuildException(
+ "Instantiation Exception: JDBC driver " + driver + " could not be loaded",
+ e,
+ getLocation());
+ }
+ return driverInstance;
+ }
+
+
+ /**
+ * Set the caching attribute.
+ * @param value a <code>boolean</code> value
+ */
+ public void isCaching(boolean value) {
+ caching = value;
+ }
+
+ /**
+ * Gets the classpath.
+ * @return Returns a Path
+ */
+ public Path getClasspath() {
+ return classpath;
+ }
+
+ /**
+ * Gets the autocommit.
+ * @return Returns a boolean
+ */
+ public boolean isAutocommit() {
+ return autocommit;
+ }
+
+ /**
+ * Gets the url.
+ * @return Returns a String
+ */
+ public String getUrl() {
+ return url;
+ }
+
+ /**
+ * Gets the userId.
+ * @return Returns a String
+ */
+ public String getUserId() {
+ return userId;
+ }
+
+ /**
+ * Set the user name for the connection; required.
+ * @param userId The userId to set
+ */
+ public void setUserid(String userId) {
+ this.userId = userId;
+ }
+
+ /**
+ * Gets the password.
+ * @return Returns a String
+ */
+ public String getPassword() {
+ return password;
+ }
+
+ /**
+ * Gets the rdbms.
+ * @return Returns a String
+ */
+ public String getRdbms() {
+ return rdbms;
+ }
+
+ /**
+ * Gets the version.
+ * @return Returns a String
+ */
+ public String getVersion() {
+ return version;
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Jar.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Jar.java
new file mode 100644
index 00000000..c2c0f0ed
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Jar.java
@@ -0,0 +1,1238 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.io.Reader;
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.List;
+import java.util.StringTokenizer;
+import java.util.TreeMap;
+import java.util.Vector;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.Manifest.Section;
+import org.apache.tools.ant.types.ArchiveFileSet;
+import org.apache.tools.ant.types.EnumeratedAttribute;
+import org.apache.tools.ant.types.FileSet;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.ResourceCollection;
+import org.apache.tools.ant.types.ZipFileSet;
+import org.apache.tools.ant.types.spi.Service;
+import org.apache.tools.ant.util.FileUtils;
+import org.apache.tools.zip.JarMarker;
+import org.apache.tools.zip.ZipExtraField;
+import org.apache.tools.zip.ZipOutputStream;
+
+/**
+ * Creates a JAR archive.
+ *
+ * @since Ant 1.1
+ *
+ * @ant.task category="packaging"
+ */
+public class Jar extends Zip {
+ /** The index file name. */
+ private static final String INDEX_NAME = "META-INF/INDEX.LIST";
+
+ /** The manifest file name. */
+ private static final String MANIFEST_NAME = "META-INF/MANIFEST.MF";
+
+ /**
+ * List of all known SPI Services
+ */
+ private List<Service> serviceList = new ArrayList<Service>();
+
+ /** merged manifests added through addConfiguredManifest */
+ private Manifest configuredManifest;
+
+ /** shadow of the above if upToDate check alters the value */
+ private Manifest savedConfiguredManifest;
+
+ /** merged manifests added through filesets */
+ private Manifest filesetManifest;
+
+ /**
+ * Manifest of original archive, will be set to null if not in
+ * update mode.
+ */
+ private Manifest originalManifest;
+
+ /**
+ * whether to merge fileset manifests;
+ * value is true if filesetmanifest is 'merge' or 'mergewithoutmain'
+ */
+ private FilesetManifestConfig filesetManifestConfig;
+
+ /**
+ * whether to merge the main section of fileset manifests;
+ * value is true if filesetmanifest is 'merge'
+ */
+ private boolean mergeManifestsMain = true;
+
+ /** the manifest specified by the 'manifest' attribute **/
+ private Manifest manifest;
+
+ /** The encoding to use when reading in a manifest file */
+ private String manifestEncoding;
+
+ /**
+ * The file found from the 'manifest' attribute. This can be
+ * either the location of a manifest, or the name of a jar added
+ * through a fileset. If its the name of an added jar, the
+ * manifest is looked for in META-INF/MANIFEST.MF
+ */
+ private File manifestFile;
+
+ /** jar index is JDK 1.3+ only */
+ private boolean index = false;
+
+ /** Whether to index META-INF/ and its children */
+ private boolean indexMetaInf = false;
+
+ /**
+ * whether to really create the archive in createEmptyZip, will
+ * get set in getResourcesToAdd.
+ */
+ private boolean createEmpty = false;
+
+ /**
+ * Stores all files that are in the root of the archive (i.e. that
+ * have a name that doesn't contain a slash) so they can get
+ * listed in the index.
+ *
+ * Will not be filled unless the user has asked for an index.
+ *
+ * @since Ant 1.6
+ */
+ private Vector<String> rootEntries;
+
+ /**
+ * Path containing jars that shall be indexed in addition to this archive.
+ *
+ * @since Ant 1.6.2
+ */
+ private Path indexJars;
+
+ // CheckStyle:LineLength OFF - Link is too long.
+ /**
+ * Strict mode for checking rules of the JAR-Specification.
+ * @see http://java.sun.com/j2se/1.3/docs/guide/versioning/spec/VersioningSpecification.html#PackageVersioning
+ */
+ private StrictMode strict = new StrictMode("ignore");
+
+ // CheckStyle:LineLength ON
+
+ /**
+ * whether to merge Class-Path attributes.
+ */
+ private boolean mergeClassPaths = false;
+
+ /**
+ * whether to flatten Class-Path attributes into a single one.
+ */
+ private boolean flattenClassPaths = false;
+
+ /**
+ * Extra fields needed to make Solaris recognize the archive as a jar file.
+ *
+ * @since Ant 1.6.3
+ */
+ private static final ZipExtraField[] JAR_MARKER = new ZipExtraField[] {
+ JarMarker.getInstance()
+ };
+
+ /** constructor */
+ public Jar() {
+ super();
+ archiveType = "jar";
+ emptyBehavior = "create";
+ setEncoding("UTF8");
+ setZip64Mode(Zip64ModeAttribute.NEVER);
+ rootEntries = new Vector<String>();
+ }
+
+ /**
+ * Not used for jar files.
+ * @param we not used
+ * @ant.attribute ignore="true"
+ */
+ public void setWhenempty(WhenEmpty we) {
+ log("JARs are never empty, they contain at least a manifest file",
+ Project.MSG_WARN);
+ }
+
+ /**
+ * Indicates if a jar file should be created when it would only contain a
+ * manifest file.
+ * Possible values are: <code>fail</code> (throw an exception
+ * and halt the build); <code>skip</code> (do not create
+ * any archive, but issue a warning); <code>create</code>
+ * (make an archive with only a manifest file).
+ * Default is <code>create</code>;
+ * @param we a <code>WhenEmpty</code> enumerated value
+ */
+ public void setWhenmanifestonly(WhenEmpty we) {
+ emptyBehavior = we.getValue();
+ }
+
+ /**
+ * Activate the strict mode. When set to <i>true</i> a BuildException
+ * will be thrown if the Jar-Packaging specification was broken.
+ * @param strict New value of the strict mode.
+ * @since Ant 1.7.1
+ */
+ public void setStrict(StrictMode strict) {
+ this.strict = strict;
+ }
+
+ /**
+ * Set the destination file.
+ * @param jarFile the destination file
+ * @deprecated since 1.5.x.
+ * Use setDestFile(File) instead.
+ */
+ public void setJarfile(File jarFile) {
+ setDestFile(jarFile);
+ }
+
+ /**
+ * Set whether or not to create an index list for classes.
+ * This may speed up classloading in some cases.
+ * @param flag a <code>boolean</code> value
+ */
+ public void setIndex(boolean flag) {
+ index = flag;
+ }
+
+ /**
+ * Set whether or not to add META-INF and its children to the index.
+ *
+ * <p>Doesn't have any effect if index is false.</p>
+ *
+ * <p>Sun's jar implementation used to skip the META-INF directory
+ * and Ant followed that example. The behavior has been changed
+ * with Java 5. In order to avoid problems with Ant generated
+ * jars on Java 1.4 or earlier Ant will not include META-INF
+ * unless explicitly asked to.</p>
+ *
+ * @see <a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4408526">
+ * jar -i omits service providers in index.list</a>
+ * @since Ant 1.8.0
+ * @param flag a <code>boolean</code> value, defaults to false
+ */
+ public void setIndexMetaInf(boolean flag) {
+ indexMetaInf = flag;
+ }
+
+ /**
+ * The character encoding to use in the manifest file.
+ *
+ * @param manifestEncoding the character encoding
+ */
+ public void setManifestEncoding(String manifestEncoding) {
+ this.manifestEncoding = manifestEncoding;
+ }
+
+ /**
+ * Allows the manifest for the archive file to be provided inline
+ * in the build file rather than in an external file.
+ *
+ * @param newManifest an embedded manifest element
+ * @throws ManifestException on error
+ */
+ public void addConfiguredManifest(Manifest newManifest)
+ throws ManifestException {
+ if (configuredManifest == null) {
+ configuredManifest = newManifest;
+ } else {
+ configuredManifest.merge(newManifest, false, mergeClassPaths);
+ }
+ savedConfiguredManifest = configuredManifest;
+ }
+
+ /**
+ * The manifest file to use. This can be either the location of a manifest,
+ * or the name of a jar added through a fileset. If its the name of an added
+ * jar, the task expects the manifest to be in the jar at META-INF/MANIFEST.MF.
+ *
+ * @param manifestFile the manifest file to use.
+ */
+ public void setManifest(File manifestFile) {
+ if (!manifestFile.exists()) {
+ throw new BuildException("Manifest file: " + manifestFile
+ + " does not exist.", getLocation());
+ }
+
+ this.manifestFile = manifestFile;
+ }
+
+ private Manifest getManifest(File manifestFile) {
+
+ Manifest newManifest = null;
+ FileInputStream fis = null;
+ InputStreamReader isr = null;
+ try {
+ fis = new FileInputStream(manifestFile);
+ if (manifestEncoding == null) {
+ isr = new InputStreamReader(fis);
+ } else {
+ isr = new InputStreamReader(fis, manifestEncoding);
+ }
+ newManifest = getManifest(isr);
+ } catch (UnsupportedEncodingException e) {
+ throw new BuildException("Unsupported encoding while reading manifest: "
+ + e.getMessage(), e);
+ } catch (IOException e) {
+ throw new BuildException("Unable to read manifest file: "
+ + manifestFile
+ + " (" + e.getMessage() + ")", e);
+ } finally {
+ FileUtils.close(isr);
+ }
+ return newManifest;
+ }
+
+ /**
+ * @return null if jarFile doesn't contain a manifest, the
+ * manifest otherwise.
+ * @since Ant 1.5.2
+ */
+ private Manifest getManifestFromJar(File jarFile) throws IOException {
+ ZipFile zf = null;
+ try {
+ zf = new ZipFile(jarFile);
+
+ // must not use getEntry as "well behaving" applications
+ // must accept the manifest in any capitalization
+ Enumeration<? extends ZipEntry> e = zf.entries();
+ while (e.hasMoreElements()) {
+ ZipEntry ze = e.nextElement();
+ if (ze.getName().equalsIgnoreCase(MANIFEST_NAME)) {
+ InputStreamReader isr =
+ new InputStreamReader(zf.getInputStream(ze), "UTF-8");
+ return getManifest(isr);
+ }
+ }
+ return null;
+ } finally {
+ if (zf != null) {
+ try {
+ zf.close();
+ } catch (IOException e) {
+ // TODO - log an error? throw an exception?
+ }
+ }
+ }
+ }
+
+ private Manifest getManifest(Reader r) {
+
+ Manifest newManifest = null;
+ try {
+ newManifest = new Manifest(r);
+ } catch (ManifestException e) {
+ log("Manifest is invalid: " + e.getMessage(), Project.MSG_ERR);
+ throw new BuildException("Invalid Manifest: " + manifestFile,
+ e, getLocation());
+ } catch (IOException e) {
+ throw new BuildException("Unable to read manifest file"
+ + " (" + e.getMessage() + ")", e);
+ }
+ return newManifest;
+ }
+
+ private boolean jarHasIndex(File jarFile) throws IOException {
+ ZipFile zf = null;
+ try {
+ zf = new ZipFile(jarFile);
+ Enumeration<? extends ZipEntry> e = zf.entries();
+ while (e.hasMoreElements()) {
+ ZipEntry ze = e.nextElement();
+ if (ze.getName().equalsIgnoreCase(INDEX_NAME)) {
+ return true;
+ }
+ }
+ return false;
+ } finally {
+ if (zf != null) {
+ try {
+ zf.close();
+ } catch (IOException e) {
+ // TODO - log an error? throw an exception?
+ }
+ }
+ }
+ }
+
+ /**
+ * Behavior when a Manifest is found in a zipfileset or zipgroupfileset file.
+ * Valid values are "skip", "merge", and "mergewithoutmain".
+ * "merge" will merge all of manifests together, and merge this into any
+ * other specified manifests.
+ * "mergewithoutmain" merges everything but the Main section of the manifests.
+ * Default value is "skip".
+ *
+ * Note: if this attribute's value is not "skip", the created jar will not
+ * be readable by using java.util.jar.JarInputStream
+ *
+ * @param config setting for found manifest behavior.
+ */
+ public void setFilesetmanifest(FilesetManifestConfig config) {
+ filesetManifestConfig = config;
+ mergeManifestsMain = "merge".equals(config.getValue());
+
+ if (filesetManifestConfig != null
+ && !filesetManifestConfig.getValue().equals("skip")) {
+
+ doubleFilePass = true;
+ }
+ }
+
+ /**
+ * Adds a zipfileset to include in the META-INF directory.
+ *
+ * @param fs zipfileset to add
+ */
+ public void addMetainf(ZipFileSet fs) {
+ // We just set the prefix for this fileset, and pass it up.
+ fs.setPrefix("META-INF/");
+ super.addFileset(fs);
+ }
+
+ /**
+ * Add a path to index jars.
+ * @param p a path
+ * @since Ant 1.6.2
+ */
+ public void addConfiguredIndexJars(Path p) {
+ if (indexJars == null) {
+ indexJars = new Path(getProject());
+ }
+ indexJars.append(p);
+ }
+
+ /**
+ * A nested SPI service element.
+ * @param service the nested element.
+ * @since Ant 1.7
+ */
+ public void addConfiguredService(Service service) {
+ // Check if the service is configured correctly
+ service.check();
+ serviceList.add(service);
+ }
+
+ /**
+ * Write SPI Information to JAR
+ */
+ private void writeServices(ZipOutputStream zOut) throws IOException {
+ for (Service service : serviceList) {
+ InputStream is = null;
+ try {
+ is = service.getAsStream();
+ //stolen from writeManifest
+ super.zipFile(is, zOut,
+ "META-INF/services/" + service.getType(),
+ System.currentTimeMillis(), null,
+ ZipFileSet.DEFAULT_FILE_MODE);
+ } finally {
+ // technically this is unnecessary since
+ // Service.getAsStream returns a ByteArrayInputStream
+ // and not closing it wouldn't do any harm.
+ FileUtils.close(is);
+ }
+ }
+ }
+
+ /**
+ * Whether to merge Class-Path attributes.
+ *
+ * @since Ant 1.8.0
+ */
+ public void setMergeClassPathAttributes(boolean b) {
+ mergeClassPaths = b;
+ }
+
+ /**
+ * Whether to flatten multi-valued attributes (i.e. Class-Path)
+ * into a single one.
+ *
+ * @since Ant 1.8.0
+ */
+ public void setFlattenAttributes(boolean b) {
+ flattenClassPaths = b;
+ }
+
+ /**
+ * Initialize the zip output stream.
+ * @param zOut the zip output stream
+ * @throws IOException on I/O errors
+ * @throws BuildException on other errors
+ */
+ protected void initZipOutputStream(ZipOutputStream zOut)
+ throws IOException, BuildException {
+
+ if (!skipWriting) {
+ Manifest jarManifest = createManifest();
+ writeManifest(zOut, jarManifest);
+ writeServices(zOut);
+ }
+ }
+
+ private Manifest createManifest()
+ throws BuildException {
+ try {
+ if (manifest == null) {
+ if (manifestFile != null) {
+ // if we haven't got the manifest yet, attempt to
+ // get it now and have manifest be the final merge
+ manifest = getManifest(manifestFile);
+ }
+ }
+
+ // fileset manifest must come even before the default
+ // manifest if mergewithoutmain is selected and there is
+ // no explicit manifest specified - otherwise the Main
+ // section of the fileset manifest is still merged to the
+ // final manifest.
+ boolean mergeFileSetFirst = !mergeManifestsMain
+ && filesetManifest != null
+ && configuredManifest == null && manifest == null;
+
+ Manifest finalManifest;
+ if (mergeFileSetFirst) {
+ finalManifest = new Manifest();
+ finalManifest.merge(filesetManifest, false, mergeClassPaths);
+ finalManifest.merge(Manifest.getDefaultManifest(),
+ true, mergeClassPaths);
+ } else {
+ finalManifest = Manifest.getDefaultManifest();
+ }
+
+ /*
+ * Precedence: manifestFile wins over inline manifest,
+ * over manifests read from the filesets over the original
+ * manifest.
+ *
+ * merge with null argument is a no-op
+ */
+
+ if (isInUpdateMode()) {
+ finalManifest.merge(originalManifest, false, mergeClassPaths);
+ }
+ if (!mergeFileSetFirst) {
+ finalManifest.merge(filesetManifest, false, mergeClassPaths);
+ }
+ finalManifest.merge(configuredManifest, !mergeManifestsMain,
+ mergeClassPaths);
+ finalManifest.merge(manifest, !mergeManifestsMain,
+ mergeClassPaths);
+
+ return finalManifest;
+
+ } catch (ManifestException e) {
+ log("Manifest is invalid: " + e.getMessage(), Project.MSG_ERR);
+ throw new BuildException("Invalid Manifest", e, getLocation());
+ }
+ }
+
+ private void writeManifest(ZipOutputStream zOut, Manifest manifest)
+ throws IOException {
+ for (Enumeration<String> e = manifest.getWarnings();
+ e.hasMoreElements();) {
+ log("Manifest warning: " + e.nextElement(),
+ Project.MSG_WARN);
+ }
+
+ zipDir((Resource) null, zOut, "META-INF/", ZipFileSet.DEFAULT_DIR_MODE,
+ JAR_MARKER);
+ // time to write the manifest
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ OutputStreamWriter osw = new OutputStreamWriter(baos, Manifest.JAR_ENCODING);
+ PrintWriter writer = new PrintWriter(osw);
+ manifest.write(writer, flattenClassPaths);
+ if (writer.checkError()) {
+ throw new IOException("Encountered an error writing the manifest");
+ }
+ writer.close();
+
+ ByteArrayInputStream bais =
+ new ByteArrayInputStream(baos.toByteArray());
+ try {
+ super.zipFile(bais, zOut, MANIFEST_NAME,
+ System.currentTimeMillis(), null,
+ ZipFileSet.DEFAULT_FILE_MODE);
+ } finally {
+ // not really required
+ FileUtils.close(bais);
+ }
+ super.initZipOutputStream(zOut);
+ }
+
+ /**
+ * Finalize the zip output stream.
+ * This creates an index list if the index attribute is true.
+ * @param zOut the zip output stream
+ * @throws IOException on I/O errors
+ * @throws BuildException on other errors
+ */
+ protected void finalizeZipOutputStream(ZipOutputStream zOut)
+ throws IOException, BuildException {
+
+ if (index) {
+ createIndexList(zOut);
+ }
+ }
+
+ /**
+ * Create the index list to speed up classloading.
+ * This is a JDK 1.3+ specific feature and is enabled by default. See
+ * <a href="http://java.sun.com/j2se/1.3/docs/guide/jar/jar.html#JAR%20Index">
+ * the JAR index specification</a> for more details.
+ *
+ * @param zOut the zip stream representing the jar being built.
+ * @throws IOException thrown if there is an error while creating the
+ * index and adding it to the zip stream.
+ */
+ private void createIndexList(ZipOutputStream zOut) throws IOException {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ // encoding must be UTF8 as specified in the specs.
+ PrintWriter writer = new PrintWriter(new OutputStreamWriter(baos,
+ "UTF8"));
+
+ // version-info blankline
+ writer.println("JarIndex-Version: 1.0");
+ writer.println();
+
+ // header newline
+ writer.println(zipFile.getName());
+
+ writeIndexLikeList(new ArrayList<String>(addedDirs.keySet()),
+ rootEntries, writer);
+ writer.println();
+
+ if (indexJars != null) {
+ Manifest mf = createManifest();
+ Manifest.Attribute classpath =
+ mf.getMainSection().getAttribute(Manifest.ATTRIBUTE_CLASSPATH);
+ String[] cpEntries = null;
+ if (classpath != null && classpath.getValue() != null) {
+ StringTokenizer tok = new StringTokenizer(classpath.getValue(),
+ " ");
+ cpEntries = new String[tok.countTokens()];
+ int c = 0;
+ while (tok.hasMoreTokens()) {
+ cpEntries[c++] = tok.nextToken();
+ }
+ }
+ String[] indexJarEntries = indexJars.list();
+ for (int i = 0; i < indexJarEntries.length; i++) {
+ String name = findJarName(indexJarEntries[i], cpEntries);
+ if (name != null) {
+ ArrayList<String> dirs = new ArrayList<String>();
+ ArrayList<String> files = new ArrayList<String>();
+ grabFilesAndDirs(indexJarEntries[i], dirs, files);
+ if (dirs.size() + files.size() > 0) {
+ writer.println(name);
+ writeIndexLikeList(dirs, files, writer);
+ writer.println();
+ }
+ }
+ }
+ }
+
+ if (writer.checkError()) {
+ throw new IOException("Encountered an error writing jar index");
+ }
+ writer.close();
+ ByteArrayInputStream bais =
+ new ByteArrayInputStream(baos.toByteArray());
+ try {
+ super.zipFile(bais, zOut, INDEX_NAME, System.currentTimeMillis(),
+ null, ZipFileSet.DEFAULT_FILE_MODE);
+ } finally {
+ // not really required
+ FileUtils.close(bais);
+ }
+ }
+
+ /**
+ * Overridden from Zip class to deal with manifests and index lists.
+ * @param is the stream to read data for the entry from. The
+ * caller of the method is responsible for closing the stream.
+ * @param zOut the zip output stream
+ * @param vPath the name this entry shall have in the archive
+ * @param lastModified last modification time for the entry.
+ * @param fromArchive the original archive we are copying this
+ * entry from, will be null if we are not copying from an archive.
+ * @param mode the Unix permissions to set.
+ * @throws IOException on error
+ */
+ protected void zipFile(InputStream is, ZipOutputStream zOut, String vPath,
+ long lastModified, File fromArchive, int mode)
+ throws IOException {
+ if (MANIFEST_NAME.equalsIgnoreCase(vPath)) {
+ if (isFirstPass()) {
+ filesetManifest(fromArchive, is);
+ }
+ } else if (INDEX_NAME.equalsIgnoreCase(vPath) && index) {
+ logWhenWriting("Warning: selected " + archiveType
+ + " files include a " + INDEX_NAME + " which will"
+ + " be replaced by a newly generated one.",
+ Project.MSG_WARN);
+ } else {
+ if (index && vPath.indexOf("/") == -1) {
+ rootEntries.addElement(vPath);
+ }
+ super.zipFile(is, zOut, vPath, lastModified, fromArchive, mode);
+ }
+ }
+
+ private void filesetManifest(File file, InputStream is) throws IOException {
+ if (manifestFile != null && manifestFile.equals(file)) {
+ // If this is the same name specified in 'manifest', this
+ // is the manifest to use
+ log("Found manifest " + file, Project.MSG_VERBOSE);
+ try {
+ if (is != null) {
+ InputStreamReader isr;
+ if (manifestEncoding == null) {
+ isr = new InputStreamReader(is);
+ } else {
+ isr = new InputStreamReader(is, manifestEncoding);
+ }
+ manifest = getManifest(isr);
+ } else {
+ manifest = getManifest(file);
+ }
+ } catch (UnsupportedEncodingException e) {
+ throw new BuildException("Unsupported encoding while reading "
+ + "manifest: " + e.getMessage(), e);
+ }
+ } else if (filesetManifestConfig != null
+ && !filesetManifestConfig.getValue().equals("skip")) {
+ // we add this to our group of fileset manifests
+ logWhenWriting("Found manifest to merge in file " + file,
+ Project.MSG_VERBOSE);
+
+ try {
+ Manifest newManifest = null;
+ if (is != null) {
+ InputStreamReader isr;
+ if (manifestEncoding == null) {
+ isr = new InputStreamReader(is);
+ } else {
+ isr = new InputStreamReader(is, manifestEncoding);
+ }
+ newManifest = getManifest(isr);
+ } else {
+ newManifest = getManifest(file);
+ }
+
+ if (filesetManifest == null) {
+ filesetManifest = newManifest;
+ } else {
+ filesetManifest.merge(newManifest, false, mergeClassPaths);
+ }
+ } catch (UnsupportedEncodingException e) {
+ throw new BuildException("Unsupported encoding while reading "
+ + "manifest: " + e.getMessage(), e);
+ } catch (ManifestException e) {
+ log("Manifest in file " + file + " is invalid: "
+ + e.getMessage(), Project.MSG_ERR);
+ throw new BuildException("Invalid Manifest", e, getLocation());
+ }
+ } else {
+ // assuming 'skip' otherwise
+ // don't warn if skip has been requested explicitly, warn if user
+ // didn't set the attribute
+
+ // Hide warning also as it makes no sense since
+ // the filesetmanifest attribute itself has been
+ // hidden
+
+ //int logLevel = filesetManifestConfig == null ?
+ // Project.MSG_WARN : Project.MSG_VERBOSE;
+ //log("File " + file
+ // + " includes a META-INF/MANIFEST.MF which will be ignored. "
+ // + "To include this file, set filesetManifest to a value other "
+ // + "than 'skip'.", logLevel);
+ }
+ }
+
+ /**
+ * Collect the resources that are newer than the corresponding
+ * entries (or missing) in the original archive.
+ *
+ * <p>If we are going to recreate the archive instead of updating
+ * it, all resources should be considered as new, if a single one
+ * is. Because of this, subclasses overriding this method must
+ * call <code>super.getResourcesToAdd</code> and indicate with the
+ * third arg if they already know that the archive is
+ * out-of-date.</p>
+ *
+ * @param rcs The resource collections to grab resources from
+ * @param zipFile intended archive file (may or may not exist)
+ * @param needsUpdate whether we already know that the archive is
+ * out-of-date. Subclasses overriding this method are supposed to
+ * set this value correctly in their call to
+ * super.getResourcesToAdd.
+ * @return an array of resources to add for each fileset passed in as well
+ * as a flag that indicates whether the archive is uptodate.
+ *
+ * @exception BuildException if it likes
+ */
+ protected ArchiveState getResourcesToAdd(ResourceCollection[] rcs,
+ File zipFile,
+ boolean needsUpdate)
+ throws BuildException {
+
+ if (skipWriting) {
+ // this pass is only there to construct the merged
+ // manifest this means we claim an update was needed and
+ // only include the manifests, skipping any uptodate
+ // checks here deferring them for the second run
+ Resource[][] manifests = grabManifests(rcs);
+ int count = 0;
+ for (int i = 0; i < manifests.length; i++) {
+ count += manifests[i].length;
+ }
+ log("found a total of " + count + " manifests in "
+ + manifests.length + " resource collections",
+ Project.MSG_VERBOSE);
+ return new ArchiveState(true, manifests);
+ }
+
+ // need to handle manifest as a special check
+ if (zipFile.exists()) {
+ // if it doesn't exist, it will get created anyway, don't
+ // bother with any up-to-date checks.
+
+ try {
+ originalManifest = getManifestFromJar(zipFile);
+ if (originalManifest == null) {
+ log("Updating jar since the current jar has"
+ + " no manifest", Project.MSG_VERBOSE);
+ needsUpdate = true;
+ } else {
+ Manifest mf = createManifest();
+ if (!mf.equals(originalManifest)) {
+ log("Updating jar since jar manifest has"
+ + " changed", Project.MSG_VERBOSE);
+ needsUpdate = true;
+ }
+ }
+ } catch (Throwable t) {
+ log("error while reading original manifest in file: "
+ + zipFile.toString() + " due to " + t.getMessage(),
+ Project.MSG_WARN);
+ needsUpdate = true;
+ }
+
+ } else {
+ // no existing archive
+ needsUpdate = true;
+ }
+
+ createEmpty = needsUpdate;
+ if (!needsUpdate && index) {
+ try {
+ needsUpdate = !jarHasIndex(zipFile);
+ } catch (IOException e) {
+ //if we couldn't read it, we might as well recreate it?
+ needsUpdate = true;
+ }
+ }
+ return super.getResourcesToAdd(rcs, zipFile, needsUpdate);
+ }
+
+ /**
+ * Create an empty jar file.
+ * @param zipFile the file to create
+ * @return true for historic reasons
+ * @throws BuildException on error
+ */
+ protected boolean createEmptyZip(File zipFile) throws BuildException {
+ if (!createEmpty) {
+ return true;
+ }
+
+ if (emptyBehavior.equals("skip")) {
+ if (!skipWriting) {
+ log("Warning: skipping " + archiveType + " archive "
+ + zipFile + " because no files were included.",
+ Project.MSG_WARN);
+ }
+ return true;
+ } else if (emptyBehavior.equals("fail")) {
+ throw new BuildException("Cannot create " + archiveType
+ + " archive " + zipFile
+ + ": no files were included.",
+ getLocation());
+ }
+
+ ZipOutputStream zOut = null;
+ try {
+ if (!skipWriting) {
+ log("Building MANIFEST-only jar: "
+ + getDestFile().getAbsolutePath());
+ }
+ zOut = new ZipOutputStream(getDestFile());
+
+ zOut.setEncoding(getEncoding());
+ if (isCompress()) {
+ zOut.setMethod(ZipOutputStream.DEFLATED);
+ } else {
+ zOut.setMethod(ZipOutputStream.STORED);
+ }
+ initZipOutputStream(zOut);
+ finalizeZipOutputStream(zOut);
+ } catch (IOException ioe) {
+ throw new BuildException("Could not create almost empty JAR archive"
+ + " (" + ioe.getMessage() + ")", ioe,
+ getLocation());
+ } finally {
+ // Close the output stream.
+ FileUtils.close(zOut);
+ createEmpty = false;
+ }
+ return true;
+ }
+
+ /**
+ * Make sure we don't think we already have a MANIFEST next time this task
+ * gets executed.
+ *
+ * @see Zip#cleanUp
+ */
+ protected void cleanUp() {
+ super.cleanUp();
+ checkJarSpec();
+
+ // we want to save this info if we are going to make another pass
+ if (!doubleFilePass || !skipWriting) {
+ manifest = null;
+ configuredManifest = savedConfiguredManifest;
+ filesetManifest = null;
+ originalManifest = null;
+ }
+ rootEntries.removeAllElements();
+ }
+
+ // CheckStyle:LineLength OFF - Link is too long.
+ /**
+ * Check against packaging spec
+ * @see "http://java.sun.com/j2se/1.3/docs/guide/versioning/spec/VersioningSpecification.html#PackageVersioning"
+ */
+ // CheckStyle:LineLength ON
+ private void checkJarSpec() {
+ String br = System.getProperty("line.separator");
+ StringBuffer message = new StringBuffer();
+ Section mainSection = (configuredManifest == null)
+ ? null
+ : configuredManifest.getMainSection();
+
+ if (mainSection == null) {
+ message.append("No Implementation-Title set.");
+ message.append("No Implementation-Version set.");
+ message.append("No Implementation-Vendor set.");
+ } else {
+ if (mainSection.getAttribute("Implementation-Title") == null) {
+ message.append("No Implementation-Title set.");
+ }
+ if (mainSection.getAttribute("Implementation-Version") == null) {
+ message.append("No Implementation-Version set.");
+ }
+ if (mainSection.getAttribute("Implementation-Vendor") == null) {
+ message.append("No Implementation-Vendor set.");
+ }
+ }
+
+ if (message.length() > 0) {
+ message.append(br);
+ message.append("Location: ").append(getLocation());
+ message.append(br);
+ if (strict.getValue().equalsIgnoreCase("fail")) {
+ throw new BuildException(message.toString(), getLocation());
+ } else {
+ logWhenWriting(message.toString(), strict.getLogLevel());
+ }
+ }
+ }
+
+ /**
+ * reset to default values.
+ *
+ * @see Zip#reset
+ *
+ * @since 1.44, Ant 1.5
+ */
+ public void reset() {
+ super.reset();
+ emptyBehavior = "create";
+ configuredManifest = null;
+ filesetManifestConfig = null;
+ mergeManifestsMain = false;
+ manifestFile = null;
+ index = false;
+ }
+
+ /**
+ * The manifest config enumerated type.
+ */
+ public static class FilesetManifestConfig extends EnumeratedAttribute {
+ /**
+ * Get the list of valid strings.
+ * @return the list of values - "skip", "merge" and "mergewithoutmain"
+ */
+ public String[] getValues() {
+ return new String[] {"skip", "merge", "mergewithoutmain"};
+ }
+ }
+
+ /**
+ * Writes the directory entries from the first and the filenames
+ * from the second list to the given writer, one entry per line.
+ *
+ * @param dirs a list of directories
+ * @param files a list of files
+ * @param writer the writer to write to
+ * @throws IOException on error
+ * @since Ant 1.6.2
+ */
+ protected final void writeIndexLikeList(List<String> dirs, List<String> files,
+ PrintWriter writer)
+ throws IOException {
+ // JarIndex is sorting the directories by ascending order.
+ // it has no value but cosmetic since it will be read into a
+ // hashtable by the classloader, but we'll do so anyway.
+ Collections.sort(dirs);
+ Collections.sort(files);
+ for (String dir : dirs) {
+ // try to be smart, not to be fooled by a weird directory name
+ dir = dir.replace('\\', '/');
+ if (dir.startsWith("./")) {
+ dir = dir.substring(2);
+ }
+ while (dir.startsWith("/")) {
+ dir = dir.substring(1);
+ }
+ int pos = dir.lastIndexOf('/');
+ if (pos != -1) {
+ dir = dir.substring(0, pos);
+ }
+
+ // looks like nothing from META-INF should be added
+ // and the check is not case insensitive.
+ // see sun.misc.JarIndex
+ // see also
+ // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4408526
+ if (!indexMetaInf && dir.startsWith("META-INF")) {
+ continue;
+ }
+ // name newline
+ writer.println(dir);
+ }
+
+ for (String file : files) {
+ writer.println(file);
+ }
+ }
+
+ /**
+ * try to guess the name of the given file.
+ *
+ * <p>If this jar has a classpath attribute in its manifest, we
+ * can assume that it will only require an index of jars listed
+ * there. try to find which classpath entry is most likely the
+ * one the given file name points to.</p>
+ *
+ * <p>In the absence of a classpath attribute, assume the other
+ * files will be placed inside the same directory as this jar and
+ * use their basename.</p>
+ *
+ * <p>if there is a classpath and the given file doesn't match any
+ * of its entries, return null.</p>
+ *
+ * @param fileName the name to look for
+ * @param classpath the classpath to look in (may be null)
+ * @return the matching entry, or null if the file is not found
+ * @since Ant 1.6.2
+ */
+ protected static String findJarName(String fileName,
+ String[] classpath) {
+ if (classpath == null) {
+ return (new File(fileName)).getName();
+ }
+ fileName = fileName.replace(File.separatorChar, '/');
+ TreeMap<String, String> matches = new TreeMap<String, String>(new Comparator<Object>() {
+ // longest match comes first
+ public int compare(Object o1, Object o2) {
+ if (o1 instanceof String && o2 instanceof String) {
+ return ((String) o2).length()
+ - ((String) o1).length();
+ }
+ return 0;
+ }
+ });
+
+ for (int i = 0; i < classpath.length; i++) {
+ if (fileName.endsWith(classpath[i])) {
+ matches.put(classpath[i], classpath[i]);
+ } else {
+ int slash = classpath[i].indexOf("/");
+ String candidate = classpath[i];
+ while (slash > -1) {
+ candidate = candidate.substring(slash + 1);
+ if (fileName.endsWith(candidate)) {
+ matches.put(candidate, classpath[i]);
+ break;
+ }
+ slash = candidate.indexOf("/");
+ }
+ }
+ }
+
+ return matches.size() == 0
+ ? null : (String) matches.get(matches.firstKey());
+ }
+
+ /**
+ * Grab lists of all root-level files and all directories
+ * contained in the given archive.
+ * @param file the zip file to examine
+ * @param dirs where to place the directories found
+ * @param files where to place the files found
+ * @since Ant 1.7
+ * @throws IOException on error
+ */
+ protected static void grabFilesAndDirs(String file, List<String> dirs,
+ List<String> files)
+ throws IOException {
+ org.apache.tools.zip.ZipFile zf = null;
+ try {
+ zf = new org.apache.tools.zip.ZipFile(file, "utf-8");
+ Enumeration<org.apache.tools.zip.ZipEntry> entries = zf.getEntries();
+ HashSet<String> dirSet = new HashSet<String>();
+ while (entries.hasMoreElements()) {
+ org.apache.tools.zip.ZipEntry ze =
+ entries.nextElement();
+ String name = ze.getName();
+ if (ze.isDirectory()) {
+ dirSet.add(name);
+ } else if (name.indexOf("/") == -1) {
+ files.add(name);
+ } else {
+ // a file, not in the root
+ // since the jar may be one without directory
+ // entries, add the parent dir of this file as
+ // well.
+ dirSet.add(name.substring(0, name.lastIndexOf("/") + 1));
+ }
+ }
+ dirs.addAll(dirSet);
+ } finally {
+ if (zf != null) {
+ zf.close();
+ }
+ }
+ }
+
+ private Resource[][] grabManifests(ResourceCollection[] rcs) {
+ Resource[][] manifests = new Resource[rcs.length][];
+ for (int i = 0; i < rcs.length; i++) {
+ Resource[][] resources = null;
+ if (rcs[i] instanceof FileSet) {
+ resources = grabResources(new FileSet[] {(FileSet) rcs[i]});
+ } else {
+ resources = grabNonFileSetResources(new ResourceCollection[] {
+ rcs[i]
+ });
+ }
+ for (int j = 0; j < resources[0].length; j++) {
+ String name = resources[0][j].getName().replace('\\', '/');
+ if (rcs[i] instanceof ArchiveFileSet) {
+ ArchiveFileSet afs = (ArchiveFileSet) rcs[i];
+ if (!"".equals(afs.getFullpath(getProject()))) {
+ name = afs.getFullpath(getProject());
+ } else if (!"".equals(afs.getPrefix(getProject()))) {
+ String prefix = afs.getPrefix(getProject());
+ if (!prefix.endsWith("/") && !prefix.endsWith("\\")) {
+ prefix += "/";
+ }
+ name = prefix + name;
+ }
+ }
+ if (name.equalsIgnoreCase(MANIFEST_NAME)) {
+ manifests[i] = new Resource[] {resources[0][j]};
+ break;
+ }
+ }
+ if (manifests[i] == null) {
+ manifests[i] = new Resource[0];
+ }
+ }
+ return manifests;
+ }
+
+ /** The strict enumerated type. */
+ public static class StrictMode extends EnumeratedAttribute {
+ /** Public no arg constructor. */
+ public StrictMode() {
+ }
+ /**
+ * Constructor with an arg.
+ * @param value the enumerated value as a string.
+ */
+ public StrictMode(String value) {
+ setValue(value);
+ }
+ /**
+ * Get List of valid strings.
+ * @return the list of values.
+ */
+ public String[] getValues() {
+ return new String[]{"fail", "warn", "ignore"};
+ }
+ /**
+ * @return The log level according to the strict mode.
+ */
+ public int getLogLevel() {
+ return (getValue().equals("ignore")) ? Project.MSG_VERBOSE : Project.MSG_WARN;
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Java.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Java.java
new file mode 100644
index 00000000..5e065bc3
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Java.java
@@ -0,0 +1,965 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.ExitException;
+import org.apache.tools.ant.ExitStatusException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.taskdefs.condition.Os;
+import org.apache.tools.ant.types.Assertions;
+import org.apache.tools.ant.types.Commandline;
+import org.apache.tools.ant.types.CommandlineJava;
+import org.apache.tools.ant.types.Environment;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.types.Permissions;
+import org.apache.tools.ant.types.PropertySet;
+import org.apache.tools.ant.types.RedirectorElement;
+import org.apache.tools.ant.types.Reference;
+import org.apache.tools.ant.util.KeepAliveInputStream;
+
+/**
+ * Launcher for Java applications. Allows use of
+ * the same JVM for the called application thus resulting in much
+ * faster operation.
+ *
+ * @since Ant 1.1
+ *
+ * @ant.task category="java"
+ */
+public class Java extends Task {
+
+ private CommandlineJava cmdl = new CommandlineJava();
+ private Environment env = new Environment();
+ private boolean fork = false;
+ private boolean newEnvironment = false;
+ private File dir = null;
+ private boolean failOnError = false;
+ private Long timeout = null;
+
+ //include locally for screening purposes
+ private String inputString;
+ private File input;
+ private File output;
+ private File error;
+
+ // CheckStyle:VisibilityModifier OFF - bc
+ protected Redirector redirector = new Redirector(this);
+ protected RedirectorElement redirectorElement;
+ // CheckStyle:VisibilityModifier ON
+
+ private String resultProperty;
+ private Permissions perm = null;
+
+ private boolean spawn = false;
+ private boolean incompatibleWithSpawn = false;
+
+ private static final String TIMEOUT_MESSAGE =
+ "Timeout: killed the sub-process";
+
+ /**
+ * Normal constructor
+ */
+ public Java() {
+ }
+
+ /**
+ * create a bound task
+ * @param owner owner
+ */
+ public Java(Task owner) {
+ bindToOwner(owner);
+ }
+
+ /**
+ * Do the execution.
+ * @throws BuildException if failOnError is set to true and the application
+ * returns a nonzero result code.
+ */
+ public void execute() throws BuildException {
+ File savedDir = dir;
+ Permissions savedPermissions = perm;
+
+ int err = -1;
+ try {
+ checkConfiguration();
+ err = executeJava();
+ if (err != 0) {
+ if (failOnError) {
+ throw new ExitStatusException("Java returned: " + err,
+ err,
+ getLocation());
+ } else {
+ log("Java Result: " + err, Project.MSG_ERR);
+ }
+ }
+ maybeSetResultPropertyValue(err);
+ } finally {
+ dir = savedDir;
+ perm = savedPermissions;
+ }
+ }
+
+ /**
+ * Do the execution and return a return code.
+ *
+ * @return the return code from the execute java class if it was
+ * executed in a separate VM (fork = "yes") or a security manager was
+ * installed that prohibits ExitVM (default).
+ *
+ * @throws BuildException if required parameters are missing.
+ */
+ public int executeJava() throws BuildException {
+ return executeJava(getCommandLine());
+ }
+
+ /**
+ * Check configuration.
+ * @throws BuildException if required parameters are missing.
+ */
+ protected void checkConfiguration() throws BuildException {
+ String classname = getCommandLine().getClassname();
+ if (classname == null && getCommandLine().getJar() == null) {
+ throw new BuildException("Classname must not be null.");
+ }
+ if (!fork && getCommandLine().getJar() != null) {
+ throw new BuildException("Cannot execute a jar in non-forked mode."
+ + " Please set fork='true'. ");
+ }
+ if (spawn && !fork) {
+ throw new BuildException("Cannot spawn a java process in non-forked mode."
+ + " Please set fork='true'. ");
+ }
+ if (getCommandLine().getClasspath() != null
+ && getCommandLine().getJar() != null) {
+ log("When using 'jar' attribute classpath-settings are ignored. "
+ + "See the manual for more information.", Project.MSG_VERBOSE);
+ }
+ if (spawn && incompatibleWithSpawn) {
+ getProject().log("spawn does not allow attributes related to input, "
+ + "output, error, result", Project.MSG_ERR);
+ getProject().log("spawn also does not allow timeout", Project.MSG_ERR);
+ getProject().log("finally, spawn is not compatible "
+ + "with a nested I/O <redirector>", Project.MSG_ERR);
+ throw new BuildException("You have used an attribute "
+ + "or nested element which is not compatible with spawn");
+ }
+ if (getCommandLine().getAssertions() != null && !fork) {
+ log("Assertion statements are currently ignored in non-forked mode");
+ }
+ if (fork) {
+ if (perm != null) {
+ log("Permissions can not be set this way in forked mode.", Project.MSG_WARN);
+ }
+ log(getCommandLine().describeCommand(), Project.MSG_VERBOSE);
+ } else {
+ if (getCommandLine().getVmCommand().size() > 1) {
+ log("JVM args ignored when same JVM is used.",
+ Project.MSG_WARN);
+ }
+ if (dir != null) {
+ log("Working directory ignored when same JVM is used.",
+ Project.MSG_WARN);
+ }
+ if (newEnvironment || null != env.getVariables()) {
+ log("Changes to environment variables are ignored when same "
+ + "JVM is used.", Project.MSG_WARN);
+ }
+ if (getCommandLine().getBootclasspath() != null) {
+ log("bootclasspath ignored when same JVM is used.",
+ Project.MSG_WARN);
+ }
+ if (perm == null) {
+ perm = new Permissions(true);
+ log("running " + this.getCommandLine().getClassname()
+ + " with default permissions (exit forbidden)", Project.MSG_VERBOSE);
+ }
+ log("Running in same VM " + getCommandLine().describeJavaCommand(),
+ Project.MSG_VERBOSE);
+ }
+ setupRedirector();
+ }
+
+ /**
+ * Execute the specified CommandlineJava.
+ * @param commandLine CommandLineJava instance.
+ * @return the exit value of the process if forked, 0 otherwise.
+ */
+ protected int executeJava(CommandlineJava commandLine) {
+ try {
+ if (fork) {
+ if (!spawn) {
+ return fork(commandLine.getCommandline());
+ } else {
+ spawn(commandLine.getCommandline());
+ return 0;
+ }
+ } else {
+ try {
+ run(commandLine);
+ return 0;
+ } catch (ExitException ex) {
+ return ex.getStatus();
+ }
+ }
+ } catch (BuildException e) {
+ if (e.getLocation() == null && getLocation() != null) {
+ e.setLocation(getLocation());
+ }
+ if (failOnError) {
+ throw e;
+ } else {
+ if (TIMEOUT_MESSAGE.equals(e.getMessage())) {
+ log(TIMEOUT_MESSAGE);
+ } else {
+ log(e);
+ }
+ return -1;
+ }
+ } catch (ThreadDeath t) {
+ throw t; // cf. NB #47191
+ } catch (Throwable t) {
+ if (failOnError) {
+ throw new BuildException(t, getLocation());
+ } else {
+ log(t);
+ return -1;
+ }
+ }
+ }
+
+ /**
+ * Set whether or not you want the process to be spawned;
+ * default is not spawned.
+ * @param spawn if true you do not want Ant to wait for the end of the process.
+ * @since Ant 1.6
+ */
+ public void setSpawn(boolean spawn) {
+ this.spawn = spawn;
+ }
+
+ /**
+ * Set the classpath to be used when running the Java class.
+ *
+ * @param s an Ant Path object containing the classpath.
+ */
+ public void setClasspath(Path s) {
+ createClasspath().append(s);
+ }
+
+ /**
+ * Add a path to the classpath.
+ *
+ * @return created classpath.
+ */
+ public Path createClasspath() {
+ return getCommandLine().createClasspath(getProject()).createPath();
+ }
+
+ /**
+ * Add a path to the bootclasspath.
+ * @since Ant 1.6
+ *
+ * @return created bootclasspath.
+ */
+ public Path createBootclasspath() {
+ return getCommandLine().createBootclasspath(getProject()).createPath();
+ }
+
+ /**
+ * Set the permissions for the application run inside the same JVM.
+ * @since Ant 1.6
+ * @return Permissions.
+ */
+ public Permissions createPermissions() {
+ perm = (perm == null) ? new Permissions() : perm;
+ return perm;
+ }
+
+ /**
+ * Set the classpath to use by reference.
+ *
+ * @param r a reference to an existing classpath.
+ */
+ public void setClasspathRef(Reference r) {
+ createClasspath().setRefid(r);
+ }
+
+ /**
+ * Set the location of the JAR file to execute.
+ *
+ * @param jarfile the jarfile to execute.
+ *
+ * @throws BuildException if there is also a main class specified.
+ */
+ public void setJar(File jarfile) throws BuildException {
+ if (getCommandLine().getClassname() != null) {
+ throw new BuildException("Cannot use 'jar' and 'classname' "
+ + "attributes in same command.");
+ }
+ getCommandLine().setJar(jarfile.getAbsolutePath());
+ }
+
+ /**
+ * Set the Java class to execute.
+ *
+ * @param s the name of the main class.
+ *
+ * @throws BuildException if the jar attribute has been set.
+ */
+ public void setClassname(String s) throws BuildException {
+ if (getCommandLine().getJar() != null) {
+ throw new BuildException("Cannot use 'jar' and 'classname' "
+ + "attributes in same command");
+ }
+ getCommandLine().setClassname(s);
+ }
+
+ /**
+ * Deprecated: use nested arg instead.
+ * Set the command line arguments for the class.
+ *
+ * @param s arguments.
+ *
+ * @ant.attribute ignore="true"
+ */
+ public void setArgs(String s) {
+ log("The args attribute is deprecated. "
+ + "Please use nested arg elements.", Project.MSG_WARN);
+ getCommandLine().createArgument().setLine(s);
+ }
+
+ /**
+ * If set, system properties will be copied to the cloned VM--as
+ * well as the bootclasspath unless you have explicitly specified
+ * a bootclasspath.
+ *
+ * <p>Doesn't have any effect unless fork is true.</p>
+ * @param cloneVm if true copy system properties.
+ * @since Ant 1.7
+ */
+ public void setCloneVm(boolean cloneVm) {
+ getCommandLine().setCloneVm(cloneVm);
+ }
+
+ /**
+ * Add a command-line argument.
+ *
+ * @return created argument.
+ */
+ public Commandline.Argument createArg() {
+ return getCommandLine().createArgument();
+ }
+
+ /**
+ * Set the name of the property in which the return code of the
+ * command should be stored. Only of interest if failonerror=false.
+ *
+ * @param resultProperty name of property.
+ *
+ * @since Ant 1.6
+ */
+ public void setResultProperty(String resultProperty) {
+ this.resultProperty = resultProperty;
+ incompatibleWithSpawn = true;
+ }
+
+ /**
+ * Helper method to set result property to the
+ * passed in value if appropriate.
+ *
+ * @param result the exit code
+ */
+ protected void maybeSetResultPropertyValue(int result) {
+ String res = Integer.toString(result);
+ if (resultProperty != null) {
+ getProject().setNewProperty(resultProperty, res);
+ }
+ }
+
+ /**
+ * If true, execute in a new VM.
+ *
+ * @param s do you want to run Java in a new VM.
+ */
+ public void setFork(boolean s) {
+ this.fork = s;
+ }
+
+ /**
+ * Set the command line arguments for the JVM.
+ *
+ * @param s jvmargs.
+ */
+ public void setJvmargs(String s) {
+ log("The jvmargs attribute is deprecated. "
+ + "Please use nested jvmarg elements.", Project.MSG_WARN);
+ getCommandLine().createVmArgument().setLine(s);
+ }
+
+ /**
+ * Adds a JVM argument.
+ *
+ * @return JVM argument created.
+ */
+ public Commandline.Argument createJvmarg() {
+ return getCommandLine().createVmArgument();
+ }
+
+ /**
+ * Set the command used to start the VM (only if forking).
+ *
+ * @param s command to start the VM.
+ */
+ public void setJvm(String s) {
+ getCommandLine().setVm(s);
+ }
+
+ /**
+ * Add a system property.
+ *
+ * @param sysp system property.
+ */
+ public void addSysproperty(Environment.Variable sysp) {
+ getCommandLine().addSysproperty(sysp);
+ }
+
+ /**
+ * Add a set of properties as system properties.
+ *
+ * @param sysp set of properties to add.
+ *
+ * @since Ant 1.6
+ */
+ public void addSyspropertyset(PropertySet sysp) {
+ getCommandLine().addSyspropertyset(sysp);
+ }
+
+ /**
+ * If true, then fail if the command exits with a
+ * returncode other than zero.
+ *
+ * @param fail if true fail the build when the command exits with a
+ * nonzero returncode.
+ */
+ public void setFailonerror(boolean fail) {
+ failOnError = fail;
+ incompatibleWithSpawn |= fail;
+ }
+
+ /**
+ * Set the working directory of the process.
+ *
+ * @param d working directory.
+ *
+ */
+ public void setDir(File d) {
+ this.dir = d;
+ }
+
+ /**
+ * Set the File to which the output of the process is redirected.
+ *
+ * @param out the output File.
+ */
+ public void setOutput(File out) {
+ this.output = out;
+ incompatibleWithSpawn = true;
+ }
+
+ /**
+ * Set the input to use for the task.
+ *
+ * @param input name of the input file.
+ */
+ public void setInput(File input) {
+ if (inputString != null) {
+ throw new BuildException("The \"input\" and \"inputstring\" "
+ + "attributes cannot both be specified");
+ }
+ this.input = input;
+ incompatibleWithSpawn = true;
+ }
+
+ /**
+ * Set the string to use as input.
+ *
+ * @param inputString the string which is used as the input source.
+ */
+ public void setInputString(String inputString) {
+ if (input != null) {
+ throw new BuildException("The \"input\" and \"inputstring\" "
+ + "attributes cannot both be specified");
+ }
+ this.inputString = inputString;
+ incompatibleWithSpawn = true;
+ }
+
+ /**
+ * Set whether error output of exec is logged. This is only useful
+ * when output is being redirected and error output is desired in the
+ * Ant log.
+ *
+ * @param logError get in the ant log the messages coming from stderr
+ * in the case that fork = true.
+ */
+ public void setLogError(boolean logError) {
+ redirector.setLogError(logError);
+ incompatibleWithSpawn |= logError;
+ }
+
+ /**
+ * Set the File to which the error stream of the process is redirected.
+ *
+ * @param error file getting the error stream.
+ *
+ * @since Ant 1.6
+ */
+ public void setError(File error) {
+ this.error = error;
+ incompatibleWithSpawn = true;
+ }
+
+ /**
+ * Set the property name whose value should be set to the output of
+ * the process.
+ *
+ * @param outputProp property name.
+ *
+ */
+ public void setOutputproperty(String outputProp) {
+ redirector.setOutputProperty(outputProp);
+ incompatibleWithSpawn = true;
+ }
+
+ /**
+ * Set the property name whose value should be set to the error of
+ * the process.
+ *
+ * @param errorProperty property name.
+ *
+ * @since Ant 1.6
+ */
+ public void setErrorProperty(String errorProperty) {
+ redirector.setErrorProperty(errorProperty);
+ incompatibleWithSpawn = true;
+ }
+
+ /**
+ * Corresponds to -mx or -Xmx depending on VM version.
+ *
+ * @param max max memory parameter.
+ */
+ public void setMaxmemory(String max) {
+ getCommandLine().setMaxmemory(max);
+ }
+
+ /**
+ * Set the JVM version.
+ * @param value JVM version.
+ */
+ public void setJVMVersion(String value) {
+ getCommandLine().setVmversion(value);
+ }
+
+ /**
+ * Add an environment variable.
+ *
+ * <p>Will be ignored if we are not forking a new VM.
+ *
+ * @param var new environment variable.
+ *
+ * @since Ant 1.5
+ */
+ public void addEnv(Environment.Variable var) {
+ env.addVariable(var);
+ }
+
+ /**
+ * If true, use a completely new environment.
+ *
+ * <p>Will be ignored if we are not forking a new VM.
+ *
+ * @param newenv if true, use a completely new environment.
+ *
+ * @since Ant 1.5
+ */
+ public void setNewenvironment(boolean newenv) {
+ newEnvironment = newenv;
+ }
+
+ /**
+ * If true, append output to existing file.
+ *
+ * @param append if true, append output to existing file.
+ *
+ * @since Ant 1.5
+ */
+ public void setAppend(boolean append) {
+ redirector.setAppend(append);
+ incompatibleWithSpawn |= append;
+ }
+
+ /**
+ * Set the timeout in milliseconds after which the process will be killed.
+ *
+ * @param value timeout in milliseconds.
+ *
+ * @since Ant 1.5
+ */
+ public void setTimeout(Long value) {
+ timeout = value;
+ incompatibleWithSpawn |= timeout != null;
+ }
+
+ /**
+ * Add assertions to enable in this program (if fork=true).
+ * @param asserts assertion set.
+ * @since Ant 1.6
+ */
+ public void addAssertions(Assertions asserts) {
+ if (getCommandLine().getAssertions() != null) {
+ throw new BuildException("Only one assertion declaration is allowed");
+ }
+ getCommandLine().setAssertions(asserts);
+ }
+
+ /**
+ * Add a <code>RedirectorElement</code> to this task.
+ * @param redirectorElement <code>RedirectorElement</code>.
+ */
+ public void addConfiguredRedirector(RedirectorElement redirectorElement) {
+ if (this.redirectorElement != null) {
+ throw new BuildException("cannot have > 1 nested redirectors");
+ }
+ this.redirectorElement = redirectorElement;
+ incompatibleWithSpawn = true;
+ }
+
+ /**
+ * Pass output sent to System.out to specified output file.
+ *
+ * @param output a string of output on its way to the handlers.
+ *
+ * @since Ant 1.5
+ */
+ protected void handleOutput(String output) {
+ if (redirector.getOutputStream() != null) {
+ redirector.handleOutput(output);
+ } else {
+ super.handleOutput(output);
+ }
+ }
+
+ /**
+ * Handle an input request by this task.
+ *
+ * @param buffer the buffer into which data is to be read.
+ * @param offset the offset into the buffer at which data is stored.
+ * @param length the amount of data to read.
+ *
+ * @return the number of bytes read.
+ *
+ * @exception IOException if the data cannot be read.
+ * @since Ant 1.6
+ */
+ public int handleInput(byte[] buffer, int offset, int length)
+ throws IOException {
+ // Should work whether or not redirector.inputStream == null:
+ return redirector.handleInput(buffer, offset, length);
+ }
+
+ /**
+ * Pass output sent to System.out to specified output file.
+ *
+ * @param output string of output on its way to its handlers.
+ *
+ * @since Ant 1.5.2
+ */
+ protected void handleFlush(String output) {
+ if (redirector.getOutputStream() != null) {
+ redirector.handleFlush(output);
+ } else {
+ super.handleFlush(output);
+ }
+ }
+
+ /**
+ * Handle output sent to System.err.
+ *
+ * @param output string of stderr.
+ *
+ * @since Ant 1.5
+ */
+ protected void handleErrorOutput(String output) {
+ if (redirector.getErrorStream() != null) {
+ redirector.handleErrorOutput(output);
+ } else {
+ super.handleErrorOutput(output);
+ }
+ }
+
+ /**
+ * Handle output sent to System.err and flush the stream.
+ *
+ * @param output string of stderr.
+ *
+ * @since Ant 1.5.2
+ */
+ protected void handleErrorFlush(String output) {
+ if (redirector.getErrorStream() != null) {
+ redirector.handleErrorFlush(output);
+ } else {
+ super.handleErrorFlush(output);
+ }
+ }
+
+ /**
+ * Set up properties on the redirector that we needed to store locally.
+ */
+ protected void setupRedirector() {
+ redirector.setInput(input);
+ redirector.setInputString(inputString);
+ redirector.setOutput(output);
+ redirector.setError(error);
+ if (redirectorElement != null) {
+ redirectorElement.configure(redirector);
+ }
+ if (!spawn && input == null && inputString == null) {
+ // #24918: send standard input to the process by default.
+ redirector.setInputStream(
+ new KeepAliveInputStream(getProject().getDefaultInputStream()));
+ }
+ }
+
+ /**
+ * Executes the given classname with the given arguments as it
+ * were a command line application.
+ * @param command CommandlineJava.
+ */
+ private void run(CommandlineJava command) throws BuildException {
+ try {
+ ExecuteJava exe = new ExecuteJava();
+ exe.setJavaCommand(command.getJavaCommand());
+ exe.setClasspath(command.getClasspath());
+ exe.setSystemProperties(command.getSystemProperties());
+ exe.setPermissions(perm);
+ exe.setTimeout(timeout);
+ redirector.createStreams();
+ exe.execute(getProject());
+ redirector.complete();
+ if (exe.killedProcess()) {
+ throw new BuildException(TIMEOUT_MESSAGE);
+ }
+ } catch (IOException e) {
+ throw new BuildException(e);
+ }
+ }
+
+ /**
+ * Executes the given classname with the given arguments in a separate VM.
+ * @param command String[] of command-line arguments.
+ */
+ private int fork(String[] command) throws BuildException {
+ Execute exe
+ = new Execute(redirector.createHandler(), createWatchdog());
+ setupExecutable(exe, command);
+
+ try {
+ int rc = exe.execute();
+ redirector.complete();
+ if (exe.killedProcess()) {
+ throw new BuildException(TIMEOUT_MESSAGE);
+ }
+ return rc;
+ } catch (IOException e) {
+ throw new BuildException(e, getLocation());
+ }
+ }
+
+ /**
+ * Executes the given classname with the given arguments in a separate VM.
+ * @param command String[] of command-line arguments.
+ */
+ private void spawn(String[] command) throws BuildException {
+ Execute exe = new Execute();
+ setupExecutable(exe, command);
+ try {
+ exe.spawn();
+ } catch (IOException e) {
+ throw new BuildException(e, getLocation());
+ }
+ }
+
+ /**
+ * Do all configuration for an executable that
+ * is common across the {@link #fork(String[])} and
+ * {@link #spawn(String[])} methods.
+ * @param exe executable.
+ * @param command command to execute.
+ */
+ private void setupExecutable(Execute exe, String[] command) {
+ exe.setAntRun(getProject());
+ setupWorkingDir(exe);
+ setupEnvironment(exe);
+ setupCommandLine(exe, command);
+ }
+
+ /**
+ * Set up our environment variables.
+ * @param exe executable.
+ */
+ private void setupEnvironment(Execute exe) {
+ String[] environment = env.getVariables();
+ if (environment != null) {
+ for (int i = 0; i < environment.length; i++) {
+ log("Setting environment variable: " + environment[i],
+ Project.MSG_VERBOSE);
+ }
+ }
+ exe.setNewenvironment(newEnvironment);
+ exe.setEnvironment(environment);
+ }
+
+ /**
+ * Set the working dir of the new process.
+ * @param exe executable.
+ * @throws BuildException if the dir doesn't exist.
+ */
+ private void setupWorkingDir(Execute exe) {
+ if (dir == null) {
+ dir = getProject().getBaseDir();
+ } else if (!dir.exists() || !dir.isDirectory()) {
+ throw new BuildException(dir.getAbsolutePath()
+ + " is not a valid directory",
+ getLocation());
+ }
+ exe.setWorkingDirectory(dir);
+ }
+
+ /**
+ * Set the command line for the exe.
+ * On VMS, hands off to {@link #setupCommandLineForVMS(Execute, String[])}.
+ * @param exe executable.
+ * @param command command to execute.
+ */
+ private void setupCommandLine(Execute exe, String[] command) {
+ //On VMS platform, we need to create a special java options file
+ //containing the arguments and classpath for the java command.
+ //The special file is supported by the "-V" switch on the VMS JVM.
+ if (Os.isFamily("openvms")) {
+ setupCommandLineForVMS(exe, command);
+ } else {
+ exe.setCommandline(command);
+ }
+ }
+
+ /**
+ * On VMS platform, we need to create a special java options file
+ * containing the arguments and classpath for the java command.
+ * The special file is supported by the "-V" switch on the VMS JVM.
+ *
+ * @param exe executable.
+ * @param command command to execute.
+ */
+ private void setupCommandLineForVMS(Execute exe, String[] command) {
+ ExecuteJava.setupCommandLineForVMS(exe, command);
+ }
+
+ /**
+ * Executes the given classname with the given arguments as if it
+ * were a command line application.
+ *
+ * @param classname the name of the class to run.
+ * @param args arguments for the class.
+ * @throws BuildException in case of IOException in the execution.
+ */
+ protected void run(String classname, Vector<String> args) throws BuildException {
+ CommandlineJava cmdj = new CommandlineJava();
+ cmdj.setClassname(classname);
+ final int size = args.size();
+ for (int i = 0; i < size; i++) {
+ cmdj.createArgument().setValue(args.elementAt(i));
+ }
+ run(cmdj);
+ }
+
+ /**
+ * Clear out the arguments to this java task.
+ */
+ public void clearArgs() {
+ getCommandLine().clearJavaArgs();
+ }
+
+ /**
+ * Create the Watchdog to kill a runaway process.
+ *
+ * @return new watchdog.
+ *
+ * @throws BuildException under unknown circumstances.
+ *
+ * @since Ant 1.5
+ */
+ protected ExecuteWatchdog createWatchdog() throws BuildException {
+ if (timeout == null) {
+ return null;
+ }
+ return new ExecuteWatchdog(timeout.longValue());
+ }
+
+ /**
+ * Log the specified Throwable.
+ * @param t the Throwable to log.
+ * @since 1.6.2
+ */
+ private void log(Throwable t) {
+ StringWriter sw = new StringWriter();
+ PrintWriter w = new PrintWriter(sw);
+ t.printStackTrace(w);
+ w.close();
+ log(sw.toString(), Project.MSG_ERR);
+ }
+
+ /**
+ * Accessor to the command line.
+ *
+ * @return the current command line.
+ * @since 1.6.3
+ */
+ public CommandlineJava getCommandLine() {
+ return cmdl;
+ }
+
+ /**
+ * Get the system properties of the command line.
+ *
+ * @return the current properties of this java invocation.
+ * @since 1.6.3
+ */
+ public CommandlineJava.SysProperties getSysProperties() {
+ return getCommandLine().getSystemProperties();
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Javac.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Javac.java
new file mode 100644
index 00000000..3d77f7c4
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Javac.java
@@ -0,0 +1,1270 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.DirectoryScanner;
+import org.apache.tools.ant.MagicNames;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.compilers.CompilerAdapter;
+import org.apache.tools.ant.taskdefs.compilers.CompilerAdapterExtension;
+import org.apache.tools.ant.taskdefs.compilers.CompilerAdapterFactory;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.types.Reference;
+import org.apache.tools.ant.util.FileUtils;
+import org.apache.tools.ant.util.GlobPatternMapper;
+import org.apache.tools.ant.util.JavaEnvUtils;
+import org.apache.tools.ant.util.SourceFileScanner;
+import org.apache.tools.ant.util.facade.FacadeTaskHelper;
+
+/**
+ * Compiles Java source files. This task can take the following
+ * arguments:
+ * <ul>
+ * <li>sourcedir
+ * <li>destdir
+ * <li>deprecation
+ * <li>classpath
+ * <li>bootclasspath
+ * <li>extdirs
+ * <li>optimize
+ * <li>debug
+ * <li>encoding
+ * <li>target
+ * <li>depend
+ * <li>verbose
+ * <li>failonerror
+ * <li>includeantruntime
+ * <li>includejavaruntime
+ * <li>source
+ * <li>compiler
+ * </ul>
+ * Of these arguments, the <b>sourcedir</b> and <b>destdir</b> are required.
+ * <p>
+ * When this task executes, it will recursively scan the sourcedir and
+ * destdir looking for Java source files to compile. This task makes its
+ * compile decision based on timestamp.
+ *
+ *
+ * @since Ant 1.1
+ *
+ * @ant.task category="java"
+ */
+
+public class Javac extends MatchingTask {
+
+ private static final String FAIL_MSG
+ = "Compile failed; see the compiler error output for details.";
+
+ private static final String JAVAC19 = "javac1.9";
+ private static final String JAVAC18 = "javac1.8";
+ private static final String JAVAC17 = "javac1.7";
+ private static final String JAVAC16 = "javac1.6";
+ private static final String JAVAC15 = "javac1.5";
+ private static final String JAVAC14 = "javac1.4";
+ private static final String JAVAC13 = "javac1.3";
+ private static final String JAVAC12 = "javac1.2";
+ private static final String JAVAC11 = "javac1.1";
+ private static final String MODERN = "modern";
+ private static final String CLASSIC = "classic";
+ private static final String EXTJAVAC = "extJavac";
+
+ private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+
+ private Path src;
+ private File destDir;
+ private Path compileClasspath;
+ private Path compileSourcepath;
+ private String encoding;
+ private boolean debug = false;
+ private boolean optimize = false;
+ private boolean deprecation = false;
+ private boolean depend = false;
+ private boolean verbose = false;
+ private String targetAttribute;
+ private Path bootclasspath;
+ private Path extdirs;
+ private Boolean includeAntRuntime;
+ private boolean includeJavaRuntime = false;
+ private boolean fork = false;
+ private String forkedExecutable = null;
+ private boolean nowarn = false;
+ private String memoryInitialSize;
+ private String memoryMaximumSize;
+ private FacadeTaskHelper facade = null;
+
+ // CheckStyle:VisibilityModifier OFF - bc
+ protected boolean failOnError = true;
+ protected boolean listFiles = false;
+ protected File[] compileList = new File[0];
+ private Map<String, Long> packageInfos = new HashMap<String, Long>();
+ // CheckStyle:VisibilityModifier ON
+
+ private String source;
+ private String debugLevel;
+ private File tmpDir;
+ private String updatedProperty;
+ private String errorProperty;
+ private boolean taskSuccess = true; // assume the best
+ private boolean includeDestClasses = true;
+ private CompilerAdapter nestedAdapter = null;
+
+ private boolean createMissingPackageInfoClass = true;
+
+ /**
+ * Javac task for compilation of Java files.
+ */
+ public Javac() {
+ facade = new FacadeTaskHelper(assumedJavaVersion());
+ }
+
+ private String assumedJavaVersion() {
+ if (JavaEnvUtils.isJavaVersion(JavaEnvUtils.JAVA_1_4)) {
+ return JAVAC14;
+ } else if (JavaEnvUtils.isJavaVersion(JavaEnvUtils.JAVA_1_5)) {
+ return JAVAC15;
+ } else if (JavaEnvUtils.isJavaVersion(JavaEnvUtils.JAVA_1_6)) {
+ return JAVAC16;
+ } else if (JavaEnvUtils.isJavaVersion(JavaEnvUtils.JAVA_1_7)) {
+ return JAVAC17;
+ } else if (JavaEnvUtils.isJavaVersion(JavaEnvUtils.JAVA_1_8)) {
+ return JAVAC18;
+ } else if (JavaEnvUtils.isJavaVersion(JavaEnvUtils.JAVA_1_9)) {
+ return JAVAC19;
+ } else {
+ return CLASSIC;
+ }
+ }
+
+ /**
+ * Get the value of debugLevel.
+ * @return value of debugLevel.
+ */
+ public String getDebugLevel() {
+ return debugLevel;
+ }
+
+ /**
+ * Keyword list to be appended to the -g command-line switch.
+ *
+ * This will be ignored by all implementations except modern
+ * and classic(ver &gt;= 1.2). Legal values are none or a
+ * comma-separated list of the following keywords: lines, vars,
+ * and source. If debuglevel is not specified, by default, :none
+ * will be appended to -g. If debug is not turned on, this attribute
+ * will be ignored.
+ *
+ * @param v Value to assign to debugLevel.
+ */
+ public void setDebugLevel(final String v) {
+ this.debugLevel = v;
+ }
+
+ /**
+ * Get the value of source.
+ * @return value of source.
+ */
+ public String getSource() {
+ return source != null
+ ? source : getProject().getProperty(MagicNames.BUILD_JAVAC_SOURCE);
+ }
+
+ /**
+ * Value of the -source command-line switch; will be ignored by
+ * all implementations except modern, jikes and gcj (gcj uses
+ * -fsource).
+ *
+ * <p>If you use this attribute together with jikes or gcj, you
+ * must make sure that your version of jikes supports the -source
+ * switch.</p>
+ *
+ * <p>Legal values are 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, and 5, 6, 7, 8 and 9
+ * - by default, no -source argument will be used at all.</p>
+ *
+ * @param v Value to assign to source.
+ */
+ public void setSource(final String v) {
+ this.source = v;
+ }
+
+ /**
+ * Adds a path for source compilation.
+ *
+ * @return a nested src element.
+ */
+ public Path createSrc() {
+ if (src == null) {
+ src = new Path(getProject());
+ }
+ return src.createPath();
+ }
+
+ /**
+ * Recreate src.
+ *
+ * @return a nested src element.
+ */
+ protected Path recreateSrc() {
+ src = null;
+ return createSrc();
+ }
+
+ /**
+ * Set the source directories to find the source Java files.
+ * @param srcDir the source directories as a path
+ */
+ public void setSrcdir(final Path srcDir) {
+ if (src == null) {
+ src = srcDir;
+ } else {
+ src.append(srcDir);
+ }
+ }
+
+ /**
+ * Gets the source dirs to find the source java files.
+ * @return the source directories as a path
+ */
+ public Path getSrcdir() {
+ return src;
+ }
+
+ /**
+ * Set the destination directory into which the Java source
+ * files should be compiled.
+ * @param destDir the destination director
+ */
+ public void setDestdir(final File destDir) {
+ this.destDir = destDir;
+ }
+
+ /**
+ * Gets the destination directory into which the java source files
+ * should be compiled.
+ * @return the destination directory
+ */
+ public File getDestdir() {
+ return destDir;
+ }
+
+ /**
+ * Set the sourcepath to be used for this compilation.
+ * @param sourcepath the source path
+ */
+ public void setSourcepath(final Path sourcepath) {
+ if (compileSourcepath == null) {
+ compileSourcepath = sourcepath;
+ } else {
+ compileSourcepath.append(sourcepath);
+ }
+ }
+
+ /**
+ * Gets the sourcepath to be used for this compilation.
+ * @return the source path
+ */
+ public Path getSourcepath() {
+ return compileSourcepath;
+ }
+
+ /**
+ * Adds a path to sourcepath.
+ * @return a sourcepath to be configured
+ */
+ public Path createSourcepath() {
+ if (compileSourcepath == null) {
+ compileSourcepath = new Path(getProject());
+ }
+ return compileSourcepath.createPath();
+ }
+
+ /**
+ * Adds a reference to a source path defined elsewhere.
+ * @param r a reference to a source path
+ */
+ public void setSourcepathRef(final Reference r) {
+ createSourcepath().setRefid(r);
+ }
+
+ /**
+ * Set the classpath to be used for this compilation.
+ *
+ * @param classpath an Ant Path object containing the compilation classpath.
+ */
+ public void setClasspath(final Path classpath) {
+ if (compileClasspath == null) {
+ compileClasspath = classpath;
+ } else {
+ compileClasspath.append(classpath);
+ }
+ }
+
+ /**
+ * Gets the classpath to be used for this compilation.
+ * @return the class path
+ */
+ public Path getClasspath() {
+ return compileClasspath;
+ }
+
+ /**
+ * Adds a path to the classpath.
+ * @return a class path to be configured
+ */
+ public Path createClasspath() {
+ if (compileClasspath == null) {
+ compileClasspath = new Path(getProject());
+ }
+ return compileClasspath.createPath();
+ }
+
+ /**
+ * Adds a reference to a classpath defined elsewhere.
+ * @param r a reference to a classpath
+ */
+ public void setClasspathRef(final Reference r) {
+ createClasspath().setRefid(r);
+ }
+
+ /**
+ * Sets the bootclasspath that will be used to compile the classes
+ * against.
+ * @param bootclasspath a path to use as a boot class path (may be more
+ * than one)
+ */
+ public void setBootclasspath(final Path bootclasspath) {
+ if (this.bootclasspath == null) {
+ this.bootclasspath = bootclasspath;
+ } else {
+ this.bootclasspath.append(bootclasspath);
+ }
+ }
+
+ /**
+ * Gets the bootclasspath that will be used to compile the classes
+ * against.
+ * @return the boot path
+ */
+ public Path getBootclasspath() {
+ return bootclasspath;
+ }
+
+ /**
+ * Adds a path to the bootclasspath.
+ * @return a path to be configured
+ */
+ public Path createBootclasspath() {
+ if (bootclasspath == null) {
+ bootclasspath = new Path(getProject());
+ }
+ return bootclasspath.createPath();
+ }
+
+ /**
+ * Adds a reference to a classpath defined elsewhere.
+ * @param r a reference to a classpath
+ */
+ public void setBootClasspathRef(final Reference r) {
+ createBootclasspath().setRefid(r);
+ }
+
+ /**
+ * Sets the extension directories that will be used during the
+ * compilation.
+ * @param extdirs a path
+ */
+ public void setExtdirs(final Path extdirs) {
+ if (this.extdirs == null) {
+ this.extdirs = extdirs;
+ } else {
+ this.extdirs.append(extdirs);
+ }
+ }
+
+ /**
+ * Gets the extension directories that will be used during the
+ * compilation.
+ * @return the extension directories as a path
+ */
+ public Path getExtdirs() {
+ return extdirs;
+ }
+
+ /**
+ * Adds a path to extdirs.
+ * @return a path to be configured
+ */
+ public Path createExtdirs() {
+ if (extdirs == null) {
+ extdirs = new Path(getProject());
+ }
+ return extdirs.createPath();
+ }
+
+ /**
+ * If true, list the source files being handed off to the compiler.
+ * @param list if true list the source files
+ */
+ public void setListfiles(final boolean list) {
+ listFiles = list;
+ }
+
+ /**
+ * Get the listfiles flag.
+ * @return the listfiles flag
+ */
+ public boolean getListfiles() {
+ return listFiles;
+ }
+
+ /**
+ * Indicates whether the build will continue
+ * even if there are compilation errors; defaults to true.
+ * @param fail if true halt the build on failure
+ */
+ public void setFailonerror(final boolean fail) {
+ failOnError = fail;
+ }
+
+ /**
+ * @ant.attribute ignore="true"
+ * @param proceed inverse of failoferror
+ */
+ public void setProceed(final boolean proceed) {
+ failOnError = !proceed;
+ }
+
+ /**
+ * Gets the failonerror flag.
+ * @return the failonerror flag
+ */
+ public boolean getFailonerror() {
+ return failOnError;
+ }
+
+ /**
+ * Indicates whether source should be
+ * compiled with deprecation information; defaults to off.
+ * @param deprecation if true turn on deprecation information
+ */
+ public void setDeprecation(final boolean deprecation) {
+ this.deprecation = deprecation;
+ }
+
+ /**
+ * Gets the deprecation flag.
+ * @return the deprecation flag
+ */
+ public boolean getDeprecation() {
+ return deprecation;
+ }
+
+ /**
+ * The initial size of the memory for the underlying VM
+ * if javac is run externally; ignored otherwise.
+ * Defaults to the standard VM memory setting.
+ * (Examples: 83886080, 81920k, or 80m)
+ * @param memoryInitialSize string to pass to VM
+ */
+ public void setMemoryInitialSize(final String memoryInitialSize) {
+ this.memoryInitialSize = memoryInitialSize;
+ }
+
+ /**
+ * Gets the memoryInitialSize flag.
+ * @return the memoryInitialSize flag
+ */
+ public String getMemoryInitialSize() {
+ return memoryInitialSize;
+ }
+
+ /**
+ * The maximum size of the memory for the underlying VM
+ * if javac is run externally; ignored otherwise.
+ * Defaults to the standard VM memory setting.
+ * (Examples: 83886080, 81920k, or 80m)
+ * @param memoryMaximumSize string to pass to VM
+ */
+ public void setMemoryMaximumSize(final String memoryMaximumSize) {
+ this.memoryMaximumSize = memoryMaximumSize;
+ }
+
+ /**
+ * Gets the memoryMaximumSize flag.
+ * @return the memoryMaximumSize flag
+ */
+ public String getMemoryMaximumSize() {
+ return memoryMaximumSize;
+ }
+
+ /**
+ * Set the Java source file encoding name.
+ * @param encoding the source file encoding
+ */
+ public void setEncoding(final String encoding) {
+ this.encoding = encoding;
+ }
+
+ /**
+ * Gets the java source file encoding name.
+ * @return the source file encoding name
+ */
+ public String getEncoding() {
+ return encoding;
+ }
+
+ /**
+ * Indicates whether source should be compiled
+ * with debug information; defaults to off.
+ * @param debug if true compile with debug information
+ */
+ public void setDebug(final boolean debug) {
+ this.debug = debug;
+ }
+
+ /**
+ * Gets the debug flag.
+ * @return the debug flag
+ */
+ public boolean getDebug() {
+ return debug;
+ }
+
+ /**
+ * If true, compiles with optimization enabled.
+ * @param optimize if true compile with optimization enabled
+ */
+ public void setOptimize(final boolean optimize) {
+ this.optimize = optimize;
+ }
+
+ /**
+ * Gets the optimize flag.
+ * @return the optimize flag
+ */
+ public boolean getOptimize() {
+ return optimize;
+ }
+
+ /**
+ * Enables dependency-tracking for compilers
+ * that support this (jikes and classic).
+ * @param depend if true enable dependency-tracking
+ */
+ public void setDepend(final boolean depend) {
+ this.depend = depend;
+ }
+
+ /**
+ * Gets the depend flag.
+ * @return the depend flag
+ */
+ public boolean getDepend() {
+ return depend;
+ }
+
+ /**
+ * If true, asks the compiler for verbose output.
+ * @param verbose if true, asks the compiler for verbose output
+ */
+ public void setVerbose(final boolean verbose) {
+ this.verbose = verbose;
+ }
+
+ /**
+ * Gets the verbose flag.
+ * @return the verbose flag
+ */
+ public boolean getVerbose() {
+ return verbose;
+ }
+
+ /**
+ * Sets the target VM that the classes will be compiled for. Valid
+ * values depend on the compiler, for jdk 1.4 the valid values are
+ * "1.1", "1.2", "1.3", "1.4", "1.5", "1.6", "1.7", "1.8", "1.9", "5", "6", "7", "8", "9".
+ * @param target the target VM
+ */
+ public void setTarget(final String target) {
+ this.targetAttribute = target;
+ }
+
+ /**
+ * Gets the target VM that the classes will be compiled for.
+ * @return the target VM
+ */
+ public String getTarget() {
+ return targetAttribute != null
+ ? targetAttribute
+ : getProject().getProperty(MagicNames.BUILD_JAVAC_TARGET);
+ }
+
+ /**
+ * If true, includes Ant's own classpath in the classpath.
+ * @param include if true, includes Ant's own classpath in the classpath
+ */
+ public void setIncludeantruntime(final boolean include) {
+ includeAntRuntime = Boolean.valueOf(include);
+ }
+
+ /**
+ * Gets whether or not the ant classpath is to be included in the classpath.
+ * @return whether or not the ant classpath is to be included in the classpath
+ */
+ public boolean getIncludeantruntime() {
+ return includeAntRuntime != null ? includeAntRuntime.booleanValue() : true;
+ }
+
+ /**
+ * If true, includes the Java runtime libraries in the classpath.
+ * @param include if true, includes the Java runtime libraries in the classpath
+ */
+ public void setIncludejavaruntime(final boolean include) {
+ includeJavaRuntime = include;
+ }
+
+ /**
+ * Gets whether or not the java runtime should be included in this
+ * task's classpath.
+ * @return the includejavaruntime attribute
+ */
+ public boolean getIncludejavaruntime() {
+ return includeJavaRuntime;
+ }
+
+ /**
+ * If true, forks the javac compiler.
+ *
+ * @param f "true|false|on|off|yes|no"
+ */
+ public void setFork(final boolean f) {
+ fork = f;
+ }
+
+ /**
+ * Sets the name of the javac executable.
+ *
+ * <p>Ignored unless fork is true or extJavac has been specified
+ * as the compiler.</p>
+ * @param forkExec the name of the executable
+ */
+ public void setExecutable(final String forkExec) {
+ forkedExecutable = forkExec;
+ }
+
+ /**
+ * The value of the executable attribute, if any.
+ *
+ * @since Ant 1.6
+ * @return the name of the java executable
+ */
+ public String getExecutable() {
+ return forkedExecutable;
+ }
+
+ /**
+ * Is this a forked invocation of JDK's javac?
+ * @return true if this is a forked invocation
+ */
+ public boolean isForkedJavac() {
+ return fork || EXTJAVAC.equalsIgnoreCase(getCompiler());
+ }
+
+ /**
+ * The name of the javac executable to use in fork-mode.
+ *
+ * <p>This is either the name specified with the executable
+ * attribute or the full path of the javac compiler of the VM Ant
+ * is currently running in - guessed by Ant.</p>
+ *
+ * <p>You should <strong>not</strong> invoke this method if you
+ * want to get the value of the executable command - use {@link
+ * #getExecutable getExecutable} for this.</p>
+ * @return the name of the javac executable
+ */
+ public String getJavacExecutable() {
+ if (forkedExecutable == null && isForkedJavac()) {
+ forkedExecutable = getSystemJavac();
+ } else if (forkedExecutable != null && !isForkedJavac()) {
+ forkedExecutable = null;
+ }
+ return forkedExecutable;
+ }
+
+ /**
+ * If true, enables the -nowarn option.
+ * @param flag if true, enable the -nowarn option
+ */
+ public void setNowarn(final boolean flag) {
+ this.nowarn = flag;
+ }
+
+ /**
+ * Should the -nowarn option be used.
+ * @return true if the -nowarn option should be used
+ */
+ public boolean getNowarn() {
+ return nowarn;
+ }
+
+ /**
+ * Adds an implementation specific command-line argument.
+ * @return a ImplementationSpecificArgument to be configured
+ */
+ public ImplementationSpecificArgument createCompilerArg() {
+ final ImplementationSpecificArgument arg =
+ new ImplementationSpecificArgument();
+ facade.addImplementationArgument(arg);
+ return arg;
+ }
+
+ /**
+ * Get the additional implementation specific command line arguments.
+ * @return array of command line arguments, guaranteed to be non-null.
+ */
+ public String[] getCurrentCompilerArgs() {
+ final String chosen = facade.getExplicitChoice();
+ try {
+ // make sure facade knows about magic properties and fork setting
+ final String appliedCompiler = getCompiler();
+ facade.setImplementation(appliedCompiler);
+
+ String[] result = facade.getArgs();
+
+ final String altCompilerName = getAltCompilerName(facade.getImplementation());
+
+ if (result.length == 0 && altCompilerName != null) {
+ facade.setImplementation(altCompilerName);
+ result = facade.getArgs();
+ }
+
+ return result;
+
+ } finally {
+ facade.setImplementation(chosen);
+ }
+ }
+
+ private String getAltCompilerName(final String anImplementation) {
+ if (JAVAC19.equalsIgnoreCase(anImplementation)
+ || JAVAC18.equalsIgnoreCase(anImplementation)
+ || JAVAC17.equalsIgnoreCase(anImplementation)
+ || JAVAC16.equalsIgnoreCase(anImplementation)
+ || JAVAC15.equalsIgnoreCase(anImplementation)
+ || JAVAC14.equalsIgnoreCase(anImplementation)
+ || JAVAC13.equalsIgnoreCase(anImplementation)) {
+ return MODERN;
+ }
+ if (JAVAC12.equalsIgnoreCase(anImplementation)
+ || JAVAC11.equalsIgnoreCase(anImplementation)) {
+ return CLASSIC;
+ }
+ if (MODERN.equalsIgnoreCase(anImplementation)) {
+ final String nextSelected = assumedJavaVersion();
+ if (JAVAC19.equalsIgnoreCase(nextSelected)
+ || JAVAC18.equalsIgnoreCase(nextSelected)
+ || JAVAC17.equalsIgnoreCase(nextSelected)
+ || JAVAC16.equalsIgnoreCase(nextSelected)
+ || JAVAC15.equalsIgnoreCase(nextSelected)
+ || JAVAC14.equalsIgnoreCase(nextSelected)
+ || JAVAC13.equalsIgnoreCase(nextSelected)) {
+ return nextSelected;
+ }
+ }
+ if (CLASSIC.equalsIgnoreCase(anImplementation)) {
+ return assumedJavaVersion();
+ }
+ if (EXTJAVAC.equalsIgnoreCase(anImplementation)) {
+ return assumedJavaVersion();
+ }
+ return null;
+ }
+
+ /**
+ * Where Ant should place temporary files.
+ *
+ * @since Ant 1.6
+ * @param tmpDir the temporary directory
+ */
+ public void setTempdir(final File tmpDir) {
+ this.tmpDir = tmpDir;
+ }
+
+ /**
+ * Where Ant should place temporary files.
+ *
+ * @since Ant 1.6
+ * @return the temporary directory
+ */
+ public File getTempdir() {
+ return tmpDir;
+ }
+
+ /**
+ * The property to set on compilation success.
+ * This property will not be set if the compilation
+ * fails, or if there are no files to compile.
+ * @param updatedProperty the property name to use.
+ * @since Ant 1.7.1.
+ */
+ public void setUpdatedProperty(final String updatedProperty) {
+ this.updatedProperty = updatedProperty;
+ }
+
+ /**
+ * The property to set on compilation failure.
+ * This property will be set if the compilation
+ * fails.
+ * @param errorProperty the property name to use.
+ * @since Ant 1.7.1.
+ */
+ public void setErrorProperty(final String errorProperty) {
+ this.errorProperty = errorProperty;
+ }
+
+ /**
+ * This property controls whether to include the
+ * destination classes directory in the classpath
+ * given to the compiler.
+ * The default value is "true".
+ * @param includeDestClasses the value to use.
+ */
+ public void setIncludeDestClasses(final boolean includeDestClasses) {
+ this.includeDestClasses = includeDestClasses;
+ }
+
+ /**
+ * Get the value of the includeDestClasses property.
+ * @return the value.
+ */
+ public boolean isIncludeDestClasses() {
+ return includeDestClasses;
+ }
+
+ /**
+ * Get the result of the javac task (success or failure).
+ * @return true if compilation succeeded, or
+ * was not necessary, false if the compilation failed.
+ */
+ public boolean getTaskSuccess() {
+ return taskSuccess;
+ }
+
+ /**
+ * The classpath to use when loading the compiler implementation
+ * if it is not a built-in one.
+ *
+ * @since Ant 1.8.0
+ */
+ public Path createCompilerClasspath() {
+ return facade.getImplementationClasspath(getProject());
+ }
+
+ /**
+ * Set the compiler adapter explicitly.
+ * @since Ant 1.8.0
+ */
+ public void add(final CompilerAdapter adapter) {
+ if (nestedAdapter != null) {
+ throw new BuildException("Can't have more than one compiler"
+ + " adapter");
+ }
+ nestedAdapter = adapter;
+ }
+
+ /**
+ * Whether package-info.class files will be created by Ant
+ * matching package-info.java files that have been compiled but
+ * didn't create class files themselves.
+ *
+ * @since Ant 1.8.3
+ */
+ public void setCreateMissingPackageInfoClass(final boolean b) {
+ createMissingPackageInfoClass = b;
+ }
+
+ /**
+ * Executes the task.
+ * @exception BuildException if an error occurs
+ */
+ @Override
+ public void execute() throws BuildException {
+ checkParameters();
+ resetFileLists();
+
+ // scan source directories and dest directory to build up
+ // compile lists
+ final String[] list = src.list();
+ for (int i = 0; i < list.length; i++) {
+ final File srcDir = getProject().resolveFile(list[i]);
+ if (!srcDir.exists()) {
+ throw new BuildException("srcdir \""
+ + srcDir.getPath()
+ + "\" does not exist!", getLocation());
+ }
+
+ final DirectoryScanner ds = this.getDirectoryScanner(srcDir);
+ final String[] files = ds.getIncludedFiles();
+
+ scanDir(srcDir, destDir != null ? destDir : srcDir, files);
+ }
+
+ compile();
+ if (updatedProperty != null
+ && taskSuccess
+ && compileList.length != 0) {
+ getProject().setNewProperty(updatedProperty, "true");
+ }
+ }
+
+ /**
+ * Clear the list of files to be compiled and copied..
+ */
+ protected void resetFileLists() {
+ compileList = new File[0];
+ packageInfos = new HashMap<String, Long>();
+ }
+
+ /**
+ * Scans the directory looking for source files to be compiled.
+ * The results are returned in the class variable compileList
+ *
+ * @param srcDir The source directory
+ * @param destDir The destination directory
+ * @param files An array of filenames
+ */
+ protected void scanDir(final File srcDir, final File destDir, final String[] files) {
+ final GlobPatternMapper m = new GlobPatternMapper();
+ final String[] extensions = findSupportedFileExtensions();
+
+ for (int i = 0; i < extensions.length; i++) {
+ m.setFrom(extensions[i]);
+ m.setTo("*.class");
+ final SourceFileScanner sfs = new SourceFileScanner(this);
+ final File[] newFiles = sfs.restrictAsFiles(files, srcDir, destDir, m);
+
+ if (newFiles.length > 0) {
+ lookForPackageInfos(srcDir, newFiles);
+ final File[] newCompileList
+ = new File[compileList.length + newFiles.length];
+ System.arraycopy(compileList, 0, newCompileList, 0,
+ compileList.length);
+ System.arraycopy(newFiles, 0, newCompileList,
+ compileList.length, newFiles.length);
+ compileList = newCompileList;
+ }
+ }
+ }
+
+ private String[] findSupportedFileExtensions() {
+ final String compilerImpl = getCompiler();
+ final CompilerAdapter adapter =
+ nestedAdapter != null ? nestedAdapter :
+ CompilerAdapterFactory.getCompiler(compilerImpl, this,
+ createCompilerClasspath());
+ String[] extensions = null;
+ if (adapter instanceof CompilerAdapterExtension) {
+ extensions =
+ ((CompilerAdapterExtension) adapter).getSupportedFileExtensions();
+ }
+
+ if (extensions == null) {
+ extensions = new String[] {"java"};
+ }
+
+ // now process the extensions to ensure that they are the
+ // right format
+ for (int i = 0; i < extensions.length; i++) {
+ if (!extensions[i].startsWith("*.")) {
+ extensions[i] = "*." + extensions[i];
+ }
+ }
+ return extensions;
+ }
+
+ /**
+ * Gets the list of files to be compiled.
+ * @return the list of files as an array
+ */
+ public File[] getFileList() {
+ return compileList;
+ }
+
+ /**
+ * Is the compiler implementation a jdk compiler
+ *
+ * @param compilerImpl the name of the compiler implementation
+ * @return true if compilerImpl is "modern", "classic",
+ * "javac1.1", "javac1.2", "javac1.3", "javac1.4", "javac1.5",
+ * "javac1.6", "javac1.7", "javac1.8" or "javac1.9".
+ */
+ protected boolean isJdkCompiler(final String compilerImpl) {
+ return MODERN.equals(compilerImpl)
+ || CLASSIC.equals(compilerImpl)
+ || JAVAC19.equals(compilerImpl)
+ || JAVAC18.equals(compilerImpl)
+ || JAVAC17.equals(compilerImpl)
+ || JAVAC16.equals(compilerImpl)
+ || JAVAC15.equals(compilerImpl)
+ || JAVAC14.equals(compilerImpl)
+ || JAVAC13.equals(compilerImpl)
+ || JAVAC12.equals(compilerImpl)
+ || JAVAC11.equals(compilerImpl);
+ }
+
+ /**
+ * @return the executable name of the java compiler
+ */
+ protected String getSystemJavac() {
+ return JavaEnvUtils.getJdkExecutable("javac");
+ }
+
+ /**
+ * Choose the implementation for this particular task.
+ * @param compiler the name of the compiler
+ * @since Ant 1.5
+ */
+ public void setCompiler(final String compiler) {
+ facade.setImplementation(compiler);
+ }
+
+ /**
+ * The implementation for this particular task.
+ *
+ * <p>Defaults to the build.compiler property but can be overridden
+ * via the compiler and fork attributes.</p>
+ *
+ * <p>If fork has been set to true, the result will be extJavac
+ * and not classic or java1.2 - no matter what the compiler
+ * attribute looks like.</p>
+ *
+ * @see #getCompilerVersion
+ * @return the compiler.
+ * @since Ant 1.5
+ */
+ public String getCompiler() {
+ String compilerImpl = getCompilerVersion();
+ if (fork) {
+ if (isJdkCompiler(compilerImpl)) {
+ compilerImpl = EXTJAVAC;
+ } else {
+ log("Since compiler setting isn't classic or modern, "
+ + "ignoring fork setting.", Project.MSG_WARN);
+ }
+ }
+ return compilerImpl;
+ }
+
+ /**
+ * The implementation for this particular task.
+ *
+ * <p>Defaults to the build.compiler property but can be overridden
+ * via the compiler attribute.</p>
+ *
+ * <p>This method does not take the fork attribute into
+ * account.</p>
+ *
+ * @see #getCompiler
+ * @return the compiler.
+ *
+ * @since Ant 1.5
+ */
+ public String getCompilerVersion() {
+ facade.setMagicValue(getProject().getProperty("build.compiler"));
+ return facade.getImplementation();
+ }
+
+ /**
+ * Check that all required attributes have been set and nothing
+ * silly has been entered.
+ *
+ * @since Ant 1.5
+ * @exception BuildException if an error occurs
+ */
+ protected void checkParameters() throws BuildException {
+ if (src == null) {
+ throw new BuildException("srcdir attribute must be set!",
+ getLocation());
+ }
+ if (src.size() == 0) {
+ throw new BuildException("srcdir attribute must be set!",
+ getLocation());
+ }
+
+ if (destDir != null && !destDir.isDirectory()) {
+ throw new BuildException("destination directory \""
+ + destDir
+ + "\" does not exist "
+ + "or is not a directory", getLocation());
+ }
+ if (includeAntRuntime == null && getProject().getProperty("build.sysclasspath") == null) {
+ log(getLocation() + "warning: 'includeantruntime' was not set, " +
+ "defaulting to build.sysclasspath=last; set to false for repeatable builds",
+ Project.MSG_WARN);
+ }
+ }
+
+ /**
+ * Perform the compilation.
+ *
+ * @since Ant 1.5
+ */
+ protected void compile() {
+ final String compilerImpl = getCompiler();
+
+ if (compileList.length > 0) {
+ log("Compiling " + compileList.length + " source file"
+ + (compileList.length == 1 ? "" : "s")
+ + (destDir != null ? " to " + destDir : ""));
+
+ if (listFiles) {
+ for (int i = 0; i < compileList.length; i++) {
+ final String filename = compileList[i].getAbsolutePath();
+ log(filename);
+ }
+ }
+
+ final CompilerAdapter adapter =
+ nestedAdapter != null ? nestedAdapter :
+ CompilerAdapterFactory.getCompiler(compilerImpl, this,
+ createCompilerClasspath());
+
+ // now we need to populate the compiler adapter
+ adapter.setJavac(this);
+
+ // finally, lets execute the compiler!!
+ if (adapter.execute()) {
+ // Success
+ if (createMissingPackageInfoClass) {
+ try {
+ generateMissingPackageInfoClasses(destDir != null
+ ? destDir
+ : getProject()
+ .resolveFile(src.list()[0]));
+ } catch (final IOException x) {
+ // Should this be made a nonfatal warning?
+ throw new BuildException(x, getLocation());
+ }
+ }
+ } else {
+ // Fail path
+ this.taskSuccess = false;
+ if (errorProperty != null) {
+ getProject().setNewProperty(
+ errorProperty, "true");
+ }
+ if (failOnError) {
+ throw new BuildException(FAIL_MSG, getLocation());
+ } else {
+ log(FAIL_MSG, Project.MSG_ERR);
+ }
+ }
+ }
+ }
+
+ /**
+ * Adds an "compiler" attribute to Commandline$Attribute used to
+ * filter command line attributes based on the current
+ * implementation.
+ */
+ public class ImplementationSpecificArgument extends
+ org.apache.tools.ant.util.facade.ImplementationSpecificArgument {
+
+ /**
+ * @param impl the name of the compiler
+ */
+ public void setCompiler(final String impl) {
+ super.setImplementation(impl);
+ }
+ }
+
+ private void lookForPackageInfos(final File srcDir, final File[] newFiles) {
+ for (int i = 0; i < newFiles.length; i++) {
+ final File f = newFiles[i];
+ if (!f.getName().equals("package-info.java")) {
+ continue;
+ }
+ final String path = FILE_UTILS.removeLeadingPath(srcDir, f).
+ replace(File.separatorChar, '/');
+ final String suffix = "/package-info.java";
+ if (!path.endsWith(suffix)) {
+ log("anomalous package-info.java path: " + path, Project.MSG_WARN);
+ continue;
+ }
+ final String pkg = path.substring(0, path.length() - suffix.length());
+ packageInfos.put(pkg, new Long(f.lastModified()));
+ }
+ }
+
+ /**
+ * Ensure that every {@code package-info.java} produced a {@code package-info.class}.
+ * Otherwise this task's up-to-date tracking mechanisms do not work.
+ * @see <a href="https://issues.apache.org/bugzilla/show_bug.cgi?id=43114">Bug #43114</a>
+ */
+ private void generateMissingPackageInfoClasses(final File dest) throws IOException {
+ for (final Entry<String, Long> entry : packageInfos.entrySet()) {
+ final String pkg = entry.getKey();
+ final Long sourceLastMod = entry.getValue();
+ final File pkgBinDir = new File(dest, pkg.replace('/', File.separatorChar));
+ pkgBinDir.mkdirs();
+ final File pkgInfoClass = new File(pkgBinDir, "package-info.class");
+ if (pkgInfoClass.isFile() && pkgInfoClass.lastModified() >= sourceLastMod.longValue()) {
+ continue;
+ }
+ log("Creating empty " + pkgInfoClass);
+ final OutputStream os = new FileOutputStream(pkgInfoClass);
+ try {
+ os.write(PACKAGE_INFO_CLASS_HEADER);
+ final byte[] name = pkg.getBytes("UTF-8");
+ final int length = name.length + /* "/package-info" */ 13;
+ os.write((byte) length / 256);
+ os.write((byte) length % 256);
+ os.write(name);
+ os.write(PACKAGE_INFO_CLASS_FOOTER);
+ } finally {
+ os.close();
+ }
+ }
+ }
+
+ private static final byte[] PACKAGE_INFO_CLASS_HEADER = {
+ (byte) 0xca, (byte) 0xfe, (byte) 0xba, (byte) 0xbe, 0x00, 0x00, 0x00,
+ 0x31, 0x00, 0x07, 0x07, 0x00, 0x05, 0x07, 0x00, 0x06, 0x01, 0x00, 0x0a,
+ 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x01, 0x00,
+ 0x11, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x2d, 0x69, 0x6e, 0x66,
+ 0x6f, 0x2e, 0x6a, 0x61, 0x76, 0x61, 0x01
+ };
+
+ private static final byte[] PACKAGE_INFO_CLASS_FOOTER = {
+ 0x2f, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x2d, 0x69, 0x6e, 0x66,
+ 0x6f, 0x01, 0x00, 0x10, 0x6a, 0x61, 0x76, 0x61, 0x2f, 0x6c, 0x61, 0x6e,
+ 0x67, 0x2f, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x02, 0x00, 0x00, 0x01,
+ 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x03,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x04
+ };
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Javadoc.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Javadoc.java
new file mode 100644
index 00000000..7637be74
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Javadoc.java
@@ -0,0 +1,2624 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Locale;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.DirectoryScanner;
+import org.apache.tools.ant.MagicNames;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.ProjectComponent;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.types.Commandline;
+import org.apache.tools.ant.types.DirSet;
+import org.apache.tools.ant.types.EnumeratedAttribute;
+import org.apache.tools.ant.types.FileSet;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.types.PatternSet;
+import org.apache.tools.ant.types.Reference;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.ResourceCollection;
+import org.apache.tools.ant.types.resources.FileProvider;
+import org.apache.tools.ant.util.FileUtils;
+import org.apache.tools.ant.util.JavaEnvUtils;
+import org.apache.tools.ant.util.StringUtils;
+
+/**
+ * Generates Javadoc documentation for a collection
+ * of source code.
+ *
+ * <p>Current known limitations are:
+ *
+ * <p><ul>
+ * <li>patterns must be of the form "xxx.*", every other pattern doesn't
+ * work.
+ * <li>there is no control on arguments sanity since they are left
+ * to the Javadoc implementation.
+ * </ul>
+ *
+ * <p>If no <code>doclet</code> is set, then the <code>version</code> and
+ * <code>author</code> are by default <code>"yes"</code>.
+ *
+ * <p>Note: This task is run on another VM because the Javadoc code calls
+ * <code>System.exit()</code> which would break Ant functionality.
+ *
+ * @since Ant 1.1
+ *
+ * @ant.task category="java"
+ */
+public class Javadoc extends Task {
+ // Whether *this VM* is 1.4+ (but also check executable != null).
+
+ private static final boolean JAVADOC_5 =
+ !JavaEnvUtils.isJavaVersion(JavaEnvUtils.JAVA_1_4);
+
+ private static final String LOAD_FRAME = "function loadFrames() {";
+ private static final int LOAD_FRAME_LEN = LOAD_FRAME.length();
+
+ /**
+ * Inner class used to manage doclet parameters.
+ */
+ public class DocletParam {
+ /** The parameter name */
+ private String name;
+
+ /** The parameter value */
+ private String value;
+
+ /**
+ * Set the name of the parameter.
+ *
+ * @param name the name of the doclet parameter
+ */
+ public void setName(final String name) {
+ this.name = name;
+ }
+
+ /**
+ * Get the parameter name.
+ *
+ * @return the parameter's name.
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Set the parameter value.
+ *
+ * Note that only string values are supported. No resolution of file
+ * paths is performed.
+ *
+ * @param value the parameter value.
+ */
+ public void setValue(final String value) {
+ this.value = value;
+ }
+
+ /**
+ * Get the parameter value.
+ *
+ * @return the parameter value.
+ */
+ public String getValue() {
+ return value;
+ }
+ }
+
+ /**
+ * A project aware class used for Javadoc extensions which take a name
+ * and a path such as doclet and taglet arguments.
+ *
+ */
+ public static class ExtensionInfo extends ProjectComponent {
+ /** The name of the extension */
+ private String name;
+
+ /** The optional path to use to load the extension */
+ private Path path;
+
+ /**
+ * Set the name of the extension
+ *
+ * @param name the extension's name.
+ */
+ public void setName(final String name) {
+ this.name = name;
+ }
+
+ /**
+ * Get the name of the extension.
+ *
+ * @return the extension's name.
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Set the path to use when loading the component.
+ *
+ * @param path a Path instance containing the classpath to use.
+ */
+ public void setPath(final Path path) {
+ if (this.path == null) {
+ this.path = path;
+ } else {
+ this.path.append(path);
+ }
+ }
+
+ /**
+ * Get the extension's path.
+ *
+ * @return the path to be used to load the extension.
+ * May be <code>null</code>
+ */
+ public Path getPath() {
+ return path;
+ }
+
+ /**
+ * Create an empty nested path to be configured by Ant with the
+ * classpath for the extension.
+ *
+ * @return a new Path instance to be configured.
+ */
+ public Path createPath() {
+ if (path == null) {
+ path = new Path(getProject());
+ }
+ return path.createPath();
+ }
+
+ /**
+ * Adds a reference to a CLASSPATH defined elsewhere.
+ *
+ * @param r the reference containing the path.
+ */
+ public void setPathRef(final Reference r) {
+ createPath().setRefid(r);
+ }
+ }
+
+ /**
+ * This class stores info about doclets.
+ *
+ */
+ public class DocletInfo extends ExtensionInfo {
+
+ /** Collection of doclet parameters. */
+ private final Vector<DocletParam> params = new Vector<DocletParam>();
+
+ /**
+ * Create a doclet parameter to be configured by Ant.
+ *
+ * @return a new DocletParam instance to be configured.
+ */
+ public DocletParam createParam() {
+ final DocletParam param = new DocletParam();
+ params.addElement(param);
+
+ return param;
+ }
+
+ /**
+ * Get the doclet's parameters.
+ *
+ * @return an Enumeration of DocletParam instances.
+ */
+ public Enumeration<DocletParam> getParams() {
+ return params.elements();
+ }
+ }
+
+ /**
+ * Used to track info about the packages to be javadoc'd
+ */
+ public static class PackageName {
+ /** The package name */
+ private String name;
+
+ /**
+ * Set the name of the package
+ *
+ * @param name the package name.
+ */
+ public void setName(final String name) {
+ this.name = name.trim();
+ }
+
+ /**
+ * Get the package name.
+ *
+ * @return the package's name.
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Return a string rep for this object.
+ * @return the package name.
+ */
+ @Override
+ public String toString() {
+ return getName();
+ }
+ }
+
+ /**
+ * This class is used to manage the source files to be processed.
+ */
+ public static class SourceFile {
+ /** The source file */
+ private File file;
+
+ /**
+ * Default constructor
+ */
+ public SourceFile() {
+ //empty
+ }
+
+ /**
+ * Constructor specifying the source file directly
+ *
+ * @param file the source file
+ */
+ public SourceFile(final File file) {
+ this.file = file;
+ }
+
+ /**
+ * Set the source file.
+ *
+ * @param file the source file.
+ */
+ public void setFile(final File file) {
+ this.file = file;
+ }
+
+ /**
+ * Get the source file.
+ *
+ * @return the source file.
+ */
+ public File getFile() {
+ return file;
+ }
+ }
+
+ /**
+ * An HTML element in the Javadoc.
+ *
+ * This class is used for those Javadoc elements which contain HTML such as
+ * footers, headers, etc.
+ */
+ public static class Html {
+ /** The text for the element */
+ private final StringBuffer text = new StringBuffer();
+
+ /**
+ * Add text to the element.
+ *
+ * @param t the text to be added.
+ */
+ public void addText(final String t) {
+ text.append(t);
+ }
+
+ /**
+ * Get the current text for the element.
+ *
+ * @return the current text.
+ */
+ public String getText() {
+ return text.substring(0);
+ }
+ }
+
+ /**
+ * EnumeratedAttribute implementation supporting the Javadoc scoping
+ * values.
+ */
+ public static class AccessType extends EnumeratedAttribute {
+ /**
+ * @return the allowed values for the access type.
+ */
+ @Override
+ public String[] getValues() {
+ // Protected first so if any GUI tool offers a default
+ // based on enum #0, it will be right.
+ return new String[] {"protected", "public", "package", "private"};
+ }
+ }
+
+ /**
+ * Holds a collection of ResourceCollections.
+ *
+ * <p>A separate kind of container is needed since this task
+ * contains special handling for FileSets that has to occur at
+ * task runtime.</p>
+ */
+ public class ResourceCollectionContainer {
+ private final ArrayList<ResourceCollection> rcs = new ArrayList<ResourceCollection>();
+ /**
+ * Add a resource collection to the container.
+ * @param rc the collection to add.
+ */
+ public void add(final ResourceCollection rc) {
+ rcs.add(rc);
+ }
+
+ /**
+ * Get an iterator on the collection.
+ * @return an iterator.
+ */
+ private Iterator<ResourceCollection> iterator() {
+ return rcs.iterator();
+ }
+ }
+
+ private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+
+ /** The command line built to execute Javadoc. */
+ private final Commandline cmd = new Commandline();
+
+ /**
+ * Utility method to add an argument to the command line conditionally
+ * based on the given flag.
+ *
+ * @param b the flag which controls if the argument is added.
+ * @param arg the argument value.
+ */
+ private void addArgIf(final boolean b, final String arg) {
+ if (b) {
+ cmd.createArgument().setValue(arg);
+ }
+ }
+
+ /**
+ * Utility method to add a Javadoc argument.
+ *
+ * @param key the argument name.
+ * @param value the argument value.
+ */
+ private void addArgIfNotEmpty(final String key, final String value) {
+ if (value != null && value.length() != 0) {
+ cmd.createArgument().setValue(key);
+ cmd.createArgument().setValue(value);
+ } else {
+ log("Warning: Leaving out empty argument '" + key + "'",
+ Project.MSG_WARN);
+ }
+ }
+
+ /**
+ * Flag which indicates if the task should fail if there is a
+ * Javadoc error.
+ */
+ private boolean failOnError = false;
+ /**
+ * Flag which indicates if the task should fail if there is a
+ * Javadoc warning.
+ */
+ private boolean failOnWarning = false;
+ private Path sourcePath = null;
+ private File destDir = null;
+ private final Vector<SourceFile> sourceFiles = new Vector<SourceFile>();
+ private final Vector<PackageName> packageNames = new Vector<PackageName>();
+ private final Vector<PackageName> excludePackageNames = new Vector<PackageName>(1);
+ private boolean author = true;
+ private boolean version = true;
+ private DocletInfo doclet = null;
+ private Path classpath = null;
+ private Path bootclasspath = null;
+ private String group = null;
+ private String packageList = null;
+ private final Vector<LinkArgument> links = new Vector<LinkArgument>();
+ private final Vector<GroupArgument> groups = new Vector<GroupArgument>();
+ private final Vector<Object> tags = new Vector<Object>();
+ private boolean useDefaultExcludes = true;
+ private Html doctitle = null;
+ private Html header = null;
+ private Html footer = null;
+ private Html bottom = null;
+ private boolean useExternalFile = false;
+ private String source = null;
+ private boolean linksource = false;
+ private boolean breakiterator = false;
+ private String noqualifier;
+ private boolean includeNoSourcePackages = false;
+ private String executable = null;
+ private boolean docFilesSubDirs = false;
+ private String excludeDocFilesSubDir = null;
+ private String docEncoding = null;
+ private boolean postProcessGeneratedJavadocs = true;
+
+ private final ResourceCollectionContainer nestedSourceFiles
+ = new ResourceCollectionContainer();
+ private final Vector<DirSet> packageSets = new Vector<DirSet>();
+
+ /**
+ * Work around command line length limit by using an external file
+ * for the sourcefiles.
+ *
+ * @param b true if an external file is to be used.
+ */
+ public void setUseExternalFile(final boolean b) {
+ useExternalFile = b;
+ }
+
+ /**
+ * Sets whether default exclusions should be used or not.
+ *
+ * @param useDefaultExcludes "true"|"on"|"yes" when default exclusions
+ * should be used, "false"|"off"|"no" when they
+ * shouldn't be used.
+ */
+ public void setDefaultexcludes(final boolean useDefaultExcludes) {
+ this.useDefaultExcludes = useDefaultExcludes;
+ }
+
+ /**
+ * Set the maximum memory to be used by the javadoc process
+ *
+ * @param max a string indicating the maximum memory according to the
+ * JVM conventions (e.g. 128m is 128 Megabytes)
+ */
+ public void setMaxmemory(final String max) {
+ cmd.createArgument().setValue("-J-Xmx" + max);
+ }
+
+ /**
+ * Set an additional parameter on the command line
+ *
+ * @param add the additional command line parameter for the javadoc task.
+ */
+ public void setAdditionalparam(final String add) {
+ cmd.createArgument().setLine(add);
+ }
+
+ /**
+ * Adds a command-line argument.
+ * @return a command-line argument to configure
+ * @since Ant 1.6
+ */
+ public Commandline.Argument createArg() {
+ return cmd.createArgument();
+ }
+
+ /**
+ * Specify where to find source file
+ *
+ * @param src a Path instance containing the various source directories.
+ */
+ public void setSourcepath(final Path src) {
+ if (sourcePath == null) {
+ sourcePath = src;
+ } else {
+ sourcePath.append(src);
+ }
+ }
+
+ /**
+ * Create a path to be configured with the locations of the source
+ * files.
+ *
+ * @return a new Path instance to be configured by the Ant core.
+ */
+ public Path createSourcepath() {
+ if (sourcePath == null) {
+ sourcePath = new Path(getProject());
+ }
+ return sourcePath.createPath();
+ }
+
+ /**
+ * Adds a reference to a CLASSPATH defined elsewhere.
+ *
+ * @param r the reference containing the source path definition.
+ */
+ public void setSourcepathRef(final Reference r) {
+ createSourcepath().setRefid(r);
+ }
+
+ /**
+ * Set the directory where the Javadoc output will be generated.
+ *
+ * @param dir the destination directory.
+ */
+ public void setDestdir(final File dir) {
+ destDir = dir;
+ cmd.createArgument().setValue("-d");
+ cmd.createArgument().setFile(destDir);
+ }
+
+ /**
+ * Set the list of source files to process.
+ *
+ * @param src a comma separated list of source files.
+ */
+ public void setSourcefiles(final String src) {
+ final StringTokenizer tok = new StringTokenizer(src, ",");
+ while (tok.hasMoreTokens()) {
+ final String f = tok.nextToken();
+ final SourceFile sf = new SourceFile();
+ sf.setFile(getProject().resolveFile(f.trim()));
+ addSource(sf);
+ }
+ }
+
+ /**
+ * Add a single source file.
+ *
+ * @param sf the source file to be processed.
+ */
+ public void addSource(final SourceFile sf) {
+ sourceFiles.addElement(sf);
+ }
+
+ /**
+ * Set the package names to be processed.
+ *
+ * @param packages a comma separated list of packages specs
+ * (may be wildcarded).
+ *
+ * @see #addPackage for wildcard information.
+ */
+ public void setPackagenames(final String packages) {
+ final StringTokenizer tok = new StringTokenizer(packages, ",");
+ while (tok.hasMoreTokens()) {
+ final String p = tok.nextToken();
+ final PackageName pn = new PackageName();
+ pn.setName(p);
+ addPackage(pn);
+ }
+ }
+
+ /**
+ * Add a single package to be processed.
+ *
+ * If the package name ends with &quot;.*&quot; the Javadoc task
+ * will find and process all subpackages.
+ *
+ * @param pn the package name, possibly wildcarded.
+ */
+ public void addPackage(final PackageName pn) {
+ packageNames.addElement(pn);
+ }
+
+ /**
+ * Set the list of packages to be excluded.
+ *
+ * @param packages a comma separated list of packages to be excluded.
+ * This may not include wildcards.
+ */
+ public void setExcludePackageNames(final String packages) {
+ final StringTokenizer tok = new StringTokenizer(packages, ",");
+ while (tok.hasMoreTokens()) {
+ final String p = tok.nextToken();
+ final PackageName pn = new PackageName();
+ pn.setName(p);
+ addExcludePackage(pn);
+ }
+ }
+
+ /**
+ * Add a package to be excluded from the Javadoc run.
+ *
+ * @param pn the name of the package (wildcards are not permitted).
+ */
+ public void addExcludePackage(final PackageName pn) {
+ excludePackageNames.addElement(pn);
+ }
+
+ /**
+ * Specify the file containing the overview to be included in the generated
+ * documentation.
+ *
+ * @param f the file containing the overview.
+ */
+ public void setOverview(final File f) {
+ cmd.createArgument().setValue("-overview");
+ cmd.createArgument().setFile(f);
+ }
+
+ /**
+ * Indicate whether only public classes and members are to be included in
+ * the scope processed
+ *
+ * @param b true if scope is to be public.
+ */
+ public void setPublic(final boolean b) {
+ addArgIf(b, "-public");
+ }
+
+ /**
+ * Indicate whether only protected and public classes and members are to
+ * be included in the scope processed
+ *
+ * @param b true if scope is to be protected.
+ */
+ public void setProtected(final boolean b) {
+ addArgIf(b, "-protected");
+ }
+
+ /**
+ * Indicate whether only package, protected and public classes and
+ * members are to be included in the scope processed
+ *
+ * @param b true if scope is to be package level.
+ */
+ public void setPackage(final boolean b) {
+ addArgIf(b, "-package");
+ }
+
+ /**
+ * Indicate whether all classes and
+ * members are to be included in the scope processed
+ *
+ * @param b true if scope is to be private level.
+ */
+ public void setPrivate(final boolean b) {
+ addArgIf(b, "-private");
+ }
+
+ /**
+ * Set the scope to be processed. This is an alternative to the
+ * use of the setPublic, setPrivate, etc methods. It gives better build
+ * file control over what scope is processed.
+ *
+ * @param at the scope to be processed.
+ */
+ public void setAccess(final AccessType at) {
+ cmd.createArgument().setValue("-" + at.getValue());
+ }
+
+ /**
+ * Set the class that starts the doclet used in generating the
+ * documentation.
+ *
+ * @param docletName the name of the doclet class.
+ */
+ public void setDoclet(final String docletName) {
+ if (doclet == null) {
+ doclet = new DocletInfo();
+ doclet.setProject(getProject());
+ }
+ doclet.setName(docletName);
+ }
+
+ /**
+ * Set the classpath used to find the doclet class.
+ *
+ * @param docletPath the doclet classpath.
+ */
+ public void setDocletPath(final Path docletPath) {
+ if (doclet == null) {
+ doclet = new DocletInfo();
+ doclet.setProject(getProject());
+ }
+ doclet.setPath(docletPath);
+ }
+
+ /**
+ * Set the classpath used to find the doclet class by reference.
+ *
+ * @param r the reference to the Path instance to use as the doclet
+ * classpath.
+ */
+ public void setDocletPathRef(final Reference r) {
+ if (doclet == null) {
+ doclet = new DocletInfo();
+ doclet.setProject(getProject());
+ }
+ doclet.createPath().setRefid(r);
+ }
+
+ /**
+ * Create a doclet to be used in the documentation generation.
+ *
+ * @return a new DocletInfo instance to be configured.
+ */
+ public DocletInfo createDoclet() {
+ if (doclet == null) {
+ doclet = new DocletInfo();
+ }
+ return doclet;
+ }
+
+ /**
+ * Add a taglet
+ *
+ * @param tagletInfo information about the taglet.
+ */
+ public void addTaglet(final ExtensionInfo tagletInfo) {
+ tags.addElement(tagletInfo);
+ }
+
+ /**
+ * Indicate whether Javadoc should produce old style (JDK 1.1)
+ * documentation.
+ *
+ * This is not supported by JDK 1.1 and has been phased out in JDK 1.4
+ *
+ * @param b if true attempt to generate old style documentation.
+ */
+ public void setOld(final boolean b) {
+ log("Javadoc 1.4 doesn't support the -1.1 switch anymore",
+ Project.MSG_WARN);
+ }
+
+ /**
+ * Set the classpath to be used for this Javadoc run.
+ *
+ * @param path an Ant Path object containing the compilation
+ * classpath.
+ */
+ public void setClasspath(final Path path) {
+ if (classpath == null) {
+ classpath = path;
+ } else {
+ classpath.append(path);
+ }
+ }
+
+ /**
+ * Create a Path to be configured with the classpath to use
+ *
+ * @return a new Path instance to be configured with the classpath.
+ */
+ public Path createClasspath() {
+ if (classpath == null) {
+ classpath = new Path(getProject());
+ }
+ return classpath.createPath();
+ }
+
+ /**
+ * Adds a reference to a CLASSPATH defined elsewhere.
+ *
+ * @param r the reference to an instance defining the classpath.
+ */
+ public void setClasspathRef(final Reference r) {
+ createClasspath().setRefid(r);
+ }
+
+ /**
+ * Set the boot classpath to use.
+ *
+ * @param path the boot classpath.
+ */
+ public void setBootclasspath(final Path path) {
+ if (bootclasspath == null) {
+ bootclasspath = path;
+ } else {
+ bootclasspath.append(path);
+ }
+ }
+
+ /**
+ * Create a Path to be configured with the boot classpath
+ *
+ * @return a new Path instance to be configured with the boot classpath.
+ */
+ public Path createBootclasspath() {
+ if (bootclasspath == null) {
+ bootclasspath = new Path(getProject());
+ }
+ return bootclasspath.createPath();
+ }
+
+ /**
+ * Adds a reference to a CLASSPATH defined elsewhere.
+ *
+ * @param r the reference to an instance defining the bootclasspath.
+ */
+ public void setBootClasspathRef(final Reference r) {
+ createBootclasspath().setRefid(r);
+ }
+
+ /**
+ * Set the location of the extensions directories.
+ *
+ * @param path the string version of the path.
+ * @deprecated since 1.5.x.
+ * Use the {@link #setExtdirs(Path)} version.
+ */
+ @Deprecated
+ public void setExtdirs(final String path) {
+ cmd.createArgument().setValue("-extdirs");
+ cmd.createArgument().setValue(path);
+ }
+
+ /**
+ * Set the location of the extensions directories.
+ *
+ * @param path a path containing the extension directories.
+ */
+ public void setExtdirs(final Path path) {
+ cmd.createArgument().setValue("-extdirs");
+ cmd.createArgument().setPath(path);
+ }
+
+ /**
+ * Run javadoc in verbose mode
+ *
+ * @param b true if operation is to be verbose.
+ */
+ public void setVerbose(final boolean b) {
+ addArgIf(b, "-verbose");
+ }
+
+ /**
+ * Set the local to use in documentation generation.
+ *
+ * @param locale the locale to use.
+ */
+ public void setLocale(final String locale) {
+ // createArgument(true) is necessary to make sure -locale
+ // is the first argument (required in 1.3+).
+ cmd.createArgument(true).setValue(locale);
+ cmd.createArgument(true).setValue("-locale");
+ }
+
+ /**
+ * Set the encoding name of the source files,
+ *
+ * @param enc the name of the encoding for the source files.
+ */
+ public void setEncoding(final String enc) {
+ cmd.createArgument().setValue("-encoding");
+ cmd.createArgument().setValue(enc);
+ }
+
+ /**
+ * Include the version tag in the generated documentation.
+ *
+ * @param b true if the version tag should be included.
+ */
+ public void setVersion(final boolean b) {
+ this.version = b;
+ }
+
+ /**
+ * Generate the &quot;use&quot; page for each package.
+ *
+ * @param b true if the use page should be generated.
+ */
+ public void setUse(final boolean b) {
+ addArgIf(b, "-use");
+ }
+
+
+ /**
+ * Include the author tag in the generated documentation.
+ *
+ * @param b true if the author tag should be included.
+ */
+ public void setAuthor(final boolean b) {
+ author = b;
+ }
+
+ /**
+ * Generate a split index
+ *
+ * @param b true if the index should be split into a file per letter.
+ */
+ public void setSplitindex(final boolean b) {
+ addArgIf(b, "-splitindex");
+ }
+
+ /**
+ * Set the title to be placed in the HTML &lt;title&gt; tag of the
+ * generated documentation.
+ *
+ * @param title the window title to use.
+ */
+ public void setWindowtitle(final String title) {
+ addArgIfNotEmpty("-windowtitle", title);
+ }
+
+ /**
+ * Set the title of the generated overview page.
+ *
+ * @param doctitle the Document title.
+ */
+ public void setDoctitle(final String doctitle) {
+ final Html h = new Html();
+ h.addText(doctitle);
+ addDoctitle(h);
+ }
+
+ /**
+ * Add a document title to use for the overview page.
+ *
+ * @param text the HTML element containing the document title.
+ */
+ public void addDoctitle(final Html text) {
+ doctitle = text;
+ }
+
+ /**
+ * Set the header text to be placed at the top of each output file.
+ *
+ * @param header the header text
+ */
+ public void setHeader(final String header) {
+ final Html h = new Html();
+ h.addText(header);
+ addHeader(h);
+ }
+
+ /**
+ * Set the header text to be placed at the top of each output file.
+ *
+ * @param text the header text
+ */
+ public void addHeader(final Html text) {
+ header = text;
+ }
+
+ /**
+ * Set the footer text to be placed at the bottom of each output file.
+ *
+ * @param footer the footer text.
+ */
+ public void setFooter(final String footer) {
+ final Html h = new Html();
+ h.addText(footer);
+ addFooter(h);
+ }
+
+ /**
+ * Set the footer text to be placed at the bottom of each output file.
+ *
+ * @param text the footer text.
+ */
+ public void addFooter(final Html text) {
+ footer = text;
+ }
+
+ /**
+ * Set the text to be placed at the bottom of each output file.
+ *
+ * @param bottom the bottom text.
+ */
+ public void setBottom(final String bottom) {
+ final Html h = new Html();
+ h.addText(bottom);
+ addBottom(h);
+ }
+
+ /**
+ * Set the text to be placed at the bottom of each output file.
+ *
+ * @param text the bottom text.
+ */
+ public void addBottom(final Html text) {
+ bottom = text;
+ }
+
+ /**
+ * Link to docs at "url" using package list at "url2"
+ * - separate the URLs by using a space character.
+ *
+ * @param src the offline link specification (url and package list)
+ */
+ public void setLinkoffline(final String src) {
+ final LinkArgument le = createLink();
+ le.setOffline(true);
+ final String linkOfflineError = "The linkoffline attribute must include"
+ + " a URL and a package-list file location separated by a"
+ + " space";
+ if (src.trim().length() == 0) {
+ throw new BuildException(linkOfflineError);
+ }
+ final StringTokenizer tok = new StringTokenizer(src, " ", false);
+ le.setHref(tok.nextToken());
+
+ if (!tok.hasMoreTokens()) {
+ throw new BuildException(linkOfflineError);
+ }
+ le.setPackagelistLoc(getProject().resolveFile(tok.nextToken()));
+ }
+
+ /**
+ * Group specified packages together in overview page.
+ *
+ * @param src the group packages - a command separated list of group specs,
+ * each one being a group name and package specification separated
+ * by a space.
+ */
+ public void setGroup(final String src) {
+ group = src;
+ }
+
+ /**
+ * Create links to Javadoc output at the given URL.
+ * @param src the URL to link to
+ */
+ public void setLink(final String src) {
+ createLink().setHref(src);
+ }
+
+ /**
+ * Control deprecation information
+ *
+ * @param b If true, do not include deprecated information.
+ */
+ public void setNodeprecated(final boolean b) {
+ addArgIf(b, "-nodeprecated");
+ }
+
+ /**
+ * Control deprecated list generation
+ *
+ * @param b if true, do not generate deprecated list.
+ */
+ public void setNodeprecatedlist(final boolean b) {
+ addArgIf(b, "-nodeprecatedlist");
+ }
+
+ /**
+ * Control class tree generation.
+ *
+ * @param b if true, do not generate class hierarchy.
+ */
+ public void setNotree(final boolean b) {
+ addArgIf(b, "-notree");
+ }
+
+ /**
+ * Control generation of index.
+ *
+ * @param b if true, do not generate index.
+ */
+ public void setNoindex(final boolean b) {
+ addArgIf(b, "-noindex");
+ }
+
+ /**
+ * Control generation of help link.
+ *
+ * @param b if true, do not generate help link
+ */
+ public void setNohelp(final boolean b) {
+ addArgIf(b, "-nohelp");
+ }
+
+ /**
+ * Control generation of the navigation bar.
+ *
+ * @param b if true, do not generate navigation bar.
+ */
+ public void setNonavbar(final boolean b) {
+ addArgIf(b, "-nonavbar");
+ }
+
+ /**
+ * Control warnings about serial tag.
+ *
+ * @param b if true, generate warning about the serial tag.
+ */
+ public void setSerialwarn(final boolean b) {
+ addArgIf(b, "-serialwarn");
+ }
+
+ /**
+ * Specifies the CSS stylesheet file to use.
+ *
+ * @param f the file with the CSS to use.
+ */
+ public void setStylesheetfile(final File f) {
+ cmd.createArgument().setValue("-stylesheetfile");
+ cmd.createArgument().setFile(f);
+ }
+
+ /**
+ * Specifies the HTML help file to use.
+ *
+ * @param f the file containing help content.
+ */
+ public void setHelpfile(final File f) {
+ cmd.createArgument().setValue("-helpfile");
+ cmd.createArgument().setFile(f);
+ }
+
+ /**
+ * Output file encoding name.
+ *
+ * @param enc name of the encoding to use.
+ */
+ public void setDocencoding(final String enc) {
+ cmd.createArgument().setValue("-docencoding");
+ cmd.createArgument().setValue(enc);
+ docEncoding = enc;
+ }
+
+ /**
+ * The name of a file containing the packages to process.
+ *
+ * @param src the file containing the package list.
+ */
+ public void setPackageList(final String src) {
+ packageList = src;
+ }
+
+ /**
+ * Create link to Javadoc output at the given URL.
+ *
+ * @return link argument to configure
+ */
+ public LinkArgument createLink() {
+ final LinkArgument la = new LinkArgument();
+ links.addElement(la);
+ return la;
+ }
+
+ /**
+ * Represents a link triplet (href, whether link is offline,
+ * location of the package list if off line)
+ */
+ public class LinkArgument {
+ private String href;
+ private boolean offline = false;
+ private File packagelistLoc;
+ private URL packagelistURL;
+ private boolean resolveLink = false;
+
+ /** Constructor for LinkArgument */
+ public LinkArgument() {
+ //empty
+ }
+
+ /**
+ * Set the href attribute.
+ * @param hr a <code>String</code> value
+ */
+ public void setHref(final String hr) {
+ href = hr;
+ }
+
+ /**
+ * Get the href attribute.
+ * @return the href attribute.
+ */
+ public String getHref() {
+ return href;
+ }
+
+ /**
+ * Set the packetlist location attribute.
+ * @param src a <code>File</code> value
+ */
+ public void setPackagelistLoc(final File src) {
+ packagelistLoc = src;
+ }
+
+ /**
+ * Get the packetList location attribute.
+ * @return the packetList location attribute.
+ */
+ public File getPackagelistLoc() {
+ return packagelistLoc;
+ }
+
+ /**
+ * Set the packetlist location attribute.
+ * @param src an <code>URL</code> value
+ */
+ public void setPackagelistURL(final URL src) {
+ packagelistURL = src;
+ }
+
+ /**
+ * Get the packetList location attribute.
+ * @return the packetList location attribute.
+ */
+ public URL getPackagelistURL() {
+ return packagelistURL;
+ }
+
+ /**
+ * Set the offline attribute.
+ * @param offline a <code>boolean</code> value
+ */
+ public void setOffline(final boolean offline) {
+ this.offline = offline;
+ }
+
+ /**
+ * Get the linkOffline attribute.
+ * @return the linkOffline attribute.
+ */
+ public boolean isLinkOffline() {
+ return offline;
+ }
+
+ /**
+ * Sets whether Ant should resolve the link attribute relative
+ * to the current basedir.
+ * @param resolve a <code>boolean</code> value
+ */
+ public void setResolveLink(final boolean resolve) {
+ this.resolveLink = resolve;
+ }
+
+ /**
+ * should Ant resolve the link attribute relative to the
+ * current basedir?
+ * @return the resolveLink attribute.
+ */
+ public boolean shouldResolveLink() {
+ return resolveLink;
+ }
+
+ }
+
+ /**
+ * Creates and adds a -tag argument. This is used to specify
+ * custom tags. This argument is only available for Javadoc 1.4,
+ * and will generate a verbose message (and then be ignored)
+ * when run on Java versions below 1.4.
+ * @return tag argument to be configured
+ */
+ public TagArgument createTag() {
+ final TagArgument ta = new TagArgument();
+ tags.addElement (ta);
+ return ta;
+ }
+
+ /**
+ * Scope element verbose names. (Defined here as fields
+ * cannot be static in inner classes.) The first letter
+ * from each element is used to build up the scope string.
+ */
+ static final String[] SCOPE_ELEMENTS = {
+ "overview", "packages", "types", "constructors",
+ "methods", "fields"
+ };
+
+ /**
+ * Class representing a -tag argument.
+ */
+ public class TagArgument extends FileSet {
+ /** Name of the tag. */
+ private String name = null;
+ /** Whether or not the tag is enabled. */
+ private boolean enabled = true;
+ /**
+ * Scope string of the tag. This will form the middle
+ * argument of the -tag parameter when the tag is enabled
+ * (with an X prepended for and is parsed from human-readable form.
+ */
+ private String scope = "a";
+
+ /** Sole constructor. */
+ public TagArgument () {
+ //empty
+ }
+
+ /**
+ * Sets the name of the tag.
+ *
+ * @param name The name of the tag.
+ * Must not be <code>null</code> or empty.
+ */
+ public void setName (final String name) {
+ this.name = name;
+ }
+
+ /**
+ * Sets the scope of the tag. This is in comma-separated
+ * form, with each element being one of "all" (the default),
+ * "overview", "packages", "types", "constructors", "methods",
+ * "fields". The elements are treated in a case-insensitive
+ * manner.
+ *
+ * @param verboseScope The scope of the tag.
+ * Must not be <code>null</code>,
+ * should not be empty.
+ *
+ * @exception BuildException if all is specified along with
+ * other elements, if any elements are repeated, if no
+ * elements are specified, or if any unrecognised elements are
+ * specified.
+ */
+ public void setScope (String verboseScope) throws BuildException {
+ verboseScope = verboseScope.toLowerCase(Locale.ENGLISH);
+
+ final boolean[] elements = new boolean[SCOPE_ELEMENTS.length];
+
+ boolean gotAll = false;
+ boolean gotNotAll = false;
+
+ // Go through the tokens one at a time, updating the
+ // elements array and issuing warnings where appropriate.
+ final StringTokenizer tok = new StringTokenizer (verboseScope, ",");
+ while (tok.hasMoreTokens()) {
+ final String next = tok.nextToken().trim();
+ if (next.equals("all")) {
+ if (gotAll) {
+ getProject().log ("Repeated tag scope element: all",
+ Project.MSG_VERBOSE);
+ }
+ gotAll = true;
+ } else {
+ int i;
+ for (i = 0; i < SCOPE_ELEMENTS.length; i++) {
+ if (next.equals (SCOPE_ELEMENTS[i])) {
+ break;
+ }
+ }
+ if (i == SCOPE_ELEMENTS.length) {
+ throw new BuildException ("Unrecognised scope element: "
+ + next);
+ } else {
+ if (elements[i]) {
+ getProject().log ("Repeated tag scope element: "
+ + next, Project.MSG_VERBOSE);
+ }
+ elements[i] = true;
+ gotNotAll = true;
+ }
+ }
+ }
+
+ if (gotNotAll && gotAll) {
+ throw new BuildException ("Mixture of \"all\" and other scope "
+ + "elements in tag parameter.");
+ }
+ if (!gotNotAll && !gotAll) {
+ throw new BuildException ("No scope elements specified in tag "
+ + "parameter.");
+ }
+ if (gotAll) {
+ this.scope = "a";
+ } else {
+ final StringBuffer buff = new StringBuffer (elements.length);
+ for (int i = 0; i < elements.length; i++) {
+ if (elements[i]) {
+ buff.append (SCOPE_ELEMENTS[i].charAt(0));
+ }
+ }
+ this.scope = buff.toString();
+ }
+ }
+
+ /**
+ * Sets whether or not the tag is enabled.
+ *
+ * @param enabled Whether or not this tag is enabled.
+ */
+ public void setEnabled (final boolean enabled) {
+ this.enabled = enabled;
+ }
+
+ /**
+ * Returns the -tag parameter this argument represented.
+ * @return the -tag parameter as a string
+ * @exception BuildException if either the name or description
+ * is <code>null</code> or empty.
+ */
+ public String getParameter() throws BuildException {
+ if (name == null || name.equals("")) {
+ throw new BuildException ("No name specified for custom tag.");
+ }
+ if (getDescription() != null) {
+ return name + ":" + (enabled ? "" : "X")
+ + scope + ":" + getDescription();
+ } else if (!enabled || !"a".equals(scope)) {
+ return name + ":" + (enabled ? "" : "X") + scope;
+ } else {
+ return name;
+ }
+ }
+ }
+
+ /**
+ * Separates packages on the overview page into whatever
+ * groups you specify, one group per table.
+ * @return a group argument to be configured
+ */
+ public GroupArgument createGroup() {
+ final GroupArgument ga = new GroupArgument();
+ groups.addElement(ga);
+ return ga;
+ }
+
+
+ /**
+ * A class corresponding to the group nested element.
+ */
+ public class GroupArgument {
+ private Html title;
+ private final Vector<PackageName> packages = new Vector<PackageName>();
+
+ /** Constructor for GroupArgument */
+ public GroupArgument() {
+ //empty
+ }
+
+ /**
+ * Set the title attribute using a string.
+ * @param src a <code>String</code> value
+ */
+ public void setTitle(final String src) {
+ final Html h = new Html();
+ h.addText(src);
+ addTitle(h);
+ }
+ /**
+ * Set the title attribute using a nested Html value.
+ * @param text a <code>Html</code> value
+ */
+ public void addTitle(final Html text) {
+ title = text;
+ }
+
+ /**
+ * Get the title.
+ * @return the title
+ */
+ public String getTitle() {
+ return title != null ? title.getText() : null;
+ }
+
+ /**
+ * Set the packages to Javadoc on.
+ * @param src a comma separated list of packages
+ */
+ public void setPackages(final String src) {
+ final StringTokenizer tok = new StringTokenizer(src, ",");
+ while (tok.hasMoreTokens()) {
+ final String p = tok.nextToken();
+ final PackageName pn = new PackageName();
+ pn.setName(p);
+ addPackage(pn);
+ }
+ }
+ /**
+ * Add a package nested element.
+ * @param pn a nested element specifying the package.
+ */
+ public void addPackage(final PackageName pn) {
+ packages.addElement(pn);
+ }
+
+ /**
+ * Get the packages as a colon separated list.
+ * @return the packages as a string
+ */
+ public String getPackages() {
+ final StringBuffer p = new StringBuffer();
+ final int size = packages.size();
+ for (int i = 0; i < size; i++) {
+ if (i > 0) {
+ p.append(":");
+ }
+ p.append(packages.elementAt(i).toString());
+ }
+ return p.toString();
+ }
+ }
+
+ /**
+ * Charset for cross-platform viewing of generated documentation.
+ * @param src the name of the charset
+ */
+ public void setCharset(final String src) {
+ this.addArgIfNotEmpty("-charset", src);
+ }
+
+ /**
+ * Should the build process fail if Javadoc fails (as indicated by
+ * a non zero return code)?
+ *
+ * <p>Default is false.</p>
+ * @param b a <code>boolean</code> value
+ */
+ public void setFailonerror(final boolean b) {
+ failOnError = b;
+ }
+
+ /**
+ * Should the build process fail if Javadoc warns (as indicated by
+ * the word "warning" on stdout)?
+ *
+ * <p>Default is false.</p>
+ * @param b a <code>boolean</code> value
+ * @since Ant 1.9.4
+ */
+ public void setFailonwarning(final boolean b) {
+ failOnWarning = b;
+ }
+
+ /**
+ * Enables the -source switch, will be ignored if Javadoc is not
+ * the 1.4 version.
+ * @param source a <code>String</code> value
+ * @since Ant 1.5
+ */
+ public void setSource(final String source) {
+ this.source = source;
+ }
+
+ /**
+ * Sets the actual executable command to invoke, instead of the binary
+ * <code>javadoc</code> found in Ant's JDK.
+ * @param executable the command to invoke.
+ * @since Ant 1.6.3
+ */
+ public void setExecutable(final String executable) {
+ this.executable = executable;
+ }
+
+ /**
+ * Adds a packageset.
+ *
+ * <p>All included directories will be translated into package
+ * names be converting the directory separator into dots.</p>
+ * @param packageSet a directory set
+ * @since 1.5
+ */
+ public void addPackageset(final DirSet packageSet) {
+ packageSets.addElement(packageSet);
+ }
+
+ /**
+ * Adds a fileset.
+ *
+ * <p>All included files will be added as sourcefiles. The task
+ * will automatically add
+ * <code>includes=&quot;**&#47;*.java&quot;</code> to the
+ * fileset.</p>
+ * @param fs a file set
+ * @since 1.5
+ */
+ public void addFileset(final FileSet fs) {
+ createSourceFiles().add(fs);
+ }
+
+ /**
+ * Adds a container for resource collections.
+ *
+ * <p>All included files will be added as sourcefiles.</p>
+ * @return the source files to configure.
+ * @since 1.7
+ */
+ public ResourceCollectionContainer createSourceFiles() {
+ return nestedSourceFiles;
+ }
+
+ /**
+ * Enables the -linksource switch, will be ignored if Javadoc is not
+ * the 1.4 version. Default is false
+ * @param b a <code>String</code> value
+ * @since Ant 1.6
+ */
+ public void setLinksource(final boolean b) {
+ this.linksource = b;
+ }
+
+ /**
+ * Enables the -linksource switch, will be ignored if Javadoc is not
+ * the 1.4 version. Default is false
+ * @param b a <code>String</code> value
+ * @since Ant 1.6
+ */
+ public void setBreakiterator(final boolean b) {
+ this.breakiterator = b;
+ }
+
+ /**
+ * Enables the -noqualifier switch, will be ignored if Javadoc is not
+ * the 1.4 version.
+ * @param noqualifier the parameter to the -noqualifier switch
+ * @since Ant 1.6
+ */
+ public void setNoqualifier(final String noqualifier) {
+ this.noqualifier = noqualifier;
+ }
+
+ /**
+ * If set to true, Ant will also accept packages that only hold
+ * package.html files but no Java sources.
+ * @param b a <code>boolean</code> value.
+ * @since Ant 1.6.3
+ */
+ public void setIncludeNoSourcePackages(final boolean b) {
+ this.includeNoSourcePackages = b;
+ }
+
+ /**
+ * Enables deep-copying of <code>doc-files</code> directories.
+ *
+ * @since Ant 1.8.0
+ */
+ public void setDocFilesSubDirs(final boolean b) {
+ docFilesSubDirs = b;
+ }
+
+ /**
+ * Colon-separated list of <code>doc-files</code> subdirectories
+ * to skip if {@link #setDocFilesSubDirs docFilesSubDirs is true}.
+ *
+ * @since Ant 1.8.0
+ */
+ public void setExcludeDocFilesSubDir(final String s) {
+ excludeDocFilesSubDir = s;
+ }
+
+ /**
+ * Whether to post-process the generated javadocs in order to mitigate CVE-2013-1571.
+ * @since Ant 1.9.2
+ */
+ public void setPostProcessGeneratedJavadocs(final boolean b) {
+ postProcessGeneratedJavadocs = b;
+ }
+
+ /**
+ * Execute the task.
+ * @throws BuildException on error
+ */
+ @Override
+ public void execute() throws BuildException {
+ checkTaskName();
+
+ final Vector<String> packagesToDoc = new Vector<String>();
+ final Path sourceDirs = new Path(getProject());
+
+ checkPackageAndSourcePath();
+
+ if (sourcePath != null) {
+ sourceDirs.addExisting(sourcePath);
+ }
+
+ parsePackages(packagesToDoc, sourceDirs);
+ checkPackages(packagesToDoc, sourceDirs);
+
+ @SuppressWarnings("unchecked")
+ final Vector<SourceFile> sourceFilesToDoc = (Vector<SourceFile>) sourceFiles.clone();
+ addSourceFiles(sourceFilesToDoc);
+
+ checkPackagesToDoc(packagesToDoc, sourceFilesToDoc);
+
+ log("Generating Javadoc", Project.MSG_INFO);
+
+ final Commandline toExecute = (Commandline) cmd.clone();
+ if (executable != null) {
+ toExecute.setExecutable(executable);
+ } else {
+ toExecute.setExecutable(JavaEnvUtils.getJdkExecutable("javadoc"));
+ }
+
+ // Javadoc arguments
+ generalJavadocArguments(toExecute); // general Javadoc arguments
+ doSourcePath(toExecute, sourceDirs); // sourcepath
+ doDoclet(toExecute); // arguments for default doclet
+ doBootPath(toExecute); // bootpath
+ doLinks(toExecute); // links arguments
+ doGroup(toExecute); // group attribute
+ doGroups(toExecute); // groups attribute
+ doDocFilesSubDirs(toExecute); // docfilessubdir attribute
+
+ doJava14(toExecute);
+ if (breakiterator && (doclet == null || JAVADOC_5)) {
+ toExecute.createArgument().setValue("-breakiterator");
+ }
+ // If using an external file, write the command line options to it
+ if (useExternalFile) {
+ writeExternalArgs(toExecute);
+ }
+
+ File tmpList = null;
+ FileWriter wr = null;
+ try {
+ /**
+ * Write sourcefiles and package names to a temporary file
+ * if requested.
+ */
+ BufferedWriter srcListWriter = null;
+ if (useExternalFile) {
+ tmpList = FILE_UTILS.createTempFile("javadoc", "", null, true, true);
+ toExecute.createArgument()
+ .setValue("@" + tmpList.getAbsolutePath());
+ wr = new FileWriter(tmpList.getAbsolutePath(), true);
+ srcListWriter = new BufferedWriter(wr);
+ }
+
+ doSourceAndPackageNames(
+ toExecute, packagesToDoc, sourceFilesToDoc,
+ useExternalFile, tmpList, srcListWriter);
+
+ if (useExternalFile) {
+ srcListWriter.flush();
+ }
+ } catch (final IOException e) {
+ tmpList.delete();
+ throw new BuildException("Error creating temporary file",
+ e, getLocation());
+ } finally {
+ FileUtils.close(wr);
+ }
+
+ if (packageList != null) {
+ toExecute.createArgument().setValue("@" + packageList);
+ }
+ log(toExecute.describeCommand(), Project.MSG_VERBOSE);
+
+ log("Javadoc execution", Project.MSG_INFO);
+
+ final JavadocOutputStream out = new JavadocOutputStream(Project.MSG_INFO);
+ final JavadocOutputStream err = new JavadocOutputStream(Project.MSG_WARN);
+ final Execute exe = new Execute(new PumpStreamHandler(out, err));
+ exe.setAntRun(getProject());
+
+ /*
+ * No reason to change the working directory as all filenames and
+ * path components have been resolved already.
+ *
+ * Avoid problems with command line length in some environments.
+ */
+ exe.setWorkingDirectory(null);
+ try {
+ exe.setCommandline(toExecute.getCommandline());
+ final int ret = exe.execute();
+ if (ret != 0 && failOnError) {
+ throw new BuildException("Javadoc returned " + ret,
+ getLocation());
+ }
+ if (out.sawWarnings() && failOnWarning) {
+ throw new BuildException("Javadoc issued warnings.",
+ getLocation());
+ }
+ postProcessGeneratedJavadocs();
+ } catch (final IOException e) {
+ throw new BuildException("Javadoc failed: " + e, e, getLocation());
+ } finally {
+ if (tmpList != null) {
+ tmpList.delete();
+ tmpList = null;
+ }
+
+ out.logFlush();
+ err.logFlush();
+ try {
+ out.close();
+ err.close();
+ } catch (final IOException e) {
+ // ignore
+ }
+ }
+ }
+
+ private void checkTaskName() {
+ if ("javadoc2".equals(getTaskType())) {
+ log("Warning: the task name <javadoc2> is deprecated."
+ + " Use <javadoc> instead.",
+ Project.MSG_WARN);
+ }
+ }
+
+ private void checkPackageAndSourcePath() {
+ if (packageList != null && sourcePath == null) {
+ final String msg = "sourcePath attribute must be set when "
+ + "specifying packagelist.";
+ throw new BuildException(msg);
+ }
+ }
+
+ private void checkPackages(final Vector<String> packagesToDoc, final Path sourceDirs) {
+ if (packagesToDoc.size() != 0 && sourceDirs.size() == 0) {
+ final String msg = "sourcePath attribute must be set when "
+ + "specifying package names.";
+ throw new BuildException(msg);
+ }
+ }
+
+ private void checkPackagesToDoc(
+ final Vector<String> packagesToDoc, final Vector<SourceFile> sourceFilesToDoc) {
+ if (packageList == null && packagesToDoc.size() == 0
+ && sourceFilesToDoc.size() == 0) {
+ throw new BuildException("No source files and no packages have "
+ + "been specified.");
+ }
+ }
+
+ private void doSourcePath(final Commandline toExecute, final Path sourceDirs) {
+ if (sourceDirs.size() > 0) {
+ toExecute.createArgument().setValue("-sourcepath");
+ toExecute.createArgument().setPath(sourceDirs);
+ }
+ }
+
+ private void generalJavadocArguments(final Commandline toExecute) {
+ if (doctitle != null) {
+ toExecute.createArgument().setValue("-doctitle");
+ toExecute.createArgument().setValue(expand(doctitle.getText()));
+ }
+ if (header != null) {
+ toExecute.createArgument().setValue("-header");
+ toExecute.createArgument().setValue(expand(header.getText()));
+ }
+ if (footer != null) {
+ toExecute.createArgument().setValue("-footer");
+ toExecute.createArgument().setValue(expand(footer.getText()));
+ }
+ if (bottom != null) {
+ toExecute.createArgument().setValue("-bottom");
+ toExecute.createArgument().setValue(expand(bottom.getText()));
+ }
+
+ if (classpath == null) {
+ classpath = (new Path(getProject())).concatSystemClasspath("last");
+ } else {
+ classpath = classpath.concatSystemClasspath("ignore");
+ }
+
+ if (classpath.size() > 0) {
+ toExecute.createArgument().setValue("-classpath");
+ toExecute.createArgument().setPath(classpath);
+ }
+
+ if (version && doclet == null) {
+ toExecute.createArgument().setValue("-version");
+ }
+ if (author && doclet == null) {
+ toExecute.createArgument().setValue("-author");
+ }
+
+ if (doclet == null && destDir == null) {
+ throw new BuildException("destdir attribute must be set!");
+ }
+ }
+
+ private void doDoclet(final Commandline toExecute) {
+ if (doclet != null) {
+ if (doclet.getName() == null) {
+ throw new BuildException("The doclet name must be "
+ + "specified.", getLocation());
+ } else {
+ toExecute.createArgument().setValue("-doclet");
+ toExecute.createArgument().setValue(doclet.getName());
+ if (doclet.getPath() != null) {
+ final Path docletPath
+ = doclet.getPath().concatSystemClasspath("ignore");
+ if (docletPath.size() != 0) {
+ toExecute.createArgument().setValue("-docletpath");
+ toExecute.createArgument().setPath(docletPath);
+ }
+ }
+ for (final Enumeration<DocletParam> e = doclet.getParams();
+ e.hasMoreElements();) {
+ final DocletParam param = e.nextElement();
+ if (param.getName() == null) {
+ throw new BuildException("Doclet parameters must "
+ + "have a name");
+ }
+
+ toExecute.createArgument().setValue(param.getName());
+ if (param.getValue() != null) {
+ toExecute.createArgument()
+ .setValue(param.getValue());
+ }
+ }
+ }
+ }
+ }
+
+ private void writeExternalArgs(final Commandline toExecute) {
+ // If using an external file, write the command line options to it
+ File optionsTmpFile = null;
+ BufferedWriter optionsListWriter = null;
+ try {
+ optionsTmpFile = FILE_UTILS.createTempFile(
+ "javadocOptions", "", null, true, true);
+ final String[] listOpt = toExecute.getArguments();
+ toExecute.clearArgs();
+ toExecute.createArgument().setValue(
+ "@" + optionsTmpFile.getAbsolutePath());
+ optionsListWriter = new BufferedWriter(
+ new FileWriter(optionsTmpFile.getAbsolutePath(), true));
+ for (int i = 0; i < listOpt.length; i++) {
+ final String string = listOpt[i];
+ if (string.startsWith("-J-")) {
+ toExecute.createArgument().setValue(string);
+ } else {
+ if (string.startsWith("-")) {
+ optionsListWriter.write(string);
+ optionsListWriter.write(" ");
+ } else {
+ optionsListWriter.write(quoteString(string));
+ optionsListWriter.newLine();
+ }
+ }
+ }
+ optionsListWriter.close();
+ } catch (final IOException ex) {
+ if (optionsTmpFile != null) {
+ optionsTmpFile.delete();
+ }
+ throw new BuildException(
+ "Error creating or writing temporary file for javadoc options",
+ ex, getLocation());
+ } finally {
+ FileUtils.close(optionsListWriter);
+ }
+ }
+
+ private void doBootPath(final Commandline toExecute) {
+ Path bcp = new Path(getProject());
+ if (bootclasspath != null) {
+ bcp.append(bootclasspath);
+ }
+ bcp = bcp.concatSystemBootClasspath("ignore");
+ if (bcp.size() > 0) {
+ toExecute.createArgument().setValue("-bootclasspath");
+ toExecute.createArgument().setPath(bcp);
+ }
+ }
+
+ private void doLinks(final Commandline toExecute) {
+ if (links.size() != 0) {
+ for (final Enumeration<LinkArgument> e = links.elements(); e.hasMoreElements();) {
+ final LinkArgument la = e.nextElement();
+
+ if (la.getHref() == null || la.getHref().length() == 0) {
+ log("No href was given for the link - skipping",
+ Project.MSG_VERBOSE);
+ continue;
+ }
+ String link = null;
+ if (la.shouldResolveLink()) {
+ final File hrefAsFile =
+ getProject().resolveFile(la.getHref());
+ if (hrefAsFile.exists()) {
+ try {
+ link = FILE_UTILS.getFileURL(hrefAsFile)
+ .toExternalForm();
+ } catch (final MalformedURLException ex) {
+ // should be impossible
+ log("Warning: link location was invalid "
+ + hrefAsFile, Project.MSG_WARN);
+ }
+ }
+ }
+ if (link == null) {
+ // is the href a valid URL
+ try {
+ final URL base = new URL("file://.");
+ new URL(base, la.getHref());
+ link = la.getHref();
+ } catch (final MalformedURLException mue) {
+ // ok - just skip
+ log("Link href \"" + la.getHref()
+ + "\" is not a valid url - skipping link",
+ Project.MSG_WARN);
+ continue;
+ }
+ }
+
+ if (la.isLinkOffline()) {
+ final File packageListLocation = la.getPackagelistLoc();
+ URL packageListURL = la.getPackagelistURL();
+ if (packageListLocation == null
+ && packageListURL == null) {
+ throw new BuildException("The package list"
+ + " location for link "
+ + la.getHref()
+ + " must be provided "
+ + "because the link is "
+ + "offline");
+ }
+ if (packageListLocation != null) {
+ final File packageListFile =
+ new File(packageListLocation, "package-list");
+ if (packageListFile.exists()) {
+ try {
+ packageListURL =
+ FILE_UTILS.getFileURL(packageListLocation);
+ } catch (final MalformedURLException ex) {
+ log("Warning: Package list location was "
+ + "invalid " + packageListLocation,
+ Project.MSG_WARN);
+ }
+ } else {
+ log("Warning: No package list was found at "
+ + packageListLocation, Project.MSG_VERBOSE);
+ }
+ }
+ if (packageListURL != null) {
+ toExecute.createArgument().setValue("-linkoffline");
+ toExecute.createArgument().setValue(link);
+ toExecute.createArgument()
+ .setValue(packageListURL.toExternalForm());
+ }
+ } else {
+ toExecute.createArgument().setValue("-link");
+ toExecute.createArgument().setValue(link);
+ }
+ }
+ }
+ }
+
+ private void doGroup(final Commandline toExecute) {
+ // add the single group arguments
+ // Javadoc 1.2 rules:
+ // Multiple -group args allowed.
+ // Each arg includes 3 strings: -group [name] [packagelist].
+ // Elements in [packagelist] are colon-delimited.
+ // An element in [packagelist] may end with the * wildcard.
+
+ // Ant javadoc task rules for group attribute:
+ // Args are comma-delimited.
+ // Each arg is 2 space-delimited strings.
+ // E.g., group="XSLT_Packages org.apache.xalan.xslt*,
+ // XPath_Packages org.apache.xalan.xpath*"
+ if (group != null) {
+ final StringTokenizer tok = new StringTokenizer(group, ",", false);
+ while (tok.hasMoreTokens()) {
+ final String grp = tok.nextToken().trim();
+ final int space = grp.indexOf(" ");
+ if (space > 0) {
+ final String name = grp.substring(0, space);
+ final String pkgList = grp.substring(space + 1);
+ toExecute.createArgument().setValue("-group");
+ toExecute.createArgument().setValue(name);
+ toExecute.createArgument().setValue(pkgList);
+ }
+ }
+ }
+ }
+
+ // add the group arguments
+ private void doGroups(final Commandline toExecute) {
+ if (groups.size() != 0) {
+ for (final Enumeration<GroupArgument> e = groups.elements(); e.hasMoreElements();) {
+ final GroupArgument ga = e.nextElement();
+ final String title = ga.getTitle();
+ final String packages = ga.getPackages();
+ if (title == null || packages == null) {
+ throw new BuildException("The title and packages must "
+ + "be specified for group "
+ + "elements.");
+ }
+ toExecute.createArgument().setValue("-group");
+ toExecute.createArgument().setValue(expand(title));
+ toExecute.createArgument().setValue(packages);
+ }
+ }
+ }
+
+ // Do java1.4 arguments
+ private void doJava14(final Commandline toExecute) {
+ for (final Enumeration<Object> e = tags.elements(); e.hasMoreElements();) {
+ final Object element = e.nextElement();
+ if (element instanceof TagArgument) {
+ final TagArgument ta = (TagArgument) element;
+ final File tagDir = ta.getDir(getProject());
+ if (tagDir == null) {
+ // The tag element is not used as a fileset,
+ // but specifies the tag directly.
+ toExecute.createArgument().setValue ("-tag");
+ toExecute.createArgument()
+ .setValue (ta.getParameter());
+ } else {
+ // The tag element is used as a
+ // fileset. Parse all the files and create
+ // -tag arguments.
+ final DirectoryScanner tagDefScanner =
+ ta.getDirectoryScanner(getProject());
+ final String[] files = tagDefScanner.getIncludedFiles();
+ for (int i = 0; i < files.length; i++) {
+ final File tagDefFile = new File(tagDir, files[i]);
+ try {
+ final BufferedReader in
+ = new BufferedReader(
+ new FileReader(tagDefFile)
+ );
+ String line = null;
+ while ((line = in.readLine()) != null) {
+ toExecute.createArgument()
+ .setValue("-tag");
+ toExecute.createArgument()
+ .setValue(line);
+ }
+ in.close();
+ } catch (final IOException ioe) {
+ throw new BuildException(
+ "Couldn't read "
+ + " tag file from "
+ + tagDefFile.getAbsolutePath(), ioe);
+ }
+ }
+ }
+ } else {
+ final ExtensionInfo tagletInfo = (ExtensionInfo) element;
+ toExecute.createArgument().setValue("-taglet");
+ toExecute.createArgument().setValue(tagletInfo
+ .getName());
+ if (tagletInfo.getPath() != null) {
+ final Path tagletPath = tagletInfo.getPath()
+ .concatSystemClasspath("ignore");
+ if (tagletPath.size() != 0) {
+ toExecute.createArgument()
+ .setValue("-tagletpath");
+ toExecute.createArgument().setPath(tagletPath);
+ }
+ }
+ }
+ }
+
+ final String sourceArg = source != null ? source
+ : getProject().getProperty(MagicNames.BUILD_JAVAC_SOURCE);
+ if (sourceArg != null) {
+ toExecute.createArgument().setValue("-source");
+ toExecute.createArgument().setValue(sourceArg);
+ }
+
+ if (linksource && doclet == null) {
+ toExecute.createArgument().setValue("-linksource");
+ }
+ if (noqualifier != null && doclet == null) {
+ toExecute.createArgument().setValue("-noqualifier");
+ toExecute.createArgument().setValue(noqualifier);
+ }
+ }
+
+ private void doDocFilesSubDirs(final Commandline toExecute) {
+ if (docFilesSubDirs) {
+ toExecute.createArgument().setValue("-docfilessubdirs");
+ if (excludeDocFilesSubDir != null
+ && excludeDocFilesSubDir.trim().length() > 0) {
+ toExecute.createArgument().setValue("-excludedocfilessubdir");
+ toExecute.createArgument().setValue(excludeDocFilesSubDir);
+ }
+ }
+ }
+
+ private void doSourceAndPackageNames(
+ final Commandline toExecute,
+ final Vector<String> packagesToDoc,
+ final Vector<SourceFile> sourceFilesToDoc,
+ final boolean useExternalFile,
+ final File tmpList,
+ final BufferedWriter srcListWriter)
+ throws IOException {
+ for (final String packageName : packagesToDoc) {
+ if (useExternalFile) {
+ srcListWriter.write(packageName);
+ srcListWriter.newLine();
+ } else {
+ toExecute.createArgument().setValue(packageName);
+ }
+ }
+
+ for (final SourceFile sf : sourceFilesToDoc) {
+ final String sourceFileName = sf.getFile().getAbsolutePath();
+ if (useExternalFile) {
+ // TODO what is the following doing?
+ // should it run if !javadoc4 && executable != null?
+ if (sourceFileName.indexOf(" ") > -1) {
+ String name = sourceFileName;
+ if (File.separatorChar == '\\') {
+ name = sourceFileName.replace(File.separatorChar, '/');
+ }
+ srcListWriter.write("\"" + name + "\"");
+ } else {
+ srcListWriter.write(sourceFileName);
+ }
+ srcListWriter.newLine();
+ } else {
+ toExecute.createArgument().setValue(sourceFileName);
+ }
+ }
+ }
+
+ /**
+ * Quote a string to place in a @ file.
+ * @param str the string to quote
+ * @return the quoted string, if there is no need to quote the string,
+ * return the original string.
+ */
+ private String quoteString(final String str) {
+ if (!containsWhitespace(str)
+ && str.indexOf('\'') == -1
+ && str.indexOf('"') == -1) {
+ return str;
+ }
+ if (str.indexOf('\'') == -1) {
+ return quoteString(str, '\'');
+ } else {
+ return quoteString(str, '"');
+ }
+ }
+
+ private boolean containsWhitespace(final String s) {
+ final int len = s.length();
+ for (int i = 0; i < len; i++) {
+ if (Character.isWhitespace(s.charAt(i))) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private String quoteString(final String str, final char delim) {
+ final StringBuffer buf = new StringBuffer(str.length() * 2);
+ buf.append(delim);
+ final int len = str.length();
+ boolean lastCharWasCR = false;
+ for (int i = 0; i < len; i++) {
+ final char c = str.charAt(i);
+ if (c == delim) { // can't put the non-constant delim into a case
+ buf.append('\\').append(c);
+ lastCharWasCR = false;
+ } else {
+ switch (c) {
+ case '\\':
+ buf.append("\\\\");
+ lastCharWasCR = false;
+ break;
+ case '\r':
+ // insert a line continuation marker
+ buf.append("\\\r");
+ lastCharWasCR = true;
+ break;
+ case '\n':
+ // insert a line continuation marker unless this
+ // is a \r\n sequence in which case \r already has
+ // created the marker
+ if (!lastCharWasCR) {
+ buf.append("\\\n");
+ } else {
+ buf.append("\n");
+ }
+ lastCharWasCR = false;
+ break;
+ default:
+ buf.append(c);
+ lastCharWasCR = false;
+ break;
+ }
+ }
+ }
+ buf.append(delim);
+ return buf.toString();
+ }
+
+ /**
+ * Add the files matched by the nested source files to the Vector
+ * as SourceFile instances.
+ *
+ * @since 1.7
+ */
+ private void addSourceFiles(final Vector<SourceFile> sf) {
+ final Iterator<ResourceCollection> e = nestedSourceFiles.iterator();
+ while (e.hasNext()) {
+ ResourceCollection rc = e.next();
+ if (!rc.isFilesystemOnly()) {
+ throw new BuildException("only file system based resources are"
+ + " supported by javadoc");
+ }
+ if (rc instanceof FileSet) {
+ final FileSet fs = (FileSet) rc;
+ if (!fs.hasPatterns() && !fs.hasSelectors()) {
+ final FileSet fs2 = (FileSet) fs.clone();
+ fs2.createInclude().setName("**/*.java");
+ if (includeNoSourcePackages) {
+ fs2.createInclude().setName("**/package.html");
+ }
+ rc = fs2;
+ }
+ }
+ for (final Resource r : rc) {
+ sf.addElement(new SourceFile(r.as(FileProvider.class).getFile()));
+ }
+ }
+ }
+
+ /**
+ * Add the directories matched by the nested dirsets to the Vector
+ * and the base directories of the dirsets to the Path. It also
+ * handles the packages and excludepackages attributes and
+ * elements.
+ *
+ * @since 1.5
+ */
+ private void parsePackages(final Vector<String> pn, final Path sp) {
+ final HashSet<String> addedPackages = new HashSet<String>();
+ @SuppressWarnings("unchecked")
+ final Vector<DirSet> dirSets = (Vector<DirSet>) packageSets.clone();
+
+ // for each sourcePath entry, add a directoryset with includes
+ // taken from packagenames attribute and nested package
+ // elements and excludes taken from excludepackages attribute
+ // and nested excludepackage elements
+ if (sourcePath != null) {
+ final PatternSet ps = new PatternSet();
+ ps.setProject(getProject());
+ if (packageNames.size() > 0) {
+ final Enumeration<PackageName> e = packageNames.elements();
+ while (e.hasMoreElements()) {
+ final PackageName p = e.nextElement();
+ String pkg = p.getName().replace('.', '/');
+ if (pkg.endsWith("*")) {
+ pkg += "*";
+ }
+ ps.createInclude().setName(pkg);
+ }
+ } else {
+ ps.createInclude().setName("**");
+ }
+
+ final Enumeration<PackageName> e = excludePackageNames.elements();
+ while (e.hasMoreElements()) {
+ final PackageName p = e.nextElement();
+ String pkg = p.getName().replace('.', '/');
+ if (pkg.endsWith("*")) {
+ pkg += "*";
+ }
+ ps.createExclude().setName(pkg);
+ }
+
+
+ final String[] pathElements = sourcePath.list();
+ for (int i = 0; i < pathElements.length; i++) {
+ final File dir = new File(pathElements[i]);
+ if (dir.isDirectory()) {
+ final DirSet ds = new DirSet();
+ ds.setProject(getProject());
+ ds.setDefaultexcludes(useDefaultExcludes);
+ ds.setDir(dir);
+ ds.createPatternSet().addConfiguredPatternset(ps);
+ dirSets.addElement(ds);
+ } else {
+ log("Skipping " + pathElements[i]
+ + " since it is no directory.", Project.MSG_WARN);
+ }
+ }
+ }
+
+ final Enumeration<DirSet> e = dirSets.elements();
+ while (e.hasMoreElements()) {
+ final DirSet ds = e.nextElement();
+ final File baseDir = ds.getDir(getProject());
+ log("scanning " + baseDir + " for packages.", Project.MSG_DEBUG);
+ final DirectoryScanner dsc = ds.getDirectoryScanner(getProject());
+ final String[] dirs = dsc.getIncludedDirectories();
+ boolean containsPackages = false;
+ for (int i = 0; i < dirs.length; i++) {
+ // are there any java files in this directory?
+ final File pd = new File(baseDir, dirs[i]);
+ final String[] files = pd.list(new FilenameFilter () {
+ public boolean accept(final File dir1, final String name) {
+ return name.endsWith(".java")
+ || (includeNoSourcePackages
+ && name.equals("package.html"));
+ }
+ });
+
+ if (files.length > 0) {
+ if ("".equals(dirs[i])) {
+ log(baseDir
+ + " contains source files in the default package,"
+ + " you must specify them as source files"
+ + " not packages.",
+ Project.MSG_WARN);
+ } else {
+ containsPackages = true;
+ final String packageName =
+ dirs[i].replace(File.separatorChar, '.');
+ if (!addedPackages.contains(packageName)) {
+ addedPackages.add(packageName);
+ pn.addElement(packageName);
+ }
+ }
+ }
+ }
+ if (containsPackages) {
+ // We don't need to care for duplicates here,
+ // Path.list does it for us.
+ sp.createPathElement().setLocation(baseDir);
+ } else {
+ log(baseDir + " doesn\'t contain any packages, dropping it.",
+ Project.MSG_VERBOSE);
+ }
+ }
+ }
+
+ private void postProcessGeneratedJavadocs() throws IOException {
+ if (!postProcessGeneratedJavadocs) {
+ return;
+ }
+ if (destDir != null && !destDir.isDirectory()) {
+ log("No javadoc created, no need to post-process anything",
+ Project.MSG_VERBOSE);
+ return;
+ }
+ final String fixData;
+ final InputStream in = Javadoc.class
+ .getResourceAsStream("javadoc-frame-injections-fix.txt");
+ if (in == null) {
+ throw new FileNotFoundException("Missing resource "
+ + "'javadoc-frame-injections-fix.txt' in "
+ + "classpath.");
+ }
+ try {
+ fixData =
+ fixLineFeeds(FileUtils
+ .readFully(new InputStreamReader(in, "US-ASCII")))
+ .trim();
+ } finally {
+ FileUtils.close(in);
+ }
+
+ final DirectoryScanner ds = new DirectoryScanner();
+ ds.setBasedir(destDir);
+ ds.setCaseSensitive(false);
+ ds.setIncludes(new String[] {
+ "**/index.html", "**/index.htm", "**/toc.html", "**/toc.htm"
+ });
+ ds.addDefaultExcludes();
+ ds.scan();
+ int patched = 0;
+ for (final String f : ds.getIncludedFiles()) {
+ patched += postProcess(new File(destDir, f), fixData);
+ }
+ if (patched > 0) {
+ log("Patched " + patched + " link injection vulnerable javadocs",
+ Project.MSG_INFO);
+ }
+ }
+
+ private int postProcess(final File file, final String fixData) throws IOException {
+ final String enc = docEncoding != null ? docEncoding
+ : FILE_UTILS.getDefaultEncoding();
+ // we load the whole file as one String (toc/index files are
+ // generally small, because they only contain frameset declaration):
+ final InputStream fin = new FileInputStream(file);
+ String fileContents;
+ try {
+ fileContents =
+ fixLineFeeds(FileUtils
+ .safeReadFully(new InputStreamReader(fin, enc)));
+ } finally {
+ FileUtils.close(fin);
+ }
+
+ // check if file may be vulnerable because it was not
+ // patched with "validURL(url)":
+ if (fileContents.indexOf("function validURL(url) {") < 0) {
+ // we need to patch the file!
+ final String patchedFileContents = patchContent(fileContents, fixData);
+ if (!patchedFileContents.equals(fileContents)) {
+ final FileOutputStream fos = new FileOutputStream(file);
+ try {
+ final OutputStreamWriter w = new OutputStreamWriter(fos, enc);
+ w.write(patchedFileContents);
+ w.close();
+ return 1;
+ } finally {
+ FileUtils.close(fos);
+ }
+ }
+ }
+ return 0;
+ }
+
+ private String fixLineFeeds(final String orig) {
+ return orig.replace("\r\n", "\n")
+ .replace("\n", StringUtils.LINE_SEP);
+ }
+
+ private String patchContent(final String fileContents, final String fixData) {
+ // using regexes here looks like overkill
+ final int start = fileContents.indexOf(LOAD_FRAME);
+ if (start >= 0) {
+ return fileContents.substring(0, start) + fixData
+ + fileContents.substring(start + LOAD_FRAME_LEN);
+ }
+ return fileContents;
+ }
+
+ private class JavadocOutputStream extends LogOutputStream {
+ JavadocOutputStream(final int level) {
+ super(Javadoc.this, level);
+ }
+
+ //
+ // Override the logging of output in order to filter out Generating
+ // messages. Generating messages are set to a priority of VERBOSE
+ // unless they appear after what could be an informational message.
+ //
+ private String queuedLine = null;
+ private boolean sawWarnings = false;
+
+ @Override
+ protected void processLine(final String line, final int messageLevel) {
+ if (line.contains("warning")) {
+ sawWarnings = true;
+ }
+ if (messageLevel == Project.MSG_INFO
+ && line.startsWith("Generating ")) {
+ if (queuedLine != null) {
+ super.processLine(queuedLine, Project.MSG_VERBOSE);
+ }
+ queuedLine = line;
+ } else {
+ if (queuedLine != null) {
+ if (line.startsWith("Building ")) {
+ super.processLine(queuedLine, Project.MSG_VERBOSE);
+ } else {
+ super.processLine(queuedLine, Project.MSG_INFO);
+ }
+ queuedLine = null;
+ }
+ super.processLine(line, messageLevel);
+ }
+ }
+
+
+ protected void logFlush() {
+ if (queuedLine != null) {
+ super.processLine(queuedLine, Project.MSG_VERBOSE);
+ queuedLine = null;
+ }
+ }
+
+ public boolean sawWarnings() {
+ return sawWarnings;
+ }
+ }
+
+ /**
+ * Convenience method to expand properties.
+ * @param content the string to expand
+ * @return the converted string
+ */
+ protected String expand(final String content) {
+ return getProject().replaceProperties(content);
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Jikes.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Jikes.java
new file mode 100644
index 00000000..4bc6835b
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Jikes.java
@@ -0,0 +1,132 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.Locale;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.util.FileUtils;
+
+/**
+ * Encapsulates a Jikes compiler, by directly executing an external
+ * process.
+ *
+ * <p><strong>As of Ant 1.2, this class is considered to be dead code
+ * by the Ant developers and is unmaintained. Don't use
+ * it.</strong></p>
+ *
+ * @deprecated since 1.2.
+ * Merged into the class Javac.
+ */
+public class Jikes {
+ // There have been reports that 300 files could be compiled
+ // on a command line so 250 is a conservative approach
+ private static final int MAX_FILES_ON_COMMAND_LINE = 250;
+ // CheckStyle:VisibilityModifier OFF - bc
+ protected JikesOutputParser jop;
+ protected String command;
+ protected Project project;
+ // CheckStyle:VisibilityModifier ON
+
+ /**
+ * Constructs a new Jikes object.
+ * @param jop Parser to send jike's output to
+ * @param command name of jikes executable
+ * @param project the current project
+ */
+ protected Jikes(JikesOutputParser jop, String command, Project project) {
+ super();
+
+ System.err.println("As of Ant 1.2 released in October 2000, "
+ + "the Jikes class");
+ System.err.println("is considered to be dead code by the Ant "
+ + "developers and is unmaintained.");
+ System.err.println("Don\'t use it!");
+
+ this.jop = jop;
+ this.command = command;
+ this.project = project;
+ }
+
+ /**
+ * Do the compile with the specified arguments.
+ * @param args - arguments to pass to process on command line
+ */
+ protected void compile(String[] args) {
+ String[] commandArray = null;
+ File tmpFile = null;
+
+ try {
+ String myos = System.getProperty("os.name");
+
+ // Windows has a 32k limit on total arg size, so
+ // create a temporary file to store all the arguments
+
+ if (myos.toLowerCase(Locale.ENGLISH).indexOf("windows") >= 0
+ && args.length > MAX_FILES_ON_COMMAND_LINE) {
+ BufferedWriter out = null;
+ try {
+ tmpFile = FileUtils.getFileUtils().createTempFile("jikes",
+ "tmp", null, false, true);
+ out = new BufferedWriter(new FileWriter(tmpFile));
+ for (int i = 0; i < args.length; i++) {
+ out.write(args[i]);
+ out.newLine();
+ }
+ out.flush();
+ commandArray = new String[] {command,
+ "@" + tmpFile.getAbsolutePath()};
+ } catch (IOException e) {
+ throw new BuildException("Error creating temporary file",
+ e);
+ } finally {
+ FileUtils.close(out);
+ }
+ } else {
+ commandArray = new String[args.length + 1];
+ commandArray[0] = command;
+ System.arraycopy(args, 0, commandArray, 1, args.length);
+ }
+
+ // We assume, that everything jikes writes goes to
+ // standard output, not to standard error. The option
+ // -Xstdout that is given to Jikes in Javac.doJikesCompile()
+ // should guarantee this. At least I hope so. :)
+ try {
+ Execute exe = new Execute(jop);
+ exe.setAntRun(project);
+ exe.setWorkingDirectory(project.getBaseDir());
+ exe.setCommandline(commandArray);
+ exe.execute();
+ } catch (IOException e) {
+ throw new BuildException("Error running Jikes compiler", e);
+ }
+ } finally {
+ if (tmpFile != null) {
+ if (!tmpFile.delete()) {
+ tmpFile.deleteOnExit();
+ }
+ }
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/JikesOutputParser.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/JikesOutputParser.java
new file mode 100644
index 00000000..18bce30c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/JikesOutputParser.java
@@ -0,0 +1,183 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+
+/**
+ * Parses output from jikes and
+ * passes errors and warnings
+ * into the right logging channels of Project.
+ *
+ * <p><strong>As of Ant 1.2, this class is considered to be dead code
+ * by the Ant developers and is unmaintained. Don't use
+ * it.</strong></p>
+ *
+ * @deprecated since 1.2.
+ * Use Jikes' exit value to detect compilation failure.
+ */
+public class JikesOutputParser implements ExecuteStreamHandler {
+ // CheckStyle:VisibilityModifier OFF - bc
+ protected Task task;
+ protected boolean errorFlag = false; // no errors so far
+ protected int errors;
+ protected int warnings;
+ protected boolean error = false;
+ protected boolean emacsMode;
+
+ protected BufferedReader br;
+ // CheckStyle:VisibilityModifier ON
+
+ /**
+ * Ignore.
+ * @param os ignored
+ */
+ public void setProcessInputStream(OutputStream os) {
+ }
+
+ /**
+ * Ignore.
+ * @param is ignored
+ */
+ public void setProcessErrorStream(InputStream is) {
+ }
+
+ /**
+ * Set the inputstream
+ * @param is the input stream
+ * @throws IOException on error
+ */
+ public void setProcessOutputStream(InputStream is) throws IOException {
+ br = new BufferedReader(new InputStreamReader(is));
+ }
+
+ /**
+ * Invokes parseOutput.
+ * @throws IOException on error
+ */
+ public void start() throws IOException {
+ parseOutput(br);
+ }
+
+ /**
+ * Ignore.
+ */
+ public void stop() {
+ }
+
+ /**
+ * Construct a new Parser object
+ * @param task task in which context we are called
+ * @param emacsMode if true output in emacs mode
+ */
+ protected JikesOutputParser(Task task, boolean emacsMode) {
+ super();
+
+ System.err.println("As of Ant 1.2 released in October 2000, the "
+ + "JikesOutputParser class");
+ System.err.println("is considered to be dead code by the Ant "
+ + "developers and is unmaintained.");
+ System.err.println("Don\'t use it!");
+
+ this.task = task;
+ this.emacsMode = emacsMode;
+ }
+
+ /**
+ * Parse the output of a jikes compiler
+ * @param reader - Reader used to read jikes's output
+ * @throws IOException on error
+ */
+ protected void parseOutput(BufferedReader reader) throws IOException {
+ if (emacsMode) {
+ parseEmacsOutput(reader);
+ } else {
+ parseStandardOutput(reader);
+ }
+ }
+
+ private void parseStandardOutput(BufferedReader reader) throws IOException {
+ String line;
+ String lower;
+ // We assume, that every output, jikes does, stands for an error/warning
+ // TODO
+ // Is this correct?
+
+ // TODO:
+ // A warning line, that shows code, which contains a variable
+ // error will cause some trouble. The parser should definitely
+ // be much better.
+
+ while ((line = reader.readLine()) != null) {
+ lower = line.toLowerCase();
+ if (line.trim().equals("")) {
+ continue;
+ }
+ if (lower.indexOf("error") != -1) {
+ setError(true);
+ } else if (lower.indexOf("warning") != -1) {
+ setError(false);
+ } else {
+ // If we don't know the type of the line
+ // and we are in emacs mode, it will be
+ // an error, because in this mode, jikes won't
+ // always print "error", but sometimes other
+ // keywords like "Syntax". We should look for
+ // all those keywords.
+ if (emacsMode) {
+ setError(true);
+ }
+ }
+ log(line);
+ }
+ }
+
+ private void parseEmacsOutput(BufferedReader reader) throws IOException {
+ // This may change, if we add advanced parsing capabilities.
+ parseStandardOutput(reader);
+ }
+
+ private void setError(boolean err) {
+ error = err;
+ if (error) {
+ errorFlag = true;
+ }
+ }
+
+ private void log(String line) {
+ if (!emacsMode) {
+ task.log("", (error ? Project.MSG_ERR : Project.MSG_WARN));
+ }
+ task.log(line, (error ? Project.MSG_ERR : Project.MSG_WARN));
+ }
+
+ /**
+ * Indicate if there were errors during the compile
+ * @return if errors occurred
+ */
+ protected boolean getErrorFlag() {
+ return errorFlag;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/KeySubst.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/KeySubst.java
new file mode 100644
index 00000000..6ff67c04
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/KeySubst.java
@@ -0,0 +1,191 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.Hashtable;
+import java.util.StringTokenizer;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.util.FileUtils;
+
+/**
+ * Keyword substitution. Input file is written to output file.
+ * Do not make input file same as output file.
+ * Keywords in input files look like this: @foo@. See the docs for the
+ * setKeys method to understand how to do the substitutions.
+ *
+ * @since Ant 1.1
+ * @deprecated KeySubst is deprecated since Ant 1.1. Use Filter + Copy
+ * instead.
+ */
+public class KeySubst extends Task {
+ private File source = null;
+ private File dest = null;
+ private String sep = "*";
+ private Hashtable<String, String> replacements = new Hashtable<String, String>();
+
+ /**
+ * Do the execution.
+ * @throws BuildException on error
+ */
+ public void execute() throws BuildException {
+ log("!! KeySubst is deprecated. Use Filter + Copy instead. !!");
+ log("Performing Substitutions");
+ if (source == null || dest == null) {
+ log("Source and destinations must not be null");
+ return;
+ }
+ BufferedReader br = null;
+ BufferedWriter bw = null;
+ try {
+ br = new BufferedReader(new FileReader(source));
+ dest.delete();
+ bw = new BufferedWriter(new FileWriter(dest));
+
+ String line = null;
+ String newline = null;
+ line = br.readLine();
+ while (line != null) {
+ if (line.length() == 0) {
+ bw.newLine();
+ } else {
+ newline = KeySubst.replace(line, replacements);
+ bw.write(newline);
+ bw.newLine();
+ }
+ line = br.readLine();
+ }
+ bw.flush();
+ } catch (IOException ioe) {
+ ioe.printStackTrace();
+ } finally {
+ FileUtils.close(bw);
+ FileUtils.close(br);
+ }
+ }
+
+ /**
+ * Set the source file.
+ * @param s the source file
+ */
+ public void setSrc(File s) {
+ this.source = s;
+ }
+
+ /**
+ * Set the destination file.
+ * @param dest the destination file
+ */
+ public void setDest(File dest) {
+ this.dest = dest;
+ }
+
+ /**
+ * Sets the separator between name=value arguments
+ * in setKeys(). By default it is "*".
+ * @param sep the separator string
+ */
+ public void setSep(String sep) {
+ this.sep = sep;
+ }
+ /**
+ * Sets the keys.
+ *
+ * Format string is like this:
+ * <p>
+ * name=value*name2=value
+ * <p>
+ * Names are case sensitive.
+ * <p>
+ * Use the setSep() method to change the * to something else
+ * if you need to use * as a name or value.
+ * @param keys a <code>String</code> value
+ */
+ public void setKeys(String keys) {
+ if (keys != null && keys.length() > 0) {
+ StringTokenizer tok =
+ new StringTokenizer(keys, this.sep, false);
+ while (tok.hasMoreTokens()) {
+ String token = tok.nextToken().trim();
+ StringTokenizer itok =
+ new StringTokenizer(token, "=", false);
+
+ String name = itok.nextToken();
+ String value = itok.nextToken();
+ replacements.put(name, value);
+ }
+ }
+ }
+
+
+ /**
+ * A test method.
+ * @param args not used
+ */
+ public static void main(String[] args) {
+ try {
+ Hashtable<String, String> hash = new Hashtable<String, String>();
+ hash.put("VERSION", "1.0.3");
+ hash.put("b", "ffff");
+ System.out.println(KeySubst.replace("$f ${VERSION} f ${b} jj $",
+ hash));
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * Does replacement on text using the hashtable of keys.
+ * @param origString an input string
+ * @param keys mapping of keys to values
+ * @return the string with the replacements in it.
+ * @throws BuildException on error
+ */
+ public static String replace(String origString, Hashtable<String, String> keys)
+ throws BuildException {
+ StringBuffer finalString = new StringBuffer();
+ int index = 0;
+ int i = 0;
+ String key = null;
+ // CheckStyle:MagicNumber OFF
+ while ((index = origString.indexOf("${", i)) > -1) {
+ key = origString.substring(index + 2, origString.indexOf("}",
+ index + 3));
+ finalString.append (origString.substring(i, index));
+ if (keys.containsKey(key)) {
+ finalString.append (keys.get(key));
+ } else {
+ finalString.append ("${");
+ finalString.append (key);
+ finalString.append ("}");
+ }
+ i = index + 3 + key.length();
+ }
+ // CheckStyle:MagicNumber ON
+ finalString.append (origString.substring(i));
+ return finalString.toString();
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Length.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Length.java
new file mode 100644
index 00000000..bd4da442
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Length.java
@@ -0,0 +1,335 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.io.File;
+import java.io.OutputStream;
+import java.io.PrintStream;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.taskdefs.condition.Condition;
+import org.apache.tools.ant.types.Comparison;
+import org.apache.tools.ant.types.EnumeratedAttribute;
+import org.apache.tools.ant.types.FileSet;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.ResourceCollection;
+import org.apache.tools.ant.types.resources.FileResource;
+import org.apache.tools.ant.types.resources.Resources;
+import org.apache.tools.ant.util.FileUtils;
+import org.apache.tools.ant.util.PropertyOutputStream;
+
+/**
+ * Gets lengths: of files/resources, byte size; of strings, length (optionally trimmed).
+ * The task is overloaded in this way for semantic reasons, much like Available.
+ * @since Ant 1.6.3
+ */
+public class Length extends Task implements Condition {
+
+ private static final String ALL = "all";
+ private static final String EACH = "each";
+ private static final String STRING = "string";
+
+ private static final String LENGTH_REQUIRED
+ = "Use of the Length condition requires that the length attribute be set.";
+
+ private String property;
+ private String string;
+ private Boolean trim;
+ private String mode = ALL;
+ private Comparison when = Comparison.EQUAL;
+ private Long length;
+ private Resources resources;
+
+ /**
+ * The property in which the length will be stored.
+ * @param property the <code>String</code> property key.
+ */
+ public synchronized void setProperty(String property) {
+ this.property = property;
+ }
+
+ /**
+ * Set the single resource for this task.
+ * @param resource the Resource whose length to retrieve.
+ */
+ public synchronized void setResource(Resource resource) {
+ add(resource);
+ }
+
+ /**
+ * Set the single file for this task.
+ * @param file the <code>File</code> whose length to retrieve.
+ */
+ public synchronized void setFile(File file) {
+ add(new FileResource(file));
+ }
+
+ /**
+ * Add a FileSet.
+ * @param fs the <code>FileSet</code> to add.
+ */
+ public synchronized void add(FileSet fs) {
+ add((ResourceCollection) fs);
+ }
+
+ /**
+ * Add a ResourceCollection.
+ * @param c the <code>ResourceCollection</code> to add.
+ * @since Ant 1.7
+ */
+ public synchronized void add(ResourceCollection c) {
+ if (c == null) {
+ return;
+ }
+ resources = (resources == null) ? new Resources() : resources;
+ resources.add(c);
+ }
+
+ /**
+ * Set the target count number for use as a Condition.
+ * @param ell the long length to compare with.
+ */
+ public synchronized void setLength(long ell) {
+ length = new Long(ell);
+ }
+
+ /**
+ * Set the comparison for use as a Condition.
+ * @param w EnumeratedAttribute When.
+ * @see org.apache.tools.ant.types.Comparison
+ */
+ public synchronized void setWhen(When w) {
+ setWhen((Comparison) w);
+ }
+
+ /**
+ * Set the comparison for use as a Condition.
+ * @param c Comparison.
+ * @see org.apache.tools.ant.types.Comparison
+ * @since Ant 1.7
+ */
+ public synchronized void setWhen(Comparison c) {
+ when = c;
+ }
+
+ /**
+ * Set the execution mode for working with files.
+ * @param m the <code>FileMode</code> to use.
+ */
+ public synchronized void setMode(FileMode m) {
+ this.mode = m.getValue();
+ }
+
+ /**
+ * Set the string whose length to get.
+ * @param string <code>String</code>.
+ */
+ public synchronized void setString(String string) {
+ this.string = string;
+ this.mode = STRING;
+ }
+
+ /**
+ * Set whether to trim in string mode. Default false.
+ * @param trim <code>boolean</code>.
+ */
+ public synchronized void setTrim(boolean trim) {
+ this.trim = trim ? Boolean.TRUE : Boolean.FALSE;
+ }
+
+ /**
+ * Learn whether strings will be trimmed. Default false.
+ * @return boolean trim setting.
+ */
+ public boolean getTrim() {
+ return trim != null && trim.booleanValue();
+ }
+
+ /**
+ * Execute the length task.
+ */
+ public void execute() {
+ validate();
+ PrintStream ps = new PrintStream((property != null)
+ ? (OutputStream) new PropertyOutputStream(getProject(), property)
+ : (OutputStream) new LogOutputStream(this, Project.MSG_INFO));
+
+ if (STRING.equals(mode)) {
+ ps.print(getLength(string, getTrim()));
+ ps.close();
+ } else if (EACH.equals(mode)) {
+ handleResources(new EachHandler(ps));
+ } else if (ALL.equals(mode)) {
+ handleResources(new AllHandler(ps));
+ }
+ }
+
+ /**
+ * Fulfill the condition contract.
+ * @return true if the condition is true.
+ * @throws BuildException if an error occurs.
+ */
+ public boolean eval() {
+ validate();
+ if (length == null) {
+ throw new BuildException(LENGTH_REQUIRED);
+ }
+ Long ell;
+ if (STRING.equals(mode)) {
+ ell = new Long(getLength(string, getTrim()));
+ } else {
+ AccumHandler h = new AccumHandler();
+ handleResources(h);
+ ell = new Long(h.getAccum());
+ }
+ return when.evaluate(ell.compareTo(length));
+ }
+
+ private void validate() {
+ if (string != null) {
+ if (resources != null) {
+ throw new BuildException("the string length function"
+ + " is incompatible with the file/resource length function");
+ }
+ if (!(STRING.equals(mode))) {
+ throw new BuildException("the mode attribute is for use"
+ + " with the file/resource length function");
+ }
+ } else if (resources != null) {
+ if (!(EACH.equals(mode) || ALL.equals(mode))) {
+ throw new BuildException("invalid mode setting for"
+ + " file/resource length function: \"" + mode + "\"");
+ } else if (trim != null) {
+ throw new BuildException("the trim attribute is"
+ + " for use with the string length function only");
+ }
+ } else {
+ throw new BuildException("you must set either the string attribute"
+ + " or specify one or more files using the file attribute or"
+ + " nested resource collections");
+ }
+ }
+
+ private void handleResources(Handler h) {
+ for (Resource r : resources) {
+ if (!r.isExists()) {
+ log(r + " does not exist", Project.MSG_WARN);
+ }
+ if (r.isDirectory()) {
+ log(r + " is a directory; length may not be meaningful", Project.MSG_WARN);
+ }
+ h.handle(r);
+ }
+ h.complete();
+ }
+
+ private static long getLength(String s, boolean t) {
+ return (t ? s.trim() : s).length();
+ }
+
+ /** EnumeratedAttribute operation mode */
+ public static class FileMode extends EnumeratedAttribute {
+ static final String[] MODES = new String[] {EACH, ALL};
+
+ /**
+ * Return the possible values for FileMode.
+ * @return <code>String[]</code>.
+ */
+ public String[] getValues() {
+ return MODES;
+ }
+
+ }
+
+ /**
+ * EnumeratedAttribute for the when attribute.
+ */
+ public static class When extends Comparison {
+ //extend Comparison; retain for BC only
+ }
+
+ private abstract class Handler {
+ private PrintStream ps;
+ Handler(PrintStream ps) {
+ this.ps = ps;
+ }
+
+ protected PrintStream getPs() {
+ return ps;
+ }
+
+ protected abstract void handle(Resource r);
+
+ void complete() {
+ FileUtils.close(ps);
+ }
+ }
+
+ private class EachHandler extends Handler {
+ EachHandler(PrintStream ps) {
+ super(ps);
+ }
+ protected void handle(Resource r) {
+ getPs().print(r.toString());
+ getPs().print(" : ");
+ //when writing to the log, we'll see what's happening:
+ long size = r.getSize();
+ if (size == Resource.UNKNOWN_SIZE) {
+ getPs().println("unknown");
+ } else {
+ getPs().println(size);
+ }
+ }
+ }
+
+ private class AccumHandler extends Handler {
+ private long accum = 0L;
+
+ AccumHandler() {
+ super(null);
+ }
+ protected AccumHandler(PrintStream ps) {
+ super(ps);
+ }
+ protected long getAccum() {
+ return accum;
+ }
+ protected synchronized void handle(Resource r) {
+ long size = r.getSize();
+ if (size == Resource.UNKNOWN_SIZE) {
+ log("Size unknown for " + r.toString(), Project.MSG_WARN);
+ } else {
+ accum += size;
+ }
+ }
+ }
+
+ private class AllHandler extends AccumHandler {
+ AllHandler(PrintStream ps) {
+ super(ps);
+ }
+ void complete() {
+ getPs().print(getAccum());
+ super.complete();
+ }
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/LoadFile.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/LoadFile.java
new file mode 100644
index 00000000..c450a0e8
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/LoadFile.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs;
+
+import java.io.File;
+
+import org.apache.tools.ant.types.resources.FileResource;
+
+
+/**
+ * Load a file into a property
+ *
+ * @since Ant 1.5
+ * @ant.task category="utility"
+ */
+public class LoadFile extends LoadResource {
+
+ /**
+ * Sets the file to load.
+ *
+ * @param srcFile The new SrcFile value
+ */
+ public final void setSrcFile(final File srcFile) {
+ addConfigured(new FileResource(srcFile));
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/LoadProperties.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/LoadProperties.java
new file mode 100644
index 00000000..4c20c7c9
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/LoadProperties.java
@@ -0,0 +1,248 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs;
+
+import java.io.BufferedInputStream;
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.util.Properties;
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.filters.util.ChainReaderHelper;
+import org.apache.tools.ant.types.FilterChain;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.types.Reference;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.ResourceCollection;
+import org.apache.tools.ant.types.resources.FileResource;
+import org.apache.tools.ant.types.resources.JavaResource;
+import org.apache.tools.ant.util.FileUtils;
+import org.apache.tools.ant.util.ResourceUtils;
+
+/**
+ * Load a file's contents as Ant properties.
+ *
+ * @since Ant 1.5
+ * @ant.task category="utility"
+ */
+public class LoadProperties extends Task {
+
+ /**
+ * Source resource.
+ */
+ private Resource src = null;
+
+ /**
+ * Holds filterchains
+ */
+ private final Vector<FilterChain> filterChains = new Vector<FilterChain>();
+
+ /**
+ * Encoding to use for input; defaults to the platform's default encoding.
+ */
+ private String encoding = null;
+
+ /**
+ * Prefix for loaded properties.
+ */
+ private String prefix = null;
+ private boolean prefixValues = true;
+
+ /**
+ * Set the file to load.
+ *
+ * @param srcFile The new SrcFile value
+ */
+ public final void setSrcFile(final File srcFile) {
+ addConfigured(new FileResource(srcFile));
+ }
+
+ /**
+ * Set the resource name of a property file to load.
+ *
+ * @param resource resource on classpath
+ */
+ public void setResource(String resource) {
+ getRequiredJavaResource().setName(resource);
+ }
+
+ /**
+ * Encoding to use for input, defaults to the platform's default
+ * encoding. <p>
+ *
+ * For a list of possible values see
+ * <a href="http://java.sun.com/j2se/1.5.0/docs/guide/intl/encoding.doc.html">
+ * http://java.sun.com/j2se/1.5.0/docs/guide/intl/encoding.doc.html
+ * </a>.</p>
+ *
+ * @param encoding The new Encoding value
+ */
+ public final void setEncoding(final String encoding) {
+ this.encoding = encoding;
+ }
+
+ /**
+ * Set the classpath to use when looking up a resource.
+ * @param classpath to add to any existing classpath
+ */
+ public void setClasspath(Path classpath) {
+ getRequiredJavaResource().setClasspath(classpath);
+ }
+
+ /**
+ * Add a classpath to use when looking up a resource.
+ * @return The classpath to be configured
+ */
+ public Path createClasspath() {
+ return getRequiredJavaResource().createClasspath();
+ }
+
+ /**
+ * Set the classpath to use when looking up a resource,
+ * given as reference to a &lt;path&gt; defined elsewhere
+ * @param r The reference value
+ */
+ public void setClasspathRef(Reference r) {
+ getRequiredJavaResource().setClasspathRef(r);
+ }
+
+ /**
+ * get the classpath used by this <code>LoadProperties</code>.
+ * @return The classpath
+ */
+ public Path getClasspath() {
+ return getRequiredJavaResource().getClasspath();
+ }
+
+ /**
+ * Set the prefix to load these properties under.
+ * @param prefix to set
+ */
+ public void setPrefix(String prefix) {
+ this.prefix = prefix;
+ }
+
+ /**
+ * Whether to apply the prefix when expanding properties on the
+ * right hand side of a properties file as well.
+ *
+ * @since Ant 1.8.2
+ */
+ public void setPrefixValues(boolean b) {
+ prefixValues = b;
+ }
+
+ /**
+ * load Ant properties from the source file or resource
+ *
+ * @exception BuildException if something goes wrong with the build
+ */
+ public final void execute() throws BuildException {
+ //validation
+ if (src == null) {
+ throw new BuildException("A source resource is required.");
+ }
+ if (!src.isExists()) {
+ if (src instanceof JavaResource) {
+ // dreaded backwards compatibility
+ log("Unable to find resource " + src, Project.MSG_WARN);
+ return;
+ }
+ throw new BuildException("Source resource does not exist: " + src);
+ }
+ BufferedInputStream bis = null;
+ Reader instream = null;
+ ByteArrayInputStream tis = null;
+
+ try {
+ bis = new BufferedInputStream(src.getInputStream());
+ if (encoding == null) {
+ instream = new InputStreamReader(bis);
+ } else {
+ instream = new InputStreamReader(bis, encoding);
+ }
+ ChainReaderHelper crh = new ChainReaderHelper();
+ crh.setPrimaryReader(instream);
+ crh.setFilterChains(filterChains);
+ crh.setProject(getProject());
+ instream = crh.getAssembledReader();
+
+ String text = crh.readFully(instream);
+
+ if (text != null && text.length() != 0) {
+ if (!text.endsWith("\n")) {
+ text = text + "\n";
+ }
+ tis = new ByteArrayInputStream(text.getBytes(ResourceUtils.ISO_8859_1));
+ final Properties props = new Properties();
+ props.load(tis);
+
+ Property propertyTask = new Property();
+ propertyTask.bindToOwner(this);
+ propertyTask.setPrefix(prefix);
+ propertyTask.setPrefixValues(prefixValues);
+ propertyTask.addProperties(props);
+ }
+ } catch (final IOException ioe) {
+ throw new BuildException("Unable to load file: " + ioe, ioe, getLocation());
+ } finally {
+ FileUtils.close(bis);
+ FileUtils.close(tis);
+ }
+ }
+
+ /**
+ * Adds a FilterChain.
+ * @param filter the filter to add
+ */
+ public final void addFilterChain(FilterChain filter) {
+ filterChains.addElement(filter);
+ }
+
+ /**
+ * Set the source resource.
+ * @param a the resource to load as a single element Resource collection.
+ * @since Ant 1.7
+ */
+ public synchronized void addConfigured(ResourceCollection a) {
+ if (src != null) {
+ throw new BuildException("only a single source is supported");
+ }
+ if (a.size() != 1) {
+ throw new BuildException(
+ "only single-element resource collections are supported");
+ }
+ src = a.iterator().next();
+ }
+
+ private synchronized JavaResource getRequiredJavaResource() {
+ if (src == null) {
+ src = new JavaResource();
+ src.setProject(getProject());
+ } else if (!(src instanceof JavaResource)) {
+ throw new BuildException("expected a java resource as source");
+ }
+ return (JavaResource) src;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/LoadResource.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/LoadResource.java
new file mode 100644
index 00000000..f68b5ba4
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/LoadResource.java
@@ -0,0 +1,236 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs;
+
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.filters.util.ChainReaderHelper;
+import org.apache.tools.ant.types.FilterChain;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.ResourceCollection;
+import org.apache.tools.ant.util.FileUtils;
+
+/**
+ * Load a resource into a property
+ *
+ * @since Ant 1.7
+ * @ant.task category="utility"
+ */
+public class LoadResource extends Task {
+
+ /**
+ * The resource to load.
+ */
+ private Resource src;
+
+ /**
+ * what to do when it goes pear-shaped
+ */
+ private boolean failOnError = true;
+
+ /**
+ * suppress error message if it goes pear-shaped, sets failOnError=false
+ */
+ private boolean quiet = false;
+
+ /**
+ * Encoding to use for filenames, defaults to the platform's default
+ * encoding.
+ */
+ private String encoding = null;
+
+ /**
+ * name of property
+ */
+ private String property = null;
+
+ /**
+ * Holds FilterChains
+ */
+ private final Vector<FilterChain> filterChains = new Vector<FilterChain>();
+
+ /**
+ * Encoding to use for input, defaults to the platform's default
+ * encoding. <p>
+ *
+ * For a list of possible values see
+ * <a href="http://java.sun.com/j2se/1.5.0/docs/guide/intl/encoding.doc.html">
+ * http://java.sun.com/j2se/1.5.0/docs/guide/intl/encoding.doc.html
+ * </a>.</p>
+ *
+ * @param encoding The new Encoding value
+ */
+
+ public final void setEncoding(final String encoding) {
+ this.encoding = encoding;
+ }
+
+
+ /**
+ * Property name to save to.
+ *
+ * @param property The new Property value
+ */
+ public final void setProperty(final String property) {
+ this.property = property;
+ }
+
+ /**
+ * If true, fail on load error.
+ *
+ * @param fail The new Failonerror value
+ */
+ public final void setFailonerror(final boolean fail) {
+ failOnError = fail;
+ }
+
+ /**
+ * If true, suppress the load error report and set the
+ * the failonerror value to false.
+ * @param quiet The new Quiet value
+ */
+ public void setQuiet(final boolean quiet) {
+ this.quiet = quiet;
+ if (quiet) {
+ this.failOnError = false;
+ }
+ }
+
+ /**
+ * read in a source file to a property
+ *
+ * @exception BuildException if something goes wrong with the build
+ */
+ public final void execute()
+ throws BuildException {
+ //validation
+ if (src == null) {
+ throw new BuildException("source resource not defined");
+ }
+ if (property == null) {
+ throw new BuildException("output property not defined");
+ }
+ if (quiet && failOnError) {
+ throw new BuildException("quiet and failonerror cannot both be "
+ + "set to true");
+ }
+ if (!src.isExists()) {
+ String message = src + " doesn't exist";
+ if (failOnError) {
+ throw new BuildException(message);
+ } else {
+ log(message, quiet ? Project.MSG_WARN : Project.MSG_ERR);
+ return;
+ }
+ }
+ InputStream is = null;
+ BufferedInputStream bis = null;
+ Reader instream = null;
+ log("loading " + src + " into property " + property,
+ Project.MSG_VERBOSE);
+ try {
+ final long len = src.getSize();
+ log("resource size = "
+ + (len != Resource.UNKNOWN_SIZE ? String.valueOf(len)
+ : "unknown"), Project.MSG_DEBUG);
+ //discard most of really big resources
+ final int size = (int) len;
+ //open up the resource
+ is = src.getInputStream();
+ bis = new BufferedInputStream(is);
+ if (encoding == null) {
+ instream = new InputStreamReader(bis);
+ } else {
+ instream = new InputStreamReader(bis, encoding);
+ }
+
+ String text = "";
+ if (size != 0) {
+ ChainReaderHelper crh = new ChainReaderHelper();
+ if (len != Resource.UNKNOWN_SIZE) {
+ crh.setBufferSize(size);
+ }
+ crh.setPrimaryReader(instream);
+ crh.setFilterChains(filterChains);
+ crh.setProject(getProject());
+ instream = crh.getAssembledReader();
+
+ text = crh.readFully(instream);
+ } else {
+ log("Do not set property " + property + " as its length is 0.",
+ quiet ? Project.MSG_VERBOSE : Project.MSG_INFO);
+ }
+
+ if (text != null) {
+ if (text.length() > 0) {
+ getProject().setNewProperty(property, text);
+ log("loaded " + text.length() + " characters",
+ Project.MSG_VERBOSE);
+ log(property + " := " + text, Project.MSG_DEBUG);
+ }
+ }
+
+ } catch (final IOException ioe) {
+ final String message = "Unable to load resource: "
+ + ioe.toString();
+ if (failOnError) {
+ throw new BuildException(message, ioe, getLocation());
+ } else {
+ log(message, quiet ? Project.MSG_VERBOSE : Project.MSG_ERR);
+ }
+ } catch (final BuildException be) {
+ if (failOnError) {
+ throw be;
+ } else {
+ log(be.getMessage(),
+ quiet ? Project.MSG_VERBOSE : Project.MSG_ERR);
+ }
+ } finally {
+ FileUtils.close(is);
+ }
+ }
+
+ /**
+ * Add the FilterChain element.
+ * @param filter the filter to add
+ */
+ public final void addFilterChain(FilterChain filter) {
+ filterChains.addElement(filter);
+ }
+
+ /**
+ * Set the source resource.
+ * @param a the resource to load as a single element Resource collection.
+ */
+ public void addConfigured(ResourceCollection a) {
+ if (a.size() != 1) {
+ throw new BuildException("only single argument resource collections"
+ + " are supported");
+ }
+ src = a.iterator().next();
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Local.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Local.java
new file mode 100644
index 00000000..3fdf9b59
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Local.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.property.LocalProperties;
+
+/**
+ * Task to create a local property in the current scope.
+ */
+public class Local extends Task {
+ private String name;
+
+ /**
+ * Set the name attribute.
+ * @param name the name of the local property.
+ */
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ /**
+ * Run the task.
+ */
+ public void execute() {
+ if (name == null) {
+ throw new BuildException("Missing attribute name");
+ }
+ LocalProperties.get(getProject()).addLocal(name);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/LogOutputStream.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/LogOutputStream.java
new file mode 100644
index 00000000..b2c34684
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/LogOutputStream.java
@@ -0,0 +1,111 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.io.IOException;
+
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.ProjectComponent;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.util.LineOrientedOutputStream;
+
+/**
+ * Logs each line written to this stream to the log system of ant.
+ *
+ * Tries to be smart about line separators.<br>
+ *
+ * @since Ant 1.2
+ */
+public class LogOutputStream extends LineOrientedOutputStream {
+
+ private ProjectComponent pc;
+ private int level = Project.MSG_INFO;
+
+ /**
+ * Create a new LogOutputStream for the specified ProjectComponent.
+ *
+ * @param pc the project component for whom to log
+ * @since Ant 1.7.1
+ */
+ public LogOutputStream(ProjectComponent pc) {
+ this.pc = pc;
+ }
+
+ /**
+ * Creates a new instance of this class.
+ *
+ * @param task the task for whom to log
+ * @param level loglevel used to log data written to this stream.
+ */
+ public LogOutputStream(Task task, int level) {
+ this((ProjectComponent) task, level);
+ }
+
+ /**
+ * Creates a new instance of this class.
+ *
+ * @param pc the project component for whom to log
+ * @param level loglevel used to log data written to this stream.
+ * @since Ant 1.6.3
+ */
+ public LogOutputStream(ProjectComponent pc, int level) {
+ this(pc);
+ this.level = level;
+ }
+
+ /**
+ * Converts the buffer to a string and sends it to <code>processLine</code>
+ */
+ protected void processBuffer() {
+ try {
+ super.processBuffer();
+ } catch (IOException e) {
+ // impossible since *our* processLine doesn't throw an IOException
+ throw new RuntimeException("Impossible IOException caught: " + e);
+ }
+ }
+
+ /**
+ * Logs a line to the log system of ant.
+ *
+ * @param line the line to log.
+ */
+ protected void processLine(String line) {
+ processLine(line, level);
+ }
+
+ /**
+ * Logs a line to the log system of ant.
+ *
+ * @param line the line to log.
+ * @param level the logging level to use.
+ */
+ protected void processLine(String line, int level) {
+ pc.log(line, level);
+ }
+
+ /**
+ * Get the level.
+ * @return the log level.
+ */
+ public int getMessageLevel() {
+ return level;
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/LogStreamHandler.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/LogStreamHandler.java
new file mode 100644
index 00000000..ed16cf36
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/LogStreamHandler.java
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.io.IOException;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.ProjectComponent;
+import org.apache.tools.ant.Task;
+
+/**
+ * Logs standard output and error of a subprocess to the log system of ant.
+ *
+ * @since Ant 1.2
+ */
+public class LogStreamHandler extends PumpStreamHandler {
+
+ /**
+ * Creates log stream handler
+ *
+ * @param task the task for whom to log
+ * @param outlevel the loglevel used to log standard output
+ * @param errlevel the loglevel used to log standard error
+ */
+ public LogStreamHandler(Task task, int outlevel, int errlevel) {
+ this((ProjectComponent) task, outlevel, errlevel);
+ }
+
+ /**
+ * Creates log stream handler
+ *
+ * @param pc the project component for whom to log
+ * @param outlevel the loglevel used to log standard output
+ * @param errlevel the loglevel used to log standard error
+ */
+ public LogStreamHandler(ProjectComponent pc, int outlevel, int errlevel) {
+ super(new LogOutputStream(pc, outlevel),
+ new LogOutputStream(pc, errlevel));
+ }
+
+ /**
+ * Stop the log stream handler.
+ */
+ public void stop() {
+ super.stop();
+ try {
+ getErr().close();
+ getOut().close();
+ } catch (IOException e) {
+ // plain impossible
+ throw new BuildException(e);
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/MacroDef.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/MacroDef.java
new file mode 100644
index 00000000..63f68c5a
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/MacroDef.java
@@ -0,0 +1,851 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+import org.apache.tools.ant.AntTypeDefinition;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.ComponentHelper;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.ProjectHelper;
+import org.apache.tools.ant.RuntimeConfigurable;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.TaskContainer;
+import org.apache.tools.ant.UnknownElement;
+
+/**
+ * Describe class <code>MacroDef</code> here.
+ *
+ * @since Ant 1.6
+ */
+public class MacroDef extends AntlibDefinition {
+
+ private NestedSequential nestedSequential;
+ private String name;
+ private boolean backTrace = true;
+ private List<Attribute> attributes = new ArrayList<Attribute>();
+ private Map<String, TemplateElement> elements = new HashMap<String, TemplateElement>();
+ private String textName = null;
+ private Text text = null;
+ private boolean hasImplicitElement = false;
+
+ /**
+ * Name of the definition
+ * @param name the name of the definition
+ */
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ /**
+ * Add the text element.
+ * @param text the nested text element to add
+ * @since ant 1.6.1
+ */
+ public void addConfiguredText(Text text) {
+ if (this.text != null) {
+ throw new BuildException(
+ "Only one nested text element allowed");
+ }
+ if (text.getName() == null) {
+ throw new BuildException(
+ "the text nested element needed a \"name\" attribute");
+ }
+ // Check if used by attributes
+ for (Attribute attribute : attributes) {
+ if (text.getName().equals(attribute.getName())) {
+ throw new BuildException(
+ "the name \"" + text.getName()
+ + "\" is already used as an attribute");
+ }
+ }
+ this.text = text;
+ this.textName = text.getName();
+ }
+
+ /**
+ * @return the nested text element
+ * @since ant 1.6.1
+ */
+ public Text getText() {
+ return text;
+ }
+
+ /**
+ * Set the backTrace attribute.
+ *
+ * @param backTrace if true and the macro instance generates
+ * an error, a backtrace of the location within
+ * the macro and call to the macro will be output.
+ * if false, only the location of the call to the
+ * macro will be shown. Default is true.
+ * @since ant 1.7
+ */
+ public void setBackTrace(boolean backTrace) {
+ this.backTrace = backTrace;
+ }
+
+ /**
+ * @return the backTrace attribute.
+ * @since ant 1.7
+ */
+ public boolean getBackTrace() {
+ return backTrace;
+ }
+
+ /**
+ * This is the sequential nested element of the macrodef.
+ *
+ * @return a sequential element to be configured.
+ */
+ public NestedSequential createSequential() {
+ if (this.nestedSequential != null) {
+ throw new BuildException("Only one sequential allowed");
+ }
+ this.nestedSequential = new NestedSequential();
+ return this.nestedSequential;
+ }
+
+ /**
+ * The class corresponding to the sequential nested element.
+ * This is a simple task container.
+ */
+ public static class NestedSequential implements TaskContainer {
+ private List<Task> nested = new ArrayList<Task>();
+
+ /**
+ * Add a task or type to the container.
+ *
+ * @param task an unknown element.
+ */
+ public void addTask(Task task) {
+ nested.add(task);
+ }
+
+ /**
+ * @return the list of unknown elements
+ */
+ public List<Task> getNested() {
+ return nested;
+ }
+
+ /**
+ * A compare function to compare this with another
+ * NestedSequential.
+ * It calls similar on the nested unknown elements.
+ *
+ * @param other the nested sequential to compare with.
+ * @return true if they are similar, false otherwise
+ */
+ public boolean similar(NestedSequential other) {
+ final int size = nested.size();
+ if (size != other.nested.size()) {
+ return false;
+ }
+ for (int i = 0; i < size; ++i) {
+ UnknownElement me = (UnknownElement) nested.get(i);
+ UnknownElement o = (UnknownElement) other.nested.get(i);
+ if (!me.similar(o)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ }
+
+ /**
+ * Convert the nested sequential to an unknown element
+ * @return the nested sequential as an unknown element.
+ */
+ public UnknownElement getNestedTask() {
+ UnknownElement ret = new UnknownElement("sequential");
+ ret.setTaskName("sequential");
+ ret.setNamespace("");
+ ret.setQName("sequential");
+ new RuntimeConfigurable(ret, "sequential");
+ final int size = nestedSequential.getNested().size();
+ for (int i = 0; i < size; ++i) {
+ UnknownElement e =
+ (UnknownElement) nestedSequential.getNested().get(i);
+ ret.addChild(e);
+ ret.getWrapper().addChild(e.getWrapper());
+ }
+ return ret;
+ }
+
+ /**
+ * Gets this macro's attribute (and define?) list.
+ *
+ * @return the nested Attributes
+ */
+ public List<Attribute> getAttributes() {
+ return attributes;
+ }
+
+ /**
+ * Gets this macro's elements.
+ *
+ * @return the map nested elements, keyed by element name, with
+ * {@link TemplateElement} values.
+ */
+ public Map<String, TemplateElement> getElements() {
+ return elements;
+ }
+
+ /**
+ * Check if a character is a valid character for an element or
+ * attribute name.
+ *
+ * @param c the character to check
+ * @return true if the character is a letter or digit or '.' or '-'
+ * attribute name
+ */
+ public static boolean isValidNameCharacter(char c) {
+ // ? is there an xml api for this ?
+ return Character.isLetterOrDigit(c) || c == '.' || c == '-';
+ }
+
+ /**
+ * Check if a string is a valid name for an element or attribute.
+ *
+ * @param name the string to check
+ * @return true if the name consists of valid name characters
+ */
+ private static boolean isValidName(String name) {
+ if (name.length() == 0) {
+ return false;
+ }
+ for (int i = 0; i < name.length(); ++i) {
+ if (!isValidNameCharacter(name.charAt(i))) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Add an attribute element.
+ *
+ * @param attribute an attribute nested element.
+ */
+ public void addConfiguredAttribute(Attribute attribute) {
+ if (attribute.getName() == null) {
+ throw new BuildException(
+ "the attribute nested element needed a \"name\" attribute");
+ }
+ if (attribute.getName().equals(textName)) {
+ throw new BuildException(
+ "the name \"" + attribute.getName()
+ + "\" has already been used by the text element");
+ }
+ final int size = attributes.size();
+ for (int i = 0; i < size; ++i) {
+ Attribute att = (Attribute) attributes.get(i);
+ if (att.getName().equals(attribute.getName())) {
+ throw new BuildException(
+ "the name \"" + attribute.getName()
+ + "\" has already been used in "
+ + "another attribute element");
+ }
+ }
+ attributes.add(attribute);
+ }
+
+ /**
+ * Add an element element.
+ *
+ * @param element an element nested element.
+ */
+ public void addConfiguredElement(TemplateElement element) {
+ if (element.getName() == null) {
+ throw new BuildException(
+ "the element nested element needed a \"name\" attribute");
+ }
+ if (elements.get(element.getName()) != null) {
+ throw new BuildException(
+ "the element " + element.getName()
+ + " has already been specified");
+ }
+ if (hasImplicitElement
+ || (element.isImplicit() && elements.size() != 0)) {
+ throw new BuildException(
+ "Only one element allowed when using implicit elements");
+ }
+ hasImplicitElement = element.isImplicit();
+ elements.put(element.getName(), element);
+ }
+
+ /**
+ * Create a new ant type based on the embedded tasks and types.
+ */
+ public void execute() {
+ if (nestedSequential == null) {
+ throw new BuildException("Missing sequential element");
+ }
+ if (name == null) {
+ throw new BuildException("Name not specified");
+ }
+
+ name = ProjectHelper.genComponentName(getURI(), name);
+
+ MyAntTypeDefinition def = new MyAntTypeDefinition(this);
+ def.setName(name);
+ def.setClass(MacroInstance.class);
+
+ ComponentHelper helper = ComponentHelper.getComponentHelper(
+ getProject());
+
+ helper.addDataTypeDefinition(def);
+ log("creating macro " + name, Project.MSG_VERBOSE);
+ }
+
+
+ /**
+ * An attribute for the MacroDef task.
+ *
+ */
+ public static class Attribute {
+ private String name;
+ private String defaultValue;
+ private String description;
+ private boolean doubleExpanding = true;
+
+ /**
+ * The name of the attribute.
+ *
+ * @param name the name of the attribute
+ */
+ public void setName(String name) {
+ if (!isValidName(name)) {
+ throw new BuildException(
+ "Illegal name [" + name + "] for attribute");
+ }
+ this.name = name.toLowerCase(Locale.ENGLISH);
+ }
+
+ /**
+ * @return the name of the attribute
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * The default value to use if the parameter is not
+ * used in the templated instance.
+ *
+ * @param defaultValue the default value
+ */
+ public void setDefault(String defaultValue) {
+ this.defaultValue = defaultValue;
+ }
+
+ /**
+ * @return the default value, null if not set
+ */
+ public String getDefault() {
+ return defaultValue;
+ }
+
+ /**
+ * @param desc Description of the element.
+ * @since ant 1.6.1
+ */
+ public void setDescription(String desc) {
+ description = desc;
+ }
+
+ /**
+ * @return the description of the element, or <code>null</code> if
+ * no description is available.
+ * @since ant 1.6.1
+ */
+ public String getDescription() {
+ return description;
+ }
+
+ /**
+ * See {@link #isDoubleExpanding} for explanation.
+ * @param doubleExpanding true to expand twice, false for just once
+ * @since Ant 1.8.3
+ */
+ public void setDoubleExpanding(boolean doubleExpanding) {
+ this.doubleExpanding = doubleExpanding;
+ }
+
+ /**
+ * Determines whether {@link RuntimeConfigurable#maybeConfigure(Project, boolean)} will reevaluate this property.
+ * For compatibility reasons (#52621) it will, though for most applications (#42046) it should not.
+ * @return true if expanding twice (the default), false for just once
+ * @since Ant 1.8.3
+ */
+ public boolean isDoubleExpanding() {
+ return doubleExpanding;
+ }
+
+ /**
+ * equality method
+ *
+ * @param obj an <code>Object</code> value
+ * @return a <code>boolean</code> value
+ */
+ public boolean equals(Object obj) {
+ if (obj == null) {
+ return false;
+ }
+ if (obj.getClass() != getClass()) {
+ return false;
+ }
+ Attribute other = (Attribute) obj;
+ if (name == null) {
+ if (other.name != null) {
+ return false;
+ }
+ } else if (!name.equals(other.name)) {
+ return false;
+ }
+ if (defaultValue == null) {
+ if (other.defaultValue != null) {
+ return false;
+ }
+ } else if (!defaultValue.equals(other.defaultValue)) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * @return a hash code value for this object.
+ */
+ public int hashCode() {
+ return objectHashCode(defaultValue) + objectHashCode(name);
+ }
+ }
+
+ /**
+ * A nested text element for the MacroDef task.
+ * @since ant 1.6.1
+ */
+ public static class Text {
+ private String name;
+ private boolean optional;
+ private boolean trim;
+ private String description;
+ private String defaultString;
+
+ /**
+ * The name of the attribute.
+ *
+ * @param name the name of the attribute
+ */
+ public void setName(String name) {
+ if (!isValidName(name)) {
+ throw new BuildException(
+ "Illegal name [" + name + "] for attribute");
+ }
+ this.name = name.toLowerCase(Locale.ENGLISH);
+ }
+
+ /**
+ * @return the name of the attribute
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * The optional attribute of the text element.
+ *
+ * @param optional if true this is optional
+ */
+ public void setOptional(boolean optional) {
+ this.optional = optional;
+ }
+
+ /**
+ * @return true if the text is optional
+ */
+ public boolean getOptional() {
+ return optional;
+ }
+
+ /**
+ * The trim attribute of the text element.
+ *
+ * @param trim if true this String.trim() is called on
+ * the contents of the text element.
+ */
+ public void setTrim(boolean trim) {
+ this.trim = trim;
+ }
+
+ /**
+ * @return true if the text is trim
+ */
+ public boolean getTrim() {
+ return trim;
+ }
+
+ /**
+ * @param desc Description of the text.
+ */
+ public void setDescription(String desc) {
+ description = desc;
+ }
+
+ /**
+ * @return the description of the text, or <code>null</code> if
+ * no description is available.
+ */
+ public String getDescription() {
+ return description;
+ }
+
+ /**
+ * @param defaultString default text for the string.
+ */
+ public void setDefault(String defaultString) {
+ this.defaultString = defaultString;
+ }
+
+ /**
+ * @return the default text if set, null otherwise.
+ */
+ public String getDefault() {
+ return defaultString;
+ }
+
+ /**
+ * equality method
+ *
+ * @param obj an <code>Object</code> value
+ * @return a <code>boolean</code> value
+ */
+ public boolean equals(Object obj) {
+ if (obj == null) {
+ return false;
+ }
+ if (obj.getClass() != getClass()) {
+ return false;
+ }
+ Text other = (Text) obj;
+ return safeCompare(name, other.name)
+ && optional == other.optional
+ && trim == other.trim
+ && safeCompare(defaultString, other.defaultString);
+ }
+
+ /**
+ * @return a hash code value for this object.
+ */
+ public int hashCode() {
+ return objectHashCode(name);
+ }
+ }
+
+ private static boolean safeCompare(Object a, Object b) {
+ return a == null ? b == null : a.equals(b);
+ }
+
+ /**
+ * A nested element for the MacroDef task.
+ */
+ public static class TemplateElement {
+
+ private String name;
+ private String description;
+ private boolean optional = false;
+ private boolean implicit = false;
+
+ /**
+ * Sets the name of this element.
+ *
+ * @param name the name of the element
+ */
+ public void setName(String name) {
+ if (!isValidName(name)) {
+ throw new BuildException(
+ "Illegal name [" + name + "] for macro element");
+ }
+ this.name = name.toLowerCase(Locale.ENGLISH);
+ }
+
+ /**
+ * Gets the name of this element.
+ *
+ * @return the name of the element.
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Sets a textual description of this element,
+ * for build documentation purposes only.
+ *
+ * @param desc Description of the element.
+ * @since ant 1.6.1
+ */
+ public void setDescription(String desc) {
+ description = desc;
+ }
+
+ /**
+ * Gets the description of this element.
+ *
+ * @return the description of the element, or <code>null</code> if
+ * no description is available.
+ * @since ant 1.6.1
+ */
+ public String getDescription() {
+ return description;
+ }
+
+ /**
+ * Sets whether this element is optional.
+ *
+ * @param optional if true this element may be left out, default
+ * is false.
+ */
+ public void setOptional(boolean optional) {
+ this.optional = optional;
+ }
+
+ /**
+ * Gets whether this element is optional.
+ *
+ * @return the optional attribute
+ */
+ public boolean isOptional() {
+ return optional;
+ }
+
+ /**
+ * Sets whether this element is implicit.
+ *
+ * @param implicit if true this element may be left out, default
+ * is false.
+ */
+ public void setImplicit(boolean implicit) {
+ this.implicit = implicit;
+ }
+
+ /**
+ * Gets whether this element is implicit.
+ *
+ * @return the implicit attribute
+ */
+ public boolean isImplicit() {
+ return implicit;
+ }
+
+ /**
+ * equality method.
+ *
+ * @param obj an <code>Object</code> value
+ * @return a <code>boolean</code> value
+ */
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ }
+ if (obj == null || !obj.getClass().equals(getClass())) {
+ return false;
+ }
+ TemplateElement t = (TemplateElement) obj;
+ return
+ (name == null ? t.name == null : name.equals(t.name))
+ && optional == t.optional
+ && implicit == t.implicit;
+ }
+
+ /**
+ * @return a hash code value for this object.
+ */
+ public int hashCode() {
+ return objectHashCode(name)
+ + (optional ? 1 : 0) + (implicit ? 1 : 0);
+ }
+
+ } // END static class TemplateElement
+
+ /**
+ * same or similar equality method for macrodef, ignores project and
+ * runtime info.
+ *
+ * @param obj an <code>Object</code> value
+ * @param same if true test for sameness, otherwise just similar
+ * @return a <code>boolean</code> value
+ */
+ private boolean sameOrSimilar(Object obj, boolean same) {
+ if (obj == this) {
+ return true;
+ }
+
+ if (obj == null) {
+ return false;
+ }
+ if (!obj.getClass().equals(getClass())) {
+ return false;
+ }
+ MacroDef other = (MacroDef) obj;
+ if (name == null) {
+ return other.name == null;
+ }
+ if (!name.equals(other.name)) {
+ return false;
+ }
+ // Allow two macro definitions with the same location
+ // to be treated as similar - bugzilla 31215
+ if (other.getLocation() != null
+ && other.getLocation().equals(getLocation())
+ && !same) {
+ return true;
+ }
+ if (text == null) {
+ if (other.text != null) {
+ return false;
+ }
+ } else {
+ if (!text.equals(other.text)) {
+ return false;
+ }
+ }
+ if (getURI() == null || getURI().equals("")
+ || getURI().equals(ProjectHelper.ANT_CORE_URI)) {
+ if (!(other.getURI() == null || other.getURI().equals("")
+ || other.getURI().equals(ProjectHelper.ANT_CORE_URI))) {
+ return false;
+ }
+ } else {
+ if (!getURI().equals(other.getURI())) {
+ return false;
+ }
+ }
+
+ if (!nestedSequential.similar(other.nestedSequential)) {
+ return false;
+ }
+ if (!attributes.equals(other.attributes)) {
+ return false;
+ }
+ if (!elements.equals(other.elements)) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Similar method for this definition
+ *
+ * @param obj another definition
+ * @return true if the definitions are similar
+ */
+ public boolean similar(Object obj) {
+ return sameOrSimilar(obj, false);
+ }
+
+ /**
+ * Equality method for this definition
+ *
+ * @param obj another definition
+ * @return true if the definitions are the same
+ */
+ public boolean sameDefinition(Object obj) {
+ return sameOrSimilar(obj, true);
+ }
+
+ /**
+ * extends AntTypeDefinition, on create
+ * of the object, the template macro definition
+ * is given.
+ */
+ private static class MyAntTypeDefinition extends AntTypeDefinition {
+ private MacroDef macroDef;
+
+ /**
+ * Creates a new <code>MyAntTypeDefinition</code> instance.
+ *
+ * @param macroDef a <code>MacroDef</code> value
+ */
+ public MyAntTypeDefinition(MacroDef macroDef) {
+ this.macroDef = macroDef;
+ }
+
+ /**
+ * Create an instance of the definition.
+ * The instance may be wrapped in a proxy class.
+ * @param project the current project
+ * @return the created object
+ */
+ public Object create(Project project) {
+ Object o = super.create(project);
+ if (o == null) {
+ return null;
+ }
+ ((MacroInstance) o).setMacroDef(macroDef);
+ return o;
+ }
+
+ /**
+ * Equality method for this definition
+ *
+ * @param other another definition
+ * @param project the current project
+ * @return true if the definitions are the same
+ */
+ public boolean sameDefinition(AntTypeDefinition other, Project project) {
+ if (!super.sameDefinition(other, project)) {
+ return false;
+ }
+ MyAntTypeDefinition otherDef = (MyAntTypeDefinition) other;
+ return macroDef.sameDefinition(otherDef.macroDef);
+ }
+
+ /**
+ * Similar method for this definition
+ *
+ * @param other another definition
+ * @param project the current project
+ * @return true if the definitions are the same
+ */
+ public boolean similarDefinition(
+ AntTypeDefinition other, Project project) {
+ if (!super.similarDefinition(other, project)) {
+ return false;
+ }
+ MyAntTypeDefinition otherDef = (MyAntTypeDefinition) other;
+ return macroDef.similar(otherDef.macroDef);
+ }
+ }
+
+ private static int objectHashCode(Object o) {
+ if (o == null) {
+ return 0;
+ } else {
+ return o.hashCode();
+ }
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/MacroInstance.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/MacroInstance.java
new file mode 100644
index 00000000..32b1a1a2
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/MacroInstance.java
@@ -0,0 +1,411 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.DynamicAttribute;
+import org.apache.tools.ant.ProjectHelper;
+import org.apache.tools.ant.RuntimeConfigurable;
+import org.apache.tools.ant.Target;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.TaskContainer;
+import org.apache.tools.ant.UnknownElement;
+import org.apache.tools.ant.property.LocalProperties;
+import org.apache.tools.ant.taskdefs.MacroDef.Attribute;
+
+/**
+ * The class to be placed in the ant type definition.
+ * It is given a pointer to the template definition,
+ * and makes a copy of the unknown element, substituting
+ * the parameter values in attributes and text.
+ * @since Ant 1.6
+ */
+public class MacroInstance extends Task implements DynamicAttribute, TaskContainer {
+ private MacroDef macroDef;
+ private Map<String, String> map = new HashMap<String, String>();
+ private Map<String, MacroDef.TemplateElement> nsElements = null;
+ private Map<String, UnknownElement> presentElements;
+ private Hashtable<String, String> localAttributes;
+ private String text = null;
+ private String implicitTag = null;
+ private List<Task> unknownElements = new ArrayList<Task>();
+
+ /**
+ * Called from MacroDef.MyAntTypeDefinition#create()
+ *
+ * @param macroDef a <code>MacroDef</code> value
+ */
+ public void setMacroDef(MacroDef macroDef) {
+ this.macroDef = macroDef;
+ }
+
+ /**
+ * @return the macro definition object for this macro instance.
+ */
+ public MacroDef getMacroDef() {
+ return macroDef;
+ }
+
+ /**
+ * A parameter name value pair as a xml attribute.
+ *
+ * @param name the name of the attribute
+ * @param value the value of the attribute
+ */
+ public void setDynamicAttribute(String name, String value) {
+ map.put(name, value);
+ }
+
+ /**
+ * Method present for BC purposes.
+ * @param name not used
+ * @return nothing
+ * @deprecated since 1.6.x.
+ * @throws BuildException always
+ */
+ public Object createDynamicElement(String name) throws BuildException {
+ throw new BuildException("Not implemented any more");
+ }
+
+ private Map<String, MacroDef.TemplateElement> getNsElements() {
+ if (nsElements == null) {
+ nsElements = new HashMap<String, MacroDef.TemplateElement>();
+ for (Entry<String, MacroDef.TemplateElement> entry : macroDef.getElements().entrySet()) {
+ nsElements.put((String) entry.getKey(),
+ entry.getValue());
+ MacroDef.TemplateElement te = (MacroDef.TemplateElement)
+ entry.getValue();
+ if (te.isImplicit()) {
+ implicitTag = te.getName();
+ }
+ }
+ }
+ return nsElements;
+ }
+
+ /**
+ * Add a unknownElement for the macro instances nested elements.
+ *
+ * @param nestedTask a nested element.
+ */
+ public void addTask(Task nestedTask) {
+ unknownElements.add(nestedTask);
+ }
+
+ private void processTasks() {
+ if (implicitTag != null) {
+ return;
+ }
+ for (Iterator<Task> i = unknownElements.iterator(); i.hasNext();) {
+ UnknownElement ue = (UnknownElement) i.next();
+ String name = ProjectHelper.extractNameFromComponentName(
+ ue.getTag()).toLowerCase(Locale.ENGLISH);
+ if (getNsElements().get(name) == null) {
+ throw new BuildException("unsupported element " + name);
+ }
+ if (presentElements.get(name) != null) {
+ throw new BuildException("Element " + name + " already present");
+ }
+ presentElements.put(name, ue);
+ }
+ }
+
+ /**
+ * Embedded element in macro instance
+ */
+ public static class Element implements TaskContainer {
+ private List<Task> unknownElements = new ArrayList<Task>();
+
+ /**
+ * Add an unknown element (to be snipped into the macroDef instance)
+ *
+ * @param nestedTask an unknown element
+ */
+ public void addTask(Task nestedTask) {
+ unknownElements.add(nestedTask);
+ }
+
+ /**
+ * @return the list of unknown elements
+ */
+ public List<Task> getUnknownElements() {
+ return unknownElements;
+ }
+ }
+
+ private static final int STATE_NORMAL = 0;
+ private static final int STATE_EXPECT_BRACKET = 1;
+ private static final int STATE_EXPECT_NAME = 2;
+
+ private String macroSubs(String s, Map<String, String> macroMapping) {
+ if (s == null) {
+ return null;
+ }
+ StringBuffer ret = new StringBuffer();
+ StringBuffer macroName = null;
+
+ int state = STATE_NORMAL;
+ for (int i = 0; i < s.length(); ++i) {
+ char ch = s.charAt(i);
+ switch (state) {
+ case STATE_NORMAL:
+ if (ch == '@') {
+ state = STATE_EXPECT_BRACKET;
+ } else {
+ ret.append(ch);
+ }
+ break;
+ case STATE_EXPECT_BRACKET:
+ if (ch == '{') {
+ state = STATE_EXPECT_NAME;
+ macroName = new StringBuffer();
+ } else if (ch == '@') {
+ state = STATE_NORMAL;
+ ret.append('@');
+ } else {
+ state = STATE_NORMAL;
+ ret.append('@');
+ ret.append(ch);
+ }
+ break;
+ case STATE_EXPECT_NAME:
+ if (ch == '}') {
+ state = STATE_NORMAL;
+ String name = macroName.toString().toLowerCase(Locale.ENGLISH);
+ String value = (String) macroMapping.get(name);
+ if (value == null) {
+ ret.append("@{");
+ ret.append(name);
+ ret.append("}");
+ } else {
+ ret.append(value);
+ }
+ macroName = null;
+ } else {
+ macroName.append(ch);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ switch (state) {
+ case STATE_NORMAL:
+ break;
+ case STATE_EXPECT_BRACKET:
+ ret.append('@');
+ break;
+ case STATE_EXPECT_NAME:
+ ret.append("@{");
+ ret.append(macroName.toString());
+ break;
+ default:
+ break;
+ }
+
+ return ret.toString();
+ }
+
+ /**
+ * Set the text contents for the macro.
+ * @param text the text to be added to the macro.
+ */
+
+ public void addText(String text) {
+ this.text = text;
+ }
+
+ private UnknownElement copy(UnknownElement ue, boolean nested) {
+ UnknownElement ret = new UnknownElement(ue.getTag());
+ ret.setNamespace(ue.getNamespace());
+ ret.setProject(getProject());
+ ret.setQName(ue.getQName());
+ ret.setTaskType(ue.getTaskType());
+ ret.setTaskName(ue.getTaskName());
+ ret.setLocation(
+ macroDef.getBackTrace() ? ue.getLocation() : getLocation());
+ if (getOwningTarget() == null) {
+ Target t = new Target();
+ t.setProject(getProject());
+ ret.setOwningTarget(t);
+ } else {
+ ret.setOwningTarget(getOwningTarget());
+ }
+ RuntimeConfigurable rc = new RuntimeConfigurable(
+ ret, ue.getTaskName());
+ rc.setPolyType(ue.getWrapper().getPolyType());
+ Map<String, Object> m = ue.getWrapper().getAttributeMap();
+ for (Map.Entry<String, Object> entry : m.entrySet()) {
+ rc.setAttribute(
+ entry.getKey(),
+ macroSubs((String) entry.getValue(), localAttributes));
+ }
+ rc.addText(macroSubs(ue.getWrapper().getText().toString(),
+ localAttributes));
+
+ Enumeration<RuntimeConfigurable> e = ue.getWrapper().getChildren();
+ while (e.hasMoreElements()) {
+ RuntimeConfigurable r = e.nextElement();
+ UnknownElement unknownElement = (UnknownElement) r.getProxy();
+ String tag = unknownElement.getTaskType();
+ if (tag != null) {
+ tag = tag.toLowerCase(Locale.ENGLISH);
+ }
+ MacroDef.TemplateElement templateElement =
+ getNsElements().get(tag);
+ if (templateElement == null || nested) {
+ UnknownElement child = copy(unknownElement, nested);
+ rc.addChild(child.getWrapper());
+ ret.addChild(child);
+ } else if (templateElement.isImplicit()) {
+ if (unknownElements.size() == 0 && !templateElement.isOptional()) {
+ throw new BuildException(
+ "Missing nested elements for implicit element "
+ + templateElement.getName());
+ }
+ for (Iterator<Task> i = unknownElements.iterator();
+ i.hasNext();) {
+ UnknownElement child
+ = copy((UnknownElement) i.next(), true);
+ rc.addChild(child.getWrapper());
+ ret.addChild(child);
+ }
+ } else {
+ UnknownElement presentElement =
+ (UnknownElement) presentElements.get(tag);
+ if (presentElement == null) {
+ if (!templateElement.isOptional()) {
+ throw new BuildException(
+ "Required nested element "
+ + templateElement.getName() + " missing");
+ }
+ continue;
+ }
+ String presentText =
+ presentElement.getWrapper().getText().toString();
+ if (!"".equals(presentText)) {
+ rc.addText(macroSubs(presentText, localAttributes));
+ }
+ List<UnknownElement> list = presentElement.getChildren();
+ if (list != null) {
+ for (Iterator<UnknownElement> i = list.iterator();
+ i.hasNext();) {
+ UnknownElement child
+ = copy(i.next(), true);
+ rc.addChild(child.getWrapper());
+ ret.addChild(child);
+ }
+ }
+ }
+ }
+ return ret;
+ }
+
+ /**
+ * Execute the templates instance.
+ * Copies the unknown element, substitutes the attributes,
+ * and calls perform on the unknown element.
+ *
+ */
+ public void execute() {
+ presentElements = new HashMap<String, UnknownElement>();
+ getNsElements();
+ processTasks();
+ localAttributes = new Hashtable<String, String>();
+ Set<String> copyKeys = new HashSet<String>(map.keySet());
+ for (Attribute attribute : macroDef.getAttributes()) {
+ String value = (String) map.get(attribute.getName());
+ if (value == null && "description".equals(attribute.getName())) {
+ value = getDescription();
+ }
+ if (value == null) {
+ value = attribute.getDefault();
+ value = macroSubs(value, localAttributes);
+ }
+ if (value == null) {
+ throw new BuildException(
+ "required attribute " + attribute.getName() + " not set");
+ }
+ localAttributes.put(attribute.getName(), value);
+ copyKeys.remove(attribute.getName());
+ }
+ if (copyKeys.contains("id")) {
+ copyKeys.remove("id");
+ }
+ if (macroDef.getText() != null) {
+ if (text == null) {
+ String defaultText = macroDef.getText().getDefault();
+ if (!macroDef.getText().getOptional() && defaultText == null) {
+ throw new BuildException(
+ "required text missing");
+ }
+ text = defaultText == null ? "" : defaultText;
+ }
+ if (macroDef.getText().getTrim()) {
+ text = text.trim();
+ }
+ localAttributes.put(macroDef.getText().getName(), text);
+ } else {
+ if (text != null && !text.trim().equals("")) {
+ throw new BuildException(
+ "The \"" + getTaskName() + "\" macro does not support"
+ + " nested text data.");
+ }
+ }
+ if (copyKeys.size() != 0) {
+ throw new BuildException(
+ "Unknown attribute" + (copyKeys.size() > 1 ? "s " : " ")
+ + copyKeys);
+ }
+
+ // need to set the project on unknown element
+ UnknownElement c = copy(macroDef.getNestedTask(), false);
+ c.init();
+ LocalProperties localProperties
+ = LocalProperties.get(getProject());
+ localProperties.enterScope();
+ try {
+ c.perform();
+ } catch (BuildException ex) {
+ if (macroDef.getBackTrace()) {
+ throw ProjectHelper.addLocationToBuildException(
+ ex, getLocation());
+ } else {
+ ex.setLocation(getLocation());
+ throw ex;
+ }
+ } finally {
+ presentElements = null;
+ localAttributes = null;
+ localProperties.exitScope();
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/MakeUrl.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/MakeUrl.java
new file mode 100644
index 00000000..e23c0253
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/MakeUrl.java
@@ -0,0 +1,298 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs;
+
+
+import java.io.File;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.ListIterator;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.DirectoryScanner;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.types.FileSet;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.util.FileUtils;
+
+/**
+ * <p>This task takes file and turns them into a URL, which it then assigns
+ * to a property. Use when for setting up RMI codebases.</p>
+ *
+ * <p>nested filesets are supported; if present, these are turned into the
+ * url with the given separator between them (default = " ").</p>
+ *
+ * @ant.task category="core" name="makeurl"
+ */
+
+public class MakeUrl extends Task {
+
+ /**
+ * name of the property to set
+ */
+ private String property;
+
+ /**
+ * name of a file to turn into a URL
+ */
+ private File file;
+
+ /**
+ * separator char
+ */
+ private String separator = " ";
+
+ /**
+ * filesets of nested files to add to this url
+ */
+ private List<FileSet> filesets = new LinkedList<FileSet>();
+
+ /**
+ * paths to add
+ */
+ private List<Path> paths = new LinkedList<Path>();
+
+ /**
+ * validation flag
+ */
+ private boolean validate = true;
+
+ // error message strings
+ /** Missing file */
+ public static final String ERROR_MISSING_FILE = "A source file is missing: ";
+ /** No property defined */
+ public static final String ERROR_NO_PROPERTY = "No property defined";
+ /** No files defined */
+ public static final String ERROR_NO_FILES = "No files defined";
+
+ /**
+ * set the name of a property to fill with the URL
+ *
+ * @param property the name of the property.
+ */
+ public void setProperty(String property) {
+ this.property = property;
+ }
+
+ /**
+ * the name of a file to be converted into a URL
+ *
+ * @param file the file to be converted.
+ */
+ public void setFile(File file) {
+ this.file = file;
+ }
+
+ /**
+ * a fileset of jar files to include in the URL, each
+ * separated by the separator
+ *
+ * @param fileset the fileset to be added.
+ */
+ public void addFileSet(FileSet fileset) {
+ filesets.add(fileset);
+ }
+
+ /**
+ * set the separator for the multi-url option.
+ *
+ * @param separator the separator to use.
+ */
+ public void setSeparator(String separator) {
+ this.separator = separator;
+ }
+
+ /**
+ * set this flag to trigger validation that every named file exists.
+ * Optional: default=true
+ *
+ * @param validate a <code>boolean</code> value.
+ */
+ public void setValidate(boolean validate) {
+ this.validate = validate;
+ }
+
+ /**
+ * add a path to the URL. All elements in the path
+ * will be converted to individual URL entries
+ *
+ * @param path a path value.
+ */
+ public void addPath(Path path) {
+ paths.add(path);
+ }
+
+ /**
+ * convert the filesets to urls.
+ *
+ * @return null for no files
+ */
+ private String filesetsToURL() {
+ if (filesets.isEmpty()) {
+ return "";
+ }
+ int count = 0;
+ StringBuilder urls = new StringBuilder();
+ ListIterator<FileSet> list = filesets.listIterator();
+ while (list.hasNext()) {
+ FileSet set = list.next();
+ DirectoryScanner scanner = set.getDirectoryScanner(getProject());
+ String[] files = scanner.getIncludedFiles();
+ for (int i = 0; i < files.length; i++) {
+ File f = new File(scanner.getBasedir(), files[i]);
+ validateFile(f);
+ String asUrl = toURL(f);
+ urls.append(asUrl);
+ log(asUrl, Project.MSG_DEBUG);
+ urls.append(separator);
+ count++;
+ }
+ }
+ //at this point there is one trailing space to remove, if the list is not empty.
+ return stripTrailingSeparator(urls, count);
+ }
+
+ /**
+ * convert the string buffer to a string, potentially stripping
+ * out any trailing separator
+ *
+ * @param urls URL buffer
+ * @param count number of URL entries
+ * @return trimmed string, or empty string
+ */
+ private String stripTrailingSeparator(StringBuilder urls,
+ int count) {
+ if (count > 0) {
+ urls.delete(urls.length() - separator.length(), urls.length());
+ return new String(urls);
+ } else {
+ return "";
+ }
+ }
+
+
+ /**
+ * convert all paths to URLs
+ *
+ * @return the paths as a separated list of URLs
+ */
+ private String pathsToURL() {
+ if (paths.isEmpty()) {
+ return "";
+ }
+ int count = 0;
+ StringBuilder urls = new StringBuilder();
+ ListIterator<Path> list = paths.listIterator();
+ while (list.hasNext()) {
+ Path path = list.next();
+ String[] elements = path.list();
+ for (int i = 0; i < elements.length; i++) {
+ File f = new File(elements[i]);
+ validateFile(f);
+ String asUrl = toURL(f);
+ urls.append(asUrl);
+ log(asUrl, Project.MSG_DEBUG);
+ urls.append(separator);
+ count++;
+ }
+ }
+ //at this point there is one trailing space to remove, if the list is not empty.
+ return stripTrailingSeparator(urls, count);
+ }
+
+ /**
+ * verify that the file exists, if {@link #validate} is set
+ *
+ * @param fileToCheck file that may need to exist
+ * @throws BuildException with text beginning {@link #ERROR_MISSING_FILE}
+ */
+ private void validateFile(File fileToCheck) {
+ if (validate && !fileToCheck.exists()) {
+ throw new BuildException(ERROR_MISSING_FILE + fileToCheck.toString());
+ }
+ }
+
+ /**
+ * Create the url
+ *
+ * @throws org.apache.tools.ant.BuildException
+ * if something goes wrong with the build
+ */
+ @Override
+ public void execute() throws BuildException {
+ validate();
+ //now exit here if the property is already set
+ if (getProject().getProperty(property) != null) {
+ return;
+ }
+ String url;
+ String filesetURL = filesetsToURL();
+ if (file != null) {
+ validateFile(file);
+ url = toURL(file);
+ //and add any files if also defined
+ if (filesetURL.length() > 0) {
+ url = url + separator + filesetURL;
+ }
+ } else {
+ url = filesetURL;
+ }
+ //add path URLs
+ String pathURL = pathsToURL();
+ if (pathURL.length() > 0) {
+ if (url.length() > 0) {
+ url = url + separator + pathURL;
+ } else {
+ url = pathURL;
+ }
+ }
+ log("Setting " + property + " to URL " + url, Project.MSG_VERBOSE);
+ getProject().setNewProperty(property, url);
+ }
+
+ /**
+ * check for errors
+ * @throws BuildException if we are not configured right
+ */
+ private void validate() {
+ //validation
+ if (property == null) {
+ throw new BuildException(ERROR_NO_PROPERTY);
+ }
+ if (file == null && filesets.isEmpty() && paths.isEmpty()) {
+ throw new BuildException(ERROR_NO_FILES);
+ }
+ }
+
+ /**
+ * convert a file to a URL;
+ *
+ * @param fileToConvert
+ * @return the file converted to a URL
+ */
+ private String toURL(File fileToConvert) {
+ String url;
+ //create the URL
+ //ant equivalent of fileToConvert.toURI().toURL().toExternalForm();
+ url = FileUtils.getFileUtils().toURI(fileToConvert.getAbsolutePath());
+
+ return url;
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Manifest.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Manifest.java
new file mode 100644
index 00000000..06c74ddc
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Manifest.java
@@ -0,0 +1,1183 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.io.Reader;
+import java.io.StringWriter;
+import java.io.UnsupportedEncodingException;
+import java.util.Enumeration;
+import java.util.LinkedHashMap;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.util.CollectionUtils;
+import org.apache.tools.ant.util.FileUtils;
+
+/**
+ * Holds the data of a jar manifest.
+ *
+ * Manifests are processed according to the
+ * {@link <a href="http://java.sun.com/j2se/1.5.0/docs/guide/jar/jar.html">Jar
+ * file specification.</a>}.
+ * Specifically, a manifest element consists of
+ * a set of attributes and sections. These sections in turn may contain
+ * attributes. Note in particular that this may result in manifest lines
+ * greater than 72 bytes being wrapped and continued on the next
+ * line. If an application can not handle the continuation mechanism, it
+ * is a defect in the application, not this task.
+ *
+ *
+ * @since Ant 1.4
+ */
+public class Manifest {
+ /** The standard manifest version header */
+ public static final String ATTRIBUTE_MANIFEST_VERSION
+ = "Manifest-Version";
+
+ /** The standard Signature Version header */
+ public static final String ATTRIBUTE_SIGNATURE_VERSION
+ = "Signature-Version";
+
+ /** The Name Attribute is the first in a named section */
+ public static final String ATTRIBUTE_NAME = "Name";
+
+ /** The From Header is disallowed in a Manifest */
+ public static final String ATTRIBUTE_FROM = "From";
+
+ /** The Class-Path Header is special - it can be duplicated */
+ public static final String ATTRIBUTE_CLASSPATH = "Class-Path";
+
+ /** Default Manifest version if one is not specified */
+ public static final String DEFAULT_MANIFEST_VERSION = "1.0";
+
+ /** The max length of a line in a Manifest */
+ public static final int MAX_LINE_LENGTH = 72;
+
+ /**
+ * Max length of a line section which is continued. Need to allow
+ * for the CRLF.
+ */
+ public static final int MAX_SECTION_LENGTH = MAX_LINE_LENGTH - 2;
+
+ /** The End-Of-Line marker in manifests */
+ public static final String EOL = "\r\n";
+ /** Error for attributes */
+ public static final String ERROR_FROM_FORBIDDEN = "Manifest attributes should not start "
+ + "with \"" + ATTRIBUTE_FROM + "\" in \"";
+
+ /** Encoding to be used for JAR files. */
+ public static final String JAR_ENCODING = "UTF-8";
+
+ private static final String ATTRIBUTE_MANIFEST_VERSION_LC =
+ ATTRIBUTE_MANIFEST_VERSION.toLowerCase(Locale.ENGLISH);
+ private static final String ATTRIBUTE_NAME_LC =
+ ATTRIBUTE_NAME.toLowerCase(Locale.ENGLISH);
+ private static final String ATTRIBUTE_FROM_LC =
+ ATTRIBUTE_FROM.toLowerCase(Locale.ENGLISH);
+ private static final String ATTRIBUTE_CLASSPATH_LC =
+ ATTRIBUTE_CLASSPATH.toLowerCase(Locale.ENGLISH);
+
+ /**
+ * An attribute for the manifest.
+ * Those attributes that are not nested into a section will be added to the "Main" section.
+ */
+ public static class Attribute {
+
+ /**
+ * Maximum length of the name to have the value starting on the same
+ * line as the name. This to stay under 72 bytes total line length
+ * (including CRLF).
+ */
+ private static final int MAX_NAME_VALUE_LENGTH = 68;
+
+ /**
+ * Maximum length of the name according to the jar specification.
+ * In this case the first line will have 74 bytes total line length
+ * (including CRLF). This conflicts with the 72 bytes total line length
+ * max, but is the only possible conclusion from the manifest specification, if
+ * names with 70 bytes length are allowed, have to be on the first line, and
+ * have to be followed by ": ".
+ */
+ private static final int MAX_NAME_LENGTH = 70;
+
+ /** The attribute's name */
+ private String name = null;
+
+ /** The attribute's value */
+ private Vector<String> values = new Vector<String>();
+
+ /**
+ * For multivalued attributes, this is the index of the attribute
+ * currently being defined.
+ */
+ private int currentIndex = 0;
+
+ /**
+ * Construct an empty attribute */
+ public Attribute() {
+ }
+
+ /**
+ * Construct an attribute by parsing a line from the Manifest
+ *
+ * @param line the line containing the attribute name and value
+ *
+ * @throws ManifestException if the line is not valid
+ */
+ public Attribute(String line) throws ManifestException {
+ parse(line);
+ }
+
+ /**
+ * Construct a manifest by specifying its name and value
+ *
+ * @param name the attribute's name
+ * @param value the Attribute's value
+ */
+ public Attribute(String name, String value) {
+ this.name = name;
+ setValue(value);
+ }
+
+ /**
+ * @see java.lang.Object#hashCode
+ * @return a hashcode based on the key and values.
+ */
+ @Override
+ public int hashCode() {
+ int hashCode = 0;
+
+ if (name != null) {
+ hashCode += getKey().hashCode();
+ }
+
+ hashCode += values.hashCode();
+ return hashCode;
+ }
+
+ /**
+ * @param rhs the object to check for equality.
+ * @see java.lang.Object#equals
+ * @return true if the key and values are the same.
+ */
+ @Override
+ public boolean equals(Object rhs) {
+ if (rhs == null || rhs.getClass() != getClass()) {
+ return false;
+ }
+
+ if (rhs == this) {
+ return true;
+ }
+
+ Attribute rhsAttribute = (Attribute) rhs;
+ String lhsKey = getKey();
+ String rhsKey = rhsAttribute.getKey();
+ if ((lhsKey == null && rhsKey != null)
+ || (lhsKey != null && !lhsKey.equals(rhsKey))) {
+ return false;
+ }
+
+ return values.equals(rhsAttribute.values);
+ }
+
+ /**
+ * Parse a line into name and value pairs
+ *
+ * @param line the line to be parsed
+ *
+ * @throws ManifestException if the line does not contain a colon
+ * separating the name and value
+ */
+ public void parse(String line) throws ManifestException {
+ int index = line.indexOf(": ");
+ if (index == -1) {
+ throw new ManifestException("Manifest line \"" + line
+ + "\" is not valid as it does not "
+ + "contain a name and a value separated by ': ' ");
+ }
+ name = line.substring(0, index);
+ setValue(line.substring(index + 2));
+ }
+
+ /**
+ * Set the Attribute's name; required
+ *
+ * @param name the attribute's name
+ */
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ /**
+ * Get the Attribute's name
+ *
+ * @return the attribute's name.
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Get the attribute's Key - its name in lower case.
+ *
+ * @return the attribute's key.
+ */
+ public String getKey() {
+ if (name == null) {
+ return null;
+ }
+ return name.toLowerCase(Locale.ENGLISH);
+ }
+
+ /**
+ * Set the Attribute's value; required
+ *
+ * @param value the attribute's value
+ */
+ public void setValue(String value) {
+ if (currentIndex >= values.size()) {
+ values.addElement(value);
+ currentIndex = values.size() - 1;
+ } else {
+ values.setElementAt(value, currentIndex);
+ }
+ }
+
+ /**
+ * Get the Attribute's value.
+ *
+ * @return the attribute's value.
+ */
+ public String getValue() {
+ if (values.size() == 0) {
+ return null;
+ }
+
+ String fullValue = "";
+ for (Enumeration<String> e = getValues(); e.hasMoreElements();) {
+ String value = e.nextElement();
+ fullValue += value + " ";
+ }
+ return fullValue.trim();
+ }
+
+ /**
+ * Add a new value to this attribute - making it multivalued.
+ *
+ * @param value the attribute's additional value
+ */
+ public void addValue(String value) {
+ currentIndex++;
+ setValue(value);
+ }
+
+ /**
+ * Get all the attribute's values.
+ *
+ * @return an enumeration of the attributes values
+ */
+ public Enumeration<String> getValues() {
+ return values.elements();
+ }
+
+ /**
+ * Add a continuation line from the Manifest file.
+ *
+ * When lines are too long in a manifest, they are continued on the
+ * next line by starting with a space. This method adds the continuation
+ * data to the attribute value by skipping the first character.
+ *
+ * @param line the continuation line.
+ */
+ public void addContinuation(String line) {
+ String currentValue = values.elementAt(currentIndex);
+ setValue(currentValue + line.substring(1));
+ }
+
+ /**
+ * Write the attribute out to a print writer without
+ * flattening multi-values attributes (i.e. Class-Path).
+ *
+ * @param writer the Writer to which the attribute is written
+ *
+ * @throws IOException if the attribute value cannot be written
+ */
+ public void write(PrintWriter writer) throws IOException {
+ write(writer, false);
+ }
+
+ /**
+ * Write the attribute out to a print writer.
+ *
+ * @param writer the Writer to which the attribute is written
+ * @param flatten whether to collapse multi-valued attributes
+ * (i.e. potentially Class-Path) Class-Path into a
+ * single attribute.
+ *
+ * @throws IOException if the attribute value cannot be written
+ * @since Ant 1.8.0
+ */
+ public void write(PrintWriter writer, boolean flatten)
+ throws IOException {
+ if (!flatten) {
+ for (Enumeration<String> e = getValues(); e.hasMoreElements();) {
+ writeValue(writer, e.nextElement());
+ }
+ } else {
+ writeValue(writer, getValue());
+ }
+ }
+
+ /**
+ * Write a single attribute value out
+ *
+ * @param writer the Writer to which the attribute is written
+ * @param value the attribute value
+ *
+ * @throws IOException if the attribute value cannot be written
+ */
+ private void writeValue(PrintWriter writer, String value)
+ throws IOException {
+ String line = null;
+ int nameLength = name.getBytes(JAR_ENCODING).length;
+ if (nameLength > MAX_NAME_VALUE_LENGTH) {
+ if (nameLength > MAX_NAME_LENGTH) {
+ throw new IOException("Unable to write manifest line "
+ + name + ": " + value);
+ }
+ writer.print(name + ": " + EOL);
+ line = " " + value;
+ } else {
+ line = name + ": " + value;
+ }
+ while (line.getBytes(JAR_ENCODING).length > MAX_SECTION_LENGTH) {
+ // try to find a MAX_LINE_LENGTH byte section
+ int breakIndex = MAX_SECTION_LENGTH;
+ if (breakIndex >= line.length()) {
+ breakIndex = line.length() - 1;
+ }
+ String section = line.substring(0, breakIndex);
+ while (section.getBytes(JAR_ENCODING).length > MAX_SECTION_LENGTH
+ && breakIndex > 0) {
+ breakIndex--;
+ section = line.substring(0, breakIndex);
+ }
+ if (breakIndex == 0) {
+ throw new IOException("Unable to write manifest line "
+ + name + ": " + value);
+ }
+ writer.print(section + EOL);
+ line = " " + line.substring(breakIndex);
+ }
+ writer.print(line + EOL);
+ }
+ }
+
+ /**
+ * A manifest section - you can nest attribute elements into sections.
+ * A section consists of a set of attribute values,
+ * separated from other sections by a blank line.
+ */
+ public static class Section {
+ /** Warnings for this section */
+ private Vector<String> warnings = new Vector<String>();
+
+ /**
+ * The section's name if any. The main section in a
+ * manifest is unnamed.
+ */
+ private String name = null;
+
+ /** The section's attributes.*/
+ private Map<String, Attribute> attributes = new LinkedHashMap<String, Attribute>();
+
+ /**
+ * The name of the section; optional -default is the main section.
+ * @param name the section's name
+ */
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ /**
+ * Get the Section's name.
+ *
+ * @return the section's name.
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Read a section through a reader.
+ *
+ * @param reader the reader from which the section is read
+ *
+ * @return the name of the next section if it has been read as
+ * part of this section - This only happens if the
+ * Manifest is malformed.
+ *
+ * @throws ManifestException if the section is not valid according
+ * to the JAR spec
+ * @throws IOException if the section cannot be read from the reader.
+ */
+ public String read(BufferedReader reader)
+ throws ManifestException, IOException {
+ Attribute attribute = null;
+ while (true) {
+ String line = reader.readLine();
+ if (line == null || line.length() == 0) {
+ return null;
+ }
+ if (line.charAt(0) == ' ') {
+ // continuation line
+ if (attribute == null) {
+ if (name != null) {
+ // a continuation on the first line is a
+ // continuation of the name - concatenate this
+ // line and the name
+ name += line.substring(1);
+ } else {
+ throw new ManifestException("Can't start an "
+ + "attribute with a continuation line " + line);
+ }
+ } else {
+ attribute.addContinuation(line);
+ }
+ } else {
+ attribute = new Attribute(line);
+ String nameReadAhead = addAttributeAndCheck(attribute);
+ // refresh attribute in case of multivalued attributes.
+ attribute = getAttribute(attribute.getKey());
+ if (nameReadAhead != null) {
+ return nameReadAhead;
+ }
+ }
+ }
+ }
+
+ /**
+ * Merge in another section without merging Class-Path attributes.
+ *
+ * @param section the section to be merged with this one.
+ *
+ * @throws ManifestException if the sections cannot be merged.
+ */
+ public void merge(Section section) throws ManifestException {
+ merge(section, false);
+ }
+
+ /**
+ * Merge in another section
+ *
+ * @param section the section to be merged with this one.
+ * @param mergeClassPaths whether Class-Path attributes should
+ * be merged.
+ *
+ * @throws ManifestException if the sections cannot be merged.
+ */
+ public void merge(Section section, boolean mergeClassPaths)
+ throws ManifestException {
+ if (name == null && section.getName() != null
+ || (name != null && section.getName() != null
+ && !(name.toLowerCase(Locale.ENGLISH)
+ .equals(section.getName().toLowerCase(Locale.ENGLISH))))
+ ) {
+ throw new ManifestException("Unable to merge sections "
+ + "with different names");
+ }
+
+ Enumeration<String> e = section.getAttributeKeys();
+ Attribute classpathAttribute = null;
+ while (e.hasMoreElements()) {
+ String attributeName = e.nextElement();
+ Attribute attribute = section.getAttribute(attributeName);
+ if (attributeName.equalsIgnoreCase(ATTRIBUTE_CLASSPATH)) {
+ if (classpathAttribute == null) {
+ classpathAttribute = new Attribute();
+ classpathAttribute.setName(ATTRIBUTE_CLASSPATH);
+ }
+ Enumeration<String> cpe = attribute.getValues();
+ while (cpe.hasMoreElements()) {
+ String value = cpe.nextElement();
+ classpathAttribute.addValue(value);
+ }
+ } else {
+ // the merge file always wins
+ storeAttribute(attribute);
+ }
+ }
+
+ if (classpathAttribute != null) {
+ if (mergeClassPaths) {
+ Attribute currentCp = getAttribute(ATTRIBUTE_CLASSPATH);
+ if (currentCp != null) {
+ for (Enumeration<String> attribEnum = currentCp.getValues();
+ attribEnum.hasMoreElements();) {
+ String value = attribEnum.nextElement();
+ classpathAttribute.addValue(value);
+ }
+ }
+ }
+ storeAttribute(classpathAttribute);
+ }
+
+ // add in the warnings
+ Enumeration<String> warnEnum = section.warnings.elements();
+ while (warnEnum.hasMoreElements()) {
+ warnings.addElement(warnEnum.nextElement());
+ }
+ }
+
+ /**
+ * Write the section out to a print writer without flattening
+ * multi-values attributes (i.e. Class-Path).
+ *
+ * @param writer the Writer to which the section is written
+ *
+ * @throws IOException if the section cannot be written
+ */
+ public void write(PrintWriter writer) throws IOException {
+ write(writer, false);
+ }
+
+ /**
+ * Write the section out to a print writer.
+ *
+ * @param writer the Writer to which the section is written
+ * @param flatten whether to collapse multi-valued attributes
+ * (i.e. potentially Class-Path) Class-Path into a
+ * single attribute.
+ *
+ * @throws IOException if the section cannot be written
+ * @since Ant 1.8.0
+ */
+ public void write(PrintWriter writer, boolean flatten)
+ throws IOException {
+ if (name != null) {
+ Attribute nameAttr = new Attribute(ATTRIBUTE_NAME, name);
+ nameAttr.write(writer);
+ }
+ Enumeration<String> e = getAttributeKeys();
+ while (e.hasMoreElements()) {
+ String key = e.nextElement();
+ Attribute attribute = getAttribute(key);
+ attribute.write(writer, flatten);
+ }
+ writer.print(EOL);
+ }
+
+ /**
+ * Get a attribute of the section
+ *
+ * @param attributeName the name of the attribute
+ * @return a Manifest.Attribute instance if the attribute is
+ * single-valued, otherwise a Vector of Manifest.Attribute
+ * instances.
+ */
+ public Attribute getAttribute(String attributeName) {
+ return attributes.get(attributeName.toLowerCase(Locale.ENGLISH));
+ }
+
+ /**
+ * Get the attribute keys.
+ *
+ * @return an Enumeration of Strings, each string being the lower case
+ * key of an attribute of the section.
+ */
+ public Enumeration<String> getAttributeKeys() {
+ return CollectionUtils.asEnumeration(attributes.keySet().iterator());
+ }
+
+ /**
+ * Get the value of the attribute with the name given.
+ *
+ * @param attributeName the name of the attribute to be returned.
+ *
+ * @return the attribute's value or null if the attribute does not exist
+ * in the section
+ */
+ public String getAttributeValue(String attributeName) {
+ Attribute attribute = getAttribute(attributeName.toLowerCase(Locale.ENGLISH));
+ if (attribute == null) {
+ return null;
+ }
+ return attribute.getValue();
+ }
+
+ /**
+ * Remove the given attribute from the section
+ *
+ * @param attributeName the name of the attribute to be removed.
+ */
+ public void removeAttribute(String attributeName) {
+ String key = attributeName.toLowerCase(Locale.ENGLISH);
+ attributes.remove(key);
+ }
+
+ /**
+ * Add an attribute to the section.
+ *
+ * @param attribute the attribute to be added to the section
+ *
+ * @exception ManifestException if the attribute is not valid.
+ */
+ public void addConfiguredAttribute(Attribute attribute)
+ throws ManifestException {
+ String check = addAttributeAndCheck(attribute);
+ if (check != null) {
+ throw new BuildException("Specify the section name using "
+ + "the \"name\" attribute of the <section> element rather "
+ + "than using a \"Name\" manifest attribute");
+ }
+ }
+
+ /**
+ * Add an attribute to the section
+ *
+ * @param attribute the attribute to be added.
+ *
+ * @return the value of the attribute if it is a name
+ * attribute - null other wise
+ *
+ * @exception ManifestException if the attribute already
+ * exists in this section.
+ */
+ public String addAttributeAndCheck(Attribute attribute)
+ throws ManifestException {
+ if (attribute.getName() == null || attribute.getValue() == null) {
+ throw new BuildException("Attributes must have name and value");
+ }
+ String attributeKey = attribute.getKey();
+ if (attributeKey.equals(ATTRIBUTE_NAME_LC)) {
+ warnings.addElement("\"" + ATTRIBUTE_NAME + "\" attributes "
+ + "should not occur in the main section and must be the "
+ + "first element in all other sections: \""
+ + attribute.getName() + ": " + attribute.getValue() + "\"");
+ return attribute.getValue();
+ }
+
+ if (attributeKey.startsWith(ATTRIBUTE_FROM_LC)) {
+ warnings.addElement(ERROR_FROM_FORBIDDEN
+ + attribute.getName() + ": " + attribute.getValue() + "\"");
+ } else {
+ // classpath attributes go into a vector
+ if (attributeKey.equals(ATTRIBUTE_CLASSPATH_LC)) {
+ Attribute classpathAttribute =
+ attributes.get(attributeKey);
+
+ if (classpathAttribute == null) {
+ storeAttribute(attribute);
+ } else {
+ warnings.addElement("Multiple Class-Path attributes "
+ + "are supported but violate the Jar "
+ + "specification and may not be correctly "
+ + "processed in all environments");
+ Enumeration<String> e = attribute.getValues();
+ while (e.hasMoreElements()) {
+ String value = e.nextElement();
+ classpathAttribute.addValue(value);
+ }
+ }
+ } else if (attributes.containsKey(attributeKey)) {
+ throw new ManifestException("The attribute \""
+ + attribute.getName() + "\" may not occur more "
+ + "than once in the same section");
+ } else {
+ storeAttribute(attribute);
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Clone this section
+ *
+ * @return the cloned Section
+ * @since Ant 1.5.2
+ */
+ @Override
+ public Object clone() {
+ Section cloned = new Section();
+ cloned.setName(name);
+ Enumeration<String> e = getAttributeKeys();
+ while (e.hasMoreElements()) {
+ String key = e.nextElement();
+ Attribute attribute = getAttribute(key);
+ cloned.storeAttribute(new Attribute(attribute.getName(),
+ attribute.getValue()));
+ }
+ return cloned;
+ }
+
+ /**
+ * Store an attribute and update the index.
+ *
+ * @param attribute the attribute to be stored
+ */
+ private void storeAttribute(Attribute attribute) {
+ if (attribute == null) {
+ return;
+ }
+ String attributeKey = attribute.getKey();
+ attributes.put(attributeKey, attribute);
+ }
+
+ /**
+ * Get the warnings for this section.
+ *
+ * @return an Enumeration of warning strings.
+ */
+ public Enumeration<String> getWarnings() {
+ return warnings.elements();
+ }
+
+ /**
+ * @see java.lang.Object#hashCode
+ * @return a hash value based on the attributes.
+ */
+ @Override
+ public int hashCode() {
+ return attributes.hashCode();
+ }
+
+ /**
+ * @see java.lang.Object#equals
+ * @param rhs the object to check for equality.
+ * @return true if the attributes are the same.
+ */
+ @Override
+ public boolean equals(Object rhs) {
+ if (rhs == null || rhs.getClass() != getClass()) {
+ return false;
+ }
+
+ if (rhs == this) {
+ return true;
+ }
+
+ Section rhsSection = (Section) rhs;
+
+ return attributes.equals(rhsSection.attributes);
+ }
+ }
+
+
+ /** The version of this manifest */
+ private String manifestVersion = DEFAULT_MANIFEST_VERSION;
+
+ /** The main section of this manifest */
+ private Section mainSection = new Section();
+
+ /** The named sections of this manifest */
+ private Map<String, Section> sections = new LinkedHashMap<String, Section>();
+
+ /**
+ * Construct a manifest from Ant's default manifest file.
+ *
+ * @return the default manifest.
+ * @exception BuildException if there is a problem loading the
+ * default manifest
+ */
+ public static Manifest getDefaultManifest() throws BuildException {
+ InputStream in = null;
+ InputStreamReader insr = null;
+ try {
+ String defManifest = "/org/apache/tools/ant/defaultManifest.mf";
+ in = Manifest.class.getResourceAsStream(defManifest);
+ if (in == null) {
+ throw new BuildException("Could not find default manifest: "
+ + defManifest);
+ }
+ try {
+ insr = new InputStreamReader(in, "UTF-8");
+ Manifest defaultManifest = new Manifest(insr);
+ String version = System.getProperty("java.runtime.version");
+ if (version == null) {
+ version = System.getProperty("java.vm.version");
+ }
+ Attribute createdBy = new Attribute("Created-By",
+ version + " ("
+ + System.getProperty("java.vm.vendor") + ")");
+ defaultManifest.getMainSection().storeAttribute(createdBy);
+ return defaultManifest;
+ } catch (UnsupportedEncodingException e) {
+ insr = new InputStreamReader(in);
+ return new Manifest(insr);
+ }
+ } catch (ManifestException e) {
+ throw new BuildException("Default manifest is invalid !!", e);
+ } catch (IOException e) {
+ throw new BuildException("Unable to read default manifest", e);
+ } finally {
+ FileUtils.close(insr);
+ FileUtils.close(in);
+ }
+ }
+
+ /** Construct an empty manifest */
+ public Manifest() {
+ manifestVersion = null;
+ }
+
+ /**
+ * Read a manifest file from the given reader
+ *
+ * @param r is the reader from which the Manifest is read
+ *
+ * @throws ManifestException if the manifest is not valid according
+ * to the JAR spec
+ * @throws IOException if the manifest cannot be read from the reader.
+ */
+ public Manifest(Reader r) throws ManifestException, IOException {
+ BufferedReader reader = new BufferedReader(r);
+ // This should be the manifest version
+ String nextSectionName = mainSection.read(reader);
+ String readManifestVersion
+ = mainSection.getAttributeValue(ATTRIBUTE_MANIFEST_VERSION);
+ if (readManifestVersion != null) {
+ manifestVersion = readManifestVersion;
+ mainSection.removeAttribute(ATTRIBUTE_MANIFEST_VERSION);
+ }
+
+ String line = null;
+ while ((line = reader.readLine()) != null) {
+ if (line.length() == 0) {
+ continue;
+ }
+
+ Section section = new Section();
+ if (nextSectionName == null) {
+ Attribute sectionName = new Attribute(line);
+ if (!sectionName.getName().equalsIgnoreCase(ATTRIBUTE_NAME)) {
+ throw new ManifestException("Manifest sections should "
+ + "start with a \"" + ATTRIBUTE_NAME
+ + "\" attribute and not \""
+ + sectionName.getName() + "\"");
+ }
+ nextSectionName = sectionName.getValue();
+ } else {
+ // we have already started reading this section
+ // this line is the first attribute. set it and then
+ // let the normal read handle the rest
+ Attribute firstAttribute = new Attribute(line);
+ section.addAttributeAndCheck(firstAttribute);
+ }
+
+ section.setName(nextSectionName);
+ nextSectionName = section.read(reader);
+ addConfiguredSection(section);
+ }
+ }
+
+ /**
+ * Add a section to the manifest
+ *
+ * @param section the manifest section to be added
+ *
+ * @exception ManifestException if the secti0on is not valid.
+ */
+ public void addConfiguredSection(Section section)
+ throws ManifestException {
+ String sectionName = section.getName();
+ if (sectionName == null) {
+ throw new BuildException("Sections must have a name");
+ }
+ sections.put(sectionName, section);
+ }
+
+ /**
+ * Add an attribute to the manifest - it is added to the main section.
+ *
+ * @param attribute the attribute to be added.
+ *
+ * @exception ManifestException if the attribute is not valid.
+ */
+ public void addConfiguredAttribute(Attribute attribute)
+ throws ManifestException {
+ if (attribute.getKey() == null || attribute.getValue() == null) {
+ throw new BuildException("Attributes must have name and value");
+ }
+ if (attribute.getKey().equals(ATTRIBUTE_MANIFEST_VERSION_LC)) {
+ manifestVersion = attribute.getValue();
+ } else {
+ mainSection.addConfiguredAttribute(attribute);
+ }
+ }
+
+ /**
+ * Merge the contents of the given manifest into this manifest
+ * without merging Class-Path attributes.
+ *
+ * @param other the Manifest to be merged with this one.
+ *
+ * @throws ManifestException if there is a problem merging the
+ * manifest according to the Manifest spec.
+ */
+ public void merge(Manifest other) throws ManifestException {
+ merge(other, false);
+ }
+
+ /**
+ * Merge the contents of the given manifest into this manifest
+ * without merging Class-Path attributes.
+ *
+ * @param other the Manifest to be merged with this one.
+ * @param overwriteMain whether to overwrite the main section
+ * of the current manifest
+ *
+ * @throws ManifestException if there is a problem merging the
+ * manifest according to the Manifest spec.
+ */
+ public void merge(Manifest other, boolean overwriteMain)
+ throws ManifestException {
+ merge(other, overwriteMain, false);
+ }
+
+ /**
+ * Merge the contents of the given manifest into this manifest
+ *
+ * @param other the Manifest to be merged with this one.
+ * @param overwriteMain whether to overwrite the main section
+ * of the current manifest
+ * @param mergeClassPaths whether Class-Path attributes should be
+ * merged.
+ *
+ * @throws ManifestException if there is a problem merging the
+ * manifest according to the Manifest spec.
+ *
+ * @since Ant 1.8.0
+ */
+ public void merge(Manifest other, boolean overwriteMain,
+ boolean mergeClassPaths)
+ throws ManifestException {
+ if (other != null) {
+ if (overwriteMain) {
+ mainSection = (Section) other.mainSection.clone();
+ } else {
+ mainSection.merge(other.mainSection, mergeClassPaths);
+ }
+
+ if (other.manifestVersion != null) {
+ manifestVersion = other.manifestVersion;
+ }
+
+ Enumeration<String> e = other.getSectionNames();
+ while (e.hasMoreElements()) {
+ String sectionName = e.nextElement();
+ Section ourSection = sections.get(sectionName);
+ Section otherSection
+ = other.sections.get(sectionName);
+ if (ourSection == null) {
+ if (otherSection != null) {
+ addConfiguredSection((Section) otherSection.clone());
+ }
+ } else {
+ ourSection.merge(otherSection, mergeClassPaths);
+ }
+ }
+ }
+ }
+
+ /**
+ * Write the manifest out to a print writer without flattening
+ * multi-values attributes (i.e. Class-Path).
+ *
+ * @param writer the Writer to which the manifest is written
+ *
+ * @throws IOException if the manifest cannot be written
+ */
+ public void write(PrintWriter writer) throws IOException {
+ write(writer, false);
+ }
+
+ /**
+ * Write the manifest out to a print writer.
+ *
+ * @param writer the Writer to which the manifest is written
+ * @param flatten whether to collapse multi-valued attributes
+ * (i.e. potentially Class-Path) Class-Path into a single
+ * attribute.
+ *
+ * @throws IOException if the manifest cannot be written
+ * @since Ant 1.8.0
+ */
+ public void write(PrintWriter writer, boolean flatten) throws IOException {
+ writer.print(ATTRIBUTE_MANIFEST_VERSION + ": " + manifestVersion + EOL);
+ String signatureVersion
+ = mainSection.getAttributeValue(ATTRIBUTE_SIGNATURE_VERSION);
+ if (signatureVersion != null) {
+ writer.print(ATTRIBUTE_SIGNATURE_VERSION + ": "
+ + signatureVersion + EOL);
+ mainSection.removeAttribute(ATTRIBUTE_SIGNATURE_VERSION);
+ }
+ mainSection.write(writer, flatten);
+
+ // add it back
+ if (signatureVersion != null) {
+ try {
+ Attribute svAttr = new Attribute(ATTRIBUTE_SIGNATURE_VERSION,
+ signatureVersion);
+ mainSection.addConfiguredAttribute(svAttr);
+ } catch (ManifestException e) {
+ // shouldn't happen - ignore
+ }
+ }
+
+ for (String sectionName : sections.keySet()) {
+ Section section = getSection(sectionName);
+ section.write(writer, flatten);
+ }
+ }
+
+ /**
+ * Convert the manifest to its string representation
+ *
+ * @return a multiline string with the Manifest as it
+ * appears in a Manifest file.
+ */
+ @Override
+ public String toString() {
+ StringWriter sw = new StringWriter();
+ try {
+ write(new PrintWriter(sw));
+ } catch (IOException e) {
+ return null;
+ }
+ return sw.toString();
+ }
+
+ /**
+ * Get the warnings for this manifest.
+ *
+ * @return an enumeration of warning strings
+ */
+ public Enumeration<String> getWarnings() {
+ Vector<String> warnings = new Vector<String>();
+
+ Enumeration<String> warnEnum = mainSection.getWarnings();
+ while (warnEnum.hasMoreElements()) {
+ warnings.addElement(warnEnum.nextElement());
+ }
+
+ // create a vector and add in the warnings for all the sections
+ for (Section section : sections.values()) {
+ Enumeration<String> e2 = section.getWarnings();
+ while (e2.hasMoreElements()) {
+ warnings.addElement(e2.nextElement());
+ }
+ }
+
+ return warnings.elements();
+ }
+
+ /**
+ * @see java.lang.Object#hashCode
+ * @return a hashcode based on the version, main and sections.
+ */
+ @Override
+ public int hashCode() {
+ int hashCode = 0;
+
+ if (manifestVersion != null) {
+ hashCode += manifestVersion.hashCode();
+ }
+ hashCode += mainSection.hashCode();
+ hashCode += sections.hashCode();
+
+ return hashCode;
+ }
+
+ /**
+ * @see java.lang.Object#equals
+ * @param rhs the object to check for equality.
+ * @return true if the version, main and sections are the same.
+ */
+ @Override
+ public boolean equals(Object rhs) {
+ if (rhs == null || rhs.getClass() != getClass()) {
+ return false;
+ }
+
+ if (rhs == this) {
+ return true;
+ }
+
+ Manifest rhsManifest = (Manifest) rhs;
+ if (manifestVersion == null) {
+ if (rhsManifest.manifestVersion != null) {
+ return false;
+ }
+ } else if (!manifestVersion.equals(rhsManifest.manifestVersion)) {
+ return false;
+ }
+
+ if (!mainSection.equals(rhsManifest.mainSection)) {
+ return false;
+ }
+
+ return sections.equals(rhsManifest.sections);
+ }
+
+ /**
+ * Get the version of the manifest
+ *
+ * @return the manifest's version string
+ */
+ public String getManifestVersion() {
+ return manifestVersion;
+ }
+
+ /**
+ * Get the main section of the manifest
+ *
+ * @return the main section of the manifest
+ */
+ public Section getMainSection() {
+ return mainSection;
+ }
+
+ /**
+ * Get a particular section from the manifest
+ *
+ * @param name the name of the section desired.
+ * @return the specified section or null if that section
+ * does not exist in the manifest
+ */
+ public Section getSection(String name) {
+ return sections.get(name);
+ }
+
+ /**
+ * Get the section names in this manifest.
+ *
+ * @return an Enumeration of section names
+ */
+ public Enumeration<String> getSectionNames() {
+ return CollectionUtils.asEnumeration(sections.keySet().iterator());
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/ManifestClassPath.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/ManifestClassPath.java
new file mode 100644
index 00000000..4a4f2312
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/ManifestClassPath.java
@@ -0,0 +1,180 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs;
+
+import java.io.File;
+import java.io.UnsupportedEncodingException;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.launch.Locator;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.util.FileUtils;
+
+/**
+ * Converts a Path into a property suitable as a Manifest classpath.
+ *
+ * @since Ant 1.7
+ *
+ * @ant.task category="property"
+ */
+public class ManifestClassPath extends Task {
+
+ /** The property name to hold the classpath value. */
+ private String name;
+
+ /** The directory the classpath will be relative from. */
+ private File dir;
+
+ /** The maximum parent directory level to traverse. */
+ private int maxParentLevels = 2;
+
+ /** The classpath to convert. */
+ private Path path;
+
+ /**
+ * Sets a property, which must not already exist, with a space
+ * separated list of files and directories relative to the jar
+ * file's parent directory.
+ */
+ public void execute() {
+ if (name == null) {
+ throw new BuildException("Missing 'property' attribute!");
+ }
+ if (dir == null) {
+ throw new BuildException("Missing 'jarfile' attribute!");
+ }
+ if (getProject().getProperty(name) != null) {
+ throw new BuildException("Property '" + name + "' already set!");
+ }
+ if (path == null) {
+ throw new BuildException("Missing nested <classpath>!");
+ }
+
+ StringBuffer tooLongSb = new StringBuffer();
+ for (int i = 0; i < maxParentLevels + 1; i++) {
+ tooLongSb.append("../");
+ }
+ final String tooLongPrefix = tooLongSb.toString();
+
+ // Normalize the reference directory (containing the jar)
+ final FileUtils fileUtils = FileUtils.getFileUtils();
+ dir = fileUtils.normalize(dir.getAbsolutePath());
+
+ String[] elements = path.list();
+ StringBuffer buffer = new StringBuffer();
+ for (int i = 0; i < elements.length; ++i) {
+ // Normalize the current file
+ File pathEntry = new File(elements[i]);
+ String fullPath = pathEntry.getAbsolutePath();
+ pathEntry = fileUtils.normalize(fullPath);
+
+ String relPath = null;
+ String canonicalPath = null;
+ try {
+ if (dir.equals(pathEntry)) {
+ relPath = ".";
+ } else {
+ relPath = FileUtils.getRelativePath(dir, pathEntry);
+ }
+
+ canonicalPath = pathEntry.getCanonicalPath();
+ // getRelativePath always uses '/' as separator, adapt
+ if (File.separatorChar != '/') {
+ canonicalPath =
+ canonicalPath.replace(File.separatorChar, '/');
+ }
+ } catch (Exception e) {
+ throw new BuildException("error trying to get the relative path"
+ + " from " + dir + " to " + fullPath,
+ e);
+ }
+
+ // No match, so bail out!
+ if (relPath.equals(canonicalPath)
+ || relPath.startsWith(tooLongPrefix)) {
+ throw new BuildException("No suitable relative path from "
+ + dir + " to " + fullPath);
+ }
+
+ if (pathEntry.isDirectory() && !relPath.endsWith("/")) {
+ relPath = relPath + '/';
+ }
+ try {
+ relPath = Locator.encodeURI(relPath);
+ } catch (UnsupportedEncodingException exc) {
+ throw new BuildException(exc);
+ }
+ // Manifest's ClassPath: attribute always uses forward
+ // slashes '/', and is space-separated. Ant will properly
+ // format it on 72 columns with proper line continuation
+ buffer.append(relPath);
+ buffer.append(' ');
+ }
+
+ // Finally assign the property with the manifest classpath
+ getProject().setNewProperty(name, buffer.toString().trim());
+ }
+
+ /**
+ * Sets the property name to hold the classpath value.
+ *
+ * @param name the property name
+ */
+ public void setProperty(String name) {
+ this.name = name;
+ }
+
+ /**
+ * The JAR file to contain the classpath attribute in its manifest.
+ *
+ * @param jarfile the JAR file. Need not exist yet, but its parent
+ * directory must exist on the other hand.
+ */
+ public void setJarFile(File jarfile) {
+ File parent = jarfile.getParentFile();
+ if (!parent.isDirectory()) {
+ throw new BuildException("Jar's directory not found: " + parent);
+ }
+ this.dir = parent;
+ }
+
+ /**
+ * Sets the maximum parent directory levels allowed when computing
+ * a relative path.
+ *
+ * @param levels the max level. Defaults to 2.
+ */
+ public void setMaxParentLevels(int levels) {
+ if (levels < 0) {
+ throw new BuildException("maxParentLevels must not be a negative"
+ + " number");
+ }
+ this.maxParentLevels = levels;
+ }
+
+ /**
+ * Adds the classpath to convert.
+ *
+ * @param path the classpath to convert.
+ */
+ public void addClassPath(Path path) {
+ this.path = path;
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/ManifestException.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/ManifestException.java
new file mode 100644
index 00000000..c4e72132
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/ManifestException.java
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs;
+
+/**
+ * Exception thrown indicating problems in a JAR Manifest
+ *
+ * @since Ant 1.4
+ */
+public class ManifestException extends Exception {
+
+ private static final long serialVersionUID = 7685634200457515207L;
+
+ /**
+ * Constructs an exception with the given descriptive message.
+ * @param msg Description of or information about the exception.
+ */
+ public ManifestException(String msg) {
+ super(msg);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/ManifestTask.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/ManifestTask.java
new file mode 100644
index 00000000..9b600db5
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/ManifestTask.java
@@ -0,0 +1,293 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.util.Enumeration;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.taskdefs.Manifest.Attribute;
+import org.apache.tools.ant.types.EnumeratedAttribute;
+import org.apache.tools.ant.util.FileUtils;
+
+/**
+ * Creates a manifest file for inclusion in a JAR, Ant task wrapper
+ * around {@link Manifest Manifest}. This task can be used to write a
+ * Manifest file, optionally replacing or updating an existing file.
+ *
+ * @since Ant 1.5
+ *
+ * @ant.task category="java"
+ */
+public class ManifestTask extends Task {
+
+ /**
+ * Specifies the valid characters which can be used in attribute names.
+ * {@value}
+ */
+ public static final String VALID_ATTRIBUTE_CHARS =
+ "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_";
+
+ /**
+ * Holds the real data.
+ */
+ private Manifest nestedManifest = new Manifest();
+
+ /**
+ * The file to which the manifest should be written when used as a task
+ */
+ private File manifestFile;
+
+ /**
+ * The mode with which the manifest file is written
+ */
+ private Mode mode;
+
+ /**
+ * The encoding of the manifest file
+ */
+ private String encoding;
+
+ /**
+ * whether to merge Class-Path attributes.
+ */
+ private boolean mergeClassPaths = false;
+
+ /**
+ * whether to flatten Class-Path attributes into a single one.
+ */
+ private boolean flattenClassPaths = false;
+
+ /**
+ * Helper class for Manifest's mode attribute.
+ */
+ public static class Mode extends EnumeratedAttribute {
+ /**
+ * Get Allowed values for the mode attribute.
+ *
+ * @return a String array of the allowed values.
+ */
+ public String[] getValues() {
+ return new String[] {"update", "replace"};
+ }
+ }
+
+ /**
+ * Default constructor
+ */
+ public ManifestTask() {
+ mode = new Mode();
+ mode.setValue("replace");
+ }
+
+ /**
+ * Add a section to the manifest
+ *
+ * @param section the manifest section to be added
+ *
+ * @exception ManifestException if the section is not valid.
+ */
+ public void addConfiguredSection(Manifest.Section section)
+ throws ManifestException {
+ Enumeration<String> attributeKeys = section.getAttributeKeys();
+ while (attributeKeys.hasMoreElements()) {
+ Attribute attribute = section.getAttribute(
+ attributeKeys.nextElement());
+ checkAttribute(attribute);
+ }
+ nestedManifest.addConfiguredSection(section);
+ }
+
+ /**
+ * Add an attribute to the manifest - it is added to the main section.
+ *
+ * @param attribute the attribute to be added.
+ *
+ * @exception ManifestException if the attribute is not valid.
+ */
+ public void addConfiguredAttribute(Manifest.Attribute attribute)
+ throws ManifestException {
+ checkAttribute(attribute);
+ nestedManifest.addConfiguredAttribute(attribute);
+ }
+
+ /**
+ * Checks the attribute against the Jar-specification.
+ *
+ * Jar-Specification <i>"Name-Value pairs and Sections"</i>: <pre>
+ * name: alphanum *headerchar
+ * alphanum: {A-Z} | {a-z} | {0-9}
+ * headerchar: alphanum | - | _
+ * </pre>
+ * So the resulting regexp would be <tt>[A-Za-z0-9][A-Za-z0-9-_]*</tt>.
+ *
+ * Because of JDK 1.2 compliance and the possible absence of a
+ * regexp matcher we can not use regexps here. Instead we have to
+ * check each character.
+ *
+ * @param attribute The attribute to check
+ * @throws BuildException if the check fails
+ */
+ private void checkAttribute(Manifest.Attribute attribute) throws BuildException {
+ String name = attribute.getName();
+ char ch = name.charAt(0);
+
+ if (ch == '-' || ch == '_') {
+ throw new BuildException("Manifest attribute names must not start with '" + ch + "'.");
+ }
+
+ for (int i = 0; i < name.length(); i++) {
+ ch = name.charAt(i);
+ if (VALID_ATTRIBUTE_CHARS.indexOf(ch) < 0) {
+ throw new BuildException("Manifest attribute names must not contain '" + ch + "'");
+ }
+ }
+ }
+
+ /**
+ * The name of the manifest file to create/update.
+ * Required if used as a task.
+ * @param f the Manifest file to be written
+ */
+ public void setFile(File f) {
+ manifestFile = f;
+ }
+
+ /**
+ * The encoding to use for reading in an existing manifest file
+ * @param encoding the manifest file encoding.
+ */
+ public void setEncoding(String encoding) {
+ this.encoding = encoding;
+ }
+
+ /**
+ * Update policy: either "update" or "replace"; default is "replace".
+ * @param m the mode value - update or replace.
+ */
+ public void setMode(Mode m) {
+ mode = m;
+ }
+
+ /**
+ * Whether to merge Class-Path attributes.
+ *
+ * @since Ant 1.8.0
+ */
+ public void setMergeClassPathAttributes(boolean b) {
+ mergeClassPaths = b;
+ }
+
+ /**
+ * Whether to flatten multi-valued attributes (i.e. Class-Path)
+ * into a single one.
+ *
+ * @since Ant 1.8.0
+ */
+ public void setFlattenAttributes(boolean b) {
+ flattenClassPaths = b;
+ }
+
+ /**
+ * Create or update the Manifest when used as a task.
+ *
+ * @throws BuildException if the manifest cannot be written.
+ */
+ public void execute() throws BuildException {
+ if (manifestFile == null) {
+ throw new BuildException("the file attribute is required");
+ }
+
+ Manifest toWrite = Manifest.getDefaultManifest();
+ Manifest current = null;
+ BuildException error = null;
+
+ if (manifestFile.exists()) {
+ FileInputStream fis = null;
+ InputStreamReader isr = null;
+ try {
+ fis = new FileInputStream(manifestFile);
+ if (encoding == null) {
+ isr = new InputStreamReader(fis, "UTF-8");
+ } else {
+ isr = new InputStreamReader(fis, encoding);
+ }
+ current = new Manifest(isr);
+ } catch (ManifestException m) {
+ error = new BuildException("Existing manifest " + manifestFile
+ + " is invalid", m, getLocation());
+ } catch (IOException e) {
+ error = new BuildException("Failed to read " + manifestFile,
+ e, getLocation());
+ } finally {
+ FileUtils.close(isr);
+ }
+ }
+
+ //look for and print warnings
+ for (Enumeration<String> e = nestedManifest.getWarnings();
+ e.hasMoreElements();) {
+ log("Manifest warning: " + e.nextElement(),
+ Project.MSG_WARN);
+ }
+ try {
+ if (mode.getValue().equals("update") && manifestFile.exists()) {
+ if (current != null) {
+ toWrite.merge(current, false, mergeClassPaths);
+ } else if (error != null) {
+ throw error;
+ }
+ }
+
+ toWrite.merge(nestedManifest, false, mergeClassPaths);
+ } catch (ManifestException m) {
+ throw new BuildException("Manifest is invalid", m, getLocation());
+ }
+
+ if (toWrite.equals(current)) {
+ log("Manifest has not changed, do not recreate",
+ Project.MSG_VERBOSE);
+ return;
+ }
+
+ PrintWriter w = null;
+ try {
+ FileOutputStream fos = new FileOutputStream(manifestFile);
+ OutputStreamWriter osw = new OutputStreamWriter(fos, Manifest.JAR_ENCODING);
+ w = new PrintWriter(osw);
+ toWrite.write(w, flattenClassPaths);
+ if (w.checkError()) {
+ throw new IOException("Encountered an error writing manifest");
+ }
+ } catch (IOException e) {
+ throw new BuildException("Failed to write " + manifestFile,
+ e, getLocation());
+ } finally {
+ FileUtils.close(w);
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/MatchingTask.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/MatchingTask.java
new file mode 100644
index 00000000..113ff5eb
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/MatchingTask.java
@@ -0,0 +1,446 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.io.File;
+import java.util.Enumeration;
+import java.util.StringTokenizer;
+
+import org.apache.tools.ant.DirectoryScanner;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.types.FileSet;
+import org.apache.tools.ant.types.PatternSet;
+import org.apache.tools.ant.types.selectors.AndSelector;
+import org.apache.tools.ant.types.selectors.ContainsRegexpSelector;
+import org.apache.tools.ant.types.selectors.ContainsSelector;
+import org.apache.tools.ant.types.selectors.DateSelector;
+import org.apache.tools.ant.types.selectors.DependSelector;
+import org.apache.tools.ant.types.selectors.DepthSelector;
+import org.apache.tools.ant.types.selectors.DifferentSelector;
+import org.apache.tools.ant.types.selectors.ExtendSelector;
+import org.apache.tools.ant.types.selectors.FileSelector;
+import org.apache.tools.ant.types.selectors.FilenameSelector;
+import org.apache.tools.ant.types.selectors.MajoritySelector;
+import org.apache.tools.ant.types.selectors.NoneSelector;
+import org.apache.tools.ant.types.selectors.NotSelector;
+import org.apache.tools.ant.types.selectors.OrSelector;
+import org.apache.tools.ant.types.selectors.PresentSelector;
+import org.apache.tools.ant.types.selectors.SelectSelector;
+import org.apache.tools.ant.types.selectors.SelectorContainer;
+import org.apache.tools.ant.types.selectors.SizeSelector;
+import org.apache.tools.ant.types.selectors.TypeSelector;
+import org.apache.tools.ant.types.selectors.modifiedselector.ModifiedSelector;
+
+/**
+ * This is an abstract task that should be used by all those tasks that
+ * require to include or exclude files based on pattern matching.
+ *
+ * @since Ant 1.1
+ */
+
+public abstract class MatchingTask extends Task implements SelectorContainer {
+
+ // CheckStyle:VisibilityModifier OFF - bc
+ protected FileSet fileset = new FileSet();
+ // CheckStyle:VisibilityModifier ON
+
+ /** {@inheritDoc}. */
+ public void setProject(Project project) {
+ super.setProject(project);
+ fileset.setProject(project);
+ }
+
+ /**
+ * add a name entry on the include list
+ * @return a NameEntry object to be configured
+ */
+ public PatternSet.NameEntry createInclude() {
+ return fileset.createInclude();
+ }
+
+ /**
+ * add a name entry on the include files list
+ * @return an NameEntry object to be configured
+ */
+ public PatternSet.NameEntry createIncludesFile() {
+ return fileset.createIncludesFile();
+ }
+
+ /**
+ * add a name entry on the exclude list
+ * @return an NameEntry object to be configured
+ */
+ public PatternSet.NameEntry createExclude() {
+ return fileset.createExclude();
+ }
+
+ /**
+ * add a name entry on the include files list
+ * @return an NameEntry object to be configured
+ */
+ public PatternSet.NameEntry createExcludesFile() {
+ return fileset.createExcludesFile();
+ }
+
+ /**
+ * add a set of patterns
+ * @return PatternSet object to be configured
+ */
+ public PatternSet createPatternSet() {
+ return fileset.createPatternSet();
+ }
+
+ /**
+ * Sets the set of include patterns. Patterns may be separated by a comma
+ * or a space.
+ *
+ * @param includes the string containing the include patterns
+ */
+ public void setIncludes(String includes) {
+ fileset.setIncludes(includes);
+ }
+
+ // CheckStyle:MethodNameCheck OFF - bc
+ /**
+ * Set this to be the items in the base directory that you want to be
+ * included. You can also specify "*" for the items (ie: items="*")
+ * and it will include all the items in the base directory.
+ *
+ * @param itemString the string containing the files to include.
+ */
+ public void XsetItems(String itemString) {
+ log("The items attribute is deprecated. "
+ + "Please use the includes attribute.", Project.MSG_WARN);
+ if (itemString == null || itemString.equals("*")
+ || itemString.equals(".")) {
+ createInclude().setName("**");
+ } else {
+ StringTokenizer tok = new StringTokenizer(itemString, ", ");
+ while (tok.hasMoreTokens()) {
+ String pattern = tok.nextToken().trim();
+ if (pattern.length() > 0) {
+ createInclude().setName(pattern + "/**");
+ }
+ }
+ }
+ }
+
+ /**
+ * Sets the set of exclude patterns. Patterns may be separated by a comma
+ * or a space.
+ *
+ * @param excludes the string containing the exclude patterns
+ */
+ public void setExcludes(String excludes) {
+ fileset.setExcludes(excludes);
+ }
+
+ /**
+ * List of filenames and directory names to not include. They should be
+ * either , or " " (space) separated. The ignored files will be logged.
+ *
+ * @param ignoreString the string containing the files to ignore.
+ */
+ public void XsetIgnore(String ignoreString) {
+ log("The ignore attribute is deprecated."
+ + "Please use the excludes attribute.", Project.MSG_WARN);
+ if (ignoreString != null && ignoreString.length() > 0) {
+ StringTokenizer tok = new StringTokenizer(ignoreString, ", ",
+ false);
+ while (tok.hasMoreTokens()) {
+ createExclude().setName("**/" + tok.nextToken().trim() + "/**");
+ }
+ }
+ }
+
+ // CheckStyle:VisibilityModifier ON
+
+ /**
+ * Sets whether default exclusions should be used or not.
+ *
+ * @param useDefaultExcludes "true"|"on"|"yes" when default exclusions
+ * should be used, "false"|"off"|"no" when they
+ * shouldn't be used.
+ */
+ public void setDefaultexcludes(boolean useDefaultExcludes) {
+ fileset.setDefaultexcludes(useDefaultExcludes);
+ }
+
+ /**
+ * Returns the directory scanner needed to access the files to process.
+ * @param baseDir the base directory to use with the fileset
+ * @return a directory scanner
+ */
+ protected DirectoryScanner getDirectoryScanner(File baseDir) {
+ fileset.setDir(baseDir);
+ return fileset.getDirectoryScanner(getProject());
+ }
+
+ /**
+ * Sets the name of the file containing the includes patterns.
+ *
+ * @param includesfile A string containing the filename to fetch
+ * the include patterns from.
+ */
+ public void setIncludesfile(File includesfile) {
+ fileset.setIncludesfile(includesfile);
+ }
+
+ /**
+ * Sets the name of the file containing the includes patterns.
+ *
+ * @param excludesfile A string containing the filename to fetch
+ * the include patterns from.
+ */
+ public void setExcludesfile(File excludesfile) {
+ fileset.setExcludesfile(excludesfile);
+ }
+
+ /**
+ * Sets case sensitivity of the file system
+ *
+ * @param isCaseSensitive "true"|"on"|"yes" if file system is case
+ * sensitive, "false"|"off"|"no" when not.
+ */
+ public void setCaseSensitive(boolean isCaseSensitive) {
+ fileset.setCaseSensitive(isCaseSensitive);
+ }
+
+ /**
+ * Sets whether or not symbolic links should be followed.
+ *
+ * @param followSymlinks whether or not symbolic links should be followed
+ */
+ public void setFollowSymlinks(boolean followSymlinks) {
+ fileset.setFollowSymlinks(followSymlinks);
+ }
+
+ /**
+ * Indicates whether there are any selectors here.
+ *
+ * @return whether any selectors are in this container
+ */
+ public boolean hasSelectors() {
+ return fileset.hasSelectors();
+ }
+
+ /**
+ * Gives the count of the number of selectors in this container
+ *
+ * @return the number of selectors in this container
+ */
+ public int selectorCount() {
+ return fileset.selectorCount();
+ }
+
+ /**
+ * Returns the set of selectors as an array.
+ * @param p the current project
+ * @return an array of selectors in this container
+ */
+ public FileSelector[] getSelectors(Project p) {
+ return fileset.getSelectors(p);
+ }
+
+ /**
+ * Returns an enumerator for accessing the set of selectors.
+ *
+ * @return an enumerator that goes through each of the selectors
+ */
+ public Enumeration<FileSelector> selectorElements() {
+ return fileset.selectorElements();
+ }
+
+ /**
+ * Add a new selector into this container.
+ *
+ * @param selector the new selector to add
+ */
+ public void appendSelector(FileSelector selector) {
+ fileset.appendSelector(selector);
+ }
+
+ /* Methods below all add specific selectors */
+
+ /**
+ * add a "Select" selector entry on the selector list
+ * @param selector the selector to add
+ */
+ public void addSelector(SelectSelector selector) {
+ fileset.addSelector(selector);
+ }
+
+ /**
+ * add an "And" selector entry on the selector list
+ * @param selector the selector to add
+ */
+ public void addAnd(AndSelector selector) {
+ fileset.addAnd(selector);
+ }
+
+ /**
+ * add an "Or" selector entry on the selector list
+ * @param selector the selector to add
+ */
+ public void addOr(OrSelector selector) {
+ fileset.addOr(selector);
+ }
+
+ /**
+ * add a "Not" selector entry on the selector list
+ * @param selector the selector to add
+ */
+ public void addNot(NotSelector selector) {
+ fileset.addNot(selector);
+ }
+
+ /**
+ * add a "None" selector entry on the selector list
+ * @param selector the selector to add
+ */
+ public void addNone(NoneSelector selector) {
+ fileset.addNone(selector);
+ }
+
+ /**
+ * add a majority selector entry on the selector list
+ * @param selector the selector to add
+ */
+ public void addMajority(MajoritySelector selector) {
+ fileset.addMajority(selector);
+ }
+
+ /**
+ * add a selector date entry on the selector list
+ * @param selector the selector to add
+ */
+ public void addDate(DateSelector selector) {
+ fileset.addDate(selector);
+ }
+
+ /**
+ * add a selector size entry on the selector list
+ * @param selector the selector to add
+ */
+ public void addSize(SizeSelector selector) {
+ fileset.addSize(selector);
+ }
+
+ /**
+ * add a selector filename entry on the selector list
+ * @param selector the selector to add
+ */
+ public void addFilename(FilenameSelector selector) {
+ fileset.addFilename(selector);
+ }
+
+ /**
+ * add an extended selector entry on the selector list
+ * @param selector the selector to add
+ */
+ public void addCustom(ExtendSelector selector) {
+ fileset.addCustom(selector);
+ }
+
+ /**
+ * add a contains selector entry on the selector list
+ * @param selector the selector to add
+ */
+ public void addContains(ContainsSelector selector) {
+ fileset.addContains(selector);
+ }
+
+ /**
+ * add a present selector entry on the selector list
+ * @param selector the selector to add
+ */
+ public void addPresent(PresentSelector selector) {
+ fileset.addPresent(selector);
+ }
+
+ /**
+ * add a depth selector entry on the selector list
+ * @param selector the selector to add
+ */
+ public void addDepth(DepthSelector selector) {
+ fileset.addDepth(selector);
+ }
+
+ /**
+ * add a depends selector entry on the selector list
+ * @param selector the selector to add
+ */
+ public void addDepend(DependSelector selector) {
+ fileset.addDepend(selector);
+ }
+
+ /**
+ * add a regular expression selector entry on the selector list
+ * @param selector the selector to add
+ */
+ public void addContainsRegexp(ContainsRegexpSelector selector) {
+ fileset.addContainsRegexp(selector);
+ }
+
+ /**
+ * add a type selector entry on the type list
+ * @param selector the selector to add
+ * @since ant 1.6
+ */
+ public void addDifferent(DifferentSelector selector) {
+ fileset.addDifferent(selector);
+ }
+
+ /**
+ * add a type selector entry on the type list
+ * @param selector the selector to add
+ * @since ant 1.6
+ */
+ public void addType(TypeSelector selector) {
+ fileset.addType(selector);
+ }
+
+ /**
+ * add the modified selector
+ * @param selector the selector to add
+ * @since ant 1.6
+ */
+ public void addModified(ModifiedSelector selector) {
+ fileset.addModified(selector);
+ }
+
+ /**
+ * add an arbitrary selector
+ * @param selector the selector to add
+ * @since Ant 1.6
+ */
+ public void add(FileSelector selector) {
+ fileset.add(selector);
+ }
+
+ /**
+ * Accessor for the implicit fileset.
+ * @return the implicit fileset
+ * @since Ant 1.5.2
+ */
+ protected final FileSet getImplicitFileSet() {
+ return fileset;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Mkdir.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Mkdir.java
new file mode 100644
index 00000000..71b6c94a
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Mkdir.java
@@ -0,0 +1,114 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.io.File;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+
+/**
+ * Creates a given directory.
+ * Creates a directory and any non-existent parent directories, when
+ * necessary
+ *
+ * @since Ant 1.1
+ *
+ * @ant.task category="filesystem"
+ */
+
+public class Mkdir extends Task {
+
+ private static final int MKDIR_RETRY_SLEEP_MILLIS = 10;
+ /**
+ * our little directory
+ */
+ private File dir;
+
+ /**
+ * create the directory and all parents
+ * @throws BuildException if dir is somehow invalid, or creation failed.
+ */
+ public void execute() throws BuildException {
+ if (dir == null) {
+ throw new BuildException("dir attribute is required", getLocation());
+ }
+
+ if (dir.isFile()) {
+ throw new BuildException("Unable to create directory as a file "
+ + "already exists with that name: "
+ + dir.getAbsolutePath());
+ }
+
+ if (!dir.exists()) {
+ boolean result = mkdirs(dir);
+ if (!result) {
+ if (dir.exists()) {
+ log("A different process or task has already created "
+ + "dir " + dir.getAbsolutePath(),
+ Project.MSG_VERBOSE);
+ return;
+ }
+ String msg = "Directory " + dir.getAbsolutePath()
+ + " creation was not successful for an unknown reason";
+ throw new BuildException(msg, getLocation());
+ }
+ log("Created dir: " + dir.getAbsolutePath());
+ } else {
+ log("Skipping " + dir.getAbsolutePath()
+ + " because it already exists.", Project.MSG_VERBOSE);
+ }
+ }
+
+ /**
+ * the directory to create; required.
+ *
+ * @param dir the directory to be made.
+ */
+ public void setDir(File dir) {
+ this.dir = dir;
+ }
+
+ /**
+ * Get the directory to create.
+ * @return File
+ */
+ public File getDir() {
+ return dir;
+ }
+
+ /**
+ * Attempt to fix possible race condition when creating
+ * directories on WinXP. If the mkdirs does not work,
+ * wait a little and try again.
+ */
+ private boolean mkdirs(File f) {
+ if (!f.mkdirs()) {
+ try {
+ Thread.sleep(MKDIR_RETRY_SLEEP_MILLIS);
+ return f.mkdirs();
+ } catch (InterruptedException ex) {
+ return f.mkdirs();
+ }
+ }
+ return true;
+ }
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Move.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Move.java
new file mode 100644
index 00000000..7f5d9680
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Move.java
@@ -0,0 +1,382 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Iterator;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.DirectoryScanner;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.condition.Os;
+import org.apache.tools.ant.types.FileSet;
+import org.apache.tools.ant.types.FilterSet;
+import org.apache.tools.ant.types.FilterSetCollection;
+
+/**
+ * Moves a file or directory to a new file or directory.
+ * By default, the
+ * destination file is overwritten if it already exists.
+ * When <i>overwrite</i> is
+ * turned off, then files are only moved if the source file is
+ * newer than the destination file, or when the destination file does
+ * not exist.
+ *
+ * <p>Source files and directories are only deleted when the file or
+ * directory has been copied to the destination successfully. Filtering
+ * also works.</p>
+ *
+ * <p>This implementation is based on Arnout Kuiper's initial design
+ * document, the following mailing list discussions, and the
+ * copyfile/copydir tasks.</p>
+ *
+ * @since Ant 1.2
+ *
+ * @ant.task category="filesystem"
+ */
+public class Move extends Copy {
+
+ private boolean performGc = Os.isFamily("windows");
+
+ /**
+ * Constructor of object.
+ * This sets the forceOverwrite attribute of the Copy parent class
+ * to true.
+ *
+ */
+ public Move() {
+ super();
+ setOverwrite(true);
+ }
+
+ /**
+ * Whether to perform a garbage collection before retrying a failed delete.
+ *
+ * <p>This may be required on Windows (where it is set to true by
+ * default) but also on other operating systems, for example when
+ * deleting directories from an NFS share.</p>
+ *
+ * @since Ant 1.8.3
+ */
+ public void setPerformGcOnFailedDelete(boolean b) {
+ performGc = b;
+ }
+
+ /** {@inheritDoc}. */
+ protected void validateAttributes() throws BuildException {
+ if (file != null && file.isDirectory()) {
+ if ((destFile != null && destDir != null)
+ || (destFile == null && destDir == null)) {
+ throw new BuildException("One and only one of tofile and todir must be set.");
+ }
+ destFile = destFile == null ? new File(destDir, file.getName()) : destFile;
+ destDir = destDir == null ? destFile.getParentFile() : destDir;
+
+ completeDirMap.put(file, destFile);
+ file = null;
+ } else {
+ super.validateAttributes();
+ }
+ }
+
+//************************************************************************
+// protected and private methods
+//************************************************************************
+
+ /**
+ * Override copy's doFileOperations to move the files instead of copying them.
+ */
+ protected void doFileOperations() {
+ //Attempt complete directory renames, if any, first.
+ if (completeDirMap.size() > 0) {
+ for (Iterator fromDirs = completeDirMap.keySet().iterator(); fromDirs.hasNext();) {
+ File fromDir = (File) fromDirs.next();
+ File toDir = (File) completeDirMap.get(fromDir);
+ boolean renamed = false;
+ try {
+ log("Attempting to rename dir: " + fromDir + " to " + toDir, verbosity);
+ renamed = renameFile(fromDir, toDir, filtering, forceOverwrite);
+ } catch (IOException ioe) {
+ String msg = "Failed to rename dir " + fromDir
+ + " to " + toDir + " due to " + ioe.getMessage();
+ throw new BuildException(msg, ioe, getLocation());
+ }
+ if (!renamed) {
+ FileSet fs = new FileSet();
+ fs.setProject(getProject());
+ fs.setDir(fromDir);
+ addFileset(fs);
+ DirectoryScanner ds = fs.getDirectoryScanner(getProject());
+ String[] files = ds.getIncludedFiles();
+ String[] dirs = ds.getIncludedDirectories();
+ scan(fromDir, toDir, files, dirs);
+ }
+ }
+ }
+ int moveCount = fileCopyMap.size();
+ if (moveCount > 0) { // files to move
+ log("Moving " + moveCount + " file" + ((moveCount == 1) ? "" : "s")
+ + " to " + destDir.getAbsolutePath());
+
+ for (Iterator fromFiles = fileCopyMap.keySet().iterator(); fromFiles.hasNext();) {
+ String fromFile = (String) fromFiles.next();
+ File f = new File(fromFile);
+ boolean selfMove = false;
+ if (f.exists()) { //Is this file still available to be moved?
+ String[] toFiles = (String[]) fileCopyMap.get(fromFile);
+ for (int i = 0; i < toFiles.length; i++) {
+ String toFile = (String) toFiles[i];
+
+ if (fromFile.equals(toFile)) {
+ log("Skipping self-move of " + fromFile, verbosity);
+ selfMove = true;
+
+ // if this is the last time through the loop then
+ // move will not occur, but that's what we want
+ continue;
+ }
+ File d = new File(toFile);
+ if ((i + 1) == toFiles.length && !selfMove) {
+ // Only try to move if this is the last mapped file
+ // and one of the mappings isn't to itself
+ moveFile(f, d, filtering, forceOverwrite);
+ } else {
+ copyFile(f, d, filtering, forceOverwrite);
+ }
+ }
+ }
+ }
+ }
+
+ if (includeEmpty) {
+ int createCount = 0;
+ for (Iterator fromDirNames = dirCopyMap.keySet().iterator(); fromDirNames.hasNext();) {
+ String fromDirName = (String) fromDirNames.next();
+ String[] toDirNames = (String[]) dirCopyMap.get(fromDirName);
+ boolean selfMove = false;
+ for (int i = 0; i < toDirNames.length; i++) {
+ if (fromDirName.equals(toDirNames[i])) {
+ log("Skipping self-move of " + fromDirName, verbosity);
+ selfMove = true;
+ continue;
+ }
+ File d = new File(toDirNames[i]);
+ if (!d.exists()) {
+ if (!(d.mkdirs() || d.exists())) {
+ log("Unable to create directory "
+ + d.getAbsolutePath(), Project.MSG_ERR);
+ } else {
+ createCount++;
+ }
+ }
+ }
+ File fromDir = new File(fromDirName);
+ if (!selfMove && okToDelete(fromDir)) {
+ deleteDir(fromDir);
+ }
+ }
+ if (createCount > 0) {
+ log("Moved " + dirCopyMap.size()
+ + " empty director"
+ + (dirCopyMap.size() == 1 ? "y" : "ies")
+ + " to " + createCount
+ + " empty director"
+ + (createCount == 1 ? "y" : "ies") + " under "
+ + destDir.getAbsolutePath());
+ }
+ }
+ }
+
+ /**
+ * Try to move the file via a rename, but if this fails or filtering
+ * is enabled, copy the file then delete the sourceFile.
+ */
+ private void moveFile(File fromFile, File toFile, boolean filtering, boolean overwrite) {
+ boolean moved = false;
+ try {
+ log("Attempting to rename: " + fromFile + " to " + toFile, verbosity);
+ moved = renameFile(fromFile, toFile, filtering, forceOverwrite);
+ } catch (IOException ioe) {
+ String msg = "Failed to rename " + fromFile
+ + " to " + toFile + " due to " + ioe.getMessage();
+ throw new BuildException(msg, ioe, getLocation());
+ }
+
+ if (!moved) {
+ copyFile(fromFile, toFile, filtering, overwrite);
+ if (!getFileUtils().tryHardToDelete(fromFile, performGc)) {
+ throw new BuildException("Unable to delete " + "file "
+ + fromFile.getAbsolutePath());
+ }
+ }
+ }
+
+ /**
+ * Copy fromFile to toFile.
+ * @param fromFile
+ * @param toFile
+ * @param filtering
+ * @param overwrite
+ */
+ private void copyFile(File fromFile, File toFile, boolean filtering, boolean overwrite) {
+ try {
+ log("Copying " + fromFile + " to " + toFile, verbosity);
+
+ FilterSetCollection executionFilters = new FilterSetCollection();
+ if (filtering) {
+ executionFilters.addFilterSet(getProject().getGlobalFilterSet());
+ }
+ for (Iterator filterIter = getFilterSets().iterator(); filterIter.hasNext();) {
+ executionFilters.addFilterSet((FilterSet) filterIter.next());
+ }
+ getFileUtils().copyFile(fromFile, toFile, executionFilters,
+ getFilterChains(),
+ forceOverwrite,
+ getPreserveLastModified(),
+ /* append: */ false,
+ getEncoding(),
+ getOutputEncoding(),
+ getProject(), getForce());
+ } catch (IOException ioe) {
+ String msg = "Failed to copy " + fromFile
+ + " to " + toFile + " due to " + ioe.getMessage();
+ throw new BuildException(msg, ioe, getLocation());
+ }
+ }
+
+ /**
+ * Its only ok to delete a directory tree if there are no files in it.
+ * @param d the directory to check
+ * @return true if a deletion can go ahead
+ */
+ protected boolean okToDelete(File d) {
+ String[] list = d.list();
+ if (list == null) {
+ return false;
+ } // maybe io error?
+
+ for (int i = 0; i < list.length; i++) {
+ String s = list[i];
+ File f = new File(d, s);
+ if (f.isDirectory()) {
+ if (!okToDelete(f)) {
+ return false;
+ }
+ } else {
+ return false; // found a file
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Go and delete the directory tree.
+ * @param d the directory to delete
+ */
+ protected void deleteDir(File d) {
+ deleteDir(d, false);
+ }
+
+ /**
+ * Go and delete the directory tree.
+ * @param d the directory to delete
+ * @param deleteFiles whether to delete files
+ */
+ protected void deleteDir(File d, boolean deleteFiles) {
+ String[] list = d.list();
+ if (list == null) {
+ return;
+ } // on an io error list() can return null
+
+ for (int i = 0; i < list.length; i++) {
+ String s = list[i];
+ File f = new File(d, s);
+ if (f.isDirectory()) {
+ deleteDir(f);
+ } else if (deleteFiles && !getFileUtils().tryHardToDelete(f,
+ performGc)) {
+ throw new BuildException("Unable to delete file " + f.getAbsolutePath());
+ } else {
+ throw new BuildException("UNEXPECTED ERROR - The file "
+ + f.getAbsolutePath() + " should not exist!");
+ }
+ }
+ log("Deleting directory " + d.getAbsolutePath(), verbosity);
+ if (!getFileUtils().tryHardToDelete(d, performGc)) {
+ throw new BuildException("Unable to delete directory " + d.getAbsolutePath());
+ }
+ }
+
+ /**
+ * Attempts to rename a file from a source to a destination.
+ * If overwrite is set to true, this method overwrites existing file
+ * even if the destination file is newer. Otherwise, the source file is
+ * renamed only if the destination file is older than it.
+ * Method then checks if token filtering is used. If it is, this method
+ * returns false assuming it is the responsibility to the copyFile method.
+ *
+ * @param sourceFile the file to rename
+ * @param destFile the destination file
+ * @param filtering if true, filtering is in operation, file will
+ * be copied/deleted instead of renamed
+ * @param overwrite if true force overwrite even if destination file
+ * is newer than source file
+ * @return true if the file was renamed
+ * @exception IOException if an error occurs
+ * @exception BuildException if an error occurs
+ */
+ protected boolean renameFile(File sourceFile, File destFile, boolean filtering,
+ boolean overwrite) throws IOException, BuildException {
+ if (destFile.isDirectory() || filtering || getFilterSets().size() > 0
+ || getFilterChains().size() > 0) {
+ return false;
+ }
+
+ // identical logic lives in ResourceUtils.copyResource():
+ if (destFile.isFile() && !destFile.canWrite()) {
+ if (!getForce()) {
+ throw new IOException("can't replace read-only destination "
+ + "file " + destFile);
+ } else if (!getFileUtils().tryHardToDelete(destFile)) {
+ throw new IOException("failed to delete read-only "
+ + "destination file " + destFile);
+ }
+ }
+
+ // identical logic lives in FileUtils.rename():
+ File parent = destFile.getParentFile();
+ if (parent != null && !parent.exists()) {
+ parent.mkdirs();
+ } else if (destFile.isFile()) {
+ sourceFile = getFileUtils().normalize(sourceFile.getAbsolutePath()).getCanonicalFile();
+ destFile = getFileUtils().normalize(destFile.getAbsolutePath());
+ if (destFile.getAbsolutePath().equals(sourceFile.getAbsolutePath())) {
+ //no point in renaming a file to its own canonical version...
+ log("Rename of " + sourceFile + " to " + destFile
+ + " is a no-op.", Project.MSG_VERBOSE);
+ return true;
+ }
+ if (!(getFileUtils().areSame(sourceFile, destFile)
+ || getFileUtils().tryHardToDelete(destFile, performGc))) {
+ throw new BuildException("Unable to remove existing file " + destFile);
+ }
+ }
+ return sourceFile.renameTo(destFile);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Nice.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Nice.java
new file mode 100644
index 00000000..5898caee
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Nice.java
@@ -0,0 +1,99 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+
+/**
+ * A task to provide "nice-ness" to the current thread, and/or to
+ * query the current value.
+ * Examples:
+ * <pre> &lt;nice currentPriority="current.value" &gt;</pre><p>
+ * Set <code>currentPriority</code> to the current priority
+ * <pre> &lt;nice newPriority="10" &gt;</pre><p>
+ * Raise the priority of the build process (But not forked programs)
+ * <pre> &lt;nice currentPriority="old" newPriority="3" &gt;</pre><p>
+ * Lower the priority of the build process (But not forked programs), and save
+ * the old value to the property <code>old</code>.
+ *
+ * @ant.task name="nice" category="control"
+ */
+public class Nice extends Task {
+
+ /**
+ * the new priority
+ */
+ private Integer newPriority;
+
+ /**
+ * the current priority
+ */
+ private String currentPriority;
+
+
+
+ /**
+ * Execute the task
+ * @exception BuildException if something goes wrong with the build
+ */
+ public void execute() throws BuildException {
+
+ Thread self = Thread.currentThread();
+ int priority = self.getPriority();
+ if (currentPriority != null) {
+ String current = Integer.toString(priority);
+ getProject().setNewProperty(currentPriority, current);
+ }
+ //if there is a new priority, and it is different, change it
+ if (newPriority != null && priority != newPriority.intValue()) {
+ try {
+ self.setPriority(newPriority.intValue());
+ } catch (SecurityException e) {
+ //catch permissions denial and keep going
+ log("Unable to set new priority -a security manager is in the way",
+ Project.MSG_WARN);
+ } catch (IllegalArgumentException iae) {
+ throw new BuildException("Priority out of range", iae);
+ }
+ }
+ }
+
+ /**
+ * The name of a property to set to the value of the current
+ * thread priority. Optional
+ * @param currentPriority the property name.
+ */
+ public void setCurrentPriority(String currentPriority) {
+ this.currentPriority = currentPriority;
+ }
+
+ /**
+ * the new priority, in the range 1-10.
+ * @param newPriority the new priority value.
+ */
+ public void setNewPriority(int newPriority) {
+ if (newPriority < Thread.MIN_PRIORITY || newPriority > Thread.MAX_PRIORITY) {
+ throw new BuildException("The thread priority is out of the range 1-10");
+ }
+ this.newPriority = new Integer(newPriority);
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Pack.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Pack.java
new file mode 100644
index 00000000..daabd6ba
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Pack.java
@@ -0,0 +1,212 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.ResourceCollection;
+import org.apache.tools.ant.types.resources.FileProvider;
+import org.apache.tools.ant.types.resources.FileResource;
+
+/**
+ * Abstract Base class for pack tasks.
+ *
+ * @since Ant 1.5
+ */
+
+public abstract class Pack extends Task {
+ private static final int BUFFER_SIZE = 8 * 1024;
+ // CheckStyle:VisibilityModifier OFF - bc
+ protected File zipFile;
+ protected File source;
+ // CheckStyle:VisibilityModifier ON
+ private Resource src;
+
+ /**
+ * the required destination file.
+ * @param zipFile the destination file
+ */
+ public void setZipfile(File zipFile) {
+ this.zipFile = zipFile;
+ }
+
+ /**
+ * the required destination file.
+ * @param zipFile the destination file
+ */
+ public void setDestfile(File zipFile) {
+ setZipfile(zipFile);
+ }
+
+ /**
+ * the file to compress; required.
+ * @param src the source file
+ */
+ public void setSrc(File src) {
+ setSrcResource(new FileResource(src));
+ }
+
+ /**
+ * The resource to pack; required.
+ * @param src resource to expand
+ */
+ public void setSrcResource(Resource src) {
+ if (src.isDirectory()) {
+ throw new BuildException("the source can't be a directory");
+ }
+ FileProvider fp = src.as(FileProvider.class);
+ if (fp != null) {
+ source = fp.getFile();
+ } else if (!supportsNonFileResources()) {
+ throw new BuildException("Only FileSystem resources are supported.");
+ }
+ this.src = src;
+ }
+
+ /**
+ * Set the source resource.
+ * @param a the resource to pack as a single element Resource collection.
+ */
+ public void addConfigured(ResourceCollection a) {
+ if (a.size() == 0) {
+ throw new BuildException("No resource selected, " + getTaskName()
+ + " needs exactly one resource.");
+ }
+ if (a.size() != 1) {
+ throw new BuildException(getTaskName()
+ + " cannot handle multiple resources at once. (" + a.size()
+ + " resources were selected.)");
+ }
+ setSrcResource(a.iterator().next());
+ }
+
+ /**
+ * validation routine
+ * @throws BuildException if anything is invalid
+ */
+ private void validate() throws BuildException {
+ if (zipFile == null) {
+ throw new BuildException("zipfile attribute is required", getLocation());
+ }
+
+ if (zipFile.isDirectory()) {
+ throw new BuildException("zipfile attribute must not "
+ + "represent a directory!", getLocation());
+ }
+
+ if (getSrcResource() == null) {
+ throw new BuildException("src attribute or nested resource is"
+ + " required", getLocation());
+ }
+ }
+
+ /**
+ * validate, then hand off to the subclass
+ * @throws BuildException on error
+ */
+ public void execute() throws BuildException {
+ validate();
+
+ Resource s = getSrcResource();
+ if (!s.isExists()) {
+ log("Nothing to do: " + s.toString()
+ + " doesn't exist.");
+ } else if (zipFile.lastModified() < s.getLastModified()) {
+ log("Building: " + zipFile.getAbsolutePath());
+ pack();
+ } else {
+ log("Nothing to do: " + zipFile.getAbsolutePath()
+ + " is up to date.");
+ }
+ }
+
+ /**
+ * zip a stream to an output stream
+ * @param in the stream to zip
+ * @param zOut the output stream
+ * @throws IOException
+ */
+ private void zipFile(InputStream in, OutputStream zOut)
+ throws IOException {
+ byte[] buffer = new byte[BUFFER_SIZE];
+ int count = 0;
+ do {
+ zOut.write(buffer, 0, count);
+ count = in.read(buffer, 0, buffer.length);
+ } while (count != -1);
+ }
+
+ /**
+ * zip a file to an output stream
+ * @param file the file to zip
+ * @param zOut the output stream
+ * @throws IOException on error
+ */
+ protected void zipFile(File file, OutputStream zOut)
+ throws IOException {
+ zipResource(new FileResource(file), zOut);
+ }
+
+ /**
+ * zip a resource to an output stream
+ * @param resource the resource to zip
+ * @param zOut the output stream
+ * @throws IOException on error
+ */
+ protected void zipResource(Resource resource, OutputStream zOut)
+ throws IOException {
+ InputStream rIn = resource.getInputStream();
+ try {
+ zipFile(rIn, zOut);
+ } finally {
+ rIn.close();
+ }
+ }
+
+ /**
+ * subclasses must implement this method to do their compression
+ */
+ protected abstract void pack();
+
+ /**
+ * The source resource.
+ * @return the source.
+ * @since Ant 1.7
+ */
+ public Resource getSrcResource() {
+ return src;
+ }
+
+ /**
+ * Whether this task can deal with non-file resources.
+ *
+ * <p>This implementation returns false.</p>
+ * @return false.
+ * @since Ant 1.7
+ */
+ protected boolean supportsNonFileResources() {
+ return false;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Parallel.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Parallel.java
new file mode 100644
index 00000000..c4f5c9e9
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Parallel.java
@@ -0,0 +1,489 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs;
+
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.ExitStatusException;
+import org.apache.tools.ant.Location;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.TaskContainer;
+import org.apache.tools.ant.property.LocalProperties;
+import org.apache.tools.ant.util.StringUtils;
+
+/**
+ * Executes the contained tasks in separate threads, continuing
+ * once all are completed.
+ * <p>
+ * New behavior allows for the ant script to specify a maximum number of
+ * threads that will be executed in parallel. One should be very careful about
+ * using the <code>waitFor</code> task when specifying <code>threadCount</code>
+ * as it can cause deadlocks if the number of threads is too small or if one of
+ * the nested tasks fails to execute completely. The task selection algorithm
+ * will insure that the tasks listed before a task have started before that
+ * task is started, but it will not insure a successful completion of those
+ * tasks or that those tasks will finish first (i.e. it's a classic race
+ * condition).
+ * </p>
+ * @since Ant 1.4
+ *
+ * @ant.task category="control"
+ */
+public class Parallel extends Task
+ implements TaskContainer {
+
+ private static final int NUMBER_TRIES = 100;
+
+ /** Class which holds a list of tasks to execute */
+ public static class TaskList implements TaskContainer {
+ /** Collection holding the nested tasks */
+ private List tasks = new ArrayList();
+
+ /**
+ * Add a nested task to execute parallel (asynchron).
+ * <p>
+ * @param nestedTask Nested task to be executed in parallel.
+ * must not be null.
+ */
+ public void addTask(Task nestedTask) {
+ tasks.add(nestedTask);
+ }
+ }
+
+ /** Collection holding the nested tasks */
+ private Vector nestedTasks = new Vector();
+
+ /** Semaphore to notify of completed threads */
+ private final Object semaphore = new Object();
+
+ /** Total number of threads to run */
+ private int numThreads = 0;
+
+ /** Total number of threads per processor to run. */
+ private int numThreadsPerProcessor = 0;
+
+ /** The timeout period in milliseconds */
+ private long timeout;
+
+ /** Indicates threads are still running and new threads can be issued */
+ private volatile boolean stillRunning;
+
+ /** Indicates that the execution timedout */
+ private boolean timedOut;
+
+ /**
+ * Indicates whether failure of any of the nested tasks should end
+ * execution
+ */
+ private boolean failOnAny;
+
+ /** The dameon task list if any */
+ private TaskList daemonTasks;
+
+ /** Accumulation of exceptions messages from all nested tasks */
+ private StringBuffer exceptionMessage;
+
+ /** Number of exceptions from nested tasks */
+ private int numExceptions = 0;
+
+ /** The first exception encountered */
+ private Throwable firstException;
+
+ /** The location of the first exception */
+ private Location firstLocation;
+
+ /** The status of the first ExitStatusException. */
+ private Integer firstExitStatus;
+
+ /**
+ * Add a group of daemon threads
+ * @param daemonTasks The tasks to be executed as daemon.
+ */
+ public void addDaemons(TaskList daemonTasks) {
+ if (this.daemonTasks != null) {
+ throw new BuildException("Only one daemon group is supported");
+ }
+ this.daemonTasks = daemonTasks;
+ }
+
+ /**
+ * Interval to poll for completed threads when threadCount or
+ * threadsPerProcessor is specified. Integer in milliseconds.; optional
+ *
+ * @param pollInterval New value of property pollInterval.
+ */
+ public void setPollInterval(int pollInterval) {
+ }
+
+ /**
+ * Control whether a failure in a nested task halts execution. Note that
+ * the task will complete but existing threads will continue to run - they
+ * are not stopped
+ *
+ * @param failOnAny if true any nested task failure causes parallel to
+ * complete.
+ */
+ public void setFailOnAny(boolean failOnAny) {
+ this.failOnAny = failOnAny;
+ }
+
+ /**
+ * Add a nested task to execute in parallel.
+ * @param nestedTask Nested task to be executed in parallel
+ */
+ public void addTask(Task nestedTask) {
+ nestedTasks.addElement(nestedTask);
+ }
+
+ /**
+ * Dynamically generates the number of threads to execute based on the
+ * number of available processors (via
+ * <code>java.lang.Runtime.availableProcessors()</code>).
+ * Will overwrite the value set in threadCount; optional
+ * @param numThreadsPerProcessor Number of threads to create per available
+ * processor.
+ *
+ */
+ public void setThreadsPerProcessor(int numThreadsPerProcessor) {
+ this.numThreadsPerProcessor = numThreadsPerProcessor;
+ }
+
+ /**
+ * Statically determine the maximum number of tasks to execute
+ * simultaneously. If there are less tasks than threads then all will be
+ * executed at once, if there are more then only <code>threadCount</code>
+ * tasks will be executed at one time. If <code>threadsPerProcessor</code>
+ * is set then this value is
+ * ignored.; optional
+ *
+ * @param numThreads total number of threads.
+ *
+ */
+ public void setThreadCount(int numThreads) {
+ this.numThreads = numThreads;
+ }
+
+ /**
+ * Sets the timeout on this set of tasks. If the timeout is reached
+ * before the other threads complete, the execution of this
+ * task completes with an exception.
+ *
+ * Note that existing threads continue to run.
+ *
+ * @param timeout timeout in milliseconds.
+ */
+ public void setTimeout(long timeout) {
+ this.timeout = timeout;
+ }
+
+
+
+ /**
+ * Execute the parallel tasks
+ *
+ * @exception BuildException if any of the threads failed.
+ */
+ public void execute() throws BuildException {
+ updateThreadCounts();
+ if (numThreads == 0) {
+ numThreads = nestedTasks.size();
+ }
+ spinThreads();
+ }
+
+ /**
+ * Determine the number of threads based on the number of processors
+ */
+ private void updateThreadCounts() {
+ if (numThreadsPerProcessor != 0) {
+ numThreads = Runtime.getRuntime().availableProcessors() *
+ numThreadsPerProcessor;
+ }
+ }
+
+ private void processExceptions(TaskRunnable[] runnables) {
+ if (runnables == null) {
+ return;
+ }
+ for (int i = 0; i < runnables.length; ++i) {
+ Throwable t = runnables[i].getException();
+ if (t != null) {
+ numExceptions++;
+ if (firstException == null) {
+ firstException = t;
+ }
+ if (t instanceof BuildException
+ && firstLocation == Location.UNKNOWN_LOCATION) {
+ firstLocation = ((BuildException) t).getLocation();
+ }
+ if (t instanceof ExitStatusException
+ && firstExitStatus == null) {
+ ExitStatusException ex = (ExitStatusException) t;
+ firstExitStatus = ex.getStatus();
+ // potentially overwriting existing value but the
+ // location should match the exit status
+ firstLocation = ex.getLocation();
+ }
+ exceptionMessage.append(StringUtils.LINE_SEP);
+ exceptionMessage.append(t.getMessage());
+ }
+ }
+ }
+
+ /**
+ * Spin up required threads with a maximum number active at any given time.
+ *
+ * @exception BuildException if any of the threads failed.
+ */
+ private void spinThreads() throws BuildException {
+ final int numTasks = nestedTasks.size();
+ TaskRunnable[] runnables = new TaskRunnable[numTasks];
+ stillRunning = true;
+ timedOut = false;
+ boolean interrupted = false;
+
+ int threadNumber = 0;
+ for (Enumeration e = nestedTasks.elements(); e.hasMoreElements();
+ threadNumber++) {
+ Task nestedTask = (Task) e.nextElement();
+ runnables[threadNumber]
+ = new TaskRunnable(nestedTask);
+ }
+
+ final int maxRunning = numTasks < numThreads ? numTasks : numThreads;
+ TaskRunnable[] running = new TaskRunnable[maxRunning];
+
+ threadNumber = 0;
+ ThreadGroup group = new ThreadGroup("parallel");
+
+ TaskRunnable[] daemons = null;
+ if (daemonTasks != null && daemonTasks.tasks.size() != 0) {
+ daemons = new TaskRunnable[daemonTasks.tasks.size()];
+ }
+
+ synchronized (semaphore) {
+ // When we leave this block we can be sure all data is really
+ // stored in main memory before the new threads start, the new
+ // threads will for sure load the data from main memory.
+ //
+ // This probably is slightly paranoid.
+ }
+
+ synchronized (semaphore) {
+ // start any daemon threads
+ if (daemons != null) {
+ for (int i = 0; i < daemons.length; ++i) {
+ daemons[i] = new TaskRunnable((Task) daemonTasks.tasks.get(i));
+ Thread daemonThread = new Thread(group, daemons[i]);
+ daemonThread.setDaemon(true);
+ daemonThread.start();
+ }
+ }
+
+ // now run main threads in limited numbers...
+ // start initial batch of threads
+ for (int i = 0; i < maxRunning; ++i) {
+ running[i] = runnables[threadNumber++];
+ Thread thread = new Thread(group, running[i]);
+ thread.start();
+ }
+
+ if (timeout != 0) {
+ // start the timeout thread
+ Thread timeoutThread = new Thread() {
+ public synchronized void run() {
+ try {
+ wait(timeout);
+ synchronized (semaphore) {
+ stillRunning = false;
+ timedOut = true;
+ semaphore.notifyAll();
+ }
+ } catch (InterruptedException e) {
+ // ignore
+ }
+ }
+ };
+ timeoutThread.start();
+ }
+
+ try {
+ // now find available running slots for the remaining threads
+ outer: while (threadNumber < numTasks && stillRunning) {
+ for (int i = 0; i < maxRunning; i++) {
+ if (running[i] == null || running[i].isFinished()) {
+ running[i] = runnables[threadNumber++];
+ Thread thread = new Thread(group, running[i]);
+ thread.start();
+ // continue on outer while loop to get another
+ // available slot
+ continue outer;
+ }
+ }
+
+ // if we got here all slots in use, so sleep until
+ // something happens
+ semaphore.wait();
+ }
+
+ // are all threads finished
+ outer2: while (stillRunning) {
+ for (int i = 0; i < maxRunning; ++i) {
+ if (running[i] != null && !running[i].isFinished()) {
+ // System.out.println("Thread " + i + " is still
+ // alive ");
+ // still running - wait for it
+ semaphore.wait();
+ continue outer2;
+ }
+ }
+ stillRunning = false;
+ }
+ } catch (InterruptedException ie) {
+ interrupted = true;
+ }
+
+ if (!timedOut && !failOnAny) {
+ // https://issues.apache.org/bugzilla/show_bug.cgi?id=49527
+ killAll(running);
+ }
+ }
+
+ if (interrupted) {
+ throw new BuildException("Parallel execution interrupted.");
+ }
+ if (timedOut) {
+ throw new BuildException("Parallel execution timed out");
+ }
+
+ // now did any of the threads throw an exception
+ exceptionMessage = new StringBuffer();
+ numExceptions = 0;
+ firstException = null;
+ firstExitStatus = null;
+ firstLocation = Location.UNKNOWN_LOCATION;
+ processExceptions(daemons);
+ processExceptions(runnables);
+
+ if (numExceptions == 1) {
+ if (firstException instanceof BuildException) {
+ throw (BuildException) firstException;
+ } else {
+ throw new BuildException(firstException);
+ }
+ } else if (numExceptions > 1) {
+ if (firstExitStatus == null) {
+ throw new BuildException(exceptionMessage.toString(),
+ firstLocation);
+ } else {
+ throw new ExitStatusException(exceptionMessage.toString(),
+ firstExitStatus, firstLocation);
+ }
+ }
+ }
+
+ /**
+ * Doesn't do anything if all threads where already gone,
+ * else it tries to interrupt the threads 100 times.
+ * @param running The list of tasks that may currently be running.
+ */
+ private void killAll(TaskRunnable[] running) {
+ boolean oneAlive;
+ int tries = 0;
+ do {
+ oneAlive = false;
+ for (int i = 0; i < running.length; i++) {
+ if (running[i] != null && !running[i].isFinished()) {
+ running[i].interrupt();
+ Thread.yield();
+ oneAlive = true;
+ }
+ }
+ if (oneAlive) {
+ tries++;
+ Thread.yield();
+ }
+ } while (oneAlive && tries < NUMBER_TRIES);
+ }
+
+ /**
+ * thread that execs a task
+ */
+ private class TaskRunnable implements Runnable {
+ private Throwable exception;
+ private Task task;
+ private boolean finished;
+ private volatile Thread thread;
+
+ /**
+ * Construct a new TaskRunnable.<p>
+ *
+ * @param task the Task to be executed in a separate thread
+ */
+ TaskRunnable(Task task) {
+ this.task = task;
+ }
+
+ /**
+ * Executes the task within a thread and takes care about
+ * Exceptions raised within the task.
+ */
+ public void run() {
+ try {
+ LocalProperties.get(getProject()).copy();
+ thread = Thread.currentThread();
+ task.perform();
+ } catch (Throwable t) {
+ exception = t;
+ if (failOnAny) {
+ stillRunning = false;
+ }
+ } finally {
+ synchronized (semaphore) {
+ finished = true;
+ semaphore.notifyAll();
+ }
+ }
+ }
+
+ /**
+ * get any exception that got thrown during execution;
+ * @return an exception or null for no exception/not yet finished
+ */
+ public Throwable getException() {
+ return exception;
+ }
+
+ /**
+ * Provides the indicator that the task has been finished.
+ * @return Returns true when the task is finished.
+ */
+ boolean isFinished() {
+ return finished;
+ }
+
+ void interrupt() {
+ thread.interrupt();
+ }
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Patch.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Patch.java
new file mode 100644
index 00000000..96ab0823
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Patch.java
@@ -0,0 +1,215 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.types.Commandline;
+
+/**
+ * Patches a file by applying a 'diff' file to it; requires "patch" to be
+ * on the execution path.
+ *
+ * @since Ant 1.1
+ *
+ * @ant.task category="utility"
+ */
+public class Patch extends Task {
+
+ private File originalFile;
+ private File directory;
+ private boolean havePatchfile = false;
+ private Commandline cmd = new Commandline();
+
+ /**
+ * Halt on error return value from patch invocation.
+ */
+ private boolean failOnError = false;
+
+ /**
+ * The file to patch; optional if it can be inferred from
+ * the diff file
+ * @param file the file to patch
+ */
+ public void setOriginalfile(File file) {
+ originalFile = file;
+ }
+
+ /**
+ * The name of a file to send the output to, instead of patching
+ * the file(s) in place; optional.
+ * @param file the file to send the output to
+ * @since Ant 1.6
+ */
+ public void setDestfile(File file) {
+ if (file != null) {
+ cmd.createArgument().setValue("-o");
+ cmd.createArgument().setFile(file);
+ }
+ }
+
+ /**
+ * The file containing the diff output; required.
+ * @param file the file containing the diff output
+ */
+ public void setPatchfile(File file) {
+ if (!file.exists()) {
+ throw new BuildException("patchfile " + file + " doesn\'t exist",
+ getLocation());
+ }
+ cmd.createArgument().setValue("-i");
+ cmd.createArgument().setFile(file);
+ havePatchfile = true;
+ }
+
+ /**
+ * flag to create backups; optional, default=false
+ * @param backups if true create backups
+ */
+ public void setBackups(boolean backups) {
+ if (backups) {
+ cmd.createArgument().setValue("-b");
+ }
+ }
+
+ /**
+ * flag to ignore whitespace differences; default=false
+ * @param ignore if true ignore whitespace differences
+ */
+ public void setIgnorewhitespace(boolean ignore) {
+ if (ignore) {
+ cmd.createArgument().setValue("-l");
+ }
+ }
+
+ /**
+ * Strip the smallest prefix containing <i>num</i> leading slashes
+ * from filenames.
+ *
+ * <p>patch's <i>-p</i> option.
+ * @param num number of lines to strip
+ * @exception BuildException if num is &lt; 0, or other errors
+ */
+ public void setStrip(int num) throws BuildException {
+ if (num < 0) {
+ throw new BuildException("strip has to be >= 0", getLocation());
+ }
+ cmd.createArgument().setValue("-p" + num);
+ }
+
+ /**
+ * Work silently unless an error occurs; optional, default=false
+ * @param q if true suppress set the -s option on the patch command
+ */
+ public void setQuiet(boolean q) {
+ if (q) {
+ cmd.createArgument().setValue("-s");
+ }
+ }
+
+ /**
+ * Assume patch was created with old and new files swapped; optional,
+ * default=false
+ * @param r if true set the -R option on the patch command
+ */
+ public void setReverse(boolean r) {
+ if (r) {
+ cmd.createArgument().setValue("-R");
+ }
+ }
+
+ /**
+ * The directory to run the patch command in, defaults to the
+ * project's base directory.
+ * @param directory the directory to run the patch command in
+ * @since Ant 1.5
+ */
+ public void setDir(File directory) {
+ this.directory = directory;
+ }
+
+ /**
+ * If <code>true</code>, stop the build process if the patch command
+ * exits with an error status.
+ * @param value <code>true</code> if it should halt, otherwise
+ * <code>false</code>. The default is <code>false</code>.
+ * @since Ant 1.8.0
+ */
+ public void setFailOnError(boolean value) {
+ failOnError = value;
+ }
+
+ private static final String PATCH = "patch";
+
+ /**
+ * execute patch
+ * @throws BuildException when it all goes a bit pear shaped
+ */
+ public void execute() throws BuildException {
+ if (!havePatchfile) {
+ throw new BuildException("patchfile argument is required",
+ getLocation());
+ }
+ Commandline toExecute = (Commandline) cmd.clone();
+ toExecute.setExecutable(PATCH);
+
+ if (originalFile != null) {
+ toExecute.createArgument().setFile(originalFile);
+ }
+
+ Execute exe = new Execute(new LogStreamHandler(this, Project.MSG_INFO,
+ Project.MSG_WARN),
+ null);
+ exe.setCommandline(toExecute.getCommandline());
+
+ if (directory != null) {
+ if (directory.exists() && directory.isDirectory()) {
+ exe.setWorkingDirectory(directory);
+ } else if (!directory.isDirectory()) {
+ throw new BuildException(directory + " is not a directory.",
+ getLocation());
+ } else {
+ throw new BuildException("directory " + directory
+ + " doesn\'t exist", getLocation());
+ }
+ } else {
+ exe.setWorkingDirectory(getProject().getBaseDir());
+ }
+
+ log(toExecute.describeCommand(), Project.MSG_VERBOSE);
+ try {
+ int returncode = exe.execute();
+ if (Execute.isFailure(returncode)) {
+ String msg = "'" + PATCH + "' failed with exit code "
+ + returncode;
+ if (failOnError) {
+ throw new BuildException(msg);
+ } else {
+ log(msg, Project.MSG_ERR);
+ }
+ }
+ } catch (IOException e) {
+ throw new BuildException(e, getLocation());
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/PathConvert.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/PathConvert.java
new file mode 100644
index 00000000..abbc5fd6
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/PathConvert.java
@@ -0,0 +1,511 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.taskdefs.condition.Os;
+import org.apache.tools.ant.types.EnumeratedAttribute;
+import org.apache.tools.ant.types.Mapper;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.types.Reference;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.ResourceCollection;
+import org.apache.tools.ant.types.resources.Resources;
+import org.apache.tools.ant.types.resources.Union;
+import org.apache.tools.ant.util.FileNameMapper;
+import org.apache.tools.ant.util.IdentityMapper;
+
+/**
+ * Converts path and classpath information to a specific target OS
+ * format. The resulting formatted path is placed into the specified property.
+ *
+ * @since Ant 1.4
+ * @ant.task category="utility"
+ */
+public class PathConvert extends Task {
+
+ /**
+ * Set if we're running on windows
+ */
+ private static boolean onWindows = Os.isFamily("dos");
+
+ // Members
+ /**
+ * Path to be converted
+ */
+ private Resources path = null;
+ /**
+ * Reference to path/fileset to convert
+ */
+ private Reference refid = null;
+ /**
+ * The target OS type
+ */
+ private String targetOS = null;
+ /**
+ * Set when targetOS is set to windows
+ */
+ private boolean targetWindows = false;
+ /**
+ * Set if we should create a new property even if the result is empty
+ */
+ private boolean setonempty = true;
+ /**
+ * The property to receive the conversion
+ */
+ private String property = null;
+ /**
+ * Path prefix map
+ */
+ private Vector prefixMap = new Vector();
+ /**
+ * User override on path sep char
+ */
+ private String pathSep = null;
+ /**
+ * User override on directory sep char
+ */
+ private String dirSep = null;
+
+ /** Filename mapper */
+ private Mapper mapper = null;
+
+ private boolean preserveDuplicates;
+
+ /**
+ * Construct a new instance of the PathConvert task.
+ */
+ public PathConvert() {
+ }
+
+ /**
+ * Helper class, holds the nested &lt;map&gt; values. Elements will look like
+ * this: &lt;map from=&quot;d:&quot; to=&quot;/foo&quot;/&gt;
+ *
+ * When running on windows, the prefix comparison will be case
+ * insensitive.
+ */
+ public class MapEntry {
+
+ // Members
+ private String from = null;
+ private String to = null;
+
+ /**
+ * Set the &quot;from&quot; attribute of the map entry.
+ * @param from the prefix string to search for; required.
+ * Note that this value is case-insensitive when the build is
+ * running on a Windows platform and case-sensitive when running on
+ * a Unix platform.
+ */
+ public void setFrom(String from) {
+ this.from = from;
+ }
+
+ /**
+ * Set the replacement text to use when from is matched; required.
+ * @param to new prefix.
+ */
+ public void setTo(String to) {
+ this.to = to;
+ }
+
+ /**
+ * Apply this map entry to a given path element.
+ *
+ * @param elem Path element to process.
+ * @return String Updated path element after mapping.
+ */
+ public String apply(String elem) {
+ if (from == null || to == null) {
+ throw new BuildException("Both 'from' and 'to' must be set "
+ + "in a map entry");
+ }
+ // If we're on windows, then do the comparison ignoring case
+ // and treat the two directory characters the same
+ String cmpElem =
+ onWindows ? elem.toLowerCase().replace('\\', '/') : elem;
+ String cmpFrom =
+ onWindows ? from.toLowerCase().replace('\\', '/') : from;
+
+ // If the element starts with the configured prefix, then
+ // convert the prefix to the configured 'to' value.
+
+ return cmpElem.startsWith(cmpFrom)
+ ? to + elem.substring(from.length()) : elem;
+ }
+ }
+
+ /**
+ * An enumeration of supported targets:
+ * "windows", "unix", "netware", and "os/2".
+ */
+ public static class TargetOs extends EnumeratedAttribute {
+ /**
+ * @return the list of values for this enumerated attribute.
+ */
+ @Override
+ public String[] getValues() {
+ return new String[]{"windows", "unix", "netware", "os/2", "tandem"};
+ }
+ }
+
+ /**
+ * Create a nested path element.
+ * @return a Path to be used by Ant reflection.
+ */
+ public Path createPath() {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ Path result = new Path(getProject());
+ add(result);
+ return result;
+ }
+
+ /**
+ * Add an arbitrary ResourceCollection.
+ * @param rc the ResourceCollection to add.
+ * @since Ant 1.7
+ */
+ public void add(ResourceCollection rc) {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ getPath().add(rc);
+ }
+
+ private synchronized Resources getPath() {
+ if (path == null) {
+ path = new Resources(getProject());
+ path.setCache(true);
+ }
+ return path;
+ }
+
+ /**
+ * Create a nested MAP element.
+ * @return a Map to configure.
+ */
+ public MapEntry createMap() {
+ MapEntry entry = new MapEntry();
+ prefixMap.addElement(entry);
+ return entry;
+ }
+
+ /**
+ * Set targetos to a platform to one of
+ * "windows", "unix", "netware", or "os/2";
+ * current platform settings are used by default.
+ * @param target the target os.
+ * @deprecated since 1.5.x.
+ * Use the method taking a TargetOs argument instead.
+ * @see #setTargetos(PathConvert.TargetOs)
+ */
+ @Deprecated
+ public void setTargetos(String target) {
+ TargetOs to = new TargetOs();
+ to.setValue(target);
+ setTargetos(to);
+ }
+
+ /**
+ * Set targetos to a platform to one of
+ * "windows", "unix", "netware", or "os/2";
+ * current platform settings are used by default.
+ * @param target the target os
+ *
+ * @since Ant 1.5
+ */
+ public void setTargetos(TargetOs target) {
+ targetOS = target.getValue();
+
+ // Currently, we deal with only two path formats: Unix and Windows
+ // And Unix is everything that is not Windows
+
+ // for NetWare and OS/2, piggy-back on Windows, since in the
+ // validateSetup code, the same assumptions can be made as
+ // with windows - that ; is the path separator
+
+ targetWindows = !targetOS.equals("unix") && !targetOS.equals("tandem");
+ }
+
+ /**
+ * Set whether the specified property will be set if the result
+ * is the empty string.
+ * @param setonempty true or false.
+ *
+ * @since Ant 1.5
+ */
+ public void setSetonempty(boolean setonempty) {
+ this.setonempty = setonempty;
+ }
+
+ /**
+ * Set the name of the property into which the converted path will be placed.
+ * @param p the property name.
+ */
+ public void setProperty(String p) {
+ property = p;
+ }
+
+ /**
+ * Add a reference to a Path, FileSet, DirSet, or FileList defined elsewhere.
+ * @param r the reference to a path, fileset, dirset or filelist.
+ */
+ public void setRefid(Reference r) {
+ if (path != null) {
+ throw noChildrenAllowed();
+ }
+ refid = r;
+ }
+
+ /**
+ * Set the default path separator string; defaults to current JVM
+ * {@link java.io.File#pathSeparator File.pathSeparator}.
+ * @param sep path separator string.
+ */
+ public void setPathSep(String sep) {
+ pathSep = sep;
+ }
+
+
+ /**
+ * Set the default directory separator string;
+ * defaults to current JVM {@link java.io.File#separator File.separator}.
+ * @param sep directory separator string.
+ */
+ public void setDirSep(String sep) {
+ dirSep = sep;
+ }
+
+ /**
+ * Set the preserveDuplicates.
+ * @param preserveDuplicates the boolean to set
+ * @since Ant 1.8
+ */
+ public void setPreserveDuplicates(boolean preserveDuplicates) {
+ this.preserveDuplicates = preserveDuplicates;
+ }
+
+ /**
+ * Get the preserveDuplicates.
+ * @return boolean
+ * @since Ant 1.8
+ */
+ public boolean isPreserveDuplicates() {
+ return preserveDuplicates;
+ }
+
+ /**
+ * Learn whether the refid attribute of this element been set.
+ * @return true if refid is valid.
+ */
+ public boolean isReference() {
+ return refid != null;
+ }
+
+ /**
+ * Do the execution.
+ * @throws BuildException if something is invalid.
+ */
+ @Override
+ public void execute() throws BuildException {
+ Resources savedPath = path;
+ String savedPathSep = pathSep; // may be altered in validateSetup
+ String savedDirSep = dirSep; // may be altered in validateSetup
+
+ try {
+ // If we are a reference, create a Path from the reference
+ if (isReference()) {
+ Object o = refid.getReferencedObject(getProject());
+ if (!(o instanceof ResourceCollection)) {
+ throw new BuildException("refid '" + refid.getRefId()
+ + "' does not refer to a resource collection.");
+ }
+ getPath().add((ResourceCollection) o);
+ }
+ validateSetup(); // validate our setup
+
+ // Currently, we deal with only two path formats: Unix and Windows
+ // And Unix is everything that is not Windows
+ // (with the exception for NetWare and OS/2 below)
+
+ // for NetWare and OS/2, piggy-back on Windows, since here and
+ // in the apply code, the same assumptions can be made as with
+ // windows - that \\ is an OK separator, and do comparisons
+ // case-insensitive.
+ String fromDirSep = onWindows ? "\\" : "/";
+
+ StringBuffer rslt = new StringBuffer();
+
+ ResourceCollection resources = isPreserveDuplicates() ? (ResourceCollection) path : new Union(path);
+ List ret = new ArrayList();
+ FileNameMapper mapperImpl = mapper == null ? new IdentityMapper() : mapper.getImplementation();
+ for (Resource r : resources) {
+ String[] mapped = mapperImpl.mapFileName(String.valueOf(r));
+ for (int m = 0; mapped != null && m < mapped.length; ++m) {
+ ret.add(mapped[m]);
+ }
+ }
+ boolean first = true;
+ for (Iterator mappedIter = ret.iterator(); mappedIter.hasNext();) {
+ String elem = mapElement((String) mappedIter.next()); // Apply the path prefix map
+
+ // Now convert the path and file separator characters from the
+ // current os to the target os.
+
+ if (!first) {
+ rslt.append(pathSep);
+ }
+ first = false;
+
+ StringTokenizer stDirectory = new StringTokenizer(elem, fromDirSep, true);
+
+ while (stDirectory.hasMoreTokens()) {
+ String token = stDirectory.nextToken();
+ rslt.append(fromDirSep.equals(token) ? dirSep : token);
+ }
+ }
+ // Place the result into the specified property,
+ // unless setonempty == false
+ if (setonempty || rslt.length() > 0) {
+ String value = rslt.toString();
+ if (property == null) {
+ log(value);
+ } else {
+ log("Set property " + property + " = " + value, Project.MSG_VERBOSE);
+ getProject().setNewProperty(property, value);
+ }
+ }
+ } finally {
+ path = savedPath;
+ dirSep = savedDirSep;
+ pathSep = savedPathSep;
+ }
+ }
+
+ /**
+ * Apply the configured map to a path element. The map is used to convert
+ * between Windows drive letters and Unix paths. If no map is configured,
+ * then the input string is returned unchanged.
+ *
+ * @param elem The path element to apply the map to.
+ * @return String Updated element.
+ */
+ private String mapElement(String elem) {
+
+ int size = prefixMap.size();
+
+ if (size != 0) {
+
+ // Iterate over the map entries and apply each one.
+ // Stop when one of the entries actually changes the element.
+
+ for (int i = 0; i < size; i++) {
+ MapEntry entry = (MapEntry) prefixMap.elementAt(i);
+ String newElem = entry.apply(elem);
+
+ // Note I'm using "!=" to see if we got a new object back from
+ // the apply method.
+
+ if (newElem != elem) {
+ elem = newElem;
+ break; // We applied one, so we're done
+ }
+ }
+ }
+ return elem;
+ }
+
+ /**
+ * Add a mapper to convert the file names.
+ *
+ * @param mapper a <code>Mapper</code> value.
+ */
+ public void addMapper(Mapper mapper) {
+ if (this.mapper != null) {
+ throw new BuildException(
+ "Cannot define more than one mapper");
+ }
+ this.mapper = mapper;
+ }
+
+ /**
+ * Add a nested filenamemapper.
+ * @param fileNameMapper the mapper to add.
+ * @since Ant 1.6.3
+ */
+ public void add(FileNameMapper fileNameMapper) {
+ Mapper m = new Mapper(getProject());
+ m.add(fileNameMapper);
+ addMapper(m);
+ }
+
+ /**
+ * Validate that all our parameters have been properly initialized.
+ *
+ * @throws BuildException if something is not set up properly.
+ */
+ private void validateSetup() throws BuildException {
+
+ if (path == null) {
+ throw new BuildException("You must specify a path to convert");
+ }
+ // Determine the separator strings. The dirsep and pathsep attributes
+ // override the targetOS settings.
+ String dsep = File.separator;
+ String psep = File.pathSeparator;
+
+ if (targetOS != null) {
+ psep = targetWindows ? ";" : ":";
+ dsep = targetWindows ? "\\" : "/";
+ }
+ if (pathSep != null) {
+ // override with pathsep=
+ psep = pathSep;
+ }
+ if (dirSep != null) {
+ // override with dirsep=
+ dsep = dirSep;
+ }
+ pathSep = psep;
+ dirSep = dsep;
+ }
+
+ /**
+ * Creates an exception that indicates that this XML element must not have
+ * child elements if the refid attribute is set.
+ * @return BuildException.
+ */
+ private BuildException noChildrenAllowed() {
+ return new BuildException("You must not specify nested "
+ + "elements when using the refid attribute.");
+ }
+
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/PreSetDef.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/PreSetDef.java
new file mode 100644
index 00000000..fe577044
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/PreSetDef.java
@@ -0,0 +1,275 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.AntTypeDefinition;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.ComponentHelper;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.ProjectHelper;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.TaskContainer;
+import org.apache.tools.ant.UnknownElement;
+
+/**
+ * The preset definition task generates a new definition
+ * based on a current definition with some attributes or
+ * elements preset.
+ * <pre>
+ * &lt;presetdef name="my.javac"&gt;
+ * &lt;javac deprecation="${deprecation}" debug="${debug}"/&gt;
+ * &lt;/presetdef&gt;
+ * &lt;my.javac srcdir="src" destdir="classes"/&gt;
+ * </pre>
+ *
+ * @since Ant 1.6
+ */
+public class PreSetDef extends AntlibDefinition implements TaskContainer {
+ private UnknownElement nestedTask;
+ private String name;
+
+ /**
+ * Set the name of this definition.
+ * @param name the name of the definition.
+ */
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ /**
+ * Add a nested task to predefine attributes and elements on.
+ * @param nestedTask Nested task/type to extend.
+ */
+ public void addTask(Task nestedTask) {
+ if (this.nestedTask != null) {
+ throw new BuildException("Only one nested element allowed");
+ }
+ if (!(nestedTask instanceof UnknownElement)) {
+ throw new BuildException(
+ "addTask called with a task that is not an unknown element");
+ }
+ this.nestedTask = (UnknownElement) nestedTask;
+ }
+
+
+ /**
+ * Make a new definition.
+ */
+ public void execute() {
+ if (nestedTask == null) {
+ throw new BuildException("Missing nested element");
+ }
+ if (name == null) {
+ throw new BuildException("Name not specified");
+ }
+ name = ProjectHelper.genComponentName(getURI(), name);
+
+ ComponentHelper helper = ComponentHelper.getComponentHelper(
+ getProject());
+
+ String componentName = ProjectHelper.genComponentName(
+ nestedTask.getNamespace(), nestedTask.getTag());
+
+ AntTypeDefinition def = helper.getDefinition(componentName);
+ if (def == null) {
+ throw new BuildException(
+ "Unable to find typedef " + componentName);
+ }
+ PreSetDefinition newDef = new PreSetDefinition(def, nestedTask);
+
+ newDef.setName(name);
+
+ helper.addDataTypeDefinition(newDef);
+ log("defining preset " + name, Project.MSG_VERBOSE);
+ }
+
+ /**
+ * This class contains the unknown element and the object
+ * that is predefined.
+ * @see AntTypeDefinition
+ */
+ public static class PreSetDefinition extends AntTypeDefinition {
+ private AntTypeDefinition parent;
+ private UnknownElement element;
+
+ /**
+ * Creates a new <code>PresetDefinition</code> instance.
+ *
+ * @param parent The parent of this predefinition.
+ * @param el The predefined attributes, nested elements and text.
+ */
+ public PreSetDefinition(AntTypeDefinition parent, UnknownElement el) {
+ if (parent instanceof PreSetDefinition) {
+ PreSetDefinition p = (PreSetDefinition) parent;
+ el.applyPreSet(p.element);
+ parent = p.parent;
+ }
+ this.parent = parent;
+ this.element = el;
+ }
+
+ /**
+ * Override so that it is not allowed.
+ *
+ * @param clazz a <code>Class</code> value.
+ */
+ public void setClass(Class clazz) {
+ throw new BuildException("Not supported");
+ }
+
+ /**
+ * Override so that it is not allowed.
+ *
+ * @param className a <code>String</code> value.
+ */
+ public void setClassName(String className) {
+ throw new BuildException("Not supported");
+ }
+
+ /**
+ * Get the classname of the definition.
+ * @return the name of the class of this definition.
+ */
+ public String getClassName() {
+ return parent.getClassName();
+ }
+
+ /**
+ * Set the adapter class for this definition.
+ * NOT Supported
+ * @param adapterClass the adapterClass.
+ */
+ public void setAdapterClass(Class adapterClass) {
+ throw new BuildException("Not supported");
+ }
+
+ /**
+ * Set the assignable class for this definition.
+ * NOT SUPPORTED
+ * @param adaptToClass the assignable class.
+ */
+ public void setAdaptToClass(Class adaptToClass) {
+ throw new BuildException("Not supported");
+ }
+
+ /**
+ * Set the classloader to use to create an instance
+ * of the definition.
+ * NOT SUPPORTED
+ * @param classLoader the classLoader.
+ */
+ public void setClassLoader(ClassLoader classLoader) {
+ throw new BuildException("Not supported");
+ }
+
+ /**
+ * Get the classloader for this definition.
+ * @return the classloader for this definition.
+ */
+ public ClassLoader getClassLoader() {
+ return parent.getClassLoader();
+ }
+
+ /**
+ * Get the exposed class for this definition.
+ * @param project the current project.
+ * @return the exposed class.
+ */
+ public Class getExposedClass(Project project) {
+ return parent.getExposedClass(project);
+ }
+
+ /**
+ * Get the definition class.
+ * @param project the current project.
+ * @return the type of the definition.
+ */
+ public Class getTypeClass(Project project) {
+ return parent.getTypeClass(project);
+ }
+
+
+ /**
+ * Check if the attributes are correct.
+ * @param project the current project.
+ */
+ public void checkClass(Project project) {
+ parent.checkClass(project);
+ }
+
+ /**
+ * Create an instance of the definition. The instance may be wrapped
+ * in a proxy class. This is a special version of create for
+ * IntrospectionHelper and UnknownElement.
+ * @param project the current project.
+ * @return the created object.
+ */
+ public Object createObject(Project project) {
+ return parent.create(project);
+ }
+
+ /**
+ * Get the preset values.
+ * @return the predefined attributes, elements and text as
+ * an UnknownElement.
+ */
+ public UnknownElement getPreSets() {
+ return element;
+ }
+
+ /**
+ * Fake create an object, used by IntrospectionHelper and UnknownElement
+ * to see that this is a predefined object.
+ *
+ * @param project the current project.
+ * @return this object.
+ */
+ public Object create(Project project) {
+ return this;
+ }
+
+ /**
+ * Equality method for this definition.
+ *
+ * @param other another definition.
+ * @param project the current project.
+ * @return true if the definitions are the same.
+ */
+ public boolean sameDefinition(AntTypeDefinition other, Project project) {
+ return (other != null && other.getClass() == getClass() && parent != null
+ && parent.sameDefinition(((PreSetDefinition) other).parent, project)
+ && element.similar(((PreSetDefinition) other).element));
+ }
+
+ /**
+ * Similar method for this definition.
+ *
+ * @param other another definition.
+ * @param project the current project.
+ * @return true if the definitions are similar.
+ */
+ public boolean similarDefinition(
+ AntTypeDefinition other, Project project) {
+ return (other != null && other.getClass().getName().equals(
+ getClass().getName()) && parent != null
+ && parent.similarDefinition(((PreSetDefinition) other).parent, project)
+ && element.similar(((PreSetDefinition) other).element));
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/ProcessDestroyer.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/ProcessDestroyer.java
new file mode 100644
index 00000000..ba9c9d48
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/ProcessDestroyer.java
@@ -0,0 +1,220 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.HashSet;
+import java.util.Iterator;
+
+/**
+ * Destroys all registered <code>Process</code>es when the VM exits.
+ *
+ * @since Ant 1.5
+ */
+class ProcessDestroyer implements Runnable {
+ private static final int THREAD_DIE_TIMEOUT = 20000;
+ private HashSet processes = new HashSet();
+ // methods to register and unregister shutdown hooks
+ private Method addShutdownHookMethod;
+ private Method removeShutdownHookMethod;
+ private ProcessDestroyerImpl destroyProcessThread = null;
+
+ // whether or not this ProcessDestroyer has been registered as a
+ // shutdown hook
+ private boolean added = false;
+ // whether or not this ProcessDestroyer is currently running as
+ // shutdown hook
+ private boolean running = false;
+
+ private class ProcessDestroyerImpl extends Thread {
+ private boolean shouldDestroy = true;
+
+ public ProcessDestroyerImpl() {
+ super("ProcessDestroyer Shutdown Hook");
+ }
+ public void run() {
+ if (shouldDestroy) {
+ ProcessDestroyer.this.run();
+ }
+ }
+
+ public void setShouldDestroy(boolean shouldDestroy) {
+ this.shouldDestroy = shouldDestroy;
+ }
+ }
+
+ /**
+ * Constructs a <code>ProcessDestroyer</code> and obtains
+ * <code>Runtime.addShutdownHook()</code> and
+ * <code>Runtime.removeShutdownHook()</code> through reflection. The
+ * ProcessDestroyer manages a list of processes to be destroyed when the
+ * VM exits. If a process is added when the list is empty,
+ * this <code>ProcessDestroyer</code> is registered as a shutdown hook. If
+ * removing a process results in an empty list, the
+ * <code>ProcessDestroyer</code> is removed as a shutdown hook.
+ */
+ ProcessDestroyer() {
+ try {
+ // check to see if the shutdown hook methods exists
+ // (support pre-JDK 1.3 and Non-Sun VMs)
+ Class[] paramTypes = {Thread.class};
+ addShutdownHookMethod =
+ Runtime.class.getMethod("addShutdownHook", paramTypes);
+
+ removeShutdownHookMethod =
+ Runtime.class.getMethod("removeShutdownHook", paramTypes);
+ // wait to add shutdown hook as needed
+ } catch (NoSuchMethodException e) {
+ // it just won't be added as a shutdown hook... :(
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * Registers this <code>ProcessDestroyer</code> as a shutdown hook,
+ * uses reflection to ensure pre-JDK 1.3 compatibility.
+ */
+ private void addShutdownHook() {
+ if (addShutdownHookMethod != null && !running) {
+ destroyProcessThread = new ProcessDestroyerImpl();
+ Object[] args = {destroyProcessThread};
+ try {
+ addShutdownHookMethod.invoke(Runtime.getRuntime(), args);
+ added = true;
+ } catch (IllegalAccessException e) {
+ e.printStackTrace();
+ } catch (InvocationTargetException e) {
+ Throwable t = e.getTargetException();
+ if (t != null && t.getClass() == IllegalStateException.class) {
+ // shutdown already is in progress
+ running = true;
+ } else {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+
+ /**
+ * Removes this <code>ProcessDestroyer</code> as a shutdown hook,
+ * uses reflection to ensure pre-JDK 1.3 compatibility
+ */
+ private void removeShutdownHook() {
+ if (removeShutdownHookMethod != null && added && !running) {
+ Object[] args = {destroyProcessThread};
+ try {
+ Boolean removed =
+ (Boolean) removeShutdownHookMethod.invoke(
+ Runtime.getRuntime(),
+ args);
+ if (!removed.booleanValue()) {
+ System.err.println("Could not remove shutdown hook");
+ }
+ } catch (IllegalAccessException e) {
+ e.printStackTrace();
+ } catch (InvocationTargetException e) {
+ Throwable t = e.getTargetException();
+ if (t != null && t.getClass() == IllegalStateException.class) {
+ // shutdown already is in progress
+ running = true;
+ } else {
+ e.printStackTrace();
+ }
+ }
+ // start the hook thread, a unstarted thread may not be
+ // eligible for garbage collection
+ // Cf.: http://developer.java.sun.com/developer/bugParade/bugs/4533087.html
+ destroyProcessThread.setShouldDestroy(false);
+ if (!destroyProcessThread.getThreadGroup().isDestroyed()) {
+ // start() would throw IllegalThreadStateException from
+ // ThreadGroup.add if it were destroyed
+ destroyProcessThread.start();
+ }
+ // this should return quickly, since it basically is a NO-OP.
+ try {
+ destroyProcessThread.join(THREAD_DIE_TIMEOUT);
+ } catch (InterruptedException ie) {
+ // the thread didn't die in time
+ // it should not kill any processes unexpectedly
+ }
+ destroyProcessThread = null;
+ added = false;
+ }
+ }
+
+ /**
+ * Returns whether or not the ProcessDestroyer is registered as
+ * as shutdown hook
+ * @return true if this is currently added as shutdown hook
+ */
+ public boolean isAddedAsShutdownHook() {
+ return added;
+ }
+
+ /**
+ * Returns <code>true</code> if the specified <code>Process</code> was
+ * successfully added to the list of processes to destroy upon VM exit.
+ *
+ * @param process the process to add
+ * @return <code>true</code> if the specified <code>Process</code> was
+ * successfully added
+ */
+ public boolean add(Process process) {
+ synchronized (processes) {
+ // if this list is empty, register the shutdown hook
+ if (processes.size() == 0) {
+ addShutdownHook();
+ }
+ return processes.add(process);
+ }
+ }
+
+ /**
+ * Returns <code>true</code> if the specified <code>Process</code> was
+ * successfully removed from the list of processes to destroy upon VM exit.
+ *
+ * @param process the process to remove
+ * @return <code>true</code> if the specified <code>Process</code> was
+ * successfully removed
+ */
+ public boolean remove(Process process) {
+ synchronized (processes) {
+ boolean processRemoved = processes.remove(process);
+ if (processRemoved && processes.size() == 0) {
+ removeShutdownHook();
+ }
+ return processRemoved;
+ }
+ }
+
+ /**
+ * Invoked by the VM when it is exiting.
+ */
+ public void run() {
+ synchronized (processes) {
+ running = true;
+ Iterator e = processes.iterator();
+ while (e.hasNext()) {
+ ((Process) e.next()).destroy();
+ }
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/ProjectHelperTask.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/ProjectHelperTask.java
new file mode 100644
index 00000000..8f348a74
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/ProjectHelperTask.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.ProjectHelper;
+import org.apache.tools.ant.ProjectHelperRepository;
+import org.apache.tools.ant.Task;
+
+/**
+ * Task to install project helper into Ant's runtime
+ *
+ * @since Ant 1.8.2
+ */
+public class ProjectHelperTask extends Task {
+
+ private List projectHelpers = new ArrayList();
+
+ public synchronized void addConfigured(ProjectHelper projectHelper) {
+ this.projectHelpers.add(projectHelper);
+ }
+
+ @Override
+ public void execute() throws BuildException {
+ ProjectHelperRepository repo = ProjectHelperRepository.getInstance();
+ for (Iterator it = projectHelpers.iterator(); it.hasNext();) {
+ ProjectHelper helper = (ProjectHelper) it.next();
+ repo.registerProjectHelper(helper.getClass());
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Property.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Property.java
new file mode 100644
index 00000000..4aee3d0f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Property.java
@@ -0,0 +1,726 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.tools.ant.AntClassLoader;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.PropertyHelper;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.property.ResolvePropertyMap;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.types.Reference;
+import org.apache.tools.ant.util.FileUtils;
+
+/**
+ * <p>Sets a property by name, or set of properties (from file or
+ * resource) in the project. </p>
+ * <p>Properties are immutable: whoever sets a property first freezes it for the
+ * rest of the build; they are most definitely not variable.
+ * <p>There are seven ways to set properties:</p>
+ * <ul>
+ * <li>By supplying both the <i>name</i> and <i>value</i> attribute.</li>
+ * <li>By supplying the <i>name</i> and nested text.</li>
+ * <li>By supplying both the <i>name</i> and <i>refid</i> attribute.</li>
+ * <li>By setting the <i>file</i> attribute with the filename of the property
+ * file to load. This property file has the format as defined by the file used
+ * in the class java.util.Properties.</li>
+ * <li>By setting the <i>url</i> attribute with the url from which to load the
+ * properties. This url must be directed to a file that has the format as defined
+ * by the file used in the class java.util.Properties.</li>
+ * <li>By setting the <i>resource</i> attribute with the resource name of the
+ * property file to load. This property file has the format as defined by the
+ * file used in the class java.util.Properties.</li>
+ * <li>By setting the <i>environment</i> attribute with a prefix to use.
+ * Properties will be defined for every environment variable by
+ * prefixing the supplied name and a period to the name of the variable.</li>
+ * </ul>
+ * <p>Although combinations of these ways are possible, only one should be used
+ * at a time. Problems might occur with the order in which properties are set, for
+ * instance.</p>
+ * <p>The value part of the properties being set, might contain references to other
+ * properties. These references are resolved at the time these properties are set.
+ * This also holds for properties loaded from a property file.</p>
+ * Properties are case sensitive.
+ *
+ * @since Ant 1.1
+ *
+ * @ant.attribute.group name="name" description="One of these, when using the name attribute"
+ * @ant.attribute.group name="noname" description="One of these, when not using the name attribute"
+ * @ant.task category="property"
+ */
+public class Property extends Task {
+
+ // CheckStyle:VisibilityModifier OFF - bc
+ protected String name;
+ protected String value;
+ protected File file;
+ protected URL url;
+ protected String resource;
+ protected Path classpath;
+ protected String env;
+ protected Reference ref;
+ protected String prefix;
+ private Project fallback;
+ private Object untypedValue;
+ private boolean valueAttributeUsed = false;
+ private boolean relative = false;
+ private File basedir;
+ private boolean prefixValues = false;
+
+ protected boolean userProperty; // set read-only properties
+ // CheckStyle:VisibilityModifier ON
+
+ /**
+ * Constructor for Property.
+ */
+ public Property() {
+ this(false);
+ }
+
+ /**
+ * Constructor for Property.
+ * @param userProperty if true this is a user property
+ * @since Ant 1.5
+ */
+ protected Property(boolean userProperty) {
+ this(userProperty, null);
+ }
+
+ /**
+ * Constructor for Property.
+ * @param userProperty if true this is a user property
+ * @param fallback a project to use to look for references if the reference is
+ * not in the current project
+ * @since Ant 1.5
+ */
+ protected Property(boolean userProperty, Project fallback) {
+ this.userProperty = userProperty;
+ this.fallback = fallback;
+ }
+
+ /**
+ * Sets 'relative' attribute.
+ * @param relative new value
+ * @since Ant 1.8.0
+ */
+ public void setRelative(boolean relative) {
+ this.relative = relative;
+ }
+
+ /**
+ * Sets 'basedir' attribute.
+ * @param basedir new value
+ * @since Ant 1.8.0
+ */
+ public void setBasedir(File basedir) {
+ this.basedir = basedir;
+ }
+
+ /**
+ * The name of the property to set.
+ * @param name property name
+ */
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ /**
+ * Get the property name.
+ * @return the property name
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Sets the property to the absolute filename of the
+ * given file. If the value of this attribute is an absolute path, it
+ * is left unchanged (with / and \ characters converted to the
+ * current platforms conventions). Otherwise it is taken as a path
+ * relative to the project's basedir and expanded.
+ * @param location path to set
+ *
+ * @ant.attribute group="name"
+ */
+ public void setLocation(File location) {
+ if (relative) {
+ internalSetValue(location);
+ } else {
+ setValue(location.getAbsolutePath());
+ }
+ }
+
+ /* the following method is first in source so IH will pick it up first:
+ * Hopefully we'll never get any classes compiled by wise-guy compilers that behave otherwise...
+ */
+
+ /**
+ * Set the value of the property.
+ * @param value the value to use.
+ */
+ public void setValue(Object value) {
+ valueAttributeUsed = true;
+ internalSetValue(value);
+ }
+
+ private void internalSetValue(Object value) {
+ this.untypedValue = value;
+ //preserve protected string value for subclasses :(
+ this.value = value == null ? null : value.toString();
+ }
+
+ /**
+ * Set the value of the property as a String.
+ * @param value value to assign
+ *
+ * @ant.attribute group="name"
+ */
+ public void setValue(String value) {
+ setValue((Object) value);
+ }
+
+ /**
+ * Set a (multiline) property as nested text.
+ * @param msg the text to append to the output text
+ * @since Ant 1.8.0
+ */
+ public void addText(String msg) {
+ if (!valueAttributeUsed) {
+ msg = getProject().replaceProperties(msg);
+ String currentValue = getValue();
+ if (currentValue != null) {
+ msg = currentValue + msg;
+ }
+ internalSetValue(msg);
+ } else if (msg.trim().length() > 0) {
+ throw new BuildException("can't combine nested text with value"
+ + " attribute");
+ }
+ }
+
+ /**
+ * Get the property value.
+ * @return the property value
+ */
+ public String getValue() {
+ return value;
+ }
+
+ /**
+ * Filename of a property file to load.
+ * @param file filename
+ *
+ * @ant.attribute group="noname"
+ */
+ public void setFile(File file) {
+ this.file = file;
+ }
+
+ /**
+ * Get the file attribute.
+ * @return the file attribute
+ */
+ public File getFile() {
+ return file;
+ }
+
+ /**
+ * The url from which to load properties.
+ * @param url url string
+ *
+ * @ant.attribute group="noname"
+ */
+ public void setUrl(URL url) {
+ this.url = url;
+ }
+
+ /**
+ * Get the url attribute.
+ * @return the url attribute
+ */
+ public URL getUrl() {
+ return url;
+ }
+
+ /**
+ * Prefix to apply to properties loaded using <code>file</code>
+ * or <code>resource</code>.
+ * A "." is appended to the prefix if not specified.
+ * @param prefix prefix string
+ * @since Ant 1.5
+ */
+ public void setPrefix(String prefix) {
+ this.prefix = prefix;
+ if (prefix != null && !prefix.endsWith(".")) {
+ this.prefix += ".";
+ }
+ }
+
+ /**
+ * Get the prefix attribute.
+ * @return the prefix attribute
+ * @since Ant 1.5
+ */
+ public String getPrefix() {
+ return prefix;
+ }
+
+ /**
+ * Whether to apply the prefix when expanding properties on the
+ * right hand side of a properties file as well.
+ *
+ * @since Ant 1.8.2
+ */
+ public void setPrefixValues(boolean b) {
+ prefixValues = b;
+ }
+
+ /**
+ * Whether to apply the prefix when expanding properties on the
+ * right hand side of a properties file as well.
+ *
+ * @since Ant 1.8.2
+ */
+ public boolean getPrefixValues() {
+ return prefixValues;
+ }
+
+ /**
+ * Sets a reference to an Ant datatype
+ * declared elsewhere.
+ * Only yields reasonable results for references
+ * PATH like structures or properties.
+ * @param ref reference
+ *
+ * @ant.attribute group="name"
+ */
+ public void setRefid(Reference ref) {
+ this.ref = ref;
+ }
+
+ /**
+ * Get the refid attribute.
+ * @return the refid attribute
+ */
+ public Reference getRefid() {
+ return ref;
+ }
+
+ /**
+ * The resource name of a property file to load
+ * @param resource resource on classpath
+ *
+ * @ant.attribute group="noname"
+ */
+ public void setResource(String resource) {
+ this.resource = resource;
+ }
+
+ /**
+ * Get the resource attribute.
+ * @return the resource attribute
+ */
+ public String getResource() {
+ return resource;
+ }
+
+ /**
+ * Prefix to use when retrieving environment variables.
+ * Thus if you specify environment=&quot;myenv&quot;
+ * you will be able to access OS-specific
+ * environment variables via property names &quot;myenv.PATH&quot; or
+ * &quot;myenv.TERM&quot;.
+ * <p>
+ * Note that if you supply a property name with a final
+ * &quot;.&quot; it will not be doubled. ie environment=&quot;myenv.&quot; will still
+ * allow access of environment variables through &quot;myenv.PATH&quot; and
+ * &quot;myenv.TERM&quot;. This functionality is currently only implemented
+ * on select platforms. Feel free to send patches to increase the number of platforms
+ * this functionality is supported on ;).<br>
+ * Note also that properties are case sensitive, even if the
+ * environment variables on your operating system are not, e.g. it
+ * will be ${env.Path} not ${env.PATH} on Windows 2000.
+ * @param env prefix
+ *
+ * @ant.attribute group="noname"
+ */
+ public void setEnvironment(String env) {
+ this.env = env;
+ }
+
+ /**
+ * Get the environment attribute.
+ * @return the environment attribute
+ * @since Ant 1.5
+ */
+ public String getEnvironment() {
+ return env;
+ }
+
+ /**
+ * The classpath to use when looking up a resource.
+ * @param classpath to add to any existing classpath
+ */
+ public void setClasspath(Path classpath) {
+ if (this.classpath == null) {
+ this.classpath = classpath;
+ } else {
+ this.classpath.append(classpath);
+ }
+ }
+
+ /**
+ * The classpath to use when looking up a resource.
+ * @return a path to be configured
+ */
+ public Path createClasspath() {
+ if (this.classpath == null) {
+ this.classpath = new Path(getProject());
+ }
+ return this.classpath.createPath();
+ }
+
+ /**
+ * the classpath to use when looking up a resource,
+ * given as reference to a &lt;path&gt; defined elsewhere
+ * @param r a reference to a classpath
+ */
+ public void setClasspathRef(Reference r) {
+ createClasspath().setRefid(r);
+ }
+
+ /**
+ * Get the classpath used when looking up a resource.
+ * @return the classpath
+ * @since Ant 1.5
+ */
+ public Path getClasspath() {
+ return classpath;
+ }
+
+ /**
+ * @param userProperty ignored
+ * @deprecated since 1.5.x.
+ * This was never a supported feature and has been
+ * deprecated without replacement.
+ * @ant.attribute ignore="true"
+ */
+ @Deprecated
+ public void setUserProperty(boolean userProperty) {
+ log("DEPRECATED: Ignoring request to set user property in Property"
+ + " task.", Project.MSG_WARN);
+ }
+
+ /**
+ * get the value of this property
+ * @return the current value or the empty string
+ */
+ @Override
+ public String toString() {
+ return value == null ? "" : value;
+ }
+
+ /**
+ * set the property in the project to the value.
+ * if the task was give a file, resource or env attribute
+ * here is where it is loaded
+ * @throws BuildException on error
+ */
+ @Override
+ public void execute() throws BuildException {
+ if (getProject() == null) {
+ throw new IllegalStateException("project has not been set");
+ }
+
+ if (name != null) {
+ if (untypedValue == null && ref == null) {
+ throw new BuildException("You must specify value, location or "
+ + "refid with the name attribute",
+ getLocation());
+ }
+ } else {
+ if (url == null && file == null && resource == null && env == null) {
+ throw new BuildException("You must specify url, file, resource or "
+ + "environment when not using the "
+ + "name attribute", getLocation());
+ }
+ }
+
+ if (url == null && file == null && resource == null && prefix != null) {
+ throw new BuildException("Prefix is only valid when loading from "
+ + "a url, file or resource", getLocation());
+ }
+
+ if (name != null && untypedValue != null) {
+ if (relative) {
+ try {
+ File from = untypedValue instanceof File ? (File)untypedValue : new File(untypedValue.toString());
+ File to = basedir != null ? basedir : getProject().getBaseDir();
+ String relPath = FileUtils.getRelativePath(to, from);
+ relPath = relPath.replace('/', File.separatorChar);
+ addProperty(name, relPath);
+ } catch (Exception e) {
+ throw new BuildException(e, getLocation());
+ }
+ } else {
+ addProperty(name, untypedValue);
+ }
+ }
+
+ if (file != null) {
+ loadFile(file);
+ }
+
+ if (url != null) {
+ loadUrl(url);
+ }
+
+ if (resource != null) {
+ loadResource(resource);
+ }
+
+ if (env != null) {
+ loadEnvironment(env);
+ }
+
+ if ((name != null) && (ref != null)) {
+ try {
+ addProperty(name,
+ ref.getReferencedObject(getProject()).toString());
+ } catch (BuildException be) {
+ if (fallback != null) {
+ addProperty(name,
+ ref.getReferencedObject(fallback).toString());
+ } else {
+ throw be;
+ }
+ }
+ }
+ }
+
+ /**
+ * load properties from a url
+ * @param url url to load from
+ * @throws BuildException on error
+ */
+ protected void loadUrl(URL url) throws BuildException {
+ Properties props = new Properties();
+ log("Loading " + url, Project.MSG_VERBOSE);
+ try {
+ InputStream is = url.openStream();
+ try {
+ loadProperties(props, is, url.getFile().endsWith(".xml"));
+ } finally {
+ if (is != null) {
+ is.close();
+ }
+ }
+ addProperties(props);
+ } catch (IOException ex) {
+ throw new BuildException(ex, getLocation());
+ }
+ }
+
+ /**
+ * Loads the properties defined in the InputStream into the given
+ * property. On Java5+ it supports reading from XML based property
+ * definition.
+ * @param props The property object to load into
+ * @param is The input stream from where to load
+ * @param isXml <tt>true</tt> if we should try to load from xml
+ * @throws IOException if something goes wrong
+ * @since 1.8.0
+ * @see "http://java.sun.com/dtd/properties.dtd"
+ * @see java.util.Properties#loadFromXML(InputStream)
+ */
+ private void loadProperties(
+ Properties props, InputStream is, boolean isXml) throws IOException {
+ if (isXml) {
+ // load the xml based property definition
+ props.loadFromXML(is);
+ } else {
+ // load ".properties" format
+ props.load(is);
+ }
+ }
+
+ /**
+ * load properties from a file
+ * @param file file to load
+ * @throws BuildException on error
+ */
+ protected void loadFile(File file) throws BuildException {
+ Properties props = new Properties();
+ log("Loading " + file.getAbsolutePath(), Project.MSG_VERBOSE);
+ try {
+ if (file.exists()) {
+ FileInputStream fis = null;
+ try {
+ fis = new FileInputStream(file);
+ loadProperties(props, fis, file.getName().endsWith(".xml"));
+ } finally {
+ FileUtils.close(fis);
+ }
+ addProperties(props);
+ } else {
+ log("Unable to find property file: " + file.getAbsolutePath(),
+ Project.MSG_VERBOSE);
+ }
+ } catch (IOException ex) {
+ throw new BuildException(ex, getLocation());
+ }
+ }
+
+ /**
+ * load properties from a resource in the current classpath
+ * @param name name of resource to load
+ */
+ protected void loadResource(String name) {
+ Properties props = new Properties();
+ log("Resource Loading " + name, Project.MSG_VERBOSE);
+ InputStream is = null;
+ ClassLoader cL = null;
+ boolean cleanup = false;
+ try {
+ if (classpath != null) {
+ cleanup = true;
+ cL = getProject().createClassLoader(classpath);
+ } else {
+ cL = this.getClass().getClassLoader();
+ }
+
+ if (cL == null) {
+ is = ClassLoader.getSystemResourceAsStream(name);
+ } else {
+ is = cL.getResourceAsStream(name);
+ }
+
+ if (is != null) {
+ loadProperties(props, is, name.endsWith(".xml"));
+ addProperties(props);
+ } else {
+ log("Unable to find resource " + name, Project.MSG_WARN);
+ }
+ } catch (IOException ex) {
+ throw new BuildException(ex, getLocation());
+ } finally {
+ if (is != null) {
+ try {
+ is.close();
+ } catch (IOException e) {
+ // ignore
+ }
+ }
+ if (cleanup && cL != null) {
+ ((AntClassLoader) cL).cleanup();
+ }
+ }
+ }
+
+ /**
+ * load the environment values
+ * @param prefix prefix to place before them
+ */
+ protected void loadEnvironment(String prefix) {
+ Properties props = new Properties();
+ if (!prefix.endsWith(".")) {
+ prefix += ".";
+ }
+ log("Loading Environment " + prefix, Project.MSG_VERBOSE);
+ Map osEnv = Execute.getEnvironmentVariables();
+ for (Iterator e = osEnv.entrySet().iterator(); e.hasNext();) {
+ Map.Entry entry = (Map.Entry) e.next();
+ props.put(prefix + entry.getKey(), entry.getValue());
+ }
+ addProperties(props);
+ }
+
+ /**
+ * iterate through a set of properties,
+ * resolve them then assign them
+ * @param props the properties to iterate over
+ */
+ protected void addProperties(Properties props) {
+ HashMap m = new HashMap(props);
+ resolveAllProperties(m);
+ for (Iterator it = m.keySet().iterator(); it.hasNext();) {
+ Object k = it.next();
+ if (k instanceof String) {
+ String propertyName = (String) k;
+ if (prefix != null) {
+ propertyName = prefix + propertyName;
+ }
+ addProperty(propertyName, m.get(k));
+ }
+ }
+ }
+
+ /**
+ * add a name value pair to the project property set
+ * @param n name of property
+ * @param v value to set
+ */
+ protected void addProperty(String n, String v) {
+ addProperty(n, (Object) v);
+ }
+
+ /**
+ * add a name value pair to the project property set
+ * @param n name of property
+ * @param v value to set
+ * @since Ant 1.8
+ */
+ protected void addProperty(String n, Object v) {
+ PropertyHelper ph = PropertyHelper.getPropertyHelper(getProject());
+ if (userProperty) {
+ if (ph.getUserProperty(n) == null) {
+ ph.setInheritedProperty(n, v);
+ } else {
+ log("Override ignored for " + n, Project.MSG_VERBOSE);
+ }
+ } else {
+ ph.setNewProperty(n, v);
+ }
+ }
+
+ /**
+ * resolve properties inside a properties hashtable
+ * @param props properties object to resolve
+ */
+ private void resolveAllProperties(Map props) throws BuildException {
+ PropertyHelper propertyHelper
+ = PropertyHelper.getPropertyHelper(getProject());
+ new ResolvePropertyMap(
+ getProject(),
+ propertyHelper,
+ propertyHelper.getExpanders())
+ .resolveAllProperties(props, getPrefix(), getPrefixValues());
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/PropertyHelperTask.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/PropertyHelperTask.java
new file mode 100644
index 00000000..5e8867a7
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/PropertyHelperTask.java
@@ -0,0 +1,145 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.MagicNames;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.PropertyHelper;
+import org.apache.tools.ant.Task;
+
+/**
+ * This task is designed to allow the user to install a different
+ * PropertyHelper on the current Project. This task also allows the
+ * installation of PropertyHelper delegates on either the newly installed
+ * or existing PropertyHelper.
+ * @since Ant 1.8
+ */
+public class PropertyHelperTask extends Task {
+ /**
+ * Nested delegate for refid usage.
+ */
+ public final class DelegateElement {
+ private String refid;
+
+ private DelegateElement() {
+ }
+
+ /**
+ * Get the refid.
+ * @return String
+ */
+ public String getRefid() {
+ return refid;
+ }
+
+ /**
+ * Set the refid.
+ * @param refid the String to set
+ */
+ public void setRefid(String refid) {
+ this.refid = refid;
+ }
+
+ private PropertyHelper.Delegate resolve() {
+ if (refid == null) {
+ throw new BuildException("refid required for generic delegate");
+ }
+ return (PropertyHelper.Delegate) getProject().getReference(refid);
+ }
+ }
+
+ private PropertyHelper propertyHelper;
+ private List delegates;
+
+ /**
+ * Add a new PropertyHelper to be set on the Project.
+ * @param propertyHelper the PropertyHelper to set.
+ */
+ public synchronized void addConfigured(PropertyHelper propertyHelper) {
+ if (this.propertyHelper != null) {
+ throw new BuildException("Only one PropertyHelper can be installed");
+ }
+ this.propertyHelper = propertyHelper;
+ }
+
+ /**
+ * Add a PropertyHelper delegate to the existing or new PropertyHelper.
+ * @param delegate the delegate to add.
+ */
+ public synchronized void addConfigured(PropertyHelper.Delegate delegate) {
+ getAddDelegateList().add(delegate);
+ }
+
+ /**
+ * Add a nested &lt;delegate refid="foo" /&gt; element.
+ * @return DelegateElement
+ */
+ public DelegateElement createDelegate() {
+ DelegateElement result = new DelegateElement();
+ getAddDelegateList().add(result);
+ return result;
+ }
+
+ /**
+ * Execute the task.
+ * @throws BuildException on error.
+ */
+ public void execute() throws BuildException {
+ if (getProject() == null) {
+ throw new BuildException("Project instance not set");
+ }
+ if (propertyHelper == null && delegates == null) {
+ throw new BuildException("Either a new PropertyHelper"
+ + " or one or more PropertyHelper delegates are required");
+ }
+ PropertyHelper ph = propertyHelper;
+ if (ph == null) {
+ ph = PropertyHelper.getPropertyHelper(getProject());
+ } else {
+ ph = propertyHelper;
+ }
+ synchronized (ph) {
+ if (delegates != null) {
+ for (Iterator iter = delegates.iterator(); iter.hasNext();) {
+ Object o = iter.next();
+ PropertyHelper.Delegate delegate = o instanceof DelegateElement
+ ? ((DelegateElement) o).resolve() : (PropertyHelper.Delegate) o;
+ log("Adding PropertyHelper delegate " + delegate, Project.MSG_DEBUG);
+ ph.add(delegate);
+ }
+ }
+ }
+ if (propertyHelper != null) {
+ log("Installing PropertyHelper " + propertyHelper, Project.MSG_DEBUG);
+ // TODO copy existing properties to new PH?
+ getProject().addReference(MagicNames.REFID_PROPERTY_HELPER, propertyHelper);
+ }
+ }
+
+ private synchronized List getAddDelegateList() {
+ if (delegates == null) {
+ delegates = new ArrayList();
+ }
+ return delegates;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/PumpStreamHandler.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/PumpStreamHandler.java
new file mode 100644
index 00000000..42ba0f48
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/PumpStreamHandler.java
@@ -0,0 +1,298 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+/**
+ * Copies standard output and error of subprocesses to standard output and
+ * error of the parent process.
+ *
+ * @since Ant 1.2
+ */
+public class PumpStreamHandler implements ExecuteStreamHandler {
+
+ private Thread outputThread;
+ private Thread errorThread;
+ private Thread inputThread;
+
+ private OutputStream out;
+ private OutputStream err;
+ private InputStream input;
+ private final boolean nonBlockingRead;
+
+ /**
+ * Construct a new <code>PumpStreamHandler</code>.
+ * @param out the output <code>OutputStream</code>.
+ * @param err the error <code>OutputStream</code>.
+ * @param input the input <code>InputStream</code>.
+ * @param nonBlockingRead set it to <code>true</code> if the input should be
+ * read with simulated non blocking IO.
+ */
+ public PumpStreamHandler(OutputStream out, OutputStream err,
+ InputStream input, boolean nonBlockingRead) {
+ this.out = out;
+ this.err = err;
+ this.input = input;
+ this.nonBlockingRead = nonBlockingRead;
+ }
+
+ /**
+ * Construct a new <code>PumpStreamHandler</code>.
+ * @param out the output <code>OutputStream</code>.
+ * @param err the error <code>OutputStream</code>.
+ * @param input the input <code>InputStream</code>.
+ */
+ public PumpStreamHandler(OutputStream out, OutputStream err,
+ InputStream input) {
+ this(out, err, input, false);
+ }
+
+ /**
+ * Construct a new <code>PumpStreamHandler</code>.
+ * @param out the output <code>OutputStream</code>.
+ * @param err the error <code>OutputStream</code>.
+ */
+ public PumpStreamHandler(OutputStream out, OutputStream err) {
+ this(out, err, null);
+ }
+
+ /**
+ * Construct a new <code>PumpStreamHandler</code>.
+ * @param outAndErr the output/error <code>OutputStream</code>.
+ */
+ public PumpStreamHandler(OutputStream outAndErr) {
+ this(outAndErr, outAndErr);
+ }
+
+ /**
+ * Construct a new <code>PumpStreamHandler</code>.
+ */
+ public PumpStreamHandler() {
+ this(System.out, System.err);
+ }
+
+ /**
+ * Set the <code>InputStream</code> from which to read the
+ * standard output of the process.
+ * @param is the <code>InputStream</code>.
+ */
+ public void setProcessOutputStream(InputStream is) {
+ createProcessOutputPump(is, out);
+ }
+
+ /**
+ * Set the <code>InputStream</code> from which to read the
+ * standard error of the process.
+ * @param is the <code>InputStream</code>.
+ */
+ public void setProcessErrorStream(InputStream is) {
+ if (err != null) {
+ createProcessErrorPump(is, err);
+ }
+ }
+
+ /**
+ * Set the <code>OutputStream</code> by means of which
+ * input can be sent to the process.
+ * @param os the <code>OutputStream</code>.
+ */
+ public void setProcessInputStream(OutputStream os) {
+ if (input != null) {
+ inputThread = createPump(input, os, true, nonBlockingRead);
+ } else {
+ try {
+ os.close();
+ } catch (IOException e) {
+ //ignore
+ }
+ }
+ }
+
+ /**
+ * Start the <code>Thread</code>s.
+ */
+ public void start() {
+ outputThread.start();
+ errorThread.start();
+ if (inputThread != null) {
+ inputThread.start();
+ }
+ }
+
+ /**
+ * Stop pumping the streams.
+ */
+ public void stop() {
+ finish(inputThread);
+
+ try {
+ err.flush();
+ } catch (IOException e) {
+ // ignore
+ }
+ try {
+ out.flush();
+ } catch (IOException e) {
+ // ignore
+ }
+ finish(outputThread);
+ finish(errorThread);
+ }
+
+ private static final long JOIN_TIMEOUT = 200;
+
+ /**
+ * Waits for a thread to finish while trying to make it finish
+ * quicker by stopping the pumper (if the thread is a {@link
+ * ThreadWithPumper ThreadWithPumper} instance) or interrupting
+ * the thread.
+ *
+ * @since Ant 1.8.0
+ */
+ protected final void finish(Thread t) {
+ if (t == null) {
+ // nothing to terminate
+ return;
+ }
+ try {
+ StreamPumper s = null;
+ if (t instanceof ThreadWithPumper) {
+ s = ((ThreadWithPumper) t).getPumper();
+ }
+ if (s != null && s.isFinished()) {
+ return;
+ }
+ if (!t.isAlive()) {
+ return;
+ }
+
+ if (s != null && !s.isFinished()) {
+ s.stop();
+ }
+ t.join(JOIN_TIMEOUT);
+ while ((s == null || !s.isFinished()) && t.isAlive()) {
+ t.interrupt();
+ t.join(JOIN_TIMEOUT);
+ }
+ } catch (InterruptedException e) {
+ // ignore
+ }
+ }
+
+ /**
+ * Get the error stream.
+ * @return <code>OutputStream</code>.
+ */
+ protected OutputStream getErr() {
+ return err;
+ }
+
+ /**
+ * Get the output stream.
+ * @return <code>OutputStream</code>.
+ */
+ protected OutputStream getOut() {
+ return out;
+ }
+
+ /**
+ * Create the pump to handle process output.
+ * @param is the <code>InputStream</code>.
+ * @param os the <code>OutputStream</code>.
+ */
+ protected void createProcessOutputPump(InputStream is, OutputStream os) {
+ outputThread = createPump(is, os);
+ }
+
+ /**
+ * Create the pump to handle error output.
+ * @param is the input stream to copy from.
+ * @param os the output stream to copy to.
+ */
+ protected void createProcessErrorPump(InputStream is, OutputStream os) {
+ errorThread = createPump(is, os);
+ }
+
+ /**
+ * Creates a stream pumper to copy the given input stream to the
+ * given output stream.
+ * @param is the input stream to copy from.
+ * @param os the output stream to copy to.
+ * @return a thread object that does the pumping.
+ */
+ protected Thread createPump(InputStream is, OutputStream os) {
+ return createPump(is, os, false);
+ }
+
+ /**
+ * Creates a stream pumper to copy the given input stream to the
+ * given output stream.
+ * @param is the input stream to copy from.
+ * @param os the output stream to copy to.
+ * @param closeWhenExhausted if true close the inputstream.
+ * @return a thread object that does the pumping, subclasses
+ * should return an instance of {@link ThreadWithPumper
+ * ThreadWithPumper}.
+ */
+ protected Thread createPump(InputStream is, OutputStream os,
+ boolean closeWhenExhausted) {
+ return createPump(is, os, closeWhenExhausted, true);
+ }
+
+ /**
+ * Creates a stream pumper to copy the given input stream to the
+ * given output stream.
+ * @param is the input stream to copy from.
+ * @param os the output stream to copy to.
+ * @param closeWhenExhausted if true close the inputstream.
+ * @param nonBlockingIO set it to <code>true</code> to use simulated non
+ * blocking IO.
+ * @return a thread object that does the pumping, subclasses
+ * should return an instance of {@link ThreadWithPumper
+ * ThreadWithPumper}.
+ * @since Ant 1.8.2
+ */
+ protected Thread createPump(InputStream is, OutputStream os,
+ boolean closeWhenExhausted, boolean nonBlockingIO) {
+ StreamPumper pumper = new StreamPumper(is, os, closeWhenExhausted, nonBlockingIO);
+ pumper.setAutoflush(true);
+ final Thread result = new ThreadWithPumper(pumper);
+ result.setDaemon(true);
+ return result;
+ }
+
+ /**
+ * Specialized subclass that allows access to the running StreamPumper.
+ *
+ * @since Ant 1.8.0
+ */
+ protected static class ThreadWithPumper extends Thread {
+ private final StreamPumper pumper;
+ public ThreadWithPumper(StreamPumper p) {
+ super(p);
+ pumper = p;
+ }
+ protected StreamPumper getPumper() {
+ return pumper;
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Recorder.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Recorder.java
new file mode 100644
index 00000000..cc3b432a
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Recorder.java
@@ -0,0 +1,324 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs;
+
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.apache.tools.ant.BuildEvent;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.SubBuildListener;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.types.EnumeratedAttribute;
+import org.apache.tools.ant.types.LogLevel;
+
+/**
+ * Adds a listener to the current build process that records the
+ * output to a file.
+ * <p>Several recorders can exist at the same time. Each recorder is
+ * associated with a file. The filename is used as a unique identifier for
+ * the recorders. The first call to the recorder task with an unused filename
+ * will create a recorder (using the parameters provided) and add it to the
+ * listeners of the build. All subsequent calls to the recorder task using
+ * this filename will modify that recorders state (recording or not) or other
+ * properties (like logging level).</p>
+ * <p>Some technical issues: the file's print stream is flushed for &quot;finished&quot;
+ * events (buildFinished, targetFinished and taskFinished), and is closed on
+ * a buildFinished event.</p>
+ * @see RecorderEntry
+ * @version 0.5
+ * @since Ant 1.4
+ * @ant.task name="record" category="utility"
+ */
+public class Recorder extends Task implements SubBuildListener {
+
+ //////////////////////////////////////////////////////////////////////
+ // ATTRIBUTES
+
+ /** The name of the file to record to. */
+ private String filename = null;
+ /**
+ * Whether or not to append. Need Boolean to record an unset state (null).
+ */
+ private Boolean append = null;
+ /**
+ * Whether to start or stop recording. Need Boolean to record an unset
+ * state (null).
+ */
+ private Boolean start = null;
+ /** The level to log at. A level of -1 means not initialized yet. */
+ private int loglevel = -1;
+ /** Strip task banners if true. */
+ private boolean emacsMode = false;
+ /** The list of recorder entries. */
+ private static Hashtable recorderEntries = new Hashtable();
+
+ //////////////////////////////////////////////////////////////////////
+ // CONSTRUCTORS / INITIALIZERS
+
+ /**
+ * Overridden so we can add the task as build listener.
+ *
+ * @since Ant 1.7
+ */
+ public void init() {
+ getProject().addBuildListener(this);
+ }
+
+ //////////////////////////////////////////////////////////////////////
+ // ACCESSOR METHODS
+
+ /**
+ * Sets the name of the file to log to, and the name of the recorder
+ * entry.
+ *
+ * @param fname File name of logfile.
+ */
+ public void setName(String fname) {
+ filename = fname;
+ }
+
+
+ /**
+ * Sets the action for the associated recorder entry.
+ *
+ * @param action The action for the entry to take: start or stop.
+ */
+ public void setAction(ActionChoices action) {
+ if (action.getValue().equalsIgnoreCase("start")) {
+ start = Boolean.TRUE;
+ } else {
+ start = Boolean.FALSE;
+ }
+ }
+
+
+ /**
+ * Whether or not the logger should append to a previous file.
+ * @param append if true, append to a previous file.
+ */
+ public void setAppend(boolean append) {
+ this.append = (append ? Boolean.TRUE : Boolean.FALSE);
+ }
+
+
+ /**
+ * Set emacs mode.
+ * @param emacsMode if true use emacs mode
+ */
+ public void setEmacsMode(boolean emacsMode) {
+ this.emacsMode = emacsMode;
+ }
+
+
+ /**
+ * Sets the level to which this recorder entry should log to.
+ * @param level the level to set.
+ * @see VerbosityLevelChoices
+ */
+ public void setLoglevel(VerbosityLevelChoices level) {
+ loglevel = level.getLevel();
+ }
+
+ //////////////////////////////////////////////////////////////////////
+ // CORE / MAIN BODY
+
+ /**
+ * The main execution.
+ * @throws BuildException on error
+ */
+ public void execute() throws BuildException {
+ if (filename == null) {
+ throw new BuildException("No filename specified");
+ }
+
+ getProject().log("setting a recorder for name " + filename,
+ Project.MSG_DEBUG);
+
+ // get the recorder entry
+ RecorderEntry recorder = getRecorder(filename, getProject());
+ // set the values on the recorder
+ recorder.setMessageOutputLevel(loglevel);
+ recorder.setEmacsMode(emacsMode);
+ if (start != null) {
+ if (start.booleanValue()) {
+ recorder.reopenFile();
+ recorder.setRecordState(start);
+ } else {
+ recorder.setRecordState(start);
+ recorder.closeFile();
+ }
+ }
+ }
+
+ //////////////////////////////////////////////////////////////////////
+ // INNER CLASSES
+
+ /**
+ * A list of possible values for the <code>setAction()</code> method.
+ * Possible values include: start and stop.
+ */
+ public static class ActionChoices extends EnumeratedAttribute {
+ private static final String[] VALUES = {"start", "stop"};
+
+ /**
+ * @see EnumeratedAttribute#getValues()
+ */
+ /** {@inheritDoc}. */
+ public String[] getValues() {
+ return VALUES;
+ }
+ }
+
+
+ /**
+ * A list of possible values for the <code>setLoglevel()</code> method.
+ * Possible values include: error, warn, info, verbose, debug.
+ */
+ public static class VerbosityLevelChoices extends LogLevel {
+ }
+
+
+ /**
+ * Gets the recorder that's associated with the passed in name. If the
+ * recorder doesn't exist, then a new one is created.
+ * @param name the name of the recorder
+ * @param proj the current project
+ * @return a recorder
+ * @throws BuildException on error
+ */
+ protected RecorderEntry getRecorder(String name, Project proj)
+ throws BuildException {
+ Object o = recorderEntries.get(name);
+ RecorderEntry entry;
+
+ if (o == null) {
+ // create a recorder entry
+ entry = new RecorderEntry(name);
+
+ if (append == null) {
+ entry.openFile(false);
+ } else {
+ entry.openFile(append.booleanValue());
+ }
+ entry.setProject(proj);
+ recorderEntries.put(name, entry);
+ } else {
+ entry = (RecorderEntry) o;
+ }
+ return entry;
+ }
+
+ /**
+ * Empty implementation required by SubBuildListener interface.
+ * @param event ignored.
+ * @since Ant 1.7
+ */
+ public void buildStarted(BuildEvent event) {
+ }
+
+ /**
+ * Empty implementation required by SubBuildListener interface.
+ * @param event ignored.
+ * @since Ant 1.7
+ */
+ public void subBuildStarted(BuildEvent event) {
+ }
+
+ /**
+ * Empty implementation required by SubBuildListener interface.
+ * @param event ignored.
+ * @since Ant 1.7
+ */
+ public void targetStarted(BuildEvent event) {
+ }
+
+ /**
+ * Empty implementation required by SubBuildListener interface.
+ * @param event ignored.
+ * @since Ant 1.7
+ */
+ public void targetFinished(BuildEvent event) {
+ }
+
+ /**
+ * Empty implementation required by SubBuildListener interface.
+ * @param event ignored.
+ * @since Ant 1.7
+ */
+ public void taskStarted(BuildEvent event) {
+ }
+
+ /**
+ * Empty implementation required by SubBuildListener interface.
+ * @param event ignored.
+ * @since Ant 1.7
+ */
+ public void taskFinished(BuildEvent event) {
+ }
+
+ /**
+ * Empty implementation required by SubBuildListener interface.
+ * @param event ignored.
+ * @since Ant 1.7
+ */
+ public void messageLogged(BuildEvent event) {
+ }
+
+ /**
+ * Cleans recorder registry.
+ * @param event ignored.
+ * @since Ant 1.7
+ */
+ public void buildFinished(BuildEvent event) {
+ cleanup();
+ }
+
+ /**
+ * Cleans recorder registry, if this is the subbuild the task has
+ * been created in.
+ * @param event ignored.
+ * @since Ant 1.7
+ */
+ public void subBuildFinished(BuildEvent event) {
+ if (event.getProject() == getProject()) {
+ cleanup();
+ }
+ }
+
+ /**
+ * cleans recorder registry and removes itself from BuildListener list.
+ *
+ * @since Ant 1.7
+ */
+ private void cleanup() {
+ Hashtable entries = (Hashtable) recorderEntries.clone();
+ Iterator itEntries = entries.entrySet().iterator();
+ while (itEntries.hasNext()) {
+ Map.Entry entry = (Map.Entry) itEntries.next();
+ RecorderEntry re = (RecorderEntry) entry.getValue();
+ if (re.getProject() == getProject()) {
+ recorderEntries.remove(entry.getKey());
+ }
+ }
+ getProject().removeBuildListener(this);
+ }
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/RecorderEntry.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/RecorderEntry.java
new file mode 100644
index 00000000..dfb8e845
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/RecorderEntry.java
@@ -0,0 +1,367 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+
+import org.apache.tools.ant.BuildEvent;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.BuildLogger;
+import org.apache.tools.ant.DefaultLogger;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.SubBuildListener;
+import org.apache.tools.ant.util.StringUtils;
+
+/**
+ * This is a class that represents a recorder. This is the listener to the
+ * build process.
+ *
+ * @since Ant 1.4
+ */
+public class RecorderEntry implements BuildLogger, SubBuildListener {
+
+ //////////////////////////////////////////////////////////////////////
+ // ATTRIBUTES
+
+ /** The name of the file associated with this recorder entry. */
+ private String filename = null;
+ /** The state of the recorder (recorder on or off). */
+ private boolean record = true;
+ /** The current verbosity level to record at. */
+ private int loglevel = Project.MSG_INFO;
+ /** The output PrintStream to record to. */
+ private PrintStream out = null;
+ /** The start time of the last know target. */
+ private long targetStartTime = 0L;
+ /** Strip task banners if true. */
+ private boolean emacsMode = false;
+ /** project instance the recorder is associated with */
+ private Project project;
+
+ //////////////////////////////////////////////////////////////////////
+ // CONSTRUCTORS / INITIALIZERS
+
+ /**
+ * @param name The name of this recorder (used as the filename).
+ */
+ protected RecorderEntry(String name) {
+ targetStartTime = System.currentTimeMillis();
+ filename = name;
+ }
+
+ //////////////////////////////////////////////////////////////////////
+ // ACCESSOR METHODS
+
+ /**
+ * @return the name of the file the output is sent to.
+ */
+ public String getFilename() {
+ return filename;
+ }
+
+ /**
+ * Turns off or on this recorder.
+ *
+ * @param state true for on, false for off, null for no change.
+ */
+ public void setRecordState(Boolean state) {
+ if (state != null) {
+ flush();
+ record = state.booleanValue();
+ }
+ }
+
+ /**
+ * @see org.apache.tools.ant.BuildListener#buildStarted(BuildEvent)
+ */
+ /** {@inheritDoc}. */
+ public void buildStarted(BuildEvent event) {
+ log("> BUILD STARTED", Project.MSG_DEBUG);
+ }
+
+ /**
+ * @see org.apache.tools.ant.BuildListener#buildFinished(BuildEvent)
+ */
+ /** {@inheritDoc}. */
+ public void buildFinished(BuildEvent event) {
+ log("< BUILD FINISHED", Project.MSG_DEBUG);
+
+ if (record && out != null) {
+ Throwable error = event.getException();
+
+ if (error == null) {
+ out.println(StringUtils.LINE_SEP + "BUILD SUCCESSFUL");
+ } else {
+ out.println(StringUtils.LINE_SEP + "BUILD FAILED"
+ + StringUtils.LINE_SEP);
+ error.printStackTrace(out);
+ }
+ }
+ cleanup();
+ }
+
+ /**
+ * Cleans up any resources held by this recorder entry at the end
+ * of a subbuild if it has been created for the subbuild's project
+ * instance.
+ *
+ * @param event the buildFinished event
+ *
+ * @since Ant 1.6.2
+ */
+ public void subBuildFinished(BuildEvent event) {
+ if (event.getProject() == project) {
+ cleanup();
+ }
+ }
+
+ /**
+ * Empty implementation to satisfy the BuildListener interface.
+ *
+ * @param event the buildStarted event
+ *
+ * @since Ant 1.6.2
+ */
+ public void subBuildStarted(BuildEvent event) {
+ }
+
+ /**
+ * @see org.apache.tools.ant.BuildListener#targetStarted(BuildEvent)
+ */
+ /** {@inheritDoc}. */
+ public void targetStarted(BuildEvent event) {
+ log(">> TARGET STARTED -- " + event.getTarget(), Project.MSG_DEBUG);
+ log(StringUtils.LINE_SEP + event.getTarget().getName() + ":",
+ Project.MSG_INFO);
+ targetStartTime = System.currentTimeMillis();
+ }
+
+ /**
+ * @see org.apache.tools.ant.BuildListener#targetFinished(BuildEvent)
+ */
+ /** {@inheritDoc}. */
+ public void targetFinished(BuildEvent event) {
+ log("<< TARGET FINISHED -- " + event.getTarget(), Project.MSG_DEBUG);
+
+ String time = formatTime(System.currentTimeMillis() - targetStartTime);
+
+ log(event.getTarget() + ": duration " + time, Project.MSG_VERBOSE);
+ flush();
+ }
+
+ /**
+ * @see org.apache.tools.ant.BuildListener#taskStarted(BuildEvent)
+ */
+ /** {@inheritDoc}. */
+ public void taskStarted(BuildEvent event) {
+ log(">>> TASK STARTED -- " + event.getTask(), Project.MSG_DEBUG);
+ }
+
+ /**
+ * @see org.apache.tools.ant.BuildListener#taskFinished(BuildEvent)
+ */
+ /** {@inheritDoc}. */
+ public void taskFinished(BuildEvent event) {
+ log("<<< TASK FINISHED -- " + event.getTask(), Project.MSG_DEBUG);
+ flush();
+ }
+
+ /**
+ * @see org.apache.tools.ant.BuildListener#messageLogged(BuildEvent)
+ */
+ /** {@inheritDoc}. */
+ public void messageLogged(BuildEvent event) {
+ log("--- MESSAGE LOGGED", Project.MSG_DEBUG);
+
+ StringBuffer buf = new StringBuffer();
+
+ if (event.getTask() != null) {
+ String name = event.getTask().getTaskName();
+
+ if (!emacsMode) {
+ String label = "[" + name + "] ";
+ int size = DefaultLogger.LEFT_COLUMN_SIZE - label.length();
+
+ for (int i = 0; i < size; i++) {
+ buf.append(" ");
+ }
+ buf.append(label);
+ }
+ }
+ buf.append(event.getMessage());
+
+ log(buf.toString(), event.getPriority());
+ }
+
+
+ /**
+ * The thing that actually sends the information to the output.
+ *
+ * @param mesg The message to log.
+ * @param level The verbosity level of the message.
+ */
+ private void log(String mesg, int level) {
+ if (record && (level <= loglevel) && out != null) {
+ out.println(mesg);
+ }
+ }
+
+ private void flush() {
+ if (record && out != null) {
+ out.flush();
+ }
+ }
+
+ /**
+ * @see BuildLogger#setMessageOutputLevel(int)
+ */
+ /** {@inheritDoc}. */
+ public void setMessageOutputLevel(int level) {
+ if (level >= Project.MSG_ERR && level <= Project.MSG_DEBUG) {
+ loglevel = level;
+ }
+ }
+
+ /**
+ * @see BuildLogger#setOutputPrintStream(PrintStream)
+ */
+ /** {@inheritDoc}. */
+ public void setOutputPrintStream(PrintStream output) {
+ closeFile();
+ out = output;
+ }
+
+
+ /**
+ * @see BuildLogger#setEmacsMode(boolean)
+ */
+ /** {@inheritDoc}. */
+ public void setEmacsMode(boolean emacsMode) {
+ this.emacsMode = emacsMode;
+ }
+
+
+ /**
+ * @see BuildLogger#setErrorPrintStream(PrintStream)
+ */
+ /** {@inheritDoc}. */
+ public void setErrorPrintStream(PrintStream err) {
+ setOutputPrintStream(err);
+ }
+
+
+ private static String formatTime(long millis) {
+ // CheckStyle:MagicNumber OFF
+ long seconds = millis / 1000;
+ long minutes = seconds / 60;
+
+
+ if (minutes > 0) {
+ return Long.toString(minutes) + " minute"
+ + (minutes == 1 ? " " : "s ")
+ + Long.toString(seconds % 60) + " second"
+ + (seconds % 60 == 1 ? "" : "s");
+ } else {
+ return Long.toString(seconds) + " second"
+ + (seconds % 60 == 1 ? "" : "s");
+ }
+ // CheckStyle:MagicNumber ON
+ }
+
+ /**
+ * Set the project associated with this recorder entry.
+ *
+ * @param project the project instance
+ *
+ * @since 1.6.2
+ */
+ public void setProject(Project project) {
+ this.project = project;
+ if (project != null) {
+ project.addBuildListener(this);
+ }
+ }
+
+ /**
+ * Get the project associated with this recorder entry.
+ *
+ * @since 1.8.0
+ */
+ public Project getProject() {
+ return project;
+ }
+
+ /**
+ * @since 1.6.2
+ */
+ public void cleanup() {
+ closeFile();
+ if (project != null) {
+ project.removeBuildListener(this);
+ }
+ project = null;
+ }
+
+ /**
+ * Initially opens the file associated with this recorder.
+ * Used by Recorder.
+ * @param append Indicates if output must be appended to the logfile or that
+ * the logfile should be overwritten.
+ * @throws BuildException
+ * @since 1.6.3
+ */
+ void openFile(boolean append) throws BuildException {
+ openFileImpl(append);
+ }
+
+ /**
+ * Closes the file associated with this recorder.
+ * Used by Recorder.
+ * @since 1.6.3
+ */
+ void closeFile() {
+ if (out != null) {
+ out.close();
+ out = null;
+ }
+ }
+
+ /**
+ * Re-opens the file associated with this recorder.
+ * Used by Recorder.
+ * @throws BuildException
+ * @since 1.6.3
+ */
+ void reopenFile() throws BuildException {
+ openFileImpl(true);
+ }
+
+ private void openFileImpl(boolean append) throws BuildException {
+ if (out == null) {
+ try {
+ out = new PrintStream(new FileOutputStream(filename, append));
+ } catch (IOException ioe) {
+ throw new BuildException("Problems opening file using a "
+ + "recorder entry", ioe);
+ }
+ }
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Redirector.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Redirector.java
new file mode 100644
index 00000000..3b35d231
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Redirector.java
@@ -0,0 +1,1022 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.PipedOutputStream;
+import java.io.PrintStream;
+import java.io.Reader;
+import java.io.StringReader;
+import java.util.Arrays;
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.ProjectComponent;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.filters.util.ChainReaderHelper;
+import org.apache.tools.ant.types.FilterChain;
+import org.apache.tools.ant.util.ConcatFileInputStream;
+import org.apache.tools.ant.util.KeepAliveOutputStream;
+import org.apache.tools.ant.util.LazyFileOutputStream;
+import org.apache.tools.ant.util.LeadPipeInputStream;
+import org.apache.tools.ant.util.LineOrientedOutputStreamRedirector;
+import org.apache.tools.ant.util.OutputStreamFunneler;
+import org.apache.tools.ant.util.ReaderInputStream;
+import org.apache.tools.ant.util.StringUtils;
+import org.apache.tools.ant.util.TeeOutputStream;
+
+/**
+ * The Redirector class manages the setup and connection of input and output
+ * redirection for an Ant project component.
+ *
+ * @since Ant 1.6
+ */
+public class Redirector {
+ private static final int STREAMPUMPER_WAIT_INTERVAL = 1000;
+
+ private static final String DEFAULT_ENCODING = System
+ .getProperty("file.encoding");
+
+ private class PropertyOutputStream extends ByteArrayOutputStream {
+ private final String property;
+
+ private boolean closed = false;
+
+ PropertyOutputStream(final String property) {
+ super();
+ this.property = property;
+ }
+
+ @Override
+ public void close() throws IOException {
+ synchronized (outMutex) {
+ if (!closed && !(appendOut && appendProperties)) {
+ setPropertyFromBAOS(this, property);
+ closed = true;
+ }
+ }
+ }
+ }
+
+ /**
+ * The file(s) from which standard input is being taken. If &gt; 1, files'
+ * content will be concatenated in the order received.
+ */
+ private File[] input;
+
+ /**
+ * The file(s) receiving standard output. Will also receive standard error
+ * unless standard error is redirected or logError is true.
+ */
+ private File[] out;
+
+ /**
+ * The file(s) to which standard error is being redirected
+ */
+ private File[] error;
+
+ /**
+ * Indicates if standard error should be logged to Ant's log system rather
+ * than the output. This has no effect if standard error is redirected to a
+ * file or property.
+ */
+ private boolean logError = false;
+
+ /**
+ * Buffer used to capture output for storage into a property
+ */
+ private PropertyOutputStream baos = null;
+
+ /**
+ * Buffer used to capture error output for storage into a property
+ */
+ private PropertyOutputStream errorBaos = null;
+
+ /** The name of the property into which output is to be stored */
+ private String outputProperty;
+
+ /** The name of the property into which error output is to be stored */
+ private String errorProperty;
+
+ /** String from which input is taken */
+ private String inputString;
+
+ /** Flag which indicates if error and output files are to be appended. */
+ private boolean appendOut = false;
+
+ private boolean appendErr = false;
+
+ /** Flag which indicates that output should be always sent to the log */
+ private boolean alwaysLogOut = false;
+
+ private boolean alwaysLogErr = false;
+
+ /** Flag which indicates whether files should be created even when empty. */
+ private boolean createEmptyFilesOut = true;
+
+ private boolean createEmptyFilesErr = true;
+
+ /** The task for which this redirector is working */
+ private final ProjectComponent managingTask;
+
+ /** The stream for output data */
+ private OutputStream outputStream = null;
+
+ /** The stream for error output */
+ private OutputStream errorStream = null;
+
+ /** The stream for input */
+ private InputStream inputStream = null;
+
+ /** Stream which is used for line oriented output */
+ private PrintStream outPrintStream = null;
+
+ /** Stream which is used for line oriented error output */
+ private PrintStream errorPrintStream = null;
+
+ /** The output filter chains */
+ private Vector<FilterChain> outputFilterChains;
+
+ /** The error filter chains */
+ private Vector<FilterChain> errorFilterChains;
+
+ /** The input filter chains */
+ private Vector<FilterChain> inputFilterChains;
+
+ /** The output encoding */
+ private String outputEncoding = DEFAULT_ENCODING;
+
+ /** The error encoding */
+ private String errorEncoding = DEFAULT_ENCODING;
+
+ /** The input encoding */
+ private String inputEncoding = DEFAULT_ENCODING;
+
+ /** Whether to complete properties settings **/
+ private boolean appendProperties = true;
+
+ /** The thread group used for starting <code>StreamPumper</code> threads */
+ private final ThreadGroup threadGroup = new ThreadGroup("redirector");
+
+ /** whether to log the inputstring */
+ private boolean logInputString = true;
+
+ /** Mutex for in */
+ private final Object inMutex = new Object();
+
+ /** Mutex for out */
+ private final Object outMutex = new Object();
+
+ /** Mutex for err */
+ private final Object errMutex = new Object();
+
+ /** Is the output binary or can we safely split it into lines? */
+ private boolean outputIsBinary = false;
+
+ /**
+ * Create a redirector instance for the given task
+ *
+ * @param managingTask
+ * the task for which the redirector is to work
+ */
+ public Redirector(final Task managingTask) {
+ this((ProjectComponent) managingTask);
+ }
+
+ /**
+ * Create a redirector instance for the given task
+ *
+ * @param managingTask
+ * the project component for which the redirector is to work
+ * @since Ant 1.6.3
+ */
+ public Redirector(final ProjectComponent managingTask) {
+ this.managingTask = managingTask;
+ }
+
+ /**
+ * Set the input to use for the task
+ *
+ * @param input
+ * the file from which input is read.
+ */
+ public void setInput(final File input) {
+ setInput((input == null) ? null : new File[] {input});
+ }
+
+ /**
+ * Set the input to use for the task
+ *
+ * @param input
+ * the files from which input is read.
+ */
+ public void setInput(final File[] input) {
+ synchronized (inMutex) {
+ if (input == null) {
+ this.input = null;
+ } else {
+ this.input = input.clone();
+ }
+ }
+ }
+
+ /**
+ * Set the string to use as input
+ *
+ * @param inputString
+ * the string which is used as the input source
+ */
+ public void setInputString(final String inputString) {
+ synchronized (inMutex) {
+ this.inputString = inputString;
+ }
+ }
+
+ /**
+ * Set whether to include the value of the input string in log messages.
+ * Defaults to true.
+ *
+ * @param logInputString
+ * true or false.
+ * @since Ant 1.7
+ */
+ public void setLogInputString(final boolean logInputString) {
+ this.logInputString = logInputString;
+ }
+
+ /**
+ * Set a stream to use as input.
+ *
+ * @param inputStream
+ * the stream from which input will be read
+ * @since Ant 1.6.3
+ */
+ /* public */void setInputStream(final InputStream inputStream) {
+ synchronized (inMutex) {
+ this.inputStream = inputStream;
+ }
+ }
+
+ /**
+ * File the output of the process is redirected to. If error is not
+ * redirected, it too will appear in the output
+ *
+ * @param out
+ * the file to which output stream is written
+ */
+ public void setOutput(final File out) {
+ setOutput((out == null) ? null : new File[] {out});
+ }
+
+ /**
+ * Files the output of the process is redirected to. If error is not
+ * redirected, it too will appear in the output
+ *
+ * @param out
+ * the files to which output stream is written
+ */
+ public void setOutput(final File[] out) {
+ synchronized (outMutex) {
+ if (out == null) {
+ this.out = null;
+ } else {
+ this.out = out.clone();
+ }
+ }
+ }
+
+ /**
+ * Set the output encoding.
+ *
+ * @param outputEncoding
+ * <code>String</code>.
+ */
+ public void setOutputEncoding(final String outputEncoding) {
+ if (outputEncoding == null) {
+ throw new IllegalArgumentException(
+ "outputEncoding must not be null");
+ }
+ synchronized (outMutex) {
+ this.outputEncoding = outputEncoding;
+ }
+ }
+
+ /**
+ * Set the error encoding.
+ *
+ * @param errorEncoding
+ * <code>String</code>.
+ */
+ public void setErrorEncoding(final String errorEncoding) {
+ if (errorEncoding == null) {
+ throw new IllegalArgumentException("errorEncoding must not be null");
+ }
+ synchronized (errMutex) {
+ this.errorEncoding = errorEncoding;
+ }
+ }
+
+ /**
+ * Set the input encoding.
+ *
+ * @param inputEncoding
+ * <code>String</code>.
+ */
+ public void setInputEncoding(final String inputEncoding) {
+ if (inputEncoding == null) {
+ throw new IllegalArgumentException("inputEncoding must not be null");
+ }
+ synchronized (inMutex) {
+ this.inputEncoding = inputEncoding;
+ }
+ }
+
+ /**
+ * Controls whether error output of exec is logged. This is only useful when
+ * output is being redirected and error output is desired in the Ant log
+ *
+ * @param logError
+ * if true the standard error is sent to the Ant log system and
+ * not sent to output.
+ */
+ public void setLogError(final boolean logError) {
+ synchronized (errMutex) {
+ this.logError = logError;
+ }
+ }
+
+ /**
+ * This <code>Redirector</code>'s subordinate
+ * <code>PropertyOutputStream</code>s will not set their respective
+ * properties <code>while (appendProperties &amp;&amp; append)</code>.
+ *
+ * @param appendProperties
+ * whether to append properties.
+ */
+ public void setAppendProperties(final boolean appendProperties) {
+ synchronized (outMutex) {
+ this.appendProperties = appendProperties;
+ }
+ }
+
+ /**
+ * Set the file to which standard error is to be redirected.
+ *
+ * @param error
+ * the file to which error is to be written
+ */
+ public void setError(final File error) {
+ setError((error == null) ? null : new File[] {error});
+ }
+
+ /**
+ * Set the files to which standard error is to be redirected.
+ *
+ * @param error
+ * the file to which error is to be written
+ */
+ public void setError(final File[] error) {
+ synchronized (errMutex) {
+ if (error == null) {
+ this.error = null;
+ } else {
+ this.error = error.clone();
+ }
+ }
+ }
+
+ /**
+ * Property name whose value should be set to the output of the process.
+ *
+ * @param outputProperty
+ * the name of the property to be set with the task's output.
+ */
+ public void setOutputProperty(final String outputProperty) {
+ if (outputProperty == null
+ || !(outputProperty.equals(this.outputProperty))) {
+ synchronized (outMutex) {
+ this.outputProperty = outputProperty;
+ baos = null;
+ }
+ }
+ }
+
+ /**
+ * Whether output should be appended to or overwrite an existing file.
+ * Defaults to false.
+ *
+ * @param append
+ * if true output and error streams are appended to their
+ * respective files, if specified.
+ */
+ public void setAppend(final boolean append) {
+ synchronized (outMutex) {
+ appendOut = append;
+ }
+ synchronized (errMutex) {
+ appendErr = append;
+ }
+ }
+
+ /**
+ * If true, (error and non-error) output will be "teed", redirected as
+ * specified while being sent to Ant's logging mechanism as if no
+ * redirection had taken place. Defaults to false.
+ *
+ * @param alwaysLog
+ * <code>boolean</code>
+ * @since Ant 1.6.3
+ */
+ public void setAlwaysLog(final boolean alwaysLog) {
+ synchronized (outMutex) {
+ alwaysLogOut = alwaysLog;
+ }
+ synchronized (errMutex) {
+ alwaysLogErr = alwaysLog;
+ }
+ }
+
+ /**
+ * Whether output and error files should be created even when empty.
+ * Defaults to true.
+ *
+ * @param createEmptyFiles
+ * <code>boolean</code>.
+ */
+ public void setCreateEmptyFiles(final boolean createEmptyFiles) {
+ synchronized (outMutex) {
+ createEmptyFilesOut = createEmptyFiles;
+ }
+ synchronized (outMutex) {
+ createEmptyFilesErr = createEmptyFiles;
+ }
+ }
+
+ /**
+ * Property name whose value should be set to the error of the process.
+ *
+ * @param errorProperty
+ * the name of the property to be set with the error output.
+ */
+ public void setErrorProperty(final String errorProperty) {
+ synchronized (errMutex) {
+ if (errorProperty == null
+ || !(errorProperty.equals(this.errorProperty))) {
+ this.errorProperty = errorProperty;
+ errorBaos = null;
+ }
+ }
+ }
+
+ /**
+ * Set the input <code>FilterChain</code>s.
+ *
+ * @param inputFilterChains
+ * <code>Vector</code> containing <code>FilterChain</code>.
+ */
+ public void setInputFilterChains(final Vector<FilterChain> inputFilterChains) {
+ synchronized (inMutex) {
+ this.inputFilterChains = inputFilterChains;
+ }
+ }
+
+ /**
+ * Set the output <code>FilterChain</code>s.
+ *
+ * @param outputFilterChains
+ * <code>Vector</code> containing <code>FilterChain</code>.
+ */
+ public void setOutputFilterChains(final Vector<FilterChain> outputFilterChains) {
+ synchronized (outMutex) {
+ this.outputFilterChains = outputFilterChains;
+ }
+ }
+
+ /**
+ * Set the error <code>FilterChain</code>s.
+ *
+ * @param errorFilterChains
+ * <code>Vector</code> containing <code>FilterChain</code>.
+ */
+ public void setErrorFilterChains(final Vector<FilterChain> errorFilterChains) {
+ synchronized (errMutex) {
+ this.errorFilterChains = errorFilterChains;
+ }
+ }
+
+ /**
+ * Whether to consider the output created by the process binary.
+ *
+ * <p>Binary output will not be split into lines which may make
+ * error and normal output look mixed up when they get written to
+ * the same stream.</p>
+ * @since 1.9.4
+ */
+ public void setBinaryOutput(final boolean b) {
+ outputIsBinary = b;
+ }
+
+ /**
+ * Set a property from a ByteArrayOutputStream
+ *
+ * @param baos
+ * contains the property value.
+ * @param propertyName
+ * the property name.
+ *
+ * @exception IOException
+ * if the value cannot be read form the stream.
+ */
+ private void setPropertyFromBAOS(final ByteArrayOutputStream baos,
+ final String propertyName) throws IOException {
+
+ final BufferedReader in = new BufferedReader(new StringReader(Execute
+ .toString(baos)));
+ String line = null;
+ final StringBuffer val = new StringBuffer();
+ while ((line = in.readLine()) != null) {
+ if (val.length() != 0) {
+ val.append(StringUtils.LINE_SEP);
+ }
+ val.append(line);
+ }
+ managingTask.getProject().setNewProperty(propertyName, val.toString());
+ }
+
+ /**
+ * Create the input, error and output streams based on the configuration
+ * options.
+ */
+ public void createStreams() {
+
+ synchronized (outMutex) {
+ outStreams();
+ if (alwaysLogOut || outputStream == null) {
+ final OutputStream outputLog = new LogOutputStream(managingTask,
+ Project.MSG_INFO);
+ outputStream = (outputStream == null) ? outputLog
+ : new TeeOutputStream(outputLog, outputStream);
+ }
+
+ if ((outputFilterChains != null && outputFilterChains.size() > 0)
+ || !(outputEncoding.equalsIgnoreCase(inputEncoding))) {
+ try {
+ final LeadPipeInputStream snk = new LeadPipeInputStream();
+ snk.setManagingComponent(managingTask);
+
+ InputStream outPumpIn = snk;
+
+ Reader reader = new InputStreamReader(outPumpIn,
+ inputEncoding);
+
+ if (outputFilterChains != null
+ && outputFilterChains.size() > 0) {
+ final ChainReaderHelper helper = new ChainReaderHelper();
+ helper.setProject(managingTask.getProject());
+ helper.setPrimaryReader(reader);
+ helper.setFilterChains(outputFilterChains);
+ reader = helper.getAssembledReader();
+ }
+ outPumpIn = new ReaderInputStream(reader, outputEncoding);
+
+ final Thread t = new Thread(threadGroup, new StreamPumper(
+ outPumpIn, outputStream, true), "output pumper");
+ t.setPriority(Thread.MAX_PRIORITY);
+ outputStream = new PipedOutputStream(snk);
+ t.start();
+ } catch (final IOException eyeOhEx) {
+ throw new BuildException("error setting up output stream",
+ eyeOhEx);
+ }
+ }
+ }
+
+ synchronized (errMutex) {
+ errorStreams();
+ if (alwaysLogErr || errorStream == null) {
+ final OutputStream errorLog = new LogOutputStream(managingTask,
+ Project.MSG_WARN);
+ errorStream = (errorStream == null) ? errorLog
+ : new TeeOutputStream(errorLog, errorStream);
+ }
+
+ if ((errorFilterChains != null && errorFilterChains.size() > 0)
+ || !(errorEncoding.equalsIgnoreCase(inputEncoding))) {
+ try {
+ final LeadPipeInputStream snk = new LeadPipeInputStream();
+ snk.setManagingComponent(managingTask);
+
+ InputStream errPumpIn = snk;
+
+ Reader reader = new InputStreamReader(errPumpIn,
+ inputEncoding);
+
+ if (errorFilterChains != null
+ && errorFilterChains.size() > 0) {
+ final ChainReaderHelper helper = new ChainReaderHelper();
+ helper.setProject(managingTask.getProject());
+ helper.setPrimaryReader(reader);
+ helper.setFilterChains(errorFilterChains);
+ reader = helper.getAssembledReader();
+ }
+ errPumpIn = new ReaderInputStream(reader, errorEncoding);
+
+ final Thread t = new Thread(threadGroup, new StreamPumper(
+ errPumpIn, errorStream, true), "error pumper");
+ t.setPriority(Thread.MAX_PRIORITY);
+ errorStream = new PipedOutputStream(snk);
+ t.start();
+ } catch (final IOException eyeOhEx) {
+ throw new BuildException("error setting up error stream",
+ eyeOhEx);
+ }
+ }
+ }
+
+ synchronized (inMutex) {
+ // if input files are specified, inputString and inputStream are
+ // ignored;
+ // classes that work with redirector attributes can enforce
+ // whatever warnings are needed
+ if (input != null && input.length > 0) {
+ managingTask
+ .log("Redirecting input from file"
+ + ((input.length == 1) ? "" : "s"),
+ Project.MSG_VERBOSE);
+ try {
+ inputStream = new ConcatFileInputStream(input);
+ } catch (final IOException eyeOhEx) {
+ throw new BuildException(eyeOhEx);
+ }
+ ((ConcatFileInputStream) inputStream)
+ .setManagingComponent(managingTask);
+ } else if (inputString != null) {
+ final StringBuffer buf = new StringBuffer("Using input ");
+ if (logInputString) {
+ buf.append('"').append(inputString).append('"');
+ } else {
+ buf.append("string");
+ }
+ managingTask.log(buf.toString(), Project.MSG_VERBOSE);
+ inputStream = new ByteArrayInputStream(inputString.getBytes());
+ }
+
+ if (inputStream != null && inputFilterChains != null
+ && inputFilterChains.size() > 0) {
+ final ChainReaderHelper helper = new ChainReaderHelper();
+ helper.setProject(managingTask.getProject());
+ try {
+ helper.setPrimaryReader(new InputStreamReader(inputStream,
+ inputEncoding));
+ } catch (final IOException eyeOhEx) {
+ throw new BuildException("error setting up input stream",
+ eyeOhEx);
+ }
+ helper.setFilterChains(inputFilterChains);
+ inputStream = new ReaderInputStream(
+ helper.getAssembledReader(), inputEncoding);
+ }
+ }
+ }
+
+ /** outStreams */
+ private void outStreams() {
+ if (out != null && out.length > 0) {
+ final String logHead = new StringBuffer("Output ").append(
+ ((appendOut) ? "appended" : "redirected")).append(" to ")
+ .toString();
+ outputStream = foldFiles(out, logHead, Project.MSG_VERBOSE,
+ appendOut, createEmptyFilesOut);
+ }
+ if (outputProperty != null) {
+ if (baos == null) {
+ baos = new PropertyOutputStream(outputProperty);
+ managingTask.log("Output redirected to property: "
+ + outputProperty, Project.MSG_VERBOSE);
+ }
+ // shield it from being closed by a filtering StreamPumper
+ final OutputStream keepAliveOutput = new KeepAliveOutputStream(baos);
+ outputStream = (outputStream == null) ? keepAliveOutput
+ : new TeeOutputStream(outputStream, keepAliveOutput);
+ } else {
+ baos = null;
+ }
+ }
+
+ private void errorStreams() {
+ if (error != null && error.length > 0) {
+ final String logHead = new StringBuffer("Error ").append(
+ ((appendErr) ? "appended" : "redirected")).append(" to ")
+ .toString();
+ errorStream = foldFiles(error, logHead, Project.MSG_VERBOSE,
+ appendErr, createEmptyFilesErr);
+ } else if (!(logError || outputStream == null) && errorProperty == null) {
+ final long funnelTimeout = 0L;
+ final OutputStreamFunneler funneler = new OutputStreamFunneler(
+ outputStream, funnelTimeout);
+ try {
+ outputStream = funneler.getFunnelInstance();
+ errorStream = funneler.getFunnelInstance();
+ if (!outputIsBinary) {
+ outputStream = new LineOrientedOutputStreamRedirector(outputStream);
+ errorStream = new LineOrientedOutputStreamRedirector(errorStream);
+ }
+ } catch (final IOException eyeOhEx) {
+ throw new BuildException(
+ "error splitting output/error streams", eyeOhEx);
+ }
+ }
+ if (errorProperty != null) {
+ if (errorBaos == null) {
+ errorBaos = new PropertyOutputStream(errorProperty);
+ managingTask.log("Error redirected to property: "
+ + errorProperty, Project.MSG_VERBOSE);
+ }
+ // shield it from being closed by a filtering StreamPumper
+ final OutputStream keepAliveError = new KeepAliveOutputStream(errorBaos);
+ errorStream = (error == null || error.length == 0) ? keepAliveError
+ : new TeeOutputStream(errorStream, keepAliveError);
+ } else {
+ errorBaos = null;
+ }
+ }
+
+ /**
+ * Create the StreamHandler to use with our Execute instance.
+ *
+ * @return the execute stream handler to manage the input, output and error
+ * streams.
+ *
+ * @throws BuildException
+ * if the execute stream handler cannot be created.
+ */
+ public ExecuteStreamHandler createHandler() throws BuildException {
+ createStreams();
+ final boolean nonBlockingRead = input == null && inputString == null;
+ return new PumpStreamHandler(getOutputStream(), getErrorStream(),
+ getInputStream(), nonBlockingRead);
+ }
+
+ /**
+ * Pass output sent to System.out to specified output.
+ *
+ * @param output
+ * the data to be output
+ */
+ protected void handleOutput(final String output) {
+ synchronized (outMutex) {
+ if (outPrintStream == null) {
+ outPrintStream = new PrintStream(outputStream);
+ }
+ outPrintStream.print(output);
+ }
+ }
+
+ /**
+ * Handle an input request
+ *
+ * @param buffer
+ * the buffer into which data is to be read.
+ * @param offset
+ * the offset into the buffer at which data is stored.
+ * @param length
+ * the amount of data to read
+ *
+ * @return the number of bytes read
+ *
+ * @exception IOException
+ * if the data cannot be read
+ */
+ protected int handleInput(final byte[] buffer, final int offset, final int length)
+ throws IOException {
+ synchronized (inMutex) {
+ if (inputStream == null) {
+ return managingTask.getProject().defaultInput(buffer, offset,
+ length);
+ }
+ return inputStream.read(buffer, offset, length);
+
+ }
+ }
+
+ /**
+ * Process data due to a flush operation.
+ *
+ * @param output
+ * the data being flushed.
+ */
+ protected void handleFlush(final String output) {
+ synchronized (outMutex) {
+ if (outPrintStream == null) {
+ outPrintStream = new PrintStream(outputStream);
+ }
+ outPrintStream.print(output);
+ outPrintStream.flush();
+ }
+ }
+
+ /**
+ * Process error output
+ *
+ * @param output
+ * the error output data.
+ */
+ protected void handleErrorOutput(final String output) {
+ synchronized (errMutex) {
+ if (errorPrintStream == null) {
+ errorPrintStream = new PrintStream(errorStream);
+ }
+ errorPrintStream.print(output);
+ }
+ }
+
+ /**
+ * Handle a flush operation on the error stream
+ *
+ * @param output
+ * the error information being flushed.
+ */
+ protected void handleErrorFlush(final String output) {
+ synchronized (errMutex) {
+ if (errorPrintStream == null) {
+ errorPrintStream = new PrintStream(errorStream);
+ }
+ errorPrintStream.print(output);
+ errorPrintStream.flush();
+ }
+ }
+
+ /**
+ * Get the output stream for the redirector
+ *
+ * @return the redirector's output stream or null if no output has been
+ * configured
+ */
+ public OutputStream getOutputStream() {
+ synchronized (outMutex) {
+ return outputStream;
+ }
+ }
+
+ /**
+ * Get the error stream for the redirector
+ *
+ * @return the redirector's error stream or null if no output has been
+ * configured
+ */
+ public OutputStream getErrorStream() {
+ synchronized (errMutex) {
+ return errorStream;
+ }
+ }
+
+ /**
+ * Get the input stream for the redirector
+ *
+ * @return the redirector's input stream or null if no output has been
+ * configured
+ */
+ public InputStream getInputStream() {
+ synchronized (inMutex) {
+ return inputStream;
+ }
+ }
+
+ /**
+ * Complete redirection.
+ *
+ * This operation will close any streams and create any specified property
+ * values.
+ *
+ * @throws IOException
+ * if the output properties cannot be read from their output
+ * streams.
+ */
+ public void complete() throws IOException {
+ System.out.flush();
+ System.err.flush();
+
+ synchronized (inMutex) {
+ if (inputStream != null) {
+ inputStream.close();
+ }
+ }
+
+ synchronized (outMutex) {
+ outputStream.flush();
+ outputStream.close();
+ }
+
+ synchronized (errMutex) {
+ errorStream.flush();
+ errorStream.close();
+ }
+
+ // wait for the StreamPumpers to finish
+ synchronized (this) {
+ while (threadGroup.activeCount() > 0) {
+ try {
+ managingTask.log("waiting for " + threadGroup.activeCount()
+ + " Threads:", Project.MSG_DEBUG);
+ final Thread[] thread = new Thread[threadGroup.activeCount()];
+ threadGroup.enumerate(thread);
+ for (int i = 0; i < thread.length && thread[i] != null; i++) {
+ try {
+ managingTask.log(thread[i].toString(),
+ Project.MSG_DEBUG);
+ } catch (final NullPointerException enPeaEx) {
+ // Ignore exception
+ }
+ }
+ wait(STREAMPUMPER_WAIT_INTERVAL);
+ } catch (final InterruptedException eyeEx) {
+ final Thread[] thread = new Thread[threadGroup.activeCount()];
+ threadGroup.enumerate(thread);
+ for (int i = 0; i < thread.length && thread[i] != null; i++) {
+ thread[i].interrupt();
+ }
+ }
+ }
+ }
+
+ setProperties();
+
+ synchronized (inMutex) {
+ inputStream = null;
+ }
+ synchronized (outMutex) {
+ outputStream = null;
+ outPrintStream = null;
+ }
+ synchronized (errMutex) {
+ errorStream = null;
+ errorPrintStream = null;
+ }
+ }
+
+ /**
+ * Notify the <code>Redirector</code> that it is now okay to set any output
+ * and/or error properties.
+ */
+ public void setProperties() {
+ synchronized (outMutex) {
+ if (baos != null) {
+ try {
+ baos.close();
+ } catch (final IOException eyeOhEx) {
+ // Ignore exception
+ }
+ }
+ }
+ synchronized (errMutex) {
+ if (errorBaos != null) {
+ try {
+ errorBaos.close();
+ } catch (final IOException eyeOhEx) {
+ // Ignore exception
+ }
+ }
+ }
+ }
+
+ private OutputStream foldFiles(final File[] file, final String logHead, final int loglevel,
+ final boolean append, final boolean createEmptyFiles) {
+ final OutputStream result = new LazyFileOutputStream(file[0], append,
+ createEmptyFiles);
+
+ managingTask.log(logHead + file[0], loglevel);
+ final char[] c = new char[logHead.length()];
+ Arrays.fill(c, ' ');
+ final String indent = new String(c);
+
+ for (int i = 1; i < file.length; i++) {
+ outputStream = new TeeOutputStream(outputStream,
+ new LazyFileOutputStream(file[i], append, createEmptyFiles));
+ managingTask.log(indent + file[i], loglevel);
+ }
+ return result;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Rename.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Rename.java
new file mode 100644
index 00000000..382c2a77
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Rename.java
@@ -0,0 +1,96 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.util.FileUtils;
+
+/**
+ * Renames a file.
+ *
+ * @deprecated The rename task is deprecated since Ant 1.2. Use move instead.
+ * @since Ant 1.1
+ */
+public class Rename extends Task {
+
+ private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+
+ private File src;
+ private File dest;
+ private boolean replace = true;
+
+
+ /**
+ * Sets the file to be renamed.
+ * @param src the file to rename
+ */
+ public void setSrc(File src) {
+ this.src = src;
+ }
+
+ /**
+ * Sets the new name of the file.
+ * @param dest the new name of the file.
+ */
+ public void setDest(File dest) {
+ this.dest = dest;
+ }
+
+ /**
+ * Sets whether an existing file should be replaced.
+ * @param replace <code>on</code>, if an existing file should be replaced.
+ */
+ public void setReplace(String replace) {
+ this.replace = Project.toBoolean(replace);
+ }
+
+
+ /**
+ * Renames the file <code>src</code> to <code>dest</code>
+ * @exception org.apache.tools.ant.BuildException The exception is
+ * thrown, if the rename operation fails.
+ */
+ public void execute() throws BuildException {
+ log("DEPRECATED - The rename task is deprecated. Use move instead.");
+
+ if (dest == null) {
+ throw new BuildException("dest attribute is required", getLocation());
+ }
+
+ if (src == null) {
+ throw new BuildException("src attribute is required", getLocation());
+ }
+
+ if (!replace && dest.exists()) {
+ throw new BuildException(dest + " already exists.");
+ }
+
+ try {
+ FILE_UTILS.rename(src, dest);
+ } catch (IOException e) {
+ throw new BuildException("Unable to rename " + src + " to "
+ + dest, e, getLocation());
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Replace.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Replace.java
new file mode 100644
index 00000000..9aa9fe8e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Replace.java
@@ -0,0 +1,955 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Reader;
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.Properties;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.DirectoryScanner;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.ResourceCollection;
+import org.apache.tools.ant.types.resources.FileProvider;
+import org.apache.tools.ant.types.resources.FileResource;
+import org.apache.tools.ant.types.resources.Union;
+import org.apache.tools.ant.util.FileUtils;
+import org.apache.tools.ant.util.StringUtils;
+
+/**
+ * Replaces all occurrences of one or more string tokens with given
+ * values in the indicated files. Each value can be either a string
+ * or the value of a property available in a designated property file.
+ * If you want to replace a text that crosses line boundaries, you
+ * must use a nested <code>&lt;replacetoken&gt;</code> element.
+ *
+ * @since Ant 1.1
+ *
+ * @ant.task category="filesystem"
+ */
+public class Replace extends MatchingTask {
+
+ private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+
+ private File sourceFile = null;
+ private NestedString token = null;
+ private NestedString value = new NestedString();
+
+ private Resource propertyResource = null;
+ private Resource replaceFilterResource = null;
+ private Properties properties = null;
+ private ArrayList replacefilters = new ArrayList();
+
+ private File dir = null;
+
+ private int fileCount;
+ private int replaceCount;
+ private boolean summary = false;
+
+ /** The encoding used to read and write files - if null, uses default */
+ private String encoding = null;
+
+ private Union resources;
+
+ private boolean preserveLastModified = false;
+ private boolean failOnNoReplacements = false;
+
+ /**
+ * An inline string to use as the replacement text.
+ */
+ public class NestedString {
+
+ private boolean expandProperties = false;
+ private StringBuffer buf = new StringBuffer();
+
+ /**
+ * Whether properties should be expanded in nested test.
+ *
+ * <p>If you use this class via its Java interface the text
+ * you add via {@link #addText addText} has most likely been
+ * expanded already so you do <b>not</b> want to set this to
+ * true.</p>
+ *
+ * @since Ant 1.8.0
+ */
+ public void setExpandProperties(boolean b) {
+ expandProperties = b;
+ }
+
+ /**
+ * The text of the element.
+ *
+ * @param val the string to add
+ */
+ public void addText(String val) {
+ buf.append(val);
+ }
+
+ /**
+ * @return the text
+ */
+ public String getText() {
+ String s = buf.toString();
+ return expandProperties ? getProject().replaceProperties(s) : s;
+ }
+ }
+
+ /**
+ * A filter to apply.
+ */
+ public class Replacefilter {
+ private NestedString token;
+ private NestedString value;
+ private String replaceValue;
+ private String property;
+
+ private StringBuffer inputBuffer;
+ private StringBuffer outputBuffer = new StringBuffer();
+
+ /**
+ * Validate the filter's configuration.
+ * @throws BuildException if any part is invalid.
+ */
+ public void validate() throws BuildException {
+ //Validate mandatory attributes
+ if (token == null) {
+ String message = "token is a mandatory for replacefilter.";
+ throw new BuildException(message);
+ }
+
+ if ("".equals(token.getText())) {
+ String message = "The token must not be an empty "
+ + "string.";
+ throw new BuildException(message);
+ }
+
+ //value and property are mutually exclusive attributes
+ if ((value != null) && (property != null)) {
+ String message = "Either value or property "
+ + "can be specified, but a replacefilter "
+ + "element cannot have both.";
+ throw new BuildException(message);
+ }
+
+ if ((property != null)) {
+ //the property attribute must have access to a property file
+ if (propertyResource == null) {
+ String message = "The replacefilter's property attribute "
+ + "can only be used with the replacetask's "
+ + "propertyFile/Resource attribute.";
+ throw new BuildException(message);
+ }
+
+ //Make sure property exists in property file
+ if (properties == null
+ || properties.getProperty(property) == null) {
+ String message = "property \"" + property
+ + "\" was not found in " + propertyResource.getName();
+ throw new BuildException(message);
+ }
+ }
+
+ replaceValue = getReplaceValue();
+ }
+
+ /**
+ * Get the replacement value for this filter token.
+ * @return the replacement value
+ */
+ public String getReplaceValue() {
+ if (property != null) {
+ return properties.getProperty(property);
+ } else if (value != null) {
+ return value.getText();
+ } else if (Replace.this.value != null) {
+ return Replace.this.value.getText();
+ } else {
+ //Default is empty string
+ return "";
+ }
+ }
+
+ /**
+ * Set the token to replace.
+ * @param t <code>String</code> token.
+ */
+ public void setToken(String t) {
+ createReplaceToken().addText(t);
+ }
+
+ /**
+ * Get the string to search for.
+ * @return current <code>String</code> token.
+ */
+ public String getToken() {
+ return token.getText();
+ }
+
+ /**
+ * The replacement string; required if <code>property</code>
+ * is not set.
+ * @param value <code>String</code> value to replace.
+ */
+ public void setValue(String value) {
+ createReplaceValue().addText(value);
+ }
+
+ /**
+ * Get replacement <code>String</code>.
+ * @return replacement or null.
+ */
+ public String getValue() {
+ return value.getText();
+ }
+
+ /**
+ * Set the name of the property whose value is to serve as
+ * the replacement value; required if <code>value</code> is not set.
+ * @param property property name.
+ */
+ public void setProperty(String property) {
+ this.property = property;
+ }
+
+ /**
+ * Get the name of the property whose value is to serve as
+ * the replacement value.
+ * @return property or null.
+ */
+ public String getProperty() {
+ return property;
+ }
+
+ /**
+ * Create a token to filter as the text of a nested element.
+ * @return nested token <code>NestedString</code> to configure.
+ * @since Ant 1.8.0
+ */
+ public NestedString createReplaceToken() {
+ if (token == null) {
+ token = new NestedString();
+ }
+ return token;
+ }
+
+ /**
+ * Create a string to replace the token as the text of a nested element.
+ * @return replacement value <code>NestedString</code> to configure.
+ * @since Ant 1.8.0
+ */
+ public NestedString createReplaceValue() {
+ if (value == null) {
+ value = new NestedString();
+ }
+ return value;
+ }
+
+ /**
+ * Retrieves the output buffer of this filter. The filter guarantees
+ * that data is only appended to the end of this StringBuffer.
+ * @return The StringBuffer containing the output of this filter.
+ */
+ StringBuffer getOutputBuffer() {
+ return outputBuffer;
+ }
+
+ /**
+ * Sets the input buffer for this filter.
+ * The filter expects from the component providing the input that data
+ * is only added by that component to the end of this StringBuffer.
+ * This StringBuffer will be modified by this filter, and expects that
+ * another component will only apped to this StringBuffer.
+ * @param input The input for this filter.
+ */
+ void setInputBuffer(StringBuffer input) {
+ inputBuffer = input;
+ }
+
+ /**
+ * Processes the buffer as far as possible. Takes into account that
+ * appended data may make it possible to replace the end of the already
+ * received data, when the token is split over the "old" and the "new"
+ * part.
+ * @return true if some data has been made available in the
+ * output buffer.
+ */
+ boolean process() {
+ String t = getToken();
+ if (inputBuffer.length() > t.length()) {
+ int pos = replace();
+ pos = Math.max((inputBuffer.length() - t.length()), pos);
+ outputBuffer.append(inputBuffer.substring(0, pos));
+ inputBuffer.delete(0, pos);
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Processes the buffer to the end. Does not take into account that
+ * appended data may make it possible to replace the end of the already
+ * received data.
+ */
+ void flush() {
+ replace();
+ outputBuffer.append(inputBuffer);
+ inputBuffer.delete(0, inputBuffer.length());
+ }
+
+ /**
+ * Performs the replace operation.
+ * @return The position of the last character that was inserted as
+ * replacement.
+ */
+ private int replace() {
+ String t = getToken();
+ int found = inputBuffer.indexOf(t);
+ int pos = -1;
+ final int tokenLength = t.length();
+ final int replaceValueLength = replaceValue.length();
+ while (found >= 0) {
+ inputBuffer.replace(found, found + tokenLength, replaceValue);
+ pos = found + replaceValueLength;
+ found = inputBuffer.indexOf(t, pos);
+ ++replaceCount;
+ }
+ return pos;
+ }
+ }
+
+ /**
+ * Class reading a file in small chunks, and presenting these chunks in
+ * a StringBuffer. Compatible with the Replacefilter.
+ * @since 1.7
+ */
+ private class FileInput /* JDK 5: implements Closeable */ {
+ private StringBuffer outputBuffer;
+ private final InputStream is;
+ private Reader reader;
+ private char[] buffer;
+ private static final int BUFF_SIZE = 4096;
+
+ /**
+ * Constructs the input component. Opens the file for reading.
+ * @param source The file to read from.
+ * @throws IOException When the file cannot be read from.
+ */
+ FileInput(File source) throws IOException {
+ outputBuffer = new StringBuffer();
+ buffer = new char[BUFF_SIZE];
+ is = new FileInputStream(source);
+ try {
+ reader = new BufferedReader(encoding != null ? new InputStreamReader(is, encoding) : new InputStreamReader(is));
+ } finally {
+ if (reader == null) {
+ is.close();
+ }
+ }
+ }
+
+ /**
+ * Retrieves the output buffer of this filter. The component guarantees
+ * that data is only appended to the end of this StringBuffer.
+ * @return The StringBuffer containing the output of this filter.
+ */
+ StringBuffer getOutputBuffer() {
+ return outputBuffer;
+ }
+
+ /**
+ * Reads some data from the file.
+ * @return true when the end of the file has not been reached.
+ * @throws IOException When the file cannot be read from.
+ */
+ boolean readChunk() throws IOException {
+ int bufferLength = 0;
+ bufferLength = reader.read(buffer);
+ if (bufferLength < 0) {
+ return false;
+ }
+ outputBuffer.append(new String(buffer, 0, bufferLength));
+ return true;
+ }
+
+ /**
+ * Closes the file.
+ * @throws IOException When the file cannot be closed.
+ */
+ public void close() throws IOException {
+ is.close();
+ }
+
+ }
+
+ /**
+ * Component writing a file in chunks, taking the chunks from the
+ * Replacefilter.
+ * @since 1.7
+ */
+ private class FileOutput /* JDK 5: implements Closeable */ {
+ private StringBuffer inputBuffer;
+ private final OutputStream os;
+ private Writer writer;
+
+ /**
+ * Constructs the output component. Opens the file for writing.
+ * @param out The file to read to.
+ * @throws IOException When the file cannot be read from.
+ */
+ FileOutput(File out) throws IOException {
+ os = new FileOutputStream(out);
+ try {
+ writer = new BufferedWriter(encoding != null ? new OutputStreamWriter(os, encoding) : new OutputStreamWriter(os));
+ } finally {
+ if (writer == null) {
+ os.close();
+ }
+ }
+ }
+
+ /**
+ * Sets the input buffer for this component.
+ * The filter expects from the component providing the input that data
+ * is only added by that component to the end of this StringBuffer.
+ * This StringBuffer will be modified by this filter, and expects that
+ * another component will only append to this StringBuffer.
+ * @param input The input for this filter.
+ */
+ void setInputBuffer(StringBuffer input) {
+ inputBuffer = input;
+ }
+
+ /**
+ * Writes the buffer as far as possible.
+ * @return false to be inline with the Replacefilter.
+ * (Yes defining an interface crossed my mind, but would publish the
+ * internal behavior.)
+ * @throws IOException when the output cannot be written.
+ */
+ boolean process() throws IOException {
+ writer.write(inputBuffer.toString());
+ inputBuffer.delete(0, inputBuffer.length());
+ return false;
+ }
+
+ /**
+ * Processes the buffer to the end.
+ * @throws IOException when the output cannot be flushed.
+ */
+ void flush() throws IOException {
+ process();
+ writer.flush();
+ }
+
+ /**
+ * Closes the file.
+ * @throws IOException When the file cannot be closed.
+ */
+ public void close() throws IOException {
+ os.close();
+ }
+
+ }
+
+ /**
+ * Do the execution.
+ * @throws BuildException if we can't build
+ */
+ public void execute() throws BuildException {
+
+ ArrayList savedFilters = (ArrayList) replacefilters.clone();
+ Properties savedProperties =
+ properties == null ? null : (Properties) properties.clone();
+
+ if (token != null) {
+ // line separators in values and tokens are "\n"
+ // in order to compare with the file contents, replace them
+ // as needed
+ StringBuffer val = new StringBuffer(value.getText());
+ stringReplace(val, "\r\n", "\n");
+ stringReplace(val, "\n", StringUtils.LINE_SEP);
+ StringBuffer tok = new StringBuffer(token.getText());
+ stringReplace(tok, "\r\n", "\n");
+ stringReplace(tok, "\n", StringUtils.LINE_SEP);
+ Replacefilter firstFilter = createPrimaryfilter();
+ firstFilter.setToken(tok.toString());
+ firstFilter.setValue(val.toString());
+ }
+
+ try {
+ if (replaceFilterResource != null) {
+ Properties props = getProperties(replaceFilterResource);
+ Iterator e = props.keySet().iterator();
+ while (e.hasNext()) {
+ String tok = e.next().toString();
+ Replacefilter replaceFilter = createReplacefilter();
+ replaceFilter.setToken(tok);
+ replaceFilter.setValue(props.getProperty(tok));
+ }
+ }
+
+ validateAttributes();
+
+ if (propertyResource != null) {
+ properties = getProperties(propertyResource);
+ }
+
+ validateReplacefilters();
+ fileCount = 0;
+ replaceCount = 0;
+
+ if (sourceFile != null) {
+ processFile(sourceFile);
+ }
+
+ if (dir != null) {
+ DirectoryScanner ds = super.getDirectoryScanner(dir);
+ String[] srcs = ds.getIncludedFiles();
+
+ for (int i = 0; i < srcs.length; i++) {
+ File file = new File(dir, srcs[i]);
+ processFile(file);
+ }
+ }
+
+ if (resources != null) {
+ for (Resource r : resources) {
+ FileProvider fp =
+ r.as(FileProvider.class);
+ processFile(fp.getFile());
+ }
+ }
+
+ if (summary) {
+ log("Replaced " + replaceCount + " occurrences in "
+ + fileCount + " files.", Project.MSG_INFO);
+ }
+ if (failOnNoReplacements && replaceCount == 0) {
+ throw new BuildException("didn't replace anything");
+ }
+ } finally {
+ replacefilters = savedFilters;
+ properties = savedProperties;
+ } // end of finally
+
+ }
+
+ /**
+ * Validate attributes provided for this task in .xml build file.
+ *
+ * @exception BuildException if any supplied attribute is invalid or any
+ * mandatory attribute is missing.
+ */
+ public void validateAttributes() throws BuildException {
+ if (sourceFile == null && dir == null && resources == null) {
+ String message = "Either the file or the dir attribute "
+ + "or nested resources must be specified";
+ throw new BuildException(message, getLocation());
+ }
+ if (propertyResource != null && !propertyResource.isExists()) {
+ String message = "Property file " + propertyResource.getName()
+ + " does not exist.";
+ throw new BuildException(message, getLocation());
+ }
+ if (token == null && replacefilters.size() == 0) {
+ String message = "Either token or a nested replacefilter "
+ + "must be specified";
+ throw new BuildException(message, getLocation());
+ }
+ if (token != null && "".equals(token.getText())) {
+ String message = "The token attribute must not be an empty string.";
+ throw new BuildException(message, getLocation());
+ }
+ }
+
+ /**
+ * Validate nested elements.
+ *
+ * @exception BuildException if any supplied attribute is invalid or any
+ * mandatory attribute is missing.
+ */
+ public void validateReplacefilters()
+ throws BuildException {
+ final int size = replacefilters.size();
+ for (int i = 0; i < size; i++) {
+ Replacefilter element =
+ (Replacefilter) replacefilters.get(i);
+ element.validate();
+ }
+ }
+
+ /**
+ * Load a properties file.
+ * @param propertyFile the file to load the properties from.
+ * @return loaded <code>Properties</code> object.
+ * @throws BuildException if the file could not be found or read.
+ */
+ public Properties getProperties(File propertyFile) throws BuildException {
+ return getProperties(new FileResource(getProject(), propertyFile));
+ }
+
+ /**
+ * Load a properties resource.
+ * @param propertyResource the resource to load the properties from.
+ * @return loaded <code>Properties</code> object.
+ * @throws BuildException if the resource could not be found or read.
+ * @since Ant 1.8.0
+ */
+ public Properties getProperties(Resource propertyResource)
+ throws BuildException {
+ Properties props = new Properties();
+
+ InputStream in = null;
+ try {
+ in = propertyResource.getInputStream();
+ props.load(in);
+ } catch (IOException e) {
+ String message = "Property resource (" + propertyResource.getName()
+ + ") cannot be loaded.";
+ throw new BuildException(message);
+ } finally {
+ FileUtils.close(in);
+ }
+
+ return props;
+ }
+
+ /**
+ * Perform the replacement on the given file.
+ *
+ * The replacement is performed on a temporary file which then
+ * replaces the original file.
+ *
+ * @param src the source <code>File</code>.
+ */
+ private void processFile(File src) throws BuildException {
+ if (!src.exists()) {
+ throw new BuildException("Replace: source file " + src.getPath()
+ + " doesn't exist", getLocation());
+ }
+
+ int repCountStart = replaceCount;
+ logFilterChain(src.getPath());
+
+ try {
+ File temp = FILE_UTILS.createTempFile("rep", ".tmp",
+ src.getParentFile(), false, true);
+ try {
+ FileInput in = new FileInput(src);
+ try {
+ FileOutput out = new FileOutput(temp);
+ try {
+ out.setInputBuffer(buildFilterChain(in.getOutputBuffer()));
+
+ while (in.readChunk()) {
+ if (processFilterChain()) {
+ out.process();
+ }
+ }
+
+ flushFilterChain();
+
+ out.flush();
+ } finally {
+ out.close();
+ }
+ } finally {
+ in.close();
+ }
+ boolean changes = (replaceCount != repCountStart);
+ if (changes) {
+ fileCount++;
+ long origLastModified = src.lastModified();
+ FILE_UTILS.rename(temp, src);
+ if (preserveLastModified) {
+ FILE_UTILS.setFileLastModified(src, origLastModified);
+ }
+ }
+ } finally {
+ if (temp.isFile() && !temp.delete()) {
+ temp.deleteOnExit();
+ }
+ }
+ } catch (IOException ioe) {
+ throw new BuildException("IOException in " + src + " - "
+ + ioe.getClass().getName() + ":"
+ + ioe.getMessage(), ioe, getLocation());
+ }
+ }
+
+ /**
+ * Flushes all filters.
+ */
+ private void flushFilterChain() {
+ final int size = replacefilters.size();
+ for (int i = 0; i < size; i++) {
+ Replacefilter filter = (Replacefilter) replacefilters.get(i);
+ filter.flush();
+ }
+ }
+
+ /**
+ * Performs the normal processing of the filters.
+ * @return true if the filter chain produced new output.
+ */
+ private boolean processFilterChain() {
+ final int size = replacefilters.size();
+ for (int i = 0; i < size; i++) {
+ Replacefilter filter = (Replacefilter) replacefilters.get(i);
+ if (!filter.process()) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Creates the chain of filters to operate.
+ * @param inputBuffer <code>StringBuffer</code> containing the input for the
+ * first filter.
+ * @return <code>StringBuffer</code> containing the output of the last filter.
+ */
+ private StringBuffer buildFilterChain(StringBuffer inputBuffer) {
+ StringBuffer buf = inputBuffer;
+ final int size = replacefilters.size();
+ for (int i = 0; i < size; i++) {
+ Replacefilter filter = (Replacefilter) replacefilters.get(i);
+ filter.setInputBuffer(buf);
+ buf = filter.getOutputBuffer();
+ }
+ return buf;
+ }
+
+ /**
+ * Logs the chain of filters to operate on the file.
+ * @param filename <code>String</code>.
+ */
+ private void logFilterChain(String filename) {
+ final int size = replacefilters.size();
+ for (int i = 0; i < size; i++) {
+ Replacefilter filter = (Replacefilter) replacefilters.get(i);
+ log("Replacing in " + filename + ": " + filter.getToken()
+ + " --> " + filter.getReplaceValue(), Project.MSG_VERBOSE);
+ }
+ }
+ /**
+ * Set the source file; required unless <code>dir</code> is set.
+ * @param file source <code>File</code>.
+ */
+ public void setFile(File file) {
+ this.sourceFile = file;
+ }
+
+ /**
+ * Indicates whether a summary of the replace operation should be
+ * produced, detailing how many token occurrences and files were
+ * processed; optional, default=<code>false</code>.
+ *
+ * @param summary <code>boolean</code> whether a summary of the
+ * replace operation should be logged.
+ */
+ public void setSummary(boolean summary) {
+ this.summary = summary;
+ }
+
+
+ /**
+ * Sets the name of a property file containing filters; optional.
+ * Each property will be treated as a replacefilter where token is the name
+ * of the property and value is the value of the property.
+ * @param replaceFilterFile <code>File</code> to load.
+ */
+ public void setReplaceFilterFile(File replaceFilterFile) {
+ setReplaceFilterResource(new FileResource(getProject(),
+ replaceFilterFile));
+ }
+
+ /**
+ * Sets the name of a resource containing filters; optional.
+ * Each property will be treated as a replacefilter where token is the name
+ * of the property and value is the value of the property.
+ * @param replaceFilter <code>Resource</code> to load.
+ * @since Ant 1.8.0
+ */
+ public void setReplaceFilterResource(Resource replaceFilter) {
+ this.replaceFilterResource = replaceFilter;
+ }
+
+ /**
+ * The base directory to use when replacing a token in multiple files;
+ * required if <code>file</code> is not defined.
+ * @param dir <code>File</code> representing the base directory.
+ */
+ public void setDir(File dir) {
+ this.dir = dir;
+ }
+
+ /**
+ * Set the string token to replace; required unless a nested
+ * <code>replacetoken</code> element or the
+ * <code>replacefilterresource</code> attribute is used.
+ * @param token token <code>String</code>.
+ */
+ public void setToken(String token) {
+ createReplaceToken().addText(token);
+ }
+
+ /**
+ * Set the string value to use as token replacement;
+ * optional, default is the empty string "".
+ * @param value replacement value.
+ */
+ public void setValue(String value) {
+ createReplaceValue().addText(value);
+ }
+
+ /**
+ * Set the file encoding to use on the files read and written by the task;
+ * optional, defaults to default JVM encoding.
+ *
+ * @param encoding the encoding to use on the files.
+ */
+ public void setEncoding(String encoding) {
+ this.encoding = encoding;
+ }
+
+ /**
+ * Create a token to filter as the text of a nested element.
+ * @return nested token <code>NestedString</code> to configure.
+ */
+ public NestedString createReplaceToken() {
+ if (token == null) {
+ token = new NestedString();
+ }
+ return token;
+ }
+
+ /**
+ * Create a string to replace the token as the text of a nested element.
+ * @return replacement value <code>NestedString</code> to configure.
+ */
+ public NestedString createReplaceValue() {
+ return value;
+ }
+
+ /**
+ * The name of a property file from which properties specified using nested
+ * <code>&lt;replacefilter&gt;</code> elements are drawn; required only if
+ * the <i>property</i> attribute of <code>&lt;replacefilter&gt;</code> is used.
+ * @param propertyFile <code>File</code> to load.
+ */
+ public void setPropertyFile(File propertyFile) {
+ setPropertyResource(new FileResource(propertyFile));
+ }
+
+ /**
+ * A resource from which properties specified using nested
+ * <code>&lt;replacefilter&gt;</code> elements are drawn; required
+ * only if the <i>property</i> attribute of
+ * <code>&lt;replacefilter&gt;</code> is used.
+ * @param propertyResource <code>Resource</code> to load.
+ *
+ * @since Ant 1.8.0
+ */
+ public void setPropertyResource(Resource propertyResource) {
+ this.propertyResource = propertyResource;
+ }
+
+ /**
+ * Add a nested &lt;replacefilter&gt; element.
+ * @return a nested <code>Replacefilter</code> object to be configured.
+ */
+ public Replacefilter createReplacefilter() {
+ Replacefilter filter = new Replacefilter();
+ replacefilters.add(filter);
+ return filter;
+ }
+
+ /**
+ * Support arbitrary file system based resource collections.
+ *
+ * @since Ant 1.8.0
+ */
+ public void addConfigured(ResourceCollection rc) {
+ if (!rc.isFilesystemOnly()) {
+ throw new BuildException("only filesystem resources are supported");
+ }
+ if (resources == null) {
+ resources = new Union();
+ }
+ resources.add(rc);
+ }
+
+ /**
+ * Whether the file timestamp shall be preserved even if the file
+ * is modified.
+ *
+ * @since Ant 1.8.0
+ */
+ public void setPreserveLastModified(boolean b) {
+ preserveLastModified = b;
+ }
+
+ /**
+ * Whether the build should fail if nothing has been replaced.
+ *
+ * @since Ant 1.8.0
+ */
+ public void setFailOnNoReplacements(boolean b) {
+ failOnNoReplacements = b;
+ }
+
+ /**
+ * Adds the token and value as first &lt;replacefilter&gt; element.
+ * The token and value are always processed first.
+ * @return a nested <code>Replacefilter</code> object to be configured.
+ */
+ private Replacefilter createPrimaryfilter() {
+ Replacefilter filter = new Replacefilter();
+ replacefilters.add(0, filter);
+ return filter;
+ }
+
+ /**
+ * Replace occurrences of str1 in StringBuffer str with str2.
+ */
+ private void stringReplace(StringBuffer str, String str1, String str2) {
+ int found = str.indexOf(str1);
+ final int str1Length = str1.length();
+ final int str2Length = str2.length();
+ while (found >= 0) {
+ str.replace(found, found + str1Length, str2);
+ found = str.indexOf(str1, found + str2Length);
+ }
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/ResourceCount.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/ResourceCount.java
new file mode 100644
index 00000000..b29b57b6
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/ResourceCount.java
@@ -0,0 +1,124 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.taskdefs.condition.Condition;
+import org.apache.tools.ant.types.Comparison;
+import org.apache.tools.ant.types.Reference;
+import org.apache.tools.ant.types.ResourceCollection;
+
+/**
+ * Count resources from a ResourceCollection, storing to a property or
+ * writing to the log. Can also be used as a Condition.
+ * @since Ant 1.7
+ */
+public class ResourceCount extends Task implements Condition {
+
+ private static final String ONE_NESTED_MESSAGE
+ = "ResourceCount can count resources from exactly one nested ResourceCollection.";
+
+ private static final String COUNT_REQUIRED
+ = "Use of the ResourceCount condition requires that the count attribute be set.";
+
+ private ResourceCollection rc;
+ private Comparison when = Comparison.EQUAL;
+ private Integer count;
+ private String property;
+
+ /**
+ * Add the ResourceCollection to count.
+ * @param r the ResourceCollection to count.
+ * @throws BuildException if already set.
+ */
+ public void add(ResourceCollection r) {
+ if (rc != null) {
+ throw new BuildException(ONE_NESTED_MESSAGE);
+ }
+ rc = r;
+ }
+
+ /**
+ * Set the ResourceCollection reference.
+ * @param r the Reference.
+ */
+ public void setRefid(Reference r) {
+ Object o = r.getReferencedObject();
+ if (!(o instanceof ResourceCollection)) {
+ throw new BuildException(r.getRefId()
+ + " doesn\'t denote a ResourceCollection");
+ }
+ add((ResourceCollection) o);
+ }
+
+ /**
+ * Execute as a Task.
+ */
+ public void execute() {
+ if (rc == null) {
+ throw new BuildException(ONE_NESTED_MESSAGE);
+ }
+ if (property == null) {
+ log("resource count = " + rc.size());
+ } else {
+ getProject().setNewProperty(property, Integer.toString(rc.size()));
+ }
+ }
+
+ /**
+ * Fulfill the condition contract.
+ * @return true if the specified ResourceCollection satisfies the set criteria.
+ * @throws BuildException if an error occurs.
+ */
+ public boolean eval() {
+ if (rc == null) {
+ throw new BuildException(ONE_NESTED_MESSAGE);
+ }
+ if (count == null) {
+ throw new BuildException(COUNT_REQUIRED);
+ }
+ return when.evaluate(new Integer(rc.size()).compareTo(count));
+ }
+
+ /**
+ * Set the target count number for use as a Condition.
+ * @param c number of Resources as int.
+ */
+ public void setCount(int c) {
+ count = new Integer(c);
+ }
+
+ /**
+ * Set the comparison for use as a Condition.
+ * @param c Comparison (an EnumeratedAttribute) When.
+ * @see org.apache.tools.ant.types.Comparison
+ */
+ public void setWhen(Comparison c) {
+ when = c;
+ }
+
+ /**
+ * Set the name of the property to set in task mode.
+ * @param p the property name to set.
+ */
+ public void setProperty(String p) {
+ property = p;
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Retry.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Retry.java
new file mode 100644
index 00000000..1a00fa4c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Retry.java
@@ -0,0 +1,119 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.TaskContainer;
+import org.apache.tools.ant.util.StringUtils;
+
+/**
+ * Retries the nested task a set number of times
+ * @since Ant 1.7.1
+ */
+public class Retry extends Task implements TaskContainer {
+
+ /**
+ * task to execute n times
+ */
+ private Task nestedTask;
+
+ /**
+ * set retryCount to 1 by default
+ */
+ private int retryCount = 1;
+
+ /**
+ * The time to wait between retries in milliseconds, default to 0.
+ */
+ private int retryDelay = 0;
+
+ /**
+ * set the task
+ * @param t the task to retry.
+ */
+ public synchronized void addTask(Task t) {
+ if (nestedTask != null) {
+ throw new BuildException(
+ "The retry task container accepts a single nested task"
+ + " (which may be a sequential task container)");
+ }
+ nestedTask = t;
+ }
+
+ /**
+ * set the number of times to retry the task
+ * @param n the number to use.
+ */
+ public void setRetryCount(int n) {
+ retryCount = n;
+ }
+
+ /**
+ * set the delay between retries (in milliseconds)
+ * @param retryDelay the time between retries.
+ * @since Ant 1.8.3
+ */
+ public void setRetryDelay(int retryDelay) {
+ if (retryDelay < 0) {
+ throw new BuildException("retryDelay must be a non-negative number");
+ }
+ this.retryDelay = retryDelay;
+ }
+
+ /**
+ * perform the work
+ * @throws BuildException if there is an error.
+ */
+ public void execute() throws BuildException {
+ StringBuffer errorMessages = new StringBuffer();
+ for (int i = 0; i <= retryCount; i++) {
+ try {
+ nestedTask.perform();
+ break;
+ } catch (Exception e) {
+ errorMessages.append(e.getMessage());
+ if (i >= retryCount) {
+ StringBuffer exceptionMessage = new StringBuffer();
+ exceptionMessage.append("Task [").append(nestedTask.getTaskName());
+ exceptionMessage.append("] failed after [").append(retryCount);
+ exceptionMessage.append("] attempts; giving up.").append(StringUtils.LINE_SEP);
+ exceptionMessage.append("Error messages:").append(StringUtils.LINE_SEP);
+ exceptionMessage.append(errorMessages);
+ throw new BuildException(exceptionMessage.toString(), getLocation());
+ }
+ String msg;
+ if (retryDelay > 0) {
+ msg = "Attempt [" + i + "]: error occurred; retrying after " + retryDelay + " ms...";
+ } else {
+ msg = "Attempt [" + i + "]: error occurred; retrying...";
+ }
+ log(msg, e, Project.MSG_INFO);
+ errorMessages.append(StringUtils.LINE_SEP);
+ if (retryDelay > 0) {
+ try {
+ Thread.sleep(retryDelay);
+ } catch (InterruptedException ie) {
+ // Ignore Exception
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Rmic.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Rmic.java
new file mode 100644
index 00000000..6935f9e3
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Rmic.java
@@ -0,0 +1,853 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs;
+
+import java.io.File;
+import java.io.IOException;
+import java.rmi.Remote;
+import java.util.Vector;
+
+import org.apache.tools.ant.AntClassLoader;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.DirectoryScanner;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.rmic.RmicAdapter;
+import org.apache.tools.ant.taskdefs.rmic.RmicAdapterFactory;
+import org.apache.tools.ant.types.FilterSetCollection;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.types.Reference;
+import org.apache.tools.ant.util.FileNameMapper;
+import org.apache.tools.ant.util.FileUtils;
+import org.apache.tools.ant.util.SourceFileScanner;
+import org.apache.tools.ant.util.StringUtils;
+import org.apache.tools.ant.util.facade.FacadeTaskHelper;
+
+/**
+ * <p>Runs the rmic compiler against classes.</p>
+ *
+ * <p>Rmic can be run on a single class (as specified with the classname
+ * attribute) or a number of classes at once (all classes below base that
+ * are neither _Stub nor _Skel classes). If you want to rmic a single
+ * class and this class is a class nested into another class, you have to
+ * specify the classname in the form <code>Outer$$Inner</code> instead of
+ * <code>Outer.Inner</code>.</p>
+ *
+ * <p>It is possible to refine the set of files that are being rmiced. This can
+ * be done with the <i>includes</i>, <i>includesfile</i>, <i>excludes</i>,
+ * <i>excludesfile</i> and <i>defaultexcludes</i>
+ * attributes. With the <i>includes</i> or <i>includesfile</i> attribute you
+ * specify the files you want to have included by using patterns. The
+ * <i>exclude</i> or <i>excludesfile</i> attribute is used to specify
+ * the files you want to have excluded. This is also done with patterns. And
+ * finally with the <i>defaultexcludes</i> attribute, you can specify whether
+ * you want to use default exclusions or not. See the section on
+ * directory based tasks, on how the
+ * inclusion/exclusion of files works, and how to write patterns.</p>
+ *
+ * <p>This task forms an implicit FileSet and
+ * supports all attributes of <code>&lt;fileset&gt;</code>
+ * (<code>dir</code> becomes <code>base</code>) as well as the nested
+ * <code>&lt;include&gt;</code>, <code>&lt;exclude&gt;</code> and
+ * <code>&lt;patternset&gt;</code> elements.</p>
+ *
+ * <p>It is possible to use different compilers. This can be selected
+ * with the &quot;build.rmic&quot; property or the <code>compiler</code>
+ * attribute. <a name="compilervalues">There are three choices</a>:</p>
+ *
+ * <ul>
+ * <li>sun (the standard compiler of the JDK)</li>
+ * <li>kaffe (the standard compiler of
+ * {@link <a href="http://www.kaffe.org">Kaffe</a>})</li>
+ * <li>weblogic</li>
+ * </ul>
+ *
+ * <p> The <a href="http://dione.zcu.cz/~toman40/miniRMI/">miniRMI</a>
+ * project contains a compiler implementation for this task as well,
+ * please consult miniRMI's documentation to learn how to use it.</p>
+ *
+ * @since Ant 1.1
+ *
+ * @ant.task category="java"
+ */
+
+public class Rmic extends MatchingTask {
+
+ /** rmic failed message */
+ public static final String ERROR_RMIC_FAILED
+ = "Rmic failed; see the compiler error output for details.";
+
+ private File baseDir;
+ private File destDir;
+ private String classname;
+ private File sourceBase;
+ private String stubVersion;
+ private Path compileClasspath;
+ private Path extDirs;
+ private boolean verify = false;
+ private boolean filtering = false;
+
+ private boolean iiop = false;
+ private String iiopOpts;
+ private boolean idl = false;
+ private String idlOpts;
+ private boolean debug = false;
+ private boolean includeAntRuntime = true;
+ private boolean includeJavaRuntime = false;
+
+ private Vector compileList = new Vector();
+
+ private AntClassLoader loader = null;
+
+ private FacadeTaskHelper facade;
+ /** unable to verify message */
+ public static final String ERROR_UNABLE_TO_VERIFY_CLASS = "Unable to verify class ";
+ /** could not be found message */
+ public static final String ERROR_NOT_FOUND = ". It could not be found.";
+ /** not defined message */
+ public static final String ERROR_NOT_DEFINED = ". It is not defined.";
+ /** loaded error message */
+ public static final String ERROR_LOADING_CAUSED_EXCEPTION = ". Loading caused Exception: ";
+ /** base not exists message */
+ public static final String ERROR_NO_BASE_EXISTS = "base or destdir does not exist: ";
+ /** base not a directory message */
+ public static final String ERROR_NOT_A_DIR = "base or destdir is not a directory:";
+ /** base attribute not set message */
+ public static final String ERROR_BASE_NOT_SET = "base or destdir attribute must be set!";
+
+ private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+
+ private String executable = null;
+
+ private boolean listFiles = false;
+
+ private RmicAdapter nestedAdapter = null;
+
+ /**
+ * Constructor for Rmic.
+ */
+ public Rmic() {
+ facade = new FacadeTaskHelper(RmicAdapterFactory.DEFAULT_COMPILER);
+ }
+
+ /**
+ * Sets the location to store the compiled files; required
+ * @param base the location to store the compiled files
+ */
+ public void setBase(File base) {
+ this.baseDir = base;
+ }
+
+ /**
+ * Sets the base directory to output the generated files.
+ * @param destdir the base directory to output the generated files.
+ * @since Ant 1.8.0
+ */
+ public void setDestdir(File destdir) {
+ this.destDir = destdir;
+ }
+
+ /**
+ * Gets the base directory to output the generated files.
+ * @return the base directory to output the generated files.
+ * @since Ant 1.8.0
+ */
+ public File getDestdir() {
+ return this.destDir;
+ }
+
+ /**
+ * Gets the base directory to output the generated files,
+ * favoring destdir if set, otherwise defaulting to basedir.
+ * @return the actual directory to output to (either destdir or basedir)
+ * @since Ant 1.8.0
+ */
+ public File getOutputDir() {
+ if (getDestdir() != null) {
+ return getDestdir();
+ }
+ return getBase();
+ }
+
+ /**
+ * Gets the base directory to output generated class.
+ * @return the location of the compiled files
+ */
+ public File getBase() {
+ return this.baseDir;
+ }
+
+ /**
+ * Sets the class to run <code>rmic</code> against;
+ * optional
+ * @param classname the name of the class for rmic to create code for
+ */
+ public void setClassname(String classname) {
+ this.classname = classname;
+ }
+
+ /**
+ * Gets the class name to compile.
+ * @return the name of the class to compile
+ */
+ public String getClassname() {
+ return classname;
+ }
+
+ /**
+ * optional directory to save generated source files to.
+ * @param sourceBase the directory to save source files to.
+ */
+ public void setSourceBase(File sourceBase) {
+ this.sourceBase = sourceBase;
+ }
+
+ /**
+ * Gets the source dirs to find the source java files.
+ * @return sourceBase the directory containing the source files.
+ */
+ public File getSourceBase() {
+ return sourceBase;
+ }
+
+ /**
+ * Specify the JDK version for the generated stub code.
+ * Specify &quot;1.1&quot; to pass the &quot;-v1.1&quot; option to rmic.
+ * @param stubVersion the JDK version
+ */
+ public void setStubVersion(String stubVersion) {
+ this.stubVersion = stubVersion;
+ }
+
+ /**
+ * Gets the JDK version for the generated stub code.
+ * @return stubVersion
+ */
+ public String getStubVersion() {
+ return stubVersion;
+ }
+
+ /**
+ * Sets token filtering [optional], default=false
+ * @param filter turn on token filtering
+ */
+ public void setFiltering(boolean filter) {
+ this.filtering = filter;
+ }
+
+ /**
+ * Gets whether token filtering is set
+ * @return filtering
+ */
+ public boolean getFiltering() {
+ return filtering;
+ }
+
+ /**
+ * Generate debug info (passes -g to rmic);
+ * optional, defaults to false
+ * @param debug turn on debug info
+ */
+ public void setDebug(boolean debug) {
+ this.debug = debug;
+ }
+
+ /**
+ * Gets the debug flag.
+ * @return debug
+ */
+ public boolean getDebug() {
+ return debug;
+ }
+
+ /**
+ * Set the classpath to be used for this compilation.
+ * @param classpath the classpath used for this compilation
+ */
+ public synchronized void setClasspath(Path classpath) {
+ if (compileClasspath == null) {
+ compileClasspath = classpath;
+ } else {
+ compileClasspath.append(classpath);
+ }
+ }
+
+ /**
+ * Creates a nested classpath element.
+ * @return classpath
+ */
+ public synchronized Path createClasspath() {
+ if (compileClasspath == null) {
+ compileClasspath = new Path(getProject());
+ }
+ return compileClasspath.createPath();
+ }
+
+ /**
+ * Adds to the classpath a reference to
+ * a &lt;path&gt; defined elsewhere.
+ * @param pathRef the reference to add to the classpath
+ */
+ public void setClasspathRef(Reference pathRef) {
+ createClasspath().setRefid(pathRef);
+ }
+
+ /**
+ * Gets the classpath.
+ * @return the classpath
+ */
+ public Path getClasspath() {
+ return compileClasspath;
+ }
+
+ /**
+ * Flag to enable verification so that the classes
+ * found by the directory match are
+ * checked to see if they implement java.rmi.Remote.
+ * optional; This defaults to false if not set.
+ * @param verify turn on verification for classes
+ */
+ public void setVerify(boolean verify) {
+ this.verify = verify;
+ }
+
+ /**
+ * Get verify flag.
+ * @return verify
+ */
+ public boolean getVerify() {
+ return verify;
+ }
+
+ /**
+ * Indicates that IIOP compatible stubs should
+ * be generated; optional, defaults to false
+ * if not set.
+ * @param iiop generate IIOP compatible stubs
+ */
+ public void setIiop(boolean iiop) {
+ this.iiop = iiop;
+ }
+
+ /**
+ * Gets iiop flags.
+ * @return iiop
+ */
+ public boolean getIiop() {
+ return iiop;
+ }
+
+ /**
+ * Set additional arguments for iiop
+ * @param iiopOpts additional arguments for iiop
+ */
+ public void setIiopopts(String iiopOpts) {
+ this.iiopOpts = iiopOpts;
+ }
+
+ /**
+ * Gets additional arguments for iiop.
+ * @return iiopOpts
+ */
+ public String getIiopopts() {
+ return iiopOpts;
+ }
+
+ /**
+ * Indicates that IDL output should be
+ * generated. This defaults to false
+ * if not set.
+ * @param idl generate IDL output
+ */
+ public void setIdl(boolean idl) {
+ this.idl = idl;
+ }
+
+ /**
+ * Gets IDL flags.
+ * @return the idl flag
+ */
+ public boolean getIdl() {
+ return idl;
+ }
+
+ /**
+ * pass additional arguments for IDL compile
+ * @param idlOpts additional IDL arguments
+ */
+ public void setIdlopts(String idlOpts) {
+ this.idlOpts = idlOpts;
+ }
+
+ /**
+ * Gets additional arguments for idl compile.
+ * @return the idl options
+ */
+ public String getIdlopts() {
+ return idlOpts;
+ }
+
+ /**
+ * Gets file list to compile.
+ * @return the list of files to compile.
+ */
+ public Vector getFileList() {
+ return compileList;
+ }
+
+ /**
+ * Sets whether or not to include ant's own classpath in this task's
+ * classpath.
+ * Optional; default is <code>true</code>.
+ * @param include if true include ant's classpath
+ */
+ public void setIncludeantruntime(boolean include) {
+ includeAntRuntime = include;
+ }
+
+ /**
+ * Gets whether or not the ant classpath is to be included in the
+ * task's classpath.
+ * @return true if ant's classpath is to be included
+ */
+ public boolean getIncludeantruntime() {
+ return includeAntRuntime;
+ }
+
+ /**
+ * task's classpath.
+ * Enables or disables including the default run-time
+ * libraries from the executing VM; optional,
+ * defaults to false
+ * @param include if true include default run-time libraries
+ */
+ public void setIncludejavaruntime(boolean include) {
+ includeJavaRuntime = include;
+ }
+
+ /**
+ * Gets whether or not the java runtime should be included in this
+ * task's classpath.
+ * @return true if default run-time libraries are included
+ */
+ public boolean getIncludejavaruntime() {
+ return includeJavaRuntime;
+ }
+
+ /**
+ * Sets the extension directories that will be used during the
+ * compilation; optional.
+ * @param extDirs the extension directories to be used
+ */
+ public synchronized void setExtdirs(Path extDirs) {
+ if (this.extDirs == null) {
+ this.extDirs = extDirs;
+ } else {
+ this.extDirs.append(extDirs);
+ }
+ }
+
+ /**
+ * Maybe creates a nested extdirs element.
+ * @return path object to be configured with the extension directories
+ */
+ public synchronized Path createExtdirs() {
+ if (extDirs == null) {
+ extDirs = new Path(getProject());
+ }
+ return extDirs.createPath();
+ }
+
+ /**
+ * Gets the extension directories that will be used during the
+ * compilation.
+ * @return the extension directories to be used
+ */
+ public Path getExtdirs() {
+ return extDirs;
+ }
+
+ /**
+ * @return the compile list.
+ */
+ public Vector getCompileList() {
+ return compileList;
+ }
+
+ /**
+ * Sets the compiler implementation to use; optional,
+ * defaults to the value of the <code>build.rmic</code> property,
+ * or failing that, default compiler for the current VM
+ * @param compiler the compiler implementation to use
+ * @since Ant 1.5
+ */
+ public void setCompiler(String compiler) {
+ if (compiler.length() > 0) {
+ facade.setImplementation(compiler);
+ }
+ }
+
+ /**
+ * get the name of the current compiler
+ * @return the name of the compiler
+ * @since Ant 1.5
+ */
+ public String getCompiler() {
+ facade.setMagicValue(getProject().getProperty("build.rmic"));
+ return facade.getImplementation();
+ }
+
+ /**
+ * Adds an implementation specific command line argument.
+ * @return an object to be configured with a command line argument
+ * @since Ant 1.5
+ */
+ public ImplementationSpecificArgument createCompilerArg() {
+ ImplementationSpecificArgument arg = new ImplementationSpecificArgument();
+ facade.addImplementationArgument(arg);
+ return arg;
+ }
+
+ /**
+ * Get the additional implementation specific command line arguments.
+ * @return array of command line arguments, guaranteed to be non-null.
+ * @since Ant 1.5
+ */
+ public String[] getCurrentCompilerArgs() {
+ getCompiler();
+ return facade.getArgs();
+ }
+
+ /**
+ * Name of the executable to use when forking.
+ *
+ * @since Ant 1.8.0
+ */
+ public void setExecutable(String ex) {
+ executable = ex;
+ }
+
+ /**
+ * Explicitly specified name of the executable to use when forking
+ * - if any.
+ *
+ * @since Ant 1.8.0
+ */
+ public String getExecutable() {
+ return executable;
+ }
+
+ /**
+ * The classpath to use when loading the compiler implementation
+ * if it is not a built-in one.
+ *
+ * @since Ant 1.8.0
+ */
+ public Path createCompilerClasspath() {
+ return facade.getImplementationClasspath(getProject());
+ }
+
+ /**
+ * If true, list the source files being handed off to the compiler.
+ * @param list if true list the source files
+ * @since Ant 1.8.0
+ */
+ public void setListfiles(boolean list) {
+ listFiles = list;
+ }
+
+ /**
+ * Set the compiler adapter explicitly.
+ * @since Ant 1.8.0
+ */
+ public void add(RmicAdapter adapter) {
+ if (nestedAdapter != null) {
+ throw new BuildException("Can't have more than one rmic adapter");
+ }
+ nestedAdapter = adapter;
+ }
+
+ /**
+ * execute by creating an instance of an implementation
+ * class and getting to do the work
+ * @throws org.apache.tools.ant.BuildException
+ * if there's a problem with baseDir or RMIC
+ */
+ @Override
+ public void execute() throws BuildException {
+ try {
+ compileList.clear();
+
+ File outputDir = getOutputDir();
+ if (outputDir == null) {
+ throw new BuildException(ERROR_BASE_NOT_SET, getLocation());
+ }
+ if (!outputDir.exists()) {
+ throw new BuildException(ERROR_NO_BASE_EXISTS + outputDir,
+ getLocation());
+ }
+ if (!outputDir.isDirectory()) {
+ throw new BuildException(ERROR_NOT_A_DIR + outputDir, getLocation());
+ }
+ if (verify) {
+ log("Verify has been turned on.", Project.MSG_VERBOSE);
+ }
+ RmicAdapter adapter =
+ nestedAdapter != null ? nestedAdapter :
+ RmicAdapterFactory.getRmic(getCompiler(), this,
+ createCompilerClasspath());
+
+ // now we need to populate the compiler adapter
+ adapter.setRmic(this);
+
+ Path classpath = adapter.getClasspath();
+ loader = getProject().createClassLoader(classpath);
+
+ // scan base dirs to build up compile lists only if a
+ // specific classname is not given
+ if (classname == null) {
+ DirectoryScanner ds = this.getDirectoryScanner(baseDir);
+ String[] files = ds.getIncludedFiles();
+ scanDir(baseDir, files, adapter.getMapper());
+ } else {
+ // otherwise perform a timestamp comparison - at least
+ String path = classname.replace('.', File.separatorChar)
+ + ".class";
+ File f = new File(baseDir, path);
+ if (f.isFile()) {
+ scanDir(baseDir, new String[] {path}, adapter.getMapper());
+ } else {
+ // Does not exist, so checking whether it is up to
+ // date makes no sense. Compilation will fail
+ // later anyway, but tests expect a certain
+ // output.
+ compileList.add(classname);
+ }
+ }
+ int fileCount = compileList.size();
+ if (fileCount > 0) {
+ log("RMI Compiling " + fileCount + " class"
+ + (fileCount > 1 ? "es" : "") + " to "
+ + outputDir, Project.MSG_INFO);
+
+ if (listFiles) {
+ for (int i = 0; i < fileCount; i++) {
+ log(compileList.get(i).toString());
+ }
+ }
+
+ // finally, lets execute the compiler!!
+ if (!adapter.execute()) {
+ throw new BuildException(ERROR_RMIC_FAILED, getLocation());
+ }
+ }
+ /*
+ * Move the generated source file to the base directory. If
+ * base directory and sourcebase are the same, the generated
+ * sources are already in place.
+ */
+ if (null != sourceBase && !outputDir.equals(sourceBase)
+ && fileCount > 0) {
+ if (idl) {
+ log("Cannot determine sourcefiles in idl mode, ",
+ Project.MSG_WARN);
+ log("sourcebase attribute will be ignored.",
+ Project.MSG_WARN);
+ } else {
+ for (int j = 0; j < fileCount; j++) {
+ moveGeneratedFile(outputDir, sourceBase,
+ (String) compileList.elementAt(j),
+ adapter);
+ }
+ }
+ }
+ } finally {
+ cleanup();
+ }
+ }
+
+ /**
+ * Cleans up resources.
+ *
+ * @since Ant 1.8.0
+ */
+ protected void cleanup() {
+ if (loader != null) {
+ loader.cleanup();
+ loader = null;
+ }
+ }
+
+ /**
+ * Move the generated source file(s) to the base directory
+ *
+ * @throws org.apache.tools.ant.BuildException When error
+ * copying/removing files.
+ */
+ private void moveGeneratedFile(File baseDir, File sourceBaseFile, String classname,
+ RmicAdapter adapter) throws BuildException {
+ String classFileName = classname.replace('.', File.separatorChar)
+ + ".class";
+ String[] generatedFiles = adapter.getMapper().mapFileName(classFileName);
+
+ for (int i = 0; i < generatedFiles.length; i++) {
+ final String generatedFile = generatedFiles[i];
+ if (!generatedFile.endsWith(".class")) {
+ // don't know how to handle that - a IDL file doesn't
+ // have a corresponding Java source for example.
+ continue;
+ }
+ String sourceFileName = StringUtils.removeSuffix(generatedFile,
+ ".class")
+ + ".java";
+
+ File oldFile = new File(baseDir, sourceFileName);
+ if (!oldFile.exists()) {
+ // no source file generated, nothing to move
+ continue;
+ }
+
+ File newFile = new File(sourceBaseFile, sourceFileName);
+ try {
+ if (filtering) {
+ FILE_UTILS.copyFile(oldFile, newFile,
+ new FilterSetCollection(getProject()
+ .getGlobalFilterSet()));
+ } else {
+ FILE_UTILS.copyFile(oldFile, newFile);
+ }
+ oldFile.delete();
+ } catch (IOException ioe) {
+ String msg = "Failed to copy " + oldFile + " to " + newFile
+ + " due to "
+ + ioe.getMessage();
+ throw new BuildException(msg, ioe, getLocation());
+ }
+ }
+ }
+
+ /**
+ * Scans the directory looking for class files to be compiled.
+ * The result is returned in the class variable compileList.
+ * @param baseDir the base direction
+ * @param files the list of files to scan
+ * @param mapper the mapper of files to target files
+ */
+ protected void scanDir(File baseDir, String[] files, FileNameMapper mapper) {
+ String[] newFiles = files;
+ if (idl) {
+ log("will leave uptodate test to rmic implementation in idl mode.",
+ Project.MSG_VERBOSE);
+ } else if (iiop && iiopOpts != null && iiopOpts.indexOf("-always") > -1) {
+ log("no uptodate test as -always option has been specified",
+ Project.MSG_VERBOSE);
+ } else {
+ SourceFileScanner sfs = new SourceFileScanner(this);
+ newFiles = sfs.restrict(files, baseDir, getOutputDir(), mapper);
+ }
+ for (int i = 0; i < newFiles.length; i++) {
+ String name = newFiles[i].replace(File.separatorChar, '.');
+ name = name.substring(0, name.lastIndexOf(".class"));
+ compileList.addElement(name);
+ }
+ }
+
+ /**
+ * Load named class and test whether it can be rmic'ed
+ * @param classname the name of the class to be tested
+ * @return true if the class can be rmic'ed
+ */
+ public boolean isValidRmiRemote(String classname) {
+ try {
+ Class testClass = loader.loadClass(classname);
+ // One cannot RMIC an interface for "classic" RMI (JRMP)
+ if (testClass.isInterface() && !iiop && !idl) {
+ return false;
+ }
+ return isValidRmiRemote(testClass);
+ } catch (ClassNotFoundException e) {
+ log(ERROR_UNABLE_TO_VERIFY_CLASS + classname + ERROR_NOT_FOUND,
+ Project.MSG_WARN);
+ } catch (NoClassDefFoundError e) {
+ log(ERROR_UNABLE_TO_VERIFY_CLASS + classname + ERROR_NOT_DEFINED,
+ Project.MSG_WARN);
+ } catch (Throwable t) {
+ log(ERROR_UNABLE_TO_VERIFY_CLASS + classname
+ + ERROR_LOADING_CAUSED_EXCEPTION + t.getMessage(),
+ Project.MSG_WARN);
+ }
+ // we only get here if an exception has been thrown
+ return false;
+ }
+
+ /**
+ * Returns the topmost interface that extends Remote for a given
+ * class - if one exists.
+ * @param testClass the class to be tested
+ * @return the topmost interface that extends Remote, or null if there
+ * is none.
+ */
+ public Class getRemoteInterface(Class testClass) {
+ if (Remote.class.isAssignableFrom(testClass)) {
+ Class [] interfaces = testClass.getInterfaces();
+ if (interfaces != null) {
+ for (int i = 0; i < interfaces.length; i++) {
+ if (Remote.class.isAssignableFrom(interfaces[i])) {
+ return interfaces[i];
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Check to see if the class or (super)interfaces implement
+ * java.rmi.Remote.
+ */
+ private boolean isValidRmiRemote (Class testClass) {
+ return getRemoteInterface(testClass) != null;
+ }
+
+ /**
+ * Classloader for the user-specified classpath.
+ * @return the classloader
+ */
+ public ClassLoader getLoader() {
+ return loader;
+ }
+
+ /**
+ * Adds an "compiler" attribute to Commandline$Attribute used to
+ * filter command line attributes based on the current
+ * implementation.
+ */
+ public class ImplementationSpecificArgument extends
+ org.apache.tools.ant.util.facade.ImplementationSpecificArgument {
+ /**
+ * Only pass the specified argument if the
+ * chosen compiler implementation matches the
+ * value of this attribute. Legal values are
+ * the same as those in the above list of
+ * valid compilers.)
+ * @param impl the compiler to be used.
+ */
+ public void setCompiler(String impl) {
+ super.setImplementation(impl);
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/SQLExec.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/SQLExec.java
new file mode 100644
index 00000000..6d1e5148
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/SQLExec.java
@@ -0,0 +1,1162 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs;
+
+import java.io.BufferedOutputStream;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.io.Reader;
+import java.io.StringReader;
+import java.sql.Blob;
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.sql.SQLWarning;
+import java.sql.Statement;
+import java.sql.Types;
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.EnumeratedAttribute;
+import org.apache.tools.ant.types.FileSet;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.ResourceCollection;
+import org.apache.tools.ant.types.resources.Appendable;
+import org.apache.tools.ant.types.resources.FileProvider;
+import org.apache.tools.ant.types.resources.FileResource;
+import org.apache.tools.ant.types.resources.Union;
+import org.apache.tools.ant.util.FileUtils;
+import org.apache.tools.ant.util.KeepAliveOutputStream;
+import org.apache.tools.ant.util.StringUtils;
+
+/**
+ * Executes a series of SQL statements on a database using JDBC.
+ *
+ * <p>Statements can
+ * either be read in from a text file using the <i>src</i> attribute or from
+ * between the enclosing SQL tags.</p>
+ *
+ * <p>Multiple statements can be provided, separated by semicolons (or the
+ * defined <i>delimiter</i>). Individual lines within the statements can be
+ * commented using either --, // or REM at the start of the line.</p>
+ *
+ * <p>The <i>autocommit</i> attribute specifies whether auto-commit should be
+ * turned on or off whilst executing the statements. If auto-commit is turned
+ * on each statement will be executed and committed. If it is turned off the
+ * statements will all be executed as one transaction.</p>
+ *
+ * <p>The <i>onerror</i> attribute specifies how to proceed when an error occurs
+ * during the execution of one of the statements.
+ * The possible values are: <b>continue</b> execution, only show the error;
+ * <b>stop</b> execution and commit transaction;
+ * and <b>abort</b> execution and transaction and fail task.</p>
+ *
+ * @since Ant 1.2
+ *
+ * @ant.task name="sql" category="database"
+ */
+public class SQLExec extends JDBCTask {
+
+ /**
+ * delimiters we support, "normal" and "row"
+ */
+ public static class DelimiterType extends EnumeratedAttribute {
+ /** The enumerated strings */
+ public static final String NORMAL = "normal", ROW = "row";
+ /** @return the enumerated strings */
+ @Override
+ public String[] getValues() {
+ return new String[] {NORMAL, ROW};
+ }
+ }
+
+ private int goodSql = 0;
+
+ private int totalSql = 0;
+
+ /**
+ * Database connection
+ */
+ private Connection conn = null;
+
+ /**
+ * files to load
+ */
+ private Union resources;
+
+ /**
+ * SQL statement
+ */
+ private Statement statement = null;
+
+ /**
+ * SQL input file
+ */
+ private File srcFile = null;
+
+ /**
+ * SQL input command
+ */
+ private String sqlCommand = "";
+
+ /**
+ * SQL transactions to perform
+ */
+ private Vector transactions = new Vector();
+
+ /**
+ * SQL Statement delimiter
+ */
+ private String delimiter = ";";
+
+ /**
+ * The delimiter type indicating whether the delimiter will
+ * only be recognized on a line by itself
+ */
+ private String delimiterType = DelimiterType.NORMAL;
+
+ /**
+ * Print SQL results.
+ */
+ private boolean print = false;
+
+ /**
+ * Print header columns.
+ */
+ private boolean showheaders = true;
+
+ /**
+ * Print SQL stats (rows affected)
+ */
+ private boolean showtrailers = true;
+
+ /**
+ * Results Output Resource.
+ */
+ private Resource output = null;
+
+ /**
+ * Output encoding.
+ */
+ private String outputEncoding = null;
+
+ /**
+ * Action to perform if an error is found
+ */
+ private String onError = "abort";
+
+ /**
+ * Encoding to use when reading SQL statements from a file
+ */
+ private String encoding = null;
+
+ /**
+ * Append to an existing file or overwrite it?
+ */
+ private boolean append = false;
+
+ /**
+ * Keep the format of a sql block?
+ */
+ private boolean keepformat = false;
+
+ /**
+ * Argument to Statement.setEscapeProcessing
+ *
+ * @since Ant 1.6
+ */
+ private boolean escapeProcessing = true;
+
+ /**
+ * should properties be expanded in text?
+ * false for backwards compatibility
+ *
+ * @since Ant 1.7
+ */
+ private boolean expandProperties = true;
+
+ /**
+ * should we print raw BLOB data?
+ * @since Ant 1.7.1
+ */
+ private boolean rawBlobs;
+
+ /**
+ * delimiters must match in case and whitespace is significant.
+ * @since Ant 1.8.0
+ */
+ private boolean strictDelimiterMatching = true;
+
+ /**
+ * whether to show SQLWarnings as WARN messages.
+ * @since Ant 1.8.0
+ */
+ private boolean showWarnings = false;
+
+ /**
+ * The column separator used when printing the results.
+ *
+ * <p>Defaults to ","</p>
+ *
+ * @since Ant 1.8.0
+ */
+ private String csvColumnSep = ",";
+
+ /**
+ * The character used to quote column values.
+ *
+ * <p>If set, columns that contain either the column separator or
+ * the quote character itself will be surrounded by the quote
+ * character. The quote character itself will be doubled if it
+ * appears inside of the column's value.</p>
+ *
+ * <p>If this value is not set (the default), no column values
+ * will be quoted, not even if they contain the column
+ * separator.</p>
+ *
+ * <p><b>Note:<b> BLOB values will never be quoted.</p>
+ *
+ * <p>Defaults to "not set"</p>
+ *
+ * @since Ant 1.8.0
+ */
+ private String csvQuoteChar = null;
+
+ /**
+ * Whether a warning is an error - in which case onError applies.
+ * @since Ant 1.8.0
+ */
+ private boolean treatWarningsAsErrors = false;
+
+ /**
+ * The name of the property to set in the event of an error
+ * @since Ant 1.8.0
+ */
+ private String errorProperty = null;
+
+ /**
+ * The name of the property to set in the event of a warning
+ * @since Ant 1.8.0
+ */
+ private String warningProperty = null;
+
+ /**
+ * The name of the property that receives the number of rows
+ * returned
+ * @since Ant 1.8.0
+ */
+ private String rowCountProperty = null;
+
+ /**
+ * Set the name of the SQL file to be run.
+ * Required unless statements are enclosed in the build file
+ * @param srcFile the file containing the SQL command.
+ */
+ public void setSrc(File srcFile) {
+ this.srcFile = srcFile;
+ }
+
+ /**
+ * Enable property expansion inside nested text
+ *
+ * @param expandProperties if true expand properties.
+ * @since Ant 1.7
+ */
+ public void setExpandProperties(boolean expandProperties) {
+ this.expandProperties = expandProperties;
+ }
+
+ /**
+ * is property expansion inside inline text enabled?
+ *
+ * @return true if properties are to be expanded.
+ * @since Ant 1.7
+ */
+ public boolean getExpandProperties() {
+ return expandProperties;
+ }
+
+ /**
+ * Set an inline SQL command to execute.
+ * NB: Properties are not expanded in this text unless {@link #expandProperties}
+ * is set.
+ * @param sql an inline string containing the SQL command.
+ */
+ public void addText(String sql) {
+ //there is no need to expand properties here as that happens when Transaction.addText is
+ //called; to do so here would be an error.
+ this.sqlCommand += sql;
+ }
+
+ /**
+ * Adds a set of files (nested fileset attribute).
+ * @param set a set of files contains SQL commands, each File is run in
+ * a separate transaction.
+ */
+ public void addFileset(FileSet set) {
+ add(set);
+ }
+
+ /**
+ * Adds a collection of resources (nested element).
+ * @param rc a collection of resources containing SQL commands,
+ * each resource is run in a separate transaction.
+ * @since Ant 1.7
+ */
+ public void add(ResourceCollection rc) {
+ if (rc == null) {
+ throw new BuildException("Cannot add null ResourceCollection");
+ }
+ synchronized (this) {
+ if (resources == null) {
+ resources = new Union();
+ }
+ }
+ resources.add(rc);
+ }
+
+ /**
+ * Add a SQL transaction to execute
+ * @return a Transaction to be configured.
+ */
+ public Transaction createTransaction() {
+ Transaction t = new Transaction();
+ transactions.addElement(t);
+ return t;
+ }
+
+ /**
+ * Set the file encoding to use on the SQL files read in
+ *
+ * @param encoding the encoding to use on the files
+ */
+ public void setEncoding(String encoding) {
+ this.encoding = encoding;
+ }
+
+ /**
+ * Set the delimiter that separates SQL statements. Defaults to &quot;;&quot;;
+ * optional
+ *
+ * <p>For example, set this to "go" and delimitertype to "ROW" for
+ * Sybase ASE or MS SQL Server.</p>
+ * @param delimiter the separator.
+ */
+ public void setDelimiter(String delimiter) {
+ this.delimiter = delimiter;
+ }
+
+ /**
+ * Set the delimiter type: "normal" or "row" (default "normal").
+ *
+ * <p>The delimiter type takes two values - normal and row. Normal
+ * means that any occurrence of the delimiter terminate the SQL
+ * command whereas with row, only a line containing just the
+ * delimiter is recognized as the end of the command.</p>
+ * @param delimiterType the type of delimiter - "normal" or "row".
+ */
+ public void setDelimiterType(DelimiterType delimiterType) {
+ this.delimiterType = delimiterType.getValue();
+ }
+
+ /**
+ * Print result sets from the statements;
+ * optional, default false
+ * @param print if true print result sets.
+ */
+ public void setPrint(boolean print) {
+ this.print = print;
+ }
+
+ /**
+ * Print headers for result sets from the
+ * statements; optional, default true.
+ * @param showheaders if true print headers of result sets.
+ */
+ public void setShowheaders(boolean showheaders) {
+ this.showheaders = showheaders;
+ }
+
+ /**
+ * Print trailing info (rows affected) for the SQL
+ * Addresses Bug/Request #27446
+ * @param showtrailers if true prints the SQL rows affected
+ * @since Ant 1.7
+ */
+ public void setShowtrailers(boolean showtrailers) {
+ this.showtrailers = showtrailers;
+ }
+
+ /**
+ * Set the output file;
+ * optional, defaults to the Ant log.
+ * @param output the output file to use for logging messages.
+ */
+ public void setOutput(File output) {
+ setOutput(new FileResource(getProject(), output));
+ }
+
+ /**
+ * Set the output Resource;
+ * optional, defaults to the Ant log.
+ * @param output the output Resource to store results.
+ * @since Ant 1.8
+ */
+ public void setOutput(Resource output) {
+ this.output = output;
+ }
+
+ /**
+ * The encoding to use when writing the result to a resource.
+ * <p>Default's to the platform's default encoding</p>
+ * @param outputEncoding the name of the encoding or null for the
+ * platform's default encoding
+ * @since Ant 1.9.4
+ */
+ public void setOutputEncoding(String outputEncoding) {
+ this.outputEncoding = outputEncoding;
+ }
+
+ /**
+ * whether output should be appended to or overwrite
+ * an existing file. Defaults to false.
+ *
+ * @since Ant 1.5
+ * @param append if true append to an existing file.
+ */
+ public void setAppend(boolean append) {
+ this.append = append;
+ }
+
+
+ /**
+ * Action to perform when statement fails: continue, stop, or abort
+ * optional; default &quot;abort&quot;
+ * @param action the action to perform on statement failure.
+ */
+ public void setOnerror(OnError action) {
+ this.onError = action.getValue();
+ }
+
+ /**
+ * whether or not format should be preserved.
+ * Defaults to false.
+ *
+ * @param keepformat The keepformat to set
+ */
+ public void setKeepformat(boolean keepformat) {
+ this.keepformat = keepformat;
+ }
+
+ /**
+ * Set escape processing for statements.
+ * @param enable if true enable escape processing, default is true.
+ * @since Ant 1.6
+ */
+ public void setEscapeProcessing(boolean enable) {
+ escapeProcessing = enable;
+ }
+
+ /**
+ * Set whether to print raw BLOBs rather than their string (hex) representations.
+ * @param rawBlobs whether to print raw BLOBs.
+ * @since Ant 1.7.1
+ */
+ public void setRawBlobs(boolean rawBlobs) {
+ this.rawBlobs = rawBlobs;
+ }
+
+ /**
+ * If false, delimiters will be searched for in a case-insensitive
+ * manner (i.e. delimiter="go" matches "GO") and surrounding
+ * whitespace will be ignored (delimiter="go" matches "GO ").
+ * @since Ant 1.8.0
+ */
+ public void setStrictDelimiterMatching(boolean b) {
+ strictDelimiterMatching = b;
+ }
+
+ /**
+ * whether to show SQLWarnings as WARN messages.
+ * @since Ant 1.8.0
+ */
+ public void setShowWarnings(boolean b) {
+ showWarnings = b;
+ }
+
+ /**
+ * Whether a warning is an error - in which case onError applies.
+ * @since Ant 1.8.0
+ */
+ public void setTreatWarningsAsErrors(boolean b) {
+ treatWarningsAsErrors = b;
+ }
+
+ /**
+ * The column separator used when printing the results.
+ *
+ * <p>Defaults to ","</p>
+ *
+ * @since Ant 1.8.0
+ */
+ public void setCsvColumnSeparator(String s) {
+ csvColumnSep = s;
+ }
+
+ /**
+ * The character used to quote column values.
+ *
+ * <p>If set, columns that contain either the column separator or
+ * the quote character itself will be surrounded by the quote
+ * character. The quote character itself will be doubled if it
+ * appears inside of the column's value.</p>
+ *
+ * <p>If this value is not set (the default), no column values
+ * will be quoted, not even if they contain the column
+ * separator.</p>
+ *
+ * <p><b>Note:</b> BLOB values will never be quoted.</p>
+ *
+ * <p>Defaults to "not set"</p>
+ *
+ * @since Ant 1.8.0
+ */
+ public void setCsvQuoteCharacter(String s) {
+ if (s != null && s.length() > 1) {
+ throw new BuildException("The quote character must be a single"
+ + " character.");
+ }
+ csvQuoteChar = s;
+ }
+
+ /**
+ * Property to set to "true" if a statement throws an error.
+ *
+ * @param errorProperty the name of the property to set in the
+ * event of an error.
+ * @since Ant 1.8.0
+ */
+ public void setErrorProperty(String errorProperty) {
+ this.errorProperty = errorProperty;
+ }
+
+ /**
+ * Property to set to "true" if a statement produces a warning.
+ *
+ * @param warningProperty the name of the property to set in the
+ * event of a warning.
+ * @since Ant 1.8.0
+ */
+ public void setWarningProperty(String warningProperty) {
+ this.warningProperty = warningProperty;
+ }
+
+ /**
+ * Sets a given property to the number of rows in the first
+ * statement that returned a row count.
+ * @since Ant 1.8.0
+ */
+ public void setRowCountProperty(String rowCountProperty) {
+ this.rowCountProperty = rowCountProperty;
+ }
+
+ /**
+ * Load the sql file and then execute it
+ * @throws BuildException on error.
+ */
+ @Override
+ public void execute() throws BuildException {
+ Vector savedTransaction = (Vector) transactions.clone();
+ String savedSqlCommand = sqlCommand;
+
+ sqlCommand = sqlCommand.trim();
+
+ try {
+ if (srcFile == null && sqlCommand.length() == 0 && resources == null) {
+ if (transactions.size() == 0) {
+ throw new BuildException("Source file or resource collection, "
+ + "transactions or sql statement "
+ + "must be set!", getLocation());
+ }
+ }
+
+ if (srcFile != null && !srcFile.isFile()) {
+ throw new BuildException("Source file " + srcFile
+ + " is not a file!", getLocation());
+ }
+
+ if (resources != null) {
+ // deal with the resources
+ for (Resource r : resources) {
+ // Make a transaction for each resource
+ Transaction t = createTransaction();
+ t.setSrcResource(r);
+ }
+ }
+
+ // Make a transaction group for the outer command
+ Transaction t = createTransaction();
+ t.setSrc(srcFile);
+ t.addText(sqlCommand);
+
+ if (getConnection() == null) {
+ // not a valid rdbms
+ return;
+ }
+
+ try {
+ PrintStream out = KeepAliveOutputStream.wrapSystemOut();
+ try {
+ if (output != null) {
+ log("Opening PrintStream to output Resource " + output, Project.MSG_VERBOSE);
+ OutputStream os = null;
+ FileProvider fp =
+ output.as(FileProvider.class);
+ if (fp != null) {
+ os = new FileOutputStream(fp.getFile(), append);
+ } else {
+ if (append) {
+ Appendable a =
+ output.as(Appendable.class);
+ if (a != null) {
+ os = a.getAppendOutputStream();
+ }
+ }
+ if (os == null) {
+ os = output.getOutputStream();
+ if (append) {
+ log("Ignoring append=true for non-appendable"
+ + " resource " + output,
+ Project.MSG_WARN);
+ }
+ }
+ }
+ if (outputEncoding != null) {
+ out = new PrintStream(new BufferedOutputStream(os),
+ false, outputEncoding);
+ } else {
+ out = new PrintStream(new BufferedOutputStream(os));
+ }
+ }
+
+ // Process all transactions
+ for (Enumeration e = transactions.elements();
+ e.hasMoreElements();) {
+
+ ((Transaction) e.nextElement()).runTransaction(out);
+ if (!isAutocommit()) {
+ log("Committing transaction", Project.MSG_VERBOSE);
+ getConnection().commit();
+ }
+ }
+ } finally {
+ FileUtils.close(out);
+ }
+ } catch (IOException e) {
+ closeQuietly();
+ setErrorProperty();
+ if (onError.equals("abort")) {
+ throw new BuildException(e, getLocation());
+ }
+ } catch (SQLException e) {
+ closeQuietly();
+ setErrorProperty();
+ if (onError.equals("abort")) {
+ throw new BuildException(e, getLocation());
+ }
+ } finally {
+ try {
+ if (getStatement() != null) {
+ getStatement().close();
+ }
+ } catch (SQLException ex) {
+ // ignore
+ }
+ try {
+ if (getConnection() != null) {
+ getConnection().close();
+ }
+ } catch (SQLException ex) {
+ // ignore
+ }
+ }
+
+ log(goodSql + " of " + totalSql + " SQL statements executed successfully");
+ } finally {
+ transactions = savedTransaction;
+ sqlCommand = savedSqlCommand;
+ }
+ }
+
+ /**
+ * read in lines and execute them
+ * @param reader the reader contains sql lines.
+ * @param out the place to output results.
+ * @throws SQLException on sql problems
+ * @throws IOException on io problems
+ */
+ protected void runStatements(Reader reader, PrintStream out)
+ throws SQLException, IOException {
+ StringBuffer sql = new StringBuffer();
+ String line;
+
+ BufferedReader in = new BufferedReader(reader);
+
+ while ((line = in.readLine()) != null) {
+ if (!keepformat) {
+ line = line.trim();
+ }
+ if (expandProperties) {
+ line = getProject().replaceProperties(line);
+ }
+ if (!keepformat) {
+ if (line.startsWith("//")) {
+ continue;
+ }
+ if (line.startsWith("--")) {
+ continue;
+ }
+ StringTokenizer st = new StringTokenizer(line);
+ if (st.hasMoreTokens()) {
+ String token = st.nextToken();
+ if ("REM".equalsIgnoreCase(token)) {
+ continue;
+ }
+ }
+ }
+
+ sql.append(keepformat ? "\n" : " ").append(line);
+
+ // SQL defines "--" as a comment to EOL
+ // and in Oracle it may contain a hint
+ // so we cannot just remove it, instead we must end it
+ if (!keepformat && line.indexOf("--") >= 0) {
+ sql.append("\n");
+ }
+ int lastDelimPos = lastDelimiterPosition(sql, line);
+ if (lastDelimPos > -1) {
+ execSQL(sql.substring(0, lastDelimPos), out);
+ sql.replace(0, sql.length(), "");
+ }
+ }
+ // Catch any statements not followed by ;
+ if (sql.length() > 0) {
+ execSQL(sql.toString(), out);
+ }
+ }
+
+ /**
+ * Exec the sql statement.
+ * @param sql the SQL statement to execute
+ * @param out the place to put output
+ * @throws SQLException on SQL problems
+ */
+ protected void execSQL(String sql, PrintStream out) throws SQLException {
+ // Check and ignore empty statements
+ if ("".equals(sql.trim())) {
+ return;
+ }
+
+ ResultSet resultSet = null;
+ try {
+ totalSql++;
+ log("SQL: " + sql, Project.MSG_VERBOSE);
+
+ boolean ret;
+ int updateCount = 0, updateCountTotal = 0;
+
+ ret = getStatement().execute(sql);
+ updateCount = getStatement().getUpdateCount();
+ do {
+ if (updateCount != -1) {
+ updateCountTotal += updateCount;
+ }
+ if (ret) {
+ resultSet = getStatement().getResultSet();
+ printWarnings(resultSet.getWarnings(), false);
+ resultSet.clearWarnings();
+ if (print) {
+ printResults(resultSet, out);
+ }
+ }
+ ret = getStatement().getMoreResults();
+ updateCount = getStatement().getUpdateCount();
+ } while (ret || updateCount != -1);
+
+ printWarnings(getStatement().getWarnings(), false);
+ getStatement().clearWarnings();
+
+ log(updateCountTotal + " rows affected", Project.MSG_VERBOSE);
+ if (updateCountTotal != -1) {
+ setRowCountProperty(updateCountTotal);
+ }
+
+ if (print && showtrailers) {
+ out.println(updateCountTotal + " rows affected");
+ }
+ SQLWarning warning = getConnection().getWarnings();
+ printWarnings(warning, true);
+ getConnection().clearWarnings();
+ goodSql++;
+ } catch (SQLException e) {
+ log("Failed to execute: " + sql, Project.MSG_ERR);
+ setErrorProperty();
+ if (!onError.equals("abort")) {
+ log(e.toString(), Project.MSG_ERR);
+ }
+ if (!onError.equals("continue")) {
+ throw e;
+ }
+ } finally {
+ if (resultSet != null) {
+ try {
+ resultSet.close();
+ } catch (SQLException e) {
+ //ignore
+ }
+ }
+ }
+ }
+
+ /**
+ * print any results in the statement
+ * @deprecated since 1.6.x.
+ * Use {@link #printResults(java.sql.ResultSet, java.io.PrintStream)
+ * the two arg version} instead.
+ * @param out the place to print results
+ * @throws SQLException on SQL problems.
+ */
+ @Deprecated
+ protected void printResults(PrintStream out) throws SQLException {
+ ResultSet rs = getStatement().getResultSet();
+ try {
+ printResults(rs, out);
+ } finally {
+ if (rs != null) {
+ rs.close();
+ }
+ }
+ }
+
+ /**
+ * print any results in the result set.
+ * @param rs the resultset to print information about
+ * @param out the place to print results
+ * @throws SQLException on SQL problems.
+ * @since Ant 1.6.3
+ */
+ protected void printResults(ResultSet rs, PrintStream out) throws SQLException {
+ if (rs != null) {
+ log("Processing new result set.", Project.MSG_VERBOSE);
+ ResultSetMetaData md = rs.getMetaData();
+ int columnCount = md.getColumnCount();
+ if (columnCount > 0) {
+ if (showheaders) {
+ out.print(md.getColumnName(1));
+ for (int col = 2; col <= columnCount; col++) {
+ out.print(csvColumnSep);
+ out.print(maybeQuote(md.getColumnName(col)));
+ }
+ out.println();
+ }
+ while (rs.next()) {
+ printValue(rs, 1, out);
+ for (int col = 2; col <= columnCount; col++) {
+ out.print(csvColumnSep);
+ printValue(rs, col, out);
+ }
+ out.println();
+ printWarnings(rs.getWarnings(), false);
+ }
+ }
+ }
+ out.println();
+ }
+
+ private void printValue(ResultSet rs, int col, PrintStream out)
+ throws SQLException {
+ if (rawBlobs && rs.getMetaData().getColumnType(col) == Types.BLOB) {
+ Blob blob = rs.getBlob(col);
+ if (blob != null) {
+ new StreamPumper(rs.getBlob(col).getBinaryStream(), out).run();
+ }
+ } else {
+ out.print(maybeQuote(rs.getString(col)));
+ }
+ }
+
+ private String maybeQuote(String s) {
+ if (csvQuoteChar == null || s == null
+ || (s.indexOf(csvColumnSep) == -1 && s.indexOf(csvQuoteChar) == -1)
+ ) {
+ return s;
+ }
+ StringBuffer sb = new StringBuffer(csvQuoteChar);
+ int len = s.length();
+ char q = csvQuoteChar.charAt(0);
+ for (int i = 0; i < len; i++) {
+ char c = s.charAt(i);
+ if (c == q) {
+ sb.append(q);
+ }
+ sb.append(c);
+ }
+ return sb.append(csvQuoteChar).toString();
+ }
+
+ /*
+ * Closes an unused connection after an error and doesn't rethrow
+ * a possible SQLException
+ * @since Ant 1.7
+ */
+ private void closeQuietly() {
+ if (!isAutocommit() && getConnection() != null && onError.equals("abort")) {
+ try {
+ getConnection().rollback();
+ } catch (SQLException ex) {
+ // ignore
+ }
+ }
+ }
+
+
+ /**
+ * Caches the connection returned by the base class's getConnection method.
+ *
+ * <p>Subclasses that need to provide a different connection than
+ * the base class would, should override this method but keep in
+ * mind that this class expects to get the same connection
+ * instance on consecutive calls.</p>
+ *
+ * <p>returns null if the connection does not connect to the
+ * expected RDBMS.</p>
+ */
+ @Override
+ protected Connection getConnection() {
+ if (conn == null) {
+ conn = super.getConnection();
+ if (!isValidRdbms(conn)) {
+ conn = null;
+ }
+ }
+ return conn;
+ }
+
+ /**
+ * Creates and configures a Statement instance which is then
+ * cached for subsequent calls.
+ *
+ * <p>Subclasses that want to provide different Statement
+ * instances, should override this method but keep in mind that
+ * this class expects to get the same connection instance on
+ * consecutive calls.</p>
+ */
+ protected Statement getStatement() throws SQLException {
+ if (statement == null) {
+ statement = getConnection().createStatement();
+ statement.setEscapeProcessing(escapeProcessing);
+ }
+
+ return statement;
+ }
+
+ /**
+ * The action a task should perform on an error,
+ * one of "continue", "stop" and "abort"
+ */
+ public static class OnError extends EnumeratedAttribute {
+ /** @return the enumerated values */
+ @Override
+ public String[] getValues() {
+ return new String[] {"continue", "stop", "abort"};
+ }
+ }
+
+ /**
+ * Contains the definition of a new transaction element.
+ * Transactions allow several files or blocks of statements
+ * to be executed using the same JDBC connection and commit
+ * operation in between.
+ */
+ public class Transaction {
+ private Resource tSrcResource = null;
+ private String tSqlCommand = "";
+
+ /**
+ * Set the source file attribute.
+ * @param src the source file
+ */
+ public void setSrc(File src) {
+ //there are places (in this file, and perhaps elsewhere, where it is assumed
+ //that null is an acceptable parameter.
+ if (src != null) {
+ setSrcResource(new FileResource(src));
+ }
+ }
+
+ /**
+ * Set the source resource attribute.
+ * @param src the source file
+ * @since Ant 1.7
+ */
+ public void setSrcResource(Resource src) {
+ if (tSrcResource != null) {
+ throw new BuildException("only one resource per transaction");
+ }
+ tSrcResource = src;
+ }
+
+ /**
+ * Set inline text
+ * @param sql the inline text
+ */
+ public void addText(String sql) {
+ if (sql != null) {
+ this.tSqlCommand += sql;
+ }
+ }
+
+ /**
+ * Set the source resource.
+ * @param a the source resource collection.
+ * @since Ant 1.7
+ */
+ public void addConfigured(ResourceCollection a) {
+ if (a.size() != 1) {
+ throw new BuildException("only single argument resource "
+ + "collections are supported.");
+ }
+ setSrcResource(a.iterator().next());
+ }
+
+ /**
+ *
+ */
+ private void runTransaction(PrintStream out)
+ throws IOException, SQLException {
+ if (tSqlCommand.length() != 0) {
+ log("Executing commands", Project.MSG_INFO);
+ runStatements(new StringReader(tSqlCommand), out);
+ }
+
+ if (tSrcResource != null) {
+ log("Executing resource: " + tSrcResource.toString(),
+ Project.MSG_INFO);
+ InputStream is = null;
+ Reader reader = null;
+ try {
+ is = tSrcResource.getInputStream();
+ reader = (encoding == null) ? new InputStreamReader(is)
+ : new InputStreamReader(is, encoding);
+ runStatements(reader, out);
+ } finally {
+ FileUtils.close(is);
+ FileUtils.close(reader);
+ }
+ }
+ }
+ }
+
+ public int lastDelimiterPosition(StringBuffer buf, String currentLine) {
+ if (strictDelimiterMatching) {
+ if ((delimiterType.equals(DelimiterType.NORMAL)
+ && StringUtils.endsWith(buf, delimiter)) ||
+ (delimiterType.equals(DelimiterType.ROW)
+ && currentLine.equals(delimiter))) {
+ return buf.length() - delimiter.length();
+ }
+ // no match
+ return -1;
+ } else {
+ String d = delimiter.trim().toLowerCase(Locale.ENGLISH);
+ if (delimiterType.equals(DelimiterType.NORMAL)) {
+ // still trying to avoid wasteful copying, see
+ // StringUtils.endsWith
+ int endIndex = delimiter.length() - 1;
+ int bufferIndex = buf.length() - 1;
+ while (bufferIndex >= 0
+ && Character.isWhitespace(buf.charAt(bufferIndex))) {
+ --bufferIndex;
+ }
+ if (bufferIndex < endIndex) {
+ return -1;
+ }
+ while (endIndex >= 0) {
+ if (buf.substring(bufferIndex, bufferIndex + 1)
+ .toLowerCase(Locale.ENGLISH).charAt(0)
+ != d.charAt(endIndex)) {
+ return -1;
+ }
+ bufferIndex--;
+ endIndex--;
+ }
+ return bufferIndex + 1;
+ } else {
+ return currentLine.trim().toLowerCase(Locale.ENGLISH).equals(d)
+ ? buf.length() - currentLine.length() : -1;
+ }
+ }
+ }
+
+ private void printWarnings(SQLWarning warning, boolean force)
+ throws SQLException {
+ SQLWarning initialWarning = warning;
+ if (showWarnings || force) {
+ while (warning != null) {
+ log(warning + " sql warning",
+ showWarnings ? Project.MSG_WARN : Project.MSG_VERBOSE);
+ warning = warning.getNextWarning();
+ }
+ }
+ if (initialWarning != null) {
+ setWarningProperty();
+ }
+ if (treatWarningsAsErrors && initialWarning != null) {
+ throw initialWarning;
+ }
+ }
+
+ protected final void setErrorProperty() {
+ setProperty(errorProperty, "true");
+ }
+
+ protected final void setWarningProperty() {
+ setProperty(warningProperty, "true");
+ }
+
+ protected final void setRowCountProperty(int rowCount) {
+ setProperty(rowCountProperty, Integer.toString(rowCount));
+ }
+
+ private void setProperty(String name, String value) {
+ if (name != null) {
+ getProject().setNewProperty(name, value);
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/SendEmail.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/SendEmail.java
new file mode 100644
index 00000000..58d5cdc0
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/SendEmail.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.taskdefs.email.EmailTask;
+
+/**
+ * A task to send SMTP email.
+ * This task can send mail using either plain
+ * text, UU encoding or Mime format mail depending on what is available.
+ * Attachments may be sent using nested FileSet
+ * elements.
+ *
+ * @since Ant 1.2
+ *
+ * @ant.task name="mail" category="network"
+ */
+public class SendEmail extends EmailTask {
+ /**
+ * Sets the mailport parameter of this build task.
+ * @param value mail port name.
+ *
+ * @deprecated since 1.5.x.
+ * Use {@link #setMailport(int)} instead.
+ */
+ public void setMailport(Integer value) {
+ setMailport(value.intValue());
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Sequential.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Sequential.java
new file mode 100644
index 00000000..468ac148
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Sequential.java
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs;
+
+import java.util.Iterator;
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.TaskContainer;
+import org.apache.tools.ant.property.LocalProperties;
+
+/**
+ * Sequential is a container task - it can contain other Ant tasks. The nested
+ * tasks are simply executed in sequence. Sequential's primary use is to support
+ * the sequential execution of a subset of tasks within the {@link Parallel Parallel Task}
+
+ * <p>
+ * The sequential task has no attributes and does not support any nested
+ * elements apart from Ant tasks. Any valid Ant task may be embedded within the
+ * sequential task.</p>
+ *
+ * @since Ant 1.4
+ * @ant.task category="control"
+ */
+public class Sequential extends Task implements TaskContainer {
+
+ /** Optional Vector holding the nested tasks */
+ private Vector nestedTasks = new Vector();
+
+ /**
+ * Add a nested task to Sequential.
+ * <p>
+ * @param nestedTask Nested task to execute Sequential
+ * <p>
+ */
+ public void addTask(Task nestedTask) {
+ nestedTasks.addElement(nestedTask);
+ }
+
+ /**
+ * Execute all nestedTasks.
+ *
+ * @throws BuildException if one of the nested tasks fails.
+ */
+ public void execute() throws BuildException {
+ LocalProperties localProperties
+ = LocalProperties.get(getProject());
+ localProperties.enterScope();
+ try {
+ for (Iterator i = nestedTasks.iterator(); i.hasNext();) {
+ Task nestedTask = (Task) i.next();
+ nestedTask.perform();
+ }
+ } finally {
+ localProperties.exitScope();
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/SignJar.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/SignJar.java
new file mode 100644
index 00000000..fc31b1d3
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/SignJar.java
@@ -0,0 +1,645 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.condition.IsSigned;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.resources.FileProvider;
+import org.apache.tools.ant.types.resources.FileResource;
+import org.apache.tools.ant.util.FileNameMapper;
+import org.apache.tools.ant.util.FileUtils;
+import org.apache.tools.ant.util.IdentityMapper;
+import org.apache.tools.ant.util.ResourceUtils;
+
+/**
+ * Signs JAR or ZIP files with the javasign command line tool. The tool detailed
+ * dependency checking: files are only signed if they are not signed. The
+ * <tt>signjar</tt> attribute can point to the file to generate; if this file
+ * exists then its modification date is used as a cue as to whether to resign
+ * any JAR file.
+ *
+ * Timestamp driven signing is based on the unstable and inadequately documented
+ * information in the Java1.5 docs
+ * @see <a href="http://java.sun.com/j2se/1.5.0/docs/guide/security/time-of-signing-beta1.html">
+ * beta documentation</a>
+ * @ant.task category="java"
+ * @since Ant 1.1
+ */
+public class SignJar extends AbstractJarSignerTask {
+ // CheckStyle:VisibilityModifier OFF - bc
+
+ private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+
+ /**
+ * name to a signature file
+ */
+ protected String sigfile;
+
+ /**
+ * name of a single jar
+ */
+ protected File signedjar;
+
+ /**
+ * flag for internal sf signing
+ */
+ protected boolean internalsf;
+
+ /**
+ * sign sections only?
+ */
+ protected boolean sectionsonly;
+
+ /**
+ * flag to preserve timestamp on modified files
+ */
+ private boolean preserveLastModified;
+
+ /**
+ * Whether to assume a jar which has an appropriate .SF file in is already
+ * signed.
+ */
+ protected boolean lazy;
+
+ /**
+ * the output directory when using paths.
+ */
+ protected File destDir;
+
+ /**
+ * mapper for todir work
+ */
+ private FileNameMapper mapper;
+
+ /**
+ * URL for a tsa; null implies no tsa support
+ */
+ protected String tsaurl;
+
+ /**
+ * Proxy host to be used when connecting to TSA server
+ */
+ protected String tsaproxyhost;
+
+ /**
+ * Proxy port to be used when connecting to TSA server
+ */
+ protected String tsaproxyport;
+
+ /**
+ * alias for the TSA in the keystore
+ */
+ protected String tsacert;
+
+ /**
+ * force signing even if the jar is already signed.
+ */
+ private boolean force = false;
+
+ /**
+ * signature algorithm
+ */
+ private String sigAlg;
+
+ /**
+ * digest algorithm
+ */
+ private String digestAlg;
+
+ /**
+ * error string for unit test verification: {@value}
+ */
+ public static final String ERROR_TODIR_AND_SIGNEDJAR
+ = "'destdir' and 'signedjar' cannot both be set";
+ /**
+ * error string for unit test verification: {@value}
+ */
+ public static final String ERROR_TOO_MANY_MAPPERS = "Too many mappers";
+ /**
+ * error string for unit test verification {@value}
+ */
+ public static final String ERROR_SIGNEDJAR_AND_PATHS
+ = "You cannot specify the signed JAR when using paths or filesets";
+ /**
+ * error string for unit test verification: {@value}
+ */
+ public static final String ERROR_BAD_MAP = "Cannot map source file to anything sensible: ";
+ /**
+ * error string for unit test verification: {@value}
+ */
+ public static final String ERROR_MAPPER_WITHOUT_DEST
+ = "The destDir attribute is required if a mapper is set";
+ /**
+ * error string for unit test verification: {@value}
+ */
+ public static final String ERROR_NO_ALIAS = "alias attribute must be set";
+ /**
+ * error string for unit test verification: {@value}
+ */
+ public static final String ERROR_NO_STOREPASS = "storepass attribute must be set";
+ // CheckStyle:VisibilityModifier ON
+
+ /**
+ * name of .SF/.DSA file; optional
+ *
+ * @param sigfile the name of the .SF/.DSA file
+ */
+ public void setSigfile(final String sigfile) {
+ this.sigfile = sigfile;
+ }
+
+ /**
+ * name of signed JAR file; optional
+ *
+ * @param signedjar the name of the signed jar file
+ */
+ public void setSignedjar(final File signedjar) {
+ this.signedjar = signedjar;
+ }
+
+ /**
+ * Flag to include the .SF file inside the signature; optional; default
+ * false
+ *
+ * @param internalsf if true include the .SF file inside the signature
+ */
+ public void setInternalsf(final boolean internalsf) {
+ this.internalsf = internalsf;
+ }
+
+ /**
+ * flag to compute hash of entire manifest; optional, default false
+ *
+ * @param sectionsonly flag to compute hash of entire manifest
+ */
+ public void setSectionsonly(final boolean sectionsonly) {
+ this.sectionsonly = sectionsonly;
+ }
+
+ /**
+ * flag to control whether the presence of a signature file means a JAR is
+ * signed; optional, default false
+ *
+ * @param lazy flag to control whether the presence of a signature
+ */
+ public void setLazy(final boolean lazy) {
+ this.lazy = lazy;
+ }
+
+ /**
+ * Optionally sets the output directory to be used.
+ *
+ * @param destDir the directory in which to place signed jars
+ * @since Ant 1.7
+ */
+ public void setDestDir(File destDir) {
+ this.destDir = destDir;
+ }
+
+
+ /**
+ * add a mapper to determine file naming policy. Only used with toDir
+ * processing.
+ *
+ * @param newMapper the mapper to add.
+ * @since Ant 1.7
+ */
+ public void add(FileNameMapper newMapper) {
+ if (mapper != null) {
+ throw new BuildException(ERROR_TOO_MANY_MAPPERS);
+ }
+ mapper = newMapper;
+ }
+
+ /**
+ * get the active mapper; may be null
+ * @return mapper or null
+ * @since Ant 1.7
+ */
+ public FileNameMapper getMapper() {
+ return mapper;
+ }
+
+ /**
+ * get the -tsaurl url
+ * @return url or null
+ * @since Ant 1.7
+ */
+ public String getTsaurl() {
+ return tsaurl;
+ }
+
+ /**
+ *
+ * @param tsaurl the tsa url.
+ * @since Ant 1.7
+ */
+ public void setTsaurl(String tsaurl) {
+ this.tsaurl = tsaurl;
+ }
+
+ /**
+ * Get the proxy host to be used when connecting to the TSA url
+ * @return url or null
+ * @since Ant 1.9.5
+ */
+ public String getTsaproxyhost() {
+ return tsaproxyhost;
+ }
+
+ /**
+ *
+ * @param tsaproxyhost the proxy host to be used when connecting to the TSA.
+ * @since Ant 1.9.5
+ */
+ public void setTsaproxyhost(String tsaproxyhost) {
+ this.tsaproxyhost = tsaproxyhost;
+ }
+
+ /**
+ * Get the proxy host to be used when connecting to the TSA url
+ * @return url or null
+ * @since Ant 1.9.5
+ */
+ public String getTsaproxyport() {
+ return tsaproxyport;
+ }
+
+ /**
+ *
+ * @param tsaproxyport the proxy port to be used when connecting to the TSA.
+ * @since Ant 1.9.5
+ */
+ public void setTsaproxyport(String tsaproxyport) {
+ this.tsaproxyport = tsaproxyport;
+ }
+
+ /**
+ * get the -tsacert option
+ * @since Ant 1.7
+ * @return a certificate alias or null
+ */
+ public String getTsacert() {
+ return tsacert;
+ }
+
+ /**
+ * set the alias in the keystore of the TSA to use;
+ * @param tsacert the cert alias.
+ */
+ public void setTsacert(String tsacert) {
+ this.tsacert = tsacert;
+ }
+
+ /**
+ * Whether to force signing of a jar even it is already signed.
+ * @since Ant 1.8.0
+ */
+ public void setForce(boolean b) {
+ force = b;
+ }
+
+ /**
+ * Should the task force signing of a jar even it is already
+ * signed?
+ * @since Ant 1.8.0
+ */
+ public boolean isForce() {
+ return force;
+ }
+
+ /**
+ * Signature Algorithm; optional
+ *
+ * @param sigAlg the signature algorithm
+ */
+ public void setSigAlg(String sigAlg) {
+ this.sigAlg = sigAlg;
+ }
+
+ /**
+ * Signature Algorithm; optional
+ */
+ public String getSigAlg() {
+ return sigAlg;
+ }
+
+ /**
+ * Digest Algorithm; optional
+ *
+ * @param digestAlg the digest algorithm
+ */
+ public void setDigestAlg(String digestAlg) {
+ this.digestAlg = digestAlg;
+ }
+
+ /**
+ * Digest Algorithm; optional
+ */
+ public String getDigestAlg() {
+ return digestAlg;
+ }
+
+ /**
+ * sign the jar(s)
+ *
+ * @throws BuildException on errors
+ */
+ @Override
+ public void execute() throws BuildException {
+ //validation logic
+ final boolean hasJar = jar != null;
+ final boolean hasSignedJar = signedjar != null;
+ final boolean hasDestDir = destDir != null;
+ final boolean hasMapper = mapper != null;
+
+ if (!hasJar && !hasResources()) {
+ throw new BuildException(ERROR_NO_SOURCE);
+ }
+ if (null == alias) {
+ throw new BuildException(ERROR_NO_ALIAS);
+ }
+
+ if (null == storepass) {
+ throw new BuildException(ERROR_NO_STOREPASS);
+ }
+
+ if (hasDestDir && hasSignedJar) {
+ throw new BuildException(ERROR_TODIR_AND_SIGNEDJAR);
+ }
+
+
+ if (hasResources() && hasSignedJar) {
+ throw new BuildException(ERROR_SIGNEDJAR_AND_PATHS);
+ }
+
+ //this isn't strictly needed, but by being fussy now,
+ //we can change implementation details later
+ if (!hasDestDir && hasMapper) {
+ throw new BuildException(ERROR_MAPPER_WITHOUT_DEST);
+ }
+
+ beginExecution();
+
+
+ try {
+ //special case single jar handling with signedjar attribute set
+ if (hasJar && hasSignedJar) {
+ // single jar processing
+ signOneJar(jar, signedjar);
+ //return here.
+ return;
+ }
+
+ //the rest of the method treats single jar like
+ //a nested path with one file
+
+ Path sources = createUnifiedSourcePath();
+ //set up our mapping policy
+ FileNameMapper destMapper;
+ if (hasMapper) {
+ destMapper = mapper;
+ } else {
+ //no mapper? use the identity policy
+ destMapper = new IdentityMapper();
+ }
+
+
+ //at this point the paths are set up with lists of files,
+ //and the mapper is ready to map from source dirs to dest files
+ //now we iterate through every JAR giving source and dest names
+ // deal with the paths
+ for (Resource r : sources) {
+ FileResource fr = ResourceUtils
+ .asFileResource(r.as(FileProvider.class));
+
+ //calculate our destination directory; it is either the destDir
+ //attribute, or the base dir of the fileset (for in situ updates)
+ File toDir = hasDestDir ? destDir : fr.getBaseDir();
+
+ //determine the destination filename via the mapper
+ String[] destFilenames = destMapper.mapFileName(fr.getName());
+ if (destFilenames == null || destFilenames.length != 1) {
+ //we only like simple mappers.
+ throw new BuildException(ERROR_BAD_MAP + fr.getFile());
+ }
+ File destFile = new File(toDir, destFilenames[0]);
+ signOneJar(fr.getFile(), destFile);
+ }
+ } finally {
+ endExecution();
+ }
+ }
+
+ /**
+ * Sign one jar.
+ * <p/>
+ * The signing only takes place if {@link #isUpToDate(File, File)} indicates
+ * that it is needed.
+ *
+ * @param jarSource source to sign
+ * @param jarTarget target; may be null
+ * @throws BuildException
+ */
+ private void signOneJar(File jarSource, File jarTarget)
+ throws BuildException {
+
+
+ File targetFile = jarTarget;
+ if (targetFile == null) {
+ targetFile = jarSource;
+ }
+ if (isUpToDate(jarSource, targetFile)) {
+ return;
+ }
+
+ long lastModified = jarSource.lastModified();
+ final ExecTask cmd = createJarSigner();
+
+ setCommonOptions(cmd);
+
+ bindToKeystore(cmd);
+ if (null != sigfile) {
+ addValue(cmd, "-sigfile");
+ String value = this.sigfile;
+ addValue(cmd, value);
+ }
+
+ try {
+ //DO NOT SET THE -signedjar OPTION if source==dest
+ //unless you like fielding hotspot crash reports
+ if (!FILE_UTILS.areSame(jarSource, targetFile)) {
+ addValue(cmd, "-signedjar");
+ addValue(cmd, targetFile.getPath());
+ }
+ } catch (IOException ioex) {
+ throw new BuildException(ioex);
+ }
+
+ if (internalsf) {
+ addValue(cmd, "-internalsf");
+ }
+
+ if (sectionsonly) {
+ addValue(cmd, "-sectionsonly");
+ }
+
+ if (sigAlg != null) {
+ addValue(cmd, "-sigalg");
+ addValue(cmd, sigAlg);
+ }
+
+ if (digestAlg != null) {
+ addValue(cmd, "-digestalg");
+ addValue(cmd, digestAlg);
+ }
+
+ //add -tsa operations if declared
+ addTimestampAuthorityCommands(cmd);
+
+ //JAR source is required
+ addValue(cmd, jarSource.getPath());
+
+ //alias is required for signing
+ addValue(cmd, alias);
+
+ log("Signing JAR: "
+ + jarSource.getAbsolutePath()
+ + " to "
+ + targetFile.getAbsolutePath()
+ + " as " + alias);
+
+ cmd.execute();
+
+ // restore the lastModified attribute
+ if (preserveLastModified) {
+ FILE_UTILS.setFileLastModified(targetFile, lastModified);
+ }
+ }
+
+ /**
+ * If the tsa parameters are set, this passes them to the command.
+ * There is no validation of java version, as third party JDKs
+ * may implement this on earlier/later jarsigner implementations.
+ * @param cmd the exec task.
+ */
+ private void addTimestampAuthorityCommands(final ExecTask cmd) {
+ if (tsaurl != null) {
+ addValue(cmd, "-tsa");
+ addValue(cmd, tsaurl);
+ }
+
+ if (tsacert != null) {
+ addValue(cmd, "-tsacert");
+ addValue(cmd, tsacert);
+ }
+
+ if (tsaproxyhost != null) {
+ if (tsaurl == null || tsaurl.startsWith("https")) {
+ addProxyFor(cmd, "https");
+ }
+ if (tsaurl == null || !tsaurl.startsWith("https")) {
+ addProxyFor(cmd, "http");
+ }
+ }
+ }
+
+ /**
+ * <p>Compare a jar file with its corresponding signed jar. The logic for this
+ * is complex, and best explained in the source itself. Essentially if
+ * either file doesn't exist, or the destfile has an out of date timestamp,
+ * then the return value is false.</p>
+ *
+ * <p>If we are signing ourself, the check {@link #isSigned(File)} is used to
+ * trigger the process.</p>
+ *
+ * @param jarFile the unsigned jar file
+ * @param signedjarFile the result signed jar file
+ * @return true if the signedjarFile is considered up to date
+ */
+ protected boolean isUpToDate(File jarFile, File signedjarFile) {
+ if (isForce() || null == jarFile || !jarFile.exists()) {
+ //these are pathological cases, but retained in case somebody
+ //subclassed us.
+ return false;
+ }
+
+ //we normally compare destination with source
+ File destFile = signedjarFile;
+ if (destFile == null) {
+ //but if no dest is specified, compare source to source
+ destFile = jarFile;
+ }
+
+ //if, by any means, the destfile and source match,
+ if (jarFile.equals(destFile)) {
+ if (lazy) {
+ //we check the presence of signatures on lazy signing
+ return isSigned(jarFile);
+ }
+ //unsigned or non-lazy self signings are always false
+ return false;
+ }
+
+ //if they are different, the timestamps are used
+ return FILE_UTILS.isUpToDate(jarFile, destFile);
+ }
+
+ /**
+ * test for a file being signed, by looking for a signature in the META-INF
+ * directory with our alias/sigfile.
+ *
+ * @param file the file to be checked
+ * @return true if the file is signed
+ * @see IsSigned#isSigned(File, String)
+ */
+ protected boolean isSigned(File file) {
+ try {
+ return IsSigned.isSigned(file, sigfile == null ? alias : sigfile);
+ } catch (IOException e) {
+ //just log this
+ log(e.toString(), Project.MSG_VERBOSE);
+ return false;
+ }
+ }
+
+ /**
+ * true to indicate that the signed jar modification date remains the same
+ * as the original. Defaults to false
+ *
+ * @param preserveLastModified if true preserve the last modified time
+ */
+ public void setPreserveLastModified(boolean preserveLastModified) {
+ this.preserveLastModified = preserveLastModified;
+ }
+
+ private void addProxyFor(final ExecTask cmd, final String scheme) {
+ addValue(cmd, "-J-D" + scheme + ".proxyHost=" + tsaproxyhost);
+
+ if (tsaproxyport != null) {
+ addValue(cmd, "-J-D" + scheme + ".proxyPort=" + tsaproxyport);
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Sleep.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Sleep.java
new file mode 100644
index 00000000..6468c390
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Sleep.java
@@ -0,0 +1,194 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+
+/**
+ * Sleep, or pause, for a period of time.
+ *
+ * <p>A task for sleeping a short period of time, useful when a
+ * build or deployment process requires an interval between tasks.</p>
+ *
+ * <p>A negative value can be supplied to any of attributes provided the total sleep time
+ * is positive, pending fundamental changes in physics and JVM
+ * execution times</p>
+ *
+ * <p>Note that sleep times are always hints to be interpreted by the OS how it feels
+ * small times may either be ignored or rounded up to a minimum timeslice. Note
+ * also that the system clocks often have a fairly low granularity too, which complicates
+ * measuring how long a sleep actually took.</p>
+ *
+ * @since Ant 1.4
+ * @ant.task category="utility"
+ */
+public class Sleep extends Task {
+ /**
+ * failure flag
+ */
+ private boolean failOnError = true;
+
+ /**
+ * sleep seconds
+ */
+ private int seconds = 0;
+
+ /**
+ * sleep hours
+ */
+ private int hours = 0;
+ /**
+ * sleep minutes
+ */
+ private int minutes = 0;
+
+ /**
+ * sleep milliseconds
+ */
+ private int milliseconds = 0;
+
+
+
+ /**
+ * Creates new instance
+ */
+ public Sleep() {
+ }
+
+
+ /**
+ * seconds to add to the sleep time
+ *
+ * @param seconds The new Seconds value
+ */
+ public void setSeconds(int seconds) {
+ this.seconds = seconds;
+ }
+
+
+ /**
+ * hours to add to the sleep time.
+ *
+ * @param hours The new Hours value
+ */
+ public void setHours(int hours) {
+ this.hours = hours;
+ }
+
+
+ /**
+ * minutes to add to the sleep time
+ *
+ * @param minutes The new Minutes value
+ */
+ public void setMinutes(int minutes) {
+ this.minutes = minutes;
+ }
+
+
+ /**
+ * milliseconds to add to the sleep time
+ *
+ * @param milliseconds The new Milliseconds value
+ */
+ public void setMilliseconds(int milliseconds) {
+ this.milliseconds = milliseconds;
+ }
+
+
+ /**
+ * sleep for a period of time
+ *
+ * @param millis time to sleep
+ */
+ public void doSleep(long millis) {
+ try {
+ Thread.sleep(millis);
+ } catch (InterruptedException ie) {
+ // Ignore Exception
+ }
+ }
+
+
+ /**
+ * flag controlling whether to break the build on an error.
+ *
+ * @param failOnError The new FailOnError value
+ */
+ public void setFailOnError(boolean failOnError) {
+ this.failOnError = failOnError;
+ }
+
+
+ /**
+ * return time to sleep
+ *
+ * @return sleep time. if below 0 then there is an error
+ */
+
+ private long getSleepTime() {
+ // CheckStyle:MagicNumber OFF
+ return ((((long) hours * 60) + minutes) * 60 + seconds) * 1000
+ + milliseconds;
+ // CheckStyle:MagicNumber ON
+ }
+
+
+ /**
+ * verify parameters
+ *
+ * @throws BuildException if something is invalid
+ */
+ public void validate()
+ throws BuildException {
+ if (getSleepTime() < 0) {
+ throw new BuildException("Negative sleep periods are not "
+ + "supported");
+ }
+ }
+
+
+ /**
+ * Executes this build task. Throws org.apache.tools.ant.BuildException
+ * if there is an error during task execution.
+ *
+ * @exception BuildException Description of Exception
+ */
+ @Override
+ public void execute()
+ throws BuildException {
+ try {
+ validate();
+ long sleepTime = getSleepTime();
+ log("sleeping for " + sleepTime + " milliseconds",
+ Project.MSG_VERBOSE);
+ doSleep(sleepTime);
+ } catch (Exception e) {
+ if (failOnError) {
+ throw new BuildException(e);
+ } else {
+ String text = e.toString();
+ log(text, Project.MSG_ERR);
+ }
+ }
+ }
+
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/StreamPumper.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/StreamPumper.java
new file mode 100644
index 00000000..df95eedb
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/StreamPumper.java
@@ -0,0 +1,252 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.apache.tools.ant.util.FileUtils;
+
+/**
+ * Copies all data from an input stream to an output stream.
+ *
+ * @since Ant 1.2
+ */
+public class StreamPumper implements Runnable {
+
+ private static final int SMALL_BUFFER_SIZE = 128;
+
+ private final InputStream is;
+ private final OutputStream os;
+ private volatile boolean finish;
+ private volatile boolean finished;
+ private final boolean closeWhenExhausted;
+ private boolean autoflush = false;
+ private Exception exception = null;
+ private int bufferSize = SMALL_BUFFER_SIZE;
+ private boolean started = false;
+ private final boolean useAvailable;
+
+ /**
+ * Create a new StreamPumper.
+ *
+ * @param is input stream to read data from
+ * @param os output stream to write data to.
+ * @param closeWhenExhausted if true, the output stream will be closed when
+ * the input is exhausted.
+ */
+ public StreamPumper(InputStream is, OutputStream os, boolean closeWhenExhausted) {
+ this(is, os, closeWhenExhausted, false);
+ }
+
+
+ /**
+ * Create a new StreamPumper.
+ *
+ * <p><b>Note:</b> If you set useAvailable to true, you must
+ * explicitly invoke {@link #stop stop} or interrupt the
+ * corresponding Thread when you are done or the run method will
+ * never finish on some JVMs (namely those where available returns
+ * 0 on a closed stream). Setting it to true may also impact
+ * performance negatively. This flag should only be set to true
+ * if you intend to stop the pumper before the input stream gets
+ * closed.</p>
+ *
+ * @param is input stream to read data from
+ * @param os output stream to write data to.
+ * @param closeWhenExhausted if true, the output stream will be closed when
+ * the input is exhausted.
+ * @param useAvailable whether the pumper should use {@link
+ * java.io.InputStream#available available} to determine
+ * whether input is ready, thus trying to emulate
+ * non-blocking behavior.
+ *
+ * @since Ant 1.8.0
+ */
+ public StreamPumper(InputStream is, OutputStream os,
+ boolean closeWhenExhausted,
+ boolean useAvailable) {
+ this.is = is;
+ this.os = os;
+ this.closeWhenExhausted = closeWhenExhausted;
+ this.useAvailable = useAvailable;
+ }
+
+ /**
+ * Create a new StreamPumper.
+ *
+ * @param is input stream to read data from
+ * @param os output stream to write data to.
+ */
+ public StreamPumper(InputStream is, OutputStream os) {
+ this(is, os, false);
+ }
+
+ /**
+ * Set whether data should be flushed through to the output stream.
+ * @param autoflush if true, push through data; if false, let it be buffered
+ * @since Ant 1.6.3
+ */
+ /*package*/ void setAutoflush(boolean autoflush) {
+ this.autoflush = autoflush;
+ }
+
+ /**
+ * Copies data from the input stream to the output stream.
+ *
+ * Terminates as soon as the input stream is closed or an error occurs.
+ */
+ public void run() {
+ synchronized (this) {
+ started = true;
+ }
+ finished = false;
+
+ final byte[] buf = new byte[bufferSize];
+
+ int length;
+ try {
+ while (true) {
+ waitForInput(is);
+
+ if (finish || Thread.interrupted()) {
+ break;
+ }
+
+ length = is.read(buf);
+ if (length <= 0 || Thread.interrupted()) {
+ break;
+ }
+ os.write(buf, 0, length);
+ if (autoflush) {
+ os.flush();
+ }
+ if (finish) {
+ break;
+ }
+ }
+ // On completion, drain any available data (which might be the first data available for quick executions)
+ if (finish) {
+ while((length = is.available()) > 0) {
+ if (Thread.interrupted()) {
+ break;
+ }
+ length = is.read(buf, 0, Math.min(length, buf.length));
+ if (length <= 0) {
+ break;
+ }
+ os.write(buf, 0, length);
+ }
+ }
+ os.flush();
+ } catch (InterruptedException ie) {
+ // likely PumpStreamHandler trying to stop us
+ } catch (Exception e) {
+ synchronized (this) {
+ exception = e;
+ }
+ } finally {
+ if (closeWhenExhausted) {
+ FileUtils.close(os);
+ }
+ finished = true;
+ finish = false;
+ synchronized (this) {
+ notifyAll();
+ }
+ }
+ }
+
+ /**
+ * Tells whether the end of the stream has been reached.
+ * @return true is the stream has been exhausted.
+ */
+ public boolean isFinished() {
+ return finished;
+ }
+
+ /**
+ * This method blocks until the StreamPumper finishes.
+ * @throws InterruptedException if interrupted.
+ * @see #isFinished()
+ */
+ public synchronized void waitFor() throws InterruptedException {
+ while (!isFinished()) {
+ wait();
+ }
+ }
+
+ /**
+ * Set the size in bytes of the read buffer.
+ * @param bufferSize the buffer size to use.
+ * @throws IllegalStateException if the StreamPumper is already running.
+ */
+ public synchronized void setBufferSize(int bufferSize) {
+ if (started) {
+ throw new IllegalStateException("Cannot set buffer size on a running StreamPumper");
+ }
+ this.bufferSize = bufferSize;
+ }
+
+ /**
+ * Get the size in bytes of the read buffer.
+ * @return the int size of the read buffer.
+ */
+ public synchronized int getBufferSize() {
+ return bufferSize;
+ }
+
+ /**
+ * Get the exception encountered, if any.
+ * @return the Exception encountered.
+ */
+ public synchronized Exception getException() {
+ return exception;
+ }
+
+ /**
+ * Stop the pumper as soon as possible.
+ * Note that it may continue to block on the input stream
+ * but it will really stop the thread as soon as it gets EOF
+ * or any byte, and it will be marked as finished.
+ * @since Ant 1.6.3
+ */
+ /*package*/ synchronized void stop() {
+ finish = true;
+ notifyAll();
+ }
+
+ private static final long POLL_INTERVAL = 100;
+
+ private void waitForInput(InputStream is)
+ throws IOException, InterruptedException {
+ if (useAvailable) {
+ while (!finish && is.available() == 0) {
+ if (Thread.interrupted()) {
+ throw new InterruptedException();
+ }
+
+ synchronized (this) {
+ this.wait(POLL_INTERVAL);
+ }
+ }
+ }
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/SubAnt.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/SubAnt.java
new file mode 100644
index 00000000..35109faa
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/SubAnt.java
@@ -0,0 +1,642 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Main;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.taskdefs.Ant.TargetElement;
+import org.apache.tools.ant.types.DirSet;
+import org.apache.tools.ant.types.FileList;
+import org.apache.tools.ant.types.FileSet;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.types.PropertySet;
+import org.apache.tools.ant.types.Reference;
+import org.apache.tools.ant.types.ResourceCollection;
+
+
+/**
+ * Calls a given target for all defined sub-builds. This is an extension
+ * of ant for bulk project execution.
+ * <p>
+ * <h2> Use with directories </h2>
+ * <p>
+ * subant can be used with directory sets to execute a build from different directories.
+ * 2 different options are offered
+ * </p>
+ * <ul>
+ * <li>
+ * run the same build file /somepath/otherpath/mybuild.xml
+ * with different base directories use the genericantfile attribute
+ * </li>
+ * <li>if you want to run directory1/build.xml, directory2/build.xml, ....
+ * use the antfile attribute. The base directory does not get set by the subant task in this case,
+ * because you can specify it in each build file.
+ * </li>
+ * </ul>
+ * @since Ant1.6
+ * @ant.task name="subant" category="control"
+ */
+public class SubAnt extends Task {
+
+ private Path buildpath;
+
+ private Ant ant = null;
+ private String subTarget = null;
+ private String antfile = getDefaultBuildFile();
+ private File genericantfile = null;
+ private boolean verbose = false;
+ private boolean inheritAll = false;
+ private boolean inheritRefs = false;
+ private boolean failOnError = true;
+ private String output = null;
+
+ private Vector properties = new Vector();
+ private Vector references = new Vector();
+ private Vector propertySets = new Vector();
+
+ /** the targets to call on the new project */
+ private Vector/*<TargetElement>*/ targets = new Vector();
+
+ /**
+ * Get the default build file name to use when launching the task.
+ * <p>
+ * This function may be overrided by providers of custom ProjectHelper so they can implement easily their sub
+ * launcher.
+ *
+ * @return the name of the default file
+ * @since Ant 1.8.0
+ */
+ protected String getDefaultBuildFile() {
+ return Main.DEFAULT_BUILD_FILENAME;
+ }
+
+ /**
+ * Pass output sent to System.out to the new project.
+ *
+ * @param output a line of output
+ * @since Ant 1.6.2
+ */
+ @Override
+ public void handleOutput(String output) {
+ if (ant != null) {
+ ant.handleOutput(output);
+ } else {
+ super.handleOutput(output);
+ }
+ }
+
+ /**
+ * Process input into the ant task
+ *
+ * @param buffer the buffer into which data is to be read.
+ * @param offset the offset into the buffer at which data is stored.
+ * @param length the amount of data to read
+ *
+ * @return the number of bytes read
+ *
+ * @exception IOException if the data cannot be read
+ *
+ * @see Task#handleInput(byte[], int, int)
+ *
+ * @since Ant 1.6.2
+ */
+ @Override
+ public int handleInput(byte[] buffer, int offset, int length)
+ throws IOException {
+ if (ant != null) {
+ return ant.handleInput(buffer, offset, length);
+ } else {
+ return super.handleInput(buffer, offset, length);
+ }
+ }
+
+ /**
+ * Pass output sent to System.out to the new project.
+ *
+ * @param output The output to log. Should not be <code>null</code>.
+ *
+ * @since Ant 1.6.2
+ */
+ @Override
+ public void handleFlush(String output) {
+ if (ant != null) {
+ ant.handleFlush(output);
+ } else {
+ super.handleFlush(output);
+ }
+ }
+
+ /**
+ * Pass output sent to System.err to the new project.
+ *
+ * @param output The error output to log. Should not be <code>null</code>.
+ *
+ * @since Ant 1.6.2
+ */
+ @Override
+ public void handleErrorOutput(String output) {
+ if (ant != null) {
+ ant.handleErrorOutput(output);
+ } else {
+ super.handleErrorOutput(output);
+ }
+ }
+
+ /**
+ * Pass output sent to System.err to the new project.
+ *
+ * @param output The error output to log. Should not be <code>null</code>.
+ *
+ * @since Ant 1.6.2
+ */
+ @Override
+ public void handleErrorFlush(String output) {
+ if (ant != null) {
+ ant.handleErrorFlush(output);
+ } else {
+ super.handleErrorFlush(output);
+ }
+ }
+
+ /**
+ * Runs the various sub-builds.
+ */
+ @Override
+ public void execute() {
+ if (buildpath == null) {
+ throw new BuildException("No buildpath specified");
+ }
+
+ final String[] filenames = buildpath.list();
+ final int count = filenames.length;
+ if (count < 1) {
+ log("No sub-builds to iterate on", Project.MSG_WARN);
+ return;
+ }
+/*
+ //REVISIT: there must be cleaner way of doing this, if it is merited at all
+ if (subTarget == null) {
+ subTarget = getOwningTarget().getName();
+ }
+*/
+ BuildException buildException = null;
+ for (int i = 0; i < count; ++i) {
+ File file = null;
+ String subdirPath = null;
+ Throwable thrownException = null;
+ try {
+ File directory = null;
+ file = new File(filenames[i]);
+ if (file.isDirectory()) {
+ if (verbose) {
+ subdirPath = file.getPath();
+ log("Entering directory: " + subdirPath + "\n", Project.MSG_INFO);
+ }
+ if (genericantfile != null) {
+ directory = file;
+ file = genericantfile;
+ } else {
+ file = new File(file, antfile);
+ }
+ }
+ execute(file, directory);
+ if (verbose && subdirPath != null) {
+ log("Leaving directory: " + subdirPath + "\n", Project.MSG_INFO);
+ }
+ } catch (RuntimeException ex) {
+ if (!(getProject().isKeepGoingMode())) {
+ if (verbose && subdirPath != null) {
+ log("Leaving directory: " + subdirPath + "\n", Project.MSG_INFO);
+ }
+ throw ex; // throw further
+ }
+ thrownException = ex;
+ } catch (Throwable ex) {
+ if (!(getProject().isKeepGoingMode())) {
+ if (verbose && subdirPath != null) {
+ log("Leaving directory: " + subdirPath + "\n", Project.MSG_INFO);
+ }
+ throw new BuildException(ex);
+ }
+ thrownException = ex;
+ }
+ if (thrownException != null) {
+ if (thrownException instanceof BuildException) {
+ log("File '" + file
+ + "' failed with message '"
+ + thrownException.getMessage() + "'.", Project.MSG_ERR);
+ // only the first build exception is reported
+ if (buildException == null) {
+ buildException = (BuildException) thrownException;
+ }
+ } else {
+ log("Target '" + file
+ + "' failed with message '"
+ + thrownException.getMessage() + "'.", Project.MSG_ERR);
+ thrownException.printStackTrace(System.err);
+ if (buildException == null) {
+ buildException =
+ new BuildException(thrownException);
+ }
+ }
+ if (verbose && subdirPath != null) {
+ log("Leaving directory: " + subdirPath + "\n", Project.MSG_INFO);
+ }
+ }
+ }
+ // check if one of the builds failed in keep going mode
+ if (buildException != null) {
+ throw buildException;
+ }
+ }
+
+ /**
+ * Runs the given target on the provided build file.
+ *
+ * @param file the build file to execute
+ * @param directory the directory of the current iteration
+ * @throws BuildException is the file cannot be found, read, is
+ * a directory, or the target called failed, but only if
+ * <code>failOnError</code> is <code>true</code>. Otherwise,
+ * a warning log message is simply output.
+ */
+ private void execute(File file, File directory)
+ throws BuildException {
+ if (!file.exists() || file.isDirectory() || !file.canRead()) {
+ String msg = "Invalid file: " + file;
+ if (failOnError) {
+ throw new BuildException(msg);
+ }
+ log(msg, Project.MSG_WARN);
+ return;
+ }
+
+ ant = createAntTask(directory);
+ String antfilename = file.getAbsolutePath();
+ ant.setAntfile(antfilename);
+ final int size = targets.size();
+ for (int i = 0; i < size; i++) {
+ TargetElement targetElement = (TargetElement) targets.get(i);
+ ant.addConfiguredTarget(targetElement);
+ }
+
+ try {
+ if (verbose) {
+ log("Executing: " + antfilename, Project.MSG_INFO);
+ }
+ ant.execute();
+ } catch (BuildException e) {
+ if (failOnError || isHardError(e)) {
+ throw e;
+ }
+ log("Failure for target '" + subTarget
+ + "' of: " + antfilename + "\n"
+ + e.getMessage(), Project.MSG_WARN);
+ } catch (Throwable e) {
+ if (failOnError || isHardError(e)) {
+ throw new BuildException(e);
+ }
+ log("Failure for target '" + subTarget
+ + "' of: " + antfilename + "\n"
+ + e.toString(),
+ Project.MSG_WARN);
+ } finally {
+ ant = null;
+ }
+ }
+
+ /** whether we should even try to continue after this error */
+ private boolean isHardError(Throwable t) {
+ if (t instanceof BuildException) {
+ return isHardError(t.getCause());
+ } else if (t instanceof OutOfMemoryError) {
+ return true;
+ } else if (t instanceof ThreadDeath) {
+ return true;
+ } else { // incl. t == null
+ return false;
+ }
+ }
+
+ /**
+ * This method builds the file name to use in conjunction with directories.
+ *
+ * <p>Defaults to "build.xml".
+ * If <code>genericantfile</code> is set, this attribute is ignored.</p>
+ *
+ * @param antfile the short build file name. Defaults to "build.xml".
+ */
+ public void setAntfile(String antfile) {
+ this.antfile = antfile;
+ }
+
+ /**
+ * This method builds a file path to use in conjunction with directories.
+ *
+ * <p>Use <code>genericantfile</code>, in order to run the same build file
+ * with different basedirs.</p>
+ * If this attribute is set, <code>antfile</code> is ignored.
+ *
+ * @param afile (path of the generic ant file, absolute or relative to
+ * project base directory)
+ * */
+ public void setGenericAntfile(File afile) {
+ this.genericantfile = afile;
+ }
+
+ /**
+ * Sets whether to fail with a build exception on error, or go on.
+ *
+ * @param failOnError the new value for this boolean flag.
+ */
+ public void setFailonerror(boolean failOnError) {
+ this.failOnError = failOnError;
+ }
+
+ /**
+ * The target to call on the different sub-builds. Set to "" to execute
+ * the default target.
+ * @param target the target
+ * <p>
+ */
+ // REVISIT: Defaults to the target name that contains this task if not specified.
+ public void setTarget(String target) {
+ this.subTarget = target;
+ }
+
+ /**
+ * Add a target to this Ant invocation.
+ * @param t the <code>TargetElement</code> to add.
+ * @since Ant 1.7
+ */
+ public void addConfiguredTarget(TargetElement t) {
+ String name = t.getName();
+ if ("".equals(name)) {
+ throw new BuildException("target name must not be empty");
+ }
+ targets.add(t);
+ }
+
+ /**
+ * Enable/ disable verbose log messages showing when each sub-build path is entered/ exited.
+ * The default value is "false".
+ * @param on true to enable verbose mode, false otherwise (default).
+ */
+ public void setVerbose(boolean on) {
+ this.verbose = on;
+ }
+
+ /**
+ * Corresponds to <code>&lt;ant&gt;</code>'s
+ * <code>output</code> attribute.
+ *
+ * @param s the filename to write the output to.
+ */
+ public void setOutput(String s) {
+ this.output = s;
+ }
+
+ /**
+ * Corresponds to <code>&lt;ant&gt;</code>'s
+ * <code>inheritall</code> attribute.
+ *
+ * @param b the new value for this boolean flag.
+ */
+ public void setInheritall(boolean b) {
+ this.inheritAll = b;
+ }
+
+ /**
+ * Corresponds to <code>&lt;ant&gt;</code>'s
+ * <code>inheritrefs</code> attribute.
+ *
+ * @param b the new value for this boolean flag.
+ */
+ public void setInheritrefs(boolean b) {
+ this.inheritRefs = b;
+ }
+
+ /**
+ * Corresponds to <code>&lt;ant&gt;</code>'s
+ * nested <code>&lt;property&gt;</code> element.
+ *
+ * @param p the property to pass on explicitly to the sub-build.
+ */
+ public void addProperty(Property p) {
+ properties.addElement(p);
+ }
+
+ /**
+ * Corresponds to <code>&lt;ant&gt;</code>'s
+ * nested <code>&lt;reference&gt;</code> element.
+ *
+ * @param r the reference to pass on explicitly to the sub-build.
+ */
+ public void addReference(Ant.Reference r) {
+ references.addElement(r);
+ }
+
+ /**
+ * Corresponds to <code>&lt;ant&gt;</code>'s
+ * nested <code>&lt;propertyset&gt;</code> element.
+ * @param ps the propertyset
+ */
+ public void addPropertyset(PropertySet ps) {
+ propertySets.addElement(ps);
+ }
+
+ /**
+ * Adds a directory set to the implicit build path.
+ * <p>
+ * <em>Note that the directories will be added to the build path
+ * in no particular order, so if order is significant, one should
+ * use a file list instead!</em>
+ *
+ * @param set the directory set to add.
+ */
+ public void addDirset(DirSet set) {
+ add(set);
+ }
+
+ /**
+ * Adds a file set to the implicit build path.
+ * <p>
+ * <em>Note that the directories will be added to the build path
+ * in no particular order, so if order is significant, one should
+ * use a file list instead!</em>
+ *
+ * @param set the file set to add.
+ */
+ public void addFileset(FileSet set) {
+ add(set);
+ }
+
+ /**
+ * Adds an ordered file list to the implicit build path.
+ * <p>
+ * <em>Note that contrary to file and directory sets, file lists
+ * can reference non-existent files or directories!</em>
+ *
+ * @param list the file list to add.
+ */
+ public void addFilelist(FileList list) {
+ add(list);
+ }
+
+ /**
+ * Adds a resource collection to the implicit build path.
+ *
+ * @param rc the resource collection to add.
+ * @since Ant 1.7
+ */
+ public void add(ResourceCollection rc) {
+ getBuildpath().add(rc);
+ }
+
+ /**
+ * Set the buildpath to be used to find sub-projects.
+ *
+ * @param s an Ant Path object containing the buildpath.
+ */
+ public void setBuildpath(Path s) {
+ getBuildpath().append(s);
+ }
+
+ /**
+ * Creates a nested build path, and add it to the implicit build path.
+ *
+ * @return the newly created nested build path.
+ */
+ public Path createBuildpath() {
+ return getBuildpath().createPath();
+ }
+
+ /**
+ * Creates a nested <code>&lt;buildpathelement&gt;</code>,
+ * and add it to the implicit build path.
+ *
+ * @return the newly created nested build path element.
+ */
+ public Path.PathElement createBuildpathElement() {
+ return getBuildpath().createPathElement();
+ }
+
+ /**
+ * Gets the implicit build path, creating it if <code>null</code>.
+ *
+ * @return the implicit build path.
+ */
+ private Path getBuildpath() {
+ if (buildpath == null) {
+ buildpath = new Path(getProject());
+ }
+ return buildpath;
+ }
+
+ /**
+ * Buildpath to use, by reference.
+ *
+ * @param r a reference to an Ant Path object containing the buildpath.
+ */
+ public void setBuildpathRef(Reference r) {
+ createBuildpath().setRefid(r);
+ }
+
+ /**
+ * Creates the &lt;ant&gt; task configured to run a specific target.
+ *
+ * @param directory : if not null the directory where the build should run
+ *
+ * @return the ant task, configured with the explicit properties and
+ * references necessary to run the sub-build.
+ */
+ private Ant createAntTask(File directory) {
+ Ant antTask = new Ant(this);
+ antTask.init();
+ if (subTarget != null && subTarget.length() > 0) {
+ antTask.setTarget(subTarget);
+ }
+
+
+ if (output != null) {
+ antTask.setOutput(output);
+ }
+
+ if (directory != null) {
+ antTask.setDir(directory);
+ } else {
+ antTask.setUseNativeBasedir(true);
+ }
+
+ antTask.setInheritAll(inheritAll);
+ for (Enumeration i = properties.elements(); i.hasMoreElements();) {
+ copyProperty(antTask.createProperty(), (Property) i.nextElement());
+ }
+
+ for (Enumeration i = propertySets.elements(); i.hasMoreElements();) {
+ antTask.addPropertyset((PropertySet) i.nextElement());
+ }
+
+ antTask.setInheritRefs(inheritRefs);
+ for (Enumeration i = references.elements(); i.hasMoreElements();) {
+ antTask.addReference((Ant.Reference) i.nextElement());
+ }
+
+ return antTask;
+ }
+
+ /**
+ * Assigns an Ant property to another.
+ *
+ * @param to the destination property whose content is modified.
+ * @param from the source property whose content is copied.
+ */
+ private static void copyProperty(Property to, Property from) {
+ to.setName(from.getName());
+
+ if (from.getValue() != null) {
+ to.setValue(from.getValue());
+ }
+ if (from.getFile() != null) {
+ to.setFile(from.getFile());
+ }
+ if (from.getResource() != null) {
+ to.setResource(from.getResource());
+ }
+ if (from.getPrefix() != null) {
+ to.setPrefix(from.getPrefix());
+ }
+ if (from.getRefid() != null) {
+ to.setRefid(from.getRefid());
+ }
+ if (from.getEnvironment() != null) {
+ to.setEnvironment(from.getEnvironment());
+ }
+ if (from.getClasspath() != null) {
+ to.setClasspath(from.getClasspath());
+ }
+ }
+
+} // END class SubAnt
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Sync.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Sync.java
new file mode 100644
index 00000000..c1c75529
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Sync.java
@@ -0,0 +1,606 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.io.File;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.DirectoryScanner;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.types.AbstractFileSet;
+import org.apache.tools.ant.types.FileSet;
+import org.apache.tools.ant.types.PatternSet;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.ResourceCollection;
+import org.apache.tools.ant.types.resources.Resources;
+import org.apache.tools.ant.types.resources.Restrict;
+import org.apache.tools.ant.types.resources.selectors.Exists;
+import org.apache.tools.ant.types.selectors.FileSelector;
+import org.apache.tools.ant.types.selectors.NoneSelector;
+
+/**
+ * Synchronize a local target directory from the files defined
+ * in one or more filesets.
+ *
+ * <p>Uses a &lt;copy&gt; task internally, but forbidding the use of
+ * mappers and filter chains. Files of the destination directory not
+ * present in any of the source fileset are removed.</p>
+ *
+ * @since Ant 1.6
+ *
+ * revised by <a href="mailto:daniel.armbrust@mayo.edu">Dan Armbrust</a>
+ * to remove orphaned directories.
+ *
+ * @ant.task category="filesystem"
+ */
+public class Sync extends Task {
+
+ // Same as regular <copy> task... see at end-of-file!
+ private MyCopy myCopy;
+
+ // Similar to a fileset, but doesn't allow dir attribute to be set
+ private SyncTarget syncTarget;
+
+ private Resources resources = null;
+
+ // Override Task#init
+ /**
+ * Initialize the sync task.
+ * @throws BuildException if there is a problem.
+ * @see Task#init()
+ */
+ @Override
+ public void init()
+ throws BuildException {
+ // Instantiate it
+ myCopy = new MyCopy();
+ configureTask(myCopy);
+
+ // Default config of <mycopy> for our purposes.
+ myCopy.setFiltering(false);
+ myCopy.setIncludeEmptyDirs(false);
+ myCopy.setPreserveLastModified(true);
+ }
+
+ private void configureTask(Task helper) {
+ helper.setProject(getProject());
+ helper.setTaskName(getTaskName());
+ helper.setOwningTarget(getOwningTarget());
+ helper.init();
+ }
+
+ // Override Task#execute
+ /**
+ * Execute the sync task.
+ * @throws BuildException if there is an error.
+ * @see Task#execute()
+ */
+ @Override
+ public void execute()
+ throws BuildException {
+ // The destination of the files to copy
+ File toDir = myCopy.getToDir();
+
+ // The complete list of files to copy
+ Set allFiles = myCopy.nonOrphans;
+
+ // If the destination directory didn't already exist,
+ // or was empty, then no previous file removal is necessary!
+ boolean noRemovalNecessary = !toDir.exists() || toDir.list().length < 1;
+
+ // Copy all the necessary out-of-date files
+ log("PASS#1: Copying files to " + toDir, Project.MSG_DEBUG);
+ myCopy.execute();
+
+ // Do we need to perform further processing?
+ if (noRemovalNecessary) {
+ log("NO removing necessary in " + toDir, Project.MSG_DEBUG);
+ return; // nope ;-)
+ }
+
+ // will hold the directories matched by SyncTarget in reversed
+ // lexicographic order (order is important, that's why we use
+ // a LinkedHashSet
+ Set preservedDirectories = new LinkedHashSet();
+
+ // Get rid of all files not listed in the source filesets.
+ log("PASS#2: Removing orphan files from " + toDir, Project.MSG_DEBUG);
+ int[] removedFileCount = removeOrphanFiles(allFiles, toDir,
+ preservedDirectories);
+ logRemovedCount(removedFileCount[0], "dangling director", "y", "ies");
+ logRemovedCount(removedFileCount[1], "dangling file", "", "s");
+
+ // Get rid of empty directories on the destination side
+ if (!myCopy.getIncludeEmptyDirs()
+ || getExplicitPreserveEmptyDirs() == Boolean.FALSE) {
+ log("PASS#3: Removing empty directories from " + toDir,
+ Project.MSG_DEBUG);
+
+ int removedDirCount = 0;
+ if (!myCopy.getIncludeEmptyDirs()) {
+ removedDirCount =
+ removeEmptyDirectories(toDir, false, preservedDirectories);
+ } else { // must be syncTarget.preserveEmptydirs == FALSE
+ removedDirCount =
+ removeEmptyDirectories(preservedDirectories);
+ }
+ logRemovedCount(removedDirCount, "empty director", "y", "ies");
+ }
+ }
+
+ private void logRemovedCount(int count, String prefix,
+ String singularSuffix, String pluralSuffix) {
+ File toDir = myCopy.getToDir();
+
+ String what = (prefix == null) ? "" : prefix;
+ what += (count < 2) ? singularSuffix : pluralSuffix;
+
+ if (count > 0) {
+ log("Removed " + count + " " + what + " from " + toDir,
+ Project.MSG_INFO);
+ } else {
+ log("NO " + what + " to remove from " + toDir,
+ Project.MSG_VERBOSE);
+ }
+ }
+
+ /**
+ * Removes all files and folders not found as keys of a table
+ * (used as a set!).
+ *
+ * <p>If the provided file is a directory, it is recursively
+ * scanned for orphaned files which will be removed as well.</p>
+ *
+ * <p>If the directory is an orphan, it will also be removed.</p>
+ *
+ * @param nonOrphans the table of all non-orphan <code>File</code>s.
+ * @param file the initial file or directory to scan or test.
+ * @param preservedDirectories will be filled with the directories
+ * matched by preserveInTarget - if any. Will not be
+ * filled unless preserveEmptyDirs and includeEmptyDirs
+ * conflict.
+ * @return the number of orphaned files and directories actually removed.
+ * Position 0 of the array is the number of orphaned directories.
+ * Position 1 of the array is the number or orphaned files.
+ */
+ private int[] removeOrphanFiles(Set nonOrphans, File toDir,
+ Set preservedDirectories) {
+ int[] removedCount = new int[] {0, 0};
+ String[] excls =
+ (String[]) nonOrphans.toArray(new String[nonOrphans.size() + 1]);
+ // want to keep toDir itself
+ excls[nonOrphans.size()] = "";
+
+ DirectoryScanner ds = null;
+ if (syncTarget != null) {
+ FileSet fs = syncTarget.toFileSet(false);
+ fs.setDir(toDir);
+
+ // preserveInTarget would find all files we want to keep,
+ // but we need to find all that we want to delete - so the
+ // meaning of all patterns and selectors must be inverted
+ PatternSet ps = syncTarget.mergePatterns(getProject());
+ fs.appendExcludes(ps.getIncludePatterns(getProject()));
+ fs.appendIncludes(ps.getExcludePatterns(getProject()));
+ fs.setDefaultexcludes(!syncTarget.getDefaultexcludes());
+
+ // selectors are implicitly ANDed in DirectoryScanner. To
+ // revert their logic we wrap them into a <none> selector
+ // instead.
+ FileSelector[] s = syncTarget.getSelectors(getProject());
+ if (s.length > 0) {
+ NoneSelector ns = new NoneSelector();
+ for (int i = 0; i < s.length; i++) {
+ ns.appendSelector(s[i]);
+ }
+ fs.appendSelector(ns);
+ }
+ ds = fs.getDirectoryScanner(getProject());
+ } else {
+ ds = new DirectoryScanner();
+ ds.setBasedir(toDir);
+ }
+ ds.addExcludes(excls);
+
+ ds.scan();
+ String[] files = ds.getIncludedFiles();
+ for (int i = 0; i < files.length; i++) {
+ File f = new File(toDir, files[i]);
+ log("Removing orphan file: " + f, Project.MSG_DEBUG);
+ f.delete();
+ ++removedCount[1];
+ }
+ String[] dirs = ds.getIncludedDirectories();
+ // ds returns the directories in lexicographic order.
+ // iterating through the array backwards means we are deleting
+ // leaves before their parent nodes - thus making sure (well,
+ // more likely) that the directories are empty when we try to
+ // delete them.
+ for (int i = dirs.length - 1; i >= 0; --i) {
+ File f = new File(toDir, dirs[i]);
+ String[] children = f.list();
+ if (children == null || children.length < 1) {
+ log("Removing orphan directory: " + f, Project.MSG_DEBUG);
+ f.delete();
+ ++removedCount[0];
+ }
+ }
+
+ Boolean ped = getExplicitPreserveEmptyDirs();
+ if (ped != null && ped.booleanValue() != myCopy.getIncludeEmptyDirs()) {
+ FileSet fs = syncTarget.toFileSet(true);
+ fs.setDir(toDir);
+ String[] preservedDirs =
+ fs.getDirectoryScanner(getProject()).getIncludedDirectories();
+ for (int i = preservedDirs.length - 1; i >= 0; --i) {
+ preservedDirectories.add(new File(toDir, preservedDirs[i]));
+ }
+ }
+
+ return removedCount;
+ }
+
+ /**
+ * Removes all empty directories from a directory.
+ *
+ * <p><em>Note that a directory that contains only empty
+ * directories, directly or not, will be removed!</em></p>
+ *
+ * <p>Recurses depth-first to find the leaf directories
+ * which are empty and removes them, then unwinds the
+ * recursion stack, removing directories which have
+ * become empty themselves, etc...</p>
+ *
+ * @param dir the root directory to scan for empty directories.
+ * @param removeIfEmpty whether to remove the root directory
+ * itself if it becomes empty.
+ * @param preservedEmptyDirectories directories matched by
+ * syncTarget
+ * @return the number of empty directories actually removed.
+ */
+ private int removeEmptyDirectories(File dir, boolean removeIfEmpty,
+ Set preservedEmptyDirectories) {
+ int removedCount = 0;
+ if (dir.isDirectory()) {
+ File[] children = dir.listFiles();
+ for (int i = 0; i < children.length; ++i) {
+ File file = children[i];
+ // Test here again to avoid method call for non-directories!
+ if (file.isDirectory()) {
+ removedCount +=
+ removeEmptyDirectories(file, true,
+ preservedEmptyDirectories);
+ }
+ }
+ if (children.length > 0) {
+ // This directory may have become empty...
+ // We need to re-query its children list!
+ children = dir.listFiles();
+ }
+ if (children.length < 1 && removeIfEmpty
+ && !preservedEmptyDirectories.contains(dir)) {
+ log("Removing empty directory: " + dir, Project.MSG_DEBUG);
+ dir.delete();
+ ++removedCount;
+ }
+ }
+ return removedCount;
+ }
+
+ /**
+ * Removes all empty directories preserved by preserveInTarget in
+ * the preserveEmptyDirs == FALSE case.
+ *
+ * <p>Relies on the set to be ordered in reversed lexicographic
+ * order so that directories will be removed depth-first.</p>
+ *
+ * @param preservedEmptyDirectories directories matched by
+ * syncTarget
+ * @return the number of empty directories actually removed.
+ *
+ * @since Ant 1.8.0
+ */
+ private int removeEmptyDirectories(Set preservedEmptyDirectories) {
+ int removedCount = 0;
+ for (Iterator iter = preservedEmptyDirectories.iterator();
+ iter.hasNext();) {
+ File f = (File) iter.next();
+ String[] s = f.list();
+ if (s == null || s.length == 0) {
+ log("Removing empty directory: " + f, Project.MSG_DEBUG);
+ f.delete();
+ ++removedCount;
+ }
+ }
+ return removedCount;
+ }
+
+ //
+ // Various copy attributes/subelements of <copy> passed thru to <mycopy>
+ //
+
+ /**
+ * Sets the destination directory.
+ * @param destDir the destination directory
+ */
+ public void setTodir(File destDir) {
+ myCopy.setTodir(destDir);
+ }
+
+ /**
+ * Used to force listing of all names of copied files.
+ * @param verbose if true force listing of all names of copied files.
+ */
+ public void setVerbose(boolean verbose) {
+ myCopy.setVerbose(verbose);
+ }
+
+ /**
+ * Overwrite any existing destination file(s).
+ * @param overwrite if true overwrite any existing destination file(s).
+ */
+ public void setOverwrite(boolean overwrite) {
+ myCopy.setOverwrite(overwrite);
+ }
+
+ /**
+ * Used to copy empty directories.
+ * @param includeEmpty If true copy empty directories.
+ */
+ public void setIncludeEmptyDirs(boolean includeEmpty) {
+ myCopy.setIncludeEmptyDirs(includeEmpty);
+ }
+
+ /**
+ * If false, note errors to the output but keep going.
+ * @param failonerror true or false
+ */
+ public void setFailOnError(boolean failonerror) {
+ myCopy.setFailOnError(failonerror);
+ }
+
+ /**
+ * Adds a set of files to copy.
+ * @param set a fileset
+ */
+ public void addFileset(FileSet set) {
+ add(set);
+ }
+
+ /**
+ * Adds a collection of filesystem resources to copy.
+ * @param rc a resource collection
+ * @since Ant 1.7
+ */
+ public void add(ResourceCollection rc) {
+ if (rc instanceof FileSet && rc.isFilesystemOnly()) {
+ // receives special treatment in copy that this task relies on
+ myCopy.add(rc);
+ } else {
+ if (resources == null) {
+ Restrict r = new Restrict();
+ r.add(new Exists());
+ r.add(resources = new Resources());
+ myCopy.add(r);
+ }
+ resources.add(rc);
+ }
+ }
+
+ /**
+ * The number of milliseconds leeway to give before deciding a
+ * target is out of date.
+ *
+ * <p>Default is 0 milliseconds, or 2 seconds on DOS systems.</p>
+ * @param granularity a <code>long</code> value
+ * @since Ant 1.6.2
+ */
+ public void setGranularity(long granularity) {
+ myCopy.setGranularity(granularity);
+ }
+
+ /**
+ * A container for patterns and selectors that can be used to
+ * specify files that should be kept in the target even if they
+ * are not present in any source directory.
+ *
+ * <p>You must not invoke this method more than once.</p>
+ * @param s a preserveintarget nested element
+ * @since Ant 1.7
+ */
+ public void addPreserveInTarget(SyncTarget s) {
+ if (syncTarget != null) {
+ throw new BuildException("you must not specify multiple "
+ + "preserveintarget elements.");
+ }
+ syncTarget = s;
+ }
+
+ /**
+ * The value of preserveTarget's preserveEmptyDirs attribute if
+ * specified and preserveTarget has been used in the first place.
+ *
+ * @since Ant 1.8.0.
+ */
+ private Boolean getExplicitPreserveEmptyDirs() {
+ return syncTarget == null ? null : syncTarget.getPreserveEmptyDirs();
+ }
+
+ /**
+ * Subclass Copy in order to access it's file/dir maps.
+ */
+ public static class MyCopy extends Copy {
+
+ // List of files that must be copied, irrelevant from the
+ // fact that they are newer or not than the destination.
+ private Set nonOrphans = new HashSet();
+
+ /** Constructor for MyCopy. */
+ public MyCopy() {
+ }
+
+ /**
+ * @see Copy#scan(File, File, String[], String[])
+ */
+ /** {@inheritDoc} */
+ @Override
+ protected void scan(File fromDir, File toDir, String[] files,
+ String[] dirs) {
+ assertTrue("No mapper", mapperElement == null);
+
+ super.scan(fromDir, toDir, files, dirs);
+
+ for (int i = 0; i < files.length; ++i) {
+ nonOrphans.add(files[i]);
+ }
+ for (int i = 0; i < dirs.length; ++i) {
+ nonOrphans.add(dirs[i]);
+ }
+ }
+
+ /**
+ * @see Copy#scan(Resource[], File)
+ */
+ /** {@inheritDoc} */
+ @Override
+ protected Map scan(Resource[] resources, File toDir) {
+ assertTrue("No mapper", mapperElement == null);
+
+ for (int i = 0; i < resources.length; i++) {
+ nonOrphans.add(resources[i].getName());
+ }
+ return super.scan(resources, toDir);
+ }
+
+ /**
+ * Get the destination directory.
+ * @return the destination directory
+ */
+ public File getToDir() {
+ return destDir;
+ }
+
+ /**
+ * Get the includeEmptyDirs attribute.
+ * @return true if emptyDirs are to be included
+ */
+ public boolean getIncludeEmptyDirs() {
+ return includeEmpty;
+ }
+
+ /**
+ * Yes, we can.
+ * @return true always.
+ * @since Ant 1.7
+ */
+ @Override
+ protected boolean supportsNonFileResources() {
+ return true;
+ }
+ }
+
+ /**
+ * Inner class used to hold exclude patterns and selectors to save
+ * stuff that happens to live in the target directory but should
+ * not get removed.
+ *
+ * @since Ant 1.7
+ */
+ public static class SyncTarget extends AbstractFileSet {
+
+ private Boolean preserveEmptyDirs;
+
+ /**
+ * Constructor for SyncTarget.
+ * This just changes the default value of "defaultexcludes" from
+ * true to false.
+ */
+ public SyncTarget() {
+ super();
+ }
+
+ /**
+ * Override AbstractFileSet#setDir(File) to disallow
+ * setting the directory.
+ * @param dir ignored
+ * @throws BuildException always
+ */
+ @Override
+ public void setDir(File dir) throws BuildException {
+ throw new BuildException("preserveintarget doesn't support the dir "
+ + "attribute");
+ }
+
+ /**
+ * Whether empty directories matched by this fileset should be
+ * preserved.
+ *
+ * @since Ant 1.8.0
+ */
+ public void setPreserveEmptyDirs(boolean b) {
+ preserveEmptyDirs = Boolean.valueOf(b);
+ }
+
+ /**
+ * Whether empty directories matched by this fileset should be
+ * preserved.
+ *
+ * @since Ant 1.8.0
+ */
+ public Boolean getPreserveEmptyDirs() {
+ return preserveEmptyDirs;
+ }
+
+ private FileSet toFileSet(boolean withPatterns) {
+ FileSet fs = new FileSet();
+ fs.setCaseSensitive(isCaseSensitive());
+ fs.setFollowSymlinks(isFollowSymlinks());
+ fs.setMaxLevelsOfSymlinks(getMaxLevelsOfSymlinks());
+ fs.setProject(getProject());
+
+ if (withPatterns) {
+ PatternSet ps = mergePatterns(getProject());
+ fs.appendIncludes(ps.getIncludePatterns(getProject()));
+ fs.appendExcludes(ps.getExcludePatterns(getProject()));
+ for (Enumeration e = selectorElements(); e.hasMoreElements();) {
+ fs.appendSelector((FileSelector) e.nextElement());
+ }
+ fs.setDefaultexcludes(getDefaultexcludes());
+ }
+ return fs;
+ }
+ }
+
+ /**
+ * Pseudo-assert method.
+ */
+ private static void assertTrue(String message, boolean condition) {
+ if (!condition) {
+ throw new BuildException("Assertion Error: " + message);
+ }
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Tar.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Tar.java
new file mode 100644
index 00000000..97547022
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Tar.java
@@ -0,0 +1,1016 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.Vector;
+import java.util.zip.GZIPOutputStream;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.DirectoryScanner;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.ArchiveFileSet;
+import org.apache.tools.ant.types.EnumeratedAttribute;
+import org.apache.tools.ant.types.FileSet;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.ResourceCollection;
+import org.apache.tools.ant.types.resources.ArchiveResource;
+import org.apache.tools.ant.types.resources.FileProvider;
+import org.apache.tools.ant.types.resources.FileResource;
+import org.apache.tools.ant.types.resources.TarResource;
+import org.apache.tools.ant.types.selectors.SelectorUtils;
+import org.apache.tools.ant.util.FileUtils;
+import org.apache.tools.ant.util.MergingMapper;
+import org.apache.tools.ant.util.ResourceUtils;
+import org.apache.tools.ant.util.SourceFileScanner;
+import org.apache.tools.bzip2.CBZip2OutputStream;
+import org.apache.tools.tar.TarConstants;
+import org.apache.tools.tar.TarEntry;
+import org.apache.tools.tar.TarOutputStream;
+
+/**
+ * Creates a tar archive.
+ *
+ * @since Ant 1.1
+ *
+ * @ant.task category="packaging"
+ */
+public class Tar extends MatchingTask {
+ private static final int BUFFER_SIZE = 8 * 1024;
+
+ /**
+ * @deprecated since 1.5.x.
+ * Tar.WARN is deprecated and is replaced with
+ * Tar.TarLongFileMode.WARN
+ */
+ @Deprecated
+ public static final String WARN = "warn";
+ /**
+ * @deprecated since 1.5.x.
+ * Tar.FAIL is deprecated and is replaced with
+ * Tar.TarLongFileMode.FAIL
+ */
+ @Deprecated
+ public static final String FAIL = "fail";
+ /**
+ * @deprecated since 1.5.x.
+ * Tar.TRUNCATE is deprecated and is replaced with
+ * Tar.TarLongFileMode.TRUNCATE
+ */
+ @Deprecated
+ public static final String TRUNCATE = "truncate";
+ /**
+ * @deprecated since 1.5.x.
+ * Tar.GNU is deprecated and is replaced with
+ * Tar.TarLongFileMode.GNU
+ */
+ @Deprecated
+ public static final String GNU = "gnu";
+ /**
+ * @deprecated since 1.5.x.
+ * Tar.OMIT is deprecated and is replaced with
+ * Tar.TarLongFileMode.OMIT
+ */
+ @Deprecated
+ public static final String OMIT = "omit";
+
+ // CheckStyle:VisibilityModifier OFF - bc
+ File tarFile;
+ File baseDir;
+
+ private TarLongFileMode longFileMode = new TarLongFileMode();
+
+ // need to keep the package private version for backwards compatibility
+ Vector<TarFileSet> filesets = new Vector<TarFileSet>();
+ // we must keep two lists since other classes may modify the
+ // filesets Vector (it is package private) without us noticing
+ private final Vector<ResourceCollection> resourceCollections = new Vector<ResourceCollection>();
+
+ // CheckStyle:VisibilityModifier ON
+
+ /**
+ * Indicates whether the user has been warned about long files already.
+ */
+ private boolean longWarningGiven = false;
+
+ private TarCompressionMethod compression = new TarCompressionMethod();
+
+ /**
+ * Encoding to use for filenames, defaults to the platform's
+ * default encoding.
+ */
+ private String encoding;
+
+ /**
+ * Add a new fileset with the option to specify permissions
+ * @return the tar fileset to be used as the nested element.
+ */
+ public TarFileSet createTarFileSet() {
+ final TarFileSet fs = new TarFileSet();
+ fs.setProject(getProject());
+ filesets.addElement(fs);
+ return fs;
+ }
+
+ /**
+ * Add a collection of resources to archive.
+ * @param res a resource collection to archive.
+ * @since Ant 1.7
+ */
+ public void add(final ResourceCollection res) {
+ resourceCollections.add(res);
+ }
+
+ /**
+ * Set is the name/location of where to create the tar file.
+ * @param tarFile the location of the tar file.
+ * @deprecated since 1.5.x.
+ * For consistency with other tasks, please use setDestFile().
+ */
+ @Deprecated
+ public void setTarfile(final File tarFile) {
+ this.tarFile = tarFile;
+ }
+
+ /**
+ * Set is the name/location of where to create the tar file.
+ * @since Ant 1.5
+ * @param destFile The output of the tar
+ */
+ public void setDestFile(final File destFile) {
+ this.tarFile = destFile;
+ }
+
+ /**
+ * This is the base directory to look in for things to tar.
+ * @param baseDir the base directory.
+ */
+ public void setBasedir(final File baseDir) {
+ this.baseDir = baseDir;
+ }
+
+ /**
+ * Set how to handle long files, those with a path&gt;100 chars.
+ * Optional, default=warn.
+ * <p>
+ * Allowable values are
+ * <ul>
+ * <li> truncate - paths are truncated to the maximum length
+ * <li> fail - paths greater than the maximum cause a build exception
+ * <li> warn - paths greater than the maximum cause a warning and GNU is used
+ * <li> gnu - GNU extensions are used for any paths greater than the maximum.
+ * <li> omit - paths greater than the maximum are omitted from the archive
+ * </ul>
+ * @param mode the mode string to handle long files.
+ * @deprecated since 1.5.x.
+ * setLongFile(String) is deprecated and is replaced with
+ * setLongFile(Tar.TarLongFileMode) to make Ant's Introspection
+ * mechanism do the work and also to encapsulate operations on
+ * the mode in its own class.
+ */
+ @Deprecated
+ public void setLongfile(final String mode) {
+ log("DEPRECATED - The setLongfile(String) method has been deprecated."
+ + " Use setLongfile(Tar.TarLongFileMode) instead.");
+ this.longFileMode = new TarLongFileMode();
+ longFileMode.setValue(mode);
+ }
+
+ /**
+ * Set how to handle long files, those with a path&gt;100 chars.
+ * Optional, default=warn.
+ * <p>
+ * Allowable values are
+ * <ul>
+ * <li> truncate - paths are truncated to the maximum length
+ * <li> fail - paths greater than the maximum cause a build exception
+ * <li> warn - paths greater than the maximum cause a warning and GNU is used
+ * <li> gnu - extensions used by older versions of GNU tar are used for any paths greater than the maximum.
+ * <li> posix - use POSIX PAX extension headers for any paths greater than the maximum. Supported by all modern tar implementations.
+ * <li> omit - paths greater than the maximum are omitted from the archive
+ * </ul>
+ * @param mode the mode to handle long file names.
+ */
+ public void setLongfile(final TarLongFileMode mode) {
+ this.longFileMode = mode;
+ }
+
+ /**
+ * Set compression method.
+ * Allowable values are
+ * <ul>
+ * <li> none - no compression
+ * <li> gzip - Gzip compression
+ * <li> bzip2 - Bzip2 compression
+ * </ul>
+ * @param mode the compression method.
+ */
+ public void setCompression(final TarCompressionMethod mode) {
+ this.compression = mode;
+ }
+
+ /**
+ * Encoding to use for filenames, defaults to the platform's
+ * default encoding.
+ *
+ * <p>For a list of possible values see <a
+ * href="http://java.sun.com/j2se/1.5.0/docs/guide/intl/encoding.doc.html">http://java.sun.com/j2se/1.5.0/docs/guide/intl/encoding.doc.html</a>.</p>
+ * @param encoding the encoding name
+ *
+ * @since Ant 1.9.5
+ */
+ public void setEncoding(final String encoding) {
+ this.encoding = encoding;
+ }
+
+ /**
+ * do the business
+ * @throws BuildException on error
+ */
+ @Override
+ public void execute() throws BuildException {
+ if (tarFile == null) {
+ throw new BuildException("tarfile attribute must be set!",
+ getLocation());
+ }
+
+ if (tarFile.exists() && tarFile.isDirectory()) {
+ throw new BuildException("tarfile is a directory!",
+ getLocation());
+ }
+
+ if (tarFile.exists() && !tarFile.canWrite()) {
+ throw new BuildException("Can not write to the specified tarfile!",
+ getLocation());
+ }
+
+ @SuppressWarnings("unchecked")
+ final Vector<TarFileSet> savedFileSets = (Vector<TarFileSet>) filesets.clone();
+ try {
+ if (baseDir != null) {
+ if (!baseDir.exists()) {
+ throw new BuildException("basedir does not exist!",
+ getLocation());
+ }
+
+ // add the main fileset to the list of filesets to process.
+ final TarFileSet mainFileSet = new TarFileSet(fileset);
+ mainFileSet.setDir(baseDir);
+ filesets.addElement(mainFileSet);
+ }
+
+ if (filesets.size() == 0 && resourceCollections.size() == 0) {
+ throw new BuildException("You must supply either a basedir "
+ + "attribute or some nested resource"
+ + " collections.",
+ getLocation());
+ }
+
+ // check if tar is out of date with respect to each
+ // fileset
+ boolean upToDate = true;
+ for(final TarFileSet tfs : filesets) {
+ upToDate &= check(tfs);
+ }
+ for(final ResourceCollection rcol : resourceCollections) {
+ upToDate &= check(rcol);
+ }
+
+ if (upToDate) {
+ log("Nothing to do: " + tarFile.getAbsolutePath()
+ + " is up to date.", Project.MSG_INFO);
+ return;
+ }
+
+ final File parent = tarFile.getParentFile();
+ if (parent != null && !parent.isDirectory()
+ && !(parent.mkdirs() || parent.isDirectory())) {
+ throw new BuildException("Failed to create missing parent"
+ + " directory for " + tarFile);
+ }
+
+ log("Building tar: " + tarFile.getAbsolutePath(), Project.MSG_INFO);
+
+ TarOutputStream tOut = null;
+ try {
+ tOut = new TarOutputStream(
+ compression.compress(
+ new BufferedOutputStream(
+ new FileOutputStream(tarFile))),
+ encoding);
+ tOut.setDebug(true);
+ if (longFileMode.isTruncateMode()) {
+ tOut.setLongFileMode(TarOutputStream.LONGFILE_TRUNCATE);
+ } else if (longFileMode.isFailMode()
+ || longFileMode.isOmitMode()) {
+ tOut.setLongFileMode(TarOutputStream.LONGFILE_ERROR);
+ } else if (longFileMode.isPosixMode()) {
+ tOut.setLongFileMode(TarOutputStream.LONGFILE_POSIX);
+ } else {
+ // warn or GNU
+ tOut.setLongFileMode(TarOutputStream.LONGFILE_GNU);
+ }
+
+ longWarningGiven = false;
+ for (final TarFileSet tfs : filesets) {
+ tar(tfs, tOut);
+ }
+ for (final ResourceCollection rcol : resourceCollections) {
+ tar(rcol, tOut);
+ }
+ } catch (final IOException ioe) {
+ final String msg = "Problem creating TAR: " + ioe.getMessage();
+ throw new BuildException(msg, ioe, getLocation());
+ } finally {
+ FileUtils.close(tOut);
+ }
+ } finally {
+ filesets = savedFileSets;
+ }
+ }
+
+ /**
+ * tar a file
+ * @param file the file to tar
+ * @param tOut the output stream
+ * @param vPath the path name of the file to tar
+ * @param tarFileSet the fileset that the file came from.
+ * @throws IOException on error
+ */
+ protected void tarFile(final File file, final TarOutputStream tOut, final String vPath,
+ final TarFileSet tarFileSet)
+ throws IOException {
+ if (file.equals(tarFile)) {
+ // If the archive is built for the first time and it is
+ // matched by a resource collection, then it hasn't been
+ // found in check (it hasn't been there) but will be
+ // included now.
+ //
+ // for some strange reason the old code would simply skip
+ // the entry and not fail, do the same now for backwards
+ // compatibility reasons. Without this, the which4j build
+ // fails in Gump
+ return;
+ }
+ tarResource(new FileResource(file), tOut, vPath, tarFileSet);
+ }
+
+ /**
+ * tar a resource
+ * @param r the resource to tar
+ * @param tOut the output stream
+ * @param vPath the path name of the file to tar
+ * @param tarFileSet the fileset that the file came from, may be null.
+ * @throws IOException on error
+ * @since Ant 1.7
+ */
+ protected void tarResource(final Resource r, final TarOutputStream tOut, String vPath,
+ final TarFileSet tarFileSet)
+ throws IOException {
+
+ if (!r.isExists()) {
+ return;
+ }
+
+ boolean preserveLeadingSlashes = false;
+
+ if (tarFileSet != null) {
+ final String fullpath = tarFileSet.getFullpath(this.getProject());
+ if (fullpath.length() > 0) {
+ vPath = fullpath;
+ } else {
+ // don't add "" to the archive
+ if (vPath.length() <= 0) {
+ return;
+ }
+
+ String prefix = tarFileSet.getPrefix(this.getProject());
+ // '/' is appended for compatibility with the zip task.
+ if (prefix.length() > 0 && !prefix.endsWith("/")) {
+ prefix = prefix + "/";
+ }
+ vPath = prefix + vPath;
+ }
+
+ preserveLeadingSlashes = tarFileSet.getPreserveLeadingSlashes();
+
+ if (vPath.startsWith("/") && !preserveLeadingSlashes) {
+ final int l = vPath.length();
+ if (l <= 1) {
+ // we would end up adding "" to the archive
+ return;
+ }
+ vPath = vPath.substring(1, l);
+ }
+ }
+
+ if (r.isDirectory() && !vPath.endsWith("/")) {
+ vPath += "/";
+ }
+
+ if (vPath.length() >= TarConstants.NAMELEN) {
+ if (longFileMode.isOmitMode()) {
+ log("Omitting: " + vPath, Project.MSG_INFO);
+ return;
+ } else if (longFileMode.isWarnMode()) {
+ log("Entry: " + vPath + " longer than "
+ + TarConstants.NAMELEN + " characters.",
+ Project.MSG_WARN);
+ if (!longWarningGiven) {
+ log("Resulting tar file can only be processed "
+ + "successfully by GNU compatible tar commands",
+ Project.MSG_WARN);
+ longWarningGiven = true;
+ }
+ } else if (longFileMode.isFailMode()) {
+ throw new BuildException("Entry: " + vPath
+ + " longer than " + TarConstants.NAMELEN
+ + "characters.", getLocation());
+ }
+ }
+
+ final TarEntry te = new TarEntry(vPath, preserveLeadingSlashes);
+ te.setModTime(r.getLastModified());
+ // preserve permissions
+ if (r instanceof ArchiveResource) {
+ final ArchiveResource ar = (ArchiveResource) r;
+ te.setMode(ar.getMode());
+ if (r instanceof TarResource) {
+ final TarResource tr = (TarResource) r;
+ te.setUserName(tr.getUserName());
+ te.setUserId(tr.getUid());
+ te.setGroupName(tr.getGroup());
+ te.setGroupId(tr.getGid());
+ }
+ }
+
+ if (!r.isDirectory()) {
+ if (r.size() > TarConstants.MAXSIZE) {
+ throw new BuildException(
+ "Resource: " + r + " larger than "
+ + TarConstants.MAXSIZE + " bytes.");
+ }
+ te.setSize(r.getSize());
+ // override permissions if set explicitly
+ if (tarFileSet != null && tarFileSet.hasFileModeBeenSet()) {
+ te.setMode(tarFileSet.getMode());
+ }
+ } else if (tarFileSet != null && tarFileSet.hasDirModeBeenSet()) {
+ // override permissions if set explicitly
+ te.setMode(tarFileSet.getDirMode(this.getProject()));
+ }
+
+ if (tarFileSet != null) {
+ // only override permissions if set explicitly
+ if (tarFileSet.hasUserNameBeenSet()) {
+ te.setUserName(tarFileSet.getUserName());
+ }
+ if (tarFileSet.hasGroupBeenSet()) {
+ te.setGroupName(tarFileSet.getGroup());
+ }
+ if (tarFileSet.hasUserIdBeenSet()) {
+ te.setUserId(tarFileSet.getUid());
+ }
+ if (tarFileSet.hasGroupIdBeenSet()) {
+ te.setGroupId(tarFileSet.getGid());
+ }
+ }
+
+ InputStream in = null;
+ try {
+ tOut.putNextEntry(te);
+
+ if (!r.isDirectory()) {
+ in = r.getInputStream();
+
+ final byte[] buffer = new byte[BUFFER_SIZE];
+ int count = 0;
+ do {
+ tOut.write(buffer, 0, count);
+ count = in.read(buffer, 0, buffer.length);
+ } while (count != -1);
+ }
+
+ tOut.closeEntry();
+ } finally {
+ FileUtils.close(in);
+ }
+ }
+
+ /**
+ * Is the archive up to date in relationship to a list of files.
+ * @param files the files to check
+ * @return true if the archive is up to date.
+ * @deprecated since 1.5.x.
+ * use the two-arg version instead.
+ */
+ @Deprecated
+ protected boolean archiveIsUpToDate(final String[] files) {
+ return archiveIsUpToDate(files, baseDir);
+ }
+
+ /**
+ * Is the archive up to date in relationship to a list of files.
+ * @param files the files to check
+ * @param dir the base directory for the files.
+ * @return true if the archive is up to date.
+ * @since Ant 1.5.2
+ */
+ protected boolean archiveIsUpToDate(final String[] files, final File dir) {
+ final SourceFileScanner sfs = new SourceFileScanner(this);
+ final MergingMapper mm = new MergingMapper();
+ mm.setTo(tarFile.getAbsolutePath());
+ return sfs.restrict(files, dir, null, mm).length == 0;
+ }
+
+ /**
+ * Is the archive up to date in relationship to a list of files.
+ * @param r the files to check
+ * @return true if the archive is up to date.
+ * @since Ant 1.7
+ */
+ protected boolean archiveIsUpToDate(final Resource r) {
+ return SelectorUtils.isOutOfDate(new FileResource(tarFile), r,
+ FileUtils.getFileUtils()
+ .getFileTimestampGranularity());
+ }
+
+ /**
+ * Whether this task can deal with non-file resources.
+ *
+ * <p>This implementation returns true only if this task is
+ * &lt;tar&gt;. Any subclass of this class that also wants to
+ * support non-file resources needs to override this method. We
+ * need to do so for backwards compatibility reasons since we
+ * can't expect subclasses to support resources.</p>
+ * @return true for this task.
+ * @since Ant 1.7
+ */
+ protected boolean supportsNonFileResources() {
+ return getClass().equals(Tar.class);
+ }
+
+ /**
+ * Checks whether the archive is out-of-date with respect to the resources
+ * of the given collection.
+ *
+ * <p>Also checks that either all collections only contain file
+ * resources or this class supports non-file collections.</p>
+ *
+ * <p>And - in case of file-collections - ensures that the archive won't
+ * contain itself.</p>
+ *
+ * @param rc the resource collection to check
+ * @return whether the archive is up-to-date
+ * @since Ant 1.7
+ */
+ protected boolean check(final ResourceCollection rc) {
+ boolean upToDate = true;
+ if (isFileFileSet(rc)) {
+ final FileSet fs = (FileSet) rc;
+ upToDate = check(fs.getDir(getProject()), getFileNames(fs));
+ } else if (!rc.isFilesystemOnly() && !supportsNonFileResources()) {
+ throw new BuildException("only filesystem resources are supported");
+ } else if (rc.isFilesystemOnly()) {
+ final Set<File> basedirs = new HashSet<File>();
+ final Map<File, List<String>> basedirToFilesMap = new HashMap<File, List<String>>();
+ for (final Resource res : rc) {
+ final FileResource r = ResourceUtils
+ .asFileResource(res.as(FileProvider.class));
+ File base = r.getBaseDir();
+ if (base == null) {
+ base = Copy.NULL_FILE_PLACEHOLDER;
+ }
+ basedirs.add(base);
+ List<String> files = basedirToFilesMap.get(base);
+ if (files == null) {
+ files = new Vector<String>();
+ basedirToFilesMap.put(base, files);
+ }
+ if (base == Copy.NULL_FILE_PLACEHOLDER) {
+ files.add(r.getFile().getAbsolutePath());
+ } else {
+ files.add(r.getName());
+ }
+ }
+ for (final File base : basedirs) {
+ final File tmpBase = base == Copy.NULL_FILE_PLACEHOLDER ? null : base;
+ final List<String> files = basedirToFilesMap.get(base);
+ upToDate &= check(tmpBase, files);
+ }
+ } else { // non-file resources
+ final Iterator<Resource> iter = rc.iterator();
+ while (upToDate && iter.hasNext()) {
+ final Resource r = iter.next();
+ upToDate = archiveIsUpToDate(r);
+ }
+ }
+ return upToDate;
+ }
+
+ /**
+ * <p>Checks whether the archive is out-of-date with respect to the
+ * given files, ensures that the archive won't contain itself.</p>
+ *
+ * @param basedir base directory for file names
+ * @param files array of relative file names
+ * @return whether the archive is up-to-date
+ * @since Ant 1.7
+ */
+ protected boolean check(final File basedir, final String[] files) {
+ boolean upToDate = true;
+ if (!archiveIsUpToDate(files, basedir)) {
+ upToDate = false;
+ }
+
+ for (int i = 0; i < files.length; ++i) {
+ if (tarFile.equals(new File(basedir, files[i]))) {
+ throw new BuildException("A tar file cannot include "
+ + "itself", getLocation());
+ }
+ }
+ return upToDate;
+ }
+
+ /**
+ * <p>Checks whether the archive is out-of-date with respect to the
+ * given files, ensures that the archive won't contain itself.</p>
+ *
+ * @param basedir base directory for file names
+ * @param files array of relative file names
+ * @return whether the archive is up-to-date
+ * @see #check(File, String[])
+ * @since Ant 1.9.5
+ */
+ protected boolean check(final File basedir, final Collection<String> files) {
+ return check(basedir, files.toArray(new String[files.size()]));
+ }
+
+ /**
+ * Adds the resources contained in this collection to the archive.
+ *
+ * <p>Uses the file based methods for file resources for backwards
+ * compatibility.</p>
+ *
+ * @param rc the collection containing resources to add
+ * @param tOut stream writing to the archive.
+ * @throws IOException on error.
+ * @since Ant 1.7
+ */
+ protected void tar(final ResourceCollection rc, final TarOutputStream tOut)
+ throws IOException {
+ ArchiveFileSet afs = null;
+ if (rc instanceof ArchiveFileSet) {
+ afs = (ArchiveFileSet) rc;
+ }
+ if (afs != null && afs.size() > 1
+ && afs.getFullpath(this.getProject()).length() > 0) {
+ throw new BuildException("fullpath attribute may only "
+ + "be specified for "
+ + "filesets that specify a "
+ + "single file.");
+ }
+ final TarFileSet tfs = asTarFileSet(afs);
+
+ if (isFileFileSet(rc)) {
+ final FileSet fs = (FileSet) rc;
+ final String[] files = getFileNames(fs);
+ for (int i = 0; i < files.length; i++) {
+ final File f = new File(fs.getDir(getProject()), files[i]);
+ final String name = files[i].replace(File.separatorChar, '/');
+ tarFile(f, tOut, name, tfs);
+ }
+ } else if (rc.isFilesystemOnly()) {
+ for (final Resource r : rc) {
+ final File f = r.as(FileProvider.class).getFile();
+ tarFile(f, tOut, f.getName(), tfs);
+ }
+ } else { // non-file resources
+ for (final Resource r : rc) {
+ tarResource(r, tOut, r.getName(), tfs);
+ }
+ }
+ }
+
+ /**
+ * whether the given resource collection is a (subclass of)
+ * FileSet that only contains file system resources.
+ * @param rc the resource collection to check.
+ * @return true if the collection is a fileset.
+ * @since Ant 1.7
+ */
+ protected static boolean isFileFileSet(final ResourceCollection rc) {
+ return rc instanceof FileSet && rc.isFilesystemOnly();
+ }
+
+ /**
+ * Grabs all included files and directors from the FileSet and
+ * returns them as an array of (relative) file names.
+ * @param fs the fileset to operate on.
+ * @return a list of the filenames.
+ * @since Ant 1.7
+ */
+ protected static String[] getFileNames(final FileSet fs) {
+ final DirectoryScanner ds = fs.getDirectoryScanner(fs.getProject());
+ final String[] directories = ds.getIncludedDirectories();
+ final String[] filesPerSe = ds.getIncludedFiles();
+ final String[] files = new String [directories.length + filesPerSe.length];
+ System.arraycopy(directories, 0, files, 0, directories.length);
+ System.arraycopy(filesPerSe, 0, files, directories.length,
+ filesPerSe.length);
+ return files;
+ }
+
+ /**
+ * Copies fullpath, prefix and permission attributes from the
+ * ArchiveFileSet to a new TarFileSet (or returns it unchanged if
+ * it already is a TarFileSet).
+ *
+ * @param archiveFileSet fileset to copy attributes from, may be null
+ * @return a new TarFileSet.
+ * @since Ant 1.7
+ */
+ protected TarFileSet asTarFileSet(final ArchiveFileSet archiveFileSet) {
+ TarFileSet tfs = null;
+ if (archiveFileSet != null && archiveFileSet instanceof TarFileSet) {
+ tfs = (TarFileSet) archiveFileSet;
+ } else {
+ tfs = new TarFileSet();
+ tfs.setProject(getProject());
+ if (archiveFileSet != null) {
+ tfs.setPrefix(archiveFileSet.getPrefix(getProject()));
+ tfs.setFullpath(archiveFileSet.getFullpath(getProject()));
+ if (archiveFileSet.hasFileModeBeenSet()) {
+ tfs.integerSetFileMode(archiveFileSet
+ .getFileMode(getProject()));
+ }
+ if (archiveFileSet.hasDirModeBeenSet()) {
+ tfs.integerSetDirMode(archiveFileSet
+ .getDirMode(getProject()));
+ }
+
+ if (archiveFileSet
+ instanceof org.apache.tools.ant.types.TarFileSet) {
+ final org.apache.tools.ant.types.TarFileSet t =
+ (org.apache.tools.ant.types.TarFileSet) archiveFileSet;
+ if (t.hasUserNameBeenSet()) {
+ tfs.setUserName(t.getUserName());
+ }
+ if (t.hasGroupBeenSet()) {
+ tfs.setGroup(t.getGroup());
+ }
+ if (t.hasUserIdBeenSet()) {
+ tfs.setUid(t.getUid());
+ }
+ if (t.hasGroupIdBeenSet()) {
+ tfs.setGid(t.getGid());
+ }
+ }
+ }
+ }
+ return tfs;
+ }
+
+ /**
+ * This is a FileSet with the option to specify permissions
+ * and other attributes.
+ */
+ public static class TarFileSet
+ extends org.apache.tools.ant.types.TarFileSet {
+ private String[] files = null;
+
+ private boolean preserveLeadingSlashes = false;
+
+ /**
+ * Creates a new <code>TarFileSet</code> instance.
+ * Using a fileset as a constructor argument.
+ *
+ * @param fileset a <code>FileSet</code> value
+ */
+ public TarFileSet(final FileSet fileset) {
+ super(fileset);
+ }
+
+ /**
+ * Creates a new <code>TarFileSet</code> instance.
+ *
+ */
+ public TarFileSet() {
+ super();
+ }
+
+ /**
+ * Get a list of files and directories specified in the fileset.
+ * @param p the current project.
+ * @return a list of file and directory names, relative to
+ * the baseDir for the project.
+ */
+ public String[] getFiles(final Project p) {
+ if (files == null) {
+ files = getFileNames(this);
+ }
+
+ return files;
+ }
+
+ /**
+ * A 3 digit octal string, specify the user, group and
+ * other modes in the standard Unix fashion;
+ * optional, default=0644
+ * @param octalString a 3 digit octal string.
+ */
+ public void setMode(final String octalString) {
+ setFileMode(octalString);
+ }
+
+ /**
+ * @return the current mode.
+ */
+ public int getMode() {
+ return getFileMode(this.getProject());
+ }
+
+ /**
+ * Flag to indicates whether leading `/'s should
+ * be preserved in the file names.
+ * Optional, default is <code>false</code>.
+ * @param b the leading slashes flag.
+ */
+ public void setPreserveLeadingSlashes(final boolean b) {
+ this.preserveLeadingSlashes = b;
+ }
+
+ /**
+ * @return the leading slashes flag.
+ */
+ public boolean getPreserveLeadingSlashes() {
+ return preserveLeadingSlashes;
+ }
+ }
+
+ /**
+ * Set of options for long file handling in the task.
+ *
+ */
+ public static class TarLongFileMode extends EnumeratedAttribute {
+
+ /** permissible values for longfile attribute */
+ public static final String
+ WARN = "warn",
+ FAIL = "fail",
+ TRUNCATE = "truncate",
+ GNU = "gnu",
+ POSIX = "posix",
+ OMIT = "omit";
+
+ private final String[] validModes = {
+ WARN, FAIL, TRUNCATE, GNU, POSIX, OMIT
+ };
+
+ /** Constructor, defaults to "warn" */
+ public TarLongFileMode() {
+ super();
+ setValue(WARN);
+ }
+
+ /**
+ * @return the possible values for this enumerated type.
+ */
+ @Override
+ public String[] getValues() {
+ return validModes;
+ }
+
+ /**
+ * @return true if value is "truncate".
+ */
+ public boolean isTruncateMode() {
+ return TRUNCATE.equalsIgnoreCase(getValue());
+ }
+
+ /**
+ * @return true if value is "warn".
+ */
+ public boolean isWarnMode() {
+ return WARN.equalsIgnoreCase(getValue());
+ }
+
+ /**
+ * @return true if value is "gnu".
+ */
+ public boolean isGnuMode() {
+ return GNU.equalsIgnoreCase(getValue());
+ }
+
+ /**
+ * @return true if value is "fail".
+ */
+ public boolean isFailMode() {
+ return FAIL.equalsIgnoreCase(getValue());
+ }
+
+ /**
+ * @return true if value is "omit".
+ */
+ public boolean isOmitMode() {
+ return OMIT.equalsIgnoreCase(getValue());
+ }
+
+ /**
+ * @return true if value is "posix".
+ */
+ public boolean isPosixMode() {
+ return POSIX.equalsIgnoreCase(getValue());
+ }
+ }
+
+ /**
+ * Valid Modes for Compression attribute to Tar Task
+ *
+ */
+ public static final class TarCompressionMethod extends EnumeratedAttribute {
+
+ // permissible values for compression attribute
+ /**
+ * No compression
+ */
+ private static final String NONE = "none";
+ /**
+ * GZIP compression
+ */
+ private static final String GZIP = "gzip";
+ /**
+ * BZIP2 compression
+ */
+ private static final String BZIP2 = "bzip2";
+
+
+ /**
+ * Default constructor
+ */
+ public TarCompressionMethod() {
+ super();
+ setValue(NONE);
+ }
+
+ /**
+ * Get valid enumeration values.
+ * @return valid enumeration values
+ */
+ @Override
+ public String[] getValues() {
+ return new String[] {NONE, GZIP, BZIP2 };
+ }
+
+ /**
+ * This method wraps the output stream with the
+ * corresponding compression method
+ *
+ * @param ostream output stream
+ * @return output stream with on-the-fly compression
+ * @exception IOException thrown if file is not writable
+ */
+ private OutputStream compress(final OutputStream ostream)
+ throws IOException {
+ final String v = getValue();
+ if (GZIP.equals(v)) {
+ return new GZIPOutputStream(ostream);
+ } else {
+ if (BZIP2.equals(v)) {
+ ostream.write('B');
+ ostream.write('Z');
+ return new CBZip2OutputStream(ostream);
+ }
+ }
+ return ostream;
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/TaskOutputStream.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/TaskOutputStream.java
new file mode 100644
index 00000000..0fdeeff6
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/TaskOutputStream.java
@@ -0,0 +1,96 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import org.apache.tools.ant.Task;
+
+/**
+ * Redirects text written to a stream thru the standard
+ * ant logging mechanism. This class is useful for integrating
+ * with tools that write to System.out and System.err. For example,
+ * the following will cause all text written to System.out to be
+ * logged with "info" priority:
+ * <pre>System.setOut(new PrintStream(new TaskOutputStream(project, Project.MSG_INFO)));</pre>
+ *
+ * <p><strong>As of Ant 1.2, this class is considered to be dead code
+ * by the Ant developers and is unmaintained. Don't use
+ * it.</strong></p>
+ *
+ * @deprecated since 1.2.x.
+ * Use LogOutputStream instead.
+ */
+
+public class TaskOutputStream extends OutputStream {
+
+ private Task task;
+ private StringBuffer line;
+ private int msgOutputLevel;
+
+ /**
+ * Constructs a new JavacOutputStream with the given project
+ * as the output source for messages.
+ */
+
+ TaskOutputStream(Task task, int msgOutputLevel) {
+ System.err.println("As of Ant 1.2 released in October 2000, the "
+ + "TaskOutputStream class");
+ System.err.println("is considered to be dead code by the Ant "
+ + "developers and is unmaintained.");
+ System.err.println("Don\'t use it!");
+
+ this.task = task;
+ this.msgOutputLevel = msgOutputLevel;
+
+ line = new StringBuffer();
+ }
+
+ /**
+ * Write a character to the output stream. This method looks
+ * to make sure that there isn't an error being reported and
+ * will flush each line of input out to the project's log stream.
+ * @param c the character to write
+ * @throws IOException on error
+ */
+
+ public void write(int c) throws IOException {
+ char cc = (char) c;
+ if (cc == '\r' || cc == '\n') {
+ // line feed
+ if (line.length() > 0) {
+ processLine();
+ }
+ } else {
+ line.append(cc);
+ }
+ }
+
+ /**
+ * Processes a line of input and determines if an error occurred.
+ */
+
+ private void processLine() {
+ String s = line.toString();
+ task.log(s, msgOutputLevel);
+ line = new StringBuffer();
+ }
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Taskdef.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Taskdef.java
new file mode 100644
index 00000000..a7d0b71c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Taskdef.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.TaskAdapter;
+
+/**
+ * <p>Adds a task definition to the current project, such that this new task can be
+ * used in the current project. Two attributes are needed, the name that identifies
+ * this task uniquely, and the full name of the class (including the packages) that
+ * implements this task.</p>
+ * <p>You can also define a group of tasks at once using the file or
+ * resource attributes. These attributes point to files in the format of
+ * Java property files. Each line defines a single task in the format:</p>
+ * <pre>
+ * taskname=fully.qualified.java.classname
+ * </pre>
+ * @since Ant 1.1
+ * @ant.task category="internal"
+ */
+public class Taskdef extends Typedef {
+
+ /**
+ * Default constructor.
+ * Creates a new Taskdef instance.
+ * This sets the adapter and the adaptto classes to
+ * TaskAdapter and Task.
+ */
+
+ public Taskdef() {
+ setAdapterClass(TaskAdapter.class);
+ setAdaptToClass(Task.class);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/TempFile.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/TempFile.java
new file mode 100644
index 00000000..5f55a376
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/TempFile.java
@@ -0,0 +1,163 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs;
+
+import java.io.File;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.util.FileUtils;
+
+/**
+ * This task sets a property to the name of a temporary file.
+ * Unlike {@link File#createTempFile}, this task does not (by default) actually create the
+ * temporary file, but it does guarantee that the file did not
+ * exist when the task was executed.
+ * <p>
+ * Examples
+ * <pre>&lt;tempfile property="temp.file" /&gt;</pre>
+ * create a temporary file
+ * <pre>&lt;tempfile property="temp.file" suffix=".xml" /&gt;</pre>
+ * create a temporary file with the .xml suffix.
+ * <pre>&lt;tempfile property="temp.file" destDir="build"/&gt;</pre>
+ * create a temp file in the build subdir
+ * @since Ant 1.5
+ * @ant.task
+ */
+
+public class TempFile extends Task {
+
+ private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+
+ /**
+ * Name of property to set.
+ */
+ private String property;
+
+ /**
+ * Directory to create the file in. Can be null.
+ */
+ private File destDir = null;
+
+ /**
+ * Prefix for the file.
+ */
+ private String prefix;
+
+ /**
+ * Suffix for the file.
+ */
+ private String suffix = "";
+
+ /** deleteOnExit flag */
+ private boolean deleteOnExit;
+
+ /** createFile flag */
+ private boolean createFile;
+
+ /**
+ * Sets the property you wish to assign the temporary file to.
+ *
+ * @param property The property to set
+ * @ant.attribute group="required"
+ */
+ public void setProperty(String property) {
+ this.property = property;
+ }
+
+
+ /**
+ * Sets the destination directory. If not set,
+ * the basedir directory is used instead.
+ *
+ * @param destDir The new destDir value
+ */
+ public void setDestDir(File destDir) {
+ this.destDir = destDir;
+ }
+
+
+ /**
+ * Sets the optional prefix string for the temp file.
+ *
+ * @param prefix string to prepend to generated string
+ */
+ public void setPrefix(String prefix) {
+ this.prefix = prefix;
+ }
+
+
+ /**
+ * Sets the optional suffix string for the temp file.
+ *
+ * @param suffix suffix including any "." , e.g ".xml"
+ */
+ public void setSuffix(String suffix) {
+ this.suffix = suffix;
+ }
+
+ /**
+ * Set whether the tempfile created by this task should be set
+ * for deletion on normal VM exit.
+ * @param deleteOnExit boolean flag.
+ */
+ public void setDeleteOnExit(boolean deleteOnExit) {
+ this.deleteOnExit = deleteOnExit;
+ }
+
+ /**
+ * Learn whether deleteOnExit is set for this tempfile task.
+ * @return boolean deleteOnExit flag.
+ */
+ public boolean isDeleteOnExit() {
+ return deleteOnExit;
+ }
+
+ /**
+ * If set the file is actually created, if not just a name is created.
+ * @param createFile boolean flag.
+ */
+ public void setCreateFile(boolean createFile) {
+ this.createFile = createFile;
+ }
+
+ /**
+ * Learn whether createFile flag is set for this tempfile task.
+ * @return the createFile flag.
+ */
+ public boolean isCreateFile() {
+ return createFile;
+ }
+
+ /**
+ * Creates the temporary file.
+ *
+ * @exception BuildException if something goes wrong with the build
+ */
+ public void execute() throws BuildException {
+ if (property == null || property.length() == 0) {
+ throw new BuildException("no property specified");
+ }
+ if (destDir == null) {
+ destDir = getProject().resolveFile(".");
+ }
+ File tfile = FILE_UTILS.createTempFile(prefix, suffix, destDir,
+ deleteOnExit, createFile);
+ getProject().setNewProperty(property, tfile.toString());
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Touch.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Touch.java
new file mode 100644
index 00000000..4a4118ce
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Touch.java
@@ -0,0 +1,381 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.io.File;
+import java.io.IOException;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Locale;
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.DirectoryScanner;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.types.FileList;
+import org.apache.tools.ant.types.FileSet;
+import org.apache.tools.ant.types.Mapper;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.ResourceCollection;
+import org.apache.tools.ant.types.resources.FileProvider;
+import org.apache.tools.ant.types.resources.FileResource;
+import org.apache.tools.ant.types.resources.Touchable;
+import org.apache.tools.ant.types.resources.Union;
+import org.apache.tools.ant.util.FileNameMapper;
+import org.apache.tools.ant.util.FileUtils;
+
+/**
+ * Touch a file and/or fileset(s) and/or filelist(s);
+ * corresponds to the Unix touch command.
+ *
+ * <p>If the file to touch doesn't exist, an empty one is created.</p>
+ *
+ * @since Ant 1.1
+ *
+ * @ant.task category="filesystem"
+ */
+public class Touch extends Task {
+
+ public interface DateFormatFactory {
+ DateFormat getPrimaryFormat();
+ DateFormat getFallbackFormat();
+ }
+
+ public static final DateFormatFactory DEFAULT_DF_FACTORY
+ = new DateFormatFactory() {
+ /*
+ * The initial version used DateFormat.SHORT for the
+ * time format, which ignores seconds. If we want
+ * seconds as well, we need DateFormat.MEDIUM, which
+ * in turn would break all old build files.
+ *
+ * First try to parse with DateFormat.SHORT and if
+ * that fails with MEDIUM - throw an exception if both
+ * fail.
+ */
+ public DateFormat getPrimaryFormat() {
+ return DateFormat.getDateTimeInstance(DateFormat.SHORT,
+ DateFormat.SHORT, Locale.US);
+ }
+ public DateFormat getFallbackFormat() {
+ return DateFormat.getDateTimeInstance(DateFormat.SHORT,
+ DateFormat.MEDIUM, Locale.US);
+ }
+ };
+ private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+
+ private File file;
+ private long millis = -1;
+ private String dateTime;
+ private Vector filesets = new Vector();
+ private Union resources;
+ private boolean dateTimeConfigured;
+ private boolean mkdirs;
+ private boolean verbose = true;
+ private FileNameMapper fileNameMapper = null;
+ private DateFormatFactory dfFactory = DEFAULT_DF_FACTORY;
+
+ /**
+ * Construct a new <code>Touch</code> task.
+ */
+ public Touch() {
+ }
+
+ /**
+ * Sets a single source file to touch. If the file does not exist
+ * an empty file will be created.
+ * @param file the <code>File</code> to touch.
+ */
+ public void setFile(File file) {
+ this.file = file;
+ }
+
+ /**
+ * Set the new modification time of file(s) touched
+ * in milliseconds since midnight Jan 1 1970. Optional, default=now.
+ * @param millis the <code>long</code> timestamp to use.
+ */
+ public void setMillis(long millis) {
+ this.millis = millis;
+ }
+
+ /**
+ * Set the new modification time of file(s) touched
+ * in the format &quot;MM/DD/YYYY HH:MM AM <i>or</i> PM&quot;
+ * or &quot;MM/DD/YYYY HH:MM:SS AM <i>or</i> PM&quot;.
+ * Optional, default=now.
+ * @param dateTime the <code>String</code> date in the specified format.
+ */
+ public void setDatetime(String dateTime) {
+ if (this.dateTime != null) {
+ log("Resetting datetime attribute to " + dateTime, Project.MSG_VERBOSE);
+ }
+ this.dateTime = dateTime;
+ dateTimeConfigured = false;
+ }
+
+ /**
+ * Set whether nonexistent parent directories should be created
+ * when touching new files.
+ * @param mkdirs <code>boolean</code> whether to create parent directories.
+ * @since Ant 1.6.3
+ */
+ public void setMkdirs(boolean mkdirs) {
+ this.mkdirs = mkdirs;
+ }
+
+ /**
+ * Set whether the touch task will report every file it creates;
+ * defaults to <code>true</code>.
+ * @param verbose <code>boolean</code> flag.
+ * @since Ant 1.6.3
+ */
+ public void setVerbose(boolean verbose) {
+ this.verbose = verbose;
+ }
+
+ /**
+ * Set the format of the datetime attribute.
+ * @param pattern the <code>SimpleDateFormat</code>-compatible format pattern.
+ * @since Ant 1.6.3
+ */
+ public void setPattern(final String pattern) {
+ dfFactory = new DateFormatFactory() {
+ public DateFormat getPrimaryFormat() {
+ return new SimpleDateFormat(pattern);
+ }
+ public DateFormat getFallbackFormat() {
+ return null;
+ }
+ };
+ }
+
+ /**
+ * Add a <code>Mapper</code>.
+ * @param mapper the <code>Mapper</code> to add.
+ * @since Ant 1.6.3
+ */
+ public void addConfiguredMapper(Mapper mapper) {
+ add(mapper.getImplementation());
+ }
+
+ /**
+ * Add a <code>FileNameMapper</code>.
+ * @param fileNameMapper the <code>FileNameMapper</code> to add.
+ * @since Ant 1.6.3
+ * @throws BuildException if multiple mappers are added.
+ */
+ public void add(FileNameMapper fileNameMapper) throws BuildException {
+ if (this.fileNameMapper != null) {
+ throw new BuildException("Only one mapper may be added to the "
+ + getTaskName() + " task.");
+ }
+ this.fileNameMapper = fileNameMapper;
+ }
+
+ /**
+ * Add a set of files to touch.
+ * @param set the <code>Fileset</code> to add.
+ */
+ public void addFileset(FileSet set) {
+ filesets.add(set);
+ add(set);
+ }
+
+ /**
+ * Add a filelist to touch.
+ * @param list the <code>Filelist</code> to add.
+ */
+ public void addFilelist(FileList list) {
+ add(list);
+ }
+
+ /**
+ * Add a collection of resources to touch.
+ * @param rc the collection to add.
+ * @since Ant 1.7
+ */
+ public synchronized void add(ResourceCollection rc) {
+ resources = resources == null ? new Union() : resources;
+ resources.add(rc);
+ }
+
+ /**
+ * Check that this task has been configured properly.
+ * @throws BuildException if configuration errors are detected.
+ * @since Ant 1.6.3
+ */
+ protected synchronized void checkConfiguration() throws BuildException {
+ if (file == null && resources == null) {
+ throw new BuildException("Specify at least one source"
+ + "--a file or resource collection.");
+ }
+ if (file != null && file.exists() && file.isDirectory()) {
+ throw new BuildException("Use a resource collection to touch directories.");
+ }
+ if (dateTime != null && !dateTimeConfigured) {
+ long workmillis = millis;
+ if ("now".equalsIgnoreCase(dateTime)) {
+ workmillis = System.currentTimeMillis();
+ } else {
+ DateFormat df = dfFactory.getPrimaryFormat();
+ ParseException pe = null;
+ try {
+ workmillis = df.parse(dateTime).getTime();
+ } catch (ParseException peOne) {
+ df = dfFactory.getFallbackFormat();
+ if (df == null) {
+ pe = peOne;
+ } else {
+ try {
+ workmillis = df.parse(dateTime).getTime();
+ } catch (ParseException peTwo) {
+ pe = peTwo;
+ }
+ }
+ }
+ if (pe != null) {
+ throw new BuildException(pe.getMessage(), pe, getLocation());
+ }
+ if (workmillis < 0) {
+ throw new BuildException("Date of " + dateTime
+ + " results in negative " + "milliseconds value "
+ + "relative to epoch " + "(January 1, 1970, "
+ + "00:00:00 GMT).");
+ }
+ }
+ log("Setting millis to " + workmillis + " from datetime attribute",
+ ((millis < 0) ? Project.MSG_DEBUG : Project.MSG_VERBOSE));
+ setMillis(workmillis);
+ // only set if successful to this point:
+ dateTimeConfigured = true;
+ }
+ }
+
+ /**
+ * Execute the touch operation.
+ *
+ * @throws BuildException
+ * if an error occurs.
+ */
+ public void execute() throws BuildException {
+ checkConfiguration();
+ touch();
+ }
+
+ /**
+ * Does the actual work; assumes everything has been checked by now.
+ * @throws BuildException if an error occurs.
+ */
+ protected void touch() throws BuildException {
+ long defaultTimestamp = getTimestamp();
+
+ if (file != null) {
+ touch(new FileResource(file.getParentFile(), file.getName()),
+ defaultTimestamp);
+ }
+ if (resources == null) {
+ return;
+ }
+ // deal with the resource collections
+ for (Resource r : resources) {
+ Touchable t = r.as(Touchable.class);
+ if (t == null) {
+ throw new BuildException("Can't touch " + r);
+ }
+ touch(r, defaultTimestamp);
+ }
+
+ // deal with filesets in a special way since the task
+ // originally also used the directories and Union won't return
+ // them.
+ final int size = filesets.size();
+ for (int i = 0; i < size; i++) {
+ FileSet fs = (FileSet) filesets.elementAt(i);
+ DirectoryScanner ds = fs.getDirectoryScanner(getProject());
+ File fromDir = fs.getDir(getProject());
+
+ String[] srcDirs = ds.getIncludedDirectories();
+
+ for (int j = 0; j < srcDirs.length; j++) {
+ touch(new FileResource(fromDir, srcDirs[j]), defaultTimestamp);
+ }
+ }
+ }
+
+ /**
+ * Touch a single file with the current timestamp (this.millis). This method
+ * does not interact with any nested mappers and remains for reasons of
+ * backwards-compatibility only.
+ * @param file file to touch
+ * @throws BuildException on error
+ * @deprecated since 1.6.x.
+ */
+ protected void touch(File file) {
+ touch(file, getTimestamp());
+ }
+
+ private long getTimestamp() {
+ return (millis < 0) ? System.currentTimeMillis() : millis;
+ }
+
+ private void touch(Resource r, long defaultTimestamp) {
+ if (fileNameMapper == null) {
+ FileProvider fp = r.as(FileProvider.class);
+ if (fp != null) {
+ // use this to create file and deal with non-writable files
+ touch(fp.getFile(), defaultTimestamp);
+ } else {
+ r.as(Touchable.class).touch(defaultTimestamp);
+ }
+ } else {
+ String[] mapped = fileNameMapper.mapFileName(r.getName());
+ if (mapped != null && mapped.length > 0) {
+ long modTime = defaultTimestamp;
+ if (millis < 0 && r.isExists()) {
+ modTime = r.getLastModified();
+ }
+ for (int i = 0; i < mapped.length; i++) {
+ touch(getProject().resolveFile(mapped[i]), modTime);
+ }
+ }
+ }
+ }
+
+ private void touch(File file, long modTime) {
+ if (!file.exists()) {
+ log("Creating " + file,
+ ((verbose) ? Project.MSG_INFO : Project.MSG_VERBOSE));
+ try {
+ FILE_UTILS.createNewFile(file, mkdirs);
+ } catch (IOException ioe) {
+ throw new BuildException("Could not create " + file, ioe,
+ getLocation());
+ }
+ }
+ if (!file.canWrite()) {
+ throw new BuildException("Can not change modification date of "
+ + "read-only file " + file);
+ }
+ FILE_UTILS.setFileLastModified(file, modTime);
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Transform.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Transform.java
new file mode 100644
index 00000000..9fd15d1f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Transform.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+/**
+ * Has been merged into ExecuteOn, empty class for backwards compatibility.
+ * We leave that in case that external programs access this class directly,
+ * for example via
+ * <tt> Transform tr = (Transform) getProject().createTask("apply") </tt>
+ *
+ * @ant.task ignore="true"
+ */
+public class Transform extends ExecuteOn {
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Truncate.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Truncate.java
new file mode 100644
index 00000000..fe5e9a7a
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Truncate.java
@@ -0,0 +1,205 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.ResourceCollection;
+import org.apache.tools.ant.types.resources.FileProvider;
+import org.apache.tools.ant.types.resources.FileResource;
+import org.apache.tools.ant.util.FileUtils;
+
+/**
+ * Set the length of one or more files, as the intermittently available
+ * <code>truncate</code> Unix utility/function.
+ * @since Ant 1.7.1
+ */
+public class Truncate extends Task {
+
+ private static final int BUFFER_SIZE = 1024;
+
+ private static final Long ZERO = new Long(0L);
+
+ private static final String NO_CHILD = "No files specified.";
+
+ private static final String INVALID_LENGTH = "Cannot truncate to length ";
+
+ private static final String READ_WRITE = "rw";
+
+ private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+
+ private static final byte[] FILL_BUFFER = new byte[BUFFER_SIZE];
+
+ private Path path;
+ private boolean create = true;
+ private boolean mkdirs = false;
+
+ private Long length;
+ private Long adjust;
+
+ /**
+ * Set a single target File.
+ * @param f the single File
+ */
+ public void setFile(File f) {
+ add(new FileResource(f));
+ }
+
+ /**
+ * Add a nested (filesystem-only) ResourceCollection.
+ * @param rc the ResourceCollection to add.
+ */
+ public void add(ResourceCollection rc) {
+ getPath().add(rc);
+ }
+
+ /**
+ * Set the amount by which files' lengths should be adjusted.
+ * It is permissible to append K / M / G / T / P.
+ * @param adjust (positive or negative) adjustment amount.
+ */
+ public void setAdjust(Long adjust) {
+ this.adjust = adjust;
+ }
+
+ /**
+ * Set the length to which files should be set.
+ * It is permissible to append K / M / G / T / P.
+ * @param length (positive) adjustment amount.
+ */
+ public void setLength(Long length) {
+ this.length = length;
+ if (length != null && length.longValue() < 0) {
+ throw new BuildException(INVALID_LENGTH + length);
+ }
+ }
+
+ /**
+ * Set whether to create nonexistent files.
+ * @param create boolean, default <code>true</code>.
+ */
+ public void setCreate(boolean create) {
+ this.create = create;
+ }
+
+ /**
+ * Set whether, when creating nonexistent files, nonexistent directories
+ * should also be created.
+ * @param mkdirs boolean, default <code>false</code>.
+ */
+ public void setMkdirs(boolean mkdirs) {
+ this.mkdirs = mkdirs;
+ }
+
+ /** {@inheritDoc}. */
+ public void execute() {
+ if (length != null && adjust != null) {
+ throw new BuildException(
+ "length and adjust are mutually exclusive options");
+ }
+ if (length == null && adjust == null) {
+ length = ZERO;
+ }
+ if (path == null) {
+ throw new BuildException(NO_CHILD);
+ }
+ for (Resource r : path) {
+ File f = r.as(FileProvider.class).getFile();
+ if (shouldProcess(f)) {
+ process(f);
+ }
+ }
+ }
+
+ private boolean shouldProcess(File f) {
+ if (f.isFile()) {
+ return true;
+ }
+ if (!create) {
+ return false;
+ }
+ Exception exception = null;
+ try {
+ if (FILE_UTILS.createNewFile(f, mkdirs)) {
+ return true;
+ }
+ } catch (IOException e) {
+ exception = e;
+ }
+ String msg = "Unable to create " + f;
+ if (exception == null) {
+ log(msg, Project.MSG_WARN);
+ return false;
+ }
+ throw new BuildException(msg, exception);
+ }
+
+ private void process(File f) {
+ long len = f.length();
+ long newLength = length == null
+ ? len + adjust.longValue() : length.longValue();
+
+ if (len == newLength) {
+ //nothing to do!
+ return;
+ }
+ RandomAccessFile raf = null;
+ try {
+ raf = new RandomAccessFile(f, READ_WRITE);
+ } catch (Exception e) {
+ throw new BuildException("Could not open " + f + " for writing", e);
+ }
+ try {
+ if (newLength > len) {
+ long pos = len;
+ raf.seek(pos);
+ while (pos < newLength) {
+ long writeCount = Math.min(FILL_BUFFER.length,
+ newLength - pos);
+ raf.write(FILL_BUFFER, 0, (int) writeCount);
+ pos += writeCount;
+ }
+ } else {
+ raf.setLength(newLength);
+ }
+ } catch (IOException e) {
+ throw new BuildException("Exception working with " + raf, e);
+ } finally {
+ try {
+ raf.close();
+ } catch (IOException e) {
+ log("Caught " + e + " closing " + raf, Project.MSG_WARN);
+ }
+ }
+ }
+
+ private synchronized Path getPath() {
+ if (path == null) {
+ path = new Path(getProject());
+ }
+ return path;
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Tstamp.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Tstamp.java
new file mode 100644
index 00000000..805427ab
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Tstamp.java
@@ -0,0 +1,341 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.StringTokenizer;
+import java.util.TimeZone;
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Location;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.types.EnumeratedAttribute;
+
+/**
+ * Sets properties to the current time, or offsets from the current time.
+ * The default properties are TSTAMP, DSTAMP and TODAY;
+ *
+ * @since Ant 1.1
+ * @ant.task category="utility"
+ */
+public class Tstamp extends Task {
+
+ private Vector customFormats = new Vector();
+ private String prefix = "";
+
+ /**
+ * Set a prefix for the properties. If the prefix does not end with a "."
+ * one is automatically added.
+ * @param prefix the prefix to use.
+ * @since Ant 1.5
+ */
+ public void setPrefix(String prefix) {
+ this.prefix = prefix;
+ if (!this.prefix.endsWith(".")) {
+ this.prefix += ".";
+ }
+ }
+
+ /**
+ * create the timestamps. Custom ones are done before
+ * the standard ones, to get their retaliation in early.
+ * @throws BuildException on error.
+ */
+ public void execute() throws BuildException {
+ try {
+ Date d = new Date();
+
+ Enumeration i = customFormats.elements();
+ while (i.hasMoreElements()) {
+ CustomFormat cts = (CustomFormat) i.nextElement();
+ cts.execute(getProject(), d, getLocation());
+ }
+
+ SimpleDateFormat dstamp = new SimpleDateFormat ("yyyyMMdd");
+ setProperty("DSTAMP", dstamp.format(d));
+
+ SimpleDateFormat tstamp = new SimpleDateFormat ("HHmm");
+ setProperty("TSTAMP", tstamp.format(d));
+
+ SimpleDateFormat today
+ = new SimpleDateFormat ("MMMM d yyyy", Locale.US);
+ setProperty("TODAY", today.format(d));
+
+ } catch (Exception e) {
+ throw new BuildException(e);
+ }
+ }
+
+ /**
+ * create a custom format with the current prefix.
+ * @return a ready to fill-in format
+ */
+ public CustomFormat createFormat() {
+ CustomFormat cts = new CustomFormat();
+ customFormats.addElement(cts);
+ return cts;
+ }
+
+ /**
+ * helper that encapsulates prefix logic and property setting
+ * policy (i.e. we use setNewProperty instead of setProperty).
+ */
+ private void setProperty(String name, String value) {
+ getProject().setNewProperty(prefix + name, value);
+ }
+
+ /**
+ * This nested element that allows a property to be set
+ * to the current date and time in a given format.
+ * The date/time patterns are as defined in the
+ * Java SimpleDateFormat class.
+ * The format element also allows offsets to be applied to
+ * the time to generate different time values.
+ * @todo consider refactoring out into a re-usable element.
+ */
+ public class CustomFormat {
+ private TimeZone timeZone;
+ private String propertyName;
+ private String pattern;
+ private String language;
+ private String country;
+ private String variant;
+ private int offset = 0;
+ private int field = Calendar.DATE;
+
+ /**
+ * Create a format
+ */
+ public CustomFormat() {
+ }
+
+ /**
+ * The property to receive the date/time string in the given pattern
+ * @param propertyName the name of the property.
+ */
+ public void setProperty(String propertyName) {
+ this.propertyName = propertyName;
+ }
+
+ /**
+ * The date/time pattern to be used. The values are as
+ * defined by the Java SimpleDateFormat class.
+ * @param pattern the pattern to use.
+ * @see java.text.SimpleDateFormat
+ */
+ public void setPattern(String pattern) {
+ this.pattern = pattern;
+ }
+
+ /**
+ * The locale used to create date/time string.
+ * The general form is "language, country, variant" but
+ * either variant or variant and country may be omitted.
+ * For more information please refer to documentation
+ * for the java.util.Locale class.
+ * @param locale the locale to use.
+ * @see java.util.Locale
+ */
+ public void setLocale(String locale) {
+ StringTokenizer st = new StringTokenizer(locale, " \t\n\r\f,");
+ try {
+ language = st.nextToken();
+ if (st.hasMoreElements()) {
+ country = st.nextToken();
+ if (st.hasMoreElements()) {
+ variant = st.nextToken();
+ if (st.hasMoreElements()) {
+ throw new BuildException("bad locale format",
+ getLocation());
+ }
+ }
+ } else {
+ country = "";
+ }
+ } catch (NoSuchElementException e) {
+ throw new BuildException("bad locale format", e,
+ getLocation());
+ }
+ }
+
+ /**
+ * The timezone to use for displaying time.
+ * The values are as defined by the Java TimeZone class.
+ * @param id the timezone value.
+ * @see java.util.TimeZone
+ */
+ public void setTimezone(String id) {
+ timeZone = TimeZone.getTimeZone(id);
+ }
+
+ /**
+ * The numeric offset to the current time.
+ * @param offset the offset to use.
+ */
+ public void setOffset(int offset) {
+ this.offset = offset;
+ }
+
+ /**
+ * Set the unit type (using String).
+ * @param unit the unit to use.
+ * @deprecated since 1.5.x.
+ * setUnit(String) is deprecated and is replaced with
+ * setUnit(Tstamp.Unit) to make Ant's
+ * Introspection mechanism do the work and also to
+ * encapsulate operations on the unit in its own
+ * class.
+ */
+ public void setUnit(String unit) {
+ log("DEPRECATED - The setUnit(String) method has been deprecated."
+ + " Use setUnit(Tstamp.Unit) instead.");
+ Unit u = new Unit();
+ u.setValue(unit);
+ field = u.getCalendarField();
+ }
+
+ /**
+ * The unit of the offset to be applied to the current time.
+ * Valid Values are
+ * <ul>
+ * <li>millisecond</li>
+ * <li>second</li>
+ * <li>minute</li>
+ * <li>hour</li>
+ * <li>day</li>
+ * <li>week</li>
+ * <li>month</li>
+ * <li>year</li>
+ * </ul>
+ * The default unit is day.
+ * @param unit the unit to use.
+ */
+ public void setUnit(Unit unit) {
+ field = unit.getCalendarField();
+ }
+
+ /**
+ * validate parameter and execute the format.
+ * @param project project to set property in.
+ * @param date date to use as a starting point.
+ * @param location line in file (for errors)
+ */
+ public void execute(Project project, Date date, Location location) {
+ if (propertyName == null) {
+ throw new BuildException("property attribute must be provided",
+ location);
+ }
+
+ if (pattern == null) {
+ throw new BuildException("pattern attribute must be provided",
+ location);
+ }
+
+ SimpleDateFormat sdf;
+ if (language == null) {
+ sdf = new SimpleDateFormat(pattern);
+ } else if (variant == null) {
+ sdf = new SimpleDateFormat(pattern,
+ new Locale(language, country));
+ } else {
+ sdf = new SimpleDateFormat(pattern,
+ new Locale(language, country,
+ variant));
+ }
+ if (offset != 0) {
+ Calendar calendar = Calendar.getInstance();
+ calendar.setTime(date);
+ calendar.add(field, offset);
+ date = calendar.getTime();
+ }
+ if (timeZone != null) {
+ sdf.setTimeZone(timeZone);
+ }
+ Tstamp.this.setProperty(propertyName, sdf.format(date));
+ }
+ }
+
+ /**
+ * set of valid units to use for time offsets.
+ */
+ public static class Unit extends EnumeratedAttribute {
+
+ private static final String MILLISECOND = "millisecond";
+ private static final String SECOND = "second";
+ private static final String MINUTE = "minute";
+ private static final String HOUR = "hour";
+ private static final String DAY = "day";
+ private static final String WEEK = "week";
+ private static final String MONTH = "month";
+ private static final String YEAR = "year";
+
+ private static final String[] UNITS = {
+ MILLISECOND,
+ SECOND,
+ MINUTE,
+ HOUR,
+ DAY,
+ WEEK,
+ MONTH,
+ YEAR
+ };
+
+ private Map calendarFields = new HashMap();
+
+ /** Constructor for Unit enumerated type. */
+ public Unit() {
+ calendarFields.put(MILLISECOND,
+ new Integer(Calendar.MILLISECOND));
+ calendarFields.put(SECOND, new Integer(Calendar.SECOND));
+ calendarFields.put(MINUTE, new Integer(Calendar.MINUTE));
+ calendarFields.put(HOUR, new Integer(Calendar.HOUR_OF_DAY));
+ calendarFields.put(DAY, new Integer(Calendar.DATE));
+ calendarFields.put(WEEK, new Integer(Calendar.WEEK_OF_YEAR));
+ calendarFields.put(MONTH, new Integer(Calendar.MONTH));
+ calendarFields.put(YEAR, new Integer(Calendar.YEAR));
+ }
+
+ /**
+ * Convert the value to int unit value.
+ * @return an int value.
+ */
+ public int getCalendarField() {
+ String key = getValue().toLowerCase(Locale.ENGLISH);
+ Integer i = (Integer) calendarFields.get(key);
+ return i.intValue();
+ }
+
+ /**
+ * Get the valid values.
+ * @return the value values.
+ */
+ public String[] getValues() {
+ return UNITS;
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Typedef.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Typedef.java
new file mode 100644
index 00000000..87276e2e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Typedef.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+
+
+/**
+ *
+ * Adds a data type definition to the current project.
+ * Two attributes are
+ * needed, the name that identifies this data type uniquely, and the full
+ * name of the class (including the packages) that implements this
+ * type.
+ * <p>You can also define a group of data types at once using the file or
+ * resource attributes. These attributes point to files in the format of
+ * Java property files. Each line defines a single data type in the
+ * format:</p>
+ * <pre>
+ * typename=fully.qualified.java.classname
+ * </pre>
+ * <p>Typedef should be used to add your own types to the system. Data
+ * types are things likepaths or filesets that can be defined at
+ * the project level and referenced via their ID attribute.</p>
+ * <p>Custom data types usually need custom tasks to put them to good use.</p>
+ *
+ * @since Ant 1.4
+ * @ant.task category="internal"
+ */
+public class Typedef extends Definer {
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Unpack.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Unpack.java
new file mode 100644
index 00000000..8640f8fb
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Unpack.java
@@ -0,0 +1,195 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+
+import java.io.File;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.ResourceCollection;
+import org.apache.tools.ant.types.resources.FileProvider;
+import org.apache.tools.ant.types.resources.FileResource;
+
+/**
+ * Abstract Base class for unpack tasks.
+ *
+ * @since Ant 1.5
+ */
+
+public abstract class Unpack extends Task {
+ // CheckStyle:VisibilityModifier OFF - bc
+ protected File source;
+ protected File dest;
+ protected Resource srcResource;
+ // CheckStyle:VisibilityModifier ON
+
+ /**
+ * @deprecated since 1.5.x.
+ * setSrc(String) is deprecated and is replaced with
+ * setSrc(File) to make Ant's Introspection
+ * mechanism do the work and also to encapsulate operations on
+ * the type in its own class.
+ * @ant.attribute ignore="true"
+ * @param src a <code>String</code> value
+ */
+ public void setSrc(String src) {
+ log("DEPRECATED - The setSrc(String) method has been deprecated."
+ + " Use setSrc(File) instead.");
+ setSrc(getProject().resolveFile(src));
+ }
+
+ /**
+ * @deprecated since 1.5.x.
+ * setDest(String) is deprecated and is replaced with
+ * setDest(File) to make Ant's Introspection
+ * mechanism do the work and also to encapsulate operations on
+ * the type in its own class.
+ * @ant.attribute ignore="true"
+ * @param dest a <code>String</code> value
+ */
+ public void setDest(String dest) {
+ log("DEPRECATED - The setDest(String) method has been deprecated."
+ + " Use setDest(File) instead.");
+ setDest(getProject().resolveFile(dest));
+ }
+
+ /**
+ * The file to expand; required.
+ * @param src file to expand
+ */
+ public void setSrc(File src) {
+ setSrcResource(new FileResource(src));
+ }
+
+ /**
+ * The resource to expand; required.
+ * @param src resource to expand
+ */
+ public void setSrcResource(Resource src) {
+ if (!src.isExists()) {
+ throw new BuildException(
+ "the archive " + src.getName() + " doesn't exist");
+ }
+ if (src.isDirectory()) {
+ throw new BuildException(
+ "the archive " + src.getName() + " can't be a directory");
+ }
+ FileProvider fp = src.as(FileProvider.class);
+ if (fp != null) {
+ source = fp.getFile();
+ } else if (!supportsNonFileResources()) {
+ throw new BuildException(
+ "The source " + src.getName()
+ + " is not a FileSystem "
+ + "Only FileSystem resources are"
+ + " supported.");
+ }
+ srcResource = src;
+ }
+
+ /**
+ * Set the source Archive resource.
+ * @param a the archive as a single element Resource collection.
+ */
+ public void addConfigured(ResourceCollection a) {
+ if (a.size() != 1) {
+ throw new BuildException("only single argument resource collections"
+ + " are supported as archives");
+ }
+ setSrcResource(a.iterator().next());
+ }
+
+ /**
+ * The destination file or directory; optional.
+ * @param dest destination file or directory
+ */
+ public void setDest(File dest) {
+ this.dest = dest;
+ }
+
+ private void validate() throws BuildException {
+ if (srcResource == null) {
+ throw new BuildException("No Src specified", getLocation());
+ }
+
+ if (dest == null) {
+ dest = new File(source.getParent());
+ }
+
+ if (dest.isDirectory()) {
+ String defaultExtension = getDefaultExtension();
+ createDestFile(defaultExtension);
+ }
+ }
+
+ private void createDestFile(String defaultExtension) {
+ String sourceName = source.getName();
+ int len = sourceName.length();
+ if (defaultExtension != null
+ && len > defaultExtension.length()
+ && defaultExtension.equalsIgnoreCase(
+ sourceName.substring(len - defaultExtension.length()))) {
+ dest = new File(dest, sourceName.substring(0,
+ len - defaultExtension.length()));
+ } else {
+ dest = new File(dest, sourceName);
+ }
+ }
+
+ /**
+ * Execute the task.
+ * @throws BuildException on error
+ */
+ public void execute() throws BuildException {
+ File savedDest = dest; // may be altered in validate
+ try {
+ validate();
+ extract();
+ } finally {
+ dest = savedDest;
+ }
+ }
+
+ /**
+ * Get the extension.
+ * This is to be overridden by subclasses.
+ * @return the default extension.
+ */
+ protected abstract String getDefaultExtension();
+
+ /**
+ * Do the uncompressing.
+ * This is to be overridden by subclasses.
+ */
+ protected abstract void extract();
+
+ /**
+ * Whether this task can deal with non-file resources.
+ *
+ * <p>This implementation returns false.</p>
+ * @return false for this task.
+ * @since Ant 1.7
+ */
+ protected boolean supportsNonFileResources() {
+ return false;
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Untar.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Untar.java
new file mode 100644
index 00000000..8343aec5
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Untar.java
@@ -0,0 +1,244 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.zip.GZIPInputStream;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.EnumeratedAttribute;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.util.FileNameMapper;
+import org.apache.tools.ant.util.FileUtils;
+import org.apache.tools.bzip2.CBZip2InputStream;
+import org.apache.tools.tar.TarEntry;
+import org.apache.tools.tar.TarInputStream;
+
+
+
+/**
+ * Untar a file.
+ * <p>PatternSets are used to select files to extract
+ * <I>from</I> the archive. If no patternset is used, all files are extracted.
+ * </p>
+ * <p>FileSets may be used to select archived files
+ * to perform unarchival upon.
+ * </p>
+ * <p>File permissions will not be restored on extracted files.</p>
+ * <p>The untar task recognizes the long pathname entries used by GNU tar.<p>
+ *
+ * @since Ant 1.1
+ *
+ * @ant.task category="packaging"
+ */
+public class Untar extends Expand {
+ /**
+ * compression method
+ */
+ private UntarCompressionMethod compression = new UntarCompressionMethod();
+
+ public Untar() {
+ super(null);
+ }
+
+ /**
+ * Set decompression algorithm to use; default=none.
+ *
+ * Allowable values are
+ * <ul>
+ * <li>none - no compression
+ * <li>gzip - Gzip compression
+ * <li>bzip2 - Bzip2 compression
+ * </ul>
+ *
+ * @param method compression method
+ */
+ public void setCompression(UntarCompressionMethod method) {
+ compression = method;
+ }
+
+ /**
+ * No unicode extra fields in tar.
+ *
+ * @since Ant 1.8.0
+ */
+ public void setScanForUnicodeExtraFields(boolean b) {
+ throw new BuildException("The " + getTaskName()
+ + " task doesn't support the encoding"
+ + " attribute", getLocation());
+ }
+
+ /**
+ * @see Expand#expandFile(FileUtils, File, File)
+ */
+ /** {@inheritDoc} */
+ protected void expandFile(FileUtils fileUtils, File srcF, File dir) {
+ FileInputStream fis = null;
+ if (!srcF.exists()) {
+ throw new BuildException("Unable to untar "
+ + srcF
+ + " as the file does not exist",
+ getLocation());
+ }
+ try {
+ fis = new FileInputStream(srcF);
+ expandStream(srcF.getPath(), fis, dir);
+ } catch (IOException ioe) {
+ throw new BuildException("Error while expanding " + srcF.getPath()
+ + "\n" + ioe.toString(),
+ ioe, getLocation());
+ } finally {
+ FileUtils.close(fis);
+ }
+ }
+
+ /**
+ * This method is to be overridden by extending unarchival tasks.
+ *
+ * @param srcR the source resource
+ * @param dir the destination directory
+ * @since Ant 1.7
+ */
+ protected void expandResource(Resource srcR, File dir) {
+ if (!srcR.isExists()) {
+ throw new BuildException("Unable to untar "
+ + srcR.getName()
+ + " as the it does not exist",
+ getLocation());
+ }
+
+ InputStream i = null;
+ try {
+ i = srcR.getInputStream();
+ expandStream(srcR.getName(), i, dir);
+ } catch (IOException ioe) {
+ throw new BuildException("Error while expanding " + srcR.getName(),
+ ioe, getLocation());
+ } finally {
+ FileUtils.close(i);
+ }
+ }
+
+ /**
+ * @since Ant 1.7
+ */
+ private void expandStream(String name, InputStream stream, File dir)
+ throws IOException {
+ TarInputStream tis = null;
+ try {
+ tis =
+ new TarInputStream(compression.decompress(name,
+ new BufferedInputStream(stream)),
+ getEncoding());
+ log("Expanding: " + name + " into " + dir, Project.MSG_INFO);
+ TarEntry te = null;
+ boolean empty = true;
+ FileNameMapper mapper = getMapper();
+ while ((te = tis.getNextEntry()) != null) {
+ empty = false;
+ extractFile(FileUtils.getFileUtils(), null, dir, tis,
+ te.getName(), te.getModTime(),
+ te.isDirectory(), mapper);
+ }
+ if (empty && getFailOnEmptyArchive()) {
+ throw new BuildException("archive '" + name + "' is empty");
+ }
+ log("expand complete", Project.MSG_VERBOSE);
+ } finally {
+ FileUtils.close(tis);
+ }
+ }
+
+ /**
+ * Valid Modes for Compression attribute to Untar Task
+ *
+ */
+ public static final class UntarCompressionMethod
+ extends EnumeratedAttribute {
+
+ // permissible values for compression attribute
+ /**
+ * No compression
+ */
+ private static final String NONE = "none";
+ /**
+ * GZIP compression
+ */
+ private static final String GZIP = "gzip";
+ /**
+ * BZIP2 compression
+ */
+ private static final String BZIP2 = "bzip2";
+
+
+ /**
+ * Constructor
+ */
+ public UntarCompressionMethod() {
+ super();
+ setValue(NONE);
+ }
+
+ /**
+ * Get valid enumeration values
+ *
+ * @return valid values
+ */
+ public String[] getValues() {
+ return new String[] {NONE, GZIP, BZIP2};
+ }
+
+ /**
+ * This method wraps the input stream with the
+ * corresponding decompression method
+ *
+ * @param name provides location information for BuildException
+ * @param istream input stream
+ * @return input stream with on-the-fly decompression
+ * @exception IOException thrown by GZIPInputStream constructor
+ * @exception BuildException thrown if bzip stream does not
+ * start with expected magic values
+ */
+ public InputStream decompress(final String name,
+ final InputStream istream)
+ throws IOException, BuildException {
+ final String v = getValue();
+ if (GZIP.equals(v)) {
+ return new GZIPInputStream(istream);
+ } else {
+ if (BZIP2.equals(v)) {
+ final char[] magic = new char[] {'B', 'Z'};
+ for (int i = 0; i < magic.length; i++) {
+ if (istream.read() != magic[i]) {
+ throw new BuildException(
+ "Invalid bz2 file." + name);
+ }
+ }
+ return new CBZip2InputStream(istream);
+ }
+ }
+ return istream;
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/UpToDate.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/UpToDate.java
new file mode 100644
index 00000000..e5c85ce1
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/UpToDate.java
@@ -0,0 +1,277 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.io.File;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.DirectoryScanner;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.taskdefs.condition.Condition;
+import org.apache.tools.ant.types.FileSet;
+import org.apache.tools.ant.types.Mapper;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.resources.Union;
+import org.apache.tools.ant.util.FileNameMapper;
+import org.apache.tools.ant.util.MergingMapper;
+import org.apache.tools.ant.util.ResourceUtils;
+import org.apache.tools.ant.util.SourceFileScanner;
+
+/**
+ * Sets the given property if the specified target has a timestamp
+ * greater than all of the source files.
+ *
+ * @since Ant 1.2
+ *
+ * @ant.task category="control"
+ */
+
+public class UpToDate extends Task implements Condition {
+
+ private String property;
+ private String value;
+ private File sourceFile;
+ private File targetFile;
+ private Vector sourceFileSets = new Vector();
+ private Union sourceResources = new Union();
+
+ // CheckStyle:VisibilityModifier OFF - bc
+ protected Mapper mapperElement = null;
+ // CheckStyle:VisibilityModifier ON
+
+ /**
+ * The property to set if the target file is more up-to-date than
+ * (each of) the source file(s).
+ *
+ * @param property the name of the property to set if Target is up-to-date.
+ */
+ public void setProperty(final String property) {
+ this.property = property;
+ }
+
+ /**
+ * The value to set the named property to if the target file is more
+ * up-to-date than (each of) the source file(s). Defaults to 'true'.
+ *
+ * @param value the value to set the property to if Target is up-to-date
+ */
+ public void setValue(final String value) {
+ this.value = value;
+ }
+
+ /**
+ * Returns the value, or "true" if a specific value wasn't provided.
+ */
+ private String getValue() {
+ return (value != null) ? value : "true";
+ }
+
+ /**
+ * The file which must be more up-to-date than (each of) the source file(s)
+ * if the property is to be set.
+ *
+ * @param file the file we are checking against.
+ */
+ public void setTargetFile(final File file) {
+ this.targetFile = file;
+ }
+
+ /**
+ * The file that must be older than the target file
+ * if the property is to be set.
+ *
+ * @param file the file we are checking against the target file.
+ */
+ public void setSrcfile(final File file) {
+ this.sourceFile = file;
+ }
+
+ /**
+ * Nested &lt;srcfiles&gt; element.
+ * @param fs the source files
+ */
+ public void addSrcfiles(final FileSet fs) {
+ sourceFileSets.addElement(fs);
+ }
+
+ /**
+ * Nested resource collections as sources.
+ * @return the source resources to configure.
+ * @since Ant 1.7
+ */
+ public Union createSrcResources() {
+ return sourceResources;
+ }
+
+ /**
+ * Defines the FileNameMapper to use (nested mapper element).
+ * @return a mapper to be configured
+ * @throws BuildException if more than one mapper is defined
+ */
+ public Mapper createMapper() throws BuildException {
+ if (mapperElement != null) {
+ throw new BuildException("Cannot define more than one mapper",
+ getLocation());
+ }
+ mapperElement = new Mapper(getProject());
+ return mapperElement;
+ }
+
+ /**
+ * A nested filenamemapper
+ * @param fileNameMapper the mapper to add
+ * @since Ant 1.6.3
+ */
+ public void add(FileNameMapper fileNameMapper) {
+ createMapper().add(fileNameMapper);
+ }
+
+ /**
+ * Evaluate (all) target and source file(s) to
+ * see if the target(s) is/are up-to-date.
+ * @return true if the target(s) is/are up-to-date
+ */
+ public boolean eval() {
+ if (sourceFileSets.size() == 0 && sourceResources.size() == 0
+ && sourceFile == null) {
+ throw new BuildException("At least one srcfile or a nested "
+ + "<srcfiles> or <srcresources> element "
+ + "must be set.");
+ }
+
+ if ((sourceFileSets.size() > 0 || sourceResources.size() > 0)
+ && sourceFile != null) {
+ throw new BuildException("Cannot specify both the srcfile "
+ + "attribute and a nested <srcfiles> "
+ + "or <srcresources> element.");
+ }
+
+ if (targetFile == null && mapperElement == null) {
+ throw new BuildException("The targetfile attribute or a nested "
+ + "mapper element must be set.");
+ }
+
+ // if the target file is not there, then it can't be up-to-date
+ if (targetFile != null && !targetFile.exists()) {
+ log("The targetfile \"" + targetFile.getAbsolutePath()
+ + "\" does not exist.", Project.MSG_VERBOSE);
+ return false;
+ }
+
+ // if the source file isn't there, throw an exception
+ if (sourceFile != null && !sourceFile.exists()) {
+ throw new BuildException(sourceFile.getAbsolutePath()
+ + " not found.");
+ }
+
+ boolean upToDate = true;
+ if (sourceFile != null) {
+ if (mapperElement == null) {
+ upToDate = targetFile.lastModified() >= sourceFile.lastModified();
+ } else {
+ SourceFileScanner sfs = new SourceFileScanner(this);
+ upToDate = sfs.restrict(new String[] {sourceFile.getAbsolutePath()},
+ null, null,
+ mapperElement.getImplementation()).length == 0;
+ }
+ if (!upToDate) {
+ log(sourceFile.getAbsolutePath()
+ + " is newer than (one of) its target(s).",
+ Project.MSG_VERBOSE);
+ }
+ }
+
+ // filesets are separate from the rest for performance
+ // reasons. If we use the code for union below, we'll always
+ // scan all filesets, even if we know the target is out of
+ // date after the first test.
+ Enumeration e = sourceFileSets.elements();
+ while (upToDate && e.hasMoreElements()) {
+ FileSet fs = (FileSet) e.nextElement();
+ DirectoryScanner ds = fs.getDirectoryScanner(getProject());
+ upToDate = scanDir(fs.getDir(getProject()),
+ ds.getIncludedFiles());
+ }
+
+ if (upToDate) {
+ Resource[] r = sourceResources.listResources();
+ if (r.length > 0) {
+ upToDate = ResourceUtils.selectOutOfDateSources(
+ this, r, getMapper(), getProject()).length == 0;
+ }
+ }
+
+ return upToDate;
+ }
+
+
+ /**
+ * Sets property to true if target file(s) have a more recent timestamp
+ * than (each of) the corresponding source file(s).
+ * @throws BuildException on error
+ */
+ public void execute() throws BuildException {
+ if (property == null) {
+ throw new BuildException("property attribute is required.",
+ getLocation());
+ }
+ boolean upToDate = eval();
+ if (upToDate) {
+ getProject().setNewProperty(property, getValue());
+ if (mapperElement == null) {
+ log("File \"" + targetFile.getAbsolutePath()
+ + "\" is up-to-date.", Project.MSG_VERBOSE);
+ } else {
+ log("All target files are up-to-date.",
+ Project.MSG_VERBOSE);
+ }
+ }
+ }
+
+ /**
+ * Scan a directory for files to check for "up to date"ness
+ * @param srcDir the directory
+ * @param files the files to scan for
+ * @return true if the files are up to date
+ */
+ protected boolean scanDir(File srcDir, String[] files) {
+ SourceFileScanner sfs = new SourceFileScanner(this);
+ FileNameMapper mapper = getMapper();
+ File dir = srcDir;
+ if (mapperElement == null) {
+ dir = null;
+ }
+ return sfs.restrict(files, srcDir, dir, mapper).length == 0;
+ }
+
+ private FileNameMapper getMapper() {
+ FileNameMapper mapper = null;
+ if (mapperElement == null) {
+ MergingMapper mm = new MergingMapper();
+ mm.setTo(targetFile.getAbsolutePath());
+ mapper = mm;
+ } else {
+ mapper = mapperElement.getImplementation();
+ }
+ return mapper;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/VerifyJar.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/VerifyJar.java
new file mode 100644
index 00000000..4ab21428
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/VerifyJar.java
@@ -0,0 +1,207 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.Reader;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.filters.ChainableReader;
+import org.apache.tools.ant.types.FilterChain;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.types.RedirectorElement;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.resources.FileProvider;
+
+/**
+ * JAR verification task.
+ * For every JAR passed in, we fork jarsigner to verify
+ * that it is correctly signed. This is more rigorous than just checking for
+ * the existence of a signature; the entire certification chain is tested
+ * @since Ant 1.7
+ */
+
+public class VerifyJar extends AbstractJarSignerTask {
+ /**
+ * no file message {@value}
+ */
+ public static final String ERROR_NO_FILE = "Not found :";
+
+ /**
+ * The string we look for in the text to indicate direct verification
+ */
+ private static final String VERIFIED_TEXT = "jar verified.";
+
+ /**
+ * certification flag
+ */
+ private boolean certificates = false;
+ private BufferingOutputFilter outputCache = new BufferingOutputFilter();
+ /** Error output if there is a failure to verify the jar. */
+ public static final String ERROR_NO_VERIFY = "Failed to verify ";
+
+ /**
+ * Ask for certificate information to be printed
+ * @param certificates if true print certificates.
+ */
+ public void setCertificates(boolean certificates) {
+ this.certificates = certificates;
+ }
+
+ /**
+ * verify our jar files
+ * @throws BuildException on error.
+ */
+ public void execute() throws BuildException {
+ //validation logic
+ final boolean hasJar = jar != null;
+
+ if (!hasJar && !hasResources()) {
+ throw new BuildException(ERROR_NO_SOURCE);
+ }
+
+ beginExecution();
+
+ //patch the redirector to save output to a file
+ RedirectorElement redirector = getRedirector();
+ redirector.setAlwaysLog(true);
+ FilterChain outputFilterChain = redirector.createOutputFilterChain();
+ outputFilterChain.add(outputCache);
+
+ try {
+ Path sources = createUnifiedSourcePath();
+ for (Resource r : sources) {
+ FileProvider fr = r.as(FileProvider.class);
+ verifyOneJar(fr.getFile());
+ }
+
+ } finally {
+ endExecution();
+ }
+
+ }
+
+ /**
+ * verify a JAR.
+ * @param jar the jar to verify.
+ * @throws BuildException if the file could not be verified
+ */
+ private void verifyOneJar(File jar) {
+ if (!jar.exists()) {
+ throw new BuildException(ERROR_NO_FILE + jar);
+ }
+ final ExecTask cmd = createJarSigner();
+
+ setCommonOptions(cmd);
+ bindToKeystore(cmd);
+
+ //verify special operations
+ addValue(cmd, "-verify");
+
+ if (certificates) {
+ addValue(cmd, "-certs");
+ }
+
+ //JAR is required
+ addValue(cmd, jar.getPath());
+
+ log("Verifying JAR: " + jar.getAbsolutePath());
+ outputCache.clear();
+ BuildException ex = null;
+ try {
+ cmd.execute();
+ } catch (BuildException e) {
+ ex = e;
+ }
+ String results = outputCache.toString();
+ //deal with jdk1.4.2 bug:
+ if (ex != null) {
+ if (results.indexOf("zip file closed") >= 0) {
+ log("You are running " + JARSIGNER_COMMAND + " against a JVM with"
+ + " a known bug that manifests as an IllegalStateException.",
+ Project.MSG_WARN);
+ } else {
+ throw ex;
+ }
+ }
+ if (results.indexOf(VERIFIED_TEXT) < 0) {
+ throw new BuildException(ERROR_NO_VERIFY + jar);
+ }
+ }
+
+ /**
+ * we are not thread safe here. Do not use on multiple threads at the same time.
+ */
+ private static class BufferingOutputFilter implements ChainableReader {
+
+ private BufferingOutputFilterReader buffer;
+
+ public Reader chain(Reader rdr) {
+ buffer = new BufferingOutputFilterReader(rdr);
+ return buffer;
+ }
+
+ public String toString() {
+ return buffer.toString();
+ }
+
+ public void clear() {
+ if (buffer != null) {
+ buffer.clear();
+ }
+ }
+ }
+
+ /**
+ * catch the output of the buffer
+ */
+ private static class BufferingOutputFilterReader extends Reader {
+
+ private Reader next;
+
+ private StringBuffer buffer = new StringBuffer();
+
+ public BufferingOutputFilterReader(Reader next) {
+ this.next = next;
+ }
+
+ public int read(char[] cbuf, int off, int len) throws IOException {
+ //hand down
+ int result = next.read(cbuf, off, len);
+ //cache
+ buffer.append(cbuf, off, len);
+ //return
+ return result;
+ }
+
+ public void close() throws IOException {
+ next.close();
+ }
+
+ public String toString() {
+ return buffer.toString();
+ }
+
+ public void clear() {
+ buffer = new StringBuffer();
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/WaitFor.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/WaitFor.java
new file mode 100644
index 00000000..d23beabc
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/WaitFor.java
@@ -0,0 +1,277 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.condition.Condition;
+import org.apache.tools.ant.taskdefs.condition.ConditionBase;
+import org.apache.tools.ant.types.EnumeratedAttribute;
+
+/**
+ * Wait for an external event to occur.
+ *
+ * Wait for an external process to start or to complete some
+ * task. This is useful with the <code>parallel</code> task to
+ * synchronize the execution of tests with server startup.
+ *
+ * The following attributes can be specified on a waitfor task:
+ * <ul>
+ * <li>maxwait - maximum length of time to wait before giving up</li>
+ * <li>maxwaitunit - The unit to be used to interpret maxwait attribute</li>
+ * <li>checkevery - amount of time to sleep between each check</li>
+ * <li>checkeveryunit - The unit to be used to interpret checkevery attribute</li>
+ * <li>timeoutproperty - name of a property to set if maxwait has been exceeded.</li>
+ * </ul>
+ *
+ * The maxwaitunit and checkeveryunit are allowed to have the following values:
+ * millisecond, second, minute, hour, day and week. The default is millisecond.
+ *
+ * For programmatic use/subclassing, there are two methods that may be overridden,
+ * <code>processSuccess</code> and <code>processTimeout</code>
+ * @since Ant 1.5
+ *
+ * @ant.task category="control"
+ */
+public class WaitFor extends ConditionBase {
+ /** a millisecond */
+ public static final long ONE_MILLISECOND = 1L;
+ /** a second in milliseconds */
+ public static final long ONE_SECOND = 1000L;
+ /** a minute in milliseconds */
+ public static final long ONE_MINUTE = ONE_SECOND * 60L;
+ /** an hour in milliseconds */
+ public static final long ONE_HOUR = ONE_MINUTE * 60L;
+ /** a day in milliseconds */
+ public static final long ONE_DAY = ONE_HOUR * 24L;
+ /** a week in milliseconds */
+ public static final long ONE_WEEK = ONE_DAY * 7L;
+
+ /** default wait time */
+ public static final long DEFAULT_MAX_WAIT_MILLIS = ONE_MINUTE * 3L;
+ /** default check time */
+ public static final long DEFAULT_CHECK_MILLIS = 500L;
+
+ /** default max wait time in the current unit*/
+ private long maxWait = DEFAULT_MAX_WAIT_MILLIS;
+ private long maxWaitMultiplier = ONE_MILLISECOND;
+ /**
+ * check time in the current unit
+ */
+ private long checkEvery = DEFAULT_CHECK_MILLIS;
+ private long checkEveryMultiplier = ONE_MILLISECOND;
+ private String timeoutProperty;
+
+ /**
+ * Constructor, names this task "waitfor".
+ */
+ public WaitFor() {
+ super("waitfor");
+ }
+
+
+ /**
+ * Constructor that takes the name of the task in the task name.
+ *
+ * @param taskName the name of the task.
+ * @since Ant 1.8
+ */
+ public WaitFor(String taskName) {
+ super(taskName);
+ }
+
+ /**
+ * Set the maximum length of time to wait.
+ * @param time a <code>long</code> value
+ */
+ public void setMaxWait(long time) {
+ maxWait = time;
+ }
+
+
+ /**
+ * Set the max wait time unit
+ * @param unit an enumerated <code>Unit</code> value
+ */
+ public void setMaxWaitUnit(Unit unit) {
+ maxWaitMultiplier = unit.getMultiplier();
+ }
+
+
+
+ /**
+ * Set the time between each check
+ * @param time a <code>long</code> value
+ */
+ public void setCheckEvery(long time) {
+ checkEvery = time;
+ }
+
+ /**
+ * Set the check every time unit
+ * @param unit an enumerated <code>Unit</code> value
+ */
+ public void setCheckEveryUnit(Unit unit) {
+ checkEveryMultiplier = unit.getMultiplier();
+ }
+
+ /**
+ * Name the property to set after a timeout.
+ * @param p the property name
+ */
+ public void setTimeoutProperty(String p) {
+ timeoutProperty = p;
+ }
+
+ /**
+ * Check repeatedly for the specified conditions until they become
+ * true or the timeout expires.
+ * @throws BuildException on error
+ */
+ public void execute() throws BuildException {
+ if (countConditions() > 1) {
+ throw new BuildException("You must not nest more than one "
+ + "condition into "
+ + getTaskName());
+ }
+ if (countConditions() < 1) {
+ throw new BuildException("You must nest a condition into "
+ + getTaskName());
+ }
+ Condition c = (Condition) getConditions().nextElement();
+ try {
+ long maxWaitMillis = calculateMaxWaitMillis();
+ long checkEveryMillis = calculateCheckEveryMillis();
+ long start = System.currentTimeMillis();
+ long end = start + maxWaitMillis;
+
+ while (System.currentTimeMillis() < end) {
+ if (c.eval()) {
+ processSuccess();
+ return;
+ }
+ Thread.sleep(checkEveryMillis);
+ }
+ } catch (InterruptedException e) {
+ log("Task " + getTaskName()
+ + " interrupted, treating as timed out.");
+ }
+ processTimeout();
+ }
+
+ /**
+ * Get the check wait time, in milliseconds.
+ * @since Ant 1.8
+ * @return how long to wait between checks
+ */
+ public long calculateCheckEveryMillis() {
+ return checkEvery * checkEveryMultiplier;
+ }
+
+ /**
+ * Get the maximum wait time, in milliseconds.
+ * @since Ant 1.8
+ * @return how long to wait before timing out
+ */
+ public long calculateMaxWaitMillis() {
+ return maxWait * maxWaitMultiplier;
+ }
+
+ /**
+ * Actions to be taken on a successful waitfor.
+ * This is an override point. The base implementation does nothing.
+ * @since Ant1.7
+ */
+ protected void processSuccess() {
+ log(getTaskName() + ": condition was met", Project.MSG_VERBOSE);
+ }
+
+ /**
+ * Actions to be taken on an unsuccessful wait.
+ * This is an override point. It is where the timeout processing takes place.
+ * The base implementation sets the timeoutproperty if there was a timeout
+ * and the property was defined.
+ * @since Ant1.7
+ */
+ protected void processTimeout() {
+ log(getTaskName() + ": timeout", Project.MSG_VERBOSE);
+ if (timeoutProperty != null) {
+ getProject().setNewProperty(timeoutProperty, "true");
+ }
+ }
+
+ /**
+ * The enumeration of units:
+ * millisecond, second, minute, hour, day, week
+ * @todo we use timestamps in many places, why not factor this out
+ */
+ public static class Unit extends EnumeratedAttribute {
+
+ /** millisecond string */
+ public static final String MILLISECOND = "millisecond";
+ /** second string */
+ public static final String SECOND = "second";
+ /** minute string */
+ public static final String MINUTE = "minute";
+ /** hour string */
+ public static final String HOUR = "hour";
+ /** day string */
+ public static final String DAY = "day";
+ /** week string */
+ public static final String WEEK = "week";
+
+ private static final String[] UNITS = {
+ MILLISECOND, SECOND, MINUTE, HOUR, DAY, WEEK
+ };
+
+ private Map timeTable = new HashMap();
+
+ /** Constructor the Unit enumerated type. */
+ public Unit() {
+ timeTable.put(MILLISECOND, new Long(1L));
+ timeTable.put(SECOND, new Long(ONE_SECOND));
+ timeTable.put(MINUTE, new Long(ONE_MINUTE));
+ timeTable.put(HOUR, new Long(ONE_HOUR));
+ timeTable.put(DAY, new Long(ONE_DAY));
+ timeTable.put(WEEK, new Long(ONE_WEEK));
+ }
+
+ /**
+ * Convert the value to a multipler (millisecond to unit).
+ * @return a multipler (a long value)
+ */
+ public long getMultiplier() {
+ String key = getValue().toLowerCase(Locale.ENGLISH);
+ Long l = (Long) timeTable.get(key);
+ return l.longValue();
+ }
+
+ /**
+ * @see EnumeratedAttribute#getValues()
+ */
+ /** {@inheritDoc} */
+ public String[] getValues() {
+ return UNITS;
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/War.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/War.java
new file mode 100644
index 00000000..7daf08ef
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/War.java
@@ -0,0 +1,233 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.ZipFileSet;
+import org.apache.tools.ant.util.FileUtils;
+import org.apache.tools.zip.ZipOutputStream;
+
+
+/**
+ * <p>An extension of &lt;jar&gt; to create a WAR archive.
+ * Contains special treatment for files that should end up in the
+ * <code>WEB-INF/lib</code>, <code>WEB-INF/classes</code> or
+ * <code>WEB-INF</code> directories of the Web Application Archive.</p>
+ *
+ * <p>(The War task is a shortcut for specifying the particular layout of a WAR file.
+ * The same thing can be accomplished by using the <i>prefix</i> and <i>fullpath</i>
+ * attributes of zipfilesets in a Zip or Jar task.)</p>
+ *
+ * <p>The extended zipfileset element from the zip task
+ * (with attributes <i>prefix</i>, <i>fullpath</i>, and <i>src</i>)
+ * is available in the War task.</p>
+ *
+ * @since Ant 1.2
+ *
+ * @ant.task category="packaging"
+ * @see Jar
+ */
+public class War extends Jar {
+
+ /**
+ * our web.xml deployment descriptor
+ */
+ private File deploymentDescriptor;
+
+ /**
+ * flag set if the descriptor is added
+ */
+ private boolean needxmlfile = true;
+ private File addedWebXmlFile;
+
+ private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+ /** path to web.xml file */
+ private static final String XML_DESCRIPTOR_PATH = "WEB-INF/web.xml";
+
+ /** Constructor for the War Task. */
+ public War() {
+ super();
+ archiveType = "war";
+ emptyBehavior = "create";
+ }
+
+ /**
+ * <i>Deprecated</i> name of the file to create
+ * -use <tt>destfile</tt> instead.
+ * @param warFile the destination file
+ * @deprecated since 1.5.x.
+ * Use setDestFile(File) instead
+ * @ant.attribute ignore="true"
+ */
+ @Deprecated
+ public void setWarfile(File warFile) {
+ setDestFile(warFile);
+ }
+
+ /**
+ * set the deployment descriptor to use (WEB-INF/web.xml);
+ * required unless <tt>update=true</tt>
+ * @param descr the deployment descriptor file
+ */
+ public void setWebxml(File descr) {
+ deploymentDescriptor = descr;
+ if (!deploymentDescriptor.exists()) {
+ throw new BuildException("Deployment descriptor: "
+ + deploymentDescriptor
+ + " does not exist.");
+ }
+
+ // Create a ZipFileSet for this file, and pass it up.
+ ZipFileSet fs = new ZipFileSet();
+ fs.setFile(deploymentDescriptor);
+ fs.setFullpath(XML_DESCRIPTOR_PATH);
+ super.addFileset(fs);
+ }
+
+
+ /**
+ * Set the policy on the web.xml file, that is, whether or not it is needed
+ * @param needxmlfile whether a web.xml file is needed. Default: true
+ */
+ public void setNeedxmlfile(boolean needxmlfile) {
+ this.needxmlfile = needxmlfile;
+ }
+
+ /**
+ * add files under WEB-INF/lib/
+ * @param fs the zip file set to add
+ */
+
+ public void addLib(ZipFileSet fs) {
+ // We just set the prefix for this fileset, and pass it up.
+ fs.setPrefix("WEB-INF/lib/");
+ super.addFileset(fs);
+ }
+
+ /**
+ * add files under WEB-INF/classes
+ * @param fs the zip file set to add
+ */
+ public void addClasses(ZipFileSet fs) {
+ // We just set the prefix for this fileset, and pass it up.
+ fs.setPrefix("WEB-INF/classes/");
+ super.addFileset(fs);
+ }
+
+ /**
+ * files to add under WEB-INF;
+ * @param fs the zip file set to add
+ */
+ public void addWebinf(ZipFileSet fs) {
+ // We just set the prefix for this fileset, and pass it up.
+ fs.setPrefix("WEB-INF/");
+ super.addFileset(fs);
+ }
+
+ /**
+ * override of parent; validates configuration
+ * before initializing the output stream.
+ * @param zOut the zip output stream
+ * @throws IOException on output error
+ * @throws BuildException if invalid configuration
+ */
+ @Override
+ protected void initZipOutputStream(ZipOutputStream zOut)
+ throws IOException, BuildException {
+ super.initZipOutputStream(zOut);
+ }
+
+ /**
+ * Overridden from Zip class to deal with web.xml
+ *
+ * Here are cases that can arise
+ * -not a web.xml file : add
+ * -first web.xml : add, remember we added it
+ * -same web.xml again: skip
+ * -alternate web.xml : warn and skip
+ *
+ * @param file the file to add to the archive
+ * @param zOut the stream to write to
+ * @param vPath the name this entry shall have in the archive
+ * @param mode the Unix permissions to set.
+ * @throws IOException on output error
+ */
+ @Override
+ protected void zipFile(File file, ZipOutputStream zOut, String vPath,
+ int mode)
+ throws IOException {
+ // If the file being added is WEB-INF/web.xml, we warn if it's
+ // not the one specified in the "webxml" attribute - or if
+ // it's being added twice, meaning the same file is specified
+ // by the "webxml" attribute and in a <fileset> element.
+ //by default, we add the file.
+ boolean addFile = true;
+ if (XML_DESCRIPTOR_PATH.equalsIgnoreCase(vPath)) {
+ //a web.xml file was found. See if it is a duplicate or not
+ if (addedWebXmlFile != null) {
+ //a second web.xml file, so skip it
+ addFile = false;
+ //check to see if we warn or not
+ if (!FILE_UTILS.fileNameEquals(addedWebXmlFile, file)) {
+ logWhenWriting("Warning: selected " + archiveType
+ + " files include a second "
+ + XML_DESCRIPTOR_PATH
+ + " which will be ignored.\n"
+ + "The duplicate entry is at " + file + '\n'
+ + "The file that will be used is "
+ + addedWebXmlFile,
+ Project.MSG_WARN);
+ }
+ } else {
+ //no added file, yet
+ addedWebXmlFile = file;
+ //there is no web.xml file, so add it
+ addFile = true;
+ //and remember that we did
+ deploymentDescriptor = file;
+ }
+ }
+ if (addFile) {
+ super.zipFile(file, zOut, vPath, mode);
+ }
+ }
+
+
+ /**
+ * Make sure we don't think we already have a web.xml next time this task
+ * gets executed.
+ */
+ @Override
+ protected void cleanUp() {
+ if (addedWebXmlFile == null
+ && deploymentDescriptor == null
+ && needxmlfile
+ && !isInUpdateMode()
+ && hasUpdatedFile()) {
+ throw new BuildException("No WEB-INF/web.xml file was added.\n"
+ + "If this is your intent, set needxmlfile='false' ");
+ }
+ addedWebXmlFile = null;
+ super.cleanUp();
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/WhichResource.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/WhichResource.java
new file mode 100644
index 00000000..3f315a8d
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/WhichResource.java
@@ -0,0 +1,199 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.net.URL;
+
+import org.apache.tools.ant.AntClassLoader;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.types.Reference;
+
+/**
+ * Find a class or resource on the supplied classpath, or the
+ * system classpath if none is supplied. The named property is set if
+ * the item can be found. For example
+ * <pre>
+ * &lt;whichresource resource="/log4j.properties"
+ * property="log4j.url" &gt;
+ * </pre>
+ * @since Ant 1.6
+ * @ant.attribute.group name="oneof" description="Exactly one of these two"
+ */
+public class WhichResource extends Task {
+ /**
+ * our classpath
+ */
+ private Path classpath;
+
+ /**
+ * class to look for
+ */
+ private String classname;
+
+ /**
+ * resource to look for
+ */
+ private String resource;
+
+ /**
+ * property to set
+ */
+ private String property;
+
+
+ /**
+ * Set the classpath to be used for this compilation.
+ * @param cp the classpath to be used.
+ */
+ public void setClasspath(Path cp) {
+ if (classpath == null) {
+ classpath = cp;
+ } else {
+ classpath.append(cp);
+ }
+ }
+
+ /**
+ * Adds a path to the classpath.
+ * @return a classpath to be configured.
+ */
+ public Path createClasspath() {
+ if (classpath == null) {
+ classpath = new Path(getProject());
+ }
+ return classpath.createPath();
+ }
+
+ /**
+ * Set the classpath to use by reference.
+ *
+ * @param r a reference to an existing classpath.
+ * @since Ant 1.7.1
+ */
+ public void setClasspathRef(Reference r) {
+ createClasspath().setRefid(r);
+ }
+
+ /**
+ * validate
+ */
+ private void validate() {
+ int setcount = 0;
+ if (classname != null) {
+ setcount++;
+ }
+ if (resource != null) {
+ setcount++;
+ }
+
+
+ if (setcount == 0) {
+ throw new BuildException("One of classname or resource must"
+ + " be specified");
+ }
+ if (setcount > 1) {
+ throw new BuildException("Only one of classname or resource can"
+ + " be specified");
+ }
+ if (property == null) {
+ throw new BuildException("No property defined");
+ }
+ }
+
+ /**
+ * execute it
+ * @throws BuildException on error
+ */
+ public void execute() throws BuildException {
+ validate();
+ if (classpath != null) {
+ classpath = classpath.concatSystemClasspath("ignore");
+ getProject().log("using user supplied classpath: " + classpath,
+ Project.MSG_DEBUG);
+ } else {
+ classpath = new Path(getProject());
+ classpath = classpath.concatSystemClasspath("only");
+ getProject().log("using system classpath: " + classpath,
+ Project.MSG_DEBUG);
+ }
+ AntClassLoader loader = null;
+ try {
+ loader = AntClassLoader.newAntClassLoader(getProject().getCoreLoader(),
+ getProject(),
+ classpath, false);
+ String loc = null;
+ if (classname != null) {
+ //convert a class name into a resource
+ resource = classname.replace('.', '/') + ".class";
+ }
+
+ if (resource == null) {
+ throw new BuildException("One of class or resource is required");
+ }
+
+ if (resource.startsWith("/")) {
+ resource = resource.substring(1);
+ }
+
+ log("Searching for " + resource, Project.MSG_VERBOSE);
+ URL url;
+ url = loader.getResource(resource);
+ if (url != null) {
+ //set the property
+ loc = url.toExternalForm();
+ getProject().setNewProperty(property, loc);
+ }
+ } finally {
+ if (loader != null) {
+ loader.cleanup();
+ }
+ }
+ }
+
+ /**
+ * name the resource to look for
+ * @param resource the name of the resource to look for.
+ * @ant.attribute group="oneof"
+ */
+ public void setResource(String resource) {
+ this.resource = resource;
+ }
+
+ /**
+ * name the class to look for
+ * @param classname the name of the class to look for.
+ * @ant.attribute group="oneof"
+ */
+ public void setClass(String classname) {
+ this.classname = classname;
+ }
+
+ /**
+ * the property to fill with the URL of the resource or class
+ * @param property the property to be set.
+ * @ant.attribute group="required"
+ */
+ public void setProperty(String property) {
+ this.property = property;
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/XSLTLiaison.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/XSLTLiaison.java
new file mode 100644
index 00000000..304995c6
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/XSLTLiaison.java
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.io.File;
+
+/**
+ * Proxy interface for XSLT processors.
+ *
+ * @see XSLTProcess
+ * @since Ant 1.1
+ */
+public interface XSLTLiaison {
+
+ /**
+ * the file protocol prefix for systemid.
+ * This file protocol must be appended to an absolute path.
+ * Typically: <tt>FILE_PROTOCOL_PREFIX + file.getAbsolutePath()</tt>
+ * Note that on Windows, an extra '/' must be appended to the
+ * protocol prefix so that there is always 3 consecutive slashes.
+ * @since Ant 1.4
+ */
+ String FILE_PROTOCOL_PREFIX = "file://";
+
+ /**
+ * set the stylesheet to use for the transformation.
+ * @param stylesheet the stylesheet to be used for transformation.
+ * @throws Exception thrown if any problems happens.
+ * @since Ant 1.4
+ */
+ void setStylesheet(File stylesheet) throws Exception;
+
+ /**
+ * Add a parameter to be set during the XSL transformation.
+ * @param name the parameter name.
+ * @param expression the parameter value as an expression string.
+ * @throws Exception thrown if any problems happens.
+ * @see XSLTLiaison4#addParam(java.lang.String, java.lang.Object)
+ * @since Ant 1.3
+ */
+ void addParam(String name, String expression) throws Exception;
+
+ /**
+ * Perform the transformation of a file into another.
+ * @param infile the input file, probably an XML one. :-)
+ * @param outfile the output file resulting from the transformation
+ * @throws Exception thrown if any problems happens.
+ * @see #setStylesheet(File)
+ * @since Ant 1.4
+ */
+ void transform(File infile, File outfile) throws Exception;
+
+} //-- XSLTLiaison
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/XSLTLiaison2.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/XSLTLiaison2.java
new file mode 100644
index 00000000..f41f9151
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/XSLTLiaison2.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+/**
+ * Extended Proxy interface for XSLT processors.
+ *
+ * @see XSLTProcess
+ * @since Ant 1.6
+ */
+public interface XSLTLiaison2 extends XSLTLiaison {
+ /**
+ * Configure the liaision from the XSLTProcess task
+ * @param xsltTask the XSLTProcess task
+ */
+ void configure(XSLTProcess xsltTask);
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/XSLTLiaison3.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/XSLTLiaison3.java
new file mode 100644
index 00000000..963093ff
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/XSLTLiaison3.java
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.types.Resource;
+
+/**
+ * Extends Proxy interface for XSLT processors.
+ *
+ * @see XSLTProcess
+ * @since Ant 1.7
+ */
+public interface XSLTLiaison3 extends XSLTLiaison2 {
+ /**
+ * sets the stylesheet to use as a resource
+ * @param stylesheet the stylesheet to use as a resource
+ * @throws Exception if the stylesheet cannot be loaded
+ */
+ void setStylesheet(Resource stylesheet) throws Exception;
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/XSLTLiaison4.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/XSLTLiaison4.java
new file mode 100644
index 00000000..6e16e623
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/XSLTLiaison4.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs;
+
+
+/**
+ * Extends Proxy interface for XSLT processors: adds support for XSLT parameters
+ * of various types (not only String)
+ *
+ *
+ * @see XSLTProcess
+ * @author Frantisek Kucera (xkucf03)
+ * @since Ant 1.9.3
+ */
+public interface XSLTLiaison4 extends XSLTLiaison3 {
+
+ /**
+ * Add a parameter to be set during the XSL transformation.
+ *
+ * @param name the parameter name.
+ * @param value the parameter value as String, Boolean, int, etc.
+ * @throws Exception thrown if any problems happens.
+ * @since Ant 1.9.3
+ * @see javax.xml.transform.Transformer#setParameter(java.lang.String, java.lang.Object)
+ */
+ void addParam(String name, Object value) throws Exception;
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/XSLTLogger.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/XSLTLogger.java
new file mode 100644
index 00000000..4dadebc7
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/XSLTLogger.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+/**
+ * Interface to log messages for XSLT
+ * @since Ant 1.5
+ */
+public interface XSLTLogger {
+ /**
+ * Log a message.
+ * @param msg the message to log
+ */
+ void log(String msg);
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/XSLTLoggerAware.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/XSLTLoggerAware.java
new file mode 100644
index 00000000..edf0fce8
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/XSLTLoggerAware.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+/**
+ * Interface for a class that one can set an XSLTLogger on.
+ * @since Ant 1.5
+ */
+public interface XSLTLoggerAware {
+ /**
+ * Set the logger for this class.
+ * @param l the logger
+ */
+ void setLogger(XSLTLogger l);
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/XSLTProcess.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/XSLTProcess.java
new file mode 100644
index 00000000..4fe31260
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/XSLTProcess.java
@@ -0,0 +1,1689 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.EnumMap;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.Map;
+import java.util.Vector;
+
+import javax.xml.namespace.QName;
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpression;
+import javax.xml.xpath.XPathExpressionException;
+import javax.xml.xpath.XPathFactory;
+import javax.xml.xpath.XPathVariableResolver;
+
+import org.apache.tools.ant.AntClassLoader;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.DirectoryScanner;
+import org.apache.tools.ant.DynamicConfigurator;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.PropertyHelper;
+import org.apache.tools.ant.types.CommandlineJava;
+import org.apache.tools.ant.types.Environment;
+import org.apache.tools.ant.types.Mapper;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.types.PropertySet;
+import org.apache.tools.ant.types.Reference;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.ResourceCollection;
+import org.apache.tools.ant.types.XMLCatalog;
+import org.apache.tools.ant.types.resources.FileProvider;
+import org.apache.tools.ant.types.resources.FileResource;
+import org.apache.tools.ant.types.resources.Resources;
+import org.apache.tools.ant.types.resources.Union;
+import org.apache.tools.ant.util.FileNameMapper;
+import org.apache.tools.ant.util.FileUtils;
+import org.apache.tools.ant.util.ResourceUtils;
+
+/**
+ * Processes a set of XML documents via XSLT. This is
+ * useful for building views of XML based documentation.
+ *
+ *
+ * @since Ant 1.1
+ *
+ * @ant.task name="xslt" category="xml"
+ */
+
+public class XSLTProcess extends MatchingTask implements XSLTLogger {
+ /** destination directory */
+ private File destDir = null;
+
+ /** where to find the source XML file, default is the project's basedir */
+ private File baseDir = null;
+
+ /** XSL stylesheet as a filename */
+ private String xslFile = null;
+
+ /** XSL stylesheet as a {@link org.apache.tools.ant.types.Resource} */
+ private Resource xslResource = null;
+
+ /** extension of the files produced by XSL processing */
+ private String targetExtension = ".html";
+
+ /** name for XSL parameter containing the filename */
+ private String fileNameParameter = null;
+
+ /** name for XSL parameter containing the file directory */
+ private String fileDirParameter = null;
+
+ /** additional parameters to be passed to the stylesheets */
+ private final List<Param> params = new ArrayList<Param>();
+
+ /** Input XML document to be used */
+ private File inFile = null;
+
+ /** Output file */
+ private File outFile = null;
+
+ /** The name of the XSL processor to use */
+ private String processor;
+
+ /** Classpath to use when trying to load the XSL processor */
+ private Path classpath = null;
+
+ /** The Liaison implementation to use to communicate with the XSL
+ * processor */
+ private XSLTLiaison liaison;
+
+ /** Flag which indicates if the stylesheet has been loaded into
+ * the processor */
+ private boolean stylesheetLoaded = false;
+
+ /** force output of target files even if they already exist */
+ private boolean force = false;
+
+ /** XSL output properties to be used */
+ private final Vector outputProperties = new Vector();
+
+ /** for resolving entities such as dtds */
+ private final XMLCatalog xmlCatalog = new XMLCatalog();
+
+ /** Utilities used for file operations */
+ private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+
+ /**
+ * Whether to style all files in the included directories as well.
+ *
+ * @since Ant 1.5
+ */
+ private boolean performDirectoryScan = true;
+
+ /**
+ * factory element for TraX processors only
+ * @since Ant 1.6
+ */
+ private Factory factory = null;
+
+ /**
+ * whether to reuse Transformer if transforming multiple files.
+ * @since 1.5.2
+ */
+ private boolean reuseLoadedStylesheet = true;
+
+ /**
+ * AntClassLoader for the nested &lt;classpath&gt; - if set.
+ *
+ * <p>We keep this here in order to reset the context classloader
+ * in execute. We can't use liaison.getClass().getClassLoader()
+ * since the actual liaison class may have been loaded by a loader
+ * higher up (system classloader, for example).</p>
+ *
+ * @since Ant 1.6.2
+ */
+ private AntClassLoader loader = null;
+
+ /**
+ * Mapper to use when a set of files gets processed.
+ *
+ * @since Ant 1.6.2
+ */
+ private Mapper mapperElement = null;
+
+ /**
+ * Additional resource collections to process.
+ *
+ * @since Ant 1.7
+ */
+ private final Union resources = new Union();
+
+ /**
+ * Whether to use the implicit fileset.
+ *
+ * @since Ant 1.7
+ */
+ private boolean useImplicitFileset = true;
+
+ /**
+ * The default processor is trax
+ * @since Ant 1.7
+ */
+ public static final String PROCESSOR_TRAX = "trax";
+
+ /**
+ * whether to suppress warnings.
+ *
+ * @since Ant 1.8.0
+ */
+ private boolean suppressWarnings = false;
+
+ /**
+ * whether to fail the build if an error occurs during transformation.
+ *
+ * @since Ant 1.8.0
+ */
+ private boolean failOnTransformationError = true;
+
+ /**
+ * whether to fail the build if an error occurs.
+ *
+ * @since Ant 1.8.0
+ */
+ private boolean failOnError = true;
+
+ /**
+ * Whether the build should fail if the nested resource collection
+ * is empty.
+ *
+ * @since Ant 1.8.0
+ */
+ private boolean failOnNoResources = true;
+
+ /**
+ * For evaluating template params
+ *
+ * @since Ant 1.9.3
+ */
+ private XPathFactory xpathFactory;
+ /**
+ * For evaluating template params
+ *
+ * @since Ant 1.9.3
+ */
+ private XPath xpath;
+
+ /**
+ * System properties to set during transformation.
+ *
+ * @since Ant 1.8.0
+ */
+ private final CommandlineJava.SysProperties sysProperties =
+ new CommandlineJava.SysProperties();
+
+ /**
+ * Trace configuration for Xalan2.
+ *
+ * @since Ant 1.8.0
+ */
+ private TraceConfiguration traceConfiguration;
+
+ /**
+ * Creates a new XSLTProcess Task.
+ */
+ public XSLTProcess() {
+ } //-- XSLTProcess
+
+ /**
+ * Whether to style all files in the included directories as well;
+ * optional, default is true.
+ *
+ * @param b true if files in included directories are processed.
+ * @since Ant 1.5
+ */
+ public void setScanIncludedDirectories(final boolean b) {
+ performDirectoryScan = b;
+ }
+
+ /**
+ * Controls whether the stylesheet is reloaded for every transform.
+ *
+ * <p>Setting this to true may get around a bug in certain
+ * Xalan-J versions, default is false.</p>
+ * @param b a <code>boolean</code> value
+ * @since Ant 1.5.2
+ */
+ public void setReloadStylesheet(final boolean b) {
+ reuseLoadedStylesheet = !b;
+ }
+
+ /**
+ * Defines the mapper to map source to destination files.
+ * @param mapper the mapper to use
+ * @exception BuildException if more than one mapper is defined
+ * @since Ant 1.6.2
+ */
+ public void addMapper(final Mapper mapper) {
+ if (mapperElement != null) {
+ handleError("Cannot define more than one mapper");
+ } else {
+ mapperElement = mapper;
+ }
+ }
+
+ /**
+ * Adds a collection of resources to style in addition to the
+ * given file or the implicit fileset.
+ *
+ * @param rc the collection of resources to style
+ * @since Ant 1.7
+ */
+ public void add(final ResourceCollection rc) {
+ resources.add(rc);
+ }
+
+ /**
+ * Add a nested &lt;style&gt; element.
+ * @param rc the configured Resources object represented as &lt;style&gt;.
+ * @since Ant 1.7
+ */
+ public void addConfiguredStyle(final Resources rc) {
+ if (rc.size() != 1) {
+ handleError("The style element must be specified with exactly one"
+ + " nested resource.");
+ } else {
+ setXslResource(rc.iterator().next());
+ }
+ }
+
+ /**
+ * API method to set the XSL Resource.
+ * @param xslResource Resource to set as the stylesheet.
+ * @since Ant 1.7
+ */
+ public void setXslResource(final Resource xslResource) {
+ this.xslResource = xslResource;
+ }
+
+ /**
+ * Adds a nested filenamemapper.
+ * @param fileNameMapper the mapper to add
+ * @exception BuildException if more than one mapper is defined
+ * @since Ant 1.7.0
+ */
+ public void add(final FileNameMapper fileNameMapper) throws BuildException {
+ final Mapper mapper = new Mapper(getProject());
+ mapper.add(fileNameMapper);
+ addMapper(mapper);
+ }
+
+ /**
+ * Executes the task.
+ *
+ * @exception BuildException if there is an execution problem.
+ * @todo validate that if either in or out is defined, then both are
+ */
+ @Override
+ public void execute() throws BuildException {
+ if ("style".equals(getTaskType())) {
+ log("Warning: the task name <style> is deprecated. Use <xslt> instead.",
+ Project.MSG_WARN);
+ }
+ final File savedBaseDir = baseDir;
+
+ DirectoryScanner scanner;
+ String[] list;
+ String[] dirs;
+
+ final String baseMessage =
+ "specify the stylesheet either as a filename in style attribute "
+ + "or as a nested resource";
+
+ if (xslResource == null && xslFile == null) {
+ handleError(baseMessage);
+ return;
+ }
+ if (xslResource != null && xslFile != null) {
+ handleError(baseMessage + " but not as both");
+ return;
+ }
+ if (inFile != null && !inFile.exists()) {
+ handleError("input file " + inFile + " does not exist");
+ return;
+ }
+ try {
+ setupLoader();
+
+ if (sysProperties.size() > 0) {
+ sysProperties.setSystem();
+ }
+
+ Resource styleResource;
+ if (baseDir == null) {
+ baseDir = getProject().getBaseDir();
+ }
+ liaison = getLiaison();
+
+ // check if liaison wants to log errors using us as logger
+ if (liaison instanceof XSLTLoggerAware) {
+ ((XSLTLoggerAware) liaison).setLogger(this);
+ }
+ log("Using " + liaison.getClass().toString(), Project.MSG_VERBOSE);
+
+ if (xslFile != null) {
+ // If we enter here, it means that the stylesheet is supplied
+ // via style attribute
+ File stylesheet = getProject().resolveFile(xslFile);
+ if (!stylesheet.exists()) {
+ final File alternative = FILE_UTILS.resolveFile(baseDir, xslFile);
+ /*
+ * shouldn't throw out deprecation warnings before we know,
+ * the wrong version has been used.
+ */
+ if (alternative.exists()) {
+ log("DEPRECATED - the 'style' attribute should be "
+ + "relative to the project's");
+ log(" basedir, not the tasks's basedir.");
+ stylesheet = alternative;
+ }
+ }
+ final FileResource fr = new FileResource();
+ fr.setProject(getProject());
+ fr.setFile(stylesheet);
+ styleResource = fr;
+ } else {
+ styleResource = xslResource;
+ }
+
+ if (!styleResource.isExists()) {
+ handleError("stylesheet " + styleResource + " doesn't exist.");
+ return;
+ }
+
+ // if we have an in file and out then process them
+ if (inFile != null && outFile != null) {
+ process(inFile, outFile, styleResource);
+ return;
+ }
+ /*
+ * if we get here, in and out have not been specified, we are
+ * in batch processing mode.
+ */
+
+ //-- make sure destination directory exists...
+ checkDest();
+
+ if (useImplicitFileset) {
+ scanner = getDirectoryScanner(baseDir);
+ log("Transforming into " + destDir, Project.MSG_INFO);
+
+ // Process all the files marked for styling
+ list = scanner.getIncludedFiles();
+ for (int i = 0; i < list.length; ++i) {
+ process(baseDir, list[i], destDir, styleResource);
+ }
+ if (performDirectoryScan) {
+ // Process all the directories marked for styling
+ dirs = scanner.getIncludedDirectories();
+ for (int j = 0; j < dirs.length; ++j) {
+ list = new File(baseDir, dirs[j]).list();
+ for (int i = 0; i < list.length; ++i) {
+ process(baseDir, dirs[j] + File.separator + list[i], destDir,
+ styleResource);
+ }
+ }
+ }
+ } else { // only resource collections, there better be some
+ if (resources.size() == 0) {
+ if (failOnNoResources) {
+ handleError("no resources specified");
+ }
+ return;
+ }
+ }
+ processResources(styleResource);
+ } finally {
+ if (loader != null) {
+ loader.resetThreadContextLoader();
+ loader.cleanup();
+ loader = null;
+ }
+ if (sysProperties.size() > 0) {
+ sysProperties.restoreSystem();
+ }
+ liaison = null;
+ stylesheetLoaded = false;
+ baseDir = savedBaseDir;
+ }
+ }
+
+ /**
+ * Set whether to check dependencies, or always generate;
+ * optional, default is false.
+ *
+ * @param force true if always generate.
+ */
+ public void setForce(final boolean force) {
+ this.force = force;
+ }
+
+ /**
+ * Set the base directory;
+ * optional, default is the project's basedir.
+ *
+ * @param dir the base directory
+ **/
+ public void setBasedir(final File dir) {
+ baseDir = dir;
+ }
+
+ /**
+ * Set the destination directory into which the XSL result
+ * files should be copied to;
+ * required, unless <tt>in</tt> and <tt>out</tt> are
+ * specified.
+ * @param dir the name of the destination directory
+ **/
+ public void setDestdir(final File dir) {
+ destDir = dir;
+ }
+
+ /**
+ * Set the desired file extension to be used for the target;
+ * optional, default is html.
+ * @param name the extension to use
+ **/
+ public void setExtension(final String name) {
+ targetExtension = name;
+ }
+
+ /**
+ * Name of the stylesheet to use - given either relative
+ * to the project's basedir or as an absolute path; required.
+ *
+ * @param xslFile the stylesheet to use
+ */
+ public void setStyle(final String xslFile) {
+ this.xslFile = xslFile;
+ }
+
+ /**
+ * Set the optional classpath to the XSL processor
+ *
+ * @param classpath the classpath to use when loading the XSL processor
+ */
+ public void setClasspath(final Path classpath) {
+ createClasspath().append(classpath);
+ }
+
+ /**
+ * Set the optional classpath to the XSL processor
+ *
+ * @return a path instance to be configured by the Ant core.
+ */
+ public Path createClasspath() {
+ if (classpath == null) {
+ classpath = new Path(getProject());
+ }
+ return classpath.createPath();
+ }
+
+ /**
+ * Set the reference to an optional classpath to the XSL processor
+ *
+ * @param r the id of the Ant path instance to act as the classpath
+ * for loading the XSL processor
+ */
+ public void setClasspathRef(final Reference r) {
+ createClasspath().setRefid(r);
+ }
+
+ /**
+ * Set the name of the XSL processor to use; optional, default trax.
+ *
+ * @param processor the name of the XSL processor
+ */
+ public void setProcessor(final String processor) {
+ this.processor = processor;
+ }
+
+ /**
+ * Whether to use the implicit fileset.
+ *
+ * <p>Set this to false if you want explicit control with nested
+ * resource collections.</p>
+ * @param useimplicitfileset set to true if you want to use implicit fileset
+ * @since Ant 1.7
+ */
+ public void setUseImplicitFileset(final boolean useimplicitfileset) {
+ useImplicitFileset = useimplicitfileset;
+ }
+
+ /**
+ * Add the catalog to our internal catalog
+ *
+ * @param xmlCatalog the XMLCatalog instance to use to look up DTDs
+ */
+ public void addConfiguredXMLCatalog(final XMLCatalog xmlCatalog) {
+ this.xmlCatalog.addConfiguredXMLCatalog(xmlCatalog);
+ }
+
+ /**
+ * Pass the filename of the current processed file as a xsl parameter
+ * to the transformation. This value sets the name of that xsl parameter.
+ *
+ * @param fileNameParameter name of the xsl parameter retrieving the
+ * current file name
+ */
+ public void setFileNameParameter(final String fileNameParameter) {
+ this.fileNameParameter = fileNameParameter;
+ }
+
+ /**
+ * Pass the directory name of the current processed file as a xsl parameter
+ * to the transformation. This value sets the name of that xsl parameter.
+ *
+ * @param fileDirParameter name of the xsl parameter retrieving the
+ * current file directory
+ */
+ public void setFileDirParameter(final String fileDirParameter) {
+ this.fileDirParameter = fileDirParameter;
+ }
+
+ /**
+ * Whether to suppress warning messages of the processor.
+ *
+ * @since Ant 1.8.0
+ */
+ public void setSuppressWarnings(final boolean b) {
+ suppressWarnings = b;
+ }
+
+ /**
+ * Whether to suppress warning messages of the processor.
+ *
+ * @since Ant 1.8.0
+ */
+ public boolean getSuppressWarnings() {
+ return suppressWarnings;
+ }
+
+ /**
+ * Whether transformation errors should make the build fail.
+ *
+ * @since Ant 1.8.0
+ */
+ public void setFailOnTransformationError(final boolean b) {
+ failOnTransformationError = b;
+ }
+
+ /**
+ * Whether any errors should make the build fail.
+ *
+ * @since Ant 1.8.0
+ */
+ public void setFailOnError(final boolean b) {
+ failOnError = b;
+ }
+
+ /**
+ * Whether the build should fail if the nested resource collection is empty.
+ *
+ * @since Ant 1.8.0
+ */
+ public void setFailOnNoResources(final boolean b) {
+ failOnNoResources = b;
+ }
+
+ /**
+ * A system property to set during transformation.
+ *
+ * @since Ant 1.8.0
+ */
+ public void addSysproperty(final Environment.Variable sysp) {
+ sysProperties.addVariable(sysp);
+ }
+
+ /**
+ * A set of system properties to set during transformation.
+ *
+ * @since Ant 1.8.0
+ */
+ public void addSyspropertyset(final PropertySet sysp) {
+ sysProperties.addSyspropertyset(sysp);
+ }
+
+ /**
+ * Enables Xalan2 traces and uses the given configuration.
+ *
+ * <p>Note that this element doesn't have any effect with a
+ * processor other than trax or if the Transformer is not Xalan2's
+ * transformer implementation.</p>
+ *
+ * @since Ant 1.8.0
+ */
+ public TraceConfiguration createTrace() {
+ if (traceConfiguration != null) {
+ throw new BuildException("can't have more than one trace"
+ + " configuration");
+ }
+ traceConfiguration = new TraceConfiguration();
+ return traceConfiguration;
+ }
+
+ /**
+ * Configuration for Xalan2 traces.
+ *
+ * @since Ant 1.8.0
+ */
+ public TraceConfiguration getTraceConfiguration() {
+ return traceConfiguration;
+ }
+
+ /**
+ * Load processor here instead of in setProcessor - this will be
+ * called from within execute, so we have access to the latest
+ * classpath.
+ *
+ * @param proc the name of the processor to load.
+ * @exception Exception if the processor cannot be loaded.
+ */
+ private void resolveProcessor(final String proc) throws Exception {
+ if (proc.equals(PROCESSOR_TRAX)) {
+ liaison = new org.apache.tools.ant.taskdefs.optional.TraXLiaison();
+ } else {
+ //anything else is a classname
+ final Class clazz = loadClass(proc);
+ liaison = (XSLTLiaison) clazz.newInstance();
+ }
+ }
+
+ /**
+ * Load named class either via the system classloader or a given
+ * custom classloader.
+ *
+ * As a side effect, the loader is set as the thread context classloader
+ * @param classname the name of the class to load.
+ * @return the requested class.
+ * @exception Exception if the class could not be loaded.
+ */
+ private Class loadClass(final String classname) throws Exception {
+ setupLoader();
+ if (loader == null) {
+ return Class.forName(classname);
+ }
+ return Class.forName(classname, true, loader);
+ }
+
+ /**
+ * If a custom classpath has been defined but no loader created
+ * yet, create the classloader and set it as the context
+ * classloader.
+ */
+ private void setupLoader() {
+ if (classpath != null && loader == null) {
+ loader = getProject().createClassLoader(classpath);
+ loader.setThreadContextLoader();
+ }
+ }
+
+ /**
+ * Specifies the output name for the styled result from the
+ * <tt>in</tt> attribute; required if <tt>in</tt> is set
+ *
+ * @param outFile the output File instance.
+ */
+ public void setOut(final File outFile) {
+ this.outFile = outFile;
+ }
+
+ /**
+ * specifies a single XML document to be styled. Should be used
+ * with the <tt>out</tt> attribute; ; required if <tt>out</tt> is set
+ *
+ * @param inFile the input file
+ */
+ public void setIn(final File inFile) {
+ this.inFile = inFile;
+ }
+
+ /**
+ * Throws a BuildException if the destination directory hasn't
+ * been specified.
+ * @since Ant 1.7
+ */
+ private void checkDest() {
+ if (destDir == null) {
+ handleError("destdir attributes must be set!");
+ }
+ }
+
+ /**
+ * Styles all existing resources.
+ *
+ * @param stylesheet style sheet to use
+ * @since Ant 1.7
+ */
+ private void processResources(final Resource stylesheet) {
+ for (final Resource r : resources) {
+ if (!r.isExists()) {
+ continue;
+ }
+ File base = baseDir;
+ String name = r.getName();
+ final FileProvider fp = r.as(FileProvider.class);
+ if (fp != null) {
+ final FileResource f = ResourceUtils.asFileResource(fp);
+ base = f.getBaseDir();
+ if (base == null) {
+ name = f.getFile().getAbsolutePath();
+ }
+ }
+ process(base, name, destDir, stylesheet);
+ }
+ }
+
+ /**
+ * Processes the given input XML file and stores the result
+ * in the given resultFile.
+ *
+ * @param baseDir the base directory for resolving files.
+ * @param xmlFile the input file
+ * @param destDir the destination directory
+ * @param stylesheet the stylesheet to use.
+ * @exception BuildException if the processing fails.
+ */
+ private void process(final File baseDir, final String xmlFile, final File destDir, final Resource stylesheet)
+ throws BuildException {
+
+ File outF = null;
+ File inF = null;
+
+ try {
+ final long styleSheetLastModified = stylesheet.getLastModified();
+ inF = new File(baseDir, xmlFile);
+
+ if (inF.isDirectory()) {
+ log("Skipping " + inF + " it is a directory.", Project.MSG_VERBOSE);
+ return;
+ }
+ FileNameMapper mapper = null;
+ if (mapperElement != null) {
+ mapper = mapperElement.getImplementation();
+ } else {
+ mapper = new StyleMapper();
+ }
+
+ final String[] outFileName = mapper.mapFileName(xmlFile);
+ if (outFileName == null || outFileName.length == 0) {
+ log("Skipping " + inFile + " it cannot get mapped to output.", Project.MSG_VERBOSE);
+ return;
+ } else if (outFileName == null || outFileName.length > 1) {
+ log("Skipping " + inFile + " its mapping is ambiguos.", Project.MSG_VERBOSE);
+ return;
+ }
+ outF = new File(destDir, outFileName[0]);
+
+ if (force || inF.lastModified() > outF.lastModified()
+ || styleSheetLastModified > outF.lastModified()) {
+ ensureDirectoryFor(outF);
+ log("Processing " + inF + " to " + outF);
+ configureLiaison(stylesheet);
+ setLiaisonDynamicFileParameters(liaison, inF);
+ liaison.transform(inF, outF);
+ }
+ } catch (final Exception ex) {
+ // If failed to process document, must delete target document,
+ // or it will not attempt to process it the second time
+ log("Failed to process " + inFile, Project.MSG_INFO);
+ if (outF != null) {
+ outF.delete();
+ }
+ handleTransformationError(ex);
+ }
+
+ } //-- processXML
+
+ /**
+ * Process the input file to the output file with the given stylesheet.
+ *
+ * @param inFile the input file to process.
+ * @param outFile the destination file.
+ * @param stylesheet the stylesheet to use.
+ * @exception BuildException if the processing fails.
+ */
+ private void process(final File inFile, final File outFile, final Resource stylesheet) throws BuildException {
+ try {
+ final long styleSheetLastModified = stylesheet.getLastModified();
+ log("In file " + inFile + " time: " + inFile.lastModified(), Project.MSG_DEBUG);
+ log("Out file " + outFile + " time: " + outFile.lastModified(), Project.MSG_DEBUG);
+ log("Style file " + xslFile + " time: " + styleSheetLastModified, Project.MSG_DEBUG);
+ if (force || inFile.lastModified() >= outFile.lastModified()
+ || styleSheetLastModified >= outFile.lastModified()) {
+ ensureDirectoryFor(outFile);
+ log("Processing " + inFile + " to " + outFile, Project.MSG_INFO);
+ configureLiaison(stylesheet);
+ setLiaisonDynamicFileParameters(liaison, inFile);
+ liaison.transform(inFile, outFile);
+ } else {
+ log("Skipping input file " + inFile + " because it is older than output file "
+ + outFile + " and so is the stylesheet " + stylesheet, Project.MSG_DEBUG);
+ }
+ } catch (final Exception ex) {
+ log("Failed to process " + inFile, Project.MSG_INFO);
+ if (outFile != null) {
+ outFile.delete();
+ }
+ handleTransformationError(ex);
+ }
+ }
+
+ /**
+ * Ensure the directory exists for a given file
+ *
+ * @param targetFile the file for which the directories are required.
+ * @exception BuildException if the directories cannot be created.
+ */
+ private void ensureDirectoryFor(final File targetFile) throws BuildException {
+ final File directory = targetFile.getParentFile();
+ if (!directory.exists()) {
+ if (!(directory.mkdirs() || directory.isDirectory())) {
+ handleError("Unable to create directory: "
+ + directory.getAbsolutePath());
+ }
+ }
+ }
+
+ /**
+ * Get the factory instance configured for this processor
+ *
+ * @return the factory instance in use
+ */
+ public Factory getFactory() {
+ return factory;
+ }
+
+ /**
+ * Get the XML catalog containing entity definitions
+ *
+ * @return the XML catalog for the task.
+ */
+ public XMLCatalog getXMLCatalog() {
+ xmlCatalog.setProject(getProject());
+ return xmlCatalog;
+ }
+
+ /**
+ * Get an enumeration on the outputproperties.
+ * @return the outputproperties
+ */
+ public Enumeration getOutputProperties() {
+ return outputProperties.elements();
+ }
+
+ /**
+ * Get the Liaison implementation to use in processing.
+ *
+ * @return an instance of the XSLTLiaison interface.
+ */
+ protected XSLTLiaison getLiaison() {
+ // if processor wasn't specified, use TraX.
+ if (liaison == null) {
+ if (processor != null) {
+ try {
+ resolveProcessor(processor);
+ } catch (final Exception e) {
+ handleError(e);
+ }
+ } else {
+ try {
+ resolveProcessor(PROCESSOR_TRAX);
+ } catch (final Throwable e1) {
+ e1.printStackTrace();
+ handleError(e1);
+ }
+ }
+ }
+ return liaison;
+ }
+
+ /**
+ * Create an instance of an XSL parameter for configuration by Ant.
+ *
+ * @return an instance of the Param class to be configured.
+ */
+ public Param createParam() {
+ final Param p = new Param();
+ params.add(p);
+ return p;
+ }
+
+ /**
+ * The Param inner class used to store XSL parameters
+ */
+ public static class Param {
+ /** The parameter name */
+ private String name = null;
+
+ /** The parameter's value */
+ private String expression = null;
+
+ /**
+ * Type of the expression.
+ * @see ParamType
+ */
+ private String type;
+
+ private Object ifCond;
+ private Object unlessCond;
+ private Project project;
+
+ /**
+ * Set the current project
+ *
+ * @param project the current project
+ */
+ public void setProject(final Project project) {
+ this.project = project;
+ }
+
+ /**
+ * Set the parameter name.
+ *
+ * @param name the name of the parameter.
+ */
+ public void setName(final String name) {
+ this.name = name;
+ }
+
+ /**
+ * The parameter value -
+ * can be a primitive type value or an XPath expression.
+ * @param expression the parameter's value/expression.
+ * @see #setType(java.lang.String)
+ */
+ public void setExpression(final String expression) {
+ this.expression = expression;
+ }
+
+ /**
+ * @see ParamType
+ * @since Ant 1.9.3
+ */
+ public void setType(final String type) {
+ this.type = type;
+ }
+
+ /**
+ * Get the parameter name
+ *
+ * @return the parameter name
+ * @exception BuildException if the name is not set.
+ */
+ public String getName() throws BuildException {
+ if (name == null) {
+ throw new BuildException("Name attribute is missing.");
+ }
+ return name;
+ }
+
+ /**
+ * Get the parameter's value
+ *
+ * @return the parameter value
+ * @exception BuildException if the value is not set.
+ * @see #getType()
+ */
+ public String getExpression() throws BuildException {
+ if (expression == null) {
+ throw new BuildException("Expression attribute is missing.");
+ }
+ return expression;
+ }
+
+ /**
+ * @see ParamType
+ * @since Ant 1.9.3
+ */
+ public String getType() {
+ return type;
+ }
+
+ /**
+ * Set whether this param should be used. It will be used if
+ * the expression evaluates to true or the name of a property
+ * which has been set, otherwise it won't.
+ * @param ifCond evaluated expression
+ * @since Ant 1.8.0
+ */
+ public void setIf(final Object ifCond) {
+ this.ifCond = ifCond;
+ }
+
+ /**
+ * Set whether this param should be used. It will be used if
+ * the expression evaluates to true or the name of a property
+ * which has been set, otherwise it won't.
+ * @param ifProperty evaluated expression
+ */
+ public void setIf(final String ifProperty) {
+ setIf((Object) ifProperty);
+ }
+
+ /**
+ * Set whether this param should NOT be used. It will not be
+ * used if the expression evaluates to true or the name of a
+ * property which has been set, otherwise it will be used.
+ * @param unlessCond evaluated expression
+ * @since Ant 1.8.0
+ */
+ public void setUnless(final Object unlessCond) {
+ this.unlessCond = unlessCond;
+ }
+
+ /**
+ * Set whether this param should NOT be used. It will not be
+ * used if the expression evaluates to true or the name of a
+ * property which has been set, otherwise it will be used.
+ * @param unlessProperty evaluated expression
+ */
+ public void setUnless(final String unlessProperty) {
+ setUnless((Object) unlessProperty);
+ }
+
+ /**
+ * Ensures that the param passes the conditions placed
+ * on it with <code>if</code> and <code>unless</code> properties.
+ * @return true if the task passes the "if" and "unless" parameters
+ */
+ public boolean shouldUse() {
+ final PropertyHelper ph = PropertyHelper.getPropertyHelper(project);
+ return ph.testIfCondition(ifCond)
+ && ph.testUnlessCondition(unlessCond);
+ }
+ } // Param
+
+ /**
+ * Enum for types of the parameter expression.
+ *
+ * <p>The expression can be:</p>
+ * <ul>
+ * <li>primitive type that will be parsed from the string value e.g.
+ * {@linkplain Integer#parseInt(java.lang.String)}</li>
+ * <li>XPath expression that will be evaluated (outside of the transformed
+ * document - on empty one) and casted to given type. Inside XPath
+ * expressions the Ant variables (properties) can be used (as XPath
+ * variables - e.g. $variable123). n.b. placeholders in form of
+ * ${variable123} will be substituted with their values before evaluating the
+ * XPath expression (so it can be used for dynamic XPath function names and
+ * other hacks).</li>
+ * </ul>
+ * <p>The parameter will be then passed to the XSLT template.</p>
+ *
+ * <p>Default type (if omitted) is primitive String. So if the expression is e.g
+ * "true" with no type, in XSLT it will be only a text string, not true
+ * boolean.</p>
+ *
+ * @see Param#setType(java.lang.String)
+ * @see Param#setExpression(java.lang.String)
+ * @since Ant 1.9.3
+ */
+ public enum ParamType {
+
+ STRING,
+ BOOLEAN,
+ INT,
+ LONG,
+ DOUBLE,
+ XPATH_STRING,
+ XPATH_BOOLEAN,
+ XPATH_NUMBER,
+ XPATH_NODE,
+ XPATH_NODESET;
+
+ public static final Map<ParamType, QName> XPATH_TYPES;
+
+ static {
+ final Map<ParamType, QName> m = new EnumMap<ParamType, QName>(ParamType.class);
+ m.put(XPATH_STRING, XPathConstants.STRING);
+ m.put(XPATH_BOOLEAN, XPathConstants.BOOLEAN);
+ m.put(XPATH_NUMBER, XPathConstants.NUMBER);
+ m.put(XPATH_NODE, XPathConstants.NODE);
+ m.put(XPATH_NODESET, XPathConstants.NODESET);
+ XPATH_TYPES = Collections.unmodifiableMap(m);
+ }
+ }
+
+ /**
+ * Create an instance of an output property to be configured.
+ * @return the newly created output property.
+ * @since Ant 1.5
+ */
+ public OutputProperty createOutputProperty() {
+ final OutputProperty p = new OutputProperty();
+ outputProperties.addElement(p);
+ return p;
+ }
+
+ /**
+ * Specify how the result tree should be output as specified
+ * in the <a href="http://www.w3.org/TR/xslt#output">
+ * specification</a>.
+ * @since Ant 1.5
+ */
+ public static class OutputProperty {
+ /** output property name */
+ private String name;
+
+ /** output property value */
+ private String value;
+
+ /**
+ * @return the output property name.
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * set the name for this property
+ * @param name A non-null String that specifies an
+ * output property name, which may be namespace qualified.
+ */
+ public void setName(final String name) {
+ this.name = name;
+ }
+
+ /**
+ * @return the output property value.
+ */
+ public String getValue() {
+ return value;
+ }
+
+ /**
+ * set the value for this property
+ * @param value The non-null string value of the output property.
+ */
+ public void setValue(final String value) {
+ this.value = value;
+ }
+ }
+
+ /**
+ * Initialize internal instance of XMLCatalog.
+ * Initialize XPath for parameter evaluation.
+ * @throws BuildException on error
+ */
+ @Override
+ public void init() throws BuildException {
+ super.init();
+ xmlCatalog.setProject(getProject());
+
+ xpathFactory = XPathFactory.newInstance();
+ xpath = xpathFactory.newXPath();
+ xpath.setXPathVariableResolver(new XPathVariableResolver() {
+ public Object resolveVariable(final QName variableName) {
+ return getProject().getProperty(variableName.toString());
+ }
+ });
+ }
+
+ /**
+ * Loads the stylesheet and set xsl:param parameters.
+ *
+ * @param stylesheet the file from which to load the stylesheet.
+ * @exception BuildException if the stylesheet cannot be loaded.
+ * @deprecated since Ant 1.7
+ */
+ @Deprecated
+ protected void configureLiaison(final File stylesheet) throws BuildException {
+ final FileResource fr = new FileResource();
+ fr.setProject(getProject());
+ fr.setFile(stylesheet);
+ configureLiaison(fr);
+ }
+
+ /**
+ * Loads the stylesheet and set xsl:param parameters.
+ *
+ * @param stylesheet the resource from which to load the stylesheet.
+ * @exception BuildException if the stylesheet cannot be loaded.
+ * @since Ant 1.7
+ */
+ protected void configureLiaison(final Resource stylesheet) throws BuildException {
+ if (stylesheetLoaded && reuseLoadedStylesheet) {
+ return;
+ }
+ stylesheetLoaded = true;
+
+ try {
+ log("Loading stylesheet " + stylesheet, Project.MSG_INFO);
+ // We call liaison.configure() and then liaison.setStylesheet()
+ // so that the internal variables of liaison can be set up
+ if (liaison instanceof XSLTLiaison2) {
+ ((XSLTLiaison2) liaison).configure(this);
+ }
+ if (liaison instanceof XSLTLiaison3) {
+ // If we are here we can set the stylesheet as a
+ // resource
+ ((XSLTLiaison3) liaison).setStylesheet(stylesheet);
+ } else {
+ // If we are here we cannot set the stylesheet as
+ // a resource, but we can set it as a file. So,
+ // we make an attempt to get it as a file
+ final FileProvider fp =
+ stylesheet.as(FileProvider.class);
+ if (fp != null) {
+ liaison.setStylesheet(fp.getFile());
+ } else {
+ handleError(liaison.getClass().toString()
+ + " accepts the stylesheet only as a file");
+ return;
+ }
+ }
+ for (final Param p : params) {
+ if (p.shouldUse()) {
+ final Object evaluatedParam = evaluateParam(p);
+ if (liaison instanceof XSLTLiaison4) {
+ ((XSLTLiaison4)liaison).addParam(p.getName(), evaluatedParam);
+ } else {
+ if (evaluatedParam == null || evaluatedParam instanceof String) {
+ liaison.addParam(p.getName(), (String)evaluatedParam);
+ } else {
+ log("XSLTLiaison '" + liaison.getClass().getName()
+ + "' supports only String parameters. Converting parameter '" + p.getName()
+ + "' to its String value '" + evaluatedParam, Project.MSG_WARN);
+ liaison.addParam(p.getName(), String.valueOf(evaluatedParam));
+ }
+ }
+ }
+ }
+ } catch (final Exception ex) {
+ log("Failed to transform using stylesheet " + stylesheet, Project.MSG_INFO);
+ handleTransformationError(ex);
+ }
+ }
+
+ /**
+ * Evaluates parameter expression according to its type.
+ *
+ * @param param parameter from Ant build file
+ * @return value to be passed to XSLT as parameter
+ * @throws IllegalArgumentException if param type is unsupported
+ * @throws NumberFormatException if expression of numeric type is not
+ * desired numeric type
+ * @throws XPathExpressionException if XPath expression can not be compiled
+ * @since Ant 1.9.3
+ */
+ private Object evaluateParam(final Param param) throws XPathExpressionException {
+ final String typeName = param.getType();
+ final String expression = param.getExpression();
+
+ ParamType type;
+
+ if (typeName == null || "".equals(typeName)) {
+ type = ParamType.STRING; // String is default
+ } else {
+ try {
+ type = ParamType.valueOf(typeName);
+ } catch (final IllegalArgumentException e) {
+ throw new IllegalArgumentException("Invalid XSLT parameter type: " + typeName, e);
+ }
+ }
+
+ switch (type) {
+ case STRING:
+ return expression;
+ case BOOLEAN:
+ return Boolean.parseBoolean(expression);
+ case DOUBLE:
+ return Double.parseDouble(expression);
+ case INT:
+ return Integer.parseInt(expression);
+ case LONG:
+ return Long.parseLong(expression);
+ default: // XPath expression
+ final QName xpathType = ParamType.XPATH_TYPES.get(type);
+ if (xpathType == null) {
+ throw new IllegalArgumentException("Invalid XSLT parameter type: " + typeName);
+ } else {
+ final XPathExpression xpe = xpath.compile(expression);
+ // null = evaluate XPath on empty XML document
+ return xpe.evaluate((Object) null, xpathType);
+ }
+ }
+ }
+
+ /**
+ * Sets file parameter(s) for directory and filename if the attribute
+ * 'filenameparameter' or 'filedirparameter' are set in the task.
+ *
+ * @param liaison to change parameters for
+ * @param inFile to get the additional file information from
+ * @throws Exception if an exception occurs on filename lookup
+ *
+ * @since Ant 1.7
+ */
+ private void setLiaisonDynamicFileParameters(
+ final XSLTLiaison liaison, final File inFile) throws Exception {
+ if (fileNameParameter != null) {
+ liaison.addParam(fileNameParameter, inFile.getName());
+ }
+ if (fileDirParameter != null) {
+ final String fileName = FileUtils.getRelativePath(baseDir, inFile);
+ final File file = new File(fileName);
+ // Give always a slash as file separator, so the stylesheet could be sure about that
+ // Use '.' so a dir+"/"+name would not result in an absolute path
+ liaison.addParam(fileDirParameter, file.getParent() != null ? file.getParent().replace(
+ '\\', '/') : ".");
+ }
+ }
+
+ /**
+ * Create the factory element to configure a trax liaison.
+ * @return the newly created factory element.
+ * @throws BuildException if the element is created more than one time.
+ */
+ public Factory createFactory() throws BuildException {
+ if (factory != null) {
+ handleError("'factory' element must be unique");
+ } else {
+ factory = new Factory();
+ }
+ return factory;
+ }
+
+ /**
+ * Throws an exception with the given message if failOnError is
+ * true, otherwise logs the message using the WARN level.
+ *
+ * @since Ant 1.8.0
+ */
+ protected void handleError(final String msg) {
+ if (failOnError) {
+ throw new BuildException(msg, getLocation());
+ }
+ log(msg, Project.MSG_WARN);
+ }
+
+
+ /**
+ * Throws an exception with the given nested exception if
+ * failOnError is true, otherwise logs the message using the WARN
+ * level.
+ *
+ * @since Ant 1.8.0
+ */
+ protected void handleError(final Throwable ex) {
+ if (failOnError) {
+ throw new BuildException(ex);
+ } else {
+ log("Caught an exception: " + ex, Project.MSG_WARN);
+ }
+ }
+
+ /**
+ * Throws an exception with the given nested exception if
+ * failOnError and failOnTransformationError are true, otherwise
+ * logs the message using the WARN level.
+ *
+ * @since Ant 1.8.0
+ */
+ protected void handleTransformationError(final Exception ex) {
+ if (failOnError && failOnTransformationError) {
+ throw new BuildException(ex);
+ } else {
+ log("Caught an error during transformation: " + ex,
+ Project.MSG_WARN);
+ }
+ }
+
+ /**
+ * The factory element to configure a transformer factory
+ * @since Ant 1.6
+ */
+ public static class Factory {
+
+ /** the factory class name to use for TraXLiaison */
+ private String name;
+
+ /**
+ * the list of factory attributes to use for TraXLiaison
+ */
+ private final Vector attributes = new Vector();
+
+ /**
+ * @return the name of the factory.
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Set the name of the factory
+ * @param name the name of the factory.
+ */
+ public void setName(final String name) {
+ this.name = name;
+ }
+
+ /**
+ * Create an instance of a factory attribute.
+ * @param attr the newly created factory attribute
+ */
+ public void addAttribute(final Attribute attr) {
+ attributes.addElement(attr);
+ }
+
+ /**
+ * return the attribute elements.
+ * @return the enumeration of attributes
+ */
+ public Enumeration getAttributes() {
+ return attributes.elements();
+ }
+
+ /**
+ * A JAXP factory attribute. This is mostly processor specific, for
+ * example for Xalan 2.3+, the following attributes could be set:
+ * <ul>
+ * <li>http://xml.apache.org/xalan/features/optimize (true|false) </li>
+ * <li>http://xml.apache.org/xalan/features/incremental (true|false) </li>
+ * </ul>
+ */
+ public static class Attribute implements DynamicConfigurator {
+
+ /** attribute name, mostly processor specific */
+ private String name;
+
+ /** attribute value, often a boolean string */
+ private Object value;
+
+ /**
+ * @return the attribute name.
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * @return the output property value.
+ */
+ public Object getValue() {
+ return value;
+ }
+
+ /**
+ * Not used.
+ * @param name not used
+ * @return null
+ * @throws BuildException never
+ */
+ public Object createDynamicElement(final String name) throws BuildException {
+ return null;
+ }
+
+ /**
+ * Set an attribute.
+ * Only "name" and "value" are supported as names.
+ * @param name the name of the attribute
+ * @param value the value of the attribute
+ * @throws BuildException on error
+ */
+ public void setDynamicAttribute(final String name, final String value) throws BuildException {
+ // only 'name' and 'value' exist.
+ if ("name".equalsIgnoreCase(name)) {
+ this.name = value;
+ } else if ("value".equalsIgnoreCase(name)) {
+ // a value must be of a given type
+ // say boolean|integer|string that are mostly used.
+ if ("true".equalsIgnoreCase(value)) {
+ this.value = Boolean.TRUE;
+ } else if ("false".equalsIgnoreCase(value)) {
+ this.value = Boolean.FALSE;
+ } else {
+ try {
+ this.value = new Integer(value);
+ } catch (final NumberFormatException e) {
+ this.value = value;
+ }
+ }
+ } else {
+ throw new BuildException("Unsupported attribute: " + name);
+ }
+ }
+ } // -- class Attribute
+ } // -- class Factory
+
+ /**
+ * Mapper implementation of the "traditional" way &lt;xslt&gt;
+ * mapped filenames.
+ *
+ * <p>If the file has an extension, chop it off. Append whatever
+ * the user has specified as extension or ".html".</p>
+ *
+ * @since Ant 1.6.2
+ */
+ private class StyleMapper implements FileNameMapper {
+ public void setFrom(final String from) {
+ }
+ public void setTo(final String to) {
+ }
+ public String[] mapFileName(String xmlFile) {
+ final int dotPos = xmlFile.lastIndexOf('.');
+ if (dotPos > 0) {
+ xmlFile = xmlFile.substring(0, dotPos);
+ }
+ return new String[] {xmlFile + targetExtension};
+ }
+ }
+
+ /**
+ * Configuration for Xalan2 traces.
+ *
+ * @since Ant 1.8.0
+ */
+ public final class TraceConfiguration {
+ private boolean elements, extension, generation, selection, templates;
+
+ /**
+ * Set to true if the listener is to print events that occur
+ * as each node is 'executed' in the stylesheet.
+ */
+ public void setElements(final boolean b) {
+ elements = b;
+ }
+
+ /**
+ * True if the listener is to print events that occur as each
+ * node is 'executed' in the stylesheet.
+ */
+ public boolean getElements() {
+ return elements;
+ }
+
+ /**
+ * Set to true if the listener is to print information after
+ * each extension event.
+ */
+ public void setExtension(final boolean b) {
+ extension = b;
+ }
+
+ /**
+ * True if the listener is to print information after each
+ * extension event.
+ */
+ public boolean getExtension() {
+ return extension;
+ }
+
+ /**
+ * Set to true if the listener is to print information after
+ * each result-tree generation event.
+ */
+ public void setGeneration(final boolean b) {
+ generation = b;
+ }
+
+ /**
+ * True if the listener is to print information after each
+ * result-tree generation event.
+ */
+ public boolean getGeneration() {
+ return generation;
+ }
+
+ /**
+ * Set to true if the listener is to print information after
+ * each selection event.
+ */
+ public void setSelection(final boolean b) {
+ selection = b;
+ }
+
+ /**
+ * True if the listener is to print information after each
+ * selection event.
+ */
+ public boolean getSelection() {
+ return selection;
+ }
+
+ /**
+ * Set to true if the listener is to print an event whenever a
+ * template is invoked.
+ */
+ public void setTemplates(final boolean b) {
+ templates = b;
+ }
+
+ /**
+ * True if the listener is to print an event whenever a
+ * template is invoked.
+ */
+ public boolean getTemplates() {
+ return templates;
+ }
+
+ /**
+ * The stream to write traces to.
+ */
+ public java.io.OutputStream getOutputStream() {
+ return new LogOutputStream(XSLTProcess.this);
+ }
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/XmlProperty.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/XmlProperty.java
new file mode 100644
index 00000000..2830bdf9
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/XmlProperty.java
@@ -0,0 +1,780 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Hashtable;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.ResourceCollection;
+import org.apache.tools.ant.types.XMLCatalog;
+import org.apache.tools.ant.types.resources.FileProvider;
+import org.apache.tools.ant.types.resources.FileResource;
+import org.apache.tools.ant.util.FileUtils;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.EntityResolver;
+import org.xml.sax.SAXException;
+
+/**
+ * Loads property values from a valid XML file, generating the
+ * property names from the file's element and attribute names.
+ *
+ * <p>Example:</p>
+ * <pre>
+ * &lt;root-tag myattr="true"&gt;
+ * &lt;inner-tag someattr="val"&gt;Text&lt;/inner-tag&gt;
+ * &lt;a2&gt;&lt;a3&gt;&lt;a4&gt;false&lt;/a4&gt;&lt;/a3&gt;&lt;/a2&gt;
+ * &lt;x&gt;x1&lt;/x&gt;
+ * &lt;x&gt;x2&lt;/x&gt;
+ * &lt;/root-tag&gt;
+ *</pre>
+ *
+ * <p>this generates the following properties:</p>
+ *
+ * <pre>
+ * root-tag(myattr)=true
+ * root-tag.inner-tag=Text
+ * root-tag.inner-tag(someattr)=val
+ * root-tag.a2.a3.a4=false
+ * root-tag.x=x1,x2
+ * </pre>
+ *
+ * <p>The <i>collapseAttributes</i> property of this task can be set
+ * to true (the default is false) which will instead result in the
+ * following properties (note the difference in names of properties
+ * corresponding to XML attributes):</p>
+ *
+ * <pre>
+ * root-tag.myattr=true
+ * root-tag.inner-tag=Text
+ * root-tag.inner-tag.someattr=val
+ * root-tag.a2.a3.a4=false
+ * root-tag.x=x1,x2
+ * </pre>
+ *
+ * <p>Optionally, to more closely mirror the abilities of the Property
+ * task, a selected set of attributes can be treated specially. To
+ * enable this behavior, the "semanticAttributes" property of this task
+ * must be set to true (it defaults to false). If this attribute is
+ * specified, the following attributes take on special meaning
+ * (setting this to true implicitly sets collapseAttributes to true as
+ * well):</p>
+ *
+ * <ul>
+ * <li><b>value</b>: Identifies a text value for a property.</li>
+ * <li><b>location</b>: Identifies a file location for a property.</li>
+ * <li><b>id</b>: Sets an id for a property</li>
+ * <li><b>refid</b>: Sets a property to the value of another property
+ * based upon the provided id</li>
+ * <li><b>pathid</b>: Defines a path rather than a property with
+ * the given id.</li>
+ * </ul>
+ *
+ * <p>For example, with keepRoot = false, the following properties file:</p>
+ *
+ * <pre>
+ * &lt;root-tag&gt;
+ * &lt;build&gt;
+ * &lt;build folder="build"&gt;
+ * &lt;classes id="build.classes" location="${build.folder}/classes"/&gt;
+ * &lt;reference refid="build.classes"/&gt;
+ * &lt;/build&gt;
+ * &lt;compile&gt;
+ * &lt;classpath pathid="compile.classpath"&gt;
+ * &lt;pathelement location="${build.classes}"/&gt;
+ * &lt;/classpath&gt;
+ * &lt;/compile&gt;
+ * &lt;run-time&gt;
+ * &lt;jars&gt;*.jar&lt;/jars&gt;
+ * &lt;classpath pathid="run-time.classpath"&gt;
+ * &lt;path refid="compile.classpath"/&gt;
+ * &lt;pathelement path="${run-time.jars}"/&gt;
+ * &lt;/classpath&gt;
+ * &lt;/run-time&gt;
+ * &lt;/root-tag&gt;
+ * </pre>
+ *
+ * <p>is equivalent to the following entries in a build file:</p>
+ *
+ * <pre>
+ * &lt;property name="build" location="build"/&gt;
+ * &lt;property name="build.classes" location="${build.location}/classes"/&gt;
+ * &lt;property name="build.reference" refid="build.classes"/&gt;
+ *
+ * &lt;property name="run-time.jars" value="*.jar/&gt;
+ *
+ * &lt;classpath id="compile.classpath"&gt;
+ * &lt;pathelement location="${build.classes}"/&gt;
+ * &lt;/classpath&gt;
+ *
+ * &lt;classpath id="run-time.classpath"&gt;
+ * &lt;path refid="compile.classpath"/&gt;
+ * &lt;pathelement path="${run-time.jars}"/&gt;
+ * &lt;/classpath&gt;
+ * </pre>
+ *
+ * <p> This task <i>requires</i> the following attributes:</p>
+ *
+ * <ul>
+ * <li><b>file</b>: The name of the file to load.</li>
+ * </ul>
+ *
+ * <p>This task supports the following attributes:</p>
+ *
+ * <ul>
+ * <li><b>prefix</b>: Optionally specify a prefix applied to
+ * all properties loaded. Defaults to an empty string.</li>
+ * <li><b>keepRoot</b>: Indicate whether the root xml element
+ * is kept as part of property name. Defaults to true.</li>
+ * <li><b>validate</b>: Indicate whether the xml file is validated.
+ * Defaults to false.</li>
+ * <li><b>collapseAttributes</b>: Indicate whether attributes are
+ * stored in property names with parens or with period
+ * delimiters. Defaults to false, meaning properties
+ * are stored with parens (i.e., foo(attr)).</li>
+ * <li><b>semanticAttributes</b>: Indicate whether attributes
+ * named "location", "value", "refid" and "path"
+ * are interpreted as ant properties. Defaults
+ * to false.</li>
+ * <li><b>rootDirectory</b>: Indicate the directory to use
+ * as the root directory for resolving location
+ * properties. Defaults to the directory
+ * of the project using the task.</li>
+ * <li><b>includeSemanticAttribute</b>: Indicate whether to include
+ * the semantic attribute ("location" or "value") as
+ * part of the property name. Defaults to false.</li>
+ * </ul>
+ *
+ * @ant.task name="xmlproperty" category="xml"
+ */
+public class XmlProperty extends org.apache.tools.ant.Task {
+
+ private Resource src;
+ private String prefix = "";
+ private boolean keepRoot = true;
+ private boolean validate = false;
+ private boolean collapseAttributes = false;
+ private boolean semanticAttributes = false;
+ private boolean includeSemanticAttribute = false;
+ private File rootDirectory = null;
+ private Hashtable addedAttributes = new Hashtable();
+ private XMLCatalog xmlCatalog = new XMLCatalog();
+ private String delimiter = ",";
+
+ private static final String ID = "id";
+ private static final String REF_ID = "refid";
+ private static final String LOCATION = "location";
+ private static final String VALUE = "value";
+ private static final String PATH = "path";
+ private static final String PATHID = "pathid";
+ private static final String[] ATTRIBUTES = new String[] {
+ ID, REF_ID, LOCATION, VALUE, PATH, PATHID
+ };
+
+ private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+
+ /**
+ * Constructor.
+ */
+ public XmlProperty() {
+ super();
+ }
+
+ /**
+ * Initializes the task.
+ */
+
+ public void init() {
+ super.init();
+ xmlCatalog.setProject(getProject());
+ }
+
+ /**
+ * @return the xmlCatalog as the entityresolver.
+ */
+ protected EntityResolver getEntityResolver() {
+ return xmlCatalog;
+ }
+
+ /**
+ * Run the task.
+ * @throws BuildException The exception raised during task execution.
+ * @todo validate the source file is valid before opening, print a better error message
+ * @todo add a verbose level log message listing the name of the file being loaded
+ */
+ public void execute() throws BuildException {
+ Resource r = getResource();
+
+ if (r == null) {
+ throw new BuildException("XmlProperty task requires a source resource");
+ }
+ try {
+ log("Loading " + src, Project.MSG_VERBOSE);
+
+ if (r.isExists()) {
+
+ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+ factory.setValidating(validate);
+ factory.setNamespaceAware(false);
+ DocumentBuilder builder = factory.newDocumentBuilder();
+ builder.setEntityResolver(getEntityResolver());
+ Document document = null;
+ FileProvider fp = src.as(FileProvider.class);
+ if (fp != null) {
+ document = builder.parse(fp.getFile());
+ } else {
+ document = builder.parse(src.getInputStream());
+ }
+ Element topElement = document.getDocumentElement();
+
+ // Keep a hashtable of attributes added by this task.
+ // This task is allow to override its own properties
+ // but not other properties. So we need to keep track
+ // of which properties we've added.
+ addedAttributes = new Hashtable();
+
+ if (keepRoot) {
+ addNodeRecursively(topElement, prefix, null);
+ } else {
+ NodeList topChildren = topElement.getChildNodes();
+ int numChildren = topChildren.getLength();
+ for (int i = 0; i < numChildren; i++) {
+ addNodeRecursively(topChildren.item(i), prefix, null);
+ }
+ }
+ } else {
+ log("Unable to find property resource: " + r, Project.MSG_VERBOSE);
+ }
+
+ } catch (SAXException sxe) {
+ // Error generated during parsing
+ Exception x = sxe;
+ if (sxe.getException() != null) {
+ x = sxe.getException();
+ }
+ throw new BuildException("Failed to load " + src, x);
+ } catch (ParserConfigurationException pce) {
+ // Parser with specified options can't be built
+ throw new BuildException(pce);
+ } catch (IOException ioe) {
+ // I/O error
+ throw new BuildException("Failed to load " + src, ioe);
+ }
+ }
+
+ /** Iterate through all nodes in the tree. */
+ private void addNodeRecursively(Node node, String prefix, Object container) {
+ // Set the prefix for this node to include its tag name.
+ String nodePrefix = prefix;
+ if (node.getNodeType() != Node.TEXT_NODE) {
+ if (prefix.trim().length() > 0) {
+ nodePrefix += ".";
+ }
+ nodePrefix += node.getNodeName();
+ }
+ // Pass the container to the processing of this node,
+ Object nodeObject = processNode(node, nodePrefix, container);
+
+ // now, iterate through children.
+ if (node.hasChildNodes()) {
+ NodeList nodeChildren = node.getChildNodes();
+ int numChildren = nodeChildren.getLength();
+
+ for (int i = 0; i < numChildren; i++) {
+ // For each child, pass the object added by
+ // processNode to its children -- in other word, each
+ // object can pass information along to its children.
+ addNodeRecursively(nodeChildren.item(i), nodePrefix, nodeObject);
+ }
+ }
+ }
+
+ void addNodeRecursively(org.w3c.dom.Node node, String prefix) {
+ addNodeRecursively(node, prefix, null);
+ }
+
+ /**
+ * Process the given node, adding any required attributes from
+ * this child node alone -- but <em>not</em> processing any
+ * children.
+ *
+ * @param node the XML Node to parse
+ * @param prefix A string to prepend to any properties that get
+ * added by this node.
+ * @param container Optionally, an object that a parent node
+ * generated that this node might belong to. For example, this
+ * node could be within a node that generated a Path.
+ * @return the Object created by this node. Generally, this is
+ * either a String if this node resulted in setting an attribute,
+ * or a Path.
+ */
+ public Object processNode (Node node, String prefix, Object container) {
+
+ // Parse the attribute(s) and text of this node, adding
+ // properties for each.
+ // if the "path" attribute is specified, then return the created path
+ // which will be passed to the children of this node.
+ Object addedPath = null;
+
+ // The value of an id attribute of this node.
+ String id = null;
+
+ if (node.hasAttributes()) {
+
+ NamedNodeMap nodeAttributes = node.getAttributes();
+
+ // Is there an id attribute?
+ Node idNode = nodeAttributes.getNamedItem(ID);
+ id = semanticAttributes && idNode != null ? idNode.getNodeValue() : null;
+
+ // Now, iterate through the attributes adding them.
+ for (int i = 0; i < nodeAttributes.getLength(); i++) {
+
+ Node attributeNode = nodeAttributes.item(i);
+
+ if (!semanticAttributes) {
+ String attributeName = getAttributeName(attributeNode);
+ String attributeValue = getAttributeValue(attributeNode);
+ addProperty(prefix + attributeName, attributeValue, null);
+ } else {
+ String nodeName = attributeNode.getNodeName();
+ String attributeValue = getAttributeValue(attributeNode);
+
+ Path containingPath =
+ ((container != null) && (container instanceof Path))
+ ? (Path) container
+ : null;
+ /*
+ * The main conditional logic -- if the attribute
+ * is somehow "special" (i.e., it has known
+ * semantic meaning) then deal with it
+ * appropriately.
+ */
+ if (nodeName.equals(ID)) {
+ // ID has already been found above.
+ continue;
+ }
+ if (containingPath != null && nodeName.equals(PATH)) {
+ // A "path" attribute for a node within a Path object.
+ containingPath.setPath(attributeValue);
+ } else if (container instanceof Path && nodeName.equals(REF_ID)) {
+ // A "refid" attribute for a node within a Path object.
+ containingPath.setPath(attributeValue);
+ } else if (container instanceof Path && nodeName.equals(LOCATION)) {
+ // A "location" attribute for a node within a
+ // Path object.
+ containingPath.setLocation(resolveFile(attributeValue));
+ } else if (nodeName.equals(PATHID)) {
+ // A node identifying a new path
+ if (container != null) {
+ throw new BuildException("XmlProperty does not support nested paths");
+ }
+ addedPath = new Path(getProject());
+ getProject().addReference(attributeValue, addedPath);
+ } else {
+ // An arbitrary attribute.
+ String attributeName = getAttributeName(attributeNode);
+ addProperty(prefix + attributeName, attributeValue, id);
+ }
+ }
+ }
+ }
+ String nodeText = null;
+ boolean emptyNode = false;
+ boolean semanticEmptyOverride = false;
+ if (node.getNodeType() == Node.ELEMENT_NODE
+ && semanticAttributes
+ && node.hasAttributes()
+ && (node.getAttributes().getNamedItem(VALUE) != null
+ || node.getAttributes().getNamedItem(LOCATION) != null
+ || node.getAttributes().getNamedItem(REF_ID) != null
+ || node.getAttributes().getNamedItem(PATH) != null || node.getAttributes()
+ .getNamedItem(PATHID) != null)) {
+ semanticEmptyOverride = true;
+ }
+ if (node.getNodeType() == Node.TEXT_NODE) {
+ // For the text node, add a property.
+ nodeText = getAttributeValue(node);
+ } else if (node.getNodeType() == Node.ELEMENT_NODE
+ && node.getChildNodes().getLength() == 1
+ && node.getFirstChild().getNodeType() == Node.CDATA_SECTION_NODE) {
+
+ nodeText = node.getFirstChild().getNodeValue();
+ if ("".equals(nodeText) && !semanticEmptyOverride) {
+ emptyNode = true;
+ }
+ } else if (node.getNodeType() == Node.ELEMENT_NODE
+ && node.getChildNodes().getLength() == 0
+ && !semanticEmptyOverride) {
+ nodeText = "";
+ emptyNode = true;
+ } else if (node.getNodeType() == Node.ELEMENT_NODE
+ && node.getChildNodes().getLength() == 1
+ && node.getFirstChild().getNodeType() == Node.TEXT_NODE
+ && "".equals(node.getFirstChild().getNodeValue())
+ && !semanticEmptyOverride) {
+ nodeText = "";
+ emptyNode = true;
+ }
+ if (nodeText != null) {
+ // If the containing object was a String, then use it as the ID.
+ if (semanticAttributes && id == null && container instanceof String) {
+ id = (String) container;
+ }
+ if (nodeText.trim().length() != 0 || emptyNode) {
+ addProperty(prefix, nodeText, id);
+ }
+ }
+ // Return the Path we added or the ID of this node for
+ // children to reference if needed. Path objects are
+ // definitely used by child path elements, and ID may be used
+ // for a child text node.
+ return (addedPath != null ? addedPath : id);
+ }
+
+ /**
+ * Actually add the given property/value to the project
+ * after writing a log message.
+ */
+ private void addProperty (String name, String value, String id) {
+ String msg = name + ":" + value;
+ if (id != null) {
+ msg += ("(id=" + id + ")");
+ }
+ log(msg, Project.MSG_DEBUG);
+
+ if (addedAttributes.containsKey(name)) {
+ // If this attribute was added by this task, then
+ // we append this value to the existing value.
+ // We use the setProperty method which will
+ // forcibly override the property if it already exists.
+ // We need to put these properties into the project
+ // when we read them, though (instead of keeping them
+ // outside of the project and batch adding them at the end)
+ // to allow other properties to reference them.
+ value = (String) addedAttributes.get(name) + getDelimiter() + value;
+ getProject().setProperty(name, value);
+ addedAttributes.put(name, value);
+ } else if (getProject().getProperty(name) == null) {
+ getProject().setNewProperty(name, value);
+ addedAttributes.put(name, value);
+ } else {
+ log("Override ignored for property " + name, Project.MSG_VERBOSE);
+ }
+ if (id != null) {
+ getProject().addReference(id, value);
+ }
+ }
+
+ /**
+ * Return a reasonable attribute name for the given node.
+ * If we are using semantic attributes or collapsing
+ * attributes, the returned name is ".nodename".
+ * Otherwise, we return "(nodename)". This is long-standing
+ * (and default) &lt;xmlproperty&gt; behavior.
+ */
+ private String getAttributeName (Node attributeNode) {
+ String attributeName = attributeNode.getNodeName();
+
+ if (semanticAttributes) {
+ // Never include the "refid" attribute as part of the
+ // attribute name.
+ if (attributeName.equals(REF_ID)) {
+ return "";
+ }
+ // Otherwise, return it appended unless property to hide it is set.
+ if (!isSemanticAttribute(attributeName) || includeSemanticAttribute) {
+ return "." + attributeName;
+ }
+ return "";
+ }
+ return collapseAttributes ? "." + attributeName : "(" + attributeName + ")";
+ }
+
+ /**
+ * Return whether the provided attribute name is recognized or not.
+ */
+ private static boolean isSemanticAttribute (String attributeName) {
+ for (int i = 0; i < ATTRIBUTES.length; i++) {
+ if (attributeName.equals(ATTRIBUTES[i])) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Return the value for the given attribute.
+ * If we are not using semantic attributes, its just the
+ * literal string value of the attribute.
+ *
+ * <p>If we <em>are</em> using semantic attributes, then first
+ * dependent properties are resolved (i.e., ${foo} is resolved
+ * based on the foo property value), and then an appropriate data
+ * type is used. In particular, location-based properties are
+ * resolved to absolute file names. Also for refid values, look
+ * up the referenced object from the project.</p>
+ */
+ private String getAttributeValue (Node attributeNode) {
+ String nodeValue = attributeNode.getNodeValue().trim();
+ if (semanticAttributes) {
+ String attributeName = attributeNode.getNodeName();
+ nodeValue = getProject().replaceProperties(nodeValue);
+ if (attributeName.equals(LOCATION)) {
+ File f = resolveFile(nodeValue);
+ return f.getPath();
+ }
+ if (attributeName.equals(REF_ID)) {
+ Object ref = getProject().getReference(nodeValue);
+ if (ref != null) {
+ return ref.toString();
+ }
+ }
+ }
+ return nodeValue;
+ }
+
+ /**
+ * The XML file to parse; required.
+ * @param src the file to parse
+ */
+ public void setFile(File src) {
+ setSrcResource(new FileResource(src));
+ }
+
+ /**
+ * The resource to pack; required.
+ * @param src resource to expand
+ */
+ public void setSrcResource(Resource src) {
+ if (src.isDirectory()) {
+ throw new BuildException("the source can't be a directory");
+ }
+ if (src.as(FileProvider.class) != null || supportsNonFileResources()) {
+ this.src = src;
+ } else {
+ throw new BuildException("Only FileSystem resources are supported.");
+ }
+ }
+
+ /**
+ * Set the source resource.
+ * @param a the resource to pack as a single element Resource collection.
+ */
+ public void addConfigured(ResourceCollection a) {
+ if (a.size() != 1) {
+ throw new BuildException(
+ "only single argument resource collections are supported as archives");
+ }
+ setSrcResource(a.iterator().next());
+ }
+
+ /**
+ * the prefix to prepend to each property
+ * @param prefix the prefix to prepend to each property
+ */
+ public void setPrefix(String prefix) {
+ this.prefix = prefix.trim();
+ }
+
+ /**
+ * flag to include the xml root tag as a
+ * first value in the property name; optional,
+ * default is true
+ * @param keepRoot if true (default), include the xml root tag
+ */
+ public void setKeeproot(boolean keepRoot) {
+ this.keepRoot = keepRoot;
+ }
+
+ /**
+ * flag to validate the XML file; optional, default false
+ * @param validate if true validate the XML file, default false
+ */
+ public void setValidate(boolean validate) {
+ this.validate = validate;
+ }
+
+ /**
+ * flag to treat attributes as nested elements;
+ * optional, default false
+ * @param collapseAttributes if true treat attributes as nested elements
+ */
+ public void setCollapseAttributes(boolean collapseAttributes) {
+ this.collapseAttributes = collapseAttributes;
+ }
+
+ /**
+ * Attribute to enable special handling of attributes - see ant manual.
+ * @param semanticAttributes if true enable the special handling.
+ */
+ public void setSemanticAttributes(boolean semanticAttributes) {
+ this.semanticAttributes = semanticAttributes;
+ }
+
+ /**
+ * The directory to use for resolving file references.
+ * Ignored if semanticAttributes is not set to true.
+ * @param rootDirectory the directory.
+ */
+ public void setRootDirectory(File rootDirectory) {
+ this.rootDirectory = rootDirectory;
+ }
+
+ /**
+ * Include the semantic attribute name as part of the property name.
+ * Ignored if semanticAttributes is not set to true.
+ * @param includeSemanticAttribute if true include the semantic attribute
+ * name.
+ */
+ public void setIncludeSemanticAttribute(boolean includeSemanticAttribute) {
+ this.includeSemanticAttribute = includeSemanticAttribute;
+ }
+
+ /**
+ * add an XMLCatalog as a nested element; optional.
+ * @param catalog the XMLCatalog to use
+ */
+ public void addConfiguredXMLCatalog(XMLCatalog catalog) {
+ xmlCatalog.addConfiguredXMLCatalog(catalog);
+ }
+
+ /* Expose members for extensibility */
+
+ /**
+ * @return the file attribute.
+ */
+ protected File getFile () {
+ FileProvider fp = src.as(FileProvider.class);
+ return fp != null ? fp.getFile() : null;
+ }
+
+ /**
+ * @return the resource.
+ */
+ protected Resource getResource() {
+ // delegate this way around to support subclasses that
+ // overwrite getFile
+ File f = getFile();
+ FileProvider fp = src.as(FileProvider.class);
+ return f == null ? src : fp != null
+ && fp.getFile().equals(f) ? src : new FileResource(f);
+ }
+
+ /**
+ * @return the prefix attribute.
+ */
+ protected String getPrefix () {
+ return this.prefix;
+ }
+
+ /**
+ * @return the keeproot attribute.
+ */
+ protected boolean getKeeproot () {
+ return this.keepRoot;
+ }
+
+ /**
+ * @return the validate attribute.
+ */
+ protected boolean getValidate () {
+ return this.validate;
+ }
+
+ /**
+ * @return the collapse attributes attribute.
+ */
+ protected boolean getCollapseAttributes () {
+ return this.collapseAttributes;
+ }
+
+ /**
+ * @return the semantic attributes attribute.
+ */
+ protected boolean getSemanticAttributes () {
+ return this.semanticAttributes;
+ }
+
+ /**
+ * @return the root directory attribute.
+ */
+ protected File getRootDirectory () {
+ return this.rootDirectory;
+ }
+
+ /**
+ * @return the include semantic attribute.
+ */
+ protected boolean getIncludeSementicAttribute () {
+ return this.includeSemanticAttribute;
+ }
+
+ /**
+ * Let project resolve the file - or do it ourselves if
+ * rootDirectory has been set.
+ */
+ private File resolveFile(String fileName) {
+ return FILE_UTILS.resolveFile(rootDirectory == null ? getProject().getBaseDir()
+ : rootDirectory, fileName);
+ }
+
+ /**
+ * Whether this task can deal with non-file resources.
+ *
+ * <p>This implementation returns true only if this task is
+ * &lt;xmlproperty&gt;. Any subclass of this class that also wants to
+ * support non-file resources needs to override this method. We
+ * need to do so for backwards compatibility reasons since we
+ * can't expect subclasses to support resources.</p>
+ * @return true for this task.
+ * @since Ant 1.7
+ */
+ protected boolean supportsNonFileResources() {
+ return getClass().equals(XmlProperty.class);
+ }
+
+ /**
+ * Get the current delimiter.
+ * @return delimiter
+ */
+ public String getDelimiter() {
+ return delimiter;
+ }
+
+ /**
+ * Sets a new delimiter.
+ * @param delimiter new value
+ * @since Ant 1.7.1
+ */
+ public void setDelimiter(String delimiter) {
+ this.delimiter = delimiter;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Zip.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Zip.java
new file mode 100644
index 00000000..ddc9bd49
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Zip.java
@@ -0,0 +1,2274 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Map;
+import java.util.Stack;
+import java.util.Vector;
+import java.util.zip.CRC32;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.DirectoryScanner;
+import org.apache.tools.ant.FileScanner;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.ArchiveFileSet;
+import org.apache.tools.ant.types.EnumeratedAttribute;
+import org.apache.tools.ant.types.FileSet;
+import org.apache.tools.ant.types.PatternSet;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.ResourceCollection;
+import org.apache.tools.ant.types.ZipFileSet;
+import org.apache.tools.ant.types.ZipScanner;
+import org.apache.tools.ant.types.resources.ArchiveResource;
+import org.apache.tools.ant.types.resources.FileProvider;
+import org.apache.tools.ant.types.resources.FileResource;
+import org.apache.tools.ant.types.resources.Union;
+import org.apache.tools.ant.types.resources.ZipResource;
+import org.apache.tools.ant.types.resources.selectors.ResourceSelector;
+import org.apache.tools.ant.util.FileNameMapper;
+import org.apache.tools.ant.util.FileUtils;
+import org.apache.tools.ant.util.GlobPatternMapper;
+import org.apache.tools.ant.util.IdentityMapper;
+import org.apache.tools.ant.util.MergingMapper;
+import org.apache.tools.ant.util.ResourceUtils;
+import org.apache.tools.zip.UnixStat;
+import org.apache.tools.zip.Zip64Mode;
+import org.apache.tools.zip.ZipEntry;
+import org.apache.tools.zip.ZipExtraField;
+import org.apache.tools.zip.ZipFile;
+import org.apache.tools.zip.ZipOutputStream;
+import org.apache.tools.zip.ZipOutputStream.UnicodeExtraFieldPolicy;
+
+/**
+ * Create a Zip file.
+ *
+ * @since Ant 1.1
+ *
+ * @ant.task category="packaging"
+ */
+public class Zip extends MatchingTask {
+ private static final int BUFFER_SIZE = 8 * 1024;
+ private static final int ROUNDUP_MILLIS = 1999; // 2 seconds - 1
+ // CheckStyle:VisibilityModifier OFF - bc
+
+ protected File zipFile;
+ // use to scan own archive
+ private ZipScanner zs;
+ private File baseDir;
+ protected Hashtable<String, String> entries = new Hashtable<String, String>();
+ private final Vector<FileSet> groupfilesets = new Vector<FileSet>();
+ private final Vector<ZipFileSet> filesetsFromGroupfilesets = new Vector<ZipFileSet>();
+ protected String duplicate = "add";
+ private boolean doCompress = true;
+ private boolean doUpdate = false;
+ // shadow of the above if the value is altered in execute
+ private boolean savedDoUpdate = false;
+ private boolean doFilesonly = false;
+ protected String archiveType = "zip";
+
+ // For directories:
+ private static final long EMPTY_CRC = new CRC32 ().getValue ();
+ protected String emptyBehavior = "skip";
+ private final Vector<ResourceCollection> resources = new Vector<ResourceCollection>();
+ protected Hashtable<String, String> addedDirs = new Hashtable<String, String>();
+ private final Vector<String> addedFiles = new Vector<String>();
+
+ private static final ResourceSelector MISSING_SELECTOR =
+ new ResourceSelector() {
+ public boolean isSelected(final Resource target) {
+ return !target.isExists();
+ }
+ };
+
+ private static final ResourceUtils.ResourceSelectorProvider
+ MISSING_DIR_PROVIDER = new ResourceUtils.ResourceSelectorProvider() {
+ public ResourceSelector
+ getTargetSelectorForSource(final Resource sr) {
+ return MISSING_SELECTOR;
+ }
+ };
+
+ /**
+ * If this flag is true, execute() will run most operations twice,
+ * the first time with {@link #skipWriting skipWriting} set to
+ * true and the second time with setting it to false.
+ *
+ * <p>The only situation in Ant's current code base where this is
+ * ever going to be true is if the jar task has been configured
+ * with a filesetmanifest other than "skip".</p>
+ */
+ protected boolean doubleFilePass = false;
+ /**
+ * whether the methods should just perform some sort of dry-run.
+ *
+ * <p>Will only ever be true in the first pass if the task
+ * performs two passes because {@link #doubleFilePass
+ * doubleFilePass} is true.</p>
+ */
+ protected boolean skipWriting = false;
+
+ /**
+ * Whether this is the first time the archive building methods are invoked.
+ *
+ * @return true if either {@link #doubleFilePass doubleFilePass}
+ * is false or {@link #skipWriting skipWriting} is true.
+ *
+ * @since Ant 1.8.0
+ */
+ protected final boolean isFirstPass() {
+ return !doubleFilePass || skipWriting;
+ }
+
+ private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+
+ // CheckStyle:VisibilityModifier ON
+
+ // This boolean is set if the task detects that the
+ // target is outofdate and has written to the target file.
+ private boolean updatedFile = false;
+
+ /**
+ * true when we are adding new files into the Zip file, as opposed
+ * to adding back the unchanged files
+ */
+ private boolean addingNewFiles = false;
+
+ /**
+ * Encoding to use for filenames, defaults to the platform's
+ * default encoding.
+ */
+ private String encoding;
+
+ /**
+ * Whether the original compression of entries coming from a ZIP
+ * archive should be kept (for example when updating an archive).
+ *
+ * @since Ant 1.6
+ */
+ private boolean keepCompression = false;
+
+ /**
+ * Whether the file modification times will be rounded up to the
+ * next even number of seconds.
+ *
+ * @since Ant 1.6.2
+ */
+ private boolean roundUp = true;
+
+ /**
+ * Comment for the archive.
+ * @since Ant 1.6.3
+ */
+ private String comment = "";
+
+ private int level = ZipOutputStream.DEFAULT_COMPRESSION;
+
+ /**
+ * Assume 0 Unix mode is intentional.
+ * @since Ant 1.8.0
+ */
+ private boolean preserve0Permissions = false;
+
+ /**
+ * Whether to set the language encoding flag when creating the archive.
+ *
+ * @since Ant 1.8.0
+ */
+ private boolean useLanguageEncodingFlag = true;
+
+ /**
+ * Whether to add unicode extra fields.
+ *
+ * @since Ant 1.8.0
+ */
+ private UnicodeExtraField createUnicodeExtraFields =
+ UnicodeExtraField.NEVER;
+
+ /**
+ * Whether to fall back to UTF-8 if a name cannot be encoded using
+ * the specified encoding.
+ *
+ * @since Ant 1.8.0
+ */
+ private boolean fallBackToUTF8 = false;
+
+ /**
+ * Whether to enable Zip64 extensions.
+ *
+ * @since Ant 1.9.1
+ */
+ private Zip64ModeAttribute zip64Mode = Zip64ModeAttribute.AS_NEEDED;
+
+ /**
+ * This is the name/location of where to
+ * create the .zip file.
+ * @param zipFile the path of the zipFile
+ * @deprecated since 1.5.x.
+ * Use setDestFile(File) instead.
+ * @ant.attribute ignore="true"
+ */
+ @Deprecated
+ public void setZipfile(final File zipFile) {
+ setDestFile(zipFile);
+ }
+
+ /**
+ * This is the name/location of where to
+ * create the file.
+ * @param file the path of the zipFile
+ * @since Ant 1.5
+ * @deprecated since 1.5.x.
+ * Use setDestFile(File) instead.
+ * @ant.attribute ignore="true"
+ */
+ @Deprecated
+ public void setFile(final File file) {
+ setDestFile(file);
+ }
+
+
+ /**
+ * The file to create; required.
+ * @since Ant 1.5
+ * @param destFile The new destination File
+ */
+ public void setDestFile(final File destFile) {
+ this.zipFile = destFile;
+ }
+
+ /**
+ * The file to create.
+ * @return the destination file
+ * @since Ant 1.5.2
+ */
+ public File getDestFile() {
+ return zipFile;
+ }
+
+
+ /**
+ * Directory from which to archive files; optional.
+ * @param baseDir the base directory
+ */
+ public void setBasedir(final File baseDir) {
+ this.baseDir = baseDir;
+ }
+
+ /**
+ * Whether we want to compress the files or only store them;
+ * optional, default=true;
+ * @param c if true, compress the files
+ */
+ public void setCompress(final boolean c) {
+ doCompress = c;
+ }
+
+ /**
+ * Whether we want to compress the files or only store them;
+ * @return true if the files are to be compressed
+ * @since Ant 1.5.2
+ */
+ public boolean isCompress() {
+ return doCompress;
+ }
+
+ /**
+ * If true, emulate Sun's jar utility by not adding parent directories;
+ * optional, defaults to false.
+ * @param f if true, emulate sun's jar by not adding parent directories
+ */
+ public void setFilesonly(final boolean f) {
+ doFilesonly = f;
+ }
+
+ /**
+ * If true, updates an existing file, otherwise overwrite
+ * any existing one; optional defaults to false.
+ * @param c if true, updates an existing zip file
+ */
+ public void setUpdate(final boolean c) {
+ doUpdate = c;
+ savedDoUpdate = c;
+ }
+
+ /**
+ * Are we updating an existing archive?
+ * @return true if updating an existing archive
+ */
+ public boolean isInUpdateMode() {
+ return doUpdate;
+ }
+
+ /**
+ * Adds a set of files.
+ * @param set the fileset to add
+ */
+ public void addFileset(final FileSet set) {
+ add(set);
+ }
+
+ /**
+ * Adds a set of files that can be
+ * read from an archive and be given a prefix/fullpath.
+ * @param set the zipfileset to add
+ */
+ public void addZipfileset(final ZipFileSet set) {
+ add(set);
+ }
+
+ /**
+ * Add a collection of resources to be archived.
+ * @param a the resources to archive
+ * @since Ant 1.7
+ */
+ public void add(final ResourceCollection a) {
+ resources.add(a);
+ }
+
+ /**
+ * Adds a group of zip files.
+ * @param set the group (a fileset) to add
+ */
+ public void addZipGroupFileset(final FileSet set) {
+ groupfilesets.addElement(set);
+ }
+
+ /**
+ * Sets behavior for when a duplicate file is about to be added -
+ * one of <code>add</code>, <code>preserve</code> or <code>fail</code>.
+ * Possible values are: <code>add</code> (keep both
+ * of the files); <code>preserve</code> (keep the first version
+ * of the file found); <code>fail</code> halt a problem
+ * Default for zip tasks is <code>add</code>
+ * @param df a <code>Duplicate</code> enumerated value
+ */
+ public void setDuplicate(final Duplicate df) {
+ duplicate = df.getValue();
+ }
+
+ /**
+ * Possible behaviors when there are no matching files for the task:
+ * "fail", "skip", or "create".
+ */
+ public static class WhenEmpty extends EnumeratedAttribute {
+ /**
+ * The string values for the enumerated value
+ * @return the values
+ */
+ @Override
+ public String[] getValues() {
+ return new String[] {"fail", "skip", "create"};
+ }
+ }
+
+ /**
+ * Sets behavior of the task when no files match.
+ * Possible values are: <code>fail</code> (throw an exception
+ * and halt the build); <code>skip</code> (do not create
+ * any archive, but issue a warning); <code>create</code>
+ * (make an archive with no entries).
+ * Default for zip tasks is <code>skip</code>;
+ * for jar tasks, <code>create</code>.
+ * @param we a <code>WhenEmpty</code> enumerated value
+ */
+ public void setWhenempty(final WhenEmpty we) {
+ emptyBehavior = we.getValue();
+ }
+
+ /**
+ * Encoding to use for filenames, defaults to the platform's
+ * default encoding.
+ *
+ * <p>For a list of possible values see <a
+ * href="http://java.sun.com/j2se/1.5.0/docs/guide/intl/encoding.doc.html">http://java.sun.com/j2se/1.5.0/docs/guide/intl/encoding.doc.html</a>.</p>
+ * @param encoding the encoding name
+ */
+ public void setEncoding(final String encoding) {
+ this.encoding = encoding;
+ }
+
+ /**
+ * Encoding to use for filenames.
+ * @return the name of the encoding to use
+ * @since Ant 1.5.2
+ */
+ public String getEncoding() {
+ return encoding;
+ }
+
+ /**
+ * Whether the original compression of entries coming from a ZIP
+ * archive should be kept (for example when updating an archive).
+ * Default is false.
+ * @param keep if true, keep the original compression
+ * @since Ant 1.6
+ */
+ public void setKeepCompression(final boolean keep) {
+ keepCompression = keep;
+ }
+
+ /**
+ * Comment to use for archive.
+ *
+ * @param comment The content of the comment.
+ * @since Ant 1.6.3
+ */
+ public void setComment(final String comment) {
+ this.comment = comment;
+ }
+
+ /**
+ * Comment of the archive
+ *
+ * @return Comment of the archive.
+ * @since Ant 1.6.3
+ */
+ public String getComment() {
+ return comment;
+ }
+
+ /**
+ * Set the compression level to use. Default is
+ * ZipOutputStream.DEFAULT_COMPRESSION.
+ * @param level compression level.
+ * @since Ant 1.7
+ */
+ public void setLevel(final int level) {
+ this.level = level;
+ }
+
+ /**
+ * Get the compression level.
+ * @return compression level.
+ * @since Ant 1.7
+ */
+ public int getLevel() {
+ return level;
+ }
+
+ /**
+ * Whether the file modification times will be rounded up to the
+ * next even number of seconds.
+ *
+ * <p>Zip archives store file modification times with a
+ * granularity of two seconds, so the times will either be rounded
+ * up or down. If you round down, the archive will always seem
+ * out-of-date when you rerun the task, so the default is to round
+ * up. Rounding up may lead to a different type of problems like
+ * JSPs inside a web archive that seem to be slightly more recent
+ * than precompiled pages, rendering precompilation useless.</p>
+ * @param r a <code>boolean</code> value
+ * @since Ant 1.6.2
+ */
+ public void setRoundUp(final boolean r) {
+ roundUp = r;
+ }
+
+ /**
+ * Assume 0 Unix mode is intentional.
+ * @since Ant 1.8.0
+ */
+ public void setPreserve0Permissions(final boolean b) {
+ preserve0Permissions = b;
+ }
+
+ /**
+ * Assume 0 Unix mode is intentional.
+ * @since Ant 1.8.0
+ */
+ public boolean getPreserve0Permissions() {
+ return preserve0Permissions;
+ }
+
+ /**
+ * Whether to set the language encoding flag.
+ * @since Ant 1.8.0
+ */
+ public void setUseLanguageEncodingFlag(final boolean b) {
+ useLanguageEncodingFlag = b;
+ }
+
+ /**
+ * Whether the language encoding flag will be used.
+ * @since Ant 1.8.0
+ */
+ public boolean getUseLanguageEnodingFlag() {
+ return useLanguageEncodingFlag;
+ }
+
+ /**
+ * Whether Unicode extra fields will be created.
+ * @since Ant 1.8.0
+ */
+ public void setCreateUnicodeExtraFields(final UnicodeExtraField b) {
+ createUnicodeExtraFields = b;
+ }
+
+ /**
+ * Whether Unicode extra fields will be created.
+ * @since Ant 1.8.0
+ */
+ public UnicodeExtraField getCreateUnicodeExtraFields() {
+ return createUnicodeExtraFields;
+ }
+
+ /**
+ * Whether to fall back to UTF-8 if a name cannot be encoded using
+ * the specified encoding.
+ *
+ * <p>Defaults to false.</p>
+ *
+ * @since Ant 1.8.0
+ */
+ public void setFallBackToUTF8(final boolean b) {
+ fallBackToUTF8 = b;
+ }
+
+ /**
+ * Whether to fall back to UTF-8 if a name cannot be encoded using
+ * the specified encoding.
+ *
+ * @since Ant 1.8.0
+ */
+ public boolean getFallBackToUTF8() {
+ return fallBackToUTF8;
+ }
+
+ /**
+ * Whether Zip64 extensions should be used.
+ * @since Ant 1.9.1
+ */
+ public void setZip64Mode(final Zip64ModeAttribute b) {
+ zip64Mode = b;
+ }
+
+ /**
+ * Whether Zip64 extensions will be used.
+ * @since Ant 1.9.1
+ */
+ public Zip64ModeAttribute getZip64Mode() {
+ return zip64Mode;
+ }
+
+ /**
+ * validate and build
+ * @throws BuildException on error
+ */
+ @Override
+ public void execute() throws BuildException {
+
+ if (doubleFilePass) {
+ skipWriting = true;
+ executeMain();
+ skipWriting = false;
+ executeMain();
+ } else {
+ executeMain();
+ }
+ }
+
+ /**
+ * Get the value of the updatedFile attribute.
+ * This should only be called after executeMain has been
+ * called.
+ * @return true if executeMain has written to the zip file.
+ */
+ protected boolean hasUpdatedFile() {
+ return updatedFile;
+ }
+
+ /**
+ * Build the zip file.
+ * This is called twice if doubleFilePass is true.
+ * @throws BuildException on error
+ */
+ public void executeMain() throws BuildException {
+
+ checkAttributesAndElements();
+
+ // Renamed version of original file, if it exists
+ File renamedFile = null;
+ addingNewFiles = true;
+
+ processDoUpdate();
+ processGroupFilesets();
+
+ // collect filesets to pass them to getResourcesToAdd
+ final Vector<ResourceCollection> vfss = new Vector<ResourceCollection>();
+ if (baseDir != null) {
+ final FileSet fs = (FileSet) getImplicitFileSet().clone();
+ fs.setDir(baseDir);
+ vfss.addElement(fs);
+ }
+ final int size = resources.size();
+ for (int i = 0; i < size; i++) {
+ final ResourceCollection rc = resources.elementAt(i);
+ vfss.addElement(rc);
+ }
+
+ final ResourceCollection[] fss = new ResourceCollection[vfss.size()];
+ vfss.copyInto(fss);
+ boolean success = false;
+ try {
+ // can also handle empty archives
+ final ArchiveState state = getResourcesToAdd(fss, zipFile, false);
+
+ // quick exit if the target is up to date
+ if (!state.isOutOfDate()) {
+ return;
+ }
+
+ final File parent = zipFile.getParentFile();
+ if (parent != null && !parent.isDirectory()
+ && !(parent.mkdirs() || parent.isDirectory())) {
+ throw new BuildException("Failed to create missing parent"
+ + " directory for " + zipFile);
+ }
+
+ updatedFile = true;
+ if (!zipFile.exists() && state.isWithoutAnyResources()) {
+ createEmptyZip(zipFile);
+ return;
+ }
+ final Resource[][] addThem = state.getResourcesToAdd();
+
+ if (doUpdate) {
+ renamedFile = renameFile();
+ }
+
+ final String action = doUpdate ? "Updating " : "Building ";
+
+ if (!skipWriting) {
+ log(action + archiveType + ": " + zipFile.getAbsolutePath());
+ }
+
+ ZipOutputStream zOut = null;
+ try {
+ if (!skipWriting) {
+ zOut = new ZipOutputStream(zipFile);
+
+ zOut.setEncoding(encoding);
+ zOut.setUseLanguageEncodingFlag(useLanguageEncodingFlag);
+ zOut.setCreateUnicodeExtraFields(createUnicodeExtraFields.
+ getPolicy());
+ zOut.setFallbackToUTF8(fallBackToUTF8);
+ zOut.setMethod(doCompress
+ ? ZipOutputStream.DEFLATED : ZipOutputStream.STORED);
+ zOut.setLevel(level);
+ zOut.setUseZip64(zip64Mode.getMode());
+ }
+ initZipOutputStream(zOut);
+
+ // Add the explicit resource collections to the archive.
+ for (int i = 0; i < fss.length; i++) {
+ if (addThem[i].length != 0) {
+ addResources(fss[i], addThem[i], zOut);
+ }
+ }
+
+ if (doUpdate) {
+ addingNewFiles = false;
+ final ZipFileSet oldFiles = new ZipFileSet();
+ oldFiles.setProject(getProject());
+ oldFiles.setSrc(renamedFile);
+ oldFiles.setDefaultexcludes(false);
+
+ final int addSize = addedFiles.size();
+ for (int i = 0; i < addSize; i++) {
+ final PatternSet.NameEntry ne = oldFiles.createExclude();
+ ne.setName(addedFiles.elementAt(i));
+ }
+ final DirectoryScanner ds =
+ oldFiles.getDirectoryScanner(getProject());
+ ((ZipScanner) ds).setEncoding(encoding);
+
+ final String[] f = ds.getIncludedFiles();
+ Resource[] r = new Resource[f.length];
+ for (int i = 0; i < f.length; i++) {
+ r[i] = ds.getResource(f[i]);
+ }
+
+ if (!doFilesonly) {
+ final String[] d = ds.getIncludedDirectories();
+ final Resource[] dr = new Resource[d.length];
+ for (int i = 0; i < d.length; i++) {
+ dr[i] = ds.getResource(d[i]);
+ }
+ final Resource[] tmp = r;
+ r = new Resource[tmp.length + dr.length];
+ System.arraycopy(dr, 0, r, 0, dr.length);
+ System.arraycopy(tmp, 0, r, dr.length, tmp.length);
+ }
+ addResources(oldFiles, r, zOut);
+ }
+ if (zOut != null) {
+ zOut.setComment(comment);
+ }
+ finalizeZipOutputStream(zOut);
+
+ // If we've been successful on an update, delete the
+ // temporary file
+ if (doUpdate) {
+ if (!renamedFile.delete()) {
+ log ("Warning: unable to delete temporary file "
+ + renamedFile.getName(), Project.MSG_WARN);
+ }
+ }
+ success = true;
+ } finally {
+ // Close the output stream.
+ closeZout(zOut, success);
+ }
+ } catch (final IOException ioe) {
+ String msg = "Problem creating " + archiveType + ": "
+ + ioe.getMessage();
+
+ // delete a bogus ZIP file (but only if it's not the original one)
+ if ((!doUpdate || renamedFile != null) && !zipFile.delete()) {
+ msg += " (and the archive is probably corrupt but I could not "
+ + "delete it)";
+ }
+
+ if (doUpdate && renamedFile != null) {
+ try {
+ FILE_UTILS.rename(renamedFile, zipFile);
+ } catch (final IOException e) {
+ msg += " (and I couldn't rename the temporary file "
+ + renamedFile.getName() + " back)";
+ }
+ }
+
+ throw new BuildException(msg, ioe, getLocation());
+ } finally {
+ cleanUp();
+ }
+ }
+
+ /** rename the zip file. */
+ private File renameFile() {
+ final File renamedFile = FILE_UTILS.createTempFile(
+ "zip", ".tmp", zipFile.getParentFile(), true, false);
+ try {
+ FILE_UTILS.rename(zipFile, renamedFile);
+ } catch (final SecurityException e) {
+ throw new BuildException(
+ "Not allowed to rename old file ("
+ + zipFile.getAbsolutePath()
+ + ") to temporary file");
+ } catch (final IOException e) {
+ throw new BuildException(
+ "Unable to rename old file ("
+ + zipFile.getAbsolutePath()
+ + ") to temporary file");
+ }
+ return renamedFile;
+ }
+
+ /** Close zout */
+ private void closeZout(final ZipOutputStream zOut, final boolean success)
+ throws IOException {
+ if (zOut == null) {
+ return;
+ }
+ try {
+ zOut.close();
+ } catch (final IOException ex) {
+ // If we're in this finally clause because of an
+ // exception, we don't really care if there's an
+ // exception when closing the stream. E.g. if it
+ // throws "ZIP file must have at least one entry",
+ // because an exception happened before we added
+ // any files, then we must swallow this
+ // exception. Otherwise, the error that's reported
+ // will be the close() error, which is not the
+ // real cause of the problem.
+ if (success) {
+ throw ex;
+ }
+ }
+ }
+
+ /** Check the attributes and elements */
+ private void checkAttributesAndElements() {
+ if (baseDir == null && resources.size() == 0
+ && groupfilesets.size() == 0 && "zip".equals(archiveType)) {
+ throw new BuildException("basedir attribute must be set, "
+ + "or at least one "
+ + "resource collection must be given!");
+ }
+
+ if (zipFile == null) {
+ throw new BuildException("You must specify the "
+ + archiveType + " file to create!");
+ }
+
+ if (zipFile.exists() && !zipFile.isFile()) {
+ throw new BuildException(zipFile + " is not a file.");
+ }
+
+ if (zipFile.exists() && !zipFile.canWrite()) {
+ throw new BuildException(zipFile + " is read-only.");
+ }
+ }
+
+ /** Process doupdate */
+ private void processDoUpdate() {
+ // Whether or not an actual update is required -
+ // we don't need to update if the original file doesn't exist
+ if (doUpdate && !zipFile.exists()) {
+ doUpdate = false;
+ logWhenWriting("ignoring update attribute as " + archiveType
+ + " doesn't exist.", Project.MSG_DEBUG);
+ }
+ }
+
+ /** Process groupfilesets */
+ private void processGroupFilesets() {
+ // Add the files found in groupfileset to fileset
+ final int size = groupfilesets.size();
+ for (int i = 0; i < size; i++) {
+
+ logWhenWriting("Processing groupfileset ", Project.MSG_VERBOSE);
+ final FileSet fs = groupfilesets.elementAt(i);
+ final FileScanner scanner = fs.getDirectoryScanner(getProject());
+ final String[] files = scanner.getIncludedFiles();
+ final File basedir = scanner.getBasedir();
+ for (int j = 0; j < files.length; j++) {
+
+ logWhenWriting("Adding file " + files[j] + " to fileset",
+ Project.MSG_VERBOSE);
+ final ZipFileSet zf = new ZipFileSet();
+ zf.setProject(getProject());
+ zf.setSrc(new File(basedir, files[j]));
+ add(zf);
+ filesetsFromGroupfilesets.addElement(zf);
+ }
+ }
+ }
+
+ /**
+ * Indicates if the task is adding new files into the archive as opposed to
+ * copying back unchanged files from the backup copy
+ * @return true if adding new files
+ */
+ protected final boolean isAddingNewFiles() {
+ return addingNewFiles;
+ }
+
+ /**
+ * Add the given resources.
+ *
+ * @param fileset may give additional information like fullpath or
+ * permissions.
+ * @param resources the resources to add
+ * @param zOut the stream to write to
+ * @throws IOException on error
+ *
+ * @since Ant 1.5.2
+ */
+ protected final void addResources(final FileSet fileset, final Resource[] resources,
+ final ZipOutputStream zOut)
+ throws IOException {
+
+ String prefix = "";
+ String fullpath = "";
+ int dirMode = ArchiveFileSet.DEFAULT_DIR_MODE;
+ int fileMode = ArchiveFileSet.DEFAULT_FILE_MODE;
+
+ ArchiveFileSet zfs = null;
+ if (fileset instanceof ArchiveFileSet) {
+ zfs = (ArchiveFileSet) fileset;
+ prefix = zfs.getPrefix(getProject());
+ fullpath = zfs.getFullpath(getProject());
+ dirMode = zfs.getDirMode(getProject());
+ fileMode = zfs.getFileMode(getProject());
+ }
+
+ if (prefix.length() > 0 && fullpath.length() > 0) {
+ throw new BuildException("Both prefix and fullpath attributes must"
+ + " not be set on the same fileset.");
+ }
+
+ if (resources.length != 1 && fullpath.length() > 0) {
+ throw new BuildException("fullpath attribute may only be specified"
+ + " for filesets that specify a single"
+ + " file.");
+ }
+
+ if (prefix.length() > 0) {
+ if (!prefix.endsWith("/") && !prefix.endsWith("\\")) {
+ prefix += "/";
+ }
+ addParentDirs(null, prefix, zOut, "", dirMode);
+ }
+
+ ZipFile zf = null;
+ try {
+ boolean dealingWithFiles = false;
+ File base = null;
+
+ if (zfs == null || zfs.getSrc(getProject()) == null) {
+ dealingWithFiles = true;
+ base = fileset.getDir(getProject());
+ } else if (zfs instanceof ZipFileSet) {
+ zf = new ZipFile(zfs.getSrc(getProject()), encoding);
+ }
+
+ for (int i = 0; i < resources.length; i++) {
+ String name = null;
+ if (fullpath.length() > 0) {
+ name = fullpath;
+ } else {
+ name = resources[i].getName();
+ }
+ name = name.replace(File.separatorChar, '/');
+
+ if ("".equals(name)) {
+ continue;
+ }
+
+ if (resources[i].isDirectory()) {
+ if (doFilesonly) {
+ continue;
+ }
+ final int thisDirMode = zfs != null && zfs.hasDirModeBeenSet()
+ ? dirMode : getUnixMode(resources[i], zf, dirMode);
+ addDirectoryResource(resources[i], name, prefix,
+ base, zOut,
+ dirMode, thisDirMode);
+
+ } else { // !isDirectory
+
+ addParentDirs(base, name, zOut, prefix, dirMode);
+
+ if (dealingWithFiles) {
+ final File f = FILE_UTILS.resolveFile(base,
+ resources[i].getName());
+ zipFile(f, zOut, prefix + name, fileMode);
+ } else {
+ final int thisFileMode =
+ zfs != null && zfs.hasFileModeBeenSet()
+ ? fileMode : getUnixMode(resources[i], zf,
+ fileMode);
+ addResource(resources[i], name, prefix,
+ zOut, thisFileMode, zf,
+ zfs == null
+ ? null : zfs.getSrc(getProject()));
+ }
+ }
+ }
+ } finally {
+ if (zf != null) {
+ zf.close();
+ }
+ }
+ }
+
+ /**
+ * Add a directory entry to the archive using a specified
+ * Unix-mode and the default mode for its parent directories (if
+ * necessary).
+ */
+ private void addDirectoryResource(final Resource r, String name, final String prefix,
+ final File base, final ZipOutputStream zOut,
+ final int defaultDirMode, final int thisDirMode)
+ throws IOException {
+
+ if (!name.endsWith("/")) {
+ name = name + "/";
+ }
+
+ final int nextToLastSlash = name.lastIndexOf("/", name.length() - 2);
+ if (nextToLastSlash != -1) {
+ addParentDirs(base, name.substring(0, nextToLastSlash + 1),
+ zOut, prefix, defaultDirMode);
+ }
+ zipDir(r, zOut, prefix + name, thisDirMode,
+ r instanceof ZipResource
+ ? ((ZipResource) r).getExtraFields() : null);
+ }
+
+ /**
+ * Determine a Resource's Unix mode or return the given default
+ * value if not available.
+ */
+ private int getUnixMode(final Resource r, final ZipFile zf, final int defaultMode)
+ throws IOException {
+
+ int unixMode = defaultMode;
+ if (zf != null) {
+ final ZipEntry ze = zf.getEntry(r.getName());
+ unixMode = ze.getUnixMode();
+ if ((unixMode == 0 || unixMode == UnixStat.DIR_FLAG)
+ && !preserve0Permissions) {
+ unixMode = defaultMode;
+ }
+ } else if (r instanceof ArchiveResource) {
+ unixMode = ((ArchiveResource) r).getMode();
+ }
+ return unixMode;
+ }
+
+ /**
+ * Add a file entry.
+ */
+ private void addResource(final Resource r, final String name, final String prefix,
+ final ZipOutputStream zOut, final int mode,
+ final ZipFile zf, final File fromArchive)
+ throws IOException {
+
+ if (zf != null) {
+ final ZipEntry ze = zf.getEntry(r.getName());
+
+ if (ze != null) {
+ final boolean oldCompress = doCompress;
+ if (keepCompression) {
+ doCompress = (ze.getMethod() == ZipEntry.DEFLATED);
+ }
+ InputStream is = null;
+ try {
+ is = zf.getInputStream(ze);
+ zipFile(is, zOut, prefix + name, ze.getTime(),
+ fromArchive, mode, ze.getExtraFields(true));
+ } finally {
+ doCompress = oldCompress;
+ FileUtils.close(is);
+ }
+ }
+ } else {
+ InputStream is = null;
+ try {
+ is = r.getInputStream();
+ zipFile(is, zOut, prefix + name, r.getLastModified(),
+ fromArchive, mode, r instanceof ZipResource
+ ? ((ZipResource) r).getExtraFields() : null);
+ } finally {
+ FileUtils.close(is);
+ }
+ }
+ }
+
+ /**
+ * Add the given resources.
+ *
+ * @param rc may give additional information like fullpath or
+ * permissions.
+ * @param resources the resources to add
+ * @param zOut the stream to write to
+ * @throws IOException on error
+ *
+ * @since Ant 1.7
+ */
+ protected final void addResources(final ResourceCollection rc,
+ final Resource[] resources,
+ final ZipOutputStream zOut)
+ throws IOException {
+ if (rc instanceof FileSet) {
+ addResources((FileSet) rc, resources, zOut);
+ return;
+ }
+ for (int i = 0; i < resources.length; i++) {
+ final Resource resource = resources[i];
+ String name = resource.getName();
+ if (name == null) {
+ continue;
+ }
+ name = name.replace(File.separatorChar, '/');
+
+ if ("".equals(name)) {
+ continue;
+ }
+ if (resource.isDirectory() && doFilesonly) {
+ continue;
+ }
+ File base = null;
+ final FileProvider fp = resource.as(FileProvider.class);
+ if (fp != null) {
+ base = ResourceUtils.asFileResource(fp).getBaseDir();
+ }
+
+ if (resource.isDirectory()) {
+ addDirectoryResource(resource, name, "", base, zOut,
+ ArchiveFileSet.DEFAULT_DIR_MODE,
+ ArchiveFileSet.DEFAULT_DIR_MODE);
+
+ } else {
+ addParentDirs(base, name, zOut, "",
+ ArchiveFileSet.DEFAULT_DIR_MODE);
+
+ if (fp != null) {
+ final File f = (fp).getFile();
+ zipFile(f, zOut, name, ArchiveFileSet.DEFAULT_FILE_MODE);
+ } else {
+ addResource(resource, name, "", zOut,
+ ArchiveFileSet.DEFAULT_FILE_MODE,
+ null, null);
+ }
+ }
+ }
+ }
+
+ /**
+ * method for subclasses to override
+ * @param zOut the zip output stream
+ * @throws IOException on output error
+ * @throws BuildException on other errors
+ */
+ protected void initZipOutputStream(final ZipOutputStream zOut)
+ throws IOException, BuildException {
+ }
+
+ /**
+ * method for subclasses to override
+ * @param zOut the zip output stream
+ * @throws IOException on output error
+ * @throws BuildException on other errors
+ */
+ protected void finalizeZipOutputStream(final ZipOutputStream zOut)
+ throws IOException, BuildException {
+ }
+
+ /**
+ * Create an empty zip file
+ * @param zipFile the zip file
+ * @return true for historic reasons
+ * @throws BuildException on error
+ */
+ protected boolean createEmptyZip(final File zipFile) throws BuildException {
+ // In this case using java.util.zip will not work
+ // because it does not permit a zero-entry archive.
+ // Must create it manually.
+ if (!skipWriting) {
+ log("Note: creating empty " + archiveType + " archive " + zipFile,
+ Project.MSG_INFO);
+ }
+ OutputStream os = null;
+ try {
+ os = new FileOutputStream(zipFile);
+ // CheckStyle:MagicNumber OFF
+ // Cf. PKZIP specification.
+ final byte[] empty = new byte[22];
+ empty[0] = 80; // P
+ empty[1] = 75; // K
+ empty[2] = 5;
+ empty[3] = 6;
+ // remainder zeros
+ // CheckStyle:MagicNumber ON
+ os.write(empty);
+ } catch (final IOException ioe) {
+ throw new BuildException("Could not create empty ZIP archive "
+ + "(" + ioe.getMessage() + ")", ioe,
+ getLocation());
+ } finally {
+ FileUtils.close(os);
+ }
+ return true;
+ }
+
+ /**
+ * @since Ant 1.5.2
+ */
+ private synchronized ZipScanner getZipScanner() {
+ if (zs == null) {
+ zs = new ZipScanner();
+ zs.setEncoding(encoding);
+ zs.setSrc(zipFile);
+ }
+ return zs;
+ }
+
+ /**
+ * Collect the resources that are newer than the corresponding
+ * entries (or missing) in the original archive.
+ *
+ * <p>If we are going to recreate the archive instead of updating
+ * it, all resources should be considered as new, if a single one
+ * is. Because of this, subclasses overriding this method must
+ * call <code>super.getResourcesToAdd</code> and indicate with the
+ * third arg if they already know that the archive is
+ * out-of-date.</p>
+ *
+ * <p>This method first delegates to getNonFileSetResourcesToAdd
+ * and then invokes the FileSet-arg version. All this to keep
+ * backwards compatibility for subclasses that don't know how to
+ * deal with non-FileSet ResourceCollections.</p>
+ *
+ * @param rcs The resource collections to grab resources from
+ * @param zipFile intended archive file (may or may not exist)
+ * @param needsUpdate whether we already know that the archive is
+ * out-of-date. Subclasses overriding this method are supposed to
+ * set this value correctly in their call to
+ * <code>super.getResourcesToAdd</code>.
+ * @return an array of resources to add for each fileset passed in as well
+ * as a flag that indicates whether the archive is uptodate.
+ *
+ * @exception BuildException if it likes
+ * @since Ant 1.7
+ */
+ protected ArchiveState getResourcesToAdd(final ResourceCollection[] rcs,
+ final File zipFile,
+ final boolean needsUpdate)
+ throws BuildException {
+ final ArrayList<ResourceCollection> filesets = new ArrayList<ResourceCollection>();
+ final ArrayList<ResourceCollection> rest = new ArrayList<ResourceCollection>();
+ for (int i = 0; i < rcs.length; i++) {
+ if (rcs[i] instanceof FileSet) {
+ filesets.add(rcs[i]);
+ } else {
+ rest.add(rcs[i]);
+ }
+ }
+ final ResourceCollection[] rc =
+ rest.toArray(new ResourceCollection[rest.size()]);
+ ArchiveState as = getNonFileSetResourcesToAdd(rc, zipFile,
+ needsUpdate);
+
+ final FileSet[] fs = filesets.toArray(new FileSet[filesets
+ .size()]);
+ final ArchiveState as2 = getResourcesToAdd(fs, zipFile, as.isOutOfDate());
+ if (!as.isOutOfDate() && as2.isOutOfDate()) {
+ /*
+ * Bad luck.
+ *
+ * There are resources in the filesets that make the
+ * archive out of date, but not in the non-fileset
+ * resources. We need to rescan the non-FileSets to grab
+ * all of them now.
+ */
+ as = getNonFileSetResourcesToAdd(rc, zipFile, true);
+ }
+
+ final Resource[][] toAdd = new Resource[rcs.length][];
+ int fsIndex = 0;
+ int restIndex = 0;
+ for (int i = 0; i < rcs.length; i++) {
+ if (rcs[i] instanceof FileSet) {
+ toAdd[i] = as2.getResourcesToAdd()[fsIndex++];
+ } else {
+ toAdd[i] = as.getResourcesToAdd()[restIndex++];
+ }
+ }
+ return new ArchiveState(as2.isOutOfDate(), toAdd);
+ }
+
+ /*
+ * This is yet another hacky construct to extend the FileSet[]
+ * getResourcesToAdd method so we can pass the information whether
+ * non-fileset resources have been available to it without having
+ * to move the withEmpty behavior checks (since either would break
+ * subclasses in several ways).
+ */
+ private static final ThreadLocal<Boolean> HAVE_NON_FILE_SET_RESOURCES_TO_ADD = new ThreadLocal<Boolean>() {
+ @Override
+ protected Boolean initialValue() {
+ return Boolean.FALSE;
+ }
+ };
+
+ /**
+ * Collect the resources that are newer than the corresponding
+ * entries (or missing) in the original archive.
+ *
+ * <p>If we are going to recreate the archive instead of updating
+ * it, all resources should be considered as new, if a single one
+ * is. Because of this, subclasses overriding this method must
+ * call <code>super.getResourcesToAdd</code> and indicate with the
+ * third arg if they already know that the archive is
+ * out-of-date.</p>
+ *
+ * @param filesets The filesets to grab resources from
+ * @param zipFile intended archive file (may or may not exist)
+ * @param needsUpdate whether we already know that the archive is
+ * out-of-date. Subclasses overriding this method are supposed to
+ * set this value correctly in their call to
+ * <code>super.getResourcesToAdd</code>.
+ * @return an array of resources to add for each fileset passed in as well
+ * as a flag that indicates whether the archive is uptodate.
+ *
+ * @exception BuildException if it likes
+ */
+ protected ArchiveState getResourcesToAdd(final FileSet[] filesets,
+ final File zipFile,
+ boolean needsUpdate)
+ throws BuildException {
+
+ final Resource[][] initialResources = grabResources(filesets);
+ if (isEmpty(initialResources)) {
+ if (Boolean.FALSE.equals(HAVE_NON_FILE_SET_RESOURCES_TO_ADD.get())) {
+ if (needsUpdate && doUpdate) {
+ /*
+ * This is a rather hairy case.
+ *
+ * One of our subclasses knows that we need to
+ * update the archive, but at the same time, there
+ * are no resources known to us that would need to
+ * be added. Only the subclass seems to know
+ * what's going on.
+ *
+ * This happens if <jar> detects that the manifest
+ * has changed, for example. The manifest is not
+ * part of any resources because of our support
+ * for inline <manifest>s.
+ *
+ * If we invoke createEmptyZip like Ant 1.5.2 did,
+ * we'll loose all stuff that has been in the
+ * original archive (bugzilla report 17780).
+ */
+ return new ArchiveState(true, initialResources);
+ }
+
+ if (emptyBehavior.equals("skip")) {
+ if (doUpdate) {
+ logWhenWriting(archiveType + " archive " + zipFile
+ + " not updated because no new files were"
+ + " included.", Project.MSG_VERBOSE);
+ } else {
+ logWhenWriting("Warning: skipping " + archiveType
+ + " archive " + zipFile
+ + " because no files were included.",
+ Project.MSG_WARN);
+ }
+ } else if (emptyBehavior.equals("fail")) {
+ throw new BuildException("Cannot create " + archiveType
+ + " archive " + zipFile
+ + ": no files were included.",
+ getLocation());
+ } else {
+ // Create.
+ if (!zipFile.exists()) {
+ needsUpdate = true;
+ }
+ }
+ }
+
+ // either there are non-fileset resources or we
+ // (re-)create the archive anyway
+ return new ArchiveState(needsUpdate, initialResources);
+ }
+
+ // initialResources is not empty
+
+ if (!zipFile.exists()) {
+ return new ArchiveState(true, initialResources);
+ }
+
+ if (needsUpdate && !doUpdate) {
+ // we are recreating the archive, need all resources
+ return new ArchiveState(true, initialResources);
+ }
+
+ final Resource[][] newerResources = new Resource[filesets.length][];
+
+ for (int i = 0; i < filesets.length; i++) {
+ if (!(fileset instanceof ZipFileSet)
+ || ((ZipFileSet) fileset).getSrc(getProject()) == null) {
+ final File base = filesets[i].getDir(getProject());
+
+ for (int j = 0; j < initialResources[i].length; j++) {
+ final File resourceAsFile =
+ FILE_UTILS.resolveFile(base,
+ initialResources[i][j].getName());
+ if (resourceAsFile.equals(zipFile)) {
+ throw new BuildException("A zip file cannot include "
+ + "itself", getLocation());
+ }
+ }
+ }
+ }
+
+ for (int i = 0; i < filesets.length; i++) {
+ if (initialResources[i].length == 0) {
+ newerResources[i] = new Resource[] {};
+ continue;
+ }
+
+ FileNameMapper myMapper = new IdentityMapper();
+ if (filesets[i] instanceof ZipFileSet) {
+ final ZipFileSet zfs = (ZipFileSet) filesets[i];
+ if (zfs.getFullpath(getProject()) != null
+ && !zfs.getFullpath(getProject()).equals("")) {
+ // in this case all files from origin map to
+ // the fullPath attribute of the zipfileset at
+ // destination
+ final MergingMapper fm = new MergingMapper();
+ fm.setTo(zfs.getFullpath(getProject()));
+ myMapper = fm;
+
+ } else if (zfs.getPrefix(getProject()) != null
+ && !zfs.getPrefix(getProject()).equals("")) {
+ final GlobPatternMapper gm = new GlobPatternMapper();
+ gm.setFrom("*");
+ String prefix = zfs.getPrefix(getProject());
+ if (!prefix.endsWith("/") && !prefix.endsWith("\\")) {
+ prefix += "/";
+ }
+ gm.setTo(prefix + "*");
+ myMapper = gm;
+ }
+ }
+
+ newerResources[i] = selectOutOfDateResources(initialResources[i],
+ myMapper);
+ needsUpdate = needsUpdate || (newerResources[i].length > 0);
+
+ if (needsUpdate && !doUpdate) {
+ // we will return initialResources anyway, no reason
+ // to scan further.
+ break;
+ }
+ }
+
+ if (needsUpdate && !doUpdate) {
+ // we are recreating the archive, need all resources
+ return new ArchiveState(true, initialResources);
+ }
+
+ return new ArchiveState(needsUpdate, newerResources);
+ }
+
+ /**
+ * Collect the resources that are newer than the corresponding
+ * entries (or missing) in the original archive.
+ *
+ * <p>If we are going to recreate the archive instead of updating
+ * it, all resources should be considered as new, if a single one
+ * is. Because of this, subclasses overriding this method must
+ * call <code>super.getResourcesToAdd</code> and indicate with the
+ * third arg if they already know that the archive is
+ * out-of-date.</p>
+ *
+ * @param rcs The filesets to grab resources from
+ * @param zipFile intended archive file (may or may not exist)
+ * @param needsUpdate whether we already know that the archive is
+ * out-of-date. Subclasses overriding this method are supposed to
+ * set this value correctly in their call to
+ * <code>super.getResourcesToAdd</code>.
+ * @return an array of resources to add for each fileset passed in as well
+ * as a flag that indicates whether the archive is uptodate.
+ *
+ * @exception BuildException if it likes
+ */
+ protected ArchiveState getNonFileSetResourcesToAdd(final ResourceCollection[] rcs,
+ final File zipFile,
+ boolean needsUpdate)
+ throws BuildException {
+ /*
+ * Backwards compatibility forces us to repeat the logic of
+ * getResourcesToAdd(FileSet[], ...) here once again.
+ */
+
+ final Resource[][] initialResources = grabNonFileSetResources(rcs);
+ final boolean empty = isEmpty(initialResources);
+ HAVE_NON_FILE_SET_RESOURCES_TO_ADD.set(Boolean.valueOf(!empty));
+ if (empty) {
+ // no emptyBehavior handling since the FileSet version
+ // will take care of it.
+ return new ArchiveState(needsUpdate, initialResources);
+ }
+
+ // initialResources is not empty
+
+ if (!zipFile.exists()) {
+ return new ArchiveState(true, initialResources);
+ }
+
+ if (needsUpdate && !doUpdate) {
+ // we are recreating the archive, need all resources
+ return new ArchiveState(true, initialResources);
+ }
+
+ final Resource[][] newerResources = new Resource[rcs.length][];
+
+ for (int i = 0; i < rcs.length; i++) {
+ if (initialResources[i].length == 0) {
+ newerResources[i] = new Resource[] {};
+ continue;
+ }
+
+ for (int j = 0; j < initialResources[i].length; j++) {
+ final FileProvider fp =
+ initialResources[i][j].as(FileProvider.class);
+ if (fp != null && zipFile.equals(fp.getFile())) {
+ throw new BuildException("A zip file cannot include "
+ + "itself", getLocation());
+ }
+ }
+
+ newerResources[i] = selectOutOfDateResources(initialResources[i],
+ new IdentityMapper());
+ needsUpdate = needsUpdate || (newerResources[i].length > 0);
+
+ if (needsUpdate && !doUpdate) {
+ // we will return initialResources anyway, no reason
+ // to scan further.
+ break;
+ }
+ }
+
+ if (needsUpdate && !doUpdate) {
+ // we are recreating the archive, need all resources
+ return new ArchiveState(true, initialResources);
+ }
+
+ return new ArchiveState(needsUpdate, newerResources);
+ }
+
+ private Resource[] selectOutOfDateResources(final Resource[] initial,
+ final FileNameMapper mapper) {
+ final Resource[] rs = selectFileResources(initial);
+ Resource[] result =
+ ResourceUtils.selectOutOfDateSources(this, rs, mapper,
+ getZipScanner());
+ if (!doFilesonly) {
+ final Union u = new Union();
+ u.addAll(Arrays.asList(selectDirectoryResources(initial)));
+ final ResourceCollection rc =
+ ResourceUtils.selectSources(this, u, mapper,
+ getZipScanner(),
+ MISSING_DIR_PROVIDER);
+ if (rc.size() > 0) {
+ final ArrayList<Resource> newer = new ArrayList<Resource>();
+ newer.addAll(Arrays.asList(((Union) rc).listResources()));
+ newer.addAll(Arrays.asList(result));
+ result = newer.toArray(result);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Fetch all included and not excluded resources from the sets.
+ *
+ * <p>Included directories will precede included files.</p>
+ * @param filesets an array of filesets
+ * @return the resources included
+ * @since Ant 1.5.2
+ */
+ protected Resource[][] grabResources(final FileSet[] filesets) {
+ final Resource[][] result = new Resource[filesets.length][];
+ for (int i = 0; i < filesets.length; i++) {
+ boolean skipEmptyNames = true;
+ if (filesets[i] instanceof ZipFileSet) {
+ final ZipFileSet zfs = (ZipFileSet) filesets[i];
+ skipEmptyNames = zfs.getPrefix(getProject()).equals("")
+ && zfs.getFullpath(getProject()).equals("");
+ }
+ final DirectoryScanner rs =
+ filesets[i].getDirectoryScanner(getProject());
+ if (rs instanceof ZipScanner) {
+ ((ZipScanner) rs).setEncoding(encoding);
+ }
+ final Vector<Resource> resources = new Vector<Resource>();
+ if (!doFilesonly) {
+ final String[] directories = rs.getIncludedDirectories();
+ for (int j = 0; j < directories.length; j++) {
+ if (!"".equals(directories[j]) || !skipEmptyNames) {
+ resources.addElement(rs.getResource(directories[j]));
+ }
+ }
+ }
+ final String[] files = rs.getIncludedFiles();
+ for (int j = 0; j < files.length; j++) {
+ if (!"".equals(files[j]) || !skipEmptyNames) {
+ resources.addElement(rs.getResource(files[j]));
+ }
+ }
+
+ result[i] = new Resource[resources.size()];
+ resources.copyInto(result[i]);
+ }
+ return result;
+ }
+
+ /**
+ * Fetch all included and not excluded resources from the collections.
+ *
+ * <p>Included directories will precede included files.</p>
+ * @param rcs an array of resource collections
+ * @return the resources included
+ * @since Ant 1.7
+ */
+ protected Resource[][] grabNonFileSetResources(final ResourceCollection[] rcs) {
+ final Resource[][] result = new Resource[rcs.length][];
+ for (int i = 0; i < rcs.length; i++) {
+ final ArrayList<Resource> dirs = new ArrayList<Resource>();
+ final ArrayList<Resource> files = new ArrayList<Resource>();
+ for (final Resource r : rcs[i]) {
+ if (r.isExists()) {
+ if (r.isDirectory()) {
+ dirs.add(r);
+ } else {
+ files.add(r);
+ }
+ }
+ }
+ // make sure directories are in alpha-order - this also
+ // ensures parents come before their children
+ Collections.sort(dirs, new Comparator<Resource>() {
+ public int compare(final Resource r1, final Resource r2) {
+ return r1.getName().compareTo(r2.getName());
+ }
+ });
+ final ArrayList<Resource> rs = new ArrayList<Resource>(dirs);
+ rs.addAll(files);
+ result[i] = rs.toArray(new Resource[rs.size()]);
+ }
+ return result;
+ }
+
+ /**
+ * Add a directory to the zip stream.
+ * @param dir the directort to add to the archive
+ * @param zOut the stream to write to
+ * @param vPath the name this entry shall have in the archive
+ * @param mode the Unix permissions to set.
+ * @throws IOException on error
+ * @since Ant 1.5.2
+ */
+ protected void zipDir(final File dir, final ZipOutputStream zOut, final String vPath,
+ final int mode)
+ throws IOException {
+ zipDir(dir, zOut, vPath, mode, null);
+ }
+
+ /**
+ * Add a directory to the zip stream.
+ * @param dir the directory to add to the archive
+ * @param zOut the stream to write to
+ * @param vPath the name this entry shall have in the archive
+ * @param mode the Unix permissions to set.
+ * @param extra ZipExtraFields to add
+ * @throws IOException on error
+ * @since Ant 1.6.3
+ */
+ protected void zipDir(final File dir, final ZipOutputStream zOut, final String vPath,
+ final int mode, final ZipExtraField[] extra)
+ throws IOException {
+ zipDir(dir == null ? (Resource) null : new FileResource(dir),
+ zOut, vPath, mode, extra);
+ }
+
+ /**
+ * Add a directory to the zip stream.
+ * @param dir the directory to add to the archive
+ * @param zOut the stream to write to
+ * @param vPath the name this entry shall have in the archive
+ * @param mode the Unix permissions to set.
+ * @param extra ZipExtraFields to add
+ * @throws IOException on error
+ * @since Ant 1.8.0
+ */
+ protected void zipDir(final Resource dir, final ZipOutputStream zOut, final String vPath,
+ final int mode, final ZipExtraField[] extra)
+ throws IOException {
+ if (doFilesonly) {
+ logWhenWriting("skipping directory " + vPath
+ + " for file-only archive",
+ Project.MSG_VERBOSE);
+ return;
+ }
+ if (addedDirs.get(vPath) != null) {
+ // don't add directories we've already added.
+ // no warning if we try, it is harmless in and of itself
+ return;
+ }
+
+ logWhenWriting("adding directory " + vPath, Project.MSG_VERBOSE);
+ addedDirs.put(vPath, vPath);
+
+ if (!skipWriting) {
+ final ZipEntry ze = new ZipEntry (vPath);
+
+ // ZIPs store time with a granularity of 2 seconds, round up
+ final int millisToAdd = roundUp ? ROUNDUP_MILLIS : 0;
+
+ if (dir != null && dir.isExists()) {
+ ze.setTime(dir.getLastModified() + millisToAdd);
+ } else {
+ ze.setTime(System.currentTimeMillis() + millisToAdd);
+ }
+ ze.setSize (0);
+ ze.setMethod (ZipEntry.STORED);
+ // This is faintly ridiculous:
+ ze.setCrc (EMPTY_CRC);
+ ze.setUnixMode(mode);
+
+ if (extra != null) {
+ ze.setExtraFields(extra);
+ }
+
+ zOut.putNextEntry(ze);
+ }
+ }
+
+ /*
+ * This is a hacky construct to extend the zipFile method to
+ * support a new parameter (extra fields to preserve) without
+ * breaking subclasses that override the old method signature.
+ */
+ private static final ThreadLocal<ZipExtraField[]> CURRENT_ZIP_EXTRA = new ThreadLocal<ZipExtraField[]>();
+
+ /**
+ * Provides the extra fields for the zip entry currently being
+ * added to the archive - if any.
+ * @since Ant 1.8.0
+ */
+ protected final ZipExtraField[] getCurrentExtraFields() {
+ return CURRENT_ZIP_EXTRA.get();
+ }
+
+ /**
+ * Sets the extra fields for the zip entry currently being
+ * added to the archive - if any.
+ * @since Ant 1.8.0
+ */
+ protected final void setCurrentExtraFields(final ZipExtraField[] extra) {
+ CURRENT_ZIP_EXTRA.set(extra);
+ }
+
+ /**
+ * Adds a new entry to the archive, takes care of duplicates as well.
+ *
+ * @param in the stream to read data for the entry from. The
+ * caller of the method is responsible for closing the stream.
+ * @param zOut the stream to write to.
+ * @param vPath the name this entry shall have in the archive.
+ * @param lastModified last modification time for the entry.
+ * @param fromArchive the original archive we are copying this
+ * entry from, will be null if we are not copying from an archive.
+ * @param mode the Unix permissions to set.
+ *
+ * @since Ant 1.5.2
+ * @throws IOException on error
+ */
+ protected void zipFile(InputStream in, final ZipOutputStream zOut, final String vPath,
+ final long lastModified, final File fromArchive, final int mode)
+ throws IOException {
+ // fromArchive is used in subclasses overriding this method
+
+ if (entries.containsKey(vPath)) {
+
+ if (duplicate.equals("preserve")) {
+ logWhenWriting(vPath + " already added, skipping",
+ Project.MSG_INFO);
+ return;
+ } else if (duplicate.equals("fail")) {
+ throw new BuildException("Duplicate file " + vPath
+ + " was found and the duplicate "
+ + "attribute is 'fail'.");
+ } else {
+ // duplicate equal to add, so we continue
+ logWhenWriting("duplicate file " + vPath
+ + " found, adding.", Project.MSG_VERBOSE);
+ }
+ } else {
+ logWhenWriting("adding entry " + vPath, Project.MSG_VERBOSE);
+ }
+
+ entries.put(vPath, vPath);
+
+ if (!skipWriting) {
+ final ZipEntry ze = new ZipEntry(vPath);
+ ze.setTime(lastModified);
+ ze.setMethod(doCompress ? ZipEntry.DEFLATED : ZipEntry.STORED);
+
+ /*
+ * ZipOutputStream.putNextEntry expects the ZipEntry to
+ * know its size and the CRC sum before you start writing
+ * the data when using STORED mode - unless it is seekable.
+ *
+ * This forces us to process the data twice.
+ */
+ if (!zOut.isSeekable() && !doCompress) {
+ long size = 0;
+ final CRC32 cal = new CRC32();
+ if (!in.markSupported()) {
+ // Store data into a byte[]
+ final ByteArrayOutputStream bos = new ByteArrayOutputStream();
+
+ final byte[] buffer = new byte[BUFFER_SIZE];
+ int count = 0;
+ do {
+ size += count;
+ cal.update(buffer, 0, count);
+ bos.write(buffer, 0, count);
+ count = in.read(buffer, 0, buffer.length);
+ } while (count != -1);
+ in = new ByteArrayInputStream(bos.toByteArray());
+
+ } else {
+ in.mark(Integer.MAX_VALUE);
+ final byte[] buffer = new byte[BUFFER_SIZE];
+ int count = 0;
+ do {
+ size += count;
+ cal.update(buffer, 0, count);
+ count = in.read(buffer, 0, buffer.length);
+ } while (count != -1);
+ in.reset();
+ }
+ ze.setSize(size);
+ ze.setCrc(cal.getValue());
+ }
+
+ ze.setUnixMode(mode);
+ final ZipExtraField[] extra = getCurrentExtraFields();
+ if (extra != null) {
+ ze.setExtraFields(extra);
+ }
+
+ zOut.putNextEntry(ze);
+
+ final byte[] buffer = new byte[BUFFER_SIZE];
+ int count = 0;
+ do {
+ if (count != 0) {
+ zOut.write(buffer, 0, count);
+ }
+ count = in.read(buffer, 0, buffer.length);
+ } while (count != -1);
+ }
+ addedFiles.addElement(vPath);
+ }
+
+ /**
+ * Adds a new entry to the archive, takes care of duplicates as well.
+ *
+ * @param in the stream to read data for the entry from. The
+ * caller of the method is responsible for closing the stream.
+ * @param zOut the stream to write to.
+ * @param vPath the name this entry shall have in the archive.
+ * @param lastModified last modification time for the entry.
+ * @param fromArchive the original archive we are copying this
+ * entry from, will be null if we are not copying from an archive.
+ * @param mode the Unix permissions to set.
+ * @param extra ZipExtraFields to add
+ *
+ * @since Ant 1.8.0
+ * @throws IOException on error
+ */
+ protected final void zipFile(final InputStream in, final ZipOutputStream zOut,
+ final String vPath, final long lastModified,
+ final File fromArchive, final int mode,
+ final ZipExtraField[] extra)
+ throws IOException {
+ try {
+ setCurrentExtraFields(extra);
+ zipFile(in, zOut, vPath, lastModified, fromArchive, mode);
+ } finally {
+ setCurrentExtraFields(null);
+ }
+ }
+
+ /**
+ * Method that gets called when adding from <code>java.io.File</code> instances.
+ *
+ * <p>This implementation delegates to the six-arg version.</p>
+ *
+ * @param file the file to add to the archive
+ * @param zOut the stream to write to
+ * @param vPath the name this entry shall have in the archive
+ * @param mode the Unix permissions to set.
+ * @throws IOException on error
+ *
+ * @since Ant 1.5.2
+ */
+ protected void zipFile(final File file, final ZipOutputStream zOut, final String vPath,
+ final int mode)
+ throws IOException {
+ if (file.equals(zipFile)) {
+ throw new BuildException("A zip file cannot include itself",
+ getLocation());
+ }
+
+ final FileInputStream fIn = new FileInputStream(file);
+ try {
+ // ZIPs store time with a granularity of 2 seconds, round up
+ zipFile(fIn, zOut, vPath,
+ file.lastModified() + (roundUp ? ROUNDUP_MILLIS : 0),
+ null, mode);
+ } finally {
+ fIn.close();
+ }
+ }
+
+ /**
+ * Ensure all parent dirs of a given entry have been added.
+ * @param baseDir the base directory to use (may be null)
+ * @param entry the entry name to create directories from
+ * @param zOut the stream to write to
+ * @param prefix a prefix to place on the created entries
+ * @param dirMode the directory mode
+ * @throws IOException on error
+ * @since Ant 1.5.2
+ */
+ protected final void addParentDirs(final File baseDir, final String entry,
+ final ZipOutputStream zOut, final String prefix,
+ final int dirMode)
+ throws IOException {
+ if (!doFilesonly) {
+ final Stack<String> directories = new Stack<String>();
+ int slashPos = entry.length();
+
+ while ((slashPos = entry.lastIndexOf('/', slashPos - 1)) != -1) {
+ final String dir = entry.substring(0, slashPos + 1);
+ if (addedDirs.get(prefix + dir) != null) {
+ break;
+ }
+ directories.push(dir);
+ }
+
+ while (!directories.isEmpty()) {
+ final String dir = directories.pop();
+ File f = null;
+ if (baseDir != null) {
+ f = new File(baseDir, dir);
+ } else {
+ f = new File(dir);
+ }
+ zipDir(f, zOut, prefix + dir, dirMode);
+ }
+ }
+ }
+
+ /**
+ * Do any clean up necessary to allow this instance to be used again.
+ *
+ * <p>When we get here, the Zip file has been closed and all we
+ * need to do is to reset some globals.</p>
+ *
+ * <p>This method will only reset globals that have been changed
+ * during execute(), it will not alter the attributes or nested
+ * child elements. If you want to reset the instance so that you
+ * can later zip a completely different set of files, you must use
+ * the reset method.</p>
+ *
+ * @see #reset
+ */
+ protected void cleanUp() {
+ addedDirs.clear();
+ addedFiles.removeAllElements();
+ entries.clear();
+ addingNewFiles = false;
+ doUpdate = savedDoUpdate;
+ final Enumeration<ZipFileSet> e = filesetsFromGroupfilesets.elements();
+ while (e.hasMoreElements()) {
+ final ZipFileSet zf = e.nextElement();
+ resources.removeElement(zf);
+ }
+ filesetsFromGroupfilesets.removeAllElements();
+ HAVE_NON_FILE_SET_RESOURCES_TO_ADD.set(Boolean.FALSE);
+ }
+
+ /**
+ * Makes this instance reset all attributes to their default
+ * values and forget all children.
+ *
+ * @since Ant 1.5
+ *
+ * @see #cleanUp
+ */
+ public void reset() {
+ resources.removeAllElements();
+ zipFile = null;
+ baseDir = null;
+ groupfilesets.removeAllElements();
+ duplicate = "add";
+ archiveType = "zip";
+ doCompress = true;
+ emptyBehavior = "skip";
+ doUpdate = false;
+ doFilesonly = false;
+ encoding = null;
+ }
+
+ /**
+ * Check is the resource arrays are empty.
+ * @param r the arrays to check
+ * @return true if all individual arrays are empty
+ *
+ * @since Ant 1.5.2
+ */
+ protected static final boolean isEmpty(final Resource[][] r) {
+ for (int i = 0; i < r.length; i++) {
+ if (r[i].length > 0) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Drops all non-file resources from the given array.
+ * @param orig the resources to filter
+ * @return the filters resources
+ * @since Ant 1.6
+ */
+ protected Resource[] selectFileResources(final Resource[] orig) {
+ return selectResources(orig,
+ new ResourceSelector() {
+ public boolean isSelected(final Resource r) {
+ if (!r.isDirectory()) {
+ return true;
+ } else if (doFilesonly) {
+ logWhenWriting("Ignoring directory "
+ + r.getName()
+ + " as only files will"
+ + " be added.",
+ Project.MSG_VERBOSE);
+ }
+ return false;
+ }
+ });
+ }
+
+ /**
+ * Drops all non-directory resources from the given array.
+ * @param orig the resources to filter
+ * @return the filters resources
+ * @since Ant 1.8.0
+ */
+ protected Resource[] selectDirectoryResources(final Resource[] orig) {
+ return selectResources(orig,
+ new ResourceSelector() {
+ public boolean isSelected(final Resource r) {
+ return r.isDirectory();
+ }
+ });
+ }
+
+ /**
+ * Drops all resources from the given array that are not selected
+ * @param orig the resources to filter
+ * @return the filters resources
+ * @since Ant 1.8.0
+ */
+ protected Resource[] selectResources(final Resource[] orig,
+ final ResourceSelector selector) {
+ if (orig.length == 0) {
+ return orig;
+ }
+
+ final ArrayList<Resource> v = new ArrayList<Resource>(orig.length);
+ for (int i = 0; i < orig.length; i++) {
+ if (selector.isSelected(orig[i])) {
+ v.add(orig[i]);
+ }
+ }
+
+ if (v.size() != orig.length) {
+ return v.toArray(new Resource[v.size()]);
+ }
+ return orig;
+ }
+
+ /**
+ * Logs a message at the given output level, but only if this is
+ * the pass that will actually create the archive.
+ *
+ * @since Ant 1.8.0
+ */
+ protected void logWhenWriting(final String msg, final int level) {
+ if (!skipWriting) {
+ log(msg, level);
+ }
+ }
+
+ /**
+ * Possible behaviors when a duplicate file is added:
+ * "add", "preserve" or "fail"
+ */
+ public static class Duplicate extends EnumeratedAttribute {
+ /**
+ * @see EnumeratedAttribute#getValues()
+ */
+ /** {@inheritDoc} */
+ @Override
+ public String[] getValues() {
+ return new String[] {"add", "preserve", "fail"};
+ }
+ }
+
+ /**
+ * Holds the up-to-date status and the out-of-date resources of
+ * the original archive.
+ *
+ * @since Ant 1.5.3
+ */
+ public static class ArchiveState {
+ private final boolean outOfDate;
+ private final Resource[][] resourcesToAdd;
+
+ ArchiveState(final boolean state, final Resource[][] r) {
+ outOfDate = state;
+ resourcesToAdd = r;
+ }
+
+ /**
+ * Return the outofdate status.
+ * @return the outofdate status
+ */
+ public boolean isOutOfDate() {
+ return outOfDate;
+ }
+
+ /**
+ * Get the resources to add.
+ * @return the resources to add
+ */
+ public Resource[][] getResourcesToAdd() {
+ return resourcesToAdd;
+ }
+ /**
+ * find out if there are absolutely no resources to add
+ * @since Ant 1.6.3
+ * @return true if there are no resources to add
+ */
+ public boolean isWithoutAnyResources() {
+ if (resourcesToAdd == null) {
+ return true;
+ }
+ for (int counter = 0; counter < resourcesToAdd.length; counter++) {
+ if (resourcesToAdd[counter] != null) {
+ if (resourcesToAdd[counter].length > 0) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+ }
+
+ /**
+ * Policiy for creation of Unicode extra fields: never, always or
+ * not-encodeable.
+ *
+ * @since Ant 1.8.0
+ */
+ public static final class UnicodeExtraField extends EnumeratedAttribute {
+ private static final Map<String, UnicodeExtraFieldPolicy> POLICIES = new HashMap<String, UnicodeExtraFieldPolicy>();
+ private static final String NEVER_KEY = "never";
+ private static final String ALWAYS_KEY = "always";
+ private static final String N_E_KEY = "not-encodeable";
+ static {
+ POLICIES.put(NEVER_KEY,
+ ZipOutputStream.UnicodeExtraFieldPolicy.NEVER);
+ POLICIES.put(ALWAYS_KEY,
+ ZipOutputStream.UnicodeExtraFieldPolicy.ALWAYS);
+ POLICIES.put(N_E_KEY,
+ ZipOutputStream.UnicodeExtraFieldPolicy
+ .NOT_ENCODEABLE);
+ }
+
+ @Override
+ public String[] getValues() {
+ return new String[] {NEVER_KEY, ALWAYS_KEY, N_E_KEY};
+ }
+
+ public static final UnicodeExtraField NEVER =
+ new UnicodeExtraField(NEVER_KEY);
+
+ private UnicodeExtraField(final String name) {
+ setValue(name);
+ }
+
+ public UnicodeExtraField() {
+ }
+
+ public ZipOutputStream.UnicodeExtraFieldPolicy getPolicy() {
+ return POLICIES.get(getValue());
+ }
+ }
+
+
+ /**
+ * The choices for Zip64 extensions.
+ *
+ * <p><b>never</b>: never add any Zip64 extensions. This will
+ * cause the task to fail if you try to add entries bigger than
+ * 4GB or create an archive bigger than 4GB or holding more that
+ * 65535 entries.</p>
+ *
+ * <p><b>as-needed</b>: create Zip64 extensions only when the
+ * entry's size is bigger than 4GB or one of the archive limits is
+ * hit. This mode also adds partial Zip64 extensions for all
+ * deflated entries written by Ant.</p>
+ *
+ * <p><b>always</b>: create Zip64 extensions for all entries.</p>
+ *
+ * <p><b>Note</b> some ZIP implementations don't handle Zip64
+ * extensions well and others may fail if the Zip64 extra field
+ * data is only present inside the local file header but not the
+ * central directory - which is what <em>as-needed</em> may result
+ * in. Java5 and Microsoft Visual Studio's Extension loader are
+ * known to fconsider the archive broken in such cases. If you
+ * are targeting such an archiver uset the value <em>never</em>
+ * unless you know you need Zip64 extensions.</p>
+ *
+ * @since Ant 1.9.1
+ */
+ public static final class Zip64ModeAttribute extends EnumeratedAttribute {
+ private static final Map<String, Zip64Mode> MODES = new HashMap<String, Zip64Mode>();
+
+ private static final String NEVER_KEY = "never";
+ private static final String ALWAYS_KEY = "always";
+ private static final String A_N_KEY = "as-needed";
+ static {
+ MODES.put(NEVER_KEY, Zip64Mode.Never);
+ MODES.put(ALWAYS_KEY, Zip64Mode.Always);
+ MODES.put(A_N_KEY, Zip64Mode.AsNeeded);
+ }
+
+ @Override
+ public String[] getValues() {
+ return new String[] {NEVER_KEY, ALWAYS_KEY, A_N_KEY};
+ }
+
+ public static final Zip64ModeAttribute NEVER =
+ new Zip64ModeAttribute(NEVER_KEY);
+ public static final Zip64ModeAttribute AS_NEEDED =
+ new Zip64ModeAttribute(A_N_KEY);
+
+ private Zip64ModeAttribute(final String name) {
+ setValue(name);
+ }
+
+ public Zip64ModeAttribute() {
+ }
+
+ public Zip64Mode getMode() {
+ return MODES.get(getValue());
+ }
+
+ }
+ }
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/compilers/AptCompilerAdapter.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/compilers/AptCompilerAdapter.java
new file mode 100644
index 00000000..9503ac02
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/compilers/AptCompilerAdapter.java
@@ -0,0 +1,187 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.compilers;
+
+import java.io.File;
+import java.lang.reflect.Method;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.Apt;
+import org.apache.tools.ant.types.Commandline;
+import org.apache.tools.ant.types.Path;
+
+
+/**
+ * <p>The implementation of the apt compiler for JDK 1.5.</p>
+ *
+ * <p>As usual, the low level entry points for Java tools are neither documented or
+ * stable; this entry point may change from that of 1.5.0_01-b08 without any
+ * warning at all. The IDE decompile of the tool entry points is as follows:</p>
+ * <pre>
+ * public class Main {
+ * public Main() ;
+ *
+ * public static transient void main(String... strings);
+ *
+ * public static transient int process(String... strings);
+ *
+ * public static transient int process(PrintWriter printWriter,
+ * String... strings);
+ * public static transient int process(
+ * AnnotationProcessorFactory annotationProcessorFactory,
+ * String... strings);
+ *
+ * public static transient int process(
+ * AnnotationProcessorFactory annotationProcessorFactory,
+ * PrintWriter printWriter,
+ * String... strings);
+ * private static transient int processing(
+ * AnnotationProcessorFactory annotationProcessorFactory,
+ * PrintWriter printWriter,
+ * String... strings) ;
+ * }
+ * </pre>
+ *
+ * This Adapter is designed to run Apt in-JVM, an option that is not actually
+ * exposed to end-users, because it was too brittle during beta testing; classpath
+ * problems being the core issue.
+ *
+ * @since Ant 1.7
+ */
+public class AptCompilerAdapter extends DefaultCompilerAdapter {
+
+ /**
+ * Integer returned by the Apt compiler to indicate success.
+ */
+ private static final int APT_COMPILER_SUCCESS = 0;
+ /**
+ * class in tools.jar that implements APT
+ */
+ public static final String APT_ENTRY_POINT = "com.sun.tools.apt.Main";
+
+ /**
+ * method used to compile.
+ */
+ public static final String APT_METHOD_NAME = "process";
+
+ /**
+ * Get the facade task that fronts this adapter
+ *
+ * @return task instance
+ * @see DefaultCompilerAdapter#getJavac()
+ */
+ protected Apt getApt() {
+ return (Apt) getJavac();
+ }
+
+ /**
+ * Using the front end arguments, set up the command line to run Apt
+ *
+ * @param apt task
+ * @param cmd command that is set up with the various switches from the task
+ * options
+ */
+ static void setAptCommandlineSwitches(final Apt apt, final Commandline cmd) {
+
+ if (!apt.isCompile()) {
+ cmd.createArgument().setValue("-nocompile");
+ }
+
+ // Process the factory class
+ final String factory = apt.getFactory();
+ if (factory != null) {
+ cmd.createArgument().setValue("-factory");
+ cmd.createArgument().setValue(factory);
+ }
+
+ // Process the factory path
+ final Path factoryPath = apt.getFactoryPath();
+ if (factoryPath != null) {
+ cmd.createArgument().setValue("-factorypath");
+ cmd.createArgument().setPath(factoryPath);
+ }
+
+ final File preprocessDir = apt.getPreprocessDir();
+ if (preprocessDir != null) {
+ cmd.createArgument().setValue("-s");
+ cmd.createArgument().setFile(preprocessDir);
+ }
+
+ // Process the processor options
+ final Vector options = apt.getOptions();
+ final Enumeration elements = options.elements();
+ Apt.Option opt;
+ StringBuffer arg = null;
+ while (elements.hasMoreElements()) {
+ opt = (Apt.Option) elements.nextElement();
+ arg = new StringBuffer();
+ arg.append("-A").append(opt.getName());
+ if (opt.getValue() != null) {
+ arg.append("=").append(opt.getValue());
+ }
+ cmd.createArgument().setValue(arg.toString());
+ }
+ }
+
+ /**
+ * using our front end task, set up the command line switches
+ *
+ * @param cmd command line to set up
+ */
+ protected void setAptCommandlineSwitches(final Commandline cmd) {
+ final Apt apt = getApt();
+ setAptCommandlineSwitches(apt, cmd);
+ }
+
+ /**
+ * Run the compilation.
+ * @return true on success.
+ * @throws BuildException if the compilation has problems.
+ */
+ public boolean execute() throws BuildException {
+ attributes.log("Using apt compiler", Project.MSG_VERBOSE);
+ //set up the javac options
+ final Commandline cmd = setupModernJavacCommand();
+ //then add the Apt options
+ setAptCommandlineSwitches(cmd);
+
+ //finally invoke APT
+ // Use reflection to be able to build on all JDKs:
+ try {
+ final Class c = Class.forName(APT_ENTRY_POINT);
+ final Object compiler = c.newInstance();
+ final Method compile = c.getMethod(APT_METHOD_NAME,
+ new Class[]{(new String[]{}).getClass()});
+ final int result = ((Integer) compile.invoke
+ (compiler, new Object[]{cmd.getArguments()}))
+ .intValue();
+ return (result == APT_COMPILER_SUCCESS);
+ } catch (final BuildException be) {
+ //rethrow build exceptions
+ throw be;
+ } catch (final Exception ex) {
+ //cast everything else to a build exception
+ throw new BuildException("Error starting apt compiler",
+ ex, location);
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/compilers/AptExternalCompilerAdapter.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/compilers/AptExternalCompilerAdapter.java
new file mode 100644
index 00000000..dadb55ba
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/compilers/AptExternalCompilerAdapter.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.compilers;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.Apt;
+import org.apache.tools.ant.types.Commandline;
+
+/**
+ * The implementation of the apt compiler for JDK 1.5 using an external process
+ *
+ * @since Ant 1.7
+ */
+public class AptExternalCompilerAdapter extends DefaultCompilerAdapter {
+
+
+ /**
+ * Get the facade task that fronts this adapter
+ *
+ * @return task instance
+ * @see DefaultCompilerAdapter#getJavac()
+ */
+ protected Apt getApt() {
+ return (Apt) getJavac();
+ }
+
+ /**
+ * Performs a compile using the Javac externally.
+ * @return true the compilation was successful.
+ * @throws BuildException if there is a problem.
+ */
+ public boolean execute() throws BuildException {
+ attributes.log("Using external apt compiler", Project.MSG_VERBOSE);
+
+
+ // Setup the apt executable
+ Apt apt = getApt();
+ Commandline cmd = new Commandline();
+ cmd.setExecutable(apt.getAptExecutable());
+ setupModernJavacCommandlineSwitches(cmd);
+ AptCompilerAdapter.setAptCommandlineSwitches(apt, cmd);
+ int firstFileName = cmd.size();
+ //add the files
+ logAndAddFilesToCompile(cmd);
+
+ //run
+ return 0 == executeExternalCompile(cmd.getCommandline(),
+ firstFileName,
+ true);
+
+ }
+
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/compilers/CompilerAdapter.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/compilers/CompilerAdapter.java
new file mode 100644
index 00000000..5a275b8c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/compilers/CompilerAdapter.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.compilers;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.taskdefs.Javac;
+
+/**
+ * The interface that all compiler adapters must adhere to.
+ *
+ * <p>A compiler adapter is an adapter that interprets the javac's
+ * parameters in preparation to be passed off to the compiler this
+ * adapter represents. As all the necessary values are stored in the
+ * Javac task itself, the only thing all adapters need is the javac
+ * task, the execute command and a parameterless constructor (for
+ * reflection).</p>
+ *
+ * @since Ant 1.3
+ */
+
+public interface CompilerAdapter {
+
+ /**
+ * Sets the compiler attributes, which are stored in the Javac task.
+ * @param attributes the compiler attributes
+ */
+ void setJavac(Javac attributes);
+
+ /**
+ * Executes the task.
+ *
+ * @return has the compilation been successful
+ * @throws BuildException on error
+ */
+ boolean execute() throws BuildException;
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/compilers/CompilerAdapterExtension.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/compilers/CompilerAdapterExtension.java
new file mode 100644
index 00000000..038b9cbe
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/compilers/CompilerAdapterExtension.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.compilers;
+
+/**
+ * Extension interface for compilers that support source extensions
+ * other than .java.
+ *
+ * @since Ant 1.8.2
+ */
+public interface CompilerAdapterExtension {
+
+ /**
+ * Returns a list of source file extensions that are recognized by
+ * this compiler adapter.
+ *
+ * <p>For example, most compiler adapters will return [ "java" ],
+ * but a compiler adapter that can compile both Java and Groovy
+ * source code would return [ "java", "groovy" ].</p>
+ *
+ * @return list of source file extensions recognized by this
+ * compiler adapter.
+ */
+ String[] getSupportedFileExtensions();
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/compilers/CompilerAdapterFactory.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/compilers/CompilerAdapterFactory.java
new file mode 100644
index 00000000..aeecb4a5
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/compilers/CompilerAdapterFactory.java
@@ -0,0 +1,202 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.compilers;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.util.ClasspathUtils;
+import org.apache.tools.ant.util.JavaEnvUtils;
+
+/**
+ * Creates the necessary compiler adapter, given basic criteria.
+ *
+ * @since Ant 1.3
+ */
+public final class CompilerAdapterFactory {
+ private static final String MODERN_COMPILER = "com.sun.tools.javac.Main";
+
+ /** This is a singleton -- can't create instances!! */
+ private CompilerAdapterFactory() {
+ }
+
+ /**
+ * Based on the parameter passed in, this method creates the necessary
+ * factory desired.
+ *
+ * The current mapping for compiler names are as follows:
+ * <ul><li>jikes = jikes compiler
+ * <li>classic, javac1.1, javac1.2 = the standard compiler from JDK
+ * 1.1/1.2
+ * <li>modern, javac1.3, javac1.4, javac1.5 = the compiler of JDK 1.3+
+ * <li>jvc, microsoft = the command line compiler from Microsoft's SDK
+ * for Java / Visual J++
+ * <li>kjc = the kopi compiler</li>
+ * <li>gcj = the gcj compiler from gcc</li>
+ * <li>sj, symantec = the Symantec Java compiler</li>
+ * <li><i>a fully qualified classname</i> = the name of a compiler
+ * adapter
+ * </ul>
+ *
+ * @param compilerType either the name of the desired compiler, or the
+ * full classname of the compiler's adapter.
+ * @param task a task to log through.
+ * @return the compiler adapter
+ * @throws BuildException if the compiler type could not be resolved into
+ * a compiler adapter.
+ */
+ public static CompilerAdapter getCompiler(String compilerType, Task task)
+ throws BuildException {
+ return getCompiler(compilerType, task, null);
+ }
+
+ /**
+ * Based on the parameter passed in, this method creates the necessary
+ * factory desired.
+ *
+ * The current mapping for compiler names are as follows:
+ * <ul><li>jikes = jikes compiler
+ * <li>classic, javac1.1, javac1.2 = the standard compiler from JDK
+ * 1.1/1.2
+ * <li>modern, javac1.3, javac1.4, javac1.5 = the compiler of JDK 1.3+
+ * <li>jvc, microsoft = the command line compiler from Microsoft's SDK
+ * for Java / Visual J++
+ * <li>kjc = the kopi compiler</li>
+ * <li>gcj = the gcj compiler from gcc</li>
+ * <li>sj, symantec = the Symantec Java compiler</li>
+ * <li><i>a fully qualified classname</i> = the name of a compiler
+ * adapter
+ * </ul>
+ *
+ * @param compilerType either the name of the desired compiler, or the
+ * full classname of the compiler's adapter.
+ * @param task a task to log through.
+ * @param classpath the classpath to use when looking up an
+ * adapter class
+ * @return the compiler adapter
+ * @throws BuildException if the compiler type could not be resolved into
+ * a compiler adapter.
+ * @since Ant 1.8.0
+ */
+ public static CompilerAdapter getCompiler(String compilerType, Task task,
+ Path classpath)
+ throws BuildException {
+ if (compilerType.equalsIgnoreCase("jikes")) {
+ return new Jikes();
+ }
+ if (compilerType.equalsIgnoreCase("extjavac")) {
+ return new JavacExternal();
+ }
+ if (compilerType.equalsIgnoreCase("classic")
+ || compilerType.equalsIgnoreCase("javac1.1")
+ || compilerType.equalsIgnoreCase("javac1.2")) {
+ task.log("This version of java does "
+ + "not support the classic "
+ + "compiler; upgrading to modern",
+ Project.MSG_WARN);
+ compilerType = "modern";
+ }
+ //on java<=1.3 the modern falls back to classic if it is not found
+ //but on java>=1.4 we just bail out early
+ if (compilerType.equalsIgnoreCase("modern")
+ || compilerType.equalsIgnoreCase("javac1.3")
+ || compilerType.equalsIgnoreCase("javac1.4")
+ || compilerType.equalsIgnoreCase("javac1.5")
+ || compilerType.equalsIgnoreCase("javac1.6")
+ || compilerType.equalsIgnoreCase("javac1.7")
+ || compilerType.equalsIgnoreCase("javac1.8")
+ || compilerType.equalsIgnoreCase("javac1.9")) {
+ // does the modern compiler exist?
+ if (doesModernCompilerExist()) {
+ return new Javac13();
+ } else {
+ throw new BuildException("Unable to find a javac "
+ + "compiler;\n"
+ + MODERN_COMPILER
+ + " is not on the "
+ + "classpath.\n"
+ + "Perhaps JAVA_HOME does not"
+ + " point to the JDK.\n"
+ + "It is currently set to \""
+ + JavaEnvUtils.getJavaHome()
+ + "\"");
+ }
+ }
+
+ if (compilerType.equalsIgnoreCase("jvc")
+ || compilerType.equalsIgnoreCase("microsoft")) {
+ return new Jvc();
+ }
+ if (compilerType.equalsIgnoreCase("kjc")) {
+ return new Kjc();
+ }
+ if (compilerType.equalsIgnoreCase("gcj")) {
+ return new Gcj();
+ }
+ if (compilerType.equalsIgnoreCase("sj")
+ || compilerType.equalsIgnoreCase("symantec")) {
+ return new Sj();
+ }
+ return resolveClassName(compilerType,
+ // Memory-Leak in line below
+ task.getProject().createClassLoader(classpath));
+ }
+
+ /**
+ * query for the Modern compiler existing
+ * @return true if classic os on the classpath
+ */
+ private static boolean doesModernCompilerExist() {
+ try {
+ Class.forName(MODERN_COMPILER);
+ return true;
+ } catch (ClassNotFoundException cnfe) {
+ try {
+ ClassLoader cl = CompilerAdapterFactory.class.getClassLoader();
+ if (cl != null) {
+ cl.loadClass(MODERN_COMPILER);
+ return true;
+ }
+ } catch (ClassNotFoundException cnfe2) {
+ // Ignore Exception
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Tries to resolve the given classname into a compiler adapter.
+ * Throws a fit if it can't.
+ *
+ * @param className The fully qualified classname to be created.
+ * @param loader the classloader to use
+ * @throws BuildException This is the fit that is thrown if className
+ * isn't an instance of CompilerAdapter.
+ */
+ private static CompilerAdapter resolveClassName(String className,
+ ClassLoader loader)
+ throws BuildException {
+ return (CompilerAdapter) ClasspathUtils.newInstance(className,
+ loader != null ? loader :
+ CompilerAdapterFactory.class.getClassLoader(),
+ CompilerAdapter.class);
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/compilers/DefaultCompilerAdapter.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/compilers/DefaultCompilerAdapter.java
new file mode 100644
index 00000000..519163cc
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/compilers/DefaultCompilerAdapter.java
@@ -0,0 +1,736 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.compilers;
+
+//Java5 style
+//import static org.apache.tools.ant.util.StringUtils.LINE_SEP;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Location;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.Execute;
+import org.apache.tools.ant.taskdefs.Javac;
+import org.apache.tools.ant.taskdefs.LogStreamHandler;
+import org.apache.tools.ant.taskdefs.condition.Os;
+import org.apache.tools.ant.types.Commandline;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.util.FileUtils;
+import org.apache.tools.ant.util.JavaEnvUtils;
+import org.apache.tools.ant.util.StringUtils;
+
+/**
+ * This is the default implementation for the CompilerAdapter interface.
+ * Currently, this is a cut-and-paste of the original javac task.
+ *
+ * @since Ant 1.3
+ */
+public abstract class DefaultCompilerAdapter
+ implements CompilerAdapter, CompilerAdapterExtension {
+
+ private static final int COMMAND_LINE_LIMIT;
+ static {
+ if (Os.isFamily("os/2")) {
+ // OS/2 CMD.EXE has a much smaller limit around 1K
+ COMMAND_LINE_LIMIT = 1000;
+ } else {
+ COMMAND_LINE_LIMIT = 4096; // 4K
+ }
+ }
+ // CheckStyle:VisibilityModifier OFF - bc
+
+ private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+
+ protected Path src;
+ protected File destDir;
+ protected String encoding;
+ protected boolean debug = false;
+ protected boolean optimize = false;
+ protected boolean deprecation = false;
+ protected boolean depend = false;
+ protected boolean verbose = false;
+ protected String target;
+ protected Path bootclasspath;
+ protected Path extdirs;
+ protected Path compileClasspath;
+ protected Path compileSourcepath;
+ protected Project project;
+ protected Location location;
+ protected boolean includeAntRuntime;
+ protected boolean includeJavaRuntime;
+ protected String memoryInitialSize;
+ protected String memoryMaximumSize;
+
+ protected File[] compileList;
+ protected Javac attributes;
+
+ //must keep for subclass BC, though unused:
+ // CheckStyle:ConstantNameCheck OFF - bc
+ protected static final String lSep = StringUtils.LINE_SEP;
+
+ // CheckStyle:ConstantNameCheck ON
+ // CheckStyle:VisibilityModifier ON
+
+ /**
+ * Set the Javac instance which contains the configured compilation
+ * attributes.
+ *
+ * @param attributes a configured Javac task.
+ */
+ public void setJavac(final Javac attributes) {
+ this.attributes = attributes;
+ src = attributes.getSrcdir();
+ destDir = attributes.getDestdir();
+ encoding = attributes.getEncoding();
+ debug = attributes.getDebug();
+ optimize = attributes.getOptimize();
+ deprecation = attributes.getDeprecation();
+ depend = attributes.getDepend();
+ verbose = attributes.getVerbose();
+ target = attributes.getTarget();
+ bootclasspath = attributes.getBootclasspath();
+ extdirs = attributes.getExtdirs();
+ compileList = attributes.getFileList();
+ compileClasspath = attributes.getClasspath();
+ compileSourcepath = attributes.getSourcepath();
+ project = attributes.getProject();
+ location = attributes.getLocation();
+ includeAntRuntime = attributes.getIncludeantruntime();
+ includeJavaRuntime = attributes.getIncludejavaruntime();
+ memoryInitialSize = attributes.getMemoryInitialSize();
+ memoryMaximumSize = attributes.getMemoryMaximumSize();
+ }
+
+ /**
+ * Get the Javac task instance associated with this compiler adapter
+ *
+ * @return the configured Javac task instance used by this adapter.
+ */
+ public Javac getJavac() {
+ return attributes;
+ }
+
+ /**
+ * By default, only recognize files with a Java extension,
+ * but specialized compilers can recognize multiple kinds
+ * of files.
+ */
+ public String[] getSupportedFileExtensions() {
+ return new String[] {"java"};
+ }
+
+ /**
+ * Get the project this compiler adapter was created in.
+ * @return the owner project
+ * @since Ant 1.6
+ */
+ protected Project getProject() {
+ return project;
+ }
+
+ /**
+ * Builds the compilation classpath.
+ * @return the compilation class path
+ */
+ protected Path getCompileClasspath() {
+ final Path classpath = new Path(project);
+
+ // add dest dir to classpath so that previously compiled and
+ // untouched classes are on classpath
+
+ if (destDir != null && getJavac().isIncludeDestClasses()) {
+ classpath.setLocation(destDir);
+ }
+
+ // Combine the build classpath with the system classpath, in an
+ // order determined by the value of build.sysclasspath
+
+ Path cp = compileClasspath;
+ if (cp == null) {
+ cp = new Path(project);
+ }
+ if (includeAntRuntime) {
+ classpath.addExisting(cp.concatSystemClasspath("last"));
+ } else {
+ classpath.addExisting(cp.concatSystemClasspath("ignore"));
+ }
+
+ if (includeJavaRuntime) {
+ classpath.addJavaRuntime();
+ }
+
+ return classpath;
+ }
+
+ /**
+ * Get the command line arguments for the switches.
+ * @param cmd the command line
+ * @return the command line
+ */
+ protected Commandline setupJavacCommandlineSwitches(final Commandline cmd) {
+ return setupJavacCommandlineSwitches(cmd, false);
+ }
+
+ /**
+ * Does the command line argument processing common to classic and
+ * modern. Doesn't add the files to compile.
+ * @param cmd the command line
+ * @param useDebugLevel if true set set the debug level with the -g switch
+ * @return the command line
+ */
+ protected Commandline setupJavacCommandlineSwitches(final Commandline cmd,
+ final boolean useDebugLevel) {
+ final Path classpath = getCompileClasspath();
+ // For -sourcepath, use the "sourcepath" value if present.
+ // Otherwise default to the "srcdir" value.
+ Path sourcepath = null;
+ if (compileSourcepath != null) {
+ sourcepath = compileSourcepath;
+ } else {
+ sourcepath = src;
+ }
+
+ final String memoryParameterPrefix = assumeJava11() ? "-J-" : "-J-X";
+ if (memoryInitialSize != null) {
+ if (!attributes.isForkedJavac()) {
+ attributes.log("Since fork is false, ignoring "
+ + "memoryInitialSize setting.",
+ Project.MSG_WARN);
+ } else {
+ cmd.createArgument().setValue(memoryParameterPrefix
+ + "ms" + memoryInitialSize);
+ }
+ }
+
+ if (memoryMaximumSize != null) {
+ if (!attributes.isForkedJavac()) {
+ attributes.log("Since fork is false, ignoring "
+ + "memoryMaximumSize setting.",
+ Project.MSG_WARN);
+ } else {
+ cmd.createArgument().setValue(memoryParameterPrefix
+ + "mx" + memoryMaximumSize);
+ }
+ }
+
+ if (attributes.getNowarn()) {
+ cmd.createArgument().setValue("-nowarn");
+ }
+
+ if (deprecation) {
+ cmd.createArgument().setValue("-deprecation");
+ }
+
+ if (destDir != null) {
+ cmd.createArgument().setValue("-d");
+ cmd.createArgument().setFile(destDir);
+ }
+
+ cmd.createArgument().setValue("-classpath");
+
+ // Just add "sourcepath" to classpath ( for JDK1.1 )
+ // as well as "bootclasspath" and "extdirs"
+ if (assumeJava11()) {
+ final Path cp = new Path(project);
+
+ final Path bp = getBootClassPath();
+ if (bp.size() > 0) {
+ cp.append(bp);
+ }
+
+ if (extdirs != null) {
+ cp.addExtdirs(extdirs);
+ }
+ cp.append(classpath);
+ cp.append(sourcepath);
+ cmd.createArgument().setPath(cp);
+ } else {
+ cmd.createArgument().setPath(classpath);
+ // If the buildfile specifies sourcepath="", then don't
+ // output any sourcepath.
+ if (sourcepath.size() > 0) {
+ cmd.createArgument().setValue("-sourcepath");
+ cmd.createArgument().setPath(sourcepath);
+ }
+ if (target != null) {
+ cmd.createArgument().setValue("-target");
+ cmd.createArgument().setValue(target);
+ }
+
+ final Path bp = getBootClassPath();
+ if (bp.size() > 0) {
+ cmd.createArgument().setValue("-bootclasspath");
+ cmd.createArgument().setPath(bp);
+ }
+
+ if (extdirs != null && extdirs.size() > 0) {
+ cmd.createArgument().setValue("-extdirs");
+ cmd.createArgument().setPath(extdirs);
+ }
+ }
+
+ if (encoding != null) {
+ cmd.createArgument().setValue("-encoding");
+ cmd.createArgument().setValue(encoding);
+ }
+ if (debug) {
+ if (useDebugLevel && !assumeJava11()) {
+ final String debugLevel = attributes.getDebugLevel();
+ if (debugLevel != null) {
+ cmd.createArgument().setValue("-g:" + debugLevel);
+ } else {
+ cmd.createArgument().setValue("-g");
+ }
+ } else {
+ cmd.createArgument().setValue("-g");
+ }
+ } else if (getNoDebugArgument() != null) {
+ cmd.createArgument().setValue(getNoDebugArgument());
+ }
+ if (optimize) {
+ cmd.createArgument().setValue("-O");
+ }
+
+ if (depend) {
+ if (assumeJava11()) {
+ cmd.createArgument().setValue("-depend");
+ } else if (assumeJava12()) {
+ cmd.createArgument().setValue("-Xdepend");
+ } else {
+ attributes.log("depend attribute is not supported by the "
+ + "modern compiler", Project.MSG_WARN);
+ }
+ }
+
+ if (verbose) {
+ cmd.createArgument().setValue("-verbose");
+ }
+
+ addCurrentCompilerArgs(cmd);
+
+ return cmd;
+ }
+
+ /**
+ * Does the command line argument processing for modern. Doesn't
+ * add the files to compile.
+ * @param cmd the command line
+ * @return the command line
+ */
+ protected Commandline setupModernJavacCommandlineSwitches(final Commandline cmd) {
+ setupJavacCommandlineSwitches(cmd, true);
+ if (!assumeJava13()) { // -source added with JDK 1.4
+ final String t = attributes.getTarget();
+ if (attributes.getSource() != null) {
+ cmd.createArgument().setValue("-source");
+ cmd.createArgument()
+ .setValue(adjustSourceValue(attributes.getSource()));
+
+ } else if (t != null && mustSetSourceForTarget(t)) {
+ setImplicitSourceSwitch(cmd, t, adjustSourceValue(t));
+ }
+ }
+ return cmd;
+ }
+
+ /**
+ * Does the command line argument processing for modern and adds
+ * the files to compile as well.
+ * @return the command line
+ */
+ protected Commandline setupModernJavacCommand() {
+ final Commandline cmd = new Commandline();
+ setupModernJavacCommandlineSwitches(cmd);
+
+ logAndAddFilesToCompile(cmd);
+ return cmd;
+ }
+
+ /**
+ * Set up the command line.
+ * @return the command line
+ */
+ protected Commandline setupJavacCommand() {
+ return setupJavacCommand(false);
+ }
+
+ /**
+ * Does the command line argument processing for classic and adds
+ * the files to compile as well.
+ * @param debugLevelCheck if true set the debug level with the -g switch
+ * @return the command line
+ */
+ protected Commandline setupJavacCommand(final boolean debugLevelCheck) {
+ final Commandline cmd = new Commandline();
+ setupJavacCommandlineSwitches(cmd, debugLevelCheck);
+ logAndAddFilesToCompile(cmd);
+ return cmd;
+ }
+
+ /**
+ * Logs the compilation parameters, adds the files to compile and logs the
+ * &quot;niceSourceList&quot;
+ * @param cmd the command line
+ */
+ protected void logAndAddFilesToCompile(final Commandline cmd) {
+ attributes.log("Compilation " + cmd.describeArguments(),
+ Project.MSG_VERBOSE);
+
+ final StringBuffer niceSourceList = new StringBuffer("File");
+ if (compileList.length != 1) {
+ niceSourceList.append("s");
+ }
+ niceSourceList.append(" to be compiled:");
+
+ niceSourceList.append(StringUtils.LINE_SEP);
+
+ for (int i = 0; i < compileList.length; i++) {
+ final String arg = compileList[i].getAbsolutePath();
+ cmd.createArgument().setValue(arg);
+ niceSourceList.append(" ");
+ niceSourceList.append(arg);
+ niceSourceList.append(StringUtils.LINE_SEP);
+ }
+
+ attributes.log(niceSourceList.toString(), Project.MSG_VERBOSE);
+ }
+
+ /**
+ * Do the compile with the specified arguments.
+ * @param args - arguments to pass to process on command line
+ * @param firstFileName - index of the first source file in args,
+ * if the index is negative, no temporary file will ever be
+ * created, but this may hit the command line length limit on your
+ * system.
+ * @return the exit code of the compilation
+ */
+ protected int executeExternalCompile(final String[] args, final int firstFileName) {
+ return executeExternalCompile(args, firstFileName, true);
+ }
+
+ /**
+ * Do the compile with the specified arguments.
+ *
+ * <p>The working directory if the executed process will be the
+ * project's base directory.</p>
+ *
+ * @param args - arguments to pass to process on command line
+ * @param firstFileName - index of the first source file in args,
+ * if the index is negative, no temporary file will ever be
+ * created, but this may hit the command line length limit on your
+ * system.
+ * @param quoteFiles - if set to true, filenames containing
+ * spaces will be quoted when they appear in the external file.
+ * This is necessary when running JDK 1.4's javac and probably
+ * others.
+ * @return the exit code of the compilation
+ *
+ * @since Ant 1.6
+ */
+ protected int executeExternalCompile(final String[] args, final int firstFileName,
+ final boolean quoteFiles) {
+ String[] commandArray = null;
+ File tmpFile = null;
+
+ try {
+ /*
+ * Many system have been reported to get into trouble with
+ * long command lines - no, not only Windows ;-).
+ *
+ * POSIX seems to define a lower limit of 4k, so use a temporary
+ * file if the total length of the command line exceeds this limit.
+ */
+ if (Commandline.toString(args).length() > COMMAND_LINE_LIMIT
+ && firstFileName >= 0) {
+ BufferedWriter out = null;
+ try {
+ tmpFile = FILE_UTILS.createTempFile(
+ "files", "", getJavac().getTempdir(), true, true);
+ out = new BufferedWriter(new FileWriter(tmpFile));
+ for (int i = firstFileName; i < args.length; i++) {
+ if (quoteFiles && args[i].indexOf(" ") > -1) {
+ args[i] = args[i].replace(File.separatorChar, '/');
+ out.write("\"" + args[i] + "\"");
+ } else {
+ out.write(args[i]);
+ }
+ out.newLine();
+ }
+ out.flush();
+ commandArray = new String[firstFileName + 1];
+ System.arraycopy(args, 0, commandArray, 0, firstFileName);
+ commandArray[firstFileName] = "@" + tmpFile;
+ } catch (final IOException e) {
+ throw new BuildException("Error creating temporary file",
+ e, location);
+ } finally {
+ FileUtils.close(out);
+ }
+ } else {
+ commandArray = args;
+ }
+
+ try {
+ final Execute exe = new Execute(
+ new LogStreamHandler(attributes,
+ Project.MSG_INFO,
+ Project.MSG_WARN));
+ if (Os.isFamily("openvms")) {
+ //Use the VM launcher instead of shell launcher on VMS
+ //for java
+ exe.setVMLauncher(true);
+ }
+ exe.setAntRun(project);
+ exe.setWorkingDirectory(project.getBaseDir());
+ exe.setCommandline(commandArray);
+ exe.execute();
+ return exe.getExitValue();
+ } catch (final IOException e) {
+ throw new BuildException("Error running " + args[0]
+ + " compiler", e, location);
+ }
+ } finally {
+ if (tmpFile != null) {
+ tmpFile.delete();
+ }
+ }
+ }
+
+ /**
+ * Add extdirs to classpath
+ * @param classpath the classpath to use
+ * @deprecated since 1.5.x.
+ * Use org.apache.tools.ant.types.Path#addExtdirs instead.
+ */
+ @Deprecated
+ protected void addExtdirsToClasspath(final Path classpath) {
+ classpath.addExtdirs(extdirs);
+ }
+
+ /**
+ * Adds the command line arguments specific to the current implementation.
+ * @param cmd the command line to use
+ */
+ protected void addCurrentCompilerArgs(final Commandline cmd) {
+ cmd.addArguments(getJavac().getCurrentCompilerArgs());
+ }
+
+ /**
+ * Shall we assume JDK 1.1 command line switches?
+ * @return true if jdk 1.1
+ * @since Ant 1.5
+ */
+ protected boolean assumeJava11() {
+ return "javac1.1".equals(attributes.getCompilerVersion());
+ }
+
+ /**
+ * Shall we assume JDK 1.2 command line switches?
+ * @return true if jdk 1.2
+ * @since Ant 1.5
+ */
+ protected boolean assumeJava12() {
+ return "javac1.2".equals(attributes.getCompilerVersion());
+ }
+
+ /**
+ * Shall we assume JDK 1.3 command line switches?
+ * @return true if jdk 1.3
+ * @since Ant 1.5
+ */
+ protected boolean assumeJava13() {
+ return "javac1.3".equals(attributes.getCompilerVersion());
+ }
+
+ /**
+ * Shall we assume JDK 1.4 command line switches?
+ * @return true if jdk 1.4
+ * @since Ant 1.6.3
+ */
+ protected boolean assumeJava14() {
+ return assumeJavaXY("javac1.4", JavaEnvUtils.JAVA_1_4);
+ }
+
+ /**
+ * Shall we assume JDK 1.5 command line switches?
+ * @return true if JDK 1.5
+ * @since Ant 1.6.3
+ */
+ protected boolean assumeJava15() {
+ return assumeJavaXY("javac1.5", JavaEnvUtils.JAVA_1_5);
+ }
+
+ /**
+ * Shall we assume JDK 1.6 command line switches?
+ * @return true if JDK 1.6
+ * @since Ant 1.7
+ */
+ protected boolean assumeJava16() {
+ return assumeJavaXY("javac1.6", JavaEnvUtils.JAVA_1_6);
+ }
+
+ /**
+ * Shall we assume JDK 1.7 command line switches?
+ * @return true if JDK 1.7
+ * @since Ant 1.8.2
+ */
+ protected boolean assumeJava17() {
+ return assumeJavaXY("javac1.7", JavaEnvUtils.JAVA_1_7);
+ }
+
+ /**
+ * Shall we assume JDK 1.8 command line switches?
+ * @return true if JDK 1.8
+ * @since Ant 1.8.3
+ */
+ protected boolean assumeJava18() {
+ return assumeJavaXY("javac1.8", JavaEnvUtils.JAVA_1_8);
+ }
+
+ /**
+ * Shall we assume JDK 1.9 command line switches?
+ * @return true if JDK 1.9
+ * @since Ant 1.9.4
+ */
+ protected boolean assumeJava19() {
+ return assumeJavaXY("javac1.9", JavaEnvUtils.JAVA_1_9);
+ }
+
+ /**
+ * Shall we assume command line switches for the given version of Java?
+ * @since Ant 1.8.3
+ */
+ private boolean assumeJavaXY(final String javacXY, final String javaEnvVersionXY) {
+ return javacXY.equals(attributes.getCompilerVersion())
+ || ("classic".equals(attributes.getCompilerVersion())
+ && JavaEnvUtils.isJavaVersion(javaEnvVersionXY))
+ || ("modern".equals(attributes.getCompilerVersion())
+ && JavaEnvUtils.isJavaVersion(javaEnvVersionXY))
+ || ("extJavac".equals(attributes.getCompilerVersion())
+ && JavaEnvUtils.isJavaVersion(javaEnvVersionXY));
+ }
+
+ /**
+ * Combines a user specified bootclasspath with the system
+ * bootclasspath taking build.sysclasspath into account.
+ *
+ * @return a non-null Path instance that combines the user
+ * specified and the system bootclasspath.
+ */
+ protected Path getBootClassPath() {
+ final Path bp = new Path(project);
+ if (bootclasspath != null) {
+ bp.append(bootclasspath);
+ }
+ return bp.concatSystemBootClasspath("ignore");
+ }
+
+ /**
+ * The argument the compiler wants to see if the debug attribute
+ * has been set to false.
+ *
+ * <p>A return value of <code>null</code> means no argument at all.</p>
+ *
+ * @return "-g:none" unless we expect to invoke a JDK 1.1 compiler.
+ *
+ * @since Ant 1.6.3
+ */
+ protected String getNoDebugArgument() {
+ return assumeJava11() ? null : "-g:none";
+ }
+
+ private void setImplicitSourceSwitch(final Commandline cmd,
+ final String target, final String source) {
+ attributes.log("", Project.MSG_WARN);
+ attributes.log(" WARNING", Project.MSG_WARN);
+ attributes.log("", Project.MSG_WARN);
+ attributes.log("The -source switch defaults to " + getDefaultSource()
+ + ".",
+ Project.MSG_WARN);
+ attributes.log("If you specify -target " + target
+ + " you now must also specify -source " + source
+ + ".", Project.MSG_WARN);
+ attributes.log("Ant will implicitly add -source " + source
+ + " for you. Please change your build file.",
+ Project.MSG_WARN);
+ cmd.createArgument().setValue("-source");
+ cmd.createArgument().setValue(source);
+ }
+
+ /**
+ * A string that describes the default value for -source of the
+ * selected JDK's javac.
+ */
+ private String getDefaultSource() {
+ if (assumeJava15() || assumeJava16()) {
+ return "1.5 in JDK 1.5 and 1.6";
+ }
+ if (assumeJava17()) {
+ return "1.7 in JDK 1.7";
+ }
+ if (assumeJava18()) {
+ return "1.8 in JDK 1.8";
+ }
+ if (assumeJava19()) {
+ return "1.9 in JDK 1.9";
+ }
+ return "";
+ }
+
+ /**
+ * Whether the selected -target is known to be incompatible with
+ * the default -source value of the selected JDK's javac.
+ *
+ * <p>Assumes it will never be called unless the selected JDK is
+ * at least Java 1.5.</p>
+ *
+ * @param t the -target value, must not be null
+ */
+ private boolean mustSetSourceForTarget(String t) {
+ if (assumeJava14()) {
+ return false;
+ }
+ if (t.startsWith("1.")) {
+ t = t.substring(2);
+ }
+ return t.equals("1") || t.equals("2") || t.equals("3") || t.equals("4")
+ || ((t.equals("5") || t.equals("6"))
+ && !assumeJava15() && !assumeJava16())
+ || (t.equals("7") && !assumeJava17())
+ || (t.equals("8") && !assumeJava18())
+ || (t.equals("9") && !assumeJava19());
+ }
+
+
+ /**
+ * Turn the task's attribute for -source into soemthing that is
+ * understood by all javac's after 1.4.
+ *
+ * <p>support for -source 1.1 and -source 1.2 has been added with
+ * JDK 1.4.2 but isn't present in 1.5.0+</p>
+ */
+ private String adjustSourceValue(final String source) {
+ return (source.equals("1.1") || source.equals("1.2")) ? "1.3" : source;
+ }
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/compilers/Gcj.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/compilers/Gcj.java
new file mode 100644
index 00000000..3167cc24
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/compilers/Gcj.java
@@ -0,0 +1,160 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.compilers;
+
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.Commandline;
+import org.apache.tools.ant.types.Path;
+
+/**
+ * The implementation of the gcj compiler.
+ * This is primarily a cut-and-paste from the jikes.
+ *
+ * @since Ant 1.4
+ */
+public class Gcj extends DefaultCompilerAdapter {
+
+ /**
+ * Performs a compile using the gcj compiler.
+ * @return true if the compilation succeeded
+ * @throws BuildException on error
+ */
+ public boolean execute() throws BuildException {
+ Commandline cmd;
+ attributes.log("Using gcj compiler", Project.MSG_VERBOSE);
+ cmd = setupGCJCommand();
+
+ int firstFileName = cmd.size();
+ logAndAddFilesToCompile(cmd);
+
+ return
+ executeExternalCompile(cmd.getCommandline(), firstFileName) == 0;
+ }
+
+ /**
+ * Set up the gcj commandline.
+ * @return the command line
+ */
+ protected Commandline setupGCJCommand() {
+ Commandline cmd = new Commandline();
+ Path classpath = new Path(project);
+
+ // gcj doesn't support bootclasspath dir (-bootclasspath)
+ // so we'll emulate it for compatibility and convenience.
+ Path p = getBootClassPath();
+ if (p.size() > 0) {
+ classpath.append(p);
+ }
+
+ // gcj doesn't support an extension dir (-extdir)
+ // so we'll emulate it for compatibility and convenience.
+ if (extdirs != null || includeJavaRuntime) {
+ classpath.addExtdirs(extdirs);
+ }
+
+ classpath.append(getCompileClasspath());
+
+ // Gcj has no option for source-path so we
+ // will add it to classpath.
+ if (compileSourcepath != null) {
+ classpath.append(compileSourcepath);
+ } else {
+ classpath.append(src);
+ }
+
+ String exec = getJavac().getExecutable();
+ cmd.setExecutable(exec == null ? "gcj" : exec);
+
+ if (destDir != null) {
+ cmd.createArgument().setValue("-d");
+ cmd.createArgument().setFile(destDir);
+
+ if (!destDir.exists()
+ && !(destDir.mkdirs() || destDir.isDirectory())) {
+ throw new BuildException("Can't make output directories. "
+ + "Maybe permission is wrong. ");
+ }
+ }
+
+ cmd.createArgument().setValue("-classpath");
+ cmd.createArgument().setPath(classpath);
+
+ if (encoding != null) {
+ cmd.createArgument().setValue("--encoding=" + encoding);
+ }
+ if (debug) {
+ cmd.createArgument().setValue("-g1");
+ }
+ if (optimize) {
+ cmd.createArgument().setValue("-O");
+ }
+
+ /**
+ * gcj should be set for generate class.
+ * ... if no 'compile to native' argument is passed
+ */
+ if (!isNativeBuild()) {
+ cmd.createArgument().setValue("-C");
+ }
+
+ if (attributes.getSource() != null) {
+ String source = attributes.getSource();
+ cmd.createArgument().setValue("-fsource=" + source);
+ }
+
+ if (attributes.getTarget() != null) {
+ String target = attributes.getTarget();
+ cmd.createArgument().setValue("-ftarget=" + target);
+ }
+
+ addCurrentCompilerArgs(cmd);
+
+ return cmd;
+ }
+
+ /**
+ * Whether any of the arguments given via &lt;compilerarg&gt;
+ * implies that compilation to native code is requested.
+ * @return true if compilation to native code is requested
+ * @since Ant 1.6.2
+ */
+ public boolean isNativeBuild() {
+ boolean nativeBuild = false;
+ String[] additionalArguments = getJavac().getCurrentCompilerArgs();
+ int argsLength = 0;
+ while (!nativeBuild && argsLength < additionalArguments.length) {
+ int conflictLength = 0;
+ while (!nativeBuild
+ && conflictLength < CONFLICT_WITH_DASH_C.length) {
+ nativeBuild = (additionalArguments[argsLength].startsWith
+ (CONFLICT_WITH_DASH_C[conflictLength]));
+ conflictLength++;
+ }
+ argsLength++;
+ }
+ return nativeBuild;
+ }
+
+ private static final String [] CONFLICT_WITH_DASH_C = {
+ "-o" , "--main=", "-D", "-fjni", "-L"
+ };
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/compilers/Javac12.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/compilers/Javac12.java
new file mode 100644
index 00000000..3fd8ccdd
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/compilers/Javac12.java
@@ -0,0 +1,91 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.compilers;
+
+import java.io.OutputStream;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.LogOutputStream;
+import org.apache.tools.ant.types.Commandline;
+import org.apache.tools.ant.util.FileUtils;
+import org.apache.tools.ant.util.JavaEnvUtils;
+
+/**
+ * The implementation of the javac compiler for JDK 1.2
+ * This is primarily a cut-and-paste from the original javac task before it
+ * was refactored.
+ *
+ * @since Ant 1.3
+ * @deprecated Use {@link Javac13} instead.
+ */
+public class Javac12 extends DefaultCompilerAdapter {
+ protected static final String CLASSIC_COMPILER_CLASSNAME = "sun.tools.javac.Main";
+
+ /**
+ * Run the compilation.
+ * @return true if the compiler ran with a zero exit result (ok)
+ * @exception BuildException if the compilation has problems.
+ */
+ public boolean execute() throws BuildException {
+ attributes.log("Using classic compiler", Project.MSG_VERBOSE);
+ Commandline cmd = setupJavacCommand(true);
+
+ OutputStream logstr = new LogOutputStream(attributes, Project.MSG_WARN);
+ try {
+ // Create an instance of the compiler, redirecting output to
+ // the project log
+ Class c = Class.forName(CLASSIC_COMPILER_CLASSNAME);
+ Constructor cons =
+ c.getConstructor(new Class[] {OutputStream.class,
+ String.class});
+ Object compiler
+ = cons.newInstance(new Object[] {logstr, "javac"});
+
+ // Call the compile() method
+ Method compile = c.getMethod("compile",
+ new Class [] {String[].class});
+ Boolean ok =
+ (Boolean) compile.invoke(compiler,
+ new Object[] {cmd.getArguments()});
+ return ok.booleanValue();
+ } catch (ClassNotFoundException ex) {
+ throw new BuildException("Cannot use classic compiler , as it is "
+ + "not available. \n"
+ + " A common solution is "
+ + "to set the environment variable"
+ + " JAVA_HOME to your jdk directory.\n"
+ + "It is currently set to \""
+ + JavaEnvUtils.getJavaHome()
+ + "\"",
+ location);
+ } catch (Exception ex) {
+ if (ex instanceof BuildException) {
+ throw (BuildException) ex;
+ } else {
+ throw new BuildException("Error starting classic compiler: ",
+ ex, location);
+ }
+ } finally {
+ FileUtils.close(logstr);
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/compilers/Javac13.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/compilers/Javac13.java
new file mode 100644
index 00000000..acb6a7f0
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/compilers/Javac13.java
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.compilers;
+
+import java.lang.reflect.Method;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.Commandline;
+
+
+/**
+ * The implementation of the javac compiler for JDK 1.3
+ * This is primarily a cut-and-paste from the original javac task before it
+ * was refactored.
+ *
+ * @since Ant 1.3
+ */
+public class Javac13 extends DefaultCompilerAdapter {
+
+ /**
+ * Integer returned by the "Modern" jdk1.3 compiler to indicate success.
+ */
+ private static final int MODERN_COMPILER_SUCCESS = 0;
+
+ /**
+ * Run the compilation.
+ * @return true if the compiler ran with a zero exit result (ok)
+ * @exception BuildException if the compilation has problems.
+ */
+ public boolean execute() throws BuildException {
+ attributes.log("Using modern compiler", Project.MSG_VERBOSE);
+ Commandline cmd = setupModernJavacCommand();
+
+ // Use reflection to be able to build on all JDKs >= 1.1:
+ try {
+ Class c = Class.forName ("com.sun.tools.javac.Main");
+ Object compiler = c.newInstance ();
+ Method compile = c.getMethod ("compile",
+ new Class [] {(new String [] {}).getClass ()});
+ int result = ((Integer) compile.invoke
+ (compiler, new Object[] {cmd.getArguments()}))
+ .intValue ();
+ return (result == MODERN_COMPILER_SUCCESS);
+ } catch (Exception ex) {
+ if (ex instanceof BuildException) {
+ throw (BuildException) ex;
+ } else {
+ throw new BuildException("Error starting modern compiler",
+ ex, location);
+ }
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/compilers/JavacExternal.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/compilers/JavacExternal.java
new file mode 100644
index 00000000..ab284544
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/compilers/JavacExternal.java
@@ -0,0 +1,92 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.compilers;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.condition.Os;
+import org.apache.tools.ant.types.Commandline;
+import org.apache.tools.ant.util.FileUtils;
+import org.apache.tools.ant.util.JavaEnvUtils;
+
+/**
+ * Performs a compile using javac externally.
+ *
+ * @since Ant 1.4
+ */
+public class JavacExternal extends DefaultCompilerAdapter {
+
+ /**
+ * Performs a compile using the Javac externally.
+ * @return true if the compilation succeeded
+ * @throws BuildException on error
+ */
+ public boolean execute() throws BuildException {
+ attributes.log("Using external javac compiler", Project.MSG_VERBOSE);
+
+ Commandline cmd = new Commandline();
+ cmd.setExecutable(getJavac().getJavacExecutable());
+ if (!assumeJava11() && !assumeJava12()) {
+ setupModernJavacCommandlineSwitches(cmd);
+ } else {
+ setupJavacCommandlineSwitches(cmd, true);
+ }
+ int firstFileName = assumeJava11() ? -1 : cmd.size();
+ logAndAddFilesToCompile(cmd);
+ //On VMS platform, we need to create a special java options file
+ //containing the arguments and classpath for the javac command.
+ //The special file is supported by the "-V" switch on the VMS JVM.
+ if (Os.isFamily("openvms")) {
+ return execOnVMS(cmd, firstFileName);
+ }
+ return
+ executeExternalCompile(cmd.getCommandline(), firstFileName,
+ true)
+ == 0;
+ }
+
+ /**
+ * helper method to execute our command on VMS.
+ * @param cmd
+ * @param firstFileName
+ * @return
+ */
+ private boolean execOnVMS(Commandline cmd, int firstFileName) {
+ File vmsFile = null;
+ try {
+ vmsFile = JavaEnvUtils.createVmsJavaOptionFile(cmd.getArguments());
+ String[] commandLine = {cmd.getExecutable(),
+ "-V",
+ vmsFile.getPath()};
+ return 0 == executeExternalCompile(commandLine,
+ firstFileName,
+ true);
+
+ } catch (IOException e) {
+ throw new BuildException("Failed to create a temporary file for \"-V\" switch");
+ } finally {
+ FileUtils.delete(vmsFile);
+ }
+ }
+
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/compilers/Jikes.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/compilers/Jikes.java
new file mode 100644
index 00000000..eac1bcfc
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/compilers/Jikes.java
@@ -0,0 +1,221 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.compilers;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.Commandline;
+import org.apache.tools.ant.types.Path;
+
+/**
+ * The implementation of the jikes compiler.
+ * This is primarily a cut-and-paste from the original javac task before it
+ * was refactored.
+ *
+ * @since Ant 1.3
+ */
+public class Jikes extends DefaultCompilerAdapter {
+
+ /**
+ * Performs a compile using the Jikes compiler from IBM.
+ * Mostly of this code is identical to doClassicCompile()
+ * However, it does not support all options like
+ * extdirs, deprecation and so on, because
+ * there is no option in jikes and I don't understand
+ * what they should do.
+ *
+ * It has been successfully tested with jikes &gt;1.10.
+ * @return true if the compilation succeeded
+ * @throws BuildException on error
+ */
+ public boolean execute() throws BuildException {
+ attributes.log("Using jikes compiler", Project.MSG_VERBOSE);
+
+ Commandline cmd = new Commandline();
+
+ // For -sourcepath, use the "sourcepath" value if present.
+ // Otherwise default to the "srcdir" value.
+ Path sourcepath = null;
+ if (compileSourcepath != null) {
+ sourcepath = compileSourcepath;
+ } else {
+ sourcepath = src;
+ }
+ // If the buildfile specifies sourcepath="", then don't
+ // output any sourcepath.
+ if (sourcepath.size() > 0) {
+ cmd.createArgument().setValue("-sourcepath");
+ cmd.createArgument().setPath(sourcepath);
+ }
+
+ Path classpath = new Path(project);
+
+ if (bootclasspath == null || bootclasspath.size() == 0) {
+ // no bootclasspath, therefore, get one from the java runtime
+ includeJavaRuntime = true;
+ } else {
+ // there is a bootclasspath stated. By default, the
+ // includeJavaRuntime is false. If the user has stated a
+ // bootclasspath and said to include the java runtime, it's on
+ // their head!
+ }
+ classpath.append(getCompileClasspath());
+
+ // if the user has set JIKESPATH we should add the contents as well
+ String jikesPath = System.getProperty("jikes.class.path");
+ if (jikesPath != null) {
+ classpath.append(new Path(project, jikesPath));
+ }
+
+ if (extdirs != null && extdirs.size() > 0) {
+ cmd.createArgument().setValue("-extdirs");
+ cmd.createArgument().setPath(extdirs);
+ }
+
+ String exec = getJavac().getExecutable();
+ cmd.setExecutable(exec == null ? "jikes" : exec);
+
+ if (deprecation) {
+ cmd.createArgument().setValue("-deprecation");
+ }
+
+ if (destDir != null) {
+ cmd.createArgument().setValue("-d");
+ cmd.createArgument().setFile(destDir);
+ }
+
+ cmd.createArgument().setValue("-classpath");
+ cmd.createArgument().setPath(classpath);
+
+ if (encoding != null) {
+ cmd.createArgument().setValue("-encoding");
+ cmd.createArgument().setValue(encoding);
+ }
+ if (debug) {
+ String debugLevel = attributes.getDebugLevel();
+ if (debugLevel != null) {
+ cmd.createArgument().setValue("-g:" + debugLevel);
+ } else {
+ cmd.createArgument().setValue("-g");
+ }
+ } else {
+ cmd.createArgument().setValue("-g:none");
+ }
+ if (optimize) {
+ cmd.createArgument().setValue("-O");
+ }
+ if (verbose) {
+ cmd.createArgument().setValue("-verbose");
+ }
+ if (depend) {
+ cmd.createArgument().setValue("-depend");
+ }
+
+ if (target != null) {
+ cmd.createArgument().setValue("-target");
+ cmd.createArgument().setValue(target);
+ }
+
+ addPropertyParams(cmd);
+
+ if (attributes.getSource() != null) {
+ cmd.createArgument().setValue("-source");
+ String source = attributes.getSource();
+ if (source.equals("1.1") || source.equals("1.2")) {
+ // support for -source 1.1 and -source 1.2 has been
+ // added with JDK 1.4.2, Jikes doesn't like it
+ attributes.log("Jikes doesn't support '-source " + source
+ + "', will use '-source 1.3' instead");
+ cmd.createArgument().setValue("1.3");
+ } else {
+ cmd.createArgument().setValue(source);
+ }
+ }
+ addCurrentCompilerArgs(cmd);
+
+ int firstFileName = cmd.size();
+
+ Path boot = getBootClassPath();
+ if (boot.size() > 0) {
+ cmd.createArgument().setValue("-bootclasspath");
+ cmd.createArgument().setPath(boot);
+ }
+ logAndAddFilesToCompile(cmd);
+
+ return executeExternalCompile(cmd.getCommandline(), firstFileName) == 0;
+ }
+
+ private void addPropertyParams(Commandline cmd) {
+ /**
+ * TODO
+ * Perhaps we shouldn't use properties for these
+ * three options (emacs mode, warnings and pedantic),
+ * but include it in the javac directive?
+ */
+
+ /**
+ * Jikes has the nice feature to print error
+ * messages in a form readable by emacs, so
+ * that emacs can directly set the cursor
+ * to the place, where the error occurred.
+ */
+ String emacsProperty = project.getProperty("build.compiler.emacs");
+ if (emacsProperty != null && Project.toBoolean(emacsProperty)) {
+ cmd.createArgument().setValue("+E");
+ }
+
+ /**
+ * Jikes issues more warnings that javac, for
+ * example, when you have files in your classpath
+ * that don't exist. As this is often the case, these
+ * warning can be pretty annoying.
+ */
+ String warningsProperty = project.getProperty("build.compiler.warnings");
+ if (warningsProperty != null) {
+ attributes.log("!! the build.compiler.warnings property is " + "deprecated. !!",
+ Project.MSG_WARN);
+ attributes.log("!! Use the nowarn attribute instead. !!", Project.MSG_WARN);
+ if (!Project.toBoolean(warningsProperty)) {
+ cmd.createArgument().setValue("-nowarn");
+ }
+ }
+ if (attributes.getNowarn()) {
+ cmd.createArgument().setValue("-nowarn");
+ }
+
+ /**
+ * Jikes can issue pedantic warnings.
+ */
+ String pedanticProperty = project.getProperty("build.compiler.pedantic");
+ if (pedanticProperty != null && Project.toBoolean(pedanticProperty)) {
+ cmd.createArgument().setValue("+P");
+ }
+
+ /**
+ * Jikes supports something it calls "full dependency
+ * checking", see the jikes documentation for differences
+ * between -depend and +F.
+ */
+ String fullDependProperty = project.getProperty("build.compiler.fulldepend");
+ if (fullDependProperty != null
+ && Project.toBoolean(fullDependProperty)) {
+ cmd.createArgument().setValue("+F");
+ }
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/compilers/Jvc.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/compilers/Jvc.java
new file mode 100644
index 00000000..85ec4793
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/compilers/Jvc.java
@@ -0,0 +1,116 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.compilers;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.Commandline;
+import org.apache.tools.ant.types.Path;
+
+/**
+ * The implementation of the jvc compiler from microsoft.
+ * This is primarily a cut-and-paste from the original javac task before it
+ * was refactored.
+ *
+ * @since Ant 1.3
+ */
+public class Jvc extends DefaultCompilerAdapter {
+
+ /**
+ * Run the compilation.
+ * @return true if the compiler ran with a zero exit result (ok)
+ * @exception BuildException if the compilation has problems.
+ */
+ public boolean execute() throws BuildException {
+ attributes.log("Using jvc compiler", Project.MSG_VERBOSE);
+
+ Path classpath = new Path(project);
+
+ // jvc doesn't support bootclasspath dir (-bootclasspath)
+ // so we'll emulate it for compatibility and convenience.
+ Path p = getBootClassPath();
+ if (p.size() > 0) {
+ classpath.append(p);
+ }
+
+ if (includeJavaRuntime) {
+ // jvc doesn't support an extension dir (-extdir)
+ // so we'll emulate it for compatibility and convenience.
+ classpath.addExtdirs(extdirs);
+ }
+
+ classpath.append(getCompileClasspath());
+
+ // jvc has no option for source-path so we
+ // will add it to classpath.
+ if (compileSourcepath != null) {
+ classpath.append(compileSourcepath);
+ } else {
+ classpath.append(src);
+ }
+
+ Commandline cmd = new Commandline();
+ String exec = getJavac().getExecutable();
+ cmd.setExecutable(exec == null ? "jvc" : exec);
+
+ if (destDir != null) {
+ cmd.createArgument().setValue("/d");
+ cmd.createArgument().setFile(destDir);
+ }
+
+ // Add the Classpath before the "internal" one.
+ cmd.createArgument().setValue("/cp:p");
+ cmd.createArgument().setPath(classpath);
+
+ boolean msExtensions = true;
+ String mse = getProject().getProperty("build.compiler.jvc.extensions");
+ if (mse != null) {
+ msExtensions = Project.toBoolean(mse);
+ }
+
+ if (msExtensions) {
+ // Enable MS-Extensions and ...
+ cmd.createArgument().setValue("/x-");
+ // ... do not display a Message about this.
+ cmd.createArgument().setValue("/nomessage");
+ }
+
+ // Do not display Logo
+ cmd.createArgument().setValue("/nologo");
+
+ if (debug) {
+ cmd.createArgument().setValue("/g");
+ }
+ if (optimize) {
+ cmd.createArgument().setValue("/O");
+ }
+ if (verbose) {
+ cmd.createArgument().setValue("/verbose");
+ }
+
+ addCurrentCompilerArgs(cmd);
+
+ int firstFileName = cmd.size();
+ logAndAddFilesToCompile(cmd);
+
+ return
+ executeExternalCompile(cmd.getCommandline(), firstFileName,
+ false) == 0;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/compilers/Kjc.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/compilers/Kjc.java
new file mode 100644
index 00000000..68b5ba18
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/compilers/Kjc.java
@@ -0,0 +1,119 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.compilers;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.ExecuteJava;
+import org.apache.tools.ant.types.Commandline;
+import org.apache.tools.ant.types.Path;
+
+/**
+ * The implementation of the Java compiler for KJC.
+ * This is primarily a cut-and-paste from Jikes.java and
+ * DefaultCompilerAdapter.
+ *
+ * @since Ant 1.4
+ */
+public class Kjc extends DefaultCompilerAdapter {
+
+ /**
+ * Run the compilation.
+ * @return true if the compilation succeeded
+ * @exception BuildException if the compilation has problems.
+ */
+ public boolean execute() throws BuildException {
+ attributes.log("Using kjc compiler", Project.MSG_VERBOSE);
+ Commandline cmd = setupKjcCommand();
+ cmd.setExecutable("at.dms.kjc.Main");
+ ExecuteJava ej = new ExecuteJava();
+ ej.setJavaCommand(cmd);
+ return ej.fork(getJavac()) == 0;
+ }
+
+ /**
+ * setup kjc command arguments.
+ * @return the command line
+ */
+ protected Commandline setupKjcCommand() {
+ Commandline cmd = new Commandline();
+
+ // generate classpath, because kjc doesn't support sourcepath.
+ Path classpath = getCompileClasspath();
+
+ if (deprecation) {
+ cmd.createArgument().setValue("-deprecation");
+ }
+
+ if (destDir != null) {
+ cmd.createArgument().setValue("-d");
+ cmd.createArgument().setFile(destDir);
+ }
+
+ // generate the clsspath
+ cmd.createArgument().setValue("-classpath");
+
+ Path cp = new Path(project);
+
+ // kjc don't have bootclasspath option.
+ Path p = getBootClassPath();
+ if (p.size() > 0) {
+ cp.append(p);
+ }
+
+ if (extdirs != null) {
+ cp.addExtdirs(extdirs);
+ }
+
+ cp.append(classpath);
+ if (compileSourcepath != null) {
+ cp.append(compileSourcepath);
+ } else {
+ cp.append(src);
+ }
+
+ cmd.createArgument().setPath(cp);
+
+ // kjc-1.5A doesn't support -encoding option now.
+ // but it will be supported near the feature.
+ if (encoding != null) {
+ cmd.createArgument().setValue("-encoding");
+ cmd.createArgument().setValue(encoding);
+ }
+
+ if (debug) {
+ cmd.createArgument().setValue("-g");
+ }
+
+ if (optimize) {
+ cmd.createArgument().setValue("-O2");
+ }
+
+ if (verbose) {
+ cmd.createArgument().setValue("-verbose");
+ }
+
+ addCurrentCompilerArgs(cmd);
+
+ logAndAddFilesToCompile(cmd);
+ return cmd;
+ }
+}
+
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/compilers/Sj.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/compilers/Sj.java
new file mode 100644
index 00000000..0dcc0e4c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/compilers/Sj.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.compilers;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.Commandline;
+
+/**
+ * The implementation of the sj compiler.
+ * Uses the defaults for DefaultCompilerAdapter
+ *
+ * @since Ant 1.4
+ */
+public class Sj extends DefaultCompilerAdapter {
+
+ /**
+ * Performs a compile using the sj compiler from Symantec.
+ * @return true if the compilation succeeded
+ * @throws BuildException on error
+ */
+ public boolean execute() throws BuildException {
+ attributes.log("Using symantec java compiler", Project.MSG_VERBOSE);
+
+ Commandline cmd = setupJavacCommand();
+ String exec = getJavac().getExecutable();
+ cmd.setExecutable(exec == null ? "sj" : exec);
+
+ int firstFileName = cmd.size() - compileList.length;
+
+ return
+ executeExternalCompile(cmd.getCommandline(), firstFileName) == 0;
+ }
+
+ /**
+ * Returns null since sj either has -g for debug=true or no
+ * argument at all.
+ * @return null.
+ * @since Ant 1.6.3
+ */
+ protected String getNoDebugArgument() {
+ return null;
+ }
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/And.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/And.java
new file mode 100644
index 00000000..91b34c82
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/And.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.condition;
+
+import java.util.Enumeration;
+
+import org.apache.tools.ant.BuildException;
+
+/**
+ * &lt;and&gt; condition container.
+ *
+ * <p>Iterates over all conditions and returns false as soon as one
+ * evaluates to false.</p>
+ *
+ * @since Ant 1.4
+ */
+public class And extends ConditionBase implements Condition {
+
+ /**
+ * @return true if all the contained conditions evaluates to true
+ * @exception BuildException if an error occurs
+ */
+ public boolean eval() throws BuildException {
+ Enumeration e = getConditions();
+ while (e.hasMoreElements()) {
+ Condition c = (Condition) e.nextElement();
+ if (!c.eval()) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/AntVersion.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/AntVersion.java
new file mode 100644
index 00000000..aadf5a7e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/AntVersion.java
@@ -0,0 +1,171 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.condition;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.util.DeweyDecimal;
+
+/**
+ * An Ant version condition.
+ * @since Ant 1.7
+ */
+public class AntVersion extends Task implements Condition {
+
+ private String atLeast = null;
+ private String exactly = null;
+ private String propertyname = null;
+
+ /**
+ * Run as a task.
+ * @throws BuildException if an error occurs.
+ */
+ public void execute() throws BuildException {
+ if (propertyname == null) {
+ throw new BuildException("'property' must be set.");
+ }
+ if (atLeast != null || exactly != null) {
+ // If condition values are set, evaluate the condition
+ if (eval()) {
+ getProject().setNewProperty(propertyname, getVersion().toString());
+ }
+ } else {
+ // Raw task
+ getProject().setNewProperty(propertyname, getVersion().toString());
+ }
+ }
+
+ /**
+ * Evaluate the condition.
+ * @return true if the condition is true.
+ * @throws BuildException if an error occurs.
+ */
+ public boolean eval() throws BuildException {
+ validate();
+ DeweyDecimal actual = getVersion();
+ if (null != atLeast) {
+ return actual.isGreaterThanOrEqual(new DeweyDecimal(atLeast));
+ }
+ if (null != exactly) {
+ return actual.isEqual(new DeweyDecimal(exactly));
+ }
+ //default
+ return false;
+ }
+
+ private void validate() throws BuildException {
+ if (atLeast != null && exactly != null) {
+ throw new BuildException("Only one of atleast or exactly may be set.");
+ }
+ if (null == atLeast && null == exactly) {
+ throw new BuildException("One of atleast or exactly must be set.");
+ }
+ if (atLeast != null) {
+ try {
+ new DeweyDecimal(atLeast);
+ } catch (NumberFormatException e) {
+ throw new BuildException(
+ "The 'atleast' attribute is not a Dewey Decimal eg 1.1.0 : "
+ + atLeast);
+ }
+ } else {
+ try {
+ new DeweyDecimal(exactly);
+ } catch (NumberFormatException e) {
+ throw new BuildException(
+ "The 'exactly' attribute is not a Dewey Decimal eg 1.1.0 : "
+ + exactly);
+ }
+ }
+ }
+
+ private DeweyDecimal getVersion() {
+ Project p = new Project();
+ p.init();
+ char[] versionString = p.getProperty("ant.version").toCharArray();
+ StringBuffer sb = new StringBuffer();
+ boolean foundFirstDigit = false;
+ for (int i = 0; i < versionString.length; i++) {
+ if (Character.isDigit(versionString[i])) {
+ sb.append(versionString[i]);
+ foundFirstDigit = true;
+ }
+ if (versionString[i] == '.' && foundFirstDigit) {
+ sb.append(versionString[i]);
+ }
+ if (Character.isLetter(versionString[i]) && foundFirstDigit) {
+ break;
+ }
+ }
+ return new DeweyDecimal(sb.toString());
+ }
+
+ /**
+ * Get the atleast attribute.
+ * @return the atleast attribute.
+ */
+ public String getAtLeast() {
+ return atLeast;
+ }
+
+ /**
+ * Set the atleast attribute.
+ * This is of the form major.minor.point.
+ * For example 1.7.0.
+ * @param atLeast the version to check against.
+ */
+ public void setAtLeast(String atLeast) {
+ this.atLeast = atLeast;
+ }
+
+ /**
+ * Get the exactly attribute.
+ * @return the exactly attribute.
+ */
+ public String getExactly() {
+ return exactly;
+ }
+
+ /**
+ * Set the exactly attribute.
+ * This is of the form major.minor.point.
+ * For example 1.7.0.
+ * @param exactly the version to check against.
+ */
+ public void setExactly(String exactly) {
+ this.exactly = exactly;
+ }
+
+ /**
+ * Get the name of the property to hold the ant version.
+ * @return the name of the property.
+ */
+ public String getProperty() {
+ return propertyname;
+ }
+
+ /**
+ * Set the name of the property to hold the ant version.
+ * @param propertyname the name of the property.
+ */
+ public void setProperty(String propertyname) {
+ this.propertyname = propertyname;
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/Condition.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/Condition.java
new file mode 100644
index 00000000..62adbf36
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/Condition.java
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.condition;
+
+import org.apache.tools.ant.BuildException;
+
+/**
+ * Interface for conditions to use inside the &lt;condition&gt; task.
+ *
+ */
+public interface Condition {
+ /**
+ * Is this condition true?
+ * @return true if the condition is true
+ * @exception BuildException if an error occurs
+ */
+ boolean eval() throws BuildException;
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/ConditionBase.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/ConditionBase.java
new file mode 100644
index 00000000..d057b46d
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/ConditionBase.java
@@ -0,0 +1,281 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.condition;
+
+import java.util.Enumeration;
+import java.util.Vector;
+
+import org.apache.tools.ant.ProjectComponent;
+import org.apache.tools.ant.taskdefs.Available;
+import org.apache.tools.ant.taskdefs.Checksum;
+import org.apache.tools.ant.taskdefs.UpToDate;
+
+/**
+ * Baseclass for the &lt;condition&gt; task as well as several
+ * conditions - ensures that the types of conditions inside the task
+ * and the "container" conditions are in sync.
+ *
+ * @since Ant 1.4
+ */
+public abstract class ConditionBase extends ProjectComponent {
+
+ /**
+ * name of the component
+ */
+ private String taskName = "condition";
+
+ /**
+ *
+ */
+ private Vector conditions = new Vector();
+
+ /**
+ * Simple constructor.
+ */
+ protected ConditionBase() {
+ taskName = "component";
+ }
+
+ /**
+ * Constructor that takes the name of the task in the task name.
+ * @param taskName the name of the task.
+ * @since Ant 1.7
+ */
+ protected ConditionBase(String taskName) {
+ this.taskName = taskName;
+ }
+
+ /**
+ * Count the conditions.
+ *
+ * @return the number of conditions in the container
+ * @since 1.1
+ */
+ protected int countConditions() {
+ return conditions.size();
+ }
+
+ /**
+ * Iterate through all conditions.
+ *
+ * @return an enumeration to use for iteration
+ * @since 1.1
+ */
+ protected final Enumeration getConditions() {
+ return conditions.elements();
+ }
+
+ /**
+ * Sets the name to use in logging messages.
+ *
+ * @param name The name to use in logging messages.
+ * Should not be <code>null</code>.
+ * @since Ant 1.7
+ */
+ public void setTaskName(String name) {
+ this.taskName = name;
+ }
+
+ /**
+ * Returns the name to use in logging messages.
+ *
+ * @return the name to use in logging messages.
+ * @since Ant 1.7
+ */
+ public String getTaskName() {
+ return taskName;
+ }
+
+ /**
+ * Add an &lt;available&gt; condition.
+ * @param a an available condition
+ * @since 1.1
+ */
+ public void addAvailable(Available a) {
+ conditions.addElement(a);
+ }
+
+ /**
+ * Add an &lt;checksum&gt; condition.
+ *
+ * @param c a Checksum condition
+ * @since 1.4, Ant 1.5
+ */
+ public void addChecksum(Checksum c) {
+ conditions.addElement(c);
+ }
+
+ /**
+ * Add an &lt;uptodate&gt; condition.
+ *
+ * @param u an UpToDate condition
+ * @since 1.1
+ */
+ public void addUptodate(UpToDate u) {
+ conditions.addElement(u);
+ }
+
+ /**
+ * Add an &lt;not&gt; condition "container".
+ *
+ * @param n a Not condition
+ * @since 1.1
+ */
+ public void addNot(Not n) {
+ conditions.addElement(n);
+ }
+
+ /**
+ * Add an &lt;and&gt; condition "container".
+ *
+ * @param a an And condition
+ * @since 1.1
+ */
+ public void addAnd(And a) {
+ conditions.addElement(a);
+ }
+
+ /**
+ * Add an &lt;or&gt; condition "container".
+ *
+ * @param o an Or condition
+ * @since 1.1
+ */
+ public void addOr(Or o) {
+ conditions.addElement(o);
+ }
+
+ /**
+ * Add an &lt;equals&gt; condition.
+ *
+ * @param e an Equals condition
+ * @since 1.1
+ */
+ public void addEquals(Equals e) {
+ conditions.addElement(e);
+ }
+
+ /**
+ * Add an &lt;os&gt; condition.
+ *
+ * @param o an Os condition
+ * @since 1.1
+ */
+ public void addOs(Os o) {
+ conditions.addElement(o);
+ }
+
+ /**
+ * Add an &lt;isset&gt; condition.
+ *
+ * @param i an IsSet condition
+ * @since Ant 1.5
+ */
+ public void addIsSet(IsSet i) {
+ conditions.addElement(i);
+ }
+
+ /**
+ * Add an &lt;http&gt; condition.
+ *
+ * @param h an Http condition
+ * @since Ant 1.5
+ */
+ public void addHttp(Http h) {
+ conditions.addElement(h);
+ }
+
+ /**
+ * Add a &lt;socket&gt; condition.
+ *
+ * @param s a Socket condition
+ * @since Ant 1.5
+ */
+ public void addSocket(Socket s) {
+ conditions.addElement(s);
+ }
+
+ /**
+ * Add a &lt;filesmatch&gt; condition.
+ *
+ * @param test a FilesMatch condition
+ * @since Ant 1.5
+ */
+ public void addFilesMatch(FilesMatch test) {
+ conditions.addElement(test);
+ }
+
+ /**
+ * Add a &lt;contains&gt; condition.
+ *
+ * @param test a Contains condition
+ * @since Ant 1.5
+ */
+ public void addContains(Contains test) {
+ conditions.addElement(test);
+ }
+
+ /**
+ * Add a &lt;istrue&gt; condition.
+ *
+ * @param test an IsTrue condition
+ * @since Ant 1.5
+ */
+ public void addIsTrue(IsTrue test) {
+ conditions.addElement(test);
+ }
+
+ /**
+ * Add a &lt;isfalse&gt; condition.
+ *
+ * @param test an IsFalse condition
+ * @since Ant 1.5
+ */
+ public void addIsFalse(IsFalse test) {
+ conditions.addElement(test);
+ }
+
+ /**
+ * Add an &lt;isreference&gt; condition.
+ *
+ * @param i an IsReference condition
+ * @since Ant 1.6
+ */
+ public void addIsReference(IsReference i) {
+ conditions.addElement(i);
+ }
+
+ /**
+ * Add an &lt;isfileselected&gt; condition.
+ * @param test the condition
+ */
+ public void addIsFileSelected(IsFileSelected test) {
+ conditions.addElement(test);
+ }
+
+ /**
+ * Add an arbitrary condition
+ * @param c a condition
+ * @since Ant 1.6
+ */
+ public void add(Condition c) {
+ conditions.addElement(c);
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/Contains.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/Contains.java
new file mode 100644
index 00000000..8830a39d
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/Contains.java
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.condition;
+
+import org.apache.tools.ant.BuildException;
+
+/**
+ * Is one string part of another string?
+ *
+ *
+ * @since Ant 1.5
+ */
+public class Contains implements Condition {
+
+ private String string, subString;
+ private boolean caseSensitive = true;
+
+ /**
+ * The string to search in.
+ * @param string the string to search in
+ * @since Ant 1.5
+ */
+ public void setString(String string) {
+ this.string = string;
+ }
+
+ /**
+ * The string to search for.
+ * @param subString the string to search for
+ * @since Ant 1.5
+ */
+ public void setSubstring(String subString) {
+ this.subString = subString;
+ }
+
+ /**
+ * Whether to search ignoring case or not.
+ * @param b if false, ignore case
+ * @since Ant 1.5
+ */
+ public void setCasesensitive(boolean b) {
+ caseSensitive = b;
+ }
+
+ /**
+ * @since Ant 1.5
+ * @return true if the substring is within the string
+ * @exception BuildException if the attributes are not set correctly
+ */
+ public boolean eval() throws BuildException {
+ if (string == null || subString == null) {
+ throw new BuildException("both string and substring are required "
+ + "in contains");
+ }
+
+ return caseSensitive
+ ? string.indexOf(subString) > -1
+ : string.toLowerCase().indexOf(subString.toLowerCase()) > -1;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/Equals.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/Equals.java
new file mode 100644
index 00000000..2d930f98
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/Equals.java
@@ -0,0 +1,148 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.condition;
+
+import org.apache.tools.ant.BuildException;
+
+/**
+ * Simple comparison condition.
+ *
+ * @since Ant 1.4
+ */
+public class Equals implements Condition {
+ private static final int REQUIRED = 1 | 2;
+
+ private Object arg1, arg2;
+ private boolean trim = false;
+ private boolean caseSensitive = true;
+ private int args;
+ private boolean forcestring = false;
+
+ /**
+ * Set the first argument
+ * @param arg1 the first argument.
+ * @since Ant 1.8
+ */
+ public void setArg1(Object arg1) {
+ if (arg1 instanceof String) {
+ setArg1((String) arg1);
+ } else {
+ setArg1Internal(arg1);
+ }
+ }
+
+ /**
+ * Set the first string
+ *
+ * @param a1 the first string
+ */
+ public void setArg1(String a1) {
+ setArg1Internal(a1);
+ }
+
+ private void setArg1Internal(Object arg1) {
+ this.arg1 = arg1;
+ args |= 1;
+ }
+
+ /**
+ * Set the second argument
+ * @param arg2 the second argument.
+ * @since Ant 1.8
+ */
+ public void setArg2(Object arg2) {
+ if (arg2 instanceof String) {
+ setArg2((String) arg2);
+ } else {
+ setArg2Internal(arg2);
+ }
+ }
+
+ /**
+ * Set the second string
+ *
+ * @param a2 the second string
+ */
+ public void setArg2(String a2) {
+ setArg2Internal(a2);
+ }
+
+ private void setArg2Internal(Object arg2) {
+ this.arg2 = arg2;
+ args |= 2;
+ }
+
+ /**
+ * Should we want to trim the arguments before comparing them?
+ * @param b if true trim the arguments
+ * @since Ant 1.5
+ */
+ public void setTrim(boolean b) {
+ trim = b;
+ }
+
+ /**
+ * Should the comparison be case sensitive?
+ * @param b if true use a case sensitive comparison (this is the
+ * default)
+ * @since Ant 1.5
+ */
+ public void setCasesensitive(boolean b) {
+ caseSensitive = b;
+ }
+
+ /**
+ * Set whether to force string comparisons for non-equal, non-string objects.
+ * This allows object properties (legal in Ant 1.8.x+) to be compared as strings.
+ * @param forcestring value to set
+ * @since Ant 1.8.1
+ */
+ public void setForcestring(boolean forcestring) {
+ this.forcestring = forcestring;
+ }
+
+ /**
+ * @return true if the two strings are equal
+ * @exception BuildException if the attributes are not set correctly
+ */
+ public boolean eval() throws BuildException {
+ if ((args & REQUIRED) != REQUIRED) {
+ throw new BuildException("both arg1 and arg2 are required in equals");
+ }
+ if (arg1 == arg2 || arg1 != null && arg1.equals(arg2)) {
+ return true;
+ }
+ if (forcestring) {
+ arg1 = arg1 == null || arg1 instanceof String ? arg1 : arg1.toString();
+ arg2 = arg2 == null || arg2 instanceof String ? arg2 : arg2.toString();
+ }
+ if (arg1 instanceof String && trim) {
+ arg1 = ((String) arg1).trim();
+ }
+ if (arg2 instanceof String && trim) {
+ arg2 = ((String) arg2).trim();
+ }
+ if (arg1 instanceof String && arg2 instanceof String) {
+ String s1 = (String) arg1;
+ String s2 = (String) arg2;
+ return caseSensitive ? s1.equals(s2) : s1.equalsIgnoreCase(s2);
+ }
+ return false;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/FilesMatch.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/FilesMatch.java
new file mode 100644
index 00000000..5e99398f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/FilesMatch.java
@@ -0,0 +1,101 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+ package org.apache.tools.ant.taskdefs.condition;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.util.FileUtils;
+
+/**
+ * Compares two files for equality based on size and
+ * content. Timestamps are not at all looked at.
+ *
+ * @since Ant 1.5
+ */
+
+public class FilesMatch implements Condition {
+
+ /**
+ * Helper that provides the file comparison method.
+ */
+ private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+
+ /**
+ * files to compare
+ */
+ private File file1, file2;
+
+ private boolean textfile = false;
+
+
+ /**
+ * Sets the File1 attribute
+ *
+ * @param file1 The new File1 value
+ */
+ public void setFile1(File file1) {
+ this.file1 = file1;
+ }
+
+
+ /**
+ * Sets the File2 attribute
+ *
+ * @param file2 The new File2 value
+ */
+ public void setFile2(File file2) {
+ this.file2 = file2;
+ }
+
+ /**
+ * Set whether to ignore line endings when comparing files.
+ * @param textfile whether to ignore line endings.
+ */
+ public void setTextfile(boolean textfile) {
+ this.textfile = textfile;
+ }
+
+ /**
+ * comparison method of the interface
+ *
+ * @return true if the files are equal
+ * @exception BuildException if it all went pear-shaped
+ */
+ public boolean eval()
+ throws BuildException {
+
+ //validate
+ if (file1 == null || file2 == null) {
+ throw new BuildException("both file1 and file2 are required in "
+ + "filesmatch");
+ }
+
+ //#now match the files
+ boolean matches = false;
+ try {
+ matches = FILE_UTILS.contentEquals(file1, file2, textfile);
+ } catch (IOException ioe) {
+ throw new BuildException("when comparing files: "
+ + ioe.getMessage(), ioe);
+ }
+ return matches;
+ }
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/HasFreeSpace.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/HasFreeSpace.java
new file mode 100644
index 00000000..420c1894
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/HasFreeSpace.java
@@ -0,0 +1,101 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.condition;
+
+import java.io.File;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.util.JavaEnvUtils;
+import org.apache.tools.ant.util.ReflectWrapper;
+import org.apache.tools.ant.util.StringUtils;
+
+/**
+ * &lt;hasfreespace&gt;
+ * <p>Condition returns true if selected partition
+ * has the requested space, false otherwise.</p>
+ * @since Ant 1.7
+ */
+public class HasFreeSpace implements Condition {
+
+ private String partition;
+ private String needed;
+
+ /**
+ * Evaluate the condition.
+ * @return true if there enough free space.
+ * @throws BuildException if there is a problem.
+ */
+ public boolean eval() throws BuildException {
+ validate();
+ try {
+ if (JavaEnvUtils.isAtLeastJavaVersion("1.6")) {
+ //reflection to avoid bootstrap/build problems
+ File fs = new File(partition);
+ ReflectWrapper w = new ReflectWrapper(fs);
+ long free = ((Long) w.invoke("getFreeSpace")).longValue();
+ return free >= StringUtils.parseHumanSizes(needed);
+ } else {
+ throw new BuildException("HasFreeSpace condition not supported on Java5 or less.");
+ }
+ } catch (Exception e) {
+ throw new BuildException(e);
+ }
+ }
+
+ private void validate() throws BuildException {
+ if (null == partition) {
+ throw new BuildException("Please set the partition attribute.");
+ }
+ if (null == needed) {
+ throw new BuildException("Please set the needed attribute.");
+ }
+ }
+
+ /**
+ * The partition/device to check
+ * @return the partition.
+ */
+ public String getPartition() {
+ return partition;
+ }
+
+ /**
+ * Set the partition name.
+ * @param partition the name to use.
+ */
+ public void setPartition(String partition) {
+ this.partition = partition;
+ }
+
+ /**
+ * The amount of free space required
+ * @return the amount required
+ */
+ public String getNeeded() {
+ return needed;
+ }
+
+ /**
+ * Set the amount of space required.
+ * @param needed the amount required.
+ */
+ public void setNeeded(String needed) {
+ this.needed = needed;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/HasMethod.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/HasMethod.java
new file mode 100644
index 00000000..002af7a7
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/HasMethod.java
@@ -0,0 +1,192 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.condition;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+
+import org.apache.tools.ant.AntClassLoader;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.ProjectComponent;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.types.Reference;
+
+/**
+ * test for a method
+ */
+public class HasMethod extends ProjectComponent implements Condition {
+ private String classname;
+ private String method;
+ private String field;
+ private Path classpath;
+ private AntClassLoader loader;
+ private boolean ignoreSystemClasses = false;
+
+
+ /**
+ * Set the classpath to be used when searching for classes and resources.
+ *
+ * @param classpath an Ant Path object containing the search path.
+ */
+ public void setClasspath(Path classpath) {
+ createClasspath().append(classpath);
+ }
+
+ /**
+ * Classpath to be used when searching for classes and resources.
+ *
+ * @return an empty Path instance to be configured by Ant.
+ */
+ public Path createClasspath() {
+ if (this.classpath == null) {
+ this.classpath = new Path(getProject());
+ }
+ return this.classpath.createPath();
+ }
+
+ /**
+ * Set the classpath by reference.
+ *
+ * @param r a Reference to a Path instance to be used as the classpath
+ * value.
+ */
+ public void setClasspathRef(Reference r) {
+ createClasspath().setRefid(r);
+ }
+
+ /**
+ * Set the classname attribute.
+ * @param classname the name of the class to check.
+ */
+ public void setClassname(String classname) {
+ this.classname = classname;
+ }
+
+ /**
+ * Set the name of the method.
+ * @param method the name of the method to check.
+ */
+ public void setMethod(String method) {
+ this.method = method;
+ }
+
+ /**
+ * Set the name of the field.
+ * @param field the name of the field to check.
+ */
+ public void setField(String field) {
+ this.field = field;
+ }
+
+ /**
+ * Set whether to ignore system classes when looking for the class.
+ * @param ignoreSystemClasses a <code>boolean</code> value.
+ */
+ public void setIgnoreSystemClasses(boolean ignoreSystemClasses) {
+ this.ignoreSystemClasses = ignoreSystemClasses;
+ }
+
+ /**
+ * Check if a given class can be loaded.
+ */
+ private Class loadClass(String classname) {
+ try {
+ if (ignoreSystemClasses) {
+ loader = getProject().createClassLoader(classpath);
+ loader.setParentFirst(false);
+ loader.addJavaLibraries();
+ try {
+ return loader.findClass(classname);
+ } catch (SecurityException se) {
+ // class found but restricted name
+ throw new BuildException("class \"" + classname
+ + "\" was found but a"
+ + " SecurityException has been"
+ + " raised while loading it",
+ se);
+ }
+ } else if (loader != null) {
+ // How do we ever get here?
+ return loader.loadClass(classname);
+ } else {
+ ClassLoader l = this.getClass().getClassLoader();
+ // Can return null to represent the bootstrap class loader.
+ // see API docs of Class.getClassLoader.
+ if (l != null) {
+ return Class.forName(classname, true, l);
+ } else {
+ return Class.forName(classname);
+ }
+ }
+ } catch (ClassNotFoundException e) {
+ throw new BuildException("class \"" + classname
+ + "\" was not found");
+ } catch (NoClassDefFoundError e) {
+ throw new BuildException("Could not load dependent class \""
+ + e.getMessage()
+ + "\" for class \"" + classname + "\"");
+ }
+ }
+
+
+ /** {@inheritDoc}. */
+ public boolean eval() throws BuildException {
+ if (classname == null) {
+ throw new BuildException("No classname defined");
+ }
+ ClassLoader preLoadClass = loader;
+ try {
+ Class clazz = loadClass(classname);
+ if (method != null) {
+ return isMethodFound(clazz);
+ }
+ if (field != null) {
+ return isFieldFound(clazz);
+ }
+ throw new BuildException("Neither method nor field defined");
+ } finally {
+ if (preLoadClass != loader && loader != null) {
+ loader.cleanup();
+ loader = null;
+ }
+ }
+ }
+
+ private boolean isFieldFound(Class clazz) {
+ Field[] fields = clazz.getDeclaredFields();
+ for (int i = 0; i < fields.length; i++) {
+ Field fieldEntry = fields[i];
+ if (fieldEntry.getName().equals(field)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private boolean isMethodFound(Class clazz) {
+ Method[] methods = clazz.getDeclaredMethods();
+ for (int i = 0; i < methods.length; i++) {
+ Method methodEntry = methods[i];
+ if (methodEntry.getName().equals(method)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/Http.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/Http.java
new file mode 100644
index 00000000..1dc94204
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/Http.java
@@ -0,0 +1,117 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.condition;
+
+import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.Locale;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.ProjectComponent;
+
+/**
+ * Condition to wait for a HTTP request to succeed. Its attribute(s) are:
+ * url - the URL of the request.
+ * errorsBeginAt - number at which errors begin at; default=400.
+ * requestMethod - HTTP request method to use; GET, HEAD, etc. default=GET
+ * @since Ant 1.5
+ */
+public class Http extends ProjectComponent implements Condition {
+ private static final int ERROR_BEGINS = 400;
+ private static final String DEFAULT_REQUEST_METHOD = "GET";
+
+ private String spec = null;
+ private String requestMethod = DEFAULT_REQUEST_METHOD;
+
+
+ /**
+ * Set the url attribute
+ * @param url the url of the request
+ */
+ public void setUrl(String url) {
+ spec = url;
+ }
+
+ private int errorsBeginAt = ERROR_BEGINS;
+
+ /**
+ * Set the errorsBeginAt attribute
+ * @param errorsBeginAt number at which errors begin at, default is
+ * 400
+ */
+ public void setErrorsBeginAt(int errorsBeginAt) {
+ this.errorsBeginAt = errorsBeginAt;
+ }
+
+ /**
+ * Sets the method to be used when issuing the HTTP request.
+ *
+ * @param method The HTTP request method to use. Valid values are
+ * the same as those accepted by the
+ * HttpURLConnection.setRequestMetho d() method,
+ * such as "GET", "HEAD", "TRACE", etc. The default
+ * if not specified is "GET".
+ *
+ * @see java.net.HttpURLConnection#setRequestMethod
+ * @since Ant 1.8.0
+ */
+ public void setRequestMethod(String method) {
+ this.requestMethod = method == null ? DEFAULT_REQUEST_METHOD
+ : method.toUpperCase(Locale.ENGLISH);
+ }
+
+ /**
+ * @return true if the HTTP request succeeds
+ * @exception BuildException if an error occurs
+ */
+ public boolean eval() throws BuildException {
+ if (spec == null) {
+ throw new BuildException("No url specified in http condition");
+ }
+ log("Checking for " + spec, Project.MSG_VERBOSE);
+ try {
+ URL url = new URL(spec);
+ try {
+ URLConnection conn = url.openConnection();
+ if (conn instanceof HttpURLConnection) {
+ HttpURLConnection http = (HttpURLConnection) conn;
+ http.setRequestMethod(requestMethod);
+ int code = http.getResponseCode();
+ log("Result code for " + spec + " was " + code,
+ Project.MSG_VERBOSE);
+ if (code > 0 && code < errorsBeginAt) {
+ return true;
+ }
+ return false;
+ }
+ } catch (java.net.ProtocolException pe) {
+ throw new BuildException("Invalid HTTP protocol: "
+ + requestMethod, pe);
+ } catch (java.io.IOException e) {
+ return false;
+ }
+ } catch (MalformedURLException e) {
+ throw new BuildException("Badly formed URL: " + spec, e);
+ }
+ return true;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/IsFailure.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/IsFailure.java
new file mode 100644
index 00000000..b0ffb9ec
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/IsFailure.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.condition;
+
+import org.apache.tools.ant.taskdefs.Execute;
+
+/**
+ * Condition to test a return-code for failure.
+ * @since Ant 1.7
+ */
+public class IsFailure implements Condition {
+ private int code;
+
+ /**
+ * Set the return code to check.
+ * @param c the return code.
+ */
+ public void setCode(int c) {
+ code = c;
+ }
+
+ /**
+ * Get the return code that will be checked by this IsFailure condition.
+ * @return return code as int.
+ */
+ public int getCode() {
+ return code;
+ }
+
+ /**
+ * Fulfill the condition interface.
+ * @return the result of evaluating the specified return code.
+ */
+ public boolean eval() {
+ return Execute.isFailure(code);
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/IsFalse.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/IsFalse.java
new file mode 100644
index 00000000..0b3e69b4
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/IsFalse.java
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.condition;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.ProjectComponent;
+
+/**
+ * Condition that tests whether a given string evals to false
+ *
+ * @since Ant 1.5
+ */
+public class IsFalse extends ProjectComponent implements Condition {
+ /**
+ * what we eval
+ */
+ private Boolean value = null;
+
+ /**
+ * set the value to be tested; let ant eval it to true/false
+ * @param value the value to test
+ */
+ public void setValue(boolean value) {
+ this.value = value ? Boolean.TRUE : Boolean.FALSE;
+ }
+
+ /**
+ * @return the inverted value;
+ * @throws BuildException if someone forgot to spec a value
+ */
+ public boolean eval() throws BuildException {
+ if (value == null) {
+ throw new BuildException("Nothing to test for falsehood");
+ }
+ return !value.booleanValue();
+ }
+
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/IsFileSelected.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/IsFileSelected.java
new file mode 100644
index 00000000..efdb6648
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/IsFileSelected.java
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.condition;
+import java.io.File;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.types.selectors.AbstractSelectorContainer;
+import org.apache.tools.ant.types.selectors.FileSelector;
+import org.apache.tools.ant.util.FileUtils;
+
+/**
+ * This is a condition that checks to see if a file passes an embedded selector.
+ */
+public class IsFileSelected extends AbstractSelectorContainer implements Condition {
+
+ private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+
+ private File file;
+ private File baseDir;
+
+ /**
+ * The file to check.
+ * @param file the file to check if if passes the embedded selector.
+ */
+ public void setFile(File file) {
+ this.file = file;
+ }
+
+ /**
+ * The base directory to use.
+ * @param baseDir the base directory to use, if null use the project's
+ * basedir.
+ */
+ public void setBaseDir(File baseDir) {
+ this.baseDir = baseDir;
+ }
+
+ /**
+ * validate the parameters.
+ */
+ public void validate() {
+ if (selectorCount() != 1) {
+ throw new BuildException("Only one selector allowed");
+ }
+ super.validate();
+ }
+
+ /**
+ * Evaluate the selector with the file.
+ * @return true if the file is selected by the embedded selector.
+ */
+ public boolean eval() {
+ if (file == null) {
+ throw new BuildException("file attribute not set");
+ }
+ validate();
+ File myBaseDir = baseDir;
+ if (myBaseDir == null) {
+ myBaseDir = getProject().getBaseDir();
+ }
+
+ FileSelector f = getSelectors(getProject())[0];
+ return f.isSelected(
+ myBaseDir, FILE_UTILS.removeLeadingPath(myBaseDir, file), file);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/IsLastModified.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/IsLastModified.java
new file mode 100644
index 00000000..ddacd998
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/IsLastModified.java
@@ -0,0 +1,219 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.condition;
+
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.ProjectComponent;
+import org.apache.tools.ant.taskdefs.Touch;
+import org.apache.tools.ant.types.EnumeratedAttribute;
+import org.apache.tools.ant.types.Resource;
+
+/**
+ * Condition that makes assertions about the last modified date of a
+ * resource.
+ *
+ * @since Ant 1.8.0
+ */
+public class IsLastModified extends ProjectComponent implements Condition {
+ private long millis = -1;
+ private String dateTime = null;
+ private Touch.DateFormatFactory dfFactory = Touch.DEFAULT_DF_FACTORY;
+ private Resource resource;
+ private CompareMode mode = CompareMode.EQUALS;
+
+ /**
+ * Set the new modification time of file(s) touched
+ * in milliseconds since midnight Jan 1 1970.
+ * @param millis the <code>long</code> timestamp to use.
+ */
+ public void setMillis(long millis) {
+ this.millis = millis;
+ }
+
+ /**
+ * Set the new modification time of file(s) touched
+ * in the format &quot;MM/DD/YYYY HH:MM AM <i>or</i> PM&quot;
+ * or &quot;MM/DD/YYYY HH:MM:SS AM <i>or</i> PM&quot;.
+ * @param dateTime the <code>String</code> date in the specified format.
+ */
+ public void setDatetime(String dateTime) {
+ this.dateTime = dateTime;
+ }
+
+ /**
+ * Set the format of the datetime attribute.
+ * @param pattern the <code>SimpleDateFormat</code>-compatible
+ * format pattern.
+ */
+ public void setPattern(final String pattern) {
+ dfFactory = new Touch.DateFormatFactory() {
+ public DateFormat getPrimaryFormat() {
+ return new SimpleDateFormat(pattern);
+ }
+ public DateFormat getFallbackFormat() {
+ return null;
+ }
+ };
+ }
+
+ /**
+ * The resource to test.
+ * @param r the resource to test
+ */
+ public void add(Resource r) {
+ if (resource != null) {
+ throw new BuildException("only one resource can be tested");
+ }
+ resource = r;
+ }
+
+ /**
+ * The type of comparison to test.
+ * @param mode the mode of comparison.
+ */
+ public void setMode(CompareMode mode) {
+ this.mode = mode;
+ }
+
+ /**
+ * Argument validation.
+ * @throws BuildException if the required attributes are not supplied or
+ * if there is an inconsistency in the attributes.
+ */
+ protected void validate() throws BuildException {
+ if (millis >= 0 && dateTime != null) {
+ throw new BuildException("Only one of dateTime and millis can be"
+ + " set");
+ }
+ if (millis < 0 && dateTime == null) {
+ throw new BuildException("millis or dateTime is required");
+ }
+ if (resource == null) {
+ throw new BuildException("resource is required");
+ }
+ }
+
+ /**
+ * Calculate timestamp as millis either based on millis or
+ * dateTime (and pattern) attribute.
+ * @return time in milliseconds
+ * @throws BuildException if the date cannot be parsed.
+ */
+ protected long getMillis() throws BuildException {
+ if (millis >= 0) {
+ return millis;
+ }
+ if ("now".equalsIgnoreCase(dateTime)) {
+ return System.currentTimeMillis();
+ }
+ DateFormat df = dfFactory.getPrimaryFormat();
+ ParseException pe = null;
+ try {
+ return df.parse(dateTime).getTime();
+ } catch (ParseException peOne) {
+ df = dfFactory.getFallbackFormat();
+ if (df == null) {
+ pe = peOne;
+ } else {
+ try {
+ return df.parse(dateTime).getTime();
+ } catch (ParseException peTwo) {
+ pe = peTwo;
+ }
+ }
+ }
+ if (pe != null) {
+ throw new BuildException(pe.getMessage(), pe, getLocation());
+ }
+ /* NOTREACHED */
+ return 0;
+ }
+
+ /**
+ * evaluate the condition
+ * @return true or false depending on the compoarison mode and the time of the resource
+ * @throws BuildException
+ */
+ public boolean eval() throws BuildException {
+ validate();
+ long expected = getMillis();
+ long actual = resource.getLastModified();
+ log("expected timestamp: " + expected + " (" + new Date(expected) + ")"
+ + ", actual timestamp: " + actual + " (" + new Date(actual) + ")" ,
+ Project.MSG_VERBOSE);
+ if (CompareMode.EQUALS_TEXT.equals(mode.getValue())) {
+ return expected == actual;
+ }
+ if (CompareMode.BEFORE_TEXT.equals(mode.getValue())) {
+ return expected > actual;
+ }
+ if (CompareMode.NOT_BEFORE_TEXT.equals(mode.getValue())) {
+ return expected <= actual;
+ }
+ if (CompareMode.AFTER_TEXT.equals(mode.getValue())) {
+ return expected < actual;
+ }
+ if (CompareMode.NOT_AFTER_TEXT.equals(mode.getValue())) {
+ return expected >= actual;
+ }
+ throw new BuildException("Unknown mode " + mode.getValue());
+ }
+
+ /**
+ * describes comparison modes.
+ */
+ public static class CompareMode extends EnumeratedAttribute {
+ private static final String EQUALS_TEXT = "equals";
+ private static final String BEFORE_TEXT = "before";
+ private static final String AFTER_TEXT = "after";
+ private static final String NOT_BEFORE_TEXT = "not-before";
+ private static final String NOT_AFTER_TEXT = "not-after";
+
+ private static final CompareMode EQUALS = new CompareMode(EQUALS_TEXT);
+
+ /**
+ * creates a CompareMode instance of type equals
+ */
+ public CompareMode() {
+ this(EQUALS_TEXT);
+ }
+
+ /**
+ * creates a comparemode instance
+ * @param s one of the authorized values for comparemode
+ */
+ public CompareMode(String s) {
+ super();
+ setValue(s);
+ }
+
+ public String[] getValues() {
+ return new String[] {
+ EQUALS_TEXT, BEFORE_TEXT, AFTER_TEXT, NOT_BEFORE_TEXT,
+ NOT_AFTER_TEXT,
+ };
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/IsReachable.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/IsReachable.java
new file mode 100644
index 00000000..e699da11
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/IsReachable.java
@@ -0,0 +1,207 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.condition;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.net.InetAddress;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.UnknownHostException;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.ProjectComponent;
+
+/**
+ * <p>Test for a host being reachable using ICMP "ping" packets &amp; echo operations.
+ * Ping packets are very reliable for assessing reachability in a LAN or WAN,
+ * but they do not get through any well-configured firewall. Echo (port 7) may.</p>
+ *
+ * <p>This condition turns unknown host exceptions into false conditions. This is
+ * because on a laptop, DNS is one of the first services lost when the network
+ * goes; you are implicitly offline.</p>
+ *
+ * <p>If a URL is supplied instead of a host, the hostname is extracted and used in
+ * the test--all other parts of the URL are discarded.</p>
+ *
+ * <p>The test may not work through firewalls; that is, something may be reachable
+ * using a protocol such as HTTP, while the lower level ICMP packets get dropped
+ * on the floor. Similarly, a host may be detected as reachable with ICMP, but not
+ * reachable on other ports (i.e. port 80), because of firewalls.</p>
+ *
+ * <p>Requires Java 5+ to work properly. On Java 1.4, if a hostname
+ * can be resolved, the destination is assumed to be reachable.</p>
+ *
+ * @since Ant 1.7
+ */
+public class IsReachable extends ProjectComponent implements Condition {
+
+ private static final int SECOND = 1000; // millis per second
+ private String host;
+ private String url;
+
+ /**
+ * The default timeout.
+ */
+ public static final int DEFAULT_TIMEOUT = 30;
+ private int timeout = DEFAULT_TIMEOUT;
+ /**
+ * Error when no hostname is defined
+ */
+ public static final String ERROR_NO_HOSTNAME = "No hostname defined";
+ /**
+ * Error when invalid timeout value is defined
+ */
+ public static final String ERROR_BAD_TIMEOUT = "Invalid timeout value";
+ /**
+ * Unknown host message is seen.
+ */
+ private static final String WARN_UNKNOWN_HOST = "Unknown host: ";
+ /**
+ * Network error message is seen.
+ */
+ public static final String ERROR_ON_NETWORK = "network error to ";
+ /** Error message when url and host are specified. */
+ public static final String ERROR_BOTH_TARGETS
+ = "Both url and host have been specified";
+ /** Error message when no reachably test avail. */
+ public static final String MSG_NO_REACHABLE_TEST
+ = "cannot do a proper reachability test on this Java version";
+ /** Error message when an invalid url is used. */
+ public static final String ERROR_BAD_URL = "Bad URL ";
+ /** Error message when no hostname in url. */
+ public static final String ERROR_NO_HOST_IN_URL = "No hostname in URL ";
+ /** The method name to look for in InetAddress */
+ public static final String METHOD_NAME = "isReachable";
+
+ /**
+ * Set the host to ping.
+ *
+ * @param host the host to ping.
+ */
+ public void setHost(final String host) {
+ this.host = host;
+ }
+
+ /**
+ * Set the URL from which to extract the hostname.
+ *
+ * @param url a URL object.
+ */
+ public void setUrl(final String url) {
+ this.url = url;
+ }
+
+ /**
+ * Set the timeout for the reachability test in seconds.
+ *
+ * @param timeout the timeout in seconds.
+ */
+ public void setTimeout(final int timeout) {
+ this.timeout = timeout;
+ }
+
+ /**
+ * emptyness test
+ *
+ * @param string param to check
+ *
+ * @return true if it is empty
+ */
+ private boolean empty(final String string) {
+ return string == null || string.length() == 0;
+ }
+
+ private static Class[] parameterTypes = {Integer.TYPE};
+
+ /**
+ * Evaluate the condition.
+ *
+ * @return true if the condition is true.
+ *
+ * @throws org.apache.tools.ant.BuildException
+ * if an error occurs
+ */
+ public boolean eval() throws BuildException {
+ if (empty(host) && empty(url)) {
+ throw new BuildException(ERROR_NO_HOSTNAME);
+ }
+ if (timeout < 0) {
+ throw new BuildException(ERROR_BAD_TIMEOUT);
+ }
+ String target = host;
+ if (!empty(url)) {
+ if (!empty(host)) {
+ throw new BuildException(ERROR_BOTH_TARGETS);
+ }
+ try {
+ //get the host of a url
+ final URL realURL = new URL(url);
+ target = realURL.getHost();
+ if (empty(target)) {
+ throw new BuildException(ERROR_NO_HOST_IN_URL + url);
+ }
+ } catch (final MalformedURLException e) {
+ throw new BuildException(ERROR_BAD_URL + url, e);
+ }
+ }
+ log("Probing host " + target, Project.MSG_VERBOSE);
+ InetAddress address;
+ try {
+ address = InetAddress.getByName(target);
+ } catch (final UnknownHostException e1) {
+ log(WARN_UNKNOWN_HOST + target);
+ return false;
+ }
+ log("Host address = " + address.getHostAddress(),
+ Project.MSG_VERBOSE);
+ boolean reachable;
+ //Java1.5: reachable = address.isReachable(timeout * 1000);
+ Method reachableMethod = null;
+ try {
+ reachableMethod = InetAddress.class.getMethod(METHOD_NAME,
+ parameterTypes);
+ final Object[] params = new Object[1];
+ params[0] = new Integer(timeout * SECOND);
+ try {
+ reachable = ((Boolean) reachableMethod.invoke(address, params))
+ .booleanValue();
+ } catch (final IllegalAccessException e) {
+ //utterly implausible, but catered for anyway
+ throw new BuildException("When calling " + reachableMethod);
+ } catch (final InvocationTargetException e) {
+ //assume this is an IOexception about un readability
+ final Throwable nested = e.getTargetException();
+ log(ERROR_ON_NETWORK + target + ": " + nested.toString());
+ //any kind of fault: not reachable.
+ reachable = false;
+ }
+ } catch (final NoSuchMethodException e) {
+ //java1.4
+ log("Not found: InetAddress." + METHOD_NAME, Project.MSG_VERBOSE);
+ log(MSG_NO_REACHABLE_TEST);
+ reachable = true;
+
+ }
+
+ log("host is" + (reachable ? "" : " not") + " reachable", Project.MSG_VERBOSE);
+ return reachable;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/IsReference.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/IsReference.java
new file mode 100644
index 00000000..f172849b
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/IsReference.java
@@ -0,0 +1,89 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.condition;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.ProjectComponent;
+import org.apache.tools.ant.types.Reference;
+
+/**
+ * Condition that tests whether a given reference has been defined.
+ *
+ * <p>Optionally tests whether it is of a given type/class.</p>
+ *
+ * @since Ant 1.6
+ */
+public class IsReference extends ProjectComponent implements Condition {
+ private Reference ref;
+ private String type;
+
+ /**
+ * Set the refid attribute.
+ *
+ * @param r a Reference value
+ */
+ public void setRefid(Reference r) {
+ ref = r;
+ }
+
+ /**
+ * Set the type attribute. This is optional attribute.
+ *
+ * @param type an ant component type name
+ */
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ /**
+ * @return true if the reference exists and if type is set, if
+ * the reference is the same type
+ * @exception BuildException if an error occurs
+ */
+ public boolean eval() throws BuildException {
+ if (ref == null) {
+ throw new BuildException("No reference specified for isreference "
+ + "condition");
+ }
+
+ String key = ref.getRefId();
+ if (!getProject().hasReference(key)) {
+ return false;
+ } else if (type == null) {
+ return true;
+ } else {
+ Object o = getProject().getReference(key);
+ Class typeClass =
+ (Class) getProject().getDataTypeDefinitions().get(type);
+
+ if (typeClass == null) {
+ typeClass =
+ (Class) getProject().getTaskDefinitions().get(type);
+ }
+
+ if (typeClass == null) {
+ // don't know the type, should throw exception instead?
+ return false;
+ }
+
+ return typeClass.isAssignableFrom(o.getClass());
+ }
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/IsSet.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/IsSet.java
new file mode 100644
index 00000000..d4a59145
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/IsSet.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.condition;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.ProjectComponent;
+
+/**
+ * Condition that tests whether a given property has been set.
+ *
+ * @since Ant 1.5
+ */
+public class IsSet extends ProjectComponent implements Condition {
+ private String property;
+
+ /**
+ * Set the property attribute
+ *
+ * @param p the property name
+ */
+ public void setProperty(String p) {
+ property = p;
+ }
+
+ /**
+ * @return true if the property exists
+ * @exception BuildException if the property attribute is not set
+ */
+ public boolean eval() throws BuildException {
+ if (property == null) {
+ throw new BuildException("No property specified for isset " + "condition");
+ }
+ return getProject().getProperty(property) != null;
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/IsSigned.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/IsSigned.java
new file mode 100644
index 00000000..585fb3a7
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/IsSigned.java
@@ -0,0 +1,152 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.condition;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Enumeration;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.ManifestTask;
+import org.apache.tools.ant.types.DataType;
+import org.apache.tools.zip.ZipEntry;
+import org.apache.tools.zip.ZipFile;
+
+/**
+ * Checks whether a jarfile is signed: if the name of the
+ * signature is passed, the file is checked for presence of that
+ * particular signature; otherwise the file is checked for the
+ * existence of any signature.
+ */
+public class IsSigned extends DataType implements Condition {
+
+ private static final String SIG_START = "META-INF/";
+ private static final String SIG_END = ".SF";
+ private static final int SHORT_SIG_LIMIT = 8;
+
+ private String name;
+ private File file;
+
+ /**
+ * The jarfile that is to be tested for the presence
+ * of a signature.
+ * @param file jarfile to be tested.
+ */
+ public void setFile(File file) {
+ this.file = file;
+ }
+
+ /**
+ * The signature name to check jarfile for.
+ * @param name signature to look for.
+ */
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ /**
+ * Returns <code>true</code> if the file exists and is signed with
+ * the signature specified, or, if <code>name</code> wasn't
+ * specified, if the file contains a signature.
+ * @param zipFile the zipfile to check
+ * @param name the signature to check (may be killed)
+ * @return true if the file is signed.
+ * @throws IOException on error
+ */
+ public static boolean isSigned(File zipFile, String name)
+ throws IOException {
+ ZipFile jarFile = null;
+ try {
+ jarFile = new ZipFile(zipFile);
+ if (null == name) {
+ Enumeration entries = jarFile.getEntries();
+ while (entries.hasMoreElements()) {
+ String eName = ((ZipEntry) entries.nextElement()).getName();
+ if (eName.startsWith(SIG_START)
+ && eName.endsWith(SIG_END)) {
+ return true;
+ }
+ }
+ return false;
+ }
+ name = replaceInvalidChars(name);
+ boolean shortSig = jarFile.getEntry(SIG_START
+ + name.toUpperCase()
+ + SIG_END) != null;
+ boolean longSig = false;
+ if (name.length() > SHORT_SIG_LIMIT) {
+ longSig = jarFile.getEntry(
+ SIG_START
+ + name.substring(0, SHORT_SIG_LIMIT).toUpperCase()
+ + SIG_END) != null;
+ }
+
+ return shortSig || longSig;
+ } finally {
+ ZipFile.closeQuietly(jarFile);
+ }
+ }
+
+ /**
+ * Returns <code>true</code> if the file exists and is signed with
+ * the signature specified, or, if <code>name</code> wasn't
+ * specified, if the file contains a signature.
+ * @return true if the file is signed.
+ */
+ public boolean eval() {
+ if (file == null) {
+ throw new BuildException("The file attribute must be set.");
+ }
+ if (!file.exists()) {
+ log("The file \"" + file.getAbsolutePath()
+ + "\" does not exist.", Project.MSG_VERBOSE);
+ return false;
+ }
+
+ boolean r = false;
+ try {
+ r = isSigned(file, name);
+ } catch (IOException e) {
+ log("Got IOException reading file \"" + file.getAbsolutePath()
+ + "\"" + e, Project.MSG_WARN);
+ }
+
+ if (r) {
+ log("File \"" + file.getAbsolutePath() + "\" is signed.",
+ Project.MSG_VERBOSE);
+ }
+ return r;
+ }
+
+ private static String replaceInvalidChars(final String name) {
+ StringBuffer sb = new StringBuffer();
+ final int len = name.length();
+ boolean changes = false;
+ for (int i = 0; i < len; i++) {
+ final char ch = name.charAt(i);
+ if (ManifestTask.VALID_ATTRIBUTE_CHARS.indexOf(ch) < 0) {
+ sb.append("_");
+ changes = true;
+ } else {
+ sb.append(ch);
+ }
+ }
+ return changes ? sb.toString() : name;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/IsTrue.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/IsTrue.java
new file mode 100644
index 00000000..753b441d
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/IsTrue.java
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.condition;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.ProjectComponent;
+
+/**
+ * Condition that tests whether a given string evals to true
+ *
+ * @since Ant 1.5
+ */
+public class IsTrue extends ProjectComponent implements Condition {
+ /**
+ * what we eval
+ */
+ private Boolean value = null;
+
+ /**
+ * set the value to be tested; let ant eval it to true/false
+ * @param value the value to test
+ */
+ public void setValue(boolean value) {
+ this.value = value ? Boolean.TRUE : Boolean.FALSE;
+ }
+
+ /**
+ * @return the value
+ * @throws BuildException if someone forgot to spec a value
+ */
+ public boolean eval() throws BuildException {
+ if (value == null) {
+ throw new BuildException("Nothing to test for truth");
+ }
+ return value.booleanValue();
+ }
+
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/Matches.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/Matches.java
new file mode 100644
index 00000000..ac37f8fe
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/Matches.java
@@ -0,0 +1,119 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.condition;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.ProjectComponent;
+import org.apache.tools.ant.types.RegularExpression;
+import org.apache.tools.ant.util.regexp.Regexp;
+import org.apache.tools.ant.util.regexp.RegexpUtil;
+
+/**
+ * Simple regular expression condition.
+ *
+ * @since Ant 1.7
+ */
+public class Matches extends ProjectComponent implements Condition {
+
+ private String string;
+ private boolean caseSensitive = true;
+ private boolean multiLine = false;
+ private boolean singleLine = false;
+ private RegularExpression regularExpression;
+
+ /**
+ * Set the string
+ *
+ * @param string the string to match
+ */
+ public void setString(String string) {
+ this.string = string;
+ }
+
+ /**
+ * Set the regular expression to match against
+ *
+ * @param pattern the regular expression pattern
+ */
+ public void setPattern(String pattern) {
+ if (regularExpression != null) {
+ throw new BuildException(
+ "Only one regular expression is allowed.");
+ }
+ regularExpression = new RegularExpression();
+ regularExpression.setPattern(pattern);
+ }
+
+ /**
+ * A regular expression.
+ * You can use this element to refer to a previously
+ * defined regular expression datatype instance
+ * @param regularExpression the regular expression object
+ * to be configured as an element
+ */
+ public void addRegexp(RegularExpression regularExpression) {
+ if (this.regularExpression != null) {
+ throw new BuildException(
+ "Only one regular expression is allowed.");
+ }
+ this.regularExpression = regularExpression;
+ }
+
+ /**
+ * Whether to ignore case or not.
+ * @param b if false, ignore case.
+ * @since Ant 1.7
+ */
+ public void setCasesensitive(boolean b) {
+ caseSensitive = b;
+ }
+
+ /**
+ * Whether to match should be multiline.
+ * @param b the value to set.
+ */
+ public void setMultiline(boolean b) {
+ multiLine = b;
+ }
+
+ /**
+ * Whether to treat input as singleline ('.' matches newline).
+ * Corresponds to java.util.regex.Pattern.DOTALL.
+ * @param b the value to set.
+ */
+ public void setSingleLine(boolean b) {
+ singleLine = b;
+ }
+
+ /**
+ * @return true if the string matches the regular expression pattern
+ * @exception BuildException if the attributes are not set correctly
+ */
+ public boolean eval() throws BuildException {
+ if (string == null) {
+ throw new BuildException(
+ "Parameter string is required in matches.");
+ }
+ if (regularExpression == null) {
+ throw new BuildException("Missing pattern in matches.");
+ }
+ int options = RegexpUtil.asOptions(caseSensitive, multiLine, singleLine);
+ Regexp regexp = regularExpression.getRegexp(getProject());
+ return regexp.matches(string, options);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/Not.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/Not.java
new file mode 100644
index 00000000..a39dcbb0
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/Not.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.condition;
+
+import org.apache.tools.ant.BuildException;
+
+/**
+ * &lt;not&gt; condition.
+ *
+ * Evaluates to true if the single condition nested into it is false
+ * and vice versa.
+ *
+ * @since Ant 1.4
+ */
+public class Not extends ConditionBase implements Condition {
+
+ /**
+ * Evaluate condition
+ *
+ * @return true if the condition is true.
+ * @throws BuildException if the condition is not configured correctly.
+ */
+ public boolean eval() throws BuildException {
+ if (countConditions() > 1) {
+ throw new BuildException("You must not nest more than one "
+ + "condition into <not>");
+ }
+ if (countConditions() < 1) {
+ throw new BuildException("You must nest a condition into <not>");
+ }
+ return !((Condition) getConditions().nextElement()).eval();
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/Or.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/Or.java
new file mode 100644
index 00000000..aedfe74f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/Or.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.condition;
+
+import java.util.Enumeration;
+
+import org.apache.tools.ant.BuildException;
+
+/**
+ * &lt;or&gt; condition container.
+ *
+ * <p>Iterates over all conditions and returns true as soon as one
+ * evaluates to true.</p>
+ *
+ * @since Ant 1.4
+ */
+public class Or extends ConditionBase implements Condition {
+
+ /**
+ * @return true if any of the contained conditions evaluate to true
+ * @exception BuildException if an error occurs
+ */
+ public boolean eval() throws BuildException {
+ Enumeration e = getConditions();
+ while (e.hasMoreElements()) {
+ Condition c = (Condition) e.nextElement();
+ if (c.eval()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/Os.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/Os.java
new file mode 100644
index 00000000..974c396f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/Os.java
@@ -0,0 +1,321 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.condition;
+
+import java.util.Locale;
+
+import org.apache.tools.ant.BuildException;
+
+/**
+ * Condition that tests the OS type.
+ *
+ * @since Ant 1.4
+ */
+public class Os implements Condition {
+ private static final String OS_NAME =
+ System.getProperty("os.name").toLowerCase(Locale.ENGLISH);
+ private static final String OS_ARCH =
+ System.getProperty("os.arch").toLowerCase(Locale.ENGLISH);
+ private static final String OS_VERSION =
+ System.getProperty("os.version").toLowerCase(Locale.ENGLISH);
+ private static final String PATH_SEP =
+ System.getProperty("path.separator");
+
+ /**
+ * OS family to look for
+ */
+ private String family;
+ /**
+ * Name of OS
+ */
+ private String name;
+ /**
+ * version of OS
+ */
+ private String version;
+ /**
+ * OS architecture
+ */
+ private String arch;
+ /**
+ * OS family that can be tested for. {@value}
+ */
+ public static final String FAMILY_WINDOWS = "windows";
+ /**
+ * OS family that can be tested for. {@value}
+ */
+ public static final String FAMILY_9X = "win9x";
+ /**
+ * OS family that can be tested for. {@value}
+ */
+ public static final String FAMILY_NT = "winnt";
+ /**
+ * OS family that can be tested for. {@value}
+ */
+ public static final String FAMILY_OS2 = "os/2";
+ /**
+ * OS family that can be tested for. {@value}
+ */
+ public static final String FAMILY_NETWARE = "netware";
+ /**
+ * OS family that can be tested for. {@value}
+ */
+ public static final String FAMILY_DOS = "dos";
+ /**
+ * OS family that can be tested for. {@value}
+ */
+ public static final String FAMILY_MAC = "mac";
+ /**
+ * OS family that can be tested for. {@value}
+ */
+ public static final String FAMILY_TANDEM = "tandem";
+ /**
+ * OS family that can be tested for. {@value}
+ */
+ public static final String FAMILY_UNIX = "unix";
+ /**
+ * OS family that can be tested for. {@value}
+ */
+ public static final String FAMILY_VMS = "openvms";
+ /**
+ * OS family that can be tested for. {@value}
+ */
+ public static final String FAMILY_ZOS = "z/os";
+ /** OS family that can be tested for. {@value} */
+ public static final String FAMILY_OS400 = "os/400";
+
+ /**
+ * OpenJDK is reported to call MacOS X "Darwin"
+ * @see https://issues.apache.org/bugzilla/show_bug.cgi?id=44889
+ * @see https://issues.apache.org/jira/browse/HADOOP-3318
+ */
+ private static final String DARWIN = "darwin";
+
+ /**
+ * Default constructor
+ *
+ */
+ public Os() {
+ //default
+ }
+
+ /**
+ * Constructor that sets the family attribute
+ * @param family a String value
+ */
+ public Os(String family) {
+ setFamily(family);
+ }
+
+ /**
+ * Sets the desired OS family type
+ *
+ * @param f The OS family type desired<br>
+ * Possible values:<br>
+ * <ul>
+ * <li>dos</li>
+ * <li>mac</li>
+ * <li>netware</li>
+ * <li>os/2</li>
+ * <li>tandem</li>
+ * <li>unix</li>
+ * <li>windows</li>
+ * <li>win9x</li>
+ * <li>z/os</li>
+ * <li>os/400</li>
+ * </ul>
+ */
+ public void setFamily(String f) {
+ family = f.toLowerCase(Locale.ENGLISH);
+ }
+
+ /**
+ * Sets the desired OS name
+ *
+ * @param name The OS name
+ */
+ public void setName(String name) {
+ this.name = name.toLowerCase(Locale.ENGLISH);
+ }
+
+ /**
+ * Sets the desired OS architecture
+ *
+ * @param arch The OS architecture
+ */
+ public void setArch(String arch) {
+ this.arch = arch.toLowerCase(Locale.ENGLISH);
+ }
+
+ /**
+ * Sets the desired OS version
+ *
+ * @param version The OS version
+ */
+ public void setVersion(String version) {
+ this.version = version.toLowerCase(Locale.ENGLISH);
+ }
+
+ /**
+ * Determines if the OS on which Ant is executing matches the type of
+ * that set in setFamily.
+ * @return true if the os matches.
+ * @throws BuildException if there is an error.
+ * @see Os#setFamily(String)
+ */
+ public boolean eval() throws BuildException {
+ return isOs(family, name, arch, version);
+ }
+
+ /**
+ * Determines if the OS on which Ant is executing matches the
+ * given OS family.
+ * @param family the family to check for
+ * @return true if the OS matches
+ * @since 1.5
+ */
+ public static boolean isFamily(String family) {
+ return isOs(family, null, null, null);
+ }
+
+ /**
+ * Determines if the OS on which Ant is executing matches the
+ * given OS name.
+ *
+ * @param name the OS name to check for
+ * @return true if the OS matches
+ * @since 1.7
+ */
+ public static boolean isName(String name) {
+ return isOs(null, name, null, null);
+ }
+
+ /**
+ * Determines if the OS on which Ant is executing matches the
+ * given OS architecture.
+ *
+ * @param arch the OS architecture to check for
+ * @return true if the OS matches
+ * @since 1.7
+ */
+ public static boolean isArch(String arch) {
+ return isOs(null, null, arch, null);
+ }
+
+ /**
+ * Determines if the OS on which Ant is executing matches the
+ * given OS version.
+ *
+ * @param version the OS version to check for
+ * @return true if the OS matches
+ * @since 1.7
+ */
+ public static boolean isVersion(String version) {
+ return isOs(null, null, null, version);
+ }
+
+ /**
+ * Determines if the OS on which Ant is executing matches the
+ * given OS family, name, architecture and version
+ *
+ * @param family The OS family
+ * @param name The OS name
+ * @param arch The OS architecture
+ * @param version The OS version
+ * @return true if the OS matches
+ * @since 1.7
+ */
+ public static boolean isOs(String family, String name, String arch,
+ String version) {
+ boolean retValue = false;
+
+ if (family != null || name != null || arch != null
+ || version != null) {
+
+ boolean isFamily = true;
+ boolean isName = true;
+ boolean isArch = true;
+ boolean isVersion = true;
+
+ if (family != null) {
+
+ //windows probing logic relies on the word 'windows' in
+ //the OS
+ boolean isWindows = OS_NAME.indexOf(FAMILY_WINDOWS) > -1;
+ boolean is9x = false;
+ boolean isNT = false;
+ if (isWindows) {
+ //there are only four 9x platforms that we look for
+ is9x = (OS_NAME.indexOf("95") >= 0
+ || OS_NAME.indexOf("98") >= 0
+ || OS_NAME.indexOf("me") >= 0
+ //wince isn't really 9x, but crippled enough to
+ //be a muchness. Ant doesn't run on CE, anyway.
+ || OS_NAME.indexOf("ce") >= 0);
+ isNT = !is9x;
+ }
+ if (family.equals(FAMILY_WINDOWS)) {
+ isFamily = isWindows;
+ } else if (family.equals(FAMILY_9X)) {
+ isFamily = isWindows && is9x;
+ } else if (family.equals(FAMILY_NT)) {
+ isFamily = isWindows && isNT;
+ } else if (family.equals(FAMILY_OS2)) {
+ isFamily = OS_NAME.indexOf(FAMILY_OS2) > -1;
+ } else if (family.equals(FAMILY_NETWARE)) {
+ isFamily = OS_NAME.indexOf(FAMILY_NETWARE) > -1;
+ } else if (family.equals(FAMILY_DOS)) {
+ isFamily = PATH_SEP.equals(";") && !isFamily(FAMILY_NETWARE);
+ } else if (family.equals(FAMILY_MAC)) {
+ isFamily = OS_NAME.indexOf(FAMILY_MAC) > -1
+ || OS_NAME.indexOf(DARWIN) > -1;
+ } else if (family.equals(FAMILY_TANDEM)) {
+ isFamily = OS_NAME.indexOf("nonstop_kernel") > -1;
+ } else if (family.equals(FAMILY_UNIX)) {
+ isFamily = PATH_SEP.equals(":")
+ && !isFamily(FAMILY_VMS)
+ && (!isFamily(FAMILY_MAC) || OS_NAME.endsWith("x")
+ || OS_NAME.indexOf(DARWIN) > -1);
+ } else if (family.equals(FAMILY_ZOS)) {
+ isFamily = OS_NAME.indexOf(FAMILY_ZOS) > -1
+ || OS_NAME.indexOf("os/390") > -1;
+ } else if (family.equals(FAMILY_OS400)) {
+ isFamily = OS_NAME.indexOf(FAMILY_OS400) > -1;
+ } else if (family.equals(FAMILY_VMS)) {
+ isFamily = OS_NAME.indexOf(FAMILY_VMS) > -1;
+ } else {
+ throw new BuildException(
+ "Don\'t know how to detect os family \""
+ + family + "\"");
+ }
+ }
+ if (name != null) {
+ isName = name.equals(OS_NAME);
+ }
+ if (arch != null) {
+ isArch = arch.equals(OS_ARCH);
+ }
+ if (version != null) {
+ isVersion = version.equals(OS_VERSION);
+ }
+ retValue = isFamily && isName && isArch && isVersion;
+ }
+ return retValue;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/ParserSupports.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/ParserSupports.java
new file mode 100644
index 00000000..d2834019
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/ParserSupports.java
@@ -0,0 +1,150 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.condition;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.ProjectComponent;
+import org.apache.tools.ant.util.JAXPUtils;
+import org.xml.sax.SAXNotRecognizedException;
+import org.xml.sax.SAXNotSupportedException;
+import org.xml.sax.XMLReader;
+
+/**
+ * Test for the XML parser supporting a particular feature
+ * @since Ant 1.7
+ */
+public class ParserSupports extends ProjectComponent implements Condition {
+
+ private String feature;
+ private String property;
+ private String value;
+ // Error messages
+ /** error - combined attributes not allowed */
+ public static final String ERROR_BOTH_ATTRIBUTES =
+ "Property and feature attributes are exclusive";
+ /** feature */
+ public static final String FEATURE = "feature";
+ /** property */
+ public static final String PROPERTY = "property";
+
+ /** error - not recognized */
+ public static final String NOT_RECOGNIZED =
+ " not recognized: ";
+ /** error - not supported */
+ public static final String NOT_SUPPORTED =
+ " not supported: ";
+ /** error - missing attribute */
+ public static final String ERROR_NO_ATTRIBUTES =
+ "Neither feature or property are set";
+ /** error - no value */
+ public static final String ERROR_NO_VALUE =
+ "A value is needed when testing for property support";
+
+ /**
+ * Feature to probe for.
+ * @param feature the feature to probe for.
+ */
+ public void setFeature(String feature) {
+ this.feature = feature;
+ }
+
+ /**
+ * Property to probe for
+ * @param property the property to probe for.
+ */
+ public void setProperty(String property) {
+ this.property = property;
+ }
+
+ /**
+ * Optional value to set.
+ * Converted to a boolean value when setting a property
+ * @param value the value to set.
+ */
+ public void setValue(String value) {
+ this.value = value;
+ }
+
+ /** {@inheritDoc}. */
+ public boolean eval() throws BuildException {
+ if (feature != null && property != null) {
+ throw new BuildException(ERROR_BOTH_ATTRIBUTES);
+ }
+ if (feature == null && property == null) {
+ throw new BuildException(ERROR_NO_ATTRIBUTES);
+ }
+ //pick a value that is good for everything
+ if (feature != null) {
+ return evalFeature();
+ }
+ if (value == null) {
+ throw new BuildException(ERROR_NO_VALUE);
+ }
+ return evalProperty();
+ }
+
+ /**
+ * Get our reader
+ * @return a reader
+ */
+ private XMLReader getReader() {
+ JAXPUtils.getParser();
+ return JAXPUtils.getXMLReader();
+ }
+
+ /**
+ * Set a feature
+ * @return true if the feature could be set
+ */
+ public boolean evalFeature() {
+ XMLReader reader = getReader();
+ if (value == null) {
+ value = "true";
+ }
+ boolean v = Project.toBoolean(value);
+ try {
+ reader.setFeature(feature, v);
+ } catch (SAXNotRecognizedException e) {
+ log(FEATURE + NOT_RECOGNIZED + feature, Project.MSG_VERBOSE);
+ return false;
+ } catch (SAXNotSupportedException e) {
+ log(FEATURE + NOT_SUPPORTED + feature, Project.MSG_VERBOSE);
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Set a property
+ * @return true if the feature could be set
+ */
+ public boolean evalProperty() {
+ XMLReader reader = getReader();
+ try {
+ reader.setProperty(property, value);
+ } catch (SAXNotRecognizedException e) {
+ log(PROPERTY + NOT_RECOGNIZED + property, Project.MSG_VERBOSE);
+ return false;
+ } catch (SAXNotSupportedException e) {
+ log(PROPERTY + NOT_SUPPORTED + property, Project.MSG_VERBOSE);
+ return false;
+ }
+ return true;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/ResourceContains.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/ResourceContains.java
new file mode 100644
index 00000000..76a9ad35
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/ResourceContains.java
@@ -0,0 +1,165 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.condition;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.ResourceCollection;
+import org.apache.tools.ant.types.resources.FileResource;
+import org.apache.tools.ant.util.FileUtils;
+
+/**
+ * &lt;resourcecontains&gt;
+ * Is a string contained in a resource (file currently)?
+ * @since Ant 1.7.1
+ */
+public class ResourceContains implements Condition {
+
+ private Project project;
+ private String substring;
+ private Resource resource;
+ private String refid;
+ private boolean casesensitive = true;
+
+ /**
+ * Set this condition's Project.
+ * @param project Project
+ */
+ public void setProject(Project project) {
+ this.project = project;
+ }
+
+ /**
+ * Get this condition's Project.
+ * @return Project
+ */
+ public Project getProject() {
+ return project;
+ }
+
+ /**
+ * Sets the resource to search
+ * @param r the value to use.
+ */
+ public void setResource(String r) {
+ this.resource = new FileResource(new File(r));
+ }
+
+ /**
+ * Sets the refid to search; should indicate a resource directly
+ * or by way of a single-element ResourceCollection.
+ * @param refid the value to use.
+ */
+ public void setRefid(String refid) {
+ this.refid = refid;
+ }
+
+ private void resolveRefid() {
+ try {
+ if (getProject() == null) {
+ throw new BuildException("Cannot retrieve refid; project unset");
+ }
+ Object o = getProject().getReference(refid);
+ if (!(o instanceof Resource)) {
+ if (o instanceof ResourceCollection) {
+ ResourceCollection rc = (ResourceCollection) o;
+ if (rc.size() == 1) {
+ o = rc.iterator().next();
+ }
+ } else {
+ throw new BuildException(
+ "Illegal value at '" + refid + "': " + String.valueOf(o));
+ }
+ }
+ this.resource = (Resource) o;
+ } finally {
+ refid = null;
+ }
+ }
+
+ /**
+ * Sets the substring to look for
+ * @param substring the value to use.
+ */
+ public void setSubstring(String substring) {
+ this.substring = substring;
+ }
+
+ /**
+ * Sets case sensitivity attribute.
+ * @param casesensitive the value to use.
+ */
+ public void setCasesensitive(boolean casesensitive) {
+ this.casesensitive = casesensitive;
+ }
+
+ private void validate() {
+ if (resource != null && refid != null) {
+ throw new BuildException("Cannot set both resource and refid");
+ }
+ if (resource == null && refid != null) {
+ resolveRefid();
+ }
+ if (resource == null || substring == null) {
+ throw new BuildException("both resource and substring are required "
+ + "in <resourcecontains>");
+ }
+ }
+
+ /**
+ * Evaluates the condition.
+ * @return true if the substring is contained in the resource
+ * @throws BuildException if there is a problem.
+ */
+ public synchronized boolean eval() throws BuildException {
+ validate();
+
+ if (substring.length() == 0) {
+ if (getProject() != null) {
+ getProject().log("Substring is empty; returning true",
+ Project.MSG_VERBOSE);
+ }
+ return true;
+ }
+ if (resource.getSize() == 0) {
+ return false;
+ }
+
+ BufferedReader reader = null;
+ try {
+ reader = new BufferedReader(new InputStreamReader(resource.getInputStream()));
+ String contents = FileUtils.safeReadFully(reader);
+ String sub = substring;
+ if (!casesensitive) {
+ contents = contents.toLowerCase();
+ sub = sub.toLowerCase();
+ }
+ return contents.indexOf(sub) >= 0;
+ } catch (IOException e) {
+ throw new BuildException("There was a problem accessing resource : " + resource);
+ } finally {
+ FileUtils.close(reader);
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/ResourceExists.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/ResourceExists.java
new file mode 100644
index 00000000..feda65b2
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/ResourceExists.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.condition;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.ProjectComponent;
+import org.apache.tools.ant.types.Resource;
+
+/**
+ * Condition that checks whether a given resource exists.
+ *
+ * @since Ant 1.8.0
+ */
+public class ResourceExists extends ProjectComponent implements Condition {
+ private Resource resource;
+
+ /**
+ * The resource to test.
+ */
+ public void add(Resource r) {
+ if (resource != null) {
+ throw new BuildException("only one resource can be tested");
+ }
+ resource = r;
+ }
+
+ /**
+ * Argument validation.
+ */
+ protected void validate() throws BuildException {
+ if (resource == null) {
+ throw new BuildException("resource is required");
+ }
+ }
+
+ public boolean eval() throws BuildException {
+ validate();
+ return resource.isExists();
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/ResourcesMatch.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/ResourcesMatch.java
new file mode 100644
index 00000000..29e3e800
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/ResourcesMatch.java
@@ -0,0 +1,93 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.condition;
+
+import java.io.IOException;
+import java.util.Iterator;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.ResourceCollection;
+import org.apache.tools.ant.types.resources.Union;
+import org.apache.tools.ant.util.ResourceUtils;
+
+/**
+ * Compares resources for equality based on size and content.
+ * All resources specified must match; no resource collections
+ * specified is an error condition; if resource collections are
+ * specified, but yield fewer than two elements, the condition
+ * evaluates to <code>true</code>.
+ * @since Ant 1.7
+ */
+public class ResourcesMatch implements Condition {
+
+ private Union resources = null;
+ private boolean asText = false;
+
+ /**
+ * Set whether to treat resources as if they were text files,
+ * ignoring line endings.
+ * @param asText whether to ignore line endings.
+ */
+ public void setAsText(boolean asText) {
+ this.asText = asText;
+ }
+
+ /**
+ * Add a resource collection.
+ * @param rc the resource collection to add.
+ */
+ public void add(ResourceCollection rc) {
+ if (rc == null) {
+ return;
+ }
+ resources = resources == null ? new Union() : resources;
+ resources.add(rc);
+ }
+
+ /**
+ * Verify that all resources match.
+ * @return true if all resources are equal.
+ * @exception BuildException if there is an error.
+ */
+ public boolean eval() throws BuildException {
+ if (resources == null) {
+ throw new BuildException(
+ "You must specify one or more nested resource collections");
+ }
+ if (resources.size() > 1) {
+ Iterator<Resource> i = resources.iterator();
+ Resource r1 = (Resource) i.next();
+ Resource r2 = null;
+
+ while (i.hasNext()) {
+ r2 = (Resource) i.next();
+ try {
+ if (!ResourceUtils.contentEquals(r1, r2, asText)) {
+ return false;
+ }
+ } catch (IOException ioe) {
+ throw new BuildException("when comparing resources "
+ + r1.toString() + " and " + r2.toString(), ioe);
+ }
+ r1 = r2;
+ }
+ }
+ return true;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/Socket.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/Socket.java
new file mode 100644
index 00000000..d6a69ec8
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/Socket.java
@@ -0,0 +1,87 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.condition;
+
+import java.io.IOException;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.ProjectComponent;
+
+/**
+ * Condition to wait for a TCP/IP socket to have a listener. Its attributes are:
+ * server - the name of the server.
+ * port - the port number of the socket.
+ *
+ * @since Ant 1.5
+ */
+public class Socket extends ProjectComponent implements Condition {
+ private String server = null;
+ private int port = 0;
+
+ /**
+ * Set the server attribute
+ *
+ * @param server the server name
+ */
+ public void setServer(String server) {
+ this.server = server;
+ }
+
+ /**
+ * Set the port attribute
+ *
+ * @param port the port number of the socket
+ */
+ public void setPort(int port) {
+ this.port = port;
+ }
+
+ /**
+ * @return true if a socket can be created
+ * @exception BuildException if the attributes are not set
+ */
+ public boolean eval() throws BuildException {
+ if (server == null) {
+ throw new BuildException("No server specified in socket "
+ + "condition");
+ }
+ if (port == 0) {
+ throw new BuildException("No port specified in socket condition");
+ }
+ log("Checking for listener at " + server + ":" + port,
+ Project.MSG_VERBOSE);
+ java.net.Socket s = null;
+ try {
+ s = new java.net.Socket(server, port);
+ } catch (IOException e) {
+ return false;
+ } finally {
+ if (s != null) {
+ try {
+ s.close();
+ } catch (IOException ioe) {
+ // Intentionally left blank
+ }
+ }
+ }
+ return true;
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/TypeFound.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/TypeFound.java
new file mode 100644
index 00000000..f97c7f44
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/TypeFound.java
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.condition;
+
+import org.apache.tools.ant.AntTypeDefinition;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.ComponentHelper;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.ProjectComponent;
+import org.apache.tools.ant.ProjectHelper;
+
+/**
+ * looks for a task or other Ant type that exists. Existence is defined as
+ * the type is defined, and its implementation class is present. This
+ * will work for datatypes and preset, script and macro definitions.
+ */
+public class TypeFound extends ProjectComponent implements Condition {
+
+ private String name;
+ private String uri;
+
+ /**
+ * the task or other type to look for
+ * @param name the name of the type
+ */
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ /**
+ * The URI for this definition.
+ * @param uri the namespace URI. If this is not set, use the
+ * default ant namespace.
+ */
+ public void setURI(String uri) {
+ this.uri = uri;
+ }
+
+ /**
+ * test for a task or other ant type existing in the current project
+ * @param typename the name of the type
+ * @return true if the typename exists
+ */
+ protected boolean doesTypeExist(String typename) {
+
+ ComponentHelper helper =
+ ComponentHelper.getComponentHelper(getProject());
+ String componentName = ProjectHelper.genComponentName(uri, typename);
+ AntTypeDefinition def = helper.getDefinition(componentName);
+ if (def == null) {
+ return false;
+ }
+ //now verify that the class has an implementation
+ boolean found = def.getExposedClass(getProject()) != null;
+ if (!found) {
+ String text = helper.diagnoseCreationFailure(componentName, "type");
+ log(text, Project.MSG_VERBOSE);
+ }
+ return found;
+ }
+
+
+ /**
+ * Is this condition true?
+ * @return true if the condition is true
+ * @exception BuildException if an error occurs
+ */
+ public boolean eval() throws BuildException {
+ if (name == null) {
+ throw new BuildException("No type specified");
+ }
+ return doesTypeExist(name);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/Xor.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/Xor.java
new file mode 100644
index 00000000..a2e675cb
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/condition/Xor.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.condition;
+
+import java.util.Enumeration;
+
+import org.apache.tools.ant.BuildException;
+
+/**
+ * The <tt>Xor</tt> condition type to exclusive or operations.
+ * This does not shortcut stuff.
+ * @since Ant 1.7
+ */
+public class Xor extends ConditionBase implements Condition {
+
+ /**
+ * Evaluate the contained conditions.
+ * @return the result of xoring the conditions together.
+ * @throws org.apache.tools.ant.BuildException
+ * if an error occurs.
+ */
+ public boolean eval() throws BuildException {
+ Enumeration e = getConditions();
+ //initial state is false.
+ boolean state = false;
+ while (e.hasMoreElements()) {
+ Condition c = (Condition) e.nextElement();
+ //every condition is xored against the previous one
+ state ^= c.eval();
+ }
+ return state;
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/cvslib/CVSEntry.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/cvslib/CVSEntry.java
new file mode 100644
index 00000000..b1a9a123
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/cvslib/CVSEntry.java
@@ -0,0 +1,112 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.cvslib;
+
+import java.util.Date;
+import java.util.Vector;
+
+/**
+ * CVS Entry.
+ *
+ */
+public class CVSEntry {
+ private Date date;
+ private String author;
+ private final String comment;
+ private final Vector files = new Vector();
+
+ /**
+ * Creates a new instance of a CVSEntry
+ * @param date the date
+ * @param author the author
+ * @param comment a comment to be added to the revision
+ */
+ public CVSEntry(final Date date, final String author, final String comment) {
+ this.date = date;
+ this.author = author;
+ this.comment = comment;
+ }
+
+ /**
+ * Adds a file to the CVSEntry
+ * @param file the file to add
+ * @param revision the revision
+ */
+ public void addFile(final String file, final String revision) {
+ files.addElement(new RCSFile(file, revision));
+ }
+
+ /**
+ * Adds a file to the CVSEntry
+ * @param file the file to add
+ * @param revision the revision
+ * @param previousRevision the previous revision
+ */
+ public void addFile(final String file, final String revision, final String previousRevision) {
+ files.addElement(new RCSFile(file, revision, previousRevision));
+ }
+
+ /**
+ * Gets the date of the CVSEntry
+ * @return the date
+ */
+ public Date getDate() {
+ return date;
+ }
+
+ /**
+ * Sets the author of the CVSEntry
+ * @param author the author
+ */
+ public void setAuthor(final String author) {
+ this.author = author;
+ }
+
+ /**
+ * Gets the author of the CVSEntry
+ * @return the author
+ */
+ public String getAuthor() {
+ return author;
+ }
+
+ /**
+ * Gets the comment for the CVSEntry
+ * @return the comment
+ */
+ public String getComment() {
+ return comment;
+ }
+
+ /**
+ * Gets the files in this CVSEntry
+ * @return the files
+ */
+ public Vector getFiles() {
+ return files;
+ }
+
+ /**
+ * Gets a String containing author, date, files and comment
+ * @return a string representation of this CVSEntry
+ */
+ public String toString() {
+ return getAuthor() + "\n" + getDate() + "\n" + getFiles() + "\n"
+ + getComment();
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/cvslib/ChangeLogParser.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/cvslib/ChangeLogParser.java
new file mode 100644
index 00000000..0096aadf
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/cvslib/ChangeLogParser.java
@@ -0,0 +1,321 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.cvslib;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+import java.util.StringTokenizer;
+import java.util.TimeZone;
+
+import org.apache.tools.ant.taskdefs.AbstractCvsTask;
+import org.apache.tools.ant.util.CollectionUtils;
+
+/**
+ * A class used to parse the output of the CVS log command.
+ *
+ */
+class ChangeLogParser {
+ //private static final int GET_ENTRY = 0;
+ private static final int GET_FILE = 1;
+ private static final int GET_DATE = 2;
+ private static final int GET_COMMENT = 3;
+ private static final int GET_REVISION = 4;
+ private static final int GET_PREVIOUS_REV = 5;
+
+// FIXME formatters are not thread-safe
+
+ /** input format for dates read in from cvs log */
+ private static final SimpleDateFormat INPUT_DATE
+ = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss", Locale.US);
+ /**
+ * New formatter used to parse CVS date/timestamp.
+ */
+ private static final SimpleDateFormat CVS1129_INPUT_DATE =
+ new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z", Locale.US);
+
+ static {
+ TimeZone utc = TimeZone.getTimeZone("UTC");
+ INPUT_DATE.setTimeZone(utc);
+ CVS1129_INPUT_DATE.setTimeZone(utc);
+ }
+
+ //The following is data used while processing stdout of CVS command
+ private String file;
+ private String date;
+ private String author;
+ private String comment;
+ private String revision;
+ private String previousRevision;
+
+ private int status = GET_FILE;
+
+ /** rcs entries */
+ private final Hashtable entries = new Hashtable();
+
+ private final boolean remote;
+ private final String[] moduleNames;
+ private final int[] moduleNameLengths;
+
+ public ChangeLogParser() {
+ this(false, "", CollectionUtils.EMPTY_LIST);
+ }
+
+ public ChangeLogParser(boolean remote, String packageName, List modules) {
+ this.remote = remote;
+
+ ArrayList names = new ArrayList();
+ if (packageName != null) {
+ for (StringTokenizer tok = new StringTokenizer(packageName);
+ tok.hasMoreTokens();) {
+ names.add(tok.nextToken());
+ }
+ }
+ for (Iterator iter = modules.iterator(); iter.hasNext();) {
+ AbstractCvsTask.Module m = (AbstractCvsTask.Module) iter.next();
+ names.add(m.getName());
+ }
+
+ moduleNames = (String[]) names.toArray(new String[names.size()]);
+ moduleNameLengths = new int[moduleNames.length];
+ for (int i = 0; i < moduleNames.length; i++) {
+ moduleNameLengths[i] = moduleNames[i].length();
+ }
+ }
+
+ /**
+ * Get a list of rcs entries as an array.
+ *
+ * @return a list of rcs entries as an array
+ */
+ public CVSEntry[] getEntrySetAsArray() {
+ final CVSEntry[] array = new CVSEntry[ entries.size() ];
+ int i = 0;
+ for (Enumeration e = entries.elements(); e.hasMoreElements();) {
+ array[i++] = (CVSEntry) e.nextElement();
+ }
+ return array;
+ }
+
+ /**
+ * Receive notification about the process writing
+ * to standard output.
+ * @param line the line to process
+ */
+ public void stdout(final String line) {
+ switch(status) {
+ case GET_FILE:
+ // make sure attributes are reset when
+ // working on a 'new' file.
+ reset();
+ processFile(line);
+ break;
+ case GET_REVISION:
+ processRevision(line);
+ break;
+
+ case GET_DATE:
+ processDate(line);
+ break;
+
+ case GET_COMMENT:
+ processComment(line);
+ break;
+
+ case GET_PREVIOUS_REV:
+ processGetPreviousRevision(line);
+ break;
+
+ default:
+ // Do nothing
+ break;
+ }
+ }
+
+ /**
+ * Process a line while in "GET_COMMENT" state.
+ *
+ * @param line the line
+ */
+ private void processComment(final String line) {
+ final String lineSeparator = System.getProperty("line.separator");
+ if (line.equals(
+ "=============================================================================")) {
+ //We have ended changelog for that particular file
+ //so we can save it
+ final int end
+ = comment.length() - lineSeparator.length(); //was -1
+ comment = comment.substring(0, end);
+ saveEntry();
+ status = GET_FILE;
+ } else if (line.equals("----------------------------")) {
+ final int end
+ = comment.length() - lineSeparator.length(); //was -1
+ comment = comment.substring(0, end);
+ status = GET_PREVIOUS_REV;
+ } else {
+ comment += line + lineSeparator;
+ }
+ }
+
+ /**
+ * Process a line while in "GET_FILE" state.
+ *
+ * @param line the line to process
+ */
+ private void processFile(final String line) {
+ if (!remote && line.startsWith("Working file:")) {
+ // CheckStyle:MagicNumber OFF
+ file = line.substring(14, line.length());
+ // CheckStyle:MagicNumber ON
+ status = GET_REVISION;
+ } else if (remote && line.startsWith("RCS file:")) {
+ // exclude the part of the RCS filename up to and
+ // including the module name (and the path separator)
+ int startOfFileName = 0;
+ for (int i = 0; i < moduleNames.length; i++) {
+ int index = line.indexOf(moduleNames[i]);
+ if (index >= 0) {
+ startOfFileName = index + moduleNameLengths[i] + 1;
+ break;
+ }
+ }
+ int endOfFileName = line.indexOf(",v");
+ if (endOfFileName == -1) {
+ file = line.substring(startOfFileName);
+ } else {
+ file = line.substring(startOfFileName, endOfFileName);
+ }
+ status = GET_REVISION;
+ }
+ }
+
+ /**
+ * Process a line while in "REVISION" state.
+ *
+ * @param line the line to process
+ */
+ private void processRevision(final String line) {
+ if (line.startsWith("revision")) {
+ // CheckStyle:MagicNumber OFF
+ revision = line.substring(9);
+ // CheckStyle:MagicNumber ON
+ status = GET_DATE;
+ } else if (line.startsWith("======")) {
+ //There were no revisions in this changelog
+ //entry so lets move onto next file
+ status = GET_FILE;
+ }
+ }
+
+ /**
+ * Process a line while in "DATE" state.
+ *
+ * @param line the line to process
+ */
+ private void processDate(final String line) {
+ if (line.startsWith("date:")) {
+ // The date format is using a - format since 1.12.9 so we have:
+ // 1.12.9-: 'date: YYYY/mm/dd HH:mm:ss; author: name;'
+ // 1.12.9+: 'date: YYYY-mm-dd HH:mm:ss Z; author: name'
+ int endOfDateIndex = line.indexOf(';');
+ date = line.substring("date: ".length(), endOfDateIndex);
+
+ int startOfAuthorIndex = line.indexOf("author: ", endOfDateIndex + 1);
+ int endOfAuthorIndex = line.indexOf(';', startOfAuthorIndex + 1);
+ author = line.substring("author: ".length() + startOfAuthorIndex, endOfAuthorIndex);
+
+ status = GET_COMMENT;
+
+ //Reset comment to empty here as we can accumulate multiple lines
+ //in the processComment method
+ comment = "";
+ }
+ }
+
+ /**
+ * Process a line while in "GET_PREVIOUS_REVISION" state.
+ *
+ * @param line the line to process
+ */
+ private void processGetPreviousRevision(final String line) {
+ if (!line.startsWith("revision ")) {
+ throw new IllegalStateException("Unexpected line from CVS: "
+ + line);
+ }
+ previousRevision = line.substring("revision ".length());
+
+ saveEntry();
+
+ revision = previousRevision;
+ status = GET_DATE;
+ }
+
+ /**
+ * Utility method that saves the current entry.
+ */
+ private void saveEntry() {
+ final String entryKey = date + author + comment;
+ CVSEntry entry;
+ if (!entries.containsKey(entryKey)) {
+ Date dateObject = parseDate(date);
+ entry = new CVSEntry(dateObject, author, comment);
+ entries.put(entryKey, entry);
+ } else {
+ entry = (CVSEntry) entries.get(entryKey);
+ }
+
+ entry.addFile(file, revision, previousRevision);
+ }
+
+ /**
+ * Parse date out from expected format.
+ *
+ * @param date the string holding date
+ * @return the date object or null if unknown date format
+ */
+ private Date parseDate(final String date) {
+ try {
+ return INPUT_DATE.parse(date);
+ } catch (ParseException e) {
+ try {
+ return CVS1129_INPUT_DATE.parse(date);
+ } catch (ParseException e2) {
+ throw new IllegalStateException("Invalid date format: " + date);
+ }
+ }
+ }
+
+ /**
+ * Reset all internal attributes except status.
+ */
+ public void reset() {
+ this.file = null;
+ this.date = null;
+ this.author = null;
+ this.comment = null;
+ this.revision = null;
+ this.previousRevision = null;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/cvslib/ChangeLogTask.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/cvslib/ChangeLogTask.java
new file mode 100644
index 00000000..b4b51ced
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/cvslib/ChangeLogTask.java
@@ -0,0 +1,489 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.cvslib;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.io.UnsupportedEncodingException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Properties;
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.DirectoryScanner;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.AbstractCvsTask;
+import org.apache.tools.ant.types.FileSet;
+import org.apache.tools.ant.util.FileUtils;
+
+/**
+ * Examines the output of cvs log and group related changes together.
+ *
+ * It produces an XML output representing the list of changes.
+ * <pre>
+ * <font color=#0000ff>&lt;!-- Root element --&gt;</font>
+ * <font color=#6a5acd>&lt;!ELEMENT</font> changelog <font color=#ff00ff>
+ * (entry</font><font color=#ff00ff>+</font><font color=#ff00ff>)
+ * </font><font color=#6a5acd>&gt;</font>
+ * <font color=#0000ff>&lt;!-- CVS Entry --&gt;</font>
+ * <font color=#6a5acd>&lt;!ELEMENT</font> entry <font color=#ff00ff>
+ * (date,author,file</font><font color=#ff00ff>+</font><font color=#ff00ff>,msg)
+ * </font><font color=#6a5acd>&gt;</font>
+ * <font color=#0000ff>&lt;!-- Date of cvs entry --&gt;</font>
+ * <font color=#6a5acd>&lt;!ELEMENT</font> date <font color=#ff00ff>(#PCDATA)
+ * </font><font color=#6a5acd>&gt;</font>
+ * <font color=#0000ff>&lt;!-- Author of change --&gt;</font>
+ * <font color=#6a5acd>&lt;!ELEMENT</font> author <font color=#ff00ff>(#PCDATA)
+ * </font><font color=#6a5acd>&gt;</font>
+ * <font color=#0000ff>&lt;!-- List of files affected --&gt;</font>
+ * <font color=#6a5acd>&lt;!ELEMENT</font> msg <font color=#ff00ff>(#PCDATA)
+ * </font><font color=#6a5acd>&gt;</font>
+ * <font color=#0000ff>&lt;!-- File changed --&gt;</font>
+ * <font color=#6a5acd>&lt;!ELEMENT</font> file <font color=#ff00ff>
+ * (name,revision,prevrevision</font><font color=#ff00ff>?</font>
+ * <font color=#ff00ff>)</font><font color=#6a5acd>&gt;</font>
+ * <font color=#0000ff>&lt;!-- Name of the file --&gt;</font>
+ * <font color=#6a5acd>&lt;!ELEMENT</font> name <font color=#ff00ff>(#PCDATA)
+ * </font><font color=#6a5acd>&gt;</font>
+ * <font color=#0000ff>&lt;!-- Revision number --&gt;</font>
+ * <font color=#6a5acd>&lt;!ELEMENT</font> revision <font color=#ff00ff>
+ * (#PCDATA)</font><font color=#6a5acd>&gt;</font>
+ * <font color=#0000ff>&lt;!-- Previous revision number --&gt;</font>
+ * <font color=#6a5acd>&lt;!ELEMENT</font> prevrevision <font color=#ff00ff>
+ * (#PCDATA)</font><font color=#6a5acd>&gt;</font>
+ * </pre>
+ *
+ * @since Ant 1.5
+ * @ant.task name="cvschangelog" category="scm"
+ */
+public class ChangeLogTask extends AbstractCvsTask {
+ /** User list */
+ private File usersFile;
+
+ /** User list */
+ private Vector cvsUsers = new Vector();
+
+ /** Input dir */
+ private File inputDir;
+
+ /** Output file */
+ private File destFile;
+
+ /** The earliest date at which to start processing entries. */
+ private Date startDate;
+
+ /** The latest date at which to stop processing entries. */
+ private Date endDate;
+
+ /** Determines whether log (false) or rlog (true) is used */
+ private boolean remote = false;
+
+ /** Start tag when doing tag ranges. */
+ private String startTag;
+
+ /** End tag when doing tag ranges. */
+ private String endTag;
+
+ /**
+ * Filesets containing list of files against which the cvs log will be
+ * performed. If empty then all files in the working directory will
+ * be checked.
+ */
+ private final Vector filesets = new Vector();
+
+
+ /**
+ * Set the base dir for cvs.
+ *
+ * @param inputDir The new dir value
+ */
+ public void setDir(final File inputDir) {
+ this.inputDir = inputDir;
+ }
+
+
+ /**
+ * Set the output file for the log.
+ *
+ * @param destFile The new destfile value
+ */
+ public void setDestfile(final File destFile) {
+ this.destFile = destFile;
+ }
+
+
+ /**
+ * Set a lookup list of user names &amp; addresses
+ *
+ * @param usersFile The file containing the users info.
+ */
+ public void setUsersfile(final File usersFile) {
+ this.usersFile = usersFile;
+ }
+
+
+ /**
+ * Add a user to list changelog knows about.
+ *
+ * @param user the user
+ */
+ public void addUser(final CvsUser user) {
+ cvsUsers.addElement(user);
+ }
+
+
+ /**
+ * Set the date at which the changelog should start.
+ *
+ * @param start The date at which the changelog should start.
+ */
+ public void setStart(final Date start) {
+ this.startDate = start;
+ }
+
+
+ /**
+ * Set the date at which the changelog should stop.
+ *
+ * @param endDate The date at which the changelog should stop.
+ */
+ public void setEnd(final Date endDate) {
+ this.endDate = endDate;
+ }
+
+
+ /**
+ * Set the number of days worth of log entries to process.
+ *
+ * @param days the number of days of log to process.
+ */
+ public void setDaysinpast(final int days) {
+ // CheckStyle:MagicNumber OFF
+ final long time = System.currentTimeMillis()
+ - (long) days * 24 * 60 * 60 * 1000;
+ // CheckStyle:MagicNumber ON
+
+ setStart(new Date(time));
+ }
+
+ /**
+ * Whether to use rlog against a remote repository instead of log
+ * in a working copy's directory.
+ *
+ * @since Ant 1.8.0
+ */
+ public void setRemote(final boolean remote) {
+ this.remote = remote;
+ }
+
+ /**
+ * Set the tag at which the changelog should start.
+ *
+ * @param start The date at which the changelog should start.
+ */
+ public void setStartTag(final String start) {
+ this.startTag = start;
+ }
+
+
+ /**
+ * Set the tag at which the changelog should stop.
+ *
+ * @param end The date at which the changelog should stop.
+ */
+ public void setEndTag(final String end) {
+ this.endTag = end;
+ }
+
+ /**
+ * Adds a set of files about which cvs logs will be generated.
+ *
+ * @param fileSet a set of files about which cvs logs will be generated.
+ */
+ public void addFileset(final FileSet fileSet) {
+ filesets.addElement(fileSet);
+ }
+
+
+ /**
+ * Execute task
+ *
+ * @exception BuildException if something goes wrong executing the
+ * cvs command
+ */
+ public void execute() throws BuildException {
+ File savedDir = inputDir; // may be altered in validate
+
+ try {
+
+ validate();
+ final Properties userList = new Properties();
+
+ loadUserlist(userList);
+
+ final int size = cvsUsers.size();
+ for (int i = 0; i < size; i++) {
+ final CvsUser user = (CvsUser) cvsUsers.get(i);
+ user.validate();
+ userList.put(user.getUserID(), user.getDisplayname());
+ }
+
+ if (!remote) {
+ setCommand("log");
+
+ if (getTag() != null) {
+ CvsVersion myCvsVersion = new CvsVersion();
+ myCvsVersion.setProject(getProject());
+ myCvsVersion.setTaskName("cvsversion");
+ myCvsVersion.setCvsRoot(getCvsRoot());
+ myCvsVersion.setCvsRsh(getCvsRsh());
+ myCvsVersion.setPassfile(getPassFile());
+ myCvsVersion.setDest(inputDir);
+ myCvsVersion.execute();
+ if (myCvsVersion.supportsCvsLogWithSOption()) {
+ addCommandArgument("-S");
+ }
+ }
+ } else {
+ // supply 'rlog' as argument instead of command
+ setCommand("");
+ addCommandArgument("rlog");
+ // Do not print name/header if no revisions
+ // selected. This is quicker: less output to parse.
+ addCommandArgument("-S");
+ // Do not list tags. This is quicker: less output to
+ // parse.
+ addCommandArgument("-N");
+ }
+ if (null != startTag || null != endTag) {
+ // man, do I get spoiled by C#'s ?? operator
+ String startValue = startTag == null ? "" : startTag;
+ String endValue = endTag == null ? "" : endTag;
+ addCommandArgument("-r" + startValue + "::" + endValue);
+ } else if (null != startDate) {
+ final SimpleDateFormat outputDate =
+ new SimpleDateFormat("yyyy-MM-dd");
+
+ // We want something of the form: -d ">=YYYY-MM-dd"
+ final String dateRange = ">=" + outputDate.format(startDate);
+
+ // Supply '-d' as a separate argument - Bug# 14397
+ addCommandArgument("-d");
+ addCommandArgument(dateRange);
+ }
+
+ // Check if list of files to check has been specified
+ if (!filesets.isEmpty()) {
+ final Enumeration e = filesets.elements();
+
+ while (e.hasMoreElements()) {
+ final FileSet fileSet = (FileSet) e.nextElement();
+ final DirectoryScanner scanner =
+ fileSet.getDirectoryScanner(getProject());
+ final String[] files = scanner.getIncludedFiles();
+
+ for (int i = 0; i < files.length; i++) {
+ addCommandArgument(files[i]);
+ }
+ }
+ }
+
+ final ChangeLogParser parser = new ChangeLogParser(remote,
+ getPackage(),
+ getModules());
+ final RedirectingStreamHandler handler =
+ new RedirectingStreamHandler(parser);
+
+ log(getCommand(), Project.MSG_VERBOSE);
+
+ setDest(inputDir);
+ setExecuteStreamHandler(handler);
+ try {
+ super.execute();
+ } finally {
+ final String errors = handler.getErrors();
+
+ if (null != errors) {
+ log(errors, Project.MSG_ERR);
+ }
+ }
+ final CVSEntry[] entrySet = parser.getEntrySetAsArray();
+ final CVSEntry[] filteredEntrySet = filterEntrySet(entrySet);
+
+ replaceAuthorIdWithName(userList, filteredEntrySet);
+
+ writeChangeLog(filteredEntrySet);
+
+ } finally {
+ inputDir = savedDir;
+ }
+ }
+
+ /**
+ * Validate the parameters specified for task.
+ *
+ * @throws BuildException if fails validation checks
+ */
+ private void validate()
+ throws BuildException {
+ if (null == inputDir) {
+ inputDir = getProject().getBaseDir();
+ }
+ if (null == destFile) {
+ final String message = "Destfile must be set.";
+
+ throw new BuildException(message);
+ }
+ if (!inputDir.exists()) {
+ final String message = "Cannot find base dir "
+ + inputDir.getAbsolutePath();
+
+ throw new BuildException(message);
+ }
+ if (null != usersFile && !usersFile.exists()) {
+ final String message = "Cannot find user lookup list "
+ + usersFile.getAbsolutePath();
+
+ throw new BuildException(message);
+ }
+ if ((null != startTag || null != endTag)
+ && (null != startDate || null != endDate)) {
+ final String message = "Specify either a tag or date range,"
+ + " not both";
+ throw new BuildException(message);
+ }
+ }
+
+ /**
+ * Load the userlist from the userList file (if specified) and add to
+ * list of users.
+ *
+ * @param userList the file of users
+ * @throws BuildException if file can not be loaded for some reason
+ */
+ private void loadUserlist(final Properties userList)
+ throws BuildException {
+ if (null != usersFile) {
+ try {
+ userList.load(new FileInputStream(usersFile));
+ } catch (final IOException ioe) {
+ throw new BuildException(ioe.toString(), ioe);
+ }
+ }
+ }
+
+ /**
+ * Filter the specified entries according to an appropriate rule.
+ *
+ * @param entrySet the entry set to filter
+ * @return the filtered entry set
+ */
+ private CVSEntry[] filterEntrySet(final CVSEntry[] entrySet) {
+ final Vector results = new Vector();
+
+ for (int i = 0; i < entrySet.length; i++) {
+ final CVSEntry cvsEntry = entrySet[i];
+ final Date date = cvsEntry.getDate();
+
+ //bug#30471
+ //this is caused by Date.after throwing a NullPointerException
+ //for some reason there's no date set in the CVSEntry
+ //Java 1.3.1 API
+ //http://java.sun.com/j2se/1.3/docs/api/java/util/Date.html#after(java.util.Date)
+ //doesn't throw NullPointerException
+ //Java 1.4.2 + 1.5 API
+ //http://java.sun.com/j2se/1.4.2/docs/api/java/util/Date.html#after(java.util.Date)
+ //according to the docs it doesn't throw, according to the bug report it does
+ //http://java.sun.com/j2se/1.5.0/docs/api/java/util/Date.html#after(java.util.Date)
+ //according to the docs it does throw
+
+ //for now skip entries which are missing a date
+ if (null == date) {
+ continue;
+ }
+
+ if (null != startDate && startDate.after(date)) {
+ //Skip dates that are too early
+ continue;
+ }
+ if (null != endDate && endDate.before(date)) {
+ //Skip dates that are too late
+ continue;
+ }
+ results.addElement(cvsEntry);
+ }
+
+ final CVSEntry[] resultArray = new CVSEntry[results.size()];
+
+ results.copyInto(resultArray);
+ return resultArray;
+ }
+
+ /**
+ * replace all known author's id's with their maven specified names
+ */
+ private void replaceAuthorIdWithName(final Properties userList,
+ final CVSEntry[] entrySet) {
+ for (int i = 0; i < entrySet.length; i++) {
+
+ final CVSEntry entry = entrySet[ i ];
+ if (userList.containsKey(entry.getAuthor())) {
+ entry.setAuthor(userList.getProperty(entry.getAuthor()));
+ }
+ }
+ }
+
+ /**
+ * Print changelog to file specified in task.
+ *
+ * @param entrySet the entry set to write.
+ * @throws BuildException if there is an error writing changelog.
+ */
+ private void writeChangeLog(final CVSEntry[] entrySet)
+ throws BuildException {
+ FileOutputStream output = null;
+
+ try {
+ output = new FileOutputStream(destFile);
+
+ final PrintWriter writer =
+ new PrintWriter(new OutputStreamWriter(output, "UTF-8"));
+
+ final ChangeLogWriter serializer = new ChangeLogWriter();
+
+ serializer.printChangeLog(writer, entrySet);
+
+ if (writer.checkError()) {
+ throw new IOException("Encountered an error writing changelog");
+ }
+ } catch (final UnsupportedEncodingException uee) {
+ getProject().log(uee.toString(), Project.MSG_ERR);
+ } catch (final IOException ioe) {
+ throw new BuildException(ioe.toString(), ioe);
+ } finally {
+ FileUtils.close(output);
+ }
+ }
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/cvslib/ChangeLogWriter.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/cvslib/ChangeLogWriter.java
new file mode 100644
index 00000000..2385e51f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/cvslib/ChangeLogWriter.java
@@ -0,0 +1,114 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.cvslib;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.text.SimpleDateFormat;
+import java.util.Enumeration;
+import java.util.TimeZone;
+
+import org.apache.tools.ant.util.DOMElementWriter;
+import org.apache.tools.ant.util.DOMUtils;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+/**
+ * Class used to generate an XML changelog.
+ *
+ */
+public class ChangeLogWriter {
+ /** output format for dates written to xml file */
+ private static final SimpleDateFormat OUTPUT_DATE
+ = new SimpleDateFormat("yyyy-MM-dd");
+ /** output format for times written to xml file */
+ private static final SimpleDateFormat OUTPUT_TIME
+ = new SimpleDateFormat("HH:mm");
+ /** stateless helper for writing the XML document */
+ private static final DOMElementWriter DOM_WRITER = new DOMElementWriter();
+
+ static {
+ TimeZone utc = TimeZone.getTimeZone("UTC");
+ OUTPUT_DATE.setTimeZone(utc);
+ OUTPUT_TIME.setTimeZone(utc);
+ }
+
+ /**
+ * Print out the specified entries.
+ *
+ * @param output writer to which to send output.
+ * @param entries the entries to be written.
+ */
+ public void printChangeLog(final PrintWriter output,
+ final CVSEntry[] entries) {
+ try {
+ output.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
+ Document doc = DOMUtils.newDocument();
+ Element root = doc.createElement("changelog");
+ DOM_WRITER.openElement(root, output, 0, "\t");
+ output.println();
+ for (int i = 0; i < entries.length; i++) {
+ final CVSEntry entry = entries[i];
+
+ printEntry(doc, output, entry);
+ }
+ DOM_WRITER.closeElement(root, output, 0, "\t", true);
+ output.flush();
+ output.close();
+ } catch (IOException e) {
+ throw new org.apache.tools.ant.BuildException(e);
+ }
+ }
+
+
+ /**
+ * Print out an individual entry in changelog.
+ *
+ * @param doc Document used to create elements.
+ * @param entry the entry to print
+ * @param output writer to which to send output.
+ */
+ private void printEntry(Document doc, final PrintWriter output,
+ final CVSEntry entry) throws IOException {
+ Element ent = doc.createElement("entry");
+ DOMUtils.appendTextElement(ent, "date",
+ OUTPUT_DATE.format(entry.getDate()));
+ DOMUtils.appendTextElement(ent, "time",
+ OUTPUT_TIME.format(entry.getDate()));
+ DOMUtils.appendCDATAElement(ent, "author", entry.getAuthor());
+
+ final Enumeration enumeration = entry.getFiles().elements();
+
+ while (enumeration.hasMoreElements()) {
+ final RCSFile file = (RCSFile) enumeration.nextElement();
+
+ Element f = DOMUtils.createChildElement(ent, "file");
+ DOMUtils.appendCDATAElement(f, "name", file.getName());
+ DOMUtils.appendTextElement(f, "revision", file.getRevision());
+
+ final String previousRevision = file.getPreviousRevision();
+ if (previousRevision != null) {
+ DOMUtils.appendTextElement(f, "prevrevision",
+ previousRevision);
+ }
+ }
+ DOMUtils.appendCDATAElement(ent, "msg", entry.getComment());
+ DOM_WRITER.write(ent, output, 1, "\t");
+ }
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/cvslib/CvsTagDiff.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/cvslib/CvsTagDiff.java
new file mode 100644
index 00000000..a90bcc01
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/cvslib/CvsTagDiff.java
@@ -0,0 +1,576 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.cvslib;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.AbstractCvsTask;
+import org.apache.tools.ant.util.CollectionUtils;
+import org.apache.tools.ant.util.DOMElementWriter;
+import org.apache.tools.ant.util.DOMUtils;
+import org.apache.tools.ant.util.FileUtils;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+/**
+ * Examines the output of cvs rdiff between two tags.
+ *
+ * It produces an XML output representing the list of changes.
+ * <PRE>
+ * &lt;!-- Root element --&gt;
+ * &lt;!ELEMENT tagdiff ( entry+ ) &gt;
+ * &lt;!-- Start tag of the report --&gt;
+ * &lt;!ATTLIST tagdiff startTag NMTOKEN #IMPLIED &gt;
+ * &lt;!-- End tag of the report --&gt;
+ * &lt;!ATTLIST tagdiff endTag NMTOKEN #IMPLIED &gt;
+ * &lt;!-- Start date of the report --&gt;
+ * &lt;!ATTLIST tagdiff startDate NMTOKEN #IMPLIED &gt;
+ * &lt;!-- End date of the report --&gt;
+ * &lt;!ATTLIST tagdiff endDate NMTOKEN #IMPLIED &gt;
+ *
+ * &lt;!-- CVS tag entry --&gt;
+ * &lt;!ELEMENT entry ( file ) &gt;
+ * &lt;!-- File added, changed or removed --&gt;
+ * &lt;!ELEMENT file ( name, revision?, prevrevision? ) &gt;
+ * &lt;!-- Name of the file --&gt;
+ * &lt;!ELEMENT name ( #PCDATA ) &gt;
+ * &lt;!-- Revision number --&gt;
+ * &lt;!ELEMENT revision ( #PCDATA ) &gt;
+ * &lt;!-- Previous revision number --&gt;
+ * &lt;!ELEMENT prevrevision ( #PCDATA ) &gt;
+ * </PRE>
+ *
+ * @since Ant 1.5
+ * @ant.task name="cvstagdiff"
+ */
+public class CvsTagDiff extends AbstractCvsTask {
+
+ /**
+ * Used to create the temp file for cvs log
+ */
+ private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+
+ /** stateless helper for writing the XML document */
+ private static final DOMElementWriter DOM_WRITER = new DOMElementWriter();
+
+ /**
+ * Token to identify the word file in the rdiff log
+ */
+ static final String FILE_STRING = "File ";
+ /**
+ * Length of token to identify the word file in the rdiff log
+ */
+ static final int FILE_STRING_LENGTH = FILE_STRING.length();
+ /**
+ * Token to identify the word file in the rdiff log
+ */
+ static final String TO_STRING = " to ";
+ /**
+ * Token to identify a new file in the rdiff log
+ */
+ static final String FILE_IS_NEW = " is new;";
+ /**
+ * Token to identify the revision
+ */
+ static final String REVISION = "revision ";
+
+ /**
+ * Token to identify a modified file in the rdiff log
+ */
+ static final String FILE_HAS_CHANGED = " changed from revision ";
+
+ /**
+ * Token to identify a removed file in the rdiff log
+ */
+ static final String FILE_WAS_REMOVED = " is removed";
+
+ /**
+ * The cvs package/module to analyse
+ */
+ private String mypackage;
+
+ /**
+ * The earliest tag from which diffs are to be included in the report.
+ */
+ private String mystartTag;
+
+ /**
+ * The latest tag from which diffs are to be included in the report.
+ */
+ private String myendTag;
+
+ /**
+ * The earliest date from which diffs are to be included in the report.
+ */
+ private String mystartDate;
+
+ /**
+ * The latest date from which diffs are to be included in the report.
+ */
+ private String myendDate;
+
+ /**
+ * The file in which to write the diff report.
+ */
+ private File mydestfile;
+
+ /**
+ * Used to skip over removed files
+ */
+ private boolean ignoreRemoved = false;
+
+ /**
+ * temporary list of package names.
+ */
+ private List packageNames = new ArrayList();
+
+ /**
+ * temporary list of "File:" + package name + "/" for all packages.
+ */
+ private String[] packageNamePrefixes = null;
+
+ /**
+ * temporary list of length values for prefixes.
+ */
+ private int[] packageNamePrefixLengths = null;
+
+ /**
+ * The package/module to analyze.
+ * @param p the name of the package to analyse
+ */
+ @Override
+ public void setPackage(String p) {
+ mypackage = p;
+ }
+
+ /**
+ * Set the start tag.
+ *
+ * @param s the start tag.
+ */
+ public void setStartTag(String s) {
+ mystartTag = s;
+ }
+
+ /**
+ * Set the start date.
+ *
+ * @param s the start date.
+ */
+ public void setStartDate(String s) {
+ mystartDate = s;
+ }
+
+ /**
+ * Set the end tag.
+ *
+ * @param s the end tag.
+ */
+ public void setEndTag(String s) {
+ myendTag = s;
+ }
+
+ /**
+ * Set the end date.
+ *
+ * @param s the end date.
+ */
+ public void setEndDate(String s) {
+ myendDate = s;
+ }
+
+ /**
+ * Set the output file for the diff.
+ *
+ * @param f the output file for the diff.
+ */
+ public void setDestFile(File f) {
+ mydestfile = f;
+ }
+
+ /**
+ * Set the ignore removed indicator.
+ *
+ * @param b the ignore removed indicator.
+ *
+ * @since Ant 1.8.0
+ */
+ public void setIgnoreRemoved(boolean b) {
+ ignoreRemoved = b;
+ }
+
+
+ /**
+ * Execute task.
+ *
+ * @exception BuildException if an error occurs
+ */
+ @Override
+ public void execute() throws BuildException {
+ // validate the input parameters
+ validate();
+
+ // build the rdiff command
+ addCommandArgument("rdiff");
+ addCommandArgument("-s");
+ if (mystartTag != null) {
+ addCommandArgument("-r");
+ addCommandArgument(mystartTag);
+ } else {
+ addCommandArgument("-D");
+ addCommandArgument(mystartDate);
+ }
+ if (myendTag != null) {
+ addCommandArgument("-r");
+ addCommandArgument(myendTag);
+ } else {
+ addCommandArgument("-D");
+ addCommandArgument(myendDate);
+ }
+
+ // force command not to be null
+ setCommand("");
+ File tmpFile = null;
+ try {
+ handlePackageNames();
+
+ tmpFile = FILE_UTILS.createTempFile("cvstagdiff", ".log", null,
+ true, true);
+ setOutput(tmpFile);
+
+ // run the cvs command
+ super.execute();
+
+ // parse the rdiff
+ CvsTagEntry[] entries = parseRDiff(tmpFile);
+
+ // write the tag diff
+ writeTagDiff(entries);
+
+ } finally {
+ packageNamePrefixes = null;
+ packageNamePrefixLengths = null;
+ packageNames.clear();
+ if (tmpFile != null) {
+ tmpFile.delete();
+ }
+ }
+ }
+
+ /**
+ * Parse the tmpFile and return and array of CvsTagEntry to be
+ * written in the output.
+ *
+ * @param tmpFile the File containing the output of the cvs rdiff command
+ * @return the entries in the output
+ * @exception BuildException if an error occurs
+ */
+ private CvsTagEntry[] parseRDiff(File tmpFile) throws BuildException {
+ // parse the output of the command
+ BufferedReader reader = null;
+
+ try {
+ reader = new BufferedReader(new FileReader(tmpFile));
+
+ // entries are of the form:
+ //CVS 1.11
+ // File module/filename is new; current revision 1.1
+ //CVS 1.11.9
+ // File module/filename is new; cvstag_2003_11_03_2 revision 1.1
+ // or
+ // File module/filename changed from revision 1.4 to 1.6
+ // or
+ // File module/filename is removed; not included in
+ // release tag SKINLF_12
+ //CVS 1.11.9
+ // File testantoine/antoine.bat is removed; TESTANTOINE_1 revision 1.1.1.1
+ //
+ // get rid of 'File module/"
+ Vector entries = new Vector();
+
+ String line = reader.readLine();
+
+ while (null != line) {
+ line = removePackageName(line, packageNamePrefixes,
+ packageNamePrefixLengths);
+ if (line != null) {
+ // use || in a perl like fashion
+ boolean processed
+ = doFileIsNew(entries, line)
+ || doFileHasChanged(entries, line)
+ || doFileWasRemoved(entries, line);
+ }
+ line = reader.readLine();
+ }
+
+ CvsTagEntry[] array = new CvsTagEntry[entries.size()];
+ entries.copyInto(array);
+
+ return array;
+ } catch (IOException e) {
+ throw new BuildException("Error in parsing", e);
+ } finally {
+ if (reader != null) {
+ try {
+ reader.close();
+ } catch (IOException e) {
+ log(e.toString(), Project.MSG_ERR);
+ }
+ }
+ }
+ }
+
+ private boolean doFileIsNew(Vector entries, String line) {
+ int index = line.indexOf(FILE_IS_NEW);
+ if (index == -1) {
+ return false;
+ }
+ // it is a new file
+ // set the revision but not the prevrevision
+ String filename = line.substring(0, index);
+ String rev = null;
+ int indexrev = line.indexOf(REVISION, index);
+ if (indexrev != -1) {
+ rev = line.substring(indexrev + REVISION.length());
+ }
+ CvsTagEntry entry = new CvsTagEntry(filename, rev);
+ entries.addElement(entry);
+ log(entry.toString(), Project.MSG_VERBOSE);
+ return true;
+ }
+
+ private boolean doFileHasChanged(Vector entries, String line) {
+ int index = line.indexOf(FILE_HAS_CHANGED);
+ if (index == -1) {
+ return false;
+ }
+ // it is a modified file
+ // set the revision and the prevrevision
+ String filename = line.substring(0, index);
+ int revSeparator = line.indexOf(" to ", index);
+ String prevRevision =
+ line.substring(index + FILE_HAS_CHANGED.length(),
+ revSeparator);
+ String revision = line.substring(revSeparator + TO_STRING.length());
+ CvsTagEntry entry = new CvsTagEntry(filename,
+ revision,
+ prevRevision);
+ entries.addElement(entry);
+ log(entry.toString(), Project.MSG_VERBOSE);
+ return true;
+ }
+
+ private boolean doFileWasRemoved(Vector entries, String line) {
+ if (ignoreRemoved) {
+ return false;
+ }
+ int index = line.indexOf(FILE_WAS_REMOVED);
+ if (index == -1) {
+ return false;
+ }
+ // it is a removed file
+ String filename = line.substring(0, index);
+ String rev = null;
+ int indexrev = line.indexOf(REVISION, index);
+ if (indexrev != -1) {
+ rev = line.substring(indexrev + REVISION.length());
+ }
+ CvsTagEntry entry = new CvsTagEntry(filename, null, rev);
+ entries.addElement(entry);
+ log(entry.toString(), Project.MSG_VERBOSE);
+ return true;
+ }
+
+ /**
+ * Write the rdiff log.
+ *
+ * @param entries a <code>CvsTagEntry[]</code> value
+ * @exception BuildException if an error occurs
+ */
+ private void writeTagDiff(CvsTagEntry[] entries) throws BuildException {
+ FileOutputStream output = null;
+ try {
+ output = new FileOutputStream(mydestfile);
+ PrintWriter writer = new PrintWriter(
+ new OutputStreamWriter(output, "UTF-8"));
+ writer.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
+ Document doc = DOMUtils.newDocument();
+ Element root = doc.createElement("tagdiff");
+ if (mystartTag != null) {
+ root.setAttribute("startTag", mystartTag);
+ } else {
+ root.setAttribute("startDate", mystartDate);
+ }
+ if (myendTag != null) {
+ root.setAttribute("endTag", myendTag);
+ } else {
+ root.setAttribute("endDate", myendDate);
+ }
+
+ root.setAttribute("cvsroot", getCvsRoot());
+ root.setAttribute("package",
+ CollectionUtils.flattenToString(packageNames));
+ DOM_WRITER.openElement(root, writer, 0, "\t");
+ writer.println();
+ for (int i = 0, c = entries.length; i < c; i++) {
+ writeTagEntry(doc, writer, entries[i]);
+ }
+ DOM_WRITER.closeElement(root, writer, 0, "\t", true);
+ writer.flush();
+ if (writer.checkError()) {
+ throw new IOException("Encountered an error writing tagdiff");
+ }
+ writer.close();
+ } catch (UnsupportedEncodingException uee) {
+ log(uee.toString(), Project.MSG_ERR);
+ } catch (IOException ioe) {
+ throw new BuildException(ioe.toString(), ioe);
+ } finally {
+ if (null != output) {
+ try {
+ output.close();
+ } catch (IOException ioe) {
+ log(ioe.toString(), Project.MSG_ERR);
+ }
+ }
+ }
+ }
+
+ /**
+ * Write a single entry to the given writer.
+ *
+ * @param doc Document used to create elements.
+ * @param writer a <code>PrintWriter</code> value
+ * @param entry a <code>CvsTagEntry</code> value
+ */
+ private void writeTagEntry(Document doc, PrintWriter writer,
+ CvsTagEntry entry)
+ throws IOException {
+ Element ent = doc.createElement("entry");
+ Element f = DOMUtils.createChildElement(ent, "file");
+ DOMUtils.appendCDATAElement(f, "name", entry.getFile());
+ if (entry.getRevision() != null) {
+ DOMUtils.appendTextElement(f, "revision", entry.getRevision());
+ }
+ if (entry.getPreviousRevision() != null) {
+ DOMUtils.appendTextElement(f, "prevrevision",
+ entry.getPreviousRevision());
+ }
+ DOM_WRITER.write(ent, writer, 1, "\t");
+ }
+
+ /**
+ * Validate the parameters specified for task.
+ *
+ * @exception BuildException if a parameter is not correctly set
+ */
+ private void validate() throws BuildException {
+ if (null == mypackage && getModules().size() == 0) {
+ throw new BuildException("Package/module must be set.");
+ }
+
+ if (null == mydestfile) {
+ throw new BuildException("Destfile must be set.");
+ }
+
+ if (null == mystartTag && null == mystartDate) {
+ throw new BuildException("Start tag or start date must be set.");
+ }
+
+ if (null != mystartTag && null != mystartDate) {
+ throw new BuildException("Only one of start tag and start date "
+ + "must be set.");
+ }
+
+ if (null == myendTag && null == myendDate) {
+ throw new BuildException("End tag or end date must be set.");
+ }
+
+ if (null != myendTag && null != myendDate) {
+ throw new BuildException("Only one of end tag and end date must "
+ + "be set.");
+ }
+ }
+
+ /**
+ * collects package names from the package attribute and nested
+ * module elements.
+ */
+ private void handlePackageNames() {
+ if (mypackage != null) {
+ // support multiple packages
+ StringTokenizer myTokenizer = new StringTokenizer(mypackage);
+ while (myTokenizer.hasMoreTokens()) {
+ String pack = myTokenizer.nextToken();
+ packageNames.add(pack);
+ addCommandArgument(pack);
+ }
+ }
+ for (Iterator iter = getModules().iterator(); iter.hasNext();) {
+ AbstractCvsTask.Module m = (AbstractCvsTask.Module) iter.next();
+ packageNames.add(m.getName());
+ // will be added to command line in super.execute()
+ }
+ packageNamePrefixes = new String[packageNames.size()];
+ packageNamePrefixLengths = new int[packageNames.size()];
+ for (int i = 0; i < packageNamePrefixes.length; i++) {
+ packageNamePrefixes[i] = FILE_STRING + packageNames.get(i) + "/";
+ packageNamePrefixLengths[i] = packageNamePrefixes[i].length();
+ }
+ }
+
+
+ /**
+ * removes a "File: module/" prefix if present.
+ *
+ * @return null if the line was shorter than expected.
+ */
+ private static String removePackageName(String line,
+ String[] packagePrefixes,
+ int[] prefixLengths) {
+ if (line.length() < FILE_STRING_LENGTH) {
+ return null;
+ }
+ boolean matched = false;
+ for (int i = 0; i < packagePrefixes.length; i++) {
+ if (line.startsWith(packagePrefixes[i])) {
+ matched = true;
+ line = line.substring(prefixLengths[i]);
+ break;
+ }
+ }
+ if (!matched) {
+ line = line.substring(FILE_STRING_LENGTH);
+ }
+ return line;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/cvslib/CvsTagEntry.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/cvslib/CvsTagEntry.java
new file mode 100644
index 00000000..6e349c7d
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/cvslib/CvsTagEntry.java
@@ -0,0 +1,109 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.cvslib;
+
+/**
+ * Holds the information of a line of rdiff
+ */
+public class CvsTagEntry {
+
+ /** the filename */
+ private String filename;
+
+ /** the previous revision */
+ private String prevRevision;
+
+ /** the revision */
+ private String revision;
+
+ /**
+ * Creates a new CvsTagEntry
+ * @param filename the filename to add
+ */
+ public CvsTagEntry(final String filename) {
+ this(filename, null, null);
+ }
+
+ /**
+ * Creates a new CvsTagEntry
+ * @param filename the filename to add
+ * @param revision the revision
+ */
+ public CvsTagEntry(final String filename, final String revision) {
+ this(filename, revision, null);
+ }
+
+ /**
+ * Creates a new CvsTagEntry
+ * @param filename the filename to add
+ * @param revision the revision
+ * @param prevRevision the previous revision
+ */
+ public CvsTagEntry(final String filename, final String revision,
+ final String prevRevision) {
+ this.filename = filename;
+ this.revision = revision;
+ this.prevRevision = prevRevision;
+ }
+
+ /**
+ * Gets the filename for this CvsTagEntry
+ * @return the filename
+ */
+ public String getFile() {
+ return filename;
+ }
+
+ /**
+ * Gets the revision for this CvsTagEntry
+ * @return the revision
+ */
+ public String getRevision() {
+ return revision;
+ }
+
+ /**
+ * Gets the previous revision for this CvsTagEntry
+ * @return the previous revision
+ */
+ public String getPreviousRevision() {
+ return prevRevision;
+ }
+
+ /**
+ * Gets a String containing filename and difference from previous version
+ * @return a string representation of this CVSTagEntry
+ */
+ public String toString() {
+ StringBuffer buffer = new StringBuffer();
+ buffer.append(filename);
+ if (revision == null) {
+ buffer.append(" was removed");
+ if (prevRevision != null) {
+ buffer.append("; previous revision was ").append(prevRevision);
+ }
+ } else if (prevRevision == null) {
+ buffer.append(" is new; current revision is ")
+ .append(revision);
+ } else {
+ buffer.append(" has changed from ")
+ .append(prevRevision).append(" to ").append(revision);
+ }
+ return buffer.toString();
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/cvslib/CvsUser.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/cvslib/CvsUser.java
new file mode 100644
index 00000000..85a2fc6b
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/cvslib/CvsUser.java
@@ -0,0 +1,93 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.cvslib;
+
+import org.apache.tools.ant.BuildException;
+
+/**
+ * Represents a CVS user with a userID and a full name.
+ *
+ */
+public class CvsUser {
+ /** The user's Id */
+ private String userID;
+ /** The user's full name */
+ private String displayName;
+
+
+ /**
+ * Set the user's fullname
+ *
+ * @param displayName the user's full name
+ */
+ public void setDisplayname(final String displayName) {
+ this.displayName = displayName;
+ }
+
+
+ /**
+ * Set the user's id
+ *
+ * @param userID the user's new id value.
+ */
+ public void setUserid(final String userID) {
+ this.userID = userID;
+ }
+
+
+ /**
+ * Get the user's id.
+ *
+ * @return The userID value
+ */
+ public String getUserID() {
+ return userID;
+ }
+
+
+ /**
+ * Get the user's full name
+ *
+ * @return the user's full name
+ */
+ public String getDisplayname() {
+ return displayName;
+ }
+
+
+ /**
+ * Validate that this object is configured.
+ *
+ * @exception BuildException if the instance has not be correctly
+ * configured.
+ */
+ public void validate() throws BuildException {
+ if (null == userID) {
+ final String message = "Username attribute must be set.";
+
+ throw new BuildException(message);
+ }
+ if (null == displayName) {
+ final String message =
+ "Displayname attribute must be set for userID " + userID;
+
+ throw new BuildException(message);
+ }
+ }
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/cvslib/CvsVersion.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/cvslib/CvsVersion.java
new file mode 100644
index 00000000..618da4ec
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/cvslib/CvsVersion.java
@@ -0,0 +1,169 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.cvslib;
+
+import java.io.ByteArrayOutputStream;
+import java.util.StringTokenizer;
+
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.AbstractCvsTask;
+
+/**
+ * this task allows to find out the client and the server version of a
+ * CVS installation
+ *
+ * example usage :
+ * &lt;cvsversion
+ * cvsRoot=&quot;:pserver:anoncvs@cvs.apache.org:/home/cvspublic&quot;
+ * passfile=&quot;c:/programme/cygwin/home/antoine/.cvspass&quot;
+ * clientversionproperty=&quot;apacheclient&quot;
+ * serverversionproperty=&quot;apacheserver&quot; /&gt;
+ *
+ * the task can be used also in the API by calling its execute method,
+ * then calling getServerVersion and/or getClientVersion
+ *
+ * @ant.task category="scm"
+ * @since ant 1.6.1
+ */
+public class CvsVersion extends AbstractCvsTask {
+ static final long VERSION_1_11_2 = 11102;
+ static final long MULTIPLY = 100;
+ private String clientVersion;
+ private String serverVersion;
+ private String clientVersionProperty;
+ private String serverVersionProperty;
+
+ /**
+ * Get the CVS client version
+ * @return CVS client version
+ */
+ public String getClientVersion() {
+ return clientVersion;
+ }
+ /**
+ * Get the CVS server version
+ * @return CVS server version
+ */
+ public String getServerVersion() {
+ return serverVersion;
+ }
+ /**
+ * Set a property where to store the CVS client version
+ * @param clientVersionProperty property for CVS client version
+ */
+ public void setClientVersionProperty(String clientVersionProperty) {
+ this.clientVersionProperty = clientVersionProperty;
+ }
+
+ /**
+ * Set a property where to store the CVS server version
+ * @param serverVersionProperty property for CVS server version
+ */
+ public void setServerVersionProperty(String serverVersionProperty) {
+ this.serverVersionProperty = serverVersionProperty;
+ }
+ /**
+ * Find out if the server version supports log with S option
+ * @return boolean indicating if the server version supports log with S option
+ */
+ public boolean supportsCvsLogWithSOption() {
+ if (serverVersion == null) {
+ return false;
+ }
+ StringTokenizer tokenizer = new StringTokenizer(serverVersion, ".");
+ long counter = MULTIPLY * MULTIPLY;
+ long version = 0;
+ while (tokenizer.hasMoreTokens()) {
+ String s = tokenizer.nextToken();
+ int i = 0;
+ for (i = 0; i < s.length(); i++) {
+ if (!Character.isDigit(s.charAt(i))) {
+ break;
+ }
+ }
+ String s2 = s.substring(0, i);
+ version = version + counter * Long.parseLong(s2);
+ if (counter == 1) {
+ break;
+ }
+ counter = counter / MULTIPLY;
+ }
+ return (version >= VERSION_1_11_2);
+ }
+ /**
+ * the execute method running CvsVersion
+ */
+ public void execute() {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ this.setOutputStream(bos);
+ ByteArrayOutputStream berr = new ByteArrayOutputStream();
+ this.setErrorStream(berr);
+ setCommand("version");
+ super.execute();
+ String output = bos.toString();
+ log("Received version response \"" + output + "\"",
+ Project.MSG_DEBUG);
+ StringTokenizer st = new StringTokenizer(output);
+ boolean client = false;
+ boolean server = false;
+ String cvs = null;
+ String cachedVersion = null;
+ boolean haveReadAhead = false;
+ while (haveReadAhead || st.hasMoreTokens()) {
+ String currentToken = haveReadAhead ? cachedVersion : st.nextToken();
+ haveReadAhead = false;
+ if (currentToken.equals("Client:")) {
+ client = true;
+ } else if (currentToken.equals("Server:")) {
+ server = true;
+ } else if (currentToken.startsWith("(CVS")
+ && currentToken.endsWith(")")) {
+ cvs = currentToken.length() == 5 ? "" : " " + currentToken;
+ }
+ if (!client && !server && cvs != null
+ && cachedVersion == null && st.hasMoreTokens()) {
+ cachedVersion = st.nextToken();
+ haveReadAhead = true;
+ } else if (client && cvs != null) {
+ if (st.hasMoreTokens()) {
+ clientVersion = st.nextToken() + cvs;
+ }
+ client = false;
+ cvs = null;
+ } else if (server && cvs != null) {
+ if (st.hasMoreTokens()) {
+ serverVersion = st.nextToken() + cvs;
+ }
+ server = false;
+ cvs = null;
+ } else if (currentToken.equals("(client/server)")
+ && cvs != null && cachedVersion != null
+ && !client && !server) {
+ client = server = true;
+ clientVersion = serverVersion = cachedVersion + cvs;
+ cachedVersion = cvs = null;
+ }
+ }
+ if (clientVersionProperty != null) {
+ getProject().setNewProperty(clientVersionProperty, clientVersion);
+ }
+ if (serverVersionProperty != null) {
+ getProject().setNewProperty(serverVersionProperty, serverVersion);
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/cvslib/RCSFile.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/cvslib/RCSFile.java
new file mode 100644
index 00000000..70a8cf36
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/cvslib/RCSFile.java
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.cvslib;
+
+/**
+ * Represents a RCS File change.
+ *
+ */
+class RCSFile {
+ private String name;
+ private String revision;
+ private String previousRevision;
+
+
+ RCSFile(final String name, final String rev) {
+ this(name, rev, null);
+ }
+
+
+ RCSFile(final String name,
+ final String revision,
+ final String previousRevision) {
+ this.name = name;
+ this.revision = revision;
+ if (!revision.equals(previousRevision)) {
+ this.previousRevision = previousRevision;
+ }
+ }
+
+ /**
+ * Gets the name of the RCSFile
+ * @return name of the file
+ */
+ String getName() {
+ return name;
+ }
+
+ /**
+ * Gets the revision number of the RCSFile
+ * @return the revision number (as String)
+ */
+ String getRevision() {
+ return revision;
+ }
+
+ /**
+ * Gets the previous revision of the RCSFile
+ * @return the previous revision number (as String)
+ */
+ String getPreviousRevision() {
+ return previousRevision;
+ }
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/cvslib/RedirectingOutputStream.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/cvslib/RedirectingOutputStream.java
new file mode 100644
index 00000000..f2b61cf9
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/cvslib/RedirectingOutputStream.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.cvslib;
+
+import org.apache.tools.ant.util.LineOrientedOutputStream;
+
+/**
+ * A dummy stream that just passes stuff to the parser.
+ */
+class RedirectingOutputStream extends LineOrientedOutputStream {
+ private final ChangeLogParser parser;
+
+ /**
+ * Creates a new instance of this class.
+ *
+ * @param parser the parser to which output is sent.
+ */
+ public RedirectingOutputStream(final ChangeLogParser parser) {
+ this.parser = parser;
+ }
+
+ /**
+ * Logs a line to the log system of ant.
+ *
+ * @param line the line to log.
+ */
+ protected void processLine(final String line) {
+ parser.stdout(line);
+ }
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/cvslib/RedirectingStreamHandler.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/cvslib/RedirectingStreamHandler.java
new file mode 100644
index 00000000..713de0c4
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/cvslib/RedirectingStreamHandler.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.cvslib;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.taskdefs.PumpStreamHandler;
+
+/**
+ * A dummy stream handler that just passes stuff to the parser.
+ *
+ */
+class RedirectingStreamHandler
+ extends PumpStreamHandler {
+ RedirectingStreamHandler(final ChangeLogParser parser) {
+ super(new RedirectingOutputStream(parser),
+ new ByteArrayOutputStream());
+ }
+
+
+ String getErrors() {
+ try {
+ final ByteArrayOutputStream error
+ = (ByteArrayOutputStream) getErr();
+
+ return error.toString("ASCII");
+ } catch (final Exception e) {
+ return null;
+ }
+ }
+
+
+ public void stop() {
+ super.stop();
+ try {
+ getErr().close();
+ getOut().close();
+ } catch (final IOException e) {
+ // plain impossible
+ throw new BuildException(e);
+ }
+ }
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/defaults.properties b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/defaults.properties
new file mode 100644
index 00000000..9cf1499f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/defaults.properties
@@ -0,0 +1,210 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# standard ant tasks
+ant=org.apache.tools.ant.taskdefs.Ant
+antcall=org.apache.tools.ant.taskdefs.CallTarget
+antstructure=org.apache.tools.ant.taskdefs.AntStructure
+antversion=org.apache.tools.ant.taskdefs.condition.AntVersion
+apply=org.apache.tools.ant.taskdefs.Transform
+apt=org.apache.tools.ant.taskdefs.Apt
+attributenamespacedef=org.apache.tools.ant.taskdefs.AttributeNamespaceDef
+augment=org.apache.tools.ant.taskdefs.AugmentReference
+available=org.apache.tools.ant.taskdefs.Available
+basename=org.apache.tools.ant.taskdefs.Basename
+bindtargets=org.apache.tools.ant.taskdefs.BindTargets
+buildnumber=org.apache.tools.ant.taskdefs.BuildNumber
+bunzip2=org.apache.tools.ant.taskdefs.BUnzip2
+bzip2=org.apache.tools.ant.taskdefs.BZip2
+checksum=org.apache.tools.ant.taskdefs.Checksum
+chmod=org.apache.tools.ant.taskdefs.Chmod
+classloader=org.apache.tools.ant.taskdefs.Classloader
+commandlauncher=org.apache.tools.ant.taskdefs.CommandLauncherTask
+componentdef=org.apache.tools.ant.taskdefs.Componentdef
+concat=org.apache.tools.ant.taskdefs.Concat
+condition=org.apache.tools.ant.taskdefs.ConditionTask
+copy=org.apache.tools.ant.taskdefs.Copy
+cvs=org.apache.tools.ant.taskdefs.Cvs
+cvschangelog=org.apache.tools.ant.taskdefs.cvslib.ChangeLogTask
+cvspass=org.apache.tools.ant.taskdefs.CVSPass
+cvstagdiff=org.apache.tools.ant.taskdefs.cvslib.CvsTagDiff
+cvsversion=org.apache.tools.ant.taskdefs.cvslib.CvsVersion
+defaultexcludes=org.apache.tools.ant.taskdefs.DefaultExcludes
+delete=org.apache.tools.ant.taskdefs.Delete
+dependset=org.apache.tools.ant.taskdefs.DependSet
+diagnostics=org.apache.tools.ant.taskdefs.DiagnosticsTask
+dirname=org.apache.tools.ant.taskdefs.Dirname
+ear=org.apache.tools.ant.taskdefs.Ear
+echo=org.apache.tools.ant.taskdefs.Echo
+echoproperties=org.apache.tools.ant.taskdefs.optional.EchoProperties
+echoxml=org.apache.tools.ant.taskdefs.EchoXML
+exec=org.apache.tools.ant.taskdefs.ExecTask
+fail=org.apache.tools.ant.taskdefs.Exit
+filter=org.apache.tools.ant.taskdefs.Filter
+fixcrlf=org.apache.tools.ant.taskdefs.FixCRLF
+#funtest=org.apache.tools.ant.taskdefs.optional.testing.Funtest
+genkey=org.apache.tools.ant.taskdefs.GenerateKey
+get=org.apache.tools.ant.taskdefs.Get
+gunzip=org.apache.tools.ant.taskdefs.GUnzip
+gzip=org.apache.tools.ant.taskdefs.GZip
+hostinfo=org.apache.tools.ant.taskdefs.HostInfo
+import=org.apache.tools.ant.taskdefs.ImportTask
+include=org.apache.tools.ant.taskdefs.ImportTask
+input=org.apache.tools.ant.taskdefs.Input
+jar=org.apache.tools.ant.taskdefs.Jar
+java=org.apache.tools.ant.taskdefs.Java
+javac=org.apache.tools.ant.taskdefs.Javac
+javadoc=org.apache.tools.ant.taskdefs.Javadoc
+length=org.apache.tools.ant.taskdefs.Length
+loadfile=org.apache.tools.ant.taskdefs.LoadFile
+loadproperties=org.apache.tools.ant.taskdefs.LoadProperties
+loadresource=org.apache.tools.ant.taskdefs.LoadResource
+local=org.apache.tools.ant.taskdefs.Local
+macrodef=org.apache.tools.ant.taskdefs.MacroDef
+mail=org.apache.tools.ant.taskdefs.email.EmailTask
+makeurl=org.apache.tools.ant.taskdefs.MakeUrl
+manifest=org.apache.tools.ant.taskdefs.ManifestTask
+manifestclasspath=org.apache.tools.ant.taskdefs.ManifestClassPath
+mkdir=org.apache.tools.ant.taskdefs.Mkdir
+move=org.apache.tools.ant.taskdefs.Move
+nice=org.apache.tools.ant.taskdefs.Nice
+parallel=org.apache.tools.ant.taskdefs.Parallel
+patch=org.apache.tools.ant.taskdefs.Patch
+pathconvert=org.apache.tools.ant.taskdefs.PathConvert
+presetdef=org.apache.tools.ant.taskdefs.PreSetDef
+projecthelper=org.apache.tools.ant.taskdefs.ProjectHelperTask
+property=org.apache.tools.ant.taskdefs.Property
+propertyhelper=org.apache.tools.ant.taskdefs.PropertyHelperTask
+record=org.apache.tools.ant.taskdefs.Recorder
+replace=org.apache.tools.ant.taskdefs.Replace
+resourcecount=org.apache.tools.ant.taskdefs.ResourceCount
+retry=org.apache.tools.ant.taskdefs.Retry
+rmic=org.apache.tools.ant.taskdefs.Rmic
+sequential=org.apache.tools.ant.taskdefs.Sequential
+signjar=org.apache.tools.ant.taskdefs.SignJar
+sleep=org.apache.tools.ant.taskdefs.Sleep
+sql=org.apache.tools.ant.taskdefs.SQLExec
+subant=org.apache.tools.ant.taskdefs.SubAnt
+sync=org.apache.tools.ant.taskdefs.Sync
+tar=org.apache.tools.ant.taskdefs.Tar
+taskdef=org.apache.tools.ant.taskdefs.Taskdef
+tempfile=org.apache.tools.ant.taskdefs.TempFile
+touch=org.apache.tools.ant.taskdefs.Touch
+tstamp=org.apache.tools.ant.taskdefs.Tstamp
+truncate=org.apache.tools.ant.taskdefs.Truncate
+typedef=org.apache.tools.ant.taskdefs.Typedef
+unjar=org.apache.tools.ant.taskdefs.Expand
+untar=org.apache.tools.ant.taskdefs.Untar
+unwar=org.apache.tools.ant.taskdefs.Expand
+unzip=org.apache.tools.ant.taskdefs.Expand
+uptodate=org.apache.tools.ant.taskdefs.UpToDate
+waitfor=org.apache.tools.ant.taskdefs.WaitFor
+war=org.apache.tools.ant.taskdefs.War
+whichresource=org.apache.tools.ant.taskdefs.WhichResource
+xmlproperty=org.apache.tools.ant.taskdefs.XmlProperty
+xslt=org.apache.tools.ant.taskdefs.XSLTProcess
+zip=org.apache.tools.ant.taskdefs.Zip
+
+# optional tasks
+antlr=org.apache.tools.ant.taskdefs.optional.ANTLR
+attrib=org.apache.tools.ant.taskdefs.optional.windows.Attrib
+blgenclient=org.apache.tools.ant.taskdefs.optional.ejb.BorlandGenerateClient
+cab=org.apache.tools.ant.taskdefs.optional.Cab
+cccheckin=org.apache.tools.ant.taskdefs.optional.clearcase.CCCheckin
+cccheckout=org.apache.tools.ant.taskdefs.optional.clearcase.CCCheckout
+cclock=org.apache.tools.ant.taskdefs.optional.clearcase.CCLock
+ccmcheckin=org.apache.tools.ant.taskdefs.optional.ccm.CCMCheckin
+ccmcheckintask=org.apache.tools.ant.taskdefs.optional.ccm.CCMCheckinDefault
+ccmcheckout=org.apache.tools.ant.taskdefs.optional.ccm.CCMCheckout
+ccmcreatetask=org.apache.tools.ant.taskdefs.optional.ccm.CCMCreateTask
+ccmkattr=org.apache.tools.ant.taskdefs.optional.clearcase.CCMkattr
+ccmkbl=org.apache.tools.ant.taskdefs.optional.clearcase.CCMkbl
+ccmkdir=org.apache.tools.ant.taskdefs.optional.clearcase.CCMkdir
+ccmkelem=org.apache.tools.ant.taskdefs.optional.clearcase.CCMkelem
+ccmklabel=org.apache.tools.ant.taskdefs.optional.clearcase.CCMklabel
+ccmklbtype=org.apache.tools.ant.taskdefs.optional.clearcase.CCMklbtype
+ccmreconfigure=org.apache.tools.ant.taskdefs.optional.ccm.CCMReconfigure
+ccrmtype=org.apache.tools.ant.taskdefs.optional.clearcase.CCRmtype
+ccuncheckout=org.apache.tools.ant.taskdefs.optional.clearcase.CCUnCheckout
+ccunlock=org.apache.tools.ant.taskdefs.optional.clearcase.CCUnlock
+ccupdate=org.apache.tools.ant.taskdefs.optional.clearcase.CCUpdate
+chgrp=org.apache.tools.ant.taskdefs.optional.unix.Chgrp
+chown=org.apache.tools.ant.taskdefs.optional.unix.Chown
+depend=org.apache.tools.ant.taskdefs.optional.depend.Depend
+ejbjar=org.apache.tools.ant.taskdefs.optional.ejb.EjbJar
+ftp=org.apache.tools.ant.taskdefs.optional.net.FTP
+image=org.apache.tools.ant.taskdefs.optional.image.Image
+iplanet-ejbc=org.apache.tools.ant.taskdefs.optional.ejb.IPlanetEjbcTask
+jarlib-available=org.apache.tools.ant.taskdefs.optional.extension.JarLibAvailableTask
+jarlib-display=org.apache.tools.ant.taskdefs.optional.extension.JarLibDisplayTask
+jarlib-manifest=org.apache.tools.ant.taskdefs.optional.extension.JarLibManifestTask
+jarlib-resolve=org.apache.tools.ant.taskdefs.optional.extension.JarLibResolveTask
+javacc=org.apache.tools.ant.taskdefs.optional.javacc.JavaCC
+javah=org.apache.tools.ant.taskdefs.optional.Javah
+jdepend=org.apache.tools.ant.taskdefs.optional.jdepend.JDependTask
+jjdoc=org.apache.tools.ant.taskdefs.optional.javacc.JJDoc
+jjtree=org.apache.tools.ant.taskdefs.optional.javacc.JJTree
+junit=org.apache.tools.ant.taskdefs.optional.junit.JUnitTask
+junitreport=org.apache.tools.ant.taskdefs.optional.junit.XMLResultAggregator
+native2ascii=org.apache.tools.ant.taskdefs.optional.Native2Ascii
+netrexxc=org.apache.tools.ant.taskdefs.optional.NetRexxC
+propertyfile=org.apache.tools.ant.taskdefs.optional.PropertyFile
+pvcs=org.apache.tools.ant.taskdefs.optional.pvcs.Pvcs
+replaceregexp=org.apache.tools.ant.taskdefs.optional.ReplaceRegExp
+rexec=org.apache.tools.ant.taskdefs.optional.net.RExecTask
+rpm=org.apache.tools.ant.taskdefs.optional.Rpm
+schemavalidate=org.apache.tools.ant.taskdefs.optional.SchemaValidate
+scp=org.apache.tools.ant.taskdefs.optional.ssh.Scp
+script=org.apache.tools.ant.taskdefs.optional.Script
+scriptdef=org.apache.tools.ant.taskdefs.optional.script.ScriptDef
+serverdeploy=org.apache.tools.ant.taskdefs.optional.j2ee.ServerDeploy
+setproxy=org.apache.tools.ant.taskdefs.optional.net.SetProxy
+soscheckin=org.apache.tools.ant.taskdefs.optional.sos.SOSCheckin
+soscheckout=org.apache.tools.ant.taskdefs.optional.sos.SOSCheckout
+sosget=org.apache.tools.ant.taskdefs.optional.sos.SOSGet
+soslabel=org.apache.tools.ant.taskdefs.optional.sos.SOSLabel
+sound=org.apache.tools.ant.taskdefs.optional.sound.SoundTask
+splash=org.apache.tools.ant.taskdefs.optional.splash.SplashTask
+sshexec=org.apache.tools.ant.taskdefs.optional.ssh.SSHExec
+sshsession=org.apache.tools.ant.taskdefs.optional.ssh.SSHSession
+symlink=org.apache.tools.ant.taskdefs.optional.unix.Symlink
+telnet=org.apache.tools.ant.taskdefs.optional.net.TelnetTask
+translate=org.apache.tools.ant.taskdefs.optional.i18n.Translate
+verifyjar=org.apache.tools.ant.taskdefs.VerifyJar
+vssadd=org.apache.tools.ant.taskdefs.optional.vss.MSVSSADD
+vsscheckin=org.apache.tools.ant.taskdefs.optional.vss.MSVSSCHECKIN
+vsscheckout=org.apache.tools.ant.taskdefs.optional.vss.MSVSSCHECKOUT
+vsscp=org.apache.tools.ant.taskdefs.optional.vss.MSVSSCP
+vsscreate=org.apache.tools.ant.taskdefs.optional.vss.MSVSSCREATE
+vssget=org.apache.tools.ant.taskdefs.optional.vss.MSVSSGET
+vsshistory=org.apache.tools.ant.taskdefs.optional.vss.MSVSSHISTORY
+vsslabel=org.apache.tools.ant.taskdefs.optional.vss.MSVSSLABEL
+wljspc=org.apache.tools.ant.taskdefs.optional.jsp.WLJspc
+xmlvalidate=org.apache.tools.ant.taskdefs.optional.XMLValidateTask
+
+
+# deprecated ant tasks (kept for back compatibility)
+copydir=org.apache.tools.ant.taskdefs.Copydir
+copyfile=org.apache.tools.ant.taskdefs.Copyfile
+copypath=org.apache.tools.ant.taskdefs.CopyPath
+deltree=org.apache.tools.ant.taskdefs.Deltree
+execon=org.apache.tools.ant.taskdefs.ExecuteOn
+javadoc2=org.apache.tools.ant.taskdefs.Javadoc
+jlink=org.apache.tools.ant.taskdefs.optional.jlink.JlinkTask
+jspc=org.apache.tools.ant.taskdefs.optional.jsp.JspC
+mimemail=org.apache.tools.ant.taskdefs.optional.net.MimeMail
+rename=org.apache.tools.ant.taskdefs.Rename
+renameext=org.apache.tools.ant.taskdefs.optional.RenameExtensions
+style=org.apache.tools.ant.taskdefs.XSLTProcess
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/email/EmailAddress.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/email/EmailAddress.java
new file mode 100644
index 00000000..edc9c9dc
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/email/EmailAddress.java
@@ -0,0 +1,197 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.email;
+
+/**
+ * Holds an email address.
+ *
+ * @since Ant 1.5
+ */
+public class EmailAddress {
+ private String name;
+ private String address;
+
+
+ /** Creates an empty email address */
+ public EmailAddress() {
+ }
+
+
+ /**
+ * Creates a new email address based on the given string
+ *
+ * @param email the email address (with or without &lt;&gt;)
+ * Acceptable forms include:
+ * address
+ * &lt;address&gt;
+ * name &lt;address&gt;
+ * &lt;address&gt; name
+ * (name) address
+ * address (name)
+ */
+ // Make a limited attempt to extract a sanitized name and email address
+ // Algorithm based on the one found in Ant's MailMessage.java
+ public EmailAddress(String email) {
+ final int minLen = 9;
+ int len = email.length();
+
+ // shortcut for "<address>"
+ if (len > minLen) {
+ if ((email.charAt(0) == '<' || email.charAt(1) == '<')
+ && (email.charAt(len - 1) == '>' || email.charAt(len - 2) == '>')) {
+ this.address = trim(email, true);
+ return;
+ }
+ }
+
+ int paramDepth = 0;
+ int start = 0;
+ int end = 0;
+ int nStart = 0;
+ int nEnd = 0;
+
+ for (int i = 0; i < len; i++) {
+ char c = email.charAt(i);
+ if (c == '(') {
+ paramDepth++;
+ if (start == 0) {
+ end = i; // support "address (name)"
+ nStart = i + 1;
+ }
+ } else if (c == ')') {
+ paramDepth--;
+ if (end == 0) {
+ start = i + 1; // support "(name) address"
+ nEnd = i;
+ }
+ } else if (paramDepth == 0 && c == '<') {
+ if (start == 0) {
+ nEnd = i;
+ }
+ start = i + 1;
+ } else if (paramDepth == 0 && c == '>') {
+ end = i;
+ if (end != len - 1) {
+ nStart = i + 1;
+ }
+ }
+ }
+
+ // DEBUG: System.out.println( email );
+ if (end == 0) {
+ end = len;
+ }
+ // DEBUG: System.out.println( "address: " + start + " " + end );
+ if (nEnd == 0) {
+ nEnd = len;
+ }
+ // DEBUG: System.out.println( "name: " + nStart + " " + nEnd );
+
+ this.address = trim(email.substring(start, end), true);
+ this.name = trim(email.substring(nStart, nEnd), false);
+
+ // if the two substrings are longer than the original, then name
+ // contains address - so reset the name to null
+ if (this.name.length() + this.address.length() > len) {
+ this.name = null;
+ }
+ }
+
+ /**
+ * A specialised trim() that trims whitespace,
+ * '(', ')', '"', '<', '>' from the start and end of strings
+ */
+ private String trim(String t, boolean trimAngleBrackets) {
+ int start = 0;
+ int end = t.length();
+ boolean trim = false;
+ do {
+ trim = false;
+ if (t.charAt(end - 1) == ')'
+ || (t.charAt(end - 1) == '>' && trimAngleBrackets)
+ || (t.charAt(end - 1) == '"' && t.charAt(end - 2) != '\\')
+ || t.charAt(end - 1) <= '\u0020') {
+ trim = true;
+ end--;
+ }
+ if (t.charAt(start) == '('
+ || (t.charAt(start) == '<' && trimAngleBrackets)
+ || t.charAt(start) == '"'
+ || t.charAt(start) <= '\u0020') {
+ trim = true;
+ start++;
+ }
+ } while (trim);
+ return t.substring(start, end);
+ }
+
+
+ /**
+ * Sets the personal / display name of the address.
+ *
+ * @param name the display name
+ */
+ public void setName(String name) {
+ this.name = name;
+ }
+
+
+ /**
+ * Sets the email address.
+ *
+ * @param address the actual email address (without &lt;&gt;)
+ */
+ public void setAddress(String address) {
+ this.address = address;
+ }
+
+
+ /**
+ * Constructs a string "name &lt;address&gt;" or "address"
+ *
+ * @return a string representation of the address
+ */
+ public String toString() {
+ if (name == null) {
+ return address;
+ } else {
+ return name + " <" + address + ">";
+ }
+ }
+
+
+ /**
+ * Returns the address
+ *
+ * @return the address part
+ */
+ public String getAddress() {
+ return address;
+ }
+
+
+ /**
+ * Returns the display name
+ *
+ * @return the display name part
+ */
+ public String getName() {
+ return name;
+ }
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/email/EmailTask.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/email/EmailTask.java
new file mode 100644
index 00000000..0a5bc681
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/email/EmailTask.java
@@ -0,0 +1,634 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.email;
+
+import java.io.File;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.types.EnumeratedAttribute;
+import org.apache.tools.ant.types.FileSet;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.resources.FileProvider;
+import org.apache.tools.ant.types.resources.FileResource;
+import org.apache.tools.ant.util.ClasspathUtils;
+
+/**
+ * A task to send SMTP email. This is a refactoring of the SendMail and
+ * MimeMail tasks such that both are within a single task.
+ *
+ * @since Ant 1.5
+ * @ant.task name="mail" category="network"
+ */
+public class EmailTask extends Task {
+ private static final int SMTP_PORT = 25;
+
+ /** Constant to show that the best available mailer should be used. */
+ public static final String AUTO = "auto";
+ /** Constant to allow the Mime mailer to be requested */
+ public static final String MIME = "mime";
+ /** Constant to allow the UU mailer to be requested */
+ public static final String UU = "uu";
+ /** Constant to allow the plaintext mailer to be requested */
+ public static final String PLAIN = "plain";
+
+ /**
+ * Enumerates the encoding constants.
+ */
+ public static class Encoding extends EnumeratedAttribute {
+ /**
+ * finds the valid encoding values
+ *
+ * @return a list of valid entries
+ */
+ public String[] getValues() {
+ return new String[] {AUTO, MIME, UU, PLAIN};
+ }
+ }
+
+ private String encoding = AUTO;
+ /** host running SMTP */
+ private String host = "localhost";
+ private Integer port = null;
+ /** subject field */
+ private String subject = null;
+ /** any text */
+ private Message message = null;
+ /** failure flag */
+ private boolean failOnError = true;
+ private boolean includeFileNames = false;
+ private String messageMimeType = null;
+ private String messageFileInputEncoding;
+ /* special headers */
+ /** sender */
+ private EmailAddress from = null;
+ /** replyto */
+ private Vector replyToList = new Vector();
+ /** TO recipients */
+ private Vector toList = new Vector();
+ /** CC (Carbon Copy) recipients */
+ private Vector ccList = new Vector();
+ /** BCC (Blind Carbon Copy) recipients */
+ private Vector bccList = new Vector();
+
+ /** generic headers */
+ private Vector headers = new Vector();
+
+ /** file list */
+ private Path attachments = null;
+ /** Character set for MimeMailer*/
+ private String charset = null;
+ /** User for SMTP auth */
+ private String user = null;
+ /** Password for SMTP auth */
+ private String password = null;
+ /** indicate if the user wishes SSL-TLS */
+ private boolean ssl = false;
+ /** indicate if the user wishes support for STARTTLS */
+ private boolean starttls = false;
+
+ /** ignore invalid recipients? */
+ private boolean ignoreInvalidRecipients = false;
+
+ /**
+ * Set the user for SMTP auth; this requires JavaMail.
+ * @param user the String username.
+ * @since Ant 1.6
+ */
+ public void setUser(String user) {
+ this.user = user;
+ }
+
+ /**
+ * Set the password for SMTP auth; this requires JavaMail.
+ * @param password the String password.
+ * @since Ant 1.6
+ */
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ /**
+ * Set whether to send data over SSL.
+ * @param ssl boolean; if true SSL will be used.
+ * @since Ant 1.6
+ */
+ public void setSSL(boolean ssl) {
+ this.ssl = ssl;
+ }
+
+ /**
+ * Set whether to allow authentication to switch to a TLS
+ * connection via STARTTLS.
+ * @param b boolean; if true STARTTLS will be supported.
+ * @since Ant 1.8.0
+ */
+ public void setEnableStartTLS(boolean b) {
+ this.starttls = b;
+ }
+
+ /**
+ * Set the preferred encoding method.
+ *
+ * @param encoding The encoding (one of AUTO, MIME, UU, PLAIN).
+ */
+ public void setEncoding(Encoding encoding) {
+ this.encoding = encoding.getValue();
+ }
+
+ /**
+ * Set the mail server port.
+ *
+ * @param port The port to use.
+ */
+ public void setMailport(int port) {
+ this.port = new Integer(port);
+ }
+
+ /**
+ * Set the host.
+ *
+ * @param host The host to connect to.
+ */
+ public void setMailhost(String host) {
+ this.host = host;
+ }
+
+ /**
+ * Set the subject line of the email.
+ *
+ * @param subject Subject of this email.
+ */
+ public void setSubject(String subject) {
+ this.subject = subject;
+ }
+
+ /**
+ * Shorthand method to set the message.
+ *
+ * @param message Message body of this email.
+ */
+ public void setMessage(String message) {
+ if (this.message != null) {
+ throw new BuildException("Only one message can be sent in an "
+ + "email");
+ }
+ this.message = new Message(message);
+ this.message.setProject(getProject());
+ }
+
+ /**
+ * Shorthand method to set the message from a file.
+ *
+ * @param file The file from which to take the message.
+ */
+ public void setMessageFile(File file) {
+ if (this.message != null) {
+ throw new BuildException("Only one message can be sent in an "
+ + "email");
+ }
+ this.message = new Message(file);
+ this.message.setProject(getProject());
+ }
+
+ /**
+ * Shorthand method to set type of the text message, text/plain by default
+ * but text/html or text/xml is quite feasible.
+ *
+ * @param type The new MessageMimeType value.
+ */
+ public void setMessageMimeType(String type) {
+ this.messageMimeType = type;
+ }
+
+ /**
+ * Add a message element.
+ *
+ * @param message The message object.
+ * @throws BuildException if a message has already been added.
+ */
+ public void addMessage(Message message) throws BuildException {
+ if (this.message != null) {
+ throw new BuildException(
+ "Only one message can be sent in an email");
+ }
+ this.message = message;
+ }
+
+ /**
+ * Add a from address element.
+ *
+ * @param address The address to send from.
+ */
+ public void addFrom(EmailAddress address) {
+ if (this.from != null) {
+ throw new BuildException("Emails can only be from one address");
+ }
+ this.from = address;
+ }
+
+ /**
+ * Shorthand to set the from address element.
+ *
+ * @param address The address to send mail from.
+ */
+ public void setFrom(String address) {
+ if (this.from != null) {
+ throw new BuildException("Emails can only be from one address");
+ }
+ this.from = new EmailAddress(address);
+ }
+
+ /**
+ * Add a replyto address element.
+ *
+ * @param address The address to reply to.
+ * @since Ant 1.6
+ */
+ public void addReplyTo(EmailAddress address) {
+ this.replyToList.add(address);
+ }
+
+ /**
+ * Shorthand to set the replyto address element.
+ *
+ * @param address The address to which replies should be directed.
+ * @since Ant 1.6
+ */
+ public void setReplyTo(String address) {
+ this.replyToList.add(new EmailAddress(address));
+ }
+
+ /**
+ * Add a to address element.
+ *
+ * @param address An email address.
+ */
+ public void addTo(EmailAddress address) {
+ toList.addElement(address);
+ }
+
+ /**
+ * Shorthand to set the "to" address element.
+ *
+ * @param list Comma-separated list of addresses.
+ */
+ public void setToList(String list) {
+ StringTokenizer tokens = new StringTokenizer(list, ",");
+
+ while (tokens.hasMoreTokens()) {
+ toList.addElement(new EmailAddress(tokens.nextToken()));
+ }
+ }
+
+ /**
+ * Add a "cc" address element.
+ *
+ * @param address The email address.
+ */
+ public void addCc(EmailAddress address) {
+ ccList.addElement(address);
+ }
+
+ /**
+ * Shorthand to set the "cc" address element.
+ *
+ * @param list Comma separated list of addresses.
+ */
+ public void setCcList(String list) {
+ StringTokenizer tokens = new StringTokenizer(list, ",");
+
+ while (tokens.hasMoreTokens()) {
+ ccList.addElement(new EmailAddress(tokens.nextToken()));
+ }
+ }
+
+ /**
+ * Add a "bcc" address element.
+ *
+ * @param address The email address.
+ */
+ public void addBcc(EmailAddress address) {
+ bccList.addElement(address);
+ }
+
+ /**
+ * Shorthand to set the "bcc" address element.
+ *
+ * @param list comma separated list of addresses.
+ */
+ public void setBccList(String list) {
+ StringTokenizer tokens = new StringTokenizer(list, ",");
+
+ while (tokens.hasMoreTokens()) {
+ bccList.addElement(new EmailAddress(tokens.nextToken()));
+ }
+ }
+
+ /**
+ * Set whether BuildExceptions should be passed back to the core.
+ *
+ * @param failOnError The new FailOnError value.
+ */
+ public void setFailOnError(boolean failOnError) {
+ this.failOnError = failOnError;
+ }
+
+ /**
+ * Set the list of files to be attached.
+ *
+ * @param filenames Comma-separated list of files.
+ */
+ public void setFiles(String filenames) {
+ StringTokenizer t = new StringTokenizer(filenames, ", ");
+
+ while (t.hasMoreTokens()) {
+ createAttachments()
+ .add(new FileResource(getProject().resolveFile(t.nextToken())));
+ }
+ }
+
+ /**
+ * Add a set of files (nested fileset attribute).
+ *
+ * @param fs The fileset.
+ */
+ public void addFileset(FileSet fs) {
+ createAttachments().add(fs);
+ }
+
+ /**
+ * Creates a Path as container for attachments. Supports any
+ * filesystem resource-collections that way.
+ * @return the path to be configured.
+ * @since Ant 1.7
+ */
+ public Path createAttachments() {
+ if (attachments == null) {
+ attachments = new Path(getProject());
+ }
+ return attachments.createPath();
+ }
+
+ /**
+ * Create a nested header element.
+ * @return a Header instance.
+ */
+ public Header createHeader() {
+ Header h = new Header();
+ headers.add(h);
+ return h;
+ }
+
+ /**
+ * Set whether to include filenames.
+ *
+ * @param includeFileNames Whether to include filenames in the text of the
+ * message.
+ */
+ public void setIncludefilenames(boolean includeFileNames) {
+ this.includeFileNames = includeFileNames;
+ }
+
+ /**
+ * Get whether file names should be included.
+ *
+ * @return Identifies whether file names should be included.
+ */
+ public boolean getIncludeFileNames() {
+ return includeFileNames;
+ }
+
+ /**
+ * Whether invalid recipients should be ignored (but a warning
+ * will be logged) instead of making the task fail.
+ *
+ * <p>Even with this property set to true the task will still fail
+ * if the mail couldn't be sent to any recipient at all.</p>
+ *
+ * @since Ant 1.8.0
+ */
+ public void setIgnoreInvalidRecipients(boolean b) {
+ ignoreInvalidRecipients = b;
+ }
+
+ /**
+ * Send an email.
+ */
+ public void execute() {
+ Message savedMessage = message;
+
+ try {
+ Mailer mailer = null;
+
+ // prepare for the auto select mechanism
+ boolean autoFound = false;
+ // try MIME format
+ if (encoding.equals(MIME)
+ || (encoding.equals(AUTO) && !autoFound)) {
+ try {
+ //check to make sure that activation.jar
+ //and mail.jar are available - see bug 31969
+ Class.forName("javax.activation.DataHandler");
+ Class.forName("javax.mail.internet.MimeMessage");
+
+ mailer = (Mailer) ClasspathUtils.newInstance(
+ "org.apache.tools.ant.taskdefs.email.MimeMailer",
+ EmailTask.class.getClassLoader(), Mailer.class);
+ autoFound = true;
+
+ log("Using MIME mail", Project.MSG_VERBOSE);
+ } catch (BuildException e) {
+ logBuildException("Failed to initialise MIME mail: ", e);
+ }
+ }
+ // SMTP auth only allowed with MIME mail
+ if (!autoFound && ((user != null) || (password != null))
+ && (encoding.equals(UU) || encoding.equals(PLAIN))) {
+ throw new BuildException("SMTP auth only possible with MIME mail");
+ }
+ // SSL only allowed with MIME mail
+ if (!autoFound && (ssl || starttls)
+ && (encoding.equals(UU) || encoding.equals(PLAIN))) {
+ throw new BuildException("SSL and STARTTLS only possible with"
+ + " MIME mail");
+ }
+ // try UU format
+ if (encoding.equals(UU)
+ || (encoding.equals(AUTO) && !autoFound)) {
+ try {
+ mailer = (Mailer) ClasspathUtils.newInstance(
+ "org.apache.tools.ant.taskdefs.email.UUMailer",
+ EmailTask.class.getClassLoader(), Mailer.class);
+ autoFound = true;
+ log("Using UU mail", Project.MSG_VERBOSE);
+ } catch (BuildException e) {
+ logBuildException("Failed to initialise UU mail: ", e);
+ }
+ }
+ // try plain format
+ if (encoding.equals(PLAIN)
+ || (encoding.equals(AUTO) && !autoFound)) {
+ mailer = new PlainMailer();
+ autoFound = true;
+ log("Using plain mail", Project.MSG_VERBOSE);
+ }
+ // a valid mailer must be present by now
+ if (mailer == null) {
+ throw new BuildException("Failed to initialise encoding: "
+ + encoding);
+ }
+ // a valid message is required
+ if (message == null) {
+ message = new Message();
+ message.setProject(getProject());
+ }
+ // an address to send from is required
+ if (from == null || from.getAddress() == null) {
+ throw new BuildException("A from element is required");
+ }
+ // at least one address to send to/cc/bcc is required
+ if (toList.isEmpty() && ccList.isEmpty() && bccList.isEmpty()) {
+ throw new BuildException("At least one of to, cc or bcc must "
+ + "be supplied");
+ }
+ // set the mimetype if not done already (and required)
+ if (messageMimeType != null) {
+ if (message.isMimeTypeSpecified()) {
+ throw new BuildException("The mime type can only be "
+ + "specified in one location");
+ }
+ message.setMimeType(messageMimeType);
+ }
+ // set the character set if not done already (and required)
+ if (charset != null) {
+ if (message.getCharset() != null) {
+ throw new BuildException("The charset can only be "
+ + "specified in one location");
+ }
+ message.setCharset(charset);
+ }
+ message.setInputEncoding(messageFileInputEncoding);
+
+ // identify which files should be attached
+ Vector<File> files = new Vector<File>();
+ if (attachments != null) {
+ for (Resource r : attachments) {
+ files.addElement(r.as(FileProvider.class)
+ .getFile());
+ }
+ }
+ // let the user know what's going to happen
+ log("Sending email: " + subject, Project.MSG_INFO);
+ log("From " + from, Project.MSG_VERBOSE);
+ log("ReplyTo " + replyToList, Project.MSG_VERBOSE);
+ log("To " + toList, Project.MSG_VERBOSE);
+ log("Cc " + ccList, Project.MSG_VERBOSE);
+ log("Bcc " + bccList, Project.MSG_VERBOSE);
+
+ // pass the params to the mailer
+ mailer.setHost(host);
+ if (port != null) {
+ mailer.setPort(port.intValue());
+ mailer.setPortExplicitlySpecified(true);
+ } else {
+ mailer.setPort(SMTP_PORT);
+ mailer.setPortExplicitlySpecified(false);
+ }
+ mailer.setUser(user);
+ mailer.setPassword(password);
+ mailer.setSSL(ssl);
+ mailer.setEnableStartTLS(starttls);
+ mailer.setMessage(message);
+ mailer.setFrom(from);
+ mailer.setReplyToList(replyToList);
+ mailer.setToList(toList);
+ mailer.setCcList(ccList);
+ mailer.setBccList(bccList);
+ mailer.setFiles(files);
+ mailer.setSubject(subject);
+ mailer.setTask(this);
+ mailer.setIncludeFileNames(includeFileNames);
+ mailer.setHeaders(headers);
+ mailer.setIgnoreInvalidRecipients(ignoreInvalidRecipients);
+
+ // send the email
+ mailer.send();
+
+ // let the user know what happened
+ int count = files.size();
+
+ log("Sent email with " + count + " attachment"
+ + (count == 1 ? "" : "s"), Project.MSG_INFO);
+ } catch (BuildException e) {
+ logBuildException("Failed to send email: ", e);
+ if (failOnError) {
+ throw e;
+ }
+ } catch (Exception e) {
+ log("Failed to send email: " + e.getMessage(), Project.MSG_WARN);
+ if (failOnError) {
+ throw new BuildException(e);
+ }
+ } finally {
+ message = savedMessage;
+ }
+ }
+
+ private void logBuildException(String reason, BuildException e) {
+ Throwable t = e.getCause() == null ? e : e.getCause();
+ log(reason + t.getMessage(), Project.MSG_WARN);
+ }
+
+ /**
+ * Sets the character set of mail message.
+ * Will be ignored if mimeType contains ....; Charset=... substring or
+ * encoding is not <code>mime</code>.
+ * @param charset the character encoding to use.
+ * @since Ant 1.6
+ */
+ public void setCharset(String charset) {
+ this.charset = charset;
+ }
+
+ /**
+ * Returns the character set of mail message.
+ *
+ * @return Charset of mail message.
+ * @since Ant 1.6
+ */
+ public String getCharset() {
+ return charset;
+ }
+
+ /**
+ * Sets the encoding to expect when reading the message from a file.
+ * <p>Will be ignored if the message has been specified inline.</p>
+ * @param encoding the name of the charset used
+ * @since Ant 1.9.4
+ */
+ public void setMessageFileInputEncoding(String encoding) {
+ messageFileInputEncoding = encoding;
+ }
+
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/email/Header.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/email/Header.java
new file mode 100644
index 00000000..6bcfb66f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/email/Header.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.email;
+
+/**
+ * Class representing a generic e-mail header.
+ * @since Ant 1.7
+ */
+public class Header {
+ private String name;
+ private String value;
+
+ /**
+ * Set the name of this Header.
+ * @param name the name to set.
+ */
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ /**
+ * Get the name of this Header.
+ * @return name as String.
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Set the value of this Header.
+ * @param value the value to set.
+ */
+ public void setValue(String value) {
+ this.value = value;
+ }
+
+ /**
+ * Get the value of this Header.
+ * @return value as String.
+ */
+ public String getValue() {
+ return value;
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/email/Mailer.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/email/Mailer.java
new file mode 100644
index 00000000..4aaa9823
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/email/Mailer.java
@@ -0,0 +1,277 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.email;
+
+import java.io.File;
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.util.DateUtils;
+
+/**
+ * Base class for the various emailing implementations.
+ *
+ * @since Ant 1.5
+ */
+public abstract class Mailer {
+ // CheckStyle:VisibilityModifier OFF - bc
+ protected String host = null;
+ protected int port = -1;
+ protected String user = null;
+ protected String password = null;
+ // CheckStyle:MemberNameCheck OFF - bc
+ protected boolean SSL = false;
+ // CheckStyle:MemberNameCheck ON
+ protected Message message;
+ protected EmailAddress from;
+ protected Vector<EmailAddress> replyToList = null;
+ protected Vector<EmailAddress> toList = null;
+ protected Vector<EmailAddress> ccList = null;
+ protected Vector<EmailAddress> bccList = null;
+ protected Vector<File> files = null;
+ protected String subject = null;
+ protected Task task;
+ protected boolean includeFileNames = false;
+ protected Vector<Header> headers = null;
+ // CheckStyle:VisibilityModifier ON
+ private boolean ignoreInvalidRecipients = false;
+ private boolean starttls = false;
+ private boolean portExplicitlySpecified = false;
+
+ /**
+ * Set the mail server.
+ *
+ * @param host the mail server name.
+ */
+ public void setHost(String host) {
+ this.host = host;
+ }
+
+ /**
+ * Set the smtp port.
+ *
+ * @param port the SMTP port.
+ */
+ public void setPort(int port) {
+ this.port = port;
+ }
+
+ /**
+ * Whether the port has been explicitly specified by the user.
+ * @since Ant 1.8.2
+ */
+ public void setPortExplicitlySpecified(boolean explicit) {
+ portExplicitlySpecified = explicit;
+ }
+
+ /**
+ * Whether the port has been explicitly specified by the user.
+ * @since Ant 1.8.2
+ */
+ protected boolean isPortExplicitlySpecified() {
+ return portExplicitlySpecified;
+ }
+
+ /**
+ * Set the user for smtp auth.
+ *
+ * @param user the username.
+ * @since Ant 1.6
+ */
+ public void setUser(String user) {
+ this.user = user;
+ }
+
+ /**
+ * Set the password for smtp auth.
+ *
+ * @param password the authentication password.
+ * @since Ant 1.6
+ */
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ /**
+ * Set whether to send the mail through SSL.
+ *
+ * @param ssl if true use SSL transport.
+ * @since Ant 1.6
+ */
+ public void setSSL(boolean ssl) {
+ this.SSL = ssl;
+ }
+
+ /**
+ * Set whether to allow authentication to switch to a TLS
+ * connection via STARTTLS.
+ * @param b boolean; if true STARTTLS will be supported.
+ * @since Ant 1.8.0
+ */
+ public void setEnableStartTLS(boolean b) {
+ this.starttls = b;
+ }
+
+ protected boolean isStartTLSEnabled() {
+ return starttls;
+ }
+
+ /**
+ * Set the message.
+ *
+ * @param m the message content.
+ */
+ public void setMessage(Message m) {
+ this.message = m;
+ }
+
+ /**
+ * Set the address to send from.
+ *
+ * @param from the sender.
+ */
+ public void setFrom(EmailAddress from) {
+ this.from = from;
+ }
+
+ /**
+ * Set the replyto addresses.
+ *
+ * @param list a vector of reployTo addresses.
+ * @since Ant 1.6
+ */
+ public void setReplyToList(Vector<EmailAddress> list) {
+ this.replyToList = list;
+ }
+
+ /**
+ * Set the to addresses.
+ *
+ * @param list a vector of recipient addresses.
+ */
+ public void setToList(Vector<EmailAddress> list) {
+ this.toList = list;
+ }
+
+ /**
+ * Set the cc addresses.
+ *
+ * @param list a vector of cc addresses.
+ */
+ public void setCcList(Vector<EmailAddress> list) {
+ this.ccList = list;
+ }
+
+ /**
+ * Set the bcc addresses.
+ *
+ * @param list a vector of the bcc addresses.
+ */
+ public void setBccList(Vector<EmailAddress> list) {
+ this.bccList = list;
+ }
+
+ /**
+ * Set the files to attach.
+ *
+ * @param files list of files to attach to the email.
+ */
+ public void setFiles(Vector<File> files) {
+ this.files = files;
+ }
+
+ /**
+ * Set the subject.
+ *
+ * @param subject the subject line.
+ */
+ public void setSubject(String subject) {
+ this.subject = subject;
+ }
+
+ /**
+ * Set the owning task.
+ *
+ * @param task the owning task instance.
+ */
+ public void setTask(Task task) {
+ this.task = task;
+ }
+
+ /**
+ * Indicate whether filenames should be listed in the body.
+ *
+ * @param b if true list attached file names in the body content.
+ */
+ public void setIncludeFileNames(boolean b) {
+ this.includeFileNames = b;
+ }
+
+ /**
+ * Set the generic headers to add to the email.
+ * @param v a Vector presumed to contain Header objects.
+ * @since Ant 1.7
+ */
+ public void setHeaders(Vector<Header> v) {
+ this.headers = v;
+ }
+
+ /**
+ * Send the email.
+ *
+ * @throws BuildException if the email can't be sent.
+ */
+ public abstract void send()
+ throws BuildException;
+
+ /**
+ * Whether invalid recipients should be ignored (but a warning
+ * will be logged) instead of making the task fail.
+ *
+ * <p>Even with this property set to true the task will still fail
+ * if the mail couldn't be sent to any recipient at all.</p>
+ *
+ * @since Ant 1.8.0
+ */
+ public void setIgnoreInvalidRecipients(boolean b) {
+ ignoreInvalidRecipients = b;
+ }
+
+ /**
+ * Whether invalid recipients should be ignored.
+ *
+ * @since Ant 1.8.0
+ */
+ protected boolean shouldIgnoreInvalidRecipients() {
+ return ignoreInvalidRecipients;
+ }
+
+ /**
+ * Return the current Date in a format suitable for a SMTP date
+ * header.
+ *
+ * @return the current date in SMTP suitable format.
+ *
+ * @since Ant 1.5
+ */
+ protected final String getDate() {
+ return DateUtils.getDateForHeader();
+ }
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/email/Message.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/email/Message.java
new file mode 100644
index 00000000..c121f5d7
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/email/Message.java
@@ -0,0 +1,203 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.email;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.io.PrintStream;
+import java.io.Reader;
+
+import org.apache.tools.ant.ProjectComponent;
+
+/**
+ * Class representing an email message.
+ *
+ * @since Ant 1.5
+ */
+public class Message extends ProjectComponent {
+ private File messageSource = null;
+ private StringBuffer buffer = new StringBuffer();
+ private String mimeType = "text/plain";
+ private boolean specified = false;
+ private String charset = null;
+ private String inputEncoding;
+
+ /** Creates a new empty message */
+ public Message() {
+ }
+
+
+ /**
+ * Creates a new message based on the given string
+ *
+ * @param text the message
+ */
+ public Message(String text) {
+ addText(text);
+ }
+
+
+ /**
+ * Creates a new message using the contents of the given file.
+ *
+ * @param file the source of the message
+ */
+ public Message(File file) {
+ messageSource = file;
+ }
+
+
+ /**
+ * Adds a textual part of the message
+ *
+ * @param text some text to add
+ */
+ public void addText(String text) {
+ buffer.append(text);
+ }
+
+
+ /**
+ * Sets the source file of the message
+ *
+ * @param src the source of the message
+ */
+ public void setSrc(File src) {
+ this.messageSource = src;
+ }
+
+
+ /**
+ * Sets the content type for the message
+ *
+ * @param mimeType a mime type e.g. "text/plain"
+ */
+ public void setMimeType(String mimeType) {
+ this.mimeType = mimeType;
+ specified = true;
+ }
+
+
+ /**
+ * Returns the content type
+ *
+ * @return the mime type
+ */
+ public String getMimeType() {
+ return mimeType;
+ }
+
+
+ /**
+ * Prints the message onto an output stream
+ *
+ * @param ps The print stream to write to
+ * @throws IOException if an error occurs
+ */
+ public void print(PrintStream ps)
+ throws IOException {
+ // We need character encoding aware printing here.
+ // So, using BufferedWriter over OutputStreamWriter instead of PrintStream
+ BufferedWriter out = null;
+ try {
+ out
+ = charset != null ? new BufferedWriter(new OutputStreamWriter(ps, charset))
+ : new BufferedWriter(new OutputStreamWriter(ps));
+ if (messageSource != null) {
+ // Read message from a file
+ Reader freader = getReader(messageSource);
+
+ try {
+ BufferedReader in = new BufferedReader(freader);
+ String line = null;
+ while ((line = in.readLine()) != null) {
+ out.write(getProject().replaceProperties(line));
+ out.newLine();
+ }
+ } finally {
+ freader.close();
+ }
+ } else {
+ out.write(getProject().replaceProperties(buffer.substring(0)));
+ out.newLine();
+ }
+ out.flush();
+ } finally {
+ //do not close the out writer as it is reused afterwards by the mail task
+ }
+ }
+
+
+ /**
+ * Returns true if the mimeType has been set.
+ *
+ * @return false if the default value is in use
+ */
+ public boolean isMimeTypeSpecified() {
+ return specified;
+ }
+
+ /**
+ * Sets the character set of mail message.
+ * Will be ignored if mimeType contains ....; Charset=... substring.
+ * @param charset the character set name.
+ * @since Ant 1.6
+ */
+ public void setCharset(String charset) {
+ this.charset = charset;
+ }
+ /**
+ * Returns the charset of mail message.
+ *
+ * @return Charset of mail message.
+ * @since Ant 1.6
+ */
+ public String getCharset() {
+ return charset;
+ }
+
+ /**
+ * Sets the encoding to expect when reading the message from a file.
+ * <p>Will be ignored if the message has been specified inline.</p>
+ * @param encoding the name of the charset used
+ * @since Ant 1.9.4
+ */
+ public void setInputEncoding(String encoding) {
+ this.inputEncoding = encoding;
+ }
+
+ private Reader getReader(File f) throws IOException {
+ if (inputEncoding != null) {
+ FileInputStream fis = new FileInputStream(f);
+ try {
+ return new InputStreamReader(fis, inputEncoding);
+ } catch (IOException ex) {
+ fis.close();
+ throw ex;
+ }
+ }
+ return new FileReader(f);
+ }
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/email/MimeMailer.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/email/MimeMailer.java
new file mode 100644
index 00000000..186d71e0
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/email/MimeMailer.java
@@ -0,0 +1,343 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.email;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.io.UnsupportedEncodingException;
+import java.security.Provider;
+import java.security.Security;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.Locale;
+import java.util.Properties;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import javax.activation.DataHandler;
+import javax.activation.FileDataSource;
+import javax.mail.Address;
+import javax.mail.Authenticator;
+import javax.mail.Message;
+import javax.mail.MessagingException;
+import javax.mail.PasswordAuthentication;
+import javax.mail.SendFailedException;
+import javax.mail.Session;
+import javax.mail.Transport;
+import javax.mail.internet.AddressException;
+import javax.mail.internet.InternetAddress;
+import javax.mail.internet.MimeBodyPart;
+import javax.mail.internet.MimeMessage;
+import javax.mail.internet.MimeMultipart;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+
+
+/**
+ * Uses the JavaMail classes to send Mime format email.
+ *
+ * @since Ant 1.5
+ */
+public class MimeMailer extends Mailer {
+ private static final String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory";
+
+ private static final String GENERIC_ERROR =
+ "Problem while sending mime mail:";
+
+ /** Default character set */
+ private static final String DEFAULT_CHARSET
+ = System.getProperty("file.encoding");
+
+ // To work properly with national charsets we have to use
+ // implementation of interface javax.activation.DataSource
+ /**
+ * String data source implementation.
+ * @since Ant 1.6
+ */
+ class StringDataSource implements javax.activation.DataSource {
+ private String data = null;
+ private String type = null;
+ private String charset = null;
+ private ByteArrayOutputStream out;
+
+ public InputStream getInputStream() throws IOException {
+ if (data == null && out == null) {
+ throw new IOException("No data");
+ }
+ if (out != null) {
+ final String encodedOut = out.toString(charset);
+ data = (data != null) ? data.concat(encodedOut) : encodedOut;
+ out = null;
+ }
+ return new ByteArrayInputStream(data.getBytes(charset));
+ }
+
+ public OutputStream getOutputStream() throws IOException {
+ out = (out == null) ? new ByteArrayOutputStream() : out;
+ return out;
+ }
+
+ public void setContentType(final String type) {
+ this.type = type.toLowerCase(Locale.ENGLISH);
+ }
+
+ public String getContentType() {
+ if (type != null && type.indexOf("charset") > 0
+ && type.startsWith("text/")) {
+ return type;
+ }
+ // Must be like "text/plain; charset=windows-1251"
+ return new StringBuffer(type != null ? type : "text/plain").append(
+ "; charset=").append(charset).toString();
+ }
+
+ public String getName() {
+ return "StringDataSource";
+ }
+
+ public void setCharset(final String charset) {
+ this.charset = charset;
+ }
+
+ public String getCharset() {
+ return charset;
+ }
+ }
+
+ /**
+ * Send the email.
+ *
+ * @throws BuildException if the email can't be sent.
+ */
+ public void send() {
+ try {
+ final Properties props = new Properties();
+
+ props.put("mail.smtp.host", host);
+ props.put("mail.smtp.port", String.valueOf(port));
+
+ // Aside, the JDK is clearly unaware of the Scottish
+ // 'session', which involves excessive quantities of
+ // alcohol :-)
+ Session sesh;
+ Authenticator auth = null;
+ if (SSL) {
+ try {
+ final Provider p = (Provider) Class.forName(
+ "com.sun.net.ssl.internal.ssl.Provider").newInstance();
+ Security.addProvider(p);
+ } catch (final Exception e) {
+ throw new BuildException("could not instantiate ssl "
+ + "security provider, check that you have JSSE in "
+ + "your classpath");
+ }
+ // SMTP provider
+ props.put("mail.smtp.socketFactory.class", SSL_FACTORY);
+ props.put("mail.smtp.socketFactory.fallback", "false");
+ props.put("mail.smtps.host", host);
+ if (isPortExplicitlySpecified()) {
+ props.put("mail.smtps.port", String.valueOf(port));
+ props.put("mail.smtp.socketFactory.port",
+ String.valueOf(port));
+ }
+ }
+ if (user != null || password != null) {
+ props.put("mail.smtp.auth", "true");
+ auth = new SimpleAuthenticator(user, password);
+ }
+ if (isStartTLSEnabled()) {
+ props.put("mail.smtp.starttls.enable", "true");
+ }
+ sesh = Session.getInstance(props, auth);
+
+ //create the message
+ final MimeMessage msg = new MimeMessage(sesh);
+ final MimeMultipart attachments = new MimeMultipart();
+
+ //set the sender
+ if (from.getName() == null) {
+ msg.setFrom(new InternetAddress(from.getAddress()));
+ } else {
+ msg.setFrom(new InternetAddress(from.getAddress(),
+ from.getName()));
+ }
+ // set the reply to addresses
+ msg.setReplyTo(internetAddresses(replyToList));
+ msg.setRecipients(Message.RecipientType.TO,
+ internetAddresses(toList));
+ msg.setRecipients(Message.RecipientType.CC,
+ internetAddresses(ccList));
+ msg.setRecipients(Message.RecipientType.BCC,
+ internetAddresses(bccList));
+
+ // Choosing character set of the mail message
+ // First: looking it from MimeType
+ String charset = parseCharSetFromMimeType(message.getMimeType());
+ if (charset != null) {
+ // Assign/reassign message charset from MimeType
+ message.setCharset(charset);
+ } else {
+ // Next: looking if charset having explicit definition
+ charset = message.getCharset();
+ if (charset == null) {
+ // Using default
+ charset = DEFAULT_CHARSET;
+ message.setCharset(charset);
+ }
+ }
+ // Using javax.activation.DataSource paradigm
+ final StringDataSource sds = new StringDataSource();
+ sds.setContentType(message.getMimeType());
+ sds.setCharset(charset);
+
+ if (subject != null) {
+ msg.setSubject(subject, charset);
+ }
+ msg.addHeader("Date", getDate());
+
+ if (headers != null) {
+ for (final Iterator iter = headers.iterator(); iter.hasNext();) {
+ final Header h = (Header) iter.next();
+ msg.addHeader(h.getName(), h.getValue());
+ }
+ }
+ final PrintStream out = new PrintStream(sds.getOutputStream());
+ message.print(out);
+ out.close();
+
+ final MimeBodyPart textbody = new MimeBodyPart();
+ textbody.setDataHandler(new DataHandler(sds));
+ attachments.addBodyPart(textbody);
+
+ final Enumeration e = files.elements();
+
+ while (e.hasMoreElements()) {
+ final File file = (File) e.nextElement();
+
+ MimeBodyPart body;
+
+ body = new MimeBodyPart();
+ if (!file.exists() || !file.canRead()) {
+ throw new BuildException("File \"" + file.getAbsolutePath()
+ + "\" does not exist or is not "
+ + "readable.");
+ }
+ final FileDataSource fileData = new FileDataSource(file);
+ final DataHandler fileDataHandler = new DataHandler(fileData);
+
+ body.setDataHandler(fileDataHandler);
+ body.setFileName(file.getName());
+ attachments.addBodyPart(body);
+ }
+ msg.setContent(attachments);
+ try {
+ // Send the message using SMTP, or SMTPS if the host uses SSL
+ final Transport transport = sesh.getTransport(SSL ? "smtps" : "smtp");
+ transport.connect(host, user, password);
+ transport.sendMessage(msg, msg.getAllRecipients());
+ } catch (final SendFailedException sfe) {
+ if (!shouldIgnoreInvalidRecipients()) {
+ throw new BuildException(GENERIC_ERROR, sfe);
+ } else if (sfe.getValidSentAddresses() == null
+ || sfe.getValidSentAddresses().length == 0) {
+ throw new BuildException("Couldn't reach any recipient",
+ sfe);
+ } else {
+ Address[] invalid = sfe.getInvalidAddresses();
+ if (invalid == null) {
+ invalid = new Address[0];
+ }
+ for (int i = 0; i < invalid.length; i++) {
+ didntReach(invalid[i], "invalid", sfe);
+ }
+ Address[] validUnsent = sfe.getValidUnsentAddresses();
+ if (validUnsent == null) {
+ validUnsent = new Address[0];
+ }
+ for (int i = 0; i < validUnsent.length; i++) {
+ didntReach(validUnsent[i], "valid", sfe);
+ }
+ }
+ }
+ } catch (final MessagingException e) {
+ throw new BuildException(GENERIC_ERROR, e);
+ } catch (final IOException e) {
+ throw new BuildException(GENERIC_ERROR, e);
+ }
+ }
+
+ private static InternetAddress[] internetAddresses(final Vector list)
+ throws AddressException, UnsupportedEncodingException {
+ final int size = list.size();
+ final InternetAddress[] addrs = new InternetAddress[size];
+
+ for (int i = 0; i < size; ++i) {
+ final EmailAddress addr = (EmailAddress) list.elementAt(i);
+
+ final String name = addr.getName();
+ addrs[i] = (name == null)
+ ? new InternetAddress(addr.getAddress())
+ : new InternetAddress(addr.getAddress(), name);
+ }
+ return addrs;
+ }
+
+ private String parseCharSetFromMimeType(final String type) {
+ if (type == null) {
+ return null;
+ }
+ final int pos = type.indexOf("charset");
+ if (pos < 0) {
+ return null;
+ }
+ // Assuming mime type in form "text/XXXX; charset=XXXXXX"
+ final StringTokenizer token = new StringTokenizer(type.substring(pos), "=; ");
+ token.nextToken(); // Skip 'charset='
+ return token.nextToken();
+ }
+
+ private void didntReach(final Address addr, final String category,
+ final MessagingException ex) {
+ final String msg = "Failed to send mail to " + category + " address "
+ + addr + " because of " + ex.getMessage();
+ if (task != null) {
+ task.log(msg, Project.MSG_WARN);
+ } else {
+ System.err.println(msg);
+ }
+ }
+
+ static class SimpleAuthenticator extends Authenticator {
+ private String user = null;
+ private String password = null;
+ public SimpleAuthenticator(final String user, final String password) {
+ this.user = user;
+ this.password = password;
+ }
+ public PasswordAuthentication getPasswordAuthentication() {
+ return new PasswordAuthentication(user, password);
+ }
+ }
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/email/PlainMailer.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/email/PlainMailer.java
new file mode 100644
index 00000000..20524ac3
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/email/PlainMailer.java
@@ -0,0 +1,177 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.email;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.util.Enumeration;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.mail.MailMessage;
+
+/**
+ * Class responsible for sending email through raw protocol methods.
+ *
+ * @since Ant 1.5
+ */
+class PlainMailer extends Mailer {
+ /**
+ * Sends the email using the apache MailMessage class.
+ *
+ * @see org.apache.tools.mail.MailMessage
+ */
+ public void send() {
+ try {
+ MailMessage mailMessage = new MailMessage(host, port);
+
+ mailMessage.from(from.toString());
+
+ Enumeration e;
+ boolean atLeastOneRcptReached = false;
+
+ e = replyToList.elements();
+ while (e.hasMoreElements()) {
+ mailMessage.replyto(e.nextElement().toString());
+ }
+ e = toList.elements();
+ while (e.hasMoreElements()) {
+ String to = e.nextElement().toString();
+ try {
+ mailMessage.to(to);
+ atLeastOneRcptReached = true;
+ } catch (IOException ex) {
+ badRecipient(to, ex);
+ }
+ }
+ e = ccList.elements();
+ while (e.hasMoreElements()) {
+ String to = e.nextElement().toString();
+ try {
+ mailMessage.cc(to);
+ atLeastOneRcptReached = true;
+ } catch (IOException ex) {
+ badRecipient(to, ex);
+ }
+ }
+ e = bccList.elements();
+ while (e.hasMoreElements()) {
+ String to = e.nextElement().toString();
+ try {
+ mailMessage.bcc(to);
+ atLeastOneRcptReached = true;
+ } catch (IOException ex) {
+ badRecipient(to, ex);
+ }
+ }
+ if (!atLeastOneRcptReached) {
+ throw new BuildException("Couldn't reach any recipient");
+ }
+ if (subject != null) {
+ mailMessage.setSubject(subject);
+ }
+ mailMessage.setHeader("Date", getDate());
+ if (message.getCharset() != null) {
+ mailMessage.setHeader("Content-Type", message.getMimeType()
+ + "; charset=\"" + message.getCharset() + "\"");
+ } else {
+ mailMessage.setHeader("Content-Type", message.getMimeType());
+ }
+ if (headers != null) {
+ e = headers.elements();
+ while (e.hasMoreElements()) {
+ Header h = (Header) e.nextElement();
+ mailMessage.setHeader(h.getName(), h.getValue());
+ }
+ }
+ PrintStream out = mailMessage.getPrintStream();
+ message.print(out);
+
+ e = files.elements();
+ while (e.hasMoreElements()) {
+ attach((File) e.nextElement(), out);
+ }
+ mailMessage.sendAndClose();
+ } catch (IOException ioe) {
+ throw new BuildException("IO error sending mail", ioe);
+ }
+
+ }
+
+ /**
+ * Attaches a file to this email
+ *
+ * @param file The file to attache
+ * @param out The message stream to add to
+ * @throws IOException if errors occur
+ */
+ protected void attach(File file, PrintStream out)
+ throws IOException {
+ if (!file.exists() || !file.canRead()) {
+ throw new BuildException("File \"" + file.getName()
+ + "\" does not exist or is not "
+ + "readable.");
+ }
+
+ if (includeFileNames) {
+ out.println();
+
+ String filename = file.getName();
+ int filenamelength = filename.length();
+
+ out.println(filename);
+ for (int star = 0; star < filenamelength; star++) {
+ out.print('=');
+ }
+ out.println();
+ }
+
+ int length;
+ final int maxBuf = 1024;
+ byte[] buf = new byte[maxBuf];
+ FileInputStream finstr = new FileInputStream(file);
+
+ try {
+ BufferedInputStream in = new BufferedInputStream(finstr, buf.length);
+
+ while ((length = in.read(buf)) != -1) {
+ out.write(buf, 0, length);
+ }
+ } finally {
+ finstr.close();
+ }
+ }
+
+ private void badRecipient(String rcpt, IOException reason) {
+ String msg = "Failed to send mail to " + rcpt;
+ if (shouldIgnoreInvalidRecipients()) {
+ msg += " because of :" + reason.getMessage();
+ if (task != null) {
+ task.log(msg, Project.MSG_WARN);
+ } else {
+ System.err.println(msg);
+ }
+ } else {
+ throw new BuildException(msg, reason);
+ }
+ }
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/email/UUMailer.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/email/UUMailer.java
new file mode 100644
index 00000000..d6542be4
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/email/UUMailer.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.email;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.util.UUEncoder;
+
+/**
+ * An emailer that uuencodes attachments.
+ *
+ * @since Ant 1.5
+ */
+class UUMailer extends PlainMailer {
+ protected void attach(File file, PrintStream out)
+ throws IOException {
+ if (!file.exists() || !file.canRead()) {
+ throw new BuildException("File \"" + file.getName()
+ + "\" does not exist or is not "
+ + "readable.");
+ }
+
+ FileInputStream finstr = new FileInputStream(file);
+
+ try {
+ BufferedInputStream in = new BufferedInputStream(finstr);
+ UUEncoder encoder = new UUEncoder(file.getName());
+
+ encoder.encode(in, out);
+
+ } finally {
+ finstr.close();
+ }
+ }
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/launcher/CommandLauncher.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/launcher/CommandLauncher.java
new file mode 100644
index 00000000..8c126efe
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/launcher/CommandLauncher.java
@@ -0,0 +1,213 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.launcher;
+
+import static org.apache.tools.ant.MagicNames.ANT_SHELL_LAUNCHER_REF_ID;
+import static org.apache.tools.ant.MagicNames.ANT_VM_LAUNCHER_REF_ID;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.condition.Os;
+import org.apache.tools.ant.types.Commandline;
+import org.apache.tools.ant.util.FileUtils;
+
+/**
+ * A command launcher for a particular JVM/OS platform. This class is
+ * a general purpose command launcher which can only launch commands
+ * in the current working directory.
+ */
+public class CommandLauncher {
+
+ protected static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+
+ private static CommandLauncher vmLauncher = null;
+ private static CommandLauncher shellLauncher = null;
+
+ static {
+ if(!Os.isFamily("os/2")) {
+ vmLauncher = new Java13CommandLauncher();
+ }
+
+ if (Os.isFamily("mac") && !Os.isFamily("unix")) {
+ // Mac
+ shellLauncher = new MacCommandLauncher(new CommandLauncher());
+ } else if (Os.isFamily("os/2")) {
+ // OS/2
+ shellLauncher = new OS2CommandLauncher(new CommandLauncher());
+ } else if (Os.isFamily("windows")) {
+ CommandLauncher baseLauncher = new CommandLauncher();
+
+ if (!Os.isFamily("win9x")) {
+ // Windows XP/2000/NT
+ shellLauncher = new WinNTCommandLauncher(baseLauncher);
+ } else {
+ // Windows 98/95 - need to use an auxiliary script
+ shellLauncher =
+ new ScriptCommandLauncher("bin/antRun.bat", baseLauncher);
+ }
+ } else if (Os.isFamily("netware")) {
+
+ CommandLauncher baseLauncher = new CommandLauncher();
+
+ shellLauncher =
+ new PerlScriptCommandLauncher("bin/antRun.pl", baseLauncher);
+ } else if (Os.isFamily("openvms")) {
+ // OpenVMS
+ shellLauncher = new VmsCommandLauncher();
+ } else {
+ // Generic
+ shellLauncher = new ScriptCommandLauncher("bin/antRun",
+ new CommandLauncher());
+ }
+ }
+
+ /**
+ * Launches the given command in a new process.
+ *
+ * @param project
+ * The project that the command is part of.
+ * @param cmd
+ * The command to execute.
+ * @param env
+ * The environment for the new process. If null, the
+ * environment of the current process is used.
+ * @return the created Process.
+ * @throws IOException
+ * if attempting to run a command in a specific directory.
+ */
+ public Process exec(Project project, String[] cmd, String[] env)
+ throws IOException {
+ if(project != null) {
+ project.log("Execute:CommandLauncher: "
+ + Commandline.describeCommand(cmd), Project.MSG_DEBUG);
+ }
+ return Runtime.getRuntime().exec(cmd, env);
+ }
+
+ /**
+ * Launches the given command in a new process, in the given
+ * working directory.
+ *
+ * @param project
+ * The project that the command is part of.
+ * @param cmd
+ * The command to execute.
+ * @param env
+ * The environment for the new process. If null, the
+ * environment of the current process is used.
+ * @param workingDir
+ * The directory to start the command in. If null, the
+ * current directory is used.
+ * @return the created Process.
+ * @throws IOException
+ * if trying to change directory.
+ */
+ public Process exec(Project project, String[] cmd, String[] env,
+ File workingDir) throws IOException {
+ if (workingDir == null) {
+ return exec(project, cmd, env);
+ }
+ throw new IOException("Cannot execute a process in different "
+ + "directory under this JVM");
+ }
+
+ /**
+ * Obtains the shell launcher configured for the given project or
+ * the default shell launcher.
+ */
+ public static CommandLauncher getShellLauncher(Project project) {
+ CommandLauncher launcher = extractLauncher(ANT_SHELL_LAUNCHER_REF_ID,
+ project);
+ if (launcher == null) {
+ launcher = shellLauncher;
+ }
+
+ return launcher;
+ }
+
+ /**
+ * Obtains the VM launcher configured for the given project or
+ * the default VM launcher.
+ */
+ public static CommandLauncher getVMLauncher(Project project) {
+ CommandLauncher launcher = extractLauncher(ANT_VM_LAUNCHER_REF_ID,
+ project);
+ if (launcher == null) {
+ launcher = vmLauncher;
+ }
+ return launcher;
+ }
+
+ private static CommandLauncher extractLauncher(String referenceName,
+ Project project) {
+ CommandLauncher launcher = null;
+ if (project != null) {
+ launcher = (CommandLauncher) project.getReference(referenceName);
+ }
+
+ if (launcher == null) {
+ launcher = getSystemLauncher(referenceName);
+ }
+ return launcher;
+ }
+
+ private static CommandLauncher getSystemLauncher(String launcherRefId) {
+ CommandLauncher launcher = null;
+ String launcherClass = System.getProperty(launcherRefId);
+ if (launcherClass != null) {
+ try {
+ launcher = (CommandLauncher) Class.forName(launcherClass)
+ .newInstance();
+ } catch(InstantiationException e) {
+ System.err.println("Could not instantiate launcher class "
+ + launcherClass + ": " + e.getMessage());
+ } catch(IllegalAccessException e) {
+ System.err.println("Could not instantiate launcher class "
+ + launcherClass + ": " + e.getMessage());
+ } catch(ClassNotFoundException e) {
+ System.err.println("Could not instantiate launcher class "
+ + launcherClass + ": " + e.getMessage());
+ }
+ }
+
+ return launcher;
+ }
+
+ /**
+ * Sets the VM launcher to use for the given project.
+ */
+ public static void setVMLauncher(Project project,
+ CommandLauncher launcher) {
+ if (project != null) {
+ project.addReference(ANT_VM_LAUNCHER_REF_ID, launcher);
+ }
+ }
+
+ /**
+ * Sets the shell launcher to use for the given project.
+ */
+ public static void setShellLauncher(Project project,
+ CommandLauncher launcher) {
+ if (project != null) {
+ project.addReference(ANT_SHELL_LAUNCHER_REF_ID, launcher);
+ }
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/launcher/CommandLauncherProxy.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/launcher/CommandLauncherProxy.java
new file mode 100644
index 00000000..32ddf2b2
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/launcher/CommandLauncherProxy.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.launcher;
+
+import java.io.IOException;
+
+import org.apache.tools.ant.Project;
+
+/**
+ * A command launcher that proxies another command
+ * launcher. Sub-classes override exec(args, env, workdir).
+ */
+public class CommandLauncherProxy extends CommandLauncher {
+ private final CommandLauncher myLauncher;
+
+ protected CommandLauncherProxy(CommandLauncher launcher) {
+ myLauncher = launcher;
+ }
+
+ /**
+ * Launches the given command in a new process. Delegates this
+ * method to the proxied launcher.
+ *
+ * @param project
+ * the Ant project.
+ * @param cmd
+ * the command line to execute as an array of strings.
+ * @param env
+ * the environment to set as an array of strings.
+ * @return the created Process.
+ * @throws IOException
+ * forwarded from the exec method of the command launcher.
+ */
+ @Override
+ public Process exec(Project project, String[] cmd, String[] env)
+ throws IOException {
+ return myLauncher.exec(project, cmd, env);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/launcher/Java13CommandLauncher.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/launcher/Java13CommandLauncher.java
new file mode 100644
index 00000000..0a018756
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/launcher/Java13CommandLauncher.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.launcher;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.Commandline;
+
+/**
+ * A command launcher for JDK/JRE 1.3 (and higher). Uses the built-in
+ * Runtime.exec() command.
+ */
+public class Java13CommandLauncher extends CommandLauncher {
+
+ /**
+ * Launches the given command in a new process, in the given
+ * working directory.
+ *
+ * @param project
+ * the Ant project.
+ * @param cmd
+ * the command line to execute as an array of strings.
+ * @param env
+ * the environment to set as an array of strings.
+ * @param workingDir
+ * the working directory where the command should run.
+ * @return the created Process.
+ * @throws IOException
+ * probably forwarded from Runtime#exec.
+ */
+ @Override
+ public Process exec(Project project, String[] cmd, String[] env,
+ File workingDir) throws IOException {
+ try {
+ if (project != null) {
+ project.log("Execute:Java13CommandLauncher: "
+ + Commandline.describeCommand(cmd),
+ Project.MSG_DEBUG);
+ }
+ return Runtime.getRuntime().exec(cmd, env, workingDir);
+ } catch(IOException ioex) {
+ throw ioex;
+ } catch(Exception exc) {
+ // IllegalAccess, IllegalArgument, ClassCast
+ throw new BuildException("Unable to execute command", exc);
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/launcher/MacCommandLauncher.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/launcher/MacCommandLauncher.java
new file mode 100644
index 00000000..58d8d71f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/launcher/MacCommandLauncher.java
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.launcher;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.tools.ant.Project;
+
+/**
+ * A command launcher for Mac that uses a dodgy mechanism to change
+ * working directory before launching commands.
+ */
+public class MacCommandLauncher extends CommandLauncherProxy {
+ public MacCommandLauncher(CommandLauncher launcher) {
+ super(launcher);
+ }
+
+ /**
+ * Launches the given command in a new process, in the given
+ * working directory.
+ *
+ * @param project
+ * the Ant project.
+ * @param cmd
+ * the command line to execute as an array of strings.
+ * @param env
+ * the environment to set as an array of strings.
+ * @param workingDir
+ * working directory where the command should run.
+ * @return the created Process.
+ * @throws IOException
+ * forwarded from the exec method of the command launcher.
+ */
+ @Override
+ public Process exec(Project project, String[] cmd, String[] env,
+ File workingDir) throws IOException {
+ if (workingDir == null) {
+ return exec(project, cmd, env);
+ }
+ System.getProperties().put("user.dir", workingDir.getAbsolutePath());
+ try {
+ return exec(project, cmd, env);
+ } finally {
+ System.getProperties().put("user.dir", System.getProperty("user.dir"));
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/launcher/OS2CommandLauncher.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/launcher/OS2CommandLauncher.java
new file mode 100644
index 00000000..6d6d2aa2
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/launcher/OS2CommandLauncher.java
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.launcher;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.tools.ant.Project;
+
+/**
+ * A command launcher for OS/2 that uses 'cmd.exe' when launching
+ * commands in directories other than the current working directory.
+ *
+ * <p>Unlike Windows NT and friends, OS/2's cd doesn't support the /d
+ * switch to change drives and directories in one go.</p>
+ */
+public class OS2CommandLauncher extends CommandLauncherProxy {
+ public OS2CommandLauncher(CommandLauncher launcher) {
+ super(launcher);
+ }
+
+ /**
+ * Launches the given command in a new process, in the given
+ * working directory.
+ *
+ * @param project
+ * the Ant project.
+ * @param cmd
+ * the command line to execute as an array of strings.
+ * @param env
+ * the environment to set as an array of strings.
+ * @param workingDir
+ * working directory where the command should run.
+ * @return the created Process.
+ * @throws IOException
+ * forwarded from the exec method of the command launcher.
+ */
+ @Override
+ public Process exec(Project project, String[] cmd, String[] env,
+ File workingDir) throws IOException {
+ File commandDir = workingDir;
+ if (workingDir == null) {
+ if (project != null) {
+ commandDir = project.getBaseDir();
+ } else {
+ return exec(project, cmd, env);
+ }
+ }
+ // Use cmd.exe to change to the specified drive and
+ // directory before running the command
+ final int preCmdLength = 7;
+ final String cmdDir = commandDir.getAbsolutePath();
+ String[] newcmd = new String[cmd.length + preCmdLength];
+ // CheckStyle:MagicNumber OFF - do not bother
+ newcmd[0] = "cmd";
+ newcmd[1] = "/c";
+ newcmd[2] = cmdDir.substring(0, 2);
+ newcmd[3] = "&&";
+ newcmd[4] = "cd";
+ newcmd[5] = cmdDir.substring(2);
+ newcmd[6] = "&&";
+ // CheckStyle:MagicNumber ON
+ System.arraycopy(cmd, 0, newcmd, preCmdLength, cmd.length);
+
+ return exec(project, newcmd, env);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/launcher/PerlScriptCommandLauncher.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/launcher/PerlScriptCommandLauncher.java
new file mode 100644
index 00000000..9b76e760
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/launcher/PerlScriptCommandLauncher.java
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.launcher;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.tools.ant.MagicNames;
+import org.apache.tools.ant.Project;
+
+/**
+ * A command launcher that uses an auxiliary perl script to launch
+ * commands in directories other than the current working directory.
+ */
+public class PerlScriptCommandLauncher extends CommandLauncherProxy {
+ private final String myScript;
+
+ public PerlScriptCommandLauncher(String script, CommandLauncher launcher) {
+ super(launcher);
+ myScript = script;
+ }
+
+ /**
+ * Launches the given command in a new process, in the given
+ * working directory.
+ *
+ * @param project
+ * the Ant project.
+ * @param cmd
+ * the command line to execute as an array of strings.
+ * @param env
+ * the environment to set as an array of strings.
+ * @param workingDir
+ * working directory where the command should run.
+ * @return the created Process.
+ * @throws IOException
+ * forwarded from the exec method of the command launcher.
+ */
+ @Override
+ public Process exec(Project project, String[] cmd, String[] env,
+ File workingDir) throws IOException {
+ if (project == null) {
+ if (workingDir == null) {
+ return exec(project, cmd, env);
+ }
+ throw new IOException("Cannot locate antRun script: "
+ + "No project provided");
+ }
+ // Locate the auxiliary script
+ String antHome = project.getProperty(MagicNames.ANT_HOME);
+ if (antHome == null) {
+ throw new IOException("Cannot locate antRun script: "
+ + "Property '" + MagicNames.ANT_HOME
+ + "' not found");
+ }
+ String antRun = FILE_UTILS.resolveFile(project.getBaseDir(),
+ antHome + File.separator
+ + myScript).toString();
+
+ // Build the command
+ File commandDir = workingDir;
+ if (workingDir == null) {
+ commandDir = project.getBaseDir();
+ }
+ // CheckStyle:MagicNumber OFF
+ String[] newcmd = new String[cmd.length + 3];
+ newcmd[0] = "perl";
+ newcmd[1] = antRun;
+ newcmd[2] = commandDir.getAbsolutePath();
+ System.arraycopy(cmd, 0, newcmd, 3, cmd.length);
+ // CheckStyle:MagicNumber ON
+
+ return exec(project, newcmd, env);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/launcher/ScriptCommandLauncher.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/launcher/ScriptCommandLauncher.java
new file mode 100644
index 00000000..fc7e3ebc
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/launcher/ScriptCommandLauncher.java
@@ -0,0 +1,88 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.launcher;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.tools.ant.MagicNames;
+import org.apache.tools.ant.Project;
+
+/**
+ * A command launcher that uses an auxiliary script to launch commands
+ * in directories other than the current working directory.
+ */
+public class ScriptCommandLauncher extends CommandLauncherProxy {
+ private final String myScript;
+
+ public ScriptCommandLauncher(String script, CommandLauncher launcher) {
+ super(launcher);
+ myScript = script;
+ }
+
+ /**
+ * Launches the given command in a new process, in the given
+ * working directory.
+ *
+ * @param project
+ * the Ant project.
+ * @param cmd
+ * the command line to execute as an array of strings.
+ * @param env
+ * the environment to set as an array of strings.
+ * @param workingDir
+ * working directory where the command should run.
+ * @return the created Process.
+ * @throws IOException
+ * forwarded from the exec method of the command launcher.
+ */
+ @Override
+ public Process exec(Project project, String[] cmd, String[] env,
+ File workingDir) throws IOException {
+ if (project == null) {
+ if (workingDir == null) {
+ return exec(project, cmd, env);
+ }
+ throw new IOException("Cannot locate antRun script: "
+ + "No project provided");
+ }
+ // Locate the auxiliary script
+ String antHome = project.getProperty(MagicNames.ANT_HOME);
+ if (antHome == null) {
+ throw new IOException("Cannot locate antRun script: "
+ + "Property '" + MagicNames.ANT_HOME
+ + "' not found");
+ }
+ String antRun = FILE_UTILS.resolveFile(project.getBaseDir(),
+ antHome + File.separator
+ + myScript).toString();
+
+ // Build the command
+ File commandDir = workingDir;
+ if (workingDir == null) {
+ commandDir = project.getBaseDir();
+ }
+ String[] newcmd = new String[cmd.length + 2];
+ newcmd[0] = antRun;
+ newcmd[1] = commandDir.getAbsolutePath();
+ System.arraycopy(cmd, 0, newcmd, 2, cmd.length);
+
+ return exec(project, newcmd, env);
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/launcher/VmsCommandLauncher.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/launcher/VmsCommandLauncher.java
new file mode 100644
index 00000000..c26d9841
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/launcher/VmsCommandLauncher.java
@@ -0,0 +1,145 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.launcher;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.util.FileUtils;
+
+/**
+ * A command launcher for VMS that writes the command to a temporary
+ * DCL script before launching commands. This is due to limitations of
+ * both the DCL interpreter and the Java VM implementation.
+ */
+public class VmsCommandLauncher extends Java13CommandLauncher {
+
+ public VmsCommandLauncher() {
+ super();
+ }
+
+ /**
+ * Launches the given command in a new process.
+ *
+ * @param project
+ * the Ant project.
+ * @param cmd
+ * the command line to execute as an array of strings.
+ * @param env
+ * the environment to set as an array of strings.
+ * @return the created Process.
+ * @throws IOException
+ * forwarded from the exec method of the command launcher.
+ */
+ @Override
+ public Process exec(Project project, String[] cmd, String[] env)
+ throws IOException {
+ File cmdFile = createCommandFile(cmd, env);
+ Process p = super.exec(project, new String[] {cmdFile.getPath()}, env);
+ deleteAfter(cmdFile, p);
+ return p;
+ }
+
+ /**
+ * Launches the given command in a new process, in the given
+ * working directory. Note that under Java 1.4.0 and 1.4.1 on VMS
+ * this method only works if <code>workingDir</code> is null or
+ * the logical JAVA$FORK_SUPPORT_CHDIR needs to be set to TRUE.
+ *
+ * @param project
+ * the Ant project.
+ * @param cmd
+ * the command line to execute as an array of strings.
+ * @param env
+ * the environment to set as an array of strings.
+ * @param workingDir
+ * working directory where the command should run.
+ * @return the created Process.
+ * @throws IOException
+ * forwarded from the exec method of the command launcher.
+ */
+ @Override
+ public Process exec(Project project, String[] cmd, String[] env,
+ File workingDir) throws IOException {
+ File cmdFile = createCommandFile(cmd, env);
+ Process p = super.exec(project, new String[] {
+ cmdFile.getPath()
+ }, env, workingDir);
+ deleteAfter(cmdFile, p);
+ return p;
+ }
+
+ /*
+ * Writes the command into a temporary DCL script and returns the
+ * corresponding File object. The script will be deleted on exit.
+ * @param cmd the command line to execute as an array of strings.
+ * @param env the environment to set as an array of strings.
+ * @return the command File.
+ * @throws IOException if errors are encountered creating the file.
+ */
+ private File createCommandFile(String[] cmd, String[] env)
+ throws IOException {
+ File script = FILE_UTILS.createTempFile("ANT", ".COM", null, true, true);
+ BufferedWriter out = null;
+ try {
+ out = new BufferedWriter(new FileWriter(script));
+
+ // add the environment as logicals to the DCL script
+ if (env != null) {
+ int eqIndex;
+ for (int i = 0; i < env.length; i++) {
+ eqIndex = env[i].indexOf('=');
+ if (eqIndex != -1) {
+ out.write("$ DEFINE/NOLOG ");
+ out.write(env[i].substring(0, eqIndex));
+ out.write(" \"");
+ out.write(env[i].substring(eqIndex + 1));
+ out.write('\"');
+ out.newLine();
+ }
+ }
+ }
+ out.write("$ " + cmd[0]);
+ for (int i = 1; i < cmd.length; i++) {
+ out.write(" -");
+ out.newLine();
+ out.write(cmd[i]);
+ }
+ } finally {
+ FileUtils.close(out);
+ }
+ return script;
+ }
+
+ private void deleteAfter(final File f, final Process p) {
+ new Thread() {
+ @Override
+ public void run() {
+ try {
+ p.waitFor();
+ } catch(InterruptedException e) {
+ // ignore
+ }
+ FileUtils.delete(f);
+ }
+ }.start();
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/launcher/WinNTCommandLauncher.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/launcher/WinNTCommandLauncher.java
new file mode 100644
index 00000000..4ac2af25
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/launcher/WinNTCommandLauncher.java
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.launcher;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.tools.ant.Project;
+
+/**
+ * A command launcher for Windows XP/2000/NT that uses 'cmd.exe' when
+ * launching commands in directories other than the current working
+ * directory.
+ */
+public class WinNTCommandLauncher extends CommandLauncherProxy {
+ public WinNTCommandLauncher(CommandLauncher launcher) {
+ super(launcher);
+ }
+
+ /**
+ * Launches the given command in a new process, in the given
+ * working directory.
+ *
+ * @param project
+ * the Ant project.
+ * @param cmd
+ * the command line to execute as an array of strings.
+ * @param env
+ * the environment to set as an array of strings.
+ * @param workingDir
+ * working directory where the command should run.
+ * @return the created Process.
+ * @throws IOException
+ * forwarded from the exec method of the command launcher.
+ */
+ @Override
+ public Process exec(Project project, String[] cmd, String[] env,
+ File workingDir) throws IOException {
+ File commandDir = workingDir;
+ if (workingDir == null) {
+ if (project != null) {
+ commandDir = project.getBaseDir();
+ } else {
+ return exec(project, cmd, env);
+ }
+ }
+ // Use cmd.exe to change to the specified directory before running
+ // the command
+ final int preCmdLength = 6;
+ String[] newcmd = new String[cmd.length + preCmdLength];
+ // CheckStyle:MagicNumber OFF - do not bother
+ newcmd[0] = "cmd";
+ newcmd[1] = "/c";
+ newcmd[2] = "cd";
+ newcmd[3] = "/d";
+ newcmd[4] = commandDir.getAbsolutePath();
+ newcmd[5] = "&&";
+ // CheckStyle:MagicNumber ON
+ System.arraycopy(cmd, 0, newcmd, preCmdLength, cmd.length);
+
+ return exec(project, newcmd, env);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ANTLR.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ANTLR.java
new file mode 100644
index 00000000..605b3368
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ANTLR.java
@@ -0,0 +1,438 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+
+import org.apache.tools.ant.AntClassLoader;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.taskdefs.Execute;
+import org.apache.tools.ant.taskdefs.LogOutputStream;
+import org.apache.tools.ant.taskdefs.PumpStreamHandler;
+import org.apache.tools.ant.taskdefs.condition.Os;
+import org.apache.tools.ant.types.Commandline;
+import org.apache.tools.ant.types.CommandlineJava;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.util.FileUtils;
+import org.apache.tools.ant.util.JavaEnvUtils;
+import org.apache.tools.ant.util.LoaderUtils;
+import org.apache.tools.ant.util.TeeOutputStream;
+
+/**
+ * Invokes the ANTLR Translator generator on a grammar file.
+ *
+ */
+public class ANTLR extends Task {
+
+ private CommandlineJava commandline = new CommandlineJava();
+
+ /** the file to process */
+ private File targetFile;
+
+ /** where to output the result */
+ private File outputDirectory;
+
+ /** an optional super grammar file */
+ private File superGrammar;
+
+ /** optional flag to enable html output */
+ private boolean html;
+
+ /** optional flag to print out a diagnostic file */
+ private boolean diagnostic;
+
+ /** optional flag to add trace methods */
+ private boolean trace;
+
+ /** optional flag to add trace methods to the parser only */
+ private boolean traceParser;
+
+ /** optional flag to add trace methods to the lexer only */
+ private boolean traceLexer;
+
+ /** optional flag to add trace methods to the tree walker only */
+ private boolean traceTreeWalker;
+
+ /** working directory */
+ private File workingdir = null;
+
+ /** captures ANTLR's output */
+ private ByteArrayOutputStream bos = new ByteArrayOutputStream();
+
+ /** The debug attribute */
+ private boolean debug;
+
+
+ /** Instance of a utility class to use for file operations. */
+ private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+
+ /** Constructor for ANTLR task. */
+ public ANTLR() {
+ commandline.setVm(JavaEnvUtils.getJreExecutable("java"));
+ commandline.setClassname("antlr.Tool");
+ }
+
+ /**
+ * The grammar file to process.
+ * @param target the gramer file
+ */
+ public void setTarget(File target) {
+ log("Setting target to: " + target.toString(), Project.MSG_VERBOSE);
+ this.targetFile = target;
+ }
+
+ /**
+ * The directory to write the generated files to.
+ * @param outputDirectory the output directory
+ */
+ public void setOutputdirectory(File outputDirectory) {
+ log("Setting output directory to: " + outputDirectory.toString(), Project.MSG_VERBOSE);
+ this.outputDirectory = outputDirectory;
+ }
+
+ /**
+ * Sets an optional super grammar file.
+ * Use setGlib(File superGrammar) instead.
+ * @param superGrammar the super grammar filename
+ * @deprecated since ant 1.6
+ */
+ public void setGlib(String superGrammar) {
+ String sg = null;
+ if (Os.isFamily("dos")) {
+ sg = superGrammar.replace('\\', '/');
+ } else {
+ sg = superGrammar;
+ }
+ setGlib(FILE_UTILS.resolveFile(getProject().getBaseDir(), sg));
+ }
+ /**
+ * Sets an optional super grammar file
+ * @param superGrammar the super grammar file
+ * @since ant 1.6
+ */
+ public void setGlib(File superGrammar) {
+ this.superGrammar = superGrammar;
+ }
+ /**
+ * Sets a flag to enable ParseView debugging
+ * @param enable a <code>boolean</code> value
+ */
+ public void setDebug(boolean enable) {
+ this.debug = enable;
+ }
+
+ /**
+ * If true, emit html
+ * @param enable a <code>boolean</code> value
+ */
+ public void setHtml(boolean enable) {
+ html = enable;
+ }
+
+ /**
+ * Sets a flag to emit diagnostic text
+ * @param enable a <code>boolean</code> value
+ */
+ public void setDiagnostic(boolean enable) {
+ diagnostic = enable;
+ }
+
+ /**
+ * If true, enables all tracing.
+ * @param enable a <code>boolean</code> value
+ */
+ public void setTrace(boolean enable) {
+ trace = enable;
+ }
+
+ /**
+ * If true, enables parser tracing.
+ * @param enable a <code>boolean</code> value
+ */
+ public void setTraceParser(boolean enable) {
+ traceParser = enable;
+ }
+
+ /**
+ * If true, enables lexer tracing.
+ * @param enable a <code>boolean</code> value
+ */
+ public void setTraceLexer(boolean enable) {
+ traceLexer = enable;
+ }
+
+ /**
+ * Sets a flag to allow the user to enable tree walker tracing
+ * @param enable a <code>boolean</code> value
+ */
+ public void setTraceTreeWalker(boolean enable) {
+ traceTreeWalker = enable;
+ }
+
+ // we are forced to fork ANTLR since there is a call
+ // to System.exit() and there is nothing we can do
+ // right now to avoid this. :-( (SBa)
+ // I'm not removing this method to keep backward compatibility
+ /**
+ * @ant.attribute ignore="true"
+ * @param s a <code>boolean</code> value
+ */
+ public void setFork(boolean s) {
+ //this.fork = s;
+ }
+
+ /**
+ * The working directory of the process
+ * @param d the working directory
+ */
+ public void setDir(File d) {
+ this.workingdir = d;
+ }
+
+ /**
+ * Adds a classpath to be set
+ * because a directory might be given for Antlr debug.
+ * @return a path to be configured
+ */
+ public Path createClasspath() {
+ return commandline.createClasspath(getProject()).createPath();
+ }
+
+ /**
+ * Adds a new JVM argument.
+ * @return create a new JVM argument so that any argument can be passed to the JVM.
+ * @see #setFork(boolean)
+ */
+ public Commandline.Argument createJvmarg() {
+ return commandline.createVmArgument();
+ }
+
+ /**
+ * Adds the jars or directories containing Antlr
+ * this should make the forked JVM work without having to
+ * specify it directly.
+ * @throws BuildException on error
+ */
+ public void init() throws BuildException {
+ addClasspathEntry("/antlr/ANTLRGrammarParseBehavior.class");
+ }
+
+ /**
+ * Search for the given resource and add the directory or archive
+ * that contains it to the classpath.
+ *
+ * <p>Doesn't work for archives in JDK 1.1 as the URL returned by
+ * getResource doesn't contain the name of the archive.</p>
+ * @param resource the resource name to search for
+ */
+ protected void addClasspathEntry(String resource) {
+ /*
+ * pre Ant 1.6 this method used to call getClass().getResource
+ * while Ant 1.6 will call ClassLoader.getResource().
+ *
+ * The difference is that Class.getResource expects a leading
+ * slash for "absolute" resources and will strip it before
+ * delegating to ClassLoader.getResource - so we now have to
+ * emulate Class's behavior.
+ */
+ if (resource.startsWith("/")) {
+ resource = resource.substring(1);
+ } else {
+ resource = "org/apache/tools/ant/taskdefs/optional/"
+ + resource;
+ }
+
+ File f = LoaderUtils.getResourceSource(getClass().getClassLoader(),
+ resource);
+ if (f != null) {
+ log("Found " + f.getAbsolutePath(), Project.MSG_DEBUG);
+ createClasspath().setLocation(f);
+ } else {
+ log("Couldn\'t find " + resource, Project.MSG_VERBOSE);
+ }
+ }
+
+ /**
+ * Execute the task.
+ * @throws BuildException on error
+ */
+ public void execute() throws BuildException {
+ validateAttributes();
+
+ //TODO: use ANTLR to parse the grammar file to do this.
+ File generatedFile = getGeneratedFile();
+ boolean targetIsOutOfDate =
+ targetFile.lastModified() > generatedFile.lastModified();
+ boolean superGrammarIsOutOfDate = superGrammar != null
+ && (superGrammar.lastModified() > generatedFile.lastModified());
+ if (targetIsOutOfDate || superGrammarIsOutOfDate) {
+ if (targetIsOutOfDate) {
+ log("Compiling " + targetFile + " as it is newer than "
+ + generatedFile, Project.MSG_VERBOSE);
+ } else {
+ log("Compiling " + targetFile + " as " + superGrammar
+ + " is newer than " + generatedFile, Project.MSG_VERBOSE);
+ }
+ populateAttributes();
+ commandline.createArgument().setValue(targetFile.toString());
+
+ log(commandline.describeCommand(), Project.MSG_VERBOSE);
+ int err = run(commandline.getCommandline());
+ if (err != 0) {
+ throw new BuildException("ANTLR returned: " + err, getLocation());
+ } else {
+ String output = bos.toString();
+ if (output.indexOf("error:") > -1) {
+ throw new BuildException("ANTLR signaled an error: "
+ + output, getLocation());
+ }
+ }
+ } else {
+ log("Skipped grammar file. Generated file " + generatedFile
+ + " is newer.", Project.MSG_VERBOSE);
+ }
+ }
+
+ /**
+ * A refactored method for populating all the command line arguments based
+ * on the user-specified attributes.
+ */
+ private void populateAttributes() {
+ commandline.createArgument().setValue("-o");
+ commandline.createArgument().setValue(outputDirectory.toString());
+ if (superGrammar != null) {
+ commandline.createArgument().setValue("-glib");
+ commandline.createArgument().setValue(superGrammar.toString());
+ }
+ if (html) {
+ commandline.createArgument().setValue("-html");
+ }
+ if (diagnostic) {
+ commandline.createArgument().setValue("-diagnostic");
+ }
+ if (trace) {
+ commandline.createArgument().setValue("-trace");
+ }
+ if (traceParser) {
+ commandline.createArgument().setValue("-traceParser");
+ }
+ if (traceLexer) {
+ commandline.createArgument().setValue("-traceLexer");
+ }
+ if (traceTreeWalker) {
+ if (is272()) {
+ commandline.createArgument().setValue("-traceTreeParser");
+ } else {
+ commandline.createArgument().setValue("-traceTreeWalker");
+ }
+ }
+ if (debug) {
+ commandline.createArgument().setValue("-debug");
+ }
+ }
+
+ private void validateAttributes() throws BuildException {
+ if (targetFile == null || !targetFile.isFile()) {
+ throw new BuildException("Invalid target: " + targetFile);
+ }
+
+ // if no output directory is specified, used the target's directory
+ if (outputDirectory == null) {
+ setOutputdirectory(new File(targetFile.getParent()));
+ }
+ if (!outputDirectory.isDirectory()) {
+ throw new BuildException("Invalid output directory: " + outputDirectory);
+ }
+ }
+
+ private File getGeneratedFile() throws BuildException {
+ String generatedFileName = null;
+ try {
+ BufferedReader in = new BufferedReader(new FileReader(targetFile));
+ String line;
+ while ((line = in.readLine()) != null) {
+ int extendsIndex = line.indexOf(" extends ");
+ if (line.startsWith("class ") && extendsIndex > -1) {
+ generatedFileName = line.substring(
+ "class ".length(), extendsIndex).trim();
+ break;
+ }
+ }
+ in.close();
+ } catch (Exception e) {
+ throw new BuildException("Unable to determine generated class", e);
+ }
+ if (generatedFileName == null) {
+ throw new BuildException("Unable to determine generated class");
+ }
+ return new File(outputDirectory, generatedFileName
+ + (html ? ".html" : ".java"));
+ }
+
+ /** execute in a forked VM */
+ private int run(String[] command) throws BuildException {
+ PumpStreamHandler psh =
+ new PumpStreamHandler(new LogOutputStream(this, Project.MSG_INFO),
+ new TeeOutputStream(
+ new LogOutputStream(this,
+ Project.MSG_WARN),
+ bos)
+ );
+ Execute exe = new Execute(psh, null);
+ exe.setAntRun(getProject());
+ if (workingdir != null) {
+ exe.setWorkingDirectory(workingdir);
+ }
+ exe.setCommandline(command);
+ try {
+ return exe.execute();
+ } catch (IOException e) {
+ throw new BuildException(e, getLocation());
+ } finally {
+ FileUtils.close(bos);
+ }
+ }
+
+ /**
+ * Whether the antlr version is 2.7.2 (or higher).
+ *
+ * @return true if the version of Antlr present is 2.7.2 or later.
+ * @since Ant 1.6
+ */
+ protected boolean is272() {
+ AntClassLoader l = null;
+ try {
+ l = getProject().createClassLoader(commandline.getClasspath());
+ l.loadClass("antlr.Version");
+ return true;
+ } catch (ClassNotFoundException e) {
+ return false;
+ } finally {
+ if (l != null) {
+ l.cleanup();
+ }
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/Cab.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/Cab.java
new file mode 100644
index 00000000..11c091a8
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/Cab.java
@@ -0,0 +1,357 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.DirectoryScanner;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.ExecTask;
+import org.apache.tools.ant.taskdefs.Execute;
+import org.apache.tools.ant.taskdefs.LogOutputStream;
+import org.apache.tools.ant.taskdefs.MatchingTask;
+import org.apache.tools.ant.taskdefs.StreamPumper;
+import org.apache.tools.ant.taskdefs.condition.Os;
+import org.apache.tools.ant.types.FileSet;
+import org.apache.tools.ant.util.FileUtils;
+
+
+/**
+ * Create a CAB archive.
+ *
+ */
+
+public class Cab extends MatchingTask {
+ private static final int DEFAULT_RESULT = -99;
+ private File cabFile;
+ private File baseDir;
+ private Vector filesets = new Vector();
+ private boolean doCompress = true;
+ private boolean doVerbose = false;
+ private String cmdOptions;
+
+ // CheckStyle:VisibilityModifier OFF - bc
+ protected String archiveType = "cab";
+ // CheckStyle:VisibilityModifier ON
+
+ private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+
+ /**
+ * The name/location of where to create the .cab file.
+ * @param cabFile the location of the cab file.
+ */
+ public void setCabfile(File cabFile) {
+ this.cabFile = cabFile;
+ }
+
+ /**
+ * Base directory to look in for files to CAB.
+ * @param baseDir base directory for files to cab.
+ */
+ public void setBasedir(File baseDir) {
+ this.baseDir = baseDir;
+ }
+
+ /**
+ * If true, compress the files otherwise only store them.
+ * @param compress a <code>boolean</code> value.
+ */
+ public void setCompress(boolean compress) {
+ doCompress = compress;
+ }
+
+ /**
+ * If true, display cabarc output.
+ * @param verbose a <code>boolean</code> value.
+ */
+ public void setVerbose(boolean verbose) {
+ doVerbose = verbose;
+ }
+
+ /**
+ * Sets additional cabarc options that are not supported directly.
+ * @param options cabarc command line options.
+ */
+ public void setOptions(String options) {
+ cmdOptions = options;
+ }
+
+ /**
+ * Adds a set of files to archive.
+ * @param set a set of files to archive.
+ */
+ public void addFileset(FileSet set) {
+ if (filesets.size() > 0) {
+ throw new BuildException("Only one nested fileset allowed");
+ }
+ filesets.addElement(set);
+ }
+
+ /*
+ * I'm not fond of this pattern: "sub-method expected to throw
+ * task-cancelling exceptions". It feels too much like programming
+ * for side-effects to me...
+ */
+ /**
+ * Check if the attributes and nested elements are correct.
+ * @throws BuildException on error.
+ */
+ protected void checkConfiguration() throws BuildException {
+ if (baseDir == null && filesets.size() == 0) {
+ throw new BuildException("basedir attribute or one "
+ + "nested fileset is required!",
+ getLocation());
+ }
+ if (baseDir != null && !baseDir.exists()) {
+ throw new BuildException("basedir does not exist!", getLocation());
+ }
+ if (baseDir != null && filesets.size() > 0) {
+ throw new BuildException(
+ "Both basedir attribute and a nested fileset is not allowed");
+ }
+ if (cabFile == null) {
+ throw new BuildException("cabfile attribute must be set!",
+ getLocation());
+ }
+ }
+
+ /**
+ * Create a new exec delegate. The delegate task is populated so that
+ * it appears in the logs to be the same task as this one.
+ * @return the delegate.
+ * @throws BuildException on error.
+ */
+ protected ExecTask createExec() throws BuildException {
+ ExecTask exec = new ExecTask(this);
+ return exec;
+ }
+
+ /**
+ * Check to see if the target is up to date with respect to input files.
+ * @param files the list of files to check.
+ * @return true if the cab file is newer than its dependents.
+ */
+ protected boolean isUpToDate(Vector files) {
+ boolean upToDate = true;
+ final int size = files.size();
+ for (int i = 0; i < size && upToDate; i++) {
+ String file = files.elementAt(i).toString();
+ if (FILE_UTILS.resolveFile(baseDir, file).lastModified()
+ > cabFile.lastModified()) {
+ upToDate = false;
+ }
+ }
+ return upToDate;
+ }
+
+ /**
+ * Creates a list file. This temporary file contains a list of all files
+ * to be included in the cab, one file per line.
+ *
+ * <p>This method expects to only be called on Windows and thus
+ * quotes the file names.</p>
+ * @param files the list of files to use.
+ * @return the list file created.
+ * @throws IOException if there is an error.
+ */
+ protected File createListFile(Vector files)
+ throws IOException {
+ File listFile = FILE_UTILS.createTempFile("ant", "", null, true, true);
+
+ BufferedWriter writer = null;
+ try {
+ writer = new BufferedWriter(new FileWriter(listFile));
+
+ final int size = files.size();
+ for (int i = 0; i < size; i++) {
+ writer.write('\"' + files.elementAt(i).toString() + '\"');
+ writer.newLine();
+ }
+ } finally {
+ FileUtils.close(writer);
+ }
+
+ return listFile;
+ }
+
+ /**
+ * Append all files found by a directory scanner to a vector.
+ * @param files the vector to append the files to.
+ * @param ds the scanner to get the files from.
+ */
+ protected void appendFiles(Vector files, DirectoryScanner ds) {
+ String[] dsfiles = ds.getIncludedFiles();
+
+ for (int i = 0; i < dsfiles.length; i++) {
+ files.addElement(dsfiles[i]);
+ }
+ }
+
+ /**
+ * Get the complete list of files to be included in the cab. Filenames
+ * are gathered from the fileset if it has been added, otherwise from the
+ * traditional include parameters.
+ * @return the list of files.
+ * @throws BuildException if there is an error.
+ */
+ protected Vector getFileList() throws BuildException {
+ Vector files = new Vector();
+
+ if (baseDir != null) {
+ // get files from old methods - includes and nested include
+ appendFiles(files, super.getDirectoryScanner(baseDir));
+ } else {
+ FileSet fs = (FileSet) filesets.elementAt(0);
+ baseDir = fs.getDir();
+ appendFiles(files, fs.getDirectoryScanner(getProject()));
+ }
+
+ return files;
+ }
+
+ /**
+ * execute this task.
+ * @throws BuildException on error.
+ */
+ public void execute() throws BuildException {
+
+ checkConfiguration();
+
+ Vector files = getFileList();
+
+ // quick exit if the target is up to date
+ if (isUpToDate(files)) {
+ return;
+ }
+
+ log("Building " + archiveType + ": " + cabFile.getAbsolutePath());
+
+ if (!Os.isFamily("windows")) {
+ log("Using listcab/libcabinet", Project.MSG_VERBOSE);
+
+ StringBuffer sb = new StringBuffer();
+
+ Enumeration fileEnum = files.elements();
+
+ while (fileEnum.hasMoreElements()) {
+ sb.append(fileEnum.nextElement()).append("\n");
+ }
+ sb.append("\n").append(cabFile.getAbsolutePath()).append("\n");
+
+ try {
+ Process p = Execute.launch(getProject(),
+ new String[] {"listcab"}, null,
+ baseDir != null ? baseDir
+ : getProject().getBaseDir(),
+ true);
+ OutputStream out = p.getOutputStream();
+
+ // Create the stream pumpers to forward listcab's stdout and stderr to the log
+ // note: listcab is an interactive program, and issues prompts for every new line.
+ // Therefore, make it show only with verbose logging turned on.
+ LogOutputStream outLog = new LogOutputStream(this, Project.MSG_VERBOSE);
+ LogOutputStream errLog = new LogOutputStream(this, Project.MSG_ERR);
+ StreamPumper outPump = new StreamPumper(p.getInputStream(), outLog);
+ StreamPumper errPump = new StreamPumper(p.getErrorStream(), errLog);
+
+ // Pump streams asynchronously
+ (new Thread(outPump)).start();
+ (new Thread(errPump)).start();
+
+ out.write(sb.toString().getBytes());
+ out.flush();
+ out.close();
+
+ // A wild default for when the thread is interrupted
+ int result = DEFAULT_RESULT;
+
+ try {
+ // Wait for the process to finish
+ result = p.waitFor();
+
+ // Wait for the end of output and error streams
+ outPump.waitFor();
+ outLog.close();
+ errPump.waitFor();
+ errLog.close();
+ } catch (InterruptedException ie) {
+ log("Thread interrupted: " + ie);
+ }
+
+ // Informative summary message in case of errors
+ if (Execute.isFailure(result)) {
+ log("Error executing listcab; error code: " + result);
+ }
+ } catch (IOException ex) {
+ String msg = "Problem creating " + cabFile + " " + ex.getMessage();
+ throw new BuildException(msg, getLocation());
+ }
+ } else {
+ try {
+ File listFile = createListFile(files);
+ ExecTask exec = createExec();
+ File outFile = null;
+
+ // die if cabarc fails
+ exec.setFailonerror(true);
+ exec.setDir(baseDir);
+
+ if (!doVerbose) {
+ outFile = FILE_UTILS.createTempFile("ant", "", null, true, true);
+ exec.setOutput(outFile);
+ }
+
+ exec.setExecutable("cabarc");
+ exec.createArg().setValue("-r");
+ exec.createArg().setValue("-p");
+
+ if (!doCompress) {
+ exec.createArg().setValue("-m");
+ exec.createArg().setValue("none");
+ }
+
+ if (cmdOptions != null) {
+ exec.createArg().setLine(cmdOptions);
+ }
+
+ exec.createArg().setValue("n");
+ exec.createArg().setFile(cabFile);
+ exec.createArg().setValue("@" + listFile.getAbsolutePath());
+
+ exec.execute();
+
+ if (outFile != null) {
+ outFile.delete();
+ }
+
+ listFile.delete();
+ } catch (IOException ioe) {
+ String msg = "Problem creating " + cabFile + " " + ioe.getMessage();
+ throw new BuildException(msg, getLocation());
+ }
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/EchoProperties.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/EchoProperties.java
new file mode 100644
index 00000000..b63ef933
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/EchoProperties.java
@@ -0,0 +1,543 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.Vector;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.types.EnumeratedAttribute;
+import org.apache.tools.ant.types.PropertySet;
+import org.apache.tools.ant.util.CollectionUtils;
+import org.apache.tools.ant.util.DOMElementWriter;
+import org.apache.tools.ant.util.FileUtils;
+import org.apache.tools.ant.util.JavaEnvUtils;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+/**
+ * Displays all the current properties in the build. The output can be sent to
+ * a file if desired. <P>
+ *
+ * Attribute "destfile" defines a file to send the properties to. This can be
+ * processed as a standard property file later. <P>
+ *
+ * Attribute "prefix" defines a prefix which is used to filter the properties
+ * only those properties starting with this prefix will be echoed. <P>
+ *
+ * By default, the "failonerror" attribute is enabled. If an error occurs while
+ * writing the properties to a file, and this attribute is enabled, then a
+ * BuildException will be thrown. If disabled, then IO errors will be reported
+ * as a log statement, but no error will be thrown. <P>
+ *
+ * Examples: <pre>
+ * &lt;echoproperties /&gt;
+ * </pre> Report the current properties to the log. <P>
+ *
+ * <pre>
+ * &lt;echoproperties destfile="my.properties" /&gt;
+ * </pre> Report the current properties to the file "my.properties", and will
+ * fail the build if the file could not be created or written to. <P>
+ *
+ * <pre>
+ * &lt;echoproperties destfile="my.properties" failonerror="false"
+ * prefix="ant" /&gt;
+ * </pre> Report all properties beginning with 'ant' to the file
+ * "my.properties", and will log a message if the file could not be created or
+ * written to, but will still allow the build to continue.
+ *
+ *@since Ant 1.5
+ */
+public class EchoProperties extends Task {
+
+ /**
+ * the properties element.
+ */
+ private static final String PROPERTIES = "properties";
+
+ /**
+ * the property element.
+ */
+ private static final String PROPERTY = "property";
+
+ /**
+ * name attribute for property, testcase and testsuite elements.
+ */
+ private static final String ATTR_NAME = "name";
+
+ /**
+ * value attribute for property elements.
+ */
+ private static final String ATTR_VALUE = "value";
+
+ /**
+ * the input file.
+ */
+ private File inFile = null;
+
+ /**
+ * File object pointing to the output file. If this is null, then
+ * we output to the project log, not to a file.
+ */
+ private File destfile = null;
+
+ /**
+ * If this is true, then errors generated during file output will become
+ * build errors, and if false, then such errors will be logged, but not
+ * thrown.
+ */
+ private boolean failonerror = true;
+
+ private Vector propertySets = new Vector();
+
+ private String format = "text";
+
+ private String prefix;
+
+ /**
+ * @since Ant 1.7
+ */
+ private String regex;
+
+ /**
+ * Sets the input file.
+ *
+ * @param file the input file
+ */
+ public void setSrcfile(File file) {
+ inFile = file;
+ }
+
+ /**
+ * Set a file to store the property output. If this is never specified,
+ * then the output will be sent to the Ant log.
+ *
+ *@param destfile file to store the property output
+ */
+ public void setDestfile(File destfile) {
+ this.destfile = destfile;
+ }
+
+
+ /**
+ * If true, the task will fail if an error occurs writing the properties
+ * file, otherwise errors are just logged.
+ *
+ *@param failonerror <tt>true</tt> if IO exceptions are reported as build
+ * exceptions, or <tt>false</tt> if IO exceptions are ignored.
+ */
+ public void setFailOnError(boolean failonerror) {
+ this.failonerror = failonerror;
+ }
+
+
+ /**
+ * If the prefix is set, then only properties which start with this
+ * prefix string will be recorded. If regex is not set and if this
+ * is never set, or it is set to an empty string or <tt>null</tt>,
+ * then all properties will be recorded. <P>
+ *
+ * For example, if the attribute is set as:
+ * <PRE>&lt;echoproperties prefix="ant." /&gt;</PRE>
+ * then the property "ant.home" will be recorded, but "ant-example"
+ * will not.
+ *
+ * @param prefix The new prefix value
+ */
+ public void setPrefix(String prefix) {
+ if (prefix != null && prefix.length() != 0) {
+ this.prefix = prefix;
+ PropertySet ps = new PropertySet();
+ ps.setProject(getProject());
+ ps.appendPrefix(prefix);
+ addPropertyset(ps);
+ }
+ }
+
+ /**
+ * If the regex is set, then only properties whose names match it
+ * will be recorded. If prefix is not set and if this is never set,
+ * or it is set to an empty string or <tt>null</tt>, then all
+ * properties will be recorded.<P>
+ *
+ * For example, if the attribute is set as:
+ * <PRE>&lt;echoproperties prefix=".*ant.*" /&gt;</PRE>
+ * then the properties "ant.home" and "user.variant" will be recorded,
+ * but "ant-example" will not.
+ *
+ * @param regex The new regex value
+ *
+ * @since Ant 1.7
+ */
+ public void setRegex(String regex) {
+ if (regex != null && regex.length() != 0) {
+ this.regex = regex;
+ PropertySet ps = new PropertySet();
+ ps.setProject(getProject());
+ ps.appendRegex(regex);
+ addPropertyset(ps);
+ }
+ }
+
+ /**
+ * A set of properties to write.
+ * @param ps the property set to write
+ * @since Ant 1.6
+ */
+ public void addPropertyset(PropertySet ps) {
+ propertySets.addElement(ps);
+ }
+
+ /**
+ * Set the output format - xml or text.
+ * @param ea an enumerated <code>FormatAttribute</code> value
+ */
+ public void setFormat(FormatAttribute ea) {
+ format = ea.getValue();
+ }
+
+ /**
+ * A enumerated type for the format attribute.
+ * The values are "xml" and "text".
+ */
+ public static class FormatAttribute extends EnumeratedAttribute {
+ private String [] formats = new String[]{"xml", "text"};
+
+ /**
+ * @see EnumeratedAttribute#getValues()
+ * @return accepted values
+ */
+ public String[] getValues() {
+ return formats;
+ }
+ }
+
+ /**
+ * Run the task.
+ *
+ *@exception BuildException trouble, probably file IO
+ */
+ public void execute() throws BuildException {
+ if (prefix != null && regex != null) {
+ throw new BuildException("Please specify either prefix"
+ + " or regex, but not both", getLocation());
+ }
+ //copy the properties file
+ Hashtable allProps = new Hashtable();
+
+ /* load properties from file if specified, otherwise
+ use Ant's properties */
+ if (inFile == null && propertySets.size() == 0) {
+ // add ant properties
+ allProps.putAll(getProject().getProperties());
+ } else if (inFile != null) {
+ if (inFile.exists() && inFile.isDirectory()) {
+ String message = "srcfile is a directory!";
+ if (failonerror) {
+ throw new BuildException(message, getLocation());
+ } else {
+ log(message, Project.MSG_ERR);
+ }
+ return;
+ }
+
+ if (inFile.exists() && !inFile.canRead()) {
+ String message = "Can not read from the specified srcfile!";
+ if (failonerror) {
+ throw new BuildException(message, getLocation());
+ } else {
+ log(message, Project.MSG_ERR);
+ }
+ return;
+ }
+
+ FileInputStream in = null;
+ try {
+ in = new FileInputStream(inFile);
+ Properties props = new Properties();
+ props.load(in);
+ allProps.putAll(props);
+ } catch (FileNotFoundException fnfe) {
+ String message =
+ "Could not find file " + inFile.getAbsolutePath();
+ if (failonerror) {
+ throw new BuildException(message, fnfe, getLocation());
+ } else {
+ log(message, Project.MSG_WARN);
+ }
+ return;
+ } catch (IOException ioe) {
+ String message =
+ "Could not read file " + inFile.getAbsolutePath();
+ if (failonerror) {
+ throw new BuildException(message, ioe, getLocation());
+ } else {
+ log(message, Project.MSG_WARN);
+ }
+ return;
+ } finally {
+ FileUtils.close(in);
+ }
+ }
+
+ Enumeration e = propertySets.elements();
+ while (e.hasMoreElements()) {
+ PropertySet ps = (PropertySet) e.nextElement();
+ allProps.putAll(ps.getProperties());
+ }
+
+ OutputStream os = null;
+ try {
+ if (destfile == null) {
+ os = new ByteArrayOutputStream();
+ saveProperties(allProps, os);
+ log(os.toString(), Project.MSG_INFO);
+ } else {
+ if (destfile.exists() && destfile.isDirectory()) {
+ String message = "destfile is a directory!";
+ if (failonerror) {
+ throw new BuildException(message, getLocation());
+ } else {
+ log(message, Project.MSG_ERR);
+ }
+ return;
+ }
+
+ if (destfile.exists() && !destfile.canWrite()) {
+ String message =
+ "Can not write to the specified destfile!";
+ if (failonerror) {
+ throw new BuildException(message, getLocation());
+ } else {
+ log(message, Project.MSG_ERR);
+ }
+ return;
+ }
+ os = new FileOutputStream(this.destfile);
+ saveProperties(allProps, os);
+ }
+ } catch (IOException ioe) {
+ if (failonerror) {
+ throw new BuildException(ioe, getLocation());
+ } else {
+ log(ioe.getMessage(), Project.MSG_INFO);
+ }
+ } finally {
+ if (os != null) {
+ try {
+ os.close();
+ } catch (IOException ex) {
+ //ignore
+ }
+ }
+ }
+ }
+
+
+ /**
+ * Send the key/value pairs in the hashtable to the given output stream.
+ * Only those properties matching the <tt>prefix</tt> constraint will be
+ * sent to the output stream.
+ * The output stream will be closed when this method returns.
+ *
+ * @param allProps propfile to save
+ * @param os output stream
+ * @throws IOException on output errors
+ * @throws BuildException on other errors
+ */
+ protected void saveProperties(Hashtable allProps, OutputStream os)
+ throws IOException, BuildException {
+ final List keyList = new ArrayList(allProps.keySet());
+ Collections.sort(keyList);
+ Properties props = new Properties() {
+ private static final long serialVersionUID = 5090936442309201654L;
+ public Enumeration keys() {
+ return CollectionUtils.asEnumeration(keyList.iterator());
+ }
+ public Set entrySet() {
+ Set result = super.entrySet();
+ if (JavaEnvUtils.isKaffe()) {
+ TreeSet t = new TreeSet(new Comparator() {
+ public int compare(Object o1, Object o2) {
+ String key1 = (String) ((Map.Entry) o1).getKey();
+ String key2 = (String) ((Map.Entry) o2).getKey();
+ return key1.compareTo(key2);
+ }
+ });
+ t.addAll(result);
+ result = t;
+ }
+ return result;
+ }
+ };
+ final int size = keyList.size();
+ for (int i = 0; i < size; i++) {
+ String name = keyList.get(i).toString();
+ String value = allProps.get(name).toString();
+ props.setProperty(name, value);
+ }
+ if ("text".equals(format)) {
+ jdkSaveProperties(props, os, "Ant properties");
+ } else if ("xml".equals(format)) {
+ xmlSaveProperties(props, os);
+ }
+ }
+
+ /**
+ * a tuple for the sort list.
+ */
+ private static final class Tuple implements Comparable {
+ private String key;
+ private String value;
+
+ private Tuple(String key, String value) {
+ this.key = key;
+ this.value = value;
+ }
+
+ /**
+ * Compares this object with the specified object for order.
+ * @param o the Object to be compared.
+ * @return a negative integer, zero, or a positive integer as this object is
+ * less than, equal to, or greater than the specified object.
+ * @throws ClassCastException if the specified object's type prevents it
+ * from being compared to this Object.
+ */
+ public int compareTo(Object o) {
+ Tuple that = (Tuple) o;
+ return key.compareTo(that.key);
+ }
+ }
+
+ private List sortProperties(Properties props) {
+ //sort the list. Makes SCM and manual diffs easier.
+ List sorted = new ArrayList(props.size());
+ Enumeration e = props.propertyNames();
+ while (e.hasMoreElements()) {
+ String name = (String) e.nextElement();
+ sorted.add(new Tuple(name, props.getProperty(name)));
+ }
+ Collections.sort(sorted);
+ return sorted;
+ }
+
+ /**
+ * Output the properties as xml output.
+ * @param props the properties to save
+ * @param os the output stream to write to (Note this gets closed)
+ * @throws IOException on error in writing to the stream
+ */
+ protected void xmlSaveProperties(Properties props,
+ OutputStream os) throws IOException {
+ // create XML document
+ Document doc = getDocumentBuilder().newDocument();
+ Element rootElement = doc.createElement(PROPERTIES);
+
+ List sorted = sortProperties(props);
+
+
+ // output properties
+ Iterator iten = sorted.iterator();
+ while (iten.hasNext()) {
+ Tuple tuple = (Tuple) iten.next();
+ Element propElement = doc.createElement(PROPERTY);
+ propElement.setAttribute(ATTR_NAME, tuple.key);
+ propElement.setAttribute(ATTR_VALUE, tuple.value);
+ rootElement.appendChild(propElement);
+ }
+
+ Writer wri = null;
+ try {
+ wri = new OutputStreamWriter(os, "UTF8");
+ wri.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
+ (new DOMElementWriter()).write(rootElement, wri, 0, "\t");
+ wri.flush();
+ } catch (IOException ioe) {
+ throw new BuildException("Unable to write XML file", ioe);
+ } finally {
+ FileUtils.close(wri);
+ }
+ }
+
+ /**
+ * JDK 1.2 allows for the safer method
+ * <tt>Properties.store(OutputStream, String)</tt>, which throws an
+ * <tt>IOException</tt> on an output error.
+ *
+ *@param props the properties to record
+ *@param os record the properties to this output stream
+ *@param header prepend this header to the property output
+ *@exception IOException on an I/O error during a write.
+ */
+ protected void jdkSaveProperties(Properties props, OutputStream os,
+ String header) throws IOException {
+ try {
+ props.store(os, header);
+
+ } catch (IOException ioe) {
+ throw new BuildException(ioe, getLocation());
+ } finally {
+ if (os != null) {
+ try {
+ os.close();
+ } catch (IOException ioex) {
+ log("Failed to close output stream");
+ }
+ }
+ }
+ }
+
+
+ /**
+ * Uses the DocumentBuilderFactory to get a DocumentBuilder instance.
+ *
+ * @return The DocumentBuilder instance
+ */
+ private static DocumentBuilder getDocumentBuilder() {
+ try {
+ return DocumentBuilderFactory.newInstance().newDocumentBuilder();
+ } catch (Exception e) {
+ throw new ExceptionInInitializerError(e);
+ }
+ }
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/Javah.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/Javah.java
new file mode 100644
index 00000000..aaed7832
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/Javah.java
@@ -0,0 +1,513 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.taskdefs.optional.javah.JavahAdapter;
+import org.apache.tools.ant.taskdefs.optional.javah.JavahAdapterFactory;
+import org.apache.tools.ant.types.Commandline;
+import org.apache.tools.ant.types.FileSet;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.types.Reference;
+import org.apache.tools.ant.util.StringUtils;
+import org.apache.tools.ant.util.facade.FacadeTaskHelper;
+import org.apache.tools.ant.util.facade.ImplementationSpecificArgument;
+
+/**
+ * Generates JNI header files using javah.
+ *
+ * This task can take the following arguments:
+ * <ul>
+ * <li>classname - the fully-qualified name of a class</li>
+ * <li>outputFile - Concatenates the resulting header or source files for all
+ * the classes listed into this file</li>
+ * <li>destdir - Sets the directory where javah saves the header files or the
+ * stub files</li>
+ * <li>classpath</li>
+ * <li>bootclasspath</li>
+ * <li>force - Specifies that output files should always be written
+ (JDK1.2 only)</li>
+ * <li>old - Specifies that old JDK1.0-style header files should be generated
+ * (otherwise output file contain JNI-style native method
+ * function prototypes) (JDK1.2 only)</li>
+ * <li>stubs - generate C declarations from the Java object file (used with old)</li>
+ * <li>verbose - causes javah to print a message to stdout concerning the status
+ * of the generated files</li>
+ * <li>extdirs - Override location of installed extensions</li>
+ * </ul>
+ * Of these arguments, either <b>outputFile</b> or <b>destdir</b> is required,
+ * but not both. More than one classname may be specified, using a comma-separated
+ * list or by using <code>&lt;class name="xxx"&gt;</code> elements within the task.
+ * <p>
+ * When this task executes, it will generate C header and source files that
+ * are needed to implement native methods.
+ *
+ */
+
+public class Javah extends Task {
+
+ private Vector classes = new Vector(2);
+ private String cls;
+ private File destDir;
+ private Path classpath = null;
+ private File outputFile = null;
+ private boolean verbose = false;
+ private boolean force = false;
+ private boolean old = false;
+ private boolean stubs = false;
+ private Path bootclasspath;
+ //private Path extdirs;
+ private FacadeTaskHelper facade = null;
+ private Vector files = new Vector();
+ private JavahAdapter nestedAdapter = null;
+
+ /**
+ * No arg constructor.
+ */
+ public Javah() {
+ facade = new FacadeTaskHelper(JavahAdapterFactory.getDefault());
+ }
+
+ /**
+ * the fully-qualified name of the class (or classes, separated by commas).
+ * @param cls the classname (or classnames).
+ */
+ public void setClass(String cls) {
+ this.cls = cls;
+ }
+
+ /**
+ * Adds class to process.
+ * @return a <code>ClassArgument</code> to be configured.
+ */
+ public ClassArgument createClass() {
+ ClassArgument ga = new ClassArgument();
+ classes.addElement(ga);
+ return ga;
+ }
+
+ /**
+ * A class corresponding the the nested "class" element.
+ * It contains a "name" attribute.
+ */
+ public class ClassArgument {
+ private String name;
+
+ /** Constructor for ClassArgument. */
+ public ClassArgument() {
+ }
+
+ /**
+ * Set the name attribute.
+ * @param name the name attribute.
+ */
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ /**
+ * Get the name attribute.
+ * @return the name attribute.
+ */
+ public String getName() {
+ return name;
+ }
+ }
+
+ /**
+ * Add a fileset.
+ * @param fs the fileset to add.
+ */
+ public void addFileSet(FileSet fs) {
+ files.add(fs);
+ }
+
+ /**
+ * Names of the classes to process.
+ * @return the array of classes.
+ * @since Ant 1.6.3
+ */
+ public String[] getClasses() {
+ ArrayList al = new ArrayList();
+ if (cls != null) {
+ StringTokenizer tok = new StringTokenizer(cls, ",", false);
+ while (tok.hasMoreTokens()) {
+ al.add(tok.nextToken().trim());
+ }
+ }
+
+ if (files.size() > 0) {
+ for (Enumeration e = files.elements(); e.hasMoreElements();) {
+ FileSet fs = (FileSet) e.nextElement();
+ String[] includedClasses = fs.getDirectoryScanner(
+ getProject()).getIncludedFiles();
+ for (int i = 0; i < includedClasses.length; i++) {
+ String className =
+ includedClasses[i].replace('\\', '.').replace('/', '.')
+ .substring(0, includedClasses[i].length() - 6);
+ al.add(className);
+ }
+ }
+ }
+ Enumeration e = classes.elements();
+ while (e.hasMoreElements()) {
+ ClassArgument arg = (ClassArgument) e.nextElement();
+ al.add(arg.getName());
+ }
+ return (String[]) al.toArray(new String[al.size()]);
+ }
+
+ /**
+ * Set the destination directory into which the Java source
+ * files should be compiled.
+ * @param destDir the destination directory.
+ */
+ public void setDestdir(File destDir) {
+ this.destDir = destDir;
+ }
+
+ /**
+ * The destination directory, if any.
+ * @return the destination directory.
+ * @since Ant 1.6.3
+ */
+ public File getDestdir() {
+ return destDir;
+ }
+
+ /**
+ * the classpath to use.
+ * @param src the classpath.
+ */
+ public void setClasspath(Path src) {
+ if (classpath == null) {
+ classpath = src;
+ } else {
+ classpath.append(src);
+ }
+ }
+
+ /**
+ * Path to use for classpath.
+ * @return a path to be configured.
+ */
+ public Path createClasspath() {
+ if (classpath == null) {
+ classpath = new Path(getProject());
+ }
+ return classpath.createPath();
+ }
+
+ /**
+ * Adds a reference to a classpath defined elsewhere.
+ * @param r a reference to a classpath.
+ * @todo this needs to be documented in the HTML docs.
+ */
+ public void setClasspathRef(Reference r) {
+ createClasspath().setRefid(r);
+ }
+
+ /**
+ * The classpath to use.
+ * @return the classpath.
+ * @since Ant 1.6.3
+ */
+ public Path getClasspath() {
+ return classpath;
+ }
+
+ /**
+ * location of bootstrap class files.
+ * @param src the bootstrap classpath.
+ */
+ public void setBootclasspath(Path src) {
+ if (bootclasspath == null) {
+ bootclasspath = src;
+ } else {
+ bootclasspath.append(src);
+ }
+ }
+
+ /**
+ * Adds path to bootstrap class files.
+ * @return a path to be configured.
+ */
+ public Path createBootclasspath() {
+ if (bootclasspath == null) {
+ bootclasspath = new Path(getProject());
+ }
+ return bootclasspath.createPath();
+ }
+
+ /**
+ * To the bootstrap path, this adds a reference to a classpath defined elsewhere.
+ * @param r a reference to a classpath
+ * @todo this needs to be documented in the HTML.
+ */
+ public void setBootClasspathRef(Reference r) {
+ createBootclasspath().setRefid(r);
+ }
+
+ /**
+ * The bootclasspath to use.
+ * @return the bootclass path.
+ * @since Ant 1.6.3
+ */
+ public Path getBootclasspath() {
+ return bootclasspath;
+ }
+
+ /**
+ * Concatenates the resulting header or source files for all
+ * the classes listed into this file.
+ * @param outputFile the output file.
+ */
+ public void setOutputFile(File outputFile) {
+ this.outputFile = outputFile;
+ }
+
+ /**
+ * The destination file, if any.
+ * @return the destination file.
+ * @since Ant 1.6.3
+ */
+ public File getOutputfile() {
+ return outputFile;
+ }
+
+ /**
+ * If true, output files should always be written (JDK1.2 only).
+ * @param force the value to use.
+ */
+ public void setForce(boolean force) {
+ this.force = force;
+ }
+
+ /**
+ * Whether output files should always be written.
+ * @return the force attribute.
+ * @since Ant 1.6.3
+ */
+ public boolean getForce() {
+ return force;
+ }
+
+ /**
+ * If true, specifies that old JDK1.0-style header files should be
+ * generated.
+ * (otherwise output file contain JNI-style native method function
+ * prototypes) (JDK1.2 only).
+ * @param old if true use old 1.0 style header files.
+ */
+ public void setOld(boolean old) {
+ this.old = old;
+ }
+
+ /**
+ * Whether old JDK1.0-style header files should be generated.
+ * @return the old attribute.
+ * @since Ant 1.6.3
+ */
+ public boolean getOld() {
+ return old;
+ }
+
+ /**
+ * If true, generate C declarations from the Java object file (used with old).
+ * @param stubs if true, generated C declarations.
+ */
+ public void setStubs(boolean stubs) {
+ this.stubs = stubs;
+ }
+
+ /**
+ * Whether C declarations from the Java object file should be generated.
+ * @return the stubs attribute.
+ * @since Ant 1.6.3
+ */
+ public boolean getStubs() {
+ return stubs;
+ }
+
+ /**
+ * If true, causes Javah to print a message concerning
+ * the status of the generated files.
+ * @param verbose if true, do verbose printing.
+ */
+ public void setVerbose(boolean verbose) {
+ this.verbose = verbose;
+ }
+
+ /**
+ * Whether verbose output should get generated.
+ * @return the verbose attribute.
+ * @since Ant 1.6.3
+ */
+ public boolean getVerbose() {
+ return verbose;
+ }
+
+ /**
+ * Choose the implementation for this particular task.
+ * @param impl the name of the implementation.
+ * @since Ant 1.6.3
+ */
+ public void setImplementation(String impl) {
+ if ("default".equals(impl)) {
+ facade.setImplementation(JavahAdapterFactory.getDefault());
+ } else {
+ facade.setImplementation(impl);
+ }
+ }
+
+ /**
+ * Adds an implementation specific command-line argument.
+ * @return a ImplementationSpecificArgument to be configured.
+ *
+ * @since Ant 1.6.3
+ */
+ public ImplementationSpecificArgument createArg() {
+ ImplementationSpecificArgument arg =
+ new ImplementationSpecificArgument();
+ facade.addImplementationArgument(arg);
+ return arg;
+ }
+
+ /**
+ * Returns the (implementation specific) settings given as nested
+ * arg elements.
+ * @return the arguments.
+ * @since Ant 1.6.3
+ */
+ public String[] getCurrentArgs() {
+ return facade.getArgs();
+ }
+
+ /**
+ * The classpath to use when loading the javah implementation
+ * if it is not a built-in one.
+ *
+ * @since Ant 1.8.0
+ */
+ public Path createImplementationClasspath() {
+ return facade.getImplementationClasspath(getProject());
+ }
+
+ /**
+ * Set the adapter explicitly.
+ * @since Ant 1.8.0
+ */
+ public void add(JavahAdapter adapter) {
+ if (nestedAdapter != null) {
+ throw new BuildException("Can't have more than one javah"
+ + " adapter");
+ }
+ nestedAdapter = adapter;
+ }
+
+ /**
+ * Execute the task
+ *
+ * @throws BuildException is there is a problem in the task execution.
+ */
+ public void execute() throws BuildException {
+ // first off, make sure that we've got a srcdir
+
+ if ((cls == null) && (classes.size() == 0) && (files.size() == 0)) {
+ throw new BuildException("class attribute must be set!",
+ getLocation());
+ }
+
+ if ((cls != null) && (classes.size() > 0) && (files.size() > 0)) {
+ throw new BuildException("set class attribute OR class element OR fileset, "
+ + "not 2 or more of them.", getLocation());
+ }
+
+ if (destDir != null) {
+ if (!destDir.isDirectory()) {
+ throw new BuildException("destination directory \"" + destDir
+ + "\" does not exist or is not a directory", getLocation());
+ }
+ if (outputFile != null) {
+ throw new BuildException("destdir and outputFile are mutually "
+ + "exclusive", getLocation());
+ }
+ }
+
+ if (classpath == null) {
+ classpath = (new Path(getProject())).concatSystemClasspath("last");
+ } else {
+ classpath = classpath.concatSystemClasspath("ignore");
+ }
+
+ JavahAdapter ad =
+ nestedAdapter != null ? nestedAdapter :
+ JavahAdapterFactory.getAdapter(facade.getImplementation(),
+ this,
+ createImplementationClasspath());
+ if (!ad.compile(this)) {
+ throw new BuildException("compilation failed");
+ }
+ }
+
+ /**
+ * Logs the compilation parameters, adds the files to compile and logs the
+ * &quot;niceSourceList&quot;
+ * @param cmd the command line.
+ */
+ public void logAndAddFiles(Commandline cmd) {
+ logAndAddFilesToCompile(cmd);
+ }
+
+ /**
+ * Logs the compilation parameters, adds the files to compile and logs the
+ * &quot;niceSourceList&quot;
+ * @param cmd the command line to add parameters to.
+ */
+ protected void logAndAddFilesToCompile(Commandline cmd) {
+ log("Compilation " + cmd.describeArguments(),
+ Project.MSG_VERBOSE);
+
+ StringBuffer niceClassList = new StringBuffer();
+ String[] c = getClasses();
+ for (int i = 0; i < c.length; i++) {
+ cmd.createArgument().setValue(c[i]);
+ niceClassList.append(" ");
+ niceClassList.append(c[i]);
+ niceClassList.append(StringUtils.LINE_SEP);
+ }
+
+ StringBuffer prefix = new StringBuffer("Class");
+ if (c.length > 1) {
+ prefix.append("es");
+ }
+ prefix.append(" to be compiled:");
+ prefix.append(StringUtils.LINE_SEP);
+
+ log(prefix.toString() + niceClassList.toString(), Project.MSG_VERBOSE);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/Native2Ascii.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/Native2Ascii.java
new file mode 100644
index 00000000..81a386fd
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/Native2Ascii.java
@@ -0,0 +1,328 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional;
+
+import java.io.File;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.DirectoryScanner;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.MatchingTask;
+import org.apache.tools.ant.taskdefs.optional.native2ascii.Native2AsciiAdapter;
+import org.apache.tools.ant.taskdefs.optional.native2ascii.Native2AsciiAdapterFactory;
+import org.apache.tools.ant.types.Mapper;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.util.FileNameMapper;
+import org.apache.tools.ant.util.IdentityMapper;
+import org.apache.tools.ant.util.SourceFileScanner;
+import org.apache.tools.ant.util.facade.FacadeTaskHelper;
+import org.apache.tools.ant.util.facade.ImplementationSpecificArgument;
+
+/**
+ * Converts files from native encodings to ASCII.
+ *
+ * @since Ant 1.2
+ */
+public class Native2Ascii extends MatchingTask {
+
+ private boolean reverse = false; // convert from ascii back to native
+ private String encoding = null; // encoding to convert to/from
+ private File srcDir = null; // Where to find input files
+ private File destDir = null; // Where to put output files
+ private String extension = null; // Extension of output files if different
+
+ private Mapper mapper;
+ private FacadeTaskHelper facade = null;
+ private Native2AsciiAdapter nestedAdapter = null;
+
+ /** No args constructor */
+ public Native2Ascii() {
+ facade = new FacadeTaskHelper(Native2AsciiAdapterFactory.getDefault());
+ }
+
+ /**
+ * Flag the conversion to run in the reverse sense,
+ * that is Ascii to Native encoding.
+ *
+ * @param reverse True if the conversion is to be reversed,
+ * otherwise false;
+ */
+ public void setReverse(boolean reverse) {
+ this.reverse = reverse;
+ }
+
+ /**
+ * The value of the reverse attribute.
+ * @return the reverse attribute.
+ * @since Ant 1.6.3
+ */
+ public boolean getReverse() {
+ return reverse;
+ }
+
+ /**
+ * Set the encoding to translate to/from.
+ * If unset, the default encoding for the JVM is used.
+ *
+ * @param encoding String containing the name of the Native
+ * encoding to convert from or to.
+ */
+ public void setEncoding(String encoding) {
+ this.encoding = encoding;
+ }
+
+ /**
+ * The value of the encoding attribute.
+ * @return the encoding attribute.
+ * @since Ant 1.6.3
+ */
+ public String getEncoding() {
+ return encoding;
+ }
+
+ /**
+ * Set the source directory in which to find files to convert.
+ *
+ * @param srcDir directory to find input file in.
+ */
+ public void setSrc(File srcDir) {
+ this.srcDir = srcDir;
+ }
+
+
+ /**
+ * Set the destination directory to place converted files into.
+ *
+ * @param destDir directory to place output file into.
+ */
+ public void setDest(File destDir) {
+ this.destDir = destDir;
+ }
+
+ /**
+ * Set the extension which converted files should have.
+ * If unset, files will not be renamed.
+ *
+ * @param ext File extension to use for converted files.
+ */
+ public void setExt(String ext) {
+ this.extension = ext;
+ }
+
+ /**
+ * Choose the implementation for this particular task.
+ * @param impl the name of the implementation
+ * @since Ant 1.6.3
+ */
+ public void setImplementation(String impl) {
+ if ("default".equals(impl)) {
+ facade.setImplementation(Native2AsciiAdapterFactory.getDefault());
+ } else {
+ facade.setImplementation(impl);
+ }
+ }
+
+ /**
+ * Defines the FileNameMapper to use (nested mapper element).
+ *
+ * @return the mapper to use for file name translations.
+ *
+ * @throws BuildException if more than one mapper is defined.
+ */
+ public Mapper createMapper() throws BuildException {
+ if (mapper != null) {
+ throw new BuildException("Cannot define more than one mapper",
+ getLocation());
+ }
+ mapper = new Mapper(getProject());
+ return mapper;
+ }
+
+ /**
+ * A nested filenamemapper
+ * @param fileNameMapper the mapper to add
+ * @since Ant 1.6.3
+ */
+ public void add(FileNameMapper fileNameMapper) {
+ createMapper().add(fileNameMapper);
+ }
+
+ /**
+ * Adds an implementation specific command-line argument.
+ * @return a ImplementationSpecificArgument to be configured
+ *
+ * @since Ant 1.6.3
+ */
+ public ImplementationSpecificArgument createArg() {
+ ImplementationSpecificArgument arg =
+ new ImplementationSpecificArgument();
+ facade.addImplementationArgument(arg);
+ return arg;
+ }
+
+ /**
+ * The classpath to use when loading the native2ascii
+ * implementation if it is not a built-in one.
+ *
+ * @since Ant 1.8.0
+ */
+ public Path createImplementationClasspath() {
+ return facade.getImplementationClasspath(getProject());
+ }
+
+ /**
+ * Set the adapter explicitly.
+ * @since Ant 1.8.0
+ */
+ public void add(Native2AsciiAdapter adapter) {
+ if (nestedAdapter != null) {
+ throw new BuildException("Can't have more than one native2ascii"
+ + " adapter");
+ }
+ nestedAdapter = adapter;
+ }
+
+ /**
+ * Execute the task
+ *
+ * @throws BuildException is there is a problem in the task execution.
+ */
+ public void execute() throws BuildException {
+
+ DirectoryScanner scanner = null; // Scanner to find our inputs
+ String[] files; // list of files to process
+
+ // default srcDir to basedir
+ if (srcDir == null) {
+ srcDir = getProject().resolveFile(".");
+ }
+
+ // Require destDir
+ if (destDir == null) {
+ throw new BuildException("The dest attribute must be set.");
+ }
+
+ // if src and dest dirs are the same, require the extension
+ // to be set, so we don't stomp every file. One could still
+ // include a file with the same extension, but ....
+ if (srcDir.equals(destDir) && extension == null && mapper == null) {
+ throw new BuildException("The ext attribute or a mapper must be set if"
+ + " src and dest dirs are the same.");
+ }
+
+ FileNameMapper m = null;
+ if (mapper == null) {
+ if (extension == null) {
+ m = new IdentityMapper();
+ } else {
+ m = new ExtMapper();
+ }
+ } else {
+ m = mapper.getImplementation();
+ }
+
+ scanner = getDirectoryScanner(srcDir);
+ files = scanner.getIncludedFiles();
+ SourceFileScanner sfs = new SourceFileScanner(this);
+ files = sfs.restrict(files, srcDir, destDir, m);
+ int count = files.length;
+ if (count == 0) {
+ return;
+ }
+ String message = "Converting " + count + " file"
+ + (count != 1 ? "s" : "") + " from ";
+ log(message + srcDir + " to " + destDir);
+ for (int i = 0; i < files.length; i++) {
+ convert(files[i], m.mapFileName(files[i])[0]);
+ }
+ }
+
+ /**
+ * Convert a single file.
+ *
+ * @param srcName name of the input file.
+ * @param destName name of the input file.
+ */
+ private void convert(String srcName, String destName)
+ throws BuildException {
+ File srcFile; // File to convert
+ File destFile; // where to put the results
+
+ // Build the full file names
+ srcFile = new File(srcDir, srcName);
+ destFile = new File(destDir, destName);
+
+ // Make sure we're not about to clobber something
+ if (srcFile.equals(destFile)) {
+ throw new BuildException("file " + srcFile
+ + " would overwrite its self");
+ }
+
+ // Make intermediate directories if needed
+ // TODO JDK 1.1 doesn't have File.getParentFile,
+ String parentName = destFile.getParent();
+ if (parentName != null) {
+ File parentFile = new File(parentName);
+
+ if (!parentFile.exists()
+ && !(parentFile.mkdirs() || parentFile.isDirectory())) {
+ throw new BuildException("cannot create parent directory "
+ + parentName);
+ }
+ }
+
+ log("converting " + srcName, Project.MSG_VERBOSE);
+ Native2AsciiAdapter ad =
+ nestedAdapter != null ? nestedAdapter :
+ Native2AsciiAdapterFactory.getAdapter(facade.getImplementation(),
+ this,
+ createImplementationClasspath());
+ if (!ad.convert(this, srcFile, destFile)) {
+ throw new BuildException("conversion failed");
+ }
+ }
+
+ /**
+ * Returns the (implementation specific) settings given as nested
+ * arg elements.
+ * @return the arguments.
+ * @since Ant 1.6.3
+ */
+ public String[] getCurrentArgs() {
+ return facade.getArgs();
+ }
+
+ private class ExtMapper implements FileNameMapper {
+
+ public void setFrom(String s) {
+ }
+ public void setTo(String s) {
+ }
+
+ public String[] mapFileName(String fileName) {
+ int lastDot = fileName.lastIndexOf('.');
+ if (lastDot >= 0) {
+ return new String[] {fileName.substring(0, lastDot)
+ + extension};
+ } else {
+ return new String[] {fileName + extension};
+ }
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/NetRexxC.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/NetRexxC.java
new file mode 100644
index 00000000..5ba2a760
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/NetRexxC.java
@@ -0,0 +1,1042 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Properties;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import netrexx.lang.Rexx;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.DirectoryScanner;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.MatchingTask;
+import org.apache.tools.ant.types.EnumeratedAttribute;
+import org.apache.tools.ant.util.FileUtils;
+
+// CheckStyle:InnerAssignmentCheck OFF - used too much in the file to be removed
+/**
+ * Compiles NetRexx source files.
+ * This task can take the following
+ * arguments:
+ * <ul>
+ * <li>binary</li>
+ * <li>classpath</li>
+ * <li>comments</li>
+ * <li>compile</li>
+ * <li>console</li>
+ * <li>crossref</li>
+ * <li>decimal</li>
+ * <li>destdir</li>
+ * <li>diag</li>
+ * <li>explicit</li>
+ * <li>format</li>
+ * <li>keep</li>
+ * <li>logo</li>
+ * <li>replace</li>
+ * <li>savelog</li>
+ * <li>srcdir</li>
+ * <li>sourcedir</li>
+ * <li>strictargs</li>
+ * <li>strictassign</li>
+ * <li>strictcase</li>
+ * <li>strictimport</li>
+ * <li>symbols</li>
+ * <li>time</li>
+ * <li>trace</li>
+ * <li>utf8</li>
+ * <li>verbose</li>
+ * <li>suppressMethodArgumentNotUsed</li>
+ * <li>suppressPrivatePropertyNotUsed</li>
+ * <li>suppressVariableNotUsed</li>
+ * <li>suppressExceptionNotSignalled</li>
+ * <li>suppressDeprecation</li>
+ * <li>removeKeepExtension</li>
+ * </ul>
+ * Of these arguments, the <b>srcdir</b> argument is required.
+ *
+ * <p>When this task executes, it will recursively scan the srcdir
+ * looking for NetRexx source files to compile. This task makes its
+ * compile decision based on timestamp.
+ * <p>Before files are compiled they and any other file in the
+ * srcdir will be copied to the destdir allowing support files to be
+ * located properly in the classpath. The reason for copying the source files
+ * before the compile is that NetRexxC has only two destinations for classfiles:
+ * <ol>
+ * <li>The current directory, and,</li>
+ * <li>The directory the source is in (see sourcedir option)
+ * </ol>
+ *
+ */
+public class NetRexxC extends MatchingTask {
+
+ // variables to hold arguments
+ private boolean binary;
+ private String classpath;
+ private boolean comments;
+ private boolean compact = true; // should be the default, as it integrates better in ant.
+ private boolean compile = true;
+ private boolean console;
+ private boolean crossref;
+ private boolean decimal = true;
+ private File destDir;
+ private boolean diag;
+ private boolean explicit;
+ private boolean format;
+ private boolean keep;
+ private boolean logo = true;
+ private boolean replace;
+ private boolean savelog;
+ private File srcDir;
+ private boolean sourcedir = true; // ?? Should this be the default for ant?
+ private boolean strictargs;
+ private boolean strictassign;
+ private boolean strictcase;
+ private boolean strictimport;
+ private boolean strictprops;
+ private boolean strictsignal;
+ private boolean symbols;
+ private boolean time;
+ private String trace = "trace2";
+ private boolean utf8;
+ private String verbose = "verbose3";
+ private boolean suppressMethodArgumentNotUsed = false;
+ private boolean suppressPrivatePropertyNotUsed = false;
+ private boolean suppressVariableNotUsed = false;
+ private boolean suppressExceptionNotSignalled = false;
+ private boolean suppressDeprecation = false;
+ private boolean removeKeepExtension = false;
+
+ // constants for the messages to suppress by flags and their corresponding properties
+ static final String MSG_METHOD_ARGUMENT_NOT_USED
+ = "Warning: Method argument is not used";
+ static final String MSG_PRIVATE_PROPERTY_NOT_USED
+ = "Warning: Private property is defined but not used";
+ static final String MSG_VARIABLE_NOT_USED
+ = "Warning: Variable is set but not used";
+ static final String MSG_EXCEPTION_NOT_SIGNALLED
+ = "is in SIGNALS list but is not signalled within the method";
+ static final String MSG_DEPRECATION = "has been deprecated";
+
+ // other implementation variables
+ private Vector compileList = new Vector();
+ private Hashtable filecopyList = new Hashtable();
+
+ /**
+ * Set whether literals are treated as binary, rather than NetRexx types.
+ * Valid true values are "yes", "on" or "true". Anything else sets the flag to false.
+ * The default is false.
+ * @param binary a <code>boolean</code> value.
+ */
+ public void setBinary(boolean binary) {
+ this.binary = binary;
+ }
+
+
+ /**
+ * Set the classpath used for NetRexx compilation.
+ * @param classpath the classpath to use.
+ */
+ public void setClasspath(String classpath) {
+ this.classpath = classpath;
+ }
+
+
+ /**
+ * Set whether comments are passed through to the generated java source.
+ * Valid true values are "yes", "on" or "true". Anything else sets the flag to false.
+ * The default value is false.
+ * @param comments a <code>boolean</code> value.
+ */
+ public void setComments(boolean comments) {
+ this.comments = comments;
+ }
+
+
+ /**
+ * Set whether error messages come out in compact or verbose format.
+ * Valid true values are "yes", "on" or "true". Anything else sets the flag to false.
+ * The default value is true.
+ * @param compact a <code>boolean</code> value.
+ */
+ public void setCompact(boolean compact) {
+ this.compact = compact;
+ }
+
+
+ /**
+ * Set whether the NetRexx compiler should compile the generated java code.
+ * Valid true values are "yes", "on" or "true". Anything else sets the flag to false.
+ * The default value is true.
+ * Setting this flag to false, will automatically set the keep flag to true.
+ * @param compile a <code>boolean</code> value.
+ */
+ public void setCompile(boolean compile) {
+ this.compile = compile;
+ if (!this.compile && !this.keep) {
+ this.keep = true;
+ }
+ }
+
+
+ /**
+ * Set whether or not compiler messages should be displayed on the 'console'.
+ * Note that this task will rely on the default value for filtering compile messages.
+ * Valid true values are "yes", "on" or "true". Anything else sets the flag to false.
+ * The default value is false.
+ * @param console a <code>boolean</code> value.
+ */
+ public void setConsole(boolean console) {
+ this.console = console;
+ }
+
+
+ /**
+ * Whether variable cross references are generated.
+ * Valid true values are "yes", "on" or "true". Anything else sets the flag to false.
+ * The default value is false.
+ * @param crossref a <code>boolean</code> value.
+ */
+ public void setCrossref(boolean crossref) {
+ this.crossref = crossref;
+ }
+
+
+ /**
+ * Set whether decimal arithmetic should be used for the netrexx code.
+ * Setting this to off will report decimal arithmetic as an error, for
+ * performance critical applications.
+ * Valid true values are "yes", "on" or "true". Anything else sets the flag to false.
+ * The default value is true.
+ * @param decimal a <code>boolean</code> value.
+ */
+ public void setDecimal(boolean decimal) {
+ this.decimal = decimal;
+ }
+
+
+ /**
+ * Set the destination directory into which the NetRexx source files
+ * should be copied and then compiled.
+ * @param destDirName the destination directory.
+ */
+ public void setDestDir(File destDirName) {
+ destDir = destDirName;
+ }
+
+
+ /**
+ * Whether diagnostic information about the compile is generated
+ * @param diag a <code>boolean</code> value.
+ */
+ public void setDiag(boolean diag) {
+ this.diag = diag;
+ }
+
+
+ /**
+ * Sets whether variables must be declared explicitly before use.
+ * Valid true values are "yes", "on" or "true". Anything else sets the flag to false.
+ * The default value is false.
+ * @param explicit a <code>boolean</code> value.
+ */
+ public void setExplicit(boolean explicit) {
+ this.explicit = explicit;
+ }
+
+
+ /**
+ * Whether the generated java code is formatted nicely or left to match
+ * NetRexx line numbers for call stack debugging.
+ * Valid true values are "yes", "on" or "true". Anything else sets the flag to false.
+ * The default value false.
+ * @param format a <code>boolean</code> value.
+ */
+ public void setFormat(boolean format) {
+ this.format = format;
+ }
+
+
+ /**
+ * Whether the generated java code is produced.
+ * This is not implemented yet.
+ * @param java a <code>boolean</code> value.
+ */
+ public void setJava(boolean java) {
+ log("The attribute java is currently unused.", Project.MSG_WARN);
+ }
+
+
+ /**
+ * Sets whether the generated java source file should be kept after
+ * compilation. The generated files will have an extension of .java.keep,
+ * <b>not</b> .java. See setRemoveKeepExtension
+ * Valid true values are "yes", "on" or "true". Anything else sets the flag to false.
+ * The default value is false.
+ * @param keep a <code>boolean</code> value.
+ * @see #setRemoveKeepExtension(boolean)
+ */
+ public void setKeep(boolean keep) {
+ this.keep = keep;
+ }
+
+
+ /**
+ * Whether the compiler text logo is displayed when compiling.
+ * Valid true values are "yes", "on" or "true". Anything else sets the flag to false.
+ * The default value is false.
+ * @param logo a <code>boolean</code> value.
+ */
+ public void setLogo(boolean logo) {
+ this.logo = logo;
+ }
+
+
+ /**
+ * Whether the generated .java file should be replaced when compiling.
+ * Valid true values are "yes", "on" or "true". Anything else sets the flag to false.
+ * The default value is false.
+ * @param replace a <code>boolean</code> value.
+ */
+ public void setReplace(boolean replace) {
+ this.replace = replace;
+ }
+
+
+ /**
+ * Sets whether the compiler messages will be written to NetRexxC.log as
+ * well as to the console.
+ * Valid true values are "yes", "on" or "true". Anything else sets the flag to false.
+ * The default value is false.
+ * @param savelog a <code>boolean</code> value.
+ */
+ public void setSavelog(boolean savelog) {
+ this.savelog = savelog;
+ }
+
+
+ /**
+ * Tells the NetRexx compiler to store the class files in the same
+ * directory as the source files. The alternative is the working directory.
+ * Valid true values are "yes", "on" or "true". Anything else sets the flag to false.
+ * The default value is true.
+ * @param sourcedir a <code>boolean</code> value.
+ */
+ public void setSourcedir(boolean sourcedir) {
+ this.sourcedir = sourcedir;
+ }
+
+
+ /**
+ * Set the source dir to find the source Java files.
+ * @param srcDirName the source directory.
+ */
+ public void setSrcDir(File srcDirName) {
+ srcDir = srcDirName;
+ }
+
+
+ /**
+ * Tells the NetRexx compiler that method calls always need parentheses,
+ * even if no arguments are needed, e.g. <code>aStringVar.getBytes</code>
+ * vs. <code>aStringVar.getBytes()</code>.
+ * Valid true values are "yes", "on" or "true". Anything else sets the flag to false.
+ * The default value is false.
+ * @param strictargs a <code>boolean</code> value.
+ */
+ public void setStrictargs(boolean strictargs) {
+ this.strictargs = strictargs;
+ }
+
+
+ /**
+ * Tells the NetRexx compile that assignments must match exactly on type.
+ * Valid true values are "yes", "on" or "true". Anything else sets the flag to false.
+ * The default value is false.
+ * @param strictassign a <code>boolean</code> value.
+ */
+ public void setStrictassign(boolean strictassign) {
+ this.strictassign = strictassign;
+ }
+
+
+ /**
+ * Specifies whether the NetRexx compiler should be case sensitive or not.
+ * Valid true values are "yes", "on" or "true". Anything else sets the flag to false.
+ * The default value is false.
+ * @param strictcase a <code>boolean</code> value.
+ */
+ public void setStrictcase(boolean strictcase) {
+ this.strictcase = strictcase;
+ }
+
+
+ /**
+ * Sets whether classes need to be imported explicitly using an <code>import</code>
+ * statement. By default the NetRexx compiler will import certain packages
+ * automatically.
+ * Valid true values are "yes", "on" or "true". Anything else sets the flag to false.
+ * The default value is false.
+ * @param strictimport a <code>boolean</code> value.
+ */
+ public void setStrictimport(boolean strictimport) {
+ this.strictimport = strictimport;
+ }
+
+
+ /**
+ * Sets whether local properties need to be qualified explicitly using
+ * <code>this</code>.
+ * Valid true values are "yes", "on" or "true". Anything else sets the flag to false.
+ * The default value is false.
+ * @param strictprops a <code>boolean</code> value.
+ */
+ public void setStrictprops(boolean strictprops) {
+ this.strictprops = strictprops;
+ }
+
+
+ /**
+ * Whether the compiler should force catching of exceptions by explicitly
+ * named types.
+ * Valid true values are "yes", "on" or "true". Anything else sets the flag to false.
+ * The default value is false
+ * @param strictsignal a <code>boolean</code> value.
+ */
+ public void setStrictsignal(boolean strictsignal) {
+ this.strictsignal = strictsignal;
+ }
+
+
+ /**
+ * Sets whether debug symbols should be generated into the class file.
+ * Valid true values are "yes", "on" or "true". Anything else sets the flag to false.
+ * The default value is false.
+ * @param symbols a <code>boolean</code> value.
+ */
+ public void setSymbols(boolean symbols) {
+ this.symbols = symbols;
+ }
+
+
+ /**
+ * Asks the NetRexx compiler to print compilation times to the console
+ * Valid true values are "yes", "on" or "true". Anything else sets the flag to false.
+ * The default value is false.
+ * @param time a <code>boolean</code> value.
+ */
+ public void setTime(boolean time) {
+ this.time = time;
+ }
+
+ /**
+ * Turns on or off tracing and directs the resultant trace output Valid
+ * values are: "trace", "trace1", "trace2" and "notrace". "trace" and
+ * "trace2".
+ * @param trace the value to set.
+ */
+ public void setTrace(TraceAttr trace) {
+ this.trace = trace.getValue();
+ }
+
+ /**
+ * Turns on or off tracing and directs the resultant trace output Valid
+ * values are: "trace", "trace1", "trace2" and "notrace". "trace" and
+ * "trace2".
+ * @param trace the value to set.
+ */
+ public void setTrace(String trace) {
+ TraceAttr t = new TraceAttr();
+
+ t.setValue(trace);
+ setTrace(t);
+ }
+
+
+ /**
+ * Tells the NetRexx compiler that the source is in UTF8.
+ * Valid true values are "yes", "on" or "true". Anything else sets the flag to false.
+ * The default value is false.
+ * @param utf8 a <code>boolean</code> value.
+ */
+ public void setUtf8(boolean utf8) {
+ this.utf8 = utf8;
+ }
+
+
+ /**
+ * Whether lots of warnings and error messages should be generated
+ * @param verbose the value to set - verbose&lt;level&gt; or noverbose.
+ */
+ public void setVerbose(VerboseAttr verbose) {
+ this.verbose = verbose.getValue();
+ }
+
+
+ /**
+ * Whether lots of warnings and error messages should be generated
+ * @param verbose the value to set - verbose&lt;level&gt; or noverbose.
+ */
+ public void setVerbose(String verbose) {
+ VerboseAttr v = new VerboseAttr();
+
+ v.setValue(verbose);
+ setVerbose(v);
+ }
+
+ /**
+ * Whether the task should suppress the "Method argument is not used" in
+ * strictargs-Mode, which can not be suppressed by the compiler itself.
+ * The warning is logged as verbose message, though.
+ * @param suppressMethodArgumentNotUsed a <code>boolean</code> value.
+ */
+ public void setSuppressMethodArgumentNotUsed(boolean suppressMethodArgumentNotUsed) {
+ this.suppressMethodArgumentNotUsed = suppressMethodArgumentNotUsed;
+ }
+
+
+ /**
+ * Whether the task should suppress the "Private property is defined but
+ * not used" in strictargs-Mode, which can be quite annoying while
+ * developing. The warning is logged as verbose message, though.
+ * @param suppressPrivatePropertyNotUsed a <code>boolean</code> value.
+ */
+ public void setSuppressPrivatePropertyNotUsed(boolean suppressPrivatePropertyNotUsed) {
+ this.suppressPrivatePropertyNotUsed = suppressPrivatePropertyNotUsed;
+ }
+
+
+ /**
+ * Whether the task should suppress the "Variable is set but not used" in
+ * strictargs-Mode. Be careful with this one! The warning is logged as
+ * verbose message, though.
+ * @param suppressVariableNotUsed a <code>boolean</code> value.
+ */
+ public void setSuppressVariableNotUsed(boolean suppressVariableNotUsed) {
+ this.suppressVariableNotUsed = suppressVariableNotUsed;
+ }
+
+
+ /**
+ * Whether the task should suppress the "FooException is in SIGNALS list
+ * but is not signalled within the method", which is sometimes rather
+ * useless. The warning is logged as verbose message, though.
+ * @param suppressExceptionNotSignalled a <code>boolean</code> value.
+ */
+ public void setSuppressExceptionNotSignalled(boolean suppressExceptionNotSignalled) {
+ this.suppressExceptionNotSignalled = suppressExceptionNotSignalled;
+ }
+
+
+ /**
+ * Tells whether we should filter out any deprecation-messages
+ * of the compiler out.
+ * @param suppressDeprecation a <code>boolean</code> value.
+ */
+ public void setSuppressDeprecation(boolean suppressDeprecation) {
+ this.suppressDeprecation = suppressDeprecation;
+ }
+
+
+ /**
+ * Tells whether the trailing .keep in nocompile-mode should be removed
+ * so that the resulting java source really ends on .java.
+ * This facilitates the use of the javadoc tool lateron.
+ */
+ public void setRemoveKeepExtension(boolean removeKeepExtension) {
+ this.removeKeepExtension = removeKeepExtension;
+ }
+
+
+ /**
+ * init-Method sets defaults from Properties. That way, when ant is called
+ * with arguments like -Dant.netrexxc.verbose=verbose5 one can easily take
+ * control of all netrexxc-tasks.
+ */
+ public void init() {
+ String p;
+
+ if ((p = getProject().getProperty("ant.netrexxc.binary")) != null) {
+ this.binary = Project.toBoolean(p);
+ }
+ // classpath makes no sense
+ if ((p = getProject().getProperty("ant.netrexxc.comments")) != null) {
+ this.comments = Project.toBoolean(p);
+ }
+ if ((p = getProject().getProperty("ant.netrexxc.compact")) != null) {
+ this.compact = Project.toBoolean(p);
+ }
+ if ((p = getProject().getProperty("ant.netrexxc.compile")) != null) {
+ this.compile = Project.toBoolean(p);
+ }
+ if ((p = getProject().getProperty("ant.netrexxc.console")) != null) {
+ this.console = Project.toBoolean(p);
+ }
+ if ((p = getProject().getProperty("ant.netrexxc.crossref")) != null) {
+ this.crossref = Project.toBoolean(p);
+ }
+ if ((p = getProject().getProperty("ant.netrexxc.decimal")) != null) {
+ this.decimal = Project.toBoolean(p);
+ // destDir
+ }
+ if ((p = getProject().getProperty("ant.netrexxc.diag")) != null) {
+ this.diag = Project.toBoolean(p);
+ }
+ if ((p = getProject().getProperty("ant.netrexxc.explicit")) != null) {
+ this.explicit = Project.toBoolean(p);
+ }
+ if ((p = getProject().getProperty("ant.netrexxc.format")) != null) {
+ this.format = Project.toBoolean(p);
+ }
+ if ((p = getProject().getProperty("ant.netrexxc.keep")) != null) {
+ this.keep = Project.toBoolean(p);
+ }
+ if ((p = getProject().getProperty("ant.netrexxc.logo")) != null) {
+ this.logo = Project.toBoolean(p);
+ }
+ if ((p = getProject().getProperty("ant.netrexxc.replace")) != null) {
+ this.replace = Project.toBoolean(p);
+ }
+ if ((p = getProject().getProperty("ant.netrexxc.savelog")) != null) {
+ this.savelog = Project.toBoolean(p);
+ // srcDir
+ }
+ if ((p = getProject().getProperty("ant.netrexxc.sourcedir")) != null) {
+ this.sourcedir = Project.toBoolean(p);
+ }
+ if ((p = getProject().getProperty("ant.netrexxc.strictargs")) != null) {
+ this.strictargs = Project.toBoolean(p);
+ }
+ if ((p = getProject().getProperty("ant.netrexxc.strictassign")) != null) {
+ this.strictassign = Project.toBoolean(p);
+ }
+ if ((p = getProject().getProperty("ant.netrexxc.strictcase")) != null) {
+ this.strictcase = Project.toBoolean(p);
+ }
+ if ((p = getProject().getProperty("ant.netrexxc.strictimport")) != null) {
+ this.strictimport = Project.toBoolean(p);
+ }
+ if ((p = getProject().getProperty("ant.netrexxc.strictprops")) != null) {
+ this.strictprops = Project.toBoolean(p);
+ }
+ if ((p = getProject().getProperty("ant.netrexxc.strictsignal")) != null) {
+ this.strictsignal = Project.toBoolean(p);
+ }
+ if ((p = getProject().getProperty("ant.netrexxc.symbols")) != null) {
+ this.symbols = Project.toBoolean(p);
+ }
+ if ((p = getProject().getProperty("ant.netrexxc.time")) != null) {
+ this.time = Project.toBoolean(p);
+ }
+ if ((p = getProject().getProperty("ant.netrexxc.trace")) != null) {
+ setTrace(p);
+ }
+ if ((p = getProject().getProperty("ant.netrexxc.utf8")) != null) {
+ this.utf8 = Project.toBoolean(p);
+ }
+ if ((p = getProject().getProperty("ant.netrexxc.verbose")) != null) {
+ setVerbose(p);
+ }
+ if ((p = getProject().getProperty("ant.netrexxc.suppressMethodArgumentNotUsed")) != null) {
+ this.suppressMethodArgumentNotUsed = Project.toBoolean(p);
+ }
+ if ((p = getProject().getProperty("ant.netrexxc.suppressPrivatePropertyNotUsed")) != null) {
+ this.suppressPrivatePropertyNotUsed = Project.toBoolean(p);
+ }
+ if ((p = getProject().getProperty("ant.netrexxc.suppressVariableNotUsed")) != null) {
+ this.suppressVariableNotUsed = Project.toBoolean(p);
+ }
+ if ((p = getProject().getProperty("ant.netrexxc.suppressExceptionNotSignalled")) != null) {
+ this.suppressExceptionNotSignalled = Project.toBoolean(p);
+ }
+ if ((p = getProject().getProperty("ant.netrexxc.suppressDeprecation")) != null) {
+ this.suppressDeprecation = Project.toBoolean(p);
+ }
+ if ((p = getProject().getProperty("ant.netrexxc.removeKeepExtension")) != null) {
+ this.removeKeepExtension = Project.toBoolean(p);
+ }
+ }
+
+
+ /**
+ * Executes the task - performs the actual compiler call.
+ * @throws BuildException on error.
+ */
+ public void execute() throws BuildException {
+
+ // first off, make sure that we've got a srcdir and destdir
+ if (srcDir == null || destDir == null) {
+ throw new BuildException("srcDir and destDir attributes must be set!");
+ }
+
+ // scan source and dest dirs to build up both copy lists and
+ // compile lists
+ // scanDir(srcDir, destDir);
+ DirectoryScanner ds = getDirectoryScanner(srcDir);
+
+ String[] files = ds.getIncludedFiles();
+
+ scanDir(srcDir, destDir, files);
+
+ // copy the source and support files
+ copyFilesToDestination();
+
+ // compile the source files
+ if (compileList.size() > 0) {
+ log("Compiling " + compileList.size() + " source file"
+ + (compileList.size() == 1 ? "" : "s")
+ + " to " + destDir);
+ doNetRexxCompile();
+ if (removeKeepExtension && (!compile || keep)) {
+ removeKeepExtensions();
+ }
+ }
+ }
+
+
+ /**
+ * Scans the directory looking for source files to be compiled and support
+ * files to be copied.
+ */
+ private void scanDir(File srcDir, File destDir, String[] files) {
+ for (int i = 0; i < files.length; i++) {
+ File srcFile = new File(srcDir, files[i]);
+ File destFile = new File(destDir, files[i]);
+ String filename = files[i];
+ // if it's a non source file, copy it if a later date than the
+ // dest
+ // if it's a source file, see if the destination class file
+ // needs to be recreated via compilation
+ if (filename.toLowerCase().endsWith(".nrx")) {
+ File classFile =
+ new File(destDir,
+ filename.substring(0, filename.lastIndexOf('.')) + ".class");
+ File javaFile =
+ new File(destDir,
+ filename.substring(0, filename.lastIndexOf('.'))
+ + (removeKeepExtension ? ".java" : ".java.keep"));
+
+ // nocompile case tests against .java[.keep] file
+ if (!compile && srcFile.lastModified() > javaFile.lastModified()) {
+ filecopyList.put(srcFile.getAbsolutePath(), destFile.getAbsolutePath());
+ compileList.addElement(destFile.getAbsolutePath());
+ } else if (compile && srcFile.lastModified() > classFile.lastModified()) {
+ // compile case tests against .class file
+ filecopyList.put(srcFile.getAbsolutePath(), destFile.getAbsolutePath());
+ compileList.addElement(destFile.getAbsolutePath());
+ }
+ } else {
+ if (srcFile.lastModified() > destFile.lastModified()) {
+ filecopyList.put(srcFile.getAbsolutePath(), destFile.getAbsolutePath());
+ }
+ }
+ }
+ }
+
+
+ /** Copy eligible files from the srcDir to destDir */
+ private void copyFilesToDestination() {
+ if (filecopyList.size() > 0) {
+ log("Copying " + filecopyList.size() + " file"
+ + (filecopyList.size() == 1 ? "" : "s")
+ + " to " + destDir.getAbsolutePath());
+
+ Enumeration e = filecopyList.keys();
+
+ while (e.hasMoreElements()) {
+ String fromFile = (String) e.nextElement();
+ String toFile = (String) filecopyList.get(fromFile);
+
+ try {
+ FileUtils.getFileUtils().copyFile(fromFile, toFile);
+ } catch (IOException ioe) {
+ String msg = "Failed to copy " + fromFile + " to " + toFile
+ + " due to " + ioe.getMessage();
+
+ throw new BuildException(msg, ioe);
+ }
+ }
+ }
+ }
+
+
+ /**
+ * Rename .java.keep files (back) to .java. The netrexxc renames all
+ * .java files to .java.keep if either -keep or -nocompile option is set.
+ */
+ private void removeKeepExtensions() {
+ if (compileList.size() > 0) {
+ log("Removing .keep extension on " + compileList.size() + " file"
+ + (compileList.size() == 1 ? "" : "s"));
+ Enumeration e = compileList.elements();
+ while (e.hasMoreElements()) {
+ String nrxName = (String) e.nextElement();
+ String baseName = nrxName.substring(0, nrxName.lastIndexOf('.'));
+ File fromFile = new File(baseName + ".java.keep");
+ File toFile = new File(baseName + ".java");
+ if (fromFile.renameTo(toFile)) {
+ log("Successfully renamed " + fromFile + " to " + toFile, Project.MSG_VERBOSE);
+ } else {
+ log("Failed to rename " + fromFile + " to " + toFile);
+ }
+ }
+ }
+ }
+
+
+ /** Performs a compile using the NetRexx 1.1.x compiler */
+ private void doNetRexxCompile() throws BuildException {
+ log("Using NetRexx compiler", Project.MSG_VERBOSE);
+
+ String classpath = getCompileClasspath();
+ StringBuffer compileOptions = new StringBuffer();
+
+ // create an array of strings for input to the compiler: one array
+ // comes from the compile options, the other from the compileList
+ String[] compileOptionsArray = getCompileOptionsAsArray();
+ String[] fileListArray = new String[compileList.size()];
+ Enumeration e = compileList.elements();
+ int j = 0;
+
+ while (e.hasMoreElements()) {
+ fileListArray[j] = (String) e.nextElement();
+ j++;
+ }
+ // create a single array of arguments for the compiler
+ String[] compileArgs = new String[compileOptionsArray.length + fileListArray.length];
+
+ for (int i = 0; i < compileOptionsArray.length; i++) {
+ compileArgs[i] = compileOptionsArray[i];
+ }
+ for (int i = 0; i < fileListArray.length; i++) {
+ compileArgs[i + compileOptionsArray.length] = fileListArray[i];
+ }
+
+ // print nice output about what we are doing for the log
+ compileOptions.append("Compilation args: ");
+ for (int i = 0; i < compileOptionsArray.length; i++) {
+ compileOptions.append(compileOptionsArray[i]);
+ compileOptions.append(" ");
+ }
+ log(compileOptions.toString(), Project.MSG_VERBOSE);
+
+ String eol = System.getProperty("line.separator");
+ StringBuffer niceSourceList = new StringBuffer("Files to be compiled:" + eol);
+
+ final int size = compileList.size();
+ for (int i = 0; i < size; i++) {
+ niceSourceList.append(" ");
+ niceSourceList.append(compileList.elementAt(i).toString());
+ niceSourceList.append(eol);
+ }
+
+ log(niceSourceList.toString(), Project.MSG_VERBOSE);
+
+ // need to set java.class.path property and restore it later
+ // since the NetRexx compiler has no option for the classpath
+ String currentClassPath = System.getProperty("java.class.path");
+ Properties currentProperties = System.getProperties();
+
+ currentProperties.put("java.class.path", classpath);
+
+ try {
+ StringWriter out = new StringWriter();
+ PrintWriter w = null;
+ int rc =
+ COM.ibm.netrexx.process.NetRexxC.main(new Rexx(compileArgs),
+ w = new PrintWriter(out));
+ String sdir = srcDir.getAbsolutePath();
+ String ddir = destDir.getAbsolutePath();
+ boolean doReplace = !(sdir.equals(ddir));
+ int dlen = ddir.length();
+ String l;
+ BufferedReader in = new BufferedReader(new StringReader(out.toString()));
+
+ log("replacing destdir '" + ddir + "' through sourcedir '"
+ + sdir + "'", Project.MSG_VERBOSE);
+ while ((l = in.readLine()) != null) {
+ int idx;
+
+ while (doReplace && ((idx = l.indexOf(ddir)) != -1)) {
+ // path is mentioned in the message
+ l = (new StringBuffer(l)).replace(idx, idx + dlen, sdir).toString();
+ }
+ // verbose level logging for suppressed messages
+ if (suppressMethodArgumentNotUsed
+ && l.indexOf(MSG_METHOD_ARGUMENT_NOT_USED) != -1) {
+ log(l, Project.MSG_VERBOSE);
+ } else if (suppressPrivatePropertyNotUsed
+ && l.indexOf(MSG_PRIVATE_PROPERTY_NOT_USED) != -1) {
+ log(l, Project.MSG_VERBOSE);
+ } else if (suppressVariableNotUsed
+ && l.indexOf(MSG_VARIABLE_NOT_USED) != -1) {
+ log(l, Project.MSG_VERBOSE);
+ } else if (suppressExceptionNotSignalled
+ && l.indexOf(MSG_EXCEPTION_NOT_SIGNALLED) != -1) {
+ log(l, Project.MSG_VERBOSE);
+ } else if (suppressDeprecation
+ && l.indexOf(MSG_DEPRECATION) != -1) {
+ log(l, Project.MSG_VERBOSE);
+ } else if (l.indexOf("Error:") != -1) {
+ // error level logging for compiler errors
+ log(l, Project.MSG_ERR);
+ } else if (l.indexOf("Warning:") != -1) {
+ // warning for all warning messages
+ log(l, Project.MSG_WARN);
+ } else {
+ log(l, Project.MSG_INFO); // info level for the rest.
+ }
+ }
+ if (rc > 1) {
+ throw new BuildException("Compile failed, messages should "
+ + "have been provided.");
+ }
+ if (w.checkError()) {
+ throw new IOException("Encountered an error");
+ }
+ } catch (IOException ioe) {
+ throw new BuildException("Unexpected IOException while "
+ + "playing with Strings", ioe);
+ } finally {
+ // need to reset java.class.path property
+ // since the NetRexx compiler has no option for the classpath
+ currentProperties = System.getProperties();
+ currentProperties.put("java.class.path", currentClassPath);
+ }
+
+ }
+
+
+ /** Builds the compilation classpath. */
+ private String getCompileClasspath() {
+ StringBuffer classpath = new StringBuffer();
+
+ // add dest dir to classpath so that previously compiled and
+ // untouched classes are on classpath
+ classpath.append(destDir.getAbsolutePath());
+
+ // add our classpath to the mix
+ if (this.classpath != null) {
+ addExistingToClasspath(classpath, this.classpath);
+ }
+
+ // add the system classpath
+ // addExistingToClasspath(classpath,System.getProperty("java.class.path"));
+ return classpath.toString();
+ }
+
+
+ /** This */
+ private String[] getCompileOptionsAsArray() {
+ Vector options = new Vector();
+
+ options.addElement(binary ? "-binary" : "-nobinary");
+ options.addElement(comments ? "-comments" : "-nocomments");
+ options.addElement(compile ? "-compile" : "-nocompile");
+ options.addElement(compact ? "-compact" : "-nocompact");
+ options.addElement(console ? "-console" : "-noconsole");
+ options.addElement(crossref ? "-crossref" : "-nocrossref");
+ options.addElement(decimal ? "-decimal" : "-nodecimal");
+ options.addElement(diag ? "-diag" : "-nodiag");
+ options.addElement(explicit ? "-explicit" : "-noexplicit");
+ options.addElement(format ? "-format" : "-noformat");
+ options.addElement(keep ? "-keep" : "-nokeep");
+ options.addElement(logo ? "-logo" : "-nologo");
+ options.addElement(replace ? "-replace" : "-noreplace");
+ options.addElement(savelog ? "-savelog" : "-nosavelog");
+ options.addElement(sourcedir ? "-sourcedir" : "-nosourcedir");
+ options.addElement(strictargs ? "-strictargs" : "-nostrictargs");
+ options.addElement(strictassign ? "-strictassign" : "-nostrictassign");
+ options.addElement(strictcase ? "-strictcase" : "-nostrictcase");
+ options.addElement(strictimport ? "-strictimport" : "-nostrictimport");
+ options.addElement(strictprops ? "-strictprops" : "-nostrictprops");
+ options.addElement(strictsignal ? "-strictsignal" : "-nostrictsignal");
+ options.addElement(symbols ? "-symbols" : "-nosymbols");
+ options.addElement(time ? "-time" : "-notime");
+ options.addElement("-" + trace);
+ options.addElement(utf8 ? "-utf8" : "-noutf8");
+ options.addElement("-" + verbose);
+
+ String[] results = new String[options.size()];
+
+ options.copyInto(results);
+ return results;
+ }
+
+
+ /**
+ * Takes a classpath-like string, and adds each element of this string to
+ * a new classpath, if the components exist. Components that don't exist,
+ * aren't added. We do this, because jikes issues warnings for
+ * non-existent files/dirs in his classpath, and these warnings are pretty
+ * annoying.
+ *
+ * @param target - target classpath
+ * @param source - source classpath to get file objects.
+ */
+ private void addExistingToClasspath(StringBuffer target, String source) {
+ StringTokenizer tok = new StringTokenizer(source,
+ System.getProperty("path.separator"), false);
+
+ while (tok.hasMoreTokens()) {
+ File f = getProject().resolveFile(tok.nextToken());
+
+ if (f.exists()) {
+ target.append(File.pathSeparator);
+ target.append(f.getAbsolutePath());
+ } else {
+ log("Dropping from classpath: "
+ + f.getAbsolutePath(), Project.MSG_VERBOSE);
+ }
+ }
+
+ }
+
+
+ /**
+ * Enumerated class corresponding to the trace attribute.
+ */
+ public static class TraceAttr extends EnumeratedAttribute {
+ /** {@inheritDoc}. */
+ public String[] getValues() {
+ return new String[]{"trace", "trace1", "trace2", "notrace"};
+ }
+ }
+
+ /**
+ * Enumerated class corresponding to the verbose attribute.
+ */
+ public static class VerboseAttr extends EnumeratedAttribute {
+ /** {@inheritDoc}. */
+ public String[] getValues() {
+ return new String[]{"verbose", "verbose0", "verbose1",
+ "verbose2", "verbose3", "verbose4",
+ "verbose5", "noverbose"};
+ }
+ }
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/PropertyFile.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/PropertyFile.java
new file mode 100644
index 00000000..162cab1a
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/PropertyFile.java
@@ -0,0 +1,726 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional;
+
+import java.io.BufferedInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.text.DateFormat;
+import java.text.DecimalFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.types.EnumeratedAttribute;
+import org.apache.tools.ant.util.FileUtils;
+import org.apache.tools.ant.util.LayoutPreservingProperties;
+
+/**
+ * Modifies settings in a property file.
+ *
+ * <p>The following is an example of its usage:</p>
+ * <pre>
+ * &lt;target name="setState"&gt;
+ * &lt;property
+ * name="header"
+ * value="##Generated file - do not modify!"/&gt;
+ * &lt;propertyfile file="apropfile.properties" comment="${header}"&gt;
+ * &lt;entry key="product.version.major" type="int" value="5"/&gt;
+ * &lt;entry key="product.version.minor" type="int" value="0"/&gt;
+ * &lt;entry key="product.build.major" type="int" value="0" /&gt;
+ * &lt;entry key="product.build.minor" type="int" operation="+" /&gt;
+ * &lt;entry key="product.build.date" type="date" value="now" /&gt;
+ * &lt;entry key="intSet" type="int" operation="=" value="681"/&gt;
+ * &lt;entry key="intDec" type="int" operation="-"/&gt;
+ * &lt;entry key="StringEquals" type="string" value="testValue"/&gt;
+ * &lt;/propertyfile&gt;
+ * &lt;/target&gt;
+ * </pre>
+ *
+ * The &lt;propertyfile&gt; task must have:
+ * <ul>
+ * <li>file</li>
+ * </ul>
+ * Other parameters are:
+ * <ul>
+ * <li>comment</li>
+ * <li>key</li>
+ * <li>operation</li>
+ * <li>type</li>
+ * <li>value (the final four being eliminated shortly)</li>
+ * </ul>
+ *
+ * The &lt;entry&gt; task must have:
+ * <ul>
+ * <li>key</li>
+ * </ul>
+ * Other parameters are:
+ * <ul>
+ * <li>operation</li>
+ * <li>type</li>
+ * <li>value</li>
+ * <li>default</li>
+ * <li>unit</li>
+ * </ul>
+ *
+ * If type is unspecified, it defaults to string.
+ *
+ * Parameter values:
+ * <ul>
+ * <li>operation:</li>
+ * <ul>
+ * <li>"=" (set -- default)</li>
+ * <li>"-" (dec)</li>
+ * <li>"+" (inc)</li>
+ * </ul>
+ * <li>type:</li>
+ * <ul>
+ * <li>"int"</li>
+ * <li>"date"</li>
+ * <li>"string"</li>
+ * </ul>
+ * <li>value:</li>
+ * <ul>
+ * <li>holds the default value, if the property
+ * was not found in property file</li>
+ * <li>"now" In case of type "date", the
+ * value "now" will be replaced by the current
+ * date/time and used even if a valid date was
+ * found in the property file.</li>
+ * </ul>
+ * </ul>
+ *
+ * <p>String property types can only use the "=" operation.
+ * Int property types can only use the "=", "-" or "+" operations.<p>
+ *
+ * The message property is used for the property file header, with "\\" being
+ * a newline delimiter character.
+ *
+ */
+public class PropertyFile extends Task {
+
+ /* ========================================================================
+ *
+ * Instance variables.
+ */
+
+ // Use this to prepend a message to the properties file
+ private String comment;
+
+ private Properties properties;
+ private File propertyfile;
+ private boolean useJDKProperties;
+
+ private Vector entries = new Vector();
+
+ /* ========================================================================
+ *
+ * Constructors
+ */
+
+ /* ========================================================================
+ *
+ * Methods
+ */
+
+ /**
+ * Execute the task.
+ * @throws BuildException on error.
+ */
+ @Override
+ public void execute() throws BuildException {
+ checkParameters();
+ readFile();
+ executeOperation();
+ writeFile();
+ }
+
+ /**
+ * The entry nested element.
+ * @return an entry nested element to be configured.
+ */
+ public Entry createEntry() {
+ Entry e = new Entry();
+ entries.addElement(e);
+ return e;
+ }
+
+ private void executeOperation() throws BuildException {
+ for (Enumeration e = entries.elements(); e.hasMoreElements();) {
+ Entry entry = (Entry) e.nextElement();
+ entry.executeOn(properties);
+ }
+ }
+
+ private void readFile() throws BuildException {
+ if (useJDKProperties) {
+ // user chose to use standard Java properties, which loose
+ // comments and layout
+ properties = new Properties();
+ } else {
+ properties = new LayoutPreservingProperties();
+ }
+ try {
+ if (propertyfile.exists()) {
+ log("Updating property file: "
+ + propertyfile.getAbsolutePath());
+ FileInputStream fis = null;
+ try {
+ fis = new FileInputStream(propertyfile);
+ BufferedInputStream bis = new BufferedInputStream(fis);
+ properties.load(bis);
+ } finally {
+ if (fis != null) {
+ fis.close();
+ }
+ }
+ } else {
+ log("Creating new property file: "
+ + propertyfile.getAbsolutePath());
+ FileOutputStream out = null;
+ try {
+ out = new FileOutputStream(propertyfile.getAbsolutePath());
+ out.flush();
+ } finally {
+ if (out != null) {
+ out.close();
+ }
+ }
+ }
+ } catch (IOException ioe) {
+ throw new BuildException(ioe.toString());
+ }
+ }
+
+ private void checkParameters() throws BuildException {
+ if (!checkParam(propertyfile)) {
+ throw new BuildException("file token must not be null.",
+ getLocation());
+ }
+ }
+
+ /**
+ * Location of the property file to be edited; required.
+ * @param file the property file.
+ */
+ public void setFile(File file) {
+ propertyfile = file;
+ }
+
+ /**
+ * optional header comment for the file
+ * @param hdr the string to use for the comment.
+ */
+ public void setComment(String hdr) {
+ comment = hdr;
+ }
+
+ /**
+ * optional flag to use original Java properties (as opposed to
+ * layout preserving properties)
+ */
+ public void setJDKProperties(boolean val) {
+ useJDKProperties = val;
+ }
+
+ private void writeFile() throws BuildException {
+ // Write to RAM first, as an OOME could otherwise produce a truncated file:
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ try {
+ properties.store(baos, comment);
+ } catch (IOException x) { // should not happen
+ throw new BuildException(x, getLocation());
+ }
+ try {
+ OutputStream os = new FileOutputStream(propertyfile);
+ try {
+ try {
+ os.write(baos.toByteArray());
+ } finally {
+ os.close();
+ }
+ } catch (IOException x) { // possibly corrupt
+ FileUtils.getFileUtils().tryHardToDelete(propertyfile);
+ throw x;
+ }
+ } catch (IOException x) { // opening, writing, or closing
+ throw new BuildException(x, getLocation());
+ }
+ }
+
+ private boolean checkParam(File param) {
+ return !(param == null);
+ }
+
+ /**
+ * Instance of this class represents nested elements of
+ * a task propertyfile.
+ */
+ public static class Entry {
+ private static final int DEFAULT_INT_VALUE = 0;
+ private static final String DEFAULT_DATE_VALUE = "now";
+ private static final String DEFAULT_STRING_VALUE = "";
+
+ private String key = null;
+ private int type = Type.STRING_TYPE;
+ private int operation = Operation.EQUALS_OPER;
+ private String value = null;
+ private String defaultValue = null;
+ private String newValue = null;
+ private String pattern = null;
+ private int field = Calendar.DATE;
+
+ /**
+ * Name of the property name/value pair
+ * @param value the key.
+ */
+ public void setKey(String value) {
+ this.key = value;
+ }
+
+ /**
+ * Value to set (=), to add (+) or subtract (-)
+ * @param value the value.
+ */
+ public void setValue(String value) {
+ this.value = value;
+ }
+
+ /**
+ * operation to apply.
+ * &quot;+&quot; or &quot;=&quot;
+ *(default) for all datatypes; &quot;-&quot; for date and int only)\.
+ * @param value the operation enumerated value.
+ */
+ public void setOperation(Operation value) {
+ this.operation = Operation.toOperation(value.getValue());
+ }
+
+ /**
+ * Regard the value as : int, date or string (default)
+ * @param value the type enumerated value.
+ */
+ public void setType(Type value) {
+ this.type = Type.toType(value.getValue());
+ }
+
+ /**
+ * Initial value to set for a property if it is not
+ * already defined in the property file.
+ * For type date, an additional keyword is allowed: &quot;now&quot;
+ * @param value the default value.
+ */
+ public void setDefault(String value) {
+ this.defaultValue = value;
+ }
+
+ /**
+ * For int and date type only. If present, Values will
+ * be parsed and formatted accordingly.
+ * @param value the pattern to use.
+ */
+ public void setPattern(String value) {
+ this.pattern = value;
+ }
+
+ /**
+ * The unit of the value to be applied to date +/- operations.
+ * Valid Values are:
+ * <ul>
+ * <li>millisecond</li>
+ * <li>second</li>
+ * <li>minute</li>
+ * <li>hour</li>
+ * <li>day (default)</li>
+ * <li>week</li>
+ * <li>month</li>
+ * <li>year</li>
+ * </ul>
+ * This only applies to date types using a +/- operation.
+ * @param unit the unit enumerated value.
+ * @since Ant 1.5
+ */
+ public void setUnit(PropertyFile.Unit unit) {
+ field = unit.getCalendarField();
+ }
+
+ /**
+ * Apply the nested element to the properties.
+ * @param props the properties to apply the entry on.
+ * @throws BuildException if there is an error.
+ */
+ protected void executeOn(Properties props) throws BuildException {
+ checkParameters();
+
+ if (operation == Operation.DELETE_OPER) {
+ props.remove(key);
+ return;
+ }
+
+ // type may be null because it wasn't set
+ String oldValue = (String) props.get(key);
+ try {
+ if (type == Type.INTEGER_TYPE) {
+ executeInteger(oldValue);
+ } else if (type == Type.DATE_TYPE) {
+ executeDate(oldValue);
+ } else if (type == Type.STRING_TYPE) {
+ executeString(oldValue);
+ } else {
+ throw new BuildException("Unknown operation type: "
+ + type);
+ }
+ } catch (NullPointerException npe) {
+ // Default to string type
+ // which means do nothing
+ npe.printStackTrace();
+ }
+
+ if (newValue == null) {
+ newValue = "";
+ }
+
+ // Insert as a string by default
+ props.put(key, newValue);
+ }
+
+ /**
+ * Handle operations for type <code>date</code>.
+ *
+ * @param oldValue the current value read from the property file or
+ * <code>null</code> if the <code>key</code> was
+ * not contained in the property file.
+ */
+ private void executeDate(String oldValue) throws BuildException {
+ Calendar currentValue = Calendar.getInstance();
+
+ if (pattern == null) {
+ pattern = "yyyy/MM/dd HH:mm";
+ }
+ DateFormat fmt = new SimpleDateFormat(pattern);
+
+ String currentStringValue = getCurrentValue(oldValue);
+ if (currentStringValue == null) {
+ currentStringValue = DEFAULT_DATE_VALUE;
+ }
+
+ if ("now".equals(currentStringValue)) {
+ currentValue.setTime(new Date());
+ } else {
+ try {
+ currentValue.setTime(fmt.parse(currentStringValue));
+ } catch (ParseException pe) {
+ // swallow
+ }
+ }
+
+ if (operation != Operation.EQUALS_OPER) {
+ int offset = 0;
+ try {
+ offset = Integer.parseInt(value);
+ if (operation == Operation.DECREMENT_OPER) {
+ offset = -1 * offset;
+ }
+ } catch (NumberFormatException e) {
+ throw new BuildException("Value not an integer on " + key);
+ }
+ currentValue.add(field, offset);
+ }
+
+ newValue = fmt.format(currentValue.getTime());
+ }
+
+
+ /**
+ * Handle operations for type <code>int</code>.
+ *
+ * @param oldValue the current value read from the property file or
+ * <code>null</code> if the <code>key</code> was
+ * not contained in the property file.
+ */
+ private void executeInteger(String oldValue) throws BuildException {
+ int currentValue = DEFAULT_INT_VALUE;
+ int newV = DEFAULT_INT_VALUE;
+
+
+ DecimalFormat fmt = (pattern != null) ? new DecimalFormat(pattern)
+ : new DecimalFormat();
+ try {
+ String curval = getCurrentValue(oldValue);
+ if (curval != null) {
+ currentValue = fmt.parse(curval).intValue();
+ } else {
+ currentValue = 0;
+ }
+ } catch (NumberFormatException nfe) {
+ // swallow
+ } catch (ParseException pe) {
+ // swallow
+ }
+
+ if (operation == Operation.EQUALS_OPER) {
+ newV = currentValue;
+ } else {
+ int operationValue = 1;
+ if (value != null) {
+ try {
+ operationValue = fmt.parse(value).intValue();
+ } catch (NumberFormatException nfe) {
+ // swallow
+ } catch (ParseException pe) {
+ // swallow
+ }
+ }
+
+ if (operation == Operation.INCREMENT_OPER) {
+ newV = currentValue + operationValue;
+ } else if (operation == Operation.DECREMENT_OPER) {
+ newV = currentValue - operationValue;
+ }
+ }
+
+ this.newValue = fmt.format(newV);
+ }
+
+ /**
+ * Handle operations for type <code>string</code>.
+ *
+ * @param oldValue the current value read from the property file or
+ * <code>null</code> if the <code>key</code> was
+ * not contained in the property file.
+ */
+ private void executeString(String oldValue) throws BuildException {
+ String newV = DEFAULT_STRING_VALUE;
+
+ String currentValue = getCurrentValue(oldValue);
+
+ if (currentValue == null) {
+ currentValue = DEFAULT_STRING_VALUE;
+ }
+
+ if (operation == Operation.EQUALS_OPER) {
+ newV = currentValue;
+ } else if (operation == Operation.INCREMENT_OPER) {
+ newV = currentValue + value;
+ }
+ this.newValue = newV;
+ }
+
+ /**
+ * Check if parameter combinations can be supported
+ * @todo make sure the 'unit' attribute is only specified on date
+ * fields
+ */
+ private void checkParameters() throws BuildException {
+ if (type == Type.STRING_TYPE
+ && operation == Operation.DECREMENT_OPER) {
+ throw new BuildException("- is not supported for string "
+ + "properties (key:" + key + ")");
+ }
+ if (value == null && defaultValue == null && operation != Operation.DELETE_OPER) {
+ throw new BuildException("\"value\" and/or \"default\" "
+ + "attribute must be specified (key:" + key + ")");
+ }
+ if (key == null) {
+ throw new BuildException("key is mandatory");
+ }
+ if (type == Type.STRING_TYPE && pattern != null) {
+ throw new BuildException("pattern is not supported for string "
+ + "properties (key:" + key + ")");
+ }
+ }
+
+ private String getCurrentValue(String oldValue) {
+ String ret = null;
+ if (operation == Operation.EQUALS_OPER) {
+ // If only value is specified, the property is set to it
+ // regardless of its previous value.
+ if (value != null && defaultValue == null) {
+ ret = value;
+ }
+
+ // If only default is specified and the property previously
+ // existed in the property file, it is unchanged.
+ if (value == null && defaultValue != null && oldValue != null) {
+ ret = oldValue;
+ }
+
+ // If only default is specified and the property did not
+ // exist in the property file, the property is set to default.
+ if (value == null && defaultValue != null && oldValue == null) {
+ ret = defaultValue;
+ }
+
+ // If value and default are both specified and the property
+ // previously existed in the property file, the property
+ // is set to value.
+ if (value != null && defaultValue != null && oldValue != null) {
+ ret = value;
+ }
+
+ // If value and default are both specified and the property
+ // did not exist in the property file, the property is set
+ // to default.
+ if (value != null && defaultValue != null && oldValue == null) {
+ ret = defaultValue;
+ }
+ } else {
+ ret = (oldValue == null) ? defaultValue : oldValue;
+ }
+
+ return ret;
+ }
+
+ /**
+ * Enumerated attribute with the values "+", "-", "="
+ */
+ public static class Operation extends EnumeratedAttribute {
+
+ // Property type operations
+ /** + */
+ public static final int INCREMENT_OPER = 0;
+ /** - */
+ public static final int DECREMENT_OPER = 1;
+ /** = */
+ public static final int EQUALS_OPER = 2;
+ /** del */
+ public static final int DELETE_OPER = 3;
+
+ /** {@inheritDoc}. */
+ @Override
+ public String[] getValues() {
+ return new String[] {"+", "-", "=", "del"};
+ }
+
+ /**
+ * Convert string to index.
+ * @param oper the string to convert.
+ * @return the index.
+ */
+ public static int toOperation(String oper) {
+ if ("+".equals(oper)) {
+ return INCREMENT_OPER;
+ } else if ("-".equals(oper)) {
+ return DECREMENT_OPER;
+ } else if ("del".equals(oper)) {
+ return DELETE_OPER;
+ }
+ return EQUALS_OPER;
+ }
+ }
+
+ /**
+ * Enumerated attribute with the values "int", "date" and "string".
+ */
+ public static class Type extends EnumeratedAttribute {
+
+ // Property types
+ /** int */
+ public static final int INTEGER_TYPE = 0;
+ /** date */
+ public static final int DATE_TYPE = 1;
+ /** string */
+ public static final int STRING_TYPE = 2;
+
+ /** {@inheritDoc} */
+ @Override
+ public String[] getValues() {
+ return new String[] {"int", "date", "string"};
+ }
+
+ /**
+ * Convert string to index.
+ * @param type the string to convert.
+ * @return the index.
+ */
+ public static int toType(String type) {
+ if ("int".equals(type)) {
+ return INTEGER_TYPE;
+ } else if ("date".equals(type)) {
+ return DATE_TYPE;
+ }
+ return STRING_TYPE;
+ }
+ }
+ }
+
+ /**
+ * Borrowed from Tstamp
+ * @todo share all this time stuff across many tasks as a datetime datatype
+ * @since Ant 1.5
+ */
+ public static class Unit extends EnumeratedAttribute {
+
+ private static final String MILLISECOND = "millisecond";
+ private static final String SECOND = "second";
+ private static final String MINUTE = "minute";
+ private static final String HOUR = "hour";
+ private static final String DAY = "day";
+ private static final String WEEK = "week";
+ private static final String MONTH = "month";
+ private static final String YEAR = "year";
+
+ private static final String[] UNITS
+ = {MILLISECOND, SECOND, MINUTE, HOUR,
+ DAY, WEEK, MONTH, YEAR };
+
+ private Map calendarFields = new HashMap();
+
+ /** no arg constructor */
+ public Unit() {
+ calendarFields.put(MILLISECOND,
+ new Integer(Calendar.MILLISECOND));
+ calendarFields.put(SECOND, new Integer(Calendar.SECOND));
+ calendarFields.put(MINUTE, new Integer(Calendar.MINUTE));
+ calendarFields.put(HOUR, new Integer(Calendar.HOUR_OF_DAY));
+ calendarFields.put(DAY, new Integer(Calendar.DATE));
+ calendarFields.put(WEEK, new Integer(Calendar.WEEK_OF_YEAR));
+ calendarFields.put(MONTH, new Integer(Calendar.MONTH));
+ calendarFields.put(YEAR, new Integer(Calendar.YEAR));
+ }
+
+ /**
+ * Convert the value to a Calendar field index.
+ * @return the calendar value.
+ */
+ public int getCalendarField() {
+ String key = getValue().toLowerCase();
+ Integer i = (Integer) calendarFields.get(key);
+ return i.intValue();
+ }
+
+ /** {@inheritDoc}. */
+ @Override
+ public String[] getValues() {
+ return UNITS;
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/RenameExtensions.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/RenameExtensions.java
new file mode 100644
index 00000000..c4acadb2
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/RenameExtensions.java
@@ -0,0 +1,146 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+/*
+ * Task to rename files based on extension. This task has the following
+ * properties which can be set:
+ * <ul>
+ * <li>fromExtension: </li>
+ * <li>toExtension: </li>
+ * <li>srcDir: </li>
+ * <li>replace: </li>
+ * </ul>
+ */
+
+package org.apache.tools.ant.taskdefs.optional;
+
+import java.io.File;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.MatchingTask;
+import org.apache.tools.ant.taskdefs.Move;
+import org.apache.tools.ant.types.Mapper;
+
+/**
+ *
+ * @version 1.2
+ *
+ * @deprecated since 1.5.x.
+ * Use &lt;move&gt; instead
+ */
+public class RenameExtensions extends MatchingTask {
+
+ private String fromExtension = "";
+ private String toExtension = "";
+ private boolean replace = false;
+ private File srcDir;
+
+ private Mapper.MapperType globType;
+
+
+ /** Creates new RenameExtensions */
+ public RenameExtensions() {
+ super();
+ globType = new Mapper.MapperType();
+ globType.setValue("glob");
+ }
+
+ /**
+ * The string that files must end in to be renamed
+ *
+ * @param from the extension of files being renamed.
+ */
+ public void setFromExtension(String from) {
+ fromExtension = from;
+ }
+
+ /**
+ * The string that renamed files will end with on
+ * completion
+ *
+ * @param to the extension of the renamed files.
+ */
+ public void setToExtension(String to) {
+ toExtension = to;
+ }
+
+ /**
+ * store replace attribute - this determines whether the target file
+ * should be overwritten if present
+ *
+ * @param replace if true overwrite any target files that exist.
+ */
+ public void setReplace(boolean replace) {
+ this.replace = replace;
+ }
+
+ /**
+ * Set the source dir to find the files to be renamed.
+ *
+ * @param srcDir the source directory.
+ */
+ public void setSrcDir(File srcDir) {
+ this.srcDir = srcDir;
+ }
+
+ /**
+ * Executes the task.
+ *
+ * @throws BuildException is there is a problem in the task execution.
+ */
+ public void execute() throws BuildException {
+
+ // first off, make sure that we've got a from and to extension
+ if (fromExtension == null || toExtension == null || srcDir == null) {
+ throw new BuildException("srcDir, fromExtension and toExtension "
+ + "attributes must be set!");
+ }
+
+ log("DEPRECATED - The renameext task is deprecated. Use move instead.",
+ Project.MSG_WARN);
+ log("Replace this with:", Project.MSG_INFO);
+ log("<move todir=\"" + srcDir + "\" overwrite=\"" + replace + "\">",
+ Project.MSG_INFO);
+ log(" <fileset dir=\"" + srcDir + "\" />", Project.MSG_INFO);
+ log(" <mapper type=\"glob\"", Project.MSG_INFO);
+ log(" from=\"*" + fromExtension + "\"", Project.MSG_INFO);
+ log(" to=\"*" + toExtension + "\" />", Project.MSG_INFO);
+ log("</move>", Project.MSG_INFO);
+ log("using the same patterns on <fileset> as you\'ve used here",
+ Project.MSG_INFO);
+
+ Move move = new Move();
+ move.bindToOwner(this);
+ move.setOwningTarget(getOwningTarget());
+ move.setTaskName(getTaskName());
+ move.setLocation(getLocation());
+ move.setTodir(srcDir);
+ move.setOverwrite(replace);
+
+ fileset.setDir(srcDir);
+ move.addFileset(fileset);
+
+ Mapper me = move.createMapper();
+ me.setType(globType);
+ me.setFrom("*" + fromExtension);
+ me.setTo("*" + toExtension);
+
+ move.execute();
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ReplaceRegExp.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ReplaceRegExp.java
new file mode 100644
index 00000000..d088096a
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ReplaceRegExp.java
@@ -0,0 +1,533 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Reader;
+import java.io.Writer;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.types.FileSet;
+import org.apache.tools.ant.types.RegularExpression;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.ResourceCollection;
+import org.apache.tools.ant.types.Substitution;
+import org.apache.tools.ant.types.resources.FileProvider;
+import org.apache.tools.ant.types.resources.Union;
+import org.apache.tools.ant.util.FileUtils;
+import org.apache.tools.ant.util.regexp.Regexp;
+import org.apache.tools.ant.util.regexp.RegexpUtil;
+
+/**
+ * Performs regular expression string replacements in a text
+ * file. The input file(s) must be able to be properly processed by
+ * a Reader instance. That is, they must be text only, no binary.
+ *
+ * The syntax of the regular expression depends on the implementation that
+ * you choose to use. The system property <code>ant.regexp.regexpimpl</code>
+ * will be the classname of the implementation that will be used (the default
+ * is <code>org.apache.tools.ant.util.regexp.JakartaOroRegexp</code> and
+ * requires the Jakarta Oro Package).
+ *
+ * <pre>
+ * Available implementations:
+ *
+ * org.apache.tools.ant.util.regexp.Jdk14RegexpRegexp (default)
+ * Uses Java's built-in regular expression package
+ *
+ * org.apache.tools.ant.util.regexp.JakartaOroRegexp
+ * Requires the jakarta-oro package
+ *
+ * org.apache.tools.ant.util.regexp.JakartaRegexpRegexp
+ * Requires the jakarta-regexp package
+ *
+ * Usage:
+ *
+ * Call Syntax:
+ *
+ * &lt;replaceregexp file="file"
+ * match="pattern"
+ * replace="pattern"
+ * flags="options"?
+ * byline="true|false"? &gt;
+ * regexp?
+ * substitution?
+ * fileset*
+ * &lt;/replaceregexp&gt;
+ *
+ * NOTE: You must have either the file attribute specified, or at least one fileset subelement
+ * to operation on. You may not have the file attribute specified if you nest fileset elements
+ * inside this task. Also, you cannot specify both match and a regular expression subelement at
+ * the same time, nor can you specify the replace attribute and the substitution subelement at
+ * the same time.
+ *
+ * Attributes:
+ *
+ * file --&gt; A single file to operation on (mutually exclusive
+ * with the fileset subelements)
+ * match --&gt; The Regular expression to match
+ * replace --&gt; The Expression replacement string
+ * flags --&gt; The options to give to the replacement
+ * g = Substitute all occurrences. default is to replace only the first one
+ * i = Case insensitive match
+ *
+ * byline --&gt; Should this file be processed a single line at a time (default is false)
+ * "true" indicates to perform replacement on a line by line basis
+ * "false" indicates to perform replacement on the whole file at once.
+ *
+ * Example:
+ *
+ * The following call could be used to replace an old property name in a ".properties"
+ * file with a new name. In the replace attribute, you can refer to any part of the
+ * match expression in parenthesis using backslash followed by a number like '\1'.
+ *
+ * &lt;replaceregexp file="test.properties"
+ * match="MyProperty=(.*)"
+ * replace="NewProperty=\1"
+ * byline="true" /&gt;
+ *
+ * </pre>
+ *
+ */
+public class ReplaceRegExp extends Task {
+
+ private File file;
+ private String flags;
+ private boolean byline;
+ private Union resources;
+ private RegularExpression regex;
+ private Substitution subs;
+
+ private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+
+ private boolean preserveLastModified = false;
+
+ /**
+ * Encoding to assume for the files
+ */
+ private String encoding = null;
+
+ /** Default Constructor */
+ public ReplaceRegExp() {
+ super();
+ this.file = null;
+ this.flags = "";
+ this.byline = false;
+
+ this.regex = null;
+ this.subs = null;
+ }
+
+
+ /**
+ * file for which the regular expression should be replaced;
+ * required unless a nested fileset is supplied.
+ * @param file The file for which the reg exp should be replaced.
+ */
+ public void setFile(File file) {
+ this.file = file;
+ }
+
+
+ /**
+ * the regular expression pattern to match in the file(s);
+ * required if no nested &lt;regexp&gt; is used
+ * @param match the match attribute.
+ */
+ public void setMatch(String match) {
+ if (regex != null) {
+ throw new BuildException("Only one regular expression is allowed");
+ }
+
+ regex = new RegularExpression();
+ regex.setPattern(match);
+ }
+
+
+ /**
+ * The substitution pattern to place in the file(s) in place
+ * of the regular expression.
+ * Required if no nested &lt;substitution&gt; is used
+ * @param replace the replace attribute
+ */
+
+ public void setReplace(String replace) {
+ if (subs != null) {
+ throw new BuildException("Only one substitution expression is "
+ + "allowed");
+ }
+
+ subs = new Substitution();
+ subs.setExpression(replace);
+ }
+
+ /**
+ * The flags to use when matching the regular expression. For more
+ * information, consult the Perl5 syntax.
+ * <ul>
+ * <li>g : Global replacement. Replace all occurrences found
+ * <li>i : Case Insensitive. Do not consider case in the match
+ * <li>m : Multiline. Treat the string as multiple lines of input,
+ * using "^" and "$" as the start or end of any line, respectively,
+ * rather than start or end of string.
+ * <li> s : Singleline. Treat the string as a single line of input, using
+ * "." to match any character, including a newline, which normally,
+ * it would not match.
+ *</ul>
+ * @param flags the flags attribute
+ */
+ public void setFlags(String flags) {
+ this.flags = flags;
+ }
+
+
+ /**
+ * Process the file(s) one line at a time, executing the replacement
+ * on one line at a time. This is useful if you
+ * want to only replace the first occurrence of a regular expression on
+ * each line, which is not easy to do when processing the file as a whole.
+ * Defaults to <i>false</i>.
+ *
+ * @param byline the byline attribute as a string
+ * @deprecated since 1.6.x.
+ * Use setByLine(boolean).
+ */
+ @Deprecated
+ public void setByLine(String byline) {
+ Boolean res = Boolean.valueOf(byline);
+
+ if (res == null) {
+ res = Boolean.FALSE;
+ }
+ this.byline = res.booleanValue();
+ }
+
+ /**
+ * Process the file(s) one line at a time, executing the replacement
+ * on one line at a time. This is useful if you
+ * want to only replace the first occurrence of a regular expression on
+ * each line, which is not easy to do when processing the file as a whole.
+ * Defaults to <i>false</i>.
+ *
+ * @param byline the byline attribute
+ */
+ public void setByLine(boolean byline) {
+ this.byline = byline;
+ }
+
+ /**
+ * Specifies the encoding Ant expects the files to be in -
+ * defaults to the platforms default encoding.
+ * @param encoding the encoding attribute
+ *
+ * @since Ant 1.6
+ */
+ public void setEncoding(String encoding) {
+ this.encoding = encoding;
+ }
+
+ /**
+ * list files to apply the replacement to
+ * @param set the fileset element
+ */
+ public void addFileset(FileSet set) {
+ addConfigured(set);
+ }
+
+ /**
+ * Support arbitrary file system based resource collections.
+ *
+ * @since Ant 1.8.0
+ */
+ public void addConfigured(ResourceCollection rc) {
+ if (!rc.isFilesystemOnly()) {
+ throw new BuildException("only filesystem resources are supported");
+ }
+ if (resources == null) {
+ resources = new Union();
+ }
+ resources.add(rc);
+ }
+
+ /**
+ * A regular expression.
+ * You can use this element to refer to a previously
+ * defined regular expression datatype instance
+ * @return the regular expression object to be configured as an element
+ */
+ public RegularExpression createRegexp() {
+ if (regex != null) {
+ throw new BuildException("Only one regular expression is allowed.");
+ }
+
+ regex = new RegularExpression();
+ return regex;
+ }
+
+
+ /**
+ * A substitution pattern. You can use this element to refer to a previously
+ * defined substitution pattern datatype instance.
+ * @return the substitution pattern object to be configured as an element
+ */
+ public Substitution createSubstitution() {
+ if (subs != null) {
+ throw new BuildException("Only one substitution expression is "
+ + "allowed");
+ }
+
+ subs = new Substitution();
+ return subs;
+ }
+
+ /**
+ * Whether the file timestamp shall be preserved even if the file
+ * is modified.
+ *
+ * @since Ant 1.8.0
+ */
+ public void setPreserveLastModified(boolean b) {
+ preserveLastModified = b;
+ }
+
+ /**
+ * Invoke a regular expression (r) on a string (input) using
+ * substitutions (s) for a matching regex.
+ *
+ * @param r a regular expression
+ * @param s a Substitution
+ * @param input the string to do the replacement on
+ * @param options The options for the regular expression
+ * @return the replacement result
+ */
+ protected String doReplace(RegularExpression r,
+ Substitution s,
+ String input,
+ int options) {
+ String res = input;
+ Regexp regexp = r.getRegexp(getProject());
+
+ if (regexp.matches(input, options)) {
+ log("Found match; substituting", Project.MSG_DEBUG);
+ res = regexp.substitute(input, s.getExpression(getProject()),
+ options);
+ }
+
+ return res;
+ }
+
+
+ /**
+ * Perform the replacement on a file
+ *
+ * @param f the file to perform the replacement on
+ * @param options the regular expressions options
+ * @exception IOException if an error occurs
+ */
+ protected void doReplace(File f, int options)
+ throws IOException {
+ File temp = FILE_UTILS.createTempFile("replace", ".txt", null, true, true);
+ try {
+ boolean changes = false;
+
+ InputStream is = new FileInputStream(f);
+ try {
+ Reader r = encoding != null ? new InputStreamReader(is, encoding) : new InputStreamReader(is);
+ OutputStream os = new FileOutputStream(temp);
+ try {
+ Writer w = encoding != null ? new OutputStreamWriter(os, encoding) : new OutputStreamWriter(os);
+
+ log("Replacing pattern '" + regex.getPattern(getProject())
+ + "' with '" + subs.getExpression(getProject())
+ + "' in '" + f.getPath() + "'" + (byline ? " by line" : "")
+ + (flags.length() > 0 ? " with flags: '" + flags + "'" : "")
+ + ".", Project.MSG_VERBOSE);
+
+ if (byline) {
+ r = new BufferedReader(r);
+ w = new BufferedWriter(w);
+
+ StringBuffer linebuf = new StringBuffer();
+ int c;
+ boolean hasCR = false;
+
+ do {
+ c = r.read();
+
+ if (c == '\r') {
+ if (hasCR) {
+ // second CR -> EOL + possibly empty line
+ changes |= replaceAndWrite(linebuf.toString(),
+ w, options);
+ w.write('\r');
+
+ linebuf = new StringBuffer();
+ // hasCR is still true (for the second one)
+ } else {
+ // first CR in this line
+ hasCR = true;
+ }
+ } else if (c == '\n') {
+ // LF -> EOL
+ changes |= replaceAndWrite(linebuf.toString(),
+ w, options);
+ if (hasCR) {
+ w.write('\r');
+ hasCR = false;
+ }
+ w.write('\n');
+
+ linebuf = new StringBuffer();
+ } else { // any other char
+ if ((hasCR) || (c < 0)) {
+ // Mac-style linebreak or EOF (or both)
+ changes |= replaceAndWrite(linebuf.toString(),
+ w, options);
+ if (hasCR) {
+ w.write('\r');
+ hasCR = false;
+ }
+
+ linebuf = new StringBuffer();
+ }
+
+ if (c >= 0) {
+ linebuf.append((char) c);
+ }
+ }
+ } while (c >= 0);
+
+ } else {
+ changes = multilineReplace(r, w, options);
+ }
+
+ r.close();
+ w.close();
+
+ } finally {
+ os.close();
+ }
+ } finally {
+ is.close();
+ }
+ if (changes) {
+ log("File has changed; saving the updated file", Project.MSG_VERBOSE);
+ try {
+ long origLastModified = f.lastModified();
+ FILE_UTILS.rename(temp, f);
+ if (preserveLastModified) {
+ FILE_UTILS.setFileLastModified(f, origLastModified);
+ }
+ temp = null;
+ } catch (IOException e) {
+ throw new BuildException("Couldn't rename temporary file "
+ + temp, e, getLocation());
+ }
+ } else {
+ log("No change made", Project.MSG_DEBUG);
+ }
+ } finally {
+ if (temp != null) {
+ temp.delete();
+ }
+ }
+ }
+
+
+ /**
+ * Execute the task
+ *
+ * @throws BuildException is there is a problem in the task execution.
+ */
+ @Override
+ public void execute() throws BuildException {
+ if (regex == null) {
+ throw new BuildException("No expression to match.");
+ }
+ if (subs == null) {
+ throw new BuildException("Nothing to replace expression with.");
+ }
+
+ if (file != null && resources != null) {
+ throw new BuildException("You cannot supply the 'file' attribute "
+ + "and resource collections at the same "
+ + "time.");
+ }
+
+ int options = RegexpUtil.asOptions(flags);
+
+ if (file != null && file.exists()) {
+ try {
+ doReplace(file, options);
+ } catch (IOException e) {
+ log("An error occurred processing file: '"
+ + file.getAbsolutePath() + "': " + e.toString(),
+ Project.MSG_ERR);
+ }
+ } else if (file != null) {
+ log("The following file is missing: '"
+ + file.getAbsolutePath() + "'", Project.MSG_ERR);
+ }
+
+ if (resources != null) {
+ for (Resource r : resources) {
+ FileProvider fp =
+ r.as(FileProvider.class);
+ File f = fp.getFile();
+
+ if (f.exists()) {
+ try {
+ doReplace(f, options);
+ } catch (Exception e) {
+ log("An error occurred processing file: '"
+ + f.getAbsolutePath() + "': " + e.toString(),
+ Project.MSG_ERR);
+ }
+ } else {
+ log("The following file is missing: '"
+ + f.getAbsolutePath() + "'", Project.MSG_ERR);
+ }
+ }
+ }
+ }
+
+ private boolean multilineReplace(Reader r, Writer w, int options)
+ throws IOException {
+ return replaceAndWrite(FileUtils.safeReadFully(r), w, options);
+ }
+
+ private boolean replaceAndWrite(String s, Writer w, int options)
+ throws IOException {
+ String res = doReplace(regex, subs, s, options);
+ w.write(res);
+ return !res.equals(s);
+ }
+}
+
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/Rpm.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/Rpm.java
new file mode 100644
index 00000000..b395a16c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/Rpm.java
@@ -0,0 +1,364 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional;
+
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.util.Map;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.taskdefs.Execute;
+import org.apache.tools.ant.taskdefs.ExecuteStreamHandler;
+import org.apache.tools.ant.taskdefs.LogOutputStream;
+import org.apache.tools.ant.taskdefs.LogStreamHandler;
+import org.apache.tools.ant.taskdefs.PumpStreamHandler;
+import org.apache.tools.ant.taskdefs.condition.Os;
+import org.apache.tools.ant.types.Commandline;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.util.FileUtils;
+
+/**
+ * Invokes the rpm tool to build a Linux installation file.
+ *
+ */
+public class Rpm extends Task {
+
+ private static final String PATH1 = "PATH";
+ private static final String PATH2 = "Path";
+ private static final String PATH3 = "path";
+
+ /**
+ * the spec file
+ */
+ private String specFile;
+
+ /**
+ * the rpm top dir
+ */
+ private File topDir;
+
+ /**
+ * the rpm command to use
+ */
+ private String command = "-bb";
+
+ /**
+ * The executable to use for building the packages.
+ * @since Ant 1.6
+ */
+ private String rpmBuildCommand = null;
+
+ /**
+ * clean BUILD directory
+ */
+ private boolean cleanBuildDir = false;
+
+ /**
+ * remove spec file
+ */
+ private boolean removeSpec = false;
+
+ /**
+ * remove sources
+ */
+ private boolean removeSource = false;
+
+ /**
+ * the file to direct standard output from the command
+ */
+ private File output;
+
+ /**
+ * the file to direct standard error from the command
+ */
+ private File error;
+
+ /**
+ * Halt on error return value from rpm build.
+ */
+ private boolean failOnError = false;
+
+ /**
+ * Don't show output of RPM build command on console. This does not affect
+ * the printing of output and error messages to files.
+ */
+ private boolean quiet = false;
+
+ /**
+ * Execute the task
+ *
+ * @throws BuildException is there is a problem in the task execution.
+ */
+ public void execute() throws BuildException {
+
+ Commandline toExecute = new Commandline();
+
+ toExecute.setExecutable(rpmBuildCommand == null
+ ? guessRpmBuildCommand()
+ : rpmBuildCommand);
+ if (topDir != null) {
+ toExecute.createArgument().setValue("--define");
+ toExecute.createArgument().setValue("_topdir " + topDir);
+ }
+
+ toExecute.createArgument().setLine(command);
+
+ if (cleanBuildDir) {
+ toExecute.createArgument().setValue("--clean");
+ }
+ if (removeSpec) {
+ toExecute.createArgument().setValue("--rmspec");
+ }
+ if (removeSource) {
+ toExecute.createArgument().setValue("--rmsource");
+ }
+
+ toExecute.createArgument().setValue("SPECS/" + specFile);
+
+ ExecuteStreamHandler streamhandler = null;
+ OutputStream outputstream = null;
+ OutputStream errorstream = null;
+ if (error == null && output == null) {
+ if (!quiet) {
+ streamhandler = new LogStreamHandler(this, Project.MSG_INFO,
+ Project.MSG_WARN);
+ } else {
+ streamhandler = new LogStreamHandler(this, Project.MSG_DEBUG,
+ Project.MSG_DEBUG);
+ }
+ } else {
+ if (output != null) {
+ try {
+ BufferedOutputStream bos
+ = new BufferedOutputStream(new FileOutputStream(output));
+ outputstream = new PrintStream(bos);
+ } catch (IOException e) {
+ throw new BuildException(e, getLocation());
+ }
+ } else if (!quiet) {
+ outputstream = new LogOutputStream(this, Project.MSG_INFO);
+ } else {
+ outputstream = new LogOutputStream(this, Project.MSG_DEBUG);
+ }
+ if (error != null) {
+ try {
+ BufferedOutputStream bos
+ = new BufferedOutputStream(new FileOutputStream(error));
+ errorstream = new PrintStream(bos);
+ } catch (IOException e) {
+ throw new BuildException(e, getLocation());
+ }
+ } else if (!quiet) {
+ errorstream = new LogOutputStream(this, Project.MSG_WARN);
+ } else {
+ errorstream = new LogOutputStream(this, Project.MSG_DEBUG);
+ }
+ streamhandler = new PumpStreamHandler(outputstream, errorstream);
+ }
+
+ Execute exe = getExecute(toExecute, streamhandler);
+ try {
+ log("Building the RPM based on the " + specFile + " file");
+ int returncode = exe.execute();
+ if (Execute.isFailure(returncode)) {
+ String msg = "'" + toExecute.getExecutable()
+ + "' failed with exit code " + returncode;
+ if (failOnError) {
+ throw new BuildException(msg);
+ }
+ log(msg, Project.MSG_ERR);
+ }
+ } catch (IOException e) {
+ throw new BuildException(e, getLocation());
+ } finally {
+ FileUtils.close(outputstream);
+ FileUtils.close(errorstream);
+ }
+ }
+
+ /**
+ * The directory which will have the expected
+ * subdirectories, SPECS, SOURCES, BUILD, SRPMS ; optional.
+ * If this isn't specified,
+ * the <tt>baseDir</tt> value is used
+ *
+ * @param td the directory containing the normal RPM directories.
+ */
+ public void setTopDir(File td) {
+ this.topDir = td;
+ }
+
+ /**
+ * What command to issue to the rpm build tool; optional.
+ * The default is "-bb"
+ * @param c the command to use.
+ */
+ public void setCommand(String c) {
+ this.command = c;
+ }
+
+ /**
+ * The name of the spec File to use; required.
+ * @param sf the spec file name to use.
+ */
+ public void setSpecFile(String sf) {
+ if ((sf == null) || (sf.trim().length() == 0)) {
+ throw new BuildException("You must specify a spec file", getLocation());
+ }
+ this.specFile = sf;
+ }
+
+ /**
+ * Flag (optional, default=false) to remove
+ * the generated files in the BUILD directory
+ * @param cbd a <code>boolean</code> value.
+ */
+ public void setCleanBuildDir(boolean cbd) {
+ cleanBuildDir = cbd;
+ }
+
+ /**
+ * Flag (optional, default=false) to remove the spec file from SPECS
+ * @param rs a <code>boolean</code> value.
+ */
+ public void setRemoveSpec(boolean rs) {
+ removeSpec = rs;
+ }
+
+ /**
+ * Flag (optional, default=false)
+ * to remove the sources after the build.
+ * See the <tt>--rmsource</tt> option of rpmbuild.
+ * @param rs a <code>boolean</code> value.
+ */
+ public void setRemoveSource(boolean rs) {
+ removeSource = rs;
+ }
+
+ /**
+ * Optional file to save stdout to.
+ * @param output the file to save stdout to.
+ */
+ public void setOutput(File output) {
+ this.output = output;
+ }
+
+ /**
+ * Optional file to save stderr to
+ * @param error the file to save error output to.
+ */
+ public void setError(File error) {
+ this.error = error;
+ }
+
+ /**
+ * The executable to run when building; optional.
+ * The default is <code>rpmbuild</code>.
+ *
+ * @since Ant 1.6
+ * @param c the rpm build executable
+ */
+ public void setRpmBuildCommand(String c) {
+ this.rpmBuildCommand = c;
+ }
+
+ /**
+ * If <code>true</code>, stop the build process when the rpmbuild command
+ * exits with an error status.
+ * @param value <code>true</code> if it should halt, otherwise
+ * <code>false</code>. The default is <code>false</code>.
+ *
+ * @since Ant 1.6.3
+ */
+ public void setFailOnError(boolean value) {
+ failOnError = value;
+ }
+
+ /**
+ * If true, output from the RPM build command will only be logged to DEBUG.
+ * @param value <code>false</code> if output should be logged, otherwise
+ * <code>true</code>. The default is <code>false</code>.
+ *
+ * @since Ant 1.6.3
+ */
+ public void setQuiet(boolean value) {
+ quiet = value;
+ }
+
+ /**
+ * Checks whether <code>rpmbuild</code> is on the PATH and returns
+ * the absolute path to it - falls back to <code>rpm</code>
+ * otherwise.
+ *
+ * @return the command used to build RPM's
+ *
+ * @since 1.6
+ */
+ protected String guessRpmBuildCommand() {
+ Map/*<String, String>*/ env = Execute.getEnvironmentVariables();
+ String path = (String) env.get(PATH1);
+ if (path == null) {
+ path = (String) env.get(PATH2);
+ if (path == null) {
+ path = (String) env.get(PATH3);
+ }
+ }
+
+ if (path != null) {
+ Path p = new Path(getProject(), path);
+ String[] pElements = p.list();
+ for (int i = 0; i < pElements.length; i++) {
+ File f = new File(pElements[i],
+ "rpmbuild"
+ + (Os.isFamily("dos") ? ".exe" : ""));
+ if (f.canRead()) {
+ return f.getAbsolutePath();
+ }
+ }
+ }
+
+ return "rpm";
+ }
+
+ /**
+ * Get the execute object.
+ * @param toExecute the command line to use.
+ * @param streamhandler the stream handler to use.
+ * @return the execute object.
+ * @since Ant 1.6.3
+ */
+ protected Execute getExecute(Commandline toExecute,
+ ExecuteStreamHandler streamhandler) {
+ Execute exe = new Execute(streamhandler, null);
+
+ exe.setAntRun(getProject());
+ if (topDir == null) {
+ topDir = getProject().getBaseDir();
+ }
+ exe.setWorkingDirectory(topDir);
+
+ exe.setCommandline(toExecute.getCommandline());
+ return exe;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/SchemaValidate.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/SchemaValidate.java
new file mode 100644
index 00000000..e57d6d22
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/SchemaValidate.java
@@ -0,0 +1,529 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional;
+
+import java.io.File;
+import java.net.MalformedURLException;
+import java.util.HashMap;
+import java.util.Iterator;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.util.FileUtils;
+import org.apache.tools.ant.util.XmlConstants;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXNotRecognizedException;
+import org.xml.sax.SAXNotSupportedException;
+import org.xml.sax.XMLReader;
+
+/**
+ * Validate XML Schema documents.
+ * This task validates XML schema documents. It requires an XML parser
+ * that handles the relevant SAX, Xerces or JAXP options.
+ *
+ * To resolve remote referencies, Ant may need its proxy set up, using the
+ * setproxy task.
+ *
+ * Hands off most of the work to its parent, {@link XMLValidateTask}
+ * @since Ant1.7
+ */
+
+public class SchemaValidate extends XMLValidateTask {
+
+ /** map of all declared schemas; we catch and complain about redefinitions */
+ private HashMap schemaLocations = new HashMap();
+
+ /** full checking of a schema */
+ private boolean fullChecking = true;
+
+ /**
+ * flag to disable DTD support. Best left enabled.
+ */
+ private boolean disableDTD = false;
+
+ /**
+ * default URL for nonamespace schemas
+ */
+ private SchemaLocation anonymousSchema;
+
+ // Error strings
+ /** SAX1 not supported */
+ public static final String ERROR_SAX_1 = "SAX1 parsers are not supported";
+
+ /** schema features not supported */
+ public static final String ERROR_NO_XSD_SUPPORT
+ = "Parser does not support Xerces or JAXP schema features";
+
+ /** too many default schemas */
+ public static final String ERROR_TOO_MANY_DEFAULT_SCHEMAS
+ = "Only one of defaultSchemaFile and defaultSchemaURL allowed";
+
+ /** unable to create parser */
+ public static final String ERROR_PARSER_CREATION_FAILURE
+ = "Could not create parser";
+
+ /** adding schema */
+ public static final String MESSAGE_ADDING_SCHEMA = "Adding schema ";
+
+ /** Duplicate declaration of schema */
+ public static final String ERROR_DUPLICATE_SCHEMA
+ = "Duplicate declaration of schema ";
+
+ /**
+ * Called by the project to let the task initialize properly. The default
+ * implementation is a no-op.
+ *
+ * @throws BuildException if something goes wrong with the build
+ */
+ public void init() throws BuildException {
+ super.init();
+ //validating
+ setLenient(false);
+ }
+
+ /**
+ * Turn on XSD support in Xerces.
+ * @return true on success, false on failure
+ */
+ public boolean enableXercesSchemaValidation() {
+ try {
+ setFeature(XmlConstants.FEATURE_XSD, true);
+ //set the schema source for the doc
+ setNoNamespaceSchemaProperty(XmlConstants.PROPERTY_NO_NAMESPACE_SCHEMA_LOCATION);
+ } catch (BuildException e) {
+ log(e.toString(), Project.MSG_VERBOSE);
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * set nonamespace handling up for xerces or other parsers
+ * @param property name of the property to set
+ */
+ private void setNoNamespaceSchemaProperty(String property) {
+ String anonSchema = getNoNamespaceSchemaURL();
+ if (anonSchema != null) {
+ setProperty(property, anonSchema);
+ }
+ }
+
+ /**
+ * Set schema attributes in a JAXP 1.2 engine.
+ * @see <A href="http://java.sun.com/xml/jaxp/change-requests-11.html">
+ * JAXP 1.2 Approved CHANGES</A>
+ * @return true on success, false on failure
+ */
+ public boolean enableJAXP12SchemaValidation() {
+ try {
+ //enable XSD
+ setProperty(XmlConstants.FEATURE_JAXP12_SCHEMA_LANGUAGE, XmlConstants.URI_XSD);
+ //set the schema source for the doc
+ setNoNamespaceSchemaProperty(XmlConstants.FEATURE_JAXP12_SCHEMA_SOURCE);
+ } catch (BuildException e) {
+ log(e.toString(), Project.MSG_VERBOSE);
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * add the schema
+ * @param location the schema location.
+ * @throws BuildException if there is no namespace, or if there already
+ * is a declaration of this schema with a different value
+ */
+ public void addConfiguredSchema(SchemaLocation location) {
+ log("adding schema " + location, Project.MSG_DEBUG);
+ location.validateNamespace();
+ SchemaLocation old = (SchemaLocation) schemaLocations.get(location.getNamespace());
+ if (old != null && !old.equals(location)) {
+ throw new BuildException(ERROR_DUPLICATE_SCHEMA + location);
+ }
+ schemaLocations.put(location.getNamespace(), location);
+ }
+
+ /**
+ * enable full schema checking. Slower but better.
+ * @param fullChecking a <code>boolean</code> value.
+ */
+ public void setFullChecking(boolean fullChecking) {
+ this.fullChecking = fullChecking;
+ }
+
+ /**
+ * create a schema location to hold the anonymous
+ * schema
+ */
+ protected void createAnonymousSchema() {
+ if (anonymousSchema == null) {
+ anonymousSchema = new SchemaLocation();
+ }
+ anonymousSchema.setNamespace("(no namespace)");
+ }
+
+ /**
+ * identify the URL of the default schema
+ * @param defaultSchemaURL the URL of the default schema.
+ */
+ public void setNoNamespaceURL(String defaultSchemaURL) {
+ createAnonymousSchema();
+ this.anonymousSchema.setUrl(defaultSchemaURL);
+ }
+
+ /**
+ * identify a file containing the default schema
+ * @param defaultSchemaFile the location of the default schema.
+ */
+ public void setNoNamespaceFile(File defaultSchemaFile) {
+ createAnonymousSchema();
+ this.anonymousSchema.setFile(defaultSchemaFile);
+ }
+
+ /**
+ * flag to disable DTD support.
+ * @param disableDTD a <code>boolean</code> value.
+ */
+ public void setDisableDTD(boolean disableDTD) {
+ this.disableDTD = disableDTD;
+ }
+
+ /**
+ * init the parser : load the parser class, and set features if necessary It
+ * is only after this that the reader is valid
+ *
+ * @throws BuildException if something went wrong
+ */
+ protected void initValidator() {
+ super.initValidator();
+ //validate the parser type
+ if (isSax1Parser()) {
+ throw new BuildException(ERROR_SAX_1);
+ }
+
+ //enable schema
+ //setFeature(XmlConstants.FEATURE_VALIDATION, false);
+ setFeature(XmlConstants.FEATURE_NAMESPACES, true);
+ if (!enableXercesSchemaValidation() && !enableJAXP12SchemaValidation()) {
+ //couldnt use the xerces or jaxp calls
+ throw new BuildException(ERROR_NO_XSD_SUPPORT);
+ }
+
+ //enable schema checking
+ setFeature(XmlConstants.FEATURE_XSD_FULL_VALIDATION, fullChecking);
+
+ //turn off DTDs if desired
+ setFeatureIfSupported(XmlConstants.FEATURE_DISALLOW_DTD, disableDTD);
+
+ //schema declarations go in next
+ addSchemaLocations();
+ }
+
+ /**
+ * Create a reader if the use of the class did not specify another one.
+ * The reason to not use {@link org.apache.tools.ant.util.JAXPUtils#getXMLReader()} was to
+ * create our own factory with our own options.
+ * @return a default XML parser
+ */
+ protected XMLReader createDefaultReader() {
+ SAXParserFactory factory = SAXParserFactory.newInstance();
+ factory.setValidating(true);
+ factory.setNamespaceAware(true);
+ XMLReader reader = null;
+ try {
+ SAXParser saxParser = factory.newSAXParser();
+ reader = saxParser.getXMLReader();
+ } catch (ParserConfigurationException e) {
+ throw new BuildException(ERROR_PARSER_CREATION_FAILURE, e);
+ } catch (SAXException e) {
+ throw new BuildException(ERROR_PARSER_CREATION_FAILURE, e);
+ }
+ return reader;
+ }
+
+ /**
+ * build a string list of all schema locations, then set the relevant
+ * property.
+ */
+ protected void addSchemaLocations() {
+ Iterator it = schemaLocations.values().iterator();
+ StringBuffer buffer = new StringBuffer();
+ int count = 0;
+ while (it.hasNext()) {
+ if (count > 0) {
+ buffer.append(' ');
+ }
+ SchemaLocation schemaLocation = (SchemaLocation) it.next();
+ String tuple = schemaLocation.getURIandLocation();
+ buffer.append(tuple);
+ log("Adding schema " + tuple, Project.MSG_VERBOSE);
+ count++;
+ }
+ if (count > 0) {
+ setProperty(XmlConstants.PROPERTY_SCHEMA_LOCATION, buffer.toString());
+ }
+
+ }
+
+ /**
+ * get the URL of the no namespace schema
+ * @return the schema URL
+ */
+ protected String getNoNamespaceSchemaURL() {
+ if (anonymousSchema == null) {
+ return null;
+ } else {
+ return anonymousSchema.getSchemaLocationURL();
+ }
+ }
+
+ /**
+ * set a feature if it is supported, log at verbose level if
+ * not
+ * @param feature the feature.
+ * @param value a <code>boolean</code> value.
+ */
+ protected void setFeatureIfSupported(String feature, boolean value) {
+ try {
+ getXmlReader().setFeature(feature, value);
+ } catch (SAXNotRecognizedException e) {
+ log("Not recognizied: " + feature, Project.MSG_VERBOSE);
+ } catch (SAXNotSupportedException e) {
+ log("Not supported: " + feature, Project.MSG_VERBOSE);
+ }
+ }
+
+ /**
+ * handler called on successful file validation.
+ *
+ * @param fileProcessed number of files processed.
+ */
+ protected void onSuccessfulValidation(int fileProcessed) {
+ log(fileProcessed + MESSAGE_FILES_VALIDATED, Project.MSG_VERBOSE);
+ }
+
+ /**
+ * representation of a schema location. This is a URI plus either a file or
+ * a url
+ */
+ public static class SchemaLocation {
+ private String namespace;
+
+ private File file;
+
+ private String url;
+
+ /** No namespace URI */
+ public static final String ERROR_NO_URI = "No namespace URI";
+
+ /** Both URL and File were given for schema */
+ public static final String ERROR_TWO_LOCATIONS
+ = "Both URL and File were given for schema ";
+
+ /** File not found */
+ public static final String ERROR_NO_FILE = "File not found: ";
+
+ /** Cannot make URL */
+ public static final String ERROR_NO_URL_REPRESENTATION
+ = "Cannot make a URL of ";
+
+ /** No location provided */
+ public static final String ERROR_NO_LOCATION
+ = "No file or URL supplied for the schema ";
+
+ /** No arg constructor */
+ public SchemaLocation() {
+ }
+
+ /**
+ * Get the namespace.
+ * @return the namespace.
+ */
+ public String getNamespace() {
+ return namespace;
+ }
+
+ /**
+ * set the namespace of this schema. Any URI
+ * @param namespace the namespace to use.
+ */
+ public void setNamespace(String namespace) {
+ this.namespace = namespace;
+ }
+
+ /**
+ * Get the file.
+ * @return the file containing the schema.
+ */
+ public File getFile() {
+ return file;
+ }
+
+ /**
+ * identify a file that contains this namespace's schema.
+ * The file must exist.
+ * @param file the file contains the schema.
+ */
+ public void setFile(File file) {
+ this.file = file;
+ }
+
+ /**
+ * The URL containing the schema.
+ * @return the URL string.
+ */
+ public String getUrl() {
+ return url;
+ }
+
+ /**
+ * identify a URL that hosts the schema.
+ * @param url the URL string.
+ */
+ public void setUrl(String url) {
+ this.url = url;
+ }
+
+ /**
+ * get the URL of the schema
+ * @return a URL to the schema
+ * @throws BuildException if not
+ */
+ public String getSchemaLocationURL() {
+ boolean hasFile = file != null;
+ boolean hasURL = isSet(url);
+ //error if both are empty, or both are set
+ if (!hasFile && !hasURL) {
+ throw new BuildException(ERROR_NO_LOCATION + namespace);
+ }
+ if (hasFile && hasURL) {
+ throw new BuildException(ERROR_TWO_LOCATIONS + namespace);
+ }
+ String schema = url;
+ if (hasFile) {
+ if (!file.exists()) {
+ throw new BuildException(ERROR_NO_FILE + file);
+ }
+
+ try {
+ schema = FileUtils.getFileUtils().getFileURL(file).toString();
+ } catch (MalformedURLException e) {
+ //this is almost implausible, but required handling
+ throw new BuildException(ERROR_NO_URL_REPRESENTATION + file, e);
+ }
+ }
+ return schema;
+ }
+
+ /**
+ * validate the fields then create a "uri location" string
+ *
+ * @return string of uri and location
+ * @throws BuildException if there is an error.
+ */
+ public String getURIandLocation() throws BuildException {
+ validateNamespace();
+ StringBuffer buffer = new StringBuffer();
+ buffer.append(namespace);
+ buffer.append(' ');
+ buffer.append(getSchemaLocationURL());
+ return new String(buffer);
+ }
+
+ /**
+ * assert that a namespace is valid
+ * @throws BuildException if not
+ */
+ public void validateNamespace() {
+ if (!isSet(getNamespace())) {
+ throw new BuildException(ERROR_NO_URI);
+ }
+ }
+
+ /**
+ * check that a property is set
+ * @param property string to check
+ * @return true if it is not null or empty
+ */
+ private boolean isSet(String property) {
+ return property != null && property.length() != 0;
+ }
+
+ /**
+ * equality test checks namespace, location and filename. All must match,
+ * @param o object to compare against
+ * @return true iff the objects are considered equal in value
+ */
+
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof SchemaLocation)) {
+ return false;
+ }
+
+ final SchemaLocation schemaLocation = (SchemaLocation) o;
+
+ if (file != null ? !file.equals(schemaLocation.file) : schemaLocation.file != null) {
+ return false;
+ }
+ if (namespace != null ? !namespace.equals(schemaLocation.namespace)
+ : schemaLocation.namespace != null) {
+ return false;
+ }
+ if (url != null ? !url.equals(schemaLocation.url) : schemaLocation.url != null) {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Generate a hashcode depending on the namespace, url and file name.
+ * @return the hashcode.
+ */
+ public int hashCode() {
+ int result;
+ // CheckStyle:MagicNumber OFF
+ result = (namespace != null ? namespace.hashCode() : 0);
+ result = 29 * result + (file != null ? file.hashCode() : 0);
+ result = 29 * result + (url != null ? url.hashCode() : 0);
+ // CheckStyle:MagicNumber OFF
+ return result;
+ }
+
+ /**
+ * Returns a string representation of the object for error messages
+ * and the like
+ * @return a string representation of the object.
+ */
+ public String toString() {
+ StringBuffer buffer = new StringBuffer();
+ buffer.append(namespace != null ? namespace : "(anonymous)");
+ buffer.append(' ');
+ buffer.append(url != null ? (url + " ") : "");
+ buffer.append(file != null ? file.getAbsolutePath() : "");
+ return buffer.toString();
+ }
+ } //SchemaLocation
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/Script.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/Script.java
new file mode 100644
index 00000000..2b8d9f65
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/Script.java
@@ -0,0 +1,133 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional;
+
+import java.io.File;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.types.Reference;
+import org.apache.tools.ant.util.ScriptRunnerHelper;
+
+/**
+ * Executes a script.
+ *
+ * @ant.task name="script"
+ */
+public class Script extends Task {
+
+ private ScriptRunnerHelper helper = new ScriptRunnerHelper();
+
+ /**
+ * Set the project.
+ * @param project the project that this task belongs to.
+ */
+ public void setProject(Project project) {
+ super.setProject(project);
+ helper.setProjectComponent(this);
+ }
+
+ /**
+ * Run the script using the helper object.
+ *
+ * @exception BuildException if something goes wrong with the build
+ */
+ public void execute() throws BuildException {
+ helper.getScriptRunner().executeScript("ANT");
+ }
+
+ /**
+ * Defines the manager.
+ *
+ * @param manager the scripting manager.
+ */
+ public void setManager(String manager) {
+ helper.setManager(manager);
+ }
+
+ /**
+ * Defines the language (required).
+ *
+ * @param language the scripting language name for the script.
+ */
+ public void setLanguage(String language) {
+ helper.setLanguage(language);
+ }
+
+ /**
+ * Load the script from an external file ; optional.
+ *
+ * @param fileName the name of the file containing the script source.
+ */
+ public void setSrc(String fileName) {
+ helper.setSrc(new File(fileName));
+ }
+
+ /**
+ * Set the script text.
+ *
+ * @param text a component of the script text to be added.
+ */
+ public void addText(String text) {
+ helper.addText(text);
+ }
+
+ /**
+ * Set the classpath to be used when searching for classes and resources.
+ *
+ * @param classpath an Ant Path object containing the search path.
+ */
+ public void setClasspath(Path classpath) {
+ helper.setClasspath(classpath);
+ }
+
+ /**
+ * Classpath to be used when searching for classes and resources.
+ *
+ * @return an empty Path instance to be configured by Ant.
+ */
+ public Path createClasspath() {
+ return helper.createClasspath();
+ }
+
+ /**
+ * Set the classpath by reference.
+ *
+ * @param r a Reference to a Path instance to be used as the classpath
+ * value.
+ */
+ public void setClasspathRef(Reference r) {
+ helper.setClasspathRef(r);
+ }
+
+ /**
+ * Set the setbeans attribute.
+ * If this is true, &lt;script&gt; will create variables in the
+ * script instance for all
+ * properties, targets and references of the current project.
+ * It this is false, only the project and self variables will
+ * be set.
+ * The default is true.
+ * @param setBeans the value to set.
+ */
+ public void setSetBeans(boolean setBeans) {
+ helper.setSetBeans(setBeans);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/TraXLiaison.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/TraXLiaison.java
new file mode 100644
index 00000000..8d9a44a6
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/TraXLiaison.java
@@ -0,0 +1,650 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.lang.reflect.Field;
+import java.net.URL;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Vector;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParserFactory;
+import javax.xml.transform.ErrorListener;
+import javax.xml.transform.Source;
+import javax.xml.transform.SourceLocator;
+import javax.xml.transform.Templates;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.URIResolver;
+import javax.xml.transform.sax.SAXSource;
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.stream.StreamSource;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.XSLTLiaison4;
+import org.apache.tools.ant.taskdefs.XSLTLogger;
+import org.apache.tools.ant.taskdefs.XSLTLoggerAware;
+import org.apache.tools.ant.taskdefs.XSLTProcess;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.XMLCatalog;
+import org.apache.tools.ant.types.resources.FileProvider;
+import org.apache.tools.ant.types.resources.FileResource;
+import org.apache.tools.ant.types.resources.URLProvider;
+import org.apache.tools.ant.util.FileUtils;
+import org.apache.tools.ant.util.JAXPUtils;
+import org.xml.sax.EntityResolver;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.XMLReader;
+
+/**
+ * Concrete liaison for XSLT processor implementing TraX. (ie JAXP 1.1)
+ *
+ * @since Ant 1.3
+ */
+public class TraXLiaison implements XSLTLiaison4, ErrorListener, XSLTLoggerAware {
+
+ /**
+ * Helper for transforming filenames to URIs.
+ *
+ * @since Ant 1.7
+ */
+ private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+
+ /**
+ * The current <code>Project</code>
+ */
+ private Project project;
+
+ /**
+ * the name of the factory implementation class to use
+ * or null for default JAXP lookup.
+ */
+ private String factoryName = null;
+
+ /** The trax TransformerFactory */
+ private TransformerFactory tfactory = null;
+
+ /** stylesheet to use for transformation */
+ private Resource stylesheet;
+
+ private XSLTLogger logger;
+
+ /** possible resolver for publicIds */
+ private EntityResolver entityResolver;
+
+ /** transformer to use for processing files */
+ private Transformer transformer;
+
+ /** The In memory version of the stylesheet */
+ private Templates templates;
+
+ /**
+ * The modification time of the stylesheet from which the templates
+ * are read
+ */
+ private long templatesModTime;
+
+ /** possible resolver for URIs */
+ private URIResolver uriResolver;
+
+ /** transformer output properties */
+ private final Vector outputProperties = new Vector();
+
+ /** stylesheet parameters */
+ private final Hashtable<String, Object> params = new Hashtable<String, Object>();
+
+ /** factory attributes */
+ private final Vector attributes = new Vector();
+
+ /** whether to suppress warnings */
+ private boolean suppressWarnings = false;
+
+ /** optional trace configuration. */
+ private XSLTProcess.TraceConfiguration traceConfiguration = null;
+
+ /**
+ * Constructor for TraXLiaison.
+ * @throws Exception never
+ */
+ public TraXLiaison() throws Exception {
+ }
+
+ /**
+ * Set the stylesheet file.
+ * @param stylesheet a <code>File</code> value
+ * @throws Exception on error
+ */
+ public void setStylesheet(final File stylesheet) throws Exception {
+ final FileResource fr = new FileResource();
+ fr.setProject(project);
+ fr.setFile(stylesheet);
+ setStylesheet(fr);
+ }
+
+ /**
+ * Set the stylesheet file.
+ * @param stylesheet a {@link org.apache.tools.ant.types.Resource} value
+ * @throws Exception on error
+ */
+ public void setStylesheet(final Resource stylesheet) throws Exception {
+ if (this.stylesheet != null) {
+ // resetting the stylesheet - reset transformer
+ transformer = null;
+
+ // do we need to reset templates as well
+ if (!this.stylesheet.equals(stylesheet)
+ || (stylesheet.getLastModified() != templatesModTime)) {
+ templates = null;
+ }
+ }
+ this.stylesheet = stylesheet;
+ }
+
+ /**
+ * Transform an input file.
+ * @param infile the file to transform
+ * @param outfile the result file
+ * @throws Exception on error
+ */
+ public void transform(final File infile, final File outfile) throws Exception {
+ if (transformer == null) {
+ createTransformer();
+ }
+
+ InputStream fis = null;
+ OutputStream fos = null;
+ try {
+ fis = new BufferedInputStream(new FileInputStream(infile));
+ fos = new BufferedOutputStream(new FileOutputStream(outfile));
+ final StreamResult res = new StreamResult(fos);
+ // not sure what could be the need of this...
+ res.setSystemId(JAXPUtils.getSystemId(outfile));
+ final Source src = getSource(fis, infile);
+
+ // set parameters on each transformation, maybe something has changed
+ //(e.g. value of file name parameter)
+ setTransformationParameters();
+
+ transformer.transform(src, res);
+ } finally {
+ // make sure to close all handles, otherwise the garbage
+ // collector will close them...whenever possible and
+ // Windows may complain about not being able to delete files.
+ FileUtils.close(fis);
+ FileUtils.close(fos);
+ }
+ }
+
+ /**
+ * Get the source instance from the stream and id of the file.
+ * @param is the stream containing the stylesheet data.
+ * @param infile the file that will be used for the systemid.
+ * @return the configured source instance matching the stylesheet.
+ * @throws ParserConfigurationException if a parser cannot be created which
+ * satisfies the requested configuration.
+ * @throws SAXException in case of problem detected by the SAX parser.
+ */
+ private Source getSource(final InputStream is, final File infile)
+ throws ParserConfigurationException, SAXException {
+ // todo: is this comment still relevant ??
+ // FIXME: need to use a SAXSource as the source for the transform
+ // so we can plug in our own entity resolver
+ Source src = null;
+ if (entityResolver != null) {
+ if (getFactory().getFeature(SAXSource.FEATURE)) {
+ final SAXParserFactory spFactory = SAXParserFactory.newInstance();
+ spFactory.setNamespaceAware(true);
+ final XMLReader reader = spFactory.newSAXParser().getXMLReader();
+ reader.setEntityResolver(entityResolver);
+ src = new SAXSource(reader, new InputSource(is));
+ } else {
+ throw new IllegalStateException("xcatalog specified, but "
+ + "parser doesn't support SAX");
+ }
+ } else {
+ // WARN: Don't use the StreamSource(File) ctor. It won't work with
+ // xalan prior to 2.2 because of systemid bugs.
+ src = new StreamSource(is);
+ }
+ src.setSystemId(JAXPUtils.getSystemId(infile));
+ return src;
+ }
+
+ private Source getSource(final InputStream is, final Resource resource)
+ throws ParserConfigurationException, SAXException {
+ // todo: is this comment still relevant ??
+ // FIXME: need to use a SAXSource as the source for the transform
+ // so we can plug in our own entity resolver
+ Source src = null;
+ if (entityResolver != null) {
+ if (getFactory().getFeature(SAXSource.FEATURE)) {
+ final SAXParserFactory spFactory = SAXParserFactory.newInstance();
+ spFactory.setNamespaceAware(true);
+ final XMLReader reader = spFactory.newSAXParser().getXMLReader();
+ reader.setEntityResolver(entityResolver);
+ src = new SAXSource(reader, new InputSource(is));
+ } else {
+ throw new IllegalStateException("xcatalog specified, but "
+ + "parser doesn't support SAX");
+ }
+ } else {
+ // WARN: Don't use the StreamSource(File) ctor. It won't work with
+ // xalan prior to 2.2 because of systemid bugs.
+ src = new StreamSource(is);
+ }
+ // The line below is a hack: the system id must an URI, but it is not
+ // cleat to get the URI of an resource, so just set the name of the
+ // resource as a system id
+ src.setSystemId(resourceToURI(resource));
+ return src;
+ }
+
+ private String resourceToURI(final Resource resource) {
+ final FileProvider fp = resource.as(FileProvider.class);
+ if (fp != null) {
+ return FILE_UTILS.toURI(fp.getFile().getAbsolutePath());
+ }
+ final URLProvider up = resource.as(URLProvider.class);
+ if (up != null) {
+ final URL u = up.getURL();
+ return String.valueOf(u);
+ } else {
+ return resource.getName();
+ }
+ }
+
+ /**
+ * Read in templates from the stylesheet
+ */
+ private void readTemplates()
+ throws IOException, TransformerConfigurationException,
+ ParserConfigurationException, SAXException {
+
+ // Use a stream so that you can close it yourself quickly
+ // and avoid keeping the handle until the object is garbaged.
+ // (always keep control), otherwise you won't be able to delete
+ // the file quickly on windows.
+ InputStream xslStream = null;
+ try {
+ xslStream
+ = new BufferedInputStream(stylesheet.getInputStream());
+ templatesModTime = stylesheet.getLastModified();
+ final Source src = getSource(xslStream, stylesheet);
+ templates = getFactory().newTemplates(src);
+ } finally {
+ if (xslStream != null) {
+ xslStream.close();
+ }
+ }
+ }
+
+ /**
+ * Create a new transformer based on the liaison settings
+ * @throws Exception thrown if there is an error during creation.
+ * @see #setStylesheet(java.io.File)
+ * @see #addParam(java.lang.String, java.lang.String)
+ * @see #setOutputProperty(java.lang.String, java.lang.String)
+ */
+ private void createTransformer() throws Exception {
+ if (templates == null) {
+ readTemplates();
+ }
+
+ transformer = templates.newTransformer();
+
+ // configure the transformer...
+ transformer.setErrorListener(this);
+ if (uriResolver != null) {
+ transformer.setURIResolver(uriResolver);
+ }
+ final int size = outputProperties.size();
+ for (int i = 0; i < size; i++) {
+ final String[] pair = (String[]) outputProperties.elementAt(i);
+ transformer.setOutputProperty(pair[0], pair[1]);
+ }
+
+ if (traceConfiguration != null) {
+ if ("org.apache.xalan.transformer.TransformerImpl"
+ .equals(transformer.getClass().getName())) {
+ try {
+ final Class traceSupport =
+ Class.forName("org.apache.tools.ant.taskdefs.optional."
+ + "Xalan2TraceSupport", true,
+ Thread.currentThread()
+ .getContextClassLoader());
+ final XSLTTraceSupport ts =
+ (XSLTTraceSupport) traceSupport.newInstance();
+ ts.configureTrace(transformer, traceConfiguration);
+ } catch (final Exception e) {
+ final String msg = "Failed to enable tracing because of " + e;
+ if (project != null) {
+ project.log(msg, Project.MSG_WARN);
+ } else {
+ System.err.println(msg);
+ }
+ }
+ } else {
+ final String msg = "Not enabling trace support for transformer"
+ + " implementation" + transformer.getClass().getName();
+ if (project != null) {
+ project.log(msg, Project.MSG_WARN);
+ } else {
+ System.err.println(msg);
+ }
+ }
+ }
+ }
+
+ /**
+ * Sets the parameters for the transformer.
+ */
+ private void setTransformationParameters() {
+ for (final Enumeration enumeration = params.keys();
+ enumeration.hasMoreElements();) {
+ final String name = (String) enumeration.nextElement();
+ final Object value = params.get(name);
+ transformer.setParameter(name, value);
+ }
+ }
+
+ /**
+ * return the Transformer factory associated to this liaison.
+ * @return the Transformer factory associated to this liaison.
+ * @throws BuildException thrown if there is a problem creating
+ * the factory.
+ * @see #setFactory(String)
+ * @since Ant 1.5.2
+ */
+ private TransformerFactory getFactory() throws BuildException {
+ if (tfactory != null) {
+ return tfactory;
+ }
+ // not initialized yet, so create the factory
+ if (factoryName == null) {
+ tfactory = TransformerFactory.newInstance();
+ } else {
+ try {
+ Class clazz = null;
+ try {
+ clazz =
+ Class.forName(factoryName, true,
+ Thread.currentThread()
+ .getContextClassLoader());
+ } catch (final ClassNotFoundException cnfe) {
+ final String msg = "Failed to load " + factoryName
+ + " via the configured classpath, will try"
+ + " Ant's classpath instead.";
+ if (logger != null) {
+ logger.log(msg);
+ } else if (project != null) {
+ project.log(msg, Project.MSG_WARN);
+ } else {
+ System.err.println(msg);
+ }
+ }
+
+ if (clazz == null) {
+ clazz = Class.forName(factoryName);
+ }
+ tfactory = (TransformerFactory) clazz.newInstance();
+ } catch (final Exception e) {
+ throw new BuildException(e);
+ }
+ }
+
+ try { // #51668, #52382
+ final Field _isNotSecureProcessing = tfactory.getClass().getDeclaredField("_isNotSecureProcessing");
+ _isNotSecureProcessing.setAccessible(true);
+ _isNotSecureProcessing.set(tfactory, Boolean.TRUE);
+ } catch (final Exception x) {
+ if (project != null) {
+ project.log(x.toString(), Project.MSG_DEBUG);
+ }
+ }
+
+ tfactory.setErrorListener(this);
+
+ // specific attributes for the transformer
+ final int size = attributes.size();
+ for (int i = 0; i < size; i++) {
+ final Object[] pair = (Object[]) attributes.elementAt(i);
+ tfactory.setAttribute((String) pair[0], pair[1]);
+ }
+
+ if (uriResolver != null) {
+ tfactory.setURIResolver(uriResolver);
+ }
+ return tfactory;
+ }
+
+
+ /**
+ * Set the factory name to use instead of JAXP default lookup.
+ * @param name the fully qualified class name of the factory to use
+ * or null for the default JAXP look up mechanism.
+ * @since Ant 1.6
+ */
+ public void setFactory(final String name) {
+ factoryName = name;
+ }
+
+ /**
+ * Set a custom attribute for the JAXP factory implementation.
+ * @param name the attribute name.
+ * @param value the value of the attribute, usually a boolean
+ * string or object.
+ * @since Ant 1.6
+ */
+ public void setAttribute(final String name, final Object value) {
+ final Object[] pair = new Object[]{name, value};
+ attributes.addElement(pair);
+ }
+
+ /**
+ * Set the output property for the current transformer.
+ * Note that the stylesheet must be set prior to calling
+ * this method.
+ * @param name the output property name.
+ * @param value the output property value.
+ * @since Ant 1.5
+ * @since Ant 1.5
+ */
+ public void setOutputProperty(final String name, final String value) {
+ final String[] pair = new String[]{name, value};
+ outputProperties.addElement(pair);
+ }
+
+ /**
+ * Set the class to resolve entities during the transformation.
+ * @param aResolver the resolver class.
+ */
+ public void setEntityResolver(final EntityResolver aResolver) {
+ entityResolver = aResolver;
+ }
+
+ /**
+ * Set the class to resolve URIs during the transformation
+ * @param aResolver a <code>EntityResolver</code> value
+ */
+ public void setURIResolver(final URIResolver aResolver) {
+ uriResolver = aResolver;
+ }
+
+ /**
+ * Add a parameter.
+ * @param name the name of the parameter
+ * @param value the value of the parameter
+ */
+ public void addParam(final String name, final String value) {
+ params.put(name, value);
+ }
+
+ /**
+ * Add a parameter.
+ * @param name the name of the parameter
+ * @param value the value of the parameter
+ * @since Ant 1.9.3
+ */
+ public void addParam(final String name, final Object value) {
+ params.put(name, value);
+ }
+
+ /**
+ * Set a logger.
+ * @param l a logger.
+ */
+ public void setLogger(final XSLTLogger l) {
+ logger = l;
+ }
+
+ /**
+ * Log an error.
+ * @param e the exception to log.
+ */
+ public void error(final TransformerException e) {
+ logError(e, "Error");
+ }
+
+ /**
+ * Log a fatal error.
+ * @param e the exception to log.
+ */
+ public void fatalError(final TransformerException e) {
+ logError(e, "Fatal Error");
+ throw new BuildException("Fatal error during transformation using " + stylesheet + ": " + e.getMessageAndLocation(), e);
+ }
+
+ /**
+ * Log a warning.
+ * @param e the exception to log.
+ */
+ public void warning(final TransformerException e) {
+ if (!suppressWarnings) {
+ logError(e, "Warning");
+ }
+ }
+
+ private void logError(final TransformerException e, final String type) {
+ if (logger == null) {
+ return;
+ }
+
+ final StringBuffer msg = new StringBuffer();
+ final SourceLocator locator = e.getLocator();
+ if (locator != null) {
+ final String systemid = locator.getSystemId();
+ if (systemid != null) {
+ String url = systemid;
+ if (url.startsWith("file:")) {
+ url = FileUtils.getFileUtils().fromURI(url);
+ }
+ msg.append(url);
+ } else {
+ msg.append("Unknown file");
+ }
+ final int line = locator.getLineNumber();
+ if (line != -1) {
+ msg.append(":");
+ msg.append(line);
+ final int column = locator.getColumnNumber();
+ if (column != -1) {
+ msg.append(":");
+ msg.append(column);
+ }
+ }
+ }
+ msg.append(": ");
+ msg.append(type);
+ msg.append("! ");
+ msg.append(e.getMessage());
+ if (e.getCause() != null) {
+ msg.append(" Cause: ");
+ msg.append(e.getCause());
+ }
+
+ logger.log(msg.toString());
+ }
+
+ // kept for backwards compatibility
+ /**
+ * @param file the filename to use for the systemid
+ * @return the systemid
+ * @deprecated since 1.5.x.
+ * Use org.apache.tools.ant.util.JAXPUtils#getSystemId instead.
+ */
+ @Deprecated
+ protected String getSystemId(final File file) {
+ return JAXPUtils.getSystemId(file);
+ }
+
+
+ /**
+ * Specific configuration for the TRaX liaison.
+ * @param xsltTask the XSLTProcess task instance from which this liaison
+ * is to be configured.
+ */
+ public void configure(final XSLTProcess xsltTask) {
+ project = xsltTask.getProject();
+ final XSLTProcess.Factory factory = xsltTask.getFactory();
+ if (factory != null) {
+ setFactory(factory.getName());
+
+ // configure factory attributes
+ for (final Enumeration attrs = factory.getAttributes();
+ attrs.hasMoreElements();) {
+ final XSLTProcess.Factory.Attribute attr =
+ (XSLTProcess.Factory.Attribute) attrs.nextElement();
+ setAttribute(attr.getName(), attr.getValue());
+ }
+ }
+
+ final XMLCatalog xmlCatalog = xsltTask.getXMLCatalog();
+ // use XMLCatalog as the entity resolver and URI resolver
+ if (xmlCatalog != null) {
+ setEntityResolver(xmlCatalog);
+ setURIResolver(xmlCatalog);
+ }
+
+
+ // configure output properties
+ for (final Enumeration props = xsltTask.getOutputProperties();
+ props.hasMoreElements();) {
+ final XSLTProcess.OutputProperty prop
+ = (XSLTProcess.OutputProperty) props.nextElement();
+ setOutputProperty(prop.getName(), prop.getValue());
+ }
+
+ suppressWarnings = xsltTask.getSuppressWarnings();
+
+ traceConfiguration = xsltTask.getTraceConfiguration();
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/XMLValidateTask.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/XMLValidateTask.java
new file mode 100644
index 00000000..05c043df
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/XMLValidateTask.java
@@ -0,0 +1,764 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.Vector;
+
+import org.apache.tools.ant.AntClassLoader;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.DirectoryScanner;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.types.DTDLocation;
+import org.apache.tools.ant.types.FileSet;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.types.Reference;
+import org.apache.tools.ant.types.XMLCatalog;
+import org.apache.tools.ant.util.FileUtils;
+import org.apache.tools.ant.util.JAXPUtils;
+import org.apache.tools.ant.util.XmlConstants;
+import org.xml.sax.EntityResolver;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.InputSource;
+import org.xml.sax.Parser;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXNotRecognizedException;
+import org.xml.sax.SAXNotSupportedException;
+import org.xml.sax.SAXParseException;
+import org.xml.sax.XMLReader;
+import org.xml.sax.helpers.ParserAdapter;
+
+/**
+ * Checks XML files are valid (or only well formed). The
+ * task uses the SAX2 parser implementation provided by JAXP by default
+ * (probably the one that is used by Ant itself), but one can specify any
+ * SAX1/2 parser if needed.
+ *
+ */
+public class XMLValidateTask extends Task {
+
+ /**
+ * helper for path -> URI and URI -> path conversions.
+ */
+ private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+
+ protected static final String INIT_FAILED_MSG =
+ "Could not start xml validation: ";
+
+ // ant task properties
+ // defaults
+ // CheckStyle:VisibilityModifier OFF - bc
+ protected boolean failOnError = true;
+ protected boolean warn = true;
+ protected boolean lenient = false;
+ protected String readerClassName = null;
+
+ /** file to be validated */
+ protected File file = null;
+ /** sets of file to be validated */
+ protected Vector filesets = new Vector();
+ protected Path classpath;
+
+ /**
+ * the parser is viewed as a SAX2 XMLReader. If a SAX1 parser is specified,
+ * it's wrapped in an adapter that make it behave as a XMLReader.
+ * a more 'standard' way of doing this would be to use the JAXP1.1 SAXParser
+ * interface.
+ */
+ protected XMLReader xmlReader = null;
+ // XMLReader used to validation process
+ protected ValidatorErrorHandler errorHandler = new ValidatorErrorHandler();
+ // to report sax parsing errors
+ // CheckStyle:VisibilityModifier ON
+
+ /** The vector to store all attributes (features) to be set on the parser. **/
+ private Vector attributeList = new Vector();
+
+ /**
+ * List of properties.
+ */
+ private final Vector propertyList = new Vector();
+
+ private XMLCatalog xmlCatalog = new XMLCatalog();
+ /** Message for successful validation */
+ public static final String MESSAGE_FILES_VALIDATED
+ = " file(s) have been successfully validated.";
+
+ private AntClassLoader readerLoader = null;
+
+ /**
+ * Specify how parser error are to be handled.
+ * Optional, default is <code>true</code>.
+ * <p>
+ * If set to <code>true</code> (default), throw a buildException if the
+ * parser yields an error.
+ * @param fail if set to <code>false</code> do not fail on error
+ */
+ public void setFailOnError(boolean fail) {
+ failOnError = fail;
+ }
+
+ /**
+ * Specify how parser error are to be handled.
+ * <p>
+ * If set to <code>true</code> (default), log a warn message for each SAX warn event.
+ * @param bool if set to <code>false</code> do not send warnings
+ */
+ public void setWarn(boolean bool) {
+ warn = bool;
+ }
+
+ /**
+ * Specify whether the parser should be validating. Default
+ * is <code>true</code>.
+ * <p>
+ * If set to false, the validation will fail only if the parsed document
+ * is not well formed XML.
+ * <p>
+ * this option is ignored if the specified class
+ * with {@link #setClassName(String)} is not a SAX2 XMLReader.
+ * @param bool if set to <code>false</code> only fail on malformed XML
+ */
+ public void setLenient(boolean bool) {
+ lenient = bool;
+ }
+
+ /**
+ * Specify the class name of the SAX parser to be used. (optional)
+ * @param className should be an implementation of SAX2
+ * <code>org.xml.sax.XMLReader</code> or SAX2 <code>org.xml.sax.Parser</code>.
+ * <p> if className is an implementation of
+ * <code>org.xml.sax.Parser</code>, {@link #setLenient(boolean)},
+ * will be ignored.
+ * <p> if not set, the default will be used.
+ * @see org.xml.sax.XMLReader
+ * @see org.xml.sax.Parser
+ */
+ public void setClassName(String className) {
+ readerClassName = className;
+ }
+
+ /**
+ * Specify the classpath to be searched to load the parser (optional)
+ * @param classpath the classpath to load the parser
+ */
+ public void setClasspath(Path classpath) {
+ if (this.classpath == null) {
+ this.classpath = classpath;
+ } else {
+ this.classpath.append(classpath);
+ }
+ }
+
+ /**
+ * @see #setClasspath
+ * @return the classpath created
+ */
+ public Path createClasspath() {
+ if (this.classpath == null) {
+ this.classpath = new Path(getProject());
+ }
+ return this.classpath.createPath();
+ }
+
+ /**
+ * Where to find the parser class; optional.
+ * @see #setClasspath
+ * @param r reference to a classpath defined elsewhere
+ */
+ public void setClasspathRef(Reference r) {
+ createClasspath().setRefid(r);
+ }
+
+ /**
+ * specify the file to be checked; optional.
+ * @param file the file to be checked
+ */
+ public void setFile(File file) {
+ this.file = file;
+ }
+
+ /**
+ * add an XMLCatalog as a nested element; optional.
+ * @param catalog XMLCatalog to use
+ */
+ public void addConfiguredXMLCatalog(XMLCatalog catalog) {
+ xmlCatalog.addConfiguredXMLCatalog(catalog);
+ }
+
+ /**
+ * specify a set of file to be checked
+ * @param set the fileset to check
+ */
+ public void addFileset(FileSet set) {
+ filesets.addElement(set);
+ }
+
+ /**
+ * Add an attribute nested element. This is used for setting arbitrary
+ * features of the SAX parser.
+ * Valid attributes
+ * <a href=
+ * "http://www.saxproject.org/apidoc/org/xml/sax/package-summary.html#package_description"
+ * >include</a>
+ * @return attribute created
+ * @since ant1.6
+ */
+ public Attribute createAttribute() {
+ final Attribute feature = new Attribute();
+ attributeList.addElement(feature);
+ return feature;
+ }
+
+ /**
+ * Creates a property.
+ *
+ * @return a property.
+ * @since ant 1.6.2
+ */
+ public Property createProperty() {
+ final Property prop = new Property();
+ propertyList.addElement(prop);
+ return prop;
+ }
+
+ /**
+ * Called by the project to let the task initialize properly.
+ *
+ * @exception BuildException if something goes wrong with the build
+ */
+ public void init() throws BuildException {
+ super.init();
+ xmlCatalog.setProject(getProject());
+ }
+
+ /**
+ * Create a DTD location record; optional.
+ * This stores the location of a DTD. The DTD is identified
+ * by its public Id.
+ * @return created DTD location
+ */
+ public DTDLocation createDTD() {
+ DTDLocation dtdLocation = new DTDLocation();
+ xmlCatalog.addDTD(dtdLocation);
+ return dtdLocation;
+ }
+ /**
+ * accessor to the xmlCatalog used in the task
+ * @return xmlCatalog reference
+ */
+ protected EntityResolver getEntityResolver() {
+ return xmlCatalog;
+ }
+
+ /**
+ * get the XML reader. Non-null only after {@link #initValidator()}.
+ * If the reader is an instance of {@link ParserAdapter} then
+ * the parser is a SAX1 parser, and you cannot call
+ * {@link #setFeature(String, boolean)} or {@link #setProperty(String, String)}
+ * on it.
+ * @return the XML reader or null.
+ */
+ protected XMLReader getXmlReader() {
+ return xmlReader;
+ }
+
+ /**
+ * execute the task
+ * @throws BuildException if <code>failonerror</code> is true and an error happens
+ */
+ public void execute() throws BuildException {
+ try {
+ int fileProcessed = 0;
+ if (file == null && (filesets.size() == 0)) {
+ throw new BuildException(
+ "Specify at least one source - " + "a file or a fileset.");
+ }
+
+
+
+ if (file != null) {
+ if (file.exists() && file.canRead() && file.isFile()) {
+ doValidate(file);
+ fileProcessed++;
+ } else {
+ String errorMsg = "File " + file + " cannot be read";
+ if (failOnError) {
+ throw new BuildException(errorMsg);
+ } else {
+ log(errorMsg, Project.MSG_ERR);
+ }
+ }
+ }
+
+ final int size = filesets.size();
+ for (int i = 0; i < size; i++) {
+
+ FileSet fs = (FileSet) filesets.elementAt(i);
+ DirectoryScanner ds = fs.getDirectoryScanner(getProject());
+ String[] files = ds.getIncludedFiles();
+
+ for (int j = 0; j < files.length; j++) {
+ File srcFile = new File(fs.getDir(getProject()), files[j]);
+ doValidate(srcFile);
+ fileProcessed++;
+ }
+ }
+ onSuccessfulValidation(fileProcessed);
+ } finally {
+ cleanup();
+ }
+ }
+
+ /**
+ * handler called on successful file validation.
+ * @param fileProcessed number of files processed.
+ */
+ protected void onSuccessfulValidation(int fileProcessed) {
+ log(fileProcessed + MESSAGE_FILES_VALIDATED);
+ }
+
+ /**
+ * init the parser :
+ * load the parser class, and set features if necessary
+ * It is only after this that the reader is valid
+ * @throws BuildException if something went wrong
+ */
+ protected void initValidator() {
+
+ xmlReader = createXmlReader();
+
+ xmlReader.setEntityResolver(getEntityResolver());
+ xmlReader.setErrorHandler(errorHandler);
+
+ if (!isSax1Parser()) {
+ // turn validation on
+ if (!lenient) {
+ setFeature(XmlConstants.FEATURE_VALIDATION, true);
+ }
+ // set the feature from the attribute list
+ final int attSize = attributeList.size();
+ for (int i = 0; i < attSize; i++) {
+ Attribute feature = (Attribute) attributeList.elementAt(i);
+ setFeature(feature.getName(), feature.getValue());
+
+ }
+ // Sets properties
+ final int propSize = propertyList.size();
+ for (int i = 0; i < propSize; i++) {
+ final Property prop = (Property) propertyList.elementAt(i);
+ setProperty(prop.getName(), prop.getValue());
+ }
+ }
+ }
+
+ /**
+ * test that returns true if we are using a SAX1 parser.
+ * @return true when a SAX1 parser is in use
+ */
+ protected boolean isSax1Parser() {
+ return (xmlReader instanceof ParserAdapter);
+ }
+
+ /**
+ * create the XML reader.
+ * This is one by instantiating anything specified by {@link #readerClassName},
+ * falling back to a default reader if not.
+ * If the returned reader is an instance of {@link ParserAdapter} then
+ * we have created and wrapped a SAX1 parser.
+ * @return the new XMLReader.
+ */
+ protected XMLReader createXmlReader() {
+ Object reader = null;
+ if (readerClassName == null) {
+ reader = createDefaultReaderOrParser();
+ } else {
+
+ Class readerClass = null;
+ try {
+ // load the parser class
+ if (classpath != null) {
+ readerLoader = getProject().createClassLoader(classpath);
+ readerClass = Class.forName(readerClassName, true,
+ readerLoader);
+ } else {
+ readerClass = Class.forName(readerClassName);
+ }
+
+ reader = readerClass.newInstance();
+ } catch (ClassNotFoundException e) {
+ throw new BuildException(INIT_FAILED_MSG + readerClassName, e);
+ } catch (InstantiationException e) {
+ throw new BuildException(INIT_FAILED_MSG + readerClassName, e);
+ } catch (IllegalAccessException e) {
+ throw new BuildException(INIT_FAILED_MSG + readerClassName, e);
+ }
+ }
+
+ // then check it implements XMLReader
+ XMLReader newReader;
+ if (reader instanceof XMLReader) {
+ newReader = (XMLReader) reader;
+ log(
+ "Using SAX2 reader " + reader.getClass().getName(),
+ Project.MSG_VERBOSE);
+ } else {
+
+ // see if it is a SAX1 Parser
+ if (reader instanceof Parser) {
+ newReader = new ParserAdapter((Parser) reader);
+ log(
+ "Using SAX1 parser " + reader.getClass().getName(),
+ Project.MSG_VERBOSE);
+ } else {
+ throw new BuildException(
+ INIT_FAILED_MSG
+ + reader.getClass().getName()
+ + " implements nor SAX1 Parser nor SAX2 XMLReader.");
+ }
+ }
+ return newReader;
+ }
+
+ /**
+ * Cleans up resources.
+ *
+ * @since Ant 1.8.0
+ */
+ protected void cleanup() {
+ if (readerLoader != null) {
+ readerLoader.cleanup();
+ readerLoader = null;
+ }
+ }
+
+ /**
+ * Returns a SAX-based XMLReader or a SAX-based Parser.
+ * @return reader or parser
+ */
+ private Object createDefaultReaderOrParser() {
+ Object reader;
+ try {
+ reader = createDefaultReader();
+ } catch (BuildException exc) {
+ reader = JAXPUtils.getParser();
+ }
+ return reader;
+ }
+
+ /**
+ * Create a reader if the use of the class did not specify another one.
+ * If a BuildException is thrown, the caller may revert to an alternate
+ * reader.
+ * @return a new reader.
+ * @throws BuildException if something went wrong
+ */
+ protected XMLReader createDefaultReader() {
+ return JAXPUtils.getXMLReader();
+ }
+
+ /**
+ * Set a feature on the parser.
+ * @param feature the name of the feature to set
+ * @param value the value of the feature
+ * @throws BuildException if the feature was not supported
+ */
+ protected void setFeature(String feature, boolean value)
+ throws BuildException {
+ log("Setting feature " + feature + "=" + value, Project.MSG_DEBUG);
+ try {
+ xmlReader.setFeature(feature, value);
+ } catch (SAXNotRecognizedException e) {
+ throw new BuildException(
+ "Parser "
+ + xmlReader.getClass().getName()
+ + " doesn't recognize feature "
+ + feature,
+ e,
+ getLocation());
+ } catch (SAXNotSupportedException e) {
+ throw new BuildException(
+ "Parser "
+ + xmlReader.getClass().getName()
+ + " doesn't support feature "
+ + feature,
+ e,
+ getLocation());
+ }
+ }
+
+ /**
+ * Sets a property.
+ *
+ * @param name a property name
+ * @param value a property value.
+ * @throws BuildException if an error occurs.
+ * @throws BuildException if the property was not supported
+ */
+ protected void setProperty(String name, String value) throws BuildException {
+ // Validates property
+ if (name == null || value == null) {
+ throw new BuildException("Property name and value must be specified.");
+ }
+
+ try {
+ xmlReader.setProperty(name, value);
+ } catch (SAXNotRecognizedException e) {
+ throw new BuildException(
+ "Parser "
+ + xmlReader.getClass().getName()
+ + " doesn't recognize property "
+ + name,
+ e,
+ getLocation());
+ } catch (SAXNotSupportedException e) {
+ throw new BuildException(
+ "Parser "
+ + xmlReader.getClass().getName()
+ + " doesn't support property "
+ + name,
+ e,
+ getLocation());
+ }
+ }
+
+ /**
+ * parse the file
+ * @param afile the file to validate.
+ * @return true if the file validates.
+ */
+ protected boolean doValidate(File afile) {
+ //for every file, we have a new instance of the validator
+ initValidator();
+ boolean result = true;
+ try {
+ log("Validating " + afile.getName() + "... ", Project.MSG_VERBOSE);
+ errorHandler.init(afile);
+ InputSource is = new InputSource(new FileInputStream(afile));
+ String uri = FILE_UTILS.toURI(afile.getAbsolutePath());
+ is.setSystemId(uri);
+ xmlReader.parse(is);
+ } catch (SAXException ex) {
+ log("Caught when validating: " + ex.toString(), Project.MSG_DEBUG);
+ if (failOnError) {
+ throw new BuildException(
+ "Could not validate document " + afile);
+ }
+ log("Could not validate document " + afile + ": " + ex.toString());
+ result = false;
+ } catch (IOException ex) {
+ throw new BuildException(
+ "Could not validate document " + afile,
+ ex);
+ }
+ if (errorHandler.getFailure()) {
+ if (failOnError) {
+ throw new BuildException(
+ afile + " is not a valid XML document.");
+ }
+ result = false;
+ log(afile + " is not a valid XML document", Project.MSG_ERR);
+ }
+ return result;
+ }
+
+ /**
+ * ValidatorErrorHandler role :
+ * <ul>
+ * <li> log SAX parse exceptions,
+ * <li> remember if an error occurred
+ * </ul>
+ */
+ protected class ValidatorErrorHandler implements ErrorHandler {
+
+ // CheckStyle:VisibilityModifier OFF - bc
+ protected File currentFile = null;
+ protected String lastErrorMessage = null;
+ protected boolean failed = false;
+ // CheckStyle:VisibilityModifier ON
+ /**
+ * initialises the class
+ * @param file file used
+ */
+ public void init(File file) {
+ currentFile = file;
+ failed = false;
+ }
+ /**
+ * did an error happen during last parsing ?
+ * @return did an error happen during last parsing ?
+ */
+ public boolean getFailure() {
+ return failed;
+ }
+
+ /**
+ * record a fatal error
+ * @param exception the fatal error
+ */
+ public void fatalError(SAXParseException exception) {
+ failed = true;
+ doLog(exception, Project.MSG_ERR);
+ }
+ /**
+ * receive notification of a recoverable error
+ * @param exception the error
+ */
+ public void error(SAXParseException exception) {
+ failed = true;
+ doLog(exception, Project.MSG_ERR);
+ }
+ /**
+ * receive notification of a warning
+ * @param exception the warning
+ */
+ public void warning(SAXParseException exception) {
+ // depending on implementation, XMLReader can yield hips of warning,
+ // only output then if user explicitly asked for it
+ if (warn) {
+ doLog(exception, Project.MSG_WARN);
+ }
+ }
+
+ private void doLog(SAXParseException e, int logLevel) {
+
+ log(getMessage(e), logLevel);
+ }
+
+ private String getMessage(SAXParseException e) {
+ String sysID = e.getSystemId();
+ if (sysID != null) {
+ String name = sysID;
+ if (sysID.startsWith("file:")) {
+ try {
+ name = FILE_UTILS.fromURI(sysID);
+ } catch (Exception ex) {
+ // if this is not a valid file: just use the uri
+ }
+ }
+ int line = e.getLineNumber();
+ int col = e.getColumnNumber();
+ return name
+ + (line == -1
+ ? ""
+ : (":" + line + (col == -1 ? "" : (":" + col))))
+ + ": "
+ + e.getMessage();
+ }
+ return e.getMessage();
+ }
+ }
+
+ /**
+ * The class to create to set a feature of the parser.
+ * @since ant1.6
+ */
+ public static class Attribute {
+ /** The name of the attribute to set.
+ *
+ * Valid attributes <a href=
+ * "http://www.saxproject.org/apidoc/org/xml/sax/package-summary.html#package_description"
+ * >include.</a>
+ */
+ private String attributeName = null;
+
+ /**
+ * The value of the feature.
+ **/
+ private boolean attributeValue;
+
+ /**
+ * Set the feature name.
+ * @param name the name to set
+ */
+ public void setName(String name) {
+ attributeName = name;
+ }
+ /**
+ * Set the feature value to true or false.
+ * @param value feature value
+ */
+ public void setValue(boolean value) {
+ attributeValue = value;
+ }
+
+ /**
+ * Gets the attribute name.
+ * @return the feature name
+ */
+ public String getName() {
+ return attributeName;
+ }
+
+ /**
+ * Gets the attribute value.
+ * @return the feature value
+ */
+ public boolean getValue() {
+ return attributeValue;
+ }
+ }
+
+ /**
+ * A Parser property.
+ * See <a href="http://xml.apache.org/xerces-j/properties.html">
+ * XML parser properties</a> for usable properties
+ * @since ant 1.6.2
+ */
+ public static final class Property {
+
+ private String name;
+ private String value;
+ /**
+ * accessor to the name of the property
+ * @return name of the property
+ */
+ public String getName() {
+ return name;
+ }
+ /**
+ * setter for the name of the property
+ * @param name name of the property
+ */
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ /**
+ * getter for the value of the property
+ * @return value of the property
+ */
+ public String getValue() {
+ return value;
+ }
+ /**
+ * sets the value of the property
+ * @param value value of the property
+ */
+ public void setValue(String value) {
+ this.value = value;
+ }
+
+ } // Property
+
+
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/XSLTTraceSupport.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/XSLTTraceSupport.java
new file mode 100644
index 00000000..8b684d83
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/XSLTTraceSupport.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional;
+
+import javax.xml.transform.Transformer;
+
+import org.apache.tools.ant.taskdefs.XSLTProcess;
+
+/**
+ * Sets up trace support for a given transformer.
+ *
+ * @since Ant 1.8.0
+ */
+public interface XSLTTraceSupport {
+ void configureTrace(Transformer t, XSLTProcess.TraceConfiguration conf);
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/Xalan2TraceSupport.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/Xalan2TraceSupport.java
new file mode 100644
index 00000000..e5da0185
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/Xalan2TraceSupport.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional;
+
+import java.io.PrintWriter;
+import java.util.TooManyListenersException;
+
+import javax.xml.transform.Transformer;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.taskdefs.XSLTProcess;
+import org.apache.xalan.trace.PrintTraceListener;
+import org.apache.xalan.transformer.TransformerImpl;
+
+/**
+ * Sets up trace support for a given transformer.
+ *
+ * @since Ant 1.8.0
+ */
+public class Xalan2TraceSupport implements XSLTTraceSupport {
+ public void configureTrace(final Transformer t,
+ final XSLTProcess.TraceConfiguration conf) {
+ if (t instanceof TransformerImpl && conf != null) {
+ final PrintWriter w = new PrintWriter(conf.getOutputStream(), false);
+ final PrintTraceListener tl = new PrintTraceListener(w);
+ tl.m_traceElements = conf.getElements();
+ tl.m_traceExtension = conf.getExtension();
+ tl.m_traceGeneration = conf.getGeneration();
+ tl.m_traceSelection = conf.getSelection();
+ tl.m_traceTemplates = conf.getTemplates();
+ try {
+ ((TransformerImpl) t).getTraceManager().addTraceListener(tl);
+ } catch (final TooManyListenersException tml) {
+ throw new BuildException(tml);
+ }
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ccm/CCMCheck.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ccm/CCMCheck.java
new file mode 100644
index 00000000..f6a94b52
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ccm/CCMCheck.java
@@ -0,0 +1,208 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.ccm;
+
+
+import java.io.File;
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.DirectoryScanner;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.Execute;
+import org.apache.tools.ant.types.Commandline;
+import org.apache.tools.ant.types.FileSet;
+
+
+/**
+ * Class common to all check commands (checkout, checkin,checkin default task);
+ * @ant.task ignore="true"
+ */
+public class CCMCheck extends Continuus {
+
+ private File file = null;
+ private String comment = null;
+ private String task = null;
+
+ // CheckStyle:VisibilityModifier OFF - bc
+
+ protected Vector filesets = new Vector();
+
+ // CheckStyle:VisibilityModifier ON
+
+ /** Constructor for CCMCheck. */
+ public CCMCheck() {
+ super();
+ }
+
+ /**
+ * Get the value of file.
+ * @return value of file.
+ */
+ public File getFile() {
+ return file;
+ }
+
+ /**
+ * Sets the path to the file that the command will operate on.
+ * @param v Value to assign to file.
+ */
+ public void setFile(File v) {
+ log("working file " + v, Project.MSG_VERBOSE);
+ this.file = v;
+ }
+
+ /**
+ * Get the value of comment.
+ * @return value of comment.
+ */
+ public String getComment() {
+ return comment;
+ }
+
+ /**
+ * Specifies a comment.
+ * @param v Value to assign to comment.
+ */
+ public void setComment(String v) {
+ this.comment = v;
+ }
+
+
+ /**
+ * Get the value of task.
+ * @return value of task.
+ */
+ public String getTask() {
+ return task;
+ }
+
+ /**
+ * Specifies the task number used to check
+ * in the file (may use 'default').
+ * @param v Value to assign to task.
+ */
+ public void setTask(String v) {
+ this.task = v;
+ }
+
+
+ /**
+ * Adds a set of files to copy.
+ * @param set the set of files
+ */
+ public void addFileset(FileSet set) {
+ filesets.addElement(set);
+ }
+
+
+ /**
+ * Executes the task.
+ * <p>
+ * Builds a command line to execute ccm and then calls Exec's run method
+ * to execute the command line.
+ * </p>
+ * @throws BuildException on error
+ */
+ public void execute() throws BuildException {
+
+ if (file == null && filesets.size() == 0) {
+ throw new BuildException(
+ "Specify at least one source - a file or a fileset.");
+ }
+
+ if (file != null && file.exists() && file.isDirectory()) {
+ throw new BuildException("CCMCheck cannot be generated for directories");
+ }
+
+ if (file != null && filesets.size() > 0) {
+ throw new BuildException("Choose between file and fileset !");
+ }
+
+ if (getFile() != null) {
+ doit();
+ return;
+ }
+
+ int sizeofFileSet = filesets.size();
+ for (int i = 0; i < sizeofFileSet; i++) {
+ FileSet fs = (FileSet) filesets.elementAt(i);
+ DirectoryScanner ds = fs.getDirectoryScanner(getProject());
+ String[] srcFiles = ds.getIncludedFiles();
+ for (int j = 0; j < srcFiles.length; j++) {
+ File src = new File(fs.getDir(getProject()), srcFiles[j]);
+ setFile(src);
+ doit();
+ }
+ }
+ }
+
+ /**
+ * check the file given by getFile().
+ */
+ private void doit() {
+ Commandline commandLine = new Commandline();
+
+ // build the command line from what we got the format is
+ // ccm co /t .. files
+ // as specified in the CCM.EXE help
+
+ commandLine.setExecutable(getCcmCommand());
+ commandLine.createArgument().setValue(getCcmAction());
+
+ checkOptions(commandLine);
+
+ int result = run(commandLine);
+ if (Execute.isFailure(result)) {
+ String msg = "Failed executing: " + commandLine.toString();
+ throw new BuildException(msg, getLocation());
+ }
+ }
+
+
+ /**
+ * Check the command line options.
+ */
+ private void checkOptions(Commandline cmd) {
+ if (getComment() != null) {
+ cmd.createArgument().setValue(FLAG_COMMENT);
+ cmd.createArgument().setValue(getComment());
+ }
+
+ if (getTask() != null) {
+ cmd.createArgument().setValue(FLAG_TASK);
+ cmd.createArgument().setValue(getTask());
+ }
+
+ if (getFile() != null) {
+ cmd.createArgument().setValue(file.getAbsolutePath());
+ }
+ }
+
+ /**
+ * -comment flag -- comment to attach to the file
+ */
+ public static final String FLAG_COMMENT = "/comment";
+
+ /**
+ * -task flag -- associate checkout task with task
+ */
+ public static final String FLAG_TASK = "/task";
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ccm/CCMCheckin.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ccm/CCMCheckin.java
new file mode 100644
index 00000000..ff7472c9
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ccm/CCMCheckin.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.ccm;
+
+import java.util.Date;
+
+/**
+ * Performs Continuus checkin command.
+ *
+ */
+public class CCMCheckin extends CCMCheck {
+
+ /**
+ * Default constructor - setup checkin command
+ */
+ public CCMCheckin() {
+ super();
+ setCcmAction(COMMAND_CHECKIN);
+ setComment("Checkin " + new Date());
+ }
+
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ccm/CCMCheckinDefault.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ccm/CCMCheckinDefault.java
new file mode 100644
index 00000000..2fe2a2a1
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ccm/CCMCheckinDefault.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.ccm;
+
+/**
+ * Performs Continuus Checkin Default task command.
+ *
+ * @ant.task name="ccmcheckintask" category="scm"
+ */
+public class CCMCheckinDefault extends CCMCheck {
+
+ /** Constructor for CCMCheckinDefault. */
+ public CCMCheckinDefault() {
+ super();
+ setCcmAction(COMMAND_CHECKIN);
+ setTask(DEFAULT_TASK);
+ }
+
+ /** The default task */
+ public static final String DEFAULT_TASK = "default";
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ccm/CCMCheckout.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ccm/CCMCheckout.java
new file mode 100644
index 00000000..44bbc6bf
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ccm/CCMCheckout.java
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.ccm;
+
+/**
+ * Performs Continuus checkout command.
+ *
+ */
+public class CCMCheckout extends CCMCheck {
+
+ /**
+ * default constructor
+ */
+ public CCMCheckout() {
+ super();
+ setCcmAction(COMMAND_CHECKOUT);
+ }
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ccm/CCMCreateTask.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ccm/CCMCreateTask.java
new file mode 100644
index 00000000..cda13a5c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ccm/CCMCreateTask.java
@@ -0,0 +1,335 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.ccm;
+
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.Execute;
+import org.apache.tools.ant.taskdefs.ExecuteStreamHandler;
+import org.apache.tools.ant.types.Commandline;
+
+
+/**
+ * Creates new Continuus ccm task and sets it as the default.
+ *
+ * @ant.task name="ccmcreatetask" category="scm"
+ */
+public class CCMCreateTask extends Continuus implements ExecuteStreamHandler {
+
+ private String comment = null;
+ private String platform = null;
+ private String resolver = null;
+ private String release = null;
+ private String subSystem = null;
+ private String task = null;
+
+ /**
+ * Constructor for CCMCreateTask.
+ */
+ public CCMCreateTask() {
+ super();
+ setCcmAction(COMMAND_CREATE_TASK);
+ }
+
+
+ /**
+ * Executes the task.
+ * <p>
+ * Builds a command line to execute ccm and then calls Exec's run method
+ * to execute the command line.
+ * </p>
+ * @throws BuildException on error
+ */
+ public void execute() throws BuildException {
+ Commandline commandLine = new Commandline();
+ int result = 0;
+
+ // build the command line from what we got the format
+ // as specified in the CCM.EXE help
+ commandLine.setExecutable(getCcmCommand());
+ commandLine.createArgument().setValue(getCcmAction());
+
+ checkOptions(commandLine);
+
+ result = run(commandLine, this);
+ if (Execute.isFailure(result)) {
+ String msg = "Failed executing: " + commandLine.toString();
+ throw new BuildException(msg, getLocation());
+ }
+
+ //create task ok, set this task as the default one
+ Commandline commandLine2 = new Commandline();
+ commandLine2.setExecutable(getCcmCommand());
+ commandLine2.createArgument().setValue(COMMAND_DEFAULT_TASK);
+ commandLine2.createArgument().setValue(getTask());
+
+ log(commandLine.describeCommand(), Project.MSG_DEBUG);
+
+ result = run(commandLine2);
+ if (result != 0) {
+ String msg = "Failed executing: " + commandLine2.toString();
+ throw new BuildException(msg, getLocation());
+ }
+
+ }
+
+
+ /**
+ * Check the command line options.
+ */
+ private void checkOptions(Commandline cmd) {
+ if (getComment() != null) {
+ cmd.createArgument().setValue(FLAG_COMMENT);
+ cmd.createArgument().setValue("\"" + getComment() + "\"");
+ }
+
+ if (getPlatform() != null) {
+ cmd.createArgument().setValue(FLAG_PLATFORM);
+ cmd.createArgument().setValue(getPlatform());
+ } // end of if ()
+
+ if (getResolver() != null) {
+ cmd.createArgument().setValue(FLAG_RESOLVER);
+ cmd.createArgument().setValue(getResolver());
+ } // end of if ()
+
+ if (getSubSystem() != null) {
+ cmd.createArgument().setValue(FLAG_SUBSYSTEM);
+ cmd.createArgument().setValue("\"" + getSubSystem() + "\"");
+ } // end of if ()
+
+ if (getRelease() != null) {
+ cmd.createArgument().setValue(FLAG_RELEASE);
+ cmd.createArgument().setValue(getRelease());
+ } // end of if ()
+ }
+
+
+ /**
+ * Get the value of comment.
+ * @return value of comment.
+ */
+ public String getComment() {
+ return comment;
+ }
+
+ /**
+ * Specifies a comment.
+ *
+ * @param v Value to assign to comment.
+ */
+ public void setComment(String v) {
+ this.comment = v;
+ }
+
+
+ /**
+ * Get the value of platform.
+ * @return value of platform.
+ */
+ public String getPlatform() {
+ return platform;
+ }
+
+ /**
+ * Specifies the target platform.
+ *
+ * @param v Value to assign to platform.
+ */
+ public void setPlatform(String v) {
+ this.platform = v;
+ }
+
+
+ /**
+ * Get the value of resolver.
+ * @return value of resolver.
+ */
+ public String getResolver() {
+ return resolver;
+ }
+
+ /**
+ * Specifies the resolver.
+ *
+ * @param v Value to assign to resolver.
+ */
+ public void setResolver(String v) {
+ this.resolver = v;
+ }
+
+
+ /**
+ * Get the value of release.
+ * @return value of release.
+ */
+ public String getRelease() {
+ return release;
+ }
+
+ /**
+ * Specify the CCM release.
+ *
+ * @param v Value to assign to release.
+ */
+ public void setRelease(String v) {
+ this.release = v;
+ }
+
+ /**
+ * Get the value of subSystem.
+ * @return value of subSystem.
+ */
+ public String getSubSystem() {
+ return subSystem;
+ }
+
+ /**
+ * Specifies the subsystem.
+ *
+ * @param v Value to assign to subSystem.
+ */
+ public void setSubSystem(String v) {
+ this.subSystem = v;
+ }
+
+
+ /**
+ * Get the value of task.
+ * @return value of task.
+ */
+ public String getTask() {
+ return task;
+ }
+
+ /**
+ * Specifies the task number used to checkin
+ * the file (may use 'default').
+ *
+ * @param v Value to assign to task.
+ */
+ public void setTask(String v) {
+ this.task = v;
+ }
+
+ /**
+ * /comment -- comments associated to the task
+ */
+ public static final String FLAG_COMMENT = "/synopsis";
+
+ /**
+ * /platform flag -- target platform
+ */
+ public static final String FLAG_PLATFORM = "/plat";
+
+ /**
+ * /resolver flag
+ */
+ public static final String FLAG_RESOLVER = "/resolver";
+
+ /**
+ * /release flag
+ */
+ public static final String FLAG_RELEASE = "/release";
+
+ /**
+ * /release flag
+ */
+ public static final String FLAG_SUBSYSTEM = "/subsystem";
+
+ /**
+ * -task flag -- associate checkout task with task
+ */
+ public static final String FLAG_TASK = "/task";
+
+
+ // implementation of org.apache.tools.ant.taskdefs.ExecuteStreamHandler interface
+
+ /**
+ *
+ * @throws IOException on error
+ */
+ public void start() throws IOException {
+ }
+
+ /**
+ *
+ */
+ public void stop() {
+ }
+
+ /**
+ *
+ * @param param1 the output stream
+ * @exception java.io.IOException on error
+ */
+ public void setProcessInputStream(OutputStream param1) throws IOException {
+ }
+
+ /**
+ *
+ * @param is the input stream
+ * @exception java.io.IOException on error
+ */
+ public void setProcessErrorStream(InputStream is) throws IOException {
+ BufferedReader reader = new BufferedReader(new InputStreamReader(is));
+ String s = reader.readLine();
+ if (s != null) {
+ log("err " + s, Project.MSG_DEBUG);
+ } // end of if ()
+ }
+
+ /**
+ * read the output stream to retrieve the new task number.
+ * @param is InputStream
+ * @throws IOException on error
+ */
+ public void setProcessOutputStream(InputStream is) throws IOException {
+
+ String buffer = "";
+ try {
+ BufferedReader reader = new BufferedReader(new InputStreamReader(is));
+ buffer = reader.readLine();
+ if (buffer != null) {
+ log("buffer:" + buffer, Project.MSG_DEBUG);
+ String taskstring = buffer.substring(buffer.indexOf(' ')).trim();
+ taskstring = taskstring.substring(0, taskstring.lastIndexOf(' ')).trim();
+ setTask(taskstring);
+ log("task is " + getTask(), Project.MSG_DEBUG);
+ } // end of if ()
+ } catch (NullPointerException npe) {
+ log("error procession stream , null pointer exception", Project.MSG_ERR);
+ npe.printStackTrace();
+ throw new BuildException(npe.getClass().getName());
+ } catch (Exception e) {
+ log("error procession stream " + e.getMessage(), Project.MSG_ERR);
+ throw new BuildException(e.getMessage());
+ } // end of try-catch
+
+ }
+
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ccm/CCMReconfigure.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ccm/CCMReconfigure.java
new file mode 100644
index 00000000..28f80645
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ccm/CCMReconfigure.java
@@ -0,0 +1,159 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.ccm;
+
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.taskdefs.Execute;
+import org.apache.tools.ant.types.Commandline;
+
+
+/**
+ * Task allows to reconfigure a project, recursively or not
+ */
+public class CCMReconfigure extends Continuus {
+
+ private String ccmProject = null;
+ private boolean recurse = false;
+ private boolean verbose = false;
+
+ /** Constructor for CCMReconfigure. */
+ public CCMReconfigure() {
+ super();
+ setCcmAction(COMMAND_RECONFIGURE);
+ }
+
+
+ /**
+ * Executes the task.
+ * <p>
+ * Builds a command line to execute ccm and then calls Exec's run method
+ * to execute the command line.
+ * </p>
+ * @throws BuildException on error
+ */
+ public void execute() throws BuildException {
+ Commandline commandLine = new Commandline();
+ int result = 0;
+
+ // build the command line from what we got the format
+ // as specified in the CCM.EXE help
+ commandLine.setExecutable(getCcmCommand());
+ commandLine.createArgument().setValue(getCcmAction());
+
+ checkOptions(commandLine);
+
+ result = run(commandLine);
+ if (Execute.isFailure(result)) {
+ String msg = "Failed executing: " + commandLine.toString();
+ throw new BuildException(msg, getLocation());
+ }
+ }
+
+
+ /**
+ * Check the command line options.
+ */
+ private void checkOptions(Commandline cmd) {
+
+ if (isRecurse()) {
+ cmd.createArgument().setValue(FLAG_RECURSE);
+ } // end of if ()
+
+ if (isVerbose()) {
+ cmd.createArgument().setValue(FLAG_VERBOSE);
+ } // end of if ()
+
+ if (getCcmProject() != null) {
+ cmd.createArgument().setValue(FLAG_PROJECT);
+ cmd.createArgument().setValue(getCcmProject());
+ }
+
+ }
+
+ /**
+ * Get the value of project.
+ * @return value of project.
+ */
+ public String getCcmProject() {
+ return ccmProject;
+ }
+
+ /**
+ * Sets the ccm project on which the operation is applied.
+ * @param v Value to assign to project.
+ */
+ public void setCcmProject(String v) {
+ this.ccmProject = v;
+ }
+
+
+ /**
+ * Get the value of recurse.
+ * @return value of recurse.
+ */
+ public boolean isRecurse() {
+ return recurse;
+ }
+
+ /**
+ * If true, recurse on subproject (default false).
+ *
+ * @param v Value to assign to recurse.
+ */
+ public void setRecurse(boolean v) {
+ this.recurse = v;
+ }
+
+
+ /**
+ * Get the value of verbose.
+ * @return value of verbose.
+ */
+ public boolean isVerbose() {
+ return verbose;
+ }
+
+ /**
+ * If true, do a verbose reconfigure operation (default false).
+ * @param v Value to assign to verbose.
+ */
+ public void setVerbose(boolean v) {
+ this.verbose = v;
+ }
+
+
+ /**
+ * /recurse --
+ */
+ public static final String FLAG_RECURSE = "/recurse";
+
+ /**
+ * /recurse --
+ */
+ public static final String FLAG_VERBOSE = "/verbose";
+
+
+ /**
+ * /project flag -- target project
+ */
+ public static final String FLAG_PROJECT = "/project";
+
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ccm/Continuus.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ccm/Continuus.java
new file mode 100644
index 00000000..5618dd6a
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ccm/Continuus.java
@@ -0,0 +1,144 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.ccm;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.taskdefs.Execute;
+import org.apache.tools.ant.taskdefs.ExecuteStreamHandler;
+import org.apache.tools.ant.taskdefs.LogStreamHandler;
+import org.apache.tools.ant.types.Commandline;
+import org.apache.tools.ant.util.FileUtils;
+
+
+/**
+ * A base class for creating tasks for executing commands on Continuus 5.1.
+ * <p>
+ * The class extends the task as it operates by executing the ccm.exe program
+ * supplied with Continuus/Synergy. By default the task expects the ccm executable to be
+ * in the path,
+ * you can override this be specifying the ccmdir attribute.
+ * </p>
+ *
+ */
+public abstract class Continuus extends Task {
+
+ private String ccmDir = "";
+ private String ccmAction = "";
+
+ /**
+ * Get the value of ccmAction.
+ * @return value of ccmAction.
+ */
+ public String getCcmAction() {
+ return ccmAction;
+ }
+
+ /**
+ * Set the value of ccmAction.
+ * @param v Value to assign to ccmAction.
+ * @ant.attribute ignore="true"
+ */
+ public void setCcmAction(String v) {
+ this.ccmAction = v;
+ }
+
+
+ /**
+ * Set the directory where the ccm executable is located.
+ *
+ * @param dir the directory containing the ccm executable
+ */
+ public final void setCcmDir(String dir) {
+ ccmDir = FileUtils.translatePath(dir);
+ }
+
+ /**
+ * Builds and returns the command string to execute ccm
+ * @return String containing path to the executable
+ */
+ protected final String getCcmCommand() {
+ String toReturn = ccmDir;
+ if (!toReturn.equals("") && !toReturn.endsWith("/")) {
+ toReturn += "/";
+ }
+
+ toReturn += CCM_EXE;
+
+ return toReturn;
+ }
+
+
+ /**
+ * Run the command.
+ * @param cmd the command line
+ * @param handler an execute stream handler
+ * @return the exit status of the command
+ */
+ protected int run(Commandline cmd, ExecuteStreamHandler handler) {
+ try {
+ Execute exe = new Execute(handler);
+ exe.setAntRun(getProject());
+ exe.setWorkingDirectory(getProject().getBaseDir());
+ exe.setCommandline(cmd.getCommandline());
+ return exe.execute();
+ } catch (java.io.IOException e) {
+ throw new BuildException(e, getLocation());
+ }
+ }
+
+ /**
+ * Run the command.
+ * @param cmd the command line
+ * @return the exit status of the command
+ */
+ protected int run(Commandline cmd) {
+ return run(cmd, new LogStreamHandler(this, Project.MSG_VERBOSE, Project.MSG_WARN));
+ }
+
+ /**
+ * Constant for the thing to execute
+ */
+ private static final String CCM_EXE = "ccm";
+
+ /**
+ * The 'CreateTask' command
+ */
+ public static final String COMMAND_CREATE_TASK = "create_task";
+ /**
+ * The 'Checkout' command
+ */
+ public static final String COMMAND_CHECKOUT = "co";
+ /**
+ * The 'Checkin' command
+ */
+ public static final String COMMAND_CHECKIN = "ci";
+ /**
+ * The 'Reconfigure' command
+ */
+ public static final String COMMAND_RECONFIGURE = "reconfigure";
+
+ /**
+ * The 'Reconfigure' command
+ */
+ public static final String COMMAND_DEFAULT_TASK = "default_task";
+
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCCheckin.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCCheckin.java
new file mode 100644
index 00000000..371d418b
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCCheckin.java
@@ -0,0 +1,343 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.clearcase;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.Execute;
+import org.apache.tools.ant.types.Commandline;
+
+/**
+ * Performs ClearCase checkin.
+ *
+ * <p>
+ * The following attributes are interpreted:
+ * <table border="1">
+ * <tr>
+ * <th>Attribute</th>
+ * <th>Values</th>
+ * <th>Required</th>
+ * </tr>
+ * <tr>
+ * <td>viewpath</td>
+ * <td>Path to the ClearCase view file or directory that the command will operate on</td>
+ * <td>No</td>
+ * </tr>
+ * <tr>
+ * <td>comment</td>
+ * <td>Specify a comment. Only one of comment or cfile may be used.</td>
+ * <td>No</td>
+ * </tr>
+ * <tr>
+ * <td>commentfile</td>
+ * <td>Specify a file containing a comment. Only one of comment or cfile may be used.</td>
+ * <td>No</td>
+ * </tr>
+ * <tr>
+ * <td>nowarn</td>
+ * <td>Suppress warning messages</td>
+ * <td>No</td>
+ * </tr>
+ * <tr>
+ * <td>preservetime</td>
+ * <td>Preserve the modification time</td>
+ * <td>No</td>
+ * </tr>
+ * <tr>
+ * <td>keepcopy</td>
+ * <td>Keeps a copy of the file with a .keep extension</td>
+ * <td>No</td>
+ * </tr>
+ * <tr>
+ * <td>identical</td>
+ * <td>Allows the file to be checked in even if it is identical to the original</td>
+ * <td>No</td>
+ * </tr>
+ * <tr>
+ * <td>failonerr</td>
+ * <td>Throw an exception if the command fails. Default is true</td>
+ * <td>No</td>
+ * </tr>
+ * </table>
+ *
+ */
+public class CCCheckin extends ClearCase {
+ private String mComment = null;
+ private String mCfile = null;
+ private boolean mNwarn = false;
+ private boolean mPtime = false;
+ private boolean mKeep = false;
+ private boolean mIdentical = true;
+
+ /**
+ * Executes the task.
+ * <p>
+ * Builds a command line to execute cleartool and then calls Exec's run method
+ * to execute the command line.
+ * @throws BuildException if the command fails and failonerr is set to true
+ */
+ public void execute() throws BuildException {
+ Commandline commandLine = new Commandline();
+ Project aProj = getProject();
+ int result = 0;
+
+ // Default the viewpath to basedir if it is not specified
+ if (getViewPath() == null) {
+ setViewPath(aProj.getBaseDir().getPath());
+ }
+
+ // build the command line from what we got. the format is
+ // cleartool checkin [options...] [viewpath ...]
+ // as specified in the CLEARTOOL.EXE help
+ commandLine.setExecutable(getClearToolCommand());
+ commandLine.createArgument().setValue(COMMAND_CHECKIN);
+
+ checkOptions(commandLine);
+
+ if (!getFailOnErr()) {
+ getProject().log("Ignoring any errors that occur for: "
+ + getViewPathBasename(), Project.MSG_VERBOSE);
+ }
+ result = run(commandLine);
+ if (Execute.isFailure(result) && getFailOnErr()) {
+ String msg = "Failed executing: " + commandLine.toString();
+ throw new BuildException(msg, getLocation());
+ }
+ }
+
+
+ /**
+ * Check the command line options.
+ */
+ private void checkOptions(Commandline cmd) {
+ if (getComment() != null) {
+ // -c
+ getCommentCommand(cmd);
+ } else {
+ if (getCommentFile() != null) {
+ // -cfile
+ getCommentFileCommand(cmd);
+ } else {
+ cmd.createArgument().setValue(FLAG_NOCOMMENT);
+ }
+ }
+
+ if (getNoWarn()) {
+ // -nwarn
+ cmd.createArgument().setValue(FLAG_NOWARN);
+ }
+
+ if (getPreserveTime()) {
+ // -ptime
+ cmd.createArgument().setValue(FLAG_PRESERVETIME);
+ }
+
+ if (getKeepCopy()) {
+ // -keep
+ cmd.createArgument().setValue(FLAG_KEEPCOPY);
+ }
+
+ if (getIdentical()) {
+ // -identical
+ cmd.createArgument().setValue(FLAG_IDENTICAL);
+ }
+
+ // viewpath
+ cmd.createArgument().setValue(getViewPath());
+ }
+
+
+ /**
+ * Sets the comment string.
+ *
+ * @param comment the comment string
+ */
+ public void setComment(String comment) {
+ mComment = comment;
+ }
+
+ /**
+ * Get comment string
+ *
+ * @return String containing the comment
+ */
+ public String getComment() {
+ return mComment;
+ }
+
+ /**
+ * Specifies a file containing a comment.
+ *
+ * @param cfile the path to the comment file
+ */
+ public void setCommentFile(String cfile) {
+ mCfile = cfile;
+ }
+
+ /**
+ * Get comment file
+ *
+ * @return String containing the path to the comment file
+ */
+ public String getCommentFile() {
+ return mCfile;
+ }
+
+ /**
+ * If true, suppress warning messages.
+ *
+ * @param nwarn the status to set the flag to
+ */
+ public void setNoWarn(boolean nwarn) {
+ mNwarn = nwarn;
+ }
+
+ /**
+ * Get nowarn flag status
+ *
+ * @return boolean containing status of nwarn flag
+ */
+ public boolean getNoWarn() {
+ return mNwarn;
+ }
+
+ /**
+ * If true, preserve the modification time.
+ *
+ * @param ptime the status to set the flag to
+ */
+ public void setPreserveTime(boolean ptime) {
+ mPtime = ptime;
+ }
+
+ /**
+ * Get preservetime flag status
+ *
+ * @return boolean containing status of preservetime flag
+ */
+ public boolean getPreserveTime() {
+ return mPtime;
+ }
+
+ /**
+ * If true, keeps a copy of the file with a .keep extension.
+ *
+ * @param keep the status to set the flag to
+ */
+ public void setKeepCopy(boolean keep) {
+ mKeep = keep;
+ }
+
+ /**
+ * Get keepcopy flag status
+ *
+ * @return boolean containing status of keepcopy flag
+ */
+ public boolean getKeepCopy() {
+ return mKeep;
+ }
+
+ /**
+ * If true, allows the file to be checked in even
+ * if it is identical to the original.
+ *
+ * @param identical the status to set the flag to
+ */
+ public void setIdentical(boolean identical) {
+ mIdentical = identical;
+ }
+
+ /**
+ * Get identical flag status
+ *
+ * @return boolean containing status of identical flag
+ */
+ public boolean getIdentical() {
+ return mIdentical;
+ }
+
+
+ /**
+ * Get the 'comment' command
+ *
+ * @param cmd containing the command line string with or
+ * without the comment flag and string appended
+ */
+ private void getCommentCommand(Commandline cmd) {
+ if (getComment() != null) {
+ /* Had to make two separate commands here because if a space is
+ inserted between the flag and the value, it is treated as a
+ Windows filename with a space and it is enclosed in double
+ quotes ("). This breaks clearcase.
+ */
+ cmd.createArgument().setValue(FLAG_COMMENT);
+ cmd.createArgument().setValue(getComment());
+ }
+ }
+
+ /**
+ * Get the 'commentfile' command
+ *
+ * @param cmd containing the command line string with or
+ * without the commentfile flag and file appended
+ */
+ private void getCommentFileCommand(Commandline cmd) {
+ if (getCommentFile() != null) {
+ /* Had to make two separate commands here because if a space is
+ inserted between the flag and the value, it is treated as a
+ Windows filename with a space and it is enclosed in double
+ quotes ("). This breaks clearcase.
+ */
+ cmd.createArgument().setValue(FLAG_COMMENTFILE);
+ cmd.createArgument().setValue(getCommentFile());
+ }
+ }
+
+
+ /**
+ * -c flag -- comment to attach to the file
+ */
+ public static final String FLAG_COMMENT = "-c";
+ /**
+ * -cfile flag -- file containing a comment to attach to the file
+ */
+ public static final String FLAG_COMMENTFILE = "-cfile";
+ /**
+ * -nc flag -- no comment is specified
+ */
+ public static final String FLAG_NOCOMMENT = "-nc";
+ /**
+ * -nwarn flag -- suppresses warning messages
+ */
+ public static final String FLAG_NOWARN = "-nwarn";
+ /**
+ * -ptime flag -- preserves the modification time
+ */
+ public static final String FLAG_PRESERVETIME = "-ptime";
+ /**
+ * -keep flag -- keeps a copy of the file with a .keep extension
+ */
+ public static final String FLAG_KEEPCOPY = "-keep";
+ /**
+ * -identical flag -- allows the file to be checked in even if it is identical to the original
+ */
+ public static final String FLAG_IDENTICAL = "-identical";
+
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCCheckout.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCCheckout.java
new file mode 100644
index 00000000..0eaf09ac
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCCheckout.java
@@ -0,0 +1,516 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.clearcase;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.Execute;
+import org.apache.tools.ant.types.Commandline;
+
+
+/**
+ * Performs ClearCase checkout.
+ *
+ * <p>
+ * The following attributes are interpreted:
+ * <table border="1">
+ * <tr>
+ * <th>Attribute</th>
+ * <th>Values</th>
+ * <th>Required</th>
+ * </tr>
+ * <tr>
+ * <td>viewpath</td>
+ * <td>Path to the ClearCase view file or directory that the command will operate on</td>
+ * <td>No</td>
+ * <tr>
+ * <tr>
+ * <td>reserved</td>
+ * <td>Specifies whether to check out the file as reserved or not</td>
+ * <td>Yes</td>
+ * <tr>
+ * <tr>
+ * <td>out</td>
+ * <td>Creates a writable file under a different filename</td>
+ * <td>No</td>
+ * <tr>
+ * <tr>
+ * <td>nodata</td>
+ * <td>Checks out the file but does not create an editable file containing its data</td>
+ * <td>No</td>
+ * <tr>
+ * <tr>
+ * <td>branch</td>
+ * <td>Specify a branch to check out the file to</td>
+ * <td>No</td>
+ * <tr>
+ * <tr>
+ * <td>version</td>
+ * <td>Allows checkout of a version other than main latest</td>
+ * <td>No</td>
+ * <tr>
+ * <tr>
+ * <td>nowarn</td>
+ * <td>Suppress warning messages</td>
+ * <td>No</td>
+ * <tr>
+ * <tr>
+ * <td>comment</td>
+ * <td>Specify a comment. Only one of comment or cfile may be used.</td>
+ * <td>No</td>
+ * <tr>
+ * <tr>
+ * <td>commentfile</td>
+ * <td>Specify a file containing a comment. Only one of comment or cfile may be used.</td>
+ * <td>No</td>
+ * <tr>
+ * <tr>
+ * <td>notco</td>
+ * <td>Fail if it's already checked out to the current view. Set to false to ignore it.</td>
+ * <td>No</td>
+ * <tr>
+ * <tr>
+ * <td>failonerr</td>
+ * <td>Throw an exception if the command fails. Default is true</td>
+ * <td>No</td>
+ * <tr>
+ * </table>
+ *
+ */
+public class CCCheckout extends ClearCase {
+ private boolean mReserved = true;
+ private String mOut = null;
+ private boolean mNdata = false;
+ private String mBranch = null;
+ private boolean mVersion = false;
+ private boolean mNwarn = false;
+ private String mComment = null;
+ private String mCfile = null;
+ private boolean mNotco = true;
+
+ /**
+ * Executes the task.
+ * <p>
+ * Builds a command line to execute cleartool and then calls Exec's run method
+ * to execute the command line.
+ * @throws BuildException if the command fails and failonerr is set to true
+ */
+ public void execute() throws BuildException {
+ Commandline commandLine = new Commandline();
+ Project aProj = getProject();
+ int result = 0;
+
+ // Default the viewpath to basedir if it is not specified
+ if (getViewPath() == null) {
+ setViewPath(aProj.getBaseDir().getPath());
+ }
+
+ // build the command line from what we got the format is
+ // cleartool checkout [options...] [viewpath ...]
+ // as specified in the CLEARTOOL.EXE help
+ commandLine.setExecutable(getClearToolCommand());
+ commandLine.createArgument().setValue(COMMAND_CHECKOUT);
+
+ checkOptions(commandLine);
+ /*
+ * If configured to not care about whether the element is
+ * already checked out to the current view.
+ * Then check to see if it is checked out.
+ */
+ if (!getNotco() && lsCheckout()) {
+ getProject().log("Already checked out in this view: "
+ + getViewPathBasename(), Project.MSG_VERBOSE);
+ return;
+ }
+ if (!getFailOnErr()) {
+ getProject().log("Ignoring any errors that occur for: "
+ + getViewPathBasename(), Project.MSG_VERBOSE);
+ }
+ result = run(commandLine);
+ if (Execute.isFailure(result) && getFailOnErr()) {
+ String msg = "Failed executing: " + commandLine.toString();
+ throw new BuildException(msg, getLocation());
+ }
+ }
+
+ /**
+ * Check to see if the element is checked out in the current view.
+ */
+ private boolean lsCheckout() {
+ Commandline cmdl = new Commandline();
+ String result;
+
+ // build the command line from what we got the format is
+ // cleartool lsco [options...] [viewpath ...]
+ // as specified in the CLEARTOOL.EXE help
+ cmdl.setExecutable(getClearToolCommand());
+ cmdl.createArgument().setValue(COMMAND_LSCO);
+ cmdl.createArgument().setValue("-cview");
+ cmdl.createArgument().setValue("-short");
+ cmdl.createArgument().setValue("-d");
+ // viewpath
+ cmdl.createArgument().setValue(getViewPath());
+
+ result = runS(cmdl);
+
+ // System.out.println( "lsCheckout: " + result );
+
+ return (result != null && result.length() > 0) ? true : false;
+ }
+ /**
+ * Check the command line options.
+ */
+ private void checkOptions(Commandline cmd) {
+ // ClearCase items
+ if (getReserved()) {
+ // -reserved
+ cmd.createArgument().setValue(FLAG_RESERVED);
+ } else {
+ // -unreserved
+ cmd.createArgument().setValue(FLAG_UNRESERVED);
+ }
+
+ if (getOut() != null) {
+ // -out
+ getOutCommand(cmd);
+ } else {
+ if (getNoData()) {
+ // -ndata
+ cmd.createArgument().setValue(FLAG_NODATA);
+ }
+
+ }
+
+ if (getBranch() != null) {
+ // -branch
+ getBranchCommand(cmd);
+ } else {
+ if (getVersion()) {
+ // -version
+ cmd.createArgument().setValue(FLAG_VERSION);
+ }
+
+ }
+
+ if (getNoWarn()) {
+ // -nwarn
+ cmd.createArgument().setValue(FLAG_NOWARN);
+ }
+
+ if (getComment() != null) {
+ // -c
+ getCommentCommand(cmd);
+ } else {
+ if (getCommentFile() != null) {
+ // -cfile
+ getCommentFileCommand(cmd);
+ } else {
+ cmd.createArgument().setValue(FLAG_NOCOMMENT);
+ }
+ }
+
+ // viewpath
+ cmd.createArgument().setValue(getViewPath());
+
+ // Print out info about the notco option
+ // System.out.println( "Notco: " + (getNotco() ? "yes" : "no") );
+ }
+
+ /**
+ * If true, checks out the file as reserved.
+ *
+ * @param reserved the status to set the flag to
+ */
+ public void setReserved(boolean reserved) {
+ mReserved = reserved;
+ }
+
+ /**
+ * Get reserved flag status
+ *
+ * @return boolean containing status of reserved flag
+ */
+ public boolean getReserved() {
+ return mReserved;
+ }
+
+ /**
+ * If true, checkout fails if the element is already checked out to the current view.
+ *
+ * @param notco the status to set the flag to
+ * @since ant 1.6.1
+ */
+ public void setNotco(boolean notco) {
+ mNotco = notco;
+ }
+
+ /**
+ * Get notco flag status
+ *
+ * @return boolean containing status of notco flag
+ * @since ant 1.6.1
+ */
+ public boolean getNotco() {
+ return mNotco;
+ }
+
+
+ /**
+ * Creates a writable file under a different filename.
+ *
+ * @param outf the path to the out file
+ */
+ public void setOut(String outf) {
+ mOut = outf;
+ }
+
+ /**
+ * Get out file
+ *
+ * @return String containing the path to the out file
+ */
+ public String getOut() {
+ return mOut;
+ }
+
+ /**
+ * If true, checks out the file but does not create an
+ * editable file containing its data.
+ *
+ * @param ndata the status to set the flag to
+ */
+ public void setNoData(boolean ndata) {
+ mNdata = ndata;
+ }
+
+ /**
+ * Get nodata flag status
+ *
+ * @return boolean containing status of ndata flag
+ */
+ public boolean getNoData() {
+ return mNdata;
+ }
+
+ /**
+ * Specify a branch to check out the file to.
+ *
+ * @param branch the name of the branch
+ */
+ public void setBranch(String branch) {
+ mBranch = branch;
+ }
+
+ /**
+ * Get branch name
+ *
+ * @return String containing the name of the branch
+ */
+ public String getBranch() {
+ return mBranch;
+ }
+
+ /**
+ * If true, allows checkout of a version other than main latest.
+ *
+ * @param version the status to set the flag to
+ */
+ public void setVersion(boolean version) {
+ mVersion = version;
+ }
+
+ /**
+ * Get version flag status
+ *
+ * @return boolean containing status of version flag
+ */
+ public boolean getVersion() {
+ return mVersion;
+ }
+
+ /**
+ * If true, warning messages are suppressed.
+ *
+ * @param nwarn the status to set the flag to
+ */
+ public void setNoWarn(boolean nwarn) {
+ mNwarn = nwarn;
+ }
+
+ /**
+ * Get nowarn flag status
+ *
+ * @return boolean containing status of nwarn flag
+ */
+ public boolean getNoWarn() {
+ return mNwarn;
+ }
+
+ /**
+ * Sets the comment string.
+ *
+ * @param comment the comment string
+ */
+ public void setComment(String comment) {
+ mComment = comment;
+ }
+
+ /**
+ * Get comment string
+ *
+ * @return String containing the comment
+ */
+ public String getComment() {
+ return mComment;
+ }
+
+ /**
+ * Specifies a file containing a comment.
+ *
+ * @param cfile the path to the comment file
+ */
+ public void setCommentFile(String cfile) {
+ mCfile = cfile;
+ }
+
+ /**
+ * Get comment file
+ *
+ * @return String containing the path to the comment file
+ */
+ public String getCommentFile() {
+ return mCfile;
+ }
+
+ /**
+ * Get the 'out' command
+ *
+ * @param cmd containing the command line string with or
+ * without the out flag and path appended
+ */
+ private void getOutCommand(Commandline cmd) {
+ if (getOut() != null) {
+ /* Had to make two separate commands here because if a space is
+ inserted between the flag and the value, it is treated as a
+ Windows filename with a space and it is enclosed in double
+ quotes ("). This breaks clearcase.
+ */
+ cmd.createArgument().setValue(FLAG_OUT);
+ cmd.createArgument().setValue(getOut());
+ }
+ }
+
+ /**
+ * Get the 'branch' command
+ *
+ * @param cmd containing the command line string with or
+ without the branch flag and name appended
+ */
+ private void getBranchCommand(Commandline cmd) {
+ if (getBranch() != null) {
+ /* Had to make two separate commands here because if a space is
+ inserted between the flag and the value, it is treated as a
+ Windows filename with a space and it is enclosed in double
+ quotes ("). This breaks clearcase.
+ */
+ cmd.createArgument().setValue(FLAG_BRANCH);
+ cmd.createArgument().setValue(getBranch());
+ }
+ }
+
+
+ /**
+ * Get the 'comment' command
+ *
+ * @param cmd containing the command line string with or
+ * without the comment flag and string appended
+ */
+ private void getCommentCommand(Commandline cmd) {
+ if (getComment() != null) {
+ /* Had to make two separate commands here because if a space is
+ inserted between the flag and the value, it is treated as a
+ Windows filename with a space and it is enclosed in double
+ quotes ("). This breaks clearcase.
+ */
+ cmd.createArgument().setValue(FLAG_COMMENT);
+ cmd.createArgument().setValue(getComment());
+ }
+ }
+
+ /**
+ * Get the 'cfile' command
+ *
+ * @param cmd containing the command line string with or
+ * without the cfile flag and file appended
+ */
+ private void getCommentFileCommand(Commandline cmd) {
+ if (getCommentFile() != null) {
+ /* Had to make two separate commands here because if a space is
+ inserted between the flag and the value, it is treated as a
+ Windows filename with a space and it is enclosed in double
+ quotes ("). This breaks clearcase.
+ */
+ cmd.createArgument().setValue(FLAG_COMMENTFILE);
+ cmd.createArgument().setValue(getCommentFile());
+ }
+ }
+
+ /**
+ * -reserved flag -- check out the file as reserved
+ */
+ public static final String FLAG_RESERVED = "-reserved";
+ /**
+ * -reserved flag -- check out the file as unreserved
+ */
+ public static final String FLAG_UNRESERVED = "-unreserved";
+ /**
+ * -out flag -- create a writable file under a different filename
+ */
+ public static final String FLAG_OUT = "-out";
+ /**
+ * -ndata flag -- checks out the file but does not create an editable file containing its data
+ */
+ public static final String FLAG_NODATA = "-ndata";
+ /**
+ * -branch flag -- checks out the file on a specified branch
+ */
+ public static final String FLAG_BRANCH = "-branch";
+ /**
+ * -version flag -- allows checkout of a version that is not main latest
+ */
+ public static final String FLAG_VERSION = "-version";
+ /**
+ * -nwarn flag -- suppresses warning messages
+ */
+ public static final String FLAG_NOWARN = "-nwarn";
+ /**
+ * -c flag -- comment to attach to the file
+ */
+ public static final String FLAG_COMMENT = "-c";
+ /**
+ * -cfile flag -- file containing a comment to attach to the file
+ */
+ public static final String FLAG_COMMENTFILE = "-cfile";
+ /**
+ * -nc flag -- no comment is specified
+ */
+ public static final String FLAG_NOCOMMENT = "-nc";
+
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCLock.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCLock.java
new file mode 100644
index 00000000..c273554e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCLock.java
@@ -0,0 +1,378 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.clearcase;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.Execute;
+import org.apache.tools.ant.types.Commandline;
+
+
+/**
+ * TODO:
+ * comment field doesn't include all options yet
+ */
+
+
+
+/**
+ * Performs a ClearCase Lock command.
+ *
+ * <p>
+ * The following attributes are interpreted:
+ * <table border="1">
+ * <tr>
+ * <th>Attribute</th>
+ * <th>Values</th>
+ * <th>Required</th>
+ * </tr>
+ * <tr>
+ * <td>replace</td>
+ * <td>Specifies replacing an existing lock</td>
+ * <td>No</td>
+ * <tr>
+ * <tr>
+ * <td>nusers</td>
+ * <td>Specifies user(s) who can still modify the object/pname</td>
+ * <td>No</td>
+ * <tr>
+ * <tr>
+ * <td>obsolete</td>
+ * <td>Specifies that the object/pname should be marked obsolete</td>
+ * <td>No</td>
+ * <tr>
+ * <tr>
+ * <td>comment</td>
+ * <td>Specifies how to populate comments fields</td>
+ * <td>No</td>
+ * <tr>
+ * <tr>
+ * <td>pname</td>
+ * <td>Specifies the pathname to be locked.</td>
+ * <td>No</td>
+ * <tr>
+ * <td>objselect</td>
+ * <td>This variable is obsolete. Should use <i>objsel</i> instead.</td>
+ * <td>No</td>
+ * <tr>
+ * <tr>
+ * <td>objsel</td>
+ * <td>Specifies the object(s) to be unlocked.</td>
+ * <td>No</td>
+ * <tr>
+ * <tr>
+ * <td>failonerr</td>
+ * <td>Throw an exception if the command fails. Default is true</td>
+ * <td>No</td>
+ * <tr>
+ * </table>
+ *
+ */
+public class CCLock extends ClearCase {
+ private boolean mReplace = false;
+ private boolean mObsolete = false;
+ private String mComment = null;
+ private String mNusers = null;
+ private String mPname = null;
+ private String mObjselect = null;
+
+ /**
+ * Executes the task.
+ * <p>
+ * Builds a command line to execute cleartool and then calls Exec's run method
+ * to execute the command line.
+ * @throws BuildException if the command fails and failonerr is set to true
+ */
+ public void execute() throws BuildException {
+ Commandline commandLine = new Commandline();
+ Project aProj = getProject();
+ int result = 0;
+
+ // Default the viewpath to basedir if it is not specified
+ if (getViewPath() == null) {
+ setViewPath(aProj.getBaseDir().getPath());
+ }
+
+ // build the command line from what we got the format is
+ // cleartool lock [options...]
+ // as specified in the CLEARTOOL.EXE help
+ commandLine.setExecutable(getClearToolCommand());
+ commandLine.createArgument().setValue(COMMAND_LOCK);
+
+ // Check the command line options
+ checkOptions(commandLine);
+
+ // For debugging
+ // System.out.println(commandLine.toString());
+
+ if (!getFailOnErr()) {
+ getProject().log("Ignoring any errors that occur for: "
+ + getOpType(), Project.MSG_VERBOSE);
+ }
+ result = run(commandLine);
+ if (Execute.isFailure(result) && getFailOnErr()) {
+ String msg = "Failed executing: " + commandLine.toString();
+ throw new BuildException(msg, getLocation());
+ }
+ }
+
+ /**
+ * Check the command line options.
+ */
+private void checkOptions(Commandline cmd) {
+ // ClearCase items
+ if (getReplace()) {
+ // -replace
+ cmd.createArgument().setValue(FLAG_REPLACE);
+ }
+ if (getObsolete()) {
+ // -obsolete
+ cmd.createArgument().setValue(FLAG_OBSOLETE);
+ } else {
+ getNusersCommand(cmd);
+ }
+ getCommentCommand(cmd);
+
+ if (getObjselect() == null && getPname() == null) {
+ throw new BuildException("Should select either an element "
+ + "(pname) or an object (objselect)");
+ }
+ getPnameCommand(cmd);
+ // object selector
+ if (getObjselect() != null) {
+ cmd.createArgument().setValue(getObjselect());
+ }
+}
+
+ /**
+ * If true, replace an existing lock.
+ *
+ * @param replace the status to set the flag to
+ */
+ public void setReplace(boolean replace) {
+ mReplace = replace;
+ }
+
+ /**
+ * Get replace flag status
+ *
+ * @return boolean containing status of replace flag
+ */
+ public boolean getReplace() {
+ return mReplace;
+ }
+
+ /**
+ * If true, mark object as obsolete.
+ *
+ * @param obsolete the status to set the flag to
+ */
+ public void setObsolete(boolean obsolete) {
+ mObsolete = obsolete;
+ }
+
+ /**
+ * Get obsolete flag status
+ *
+ * @return boolean containing status of obsolete flag
+ */
+ public boolean getObsolete() {
+ return mObsolete;
+ }
+
+ /**
+ * Sets the users who may continue to
+ * edit the object while it is locked.
+ *
+ * @param nusers users excluded from lock
+ */
+ public void setNusers(String nusers) {
+ mNusers = nusers;
+ }
+
+ /**
+ * Get nusers list
+ *
+ * @return String containing the list of users excluded from lock
+ */
+ public String getNusers() {
+ return mNusers;
+ }
+
+ /**
+ * Sets how comments should be written
+ * for the event record(s)
+ *
+ * @param comment comment method to use
+ */
+ public void setComment(String comment) {
+ mComment = comment;
+ }
+
+ /**
+ * Get comment method
+ *
+ * @return String containing the desired comment method
+ */
+ public String getComment() {
+ return mComment;
+ }
+
+ /**
+ * Sets the pathname to be locked
+ *
+ * @param pname pathname to be locked
+ */
+ public void setPname(String pname) {
+ mPname = pname;
+ }
+
+ /**
+ * Get the pathname to be locked
+ *
+ * @return String containing the pathname to be locked
+ */
+ public String getPname() {
+ return mPname;
+ }
+
+ /**
+ * Sets the object(s) to be locked
+ *
+ * @param objsel objects to be locked
+ * @since ant 1.6.1
+ */
+ public void setObjSel(String objsel) {
+ mObjselect = objsel;
+ }
+
+ /**
+ * Sets the object(s) to be locked
+ *
+ * @param objselect objects to be locked
+ */
+ public void setObjselect(String objselect) {
+ mObjselect = objselect;
+ }
+
+ /**
+ * Get list of objects to be locked
+ *
+ * @return String containing the objects to be locked
+ */
+ public String getObjselect() {
+ return mObjselect;
+ }
+
+ /**
+ * Get the 'nusers' command
+ *
+ * @param cmd containing the command line string with or
+ * without the nusers flag and value appended
+ */
+ private void getNusersCommand(Commandline cmd) {
+ if (getNusers() == null) {
+ return;
+ } else {
+ /* Had to make two separate commands here because if a space is
+ inserted between the flag and the value, it is treated as a
+ Windows filename with a space and it is enclosed in double
+ quotes ("). This breaks clearcase.
+ */
+ cmd.createArgument().setValue(FLAG_NUSERS);
+ cmd.createArgument().setValue(getNusers());
+ }
+ }
+
+ /**
+ * Get the 'comment' command
+ *
+ * @param cmd containing the command line string with or without the
+ * comment flag and value appended
+ */
+ private void getCommentCommand(Commandline cmd) {
+ if (getComment() == null) {
+ return;
+ } else {
+ /* Had to make two separate commands here because if a space is
+ inserted between the flag and the value, it is treated as a
+ Windows filename with a space and it is enclosed in double
+ quotes ("). This breaks clearcase.
+ */
+ cmd.createArgument().setValue(FLAG_COMMENT);
+ cmd.createArgument().setValue(getComment());
+ }
+ }
+
+ /**
+ * Get the 'pname' command
+ *
+ * @param cmd containing the command line string with or
+ * without the pname flag and value appended
+ */
+ private void getPnameCommand(Commandline cmd) {
+ if (getPname() == null) {
+ return;
+ } else {
+ /* Had to make two separate commands here because if a space is
+ inserted between the flag and the value, it is treated as a
+ Windows filename with a space and it is enclosed in double
+ quotes ("). This breaks clearcase.
+ */
+ cmd.createArgument().setValue(FLAG_PNAME);
+ cmd.createArgument().setValue(getPname());
+ }
+ }
+
+ /**
+ * Return which object/pname is being operated on
+ *
+ * @return String containing the object/pname being worked on
+ */
+ private String getOpType() {
+
+ if (getPname() != null) {
+ return getPname();
+ } else {
+ return getObjselect();
+ }
+ }
+
+ /**
+ * -replace flag -- replace existing lock on object(s)
+ */
+ public static final String FLAG_REPLACE = "-replace";
+ /**
+ * -nusers flag -- list of users to exclude from lock
+ */
+ public static final String FLAG_NUSERS = "-nusers";
+ /**
+ * -obsolete flag -- mark locked object as obsolete
+ */
+ public static final String FLAG_OBSOLETE = "-obsolete";
+ /**
+ * -comment flag -- method to use for commenting events
+ */
+ public static final String FLAG_COMMENT = "-comment";
+ /**
+ * -pname flag -- pathname to lock
+ */
+ public static final String FLAG_PNAME = "-pname";
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCMkattr.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCMkattr.java
new file mode 100644
index 00000000..128ea16b
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCMkattr.java
@@ -0,0 +1,425 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.clearcase;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.Execute;
+import org.apache.tools.ant.taskdefs.condition.Os;
+import org.apache.tools.ant.types.Commandline;
+
+/**
+ * Task to perform mkattr command to ClearCase.
+ * <p>
+ * The following attributes are interpreted:
+ * <table border="1">
+ * <tr>
+ * <th>Attribute</th>
+ * <th>Values</th>
+ * <th>Required</th>
+ * </tr>
+ * <tr>
+ * <td>viewpath</td>
+ * <td>Path to the ClearCase view file or directory that the command will operate on</td>
+ * <td>Yes</td>
+ * <tr>
+ * <tr>
+ * <td>replace</td>
+ * <td>Replace the value of the attribute if it already exists</td>
+ * <td>No</td>
+ * <tr>
+ * <tr>
+ * <td>recurse</td>
+ * <td>Process each subdirectory under viewpath</td>
+ * <td>No</td>
+ * <tr>
+ * <tr>
+ * <td>version</td>
+ * <td>Identify a specific version to attach the attribute to</td>
+ * <td>No</td>
+ * <tr>
+ * <tr>
+ * <td>typename</td>
+ * <td>Name of the attribute type</td>
+ * <td>Yes</td>
+ * <tr>
+ * <tr>
+ * <td>typevalue</td>
+ * <td>Value to attach to the attribute type</td>
+ * <td>Yes</td>
+ * <tr>
+ * <tr>
+ * <td>comment</td>
+ * <td>Specify a comment. Only one of comment or cfile may be used.</td>
+ * <td>No</td>
+ * <tr>
+ * <tr>
+ * <td>commentfile</td>
+ * <td>Specify a file containing a comment. Only one of comment or cfile may be used.</td>
+ * <td>No</td>
+ * <tr>
+ * <tr>
+ * <td>failonerr</td>
+ * <td>Throw an exception if the command fails. Default is true</td>
+ * <td>No</td>
+ * <tr>
+ * </table>
+ *
+ */
+public class CCMkattr extends ClearCase {
+ private boolean mReplace = false;
+ private boolean mRecurse = false;
+ private String mVersion = null;
+ private String mTypeName = null;
+ private String mTypeValue = null;
+ private String mComment = null;
+ private String mCfile = null;
+
+ /**
+ * Executes the task.
+ * <p>
+ * Builds a command line to execute cleartool and then calls Exec's run method
+ * to execute the command line.
+ * @throws BuildException if the command fails and failonerr is set to true
+ */
+ public void execute() throws BuildException {
+ Commandline commandLine = new Commandline();
+ Project aProj = getProject();
+ int result = 0;
+
+ // Check for required attributes
+ if (getTypeName() == null) {
+ throw new BuildException("Required attribute TypeName not specified");
+ }
+ if (getTypeValue() == null) {
+ throw new BuildException("Required attribute TypeValue not specified");
+ }
+ // Default the viewpath to basedir if it is not specified
+ if (getViewPath() == null) {
+ setViewPath(aProj.getBaseDir().getPath());
+ }
+
+ // build the command line from what we got. the format is
+ // cleartool mkattr [options...] [viewpath ...]
+ // as specified in the CLEARTOOL help
+ commandLine.setExecutable(getClearToolCommand());
+ commandLine.createArgument().setValue(COMMAND_MKATTR);
+
+ checkOptions(commandLine);
+
+ if (!getFailOnErr()) {
+ getProject().log("Ignoring any errors that occur for: "
+ + getViewPathBasename(), Project.MSG_VERBOSE);
+ }
+
+ // For debugging
+ // System.out.println(commandLine.toString());
+
+ result = run(commandLine);
+ if (Execute.isFailure(result) && getFailOnErr()) {
+ String msg = "Failed executing: " + commandLine.toString();
+ throw new BuildException(msg, getLocation());
+ }
+ }
+
+
+ /**
+ * Check the command line options.
+ */
+ private void checkOptions(Commandline cmd) {
+ if (getReplace()) {
+ // -replace
+ cmd.createArgument().setValue(FLAG_REPLACE);
+ }
+
+ if (getRecurse()) {
+ // -recurse
+ cmd.createArgument().setValue(FLAG_RECURSE);
+ }
+
+ if (getVersion() != null) {
+ // -version
+ getVersionCommand(cmd);
+ }
+
+ if (getComment() != null) {
+ // -c
+ getCommentCommand(cmd);
+ } else {
+ if (getCommentFile() != null) {
+ // -cfile
+ getCommentFileCommand(cmd);
+ } else {
+ cmd.createArgument().setValue(FLAG_NOCOMMENT);
+ }
+ }
+
+ if (getTypeName() != null) {
+ // type
+ getTypeCommand(cmd);
+ }
+ if (getTypeValue() != null) {
+ // type value
+ getTypeValueCommand(cmd);
+ }
+ // viewpath
+ cmd.createArgument().setValue(getViewPath());
+ }
+
+
+ /**
+ * Set the replace flag
+ *
+ * @param replace the status to set the flag to
+ */
+ public void setReplace(boolean replace) {
+ mReplace = replace;
+ }
+
+ /**
+ * Get replace flag status
+ *
+ * @return boolean containing status of replace flag
+ */
+ public boolean getReplace() {
+ return mReplace;
+ }
+
+ /**
+ * Set recurse flag
+ *
+ * @param recurse the status to set the flag to
+ */
+ public void setRecurse(boolean recurse) {
+ mRecurse = recurse;
+ }
+
+ /**
+ * Get recurse flag status
+ *
+ * @return boolean containing status of recurse flag
+ */
+ public boolean getRecurse() {
+ return mRecurse;
+ }
+
+ /**
+ * Set the version flag
+ *
+ * @param version the status to set the flag to
+ */
+ public void setVersion(String version) {
+ mVersion = version;
+ }
+
+ /**
+ * Get version flag status
+ *
+ * @return boolean containing status of version flag
+ */
+ public String getVersion() {
+ return mVersion;
+ }
+
+ /**
+ * Set comment string
+ *
+ * @param comment the comment string
+ */
+ public void setComment(String comment) {
+ mComment = comment;
+ }
+
+ /**
+ * Get comment string
+ *
+ * @return String containing the comment
+ */
+ public String getComment() {
+ return mComment;
+ }
+
+ /**
+ * Set comment file
+ *
+ * @param cfile the path to the comment file
+ */
+ public void setCommentFile(String cfile) {
+ mCfile = cfile;
+ }
+
+ /**
+ * Get comment file
+ *
+ * @return String containing the path to the comment file
+ */
+ public String getCommentFile() {
+ return mCfile;
+ }
+
+ /**
+ * Set the attribute type-name
+ *
+ * @param tn the type name
+ */
+ public void setTypeName(String tn) {
+ mTypeName = tn;
+ }
+
+ /**
+ * Get attribute type-name
+ *
+ * @return String containing type name
+ */
+ public String getTypeName() {
+ return mTypeName;
+ }
+
+ /**
+ * Set the attribute type-value
+ *
+ * @param tv the type value
+ */
+ public void setTypeValue(String tv) {
+ mTypeValue = tv;
+ }
+
+ /**
+ * Get the attribute type-value
+ *
+ * @return String containing type value
+ */
+ public String getTypeValue() {
+ return mTypeValue;
+ }
+
+
+ /**
+ * Get the 'version' command
+ *
+ * @param cmd CommandLine containing the command line string with or
+ * without the version flag and string appended
+ */
+ private void getVersionCommand(Commandline cmd) {
+ if (getVersion() != null) {
+ /* Had to make two separate commands here because if a space is
+ inserted between the flag and the value, it is treated as a
+ Windows filename with a space and it is enclosed in double
+ quotes ("). This breaks clearcase.
+ */
+ cmd.createArgument().setValue(FLAG_VERSION);
+ cmd.createArgument().setValue(getVersion());
+ }
+ }
+
+ /**
+ * Get the 'comment' command
+ *
+ * @param cmd containing the command line string with or
+ * without the comment flag and string appended
+ */
+ private void getCommentCommand(Commandline cmd) {
+ if (getComment() != null) {
+ /* Had to make two separate commands here because if a space is
+ inserted between the flag and the value, it is treated as a
+ Windows filename with a space and it is enclosed in double
+ quotes ("). This breaks clearcase.
+ */
+ cmd.createArgument().setValue(FLAG_COMMENT);
+ cmd.createArgument().setValue(getComment());
+ }
+ }
+
+ /**
+ * Get the 'commentfile' command
+ *
+ * @param cmd containing the command line string with or
+ * without the commentfile flag and file appended
+ */
+ private void getCommentFileCommand(Commandline cmd) {
+ if (getCommentFile() != null) {
+ /* Had to make two separate commands here because if a space is
+ inserted between the flag and the value, it is treated as a
+ Windows filename with a space and it is enclosed in double
+ quotes ("). This breaks clearcase.
+ */
+ cmd.createArgument().setValue(FLAG_COMMENTFILE);
+ cmd.createArgument().setValue(getCommentFile());
+ }
+ }
+
+ /**
+ * Get the attribute type-name
+ *
+ * @param cmd containing the command line string with or
+ * without the type-name
+ */
+ private void getTypeCommand(Commandline cmd) {
+ String typenm = getTypeName();
+
+ if (typenm != null) {
+ cmd.createArgument().setValue(typenm);
+ }
+ }
+
+ /**
+ * Get the attribute type-value
+ *
+ * @param cmd containing the command line string with or
+ * without the type-value
+ */
+ private void getTypeValueCommand(Commandline cmd) {
+ String typevl = getTypeValue();
+
+ if (typevl != null) {
+ if (Os.isFamily("windows")) {
+ typevl = "\\\"" + typevl + "\\\""; // Windows quoting of the value
+ } else {
+ typevl = "\"" + typevl + "\"";
+ }
+ cmd.createArgument().setValue(typevl);
+ }
+ }
+
+ /**
+ * -replace flag -- replace the existing value of the attribute
+ */
+ public static final String FLAG_REPLACE = "-replace";
+ /**
+ * -recurse flag -- process all subdirectories
+ */
+ public static final String FLAG_RECURSE = "-recurse";
+ /**
+ * -version flag -- attach attribute to specified version
+ */
+ public static final String FLAG_VERSION = "-version";
+ /**
+ * -c flag -- comment to attach to the element
+ */
+ public static final String FLAG_COMMENT = "-c";
+ /**
+ * -cfile flag -- file containing a comment to attach to the file
+ */
+ public static final String FLAG_COMMENTFILE = "-cfile";
+ /**
+ * -nc flag -- no comment is specified
+ */
+ public static final String FLAG_NOCOMMENT = "-nc";
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCMkbl.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCMkbl.java
new file mode 100644
index 00000000..82c96005
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCMkbl.java
@@ -0,0 +1,365 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.clearcase;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.Execute;
+import org.apache.tools.ant.types.Commandline;
+
+/**
+ * Task to CreateBaseline command to ClearCase.
+ * <p>
+ * The following attributes are interpreted:
+ * <table border="1">
+ * <tr>
+ * <th>Attribute</th>
+ * <th>Values</th>
+ * <th>Required</th>
+ * </tr>
+ * <tr>
+ * <td>comment</td>
+ * <td>Specify a comment. Only one of comment or cfile may be
+used.</td>
+ * <td>No</td>
+ * </tr>
+ * <tr>
+ * <td>commentfile</td>
+ * <td>Specify a file containing a comment. Only one of comment or
+cfile may be used.</td>
+ * <td>No</td>
+ * </tr>
+ * <tr>
+ * <td>baselinerootname</td>
+ * <td>Specify the name to be associated with the baseline.</td>
+ * <td>Yes</td>
+ * </tr>
+ * <tr>
+ * <td>nowarn</td>
+ * <td>Suppress warning messages</td>
+ * <td>No</td>
+ * <tr>
+ * <tr>
+ * <td>identical</td>
+ * <td>Allows the baseline to be created even if it is identical to the
+previous baseline.</td>
+ * <td>No</td>
+ * </tr>
+ * <tr>
+ * <td>full</td>
+ * <td>Creates a full baseline.</td>
+ * <td>No</td>
+ * </tr>
+ * <tr>
+ * <td>nlabel</td>
+ * <td>Allows the baseline to be created without a label.</td>
+ * <td>No</td>
+ * </tr>
+ * <tr>
+ * <td>failonerr</td>
+ * <td>Throw an exception if the command fails. Default is true</td>
+ * <td>No</td>
+ * <tr>
+ * </table>
+ *
+ */
+public class CCMkbl extends ClearCase {
+ private String mComment = null;
+ private String mCfile = null;
+ private String mBaselineRootName = null;
+ private boolean mNwarn = false;
+ private boolean mIdentical = true;
+ private boolean mFull = false;
+ private boolean mNlabel = false;
+
+
+ /**
+ * Executes the task.
+ * <p>
+ * Builds a command line to execute cleartool and then calls Exec's run method
+ * to execute the command line.
+ * @throws BuildException if the command fails and failonerr is set to true
+ */
+ public void execute() throws BuildException {
+ Commandline commandLine = new Commandline();
+ Project aProj = getProject();
+ int result = 0;
+
+ // Default the viewpath to basedir if it is not specified
+ if (getViewPath() == null) {
+ setViewPath(aProj.getBaseDir().getPath());
+ }
+
+ // build the command line from what we got. the format is
+ // cleartool checkin [options...] [viewpath ...]
+ // as specified in the CLEARTOOL.EXE help
+ commandLine.setExecutable(getClearToolCommand());
+ commandLine.createArgument().setValue(COMMAND_MKBL);
+
+ checkOptions(commandLine);
+
+ if (!getFailOnErr()) {
+ getProject().log("Ignoring any errors that occur for: "
+ + getBaselineRootName(), Project.MSG_VERBOSE);
+ }
+ result = run(commandLine);
+ if (Execute.isFailure(result) && getFailOnErr()) {
+ String msg = "Failed executing: " + commandLine.toString();
+ throw new BuildException(msg, getLocation());
+ }
+ }
+
+
+ /**
+ * Check the command line options.
+ */
+ private void checkOptions(Commandline cmd) {
+ if (getComment() != null) {
+ // -c
+ getCommentCommand(cmd);
+ } else {
+ if (getCommentFile() != null) {
+ // -cfile
+ getCommentFileCommand(cmd);
+ } else {
+ cmd.createArgument().setValue(FLAG_NOCOMMENT);
+ }
+ }
+
+ if (getIdentical()) {
+ // -identical
+ cmd.createArgument().setValue(FLAG_IDENTICAL);
+ }
+
+ if (getFull()) {
+ // -full
+ cmd.createArgument().setValue(FLAG_FULL);
+ } else {
+ // -incremental
+ cmd.createArgument().setValue(FLAG_INCREMENTAL);
+ }
+
+ if (getNlabel()) {
+ // -nlabel
+ cmd.createArgument().setValue(FLAG_NLABEL);
+ }
+
+ // baseline_root_name
+ cmd.createArgument().setValue(getBaselineRootName());
+
+ }
+
+
+ /**
+ * Set comment string
+ *
+ * @param comment the comment string
+ */
+ public void setComment(String comment) {
+ mComment = comment;
+ }
+
+ /**
+ * Get comment string
+ *
+ * @return String containing the comment
+ */
+ public String getComment() {
+ return mComment;
+ }
+
+ /**
+ * Set comment file
+ *
+ * @param cfile the path to the comment file
+ */
+ public void setCommentFile(String cfile) {
+ mCfile = cfile;
+ }
+
+ /**
+ * Get comment file
+ *
+ * @return String containing the path to the comment file
+ */
+ public String getCommentFile() {
+ return mCfile;
+ }
+
+ /**
+ * Set baseline_root_name
+ *
+ * @param baselineRootName the name of the baseline
+ */
+ public void setBaselineRootName(String baselineRootName) {
+ mBaselineRootName = baselineRootName;
+ }
+
+ /**
+ * Get baseline_root_name
+ *
+ * @return String containing the name of the baseline
+ */
+ public String getBaselineRootName() {
+ return mBaselineRootName;
+ }
+
+ /**
+
+ /**
+ * Set the nowarn flag
+ *
+ * @param nwarn the status to set the flag to
+ */
+ public void setNoWarn(boolean nwarn) {
+ mNwarn = nwarn;
+ }
+
+ /**
+ * Get nowarn flag status
+ *
+ * @return boolean containing status of nwarn flag
+ */
+ public boolean getNoWarn() {
+ return mNwarn;
+ }
+
+ /**
+ * Set the identical flag
+ *
+ * @param identical the status to set the flag to
+ */
+ public void setIdentical(boolean identical) {
+ mIdentical = identical;
+ }
+
+ /**
+ * Get identical flag status
+ *
+ * @return boolean containing status of identical flag
+ */
+ public boolean getIdentical() {
+ return mIdentical;
+ }
+
+ /**
+ * Set the full flag
+ *
+ * @param full the status to set the flag to
+ */
+ public void setFull(boolean full) {
+ mFull = full;
+ }
+
+ /**
+ * Get full flag status
+ *
+ * @return boolean containing status of full flag
+ */
+ public boolean getFull() {
+ return mFull;
+ }
+
+ /**
+ * Set the nlabel flag
+ *
+ * @param nlabel the status to set the flag to
+ */
+ public void setNlabel(boolean nlabel) {
+ mNlabel = nlabel;
+ }
+
+ /**
+ * Get nlabel status
+ *
+ * @return boolean containing status of nlabel flag
+ */
+ public boolean getNlabel() {
+ return mNlabel;
+ }
+
+
+ /**
+ * Get the 'comment' command
+ *
+ * @param cmd containing the command line string with or
+ * without the comment flag and string appended
+ */
+ private void getCommentCommand(Commandline cmd) {
+ if (getComment() != null) {
+ /* Had to make two separate commands here because if a space is
+ inserted between the flag and the value, it is treated as a
+ Windows filename with a space and it is enclosed in double
+ quotes ("). This breaks clearcase.
+ */
+ cmd.createArgument().setValue(FLAG_COMMENT);
+ cmd.createArgument().setValue(getComment());
+ }
+ }
+
+ /**
+ * Get the 'commentfile' command
+ *
+ * @param cmd CommandLine containing the command line string with or
+ * without the commentfile flag and file appended
+ */
+ private void getCommentFileCommand(Commandline cmd) {
+ if (getCommentFile() != null) {
+ /* Had to make two separate commands here because if a space is
+ inserted between the flag and the value, it is treated as a
+ Windows filename with a space and it is enclosed in double
+ quotes ("). This breaks clearcase.
+ */
+ cmd.createArgument().setValue(FLAG_COMMENTFILE);
+ cmd.createArgument().setValue(getCommentFile());
+ }
+ }
+
+
+ /**
+ * -c flag -- comment to attach to the file
+ */
+ public static final String FLAG_COMMENT = "-c";
+ /**
+ * -cfile flag -- file containing a comment to attach to the file
+ */
+ public static final String FLAG_COMMENTFILE = "-cfile";
+ /**
+ * -nc flag -- no comment is specified
+ */
+ public static final String FLAG_NOCOMMENT = "-nc";
+ /**
+ * -identical flag -- allows the file to be checked in even if it is identical to the original
+ */
+ public static final String FLAG_IDENTICAL = "-identical";
+ /**
+ * -incremental flag -- baseline to be created is incremental
+ */
+ public static final String FLAG_INCREMENTAL = "-incremental";
+ /**
+ * -full flag -- baseline to be created is full
+ */
+ public static final String FLAG_FULL = "-full";
+ /**
+ * -nlabel -- baseline to be created without a label
+ */
+ public static final String FLAG_NLABEL = "-nlabel";
+
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCMkdir.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCMkdir.java
new file mode 100644
index 00000000..4c89539f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCMkdir.java
@@ -0,0 +1,237 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.clearcase;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.Execute;
+import org.apache.tools.ant.types.Commandline;
+
+/**
+ * Performs ClearCase mkdir.
+ *
+ * <p>
+ * The following attributes are interpreted:
+ * <table border="1">
+ * <tr>
+ * <th>Attribute</th>
+ * <th>Values</th>
+ * <th>Required</th>
+ * </tr>
+ * <tr>
+ * <td>viewpath</td>
+ * <td>Path to the ClearCase view directory that the command will operate on</td>
+ * <td>Yes</td>
+ * <tr>
+ * <tr>
+ * <td>comment</td>
+ * <td>Specify a comment. Only one of comment or cfile may be used.</td>
+ * <td>No</td>
+ * <tr>
+ * <tr>
+ * <td>commentfile</td>
+ * <td>Specify a file containing a comment. Only one of comment or cfile may be used.</td>
+ * <td>No</td>
+ * <tr>
+ * <tr>
+ * <td>nocheckout</td>
+ * <td>Do not checkout after element creation</td>
+ * <td>No</td>
+ * <tr>
+ * <tr>
+ * <td>failonerr</td>
+ * <td>Throw an exception if the command fails. Default is true</td>
+ * <td>No</td>
+ * <tr>
+ * </table>
+ *
+ */
+public class CCMkdir extends ClearCase {
+ private String mComment = null;
+ private String mCfile = null;
+ private boolean mNoco = false;
+
+ /**
+ * Executes the task.
+ * <p>
+ * Builds a command line to execute cleartool and then calls Exec's run method
+ * to execute the command line.
+ * @throws BuildException if the command fails and failonerr is set to true
+ */
+ public void execute() throws BuildException {
+ Commandline commandLine = new Commandline();
+ Project aProj = getProject();
+ int result = 0;
+
+ // Default the viewpath to basedir if it is not specified
+ if (getViewPath() == null) {
+ setViewPath(aProj.getBaseDir().getPath());
+ }
+
+ // build the command line from what we got. the format is
+ // cleartool mkelem [options...] [viewpath ...]
+ // as specified in the CLEARTOOL.EXE help
+ commandLine.setExecutable(getClearToolCommand());
+ commandLine.createArgument().setValue(COMMAND_MKDIR);
+
+ checkOptions(commandLine);
+
+ if (!getFailOnErr()) {
+ getProject().log("Ignoring any errors that occur for: "
+ + getViewPathBasename(), Project.MSG_VERBOSE);
+ }
+ result = run(commandLine);
+ if (Execute.isFailure(result) && getFailOnErr()) {
+ String msg = "Failed executing: " + commandLine.toString();
+ throw new BuildException(msg, getLocation());
+ }
+ }
+
+ /**
+ * Check the command line options.
+ */
+ private void checkOptions(Commandline cmd) {
+ if (getComment() != null) {
+ // -c
+ getCommentCommand(cmd);
+ } else {
+ if (getCommentFile() != null) {
+ // -cfile
+ getCommentFileCommand(cmd);
+ } else {
+ cmd.createArgument().setValue(FLAG_NOCOMMENT);
+ }
+ }
+ if (getNoCheckout()) {
+ // -nco
+ cmd.createArgument().setValue(FLAG_NOCHECKOUT);
+ }
+ // viewpath
+ cmd.createArgument().setValue(getViewPath());
+ }
+
+ /**
+ * Sets the comment string.
+ *
+ * @param comment the comment string
+ */
+ public void setComment(String comment) {
+ mComment = comment;
+ }
+
+ /**
+ * Get comment string
+ *
+ * @return String containing the comment
+ */
+ public String getComment() {
+ return mComment;
+ }
+
+ /**
+ * Specifies a file containing a comment.
+ *
+ * @param cfile the path to the comment file
+ */
+ public void setCommentFile(String cfile) {
+ mCfile = cfile;
+ }
+
+ /**
+ * Get comment file
+ *
+ * @return String containing the path to the comment file
+ */
+ public String getCommentFile() {
+ return mCfile;
+ }
+
+ /**
+ * If true, do not checkout element after creation.
+ *
+ * @param co the status to set the flag to
+ */
+ public void setNoCheckout(boolean co) {
+ mNoco = co;
+ }
+
+ /**
+ * Get no checkout flag status
+ *
+ * @return boolean containing status of noco flag
+ */
+ public boolean getNoCheckout() {
+ return mNoco;
+ }
+
+
+ /**
+ * Get the 'comment' command
+ *
+ * @param cmd containing the command line string with or
+ * without the comment flag and string appended
+ */
+ private void getCommentCommand(Commandline cmd) {
+ if (getComment() != null) {
+ /* Had to make two separate commands here because if a space is
+ inserted between the flag and the value, it is treated as a
+ Windows filename with a space and it is enclosed in double
+ quotes ("). This breaks clearcase.
+ */
+ cmd.createArgument().setValue(FLAG_COMMENT);
+ cmd.createArgument().setValue(getComment());
+ }
+ }
+
+ /**
+ * Get the 'commentfile' command
+ *
+ * @param cmd containing the command line string with or
+ * without the commentfile flag and file appended
+ */
+ private void getCommentFileCommand(Commandline cmd) {
+ if (getCommentFile() != null) {
+ /* Had to make two separate commands here because if a space is
+ inserted between the flag and the value, it is treated as a
+ Windows filename with a space and it is enclosed in double
+ quotes ("). This breaks clearcase.
+ */
+ cmd.createArgument().setValue(FLAG_COMMENTFILE);
+ cmd.createArgument().setValue(getCommentFile());
+ }
+ }
+
+ /**
+ * -c flag -- comment to attach to the directory
+ */
+ public static final String FLAG_COMMENT = "-c";
+ /**
+ * -cfile flag -- file containing a comment to attach to the directory
+ */
+ public static final String FLAG_COMMENTFILE = "-cfile";
+ /**
+ * -nc flag -- no comment is specified
+ */
+ public static final String FLAG_NOCOMMENT = "-nc";
+ /**
+ * -nco flag -- do not checkout element after creation
+ */
+ public static final String FLAG_NOCHECKOUT = "-nco";
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCMkelem.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCMkelem.java
new file mode 100644
index 00000000..94faa5a6
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCMkelem.java
@@ -0,0 +1,424 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.clearcase;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.Execute;
+import org.apache.tools.ant.types.Commandline;
+
+/**
+ * Performs ClearCase mkelem.
+ *
+ * <p>
+ * The following attributes are interpreted:
+ * <table border="1">
+ * <tr>
+ * <th>Attribute</th>
+ * <th>Values</th>
+ * <th>Required</th>
+ * </tr>
+ * <tr>
+ * <td>viewpath</td>
+ * <td>Path to the ClearCase view file or directory that the command will operate on</td>
+ * <td>Yes</td>
+ * <tr>
+ * <tr>
+ * <td>comment</td>
+ * <td>Specify a comment. Only one of comment or cfile may be used.</td>
+ * <td>No</td>
+ * <tr>
+ * <tr>
+ * <td>commentfile</td>
+ * <td>Specify a file containing a comment. Only one of comment or cfile may be used.</td>
+ * <td>No</td>
+ * <tr>
+ * <tr>
+ * <td>nowarn</td>
+ * <td>Suppress warning messages</td>
+ * <td>No</td>
+ * <tr>
+ * <tr>
+ * <td>nocheckout</td>
+ * <td>Do not checkout after element creation</td>
+ * <td>No</td>
+ * <tr>
+ * <tr>
+ * <td>checkin</td>
+ * <td>Checkin element after creation</td>
+ * <td>No</td>
+ * <tr>
+ * <tr>
+ * <td>preservetime</td>
+ * <td>Preserve the modification time (for checkin)</td>
+ * <td>No</td>
+ * <tr>
+ * <tr>
+ * <td>master</td>
+ * <td>Assign mastership of the main branch to the current site</td>
+ * <td>No</td>
+ * <tr>
+ * <tr>
+ * <td>eltype</td>
+ * <td>Element type to use during element creation</td>
+ * <td>No</td>
+ * <tr>
+ * <tr>
+ * <td>failonerr</td>
+ * <td>Throw an exception if the command fails. Default is true</td>
+ * <td>No</td>
+ * <tr>
+ * </table>
+ *
+ */
+public class CCMkelem extends ClearCase {
+ private String mComment = null;
+ private String mCfile = null;
+ private boolean mNwarn = false;
+ private boolean mPtime = false;
+ private boolean mNoco = false;
+ private boolean mCheckin = false;
+ private boolean mMaster = false;
+ private String mEltype = null;
+
+ /**
+ * Executes the task.
+ * <p>
+ * Builds a command line to execute cleartool and then calls Exec's run method
+ * to execute the command line.
+ * @throws BuildException if the command fails and failonerr is set to true
+ */
+ public void execute() throws BuildException {
+ Commandline commandLine = new Commandline();
+ Project aProj = getProject();
+ int result = 0;
+
+ // Default the viewpath to basedir if it is not specified
+ if (getViewPath() == null) {
+ setViewPath(aProj.getBaseDir().getPath());
+ }
+
+ // build the command line from what we got. the format is
+ // cleartool mkelem [options...] [viewpath ...]
+ // as specified in the CLEARTOOL.EXE help
+ commandLine.setExecutable(getClearToolCommand());
+ commandLine.createArgument().setValue(COMMAND_MKELEM);
+
+ checkOptions(commandLine);
+
+ if (!getFailOnErr()) {
+ getProject().log("Ignoring any errors that occur for: "
+ + getViewPathBasename(), Project.MSG_VERBOSE);
+ }
+ result = run(commandLine);
+ if (Execute.isFailure(result) && getFailOnErr()) {
+ String msg = "Failed executing: " + commandLine.toString();
+ throw new BuildException(msg, getLocation());
+ }
+ }
+
+
+ /**
+ * Check the command line options.
+ */
+ private void checkOptions(Commandline cmd) {
+ if (getComment() != null) {
+ // -c
+ getCommentCommand(cmd);
+ } else {
+ if (getCommentFile() != null) {
+ // -cfile
+ getCommentFileCommand(cmd);
+ } else {
+ cmd.createArgument().setValue(FLAG_NOCOMMENT);
+ }
+ }
+
+ if (getNoWarn()) {
+ // -nwarn
+ cmd.createArgument().setValue(FLAG_NOWARN);
+ }
+ /*
+ * Should choose either -ci or -nco.
+ */
+ if (getNoCheckout() && getCheckin()) {
+ throw new BuildException("Should choose either [nocheckout | checkin]");
+ }
+ if (getNoCheckout()) {
+ // -nco
+ cmd.createArgument().setValue(FLAG_NOCHECKOUT);
+ }
+ if (getCheckin()) {
+ // -ci
+ cmd.createArgument().setValue(FLAG_CHECKIN);
+ if (getPreserveTime()) {
+ // -ptime
+ cmd.createArgument().setValue(FLAG_PRESERVETIME);
+ }
+ }
+ if (getMaster()) {
+ // -master
+ cmd.createArgument().setValue(FLAG_MASTER);
+ }
+ if (getEltype() != null) {
+ // -eltype
+ getEltypeCommand(cmd);
+ }
+ // viewpath
+ cmd.createArgument().setValue(getViewPath());
+ }
+
+ /**
+ * Sets the comment string.
+ *
+ * @param comment the comment string
+ */
+ public void setComment(String comment) {
+ mComment = comment;
+ }
+
+ /**
+ * Get comment string
+ *
+ * @return String containing the comment
+ */
+ public String getComment() {
+ return mComment;
+ }
+
+ /**
+ * Specifies a file containing a comment.
+ *
+ * @param cfile the path to the comment file
+ */
+ public void setCommentFile(String cfile) {
+ mCfile = cfile;
+ }
+
+ /**
+ * Get comment file
+ *
+ * @return String containing the path to the comment file
+ */
+ public String getCommentFile() {
+ return mCfile;
+ }
+
+ /**
+ * If true, suppress warning messages.
+ *
+ * @param nwarn the status to set the flag to
+ */
+ public void setNoWarn(boolean nwarn) {
+ mNwarn = nwarn;
+ }
+
+ /**
+ * Get nowarn flag status
+ *
+ * @return boolean containing status of nwarn flag
+ */
+ public boolean getNoWarn() {
+ return mNwarn;
+ }
+
+ /**
+ * If true, preserve the modification time.
+ *
+ * @param ptime the status to set the flag to
+ */
+ public void setPreserveTime(boolean ptime) {
+ mPtime = ptime;
+ }
+
+ /**
+ * Get preservetime flag status
+ *
+ * @return boolean containing status of preservetime flag
+ */
+ public boolean getPreserveTime() {
+ return mPtime;
+ }
+
+ /**
+ * If true, do not checkout element after creation.
+ *
+ * @param co the status to set the flag to
+ */
+ public void setNoCheckout(boolean co) {
+ mNoco = co;
+ }
+
+ /**
+ * Get no checkout flag status
+ *
+ * @return boolean containing status of noco flag
+ */
+ public boolean getNoCheckout() {
+ return mNoco;
+ }
+
+ /**
+ * If true, checkin the element after creation
+ *
+ * @param ci the status to set the flag to
+ */
+ public void setCheckin(boolean ci) {
+ mCheckin = ci;
+ }
+
+ /**
+ * Get ci flag status
+ *
+ * @return boolean containing status of ci flag
+ */
+ public boolean getCheckin() {
+ return mCheckin;
+ }
+
+ /**
+ * If true, changes mastership of the main branch
+ * to the current site
+ *
+ * @param master the status to set the flag to
+ */
+ public void setMaster(boolean master) {
+ mMaster = master;
+ }
+
+ /**
+ * Get master flag status
+ *
+ * @return boolean containing status of master flag
+ */
+ public boolean getMaster() {
+ return mMaster;
+ }
+
+ /**
+ * Specifies the element type to use.
+ *
+ * @param eltype to create element
+ */
+ public void setEltype(String eltype) {
+ mEltype = eltype;
+ }
+
+ /**
+ * Get element type
+ *
+ * @return String containing the element type
+ */
+ public String getEltype() {
+ return mEltype;
+ }
+
+
+ /**
+ * Get the 'comment' command
+ *
+ * @param cmd containing the command line string with or
+ * without the comment flag and string appended
+ */
+ private void getCommentCommand(Commandline cmd) {
+ if (getComment() != null) {
+ /* Had to make two separate commands here because if a space is
+ inserted between the flag and the value, it is treated as a
+ Windows filename with a space and it is enclosed in double
+ quotes ("). This breaks clearcase.
+ */
+ cmd.createArgument().setValue(FLAG_COMMENT);
+ cmd.createArgument().setValue(getComment());
+ }
+ }
+
+ /**
+ * Get the 'commentfile' command
+ *
+ * @param cmd containing the command line string with or
+ * without the commentfile flag and file appended
+ */
+ private void getCommentFileCommand(Commandline cmd) {
+ if (getCommentFile() != null) {
+ /* Had to make two separate commands here because if a space is
+ inserted between the flag and the value, it is treated as a
+ Windows filename with a space and it is enclosed in double
+ quotes ("). This breaks clearcase.
+ */
+ cmd.createArgument().setValue(FLAG_COMMENTFILE);
+ cmd.createArgument().setValue(getCommentFile());
+ }
+ }
+
+ /**
+ * Get the 'element type' command
+ *
+ * @param cmd containing the command line string with or
+ * without the comment flag and string appended
+ */
+ private void getEltypeCommand(Commandline cmd) {
+ if (getEltype() != null) {
+ /* Had to make two separate commands here because if a space is
+ inserted between the flag and the value, it is treated as a
+ Windows filename with a space and it is enclosed in double
+ quotes ("). This breaks clearcase.
+ */
+ cmd.createArgument().setValue(FLAG_ELTYPE);
+ cmd.createArgument().setValue(getEltype());
+ }
+ }
+
+ /**
+ * -c flag -- comment to attach to the file
+ */
+ public static final String FLAG_COMMENT = "-c";
+ /**
+ * -cfile flag -- file containing a comment to attach to the file
+ */
+ public static final String FLAG_COMMENTFILE = "-cfile";
+ /**
+ * -nc flag -- no comment is specified
+ */
+ public static final String FLAG_NOCOMMENT = "-nc";
+ /**
+ * -nwarn flag -- suppresses warning messages
+ */
+ public static final String FLAG_NOWARN = "-nwarn";
+ /**
+ * -ptime flag -- preserves the modification time on checkin
+ */
+ public static final String FLAG_PRESERVETIME = "-ptime";
+ /**
+ * -nco flag -- do not checkout element after creation
+ */
+ public static final String FLAG_NOCHECKOUT = "-nco";
+ /**
+ * -ci flag -- checkin element after creation
+ */
+ public static final String FLAG_CHECKIN = "-ci";
+ /**
+ * -master flag -- change mastership of main branch to current site
+ */
+ public static final String FLAG_MASTER = "-master";
+ /**
+ * -eltype flag -- element type to use during creation
+ */
+ public static final String FLAG_ELTYPE = "-eltype";
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCMklabel.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCMklabel.java
new file mode 100644
index 00000000..e3d288df
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCMklabel.java
@@ -0,0 +1,402 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.clearcase;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.Execute;
+import org.apache.tools.ant.types.Commandline;
+
+/**
+ * Task to perform mklabel command to ClearCase.
+ * <p>
+ * The following attributes are interpreted:
+ * <table border="1">
+ * <tr>
+ * <th>Attribute</th>
+ * <th>Values</th>
+ * <th>Required</th>
+ * </tr>
+ * <tr>
+ * <td>viewpath</td>
+ * <td>Path to the ClearCase view file or directory that the command will operate on</td>
+ * <td>No</td>
+ * <tr>
+ * <tr>
+ * <td>replace</td>
+ * <td>Replace a label of the same type on the same branch</td>
+ * <td>No</td>
+ * <tr>
+ * <tr>
+ * <td>recurse</td>
+ * <td>Process each subdirectory under viewpath</td>
+ * <td>No</td>
+ * <tr>
+ * <tr>
+ * <td>version</td>
+ * <td>Identify a specific version to attach the label to</td>
+ * <td>No</td>
+ * <tr>
+ * <tr>
+ * <td>typename</td>
+ * <td>Name of the label type</td>
+ * <td>Yes</td>
+ * <tr>
+ * <tr>
+ * <td>vob</td>
+ * <td>Name of the VOB</td>
+ * <td>No</td>
+ * <tr>
+ * <tr>
+ * <td>comment</td>
+ * <td>Specify a comment. Only one of comment or cfile may be used.</td>
+ * <td>No</td>
+ * <tr>
+ * <tr>
+ * <td>commentfile</td>
+ * <td>Specify a file containing a comment. Only one of comment or cfile may be used.</td>
+ * <td>No</td>
+ * <tr>
+ * <tr>
+ * <td>failonerr</td>
+ * <td>Throw an exception if the command fails. Default is true</td>
+ * <td>No</td>
+ * <tr>
+ * </table>
+ *
+ */
+public class CCMklabel extends ClearCase {
+ private boolean mReplace = false;
+ private boolean mRecurse = false;
+ private String mVersion = null;
+ private String mTypeName = null;
+ private String mVOB = null;
+ private String mComment = null;
+ private String mCfile = null;
+
+ /**
+ * Executes the task.
+ * <p>
+ * Builds a command line to execute cleartool and then calls Exec's run method
+ * to execute the command line.
+ * @throws BuildException if the command fails and failonerr is set to true
+ */
+ public void execute() throws BuildException {
+ Commandline commandLine = new Commandline();
+ Project aProj = getProject();
+ int result = 0;
+
+ // Check for required attributes
+ if (getTypeName() == null) {
+ throw new BuildException("Required attribute TypeName not specified");
+ }
+
+ // Default the viewpath to basedir if it is not specified
+ if (getViewPath() == null) {
+ setViewPath(aProj.getBaseDir().getPath());
+ }
+
+ // build the command line from what we got. the format is
+ // cleartool mklabel [options...] [viewpath ...]
+ // as specified in the CLEARTOOL help
+ commandLine.setExecutable(getClearToolCommand());
+ commandLine.createArgument().setValue(COMMAND_MKLABEL);
+
+ checkOptions(commandLine);
+
+ if (!getFailOnErr()) {
+ getProject().log("Ignoring any errors that occur for: "
+ + getViewPathBasename(), Project.MSG_VERBOSE);
+ }
+ result = run(commandLine);
+ if (Execute.isFailure(result) && getFailOnErr()) {
+ String msg = "Failed executing: " + commandLine.toString();
+ throw new BuildException(msg, getLocation());
+ }
+ }
+
+
+ /**
+ * Check the command line options.
+ */
+ private void checkOptions(Commandline cmd) {
+ if (getReplace()) {
+ // -replace
+ cmd.createArgument().setValue(FLAG_REPLACE);
+ }
+
+ if (getRecurse()) {
+ // -recurse
+ cmd.createArgument().setValue(FLAG_RECURSE);
+ }
+
+ if (getVersion() != null) {
+ // -version
+ getVersionCommand(cmd);
+ }
+
+ if (getComment() != null) {
+ // -c
+ getCommentCommand(cmd);
+ } else {
+ if (getCommentFile() != null) {
+ // -cfile
+ getCommentFileCommand(cmd);
+ } else {
+ cmd.createArgument().setValue(FLAG_NOCOMMENT);
+ }
+ }
+
+ if (getTypeName() != null) {
+ // type
+ getTypeCommand(cmd);
+ }
+
+ // viewpath
+ cmd.createArgument().setValue(getViewPath());
+ }
+
+
+ /**
+ * Set the replace flag
+ *
+ * @param replace the status to set the flag to
+ */
+ public void setReplace(boolean replace) {
+ mReplace = replace;
+ }
+
+ /**
+ * Get replace flag status
+ *
+ * @return boolean containing status of replace flag
+ */
+ public boolean getReplace() {
+ return mReplace;
+ }
+
+ /**
+ * Set recurse flag
+ *
+ * @param recurse the status to set the flag to
+ */
+ public void setRecurse(boolean recurse) {
+ mRecurse = recurse;
+ }
+
+ /**
+ * Get recurse flag status
+ *
+ * @return boolean containing status of recurse flag
+ */
+ public boolean getRecurse() {
+ return mRecurse;
+ }
+
+ /**
+ * Set the version flag
+ *
+ * @param version the status to set the flag to
+ */
+ public void setVersion(String version) {
+ mVersion = version;
+ }
+
+ /**
+ * Get version flag status
+ *
+ * @return boolean containing status of version flag
+ */
+ public String getVersion() {
+ return mVersion;
+ }
+
+ /**
+ * Set comment string
+ *
+ * @param comment the comment string
+ */
+ public void setComment(String comment) {
+ mComment = comment;
+ }
+
+ /**
+ * Get comment string
+ *
+ * @return String containing the comment
+ */
+ public String getComment() {
+ return mComment;
+ }
+
+ /**
+ * Set comment file
+ *
+ * @param cfile the path to the comment file
+ */
+ public void setCommentFile(String cfile) {
+ mCfile = cfile;
+ }
+
+ /**
+ * Get comment file
+ *
+ * @return String containing the path to the comment file
+ */
+ public String getCommentFile() {
+ return mCfile;
+ }
+
+ /**
+ * Set the type-name
+ *
+ * @param tn the type name
+ */
+ public void setTypeName(String tn) {
+ mTypeName = tn;
+ }
+
+ /**
+ * Get type-name
+ *
+ * @return String containing type name
+ */
+ public String getTypeName() {
+ return mTypeName;
+ }
+
+ /**
+ * Set the VOB name
+ *
+ * @param vob the VOB name
+ */
+ public void setVOB(String vob) {
+ mVOB = vob;
+ }
+
+ /**
+ * Get VOB name
+ *
+ * @return String containing VOB name
+ */
+ public String getVOB() {
+ return mVOB;
+ }
+
+
+ /**
+ * Get the 'version' command
+ *
+ * @param cmd CommandLine containing the command line string with or
+ * without the version flag and string appended
+ */
+ private void getVersionCommand(Commandline cmd) {
+ if (getVersion() != null) {
+ /* Had to make two separate commands here because if a space is
+ inserted between the flag and the value, it is treated as a
+ Windows filename with a space and it is enclosed in double
+ quotes ("). This breaks clearcase.
+ */
+ cmd.createArgument().setValue(FLAG_VERSION);
+ cmd.createArgument().setValue(getVersion());
+ }
+ }
+
+ /**
+ * Get the 'comment' command
+ *
+ * @param cmd containing the command line string with or
+ * without the comment flag and string appended
+ */
+ private void getCommentCommand(Commandline cmd) {
+ if (getComment() != null) {
+ /* Had to make two separate commands here because if a space is
+ inserted between the flag and the value, it is treated as a
+ Windows filename with a space and it is enclosed in double
+ quotes ("). This breaks clearcase.
+ */
+ cmd.createArgument().setValue(FLAG_COMMENT);
+ cmd.createArgument().setValue(getComment());
+ }
+ }
+
+ /**
+ * Get the 'commentfile' command
+ *
+ * @param cmd containing the command line string with or
+ * without the commentfile flag and file appended
+ */
+ private void getCommentFileCommand(Commandline cmd) {
+ if (getCommentFile() != null) {
+ /* Had to make two separate commands here because if a space is
+ inserted between the flag and the value, it is treated as a
+ Windows filename with a space and it is enclosed in double
+ quotes ("). This breaks clearcase.
+ */
+ cmd.createArgument().setValue(FLAG_COMMENTFILE);
+ cmd.createArgument().setValue(getCommentFile());
+ }
+ }
+
+ /**
+ * Get the type-name
+ *
+ * @param cmd containing the command line string with or
+ * without the type-name
+ */
+ private void getTypeCommand(Commandline cmd) {
+ String typenm = null;
+
+ if (getTypeName() != null) {
+ typenm = getTypeName();
+ if (getVOB() != null) {
+ typenm += "@" + getVOB();
+ }
+ cmd.createArgument().setValue(typenm);
+ }
+ }
+
+
+ /**
+ * -replace flag -- replace another label of the same type
+ */
+ public static final String FLAG_REPLACE = "-replace";
+ /**
+ * -recurse flag -- process all subdirectories
+ */
+ public static final String FLAG_RECURSE = "-recurse";
+ /**
+ * -version flag -- attach label to specified version
+ */
+ public static final String FLAG_VERSION = "-version";
+ /**
+ * -c flag -- comment to attach to the file
+ */
+ public static final String FLAG_COMMENT = "-c";
+ /**
+ * -cfile flag -- file containing a comment to attach to the file
+ */
+ public static final String FLAG_COMMENTFILE = "-cfile";
+ /**
+ * -nc flag -- no comment is specified
+ */
+ public static final String FLAG_NOCOMMENT = "-nc";
+
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCMklbtype.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCMklbtype.java
new file mode 100644
index 00000000..7bb7192e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCMklbtype.java
@@ -0,0 +1,440 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.clearcase;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.Execute;
+import org.apache.tools.ant.types.Commandline;
+
+/**
+ * Task to perform mklbtype command to ClearCase.
+ * <p>
+ * The following attributes are interpreted:
+ * <table border="1">
+ * <tr>
+ * <th>Attribute</th>
+ * <th>Values</th>
+ * <th>Required</th>
+ * </tr>
+ * <tr>
+ * <td>typename</td>
+ * <td>Name of the label type to create</td>
+ * <td>Yes</td>
+ * <tr>
+ * <tr>
+ * <td>vob</td>
+ * <td>Name of the VOB</td>
+ * <td>No</td>
+ * <tr>
+ * <tr>
+ * <td>replace</td>
+ * <td>Replace an existing label definition of the same type</td>
+ * <td>No</td>
+ * <tr>
+ * <tr>
+ * <td>global</td>
+ * <td>Either global or ordinary can be specified, not both.
+ * Creates a label type that is global to the VOB or to
+ * VOBs that use this VOB</td>
+ * <td>No</td>
+ * <tr>
+ * <tr>
+ * <td>ordinary</td>
+ * <td>Either global or ordinary can be specified, not both.
+ * Creates a label type that can be used only in the current
+ * VOB. <B>Default</B></td>
+ * <td>No</td>
+ * <tr>
+ * <tr>
+ * <td>pbranch</td>
+ * <td>Allows the label type to be used once per branch in a given
+ * element's version tree</td>
+ * <td>No</td>
+ * <tr>
+ * <tr>
+ * <td>shared</td>
+ * <td>Sets the way mastership is checked by ClearCase. See ClearCase
+ * documentation for details</td>
+ * <td>No</td>
+ * <tr>
+ * <tr>
+ * <td>comment</td>
+ * <td>Specify a comment. Only one of comment or cfile may be used.</td>
+ * <td>No</td>
+ * <tr>
+ * <tr>
+ * <td>commentfile</td>
+ * <td>Specify a file containing a comment. Only one of comment or
+ * cfile may be used.</td>
+ * <td>No</td>
+ * <tr>
+ * <tr>
+ * <td>failonerr</td>
+ * <td>Throw an exception if the command fails. Default is true</td>
+ * <td>No</td>
+ * <tr>
+ * </table>
+ *
+ */
+public class CCMklbtype extends ClearCase {
+ private String mTypeName = null;
+ private String mVOB = null;
+ private String mComment = null;
+ private String mCfile = null;
+ private boolean mReplace = false;
+ private boolean mGlobal = false;
+ private boolean mOrdinary = true;
+ private boolean mPbranch = false;
+ private boolean mShared = false;
+
+ /**
+ * Executes the task.
+ * <p>
+ * Builds a command line to execute cleartool and then calls Exec's run method
+ * to execute the command line.
+ * @throws BuildException if the command fails and failonerr is set to true
+ */
+ public void execute() throws BuildException {
+ Commandline commandLine = new Commandline();
+ int result = 0;
+
+ // Check for required attributes
+ if (getTypeName() == null) {
+ throw new BuildException("Required attribute TypeName not specified");
+ }
+
+ // build the command line from what we got. the format is
+ // cleartool mklbtype [options...] type-selector...
+ // as specified in the CLEARTOOL help
+ commandLine.setExecutable(getClearToolCommand());
+ commandLine.createArgument().setValue(COMMAND_MKLBTYPE);
+
+ checkOptions(commandLine);
+
+ if (!getFailOnErr()) {
+ getProject().log("Ignoring any errors that occur for: "
+ + getTypeSpecifier(), Project.MSG_VERBOSE);
+ }
+ result = run(commandLine);
+ if (Execute.isFailure(result) && getFailOnErr()) {
+ String msg = "Failed executing: " + commandLine.toString();
+ throw new BuildException(msg, getLocation());
+ }
+ }
+
+
+ /**
+ * Check the command line options.
+ */
+ private void checkOptions(Commandline cmd) {
+ if (getReplace()) {
+ // -replace
+ cmd.createArgument().setValue(FLAG_REPLACE);
+ }
+
+ if (getOrdinary()) {
+ // -ordinary
+ cmd.createArgument().setValue(FLAG_ORDINARY);
+ } else {
+ if (getGlobal()) {
+ // -global
+ cmd.createArgument().setValue(FLAG_GLOBAL);
+ }
+ }
+
+ if (getPbranch()) {
+ // -pbranch
+ cmd.createArgument().setValue(FLAG_PBRANCH);
+ }
+
+ if (getShared()) {
+ // -shared
+ cmd.createArgument().setValue(FLAG_SHARED);
+ }
+
+ if (getComment() != null) {
+ // -c
+ getCommentCommand(cmd);
+ } else {
+ if (getCommentFile() != null) {
+ // -cfile
+ getCommentFileCommand(cmd);
+ } else {
+ cmd.createArgument().setValue(FLAG_NOCOMMENT);
+ }
+ }
+
+ // type-name@vob
+ cmd.createArgument().setValue(getTypeSpecifier());
+ }
+
+
+ /**
+ * Set type-name string
+ *
+ * @param tn the type-name string
+ */
+ public void setTypeName(String tn) {
+ mTypeName = tn;
+ }
+
+ /**
+ * Get type-name string
+ *
+ * @return String containing the type-name
+ */
+ public String getTypeName() {
+ return mTypeName;
+ }
+
+ /**
+ * Set the VOB name
+ *
+ * @param vob the VOB name
+ */
+ public void setVOB(String vob) {
+ mVOB = vob;
+ }
+
+ /**
+ * Get VOB name
+ *
+ * @return String containing VOB name
+ */
+ public String getVOB() {
+ return mVOB;
+ }
+
+ /**
+ * Set the replace flag
+ *
+ * @param repl the status to set the flag to
+ */
+ public void setReplace(boolean repl) {
+ mReplace = repl;
+ }
+
+ /**
+ * Get replace flag status
+ *
+ * @return boolean containing status of replace flag
+ */
+ public boolean getReplace() {
+ return mReplace;
+ }
+
+ /**
+ * Set the global flag
+ *
+ * @param glob the status to set the flag to
+ */
+ public void setGlobal(boolean glob) {
+ mGlobal = glob;
+ }
+
+ /**
+ * Get global flag status
+ *
+ * @return boolean containing status of global flag
+ */
+ public boolean getGlobal() {
+ return mGlobal;
+ }
+
+ /**
+ * Set the ordinary flag
+ *
+ * @param ordinary the status to set the flag to
+ */
+ public void setOrdinary(boolean ordinary) {
+ mOrdinary = ordinary;
+ }
+
+ /**
+ * Get ordinary flag status
+ *
+ * @return boolean containing status of ordinary flag
+ */
+ public boolean getOrdinary() {
+ return mOrdinary;
+ }
+
+ /**
+ * Set the pbranch flag
+ *
+ * @param pbranch the status to set the flag to
+ */
+ public void setPbranch(boolean pbranch) {
+ mPbranch = pbranch;
+ }
+
+ /**
+ * Get pbranch flag status
+ *
+ * @return boolean containing status of pbranch flag
+ */
+ public boolean getPbranch() {
+ return mPbranch;
+ }
+
+ /**
+ * Set the shared flag
+ *
+ * @param shared the status to set the flag to
+ */
+ public void setShared(boolean shared) {
+ mShared = shared;
+ }
+
+ /**
+ * Get shared flag status
+ *
+ * @return boolean containing status of shared flag
+ */
+ public boolean getShared() {
+ return mShared;
+ }
+
+ /**
+ * Set comment string
+ *
+ * @param comment the comment string
+ */
+ public void setComment(String comment) {
+ mComment = comment;
+ }
+
+ /**
+ * Get comment string
+ *
+ * @return String containing the comment
+ */
+ public String getComment() {
+ return mComment;
+ }
+
+ /**
+ * Set comment file
+ *
+ * @param cfile the path to the comment file
+ */
+ public void setCommentFile(String cfile) {
+ mCfile = cfile;
+ }
+
+ /**
+ * Get comment file
+ *
+ * @return String containing the path to the comment file
+ */
+ public String getCommentFile() {
+ return mCfile;
+ }
+
+
+ /**
+ * Get the 'comment' command
+ *
+ * @param cmd containing the command line string with or
+ * without the comment flag and string appended
+ */
+ private void getCommentCommand(Commandline cmd) {
+ if (getComment() != null) {
+ /* Had to make two separate commands here because if a space is
+ inserted between the flag and the value, it is treated as a
+ Windows filename with a space and it is enclosed in double
+ quotes ("). This breaks clearcase.
+ */
+ cmd.createArgument().setValue(FLAG_COMMENT);
+ cmd.createArgument().setValue(getComment());
+ }
+ }
+
+ /**
+ * Get the 'commentfile' command
+ *
+ * @param cmd containing the command line string with or
+ * without the commentfile flag and file appended
+ */
+ private void getCommentFileCommand(Commandline cmd) {
+ if (getCommentFile() != null) {
+ /* Had to make two separate commands here because if a space is
+ inserted between the flag and the value, it is treated as a
+ Windows filename with a space and it is enclosed in double
+ quotes ("). This breaks clearcase.
+ */
+ cmd.createArgument().setValue(FLAG_COMMENTFILE);
+ cmd.createArgument().setValue(getCommentFile());
+ }
+ }
+
+ /**
+ * Get the type-name specifier
+ *
+ * @return the 'type-name-specifier' command if the attribute was
+ * specified, otherwise an empty string
+ */
+ private String getTypeSpecifier() {
+ String typenm = null;
+
+ typenm = getTypeName();
+ if (getVOB() != null) {
+ typenm += "@" + getVOB();
+ }
+
+ return typenm;
+ }
+
+
+ /**
+ * -replace flag -- replace existing label definition of the same type
+ */
+ public static final String FLAG_REPLACE = "-replace";
+ /**
+ * -global flag -- creates a label type that is global to the VOB or to VOBs that use this VOB
+ */
+ public static final String FLAG_GLOBAL = "-global";
+ /**
+ * -ordinary flag -- creates a label type that can be used only in the current VOB
+ */
+ public static final String FLAG_ORDINARY = "-ordinary";
+ /**
+ * -pbranch flag -- allows label type to be used once per branch
+ */
+ public static final String FLAG_PBRANCH = "-pbranch";
+ /**
+ * -shared flag -- sets the way mastership is checked by ClearCase
+ */
+ public static final String FLAG_SHARED = "-shared";
+ /**
+ * -c flag -- comment to attach to the file
+ */
+ public static final String FLAG_COMMENT = "-c";
+ /**
+ * -cfile flag -- file containing a comment to attach to the file
+ */
+ public static final String FLAG_COMMENTFILE = "-cfile";
+ /**
+ * -nc flag -- no comment is specified
+ */
+ public static final String FLAG_NOCOMMENT = "-nc";
+
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCRmtype.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCRmtype.java
new file mode 100644
index 00000000..cef0c3a5
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCRmtype.java
@@ -0,0 +1,373 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.clearcase;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.Execute;
+import org.apache.tools.ant.types.Commandline;
+
+/**
+ * Task to perform rmtype command to ClearCase.
+ * <p>
+ * The following attributes are interpreted:
+ * <table border="1">
+ * <tr>
+ * <th>Attribute</th>
+ * <th>Values</th>
+ * <th>Required</th>
+ * </tr>
+ * <tr>
+ * <td>typekind</td>
+ * <td>The kind of type to create. Valid types are:<br>
+ * attype attribute type<br>
+ * brtype branch type<br>
+ * eltype element type<br>
+ * hltype hyperlink type<br>
+ * lbtype label type<br>
+ * trtype trigger type<br>
+ * </td>
+ * <td>Yes</td>
+ * <tr>
+ * <tr>
+ * <td>typename</td>
+ * <td>The name of the type to remove</td>
+ * <td>Yes</td>
+ * <tr>
+ * <tr>
+ * <td>vob</td>
+ * <td>Name of the VOB</td>
+ * <td>No</td>
+ * <tr>
+ * <tr>
+ * <td>ignore</td>
+ * <td>Used with trigger types only. Forces removal of trigger type
+ * even if a pre-operation trigger would prevent its removal</td>
+ * <td>No</td>
+ * <tr>
+ * <tr>
+ * <td>rmall</td>
+ * <td>Removes all instances of a type and the type object itself</td>
+ * <td>No</td>
+ * <tr>
+ * <tr>
+ * <td>comment</td>
+ * <td>Specify a comment. Only one of comment or cfile may be used.</td>
+ * <td>No</td>
+ * <tr>
+ * <tr>
+ * <td>commentfile</td>
+ * <td>Specify a file containing a comment. Only one of comment or cfile
+ * may be used.</td>
+ * <td>No</td>
+ * <tr>
+ * <tr>
+ * <td>failonerr</td>
+ * <td>Throw an exception if the command fails. Default is true</td>
+ * <td>No</td>
+ * <tr>
+ * </table>
+ *
+ */
+public class CCRmtype extends ClearCase {
+ private String mTypeKind = null;
+ private String mTypeName = null;
+ private String mVOB = null;
+ private String mComment = null;
+ private String mCfile = null;
+ private boolean mRmall = false;
+ private boolean mIgnore = false;
+
+ /**
+ * Executes the task.
+ * <p>
+ * Builds a command line to execute cleartool and then calls Exec's run method
+ * to execute the command line.
+ * @throws BuildException if the command fails and failonerr is set to true
+ */
+ public void execute() throws BuildException {
+ Commandline commandLine = new Commandline();
+ int result = 0;
+
+ // Check for required attributes
+ if (getTypeKind() == null) {
+ throw new BuildException("Required attribute TypeKind not specified");
+ }
+ if (getTypeName() == null) {
+ throw new BuildException("Required attribute TypeName not specified");
+ }
+
+ // build the command line from what we got. the format is
+ // cleartool rmtype [options...] type-selector...
+ // as specified in the CLEARTOOL help
+ commandLine.setExecutable(getClearToolCommand());
+ commandLine.createArgument().setValue(COMMAND_RMTYPE);
+
+ checkOptions(commandLine);
+
+ if (!getFailOnErr()) {
+ getProject().log("Ignoring any errors that occur for: "
+ + getTypeSpecifier(), Project.MSG_VERBOSE);
+ }
+ result = run(commandLine);
+ if (Execute.isFailure(result) && getFailOnErr()) {
+ String msg = "Failed executing: " + commandLine.toString();
+ throw new BuildException(msg, getLocation());
+ }
+ }
+
+
+ /**
+ * Check the command line options.
+ */
+ private void checkOptions(Commandline cmd) {
+ if (getIgnore()) {
+ // -ignore
+ cmd.createArgument().setValue(FLAG_IGNORE);
+ }
+ if (getRmAll()) {
+ // -rmall -force
+ cmd.createArgument().setValue(FLAG_RMALL);
+ cmd.createArgument().setValue(FLAG_FORCE);
+ }
+ if (getComment() != null) {
+ // -c
+ getCommentCommand(cmd);
+ } else {
+ if (getCommentFile() != null) {
+ // -cfile
+ getCommentFileCommand(cmd);
+ } else {
+ cmd.createArgument().setValue(FLAG_NOCOMMENT);
+ }
+ }
+
+ // type-kind:type-name
+ cmd.createArgument().setValue(getTypeSpecifier());
+ }
+
+ /**
+ * Set the ignore flag
+ *
+ * @param ignore the status to set the flag to
+ */
+ public void setIgnore(boolean ignore) {
+ mIgnore = ignore;
+ }
+
+ /**
+ * Get ignore flag status
+ *
+ * @return boolean containing status of ignore flag
+ */
+ public boolean getIgnore() {
+ return mIgnore;
+ }
+
+ /**
+ * Set rmall flag
+ *
+ * @param rmall the status to set the flag to
+ */
+ public void setRmAll(boolean rmall) {
+ mRmall = rmall;
+ }
+
+ /**
+ * Get rmall flag status
+ *
+ * @return boolean containing status of rmall flag
+ */
+ public boolean getRmAll() {
+ return mRmall;
+ }
+
+ /**
+ * Set comment string
+ *
+ * @param comment the comment string
+ */
+ public void setComment(String comment) {
+ mComment = comment;
+ }
+
+ /**
+ * Get comment string
+ *
+ * @return String containing the comment
+ */
+ public String getComment() {
+ return mComment;
+ }
+
+ /**
+ * Set comment file
+ *
+ * @param cfile the path to the comment file
+ */
+ public void setCommentFile(String cfile) {
+ mCfile = cfile;
+ }
+
+ /**
+ * Get comment file
+ *
+ * @return String containing the path to the comment file
+ */
+ public String getCommentFile() {
+ return mCfile;
+ }
+
+ /**
+ * Set type-kind string
+ *
+ * @param tk the type-kind string
+ */
+ public void setTypeKind(String tk) {
+ mTypeKind = tk;
+ }
+
+ /**
+ * Get type-kind string
+ *
+ * @return String containing the type-kind
+ */
+ public String getTypeKind() {
+ return mTypeKind;
+ }
+
+ /**
+ * Set type-name string
+ *
+ * @param tn the type-name string
+ */
+ public void setTypeName(String tn) {
+ mTypeName = tn;
+ }
+
+ /**
+ * Get type-name string
+ *
+ * @return String containing the type-name
+ */
+ public String getTypeName() {
+ return mTypeName;
+ }
+
+ /**
+ * Set the VOB name
+ *
+ * @param vob the VOB name
+ */
+ public void setVOB(String vob) {
+ mVOB = vob;
+ }
+
+ /**
+ * Get VOB name
+ *
+ * @return String containing VOB name
+ */
+ public String getVOB() {
+ return mVOB;
+ }
+
+ /**
+ * Get the 'type-specifier' string
+ *
+ * @return the 'type-kind:type-name@vob' specifier
+ *
+ */
+ private String getTypeSpecifier() {
+ String tkind = getTypeKind();
+ String tname = getTypeName();
+ String typeSpec = null;
+
+ // Return the type-selector
+ typeSpec = tkind + ":" + tname;
+ if (getVOB() != null) {
+ typeSpec += "@" + getVOB();
+ }
+ return typeSpec;
+ }
+
+ /**
+ * Get the 'comment' command
+ *
+ * @param cmd containing the command line string with or
+ * without the comment flag and string appended
+ */
+ private void getCommentCommand(Commandline cmd) {
+ if (getComment() != null) {
+ /* Had to make two separate commands here because if a space is
+ inserted between the flag and the value, it is treated as a
+ Windows filename with a space and it is enclosed in double
+ quotes ("). This breaks clearcase.
+ */
+ cmd.createArgument().setValue(FLAG_COMMENT);
+ cmd.createArgument().setValue(getComment());
+ }
+ }
+
+ /**
+ * Get the 'commentfile' command
+ *
+ * @param cmd containing the command line string with or
+ * without the commentfile flag and file appended
+ */
+ private void getCommentFileCommand(Commandline cmd) {
+ if (getCommentFile() != null) {
+ /* Had to make two separate commands here because if a space is
+ inserted between the flag and the value, it is treated as a
+ Windows filename with a space and it is enclosed in double
+ quotes ("). This breaks clearcase.
+ */
+ cmd.createArgument().setValue(FLAG_COMMENTFILE);
+ cmd.createArgument().setValue(getCommentFile());
+ }
+ }
+
+
+ /**
+ * -ignore flag -- ignore pre-trigger operations when removing a trigger type
+ */
+ public static final String FLAG_IGNORE = "-ignore";
+ /**
+ * -rmall flag -- removes all instances of a type and the type object itself
+ */
+ public static final String FLAG_RMALL = "-rmall";
+ /**
+ * -force flag -- suppresses confirmation prompts
+ */
+ public static final String FLAG_FORCE = "-force";
+ /**
+ * -c flag -- comment to attach to the file
+ */
+ public static final String FLAG_COMMENT = "-c";
+ /**
+ * -cfile flag -- file containing a comment to attach to the file
+ */
+ public static final String FLAG_COMMENTFILE = "-cfile";
+ /**
+ * -nc flag -- no comment is specified
+ */
+ public static final String FLAG_NOCOMMENT = "-nc";
+
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCUnCheckout.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCUnCheckout.java
new file mode 100644
index 00000000..3c00e1af
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCUnCheckout.java
@@ -0,0 +1,141 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.clearcase;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.Execute;
+import org.apache.tools.ant.types.Commandline;
+
+/**
+ * Performs ClearCase UnCheckout command.
+ *
+ * <p>
+ * The following attributes are interpreted:
+ * <table border="1">
+ * <tr>
+ * <th>Attribute</th>
+ * <th>Values</th>
+ * <th>Required</th>
+ * </tr>
+ * <tr>
+ * <td>viewpath</td>
+ * <td>Path to the ClearCase view file or directory that the command will operate on</td>
+ * <td>No</td>
+ * <tr>
+ * <tr>
+ * <td>keepcopy</td>
+ * <td>Specifies whether to keep a copy of the file with a .keep extension or not</td>
+ * <td>No</td>
+ * <tr>
+ * <tr>
+ * <td>failonerr</td>
+ * <td>Throw an exception if the command fails. Default is true</td>
+ * <td>No</td>
+ * <tr>
+ * </table>
+ *
+ */
+public class CCUnCheckout extends ClearCase {
+ private boolean mKeep = false;
+
+ /**
+ * Executes the task.
+ * <p>
+ * Builds a command line to execute cleartool and then calls Exec's run method
+ * to execute the command line.
+ * @throws BuildException if the command fails and failonerr is set to true
+ */
+ public void execute() throws BuildException {
+ Commandline commandLine = new Commandline();
+ Project aProj = getProject();
+ int result = 0;
+
+ // Default the viewpath to basedir if it is not specified
+ if (getViewPath() == null) {
+ setViewPath(aProj.getBaseDir().getPath());
+ }
+
+ // build the command line from what we got the format is
+ // cleartool uncheckout [options...] [viewpath ...]
+ // as specified in the CLEARTOOL.EXE help
+ commandLine.setExecutable(getClearToolCommand());
+ commandLine.createArgument().setValue(COMMAND_UNCHECKOUT);
+
+ checkOptions(commandLine);
+
+ if (!getFailOnErr()) {
+ getProject().log("Ignoring any errors that occur for: "
+ + getViewPathBasename(), Project.MSG_VERBOSE);
+ }
+ result = run(commandLine);
+ if (Execute.isFailure(result) && getFailOnErr()) {
+ String msg = "Failed executing: " + commandLine.toString();
+ throw new BuildException(msg, getLocation());
+ }
+ }
+
+
+ /**
+ * Check the command line options.
+ */
+ private void checkOptions(Commandline cmd) {
+ // ClearCase items
+ if (getKeepCopy()) {
+ // -keep
+ cmd.createArgument().setValue(FLAG_KEEPCOPY);
+ } else {
+ // -rm
+ cmd.createArgument().setValue(FLAG_RM);
+ }
+
+ // viewpath
+ cmd.createArgument().setValue(getViewPath());
+ }
+
+ /**
+ * If true, keep a copy of the file with a .keep extension.
+ *
+ * @param keep the status to set the flag to
+ */
+ public void setKeepCopy(boolean keep) {
+ mKeep = keep;
+ }
+
+ /**
+ * Get keepcopy flag status
+ *
+ * @return boolean containing status of keep flag
+ */
+ public boolean getKeepCopy() {
+ return mKeep;
+ }
+
+
+ /**
+ * -keep flag -- keep a copy of the file with .keep extension
+ */
+ public static final String FLAG_KEEPCOPY = "-keep";
+ /**
+ * -rm flag -- remove the copy of the file
+ */
+ public static final String FLAG_RM = "-rm";
+
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCUnlock.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCUnlock.java
new file mode 100644
index 00000000..4ca3e890
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCUnlock.java
@@ -0,0 +1,260 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.clearcase;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.Execute;
+import org.apache.tools.ant.types.Commandline;
+
+/**
+ * TODO:
+ * comment field doesn't include all options yet
+ */
+
+/**
+ * Performs a ClearCase Unlock command.
+ *
+ * <p>
+ * The following attributes are interpreted:
+ * <table border="1">
+ * <tr>
+ * <th>Attribute</th>
+ * <th>Values</th>
+ * <th>Required</th>
+ * </tr>
+ * <tr>
+ * <td>comment</td>
+ * <td>Specifies how to populate comments fields</td>
+ * <td>No</td>
+ * <tr>
+ * <tr>
+ * <td>pname</td>
+ * <td>Specifies the object pathname to be unlocked.</td>
+ * <td>No</td>
+ * <tr>
+ * <td>objselect</td>
+ * <td>This variable is obsolete. Should use <i>objsel</i> instead.</td>
+ * <td>no</td>
+ * <tr>
+ * <tr>
+ * <td>objsel</td>
+ * <td>Specifies the object(s) to be unlocked.</td>
+ * <td>No</td>
+ * <tr>
+ * <tr>
+ * <td>failonerr</td>
+ * <td>Throw an exception if the command fails. Default is true</td>
+ * <td>No</td>
+ * <tr>
+ *
+ * </table>
+ *
+ */
+public class CCUnlock extends ClearCase {
+ private String mComment = null;
+ private String mPname = null;
+
+ /**
+ * Executes the task.
+ * <p>
+ * Builds a command line to execute cleartool and then calls Exec's run method
+ * to execute the command line.
+ * @throws BuildException if the command fails and failonerr is set to true
+ */
+ public void execute() throws BuildException {
+ Commandline commandLine = new Commandline();
+ Project aProj = getProject();
+ int result = 0;
+
+ // Default the viewpath to basedir if it is not specified
+ if (getViewPath() == null) {
+ setViewPath(aProj.getBaseDir().getPath());
+ }
+
+ // build the command line from what we got the format is
+ // cleartool lock [options...]
+ // as specified in the CLEARTOOL.EXE help
+ commandLine.setExecutable(getClearToolCommand());
+ commandLine.createArgument().setValue(COMMAND_UNLOCK);
+
+ // Check the command line options
+ checkOptions(commandLine);
+
+ // For debugging
+ // System.out.println(commandLine.toString());
+
+ if (!getFailOnErr()) {
+ getProject().log("Ignoring any errors that occur for: "
+ + getOpType(), Project.MSG_VERBOSE);
+ }
+ result = run(commandLine);
+ if (Execute.isFailure(result) && getFailOnErr()) {
+ String msg = "Failed executing: " + commandLine.toString();
+ throw new BuildException(msg, getLocation());
+ }
+ }
+
+ /**
+ * Check the command line options.
+ */
+ private void checkOptions(Commandline cmd) {
+ // ClearCase items
+ getCommentCommand(cmd);
+
+ if (getObjSelect() == null && getPname() == null) {
+ throw new BuildException("Should select either an element "
+ + "(pname) or an object (objselect)");
+ }
+ getPnameCommand(cmd);
+ // object selector
+ if (getObjSelect() != null) {
+ cmd.createArgument().setValue(getObjSelect());
+ }
+ }
+
+ /**
+ * Sets how comments should be written
+ * for the event record(s)
+ *
+ * @param comment comment method to use
+ */
+ public void setComment(String comment) {
+ mComment = comment;
+ }
+
+ /**
+ * Get comment method
+ *
+ * @return String containing the desired comment method
+ */
+ public String getComment() {
+ return mComment;
+ }
+
+ /**
+ * Sets the pathname to be locked
+ *
+ * @param pname pathname to be locked
+ */
+ public void setPname(String pname) {
+ mPname = pname;
+ }
+
+ /**
+ * Get the pathname to be locked
+ *
+ * @return String containing the pathname to be locked
+ */
+ public String getPname() {
+ return mPname;
+ }
+
+ /**
+ * Sets the object(s) to be locked
+ *
+ * @param objselect objects to be locked
+ */
+ public void setObjselect(String objselect) {
+ setObjSelect(objselect);
+ }
+
+ /**
+ * Sets the object(s) to be locked
+ *
+ * @param objsel objects to be locked
+ * @since ant 1.6.1
+ */
+ public void setObjSel(String objsel) {
+ setObjSelect(objsel);
+ }
+
+ /**
+ * Get list of objects to be locked
+ *
+ * @return String containing the objects to be locked
+ */
+ public String getObjselect() {
+ return getObjSelect();
+ }
+
+ /**
+ * Get the 'comment' command
+ *
+ * @param cmd containing the command line string with or without the
+ * comment flag and value appended
+ */
+ private void getCommentCommand(Commandline cmd) {
+ if (getComment() == null) {
+ return;
+ } else {
+ /* Had to make two separate commands here because if a space is
+ inserted between the flag and the value, it is treated as a
+ Windows filename with a space and it is enclosed in double
+ quotes ("). This breaks clearcase.
+ */
+ cmd.createArgument().setValue(FLAG_COMMENT);
+ cmd.createArgument().setValue(getComment());
+ }
+ }
+
+ /**
+ * Get the 'pname' command
+ *
+ * @param cmd containing the command line string with or without the
+ * pname flag and value appended
+ */
+ private void getPnameCommand(Commandline cmd) {
+ if (getPname() == null) {
+ return;
+ } else {
+ /* Had to make two separate commands here because if a space is
+ inserted between the flag and the value, it is treated as a
+ Windows filename with a space and it is enclosed in double
+ quotes ("). This breaks clearcase.
+ */
+ cmd.createArgument().setValue(FLAG_PNAME);
+ cmd.createArgument().setValue(getPname());
+ }
+ }
+
+ /**
+ * Return which object/pname is being operated on
+ *
+ * @return String containing the object/pname being worked on
+ */
+ private String getOpType() {
+
+ if (getPname() != null) {
+ return getPname();
+ } else {
+ return getObjSelect();
+ }
+ }
+
+ /**
+ * -comment flag -- method to use for commenting events
+ */
+ public static final String FLAG_COMMENT = "-comment";
+ /**
+ * -pname flag -- pathname to lock
+ */
+ public static final String FLAG_PNAME = "-pname";
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCUpdate.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCUpdate.java
new file mode 100644
index 00000000..712efdca
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/CCUpdate.java
@@ -0,0 +1,331 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.clearcase;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.Execute;
+import org.apache.tools.ant.types.Commandline;
+
+/**
+ * Performs a ClearCase Update command.
+ *
+ * <p>
+ * The following attributes are interpreted:
+ * <table border="1">
+ * <tr>
+ * <th>Attribute</th>
+ * <th>Values</th>
+ * <th>Required</th>
+ * </tr>
+ * <tr>
+ * <td>viewpath</td>
+ * <td>Path to the ClearCase view file or directory that the command will operate on</td>
+ * <td>No</td>
+ * <tr>
+ * <tr>
+ * <td>graphical</td>
+ * <td>Displays a graphical dialog during the update</td>
+ * <td>No</td>
+ * <tr>
+ * <tr>
+ * <td>log</td>
+ * <td>Specifies a log file for ClearCase to write to</td>
+ * <td>No</td>
+ * <tr>
+ * <tr>
+ * <td>overwrite</td>
+ * <td>Specifies whether to overwrite hijacked files or not</td>
+ * <td>No</td>
+ * <tr>
+ * <tr>
+ * <td>rename</td>
+ * <td>Specifies that hijacked files should be renamed with a .keep extension</td>
+ * <td>No</td>
+ * <tr>
+ * <tr>
+ * <td>currenttime</td>
+ * <td>Specifies that modification time should be written as the current
+ * time. Either currenttime or preservetime can be specified.</td>
+ * <td>No</td>
+ * <tr>
+ * <tr>
+ * <td>preservetime</td>
+ * <td>Specifies that modification time should preserved from the VOB
+ * time. Either currenttime or preservetime can be specified.</td>
+ * <td>No</td>
+ * <tr>
+ * <tr>
+ * <td>failonerr</td>
+ * <td>Throw an exception if the command fails. Default is true</td>
+ * <td>No</td>
+ * <tr>
+ * </table>
+ *
+ */
+public class CCUpdate extends ClearCase {
+ private boolean mGraphical = false;
+ private boolean mOverwrite = false;
+ private boolean mRename = false;
+ private boolean mCtime = false;
+ private boolean mPtime = false;
+ private String mLog = null;
+
+ /**
+ * Executes the task.
+ * <p>
+ * Builds a command line to execute cleartool and then calls Exec's run method
+ * to execute the command line.
+ * @throws BuildException if the command fails and failonerr is set to true
+ */
+ public void execute() throws BuildException {
+ Commandline commandLine = new Commandline();
+ Project aProj = getProject();
+ int result = 0;
+
+ // Default the viewpath to basedir if it is not specified
+ if (getViewPath() == null) {
+ setViewPath(aProj.getBaseDir().getPath());
+ }
+
+ // build the command line from what we got the format is
+ // cleartool update [options...] [viewpath ...]
+ // as specified in the CLEARTOOL.EXE help
+ commandLine.setExecutable(getClearToolCommand());
+ commandLine.createArgument().setValue(COMMAND_UPDATE);
+
+ // Check the command line options
+ checkOptions(commandLine);
+
+ // For debugging
+ getProject().log(commandLine.toString(), Project.MSG_DEBUG);
+
+ if (!getFailOnErr()) {
+ getProject().log("Ignoring any errors that occur for: "
+ + getViewPathBasename(), Project.MSG_VERBOSE);
+ }
+ result = run(commandLine);
+ if (Execute.isFailure(result) && getFailOnErr()) {
+ String msg = "Failed executing: " + commandLine.toString();
+ throw new BuildException(msg, getLocation());
+ }
+ }
+
+ /**
+ * Check the command line options.
+ */
+ private void checkOptions(Commandline cmd) {
+ // ClearCase items
+ if (getGraphical()) {
+ // -graphical
+ cmd.createArgument().setValue(FLAG_GRAPHICAL);
+ } else {
+ if (getOverwrite()) {
+ // -overwrite
+ cmd.createArgument().setValue(FLAG_OVERWRITE);
+ } else {
+ if (getRename()) {
+ // -rename
+ cmd.createArgument().setValue(FLAG_RENAME);
+ } else {
+ // -noverwrite
+ cmd.createArgument().setValue(FLAG_NOVERWRITE);
+ }
+ }
+
+ if (getCurrentTime()) {
+ // -ctime
+ cmd.createArgument().setValue(FLAG_CURRENTTIME);
+ } else {
+ if (getPreserveTime()) {
+ // -ptime
+ cmd.createArgument().setValue(FLAG_PRESERVETIME);
+ }
+ }
+
+ // -log logname
+ getLogCommand(cmd);
+ }
+
+ // viewpath
+ cmd.createArgument().setValue(getViewPath());
+ }
+
+ /**
+ * If true, displays a graphical dialog during the update.
+ *
+ * @param graphical the status to set the flag to
+ */
+ public void setGraphical(boolean graphical) {
+ mGraphical = graphical;
+ }
+
+ /**
+ * Get graphical flag status
+ *
+ * @return boolean containing status of graphical flag
+ */
+ public boolean getGraphical() {
+ return mGraphical;
+ }
+
+ /**
+ * If true, overwrite hijacked files.
+ *
+ * @param ow the status to set the flag to
+ */
+ public void setOverwrite(boolean ow) {
+ mOverwrite = ow;
+ }
+
+ /**
+ * Get overwrite hijacked files status
+ *
+ * @return boolean containing status of overwrite flag
+ */
+ public boolean getOverwrite() {
+ return mOverwrite;
+ }
+
+ /**
+ * If true, hijacked files are renamed with a .keep extension.
+ *
+ * @param ren the status to set the flag to
+ */
+ public void setRename(boolean ren) {
+ mRename = ren;
+ }
+
+ /**
+ * Get rename hijacked files status
+ *
+ * @return boolean containing status of rename flag
+ */
+ public boolean getRename() {
+ return mRename;
+ }
+
+ /**
+ * If true, modification time should be written as the current time.
+ * Either currenttime or preservetime can be specified.
+ *
+ * @param ct the status to set the flag to
+ */
+ public void setCurrentTime(boolean ct) {
+ mCtime = ct;
+ }
+
+ /**
+ * Get current time status
+ *
+ * @return boolean containing status of current time flag
+ */
+ public boolean getCurrentTime() {
+ return mCtime;
+ }
+
+ /**
+ * If true, modification time should be preserved from the VOB time.
+ * Either currenttime or preservetime can be specified.
+ *
+ * @param pt the status to set the flag to
+ */
+ public void setPreserveTime(boolean pt) {
+ mPtime = pt;
+ }
+
+ /**
+ * Get preserve time status
+ *
+ * @return boolean containing status of preserve time flag
+ */
+ public boolean getPreserveTime() {
+ return mPtime;
+ }
+
+ /**
+ * Sets the log file where cleartool records
+ * the status of the command.
+ *
+ * @param log the path to the log file
+ */
+ public void setLog(String log) {
+ mLog = log;
+ }
+
+ /**
+ * Get log file
+ *
+ * @return String containing the path to the log file
+ */
+ public String getLog() {
+ return mLog;
+ }
+
+
+ /**
+ * Get the 'log' command
+ *
+ * @param cmd containing the command line string with or without the log flag and path appended
+ */
+ private void getLogCommand(Commandline cmd) {
+ if (getLog() == null) {
+ return;
+ } else {
+ /* Had to make two separate commands here because if a space is
+ inserted between the flag and the value, it is treated as a
+ Windows filename with a space and it is enclosed in double
+ quotes ("). This breaks clearcase.
+ */
+ cmd.createArgument().setValue(FLAG_LOG);
+ cmd.createArgument().setValue(getLog());
+ }
+ }
+
+ /**
+ * -graphical flag -- display graphical dialog during update operation
+ */
+ public static final String FLAG_GRAPHICAL = "-graphical";
+ /**
+ * -log flag -- file to log status to
+ */
+ public static final String FLAG_LOG = "-log";
+ /**
+ * -overwrite flag -- overwrite hijacked files
+ */
+ public static final String FLAG_OVERWRITE = "-overwrite";
+ /**
+ * -noverwrite flag -- do not overwrite hijacked files
+ */
+ public static final String FLAG_NOVERWRITE = "-noverwrite";
+ /**
+ * -rename flag -- rename hijacked files with .keep extension
+ */
+ public static final String FLAG_RENAME = "-rename";
+ /**
+ * -ctime flag -- modified time is written as the current time
+ */
+ public static final String FLAG_CURRENTTIME = "-ctime";
+ /**
+ * -ptime flag -- modified time is written as the VOB time
+ */
+ public static final String FLAG_PRESERVETIME = "-ptime";
+
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/ClearCase.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/ClearCase.java
new file mode 100644
index 00000000..d81e505c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/clearcase/ClearCase.java
@@ -0,0 +1,242 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.clearcase;
+
+import java.io.File;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.taskdefs.ExecTask;
+import org.apache.tools.ant.taskdefs.Execute;
+import org.apache.tools.ant.taskdefs.LogStreamHandler;
+import org.apache.tools.ant.types.Commandline;
+import org.apache.tools.ant.util.FileUtils;
+
+
+
+/**
+ * A base class for creating tasks for executing commands on ClearCase.
+ * <p>
+ * The class extends the 'exec' task as it operates by executing the cleartool program
+ * supplied with ClearCase. By default the task expects the cleartool executable to be
+ * in the path, * you can override this be specifying the cleartooldir attribute.
+ * </p>
+ * <p>
+ * This class provides set and get methods for the 'viewpath' and 'objselect'
+ * attribute. It also contains constants for the flags that can be passed to
+ * cleartool.
+ * </p>
+ *
+ */
+public abstract class ClearCase extends Task {
+ private String mClearToolDir = "";
+ private String mviewPath = null;
+ private String mobjSelect = null;
+ private static int pcnt = 0;
+ private boolean mFailonerr = true;
+ /**
+ * Set the directory where the cleartool executable is located.
+ *
+ * @param dir the directory containing the cleartool executable
+ */
+ public final void setClearToolDir(String dir) {
+ mClearToolDir = FileUtils.translatePath(dir);
+ }
+
+ /**
+ * Builds and returns the command string to execute cleartool
+ *
+ * @return String containing path to the executable
+ */
+ protected final String getClearToolCommand() {
+ String toReturn = mClearToolDir;
+ if (!toReturn.equals("") && !toReturn.endsWith("/")) {
+ toReturn += "/";
+ }
+
+ toReturn += CLEARTOOL_EXE;
+
+ return toReturn;
+ }
+
+ /**
+ * Set the path to the item in a ClearCase view to operate on.
+ *
+ * @param viewPath Path to the view directory or file
+ */
+ public final void setViewPath(String viewPath) {
+ mviewPath = viewPath;
+ }
+
+ /**
+ * Get the path to the item in a clearcase view
+ *
+ * @return mviewPath
+ */
+ public String getViewPath() {
+ return mviewPath;
+ }
+
+ /**
+ * Get the basename path of the item in a clearcase view
+ *
+ * @return basename
+ */
+ public String getViewPathBasename() {
+ return (new File(mviewPath)).getName();
+ }
+
+ /**
+ * Set the object to operate on.
+ *
+ * @param objSelect object to operate on
+ */
+ public final void setObjSelect(String objSelect) {
+ mobjSelect = objSelect;
+ }
+
+ /**
+ * Get the object to operate on
+ *
+ * @return mobjSelect
+ */
+ public String getObjSelect() {
+ return mobjSelect;
+ }
+
+ /**
+ * Execute the given command are return success or failure
+ * @param cmd command line to execute
+ * @return the exit status of the subprocess or <code>INVALID</code>
+ */
+ protected int run(Commandline cmd) {
+ try {
+ Project aProj = getProject();
+ Execute exe
+ = new Execute(new LogStreamHandler(this, Project.MSG_INFO, Project.MSG_WARN));
+ exe.setAntRun(aProj);
+ exe.setWorkingDirectory(aProj.getBaseDir());
+ exe.setCommandline(cmd.getCommandline());
+ return exe.execute();
+ } catch (java.io.IOException e) {
+ throw new BuildException(e, getLocation());
+ }
+ }
+
+ /**
+ * Execute the given command, and return it's output
+ * @param cmdline command line to execute
+ * @return output of the command line
+ */
+ protected String runS(Commandline cmdline) {
+ String outV = "opts.cc.runS.output" + pcnt++;
+ ExecTask exe = new ExecTask(this);
+ Commandline.Argument arg = exe.createArg();
+
+ exe.setExecutable(cmdline.getExecutable());
+ arg.setLine(Commandline.toString(cmdline.getArguments()));
+ exe.setOutputproperty(outV);
+ exe.execute();
+
+ return getProject().getProperty(outV);
+ }
+ /**
+ * If true, command will throw an exception on failure.
+ *
+ * @param failonerr the status to set the flag to
+ * @since ant 1.6.1
+ */
+ public void setFailOnErr(boolean failonerr) {
+ mFailonerr = failonerr;
+ }
+
+ /**
+ * Get failonerr flag status
+ *
+ * @return boolean containing status of failonerr flag
+ * @since ant 1.6.1
+ */
+ public boolean getFailOnErr() {
+ return mFailonerr;
+ }
+
+ /**
+ * Constant for the thing to execute
+ */
+ private static final String CLEARTOOL_EXE = "cleartool";
+ /**
+ * The 'Update' command
+ */
+ public static final String COMMAND_UPDATE = "update";
+ /**
+ * The 'Checkout' command
+ */
+ public static final String COMMAND_CHECKOUT = "checkout";
+ /**
+ * The 'Checkin' command
+ */
+ public static final String COMMAND_CHECKIN = "checkin";
+ /**
+ * The 'UndoCheckout' command
+ */
+ public static final String COMMAND_UNCHECKOUT = "uncheckout";
+ /**
+ * The 'Lock' command
+ */
+ public static final String COMMAND_LOCK = "lock";
+ /**
+ * The 'Unlock' command
+ */
+ public static final String COMMAND_UNLOCK = "unlock";
+ /**
+ * The 'Mkbl' command
+ */
+ public static final String COMMAND_MKBL = "mkbl";
+ /**
+ * The 'Mklabel' command
+ */
+ public static final String COMMAND_MKLABEL = "mklabel";
+ /**
+ * The 'Mklbtype' command
+ */
+ public static final String COMMAND_MKLBTYPE = "mklbtype";
+ /**
+ * The 'Rmtype' command
+ */
+ public static final String COMMAND_RMTYPE = "rmtype";
+ /**
+ * The 'LsCheckout' command
+ */
+ public static final String COMMAND_LSCO = "lsco";
+ /**
+ * The 'Mkelem' command
+ */
+ public static final String COMMAND_MKELEM = "mkelem";
+ /**
+ * The 'Mkattr' command
+ */
+ public static final String COMMAND_MKATTR = "mkattr";
+ /**
+ * The 'Mkdir' command
+ */
+ public static final String COMMAND_MKDIR = "mkdir";
+
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/AntAnalyzer.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/AntAnalyzer.java
new file mode 100644
index 00000000..341f6707
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/AntAnalyzer.java
@@ -0,0 +1,144 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.depend;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Vector;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+import org.apache.tools.ant.util.FileUtils;
+import org.apache.tools.ant.util.depend.AbstractAnalyzer;
+
+/**
+ * An analyzer which uses the depend task's bytecode classes to analyze
+ * dependencies
+ *
+ */
+public class AntAnalyzer extends AbstractAnalyzer {
+ /**
+ * Default constructor
+ */
+ public AntAnalyzer() {
+ }
+
+ /**
+ * Determine the dependencies of the configured root classes.
+ *
+ * @param files a vector to be populated with the files which contain
+ * the dependency classes
+ * @param classes a vector to be populated with the names of the
+ * dependency classes.
+ */
+ protected void determineDependencies(Vector<File> files, Vector<String> classes) {
+ // we get the root classes and build up a set of
+ // classes upon which they depend
+ Hashtable<String, String> dependencies = new Hashtable<String, String>();
+ Hashtable<File, File> containers = new Hashtable<File, File>();
+ Hashtable<String, String> toAnalyze = new Hashtable<String, String>();
+ for (Enumeration<String> e = getRootClasses(); e.hasMoreElements();) {
+ String classname = e.nextElement();
+ toAnalyze.put(classname, classname);
+ }
+
+ int count = 0;
+ int maxCount = isClosureRequired() ? MAX_LOOPS : 1;
+ Hashtable<String, String> analyzedDeps = null;
+ while (toAnalyze.size() != 0 && count++ < maxCount) {
+ analyzedDeps = new Hashtable<String, String>();
+ for (Enumeration<String> e = toAnalyze.keys(); e.hasMoreElements();) {
+ String classname = e.nextElement();
+ dependencies.put(classname, classname);
+ try {
+ File container = getClassContainer(classname);
+ if (container == null) {
+ continue;
+ }
+ containers.put(container, container);
+
+ ZipFile zipFile = null;
+ InputStream inStream = null;
+ try {
+ if (container.getName().endsWith(".class")) {
+ inStream = new FileInputStream(container.getPath());
+ } else {
+ zipFile = new ZipFile(container.getPath());
+ String entryName
+ = classname.replace('.', '/') + ".class";
+ ZipEntry entry = new ZipEntry(entryName);
+ inStream
+ = zipFile.getInputStream(entry);
+ }
+ ClassFile classFile = new ClassFile();
+ classFile.read(inStream);
+ for (String dependency : classFile.getClassRefs()) {
+ analyzedDeps.put(dependency, dependency);
+ }
+ } finally {
+ FileUtils.close(inStream);
+ if (zipFile != null) {
+ zipFile.close();
+ }
+ }
+ } catch (IOException ioe) {
+ // ignore
+ }
+ }
+
+ toAnalyze.clear();
+
+ // now recover all the dependencies collected and add to the list.
+ for (String className : analyzedDeps.values()) {
+ if (!dependencies.containsKey(className)) {
+ toAnalyze.put(className, className);
+ }
+ }
+ }
+
+ // pick up the last round of dependencies that were determined
+ for (String className : analyzedDeps.values()) {
+ dependencies.put(className, className);
+ }
+
+ files.removeAllElements();
+ for (File f : containers.keySet()) {
+ files.add(f);
+ }
+
+ classes.removeAllElements();
+ for (String dependency :dependencies.keySet()) {
+ classes.add(dependency);
+ }
+ }
+
+ /**
+ * Indicate if this analyzer can determine dependent files.
+ *
+ * @return true if the analyzer provides dependency file information.
+ */
+ protected boolean supportsFileDependencies() {
+ return true;
+ }
+
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/ClassFile.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/ClassFile.java
new file mode 100644
index 00000000..858ce03e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/ClassFile.java
@@ -0,0 +1,121 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.depend;
+
+import java.io.DataInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Vector;
+
+import org.apache.tools.ant.taskdefs.optional.depend.constantpool.ClassCPInfo;
+import org.apache.tools.ant.taskdefs.optional.depend.constantpool.ConstantPool;
+import org.apache.tools.ant.taskdefs.optional.depend.constantpool.ConstantPoolEntry;
+
+/**
+ * A ClassFile object stores information about a Java class. The class may
+ * be read from a DataInputStream.and written to a DataOutputStream. These
+ * are usually streams from a Java class file or a class file component of a
+ * Jar file.
+ *
+ */
+public class ClassFile {
+
+ /** The Magic Value that marks the start of a Java class file */
+ private static final int CLASS_MAGIC = 0xCAFEBABE;
+
+ /** This class' constant pool. */
+ private ConstantPool constantPool;
+
+ /** The class name for this class. */
+ private String className;
+
+ /**
+ * Read the class from a data stream. This method takes an InputStream
+ * as input and parses the class from the stream. <p>
+ *
+ *
+ *
+ * @param stream an InputStream from which the class will be read
+ * @exception IOException if there is a problem reading from the given
+ * stream.
+ * @exception ClassFormatError if the class cannot be parsed correctly
+ */
+ public void read(InputStream stream) throws IOException, ClassFormatError {
+ DataInputStream classStream = new DataInputStream(stream);
+
+ if (classStream.readInt() != CLASS_MAGIC) {
+ throw new ClassFormatError("No Magic Code Found "
+ + "- probably not a Java class file.");
+ }
+
+ // right we have a good looking class file.
+ /* int minorVersion = */ classStream.readUnsignedShort();
+ /* int majorVersion = */ classStream.readUnsignedShort();
+
+ // read the constant pool in and resolve it
+ constantPool = new ConstantPool();
+
+ constantPool.read(classStream);
+ constantPool.resolve();
+
+ /* int accessFlags = */ classStream.readUnsignedShort();
+ int thisClassIndex = classStream.readUnsignedShort();
+ /* int superClassIndex = */ classStream.readUnsignedShort();
+ ClassCPInfo classInfo
+ = (ClassCPInfo) constantPool.getEntry(thisClassIndex);
+ className = classInfo.getClassName();
+ }
+
+
+ /**
+ * Get the classes which this class references.
+ *
+ * @return a vector of class names which this class references
+ */
+ public Vector<String> getClassRefs() {
+
+ Vector<String> classRefs = new Vector<String>();
+
+ final int size = constantPool.size();
+ for (int i = 0; i < size; ++i) {
+ ConstantPoolEntry entry = constantPool.getEntry(i);
+
+ if (entry != null
+ && entry.getTag() == ConstantPoolEntry.CONSTANT_CLASS) {
+ ClassCPInfo classEntry = (ClassCPInfo) entry;
+
+ if (!classEntry.getClassName().equals(className)) {
+ classRefs.add(
+ ClassFileUtils.convertSlashName(classEntry.getClassName()));
+ }
+ }
+ }
+
+ return classRefs;
+ }
+
+ /**
+ * Get the class' fully qualified name in dot format.
+ *
+ * @return the class name in dot format (eg. java.lang.Object)
+ */
+ public String getFullClassName() {
+ return ClassFileUtils.convertSlashName(className);
+ }
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/ClassFileIterator.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/ClassFileIterator.java
new file mode 100644
index 00000000..92fc191b
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/ClassFileIterator.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.depend;
+
+/**
+ * Iterator interface for iterating over a set of class files
+ *
+ */
+public interface ClassFileIterator {
+
+ /**
+ * Get the next class file in the iteration
+ *
+ * @return the next class file in the iteration
+ */
+ ClassFile getNextClassFile();
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/ClassFileUtils.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/ClassFileUtils.java
new file mode 100644
index 00000000..c6eec6cc
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/ClassFileUtils.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.depend;
+
+/**
+ * Utility class file routines. This class provides a number of static
+ * utility methods to convert between the formats used in the Java class
+ * file format and those commonly used in Java programming.
+ *
+ *
+ */
+// CheckStyle:HideUtilityClassConstructorCheck OFF (bc)
+public class ClassFileUtils {
+
+ /**
+ * Convert a class name from class file slash notation to java source
+ * file dot notation.
+ *
+ * @param name the class name in slash notation org/apache/ant
+ * @return the class name in dot notation (eg. java.lang.Object).
+ */
+ public static String convertSlashName(String name) {
+ return name.replace('\\', '.').replace('/', '.');
+ }
+
+ /**
+ * Convert a class name from java source file dot notation to class file
+ * slash notation..
+ *
+ * @param dotName the class name in dot notation (eg. java.lang.Object).
+ * @return the class name in slash notation (eg. java/lang/Object).
+ */
+ public static String convertDotName(String dotName) {
+ return dotName.replace('.', '/');
+ }
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/Depend.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/Depend.java
new file mode 100644
index 00000000..cc65129f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/Depend.java
@@ -0,0 +1,917 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.depend;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.net.URL;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Vector;
+
+import org.apache.tools.ant.AntClassLoader;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.DirectoryScanner;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.MatchingTask;
+import org.apache.tools.ant.taskdefs.rmic.DefaultRmicAdapter;
+import org.apache.tools.ant.taskdefs.rmic.WLRmic;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.types.Reference;
+import org.apache.tools.ant.util.FileUtils;
+import org.apache.tools.ant.util.depend.DependencyAnalyzer;
+
+/**
+ * Generates a dependency file for a given set of classes.
+ *
+ */
+public class Depend extends MatchingTask {
+ private static final int ONE_SECOND = 1000;
+
+ /**
+ * A class (struct) user to manage information about a class
+ *
+ */
+ private static class ClassFileInfo {
+ /** The file where the class file is stored in the file system */
+ private File absoluteFile;
+
+ /** The Java class name of this class */
+ private String className;
+
+ /** The source File containing this class */
+ private File sourceFile;
+
+ /** if user has been warned about this file not having a source file */
+ private boolean isUserWarned = false;
+ }
+
+ /** The path where source files exist */
+ private Path srcPath;
+
+ /** The path where compiled class files exist. */
+ private Path destPath;
+
+ /** The directory which contains the dependency cache. */
+ private File cache;
+
+ /** The list of source paths derived from the srcPath field. */
+ private String[] srcPathList;
+
+ /**
+ * A map which gives for every class a list of the class which it
+ * affects.
+ */
+ private Hashtable affectedClassMap;
+
+ /** A map which gives information about a class */
+ private Hashtable classFileInfoMap;
+
+ /**
+ * A map which gives the list of jars and classes from the classpath
+ * that a class depends upon
+ */
+ private Hashtable classpathDependencies;
+
+ /** The list of classes which are out of date. */
+ private Hashtable outOfDateClasses;
+
+ /**
+ * indicates that the dependency relationships should be extended beyond
+ * direct dependencies to include all classes. So if A directly affects
+ * B and B directly affects C, then A indirectly affects C.
+ */
+ private boolean closure = false;
+
+ /**
+ * flag to enable warning if we encounter RMI stubs
+ */
+ private boolean warnOnRmiStubs = true;
+
+ /**
+ * Flag which controls whether the reversed dependencies should be
+ * dumped to the log
+ */
+ private boolean dump = false;
+
+ /** The classpath to look for additional dependencies */
+ private Path dependClasspath;
+
+ /** constants used with the cache file */
+ private static final String CACHE_FILE_NAME = "dependencies.txt";
+ /** String Used to separate classnames in the dependency file */
+ private static final String CLASSNAME_PREPEND = "||:";
+
+ /**
+ * Set the classpath to be used for this dependency check.
+ *
+ * @param classpath the classpath to be used when checking for
+ * dependencies on elements in the classpath
+ */
+ public void setClasspath(Path classpath) {
+ if (dependClasspath == null) {
+ dependClasspath = classpath;
+ } else {
+ dependClasspath.append(classpath);
+ }
+ }
+
+ /**
+ * Gets the classpath to be used for this dependency check.
+ *
+ * @return the current dependency classpath
+ */
+ public Path getClasspath() {
+ return dependClasspath;
+ }
+
+ /**
+ * Adds a classpath to be used for this dependency check.
+ *
+ * @return A path object to be configured by Ant
+ */
+ public Path createClasspath() {
+ if (dependClasspath == null) {
+ dependClasspath = new Path(getProject());
+ }
+ return dependClasspath.createPath();
+ }
+
+ /**
+ * Adds a reference to a classpath defined elsewhere.
+ *
+ * @param r a reference to a path object to be used as the depend
+ * classpath
+ */
+ public void setClasspathRef(Reference r) {
+ createClasspath().setRefid(r);
+ }
+
+ /**
+ * Flag to set to true if you want dependency issues with RMI
+ * stubs to appear at warning level.
+ * @param warnOnRmiStubs if true set dependency issues to appear at warning level.
+ * @since Ant1.7
+ */
+ public void setWarnOnRmiStubs(boolean warnOnRmiStubs) {
+ this.warnOnRmiStubs = warnOnRmiStubs;
+ }
+
+ /**
+ * Read the dependencies from cache file
+ *
+ * @return a collection of class dependencies
+ * @exception IOException if the dependency file cannot be read
+ */
+ private Hashtable readCachedDependencies(File depFile) throws IOException {
+ Hashtable dependencyMap = new Hashtable();
+
+ BufferedReader in = null;
+ try {
+ in = new BufferedReader(new FileReader(depFile));
+ String line = null;
+ Vector dependencyList = null;
+ String className = null;
+ int prependLength = CLASSNAME_PREPEND.length();
+ while ((line = in.readLine()) != null) {
+ if (line.startsWith(CLASSNAME_PREPEND)) {
+ dependencyList = new Vector();
+ className = line.substring(prependLength);
+ dependencyMap.put(className, dependencyList);
+ } else {
+ dependencyList.addElement(line);
+ }
+ }
+ } finally {
+ FileUtils.close(in);
+ }
+
+ return dependencyMap;
+ }
+
+ /**
+ * Write the dependencies to cache file
+ *
+ * @param dependencyMap the map of dependencies to be written out.
+ * @exception IOException if the dependency file cannot be written out.
+ */
+ private void writeCachedDependencies(Hashtable dependencyMap)
+ throws IOException {
+ if (cache != null) {
+ BufferedWriter pw = null;
+ try {
+ cache.mkdirs();
+ File depFile = new File(cache, CACHE_FILE_NAME);
+
+ pw = new BufferedWriter(new FileWriter(depFile));
+ Enumeration e = dependencyMap.keys();
+ while (e.hasMoreElements()) {
+ String className = (String) e.nextElement();
+
+ pw.write(CLASSNAME_PREPEND + className);
+ pw.newLine();
+
+ Vector dependencyList
+ = (Vector) dependencyMap.get(className);
+ int size = dependencyList.size();
+ for (int x = 0; x < size; x++) {
+ pw.write(String.valueOf(dependencyList.elementAt(x)));
+ pw.newLine();
+ }
+ }
+ } finally {
+ FileUtils.close(pw);
+ }
+ }
+ }
+
+ /**
+ * Get the classpath for dependency checking.
+ *
+ * This method removes the dest dirs if it is given from the dependency classpath
+ */
+ private Path getCheckClassPath() {
+ if (dependClasspath == null) {
+ return null;
+ }
+
+ String[] destPathElements = destPath.list();
+ String[] classpathElements = dependClasspath.list();
+ String checkPath = "";
+ for (int i = 0; i < classpathElements.length; ++i) {
+ String element = classpathElements[i];
+ boolean inDestPath = false;
+ for (int j = 0; j < destPathElements.length && !inDestPath; ++j) {
+ inDestPath = destPathElements[j].equals(element);
+ }
+ if (!inDestPath) {
+ if (checkPath.length() == 0) {
+ checkPath = element;
+ } else {
+ checkPath += ":" + element;
+ }
+ }
+ }
+
+ Path p = null;
+ if (checkPath.length() > 0) {
+ p = new Path(getProject(), checkPath);
+ }
+
+ log("Classpath without dest dir is " + p, Project.MSG_DEBUG);
+ return p;
+ }
+
+ /**
+ * Determine the dependencies between classes. Class dependencies are
+ * determined by examining the class references in a class file to other
+ * classes.
+ *
+ * This method sets up the following fields
+ * <ul>
+ * <li>affectedClassMap - the list of classes each class affects</li>
+ * <li>classFileInfoMap - information about each class</li>
+ * <li>classpathDependencies - the list of jars and classes from the
+ * classpath that each class depends upon.</li>
+ * </ul>
+ *
+ * If required, the dependencies are written to the cache.
+ *
+ * @exception IOException if either the dependencies cache or the class
+ * files cannot be read or written
+ */
+ private void determineDependencies() throws IOException {
+ affectedClassMap = new Hashtable();
+ classFileInfoMap = new Hashtable();
+ boolean cacheDirty = false;
+
+ Hashtable dependencyMap = new Hashtable();
+ File cacheFile = null;
+ boolean cacheFileExists = true;
+ long cacheLastModified = Long.MAX_VALUE;
+
+ // read the dependency cache from the disk
+ if (cache != null) {
+ cacheFile = new File(cache, CACHE_FILE_NAME);
+ cacheFileExists = cacheFile.exists();
+ cacheLastModified = cacheFile.lastModified();
+ if (cacheFileExists) {
+ dependencyMap = readCachedDependencies(cacheFile);
+ }
+ }
+ Enumeration classfileEnum = getClassFiles(destPath).elements();
+ while (classfileEnum.hasMoreElements()) {
+ ClassFileInfo info = (ClassFileInfo) classfileEnum.nextElement();
+ log("Adding class info for " + info.className, Project.MSG_DEBUG);
+ classFileInfoMap.put(info.className, info);
+
+ Vector dependencyList = null;
+
+ if (cache != null) {
+ // try to read the dependency info from the map if it is
+ // not out of date
+ if (cacheFileExists
+ && cacheLastModified > info.absoluteFile.lastModified()) {
+ // depFile exists and is newer than the class file
+ // need to get dependency list from the map.
+ dependencyList = (Vector) dependencyMap.get(info.className);
+ }
+ }
+
+ if (dependencyList == null) {
+ // not cached - so need to read directly from the class file
+ DependencyAnalyzer analyzer = new AntAnalyzer();
+ analyzer.addRootClass(info.className);
+ analyzer.addClassPath(destPath);
+ analyzer.setClosure(false);
+ dependencyList = new Vector();
+ Enumeration depEnum = analyzer.getClassDependencies();
+ while (depEnum.hasMoreElements()) {
+ Object o = depEnum.nextElement();
+ dependencyList.addElement(o);
+ log("Class " + info.className + " depends on " + o,
+ Project.MSG_DEBUG);
+ }
+ cacheDirty = true;
+ dependencyMap.put(info.className, dependencyList);
+ }
+
+ // This class depends on each class in the dependency list. For each
+ // one of those, add this class into their affected classes list
+ Enumeration depEnum = dependencyList.elements();
+ while (depEnum.hasMoreElements()) {
+ String dependentClass = (String) depEnum.nextElement();
+
+ Hashtable affectedClasses
+ = (Hashtable) affectedClassMap.get(dependentClass);
+ if (affectedClasses == null) {
+ affectedClasses = new Hashtable();
+ affectedClassMap.put(dependentClass, affectedClasses);
+ }
+
+ affectedClasses.put(info.className, info);
+ log(dependentClass + " affects " + info.className,
+ Project.MSG_DEBUG);
+ }
+ }
+
+ classpathDependencies = null;
+ Path checkPath = getCheckClassPath();
+ if (checkPath != null) {
+ // now determine which jars each class depends upon
+ classpathDependencies = new Hashtable();
+ AntClassLoader loader = null;
+ try {
+ loader = getProject().createClassLoader(checkPath);
+
+ Hashtable classpathFileCache = new Hashtable();
+ Object nullFileMarker = new Object();
+ for (Enumeration e = dependencyMap.keys(); e.hasMoreElements();) {
+ String className = (String) e.nextElement();
+ log("Determining classpath dependencies for " + className,
+ Project.MSG_DEBUG);
+ Vector dependencyList = (Vector) dependencyMap.get(className);
+ Hashtable dependencies = new Hashtable();
+ classpathDependencies.put(className, dependencies);
+ Enumeration e2 = dependencyList.elements();
+ while (e2.hasMoreElements()) {
+ String dependency = (String) e2.nextElement();
+ log("Looking for " + dependency, Project.MSG_DEBUG);
+ Object classpathFileObject
+ = classpathFileCache.get(dependency);
+ if (classpathFileObject == null) {
+ classpathFileObject = nullFileMarker;
+
+ if (!dependency.startsWith("java.")
+ && !dependency.startsWith("javax.")) {
+ URL classURL
+ = loader.getResource(dependency.replace('.', '/') + ".class");
+ log("URL is " + classURL, Project.MSG_DEBUG);
+ if (classURL != null) {
+ if (classURL.getProtocol().equals("jar")) {
+ String jarFilePath = classURL.getFile();
+ int classMarker = jarFilePath.indexOf('!');
+ jarFilePath = jarFilePath.substring(0, classMarker);
+ if (jarFilePath.startsWith("file:")) {
+ classpathFileObject = new File(
+ FileUtils.getFileUtils().fromURI(jarFilePath));
+ } else {
+ throw new IOException(
+ "Bizarre nested path in jar: protocol: "
+ + jarFilePath);
+ }
+ } else if (classURL.getProtocol().equals("file")) {
+ classpathFileObject = new File(
+ FileUtils.getFileUtils()
+ .fromURI(classURL.toExternalForm()));
+ }
+ log("Class " + className
+ + " depends on " + classpathFileObject
+ + " due to " + dependency, Project.MSG_DEBUG);
+ }
+ } else {
+ log("Ignoring base classlib dependency "
+ + dependency, Project.MSG_DEBUG);
+ }
+ classpathFileCache.put(dependency, classpathFileObject);
+ }
+ if (classpathFileObject != nullFileMarker) {
+ // we need to add this jar to the list for this class.
+ File jarFile = (File) classpathFileObject;
+ log("Adding a classpath dependency on " + jarFile,
+ Project.MSG_DEBUG);
+ dependencies.put(jarFile, jarFile);
+ }
+ }
+ }
+ } finally {
+ if (loader != null) {
+ loader.cleanup();
+ }
+ }
+ } else {
+ log("No classpath to check", Project.MSG_DEBUG);
+ }
+
+ // write the dependency cache to the disk
+ if (cache != null && cacheDirty) {
+ writeCachedDependencies(dependencyMap);
+ }
+ }
+
+ /**
+ * Delete all the class files which are out of date, by way of their
+ * dependency on a class which is out of date
+ *
+ * @return the number of files deleted.
+ */
+ private int deleteAllAffectedFiles() {
+ int count = 0;
+ for (Enumeration e = outOfDateClasses.elements(); e.hasMoreElements();) {
+ String className = (String) e.nextElement();
+ count += deleteAffectedFiles(className);
+ ClassFileInfo classInfo
+ = (ClassFileInfo) classFileInfoMap.get(className);
+ if (classInfo != null && classInfo.absoluteFile.exists()) {
+ if (classInfo.sourceFile == null) {
+ warnOutOfDateButNotDeleted(classInfo, className, className);
+ } else {
+ classInfo.absoluteFile.delete();
+ count++;
+ }
+ }
+ }
+ return count;
+ }
+
+ /**
+ * Delete all the class files of classes which depend on the given class
+ *
+ * @param className the name of the class whose dependent classes will be
+ * deleted
+ * @return the number of class files removed
+ */
+ private int deleteAffectedFiles(String className) {
+ int count = 0;
+
+ Hashtable affectedClasses = (Hashtable) affectedClassMap.get(className);
+ if (affectedClasses == null) {
+ return count;
+ }
+ for (Enumeration e = affectedClasses.keys(); e.hasMoreElements();) {
+ String affectedClass = (String) e.nextElement();
+ ClassFileInfo affectedClassInfo
+ = (ClassFileInfo) affectedClasses.get(affectedClass);
+
+ if (!affectedClassInfo.absoluteFile.exists()) {
+ continue;
+ }
+
+ if (affectedClassInfo.sourceFile == null) {
+ warnOutOfDateButNotDeleted(affectedClassInfo, affectedClass, className);
+ continue;
+ }
+
+ log("Deleting file " + affectedClassInfo.absoluteFile.getPath()
+ + " since " + className + " out of date", Project.MSG_VERBOSE);
+
+ affectedClassInfo.absoluteFile.delete();
+ count++;
+ if (closure) {
+ count += deleteAffectedFiles(affectedClass);
+ } else {
+ // without closure we may delete an inner class but not the
+ // top level class which would not trigger a recompile.
+
+ if (affectedClass.indexOf("$") == -1) {
+ continue;
+ }
+ // need to delete the main class
+ String topLevelClassName
+ = affectedClass.substring(0, affectedClass.indexOf("$"));
+ log("Top level class = " + topLevelClassName,
+ Project.MSG_VERBOSE);
+ ClassFileInfo topLevelClassInfo
+ = (ClassFileInfo) classFileInfoMap.get(topLevelClassName);
+ if (topLevelClassInfo != null
+ && topLevelClassInfo.absoluteFile.exists()) {
+ log("Deleting file "
+ + topLevelClassInfo.absoluteFile.getPath()
+ + " since one of its inner classes was removed",
+ Project.MSG_VERBOSE);
+ topLevelClassInfo.absoluteFile.delete();
+ count++;
+ if (closure) {
+ count += deleteAffectedFiles(topLevelClassName);
+ }
+ }
+ }
+ }
+ return count;
+ }
+
+ /**
+ * warn when a class is out of date, but not deleted as its source is unknown.
+ * MSG_WARN is the normal level, but we downgrade to MSG_VERBOSE for RMI files
+ * if {@link #warnOnRmiStubs is false}
+ * @param affectedClassInfo info about the affectd class
+ * @param affectedClass the name of the affected .class file
+ * @param className the file that is triggering the out of dateness
+ */
+ private void warnOutOfDateButNotDeleted(
+ ClassFileInfo affectedClassInfo, String affectedClass,
+ String className) {
+ if (affectedClassInfo.isUserWarned) {
+ return;
+ }
+ int level = Project.MSG_WARN;
+ if (!warnOnRmiStubs) {
+ //downgrade warnings on RMI stublike classes, as they are generated
+ //by rmic, so there is no need to tell the user that their source is
+ //missing.
+ if (isRmiStub(affectedClass, className)) {
+ level = Project.MSG_VERBOSE;
+ }
+ }
+ log("The class " + affectedClass + " in file "
+ + affectedClassInfo.absoluteFile.getPath()
+ + " is out of date due to " + className
+ + " but has not been deleted because its source file"
+ + " could not be determined", level);
+ affectedClassInfo.isUserWarned = true;
+ }
+
+ /**
+ * test for being an RMI stub
+ * @param affectedClass class being tested
+ * @param className possible origin of the RMI stub
+ * @return whether the class affectedClass is a RMI stub
+ */
+ private boolean isRmiStub(String affectedClass, String className) {
+ return isStub(affectedClass, className, DefaultRmicAdapter.RMI_STUB_SUFFIX)
+ || isStub(affectedClass, className, DefaultRmicAdapter.RMI_SKEL_SUFFIX)
+ || isStub(affectedClass, className, WLRmic.RMI_STUB_SUFFIX)
+ || isStub(affectedClass, className, WLRmic.RMI_SKEL_SUFFIX);
+ }
+
+ private boolean isStub(String affectedClass, String baseClass, String suffix) {
+ return (baseClass + suffix).equals(affectedClass);
+ }
+
+ /**
+ * Dump the dependency information loaded from the classes to the Ant log
+ */
+ private void dumpDependencies() {
+ log("Reverse Dependency Dump for " + affectedClassMap.size()
+ + " classes:", Project.MSG_DEBUG);
+
+ Enumeration classEnum = affectedClassMap.keys();
+ while (classEnum.hasMoreElements()) {
+ String className = (String) classEnum.nextElement();
+ log(" Class " + className + " affects:", Project.MSG_DEBUG);
+ Hashtable affectedClasses
+ = (Hashtable) affectedClassMap.get(className);
+ Enumeration affectedClassEnum = affectedClasses.keys();
+ while (affectedClassEnum.hasMoreElements()) {
+ String affectedClass = (String) affectedClassEnum.nextElement();
+ ClassFileInfo info
+ = (ClassFileInfo) affectedClasses.get(affectedClass);
+ log(" " + affectedClass + " in "
+ + info.absoluteFile.getPath(), Project.MSG_DEBUG);
+ }
+ }
+
+ if (classpathDependencies != null) {
+ log("Classpath file dependencies (Forward):", Project.MSG_DEBUG);
+
+ Enumeration classpathEnum = classpathDependencies.keys();
+ while (classpathEnum.hasMoreElements()) {
+ String className = (String) classpathEnum.nextElement();
+ log(" Class " + className + " depends on:", Project.MSG_DEBUG);
+ Hashtable dependencies
+ = (Hashtable) classpathDependencies.get(className);
+
+ Enumeration classpathFileEnum = dependencies.elements();
+ while (classpathFileEnum.hasMoreElements()) {
+ File classpathFile = (File) classpathFileEnum.nextElement();
+ log(" " + classpathFile.getPath(), Project.MSG_DEBUG);
+ }
+ }
+ }
+ }
+
+ private void determineOutOfDateClasses() {
+ outOfDateClasses = new Hashtable();
+ for (int i = 0; i < srcPathList.length; i++) {
+ File srcDir = getProject().resolveFile(srcPathList[i]);
+ if (srcDir.exists()) {
+ DirectoryScanner ds = this.getDirectoryScanner(srcDir);
+ String[] files = ds.getIncludedFiles();
+ scanDir(srcDir, files);
+ }
+ }
+
+ // now check classpath file dependencies
+ if (classpathDependencies == null) {
+ return;
+ }
+
+ Enumeration classpathDepsEnum = classpathDependencies.keys();
+ while (classpathDepsEnum.hasMoreElements()) {
+ String className = (String) classpathDepsEnum.nextElement();
+ if (outOfDateClasses.containsKey(className)) {
+ continue;
+ }
+ ClassFileInfo info
+ = (ClassFileInfo) classFileInfoMap.get(className);
+
+ // if we have no info about the class - it may have been deleted already and we
+ // are using cached info.
+ if (info != null) {
+ Hashtable dependencies
+ = (Hashtable) classpathDependencies.get(className);
+ for (Enumeration e2 = dependencies.elements(); e2.hasMoreElements();) {
+ File classpathFile = (File) e2.nextElement();
+ if (classpathFile.lastModified()
+ > info.absoluteFile.lastModified()) {
+ log("Class " + className
+ + " is out of date with respect to "
+ + classpathFile, Project.MSG_DEBUG);
+ outOfDateClasses.put(className, className);
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Does the work.
+ *
+ * @exception BuildException Thrown in case of an unrecoverable error.
+ */
+ public void execute() throws BuildException {
+ try {
+ long start = System.currentTimeMillis();
+ if (srcPath == null) {
+ throw new BuildException("srcdir attribute must be set",
+ getLocation());
+ }
+
+ srcPathList = srcPath.list();
+ if (srcPathList.length == 0) {
+ throw new BuildException("srcdir attribute must be non-empty",
+ getLocation());
+ }
+
+ if (destPath == null) {
+ destPath = srcPath;
+ }
+
+ if (cache != null && cache.exists() && !cache.isDirectory()) {
+ throw new BuildException("The cache, if specified, must "
+ + "point to a directory");
+ }
+
+ if (cache != null && !cache.exists()) {
+ cache.mkdirs();
+ }
+
+ determineDependencies();
+ if (dump) {
+ dumpDependencies();
+ }
+ determineOutOfDateClasses();
+ int count = deleteAllAffectedFiles();
+
+ long duration = (System.currentTimeMillis() - start) / ONE_SECOND;
+
+ final int summaryLogLevel;
+ if (count > 0) {
+ summaryLogLevel = Project.MSG_INFO;
+ } else {
+ summaryLogLevel = Project.MSG_DEBUG;
+ }
+
+ log("Deleted " + count + " out of date files in "
+ + duration + " seconds", summaryLogLevel);
+ } catch (Exception e) {
+ throw new BuildException(e);
+ }
+ }
+
+ /**
+ * Scans the directory looking for source files that are newer than
+ * their class files. The results are returned in the class variable
+ * compileList
+ *
+ * @param srcDir the source directory
+ * @param files the names of the files in the source dir which are to be
+ * checked.
+ */
+ protected void scanDir(File srcDir, String[] files) {
+
+ for (int i = 0; i < files.length; i++) {
+ File srcFile = new File(srcDir, files[i]);
+ if (files[i].endsWith(".java")) {
+ String filePath = srcFile.getPath();
+ String className
+ = filePath.substring(srcDir.getPath().length() + 1,
+ filePath.length() - ".java".length());
+ className = ClassFileUtils.convertSlashName(className);
+ ClassFileInfo info
+ = (ClassFileInfo) classFileInfoMap.get(className);
+ if (info == null) {
+ // there was no class file. add this class to the list
+ outOfDateClasses.put(className, className);
+ } else {
+ if (srcFile.lastModified()
+ > info.absoluteFile.lastModified()) {
+ outOfDateClasses.put(className, className);
+ }
+ }
+ }
+ }
+ }
+
+
+ /**
+ * Get the list of class files we are going to analyse.
+ *
+ * @param classLocations a path structure containing all the directories
+ * where classes can be found.
+ * @return a vector containing the classes to analyse.
+ */
+ private Vector getClassFiles(Path classLocations) {
+ // break the classLocations into its components.
+ String[] classLocationsList = classLocations.list();
+
+ Vector classFileList = new Vector();
+
+ for (int i = 0; i < classLocationsList.length; ++i) {
+ File dir = new File(classLocationsList[i]);
+ if (dir.isDirectory()) {
+ addClassFiles(classFileList, dir, dir);
+ }
+ }
+
+ return classFileList;
+ }
+
+ /**
+ * Find the source file for a given class
+ *
+ * @param classname the classname in slash format.
+ * @param sourceFileKnownToExist if not null, a file already known to exist
+ * (saves call to .exists())
+ */
+ private File findSourceFile(String classname, File sourceFileKnownToExist) {
+ String sourceFilename;
+ int innerIndex = classname.indexOf("$");
+ if (innerIndex != -1) {
+ sourceFilename = classname.substring(0, innerIndex) + ".java";
+ } else {
+ sourceFilename = classname + ".java";
+ }
+
+ // search the various source path entries
+ for (int i = 0; i < srcPathList.length; ++i) {
+ File sourceFile = new File(srcPathList[i], sourceFilename);
+ if (sourceFile.equals(sourceFileKnownToExist) || sourceFile.exists()) {
+ return sourceFile;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Add the list of class files from the given directory to the class
+ * file vector, including any subdirectories.
+ *
+ * @param classFileList a list of ClassFileInfo objects for all the
+ * files in the directory tree
+ * @param dir the directory tree to be searched, recursively, for class
+ * files
+ * @param root the root of the source tree. This is used to determine
+ * the absolute class name from the relative position in the
+ * source tree
+ */
+ private void addClassFiles(Vector classFileList, File dir, File root) {
+ String[] filesInDir = dir.list();
+
+ if (filesInDir == null) {
+ return;
+ }
+ int length = filesInDir.length;
+
+ int rootLength = root.getPath().length();
+ File sourceFileKnownToExist = null; // speed optimization
+ for (int i = 0; i < length; ++i) {
+ File file = new File(dir, filesInDir[i]);
+ if (filesInDir[i].endsWith(".class")) {
+ ClassFileInfo info = new ClassFileInfo();
+ info.absoluteFile = file;
+ String relativeName = file.getPath().substring(
+ rootLength + 1,
+ file.getPath().length() - ".class".length());
+ info.className
+ = ClassFileUtils.convertSlashName(relativeName);
+ info.sourceFile = sourceFileKnownToExist = findSourceFile(
+ relativeName, sourceFileKnownToExist);
+ classFileList.addElement(info);
+ } else {
+ addClassFiles(classFileList, file, root);
+ }
+ }
+ }
+
+
+ /**
+ * Set the directories path to find the Java source files.
+ *
+ * @param srcPath the source path
+ */
+ public void setSrcdir(Path srcPath) {
+ this.srcPath = srcPath;
+ }
+
+ /**
+ * Set the destination directory where the compiled Java files exist.
+ *
+ * @param destPath the destination areas where build files are written
+ */
+ public void setDestDir(Path destPath) {
+ this.destPath = destPath;
+ }
+
+ /**
+ * Sets the dependency cache file.
+ *
+ * @param cache the dependency cache file
+ */
+ public void setCache(File cache) {
+ this.cache = cache;
+ }
+
+ /**
+ * If true, transitive dependencies are followed until the
+ * closure of the dependency set if reached.
+ * When not set, the depend task will only follow
+ * direct dependencies between classes.
+ *
+ * @param closure indicate if dependency closure is required.
+ */
+ public void setClosure(boolean closure) {
+ this.closure = closure;
+ }
+
+ /**
+ * If true, the dependency information will be written
+ * to the debug level log.
+ *
+ * @param dump set to true to dump dependency information to the log
+ */
+ public void setDump(boolean dump) {
+ this.dump = dump;
+ }
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/DirectoryIterator.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/DirectoryIterator.java
new file mode 100644
index 00000000..ebf244a5
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/DirectoryIterator.java
@@ -0,0 +1,164 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.depend;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.Stack;
+import java.util.Vector;
+
+/**
+ * An iterator which iterates through the contents of a java directory. The
+ * iterator should be created with the directory at the root of the Java
+ * namespace.
+ *
+ */
+public class DirectoryIterator implements ClassFileIterator {
+
+ /**
+ * This is a stack of current iterators supporting the depth first
+ * traversal of the directory tree.
+ */
+ private Stack enumStack;
+
+ /**
+ * The current directory iterator. As directories encounter lower level
+ * directories, the current iterator is pushed onto the iterator stack
+ * and a new iterator over the sub directory becomes the current
+ * directory. This implements a depth first traversal of the directory
+ * namespace.
+ */
+ private Enumeration currentEnum;
+
+ /**
+ * Creates a directory iterator. The directory iterator is created to
+ * scan the root directory. If the changeInto flag is given, then the
+ * entries returned will be relative to this directory and not the
+ * current directory.
+ *
+ * @param rootDirectory the root if the directory namespace which is to
+ * be iterated over
+ * @param changeInto if true then the returned entries will be relative
+ * to the rootDirectory and not the current directory.
+ * @exception IOException if there is a problem reading the directory
+ * information.
+ */
+ public DirectoryIterator(File rootDirectory, boolean changeInto)
+ throws IOException {
+ super();
+
+ enumStack = new Stack();
+
+ Vector filesInRoot = getDirectoryEntries(rootDirectory);
+
+ currentEnum = filesInRoot.elements();
+ }
+
+ /**
+ * Get a vector covering all the entries (files and subdirectories in a
+ * directory).
+ *
+ * @param directory the directory to be scanned.
+ * @return a vector containing File objects for each entry in the
+ * directory.
+ */
+ private Vector getDirectoryEntries(File directory) {
+ Vector files = new Vector();
+
+ // File[] filesInDir = directory.listFiles();
+ String[] filesInDir = directory.list();
+
+ if (filesInDir != null) {
+ int length = filesInDir.length;
+
+ for (int i = 0; i < length; ++i) {
+ files.addElement(new File(directory, filesInDir[i]));
+ }
+ }
+
+ return files;
+ }
+
+ /**
+ * Template method to allow subclasses to supply elements for the
+ * iteration. The directory iterator maintains a stack of iterators
+ * covering each level in the directory hierarchy. The current iterator
+ * covers the current directory being scanned. If the next entry in that
+ * directory is a subdirectory, the current iterator is pushed onto the
+ * stack and a new iterator is created for the subdirectory. If the
+ * entry is a file, it is returned as the next element and the iterator
+ * remains valid. If there are no more entries in the current directory,
+ * the topmost iterator on the stack is popped off to become the
+ * current iterator.
+ *
+ * @return the next ClassFile in the iteration.
+ */
+ public ClassFile getNextClassFile() {
+ ClassFile nextElement = null;
+
+ try {
+ while (nextElement == null) {
+ if (currentEnum.hasMoreElements()) {
+ File element = (File) currentEnum.nextElement();
+
+ if (element.isDirectory()) {
+
+ // push the current iterator onto the stack and then
+ // iterate through this directory.
+ enumStack.push(currentEnum);
+
+ Vector files = getDirectoryEntries(element);
+
+ currentEnum = files.elements();
+ } else {
+
+ // we have a file. create a stream for it
+ FileInputStream inFileStream
+ = new FileInputStream(element);
+
+ if (element.getName().endsWith(".class")) {
+
+ // create a data input stream from the jar
+ // input stream
+ ClassFile javaClass = new ClassFile();
+
+ javaClass.read(inFileStream);
+
+ nextElement = javaClass;
+ }
+ }
+ } else {
+ // this iterator is exhausted. Can we pop one off the stack
+ if (enumStack.empty()) {
+ break;
+ } else {
+ currentEnum = (Enumeration) enumStack.pop();
+ }
+ }
+ }
+ } catch (IOException e) {
+ nextElement = null;
+ }
+
+ return nextElement;
+ }
+
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/JarFileIterator.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/JarFileIterator.java
new file mode 100644
index 00000000..bc315d2e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/JarFileIterator.java
@@ -0,0 +1,89 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.depend;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+
+/**
+ * A class file iterator which iterates through the contents of a Java jar
+ * file.
+ *
+ */
+public class JarFileIterator implements ClassFileIterator {
+ /** The jar stream from the jar file being iterated over*/
+ private ZipInputStream jarStream;
+
+ /**
+ * Construct an iterator over a jar stream
+ *
+ * @param stream the basic input stream from which the Jar is received
+ * @exception IOException if the jar stream cannot be created
+ */
+ public JarFileIterator(InputStream stream) throws IOException {
+ super();
+
+ jarStream = new ZipInputStream(stream);
+ }
+
+ /**
+ * Get the next ClassFile object from the jar
+ *
+ * @return a ClassFile object describing the class from the jar
+ */
+ public ClassFile getNextClassFile() {
+ ZipEntry jarEntry;
+ ClassFile nextElement = null;
+
+ try {
+ jarEntry = jarStream.getNextEntry();
+
+ while (nextElement == null && jarEntry != null) {
+ String entryName = jarEntry.getName();
+
+ if (!jarEntry.isDirectory() && entryName.endsWith(".class")) {
+
+ // create a data input stream from the jar input stream
+ ClassFile javaClass = new ClassFile();
+
+ javaClass.read(jarStream);
+
+ nextElement = javaClass;
+ } else {
+
+ jarEntry = jarStream.getNextEntry();
+ }
+ }
+ } catch (IOException e) {
+ String message = e.getMessage();
+ String text = e.getClass().getName();
+
+ if (message != null) {
+ text += ": " + message;
+ }
+
+ throw new RuntimeException("Problem reading JAR file: " + text);
+ }
+
+ return nextElement;
+ }
+
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/ClassCPInfo.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/ClassCPInfo.java
new file mode 100644
index 00000000..8abbfc82
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/ClassCPInfo.java
@@ -0,0 +1,93 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.depend.constantpool;
+
+import java.io.DataInputStream;
+import java.io.IOException;
+
+/**
+ * The constant pool entry which stores class information.
+ *
+ */
+public class ClassCPInfo extends ConstantPoolEntry {
+
+ /**
+ * The class' name. This will be only valid if the entry has been
+ * resolved against the constant pool.
+ */
+ private String className;
+
+ /**
+ * The index into the constant pool where this class' name is stored. If
+ * the class name is changed, this entry is invalid until this entry is
+ * connected to a constant pool.
+ */
+ private int index;
+
+ /**
+ * Constructor. Sets the tag value for this entry to type Class
+ */
+ public ClassCPInfo() {
+ super(CONSTANT_CLASS, 1);
+ }
+
+ /**
+ * Read the entry from a stream.
+ *
+ * @param cpStream the stream containing the constant pool entry to be
+ * read.
+ * @exception IOException thrown if there is a problem reading the entry
+ * from the stream.
+ */
+ public void read(DataInputStream cpStream) throws IOException {
+ index = cpStream.readUnsignedShort();
+ className = "unresolved";
+ }
+
+ /**
+ * Generate a string readable version of this entry
+ *
+ * @return string representation of this constant pool entry
+ */
+ public String toString() {
+ return "Class Constant Pool Entry for " + className + "[" + index + "]";
+ }
+
+ /**
+ * Resolve this class info against the given constant pool.
+ *
+ * @param constantPool the constant pool with which to resolve the
+ * class.
+ */
+ public void resolve(ConstantPool constantPool) {
+ className = ((Utf8CPInfo) constantPool.getEntry(index)).getValue();
+
+ super.resolve(constantPool);
+ }
+
+ /**
+ * Get the class name of this entry.
+ *
+ * @return the class' name.
+ */
+ public String getClassName() {
+ return className;
+ }
+
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/ConstantCPInfo.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/ConstantCPInfo.java
new file mode 100644
index 00000000..6103422e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/ConstantCPInfo.java
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.depend.constantpool;
+
+/**
+ * A Constant Pool entry which represents a constant value.
+ *
+ */
+public abstract class ConstantCPInfo extends ConstantPoolEntry {
+
+ /**
+ * The entry's untyped value. Each subclass interprets the constant
+ * value based on the subclass's type. The value here must be
+ * compatible.
+ */
+ private Object value;
+
+ /**
+ * Initialise the constant entry.
+ *
+ * @param tagValue the constant pool entry type to be used.
+ * @param entries the number of constant pool entry slots occupied by
+ * this entry.
+ */
+ protected ConstantCPInfo(int tagValue, int entries) {
+ super(tagValue, entries);
+ }
+
+ /**
+ * Get the value of the constant.
+ *
+ * @return the value of the constant (untyped).
+ */
+ public Object getValue() {
+ return value;
+ }
+
+ /**
+ * Set the constant value.
+ *
+ * @param newValue the new untyped value of this constant.
+ */
+ public void setValue(Object newValue) {
+ value = newValue;
+ }
+
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/ConstantPool.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/ConstantPool.java
new file mode 100644
index 00000000..67d366b8
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/ConstantPool.java
@@ -0,0 +1,358 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.depend.constantpool;
+
+import java.io.DataInputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * The constant pool of a Java class. The constant pool is a collection of
+ * constants used in a Java class file. It stores strings, constant values,
+ * class names, method names, field names etc.
+ *
+ * @see <a href="http://java.sun.com/docs/books/vmspec/">The Java Virtual
+ * Machine Specification</a>
+ */
+public class ConstantPool {
+
+ /** The entries in the constant pool. */
+ private final List<ConstantPoolEntry> entries = new ArrayList<ConstantPoolEntry>();
+
+ /**
+ * A Hashtable of UTF8 entries - used to get constant pool indexes of
+ * the UTF8 values quickly
+ */
+ private final Map<String, Integer> utf8Indexes = new HashMap<String, Integer>();
+
+ /** Initialise the constant pool. */
+ public ConstantPool() {
+ // The zero index is never present in the constant pool itself so
+ // we add a null entry for it
+ entries.add(null);
+ }
+
+ /**
+ * Read the constant pool from a class input stream.
+ *
+ * @param classStream the DataInputStream of a class file.
+ * @exception IOException if there is a problem reading the constant pool
+ * from the stream
+ */
+ public void read(DataInputStream classStream) throws IOException {
+ int numEntries = classStream.readUnsignedShort();
+
+ for (int i = 1; i < numEntries;) {
+ ConstantPoolEntry nextEntry
+ = ConstantPoolEntry.readEntry(classStream);
+
+ i += nextEntry.getNumEntries();
+
+ addEntry(nextEntry);
+ }
+ }
+
+ /**
+ * Get the size of the constant pool.
+ *
+ * @return the size of the constant pool
+ */
+ public int size() {
+ return entries.size();
+ }
+
+ /**
+ * Add an entry to the constant pool.
+ *
+ * @param entry the new entry to be added to the constant pool.
+ * @return the index into the constant pool at which the entry is
+ * stored.
+ */
+ public int addEntry(ConstantPoolEntry entry) {
+ int index = entries.size();
+
+ entries.add(entry);
+
+ int numSlots = entry.getNumEntries();
+
+ // add null entries for any additional slots required.
+ for (int j = 0; j < numSlots - 1; ++j) {
+ entries.add(null);
+ }
+
+ if (entry instanceof Utf8CPInfo) {
+ Utf8CPInfo utf8Info = (Utf8CPInfo) entry;
+
+ utf8Indexes.put(utf8Info.getValue(), new Integer(index));
+ }
+
+ return index;
+ }
+
+ /**
+ * Resolve the entries in the constant pool. Resolution of the constant
+ * pool involves transforming indexes to other constant pool entries
+ * into the actual data for that entry.
+ */
+ public void resolve() {
+ for (ConstantPoolEntry poolInfo : entries) {
+ if (poolInfo != null && !poolInfo.isResolved()) {
+ poolInfo.resolve(this);
+ }
+ }
+ }
+
+
+ /**
+ * Get an constant pool entry at a particular index.
+ *
+ * @param index the index into the constant pool.
+ * @return the constant pool entry at that index.
+ */
+ public ConstantPoolEntry getEntry(int index) {
+ return entries.get(index);
+ }
+
+ /**
+ * Get the index of a given UTF8 constant pool entry.
+ *
+ * @param value the string value of the UTF8 entry.
+ * @return the index at which the given string occurs in the constant
+ * pool or -1 if the value does not occur.
+ */
+ public int getUTF8Entry(String value) {
+ int index = -1;
+ Integer indexInteger = utf8Indexes.get(value);
+
+ if (indexInteger != null) {
+ index = indexInteger.intValue();
+ }
+
+ return index;
+ }
+
+ /**
+ * Get the index of a given CONSTANT_CLASS entry in the constant pool.
+ *
+ * @param className the name of the class for which the class entry
+ * index is required.
+ * @return the index at which the given class entry occurs in the
+ * constant pool or -1 if the value does not occur.
+ */
+ public int getClassEntry(String className) {
+ int index = -1;
+
+ final int size = entries.size();
+ for (int i = 0; i < size && index == -1; ++i) {
+ Object element = entries.get(i);
+
+ if (element instanceof ClassCPInfo) {
+ ClassCPInfo classinfo = (ClassCPInfo) element;
+
+ if (classinfo.getClassName().equals(className)) {
+ index = i;
+ }
+ }
+ }
+
+ return index;
+ }
+
+ /**
+ * Get the index of a given constant value entry in the constant pool.
+ *
+ * @param constantValue the constant value for which the index is
+ * required.
+ * @return the index at which the given value entry occurs in the
+ * constant pool or -1 if the value does not occur.
+ */
+ public int getConstantEntry(Object constantValue) {
+ int index = -1;
+
+ final int size = entries.size();
+ for (int i = 0; i < size && index == -1; ++i) {
+ Object element = entries.get(i);
+
+ if (element instanceof ConstantCPInfo) {
+ ConstantCPInfo constantEntry = (ConstantCPInfo) element;
+
+ if (constantEntry.getValue().equals(constantValue)) {
+ index = i;
+ }
+ }
+ }
+
+ return index;
+ }
+
+ /**
+ * Get the index of a given CONSTANT_METHODREF entry in the constant
+ * pool.
+ *
+ * @param methodClassName the name of the class which contains the
+ * method being referenced.
+ * @param methodName the name of the method being referenced.
+ * @param methodType the type descriptor of the method being referenced.
+ * @return the index at which the given method ref entry occurs in the
+ * constant pool or -1 if the value does not occur.
+ */
+ public int getMethodRefEntry(String methodClassName, String methodName,
+ String methodType) {
+ int index = -1;
+
+ final int size = entries.size();
+ for (int i = 0; i < size && index == -1; ++i) {
+ Object element = entries.get(i);
+
+ if (element instanceof MethodRefCPInfo) {
+ MethodRefCPInfo methodRefEntry = (MethodRefCPInfo) element;
+
+ if (methodRefEntry.getMethodClassName().equals(methodClassName)
+ && methodRefEntry.getMethodName().equals(methodName)
+ && methodRefEntry.getMethodType().equals(methodType)) {
+ index = i;
+ }
+ }
+ }
+
+ return index;
+ }
+
+ /**
+ * Get the index of a given CONSTANT_INTERFACEMETHODREF entry in the
+ * constant pool.
+ *
+ * @param interfaceMethodClassName the name of the interface which
+ * contains the method being referenced.
+ * @param interfaceMethodName the name of the method being referenced.
+ * @param interfaceMethodType the type descriptor of the method being
+ * referenced.
+ * @return the index at which the given method ref entry occurs in the
+ * constant pool or -1 if the value does not occur.
+ */
+ public int getInterfaceMethodRefEntry(String interfaceMethodClassName,
+ String interfaceMethodName,
+ String interfaceMethodType) {
+ int index = -1;
+
+ final int size = entries.size();
+ for (int i = 0; i < size && index == -1; ++i) {
+ Object element = entries.get(i);
+
+ if (element instanceof InterfaceMethodRefCPInfo) {
+ InterfaceMethodRefCPInfo interfaceMethodRefEntry
+ = (InterfaceMethodRefCPInfo) element;
+
+ if (interfaceMethodRefEntry.getInterfaceMethodClassName().equals(
+ interfaceMethodClassName)
+ && interfaceMethodRefEntry.getInterfaceMethodName().equals(
+ interfaceMethodName)
+ && interfaceMethodRefEntry.getInterfaceMethodType().equals(
+ interfaceMethodType)) {
+ index = i;
+ }
+ }
+ }
+
+ return index;
+ }
+
+ /**
+ * Get the index of a given CONSTANT_FIELDREF entry in the constant
+ * pool.
+ *
+ * @param fieldClassName the name of the class which contains the field
+ * being referenced.
+ * @param fieldName the name of the field being referenced.
+ * @param fieldType the type descriptor of the field being referenced.
+ * @return the index at which the given field ref entry occurs in the
+ * constant pool or -1 if the value does not occur.
+ */
+ public int getFieldRefEntry(String fieldClassName, String fieldName,
+ String fieldType) {
+ int index = -1;
+
+ final int size = entries.size();
+ for (int i = 0; i < size && index == -1; ++i) {
+ Object element = entries.get(i);
+
+ if (element instanceof FieldRefCPInfo) {
+ FieldRefCPInfo fieldRefEntry = (FieldRefCPInfo) element;
+
+ if (fieldRefEntry.getFieldClassName().equals(fieldClassName)
+ && fieldRefEntry.getFieldName().equals(fieldName)
+ && fieldRefEntry.getFieldType().equals(fieldType)) {
+ index = i;
+ }
+ }
+ }
+
+ return index;
+ }
+
+ /**
+ * Get the index of a given CONSTANT_NAMEANDTYPE entry in the constant
+ * pool.
+ *
+ * @param name the name
+ * @param type the type
+ * @return the index at which the given NameAndType entry occurs in the
+ * constant pool or -1 if the value does not occur.
+ */
+ public int getNameAndTypeEntry(String name, String type) {
+ int index = -1;
+
+ final int size = entries.size();
+ for (int i = 0; i < size && index == -1; ++i) {
+ Object element = entries.get(i);
+
+ if (element instanceof NameAndTypeCPInfo) {
+ NameAndTypeCPInfo nameAndTypeEntry
+ = (NameAndTypeCPInfo) element;
+
+ if (nameAndTypeEntry.getName().equals(name)
+ && nameAndTypeEntry.getType().equals(type)) {
+ index = i;
+ }
+ }
+ }
+
+ return index;
+ }
+
+ /**
+ * Dump the constant pool to a string.
+ *
+ * @return the constant pool entries as strings
+ */
+ public String toString() {
+ StringBuilder sb = new StringBuilder("\n");
+ final int size = entries.size();
+
+ for (int i = 0; i < size; ++i) {
+ sb.append("[" + i + "] = " + getEntry(i) + "\n");
+ }
+
+ return sb.toString();
+ }
+
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/ConstantPoolEntry.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/ConstantPoolEntry.java
new file mode 100644
index 00000000..26a0d094
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/ConstantPoolEntry.java
@@ -0,0 +1,242 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.depend.constantpool;
+
+import java.io.DataInputStream;
+import java.io.IOException;
+
+/**
+ * An entry in the constant pool. This class contains a representation of the
+ * constant pool entries. It is an abstract base class for all the different
+ * forms of constant pool entry.
+ *
+ * @see ConstantPool
+ */
+public abstract class ConstantPoolEntry {
+
+ /** Tag value for UTF8 entries. */
+ public static final int CONSTANT_UTF8 = 1;
+
+ /** Tag value for Integer entries. */
+ public static final int CONSTANT_INTEGER = 3;
+
+ /** Tag value for Float entries. */
+ public static final int CONSTANT_FLOAT = 4;
+
+ /** Tag value for Long entries. */
+ public static final int CONSTANT_LONG = 5;
+
+ /** Tag value for Double entries. */
+ public static final int CONSTANT_DOUBLE = 6;
+
+ /** Tag value for Class entries. */
+ public static final int CONSTANT_CLASS = 7;
+
+ /** Tag value for String entries. */
+ public static final int CONSTANT_STRING = 8;
+
+ /** Tag value for Field Reference entries. */
+ public static final int CONSTANT_FIELDREF = 9;
+
+ /** Tag value for Method Reference entries. */
+ public static final int CONSTANT_METHODREF = 10;
+
+ /** Tag value for Interface Method Reference entries. */
+ public static final int CONSTANT_INTERFACEMETHODREF = 11;
+
+ /** Tag value for Name and Type entries. */
+ public static final int CONSTANT_NAMEANDTYPE = 12;
+
+ /** Tag value for Method Handle entries */
+ public static final int CONSTANT_METHODHANDLE = 15;
+
+ /** Tag value for Method Type entries */
+ public static final int CONSTANT_METHODTYPE = 16;
+
+ /** Tag value for InvokeDynamic entries*/
+ public static final int CONSTANT_INVOKEDYNAMIC = 18;
+
+ /**
+ * This entry's tag which identifies the type of this constant pool
+ * entry.
+ */
+ private int tag;
+
+ /**
+ * The number of slots in the constant pool, occupied by this entry.
+ */
+ private int numEntries;
+
+ /**
+ * A flag which indicates if this entry has been resolved or not.
+ */
+ private boolean resolved;
+
+ /**
+ * Initialise the constant pool entry.
+ *
+ * @param tagValue the tag value which identifies which type of constant
+ * pool entry this is.
+ * @param entries the number of constant pool entry slots this entry
+ * occupies.
+ */
+ public ConstantPoolEntry(int tagValue, int entries) {
+ tag = tagValue;
+ numEntries = entries;
+ resolved = false;
+ }
+
+ /**
+ * Read a constant pool entry from a stream. This is a factory method
+ * which reads a constant pool entry form a stream and returns the
+ * appropriate subclass for the entry.
+ *
+ * @param cpStream the stream from which the constant pool entry is to
+ * be read.
+ * @return the appropriate ConstantPoolEntry subclass representing the
+ * constant pool entry from the stream.
+ * @exception IOException if the constant pool entry cannot be read
+ * from the stream
+ */
+ public static ConstantPoolEntry readEntry(DataInputStream cpStream)
+ throws IOException {
+ ConstantPoolEntry cpInfo = null;
+ int cpTag = cpStream.readUnsignedByte();
+
+ switch (cpTag) {
+
+ case CONSTANT_UTF8:
+ cpInfo = new Utf8CPInfo();
+
+ break;
+ case CONSTANT_INTEGER:
+ cpInfo = new IntegerCPInfo();
+
+ break;
+ case CONSTANT_FLOAT:
+ cpInfo = new FloatCPInfo();
+
+ break;
+ case CONSTANT_LONG:
+ cpInfo = new LongCPInfo();
+
+ break;
+ case CONSTANT_DOUBLE:
+ cpInfo = new DoubleCPInfo();
+
+ break;
+ case CONSTANT_CLASS:
+ cpInfo = new ClassCPInfo();
+
+ break;
+ case CONSTANT_STRING:
+ cpInfo = new StringCPInfo();
+
+ break;
+ case CONSTANT_FIELDREF:
+ cpInfo = new FieldRefCPInfo();
+
+ break;
+ case CONSTANT_METHODREF:
+ cpInfo = new MethodRefCPInfo();
+
+ break;
+ case CONSTANT_INTERFACEMETHODREF:
+ cpInfo = new InterfaceMethodRefCPInfo();
+
+ break;
+ case CONSTANT_NAMEANDTYPE:
+ cpInfo = new NameAndTypeCPInfo();
+
+ break;
+ case CONSTANT_METHODHANDLE:
+ cpInfo = new MethodHandleCPInfo();
+
+ break;
+ case CONSTANT_METHODTYPE:
+ cpInfo = new MethodTypeCPInfo();
+
+ break;
+ case CONSTANT_INVOKEDYNAMIC:
+ cpInfo = new InvokeDynamicCPInfo();
+
+ break;
+ default:
+ throw new ClassFormatError("Invalid Constant Pool entry Type "
+ + cpTag);
+ }
+
+ cpInfo.read(cpStream);
+
+ return cpInfo;
+ }
+
+ /**
+ * Indicates whether this entry has been resolved. In general a constant
+ * pool entry can reference another constant pool entry by its index
+ * value. Resolution involves replacing this index value with the
+ * constant pool entry at that index.
+ *
+ * @return true if this entry has been resolved.
+ */
+ public boolean isResolved() {
+ return resolved;
+ }
+
+ /**
+ * Resolve this constant pool entry with respect to its dependents in
+ * the constant pool.
+ *
+ * @param constantPool the constant pool of which this entry is a member
+ * and against which this entry is to be resolved.
+ */
+ public void resolve(ConstantPool constantPool) {
+ resolved = true;
+ }
+
+ /**
+ * read a constant pool entry from a class stream.
+ *
+ * @param cpStream the DataInputStream which contains the constant pool
+ * entry to be read.
+ * @exception IOException if there is a problem reading the entry from
+ * the stream.
+ */
+ public abstract void read(DataInputStream cpStream) throws IOException;
+
+ /**
+ * Get the Entry's type tag.
+ *
+ * @return The Tag value of this entry
+ */
+ public int getTag() {
+ return tag;
+ }
+
+ /**
+ * Get the number of Constant Pool Entry slots within the constant pool
+ * occupied by this entry.
+ *
+ * @return the number of slots used.
+ */
+ public final int getNumEntries() {
+ return numEntries;
+ }
+
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/DoubleCPInfo.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/DoubleCPInfo.java
new file mode 100644
index 00000000..a21c0d66
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/DoubleCPInfo.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.depend.constantpool;
+
+import java.io.DataInputStream;
+import java.io.IOException;
+
+/**
+ * The constant pool entry subclass used to represent double constant
+ * values.
+ *
+ */
+public class DoubleCPInfo extends ConstantCPInfo {
+ /**
+ * Constructor
+ */
+ public DoubleCPInfo() {
+ super(CONSTANT_DOUBLE, 2);
+ }
+
+ /**
+ * read a constant pool entry from a class stream.
+ *
+ * @param cpStream the DataInputStream which contains the constant pool
+ * entry to be read.
+ * @exception IOException if there is a problem reading the entry from the
+ * stream.
+ */
+ public void read(DataInputStream cpStream) throws IOException {
+ setValue(new Double(cpStream.readDouble()));
+ }
+
+ /**
+ * Print a readable version of the constant pool entry.
+ *
+ * @return the string representation of this constant pool entry.
+ */
+ public String toString() {
+ return "Double Constant Pool Entry: " + getValue();
+ }
+
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/FieldRefCPInfo.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/FieldRefCPInfo.java
new file mode 100644
index 00000000..06c0925d
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/FieldRefCPInfo.java
@@ -0,0 +1,130 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.depend.constantpool;
+
+import java.io.DataInputStream;
+import java.io.IOException;
+
+/**
+ * A FieldRef CP Info
+ *
+ */
+public class FieldRefCPInfo extends ConstantPoolEntry {
+ /** Name of the field's class */
+ private String fieldClassName;
+ /** name of the field in that class */
+ private String fieldName;
+ /** The type of the field */
+ private String fieldType;
+ /** Index into the constant pool for the class */
+ private int classIndex;
+ /** Index into the constant pool for the name and type entry */
+ private int nameAndTypeIndex;
+
+ /** Constructor. */
+ public FieldRefCPInfo() {
+ super(CONSTANT_FIELDREF, 1);
+ }
+
+ /**
+ * read a constant pool entry from a class stream.
+ *
+ * @param cpStream the DataInputStream which contains the constant pool
+ * entry to be read.
+ * @exception IOException if there is a problem reading the entry from
+ * the stream.
+ */
+ public void read(DataInputStream cpStream) throws IOException {
+ classIndex = cpStream.readUnsignedShort();
+ nameAndTypeIndex = cpStream.readUnsignedShort();
+ }
+
+ /**
+ * Resolve this constant pool entry with respect to its dependents in
+ * the constant pool.
+ *
+ * @param constantPool the constant pool of which this entry is a member
+ * and against which this entry is to be resolved.
+ */
+ public void resolve(ConstantPool constantPool) {
+ ClassCPInfo fieldClass
+ = (ClassCPInfo) constantPool.getEntry(classIndex);
+
+ fieldClass.resolve(constantPool);
+
+ fieldClassName = fieldClass.getClassName();
+
+ NameAndTypeCPInfo nt
+ = (NameAndTypeCPInfo) constantPool.getEntry(nameAndTypeIndex);
+
+ nt.resolve(constantPool);
+
+ fieldName = nt.getName();
+ fieldType = nt.getType();
+
+ super.resolve(constantPool);
+ }
+
+ /**
+ * Print a readable version of the constant pool entry.
+ *
+ * @return the string representation of this constant pool entry.
+ */
+ public String toString() {
+ String value;
+
+ if (isResolved()) {
+ value = "Field : Class = " + fieldClassName + ", name = "
+ + fieldName + ", type = " + fieldType;
+ } else {
+ value = "Field : Class index = " + classIndex
+ + ", name and type index = " + nameAndTypeIndex;
+ }
+
+ return value;
+ }
+
+ /**
+ * Gets the name of the class defining the field
+ *
+ * @return the name of the class defining the field
+ */
+ public String getFieldClassName() {
+ return fieldClassName;
+ }
+
+ /**
+ * Get the name of the field
+ *
+ * @return the field's name
+ */
+ public String getFieldName() {
+ return fieldName;
+ }
+
+ /**
+ * Get the type of the field
+ *
+ * @return the field's type in string format
+ */
+ public String getFieldType() {
+ return fieldType;
+ }
+
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/FloatCPInfo.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/FloatCPInfo.java
new file mode 100644
index 00000000..532b6725
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/FloatCPInfo.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.depend.constantpool;
+
+import java.io.DataInputStream;
+import java.io.IOException;
+
+/**
+ * A Float CP Info
+ *
+ */
+public class FloatCPInfo extends ConstantCPInfo {
+
+ /** Constructor. */
+ public FloatCPInfo() {
+ super(CONSTANT_FLOAT, 1);
+ }
+
+ /**
+ * read a constant pool entry from a class stream.
+ *
+ * @param cpStream the DataInputStream which contains the constant pool
+ * entry to be read.
+ * @exception IOException if there is a problem reading the entry from
+ * the stream.
+ */
+ public void read(DataInputStream cpStream) throws IOException {
+ setValue(new Float(cpStream.readFloat()));
+ }
+
+ /**
+ * Print a readable version of the constant pool entry.
+ *
+ * @return the string representation of this constant pool entry.
+ */
+ public String toString() {
+ return "Float Constant Pool Entry: " + getValue();
+ }
+
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/IntegerCPInfo.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/IntegerCPInfo.java
new file mode 100644
index 00000000..3beaa8cd
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/IntegerCPInfo.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.depend.constantpool;
+
+import java.io.DataInputStream;
+import java.io.IOException;
+
+/**
+ * An Integer CP Info
+ *
+ */
+public class IntegerCPInfo extends ConstantCPInfo {
+
+ /** Constructor. */
+ public IntegerCPInfo() {
+ super(CONSTANT_INTEGER, 1);
+ }
+
+ /**
+ * read a constant pool entry from a class stream.
+ *
+ * @param cpStream the DataInputStream which contains the constant pool
+ * entry to be read.
+ * @exception IOException if there is a problem reading the entry from
+ * the stream.
+ */
+ public void read(DataInputStream cpStream) throws IOException {
+ setValue(new Integer(cpStream.readInt()));
+ }
+
+ /**
+ * Print a readable version of the constant pool entry.
+ *
+ * @return the string representation of this constant pool entry.
+ */
+ public String toString() {
+ return "Integer Constant Pool Entry: " + getValue();
+ }
+
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/InterfaceMethodRefCPInfo.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/InterfaceMethodRefCPInfo.java
new file mode 100644
index 00000000..fbc23c1c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/InterfaceMethodRefCPInfo.java
@@ -0,0 +1,137 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.depend.constantpool;
+
+import java.io.DataInputStream;
+import java.io.IOException;
+
+/**
+ * A InterfaceMethodRef CP Info
+ *
+ */
+public class InterfaceMethodRefCPInfo extends ConstantPoolEntry {
+ /** the class name of the class defining the interface method */
+ private String interfaceMethodClassName;
+ /** the name of the interface nmethod */
+ private String interfaceMethodName;
+ /** the method signature of the interface method */
+ private String interfaceMethodType;
+ /**
+ * the index into the constant pool of the class entry for the interface
+ * class
+ */
+ private int classIndex;
+ /**
+ * the index into the constant pool of the name and type entry
+ * describing the method
+ */
+ private int nameAndTypeIndex;
+
+ /** Constructor. */
+ public InterfaceMethodRefCPInfo() {
+ super(CONSTANT_INTERFACEMETHODREF, 1);
+ }
+
+ /**
+ * read a constant pool entry from a class stream.
+ *
+ * @param cpStream the DataInputStream which contains the constant pool
+ * entry to be read.
+ * @exception IOException if there is a problem reading the entry from
+ * the stream.
+ */
+ public void read(DataInputStream cpStream) throws IOException {
+ classIndex = cpStream.readUnsignedShort();
+ nameAndTypeIndex = cpStream.readUnsignedShort();
+ }
+
+ /**
+ * Resolve this constant pool entry with respect to its dependents in
+ * the constant pool.
+ *
+ * @param constantPool the constant pool of which this entry is a member
+ * and against which this entry is to be resolved.
+ */
+ public void resolve(ConstantPool constantPool) {
+ ClassCPInfo interfaceMethodClass
+ = (ClassCPInfo) constantPool.getEntry(classIndex);
+
+ interfaceMethodClass.resolve(constantPool);
+
+ interfaceMethodClassName = interfaceMethodClass.getClassName();
+
+ NameAndTypeCPInfo nt
+ = (NameAndTypeCPInfo) constantPool.getEntry(nameAndTypeIndex);
+
+ nt.resolve(constantPool);
+
+ interfaceMethodName = nt.getName();
+ interfaceMethodType = nt.getType();
+
+ super.resolve(constantPool);
+ }
+
+ /**
+ * Print a readable version of the constant pool entry.
+ *
+ * @return the string representation of this constant pool entry.
+ */
+ public String toString() {
+ String value;
+
+ if (isResolved()) {
+ value = "InterfaceMethod : Class = " + interfaceMethodClassName
+ + ", name = " + interfaceMethodName + ", type = "
+ + interfaceMethodType;
+ } else {
+ value = "InterfaceMethod : Class index = " + classIndex
+ + ", name and type index = " + nameAndTypeIndex;
+ }
+
+ return value;
+ }
+
+ /**
+ * Gets the name of the class defining the interface method
+ *
+ * @return the name of the class defining the interface method
+ */
+ public String getInterfaceMethodClassName() {
+ return interfaceMethodClassName;
+ }
+
+ /**
+ * Get the name of the interface method
+ *
+ * @return the name of the interface method
+ */
+ public String getInterfaceMethodName() {
+ return interfaceMethodName;
+ }
+
+ /**
+ * Gets the type of the interface method
+ *
+ * @return the interface method's type signature
+ */
+ public String getInterfaceMethodType() {
+ return interfaceMethodType;
+ }
+
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/InvokeDynamicCPInfo.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/InvokeDynamicCPInfo.java
new file mode 100644
index 00000000..3795db75
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/InvokeDynamicCPInfo.java
@@ -0,0 +1,85 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.depend.constantpool;
+
+import java.io.DataInputStream;
+import java.io.IOException;
+
+/**
+ * An InvokeDynamic CP Info
+ *
+ */
+public class InvokeDynamicCPInfo extends ConstantCPInfo {
+
+ /** Index into the bootstrap methods for the class */
+ private int bootstrapMethodAttrIndex;
+ /** the value of the method descriptor pointed to */
+ private int nameAndTypeIndex;
+ /** the name and type CP info pointed to */
+ private NameAndTypeCPInfo nameAndTypeCPInfo;
+ /** */
+ /** Constructor. */
+ public InvokeDynamicCPInfo() {
+ super(CONSTANT_INVOKEDYNAMIC, 1);
+ }
+
+ /**
+ * read a constant pool entry from a class stream.
+ *
+ * @param cpStream the DataInputStream which contains the constant pool
+ * entry to be read.
+ * @exception java.io.IOException if there is a problem reading the entry from
+ * the stream.
+ */
+ public void read(DataInputStream cpStream) throws IOException {
+ bootstrapMethodAttrIndex = cpStream.readUnsignedShort();
+ nameAndTypeIndex = cpStream.readUnsignedShort();
+ }
+
+ /**
+ * Print a readable version of the constant pool entry.
+ *
+ * @return the string representation of this constant pool entry.
+ */
+ public String toString() {
+ String value;
+ if (isResolved()) {
+ value = "Name = " + nameAndTypeCPInfo.getName() + ", type = " + nameAndTypeCPInfo.getType();
+ } else {
+ value = "BootstrapMethodAttrIndex inx = " + bootstrapMethodAttrIndex
+ + "NameAndType index = " + nameAndTypeIndex;
+ }
+
+ return value;
+ }
+ /**
+ * Resolve this constant pool entry with respect to its dependents in
+ * the constant pool.
+ *
+ * @param constantPool the constant pool of which this entry is a member
+ * and against which this entry is to be resolved.
+ */
+ public void resolve(ConstantPool constantPool) {
+ nameAndTypeCPInfo
+ = (NameAndTypeCPInfo) constantPool.getEntry(nameAndTypeIndex);
+ nameAndTypeCPInfo.resolve(constantPool);
+ super.resolve(constantPool);
+ }
+
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/LongCPInfo.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/LongCPInfo.java
new file mode 100644
index 00000000..e854f04f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/LongCPInfo.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.depend.constantpool;
+
+import java.io.DataInputStream;
+import java.io.IOException;
+
+/**
+ * A Long CP Info
+ *
+ */
+public class LongCPInfo extends ConstantCPInfo {
+
+ /** Constructor. */
+ public LongCPInfo() {
+ super(CONSTANT_LONG, 2);
+ }
+
+ /**
+ * read a constant pool entry from a class stream.
+ *
+ * @param cpStream the DataInputStream which contains the constant pool
+ * entry to be read.
+ * @exception IOException if there is a problem reading the entry from
+ * the stream.
+ */
+ public void read(DataInputStream cpStream) throws IOException {
+ setValue(new Long(cpStream.readLong()));
+ }
+
+ /**
+ * Print a readable version of the constant pool entry.
+ *
+ * @return the string representation of this constant pool entry.
+ */
+ public String toString() {
+ return "Long Constant Pool Entry: " + getValue();
+ }
+
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/MethodHandleCPInfo.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/MethodHandleCPInfo.java
new file mode 100644
index 00000000..e11e3aab
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/MethodHandleCPInfo.java
@@ -0,0 +1,107 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.depend.constantpool;
+
+import java.io.DataInputStream;
+import java.io.IOException;
+
+/**
+ * A MethodHandle CP Info
+ *
+ */
+public class MethodHandleCPInfo extends ConstantPoolEntry {
+ private ConstantPoolEntry reference;
+
+ /** reference kind **/
+ private ReferenceKind referenceKind;
+ /** Must be a valid index into the constant pool tabel. */
+ private int referenceIndex;
+ /**
+ * the index into the constant pool which defined the name and type
+ * signature of the method
+ */
+ private int nameAndTypeIndex;
+ public enum ReferenceKind {
+ REF_getField(1),
+ REF_getStatic(2),
+ REF_putField(3),
+ REF_putStatic(4),
+ REF_invokeVirtual(5),
+ REF_invokeStatic(6),
+ REF_invokeSpecial(7),
+ REF_newInvokeSpecial(8),
+ REF_invokeInterface(9);
+ private final int referenceKind;
+ ReferenceKind(int referenceKind) {
+ this.referenceKind = referenceKind;
+ }
+
+ }
+ /** Constructor. */
+ public MethodHandleCPInfo() {
+ super(CONSTANT_METHODHANDLE, 1);
+ }
+
+ /**
+ * read a constant pool entry from a class stream.
+ *
+ * @param cpStream the DataInputStream which contains the constant pool
+ * entry to be read.
+ * @exception java.io.IOException if there is a problem reading the entry from
+ * the stream.
+ */
+ public void read(DataInputStream cpStream) throws IOException {
+ referenceKind = ReferenceKind.values()[cpStream.readUnsignedByte() - 1];
+
+ referenceIndex = cpStream.readUnsignedShort();
+ }
+
+ /**
+ * Print a readable version of the constant pool entry.
+ *
+ * @return the string representation of this constant pool entry.
+ */
+ public String toString() {
+ String value;
+
+ if (isResolved()) {
+ value = "MethodHandle : " + reference.toString();
+ } else {
+ value = "MethodHandle : Reference kind = " + referenceKind
+ + "Reference index = " + referenceIndex;
+ }
+
+ return value;
+ }
+
+ /**
+ * Resolve this constant pool entry with respect to its dependents in
+ * the constant pool.
+ *
+ * @param constantPool the constant pool of which this entry is a member
+ * and against which this entry is to be resolved.
+ */
+ public void resolve(ConstantPool constantPool) {
+ reference = constantPool.getEntry(referenceIndex);
+ reference.resolve(constantPool);
+ super.resolve(constantPool);
+ }
+
+
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/MethodRefCPInfo.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/MethodRefCPInfo.java
new file mode 100644
index 00000000..6b335212
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/MethodRefCPInfo.java
@@ -0,0 +1,133 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.depend.constantpool;
+
+import java.io.DataInputStream;
+import java.io.IOException;
+
+/**
+ * A MethodRef CP Info
+ *
+ */
+public class MethodRefCPInfo extends ConstantPoolEntry {
+ /** the name of the class defining this method */
+ private String methodClassName;
+ /** the name of the method */
+ private String methodName;
+ /** the method's type descriptor */
+ private String methodType;
+ /** The index into the constant pool which defines the class of this method. */
+ private int classIndex;
+ /**
+ * the index into the constant pool which defined the name and type
+ * signature of the method
+ */
+ private int nameAndTypeIndex;
+
+ /** Constructor. */
+ public MethodRefCPInfo() {
+ super(CONSTANT_METHODREF, 1);
+ }
+
+ /**
+ * read a constant pool entry from a class stream.
+ *
+ * @param cpStream the DataInputStream which contains the constant pool
+ * entry to be read.
+ * @exception IOException if there is a problem reading the entry from
+ * the stream.
+ */
+ public void read(DataInputStream cpStream) throws IOException {
+ classIndex = cpStream.readUnsignedShort();
+ nameAndTypeIndex = cpStream.readUnsignedShort();
+ }
+
+ /**
+ * Print a readable version of the constant pool entry.
+ *
+ * @return the string representation of this constant pool entry.
+ */
+ public String toString() {
+ String value;
+
+ if (isResolved()) {
+ value = "Method : Class = " + methodClassName + ", name = "
+ + methodName + ", type = " + methodType;
+ } else {
+ value = "Method : Class index = " + classIndex
+ + ", name and type index = " + nameAndTypeIndex;
+ }
+
+ return value;
+ }
+
+ /**
+ * Resolve this constant pool entry with respect to its dependents in
+ * the constant pool.
+ *
+ * @param constantPool the constant pool of which this entry is a member
+ * and against which this entry is to be resolved.
+ */
+ public void resolve(ConstantPool constantPool) {
+ ClassCPInfo methodClass
+ = (ClassCPInfo) constantPool.getEntry(classIndex);
+
+ methodClass.resolve(constantPool);
+
+ methodClassName = methodClass.getClassName();
+
+ NameAndTypeCPInfo nt
+ = (NameAndTypeCPInfo) constantPool.getEntry(nameAndTypeIndex);
+
+ nt.resolve(constantPool);
+
+ methodName = nt.getName();
+ methodType = nt.getType();
+
+ super.resolve(constantPool);
+ }
+
+ /**
+ * Get the name of the class defining the method
+ *
+ * @return the name of the class defining this method
+ */
+ public String getMethodClassName() {
+ return methodClassName;
+ }
+
+ /**
+ * Get the name of the method.
+ *
+ * @return the name of the method.
+ */
+ public String getMethodName() {
+ return methodName;
+ }
+
+ /**
+ * Get the type signature of the method.
+ *
+ * @return the type signature of the method.
+ */
+ public String getMethodType() {
+ return methodType;
+ }
+
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/MethodTypeCPInfo.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/MethodTypeCPInfo.java
new file mode 100644
index 00000000..d3c35cee
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/MethodTypeCPInfo.java
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.depend.constantpool;
+
+import java.io.DataInputStream;
+import java.io.IOException;
+
+/**
+ * A Method Type CP Info
+ *
+ */
+public class MethodTypeCPInfo extends ConstantCPInfo {
+
+ /** Index into the constant pool for the class */
+ private int methodDescriptorIndex;
+ /** the value of the method descriptor pointed to */
+ private String methodDescriptor;
+ /** Constructor. */
+ public MethodTypeCPInfo() {
+ super(CONSTANT_METHODTYPE, 1);
+ }
+
+ /**
+ * read a constant pool entry from a class stream.
+ *
+ * @param cpStream the DataInputStream which contains the constant pool
+ * entry to be read.
+ * @exception java.io.IOException if there is a problem reading the entry from
+ * the stream.
+ */
+ @Override
+ public void read(final DataInputStream cpStream) throws IOException {
+ methodDescriptorIndex = cpStream.readUnsignedShort();
+ }
+
+ /**
+ * Resolve this constant pool entry with respect to its dependents in
+ * the constant pool.
+ *
+ * @param constantPool the constant pool of which this entry is a member
+ * and against which this entry is to be resolved.
+ */
+ @Override
+ public void resolve(final ConstantPool constantPool) {
+ final Utf8CPInfo methodClass
+ = (Utf8CPInfo) constantPool.getEntry(methodDescriptorIndex);
+ methodClass.resolve(constantPool);
+ methodDescriptor = methodClass.getValue();
+ super.resolve(constantPool);
+ }
+ /**
+ * Print a readable version of the constant pool entry.
+ *
+ * @return the string representation of this constant pool entry.
+ */
+ @Override
+ public String toString() {
+ if (!isResolved()) {
+ return "MethodDescriptorIndex: " + methodDescriptorIndex;
+ } else {
+ return "MethodDescriptor: " + methodDescriptor;
+
+ }
+ }
+
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/NameAndTypeCPInfo.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/NameAndTypeCPInfo.java
new file mode 100644
index 00000000..47f454d2
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/NameAndTypeCPInfo.java
@@ -0,0 +1,112 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.depend.constantpool;
+
+import java.io.DataInputStream;
+import java.io.IOException;
+
+/**
+ * A NameAndType CP Info
+ *
+ */
+public class NameAndTypeCPInfo extends ConstantPoolEntry {
+
+ /** Constructor. */
+ public NameAndTypeCPInfo() {
+ super(CONSTANT_NAMEANDTYPE, 1);
+ }
+
+ /**
+ * read a constant pool entry from a class stream.
+ *
+ * @param cpStream the DataInputStream which contains the constant pool
+ * entry to be read.
+ * @exception IOException if there is a problem reading the entry from
+ * the stream.
+ */
+ public void read(DataInputStream cpStream) throws IOException {
+ nameIndex = cpStream.readUnsignedShort();
+ descriptorIndex = cpStream.readUnsignedShort();
+ }
+
+ /**
+ * Print a readable version of the constant pool entry.
+ *
+ * @return the string representation of this constant pool entry.
+ */
+ public String toString() {
+ String value;
+
+ if (isResolved()) {
+ value = "Name = " + name + ", type = " + type;
+ } else {
+ value = "Name index = " + nameIndex
+ + ", descriptor index = " + descriptorIndex;
+ }
+
+ return value;
+ }
+
+ /**
+ * Resolve this constant pool entry with respect to its dependents in
+ * the constant pool.
+ *
+ * @param constantPool the constant pool of which this entry is a member
+ * and against which this entry is to be resolved.
+ */
+ public void resolve(ConstantPool constantPool) {
+ name = ((Utf8CPInfo) constantPool.getEntry(nameIndex)).getValue();
+ type = ((Utf8CPInfo) constantPool.getEntry(descriptorIndex)).getValue();
+
+ super.resolve(constantPool);
+ }
+
+ /**
+ * Get the name component of this entry
+ *
+ * @return the name of this name and type entry
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Get the type signature of this entry
+ *
+ * @return the type signature of this entry
+ */
+ public String getType() {
+ return type;
+ }
+
+ /** the name component of this entry */
+ private String name;
+ /** the type component of this entry */
+ private String type;
+ /**
+ * the index into the constant pool at which the name component's string
+ * value is stored
+ */
+ private int nameIndex;
+ /**
+ * the index into the constant pool where the type descriptor string is
+ * stored.
+ */
+ private int descriptorIndex;
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/StringCPInfo.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/StringCPInfo.java
new file mode 100644
index 00000000..bc9ee24b
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/StringCPInfo.java
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.depend.constantpool;
+
+import java.io.DataInputStream;
+import java.io.IOException;
+
+/**
+ * A String Constant Pool Entry. The String info contains an index into the
+ * constant pool where a UTF8 string is stored.
+ *
+ */
+public class StringCPInfo extends ConstantCPInfo {
+
+ /** Constructor. */
+ public StringCPInfo() {
+ super(CONSTANT_STRING, 1);
+ }
+
+ /**
+ * read a constant pool entry from a class stream.
+ *
+ * @param cpStream the DataInputStream which contains the constant pool
+ * entry to be read.
+ * @exception IOException if there is a problem reading the entry from
+ * the stream.
+ */
+ public void read(DataInputStream cpStream) throws IOException {
+ index = cpStream.readUnsignedShort();
+
+ setValue("unresolved");
+ }
+
+ /**
+ * Print a readable version of the constant pool entry.
+ *
+ * @return the string representation of this constant pool entry.
+ */
+ public String toString() {
+ return "String Constant Pool Entry for "
+ + getValue() + "[" + index + "]";
+ }
+
+ /**
+ * Resolve this constant pool entry with respect to its dependents in
+ * the constant pool.
+ *
+ * @param constantPool the constant pool of which this entry is a member
+ * and against which this entry is to be resolved.
+ */
+ public void resolve(ConstantPool constantPool) {
+ setValue(((Utf8CPInfo) constantPool.getEntry(index)).getValue());
+ super.resolve(constantPool);
+ }
+
+ /** the index into the constant pool containing the string's content */
+ private int index;
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/Utf8CPInfo.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/Utf8CPInfo.java
new file mode 100644
index 00000000..5471ccde
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/depend/constantpool/Utf8CPInfo.java
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.depend.constantpool;
+
+import java.io.DataInputStream;
+import java.io.IOException;
+
+/**
+ * A UTF8 Constant Pool Entry.
+ *
+ */
+public class Utf8CPInfo extends ConstantPoolEntry {
+ /** The String value of the UTF-8 entry */
+ private String value;
+
+ /** Constructor. */
+ public Utf8CPInfo() {
+ super(CONSTANT_UTF8, 1);
+ }
+
+ /**
+ * read a constant pool entry from a class stream.
+ *
+ * @param cpStream the DataInputStream which contains the constant pool
+ * entry to be read.
+ * @exception IOException if there is a problem reading the entry from
+ * the stream.
+ */
+ public void read(DataInputStream cpStream) throws IOException {
+ value = cpStream.readUTF();
+ }
+
+ /**
+ * Print a readable version of the constant pool entry.
+ *
+ * @return the string representation of this constant pool entry.
+ */
+ public String toString() {
+ return "UTF8 Value = " + value;
+ }
+
+ /**
+ * Get the string value of the UTF-8 entry
+ *
+ * @return the UTF-8 value as a Java string
+ */
+ public String getValue() {
+ return value;
+ }
+
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ejb/BorlandDeploymentTool.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ejb/BorlandDeploymentTool.java
new file mode 100644
index 00000000..4eefaebf
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ejb/BorlandDeploymentTool.java
@@ -0,0 +1,559 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+
+package org.apache.tools.ant.taskdefs.optional.ejb;
+
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.ExecTask;
+import org.apache.tools.ant.taskdefs.Execute;
+import org.apache.tools.ant.taskdefs.ExecuteStreamHandler;
+import org.apache.tools.ant.taskdefs.Java;
+import org.apache.tools.ant.types.Commandline;
+import org.apache.tools.ant.types.Path;
+
+
+/**
+ * BorlandDeploymentTool is dedicated to the Borland Application Server 4.5 and 4.5.1
+ * This task generates and compiles the stubs and skeletons for all ejb described into the
+ * Deployment Descriptor, builds the jar file including the support files and verify
+ * whether the produced jar is valid or not.
+ * The supported options are:
+ * <ul>
+ * <li>debug (boolean) : turn on the debug mode for generation of
+ * stubs and skeletons (default:false)</li>
+ * <li>verify (boolean) : turn on the verification at the end of the jar
+ * production (default:true) </li>
+ * <li>verifyargs (String) : add optional argument to verify command
+ * (see vbj com.inprise.ejb.util.Verify)</li>
+ * <li>basdtd (String) : location of the BAS DTD </li>
+ * <li>generateclient (boolean) : turn on the client jar file generation </li>
+ * <li>version (int) : tell what is the Borland appserver version 4 or 5 </li>
+ * </ul>
+ *
+ *<PRE>
+ *
+ * &lt;ejbjar srcdir=&quot;${build.classes}&quot;
+ * basejarname=&quot;vsmp&quot;
+ * descriptordir=&quot;${rsc.dir}/hrmanager&quot;&gt;
+ * &lt;borland destdir=&quot;tstlib&quot;&gt;
+ * &lt;classpath refid=&quot;classpath&quot; /&gt;
+ * &lt;/borland&gt;
+ * &lt;include name=&quot;**\ejb-jar.xml&quot;/&gt;
+ * &lt;support dir=&quot;${build.classes}&quot;&gt;
+ * &lt;include name=&quot;demo\smp\*.class&quot;/&gt;
+ * &lt;include name=&quot;demo\helper\*.class&quot;/&gt;
+ * &lt;/support&gt;
+ * &lt;/ejbjar&gt;
+ *</PRE>
+ *
+ */
+public class BorlandDeploymentTool extends GenericDeploymentTool
+ implements ExecuteStreamHandler {
+ /** Borland 1.1 ejb id */
+ public static final String PUBLICID_BORLAND_EJB
+ = "-//Inprise Corporation//DTD Enterprise JavaBeans 1.1//EN";
+
+ protected static final String DEFAULT_BAS45_EJB11_DTD_LOCATION
+ = "/com/inprise/j2ee/xml/dtds/ejb-jar.dtd";
+
+ protected static final String DEFAULT_BAS_DTD_LOCATION
+ = "/com/inprise/j2ee/xml/dtds/ejb-inprise.dtd";
+
+ protected static final String BAS_DD = "ejb-inprise.xml";
+ protected static final String BES_DD = "ejb-borland.xml";
+
+
+ /** Java2iiop executable **/
+ protected static final String JAVA2IIOP = "java2iiop";
+
+ /** Verify class */
+ protected static final String VERIFY = "com.inprise.ejb.util.Verify";
+
+ /** Instance variable that stores the suffix for the borland jarfile. */
+ private String jarSuffix = "-ejb.jar";
+
+ /** Instance variable that stores the location of the borland DTD file. */
+ private String borlandDTD;
+
+ /** Instance variable that determines whether the debug mode is on */
+ private boolean java2iiopdebug = false;
+
+ /** store additional param for java2iiop command used to build EJB Stubs */
+ private String java2iioparams = null;
+
+ /** Instance variable that determines whether the client jar file is generated */
+ private boolean generateclient = false;
+
+ /** Borland Enterprise Server = version 5 */
+ static final int BES = 5;
+ /** Borland Application Server or Inprise Application Server = version 4 */
+ static final int BAS = 4;
+
+ /** borland appserver version 4 or 5 */
+ private int version = BAS;
+
+
+ /**
+ * Instance variable that determines whether it is necessary to verify the
+ * produced jar
+ */
+ private boolean verify = true;
+ private String verifyArgs = "";
+
+ private Hashtable genfiles = new Hashtable();
+
+ /**
+ * set the debug mode for java2iiop (default false)
+ * @param debug the setting to use.
+ **/
+ public void setDebug(boolean debug) {
+ this.java2iiopdebug = debug;
+ }
+
+ /**
+ * set the verify mode for the produced jar (default true)
+ * @param verify the setting to use.
+ **/
+ public void setVerify(boolean verify) {
+ this.verify = verify;
+ }
+
+
+ /**
+ * Setter used to store the suffix for the generated borland jar file.
+ * @param inString the string to use as the suffix.
+ */
+ public void setSuffix(String inString) {
+ this.jarSuffix = inString;
+ }
+
+
+ /**
+ * sets some additional args to send to verify command
+ * @param args additional command line parameters
+ */
+ public void setVerifyArgs(String args) {
+ this.verifyArgs = args;
+ }
+
+ /**
+ * Setter used to store the location of the borland DTD. This can be a file on the system
+ * or a resource on the classpath.
+ * @param inString the string to use as the DTD location.
+ */
+ public void setBASdtd(String inString) {
+ this.borlandDTD = inString;
+ }
+
+
+ /**
+ * setter used to store whether the task will include the generate client task.
+ * (see : BorlandGenerateClient task)
+ * @param b if true generate the client task.
+ */
+ public void setGenerateclient(boolean b) {
+ this.generateclient = b;
+ }
+
+ /**
+ * setter used to store the borland appserver version [4 or 5]
+ * @param version app server version 4 or 5
+ */
+ public void setVersion(int version) {
+ this.version = version;
+ }
+
+ /**
+ * If filled, the params are added to the java2iiop command.
+ * (ex: -no_warn_missing_define)
+ * @param params additional params for java2iiop
+ */
+ public void setJava2iiopParams(String params) {
+ this.java2iioparams = params;
+ }
+
+
+ /**
+ * Get the borland descriptor handler.
+ * @param srcDir the source directory.
+ * @return the descriptor.
+ */
+ protected DescriptorHandler getBorlandDescriptorHandler(final File srcDir) {
+ DescriptorHandler handler =
+ new DescriptorHandler(getTask(), srcDir) {
+ protected void processElement() {
+ if (currentElement.equals("type-storage")) {
+ // Get the filename of vendor specific descriptor
+ String fileNameWithMETA = currentText;
+ //trim the META_INF\ off of the file name
+ String fileName
+ = fileNameWithMETA.substring(META_DIR.length(),
+ fileNameWithMETA.length());
+ File descriptorFile = new File(srcDir, fileName);
+
+ ejbFiles.put(fileNameWithMETA, descriptorFile);
+ }
+ }
+ };
+ handler.registerDTD(PUBLICID_BORLAND_EJB,
+ borlandDTD == null ? DEFAULT_BAS_DTD_LOCATION : borlandDTD);
+
+ for (Iterator i = getConfig().dtdLocations.iterator(); i.hasNext();) {
+ EjbJar.DTDLocation dtdLocation = (EjbJar.DTDLocation) i.next();
+ handler.registerDTD(dtdLocation.getPublicId(), dtdLocation.getLocation());
+ }
+ return handler;
+ }
+
+ /**
+ * Add any vendor specific files which should be included in the
+ * EJB Jar.
+ * @param ejbFiles the map to add the files to.
+ * @param ddPrefix the prefix to use.
+ */
+ protected void addVendorFiles(Hashtable ejbFiles, String ddPrefix) {
+
+ //choose the right vendor DD
+ if (!(version == BES || version == BAS)) {
+ throw new BuildException("version " + version + " is not supported");
+ }
+
+ String dd = (version == BES ? BES_DD : BAS_DD);
+
+ log("vendor file : " + ddPrefix + dd, Project.MSG_DEBUG);
+
+ File borlandDD = new File(getConfig().descriptorDir, ddPrefix + dd);
+ if (borlandDD.exists()) {
+ log("Borland specific file found " + borlandDD, Project.MSG_VERBOSE);
+ ejbFiles.put(META_DIR + dd , borlandDD);
+ } else {
+ log("Unable to locate borland deployment descriptor. "
+ + "It was expected to be in "
+ + borlandDD.getPath(), Project.MSG_WARN);
+ return;
+ }
+ }
+
+ /**
+ * Get the vendor specific name of the Jar that will be output. The modification date
+ * of this jar will be checked against the dependent bean classes.
+ */
+ File getVendorOutputJarFile(String baseName) {
+ return new File(getDestDir(), baseName + jarSuffix);
+ }
+
+ /**
+ * Verify the produced jar file by invoking the Borland verify tool
+ * @param sourceJar java.io.File representing the produced jar file
+ */
+ private void verifyBorlandJar(File sourceJar) {
+ if (version == BAS) {
+ verifyBorlandJarV4(sourceJar);
+ return;
+ }
+ if (version == BES) {
+ verifyBorlandJarV5(sourceJar);
+ return;
+ }
+ log("verify jar skipped because the version is invalid ["
+ + version + "]", Project.MSG_WARN);
+ }
+
+ /**
+ * Verify the produced jar file by invoking the Borland iastool tool
+ * @param sourceJar java.io.File representing the produced jar file
+ */
+ private void verifyBorlandJarV5(File sourceJar) {
+ log("verify BES " + sourceJar, Project.MSG_INFO);
+ try {
+ ExecTask execTask = null;
+ execTask = new ExecTask(getTask());
+ execTask.setDir(new File("."));
+ execTask.setExecutable("iastool");
+ //classpath
+ if (getCombinedClasspath() != null) {
+ execTask.createArg().setValue("-VBJclasspath");
+ execTask.createArg().setValue(getCombinedClasspath().toString());
+ }
+
+ if (java2iiopdebug) {
+ execTask.createArg().setValue("-debug");
+ }
+ execTask.createArg().setValue("-verify");
+ execTask.createArg().setValue("-src");
+ // ejb jar file to verify
+ execTask.createArg().setValue(sourceJar.getPath());
+ log("Calling iastool", Project.MSG_VERBOSE);
+ execTask.execute();
+ } catch (Exception e) {
+ // Have to catch this because of the semantics of calling main()
+ String msg = "Exception while calling generateclient Details: "
+ + e.toString();
+ throw new BuildException(msg, e);
+ }
+ }
+
+ /**
+ * Verify the produced jar file by invoking the Borland verify tool
+ * @param sourceJar java.io.File representing the produced jar file
+ */
+ private void verifyBorlandJarV4(File sourceJar) {
+ org.apache.tools.ant.taskdefs.Java javaTask = null;
+ log("verify BAS " + sourceJar, Project.MSG_INFO);
+ try {
+ String args = verifyArgs;
+ args += " " + sourceJar.getPath();
+
+ javaTask = new Java(getTask());
+ javaTask.setTaskName("verify");
+ javaTask.setClassname(VERIFY);
+ Commandline.Argument arguments = javaTask.createArg();
+ arguments.setLine(args);
+ Path classpath = getCombinedClasspath();
+ if (classpath != null) {
+ javaTask.setClasspath(classpath);
+ javaTask.setFork(true);
+ }
+
+ log("Calling " + VERIFY + " for " + sourceJar.toString(),
+ Project.MSG_VERBOSE);
+ javaTask.execute();
+ } catch (Exception e) {
+ //TO DO : delete the file if it is not a valid file.
+ String msg = "Exception while calling " + VERIFY + " Details: "
+ + e.toString();
+ throw new BuildException(msg, e);
+ }
+ }
+
+
+ /**
+ * Generate the client jar corresponding to the jar file passed as parameter
+ * the method uses the BorlandGenerateClient task.
+ * @param sourceJar java.io.File representing the produced jar file
+ */
+ private void generateClient(File sourceJar) {
+ getTask().getProject().addTaskDefinition("internal_bas_generateclient",
+ org.apache.tools.ant.taskdefs.optional.ejb.BorlandGenerateClient.class);
+
+ org.apache.tools.ant.taskdefs.optional.ejb.BorlandGenerateClient gentask = null;
+ log("generate client for " + sourceJar, Project.MSG_INFO);
+ try {
+ Project project = getTask().getProject();
+ gentask
+ = (BorlandGenerateClient) project.createTask("internal_bas_generateclient");
+ gentask.setEjbjar(sourceJar);
+ gentask.setDebug(java2iiopdebug);
+ Path classpath = getCombinedClasspath();
+ if (classpath != null) {
+ gentask.setClasspath(classpath);
+ }
+ gentask.setVersion(version);
+ gentask.setTaskName("generate client");
+ gentask.execute();
+ } catch (Exception e) {
+ //TO DO : delete the file if it is not a valid file.
+ String msg = "Exception while calling " + VERIFY + " Details: "
+ + e.toString();
+ throw new BuildException(msg, e);
+ }
+ }
+
+ /**
+ * Generate stubs & skeleton for each home found into the DD
+ * Add all the generate class file into the ejb files
+ * @param ithomes : iterator on home class
+ */
+ private void buildBorlandStubs(Iterator ithomes) {
+ Execute execTask = null;
+
+ execTask = new Execute(this);
+ Project project = getTask().getProject();
+ execTask.setAntRun(project);
+ execTask.setWorkingDirectory(project.getBaseDir());
+
+ Commandline commandline = new Commandline();
+ commandline.setExecutable(JAVA2IIOP);
+ //debug ?
+ if (java2iiopdebug) {
+ commandline.createArgument().setValue("-VBJdebug");
+ }
+ //set the classpath
+ commandline.createArgument().setValue("-VBJclasspath");
+ commandline.createArgument().setPath(getCombinedClasspath());
+ //list file
+ commandline.createArgument().setValue("-list_files");
+ //no TIE classes
+ commandline.createArgument().setValue("-no_tie");
+
+ if (java2iioparams != null) {
+ log("additional " + java2iioparams + " to java2iiop ", 0);
+ commandline.createArgument().setLine(java2iioparams);
+ }
+
+
+ //root dir
+ commandline.createArgument().setValue("-root_dir");
+ commandline.createArgument().setValue(getConfig().srcDir.getAbsolutePath());
+ //compiling order
+ commandline.createArgument().setValue("-compile");
+ //add the home class
+ while (ithomes.hasNext()) {
+ commandline.createArgument().setValue(ithomes.next().toString());
+ }
+
+ try {
+ log("Calling java2iiop", Project.MSG_VERBOSE);
+ log(commandline.describeCommand(), Project.MSG_DEBUG);
+ execTask.setCommandline(commandline.getCommandline());
+ int result = execTask.execute();
+ if (Execute.isFailure(result)) {
+ String msg = "Failed executing java2iiop (ret code is "
+ + result + ")";
+ throw new BuildException(msg, getTask().getLocation());
+ }
+ } catch (java.io.IOException e) {
+ log("java2iiop exception :" + e.getMessage(), Project.MSG_ERR);
+ throw new BuildException(e, getTask().getLocation());
+ }
+ }
+
+ /**
+ * Method used to encapsulate the writing of the JAR file. Iterates over the
+ * filenames/java.io.Files in the Hashtable stored on the instance variable
+ * ejbFiles.
+ * @param baseName the base name.
+ * @param jarFile the jar file to write to.
+ * @param files the files to write to the jar.
+ * @param publicId the id to use.
+ * @throws BuildException if there is an error.
+ */
+ protected void writeJar(String baseName, File jarFile, Hashtable files, String publicId)
+ throws BuildException {
+ //build the home classes list.
+ Vector homes = new Vector();
+ Iterator it = files.keySet().iterator();
+ while (it.hasNext()) {
+ String clazz = (String) it.next();
+ if (clazz.endsWith("Home.class")) {
+ //remove .class extension
+ String home = toClass(clazz);
+ homes.add(home);
+ log(" Home " + home, Project.MSG_VERBOSE);
+ }
+ }
+
+ buildBorlandStubs(homes.iterator());
+
+ //add the gen files to the collection
+ files.putAll(genfiles);
+
+ super.writeJar(baseName, jarFile, files, publicId);
+
+ if (verify) {
+ verifyBorlandJar(jarFile);
+ }
+
+ if (generateclient) {
+ generateClient(jarFile);
+ }
+ genfiles.clear();
+ }
+
+ /**
+ * convert a class file name : A/B/C/toto.class
+ * into a class name: A.B.C.toto
+ */
+ private String toClass(String filename) {
+ //remove the .class
+ String classname = filename.substring(0, filename.lastIndexOf(".class"));
+ classname = classname.replace('\\', '.');
+ return classname;
+ }
+
+ /**
+ * convert a file name : A/B/C/toto.java
+ * into a class name: A/B/C/toto.class
+ */
+ private String toClassFile(String filename) {
+ //remove the .class
+ String classfile = filename.substring(0, filename.lastIndexOf(".java"));
+ classfile = classfile + ".class";
+ return classfile;
+ }
+
+ // implementation of org.apache.tools.ant.taskdefs.ExecuteStreamHandler interface
+
+ /** {@inheritDoc}. */
+ public void start() throws IOException { }
+ /** {@inheritDoc}. */
+ public void stop() { }
+ /** {@inheritDoc}. */
+ public void setProcessInputStream(OutputStream param1) throws IOException { }
+
+ /**
+ * Set the output stream of the process.
+ * @param is the input stream.
+ * @throws IOException if there is an error.
+ */
+ public void setProcessOutputStream(InputStream is) throws IOException {
+ try {
+ BufferedReader reader = new BufferedReader(new InputStreamReader(is));
+ String javafile;
+ while ((javafile = reader.readLine()) != null) {
+ if (javafile.endsWith(".java")) {
+ String classfile = toClassFile(javafile);
+ String key = classfile.substring(
+ getConfig().srcDir.getAbsolutePath().length() + 1);
+ genfiles.put(key, new File(classfile));
+ }
+ }
+ reader.close();
+ } catch (Exception e) {
+ String msg = "Exception while parsing java2iiop output. Details: " + e.toString();
+ throw new BuildException(msg, e);
+ }
+ }
+
+ /**
+ * Set the error stream of the process.
+ * @param is the input stream.
+ * @throws IOException if there is an error.
+ */
+ public void setProcessErrorStream(InputStream is) throws IOException {
+ BufferedReader reader = new BufferedReader(new InputStreamReader(is));
+ String s = reader.readLine();
+ if (s != null) {
+ log("[java2iiop] " + s, Project.MSG_ERR);
+ }
+ }
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ejb/BorlandGenerateClient.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ejb/BorlandGenerateClient.java
new file mode 100644
index 00000000..dd46269d
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ejb/BorlandGenerateClient.java
@@ -0,0 +1,313 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+
+package org.apache.tools.ant.taskdefs.optional.ejb;
+
+import java.io.File;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.taskdefs.ExecTask;
+import org.apache.tools.ant.taskdefs.Java;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.types.Reference;
+
+/**
+ * Generates a Borland Application Server 4.5 client JAR using as
+ * input the EJB JAR file.
+ *
+ * Two mode are available: java mode (default) and fork mode. With the fork mode,
+ * it is impossible to add classpath to the command line.
+ *
+ * @ant.task name="blgenclient" category="ejb"
+ */
+public class BorlandGenerateClient extends Task {
+ static final String JAVA_MODE = "java";
+ static final String FORK_MODE = "fork";
+
+ // CheckStyle:VisibilityModifier OFF - bc
+ /** debug the generateclient task */
+ boolean debug = false;
+
+ /** hold the ejbjar file name */
+ File ejbjarfile = null;
+
+ /** hold the client jar file name */
+ File clientjarfile = null;
+
+ /** hold the classpath */
+ Path classpath;
+
+ /** hold the mode (java|fork) */
+ String mode = FORK_MODE;
+
+ /** hold the version */
+ int version = BorlandDeploymentTool.BAS;
+ // CheckStyle:VisibilityModifier ON
+
+ /**
+ * Set the version attribute.
+ * @param version the value to use.
+ */
+ public void setVersion(int version) {
+ this.version = version;
+ }
+
+ /**
+ * Command launching mode: java or fork.
+ * @param s the mode to use.
+ */
+ public void setMode(String s) {
+ mode = s;
+ }
+
+ /**
+ * If true, turn on the debug mode for each of the Borland tools launched.
+ * @param debug a <code>boolean</code> value.
+ */
+ public void setDebug(boolean debug) {
+ this.debug = debug;
+ }
+
+ /**
+ * EJB JAR file.
+ * @param ejbfile the file to use.
+ */
+ public void setEjbjar(File ejbfile) {
+ ejbjarfile = ejbfile;
+ }
+
+ /**
+ * Client JAR file name.
+ * @param clientjar the file to use.
+ */
+ public void setClientjar(File clientjar) {
+ clientjarfile = clientjar;
+ }
+
+ /**
+ * Path to use for classpath.
+ * @param classpath the path to use.
+ */
+ public void setClasspath(Path classpath) {
+ if (this.classpath == null) {
+ this.classpath = classpath;
+ } else {
+ this.classpath.append(classpath);
+ }
+ }
+
+ /**
+ * Adds path to the classpath.
+ * @return a path to be configured as a nested element.
+ */
+ public Path createClasspath() {
+ if (this.classpath == null) {
+ this.classpath = new Path(getProject());
+ }
+ return this.classpath.createPath();
+ }
+
+ /**
+ * Reference to existing path, to use as a classpath.
+ * @param r the reference to use.
+ */
+ public void setClasspathRef(Reference r) {
+ createClasspath().setRefid(r);
+ }
+
+
+ /**
+ * Do the work.
+ *
+ * The work is actually done by creating a separate JVM to run a java task.
+ *
+ * @exception BuildException if something goes wrong with the build
+ */
+ public void execute() throws BuildException {
+ if (ejbjarfile == null || ejbjarfile.isDirectory()) {
+ throw new BuildException("invalid ejb jar file.");
+ }
+
+ if (clientjarfile == null || clientjarfile.isDirectory()) {
+ log("invalid or missing client jar file.", Project.MSG_VERBOSE);
+ String ejbjarname = ejbjarfile.getAbsolutePath();
+ //clientname = ejbjarfile+client.jar
+ String clientname = ejbjarname.substring(0, ejbjarname.lastIndexOf("."));
+ clientname = clientname + "client.jar";
+ clientjarfile = new File(clientname);
+ }
+
+ if (mode == null) {
+ log("mode is null default mode is java");
+ setMode(JAVA_MODE);
+ }
+
+ if (!(version == BorlandDeploymentTool.BES
+ || version == BorlandDeploymentTool.BAS)) {
+ throw new BuildException("version " + version
+ + " is not supported");
+ }
+
+ log("client jar file is " + clientjarfile);
+
+ if (mode.equalsIgnoreCase(FORK_MODE)) {
+ executeFork();
+ } else {
+ executeJava();
+ } // end of else
+ }
+
+ /**
+ * launch the generate client using java api.
+ * @throws BuildException if there is an error.
+ */
+ protected void executeJava() throws BuildException {
+ try {
+ if (version == BorlandDeploymentTool.BES) {
+ throw new BuildException("java mode is supported only for "
+ + "previous version <=" + BorlandDeploymentTool.BAS);
+ }
+
+ log("mode : java");
+
+ Java execTask = null;
+ execTask = new Java(this);
+
+ execTask.setDir(new File("."));
+ execTask.setClassname("com.inprise.server.commandline.EJBUtilities");
+ //classpath
+ //add at the end of the classpath
+ //the system classpath in order to find the tools.jar file
+ execTask.setClasspath(classpath.concatSystemClasspath());
+
+ execTask.setFork(true);
+ execTask.createArg().setValue("generateclient");
+ if (debug) {
+ execTask.createArg().setValue("-trace");
+ }
+
+ execTask.createArg().setValue("-short");
+ execTask.createArg().setValue("-jarfile");
+ // ejb jar file
+ execTask.createArg().setValue(ejbjarfile.getAbsolutePath());
+ //client jar file
+ execTask.createArg().setValue("-single");
+ execTask.createArg().setValue("-clientjarfile");
+ execTask.createArg().setValue(clientjarfile.getAbsolutePath());
+
+ log("Calling EJBUtilities", Project.MSG_VERBOSE);
+ execTask.execute();
+
+ } catch (Exception e) {
+ // Have to catch this because of the semantics of calling main()
+ String msg = "Exception while calling generateclient Details: " + e.toString();
+ throw new BuildException(msg, e);
+ }
+ }
+
+ /**
+ * launch the generate client using system api.
+ * @throws BuildException if there is an error.
+ */
+ protected void executeFork() throws BuildException {
+ if (version == BorlandDeploymentTool.BAS) {
+ executeForkV4();
+ }
+ if (version == BorlandDeploymentTool.BES) {
+ executeForkV5();
+ }
+ }
+
+ /**
+ * launch the generate client using system api.
+ * @throws BuildException if there is an error.
+ */
+ protected void executeForkV4() throws BuildException {
+ try {
+
+ log("mode : fork " + BorlandDeploymentTool.BAS, Project.MSG_DEBUG);
+
+ ExecTask execTask = new ExecTask(this);
+
+ execTask.setDir(new File("."));
+ execTask.setExecutable("iastool");
+ execTask.createArg().setValue("generateclient");
+ if (debug) {
+ execTask.createArg().setValue("-trace");
+ }
+
+ execTask.createArg().setValue("-short");
+ execTask.createArg().setValue("-jarfile");
+ // ejb jar file
+ execTask.createArg().setValue(ejbjarfile.getAbsolutePath());
+ //client jar file
+ execTask.createArg().setValue("-single");
+ execTask.createArg().setValue("-clientjarfile");
+ execTask.createArg().setValue(clientjarfile.getAbsolutePath());
+
+ log("Calling iastool", Project.MSG_VERBOSE);
+ execTask.execute();
+ } catch (Exception e) {
+ // Have to catch this because of the semantics of calling main()
+ String msg = "Exception while calling generateclient Details: "
+ + e.toString();
+ throw new BuildException(msg, e);
+ }
+
+ }
+
+ /**
+ * launch the generate client using system api.
+ * @throws BuildException if there is an error.
+ */
+ protected void executeForkV5() throws BuildException {
+ try {
+ log("mode : fork " + BorlandDeploymentTool.BES, Project.MSG_DEBUG);
+ ExecTask execTask = new ExecTask(this);
+
+ execTask.setDir(new File("."));
+
+ execTask.setExecutable("iastool");
+ if (debug) {
+ execTask.createArg().setValue("-debug");
+ }
+ execTask.createArg().setValue("-genclient");
+ execTask.createArg().setValue("-jars");
+ // ejb jar file
+ execTask.createArg().setValue(ejbjarfile.getAbsolutePath());
+ //client jar file
+ execTask.createArg().setValue("-target");
+ execTask.createArg().setValue(clientjarfile.getAbsolutePath());
+ //classpath
+ execTask.createArg().setValue("-cp");
+ execTask.createArg().setValue(classpath.toString());
+ log("Calling iastool", Project.MSG_VERBOSE);
+ execTask.execute();
+ } catch (Exception e) {
+ // Have to catch this because of the semantics of calling main()
+ String msg = "Exception while calling generateclient Details: "
+ + e.toString();
+ throw new BuildException(msg, e);
+ }
+
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ejb/DescriptorHandler.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ejb/DescriptorHandler.java
new file mode 100644
index 00000000..158cba93
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ejb/DescriptorHandler.java
@@ -0,0 +1,390 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.ejb;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.Hashtable;
+
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.xml.sax.AttributeList;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+/**
+ * Inner class used by EjbJar to facilitate the parsing of deployment
+ * descriptors and the capture of appropriate information. Extends
+ * HandlerBase so it only implements the methods needed. During parsing
+ * creates a hashtable consisting of entries mapping the name it should be
+ * inserted into an EJB jar as to a File representing the file on disk. This
+ * list can then be accessed through the getFiles() method.
+ */
+public class DescriptorHandler extends org.xml.sax.HandlerBase {
+ private static final int DEFAULT_HASH_TABLE_SIZE = 10;
+ private static final int STATE_LOOKING_EJBJAR = 1;
+ private static final int STATE_IN_EJBJAR = 2;
+ private static final int STATE_IN_BEANS = 3;
+ private static final int STATE_IN_SESSION = 4;
+ private static final int STATE_IN_ENTITY = 5;
+ private static final int STATE_IN_MESSAGE = 6;
+
+ private Task owningTask;
+
+ private String publicId = null;
+
+ /**
+ * Bunch of constants used for storing entries in a hashtable, and for
+ * constructing the filenames of various parts of the ejb jar.
+ */
+ private static final String EJB_REF = "ejb-ref";
+ private static final String EJB_LOCAL_REF = "ejb-local-ref";
+ private static final String HOME_INTERFACE = "home";
+ private static final String REMOTE_INTERFACE = "remote";
+ private static final String LOCAL_HOME_INTERFACE = "local-home";
+ private static final String LOCAL_INTERFACE = "local";
+ private static final String BEAN_CLASS = "ejb-class";
+ private static final String PK_CLASS = "prim-key-class";
+ private static final String EJB_NAME = "ejb-name";
+ private static final String EJB_JAR = "ejb-jar";
+ private static final String ENTERPRISE_BEANS = "enterprise-beans";
+ private static final String ENTITY_BEAN = "entity";
+ private static final String SESSION_BEAN = "session";
+ private static final String MESSAGE_BEAN = "message-driven";
+
+ /**
+ * The state of the parsing
+ */
+ private int parseState = STATE_LOOKING_EJBJAR;
+
+ // CheckStyle:VisibilityModifier OFF - bc
+ /**
+ * Instance variable used to store the name of the current element being
+ * processed by the SAX parser. Accessed by the SAX parser call-back methods
+ * startElement() and endElement().
+ */
+ protected String currentElement = null;
+
+ /**
+ * The text of the current element
+ */
+ protected String currentText = null;
+
+ /**
+ * Instance variable that stores the names of the files as they will be
+ * put into the jar file, mapped to File objects Accessed by the SAX
+ * parser call-back method characters().
+ */
+ protected Hashtable ejbFiles = null;
+
+ /**
+ * Instance variable that stores the value found in the &lt;ejb-name&gt; element
+ */
+ protected String ejbName = null;
+
+ private Hashtable fileDTDs = new Hashtable();
+
+ private Hashtable resourceDTDs = new Hashtable();
+
+ private boolean inEJBRef = false;
+
+ private Hashtable urlDTDs = new Hashtable();
+ // CheckStyle:VisibilityModifier OFF - bc
+
+ /**
+ * The directory containing the bean classes and interfaces. This is
+ * used for performing dependency file lookups.
+ */
+ private File srcDir;
+
+ /**
+ * Constructor for DescriptorHandler.
+ * @param task the task that owns this descriptor
+ * @param srcDir the source directory
+ */
+ public DescriptorHandler(Task task, File srcDir) {
+ this.owningTask = task;
+ this.srcDir = srcDir;
+ }
+
+ /**
+ * Register a dtd with a location.
+ * The location is one of a filename, a resource name in the classpath, or
+ * a URL.
+ * @param publicId the public identity of the dtd
+ * @param location the location of the dtd
+ */
+ public void registerDTD(String publicId, String location) {
+ if (location == null) {
+ return;
+ }
+
+ File fileDTD = new File(location);
+ if (!fileDTD.exists()) {
+ // resolve relative to project basedir
+ fileDTD = owningTask.getProject().resolveFile(location);
+ }
+
+ if (fileDTD.exists()) {
+ if (publicId != null) {
+ fileDTDs.put(publicId, fileDTD);
+ owningTask.log("Mapped publicId " + publicId + " to file "
+ + fileDTD, Project.MSG_VERBOSE);
+ }
+ return;
+ }
+
+ if (getClass().getResource(location) != null) {
+ if (publicId != null) {
+ resourceDTDs.put(publicId, location);
+ owningTask.log("Mapped publicId " + publicId + " to resource "
+ + location, Project.MSG_VERBOSE);
+ }
+ }
+
+ try {
+ if (publicId != null) {
+ URL urldtd = new URL(location);
+ urlDTDs.put(publicId, urldtd);
+ }
+ } catch (java.net.MalformedURLException e) {
+ //ignored
+ }
+
+ }
+
+ /**
+ * Resolve the entity.
+ * @see org.xml.sax.EntityResolver#resolveEntity(String, String).
+ * @param publicId The public identifier, or <code>null</code>
+ * if none is available.
+ * @param systemId The system identifier provided in the XML
+ * document. Will not be <code>null</code>.
+ * @return an inputsource for this identifier
+ * @throws SAXException if there is a problem.
+ */
+ public InputSource resolveEntity(String publicId, String systemId)
+ throws SAXException {
+ this.publicId = publicId;
+
+ File dtdFile = (File) fileDTDs.get(publicId);
+ if (dtdFile != null) {
+ try {
+ owningTask.log("Resolved " + publicId + " to local file "
+ + dtdFile, Project.MSG_VERBOSE);
+ return new InputSource(new FileInputStream(dtdFile));
+ } catch (FileNotFoundException ex) {
+ // ignore
+ }
+ }
+
+ String dtdResourceName = (String) resourceDTDs.get(publicId);
+ if (dtdResourceName != null) {
+ InputStream is = this.getClass().getResourceAsStream(dtdResourceName);
+ if (is != null) {
+ owningTask.log("Resolved " + publicId + " to local resource "
+ + dtdResourceName, Project.MSG_VERBOSE);
+ return new InputSource(is);
+ }
+ }
+
+ URL dtdUrl = (URL) urlDTDs.get(publicId);
+ if (dtdUrl != null) {
+ try {
+ InputStream is = dtdUrl.openStream();
+ owningTask.log("Resolved " + publicId + " to url "
+ + dtdUrl, Project.MSG_VERBOSE);
+ return new InputSource(is);
+ } catch (IOException ioe) {
+ //ignore
+ }
+ }
+
+ owningTask.log("Could not resolve ( publicId: " + publicId
+ + ", systemId: " + systemId + ") to a local entity", Project.MSG_INFO);
+
+ return null;
+ }
+
+ /**
+ * Getter method that returns the set of files to include in the EJB jar.
+ * @return the map of files
+ */
+ public Hashtable getFiles() {
+ return (ejbFiles == null) ? new Hashtable() : ejbFiles;
+ }
+
+ /**
+ * Get the publicId of the DTD
+ * @return the public id
+ */
+ public String getPublicId() {
+ return publicId;
+ }
+
+ /**
+ * Getter method that returns the value of the &lt;ejb-name&gt; element.
+ * @return the ejb name
+ */
+ public String getEjbName() {
+ return ejbName;
+ }
+
+ /**
+ * SAX parser call-back method that is used to initialize the values of some
+ * instance variables to ensure safe operation.
+ * @throws SAXException on error
+ */
+ public void startDocument() throws SAXException {
+ this.ejbFiles = new Hashtable(DEFAULT_HASH_TABLE_SIZE, 1);
+ this.currentElement = null;
+ inEJBRef = false;
+ }
+
+
+ /**
+ * SAX parser call-back method that is invoked when a new element is entered
+ * into. Used to store the context (attribute name) in the currentAttribute
+ * instance variable.
+ * @param name The name of the element being entered.
+ * @param attrs Attributes associated to the element.
+ * @throws SAXException on error
+ */
+ public void startElement(String name, AttributeList attrs)
+ throws SAXException {
+ this.currentElement = name;
+ currentText = "";
+ if (name.equals(EJB_REF) || name.equals(EJB_LOCAL_REF)) {
+ inEJBRef = true;
+ } else if (parseState == STATE_LOOKING_EJBJAR && name.equals(EJB_JAR)) {
+ parseState = STATE_IN_EJBJAR;
+ } else if (parseState == STATE_IN_EJBJAR && name.equals(ENTERPRISE_BEANS)) {
+ parseState = STATE_IN_BEANS;
+ } else if (parseState == STATE_IN_BEANS && name.equals(SESSION_BEAN)) {
+ parseState = STATE_IN_SESSION;
+ } else if (parseState == STATE_IN_BEANS && name.equals(ENTITY_BEAN)) {
+ parseState = STATE_IN_ENTITY;
+ } else if (parseState == STATE_IN_BEANS && name.equals(MESSAGE_BEAN)) {
+ parseState = STATE_IN_MESSAGE;
+ }
+ }
+
+
+ /**
+ * SAX parser call-back method that is invoked when an element is exited.
+ * Used to blank out (set to the empty string, not nullify) the name of
+ * the currentAttribute. A better method would be to use a stack as an
+ * instance variable, however since we are only interested in leaf-node
+ * data this is a simpler and workable solution.
+ * @param name The name of the attribute being exited. Ignored
+ * in this implementation.
+ * @throws SAXException on error
+ */
+ public void endElement(String name) throws SAXException {
+ processElement();
+ currentText = "";
+ this.currentElement = "";
+ if (name.equals(EJB_REF) || name.equals(EJB_LOCAL_REF)) {
+ inEJBRef = false;
+ } else if (parseState == STATE_IN_ENTITY && name.equals(ENTITY_BEAN)) {
+ parseState = STATE_IN_BEANS;
+ } else if (parseState == STATE_IN_SESSION && name.equals(SESSION_BEAN)) {
+ parseState = STATE_IN_BEANS;
+ } else if (parseState == STATE_IN_MESSAGE && name.equals(MESSAGE_BEAN)) {
+ parseState = STATE_IN_BEANS;
+ } else if (parseState == STATE_IN_BEANS && name.equals(ENTERPRISE_BEANS)) {
+ parseState = STATE_IN_EJBJAR;
+ } else if (parseState == STATE_IN_EJBJAR && name.equals(EJB_JAR)) {
+ parseState = STATE_LOOKING_EJBJAR;
+ }
+ }
+
+ /**
+ * SAX parser call-back method invoked whenever characters are located within
+ * an element. currentAttribute (modified by startElement and endElement)
+ * tells us whether we are in an interesting element (one of the up to four
+ * classes of an EJB). If so then converts the classname from the format
+ * org.apache.tools.ant.Parser to the convention for storing such a class,
+ * org/apache/tools/ant/Parser.class. This is then resolved into a file
+ * object under the srcdir which is stored in a Hashtable.
+ * @param ch A character array containing all the characters in
+ * the element, and maybe others that should be ignored.
+ * @param start An integer marking the position in the char
+ * array to start reading from.
+ * @param length An integer representing an offset into the
+ * char array where the current data terminates.
+ * @throws SAXException on error
+ */
+ public void characters(char[] ch, int start, int length)
+ throws SAXException {
+
+ currentText += new String(ch, start, length);
+ }
+
+
+ /**
+ * Called when an endelement is seen.
+ * This may be overridden in derived classes.
+ * This updates the ejbfiles if the element is an interface or a bean class.
+ * This updates the ejbname if the element is an ejb name.
+ */
+ protected void processElement() {
+ if (inEJBRef
+ || (parseState != STATE_IN_ENTITY
+ && parseState != STATE_IN_SESSION
+ && parseState != STATE_IN_MESSAGE)) {
+ return;
+ }
+
+ if (currentElement.equals(HOME_INTERFACE)
+ || currentElement.equals(REMOTE_INTERFACE)
+ || currentElement.equals(LOCAL_INTERFACE)
+ || currentElement.equals(LOCAL_HOME_INTERFACE)
+ || currentElement.equals(BEAN_CLASS)
+ || currentElement.equals(PK_CLASS)) {
+
+ // Get the filename into a String object
+ File classFile = null;
+ String className = currentText.trim();
+
+ // If it's a primitive wrapper then we shouldn't try and put
+ // it into the jar, so ignore it.
+ if (!className.startsWith("java.")
+ && !className.startsWith("javax.")) {
+ // Translate periods into path separators, add .class to the
+ // name, create the File object and add it to the Hashtable.
+ className = className.replace('.', File.separatorChar);
+ className += ".class";
+ classFile = new File(srcDir, className);
+ ejbFiles.put(className, classFile);
+ }
+ }
+
+ // Get the value of the <ejb-name> tag. Only the first occurrence.
+ if (currentElement.equals(EJB_NAME)) {
+ if (ejbName == null) {
+ ejbName = currentText.trim();
+ }
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ejb/EJBDeploymentTool.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ejb/EJBDeploymentTool.java
new file mode 100644
index 00000000..6ed8e34a
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ejb/EJBDeploymentTool.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.ejb;
+
+
+
+import javax.xml.parsers.SAXParser;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Task;
+
+
+/**
+ * The interface to implement for deployment tools.
+ */
+public interface EJBDeploymentTool {
+ /**
+ * Process a deployment descriptor, generating the necessary vendor specific
+ * deployment files.
+ *
+ * @param descriptorFilename the name of the deployment descriptor
+ * @param saxParser a SAX parser which can be used to parse the deployment descriptor.
+ * @throws BuildException if there is an error.
+ */
+ void processDescriptor(String descriptorFilename, SAXParser saxParser)
+ throws BuildException;
+
+ /**
+ * Called to validate that the tool parameters have been configured.
+ * @throws BuildException if there is an error.
+ */
+ void validateConfigured() throws BuildException;
+
+ /**
+ * Set the task which owns this tool
+ * @param task the task.
+ */
+ void setTask(Task task);
+
+ /**
+ * Configure this tool for use in the ejbjar task.
+ * @param config contains configuration state.
+ */
+ void configure(EjbJar.Config config);
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ejb/EjbJar.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ejb/EjbJar.java
new file mode 100644
index 00000000..e9b7ed42
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ejb/EjbJar.java
@@ -0,0 +1,630 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.ejb;
+
+// Standard java imports
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.DirectoryScanner;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.MatchingTask;
+import org.apache.tools.ant.types.EnumeratedAttribute;
+import org.apache.tools.ant.types.FileSet;
+import org.apache.tools.ant.types.Path;
+import org.xml.sax.SAXException;
+
+/**
+ * Provides automated EJB JAR file creation.
+ * <p>
+ * Extends the
+ * MatchingTask class provided in the default ant distribution to provide a
+ * directory scanning EJB jarfile generator.
+ * </p>
+ *
+ * <p>
+ * The task works by taking the deployment descriptors one at a time and
+ * parsing them to locate the names of the classes which should be placed in
+ * the jar. The classnames are translated to java.io.Files by replacing
+ * periods with File.separatorChar and resolving the generated filename as a
+ * relative path under the srcDir attribute. All necessary files are then
+ * assembled into a jarfile. One jarfile is constructed for each deployment
+ * descriptor found.
+ * </p>
+ *
+ * */
+public class EjbJar extends MatchingTask {
+
+ /**
+ * Inner class used to record information about the location of a local DTD
+ */
+ public static class DTDLocation
+ extends org.apache.tools.ant.types.DTDLocation {
+ }
+
+ /**
+ * A class which contains the configuration state of the ejbjar task.
+ * This state is passed to the deployment tools for configuration
+ */
+ static class Config {
+ // CheckStyle:VisibilityModifier OFF - bc
+ /**
+ * Stores a handle to the directory under which to search for class
+ * files
+ */
+ public File srcDir;
+
+ /**
+ * Stores a handle to the directory under which to search for
+ * deployment descriptors
+ */
+ public File descriptorDir;
+
+ /** Instance variable that marks the end of the 'basename' */
+ public String baseNameTerminator = "-";
+
+ /** Stores a handle to the destination EJB Jar file */
+ public String baseJarName;
+
+ /**
+ * Instance variable that determines whether to use a package structure
+ * of a flat directory as the destination for the jar files.
+ */
+ public boolean flatDestDir = false;
+
+ /**
+ * The classpath to use when loading classes
+ */
+ public Path classpath;
+
+ /**
+ * A Fileset of support classes
+ */
+ public List supportFileSets = new ArrayList();
+
+ /**
+ * The list of configured DTD locations
+ */
+ public ArrayList dtdLocations = new ArrayList();
+
+ /**
+ * The naming scheme used to determine the generated jar name
+ * from the descriptor information
+ */
+ public NamingScheme namingScheme;
+
+ /**
+ * The Manifest file
+ */
+ public File manifest;
+
+ /**
+ * The dependency analyzer to use to add additional classes to the jar
+ */
+ public String analyzer;
+ // CheckStyle:VisibilityModifier ON
+ }
+
+ /**
+ * An EnumeratedAttribute class for handling different EJB jar naming
+ * schemes
+ */
+ public static class NamingScheme extends EnumeratedAttribute {
+ /**
+ * Naming scheme where generated jar is determined from the ejb-name in
+ * the deployment descriptor
+ */
+ public static final String EJB_NAME = "ejb-name";
+
+ /**
+ * Naming scheme where the generated jar name is based on the
+ * name of the directory containing the deployment descriptor
+ */
+ public static final String DIRECTORY = "directory";
+
+ /**
+ * Naming scheme where the generated jar name is based on the name of
+ * the deployment descriptor file
+ */
+ public static final String DESCRIPTOR = "descriptor";
+
+ /**
+ * Naming scheme where the generated jar is named by the basejarname
+ * attribute
+ */
+ public static final String BASEJARNAME = "basejarname";
+
+ /**
+ * Gets the values of the NamingScheme
+ *
+ * @return an array of the values of this attribute class.
+ */
+ public String[] getValues() {
+ return new String[] {EJB_NAME, DIRECTORY, DESCRIPTOR, BASEJARNAME};
+ }
+ }
+
+ /**
+ * CMP versions supported
+ * valid CMP versions are 1.0 and 2.0
+ * @since ant 1.6
+ */
+ public static class CMPVersion extends EnumeratedAttribute {
+ /** 1.0 value */
+ public static final String CMP1_0 = "1.0";
+ /** 2.0 value */
+ public static final String CMP2_0 = "2.0";
+ /** {@inheritDoc}. */
+ public String[] getValues() {
+ return new String[]{
+ CMP1_0,
+ CMP2_0,
+ };
+ }
+ }
+ /**
+ * The config which is built by this task and used by the various deployment
+ * tools to access the configuration of the ejbjar task
+ */
+ private Config config = new Config();
+
+
+ /**
+ * Stores a handle to the directory to put the Jar files in. This is
+ * only used by the generic deployment descriptor tool which is created
+ * if no other deployment descriptor tools are provided. Normally each
+ * deployment tool will specify the desitination dir itself.
+ */
+ private File destDir;
+
+ /** Instance variable that stores the suffix for the generated jarfile. */
+ private String genericJarSuffix = "-generic.jar";
+
+ /** Instance variable that stores the CMP version for the jboss jarfile. */
+ private String cmpVersion = CMPVersion.CMP1_0;
+
+ /** The list of deployment tools we are going to run. */
+ private ArrayList deploymentTools = new ArrayList();
+
+ /**
+ * Add a deployment tool to the list of deployment tools that will be
+ * processed
+ *
+ * @param deploymentTool a deployment tool instance to which descriptors
+ * will be passed for processing.
+ */
+ protected void addDeploymentTool(EJBDeploymentTool deploymentTool) {
+ deploymentTool.setTask(this);
+ deploymentTools.add(deploymentTool);
+ }
+
+ /**
+ * Adds a deployment tool for Weblogic server.
+ *
+ * @return the deployment tool instance to be configured.
+ */
+ public WeblogicDeploymentTool createWeblogic() {
+ WeblogicDeploymentTool tool = new WeblogicDeploymentTool();
+ addDeploymentTool(tool);
+ return tool;
+ }
+
+ /**
+ * Adds a deployment tool for Websphere 4.0 server.
+ *
+ * @return the deployment tool instance to be configured.
+ */
+ public WebsphereDeploymentTool createWebsphere() {
+ WebsphereDeploymentTool tool = new WebsphereDeploymentTool();
+ addDeploymentTool(tool);
+ return tool;
+ }
+
+ /**
+ * Adds a deployment tool for Borland server.
+ *
+ * @return the deployment tool instance to be configured.
+ */
+ public BorlandDeploymentTool createBorland() {
+ log("Borland deployment tools", Project.MSG_VERBOSE);
+
+ BorlandDeploymentTool tool = new BorlandDeploymentTool();
+ tool.setTask(this);
+ deploymentTools.add(tool);
+ return tool;
+ }
+
+ /**
+ * Adds a deployment tool for iPlanet Application Server.
+ *
+ * @return the deployment tool instance to be configured.
+ */
+ public IPlanetDeploymentTool createIplanet() {
+ log("iPlanet Application Server deployment tools", Project.MSG_VERBOSE);
+
+ IPlanetDeploymentTool tool = new IPlanetDeploymentTool();
+ addDeploymentTool(tool);
+ return tool;
+ }
+
+ /**
+ * Adds a deployment tool for JBoss server.
+ *
+ * @return the deployment tool instance to be configured.
+ */
+ public JbossDeploymentTool createJboss() {
+ JbossDeploymentTool tool = new JbossDeploymentTool();
+ addDeploymentTool(tool);
+ return tool;
+ }
+
+ /**
+ * Adds a deployment tool for JOnAS server.
+ *
+ * @return the deployment tool instance to be configured.
+ */
+ public JonasDeploymentTool createJonas() {
+ log("JOnAS deployment tools", Project.MSG_VERBOSE);
+
+ JonasDeploymentTool tool = new JonasDeploymentTool();
+ addDeploymentTool(tool);
+ return tool;
+ }
+
+ /**
+ * Adds a deployment tool for Weblogic when using the Toplink
+ * Object-Relational mapping.
+ *
+ * @return the deployment tool instance to be configured.
+ */
+ public WeblogicTOPLinkDeploymentTool createWeblogictoplink() {
+ log("The <weblogictoplink> element is no longer required. Please use "
+ + "the <weblogic> element and set newCMP=\"true\"",
+ Project.MSG_INFO);
+ WeblogicTOPLinkDeploymentTool tool
+ = new WeblogicTOPLinkDeploymentTool();
+ addDeploymentTool(tool);
+ return tool;
+ }
+
+ /**
+ * Adds to the classpath used to locate the super classes and
+ * interfaces of the classes that will make up the EJB JAR.
+ *
+ * @return the path to be configured.
+ */
+ public Path createClasspath() {
+ if (config.classpath == null) {
+ config.classpath = new Path(getProject());
+ }
+ return config.classpath.createPath();
+ }
+
+ /**
+ * Create a DTD location record. This stores the location of a DTD. The
+ * DTD is identified by its public Id. The location may either be a file
+ * location or a resource location.
+ *
+ * @return the DTD location object to be configured by Ant
+ */
+ public DTDLocation createDTD() {
+ DTDLocation dtdLocation = new DTDLocation();
+ config.dtdLocations.add(dtdLocation);
+
+ return dtdLocation;
+ }
+
+ /**
+ * Adds a fileset for support elements.
+ *
+ * @return a fileset which can be populated with support files.
+ */
+ public FileSet createSupport() {
+ FileSet supportFileSet = new FileSet();
+ config.supportFileSets.add(supportFileSet);
+ return supportFileSet;
+ }
+
+
+ /**
+ * Set the Manifest file to use when jarring. As of EJB 1.1, manifest
+ * files are no longer used to configure the EJB. However, they still
+ * have a vital importance if the EJB is intended to be packaged in an
+ * EAR file. By adding "Class-Path" settings to a Manifest file, the EJB
+ * can look for classes inside the EAR file itself, allowing for easier
+ * deployment. This is outlined in the J2EE specification, and all J2EE
+ * components are meant to support it.
+ *
+ * @param manifest the manifest to be used in the EJB jar
+ */
+ public void setManifest(File manifest) {
+ config.manifest = manifest;
+ }
+
+ /**
+ * Sets the source directory, which is the directory that
+ * contains the classes that will be added to the EJB jar. Typically
+ * this will include the home and remote interfaces and the bean class.
+ *
+ * @param inDir the source directory.
+ */
+ public void setSrcdir(File inDir) {
+ config.srcDir = inDir;
+ }
+
+ /**
+ * Set the descriptor directory. The descriptor directory contains the
+ * EJB deployment descriptors. These are XML files that declare the
+ * properties of a bean in a particular deployment scenario. Such
+ * properties include, for example, the transactional nature of the bean
+ * and the security access control to the bean's methods.
+ *
+ * @param inDir the directory containing the deployment descriptors.
+ */
+ public void setDescriptordir(File inDir) {
+ config.descriptorDir = inDir;
+ }
+
+ /**
+ * Set the analyzer to use when adding in dependencies to the JAR.
+ *
+ * @param analyzer the name of the dependency analyzer or a class.
+ */
+ public void setDependency(String analyzer) {
+ config.analyzer = analyzer;
+ }
+
+ /**
+ * Set the base name of the EJB JAR that is to be created if it is not
+ * to be determined from the name of the deployment descriptor files.
+ *
+ * @param inValue the basename that will be used when writing the jar
+ * file containing the EJB
+ */
+ public void setBasejarname(String inValue) {
+ config.baseJarName = inValue;
+ if (config.namingScheme == null) {
+ config.namingScheme = new NamingScheme();
+ config.namingScheme.setValue(NamingScheme.BASEJARNAME);
+ } else if (!config.namingScheme.getValue().equals(NamingScheme.BASEJARNAME)) {
+ throw new BuildException("The basejarname attribute is not "
+ + "compatible with the "
+ + config.namingScheme.getValue() + " naming scheme");
+ }
+ }
+
+ /**
+ * Set the naming scheme used to determine the name of the generated jars
+ * from the deployment descriptor
+ *
+ * @param namingScheme the naming scheme to be used
+ */
+ public void setNaming(NamingScheme namingScheme) {
+ config.namingScheme = namingScheme;
+ if (!config.namingScheme.getValue().equals(NamingScheme.BASEJARNAME)
+ && config.baseJarName != null) {
+ throw new BuildException("The basejarname attribute is not "
+ + "compatible with the "
+ + config.namingScheme.getValue() + " naming scheme");
+ }
+ }
+
+ /**
+ * Gets the destination directory.
+ *
+ * @return destination directory
+ * @since ant 1.6
+ */
+ public File getDestdir() {
+ return this.destDir;
+ }
+
+ /**
+ * Set the destination directory. The EJB jar files will be written into
+ * this directory. The jar files that exist in this directory are also
+ * used when determining if the contents of the jar file have changed.
+ * Note that this parameter is only used if no deployment tools are
+ * specified. Typically each deployment tool will specify its own
+ * destination directory.
+ *
+ * @param inDir the destination directory in which to generate jars
+ */
+ public void setDestdir(File inDir) {
+ this.destDir = inDir;
+ }
+
+ /**
+ * Gets the CMP version.
+ *
+ * @return CMP version
+ * @since ant 1.6
+ */
+ public String getCmpversion() {
+ return this.cmpVersion;
+ }
+
+ /**
+ * Sets the CMP version.
+ *
+ * @param version CMP version.
+ * Must be either <code>1.0</code> or <code>2.0</code>.<br/>
+ * Default is <code>1.0</code>.<br/>
+ * Initially, only the JBoss implementation does something specific for CMP 2.0.<br/>
+ * @since ant 1.6
+ */
+ public void setCmpversion(CMPVersion version) {
+ this.cmpVersion = version.getValue();
+ }
+
+ /**
+ * Set the classpath to use when resolving classes for inclusion in the jar.
+ *
+ * @param classpath the classpath to use.
+ */
+ public void setClasspath(Path classpath) {
+ config.classpath = classpath;
+ }
+
+ /**
+ * Controls whether the
+ * destination JARs are written out in the destination directory with
+ * the same hierarchical structure from which the deployment descriptors
+ * have been read. If this is set to true the generated EJB jars are
+ * written into the root of the destination directory, otherwise they
+ * are written out in the same relative position as the deployment
+ * descriptors in the descriptor directory.
+ *
+ * @param inValue the new value of the flatdestdir flag.
+ */
+ public void setFlatdestdir(boolean inValue) {
+ config.flatDestDir = inValue;
+ }
+
+ /**
+ * Set the suffix for the generated jar file. When generic jars are
+ * generated, they have a suffix which is appended to the the bean name
+ * to create the name of the jar file. Note that this suffix includes
+ * the extension fo te jar file and should therefore end with an
+ * appropriate extension such as .jar or .ear
+ *
+ * @param inString the string to use as the suffix.
+ */
+ public void setGenericjarsuffix(String inString) {
+ this.genericJarSuffix = inString;
+ }
+
+ /**
+ * The string which terminates the bean name.
+ * The convention used by this task is
+ * that bean descriptors are named as the BeanName with some suffix. The
+ * baseNameTerminator string separates the bean name and the suffix and
+ * is used to determine the bean name.
+ *
+ * @param inValue a string which marks the end of the basename.
+ */
+ public void setBasenameterminator(String inValue) {
+ config.baseNameTerminator = inValue;
+ }
+
+ /**
+ * Validate the config that has been configured from the build file
+ *
+ * @throws BuildException if the config is not valid
+ */
+ private void validateConfig() throws BuildException {
+ if (config.srcDir == null) {
+ throw new BuildException("The srcDir attribute must be specified");
+ }
+
+ if (config.descriptorDir == null) {
+ config.descriptorDir = config.srcDir;
+ }
+
+ if (config.namingScheme == null) {
+ config.namingScheme = new NamingScheme();
+ config.namingScheme.setValue(NamingScheme.DESCRIPTOR);
+ } else if (config.namingScheme.getValue().equals(NamingScheme.BASEJARNAME)
+ && config.baseJarName == null) {
+ throw new BuildException("The basejarname attribute must "
+ + "be specified with the basejarname naming scheme");
+ }
+ }
+
+ /**
+ * Invoked by Ant after the task is prepared, when it is ready to execute
+ * this task.
+ *
+ * This will configure all of the nested deployment tools to allow them to
+ * process the jar. If no deployment tools have been configured a generic
+ * tool is created to handle the jar.
+ *
+ * A parser is configured and then each descriptor found is passed to all
+ * the deployment tool elements for processing.
+ *
+ * @exception BuildException thrown whenever a problem is
+ * encountered that cannot be recovered from, to signal to ant
+ * that a major problem occurred within this task.
+ */
+ public void execute() throws BuildException {
+ validateConfig();
+
+ if (deploymentTools.size() == 0) {
+ GenericDeploymentTool genericTool = new GenericDeploymentTool();
+ genericTool.setTask(this);
+ genericTool.setDestdir(destDir);
+ genericTool.setGenericJarSuffix(genericJarSuffix);
+ deploymentTools.add(genericTool);
+ }
+
+ for (Iterator i = deploymentTools.iterator(); i.hasNext();) {
+ EJBDeploymentTool tool = (EJBDeploymentTool) i.next();
+ tool.configure(config);
+ tool.validateConfigured();
+ }
+
+ try {
+ // Create the parser using whatever parser the system dictates
+ SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
+ saxParserFactory.setValidating(true);
+ SAXParser saxParser = saxParserFactory.newSAXParser();
+
+
+ DirectoryScanner ds = getDirectoryScanner(config.descriptorDir);
+ ds.scan();
+ String[] files = ds.getIncludedFiles();
+
+ log(files.length + " deployment descriptors located.",
+ Project.MSG_VERBOSE);
+
+ // Loop through the files. Each file represents one deployment
+ // descriptor, and hence one bean in our model.
+ for (int index = 0; index < files.length; ++index) {
+ // process the deployment descriptor in each tool
+ for (Iterator i = deploymentTools.iterator(); i.hasNext();) {
+ EJBDeploymentTool tool = (EJBDeploymentTool) i.next();
+ tool.processDescriptor(files[index], saxParser);
+ }
+ }
+ } catch (SAXException se) {
+ String msg = "SAXException while creating parser."
+ + " Details: "
+ + se.getMessage();
+ throw new BuildException(msg, se);
+ } catch (ParserConfigurationException pce) {
+ String msg = "ParserConfigurationException while creating parser. "
+ + "Details: " + pce.getMessage();
+ throw new BuildException(msg, pce);
+ }
+ } // end of execute()
+
+}
+
+
+
+
+
+
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ejb/GenericDeploymentTool.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ejb/GenericDeploymentTool.java
new file mode 100644
index 00000000..069bdfcf
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ejb/GenericDeploymentTool.java
@@ -0,0 +1,953 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.ejb;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.jar.JarOutputStream;
+import java.util.jar.Manifest;
+import java.util.zip.ZipEntry;
+
+import javax.xml.parsers.SAXParser;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.DirectoryScanner;
+import org.apache.tools.ant.Location;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.types.FileSet;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.util.depend.DependencyAnalyzer;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+
+/**
+ * A deployment tool which creates generic EJB jars. Generic jars contains
+ * only those classes and META-INF entries specified in the EJB 1.1 standard
+ *
+ * This class is also used as a framework for the creation of vendor specific
+ * deployment tools. A number of template methods are provided through which the
+ * vendor specific tool can hook into the EJB creation process.
+ *
+ */
+public class GenericDeploymentTool implements EJBDeploymentTool {
+ /** The default buffer byte size to use for IO */
+ public static final int DEFAULT_BUFFER_SIZE = 1024;
+ /** The level to use for compression */
+ public static final int JAR_COMPRESS_LEVEL = 9;
+
+ /** The standard META-INF directory in jar files */
+ protected static final String META_DIR = "META-INF/";
+
+ /** The standard MANIFEST file */
+ protected static final String MANIFEST = META_DIR + "MANIFEST.MF";
+
+ /** Name for EJB Deployment descriptor within EJB jars */
+ protected static final String EJB_DD = "ejb-jar.xml";
+
+ /** A dependency analyzer name to find ancestor classes */
+ public static final String ANALYZER_SUPER = "super";
+ /** A dependency analyzer name to find all related classes */
+ public static final String ANALYZER_FULL = "full";
+ /** A dependency analyzer name for no analyzer */
+ public static final String ANALYZER_NONE = "none";
+
+ /** The default analyzer */
+ public static final String DEFAULT_ANALYZER = ANALYZER_SUPER;
+
+ /** The analyzer class for the super analyzer */
+ public static final String ANALYZER_CLASS_SUPER
+ = "org.apache.tools.ant.util.depend.bcel.AncestorAnalyzer";
+ /** The analyzer class for the super analyzer */
+ public static final String ANALYZER_CLASS_FULL
+ = "org.apache.tools.ant.util.depend.bcel.FullAnalyzer";
+
+ /**
+ * The configuration from the containing task. This config combined
+ * with the settings of the individual attributes here constitues the
+ * complete config for this deployment tool.
+ */
+ private EjbJar.Config config;
+
+ /** Stores a handle to the directory to put the Jar files in */
+ private File destDir;
+
+ /** The classpath to use with this deployment tool. This is appended to
+ any paths from the ejbjar task itself.*/
+ private Path classpath;
+
+ /** Instance variable that stores the suffix for the generated jarfile. */
+ private String genericJarSuffix = "-generic.jar";
+
+ /**
+ * The task to which this tool belongs. This is used to access services
+ * provided by the ant core, such as logging.
+ */
+ private Task task;
+
+ /**
+ * The classloader generated from the given classpath to load
+ * the super classes and super interfaces.
+ */
+ private ClassLoader classpathLoader = null;
+
+ /**
+ * Set of files have been loaded into the EJB jar
+ */
+ private Set addedfiles;
+
+ /**
+ * Handler used to parse the EJB XML descriptor
+ */
+ private DescriptorHandler handler;
+
+ /**
+ * Dependency analyzer used to collect class dependencies
+ */
+ private DependencyAnalyzer dependencyAnalyzer;
+
+ /** No arg constructor */
+ public GenericDeploymentTool() {
+ }
+
+
+ /**
+ * Set the destination directory; required.
+ * @param inDir the destination directory.
+ */
+ public void setDestdir(File inDir) {
+ this.destDir = inDir;
+ }
+
+ /**
+ * Get the destination directory.
+ *
+ * @return the destination directory into which EJB jars are to be written
+ */
+ protected File getDestDir() {
+ return destDir;
+ }
+
+
+ /**
+ * Set the task which owns this tool
+ *
+ * @param task the Task to which this deployment tool is associated.
+ */
+ public void setTask(Task task) {
+ this.task = task;
+ }
+
+ /**
+ * Get the task for this tool.
+ *
+ * @return the Task instance this tool is associated with.
+ */
+ protected Task getTask() {
+ return task;
+ }
+
+ /**
+ * Get the basename terminator.
+ *
+ * @return an ejbjar task configuration
+ */
+ protected EjbJar.Config getConfig() {
+ return config;
+ }
+
+ /**
+ * Indicate if this build is using the base jar name.
+ *
+ * @return true if the name of the generated jar is coming from the
+ * basejarname attribute
+ */
+ protected boolean usingBaseJarName() {
+ return config.baseJarName != null;
+ }
+
+ /**
+ * Set the suffix for the generated jar file.
+ * @param inString the string to use as the suffix.
+ */
+ public void setGenericJarSuffix(String inString) {
+ this.genericJarSuffix = inString;
+ }
+
+ /**
+ * Add the classpath for the user classes
+ *
+ * @return a Path instance to be configured by Ant.
+ */
+ public Path createClasspath() {
+ if (classpath == null) {
+ classpath = new Path(task.getProject());
+ }
+ return classpath.createPath();
+ }
+
+ /**
+ * Set the classpath to be used for this compilation.
+ *
+ * @param classpath the classpath to be used for this build.
+ */
+ public void setClasspath(Path classpath) {
+ this.classpath = classpath;
+ }
+
+ /**
+ * Get the classpath by combining the one from the surrounding task, if any
+ * and the one from this tool.
+ *
+ * @return the combined classpath
+ */
+ protected Path getCombinedClasspath() {
+ Path combinedPath = classpath;
+ if (config.classpath != null) {
+ if (combinedPath == null) {
+ combinedPath = config.classpath;
+ } else {
+ combinedPath.append(config.classpath);
+ }
+ }
+
+ return combinedPath;
+ }
+
+ /**
+ * Log a message to the Ant output.
+ *
+ * @param message the message to be logged.
+ * @param level the severity of this message.
+ */
+ protected void log(String message, int level) {
+ getTask().log(message, level);
+ }
+
+ /**
+ * Get the build file location associated with this element's task.
+ *
+ * @return the task's location instance.
+ */
+ protected Location getLocation() {
+ return getTask().getLocation();
+ }
+
+ private void createAnalyzer() {
+ String analyzer = config.analyzer;
+ if (analyzer == null) {
+ analyzer = DEFAULT_ANALYZER;
+ }
+
+ if (analyzer.equals(ANALYZER_NONE)) {
+ return;
+ }
+
+ String analyzerClassName = null;
+ if (analyzer.equals(ANALYZER_SUPER)) {
+ analyzerClassName = ANALYZER_CLASS_SUPER;
+ } else if (analyzer.equals(ANALYZER_FULL)) {
+ analyzerClassName = ANALYZER_CLASS_FULL;
+ } else {
+ analyzerClassName = analyzer;
+ }
+
+ try {
+ Class analyzerClass = Class.forName(analyzerClassName);
+ dependencyAnalyzer
+ = (DependencyAnalyzer) analyzerClass.newInstance();
+ dependencyAnalyzer.addClassPath(new Path(task.getProject(),
+ config.srcDir.getPath()));
+ dependencyAnalyzer.addClassPath(config.classpath);
+ } catch (NoClassDefFoundError e) {
+ dependencyAnalyzer = null;
+ task.log("Unable to load dependency analyzer: " + analyzerClassName
+ + " - dependent class not found: " + e.getMessage(),
+ Project.MSG_WARN);
+ } catch (Exception e) {
+ dependencyAnalyzer = null;
+ task.log("Unable to load dependency analyzer: " + analyzerClassName
+ + " - exception: " + e.getMessage(),
+ Project.MSG_WARN);
+ }
+ }
+
+
+ /**
+ * Configure this tool for use in the ejbjar task.
+ *
+ * @param config the configuration from the surrounding ejbjar task.
+ */
+ public void configure(EjbJar.Config config) {
+ this.config = config;
+
+ createAnalyzer();
+ classpathLoader = null;
+ }
+
+ /**
+ * Utility method that encapsulates the logic of adding a file entry to
+ * a .jar file. Used by execute() to add entries to the jar file as it is
+ * constructed.
+ * @param jStream A JarOutputStream into which to write the
+ * jar entry.
+ * @param inputFile A File from which to read the
+ * contents the file being added.
+ * @param logicalFilename A String representing the name, including
+ * all relevant path information, that should be stored for the entry
+ * being added.
+ * @throws BuildException if there is a problem.
+ */
+ protected void addFileToJar(JarOutputStream jStream,
+ File inputFile,
+ String logicalFilename)
+ throws BuildException {
+ FileInputStream iStream = null;
+ try {
+ if (!addedfiles.contains(logicalFilename)) {
+ iStream = new FileInputStream(inputFile);
+ // Create the zip entry and add it to the jar file
+ ZipEntry zipEntry = new ZipEntry(logicalFilename.replace('\\', '/'));
+ jStream.putNextEntry(zipEntry);
+
+ // Create the file input stream, and buffer everything over
+ // to the jar output stream
+ byte[] byteBuffer = new byte[2 * DEFAULT_BUFFER_SIZE];
+ int count = 0;
+ do {
+ jStream.write(byteBuffer, 0, count);
+ count = iStream.read(byteBuffer, 0, byteBuffer.length);
+ } while (count != -1);
+
+ //add it to list of files in jar
+ addedfiles.add(logicalFilename);
+ }
+ } catch (IOException ioe) {
+ log("WARNING: IOException while adding entry "
+ + logicalFilename + " to jarfile from "
+ + inputFile.getPath() + " " + ioe.getClass().getName()
+ + "-" + ioe.getMessage(), Project.MSG_WARN);
+ } finally {
+ // Close up the file input stream for the class file
+ if (iStream != null) {
+ try {
+ iStream.close();
+ } catch (IOException closeException) {
+ // ignore
+ }
+ }
+ }
+ }
+
+ /**
+ * Get a descriptionHandler.
+ * @param srcDir the source directory.
+ * @return a handler.
+ */
+ protected DescriptorHandler getDescriptorHandler(File srcDir) {
+ DescriptorHandler h = new DescriptorHandler(getTask(), srcDir);
+
+ registerKnownDTDs(h);
+
+ // register any DTDs supplied by the user
+ for (Iterator i = getConfig().dtdLocations.iterator(); i.hasNext();) {
+ EjbJar.DTDLocation dtdLocation = (EjbJar.DTDLocation) i.next();
+ h.registerDTD(dtdLocation.getPublicId(), dtdLocation.getLocation());
+ }
+ return h;
+ }
+
+ /**
+ * Register the locations of all known DTDs.
+ *
+ * vendor-specific subclasses should override this method to define
+ * the vendor-specific locations of the EJB DTDs
+ * @param handler no used in this class.
+ */
+ protected void registerKnownDTDs(DescriptorHandler handler) {
+ // none to register for generic
+ }
+
+ /** {@inheritDoc}. */
+ public void processDescriptor(String descriptorFileName, SAXParser saxParser) {
+
+ checkConfiguration(descriptorFileName, saxParser);
+
+ try {
+ handler = getDescriptorHandler(config.srcDir);
+
+ // Retrive the files to be added to JAR from EJB descriptor
+ Hashtable ejbFiles = parseEjbFiles(descriptorFileName, saxParser);
+
+ // Add any support classes specified in the build file
+ addSupportClasses(ejbFiles);
+
+ // Determine the JAR filename (without filename extension)
+ String baseName = getJarBaseName(descriptorFileName);
+
+ String ddPrefix = getVendorDDPrefix(baseName, descriptorFileName);
+
+ File manifestFile = getManifestFile(ddPrefix);
+ if (manifestFile != null) {
+ ejbFiles.put(MANIFEST, manifestFile);
+ }
+
+
+
+ // First the regular deployment descriptor
+ ejbFiles.put(META_DIR + EJB_DD,
+ new File(config.descriptorDir, descriptorFileName));
+
+ // now the vendor specific files, if any
+ addVendorFiles(ejbFiles, ddPrefix);
+
+ // add any dependent files
+ checkAndAddDependants(ejbFiles);
+
+ // Lastly create File object for the Jar files. If we are using
+ // a flat destination dir, then we need to redefine baseName!
+ if (config.flatDestDir && baseName.length() != 0) {
+ int startName = baseName.lastIndexOf(File.separator);
+ if (startName == -1) {
+ startName = 0;
+ }
+
+ int endName = baseName.length();
+ baseName = baseName.substring(startName, endName);
+ }
+
+ File jarFile = getVendorOutputJarFile(baseName);
+
+
+ // Check to see if we need a build and start doing the work!
+ if (needToRebuild(ejbFiles, jarFile)) {
+ // Log that we are going to build...
+ log("building "
+ + jarFile.getName()
+ + " with "
+ + String.valueOf(ejbFiles.size())
+ + " files",
+ Project.MSG_INFO);
+
+ // Use helper method to write the jarfile
+ String publicId = getPublicId();
+ writeJar(baseName, jarFile, ejbFiles, publicId);
+
+ } else {
+ // Log that the file is up to date...
+ log(jarFile.toString() + " is up to date.",
+ Project.MSG_VERBOSE);
+ }
+
+ } catch (SAXException se) {
+ String msg = "SAXException while parsing '"
+ + descriptorFileName
+ + "'. This probably indicates badly-formed XML."
+ + " Details: "
+ + se.getMessage();
+ throw new BuildException(msg, se);
+ } catch (IOException ioe) {
+ String msg = "IOException while parsing'"
+ + descriptorFileName
+ + "'. This probably indicates that the descriptor"
+ + " doesn't exist. Details: "
+ + ioe.getMessage();
+ throw new BuildException(msg, ioe);
+ }
+ }
+
+ /**
+ * This method is called as the first step in the processDescriptor method
+ * to allow vendor-specific subclasses to validate the task configuration
+ * prior to processing the descriptor. If the configuration is invalid,
+ * a BuildException should be thrown.
+ *
+ * @param descriptorFileName String representing the file name of an EJB
+ * descriptor to be processed
+ * @param saxParser SAXParser which may be used to parse the XML
+ * descriptor
+ * @throws BuildException if there is a problem.
+ */
+ protected void checkConfiguration(String descriptorFileName,
+ SAXParser saxParser) throws BuildException {
+
+ /*
+ * For the GenericDeploymentTool, do nothing. Vendor specific
+ * subclasses should throw a BuildException if the configuration is
+ * invalid for their server.
+ */
+ }
+
+ /**
+ * This method returns a list of EJB files found when the specified EJB
+ * descriptor is parsed and processed.
+ *
+ * @param descriptorFileName String representing the file name of an EJB
+ * descriptor to be processed
+ * @param saxParser SAXParser which may be used to parse the XML
+ * descriptor
+ * @return Hashtable of EJB class (and other) files to be
+ * added to the completed JAR file
+ * @throws SAXException Any SAX exception, possibly wrapping another
+ * exception
+ * @throws IOException An IOException from the parser, possibly from a
+ * the byte stream or character stream
+ */
+ protected Hashtable parseEjbFiles(String descriptorFileName, SAXParser saxParser)
+ throws IOException, SAXException {
+ FileInputStream descriptorStream = null;
+ Hashtable ejbFiles = null;
+
+ try {
+
+ /* Parse the ejb deployment descriptor. While it may not
+ * look like much, we use a SAXParser and an inner class to
+ * get hold of all the classfile names for the descriptor.
+ */
+ descriptorStream
+ = new FileInputStream(new File(config.descriptorDir, descriptorFileName));
+ saxParser.parse(new InputSource(descriptorStream), handler);
+
+ ejbFiles = handler.getFiles();
+
+ } finally {
+ if (descriptorStream != null) {
+ try {
+ descriptorStream.close();
+ } catch (IOException closeException) {
+ // ignore
+ }
+ }
+ }
+
+ return ejbFiles;
+ }
+
+ /**
+ * Adds any classes the user specifies using <i>support</i> nested elements
+ * to the <code>ejbFiles</code> Hashtable.
+ *
+ * @param ejbFiles Hashtable of EJB classes (and other) files that will be
+ * added to the completed JAR file
+ */
+ protected void addSupportClasses(Hashtable ejbFiles) {
+ // add in support classes if any
+ Project project = task.getProject();
+ for (Iterator i = config.supportFileSets.iterator(); i.hasNext();) {
+ FileSet supportFileSet = (FileSet) i.next();
+ File supportBaseDir = supportFileSet.getDir(project);
+ DirectoryScanner supportScanner = supportFileSet.getDirectoryScanner(project);
+ supportScanner.scan();
+ String[] supportFiles = supportScanner.getIncludedFiles();
+ for (int j = 0; j < supportFiles.length; ++j) {
+ ejbFiles.put(supportFiles[j], new File(supportBaseDir, supportFiles[j]));
+ }
+ }
+ }
+
+
+ /**
+ * Using the EJB descriptor file name passed from the <code>ejbjar</code>
+ * task, this method returns the "basename" which will be used to name the
+ * completed JAR file.
+ *
+ * @param descriptorFileName String representing the file name of an EJB
+ * descriptor to be processed
+ * @return The "basename" which will be used to name the
+ * completed JAR file
+ */
+ protected String getJarBaseName(String descriptorFileName) {
+
+ String baseName = "";
+
+ // Work out what the base name is
+ if (config.namingScheme.getValue().equals(EjbJar.NamingScheme.BASEJARNAME)) {
+ String canonicalDescriptor = descriptorFileName.replace('\\', '/');
+ int index = canonicalDescriptor.lastIndexOf('/');
+ if (index != -1) {
+ baseName = descriptorFileName.substring(0, index + 1);
+ }
+ baseName += config.baseJarName;
+ } else if (config.namingScheme.getValue().equals(EjbJar.NamingScheme.DESCRIPTOR)) {
+ int lastSeparatorIndex = descriptorFileName.lastIndexOf(File.separator);
+ int endBaseName = -1;
+ if (lastSeparatorIndex != -1) {
+ endBaseName = descriptorFileName.indexOf(config.baseNameTerminator,
+ lastSeparatorIndex);
+ } else {
+ endBaseName = descriptorFileName.indexOf(config.baseNameTerminator);
+ }
+
+ if (endBaseName != -1) {
+ baseName = descriptorFileName.substring(0, endBaseName);
+ } else {
+ throw new BuildException("Unable to determine jar name "
+ + "from descriptor \"" + descriptorFileName + "\"");
+ }
+ } else if (config.namingScheme.getValue().equals(EjbJar.NamingScheme.DIRECTORY)) {
+ File descriptorFile = new File(config.descriptorDir, descriptorFileName);
+ String path = descriptorFile.getAbsolutePath();
+ int lastSeparatorIndex
+ = path.lastIndexOf(File.separator);
+ if (lastSeparatorIndex == -1) {
+ throw new BuildException("Unable to determine directory name holding descriptor");
+ }
+ String dirName = path.substring(0, lastSeparatorIndex);
+ int dirSeparatorIndex = dirName.lastIndexOf(File.separator);
+ if (dirSeparatorIndex != -1) {
+ dirName = dirName.substring(dirSeparatorIndex + 1);
+ }
+
+ baseName = dirName;
+ } else if (config.namingScheme.getValue().equals(EjbJar.NamingScheme.EJB_NAME)) {
+ baseName = handler.getEjbName();
+ }
+ return baseName;
+ }
+
+ /**
+ * Get the prefix for vendor deployment descriptors.
+ *
+ * This will contain the path and the start of the descriptor name,
+ * depending on the naming scheme
+ * @param baseName the base name to use.
+ * @param descriptorFileName the file name to use.
+ * @return the prefix.
+ */
+ public String getVendorDDPrefix(String baseName, String descriptorFileName) {
+ String ddPrefix = null;
+
+ if (config.namingScheme.getValue().equals(EjbJar.NamingScheme.DESCRIPTOR)) {
+ ddPrefix = baseName + config.baseNameTerminator;
+ } else if (config.namingScheme.getValue().equals(EjbJar.NamingScheme.BASEJARNAME)
+ || config.namingScheme.getValue().equals(EjbJar.NamingScheme.EJB_NAME)
+ || config.namingScheme.getValue().equals(EjbJar.NamingScheme.DIRECTORY)) {
+ String canonicalDescriptor = descriptorFileName.replace('\\', '/');
+ int index = canonicalDescriptor.lastIndexOf('/');
+ if (index == -1) {
+ ddPrefix = "";
+ } else {
+ ddPrefix = descriptorFileName.substring(0, index + 1);
+ }
+ }
+ return ddPrefix;
+ }
+
+ /**
+ * Add any vendor specific files which should be included in the
+ * EJB Jar.
+ * @param ejbFiles a hashtable entryname -> file.
+ * @param ddPrefix a prefix to use.
+ */
+ protected void addVendorFiles(Hashtable ejbFiles, String ddPrefix) {
+ // nothing to add for generic tool.
+ }
+
+
+ /**
+ * Get the vendor specific name of the Jar that will be output. The modification date
+ * of this jar will be checked against the dependent bean classes.
+ * @param baseName the basename to use.
+ */
+ File getVendorOutputJarFile(String baseName) {
+ return new File(destDir, baseName + genericJarSuffix);
+ }
+
+ /**
+ * This method checks the timestamp on each file listed in the <code>
+ * ejbFiles</code> and compares them to the timestamp on the <code>jarFile
+ * </code>. If the <code>jarFile</code>'s timestamp is more recent than
+ * each EJB file, <code>true</code> is returned. Otherwise, <code>false
+ * </code> is returned.
+ * TODO: find a way to check the manifest-file, that is found by naming convention
+ *
+ * @param ejbFiles Hashtable of EJB classes (and other) files that will be
+ * added to the completed JAR file
+ * @param jarFile JAR file which will contain all of the EJB classes (and
+ * other) files
+ * @return boolean indicating whether or not the <code>jarFile</code>
+ * is up to date
+ */
+ protected boolean needToRebuild(Hashtable ejbFiles, File jarFile) {
+ if (jarFile.exists()) {
+ long lastBuild = jarFile.lastModified();
+
+ Iterator fileIter = ejbFiles.values().iterator();
+
+ // Loop through the files seeing if any has been touched
+ // more recently than the destination jar.
+ while (fileIter.hasNext()) {
+ File currentFile = (File) fileIter.next();
+ if (lastBuild < currentFile.lastModified()) {
+ log("Build needed because " + currentFile.getPath() + " is out of date",
+ Project.MSG_VERBOSE);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Returns the Public ID of the DTD specified in the EJB descriptor. Not
+ * every vendor-specific <code>DeploymentTool</code> will need to reference
+ * this value or may want to determine this value in a vendor-specific way.
+ *
+ * @return Public ID of the DTD specified in the EJB descriptor.
+ */
+ protected String getPublicId() {
+ return handler.getPublicId();
+ }
+
+ /**
+ * Get the manifest file to use for building the generic jar.
+ *
+ * If the file does not exist the global manifest from the config is used
+ * otherwise the default Ant manifest will be used.
+ *
+ * @param prefix the prefix where to llook for the manifest file based on
+ * the naming convention.
+ *
+ * @return the manifest file or null if the manifest file does not exist
+ */
+ protected File getManifestFile(String prefix) {
+ File manifestFile
+ = new File(getConfig().descriptorDir, prefix + "manifest.mf");
+ if (manifestFile.exists()) {
+ return manifestFile;
+ }
+
+ if (config.manifest != null) {
+ return config.manifest;
+ }
+ return null;
+ }
+
+ /**
+ * Method used to encapsulate the writing of the JAR file. Iterates over the
+ * filenames/java.io.Files in the Hashtable stored on the instance variable
+ * ejbFiles.
+ * @param baseName the base name to use.
+ * @param jarfile the jar file to write to.
+ * @param files the files to write to the jar.
+ * @param publicId the id to use.
+ * @throws BuildException if there is a problem.
+ */
+ protected void writeJar(String baseName, File jarfile, Hashtable files,
+ String publicId) throws BuildException {
+
+ JarOutputStream jarStream = null;
+ try {
+ // clean the addedfiles set
+ if (addedfiles == null) {
+ addedfiles = new HashSet();
+ } else {
+ addedfiles.clear();
+ }
+
+ /* If the jarfile already exists then whack it and recreate it.
+ * Should probably think of a more elegant way to handle this
+ * so that in case of errors we don't leave people worse off
+ * than when we started =)
+ */
+ if (jarfile.exists()) {
+ jarfile.delete();
+ }
+ jarfile.getParentFile().mkdirs();
+ jarfile.createNewFile();
+
+ InputStream in = null;
+ Manifest manifest = null;
+ try {
+ File manifestFile = (File) files.get(MANIFEST);
+ if (manifestFile != null && manifestFile.exists()) {
+ in = new FileInputStream(manifestFile);
+ } else {
+ String defaultManifest = "/org/apache/tools/ant/defaultManifest.mf";
+ in = this.getClass().getResourceAsStream(defaultManifest);
+ if (in == null) {
+ throw new BuildException("Could not find "
+ + "default manifest: " + defaultManifest);
+ }
+ }
+
+ manifest = new Manifest(in);
+ } catch (IOException e) {
+ throw new BuildException ("Unable to read manifest", e, getLocation());
+ } finally {
+ if (in != null) {
+ in.close();
+ }
+ }
+
+ // Create the streams necessary to write the jarfile
+
+ jarStream = new JarOutputStream(new FileOutputStream(jarfile), manifest);
+ jarStream.setMethod(JarOutputStream.DEFLATED);
+
+ // Loop through all the class files found and add them to the jar
+ for (Iterator entryIterator = files.keySet().iterator(); entryIterator.hasNext();) {
+ String entryName = (String) entryIterator.next();
+ if (entryName.equals(MANIFEST)) {
+ continue;
+ }
+
+ File entryFile = (File) files.get(entryName);
+
+ log("adding file '" + entryName + "'",
+ Project.MSG_VERBOSE);
+
+ addFileToJar(jarStream, entryFile, entryName);
+
+ // See if there are any inner classes for this class and add them in if there are
+ InnerClassFilenameFilter flt = new InnerClassFilenameFilter(entryFile.getName());
+ File entryDir = entryFile.getParentFile();
+ String[] innerfiles = entryDir.list(flt);
+ if (innerfiles != null) {
+ for (int i = 0, n = innerfiles.length; i < n; i++) {
+
+ //get and clean up innerclass name
+ int entryIndex = entryName.lastIndexOf(entryFile.getName()) - 1;
+ if (entryIndex < 0) {
+ entryName = innerfiles[i];
+ } else {
+ entryName = entryName.substring(0, entryIndex)
+ + File.separatorChar + innerfiles[i];
+ }
+ // link the file
+ entryFile = new File(config.srcDir, entryName);
+
+ log("adding innerclass file '" + entryName + "'",
+ Project.MSG_VERBOSE);
+
+ addFileToJar(jarStream, entryFile, entryName);
+
+ }
+ }
+ }
+ } catch (IOException ioe) {
+ String msg = "IOException while processing ejb-jar file '"
+ + jarfile.toString()
+ + "'. Details: "
+ + ioe.getMessage();
+ throw new BuildException(msg, ioe);
+ } finally {
+ if (jarStream != null) {
+ try {
+ jarStream.close();
+ } catch (IOException closeException) {
+ // ignore
+ }
+ }
+ }
+ } // end of writeJar
+
+
+ /**
+ * Add all available classes, that depend on Remote, Home, Bean, PK
+ * @param checkEntries files, that are extracted from the deployment descriptor
+ * @throws BuildException if there is a problem.
+ */
+ protected void checkAndAddDependants(Hashtable checkEntries)
+ throws BuildException {
+
+ if (dependencyAnalyzer == null) {
+ return;
+ }
+
+ dependencyAnalyzer.reset();
+
+ Iterator i = checkEntries.keySet().iterator();
+ while (i.hasNext()) {
+ String entryName = (String) i.next();
+ if (entryName.endsWith(".class")) {
+ String className = entryName.substring(0,
+ entryName.length() - ".class".length());
+ className = className.replace(File.separatorChar, '/');
+ className = className.replace('/', '.');
+
+ dependencyAnalyzer.addRootClass(className);
+ }
+ }
+
+ Enumeration e = dependencyAnalyzer.getClassDependencies();
+
+ while (e.hasMoreElements()) {
+ String classname = (String) e.nextElement();
+ String location
+ = classname.replace('.', File.separatorChar) + ".class";
+ File classFile = new File(config.srcDir, location);
+ if (classFile.exists()) {
+ checkEntries.put(location, classFile);
+ log("dependent class: " + classname + " - " + classFile,
+ Project.MSG_VERBOSE);
+ }
+ }
+ }
+
+
+ /**
+ * Returns a Classloader object which parses the passed in generic EjbJar classpath.
+ * The loader is used to dynamically load classes from javax.ejb.* and the classes
+ * being added to the jar.
+ * @return a classloader.
+ */
+ protected ClassLoader getClassLoaderForBuild() {
+ if (classpathLoader != null) {
+ return classpathLoader;
+ }
+
+ Path combinedClasspath = getCombinedClasspath();
+
+ // only generate a new ClassLoader if we have a classpath
+ if (combinedClasspath == null) {
+ classpathLoader = getClass().getClassLoader();
+ } else {
+ // Memory leak in line below
+ classpathLoader
+ = getTask().getProject().createClassLoader(combinedClasspath);
+ }
+
+ return classpathLoader;
+ }
+
+ /**
+ * Called to validate that the tool parameters have been configured.
+ *
+ * @throws BuildException If the Deployment Tool's configuration isn't
+ * valid
+ */
+ public void validateConfigured() throws BuildException {
+ if ((destDir == null) || (!destDir.isDirectory())) {
+ String msg = "A valid destination directory must be specified "
+ + "using the \"destdir\" attribute.";
+ throw new BuildException(msg, getLocation());
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ejb/IPlanetDeploymentTool.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ejb/IPlanetDeploymentTool.java
new file mode 100644
index 00000000..cbc8526a
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ejb/IPlanetDeploymentTool.java
@@ -0,0 +1,403 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.ejb;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Hashtable;
+import java.util.Iterator;
+
+import javax.xml.parsers.SAXParser;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.xml.sax.SAXException;
+
+/**
+ * This class is used to generate iPlanet Application Server (iAS) 6.0 stubs and
+ * skeletons and build an EJB Jar file. It is designed to be used with the Ant
+ * <code>ejbjar</code> task. If only stubs and skeletons need to be generated
+ * (in other words, if no JAR file needs to be created), refer to the
+ * <code>iplanet-ejbc</code> task and the <code>IPlanetEjbcTask</code> class.
+ * <p>
+ * The following attributes may be specified by the user:
+ * <ul>
+ * <li><i>destdir</i> -- The base directory into which the generated JAR
+ * files will be written. Each JAR file is written
+ * in directories which correspond to their location
+ * within the "descriptordir" namespace. This is a
+ * required attribute.
+ * <li><i>classpath</i> -- The classpath used when generating EJB stubs and
+ * skeletons. This is an optional attribute (if
+ * omitted, the classpath specified in the "ejbjar"
+ * parent task will be used). If specified, the
+ * classpath elements will be prepended to the
+ * classpath specified in the parent "ejbjar" task.
+ * Note that nested "classpath" elements may also be
+ * used.
+ * <li><i>keepgenerated</i> -- Indicates whether or not the Java source
+ * files which are generated by ejbc will be
+ * saved or automatically deleted. If "yes",
+ * the source files will be retained. This is
+ * an optional attribute (if omitted, it
+ * defaults to "no").
+ * <li><i>debug</i> -- Indicates whether or not the ejbc utility should
+ * log additional debugging statements to the standard
+ * output. If "yes", the additional debugging statements
+ * will be generated (if omitted, it defaults to "no").
+ * <li><i>iashome</i> -- May be used to specify the "home" directory for
+ * this iPlanet Application server installation. This
+ * is used to find the ejbc utility if it isn't
+ * included in the user's system path. This is an
+ * optional attribute (if specified, it should refer
+ * to the <code>[install-location]/iplanet/ias6/ias
+ * </code> directory). If omitted, the ejbc utility
+ * must be on the user's system path.
+ * <li><i>suffix</i> -- String value appended to the JAR filename when
+ * creating each JAR. This attribute is not required
+ * (if omitted, it defaults to ".jar").
+ * </ul>
+ * <p>
+ * For each EJB descriptor found in the "ejbjar" parent task, this deployment
+ * tool will locate the three classes that comprise the EJB. If these class
+ * files cannot be located in the specified <code>srcdir</code> directory, the
+ * task will fail. The task will also attempt to locate the EJB stubs and
+ * skeletons in this directory. If found, the timestamps on the stubs and
+ * skeletons will be checked to ensure they are up to date. Only if these files
+ * cannot be found or if they are out of date will ejbc be called.
+ *
+ * @see IPlanetEjbc
+ */
+public class IPlanetDeploymentTool extends GenericDeploymentTool {
+
+ /* Attributes set by the Ant build file */
+ private File iashome;
+ private String jarSuffix = ".jar";
+ private boolean keepgenerated = false;
+ private boolean debug = false;
+
+ /*
+ * Filenames of the standard EJB descriptor (which is passed to this class
+ * from the parent "ejbjar" task) and the iAS-specific EJB descriptor
+ * (whose name is determined by this class). Both filenames are relative
+ * to the directory specified by the "srcdir" attribute in the ejbjar task.
+ */
+ private String descriptorName;
+ private String iasDescriptorName;
+
+ /*
+ * The displayName variable stores the value of the "display-name" element
+ * from the standard EJB descriptor. As a future enhancement to this task,
+ * we may determine the name of the EJB JAR file using this display-name,
+ * but this has not be implemented yet.
+ */
+ private String displayName;
+
+ /*
+ * Regardless of the name of the iAS-specific EJB descriptor file, it will
+ * written in the completed JAR file as "ias-ejb-jar.xml". This is the
+ * naming convention implemented by iAS.
+ */
+ private static final String IAS_DD = "ias-ejb-jar.xml";
+
+ /**
+ * Setter method used to store the "home" directory of the user's iAS
+ * installation. The directory specified should typically be
+ * <code>[install-location]/iplanet/ias6/ias</code>.
+ *
+ * @param iashome The home directory for the user's iAS installation.
+ */
+ public void setIashome(File iashome) {
+ this.iashome = iashome;
+ }
+
+ /**
+ * Setter method used to specify whether the Java source files generated by
+ * the ejbc utility should be saved or automatically deleted.
+ *
+ * @param keepgenerated boolean which, if <code>true</code>, indicates that
+ * Java source files generated by ejbc for the stubs
+ * and skeletons should be kept.
+ */
+ public void setKeepgenerated(boolean keepgenerated) {
+ this.keepgenerated = keepgenerated;
+ }
+
+ /**
+ * Sets whether or not debugging output will be generated when ejbc is
+ * executed.
+ *
+ * @param debug A boolean indicating if debugging output should be generated
+ */
+ public void setDebug(boolean debug) {
+ this.debug = debug;
+ }
+
+ /**
+ * Setter method used to specify the filename suffix (for example, ".jar")
+ * for the JAR files to be created.
+ *
+ * @param jarSuffix The string to use as the JAR filename suffix.
+ */
+ public void setSuffix(String jarSuffix) {
+ this.jarSuffix = jarSuffix;
+ }
+
+ /**
+ * Since iAS doesn't generate a "generic" JAR as part of its processing,
+ * this attribute is ignored and a warning message is displayed to the user.
+ *
+ * @param inString the string to use as the suffix. This parameter is
+ * ignored.
+ */
+ @Override
+ public void setGenericJarSuffix(String inString) {
+ log("Since a generic JAR file is not created during processing, the "
+ + "iPlanet Deployment Tool does not support the "
+ + "\"genericjarsuffix\" attribute. It will be ignored.",
+ Project.MSG_WARN);
+ }
+
+ /** {@inheritDoc}. */
+ @Override
+ public void processDescriptor(String descriptorName, SAXParser saxParser) {
+ this.descriptorName = descriptorName;
+ this.iasDescriptorName = null;
+
+ log("iPlanet Deployment Tool processing: " + descriptorName + " (and "
+ + getIasDescriptorName() + ")", Project.MSG_VERBOSE);
+
+ super.processDescriptor(descriptorName, saxParser);
+ }
+
+ /**
+ * Verifies that the user selections are valid.
+ *
+ * @param descriptorFileName String representing the file name of an EJB
+ * descriptor to be processed
+ * @param saxParser SAXParser which may be used to parse the XML
+ * descriptor
+ * @throws BuildException If the user selections are invalid.
+ */
+ @Override
+ protected void checkConfiguration(String descriptorFileName,
+ SAXParser saxParser) throws BuildException {
+
+ int startOfName = descriptorFileName.lastIndexOf(File.separatorChar) + 1;
+ String stdXml = descriptorFileName.substring(startOfName);
+ if (stdXml.equals(EJB_DD) && (getConfig().baseJarName == null)) {
+ String msg = "No name specified for the completed JAR file. The EJB"
+ + " descriptor should be prepended with the JAR "
+ + "name or it should be specified using the "
+ + "attribute \"basejarname\" in the \"ejbjar\" task.";
+ throw new BuildException(msg, getLocation());
+ }
+
+ File iasDescriptor = new File(getConfig().descriptorDir,
+ getIasDescriptorName());
+ if ((!iasDescriptor.exists()) || (!iasDescriptor.isFile())) {
+ String msg = "The iAS-specific EJB descriptor ("
+ + iasDescriptor + ") was not found.";
+ throw new BuildException(msg, getLocation());
+ }
+
+ if ((iashome != null) && (!iashome.isDirectory())) {
+ String msg = "If \"iashome\" is specified, it must be a valid "
+ + "directory (it was set to " + iashome + ").";
+ throw new BuildException(msg, getLocation());
+ }
+ }
+
+ /**
+ * This method returns a list of EJB files found when the specified EJB
+ * descriptor is parsed and processed.
+ *
+ * @param descriptorFileName String representing the file name of an EJB
+ * descriptor to be processed
+ * @param saxParser SAXParser which may be used to parse the XML
+ * descriptor
+ * @return Hashtable of EJB class (and other) files to be
+ * added to the completed JAR file
+ * @throws IOException An IOException from the parser, possibly from
+ * the byte stream or character stream
+ * @throws SAXException Any SAX exception, possibly wrapping another
+ * exception
+ */
+ @Override
+ protected Hashtable parseEjbFiles(String descriptorFileName,
+ SAXParser saxParser) throws IOException, SAXException {
+
+ Hashtable files;
+
+ /* Build and populate an instance of the ejbc utility */
+ IPlanetEjbc ejbc = new IPlanetEjbc(
+ new File(getConfig().descriptorDir,
+ descriptorFileName),
+ new File(getConfig().descriptorDir,
+ getIasDescriptorName()),
+ getConfig().srcDir,
+ getCombinedClasspath().toString(),
+ saxParser);
+ ejbc.setRetainSource(keepgenerated);
+ ejbc.setDebugOutput(debug);
+ if (iashome != null) {
+ ejbc.setIasHomeDir(iashome);
+ }
+ if (getConfig().dtdLocations != null) {
+ for (Iterator i = getConfig().dtdLocations.iterator();
+ i.hasNext();) {
+ EjbJar.DTDLocation dtdLocation =
+ (EjbJar.DTDLocation) i.next();
+ ejbc.registerDTD(dtdLocation.getPublicId(),
+ dtdLocation.getLocation());
+ }
+ }
+
+ /* Execute the ejbc utility -- stubs/skeletons are rebuilt, if needed */
+ try {
+ ejbc.execute();
+ } catch (IPlanetEjbc.EjbcException e) {
+ throw new BuildException("An error has occurred while trying to "
+ + "execute the iAS ejbc utility", e, getLocation());
+ }
+
+ displayName = ejbc.getDisplayName();
+ files = ejbc.getEjbFiles();
+
+ /* Add CMP descriptors to the list of EJB files */
+ String[] cmpDescriptors = ejbc.getCmpDescriptors();
+ if (cmpDescriptors.length > 0) {
+ File baseDir = getConfig().descriptorDir;
+
+ int endOfPath = descriptorFileName.lastIndexOf(File.separator);
+ String relativePath = descriptorFileName.substring(0, endOfPath + 1);
+
+ for (int i = 0; i < cmpDescriptors.length; i++) {
+ int endOfCmp = cmpDescriptors[i].lastIndexOf('/');
+ String cmpDescriptor = cmpDescriptors[i].substring(endOfCmp + 1);
+
+ File cmpFile = new File(baseDir, relativePath + cmpDescriptor);
+ if (!cmpFile.exists()) {
+ throw new BuildException("The CMP descriptor file ("
+ + cmpFile + ") could not be found.", getLocation());
+ }
+ files.put(cmpDescriptors[i], cmpFile);
+ }
+ }
+
+ return files;
+ }
+
+ /**
+ * Add the iAS-specific EJB descriptor to the list of files which will be
+ * written to the JAR file.
+ *
+ * @param ejbFiles Hashtable of EJB class (and other) files to be added to
+ * the completed JAR file.
+ * @param ddPrefix not used
+ */
+ @Override
+ protected void addVendorFiles(Hashtable ejbFiles, String ddPrefix) {
+ ejbFiles.put(META_DIR + IAS_DD, new File(getConfig().descriptorDir,
+ getIasDescriptorName()));
+ }
+
+ /**
+ * Get the name of the Jar that will be written. The modification date
+ * of this jar will be checked against the dependent bean classes.
+ *
+ * @param baseName String name of the EJB JAR file to be written (without
+ * a filename extension).
+ *
+ * @return File representing the JAR file which will be written.
+ */
+ @Override
+ File getVendorOutputJarFile(String baseName) {
+ File jarFile = new File(getDestDir(), baseName + jarSuffix);
+ log("JAR file name: " + jarFile.toString(), Project.MSG_VERBOSE);
+ return jarFile;
+ }
+
+ /**
+ * The iAS ejbc utility doesn't require the Public ID of the descriptor's
+ * DTD for it to process correctly--this method always returns <code>null
+ * </code>.
+ *
+ * @return <code>null</code>.
+ */
+ @Override
+ protected String getPublicId() {
+ return null;
+ }
+
+ /**
+ * Determines the name of the iAS-specific EJB descriptor using the
+ * specified standard EJB descriptor name. In general, the standard
+ * descriptor will be named "[basename]-ejb-jar.xml", and this method will
+ * return "[basename]-ias-ejb-jar.xml".
+ *
+ * @return The name of the iAS-specific EJB descriptor file.
+ */
+ private String getIasDescriptorName() {
+
+ /* Only calculate the descriptor name once */
+ if (iasDescriptorName != null) {
+ return iasDescriptorName;
+ }
+
+ String path = ""; // Directory path of the EJB descriptor
+ String basename; // Filename appearing before name terminator
+ String remainder; // Filename appearing after the name terminator
+
+ /* Find the end of the standard descriptor's relative path */
+ int startOfFileName = descriptorName.lastIndexOf(File.separatorChar);
+ if (startOfFileName != -1) {
+ path = descriptorName.substring(0, startOfFileName + 1);
+ }
+
+ /* Check to see if the standard name is used (there's no basename) */
+ if (descriptorName.substring(startOfFileName + 1).equals(EJB_DD)) {
+ basename = "";
+ remainder = EJB_DD;
+
+ } else {
+ int endOfBaseName = descriptorName.indexOf(
+ getConfig().baseNameTerminator,
+ startOfFileName);
+ /*
+ * Check for the odd case where the terminator and/or filename
+ * extension aren't found. These will ensure "ias-" appears at the
+ * end of the name and before the '.' (if present).
+ */
+ if (endOfBaseName < 0) {
+ endOfBaseName = descriptorName.lastIndexOf('.') - 1;
+ if (endOfBaseName < 0) {
+ endOfBaseName = descriptorName.length() - 1;
+ }
+ }
+
+ basename = descriptorName.substring(startOfFileName + 1,
+ endOfBaseName + 1);
+ remainder = descriptorName.substring(endOfBaseName + 1);
+ }
+
+ iasDescriptorName = path + basename + "ias-" + remainder;
+ return iasDescriptorName;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ejb/IPlanetEjbc.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ejb/IPlanetEjbc.java
new file mode 100644
index 00000000..ed799d33
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ejb/IPlanetEjbc.java
@@ -0,0 +1,1495 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.ejb;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.StringTokenizer;
+
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+import org.xml.sax.AttributeList;
+import org.xml.sax.HandlerBase;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+/**
+ * Compiles EJB stubs and skeletons for the iPlanet Application
+ * Server (iAS). The class will read a standard EJB descriptor (as well as an
+ * EJB descriptor specific to iPlanet Application Server) to identify one or
+ * more EJBs to process. It will search for EJB "source" classes (the remote
+; * interface, home interface, and EJB implementation class) and the EJB stubs
+ * and skeletons in the specified destination directory. Only if the stubs and
+ * skeletons cannot be found or if they're out of date will the iPlanet
+ * Application Server ejbc utility be run.
+ * <p>
+ * Because this class (and it's assorted inner classes) may be bundled into the
+ * iPlanet Application Server distribution at some point (and removed from the
+ * Ant distribution), the class has been written to be independent of all
+ * Ant-specific classes. It is also for this reason (and to avoid cluttering
+ * the Apache Ant source files) that this utility has been packaged into a
+ * single source file.
+ * <p>
+ * For more information on Ant Tasks for iPlanet Application Server, see the
+ * <code>IPlanetDeploymentTool</code> and <code>IPlanetEjbcTask</code> classes.
+ *
+ * @see IPlanetDeploymentTool
+ * @see IPlanetEjbcTask
+ * @ant.task ignore="true"
+ */
+public class IPlanetEjbc {
+
+ private static final int MIN_NUM_ARGS = 2;
+ private static final int MAX_NUM_ARGS = 8;
+ private static final int NUM_CLASSES_WITH_IIOP = 15;
+ private static final int NUM_CLASSES_WITHOUT_IIOP = 9;
+
+ /* Constants used for the "beantype" attribute */
+ private static final String ENTITY_BEAN = "entity";
+ private static final String STATELESS_SESSION = "stateless";
+ private static final String STATEFUL_SESSION = "stateful";
+
+ /* Filenames of the standard EJB descriptor and the iAS-specific descriptor */
+ private File stdDescriptor;
+ private File iasDescriptor;
+
+ /*
+ * Directory where "source" EJB files are stored and where stubs and
+ * skeletons will also be written.
+ */
+ private File destDirectory;
+
+ /* Classpath used when the iAS ejbc is called */
+ private String classpath;
+ private String[] classpathElements;
+
+ /* Options passed to the iAS ejbc */
+ private boolean retainSource = false;
+ private boolean debugOutput = false;
+
+ /* iAS installation directory (used if ejbc isn't on user's PATH) */
+ private File iasHomeDir;
+
+ /* Parser and handler used to process both EJB descriptor files */
+ private SAXParser parser;
+ private EjbcHandler handler = new EjbcHandler();
+
+ /*
+ * This Hashtable maintains a list of EJB class files processed by the ejbc
+ * utility (both "source" class files as well as stubs and skeletons). The
+ * key for the Hashtable is a String representing the path to the class file
+ * (relative to the destination directory). The value for the Hashtable is
+ * a File object which reference the actual class file.
+ */
+ private Hashtable ejbFiles = new Hashtable();
+
+ /* Value of the display-name element read from the standard EJB descriptor */
+ private String displayName;
+
+ /**
+ * Constructs an instance which may be used to process EJB descriptors and
+ * generate EJB stubs and skeletons, if needed.
+ *
+ * @param stdDescriptor File referencing a standard EJB descriptor.
+ * @param iasDescriptor File referencing an iAS-specific EJB descriptor.
+ * @param destDirectory File referencing the base directory where both
+ * EJB "source" files are found and where stubs and
+ * skeletons will be written.
+ * @param classpath String representation of the classpath to be used
+ * by the iAS ejbc utility.
+ * @param parser SAXParser to be used to process both of the EJB
+ * descriptors.
+ * @todo classpathElements is not needed here, its never used
+ * (at least IDEA tells me so! :)
+ */
+ public IPlanetEjbc(File stdDescriptor,
+ File iasDescriptor,
+ File destDirectory,
+ String classpath,
+ SAXParser parser) {
+ this.stdDescriptor = stdDescriptor;
+ this.iasDescriptor = iasDescriptor;
+ this.destDirectory = destDirectory;
+ this.classpath = classpath;
+ this.parser = parser;
+
+ /*
+ * Parse the classpath into it's individual elements and store the
+ * results in the "classpathElements" instance variable.
+ */
+ List elements = new ArrayList();
+ if (classpath != null) {
+ StringTokenizer st = new StringTokenizer(classpath,
+ File.pathSeparator);
+ while (st.hasMoreTokens()) {
+ elements.add(st.nextToken());
+ }
+ classpathElements
+ = (String[]) elements.toArray(new String[elements.size()]);
+ }
+ }
+
+ /**
+ * If true, the Java source files which are generated by the
+ * ejbc process are retained.
+ *
+ * @param retainSource A boolean indicating if the Java source files for
+ * the stubs and skeletons should be retained.
+ * @todo This is not documented in the HTML. On purpose?
+ */
+ public void setRetainSource(boolean retainSource) {
+ this.retainSource = retainSource;
+ }
+
+ /**
+ * If true, enables debugging output when ejbc is executed.
+ *
+ * @param debugOutput A boolean indicating if debugging output should be
+ * generated
+ */
+ public void setDebugOutput(boolean debugOutput) {
+ this.debugOutput = debugOutput;
+ }
+
+ /**
+ * Registers the location of a local DTD file or resource. By registering
+ * a local DTD, EJB descriptors can be parsed even when the remote servers
+ * which contain the "public" DTDs cannot be accessed.
+ *
+ * @param publicID The public DTD identifier found in an XML document.
+ * @param location The file or resource name for the appropriate DTD stored
+ * on the local machine.
+ */
+ public void registerDTD(String publicID, String location) {
+ handler.registerDTD(publicID, location);
+ }
+
+ /**
+ * May be used to specify the "home" directory for this iAS installation.
+ * The directory specified should typically be
+ * <code>[install-location]/iplanet/ias6/ias</code>.
+ *
+ * @param iasHomeDir The home directory for the user's iAS installation.
+ */
+ public void setIasHomeDir(File iasHomeDir) {
+ this.iasHomeDir = iasHomeDir;
+ }
+
+ /**
+ * Returns a Hashtable which contains a list of EJB class files processed by
+ * the ejbc utility (both "source" class files as well as stubs and
+ * skeletons). The key for the Hashtable is a String representing the path
+ * to the class file (relative to the destination directory). The value for
+ * the Hashtable is a File object which reference the actual class file.
+ *
+ * @return The list of EJB files processed by the ejbc utility.
+ */
+ public Hashtable getEjbFiles() {
+ return ejbFiles;
+ }
+
+ /**
+ * Returns the display-name element read from the standard EJB descriptor.
+ *
+ * @return The EJB-JAR display name.
+ */
+ public String getDisplayName() {
+ return displayName;
+ }
+
+ /**
+ * Returns the list of CMP descriptors referenced in the EJB descriptors.
+ *
+ * @return An array of CMP descriptors.
+ */
+ public String[] getCmpDescriptors() {
+ List returnList = new ArrayList();
+
+ EjbInfo[] ejbs = handler.getEjbs();
+
+ for (int i = 0; i < ejbs.length; i++) {
+ List descriptors = (List) ejbs[i].getCmpDescriptors();
+ returnList.addAll(descriptors);
+ }
+
+ return (String[]) returnList.toArray(new String[returnList.size()]);
+ }
+
+ /**
+ * Main application method for the iPlanet Application Server ejbc utility.
+ * If the application is run with no commandline arguments, a usage
+ * statement is printed for the user.
+ *
+ * @param args The commandline arguments passed to the application.
+ */
+ public static void main(String[] args) {
+ File stdDescriptor;
+ File iasDescriptor;
+ File destDirectory = null;
+ String classpath = null;
+ SAXParser parser = null;
+ boolean debug = false;
+ boolean retainSource = false;
+ IPlanetEjbc ejbc;
+
+ if ((args.length < MIN_NUM_ARGS) || (args.length > MAX_NUM_ARGS)) {
+ usage();
+ return;
+ }
+
+ stdDescriptor = new File(args[args.length - 2]);
+ iasDescriptor = new File(args[args.length - 1]);
+
+ for (int i = 0; i < args.length - 2; i++) {
+ if (args[i].equals("-classpath")) {
+ classpath = args[++i];
+ } else if (args[i].equals("-d")) {
+ destDirectory = new File(args[++i]);
+ } else if (args[i].equals("-debug")) {
+ debug = true;
+ } else if (args[i].equals("-keepsource")) {
+ retainSource = true;
+ } else {
+ usage();
+ return;
+ }
+ }
+
+ /* If the -classpath flag isn't specified, use the system classpath */
+ if (classpath == null) {
+ Properties props = System.getProperties();
+ classpath = props.getProperty("java.class.path");
+ }
+
+ /*
+ * If the -d flag isn't specified, use the working directory as the
+ * destination directory
+ */
+ if (destDirectory == null) {
+ Properties props = System.getProperties();
+ destDirectory = new File(props.getProperty("user.dir"));
+ }
+
+ /* Construct a SAXParser used to process the descriptors */
+ SAXParserFactory parserFactory = SAXParserFactory.newInstance();
+ parserFactory.setValidating(true);
+ try {
+ parser = parserFactory.newSAXParser();
+ } catch (Exception e) {
+ // SAXException or ParserConfigurationException may be thrown
+ System.out.println("An exception was generated while trying to ");
+ System.out.println("create a new SAXParser.");
+ e.printStackTrace();
+ return;
+ }
+
+ /* Build and populate an instance of the ejbc utility */
+ ejbc = new IPlanetEjbc(stdDescriptor, iasDescriptor, destDirectory,
+ classpath, parser);
+ ejbc.setDebugOutput(debug);
+ ejbc.setRetainSource(retainSource);
+
+ /* Execute the ejbc utility -- stubs/skeletons are rebuilt, if needed */
+ try {
+ ejbc.execute();
+ } catch (IOException e) {
+ System.out.println("An IOException has occurred while reading the "
+ + "XML descriptors (" + e.getMessage() + ").");
+ return;
+ } catch (SAXException e) {
+ System.out.println("A SAXException has occurred while reading the "
+ + "XML descriptors (" + e.getMessage() + ").");
+ return;
+ } catch (IPlanetEjbc.EjbcException e) {
+ System.out.println("An error has occurred while executing the ejbc "
+ + "utility (" + e.getMessage() + ").");
+ return;
+ }
+ }
+
+ /**
+ * Print a usage statement.
+ */
+ private static void usage() {
+ System.out.println("java org.apache.tools.ant.taskdefs.optional.ejb.IPlanetEjbc \\");
+ System.out.println(" [OPTIONS] [EJB 1.1 descriptor] [iAS EJB descriptor]");
+ System.out.println("");
+ System.out.println("Where OPTIONS are:");
+ System.out.println(" -debug -- for additional debugging output");
+ System.out.println(" -keepsource -- to retain Java source files generated");
+ System.out.println(" -classpath [classpath] -- classpath used for compilation");
+ System.out.println(" -d [destination directory] -- directory for compiled classes");
+ System.out.println("");
+ System.out.println("If a classpath is not specified, the system classpath");
+ System.out.println("will be used. If a destination directory is not specified,");
+ System.out.println("the current working directory will be used (classes will");
+ System.out.println("still be placed in subfolders which correspond to their");
+ System.out.println("package name).");
+ System.out.println("");
+ System.out.println("The EJB home interface, remote interface, and implementation");
+ System.out.println("class must be found in the destination directory. In");
+ System.out.println("addition, the destination will look for the stubs and skeletons");
+ System.out.println("in the destination directory to ensure they are up to date.");
+ }
+
+ /**
+ * Compiles the stub and skeletons for the specified EJBs, if they need to
+ * be updated.
+ *
+ * @throws EjbcException If the ejbc utility cannot be correctly configured
+ * or if one or more of the EJB "source" classes
+ * cannot be found in the destination directory
+ * @throws IOException If the parser encounters a problem reading the XML
+ * file
+ * @throws SAXException If the parser encounters a problem processing the
+ * XML descriptor (it may wrap another exception)
+ */
+ public void execute() throws EjbcException, IOException, SAXException {
+
+ checkConfiguration(); // Throws EjbcException if unsuccessful
+
+ EjbInfo[] ejbs = getEjbs(); // Returns list of EJBs for processing
+
+ for (int i = 0; i < ejbs.length; i++) {
+ log("EJBInfo...");
+ log(ejbs[i].toString());
+ }
+
+ for (int i = 0; i < ejbs.length; i++) {
+ EjbInfo ejb = ejbs[i];
+
+ ejb.checkConfiguration(destDirectory); // Throws EjbcException
+
+ if (ejb.mustBeRecompiled(destDirectory)) {
+ log(ejb.getName() + " must be recompiled using ejbc.");
+
+ String[] arguments = buildArgumentList(ejb);
+ callEjbc(arguments);
+
+ } else {
+ log(ejb.getName() + " is up to date.");
+ }
+ }
+ }
+
+ /**
+ * Executes the iPlanet Application Server ejbc command-line utility.
+ *
+ * @param arguments Command line arguments to be passed to the ejbc utility.
+ */
+ private void callEjbc(String[] arguments) {
+
+ /* Concatenate all of the command line arguments into a single String */
+ StringBuffer args = new StringBuffer();
+ for (int i = 0; i < arguments.length; i++) {
+ args.append(arguments[i]).append(" ");
+ }
+
+ /* If an iAS home directory is specified, prepend it to the commmand */
+ String command;
+ if (iasHomeDir == null) {
+ command = "";
+ } else {
+ command = iasHomeDir.toString() + File.separator + "bin"
+ + File.separator;
+ }
+ command += "ejbc ";
+
+ log(command + args);
+
+ /*
+ * Use the Runtime object to execute an external command. Use the
+ * RedirectOutput inner class to direct the standard and error output
+ * from the command to the JRE's standard output
+ */
+ try {
+ Process p = Runtime.getRuntime().exec(command + args);
+ RedirectOutput output = new RedirectOutput(p.getInputStream());
+ RedirectOutput error = new RedirectOutput(p.getErrorStream());
+ output.start();
+ error.start();
+ p.waitFor();
+ p.destroy();
+ } catch (IOException e) {
+ log("An IOException has occurred while trying to execute ejbc.");
+ e.printStackTrace();
+ } catch (InterruptedException e) {
+ // Do nothing
+ }
+ }
+
+ /**
+ * Verifies that the user selections are valid.
+ *
+ * @throws EjbcException If the user selections are invalid.
+ */
+ protected void checkConfiguration() throws EjbcException {
+
+ String msg = "";
+
+ if (stdDescriptor == null) {
+ msg += "A standard XML descriptor file must be specified. ";
+ }
+ if (iasDescriptor == null) {
+ msg += "An iAS-specific XML descriptor file must be specified. ";
+ }
+ if (classpath == null) {
+ msg += "A classpath must be specified. ";
+ }
+ if (parser == null) {
+ msg += "An XML parser must be specified. ";
+ }
+
+ if (destDirectory == null) {
+ msg += "A destination directory must be specified. ";
+ } else if (!destDirectory.exists()) {
+ msg += "The destination directory specified does not exist. ";
+ } else if (!destDirectory.isDirectory()) {
+ msg += "The destination specified is not a directory. ";
+ }
+
+ if (msg.length() > 0) {
+ throw new EjbcException(msg);
+ }
+ }
+
+ /**
+ * Parses the EJB descriptors and returns a list of EJBs which may need to
+ * be compiled.
+ *
+ * @return An array of objects which describe the EJBs to be
+ * processed.
+ * @throws IOException If the parser encounters a problem reading the XML
+ * files
+ * @throws SAXException If the parser encounters a problem processing the
+ * XML descriptor (it may wrap another exception)
+ */
+ private EjbInfo[] getEjbs() throws IOException, SAXException {
+ EjbInfo[] ejbs = null;
+
+ /*
+ * The EJB information is gathered from the standard XML EJB descriptor
+ * and the iAS-specific XML EJB descriptor using a SAX parser.
+ */
+
+ parser.parse(stdDescriptor, handler);
+ parser.parse(iasDescriptor, handler);
+ ejbs = handler.getEjbs();
+
+ return ejbs;
+ }
+
+ /**
+ * Based on this object's instance variables as well as the EJB to be
+ * processed, the correct flags and parameters are set for the ejbc
+ * command-line utility.
+ * @param ejb The EJB for which stubs and skeletons will be compiled.
+ * @return An array of Strings which are the command-line parameters for
+ * for the ejbc utility.
+ */
+ private String[] buildArgumentList(EjbInfo ejb) {
+
+ List arguments = new ArrayList();
+
+ /* OPTIONAL COMMAND LINE PARAMETERS */
+
+ if (debugOutput) {
+ arguments.add("-debug");
+ }
+
+ /* No beantype flag is needed for an entity bean */
+ if (ejb.getBeantype().equals(STATELESS_SESSION)) {
+ arguments.add("-sl");
+ } else if (ejb.getBeantype().equals(STATEFUL_SESSION)) {
+ arguments.add("-sf");
+ }
+
+ if (ejb.getIiop()) {
+ arguments.add("-iiop");
+ }
+
+ if (ejb.getCmp()) {
+ arguments.add("-cmp");
+ }
+
+ if (retainSource) {
+ arguments.add("-gs");
+ }
+
+ if (ejb.getHasession()) {
+ arguments.add("-fo");
+ }
+
+ /* REQUIRED COMMAND LINE PARAMETERS */
+
+ arguments.add("-classpath");
+ arguments.add(classpath);
+
+ arguments.add("-d");
+ arguments.add(destDirectory.toString());
+
+ arguments.add(ejb.getHome().getQualifiedClassName());
+ arguments.add(ejb.getRemote().getQualifiedClassName());
+ arguments.add(ejb.getImplementation().getQualifiedClassName());
+
+ /* Convert the List into an Array and return it */
+ return (String[]) arguments.toArray(new String[arguments.size()]);
+ }
+
+ /**
+ * Convenience method used to print messages to the user if debugging
+ * messages are enabled.
+ *
+ * @param msg The String to print to standard output.
+ */
+ private void log(String msg) {
+ if (debugOutput) {
+ System.out.println(msg);
+ }
+ }
+
+
+ /* Inner classes follow */
+
+
+ /**
+ * This inner class is used to signal any problems during the execution of
+ * the ejbc compiler.
+ *
+ */
+ public class EjbcException extends Exception {
+
+ /**
+ * Constructs an exception with the given descriptive message.
+ *
+ * @param msg Description of the exception which has occurred.
+ */
+ public EjbcException(String msg) {
+ super(msg);
+ }
+ } // End of EjbcException inner class
+
+
+ /**
+ * This inner class is an XML document handler that can be used to parse EJB
+ * descriptors (both the standard EJB descriptor as well as the iAS-specific
+ * descriptor that stores additional values for iAS). Once the descriptors
+ * have been processed, the list of EJBs found can be obtained by calling
+ * the <code>getEjbs()</code> method.
+ *
+ * @see IPlanetEjbc.EjbInfo
+ */
+ private class EjbcHandler extends HandlerBase {
+ /** EJB 1.1 ID */
+ private static final String PUBLICID_EJB11 =
+ "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 1.1//EN";
+ /** IPlanet ID */
+ private static final String PUBLICID_IPLANET_EJB_60 =
+ "-//Sun Microsystems, Inc.//DTD iAS Enterprise JavaBeans 1.0//EN";
+ /** EJB 1.1 location */
+ private static final String DEFAULT_IAS60_EJB11_DTD_LOCATION =
+ "ejb-jar_1_1.dtd";
+ /** IAS60 location */
+ private static final String DEFAULT_IAS60_DTD_LOCATION =
+ "IASEjb_jar_1_0.dtd";
+
+ /*
+ * Two Maps are used to track local DTDs that will be used in case the
+ * remote copies of these DTDs cannot be accessed. The key for the Map
+ * is the DTDs public ID and the value is the local location for the DTD
+ */
+ private Map resourceDtds = new HashMap();
+ private Map fileDtds = new HashMap();
+
+ private Map ejbs = new HashMap(); // List of EJBs found in XML
+ private EjbInfo currentEjb; // One item within the Map
+ private boolean iasDescriptor = false; // Is doc iAS or EJB descriptor
+
+ private String currentLoc = ""; // Tracks current element
+ private String currentText; // Tracks current text data
+ private String ejbType; // "session" or "entity"
+
+ /**
+ * Constructs a new instance of the handler and registers local copies
+ * of the standard EJB 1.1 descriptor DTD as well as iAS's EJB
+ * descriptor DTD.
+ */
+ public EjbcHandler() {
+ registerDTD(PUBLICID_EJB11, DEFAULT_IAS60_EJB11_DTD_LOCATION);
+ registerDTD(PUBLICID_IPLANET_EJB_60, DEFAULT_IAS60_DTD_LOCATION);
+ }
+
+ /**
+ * Returns the list of EJB objects found during the processing of the
+ * standard EJB 1.1 descriptor and iAS-specific EJB descriptor.
+ *
+ * @return An array of EJBs which were found during the descriptor
+ * parsing.
+ */
+ public EjbInfo[] getEjbs() {
+ return (EjbInfo[]) ejbs.values().toArray(new EjbInfo[ejbs.size()]);
+ }
+
+ /**
+ * Returns the value of the display-name element found in the standard
+ * EJB 1.1 descriptor.
+ *
+ * @return String display-name value.
+ */
+ public String getDisplayName() {
+ return displayName;
+ }
+
+ /**
+ * Registers a local DTD that will be used when parsing an EJB
+ * descriptor. When the DTD's public identifier is found in an XML
+ * document, the parser will reference the local DTD rather than the
+ * remote DTD. This enables XML documents to be processed even when the
+ * public DTD isn't available.
+ *
+ * @param publicID The DTD's public identifier.
+ * @param location The location of the local DTD copy -- the location
+ * may either be a resource found on the classpath or a
+ * local file.
+ */
+ public void registerDTD(String publicID, String location) {
+ log("Registering: " + location);
+ if ((publicID == null) || (location == null)) {
+ return;
+ }
+
+ if (ClassLoader.getSystemResource(location) != null) {
+ log("Found resource: " + location);
+ resourceDtds.put(publicID, location);
+ } else {
+ File dtdFile = new File(location);
+ if (dtdFile.exists() && dtdFile.isFile()) {
+ log("Found file: " + location);
+ fileDtds.put(publicID, location);
+ }
+ }
+ }
+
+ /**
+ * Resolves an external entity found during XML processing. If a public
+ * ID is found that has been registered with the handler, an <code>
+ * InputSource</code> will be returned which refers to the local copy.
+ * If the public ID hasn't been registered or if an error occurs, the
+ * superclass implementation is used.
+ *
+ * @param publicId The DTD's public identifier.
+ * @param systemId The location of the DTD, as found in the XML document.
+ */
+ public InputSource resolveEntity(String publicId, String systemId)
+ throws SAXException {
+ InputStream inputStream = null;
+
+
+ try {
+
+ /* Search the resource Map and (if not found) file Map */
+
+ String location = (String) resourceDtds.get(publicId);
+ if (location != null) {
+ inputStream
+ = ClassLoader.getSystemResource(location).openStream();
+ } else {
+ location = (String) fileDtds.get(publicId);
+ if (location != null) {
+ inputStream = new FileInputStream(location);
+ }
+ }
+ } catch (IOException e) {
+ return super.resolveEntity(publicId, systemId);
+ }
+
+ if (inputStream == null) {
+ return super.resolveEntity(publicId, systemId);
+ } else {
+ return new InputSource(inputStream);
+ }
+ }
+
+ /**
+ * Receive notification that the start of an XML element has been found.
+ *
+ * @param name String name of the element found.
+ * @param atts AttributeList of the attributes included with the element
+ * (if any).
+ * @throws SAXException If the parser cannot process the document.
+ */
+ public void startElement(String name, AttributeList atts)
+ throws SAXException {
+
+ /*
+ * I need to "push" the element onto the String (currentLoc) which
+ * always represents the current location in the XML document.
+ */
+ currentLoc += "\\" + name;
+
+ /* A new element has started, so reset the text being captured */
+ currentText = "";
+
+ if (currentLoc.equals("\\ejb-jar")) {
+ iasDescriptor = false;
+ } else if (currentLoc.equals("\\ias-ejb-jar")) {
+ iasDescriptor = true;
+ }
+
+ if ((name.equals("session")) || (name.equals("entity"))) {
+ ejbType = name;
+ }
+ }
+
+ /**
+ * Receive notification that character data has been found in the XML
+ * document
+ *
+ * @param ch Array of characters which have been found in the document.
+ * @param start Starting index of the data found in the document.
+ * @param len The number of characters found in the document.
+ * @throws SAXException If the parser cannot process the document.
+ */
+ public void characters(char[] ch, int start, int len)
+ throws SAXException {
+
+ currentText += new String(ch).substring(start, start + len);
+ }
+
+ /**
+ * Receive notification that the end of an XML element has been found.
+ *
+ * @param name String name of the element.
+ * @throws SAXException If the parser cannot process the document.
+ */
+ public void endElement(String name) throws SAXException {
+
+ /*
+ * If this is a standard EJB 1.1 descriptor, we are looking for one
+ * set of data, while if this is an iAS-specific descriptor, we're
+ * looking for different set of data. Hand the processing off to
+ * the appropriate method.
+ */
+ if (iasDescriptor) {
+ iasCharacters(currentText);
+ } else {
+ stdCharacters(currentText);
+ }
+
+ /*
+ * I need to "pop" the element off the String (currentLoc) which
+ * always represents my current location in the XML document.
+ */
+
+ int nameLength = name.length() + 1; // Add one for the "\"
+ int locLength = currentLoc.length();
+
+ currentLoc = currentLoc.substring(0, locLength - nameLength);
+ }
+
+ /**
+ * Receive notification that character data has been found in a standard
+ * EJB 1.1 descriptor. We're interested in retrieving the home
+ * interface, remote interface, implementation class, the type of bean,
+ * and if the bean uses CMP.
+ *
+ * @param value String data found in the XML document.
+ */
+ private void stdCharacters(String value) {
+
+ if (currentLoc.equals("\\ejb-jar\\display-name")) {
+ displayName = value;
+ return;
+ }
+
+ String base = "\\ejb-jar\\enterprise-beans\\" + ejbType;
+
+ if (currentLoc.equals(base + "\\ejb-name")) {
+ currentEjb = (EjbInfo) ejbs.get(value);
+ if (currentEjb == null) {
+ currentEjb = new EjbInfo(value);
+ ejbs.put(value, currentEjb);
+ }
+ } else if (currentLoc.equals(base + "\\home")) {
+ currentEjb.setHome(value);
+ } else if (currentLoc.equals(base + "\\remote")) {
+ currentEjb.setRemote(value);
+ } else if (currentLoc.equals(base + "\\ejb-class")) {
+ currentEjb.setImplementation(value);
+ } else if (currentLoc.equals(base + "\\prim-key-class")) {
+ currentEjb.setPrimaryKey(value);
+ } else if (currentLoc.equals(base + "\\session-type")) {
+ currentEjb.setBeantype(value);
+ } else if (currentLoc.equals(base + "\\persistence-type")) {
+ currentEjb.setCmp(value);
+ }
+ }
+
+ /**
+ * Receive notification that character data has been found in an
+ * iAS-specific descriptor. We're interested in retrieving data
+ * indicating whether the bean must support RMI/IIOP access, whether
+ * the bean must provide highly available stubs and skeletons (in the
+ * case of stateful session beans), and if this bean uses additional
+ * CMP XML descriptors (in the case of entity beans with CMP).
+ *
+ * @param value String data found in the XML document.
+ */
+ private void iasCharacters(String value) {
+ String base = "\\ias-ejb-jar\\enterprise-beans\\" + ejbType;
+
+ if (currentLoc.equals(base + "\\ejb-name")) {
+ currentEjb = (EjbInfo) ejbs.get(value);
+ if (currentEjb == null) {
+ currentEjb = new EjbInfo(value);
+ ejbs.put(value, currentEjb);
+ }
+ } else if (currentLoc.equals(base + "\\iiop")) {
+ currentEjb.setIiop(value);
+ } else if (currentLoc.equals(base + "\\failover-required")) {
+ currentEjb.setHasession(value);
+ } else if (currentLoc.equals(base + "\\persistence-manager"
+ + "\\properties-file-location")) {
+ currentEjb.addCmpDescriptor(value);
+ }
+ }
+ } // End of EjbcHandler inner class
+
+
+ /**
+ * This inner class represents an EJB that will be compiled using ejbc.
+ *
+ */
+ private class EjbInfo {
+ private String name; // EJB's display name
+ private Classname home; // EJB's home interface name
+ private Classname remote; // EJB's remote interface name
+ private Classname implementation; // EJB's implementation class
+ private Classname primaryKey; // EJB's primary key class
+ private String beantype = "entity"; // or "stateful" or "stateless"
+ private boolean cmp = false; // Does this EJB support CMP?
+ private boolean iiop = false; // Does this EJB support IIOP?
+ private boolean hasession = false; // Does this EJB require failover?
+ private List cmpDescriptors = new ArrayList(); // CMP descriptor list
+
+ /**
+ * Construct a new EJBInfo object with the given name.
+ *
+ * @param name The display name for the EJB.
+ */
+ public EjbInfo(String name) {
+ this.name = name;
+ }
+
+ /**
+ * Returns the display name of the EJB. If a display name has not been
+ * set, it returns the EJB implementation classname (if the
+ * implementation class is not set, it returns "[unnamed]").
+ *
+ * @return The display name for the EJB.
+ */
+ public String getName() {
+ if (name == null) {
+ if (implementation == null) {
+ return "[unnamed]";
+ } else {
+ return implementation.getClassName();
+ }
+ }
+ return name;
+ }
+
+ /*
+ * Below are getter's and setter's for each of the instance variables.
+ * Note that (in addition to supporting setters with the same type as
+ * the instance variable) a setter is provided with takes a String
+ * argument -- this are provided so the XML document handler can set
+ * the EJB values using the Strings it parses.
+ */
+
+ public void setHome(String home) {
+ setHome(new Classname(home));
+ }
+
+ public void setHome(Classname home) {
+ this.home = home;
+ }
+
+ public Classname getHome() {
+ return home;
+ }
+
+ public void setRemote(String remote) {
+ setRemote(new Classname(remote));
+ }
+
+ public void setRemote(Classname remote) {
+ this.remote = remote;
+ }
+
+ public Classname getRemote() {
+ return remote;
+ }
+
+ public void setImplementation(String implementation) {
+ setImplementation(new Classname(implementation));
+ }
+
+ public void setImplementation(Classname implementation) {
+ this.implementation = implementation;
+ }
+
+ public Classname getImplementation() {
+ return implementation;
+ }
+
+ public void setPrimaryKey(String primaryKey) {
+ setPrimaryKey(new Classname(primaryKey));
+ }
+
+ public void setPrimaryKey(Classname primaryKey) {
+ this.primaryKey = primaryKey;
+ }
+
+ public Classname getPrimaryKey() {
+ return primaryKey;
+ }
+
+ public void setBeantype(String beantype) {
+ this.beantype = beantype.toLowerCase();
+ }
+
+ public String getBeantype() {
+ return beantype;
+ }
+
+ public void setCmp(boolean cmp) {
+ this.cmp = cmp;
+ }
+
+ public void setCmp(String cmp) {
+ setCmp(cmp.equals("Container"));
+ }
+
+ public boolean getCmp() {
+ return cmp;
+ }
+
+ public void setIiop(boolean iiop) {
+ this.iiop = iiop;
+ }
+
+ public void setIiop(String iiop) {
+ setIiop(iiop.equals("true"));
+ }
+
+ public boolean getIiop() {
+ return iiop;
+ }
+
+ public void setHasession(boolean hasession) {
+ this.hasession = hasession;
+ }
+
+ public void setHasession(String hasession) {
+ setHasession(hasession.equals("true"));
+ }
+
+ public boolean getHasession() {
+ return hasession;
+ }
+
+ public void addCmpDescriptor(String descriptor) {
+ cmpDescriptors.add(descriptor);
+ }
+
+ public List getCmpDescriptors() {
+ return cmpDescriptors;
+ }
+
+ /**
+ * Verifies that the EJB is valid--if it is invalid, an exception is
+ * thrown
+ *
+ *
+ * @param buildDir The directory where the EJB remote interface, home
+ * interface, and implementation class must be found.
+ * @throws EjbcException If the EJB is invalid.
+ */
+ private void checkConfiguration(File buildDir) throws EjbcException {
+
+ /* Check that the specified instance variables are valid */
+ if (home == null) {
+ throw new EjbcException("A home interface was not found "
+ + "for the " + name + " EJB.");
+ }
+ if (remote == null) {
+ throw new EjbcException("A remote interface was not found "
+ + "for the " + name + " EJB.");
+ }
+ if (implementation == null) {
+ throw new EjbcException("An EJB implementation class was not "
+ + "found for the " + name + " EJB.");
+ }
+
+ if ((!beantype.equals(ENTITY_BEAN))
+ && (!beantype.equals(STATELESS_SESSION))
+ && (!beantype.equals(STATEFUL_SESSION))) {
+ throw new EjbcException("The beantype found (" + beantype + ") "
+ + "isn't valid in the " + name + " EJB.");
+ }
+
+ if (cmp && (!beantype.equals(ENTITY_BEAN))) {
+ System.out.println("CMP stubs and skeletons may not be generated"
+ + " for a Session Bean -- the \"cmp\" attribute will be"
+ + " ignoredfor the " + name + " EJB.");
+ }
+
+ if (hasession && (!beantype.equals(STATEFUL_SESSION))) {
+ System.out.println("Highly available stubs and skeletons may "
+ + "only be generated for a Stateful Session Bean -- the "
+ + "\"hasession\" attribute will be ignored for the "
+ + name + " EJB.");
+ }
+
+ /* Check that the EJB "source" classes all exist */
+ if (!remote.getClassFile(buildDir).exists()) {
+ throw new EjbcException("The remote interface "
+ + remote.getQualifiedClassName() + " could not be "
+ + "found.");
+ }
+ if (!home.getClassFile(buildDir).exists()) {
+ throw new EjbcException("The home interface "
+ + home.getQualifiedClassName() + " could not be "
+ + "found.");
+ }
+ if (!implementation.getClassFile(buildDir).exists()) {
+ throw new EjbcException("The EJB implementation class "
+ + implementation.getQualifiedClassName() + " could "
+ + "not be found.");
+ }
+ }
+
+ /**
+ * Determines if the ejbc utility needs to be run or not. If the stubs
+ * and skeletons can all be found in the destination directory AND all
+ * of their timestamps are more recent than the EJB source classes
+ * (home, remote, and implementation classes), the method returns
+ * <code>false</code>. Otherwise, the method returns <code>true</code>.
+ *
+ * @param destDir The directory where the EJB source classes, stubs and
+ * skeletons are located.
+ * @return A boolean indicating whether or not the ejbc utility needs to
+ * be run to bring the stubs and skeletons up to date.
+ */
+ public boolean mustBeRecompiled(File destDir) {
+
+ long sourceModified = sourceClassesModified(destDir);
+
+ long destModified = destClassesModified(destDir);
+
+ return (destModified < sourceModified);
+ }
+
+ /**
+ * Examines each of the EJB source classes (home, remote, and
+ * implementation) and returns the modification timestamp for the
+ * "oldest" class.
+ *
+ * @param classpath The classpath to be used to find the source EJB
+ * classes. If <code>null</code>, the system classpath
+ * is used.
+ * @return The modification timestamp for the "oldest" EJB source class.
+ * @throws BuildException If one of the EJB source classes cannot be
+ * found on the classpath.
+ */
+ private long sourceClassesModified(File buildDir) {
+ long latestModified; // The timestamp of the "newest" class
+ long modified; // Timestamp for a given class
+ File remoteFile; // File for the remote interface class
+ File homeFile; // File for the home interface class
+ File implFile; // File for the EJB implementation class
+ File pkFile; // File for the EJB primary key class
+
+ /* Check the timestamp on the remote interface */
+ remoteFile = remote.getClassFile(buildDir);
+ modified = remoteFile.lastModified();
+ if (modified == -1) {
+ System.out.println("The class "
+ + remote.getQualifiedClassName() + " couldn't "
+ + "be found on the classpath");
+ return -1;
+ }
+ latestModified = modified;
+
+ /* Check the timestamp on the home interface */
+ homeFile = home.getClassFile(buildDir);
+ modified = homeFile.lastModified();
+ if (modified == -1) {
+ System.out.println("The class "
+ + home.getQualifiedClassName() + " couldn't be "
+ + "found on the classpath");
+ return -1;
+ }
+ latestModified = Math.max(latestModified, modified);
+
+ /* Check the timestamp of the primary key class */
+ if (primaryKey != null) {
+ pkFile = primaryKey.getClassFile(buildDir);
+ modified = pkFile.lastModified();
+ if (modified == -1) {
+ System.out.println("The class "
+ + primaryKey.getQualifiedClassName() + "couldn't be "
+ + "found on the classpath");
+ return -1;
+ }
+ latestModified = Math.max(latestModified, modified);
+ } else {
+ pkFile = null;
+ }
+
+ /* Check the timestamp on the EJB implementation class.
+ *
+ * Note that if ONLY the implementation class has changed, it's not
+ * necessary to rebuild the EJB stubs and skeletons. For this
+ * reason, we ensure the file exists (using lastModified above), but
+ * we DON'T compare it's timestamp with the timestamps of the home
+ * and remote interfaces (because it's irrelevant in determining if
+ * ejbc must be run)
+ */
+ implFile = implementation.getClassFile(buildDir);
+ modified = implFile.lastModified();
+ if (modified == -1) {
+ System.out.println("The class "
+ + implementation.getQualifiedClassName()
+ + " couldn't be found on the classpath");
+ return -1;
+ }
+
+ String pathToFile = remote.getQualifiedClassName();
+ pathToFile = pathToFile.replace('.', File.separatorChar) + ".class";
+ ejbFiles.put(pathToFile, remoteFile);
+
+ pathToFile = home.getQualifiedClassName();
+ pathToFile = pathToFile.replace('.', File.separatorChar) + ".class";
+ ejbFiles.put(pathToFile, homeFile);
+
+ pathToFile = implementation.getQualifiedClassName();
+ pathToFile = pathToFile.replace('.', File.separatorChar) + ".class";
+ ejbFiles.put(pathToFile, implFile);
+
+ if (pkFile != null) {
+ pathToFile = primaryKey.getQualifiedClassName();
+ pathToFile = pathToFile.replace('.', File.separatorChar) + ".class";
+ ejbFiles.put(pathToFile, pkFile);
+ }
+
+ return latestModified;
+ }
+
+ /**
+ * Examines each of the EJB stubs and skeletons in the destination
+ * directory and returns the modification timestamp for the "oldest"
+ * class. If one of the stubs or skeletons cannot be found, <code>-1
+ * </code> is returned.
+ *
+ * @param dest The directory in which the EJB stubs and skeletons are
+ * stored.
+ * @return The modification timestamp for the "oldest" EJB stub or
+ * skeleton. If one of the classes cannot be found, <code>-1
+ * </code> is returned.
+ * @throws BuildException If the canonical path of the destination
+ * directory cannot be found.
+ */
+ private long destClassesModified(File destDir) {
+ String[] classnames = classesToGenerate(); // List of all stubs & skels
+ long destClassesModified = new Date().getTime(); // Earliest mod time
+ boolean allClassesFound = true; // Has each been found?
+
+ /*
+ * Loop through each stub/skeleton class that must be generated, and
+ * determine (if all exist) which file has the most recent timestamp
+ */
+ for (int i = 0; i < classnames.length; i++) {
+
+ String pathToClass =
+ classnames[i].replace('.', File.separatorChar) + ".class";
+ File classFile = new File(destDir, pathToClass);
+
+ /*
+ * Add each stub/skeleton class to the list of EJB files. Note
+ * that each class is added even if it doesn't exist now.
+ */
+ ejbFiles.put(pathToClass, classFile);
+
+ allClassesFound = allClassesFound && classFile.exists();
+
+ if (allClassesFound) {
+ long fileMod = classFile.lastModified();
+
+ /* Keep track of the oldest modification timestamp */
+ destClassesModified = Math.min(destClassesModified, fileMod);
+ }
+ }
+
+ return (allClassesFound) ? destClassesModified : -1;
+ }
+
+ /**
+ * Builds an array of class names which represent the stubs and
+ * skeletons which need to be generated for a given EJB. The class
+ * names are fully qualified. Nine classes are generated for all EJBs
+ * while an additional six classes are generated for beans requiring
+ * RMI/IIOP access.
+ *
+ * @return An array of Strings representing the fully-qualified class
+ * names for the stubs and skeletons to be generated.
+ */
+ private String[] classesToGenerate() {
+ String[] classnames = (iiop)
+ ? new String[NUM_CLASSES_WITH_IIOP]
+ : new String[NUM_CLASSES_WITHOUT_IIOP];
+
+ final String remotePkg = remote.getPackageName() + ".";
+ final String remoteClass = remote.getClassName();
+ final String homePkg = home.getPackageName() + ".";
+ final String homeClass = home.getClassName();
+ final String implPkg = implementation.getPackageName() + ".";
+ final String implFullClass = implementation.getQualifiedWithUnderscores();
+ int index = 0;
+
+ classnames[index++] = implPkg + "ejb_fac_" + implFullClass;
+ classnames[index++] = implPkg + "ejb_home_" + implFullClass;
+ classnames[index++] = implPkg + "ejb_skel_" + implFullClass;
+ classnames[index++] = remotePkg + "ejb_kcp_skel_" + remoteClass;
+ classnames[index++] = homePkg + "ejb_kcp_skel_" + homeClass;
+ classnames[index++] = remotePkg + "ejb_kcp_stub_" + remoteClass;
+ classnames[index++] = homePkg + "ejb_kcp_stub_" + homeClass;
+ classnames[index++] = remotePkg + "ejb_stub_" + remoteClass;
+ classnames[index++] = homePkg + "ejb_stub_" + homeClass;
+
+ if (!iiop) {
+ return classnames;
+ }
+
+ classnames[index++] = "org.omg.stub." + remotePkg + "_"
+ + remoteClass + "_Stub";
+ classnames[index++] = "org.omg.stub." + homePkg + "_"
+ + homeClass + "_Stub";
+ classnames[index++] = "org.omg.stub." + remotePkg
+ + "_ejb_RmiCorbaBridge_"
+ + remoteClass + "_Tie";
+ classnames[index++] = "org.omg.stub." + homePkg
+ + "_ejb_RmiCorbaBridge_"
+ + homeClass + "_Tie";
+
+ classnames[index++] = remotePkg + "ejb_RmiCorbaBridge_"
+ + remoteClass;
+ classnames[index++] = homePkg + "ejb_RmiCorbaBridge_" + homeClass;
+
+ return classnames;
+ }
+
+ /**
+ * Convenience method which creates a String representation of all the
+ * instance variables of an EjbInfo object.
+ *
+ * @return A String representing the EjbInfo instance.
+ */
+ public String toString() {
+ String s = "EJB name: " + name
+ + "\n\r home: " + home
+ + "\n\r remote: " + remote
+ + "\n\r impl: " + implementation
+ + "\n\r primaryKey: " + primaryKey
+ + "\n\r beantype: " + beantype
+ + "\n\r cmp: " + cmp
+ + "\n\r iiop: " + iiop
+ + "\n\r hasession: " + hasession;
+
+ Iterator i = cmpDescriptors.iterator();
+ while (i.hasNext()) {
+ s += "\n\r CMP Descriptor: " + i.next();
+ }
+
+ return s;
+ }
+
+ } // End of EjbInfo inner class
+
+ /**
+ * Convenience class used to represent the fully qualified name of a Java
+ * class. It provides an easy way to retrieve components of the class name
+ * in a format that is convenient for building iAS stubs and skeletons.
+ *
+ */
+ private static class Classname {
+ private String qualifiedName; // Fully qualified name of the Java class
+ private String packageName; // Name of the package for this class
+ private String className; // Name of the class without the package
+
+ /**
+ * This constructor builds an object which represents the name of a Java
+ * class.
+ *
+ * @param qualifiedName String representing the fully qualified class
+ * name of the Java class.
+ */
+ public Classname(String qualifiedName) {
+ if (qualifiedName == null) {
+ return;
+ }
+
+ this.qualifiedName = qualifiedName;
+
+ int index = qualifiedName.lastIndexOf('.');
+ if (index == -1) {
+ className = qualifiedName;
+ packageName = "";
+ } else {
+ packageName = qualifiedName.substring(0, index);
+ className = qualifiedName.substring(index + 1);
+ }
+ }
+
+ /**
+ * Gets the fully qualified name of the Java class.
+ *
+ * @return String representing the fully qualified class name.
+ */
+ public String getQualifiedClassName() {
+ return qualifiedName;
+ }
+
+ /**
+ * Gets the package name for the Java class.
+ *
+ * @return String representing the package name for the class.
+ */
+ public String getPackageName() {
+ return packageName;
+ }
+
+ /**
+ * Gets the Java class name without the package structure.
+ *
+ * @return String representing the name for the class.
+ */
+ public String getClassName() {
+ return className;
+ }
+
+ /**
+ * Gets the fully qualified name of the Java class with underscores
+ * separating the components of the class name rather than periods.
+ * This format is used in naming some of the stub and skeleton classes
+ * for the iPlanet Application Server.
+ *
+ * @return String representing the fully qualified class name using
+ * underscores instead of periods.
+ */
+ public String getQualifiedWithUnderscores() {
+ return qualifiedName.replace('.', '_');
+ }
+
+ /**
+ * Returns a File which references the class relative to the specified
+ * directory. Note that the class file may or may not exist.
+ *
+ * @param directory A File referencing the base directory containing
+ * class files.
+ * @return File referencing this class.
+ */
+ public File getClassFile(File directory) {
+ String pathToFile = qualifiedName.replace('.', File.separatorChar)
+ + ".class";
+ return new File(directory, pathToFile);
+ }
+
+ /**
+ * String representation of this class name. It returns the fully
+ * qualified class name.
+ *
+ * @return String representing the fully qualified class name.
+ */
+ public String toString() {
+ return getQualifiedClassName();
+ }
+ } // End of Classname inner class
+
+
+ /**
+ * Thread class used to redirect output from an <code>InputStream</code> to
+ * the JRE standard output. This class may be used to redirect output from
+ * an external process to the standard output.
+ *
+ */
+ private static class RedirectOutput extends Thread {
+
+ private InputStream stream; // Stream to read and redirect to standard output
+
+ /**
+ * Constructs a new instance that will redirect output from the
+ * specified stream to the standard output.
+ *
+ * @param stream InputStream which will be read and redirected to the
+ * standard output.
+ */
+ public RedirectOutput(InputStream stream) {
+ this.stream = stream;
+ }
+
+ /**
+ * Reads text from the input stream and redirects it to standard output
+ * using a separate thread.
+ */
+ public void run() {
+ BufferedReader reader = new BufferedReader(
+ new InputStreamReader(stream));
+ String text;
+ try {
+ while ((text = reader.readLine()) != null) {
+ System.out.println(text);
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ } finally {
+ try {
+ reader.close();
+ } catch (IOException e) {
+ // Do nothing
+ }
+ }
+ }
+ } // End of RedirectOutput inner class
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ejb/IPlanetEjbcTask.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ejb/IPlanetEjbcTask.java
new file mode 100644
index 00000000..ee5dc854
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ejb/IPlanetEjbcTask.java
@@ -0,0 +1,321 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.ejb;
+
+import java.io.File;
+import java.io.IOException;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.types.Path;
+import org.xml.sax.SAXException;
+
+/**
+ * Compiles EJB stubs and skeletons for the iPlanet Application Server.
+ * The EJBs to be processed are specified by the EJB 1.1 standard XML
+ * descriptor, and additional attributes are obtained from the iPlanet Application
+ * Server-specific XML descriptor. Since the XML descriptors can include
+ * multiple EJBs, this is a convenient way of specifying many EJBs in a single
+ * Ant task. The following attributes are allowed:
+ * <ul>
+ * <li><i>ejbdescriptor</i> -- Standard EJB 1.1 XML descriptor (typically
+ * titled "ejb-jar.xml"). This attribute is
+ * required.
+ * <li><i>iasdescriptor</i> -- EJB XML descriptor for iPlanet Application
+ * Server (typically titled "ias-ejb-jar.xml).
+ * This attribute is required.
+ * <li><i>dest</i> -- The is the base directory where the RMI stubs and
+ * skeletons are written. In addition, the class files
+ * for each bean (home interface, remote interface, and
+ * EJB implementation) must be found in this directory.
+ * This attribute is required.
+ * <li><i>classpath</i> -- The classpath used when generating EJB stubs and
+ * skeletons. This is an optional attribute (if
+ * omitted, the classpath specified when Ant was
+ * started will be used). Nested "classpath"
+ * elements may also be used.
+ * <li><i>keepgenerated</i> -- Indicates whether or not the Java source
+ * files which are generated by ejbc will be
+ * saved or automatically deleted. If "yes",
+ * the source files will be retained. This is
+ * an optional attribute (if omitted, it
+ * defaults to "no").
+ * <li><i>debug</i> -- Indicates whether or not the ejbc utility should
+ * log additional debugging statements to the standard
+ * output. If "yes", the additional debugging statements
+ * will be generated (if omitted, it defaults to "no").
+ * <li><i>iashome</i> -- May be used to specify the "home" directory for
+ * this iPlanet Application Server installation. This
+ * is used to find the ejbc utility if it isn't
+ * included in the user's system path. This is an
+ * optional attribute (if specified, it should refer
+ * to the <code>[install-location]/iplanet/ias6/ias
+ * </code> directory). If omitted, the ejbc utility
+ * must be on the user's system path.
+ * </ul>
+ * <p>
+ * For each EJB specified, this task will locate the three classes that comprise
+ * the EJB. If these class files cannot be located in the <code>dest</code>
+ * directory, the task will fail. The task will also attempt to locate the EJB
+ * stubs and skeletons in this directory. If found, the timestamps on the
+ * stubs and skeletons will be checked to ensure they are up to date. Only if
+ * these files cannot be found or if they are out of date will ejbc be called
+ * to generate new stubs and skeletons.
+ *
+ * @see IPlanetEjbc
+ *
+ * @ant.task name="iplanet-ejbc" category="ejb"
+ */
+public class IPlanetEjbcTask extends Task {
+
+ /* Attributes set by the Ant build file */
+ private File ejbdescriptor;
+ private File iasdescriptor;
+ private File dest;
+ private Path classpath;
+ private boolean keepgenerated = false;
+ private boolean debug = false;
+ private File iashome;
+
+ /**
+ * Sets the location of the standard XML EJB descriptor. Typically, this
+ * file is named "ejb-jar.xml".
+ *
+ * @param ejbdescriptor The name and location of the EJB descriptor.
+ */
+ public void setEjbdescriptor(File ejbdescriptor) {
+ this.ejbdescriptor = ejbdescriptor;
+ }
+
+ /**
+ * Sets the location of the iAS-specific XML EJB descriptor. Typically,
+ * this file is named "ias-ejb-jar.xml".
+ *
+ * @param iasdescriptor The name and location of the iAS-specific EJB
+ * descriptor.
+ */
+ public void setIasdescriptor (File iasdescriptor) {
+ this.iasdescriptor = iasdescriptor;
+ }
+
+ /**
+ * Sets the destination directory where the EJB source classes must exist
+ * and where the stubs and skeletons will be written. The destination
+ * directory must exist before this task is executed.
+ *
+ * @param dest The directory where the compiled classes will be written.
+ */
+ public void setDest(File dest) {
+ this.dest = dest;
+ }
+
+ /**
+ * Sets the classpath to be used when compiling the EJB stubs and skeletons.
+ *
+ * @param classpath The classpath to be used.
+ */
+ public void setClasspath(Path classpath) {
+ if (this.classpath == null) {
+ this.classpath = classpath;
+ } else {
+ this.classpath.append(classpath);
+ }
+ }
+
+ /**
+ * Adds to the classpath used when compiling the EJB stubs and skeletons.
+ * @return the class path.
+ */
+ public Path createClasspath() {
+ if (classpath == null) {
+ classpath = new Path(getProject());
+ }
+ return classpath.createPath();
+ }
+
+ /**
+ * If true, the Java source files which are generated by ejbc will be saved .
+ *
+ * @param keepgenerated A boolean indicating if the Java source files for
+ * the stubs and skeletons should be retained.
+ */
+ public void setKeepgenerated(boolean keepgenerated) {
+ this.keepgenerated = keepgenerated;
+ }
+
+ /**
+ * If true, debugging output will be generated when ejbc is
+ * executed.
+ *
+ * @param debug A boolean indicating if debugging output should be generated
+ */
+ public void setDebug(boolean debug) {
+ this.debug = debug;
+ }
+
+ /**
+ * May be used to specify the "home" directory for this iAS installation.
+ * The directory specified should typically be
+ * <code>[install-location]/iplanet/ias6/ias</code>.
+ *
+ * @param iashome The home directory for the user's iAS installation.
+ */
+ public void setIashome(File iashome) {
+ this.iashome = iashome;
+ }
+
+ /**
+ * Does the work.
+ * @throws BuildException if there is a problem.
+ */
+ public void execute() throws BuildException {
+ checkConfiguration();
+
+ executeEjbc(getParser());
+ }
+
+ /**
+ * Verifies that the user selections are valid.
+ *
+ * @throws BuildException If the user selections are invalid.
+ */
+ private void checkConfiguration() throws BuildException {
+
+ if (ejbdescriptor == null) {
+ String msg = "The standard EJB descriptor must be specified using "
+ + "the \"ejbdescriptor\" attribute.";
+ throw new BuildException(msg, getLocation());
+ }
+ if ((!ejbdescriptor.exists()) || (!ejbdescriptor.isFile())) {
+ String msg = "The standard EJB descriptor (" + ejbdescriptor
+ + ") was not found or isn't a file.";
+ throw new BuildException(msg, getLocation());
+ }
+
+ if (iasdescriptor == null) {
+ String msg = "The iAS-speific XML descriptor must be specified using"
+ + " the \"iasdescriptor\" attribute.";
+ throw new BuildException(msg, getLocation());
+ }
+ if ((!iasdescriptor.exists()) || (!iasdescriptor.isFile())) {
+ String msg = "The iAS-specific XML descriptor (" + iasdescriptor
+ + ") was not found or isn't a file.";
+ throw new BuildException(msg, getLocation());
+ }
+
+ if (dest == null) {
+ String msg = "The destination directory must be specified using "
+ + "the \"dest\" attribute.";
+ throw new BuildException(msg, getLocation());
+ }
+ if ((!dest.exists()) || (!dest.isDirectory())) {
+ String msg = "The destination directory (" + dest + ") was not "
+ + "found or isn't a directory.";
+ throw new BuildException(msg, getLocation());
+ }
+
+ if ((iashome != null) && (!iashome.isDirectory())) {
+ String msg = "If \"iashome\" is specified, it must be a valid "
+ + "directory (it was set to " + iashome + ").";
+ throw new BuildException(msg, getLocation());
+ }
+ }
+
+ /**
+ * Returns a SAXParser that may be used to process the XML descriptors.
+ *
+ * @return Parser which may be used to process the EJB descriptors.
+ * @throws BuildException If the parser cannot be created or configured.
+ */
+ private SAXParser getParser() throws BuildException {
+
+ SAXParser saxParser = null;
+ try {
+ SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
+ saxParserFactory.setValidating(true);
+ saxParser = saxParserFactory.newSAXParser();
+ } catch (SAXException e) {
+ String msg = "Unable to create a SAXParser: " + e.getMessage();
+ throw new BuildException(msg, e, getLocation());
+ } catch (ParserConfigurationException e) {
+ String msg = "Unable to create a SAXParser: " + e.getMessage();
+ throw new BuildException(msg, e, getLocation());
+ }
+
+ return saxParser;
+ }
+
+ /**
+ * Executes the EJBc utility using the SAXParser provided.
+ *
+ * @param saxParser SAXParser that may be used to process the EJB
+ * descriptors
+ * @throws BuildException If there is an error reading or parsing the XML
+ * descriptors
+ */
+ private void executeEjbc(SAXParser saxParser) throws BuildException {
+ IPlanetEjbc ejbc = new IPlanetEjbc(ejbdescriptor,
+ iasdescriptor,
+ dest,
+ getClasspath().toString(),
+ saxParser);
+ ejbc.setRetainSource(keepgenerated);
+ ejbc.setDebugOutput(debug);
+ if (iashome != null) {
+ ejbc.setIasHomeDir(iashome);
+ }
+
+ try {
+ ejbc.execute();
+ } catch (IOException e) {
+ String msg = "An IOException occurred while trying to read the XML "
+ + "descriptor file: " + e.getMessage();
+ throw new BuildException(msg, e, getLocation());
+ } catch (SAXException e) {
+ String msg = "A SAXException occurred while trying to read the XML "
+ + "descriptor file: " + e.getMessage();
+ throw new BuildException(msg, e, getLocation());
+ } catch (IPlanetEjbc.EjbcException e) {
+ String msg = "An exception occurred while trying to run the ejbc "
+ + "utility: " + e.getMessage();
+ throw new BuildException(msg, e, getLocation());
+ }
+ }
+
+ /**
+ * Returns the CLASSPATH to be used when calling EJBc. If no user CLASSPATH
+ * is specified, the System classpath is returned instead.
+ *
+ * @return Path The classpath to be used for EJBc.
+ */
+ private Path getClasspath() {
+ Path cp = null;
+ if (classpath == null) {
+ cp = (new Path(getProject())).concatSystemClasspath("last");
+ } else {
+ cp = classpath.concatSystemClasspath("ignore");
+ }
+
+ return cp;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ejb/InnerClassFilenameFilter.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ejb/InnerClassFilenameFilter.java
new file mode 100644
index 00000000..e92d9879
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ejb/InnerClassFilenameFilter.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.ejb;
+
+import java.io.File;
+import java.io.FilenameFilter;
+
+/**
+ * A filename filter for inner class files of a particular class.
+ */
+public class InnerClassFilenameFilter implements FilenameFilter {
+ private String baseClassName;
+
+ /**
+ * Constructor of filter.
+ * @param baseclass the class to filter inner classes on.
+ */
+ InnerClassFilenameFilter(String baseclass) {
+ int extidx = baseclass.lastIndexOf(".class");
+ if (extidx == -1) {
+ extidx = baseclass.length() - 1;
+ }
+ baseClassName = baseclass.substring(0, extidx);
+ }
+
+ /**
+ * Check if the file name passes the filter.
+ * @param dir not used.
+ * @param filename the filename to filter on.
+ * @return true if the filename is an inner class of the base class.
+ */
+ public boolean accept(File dir, String filename) {
+ if ((filename.lastIndexOf(".") != filename.lastIndexOf(".class"))
+ || (filename.indexOf(baseClassName + "$") != 0)) {
+ return false;
+ }
+ return true;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ejb/JbossDeploymentTool.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ejb/JbossDeploymentTool.java
new file mode 100644
index 00000000..79f4574e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ejb/JbossDeploymentTool.java
@@ -0,0 +1,111 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.ejb;
+
+import java.io.File;
+import java.util.Hashtable;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+
+/**
+ * The deployment tool to add the jboss specific deployment descriptor to the ejb jar file.
+ * Jboss only requires one additional file jboss.xml and does not require any additional
+ * compilation.
+ *
+ * @version 1.0
+ * @see EjbJar#createJboss
+ */
+public class JbossDeploymentTool extends GenericDeploymentTool {
+ protected static final String JBOSS_DD = "jboss.xml";
+ protected static final String JBOSS_CMP10D = "jaws.xml";
+ protected static final String JBOSS_CMP20D = "jbosscmp-jdbc.xml";
+
+ /** Instance variable that stores the suffix for the jboss jarfile. */
+ private String jarSuffix = ".jar";
+
+ /**
+ * Setter used to store the suffix for the generated JBoss jar file.
+ * @param inString the string to use as the suffix.
+ */
+ public void setSuffix(String inString) {
+ jarSuffix = inString;
+ }
+
+ /**
+ * Add any vendor specific files which should be included in the
+ * EJB Jar.
+ * @param ejbFiles the hashtable of files to populate.
+ * @param ddPrefix the prefix to use.
+ */
+ protected void addVendorFiles(Hashtable ejbFiles, String ddPrefix) {
+ File jbossDD = new File(getConfig().descriptorDir, ddPrefix + JBOSS_DD);
+ if (jbossDD.exists()) {
+ ejbFiles.put(META_DIR + JBOSS_DD, jbossDD);
+ } else {
+ log("Unable to locate jboss deployment descriptor. "
+ + "It was expected to be in " + jbossDD.getPath(),
+ Project.MSG_WARN);
+ return;
+ }
+ String descriptorFileName = JBOSS_CMP10D;
+ if (EjbJar.CMPVersion.CMP2_0.equals(getParent().getCmpversion())) {
+ descriptorFileName = JBOSS_CMP20D;
+ }
+ File jbossCMPD
+ = new File(getConfig().descriptorDir, ddPrefix + descriptorFileName);
+
+ if (jbossCMPD.exists()) {
+ ejbFiles.put(META_DIR + descriptorFileName, jbossCMPD);
+ } else {
+ log("Unable to locate jboss cmp descriptor. "
+ + "It was expected to be in "
+ + jbossCMPD.getPath(), Project.MSG_VERBOSE);
+ return;
+ }
+ }
+
+ /**
+ * Get the vendor specific name of the Jar that will be output. The modification date
+ * of this jar will be checked against the dependent bean classes.
+ */
+ File getVendorOutputJarFile(String baseName) {
+ if (getDestDir() == null && getParent().getDestdir() == null) {
+ throw new BuildException("DestDir not specified");
+ }
+ if (getDestDir() == null) {
+ return new File(getParent().getDestdir(), baseName + jarSuffix);
+ } else {
+ return new File(getDestDir(), baseName + jarSuffix);
+ }
+ }
+
+ /**
+ * Called to validate that the tool parameters have been configured.
+ *
+ * @throws BuildException If the Deployment Tool's configuration isn't
+ * valid
+ * @since ant 1.6
+ */
+ public void validateConfigured() throws BuildException {
+ }
+
+ private EjbJar getParent() {
+ return (EjbJar) this.getTask();
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ejb/JonasDeploymentTool.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ejb/JonasDeploymentTool.java
new file mode 100644
index 00000000..81fe8059
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ejb/JonasDeploymentTool.java
@@ -0,0 +1,835 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.ejb;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+import javax.xml.parsers.SAXParser;
+
+import org.apache.tools.ant.AntClassLoader;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.Java;
+import org.apache.tools.ant.types.Path;
+
+/**
+ * The deployment tool to add the jonas specific deployment descriptors to the
+ * ejb JAR file. JONAS only requires one additional file jonas-ejb-jar.xml.
+ *
+ * @version 1.0
+ * @see EjbJar#createJonas
+ */
+public class JonasDeploymentTool extends GenericDeploymentTool {
+
+ /** Public Id of the standard deployment descriptor DTD. */
+ protected static final String EJB_JAR_1_1_PUBLIC_ID
+ = "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 1.1//EN";
+ protected static final String EJB_JAR_2_0_PUBLIC_ID
+ = "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN";
+
+ /** Public Id of the JOnAS-specific deployment descriptor DTD. */
+ protected static final String JONAS_EJB_JAR_2_4_PUBLIC_ID
+ = "-//ObjectWeb//DTD JOnAS 2.4//EN";
+ protected static final String JONAS_EJB_JAR_2_5_PUBLIC_ID
+ = "-//ObjectWeb//DTD JOnAS 2.5//EN";
+
+ /** RMI ORB. */
+ protected static final String RMI_ORB = "RMI";
+
+ /** JEREMIE ORB. */
+ protected static final String JEREMIE_ORB = "JEREMIE";
+
+ /** DAVID ORB. */
+ protected static final String DAVID_ORB = "DAVID";
+
+ /**
+ * Name of the standard deployment descriptor DTD (these files are stored in
+ * the ${JONAS_ROOT}/xml directory).
+ */
+ protected static final String EJB_JAR_1_1_DTD = "ejb-jar_1_1.dtd";
+ protected static final String EJB_JAR_2_0_DTD = "ejb-jar_2_0.dtd";
+
+ /**
+ * Name of the JOnAS-specific deployment descriptor DTD (these files are
+ * stored in the ${JONAS_ROOT}/xml directory).
+ */
+ protected static final String JONAS_EJB_JAR_2_4_DTD
+ = "jonas-ejb-jar_2_4.dtd";
+ protected static final String JONAS_EJB_JAR_2_5_DTD
+ = "jonas-ejb-jar_2_5.dtd";
+
+ /** Default JOnAS deployment descriptor name. */
+ protected static final String JONAS_DD = "jonas-ejb-jar.xml";
+
+ /** GenIC class name (JOnAS 2.5) */
+ protected static final String GENIC_CLASS =
+ "org.objectweb.jonas_ejb.genic.GenIC";
+
+ /** Old GenIC class name (JOnAS 2.4.x). */
+ protected static final String OLD_GENIC_CLASS_1 =
+ "org.objectweb.jonas_ejb.tools.GenWholeIC";
+
+ /** Old GenIC class name. */
+ protected static final String OLD_GENIC_CLASS_2 =
+ "org.objectweb.jonas_ejb.tools.GenIC";
+
+ /**
+ * Filename of the standard EJB descriptor (which is passed to this class
+ * from the parent "ejbjar" task). This file is relative to the directory
+ * specified by the "srcdir" attribute in the ejbjar task.
+ */
+ private String descriptorName;
+
+ /**
+ * Filename of the JOnAS-specific EJB descriptor (which is passed to this
+ * class from the parent "ejbjar" task). This file is relative to the
+ * directory specified by the "srcdir" attribute in the ejbjar task.
+ */
+ private String jonasDescriptorName;
+
+ /* ------------- */
+ /* GenIC options */
+ /* ------------- */
+
+ /**
+ * Temporary output directory used by GenIC.
+ */
+ private File outputdir;
+
+ /**
+ * <code>true</code> if the intermediate Java source files generated by
+ * GenIC must be deleted or not. The default is <code>false</code>
+ */
+ private boolean keepgenerated = false;
+
+ /**
+ * <code>true</code> if the generated source files must not be compiled via
+ * the java and rmi compilers. The default is <code>false</code>.
+ */
+ private boolean nocompil = false;
+
+ /**
+ * <code>true</code> if the XML deployment descriptors must be parsed
+ * without validation. The default is <code>false</code>.
+ */
+ private boolean novalidation = false;
+
+ /**
+ * Java compiler to use. The default is the value of
+ * <code>build.compiler</code> property.
+ */
+ private String javac;
+
+ /** Options to pass to the java compiler. */
+ private String javacopts;
+
+ /** Options to pass to the rmi compiler. */
+ private String rmicopts;
+
+ /**
+ * Whether or not the RMI skeleton and stub must be modified to
+ * implement the implicit propagation of the security context (the
+ * transactional context is always provided). The default is
+ * <code>false</code>.
+ */
+ private boolean secpropag = false;
+
+ /**
+ * <code>true</code> if the GenIC call must be verbose. The default
+ * is <code>false</code>.
+ */
+ private boolean verbose = false;
+
+ /** Additional args to send to GenIC. */
+ private String additionalargs;
+
+ /* ------------- */
+ /* other options */
+ /* ------------- */
+
+ /** JOnAS root directory. */
+ private File jonasroot;
+
+ /**
+ * <code>true</code> if the generic JAR file used as input to GenIC must be
+ * retained. The default is <code>false</code>.
+ */
+ private boolean keepgeneric = false;
+
+ /** Stores the suffix for the JOnAS JAR file. The default is '.jar'. */
+ private String suffix = ".jar";
+
+ /**
+ * ORB to use (RMI, JEREMIE or DAVID). If omitted, it defaults to the one
+ * present in classpath. If specified, the corresponding JOnAS JAR is
+ * automatically added to the classpath.
+ */
+ private String orb;
+
+ /**
+ * <code>true</code> if GenIC must not be run on the EJB JAR.
+ * The default is <code>false</code>.
+ */
+ private boolean nogenic = false;
+
+ /* -------------------- */
+ /* GenIC options setter */
+ /* -------------------- */
+
+ /**
+ * Sets the <code>keepgenerated</code> flag.
+ *
+ * @param aBoolean <code>true</code> if the flag must be set.
+ */
+ public void setKeepgenerated(boolean aBoolean) {
+ keepgenerated = aBoolean;
+ }
+
+ /**
+ * Sets the additional arguments.
+ *
+ * @param aString additional args.
+ */
+ public void setAdditionalargs(String aString) {
+ additionalargs = aString;
+ }
+
+ /**
+ * Sets the <code>nocompil</code> flag.
+ *
+ * @param aBoolean <code>true</code> if the flag must be set.
+ */
+ public void setNocompil(boolean aBoolean) {
+ nocompil = aBoolean;
+ }
+
+ /**
+ * Sets the <code>novalidation</code> flag.
+ *
+ * @param aBoolean <code>true</code> if the flag must be set.
+ */
+ public void setNovalidation(boolean aBoolean) {
+ novalidation = aBoolean;
+ }
+
+ /**
+ * Sets the java compiler to use.
+ *
+ * @param aString the java compiler.
+ */
+ public void setJavac(String aString) {
+ javac = aString;
+ }
+
+ /**
+ * Set the options to pass to the java compiler.
+ *
+ * @param aString the options.
+ */
+ public void setJavacopts(String aString) {
+ javacopts = aString;
+ }
+
+ /**
+ * Set the options to pass to the rmi compiler.
+ *
+ * @param aString the options.
+ */
+ public void setRmicopts(String aString) {
+ rmicopts = aString;
+ }
+
+ /**
+ * Sets the <code>secpropag</code> flag.
+ *
+ * @param aBoolean <code>true</code> if the flag must be set.
+ */
+ public void setSecpropag(boolean aBoolean) {
+ secpropag = aBoolean;
+ }
+
+ /**
+ * Sets the <code>verbose</code> flag.
+ *
+ * @param aBoolean <code>true</code> if the flag must be set.
+ */
+ public void setVerbose(boolean aBoolean) {
+ verbose = aBoolean;
+ }
+
+ /* -------------------- */
+ /* other options setter */
+ /* -------------------- */
+
+ /**
+ * Set the JOnAS root directory.
+ *
+ * @param aFile the JOnAS root directory.
+ */
+ public void setJonasroot(File aFile) {
+ jonasroot = aFile;
+ }
+
+ /**
+ * Sets the <code>keepgeneric</code> flag.
+ *
+ * @param aBoolean <code>true</code> if the flag must be set.
+ */
+ public void setKeepgeneric(boolean aBoolean) {
+ keepgeneric = aBoolean;
+ }
+
+ /**
+ * Sets the jar suffix.
+ *
+ * @param aString the string to use as the suffix.
+ */
+ public void setJarsuffix(String aString) {
+ suffix = aString;
+ }
+
+ /**
+ * Sets the <code>orb</code> to construct classpath.
+ *
+ * @param aString 'RMI', 'JEREMIE', or 'DAVID'.
+ */
+ public void setOrb(String aString) {
+ orb = aString;
+ }
+
+ /**
+ * Sets the <code>nogenic</code> flag.
+ *
+ * @param aBoolean <code>true</code> if the flag must be set.
+ */
+ public void setNogenic(boolean aBoolean) {
+ nogenic = aBoolean;
+ }
+
+ /* ------------- */
+ /* other methods */
+ /* ------------- */
+
+ /** {@inheritDoc}. */
+ public void processDescriptor(String aDescriptorName, SAXParser saxParser) {
+
+ descriptorName = aDescriptorName;
+
+ log("JOnAS Deployment Tool processing: " + descriptorName,
+ Project.MSG_VERBOSE);
+
+ super.processDescriptor(descriptorName, saxParser);
+
+ if (outputdir != null) {
+ // the method deleteOnExit() do not work because the directory is not empty
+ log("Deleting temp output directory '" + outputdir + "'.", Project.MSG_VERBOSE);
+ deleteAllFiles(outputdir);
+ }
+ }
+
+ /** {@inheritDoc}. */
+ protected void writeJar(String baseName, File jarfile, Hashtable ejbFiles, String publicId)
+ throws BuildException {
+
+ // create the generic jar first
+ File genericJarFile = super.getVendorOutputJarFile(baseName);
+ super.writeJar(baseName, genericJarFile, ejbFiles, publicId);
+
+ // GenIC call on generic jar
+ addGenICGeneratedFiles(genericJarFile, ejbFiles);
+
+ // create the real jar
+ super.writeJar(baseName, getVendorOutputJarFile(baseName), ejbFiles, publicId);
+
+ if (!keepgeneric) {
+ log("Deleting generic JAR " + genericJarFile.toString(), Project.MSG_VERBOSE);
+ genericJarFile.delete();
+ }
+ }
+
+ /** {@inheritDoc}. */
+ protected void addVendorFiles(Hashtable ejbFiles, String ddPrefix) {
+
+ // JOnAS-specific descriptor deployment
+ jonasDescriptorName = getJonasDescriptorName();
+ File jonasDD = new File(getConfig().descriptorDir, jonasDescriptorName);
+
+ if (jonasDD.exists()) {
+ ejbFiles.put(META_DIR + JONAS_DD, jonasDD);
+ } else {
+ log("Unable to locate the JOnAS deployment descriptor. It was expected to be in: "
+ + jonasDD.getPath() + ".", Project.MSG_WARN);
+ }
+ }
+
+ /** {@inheritDoc}. */
+ protected File getVendorOutputJarFile(String baseName) {
+ return new File(getDestDir(), baseName + suffix);
+ }
+
+ /**
+ * Determines the name of the JOnAS-specific EJB descriptor using the
+ * specified standard EJB descriptor name. In general, the standard
+ * descriptor will be named "[basename]-ejb-jar.xml", and this method will
+ * return "[basename]-jonas-ejb-jar.xml" or "jonas-[basename].xml"
+ *
+ * @return The name of the JOnAS-specific EJB descriptor file.
+ */
+ private String getJonasDescriptorName() {
+
+ // descriptorName = <path><basename><basenameterminator><remainder>
+ // examples = /org/objectweb/fooAppli/foo/Foo-ejb-jar.xml
+ // examples = /org/objectweb/fooAppli/foo/Foo.xml (JOnAS convention)
+
+ String jonasDN; // JOnAS-specific DD
+ boolean jonasConvention = false; // true if the JOnAS convention is used for the DD
+ String path; // Directory path of the EJB descriptor
+ String fileName; // EJB descriptor file name
+ String baseName; // Filename appearing before name terminator
+ String remainder; // Filename appearing after the name terminator
+
+ int startOfFileName = descriptorName.lastIndexOf(File.separatorChar);
+ if (startOfFileName != -1) {
+ // extract path info
+ path = descriptorName.substring(0, startOfFileName + 1);
+ fileName = descriptorName.substring(startOfFileName + 1);
+ } else {
+ // descriptorName is just a file without path
+ path = "";
+ fileName = descriptorName;
+ }
+
+ if (fileName.startsWith(EJB_DD)) {
+ return path + JONAS_DD;
+ }
+
+ int endOfBaseName = descriptorName.indexOf(getConfig().baseNameTerminator, startOfFileName);
+
+ /*
+ * Check for the odd case where the terminator and/or filename
+ * extension aren't found. These will ensure "jonas-" appears at the
+ * end of the name and before the '.' (if present).
+ */
+ if (endOfBaseName < 0) {
+ // baseNameTerminator not found: the descriptor use the
+ // JOnAS naming convention, ie [Foo.xml,jonas-Foo.xml] and
+ // not [Foo<baseNameTerminator>-ejb-jar.xml,
+ // Foo<baseNameTerminator>-jonas-ejb-jar.xml].
+ endOfBaseName = descriptorName.lastIndexOf('.') - 1;
+ if (endOfBaseName < 0) {
+ // no . found
+ endOfBaseName = descriptorName.length() - 1;
+ }
+
+ jonasConvention = true;
+ }
+
+ baseName = descriptorName.substring(startOfFileName + 1, endOfBaseName + 1);
+ remainder = descriptorName.substring(endOfBaseName + 1);
+
+ if (jonasConvention) {
+ jonasDN = path + "jonas-" + baseName + ".xml";
+ } else {
+ jonasDN = path + baseName + "jonas-" + remainder;
+ }
+
+ log("Standard EJB descriptor name: " + descriptorName, Project.MSG_VERBOSE);
+ log("JOnAS-specific descriptor name: " + jonasDN, Project.MSG_VERBOSE);
+
+ return jonasDN;
+ }
+
+ /** {@inheritDoc}. */
+ protected String getJarBaseName(String descriptorFileName) {
+
+ String baseName = null;
+
+ if (getConfig().namingScheme.getValue().equals(EjbJar.NamingScheme.DESCRIPTOR)) {
+
+ // try to find JOnAS specific convention name
+ if (descriptorFileName.indexOf(getConfig().baseNameTerminator) == -1) {
+
+ // baseNameTerminator not found: the descriptor use the
+ // JOnAS naming convention, ie [Foo.xml,jonas-Foo.xml] and
+ // not [Foo<baseNameTerminator>-ejb-jar.xml,
+ // Foo<baseNameTerminator>-jonas-ejb-jar.xml].
+
+ String aCanonicalDescriptor = descriptorFileName.replace('\\', '/');
+ int lastSeparatorIndex = aCanonicalDescriptor.lastIndexOf('/');
+ int endOfBaseName;
+
+ if (lastSeparatorIndex != -1) {
+ endOfBaseName = descriptorFileName.indexOf(".xml", lastSeparatorIndex);
+ } else {
+ endOfBaseName = descriptorFileName.indexOf(".xml");
+ }
+
+ if (endOfBaseName != -1) {
+ baseName = descriptorFileName.substring(0, endOfBaseName);
+ }
+ }
+ }
+
+ if (baseName == null) {
+ // else get standard baseName
+ baseName = super.getJarBaseName(descriptorFileName);
+ }
+
+ log("JAR base name: " + baseName, Project.MSG_VERBOSE);
+
+ return baseName;
+ }
+
+ /** {@inheritDoc}. */
+ protected void registerKnownDTDs(DescriptorHandler handler) {
+ handler.registerDTD(EJB_JAR_1_1_PUBLIC_ID,
+ jonasroot + File.separator + "xml" + File.separator + EJB_JAR_1_1_DTD);
+ handler.registerDTD(EJB_JAR_2_0_PUBLIC_ID,
+ jonasroot + File.separator + "xml" + File.separator + EJB_JAR_2_0_DTD);
+
+ handler.registerDTD(JONAS_EJB_JAR_2_4_PUBLIC_ID,
+ jonasroot + File.separator + "xml" + File.separator + JONAS_EJB_JAR_2_4_DTD);
+ handler.registerDTD(JONAS_EJB_JAR_2_5_PUBLIC_ID,
+ jonasroot + File.separator + "xml" + File.separator + JONAS_EJB_JAR_2_5_DTD);
+ }
+
+ /**
+ * Add to the given hashtable all the file generated by GenIC.
+ *
+ * @param genericJarFile jar file.
+ * @param ejbFiles the hashtable.
+ */
+ private void addGenICGeneratedFiles(
+ File genericJarFile, Hashtable ejbFiles) {
+ Java genicTask = null; // GenIC task
+ String genicClass = null; // GenIC class (3 are supported for various
+ // versions
+ if (nogenic) {
+ return;
+ }
+
+ genicTask = new Java(getTask());
+ genicTask.setTaskName("genic");
+ genicTask.setFork(true);
+
+ // jonasroot
+ genicTask.createJvmarg().setValue("-Dinstall.root=" + jonasroot);
+
+ // java policy file
+ String jonasConfigDir = jonasroot + File.separator + "config";
+ File javaPolicyFile = new File(jonasConfigDir, "java.policy");
+ if (javaPolicyFile.exists()) {
+ genicTask.createJvmarg().setValue("-Djava.security.policy="
+ + javaPolicyFile.toString());
+ }
+
+ // outputdir
+ try {
+ outputdir = createTempDir();
+ } catch (IOException aIOException) {
+ String msg = "Cannot create temp dir: " + aIOException.getMessage();
+ throw new BuildException(msg, aIOException);
+ }
+ log("Using temporary output directory: " + outputdir, Project.MSG_VERBOSE);
+
+ genicTask.createArg().setValue("-d");
+ genicTask.createArg().setFile(outputdir);
+
+ // work around a bug of GenIC 2.5
+ String key;
+ File f;
+ Enumeration keys = ejbFiles.keys();
+ while (keys.hasMoreElements()) {
+ key = (String) keys.nextElement();
+ f = new File(outputdir + File.separator + key);
+ f.getParentFile().mkdirs();
+ }
+ log("Worked around a bug of GenIC 2.5.", Project.MSG_VERBOSE);
+
+ // classpath
+ Path classpath = getCombinedClasspath();
+ if (classpath == null) {
+ classpath = new Path(getTask().getProject());
+ }
+ classpath.append(new Path(classpath.getProject(), jonasConfigDir));
+ classpath.append(new Path(classpath.getProject(), outputdir.toString()));
+
+ // try to create the classpath for the correct ORB
+ if (orb != null) {
+ String orbJar = jonasroot + File.separator + "lib"
+ + File.separator + orb + "_jonas.jar";
+ classpath.append(new Path(classpath.getProject(), orbJar));
+ }
+ log("Using classpath: " + classpath.toString(), Project.MSG_VERBOSE);
+ genicTask.setClasspath(classpath);
+
+ // class name (search in the classpath provided for the ejbjar element)
+ genicClass = getGenicClassName(classpath);
+ if (genicClass == null) {
+ log("Cannot find GenIC class in classpath.", Project.MSG_ERR);
+ throw new BuildException("GenIC class not found, please check the classpath.");
+ } else {
+ log("Using '" + genicClass + "' GenIC class." , Project.MSG_VERBOSE);
+ genicTask.setClassname(genicClass);
+ }
+
+ // keepgenerated
+ if (keepgenerated) {
+ genicTask.createArg().setValue("-keepgenerated");
+ }
+
+ // nocompil
+ if (nocompil) {
+ genicTask.createArg().setValue("-nocompil");
+ }
+
+ // novalidation
+ if (novalidation) {
+ genicTask.createArg().setValue("-novalidation");
+ }
+
+ // javac
+ if (javac != null) {
+ genicTask.createArg().setValue("-javac");
+ genicTask.createArg().setLine(javac);
+ }
+
+ // javacopts
+ if (javacopts != null && !javacopts.equals("")) {
+ genicTask.createArg().setValue("-javacopts");
+ genicTask.createArg().setLine(javacopts);
+ }
+
+ // rmicopts
+ if (rmicopts != null && !rmicopts.equals("")) {
+ genicTask.createArg().setValue("-rmicopts");
+ genicTask.createArg().setLine(rmicopts);
+ }
+
+ // secpropag
+ if (secpropag) {
+ genicTask.createArg().setValue("-secpropag");
+ }
+
+ // verbose
+ if (verbose) {
+ genicTask.createArg().setValue("-verbose");
+ }
+
+ // additionalargs
+ if (additionalargs != null) {
+ genicTask.createArg().setValue(additionalargs);
+ }
+
+ // the generated classes must not be added in the generic JAR!
+ // is that buggy on old JOnAS (2.4) ??
+ genicTask.createArg().setValue("-noaddinjar");
+
+ // input file to process by GenIC
+ genicTask.createArg().setValue(genericJarFile.getPath());
+
+ // calling GenIC task
+ log("Calling " + genicClass + " for " + getConfig().descriptorDir
+ + File.separator + descriptorName + ".", Project.MSG_VERBOSE);
+
+ if (genicTask.executeJava() != 0) {
+
+ // the method deleteOnExit() do not work because the directory is not empty
+ log("Deleting temp output directory '" + outputdir + "'.", Project.MSG_VERBOSE);
+ deleteAllFiles(outputdir);
+
+ if (!keepgeneric) {
+ log("Deleting generic JAR " + genericJarFile.toString(),
+ Project.MSG_VERBOSE);
+ genericJarFile.delete();
+ }
+
+ throw new BuildException("GenIC reported an error.");
+ }
+
+ // add the generated files to the ejbFiles
+ addAllFiles(outputdir, "", ejbFiles);
+ }
+
+ /**
+ * Get the GenIC class name to use in the given classpath.
+ *
+ * @param classpath classpath where the GenIC class must be searched.
+ * @return the GenIC class name. Return <code>null</code> if the class name
+ * cannot be found.
+ */
+ String getGenicClassName(Path classpath) {
+
+ log("Looking for GenIC class in classpath: "
+ + classpath.toString(), Project.MSG_VERBOSE);
+
+ AntClassLoader cl = null;
+
+ try {
+ cl = classpath.getProject().createClassLoader(classpath);
+
+ try {
+ cl.loadClass(JonasDeploymentTool.GENIC_CLASS);
+ log("Found GenIC class '" + JonasDeploymentTool.GENIC_CLASS
+ + "' in classpath.", Project.MSG_VERBOSE);
+ return JonasDeploymentTool.GENIC_CLASS;
+
+ } catch (ClassNotFoundException cnf1) {
+ log("GenIC class '" + JonasDeploymentTool.GENIC_CLASS
+ + "' not found in classpath.",
+ Project.MSG_VERBOSE);
+ }
+
+ try {
+ cl.loadClass(JonasDeploymentTool.OLD_GENIC_CLASS_1);
+ log("Found GenIC class '"
+ + JonasDeploymentTool.OLD_GENIC_CLASS_1
+ + "' in classpath.", Project.MSG_VERBOSE);
+ return JonasDeploymentTool.OLD_GENIC_CLASS_1;
+
+ } catch (ClassNotFoundException cnf2) {
+ log("GenIC class '" + JonasDeploymentTool.OLD_GENIC_CLASS_1
+ + "' not found in classpath.",
+ Project.MSG_VERBOSE);
+ }
+
+ try {
+ cl.loadClass(JonasDeploymentTool.OLD_GENIC_CLASS_2);
+ log("Found GenIC class '"
+ + JonasDeploymentTool.OLD_GENIC_CLASS_2
+ + "' in classpath.", Project.MSG_VERBOSE);
+ return JonasDeploymentTool.OLD_GENIC_CLASS_2;
+
+ } catch (ClassNotFoundException cnf3) {
+ log("GenIC class '" + JonasDeploymentTool.OLD_GENIC_CLASS_2
+ + "' not found in classpath.",
+ Project.MSG_VERBOSE);
+ }
+ } finally {
+ if (cl != null) {
+ cl.cleanup();
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Verify the configuration.
+ * @param descriptorFileName the name of the descriptor file.
+ * @param saxParser not used.
+ * @throws BuildException if there is an error.
+ */
+ protected void checkConfiguration(String descriptorFileName,
+ SAXParser saxParser) throws BuildException {
+
+ // jonasroot
+ if (jonasroot == null) {
+ throw new BuildException("The jonasroot attribut is not set.");
+ } else if (!jonasroot.isDirectory()) {
+ throw new BuildException("The jonasroot attribut '" + jonasroot
+ + "' is not a valid directory.");
+ }
+
+ // orb
+ if (orb != null && !orb.equals(RMI_ORB) && !orb.equals(JEREMIE_ORB)
+ && !orb.equals(DAVID_ORB)) {
+ throw new BuildException("The orb attribut '" + orb
+ + "' is not valid (must be either "
+ + RMI_ORB + ", " + JEREMIE_ORB + " or " + DAVID_ORB + ").");
+ }
+
+ // additionalargs
+ if (additionalargs != null && additionalargs.equals("")) {
+ throw new BuildException("Empty additionalargs attribut.");
+ }
+
+ // javac
+ if (javac != null && javac.equals("")) {
+ throw new BuildException("Empty javac attribut.");
+ }
+ }
+
+ /* ----------------------------------------------------------------------------------- */
+ /* utilitary methods */
+ /* ----------------------------------------------------------------------------------- */
+
+ /**
+ * Create a temporary directory for GenIC output.
+ *
+ * @return the temp directory.
+ * @throws BuildException if a temp directory cannot be created.
+ */
+ private File createTempDir() throws IOException {
+ File tmpDir = File.createTempFile("genic", null, null);
+ tmpDir.delete();
+ if (!tmpDir.mkdir()) {
+ throw new IOException("Cannot create the temporary directory '" + tmpDir + "'.");
+ }
+ return tmpDir;
+ }
+
+ /**
+ * Delete a file. If the file is a directory, delete recursivly all the
+ * files inside.
+ *
+ * @param aFile file to delete.
+ */
+ private void deleteAllFiles(File aFile) {
+ if (aFile.isDirectory()) {
+ File[] someFiles = aFile.listFiles();
+
+ for (int i = 0; i < someFiles.length; i++) {
+ deleteAllFiles(someFiles[i]);
+ }
+ }
+ aFile.delete();
+ }
+
+ /**
+ * Add a file to the a given hashtable. If the file is a directory, add
+ * recursivly all the files inside to the hashtable.
+ *
+ * @param file the file to add.
+ * @param rootDir the current sub-directory to scan.
+ * @param hashtable the hashtable where to add the files.
+ */
+ private void addAllFiles(File file, String rootDir, Hashtable hashtable) {
+
+ if (!file.exists()) {
+ throw new IllegalArgumentException();
+ }
+
+ String newRootDir;
+ if (file.isDirectory()) {
+ File[] files = file.listFiles();
+ for (int i = 0; i < files.length; i++) {
+ if (rootDir.length() > 0) {
+ newRootDir = rootDir + File.separator + files[i].getName();
+ } else {
+ newRootDir = files[i].getName();
+ }
+ addAllFiles(files[i], newRootDir, hashtable);
+ }
+ } else {
+ hashtable.put(rootDir, file);
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ejb/WeblogicDeploymentTool.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ejb/WeblogicDeploymentTool.java
new file mode 100644
index 00000000..550f59ce
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ejb/WeblogicDeploymentTool.java
@@ -0,0 +1,932 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.ejb;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Vector;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+import java.util.jar.JarOutputStream;
+
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+import org.apache.tools.ant.AntClassLoader;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.Java;
+import org.apache.tools.ant.types.Environment;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.util.FileUtils;
+import org.xml.sax.InputSource;
+
+/**
+ The weblogic element is used to control the weblogic.ejbc compiler for
+ generating weblogic EJB jars. Prior to Ant 1.3, the method of locating CMP
+ descriptors was to use the ejbjar naming convention. So if your ejb-jar was
+ called, Customer-ejb-jar.xml, your weblogic descriptor was called Customer-
+ weblogic-ejb-jar.xml and your CMP descriptor had to be Customer-weblogic-cmp-
+ rdbms-jar.xml. In addition, the &lt;type-storage&gt; element in the weblogic
+ descriptor had to be set to the standard name META-INF/weblogic-cmp-rdbms-
+ jar.xml, as that is where the CMP descriptor was mapped to in the generated
+ jar.
+*/
+public class WeblogicDeploymentTool extends GenericDeploymentTool {
+ /** EJB11 id */
+ public static final String PUBLICID_EJB11
+ = "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 1.1//EN";
+ /** EJB20 id */
+ public static final String PUBLICID_EJB20
+ = "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN";
+ /** Weblogic 5.1.0 id */
+ public static final String PUBLICID_WEBLOGIC_EJB510
+ = "-//BEA Systems, Inc.//DTD WebLogic 5.1.0 EJB//EN";
+ /** Weblogic 6.0.0 id */
+ public static final String PUBLICID_WEBLOGIC_EJB600
+ = "-//BEA Systems, Inc.//DTD WebLogic 6.0.0 EJB//EN";
+ /** Weblogic 7.0.0 id */
+ public static final String PUBLICID_WEBLOGIC_EJB700
+ = "-//BEA Systems, Inc.//DTD WebLogic 7.0.0 EJB//EN";
+
+ /** Weblogic 5.1 dtd location */
+ protected static final String DEFAULT_WL51_EJB11_DTD_LOCATION
+ = "/weblogic/ejb/deployment/xml/ejb-jar.dtd";
+ /** Weblogic 6.0 ejb 1.1 dtd location */
+ protected static final String DEFAULT_WL60_EJB11_DTD_LOCATION
+ = "/weblogic/ejb20/dd/xml/ejb11-jar.dtd";
+ /** Weblogic 6.0 ejb 2.0 dtd location */
+ protected static final String DEFAULT_WL60_EJB20_DTD_LOCATION
+ = "/weblogic/ejb20/dd/xml/ejb20-jar.dtd";
+
+ protected static final String DEFAULT_WL51_DTD_LOCATION
+ = "/weblogic/ejb/deployment/xml/weblogic-ejb-jar.dtd";
+ protected static final String DEFAULT_WL60_51_DTD_LOCATION
+ = "/weblogic/ejb20/dd/xml/weblogic510-ejb-jar.dtd";
+ protected static final String DEFAULT_WL60_DTD_LOCATION
+ = "/weblogic/ejb20/dd/xml/weblogic600-ejb-jar.dtd";
+ protected static final String DEFAULT_WL70_DTD_LOCATION
+ = "/weblogic/ejb20/dd/xml/weblogic700-ejb-jar.dtd";
+
+ protected static final String DEFAULT_COMPILER = "default";
+
+ protected static final String WL_DD = "weblogic-ejb-jar.xml";
+ protected static final String WL_CMP_DD = "weblogic-cmp-rdbms-jar.xml";
+
+ protected static final String COMPILER_EJB11 = "weblogic.ejbc";
+ protected static final String COMPILER_EJB20 = "weblogic.ejbc20";
+
+ /** File utilities instance for copying jars */
+ private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+
+ /** Instance variable that stores the suffix for the weblogic jarfile. */
+ private String jarSuffix = ".jar";
+
+ /** Instance variable that stores the location of the weblogic DTD file. */
+ private String weblogicDTD;
+
+ /** Instance variable that stores the location of the ejb 1.1 DTD file. */
+ private String ejb11DTD;
+
+ /** Instance variable that determines whether generic ejb jars are kept. */
+ private boolean keepgenerated = false;
+
+ /**
+ * Instance variable that stores the fully qualified classname of the
+ * weblogic EJBC compiler
+ */
+ private String ejbcClass = null;
+
+ private String additionalArgs = "";
+
+ /**
+ * additional args to pass to the spawned jvm
+ */
+ private String additionalJvmArgs = "";
+
+ private boolean keepGeneric = false;
+
+ private String compiler = null;
+
+ private boolean alwaysRebuild = true;
+
+ /** controls whether ejbc is run on the generated jar */
+ private boolean noEJBC = false;
+
+ /** Indicates if the old CMP location convention is to be used. */
+ private boolean newCMP = false;
+
+ /** The classpath to the weblogic classes. */
+ private Path wlClasspath = null;
+
+ /** System properties for the JVM. */
+ private Vector sysprops = new Vector();
+
+ /**
+ * The weblogic.StdoutSeverityLevel to use when running the JVM that
+ * executes ejbc. Set to 16 to avoid the warnings about EJB Home and
+ * Remotes being in the classpath
+ */
+ private Integer jvmDebugLevel = null;
+
+ private File outputDir;
+
+ /**
+ * Add a nested sysproperty element.
+ * @param sysp the element to add.
+ */
+ public void addSysproperty(Environment.Variable sysp) {
+ sysprops.add(sysp);
+ }
+
+
+ /**
+ * Get the classpath to the weblogic classpaths.
+ * @return the classpath to configure.
+ */
+ public Path createWLClasspath() {
+ if (wlClasspath == null) {
+ wlClasspath = new Path(getTask().getProject());
+ }
+ return wlClasspath.createPath();
+ }
+
+ /**
+ * If set ejbc will use this directory as the output
+ * destination rather than a jar file. This allows for the
+ * generation of &quot;exploded&quot; jars.
+ * @param outputDir the directory to be used.
+ */
+ public void setOutputDir(File outputDir) {
+ this.outputDir = outputDir;
+ }
+
+
+ /**
+ * Optional classpath to WL6.0.
+ * Weblogic 6.0 will give a warning if the home and remote interfaces
+ * of a bean are on the system classpath used to run weblogic.ejbc.
+ * In that case, the standard weblogic classes should be set with
+ * this attribute (or equivalent nested element) and the
+ * home and remote interfaces located with the standard classpath
+ * attribute.
+ * @param wlClasspath the path to be used.
+ */
+ public void setWLClasspath(Path wlClasspath) {
+ this.wlClasspath = wlClasspath;
+ }
+
+
+ /**
+ * The compiler (switch <code>-compiler</code>) to use; optional.
+ * This allows for the selection of a different compiler
+ * to be used for the compilation of the generated Java
+ * files. This could be set, for example, to Jikes to
+ * compile with the Jikes compiler. If this is not set
+ * and the <code>build.compiler</code> property is set
+ * to jikes, the Jikes compiler will be used. If this
+ * is not desired, the value &quot;<code>default</code>&quot;
+ * may be given to use the default compiler.
+ * @param compiler the compiler to be used.
+ */
+ public void setCompiler(String compiler) {
+ this.compiler = compiler;
+ }
+
+
+ /**
+ * Set the rebuild flag to false to only update changes in the jar rather
+ * than rerunning ejbc; optional, default true.
+ * This flag controls whether weblogic.ejbc is always
+ * invoked to build the jar file. In certain circumstances,
+ * such as when only a bean class has been changed, the jar
+ * can be generated by merely replacing the changed classes
+ * and not rerunning ejbc. Setting this to false will reduce
+ * the time to run ejbjar.
+ * @param rebuild a <code>boolean</code> value.
+ */
+ public void setRebuild(boolean rebuild) {
+ this.alwaysRebuild = rebuild;
+ }
+
+
+ /**
+ * Sets the weblogic.StdoutSeverityLevel to use when running the JVM that
+ * executes ejbc; optional. Set to 16 to avoid the warnings about EJB Home and
+ * Remotes being in the classpath
+ * @param jvmDebugLevel the value to use.
+ */
+ public void setJvmDebugLevel(Integer jvmDebugLevel) {
+ this.jvmDebugLevel = jvmDebugLevel;
+ }
+
+
+ /**
+ * Get the debug level.
+ * @return the jvm debug level (may be null).
+ */
+ public Integer getJvmDebugLevel() {
+ return jvmDebugLevel;
+ }
+
+
+
+ /**
+ * Setter used to store the suffix for the generated weblogic jar file.
+ *
+ * @param inString the string to use as the suffix.
+ */
+ public void setSuffix(String inString) {
+ this.jarSuffix = inString;
+ }
+
+
+ /**
+ * controls whether the generic file used as input to
+ * ejbc is retained; defaults to false
+ *
+ * @param inValue true for keep generic
+ */
+ public void setKeepgeneric(boolean inValue) {
+ this.keepGeneric = inValue;
+ }
+
+
+ /**
+ * Controls whether weblogic will keep the generated Java
+ * files used to build the class files added to the
+ * jar. This can be useful when debugging; default is false.
+ *
+ * @param inValue either 'true' or 'false'
+ */
+ public void setKeepgenerated(String inValue) {
+ this.keepgenerated = Boolean.valueOf(inValue).booleanValue();
+ }
+
+
+ /**
+ * Any optional extra arguments pass to the weblogic.ejbc
+ * tool.
+ * @param args extra arguments to pass to the ejbc tool.
+ */
+ public void setArgs(String args) {
+ this.additionalArgs = args;
+ }
+
+
+ /**
+ * Set any additional arguments to pass to the weblogic JVM; optional.
+ * @param args the arguments to be passed to the JVM
+ */
+ public void setJvmargs(String args) {
+ this.additionalJvmArgs = args;
+ }
+
+ /**
+ * Set the classname of the ejbc compiler; optional
+ * Normally ejbjar determines
+ * the appropriate class based on the DTD used for the EJB. The EJB 2.0 compiler
+ * featured in weblogic 6 has, however, been deprecated in version 7. When
+ * using with version 7 this attribute should be set to
+ * &quot;weblogic.ejbc&quot; to avoid the deprecation warning.
+ * @param ejbcClass the name of the class to use.
+ */
+ public void setEjbcClass(String ejbcClass) {
+ this.ejbcClass = ejbcClass;
+ }
+
+
+ /**
+ * Get the ejbc compiler class.
+ * @return the name of the ejbc compiler class.
+ */
+ public String getEjbcClass() {
+ return ejbcClass;
+ }
+
+
+ /**
+ * <b>Deprecated</b>. Defines the location of the ejb-jar DTD in
+ * the weblogic class hierarchy. Should not be needed, and the
+ * nested &lt;dtd&gt; element is recommended when it is.
+ *
+ * @param inString the string to use as the DTD location.
+ */
+ public void setWeblogicdtd(String inString) {
+ setEJBdtd(inString);
+ }
+
+
+ /**
+ * <b>Deprecated</b>. Defines the location of weblogic DTD in
+ * the weblogic class hierarchy. Should not be needed, and the
+ * nested &lt;dtd&gt; element is recommended when it is.
+ *
+ * @param inString the string to use as the DTD location.
+ */
+ public void setWLdtd(String inString) {
+ this.weblogicDTD = inString;
+ }
+
+
+ /**
+ * <b>Deprecated</b>. Defines the location of Sun's EJB DTD in
+ * the weblogic class hierarchy. Should not be needed, and the
+ * nested &lt;dtd&gt; element is recommended when it is.
+ *
+ * @param inString the string to use as the DTD location.
+ */
+ public void setEJBdtd(String inString) {
+ this.ejb11DTD = inString;
+ }
+
+
+ /**
+ * Set the value of the oldCMP scheme. This is an antonym for newCMP
+ * @ant.attribute ignore="true'
+ * @param oldCMP a <code>boolean</code> value.
+ */
+ public void setOldCMP(boolean oldCMP) {
+ this.newCMP = !oldCMP;
+ }
+
+
+ /**
+ * If this is set to true, the new method for locating
+ * CMP descriptors will be used; optional, default false.
+ * <P>
+ * The old CMP scheme locates the
+ * weblogic CMP descriptor based on the naming convention where the
+ * weblogic CMP file is expected to be named with the bean name as the
+ * prefix. Under this scheme the name of the CMP descriptor does not match
+ * the name actually used in the main weblogic EJB descriptor. Also,
+ * descriptors which contain multiple CMP references could not be used.
+ * @param newCMP a <code>boolean</code> value.
+ */
+ public void setNewCMP(boolean newCMP) {
+ this.newCMP = newCMP;
+ }
+
+
+ /**
+ * Do not EJBC the jar after it has been put together;
+ * optional, default false
+ * @param noEJBC a <code>boolean</code> value.
+ */
+ public void setNoEJBC(boolean noEJBC) {
+ this.noEJBC = noEJBC;
+ }
+
+
+ /**
+ * Register the DTDs.
+ * @param handler the handler to use.
+ */
+ protected void registerKnownDTDs(DescriptorHandler handler) {
+ // register all the known DTDs
+ handler.registerDTD(PUBLICID_EJB11, DEFAULT_WL51_EJB11_DTD_LOCATION);
+ handler.registerDTD(PUBLICID_EJB11, DEFAULT_WL60_EJB11_DTD_LOCATION);
+ handler.registerDTD(PUBLICID_EJB11, ejb11DTD);
+ handler.registerDTD(PUBLICID_EJB20, DEFAULT_WL60_EJB20_DTD_LOCATION);
+ }
+
+
+ /**
+ * Get the weblogic descriptor handler.
+ * @param srcDir the source directory.
+ * @return the descriptor.
+ */
+ protected DescriptorHandler getWeblogicDescriptorHandler(final File srcDir) {
+ DescriptorHandler handler =
+ new DescriptorHandler(getTask(), srcDir) {
+ protected void processElement() {
+ if (currentElement.equals("type-storage")) {
+ // Get the filename of vendor specific descriptor
+ String fileNameWithMETA = currentText;
+ //trim the META_INF\ off of the file name
+ String fileName
+ = fileNameWithMETA.substring(META_DIR.length(),
+ fileNameWithMETA.length());
+ File descriptorFile = new File(srcDir, fileName);
+
+ ejbFiles.put(fileNameWithMETA, descriptorFile);
+ }
+ }
+ };
+
+ handler.registerDTD(PUBLICID_WEBLOGIC_EJB510, DEFAULT_WL51_DTD_LOCATION);
+ handler.registerDTD(PUBLICID_WEBLOGIC_EJB510, DEFAULT_WL60_51_DTD_LOCATION);
+ handler.registerDTD(PUBLICID_WEBLOGIC_EJB600, DEFAULT_WL60_DTD_LOCATION);
+ handler.registerDTD(PUBLICID_WEBLOGIC_EJB700, DEFAULT_WL70_DTD_LOCATION);
+ handler.registerDTD(PUBLICID_WEBLOGIC_EJB510, weblogicDTD);
+ handler.registerDTD(PUBLICID_WEBLOGIC_EJB600, weblogicDTD);
+
+ for (Iterator i = getConfig().dtdLocations.iterator(); i.hasNext();) {
+ EjbJar.DTDLocation dtdLocation = (EjbJar.DTDLocation) i.next();
+
+ handler.registerDTD(dtdLocation.getPublicId(), dtdLocation.getLocation());
+ }
+ return handler;
+ }
+
+
+ /**
+ * Add any vendor specific files which should be included in the EJB Jar.
+ * @param ejbFiles the hash table to be populated.
+ * @param ddPrefix the prefix to use.
+ */
+ protected void addVendorFiles(Hashtable ejbFiles, String ddPrefix) {
+ File weblogicDD = new File(getConfig().descriptorDir, ddPrefix + WL_DD);
+
+ if (weblogicDD.exists()) {
+ ejbFiles.put(META_DIR + WL_DD,
+ weblogicDD);
+ } else {
+ log("Unable to locate weblogic deployment descriptor. "
+ + "It was expected to be in "
+ + weblogicDD.getPath(), Project.MSG_WARN);
+ return;
+ }
+
+ if (!newCMP) {
+ log("The old method for locating CMP files has been DEPRECATED.", Project.MSG_VERBOSE);
+ log("Please adjust your weblogic descriptor and set "
+ + "newCMP=\"true\" to use the new CMP descriptor "
+ + "inclusion mechanism. ", Project.MSG_VERBOSE);
+ // The the weblogic cmp deployment descriptor
+ File weblogicCMPDD = new File(getConfig().descriptorDir, ddPrefix + WL_CMP_DD);
+
+ if (weblogicCMPDD.exists()) {
+ ejbFiles.put(META_DIR + WL_CMP_DD,
+ weblogicCMPDD);
+ }
+ } else {
+ // now that we have the weblogic descriptor, we parse the file
+ // to find other descriptors needed to deploy the bean.
+ // this could be the weblogic-cmp-rdbms.xml or any other O/R
+ // mapping tool descriptors.
+ try {
+ File ejbDescriptor = (File) ejbFiles.get(META_DIR + EJB_DD);
+ SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
+
+ saxParserFactory.setValidating(true);
+
+ SAXParser saxParser = saxParserFactory.newSAXParser();
+ DescriptorHandler handler
+ = getWeblogicDescriptorHandler(ejbDescriptor.getParentFile());
+
+ saxParser.parse(new InputSource
+ (new FileInputStream(weblogicDD)),
+ handler);
+
+ Hashtable ht = handler.getFiles();
+ Enumeration e = ht.keys();
+
+ while (e.hasMoreElements()) {
+ String key = (String) e.nextElement();
+
+ ejbFiles.put(key, ht.get(key));
+ }
+ } catch (Exception e) {
+ String msg = "Exception while adding Vendor specific files: " + e.toString();
+
+ throw new BuildException(msg, e);
+ }
+ }
+ }
+
+
+ /**
+ * Get the vendor specific name of the Jar that will be output. The
+ * modification date of this jar will be checked against the dependent
+ * bean classes.
+ */
+ File getVendorOutputJarFile(String baseName) {
+ return new File(getDestDir(), baseName + jarSuffix);
+ }
+
+
+ /**
+ * Helper method invoked by execute() for each WebLogic jar to be built.
+ * Encapsulates the logic of constructing a java task for calling
+ * weblogic.ejbc and executing it.
+ *
+ * @param sourceJar java.io.File representing the source (EJB1.1) jarfile.
+ * @param destJar java.io.File representing the destination, WebLogic
+ * jarfile.
+ */
+ private void buildWeblogicJar(File sourceJar, File destJar, String publicId) {
+ Java javaTask = null;
+
+ if (noEJBC) {
+ try {
+ FILE_UTILS.copyFile(sourceJar, destJar);
+ if (!keepgenerated) {
+ sourceJar.delete();
+ }
+ return;
+ } catch (IOException e) {
+ throw new BuildException("Unable to write EJB jar", e);
+ }
+ }
+
+ String ejbcClassName = ejbcClass;
+
+ try {
+ javaTask = new Java(getTask());
+ javaTask.setTaskName("ejbc");
+
+ javaTask.createJvmarg().setLine(additionalJvmArgs);
+ if (!(sysprops.isEmpty())) {
+ for (Enumeration en = sysprops.elements(); en.hasMoreElements();) {
+ Environment.Variable entry
+ = (Environment.Variable) en.nextElement();
+ javaTask.addSysproperty(entry);
+ }
+ }
+
+ if (getJvmDebugLevel() != null) {
+ javaTask.createJvmarg().setLine(" -Dweblogic.StdoutSeverityLevel=" + jvmDebugLevel);
+ }
+
+ if (ejbcClassName == null) {
+ // try to determine it from publicId
+ if (PUBLICID_EJB11.equals(publicId)) {
+ ejbcClassName = COMPILER_EJB11;
+ } else if (PUBLICID_EJB20.equals(publicId)) {
+ ejbcClassName = COMPILER_EJB20;
+ } else {
+ log("Unrecognized publicId " + publicId
+ + " - using EJB 1.1 compiler", Project.MSG_WARN);
+ ejbcClassName = COMPILER_EJB11;
+ }
+ }
+
+ javaTask.setClassname(ejbcClassName);
+ javaTask.createArg().setLine(additionalArgs);
+ if (keepgenerated) {
+ javaTask.createArg().setValue("-keepgenerated");
+ }
+ if (compiler == null) {
+ // try to use the compiler specified by build.compiler.
+ // Right now we are just going to allow Jikes
+ String buildCompiler
+ = getTask().getProject().getProperty("build.compiler");
+
+ if (buildCompiler != null && buildCompiler.equals("jikes")) {
+ javaTask.createArg().setValue("-compiler");
+ javaTask.createArg().setValue("jikes");
+ }
+ } else {
+ if (!compiler.equals(DEFAULT_COMPILER)) {
+ javaTask.createArg().setValue("-compiler");
+ javaTask.createArg().setLine(compiler);
+ }
+ }
+
+ Path combinedClasspath = getCombinedClasspath();
+ if (wlClasspath != null && combinedClasspath != null
+ && combinedClasspath.toString().trim().length() > 0) {
+ javaTask.createArg().setValue("-classpath");
+ javaTask.createArg().setPath(combinedClasspath);
+ }
+
+ javaTask.createArg().setValue(sourceJar.getPath());
+ if (outputDir == null) {
+ javaTask.createArg().setValue(destJar.getPath());
+ } else {
+ javaTask.createArg().setValue(outputDir.getPath());
+ }
+
+ Path classpath = wlClasspath;
+
+ if (classpath == null) {
+ classpath = getCombinedClasspath();
+ }
+
+ javaTask.setFork(true);
+ if (classpath != null) {
+ javaTask.setClasspath(classpath);
+ }
+
+ log("Calling " + ejbcClassName + " for " + sourceJar.toString(),
+ Project.MSG_VERBOSE);
+
+ if (javaTask.executeJava() != 0) {
+ throw new BuildException("Ejbc reported an error");
+ }
+ } catch (Exception e) {
+ // Have to catch this because of the semantics of calling main()
+ String msg = "Exception while calling " + ejbcClassName
+ + ". Details: " + e.toString();
+
+ throw new BuildException(msg, e);
+ }
+ }
+
+
+ /**
+ * Method used to encapsulate the writing of the JAR file. Iterates over
+ * the filenames/java.io.Files in the Hashtable stored on the instance
+ * variable ejbFiles.
+ * @param baseName the base name.
+ * @param jarFile the jar file to populate.
+ * @param files the hash table of files to write.
+ * @param publicId the id to use.
+ * @throws BuildException if there is a problem.
+ */
+ protected void writeJar(String baseName, File jarFile, Hashtable files,
+ String publicId) throws BuildException {
+ // need to create a generic jar first.
+ File genericJarFile = super.getVendorOutputJarFile(baseName);
+
+ super.writeJar(baseName, genericJarFile, files, publicId);
+
+ if (alwaysRebuild || isRebuildRequired(genericJarFile, jarFile)) {
+ buildWeblogicJar(genericJarFile, jarFile, publicId);
+ }
+ if (!keepGeneric) {
+ log("deleting generic jar " + genericJarFile.toString(),
+ Project.MSG_VERBOSE);
+ genericJarFile.delete();
+ }
+ }
+
+
+ /**
+ * Called to validate that the tool parameters have been configured.
+ * @throws BuildException if there is an error.
+ */
+ public void validateConfigured() throws BuildException {
+ super.validateConfigured();
+ }
+
+
+ /**
+ * Helper method to check to see if a weblogic EBJ1.1 jar needs to be
+ * rebuilt using ejbc. Called from writeJar it sees if the "Bean" classes
+ * are the only thing that needs to be updated and either updates the Jar
+ * with the Bean classfile or returns true, saying that the whole weblogic
+ * jar needs to be regened with ejbc. This allows faster build times for
+ * working developers. <p>
+ *
+ * The way weblogic ejbc works is it creates wrappers for the publicly
+ * defined methods as they are exposed in the remote interface. If the
+ * actual bean changes without changing the the method signatures then
+ * only the bean classfile needs to be updated and the rest of the
+ * weblogic jar file can remain the same. If the Interfaces, ie. the
+ * method signatures change or if the xml deployment descriptors changed,
+ * the whole jar needs to be rebuilt with ejbc. This is not strictly true
+ * for the xml files. If the JNDI name changes then the jar doesn't have to
+ * be rebuild, but if the resources references change then it does. At
+ * this point the weblogic jar gets rebuilt if the xml files change at
+ * all.
+ *
+ * @param genericJarFile java.io.File The generic jar file.
+ * @param weblogicJarFile java.io.File The weblogic jar file to check to
+ * see if it needs to be rebuilt.
+ * @return true if the jar needs to be rebuilt.
+ */
+ // CheckStyle:MethodLength OFF - this will no be fixed
+ protected boolean isRebuildRequired(File genericJarFile, File weblogicJarFile) {
+ boolean rebuild = false;
+
+ JarFile genericJar = null;
+ JarFile wlJar = null;
+ File newWLJarFile = null;
+ JarOutputStream newJarStream = null;
+ ClassLoader genericLoader = null;
+
+ try {
+ log("Checking if weblogic Jar needs to be rebuilt for jar " + weblogicJarFile.getName(),
+ Project.MSG_VERBOSE);
+ // Only go forward if the generic and the weblogic file both exist
+ if (genericJarFile.exists() && genericJarFile.isFile()
+ && weblogicJarFile.exists() && weblogicJarFile.isFile()) {
+ //open jar files
+ genericJar = new JarFile(genericJarFile);
+ wlJar = new JarFile(weblogicJarFile);
+
+ Hashtable genericEntries = new Hashtable();
+ Hashtable wlEntries = new Hashtable();
+ Hashtable replaceEntries = new Hashtable();
+
+ //get the list of generic jar entries
+ for (Enumeration e = genericJar.entries(); e.hasMoreElements();) {
+ JarEntry je = (JarEntry) e.nextElement();
+
+ genericEntries.put(je.getName().replace('\\', '/'), je);
+ }
+ //get the list of weblogic jar entries
+ for (Enumeration e = wlJar.entries(); e.hasMoreElements();) {
+ JarEntry je = (JarEntry) e.nextElement();
+
+ wlEntries.put(je.getName(), je);
+ }
+
+ //Cycle Through generic and make sure its in weblogic
+ genericLoader = getClassLoaderFromJar(genericJarFile);
+
+ for (Enumeration e = genericEntries.keys(); e.hasMoreElements();) {
+ String filepath = (String) e.nextElement();
+
+ if (wlEntries.containsKey(filepath)) {
+ // File name/path match
+
+ // Check files see if same
+ JarEntry genericEntry = (JarEntry) genericEntries.get(filepath);
+ JarEntry wlEntry = (JarEntry) wlEntries.get(filepath);
+
+ if ((genericEntry.getCrc() != wlEntry.getCrc())
+ || (genericEntry.getSize() != wlEntry.getSize())) {
+
+ if (genericEntry.getName().endsWith(".class")) {
+ //File are different see if its an object or an interface
+ String classname
+ = genericEntry.getName()
+ .replace(File.separatorChar, '.')
+ .replace('/', '.');
+
+ classname = classname.substring(0, classname.lastIndexOf(".class"));
+
+ Class genclass = genericLoader.loadClass(classname);
+
+ if (genclass.isInterface()) {
+ //Interface changed rebuild jar.
+ log("Interface " + genclass.getName()
+ + " has changed", Project.MSG_VERBOSE);
+ rebuild = true;
+ break;
+ } else {
+ //Object class Changed update it.
+ replaceEntries.put(filepath, genericEntry);
+ }
+ } else {
+ // is it the manifest. If so ignore it
+ if (!genericEntry.getName().equals("META-INF/MANIFEST.MF")) {
+ //File other then class changed rebuild
+ log("Non class file " + genericEntry.getName()
+ + " has changed", Project.MSG_VERBOSE);
+ rebuild = true;
+ break;
+ }
+ }
+ }
+ } else {
+ // a file doesn't exist rebuild
+
+ log("File " + filepath + " not present in weblogic jar",
+ Project.MSG_VERBOSE);
+ rebuild = true;
+ break;
+ }
+ }
+
+ if (!rebuild) {
+ log("No rebuild needed - updating jar", Project.MSG_VERBOSE);
+ newWLJarFile = new File(weblogicJarFile.getAbsolutePath() + ".temp");
+ if (newWLJarFile.exists()) {
+ newWLJarFile.delete();
+ }
+
+ newJarStream = new JarOutputStream(new FileOutputStream(newWLJarFile));
+ newJarStream.setLevel(0);
+
+ //Copy files from old weblogic jar
+ for (Enumeration e = wlEntries.elements(); e.hasMoreElements();) {
+ byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
+ int bytesRead;
+ InputStream is;
+ JarEntry je = (JarEntry) e.nextElement();
+
+ if (je.getCompressedSize() == -1
+ || je.getCompressedSize() == je.getSize()) {
+ newJarStream.setLevel(0);
+ } else {
+ newJarStream.setLevel(JAR_COMPRESS_LEVEL);
+ }
+
+ // Update with changed Bean class
+ if (replaceEntries.containsKey(je.getName())) {
+ log("Updating Bean class from generic Jar "
+ + je.getName(), Project.MSG_VERBOSE);
+ // Use the entry from the generic jar
+ je = (JarEntry) replaceEntries.get(je.getName());
+ is = genericJar.getInputStream(je);
+ } else {
+ //use fle from original weblogic jar
+
+ is = wlJar.getInputStream(je);
+ }
+ newJarStream.putNextEntry(new JarEntry(je.getName()));
+
+ while ((bytesRead = is.read(buffer)) != -1) {
+ newJarStream.write(buffer, 0, bytesRead);
+ }
+ is.close();
+ }
+ } else {
+ log("Weblogic Jar rebuild needed due to changed "
+ + "interface or XML", Project.MSG_VERBOSE);
+ }
+ } else {
+ rebuild = true;
+ }
+ } catch (ClassNotFoundException cnfe) {
+ String cnfmsg = "ClassNotFoundException while processing ejb-jar file"
+ + ". Details: "
+ + cnfe.getMessage();
+
+ throw new BuildException(cnfmsg, cnfe);
+ } catch (IOException ioe) {
+ String msg = "IOException while processing ejb-jar file "
+ + ". Details: "
+ + ioe.getMessage();
+
+ throw new BuildException(msg, ioe);
+ } finally {
+ // need to close files and perhaps rename output
+ if (genericJar != null) {
+ try {
+ genericJar.close();
+ } catch (IOException closeException) {
+ // empty
+ }
+ }
+
+ if (wlJar != null) {
+ try {
+ wlJar.close();
+ } catch (IOException closeException) {
+ // empty
+ }
+ }
+
+ if (newJarStream != null) {
+ try {
+ newJarStream.close();
+ } catch (IOException closeException) {
+ // empty
+ }
+
+ try {
+ FILE_UTILS.rename(newWLJarFile, weblogicJarFile);
+ } catch (IOException renameException) {
+ log(renameException.getMessage(), Project.MSG_WARN);
+ rebuild = true;
+ }
+ }
+ if (genericLoader != null
+ && genericLoader instanceof AntClassLoader) {
+ AntClassLoader loader = (AntClassLoader) genericLoader;
+ loader.cleanup();
+ }
+ }
+
+ return rebuild;
+ }
+
+
+ /**
+ * Helper method invoked by isRebuildRequired to get a ClassLoader for a
+ * Jar File passed to it.
+ *
+ * @param classjar java.io.File representing jar file to get classes from.
+ * @return the classloader for the jarfile.
+ * @throws IOException if there is a problem.
+ */
+ protected ClassLoader getClassLoaderFromJar(File classjar) throws IOException {
+ Path lookupPath = new Path(getTask().getProject());
+
+ lookupPath.setLocation(classjar);
+
+ Path classpath = getCombinedClasspath();
+
+ if (classpath != null) {
+ lookupPath.append(classpath);
+ }
+
+ return getTask().getProject().createClassLoader(lookupPath);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ejb/WeblogicTOPLinkDeploymentTool.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ejb/WeblogicTOPLinkDeploymentTool.java
new file mode 100644
index 00000000..0752bbec
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ejb/WeblogicTOPLinkDeploymentTool.java
@@ -0,0 +1,113 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.ejb;
+
+import java.io.File;
+import java.util.Hashtable;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+
+/**
+ * Deployment tool for Weblogic TOPLink.
+ */
+public class WeblogicTOPLinkDeploymentTool extends WeblogicDeploymentTool {
+
+ private static final String TL_DTD_LOC
+ = "http://www.objectpeople.com/tlwl/dtd/toplink-cmp_2_5_1.dtd";
+
+ private String toplinkDescriptor;
+ private String toplinkDTD;
+
+ /**
+ * Setter used to store the name of the toplink descriptor.
+ * @param inString the string to use as the descriptor name.
+ */
+ public void setToplinkdescriptor(String inString) {
+ this.toplinkDescriptor = inString;
+ }
+
+ /**
+ * Setter used to store the location of the toplink DTD file.
+ * This is expected to be an URL (file or otherwise). If running
+ * this on NT using a file URL, the safest thing would be to not use a
+ * drive spec in the URL and make sure the file resides on the drive that
+ * ANT is running from. This will keep the setting in the build XML
+ * platform independent.
+ *
+ * @param inString the string to use as the DTD location.
+ */
+ public void setToplinkdtd(String inString) {
+ this.toplinkDTD = inString;
+ }
+
+ /**
+ * Get the descriptor handler.
+ * @param srcDir the source file.
+ * @return the descriptor handler.
+ */
+ protected DescriptorHandler getDescriptorHandler(File srcDir) {
+ DescriptorHandler handler = super.getDescriptorHandler(srcDir);
+ if (toplinkDTD != null) {
+ handler.registerDTD("-//The Object People, Inc.//"
+ + "DTD TOPLink for WebLogic CMP 2.5.1//EN", toplinkDTD);
+ } else {
+ handler.registerDTD("-//The Object People, Inc.//"
+ + "DTD TOPLink for WebLogic CMP 2.5.1//EN", TL_DTD_LOC);
+ }
+ return handler;
+ }
+
+ /**
+ * Add any vendor specific files which should be included in the
+ * EJB Jar.
+ * @param ejbFiles the hashtable to add files to.
+ * @param ddPrefix the prefix to use.
+ */
+ protected void addVendorFiles(Hashtable ejbFiles, String ddPrefix) {
+ super.addVendorFiles(ejbFiles, ddPrefix);
+ // Then the toplink deployment descriptor
+
+ // Setup a naming standard here?.
+
+
+ File toplinkDD = new File(getConfig().descriptorDir, ddPrefix + toplinkDescriptor);
+
+ if (toplinkDD.exists()) {
+ ejbFiles.put(META_DIR + toplinkDescriptor,
+ toplinkDD);
+ } else {
+ log("Unable to locate toplink deployment descriptor. "
+ + "It was expected to be in "
+ + toplinkDD.getPath(), Project.MSG_WARN);
+ }
+ }
+
+ /**
+ * Called to validate that the tool parameters have been configured.
+ * @throws BuildException if there is an error.
+ */
+ public void validateConfigured() throws BuildException {
+ super.validateConfigured();
+ if (toplinkDescriptor == null) {
+ throw new BuildException("The toplinkdescriptor attribute must "
+ + "be specified");
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ejb/WebsphereDeploymentTool.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ejb/WebsphereDeploymentTool.java
new file mode 100644
index 00000000..d15f9f52
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ejb/WebsphereDeploymentTool.java
@@ -0,0 +1,897 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.ejb;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+import java.util.jar.JarOutputStream;
+
+import org.apache.tools.ant.AntClassLoader;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.Java;
+import org.apache.tools.ant.types.Environment;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.util.FileUtils;
+
+/**
+ * Websphere deployment tool that augments the ejbjar task.
+ * Searches for the websphere specific deployment descriptors and
+ * adds them to the final ejb jar file. Websphere has two specific descriptors for session
+ * beans:
+ * <ul>
+ * <li>ibm-ejb-jar-bnd.xmi</li>
+ * <li>ibm-ejb-jar-ext.xmi</li>
+ * </ul>
+ * and another two for container managed entity beans:
+ * <ul>
+ * <li>Map.mapxmi</li>
+ * <li>Schema.dbxmi</li>
+ * </ul>
+ * In terms of WebSphere, the generation of container code and stubs is
+ * called <code>deployment</code>. This step can be performed by the websphere
+ * element as part of the jar generation process. If the switch
+ * <code>ejbdeploy</code> is on, the ejbdeploy tool from the websphere toolset
+ * is called for every ejb-jar. Unfortunately, this step only works, if you
+ * use the ibm jdk. Otherwise, the rmic (called by ejbdeploy) throws a
+ * ClassFormatError. Be sure to switch ejbdeploy off, if run ant with
+ * sun jdk.
+ *
+ */
+public class WebsphereDeploymentTool extends GenericDeploymentTool {
+
+ /** ID for ejb 1.1 */
+ public static final String PUBLICID_EJB11
+ = "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 1.1//EN";
+ /** ID for ejb 2.0 */
+ public static final String PUBLICID_EJB20
+ = "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN";
+ /** Schema directory */
+ protected static final String SCHEMA_DIR = "Schema/";
+
+ protected static final String WAS_EXT = "ibm-ejb-jar-ext.xmi";
+ protected static final String WAS_BND = "ibm-ejb-jar-bnd.xmi";
+ protected static final String WAS_CMP_MAP = "Map.mapxmi";
+ protected static final String WAS_CMP_SCHEMA = "Schema.dbxmi";
+
+ private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+
+ /** Instance variable that stores the suffix for the websphere jarfile. */
+ private String jarSuffix = ".jar";
+
+ /** Instance variable that stores the location of the ejb 1.1 DTD file. */
+ private String ejb11DTD;
+
+ /** Instance variable that determines whether generic ejb jars are kept. */
+
+ private boolean keepGeneric = false;
+
+ private boolean alwaysRebuild = true;
+
+ private boolean ejbdeploy = true;
+
+ /** Indicates if the old CMP location convention is to be used. */
+ private boolean newCMP = false;
+
+ /** The classpath to the websphere classes. */
+ private Path wasClasspath = null;
+
+ /** The DB Vendor name, the EJB is persisted against */
+ private String dbVendor;
+
+ /** The name of the database to create. (For top-down mapping only) */
+ private String dbName;
+
+ /** The name of the schema to create. (For top-down mappings only) */
+ private String dbSchema;
+
+ /** true - Only generate the deployment code, do not run RMIC or Javac */
+ private boolean codegen;
+
+ /** true - Only output error messages, suppress informational messages */
+ private boolean quiet = true;
+
+ /** true - Disable the validation steps */
+ private boolean novalidate;
+
+ /** true - Disable warning and informational messages */
+ private boolean nowarn;
+
+ /** true - Disable informational messages */
+ private boolean noinform;
+
+ /** true - Enable internal tracing */
+ private boolean trace;
+
+ /** Additional options for RMIC */
+ private String rmicOptions;
+
+ /** true- Use the WebSphere 3.5 compatible mapping rules */
+ private boolean use35MappingRules;
+
+ /** the scratchdir for the ejbdeploy operation */
+ private String tempdir = "_ejbdeploy_temp";
+
+ /** the home directory for websphere */
+ private File websphereHome;
+
+ /**
+ * Get the classpath to the websphere classpaths.
+ * @return the websphere classpath.
+ */
+ public Path createWASClasspath() {
+ if (wasClasspath == null) {
+ wasClasspath = new Path(getTask().getProject());
+ }
+ return wasClasspath.createPath();
+ }
+
+
+ /**
+ * Set the websphere classpath.
+ * @param wasClasspath the websphere classpath.
+ */
+ public void setWASClasspath(Path wasClasspath) {
+ this.wasClasspath = wasClasspath;
+ }
+
+
+ /** Sets the DB Vendor for the Entity Bean mapping ; optional.
+ * <p>
+ * Valid options can be obtained by running the following command:
+ * <code>
+ * &lt;WAS_HOME&gt;/bin/EJBDeploy.[sh/bat] -help
+ * </code>
+ * </p>
+ * <p>
+ * This is also used to determine the name of the Map.mapxmi and
+ * Schema.dbxmi files, for example Account-DB2UDB_V81-Map.mapxmi
+ * and Account-DB2UDB_V81-Schema.dbxmi.
+ * </p>
+ *
+ * @param dbvendor database vendor type
+ */
+ public void setDbvendor(String dbvendor) {
+ this.dbVendor = dbvendor;
+ }
+
+
+ /**
+ * Sets the name of the Database to create; optional.
+ *
+ * @param dbName name of the database
+ */
+ public void setDbname(String dbName) {
+ this.dbName = dbName;
+ }
+
+
+ /**
+ * Sets the name of the schema to create; optional.
+ *
+ * @param dbSchema name of the schema
+ */
+ public void setDbschema(String dbSchema) {
+ this.dbSchema = dbSchema;
+ }
+
+
+ /**
+ * Flag, default false, to only generate the deployment
+ * code, do not run RMIC or Javac
+ *
+ * @param codegen option
+ */
+ public void setCodegen(boolean codegen) {
+ this.codegen = codegen;
+ }
+
+
+ /**
+ * Flag, default true, to only output error messages.
+ *
+ * @param quiet option
+ */
+ public void setQuiet(boolean quiet) {
+ this.quiet = quiet;
+ }
+
+
+ /**
+ * Flag to disable the validation steps; optional, default false.
+ *
+ * @param novalidate option
+ */
+ public void setNovalidate(boolean novalidate) {
+ this.novalidate = novalidate;
+ }
+
+
+ /**
+ * Flag to disable warning and informational messages; optional, default false.
+ *
+ * @param nowarn option
+ */
+ public void setNowarn(boolean nowarn) {
+ this.nowarn = nowarn;
+ }
+
+
+ /**
+ * Flag to disable informational messages; optional, default false.
+ *
+ * @param noinform if true disables informational messages
+ */
+ public void setNoinform(boolean noinform) {
+ this.noinform = noinform;
+ }
+
+
+ /**
+ * Flag to enable internal tracing when set, optional, default false.
+ *
+ * @param trace a <code>boolean</code> value.
+ */
+ public void setTrace(boolean trace) {
+ this.trace = trace;
+ }
+
+ /**
+ * Set the rmic options.
+ *
+ * @param options the options to use.
+ */
+ public void setRmicoptions(String options) {
+ this.rmicOptions = options;
+ }
+
+ /**
+ * Flag to use the WebSphere 3.5 compatible mapping rules ; optional, default false.
+ *
+ * @param attr a <code>boolean</code> value.
+ */
+ public void setUse35(boolean attr) {
+ use35MappingRules = attr;
+ }
+
+
+ /**
+ * Set the rebuild flag to false to only update changes in the jar rather
+ * than rerunning ejbdeploy; optional, default true.
+ * @param rebuild a <code>boolean</code> value.
+ */
+ public void setRebuild(boolean rebuild) {
+ this.alwaysRebuild = rebuild;
+ }
+
+
+ /**
+ * String value appended to the basename of the deployment
+ * descriptor to create the filename of the WebLogic EJB
+ * jar file. Optional, default '.jar'.
+ * @param inString the string to use as the suffix.
+ */
+ public void setSuffix(String inString) {
+ this.jarSuffix = inString;
+ }
+
+
+ /**
+ * This controls whether the generic file used as input to
+ * ejbdeploy is retained; optional, default false.
+ * @param inValue either 'true' or 'false'.
+ */
+ public void setKeepgeneric(boolean inValue) {
+ this.keepGeneric = inValue;
+ }
+
+
+ /**
+ * Decide, whether ejbdeploy should be called or not;
+ * optional, default true.
+ *
+ * @param ejbdeploy a <code>boolean</code> value.
+ */
+ public void setEjbdeploy(boolean ejbdeploy) {
+ this.ejbdeploy = ejbdeploy;
+ }
+
+
+ /**
+ * Setter used to store the location of the Sun's Generic EJB DTD. This
+ * can be a file on the system or a resource on the classpath.
+ *
+ * @param inString the string to use as the DTD location.
+ */
+ public void setEJBdtd(String inString) {
+ this.ejb11DTD = inString;
+ }
+
+
+ /**
+ * Set the value of the oldCMP scheme. This is an antonym for newCMP
+ * @ant.attribute ignore="true"
+ * @param oldCMP a <code>boolean</code> value.
+ */
+ public void setOldCMP(boolean oldCMP) {
+ this.newCMP = !oldCMP;
+ }
+
+
+ /**
+ * Set the value of the newCMP scheme. The old CMP scheme locates the
+ * websphere CMP descriptor based on the naming convention where the
+ * websphere CMP file is expected to be named with the bean name as the
+ * prefix. Under this scheme the name of the CMP descriptor does not match
+ * the name actually used in the main websphere EJB descriptor. Also,
+ * descriptors which contain multiple CMP references could not be used.
+ * @param newCMP a <code>boolean</code> value.
+ */
+ public void setNewCMP(boolean newCMP) {
+ this.newCMP = newCMP;
+ }
+
+
+ /**
+ * The directory, where ejbdeploy will write temporary files;
+ * optional, defaults to '_ejbdeploy_temp'.
+ * @param tempdir the directory name to use.
+ */
+ public void setTempdir(String tempdir) {
+ this.tempdir = tempdir;
+ }
+
+
+ /** {@inheritDoc}. */
+ protected DescriptorHandler getDescriptorHandler(File srcDir) {
+ DescriptorHandler handler = new DescriptorHandler(getTask(), srcDir);
+ // register all the DTDs, both the ones that are known and
+ // any supplied by the user
+ handler.registerDTD(PUBLICID_EJB11, ejb11DTD);
+
+ for (Iterator i = getConfig().dtdLocations.iterator(); i.hasNext();) {
+ EjbJar.DTDLocation dtdLocation = (EjbJar.DTDLocation) i.next();
+
+ handler.registerDTD(dtdLocation.getPublicId(), dtdLocation.getLocation());
+ }
+
+ return handler;
+ }
+
+
+ /**
+ * Get a description handler.
+ * @param srcDir the source directory.
+ * @return the handler.
+ */
+ protected DescriptorHandler getWebsphereDescriptorHandler(final File srcDir) {
+ DescriptorHandler handler =
+ new DescriptorHandler(getTask(), srcDir) {
+ protected void processElement() {
+ }
+ };
+
+ for (Iterator i = getConfig().dtdLocations.iterator(); i.hasNext();) {
+ EjbJar.DTDLocation dtdLocation = (EjbJar.DTDLocation) i.next();
+
+ handler.registerDTD(dtdLocation.getPublicId(), dtdLocation.getLocation());
+ }
+ return handler;
+ }
+
+
+ /**
+ * Add any vendor specific files which should be included in the EJB Jar.
+ * @param ejbFiles a hashtable entryname -> file.
+ * @param baseName a prefix to use.
+ */
+ protected void addVendorFiles(Hashtable ejbFiles, String baseName) {
+
+ String ddPrefix = (usingBaseJarName() ? "" : baseName);
+ String dbPrefix = (dbVendor == null) ? "" : dbVendor + "-";
+
+ // Get the Extensions document
+ File websphereEXT = new File(getConfig().descriptorDir, ddPrefix + WAS_EXT);
+
+ if (websphereEXT.exists()) {
+ ejbFiles.put(META_DIR + WAS_EXT,
+ websphereEXT);
+ } else {
+ log("Unable to locate websphere extensions. "
+ + "It was expected to be in "
+ + websphereEXT.getPath(), Project.MSG_VERBOSE);
+ }
+
+ File websphereBND = new File(getConfig().descriptorDir, ddPrefix + WAS_BND);
+
+ if (websphereBND.exists()) {
+ ejbFiles.put(META_DIR + WAS_BND,
+ websphereBND);
+ } else {
+ log("Unable to locate websphere bindings. "
+ + "It was expected to be in "
+ + websphereBND.getPath(), Project.MSG_VERBOSE);
+ }
+
+ if (!newCMP) {
+ log("The old method for locating CMP files has been DEPRECATED.",
+ Project.MSG_VERBOSE);
+ log("Please adjust your websphere descriptor and set "
+ + "newCMP=\"true\" to use the new CMP descriptor "
+ + "inclusion mechanism. ", Project.MSG_VERBOSE);
+ } else {
+ // We attempt to put in the MAP and Schema files of CMP beans
+ try {
+ // Add the Map file
+ File websphereMAP = new File(getConfig().descriptorDir,
+ ddPrefix + dbPrefix + WAS_CMP_MAP);
+
+ if (websphereMAP.exists()) {
+ ejbFiles.put(META_DIR + WAS_CMP_MAP,
+ websphereMAP);
+ } else {
+ log("Unable to locate the websphere Map: "
+ + websphereMAP.getPath(), Project.MSG_VERBOSE);
+ }
+
+ File websphereSchema = new File(getConfig().descriptorDir,
+ ddPrefix + dbPrefix + WAS_CMP_SCHEMA);
+
+ if (websphereSchema.exists()) {
+ ejbFiles.put(META_DIR + SCHEMA_DIR + WAS_CMP_SCHEMA,
+ websphereSchema);
+ } else {
+ log("Unable to locate the websphere Schema: "
+ + websphereSchema.getPath(), Project.MSG_VERBOSE);
+ }
+ // Theres nothing else to see here...keep moving sonny
+ } catch (Exception e) {
+ String msg = "Exception while adding Vendor specific files: "
+ + e.toString();
+
+ throw new BuildException(msg, e);
+ }
+ }
+ }
+
+
+ /**
+ * Get the vendor specific name of the Jar that will be output. The
+ * modification date of this jar will be checked against the dependent
+ * bean classes.
+ */
+ File getVendorOutputJarFile(String baseName) {
+ return new File(getDestDir(), baseName + jarSuffix);
+ }
+
+
+ /**
+ * Gets the options for the EJB Deploy operation
+ *
+ * @return String
+ */
+ protected String getOptions() {
+ // Set the options
+ StringBuffer options = new StringBuffer();
+
+ if (dbVendor != null) {
+ options.append(" -dbvendor ").append(dbVendor);
+ }
+ if (dbName != null) {
+ options.append(" -dbname \"").append(dbName).append("\"");
+ }
+
+ if (dbSchema != null) {
+ options.append(" -dbschema \"").append(dbSchema).append("\"");
+ }
+
+ if (codegen) {
+ options.append(" -codegen");
+ }
+
+ if (quiet) {
+ options.append(" -quiet");
+ }
+
+ if (novalidate) {
+ options.append(" -novalidate");
+ }
+
+ if (nowarn) {
+ options.append(" -nowarn");
+ }
+
+ if (noinform) {
+ options.append(" -noinform");
+ }
+
+ if (trace) {
+ options.append(" -trace");
+ }
+
+ if (use35MappingRules) {
+ options.append(" -35");
+ }
+
+ if (rmicOptions != null) {
+ options.append(" -rmic \"").append(rmicOptions).append("\"");
+ }
+
+ return options.toString();
+ }
+
+
+ /**
+ * Helper method invoked by execute() for each websphere jar to be built.
+ * Encapsulates the logic of constructing a java task for calling
+ * websphere.ejbdeploy and executing it.
+ *
+ * @param sourceJar java.io.File representing the source (EJB1.1) jarfile.
+ * @param destJar java.io.File representing the destination, websphere
+ * jarfile.
+ */
+ private void buildWebsphereJar(File sourceJar, File destJar) {
+ try {
+ if (ejbdeploy) {
+ Java javaTask = new Java(getTask());
+ // Set the JvmArgs
+ javaTask.createJvmarg().setValue("-Xms64m");
+ javaTask.createJvmarg().setValue("-Xmx128m");
+
+ // Set the Environment variable
+ Environment.Variable var = new Environment.Variable();
+
+ var.setKey("websphere.lib.dir");
+ File libdir = new File(websphereHome, "lib");
+ var.setValue(libdir.getAbsolutePath());
+ javaTask.addSysproperty(var);
+
+ // Set the working directory
+ javaTask.setDir(websphereHome);
+
+ // Set the Java class name
+ javaTask.setTaskName("ejbdeploy");
+ javaTask.setClassname("com.ibm.etools.ejbdeploy.EJBDeploy");
+
+ javaTask.createArg().setValue(sourceJar.getPath());
+ javaTask.createArg().setValue(tempdir);
+ javaTask.createArg().setValue(destJar.getPath());
+ javaTask.createArg().setLine(getOptions());
+ if (getCombinedClasspath() != null
+ && getCombinedClasspath().toString().length() > 0) {
+ javaTask.createArg().setValue("-cp");
+ javaTask.createArg().setValue(getCombinedClasspath().toString());
+ }
+
+ Path classpath = wasClasspath;
+
+ if (classpath == null) {
+ classpath = getCombinedClasspath();
+ }
+
+ javaTask.setFork(true);
+ if (classpath != null) {
+ javaTask.setClasspath(classpath);
+ }
+
+ log("Calling websphere.ejbdeploy for " + sourceJar.toString(),
+ Project.MSG_VERBOSE);
+
+ javaTask.execute();
+ }
+ } catch (Exception e) {
+ // Have to catch this because of the semantics of calling main()
+ String msg = "Exception while calling ejbdeploy. Details: " + e.toString();
+
+ throw new BuildException(msg, e);
+ }
+ }
+
+ /** {@inheritDoc}. */
+ protected void writeJar(String baseName, File jarFile, Hashtable files, String publicId)
+ throws BuildException {
+ if (ejbdeploy) {
+ // create the -generic.jar, if required
+ File genericJarFile = super.getVendorOutputJarFile(baseName);
+
+ super.writeJar(baseName, genericJarFile, files, publicId);
+
+ // create the output .jar, if required
+ if (alwaysRebuild || isRebuildRequired(genericJarFile, jarFile)) {
+ buildWebsphereJar(genericJarFile, jarFile);
+ }
+ if (!keepGeneric) {
+ log("deleting generic jar " + genericJarFile.toString(),
+ Project.MSG_VERBOSE);
+ genericJarFile.delete();
+ }
+ } else {
+ // create the "undeployed" output .jar, if required
+ super.writeJar(baseName, jarFile, files, publicId);
+ }
+ }
+
+
+ /**
+ * Called to validate that the tool parameters have been configured.
+ * @throws BuildException if there is an error.
+ */
+ public void validateConfigured() throws BuildException {
+ super.validateConfigured();
+ if (ejbdeploy) {
+ String home = getTask().getProject().getProperty("websphere.home");
+ if (home == null) {
+ throw new BuildException("The 'websphere.home' property must "
+ + "be set when 'ejbdeploy=true'");
+ }
+ websphereHome = getTask().getProject().resolveFile(home);
+ }
+ }
+
+
+ /**
+ * Helper method to check to see if a websphere EBJ1.1 jar needs to be
+ * rebuilt using ejbdeploy. Called from writeJar it sees if the "Bean"
+ * classes are the only thing that needs to be updated and either updates
+ * the Jar with the Bean classfile or returns true, saying that the whole
+ * websphere jar needs to be regened with ejbdeploy. This allows faster
+ * build times for working developers. <p>
+ *
+ * The way websphere ejbdeploy works is it creates wrappers for the
+ * publicly defined methods as they are exposed in the remote interface.
+ * If the actual bean changes without changing the the method signatures
+ * then only the bean classfile needs to be updated and the rest of the
+ * websphere jar file can remain the same. If the Interfaces, ie. the
+ * method signatures change or if the xml deployment descriptors changed,
+ * the whole jar needs to be rebuilt with ejbdeploy. This is not strictly
+ * true for the xml files. If the JNDI name changes then the jar doesn't
+ * have to be rebuild, but if the resources references change then it
+ * does. At this point the websphere jar gets rebuilt if the xml files
+ * change at all.
+ *
+ * @param genericJarFile java.io.File The generic jar file.
+ * @param websphereJarFile java.io.File The websphere jar file to check to
+ * see if it needs to be rebuilt.
+ * @return true if a rebuild is required.
+ */
+ // CheckStyle:MethodLength OFF - this will no be fixed
+ protected boolean isRebuildRequired(File genericJarFile, File websphereJarFile) {
+ boolean rebuild = false;
+
+ JarFile genericJar = null;
+ JarFile wasJar = null;
+ File newwasJarFile = null;
+ JarOutputStream newJarStream = null;
+ ClassLoader genericLoader = null;
+
+ try {
+ log("Checking if websphere Jar needs to be rebuilt for jar "
+ + websphereJarFile.getName(), Project.MSG_VERBOSE);
+ // Only go forward if the generic and the websphere file both exist
+ if (genericJarFile.exists() && genericJarFile.isFile()
+ && websphereJarFile.exists() && websphereJarFile.isFile()) {
+ //open jar files
+ genericJar = new JarFile(genericJarFile);
+ wasJar = new JarFile(websphereJarFile);
+
+ Hashtable genericEntries = new Hashtable();
+ Hashtable wasEntries = new Hashtable();
+ Hashtable replaceEntries = new Hashtable();
+
+ //get the list of generic jar entries
+ for (Enumeration e = genericJar.entries(); e.hasMoreElements();) {
+ JarEntry je = (JarEntry) e.nextElement();
+
+ genericEntries.put(je.getName().replace('\\', '/'), je);
+ }
+ //get the list of websphere jar entries
+ for (Enumeration e = wasJar.entries(); e.hasMoreElements();) {
+ JarEntry je = (JarEntry) e.nextElement();
+
+ wasEntries.put(je.getName(), je);
+ }
+
+ //Cycle Through generic and make sure its in websphere
+ genericLoader = getClassLoaderFromJar(genericJarFile);
+
+ for (Enumeration e = genericEntries.keys(); e.hasMoreElements();) {
+ String filepath = (String) e.nextElement();
+
+ if (wasEntries.containsKey(filepath)) {
+ // File name/path match
+ // Check files see if same
+ JarEntry genericEntry = (JarEntry) genericEntries.get(filepath);
+ JarEntry wasEntry = (JarEntry) wasEntries.get(filepath);
+
+ if ((genericEntry.getCrc() != wasEntry.getCrc())
+ || (genericEntry.getSize() != wasEntry.getSize())) {
+
+ if (genericEntry.getName().endsWith(".class")) {
+ //File are different see if its an object or an interface
+ String classname
+ = genericEntry.getName().replace(File.separatorChar, '.');
+
+ classname = classname.substring(0, classname.lastIndexOf(".class"));
+
+ Class genclass = genericLoader.loadClass(classname);
+
+ if (genclass.isInterface()) {
+ //Interface changed rebuild jar.
+ log("Interface " + genclass.getName()
+ + " has changed", Project.MSG_VERBOSE);
+ rebuild = true;
+ break;
+ } else {
+ //Object class Changed update it.
+ replaceEntries.put(filepath, genericEntry);
+ }
+ } else {
+ // is it the manifest. If so ignore it
+ if (!genericEntry.getName().equals("META-INF/MANIFEST.MF")) {
+ //File other then class changed rebuild
+ log("Non class file " + genericEntry.getName()
+ + " has changed", Project.MSG_VERBOSE);
+ rebuild = true;
+ }
+ break;
+ }
+ }
+ } else {
+ // a file doesn't exist rebuild
+
+ log("File " + filepath + " not present in websphere jar",
+ Project.MSG_VERBOSE);
+ rebuild = true;
+ break;
+ }
+ }
+
+ if (!rebuild) {
+ log("No rebuild needed - updating jar", Project.MSG_VERBOSE);
+ newwasJarFile = new File(websphereJarFile.getAbsolutePath() + ".temp");
+ if (newwasJarFile.exists()) {
+ newwasJarFile.delete();
+ }
+
+ newJarStream = new JarOutputStream(new FileOutputStream(newwasJarFile));
+ newJarStream.setLevel(0);
+
+ //Copy files from old websphere jar
+ for (Enumeration e = wasEntries.elements(); e.hasMoreElements();) {
+ byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
+ int bytesRead;
+ InputStream is;
+ JarEntry je = (JarEntry) e.nextElement();
+
+ if (je.getCompressedSize() == -1
+ || je.getCompressedSize() == je.getSize()) {
+ newJarStream.setLevel(0);
+ } else {
+ newJarStream.setLevel(JAR_COMPRESS_LEVEL);
+ }
+
+ // Update with changed Bean class
+ if (replaceEntries.containsKey(je.getName())) {
+ log("Updating Bean class from generic Jar " + je.getName(),
+ Project.MSG_VERBOSE);
+ // Use the entry from the generic jar
+ je = (JarEntry) replaceEntries.get(je.getName());
+ is = genericJar.getInputStream(je);
+ } else {
+ //use fle from original websphere jar
+
+ is = wasJar.getInputStream(je);
+ }
+ newJarStream.putNextEntry(new JarEntry(je.getName()));
+
+ while ((bytesRead = is.read(buffer)) != -1) {
+ newJarStream.write(buffer, 0, bytesRead);
+ }
+ is.close();
+ }
+ } else {
+ log("websphere Jar rebuild needed due to changed "
+ + "interface or XML", Project.MSG_VERBOSE);
+ }
+ } else {
+ rebuild = true;
+ }
+ } catch (ClassNotFoundException cnfe) {
+ String cnfmsg = "ClassNotFoundException while processing ejb-jar file"
+ + ". Details: "
+ + cnfe.getMessage();
+
+ throw new BuildException(cnfmsg, cnfe);
+ } catch (IOException ioe) {
+ String msg = "IOException while processing ejb-jar file "
+ + ". Details: "
+ + ioe.getMessage();
+
+ throw new BuildException(msg, ioe);
+ } finally {
+ // need to close files and perhaps rename output
+ if (genericJar != null) {
+ try {
+ genericJar.close();
+ } catch (IOException closeException) {
+ // Ignore
+ }
+ }
+
+ if (wasJar != null) {
+ try {
+ wasJar.close();
+ } catch (IOException closeException) {
+ // Ignore
+ }
+ }
+
+ if (newJarStream != null) {
+ try {
+ newJarStream.close();
+ } catch (IOException closeException) {
+ // Ignore
+ }
+
+ try {
+ FILE_UTILS.rename(newwasJarFile, websphereJarFile);
+ } catch (IOException renameException) {
+ log(renameException.getMessage(), Project.MSG_WARN);
+ rebuild = true;
+ }
+ }
+ if (genericLoader != null
+ && genericLoader instanceof AntClassLoader) {
+ AntClassLoader loader = (AntClassLoader) genericLoader;
+ loader.cleanup();
+ }
+ }
+
+ return rebuild;
+ }
+
+
+ /**
+ * Helper method invoked by isRebuildRequired to get a ClassLoader for a
+ * Jar File passed to it.
+ *
+ * @param classjar java.io.File representing jar file to get classes from.
+ * @return a classloader for the jar file.
+ * @throws IOException if there is an error.
+ */
+ protected ClassLoader getClassLoaderFromJar(File classjar) throws IOException {
+ Path lookupPath = new Path(getTask().getProject());
+
+ lookupPath.setLocation(classjar);
+
+ Path classpath = getCombinedClasspath();
+
+ if (classpath != null) {
+ lookupPath.append(classpath);
+ }
+
+ return getTask().getProject().createClassLoader(lookupPath);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/extension/Compatability.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/extension/Compatability.java
new file mode 100644
index 00000000..2c06daf1
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/extension/Compatability.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.extension;
+
+/**
+ * Enum used in (@link Extension) to indicate the compatibility
+ * of one extension to another. See (@link Extension) for instances
+ * of object.
+ *
+ * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
+ * This file is from excalibur.extension package. Dont edit this file
+ * directly as there is no unit tests to make sure it is operational
+ * in ant. Edit file in excalibur and run tests there before changing
+ * ants file.
+ * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
+ *
+ * @see Extension
+ */
+public final class Compatability {
+ /**
+ * A string representation of compatibility level.
+ */
+ private final String name;
+
+ /**
+ * Create a compatibility enum with specified name.
+ *
+ * @param name the name of compatibility level
+ */
+ Compatability(final String name) {
+ this.name = name;
+ }
+
+ /**
+ * Return name of compatibility level.
+ *
+ * @return the name of compatibility level
+ */
+ public String toString() {
+ return name;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/extension/Compatibility.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/extension/Compatibility.java
new file mode 100644
index 00000000..bb28cd6b
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/extension/Compatibility.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.extension;
+
+/**
+ * Enum used in (@link Extension) to indicate the compatibility
+ * of one extension to another. See (@link Extension) for instances
+ * of object.
+ *
+ * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
+ * This file is from excalibur.extension package. Dont edit this file
+ * directly as there is no unit tests to make sure it is operational
+ * in ant. Edit file in excalibur and run tests there before changing
+ * ants file.
+ * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
+ *
+ * @see Extension
+ */
+public final class Compatibility {
+ /**
+ * A string representation of compatibility level.
+ */
+ private final String name;
+
+ /**
+ * Create a compatibility enum with specified name.
+ *
+ * @param name the name of compatibility level
+ */
+ Compatibility(final String name) {
+ this.name = name;
+ }
+
+ /**
+ * Return name of compatibility level.
+ *
+ * @return the name of compatibility level
+ */
+ public String toString() {
+ return name;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/extension/DeweyDecimal.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/extension/DeweyDecimal.java
new file mode 100644
index 00000000..2edc2a78
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/extension/DeweyDecimal.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.extension;
+
+
+/**
+ * Utility class to contain version numbers in "Dewey Decimal"
+ * syntax. Numbers in the "Dewey Decimal" syntax consist of positive
+ * decimal integers separated by periods ".". For example, "2.0" or
+ * "1.2.3.4.5.6.7". This allows an extensible number to be used to
+ * represent major, minor, micro, etc versions. The version number
+ * must begin with a number.
+ *
+ * Original Implementation moved to org.apache.tools.ant.util.DeweyDecimal
+ * @deprecated use org.apache.tools.ant.util.DeweyDecimal instead.
+ * Deprecated since ant 1.8
+ */
+public final class DeweyDecimal extends org.apache.tools.ant.util.DeweyDecimal {
+
+ /**
+ * Construct a DeweyDecimal from an array of integer components.
+ *
+ * @param components an array of integer components.
+ */
+ public DeweyDecimal(final int[] components) {
+ super(components);
+ }
+
+ /**
+ * Construct a DeweyDecimal from string in DeweyDecimal format.
+ *
+ * @param string the string in dewey decimal format
+ * @exception NumberFormatException if string is malformed
+ */
+ public DeweyDecimal(final String string)
+ throws NumberFormatException {
+ super(string);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/extension/Extension.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/extension/Extension.java
new file mode 100644
index 00000000..d13d2f4e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/extension/Extension.java
@@ -0,0 +1,690 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.extension;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.StringTokenizer;
+import java.util.jar.Attributes;
+import java.util.jar.Manifest;
+
+import org.apache.tools.ant.util.DeweyDecimal;
+import org.apache.tools.ant.util.StringUtils;
+
+/**
+ * <p>Utility class that represents either an available "Optional Package"
+ * (formerly known as "Standard Extension") as described in the manifest
+ * of a JAR file, or the requirement for such an optional package.</p>
+ *
+ * <p>For more information about optional packages, see the document
+ * <em>Optional Package Versioning</em> in the documentation bundle for your
+ * Java2 Standard Edition package, in file
+ * <code>guide/extensions/versioning.html</code>.</p>
+ *
+ */
+public final class Extension {
+ /**
+ * Manifest Attribute Name object for EXTENSION_LIST.
+ */
+ public static final Attributes.Name EXTENSION_LIST
+ = new Attributes.Name("Extension-List");
+
+ /**
+ * <code>Name</code> object for <code>Optional-Extension-List</code>
+ * manifest attribute used for declaring optional dependencies on
+ * installed extensions. Note that the dependencies declared by this method
+ * are not required for the library to operate but if present will be used.
+ * It is NOT part of the official "Optional Package" specification.
+ *
+ * @see <a href="http://java.sun.com/j2se/1.3/docs/guide/extensions/spec.html#dependency">
+ * Installed extension dependency</a>
+ */
+ public static final Attributes.Name OPTIONAL_EXTENSION_LIST
+ = new Attributes.Name("Optional-Extension-List");
+
+ /**
+ * Manifest Attribute Name object for EXTENSION_NAME.
+ */
+ public static final Attributes.Name EXTENSION_NAME =
+ new Attributes.Name("Extension-Name");
+ /**
+ * Manifest Attribute Name object for SPECIFICATION_VERSION.
+ */
+ public static final Attributes.Name SPECIFICATION_VERSION
+ = Attributes.Name.SPECIFICATION_VERSION;
+
+ /**
+ * Manifest Attribute Name object for SPECIFICATION_VENDOR.
+ */
+ public static final Attributes.Name SPECIFICATION_VENDOR
+ = Attributes.Name.SPECIFICATION_VENDOR;
+
+ /**
+ * Manifest Attribute Name object for IMPLEMENTATION_VERSION.
+ */
+ public static final Attributes.Name IMPLEMENTATION_VERSION
+ = Attributes.Name.IMPLEMENTATION_VERSION;
+
+ /**
+ * Manifest Attribute Name object for IMPLEMENTATION_VENDOR.
+ */
+ public static final Attributes.Name IMPLEMENTATION_VENDOR
+ = Attributes.Name.IMPLEMENTATION_VENDOR;
+
+ /**
+ * Manifest Attribute Name object for IMPLEMENTATION_URL.
+ */
+ public static final Attributes.Name IMPLEMENTATION_URL
+ = new Attributes.Name("Implementation-URL");
+
+ /**
+ * Manifest Attribute Name object for IMPLEMENTATION_VENDOR_ID.
+ */
+ public static final Attributes.Name IMPLEMENTATION_VENDOR_ID
+ = new Attributes.Name("Implementation-Vendor-Id");
+
+ /**
+ * Enum indicating that extension is compatible with other extension.
+ */
+ public static final Compatibility COMPATIBLE
+ = new Compatibility("COMPATIBLE");
+
+ /**
+ * Enum indicating that extension requires an upgrade
+ * of specification to be compatible with other extension.
+ */
+ public static final Compatibility REQUIRE_SPECIFICATION_UPGRADE
+ = new Compatibility("REQUIRE_SPECIFICATION_UPGRADE");
+
+ /**
+ * Enum indicating that extension requires a vendor
+ * switch to be compatible with other extension.
+ */
+ public static final Compatibility REQUIRE_VENDOR_SWITCH
+ = new Compatibility("REQUIRE_VENDOR_SWITCH");
+
+ /**
+ * Enum indicating that extension requires an upgrade
+ * of implementation to be compatible with other extension.
+ */
+ public static final Compatibility REQUIRE_IMPLEMENTATION_UPGRADE
+ = new Compatibility("REQUIRE_IMPLEMENTATION_UPGRADE");
+
+ /**
+ * Enum indicating that extension is incompatible with
+ * other extension in ways other than other enums
+ * indicate). For example the other extension may have
+ * a different ID.
+ */
+ public static final Compatibility INCOMPATIBLE
+ = new Compatibility("INCOMPATIBLE");
+
+ /**
+ * The name of the optional package being made available, or required.
+ */
+ private String extensionName;
+
+ /**
+ * The version number (dotted decimal notation) of the specification
+ * to which this optional package conforms.
+ */
+ private DeweyDecimal specificationVersion;
+
+ /**
+ * The name of the company or organization that originated the
+ * specification to which this optional package conforms.
+ */
+ private String specificationVendor;
+
+ /**
+ * The unique identifier of the company that produced the optional
+ * package contained in this JAR file.
+ */
+ private String implementationVendorID;
+
+ /**
+ * The name of the company or organization that produced this
+ * implementation of this optional package.
+ */
+ private String implementationVendor;
+
+ /**
+ * The version number (dotted decimal notation) for this implementation
+ * of the optional package.
+ */
+ private DeweyDecimal implementationVersion;
+
+ /**
+ * The URL from which the most recent version of this optional package
+ * can be obtained if it is not already installed.
+ */
+ private String implementationURL;
+
+ /**
+ * Return an array of <code>Extension</code> objects representing optional
+ * packages that are available in the JAR file associated with the
+ * specified <code>Manifest</code>. If there are no such optional
+ * packages, a zero-length array is returned.
+ *
+ * @param manifest Manifest to be parsed
+ * @return the "available" extensions in specified manifest
+ */
+ public static Extension[] getAvailable(final Manifest manifest) {
+ if (null == manifest) {
+ return new Extension[ 0 ];
+ }
+
+ final ArrayList results = new ArrayList();
+
+ final Attributes mainAttributes = manifest.getMainAttributes();
+ if (null != mainAttributes) {
+ final Extension extension = getExtension("", mainAttributes);
+ if (null != extension) {
+ results.add(extension);
+ }
+ }
+
+ final Map entries = manifest.getEntries();
+ final Iterator keys = entries.keySet().iterator();
+ while (keys.hasNext()) {
+ final String key = (String) keys.next();
+ final Attributes attributes = (Attributes) entries.get(key);
+ final Extension extension = getExtension("", attributes);
+ if (null != extension) {
+ results.add(extension);
+ }
+ }
+
+ return (Extension[]) results.toArray(new Extension[results.size()]);
+ }
+
+ /**
+ * Return the set of <code>Extension</code> objects representing optional
+ * packages that are required by the application contained in the JAR
+ * file associated with the specified <code>Manifest</code>. If there
+ * are no such optional packages, a zero-length list is returned.
+ *
+ * @param manifest Manifest to be parsed
+ * @return the dependencies that are specified in manifest
+ */
+ public static Extension[] getRequired(final Manifest manifest) {
+ return getListed(manifest, Attributes.Name.EXTENSION_LIST);
+ }
+
+ /**
+ * Return the set of <code>Extension</code> objects representing "Optional
+ * Packages" that the application declares they will use if present. If
+ * there are no such optional packages, a zero-length list is returned.
+ *
+ * @param manifest Manifest to be parsed
+ * @return the optional dependencies that are specified in manifest
+ */
+ public static Extension[] getOptions(final Manifest manifest) {
+ return getListed(manifest, OPTIONAL_EXTENSION_LIST);
+ }
+
+ /**
+ * Add Extension to the specified manifest Attributes.
+ *
+ * @param attributes the attributes of manifest to add to
+ * @param extension the extension
+ */
+ public static void addExtension(final Extension extension,
+ final Attributes attributes) {
+ addExtension(extension, "", attributes);
+ }
+
+ /**
+ * Add Extension to the specified manifest Attributes.
+ * Use the specified prefix so that dependencies can added
+ * with a prefix such as "java3d-" etc.
+ *
+ * @param attributes the attributes of manifest to add to
+ * @param extension the extension
+ * @param prefix the name to prefix to extension
+ */
+ public static void addExtension(final Extension extension,
+ final String prefix,
+ final Attributes attributes) {
+ attributes.putValue(prefix + EXTENSION_NAME,
+ extension.getExtensionName());
+
+ final String specificationVendor = extension.getSpecificationVendor();
+ if (null != specificationVendor) {
+ attributes.putValue(prefix + SPECIFICATION_VENDOR,
+ specificationVendor);
+ }
+
+ final DeweyDecimal specificationVersion
+ = extension.getSpecificationVersion();
+ if (null != specificationVersion) {
+ attributes.putValue(prefix + SPECIFICATION_VERSION,
+ specificationVersion.toString());
+ }
+
+ final String implementationVendorID
+ = extension.getImplementationVendorID();
+ if (null != implementationVendorID) {
+ attributes.putValue(prefix + IMPLEMENTATION_VENDOR_ID,
+ implementationVendorID);
+ }
+
+ final String implementationVendor = extension.getImplementationVendor();
+ if (null != implementationVendor) {
+ attributes.putValue(prefix + IMPLEMENTATION_VENDOR,
+ implementationVendor);
+ }
+
+ final DeweyDecimal implementationVersion
+ = extension.getImplementationVersion();
+ if (null != implementationVersion) {
+ attributes.putValue(prefix + IMPLEMENTATION_VERSION,
+ implementationVersion.toString());
+ }
+
+ final String implementationURL = extension.getImplementationURL();
+ if (null != implementationURL) {
+ attributes.putValue(prefix + IMPLEMENTATION_URL,
+ implementationURL);
+ }
+ }
+
+ /**
+ * The constructor to create Extension object.
+ * Note that every component is allowed to be specified
+ * but only the extensionName is mandatory.
+ *
+ * @param extensionName the name of extension.
+ * @param specificationVersion the specification Version of extension.
+ * @param specificationVendor the specification Vendor of extension.
+ * @param implementationVersion the implementation Version of extension.
+ * @param implementationVendor the implementation Vendor of extension.
+ * @param implementationVendorId the implementation VendorId of extension.
+ * @param implementationURL the implementation URL of extension.
+ */
+ public Extension(final String extensionName,
+ final String specificationVersion,
+ final String specificationVendor,
+ final String implementationVersion,
+ final String implementationVendor,
+ final String implementationVendorId,
+ final String implementationURL) {
+ this.extensionName = extensionName;
+ this.specificationVendor = specificationVendor;
+
+ if (null != specificationVersion) {
+ try {
+ this.specificationVersion
+ = new DeweyDecimal(specificationVersion);
+ } catch (final NumberFormatException nfe) {
+ final String error = "Bad specification version format '"
+ + specificationVersion + "' in '" + extensionName
+ + "'. (Reason: " + nfe + ")";
+ throw new IllegalArgumentException(error);
+ }
+ }
+
+ this.implementationURL = implementationURL;
+ this.implementationVendor = implementationVendor;
+ this.implementationVendorID = implementationVendorId;
+
+ if (null != implementationVersion) {
+ try {
+ this.implementationVersion
+ = new DeweyDecimal(implementationVersion);
+ } catch (final NumberFormatException nfe) {
+ final String error = "Bad implementation version format '"
+ + implementationVersion + "' in '" + extensionName
+ + "'. (Reason: " + nfe + ")";
+ throw new IllegalArgumentException(error);
+ }
+ }
+
+ if (null == this.extensionName) {
+ throw new NullPointerException("extensionName property is null");
+ }
+ }
+
+ /**
+ * Get the name of the extension.
+ *
+ * @return the name of the extension
+ */
+ public String getExtensionName() {
+ return extensionName;
+ }
+
+ /**
+ * Get the vendor of the extensions specification.
+ *
+ * @return the vendor of the extensions specification.
+ */
+ public String getSpecificationVendor() {
+ return specificationVendor;
+ }
+
+ /**
+ * Get the version of the extensions specification.
+ *
+ * @return the version of the extensions specification.
+ */
+ public DeweyDecimal getSpecificationVersion() {
+ return specificationVersion;
+ }
+
+ /**
+ * Get the url of the extensions implementation.
+ *
+ * @return the url of the extensions implementation.
+ */
+ public String getImplementationURL() {
+ return implementationURL;
+ }
+
+ /**
+ * Get the vendor of the extensions implementation.
+ *
+ * @return the vendor of the extensions implementation.
+ */
+ public String getImplementationVendor() {
+ return implementationVendor;
+ }
+
+ /**
+ * Get the vendorID of the extensions implementation.
+ *
+ * @return the vendorID of the extensions implementation.
+ */
+ public String getImplementationVendorID() {
+ return implementationVendorID;
+ }
+
+ /**
+ * Get the version of the extensions implementation.
+ *
+ * @return the version of the extensions implementation.
+ */
+ public DeweyDecimal getImplementationVersion() {
+ return implementationVersion;
+ }
+
+ /**
+ * Return a Compatibility enum indicating the relationship of this
+ * <code>Extension</code> with the specified <code>Extension</code>.
+ *
+ * @param required Description of the required optional package
+ * @return the enum indicating the compatibility (or lack thereof)
+ * of specified extension
+ */
+ public Compatibility getCompatibilityWith(final Extension required) {
+ // Extension Name must match
+ if (!extensionName.equals(required.getExtensionName())) {
+ return INCOMPATIBLE;
+ }
+
+ // Available specification version must be >= required
+ final DeweyDecimal requiredSpecificationVersion
+ = required.getSpecificationVersion();
+ if (null != requiredSpecificationVersion) {
+ if (null == specificationVersion
+ || !isCompatible(specificationVersion, requiredSpecificationVersion)) {
+ return REQUIRE_SPECIFICATION_UPGRADE;
+ }
+ }
+
+ // Implementation Vendor ID must match
+ final String requiredImplementationVendorID
+ = required.getImplementationVendorID();
+ if (null != requiredImplementationVendorID) {
+ if (null == implementationVendorID
+ || !implementationVendorID.equals(requiredImplementationVendorID)) {
+ return REQUIRE_VENDOR_SWITCH;
+ }
+ }
+
+ // Implementation version must be >= required
+ final DeweyDecimal requiredImplementationVersion
+ = required.getImplementationVersion();
+ if (null != requiredImplementationVersion) {
+ if (null == implementationVersion
+ || !isCompatible(implementationVersion, requiredImplementationVersion)) {
+ return REQUIRE_IMPLEMENTATION_UPGRADE;
+ }
+ }
+
+ // This available optional package satisfies the requirements
+ return COMPATIBLE;
+ }
+
+ /**
+ * Return <code>true</code> if the specified <code>Extension</code>
+ * (which represents an optional package required by an application)
+ * is satisfied by this <code>Extension</code> (which represents an
+ * optional package that is already installed. Otherwise, return
+ * <code>false</code>.
+ *
+ * @param required Description of the required optional package
+ * @return true if the specified extension is compatible with this extension
+ */
+ public boolean isCompatibleWith(final Extension required) {
+ return (COMPATIBLE == getCompatibilityWith(required));
+ }
+
+ /**
+ * Return a String representation of this object.
+ *
+ * @return string representation of object.
+ */
+ public String toString() {
+ final String brace = ": ";
+
+ final StringBuffer sb = new StringBuffer(EXTENSION_NAME.toString());
+ sb.append(brace);
+ sb.append(extensionName);
+ sb.append(StringUtils.LINE_SEP);
+
+ if (null != specificationVersion) {
+ sb.append(SPECIFICATION_VERSION);
+ sb.append(brace);
+ sb.append(specificationVersion);
+ sb.append(StringUtils.LINE_SEP);
+ }
+
+ if (null != specificationVendor) {
+ sb.append(SPECIFICATION_VENDOR);
+ sb.append(brace);
+ sb.append(specificationVendor);
+ sb.append(StringUtils.LINE_SEP);
+ }
+
+ if (null != implementationVersion) {
+ sb.append(IMPLEMENTATION_VERSION);
+ sb.append(brace);
+ sb.append(implementationVersion);
+ sb.append(StringUtils.LINE_SEP);
+ }
+
+ if (null != implementationVendorID) {
+ sb.append(IMPLEMENTATION_VENDOR_ID);
+ sb.append(brace);
+ sb.append(implementationVendorID);
+ sb.append(StringUtils.LINE_SEP);
+ }
+
+ if (null != implementationVendor) {
+ sb.append(IMPLEMENTATION_VENDOR);
+ sb.append(brace);
+ sb.append(implementationVendor);
+ sb.append(StringUtils.LINE_SEP);
+ }
+
+ if (null != implementationURL) {
+ sb.append(IMPLEMENTATION_URL);
+ sb.append(brace);
+ sb.append(implementationURL);
+ sb.append(StringUtils.LINE_SEP);
+ }
+
+ return sb.toString();
+ }
+
+ /**
+ * Return <code>true</code> if the first version number is greater than
+ * or equal to the second; otherwise return <code>false</code>.
+ *
+ * @param first First version number (dotted decimal)
+ * @param second Second version number (dotted decimal)
+ */
+ private boolean isCompatible(final DeweyDecimal first,
+ final DeweyDecimal second) {
+ return first.isGreaterThanOrEqual(second);
+ }
+
+ /**
+ * Retrieve all the extensions listed under a particular key
+ * (Usually EXTENSION_LIST or OPTIONAL_EXTENSION_LIST).
+ *
+ * @param manifest the manifest to extract extensions from
+ * @param listKey the key used to get list (Usually
+ * EXTENSION_LIST or OPTIONAL_EXTENSION_LIST)
+ * @return the list of listed extensions
+ */
+ private static Extension[] getListed(final Manifest manifest,
+ final Attributes.Name listKey) {
+ final ArrayList results = new ArrayList();
+ final Attributes mainAttributes = manifest.getMainAttributes();
+
+ if (null != mainAttributes) {
+ getExtension(mainAttributes, results, listKey);
+ }
+
+ final Map entries = manifest.getEntries();
+ final Iterator keys = entries.keySet().iterator();
+ while (keys.hasNext()) {
+ final String key = (String) keys.next();
+ final Attributes attributes = (Attributes) entries.get(key);
+ getExtension(attributes, results, listKey);
+ }
+
+ return (Extension[]) results.toArray(new Extension[results.size()]);
+ }
+
+ /**
+ * Add required optional packages defined in the specified
+ * attributes entry, if any.
+ *
+ * @param attributes Attributes to be parsed
+ * @param required list to add required optional packages to
+ * @param listKey the key to use to lookup list, usually EXTENSION_LIST
+ * or OPTIONAL_EXTENSION_LIST
+ */
+ private static void getExtension(final Attributes attributes,
+ final ArrayList required,
+ final Attributes.Name listKey) {
+ final String names = attributes.getValue(listKey);
+ if (null == names) {
+ return;
+ }
+
+ final String[] extensions = split(names, " ");
+ for (int i = 0; i < extensions.length; i++) {
+ final String prefix = extensions[ i ] + "-";
+ final Extension extension = getExtension(prefix, attributes);
+
+ if (null != extension) {
+ required.add(extension);
+ }
+ }
+ }
+
+ /**
+ * Splits the string on every token into an array of strings.
+ *
+ * @param string the string
+ * @param onToken the token
+ * @return the resultant array
+ */
+ private static String[] split(final String string,
+ final String onToken) {
+ final StringTokenizer tokenizer = new StringTokenizer(string, onToken);
+ final String[] result = new String[ tokenizer.countTokens() ];
+
+ for (int i = 0; i < result.length; i++) {
+ result[ i ] = tokenizer.nextToken();
+ }
+
+ return result;
+ }
+
+ /**
+ * Extract an Extension from Attributes.
+ * Prefix indicates the prefix checked for each string.
+ * Usually the prefix is <em>"&lt;extension&gt;-"</em> if looking for a
+ * <b>Required</b> extension. If you are looking for an
+ * <b>Available</b> extension
+ * then the prefix is <em>""</em>.
+ *
+ * @param prefix the prefix for each attribute name
+ * @param attributes Attributes to searched
+ * @return the new Extension object, or null
+ */
+ private static Extension getExtension(final String prefix,
+ final Attributes attributes) {
+ //WARNING: We trim the values of all the attributes because
+ //Some extension declarations are badly defined (ie have spaces
+ //after version or vendorID)
+ final String nameKey = prefix + EXTENSION_NAME;
+ final String name = getTrimmedString(attributes.getValue(nameKey));
+ if (null == name) {
+ return null;
+ }
+
+ final String specVendorKey = prefix + SPECIFICATION_VENDOR;
+ final String specVendor
+ = getTrimmedString(attributes.getValue(specVendorKey));
+ final String specVersionKey = prefix + SPECIFICATION_VERSION;
+ final String specVersion
+ = getTrimmedString(attributes.getValue(specVersionKey));
+
+ final String impVersionKey = prefix + IMPLEMENTATION_VERSION;
+ final String impVersion
+ = getTrimmedString(attributes.getValue(impVersionKey));
+ final String impVendorKey = prefix + IMPLEMENTATION_VENDOR;
+ final String impVendor
+ = getTrimmedString(attributes.getValue(impVendorKey));
+ final String impVendorIDKey = prefix + IMPLEMENTATION_VENDOR_ID;
+ final String impVendorId
+ = getTrimmedString(attributes.getValue(impVendorIDKey));
+ final String impURLKey = prefix + IMPLEMENTATION_URL;
+ final String impURL = getTrimmedString(attributes.getValue(impURLKey));
+
+ return new Extension(name, specVersion, specVendor, impVersion,
+ impVendor, impVendorId, impURL);
+ }
+
+ /**
+ * Trim the supplied string if the string is non-null
+ *
+ * @param value the string to trim or null
+ * @return the trimmed string or null
+ */
+ private static String getTrimmedString(final String value) {
+ return null == value ? null : value.trim();
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/extension/ExtensionAdapter.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/extension/ExtensionAdapter.java
new file mode 100644
index 00000000..b3cfddc2
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/extension/ExtensionAdapter.java
@@ -0,0 +1,215 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.extension;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.types.DataType;
+import org.apache.tools.ant.types.Reference;
+import org.apache.tools.ant.util.DeweyDecimal;
+
+/**
+ * Simple class that represents an Extension and conforms to Ants
+ * patterns.
+ *
+ * @ant.datatype name="extension"
+ */
+public class ExtensionAdapter extends DataType {
+ /**
+ * The name of the optional package being made available, or required.
+ */
+ private String extensionName;
+
+ /**
+ * The version number (dotted decimal notation) of the specification
+ * to which this optional package conforms.
+ */
+ private DeweyDecimal specificationVersion;
+
+ /**
+ * The name of the company or organization that originated the
+ * specification to which this optional package conforms.
+ */
+ private String specificationVendor;
+
+ /**
+ * The unique identifier of the company that produced the optional
+ * package contained in this JAR file.
+ */
+ private String implementationVendorID;
+
+ /**
+ * The name of the company or organization that produced this
+ * implementation of this optional package.
+ */
+ private String implementationVendor;
+
+ /**
+ * The version number (dotted decimal notation) for this implementation
+ * of the optional package.
+ */
+ private DeweyDecimal implementationVersion;
+
+ /**
+ * The URL from which the most recent version of this optional package
+ * can be obtained if it is not already installed.
+ */
+ private String implementationURL;
+
+ /**
+ * Set the name of extension.
+ *
+ * @param extensionName the name of extension
+ */
+ public void setExtensionName(final String extensionName) {
+ verifyNotAReference();
+ this.extensionName = extensionName;
+ }
+
+ /**
+ * Set the specificationVersion of extension.
+ *
+ * @param specificationVersion the specificationVersion of extension
+ */
+ public void setSpecificationVersion(final String specificationVersion) {
+ verifyNotAReference();
+ this.specificationVersion = new DeweyDecimal(specificationVersion);
+ }
+
+ /**
+ * Set the specificationVendor of extension.
+ *
+ * @param specificationVendor the specificationVendor of extension
+ */
+ public void setSpecificationVendor(final String specificationVendor) {
+ verifyNotAReference();
+ this.specificationVendor = specificationVendor;
+ }
+
+ /**
+ * Set the implementationVendorID of extension.
+ *
+ * @param implementationVendorID the implementationVendorID of extension
+ */
+ public void setImplementationVendorId(final String implementationVendorID) {
+ verifyNotAReference();
+ this.implementationVendorID = implementationVendorID;
+ }
+
+ /**
+ * Set the implementationVendor of extension.
+ *
+ * @param implementationVendor the implementationVendor of extension
+ */
+ public void setImplementationVendor(final String implementationVendor) {
+ verifyNotAReference();
+ this.implementationVendor = implementationVendor;
+ }
+
+ /**
+ * Set the implementationVersion of extension.
+ *
+ * @param implementationVersion the implementationVersion of extension
+ */
+ public void setImplementationVersion(final String implementationVersion) {
+ verifyNotAReference();
+ this.implementationVersion = new DeweyDecimal(implementationVersion);
+ }
+
+ /**
+ * Set the implementationURL of extension.
+ *
+ * @param implementationURL the implementationURL of extension
+ */
+ public void setImplementationUrl(final String implementationURL) {
+ verifyNotAReference();
+ this.implementationURL = implementationURL;
+ }
+
+ /**
+ * Makes this instance in effect a reference to another ExtensionAdapter
+ * instance.
+ *
+ * <p>You must not set another attribute or nest elements inside
+ * this element if you make it a reference.</p>
+ *
+ * @param reference the reference to which this instance is associated
+ * @exception BuildException if this instance already has been configured.
+ */
+ public void setRefid(final Reference reference)
+ throws BuildException {
+ if (null != extensionName
+ || null != specificationVersion
+ || null != specificationVendor
+ || null != implementationVersion
+ || null != implementationVendorID
+ || null != implementationVendor
+ || null != implementationURL) {
+ throw tooManyAttributes();
+ }
+ super.setRefid(reference);
+ }
+
+ private void verifyNotAReference()
+ throws BuildException {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ }
+
+ /**
+ * Convert this adpater object into an extension object.
+ *
+ * @return the extension object
+ */
+ Extension toExtension()
+ throws BuildException {
+ if (isReference()) {
+ return ((ExtensionAdapter) getCheckedRef()).toExtension();
+ }
+ dieOnCircularReference();
+ if (null == extensionName) {
+ final String message = "Extension is missing name.";
+ throw new BuildException(message);
+ }
+
+ String specificationVersionString = null;
+ if (null != specificationVersion) {
+ specificationVersionString = specificationVersion.toString();
+ }
+ String implementationVersionString = null;
+ if (null != implementationVersion) {
+ implementationVersionString = implementationVersion.toString();
+ }
+ return new Extension(extensionName,
+ specificationVersionString,
+ specificationVendor,
+ implementationVersionString,
+ implementationVendor,
+ implementationVendorID,
+ implementationURL);
+ }
+
+ /**
+ * a debug toString method.
+ * @return the extension in a string.
+ * @see java.lang.Object#toString()
+ */
+ public String toString() {
+ return "{" + toExtension().toString() + "}";
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/extension/ExtensionResolver.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/extension/ExtensionResolver.java
new file mode 100644
index 00000000..a73282ec
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/extension/ExtensionResolver.java
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.extension;
+
+import java.io.File;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+
+/**
+ * Interface to locate a File that satisfies extension.
+ *
+ */
+public interface ExtensionResolver {
+ /**
+ * Attempt to locate File that satisfies
+ * extension via resolver.
+ *
+ * @param extension the extension
+ * @param project the Ant project instance
+ * @return the File satisfying extension, null
+ * if can not resolve extension
+ * @throws BuildException if error occurs attempting to
+ * resolve extension
+ */
+ File resolve(Extension extension, Project project)
+ throws BuildException;
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/extension/ExtensionSet.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/extension/ExtensionSet.java
new file mode 100644
index 00000000..5aba37c9
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/extension/ExtensionSet.java
@@ -0,0 +1,153 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.extension;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.Stack;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.DataType;
+import org.apache.tools.ant.types.FileSet;
+import org.apache.tools.ant.types.Reference;
+
+/**
+ * The Extension set lists a set of "Optional Packages" /
+ * "Extensions".
+ *
+ * @ant.datatype name="extension-set"
+ */
+public class ExtensionSet
+ extends DataType {
+ /**
+ * ExtensionAdapter objects representing extensions.
+ */
+ private final ArrayList extensions = new ArrayList();
+
+ /**
+ * Filesets specifying all the extensions wanted.
+ */
+ private final ArrayList extensionsFilesets = new ArrayList();
+
+ /**
+ * Adds an extension that this library requires.
+ *
+ * @param extensionAdapter an extension that this library requires.
+ */
+ public void addExtension(final ExtensionAdapter extensionAdapter) {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ setChecked(false);
+ extensions.add(extensionAdapter);
+ }
+
+ /**
+ * Adds a set of files about which extensions data will be extracted.
+ *
+ * @param fileSet a set of files about which extensions data will be extracted.
+ */
+ public void addLibfileset(final LibFileSet fileSet) {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ setChecked(false);
+ extensionsFilesets.add(fileSet);
+ }
+
+ /**
+ * Adds a set of files about which extensions data will be extracted.
+ *
+ * @param fileSet a set of files about which extensions data will be extracted.
+ */
+ public void addFileset(final FileSet fileSet) {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ setChecked(false);
+ extensionsFilesets.add(fileSet);
+ }
+
+ /**
+ * Extract a set of Extension objects from the ExtensionSet.
+ *
+ * @param proj the project instance.
+ * @return an array containing the Extensions from this set
+ * @throws BuildException if an error occurs
+ */
+ public Extension[] toExtensions(final Project proj)
+ throws BuildException {
+ if (isReference()) {
+ return ((ExtensionSet) getCheckedRef()).toExtensions(proj);
+ }
+ dieOnCircularReference();
+ final ArrayList extensionsList = ExtensionUtil.toExtensions(extensions);
+ ExtensionUtil.extractExtensions(proj, extensionsList, extensionsFilesets);
+ return (Extension[]) extensionsList.toArray(new Extension[extensionsList.size()]);
+ }
+
+ /**
+ * Makes this instance in effect a reference to another ExtensionSet
+ * instance.
+ *
+ * <p>You must not set another attribute or nest elements inside
+ * this element if you make it a reference.</p>
+ *
+ * @param reference the reference to which this instance is associated
+ * @exception BuildException if this instance already has been configured.
+ */
+ @Override
+ public void setRefid(final Reference reference)
+ throws BuildException {
+ if (!extensions.isEmpty() || !extensionsFilesets.isEmpty()) {
+ throw tooManyAttributes();
+ }
+ super.setRefid(reference);
+ }
+
+ @Override
+ protected synchronized void dieOnCircularReference(Stack stk, Project p)
+ throws BuildException {
+ if (isChecked()) {
+ return;
+ }
+ if (isReference()) {
+ super.dieOnCircularReference(stk, p);
+ } else {
+ for (Iterator i = extensions.iterator(); i.hasNext();) {
+ pushAndInvokeCircularReferenceCheck((ExtensionAdapter) i.next(),
+ stk, p);
+ }
+ for (Iterator i = extensionsFilesets.iterator(); i.hasNext();) {
+ pushAndInvokeCircularReferenceCheck((FileSet) i.next(), stk, p);
+ }
+ setChecked(true);
+ }
+ }
+
+ /**
+ * @see java.lang.Object#toString()
+ * @return the extensions in a string.
+ */
+ @Override
+ public String toString() {
+ return "ExtensionSet" + Arrays.asList(toExtensions(getProject()));
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/extension/ExtensionUtil.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/extension/ExtensionUtil.java
new file mode 100644
index 00000000..089c7894
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/extension/ExtensionUtil.java
@@ -0,0 +1,215 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.extension;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.jar.JarFile;
+import java.util.jar.Manifest;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.DirectoryScanner;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.FileSet;
+
+/**
+ * A set of useful methods relating to extensions.
+ *
+ */
+public final class ExtensionUtil {
+ /**
+ * Class is not meant to be instantiated.
+ */
+ private ExtensionUtil() {
+ //all methods static
+ }
+
+ /**
+ * Convert a list of extensionAdapter objects to extensions.
+ *
+ * @param adapters the list of ExtensionAdapterss to add to convert
+ * @throws BuildException if an error occurs
+ */
+ static ArrayList toExtensions(final List adapters)
+ throws BuildException {
+ final ArrayList results = new ArrayList();
+
+ final int size = adapters.size();
+ for (int i = 0; i < size; i++) {
+ final ExtensionAdapter adapter =
+ (ExtensionAdapter) adapters.get(i);
+ final Extension extension = adapter.toExtension();
+ results.add(extension);
+ }
+
+ return results;
+ }
+
+ /**
+ * Generate a list of extensions from a specified fileset.
+ *
+ * @param libraries the list to add extensions to
+ * @param fileset the filesets containing librarys
+ * @throws BuildException if an error occurs
+ */
+ static void extractExtensions(final Project project,
+ final List libraries,
+ final List fileset)
+ throws BuildException {
+ if (!fileset.isEmpty()) {
+ final Extension[] extensions = getExtensions(project,
+ fileset);
+ for (int i = 0; i < extensions.length; i++) {
+ libraries.add(extensions[ i ]);
+ }
+ }
+ }
+
+ /**
+ * Retrieve extensions from the specified libraries.
+ *
+ * @param libraries the filesets for libraries
+ * @return the extensions contained in libraries
+ * @throws BuildException if failing to scan libraries
+ */
+ private static Extension[] getExtensions(final Project project,
+ final List libraries)
+ throws BuildException {
+ final ArrayList extensions = new ArrayList();
+ final Iterator iterator = libraries.iterator();
+ while (iterator.hasNext()) {
+ final FileSet fileSet = (FileSet) iterator.next();
+
+ boolean includeImpl = true;
+ boolean includeURL = true;
+
+ if (fileSet instanceof LibFileSet) {
+ LibFileSet libFileSet = (LibFileSet) fileSet;
+ includeImpl = libFileSet.isIncludeImpl();
+ includeURL = libFileSet.isIncludeURL();
+ }
+
+ final DirectoryScanner scanner = fileSet.getDirectoryScanner(project);
+ final File basedir = scanner.getBasedir();
+ final String[] files = scanner.getIncludedFiles();
+ for (int i = 0; i < files.length; i++) {
+ final File file = new File(basedir, files[ i ]);
+ loadExtensions(file, extensions, includeImpl, includeURL);
+ }
+ }
+ return (Extension[]) extensions.toArray(new Extension[extensions.size()]);
+ }
+
+ /**
+ * Load list of available extensions from specified file.
+ *
+ * @param file the file
+ * @param extensionList the list to add available extensions to
+ * @throws BuildException if there is an error
+ */
+ private static void loadExtensions(final File file,
+ final List extensionList,
+ final boolean includeImpl,
+ final boolean includeURL)
+ throws BuildException {
+ try {
+ final JarFile jarFile = new JarFile(file);
+ final Extension[] extensions =
+ Extension.getAvailable(jarFile.getManifest());
+ for (int i = 0; i < extensions.length; i++) {
+ final Extension extension = extensions[ i ];
+ addExtension(extensionList, extension, includeImpl, includeURL);
+ }
+ } catch (final Exception e) {
+ throw new BuildException(e.getMessage(), e);
+ }
+ }
+
+ /**
+ * Add extension to list.
+ * If extension should not have implementation details but
+ * does strip them. If extension should not have url but does
+ * then strip it.
+ *
+ * @param extensionList the list of extensions to add to
+ * @param originalExtension the extension
+ * @param includeImpl false to exclude implementation details
+ * @param includeURL false to exclude implementation URL
+ */
+ private static void addExtension(final List extensionList,
+ final Extension originalExtension,
+ final boolean includeImpl,
+ final boolean includeURL) {
+ Extension extension = originalExtension;
+ if (!includeURL
+ && null != extension.getImplementationURL()) {
+ extension =
+ new Extension(extension.getExtensionName(),
+ extension.getSpecificationVersion().toString(),
+ extension.getSpecificationVendor(),
+ extension.getImplementationVersion().toString(),
+ extension.getImplementationVendor(),
+ extension.getImplementationVendorID(),
+ null);
+ }
+
+ final boolean hasImplAttributes =
+ null != extension.getImplementationURL()
+ || null != extension.getImplementationVersion()
+ || null != extension.getImplementationVendorID()
+ || null != extension.getImplementationVendor();
+
+ if (!includeImpl && hasImplAttributes) {
+ extension =
+ new Extension(extension.getExtensionName(),
+ extension.getSpecificationVersion().toString(),
+ extension.getSpecificationVendor(),
+ null,
+ null,
+ null,
+ extension.getImplementationURL());
+ }
+
+ extensionList.add(extension);
+ }
+
+ /**
+ * Retrieve manifest for specified file.
+ *
+ * @param file the file
+ * @return the manifest
+ * @throws BuildException if errror occurs (file doesn't exist,
+ * file not a jar, manifest doesn't exist in file)
+ */
+ static Manifest getManifest(final File file)
+ throws BuildException {
+ try {
+ final JarFile jarFile = new JarFile(file);
+ Manifest m = jarFile.getManifest();
+ if (m == null) {
+ throw new BuildException(file + " doesn't have a MANIFEST");
+ }
+ return m;
+ } catch (final IOException ioe) {
+ throw new BuildException(ioe.getMessage(), ioe);
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/extension/ExtraAttribute.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/extension/ExtraAttribute.java
new file mode 100644
index 00000000..d52bec41
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/extension/ExtraAttribute.java
@@ -0,0 +1,83 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.extension;
+
+import org.apache.tools.ant.BuildException;
+
+/**
+ * Simple holder for extra attributes in main section of manifest.
+ *
+ * @todo Refactor this and all the other parameter, sysproperty,
+ * property etc into a single class in framework
+ */
+public class ExtraAttribute {
+ private String name;
+ private String value;
+
+ /**
+ * Set the name of the parameter.
+ *
+ * @param name the name of parameter
+ */
+ public void setName(final String name) {
+ this.name = name;
+ }
+
+ /**
+ * Set the value of the parameter.
+ *
+ * @param value the parameter value
+ */
+ public void setValue(final String value) {
+ this.value = value;
+ }
+
+ /**
+ * Retrieve name of parameter.
+ *
+ * @return the name of parameter.
+ */
+ String getName() {
+ return name;
+ }
+
+ /**
+ * Retrieve the value of parameter.
+ *
+ * @return the value of parameter.
+ */
+ String getValue() {
+ return value;
+ }
+
+ /**
+ * Make sure that neither the name or the value
+ * is null.
+ *
+ * @throws BuildException if the attribute is invalid.
+ */
+ public void validate() throws BuildException {
+ if (null == name) {
+ final String message = "Missing name from parameter.";
+ throw new BuildException(message);
+ } else if (null == value) {
+ final String message = "Missing value from parameter " + name + ".";
+ throw new BuildException(message);
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/extension/JarLibAvailableTask.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/extension/JarLibAvailableTask.java
new file mode 100644
index 00000000..cebcf0d5
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/extension/JarLibAvailableTask.java
@@ -0,0 +1,157 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.extension;
+
+import java.io.File;
+import java.util.Iterator;
+import java.util.Vector;
+import java.util.jar.Manifest;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Task;
+
+/**
+ * Checks whether an extension is present in a fileset or an extensionSet.
+ *
+ * @ant.task name="jarlib-available"
+ */
+public class JarLibAvailableTask extends Task {
+ /**
+ * The library to display information about.
+ */
+ private File libraryFile;
+
+ /**
+ * Filesets specifying all the librarys
+ * to display information about.
+ */
+ private final Vector extensionFileSets = new Vector();
+
+ /**
+ * The name of the property to set if extension is available.
+ */
+ private String propertyName;
+
+ /**
+ * The extension that is required.
+ */
+ private ExtensionAdapter requiredExtension;
+
+ /**
+ * The name of property to set if extensions are available.
+ *
+ * @param property The name of property to set if extensions is available.
+ */
+ public void setProperty(final String property) {
+ this.propertyName = property;
+ }
+
+ /**
+ * The JAR library to check.
+ *
+ * @param file The jar library to check.
+ */
+ public void setFile(final File file) {
+ this.libraryFile = file;
+ }
+
+ /**
+ * Set the Extension looking for.
+ *
+ * @param extension Set the Extension looking for.
+ */
+ public void addConfiguredExtension(final ExtensionAdapter extension) {
+ if (null != requiredExtension) {
+ final String message = "Can not specify extension to "
+ + "search for multiple times.";
+ throw new BuildException(message);
+ }
+ requiredExtension = extension;
+ }
+
+ /**
+ * Adds a set of extensions to search in.
+ *
+ * @param extensionSet a set of extensions to search in.
+ */
+ public void addConfiguredExtensionSet(final ExtensionSet extensionSet) {
+ extensionFileSets.addElement(extensionSet);
+ }
+
+ /**
+ * Execute the task.
+ *
+ * @throws BuildException if something goes wrong.
+ */
+ public void execute() throws BuildException {
+ validate();
+
+ final Extension test = requiredExtension.toExtension();
+
+ // Check if list of files to check has been specified
+ if (!extensionFileSets.isEmpty()) {
+ final Iterator iterator = extensionFileSets.iterator();
+ while (iterator.hasNext()) {
+ final ExtensionSet extensionSet
+ = (ExtensionSet) iterator.next();
+ final Extension[] extensions =
+ extensionSet.toExtensions(getProject());
+ for (int i = 0; i < extensions.length; i++) {
+ final Extension extension = extensions[ i ];
+ if (extension.isCompatibleWith(test)) {
+ getProject().setNewProperty(propertyName, "true");
+ }
+ }
+ }
+ } else {
+ final Manifest manifest = ExtensionUtil.getManifest(libraryFile);
+ final Extension[] extensions = Extension.getAvailable(manifest);
+ for (int i = 0; i < extensions.length; i++) {
+ final Extension extension = extensions[ i ];
+ if (extension.isCompatibleWith(test)) {
+ getProject().setNewProperty(propertyName, "true");
+ }
+ }
+ }
+ }
+
+ /**
+ * Validate the tasks parameters.
+ *
+ * @throws BuildException if invalid parameters found
+ */
+ private void validate() throws BuildException {
+ if (null == requiredExtension) {
+ final String message = "Extension element must be specified.";
+ throw new BuildException(message);
+ }
+
+ if (null == libraryFile && extensionFileSets.isEmpty()) {
+ final String message = "File attribute not specified.";
+ throw new BuildException(message);
+ }
+ if (null != libraryFile && !libraryFile.exists()) {
+ final String message = "File '" + libraryFile + "' does not exist.";
+ throw new BuildException(message);
+ }
+ if (null != libraryFile && !libraryFile.isFile()) {
+ final String message = "\'" + libraryFile + "\' is not a file.";
+ throw new BuildException(message);
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/extension/JarLibDisplayTask.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/extension/JarLibDisplayTask.java
new file mode 100644
index 00000000..da12cd02
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/extension/JarLibDisplayTask.java
@@ -0,0 +1,119 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.extension;
+
+import java.io.File;
+import java.util.Iterator;
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.DirectoryScanner;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.types.FileSet;
+
+/**
+ * Displays the "Optional Package" and "Package Specification" information
+ * contained within the specified JARs.
+ *
+ * <p>Prior to JDK1.3, an "Optional Package" was known as an Extension.
+ * The specification for this mechanism is available in the JDK1.3
+ * documentation in the directory
+ * $JDK_HOME/docs/guide/extensions/versioning.html. Alternatively it is
+ * available online at <a href="http://java.sun.com/j2se/1.3/docs/guide/extensions/versioning.html">
+ * http://java.sun.com/j2se/1.3/docs/guide/extensions/versioning.html</a>.</p>
+ *
+ * @ant.task name="jarlib-display"
+ */
+public class JarLibDisplayTask extends Task {
+ /**
+ * The library to display information about.
+ */
+ private File libraryFile;
+
+ /**
+ * Filesets specifying all the librarys
+ * to display information about.
+ */
+ private final Vector libraryFileSets = new Vector();
+
+ /**
+ * The JAR library to display information for.
+ *
+ * @param file The jar library to display information for.
+ */
+ public void setFile(final File file) {
+ this.libraryFile = file;
+ }
+
+ /**
+ * Adds a set of files about which library data will be displayed.
+ *
+ * @param fileSet a set of files about which library data will be displayed.
+ */
+ public void addFileset(final FileSet fileSet) {
+ libraryFileSets.addElement(fileSet);
+ }
+
+ /**
+ * Execute the task.
+ *
+ * @throws BuildException if the task fails.
+ */
+ public void execute() throws BuildException {
+ validate();
+
+ final LibraryDisplayer displayer = new LibraryDisplayer();
+ // Check if list of files to check has been specified
+ if (!libraryFileSets.isEmpty()) {
+ final Iterator iterator = libraryFileSets.iterator();
+ while (iterator.hasNext()) {
+ final FileSet fileSet = (FileSet) iterator.next();
+ final DirectoryScanner scanner
+ = fileSet.getDirectoryScanner(getProject());
+ final File basedir = scanner.getBasedir();
+ final String[] files = scanner.getIncludedFiles();
+ for (int i = 0; i < files.length; i++) {
+ final File file = new File(basedir, files[ i ]);
+ displayer.displayLibrary(file);
+ }
+ }
+ } else {
+ displayer.displayLibrary(libraryFile);
+ }
+ }
+
+ /**
+ * Validate the tasks parameters.
+ *
+ * @throws BuildException if invalid parameters found
+ */
+ private void validate() throws BuildException {
+ if (null == libraryFile && libraryFileSets.isEmpty()) {
+ final String message = "File attribute not specified.";
+ throw new BuildException(message);
+ }
+ if (null != libraryFile && !libraryFile.exists()) {
+ final String message = "File '" + libraryFile + "' does not exist.";
+ throw new BuildException(message);
+ }
+ if (null != libraryFile && !libraryFile.isFile()) {
+ final String message = "\'" + libraryFile + "\' is not a file.";
+ throw new BuildException(message);
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/extension/JarLibManifestTask.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/extension/JarLibManifestTask.java
new file mode 100644
index 00000000..5afc57f1
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/extension/JarLibManifestTask.java
@@ -0,0 +1,296 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.extension;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.jar.Attributes;
+import java.util.jar.Manifest;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.MagicNames;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+
+/**
+ * Generates a manifest that declares all the dependencies.
+ * The dependencies are determined by looking in the
+ * specified path and searching for Extension / "Optional Package"
+ * specifications in the manifests of the jars.
+ *
+ * <p>Prior to JDK1.3, an "Optional Package" was known as an Extension.
+ * The specification for this mechanism is available in the JDK1.3
+ * documentation in the directory
+ * $JDK_HOME/docs/guide/extensions/versioning.html. Alternatively it is
+ * available online at <a href="http://java.sun.com/j2se/1.3/docs/guide/extensions/versioning.html">
+ * http://java.sun.com/j2se/1.3/docs/guide/extensions/versioning.html</a>.</p>
+ *
+ * @ant.task name="jarlib-manifest"
+ */
+public final class JarLibManifestTask extends Task {
+ /**
+ * Version of manifest spec that task generates.
+ */
+ private static final String MANIFEST_VERSION = "1.0";
+
+ /**
+ * "Created-By" string used when creating manifest.
+ */
+ private static final String CREATED_BY = "Created-By";
+
+ /**
+ * The library to display information about.
+ */
+ private File destFile;
+
+ /**
+ * The extension supported by this library (if any).
+ */
+ private Extension extension;
+
+ /**
+ * ExtensionAdapter objects representing
+ * dependencies required by library.
+ */
+ private final ArrayList dependencies = new ArrayList();
+
+ /**
+ * ExtensionAdapter objects representing optional
+ * dependencies required by library.
+ */
+ private final ArrayList optionals = new ArrayList();
+
+ /**
+ * Extra attributes the user specifies for main section
+ * in manifest.
+ */
+ private final ArrayList extraAttributes = new ArrayList();
+
+ /**
+ * The location where generated manifest is placed.
+ *
+ * @param destFile The location where generated manifest is placed.
+ */
+ public void setDestfile(final File destFile) {
+ this.destFile = destFile;
+ }
+
+ /**
+ * Adds an extension that this library implements.
+ *
+ * @param extensionAdapter an extension that this library implements.
+ *
+ * @throws BuildException if there is multiple extensions detected
+ * in the library.
+ */
+ public void addConfiguredExtension(final ExtensionAdapter extensionAdapter)
+ throws BuildException {
+ if (null != extension) {
+ throw new BuildException("Can not have multiple extensions defined in one library.");
+ }
+ extension = extensionAdapter.toExtension();
+ }
+
+ /**
+ * Adds a set of extensions that this library requires.
+ *
+ * @param extensionSet a set of extensions that this library requires.
+ */
+ public void addConfiguredDepends(final ExtensionSet extensionSet) {
+ dependencies.add(extensionSet);
+ }
+
+ /**
+ * Adds a set of extensions that this library optionally requires.
+ *
+ * @param extensionSet a set of extensions that this library optionally requires.
+ */
+ public void addConfiguredOptions(final ExtensionSet extensionSet) {
+ optionals.add(extensionSet);
+ }
+
+ /**
+ * Adds an attribute that is to be put in main section of manifest.
+ *
+ * @param attribute an attribute that is to be put in main section of manifest.
+ */
+ public void addConfiguredAttribute(final ExtraAttribute attribute) {
+ extraAttributes.add(attribute);
+ }
+
+ /**
+ * Execute the task.
+ *
+ * @throws BuildException if the task fails.
+ */
+ public void execute() throws BuildException {
+ validate();
+
+ final Manifest manifest = new Manifest();
+ final Attributes attributes = manifest.getMainAttributes();
+
+ attributes.put(Attributes.Name.MANIFEST_VERSION, MANIFEST_VERSION);
+ attributes.putValue(CREATED_BY, "Apache Ant "
+ + getProject().getProperty(MagicNames.ANT_VERSION));
+
+ appendExtraAttributes(attributes);
+
+ if (null != extension) {
+ Extension.addExtension(extension, attributes);
+ }
+
+ //Add all the dependency data to manifest for dependencies
+ final ArrayList depends = toExtensions(dependencies);
+ appendExtensionList(attributes, Extension.EXTENSION_LIST, "lib", depends.size());
+ appendLibraryList(attributes, "lib", depends);
+
+ // Add all the dependency data to manifest for "optional"
+ //dependencies
+ final ArrayList option = toExtensions(optionals);
+ appendExtensionList(attributes, Extension.OPTIONAL_EXTENSION_LIST, "opt", option.size());
+ appendLibraryList(attributes, "opt", option);
+
+ try {
+ log("Generating manifest " + destFile.getAbsoluteFile(), Project.MSG_INFO);
+ writeManifest(manifest);
+ } catch (final IOException ioe) {
+ throw new BuildException(ioe.getMessage(), ioe);
+ }
+ }
+
+ /**
+ * Validate the tasks parameters.
+ *
+ * @throws BuildException if invalid parameters found
+ */
+ private void validate() throws BuildException {
+ if (null == destFile) {
+ throw new BuildException("Destfile attribute not specified.");
+ }
+ if (destFile.exists() && !destFile.isFile()) {
+ throw new BuildException(destFile + " is not a file.");
+ }
+ }
+
+ /**
+ * Add any extra attributes to the manifest.
+ *
+ * @param attributes the manifest section to write
+ * attributes to
+ */
+ private void appendExtraAttributes(final Attributes attributes) {
+ final Iterator iterator = extraAttributes.iterator();
+ while (iterator.hasNext()) {
+ final ExtraAttribute attribute =
+ (ExtraAttribute) iterator.next();
+ attributes.putValue(attribute.getName(),
+ attribute.getValue());
+ }
+ }
+
+ /**
+ * Write out manifest to destfile.
+ *
+ * @param manifest the manifest
+ * @throws IOException if error writing file
+ */
+ private void writeManifest(final Manifest manifest) throws IOException {
+ FileOutputStream output = null;
+ try {
+ output = new FileOutputStream(destFile);
+ manifest.write(output);
+ output.flush();
+ } finally {
+ if (null != output) {
+ try {
+ output.close();
+ } catch (IOException e) {
+ // ignore
+ }
+ }
+ }
+ }
+
+ /**
+ * Append specified extensions to specified attributes.
+ * Use the extensionKey to list the extensions, usually "Extension-List:"
+ * for required dependencies and "Optional-Extension-List:" for optional
+ * dependencies. NOTE: "Optional" dependencies are not part of the
+ * specification.
+ *
+ * @param attributes the attributes to add extensions to
+ * @param extensions the list of extensions
+ * @throws BuildException if an error occurs
+ */
+ private void appendLibraryList(final Attributes attributes, final String listPrefix,
+ final ArrayList extensions) throws BuildException {
+ final int size = extensions.size();
+ for (int i = 0; i < size; i++) {
+ final Extension ext = (Extension) extensions.get(i);
+ final String prefix = listPrefix + i + "-";
+ Extension.addExtension(ext, prefix, attributes);
+ }
+ }
+
+ /**
+ * Append an attribute such as "Extension-List: lib0 lib1 lib2"
+ * using specified prefix and counting up to specified size.
+ * Also use specified extensionKey so that can generate list of
+ * optional dependencies as well.
+ *
+ * @param size the number of librarys to list
+ * @param listPrefix the prefix for all librarys
+ * @param attributes the attributes to add key-value to
+ * @param extensionKey the key to use
+ */
+ private void appendExtensionList(final Attributes attributes,
+ final Attributes.Name extensionKey, final String listPrefix, final int size) {
+ final StringBuffer sb = new StringBuffer();
+ for (int i = 0; i < size; i++) {
+ sb.append(listPrefix);
+ sb.append(i);
+ sb.append(' ');
+ }
+ //add in something like
+ //"Extension-List: javahelp java3d"
+ attributes.put(extensionKey, sb.toString());
+ }
+
+ /**
+ * Convert a list of ExtensionSet objects to extensions.
+ *
+ * @param extensionSets the list of ExtensionSets to add to list
+ * @throws BuildException if an error occurs
+ */
+ private ArrayList toExtensions(final ArrayList extensionSets) throws BuildException {
+ final ArrayList results = new ArrayList();
+
+ final int size = extensionSets.size();
+ for (int i = 0; i < size; i++) {
+ final ExtensionSet set = (ExtensionSet) extensionSets.get(i);
+ final Extension[] extensions = set.toExtensions(getProject());
+ for (int j = 0; j < extensions.length; j++) {
+ results.add(extensions[ j ]);
+ }
+ }
+ return results;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/extension/JarLibResolveTask.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/extension/JarLibResolveTask.java
new file mode 100644
index 00000000..c13194fa
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/extension/JarLibResolveTask.java
@@ -0,0 +1,268 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.extension;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.jar.Manifest;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.taskdefs.optional.extension.resolvers.AntResolver;
+import org.apache.tools.ant.taskdefs.optional.extension.resolvers.LocationResolver;
+import org.apache.tools.ant.taskdefs.optional.extension.resolvers.URLResolver;
+
+/**
+ * Tries to locate a JAR to satisfy an extension and place
+ * location of JAR into property.
+ *
+ * @ant.task name="jarlib-resolve"
+ */
+public class JarLibResolveTask extends Task {
+ /**
+ * The name of the property in which the location of
+ * library is stored.
+ */
+ private String propertyName;
+
+ /**
+ * The extension that is required.
+ */
+ private Extension requiredExtension;
+
+ /**
+ * The set of resolvers to use to attempt to locate library.
+ */
+ private final ArrayList resolvers = new ArrayList();
+
+ /**
+ * Flag to indicate that you should check that
+ * the librarys resolved actually contain
+ * extension and if they don't then raise
+ * an exception.
+ */
+ private boolean checkExtension = true;
+
+ /**
+ * Flag indicating whether or not you should
+ * throw a BuildException if you cannot resolve
+ * library.
+ */
+ private boolean failOnError = true;
+
+ /**
+ * The name of the property in which the location of
+ * library is stored.
+ *
+ * @param property The name of the property in which the location of
+ * library is stored.
+ */
+ public void setProperty(final String property) {
+ this.propertyName = property;
+ }
+
+ /**
+ * Check nested libraries for extensions
+ *
+ * @param checkExtension if true, libraries returned by nested
+ * resolvers should be checked to see if they supply extension.
+ */
+ public void setCheckExtension(final boolean checkExtension) {
+ this.checkExtension = checkExtension;
+ }
+
+ /**
+ * Set whether to fail if error.
+ *
+ * @param failOnError if true, failure to locate library should fail build.
+ */
+ public void setFailOnError(final boolean failOnError) {
+ this.failOnError = failOnError;
+ }
+
+ /**
+ * Adds location resolver to look for a library in a location
+ * relative to project directory.
+ *
+ * @param loc the resolver location to search.
+ */
+ public void addConfiguredLocation(final LocationResolver loc) {
+ resolvers.add(loc);
+ }
+
+ /**
+ * Adds a URL resolver to download a library from a URL
+ * to a local file.
+ *
+ * @param url the URL resolver from which to download the library
+ */
+ public void addConfiguredUrl(final URLResolver url) {
+ resolvers.add(url);
+ }
+
+ /**
+ * Adds Ant resolver to run an Ant build file to generate a library.
+ *
+ * @param ant the AntResolver to generate the library.
+ */
+ public void addConfiguredAnt(final AntResolver ant) {
+ resolvers.add(ant);
+ }
+
+ /**
+ * Set the Extension looking for.
+ *
+ * @param extension Set the Extension looking for.
+ */
+ public void addConfiguredExtension(final ExtensionAdapter extension) {
+ if (null != requiredExtension) {
+ final String message = "Can not specify extension to "
+ + "resolve multiple times.";
+ throw new BuildException(message);
+ }
+ requiredExtension = extension.toExtension();
+ }
+
+ /**
+ * Execute the task.
+ *
+ * @throws BuildException if the task fails.
+ */
+ public void execute() throws BuildException {
+ validate();
+
+ getProject().log("Resolving extension: " + requiredExtension, Project.MSG_VERBOSE);
+
+ String candidate = getProject().getProperty(propertyName);
+
+ if (null != candidate) {
+ final String message = "Property Already set to: " + candidate;
+ if (failOnError) {
+ throw new BuildException(message);
+ }
+ getProject().log(message, Project.MSG_ERR);
+ return;
+ }
+
+ final int size = resolvers.size();
+ for (int i = 0; i < size; i++) {
+ final ExtensionResolver resolver =
+ (ExtensionResolver) resolvers.get(i);
+
+ getProject().log("Searching for extension using Resolver:" + resolver,
+ Project.MSG_VERBOSE);
+
+ try {
+ final File file = resolver.resolve(requiredExtension, getProject());
+ try {
+ checkExtension(file);
+ return;
+ } catch (final BuildException be) {
+ final String message = "File " + file + " returned by "
+ + "resolver failed to satisfy extension due to: " + be.getMessage();
+ getProject().log(message, Project.MSG_WARN);
+ }
+ } catch (final BuildException be) {
+ final String message = "Failed to resolve extension to file " + "using resolver "
+ + resolver + " due to: " + be;
+ getProject().log(message, Project.MSG_WARN);
+ }
+ }
+ missingExtension();
+ }
+
+ /**
+ * Utility method that will throw a {@link BuildException}
+ * if {@link #failOnError} is true else it just displays
+ * a warning.
+ */
+ private void missingExtension() {
+ final String message = "Unable to resolve extension to a file";
+ if (failOnError) {
+ throw new BuildException(message);
+ }
+ getProject().log(message, Project.MSG_ERR);
+ }
+
+ /**
+ * Check if specified file satisfies extension.
+ * If it does then set the relevant property
+ * else throw a BuildException.
+ *
+ * @param file the candidate library
+ * @throws BuildException if library does not satisfy extension
+ */
+ private void checkExtension(final File file) {
+ if (!file.exists()) {
+ throw new BuildException("File " + file + " does not exist");
+ }
+ if (!file.isFile()) {
+ throw new BuildException("File " + file + " is not a file");
+ }
+ if (!checkExtension) {
+ getProject().log("Setting property to " + file
+ + " without verifying library satisfies extension", Project.MSG_VERBOSE);
+ setLibraryProperty(file);
+ } else {
+ getProject().log("Checking file " + file + " to see if it satisfies extension",
+ Project.MSG_VERBOSE);
+ final Manifest manifest = ExtensionUtil.getManifest(file);
+ final Extension[] extensions = Extension.getAvailable(manifest);
+ for (int i = 0; i < extensions.length; i++) {
+ final Extension extension = extensions[ i ];
+ if (extension.isCompatibleWith(requiredExtension)) {
+ setLibraryProperty(file);
+ return;
+ }
+ }
+ final String message = "File " + file + " skipped as it "
+ + "does not satisfy extension";
+ getProject().log(message, Project.MSG_VERBOSE);
+ throw new BuildException(message);
+ }
+ }
+
+ /**
+ * Utility method to set the appropriate property
+ * to indicate that specified file satisfies library
+ * requirements.
+ *
+ * @param file the library
+ */
+ private void setLibraryProperty(final File file) {
+ getProject().setNewProperty(propertyName, file.getAbsolutePath());
+ }
+
+ /**
+ * Validate the tasks parameters.
+ *
+ * @throws BuildException if invalid parameters found
+ */
+ private void validate() throws BuildException {
+ if (null == propertyName) {
+ final String message = "Property attribute must be specified.";
+ throw new BuildException(message);
+ }
+
+ if (null == requiredExtension) {
+ final String message = "Extension element must be specified.";
+ throw new BuildException(message);
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/extension/LibFileSet.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/extension/LibFileSet.java
new file mode 100644
index 00000000..b21719e5
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/extension/LibFileSet.java
@@ -0,0 +1,117 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.extension;
+
+import org.apache.tools.ant.types.FileSet;
+
+/**
+ * LibFileSet represents a fileset containing libraries.
+ * Associated with the libraries is data pertaining to
+ * how they are to be handled when building manifests.
+ *
+ */
+public class LibFileSet
+ extends FileSet {
+ /**
+ * Flag indicating whether should include the
+ * "Implementation-URL" attribute in manifest.
+ * Defaults to false.
+ */
+ private boolean includeURL;
+
+ /**
+ * Flag indicating whether should include the
+ * "Implementation-*" attributes in manifest.
+ * Defaults to false.
+ */
+ private boolean includeImpl;
+
+ /**
+ * String that is the base URL for the librarys
+ * when constructing the "Implementation-URL"
+ * attribute. For instance setting the base to
+ * "http://jakarta.apache.org/avalon/libs/" and then
+ * including the library "excalibur-cli-1.0.jar" in the
+ * fileset will result in the "Implementation-URL" attribute
+ * being set to "http://jakarta.apache.org/avalon/libs/excalibur-cli-1.0.jar"
+ *
+ * Note this is only used if the library does not define
+ * "Implementation-URL" itself.
+ *
+ * Note that this also implies includeURL=true
+ */
+ private String urlBase;
+
+ /**
+ * Flag indicating whether should include the
+ * "Implementation-URL" attribute in manifest.
+ * Defaults to false.
+ *
+ * @param includeURL the flag
+ */
+ public void setIncludeUrl(boolean includeURL) {
+ this.includeURL = includeURL;
+ }
+
+ /**
+ * Flag indicating whether should include the
+ * "Implementation-*" attributes in manifest.
+ * Defaults to false.
+ *
+ * @param includeImpl the flag
+ */
+ public void setIncludeImpl(boolean includeImpl) {
+ this.includeImpl = includeImpl;
+ }
+
+ /**
+ * Set the url base for fileset.
+ *
+ * @param urlBase the base url
+ */
+ public void setUrlBase(String urlBase) {
+ this.urlBase = urlBase;
+ }
+
+ /**
+ * Get the includeURL flag.
+ *
+ * @return the includeURL flag.
+ */
+ boolean isIncludeURL() {
+ return includeURL;
+ }
+
+ /**
+ * Get the includeImpl flag.
+ *
+ * @return the includeImpl flag.
+ */
+ boolean isIncludeImpl() {
+ return includeImpl;
+ }
+
+ /**
+ * Get the urlbase.
+ *
+ * @return the urlbase.
+ */
+ String getUrlBase() {
+ return urlBase;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/extension/LibraryDisplayer.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/extension/LibraryDisplayer.java
new file mode 100644
index 00000000..b0ee4f81
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/extension/LibraryDisplayer.java
@@ -0,0 +1,150 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.extension;
+
+import java.io.File;
+import java.text.ParseException;
+import java.util.jar.Manifest;
+
+import org.apache.tools.ant.BuildException;
+
+/**
+ * Utility class to output the information in a jar relating
+ * to "Optional Packages" (formely known as "Extensions")
+ * and Package Specifications.
+ *
+ */
+class LibraryDisplayer {
+ /**
+ * Display the extensions and specifications contained
+ * within specified file.
+ *
+ * @param file the file
+ * @throws BuildException if fail to read file
+ */
+ void displayLibrary(final File file)
+ throws BuildException {
+ final Manifest manifest = ExtensionUtil.getManifest(file);
+ displayLibrary(file, manifest);
+ }
+
+ /**
+ * Display the extensions and specifications contained
+ * within specified file.
+ *
+ * @param file the file to use while reporting
+ * @param manifest the manifest of file
+ * @throws BuildException if fail to read file
+ */
+ void displayLibrary(final File file,
+ final Manifest manifest)
+ throws BuildException {
+ final Extension[] available = Extension.getAvailable(manifest);
+ final Extension[] required = Extension.getRequired(manifest);
+ final Extension[] options = Extension.getOptions(manifest);
+ final Specification[] specifications = getSpecifications(manifest);
+
+ if (0 == available.length && 0 == required.length && 0 == options.length
+ && 0 == specifications.length) {
+ return;
+ }
+
+ final String message = "File: " + file;
+ final int size = message.length();
+ printLine(size);
+ System.out.println(message);
+ printLine(size);
+ if (0 != available.length) {
+ System.out.println("Extensions Supported By Library:");
+ for (int i = 0; i < available.length; i++) {
+ final Extension extension = available[ i ];
+ System.out.println(extension.toString());
+ }
+ }
+
+ if (0 != required.length) {
+ System.out.println("Extensions Required By Library:");
+ for (int i = 0; i < required.length; i++) {
+ final Extension extension = required[ i ];
+ System.out.println(extension.toString());
+ }
+ }
+
+ if (0 != options.length) {
+ System.out.println("Extensions that will be used by Library if present:");
+ for (int i = 0; i < options.length; i++) {
+ final Extension extension = options[ i ];
+ System.out.println(extension.toString());
+ }
+ }
+
+ if (0 != specifications.length) {
+ System.out.println("Specifications Supported By Library:");
+ for (int i = 0; i < specifications.length; i++) {
+ final Specification specification = specifications[ i ];
+ displaySpecification(specification);
+ }
+ }
+ }
+
+ /**
+ * Print out a line of '-'s equal to specified size.
+ *
+ * @param size the number of dashes to printout
+ */
+ private void printLine(final int size) {
+ for (int i = 0; i < size; i++) {
+ System.out.print("-");
+ }
+ System.out.println();
+ }
+
+ /**
+ * Get specifications from manifest.
+ *
+ * @param manifest the manifest
+ * @return the specifications or null if none
+ * @throws BuildException if malformed specification sections
+ */
+ private Specification[] getSpecifications(final Manifest manifest)
+ throws BuildException {
+ try {
+ return Specification.getSpecifications(manifest);
+ } catch (final ParseException pe) {
+ throw new BuildException(pe.getMessage(), pe);
+ }
+ }
+
+ /**
+ * Print out specification details.
+ *
+ * @param specification the specification
+ */
+ private void displaySpecification(final Specification specification) {
+ final String[] sections = specification.getSections();
+ if (null != sections) {
+ final StringBuffer sb = new StringBuffer("Sections: ");
+ for (int i = 0; i < sections.length; i++) {
+ sb.append(" ");
+ sb.append(sections[ i ]);
+ }
+ System.out.println(sb);
+ }
+ System.out.println(specification.toString());
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/extension/Specification.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/extension/Specification.java
new file mode 100644
index 00000000..1e4bb7b3
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/extension/Specification.java
@@ -0,0 +1,605 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.extension;
+
+import java.text.ParseException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.jar.Attributes;
+import java.util.jar.Manifest;
+
+import org.apache.tools.ant.util.DeweyDecimal;
+import org.apache.tools.ant.util.StringUtils;
+
+/**
+ * <p>Utility class that represents either an available "Optional Package"
+ * (formerly known as "Standard Extension") as described in the manifest
+ * of a JAR file, or the requirement for such an optional package.</p>
+ *
+ * <p>For more information about optional packages, see the document
+ * <em>Optional Package Versioning</em> in the documentation bundle for your
+ * Java2 Standard Edition package, in file
+ * <code>guide/extensions/versioning.html</code>.</p>
+ *
+ */
+public final class Specification {
+
+ private static final String MISSING = "Missing ";
+
+ /**
+ * Manifest Attribute Name object for SPECIFICATION_TITLE.
+ */
+ public static final Attributes.Name SPECIFICATION_TITLE
+ = Attributes.Name.SPECIFICATION_TITLE;
+
+ /**
+ * Manifest Attribute Name object for SPECIFICATION_VERSION.
+ */
+ public static final Attributes.Name SPECIFICATION_VERSION
+ = Attributes.Name.SPECIFICATION_VERSION;
+
+ /**
+ * Manifest Attribute Name object for SPECIFICATION_VENDOR.
+ */
+ public static final Attributes.Name SPECIFICATION_VENDOR
+ = Attributes.Name.SPECIFICATION_VENDOR;
+
+ /**
+ * Manifest Attribute Name object for IMPLEMENTATION_TITLE.
+ */
+ public static final Attributes.Name IMPLEMENTATION_TITLE
+ = Attributes.Name.IMPLEMENTATION_TITLE;
+
+ /**
+ * Manifest Attribute Name object for IMPLEMENTATION_VERSION.
+ */
+ public static final Attributes.Name IMPLEMENTATION_VERSION
+ = Attributes.Name.IMPLEMENTATION_VERSION;
+
+ /**
+ * Manifest Attribute Name object for IMPLEMENTATION_VENDOR.
+ */
+ public static final Attributes.Name IMPLEMENTATION_VENDOR
+ = Attributes.Name.IMPLEMENTATION_VENDOR;
+
+ /**
+ * Enum indicating that extension is compatible with other Package
+ * Specification.
+ */
+ public static final Compatibility COMPATIBLE =
+ new Compatibility("COMPATIBLE");
+
+ /**
+ * Enum indicating that extension requires an upgrade
+ * of specification to be compatible with other Package Specification.
+ */
+ public static final Compatibility REQUIRE_SPECIFICATION_UPGRADE =
+ new Compatibility("REQUIRE_SPECIFICATION_UPGRADE");
+
+ /**
+ * Enum indicating that extension requires a vendor
+ * switch to be compatible with other Package Specification.
+ */
+ public static final Compatibility REQUIRE_VENDOR_SWITCH =
+ new Compatibility("REQUIRE_VENDOR_SWITCH");
+
+ /**
+ * Enum indicating that extension requires an upgrade
+ * of implementation to be compatible with other Package Specification.
+ */
+ public static final Compatibility REQUIRE_IMPLEMENTATION_CHANGE =
+ new Compatibility("REQUIRE_IMPLEMENTATION_CHANGE");
+
+ /**
+ * This enum indicates that an extension is incompatible with
+ * other Package Specification in ways other than other enums
+ * indicate. For example, the other Package Specification
+ * may have a different ID.
+ */
+ public static final Compatibility INCOMPATIBLE =
+ new Compatibility("INCOMPATIBLE");
+
+ /**
+ * The name of the Package Specification.
+ */
+ private String specificationTitle;
+
+ /**
+ * The version number (dotted decimal notation) of the specification
+ * to which this optional package conforms.
+ */
+ private DeweyDecimal specificationVersion;
+
+ /**
+ * The name of the company or organization that originated the
+ * specification to which this specification conforms.
+ */
+ private String specificationVendor;
+
+ /**
+ * The title of implementation.
+ */
+ private String implementationTitle;
+
+ /**
+ * The name of the company or organization that produced this
+ * implementation of this specification.
+ */
+ private String implementationVendor;
+
+ /**
+ * The version string for implementation. The version string is
+ * opaque.
+ */
+ private String implementationVersion;
+
+ /**
+ * The sections of jar that the specification applies to.
+ */
+ private String[] sections;
+
+ /**
+ * Return an array of <code>Package Specification</code> objects.
+ * If there are no such optional packages, a zero-length array is returned.
+ *
+ * @param manifest Manifest to be parsed
+ * @return the Package Specifications extensions in specified manifest
+ * @throws ParseException if the attributes of the specifications cannot
+ * be parsed according to their expected formats.
+ */
+ public static Specification[] getSpecifications(final Manifest manifest)
+ throws ParseException {
+ if (null == manifest) {
+ return new Specification[ 0 ];
+ }
+
+ final ArrayList results = new ArrayList();
+
+ final Map entries = manifest.getEntries();
+ final Iterator keys = entries.keySet().iterator();
+ while (keys.hasNext()) {
+ final String key = (String) keys.next();
+ final Attributes attributes = (Attributes) entries.get(key);
+ final Specification specification
+ = getSpecification(key, attributes);
+ if (null != specification) {
+ results.add(specification);
+ }
+ }
+
+ final ArrayList trimmedResults = removeDuplicates(results);
+ return (Specification[]) trimmedResults.toArray(new Specification[trimmedResults.size()]);
+ }
+
+ /**
+ * The constructor to create Package Specification object.
+ * Note that every component is allowed to be specified
+ * but only the specificationTitle is mandatory.
+ *
+ * @param specificationTitle the name of specification.
+ * @param specificationVersion the specification Version.
+ * @param specificationVendor the specification Vendor.
+ * @param implementationTitle the title of implementation.
+ * @param implementationVersion the implementation Version.
+ * @param implementationVendor the implementation Vendor.
+ */
+ public Specification(final String specificationTitle,
+ final String specificationVersion,
+ final String specificationVendor,
+ final String implementationTitle,
+ final String implementationVersion,
+ final String implementationVendor) {
+ this(specificationTitle, specificationVersion, specificationVendor,
+ implementationTitle, implementationVersion, implementationVendor,
+ null);
+ }
+
+ /**
+ * The constructor to create Package Specification object.
+ * Note that every component is allowed to be specified
+ * but only the specificationTitle is mandatory.
+ *
+ * @param specificationTitle the name of specification.
+ * @param specificationVersion the specification Version.
+ * @param specificationVendor the specification Vendor.
+ * @param implementationTitle the title of implementation.
+ * @param implementationVersion the implementation Version.
+ * @param implementationVendor the implementation Vendor.
+ * @param sections the sections/packages that Specification applies to.
+ */
+ public Specification(final String specificationTitle,
+ final String specificationVersion,
+ final String specificationVendor,
+ final String implementationTitle,
+ final String implementationVersion,
+ final String implementationVendor,
+ final String[] sections) {
+ this.specificationTitle = specificationTitle;
+ this.specificationVendor = specificationVendor;
+
+ if (null != specificationVersion) {
+ try {
+ this.specificationVersion
+ = new DeweyDecimal(specificationVersion);
+ } catch (final NumberFormatException nfe) {
+ final String error = "Bad specification version format '"
+ + specificationVersion + "' in '" + specificationTitle
+ + "'. (Reason: " + nfe + ")";
+ throw new IllegalArgumentException(error);
+ }
+ }
+
+ this.implementationTitle = implementationTitle;
+ this.implementationVendor = implementationVendor;
+ this.implementationVersion = implementationVersion;
+
+ if (null == this.specificationTitle) {
+ throw new NullPointerException("specificationTitle");
+ }
+
+ String[] copy = null;
+ if (null != sections) {
+ copy = new String[ sections.length ];
+ System.arraycopy(sections, 0, copy, 0, sections.length);
+ }
+ this.sections = copy;
+ }
+
+ /**
+ * Get the title of the specification.
+ *
+ * @return the title of specification
+ */
+ public String getSpecificationTitle() {
+ return specificationTitle;
+ }
+
+ /**
+ * Get the vendor of the specification.
+ *
+ * @return the vendor of the specification.
+ */
+ public String getSpecificationVendor() {
+ return specificationVendor;
+ }
+
+ /**
+ * Get the title of the specification.
+ *
+ * @return the title of the specification.
+ */
+ public String getImplementationTitle() {
+ return implementationTitle;
+ }
+
+ /**
+ * Get the version of the specification.
+ *
+ * @return the version of the specification.
+ */
+ public DeweyDecimal getSpecificationVersion() {
+ return specificationVersion;
+ }
+
+ /**
+ * Get the vendor of the extensions implementation.
+ *
+ * @return the vendor of the extensions implementation.
+ */
+ public String getImplementationVendor() {
+ return implementationVendor;
+ }
+
+ /**
+ * Get the version of the implementation.
+ *
+ * @return the version of the implementation.
+ */
+ public String getImplementationVersion() {
+ return implementationVersion;
+ }
+
+ /**
+ * Return an array containing sections to which specification applies
+ * or null if relevant to no sections.
+ *
+ * @return an array containing sections to which specification applies
+ * or null if relevant to no sections.
+ */
+ public String[] getSections() {
+ if (null == sections) {
+ return null;
+ }
+ final String[] newSections = new String[ sections.length ];
+ System.arraycopy(sections, 0, newSections, 0, sections.length);
+ return newSections;
+ }
+
+ /**
+ * Return a Compatibility enum indicating the relationship of this
+ * <code>Package Specification</code> with the specified
+ * <code>Extension</code>.
+ *
+ * @param other the other specification
+ * @return the enum indicating the compatibility (or lack thereof)
+ * of specified Package Specification
+ */
+ public Compatibility getCompatibilityWith(final Specification other) {
+ // Specification Name must match
+ if (!specificationTitle.equals(other.getSpecificationTitle())) {
+ return INCOMPATIBLE;
+ }
+
+ // Available specification version must be >= required
+ final DeweyDecimal otherSpecificationVersion
+ = other.getSpecificationVersion();
+ if (null != specificationVersion) {
+ if (null == otherSpecificationVersion
+ || !isCompatible(specificationVersion, otherSpecificationVersion)) {
+ return REQUIRE_SPECIFICATION_UPGRADE;
+ }
+ }
+
+ // Implementation Vendor ID must match
+ final String otherImplementationVendor
+ = other.getImplementationVendor();
+ if (null != implementationVendor) {
+ if (null == otherImplementationVendor
+ || !implementationVendor.equals(otherImplementationVendor)) {
+ return REQUIRE_VENDOR_SWITCH;
+ }
+ }
+
+ // Implementation version must be >= required
+ final String otherImplementationVersion
+ = other.getImplementationVersion();
+ if (null != implementationVersion) {
+ if (null == otherImplementationVersion
+ || !implementationVersion.equals(otherImplementationVersion)) {
+ return REQUIRE_IMPLEMENTATION_CHANGE;
+ }
+ }
+
+ // This available optional package satisfies the requirements
+ return COMPATIBLE;
+ }
+
+ /**
+ * Return <code>true</code> if the specified <code>package</code>
+ * is satisfied by this <code>Specification</code>. Otherwise, return
+ * <code>false</code>.
+ *
+ * @param other the specification
+ * @return true if the specification is compatible with this specification
+ */
+ public boolean isCompatibleWith(final Specification other) {
+ return (COMPATIBLE == getCompatibilityWith(other));
+ }
+
+ /**
+ * Return a String representation of this object.
+ *
+ * @return string representation of object.
+ */
+ public String toString() {
+ final String brace = ": ";
+
+ final StringBuffer sb
+ = new StringBuffer(SPECIFICATION_TITLE.toString());
+ sb.append(brace);
+ sb.append(specificationTitle);
+ sb.append(StringUtils.LINE_SEP);
+
+ if (null != specificationVersion) {
+ sb.append(SPECIFICATION_VERSION);
+ sb.append(brace);
+ sb.append(specificationVersion);
+ sb.append(StringUtils.LINE_SEP);
+ }
+
+ if (null != specificationVendor) {
+ sb.append(SPECIFICATION_VENDOR);
+ sb.append(brace);
+ sb.append(specificationVendor);
+ sb.append(StringUtils.LINE_SEP);
+ }
+
+ if (null != implementationTitle) {
+ sb.append(IMPLEMENTATION_TITLE);
+ sb.append(brace);
+ sb.append(implementationTitle);
+ sb.append(StringUtils.LINE_SEP);
+ }
+
+ if (null != implementationVersion) {
+ sb.append(IMPLEMENTATION_VERSION);
+ sb.append(brace);
+ sb.append(implementationVersion);
+ sb.append(StringUtils.LINE_SEP);
+ }
+
+ if (null != implementationVendor) {
+ sb.append(IMPLEMENTATION_VENDOR);
+ sb.append(brace);
+ sb.append(implementationVendor);
+ sb.append(StringUtils.LINE_SEP);
+ }
+
+ return sb.toString();
+ }
+
+ /**
+ * Return <code>true</code> if the first version number is greater than
+ * or equal to the second; otherwise return <code>false</code>.
+ *
+ * @param first First version number (dotted decimal)
+ * @param second Second version number (dotted decimal)
+ */
+ private boolean isCompatible(final DeweyDecimal first,
+ final DeweyDecimal second) {
+ return first.isGreaterThanOrEqual(second);
+ }
+
+ /**
+ * Combine all specifications objects that are identical except
+ * for the sections.
+ *
+ * <p>Note this is very inefficent and should probably be fixed
+ * in the future.</p>
+ *
+ * @param list the array of results to trim
+ * @return an array list with all duplicates removed
+ */
+ private static ArrayList removeDuplicates(final ArrayList list) {
+ final ArrayList results = new ArrayList();
+ final ArrayList sections = new ArrayList();
+ while (list.size() > 0) {
+ final Specification specification = (Specification) list.remove(0);
+ final Iterator iterator = list.iterator();
+ while (iterator.hasNext()) {
+ final Specification other = (Specification) iterator.next();
+ if (isEqual(specification, other)) {
+ final String[] otherSections = other.getSections();
+ if (null != otherSections) {
+ sections.addAll(Arrays.asList(otherSections));
+ }
+ iterator.remove();
+ }
+ }
+
+ final Specification merged =
+ mergeInSections(specification, sections);
+ results.add(merged);
+ //Reset list of sections
+ sections.clear();
+ }
+
+ return results;
+ }
+
+ /**
+ * Test if two specifications are equal except for their sections.
+ *
+ * @param specification one specificaiton
+ * @param other the ohter specification
+ * @return true if two specifications are equal except for their
+ * sections, else false
+ */
+ private static boolean isEqual(final Specification specification,
+ final Specification other) {
+ return
+ specification.getSpecificationTitle().equals(other.getSpecificationTitle())
+ && specification.getSpecificationVersion().isEqual(other.getSpecificationVersion())
+ && specification.getSpecificationVendor().equals(other.getSpecificationVendor())
+ && specification.getImplementationTitle().equals(other.getImplementationTitle())
+ && specification.getImplementationVersion().equals(other.getImplementationVersion())
+ && specification.getImplementationVendor().equals(other.getImplementationVendor());
+ }
+
+ /**
+ * Merge the specified sections into specified section and return result.
+ * If no sections to be added then just return original specification.
+ *
+ * @param specification the specification
+ * @param sectionsToAdd the list of sections to merge
+ * @return the merged specification
+ */
+ private static Specification mergeInSections(final Specification specification,
+ final ArrayList sectionsToAdd) {
+ if (0 == sectionsToAdd.size()) {
+ return specification;
+ }
+ sectionsToAdd.addAll(Arrays.asList(specification.getSections()));
+
+ final String[] sections =
+ (String[]) sectionsToAdd.toArray(new String[sectionsToAdd.size()]);
+
+ return new Specification(specification.getSpecificationTitle(),
+ specification.getSpecificationVersion().toString(),
+ specification.getSpecificationVendor(),
+ specification.getImplementationTitle(),
+ specification.getImplementationVersion(),
+ specification.getImplementationVendor(),
+ sections);
+ }
+
+ /**
+ * Trim the supplied string if the string is non-null
+ *
+ * @param value the string to trim or null
+ * @return the trimmed string or null
+ */
+ private static String getTrimmedString(final String value) {
+ return value == null ? null : value.trim();
+ }
+
+ /**
+ * Extract an Package Specification from Attributes.
+ *
+ * @param attributes Attributes to searched
+ * @return the new Specification object, or null
+ */
+ private static Specification getSpecification(final String section,
+ final Attributes attributes)
+ throws ParseException {
+ //WARNING: We trim the values of all the attributes because
+ //Some extension declarations are badly defined (ie have spaces
+ //after version or vendor)
+ final String name
+ = getTrimmedString(attributes.getValue(SPECIFICATION_TITLE));
+ if (null == name) {
+ return null;
+ }
+
+ final String specVendor
+ = getTrimmedString(attributes.getValue(SPECIFICATION_VENDOR));
+ if (null == specVendor) {
+ throw new ParseException(MISSING + SPECIFICATION_VENDOR, 0);
+ }
+
+ final String specVersion
+ = getTrimmedString(attributes.getValue(SPECIFICATION_VERSION));
+ if (null == specVersion) {
+ throw new ParseException(MISSING + SPECIFICATION_VERSION, 0);
+ }
+
+ final String impTitle
+ = getTrimmedString(attributes.getValue(IMPLEMENTATION_TITLE));
+ if (null == impTitle) {
+ throw new ParseException(MISSING + IMPLEMENTATION_TITLE, 0);
+ }
+
+ final String impVersion
+ = getTrimmedString(attributes.getValue(IMPLEMENTATION_VERSION));
+ if (null == impVersion) {
+ throw new ParseException(MISSING + IMPLEMENTATION_VERSION, 0);
+ }
+
+ final String impVendor
+ = getTrimmedString(attributes.getValue(IMPLEMENTATION_VENDOR));
+ if (null == impVendor) {
+ throw new ParseException(MISSING + IMPLEMENTATION_VENDOR, 0);
+ }
+
+ return new Specification(name, specVersion, specVendor,
+ impTitle, impVersion, impVendor,
+ new String[]{section});
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/extension/resolvers/AntResolver.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/extension/resolvers/AntResolver.java
new file mode 100644
index 00000000..6284679f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/extension/resolvers/AntResolver.java
@@ -0,0 +1,117 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.extension.resolvers;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.Ant;
+import org.apache.tools.ant.taskdefs.optional.extension.Extension;
+import org.apache.tools.ant.taskdefs.optional.extension.ExtensionResolver;
+
+/**
+ * Resolver that just returns s specified location.
+ *
+ */
+public class AntResolver implements ExtensionResolver {
+ private File antfile;
+ private File destfile;
+ private String target;
+
+ /**
+ * Sets the ant file
+ * @param antfile the ant file to set
+ */
+ public void setAntfile(final File antfile) {
+ this.antfile = antfile;
+ }
+
+ /**
+ * Sets the destination file
+ * @param destfile the destination file
+ */
+ public void setDestfile(final File destfile) {
+ this.destfile = destfile;
+ }
+
+ /**
+ * Sets the target
+ * @param target the target
+ */
+ public void setTarget(final String target) {
+ this.target = target;
+ }
+
+ /**
+ * Returns the resolved file
+ * @param extension the extension
+ * @param project the project
+ * @return the file resolved
+ * @throws BuildException if the file cannot be resolved
+ */
+ public File resolve(final Extension extension,
+ final Project project) throws BuildException {
+ validate();
+
+ final Ant ant = new Ant();
+ ant.setProject(project);
+ ant.setInheritAll(false);
+ ant.setAntfile(antfile.getName());
+
+ try {
+ final File dir =
+ antfile.getParentFile().getCanonicalFile();
+ ant.setDir(dir);
+ } catch (final IOException ioe) {
+ throw new BuildException(ioe.getMessage(), ioe);
+ }
+
+ if (null != target) {
+ ant.setTarget(target);
+ }
+
+ ant.execute();
+
+ return destfile;
+ }
+
+ /*
+ * Validates URL
+ */
+ private void validate() {
+ if (null == antfile) {
+ final String message = "Must specify Buildfile";
+ throw new BuildException(message);
+ }
+
+ if (null == destfile) {
+ final String message = "Must specify destination file";
+ throw new BuildException(message);
+ }
+ }
+
+ /**
+ * Returns a string representation
+ * @return the string representation
+ */
+ public String toString() {
+ return "Ant[" + antfile + "==>" + destfile + "]";
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/extension/resolvers/LocationResolver.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/extension/resolvers/LocationResolver.java
new file mode 100644
index 00000000..e2fec022
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/extension/resolvers/LocationResolver.java
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.extension.resolvers;
+
+import java.io.File;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.optional.extension.Extension;
+import org.apache.tools.ant.taskdefs.optional.extension.ExtensionResolver;
+
+/**
+ * Resolver that just returns s specified location.
+ *
+ */
+public class LocationResolver implements ExtensionResolver {
+ private String location;
+
+ /**
+ * Sets the location for this resolver
+ * @param location the location
+ */
+ public void setLocation(final String location) {
+ this.location = location;
+ }
+
+ /**
+ * Returns the resolved file
+ * @param extension the extension
+ * @param project the project
+ * @return the file resolved
+ * @throws BuildException if no location is set
+ */
+ public File resolve(final Extension extension,
+ final Project project) throws BuildException {
+ if (null == location) {
+ final String message = "No location specified for resolver";
+ throw new BuildException(message);
+ }
+
+ return project.resolveFile(location);
+ }
+ /**
+ * Returns a string representation of the Location
+ * @return the string representation
+ */
+ public String toString() {
+ return "Location[" + location + "]";
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/extension/resolvers/URLResolver.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/extension/resolvers/URLResolver.java
new file mode 100644
index 00000000..d693b899
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/extension/resolvers/URLResolver.java
@@ -0,0 +1,133 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.extension.resolvers;
+
+import java.io.File;
+import java.net.URL;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.Get;
+import org.apache.tools.ant.taskdefs.optional.extension.Extension;
+import org.apache.tools.ant.taskdefs.optional.extension.ExtensionResolver;
+
+/**
+ * Resolver that just returns s specified location.
+ *
+ */
+public class URLResolver implements ExtensionResolver {
+ private File destfile;
+ private File destdir;
+ private URL url;
+
+ /**
+ * Sets the URL
+ * @param url the url
+ */
+ public void setUrl(final URL url) {
+ this.url = url;
+ }
+
+ /**
+ * Sets the destination file
+ * @param destfile the destination file
+ */
+ public void setDestfile(final File destfile) {
+ this.destfile = destfile;
+ }
+
+ /**
+ * Sets the destination directory
+ * @param destdir the destination directory
+ */
+ public void setDestdir(final File destdir) {
+ this.destdir = destdir;
+ }
+
+ /**
+ * Returns the file resolved from URL and directory
+ * @param extension the extension
+ * @param project the project
+ * @return file the file resolved
+ * @throws BuildException if the URL is invalid
+ */
+ public File resolve(final Extension extension,
+ final Project project) throws BuildException {
+ validate();
+
+ final File file = getDest();
+
+ final Get get = new Get();
+ get.setProject(project);
+ get.setDest(file);
+ get.setSrc(url);
+ get.execute();
+
+ return file;
+ }
+
+ /*
+ * Gets the destination file
+ */
+ private File getDest() {
+ File result;
+ if (null != destfile) {
+ result = destfile;
+ } else {
+ final String file = url.getFile();
+ String filename;
+ if (null == file || file.length() <= 1) {
+ filename = "default.file";
+ } else {
+ int index = file.lastIndexOf('/');
+ if (-1 == index) {
+ index = 0;
+ }
+ filename = file.substring(index);
+ }
+ result = new File(destdir, filename);
+ }
+ return result;
+ }
+
+ /*
+ * Validates URL
+ */
+ private void validate() {
+ if (null == url) {
+ final String message = "Must specify URL";
+ throw new BuildException(message);
+ }
+
+ if (null == destdir && null == destfile) {
+ final String message = "Must specify destination file or directory";
+ throw new BuildException(message);
+ } else if (null != destdir && null != destfile) {
+ final String message = "Must not specify both destination file or directory";
+ throw new BuildException(message);
+ }
+ }
+
+ /**
+ * Returns a string representation of the URL
+ * @return the string representation
+ */
+ public String toString() {
+ return "URL[" + url + "]";
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/i18n/Translate.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/i18n/Translate.java
new file mode 100644
index 00000000..82731fe9
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/i18n/Translate.java
@@ -0,0 +1,632 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.i18n;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.util.Hashtable;
+import java.util.Locale;
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.DirectoryScanner;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.MatchingTask;
+import org.apache.tools.ant.types.FileSet;
+import org.apache.tools.ant.util.FileUtils;
+import org.apache.tools.ant.util.LineTokenizer;
+
+/**
+ * Translates text embedded in files using Resource Bundle files.
+ * Since ant 1.6 preserves line endings
+ *
+ */
+public class Translate extends MatchingTask {
+ /**
+ * search a bundle matching the specified language, the country and the variant
+ */
+ private static final int BUNDLE_SPECIFIED_LANGUAGE_COUNTRY_VARIANT = 0;
+ /**
+ * search a bundle matching the specified language, and the country
+ */
+ private static final int BUNDLE_SPECIFIED_LANGUAGE_COUNTRY = 1;
+ /**
+ * search a bundle matching the specified language only
+ */
+ private static final int BUNDLE_SPECIFIED_LANGUAGE = 2;
+ /**
+ * search a bundle matching nothing special
+ */
+ private static final int BUNDLE_NOMATCH = 3;
+ /**
+ * search a bundle matching the language, the country and the variant
+ * of the current locale of the computer
+ */
+ private static final int BUNDLE_DEFAULT_LANGUAGE_COUNTRY_VARIANT = 4;
+ /**
+ * search a bundle matching the language, and the country
+ * of the current locale of the computer
+ */
+ private static final int BUNDLE_DEFAULT_LANGUAGE_COUNTRY = 5;
+ /**
+ * search a bundle matching the language only
+ * of the current locale of the computer
+ */
+ private static final int BUNDLE_DEFAULT_LANGUAGE = 6;
+ /**
+ * number of possibilities for the search
+ */
+ private static final int BUNDLE_MAX_ALTERNATIVES = BUNDLE_DEFAULT_LANGUAGE + 1;
+ /**
+ * Family name of resource bundle
+ */
+ private String bundle;
+
+ /**
+ * Locale specific language of the resource bundle
+ */
+ private String bundleLanguage;
+
+ /**
+ * Locale specific country of the resource bundle
+ */
+ private String bundleCountry;
+
+ /**
+ * Locale specific variant of the resource bundle
+ */
+ private String bundleVariant;
+
+ /**
+ * Destination directory
+ */
+ private File toDir;
+
+ /**
+ * Source file encoding scheme
+ */
+ private String srcEncoding;
+
+ /**
+ * Destination file encoding scheme
+ */
+ private String destEncoding;
+
+ /**
+ * Resource Bundle file encoding scheme, defaults to srcEncoding
+ */
+ private String bundleEncoding;
+
+ /**
+ * Starting token to identify keys
+ */
+ private String startToken;
+
+ /**
+ * Ending token to identify keys
+ */
+ private String endToken;
+
+ /**
+ * Whether or not to create a new destination file.
+ * Defaults to <code>false</code>.
+ */
+ private boolean forceOverwrite;
+
+ /**
+ * Vector to hold source file sets.
+ */
+ private Vector filesets = new Vector();
+
+ /**
+ * Holds key value pairs loaded from resource bundle file
+ */
+ private Hashtable resourceMap = new Hashtable();
+ /**
+
+ * Used to resolve file names.
+ */
+ private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+
+ /**
+ * Last Modified Timestamp of resource bundle file being used.
+ */
+ private long[] bundleLastModified = new long[BUNDLE_MAX_ALTERNATIVES];
+
+ /**
+ * Last Modified Timestamp of source file being used.
+ */
+ private long srcLastModified;
+
+ /**
+ * Last Modified Timestamp of destination file being used.
+ */
+ private long destLastModified;
+
+ /**
+ * Has at least one file from the bundle been loaded?
+ */
+ private boolean loaded = false;
+
+ /**
+ * Sets Family name of resource bundle; required.
+ * @param bundle family name of resource bundle
+ */
+ public void setBundle(String bundle) {
+ this.bundle = bundle;
+ }
+
+ /**
+ * Sets locale specific language of resource bundle; optional.
+ * @param bundleLanguage language of the bundle
+ */
+ public void setBundleLanguage(String bundleLanguage) {
+ this.bundleLanguage = bundleLanguage;
+ }
+
+ /**
+ * Sets locale specific country of resource bundle; optional.
+ * @param bundleCountry country of the bundle
+ */
+ public void setBundleCountry(String bundleCountry) {
+ this.bundleCountry = bundleCountry;
+ }
+
+ /**
+ * Sets locale specific variant of resource bundle; optional.
+ * @param bundleVariant locale variant of resource bundle
+ */
+ public void setBundleVariant(String bundleVariant) {
+ this.bundleVariant = bundleVariant;
+ }
+
+ /**
+ * Sets Destination directory; required.
+ * @param toDir destination directory
+ */
+ public void setToDir(File toDir) {
+ this.toDir = toDir;
+ }
+
+ /**
+ * Sets starting token to identify keys; required.
+ * @param startToken starting token to identify keys
+ */
+ public void setStartToken(String startToken) {
+ this.startToken = startToken;
+ }
+
+ /**
+ * Sets ending token to identify keys; required.
+ * @param endToken ending token to identify keys
+ */
+ public void setEndToken(String endToken) {
+ this.endToken = endToken;
+ }
+
+ /**
+ * Sets source file encoding scheme; optional,
+ * defaults to encoding of local system.
+ * @param srcEncoding source file encoding
+ */
+ public void setSrcEncoding(String srcEncoding) {
+ this.srcEncoding = srcEncoding;
+ }
+
+ /**
+ * Sets destination file encoding scheme; optional. Defaults to source file
+ * encoding
+ * @param destEncoding destination file encoding scheme
+ */
+ public void setDestEncoding(String destEncoding) {
+ this.destEncoding = destEncoding;
+ }
+
+ /**
+ * Sets Resource Bundle file encoding scheme; optional. Defaults to source file
+ * encoding
+ * @param bundleEncoding bundle file encoding scheme
+ */
+ public void setBundleEncoding(String bundleEncoding) {
+ this.bundleEncoding = bundleEncoding;
+ }
+
+ /**
+ * Whether or not to overwrite existing file irrespective of
+ * whether it is newer than the source file as well as the
+ * resource bundle file.
+ * Defaults to false.
+ * @param forceOverwrite whether or not to overwrite existing files
+ */
+ public void setForceOverwrite(boolean forceOverwrite) {
+ this.forceOverwrite = forceOverwrite;
+ }
+
+ /**
+ * Adds a set of files to translate as a nested fileset element.
+ * @param set the fileset to be added
+ */
+ public void addFileset(FileSet set) {
+ filesets.addElement(set);
+ }
+
+ /**
+ * Check attributes values, load resource map and translate
+ * @throws BuildException if the required attributes are not set
+ * Required : <ul>
+ * <li>bundle</li>
+ * <li>starttoken</li>
+ * <li>endtoken</li>
+ * </ul>
+ */
+ public void execute() throws BuildException {
+ if (bundle == null) {
+ throw new BuildException("The bundle attribute must be set.",
+ getLocation());
+ }
+
+ if (startToken == null) {
+ throw new BuildException("The starttoken attribute must be set.",
+ getLocation());
+ }
+
+ if (endToken == null) {
+ throw new BuildException("The endtoken attribute must be set.",
+ getLocation());
+ }
+
+ if (bundleLanguage == null) {
+ Locale l = Locale.getDefault();
+ bundleLanguage = l.getLanguage();
+ }
+
+ if (bundleCountry == null) {
+ bundleCountry = Locale.getDefault().getCountry();
+ }
+
+ if (bundleVariant == null) {
+ Locale l = new Locale(bundleLanguage, bundleCountry);
+ bundleVariant = l.getVariant();
+ }
+
+ if (toDir == null) {
+ throw new BuildException("The todir attribute must be set.",
+ getLocation());
+ }
+
+ if (!toDir.exists()) {
+ toDir.mkdirs();
+ } else if (toDir.isFile()) {
+ throw new BuildException(toDir + " is not a directory");
+ }
+
+ if (srcEncoding == null) {
+ srcEncoding = System.getProperty("file.encoding");
+ }
+
+ if (destEncoding == null) {
+ destEncoding = srcEncoding;
+ }
+
+ if (bundleEncoding == null) {
+ bundleEncoding = srcEncoding;
+ }
+
+ loadResourceMaps();
+
+ translate();
+ }
+
+ /**
+ * Load resource maps based on resource bundle encoding scheme.
+ * The resource bundle lookup searches for resource files with various
+ * suffixes on the basis of (1) the desired locale and (2) the default
+ * locale (basebundlename), in the following order from lower-level
+ * (more specific) to parent-level (less specific):
+ *
+ * basebundlename + "_" + language1 + "_" + country1 + "_" + variant1
+ * basebundlename + "_" + language1 + "_" + country1
+ * basebundlename + "_" + language1
+ * basebundlename
+ * basebundlename + "_" + language2 + "_" + country2 + "_" + variant2
+ * basebundlename + "_" + language2 + "_" + country2
+ * basebundlename + "_" + language2
+ *
+ * To the generated name, a ".properties" string is appeneded and
+ * once this file is located, it is treated just like a properties file
+ * but with bundle encoding also considered while loading.
+ */
+ private void loadResourceMaps() throws BuildException {
+ Locale locale = new Locale(bundleLanguage,
+ bundleCountry,
+ bundleVariant);
+ String language = locale.getLanguage().length() > 0
+ ? "_" + locale.getLanguage() : "";
+ String country = locale.getCountry().length() > 0
+ ? "_" + locale.getCountry() : "";
+ String variant = locale.getVariant().length() > 0
+ ? "_" + locale.getVariant() : "";
+ String bundleFile = bundle + language + country + variant;
+ processBundle(bundleFile, BUNDLE_SPECIFIED_LANGUAGE_COUNTRY_VARIANT, false);
+
+ bundleFile = bundle + language + country;
+ processBundle(bundleFile, BUNDLE_SPECIFIED_LANGUAGE_COUNTRY, false);
+
+ bundleFile = bundle + language;
+ processBundle(bundleFile, BUNDLE_SPECIFIED_LANGUAGE, false);
+
+ bundleFile = bundle;
+ processBundle(bundleFile, BUNDLE_NOMATCH, false);
+
+ //Load default locale bundle files
+ //using default file encoding scheme.
+ locale = Locale.getDefault();
+
+ language = locale.getLanguage().length() > 0
+ ? "_" + locale.getLanguage() : "";
+ country = locale.getCountry().length() > 0
+ ? "_" + locale.getCountry() : "";
+ variant = locale.getVariant().length() > 0
+ ? "_" + locale.getVariant() : "";
+ bundleEncoding = System.getProperty("file.encoding");
+
+ bundleFile = bundle + language + country + variant;
+ processBundle(bundleFile, BUNDLE_DEFAULT_LANGUAGE_COUNTRY_VARIANT, false);
+
+ bundleFile = bundle + language + country;
+ processBundle(bundleFile, BUNDLE_DEFAULT_LANGUAGE_COUNTRY, false);
+
+ bundleFile = bundle + language;
+ processBundle(bundleFile, BUNDLE_DEFAULT_LANGUAGE, true);
+ }
+
+ /**
+ * Process each file that makes up this bundle.
+ */
+ private void processBundle(final String bundleFile, final int i,
+ final boolean checkLoaded) throws BuildException {
+ final File propsFile = getProject().resolveFile(bundleFile + ".properties");
+ FileInputStream ins = null;
+ try {
+ ins = new FileInputStream(propsFile);
+ loaded = true;
+ bundleLastModified[i] = propsFile.lastModified();
+ log("Using " + propsFile, Project.MSG_DEBUG);
+ loadResourceMap(ins);
+ } catch (IOException ioe) {
+ log(propsFile + " not found.", Project.MSG_DEBUG);
+ //if all resource files associated with this bundle
+ //have been scanned for and still not able to
+ //find a single resrouce file, throw exception
+ if (!loaded && checkLoaded) {
+ throw new BuildException(ioe.getMessage(), getLocation());
+ }
+ }
+ }
+
+ /**
+ * Load resourceMap with key value pairs. Values of existing keys
+ * are not overwritten. Bundle's encoding scheme is used.
+ */
+ private void loadResourceMap(FileInputStream ins) throws BuildException {
+ try {
+ BufferedReader in = null;
+ InputStreamReader isr = new InputStreamReader(ins, bundleEncoding);
+ in = new BufferedReader(isr);
+ String line = null;
+ while ((line = in.readLine()) != null) {
+ //So long as the line isn't empty and isn't a comment...
+ if (line.trim().length() > 1 && '#' != line.charAt(0) && '!' != line.charAt(0)) {
+ //Legal Key-Value separators are :, = and white space.
+ int sepIndex = line.indexOf('=');
+ if (-1 == sepIndex) {
+ sepIndex = line.indexOf(':');
+ }
+ if (-1 == sepIndex) {
+ for (int k = 0; k < line.length(); k++) {
+ if (Character.isSpaceChar(line.charAt(k))) {
+ sepIndex = k;
+ break;
+ }
+ }
+ }
+ //Only if we do have a key is there going to be a value
+ if (-1 != sepIndex) {
+ String key = line.substring(0, sepIndex).trim();
+ String value = line.substring(sepIndex + 1).trim();
+ //Handle line continuations, if any
+ while (value.endsWith("\\")) {
+ value = value.substring(0, value.length() - 1);
+ line = in.readLine();
+ if (line != null) {
+ value = value + line.trim();
+ } else {
+ break;
+ }
+ }
+ if (key.length() > 0) {
+ //Has key already been loaded into resourceMap?
+ if (resourceMap.get(key) == null) {
+ resourceMap.put(key, value);
+ }
+ }
+ }
+ }
+ }
+ if (in != null) {
+ in.close();
+ }
+ } catch (IOException ioe) {
+ throw new BuildException(ioe.getMessage(), getLocation());
+ }
+ }
+
+ /**
+ * Reads source file line by line using the source encoding and
+ * searches for keys that are sandwiched between the startToken
+ * and endToken. The values for these keys are looked up from
+ * the hashtable and substituted. If the hashtable doesn't
+ * contain the key, they key itself is used as the value.
+ * Detination files and directories are created as needed.
+ * The destination file is overwritten only if
+ * the forceoverwritten attribute is set to true if
+ * the source file or any associated bundle resource file is
+ * newer than the destination file.
+ */
+ private void translate() throws BuildException {
+ int filesProcessed = 0;
+ final int size = filesets.size();
+ for (int i = 0; i < size; i++) {
+ FileSet fs = (FileSet) filesets.elementAt(i);
+ DirectoryScanner ds = fs.getDirectoryScanner(getProject());
+ String[] srcFiles = ds.getIncludedFiles();
+ for (int j = 0; j < srcFiles.length; j++) {
+ try {
+ File dest = FILE_UTILS.resolveFile(toDir, srcFiles[j]);
+ //Make sure parent dirs exist, else, create them.
+ try {
+ File destDir = new File(dest.getParent());
+ if (!destDir.exists()) {
+ destDir.mkdirs();
+ }
+ } catch (Exception e) {
+ log("Exception occurred while trying to check/create "
+ + " parent directory. " + e.getMessage(),
+ Project.MSG_DEBUG);
+ }
+ destLastModified = dest.lastModified();
+ File src = FILE_UTILS.resolveFile(ds.getBasedir(), srcFiles[j]);
+ srcLastModified = src.lastModified();
+ //Check to see if dest file has to be recreated
+ boolean needsWork = forceOverwrite
+ || destLastModified < srcLastModified;
+ if (!needsWork) {
+ for (int icounter = 0; icounter < BUNDLE_MAX_ALTERNATIVES; icounter++) {
+ needsWork = (destLastModified < bundleLastModified[icounter]);
+ if (needsWork) {
+ break;
+ }
+ }
+ }
+ if (needsWork) {
+ log("Processing " + srcFiles[j],
+ Project.MSG_DEBUG);
+ translateOneFile(src, dest);
+ ++filesProcessed;
+ } else {
+ log("Skipping " + srcFiles[j]
+ + " as destination file is up to date",
+ Project.MSG_VERBOSE);
+ }
+ } catch (IOException ioe) {
+ throw new BuildException(ioe.getMessage(), getLocation());
+ }
+ }
+ }
+ log("Translation performed on " + filesProcessed + " file(s).", Project.MSG_DEBUG);
+ }
+
+ private void translateOneFile(File src, File dest) throws IOException {
+ BufferedWriter out = null;
+ BufferedReader in = null;
+ try {
+ FileOutputStream fos = new FileOutputStream(dest);
+ out = new BufferedWriter(new OutputStreamWriter(fos, destEncoding));
+ FileInputStream fis = new FileInputStream(src);
+ in = new BufferedReader(new InputStreamReader(fis, srcEncoding));
+ String line;
+ LineTokenizer lineTokenizer = new LineTokenizer();
+ lineTokenizer.setIncludeDelims(true);
+ line = lineTokenizer.getToken(in);
+ while ((line) != null) {
+ // 2003-02-21 new replace algorithm by tbee (tbee@tbee.org)
+ // because it wasn't able to replace something like "@aaa;@bbb;"
+
+ // is there a startToken
+ // and there is still stuff following the startToken
+ int startIndex = line.indexOf(startToken);
+ while (startIndex >= 0
+ && (startIndex + startToken.length()) <= line.length()) {
+ // the new value, this needs to be here
+ // because it is required to calculate the next position to
+ // search from at the end of the loop
+ String replace = null;
+
+ // we found a starttoken, is there an endtoken following?
+ // start at token+tokenlength because start and end
+ // token may be identical
+ int endIndex = line.indexOf(endToken, startIndex
+ + startToken.length());
+ if (endIndex < 0) {
+ startIndex += 1;
+ } else {
+ // grab the token
+ String token = line.substring(startIndex
+ + startToken.length(),
+ endIndex);
+
+ // If there is a white space or = or :, then
+ // it isn't to be treated as a valid key.
+ boolean validToken = true;
+ for (int k = 0; k < token.length() && validToken; k++) {
+ char c = token.charAt(k);
+ if (c == ':' || c == '='
+ || Character.isSpaceChar(c)) {
+ validToken = false;
+ }
+ }
+ if (!validToken) {
+ startIndex += 1;
+ } else {
+ // find the replace string
+ if (resourceMap.containsKey(token)) {
+ replace = (String) resourceMap.get(token);
+ } else {
+ log("Replacement string missing for: " + token,
+ Project.MSG_VERBOSE);
+ replace = startToken + token + endToken;
+ }
+
+
+ // generate the new line
+ line = line.substring(0, startIndex) + replace
+ + line.substring(endIndex + endToken.length());
+
+ // set start position for next search
+ startIndex += replace.length();
+ }
+ }
+
+ // find next starttoken
+ startIndex = line.indexOf(startToken, startIndex);
+ }
+ out.write(line);
+ line = lineTokenizer.getToken(in);
+ }
+ } finally {
+ FileUtils.close(in);
+ FileUtils.close(out);
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/image/Image.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/image/Image.java
new file mode 100644
index 00000000..162e3756
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/image/Image.java
@@ -0,0 +1,421 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.image;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.Locale;
+import java.util.Vector;
+
+import javax.media.jai.JAI;
+import javax.media.jai.PlanarImage;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.DirectoryScanner;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.MatchingTask;
+import org.apache.tools.ant.types.FileSet;
+import org.apache.tools.ant.types.Mapper;
+import org.apache.tools.ant.types.optional.image.Draw;
+import org.apache.tools.ant.types.optional.image.ImageOperation;
+import org.apache.tools.ant.types.optional.image.Rotate;
+import org.apache.tools.ant.types.optional.image.Scale;
+import org.apache.tools.ant.types.optional.image.TransformOperation;
+import org.apache.tools.ant.util.FileNameMapper;
+import org.apache.tools.ant.util.FileUtils;
+import org.apache.tools.ant.util.IdentityMapper;
+
+import com.sun.media.jai.codec.FileSeekableStream;
+
+/**
+ * A MatchingTask which relies on <a
+ * href="http://java.sun.com/products/java-media/jai">JAI (Java
+ * Advanced Imaging)</a> to perform image manipulation operations on
+ * existing images. The operations are represented as ImageOperation
+ * DataType objects. The operations are arranged to conform to the
+ * Chaining Model of JAI. Check out the <a
+ * href="http://java.sun.com/products/java-media/jai/forDevelopers/jai1_0_1guide-unc/">
+ * JAI Programming Guide</a>.
+ *
+ * @see org.apache.tools.ant.types.optional.image.ImageOperation
+ * @see org.apache.tools.ant.types.DataType
+ */
+public class Image extends MatchingTask {
+ // CheckStyle:VisibilityModifier OFF - bc
+ protected Vector instructions = new Vector();
+ protected boolean overwrite = false;
+ protected Vector filesets = new Vector();
+ protected File srcDir = null;
+ protected File destDir = null;
+
+ // CheckStyle:MemberNameCheck OFF - bc
+
+ //cannot remove underscores due to protected visibility >:(
+ protected String str_encoding = "JPEG";
+ protected boolean garbage_collect = false;
+
+ private boolean failonerror = true;
+
+ // CheckStyle:MemberNameCheck ON
+
+ // CheckStyle:VisibilityModifier ON
+
+ private Mapper mapperElement = null;
+
+ /**
+ * Add a set of files to be deleted.
+ * @param set the FileSet to add.
+ */
+ public void addFileset(FileSet set) {
+ filesets.addElement(set);
+ }
+
+ /**
+ * Set whether to fail on error.
+ * If false, note errors to the output but keep going.
+ * @param failonerror true or false.
+ */
+ public void setFailOnError(boolean failonerror) {
+ this.failonerror = failonerror;
+ }
+
+ /**
+ * Set the source dir to find the image files.
+ * @param srcDir the directory in which the image files reside.
+ */
+ public void setSrcdir(File srcDir) {
+ this.srcDir = srcDir;
+ }
+
+ /**
+ * Set the image encoding type. <a
+ * href="http://java.sun.com/products/java-media/jai/forDevelopers/jai1_0_1guide-unc/Encode.doc.html#56610">
+ * See this table in the JAI Programming Guide</a>.
+ * @param encoding the String image encoding.
+ */
+ public void setEncoding(String encoding) {
+ str_encoding = encoding;
+ }
+
+ /**
+ * Set whether to overwrite a file if there is a naming conflict.
+ * @param overwrite whether to overwrite.
+ */
+ public void setOverwrite(boolean overwrite) {
+ this.overwrite = overwrite;
+ }
+
+ /**
+ * Set whether to invoke Garbage Collection after each image processed.
+ * Defaults to false.
+ * @param gc whether to invoke the garbage collector.
+ */
+ public void setGc(boolean gc) {
+ garbage_collect = gc;
+ }
+
+ /**
+ * Set the destination directory for manipulated images.
+ * @param destDir The destination directory.
+ */
+ public void setDestDir(File destDir) {
+ this.destDir = destDir;
+ }
+
+ /**
+ * Add an ImageOperation to chain.
+ * @param instr The ImageOperation to append to the chain.
+ */
+ public void addImageOperation(ImageOperation instr) {
+ instructions.add(instr);
+ }
+
+ /**
+ * Add a Rotate ImageOperation to the chain.
+ * @param instr The Rotate operation to add to the chain.
+ * @see org.apache.tools.ant.types.optional.image.Rotate
+ */
+ public void addRotate(Rotate instr) {
+ instructions.add(instr);
+ }
+
+ /**
+ * Add a Scale ImageOperation to the chain.
+ * @param instr The Scale operation to add to the chain.
+ * @see org.apache.tools.ant.types.optional.image.Scale
+ */
+ public void addScale(Scale instr) {
+ instructions.add(instr);
+ }
+
+ /**
+ * Add a Draw ImageOperation to the chain. DrawOperation
+ * DataType objects can be nested inside the Draw object.
+ * @param instr The Draw operation to add to the chain.
+ * @see org.apache.tools.ant.types.optional.image.Draw
+ * @see org.apache.tools.ant.types.optional.image.DrawOperation
+ */
+ public void addDraw(Draw instr) {
+ instructions.add(instr);
+ }
+
+ /**
+ * Add an ImageOperation to chain.
+ * @param instr The ImageOperation to append to the chain.
+ * @since Ant 1.7
+ */
+ public void add(ImageOperation instr) {
+ addImageOperation(instr);
+ }
+
+ /**
+ * Defines the mapper to map source to destination files.
+ * @return a mapper to be configured
+ * @exception BuildException if more than one mapper is defined
+ * @since Ant 1.8.0
+ */
+ public Mapper createMapper() throws BuildException {
+ if (mapperElement != null) {
+ throw new BuildException("Cannot define more than one mapper",
+ getLocation());
+ }
+ mapperElement = new Mapper(getProject());
+ return mapperElement;
+ }
+
+ /**
+ * Add a nested filenamemapper.
+ * @param fileNameMapper the mapper to add.
+ * @since Ant 1.8.0
+ */
+ public void add(FileNameMapper fileNameMapper) {
+ createMapper().add(fileNameMapper);
+ }
+
+ /**
+ * Executes all the chained ImageOperations on the files inside
+ * the directory.
+ * @since Ant 1.8.0
+ */
+ public int processDir(final File srcDir, final String[] srcNames,
+ final File dstDir, final FileNameMapper mapper) {
+ int writeCount = 0;
+
+ for (int i = 0; i < srcNames.length; ++i) {
+ final String srcName = srcNames[i];
+ final File srcFile = new File(srcDir, srcName).getAbsoluteFile();
+
+ final String[] dstNames = mapper.mapFileName(srcName);
+ if (dstNames == null) {
+ log(srcFile + " skipped, don't know how to handle it",
+ Project.MSG_VERBOSE);
+ continue;
+ }
+
+ for (int j = 0; j < dstNames.length; ++j){
+
+ final String dstName = dstNames[j];
+ final File dstFile = new File(dstDir, dstName).getAbsoluteFile();
+
+ if (dstFile.exists()){
+ // avoid overwriting unless necessary
+ if(!overwrite
+ && srcFile.lastModified() <= dstFile.lastModified()) {
+
+ log(srcFile + " omitted as " + dstFile
+ + " is up to date.", Project.MSG_VERBOSE);
+
+ // don't overwrite the file
+ continue;
+ }
+
+ // avoid extra work while overwriting
+ if (!srcFile.equals(dstFile)){
+ dstFile.delete();
+ }
+ }
+ processFile(srcFile, dstFile);
+ ++writeCount;
+ }
+ }
+
+ // run the garbage collector if wanted
+ if (garbage_collect) {
+ System.gc();
+ }
+
+ return writeCount;
+ }
+
+ /**
+ * Executes all the chained ImageOperations on the file
+ * specified.
+ * @param file The file to be processed.
+ * @deprecated this method isn't used anymore
+ */
+ public void processFile(File file) {
+ processFile(file, new File(destDir == null
+ ? srcDir : destDir, file.getName()));
+ }
+
+ /**
+ * Executes all the chained ImageOperations on the file
+ * specified.
+ * @param file The file to be processed.
+ * @param newFile The file to write to.
+ * @since Ant 1.8.0
+ */
+ public void processFile(File file, File newFile) {
+ try {
+ log("Processing File: " + file.getAbsolutePath());
+
+ FileSeekableStream input = null;
+ PlanarImage image = null;
+ try {
+ input = new FileSeekableStream(file);
+ image = JAI.create("stream", input);
+ final int size = instructions.size();
+ for (int i = 0; i < size; i++) {
+ Object instr = instructions.elementAt(i);
+ if (instr instanceof TransformOperation) {
+ image = ((TransformOperation) instr)
+ .executeTransformOperation(image);
+ } else {
+ log("Not a TransformOperation: " + instr);
+ }
+ }
+ } finally {
+ FileUtils.close(input);
+ }
+
+ File dstParent = newFile.getParentFile();
+ if (!dstParent.isDirectory()
+ && !(dstParent.mkdirs() || dstParent.isDirectory())) {
+ throw new BuildException("Failed to create parent directory "
+ + dstParent);
+ }
+
+ if ((overwrite && newFile.exists()) && (!newFile.equals(file))) {
+ newFile.delete();
+ }
+
+ FileOutputStream stream = null;
+ try {
+ stream = new FileOutputStream(newFile);
+
+ JAI.create("encode", image, stream,
+ str_encoding.toUpperCase(Locale.ENGLISH),
+ null);
+ stream.flush();
+ } finally {
+ FileUtils.close(stream);
+ }
+ } catch (IOException err) {
+ if (!file.equals(newFile)){
+ newFile.delete();
+ }
+ if (!failonerror) {
+ log("Error processing file: " + err);
+ } else {
+ throw new BuildException(err);
+ }
+ } catch (java.lang.RuntimeException rerr) {
+ if (!file.equals(newFile)){
+ newFile.delete();
+ }
+ if (!failonerror) {
+ log("Error processing file: " + rerr);
+ } else {
+ throw new BuildException(rerr);
+ }
+ }
+ }
+
+ /**
+ * Executes the Task.
+ * @throws BuildException on error.
+ */
+ public void execute() throws BuildException {
+
+ validateAttributes();
+
+ try {
+ File dest = destDir != null ? destDir : srcDir;
+
+ int writeCount = 0;
+
+ // build mapper
+ final FileNameMapper mapper;
+ if (mapperElement==null){
+ mapper = new IdentityMapper();
+ } else {
+ mapper = mapperElement.getImplementation();
+ }
+
+ // deal with specified srcDir
+ if (srcDir != null) {
+ final DirectoryScanner ds = super.getDirectoryScanner(srcDir);
+
+ final String[] files = ds.getIncludedFiles();
+ writeCount += processDir(srcDir, files, dest, mapper);
+ }
+ // deal with the filesets
+ final int size = filesets.size();
+ for (int i = 0; i < size; i++) {
+ final FileSet fs = (FileSet) filesets.elementAt(i);
+ final DirectoryScanner ds =
+ fs.getDirectoryScanner(getProject());
+ final String[] files = ds.getIncludedFiles();
+ final File fromDir = fs.getDir(getProject());
+ writeCount += processDir(fromDir, files, dest, mapper);
+ }
+
+ if (writeCount>0){
+ log("Processed " + writeCount +
+ (writeCount == 1 ? " image." : " images."));
+ }
+
+ } catch (Exception err) {
+ err.printStackTrace();
+ throw new BuildException(err.getMessage());
+ }
+ }
+
+ /**
+ * Ensure we have a consistent and legal set of attributes, and set
+ * any internal flags necessary based on different combinations
+ * of attributes.
+ * @throws BuildException on error.
+ */
+ protected void validateAttributes() throws BuildException {
+ if (srcDir == null && filesets.size() == 0) {
+ throw new BuildException("Specify at least one source"
+ + "--a srcDir or a fileset.");
+ }
+ if (srcDir == null && destDir == null) {
+ throw new BuildException("Specify the destDir, or the srcDir.");
+ }
+ if (str_encoding.equalsIgnoreCase("jpg")) {
+ str_encoding = "JPEG";
+ } else if (str_encoding.equalsIgnoreCase("tif")) {
+ str_encoding = "TIFF";
+ }
+ }
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/j2ee/AbstractHotDeploymentTool.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/j2ee/AbstractHotDeploymentTool.java
new file mode 100644
index 00000000..fdbde749
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/j2ee/AbstractHotDeploymentTool.java
@@ -0,0 +1,193 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.j2ee;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.types.Path;
+
+/**
+ * Abstract class to support vendor-specific hot deployment tools.
+ * This class will validate boilerplate attributes.
+ *
+ * Subclassing this class for a vendor specific tool involves the
+ * following.
+ * <ol><li>Implement the <code>isActionValid()<code> method to insure the
+ * action supplied as the "action" attribute of ServerDeploy is valid.
+ * <li>Implement the <code>validateAttributes()</code> method to insure
+ * all required attributes are supplied, and are in the correct format.
+ * <li>Add a <code>add&lt;TOOL&gt;</code> method to the ServerDeploy
+ * class. This method will be called when Ant encounters a
+ * <code>add&lt;TOOL&gt;</code> task nested in the
+ * <code>serverdeploy</code> task.
+ * <li>Define the <code>deploy</code> method. This method should perform
+ * whatever task it takes to hot-deploy the component. IE: spawn a JVM and
+ * run class, exec a native executable, run Java code...
+ *
+ * @see org.apache.tools.ant.taskdefs.optional.j2ee.HotDeploymentTool
+ * @see org.apache.tools.ant.taskdefs.optional.j2ee.ServerDeploy
+ */
+public abstract class AbstractHotDeploymentTool implements HotDeploymentTool {
+ /** The parent task **/
+ private ServerDeploy task;
+
+ /** The classpath passed to the JVM on execution. **/
+ private Path classpath;
+
+ /** The username for the deployment server. **/
+ private String userName;
+
+ /** The password for the deployment server. **/
+ private String password;
+
+ /** The address of the deployment server **/
+ private String server;
+
+ /**
+ * Add a classpath as a nested element.
+ * @return A Path object representing the classpath to be used.
+ */
+ public Path createClasspath() {
+ if (classpath == null) {
+ classpath = new Path(task.getProject());
+ }
+ return classpath.createPath();
+ }
+
+ /**
+ * Determines if the "action" attribute defines a valid action.
+ * <p>Subclasses should determine if the action passed in is
+ * supported by the vendor's deployment tool.
+ * <p>Actions may by "deploy", "delete", etc... It all depends
+ * on the tool.
+ * @return true if the "action" attribute is valid, false if not.
+ */
+ protected abstract boolean isActionValid();
+
+ /**
+ * Validates the passed in attributes.
+ * Subclasses should chain to this super-method to insure
+ * validation of boilerplate attributes.
+ * <p>Only the "action" attribute is required in the
+ * base class. Subclasses should check attributes accordingly.
+ * @exception org.apache.tools.ant.BuildException if the attributes are invalid or incomplete.
+ */
+ public void validateAttributes() throws BuildException {
+ if (task.getAction() == null) {
+ throw new BuildException("The \"action\" attribute must be set");
+ }
+
+ if (!isActionValid()) {
+ throw new BuildException("Invalid action \"" + task.getAction() + "\" passed");
+ }
+
+ if (classpath == null) {
+ throw new BuildException("The classpath attribute must be set");
+ }
+ }
+
+ /**
+ * Perform the actual deployment.
+ * It's up to the subclasses to implement the actual behavior.
+ * @exception org.apache.tools.ant.BuildException if the attributes are invalid or incomplete.
+ */
+ public abstract void deploy() throws BuildException;
+
+ /**
+ * Sets the parent task.
+ * @param task a ServerDeploy object representing the parent task.
+ * @ant.attribute ignore="true"
+ */
+ public void setTask(ServerDeploy task) {
+ this.task = task;
+ }
+
+ /**
+ * Returns the task field, a ServerDeploy object.
+ * @return An ServerDeploy representing the parent task.
+ */
+ protected ServerDeploy getTask() {
+ return task;
+ }
+
+ /**
+ * gets the classpath field.
+ * @return A Path representing the "classpath" attribute.
+ */
+ public Path getClasspath() {
+ return classpath;
+ }
+
+ /**
+ * The classpath to be passed to the JVM running the tool;
+ * optional depending upon the tool.
+ * The classpath may also be supplied as a nested element.
+ * @param classpath A Path object representing the "classpath" attribute.
+ */
+ public void setClasspath(Path classpath) {
+ this.classpath = classpath;
+ }
+
+ /**
+ * Returns the userName field.
+ * @return A String representing the "userName" attribute.
+ */
+ public String getUserName() {
+ return userName;
+ }
+
+ /**
+ * The user with privileges to deploy applications to the server; optional.
+ * @param userName A String representing the "userName" attribute.
+ */
+ public void setUserName(String userName) {
+ this.userName = userName;
+ }
+
+ /**
+ * Returns the password field.
+ * @return A String representing the "password" attribute.
+ */
+ public String getPassword() {
+ return password;
+ }
+
+ /**
+ * The password of the user; optional.
+ * @param password A String representing the "password" attribute.
+ */
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ /**
+ * Returns the server field.
+ * @return A String representing the "server" attribute.
+ */
+ public String getServer() {
+ return server;
+ }
+
+ /**
+ * The address or URL for the server where the component will be deployed.
+ * @param server A String representing the "server" attribute.
+ */
+ public void setServer(String server) {
+ this.server = server;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/j2ee/GenericHotDeploymentTool.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/j2ee/GenericHotDeploymentTool.java
new file mode 100644
index 00000000..5a5abbab
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/j2ee/GenericHotDeploymentTool.java
@@ -0,0 +1,140 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.j2ee;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.taskdefs.Java;
+import org.apache.tools.ant.types.Commandline;
+
+/**
+ * A generic tool for J2EE server hot deployment.
+ * <p>The simple implementation spawns a JVM with the supplied
+ * class name, jvm args, and arguments.
+ *
+ * @see org.apache.tools.ant.taskdefs.optional.j2ee.HotDeploymentTool
+ * @see org.apache.tools.ant.taskdefs.optional.j2ee.AbstractHotDeploymentTool
+ * @see org.apache.tools.ant.taskdefs.optional.j2ee.ServerDeploy
+ */
+public class GenericHotDeploymentTool extends AbstractHotDeploymentTool {
+ /** A Java task used to run the deployment tool **/
+ private Java java;
+
+ /** The fully qualified class name of the deployment tool **/
+ private String className;
+
+ /** List of valid actions **/
+ private static final String[] VALID_ACTIONS = {ACTION_DEPLOY};
+
+ /**
+ * Add a nested argument element to hand to the deployment tool; optional.
+ * @return A Commandline.Argument object representing the
+ * command line argument being passed when the deployment
+ * tool is run. IE: "-user=mark", "-password=venture"...
+ */
+ public Commandline.Argument createArg() {
+ return java.createArg();
+ }
+
+ /**
+ * Add a nested argument element to hand to the JVM running the
+ * deployment tool.
+ * Creates a nested arg element.
+ * @return A Commandline.Argument object representing the
+ * JVM command line argument being passed when the deployment
+ * tool is run. IE: "-ms64m", "-mx128m"...
+ */
+ public Commandline.Argument createJvmarg() {
+ return java.createJvmarg();
+ }
+
+ /**
+ * Determines if the "action" attribute defines a valid action.
+ * <p>Subclasses should determine if the action passed in is
+ * supported by the vendor's deployment tool.
+ * For this generic implementation, the only valid action is "deploy"
+ * @return true if the "action" attribute is valid, false if not.
+ */
+ protected boolean isActionValid() {
+ return (getTask().getAction().equals(VALID_ACTIONS[0]));
+ }
+
+ /**
+ * Sets the parent task.
+ * @param task An ServerDeploy object representing the parent task.
+ * @ant.attribute ignored="true"
+ */
+ public void setTask(ServerDeploy task) {
+ super.setTask(task);
+ java = new Java(task);
+ }
+
+ /**
+ * Perform the actual deployment.
+ * For this generic implementation, a JVM is spawned using the
+ * supplied classpath, classname, JVM args, and command line arguments.
+ * @exception org.apache.tools.ant.BuildException if the attributes are invalid or incomplete.
+ */
+ public void deploy() throws BuildException {
+ java.setClassname(className);
+ java.setClasspath(getClasspath());
+ java.setFork(true);
+ java.setFailonerror(true);
+ java.execute();
+ }
+
+ /**
+ * Validates the passed in attributes.
+ * Ensures the className and arguments attribute have been set.
+ * @exception org.apache.tools.ant.BuildException if the attributes are invalid or incomplete.
+ */
+ public void validateAttributes() throws BuildException {
+ super.validateAttributes();
+
+ if (className == null) {
+ throw new BuildException("The classname attribute must be set");
+ }
+ }
+
+ /**
+ * The name of the class to execute to perform
+ * deployment; required.
+ * Example: "com.foobar.tools.deploy.DeployTool"
+ * @param className The fully qualified class name of the class
+ * to perform deployment.
+ */
+ public void setClassName(String className) {
+ this.className = className;
+ }
+
+ /**
+ * get the java attribute.
+ * @return the java attribute.
+ */
+ public Java getJava() {
+ return java;
+ }
+
+ /**
+ * Get the classname attribute.
+ * @return the classname value.
+ */
+ public String getClassName() {
+ return className;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/j2ee/HotDeploymentTool.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/j2ee/HotDeploymentTool.java
new file mode 100644
index 00000000..16c55d8e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/j2ee/HotDeploymentTool.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.j2ee;
+
+import org.apache.tools.ant.BuildException;
+
+/**
+ * An interface for vendor-specific "hot" deployment tools.
+ *
+ * @see org.apache.tools.ant.taskdefs.optional.j2ee.AbstractHotDeploymentTool
+ * @see org.apache.tools.ant.taskdefs.optional.j2ee.ServerDeploy
+ */
+public interface HotDeploymentTool {
+ /** The delete action String **/
+ String ACTION_DELETE = "delete";
+
+ /** The deploy action String **/
+ String ACTION_DEPLOY = "deploy";
+
+ /** The list action String **/
+ String ACTION_LIST = "list";
+
+ /** The undeploy action String **/
+ String ACTION_UNDEPLOY = "undeploy";
+
+ /** The update action String **/
+ String ACTION_UPDATE = "update";
+
+ /**
+ * Validates the passed in attributes.
+ * @exception org.apache.tools.ant.BuildException if the attributes are invalid or incomplete.
+ */
+ void validateAttributes() throws BuildException;
+
+ /**
+ * Perform the actual deployment.
+ * @exception org.apache.tools.ant.BuildException if the attributes are invalid or incomplete.
+ */
+ void deploy() throws BuildException;
+
+ /**
+ * Sets the parent task.
+ * @param task A ServerDeploy object representing the parent task.
+ */
+ void setTask(ServerDeploy task);
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/j2ee/JonasHotDeploymentTool.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/j2ee/JonasHotDeploymentTool.java
new file mode 100644
index 00000000..c7a33a19
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/j2ee/JonasHotDeploymentTool.java
@@ -0,0 +1,252 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.j2ee;
+
+import java.io.File;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.taskdefs.Java;
+import org.apache.tools.ant.types.Path;
+
+/**
+ * An Ant wrapper task for the weblogic.deploy tool. This is used
+ * to hot-deploy J2EE applications to a running WebLogic server.
+ * This is <b>not</b> the same as creating the application
+ * archive. This task assumes the archive (EAR, JAR, or WAR) file
+ * has been assembled and is supplied as the "source" attribute.
+ * <p>
+ *
+ * In the end, this task assembles the commandline parameters and
+ * runs the weblogic.deploy tool in a separate JVM.
+ *
+ *@see org.apache.tools.ant.taskdefs.optional.j2ee.HotDeploymentTool
+ *@see org.apache.tools.ant.taskdefs.optional.j2ee.AbstractHotDeploymentTool
+ *@see org.apache.tools.ant.taskdefs.optional.j2ee.ServerDeploy
+ */
+public class JonasHotDeploymentTool extends GenericHotDeploymentTool implements HotDeploymentTool {
+
+ /**
+ * Description of the Field
+ */
+ protected static final String DEFAULT_ORB = "RMI";
+
+ /**
+ * The classname of the tool to run *
+ */
+ private static final String JONAS_DEPLOY_CLASS_NAME = "org.objectweb.jonas.adm.JonasAdmin";
+
+ /**
+ * All the valid actions that weblogic.deploy permits *
+ */
+ private static final String[] VALID_ACTIONS
+ = {ACTION_DELETE, ACTION_DEPLOY, ACTION_LIST, ACTION_UNDEPLOY, ACTION_UPDATE};
+
+ /**
+ * Description of the Field
+ */
+ private File jonasroot;
+
+ /**
+ * Description of the Field
+ */
+ private String orb = null;
+
+ /**
+ * Description of the Field
+ */
+ private String davidHost;
+
+ /**
+ * Description of the Field
+ */
+ private int davidPort;
+
+
+ /**
+ * Set the host for the David ORB; required if
+ * ORB==david.
+ *
+ *@param inValue The new davidhost value
+ */
+ public void setDavidhost(final String inValue) {
+ davidHost = inValue;
+ }
+
+
+ /**
+ * Set the port for the David ORB; required if
+ * ORB==david.
+ *
+ *@param inValue The new davidport value
+ */
+ public void setDavidport(final int inValue) {
+ davidPort = inValue;
+ }
+
+
+ /**
+ * set the jonas root directory (-Dinstall.root=). This
+ * element is required.
+ *
+ *@param inValue The new jonasroot value
+ */
+ public void setJonasroot(final File inValue) {
+ jonasroot = inValue;
+ }
+
+
+ /**
+ *
+ * Choose your ORB : RMI, JEREMIE, DAVID, ...; optional.
+ * If omitted, it defaults
+ * to the one present in classpath. The corresponding JOnAS JAR is
+ * automatically added to the classpath. If your orb is DAVID (RMI/IIOP) you must
+ * specify davidhost and davidport properties.
+ *
+ *@param inValue RMI, JEREMIE, DAVID,...
+ */
+ public void setOrb(final String inValue) {
+ orb = inValue;
+ }
+
+
+ /**
+ * gets the classpath field.
+ *
+ *@return A Path representing the "classpath" attribute.
+ */
+ public Path getClasspath() {
+
+ Path aClassPath = super.getClasspath();
+
+ if (aClassPath == null) {
+ aClassPath = new Path(getTask().getProject());
+ }
+ if (orb != null) {
+ String aOrbJar = new File(jonasroot, "lib/" + orb + "_jonas.jar").toString();
+ String aConfigDir = new File(jonasroot, "config/").toString();
+ Path aJOnASOrbPath = new Path(aClassPath.getProject(),
+ aOrbJar + File.pathSeparator + aConfigDir);
+ aClassPath.append(aJOnASOrbPath);
+ }
+ return aClassPath;
+ }
+
+
+ /**
+ * Validates the passed in attributes. <p>
+ *
+ * The rules are:
+ * <ol>
+ * <li> If action is "deploy" or "update" the "application"
+ * and "source" attributes must be supplied.
+ * <li> If action is "delete" or "undeploy" the
+ * "application" attribute must be supplied.
+ *
+ *@exception BuildException Description
+ * of Exception
+ */
+ public void validateAttributes() throws BuildException {
+ // super.validateAttributes(); // don't want to call this method
+
+ Java java = getJava();
+
+ String action = getTask().getAction();
+ if (action == null) {
+ throw new BuildException("The \"action\" attribute must be set");
+ }
+
+ if (!isActionValid()) {
+ throw new BuildException("Invalid action \"" + action + "\" passed");
+ }
+
+ if (getClassName() == null) {
+ setClassName(JONAS_DEPLOY_CLASS_NAME);
+ }
+
+ if (jonasroot == null || jonasroot.isDirectory()) {
+ java.createJvmarg().setValue("-Dinstall.root=" + jonasroot);
+ java.createJvmarg().setValue("-Djava.security.policy=" + jonasroot
+ + "/config/java.policy");
+
+ if ("DAVID".equals(orb)) {
+ java.createJvmarg().setValue("-Dorg.omg.CORBA.ORBClass"
+ + "=org.objectweb.david.libs.binding.orbs.iiop.IIOPORB");
+ java.createJvmarg().setValue("-Dorg.omg.CORBA.ORBSingletonClass="
+ + "org.objectweb.david.libs.binding.orbs.ORBSingletonClass");
+ java.createJvmarg().setValue("-Djavax.rmi.CORBA.StubClass="
+ + "org.objectweb.david.libs.stub_factories.rmi.StubDelegate");
+ java.createJvmarg().setValue("-Djavax.rmi.CORBA.PortableRemoteObjectClass="
+ + "org.objectweb.david.libs.binding.rmi.ORBPortableRemoteObjectDelegate");
+ java.createJvmarg().setValue("-Djavax.rmi.CORBA.UtilClass="
+ + "org.objectweb.david.libs.helpers.RMIUtilDelegate");
+ java.createJvmarg().setValue("-Ddavid.CosNaming.default_method=0");
+ java.createJvmarg().setValue("-Ddavid.rmi.ValueHandlerClass="
+ + "com.sun.corba.se.internal.io.ValueHandlerImpl");
+ if (davidHost != null) {
+ java.createJvmarg().setValue("-Ddavid.CosNaming.default_host="
+ + davidHost);
+ }
+ if (davidPort != 0) {
+ java.createJvmarg().setValue("-Ddavid.CosNaming.default_port="
+ + davidPort);
+ }
+ }
+ }
+
+ if (getServer() != null) {
+ java.createArg().setLine("-n " + getServer());
+ }
+
+ if (action.equals(ACTION_DEPLOY)
+ || action.equals(ACTION_UPDATE)
+ || action.equals("redeploy")) {
+ java.createArg().setLine("-a " + getTask().getSource());
+ } else if (action.equals(ACTION_DELETE) || action.equals(ACTION_UNDEPLOY)) {
+ java.createArg().setLine("-r " + getTask().getSource());
+ } else if (action.equals(ACTION_LIST)) {
+ java.createArg().setValue("-l");
+ }
+ }
+
+
+ /**
+ * Determines if the action supplied is valid. <p>
+ *
+ * Valid actions are contained in the static array
+ * VALID_ACTIONS
+ *
+ *@return true if the action attribute is valid, false if
+ * not.
+ */
+ protected boolean isActionValid() {
+ boolean valid = false;
+
+ String action = getTask().getAction();
+
+ for (int i = 0; i < VALID_ACTIONS.length; i++) {
+ if (action.equals(VALID_ACTIONS[i])) {
+ valid = true;
+ break;
+ }
+ }
+
+ return valid;
+ }
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/j2ee/ServerDeploy.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/j2ee/ServerDeploy.java
new file mode 100644
index 00000000..8965b8e8
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/j2ee/ServerDeploy.java
@@ -0,0 +1,153 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.j2ee;
+
+import java.io.File;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Task;
+
+/**
+ * Controls hot deployment tools for J2EE servers.
+ *
+ * This class is used as a framework for the creation of vendor specific
+ * hot deployment tools.
+ *
+ * @see org.apache.tools.ant.taskdefs.optional.j2ee.HotDeploymentTool
+ * @see org.apache.tools.ant.taskdefs.optional.j2ee.AbstractHotDeploymentTool
+ * @see org.apache.tools.ant.taskdefs.optional.j2ee.GenericHotDeploymentTool
+ * @see org.apache.tools.ant.taskdefs.optional.j2ee.WebLogicHotDeploymentTool
+ */
+public class ServerDeploy extends Task {
+ /** The action to be performed. IE: "deploy", "delete", etc... **/
+ private String action;
+
+ /** The source (fully-qualified path) to the component being deployed **/
+ private File source;
+
+ /** The vendor specific tool for deploying the component **/
+ private Vector vendorTools = new Vector();
+
+ ///////////////////////////////////////////////////////////////////////////
+ //
+ // Place vendor specific tool creations here.
+ //
+ ///////////////////////////////////////////////////////////////////////////
+
+ /**
+ * Creates a generic deployment tool.
+ * <p>Ant calls this method on creation to handle embedded "generic" elements
+ * in the ServerDeploy task.
+ * @param tool An instance of GenericHotDeployment tool, passed in by Ant.
+ */
+ public void addGeneric(GenericHotDeploymentTool tool) {
+ tool.setTask(this);
+ vendorTools.addElement(tool);
+ }
+
+ /**
+ * Creates a WebLogic deployment tool, for deployment to WebLogic servers.
+ * <p>Ant calls this method on creation to handle embedded "weblogic" elements
+ * in the ServerDeploy task.
+ * @param tool An instance of WebLogicHotDeployment tool, passed in by Ant.
+ */
+ public void addWeblogic(WebLogicHotDeploymentTool tool) {
+ tool.setTask(this);
+ vendorTools.addElement(tool);
+ }
+
+ /**
+ * Creates a JOnAS deployment tool, for deployment to JOnAS servers.
+ * <p>Ant calls this method on creation to handle embedded "jonas" elements
+ * in the ServerDeploy task.
+ * @param tool An instance of JonasHotDeployment tool, passed in by Ant.
+ */
+ public void addJonas(JonasHotDeploymentTool tool) {
+ tool.setTask(this);
+ vendorTools.addElement(tool);
+ }
+
+
+ ///////////////////////////////////////////////////////////////////////////
+ //
+ // Execute method
+ //
+ ///////////////////////////////////////////////////////////////////////////
+
+ /**
+ * Execute the task.
+ * <p>This method calls the deploy() method on each of the vendor-specific tools
+ * in the <code>vendorTools</code> collection. This performs the actual
+ * process of deployment on each tool.
+ * @exception org.apache.tools.ant.BuildException if the attributes
+ * are invalid or incomplete, or a failure occurs in the deployment process.
+ */
+ public void execute() throws BuildException {
+ for (Enumeration e = vendorTools.elements();
+ e.hasMoreElements();) {
+ HotDeploymentTool tool = (HotDeploymentTool) e.nextElement();
+ tool.validateAttributes();
+ tool.deploy();
+ }
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ //
+ // Set/get methods
+ //
+ ///////////////////////////////////////////////////////////////////////////
+
+ /**
+ * Returns the action field.
+ * @return A string representing the "action" attribute.
+ */
+ public String getAction() {
+ return action;
+ }
+
+ /**
+ * The action to be performed, usually "deploy"; required.
+ * Some tools support additional actions, such as "delete", "list", "undeploy", "update"...
+ * @param action A String representing the "action" attribute.
+ */
+ public void setAction(String action) {
+ this.action = action;
+ }
+
+ /**
+ * Returns the source field (the path/filename of the component to be
+ * deployed.
+ * @return A File object representing the "source" attribute.
+ */
+ public File getSource() {
+ return source;
+ }
+
+ /**
+ * The filename of the component to be deployed; optional
+ * depending upon the tool and the action.
+ * @param source String representing the "source" attribute.
+ */
+ public void setSource(File source) {
+ this.source = source;
+ }
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/j2ee/WebLogicHotDeploymentTool.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/j2ee/WebLogicHotDeploymentTool.java
new file mode 100644
index 00000000..da875092
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/j2ee/WebLogicHotDeploymentTool.java
@@ -0,0 +1,247 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.j2ee;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.taskdefs.Java;
+
+/**
+ * An Ant wrapper task for the weblogic.deploy tool. This is used to
+ * hot-deploy J2EE applications to a running WebLogic server.
+ * This is <b>not</b> the same as creating the application archive.
+ * This task assumes the archive (EAR, JAR, or WAR) file has been
+ * assembled and is supplied as the "source" attribute.
+ * <p>In the end, this task assembles the commandline parameters
+ * and runs the weblogic.deploy tool in a separate JVM.
+ *
+ * @see org.apache.tools.ant.taskdefs.optional.j2ee.HotDeploymentTool
+ * @see org.apache.tools.ant.taskdefs.optional.j2ee.AbstractHotDeploymentTool
+ * @see org.apache.tools.ant.taskdefs.optional.j2ee.ServerDeploy
+ */
+public class WebLogicHotDeploymentTool extends AbstractHotDeploymentTool
+ implements HotDeploymentTool {
+ private static final int STRING_BUFFER_SIZE = 1024;
+ /** The classname of the tool to run **/
+ private static final String WEBLOGIC_DEPLOY_CLASS_NAME = "weblogic.deploy";
+
+ /** All the valid actions that weblogic.deploy permits **/
+ private static final String[] VALID_ACTIONS
+ = {ACTION_DELETE, ACTION_DEPLOY, ACTION_LIST, ACTION_UNDEPLOY, ACTION_UPDATE};
+
+ /** Represents the "-debug" flag from weblogic.deploy **/
+ private boolean debug;
+
+ /** The application name that is being deployed **/
+ private String application;
+
+ /** The component name:target(s) for the "-component" argument of weblogic.deploy **/
+ private String component;
+
+ /**
+ * Perform the actual deployment.
+ * For this implementation, a JVM is spawned and the weblogic.deploy
+ * tools is executed.
+ * @exception org.apache.tools.ant.BuildException if the attributes are invalid or incomplete.
+ */
+ public void deploy() {
+ Java java = new Java(getTask());
+ java.setFork(true);
+ java.setFailonerror(true);
+ java.setClasspath(getClasspath());
+
+ java.setClassname(WEBLOGIC_DEPLOY_CLASS_NAME);
+ java.createArg().setLine(getArguments());
+ java.execute();
+ }
+
+ /**
+ * Validates the passed in attributes.
+ * <p>The rules are:
+ * <ol><li>If action is "deploy" or "update" the "application" and "source"
+ * attributes must be supplied.
+ * <li>If action is "delete" or "undeploy" the "application" attribute must
+ * be supplied.
+ * @exception org.apache.tools.ant.BuildException if the attributes are invalid or incomplete
+ */
+ public void validateAttributes() throws BuildException {
+ super.validateAttributes();
+
+ String action = getTask().getAction();
+
+ // check that the password has been set
+ if ((getPassword() == null)) {
+ throw new BuildException("The password attribute must be set.");
+ }
+
+ // check for missing application on deploy & update
+ if ((action.equals(ACTION_DEPLOY) || action.equals(ACTION_UPDATE))
+ && application == null) {
+ throw new BuildException("The application attribute must be set "
+ + "if action = " + action);
+ }
+
+ // check for missing source on deploy & update
+ if ((action.equals(ACTION_DEPLOY) || action.equals(ACTION_UPDATE))
+ && getTask().getSource() == null) {
+ throw new BuildException("The source attribute must be set if "
+ + "action = " + action);
+ }
+
+ // check for missing application on delete & undeploy
+ if ((action.equals(ACTION_DELETE) || action.equals(ACTION_UNDEPLOY))
+ && application == null) {
+ throw new BuildException("The application attribute must be set if "
+ + "action = " + action);
+ }
+ }
+
+ /**
+ * Builds the arguments to pass to weblogic.deploy according to the
+ * supplied action.
+ * @return A String containing the arguments for the weblogic.deploy tool.
+ * @throws BuildException if there is an error.
+ */
+ public String getArguments() throws BuildException {
+ String action = getTask().getAction();
+ String args = null;
+
+ if (action.equals(ACTION_DEPLOY) || action.equals(ACTION_UPDATE)) {
+ args = buildDeployArgs();
+ } else if (action.equals(ACTION_DELETE) || action.equals(ACTION_UNDEPLOY)) {
+ args = buildUndeployArgs();
+ } else if (action.equals(ACTION_LIST)) {
+ args = buildListArgs();
+ }
+
+ return args;
+ }
+
+ /**
+ * Determines if the action supplied is valid.
+ * <p>Valid actions are contained in the static array VALID_ACTIONS
+ * @return true if the action attribute is valid, false if not.
+ */
+ protected boolean isActionValid() {
+ boolean valid = false;
+
+ String action = getTask().getAction();
+
+ for (int i = 0; i < VALID_ACTIONS.length; i++) {
+ if (action.equals(VALID_ACTIONS[i])) {
+ valid = true;
+ break;
+ }
+ }
+
+ return valid;
+ }
+
+ /**
+ * Builds the prefix arguments to pass to weblogic.deploy.
+ * These arguments are generic across all actions.
+ * @return A StringBuffer containing the prefix arguments.
+ * The action-specific build methods will append to this StringBuffer.
+ */
+ protected StringBuffer buildArgsPrefix() {
+ ServerDeploy task = getTask();
+ // constructs the "-url <url> -debug <action> <password>" portion
+ // of the commmand line
+ return new StringBuffer(STRING_BUFFER_SIZE)
+ .append((getServer() != null)
+ ? "-url " + getServer()
+ : "")
+ .append(" ")
+ .append(debug ? "-debug " : "")
+ .append((getUserName() != null)
+ ? "-username " + getUserName()
+ : "")
+ .append(" ")
+ .append(task.getAction()).append(" ")
+ .append(getPassword()).append(" ");
+ }
+
+ /**
+ * Builds the arguments to pass to weblogic.deploy for deployment actions
+ * ("deploy" and "update").
+ * @return A String containing the full argument string for weblogic.deploy.
+ */
+ protected String buildDeployArgs() {
+ String args = buildArgsPrefix()
+ .append(application).append(" ")
+ .append(getTask().getSource())
+ .toString();
+
+ if (component != null) {
+ args = "-component " + component + " " + args;
+ }
+
+ return args;
+ }
+
+ /**
+ * Builds the arguments to pass to weblogic.deploy for undeployment actions
+ * ("undeploy" and "delete").
+ * @return A String containing the full argument string for weblogic.deploy.
+ */
+ protected String buildUndeployArgs() {
+ return buildArgsPrefix()
+ .append(application).append(" ")
+ .toString();
+ }
+
+ /**
+ * Builds the arguments to pass to weblogic.deploy for the list action
+ * @return A String containing the full argument string for weblogic.deploy.
+ */
+ protected String buildListArgs() {
+ return buildArgsPrefix()
+ .toString();
+ }
+
+ /**
+ * If set to true, additional information will be
+ * printed during the deployment process; optional.
+ * @param debug A boolean representing weblogic.deploy "-debug" flag.
+ */
+ public void setDebug(boolean debug) {
+ this.debug = debug;
+ }
+
+ /**
+ * The name of the application being deployed; required.
+ * @param application A String representing the application portion of the
+ * weblogic.deploy command line.
+ */
+ public void setApplication(String application) {
+ this.application = application;
+ }
+
+ /**
+ * the component string for the deployment targets; optional.
+ * It is in the form <code>&lt;component&gt;:&lt;target1&gt;,&lt;target2&gt;...</code>
+ * Where component is the archive name (minus the .jar, .ear, .war
+ * extension). Targets are the servers where the components will be deployed
+
+ * @param component A String representing the value of the "-component"
+ * argument of the weblogic.deploy command line argument.
+ */
+ public void setComponent(String component) {
+ this.component = component;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/javacc/JJDoc.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/javacc/JJDoc.java
new file mode 100644
index 00000000..a4dc0f48
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/javacc/JJDoc.java
@@ -0,0 +1,226 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.javacc;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.taskdefs.Execute;
+import org.apache.tools.ant.taskdefs.LogStreamHandler;
+import org.apache.tools.ant.types.Commandline;
+import org.apache.tools.ant.types.CommandlineJava;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.util.JavaEnvUtils;
+
+/**
+ * Runs the JJDoc compiler compiler.
+ *
+ */
+public class JJDoc extends Task {
+
+ // keys to optional attributes
+ private static final String OUTPUT_FILE = "OUTPUT_FILE";
+ private static final String TEXT = "TEXT";
+ private static final String ONE_TABLE = "ONE_TABLE";
+
+ private final Hashtable optionalAttrs = new Hashtable();
+
+ private String outputFile = null;
+ private boolean plainText = false;
+
+ private static final String DEFAULT_SUFFIX_HTML = ".html";
+ private static final String DEFAULT_SUFFIX_TEXT = ".txt";
+
+ // required attributes
+ private File targetFile = null;
+ private File javaccHome = null;
+
+ private CommandlineJava cmdl = new CommandlineJava();
+
+ private String maxMemory = null;
+
+ /**
+ * Sets the TEXT BNF documentation option.
+ * @param plainText a <code>boolean</code> value.
+ */
+ public void setText(boolean plainText) {
+ optionalAttrs.put(TEXT, plainText ? Boolean.TRUE : Boolean.FALSE);
+ this.plainText = plainText;
+ }
+
+ /**
+ * Sets the ONE_TABLE documentation option.
+ * @param oneTable a <code>boolean</code> value.
+ */
+ public void setOnetable(boolean oneTable) {
+ optionalAttrs.put(ONE_TABLE, oneTable ? Boolean.TRUE : Boolean.FALSE);
+ }
+
+ /**
+ * The outputfile to write the generated BNF documentation file to.
+ * If not set, the file is written with the same name as
+ * the JavaCC grammar file with a suffix .html or .txt.
+ * @param outputFile the name of the output file.
+ */
+ public void setOutputfile(String outputFile) {
+ this.outputFile = outputFile;
+ }
+
+ /**
+ * The javacc grammar file to process.
+ * @param target the grammar file.
+ */
+ public void setTarget(File target) {
+ this.targetFile = target;
+ }
+
+ /**
+ * The directory containing the JavaCC distribution.
+ * @param javaccHome the home directory.
+ */
+ public void setJavacchome(File javaccHome) {
+ this.javaccHome = javaccHome;
+ }
+
+ /**
+ * Corresponds -Xmx.
+ *
+ * @param max max memory parameter.
+ * @since Ant 1.8.3
+ */
+ public void setMaxmemory(String max) {
+ maxMemory = max;
+ }
+
+ /**
+ * Constructor
+ */
+ public JJDoc() {
+ cmdl.setVm(JavaEnvUtils.getJreExecutable("java"));
+ }
+
+ /**
+ * Do the task.
+ * @throws BuildException if there is an error.
+ */
+ public void execute() throws BuildException {
+
+ // load command line with optional attributes
+ Enumeration iter = optionalAttrs.keys();
+ while (iter.hasMoreElements()) {
+ String name = (String) iter.nextElement();
+ Object value = optionalAttrs.get(name);
+ cmdl.createArgument()
+ .setValue("-" + name + ":" + value.toString());
+ }
+
+ if (targetFile == null || !targetFile.isFile()) {
+ throw new BuildException("Invalid target: " + targetFile);
+ }
+
+ if (outputFile != null) {
+ cmdl.createArgument() .setValue("-" + OUTPUT_FILE + ":"
+ + outputFile.replace('\\', '/'));
+ }
+
+ // use the directory containing the target as the output directory
+ File javaFile = new File(createOutputFileName(targetFile, outputFile,
+ plainText));
+
+ if (javaFile.exists()
+ && targetFile.lastModified() < javaFile.lastModified()) {
+ log("Target is already built - skipping (" + targetFile + ")",
+ Project.MSG_VERBOSE);
+ return;
+ }
+
+ cmdl.createArgument().setValue(targetFile.getAbsolutePath());
+
+ final Path classpath = cmdl.createClasspath(getProject());
+ final File javaccJar = JavaCC.getArchiveFile(javaccHome);
+ classpath.createPathElement().setPath(javaccJar.getAbsolutePath());
+ classpath.addJavaRuntime();
+
+ cmdl.setClassname(JavaCC.getMainClass(classpath,
+ JavaCC.TASKDEF_TYPE_JJDOC));
+
+ cmdl.setMaxmemory(maxMemory);
+ final Commandline.Argument arg = cmdl.createVmArgument();
+ arg.setValue("-Dinstall.root=" + javaccHome.getAbsolutePath());
+
+ final Execute process =
+ new Execute(new LogStreamHandler(this,
+ Project.MSG_INFO,
+ Project.MSG_INFO),
+ null);
+ log(cmdl.describeCommand(), Project.MSG_VERBOSE);
+ process.setCommandline(cmdl.getCommandline());
+
+ try {
+ if (process.execute() != 0) {
+ throw new BuildException("JJDoc failed.");
+ }
+ } catch (IOException e) {
+ throw new BuildException("Failed to launch JJDoc", e);
+ }
+ }
+
+ private String createOutputFileName(File destFile, String optionalOutputFile,
+ boolean plain) {
+ String suffix = DEFAULT_SUFFIX_HTML;
+ String javaccFile = destFile.getAbsolutePath().replace('\\', '/');
+
+ if (plain) {
+ suffix = DEFAULT_SUFFIX_TEXT;
+ }
+
+ if ((optionalOutputFile == null) || optionalOutputFile.equals("")) {
+ int filePos = javaccFile.lastIndexOf("/");
+
+ if (filePos >= 0) {
+ javaccFile = javaccFile.substring(filePos + 1);
+ }
+
+ int suffixPos = javaccFile.lastIndexOf('.');
+
+ if (suffixPos == -1) {
+ optionalOutputFile = javaccFile + suffix;
+ } else {
+ String currentSuffix = javaccFile.substring(suffixPos);
+
+ if (currentSuffix.equals(suffix)) {
+ optionalOutputFile = javaccFile + suffix;
+ } else {
+ optionalOutputFile = javaccFile.substring(0, suffixPos)
+ + suffix;
+ }
+ }
+ } else {
+ optionalOutputFile = optionalOutputFile.replace('\\', '/');
+ }
+
+ return (getProject().getBaseDir() + "/" + optionalOutputFile)
+ .replace('\\', '/');
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/javacc/JJTree.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/javacc/JJTree.java
new file mode 100644
index 00000000..f5d126ee
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/javacc/JJTree.java
@@ -0,0 +1,416 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.javacc;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.taskdefs.Execute;
+import org.apache.tools.ant.taskdefs.LogStreamHandler;
+import org.apache.tools.ant.types.Commandline;
+import org.apache.tools.ant.types.CommandlineJava;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.util.JavaEnvUtils;
+
+/**
+ * Runs the JJTree compiler compiler.
+ *
+ */
+public class JJTree extends Task {
+
+ // keys to optional attributes
+ private static final String OUTPUT_FILE = "OUTPUT_FILE";
+ private static final String BUILD_NODE_FILES = "BUILD_NODE_FILES";
+ private static final String MULTI = "MULTI";
+ private static final String NODE_DEFAULT_VOID = "NODE_DEFAULT_VOID";
+ private static final String NODE_FACTORY = "NODE_FACTORY";
+ private static final String NODE_SCOPE_HOOK = "NODE_SCOPE_HOOK";
+ private static final String NODE_USES_PARSER = "NODE_USES_PARSER";
+ private static final String STATIC = "STATIC";
+ private static final String VISITOR = "VISITOR";
+
+ private static final String NODE_PACKAGE = "NODE_PACKAGE";
+ private static final String VISITOR_EXCEPTION = "VISITOR_EXCEPTION";
+ private static final String NODE_PREFIX = "NODE_PREFIX";
+
+ private final Hashtable optionalAttrs = new Hashtable();
+
+ private String outputFile = null;
+
+ private static final String DEFAULT_SUFFIX = ".jj";
+
+ // required attributes
+ private File outputDirectory = null;
+ private File targetFile = null;
+ private File javaccHome = null;
+
+ private CommandlineJava cmdl = new CommandlineJava();
+
+ private String maxMemory = null;
+
+ /**
+ * Sets the BUILD_NODE_FILES grammar option.
+ * @param buildNodeFiles a <code>boolean</code> value.
+ */
+ public void setBuildnodefiles(boolean buildNodeFiles) {
+ optionalAttrs.put(BUILD_NODE_FILES, buildNodeFiles ? Boolean.TRUE : Boolean.FALSE);
+ }
+
+ /**
+ * Sets the MULTI grammar option.
+ * @param multi a <code>boolean</code> value.
+ */
+ public void setMulti(boolean multi) {
+ optionalAttrs.put(MULTI, multi ? Boolean.TRUE : Boolean.FALSE);
+ }
+
+ /**
+ * Sets the NODE_DEFAULT_VOID grammar option.
+ * @param nodeDefaultVoid a <code>boolean</code> value.
+ */
+ public void setNodedefaultvoid(boolean nodeDefaultVoid) {
+ optionalAttrs.put(NODE_DEFAULT_VOID, nodeDefaultVoid ? Boolean.TRUE : Boolean.FALSE);
+ }
+
+ /**
+ * Sets the NODE_FACTORY grammar option.
+ * @param nodeFactory a <code>boolean</code> value.
+ */
+ public void setNodefactory(boolean nodeFactory) {
+ optionalAttrs.put(NODE_FACTORY, nodeFactory ? Boolean.TRUE : Boolean.FALSE);
+ }
+
+ /**
+ * Sets the NODE_SCOPE_HOOK grammar option.
+ * @param nodeScopeHook a <code>boolean</code> value.
+ */
+ public void setNodescopehook(boolean nodeScopeHook) {
+ optionalAttrs.put(NODE_SCOPE_HOOK, nodeScopeHook ? Boolean.TRUE : Boolean.FALSE);
+ }
+
+ /**
+ * Sets the NODE_USES_PARSER grammar option.
+ * @param nodeUsesParser a <code>boolean</code> value.
+ */
+ public void setNodeusesparser(boolean nodeUsesParser) {
+ optionalAttrs.put(NODE_USES_PARSER, nodeUsesParser ? Boolean.TRUE : Boolean.FALSE);
+ }
+
+ /**
+ * Sets the STATIC grammar option.
+ * @param staticParser a <code>boolean</code> value.
+ */
+ public void setStatic(boolean staticParser) {
+ optionalAttrs.put(STATIC, staticParser ? Boolean.TRUE : Boolean.FALSE);
+ }
+
+ /**
+ * Sets the VISITOR grammar option.
+ * @param visitor a <code>boolean</code> value.
+ */
+ public void setVisitor(boolean visitor) {
+ optionalAttrs.put(VISITOR, visitor ? Boolean.TRUE : Boolean.FALSE);
+ }
+
+ /**
+ * Sets the NODE_PACKAGE grammar option.
+ * @param nodePackage the option to use.
+ */
+ public void setNodepackage(String nodePackage) {
+ optionalAttrs.put(NODE_PACKAGE, nodePackage);
+ }
+
+ /**
+ * Sets the VISITOR_EXCEPTION grammar option.
+ * @param visitorException the option to use.
+ */
+ public void setVisitorException(String visitorException) {
+ optionalAttrs.put(VISITOR_EXCEPTION, visitorException);
+ }
+
+ /**
+ * Sets the NODE_PREFIX grammar option.
+ * @param nodePrefix the option to use.
+ */
+ public void setNodeprefix(String nodePrefix) {
+ optionalAttrs.put(NODE_PREFIX, nodePrefix);
+ }
+
+ /**
+ * The directory to write the generated JavaCC grammar and node files to.
+ * If not set, the files are written to the directory
+ * containing the grammar file.
+ * @param outputDirectory the output directory.
+ */
+ public void setOutputdirectory(File outputDirectory) {
+ this.outputDirectory = outputDirectory;
+ }
+
+ /**
+ * The outputfile to write the generated JavaCC grammar file to.
+ * If not set, the file is written with the same name as
+ * the JJTree grammar file with a suffix .jj.
+ * @param outputFile the output file name.
+ */
+ public void setOutputfile(String outputFile) {
+ this.outputFile = outputFile;
+ }
+
+ /**
+ * The jjtree grammar file to process.
+ * @param targetFile the grammar file.
+ */
+ public void setTarget(File targetFile) {
+ this.targetFile = targetFile;
+ }
+
+ /**
+ * The directory containing the JavaCC distribution.
+ * @param javaccHome the directory containing JavaCC.
+ */
+ public void setJavacchome(File javaccHome) {
+ this.javaccHome = javaccHome;
+ }
+
+ /**
+ * Corresponds -Xmx.
+ *
+ * @param max max memory parameter.
+ * @since Ant 1.8.3
+ */
+ public void setMaxmemory(String max) {
+ maxMemory = max;
+ }
+
+ /**
+ * Constructor
+ */
+ public JJTree() {
+ cmdl.setVm(JavaEnvUtils.getJreExecutable("java"));
+ }
+
+ /**
+ * Run the task.
+ * @throws BuildException on error.
+ */
+ public void execute() throws BuildException {
+
+ // load command line with optional attributes
+ Enumeration iter = optionalAttrs.keys();
+ while (iter.hasMoreElements()) {
+ String name = (String) iter.nextElement();
+ Object value = optionalAttrs.get(name);
+ cmdl.createArgument().setValue("-" + name + ":" + value.toString());
+ }
+
+ if (targetFile == null || !targetFile.isFile()) {
+ throw new BuildException("Invalid target: " + targetFile);
+ }
+
+ File javaFile = null;
+
+ // use the directory containing the target as the output directory
+ if (outputDirectory == null) {
+ // convert backslashes to slashes, otherwise jjtree will
+ // put this as comments and this seems to confuse javacc
+ cmdl.createArgument().setValue("-OUTPUT_DIRECTORY:"
+ + getDefaultOutputDirectory());
+
+ javaFile = new File(createOutputFileName(targetFile, outputFile,
+ null));
+ } else {
+ if (!outputDirectory.isDirectory()) {
+ throw new BuildException("'outputdirectory' " + outputDirectory
+ + " is not a directory.");
+ }
+
+ // convert backslashes to slashes, otherwise jjtree will
+ // put this as comments and this seems to confuse javacc
+ cmdl.createArgument().setValue("-OUTPUT_DIRECTORY:"
+ + outputDirectory.getAbsolutePath()
+ .replace('\\', '/'));
+
+ javaFile = new File(createOutputFileName(targetFile, outputFile,
+ outputDirectory
+ .getPath()));
+ }
+
+ if (javaFile.exists()
+ && targetFile.lastModified() < javaFile.lastModified()) {
+ log("Target is already built - skipping (" + targetFile + ")",
+ Project.MSG_VERBOSE);
+ return;
+ }
+
+ if (outputFile != null) {
+ cmdl.createArgument().setValue("-" + OUTPUT_FILE + ":"
+ + outputFile.replace('\\', '/'));
+ }
+
+ cmdl.createArgument().setValue(targetFile.getAbsolutePath());
+
+ final Path classpath = cmdl.createClasspath(getProject());
+ final File javaccJar = JavaCC.getArchiveFile(javaccHome);
+ classpath.createPathElement().setPath(javaccJar.getAbsolutePath());
+ classpath.addJavaRuntime();
+
+ cmdl.setClassname(JavaCC.getMainClass(classpath,
+ JavaCC.TASKDEF_TYPE_JJTREE));
+
+ cmdl.setMaxmemory(maxMemory);
+ final Commandline.Argument arg = cmdl.createVmArgument();
+ arg.setValue("-Dinstall.root=" + javaccHome.getAbsolutePath());
+
+ final Execute process =
+ new Execute(new LogStreamHandler(this,
+ Project.MSG_INFO,
+ Project.MSG_INFO),
+ null);
+ log(cmdl.describeCommand(), Project.MSG_VERBOSE);
+ process.setCommandline(cmdl.getCommandline());
+
+ try {
+ if (process.execute() != 0) {
+ throw new BuildException("JJTree failed.");
+ }
+ } catch (IOException e) {
+ throw new BuildException("Failed to launch JJTree", e);
+ }
+ }
+
+ private String createOutputFileName(File destFile, String optionalOutputFile,
+ String outputDir) {
+ optionalOutputFile = validateOutputFile(optionalOutputFile,
+ outputDir);
+ String jjtreeFile = destFile.getAbsolutePath().replace('\\', '/');
+
+ if ((optionalOutputFile == null) || optionalOutputFile.equals("")) {
+ int filePos = jjtreeFile.lastIndexOf("/");
+
+ if (filePos >= 0) {
+ jjtreeFile = jjtreeFile.substring(filePos + 1);
+ }
+
+ int suffixPos = jjtreeFile.lastIndexOf('.');
+
+ if (suffixPos == -1) {
+ optionalOutputFile = jjtreeFile + DEFAULT_SUFFIX;
+ } else {
+ String currentSuffix = jjtreeFile.substring(suffixPos);
+
+ if (currentSuffix.equals(DEFAULT_SUFFIX)) {
+ optionalOutputFile = jjtreeFile + DEFAULT_SUFFIX;
+ } else {
+ optionalOutputFile = jjtreeFile.substring(0, suffixPos)
+ + DEFAULT_SUFFIX;
+ }
+ }
+ }
+
+ if ((outputDir == null) || outputDir.equals("")) {
+ outputDir = getDefaultOutputDirectory();
+ }
+
+ return (outputDir + "/" + optionalOutputFile).replace('\\', '/');
+ }
+
+ /**
+ * When running JJTree from an Ant taskdesk the -OUTPUT_DIRECTORY must
+ * always be set. But when -OUTPUT_DIRECTORY is set, -OUTPUT_FILE is
+ * handled as if relative of this -OUTPUT_DIRECTORY. Thus when the
+ * -OUTPUT_FILE is absolute or contains a drive letter we have a problem.
+ *
+ * @param destFile
+ * @param outputDir
+ * @return validation file, relative if possible; <tt>null</tt> if not set
+ * @throws BuildException
+ */
+ private String validateOutputFile(String destFile,
+ String outputDir)
+ throws BuildException {
+ if (destFile == null) {
+ return null;
+ }
+
+ if ((outputDir == null)
+ && (destFile.startsWith("/") || destFile.startsWith("\\"))) {
+ String relativeOutputFile = makeOutputFileRelative(destFile);
+ setOutputfile(relativeOutputFile);
+
+ return relativeOutputFile;
+ }
+
+ String root = getRoot(new File(destFile)).getAbsolutePath();
+
+ if ((root.length() > 1)
+ && destFile.startsWith(root.substring(0, root.length() - 1))) {
+ throw new BuildException("Drive letter in 'outputfile' not "
+ + "supported: " + destFile);
+ }
+
+ return destFile;
+ }
+
+ private String makeOutputFileRelative(String destFile) {
+ StringBuffer relativePath = new StringBuffer();
+ String defaultOutputDirectory = getDefaultOutputDirectory();
+ int nextPos = defaultOutputDirectory.indexOf('/');
+ int startPos = nextPos + 1;
+
+ while (startPos > -1 && startPos < defaultOutputDirectory.length()) {
+ relativePath.append("/..");
+ nextPos = defaultOutputDirectory.indexOf('/', startPos);
+
+ if (nextPos == -1) {
+ startPos = nextPos;
+ } else {
+ startPos = nextPos + 1;
+ }
+ }
+
+ relativePath.append(destFile);
+
+ return relativePath.toString();
+ }
+
+ private String getDefaultOutputDirectory() {
+ return getProject().getBaseDir().getAbsolutePath().replace('\\', '/');
+ }
+
+ /**
+ * Determine root directory for a given file.
+ *
+ * @param file
+ * @return file's root directory
+ */
+ private File getRoot(File file) {
+ File root = file.getAbsoluteFile();
+
+ while (root.getParent() != null) {
+ root = root.getParentFile();
+ }
+
+ return root;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/javacc/JavaCC.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/javacc/JavaCC.java
new file mode 100644
index 00000000..219cc9c8
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/javacc/JavaCC.java
@@ -0,0 +1,579 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.javacc;
+
+import java.io.File;
+import java.io.InputStream;
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+import org.apache.tools.ant.AntClassLoader;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.taskdefs.Execute;
+import org.apache.tools.ant.types.Commandline;
+import org.apache.tools.ant.types.CommandlineJava;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.util.JavaEnvUtils;
+
+/**
+ * JavaCC compiler compiler task.
+ *
+ */
+public class JavaCC extends Task {
+
+ // keys to optional attributes
+ private static final String LOOKAHEAD = "LOOKAHEAD";
+ private static final String CHOICE_AMBIGUITY_CHECK = "CHOICE_AMBIGUITY_CHECK";
+ private static final String OTHER_AMBIGUITY_CHECK = "OTHER_AMBIGUITY_CHECK";
+
+ private static final String STATIC = "STATIC";
+ private static final String DEBUG_PARSER = "DEBUG_PARSER";
+ private static final String DEBUG_LOOKAHEAD = "DEBUG_LOOKAHEAD";
+ private static final String DEBUG_TOKEN_MANAGER = "DEBUG_TOKEN_MANAGER";
+ private static final String OPTIMIZE_TOKEN_MANAGER = "OPTIMIZE_TOKEN_MANAGER";
+ private static final String ERROR_REPORTING = "ERROR_REPORTING";
+ private static final String JAVA_UNICODE_ESCAPE = "JAVA_UNICODE_ESCAPE";
+ private static final String UNICODE_INPUT = "UNICODE_INPUT";
+ private static final String IGNORE_CASE = "IGNORE_CASE";
+ private static final String COMMON_TOKEN_ACTION = "COMMON_TOKEN_ACTION";
+ private static final String USER_TOKEN_MANAGER = "USER_TOKEN_MANAGER";
+ private static final String USER_CHAR_STREAM = "USER_CHAR_STREAM";
+ private static final String BUILD_PARSER = "BUILD_PARSER";
+ private static final String BUILD_TOKEN_MANAGER = "BUILD_TOKEN_MANAGER";
+ private static final String SANITY_CHECK = "SANITY_CHECK";
+ private static final String FORCE_LA_CHECK = "FORCE_LA_CHECK";
+ private static final String CACHE_TOKENS = "CACHE_TOKENS";
+ private static final String KEEP_LINE_COLUMN = "KEEP_LINE_COLUMN";
+ private static final String JDK_VERSION = "JDK_VERSION";
+
+ private final Hashtable optionalAttrs = new Hashtable();
+
+ // required attributes
+ private File outputDirectory = null;
+ private File targetFile = null;
+ private File javaccHome = null;
+
+ private CommandlineJava cmdl = new CommandlineJava();
+
+ protected static final int TASKDEF_TYPE_JAVACC = 1;
+ protected static final int TASKDEF_TYPE_JJTREE = 2;
+ protected static final int TASKDEF_TYPE_JJDOC = 3;
+
+ protected static final String[] ARCHIVE_LOCATIONS =
+ new String[] {
+ "JavaCC.zip",
+ "bin/lib/JavaCC.zip",
+ "bin/lib/javacc.jar",
+ "javacc.jar", // used by jpackage for JavaCC 3.x
+ };
+
+ protected static final int[] ARCHIVE_LOCATIONS_VS_MAJOR_VERSION =
+ new int[] {
+ 1,
+ 2,
+ 3,
+ 3,
+ };
+
+ protected static final String COM_PACKAGE = "COM.sun.labs.";
+ protected static final String COM_JAVACC_CLASS = "javacc.Main";
+ protected static final String COM_JJTREE_CLASS = "jjtree.Main";
+ protected static final String COM_JJDOC_CLASS = "jjdoc.JJDocMain";
+
+ protected static final String ORG_PACKAGE_3_0 = "org.netbeans.javacc.";
+ protected static final String ORG_PACKAGE_3_1 = "org.javacc.";
+ protected static final String ORG_JAVACC_CLASS = "parser.Main";
+ protected static final String ORG_JJTREE_CLASS = COM_JJTREE_CLASS;
+ protected static final String ORG_JJDOC_CLASS = COM_JJDOC_CLASS;
+
+ private String maxMemory = null;
+
+ /**
+ * Sets the LOOKAHEAD grammar option.
+ * @param lookahead an <code>int</code> value.
+ */
+ public void setLookahead(int lookahead) {
+ optionalAttrs.put(LOOKAHEAD, new Integer(lookahead));
+ }
+
+ /**
+ * Sets the CHOICE_AMBIGUITY_CHECK grammar option.
+ * @param choiceAmbiguityCheck an <code>int</code> value.
+ */
+ public void setChoiceambiguitycheck(int choiceAmbiguityCheck) {
+ optionalAttrs.put(CHOICE_AMBIGUITY_CHECK, new Integer(choiceAmbiguityCheck));
+ }
+
+ /**
+ * Sets the OTHER_AMBIGUITY_CHECK grammar option.
+ * @param otherAmbiguityCheck an <code>int</code> value.
+ */
+ public void setOtherambiguityCheck(int otherAmbiguityCheck) {
+ optionalAttrs.put(OTHER_AMBIGUITY_CHECK, new Integer(otherAmbiguityCheck));
+ }
+
+ /**
+ * Sets the STATIC grammar option.
+ * @param staticParser a <code>boolean</code> value.
+ */
+ public void setStatic(boolean staticParser) {
+ optionalAttrs.put(STATIC, staticParser ? Boolean.TRUE : Boolean.FALSE);
+ }
+
+ /**
+ * Sets the DEBUG_PARSER grammar option.
+ * @param debugParser a <code>boolean</code> value.
+ */
+ public void setDebugparser(boolean debugParser) {
+ optionalAttrs.put(DEBUG_PARSER, debugParser ? Boolean.TRUE : Boolean.FALSE);
+ }
+
+ /**
+ * Sets the DEBUG_LOOKAHEAD grammar option.
+ * @param debugLookahead a <code>boolean</code> value.
+ */
+ public void setDebuglookahead(boolean debugLookahead) {
+ optionalAttrs.put(DEBUG_LOOKAHEAD, debugLookahead ? Boolean.TRUE : Boolean.FALSE);
+ }
+
+ /**
+ * Sets the DEBUG_TOKEN_MANAGER grammar option.
+ * @param debugTokenManager a <code>boolean</code> value.
+ */
+ public void setDebugtokenmanager(boolean debugTokenManager) {
+ optionalAttrs.put(DEBUG_TOKEN_MANAGER, debugTokenManager ? Boolean.TRUE : Boolean.FALSE);
+ }
+
+ /**
+ * Sets the OPTIMIZE_TOKEN_MANAGER grammar option.
+ * @param optimizeTokenManager a <code>boolean</code> value.
+ */
+ public void setOptimizetokenmanager(boolean optimizeTokenManager) {
+ optionalAttrs.put(OPTIMIZE_TOKEN_MANAGER,
+ optimizeTokenManager ? Boolean.TRUE : Boolean.FALSE);
+ }
+
+ /**
+ * Sets the ERROR_REPORTING grammar option.
+ * @param errorReporting a <code>boolean</code> value.
+ */
+ public void setErrorreporting(boolean errorReporting) {
+ optionalAttrs.put(ERROR_REPORTING, errorReporting ? Boolean.TRUE : Boolean.FALSE);
+ }
+
+ /**
+ * Sets the JAVA_UNICODE_ESCAPE grammar option.
+ * @param javaUnicodeEscape a <code>boolean</code> value.
+ */
+ public void setJavaunicodeescape(boolean javaUnicodeEscape) {
+ optionalAttrs.put(JAVA_UNICODE_ESCAPE, javaUnicodeEscape ? Boolean.TRUE : Boolean.FALSE);
+ }
+
+ /**
+ * Sets the UNICODE_INPUT grammar option.
+ * @param unicodeInput a <code>boolean</code> value.
+ */
+ public void setUnicodeinput(boolean unicodeInput) {
+ optionalAttrs.put(UNICODE_INPUT, unicodeInput ? Boolean.TRUE : Boolean.FALSE);
+ }
+
+ /**
+ * Sets the IGNORE_CASE grammar option.
+ * @param ignoreCase a <code>boolean</code> value.
+ */
+ public void setIgnorecase(boolean ignoreCase) {
+ optionalAttrs.put(IGNORE_CASE, ignoreCase ? Boolean.TRUE : Boolean.FALSE);
+ }
+
+ /**
+ * Sets the COMMON_TOKEN_ACTION grammar option.
+ * @param commonTokenAction a <code>boolean</code> value.
+ */
+ public void setCommontokenaction(boolean commonTokenAction) {
+ optionalAttrs.put(COMMON_TOKEN_ACTION, commonTokenAction ? Boolean.TRUE : Boolean.FALSE);
+ }
+
+ /**
+ * Sets the USER_TOKEN_MANAGER grammar option.
+ * @param userTokenManager a <code>boolean</code> value.
+ */
+ public void setUsertokenmanager(boolean userTokenManager) {
+ optionalAttrs.put(USER_TOKEN_MANAGER, userTokenManager ? Boolean.TRUE : Boolean.FALSE);
+ }
+
+ /**
+ * Sets the USER_CHAR_STREAM grammar option.
+ * @param userCharStream a <code>boolean</code> value.
+ */
+ public void setUsercharstream(boolean userCharStream) {
+ optionalAttrs.put(USER_CHAR_STREAM, userCharStream ? Boolean.TRUE : Boolean.FALSE);
+ }
+
+ /**
+ * Sets the BUILD_PARSER grammar option.
+ * @param buildParser a <code>boolean</code> value.
+ */
+ public void setBuildparser(boolean buildParser) {
+ optionalAttrs.put(BUILD_PARSER, buildParser ? Boolean.TRUE : Boolean.FALSE);
+ }
+
+ /**
+ * Sets the BUILD_TOKEN_MANAGER grammar option.
+ * @param buildTokenManager a <code>boolean</code> value.
+ */
+ public void setBuildtokenmanager(boolean buildTokenManager) {
+ optionalAttrs.put(BUILD_TOKEN_MANAGER, buildTokenManager ? Boolean.TRUE : Boolean.FALSE);
+ }
+
+ /**
+ * Sets the SANITY_CHECK grammar option.
+ * @param sanityCheck a <code>boolean</code> value.
+ */
+ public void setSanitycheck(boolean sanityCheck) {
+ optionalAttrs.put(SANITY_CHECK, sanityCheck ? Boolean.TRUE : Boolean.FALSE);
+ }
+
+ /**
+ * Sets the FORCE_LA_CHECK grammar option.
+ * @param forceLACheck a <code>boolean</code> value.
+ */
+ public void setForcelacheck(boolean forceLACheck) {
+ optionalAttrs.put(FORCE_LA_CHECK, forceLACheck ? Boolean.TRUE : Boolean.FALSE);
+ }
+
+ /**
+ * Sets the CACHE_TOKENS grammar option.
+ * @param cacheTokens a <code>boolean</code> value.
+ */
+ public void setCachetokens(boolean cacheTokens) {
+ optionalAttrs.put(CACHE_TOKENS, cacheTokens ? Boolean.TRUE : Boolean.FALSE);
+ }
+
+ /**
+ * Sets the KEEP_LINE_COLUMN grammar option.
+ * @param keepLineColumn a <code>boolean</code> value.
+ */
+ public void setKeeplinecolumn(boolean keepLineColumn) {
+ optionalAttrs.put(KEEP_LINE_COLUMN, keepLineColumn ? Boolean.TRUE : Boolean.FALSE);
+ }
+
+ /**
+ * Sets the JDK_VERSION option.
+ * @param jdkVersion the version to use.
+ * @since Ant1.7
+ */
+ public void setJDKversion(String jdkVersion) {
+ optionalAttrs.put(JDK_VERSION, jdkVersion);
+ }
+
+ /**
+ * The directory to write the generated files to.
+ * If not set, the files are written to the directory
+ * containing the grammar file.
+ * @param outputDirectory the output directory.
+ */
+ public void setOutputdirectory(File outputDirectory) {
+ this.outputDirectory = outputDirectory;
+ }
+
+ /**
+ * The grammar file to process.
+ * @param targetFile the grammar file.
+ */
+ public void setTarget(File targetFile) {
+ this.targetFile = targetFile;
+ }
+
+ /**
+ * The directory containing the JavaCC distribution.
+ * @param javaccHome the directory.
+ */
+ public void setJavacchome(File javaccHome) {
+ this.javaccHome = javaccHome;
+ }
+
+ /**
+ * Corresponds -Xmx.
+ *
+ * @param max max memory parameter.
+ * @since Ant 1.8.3
+ */
+ public void setMaxmemory(String max) {
+ maxMemory = max;
+ }
+
+ /**
+ * Constructor
+ */
+ public JavaCC() {
+ cmdl.setVm(JavaEnvUtils.getJreExecutable("java"));
+ }
+
+ /**
+ * Run the task.
+ * @throws BuildException on error.
+ */
+ public void execute() throws BuildException {
+
+ // load command line with optional attributes
+ Enumeration iter = optionalAttrs.keys();
+ while (iter.hasMoreElements()) {
+ String name = (String) iter.nextElement();
+ Object value = optionalAttrs.get(name);
+ cmdl.createArgument().setValue("-" + name + ":" + value.toString());
+ }
+
+ // check the target is a file
+ if (targetFile == null || !targetFile.isFile()) {
+ throw new BuildException("Invalid target: " + targetFile);
+ }
+
+ // use the directory containing the target as the output directory
+ if (outputDirectory == null) {
+ outputDirectory = new File(targetFile.getParent());
+ } else if (!outputDirectory.isDirectory()) {
+ throw new BuildException("Outputdir not a directory.");
+ }
+ cmdl.createArgument().setValue("-OUTPUT_DIRECTORY:"
+ + outputDirectory.getAbsolutePath());
+
+ // determine if the generated java file is up-to-date
+ final File javaFile = getOutputJavaFile(outputDirectory, targetFile);
+ if (javaFile.exists()
+ && targetFile.lastModified() < javaFile.lastModified()) {
+ log("Target is already built - skipping (" + targetFile + ")",
+ Project.MSG_VERBOSE);
+ return;
+ }
+ cmdl.createArgument().setValue(targetFile.getAbsolutePath());
+
+ final Path classpath = cmdl.createClasspath(getProject());
+ final File javaccJar = JavaCC.getArchiveFile(javaccHome);
+ classpath.createPathElement().setPath(javaccJar.getAbsolutePath());
+ classpath.addJavaRuntime();
+
+ cmdl.setClassname(JavaCC.getMainClass(classpath,
+ JavaCC.TASKDEF_TYPE_JAVACC));
+
+ cmdl.setMaxmemory(maxMemory);
+ final Commandline.Argument arg = cmdl.createVmArgument();
+ arg.setValue("-Dinstall.root=" + javaccHome.getAbsolutePath());
+
+ Execute.runCommand(this, cmdl.getCommandline());
+ }
+
+ /**
+ * Helper method to retrieve the path used to store the JavaCC.zip
+ * or javacc.jar which is different from versions.
+ *
+ * @param home the javacc home path directory.
+ * @throws BuildException thrown if the home directory is invalid
+ * or if the archive could not be found despite attempts to do so.
+ * @return the file object pointing to the JavaCC archive.
+ */
+ protected static File getArchiveFile(File home) throws BuildException {
+ return new File(home,
+ ARCHIVE_LOCATIONS[getArchiveLocationIndex(home)]);
+ }
+
+ /**
+ * Helper method to retrieve main class which is different from versions.
+ * @param home the javacc home path directory.
+ * @param type the taskdef.
+ * @throws BuildException thrown if the home directory is invalid
+ * or if the archive could not be found despite attempts to do so.
+ * @return the main class for the taskdef.
+ */
+ protected static String getMainClass(File home, int type)
+ throws BuildException {
+
+ Path p = new Path(null);
+ p.createPathElement().setLocation(getArchiveFile(home));
+ p.addJavaRuntime();
+ return getMainClass(p, type);
+ }
+
+ /**
+ * Helper method to retrieve main class which is different from versions.
+ * @param path classpath to search in.
+ * @param type the taskdef.
+ * @throws BuildException thrown if the home directory is invalid
+ * or if the archive could not be found despite attempts to do so.
+ * @return the main class for the taskdef.
+ * @since Ant 1.7
+ */
+ protected static String getMainClass(Path path, int type)
+ throws BuildException {
+ String packagePrefix = null;
+ String mainClass = null;
+
+ AntClassLoader l = null;
+ try {
+ l = AntClassLoader.newAntClassLoader(null, null,
+ path
+ .concatSystemClasspath("ignore"),
+ true);
+ String javaccClass = COM_PACKAGE + COM_JAVACC_CLASS;
+ InputStream is = l.getResourceAsStream(javaccClass.replace('.', '/')
+ + ".class");
+ if (is != null) {
+ packagePrefix = COM_PACKAGE;
+ switch (type) {
+ case TASKDEF_TYPE_JAVACC:
+ mainClass = COM_JAVACC_CLASS;
+
+ break;
+
+ case TASKDEF_TYPE_JJTREE:
+ mainClass = COM_JJTREE_CLASS;
+
+ break;
+
+ case TASKDEF_TYPE_JJDOC:
+ mainClass = COM_JJDOC_CLASS;
+
+ break;
+ default:
+ // Fall Through
+ }
+ } else {
+ javaccClass = ORG_PACKAGE_3_1 + ORG_JAVACC_CLASS;
+ is = l.getResourceAsStream(javaccClass.replace('.', '/')
+ + ".class");
+ if (is != null) {
+ packagePrefix = ORG_PACKAGE_3_1;
+ } else {
+ javaccClass = ORG_PACKAGE_3_0 + ORG_JAVACC_CLASS;
+ is = l.getResourceAsStream(javaccClass.replace('.', '/')
+ + ".class");
+ if (is != null) {
+ packagePrefix = ORG_PACKAGE_3_0;
+ }
+ }
+
+ if (is != null) {
+ switch (type) {
+ case TASKDEF_TYPE_JAVACC:
+ mainClass = ORG_JAVACC_CLASS;
+
+ break;
+
+ case TASKDEF_TYPE_JJTREE:
+ mainClass = ORG_JJTREE_CLASS;
+
+ break;
+
+ case TASKDEF_TYPE_JJDOC:
+ mainClass = ORG_JJDOC_CLASS;
+
+ break;
+ default:
+ // Fall Through
+ }
+ }
+ }
+
+ if (packagePrefix == null) {
+ throw new BuildException("failed to load JavaCC");
+ }
+ if (mainClass == null) {
+ throw new BuildException("unknown task type " + type);
+ }
+ return packagePrefix + mainClass;
+ } finally {
+ if (l != null) {
+ l.cleanup();
+ }
+ }
+ }
+
+ /**
+ * Helper method to determine the archive location index.
+ *
+ * @param home the javacc home path directory.
+ * @throws BuildException thrown if the home directory is invalid
+ * or if the archive could not be found despite attempts to do so.
+ * @return the archive location index
+ */
+ private static int getArchiveLocationIndex(File home)
+ throws BuildException {
+
+ if (home == null || !home.isDirectory()) {
+ throw new BuildException("JavaCC home must be a valid directory.");
+ }
+
+ for (int i = 0; i < ARCHIVE_LOCATIONS.length; i++) {
+ File f = new File(home, ARCHIVE_LOCATIONS[i]);
+
+ if (f.exists()) {
+ return i;
+ }
+ }
+
+ throw new BuildException("Could not find a path to JavaCC.zip "
+ + "or javacc.jar from '" + home + "'.");
+ }
+
+ /**
+ * Helper method to determine the major version number of JavaCC.
+ *
+ * @param home the javacc home path directory.
+ * @throws BuildException thrown if the home directory is invalid
+ * or if the archive could not be found despite attempts to do so.
+ * @return a the major version number
+ */
+ protected static int getMajorVersionNumber(File home)
+ throws BuildException {
+
+ return
+ ARCHIVE_LOCATIONS_VS_MAJOR_VERSION[getArchiveLocationIndex(home)];
+ }
+
+ /**
+ * Determines the output Java file to be generated by the given grammar
+ * file.
+ *
+ */
+ private File getOutputJavaFile(File outputdir, File srcfile) {
+ String path = srcfile.getPath();
+
+ // Extract file's base-name
+ int startBasename = path.lastIndexOf(File.separator);
+ if (startBasename != -1) {
+ path = path.substring(startBasename + 1);
+ }
+
+ // Replace the file's extension with '.java'
+ int startExtn = path.lastIndexOf('.');
+ if (startExtn != -1) {
+ path = path.substring(0, startExtn) + ".java";
+ } else {
+ path += ".java";
+ }
+
+ // Change the directory
+ if (outputdir != null) {
+ path = outputdir + File.separator + path;
+ }
+
+ return new File(path);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/javah/Gcjh.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/javah/Gcjh.java
new file mode 100644
index 00000000..712bb76a
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/javah/Gcjh.java
@@ -0,0 +1,89 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.javah;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.taskdefs.Execute;
+import org.apache.tools.ant.taskdefs.optional.Javah;
+import org.apache.tools.ant.types.Commandline;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.util.JavaEnvUtils;
+
+/**
+ * Adapter to the native gcjh compiler.
+ *
+ * @since Ant 1.8.2
+ */
+public class Gcjh implements JavahAdapter {
+
+ public static final String IMPLEMENTATION_NAME = "gcjh";
+
+ /**
+ * Performs the actual compilation.
+ */
+ public boolean compile(Javah javah) throws BuildException {
+ Commandline cmd = setupGcjhCommand(javah);
+ try {
+ Execute.runCommand(javah, cmd.getCommandline());
+ return true;
+ } catch (BuildException e) {
+ if (e.getMessage().indexOf("failed with return code") == -1) {
+ throw e;
+ }
+ }
+ return false;
+ }
+
+ private Commandline setupGcjhCommand(Javah javah) {
+ Commandline cmd = new Commandline();
+ cmd.setExecutable(JavaEnvUtils.getJdkExecutable("gcjh"));
+
+ if (javah.getDestdir() != null) {
+ cmd.createArgument().setValue("-d");
+ cmd.createArgument().setFile(javah.getDestdir());
+ }
+
+ if (javah.getOutputfile() != null) {
+ cmd.createArgument().setValue("-o");
+ cmd.createArgument().setFile(javah.getOutputfile());
+ }
+
+ Path cp = new Path(javah.getProject());
+ if (javah.getBootclasspath() != null) {
+ cp.append(javah.getBootclasspath());
+ }
+ cp = cp.concatSystemBootClasspath("ignore");
+ if (javah.getClasspath() != null) {
+ cp.append(javah.getClasspath());
+ }
+ if (cp.size() > 0) {
+ cmd.createArgument().setValue("--classpath");
+ cmd.createArgument().setPath(cp);
+ }
+
+ if (!javah.getOld()) {
+ cmd.createArgument().setValue("-jni");
+ }
+
+ cmd.addArguments(javah.getCurrentArgs());
+
+ javah.logAndAddFiles(cmd);
+ return cmd;
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/javah/JavahAdapter.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/javah/JavahAdapter.java
new file mode 100644
index 00000000..121fa429
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/javah/JavahAdapter.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.javah;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.taskdefs.optional.Javah;
+
+/**
+ * Interface for different backend implementations of the Javah task.
+ *
+ * @since Ant 1.6.3
+ */
+public interface JavahAdapter {
+ /**
+ * Performs the actual compilation.
+ * @param javah the calling javah task.
+ * @return true if the compilation was successful.
+ * @throws BuildException if there is an error.
+ * @since Ant 1.6.3
+ */
+ boolean compile(Javah javah) throws BuildException;
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/javah/JavahAdapterFactory.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/javah/JavahAdapterFactory.java
new file mode 100644
index 00000000..d98b4276
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/javah/JavahAdapterFactory.java
@@ -0,0 +1,120 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.javah;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.ProjectComponent;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.util.ClasspathUtils;
+import org.apache.tools.ant.util.JavaEnvUtils;
+
+/**
+ * Creates the JavahAdapter based on the user choice and
+ * potentially the VM vendor.
+ *
+ * @since Ant 1.6.3
+ */
+// CheckStyle:HideUtilityClassConstructorCheck OFF (bc)
+public class JavahAdapterFactory {
+
+ /**
+ * Determines the default choice of adapter based on the VM
+ * vendor.
+ *
+ * @return the default choice of adapter based on the VM
+ * vendor
+ */
+ public static String getDefault() {
+ if (JavaEnvUtils.isKaffe()) {
+ return Kaffeh.IMPLEMENTATION_NAME;
+ } else if (JavaEnvUtils.isGij()) {
+ return Gcjh.IMPLEMENTATION_NAME;
+ }
+ return SunJavah.IMPLEMENTATION_NAME;
+ }
+
+ /**
+ * Creates the JavahAdapter based on the user choice and
+ * potentially the VM vendor.
+ *
+ * @param choice the user choice (if any).
+ * @param log a ProjectComponent instance used to access Ant's
+ * logging system.
+ * @return The adapter to use.
+ * @throws BuildException if there is an error.
+ */
+ public static JavahAdapter getAdapter(String choice,
+ ProjectComponent log)
+ throws BuildException {
+ return getAdapter(choice, log, null);
+ }
+
+ /**
+ * Creates the JavahAdapter based on the user choice and
+ * potentially the VM vendor.
+ *
+ * @param choice the user choice (if any).
+ * @param log a ProjectComponent instance used to access Ant's
+ * logging system.
+ * @param classpath the classpath to use when looking up an
+ * adapter class
+ * @return The adapter to use.
+ * @throws BuildException if there is an error.
+ * @since Ant 1.8.0
+ */
+ public static JavahAdapter getAdapter(String choice,
+ ProjectComponent log,
+ Path classpath)
+ throws BuildException {
+ if ((JavaEnvUtils.isKaffe() && choice == null)
+ || Kaffeh.IMPLEMENTATION_NAME.equals(choice)) {
+ return new Kaffeh();
+ } else if ((JavaEnvUtils.isGij() && choice == null)
+ || Gcjh.IMPLEMENTATION_NAME.equals(choice)) {
+ return new Gcjh();
+ } else if (SunJavah.IMPLEMENTATION_NAME.equals(choice)) {
+ return new SunJavah();
+ } else if (choice != null) {
+ return resolveClassName(choice,
+ // Memory leak in line below
+ log.getProject()
+ .createClassLoader(classpath));
+ }
+
+ // This default has been good enough until Ant 1.6.3, so stick
+ // with it
+ return new SunJavah();
+ }
+
+ /**
+ * Tries to resolve the given classname into a javah adapter.
+ * Throws a fit if it can't.
+ *
+ * @param className The fully qualified classname to be created.
+ * @param loader the classloader to use
+ * @throws BuildException This is the fit that is thrown if className
+ * isn't an instance of JavahAdapter.
+ */
+ private static JavahAdapter resolveClassName(String className,
+ ClassLoader loader)
+ throws BuildException {
+ return (JavahAdapter) ClasspathUtils.newInstance(className,
+ loader != null ? loader :
+ JavahAdapterFactory.class.getClassLoader(), JavahAdapter.class);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/javah/Kaffeh.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/javah/Kaffeh.java
new file mode 100644
index 00000000..d37f7717
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/javah/Kaffeh.java
@@ -0,0 +1,94 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.javah;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.taskdefs.Execute;
+import org.apache.tools.ant.taskdefs.optional.Javah;
+import org.apache.tools.ant.types.Commandline;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.util.JavaEnvUtils;
+
+/**
+ * Adapter to the native kaffeh compiler.
+ *
+ * @since Ant 1.6.3
+ */
+public class Kaffeh implements JavahAdapter {
+
+ /** the name of the javah adapter - kaffeh */
+ public static final String IMPLEMENTATION_NAME = "kaffeh";
+
+ /**
+ * Performs the actual compilation.
+ * @param javah the calling javah task.
+ * @return true if the compilation was successful.
+ * @throws BuildException if there is an error.
+ * @since Ant 1.6.3
+ */
+ public boolean compile(Javah javah) throws BuildException {
+ Commandline cmd = setupKaffehCommand(javah);
+ try {
+ Execute.runCommand(javah, cmd.getCommandline());
+ return true;
+ } catch (BuildException e) {
+ if (e.getMessage().indexOf("failed with return code") == -1) {
+ throw e;
+ }
+ }
+ return false;
+ }
+
+ private Commandline setupKaffehCommand(Javah javah) {
+ Commandline cmd = new Commandline();
+ cmd.setExecutable(JavaEnvUtils.getJdkExecutable("kaffeh"));
+
+ if (javah.getDestdir() != null) {
+ cmd.createArgument().setValue("-d");
+ cmd.createArgument().setFile(javah.getDestdir());
+ }
+
+ if (javah.getOutputfile() != null) {
+ cmd.createArgument().setValue("-o");
+ cmd.createArgument().setFile(javah.getOutputfile());
+ }
+
+ Path cp = new Path(javah.getProject());
+ if (javah.getBootclasspath() != null) {
+ cp.append(javah.getBootclasspath());
+ }
+ cp = cp.concatSystemBootClasspath("ignore");
+ if (javah.getClasspath() != null) {
+ cp.append(javah.getClasspath());
+ }
+ if (cp.size() > 0) {
+ cmd.createArgument().setValue("-classpath");
+ cmd.createArgument().setPath(cp);
+ }
+
+ if (!javah.getOld()) {
+ cmd.createArgument().setValue("-jni");
+ }
+
+ cmd.addArguments(javah.getCurrentArgs());
+
+ javah.logAndAddFiles(cmd);
+ return cmd;
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/javah/SunJavah.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/javah/SunJavah.java
new file mode 100644
index 00000000..0b1655ad
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/javah/SunJavah.java
@@ -0,0 +1,123 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.javah;
+
+import java.io.File;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.launch.Locator;
+import org.apache.tools.ant.taskdefs.ExecuteJava;
+import org.apache.tools.ant.taskdefs.optional.Javah;
+import org.apache.tools.ant.types.Commandline;
+import org.apache.tools.ant.types.Path;
+
+
+/**
+ * Adapter to com.sun.tools.javah.oldjavah.Main or com.sun.tools.javah.Main.
+ *
+ * @since Ant 1.6.3
+ */
+public class SunJavah implements JavahAdapter {
+
+ /** the name of the javah adapter - sun */
+ public static final String IMPLEMENTATION_NAME = "sun";
+
+ /**
+ * Performs the actual compilation.
+ * @param javah the calling javah task.
+ * @return true if the compilation was successful.
+ * @throws BuildException if there is an error.
+ * @since Ant 1.6.3
+ */
+ public boolean compile(Javah javah) throws BuildException {
+ Commandline cmd = setupJavahCommand(javah);
+ ExecuteJava ej = new ExecuteJava();
+ Class c = null;
+ try {
+ try {
+ // first search for the "old" javah class in 1.4.2 tools.jar
+ c = Class.forName("com.sun.tools.javah.oldjavah.Main");
+ } catch (ClassNotFoundException cnfe) {
+ // assume older than 1.4.2 tools.jar
+ c = Class.forName("com.sun.tools.javah.Main");
+ }
+ } catch (ClassNotFoundException ex) {
+ throw new BuildException(
+ "Can't load javah", ex, javah.getLocation());
+ }
+ cmd.setExecutable(c.getName());
+ ej.setJavaCommand(cmd);
+ File f = Locator.getClassSource(c);
+ if (f != null) {
+ ej.setClasspath(new Path(javah.getProject(), f.getPath()));
+ }
+ return ej.fork(javah) == 0;
+ }
+
+ private Commandline setupJavahCommand(Javah javah) {
+ Commandline cmd = new Commandline();
+
+ if (javah.getDestdir() != null) {
+ cmd.createArgument().setValue("-d");
+ cmd.createArgument().setFile(javah.getDestdir());
+ }
+
+ if (javah.getOutputfile() != null) {
+ cmd.createArgument().setValue("-o");
+ cmd.createArgument().setFile(javah.getOutputfile());
+ }
+
+ if (javah.getClasspath() != null) {
+ cmd.createArgument().setValue("-classpath");
+ cmd.createArgument().setPath(javah.getClasspath());
+ }
+
+ if (javah.getVerbose()) {
+ cmd.createArgument().setValue("-verbose");
+ }
+ if (javah.getOld()) {
+ cmd.createArgument().setValue("-old");
+ }
+ if (javah.getForce()) {
+ cmd.createArgument().setValue("-force");
+ }
+ if (javah.getStubs() && !javah.getOld()) {
+ throw new BuildException(
+ "stubs only available in old mode.", javah.getLocation());
+ }
+
+ if (javah.getStubs()) {
+ cmd.createArgument().setValue("-stubs");
+ }
+ Path bcp = new Path(javah.getProject());
+ if (javah.getBootclasspath() != null) {
+ bcp.append(javah.getBootclasspath());
+ }
+ bcp = bcp.concatSystemBootClasspath("ignore");
+ if (bcp.size() > 0) {
+ cmd.createArgument().setValue("-bootclasspath");
+ cmd.createArgument().setPath(bcp);
+ }
+
+ cmd.addArguments(javah.getCurrentArgs());
+
+ javah.logAndAddFiles(cmd);
+ return cmd;
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/jdepend/JDependTask.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/jdepend/JDependTask.java
new file mode 100644
index 00000000..21f03fe7
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/jdepend/JDependTask.java
@@ -0,0 +1,684 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.jdepend;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.util.Map;
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.taskdefs.Execute;
+import org.apache.tools.ant.taskdefs.ExecuteWatchdog;
+import org.apache.tools.ant.taskdefs.LogStreamHandler;
+import org.apache.tools.ant.types.Commandline;
+import org.apache.tools.ant.types.CommandlineJava;
+import org.apache.tools.ant.types.EnumeratedAttribute;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.types.PatternSet;
+import org.apache.tools.ant.types.Reference;
+import org.apache.tools.ant.util.FileUtils;
+import org.apache.tools.ant.util.LoaderUtils;
+
+/**
+ * Runs JDepend tests.
+ *
+ * <p>JDepend is a tool to generate design quality metrics for each Java package.
+ * It has been initially created by Mike Clark. JDepend can be found at <a
+ * href="http://www.clarkware.com/software/JDepend.html">http://www.clarkware.com/software/JDepend.html</a>.
+ *
+ * The current implementation spawn a new Java VM.
+ *
+ */
+public class JDependTask extends Task {
+ //private CommandlineJava commandline = new CommandlineJava();
+
+ // required attributes
+ private Path sourcesPath; // Deprecated!
+ private Path classesPath; // Use this going forward
+
+ // optional attributes
+ private File outputFile;
+ private File dir;
+ private Path compileClasspath;
+ private boolean haltonerror = false;
+ private boolean fork = false;
+ private Long timeout = null;
+
+ private String jvm = null;
+ private String format = "text";
+ private PatternSet defaultPatterns = new PatternSet();
+
+ private static Constructor packageFilterC;
+ private static Method setFilter;
+
+ private boolean includeRuntime = false;
+ private Path runtimeClasses = null;
+
+ static {
+ try {
+ Class packageFilter =
+ Class.forName("jdepend.framework.PackageFilter");
+ packageFilterC =
+ packageFilter.getConstructor(new Class[] {java.util.Collection.class});
+ setFilter =
+ jdepend.textui.JDepend.class.getDeclaredMethod("setFilter",
+ new Class[] {packageFilter});
+ } catch (Throwable t) {
+ if (setFilter == null) {
+ packageFilterC = null;
+ }
+ }
+ }
+
+ /**
+ * If true,
+ * include jdepend.jar in the forked VM.
+ *
+ * @param b include ant run time yes or no
+ * @since Ant 1.6
+ */
+ public void setIncluderuntime(boolean b) {
+ includeRuntime = b;
+ }
+
+ /**
+ * Set the timeout value (in milliseconds).
+ *
+ * <p>If the operation is running for more than this value, the jdepend
+ * will be canceled. (works only when in 'fork' mode).</p>
+ * @param value the maximum time (in milliseconds) allowed before
+ * declaring the test as 'timed-out'
+ * @see #setFork(boolean)
+ */
+ public void setTimeout(Long value) {
+ timeout = value;
+ }
+
+ /**
+ * @return the timeout value
+ */
+ public Long getTimeout() {
+ return timeout;
+ }
+
+ /**
+ * The output file name.
+ *
+ * @param outputFile the output file name
+ */
+ public void setOutputFile(File outputFile) {
+ this.outputFile = outputFile;
+ }
+
+ /**
+ * @return the output file name
+ */
+ public File getOutputFile() {
+ return outputFile;
+ }
+
+ /**
+ * Whether or not to halt on failure. Default: false.
+ * @param haltonerror the value to set
+ */
+ public void setHaltonerror(boolean haltonerror) {
+ this.haltonerror = haltonerror;
+ }
+
+ /**
+ * @return the value of the haltonerror attribute
+ */
+ public boolean getHaltonerror() {
+ return haltonerror;
+ }
+
+ /**
+ * If true, forks into a new JVM. Default: false.
+ *
+ * @param value <tt>true</tt> if a JVM should be forked,
+ * otherwise <tt>false<tt>
+ */
+ public void setFork(boolean value) {
+ fork = value;
+ }
+
+ /**
+ * @return the value of the fork attribute
+ */
+ public boolean getFork() {
+ return fork;
+ }
+
+ /**
+ * The command used to invoke a forked Java Virtual Machine.
+ *
+ * Default is <tt>java</tt>. Ignored if no JVM is forked.
+ * @param value the new VM to use instead of <tt>java</tt>
+ * @see #setFork(boolean)
+ */
+ public void setJvm(String value) {
+ jvm = value;
+
+ }
+
+ /**
+ * Adds a path to source code to analyze.
+ * @return a source path
+ * @deprecated since 1.6.x.
+ */
+ public Path createSourcespath() {
+ if (sourcesPath == null) {
+ sourcesPath = new Path(getProject());
+ }
+ return sourcesPath.createPath();
+ }
+
+ /**
+ * Gets the sourcepath.
+ * @return the sources path
+ * @deprecated since 1.6.x.
+ */
+ public Path getSourcespath() {
+ return sourcesPath;
+ }
+
+ /**
+ * Adds a path to class code to analyze.
+ * @return a classes path
+ */
+ public Path createClassespath() {
+ if (classesPath == null) {
+ classesPath = new Path(getProject());
+ }
+ return classesPath.createPath();
+ }
+
+ /**
+ * Gets the classespath.
+ * @return the classes path
+ */
+ public Path getClassespath() {
+ return classesPath;
+ }
+
+ /**
+ * The directory to invoke the VM in. Ignored if no JVM is forked.
+ * @param dir the directory to invoke the JVM from.
+ * @see #setFork(boolean)
+ */
+ public void setDir(File dir) {
+ this.dir = dir;
+ }
+
+ /**
+ * @return the dir attribute
+ */
+ public File getDir() {
+ return dir;
+ }
+
+ /**
+ * Set the classpath to be used for this compilation.
+ * @param classpath a class path to be used
+ */
+ public void setClasspath(Path classpath) {
+ if (compileClasspath == null) {
+ compileClasspath = classpath;
+ } else {
+ compileClasspath.append(classpath);
+ }
+ }
+
+ /**
+ * Gets the classpath to be used for this compilation.
+ * @return the class path used for compilation
+ */
+ public Path getClasspath() {
+ return compileClasspath;
+ }
+
+ /**
+ * Adds a path to the classpath.
+ * @return a classpath
+ */
+ public Path createClasspath() {
+ if (compileClasspath == null) {
+ compileClasspath = new Path(getProject());
+ }
+ return compileClasspath.createPath();
+ }
+
+ /**
+ * Create a new JVM argument. Ignored if no JVM is forked.
+ * @param commandline the commandline to create the argument on
+ * @return create a new JVM argument so that any argument can
+ * be passed to the JVM.
+ * @see #setFork(boolean)
+ */
+ public Commandline.Argument createJvmarg(CommandlineJava commandline) {
+ return commandline.createVmArgument();
+ }
+
+ /**
+ * Adds a reference to a classpath defined elsewhere.
+ * @param r a classpath reference
+ */
+ public void setClasspathRef(Reference r) {
+ createClasspath().setRefid(r);
+ }
+
+ /**
+ * add a name entry on the exclude list
+ * @return a pattern for the excludes
+ */
+ public PatternSet.NameEntry createExclude() {
+ return defaultPatterns.createExclude();
+ }
+
+ /**
+ * @return the excludes patterns
+ */
+ public PatternSet getExcludes() {
+ return defaultPatterns;
+ }
+
+ /**
+ * The format to write the output in, "xml" or "text".
+ *
+ * @param ea xml or text
+ */
+ public void setFormat(FormatAttribute ea) {
+ format = ea.getValue();
+ }
+
+ /**
+ * A class for the enumerated attribute format,
+ * values are xml and text.
+ * @see EnumeratedAttribute
+ */
+ public static class FormatAttribute extends EnumeratedAttribute {
+ private String [] formats = new String[]{"xml", "text"};
+
+ /**
+ * @return the enumerated values
+ */
+ public String[] getValues() {
+ return formats;
+ }
+ }
+
+ /**
+ * No problems with this test.
+ */
+ private static final int SUCCESS = 0;
+ /**
+ * An error occurred.
+ */
+ private static final int ERRORS = 1;
+
+ /**
+ * Search for the given resource and add the directory or archive
+ * that contains it to the classpath.
+ *
+ * <p>Doesn't work for archives in JDK 1.1 as the URL returned by
+ * getResource doesn't contain the name of the archive.</p>
+ *
+ * @param resource resource that one wants to lookup
+ * @since Ant 1.6
+ */
+ private void addClasspathEntry(String resource) {
+ /*
+ * pre Ant 1.6 this method used to call getClass().getResource
+ * while Ant 1.6 will call ClassLoader.getResource().
+ *
+ * The difference is that Class.getResource expects a leading
+ * slash for "absolute" resources and will strip it before
+ * delegating to ClassLoader.getResource - so we now have to
+ * emulate Class's behavior.
+ */
+ if (resource.startsWith("/")) {
+ resource = resource.substring(1);
+ } else {
+ resource = "org/apache/tools/ant/taskdefs/optional/jdepend/"
+ + resource;
+ }
+
+ File f = LoaderUtils.getResourceSource(getClass().getClassLoader(),
+ resource);
+ if (f != null) {
+ log("Found " + f.getAbsolutePath(), Project.MSG_DEBUG);
+ runtimeClasses.createPath().setLocation(f);
+ } else {
+ log("Couldn\'t find " + resource, Project.MSG_DEBUG);
+ }
+ }
+
+ /**
+ * execute the task
+ *
+ * @exception BuildException if an error occurs
+ */
+ public void execute() throws BuildException {
+
+ CommandlineJava commandline = new CommandlineJava();
+
+ if ("text".equals(format)) {
+ commandline.setClassname("jdepend.textui.JDepend");
+ } else
+ if ("xml".equals(format)) {
+ commandline.setClassname("jdepend.xmlui.JDepend");
+ }
+
+ if (jvm != null) {
+ commandline.setVm(jvm);
+ }
+ if (getSourcespath() == null && getClassespath() == null) {
+ throw new BuildException("Missing classespath required argument");
+ } else if (getClassespath() == null) {
+ String msg =
+ "sourcespath is deprecated in JDepend >= 2.5 "
+ + "- please convert to classespath";
+ log(msg);
+ }
+
+ // execute the test and get the return code
+ int exitValue = JDependTask.ERRORS;
+ boolean wasKilled = false;
+ if (!getFork()) {
+ exitValue = executeInVM(commandline);
+ } else {
+ ExecuteWatchdog watchdog = createWatchdog();
+ exitValue = executeAsForked(commandline, watchdog);
+ // null watchdog means no timeout, you'd better not check with null
+ if (watchdog != null) {
+ wasKilled = watchdog.killedProcess();
+ }
+ }
+
+ // if there is an error/failure and that it should halt, stop
+ // everything otherwise just log a statement
+ boolean errorOccurred = exitValue == JDependTask.ERRORS || wasKilled;
+
+ if (errorOccurred) {
+ String errorMessage = "JDepend FAILED"
+ + (wasKilled ? " - Timed out" : "");
+
+ if (getHaltonerror()) {
+ throw new BuildException(errorMessage, getLocation());
+ } else {
+ log(errorMessage, Project.MSG_ERR);
+ }
+ }
+ }
+
+ // this comment extract from JUnit Task may also apply here
+ // "in VM is not very nice since it could probably hang the
+ // whole build. IMHO this method should be avoided and it would be best
+ // to remove it in future versions. TBD. (SBa)"
+
+ /**
+ * Execute inside VM.
+ *
+ * @param commandline the command line
+ * @return the return value of the mvm
+ * @exception BuildException if an error occurs
+ */
+ public int executeInVM(CommandlineJava commandline) throws BuildException {
+ jdepend.textui.JDepend jdepend;
+
+ if ("xml".equals(format)) {
+ jdepend = new jdepend.xmlui.JDepend();
+ } else {
+ jdepend = new jdepend.textui.JDepend();
+ }
+
+ FileWriter fw = null;
+ PrintWriter pw = null;
+ if (getOutputFile() != null) {
+ try {
+ fw = new FileWriter(getOutputFile().getPath());
+ } catch (IOException e) {
+ String msg = "JDepend Failed when creating the output file: "
+ + e.getMessage();
+ log(msg);
+ throw new BuildException(msg);
+ }
+ pw = new PrintWriter(fw);
+ jdepend.setWriter(pw);
+ log("Output to be stored in " + getOutputFile().getPath());
+ }
+
+
+ try {
+ if (getClassespath() != null) {
+ // This is the new, better way - use classespath instead
+ // of sourcespath. The code is currently the same - you
+ // need class files in a directory to use this or jar files.
+ String[] cP = getClassespath().list();
+ for (int i = 0; i < cP.length; i++) {
+ File f = new File(cP[i]);
+ // not necessary as JDepend would fail, but why loose
+ // some time?
+ if (!f.exists()) {
+ String msg = "\""
+ + f.getPath()
+ + "\" does not represent a valid"
+ + " file or directory. JDepend would fail.";
+ log(msg);
+ throw new BuildException(msg);
+ }
+ try {
+ jdepend.addDirectory(f.getPath());
+ } catch (IOException e) {
+ String msg =
+ "JDepend Failed when adding a class directory: "
+ + e.getMessage();
+ log(msg);
+ throw new BuildException(msg);
+ }
+ }
+
+ } else if (getSourcespath() != null) {
+
+ // This is the old way and is deprecated - classespath is
+ // the right way to do this and is above
+ String[] sP = getSourcespath().list();
+ for (int i = 0; i < sP.length; i++) {
+ File f = new File(sP[i]);
+
+ // not necessary as JDepend would fail, but why loose
+ // some time?
+ if (!f.exists() || !f.isDirectory()) {
+ String msg = "\""
+ + f.getPath()
+ + "\" does not represent a valid"
+ + " directory. JDepend would fail.";
+ log(msg);
+ throw new BuildException(msg);
+ }
+ try {
+ jdepend.addDirectory(f.getPath());
+ } catch (IOException e) {
+ String msg =
+ "JDepend Failed when adding a source directory: "
+ + e.getMessage();
+ log(msg);
+ throw new BuildException(msg);
+ }
+ }
+ }
+
+ // This bit turns <exclude> child tags into patters to ignore
+ String[] patterns = defaultPatterns.getExcludePatterns(getProject());
+ if (patterns != null && patterns.length > 0) {
+ if (setFilter != null) {
+ Vector v = new Vector();
+ for (int i = 0; i < patterns.length; i++) {
+ v.addElement(patterns[i]);
+ }
+ try {
+ Object o = packageFilterC.newInstance(new Object[] {v});
+ setFilter.invoke(jdepend, new Object[] {o});
+ } catch (Throwable e) {
+ log("excludes will be ignored as JDepend doesn't like me: "
+ + e.getMessage(), Project.MSG_WARN);
+ }
+ } else {
+ log("Sorry, your version of JDepend doesn't support excludes",
+ Project.MSG_WARN);
+ }
+ }
+
+ jdepend.analyze();
+ if (pw.checkError()) {
+ throw new IOException("Encountered an error writing JDepend"
+ + " output");
+ }
+ } catch (IOException ex) {
+ throw new BuildException(ex);
+ } finally {
+ FileUtils.close(pw);
+ FileUtils.close(fw);
+ }
+ return SUCCESS;
+ }
+
+
+ /**
+ * Execute the task by forking a new JVM. The command will block until
+ * it finishes. To know if the process was destroyed or not, use the
+ * <tt>killedProcess()</tt> method of the watchdog class.
+ * @param commandline the commandline for forked jvm
+ * @param watchdog the watchdog in charge of cancelling the test if it
+ * exceeds a certain amount of time. Can be <tt>null</tt>.
+ * @return the result of running the jdepend
+ * @throws BuildException in case of error
+ */
+ // JL: comment extracted from JUnitTask (and slightly modified)
+ public int executeAsForked(CommandlineJava commandline,
+ ExecuteWatchdog watchdog) throws BuildException {
+ runtimeClasses = new Path(getProject());
+ addClasspathEntry("/jdepend/textui/JDepend.class");
+
+ // if not set, auto-create the ClassPath from the project
+ createClasspath();
+
+ // not sure whether this test is needed but cost nothing to put.
+ // hope it will be reviewed by anybody competent
+ if (getClasspath().toString().length() > 0) {
+ createJvmarg(commandline).setValue("-classpath");
+ createJvmarg(commandline).setValue(getClasspath().toString());
+ }
+
+ if (includeRuntime) {
+ Map/*<String, String>*/ env = Execute.getEnvironmentVariables();
+ String cp = (String) env.get("CLASSPATH");
+ if (cp != null) {
+ commandline.createClasspath(getProject()).createPath()
+ .append(new Path(getProject(), cp));
+ }
+ log("Implicitly adding " + runtimeClasses + " to CLASSPATH",
+ Project.MSG_VERBOSE);
+ commandline.createClasspath(getProject()).createPath()
+ .append(runtimeClasses);
+ }
+
+ if (getOutputFile() != null) {
+ // having a space between the file and its path causes commandline
+ // to add quotes around the argument thus making JDepend not taking
+ // it into account. Thus we split it in two
+ commandline.createArgument().setValue("-file");
+ commandline.createArgument().setValue(outputFile.getPath());
+ // we have to find a cleaner way to put this output
+ }
+
+ if (getSourcespath() != null) {
+ // This is deprecated - use classespath in the future
+ String[] sP = getSourcespath().list();
+ for (int i = 0; i < sP.length; i++) {
+ File f = new File(sP[i]);
+
+ // not necessary as JDepend would fail, but why loose
+ // some time?
+ if (!f.exists() || !f.isDirectory()) {
+ throw new BuildException("\"" + f.getPath()
+ + "\" does not represent a valid"
+ + " directory. JDepend would"
+ + " fail.");
+ }
+ commandline.createArgument().setValue(f.getPath());
+ }
+ }
+
+ if (getClassespath() != null) {
+ // This is the new way - use classespath - code is the
+ // same for now
+ String[] cP = getClassespath().list();
+ for (int i = 0; i < cP.length; i++) {
+ File f = new File(cP[i]);
+ // not necessary as JDepend would fail, but why loose
+ // some time?
+ if (!f.exists()) {
+ throw new BuildException("\"" + f.getPath()
+ + "\" does not represent a valid"
+ + " file or directory. JDepend would"
+ + " fail.");
+ }
+ commandline.createArgument().setValue(f.getPath());
+ }
+ }
+
+ Execute execute = new Execute(new LogStreamHandler(this,
+ Project.MSG_INFO, Project.MSG_WARN), watchdog);
+ execute.setCommandline(commandline.getCommandline());
+ if (getDir() != null) {
+ execute.setWorkingDirectory(getDir());
+ execute.setAntRun(getProject());
+ }
+
+ if (getOutputFile() != null) {
+ log("Output to be stored in " + getOutputFile().getPath());
+ }
+ log(commandline.describeCommand(), Project.MSG_VERBOSE);
+ try {
+ return execute.execute();
+ } catch (IOException e) {
+ throw new BuildException("Process fork failed.", e, getLocation());
+ }
+ }
+
+ /**
+ * @return <tt>null</tt> if there is a timeout value, otherwise the
+ * watchdog instance.
+ * @throws BuildException in case of error
+ */
+ protected ExecuteWatchdog createWatchdog() throws BuildException {
+ if (getTimeout() == null) {
+ return null;
+ }
+ return new ExecuteWatchdog(getTimeout().longValue());
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/jlink/ClassNameReader.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/jlink/ClassNameReader.java
new file mode 100644
index 00000000..20e9fc51
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/jlink/ClassNameReader.java
@@ -0,0 +1,139 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.jlink;
+
+import java.io.DataInput;
+import java.io.DataInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Reads just enough of a class file to determine the class' full name.
+ *
+ * <p>Extremely minimal constant pool implementation, mainly to support extracting
+ * strings from a class file.
+ */
+class ConstantPool {
+ // CheckStyle:VisibilityModifier OFF - bc
+ static final
+ byte UTF8 = 1, UNUSED = 2, INTEGER = 3, FLOAT = 4, LONG = 5, DOUBLE = 6,
+ CLASS = 7, STRING = 8, FIELDREF = 9, METHODREF = 10,
+ INTERFACEMETHODREF = 11, NAMEANDTYPE = 12;
+
+ byte[] types;
+
+ Object[] values;
+ // CheckStyle:VisibilityModifier ON
+
+ /**
+ * Create a constant pool.
+ * @param data the data input containing the class.
+ * @throws IOException if there is an error.
+ */
+ ConstantPool(DataInput data) throws IOException {
+ super();
+
+ int count = data.readUnsignedShort();
+ types = new byte [ count ];
+ values = new Object [ count ];
+ // read in all constant pool entries.
+ for (int i = 1; i < count; i++) {
+ byte type = data.readByte();
+ types[i] = type;
+ switch (type) {
+ case UTF8 :
+ values[i] = data.readUTF();
+ break;
+
+ case UNUSED :
+ break;
+
+ case INTEGER :
+ values[i] = new Integer(data.readInt());
+ break;
+
+ case FLOAT :
+ values[i] = new Float(data.readFloat());
+ break;
+
+ case LONG :
+ values[i] = new Long(data.readLong());
+ ++i;
+ break;
+
+ case DOUBLE :
+ values[i] = new Double(data.readDouble());
+ ++i;
+ break;
+
+ case CLASS :
+ case STRING :
+ values[i] = new Integer(data.readUnsignedShort());
+ break;
+
+ case FIELDREF :
+ case METHODREF :
+ case INTERFACEMETHODREF :
+ case NAMEANDTYPE :
+ values[i] = new Integer(data.readInt());
+ break;
+ default:
+ // Do nothing
+ }
+ }
+ }
+}
+
+/**
+ * Provides a quick and dirty way to determine the true name of a class
+ * given just an InputStream. Reads in just enough to perform this
+ * minimal task only.
+ */
+public class ClassNameReader extends Object {
+ private static final int CLASS_MAGIC_NUMBER = 0xCAFEBABE;
+
+ /**
+ * Get the class name of a class in an input stream.
+ *
+ * @param input an <code>InputStream</code> value
+ * @return the name of the class
+ * @exception IOException if an error occurs
+ */
+ public static String getClassName(InputStream input) throws IOException {
+ DataInputStream data = new DataInputStream(input);
+ // verify this is a valid class file.
+ int cookie = data.readInt();
+ if (cookie != CLASS_MAGIC_NUMBER) {
+ return null;
+ }
+ /* int version = */ data.readInt();
+ // read the constant pool.
+ ConstantPool constants = new ConstantPool(data);
+ Object[] values = constants.values;
+ // read access flags and class index.
+ /* int accessFlags = */ data.readUnsignedShort();
+ int classIndex = data.readUnsignedShort();
+ Integer stringIndex = (Integer) values[classIndex];
+ String className = (String) values[stringIndex.intValue()];
+ return className;
+ }
+
+
+}
+
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/jlink/JlinkTask.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/jlink/JlinkTask.java
new file mode 100644
index 00000000..f5767e67
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/jlink/JlinkTask.java
@@ -0,0 +1,183 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.jlink;
+
+import java.io.File;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.MatchingTask;
+import org.apache.tools.ant.types.Path;
+
+/**
+ * This class defines objects that can link together various jar and
+ * zip files.
+ *
+ * <p>It is basically a wrapper for the jlink code written originally
+ * by <a href="mailto:beard@netscape.com">Patrick Beard</a>. The
+ * classes org.apache.tools.ant.taskdefs.optional.jlink.Jlink and
+ * org.apache.tools.ant.taskdefs.optional.jlink.ClassNameReader
+ * support this class.</p>
+ *
+ * <p>For example:
+ * <code>
+ * <pre>
+ * &lt;jlink compress=&quot;false&quot; outfile=&quot;out.jar&quot;/&gt;
+ * &lt;mergefiles&gt;
+ * &lt;pathelement path=&quot;${build.dir}/mergefoo.jar&quot;/&gt;
+ * &lt;pathelement path=&quot;${build.dir}/mergebar.jar&quot;/&gt;
+ * &lt;/mergefiles&gt;
+ * &lt;addfiles&gt;
+ * &lt;pathelement path=&quot;${build.dir}/mac.jar&quot;/&gt;
+ * &lt;pathelement path=&quot;${build.dir}/pc.zip&quot;/&gt;
+ * &lt;/addfiles&gt;
+ * &lt;/jlink&gt;
+ * </pre>
+ * </code>
+ *
+ * @ant.task ignore="true"
+ */
+public class JlinkTask extends MatchingTask {
+
+ /**
+ * The output file for this run of jlink. Usually a jar or zip file.
+ * @param outfile the output file
+ */
+ public void setOutfile(File outfile) {
+ this.outfile = outfile;
+ }
+
+ /**
+ * Establishes the object that contains the files to
+ * be merged into the output.
+ * @return a path to be configured
+ */
+ public Path createMergefiles() {
+ if (this.mergefiles == null) {
+ this.mergefiles = new Path(getProject());
+ }
+ return this.mergefiles.createPath();
+ }
+
+ /**
+ * Sets the files to be merged into the output.
+ * @param mergefiles a path
+ */
+ public void setMergefiles(Path mergefiles) {
+ if (this.mergefiles == null) {
+ this.mergefiles = mergefiles;
+ } else {
+ this.mergefiles.append(mergefiles);
+ }
+ }
+
+ /**
+ * Establishes the object that contains the files to
+ * be added to the output.
+ * @return a path to be configured
+ */
+ public Path createAddfiles() {
+ if (this.addfiles == null) {
+ this.addfiles = new Path(getProject());
+ }
+ return this.addfiles.createPath();
+ }
+
+ /**
+ * Sets the files to be added into the output.
+ * @param addfiles a path
+ */
+ public void setAddfiles(Path addfiles) {
+ if (this.addfiles == null) {
+ this.addfiles = addfiles;
+ } else {
+ this.addfiles.append(addfiles);
+ }
+ }
+
+ /**
+ * Defines whether or not the output should be compacted.
+ * @param compress a <code>boolean</code> value
+ */
+ public void setCompress(boolean compress) {
+ this.compress = compress;
+ }
+
+ /**
+ * Does the adding and merging.
+ * @throws BuildException on error
+ */
+ public void execute() throws BuildException {
+ //Be sure everything has been set.
+ if (outfile == null) {
+ throw new BuildException("outfile attribute is required! "
+ + "Please set.");
+ }
+ if (!haveAddFiles() && !haveMergeFiles()) {
+ throw new BuildException("addfiles or mergefiles required! "
+ + "Please set.");
+ }
+ log("linking: " + outfile.getPath());
+ log("compression: " + compress, Project.MSG_VERBOSE);
+ jlink linker = new jlink();
+ linker.setOutfile(outfile.getPath());
+ linker.setCompression(compress);
+ if (haveMergeFiles()) {
+ log("merge files: " + mergefiles.toString(), Project.MSG_VERBOSE);
+ linker.addMergeFiles(mergefiles.list());
+ }
+ if (haveAddFiles()) {
+ log("add files: " + addfiles.toString(), Project.MSG_VERBOSE);
+ linker.addAddFiles(addfiles.list());
+ }
+ try {
+ linker.link();
+ } catch (Exception ex) {
+ throw new BuildException(ex, getLocation());
+ }
+ }
+
+ private boolean haveAddFiles() {
+ return haveEntries(addfiles);
+ }
+
+ private boolean haveMergeFiles() {
+ return haveEntries(mergefiles);
+ }
+
+ private boolean haveEntries(Path p) {
+ if (p == null) {
+ return false;
+ }
+ if (p.size() > 0) {
+ return true;
+ }
+ return false;
+ }
+
+ private File outfile = null;
+
+ private Path mergefiles = null;
+
+ private Path addfiles = null;
+
+ private boolean compress = false;
+
+}
+
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/jlink/jlink.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/jlink/jlink.java
new file mode 100644
index 00000000..499cca27
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/jlink/jlink.java
@@ -0,0 +1,458 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+/**
+ * jlink.java links together multiple .jar files Original code by Patrick
+ * Beard. Modifications to work with ANT by Matthew Kuperus Heun.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.jlink;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Enumeration;
+import java.util.Vector;
+import java.util.zip.CRC32;
+import java.util.zip.Deflater;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipException;
+import java.util.zip.ZipFile;
+import java.util.zip.ZipOutputStream;
+
+import org.apache.tools.ant.util.FileUtils;
+
+// CheckStyle:TypeNameCheck OFF - bc
+/**
+ * jlink links together multiple .jar files.
+ */
+public class jlink {
+ private static final int BUFFER_SIZE = 8192;
+ private static final int VECTOR_INIT_SIZE = 10;
+
+ private String outfile = null;
+
+ private Vector mergefiles = new Vector(VECTOR_INIT_SIZE);
+
+ private Vector addfiles = new Vector(VECTOR_INIT_SIZE);
+
+ private boolean compression = false;
+
+ // CheckStyle:VisibilityModifier OFF - bc
+
+ byte[] buffer = new byte[BUFFER_SIZE];
+
+ // CheckStyle:VisibilityModifier OFF - bc
+
+ /** The file that will be created by this instance of jlink.
+ * @param outfile the file to create.
+ */
+ public void setOutfile(String outfile) {
+ if (outfile == null) {
+ return;
+ }
+ this.outfile = outfile;
+ }
+
+
+ /**
+ * Adds a file to be merged into the output.
+ * @param fileToMerge the file to merge into the output.
+ */
+ public void addMergeFile(String fileToMerge) {
+ if (fileToMerge == null) {
+ return;
+ }
+ mergefiles.addElement(fileToMerge);
+ }
+
+
+ /** Adds a file to be added into the output.
+ * @param fileToAdd the file to add to the output.
+ */
+ public void addAddFile(String fileToAdd) {
+ if (fileToAdd == null) {
+ return;
+ }
+ addfiles.addElement(fileToAdd);
+ }
+
+
+ /**
+ * Adds several files to be merged into the output.
+ * @param filesToMerge an array of files to merge into the output.
+ */
+ public void addMergeFiles(String[] filesToMerge) {
+ if (filesToMerge == null) {
+ return;
+ }
+ for (int i = 0; i < filesToMerge.length; i++) {
+ addMergeFile(filesToMerge[i]);
+ }
+ }
+
+
+ /**
+ * Adds several file to be added into the output.
+ * @param filesToAdd an array of files to add to the output.
+ */
+ public void addAddFiles(String[] filesToAdd) {
+ if (filesToAdd == null) {
+ return;
+ }
+ for (int i = 0; i < filesToAdd.length; i++) {
+ addAddFile(filesToAdd[i]);
+ }
+ }
+
+
+ /**
+ * Determines whether output will be compressed.
+ * @param compress if true use compression.
+ */
+ public void setCompression(boolean compress) {
+ this.compression = compress;
+ }
+
+
+ /**
+ * Performs the linking of files. Addfiles are added to the output as-is.
+ * For example, a jar file is added to the output as a jar file. However,
+ * mergefiles are first examined for their type. If it is a jar or zip
+ * file, the contents will be extracted from the mergefile and entered
+ * into the output. If a zip or jar file is encountered in a subdirectory
+ * it will be added, not merged. If a directory is encountered, it becomes
+ * the root entry of all the files below it. Thus, you can provide
+ * multiple, disjoint directories, as addfiles: they will all be added in
+ * a rational manner to outfile.
+ * @throws Exception on error.
+ */
+ public void link() throws Exception {
+ ZipOutputStream output = new ZipOutputStream(new FileOutputStream(outfile));
+
+ if (compression) {
+ output.setMethod(ZipOutputStream.DEFLATED);
+ output.setLevel(Deflater.DEFAULT_COMPRESSION);
+ } else {
+ output.setMethod(ZipOutputStream.STORED);
+ }
+
+ Enumeration merges = mergefiles.elements();
+
+ while (merges.hasMoreElements()) {
+ String path = (String) merges.nextElement();
+ File f = new File(path);
+
+ if (f.getName().endsWith(".jar") || f.getName().endsWith(".zip")) {
+ //Do the merge
+ mergeZipJarContents(output, f);
+ } else {
+ //Add this file to the addfiles Vector and add it
+ //later at the top level of the output file.
+ addAddFile(path);
+ }
+ }
+
+ Enumeration adds = addfiles.elements();
+
+ while (adds.hasMoreElements()) {
+ String name = (String) adds.nextElement();
+ File f = new File(name);
+
+ if (f.isDirectory()) {
+ //System.out.println("in jlink: adding directory contents of " + f.getPath());
+ addDirContents(output, f, f.getName() + '/', compression);
+ } else {
+ addFile(output, f, "", compression);
+ }
+ }
+ FileUtils.close(output);
+ }
+
+
+ /**
+ * The command line entry point for jlink.
+ * @param args an array of arguments
+ */
+ public static void main(String[] args) {
+ // jlink output input1 ... inputN
+ if (args.length < 2) {
+ System.out.println("usage: jlink output input1 ... inputN");
+ System.exit(1);
+ }
+ jlink linker = new jlink();
+
+ linker.setOutfile(args[0]);
+ // To maintain compatibility with the command-line version,
+ // we will only add files to be merged.
+ for (int i = 1; i < args.length; i++) {
+ linker.addMergeFile(args[i]);
+ }
+ try {
+ linker.link();
+ } catch (Exception ex) {
+ System.err.print(ex.getMessage());
+ }
+ }
+
+
+ /*
+ * Actually performs the merging of f into the output.
+ * f should be a zip or jar file.
+ */
+ private void mergeZipJarContents(ZipOutputStream output, File f) throws IOException {
+ //Check to see that the file with name "name" exists.
+ if (!f.exists()) {
+ return;
+ }
+ ZipFile zipf = new ZipFile(f);
+ Enumeration entries = zipf.entries();
+
+ while (entries.hasMoreElements()) {
+ ZipEntry inputEntry = (ZipEntry) entries.nextElement();
+ //Ignore manifest entries. They're bound to cause conflicts between
+ //files that are being merged. User should supply their own
+ //manifest file when doing the merge.
+ String inputEntryName = inputEntry.getName();
+ int index = inputEntryName.indexOf("META-INF");
+
+ if (index < 0) {
+ //META-INF not found in the name of the entry. Go ahead and process it.
+ try {
+ output.putNextEntry(processEntry(zipf, inputEntry));
+ } catch (ZipException ex) {
+ //If we get here, it could be because we are trying to put a
+ //directory entry that already exists.
+ //For example, we're trying to write "com", but a previous
+ //entry from another mergefile was called "com".
+ //In that case, just ignore the error and go on to the
+ //next entry.
+ String mess = ex.getMessage();
+
+ if (mess.indexOf("duplicate") >= 0) {
+ //It was the duplicate entry.
+ continue;
+ } else {
+ // I hate to admit it, but we don't know what happened
+ // here. Throw the Exception.
+ throw ex;
+ }
+ }
+
+ InputStream in = zipf.getInputStream(inputEntry);
+ int len = buffer.length;
+ int count = -1;
+
+ while ((count = in.read(buffer, 0, len)) > 0) {
+ output.write(buffer, 0, count);
+ }
+ in.close();
+ output.closeEntry();
+ }
+ }
+ zipf.close();
+ }
+
+
+ /*
+ * Adds contents of a directory to the output.
+ */
+ private void addDirContents(ZipOutputStream output, File dir, String prefix,
+ boolean compress) throws IOException {
+ String[] contents = dir.list();
+
+ for (int i = 0; i < contents.length; ++i) {
+ String name = contents[i];
+ File file = new File(dir, name);
+
+ if (file.isDirectory()) {
+ addDirContents(output, file, prefix + name + '/', compress);
+ } else {
+ addFile(output, file, prefix, compress);
+ }
+ }
+ }
+
+
+ /*
+ * Gets the name of an entry in the file. This is the real name
+ * which for a class is the name of the package with the class
+ * name appended.
+ */
+ private String getEntryName(File file, String prefix) {
+ String name = file.getName();
+
+ if (!name.endsWith(".class")) {
+ // see if the file is in fact a .class file, and determine its actual name.
+ InputStream input = null;
+ try {
+ input = new FileInputStream(file);
+ String className = ClassNameReader.getClassName(input);
+
+ if (className != null) {
+ return className.replace('.', '/') + ".class";
+ }
+ } catch (IOException ioe) {
+ //do nothing
+ } finally {
+ if (input != null) {
+ try {
+ input.close();
+ } catch (IOException e) {
+ //do nothing
+ }
+ }
+ }
+ }
+ System.out.println("From " + file.getPath() + " and prefix " + prefix
+ + ", creating entry " + prefix + name);
+ return (prefix + name);
+ }
+
+
+ /*
+ * Adds a file to the output stream.
+ */
+ private void addFile(ZipOutputStream output, File file, String prefix,
+ boolean compress) throws IOException {
+ //Make sure file exists
+ if (!file.exists()) {
+ return;
+ }
+ ZipEntry entry = new ZipEntry(getEntryName(file, prefix));
+
+ entry.setTime(file.lastModified());
+ entry.setSize(file.length());
+ if (!compress) {
+ entry.setCrc(calcChecksum(file));
+ }
+ FileInputStream input = new FileInputStream(file);
+
+ addToOutputStream(output, input, entry);
+ }
+
+
+ /*
+ * A convenience method that several other methods might call.
+ */
+ private void addToOutputStream(ZipOutputStream output, InputStream input,
+ ZipEntry ze) throws IOException {
+ try {
+ output.putNextEntry(ze);
+ } catch (ZipException zipEx) {
+ //This entry already exists. So, go with the first one.
+ input.close();
+ return;
+ }
+
+ int numBytes = -1;
+
+ while ((numBytes = input.read(buffer)) > 0) {
+ output.write(buffer, 0, numBytes);
+ }
+ output.closeEntry();
+ input.close();
+ }
+
+
+ /*
+ * A method that does the work on a given entry in a mergefile.
+ * The big deal is to set the right parameters in the ZipEntry
+ * on the output stream.
+ */
+ private ZipEntry processEntry(ZipFile zip, ZipEntry inputEntry) {
+ /*
+ First, some notes.
+ On MRJ 2.2.2, getting the size, compressed size, and CRC32 from the
+ ZipInputStream does not work for compressed (deflated) files. Those calls return -1.
+ For uncompressed (stored) files, those calls do work.
+ However, using ZipFile.getEntries() works for both compressed and
+ uncompressed files.
+
+ Now, from some simple testing I did, it seems that the value of CRC-32 is
+ independent of the compression setting. So, it should be easy to pass this
+ information on to the output entry.
+ */
+ String name = inputEntry.getName();
+
+ if (!(inputEntry.isDirectory() || name.endsWith(".class"))) {
+ try {
+ InputStream input = zip.getInputStream(zip.getEntry(name));
+ String className = ClassNameReader.getClassName(input);
+
+ input.close();
+ if (className != null) {
+ name = className.replace('.', '/') + ".class";
+ }
+ } catch (IOException ioe) {
+ //do nothing
+ }
+ }
+ ZipEntry outputEntry = new ZipEntry(name);
+
+ outputEntry.setTime(inputEntry.getTime());
+ outputEntry.setExtra(inputEntry.getExtra());
+ outputEntry.setComment(inputEntry.getComment());
+ outputEntry.setTime(inputEntry.getTime());
+ if (compression) {
+ outputEntry.setMethod(ZipEntry.DEFLATED);
+ //Note, don't need to specify size or crc for compressed files.
+ } else {
+ outputEntry.setMethod(ZipEntry.STORED);
+ outputEntry.setCrc(inputEntry.getCrc());
+ outputEntry.setSize(inputEntry.getSize());
+ }
+ return outputEntry;
+ }
+
+
+ /*
+ * Necessary in the case where you add a entry that
+ * is not compressed.
+ */
+ private long calcChecksum(File f) throws IOException {
+ BufferedInputStream in = new BufferedInputStream(new FileInputStream(f));
+
+ return calcChecksum(in);
+ }
+
+
+ /*
+ * Necessary in the case where you add a entry that
+ * is not compressed.
+ */
+ private long calcChecksum(InputStream in) throws IOException {
+ CRC32 crc = new CRC32();
+ int len = buffer.length;
+ int count = -1;
+ int haveRead = 0;
+
+ while ((count = in.read(buffer, 0, len)) > 0) {
+ haveRead += count;
+ crc.update(buffer, 0, count);
+ }
+ in.close();
+ return crc.getValue();
+ }
+
+
+}
+
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/jsp/Jasper41Mangler.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/jsp/Jasper41Mangler.java
new file mode 100644
index 00000000..609938c9
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/jsp/Jasper41Mangler.java
@@ -0,0 +1,93 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.jsp;
+
+import java.io.File;
+
+/**
+ * this class implements the name mangling rules of the jasper in tomcat4.1.x
+ * which is likely to remain for some time
+ * @see "org.apache.jasper.JspCompilationContext"
+ */
+public class Jasper41Mangler implements JspMangler {
+
+
+ /**
+ * map from a jsp file to a java filename; does not do packages
+ *
+ * @param jspFile file
+ * @return java filename
+ */
+ public String mapJspToJavaName(File jspFile) {
+ String jspUri = jspFile.getAbsolutePath();
+ int start = jspUri.lastIndexOf(File.separatorChar) + 1;
+ int end = jspUri.length();
+ StringBuffer modifiedClassName;
+ modifiedClassName = new StringBuffer(jspUri.length() - start);
+ if (!Character.isJavaIdentifierStart(jspUri.charAt(start))
+ || jspUri.charAt(start) == '_') {
+ // If the first char is not a start of Java identifier or is _
+ // prepend a '_'.
+ modifiedClassName.append('_');
+ }
+ for (int i = start; i < end; i++) {
+ char ch = jspUri.charAt(i);
+ if (Character.isJavaIdentifierPart(ch)) {
+ modifiedClassName.append(ch);
+ } else if (ch == '.') {
+ modifiedClassName.append('_');
+ } else {
+ modifiedClassName.append(mangleChar(ch));
+ }
+ }
+ return modifiedClassName.toString();
+ }
+
+ /**
+ * Mangle the specified character to create a legal Java class name.
+ */
+ private static String mangleChar(char ch) {
+ // CheckStyle:MagicNumber OFF
+ String s = Integer.toHexString(ch);
+ int nzeros = 5 - s.length();
+ char[] result = new char[6];
+ result[0] = '_';
+ for (int i = 1; i <= nzeros; i++) {
+ result[i] = '0';
+ }
+ for (int i = nzeros + 1, j = 0; i < 6; i++, j++) {
+ result[i] = s.charAt(j);
+ }
+ return new String(result);
+ // CheckStyle:MagicNumber ON
+ }
+
+
+ /**
+ * taking in the substring representing the path relative to the source dir
+ * return a new string representing the destination path
+ * @param path not used.
+ * @return null as this is not implemented.
+ * @todo
+ */
+ public String mapPath(String path) {
+ return null;
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/jsp/JspC.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/jsp/JspC.java
new file mode 100644
index 00000000..4274bf0d
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/jsp/JspC.java
@@ -0,0 +1,709 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.jsp;
+
+import java.io.File;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import org.apache.tools.ant.AntClassLoader;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.DirectoryScanner;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.MatchingTask;
+import org.apache.tools.ant.taskdefs.optional.jsp.compilers.JspCompilerAdapter;
+import org.apache.tools.ant.taskdefs.optional.jsp.compilers.JspCompilerAdapterFactory;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.types.Reference;
+
+/**
+ * Runs a JSP compiler.
+ *
+ * <p> This task takes the given jsp files and compiles them into java
+ * files. It is then up to the user to compile the java files into classes.
+ *
+ * <p> The task requires the srcdir and destdir attributes to be
+ * set. This Task is a MatchingTask, so the files to be compiled can be
+ * specified using includes/excludes attributes or nested include/exclude
+ * elements. Optional attributes are verbose (set the verbosity level passed
+ * to jasper), package (name of the destination package for generated java
+ * classes and classpath (the classpath to use when running the jsp
+ * compiler).
+ * <p> This task supports the nested elements classpath (A Path) and
+ * classpathref (A Reference) which can be used in preference to the
+ * attribute classpath, if the jsp compiler is not already in the ant
+ * classpath.
+ *
+ * <p><h4>Usage</h4>
+ * <pre>
+ * &lt;jspc srcdir="${basedir}/src/war"
+ * destdir="${basedir}/gensrc"
+ * package="com.i3sp.jsp"
+ * verbose="9"&gt;
+ * &lt;include name="**\/*.jsp" /&gt;
+ * &lt;/jspc&gt;
+ * </pre>
+ *
+ * <p> Large Amount of cutting and pasting from the Javac task...
+ * @since 1.5
+ */
+public class JspC extends MatchingTask {
+ private Path classpath;
+ private Path compilerClasspath;
+ private Path src;
+ private File destDir;
+ private String packageName;
+ /** name of the compiler to use */
+ private String compilerName = "jasper";
+
+ /**
+ * -ieplugin &lt;clsid&gt; Java Plugin classid for Internet Explorer
+ */
+ private String iepluginid;
+ private boolean mapped;
+ private int verbose = 0;
+ // CheckStyle:VisibilityModifier OFF - bc
+ protected Vector compileList = new Vector();
+ Vector javaFiles = new Vector();
+
+ /**
+ * flag to control action on execution trouble
+ */
+ protected boolean failOnError = true;
+
+ /**
+ * -uriroot &lt;dir&gt; The root directory that uri files should be resolved
+ * against,
+ */
+ private File uriroot;
+
+ /**
+ * -webinc &lt;file&gt; Creates partial servlet mappings for the -webapp option
+ */
+ private File webinc;
+
+ /**
+ * -webxml &lt;file&gt; Creates a complete web.xml when using the -webapp option.
+ */
+
+ private File webxml;
+
+ /**
+ * web apps
+ */
+ protected WebAppParameter webApp;
+
+
+
+ private static final String FAIL_MSG
+ = "Compile failed, messages should have been provided.";
+
+ // CheckStyle:VisibilityModifier ON
+
+ /**
+ * Set the path for source JSP files.
+ * @param srcDir the source path.
+ */
+ public void setSrcDir(Path srcDir) {
+ if (src == null) {
+ src = srcDir;
+ } else {
+ src.append(srcDir);
+ }
+ }
+
+ /**
+ * Get the source dir.
+ * @return the source path.
+ */
+ public Path getSrcDir() {
+ return src;
+ }
+
+ /**
+ * Set the destination directory into which the JSP source
+ * files should be compiled.
+ * @param destDir the destination directory.
+ */
+ public void setDestdir(File destDir) {
+ this.destDir = destDir;
+ }
+
+ /**
+ * Get the destination directory.
+ * @return the directory.
+ */
+ public File getDestdir() {
+ return destDir;
+ }
+
+ /**
+ * Set the name of the package the compiled jsp files should be in.
+ * @param pkg the name of the package.
+ */
+ public void setPackage(String pkg) {
+ this.packageName = pkg;
+ }
+
+ /**
+ * Get the name of the package.
+ * @return the package.
+ */
+ public String getPackage() {
+ return packageName;
+ }
+
+ /**
+ * Set the verbose level of the compiler
+ * @param i the verbose level to use.
+ */
+ public void setVerbose(int i) {
+ verbose = i;
+ }
+
+ /**
+ * Get the verbose level.
+ * @return the level.
+ */
+ public int getVerbose() {
+ return verbose;
+ }
+
+ /**
+ * Whether or not the build should halt if compilation fails.
+ * Defaults to <code>true</code>.
+ * @param fail a <code>boolean</code> value.
+ */
+ public void setFailonerror(boolean fail) {
+ failOnError = fail;
+ }
+ /**
+ * Gets the failonerror flag.
+ * @return the flag.
+ */
+ public boolean getFailonerror() {
+ return failOnError;
+ }
+
+ /**
+ * Get the IE CLASSID value.
+ * @return the value.
+ */
+ public String getIeplugin() {
+ return iepluginid;
+ }
+ /**
+ * Java Plugin CLASSID for Internet Explorer
+ * @param iepluginid the id to use.
+ */
+ public void setIeplugin(String iepluginid) {
+ this.iepluginid = iepluginid;
+ }
+
+ /**
+ * If true, generate separate write() calls for each HTML line
+ * in the JSP.
+ * @return mapping status
+ */
+ public boolean isMapped() {
+ return mapped;
+ }
+
+ /**
+ * If true, generate separate write() calls for each HTML line
+ * in the JSP.
+ * @param mapped a <code>boolean</code> value.
+ */
+ public void setMapped(boolean mapped) {
+ this.mapped = mapped;
+ }
+
+ /**
+ * The URI context of relative URI references in the JSP pages.
+ * If it does not exist then it is derived from the location
+ * of the file relative to the declared or derived value of uriroot.
+ *
+ * @param uribase The new Uribase value
+ */
+ public void setUribase(File uribase) {
+ log("Uribase is currently an unused parameter", Project.MSG_WARN);
+ }
+
+ /**
+ * Get the uri base value.
+ * @return the value.
+ */
+ public File getUribase() {
+ return uriroot;
+ }
+
+ /**
+ * The root directory that uri files should be resolved
+ * against. (Default is the directory jspc is invoked from)
+ *
+ * @param uriroot The new Uribase value
+ */
+ public void setUriroot(File uriroot) {
+ this.uriroot = uriroot;
+ }
+
+ /**
+ * Get the uri root value.
+ * @return the value.
+ */
+ public File getUriroot() {
+ return uriroot;
+ }
+
+
+ /**
+ * Set the classpath to be used for this compilation.
+ * @param cp the path to be used.
+ */
+ public void setClasspath(Path cp) {
+ if (classpath == null) {
+ classpath = cp;
+ } else {
+ classpath.append(cp);
+ }
+ }
+
+ /**
+ * Adds a path to the classpath.
+ * @return a path to be configured.
+ */
+ public Path createClasspath() {
+ if (classpath == null) {
+ classpath = new Path(getProject());
+ }
+ return classpath.createPath();
+ }
+
+ /**
+ * Adds a reference to a classpath defined elsewhere
+ * @param r a reference to a classpath.
+ */
+ public void setClasspathRef(Reference r) {
+ createClasspath().setRefid(r);
+ }
+
+ /**
+ * Get the classpath.
+ * @return the classpath.
+ */
+ public Path getClasspath() {
+ return classpath;
+ }
+
+ /**
+ * Set the classpath to be used to find this compiler adapter
+ * @param cp the compiler classpath.
+ */
+ public void setCompilerclasspath(Path cp) {
+ if (compilerClasspath == null) {
+ compilerClasspath = cp;
+ } else {
+ compilerClasspath.append(cp);
+ }
+ }
+
+ /**
+ * get the classpath used to find the compiler adapter
+ * @return the compiler classpath.
+ */
+ public Path getCompilerclasspath() {
+ return compilerClasspath;
+ }
+
+ /**
+ * Support nested compiler classpath, used to locate compiler adapter
+ * @return a path to be configured.
+ */
+ public Path createCompilerclasspath() {
+ if (compilerClasspath == null) {
+ compilerClasspath = new Path(getProject());
+ }
+ return compilerClasspath.createPath();
+ }
+
+ /**
+ * Filename for web.xml.
+ *
+ * @param webxml The new Webxml value
+ */
+ public void setWebxml(File webxml) {
+ this.webxml = webxml;
+ }
+
+ /**
+ * Filename for web.xml.
+ * @return The filename for web.xml.
+ */
+ public File getWebxml() {
+ return this.webxml;
+ }
+
+ /**
+ * output filename for the fraction of web.xml that lists
+ * servlets.
+ * @param webinc The new Webinc value
+ */
+ public void setWebinc(File webinc) {
+ this.webinc = webinc;
+ }
+
+ /**
+ * Get the webinc attribute.
+ * @return the webinc attribute.
+ */
+ public File getWebinc() {
+ return this.webinc;
+ }
+
+ /**
+ * Adds a single webapp.
+ *
+ * @param webappParam add a web app parameter
+ * @throws BuildException if more than one webapp is specified.
+ */
+ public void addWebApp(WebAppParameter webappParam)
+ throws BuildException {
+ //demand create vector of filesets
+ if (webApp == null) {
+ webApp = webappParam;
+ } else {
+ throw new BuildException("Only one webapp can be specified");
+ }
+ }
+
+ /**
+ * Get the web app.
+ * @return the web app attribute.
+ */
+ public WebAppParameter getWebApp() {
+ return webApp;
+ }
+
+ /**
+ * Class name of a JSP compiler adapter.
+ * @param compiler the compiler class name.
+ */
+ public void setCompiler(String compiler) {
+ this.compilerName = compiler;
+ }
+
+ /**
+ * get the list of files to compile
+ * @return the list of files.
+ */
+ public Vector getCompileList() {
+ return compileList;
+ }
+
+ /**
+ * execute by building up a list of files that
+ * have changed and hand them off to a jsp compiler
+ * @throws BuildException on error.
+ */
+ public void execute()
+ throws BuildException {
+
+ // make sure that we've got a destdir
+ if (destDir == null) {
+ throw new BuildException("destdir attribute must be set!",
+ getLocation());
+ }
+
+ if (!destDir.isDirectory()) {
+ throw new BuildException("destination directory \"" + destDir
+ + "\" does not exist or is not a directory",
+ getLocation());
+ }
+
+ File dest = getActualDestDir();
+
+ AntClassLoader al = null;
+ try {
+ //bind to a compiler
+ JspCompilerAdapter compiler =
+ JspCompilerAdapterFactory
+ .getCompiler(compilerName, this,
+ al = getProject().createClassLoader(compilerClasspath));
+
+ //if we are a webapp, hand off to the compiler, which had
+ //better handle it
+ if (webApp != null) {
+ doCompilation(compiler);
+ return;
+ }
+
+ // make sure that we've got a srcdir
+ if (src == null) {
+ throw new BuildException("srcdir attribute must be set!",
+ getLocation());
+ }
+ String [] list = src.list();
+ if (list.length == 0) {
+ throw new BuildException("srcdir attribute must be set!",
+ getLocation());
+ }
+
+
+ // if the compiler does its own dependency stuff, we just
+ // call it right now
+ if (compiler.implementsOwnDependencyChecking()) {
+ doCompilation(compiler);
+ return;
+ }
+
+ //the remainder of this method is only for compilers that
+ //need their dependency work done
+ JspMangler mangler = compiler.createMangler();
+
+ // scan source directories and dest directory to build up both copy
+ // lists and compile lists
+ resetFileLists();
+ int filecount = 0;
+ for (int i = 0; i < list.length; i++) {
+ File srcDir = getProject().resolveFile(list[i]);
+ if (!srcDir.exists()) {
+ throw new BuildException("srcdir \"" + srcDir.getPath()
+ + "\" does not exist!",
+ getLocation());
+ }
+ DirectoryScanner ds = this.getDirectoryScanner(srcDir);
+ String[] files = ds.getIncludedFiles();
+ filecount = files.length;
+ scanDir(srcDir, dest, mangler, files);
+ }
+
+ // compile the source files
+
+ log("compiling " + compileList.size() + " files",
+ Project.MSG_VERBOSE);
+
+ if (compileList.size() > 0) {
+
+ log("Compiling " + compileList.size() + " source file"
+ + (compileList.size() == 1 ? "" : "s")
+ + " to "
+ + dest);
+ doCompilation(compiler);
+
+ } else {
+ if (filecount == 0) {
+ log("there were no files to compile", Project.MSG_INFO);
+ } else {
+ log("all files are up to date", Project.MSG_VERBOSE);
+ }
+ }
+ } finally {
+ if (al != null) {
+ al.cleanup();
+ }
+ }
+ }
+
+ /**
+ * calculate where the files will end up:
+ * this is destDir or it id destDir + the package name
+ */
+ private File getActualDestDir() {
+ File dest = null;
+ if (packageName == null) {
+ dest = destDir;
+ } else {
+ String path = destDir.getPath() + File.separatorChar
+ + packageName.replace('.', File.separatorChar);
+ dest = new File(path);
+ }
+ return dest;
+ }
+
+ /**
+ * do the compile
+ */
+ private void doCompilation(JspCompilerAdapter compiler)
+ throws BuildException {
+ // now we need to populate the compiler adapter
+ compiler.setJspc(this);
+
+ // finally, lets execute the compiler!!
+ if (!compiler.execute()) {
+ if (failOnError) {
+ throw new BuildException(FAIL_MSG, getLocation());
+ } else {
+ log(FAIL_MSG, Project.MSG_ERR);
+ }
+ }
+ }
+
+ /**
+ * Clear the list of files to be compiled and copied..
+ */
+ protected void resetFileLists() {
+ compileList.removeAllElements();
+ }
+
+ /**
+ * Scans the directory looking for source files to be compiled.
+ * The results are returned in the class variable compileList
+ * @param srcDir the source directory.
+ * @param dest the destination directory.
+ * @param mangler the jsp filename mangler.
+ * @param files the file names to mangle.
+ */
+ protected void scanDir(File srcDir, File dest, JspMangler mangler,
+ String[] files) {
+
+ long now = (new Date()).getTime();
+
+ for (int i = 0; i < files.length; i++) {
+ String filename = files[i];
+ File srcFile = new File(srcDir, filename);
+ File javaFile = mapToJavaFile(mangler, srcFile, srcDir, dest);
+ if (javaFile == null) {
+ continue;
+ }
+
+ if (srcFile.lastModified() > now) {
+ log("Warning: file modified in the future: " + filename,
+ Project.MSG_WARN);
+ }
+ boolean shouldCompile = false;
+ shouldCompile = isCompileNeeded(srcFile, javaFile);
+ if (shouldCompile) {
+ compileList.addElement(srcFile.getAbsolutePath());
+ javaFiles.addElement(javaFile);
+ }
+ }
+ }
+
+ /**
+ * Test whether or not compilation is needed. A return value of
+ * <code>true<code> means yes, <code>false</code> means
+ * our tests do not indicate this, but as the TLDs are
+ * not used for dependency checking this is not guaranteed.
+ * The current tests are
+ * <ol>
+ * <li>no dest file
+ * <li>dest file out of date w.r.t source
+ * <li>dest file zero bytes long
+ * </ol>
+ * @param srcFile JSP source file
+ * @param javaFile JSP dest file
+ * @return true if a compile is definitely needed.
+ *
+ */
+ private boolean isCompileNeeded(File srcFile, File javaFile) {
+ boolean shouldCompile = false;
+ if (!javaFile.exists()) {
+ shouldCompile = true;
+ log("Compiling " + srcFile.getPath()
+ + " because java file " + javaFile.getPath()
+ + " does not exist", Project.MSG_VERBOSE);
+ } else {
+ if (srcFile.lastModified() > javaFile.lastModified()) {
+ shouldCompile = true;
+ log("Compiling " + srcFile.getPath()
+ + " because it is out of date with respect to "
+ + javaFile.getPath(),
+ Project.MSG_VERBOSE);
+ } else {
+ if (javaFile.length() == 0) {
+ shouldCompile = true;
+ log("Compiling " + srcFile.getPath()
+ + " because java file " + javaFile.getPath()
+ + " is empty", Project.MSG_VERBOSE);
+ }
+ }
+ }
+ return shouldCompile;
+ }
+
+
+ /**
+ * get a filename from our jsp file.
+ * @param mangler the jsp filename manager.
+ * @param srcFile the source file.
+ * @param srcDir the source directory.
+ * @param dest the destination directory.
+ * @return the filename.
+ * @todo support packages and subdirs
+ */
+ protected File mapToJavaFile(JspMangler mangler, File srcFile, File srcDir,
+ File dest) {
+ if (!srcFile.getName().endsWith(".jsp")) {
+ return null;
+ }
+ String javaFileName = mangler.mapJspToJavaName(srcFile);
+ // String srcFileDir=srcFile.getParent();
+ return new File(dest, javaFileName);
+ }
+
+ /**
+ * delete any java output files that are empty
+ * this is to get around a little defect in jasper: when it
+ * fails, it leaves incomplete files around.
+ */
+ public void deleteEmptyJavaFiles() {
+ if (javaFiles != null) {
+ Enumeration e = javaFiles.elements();
+ while (e.hasMoreElements()) {
+ File file = (File) e.nextElement();
+ if (file.exists() && file.length() == 0) {
+ log("deleting empty output file " + file);
+ file.delete();
+ }
+ }
+ }
+ }
+
+ /**
+ * static inner class used as a parameter element
+ */
+ public static class WebAppParameter {
+
+ /**
+ * the sole option
+ */
+ private File directory;
+
+ /**
+ * query current directory
+ * @return the directory.
+ */
+ public File getDirectory() {
+ return directory;
+ }
+
+ /**
+ * set directory; alternate syntax
+ * @param directory the base dir.
+ */
+ public void setBaseDir(File directory) {
+ this.directory = directory;
+ }
+ //end inner class
+ }
+
+
+ //end class
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/jsp/JspMangler.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/jsp/JspMangler.java
new file mode 100644
index 00000000..f62492c3
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/jsp/JspMangler.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.jsp;
+
+import java.io.File;
+
+/**
+ * This is an interface to the Mangler service that jspc needs to map
+ * JSP file names to java files.
+ * Note the complete lack of correlation
+ * with Jasper's mangler interface.
+ */
+public interface JspMangler {
+
+
+ /**
+ * map from a jsp file to a java filename; does not do packages
+ *
+ * @param jspFile file
+ * @return java filename
+ */
+ String mapJspToJavaName(File jspFile);
+
+ /**
+ * taking in the substring representing the path relative to the source dir
+ * return a new string representing the destination path
+ * @param path the path to map.
+ * @return the mapped path.
+ */
+ String mapPath(String path);
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/jsp/JspNameMangler.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/jsp/JspNameMangler.java
new file mode 100644
index 00000000..6e08e7d5
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/jsp/JspNameMangler.java
@@ -0,0 +1,155 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.jsp;
+import java.io.File;
+
+import org.apache.tools.ant.util.StringUtils;
+
+/**
+ * This is a class derived from the Jasper code
+ * (org.apache.jasper.compiler.CommandLineCompiler) to map from a JSP filename
+ * to a valid Java classname.
+ *
+ */
+public class JspNameMangler implements JspMangler {
+
+ // CheckStyle:ConstantNameCheck OFF - bc
+
+ /**
+ * this is the list of keywords which can not be used as classnames
+ */
+ public static final String[] keywords = {
+ "assert",
+ "abstract", "boolean", "break", "byte",
+ "case", "catch", "char", "class",
+ "const", "continue", "default", "do",
+ "double", "else", "extends", "final",
+ "finally", "float", "for", "goto",
+ "if", "implements", "import",
+ "instanceof", "int", "interface",
+ "long", "native", "new", "package",
+ "private", "protected", "public",
+ "return", "short", "static", "super",
+ "switch", "synchronized", "this",
+ "throw", "throws", "transient",
+ "try", "void", "volatile", "while"
+ };
+
+ // CheckStyle:ConstantNameCheck ON
+
+ /**
+ * map from a jsp file to a java filename; does not do packages
+ *
+ * @param jspFile file
+ * @return java filename
+ */
+ public String mapJspToJavaName(File jspFile) {
+ return mapJspToBaseName(jspFile) + ".java";
+ }
+
+
+ /**
+ * map from a jsp file to a base name; does not deal with extensions
+ *
+ * @param jspFile jspFile file
+ * @return exensionless potentially remapped name
+ */
+ private String mapJspToBaseName(File jspFile) {
+ String className;
+ className = stripExtension(jspFile);
+
+ // since we don't mangle extensions like the servlet does,
+ // we need to check for keywords as class names
+ for (int i = 0; i < keywords.length; ++i) {
+ if (className.equals(keywords[i])) {
+ className += "%";
+ break;
+ }
+ }
+
+ // Fix for invalid characters. If you think of more add to the list.
+ StringBuffer modifiedClassName = new StringBuffer(className.length());
+ // first char is more restrictive than the rest
+ char firstChar = className.charAt(0);
+ if (Character.isJavaIdentifierStart(firstChar)) {
+ modifiedClassName.append(firstChar);
+ } else {
+ modifiedClassName.append(mangleChar(firstChar));
+ }
+ // this is the rest
+ for (int i = 1; i < className.length(); i++) {
+ char subChar = className.charAt(i);
+ if (Character.isJavaIdentifierPart(subChar)) {
+ modifiedClassName.append(subChar);
+ } else {
+ modifiedClassName.append(mangleChar(subChar));
+ }
+ }
+ return modifiedClassName.toString();
+ }
+
+
+ /**
+ * get short filename from file
+ *
+ * @param jspFile file in
+ * @return file without any jsp extension
+ */
+ private String stripExtension(File jspFile) {
+ return StringUtils.removeSuffix(jspFile.getName(), ".jsp");
+ }
+
+
+ /**
+ * definition of the char escaping algorithm
+ *
+ * @param ch char to mangle
+ * @return mangled string; 5 digit hex value
+ */
+ private static String mangleChar(char ch) {
+ // CheckStyle:MagicNumber OFF
+ if (ch == File.separatorChar) {
+ ch = '/';
+ }
+ String s = Integer.toHexString(ch);
+ int nzeros = 5 - s.length();
+ char[] result = new char[6];
+ result[0] = '_';
+ for (int i = 1; i <= nzeros; ++i) {
+ result[i] = '0';
+ }
+ int resultIndex = 0;
+ for (int i = nzeros + 1; i < 6; ++i) {
+ result[i] = s.charAt(resultIndex++);
+ }
+ return new String(result);
+ // CheckStyle:MagicNumber ON
+ }
+
+ /**
+ * taking in the substring representing the path relative to the source dir
+ * return a new string representing the destination path
+ * not supported, as jasper in tomcat4.0 doesn't either
+ * @param path not used
+ * @return null always.
+ */
+ public String mapPath(String path) {
+ return null;
+ }
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/jsp/WLJspc.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/jsp/WLJspc.java
new file mode 100644
index 00000000..45a427ad
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/jsp/WLJspc.java
@@ -0,0 +1,334 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.jsp;
+
+//apache/ant imports
+import java.io.File;
+import java.util.Date;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.DirectoryScanner;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.Java;
+import org.apache.tools.ant.taskdefs.MatchingTask;
+import org.apache.tools.ant.types.Path;
+
+/**
+ * Precompiles JSP's using WebLogic's JSP compiler (weblogic.jspc).
+ *
+ * Tested only on Weblogic 4.5.1 - NT4.0 and Solaris 5.7
+ *
+ * required attributes
+ * src : root of source tree for JSP, ie, the document root for your weblogic server
+ * dest : root of destination directory, what you have set as
+ * WorkingDir in the weblogic properties
+ * package : start package name under which your JSP's would be compiled
+ *
+ * other attributes
+ * classpath
+ *
+ * A classpath should be set which contains the weblogic classes as well as all
+ * application classes referenced by the JSP. The system classpath is also
+ * appended when the jspc is called, so you may choose to put everything in
+ * the classpath while calling Ant. However, since presumably the JSP's will
+ * reference classes being build by Ant, it would be better to explicitly add
+ * the classpath in the task
+ *
+ * The task checks timestamps on the JSP's and the generated classes, and compiles
+ * only those files that have changed.
+ *
+ * It follows the weblogic naming convention of putting classes in
+ * <b> _dirName/_fileName.class for dirname/fileName.jsp </b>
+ *
+ * Limitation: It compiles the files thru the Classic compiler only.
+ * Limitation: Since it is my experience that weblogic jspc throws out of
+ * memory error on being given too many files at one go, it is
+ * called multiple times with one jsp file each.
+ *
+ * <pre>
+ * example
+ * &lt;target name="jspcompile" depends="compile"&gt;
+ * &lt;wljspc src="c:\\weblogic\\myserver\\public_html"
+ * dest="c:\\weblogic\\myserver\\serverclasses" package="myapp.jsp"&gt;
+ * &lt;classpath&gt;
+ * &lt;pathelement location="${weblogic.classpath}" /&gt;
+ * &lt;pathelement path="${compile.dest}" /&gt;
+ * &lt;/classpath&gt;
+ *
+ * &lt;/wljspc&gt;
+ * &lt;/target&gt;
+ * </pre>
+ *
+ */
+
+public class WLJspc extends MatchingTask {
+ //TODO Test on other versions of weblogic
+ //TODO add more attributes to the task, to take care of all jspc options
+ //TODO Test on Unix
+
+ /** root of compiled files tree */
+ private File destinationDirectory;
+
+ /** root of source files tree */
+ private File sourceDirectory;
+
+ /** package under which resultant classes will reside */
+ private String destinationPackage;
+
+ /** classpath used to compile the jsp files. */
+ private Path compileClasspath;
+
+ //private String compilerPath; //fully qualified name for the compiler executable
+
+ private String pathToPackage = "";
+ private Vector filesToDo = new Vector();
+
+ /**
+ * Run the task.
+ * @throws BuildException if there is an error.
+ */
+ public void execute() throws BuildException {
+ if (!destinationDirectory.isDirectory()) {
+ throw new BuildException("destination directory "
+ + destinationDirectory.getPath() + " is not valid");
+ }
+
+ if (!sourceDirectory.isDirectory()) {
+ throw new BuildException("src directory "
+ + sourceDirectory.getPath() + " is not valid");
+ }
+
+ if (destinationPackage == null) {
+ throw new BuildException("package attribute must be present.",
+ getLocation());
+ }
+
+
+ pathToPackage
+ = this.destinationPackage.replace('.', File.separatorChar);
+ // get all the files in the sourceDirectory
+ DirectoryScanner ds = super.getDirectoryScanner(sourceDirectory);
+
+ //use the systemclasspath as well, to include the ant jar
+ if (compileClasspath == null) {
+ compileClasspath = new Path(getProject());
+ }
+
+ compileClasspath = compileClasspath.concatSystemClasspath();
+ String[] files = ds.getIncludedFiles();
+
+ //Weblogic.jspc calls System.exit() ... have to fork
+ // Therefore, takes loads of time
+ // Can pass directories at a time (*.jsp) but easily runs out of
+ // memory on hefty dirs (even on a Sun)
+ Java helperTask = new Java(this);
+ helperTask.setFork(true);
+ helperTask.setClassname("weblogic.jspc");
+ helperTask.setTaskName(getTaskName());
+ // CheckStyle:MagicNumber OFF
+ String[] args = new String[12];
+ // CheckStyle:MagicNumber ON
+
+ File jspFile = null;
+ String parents = "";
+ int j = 0;
+ //TODO this array stuff is a remnant of prev trials.. gotta remove.
+ args[j++] = "-d";
+ args[j++] = destinationDirectory.getAbsolutePath().trim();
+ args[j++] = "-docroot";
+ args[j++] = sourceDirectory.getAbsolutePath().trim();
+ args[j++] = "-keepgenerated";
+ //Call compiler as class... dont want to fork again
+ //Use classic compiler -- can be parameterised?
+ args[j++] = "-compilerclass";
+ args[j++] = "sun.tools.javac.Main";
+ //Weblogic jspc does not seem to work unless u explicitly set this...
+ // Does not take the classpath from the env....
+ // Am i missing something about the Java task??
+ args[j++] = "-classpath";
+ args[j++] = compileClasspath.toString();
+
+ this.scanDir(files);
+ log("Compiling " + filesToDo.size() + " JSP files");
+
+ final int size = filesToDo.size();
+ for (int i = 0; i < size; i++) {
+ //TODO
+ // All this to get package according to weblogic standards
+ // Can be written better... this is too hacky!
+ // Careful.. similar code in scanDir , but slightly different!!
+ String filename = (String) filesToDo.elementAt(i);
+ jspFile = new File(filename);
+ args[j] = "-package";
+ parents = jspFile.getParent();
+ if ((parents != null) && (!("").equals(parents))) {
+ parents = this.replaceString(parents, File.separator, "_.");
+ args[j + 1] = destinationPackage + "." + "_" + parents;
+ } else {
+ args[j + 1] = destinationPackage;
+ }
+
+
+ args[j + 2] = sourceDirectory + File.separator + filename;
+ helperTask.clearArgs();
+
+ // CheckStyle:MagicNumber OFF
+ for (int x = 0; x < j + 3; x++) {
+ helperTask.createArg().setValue(args[x]);
+ }
+ // CheckStyle:MagicNumber ON
+
+ helperTask.setClasspath(compileClasspath);
+ if (helperTask.executeJava() != 0) {
+ log(filename + " failed to compile", Project.MSG_WARN);
+ }
+ }
+ }
+
+
+
+ /**
+ * Set the classpath to be used for this compilation.
+ * @param classpath the classpath to use.
+ */
+ public void setClasspath(Path classpath) {
+ if (compileClasspath == null) {
+ compileClasspath = classpath;
+ } else {
+ compileClasspath.append(classpath);
+ }
+ }
+
+ /**
+ * Maybe creates a nested classpath element.
+ * @return a path to be configured.
+ */
+ public Path createClasspath() {
+ if (compileClasspath == null) {
+ compileClasspath = new Path(getProject());
+ }
+ return compileClasspath;
+ }
+
+ /**
+ * Set the directory containing the source jsp's
+ *
+ *
+ * @param dirName the directory containg the source jsp's
+ */
+ public void setSrc(File dirName) {
+
+ sourceDirectory = dirName;
+ }
+
+ /**
+ * Set the directory containing the source jsp's
+ *
+ *
+ * @param dirName the directory containg the source jsp's
+ */
+ public void setDest(File dirName) {
+
+ destinationDirectory = dirName;
+ }
+
+ /**
+ * Set the package under which the compiled classes go
+ *
+ * @param packageName the package name for the classes
+ */
+ public void setPackage(String packageName) {
+
+ destinationPackage = packageName;
+ }
+
+ /**
+ * Scan the array of files and add the jsp
+ * files that need to be compiled to the filesToDo field.
+ * @param files the files to scan.
+ */
+ protected void scanDir(String[] files) {
+
+ long now = (new Date()).getTime();
+ File jspFile = null;
+ String parents = null;
+ String pack = "";
+ for (int i = 0; i < files.length; i++) {
+ File srcFile = new File(this.sourceDirectory, files[i]);
+ //TODO
+ // All this to convert source to destination directory according
+ // to weblogic standards Can be written better... this is too hacky!
+ jspFile = new File(files[i]);
+ parents = jspFile.getParent();
+
+ if ((parents != null) && (!("").equals(parents))) {
+ parents = this.replaceString(parents, File.separator, "_/");
+ pack = pathToPackage + File.separator + "_" + parents;
+ } else {
+ pack = pathToPackage;
+ }
+
+ String filePath = pack + File.separator + "_";
+ int startingIndex = files[i].lastIndexOf(File.separator) != -1
+ ? files[i].lastIndexOf(File.separator) + 1 : 0;
+ int endingIndex = files[i].indexOf(".jsp");
+ if (endingIndex == -1) {
+ log("Skipping " + files[i] + ". Not a JSP",
+ Project.MSG_VERBOSE);
+ continue;
+ }
+
+ filePath += files[i].substring(startingIndex, endingIndex);
+ filePath += ".class";
+ File classFile = new File(this.destinationDirectory, filePath);
+
+ if (srcFile.lastModified() > now) {
+ log("Warning: file modified in the future: "
+ + files[i], Project.MSG_WARN);
+ }
+ if (srcFile.lastModified() > classFile.lastModified()) {
+ filesToDo.addElement(files[i]);
+ log("Recompiling File " + files[i], Project.MSG_VERBOSE);
+ }
+ }
+ }
+
+
+ /**
+ * Replace occurrences of a string with a replacement string.
+ * @param inpString the string to convert.
+ * @param escapeChars the string to replace.
+ * @param replaceChars the string to place.
+ * @return the converted string.
+ */
+ protected String replaceString(String inpString, String escapeChars,
+ String replaceChars) {
+ String localString = "";
+ int numTokens = 0;
+ StringTokenizer st = new StringTokenizer(inpString, escapeChars, true);
+ numTokens = st.countTokens();
+ for (int i = 0; i < numTokens; i++) {
+ String test = st.nextToken();
+ test = (test.equals(escapeChars) ? replaceChars : test);
+ localString += test;
+ }
+ return localString;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/jsp/compilers/DefaultJspCompilerAdapter.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/jsp/compilers/DefaultJspCompilerAdapter.java
new file mode 100644
index 00000000..5c4d0e3b
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/jsp/compilers/DefaultJspCompilerAdapter.java
@@ -0,0 +1,153 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.jsp.compilers;
+
+import java.io.File;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.optional.jsp.JspC;
+import org.apache.tools.ant.types.CommandlineJava;
+
+/**
+ * This is the default implementation for the JspCompilerAdapter interface.
+ * This is currently very light on the ground since only one compiler type is
+ * supported.
+ *
+ */
+public abstract class DefaultJspCompilerAdapter
+ implements JspCompilerAdapter {
+
+ private static String lSep = System.getProperty("line.separator");
+
+ /**
+ * Logs the compilation parameters, adds the files to compile and logs the
+ * &quot;niceSourceList&quot;
+ * @param jspc the compiler task for logging
+ * @param compileList the list of files to compile
+ * @param cmd the command line used
+ */
+ protected void logAndAddFilesToCompile(JspC jspc,
+ Vector compileList,
+ CommandlineJava cmd) {
+ jspc.log("Compilation " + cmd.describeJavaCommand(),
+ Project.MSG_VERBOSE);
+
+ StringBuffer niceSourceList = new StringBuffer("File");
+ if (compileList.size() != 1) {
+ niceSourceList.append("s");
+ }
+ niceSourceList.append(" to be compiled:");
+
+ niceSourceList.append(lSep);
+
+ Enumeration e = compileList.elements();
+ while (e.hasMoreElements()) {
+ String arg = (String) e.nextElement();
+ cmd.createArgument().setValue(arg);
+ niceSourceList.append(" ");
+ niceSourceList.append(arg);
+ niceSourceList.append(lSep);
+ }
+
+ jspc.log(niceSourceList.toString(), Project.MSG_VERBOSE);
+ }
+
+ // CheckStyle:VisibilityModifier OFF - bc
+
+ /**
+ * our owner
+ */
+ protected JspC owner;
+
+ // CheckStyle:VisibilityModifier ON
+
+ /**
+ * set the owner
+ * @param owner the owner JspC compiler
+ */
+ public void setJspc(JspC owner) {
+ this.owner = owner;
+ }
+
+ /** get the owner
+ * @return the owner; should never be null
+ */
+ public JspC getJspc() {
+ return owner;
+ }
+
+
+ /**
+ * add an argument oneple to the argument list, if the value aint null
+ * @param cmd the command line
+ * @param argument The argument
+ */
+ protected void addArg(CommandlineJava cmd, String argument) {
+ if (argument != null && argument.length() != 0) {
+ cmd.createArgument().setValue(argument);
+ }
+ }
+
+
+ /**
+ * add an argument tuple to the argument list, if the value aint null
+ * @param cmd the command line
+ * @param argument The argument
+ * @param value the parameter
+ */
+ protected void addArg(CommandlineJava cmd, String argument, String value) {
+ if (value != null) {
+ cmd.createArgument().setValue(argument);
+ cmd.createArgument().setValue(value);
+ }
+ }
+
+ /**
+ * add an argument tuple to the arg list, if the file parameter aint null
+ * @param cmd the command line
+ * @param argument The argument
+ * @param file the parameter
+ */
+ protected void addArg(CommandlineJava cmd, String argument, File file) {
+ if (file != null) {
+ cmd.createArgument().setValue(argument);
+ cmd.createArgument().setFile(file);
+ }
+ }
+
+ /**
+ * ask if compiler can sort out its own dependencies
+ * @return true if the compiler wants to do its own
+ * depends
+ */
+ public boolean implementsOwnDependencyChecking() {
+ return false;
+ }
+
+ /**
+ * get our project
+ * @return owner project data
+ */
+ public Project getProject() {
+ return getJspc().getProject();
+ }
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/jsp/compilers/JasperC.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/jsp/compilers/JasperC.java
new file mode 100644
index 00000000..f0becacb
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/jsp/compilers/JasperC.java
@@ -0,0 +1,182 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.jsp.compilers;
+
+import java.io.File;
+
+import org.apache.tools.ant.AntClassLoader;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.Java;
+import org.apache.tools.ant.taskdefs.optional.jsp.JspC;
+import org.apache.tools.ant.taskdefs.optional.jsp.JspMangler;
+import org.apache.tools.ant.types.CommandlineJava;
+import org.apache.tools.ant.types.Path;
+
+/**
+ * The implementation of the jasper compiler.
+ * This is a cut-and-paste of the original Jspc task.
+ *
+ * @since ant1.5
+ */
+public class JasperC extends DefaultJspCompilerAdapter {
+
+ // CheckStyle:VisibilityModifier OFF - bc
+
+ /**
+ * what produces java classes from .jsp files
+ */
+ JspMangler mangler;
+
+ // CheckStyle:VisibilityModifier ON
+
+ /**
+ * Constructor for JasperC.
+ * @param mangler a filename converter
+ */
+ public JasperC(JspMangler mangler) {
+ this.mangler = mangler;
+ }
+
+ /**
+ * Our execute method.
+ * @return true if successful
+ * @throws BuildException on error
+ */
+ public boolean execute()
+ throws BuildException {
+ getJspc().log("Using jasper compiler", Project.MSG_VERBOSE);
+ CommandlineJava cmd = setupJasperCommand();
+
+ try {
+ // Create an instance of the compiler, redirecting output to
+ // the project log
+ Java java = new Java(owner);
+ Path p = getClasspath();
+ if (getJspc().getClasspath() != null) {
+ getProject().log("using user supplied classpath: " + p,
+ Project.MSG_DEBUG);
+ } else {
+ getProject().log("using system classpath: " + p,
+ Project.MSG_DEBUG);
+ }
+ java.setClasspath(p);
+ java.setDir(getProject().getBaseDir());
+ java.setClassname("org.apache.jasper.JspC");
+ //this is really irritating; we need a way to set stuff
+ String []args = cmd.getJavaCommand().getArguments();
+ for (int i = 0; i < args.length; i++) {
+ java.createArg().setValue(args[i]);
+ }
+ java.setFailonerror(getJspc().getFailonerror());
+ //we are forking here to be sure that if JspC calls
+ //System.exit() it doesn't halt the build
+ java.setFork(true);
+ java.setTaskName("jasperc");
+ java.execute();
+ return true;
+ } catch (Exception ex) {
+ if (ex instanceof BuildException) {
+ throw (BuildException) ex;
+ } else {
+ throw new BuildException("Error running jsp compiler: ",
+ ex, getJspc().getLocation());
+ }
+ } finally {
+ getJspc().deleteEmptyJavaFiles();
+ }
+ }
+
+
+
+ /**
+ * build up a command line
+ * @return a command line for jasper
+ */
+ private CommandlineJava setupJasperCommand() {
+ CommandlineJava cmd = new CommandlineJava();
+ JspC jspc = getJspc();
+ addArg(cmd, "-d", jspc.getDestdir());
+ addArg(cmd, "-p", jspc.getPackage());
+
+ if (!isTomcat5x()) {
+ addArg(cmd, "-v" + jspc.getVerbose());
+ } else {
+ getProject().log("this task doesn't support Tomcat 5.x properly, "
+ + "please use the Tomcat provided jspc task "
+ + "instead");
+ }
+
+ addArg(cmd, "-uriroot", jspc.getUriroot());
+ addArg(cmd, "-uribase", jspc.getUribase());
+ addArg(cmd, "-ieplugin", jspc.getIeplugin());
+ addArg(cmd, "-webinc", jspc.getWebinc());
+ addArg(cmd, "-webxml", jspc.getWebxml());
+ addArg(cmd, "-die9");
+
+ if (jspc.isMapped()) {
+ addArg(cmd, "-mapped");
+ }
+ if (jspc.getWebApp() != null) {
+ File dir = jspc.getWebApp().getDirectory();
+ addArg(cmd, "-webapp", dir);
+ }
+ logAndAddFilesToCompile(getJspc(), getJspc().getCompileList(), cmd);
+ return cmd;
+ }
+
+ /**
+ * @return an instance of the mangler this compiler uses
+ */
+
+ public JspMangler createMangler() {
+ return mangler;
+ }
+
+ /**
+ * @since Ant 1.6.2
+ */
+ private Path getClasspath() {
+ Path p = getJspc().getClasspath();
+ if (p == null) {
+ p = new Path(getProject());
+ return p.concatSystemClasspath("only");
+ } else {
+ return p.concatSystemClasspath("ignore");
+ }
+ }
+
+ /**
+ * @since Ant 1.6.2
+ */
+ private boolean isTomcat5x() {
+ AntClassLoader l = null;
+ try {
+ l = getProject().createClassLoader(getClasspath());
+ l.loadClass("org.apache.jasper.tagplugins.jstl.If");
+ return true;
+ } catch (ClassNotFoundException e) {
+ return false;
+ } finally {
+ if (l != null) {
+ l.cleanup();
+ }
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/jsp/compilers/JspCompilerAdapter.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/jsp/compilers/JspCompilerAdapter.java
new file mode 100644
index 00000000..16b67f9d
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/jsp/compilers/JspCompilerAdapter.java
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.jsp.compilers;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.taskdefs.optional.jsp.JspC;
+import org.apache.tools.ant.taskdefs.optional.jsp.JspMangler;
+
+/**
+ * The interface that all jsp compiler adapters must adher to.
+ *
+ * <p>A compiler adapter is an adapter that interprets the jspc's
+ * parameters in preparation to be passed off to the compiler this
+ * adapter represents. As all the necessary values are stored in the
+ * Jspc task itself, the only thing all adapters need is the jsp
+ * task, the execute command and a parameterless constructor (for
+ * reflection).</p>
+ *
+ */
+
+public interface JspCompilerAdapter {
+
+ /**
+ * Sets the compiler attributes, which are stored in the Jspc task.
+ * @param attributes the jsp compiler attributes
+ */
+ void setJspc(JspC attributes);
+
+ /**
+ * Executes the task.
+ *
+ * @return has the compilation been successful
+ * @throws BuildException on error
+ */
+ boolean execute() throws BuildException;
+
+ /**
+ * @return an instance of the mangler this compiler uses
+ */
+
+ JspMangler createMangler();
+
+ /**
+ * ask if compiler can sort out its own dependencies
+ * @return true if the compiler wants to do its own
+ * depends
+ */
+ boolean implementsOwnDependencyChecking();
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/jsp/compilers/JspCompilerAdapterFactory.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/jsp/compilers/JspCompilerAdapterFactory.java
new file mode 100644
index 00000000..2876ba0c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/jsp/compilers/JspCompilerAdapterFactory.java
@@ -0,0 +1,122 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.jsp.compilers;
+
+import org.apache.tools.ant.AntClassLoader;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.taskdefs.optional.jsp.Jasper41Mangler;
+import org.apache.tools.ant.taskdefs.optional.jsp.JspNameMangler;
+
+
+/**
+ * Creates the necessary compiler adapter, given basic criteria.
+ *
+ */
+public final class JspCompilerAdapterFactory {
+
+ /** This is a singleton -- can't create instances!! */
+ private JspCompilerAdapterFactory() {
+ }
+
+ /**
+ * Based on the parameter passed in, this method creates the necessary
+ * factory desired.
+ *
+ * The current mapping for compiler names are as follows:
+ * <ul><li>jasper = jasper compiler (the default)
+ * <li><i>a fully qualified classname</i> = the name of a jsp compiler
+ * adapter
+ * </ul>
+ *
+ * @param compilerType either the name of the desired compiler, or the
+ * full classname of the compiler's adapter.
+ * @param task a task to log through.
+ * @return the compiler
+ * @throws BuildException if the compiler type could not be resolved into
+ * a compiler adapter.
+ */
+ public static JspCompilerAdapter getCompiler(String compilerType, Task task)
+ throws BuildException {
+ return getCompiler(compilerType, task,
+ // Memory-Leak in line below
+ task.getProject().createClassLoader(null));
+ }
+
+ /**
+ * Based on the parameter passed in, this method creates the necessary
+ * factory desired.
+ *
+ * The current mapping for compiler names are as follows:
+ * <ul><li>jasper = jasper compiler (the default)
+ * <li><i>a fully qualified classname</i> = the name of a jsp compiler
+ * adapter
+ * </ul>
+ *
+ * @param compilerType either the name of the desired compiler, or the
+ * full classname of the compiler's adapter.
+ * @param task a task to log through.
+ * @param loader AntClassLoader with which the compiler should be loaded
+ * @return the compiler
+ * @throws BuildException if the compiler type could not be resolved into
+ * a compiler adapter.
+ */
+ public static JspCompilerAdapter getCompiler(String compilerType, Task task,
+ AntClassLoader loader)
+ throws BuildException {
+
+ if (compilerType.equalsIgnoreCase("jasper")) {
+ //tomcat4.0 gets the old mangler
+ return new JasperC(new JspNameMangler());
+ }
+ if (compilerType.equalsIgnoreCase("jasper41")) {
+ //tomcat4.1 gets the new one
+ return new JasperC(new Jasper41Mangler());
+ }
+ return resolveClassName(compilerType, loader);
+ }
+
+ /**
+ * Tries to resolve the given classname into a compiler adapter.
+ * Throws a fit if it can't.
+ *
+ * @param className The fully qualified classname to be created.
+ * @param classloader Classloader with which to load the class
+ * @throws BuildException This is the fit that is thrown if className
+ * isn't an instance of JspCompilerAdapter.
+ */
+ private static JspCompilerAdapter resolveClassName(String className,
+ AntClassLoader classloader)
+ throws BuildException {
+ try {
+ Class c = classloader.findClass(className);
+ Object o = c.newInstance();
+ return (JspCompilerAdapter) o;
+ } catch (ClassNotFoundException cnfe) {
+ throw new BuildException(className + " can\'t be found.", cnfe);
+ } catch (ClassCastException cce) {
+ throw new BuildException(className + " isn\'t the classname of "
+ + "a compiler adapter.", cce);
+ } catch (Throwable t) {
+ // for all other possibilities
+ throw new BuildException(className + " caused an interesting "
+ + "exception.", t);
+ }
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/AggregateTransformer.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/AggregateTransformer.java
new file mode 100644
index 00000000..ec3506d4
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/AggregateTransformer.java
@@ -0,0 +1,346 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.junit;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Vector;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.taskdefs.Delete;
+import org.apache.tools.ant.taskdefs.TempFile;
+import org.apache.tools.ant.taskdefs.XSLTProcess;
+import org.apache.tools.ant.types.EnumeratedAttribute;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.resources.FileResource;
+import org.apache.tools.ant.types.resources.URLResource;
+import org.apache.tools.ant.util.FileUtils;
+import org.apache.tools.ant.util.JAXPUtils;
+import org.w3c.dom.Document;
+
+/**
+ * Transform a JUnit xml report.
+ * The default transformation generates an html report in either framed or non-framed
+ * style. The non-framed style is convenient to have a concise report via mail, the
+ * framed report is much more convenient if you want to browse into different
+ * packages or testcases since it is a Javadoc like report.
+ *
+ */
+public class AggregateTransformer {
+ /**
+ * name of the frames format.
+ */
+ public static final String FRAMES = "frames";
+
+ /**
+ * name of the no frames format.
+ */
+ public static final String NOFRAMES = "noframes";
+
+ /**
+ * defines acceptable formats.
+ */
+ public static class Format extends EnumeratedAttribute {
+ /**
+ * list authorized values.
+ * @return authorized values.
+ */
+ public String[] getValues() {
+ return new String[]{FRAMES, NOFRAMES};
+ }
+ }
+
+ // CheckStyle:VisibilityModifier OFF - bc
+ /** Task */
+ protected Task task;
+
+ /** the xml document to process */
+ protected Document document;
+
+ /** the style directory. XSLs should be read from here if necessary */
+ protected File styleDir;
+
+ /** the destination directory, this is the root from where html should be generated */
+ protected File toDir;
+
+ /**
+ * The internal XSLT task used to perform the transformation.
+ *
+ * @since Ant 1.9.5
+ */
+ private XSLTProcess xsltTask;
+
+ /**
+ * Instance of a utility class to use for file operations.
+ *
+ * @since Ant 1.7
+ */
+ private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+
+ /**
+ * Used to ensure the uniqueness of a property
+ */
+ private static int counter = 0;
+
+ /** the format to use for the report. Must be <tt>FRAMES</tt> or <tt>NOFRAMES</tt> */
+ protected String format = FRAMES;
+
+ /** XML Parser factory */
+ private static DocumentBuilderFactory privateDBFactory;
+
+ /** XML Parser factory accessible to subclasses */
+ protected static DocumentBuilderFactory dbfactory;
+
+ static {
+ privateDBFactory = DocumentBuilderFactory.newInstance();
+ dbfactory = privateDBFactory;
+ }
+ // CheckStyle:VisibilityModifier ON
+
+ /**
+ * constructor creating the transformer from the junitreport task.
+ * @param task task delegating to this class
+ */
+ public AggregateTransformer(Task task) {
+ this.task = task;
+ xsltTask = new XSLTProcess();
+ xsltTask.bindToOwner(task);
+ }
+
+ /**
+ * Get the Document Builder Factory
+ *
+ * @return the DocumentBuilderFactory instance in use
+ */
+ protected static DocumentBuilderFactory getDocumentBuilderFactory() {
+ return privateDBFactory;
+ }
+
+ /**
+ * sets the format.
+ * @param format Must be <tt>FRAMES</tt> or <tt>NOFRAMES</tt>
+ */
+ public void setFormat(Format format) {
+ this.format = format.getValue();
+ }
+
+ /**
+ * sets the input document.
+ * @param doc input dom tree
+ */
+ public void setXmlDocument(Document doc) {
+ this.document = doc;
+ }
+
+ /**
+ * Set the xml file to be processed. This is a helper if you want
+ * to set the file directly. Much more for testing purposes.
+ * @param xmlfile xml file to be processed
+ * @throws BuildException if the document cannot be parsed.
+ */
+ protected void setXmlfile(File xmlfile) throws BuildException {
+ try {
+ DocumentBuilder builder = privateDBFactory.newDocumentBuilder();
+ InputStream in = new FileInputStream(xmlfile);
+ try {
+ Document doc = builder.parse(in);
+ setXmlDocument(doc);
+ } finally {
+ in.close();
+ }
+ } catch (Exception e) {
+ throw new BuildException("Error while parsing document: " + xmlfile, e);
+ }
+ }
+
+ /**
+ * set the style directory. It is optional and will override the
+ * default xsl used.
+ * @param styledir the directory containing the xsl files if the user
+ * would like to override with its own style.
+ */
+ public void setStyledir(File styledir) {
+ this.styleDir = styledir;
+ }
+
+ /** set the destination directory.
+ * @param todir the destination directory
+ */
+ public void setTodir(File todir) {
+ this.toDir = todir;
+ }
+
+ /** set the extension of the output files
+ * @param ext extension.
+ */
+ public void setExtension(String ext) {
+ task.log("extension is not used anymore", Project.MSG_WARN);
+ }
+
+ /**
+ * Create an instance of an XSL parameter for configuration by Ant.
+ *
+ * @return an instance of the Param class to be configured.
+ * @since Ant 1.7
+ */
+ public XSLTProcess.Param createParam() {
+ return xsltTask.createParam();
+ }
+
+ /**
+ * Creates a classpath to be used for the internal XSLT task.
+ *
+ * @return the classpath to be configured
+ * @since Ant 1.9.5
+ */
+ public Path createClasspath() {
+ return xsltTask.createClasspath();
+ }
+
+ /**
+ * Creates a factory configuration to be used for the internal XSLT task.
+ *
+ * @return the factory description to be configured
+ * @since Ant 1.9.5
+ */
+ public XSLTProcess.Factory createFactory() {
+ return xsltTask.createFactory();
+ }
+
+ /**
+ * transformation
+ * @throws BuildException exception if something goes wrong with the transformation.
+ */
+ public void transform() throws BuildException {
+ checkOptions();
+ Project project = task.getProject();
+
+ TempFile tempFileTask = new TempFile();
+ tempFileTask.bindToOwner(task);
+
+ xsltTask.setXslResource(getStylesheet());
+
+ // acrobatic cast.
+ xsltTask.setIn(((XMLResultAggregator) task).getDestinationFile());
+ File outputFile = null;
+ if (format.equals(FRAMES)) {
+ String tempFileProperty = getClass().getName() + String.valueOf(counter++);
+ File tmp = FILE_UTILS.resolveFile(project.getBaseDir(), project
+ .getProperty("java.io.tmpdir"));
+ tempFileTask.setDestDir(tmp);
+ tempFileTask.setProperty(tempFileProperty);
+ tempFileTask.execute();
+ outputFile = new File(project.getProperty(tempFileProperty));
+ } else {
+ outputFile = new File(toDir, "junit-noframes.html");
+ }
+ xsltTask.setOut(outputFile);
+ XSLTProcess.Param paramx = xsltTask.createParam();
+ paramx.setProject(task.getProject());
+ paramx.setName("output.dir");
+ paramx.setExpression(toDir.getAbsolutePath());
+ final long t0 = System.currentTimeMillis();
+ try {
+ xsltTask.execute();
+ } catch (Exception e) {
+ throw new BuildException("Errors while applying transformations: " + e.getMessage(), e);
+ }
+ final long dt = System.currentTimeMillis() - t0;
+ task.log("Transform time: " + dt + "ms");
+ if (format.equals(FRAMES)) {
+ Delete delete = new Delete();
+ delete.bindToOwner(task);
+ delete.setFile(outputFile);
+ delete.execute();
+ }
+ }
+
+ /**
+ * access the stylesheet to be used as a resource.
+ * @return stylesheet as a resource
+ */
+ protected Resource getStylesheet() {
+ String xslname = "junit-frames.xsl";
+ if (NOFRAMES.equals(format)) {
+ xslname = "junit-noframes.xsl";
+ }
+ if (styleDir == null) {
+ // If style dir is not specified we have to retrieve
+ // the stylesheet from the classloader
+ URL stylesheetURL = getClass().getClassLoader().getResource(
+ "org/apache/tools/ant/taskdefs/optional/junit/xsl/" + xslname);
+ return new URLResource(stylesheetURL);
+ }
+ // If we are here, then the style dir is here and we
+ // should read the stylesheet from the filesystem
+ return new FileResource(new File(styleDir, xslname));
+ }
+
+ /** check for invalid options
+ * @throws BuildException if something goes wrong.
+ */
+ protected void checkOptions() throws BuildException {
+ // set the destination directory relative from the project if needed.
+ if (toDir == null) {
+ toDir = task.getProject().resolveFile(".");
+ } else if (!toDir.isAbsolute()) {
+ toDir = task.getProject().resolveFile(toDir.getPath());
+ }
+ }
+
+ /**
+ * Get the systemid of the appropriate stylesheet based on its
+ * name and styledir. If no styledir is defined it will load
+ * it as a java resource in the xsl child package, otherwise it
+ * will get it from the given directory.
+ * @return system ID of the stylesheet.
+ * @throws IOException thrown if the requested stylesheet does
+ * not exist.
+ */
+ protected String getStylesheetSystemId() throws IOException {
+ String xslname = "junit-frames.xsl";
+ if (NOFRAMES.equals(format)) {
+ xslname = "junit-noframes.xsl";
+ }
+ if (styleDir == null) {
+ URL url = getClass().getResource("xsl/" + xslname);
+ if (url == null) {
+ throw new FileNotFoundException("Could not find jar resource " + xslname);
+ }
+ return url.toExternalForm();
+ }
+ File file = new File(styleDir, xslname);
+ if (!file.exists()) {
+ throw new FileNotFoundException("Could not find file '" + file + "'");
+ }
+ return JAXPUtils.getSystemId(file);
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/BaseTest.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/BaseTest.java
new file mode 100644
index 00000000..55e7a5d5
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/BaseTest.java
@@ -0,0 +1,241 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.junit;
+
+import java.io.File;
+import java.util.Vector;
+
+/**
+ * Baseclass for BatchTest and JUnitTest.
+ *
+ */
+public abstract class BaseTest {
+ // CheckStyle:VisibilityModifier OFF - bc
+ protected boolean haltOnError = false;
+ protected boolean haltOnFail = false;
+ protected boolean filtertrace = true;
+ protected boolean fork = false;
+ protected String ifProperty = null;
+ protected String unlessProperty = null;
+ protected Vector formatters = new Vector();
+ /** destination directory */
+ protected File destDir = null;
+
+ protected String failureProperty;
+ protected String errorProperty;
+ // CheckStyle:VisibilityModifier ON
+
+ private Object ifCond, unlessCond;
+ private boolean skipNonTests;
+
+ /**
+ * Set the filtertrace attribute.
+ * @param value a <code>boolean</code> value.
+ */
+ public void setFiltertrace(boolean value) {
+ filtertrace = value;
+ }
+
+ /**
+ * Get the filtertrace attribute.
+ * @return the attribute.
+ */
+ public boolean getFiltertrace() {
+ return filtertrace;
+ }
+
+ /**
+ * Set the fork attribute.
+ * @param value a <code>boolean</code> value.
+ */
+ public void setFork(boolean value) {
+ fork = value;
+ }
+
+ /**
+ * Get the fork attribute.
+ * @return the attribute.
+ */
+ public boolean getFork() {
+ return fork;
+ }
+
+ /**
+ * Set the haltonerror attribute.
+ * @param value a <code>boolean</code> value.
+ */
+ public void setHaltonerror(boolean value) {
+ haltOnError = value;
+ }
+
+ /**
+ * Set the haltonfailure attribute.
+ * @param value a <code>boolean</code> value.
+ */
+ public void setHaltonfailure(boolean value) {
+ haltOnFail = value;
+ }
+
+ /**
+ * Get the haltonerror attribute.
+ * @return the attribute.
+ */
+ public boolean getHaltonerror() {
+ return haltOnError;
+ }
+
+ /**
+ * Get the haltonfailure attribute.
+ * @return the attribute.
+ */
+ public boolean getHaltonfailure() {
+ return haltOnFail;
+ }
+
+ /**
+ * Set the if attribute.
+ * If this expression evaluates to true or the name of a property
+ * which is present in project, the test will be run.
+ * @param ifCondition the expression to evaluate
+ * @since Ant 1.8.0
+ */
+ public void setIf(Object ifCondition) {
+ ifCond = ifCondition;
+ ifProperty = ifCondition != null ? String.valueOf(ifCondition) : null;
+ }
+
+ /**
+ * Set the if attribute.
+ * If this expression evaluates to true or the name of a property
+ * which is present in project, the test will be run.
+ * @param propertyName the expression to evaluate
+ */
+ public void setIf(String propertyName) {
+ setIf((Object) propertyName);
+ }
+
+ /**
+ * The if expression
+ * @since Ant 1.8.0
+ */
+ public Object getIfCondition() {
+ return ifCond;
+ }
+
+ /**
+ * Set the unless attribute. If this expression evaluates to
+ * false or the name of a property which is not present in
+ * project, the test will be run.
+ * @param unlessCondition the expression to evaluate
+ * @since Ant 1.8.0
+ */
+ public void setUnless(Object unlessCondition) {
+ unlessCond = unlessCondition;
+ unlessProperty = unlessCondition != null
+ ? String.valueOf(unlessCondition) : null;
+ }
+
+ /**
+ * Set the unless attribute. If this expression evaluates to
+ * false or the name of a property which is not present in
+ * project, the test will be run.
+ * @param propertyName the expression to evaluate
+ */
+ public void setUnless(String propertyName) {
+ setUnless((Object) propertyName);
+ }
+
+ /**
+ * The unless expression
+ * @since Ant 1.8.0
+ */
+ public Object getUnlessCondition() {
+ return unlessCond;
+ }
+
+ /**
+ * Allow a formatter nested element.
+ * @param elem a formatter nested element.
+ */
+ public void addFormatter(FormatterElement elem) {
+ formatters.addElement(elem);
+ }
+
+ /**
+ * Sets the destination directory.
+ * @param destDir the destination directory.
+ */
+ public void setTodir(File destDir) {
+ this.destDir = destDir;
+ }
+
+ /**
+ * Get the destination directory.
+ * @return the destination directory as an absolute path if it exists
+ * otherwise return <tt>null</tt>
+ */
+ public String getTodir() {
+ if (destDir != null) {
+ return destDir.getAbsolutePath();
+ }
+ return null;
+ }
+
+ /**
+ * Get the failure property name.
+ * @return the name of the property to set on failure.
+ */
+ public String getFailureProperty() {
+ return failureProperty;
+ }
+
+ /**
+ * Set the name of the failure property.
+ * @param failureProperty the name of the property to set if
+ * the test fails.
+ */
+ public void setFailureProperty(String failureProperty) {
+ this.failureProperty = failureProperty;
+ }
+
+ /**
+ * Get the failure property name.
+ * @return the name of the property to set on failure.
+ */
+ public String getErrorProperty() {
+ return errorProperty;
+ }
+
+ /**
+ * Set the name of the error property.
+ * @param errorProperty the name of the property to set if
+ * the test has an error.
+ */
+ public void setErrorProperty(String errorProperty) {
+ this.errorProperty = errorProperty;
+ }
+
+ public void setSkipNonTests(boolean skipNonTests) {
+ this.skipNonTests = skipNonTests;
+ }
+
+ public boolean isSkipNonTests() {
+ return skipNonTests;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/BatchTest.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/BatchTest.java
new file mode 100644
index 00000000..f41b96f1
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/BatchTest.java
@@ -0,0 +1,202 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.junit;
+
+
+import java.io.File;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.FileSet;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.ResourceCollection;
+import org.apache.tools.ant.types.resources.Resources;
+
+/**
+ * <p> Create then run <code>JUnitTest</code>'s based on the list of files
+ * given by the fileset attribute.
+ *
+ * <p> Every <code>.java</code> or <code>.class</code> file in the fileset is
+ * assumed to be a testcase.
+ * A <code>JUnitTest</code> is created for each of these named classes with
+ * basic setup inherited from the parent <code>BatchTest</code>.
+ *
+ * @see JUnitTest
+ */
+public final class BatchTest extends BaseTest {
+
+ /** the reference to the project */
+ private Project project;
+
+ /** the list of filesets containing the testcase filename rules */
+ private Resources resources = new Resources();
+
+ /**
+ * create a new batchtest instance
+ * @param project the project it depends on.
+ */
+ public BatchTest(Project project) {
+ this.project = project;
+ resources.setCache(true);
+ }
+
+ /**
+ * Add a new fileset instance to this batchtest. Whatever the fileset is,
+ * only filename that are <tt>.java</tt> or <tt>.class</tt> will be
+ * considered as 'candidates'.
+ * @param fs the new fileset containing the rules to get the testcases.
+ */
+ public void addFileSet(FileSet fs) {
+ add(fs);
+
+ // this one is here because the changes to support ResourceCollections
+ // have broken Magic's JUnitTestTask.
+ //
+ // The task adds a FileSet to a BatchTest instance using the
+ // Java API and without telling the FileSet about its project
+ // instance. The original code would pass in project on the
+ // call to getDirectoryScanner - which is now hidden deep into
+ // Resources.iterator() and not reachable.
+ if (fs.getProject() == null) {
+ fs.setProject(project);
+ }
+ }
+
+
+ /**
+ * Add a new ResourceCollection instance to this
+ * batchtest. Whatever the collection is, only names that are
+ * <tt>.java</tt> or <tt>.class</tt> will be considered as
+ * 'candidates'.
+ * @param rc the new ResourceCollection containing the rules to
+ * get the testcases.
+ * @since Ant 1.7
+ */
+ public void add(ResourceCollection rc) {
+ resources.add(rc);
+ }
+
+ /**
+ * Return all <tt>JUnitTest</tt> instances obtain by applying the fileset rules.
+ * @return an enumeration of all elements of this batchtest that are
+ * a <tt>JUnitTest</tt> instance.
+ */
+ public Enumeration elements() {
+ JUnitTest[] tests = createAllJUnitTest();
+ return Enumerations.fromArray(tests);
+ }
+
+ /**
+ * Convenient method to merge the <tt>JUnitTest</tt>s of this batchtest
+ * to a <tt>Vector</tt>.
+ * @param v the vector to which should be added all individual tests of this
+ * batch test.
+ */
+ void addTestsTo(Vector v) {
+ JUnitTest[] tests = createAllJUnitTest();
+ v.ensureCapacity(v.size() + tests.length);
+ for (int i = 0; i < tests.length; i++) {
+ v.addElement(tests[i]);
+ }
+ }
+
+ /**
+ * Create all <tt>JUnitTest</tt>s based on the filesets. Each instance
+ * is configured to match this instance properties.
+ * @return the array of all <tt>JUnitTest</tt>s that belongs to this batch.
+ */
+ private JUnitTest[] createAllJUnitTest() {
+ String[] filenames = getFilenames();
+ JUnitTest[] tests = new JUnitTest[filenames.length];
+ for (int i = 0; i < tests.length; i++) {
+ String classname = javaToClass(filenames[i]);
+ tests[i] = createJUnitTest(classname);
+ }
+ return tests;
+ }
+
+ /**
+ * Iterate over all filesets and return the filename of all files
+ * that end with <tt>.java</tt> or <tt>.class</tt>. This is to avoid
+ * wrapping a <tt>JUnitTest</tt> over an xml file for example. A Testcase
+ * is obviously a java file (compiled or not).
+ * @return an array of filenames without their extension. As they should
+ * normally be taken from their root, filenames should match their fully
+ * qualified class name (If it is not the case it will fail when running the test).
+ * For the class <tt>org/apache/Whatever.class</tt> it will return <tt>org/apache/Whatever</tt>.
+ */
+ private String[] getFilenames() {
+ Vector v = new Vector();
+ for (Resource r : resources) {
+ if (r.isExists()) {
+ String pathname = r.getName();
+ if (pathname.endsWith(".java")) {
+ v.addElement(pathname.substring(0, pathname.length() - ".java".length()));
+ } else if (pathname.endsWith(".class")) {
+ v.addElement(pathname.substring(0, pathname.length() - ".class".length()));
+ }
+ }
+ }
+
+ String[] files = new String[v.size()];
+ v.copyInto(files);
+ return files;
+ }
+
+ /**
+ * Convenient method to convert a pathname without extension to a
+ * fully qualified classname. For example <tt>org/apache/Whatever</tt> will
+ * be converted to <tt>org.apache.Whatever</tt>
+ * @param filename the filename to "convert" to a classname.
+ * @return the classname matching the filename.
+ */
+ public static String javaToClass(String filename) {
+ return filename.replace(File.separatorChar, '.').replace('/', '.')
+ .replace('\\', '.');
+ }
+
+ /**
+ * Create a <tt>JUnitTest</tt> that has the same property as this
+ * <tt>BatchTest</tt> instance.
+ * @param classname the name of the class that should be run as a
+ * <tt>JUnitTest</tt>. It must be a fully qualified name.
+ * @return the <tt>JUnitTest</tt> over the given classname.
+ */
+ private JUnitTest createJUnitTest(String classname) {
+ JUnitTest test = new JUnitTest();
+ test.setName(classname);
+ test.setHaltonerror(this.haltOnError);
+ test.setHaltonfailure(this.haltOnFail);
+ test.setFiltertrace(this.filtertrace);
+ test.setFork(this.fork);
+ test.setIf(getIfCondition());
+ test.setUnless(getUnlessCondition());
+ test.setTodir(this.destDir);
+ test.setFailureProperty(failureProperty);
+ test.setErrorProperty(errorProperty);
+ test.setSkipNonTests(isSkipNonTests());
+ Enumeration list = this.formatters.elements();
+ while (list.hasMoreElements()) {
+ test.addFormatter((FormatterElement) list.nextElement());
+ }
+ return test;
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/BriefJUnitResultFormatter.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/BriefJUnitResultFormatter.java
new file mode 100644
index 00000000..46d6c616
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/BriefJUnitResultFormatter.java
@@ -0,0 +1,300 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.junit;
+
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.StringWriter;
+import java.text.NumberFormat;
+
+import junit.framework.AssertionFailedError;
+import junit.framework.Test;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.util.FileUtils;
+import org.apache.tools.ant.util.StringUtils;
+
+/**
+ * Prints plain text output of the test to a specified Writer.
+ * Inspired by the PlainJUnitResultFormatter.
+ *
+ * @see FormatterElement
+ * @see PlainJUnitResultFormatter
+ */
+public class BriefJUnitResultFormatter implements JUnitResultFormatter, IgnoredTestListener {
+
+ private static final double ONE_SECOND = 1000.0;
+
+ /**
+ * Where to write the log to.
+ */
+ private OutputStream out;
+
+ /**
+ * Used for writing the results.
+ */
+ private BufferedWriter output;
+
+ /**
+ * Used as part of formatting the results.
+ */
+ private StringWriter results;
+
+ /**
+ * Used for writing formatted results to.
+ */
+ private BufferedWriter resultWriter;
+
+ /**
+ * Formatter for timings.
+ */
+ private NumberFormat numberFormat = NumberFormat.getInstance();
+
+ /**
+ * Output suite has written to System.out
+ */
+ private String systemOutput = null;
+
+ /**
+ * Output suite has written to System.err
+ */
+ private String systemError = null;
+
+ /**
+ * Constructor for BriefJUnitResultFormatter.
+ */
+ public BriefJUnitResultFormatter() {
+ results = new StringWriter();
+ resultWriter = new BufferedWriter(results);
+ }
+
+ /**
+ * Sets the stream the formatter is supposed to write its results to.
+ * @param out the output stream to write to
+ */
+ public void setOutput(OutputStream out) {
+ this.out = out;
+ output = new BufferedWriter(new java.io.OutputStreamWriter(out));
+ }
+
+ /**
+ * @see JUnitResultFormatter#setSystemOutput(String)
+ */
+ /** {@inheritDoc}. */
+ public void setSystemOutput(String out) {
+ systemOutput = out;
+ }
+
+ /**
+ * @see JUnitResultFormatter#setSystemError(String)
+ */
+ /** {@inheritDoc}. */
+ public void setSystemError(String err) {
+ systemError = err;
+ }
+
+
+ /**
+ * The whole testsuite started.
+ * @param suite the test suite
+ */
+ public void startTestSuite(JUnitTest suite) {
+ if (output == null) {
+ return; // Quick return - no output do nothing.
+ }
+ StringBuffer sb = new StringBuffer("Testsuite: ");
+ sb.append(suite.getName());
+ sb.append(StringUtils.LINE_SEP);
+ try {
+ output.write(sb.toString());
+ output.flush();
+ } catch (IOException ex) {
+ throw new BuildException(ex);
+ }
+ }
+
+ /**
+ * The whole testsuite ended.
+ * @param suite the test suite
+ */
+ public void endTestSuite(JUnitTest suite) {
+ StringBuffer sb = new StringBuffer("Tests run: ");
+ sb.append(suite.runCount());
+ sb.append(", Failures: ");
+ sb.append(suite.failureCount());
+ sb.append(", Errors: ");
+ sb.append(suite.errorCount());
+ sb.append(", Skipped: ");
+ sb.append(suite.skipCount());
+ sb.append(", Time elapsed: ");
+ sb.append(numberFormat.format(suite.getRunTime() / ONE_SECOND));
+ sb.append(" sec");
+ sb.append(StringUtils.LINE_SEP);
+ sb.append(StringUtils.LINE_SEP);
+
+ // append the err and output streams to the log
+ if (systemOutput != null && systemOutput.length() > 0) {
+ sb.append("------------- Standard Output ---------------")
+ .append(StringUtils.LINE_SEP)
+ .append(systemOutput)
+ .append("------------- ---------------- ---------------")
+ .append(StringUtils.LINE_SEP);
+ }
+
+ if (systemError != null && systemError.length() > 0) {
+ sb.append("------------- Standard Error -----------------")
+ .append(StringUtils.LINE_SEP)
+ .append(systemError)
+ .append("------------- ---------------- ---------------")
+ .append(StringUtils.LINE_SEP);
+ }
+
+ if (output != null) {
+ try {
+ output.write(sb.toString());
+ resultWriter.close();
+ output.write(results.toString());
+ } catch (IOException ex) {
+ throw new BuildException(ex);
+ } finally {
+ try {
+ output.flush();
+ } catch (IOException ex) {
+ // swallow, there has likely been an exception before this
+ }
+ if (out != System.out && out != System.err) {
+ FileUtils.close(out);
+ }
+ }
+ }
+ }
+
+ /**
+ * A test started.
+ * @param test a test
+ */
+ public void startTest(Test test) {
+ }
+
+ /**
+ * A test ended.
+ * @param test a test
+ */
+ public void endTest(Test test) {
+ }
+
+ /**
+ * Interface TestListener for JUnit &lt;= 3.4.
+ *
+ * <p>A Test failed.
+ * @param test a test
+ * @param t the exception thrown by the test
+ */
+ public void addFailure(Test test, Throwable t) {
+ formatError("\tFAILED", test, t);
+ }
+
+ /**
+ * Interface TestListener for JUnit &gt; 3.4.
+ *
+ * <p>A Test failed.
+ * @param test a test
+ * @param t the assertion failed by the test
+ */
+ public void addFailure(Test test, AssertionFailedError t) {
+ addFailure(test, (Throwable) t);
+ }
+
+ /**
+ * A test caused an error.
+ * @param test a test
+ * @param error the error thrown by the test
+ */
+ public void addError(Test test, Throwable error) {
+ formatError("\tCaused an ERROR", test, error);
+ }
+
+ /**
+ * Format the test for printing..
+ * @param test a test
+ * @return the formatted testname
+ */
+ protected String formatTest(Test test) {
+ if (test == null) {
+ return "Null Test: ";
+ } else {
+ return "Testcase: " + test.toString() + ":";
+ }
+ }
+
+ /**
+ * Format an error and print it.
+ * @param type the type of error
+ * @param test the test that failed
+ * @param error the exception that the test threw
+ */
+ protected synchronized void formatError(String type, Test test,
+ Throwable error) {
+ if (test != null) {
+ endTest(test);
+ }
+
+ try {
+ resultWriter.write(formatTest(test) + type);
+ resultWriter.newLine();
+ resultWriter.write(String.valueOf(error.getMessage()));
+ resultWriter.newLine();
+ String strace = JUnitTestRunner.getFilteredTrace(error);
+ resultWriter.write(strace);
+ resultWriter.newLine();
+ resultWriter.newLine();
+ } catch (IOException ex) {
+ throw new BuildException(ex);
+ }
+ }
+
+
+ public void testIgnored(Test test) {
+ formatSkip(test, JUnitVersionHelper.getIgnoreMessage(test));
+ }
+
+
+ public void formatSkip(Test test, String message) {
+ if (test != null) {
+ endTest(test);
+ }
+
+ try {
+ resultWriter.write(formatTest(test) + "SKIPPED");
+ if (message != null) {
+ resultWriter.write(": ");
+ resultWriter.write(message);
+ }
+ resultWriter.newLine();
+ } catch (IOException ex) {
+ throw new BuildException(ex);
+ }
+
+ }
+
+ public void testAssumptionFailure(Test test, Throwable cause) {
+ formatSkip(test, cause.getMessage());
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/Constants.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/Constants.java
new file mode 100644
index 00000000..368c72e2
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/Constants.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.junit;
+
+/**
+ * Constants, like filenames shared between various classes in this package.
+ */
+public class Constants {
+
+ private Constants() {
+ }
+
+ static final String METHOD_NAMES = "methods=";
+ static final String HALT_ON_ERROR = "haltOnError=";
+ static final String HALT_ON_FAILURE = "haltOnFailure=";
+ static final String FILTERTRACE = "filtertrace=";
+ static final String CRASHFILE = "crashfile=";
+ static final String BEFORE_FIRST_TEST = "BeforeFirstTest";
+ static final String PROPSFILE = "propsfile=";
+ static final String SHOWOUTPUT = "showoutput=";
+ static final String OUTPUT_TO_FORMATTERS = "outputtoformatters=";
+ static final String FORMATTER = "formatter=";
+ static final String LOGTESTLISTENEREVENTS = "logtestlistenerevents=";
+ static final String TESTSFILE = "testsfile=";
+ static final String TERMINATED_SUCCESSFULLY = "terminated successfully";
+ static final String LOG_FAILED_TESTS="logfailedtests=";
+ static final String SKIP_NON_TESTS = "skipNonTests=";
+ /** @since Ant 1.9.4 */
+ static final String THREADID="threadid=";
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/CustomJUnit4TestAdapterCache.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/CustomJUnit4TestAdapterCache.java
new file mode 100644
index 00000000..8ad40dd6
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/CustomJUnit4TestAdapterCache.java
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.junit;
+
+import junit.framework.JUnit4TestAdapter;
+import junit.framework.JUnit4TestAdapterCache;
+import junit.framework.TestResult;
+
+import org.junit.runner.Description;
+import org.junit.runner.notification.Failure;
+import org.junit.runner.notification.RunListener;
+import org.junit.runner.notification.RunNotifier;
+
+/**
+ * Provides a custom implementation of the notifier for a JUnit4TestAdapter
+ * so that skipped and ignored tests can be reported to the existing
+ * <tt>TestListener</tt>s.
+ *
+ */
+public class CustomJUnit4TestAdapterCache extends JUnit4TestAdapterCache {
+
+ private static final CustomJUnit4TestAdapterCache INSTANCE = new CustomJUnit4TestAdapterCache();
+
+ public static CustomJUnit4TestAdapterCache getInstance() {
+ return INSTANCE;
+ }
+
+ private CustomJUnit4TestAdapterCache() {
+ super();
+ }
+
+ public RunNotifier getNotifier(final TestResult result, final JUnit4TestAdapter adapter) {
+ return getNotifier(result);
+ }
+
+ public RunNotifier getNotifier(final TestResult result) {
+
+ final IgnoredTestResult resultWrapper = (IgnoredTestResult) result;
+
+ RunNotifier notifier = new RunNotifier();
+ notifier.addListener(new RunListener() {
+ @Override
+ public void testFailure(Failure failure) throws Exception {
+ result.addError(asTest(failure.getDescription()), failure.getException());
+ }
+
+ @Override
+ public void testFinished(Description description) throws Exception {
+ result.endTest(asTest(description));
+ }
+
+ @Override
+ public void testStarted(Description description) throws Exception {
+ result.startTest(asTest(description));
+ }
+
+ @Override
+ public void testIgnored(Description description) throws Exception {
+ if (resultWrapper != null) {
+ resultWrapper.testIgnored(asTest(description));
+ }
+ }
+
+ @Override
+ public void testAssumptionFailure(Failure failure) {
+ if (resultWrapper != null) {
+ resultWrapper.testAssumptionFailure(asTest(failure.getDescription()), failure.getException());
+ }
+ }
+ });
+
+ return notifier;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/DOMUtil.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/DOMUtil.java
new file mode 100644
index 00000000..325f44cf
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/DOMUtil.java
@@ -0,0 +1,228 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.junit;
+
+import java.util.Vector;
+
+import org.w3c.dom.Attr;
+import org.w3c.dom.CDATASection;
+import org.w3c.dom.Comment;
+import org.w3c.dom.DOMException;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.ProcessingInstruction;
+import org.w3c.dom.Text;
+
+/**
+ * Some utilities that might be useful when manipulating DOM trees.
+ *
+ */
+public final class DOMUtil {
+
+ /** unused constructor */
+ private DOMUtil() {
+ }
+
+ /**
+ * Filter interface to be applied when iterating over a DOM tree.
+ * Just think of it like a <tt>FileFilter</tt> clone.
+ */
+ public interface NodeFilter {
+ /**
+ * @param node the node to check for acceptance.
+ * @return <tt>true</tt> if the node is accepted by this filter,
+ * otherwise <tt>false</tt>
+ */
+ boolean accept(Node node);
+ }
+
+ /**
+ * list a set of node that match a specific filter. The list can be made
+ * recursively or not.
+ * @param parent the parent node to search from
+ * @param filter the filter that children should match.
+ * @param recurse <tt>true</tt> if you want the list to be made recursively
+ * otherwise <tt>false</tt>.
+ * @return the node list that matches the filter.
+ */
+ public static NodeList listChildNodes(Node parent, NodeFilter filter, boolean recurse) {
+ NodeListImpl matches = new NodeListImpl();
+ NodeList children = parent.getChildNodes();
+ if (children != null) {
+ final int len = children.getLength();
+ for (int i = 0; i < len; i++) {
+ Node child = children.item(i);
+ if (filter.accept(child)) {
+ matches.addElement(child);
+ }
+ if (recurse) {
+ NodeList recmatches = listChildNodes(child, filter, recurse);
+ final int reclength = recmatches.getLength();
+ for (int j = 0; j < reclength; j++) {
+ matches.addElement(recmatches.item(i));
+ }
+ }
+ }
+ }
+ return matches;
+ }
+
+ /** custom implementation of a nodelist */
+ public static class NodeListImpl extends Vector implements NodeList {
+ private static final long serialVersionUID = 3175749150080946423L;
+
+ /**
+ * Get the number of nodes in the list.
+ * @return the length of the list.
+ */
+ public int getLength() {
+ return size();
+ }
+ /**
+ * Get a particular node.
+ * @param i the index of the node to get.
+ * @return the node if the index is in bounds, null otherwise.
+ */
+ public Node item(int i) {
+ try {
+ return (Node) elementAt(i);
+ } catch (ArrayIndexOutOfBoundsException e) {
+ return null; // conforming to NodeList interface
+ }
+ }
+ }
+
+ /**
+ * return the attribute value of an element.
+ * @param node the node to get the attribute from.
+ * @param name the name of the attribute we are looking for the value.
+ * @return the value of the requested attribute or <tt>null</tt> if the
+ * attribute was not found or if <tt>node</tt> is not an <tt>Element</tt>.
+ */
+ public static String getNodeAttribute(Node node, String name) {
+ if (node instanceof Element) {
+ Element element = (Element) node;
+ return element.getAttribute(name);
+ }
+ return null;
+ }
+
+
+ /**
+ * Iterate over the children of a given node and return the first node
+ * that has a specific name.
+ * @param parent the node to search child from. Can be <tt>null</tt>.
+ * @param tagname the child name we are looking for. Cannot be <tt>null</tt>.
+ * @return the first child that matches the given name or <tt>null</tt> if
+ * the parent is <tt>null</tt> or if a child does not match the
+ * given name.
+ */
+ public static Element getChildByTagName (Node parent, String tagname) {
+ if (parent == null) {
+ return null;
+ }
+ NodeList childList = parent.getChildNodes();
+ final int len = childList.getLength();
+ for (int i = 0; i < len; i++) {
+ Node child = childList.item(i);
+ if (child != null && child.getNodeType() == Node.ELEMENT_NODE
+ && child.getNodeName().equals(tagname)) {
+ return (Element) child;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Simple tree walker that will clone recursively a node. This is to
+ * avoid using parser-specific API such as Sun's <tt>changeNodeOwner</tt>
+ * when we are dealing with DOM L1 implementations since <tt>cloneNode(boolean)</tt>
+ * will not change the owner document.
+ * <tt>changeNodeOwner</tt> is much faster and avoid the costly cloning process.
+ * <tt>importNode</tt> is in the DOM L2 interface.
+ * @param parent the node parent to which we should do the import to.
+ * @param child the node to clone recursively. Its clone will be
+ * appended to <tt>parent</tt>.
+ * @return the cloned node that is appended to <tt>parent</tt>
+ */
+ public static Node importNode(Node parent, Node child) {
+ Node copy = null;
+ final Document doc = parent.getOwnerDocument();
+
+ switch (child.getNodeType()) {
+ case Node.CDATA_SECTION_NODE:
+ copy = doc.createCDATASection(((CDATASection) child).getData());
+ break;
+ case Node.COMMENT_NODE:
+ copy = doc.createComment(((Comment) child).getData());
+ break;
+ case Node.DOCUMENT_FRAGMENT_NODE:
+ copy = doc.createDocumentFragment();
+ break;
+ case Node.ELEMENT_NODE:
+ final Element elem = doc.createElement(((Element) child).getTagName());
+ copy = elem;
+ final NamedNodeMap attributes = child.getAttributes();
+ if (attributes != null) {
+ final int size = attributes.getLength();
+ for (int i = 0; i < size; i++) {
+ final Attr attr = (Attr) attributes.item(i);
+ elem.setAttribute(attr.getName(), attr.getValue());
+ }
+ }
+ break;
+ case Node.ENTITY_REFERENCE_NODE:
+ copy = doc.createEntityReference(child.getNodeName());
+ break;
+ case Node.PROCESSING_INSTRUCTION_NODE:
+ final ProcessingInstruction pi = (ProcessingInstruction) child;
+ copy = doc.createProcessingInstruction(pi.getTarget(), pi.getData());
+ break;
+ case Node.TEXT_NODE:
+ copy = doc.createTextNode(((Text) child).getData());
+ break;
+ default:
+ // this should never happen
+ throw new IllegalStateException("Invalid node type: " + child.getNodeType());
+ }
+
+ // okay we have a copy of the child, now the child becomes the parent
+ // and we are iterating recursively over its children.
+ try {
+ final NodeList children = child.getChildNodes();
+ if (children != null) {
+ final int size = children.getLength();
+ for (int i = 0; i < size; i++) {
+ final Node newChild = children.item(i);
+ if (newChild != null) {
+ importNode(copy, newChild);
+ }
+ }
+ }
+ } catch (DOMException ignored) {
+ // Ignore
+ }
+
+ // bingo append it. (this should normally not be done here)
+ parent.appendChild(copy);
+ return copy;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/Enumerations.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/Enumerations.java
new file mode 100644
index 00000000..327547ef
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/Enumerations.java
@@ -0,0 +1,177 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.junit;
+
+import java.util.Enumeration;
+import java.util.NoSuchElementException;
+
+/**
+ * A couple of methods related to enumerations that might be useful.
+ * This class should probably disappear once the required JDK is set to 1.2
+ * instead of 1.1.
+ *
+ */
+public final class Enumerations {
+
+ private Enumerations() {
+ }
+
+ /**
+ * creates an enumeration from an array of objects.
+ * @param array the array of object to enumerate.
+ * @return the enumeration over the array of objects.
+ */
+ public static Enumeration fromArray(Object[] array) {
+ return new ArrayEnumeration(array);
+ }
+
+ /**
+ * creates an enumeration from an array of enumeration. The created enumeration
+ * will sequentially enumerate over all elements of each enumeration and skip
+ * <tt>null</tt> enumeration elements in the array.
+ * @param enums the array of enumerations.
+ * @return the enumeration over the array of enumerations.
+ */
+ public static Enumeration fromCompound(Enumeration[] enums) {
+ return new CompoundEnumeration(enums);
+ }
+
+}
+
+
+/**
+ * Convenient enumeration over an array of objects.
+ */
+class ArrayEnumeration implements Enumeration {
+
+ /** object array */
+ private Object[] array;
+
+ /** current index */
+ private int pos;
+
+ /**
+ * Initialize a new enumeration that wraps an array.
+ * @param array the array of object to enumerate.
+ */
+ public ArrayEnumeration(Object[] array) {
+ this.array = array;
+ this.pos = 0;
+ }
+ /**
+ * Tests if this enumeration contains more elements.
+ *
+ * @return <code>true</code> if and only if this enumeration object
+ * contains at least one more element to provide;
+ * <code>false</code> otherwise.
+ */
+ public boolean hasMoreElements() {
+ return (pos < array.length);
+ }
+
+ /**
+ * Returns the next element of this enumeration if this enumeration
+ * object has at least one more element to provide.
+ *
+ * @return the next element of this enumeration.
+ * @throws NoSuchElementException if no more elements exist.
+ */
+ public Object nextElement() throws NoSuchElementException {
+ if (hasMoreElements()) {
+ Object o = array[pos];
+ pos++;
+ return o;
+ }
+ throw new NoSuchElementException();
+ }
+}
+/**
+ * Convenient enumeration over an array of enumeration. For example:
+ * <pre>
+ * Enumeration e1 = v1.elements();
+ * while (e1.hasMoreElements()) {
+ * // do something
+ * }
+ * Enumeration e2 = v2.elements();
+ * while (e2.hasMoreElements()) {
+ * // do the same thing
+ * }
+ * </pre>
+ * can be written as:
+ * <pre>
+ * Enumeration[] enums = { v1.elements(), v2.elements() };
+ * Enumeration e = Enumerations.fromCompound(enums);
+ * while (e.hasMoreElements()) {
+ * // do something
+ * }
+ * </pre>
+ * Note that the enumeration will skip null elements in the array. The following is
+ * thus possible:
+ * <pre>
+ * Enumeration[] enums = { v1.elements(), null, v2.elements() }; // a null enumeration in the array
+ * Enumeration e = Enumerations.fromCompound(enums);
+ * while (e.hasMoreElements()) {
+ * // do something
+ * }
+ * </pre>
+ */
+ class CompoundEnumeration implements Enumeration {
+
+ /** enumeration array */
+ private Enumeration[] enumArray;
+
+ /** index in the enums array */
+ private int index = 0;
+
+ public CompoundEnumeration(Enumeration[] enumarray) {
+ this.enumArray = enumarray;
+ }
+
+ /**
+ * Tests if this enumeration contains more elements.
+ *
+ * @return <code>true</code> if and only if this enumeration object
+ * contains at least one more element to provide;
+ * <code>false</code> otherwise.
+ */
+ public boolean hasMoreElements() {
+ while (index < enumArray.length) {
+ if (enumArray[index] != null && enumArray[index].hasMoreElements()) {
+ return true;
+ }
+ index++;
+ }
+ return false;
+ }
+
+ /**
+ * Returns the next element of this enumeration if this enumeration
+ * object has at least one more element to provide.
+ *
+ * @return the next element of this enumeration.
+ * @throws NoSuchElementException if no more elements exist.
+ */
+ public Object nextElement() throws NoSuchElementException {
+ if (hasMoreElements()) {
+ return enumArray[index].nextElement();
+ }
+ throw new NoSuchElementException();
+ }
+}
+
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/FailureRecorder.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/FailureRecorder.java
new file mode 100644
index 00000000..3046b75a
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/FailureRecorder.java
@@ -0,0 +1,448 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.junit;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.SortedSet;
+import java.util.TreeSet;
+import java.util.Vector;
+
+import junit.framework.AssertionFailedError;
+import junit.framework.Test;
+
+import org.apache.tools.ant.BuildEvent;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.BuildListener;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.ProjectComponent;
+import org.apache.tools.ant.util.FileUtils;
+
+/**
+ * <p>Collects all failing test <i>cases</i> and creates a new JUnit test class containing
+ * a suite() method which calls these failed tests.</p>
+ * <p>Having classes <i>A</i> ... <i>D</i> with each several testcases you could earn a new
+ * test class like
+ * <pre>
+ * // generated on: 2007.08.06 09:42:34,555
+ * import junit.framework.*;
+ * public class FailedTests extends TestCase {
+ * public FailedTests(String testname) {
+ * super(testname);
+ * }
+ * public static Test suite() {
+ * TestSuite suite = new TestSuite();
+ * suite.addTest( new B("test04") );
+ * suite.addTest( new org.D("test10") );
+ * return suite;
+ * }
+ * }
+ * </pre>
+ *
+ * Because each running test case gets its own formatter, we collect
+ * the failing test cases in a static list. Because we dont have a finalizer
+ * method in the formatters "lifecycle", we register this formatter as
+ * BuildListener and generate the new java source on taskFinished event.
+ *
+ * @since Ant 1.8.0
+ */
+public class FailureRecorder extends ProjectComponent implements JUnitResultFormatter, BuildListener {
+
+ /**
+ * This is the name of a magic System property ({@value}). The value of this
+ * <b>System</b> property should point to the location where to store the
+ * generated class (without suffix).
+ * Default location and name is defined in DEFAULT_CLASS_LOCATION.
+ * @see #DEFAULT_CLASS_LOCATION
+ */
+ public static final String MAGIC_PROPERTY_CLASS_LOCATION
+ = "ant.junit.failureCollector";
+
+ /** Default location and name for the generated JUnit class file,
+ * in the temp directory + FailedTests */
+ public static final String DEFAULT_CLASS_LOCATION
+ = System.getProperty("java.io.tmpdir") + "FailedTests";
+
+ /** Prefix for logging. {@value} */
+ private static final String LOG_PREFIX = " [junit]";
+
+ /** Class names of failed tests without duplicates. */
+ private static SortedSet/*<TestInfos>*/ failedTests = new TreeSet();
+
+ /** A writer for writing the generated source to. */
+ private BufferedWriter writer;
+
+ /**
+ * Location and name of the generated JUnit class.
+ * Lazy instantiated via getLocationName().
+ */
+ private static String locationName;
+
+ /**
+ * Returns the (lazy evaluated) location for the collector class.
+ * Order for evaluation: System property > Ant property > default value
+ * @return location for the collector class
+ * @see #MAGIC_PROPERTY_CLASS_LOCATION
+ * @see #DEFAULT_CLASS_LOCATION
+ */
+ private String getLocationName() {
+ if (locationName == null) {
+ String syspropValue = System.getProperty(MAGIC_PROPERTY_CLASS_LOCATION);
+ String antpropValue = getProject().getProperty(MAGIC_PROPERTY_CLASS_LOCATION);
+
+ if (syspropValue != null) {
+ locationName = syspropValue;
+ verbose("System property '" + MAGIC_PROPERTY_CLASS_LOCATION + "' set, so use "
+ + "its value '" + syspropValue + "' as location for collector class.");
+ } else if (antpropValue != null) {
+ locationName = antpropValue;
+ verbose("Ant property '" + MAGIC_PROPERTY_CLASS_LOCATION + "' set, so use "
+ + "its value '" + antpropValue + "' as location for collector class.");
+ } else {
+ locationName = DEFAULT_CLASS_LOCATION;
+ verbose("System property '" + MAGIC_PROPERTY_CLASS_LOCATION + "' not set, so use "
+ + "value as location for collector class: '"
+ + DEFAULT_CLASS_LOCATION + "'");
+ }
+
+ File locationFile = new File(locationName);
+ if (!locationFile.isAbsolute()) {
+ File f = new File(getProject().getBaseDir(), locationName);
+ locationName = f.getAbsolutePath();
+ verbose("Location file is relative (" + locationFile + ")"
+ + " use absolute path instead (" + locationName + ")");
+ }
+ }
+
+ return locationName;
+ }
+
+ /**
+ * This method is called by the Ant runtime by reflection. We use the project reference for
+ * registration of this class as BuildListener.
+ *
+ * @param project
+ * project reference
+ */
+ public void setProject(Project project) {
+ // store project reference for logging
+ super.setProject(project);
+ // check if already registered
+ boolean alreadyRegistered = false;
+ Vector allListeners = project.getBuildListeners();
+ final int size = allListeners.size();
+ for (int i = 0; i < size; i++) {
+ Object listener = allListeners.get(i);
+ if (listener instanceof FailureRecorder) {
+ alreadyRegistered = true;
+ break;
+ }
+ }
+ // register if needed
+ if (!alreadyRegistered) {
+ verbose("Register FailureRecorder (@" + this.hashCode() + ") as BuildListener");
+ project.addBuildListener(this);
+ }
+ }
+
+ // ===== JUnitResultFormatter =====
+
+ /**
+ * Not used
+ * {@inheritDoc}
+ */
+ public void endTestSuite(JUnitTest suite) throws BuildException {
+ }
+
+ /**
+ * Add the failed test to the list.
+ * @param test the test that errored.
+ * @param throwable the reason it errored.
+ * @see junit.framework.TestListener#addError(junit.framework.Test, java.lang.Throwable)
+ */
+ public void addError(Test test, Throwable throwable) {
+ failedTests.add(new TestInfos(test));
+ }
+
+ // CheckStyle:LineLengthCheck OFF - @see is long
+ /**
+ * Add the failed test to the list.
+ * @param test the test that failed.
+ * @param error the assertion that failed.
+ * @see junit.framework.TestListener#addFailure(junit.framework.Test, junit.framework.AssertionFailedError)
+ */
+ // CheckStyle:LineLengthCheck ON
+ public void addFailure(Test test, AssertionFailedError error) {
+ failedTests.add(new TestInfos(test));
+ }
+
+ /**
+ * Not used
+ * {@inheritDoc}
+ */
+ public void setOutput(OutputStream out) {
+ // unused, close output file so it can be deleted before the VM exits
+ if (out != System.out) {
+ FileUtils.close(out);
+ }
+ }
+
+ /**
+ * Not used
+ * {@inheritDoc}
+ */
+ public void setSystemError(String err) {
+ }
+
+ /**
+ * Not used
+ * {@inheritDoc}
+ */
+ public void setSystemOutput(String out) {
+ }
+
+ /**
+ * Not used
+ * {@inheritDoc}
+ */
+ public void startTestSuite(JUnitTest suite) throws BuildException {
+ }
+
+ /**
+ * Not used
+ * {@inheritDoc}
+ */
+ public void endTest(Test test) {
+ }
+
+ /**
+ * Not used
+ * {@inheritDoc}
+ */
+ public void startTest(Test test) {
+ }
+
+ // ===== "Templates" for generating the JUnit class =====
+
+ private void writeJavaClass() {
+ try {
+ File sourceFile = new File((getLocationName() + ".java"));
+ verbose("Write collector class to '" + sourceFile.getAbsolutePath() + "'");
+
+ if (sourceFile.exists() && !sourceFile.delete()) {
+ throw new IOException("could not delete " + sourceFile);
+ }
+ writer = new BufferedWriter(new FileWriter(sourceFile));
+
+ createClassHeader();
+ createSuiteMethod();
+ createClassFooter();
+
+ } catch (IOException e) {
+ e.printStackTrace();
+ } finally {
+ FileUtils.close(writer);
+ }
+ }
+
+ private void createClassHeader() throws IOException {
+ String className = getLocationName().replace('\\', '/');
+ if (className.indexOf('/') > -1) {
+ className = className.substring(className.lastIndexOf('/') + 1);
+ }
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss,SSS");
+ writer.write("// generated on: ");
+ writer.write(sdf.format(new Date()));
+ writer.newLine();
+ writer.write("import junit.framework.*;");
+ writer.newLine();
+ writer.write("public class ");
+ writer.write(className);
+ // If this class does not extend TC, Ant doesn't run these
+ writer.write(" extends TestCase {");
+ writer.newLine();
+ // standard String-constructor
+ writer.write(" public ");
+ writer.write(className);
+ writer.write("(String testname) {");
+ writer.newLine();
+ writer.write(" super(testname);");
+ writer.newLine();
+ writer.write(" }");
+ writer.newLine();
+ }
+
+ private void createSuiteMethod() throws IOException {
+ writer.write(" public static Test suite() {");
+ writer.newLine();
+ writer.write(" TestSuite suite = new TestSuite();");
+ writer.newLine();
+ for (Iterator iter = failedTests.iterator(); iter.hasNext();) {
+ TestInfos testInfos = (TestInfos) iter.next();
+ writer.write(" suite.addTest(");
+ writer.write(String.valueOf(testInfos));
+ writer.write(");");
+ writer.newLine();
+ }
+ writer.write(" return suite;");
+ writer.newLine();
+ writer.write(" }");
+ writer.newLine();
+ }
+
+ private void createClassFooter() throws IOException {
+ writer.write("}");
+ writer.newLine();
+ }
+
+ // ===== Helper classes and methods =====
+
+ /**
+ * Logging facade in INFO-mode.
+ * @param message Log-message
+ */
+ public void log(String message) {
+ getProject().log(LOG_PREFIX + " " + message, Project.MSG_INFO);
+ }
+
+ /**
+ * Logging facade in VERBOSE-mode.
+ * @param message Log-message
+ */
+ public void verbose(String message) {
+ getProject().log(LOG_PREFIX + " " + message, Project.MSG_VERBOSE);
+ }
+
+ /**
+ * TestInfos holds information about a given test for later use.
+ */
+ public static class TestInfos implements Comparable {
+
+ /** The class name of the test. */
+ private final String className;
+
+ /** The method name of the testcase. */
+ private final String methodName;
+
+ /**
+ * This constructor extracts the needed information from the given test.
+ * @param test Test to analyze
+ */
+ public TestInfos(Test test) {
+ className = test.getClass().getName();
+ String _methodName = test.toString();
+ methodName = _methodName.substring(0, _methodName.indexOf('('));
+ }
+
+ /**
+ * This String-Representation can directly be used for instantiation of
+ * the JUnit testcase.
+ * @return the string representation.
+ * @see java.lang.Object#toString()
+ * @see FailureRecorder#createSuiteMethod()
+ */
+ public String toString() {
+ return "new " + className + "(\"" + methodName + "\")";
+ }
+
+ /**
+ * The SortedMap needs comparable elements.
+ * @param other the object to compare to.
+ * @return the result of the comparison.
+ * @see java.lang.Comparable#compareTo
+ * @see SortedSet#comparator()
+ */
+ public int compareTo(Object other) {
+ if (other instanceof TestInfos) {
+ TestInfos otherInfos = (TestInfos) other;
+ return toString().compareTo(otherInfos.toString());
+ } else {
+ return -1;
+ }
+ }
+ public boolean equals(Object obj) {
+ return obj instanceof TestInfos && toString().equals(obj.toString());
+ }
+ public int hashCode() {
+ return toString().hashCode();
+ }
+ }
+
+ // ===== BuildListener =====
+
+ /**
+ * Not used
+ * {@inheritDoc}
+ */
+ public void buildFinished(BuildEvent event) {
+ }
+
+ /**
+ * Not used
+ * {@inheritDoc}
+ */
+ public void buildStarted(BuildEvent event) {
+ }
+
+ /**
+ * Not used
+ * {@inheritDoc}
+ */
+ public void messageLogged(BuildEvent event) {
+ }
+
+ /**
+ * Not used
+ * {@inheritDoc}
+ */
+ public void targetFinished(BuildEvent event) {
+ }
+
+ /**
+ * Not used
+ * {@inheritDoc}
+ */
+ public void targetStarted(BuildEvent event) {
+ }
+
+ /**
+ * The task outside of this JUnitResultFormatter is the <junit> task. So all tests passed
+ * and we could create the new java class.
+ * @param event not used
+ * @see org.apache.tools.ant.BuildListener#taskFinished(org.apache.tools.ant.BuildEvent)
+ */
+ public void taskFinished(BuildEvent event) {
+ if (!failedTests.isEmpty()) {
+ writeJavaClass();
+ }
+ }
+
+ /**
+ * Not used
+ * {@inheritDoc}
+ */
+ public void taskStarted(BuildEvent event) {
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/FormatterElement.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/FormatterElement.java
new file mode 100644
index 00000000..f9fbcb0a
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/FormatterElement.java
@@ -0,0 +1,401 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.junit;
+
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.PropertyHelper;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.types.EnumeratedAttribute;
+import org.apache.tools.ant.util.KeepAliveOutputStream;
+
+/**
+ * <p> A wrapper for the implementations of <code>JUnitResultFormatter</code>.
+ * In particular, used as a nested <code>&lt;formatter&gt;</code> element in
+ * a <code>&lt;junit&gt;</code> task.
+ * <p> For example,
+ * <code><pre>
+ * &lt;junit printsummary="no" haltonfailure="yes" fork="false"&gt;
+ * &lt;formatter type="plain" usefile="false" /&gt;
+ * &lt;test name="org.apache.ecs.InternationalCharTest" /&gt;
+ * &lt;/junit&gt;</pre></code>
+ * adds a <code>plain</code> type implementation
+ * (<code>PlainJUnitResultFormatter</code>) to display the results of the test.
+ *
+ * <p> Either the <code>type</code> or the <code>classname</code> attribute
+ * must be set.
+ *
+ * @see JUnitTask
+ * @see XMLJUnitResultFormatter
+ * @see BriefJUnitResultFormatter
+ * @see PlainJUnitResultFormatter
+ * @see FailureRecorder
+ * @see JUnitResultFormatter
+ */
+public class FormatterElement {
+
+ private String classname;
+ private String extension;
+ private OutputStream out = new KeepAliveOutputStream(System.out);
+ private File outFile;
+ private boolean useFile = true;
+ private Object ifCond;
+ private Object unlessCond;
+
+ /**
+ * Store the project reference for passing it to nested components.
+ * @since Ant 1.8
+ */
+ private Project project;
+
+ /** xml formatter class */
+ public static final String XML_FORMATTER_CLASS_NAME =
+ "org.apache.tools.ant.taskdefs.optional.junit.XMLJUnitResultFormatter";
+ /** brief formatter class */
+ public static final String BRIEF_FORMATTER_CLASS_NAME =
+ "org.apache.tools.ant.taskdefs.optional.junit.BriefJUnitResultFormatter";
+ /** plain formatter class */
+ public static final String PLAIN_FORMATTER_CLASS_NAME =
+ "org.apache.tools.ant.taskdefs.optional.junit.PlainJUnitResultFormatter";
+ /** failure recorder class */
+ public static final String FAILURE_RECORDER_CLASS_NAME =
+ "org.apache.tools.ant.taskdefs.optional.junit.FailureRecorder";
+
+ /**
+ * <p> Quick way to use a standard formatter.
+ *
+ * <p> At the moment, there are three supported standard formatters.
+ * <ul>
+ * <li> The <code>xml</code> type uses a <code>XMLJUnitResultFormatter</code>.
+ * <li> The <code>brief</code> type uses a <code>BriefJUnitResultFormatter</code>.
+ * <li> The <code>plain</code> type (the default) uses a <code>PlainJUnitResultFormatter</code>.
+ * <li> The <code>failure</code> type uses a <code>FailureRecorder</code>.
+ * </ul>
+ *
+ * <p> Sets <code>classname</code> attribute - so you can't use that
+ * attribute if you use this one.
+ * @param type the enumerated value to use.
+ */
+ public void setType(TypeAttribute type) {
+ if ("xml".equals(type.getValue())) {
+ setClassname(XML_FORMATTER_CLASS_NAME);
+ } else {
+ if ("brief".equals(type.getValue())) {
+ setClassname(BRIEF_FORMATTER_CLASS_NAME);
+ } else {
+ if ("failure".equals(type.getValue())) {
+ setClassname(FAILURE_RECORDER_CLASS_NAME);
+ } else { // must be plain, ensured by TypeAttribute
+ setClassname(PLAIN_FORMATTER_CLASS_NAME);
+ }
+ }
+ }
+ }
+
+ /**
+ * <p> Set name of class to be used as the formatter.
+ *
+ * <p> This class must implement <code>JUnitResultFormatter</code>
+ * @param classname the name of the formatter class.
+ */
+ public void setClassname(String classname) {
+ this.classname = classname;
+ if (XML_FORMATTER_CLASS_NAME.equals(classname)) {
+ setExtension(".xml");
+ } else if (PLAIN_FORMATTER_CLASS_NAME.equals(classname)) {
+ setExtension(".txt");
+ } else if (BRIEF_FORMATTER_CLASS_NAME.equals(classname)) {
+ setExtension(".txt");
+ }
+ }
+
+ /**
+ * Get name of class to be used as the formatter.
+ * @return the name of the class.
+ */
+ public String getClassname() {
+ return classname;
+ }
+
+ /**
+ * Set the extension to use for the report file.
+ * @param ext the extension to use.
+ */
+ public void setExtension(String ext) {
+ this.extension = ext;
+ }
+
+ /**
+ * Get the extension used for the report file.
+ * @return the extension.
+ */
+ public String getExtension() {
+ return extension;
+ }
+
+ /**
+ * <p> Set the file which the formatte should log to.
+ *
+ * <p> Note that logging to file must be enabled .
+ */
+ void setOutfile(File out) {
+ this.outFile = out;
+ }
+
+ /**
+ * <p> Set output stream for formatter to use.
+ *
+ * <p> Defaults to standard out.
+ * @param out the output stream to use.
+ */
+ public void setOutput(OutputStream out) {
+ if (out == System.out || out == System.err) {
+ out = new KeepAliveOutputStream(out);
+ }
+ this.out = out;
+ }
+
+ /**
+ * Set whether the formatter should log to file.
+ * @param useFile if true use a file, if false send
+ * to standard out.
+ */
+ public void setUseFile(boolean useFile) {
+ this.useFile = useFile;
+ }
+
+ /**
+ * Get whether the formatter should log to file.
+ */
+ boolean getUseFile() {
+ return useFile;
+ }
+
+ /**
+ * Set whether this formatter should be used. It will be used if
+ * the expression evaluates to true or the name of a property
+ * which has been set, otherwise it won't.
+ * @param ifCond name of property
+ * @since Ant 1.8.0
+ */
+ public void setIf(Object ifCond) {
+ this.ifCond = ifCond;
+ }
+
+ /**
+ * Set whether this formatter should be used. It will be used if
+ * the expression evaluates to true or the name of a property
+ * which has been set, otherwise it won't.
+ * @param ifCond name of property
+ */
+ public void setIf(String ifCond) {
+ setIf((Object) ifCond);
+ }
+
+ /**
+ * Set whether this formatter should NOT be used. It will be used
+ * if the expression evaluates to false or the name of a property
+ * which has not been set, orthwise it will not be used.
+ * @param unlessCond name of property
+ * @since Ant 1.8.0
+ */
+ public void setUnless(Object unlessCond) {
+ this.unlessCond = unlessCond;
+ }
+
+ /**
+ * Set whether this formatter should NOT be used. It will be used
+ * if the expression evaluates to false or the name of a property
+ * which has not been set, orthwise it will not be used.
+ * @param unlessCond name of property
+ */
+ public void setUnless(String unlessCond) {
+ setUnless((Object) unlessCond);
+ }
+
+ /**
+ * Ensures that the selector passes the conditions placed
+ * on it with <code>if</code> and <code>unless</code> properties.
+ * @param t the task the this formatter is used in.
+ * @return true if the formatter should be used.
+ */
+ public boolean shouldUse(Task t) {
+ PropertyHelper ph = PropertyHelper.getPropertyHelper(t.getProject());
+ return ph.testIfCondition(ifCond)
+ && ph.testUnlessCondition(unlessCond);
+ }
+
+ /**
+ * @since Ant 1.2
+ */
+ JUnitTaskMirror.JUnitResultFormatterMirror createFormatter() throws BuildException {
+ return createFormatter(null);
+ }
+
+ /**
+ * Store the project reference for passing it to nested components.
+ * @param project the reference
+ * @since Ant 1.8
+ */
+ public void setProject(Project project) {
+ this.project = project;
+ }
+
+
+ /**
+ * @since Ant 1.6
+ */
+ JUnitTaskMirror.JUnitResultFormatterMirror createFormatter(ClassLoader loader)
+ throws BuildException {
+
+ if (classname == null) {
+ throw new BuildException("you must specify type or classname");
+ }
+ //although this code appears to duplicate that of ClasspathUtils.newInstance,
+ //we cannot use that because this formatter may run in a forked process,
+ //without that class.
+ Class f = null;
+ try {
+ if (loader == null) {
+ f = Class.forName(classname);
+ } else {
+ f = Class.forName(classname, true, loader);
+ }
+ } catch (ClassNotFoundException e) {
+ throw new BuildException(
+ "Using loader " + loader + " on class " + classname
+ + ": " + e, e);
+ } catch (NoClassDefFoundError e) {
+ throw new BuildException(
+ "Using loader " + loader + " on class " + classname
+ + ": " + e, e);
+ }
+
+ Object o = null;
+ try {
+ o = f.newInstance();
+ } catch (InstantiationException e) {
+ throw new BuildException(e);
+ } catch (IllegalAccessException e) {
+ throw new BuildException(e);
+ }
+
+ if (!(o instanceof JUnitTaskMirror.JUnitResultFormatterMirror)) {
+ throw new BuildException(classname + " is not a JUnitResultFormatter");
+ }
+ JUnitTaskMirror.JUnitResultFormatterMirror r =
+ (JUnitTaskMirror.JUnitResultFormatterMirror) o;
+ if (useFile && outFile != null) {
+ out = new DelayedFileOutputStream(outFile);
+ }
+ r.setOutput(out);
+
+
+ boolean needToSetProjectReference = true;
+ try {
+ Field field = r.getClass().getField("project");
+ Object value = field.get(r);
+ if (value instanceof Project) {
+ // there is already a project reference so dont overwrite this
+ needToSetProjectReference = false;
+ }
+ } catch (NoSuchFieldException e) {
+ // no field present, so no previous reference exists
+ } catch (IllegalAccessException e) {
+ throw new BuildException(e);
+ }
+
+ if (needToSetProjectReference) {
+ Method setter;
+ try {
+ setter = r.getClass().getMethod("setProject", new Class[] {Project.class});
+ setter.invoke(r, new Object[] {project});
+ } catch (NoSuchMethodException e) {
+ // no setProject to invoke; just ignore
+ } catch (IllegalAccessException e) {
+ throw new BuildException(e);
+ } catch (InvocationTargetException e) {
+ throw new BuildException(e);
+ }
+ }
+
+ return r;
+ }
+
+ /**
+ * <p> Enumerated attribute with the values "plain", "xml", "brief" and "failure".
+ *
+ * <p> Use to enumerate options for <code>type</code> attribute.
+ */
+ public static class TypeAttribute extends EnumeratedAttribute {
+ /** {@inheritDoc}. */
+ public String[] getValues() {
+ return new String[] {"plain", "xml", "brief", "failure"};
+ }
+ }
+
+ /**
+ * A standard FileOutputStream creates a file as soon as it's opened. This
+ * class delays the creation of the file until the first time a caller attempts
+ * to write to it so we don't end up with empty files if the listeners don't use
+ * them.
+ */
+ private static class DelayedFileOutputStream extends OutputStream {
+
+ private BufferedOutputStream outputStream;
+ private final File file;
+
+ public DelayedFileOutputStream(File file) {
+ this.file = file;
+ }
+
+ @Override
+ public void write(int b) throws IOException {
+ synchronized (this) {
+ if (outputStream == null) {
+ outputStream = new BufferedOutputStream(new FileOutputStream(file));
+ }
+ }
+ outputStream.write(b);
+ }
+
+ @Override
+ public void flush() throws IOException {
+ if (outputStream != null) {
+ outputStream.flush();
+ }
+ }
+
+ @Override
+ public void close() throws IOException {
+ if (outputStream != null) {
+ outputStream.close();
+ }
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/IgnoredTestListener.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/IgnoredTestListener.java
new file mode 100644
index 00000000..6741912e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/IgnoredTestListener.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.junit;
+
+import junit.framework.Test;
+import junit.framework.TestListener;
+
+/**
+ * Provides the functionality for TestListeners to be able to be notified of
+ * the necessary JUnit4 events for test being ignored (@Ignore annotation)
+ * or skipped (Assume failures). Tests written in JUnit4 will report against
+ * the methods in this interface alongside the methods in the existing TestListener
+ */
+public interface IgnoredTestListener extends TestListener {
+
+ /**
+ * Reports when a test has been marked with the @Ignore annotation. The parameter
+ * should normally be typed to JUnit's {@link junit.framework.JUnit4TestCaseFacade}
+ * so implementing classes should be able to get the details of the ignore by casting
+ * the argument and retrieving the descriptor from the test.
+ * @param test the details of the test and failure that have triggered this report.
+ */
+ void testIgnored(Test test);
+
+ /**
+ * Receive a report that a test has failed an assumption. Within JUnit4
+ * this is normally treated as a test being skipped, although how any
+ * listener handles this is up to that specific listener.<br />
+ * <b>Note:</b> Tests that throw assumption failures will still report
+ * the endTest method, which may differ from how the addError and addFailure
+ * methods work, it's up for any implementing classes to handle this.
+ * @param test the details of the test and failure that have triggered this report.
+ * @param exception the AssumptionViolatedException thrown from the current assumption failure.
+ */
+ void testAssumptionFailure(Test test, Throwable exception);
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/IgnoredTestResult.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/IgnoredTestResult.java
new file mode 100644
index 00000000..c3bb18da
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/IgnoredTestResult.java
@@ -0,0 +1,99 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.junit;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import junit.framework.Test;
+import junit.framework.TestListener;
+import junit.framework.TestResult;
+
+/**
+ * Records ignored and skipped tests reported as part of the execution of
+ * JUnit 4 tests.
+ *
+ */
+public class IgnoredTestResult extends TestResult {
+
+
+ private List<IgnoredTestListener> listeners = new ArrayList<IgnoredTestListener>();
+ private List<TestIgnored> ignored = new ArrayList<TestIgnored>();
+ private List<TestIgnored> skipped = new ArrayList<TestIgnored>();
+
+ public IgnoredTestResult() {
+ super();
+ }
+
+
+ public synchronized void addListener(TestListener listener) {
+ if (listener instanceof IgnoredTestListener) {
+ listeners.add((IgnoredTestListener)listener);
+ }
+ super.addListener(listener);
+ }
+
+ public synchronized void removeListener(TestListener listener) {
+ if (listener instanceof IgnoredTestListener) {
+ listeners.remove(listener);
+ }
+ super.removeListener(listener);
+ }
+
+ /**
+ * Record a test as having been ignored, normally by the @Ignore annotation.
+ * @param test the test that was ignored.
+ * @throws Exception is the listener thrown an exception on handling the notification.
+ */
+ public synchronized void testIgnored(Test test) throws Exception {
+ ignored.add(new TestIgnored(test));
+ for (IgnoredTestListener listener : listeners) {
+ listener.testIgnored(test);
+ }
+ }
+
+ /**
+ * Report how many tests were ignored.
+ * @return the number of tests reported as ignored during the current execution.
+ */
+ public long ignoredCount() {
+ return ignored.size();
+ }
+
+ /**
+ * Records a test as having an assumption failure so JUnit will no longer be executing it.
+ * Under normal circumstances this would be counted as a skipped test.
+ * @param test the test to record
+ * @param cause the details of the test and assumption failure.
+ */
+ public void testAssumptionFailure(Test test, Throwable cause) {
+ skipped.add(new TestIgnored(test));
+ for (IgnoredTestListener listener : listeners) {
+ listener.testAssumptionFailure(test, cause);
+ }
+ }
+
+ /**
+ * Report how many tests has assumption failures.
+ * @return the number of tests that reported assumption failures during the current execution.
+ */
+ public long skippedCount() {
+ return skipped.size();
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnit4TestMethodAdapter.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnit4TestMethodAdapter.java
new file mode 100644
index 00000000..f03a409b
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnit4TestMethodAdapter.java
@@ -0,0 +1,193 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.junit;
+
+import java.util.Iterator;
+import java.util.List;
+
+import junit.framework.Test;
+import junit.framework.TestResult;
+
+import org.junit.runner.Description;
+import org.junit.runner.Request;
+import org.junit.runner.Runner;
+import org.junit.runner.manipulation.Filter;
+
+/**
+ * Adapter between JUnit 3.8.x API and JUnit 4.x API for execution of tests
+ * and listening of events (test start, test finish, test failure, test skipped).
+ * The constructor is passed a JUnit 4 test class and a list of name of methods
+ * in it that should be executed. Method {@link #run run(TestResult)} executes
+ * the given JUnit-4-style test methods and notifies the given {@code TestResult}
+ * object using its old (JUnit 3.8.x style) API.
+ *
+ * @author Marian Petras
+ */
+public class JUnit4TestMethodAdapter implements Test {
+
+ private final Class testClass;
+ private final String[] methodNames;
+ private final Runner runner;
+ private final CustomJUnit4TestAdapterCache cache;
+
+ /**
+ * Creates a new adapter for the given class and a method within the class.
+ *
+ * @param testClass test class containing the method to be executed
+ * @param methodNames names of the test methods that are to be executed
+ * @exception java.lang.IllegalArgumentException
+ * if any of the arguments is {@code null}
+ * or if any of the given method names is {@code null} or empty
+ */
+ public JUnit4TestMethodAdapter(final Class testClass,
+ final String[] methodNames) {
+ if (testClass == null) {
+ throw new IllegalArgumentException("testClass is <null>");
+ }
+ if (methodNames == null) {
+ throw new IllegalArgumentException("methodNames is <null>");
+ }
+ for (int i = 0; i < methodNames.length; i++) {
+ if (methodNames[i] == null) {
+ throw new IllegalArgumentException("method name #" + i + " is <null>");
+ }
+ if (methodNames[i].length() == 0) {
+ throw new IllegalArgumentException("method name #" + i + " is empty");
+ }
+ }
+ this.testClass = testClass;
+ this.methodNames = methodNames.clone();
+ this.cache = CustomJUnit4TestAdapterCache.getInstance();
+
+ // Warning: If 'testClass' is an old-style (pre-JUnit-4) class,
+ // then all its test methods will be executed by the returned runner!
+ Request request;
+ if (methodNames.length == 1) {
+ request = Request.method(testClass, methodNames[0]);
+ } else {
+ request = Request.aClass(testClass).filterWith(
+ new MultipleMethodsFilter(testClass, methodNames));
+ }
+ runner = request.getRunner();
+ }
+
+ public int countTestCases() {
+ return runner.testCount();
+ }
+
+ public Description getDescription() {
+ return runner.getDescription();
+ }
+
+ public List/*<Test>*/ getTests() {
+ return cache.asTestList(getDescription());
+ }
+
+ public Class getTestClass() {
+ return testClass;
+ }
+
+ public void run(final TestResult result) {
+ runner.run(cache.getNotifier(result));
+ }
+
+ @Override
+ public String toString() {
+ String testClassName = testClass.getName();
+ StringBuilder buf = new StringBuilder(testClassName.length()
+ + 12 * methodNames.length)
+ .append(':');
+ if (methodNames.length != 0) {
+ buf.append(methodNames[0]);
+ for (int i = 1; i < methodNames.length; i++) {
+ buf.append(',')
+ .append(methodNames[i]);
+ }
+ }
+ return buf.toString();
+ }
+
+ private static final class MultipleMethodsFilter extends Filter {
+
+ private final Description methodsListDescription;
+ private final Class testClass;
+ private final String[] methodNames;
+
+ private MultipleMethodsFilter(Class testClass, String[] methodNames) {
+ if (testClass == null) {
+ throw new IllegalArgumentException("testClass is <null>");
+ }
+ if (methodNames == null) {
+ throw new IllegalArgumentException("methodNames is <null>");
+ }
+ methodsListDescription = Description.createSuiteDescription(testClass);
+ for (int i = 0; i < methodNames.length; i++) {
+ methodsListDescription.addChild(
+ Description.createTestDescription(testClass, methodNames[i]));
+ }
+ this.testClass = testClass;
+ this.methodNames = methodNames;
+ }
+
+ @Override
+ public boolean shouldRun(Description description) {
+ if (methodNames.length == 0) {
+ return false;
+ }
+ if (description.isTest()) {
+ Iterator/*<Description>*/ it = methodsListDescription.getChildren().iterator();
+ while (it.hasNext()) {
+ Description methodDescription = (Description) it.next();
+ if (methodDescription.equals(description)) {
+ return true;
+ }
+ }
+ } else {
+ Iterator/*<Description>*/ it = description.getChildren().iterator();
+ while (it.hasNext()) {
+ Description each = (Description) it.next();
+ if (shouldRun(each)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public String describe() {
+ StringBuilder buf = new StringBuilder(40);
+ if (methodNames.length == 0) {
+ buf.append("No methods");
+ } else {
+ buf.append(methodNames.length == 1 ? "Method" : "Methods");
+ buf.append(' ');
+ buf.append(methodNames[0]);
+ for (int i = 1; i < methodNames.length; i++) {
+ buf.append(',').append(methodNames[i]);
+ }
+ }
+ buf.append('(').append(testClass.getName()).append(')');
+ return buf.toString();
+ }
+
+ }
+
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitResultFormatter.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitResultFormatter.java
new file mode 100644
index 00000000..2119fc94
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitResultFormatter.java
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.junit;
+
+import java.io.OutputStream;
+
+import junit.framework.TestListener;
+
+import org.apache.tools.ant.BuildException;
+
+/**
+ * This Interface describes classes that format the results of a JUnit
+ * testrun.
+ *
+ */
+public interface JUnitResultFormatter
+ extends TestListener, JUnitTaskMirror.JUnitResultFormatterMirror {
+ /**
+ * The whole testsuite started.
+ * @param suite the suite.
+ * @throws BuildException on error.
+ */
+ void startTestSuite(JUnitTest suite) throws BuildException;
+
+ /**
+ * The whole testsuite ended.
+ * @param suite the suite.
+ * @throws BuildException on error.
+ */
+ void endTestSuite(JUnitTest suite) throws BuildException;
+
+ /**
+ * Sets the stream the formatter is supposed to write its results to.
+ * @param out the output stream to use.
+ */
+ void setOutput(OutputStream out);
+
+ /**
+ * This is what the test has written to System.out
+ * @param out the string to write.
+ */
+ void setSystemOutput(String out);
+
+ /**
+ * This is what the test has written to System.err
+ * @param err the string to write.
+ */
+ void setSystemError(String err);
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTask.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTask.java
new file mode 100644
index 00000000..459bd3d5
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTask.java
@@ -0,0 +1,2283 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.junit;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.lang.reflect.Constructor;
+import java.net.URL;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Vector;
+
+import org.apache.tools.ant.AntClassLoader;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.taskdefs.Execute;
+import org.apache.tools.ant.taskdefs.ExecuteWatchdog;
+import org.apache.tools.ant.taskdefs.LogOutputStream;
+import org.apache.tools.ant.taskdefs.PumpStreamHandler;
+import org.apache.tools.ant.types.Assertions;
+import org.apache.tools.ant.types.Commandline;
+import org.apache.tools.ant.types.CommandlineJava;
+import org.apache.tools.ant.types.EnumeratedAttribute;
+import org.apache.tools.ant.types.Environment;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.types.Permissions;
+import org.apache.tools.ant.types.PropertySet;
+import org.apache.tools.ant.util.FileUtils;
+import org.apache.tools.ant.util.LoaderUtils;
+import org.apache.tools.ant.util.SplitClassLoader;
+
+/**
+ * Runs JUnit tests.
+ *
+ * <p> JUnit is a framework to create unit tests. It has been initially
+ * created by Erich Gamma and Kent Beck. JUnit can be found at <a
+ * href="http://www.junit.org">http://www.junit.org</a>.
+ *
+ * <p> <code>JUnitTask</code> can run a single specific
+ * <code>JUnitTest</code> using the <code>test</code> element.</p>
+ * For example, the following target <code><pre>
+ * &lt;target name="test-int-chars" depends="jar-test"&gt;
+ * &lt;echo message="testing international characters"/&gt;
+ * &lt;junit printsummary="no" haltonfailure="yes" fork="false"&gt;
+ * &lt;classpath refid="classpath"/&gt;
+ * &lt;formatter type="plain" usefile="false" /&gt;
+ * &lt;test name="org.apache.ecs.InternationalCharTest" /&gt;
+ * &lt;/junit&gt;
+ * &lt;/target&gt;
+ * </pre></code>
+ * <p>runs a single junit test
+ * (<code>org.apache.ecs.InternationalCharTest</code>) in the current
+ * VM using the path with id <code>classpath</code> as classpath and
+ * presents the results formatted using the standard
+ * <code>plain</code> formatter on the command line.</p>
+ *
+ * <p> This task can also run batches of tests. The
+ * <code>batchtest</code> element creates a <code>BatchTest</code>
+ * based on a fileset. This allows, for example, all classes found in
+ * directory to be run as testcases.</p>
+ *
+ * <p>For example,</p><code><pre>
+ * &lt;target name="run-tests" depends="dump-info,compile-tests" if="junit.present"&gt;
+ * &lt;junit printsummary="no" haltonfailure="yes" fork="${junit.fork}"&gt;
+ * &lt;jvmarg value="-classic"/&gt;
+ * &lt;classpath refid="tests-classpath"/&gt;
+ * &lt;sysproperty key="build.tests" value="${build.tests}"/&gt;
+ * &lt;formatter type="brief" usefile="false" /&gt;
+ * &lt;batchtest&gt;
+ * &lt;fileset dir="${tests.dir}"&gt;
+ * &lt;include name="**&#047;*Test*" /&gt;
+ * &lt;/fileset&gt;
+ * &lt;/batchtest&gt;
+ * &lt;/junit&gt;
+ * &lt;/target&gt;
+ * </pre></code>
+ * <p>this target finds any classes with a <code>test</code> directory
+ * anywhere in their path (under the top <code>${tests.dir}</code>, of
+ * course) and creates <code>JUnitTest</code>'s for each one.</p>
+ *
+ * <p> Of course, <code>&lt;junit&gt;</code> and
+ * <code>&lt;batch&gt;</code> elements can be combined for more
+ * complex tests. For an example, see the ant <code>build.xml</code>
+ * target <code>run-tests</code> (the second example is an edited
+ * version).</p>
+ *
+ * <p> To spawn a new Java VM to prevent interferences between
+ * different testcases, you need to enable <code>fork</code>. A
+ * number of attributes and elements allow you to set up how this JVM
+ * runs.
+ *
+ *
+ * @since Ant 1.2
+ *
+ * @see JUnitTest
+ * @see BatchTest
+ */
+public class JUnitTask extends Task {
+
+ private static final String LINE_SEP
+ = System.getProperty("line.separator");
+ private static final String CLASSPATH = "CLASSPATH";
+ private CommandlineJava commandline;
+ private final Vector<JUnitTest> tests = new Vector<JUnitTest>();
+ private final Vector<BatchTest> batchTests = new Vector<BatchTest>();
+ private final Vector<FormatterElement> formatters = new Vector<FormatterElement>();
+ private File dir = null;
+
+ private Integer timeout = null;
+ private boolean summary = false;
+ private boolean reloading = true;
+ private String summaryValue = "";
+ private JUnitTaskMirror.JUnitTestRunnerMirror runner = null;
+
+ private boolean newEnvironment = false;
+ private final Environment env = new Environment();
+
+ private boolean includeAntRuntime = true;
+ private Path antRuntimeClasses = null;
+
+ // Do we send output to System.out/.err in addition to the formatters?
+ private boolean showOutput = false;
+
+ // Do we send output to the formatters ?
+ private boolean outputToFormatters = true;
+
+ private boolean logFailedTests = true;
+
+ private File tmpDir;
+ private AntClassLoader classLoader = null;
+ private Permissions perm = null;
+ private ForkMode forkMode = new ForkMode("perTest");
+
+ private boolean splitJUnit = false;
+ private boolean enableTestListenerEvents = false;
+ private JUnitTaskMirror delegate;
+ private ClassLoader mirrorLoader;
+
+ /** A boolean on whether to get the forked path for ant classes */
+ private boolean forkedPathChecked = false;
+
+ /* set when a test fails/errs with haltonfailure/haltonerror and >1 thread to stop other threads */
+ private volatile BuildException caughtBuildException = null;
+
+ // Attributes for basetest
+ private boolean haltOnError = false;
+ private boolean haltOnFail = false;
+ private boolean filterTrace = true;
+ private boolean fork = false;
+ private int threads = 1;
+ private String failureProperty;
+ private String errorProperty;
+
+ private static final int STRING_BUFFER_SIZE = 128;
+ /**
+ * @since Ant 1.7
+ */
+ public static final String TESTLISTENER_PREFIX =
+ "junit.framework.TestListener: ";
+
+ /**
+ * Name of magic property that enables test listener events.
+ */
+ public static final String ENABLE_TESTLISTENER_EVENTS =
+ "ant.junit.enabletestlistenerevents";
+
+ private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+
+ /**
+ * If true, force ant to re-classload all classes for each JUnit TestCase
+ *
+ * @param value force class reloading for each test case
+ */
+ public void setReloading(final boolean value) {
+ reloading = value;
+ }
+
+ /**
+ * If true, smartly filter the stack frames of
+ * JUnit errors and failures before reporting them.
+ *
+ * <p>This property is applied on all BatchTest (batchtest) and
+ * JUnitTest (test) however it can possibly be overridden by their
+ * own properties.</p>
+ * @param value <tt>false</tt> if it should not filter, otherwise
+ * <tt>true<tt>
+ *
+ * @since Ant 1.5
+ */
+ public void setFiltertrace(final boolean value) {
+ this.filterTrace = value;
+ }
+
+ /**
+ * If true, stop the build process when there is an error in a test.
+ * This property is applied on all BatchTest (batchtest) and JUnitTest
+ * (test) however it can possibly be overridden by their own
+ * properties.
+ * @param value <tt>true</tt> if it should halt, otherwise
+ * <tt>false</tt>
+ *
+ * @since Ant 1.2
+ */
+ public void setHaltonerror(final boolean value) {
+ this.haltOnError = value;
+ }
+
+ /**
+ * Property to set to "true" if there is a error in a test.
+ *
+ * <p>This property is applied on all BatchTest (batchtest) and
+ * JUnitTest (test), however, it can possibly be overridden by
+ * their own properties.</p>
+ * @param propertyName the name of the property to set in the
+ * event of an error.
+ *
+ * @since Ant 1.4
+ */
+ public void setErrorProperty(final String propertyName) {
+ this.errorProperty = propertyName;
+ }
+
+ /**
+ * If true, stop the build process if a test fails
+ * (errors are considered failures as well).
+ * This property is applied on all BatchTest (batchtest) and
+ * JUnitTest (test) however it can possibly be overridden by their
+ * own properties.
+ * @param value <tt>true</tt> if it should halt, otherwise
+ * <tt>false</tt>
+ *
+ * @since Ant 1.2
+ */
+ public void setHaltonfailure(final boolean value) {
+ this.haltOnFail = value;
+ }
+
+ /**
+ * Property to set to "true" if there is a failure in a test.
+ *
+ * <p>This property is applied on all BatchTest (batchtest) and
+ * JUnitTest (test), however, it can possibly be overridden by
+ * their own properties.</p>
+ * @param propertyName the name of the property to set in the
+ * event of an failure.
+ *
+ * @since Ant 1.4
+ */
+ public void setFailureProperty(final String propertyName) {
+ this.failureProperty = propertyName;
+ }
+
+ /**
+ * If true, JVM should be forked for each test.
+ *
+ * <p>It avoids interference between testcases and possibly avoids
+ * hanging the build. this property is applied on all BatchTest
+ * (batchtest) and JUnitTest (test) however it can possibly be
+ * overridden by their own properties.</p>
+ * @param value <tt>true</tt> if a JVM should be forked, otherwise
+ * <tt>false</tt>
+ * @see #setTimeout
+ *
+ * @since Ant 1.2
+ */
+ public void setFork(final boolean value) {
+ this.fork = value;
+ }
+
+ /**
+ * Set the behavior when {@link #setFork fork} fork has been enabled.
+ *
+ * <p>Possible values are "once", "perTest" and "perBatch". If
+ * set to "once", only a single Java VM will be forked for all
+ * tests, with "perTest" (the default) each test will run in a
+ * fresh Java VM and "perBatch" will run all tests from the same
+ * &lt;batchtest&gt; in the same Java VM.</p>
+ *
+ * <p>This attribute will be ignored if tests run in the same VM
+ * as Ant.</p>
+ *
+ * <p>Only tests with the same configuration of haltonerror,
+ * haltonfailure, errorproperty, failureproperty and filtertrace
+ * can share a forked Java VM, so even if you set the value to
+ * "once", Ant may need to fork multiple VMs.</p>
+ * @param mode the mode to use.
+ * @since Ant 1.6.2
+ */
+ public void setForkMode(final ForkMode mode) {
+ this.forkMode = mode;
+ }
+
+ /**
+ * Set the number of test threads to be used for parallel test
+ * execution. The default is 1, which is the same behavior as
+ * before parallel test execution was possible.
+ *
+ * <p>This attribute will be ignored if tests run in the same VM
+ * as Ant.</p>
+ *
+ * @since Ant 1.9.4
+ */
+ public void setThreads(final int threads) {
+ if (threads >= 0) {
+ this.threads = threads;
+ }
+ }
+
+ /**
+ * If true, print one-line statistics for each test, or "withOutAndErr"
+ * to also show standard output and error.
+ *
+ * Can take the values on, off, and withOutAndErr.
+ * @param value <tt>true</tt> to print a summary,
+ * <tt>withOutAndErr</tt> to include the test&apos;s output as
+ * well, <tt>false</tt> otherwise.
+ * @see SummaryJUnitResultFormatter
+ *
+ * @since Ant 1.2
+ */
+ public void setPrintsummary(final SummaryAttribute value) {
+ summaryValue = value.getValue();
+ summary = value.asBoolean();
+ }
+
+ /**
+ * Print summary enumeration values.
+ */
+ public static class SummaryAttribute extends EnumeratedAttribute {
+ /**
+ * list the possible values
+ * @return array of allowed values
+ */
+ @Override
+ public String[] getValues() {
+ return new String[] {"true", "yes", "false", "no",
+ "on", "off", "withOutAndErr"};
+ }
+
+ /**
+ * gives the boolean equivalent of the authorized values
+ * @return boolean equivalent of the value
+ */
+ public boolean asBoolean() {
+ final String v = getValue();
+ return "true".equals(v)
+ || "on".equals(v)
+ || "yes".equals(v)
+ || "withOutAndErr".equals(v);
+ }
+ }
+
+ /**
+ * Set the timeout value (in milliseconds).
+ *
+ * <p>If the test is running for more than this value, the test
+ * will be canceled. (works only when in 'fork' mode).</p>
+ * @param value the maximum time (in milliseconds) allowed before
+ * declaring the test as 'timed-out'
+ * @see #setFork(boolean)
+ *
+ * @since Ant 1.2
+ */
+ public void setTimeout(final Integer value) {
+ timeout = value;
+ }
+
+ /**
+ * Set the maximum memory to be used by all forked JVMs.
+ * @param max the value as defined by <tt>-mx</tt> or <tt>-Xmx</tt>
+ * in the java command line options.
+ *
+ * @since Ant 1.2
+ */
+ public void setMaxmemory(final String max) {
+ getCommandline().setMaxmemory(max);
+ }
+
+ /**
+ * The command used to invoke the Java Virtual Machine,
+ * default is 'java'. The command is resolved by
+ * java.lang.Runtime.exec(). Ignored if fork is disabled.
+ *
+ * @param value the new VM to use instead of <tt>java</tt>
+ * @see #setFork(boolean)
+ *
+ * @since Ant 1.2
+ */
+ public void setJvm(final String value) {
+ getCommandline().setVm(value);
+ }
+
+ /**
+ * Adds a JVM argument; ignored if not forking.
+ *
+ * @return create a new JVM argument so that any argument can be
+ * passed to the JVM.
+ * @see #setFork(boolean)
+ *
+ * @since Ant 1.2
+ */
+ public Commandline.Argument createJvmarg() {
+ return getCommandline().createVmArgument();
+ }
+
+ /**
+ * The directory to invoke the VM in. Ignored if no JVM is forked.
+ * @param dir the directory to invoke the JVM from.
+ * @see #setFork(boolean)
+ *
+ * @since Ant 1.2
+ */
+ public void setDir(final File dir) {
+ this.dir = dir;
+ }
+
+ /**
+ * Adds a system property that tests can access.
+ * This might be useful to transfer Ant properties to the
+ * testcases when JVM forking is not enabled.
+ *
+ * @since Ant 1.3
+ * @deprecated since ant 1.6
+ * @param sysp environment variable to add
+ */
+ @Deprecated
+ public void addSysproperty(final Environment.Variable sysp) {
+
+ getCommandline().addSysproperty(sysp);
+ }
+
+ /**
+ * Adds a system property that tests can access.
+ * This might be useful to transfer Ant properties to the
+ * testcases when JVM forking is not enabled.
+ * @param sysp new environment variable to add
+ * @since Ant 1.6
+ */
+ public void addConfiguredSysproperty(final Environment.Variable sysp) {
+ // get a build exception if there is a missing key or value
+ // see bugzilla report 21684
+ final String testString = sysp.getContent();
+ getProject().log("sysproperty added : " + testString, Project.MSG_DEBUG);
+ getCommandline().addSysproperty(sysp);
+ }
+
+ /**
+ * Adds a set of properties that will be used as system properties
+ * that tests can access.
+ *
+ * This might be useful to transfer Ant properties to the
+ * testcases when JVM forking is not enabled.
+ *
+ * @param sysp set of properties to be added
+ * @since Ant 1.6
+ */
+ public void addSyspropertyset(final PropertySet sysp) {
+ getCommandline().addSyspropertyset(sysp);
+ }
+
+ /**
+ * Adds path to classpath used for tests.
+ *
+ * @return reference to the classpath in the embedded java command line
+ * @since Ant 1.2
+ */
+ public Path createClasspath() {
+ return getCommandline().createClasspath(getProject()).createPath();
+ }
+
+ /**
+ * Adds a path to the bootclasspath.
+ * @return reference to the bootclasspath in the embedded java command line
+ * @since Ant 1.6
+ */
+ public Path createBootclasspath() {
+ return getCommandline().createBootclasspath(getProject()).createPath();
+ }
+
+ /**
+ * Adds an environment variable; used when forking.
+ *
+ * <p>Will be ignored if we are not forking a new VM.</p>
+ * @param var environment variable to be added
+ * @since Ant 1.5
+ */
+ public void addEnv(final Environment.Variable var) {
+ env.addVariable(var);
+ }
+
+ /**
+ * If true, use a new environment when forked.
+ *
+ * <p>Will be ignored if we are not forking a new VM.</p>
+ *
+ * @param newenv boolean indicating if setting a new environment is wished
+ * @since Ant 1.5
+ */
+ public void setNewenvironment(final boolean newenv) {
+ newEnvironment = newenv;
+ }
+
+ /**
+ * Preset the attributes of the test
+ * before configuration in the build
+ * script.
+ * This allows attributes in the <junit> task
+ * be be defaults for the tests, but allows
+ * individual tests to override the defaults.
+ */
+ private void preConfigure(final BaseTest test) {
+ test.setFiltertrace(filterTrace);
+ test.setHaltonerror(haltOnError);
+ if (errorProperty != null) {
+ test.setErrorProperty(errorProperty);
+ }
+ test.setHaltonfailure(haltOnFail);
+ if (failureProperty != null) {
+ test.setFailureProperty(failureProperty);
+ }
+ test.setFork(fork);
+ }
+
+ /**
+ * Add a new single testcase.
+ * @param test a new single testcase
+ * @see JUnitTest
+ *
+ * @since Ant 1.2
+ */
+ public void addTest(final JUnitTest test) {
+ tests.addElement(test);
+ preConfigure(test);
+ }
+
+ /**
+ * Adds a set of tests based on pattern matching.
+ *
+ * @return a new instance of a batch test.
+ * @see BatchTest
+ *
+ * @since Ant 1.2
+ */
+ public BatchTest createBatchTest() {
+ final BatchTest test = new BatchTest(getProject());
+ batchTests.addElement(test);
+ preConfigure(test);
+ return test;
+ }
+
+ /**
+ * Add a new formatter to all tests of this task.
+ *
+ * @param fe formatter element
+ * @since Ant 1.2
+ */
+ public void addFormatter(final FormatterElement fe) {
+ formatters.addElement(fe);
+ }
+
+ /**
+ * If true, include ant.jar, optional.jar and junit.jar in the forked VM.
+ *
+ * @param b include ant run time yes or no
+ * @since Ant 1.5
+ */
+ public void setIncludeantruntime(final boolean b) {
+ includeAntRuntime = b;
+ }
+
+ /**
+ * If true, send any output generated by tests to Ant's logging system
+ * as well as to the formatters.
+ * By default only the formatters receive the output.
+ *
+ * <p>Output will always be passed to the formatters and not by
+ * shown by default. This option should for example be set for
+ * tests that are interactive and prompt the user to do
+ * something.</p>
+ *
+ * @param showOutput if true, send output to Ant's logging system too
+ * @since Ant 1.5
+ */
+ public void setShowOutput(final boolean showOutput) {
+ this.showOutput = showOutput;
+ }
+
+ /**
+ * If true, send any output generated by tests to the formatters.
+ *
+ * @param outputToFormatters if true, send output to formatters (Default
+ * is true).
+ * @since Ant 1.7.0
+ */
+ public void setOutputToFormatters(final boolean outputToFormatters) {
+ this.outputToFormatters = outputToFormatters;
+ }
+
+ /**
+ * If true, write a single "FAILED" line for failed tests to Ant's
+ * log system.
+ *
+ * @since Ant 1.8.0
+ */
+ public void setLogFailedTests(final boolean logFailedTests) {
+ this.logFailedTests = logFailedTests;
+ }
+
+ /**
+ * Assertions to enable in this program (if fork=true)
+ * @since Ant 1.6
+ * @param asserts assertion set
+ */
+ public void addAssertions(final Assertions asserts) {
+ if (getCommandline().getAssertions() != null) {
+ throw new BuildException("Only one assertion declaration is allowed");
+ }
+ getCommandline().setAssertions(asserts);
+ }
+
+ /**
+ * Sets the permissions for the application run inside the same JVM.
+ * @since Ant 1.6
+ * @return .
+ */
+ public Permissions createPermissions() {
+ if (perm == null) {
+ perm = new Permissions();
+ }
+ return perm;
+ }
+
+ /**
+ * If set, system properties will be copied to the cloned VM - as
+ * well as the bootclasspath unless you have explicitly specified
+ * a bootclasspath.
+ *
+ * <p>Doesn't have any effect unless fork is true.</p>
+ * @param cloneVm a <code>boolean</code> value.
+ * @since Ant 1.7
+ */
+ public void setCloneVm(final boolean cloneVm) {
+ getCommandline().setCloneVm(cloneVm);
+ }
+
+ /**
+ * Creates a new JUnitRunner and enables fork of a new Java VM.
+ *
+ * @throws Exception under ??? circumstances
+ * @since Ant 1.2
+ */
+ public JUnitTask() throws Exception {
+ }
+
+ /**
+ * Where Ant should place temporary files.
+ *
+ * @param tmpDir location where temporary files should go to
+ * @since Ant 1.6
+ */
+ public void setTempdir(final File tmpDir) {
+ if (tmpDir != null) {
+ if (!tmpDir.exists() || !tmpDir.isDirectory()) {
+ throw new BuildException(tmpDir.toString()
+ + " is not a valid temp directory");
+ }
+ }
+ this.tmpDir = tmpDir;
+ }
+
+ /**
+ * Whether test listener events shall be generated.
+ *
+ * <p>Defaults to false.</p>
+ *
+ * <p>This value will be overridden by the magic property
+ * ant.junit.enabletestlistenerevents if it has been set.</p>
+ *
+ * @since Ant 1.8.2
+ */
+ public void setEnableTestListenerEvents(final boolean b) {
+ enableTestListenerEvents = b;
+ }
+
+ /**
+ * Whether test listener events shall be generated.
+ * @since Ant 1.8.2
+ */
+ public boolean getEnableTestListenerEvents() {
+ final String e = getProject().getProperty(ENABLE_TESTLISTENER_EVENTS);
+ if (e != null) {
+ return Project.toBoolean(e);
+ }
+ return enableTestListenerEvents;
+ }
+
+ /**
+ * Adds the jars or directories containing Ant, this task and
+ * JUnit to the classpath - this should make the forked JVM work
+ * without having to specify them directly.
+ *
+ * @since Ant 1.4
+ */
+ @Override
+ public void init() {
+ antRuntimeClasses = new Path(getProject());
+ splitJUnit = !addClasspathResource("/junit/framework/TestCase.class");
+ addClasspathEntry("/org/apache/tools/ant/launch/AntMain.class");
+ addClasspathEntry("/org/apache/tools/ant/Task.class");
+ addClasspathEntry("/org/apache/tools/ant/taskdefs/optional/junit/JUnitTestRunner.class");
+ addClasspathEntry("/org/apache/tools/ant/taskdefs/optional/junit/JUnit4TestMethodAdapter.class");
+ }
+
+ private static JUnitTaskMirror createMirror(final JUnitTask task, final ClassLoader loader) {
+ try {
+ loader.loadClass("junit.framework.Test"); // sanity check
+ } catch (final ClassNotFoundException e) {
+ throw new BuildException(
+ "The <classpath> for <junit> must include junit.jar "
+ + "if not in Ant's own classpath",
+ e, task.getLocation());
+ }
+ try {
+ final Class c = loader.loadClass(JUnitTaskMirror.class.getName() + "Impl");
+ if (c.getClassLoader() != loader) {
+ throw new BuildException("Overdelegating loader", task.getLocation());
+ }
+ final Constructor cons = c.getConstructor(new Class[] {JUnitTask.class});
+ return (JUnitTaskMirror) cons.newInstance(new Object[] {task});
+ } catch (final Exception e) {
+ throw new BuildException(e, task.getLocation());
+ }
+ }
+
+ /**
+ * Sets up the delegate that will actually run the tests.
+ *
+ * <p>Will be invoked implicitly once the delegate is needed.</p>
+ *
+ * @since Ant 1.7.1
+ */
+ protected void setupJUnitDelegate() {
+ final ClassLoader myLoader = JUnitTask.class.getClassLoader();
+ if (splitJUnit) {
+ final Path path = new Path(getProject());
+ path.add(antRuntimeClasses);
+ final Path extra = getCommandline().getClasspath();
+ if (extra != null) {
+ path.add(extra);
+ }
+ mirrorLoader = (ClassLoader) AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ return new SplitClassLoader(myLoader, path, getProject(),
+ new String[] {
+ "BriefJUnitResultFormatter",
+ "JUnit4TestMethodAdapter",
+ "JUnitResultFormatter",
+ "JUnitTaskMirrorImpl",
+ "JUnitTestRunner",
+ "JUnitVersionHelper",
+ "OutErrSummaryJUnitResultFormatter",
+ "PlainJUnitResultFormatter",
+ "SummaryJUnitResultFormatter",
+ "TearDownOnVmCrash",
+ "XMLJUnitResultFormatter",
+ "IgnoredTestListener",
+ "IgnoredTestResult",
+ "CustomJUnit4TestAdapterCache",
+ "TestListenerWrapper"
+ });
+ }
+ });
+ } else {
+ mirrorLoader = myLoader;
+ }
+ delegate = createMirror(this, mirrorLoader);
+ }
+
+ /**
+ * Runs the testcase.
+ *
+ * @throws BuildException in case of test failures or errors
+ * @since Ant 1.2
+ */
+ @Override
+ public void execute() throws BuildException {
+ checkMethodLists();
+
+ setupJUnitDelegate();
+
+ final List<List> testLists = new ArrayList<List>();
+ /* parallel test execution is only supported for multi-process execution */
+ final int threads = ((!fork) || (forkMode.getValue().equals(ForkMode.ONCE))
+ ? 1
+ : this.threads);
+
+ final boolean forkPerTest = forkMode.getValue().equals(ForkMode.PER_TEST);
+ if (forkPerTest || forkMode.getValue().equals(ForkMode.ONCE)) {
+ testLists.addAll(executeOrQueue(getIndividualTests(),
+ forkPerTest));
+ } else { /* forkMode.getValue().equals(ForkMode.PER_BATCH) */
+ final int count = batchTests.size();
+ for (int i = 0; i < count; i++) {
+ final BatchTest batchtest = batchTests.elementAt(i);
+ testLists.addAll(executeOrQueue(batchtest.elements(), false));
+ }
+ testLists.addAll(executeOrQueue(tests.elements(), forkPerTest));
+ }
+
+ try {
+ /* prior to parallel the code in 'oneJunitThread' used to be here. */
+ runTestsInThreads(testLists, threads);
+ } finally {
+ cleanup();
+ }
+ }
+
+ /*
+ * When the list of tests is established, an array of threads is created to pick the
+ * tests off the list one at a time and execute them until the list is empty. Tests are
+ * not assigned to threads until the thread is available.
+ *
+ * This class is the runnable thread subroutine that takes care of passing the shared
+ * list iterator and the handle back to the main class to the test execution subroutine
+ * code 'runTestsInThreads'. One object is created for each thread and each one gets
+ * a unique thread id that can be useful for tracing test starts and stops.
+ *
+ * Because the threads are picking tests off the same list, it is the list *iterator*
+ * that must be shared, not the list itself - and the iterator must have a thread-safe
+ * ability to pop the list - hence the synchronized 'getNextTest'.
+ */
+ private class JunitTestThread implements Runnable {
+
+ JunitTestThread(final JUnitTask master, final Iterator<List> iterator, final int id) {
+ this.masterTask = master;
+ this.iterator = iterator;
+ this.id = id;
+ }
+
+ public void run() {
+ try {
+ masterTask.oneJunitThread(iterator, id);
+ } catch (final BuildException b) {
+ /* saved to rethrow in main thread to be like single-threaded case */
+ caughtBuildException = b;
+ }
+ }
+
+ private final JUnitTask masterTask;
+ private final Iterator<List> iterator;
+ private final int id;
+ }
+
+ /*
+ * Because the threads are picking tests off the same list, it is the list *iterator*
+ * that must be shared, not the list itself - and the iterator must have a thread-safe
+ * ability to pop the list - hence the synchronized 'getNextTest'. We can't have two
+ * threads get the same test, or two threads simultaneously pop the list so that a test
+ * gets skipped!
+ */
+ private List getNextTest(final Iterator<List> iter) {
+ synchronized(iter) {
+ if (iter.hasNext()) {
+ return iter.next();
+ }
+ return null;
+ }
+ }
+
+ /*
+ * This code loops keeps executing the next test or test bunch (depending on fork mode)
+ * on the list of test cases until none are left. Basically this body of code used to
+ * be in the execute routine above; now, several copies (one for each test thread) execute
+ * simultaneously. The while loop was modified to call the new thread-safe atomic list
+ * popping subroutine and the logging messages were added.
+ *
+ * If one thread aborts due to a BuildException (haltOnError, haltOnFailure, or any other
+ * fatal reason, no new tests/batches will be started but the running threads will be
+ * permitted to complete. Additional tests may start in already-running batch-test threads.
+ */
+ private void oneJunitThread(final Iterator<List> iter, final int threadId) {
+
+ List l;
+ log("Starting test thread " + threadId, Project.MSG_VERBOSE);
+ while ((caughtBuildException == null) && ((l = getNextTest(iter)) != null)) {
+ log("Running test " + l.get(0).toString() + "(" + l.size() + ") in thread " + threadId, Project.MSG_VERBOSE);
+ if (l.size() == 1) {
+ execute((JUnitTest) l.get(0), threadId);
+ } else {
+ execute(l, threadId);
+ }
+ }
+ log("Ending test thread " + threadId, Project.MSG_VERBOSE);
+ }
+
+
+ private void runTestsInThreads(final List<List> testList, final int numThreads) {
+
+ Iterator<List> iter = testList.iterator();
+
+ if (numThreads == 1) {
+ /* with just one thread just run the test - don't create any threads */
+ oneJunitThread(iter, 0);
+ } else {
+ final Thread[] threads = new Thread[numThreads];
+ int i;
+ boolean exceptionOccurred;
+
+ /* Need to split apart tests, which are still grouped in batches */
+ /* is there a simpler Java mechanism to do this? */
+ /* I assume we don't want to do this with "per batch" forking. */
+ List<List> newlist = new ArrayList<List>();
+ if (forkMode.getValue().equals(ForkMode.PER_TEST)) {
+ final Iterator<List> i1 = testList.iterator();
+ while (i1.hasNext()) {
+ final List l = i1.next();
+ if (l.size() == 1) {
+ newlist.add(l);
+ } else {
+ final Iterator i2 = l.iterator();
+ while (i2.hasNext()) {
+ final List tmpSingleton = new ArrayList();
+ tmpSingleton.add(i2.next());
+ newlist.add(tmpSingleton);
+ }
+ }
+ }
+ } else {
+ newlist = testList;
+ }
+ iter = newlist.iterator();
+
+ /* create 1 thread using the passthrough class, and let each thread start */
+ for (i = 0; i < numThreads; i++) {
+ threads[i] = new Thread(new JunitTestThread(this, iter, i+1));
+ threads[i].start();
+ }
+
+ /* wait for all of the threads to complete. Not sure if the exception can actually occur in this use case. */
+ do {
+ exceptionOccurred = false;
+
+ try {
+ for (i = 0; i < numThreads; i++) {
+ threads[i].join();
+ }
+ } catch (final InterruptedException e) {
+ exceptionOccurred = true;
+ }
+ } while (exceptionOccurred);
+
+ /* an exception occurred in one of the threads - usually a haltOnError/Failure.
+ throw the exception again so it behaves like the single-thread case */
+ if (caughtBuildException != null) {
+ throw new BuildException(caughtBuildException);
+ }
+
+ /* all threads are completed - that's all there is to do. */
+ /* control will flow back to the test cleanup call and then execute is done. */
+ }
+ }
+
+ /**
+ * Run the tests.
+ * @param arg one JUnitTest
+ * @param thread Identifies which thread is test running in (0 for single-threaded runs)
+ * @throws BuildException in case of test failures or errors
+ */
+ protected void execute(final JUnitTest arg, final int thread) throws BuildException {
+ validateTestName(arg.getName());
+
+ final JUnitTest test = (JUnitTest) arg.clone();
+ test.setThread(thread);
+
+ // set the default values if not specified
+ //@todo should be moved to the test class instead.
+ if (test.getTodir() == null) {
+ test.setTodir(getProject().resolveFile("."));
+ }
+
+ if (test.getOutfile() == null) {
+ test.setOutfile("TEST-" + test.getName());
+ }
+
+ // execute the test and get the return code
+ TestResultHolder result = null;
+ if (!test.getFork()) {
+ result = executeInVM(test);
+ } else {
+ final ExecuteWatchdog watchdog = createWatchdog();
+ result = executeAsForked(test, watchdog, null);
+ // null watchdog means no timeout, you'd better not check with null
+ }
+ actOnTestResult(result, test, "Test " + test.getName());
+ }
+
+ /**
+ * Run the tests.
+ * @param arg one JUnitTest
+ * @throws BuildException in case of test failures or errors
+ */
+ protected void execute(final JUnitTest arg) throws BuildException {
+ execute(arg, 0);
+ }
+
+ /**
+ * Throws a <code>BuildException</code> if the given test name is invalid.
+ * Validity is defined as not <code>null</code>, not empty, and not the
+ * string &quot;null&quot;.
+ * @param testName the test name to be validated
+ * @throws BuildException if <code>testName</code> is not a valid test name
+ */
+ private void validateTestName(final String testName) throws BuildException {
+ if (testName == null || testName.length() == 0
+ || testName.equals("null")) {
+ throw new BuildException("test name must be specified");
+ }
+ }
+
+ /**
+ * Execute a list of tests in a single forked Java VM.
+ * @param testList the list of tests to execute.
+ * @param thread Identifies which thread is test running in (0 for single-threaded runs)
+ * @throws BuildException on error.
+ */
+ protected void execute(final List testList, final int thread) throws BuildException {
+ JUnitTest test = null;
+ // Create a temporary file to pass the test cases to run to
+ // the runner (one test case per line)
+ final File casesFile = createTempPropertiesFile("junittestcases");
+ BufferedWriter writer = null;
+ try {
+ writer = new BufferedWriter(new FileWriter(casesFile));
+
+ log("Creating casesfile '" + casesFile.getAbsolutePath()
+ + "' with content: ", Project.MSG_VERBOSE);
+ final PrintStream logWriter =
+ new PrintStream(new LogOutputStream(this, Project.MSG_VERBOSE));
+
+ final Iterator iter = testList.iterator();
+ while (iter.hasNext()) {
+ test = (JUnitTest) iter.next();
+ test.setThread(thread);
+ printDual(writer, logWriter, test.getName());
+ if (test.getMethods() != null) {
+ printDual(writer, logWriter, ":" + test.getMethodsString().replace(',', '+'));
+ }
+ if (test.getTodir() == null) {
+ printDual(writer, logWriter,
+ "," + getProject().resolveFile("."));
+ } else {
+ printDual(writer, logWriter, "," + test.getTodir());
+ }
+
+ if (test.getOutfile() == null) {
+ printlnDual(writer, logWriter,
+ "," + "TEST-" + test.getName());
+ } else {
+ printlnDual(writer, logWriter, "," + test.getOutfile());
+ }
+ }
+ writer.flush();
+ writer.close();
+ writer = null;
+
+ // execute the test and get the return code
+ final ExecuteWatchdog watchdog = createWatchdog();
+ final TestResultHolder result =
+ executeAsForked(test, watchdog, casesFile);
+ actOnTestResult(result, test, "Tests");
+ } catch (final IOException e) {
+ log(e.toString(), Project.MSG_ERR);
+ throw new BuildException(e);
+ } finally {
+ FileUtils.close(writer);
+
+ try {
+ FILE_UTILS.tryHardToDelete(casesFile);
+ } catch (final Exception e) {
+ log(e.toString(), Project.MSG_ERR);
+ }
+ }
+ }
+
+ /**
+ * Execute a list of tests in a single forked Java VM.
+ * @param testList the list of tests to execute.
+ * @throws BuildException on error.
+ */
+ protected void execute(final List testList) throws BuildException {
+ execute(testList, 0);
+ }
+
+ /**
+ * Execute a testcase by forking a new JVM. The command will block
+ * until it finishes. To know if the process was destroyed or not
+ * or whether the forked Java VM exited abnormally, use the
+ * attributes of the returned holder object.
+ * @param test the testcase to execute.
+ * @param watchdog the watchdog in charge of cancelling the test if it
+ * exceeds a certain amount of time. Can be <tt>null</tt>, in this case
+ * the test could probably hang forever.
+ * @param casesFile list of test cases to execute. Can be <tt>null</tt>,
+ * in this case only one test is executed.
+ * @return the test results from the JVM itself.
+ * @throws BuildException in case of error creating a temporary property file,
+ * or if the junit process can not be forked
+ */
+ private TestResultHolder executeAsForked(JUnitTest test,
+ final ExecuteWatchdog watchdog,
+ final File casesFile)
+ throws BuildException {
+
+ if (perm != null) {
+ log("Permissions ignored when running in forked mode!",
+ Project.MSG_WARN);
+ }
+
+ CommandlineJava cmd;
+ try {
+ cmd = (CommandlineJava) (getCommandline().clone());
+ } catch (final CloneNotSupportedException e) {
+ throw new BuildException("This shouldn't happen", e, getLocation());
+ }
+ if (casesFile == null) {
+ cmd.createArgument().setValue(test.getName());
+ if (test.getMethods() != null) {
+ cmd.createArgument().setValue(Constants.METHOD_NAMES + test.getMethodsString());
+ }
+ } else {
+ log("Running multiple tests in the same VM", Project.MSG_VERBOSE);
+ cmd.createArgument().setValue(Constants.TESTSFILE + casesFile);
+ }
+
+ cmd.createArgument().setValue(Constants.SKIP_NON_TESTS + String.valueOf(test.isSkipNonTests()));
+ cmd.createArgument().setValue(Constants.FILTERTRACE + test.getFiltertrace());
+ cmd.createArgument().setValue(Constants.HALT_ON_ERROR + test.getHaltonerror());
+ cmd.createArgument().setValue(Constants.HALT_ON_FAILURE
+ + test.getHaltonfailure());
+ checkIncludeAntRuntime(cmd);
+
+ checkIncludeSummary(cmd);
+
+ cmd.createArgument().setValue(Constants.SHOWOUTPUT
+ + String.valueOf(showOutput));
+ cmd.createArgument().setValue(Constants.OUTPUT_TO_FORMATTERS
+ + String.valueOf(outputToFormatters));
+ cmd.createArgument().setValue(Constants.LOG_FAILED_TESTS
+ + String.valueOf(logFailedTests));
+ cmd.createArgument().setValue(Constants.THREADID
+ + String.valueOf(test.getThread()));
+
+ // #31885
+ cmd.createArgument().setValue(Constants.LOGTESTLISTENEREVENTS
+ + String.valueOf(getEnableTestListenerEvents()));
+
+ StringBuffer formatterArg = new StringBuffer(STRING_BUFFER_SIZE);
+ final FormatterElement[] feArray = mergeFormatters(test);
+ for (int i = 0; i < feArray.length; i++) {
+ final FormatterElement fe = feArray[i];
+ if (fe.shouldUse(this)) {
+ formatterArg.append(Constants.FORMATTER);
+ formatterArg.append(fe.getClassname());
+ final File outFile = getOutput(fe, test);
+ if (outFile != null) {
+ formatterArg.append(",");
+ formatterArg.append(outFile);
+ }
+ cmd.createArgument().setValue(formatterArg.toString());
+ formatterArg = new StringBuffer();
+ }
+ }
+
+ final File vmWatcher = createTempPropertiesFile("junitvmwatcher");
+ cmd.createArgument().setValue(Constants.CRASHFILE
+ + vmWatcher.getAbsolutePath());
+ final File propsFile = createTempPropertiesFile("junit");
+ cmd.createArgument().setValue(Constants.PROPSFILE
+ + propsFile.getAbsolutePath());
+ final Hashtable p = getProject().getProperties();
+ final Properties props = new Properties();
+ for (final Enumeration e = p.keys(); e.hasMoreElements();) {
+ final Object key = e.nextElement();
+ props.put(key, p.get(key));
+ }
+ try {
+ final FileOutputStream outstream = new FileOutputStream(propsFile);
+ props.store(outstream, "Ant JUnitTask generated properties file");
+ outstream.close();
+ } catch (final java.io.IOException e) {
+ FILE_UTILS.tryHardToDelete(propsFile);
+ throw new BuildException("Error creating temporary properties "
+ + "file.", e, getLocation());
+ }
+
+ final Execute execute = new Execute(
+ new JUnitLogStreamHandler(
+ this,
+ Project.MSG_INFO,
+ Project.MSG_WARN),
+ watchdog);
+ execute.setCommandline(cmd.getCommandline());
+ execute.setAntRun(getProject());
+ if (dir != null) {
+ execute.setWorkingDirectory(dir);
+ }
+
+ final String[] environment = env.getVariables();
+ if (environment != null) {
+ for (int i = 0; i < environment.length; i++) {
+ log("Setting environment variable: " + environment[i],
+ Project.MSG_VERBOSE);
+ }
+ }
+ execute.setNewenvironment(newEnvironment);
+ execute.setEnvironment(environment);
+
+ log(cmd.describeCommand(), Project.MSG_VERBOSE);
+
+ checkForkedPath(cmd);
+
+ final TestResultHolder result = new TestResultHolder();
+ try {
+ result.exitCode = execute.execute();
+ } catch (final IOException e) {
+ throw new BuildException("Process fork failed.", e, getLocation());
+ } finally {
+ String vmCrashString = "unknown";
+ BufferedReader br = null;
+ try {
+ if (vmWatcher.exists()) {
+ br = new BufferedReader(new FileReader(vmWatcher));
+ vmCrashString = br.readLine();
+ } else {
+ vmCrashString = "Monitor file ("
+ + vmWatcher.getAbsolutePath()
+ + ") missing, location not writable,"
+ + " testcase not started or mixing ant versions?";
+ }
+ } catch (final Exception e) {
+ e.printStackTrace();
+ // ignored.
+ } finally {
+ FileUtils.close(br);
+ if (vmWatcher.exists()) {
+ FILE_UTILS.tryHardToDelete(vmWatcher);
+ }
+ }
+
+ final boolean crash = (watchdog != null && watchdog.killedProcess())
+ || !Constants.TERMINATED_SUCCESSFULLY.equals(vmCrashString);
+
+ if (casesFile != null && crash) {
+ test = createDummyTestForBatchTest(test);
+ }
+
+ if (watchdog != null && watchdog.killedProcess()) {
+ result.timedOut = true;
+ logTimeout(feArray, test, vmCrashString);
+ } else if (crash) {
+ result.crashed = true;
+ logVmCrash(feArray, test, vmCrashString);
+ }
+
+ if (!FILE_UTILS.tryHardToDelete(propsFile)) {
+ throw new BuildException("Could not delete temporary "
+ + "properties file '"
+ + propsFile.getAbsolutePath() + "'.");
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * Adding ant runtime.
+ * @param cmd command to run
+ */
+ private void checkIncludeAntRuntime(final CommandlineJava cmd) {
+ if (includeAntRuntime) {
+ final Map/*<String, String>*/ env = Execute.getEnvironmentVariables();
+ final String cp = (String) env.get(CLASSPATH);
+ if (cp != null) {
+ cmd.createClasspath(getProject()).createPath()
+ .append(new Path(getProject(), cp));
+ }
+ log("Implicitly adding " + antRuntimeClasses + " to CLASSPATH",
+ Project.MSG_VERBOSE);
+ cmd.createClasspath(getProject()).createPath()
+ .append(antRuntimeClasses);
+ }
+ }
+
+
+ /**
+ * check for the parameter being "withoutanderr" in a locale-independent way.
+ * @param summaryOption the summary option -can be null
+ * @return true if the run should be withoutput and error
+ */
+ private boolean equalsWithOutAndErr(final String summaryOption) {
+ return "withoutanderr".equalsIgnoreCase(summaryOption);
+ }
+
+ private void checkIncludeSummary(final CommandlineJava cmd) {
+ if (summary) {
+ String prefix = "";
+ if (equalsWithOutAndErr(summaryValue)) {
+ prefix = "OutErr";
+ }
+ cmd.createArgument()
+ .setValue(Constants.FORMATTER
+ + "org.apache.tools.ant.taskdefs.optional.junit."
+ + prefix + "SummaryJUnitResultFormatter");
+ }
+ }
+
+ /**
+ * Check the path for multiple different versions of
+ * ant.
+ * @param cmd command to execute
+ */
+ private void checkForkedPath(final CommandlineJava cmd) {
+ if (forkedPathChecked) {
+ return;
+ }
+ forkedPathChecked = true;
+ if (!cmd.haveClasspath()) {
+ return;
+ }
+ AntClassLoader loader = null;
+ try {
+ loader =
+ AntClassLoader.newAntClassLoader(null, getProject(),
+ cmd.createClasspath(getProject()),
+ true);
+ final String projectResourceName =
+ LoaderUtils.classNameToResource(Project.class.getName());
+ URL previous = null;
+ try {
+ for (final Enumeration e = loader.getResources(projectResourceName);
+ e.hasMoreElements();) {
+ final URL current = (URL) e.nextElement();
+ if (previous != null && !urlEquals(current, previous)) {
+ log("WARNING: multiple versions of ant detected "
+ + "in path for junit "
+ + LINE_SEP + " " + previous
+ + LINE_SEP + " and " + current,
+ Project.MSG_WARN);
+ return;
+ }
+ previous = current;
+ }
+ } catch (final Exception ex) {
+ // Ignore exception
+ }
+ } finally {
+ if (loader != null) {
+ loader.cleanup();
+ }
+ }
+ }
+
+ /**
+ * Compares URLs for equality but takes case-sensitivity into
+ * account when comparing file URLs and ignores the jar specific
+ * part of the URL if present.
+ */
+ private static boolean urlEquals(final URL u1, final URL u2) {
+ final String url1 = maybeStripJarAndClass(u1);
+ final String url2 = maybeStripJarAndClass(u2);
+ if (url1.startsWith("file:") && url2.startsWith("file:")) {
+ return new File(FILE_UTILS.fromURI(url1))
+ .equals(new File(FILE_UTILS.fromURI(url2)));
+ }
+ return url1.equals(url2);
+ }
+
+ private static String maybeStripJarAndClass(final URL u) {
+ String s = u.toString();
+ if (s.startsWith("jar:")) {
+ final int pling = s.indexOf('!');
+ s = s.substring(4, pling == -1 ? s.length() : pling);
+ }
+ return s;
+ }
+
+ /**
+ * Create a temporary file to pass the properties to a new process.
+ * Will auto-delete on (graceful) exit.
+ * The file will be in the project basedir unless tmpDir declares
+ * something else.
+ * @param prefix
+ * @return created file
+ */
+ private File createTempPropertiesFile(final String prefix) {
+ final File propsFile =
+ FILE_UTILS.createTempFile(prefix, ".properties",
+ tmpDir != null ? tmpDir : getProject().getBaseDir(), true, true);
+ return propsFile;
+ }
+
+
+ /**
+ * Pass output sent to System.out to the TestRunner so it can
+ * collect it for the formatters.
+ *
+ * @param output output coming from System.out
+ * @since Ant 1.5
+ */
+ @Override
+ protected void handleOutput(final String output) {
+ if (output.startsWith(TESTLISTENER_PREFIX)) {
+ log(output, Project.MSG_VERBOSE);
+ } else if (runner != null) {
+ if (outputToFormatters) {
+ runner.handleOutput(output);
+ }
+ if (showOutput) {
+ super.handleOutput(output);
+ }
+ } else {
+ super.handleOutput(output);
+ }
+ }
+
+ /**
+ * Handle an input request by this task.
+ * @see Task#handleInput(byte[], int, int)
+ * This implementation delegates to a runner if it
+ * present.
+ * @param buffer the buffer into which data is to be read.
+ * @param offset the offset into the buffer at which data is stored.
+ * @param length the amount of data to read.
+ *
+ * @return the number of bytes read.
+ * @exception IOException if the data cannot be read.
+ *
+ * @since Ant 1.6
+ */
+ @Override
+ protected int handleInput(final byte[] buffer, final int offset, final int length)
+ throws IOException {
+ if (runner != null) {
+ return runner.handleInput(buffer, offset, length);
+ } else {
+ return super.handleInput(buffer, offset, length);
+ }
+ }
+
+
+ /**
+ * Pass output sent to System.out to the TestRunner so it can
+ * collect ot for the formatters.
+ *
+ * @param output output coming from System.out
+ * @since Ant 1.5.2
+ */
+ @Override
+ protected void handleFlush(final String output) {
+ if (runner != null) {
+ runner.handleFlush(output);
+ if (showOutput) {
+ super.handleFlush(output);
+ }
+ } else {
+ super.handleFlush(output);
+ }
+ }
+
+ /**
+ * Pass output sent to System.err to the TestRunner so it can
+ * collect it for the formatters.
+ *
+ * @param output output coming from System.err
+ * @since Ant 1.5
+ */
+ @Override
+ public void handleErrorOutput(final String output) {
+ if (runner != null) {
+ runner.handleErrorOutput(output);
+ if (showOutput) {
+ super.handleErrorOutput(output);
+ }
+ } else {
+ super.handleErrorOutput(output);
+ }
+ }
+
+
+ /**
+ * Pass output sent to System.err to the TestRunner so it can
+ * collect it for the formatters.
+ *
+ * @param output coming from System.err
+ * @since Ant 1.5.2
+ */
+ @Override
+ public void handleErrorFlush(final String output) {
+ if (runner != null) {
+ runner.handleErrorFlush(output);
+ if (showOutput) {
+ super.handleErrorFlush(output);
+ }
+ } else {
+ super.handleErrorFlush(output);
+ }
+ }
+
+ // in VM is not very nice since it could probably hang the
+ // whole build. IMHO this method should be avoided and it would be best
+ // to remove it in future versions. TBD. (SBa)
+
+ /**
+ * Execute inside VM.
+ * @param arg one JUnitTest
+ * @throws BuildException under unspecified circumstances
+ * @return the results
+ */
+ private TestResultHolder executeInVM(final JUnitTest arg) throws BuildException {
+ if (delegate == null) {
+ setupJUnitDelegate();
+ }
+
+ final JUnitTest test = (JUnitTest) arg.clone();
+ test.setProperties(getProject().getProperties());
+ if (dir != null) {
+ log("dir attribute ignored if running in the same VM",
+ Project.MSG_WARN);
+ }
+
+ if (newEnvironment || null != env.getVariables()) {
+ log("Changes to environment variables are ignored if running in "
+ + "the same VM.", Project.MSG_WARN);
+ }
+
+ if (getCommandline().getBootclasspath() != null) {
+ log("bootclasspath is ignored if running in the same VM.",
+ Project.MSG_WARN);
+ }
+
+ final CommandlineJava.SysProperties sysProperties =
+ getCommandline().getSystemProperties();
+ if (sysProperties != null) {
+ sysProperties.setSystem();
+ }
+
+ try {
+ log("Using System properties " + System.getProperties(),
+ Project.MSG_VERBOSE);
+ if (splitJUnit) {
+ classLoader = (AntClassLoader) delegate.getClass().getClassLoader();
+ } else {
+ createClassLoader();
+ }
+ if (classLoader != null) {
+ classLoader.setThreadContextLoader();
+ }
+ runner = delegate.newJUnitTestRunner(test, test.getMethods(), test.getHaltonerror(),
+ test.getFiltertrace(),
+ test.getHaltonfailure(), false,
+ getEnableTestListenerEvents(),
+ classLoader);
+ if (summary) {
+
+ final JUnitTaskMirror.SummaryJUnitResultFormatterMirror f =
+ delegate.newSummaryJUnitResultFormatter();
+ f.setWithOutAndErr(equalsWithOutAndErr(summaryValue));
+ f.setOutput(getDefaultOutput());
+ runner.addFormatter(f);
+ }
+
+ runner.setPermissions(perm);
+
+ final FormatterElement[] feArray = mergeFormatters(test);
+ for (int i = 0; i < feArray.length; i++) {
+ final FormatterElement fe = feArray[i];
+ if (fe.shouldUse(this)) {
+ final File outFile = getOutput(fe, test);
+ if (outFile != null) {
+ fe.setOutfile(outFile);
+ } else {
+ fe.setOutput(getDefaultOutput());
+ }
+ runner.addFormatter(fe.createFormatter(classLoader));
+ }
+ }
+
+ runner.run();
+ final TestResultHolder result = new TestResultHolder();
+ result.exitCode = runner.getRetCode();
+ return result;
+ } finally {
+ if (sysProperties != null) {
+ sysProperties.restoreSystem();
+ }
+ if (classLoader != null) {
+ classLoader.resetThreadContextLoader();
+ }
+ }
+ }
+
+ /**
+ * @return <tt>null</tt> if there is a timeout value, otherwise the
+ * watchdog instance.
+ *
+ * @throws BuildException under unspecified circumstances
+ * @since Ant 1.2
+ */
+ protected ExecuteWatchdog createWatchdog() throws BuildException {
+ if (timeout == null) {
+ return null;
+ }
+ return new ExecuteWatchdog((long) timeout.intValue());
+ }
+
+ /**
+ * Get the default output for a formatter.
+ *
+ * @return default output stream for a formatter
+ * @since Ant 1.3
+ */
+ protected OutputStream getDefaultOutput() {
+ return new LogOutputStream(this, Project.MSG_INFO);
+ }
+
+ /**
+ * Merge all individual tests from the batchtest with all individual tests
+ * and return an enumeration over all <tt>JUnitTest</tt>.
+ *
+ * @return enumeration over individual tests
+ * @since Ant 1.3
+ */
+ protected Enumeration<JUnitTest> getIndividualTests() {
+ final int count = batchTests.size();
+ final Enumeration[] enums = new Enumeration[ count + 1];
+ for (int i = 0; i < count; i++) {
+ final BatchTest batchtest = batchTests.elementAt(i);
+ enums[i] = batchtest.elements();
+ }
+ enums[enums.length - 1] = tests.elements();
+ return Enumerations.fromCompound(enums);
+ }
+
+ /**
+ * Verifies all <code>test</code> elements having the <code>methods</code>
+ * attribute specified and having the <code>if</code>-condition resolved
+ * to true, that the value of the <code>methods</code> attribute is valid.
+ * @exception BuildException if some of the tests matching the described
+ * conditions has invalid value of the
+ * <code>methods</code> attribute
+ * @since 1.8.2
+ */
+ private void checkMethodLists() throws BuildException {
+ if (tests.isEmpty()) {
+ return;
+ }
+
+ final Enumeration<JUnitTest> testsEnum = tests.elements();
+ while (testsEnum.hasMoreElements()) {
+ final JUnitTest test = testsEnum.nextElement();
+ if (test.hasMethodsSpecified() && test.shouldRun(getProject())) {
+ test.resolveMethods();
+ }
+ }
+ }
+
+ /**
+ * return an enumeration listing each test, then each batchtest
+ * @return enumeration
+ * @since Ant 1.3
+ */
+ protected Enumeration<JUnitTest> allTests() {
+ final Enumeration[] enums = {tests.elements(), batchTests.elements()};
+ return Enumerations.fromCompound(enums);
+ }
+
+ /**
+ * @param test junit test
+ * @return array of FormatterElement
+ * @since Ant 1.3
+ */
+ private FormatterElement[] mergeFormatters(final JUnitTest test) {
+ final Vector<FormatterElement> feVector = (Vector<FormatterElement>) formatters.clone();
+ test.addFormattersTo(feVector);
+ final FormatterElement[] feArray = new FormatterElement[feVector.size()];
+ feVector.copyInto(feArray);
+ return feArray;
+ }
+
+ /**
+ * If the formatter sends output to a file, return that file.
+ * null otherwise.
+ * @param fe formatter element
+ * @param test one JUnit test
+ * @return file reference
+ * @since Ant 1.3
+ */
+ protected File getOutput(final FormatterElement fe, final JUnitTest test) {
+ if (fe.getUseFile()) {
+ String base = test.getOutfile();
+ if (base == null) {
+ base = JUnitTaskMirror.JUnitTestRunnerMirror.IGNORED_FILE_NAME;
+ }
+ final String filename = base + fe.getExtension();
+ final File destFile = new File(test.getTodir(), filename);
+ final String absFilename = destFile.getAbsolutePath();
+ return getProject().resolveFile(absFilename);
+ }
+ return null;
+ }
+
+ /**
+ * Search for the given resource and add the directory or archive
+ * that contains it to the classpath.
+ *
+ * <p>Doesn't work for archives in JDK 1.1 as the URL returned by
+ * getResource doesn't contain the name of the archive.</p>
+ *
+ * @param resource resource that one wants to lookup
+ * @since Ant 1.4
+ */
+ protected void addClasspathEntry(final String resource) {
+ addClasspathResource(resource);
+ }
+
+ /**
+ * Implementation of addClasspathEntry.
+ *
+ * @param resource resource that one wants to lookup
+ * @return true if something was in fact added
+ * @since Ant 1.7.1
+ */
+ private boolean addClasspathResource(String resource) {
+ /*
+ * pre Ant 1.6 this method used to call getClass().getResource
+ * while Ant 1.6 will call ClassLoader.getResource().
+ *
+ * The difference is that Class.getResource expects a leading
+ * slash for "absolute" resources and will strip it before
+ * delegating to ClassLoader.getResource - so we now have to
+ * emulate Class's behavior.
+ */
+ if (resource.startsWith("/")) {
+ resource = resource.substring(1);
+ } else {
+ resource = "org/apache/tools/ant/taskdefs/optional/junit/"
+ + resource;
+ }
+
+ final File f = LoaderUtils.getResourceSource(JUnitTask.class.getClassLoader(),
+ resource);
+ if (f != null) {
+ log("Found " + f.getAbsolutePath(), Project.MSG_DEBUG);
+ antRuntimeClasses.createPath().setLocation(f);
+ return true;
+ } else {
+ log("Couldn\'t find " + resource, Project.MSG_DEBUG);
+ return false;
+ }
+ }
+
+ static final String TIMEOUT_MESSAGE =
+ "Timeout occurred. Please note the time in the report does"
+ + " not reflect the time until the timeout.";
+
+ /**
+ * Take care that some output is produced in report files if the
+ * watchdog kills the test.
+ *
+ * @since Ant 1.5.2
+ */
+ private void logTimeout(final FormatterElement[] feArray, final JUnitTest test,
+ final String testCase) {
+ logVmExit(feArray, test, TIMEOUT_MESSAGE, testCase);
+ }
+
+ /**
+ * Take care that some output is produced in report files if the
+ * forked machine exited before the test suite finished but the
+ * reason is not a timeout.
+ *
+ * @since Ant 1.7
+ */
+ private void logVmCrash(final FormatterElement[] feArray, final JUnitTest test, final String testCase) {
+ logVmExit(
+ feArray, test,
+ "Forked Java VM exited abnormally. Please note the time in the report"
+ + " does not reflect the time until the VM exit.",
+ testCase);
+ }
+
+ /**
+ * Take care that some output is produced in report files if the
+ * forked machine terminated before the test suite finished
+ *
+ * @since Ant 1.7
+ */
+ private void logVmExit(final FormatterElement[] feArray, final JUnitTest test,
+ final String message, final String testCase) {
+ if (delegate == null) {
+ setupJUnitDelegate();
+ }
+
+ try {
+ log("Using System properties " + System.getProperties(),
+ Project.MSG_VERBOSE);
+ if (splitJUnit) {
+ classLoader = (AntClassLoader) delegate.getClass().getClassLoader();
+ } else {
+ createClassLoader();
+ }
+ if (classLoader != null) {
+ classLoader.setThreadContextLoader();
+ }
+
+ test.setCounts(1, 0, 1, 0);
+ test.setProperties(getProject().getProperties());
+ for (int i = 0; i < feArray.length; i++) {
+ final FormatterElement fe = feArray[i];
+ if (fe.shouldUse(this)) {
+ final JUnitTaskMirror.JUnitResultFormatterMirror formatter =
+ fe.createFormatter(classLoader);
+ if (formatter != null) {
+ OutputStream out = null;
+ final File outFile = getOutput(fe, test);
+ if (outFile != null) {
+ try {
+ out = new FileOutputStream(outFile);
+ } catch (final IOException e) {
+ // ignore
+ }
+ }
+ if (out == null) {
+ out = getDefaultOutput();
+ }
+ delegate.addVmExit(test, formatter, out, message,
+ testCase);
+ }
+ }
+ }
+ if (summary) {
+ final JUnitTaskMirror.SummaryJUnitResultFormatterMirror f =
+ delegate.newSummaryJUnitResultFormatter();
+ f.setWithOutAndErr(equalsWithOutAndErr(summaryValue));
+ delegate.addVmExit(test, f, getDefaultOutput(), message, testCase);
+ }
+ } finally {
+ if (classLoader != null) {
+ classLoader.resetThreadContextLoader();
+ }
+ }
+ }
+
+ /**
+ * Creates and configures an AntClassLoader instance from the
+ * nested classpath element.
+ *
+ * @since Ant 1.6
+ */
+ private void createClassLoader() {
+ final Path userClasspath = getCommandline().getClasspath();
+ if (userClasspath != null) {
+ if (reloading || classLoader == null) {
+ deleteClassLoader();
+ final Path classpath = (Path) userClasspath.clone();
+ if (includeAntRuntime) {
+ log("Implicitly adding " + antRuntimeClasses
+ + " to CLASSPATH", Project.MSG_VERBOSE);
+ classpath.append(antRuntimeClasses);
+ }
+ classLoader = getProject().createClassLoader(classpath);
+ if (getClass().getClassLoader() != null
+ && getClass().getClassLoader() != Project.class.getClassLoader()) {
+ classLoader.setParent(getClass().getClassLoader());
+ }
+ classLoader.setParentFirst(false);
+ classLoader.addJavaLibraries();
+ log("Using CLASSPATH " + classLoader.getClasspath(),
+ Project.MSG_VERBOSE);
+ // make sure the test will be accepted as a TestCase
+ classLoader.addSystemPackageRoot("junit");
+ // make sure the test annotation are accepted
+ classLoader.addSystemPackageRoot("org.junit");
+ // will cause trouble in JDK 1.1 if omitted
+ classLoader.addSystemPackageRoot("org.apache.tools.ant");
+ }
+ }
+ }
+
+ /**
+ * Removes resources.
+ *
+ * <p>Is invoked in {@link #execute execute}. Subclasses that
+ * don't invoke execute should invoke this method in a finally
+ * block.</p>
+ *
+ * @since Ant 1.7.1
+ */
+ protected void cleanup() {
+ deleteClassLoader();
+ delegate = null;
+ }
+
+ /**
+ * Removes a classloader if needed.
+ * @since Ant 1.7
+ */
+ private void deleteClassLoader() {
+ if (classLoader != null) {
+ classLoader.cleanup();
+ classLoader = null;
+ }
+ if (mirrorLoader instanceof SplitClassLoader) {
+ ((SplitClassLoader) mirrorLoader).cleanup();
+ }
+ mirrorLoader = null;
+ }
+
+ /**
+ * Get the command line used to run the tests.
+ * @return the command line.
+ * @since Ant 1.6.2
+ */
+ protected CommandlineJava getCommandline() {
+ if (commandline == null) {
+ commandline = new CommandlineJava();
+ commandline.setClassname("org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner");
+ }
+ return commandline;
+ }
+
+ /**
+ * Forked test support
+ * @since Ant 1.6.2
+ */
+ private static final class ForkedTestConfiguration {
+ private final boolean filterTrace;
+ private final boolean haltOnError;
+ private final boolean haltOnFailure;
+ private final String errorProperty;
+ private final String failureProperty;
+
+ /**
+ * constructor for forked test configuration
+ * @param filterTrace
+ * @param haltOnError
+ * @param haltOnFailure
+ * @param errorProperty
+ * @param failureProperty
+ */
+ ForkedTestConfiguration(final boolean filterTrace, final boolean haltOnError,
+ final boolean haltOnFailure, final String errorProperty,
+ final String failureProperty) {
+ this.filterTrace = filterTrace;
+ this.haltOnError = haltOnError;
+ this.haltOnFailure = haltOnFailure;
+ this.errorProperty = errorProperty;
+ this.failureProperty = failureProperty;
+ }
+
+ /**
+ * configure from a test; sets member variables to attributes of the test
+ * @param test
+ */
+ ForkedTestConfiguration(final JUnitTest test) {
+ this(test.getFiltertrace(),
+ test.getHaltonerror(),
+ test.getHaltonfailure(),
+ test.getErrorProperty(),
+ test.getFailureProperty());
+ }
+
+ /**
+ * equality test checks all the member variables
+ * @param other
+ * @return true if everything is equal
+ */
+ @Override
+ public boolean equals(final Object other) {
+ if (other == null
+ || other.getClass() != ForkedTestConfiguration.class) {
+ return false;
+ }
+ final ForkedTestConfiguration o = (ForkedTestConfiguration) other;
+ return filterTrace == o.filterTrace
+ && haltOnError == o.haltOnError
+ && haltOnFailure == o.haltOnFailure
+ && ((errorProperty == null && o.errorProperty == null)
+ ||
+ (errorProperty != null
+ && errorProperty.equals(o.errorProperty)))
+ && ((failureProperty == null && o.failureProperty == null)
+ ||
+ (failureProperty != null
+ && failureProperty.equals(o.failureProperty)));
+ }
+
+ /**
+ * hashcode is based only on the boolean members, and returns a value
+ * in the range 0-7.
+ * @return hash code value
+ */
+ @Override
+ public int hashCode() {
+ // CheckStyle:MagicNumber OFF
+ return (filterTrace ? 1 : 0)
+ + (haltOnError ? 2 : 0)
+ + (haltOnFailure ? 4 : 0);
+ // CheckStyle:MagicNumber ON
+ }
+ }
+
+ /**
+ * These are the different forking options
+ * @since 1.6.2
+ */
+ public static final class ForkMode extends EnumeratedAttribute {
+
+ /**
+ * fork once only
+ */
+ public static final String ONCE = "once";
+ /**
+ * fork once per test class
+ */
+ public static final String PER_TEST = "perTest";
+ /**
+ * fork once per batch of tests
+ */
+ public static final String PER_BATCH = "perBatch";
+
+ /** No arg constructor. */
+ public ForkMode() {
+ super();
+ }
+
+ /**
+ * Constructor using a value.
+ * @param value the value to use - once, perTest or perBatch.
+ */
+ public ForkMode(final String value) {
+ super();
+ setValue(value);
+ }
+
+ /** {@inheritDoc}. */
+ @Override
+ public String[] getValues() {
+ return new String[] {ONCE, PER_TEST, PER_BATCH};
+ }
+ }
+
+ /**
+ * Executes all tests that don't need to be forked (or all tests
+ * if the runIndividual argument is true. Returns a collection of
+ * lists of tests that share the same VM configuration and haven't
+ * been executed yet.
+ * @param testList the list of tests to be executed or queued.
+ * @param runIndividual if true execute each test individually.
+ * @return a list of tasks to be executed.
+ * @since 1.6.2
+ */
+ protected Collection<List> executeOrQueue(final Enumeration<JUnitTest> testList,
+ final boolean runIndividual) {
+ final Map<ForkedTestConfiguration, List> testConfigurations = new HashMap<ForkedTestConfiguration, List>();
+ while (testList.hasMoreElements()) {
+ final JUnitTest test = testList.nextElement();
+ if (test.shouldRun(getProject())) {
+ /* with multi-threaded runs need to defer execution of even */
+ /* individual tests so the threads can pick tests off the queue. */
+ if ((runIndividual || !test.getFork()) && (threads == 1)) {
+ execute(test, 0);
+ } else {
+ final ForkedTestConfiguration c =
+ new ForkedTestConfiguration(test);
+ List<JUnitTest> l = testConfigurations.get(c);
+ if (l == null) {
+ l = new ArrayList<JUnitTest>();
+ testConfigurations.put(c, l);
+ }
+ l.add(test);
+ }
+ }
+ }
+ return testConfigurations.values();
+ }
+
+ /**
+ * Logs information about failed tests, potentially stops
+ * processing (by throwing a BuildException) if a failure/error
+ * occurred or sets a property.
+ * @param exitValue the exitValue of the test.
+ * @param wasKilled if true, the test had been killed.
+ * @param test the test in question.
+ * @param name the name of the test.
+ * @since Ant 1.6.2
+ */
+ protected void actOnTestResult(final int exitValue, final boolean wasKilled,
+ final JUnitTest test, final String name) {
+ final TestResultHolder t = new TestResultHolder();
+ t.exitCode = exitValue;
+ t.timedOut = wasKilled;
+ actOnTestResult(t, test, name);
+ }
+
+ /**
+ * Logs information about failed tests, potentially stops
+ * processing (by throwing a BuildException) if a failure/error
+ * occurred or sets a property.
+ * @param result the result of the test.
+ * @param test the test in question.
+ * @param name the name of the test.
+ * @since Ant 1.7
+ */
+ protected void actOnTestResult(final TestResultHolder result, final JUnitTest test,
+ final String name) {
+ // if there is an error/failure and that it should halt, stop
+ // everything otherwise just log a statement
+ final boolean fatal = result.timedOut || result.crashed;
+ final boolean errorOccurredHere =
+ result.exitCode == JUnitTaskMirror.JUnitTestRunnerMirror.ERRORS || fatal;
+ final boolean failureOccurredHere =
+ result.exitCode != JUnitTaskMirror.JUnitTestRunnerMirror.SUCCESS || fatal;
+ if (errorOccurredHere || failureOccurredHere) {
+ if ((errorOccurredHere && test.getHaltonerror())
+ || (failureOccurredHere && test.getHaltonfailure())) {
+ throw new BuildException(name + " failed"
+ + (result.timedOut ? " (timeout)" : "")
+ + (result.crashed ? " (crashed)" : ""), getLocation());
+ } else {
+ if (logFailedTests) {
+ log(name + " FAILED"
+ + (result.timedOut ? " (timeout)" : "")
+ + (result.crashed ? " (crashed)" : ""),
+ Project.MSG_ERR);
+ }
+ if (errorOccurredHere && test.getErrorProperty() != null) {
+ getProject().setNewProperty(test.getErrorProperty(), "true");
+ }
+ if (failureOccurredHere && test.getFailureProperty() != null) {
+ getProject().setNewProperty(test.getFailureProperty(), "true");
+ }
+ }
+ }
+ }
+
+ /**
+ * A value class that contains the result of a test.
+ */
+ protected static class TestResultHolder {
+ // CheckStyle:VisibilityModifier OFF - bc
+ /** the exit code of the test. */
+ public int exitCode = JUnitTaskMirror.JUnitTestRunnerMirror.ERRORS;
+ /** true if the test timed out */
+ public boolean timedOut = false;
+ /** true if the test crashed */
+ public boolean crashed = false;
+ // CheckStyle:VisibilityModifier ON
+ }
+
+ /**
+ * A stream handler for handling the junit task.
+ * @since Ant 1.7
+ */
+ protected static class JUnitLogOutputStream extends LogOutputStream {
+ private final Task task; // local copy since LogOutputStream.task is private
+
+ /**
+ * Constructor.
+ * @param task the task being logged.
+ * @param level the log level used to log data written to this stream.
+ */
+ public JUnitLogOutputStream(final Task task, final int level) {
+ super(task, level);
+ this.task = task;
+ }
+
+ /**
+ * Logs a line.
+ * If the line starts with junit.framework.TestListener: set the level
+ * to MSG_VERBOSE.
+ * @param line the line to log.
+ * @param level the logging level to use.
+ */
+ @Override
+ protected void processLine(final String line, final int level) {
+ if (line.startsWith(TESTLISTENER_PREFIX)) {
+ task.log(line, Project.MSG_VERBOSE);
+ } else {
+ super.processLine(line, level);
+ }
+ }
+ }
+
+ /**
+ * A log stream handler for junit.
+ * @since Ant 1.7
+ */
+ protected static class JUnitLogStreamHandler extends PumpStreamHandler {
+ /**
+ * Constructor.
+ * @param task the task to log.
+ * @param outlevel the level to use for standard output.
+ * @param errlevel the level to use for error output.
+ */
+ public JUnitLogStreamHandler(final Task task, final int outlevel, final int errlevel) {
+ super(new JUnitLogOutputStream(task, outlevel),
+ new LogOutputStream(task, errlevel));
+ }
+ }
+
+ static final String NAME_OF_DUMMY_TEST = "Batch-With-Multiple-Tests";
+
+ /**
+ * Creates a JUnitTest instance that shares all flags with the
+ * passed in instance but has a more meaningful name.
+ *
+ * <p>If a VM running multiple tests crashes, we don't know which
+ * test failed. Prior to Ant 1.8.0 Ant would log the error with
+ * the last test of the batch test, which caused some confusion
+ * since the log might look as if a test had been executed last
+ * that was never started. With Ant 1.8.0 the test's name will
+ * indicate that something went wrong with a test inside the batch
+ * without giving it a real name.</p>
+ *
+ * @see "https://issues.apache.org/bugzilla/show_bug.cgi?id=45227"
+ */
+ private static JUnitTest createDummyTestForBatchTest(final JUnitTest test) {
+ final JUnitTest t = (JUnitTest) test.clone();
+ final int index = test.getName().lastIndexOf('.');
+ // make sure test looks as if it was in the same "package" as
+ // the last test of the batch
+ final String pack = index > 0 ? test.getName().substring(0, index + 1) : "";
+ t.setName(pack + NAME_OF_DUMMY_TEST);
+ return t;
+ }
+
+ private static void printDual(final BufferedWriter w, final PrintStream s, final String text)
+ throws IOException {
+ w.write(String.valueOf(text));
+ s.print(text);
+ }
+
+ private static void printlnDual(final BufferedWriter w, final PrintStream s, final String text)
+ throws IOException {
+ w.write(String.valueOf(text));
+ w.newLine();
+ s.println(text);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTaskMirror.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTaskMirror.java
new file mode 100644
index 00000000..694e1d8c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTaskMirror.java
@@ -0,0 +1,190 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.junit;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import org.apache.tools.ant.AntClassLoader;
+import org.apache.tools.ant.types.Permissions;
+
+/**
+ * Handles the portions of {@link JUnitTask} which need to directly access
+ * actual JUnit classes, so that junit.jar need not be on Ant's startup classpath.
+ * Neither JUnitTask.java nor JUnitTaskMirror.java nor their transitive static
+ * deps may import any junit.** classes!
+ * Specifically, need to not refer to
+ * - JUnitResultFormatter or its subclasses
+ * - JUnitVersionHelper
+ * - JUnitTestRunner
+ * Cf. JUnitTask.SplitLoader#isSplit(String)
+ * Public only to permit access from classes in this package; do not use directly.
+ *
+ * @since 1.7
+ * @see "bug #38799"
+ */
+public interface JUnitTaskMirror {
+
+ /**
+ * Add the formatter to be called when the jvm exits before
+ * the test suite finishes.
+ * @param test the test.
+ * @param formatter the formatter to use.
+ * @param out the output stream to use.
+ * @param message the message to write out.
+ * @param testCase the name of the test.
+ */
+ void addVmExit(JUnitTest test, JUnitResultFormatterMirror formatter,
+ OutputStream out, String message, String testCase);
+
+ /**
+ * Create a new test runner for a test.
+ * @param test the test to run.
+ * @param methods names of the test methods to be run.
+ * @param haltOnError if true halt the tests if an error occurs.
+ * @param filterTrace if true filter the stack traces.
+ * @param haltOnFailure if true halt the test if a failure occurs.
+ * @param showOutput if true show output.
+ * @param logTestListenerEvents if true log test listener events.
+ * @param classLoader the classloader to use to create the runner.
+ * @return the test runner.
+ */
+ JUnitTestRunnerMirror newJUnitTestRunner(JUnitTest test, String[] methods, boolean haltOnError,
+ boolean filterTrace, boolean haltOnFailure, boolean showOutput,
+ boolean logTestListenerEvents, AntClassLoader classLoader);
+
+ /**
+ * Create a summary result formatter.
+ * @return the created formatter.
+ */
+ SummaryJUnitResultFormatterMirror newSummaryJUnitResultFormatter();
+
+
+ /** The interface that JUnitResultFormatter extends. */
+ public interface JUnitResultFormatterMirror {
+ /**
+ * Set the output stream.
+ * @param outputStream the stream to use.
+ */
+ void setOutput(OutputStream outputStream);
+ }
+
+ /** The interface that SummaryJUnitResultFormatter extends. */
+ public interface SummaryJUnitResultFormatterMirror
+ extends JUnitResultFormatterMirror {
+
+ /**
+ * Set where standard out and standard error should be included.
+ * @param value if true include the outputs in the summary.
+ */
+ void setWithOutAndErr(boolean value);
+ }
+
+ /** Interface that test runners implement. */
+ public interface JUnitTestRunnerMirror {
+
+ /**
+ * Used in formatter arguments as a placeholder for the basename
+ * of the output file (which gets replaced by a test specific
+ * output file name later).
+ *
+ * @since Ant 1.6.3
+ */
+ String IGNORED_FILE_NAME = "IGNORETHIS";
+
+ /**
+ * No problems with this test.
+ */
+ int SUCCESS = 0;
+
+ /**
+ * Some tests failed.
+ */
+ int FAILURES = 1;
+
+ /**
+ * An error occurred.
+ */
+ int ERRORS = 2;
+
+ /**
+ * Permissions for the test run.
+ * @param perm the permissions to use.
+ */
+ void setPermissions(Permissions perm);
+
+ /** Run the test. */
+ void run();
+
+ /**
+ * Add a formatter to the test.
+ * @param formatter the formatter to use.
+ */
+ void addFormatter(JUnitResultFormatterMirror formatter);
+
+ /**
+ * Returns what System.exit() would return in the standalone version.
+ *
+ * @return 2 if errors occurred, 1 if tests failed else 0.
+ */
+ int getRetCode();
+
+ /**
+ * Handle output sent to System.err.
+ *
+ * @param output coming from System.err
+ */
+ void handleErrorFlush(String output);
+
+ /**
+ * Handle output sent to System.err.
+ *
+ * @param output output for System.err
+ */
+ void handleErrorOutput(String output);
+
+ /**
+ * Handle output sent to System.out.
+ *
+ * @param output output for System.out.
+ */
+ void handleOutput(String output);
+
+ /**
+ * Handle an input request.
+ *
+ * @param buffer the buffer into which data is to be read.
+ * @param offset the offset into the buffer at which data is stored.
+ * @param length the amount of data to read.
+ *
+ * @return the number of bytes read.
+ *
+ * @exception IOException if the data cannot be read.
+ */
+ int handleInput(byte[] buffer, int offset, int length) throws IOException;
+
+ /**
+ * Handle output sent to System.out.
+ *
+ * @param output output for System.out.
+ */
+ void handleFlush(String output);
+
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTaskMirrorImpl.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTaskMirrorImpl.java
new file mode 100644
index 00000000..c7dae258
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTaskMirrorImpl.java
@@ -0,0 +1,109 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.junit;
+
+import java.io.OutputStream;
+
+import junit.framework.AssertionFailedError;
+import junit.framework.TestCase;
+import junit.framework.TestResult;
+
+import org.apache.tools.ant.AntClassLoader;
+
+/**
+ * Implementation of the part of the junit task which can directly refer to junit.* classes.
+ * Public only to permit use of reflection; do not use directly.
+ * @see JUnitTaskMirror
+ * @see "bug #38799"
+ * @since 1.7
+ */
+public final class JUnitTaskMirrorImpl implements JUnitTaskMirror {
+
+ private final JUnitTask task;
+
+ /**
+ * Constructor.
+ * @param task the junittask that uses this mirror.
+ */
+ public JUnitTaskMirrorImpl(JUnitTask task) {
+ this.task = task;
+ }
+
+ /** {@inheritDoc}. */
+ public void addVmExit(JUnitTest test, JUnitTaskMirror.JUnitResultFormatterMirror aFormatter,
+ OutputStream out, String message, String testCase) {
+ JUnitResultFormatter formatter = (JUnitResultFormatter) aFormatter;
+ formatter.setOutput(out);
+ formatter.startTestSuite(test);
+ //the trick to integrating test output to the formatter, is to
+ //create a special test class that asserts an error
+ //and tell the formatter that it raised.
+ TestCase t = new VmExitErrorTest(message, test, testCase);
+ formatter.startTest(t);
+ formatter.addError(t, new AssertionFailedError(message));
+ formatter.endTestSuite(test);
+ }
+
+ /** {@inheritDoc}. */
+ public JUnitTaskMirror.JUnitTestRunnerMirror newJUnitTestRunner(JUnitTest test,
+ String[] methods,
+ boolean haltOnError, boolean filterTrace, boolean haltOnFailure,
+ boolean showOutput, boolean logTestListenerEvents, AntClassLoader classLoader) {
+ return new JUnitTestRunner(test, methods, haltOnError, filterTrace, haltOnFailure,
+ showOutput, logTestListenerEvents, classLoader);
+ }
+
+ /** {@inheritDoc}. */
+ public JUnitTaskMirror.SummaryJUnitResultFormatterMirror newSummaryJUnitResultFormatter() {
+ return new SummaryJUnitResultFormatter();
+ }
+
+ static class VmExitErrorTest extends TestCase {
+
+ private String message;
+ private JUnitTest test;
+ private String testCase;
+
+ VmExitErrorTest(String aMessage, JUnitTest anOriginalTest, String aTestCase) {
+ message = aMessage;
+ test = anOriginalTest;
+ testCase = aTestCase;
+ }
+
+ public int countTestCases() {
+ return 1;
+ }
+
+ public void run(TestResult r) {
+ throw new AssertionFailedError(message);
+ }
+
+ public String getName() {
+ return testCase;
+ }
+
+ String getClassName() {
+ return test.getName();
+ }
+
+ public String toString() {
+ return test.getName() + ":" + testCase;
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTest.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTest.java
new file mode 100644
index 00000000..835c013b
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTest.java
@@ -0,0 +1,542 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.junit;
+
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Properties;
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.PropertyHelper;
+
+/**
+ * <p> Run a single JUnit test.
+ *
+ * <p> The JUnit test is actually run by {@link JUnitTestRunner}.
+ * So read the doc comments for that class :)
+ *
+ * @since Ant 1.2
+ *
+ * @see JUnitTask
+ * @see JUnitTestRunner
+ */
+public class JUnitTest extends BaseTest implements Cloneable {
+
+ /** the name of the test case */
+ private String name = null;
+
+ /**
+ * whether the list of test methods has been specified
+ * @see #setMethods(java.lang.String)
+ * @see #setMethods(java.lang.String[])
+ */
+ private boolean methodsSpecified = false;
+
+ /** comma-separated list of names of test methods to execute */
+ private String methodsList = null;
+
+ /** the names of test methods to execute */
+ private String[] methods = null;
+
+ /** the name of the result file */
+ private String outfile = null;
+
+ // @todo this is duplicating TestResult information. Only the time is not
+ // part of the result. So we'd better derive a new class from TestResult
+ // and deal with it. (SB)
+ private long runs, failures, errors;
+ /**
+ @since Ant 1.9.0
+ */
+ private long skips;
+
+ private long runTime;
+
+ private int antThreadID;
+
+ // Snapshot of the system properties
+ private Properties props = null;
+
+ /** No arg constructor. */
+ public JUnitTest() {
+ }
+
+ /**
+ * Constructor with name.
+ * @param name the name of the test.
+ */
+ public JUnitTest(String name) {
+ this.name = name;
+ }
+
+ /**
+ * Constructor with options.
+ * @param name the name of the test.
+ * @param haltOnError if true halt the tests if there is an error.
+ * @param haltOnFailure if true halt the tests if there is a failure.
+ * @param filtertrace if true filter stack traces.
+ */
+ public JUnitTest(String name, boolean haltOnError, boolean haltOnFailure,
+ boolean filtertrace) {
+ this(name, haltOnError, haltOnFailure, filtertrace, null, 0);
+ }
+
+ /**
+ * Constructor with options.
+ * @param name the name of the test.
+ * @param haltOnError if true halt the tests if there is an error.
+ * @param haltOnFailure if true halt the tests if there is a failure.
+ * @param filtertrace if true filter stack traces.
+ * @param methods if non-null run only these test methods
+ * @since 1.8.2
+ */
+ public JUnitTest(String name, boolean haltOnError, boolean haltOnFailure,
+ boolean filtertrace, String[] methods) {
+ this(name, haltOnError, haltOnFailure, filtertrace, methods, 0);
+ }
+
+ /**
+ * Constructor with options.
+ * @param name the name of the test.
+ * @param haltOnError if true halt the tests if there is an error.
+ * @param haltOnFailure if true halt the tests if there is a failure.
+ * @param filtertrace if true filter stack traces.
+ * @param methods if non-null run only these test methods
+ * @param thread Ant thread ID in which test is currently running
+ * @since 1.9.4
+ */
+ public JUnitTest(String name, boolean haltOnError, boolean haltOnFailure,
+ boolean filtertrace, String[] methods, int thread) {
+ this.name = name;
+ this.haltOnError = haltOnError;
+ this.haltOnFail = haltOnFailure;
+ this.filtertrace = filtertrace;
+ this.methodsSpecified = methods != null;
+ this.methods = methodsSpecified ? (String[]) methods.clone() : null;
+ this.antThreadID = thread;
+ }
+
+ /**
+ * Sets names of individual test methods to be executed.
+ * @param value comma-separated list of names of individual test methods
+ * to be executed,
+ * or <code>null</code> if all test methods should be executed
+ * @since 1.8.2
+ */
+ public void setMethods(String value) {
+ methodsList = value;
+ methodsSpecified = (value != null);
+ methods = null;
+ }
+
+ /**
+ * Sets names of individual test methods to be executed.
+ * @param value non-empty array of names of test methods to be executed
+ * @see #setMethods(String)
+ * @since 1.8.2
+ */
+ void setMethods(String[] value) {
+ methods = value;
+ methodsSpecified = (value != null);
+ methodsList = null;
+ }
+
+ /**
+ * Set the name of the test class.
+ * @param value the name to use.
+ */
+ public void setName(String value) {
+ name = value;
+ }
+
+ /**
+ * Set the thread id
+ * @param thread the Ant id of the thread running this test
+ * (this is not the system process or thread id)
+ * (this will be 0 in single-threaded mode).
+ * @since Ant 1.9.4
+ */
+ public void setThread(int thread) {
+ this.antThreadID = thread;
+ }
+
+ /**
+ * Set the name of the output file.
+ * @param value the name of the output file to use.
+ */
+ public void setOutfile(String value) {
+ outfile = value;
+ }
+
+ /**
+ * Informs whether a list of test methods has been specified in this test.
+ * @return <code>true</code> if test methods to be executed have been
+ * specified, <code>false</code> otherwise
+ * @see #setMethods(java.lang.String)
+ * @see #setMethods(java.lang.String[])
+ * @since 1.8.2
+ */
+ boolean hasMethodsSpecified() {
+ return methodsSpecified;
+ }
+
+ /**
+ * Get names of individual test methods to be executed.
+ *
+ * @return array of names of the individual test methods to be executed,
+ * or <code>null</code> if all test methods in the suite
+ * defined by the test class will be executed
+ * @since 1.8.2
+ */
+ String[] getMethods() {
+ if (methodsSpecified && (methods == null)) {
+ resolveMethods();
+ }
+ return methods;
+ }
+
+ /**
+ * Gets a comma-separated list of names of methods that are to be executed
+ * by this test.
+ * @return the comma-separated list of test method names, or an empty
+ * string of no method is to be executed, or <code>null</code>
+ * if no method is specified
+ * @since 1.8.2
+ */
+ String getMethodsString() {
+ if ((methodsList == null) && methodsSpecified) {
+ if (methods.length == 0) {
+ methodsList = "";
+ } else if (methods.length == 1) {
+ methodsList = methods[0];
+ } else {
+ StringBuffer buf = new StringBuffer(methods.length * 16);
+ buf.append(methods[0]);
+ for (int i = 1; i < methods.length; i++) {
+ buf.append(',').append(methods[i]);
+ }
+ methodsList = buf.toString();
+ }
+ }
+ return methodsList;
+ }
+
+ /**
+ * Computes the value of the {@link #methods} field from the value
+ * of the {@link #methodsList} field, if it has not been computed yet.
+ * @exception BuildException if the value of the {@link #methodsList} field
+ * was invalid
+ * @since 1.8.2
+ */
+ void resolveMethods() {
+ if ((methods == null) && methodsSpecified) {
+ try {
+ methods = parseTestMethodNamesList(methodsList);
+ } catch (IllegalArgumentException ex) {
+ throw new BuildException(
+ "Invalid specification of test methods: \""
+ + methodsList
+ + "\"; expected: comma-separated list of valid Java identifiers",
+ ex);
+ }
+ }
+ }
+
+ /**
+ * Parses a comma-separated list of method names and check their validity.
+ * @param methodNames comma-separated list of method names to be parsed
+ * @return array of individual test method names
+ * @exception java.lang.IllegalArgumentException
+ * if the given string is <code>null</code> or if it is not
+ * a comma-separated list of valid Java identifiers;
+ * an empty string is acceptable and is handled as an empty
+ * list
+ * @since 1.8.2
+ */
+ public static String[] parseTestMethodNamesList(String methodNames)
+ throws IllegalArgumentException {
+ if (methodNames == null) {
+ throw new IllegalArgumentException("methodNames is <null>");
+ }
+
+ methodNames = methodNames.trim();
+
+ int length = methodNames.length();
+ if (length == 0) {
+ return new String[0];
+ }
+
+ /* strip the trailing comma, if any */
+ if (methodNames.charAt(length - 1) == ',') {
+ methodNames = methodNames.substring(0, length - 1).trim();
+ length = methodNames.length();
+ if (length == 0) {
+ throw new IllegalArgumentException("Empty method name");
+ }
+ }
+
+ final char[] chars = methodNames.toCharArray();
+ /* easy detection of one particular case of illegal string: */
+ if (chars[0] == ',') {
+ throw new IllegalArgumentException("Empty method name");
+ }
+ /* count number of method names: */
+ int wordCount = 1;
+ for (int i = 1; i < chars.length; i++) {
+ if (chars[i] == ',') {
+ wordCount++;
+ }
+ }
+ /* prepare the resulting array: */
+ String[] result = new String[wordCount];
+ /* parse the string: */
+ final int stateBeforeWord = 1;
+ final int stateInsideWord = 2;
+ final int stateAfterWord = 3;
+ //
+ int state = stateBeforeWord;
+ int wordStartIndex = -1;
+ int wordIndex = 0;
+ for (int i = 0; i < chars.length; i++) {
+ char c = chars[i];
+ switch (state) {
+ case stateBeforeWord:
+ if (c == ',') {
+ throw new IllegalArgumentException("Empty method name");
+ } else if (c == ' ') {
+ // remain in the same state
+ } else if (Character.isJavaIdentifierStart(c)) {
+ wordStartIndex = i;
+ state = stateInsideWord;
+ } else {
+ throw new IllegalArgumentException("Illegal start of method name: " + c);
+ }
+ break;
+ case stateInsideWord:
+ if (c == ',') {
+ result[wordIndex++] = methodNames.substring(wordStartIndex, i);
+ state = stateBeforeWord;
+ } else if (c == ' ') {
+ result[wordIndex++] = methodNames.substring(wordStartIndex, i);
+ state = stateAfterWord;
+ } else if (Character.isJavaIdentifierPart(c)) {
+ // remain in the same state
+ } else {
+ throw new IllegalArgumentException("Illegal character in method name: " + c);
+ }
+ break;
+ case stateAfterWord:
+ if (c == ',') {
+ state = stateBeforeWord;
+ } else if (c == ' ') {
+ // remain in the same state
+ } else {
+ throw new IllegalArgumentException("Space in method name");
+ }
+ break;
+ default:
+ // this should never happen
+ }
+ }
+ switch (state) {
+ case stateBeforeWord:
+ case stateAfterWord:
+ break;
+ case stateInsideWord:
+ result[wordIndex++] = methodNames.substring(wordStartIndex, chars.length);
+ break;
+ default:
+ // this should never happen
+ }
+ return result;
+ }
+
+ /**
+ * Get the name of the test class.
+ * @return the name of the test.
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Get the Ant id of the thread running the test.
+ * @return the thread id
+ */
+ public int getThread() {
+ return antThreadID;
+ }
+
+ /**
+ * Get the name of the output file
+ *
+ * @return the name of the output file.
+ */
+ public String getOutfile() {
+ return outfile;
+ }
+
+ /**
+ * Set the number of runs, failures, errors, and skipped tests.
+ * @param runs the number of runs.
+ * @param failures the number of failures.
+ * @param errors the number of errors.
+ * Kept for backward compatibility with Ant 1.8.4
+ */
+ public void setCounts(long runs, long failures, long errors) {
+ this.runs = runs;
+ this.failures = failures;
+ this.errors = errors;
+ }
+ /**
+ * Set the number of runs, failures, errors, and skipped tests.
+ * @param runs the number of runs.
+ * @param failures the number of failures.
+ * @param errors the number of errors.
+ * @param skips the number of skipped tests.
+ * @since Ant 1.9.0
+ */
+ public void setCounts(long runs, long failures, long errors, long skips) {
+ this.runs = runs;
+ this.failures = failures;
+ this.errors = errors;
+ this.skips = skips;
+ }
+
+ /**
+ * Set the runtime.
+ * @param runTime the time in milliseconds.
+ */
+ public void setRunTime(long runTime) {
+ this.runTime = runTime;
+ }
+
+ /**
+ * Get the number of runs.
+ * @return the number of runs.
+ */
+ public long runCount() {
+ return runs;
+ }
+
+ /**
+ * Get the number of failures.
+ * @return the number of failures.
+ */
+ public long failureCount() {
+ return failures;
+ }
+
+ /**
+ * Get the number of errors.
+ * @return the number of errors.
+ */
+ public long errorCount() {
+ return errors;
+ }
+
+ /**
+ * Get the number of skipped tests.
+ * @return the number of skipped tests.
+ */
+ public long skipCount() {
+ return skips;
+ }
+
+ /**
+ * Get the run time.
+ * @return the run time in milliseconds.
+ */
+ public long getRunTime() {
+ return runTime;
+ }
+
+ /**
+ * Get the properties used in the test.
+ * @return the properties.
+ */
+ public Properties getProperties() {
+ return props;
+ }
+
+ /**
+ * Set the properties to be used in the test.
+ * @param p the properties.
+ * This is a copy of the projects ant properties.
+ */
+ public void setProperties(Hashtable p) {
+ props = new Properties();
+ for (Enumeration e = p.keys(); e.hasMoreElements();) {
+ Object key = e.nextElement();
+ props.put(key, p.get(key));
+ }
+ }
+
+ /**
+ * Check if this test should run based on the if and unless
+ * attributes.
+ * @param p the project to use to check if the if and unless
+ * properties exist in.
+ * @return true if this test or testsuite should be run.
+ */
+ public boolean shouldRun(Project p) {
+ PropertyHelper ph = PropertyHelper.getPropertyHelper(p);
+ return ph.testIfCondition(getIfCondition())
+ && ph.testUnlessCondition(getUnlessCondition());
+ }
+
+ /**
+ * Get the formatters set for this test.
+ * @return the formatters as an array.
+ */
+ public FormatterElement[] getFormatters() {
+ FormatterElement[] fes = new FormatterElement[formatters.size()];
+ formatters.copyInto(fes);
+ return fes;
+ }
+
+ /**
+ * Convenient method to add formatters to a vector
+ */
+ void addFormattersTo(Vector v) {
+ final int count = formatters.size();
+ for (int i = 0; i < count; i++) {
+ v.addElement(formatters.elementAt(i));
+ }
+ }
+
+ /**
+ * @since Ant 1.5
+ * @return a clone of this test.
+ */
+ @Override
+ public Object clone() {
+ try {
+ JUnitTest t = (JUnitTest) super.clone();
+ t.props = props == null ? null : (Properties) props.clone();
+ t.formatters = (Vector) formatters.clone();
+ return t;
+ } catch (CloneNotSupportedException e) {
+ // plain impossible
+ return this;
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTestRunner.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTestRunner.java
new file mode 100644
index 00000000..a457375e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTestRunner.java
@@ -0,0 +1,1297 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.junit;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Properties;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import junit.framework.AssertionFailedError;
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestFailure;
+import junit.framework.TestListener;
+import junit.framework.TestResult;
+import junit.framework.TestSuite;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.Permissions;
+import org.apache.tools.ant.util.FileUtils;
+import org.apache.tools.ant.util.StringUtils;
+import org.apache.tools.ant.util.TeeOutputStream;
+
+/**
+ * Simple Testrunner for JUnit that runs all tests of a testsuite.
+ *
+ * <p>This TestRunner expects a name of a TestCase class as its
+ * argument. If this class provides a static suite() method it will be
+ * called and the resulting Test will be run. So, the signature should be
+ * <pre><code>
+ * public static junit.framework.Test suite()
+ * </code></pre>
+ *
+ * <p> If no such method exists, all public methods starting with
+ * "test" and taking no argument will be run.
+ *
+ * <p> Summary output is generated at the end.
+ *
+ * @since Ant 1.2
+ */
+
+public class JUnitTestRunner implements TestListener, JUnitTaskMirror.JUnitTestRunnerMirror {
+
+ /**
+ * Holds the registered formatters.
+ */
+ private final Vector<JUnitTaskMirror.JUnitResultFormatterMirror> formatters = new Vector();
+
+ /**
+ * Collects TestResults.
+ */
+ private IgnoredTestResult res;
+
+ /**
+ * Do we filter junit.*.* stack frames out of failure and error exceptions.
+ */
+ private static boolean filtertrace = true;
+
+ /**
+ * Do we send output to System.out/.err in addition to the formatters?
+ */
+ private boolean showOutput = false;
+
+ private boolean outputToFormatters = true;
+
+ /**
+ * The permissions set for the test to run.
+ */
+ private Permissions perm = null;
+
+ private static final String JUNIT_4_TEST_ADAPTER
+ = "junit.framework.JUnit4TestAdapter";
+
+ private static final String[] DEFAULT_TRACE_FILTERS = new String[] {
+ "junit.framework.TestCase",
+ "junit.framework.TestResult",
+ "junit.framework.TestSuite",
+ "junit.framework.Assert.", // don't filter AssertionFailure
+ "junit.swingui.TestRunner",
+ "junit.awtui.TestRunner",
+ "junit.textui.TestRunner",
+ "java.lang.reflect.Method.invoke(",
+ "sun.reflect.",
+ "org.apache.tools.ant.",
+ // JUnit 4 support:
+ "org.junit.",
+ "junit.framework.JUnit4TestAdapter",
+ " more",
+ };
+
+
+ /**
+ * Do we stop on errors.
+ */
+ private boolean haltOnError = false;
+
+ /**
+ * Do we stop on test failures.
+ */
+ private boolean haltOnFailure = false;
+
+ /**
+ * Returncode
+ */
+ private int retCode = SUCCESS;
+
+ /**
+ * The TestSuite we are currently running.
+ */
+ private final JUnitTest junitTest;
+
+ /** output written during the test */
+ private PrintStream systemError;
+
+ /** Error output during the test */
+ private PrintStream systemOut;
+
+ /** is this runner running in forked mode? */
+ private boolean forked = false;
+
+ /** Running more than one test suite? */
+ private static boolean multipleTests = false;
+
+ /** ClassLoader passed in in non-forked mode. */
+ private final ClassLoader loader;
+
+ /** Do we print TestListener events? */
+ private boolean logTestListenerEvents = false;
+
+ /** Turned on if we are using JUnit 4 for this test suite. see #38811 */
+ private boolean junit4;
+
+ /**
+ * The file used to indicate that the build crashed.
+ * File will be empty in case the build did not crash.
+ */
+ private static String crashFile = null;
+
+ /** Names of test methods to execute */
+ private String[] methods = null;
+
+ /**
+ * Constructor for fork=true or when the user hasn't specified a
+ * classpath.
+ * @param test the test to run.
+ * @param haltOnError whether to stop the run if an error is found.
+ * @param filtertrace whether to filter junit.*.* stack frames out of exceptions
+ * @param haltOnFailure whether to stop the run if failure is found.
+ */
+ public JUnitTestRunner(final JUnitTest test, final boolean haltOnError,
+ final boolean filtertrace, final boolean haltOnFailure) {
+ this(test, haltOnError, filtertrace, haltOnFailure, false);
+ }
+
+ /**
+ * Constructor for fork=true or when the user hasn't specified a
+ * classpath.
+ * @param test the test to run.
+ * @param haltOnError whether to stop the run if an error is found.
+ * @param filtertrace whether to filter junit.*.* stack frames out of exceptions
+ * @param haltOnFailure whether to stop the run if failure is found.
+ * @param showOutput whether to send output to System.out/.err as well as formatters.
+ */
+ public JUnitTestRunner(final JUnitTest test, final boolean haltOnError,
+ final boolean filtertrace, final boolean haltOnFailure,
+ final boolean showOutput) {
+ this(test, haltOnError, filtertrace, haltOnFailure, showOutput, false);
+ }
+
+ /**
+ * Constructor for fork=true or when the user hasn't specified a
+ * classpath.
+ * @param test the test to run.
+ * @param haltOnError whether to stop the run if an error is found.
+ * @param filtertrace whether to filter junit.*.* stack frames out of exceptions
+ * @param haltOnFailure whether to stop the run if failure is found.
+ * @param showOutput whether to send output to System.out/.err as well as formatters.
+ * @param logTestListenerEvents whether to print TestListener events.
+ * @since Ant 1.7
+ */
+ public JUnitTestRunner(final JUnitTest test, final boolean haltOnError,
+ final boolean filtertrace, final boolean haltOnFailure,
+ final boolean showOutput, final boolean logTestListenerEvents) {
+ this(test, null, haltOnError, filtertrace, haltOnFailure, showOutput,
+ logTestListenerEvents, null);
+ }
+
+ /**
+ * Constructor for fork=true or when the user hasn't specified a
+ * classpath.
+ * @param test the test to run.
+ * @param methods names of methods of the test to be executed.
+ * @param haltOnError whether to stop the run if an error is found.
+ * @param filtertrace whether to filter junit.*.* stack frames out of exceptions
+ * @param haltOnFailure whether to stop the run if failure is found.
+ * @param showOutput whether to send output to System.out/.err as well as formatters.
+ * @param logTestListenerEvents whether to print TestListener events.
+ * @since 1.8.2
+ */
+ public JUnitTestRunner(final JUnitTest test, final String[] methods, final boolean haltOnError,
+ final boolean filtertrace, final boolean haltOnFailure,
+ final boolean showOutput, final boolean logTestListenerEvents) {
+ this(test, methods, haltOnError, filtertrace, haltOnFailure, showOutput,
+ logTestListenerEvents, null);
+ }
+
+ /**
+ * Constructor to use when the user has specified a classpath.
+ * @param test the test to run.
+ * @param haltOnError whether to stop the run if an error is found.
+ * @param filtertrace whether to filter junit.*.* stack frames out of exceptions
+ * @param haltOnFailure whether to stop the run if failure is found.
+ * @param loader the classloader to use running the test.
+ */
+ public JUnitTestRunner(final JUnitTest test, final boolean haltOnError,
+ final boolean filtertrace, final boolean haltOnFailure,
+ final ClassLoader loader) {
+ this(test, haltOnError, filtertrace, haltOnFailure, false, loader);
+ }
+
+ /**
+ * Constructor to use when the user has specified a classpath.
+ * @param test the test to run.
+ * @param haltOnError whether to stop the run if an error is found.
+ * @param filtertrace whether to filter junit.*.* stack frames out of exceptions
+ * @param haltOnFailure whether to stop the run if failure is found.
+ * @param showOutput whether to send output to System.out/.err as well as formatters.
+ * @param loader the classloader to use running the test.
+ */
+ public JUnitTestRunner(final JUnitTest test, final boolean haltOnError,
+ final boolean filtertrace, final boolean haltOnFailure,
+ final boolean showOutput, final ClassLoader loader) {
+ this(test, haltOnError, filtertrace, haltOnFailure, showOutput,
+ false, loader);
+ }
+
+ /**
+ * Constructor to use when the user has specified a classpath.
+ * @param test the test to run.
+ * @param haltOnError whether to stop the run if an error is found.
+ * @param filtertrace whether to filter junit.*.* stack frames out of exceptions
+ * @param haltOnFailure whether to stop the run if failure is found.
+ * @param showOutput whether to send output to System.out/.err as well as formatters.
+ * @param logTestListenerEvents whether to print TestListener events.
+ * @param loader the classloader to use running the test.
+ * @since Ant 1.7
+ */
+ public JUnitTestRunner(final JUnitTest test, final boolean haltOnError,
+ final boolean filtertrace, final boolean haltOnFailure,
+ final boolean showOutput, final boolean logTestListenerEvents,
+ final ClassLoader loader) {
+ this(test, null, haltOnError, filtertrace, haltOnFailure, showOutput,
+ logTestListenerEvents, loader);
+ }
+
+
+ /**
+ * Constructor to use when the user has specified a classpath.
+ * @since 1.8.2
+ */
+ public JUnitTestRunner(final JUnitTest test, final String[] methods, final boolean haltOnError,
+ final boolean filtertrace, final boolean haltOnFailure,
+ final boolean showOutput, final boolean logTestListenerEvents,
+ final ClassLoader loader) {
+ super();
+ JUnitTestRunner.filtertrace = filtertrace; // TODO clumsy, should use instance field somehow
+ this.junitTest = test;
+ this.haltOnError = haltOnError;
+ this.haltOnFailure = haltOnFailure;
+ this.showOutput = showOutput;
+ this.logTestListenerEvents = logTestListenerEvents;
+ this.methods = methods != null ? (String[]) methods.clone() : null;
+ this.loader = loader;
+ }
+
+ private PrintStream savedOut = null;
+ private PrintStream savedErr = null;
+
+ private PrintStream createEmptyStream() {
+ return new PrintStream(
+ new OutputStream() {
+ @Override
+ public void write(final int b) {
+ }
+ });
+ }
+
+ private PrintStream createTeePrint(final PrintStream ps1, final PrintStream ps2) {
+ return new PrintStream(new TeeOutputStream(ps1, ps2));
+ }
+
+ private void setupIOStreams(final ByteArrayOutputStream o,
+ final ByteArrayOutputStream e) {
+ systemOut = new PrintStream(o);
+ systemError = new PrintStream(e);
+
+ if (forked) {
+ if (!outputToFormatters) {
+ if (!showOutput) {
+ savedOut = System.out;
+ savedErr = System.err;
+ System.setOut(createEmptyStream());
+ System.setErr(createEmptyStream());
+ }
+ } else {
+ savedOut = System.out;
+ savedErr = System.err;
+ if (!showOutput) {
+ System.setOut(systemOut);
+ System.setErr(systemError);
+ } else {
+ System.setOut(createTeePrint(savedOut, systemOut));
+ System.setErr(createTeePrint(savedErr, systemError));
+ }
+ perm = null;
+ }
+ } else {
+ if (perm != null) {
+ perm.setSecurityManager();
+ }
+ }
+ }
+
+ /**
+ * Run the test.
+ */
+ public void run() {
+ res = new IgnoredTestResult();
+ res.addListener(wrapListener(this));
+ final int size = formatters.size();
+ for (int i = 0; i < size; i++) {
+ res.addListener(wrapListener((TestListener) formatters.elementAt(i)));
+ }
+
+ final ByteArrayOutputStream errStrm = new ByteArrayOutputStream();
+ final ByteArrayOutputStream outStrm = new ByteArrayOutputStream();
+
+ setupIOStreams(outStrm, errStrm);
+
+ Test suite = null;
+ Throwable exception = null;
+ boolean startTestSuiteSuccess = false;
+
+ try {
+
+ try {
+ Class testClass = null;
+ if (loader == null) {
+ testClass = Class.forName(junitTest.getName());
+ } else {
+ testClass = Class.forName(junitTest.getName(), true,
+ loader);
+ }
+
+ final boolean testMethodsSpecified = (methods != null);
+
+ // check for a static suite method first, even when using
+ // JUnit 4
+ Method suiteMethod = null;
+ if (!testMethodsSpecified) {
+ try {
+ // check if there is a suite method
+ suiteMethod = testClass.getMethod("suite", new Class[0]);
+ } catch (final NoSuchMethodException e) {
+ // no appropriate suite method found. We don't report any
+ // error here since it might be perfectly normal.
+ }
+ }
+
+ if (suiteMethod != null) {
+ // if there is a suite method available, then try
+ // to extract the suite from it. If there is an error
+ // here it will be caught below and reported.
+ suite = (Test) suiteMethod.invoke(null, new Object[0]);
+
+ } else {
+ Class junit4TestAdapterClass = null;
+ Class junit4TestAdapterCacheClass = null;
+ boolean useSingleMethodAdapter = false;
+
+ if (junit.framework.TestCase.class.isAssignableFrom(testClass)) {
+ // Do not use JUnit 4 API for running JUnit 3.x
+ // tests - it is not able to run individual test
+ // methods.
+ //
+ // Technical details:
+ // org.junit.runner.Request.method(Class, String).getRunner()
+ // would return a runner which always executes all
+ // test methods. The reason is that the Runner would be
+ // an instance of class
+ // org.junit.internal.runners.OldTestClassRunner
+ // that does not implement interface Filterable - so it
+ // is unable to filter out test methods not matching
+ // the requested name.
+ } else {
+ // Check for JDK 5 first. Will *not* help on JDK 1.4
+ // if only junit-4.0.jar in CP because in that case
+ // linkage of whole task will already have failed! But
+ // will help if CP has junit-3.8.2.jar:junit-4.0.jar.
+
+ // In that case first C.fN will fail with CNFE and we
+ // will avoid UnsupportedClassVersionError.
+
+ try {
+ Class.forName("java.lang.annotation.Annotation");
+ junit4TestAdapterCacheClass = Class.forName("org.apache.tools.ant.taskdefs.optional.junit.CustomJUnit4TestAdapterCache");
+ if (loader == null) {
+ junit4TestAdapterClass =
+ Class.forName(JUNIT_4_TEST_ADAPTER);
+ if (testMethodsSpecified) {
+ /*
+ * We cannot try to load the JUnit4TestAdapter
+ * before trying to load JUnit4TestMethodAdapter
+ * because it might fail with
+ * NoClassDefFoundException, instead of plain
+ * ClassNotFoundException.
+ */
+ junit4TestAdapterClass = Class.forName(
+ "org.apache.tools.ant.taskdefs.optional.junit.JUnit4TestMethodAdapter");
+ useSingleMethodAdapter = true;
+ }
+ } else {
+ junit4TestAdapterClass =
+ Class.forName(JUNIT_4_TEST_ADAPTER,
+ true, loader);
+ if (testMethodsSpecified) {
+ junit4TestAdapterClass =
+ Class.forName(
+ "org.apache.tools.ant.taskdefs.optional.junit.JUnit4TestMethodAdapter",
+ true, loader);
+ useSingleMethodAdapter = true;
+ }
+ }
+ } catch (final ClassNotFoundException e) {
+ // OK, fall back to JUnit 3.
+ }
+ }
+ junit4 = junit4TestAdapterClass != null;
+
+ if (junitTest.isSkipNonTests()) {
+ if (!containsTests(testClass, junit4)) {
+ return;
+ }
+ }
+
+
+ if (junit4) {
+ // Let's use it!
+ Class[] formalParams;
+ Object[] actualParams;
+ if (useSingleMethodAdapter) {
+ formalParams = new Class[] {Class.class, String[].class};
+ actualParams = new Object[] {testClass, methods};
+ } else {
+ formalParams = new Class[] {Class.class, Class.forName("junit.framework.JUnit4TestAdapterCache")};
+ actualParams = new Object[] {testClass, junit4TestAdapterCacheClass.getMethod("getInstance").invoke(null)};
+ }
+ suite =
+ (Test) junit4TestAdapterClass
+ .getConstructor(formalParams).
+ newInstance(actualParams);
+ } else {
+ // Use JUnit 3.
+
+ // try to extract a test suite automatically this
+ // will generate warnings if the class is no
+ // suitable Test
+ if (!testMethodsSpecified) {
+ suite = new TestSuite(testClass);
+ } else if (methods.length == 1) {
+ suite = TestSuite.createTest(testClass, methods[0]);
+ } else {
+ final TestSuite testSuite = new TestSuite(testClass.getName());
+ for (int i = 0; i < methods.length; i++) {
+ testSuite.addTest(
+ TestSuite.createTest(testClass, methods[i]));
+ }
+ suite = testSuite;
+ }
+ }
+
+ }
+
+ } catch (final Throwable e) {
+ retCode = ERRORS;
+ exception = e;
+ }
+
+ final long start = System.currentTimeMillis();
+
+ fireStartTestSuite();
+ startTestSuiteSuccess = true;
+ if (exception != null) { // had an exception constructing suite
+ final int formatterSize = formatters.size();
+ for (int i = 0; i < formatterSize; i++) {
+ ((TestListener) formatters.elementAt(i))
+ .addError(null, exception);
+ }
+ junitTest.setCounts(1, 0, 1, 0);
+ junitTest.setRunTime(0);
+ } else {
+ try {
+ logTestListenerEvent("tests to run: " + suite.countTestCases());
+ suite.run(res);
+ } finally {
+ if (junit4 ||
+ suite.getClass().getName().equals(JUNIT_4_TEST_ADAPTER)) {
+ final int[] cnts = findJUnit4FailureErrorCount(res);
+ junitTest.setCounts(res.runCount() + res.ignoredCount(), cnts[0], cnts[1], res.ignoredCount() + res.skippedCount());
+ } else {
+ junitTest.setCounts(res.runCount() + res.ignoredCount(), res.failureCount(),
+ res.errorCount(), res.ignoredCount() + res.skippedCount());
+ }
+ junitTest.setRunTime(System.currentTimeMillis() - start);
+ }
+ }
+ } finally {
+ if (perm != null) {
+ perm.restoreSecurityManager();
+ }
+ if (savedOut != null) {
+ System.setOut(savedOut);
+ }
+ if (savedErr != null) {
+ System.setErr(savedErr);
+ }
+
+ systemError.close();
+ systemError = null;
+ systemOut.close();
+ systemOut = null;
+ if (startTestSuiteSuccess) {
+ String out, err;
+ try {
+ out = new String(outStrm.toByteArray());
+ } catch (final OutOfMemoryError ex) {
+ out = "out of memory on output stream";
+ }
+ try {
+ err = new String(errStrm.toByteArray());
+ } catch (final OutOfMemoryError ex) {
+ err = "out of memory on error stream";
+ }
+ sendOutAndErr(out, err);
+ }
+ }
+ fireEndTestSuite();
+
+ // junitTest has the correct counts for JUnit4, while res doesn't
+ if (retCode != SUCCESS || junitTest.errorCount() != 0) {
+ retCode = ERRORS;
+ } else if (junitTest.failureCount() != 0) {
+ retCode = FAILURES;
+ }
+ }
+
+ private static boolean containsTests(final Class<?> testClass, final boolean isJUnit4) {
+ Class testAnnotation = null;
+ Class suiteAnnotation = null;
+ Class runWithAnnotation = null;
+
+ try {
+ testAnnotation = Class.forName("org.junit.Test");
+ } catch (final ClassNotFoundException e) {
+ if (isJUnit4) {
+ // odd - we think we're JUnit4 but don't support the test annotation. We therefore can't have any tests!
+ return false;
+ }
+ // else... we're a JUnit3 test and don't need the annotation
+ }
+
+ try {
+ suiteAnnotation = Class.forName("org.junit.Suite.SuiteClasses");
+ } catch(final ClassNotFoundException ex) {
+ // ignore - we don't have this annotation so make sure we don't check for it
+ }
+ try {
+ runWithAnnotation = Class.forName("org.junit.runner.RunWith");
+ } catch(final ClassNotFoundException ex) {
+ // also ignore as this annotation doesn't exist so tests can't use it
+ }
+
+
+ if (!isJUnit4 && !TestCase.class.isAssignableFrom(testClass)) {
+ //a test we think is JUnit3 but does not extend TestCase. Can't really be a test.
+ return false;
+ }
+
+ // check if we have any inner classes that contain suitable test methods
+ for (final Class<?> innerClass : testClass.getDeclaredClasses()) {
+ if (containsTests(innerClass, isJUnit4) || containsTests(innerClass, !isJUnit4)) {
+ return true;
+ }
+ }
+
+ if (Modifier.isAbstract(testClass.getModifiers()) || Modifier.isInterface(testClass.getModifiers())) {
+ // can't instantiate class and no inner classes are tests either
+ return false;
+ }
+
+ if (isJUnit4) {
+ if (suiteAnnotation != null && testClass.getAnnotation(suiteAnnotation) != null) {
+ // class is marked as a suite. Let JUnit try and work its magic on it.
+ return true;
+ }
+ if (runWithAnnotation != null && testClass.getAnnotation(runWithAnnotation) != null) {
+ /* Class is marked with @RunWith. If this class is badly written (no test methods, multiple
+ * constructors, private constructor etc) then the class is automatically run and fails in the
+ * IDEs I've tried... so I'm happy handing the class to JUnit to try and run, and let JUnit
+ * report a failure if a bad test case is provided. Trying to do anything else is likely to
+ * result in us filtering out cases that could be valid for future versions of JUnit so would
+ * just increase future maintenance work.
+ */
+ return true;
+ }
+ }
+
+ for (final Method m : testClass.getMethods()) {
+ if (isJUnit4) {
+ // check if suspected JUnit4 classes have methods with @Test annotation
+ if (m.getAnnotation(testAnnotation) != null) {
+ return true;
+ }
+ } else {
+ // check if JUnit3 class have public or protected no-args methods starting with names starting with test
+ if (m.getName().startsWith("test") && m.getParameterTypes().length == 0
+ && (Modifier.isProtected(m.getModifiers()) || Modifier.isPublic(m.getModifiers()))) {
+ return true;
+ }
+ }
+ // check if JUnit3 or JUnit4 test have a public or protected, static,
+ // no-args 'suite' method
+ if (m.getName().equals("suite") && m.getParameterTypes().length == 0
+ && (Modifier.isProtected(m.getModifiers()) || Modifier.isPublic(m.getModifiers()))
+ && Modifier.isStatic(m.getModifiers())) {
+ return true;
+ }
+ }
+
+ // no test methods found
+ return false;
+ }
+
+ /**
+ * Returns what System.exit() would return in the standalone version.
+ *
+ * @return 2 if errors occurred, 1 if tests failed else 0.
+ */
+ public int getRetCode() {
+ return retCode;
+ }
+
+ /**
+ * Interface TestListener.
+ *
+ * <p>A new Test is started.
+ * @param t the test.
+ */
+ public void startTest(final Test t) {
+ final String testName = JUnitVersionHelper.getTestCaseName(t);
+ logTestListenerEvent("startTest(" + testName + ")");
+ }
+
+ /**
+ * Interface TestListener.
+ *
+ * <p>A Test is finished.
+ * @param test the test.
+ */
+ public void endTest(final Test test) {
+ final String testName = JUnitVersionHelper.getTestCaseName(test);
+ logTestListenerEvent("endTest(" + testName + ")");
+ }
+
+ private void logTestListenerEvent(String msg) {
+ if (logTestListenerEvents) {
+ final PrintStream out = savedOut != null ? savedOut : System.out;
+ out.flush();
+ if (msg == null) {
+ msg = "null";
+ }
+ final StringTokenizer msgLines = new StringTokenizer(msg, "\r\n", false);
+ while (msgLines.hasMoreTokens()) {
+ out.println(JUnitTask.TESTLISTENER_PREFIX
+ + msgLines.nextToken());
+ }
+ out.flush();
+ }
+ }
+
+ /**
+ * Interface TestListener for JUnit &lt;= 3.4.
+ *
+ * <p>A Test failed.
+ * @param test the test.
+ * @param t the exception thrown by the test.
+ */
+ public void addFailure(final Test test, final Throwable t) {
+ final String testName = JUnitVersionHelper.getTestCaseName(test);
+ logTestListenerEvent("addFailure(" + testName + ", " + t.getMessage() + ")");
+ if (haltOnFailure) {
+ res.stop();
+ }
+ }
+
+ /**
+ * Interface TestListener for JUnit &gt; 3.4.
+ *
+ * <p>A Test failed.
+ * @param test the test.
+ * @param t the assertion thrown by the test.
+ */
+ public void addFailure(final Test test, final AssertionFailedError t) {
+ addFailure(test, (Throwable) t);
+ }
+
+ /**
+ * Interface TestListener.
+ *
+ * <p>An error occurred while running the test.
+ * @param test the test.
+ * @param t the error thrown by the test.
+ */
+ public void addError(final Test test, final Throwable t) {
+ final String testName = JUnitVersionHelper.getTestCaseName(test);
+ logTestListenerEvent("addError(" + testName + ", " + t.getMessage() + ")");
+ if (haltOnError) {
+ res.stop();
+ }
+ }
+
+ /**
+ * Permissions for the test run.
+ * @since Ant 1.6
+ * @param permissions the permissions to use.
+ */
+ public void setPermissions(final Permissions permissions) {
+ perm = permissions;
+ }
+
+ /**
+ * Handle a string destined for standard output.
+ * @param output the string to output
+ */
+ public void handleOutput(final String output) {
+ if (!logTestListenerEvents && output.startsWith(JUnitTask.TESTLISTENER_PREFIX)) {
+ // ignore
+ } else if (systemOut != null) {
+ systemOut.print(output);
+ }
+ }
+
+ /**
+ * Handle input.
+ * @param buffer not used.
+ * @param offset not used.
+ * @param length not used.
+ * @return -1 always.
+ * @throws IOException never.
+ * @see org.apache.tools.ant.Task#handleInput(byte[], int, int)
+ *
+ * @since Ant 1.6
+ */
+ public int handleInput(final byte[] buffer, final int offset, final int length)
+ throws IOException {
+ return -1;
+ }
+
+ /** {@inheritDoc}. */
+ public void handleErrorOutput(final String output) {
+ if (systemError != null) {
+ systemError.print(output);
+ }
+ }
+
+ /** {@inheritDoc}. */
+ public void handleFlush(final String output) {
+ if (systemOut != null) {
+ systemOut.print(output);
+ }
+ }
+
+ /** {@inheritDoc}. */
+ public void handleErrorFlush(final String output) {
+ if (systemError != null) {
+ systemError.print(output);
+ }
+ }
+
+ private void sendOutAndErr(final String out, final String err) {
+ final int size = formatters.size();
+ for (int i = 0; i < size; i++) {
+ final JUnitResultFormatter formatter =
+ ((JUnitResultFormatter) formatters.elementAt(i));
+
+ formatter.setSystemOutput(out);
+ formatter.setSystemError(err);
+ }
+ }
+
+ private void fireStartTestSuite() {
+ final int size = formatters.size();
+ for (int i = 0; i < size; i++) {
+ ((JUnitResultFormatter) formatters.elementAt(i))
+ .startTestSuite(junitTest);
+ }
+ }
+
+ private void fireEndTestSuite() {
+ final int size = formatters.size();
+ for (int i = 0; i < size; i++) {
+ ((JUnitResultFormatter) formatters.elementAt(i))
+ .endTestSuite(junitTest);
+ }
+ }
+
+ /**
+ * Add a formatter.
+ * @param f the formatter to add.
+ */
+ public void addFormatter(final JUnitResultFormatter f) {
+ formatters.addElement(f);
+ }
+
+ /** {@inheritDoc}. */
+ public void addFormatter(final JUnitTaskMirror.JUnitResultFormatterMirror f) {
+ formatters.addElement(f);
+ }
+
+ /**
+ * Entry point for standalone (forked) mode.
+ *
+ * Parameters: testcaseclassname plus parameters in the format
+ * key=value, none of which is required.
+ *
+ * <table cols="4" border="1">
+ * <tr><th>key</th><th>description</th><th>default value</th></tr>
+ *
+ * <tr><td>haltOnError</td><td>halt test on
+ * errors?</td><td>false</td></tr>
+ *
+ * <tr><td>haltOnFailure</td><td>halt test on
+ * failures?</td><td>false</td></tr>
+ *
+ * <tr><td>formatter</td><td>A JUnitResultFormatter given as
+ * classname,filename. If filename is omitted, System.out is
+ * assumed.</td><td>none</td></tr>
+ *
+ * <tr><td>showoutput</td><td>send output to System.err/.out as
+ * well as to the formatters?</td><td>false</td></tr>
+ *
+ * <tr><td>logtestlistenerevents</td><td>log TestListener events to
+ * System.out.</td><td>false</td></tr>
+ *
+ * <tr><td>methods</td><td>Comma-separated list of names of individual
+ * test methods to execute.
+ * </td><td>null</td></tr>
+ *
+ * </table>
+ * @param args the command line arguments.
+ * @throws IOException on error.
+ */
+ public static void main(final String[] args) throws IOException {
+ String[] methods = null;
+ boolean haltError = false;
+ boolean haltFail = false;
+ boolean stackfilter = true;
+ final Properties props = new Properties();
+ boolean showOut = false;
+ boolean outputToFormat = true;
+ boolean logFailedTests = true;
+ boolean logTestListenerEvents = false;
+ boolean skipNonTests = false;
+ int antThreadID = 0; /* Ant id of thread running this unit test, 0 in single-threaded mode */
+
+ if (args.length == 0) {
+ System.err.println("required argument TestClassName missing");
+ System.exit(ERRORS);
+ }
+
+ if (args[0].startsWith(Constants.TESTSFILE)) {
+ multipleTests = true;
+ args[0] = args[0].substring(Constants.TESTSFILE.length());
+ }
+
+ for (int i = 1; i < args.length; i++) {
+ if (args[i].startsWith(Constants.METHOD_NAMES)) {
+ try {
+ final String methodsList = args[i].substring(Constants.METHOD_NAMES.length());
+ methods = JUnitTest.parseTestMethodNamesList(methodsList);
+ } catch (final IllegalArgumentException ex) {
+ System.err.println("Invalid specification of test method names: " + args[i]);
+ System.exit(ERRORS);
+ }
+ } else if (args[i].startsWith(Constants.HALT_ON_ERROR)) {
+ haltError = Project.toBoolean(args[i].substring(Constants.HALT_ON_ERROR.length()));
+ } else if (args[i].startsWith(Constants.HALT_ON_FAILURE)) {
+ haltFail = Project.toBoolean(args[i].substring(Constants.HALT_ON_FAILURE.length()));
+ } else if (args[i].startsWith(Constants.FILTERTRACE)) {
+ stackfilter = Project.toBoolean(args[i].substring(Constants.FILTERTRACE.length()));
+ } else if (args[i].startsWith(Constants.CRASHFILE)) {
+ crashFile = args[i].substring(Constants.CRASHFILE.length());
+ registerTestCase(Constants.BEFORE_FIRST_TEST);
+ } else if (args[i].startsWith(Constants.FORMATTER)) {
+ try {
+ createAndStoreFormatter(args[i].substring(Constants.FORMATTER.length()));
+ } catch (final BuildException be) {
+ System.err.println(be.getMessage());
+ System.exit(ERRORS);
+ }
+ } else if (args[i].startsWith(Constants.PROPSFILE)) {
+ final FileInputStream in = new FileInputStream(args[i]
+ .substring(Constants.PROPSFILE.length()));
+ props.load(in);
+ in.close();
+ } else if (args[i].startsWith(Constants.SHOWOUTPUT)) {
+ showOut = Project.toBoolean(args[i].substring(Constants.SHOWOUTPUT.length()));
+ } else if (args[i].startsWith(Constants.LOGTESTLISTENEREVENTS)) {
+ logTestListenerEvents = Project.toBoolean(
+ args[i].substring(Constants.LOGTESTLISTENEREVENTS.length()));
+ } else if (args[i].startsWith(Constants.OUTPUT_TO_FORMATTERS)) {
+ outputToFormat = Project.toBoolean(
+ args[i].substring(Constants.OUTPUT_TO_FORMATTERS.length()));
+ } else if (args[i].startsWith(Constants.LOG_FAILED_TESTS)) {
+ logFailedTests = Project.toBoolean(
+ args[i].substring(Constants.LOG_FAILED_TESTS.length()));
+ } else if (args[i].startsWith(Constants.SKIP_NON_TESTS)) {
+ skipNonTests = Project.toBoolean(
+ args[i].substring(Constants.SKIP_NON_TESTS.length()));
+ } else if (args[i].startsWith(Constants.THREADID)) {
+ antThreadID = Integer.parseInt(args[i].substring(Constants.THREADID.length()));
+ }
+ }
+
+ // Add/overlay system properties on the properties from the Ant project
+ final Hashtable p = System.getProperties();
+ for (final Enumeration e = p.keys(); e.hasMoreElements();) {
+ final Object key = e.nextElement();
+ props.put(key, p.get(key));
+ }
+
+ int returnCode = SUCCESS;
+ if (multipleTests) {
+ try {
+ final java.io.BufferedReader reader =
+ new java.io.BufferedReader(new java.io.FileReader(args[0]));
+ String testCaseName;
+ String[] testMethodNames;
+ int code = 0;
+ boolean errorOccurred = false;
+ boolean failureOccurred = false;
+ String line = null;
+ while ((line = reader.readLine()) != null) {
+ final StringTokenizer st = new StringTokenizer(line, ",");
+ final String testListSpec = st.nextToken();
+ final int colonIndex = testListSpec.indexOf(':');
+ if (colonIndex == -1) {
+ testCaseName = testListSpec;
+ testMethodNames = null;
+ } else {
+ testCaseName = testListSpec.substring(0, colonIndex);
+ testMethodNames = JUnitTest.parseTestMethodNamesList(
+ testListSpec
+ .substring(colonIndex + 1)
+ .replace('+', ','));
+ }
+ final JUnitTest t = new JUnitTest(testCaseName);
+ t.setTodir(new File(st.nextToken()));
+ t.setOutfile(st.nextToken());
+ t.setProperties(props);
+ t.setSkipNonTests(skipNonTests);
+ t.setThread(antThreadID);
+ code = launch(t, testMethodNames, haltError, stackfilter, haltFail,
+ showOut, outputToFormat,
+ logTestListenerEvents);
+ errorOccurred = (code == ERRORS);
+ failureOccurred = (code != SUCCESS);
+ if (errorOccurred || failureOccurred) {
+ if ((errorOccurred && haltError)
+ || (failureOccurred && haltFail)) {
+ registerNonCrash();
+ System.exit(code);
+ } else {
+ if (code > returnCode) {
+ returnCode = code;
+ }
+ if (logFailedTests) {
+ System.out.println("TEST " + t.getName()
+ + " FAILED");
+ }
+ }
+ }
+ }
+ } catch (final IOException e) {
+ e.printStackTrace();
+ }
+ } else {
+ final JUnitTest t = new JUnitTest(args[0]);
+ t.setThread(antThreadID);
+ t.setProperties(props);
+ t.setSkipNonTests(skipNonTests);
+ returnCode = launch(
+ t, methods, haltError, stackfilter, haltFail,
+ showOut, outputToFormat, logTestListenerEvents);
+ }
+
+ registerNonCrash();
+ System.exit(returnCode);
+ }
+
+ private static Vector fromCmdLine = new Vector();
+
+ private static void transferFormatters(final JUnitTestRunner runner,
+ final JUnitTest test) {
+ runner.addFormatter(new JUnitResultFormatter() {
+
+ public void startTestSuite(final JUnitTest suite) throws BuildException {
+ }
+
+ public void endTestSuite(final JUnitTest suite) throws BuildException {
+ }
+
+ public void setOutput(final OutputStream out) {
+ }
+
+ public void setSystemOutput(final String out) {
+ }
+
+ public void setSystemError(final String err) {
+ }
+
+ public void addError(final Test arg0, final Throwable arg1) {
+ }
+
+ public void addFailure(final Test arg0, final AssertionFailedError arg1) {
+ }
+
+ public void endTest(final Test arg0) {
+ }
+
+ public void startTest(final Test arg0) {
+ registerTestCase(JUnitVersionHelper.getTestCaseName(arg0));
+ }
+ });
+ final int size = fromCmdLine.size();
+ for (int i = 0; i < size; i++) {
+ final FormatterElement fe = (FormatterElement) fromCmdLine.elementAt(i);
+ if (multipleTests && fe.getUseFile()) {
+ final File destFile =
+ new File(test.getTodir(),
+ test.getOutfile() + fe.getExtension());
+ fe.setOutfile(destFile);
+ }
+ runner.addFormatter((JUnitResultFormatter) fe.createFormatter());
+ }
+ }
+
+ /**
+ * Line format is: formatter=<classname>(,<pathname>)?
+ */
+ private static void createAndStoreFormatter(final String line)
+ throws BuildException {
+ final FormatterElement fe = new FormatterElement();
+ final int pos = line.indexOf(',');
+ if (pos == -1) {
+ fe.setClassname(line);
+ fe.setUseFile(false);
+ } else {
+ fe.setClassname(line.substring(0, pos));
+ fe.setUseFile(true);
+ if (!multipleTests) {
+ fe.setOutfile(new File(line.substring(pos + 1)));
+ } else {
+ final int fName = line.indexOf(IGNORED_FILE_NAME);
+ if (fName > -1) {
+ fe.setExtension(line
+ .substring(fName
+ + IGNORED_FILE_NAME.length()));
+ }
+ }
+ }
+ fromCmdLine.addElement(fe);
+ }
+
+ /**
+ * Returns a filtered stack trace.
+ * This is ripped out of junit.runner.BaseTestRunner.
+ * @param t the exception to filter.
+ * @return the filtered stack trace.
+ */
+ public static String getFilteredTrace(final Throwable t) {
+ final String trace = StringUtils.getStackTrace(t);
+ return JUnitTestRunner.filterStack(trace);
+ }
+
+ /**
+ * Filters stack frames from internal JUnit and Ant classes
+ * @param stack the stack trace to filter.
+ * @return the filtered stack.
+ */
+ public static String filterStack(final String stack) {
+ if (!filtertrace) {
+ return stack;
+ }
+ final StringWriter sw = new StringWriter();
+ final BufferedWriter pw = new BufferedWriter(sw);
+ final StringReader sr = new StringReader(stack);
+ final BufferedReader br = new BufferedReader(sr);
+
+ String line;
+ try {
+ boolean firstLine = true;
+ while ((line = br.readLine()) != null) {
+ if (firstLine || !filterLine(line)) {
+ pw.write(line);
+ pw.newLine();
+ }
+ firstLine = false;
+ }
+ } catch (final Exception e) {
+ return stack; // return the stack unfiltered
+ } finally {
+ FileUtils.close(pw);
+ }
+ return sw.toString();
+ }
+
+ private static boolean filterLine(final String line) {
+ for (int i = 0; i < DEFAULT_TRACE_FILTERS.length; i++) {
+ if (line.indexOf(DEFAULT_TRACE_FILTERS[i]) != -1) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * @since Ant 1.6.2
+ */
+ private static int launch(final JUnitTest t, final String[] methods, final boolean haltError,
+ final boolean stackfilter, final boolean haltFail,
+ final boolean showOut, final boolean outputToFormat,
+ final boolean logTestListenerEvents) {
+ final JUnitTestRunner runner =
+ new JUnitTestRunner(t, methods, haltError, stackfilter, haltFail, showOut,
+ logTestListenerEvents, null);
+ runner.forked = true;
+ runner.outputToFormatters = outputToFormat;
+ transferFormatters(runner, t);
+
+ runner.run();
+ return runner.getRetCode();
+ }
+
+ /**
+ * @since Ant 1.7
+ */
+ private static void registerNonCrash()
+ throws IOException {
+ if (crashFile != null) {
+ FileWriter out = null;
+ try {
+ out = new FileWriter(crashFile);
+ out.write(Constants.TERMINATED_SUCCESSFULLY + "\n");
+ out.flush();
+ } finally {
+ FileUtils.close(out);
+ }
+ }
+ }
+
+ private static void registerTestCase(final String testCase) {
+ if (crashFile != null) {
+ try {
+ FileWriter out = null;
+ try {
+ out = new FileWriter(crashFile);
+ out.write(testCase + "\n");
+ out.flush();
+ } finally {
+ FileUtils.close(out);
+ }
+ } catch (final IOException e) {
+ // ignored.
+ }
+ }
+ }
+
+ /**
+ * Modifies a TestListener when running JUnit 4: treats AssertionFailedError
+ * as a failure not an error.
+ *
+ * @since Ant 1.7
+ */
+ private TestListenerWrapper wrapListener(final TestListener testListener) {
+ return new TestListenerWrapper(testListener) {
+ @Override
+ public void addError(final Test test, final Throwable t) {
+ if (junit4 && t instanceof AssertionFailedError) {
+ // JUnit 4 does not distinguish between errors and failures
+ // even in the JUnit 3 adapter.
+ // So we need to help it a bit to retain compatibility for JUnit 3 tests.
+ testListener.addFailure(test, (AssertionFailedError) t);
+ } else if (junit4 && t instanceof AssertionError) {
+ // Not strictly necessary but probably desirable.
+ // JUnit 4-specific test GUIs will show just "failures".
+ // But Ant's output shows "failures" vs. "errors".
+ // We would prefer to show "failure" for things that logically are.
+ final String msg = t.getMessage();
+ final AssertionFailedError failure = msg != null
+ ? new AssertionFailedError(msg) : new AssertionFailedError();
+ failure.setStackTrace(t.getStackTrace());
+ testListener.addFailure(test, failure);
+ } else {
+ testListener.addError(test, t);
+ }
+ }
+ @Override
+ public void addFailure(final Test test, final AssertionFailedError t) {
+ testListener.addFailure(test, t);
+ }
+ public void addFailure(final Test test, final Throwable t) { // pre-3.4
+ if (t instanceof AssertionFailedError) {
+ testListener.addFailure(test, (AssertionFailedError) t);
+ } else {
+ testListener.addError(test, t);
+ }
+ }
+ @Override
+ public void endTest(final Test test) {
+ testListener.endTest(test);
+ }
+ @Override
+ public void startTest(final Test test) {
+ testListener.startTest(test);
+ }
+ };
+ }
+
+ /**
+ * Use instead of TestResult.get{Failure,Error}Count on JUnit 4,
+ * since the adapter claims that all failures are errors.
+ * @since Ant 1.7
+ */
+ private int[] findJUnit4FailureErrorCount(final TestResult result) {
+ int failures = 0;
+ int errors = 0;
+ Enumeration e = result.failures();
+ while (e.hasMoreElements()) {
+ e.nextElement();
+ failures++;
+ }
+ e = result.errors();
+ while (e.hasMoreElements()) {
+ final Throwable t = ((TestFailure) e.nextElement()).thrownException();
+ if (t instanceof AssertionFailedError
+ || t instanceof AssertionError) {
+ failures++;
+ } else {
+ errors++;
+ }
+ }
+ return new int[] {failures, errors};
+ }
+
+} // JUnitTestRunner
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitVersionHelper.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitVersionHelper.java
new file mode 100644
index 00000000..9a21caee
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitVersionHelper.java
@@ -0,0 +1,179 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.junit;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+
+/**
+ * Work around for some changes to the public JUnit API between
+ * different JUnit releases.
+ * @since Ant 1.7
+ */
+// CheckStyle:HideUtilityClassConstructorCheck OFF (bc)
+public class JUnitVersionHelper {
+
+ private static Method testCaseName = null;
+
+ /**
+ * Name of the JUnit4 class we look for.
+ * {@value}
+ * @since Ant 1.7.1
+ */
+ public static final String JUNIT_FRAMEWORK_JUNIT4_TEST_CASE_FACADE
+ = "junit.framework.JUnit4TestCaseFacade";
+ private static final String UNKNOWN_TEST_CASE_NAME = "unknown";
+
+ static {
+ try {
+ testCaseName = TestCase.class.getMethod("getName", new Class[0]);
+ } catch (NoSuchMethodException e) {
+ // pre JUnit 3.7
+ try {
+ testCaseName = TestCase.class.getMethod("name", new Class[0]);
+ } catch (NoSuchMethodException ignored) {
+ // ignore
+ }
+ }
+ }
+
+ /**
+ * JUnit 3.7 introduces TestCase.getName() and subsequent versions
+ * of JUnit remove the old name() method. This method provides
+ * access to the name of a TestCase via reflection that is
+ * supposed to work with version before and after JUnit 3.7.
+ *
+ * <p>since Ant 1.5.1 this method will invoke &quot;<code>public
+ * String getName()</code>&quot; on any implementation of Test if
+ * it exists.</p>
+ *
+ * <p>Since Ant 1.7 also checks for JUnit4TestCaseFacade explicitly.
+ * This is used by junit.framework.JUnit4TestAdapter.</p>
+ * @param t the test.
+ * @return the name of the test.
+ */
+ public static String getTestCaseName(Test t) {
+ if (t == null) {
+ return UNKNOWN_TEST_CASE_NAME;
+ }
+ if (t.getClass().getName().equals(JUNIT_FRAMEWORK_JUNIT4_TEST_CASE_FACADE)) {
+ // Self-describing as of JUnit 4 (#38811). But trim "(ClassName)".
+ String name = t.toString();
+ if (name.endsWith(")")) {
+ int paren = name.lastIndexOf('(');
+ return name.substring(0, paren);
+ } else {
+ return name;
+ }
+ }
+ if (t instanceof TestCase && testCaseName != null) {
+ try {
+ return (String) testCaseName.invoke(t, new Object[0]);
+ } catch (Throwable ignored) {
+ // ignore
+ }
+ } else {
+ try {
+ Method getNameMethod = null;
+ try {
+ getNameMethod =
+ t.getClass().getMethod("getName", new Class [0]);
+ } catch (NoSuchMethodException e) {
+ getNameMethod = t.getClass().getMethod("name",
+ new Class [0]);
+ }
+ if (getNameMethod != null
+ && getNameMethod.getReturnType() == String.class) {
+ return (String) getNameMethod.invoke(t, new Object[0]);
+ }
+ } catch (Throwable ignored) {
+ // ignore
+ }
+ }
+ return UNKNOWN_TEST_CASE_NAME;
+ }
+
+ /**
+ * Tries to find the name of the class which a test represents
+ * across JUnit 3 and 4. For JUnit4 it parses the toString() value of the
+ * test, and extracts it from there.
+ * @since Ant 1.7.1 (it was private until then)
+ * @param test test case to look at
+ * @return the extracted class name.
+ */
+ public static String getTestCaseClassName(Test test) {
+ String className = test.getClass().getName();
+ if (test instanceof JUnitTaskMirrorImpl.VmExitErrorTest) {
+ className = ((JUnitTaskMirrorImpl.VmExitErrorTest) test).getClassName();
+ } else
+ if (className.equals(JUNIT_FRAMEWORK_JUNIT4_TEST_CASE_FACADE)) {
+ // JUnit 4 wraps solo tests this way. We can extract
+ // the original test name with a little hack.
+ String name = test.toString();
+ int paren = name.lastIndexOf('(');
+ if (paren != -1 && name.endsWith(")")) {
+ className = name.substring(paren + 1, name.length() - 1);
+ }
+ }
+ return className;
+ }
+
+ public static String getIgnoreMessage(Test test) {
+ String message = null;
+
+ try {
+ Class<?> junit4FacadeClass = Class.forName("junit.framework.JUnit4TestCaseFacade");
+ if (test != null && test.getClass().isAssignableFrom(junit4FacadeClass)) {
+ //try and get the message coded as part of the ignore
+ /*
+ * org.junit.runner.Description contains a getAnnotation(Class) method... but this
+ * wasn't in older versions of JUnit4 so we have to try and do this by reflection
+ */
+ Class<?> testClass = Class.forName(JUnitVersionHelper.getTestCaseClassName(test));
+
+ Method testMethod = testClass.getMethod(JUnitVersionHelper.getTestCaseName(test));
+ Class ignoreAnnotation = Class.forName("org.junit.Ignore");
+ Annotation annotation = testMethod.getAnnotation(ignoreAnnotation);
+ if (annotation != null) {
+ Method valueMethod = annotation.getClass().getMethod("value");
+ String value = (String) valueMethod.invoke(annotation);
+ if (value != null && value.length() > 0) {
+ message = value;
+ }
+ }
+
+ }
+ } catch (NoSuchMethodException e) {
+ // silently ignore - we'll report a skip with no message
+ } catch (ClassNotFoundException e) {
+ // silently ignore - we'll report a skip with no message
+ } catch (InvocationTargetException e) {
+ // silently ignore - we'll report a skip with no message
+ } catch (IllegalAccessException e) {
+ // silently ignore - we'll report a skip with no message
+ }
+ return message;
+
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/OutErrSummaryJUnitResultFormatter.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/OutErrSummaryJUnitResultFormatter.java
new file mode 100644
index 00000000..e0dc16c3
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/OutErrSummaryJUnitResultFormatter.java
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.junit;
+
+/**
+ * Used instead of SummaryJUnitResultFormatter in forked tests if
+ * withOutAndErr is requested.
+ */
+
+public class OutErrSummaryJUnitResultFormatter
+ extends SummaryJUnitResultFormatter {
+
+ /**
+ * Empty
+ */
+ public OutErrSummaryJUnitResultFormatter() {
+ super();
+ setWithOutAndErr(true);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/PlainJUnitResultFormatter.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/PlainJUnitResultFormatter.java
new file mode 100644
index 00000000..3386ee50
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/PlainJUnitResultFormatter.java
@@ -0,0 +1,317 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.junit;
+
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.StringWriter;
+import java.text.NumberFormat;
+import java.util.Hashtable;
+
+import junit.framework.AssertionFailedError;
+import junit.framework.Test;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.util.FileUtils;
+import org.apache.tools.ant.util.StringUtils;
+
+
+/**
+ * Prints plain text output of the test to a specified Writer.
+ *
+ */
+
+public class PlainJUnitResultFormatter implements JUnitResultFormatter, IgnoredTestListener {
+
+ private static final double ONE_SECOND = 1000.0;
+
+ /**
+ * Formatter for timings.
+ */
+ private NumberFormat nf = NumberFormat.getInstance();
+ /**
+ * Timing helper.
+ */
+ private Hashtable testStarts = new Hashtable();
+ /**
+ * Where to write the log to.
+ */
+ private OutputStream out;
+ /**
+ * Helper to store intermediate output.
+ */
+ private StringWriter inner;
+ /**
+ * Convenience layer on top of {@link #inner inner}.
+ */
+ private BufferedWriter wri;
+ /**
+ * Suppress endTest if testcase failed.
+ */
+ private Hashtable failed = new Hashtable();
+
+ private String systemOutput = null;
+ private String systemError = null;
+
+ /** No arg constructor */
+ public PlainJUnitResultFormatter() {
+ inner = new StringWriter();
+ wri = new BufferedWriter(inner);
+ }
+
+ /** {@inheritDoc}. */
+ public void setOutput(OutputStream out) {
+ this.out = out;
+ }
+
+ /** {@inheritDoc}. */
+ public void setSystemOutput(String out) {
+ systemOutput = out;
+ }
+
+ /** {@inheritDoc}. */
+ public void setSystemError(String err) {
+ systemError = err;
+ }
+
+ /**
+ * The whole testsuite started.
+ * @param suite the test suite
+ * @throws BuildException if unable to write the output
+ */
+ public void startTestSuite(JUnitTest suite) throws BuildException {
+ if (out == null) {
+ return; // Quick return - no output do nothing.
+ }
+ StringBuffer sb = new StringBuffer("Testsuite: ");
+ sb.append(suite.getName());
+ sb.append(StringUtils.LINE_SEP);
+ try {
+ out.write(sb.toString().getBytes());
+ out.flush();
+ } catch (IOException ex) {
+ throw new BuildException("Unable to write output", ex);
+ }
+ }
+
+ /**
+ * The whole testsuite ended.
+ * @param suite the test suite
+ * @throws BuildException if unable to write the output
+ */
+ public void endTestSuite(JUnitTest suite) throws BuildException {
+ try {
+ StringBuffer sb = new StringBuffer("Tests run: ");
+ sb.append(suite.runCount());
+ sb.append(", Failures: ");
+ sb.append(suite.failureCount());
+ sb.append(", Errors: ");
+ sb.append(suite.errorCount());
+ sb.append(", Skipped: ");
+ sb.append(suite.skipCount());
+ sb.append(", Time elapsed: ");
+ sb.append(nf.format(suite.getRunTime() / ONE_SECOND));
+ sb.append(" sec");
+ sb.append(StringUtils.LINE_SEP);
+ write(sb.toString());
+
+ // write the err and output streams to the log
+ if (systemOutput != null && systemOutput.length() > 0) {
+ write("------------- Standard Output ---------------");
+ write(StringUtils.LINE_SEP);
+ write(systemOutput);
+ write("------------- ---------------- ---------------");
+ write(StringUtils.LINE_SEP);
+ }
+
+ if (systemError != null && systemError.length() > 0) {
+ write("------------- Standard Error -----------------");
+ write(StringUtils.LINE_SEP);
+ write(systemError);
+ write("------------- ---------------- ---------------");
+ write(StringUtils.LINE_SEP);
+ }
+
+ write(StringUtils.LINE_SEP);
+ if (out != null) {
+ try {
+ wri.flush();
+ write(inner.toString());
+ } catch (IOException ioex) {
+ throw new BuildException("Unable to write output", ioex);
+ }
+ }
+ } finally {
+ if (out != null) {
+ try {
+ wri.close();
+ } catch (IOException ioex) {
+ throw new BuildException("Unable to flush output", ioex);
+ } finally {
+ if (out != System.out && out != System.err) {
+ FileUtils.close(out);
+ }
+ wri = null;
+ out = null;
+ }
+ }
+ }
+ }
+
+ /**
+ * Interface TestListener.
+ *
+ * <p>A new Test is started.
+ * @param t the test.
+ */
+ public void startTest(Test t) {
+ testStarts.put(t, new Long(System.currentTimeMillis()));
+ failed.put(t, Boolean.FALSE);
+ }
+
+ /**
+ * Interface TestListener.
+ *
+ * <p>A Test is finished.
+ * @param test the test.
+ */
+ public void endTest(Test test) {
+ if (Boolean.TRUE.equals(failed.get(test))) {
+ return;
+ }
+ synchronized (wri) {
+ try {
+ wri.write("Testcase: "
+ + JUnitVersionHelper.getTestCaseName(test));
+ Long l = (Long) testStarts.get(test);
+ double seconds = 0;
+ // can be null if an error occurred in setUp
+ if (l != null) {
+ seconds =
+ (System.currentTimeMillis() - l.longValue()) / ONE_SECOND;
+ }
+
+ wri.write(" took " + nf.format(seconds) + " sec");
+ wri.newLine();
+ } catch (IOException ex) {
+ throw new BuildException(ex);
+ }
+ }
+ }
+
+ /**
+ * Interface TestListener for JUnit &lt;= 3.4.
+ *
+ * <p>A Test failed.
+ * @param test the test.
+ * @param t the exception.
+ */
+ public void addFailure(Test test, Throwable t) {
+ formatError("\tFAILED", test, t);
+ }
+
+ /**
+ * Interface TestListener for JUnit &gt; 3.4.
+ *
+ * <p>A Test failed.
+ * @param test the test.
+ * @param t the assertion that failed.
+ */
+ public void addFailure(Test test, AssertionFailedError t) {
+ addFailure(test, (Throwable) t);
+ }
+
+ /**
+ * Interface TestListener.
+ *
+ * <p>An error occurred while running the test.
+ * @param test the test.
+ * @param t the exception.
+ */
+ public void addError(Test test, Throwable t) {
+ formatError("\tCaused an ERROR", test, t);
+ }
+
+ private void formatError(String type, Test test, Throwable t) {
+ synchronized (wri) {
+ if (test != null) {
+ endTest(test);
+ failed.put(test, Boolean.TRUE);
+ }
+
+ try {
+ wri.write(type);
+ wri.newLine();
+ wri.write(String.valueOf(t.getMessage()));
+ wri.newLine();
+ String strace = JUnitTestRunner.getFilteredTrace(t);
+ wri.write(strace);
+ wri.newLine();
+ } catch (IOException ex) {
+ throw new BuildException(ex);
+ }
+ }
+ }
+
+ public void testIgnored(Test test) {
+ formatSkip(test, JUnitVersionHelper.getIgnoreMessage(test));
+ }
+
+
+ public void formatSkip(Test test, String message) {
+ if (test != null) {
+ endTest(test);
+ }
+
+ try {
+ wri.write("\tSKIPPED");
+ if (message != null) {
+ wri.write(": ");
+ wri.write(message);
+ }
+ wri.newLine();
+ } catch (IOException ex) {
+ throw new BuildException(ex);
+ }
+
+ }
+
+ public void testAssumptionFailure(Test test, Throwable throwable) {
+ formatSkip(test, throwable.getMessage());
+ }
+
+ /**
+ * Print out some text, and flush the output stream; encoding in the platform
+ * local default encoding.
+ * @param text text to write.
+ * @throws BuildException on IO Problems.
+ */
+ private void write(String text) {
+ if (out == null) {
+ return;
+ }
+ try {
+ out.write(text.getBytes());
+ out.flush();
+ } catch (IOException ex) {
+ throw new BuildException("Unable to write output " + ex, ex);
+ }
+ }
+} // PlainJUnitResultFormatter
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/SummaryJUnitResultFormatter.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/SummaryJUnitResultFormatter.java
new file mode 100644
index 00000000..0b09fa20
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/SummaryJUnitResultFormatter.java
@@ -0,0 +1,213 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.junit;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.text.NumberFormat;
+
+import junit.framework.AssertionFailedError;
+import junit.framework.Test;
+
+import org.apache.tools.ant.BuildException;
+
+/**
+ * Prints short summary output of the test to Ant's logging system.
+ *
+ */
+
+public class SummaryJUnitResultFormatter
+ implements JUnitResultFormatter, JUnitTaskMirror.SummaryJUnitResultFormatterMirror {
+
+ private static final double ONE_SECOND = 1000.0;
+
+ /**
+ * Formatter for timings.
+ */
+ private NumberFormat nf = NumberFormat.getInstance();
+ /**
+ * OutputStream to write to.
+ */
+ private OutputStream out;
+
+ private boolean withOutAndErr = false;
+ private String systemOutput = null;
+ private String systemError = null;
+
+ /**
+ * Empty
+ */
+ public SummaryJUnitResultFormatter() {
+ }
+
+ /**
+ * Insures that a line of log output is written and flushed as a single
+ * operation, to prevent lines from being spliced into other lines.
+ * (Hopefully this solves the issue of run on lines -
+ * [junit] Tests Run: 2 Failures: 2 [junit] Tests run: 5...
+ * synchronized doesn't seem to be to harsh a penalty since it only
+ * occurs twice per test - at the beginning and end. Note that message
+ * construction occurs outside the locked block.
+ *
+ * @param b data to be written as an unbroken block
+ */
+ private synchronized void writeOutputLine(byte[] b) {
+ try {
+ out.write(b);
+ out.flush();
+ } catch (IOException ioex) {
+ throw new BuildException("Unable to write summary output", ioex);
+ }
+ }
+
+ /**
+ * The testsuite started.
+ * @param suite the testsuite.
+ */
+ public void startTestSuite(JUnitTest suite) {
+ String newLine = System.getProperty("line.separator");
+ StringBuffer sb = new StringBuffer("Running ");
+ int antThreadID = suite.getThread();
+
+ sb.append(suite.getName());
+ /* only write thread id in multi-thread mode so default old way doesn't change output */
+ if (antThreadID > 0) {
+ sb.append(" in thread ");
+ sb.append(antThreadID);
+ }
+ sb.append(newLine);
+ writeOutputLine(sb.toString().getBytes());
+ }
+ /**
+ * Empty
+ * @param t not used.
+ */
+ public void startTest(Test t) {
+ }
+ /**
+ * Empty
+ * @param test not used.
+ */
+ public void endTest(Test test) {
+ }
+ /**
+ * Empty
+ * @param test not used.
+ * @param t not used.
+ */
+ public void addFailure(Test test, Throwable t) {
+ }
+ /**
+ * Interface TestListener for JUnit &gt; 3.4.
+ *
+ * <p>A Test failed.
+ * @param test not used.
+ * @param t not used.
+ */
+ public void addFailure(Test test, AssertionFailedError t) {
+ addFailure(test, (Throwable) t);
+ }
+ /**
+ * Empty
+ * @param test not used.
+ * @param t not used.
+ */
+ public void addError(Test test, Throwable t) {
+ }
+
+ /** {@inheritDoc}. */
+ public void setOutput(OutputStream out) {
+ this.out = out;
+ }
+
+ /** {@inheritDoc}. */
+ public void setSystemOutput(String out) {
+ systemOutput = out;
+ }
+
+ /** {@inheritDoc}. */
+ public void setSystemError(String err) {
+ systemError = err;
+ }
+
+ /**
+ * Should the output to System.out and System.err be written to
+ * the summary.
+ * @param value if true write System.out and System.err to the summary.
+ */
+ public void setWithOutAndErr(boolean value) {
+ withOutAndErr = value;
+ }
+
+ /**
+ * The whole testsuite ended.
+ * @param suite the testsuite.
+ * @throws BuildException if there is an error.
+ */
+ public void endTestSuite(JUnitTest suite) throws BuildException {
+ String newLine = System.getProperty("line.separator");
+ StringBuffer sb = new StringBuffer("Tests run: ");
+ sb.append(suite.runCount());
+ sb.append(", Failures: ");
+ sb.append(suite.failureCount());
+ sb.append(", Errors: ");
+ sb.append(suite.errorCount());
+ sb.append(", Skipped: ");
+ sb.append(suite.skipCount());
+ sb.append(", Time elapsed: ");
+ sb.append(nf.format(suite.getRunTime() / ONE_SECOND));
+ sb.append(" sec");
+
+ /* class name needed with multi-threaded execution because
+ results line may not appear immediately below start line.
+ only write thread id, class name in multi-thread mode so
+ the line still looks as much like the old line as possible. */
+ if (suite.getThread() > 0) {
+ sb.append(", Thread: ");
+ sb.append(suite.getThread());
+ sb.append(", Class: ");
+ sb.append(suite.getName());
+ }
+ sb.append(newLine);
+
+ if (withOutAndErr) {
+ if (systemOutput != null && systemOutput.length() > 0) {
+ sb.append("Output:").append(newLine).append(systemOutput)
+ .append(newLine);
+ }
+
+ if (systemError != null && systemError.length() > 0) {
+ sb.append("Error: ").append(newLine).append(systemError)
+ .append(newLine);
+ }
+ }
+
+ try {
+ writeOutputLine(sb.toString().getBytes());
+ } finally {
+ if (out != System.out && out != System.err) {
+ try {
+ out.close();
+ } catch (IOException e) {
+ // ignore
+ }
+ }
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/TearDownOnVmCrash.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/TearDownOnVmCrash.java
new file mode 100644
index 00000000..e381a70c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/TearDownOnVmCrash.java
@@ -0,0 +1,144 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.junit;
+
+import java.io.OutputStream;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+import junit.framework.AssertionFailedError;
+import junit.framework.Test;
+
+/**
+ * Formatter that doesn't create any output but tries to invoke the
+ * tearDown method on a testcase if that test was forked and caused a
+ * timeout or VM crash.
+ *
+ * <p>This formatter has some limitations, for details see the
+ * &lt;junit&gt; task's manual.</p>
+ *
+ * @since Ant 1.8.0
+ */
+public class TearDownOnVmCrash implements JUnitResultFormatter {
+
+ private String suiteName;
+
+ /**
+ * Records the suite's name to later determine the class to invoke
+ * tearDown on.
+ */
+ public void startTestSuite(final JUnitTest suite) {
+ suiteName = suite.getName();
+ if (suiteName != null &&
+ suiteName.endsWith(JUnitTask.NAME_OF_DUMMY_TEST)) {
+ // no way to know which class caused the timeout
+ suiteName = null;
+ }
+ }
+
+ /**
+ * Only invoke tearDown if the suite is known and not the dummy
+ * test we get when a Batch fails and the error is an actual
+ * error generated by Ant.
+ */
+ public void addError(final Test fakeTest, final Throwable t) {
+ if (suiteName != null
+ && fakeTest instanceof JUnitTaskMirrorImpl.VmExitErrorTest) {
+ tearDown();
+ }
+ }
+
+ // no need to implement the rest
+ public void addFailure(Test test, Throwable t) {}
+
+ public void addFailure(Test test, AssertionFailedError t) {}
+
+ public void startTest(Test test) {}
+
+ public void endTest(Test test) {}
+
+ public void endTestSuite(JUnitTest suite) {}
+
+ public void setOutput(OutputStream out) {}
+
+ public void setSystemOutput(String out) {}
+
+ public void setSystemError(String err) {}
+
+ private void tearDown() {
+ try {
+ // first try to load the class and let's hope it is on our
+ // classpath
+ Class testClass = null;
+ if (Thread.currentThread().getContextClassLoader() != null) {
+ try {
+ testClass = Thread.currentThread().getContextClassLoader()
+ .loadClass(suiteName);
+ } catch (ClassNotFoundException cnfe) {
+ // ignore
+ }
+ }
+ if (testClass == null && getClass().getClassLoader() != null) {
+ try {
+ testClass =
+ getClass().getClassLoader().loadClass(suiteName);
+ } catch (ClassNotFoundException cnfe) {
+ // ignore
+ }
+ }
+ if (testClass == null) {
+ // fall back to system classloader
+ testClass = Class.forName(suiteName);
+ }
+
+ // if the test has a suite method, then we can't know
+ // which test of the executed suite timed out, ignore it
+ try {
+ // check if there is a suite method
+ testClass.getMethod("suite", new Class[0]);
+ return;
+ } catch (NoSuchMethodException e) {
+ // no suite method
+ }
+
+ // a loadable class and no suite method
+ // no reason to check for JUnit 4 since JUnit4TestAdapter
+ // doesn't have any tearDown method.
+
+ try {
+ Method td = testClass.getMethod("tearDown", new Class[0]);
+ if (td.getReturnType() == Void.TYPE) {
+ td.invoke(testClass.newInstance(), new Object[0]);
+ }
+ } catch (NoSuchMethodException nsme) {
+ // no tearDown, fine
+ }
+
+ } catch (ClassNotFoundException cnfe) {
+ // class probably is not in our classpath, there is
+ // nothing we can do
+ } catch (InvocationTargetException ite) {
+ System.err.println("Caught an exception while trying to invoke"
+ + " tearDown: " + ite.getMessage());
+ } catch (Throwable t) {
+ System.err.println("Caught an exception while trying to invoke"
+ + " tearDown: " + t.getMessage());
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/TestIgnored.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/TestIgnored.java
new file mode 100644
index 00000000..79a88785
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/TestIgnored.java
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.junit;
+
+import junit.framework.Test;
+
+public class TestIgnored {
+
+ private Test test;
+
+ public TestIgnored(Test test) {
+ this.test = test;
+ }
+
+ public Test getTest() {
+ return test;
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/TestListenerWrapper.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/TestListenerWrapper.java
new file mode 100644
index 00000000..692e4fc9
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/TestListenerWrapper.java
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.junit;
+
+import junit.framework.AssertionFailedError;
+import junit.framework.Test;
+import junit.framework.TestListener;
+
+
+public class TestListenerWrapper implements TestListener, IgnoredTestListener {
+
+ private TestListener wrapped;
+
+ public TestListenerWrapper(TestListener listener) {
+ super();
+ wrapped = listener;
+ }
+
+ public void addError(Test test, Throwable throwable) {
+ wrapped.addError(test, throwable);
+ }
+
+ public void addFailure(Test test, AssertionFailedError assertionFailedError) {
+ wrapped.addFailure(test, assertionFailedError);
+ }
+
+ public void endTest(Test test) {
+ wrapped.endTest(test);
+ }
+
+ public void startTest(Test test) {
+ wrapped.startTest(test);
+ }
+
+ public void testIgnored(Test test) {
+ if (wrapped instanceof IgnoredTestListener) {
+ ((IgnoredTestListener)wrapped).testIgnored(test);
+ }
+ }
+
+ public void testAssumptionFailure(Test test, Throwable throwable) {
+ if (wrapped instanceof IgnoredTestListener) {
+ ((IgnoredTestListener)wrapped).testAssumptionFailure(test, throwable);
+ }
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/XMLConstants.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/XMLConstants.java
new file mode 100644
index 00000000..03760cc9
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/XMLConstants.java
@@ -0,0 +1,141 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.junit;
+
+/**
+ * <p> Interface groups XML constants.
+ * Interface that groups all constants used throughout the <tt>XML</tt>
+ * documents that are generated by the <tt>XMLJUnitResultFormatter</tt>.
+ * <p>
+ * As of now the DTD is:
+ * <code><pre>
+ * &lt;!ELEMENT testsuites (testsuite*)&gt;
+ *
+ * &lt;!ELEMENT testsuite (properties, testcase*,
+ * failure?, error?,
+ * system-out?, system-err?)&gt;
+ * &lt;!ATTLIST testsuite name CDATA #REQUIRED&gt;
+ * &lt;!ATTLIST testsuite tests CDATA #REQUIRED&gt;
+ * &lt;!ATTLIST testsuite failures CDATA #REQUIRED&gt;
+ * &lt;!ATTLIST testsuite errors CDATA #REQUIRED&gt;
+ * &lt;!ATTLIST testsuite time CDATA #REQUIRED&gt;
+ * &lt;!ATTLIST testsuite package CDATA #IMPLIED&gt;
+ * &lt;!ATTLIST testsuite id CDATA #IMPLIED&gt;
+ *
+ *
+ * &lt;!ELEMENT properties (property*)&gt;
+ *
+ * &lt;!ELEMENT property EMPTY&gt;
+ * &lt;!ATTLIST property name CDATA #REQUIRED&gt;
+ * &lt;!ATTLIST property value CDATA #REQUIRED&gt;
+ *
+ * &lt;!ELEMENT testcase (failure?, error?)&gt;
+ * &lt;!ATTLIST testcase name CDATA #REQUIRED&gt;
+ * &lt;!ATTLIST testcase classname CDATA #IMPLIED&gt;
+ * &lt;!ATTLIST testcase time CDATA #REQUIRED&gt;
+ *
+ * &lt;!ELEMENT failure (#PCDATA)&gt;
+ * &lt;!ATTLIST failure message CDATA #IMPLIED&gt;
+ * &lt;!ATTLIST failure type CDATA #REQUIRED&gt;
+ *
+ * &lt;!ELEMENT error (#PCDATA)&gt;
+ * &lt;!ATTLIST error message CDATA #IMPLIED&gt;
+ * &lt;!ATTLIST error type CDATA #REQUIRED&gt;
+ *
+ * &lt;!ELEMENT system-err (#PCDATA)&gt;
+ *
+ * &lt;!ELEMENT system-out (#PCDATA)&gt;
+ *
+ * </pre></code>
+ * @see XMLJUnitResultFormatter
+ * @see XMLResultAggregator
+ */
+// CheckStyle:InterfaceIsTypeCheck OFF (bc)
+public interface XMLConstants {
+ /** the testsuites element for the aggregate document */
+ String TESTSUITES = "testsuites";
+
+ /** the testsuite element */
+ String TESTSUITE = "testsuite";
+
+ /** the testcase element */
+ String TESTCASE = "testcase";
+
+ /** the error element */
+ String ERROR = "error";
+
+ /** the failure element */
+ String FAILURE = "failure";
+
+ /** the system-err element */
+ String SYSTEM_ERR = "system-err";
+
+ /** the system-out element */
+ String SYSTEM_OUT = "system-out";
+
+ /** package attribute for the aggregate document */
+ String ATTR_PACKAGE = "package";
+
+ /** name attribute for property, testcase and testsuite elements */
+ String ATTR_NAME = "name";
+
+ /** time attribute for testcase and testsuite elements */
+ String ATTR_TIME = "time";
+
+ /** errors attribute for testsuite elements */
+ String ATTR_ERRORS = "errors";
+
+ /** failures attribute for testsuite elements */
+ String ATTR_FAILURES = "failures";
+
+ /** tests attribute for testsuite elements */
+ String ATTR_TESTS = "tests";
+
+ String ATTR_SKIPPED = "skipped";
+
+ /** type attribute for failure and error elements */
+ String ATTR_TYPE = "type";
+
+ /** message attribute for failure elements */
+ String ATTR_MESSAGE = "message";
+
+ /** the properties element */
+ String PROPERTIES = "properties";
+
+ /** the property element */
+ String PROPERTY = "property";
+
+ /** value attribute for property elements */
+ String ATTR_VALUE = "value";
+
+ /** classname attribute for testcase elements */
+ String ATTR_CLASSNAME = "classname";
+
+ /** id attribute */
+ String ATTR_ID = "id";
+
+ /**
+ * timestamp of test cases
+ */
+ String TIMESTAMP = "timestamp";
+
+ /**
+ * name of host running the tests
+ */
+ String HOSTNAME = "hostname";
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/XMLJUnitResultFormatter.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/XMLJUnitResultFormatter.java
new file mode 100644
index 00000000..416c10d4
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/XMLJUnitResultFormatter.java
@@ -0,0 +1,366 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.junit;
+
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Properties;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import junit.framework.AssertionFailedError;
+import junit.framework.Test;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.util.DOMElementWriter;
+import org.apache.tools.ant.util.DateUtils;
+import org.apache.tools.ant.util.FileUtils;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Text;
+
+
+/**
+ * Prints XML output of the test to a specified Writer.
+ *
+ * @see FormatterElement
+ */
+
+public class XMLJUnitResultFormatter implements JUnitResultFormatter, XMLConstants, IgnoredTestListener {
+
+ private static final double ONE_SECOND = 1000.0;
+
+ /** constant for unnnamed testsuites/cases */
+ private static final String UNKNOWN = "unknown";
+
+ private static DocumentBuilder getDocumentBuilder() {
+ try {
+ return DocumentBuilderFactory.newInstance().newDocumentBuilder();
+ } catch (final Exception exc) {
+ throw new ExceptionInInitializerError(exc);
+ }
+ }
+
+ /**
+ * The XML document.
+ */
+ private Document doc;
+
+ /**
+ * The wrapper for the whole testsuite.
+ */
+ private Element rootElement;
+
+ /**
+ * Element for the current test.
+ *
+ * The keying of this map is a bit of a hack: tests are keyed by caseName(className) since
+ * the Test we get for Test-start isn't the same as the Test we get during test-assumption-fail,
+ * so we can't easily match Test objects without manually iterating over all keys and checking
+ * individual fields.
+ */
+ private final Hashtable<String, Element> testElements = new Hashtable<String, Element>();
+
+ /**
+ * tests that failed.
+ */
+ private final Hashtable failedTests = new Hashtable();
+
+ /**
+ * Tests that were skipped.
+ */
+ private final Hashtable<String, Test> skippedTests = new Hashtable<String, Test>();
+ /**
+ * Tests that were ignored. See the note above about the key being a bit of a hack.
+ */
+ private final Hashtable<String, Test> ignoredTests = new Hashtable<String, Test>();
+ /**
+ * Timing helper.
+ */
+ private final Hashtable<String, Long> testStarts = new Hashtable<String, Long>();
+ /**
+ * Where to write the log to.
+ */
+ private OutputStream out;
+
+ /** No arg constructor. */
+ public XMLJUnitResultFormatter() {
+ }
+
+ /** {@inheritDoc}. */
+ public void setOutput(final OutputStream out) {
+ this.out = out;
+ }
+
+ /** {@inheritDoc}. */
+ public void setSystemOutput(final String out) {
+ formatOutput(SYSTEM_OUT, out);
+ }
+
+ /** {@inheritDoc}. */
+ public void setSystemError(final String out) {
+ formatOutput(SYSTEM_ERR, out);
+ }
+
+ /**
+ * The whole testsuite started.
+ * @param suite the testsuite.
+ */
+ public void startTestSuite(final JUnitTest suite) {
+ doc = getDocumentBuilder().newDocument();
+ rootElement = doc.createElement(TESTSUITE);
+ final String n = suite.getName();
+ rootElement.setAttribute(ATTR_NAME, n == null ? UNKNOWN : n);
+
+ //add the timestamp
+ final String timestamp = DateUtils.format(new Date(),
+ DateUtils.ISO8601_DATETIME_PATTERN);
+ rootElement.setAttribute(TIMESTAMP, timestamp);
+ //and the hostname.
+ rootElement.setAttribute(HOSTNAME, getHostname());
+
+ // Output properties
+ final Element propsElement = doc.createElement(PROPERTIES);
+ rootElement.appendChild(propsElement);
+ final Properties props = suite.getProperties();
+ if (props != null) {
+ final Enumeration e = props.propertyNames();
+ while (e.hasMoreElements()) {
+ final String name = (String) e.nextElement();
+ final Element propElement = doc.createElement(PROPERTY);
+ propElement.setAttribute(ATTR_NAME, name);
+ propElement.setAttribute(ATTR_VALUE, props.getProperty(name));
+ propsElement.appendChild(propElement);
+ }
+ }
+ }
+
+ /**
+ * get the local hostname
+ * @return the name of the local host, or "localhost" if we cannot work it out
+ */
+ private String getHostname() {
+ String hostname = "localhost";
+ try {
+ final InetAddress localHost = InetAddress.getLocalHost();
+ if (localHost != null) {
+ hostname = localHost.getHostName();
+ }
+ } catch (final UnknownHostException e) {
+ // fall back to default 'localhost'
+ }
+ return hostname;
+ }
+
+ /**
+ * The whole testsuite ended.
+ * @param suite the testsuite.
+ * @throws BuildException on error.
+ */
+ public void endTestSuite(final JUnitTest suite) throws BuildException {
+ rootElement.setAttribute(ATTR_TESTS, "" + suite.runCount());
+ rootElement.setAttribute(ATTR_FAILURES, "" + suite.failureCount());
+ rootElement.setAttribute(ATTR_ERRORS, "" + suite.errorCount());
+ rootElement.setAttribute(ATTR_SKIPPED, "" + suite.skipCount());
+ rootElement.setAttribute(
+ ATTR_TIME, "" + (suite.getRunTime() / ONE_SECOND));
+ if (out != null) {
+ Writer wri = null;
+ try {
+ wri = new BufferedWriter(new OutputStreamWriter(out, "UTF8"));
+ wri.write("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n");
+ (new DOMElementWriter()).write(rootElement, wri, 0, " ");
+ } catch (final IOException exc) {
+ throw new BuildException("Unable to write log file", exc);
+ } finally {
+ if (wri != null) {
+ try {
+ wri.flush();
+ } catch (final IOException ex) {
+ // ignore
+ }
+ }
+ if (out != System.out && out != System.err) {
+ FileUtils.close(wri);
+ }
+ }
+ }
+ }
+
+ /**
+ * Interface TestListener.
+ *
+ * <p>A new Test is started.
+ * @param t the test.
+ */
+ public void startTest(final Test t) {
+ testStarts.put(createDescription(t), System.currentTimeMillis());
+ }
+
+ private static String createDescription(final Test test) throws BuildException {
+ return JUnitVersionHelper.getTestCaseName(test) + "(" + JUnitVersionHelper.getTestCaseClassName(test) + ")";
+ }
+
+ /**
+ * Interface TestListener.
+ *
+ * <p>A Test is finished.
+ * @param test the test.
+ */
+ public void endTest(final Test test) {
+ final String testDescription = createDescription(test);
+
+ // Fix for bug #5637 - if a junit.extensions.TestSetup is
+ // used and throws an exception during setUp then startTest
+ // would never have been called
+ if (!testStarts.containsKey(testDescription)) {
+ startTest(test);
+ }
+ Element currentTest;
+ if (!failedTests.containsKey(test) && !skippedTests.containsKey(testDescription) && !ignoredTests.containsKey(testDescription)) {
+ currentTest = doc.createElement(TESTCASE);
+ final String n = JUnitVersionHelper.getTestCaseName(test);
+ currentTest.setAttribute(ATTR_NAME,
+ n == null ? UNKNOWN : n);
+ // a TestSuite can contain Tests from multiple classes,
+ // even tests with the same name - disambiguate them.
+ currentTest.setAttribute(ATTR_CLASSNAME,
+ JUnitVersionHelper.getTestCaseClassName(test));
+ rootElement.appendChild(currentTest);
+ testElements.put(createDescription(test), currentTest);
+ } else {
+ currentTest = testElements.get(testDescription);
+ }
+
+ final Long l = testStarts.get(createDescription(test));
+ currentTest.setAttribute(ATTR_TIME,
+ "" + ((System.currentTimeMillis() - l) / ONE_SECOND));
+ }
+
+ /**
+ * Interface TestListener for JUnit &lt;= 3.4.
+ *
+ * <p>A Test failed.
+ * @param test the test.
+ * @param t the exception.
+ */
+ public void addFailure(final Test test, final Throwable t) {
+ formatError(FAILURE, test, t);
+ }
+
+ /**
+ * Interface TestListener for JUnit &gt; 3.4.
+ *
+ * <p>A Test failed.
+ * @param test the test.
+ * @param t the assertion.
+ */
+ public void addFailure(final Test test, final AssertionFailedError t) {
+ addFailure(test, (Throwable) t);
+ }
+
+ /**
+ * Interface TestListener.
+ *
+ * <p>An error occurred while running the test.
+ * @param test the test.
+ * @param t the error.
+ */
+ public void addError(final Test test, final Throwable t) {
+ formatError(ERROR, test, t);
+ }
+
+ private void formatError(final String type, final Test test, final Throwable t) {
+ if (test != null) {
+ endTest(test);
+ failedTests.put(test, test);
+ }
+
+ final Element nested = doc.createElement(type);
+ Element currentTest;
+ if (test != null) {
+ currentTest = testElements.get(createDescription(test));
+ } else {
+ currentTest = rootElement;
+ }
+
+ currentTest.appendChild(nested);
+
+ final String message = t.getMessage();
+ if (message != null && message.length() > 0) {
+ nested.setAttribute(ATTR_MESSAGE, t.getMessage());
+ }
+ nested.setAttribute(ATTR_TYPE, t.getClass().getName());
+
+ final String strace = JUnitTestRunner.getFilteredTrace(t);
+ final Text trace = doc.createTextNode(strace);
+ nested.appendChild(trace);
+ }
+
+ private void formatOutput(final String type, final String output) {
+ final Element nested = doc.createElement(type);
+ rootElement.appendChild(nested);
+ nested.appendChild(doc.createCDATASection(output));
+ }
+
+ public void testIgnored(final Test test) {
+ formatSkip(test, JUnitVersionHelper.getIgnoreMessage(test));
+ if (test != null) {
+ ignoredTests.put(createDescription(test), test);
+ }
+ }
+
+
+ public void formatSkip(final Test test, final String message) {
+ if (test != null) {
+ endTest(test);
+ }
+
+ final Element nested = doc.createElement("skipped");
+
+ if (message != null) {
+ nested.setAttribute("message", message);
+ }
+
+ Element currentTest;
+ if (test != null) {
+ currentTest = testElements.get(createDescription(test));
+ } else {
+ currentTest = rootElement;
+ }
+
+ currentTest.appendChild(nested);
+
+ }
+
+ public void testAssumptionFailure(final Test test, final Throwable failure) {
+ formatSkip(test, failure.getMessage());
+ skippedTests.put(createDescription(test), test);
+
+ }
+} // XMLJUnitResultFormatter
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/XMLResultAggregator.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/XMLResultAggregator.java
new file mode 100644
index 00000000..4f76c968
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/junit/XMLResultAggregator.java
@@ -0,0 +1,329 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.junit;
+
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.DirectoryScanner;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.types.FileSet;
+import org.apache.tools.ant.util.DOMElementWriter;
+import org.apache.tools.ant.util.FileUtils;
+import org.apache.tools.ant.util.StringUtils;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.xml.sax.SAXException;
+
+
+/**
+ * Aggregates all &lt;junit&gt; XML formatter testsuite data under
+ * a specific directory and transforms the results via XSLT.
+ * It is not particularly clean but
+ * should be helpful while I am thinking about another technique.
+ *
+ * <p> The main problem is due to the fact that a JVM can be forked for a testcase
+ * thus making it impossible to aggregate all testcases since the listener is
+ * (obviously) in the forked JVM. A solution could be to write a
+ * TestListener that will receive events from the TestRunner via sockets. This
+ * is IMHO the simplest way to do it to avoid this file hacking thing.
+ *
+ * @ant.task name="junitreport" category="testing"
+ */
+public class XMLResultAggregator extends Task implements XMLConstants {
+
+ // CheckStyle:VisibilityModifier OFF - bc
+ /** the list of all filesets, that should contains the xml to aggregate */
+ protected Vector filesets = new Vector();
+
+ /** the name of the result file */
+ protected String toFile;
+
+ /** the directory to write the file to */
+ protected File toDir;
+
+ protected Vector transformers = new Vector();
+
+ /** The default directory: <tt>&#046;</tt>. It is resolved from the project directory */
+ public static final String DEFAULT_DIR = ".";
+
+ /** the default file name: <tt>TESTS-TestSuites.xml</tt> */
+ public static final String DEFAULT_FILENAME = "TESTS-TestSuites.xml";
+
+ /** the current generated id */
+ protected int generatedId = 0;
+
+ /**
+ * text checked for in tests, {@value}
+ */
+ static final String WARNING_IS_POSSIBLY_CORRUPTED
+ = " is not a valid XML document. It is possibly corrupted.";
+ /**
+ * text checked for in tests, {@value}
+ */
+ static final String WARNING_INVALID_ROOT_ELEMENT
+ = " is not a valid testsuite XML document";
+ /**
+ * text checked for in tests, {@value}
+ */
+ static final String WARNING_EMPTY_FILE
+ = " is empty.\nThis can be caused by the test JVM exiting unexpectedly";
+ // CheckStyle:VisibilityModifier ON
+
+ /**
+ * Generate a report based on the document created by the merge.
+ * @return the report
+ */
+ public AggregateTransformer createReport() {
+ AggregateTransformer transformer = new AggregateTransformer(this);
+ transformers.addElement(transformer);
+ return transformer;
+ }
+
+ /**
+ * Set the name of the aggregegated results file. It must be relative
+ * from the <tt>todir</tt> attribute. If not set it will use {@link #DEFAULT_FILENAME}
+ * @param value the name of the file.
+ * @see #setTodir(File)
+ */
+ public void setTofile(String value) {
+ toFile = value;
+ }
+
+ /**
+ * Set the destination directory where the results should be written. If not
+ * set if will use {@link #DEFAULT_DIR}. When given a relative directory
+ * it will resolve it from the project directory.
+ * @param value the directory where to write the results, absolute or
+ * relative.
+ */
+ public void setTodir(File value) {
+ toDir = value;
+ }
+
+ /**
+ * Add a new fileset containing the XML results to aggregate
+ * @param fs the new fileset of xml results.
+ */
+ public void addFileSet(FileSet fs) {
+ filesets.addElement(fs);
+ }
+
+ /**
+ * Aggregate all testsuites into a single document and write it to the
+ * specified directory and file.
+ * @throws BuildException thrown if there is a serious error while writing
+ * the document.
+ */
+ public void execute() throws BuildException {
+ Element rootElement = createDocument();
+ File destFile = getDestinationFile();
+ // write the document
+ try {
+ writeDOMTree(rootElement.getOwnerDocument(), destFile);
+ } catch (IOException e) {
+ throw new BuildException("Unable to write test aggregate to '" + destFile + "'", e);
+ }
+ // apply transformation
+ Enumeration e = transformers.elements();
+ while (e.hasMoreElements()) {
+ AggregateTransformer transformer =
+ (AggregateTransformer) e.nextElement();
+ transformer.setXmlDocument(rootElement.getOwnerDocument());
+ transformer.transform();
+ }
+ }
+
+ /**
+ * Get the full destination file where to write the result. It is made of
+ * the <tt>todir</tt> and <tt>tofile</tt> attributes.
+ * @return the destination file where should be written the result file.
+ */
+ public File getDestinationFile() {
+ if (toFile == null) {
+ toFile = DEFAULT_FILENAME;
+ }
+ if (toDir == null) {
+ toDir = getProject().resolveFile(DEFAULT_DIR);
+ }
+ return new File(toDir, toFile);
+ }
+
+ /**
+ * Get all <code>.xml</code> files in the fileset.
+ *
+ * @return all files in the fileset that end with a '.xml'.
+ */
+ protected File[] getFiles() {
+ Vector v = new Vector();
+ final int size = filesets.size();
+ for (int i = 0; i < size; i++) {
+ FileSet fs = (FileSet) filesets.elementAt(i);
+ DirectoryScanner ds = fs.getDirectoryScanner(getProject());
+ ds.scan();
+ String[] f = ds.getIncludedFiles();
+ for (int j = 0; j < f.length; j++) {
+ String pathname = f[j];
+ if (pathname.endsWith(".xml")) {
+ File file = new File(ds.getBasedir(), pathname);
+ file = getProject().resolveFile(file.getPath());
+ v.addElement(file);
+ }
+ }
+ }
+
+ File[] files = new File[v.size()];
+ v.copyInto(files);
+ return files;
+ }
+
+ //----- from now, the methods are all related to DOM tree manipulation
+
+ /**
+ * Write the DOM tree to a file.
+ * @param doc the XML document to dump to disk.
+ * @param file the filename to write the document to. Should obviously be a .xml file.
+ * @throws IOException thrown if there is an error while writing the content.
+ */
+ protected void writeDOMTree(Document doc, File file) throws IOException {
+ OutputStream os = new FileOutputStream(file);
+ try {
+ PrintWriter wri = new PrintWriter(new OutputStreamWriter(new BufferedOutputStream(os), "UTF8"));
+ wri.write("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n");
+ (new DOMElementWriter()).write(doc.getDocumentElement(), wri, 0, " ");
+ wri.flush();
+ // writers do not throw exceptions, so check for them.
+ if (wri.checkError()) {
+ throw new IOException("Error while writing DOM content");
+ }
+ } finally {
+ os.close();
+ }
+ }
+
+ /**
+ * <p> Create a DOM tree.
+ * Has 'testsuites' as firstchild and aggregates all
+ * testsuite results that exists in the base directory.
+ * @return the root element of DOM tree that aggregates all testsuites.
+ */
+ protected Element createDocument() {
+ // create the dom tree
+ DocumentBuilder builder = getDocumentBuilder();
+ Document doc = builder.newDocument();
+ Element rootElement = doc.createElement(TESTSUITES);
+ doc.appendChild(rootElement);
+
+ generatedId = 0;
+
+ // get all files and add them to the document
+ File[] files = getFiles();
+ for (int i = 0; i < files.length; i++) {
+ File file = files[i];
+ try {
+ log("Parsing file: '" + file + "'", Project.MSG_VERBOSE);
+ if (file.length() > 0) {
+ Document testsuiteDoc
+ = builder.parse(
+ FileUtils.getFileUtils().toURI(files[i].getAbsolutePath()));
+ Element elem = testsuiteDoc.getDocumentElement();
+ // make sure that this is REALLY a testsuite.
+ if (TESTSUITE.equals(elem.getNodeName())) {
+ addTestSuite(rootElement, elem);
+ generatedId++;
+ } else {
+ //wrong root element name
+ // issue a warning.
+ log("the file " + file
+ + WARNING_INVALID_ROOT_ELEMENT,
+ Project.MSG_WARN);
+ }
+ } else {
+ log("the file " + file
+ + WARNING_EMPTY_FILE,
+ Project.MSG_WARN);
+ }
+ } catch (SAXException e) {
+ // a testcase might have failed and write a zero-length document,
+ // It has already failed, but hey.... mm. just put a warning
+ log("The file " + file + WARNING_IS_POSSIBLY_CORRUPTED, Project.MSG_WARN);
+ log(StringUtils.getStackTrace(e), Project.MSG_DEBUG);
+ } catch (IOException e) {
+ log("Error while accessing file " + file + ": "
+ + e.getMessage(), Project.MSG_ERR);
+ log("Error while accessing file " + file + ": "
+ + e.getMessage(), e, Project.MSG_VERBOSE);
+ }
+ }
+ return rootElement;
+ }
+
+ /**
+ * <p> Add a new testsuite node to the document.
+ * The main difference is that it
+ * split the previous fully qualified name into a package and a name.
+ * <p> For example: <tt>org.apache.Whatever</tt> will be split into
+ * <tt>org.apache</tt> and <tt>Whatever</tt>.
+ * @param root the root element to which the <tt>testsuite</tt> node should
+ * be appended.
+ * @param testsuite the element to append to the given root. It will slightly
+ * modify the original node to change the name attribute and add
+ * a package one.
+ */
+ protected void addTestSuite(Element root, Element testsuite) {
+ String fullclassname = testsuite.getAttribute(ATTR_NAME);
+ int pos = fullclassname.lastIndexOf('.');
+
+ // a missing . might imply no package at all. Don't get fooled.
+ String pkgName = (pos == -1) ? "" : fullclassname.substring(0, pos);
+ String classname = (pos == -1) ? fullclassname : fullclassname.substring(pos + 1);
+ Element copy = (Element) DOMUtil.importNode(root, testsuite);
+
+ // modify the name attribute and set the package
+ copy.setAttribute(ATTR_NAME, classname);
+ copy.setAttribute(ATTR_PACKAGE, pkgName);
+ copy.setAttribute(ATTR_ID, Integer.toString(generatedId));
+ }
+
+ /**
+ * Create a new document builder. Will issue an <tt>ExceptionInitializerError</tt>
+ * if something is going wrong. It is fatal anyway.
+ * @todo factorize this somewhere else. It is duplicated code.
+ * @return a new document builder to create a DOM
+ */
+ private static DocumentBuilder getDocumentBuilder() {
+ try {
+ return DocumentBuilderFactory.newInstance().newDocumentBuilder();
+ } catch (Exception exc) {
+ throw new ExceptionInInitializerError(exc);
+ }
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/native2ascii/DefaultNative2Ascii.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/native2ascii/DefaultNative2Ascii.java
new file mode 100644
index 00000000..3cd52afe
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/native2ascii/DefaultNative2Ascii.java
@@ -0,0 +1,106 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.native2ascii;
+
+import java.io.File;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.ProjectComponent;
+import org.apache.tools.ant.taskdefs.optional.Native2Ascii;
+import org.apache.tools.ant.types.Commandline;
+
+/**
+ * encapsulates the handling common to diffent Native2Asciiadapter
+ * implementations.
+ *
+ * @since Ant 1.6.3
+ */
+public abstract class DefaultNative2Ascii implements Native2AsciiAdapter {
+
+ /** No-arg constructor. */
+ public DefaultNative2Ascii() {
+ }
+
+ /**
+ * Splits the task into setting up the command line switches
+ * @param args the native 2 ascii arguments.
+ * @param srcFile the source file.
+ * @param destFile the destination file.
+ * @return run if the conversion was successful.
+ * @throws BuildException if there is a problem.
+ * (delegated to {@link #setup setup}), adding the file names
+ * (delegated to {@link #addFiles addFiles}) and running the tool
+ * (delegated to {@link #run run}).
+ */
+ public final boolean convert(Native2Ascii args, File srcFile,
+ File destFile) throws BuildException {
+ Commandline cmd = new Commandline();
+ setup(cmd, args);
+ addFiles(cmd, args, srcFile, destFile);
+ return run(cmd, args);
+ }
+
+ /**
+ * Sets up the initial command line.
+ *
+ * <p>only the -encoding argument and nested arg elements get
+ * handled here.</p>
+ *
+ * @param cmd Command line to add to
+ * @param args provides the user-setting and access to Ant's
+ * logging system.
+ * @throws BuildException if there was a problem.
+ */
+ protected void setup(Commandline cmd, Native2Ascii args)
+ throws BuildException {
+ if (args.getEncoding() != null) {
+ cmd.createArgument().setValue("-encoding");
+ cmd.createArgument().setValue(args.getEncoding());
+ }
+ cmd.addArguments(args.getCurrentArgs());
+ }
+
+ /**
+ * Adds source and dest files to the command line.
+ *
+ * <p>This implementation adds them without any leading
+ * qualifiers, source first.</p>
+ *
+ * @param cmd Command line to add to
+ * @param log provides access to Ant's logging system.
+ * @param src the source file
+ * @param dest the destination file
+ * @throws BuildException if there was a problem.
+ */
+ protected void addFiles(Commandline cmd, ProjectComponent log, File src,
+ File dest) throws BuildException {
+ cmd.createArgument().setFile(src);
+ cmd.createArgument().setFile(dest);
+ }
+
+ /**
+ * Executes the command.
+ *
+ * @param cmd Command line to execute
+ * @param log provides access to Ant's logging system.
+ * @return whether execution was successful
+ * @throws BuildException if there was a problem.
+ */
+ protected abstract boolean run(Commandline cmd, ProjectComponent log)
+ throws BuildException;
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/native2ascii/KaffeNative2Ascii.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/native2ascii/KaffeNative2Ascii.java
new file mode 100644
index 00000000..da4836fd
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/native2ascii/KaffeNative2Ascii.java
@@ -0,0 +1,88 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.native2ascii;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.ProjectComponent;
+import org.apache.tools.ant.taskdefs.ExecuteJava;
+import org.apache.tools.ant.taskdefs.optional.Native2Ascii;
+import org.apache.tools.ant.types.Commandline;
+
+/**
+ * Adapter to kaffe.tools.native2ascii.Native2Ascii.
+ *
+ * @since Ant 1.6.3
+ */
+public final class KaffeNative2Ascii extends DefaultNative2Ascii {
+
+ // sorted by newest Kaffe version first
+ private static final String[] N2A_CLASSNAMES = new String[] {
+ "gnu.classpath.tools.native2ascii.Native2ASCII",
+ // pre Kaffe 1.1.5
+ "kaffe.tools.native2ascii.Native2Ascii",
+ };
+
+ /**
+ * Identifies this adapter.
+ */
+ public static final String IMPLEMENTATION_NAME = "kaffe";
+
+ /** {@inheritDoc} */
+ protected void setup(Commandline cmd, Native2Ascii args)
+ throws BuildException {
+ if (args.getReverse()) {
+ throw new BuildException("-reverse is not supported by Kaffe");
+ }
+ super.setup(cmd, args);
+ }
+
+ /** {@inheritDoc} */
+ protected boolean run(Commandline cmd, ProjectComponent log)
+ throws BuildException {
+ ExecuteJava ej = new ExecuteJava();
+ Class c = getN2aClass();
+ if (c == null) {
+ throw new BuildException("Couldn't load Kaffe's Native2Ascii"
+ + " class");
+ }
+
+ cmd.setExecutable(c.getName());
+ ej.setJavaCommand(cmd);
+ ej.execute(log.getProject());
+ // otherwise ExecuteJava has thrown an exception
+ return true;
+ }
+
+ /**
+ * tries to load Kaffe Native2Ascii and falls back to the older
+ * class name if necessary.
+ *
+ * @return null if neither class can get loaded.
+ */
+ private static Class getN2aClass() {
+ for (int i = 0; i < N2A_CLASSNAMES.length; i++) {
+ try {
+ return Class.forName(N2A_CLASSNAMES[i]);
+ } catch (ClassNotFoundException cnfe) {
+ // Ignore
+ }
+ }
+ return null;
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/native2ascii/Native2AsciiAdapter.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/native2ascii/Native2AsciiAdapter.java
new file mode 100644
index 00000000..af414004
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/native2ascii/Native2AsciiAdapter.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.native2ascii;
+
+import java.io.File;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.taskdefs.optional.Native2Ascii;
+
+/**
+ * Interface for an adapter to a native2ascii implementation.
+ *
+ * @since Ant 1.6.3
+ */
+// CheckStyle:HideUtilityClassConstructorCheck OFF (bc)
+public interface Native2AsciiAdapter {
+ /**
+ * Convert the encoding of srcFile writing to destFile.
+ *
+ * @param args Task that holds command line arguments and allows
+ * the implementation to send messages to Ant's logging system
+ * @param srcFile the source to convert
+ * @param destFile where to send output to
+ * @return whether the conversion has been successful.
+ * @throws BuildException if there was a problem.
+ */
+ boolean convert(Native2Ascii args, File srcFile, File destFile)
+ throws BuildException;
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/native2ascii/Native2AsciiAdapterFactory.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/native2ascii/Native2AsciiAdapterFactory.java
new file mode 100644
index 00000000..ae419039
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/native2ascii/Native2AsciiAdapterFactory.java
@@ -0,0 +1,116 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.native2ascii;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.ProjectComponent;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.util.ClasspathUtils;
+import org.apache.tools.ant.util.JavaEnvUtils;
+
+/**
+ * Creates the Native2AsciiAdapter based on the user choice and
+ * potentially the VM vendor.
+ *
+ * @since Ant 1.6.3
+ */
+// CheckStyle:HideUtilityClassConstructorCheck OFF (bc)
+public class Native2AsciiAdapterFactory {
+
+ /**
+ * Determines the default choice of adapter based on the VM
+ * vendor.
+ *
+ * @return the default choice of adapter based on the VM
+ * vendor
+ */
+ public static String getDefault() {
+ if (JavaEnvUtils.isKaffe() || JavaEnvUtils.isClasspathBased()) {
+ return KaffeNative2Ascii.IMPLEMENTATION_NAME;
+ }
+ return SunNative2Ascii.IMPLEMENTATION_NAME;
+ }
+
+ /**
+ * Creates the Native2AsciiAdapter based on the user choice and
+ * potentially the VM vendor.
+ *
+ * @param choice the user choice (if any).
+ * @param log a ProjectComponent instance used to access Ant's
+ * logging system.
+ * @return The adapter to use.
+ * @throws BuildException if there was a problem.
+ */
+ public static Native2AsciiAdapter getAdapter(String choice,
+ ProjectComponent log)
+ throws BuildException {
+ return getAdapter(choice, log, null);
+ }
+
+ /**
+ * Creates the Native2AsciiAdapter based on the user choice and
+ * potentially the VM vendor.
+ *
+ * @param choice the user choice (if any).
+ * @param log a ProjectComponent instance used to access Ant's
+ * logging system.
+ * @param classpath the classpath to use when looking up an
+ * adapter class
+ * @return The adapter to use.
+ * @throws BuildException if there was a problem.
+ * @since Ant 1.8.0
+ */
+ public static Native2AsciiAdapter getAdapter(String choice,
+ ProjectComponent log,
+ Path classpath)
+ throws BuildException {
+ if (((JavaEnvUtils.isKaffe() || JavaEnvUtils.isClasspathBased()) && choice == null)
+ || KaffeNative2Ascii.IMPLEMENTATION_NAME.equals(choice)) {
+ return new KaffeNative2Ascii();
+ } else if (SunNative2Ascii.IMPLEMENTATION_NAME.equals(choice)) {
+ return new SunNative2Ascii();
+ } else if (choice != null) {
+ return resolveClassName(choice,
+ // Memory leak in line below
+ log.getProject()
+ .createClassLoader(classpath));
+ }
+
+ // This default has been good enough until Ant 1.6.3, so stick
+ // with it
+ return new SunNative2Ascii();
+ }
+
+ /**
+ * Tries to resolve the given classname into a native2ascii adapter.
+ * Throws a fit if it can't.
+ *
+ * @param className The fully qualified classname to be created.
+ * @param loader the classloader to use
+ * @throws BuildException This is the fit that is thrown if className
+ * isn't an instance of Native2AsciiAdapter.
+ */
+ private static Native2AsciiAdapter resolveClassName(String className,
+ ClassLoader loader)
+ throws BuildException {
+ return (Native2AsciiAdapter) ClasspathUtils.newInstance(className,
+ loader != null ? loader :
+ Native2AsciiAdapterFactory.class.getClassLoader(),
+ Native2AsciiAdapter.class);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/native2ascii/SunNative2Ascii.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/native2ascii/SunNative2Ascii.java
new file mode 100644
index 00000000..fac94b18
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/native2ascii/SunNative2Ascii.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.native2ascii;
+
+import java.lang.reflect.Method;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.ProjectComponent;
+import org.apache.tools.ant.taskdefs.optional.Native2Ascii;
+import org.apache.tools.ant.types.Commandline;
+
+/**
+ * Adapter to sun.tools.native2ascii.Main.
+ *
+ * @since Ant 1.6.3
+ */
+public final class SunNative2Ascii extends DefaultNative2Ascii {
+
+ /**
+ * Identifies this adapter.
+ */
+ public static final String IMPLEMENTATION_NAME = "sun";
+
+ /** {@inheritDoc} */
+ protected void setup(Commandline cmd, Native2Ascii args)
+ throws BuildException {
+ if (args.getReverse()) {
+ cmd.createArgument().setValue("-reverse");
+ }
+ super.setup(cmd, args);
+ }
+
+ /** {@inheritDoc} */
+ protected boolean run(Commandline cmd, ProjectComponent log)
+ throws BuildException {
+ try {
+ Class n2aMain = Class.forName("sun.tools.native2ascii.Main");
+ Class[] param = new Class[] {String[].class};
+ Method convert = n2aMain.getMethod("convert", param);
+ if (convert == null) {
+ throw new BuildException("Could not find convert() method in "
+ + "sun.tools.native2ascii.Main");
+ }
+ Object o = n2aMain.newInstance();
+ return ((Boolean) convert.invoke(o,
+ new Object[] {cmd.getArguments()})
+ ).booleanValue();
+ } catch (BuildException ex) {
+ //rethrow
+ throw ex;
+ } catch (Exception ex) {
+ //wrap
+ throw new BuildException("Error starting Sun's native2ascii: ", ex);
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/net/FTP.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/net/FTP.java
new file mode 100644
index 00000000..cef9dda0
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/net/FTP.java
@@ -0,0 +1,2725 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.net;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.text.SimpleDateFormat;
+import java.util.Collection;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import org.apache.commons.net.ftp.FTPClient;
+import org.apache.commons.net.ftp.FTPClientConfig;
+import org.apache.commons.net.ftp.FTPFile;
+import org.apache.commons.net.ftp.FTPReply;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.DirectoryScanner;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.taskdefs.Delete;
+import org.apache.tools.ant.types.EnumeratedAttribute;
+import org.apache.tools.ant.types.FileSet;
+import org.apache.tools.ant.types.selectors.SelectorUtils;
+import org.apache.tools.ant.util.FileUtils;
+import org.apache.tools.ant.util.RetryHandler;
+import org.apache.tools.ant.util.Retryable;
+import org.apache.tools.ant.util.VectorSet;
+
+/**
+ * Basic FTP client. Performs the following actions:
+ * <ul>
+ * <li> <strong>send</strong> - send files to a remote server. This is the
+ * default action.</li>
+ * <li> <strong>get</strong> - retrieve files from a remote server.</li>
+ * <li> <strong>del</strong> - delete files from a remote server.</li>
+ * <li> <strong>list</strong> - create a file listing.</li>
+ * <li> <strong>chmod</strong> - change unix file permissions.</li>
+ * <li> <strong>rmdir</strong> - remove directories, if empty, from a
+ * remote server.</li>
+ * </ul>
+ * <strong>Note:</strong> Some FTP servers - notably the Solaris server - seem
+ * to hold data ports open after a "retr" operation, allowing them to timeout
+ * instead of shutting them down cleanly. This happens in active or passive
+ * mode, and the ports will remain open even after ending the FTP session. FTP
+ * "send" operations seem to close ports immediately. This behavior may cause
+ * problems on some systems when downloading large sets of files.
+ *
+ * @since Ant 1.3
+ */
+public class FTP extends Task implements FTPTaskConfig {
+ protected static final int SEND_FILES = 0;
+ protected static final int GET_FILES = 1;
+ protected static final int DEL_FILES = 2;
+ protected static final int LIST_FILES = 3;
+ protected static final int MK_DIR = 4;
+ protected static final int CHMOD = 5;
+ protected static final int RM_DIR = 6;
+ protected static final int SITE_CMD = 7;
+ /** return code of ftp */
+ private static final int CODE_521 = 521;
+ private static final int CODE_550 = 550;
+ private static final int CODE_553 = 553;
+
+ /** adjust uptodate calculations where server timestamps are HH:mm and client's
+ * are HH:mm:ss */
+ private static final long GRANULARITY_MINUTE = 60000L;
+
+ /** Date formatter used in logging, note not thread safe! */
+ private static final SimpleDateFormat TIMESTAMP_LOGGING_SDF =
+ new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+
+ /** Default port for FTP */
+ public static final int DEFAULT_FTP_PORT = 21;
+
+ private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+
+ private String remotedir;
+ private String server;
+ private String userid;
+ private String password;
+ private String account;
+ private File listing;
+ private boolean binary = true;
+ private boolean passive = false;
+ private boolean verbose = false;
+ private boolean newerOnly = false;
+ private long timeDiffMillis = 0;
+ private long granularityMillis = 0L;
+ private boolean timeDiffAuto = false;
+ private int action = SEND_FILES;
+ private Vector filesets = new Vector();
+ private Set dirCache = new HashSet();
+ private int transferred = 0;
+ private String remoteFileSep = "/";
+ private int port = DEFAULT_FTP_PORT;
+ private boolean skipFailedTransfers = false;
+ private int skipped = 0;
+ private boolean ignoreNoncriticalErrors = false;
+ private boolean preserveLastModified = false;
+ private String chmod = null;
+ private String umask = null;
+ private FTPSystemType systemTypeKey = FTPSystemType.getDefault();
+ private String defaultDateFormatConfig = null;
+ private String recentDateFormatConfig = null;
+ private LanguageCode serverLanguageCodeConfig = LanguageCode.getDefault();
+ private String serverTimeZoneConfig = null;
+ private String shortMonthNamesConfig = null;
+ private Granularity timestampGranularity = Granularity.getDefault();
+ private boolean isConfigurationSet = false;
+ private int retriesAllowed = 0;
+ private String siteCommand = null;
+ private String initialSiteCommand = null;
+ private boolean enableRemoteVerification = true;
+
+ protected static final String[] ACTION_STRS = {
+ "sending",
+ "getting",
+ "deleting",
+ "listing",
+ "making directory",
+ "chmod",
+ "removing",
+ "site"
+ };
+
+ protected static final String[] COMPLETED_ACTION_STRS = {
+ "sent",
+ "retrieved",
+ "deleted",
+ "listed",
+ "created directory",
+ "mode changed",
+ "removed",
+ "site command executed"
+ };
+
+ protected static final String[] ACTION_TARGET_STRS = {
+ "files",
+ "files",
+ "files",
+ "files",
+ "directory",
+ "files",
+ "directories",
+ "site command"
+ };
+
+ /**
+ * internal class providing a File-like interface to some of the information
+ * available from the FTP server
+ *
+ */
+ protected static class FTPFileProxy extends File {
+
+ private final FTPFile file;
+ private final String[] parts;
+ private final String name;
+
+ /**
+ * creates a proxy to a FTP file
+ * @param file
+ */
+ public FTPFileProxy(FTPFile file) {
+ super(file.getName());
+ name = file.getName();
+ this.file = file;
+ parts = FileUtils.getPathStack(name);
+ }
+
+ /**
+ * creates a proxy to a FTP directory
+ * @param completePath the remote directory.
+ */
+ public FTPFileProxy(String completePath) {
+ super(completePath);
+ file = null;
+ name = completePath;
+ parts = FileUtils.getPathStack(completePath);
+ }
+
+
+ /* (non-Javadoc)
+ * @see java.io.File#exists()
+ */
+ public boolean exists() {
+ return true;
+ }
+
+
+ /* (non-Javadoc)
+ * @see java.io.File#getAbsolutePath()
+ */
+ public String getAbsolutePath() {
+ return name;
+ }
+
+
+ /* (non-Javadoc)
+ * @see java.io.File#getName()
+ */
+ public String getName() {
+ return parts.length > 0 ? parts[parts.length - 1] : name;
+ }
+
+
+ /* (non-Javadoc)
+ * @see java.io.File#getParent()
+ */
+ public String getParent() {
+ String result = "";
+ for(int i = 0; i < parts.length - 1; i++){
+ result += File.separatorChar + parts[i];
+ }
+ return result;
+ }
+
+
+ /* (non-Javadoc)
+ * @see java.io.File#getPath()
+ */
+ public String getPath() {
+ return name;
+ }
+
+
+ /**
+ * FTP files are stored as absolute paths
+ * @return true
+ */
+ public boolean isAbsolute() {
+ return true;
+ }
+
+
+ /* (non-Javadoc)
+ * @see java.io.File#isDirectory()
+ */
+ public boolean isDirectory() {
+ return file == null;
+ }
+
+
+ /* (non-Javadoc)
+ * @see java.io.File#isFile()
+ */
+ public boolean isFile() {
+ return file != null;
+ }
+
+
+ /**
+ * FTP files cannot be hidden
+ *
+ * @return false
+ */
+ public boolean isHidden() {
+ return false;
+ }
+
+
+ /* (non-Javadoc)
+ * @see java.io.File#lastModified()
+ */
+ public long lastModified() {
+ if (file != null) {
+ return file.getTimestamp().getTimeInMillis();
+ }
+ return 0;
+ }
+
+
+ /* (non-Javadoc)
+ * @see java.io.File#length()
+ */
+ public long length() {
+ if (file != null) {
+ return file.getSize();
+ }
+ return 0;
+ }
+ }
+
+ /**
+ * internal class allowing to read the contents of a remote file system
+ * using the FTP protocol
+ * used in particular for ftp get operations
+ * differences with DirectoryScanner
+ * "" (the root of the fileset) is never included in the included directories
+ * followSymlinks defaults to false
+ */
+ protected class FTPDirectoryScanner extends DirectoryScanner {
+ // CheckStyle:VisibilityModifier OFF - bc
+ protected FTPClient ftp = null;
+ // CheckStyle:VisibilityModifier ON
+
+ private String rootPath = null;
+
+ /**
+ * since ant 1.6
+ * this flag should be set to true on UNIX and can save scanning time
+ */
+ private boolean remoteSystemCaseSensitive = false;
+ private boolean remoteSensitivityChecked = false;
+
+ /**
+ * constructor
+ * @param ftp ftpclient object
+ */
+ public FTPDirectoryScanner(FTPClient ftp) {
+ super();
+ this.ftp = ftp;
+ this.setFollowSymlinks(false);
+ }
+
+
+ /**
+ * scans the remote directory,
+ * storing internally the included files, directories, ...
+ */
+ public void scan() {
+ if (includes == null) {
+ // No includes supplied, so set it to 'matches all'
+ includes = new String[1];
+ includes[0] = "**";
+ }
+ if (excludes == null) {
+ excludes = new String[0];
+ }
+
+ filesIncluded = new VectorSet();
+ filesNotIncluded = new Vector();
+ filesExcluded = new VectorSet();
+ dirsIncluded = new VectorSet();
+ dirsNotIncluded = new Vector();
+ dirsExcluded = new VectorSet();
+
+ try {
+ String cwd = ftp.printWorkingDirectory();
+ // always start from the current ftp working dir
+ forceRemoteSensitivityCheck();
+
+ checkIncludePatterns();
+ clearCaches();
+ ftp.changeWorkingDirectory(cwd);
+ } catch (IOException e) {
+ throw new BuildException("Unable to scan FTP server: ", e);
+ }
+ }
+
+
+ /**
+ * this routine is actually checking all the include patterns in
+ * order to avoid scanning everything under base dir
+ * @since ant1.6
+ */
+ private void checkIncludePatterns() {
+
+ Hashtable newroots = new Hashtable();
+ // put in the newroots vector the include patterns without
+ // wildcard tokens
+ for (int icounter = 0; icounter < includes.length; icounter++) {
+ String newpattern =
+ SelectorUtils.rtrimWildcardTokens(includes[icounter]);
+ newroots.put(newpattern, includes[icounter]);
+ }
+ if (remotedir == null) {
+ try {
+ remotedir = ftp.printWorkingDirectory();
+ } catch (IOException e) {
+ throw new BuildException("could not read current ftp directory",
+ getLocation());
+ }
+ }
+ AntFTPFile baseFTPFile = new AntFTPRootFile(ftp, remotedir);
+ rootPath = baseFTPFile.getAbsolutePath();
+ // construct it
+ if (newroots.containsKey("")) {
+ // we are going to scan everything anyway
+ scandir(rootPath, "", true);
+ } else {
+ // only scan directories that can include matched files or
+ // directories
+ Enumeration enum2 = newroots.keys();
+
+ while (enum2.hasMoreElements()) {
+ String currentelement = (String) enum2.nextElement();
+ String originalpattern = (String) newroots.get(currentelement);
+ AntFTPFile myfile = new AntFTPFile(baseFTPFile, currentelement);
+ boolean isOK = true;
+ boolean traversesSymlinks = false;
+ String path = null;
+
+ if (myfile.exists()) {
+ forceRemoteSensitivityCheck();
+ if (remoteSensitivityChecked
+ && remoteSystemCaseSensitive && isFollowSymlinks()) {
+ // cool case,
+ //we do not need to scan all the subdirs in the relative path
+ path = myfile.getFastRelativePath();
+ } else {
+ // may be on a case insensitive file system. We want
+ // the results to show what's really on the disk, so
+ // we need to double check.
+ try {
+ path = myfile.getRelativePath();
+ traversesSymlinks = myfile.isTraverseSymlinks();
+ } catch (IOException be) {
+ throw new BuildException(be, getLocation());
+ } catch (BuildException be) {
+ isOK = false;
+ }
+ }
+ } else {
+ isOK = false;
+ }
+ if (isOK) {
+ currentelement = path.replace(remoteFileSep.charAt(0), File.separatorChar);
+ if (!isFollowSymlinks()
+ && traversesSymlinks) {
+ continue;
+ }
+
+ if (myfile.isDirectory()) {
+ if (isIncluded(currentelement)
+ && currentelement.length() > 0) {
+ accountForIncludedDir(currentelement, myfile, true);
+ } else {
+ if (currentelement.length() > 0) {
+ if (currentelement.charAt(currentelement
+ .length() - 1)
+ != File.separatorChar) {
+ currentelement =
+ currentelement + File.separatorChar;
+ }
+ }
+ scandir(myfile.getAbsolutePath(), currentelement, true);
+ }
+ } else {
+ if (isCaseSensitive
+ && originalpattern.equals(currentelement)) {
+ accountForIncludedFile(currentelement);
+ } else if (!isCaseSensitive
+ && originalpattern
+ .equalsIgnoreCase(currentelement)) {
+ accountForIncludedFile(currentelement);
+ }
+ }
+ }
+ }
+ }
+ }
+ /**
+ * scans a particular directory. populates the scannedDirs cache.
+ *
+ * @param dir directory to scan
+ * @param vpath relative path to the base directory of the remote fileset
+ * always ended with a File.separator
+ * @param fast seems to be always true in practice
+ */
+ protected void scandir(String dir, String vpath, boolean fast) {
+ // avoid double scanning of directories, can only happen in fast mode
+ if (fast && hasBeenScanned(vpath)) {
+ return;
+ }
+ try {
+ if (!ftp.changeWorkingDirectory(dir)) {
+ return;
+ }
+ String completePath = null;
+ if (!vpath.equals("")) {
+ completePath = rootPath + remoteFileSep
+ + vpath.replace(File.separatorChar, remoteFileSep.charAt(0));
+ } else {
+ completePath = rootPath;
+ }
+ FTPFile[] newfiles = listFiles(completePath, false);
+
+ if (newfiles == null) {
+ ftp.changeToParentDirectory();
+ return;
+ }
+ for (int i = 0; i < newfiles.length; i++) {
+ FTPFile file = newfiles[i];
+ if (file != null
+ && !file.getName().equals(".")
+ && !file.getName().equals("..")) {
+ String name = vpath + file.getName();
+ scannedDirs.put(name, new FTPFileProxy(file));
+ if (isFunctioningAsDirectory(ftp, dir, file)) {
+ boolean slowScanAllowed = true;
+ if (!isFollowSymlinks() && file.isSymbolicLink()) {
+ dirsExcluded.addElement(name);
+ slowScanAllowed = false;
+ } else if (isIncluded(name)) {
+ accountForIncludedDir(name,
+ new AntFTPFile(ftp, file, completePath) , fast);
+ } else {
+ dirsNotIncluded.addElement(name);
+ if (fast && couldHoldIncluded(name)) {
+ scandir(file.getName(),
+ name + File.separator, fast);
+ }
+ }
+ if (!fast && slowScanAllowed) {
+ scandir(file.getName(),
+ name + File.separator, fast);
+ }
+ } else {
+ if (!isFollowSymlinks() && file.isSymbolicLink()) {
+ filesExcluded.addElement(name);
+ } else if (isFunctioningAsFile(ftp, dir, file)) {
+ accountForIncludedFile(name);
+ }
+ }
+ }
+ }
+ ftp.changeToParentDirectory();
+ } catch (IOException e) {
+ throw new BuildException("Error while communicating with FTP "
+ + "server: ", e);
+ }
+ }
+ /**
+ * process included file
+ * @param name path of the file relative to the directory of the fileset
+ */
+ private void accountForIncludedFile(String name) {
+ if (!filesIncluded.contains(name)
+ && !filesExcluded.contains(name)) {
+
+ if (isIncluded(name)) {
+ if (!isExcluded(name)
+ && isSelected(name, (File) scannedDirs.get(name))) {
+ filesIncluded.addElement(name);
+ } else {
+ filesExcluded.addElement(name);
+ }
+ } else {
+ filesNotIncluded.addElement(name);
+ }
+ }
+ }
+
+ /**
+ *
+ * @param name path of the directory relative to the directory of
+ * the fileset
+ * @param file directory as file
+ * @param fast
+ */
+ private void accountForIncludedDir(String name, AntFTPFile file, boolean fast) {
+ if (!dirsIncluded.contains(name)
+ && !dirsExcluded.contains(name)) {
+
+ if (!isExcluded(name)) {
+ if (fast) {
+ if (file.isSymbolicLink()) {
+ try {
+ file.getClient().changeWorkingDirectory(file.curpwd);
+ } catch (IOException ioe) {
+ throw new BuildException("could not change directory to curpwd");
+ }
+ scandir(file.getLink(),
+ name + File.separator, fast);
+ } else {
+ try {
+ file.getClient().changeWorkingDirectory(file.curpwd);
+ } catch (IOException ioe) {
+ throw new BuildException("could not change directory to curpwd");
+ }
+ scandir(file.getName(),
+ name + File.separator, fast);
+ }
+ }
+ dirsIncluded.addElement(name);
+ } else {
+ dirsExcluded.addElement(name);
+ if (fast && couldHoldIncluded(name)) {
+ try {
+ file.getClient().changeWorkingDirectory(file.curpwd);
+ } catch (IOException ioe) {
+ throw new BuildException("could not change directory to curpwd");
+ }
+ scandir(file.getName(),
+ name + File.separator, fast);
+ }
+ }
+ }
+ }
+ /**
+ * temporary table to speed up the various scanning methods below
+ *
+ * @since Ant 1.6
+ */
+ private Map fileListMap = new HashMap();
+ /**
+ * List of all scanned directories.
+ *
+ * @since Ant 1.6
+ */
+
+ private Map scannedDirs = new HashMap();
+
+ /**
+ * Has the directory with the given path relative to the base
+ * directory already been scanned?
+ *
+ * @since Ant 1.6
+ */
+ private boolean hasBeenScanned(String vpath) {
+ return scannedDirs.containsKey(vpath);
+ }
+
+ /**
+ * Clear internal caches.
+ *
+ * @since Ant 1.6
+ */
+ private void clearCaches() {
+ fileListMap.clear();
+ scannedDirs.clear();
+ }
+ /**
+ * list the files present in one directory.
+ * @param directory full path on the remote side
+ * @param changedir if true change to directory directory before listing
+ * @return array of FTPFile
+ */
+ public FTPFile[] listFiles(String directory, boolean changedir) {
+ //getProject().log("listing files in directory " + directory, Project.MSG_DEBUG);
+ String currentPath = directory;
+ if (changedir) {
+ try {
+ boolean result = ftp.changeWorkingDirectory(directory);
+ if (!result) {
+ return null;
+ }
+ currentPath = ftp.printWorkingDirectory();
+ } catch (IOException ioe) {
+ throw new BuildException(ioe, getLocation());
+ }
+ }
+ if (fileListMap.containsKey(currentPath)) {
+ getProject().log("filelist map used in listing files", Project.MSG_DEBUG);
+ return ((FTPFile[]) fileListMap.get(currentPath));
+ }
+ FTPFile[] result = null;
+ try {
+ result = ftp.listFiles();
+ } catch (IOException ioe) {
+ throw new BuildException(ioe, getLocation());
+ }
+ fileListMap.put(currentPath, result);
+ if (!remoteSensitivityChecked) {
+ checkRemoteSensitivity(result, directory);
+ }
+ return result;
+ }
+
+ private void forceRemoteSensitivityCheck() {
+ if (!remoteSensitivityChecked) {
+ try {
+ checkRemoteSensitivity(ftp.listFiles(), ftp.printWorkingDirectory());
+ } catch (IOException ioe) {
+ throw new BuildException(ioe, getLocation());
+ }
+ }
+ }
+ /**
+ * cd into one directory and
+ * list the files present in one directory.
+ * @param directory full path on the remote side
+ * @return array of FTPFile
+ */
+ public FTPFile[] listFiles(String directory) {
+ return listFiles(directory, true);
+ }
+ private void checkRemoteSensitivity(FTPFile[] array, String directory) {
+ if (array == null) {
+ return;
+ }
+ boolean candidateFound = false;
+ String target = null;
+ for (int icounter = 0; icounter < array.length; icounter++) {
+ if (array[icounter] != null && array[icounter].isDirectory()) {
+ if (!array[icounter].getName().equals(".")
+ && !array[icounter].getName().equals("..")) {
+ candidateFound = true;
+ target = fiddleName(array[icounter].getName());
+ getProject().log("will try to cd to "
+ + target + " where a directory called " + array[icounter].getName()
+ + " exists", Project.MSG_DEBUG);
+ for (int pcounter = 0; pcounter < array.length; pcounter++) {
+ if (array[pcounter] != null
+ && pcounter != icounter
+ && target.equals(array[pcounter].getName())) {
+ candidateFound = false;
+ break;
+ }
+ }
+ if (candidateFound) {
+ break;
+ }
+ }
+ }
+ }
+ if (candidateFound) {
+ try {
+ getProject().log("testing case sensitivity, attempting to cd to "
+ + target, Project.MSG_DEBUG);
+ remoteSystemCaseSensitive = !ftp.changeWorkingDirectory(target);
+ } catch (IOException ioe) {
+ remoteSystemCaseSensitive = true;
+ } finally {
+ try {
+ ftp.changeWorkingDirectory(directory);
+ } catch (IOException ioe) {
+ throw new BuildException(ioe, getLocation());
+ }
+ }
+ getProject().log("remote system is case sensitive : " + remoteSystemCaseSensitive,
+ Project.MSG_VERBOSE);
+ remoteSensitivityChecked = true;
+ }
+ }
+ private String fiddleName(String origin) {
+ StringBuffer result = new StringBuffer();
+ for (int icounter = 0; icounter < origin.length(); icounter++) {
+ if (Character.isLowerCase(origin.charAt(icounter))) {
+ result.append(Character.toUpperCase(origin.charAt(icounter)));
+ } else if (Character.isUpperCase(origin.charAt(icounter))) {
+ result.append(Character.toLowerCase(origin.charAt(icounter)));
+ } else {
+ result.append(origin.charAt(icounter));
+ }
+ }
+ return result.toString();
+ }
+ /**
+ * an AntFTPFile is a representation of a remote file
+ * @since Ant 1.6
+ */
+ protected class AntFTPFile {
+ /**
+ * ftp client
+ */
+ private FTPClient client;
+ /**
+ * parent directory of the file
+ */
+ private String curpwd;
+ /**
+ * the file itself
+ */
+ private FTPFile ftpFile;
+ /**
+ *
+ */
+ private AntFTPFile parent = null;
+ private boolean relativePathCalculated = false;
+ private boolean traversesSymlinks = false;
+ private String relativePath = "";
+ /**
+ * constructor
+ * @param client ftp client variable
+ * @param ftpFile the file
+ * @param curpwd absolute remote path where the file is found
+ */
+ public AntFTPFile(FTPClient client, FTPFile ftpFile, String curpwd) {
+ this.client = client;
+ this.ftpFile = ftpFile;
+ this.curpwd = curpwd;
+ }
+ /**
+ * other constructor
+ * @param parent the parent file
+ * @param path a relative path to the parent file
+ */
+ public AntFTPFile(AntFTPFile parent, String path) {
+ this.parent = parent;
+ this.client = parent.client;
+ Vector pathElements = SelectorUtils.tokenizePath(path);
+ try {
+ boolean result = this.client.changeWorkingDirectory(parent.getAbsolutePath());
+ //this should not happen, except if parent has been deleted by another process
+ if (!result) {
+ return;
+ }
+ this.curpwd = parent.getAbsolutePath();
+ } catch (IOException ioe) {
+ throw new BuildException("could not change working dir to "
+ + parent.curpwd);
+ }
+ final int size = pathElements.size();
+ for (int fcount = 0; fcount < size - 1; fcount++) {
+ String currentPathElement = (String) pathElements.elementAt(fcount);
+ try {
+ boolean result = this.client.changeWorkingDirectory(currentPathElement);
+ if (!result && !isCaseSensitive()
+ && (remoteSystemCaseSensitive || !remoteSensitivityChecked)) {
+ currentPathElement = findPathElementCaseUnsensitive(this.curpwd,
+ currentPathElement);
+ if (currentPathElement == null) {
+ return;
+ }
+ } else if (!result) {
+ return;
+ }
+ this.curpwd = getCurpwdPlusFileSep()
+ + currentPathElement;
+ } catch (IOException ioe) {
+ throw new BuildException("could not change working dir to "
+ + (String) pathElements.elementAt(fcount)
+ + " from " + this.curpwd);
+ }
+
+ }
+ String lastpathelement = (String) pathElements.elementAt(size - 1);
+ FTPFile [] theFiles = listFiles(this.curpwd);
+ this.ftpFile = getFile(theFiles, lastpathelement);
+ }
+ /**
+ * find a file in a directory in case unsensitive way
+ * @param parentPath where we are
+ * @param soughtPathElement what is being sought
+ * @return the first file found or null if not found
+ */
+ private String findPathElementCaseUnsensitive(String parentPath,
+ String soughtPathElement) {
+ // we are already in the right path, so the second parameter
+ // is false
+ FTPFile[] theFiles = listFiles(parentPath, false);
+ if (theFiles == null) {
+ return null;
+ }
+ for (int icounter = 0; icounter < theFiles.length; icounter++) {
+ if (theFiles[icounter] != null
+ && theFiles[icounter].getName().equalsIgnoreCase(soughtPathElement)) {
+ return theFiles[icounter].getName();
+ }
+ }
+ return null;
+ }
+ /**
+ * find out if the file exists
+ * @return true if the file exists
+ */
+ public boolean exists() {
+ return (ftpFile != null);
+ }
+ /**
+ * if the file is a symbolic link, find out to what it is pointing
+ * @return the target of the symbolic link
+ */
+ public String getLink() {
+ return ftpFile.getLink();
+ }
+ /**
+ * get the name of the file
+ * @return the name of the file
+ */
+ public String getName() {
+ return ftpFile.getName();
+ }
+ /**
+ * find out the absolute path of the file
+ * @return absolute path as string
+ */
+ public String getAbsolutePath() {
+ return getCurpwdPlusFileSep() + ftpFile.getName();
+ }
+ /**
+ * find out the relative path assuming that the path used to construct
+ * this AntFTPFile was spelled properly with regards to case.
+ * This is OK on a case sensitive system such as UNIX
+ * @return relative path
+ */
+ public String getFastRelativePath() {
+ String absPath = getAbsolutePath();
+ if (absPath.startsWith(rootPath + remoteFileSep)) {
+ return absPath.substring(rootPath.length() + remoteFileSep.length());
+ }
+ return null;
+ }
+ /**
+ * find out the relative path to the rootPath of the enclosing scanner.
+ * this relative path is spelled exactly like on disk,
+ * for instance if the AntFTPFile has been instantiated as ALPHA,
+ * but the file is really called alpha, this method will return alpha.
+ * If a symbolic link is encountered, it is followed, but the name of the link
+ * rather than the name of the target is returned.
+ * (ie does not behave like File.getCanonicalPath())
+ * @return relative path, separated by remoteFileSep
+ * @throws IOException if a change directory fails, ...
+ * @throws BuildException if one of the components of the relative path cannot
+ * be found.
+ */
+ public String getRelativePath() throws IOException, BuildException {
+ if (!relativePathCalculated) {
+ if (parent != null) {
+ traversesSymlinks = parent.isTraverseSymlinks();
+ relativePath = getRelativePath(parent.getAbsolutePath(),
+ parent.getRelativePath());
+ } else {
+ relativePath = getRelativePath(rootPath, "");
+ relativePathCalculated = true;
+ }
+ }
+ return relativePath;
+ }
+ /**
+ * get the relative path of this file
+ * @param currentPath base path
+ * @param currentRelativePath relative path of the base path with regards to remote dir
+ * @return relative path
+ */
+ private String getRelativePath(String currentPath, String currentRelativePath) {
+ Vector pathElements = SelectorUtils.tokenizePath(getAbsolutePath(), remoteFileSep);
+ Vector pathElements2 = SelectorUtils.tokenizePath(currentPath, remoteFileSep);
+ String relPath = currentRelativePath;
+ final int size = pathElements.size();
+ for (int pcount = pathElements2.size(); pcount < size; pcount++) {
+ String currentElement = (String) pathElements.elementAt(pcount);
+ FTPFile[] theFiles = listFiles(currentPath);
+ FTPFile theFile = null;
+ if (theFiles != null) {
+ theFile = getFile(theFiles, currentElement);
+ }
+ if (!relPath.equals("")) {
+ relPath = relPath + remoteFileSep;
+ }
+ if (theFile == null) {
+ // hit a hidden file assume not a symlink
+ relPath = relPath + currentElement;
+ currentPath = currentPath + remoteFileSep + currentElement;
+ log("Hidden file " + relPath
+ + " assumed to not be a symlink.",
+ Project.MSG_VERBOSE);
+ } else {
+ traversesSymlinks = traversesSymlinks || theFile.isSymbolicLink();
+ relPath = relPath + theFile.getName();
+ currentPath = currentPath + remoteFileSep + theFile.getName();
+ }
+ }
+ return relPath;
+ }
+ /**
+ * find a file matching a string in an array of FTPFile.
+ * This method will find "alpha" when requested for "ALPHA"
+ * if and only if the caseSensitive attribute is set to false.
+ * When caseSensitive is set to true, only the exact match is returned.
+ * @param theFiles array of files
+ * @param lastpathelement the file name being sought
+ * @return null if the file cannot be found, otherwise return the matching file.
+ */
+ public FTPFile getFile(FTPFile[] theFiles, String lastpathelement) {
+ if (theFiles == null) {
+ return null;
+ }
+ for (int fcount = 0; fcount < theFiles.length; fcount++) {
+ if (theFiles[fcount] != null) {
+ if (theFiles[fcount].getName().equals(lastpathelement)) {
+ return theFiles[fcount];
+ } else if (!isCaseSensitive()
+ && theFiles[fcount].getName().equalsIgnoreCase(
+ lastpathelement)) {
+ return theFiles[fcount];
+ }
+ }
+ }
+ return null;
+ }
+ /**
+ * tell if a file is a directory.
+ * note that it will return false for symbolic links pointing to directories.
+ * @return <code>true</code> for directories
+ */
+ public boolean isDirectory() {
+ return ftpFile.isDirectory();
+ }
+ /**
+ * tell if a file is a symbolic link
+ * @return <code>true</code> for symbolic links
+ */
+ public boolean isSymbolicLink() {
+ return ftpFile.isSymbolicLink();
+ }
+ /**
+ * return the attached FTP client object.
+ * Warning : this instance is really shared with the enclosing class.
+ * @return FTP client
+ */
+ protected FTPClient getClient() {
+ return client;
+ }
+
+ /**
+ * sets the current path of an AntFTPFile
+ * @param curpwd the current path one wants to set
+ */
+ protected void setCurpwd(String curpwd) {
+ this.curpwd = curpwd;
+ }
+ /**
+ * returns the path of the directory containing the AntFTPFile.
+ * of the full path of the file itself in case of AntFTPRootFile
+ * @return parent directory of the AntFTPFile
+ */
+ public String getCurpwd() {
+ return curpwd;
+ }
+ /**
+ * returns the path of the directory containing the AntFTPFile.
+ * of the full path of the file itself in case of AntFTPRootFile
+ * and appends the remote file separator if necessary.
+ * @return parent directory of the AntFTPFile
+ * @since Ant 1.8.2
+ */
+ public String getCurpwdPlusFileSep() {
+ return curpwd.endsWith(remoteFileSep) ? curpwd
+ : curpwd + remoteFileSep;
+ }
+ /**
+ * find out if a symbolic link is encountered in the relative path of this file
+ * from rootPath.
+ * @return <code>true</code> if a symbolic link is encountered in the relative path.
+ * @throws IOException if one of the change directory or directory listing operations
+ * fails
+ * @throws BuildException if a path component in the relative path cannot be found.
+ */
+ public boolean isTraverseSymlinks() throws IOException, BuildException {
+ if (!relativePathCalculated) {
+ // getRelativePath also finds about symlinks
+ getRelativePath();
+ }
+ return traversesSymlinks;
+ }
+
+ /**
+ * Get a string rep of this object.
+ * @return a string containing the pwd and the file.
+ */
+ public String toString() {
+ return "AntFtpFile: " + curpwd + "%" + ftpFile;
+ }
+ }
+ /**
+ * special class to represent the remote directory itself
+ * @since Ant 1.6
+ */
+ protected class AntFTPRootFile extends AntFTPFile {
+ private String remotedir;
+ /**
+ * constructor
+ * @param aclient FTP client
+ * @param remotedir remote directory
+ */
+ public AntFTPRootFile(FTPClient aclient, String remotedir) {
+ super(aclient, null, remotedir);
+ this.remotedir = remotedir;
+ try {
+ this.getClient().changeWorkingDirectory(this.remotedir);
+ this.setCurpwd(this.getClient().printWorkingDirectory());
+ } catch (IOException ioe) {
+ throw new BuildException(ioe, getLocation());
+ }
+ }
+ /**
+ * find the absolute path
+ * @return absolute path
+ */
+ public String getAbsolutePath() {
+ return this.getCurpwd();
+ }
+ /**
+ * find out the relative path to root
+ * @return empty string
+ * @throws BuildException actually never
+ * @throws IOException actually never
+ */
+ public String getRelativePath() throws BuildException, IOException {
+ return "";
+ }
+ }
+ }
+ /**
+ * check FTPFiles to check whether they function as directories too
+ * the FTPFile API seem to make directory and symbolic links incompatible
+ * we want to find out if we can cd to a symbolic link
+ * @param dir the parent directory of the file to test
+ * @param file the file to test
+ * @return true if it is possible to cd to this directory
+ * @since ant 1.6
+ */
+ private boolean isFunctioningAsDirectory(FTPClient ftp, String dir, FTPFile file) {
+ boolean result = false;
+ String currentWorkingDir = null;
+ if (file.isDirectory()) {
+ return true;
+ } else if (file.isFile()) {
+ return false;
+ }
+ try {
+ currentWorkingDir = ftp.printWorkingDirectory();
+ } catch (IOException ioe) {
+ getProject().log("could not find current working directory " + dir
+ + " while checking a symlink",
+ Project.MSG_DEBUG);
+ }
+ if (currentWorkingDir != null) {
+ try {
+ result = ftp.changeWorkingDirectory(file.getLink());
+ } catch (IOException ioe) {
+ getProject().log("could not cd to " + file.getLink() + " while checking a symlink",
+ Project.MSG_DEBUG);
+ }
+ if (result) {
+ boolean comeback = false;
+ try {
+ comeback = ftp.changeWorkingDirectory(currentWorkingDir);
+ } catch (IOException ioe) {
+ getProject().log("could not cd back to " + dir + " while checking a symlink",
+ Project.MSG_ERR);
+ } finally {
+ if (!comeback) {
+ throw new BuildException("could not cd back to " + dir
+ + " while checking a symlink");
+ }
+ }
+ }
+ }
+ return result;
+ }
+ /**
+ * check FTPFiles to check whether they function as directories too
+ * the FTPFile API seem to make directory and symbolic links incompatible
+ * we want to find out if we can cd to a symbolic link
+ * @param dir the parent directory of the file to test
+ * @param file the file to test
+ * @return true if it is possible to cd to this directory
+ * @since ant 1.6
+ */
+ private boolean isFunctioningAsFile(FTPClient ftp, String dir, FTPFile file) {
+ if (file.isDirectory()) {
+ return false;
+ } else if (file.isFile()) {
+ return true;
+ }
+ return !isFunctioningAsDirectory(ftp, dir, file);
+ }
+ /**
+ * Sets the remote directory where files will be placed. This may be a
+ * relative or absolute path, and must be in the path syntax expected by
+ * the remote server. No correction of path syntax will be performed.
+ *
+ * @param dir the remote directory name.
+ */
+ public void setRemotedir(String dir) {
+ this.remotedir = dir;
+ }
+
+
+ /**
+ * Sets the FTP server to send files to.
+ *
+ * @param server the remote server name.
+ */
+ public void setServer(String server) {
+ this.server = server;
+ }
+
+
+ /**
+ * Sets the FTP port used by the remote server.
+ *
+ * @param port the port on which the remote server is listening.
+ */
+ public void setPort(int port) {
+ this.port = port;
+ }
+
+
+ /**
+ * Sets the login user id to use on the specified server.
+ *
+ * @param userid remote system userid.
+ */
+ public void setUserid(String userid) {
+ this.userid = userid;
+ }
+
+
+ /**
+ * Sets the login password for the given user id.
+ *
+ * @param password the password on the remote system.
+ */
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ /**
+ * Sets the login account to use on the specified server.
+ *
+ * @param pAccount the account name on remote system
+ * @since Ant 1.7
+ */
+ public void setAccount(String pAccount) {
+ this.account = pAccount;
+ }
+
+
+ /**
+ * If true, uses binary mode, otherwise text mode (default is binary).
+ *
+ * @param binary if true use binary mode in transfers.
+ */
+ public void setBinary(boolean binary) {
+ this.binary = binary;
+ }
+
+
+ /**
+ * Specifies whether to use passive mode. Set to true if you are behind a
+ * firewall and cannot connect without it. Passive mode is disabled by
+ * default.
+ *
+ * @param passive true is passive mode should be used.
+ */
+ public void setPassive(boolean passive) {
+ this.passive = passive;
+ }
+
+
+ /**
+ * Set to true to receive notification about each file as it is
+ * transferred.
+ *
+ * @param verbose true if verbose notifications are required.
+ */
+ public void setVerbose(boolean verbose) {
+ this.verbose = verbose;
+ }
+
+
+ /**
+ * A synonym for <tt>depends</tt>. Set to true to transmit only new
+ * or changed files.
+ *
+ * See the related attributes timediffmillis and timediffauto.
+ *
+ * @param newer if true only transfer newer files.
+ */
+ public void setNewer(boolean newer) {
+ this.newerOnly = newer;
+ }
+
+ /**
+ * number of milliseconds to add to the time on the remote machine
+ * to get the time on the local machine.
+ *
+ * use in conjunction with <code>newer</code>
+ *
+ * @param timeDiffMillis number of milliseconds
+ *
+ * @since ant 1.6
+ */
+ public void setTimeDiffMillis(long timeDiffMillis) {
+ this.timeDiffMillis = timeDiffMillis;
+ }
+
+ /**
+ * &quot;true&quot; to find out automatically the time difference
+ * between local and remote machine.
+ *
+ * This requires right to create
+ * and delete a temporary file in the remote directory.
+ *
+ * @param timeDiffAuto true = find automatically the time diff
+ *
+ * @since ant 1.6
+ */
+ public void setTimeDiffAuto(boolean timeDiffAuto) {
+ this.timeDiffAuto = timeDiffAuto;
+ }
+
+ /**
+ * Set to true to preserve modification times for "gotten" files.
+ *
+ * @param preserveLastModified if true preserver modification times.
+ */
+ public void setPreserveLastModified(boolean preserveLastModified) {
+ this.preserveLastModified = preserveLastModified;
+ }
+
+
+ /**
+ * Set to true to transmit only files that are new or changed from their
+ * remote counterparts. The default is to transmit all files.
+ *
+ * @param depends if true only transfer newer files.
+ */
+ public void setDepends(boolean depends) {
+ this.newerOnly = depends;
+ }
+
+
+ /**
+ * Sets the remote file separator character. This normally defaults to the
+ * Unix standard forward slash, but can be manually overridden using this
+ * call if the remote server requires some other separator. Only the first
+ * character of the string is used.
+ *
+ * @param separator the file separator on the remote system.
+ */
+ public void setSeparator(String separator) {
+ remoteFileSep = separator;
+ }
+
+
+ /**
+ * Sets the file permission mode (Unix only) for files sent to the
+ * server.
+ *
+ * @param theMode unix style file mode for the files sent to the remote
+ * system.
+ */
+ public void setChmod(String theMode) {
+ this.chmod = theMode;
+ }
+
+
+ /**
+ * Sets the default mask for file creation on a unix server.
+ *
+ * @param theUmask unix style umask for files created on the remote server.
+ */
+ public void setUmask(String theUmask) {
+ this.umask = theUmask;
+ }
+
+
+ /**
+ * A set of files to upload or download
+ *
+ * @param set the set of files to be added to the list of files to be
+ * transferred.
+ */
+ public void addFileset(FileSet set) {
+ filesets.addElement(set);
+ }
+
+
+ /**
+ * Sets the FTP action to be taken. Currently accepts "put", "get", "del",
+ * "mkdir", "chmod", "list", and "site".
+ *
+ * @deprecated since 1.5.x.
+ * setAction(String) is deprecated and is replaced with
+ * setAction(FTP.Action) to make Ant's Introspection mechanism do the
+ * work and also to encapsulate operations on the type in its own
+ * class.
+ * @ant.attribute ignore="true"
+ *
+ * @param action the FTP action to be performed.
+ *
+ * @throws BuildException if the action is not a valid action.
+ */
+ public void setAction(String action) throws BuildException {
+ log("DEPRECATED - The setAction(String) method has been deprecated."
+ + " Use setAction(FTP.Action) instead.");
+
+ Action a = new Action();
+
+ a.setValue(action);
+ this.action = a.getAction();
+ }
+
+
+ /**
+ * Sets the FTP action to be taken. Currently accepts "put", "get", "del",
+ * "mkdir", "chmod", "list", and "site".
+ *
+ * @param action the FTP action to be performed.
+ *
+ * @throws BuildException if the action is not a valid action.
+ */
+ public void setAction(Action action) throws BuildException {
+ this.action = action.getAction();
+ }
+
+
+ /**
+ * The output file for the "list" action. This attribute is ignored for
+ * any other actions.
+ *
+ * @param listing file in which to store the listing.
+ */
+ public void setListing(File listing) {
+ this.listing = listing;
+ }
+
+
+ /**
+ * If true, enables unsuccessful file put, delete and get
+ * operations to be skipped with a warning and the remainder
+ * of the files still transferred.
+ *
+ * @param skipFailedTransfers true if failures in transfers are ignored.
+ */
+ public void setSkipFailedTransfers(boolean skipFailedTransfers) {
+ this.skipFailedTransfers = skipFailedTransfers;
+ }
+
+
+ /**
+ * set the flag to skip errors on directory creation.
+ * (and maybe later other server specific errors)
+ *
+ * @param ignoreNoncriticalErrors true if non-critical errors should not
+ * cause a failure.
+ */
+ public void setIgnoreNoncriticalErrors(boolean ignoreNoncriticalErrors) {
+ this.ignoreNoncriticalErrors = ignoreNoncriticalErrors;
+ }
+
+ private void configurationHasBeenSet() {
+ this.isConfigurationSet = true;
+ }
+
+ /**
+ * Sets the systemTypeKey attribute.
+ * Method for setting <code>FTPClientConfig</code> remote system key.
+ *
+ * @param systemKey the key to be set - BUT if blank
+ * the default value of null (which signifies "autodetect") will be kept.
+ * @see org.apache.commons.net.ftp.FTPClientConfig
+ */
+ public void setSystemTypeKey(FTPSystemType systemKey) {
+ if (systemKey != null && !systemKey.getValue().equals("")) {
+ this.systemTypeKey = systemKey;
+ configurationHasBeenSet();
+ }
+ }
+
+ /**
+ * Sets the defaultDateFormatConfig attribute.
+ * @param defaultDateFormat configuration to be set, unless it is
+ * null or empty string, in which case ignored.
+ * @see org.apache.commons.net.ftp.FTPClientConfig
+ */
+ public void setDefaultDateFormatConfig(String defaultDateFormat) {
+ if (defaultDateFormat != null && !defaultDateFormat.equals("")) {
+ this.defaultDateFormatConfig = defaultDateFormat;
+ configurationHasBeenSet();
+ }
+ }
+
+ /**
+ * Sets the recentDateFormatConfig attribute.
+ * @param recentDateFormat configuration to be set, unless it is
+ * null or empty string, in which case ignored.
+ * @see org.apache.commons.net.ftp.FTPClientConfig
+ */
+ public void setRecentDateFormatConfig(String recentDateFormat) {
+ if (recentDateFormat != null && !recentDateFormat.equals("")) {
+ this.recentDateFormatConfig = recentDateFormat;
+ configurationHasBeenSet();
+ }
+ }
+
+ /**
+ * Sets the serverLanguageCode attribute.
+ * @param serverLanguageCode configuration to be set, unless it is
+ * null or empty string, in which case ignored.
+ * @see org.apache.commons.net.ftp.FTPClientConfig
+ */
+ public void setServerLanguageCodeConfig(LanguageCode serverLanguageCode) {
+ if (serverLanguageCode != null && !"".equals(serverLanguageCode.getValue())) {
+ this.serverLanguageCodeConfig = serverLanguageCode;
+ configurationHasBeenSet();
+ }
+ }
+
+ /**
+ * Sets the serverTimeZoneConfig attribute.
+ * @param serverTimeZoneId configuration to be set, unless it is
+ * null or empty string, in which case ignored.
+ * @see org.apache.commons.net.ftp.FTPClientConfig
+ */
+ public void setServerTimeZoneConfig(String serverTimeZoneId) {
+ if (serverTimeZoneId != null && !serverTimeZoneId.equals("")) {
+ this.serverTimeZoneConfig = serverTimeZoneId;
+ configurationHasBeenSet();
+ }
+ }
+
+ /**
+ * Sets the shortMonthNamesConfig attribute
+ *
+ * @param shortMonthNames configuration to be set, unless it is
+ * null or empty string, in which case ignored.
+ * @see org.apache.commons.net.ftp.FTPClientConfig
+ */
+ public void setShortMonthNamesConfig(String shortMonthNames) {
+ if (shortMonthNames != null && !shortMonthNames.equals("")) {
+ this.shortMonthNamesConfig = shortMonthNames;
+ configurationHasBeenSet();
+ }
+ }
+
+
+
+ /**
+ * Defines how many times to retry executing FTP command before giving up.
+ * Default is 0 - try once and if failure then give up.
+ *
+ * @param retriesAllowed number of retries to allow. -1 means
+ * keep trying forever. "forever" may also be specified as a
+ * synonym for -1.
+ */
+ public void setRetriesAllowed(String retriesAllowed) {
+ if ("FOREVER".equalsIgnoreCase(retriesAllowed)) {
+ this.retriesAllowed = Retryable.RETRY_FOREVER;
+ } else {
+ try {
+ int retries = Integer.parseInt(retriesAllowed);
+ if (retries < Retryable.RETRY_FOREVER) {
+ throw new BuildException(
+ "Invalid value for retriesAllowed attribute: "
+ + retriesAllowed);
+
+ }
+ this.retriesAllowed = retries;
+ } catch (NumberFormatException px) {
+ throw new BuildException(
+ "Invalid value for retriesAllowed attribute: "
+ + retriesAllowed);
+
+ }
+
+ }
+ }
+ /**
+ * @return Returns the systemTypeKey.
+ */
+ public String getSystemTypeKey() {
+ return systemTypeKey.getValue();
+ }
+ /**
+ * @return Returns the defaultDateFormatConfig.
+ */
+ public String getDefaultDateFormatConfig() {
+ return defaultDateFormatConfig;
+ }
+ /**
+ * @return Returns the recentDateFormatConfig.
+ */
+ public String getRecentDateFormatConfig() {
+ return recentDateFormatConfig;
+ }
+ /**
+ * @return Returns the serverLanguageCodeConfig.
+ */
+ public String getServerLanguageCodeConfig() {
+ return serverLanguageCodeConfig.getValue();
+ }
+ /**
+ * @return Returns the serverTimeZoneConfig.
+ */
+ public String getServerTimeZoneConfig() {
+ return serverTimeZoneConfig;
+ }
+ /**
+ * @return Returns the shortMonthNamesConfig.
+ */
+ public String getShortMonthNamesConfig() {
+ return shortMonthNamesConfig;
+ }
+ /**
+ * @return Returns the timestampGranularity.
+ */
+ Granularity getTimestampGranularity() {
+ return timestampGranularity;
+ }
+ /**
+ * Sets the timestampGranularity attribute
+ * @param timestampGranularity The timestampGranularity to set.
+ */
+ public void setTimestampGranularity(Granularity timestampGranularity) {
+ if (null == timestampGranularity || "".equals(timestampGranularity.getValue())) {
+ return;
+ }
+ this.timestampGranularity = timestampGranularity;
+ }
+ /**
+ * Sets the siteCommand attribute. This attribute
+ * names the command that will be executed if the action
+ * is "site".
+ * @param siteCommand The siteCommand to set.
+ */
+ public void setSiteCommand(String siteCommand) {
+ this.siteCommand = siteCommand;
+ }
+ /**
+ * Sets the initialSiteCommand attribute. This attribute
+ * names a site command that will be executed immediately
+ * after connection.
+ * @param initialCommand The initialSiteCommand to set.
+ */
+ public void setInitialSiteCommand(String initialCommand) {
+ this.initialSiteCommand = initialCommand;
+ }
+
+ /**
+ * Whether to verify that data and control connections are
+ * connected to the same remote host.
+ *
+ * @since Ant 1.8.0
+ */
+ public void setEnableRemoteVerification(boolean b) {
+ enableRemoteVerification = b;
+ }
+
+ /**
+ * Checks to see that all required parameters are set.
+ *
+ * @throws BuildException if the configuration is not valid.
+ */
+ protected void checkAttributes() throws BuildException {
+ if (server == null) {
+ throw new BuildException("server attribute must be set!");
+ }
+ if (userid == null) {
+ throw new BuildException("userid attribute must be set!");
+ }
+ if (password == null) {
+ throw new BuildException("password attribute must be set!");
+ }
+
+ if ((action == LIST_FILES) && (listing == null)) {
+ throw new BuildException("listing attribute must be set for list "
+ + "action!");
+ }
+
+ if (action == MK_DIR && remotedir == null) {
+ throw new BuildException("remotedir attribute must be set for "
+ + "mkdir action!");
+ }
+
+ if (action == CHMOD && chmod == null) {
+ throw new BuildException("chmod attribute must be set for chmod "
+ + "action!");
+ }
+ if (action == SITE_CMD && siteCommand == null) {
+ throw new BuildException("sitecommand attribute must be set for site "
+ + "action!");
+ }
+
+
+ if (this.isConfigurationSet) {
+ try {
+ Class.forName("org.apache.commons.net.ftp.FTPClientConfig");
+ } catch (ClassNotFoundException e) {
+ throw new BuildException(
+ "commons-net.jar >= 1.4.0 is required for at least one"
+ + " of the attributes specified.");
+ }
+ }
+ }
+
+ /**
+ * Executable a retryable object.
+ * @param h the retry handler.
+ * @param r the object that should be retried until it succeeds
+ * or the number of retrys is reached.
+ * @param descr a description of the command that is being run.
+ * @throws IOException if there is a problem.
+ */
+ protected void executeRetryable(RetryHandler h, Retryable r, String descr)
+ throws IOException {
+ h.execute(r, descr);
+ }
+
+
+ /**
+ * For each file in the fileset, do the appropriate action: send, get,
+ * delete, or list.
+ *
+ * @param ftp the FTPClient instance used to perform FTP actions
+ * @param fs the fileset on which the actions are performed.
+ *
+ * @return the number of files to be transferred.
+ *
+ * @throws IOException if there is a problem reading a file
+ * @throws BuildException if there is a problem in the configuration.
+ */
+ protected int transferFiles(final FTPClient ftp, FileSet fs)
+ throws IOException, BuildException {
+ DirectoryScanner ds;
+ if (action == SEND_FILES) {
+ ds = fs.getDirectoryScanner(getProject());
+ } else {
+ ds = new FTPDirectoryScanner(ftp);
+ fs.setupDirectoryScanner(ds, getProject());
+ ds.setFollowSymlinks(fs.isFollowSymlinks());
+ ds.scan();
+ }
+
+ String[] dsfiles = null;
+ if (action == RM_DIR) {
+ dsfiles = ds.getIncludedDirectories();
+ } else {
+ dsfiles = ds.getIncludedFiles();
+ }
+ String dir = null;
+
+ if ((ds.getBasedir() == null)
+ && ((action == SEND_FILES) || (action == GET_FILES))) {
+ throw new BuildException("the dir attribute must be set for send "
+ + "and get actions");
+ } else {
+ if ((action == SEND_FILES) || (action == GET_FILES)) {
+ dir = ds.getBasedir().getAbsolutePath();
+ }
+ }
+
+ // If we are doing a listing, we need the output stream created now.
+ BufferedWriter bw = null;
+
+ try {
+ if (action == LIST_FILES) {
+ File pd = listing.getParentFile();
+
+ if (!pd.exists()) {
+ pd.mkdirs();
+ }
+ bw = new BufferedWriter(new FileWriter(listing));
+ }
+ RetryHandler h = new RetryHandler(this.retriesAllowed, this);
+ if (action == RM_DIR) {
+ // to remove directories, start by the end of the list
+ // the trunk does not let itself be removed before the leaves
+ for (int i = dsfiles.length - 1; i >= 0; i--) {
+ final String dsfile = dsfiles[i];
+ executeRetryable(h, new Retryable() {
+ public void execute() throws IOException {
+ rmDir(ftp, dsfile);
+ }
+ }, dsfile);
+ }
+ } else {
+ final BufferedWriter fbw = bw;
+ final String fdir = dir;
+ if (this.newerOnly) {
+ this.granularityMillis =
+ this.timestampGranularity.getMilliseconds(action);
+ }
+ for (int i = 0; i < dsfiles.length; i++) {
+ final String dsfile = dsfiles[i];
+ executeRetryable(h, new Retryable() {
+ public void execute() throws IOException {
+ switch (action) {
+ case SEND_FILES:
+ sendFile(ftp, fdir, dsfile);
+ break;
+ case GET_FILES:
+ getFile(ftp, fdir, dsfile);
+ break;
+ case DEL_FILES:
+ delFile(ftp, dsfile);
+ break;
+ case LIST_FILES:
+ listFile(ftp, fbw, dsfile);
+ break;
+ case CHMOD:
+ doSiteCommand(ftp, "chmod " + chmod
+ + " " + resolveFile(dsfile));
+ transferred++;
+ break;
+ default:
+ throw new BuildException("unknown ftp action " + action);
+ }
+ }
+ }, dsfile);
+ }
+ }
+ } finally {
+ FileUtils.close(bw);
+ }
+
+ return dsfiles.length;
+ }
+
+
+ /**
+ * Sends all files specified by the configured filesets to the remote
+ * server.
+ *
+ * @param ftp the FTPClient instance used to perform FTP actions
+ *
+ * @throws IOException if there is a problem reading a file
+ * @throws BuildException if there is a problem in the configuration.
+ */
+ protected void transferFiles(FTPClient ftp)
+ throws IOException, BuildException {
+ transferred = 0;
+ skipped = 0;
+
+ if (filesets.size() == 0) {
+ throw new BuildException("at least one fileset must be specified.");
+ } else {
+ // get files from filesets
+ final int size = filesets.size();
+ for (int i = 0; i < size; i++) {
+ FileSet fs = (FileSet) filesets.elementAt(i);
+
+ if (fs != null) {
+ transferFiles(ftp, fs);
+ }
+ }
+ }
+
+ log(transferred + " " + ACTION_TARGET_STRS[action] + " "
+ + COMPLETED_ACTION_STRS[action]);
+ if (skipped != 0) {
+ log(skipped + " " + ACTION_TARGET_STRS[action]
+ + " were not successfully " + COMPLETED_ACTION_STRS[action]);
+ }
+ }
+
+
+ /**
+ * Correct a file path to correspond to the remote host requirements. This
+ * implementation currently assumes that the remote end can handle
+ * Unix-style paths with forward-slash separators. This can be overridden
+ * with the <code>separator</code> task parameter. No attempt is made to
+ * determine what syntax is appropriate for the remote host.
+ *
+ * @param file the remote file name to be resolved
+ *
+ * @return the filename as it will appear on the server.
+ */
+ protected String resolveFile(String file) {
+ return file.replace(System.getProperty("file.separator").charAt(0),
+ remoteFileSep.charAt(0));
+ }
+
+
+ /**
+ * Creates all parent directories specified in a complete relative
+ * pathname. Attempts to create existing directories will not cause
+ * errors.
+ *
+ * @param ftp the FTP client instance to use to execute FTP actions on
+ * the remote server.
+ * @param filename the name of the file whose parents should be created.
+ * @throws IOException under non documented circumstances
+ * @throws BuildException if it is impossible to cd to a remote directory
+ *
+ */
+ protected void createParents(FTPClient ftp, String filename)
+ throws IOException, BuildException {
+
+ File dir = new File(filename);
+ if (dirCache.contains(dir)) {
+ return;
+ }
+
+ Vector parents = new Vector();
+ String dirname;
+
+ while ((dirname = dir.getParent()) != null) {
+ File checkDir = new File(dirname);
+ if (dirCache.contains(checkDir)) {
+ break;
+ }
+ dir = checkDir;
+ parents.addElement(dir);
+ }
+
+ // find first non cached dir
+ int i = parents.size() - 1;
+
+ if (i >= 0) {
+ String cwd = ftp.printWorkingDirectory();
+ String parent = dir.getParent();
+ if (parent != null) {
+ if (!ftp.changeWorkingDirectory(resolveFile(parent))) {
+ throw new BuildException("could not change to "
+ + "directory: " + ftp.getReplyString());
+ }
+ }
+
+ while (i >= 0) {
+ dir = (File) parents.elementAt(i--);
+ // check if dir exists by trying to change into it.
+ if (!ftp.changeWorkingDirectory(dir.getName())) {
+ // could not change to it - try to create it
+ log("creating remote directory "
+ + resolveFile(dir.getPath()), Project.MSG_VERBOSE);
+ if (!ftp.makeDirectory(dir.getName())) {
+ handleMkDirFailure(ftp);
+ }
+ if (!ftp.changeWorkingDirectory(dir.getName())) {
+ throw new BuildException("could not change to "
+ + "directory: " + ftp.getReplyString());
+ }
+ }
+ dirCache.add(dir);
+ }
+ ftp.changeWorkingDirectory(cwd);
+ }
+ }
+ /**
+ * auto find the time difference between local and remote
+ * @param ftp handle to ftp client
+ * @return number of millis to add to remote time to make it comparable to local time
+ * @since ant 1.6
+ */
+ private long getTimeDiff(FTPClient ftp) {
+ long returnValue = 0;
+ File tempFile = findFileName(ftp);
+ try {
+ // create a local temporary file
+ FILE_UTILS.createNewFile(tempFile);
+ long localTimeStamp = tempFile.lastModified();
+ BufferedInputStream instream = new BufferedInputStream(new FileInputStream(tempFile));
+ ftp.storeFile(tempFile.getName(), instream);
+ instream.close();
+ boolean success = FTPReply.isPositiveCompletion(ftp.getReplyCode());
+ if (success) {
+ FTPFile [] ftpFiles = ftp.listFiles(tempFile.getName());
+ if (ftpFiles.length == 1) {
+ long remoteTimeStamp = ftpFiles[0].getTimestamp().getTime().getTime();
+ returnValue = localTimeStamp - remoteTimeStamp;
+ }
+ ftp.deleteFile(ftpFiles[0].getName());
+ }
+ // delegate the deletion of the local temp file to the delete task
+ // because of race conditions occurring on Windows
+ Delete mydelete = new Delete();
+ mydelete.bindToOwner(this);
+ mydelete.setFile(tempFile.getCanonicalFile());
+ mydelete.execute();
+ } catch (Exception e) {
+ throw new BuildException(e, getLocation());
+ }
+ return returnValue;
+ }
+ /**
+ * find a suitable name for local and remote temporary file
+ */
+ private File findFileName(FTPClient ftp) {
+ FTPFile [] theFiles = null;
+ final int maxIterations = 1000;
+ for (int counter = 1; counter < maxIterations; counter++) {
+ File localFile = FILE_UTILS.createTempFile(
+ "ant" + Integer.toString(counter), ".tmp",
+ null, false, false);
+ String fileName = localFile.getName();
+ boolean found = false;
+ try {
+ if (theFiles == null) {
+ theFiles = ftp.listFiles();
+ }
+ for (int counter2 = 0; counter2 < theFiles.length; counter2++) {
+ if (theFiles[counter2] != null
+ && theFiles[counter2].getName().equals(fileName)) {
+ found = true;
+ break;
+ }
+ }
+ } catch (IOException ioe) {
+ throw new BuildException(ioe, getLocation());
+ }
+ if (!found) {
+ localFile.deleteOnExit();
+ return localFile;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Checks to see if the remote file is current as compared with the local
+ * file. Returns true if the target file is up to date.
+ * @param ftp ftpclient
+ * @param localFile local file
+ * @param remoteFile remote file
+ * @return true if the target file is up to date
+ * @throws IOException in unknown circumstances
+ * @throws BuildException if the date of the remote files cannot be found and the action is
+ * GET_FILES
+ */
+ protected boolean isUpToDate(FTPClient ftp, File localFile,
+ String remoteFile)
+ throws IOException, BuildException {
+ log("checking date for " + remoteFile, Project.MSG_VERBOSE);
+
+ FTPFile[] files = ftp.listFiles(remoteFile);
+
+ // For Microsoft's Ftp-Service an Array with length 0 is
+ // returned if configured to return listings in "MS-DOS"-Format
+ if (files == null || files.length == 0) {
+ // If we are sending files, then assume out of date.
+ // If we are getting files, then throw an error
+
+ if (action == SEND_FILES) {
+ log("Could not date test remote file: " + remoteFile
+ + "assuming out of date.", Project.MSG_VERBOSE);
+ return false;
+ } else {
+ throw new BuildException("could not date test remote file: "
+ + ftp.getReplyString());
+ }
+ }
+
+ long remoteTimestamp = files[0].getTimestamp().getTime().getTime();
+ long localTimestamp = localFile.lastModified();
+ long adjustedRemoteTimestamp =
+ remoteTimestamp + this.timeDiffMillis + this.granularityMillis;
+
+ StringBuffer msg;
+ synchronized(TIMESTAMP_LOGGING_SDF) {
+ msg = new StringBuffer(" [")
+ .append(TIMESTAMP_LOGGING_SDF.format(new Date(localTimestamp)))
+ .append("] local");
+ }
+ log(msg.toString(), Project.MSG_VERBOSE);
+
+ synchronized(TIMESTAMP_LOGGING_SDF) {
+ msg = new StringBuffer(" [")
+ .append(TIMESTAMP_LOGGING_SDF.format(new Date(adjustedRemoteTimestamp)))
+ .append("] remote");
+ }
+ if (remoteTimestamp != adjustedRemoteTimestamp) {
+ synchronized(TIMESTAMP_LOGGING_SDF) {
+ msg.append(" - (raw: ")
+ .append(TIMESTAMP_LOGGING_SDF.format(new Date(remoteTimestamp)))
+ .append(")");
+ }
+ }
+ log(msg.toString(), Project.MSG_VERBOSE);
+
+
+
+ if (this.action == SEND_FILES) {
+ return adjustedRemoteTimestamp >= localTimestamp;
+ } else {
+ return localTimestamp >= adjustedRemoteTimestamp;
+ }
+ }
+
+
+ /**
+ * Sends a site command to the ftp server
+ * @param ftp ftp client
+ * @param theCMD command to execute
+ * @throws IOException in unknown circumstances
+ * @throws BuildException in unknown circumstances
+ */
+ protected void doSiteCommand(FTPClient ftp, String theCMD)
+ throws IOException, BuildException {
+ boolean rc;
+ String[] myReply = null;
+
+ log("Doing Site Command: " + theCMD, Project.MSG_VERBOSE);
+
+ rc = ftp.sendSiteCommand(theCMD);
+
+ if (!rc) {
+ log("Failed to issue Site Command: " + theCMD, Project.MSG_WARN);
+ } else {
+
+ myReply = ftp.getReplyStrings();
+
+ for (int x = 0; x < myReply.length; x++) {
+ if (myReply[x] != null && myReply[x].indexOf("200") == -1) {
+ log(myReply[x], Project.MSG_WARN);
+ }
+ }
+ }
+ }
+
+
+ /**
+ * Sends a single file to the remote host. <code>filename</code> may
+ * contain a relative path specification. When this is the case, <code>sendFile</code>
+ * will attempt to create any necessary parent directories before sending
+ * the file. The file will then be sent using the entire relative path
+ * spec - no attempt is made to change directories. It is anticipated that
+ * this may eventually cause problems with some FTP servers, but it
+ * simplifies the coding.
+ * @param ftp ftp client
+ * @param dir base directory of the file to be sent (local)
+ * @param filename relative path of the file to be send
+ * locally relative to dir
+ * remotely relative to the remotedir attribute
+ * @throws IOException in unknown circumstances
+ * @throws BuildException in unknown circumstances
+ */
+ protected void sendFile(FTPClient ftp, String dir, String filename)
+ throws IOException, BuildException {
+ InputStream instream = null;
+
+ try {
+ // TODO - why not simply new File(dir, filename)?
+ File file = getProject().resolveFile(new File(dir, filename).getPath());
+
+ if (newerOnly && isUpToDate(ftp, file, resolveFile(filename))) {
+ return;
+ }
+
+ if (verbose) {
+ log("transferring " + file.getAbsolutePath());
+ }
+
+ instream = new BufferedInputStream(new FileInputStream(file));
+
+ createParents(ftp, filename);
+
+ ftp.storeFile(resolveFile(filename), instream);
+
+ boolean success = FTPReply.isPositiveCompletion(ftp.getReplyCode());
+
+ if (!success) {
+ String s = "could not put file: " + ftp.getReplyString();
+
+ if (skipFailedTransfers) {
+ log(s, Project.MSG_WARN);
+ skipped++;
+ } else {
+ throw new BuildException(s);
+ }
+
+ } else {
+ // see if we should issue a chmod command
+ if (chmod != null) {
+ doSiteCommand(ftp, "chmod " + chmod + " " + resolveFile(filename));
+ }
+ log("File " + file.getAbsolutePath() + " copied to " + server,
+ Project.MSG_VERBOSE);
+ transferred++;
+ }
+ } finally {
+ FileUtils.close(instream);
+ }
+ }
+
+
+ /**
+ * Delete a file from the remote host.
+ * @param ftp ftp client
+ * @param filename file to delete
+ * @throws IOException in unknown circumstances
+ * @throws BuildException if skipFailedTransfers is set to false
+ * and the deletion could not be done
+ */
+ protected void delFile(FTPClient ftp, String filename)
+ throws IOException, BuildException {
+ if (verbose) {
+ log("deleting " + filename);
+ }
+
+ if (!ftp.deleteFile(resolveFile(filename))) {
+ String s = "could not delete file: " + ftp.getReplyString();
+
+ if (skipFailedTransfers) {
+ log(s, Project.MSG_WARN);
+ skipped++;
+ } else {
+ throw new BuildException(s);
+ }
+ } else {
+ log("File " + filename + " deleted from " + server,
+ Project.MSG_VERBOSE);
+ transferred++;
+ }
+ }
+
+ /**
+ * Delete a directory, if empty, from the remote host.
+ * @param ftp ftp client
+ * @param dirname directory to delete
+ * @throws IOException in unknown circumstances
+ * @throws BuildException if skipFailedTransfers is set to false
+ * and the deletion could not be done
+ */
+ protected void rmDir(FTPClient ftp, String dirname)
+ throws IOException, BuildException {
+ if (verbose) {
+ log("removing " + dirname);
+ }
+
+ if (!ftp.removeDirectory(resolveFile(dirname))) {
+ String s = "could not remove directory: " + ftp.getReplyString();
+
+ if (skipFailedTransfers) {
+ log(s, Project.MSG_WARN);
+ skipped++;
+ } else {
+ throw new BuildException(s);
+ }
+ } else {
+ log("Directory " + dirname + " removed from " + server,
+ Project.MSG_VERBOSE);
+ transferred++;
+ }
+ }
+
+
+ /**
+ * Retrieve a single file from the remote host. <code>filename</code> may
+ * contain a relative path specification. <p>
+ *
+ * The file will then be retrieved using the entire relative path spec -
+ * no attempt is made to change directories. It is anticipated that this
+ * may eventually cause problems with some FTP servers, but it simplifies
+ * the coding.</p>
+ * @param ftp the ftp client
+ * @param dir local base directory to which the file should go back
+ * @param filename relative path of the file based upon the ftp remote directory
+ * and/or the local base directory (dir)
+ * @throws IOException in unknown circumstances
+ * @throws BuildException if skipFailedTransfers is false
+ * and the file cannot be retrieved.
+ */
+ protected void getFile(FTPClient ftp, String dir, String filename)
+ throws IOException, BuildException {
+ OutputStream outstream = null;
+ try {
+ File file = getProject().resolveFile(new File(dir, filename).getPath());
+
+ if (newerOnly && isUpToDate(ftp, file, resolveFile(filename))) {
+ return;
+ }
+
+ if (verbose) {
+ log("transferring " + filename + " to "
+ + file.getAbsolutePath());
+ }
+
+ File pdir = file.getParentFile();
+
+ if (!pdir.exists()) {
+ pdir.mkdirs();
+ }
+ outstream = new BufferedOutputStream(new FileOutputStream(file));
+ ftp.retrieveFile(resolveFile(filename), outstream);
+
+ if (!FTPReply.isPositiveCompletion(ftp.getReplyCode())) {
+ String s = "could not get file: " + ftp.getReplyString();
+
+ if (skipFailedTransfers) {
+ log(s, Project.MSG_WARN);
+ skipped++;
+ } else {
+ throw new BuildException(s);
+ }
+
+ } else {
+ log("File " + file.getAbsolutePath() + " copied from "
+ + server, Project.MSG_VERBOSE);
+ transferred++;
+ if (preserveLastModified) {
+ outstream.close();
+ outstream = null;
+ FTPFile[] remote = ftp.listFiles(resolveFile(filename));
+ if (remote.length > 0) {
+ FILE_UTILS.setFileLastModified(file,
+ remote[0].getTimestamp()
+ .getTime().getTime());
+ }
+ }
+ }
+ } finally {
+ FileUtils.close(outstream);
+ }
+ }
+
+
+ /**
+ * List information about a single file from the remote host. <code>filename</code>
+ * may contain a relative path specification. <p>
+ *
+ * The file listing will then be retrieved using the entire relative path
+ * spec - no attempt is made to change directories. It is anticipated that
+ * this may eventually cause problems with some FTP servers, but it
+ * simplifies the coding.</p>
+ * @param ftp ftp client
+ * @param bw buffered writer
+ * @param filename the directory one wants to list
+ * @throws IOException in unknown circumstances
+ * @throws BuildException in unknown circumstances
+ */
+ protected void listFile(FTPClient ftp, BufferedWriter bw, String filename)
+ throws IOException, BuildException {
+ if (verbose) {
+ log("listing " + filename);
+ }
+ FTPFile[] ftpfiles = ftp.listFiles(resolveFile(filename));
+
+ if (ftpfiles != null && ftpfiles.length > 0) {
+ bw.write(ftpfiles[0].toString());
+ bw.newLine();
+ transferred++;
+ }
+ }
+
+
+ /**
+ * Create the specified directory on the remote host.
+ *
+ * @param ftp The FTP client connection
+ * @param dir The directory to create (format must be correct for host
+ * type)
+ * @throws IOException in unknown circumstances
+ * @throws BuildException if ignoreNoncriticalErrors has not been set to true
+ * and a directory could not be created, for instance because it was
+ * already existing. Precisely, the codes 521, 550 and 553 will trigger
+ * a BuildException
+ */
+ protected void makeRemoteDir(FTPClient ftp, String dir)
+ throws IOException, BuildException {
+ String workingDirectory = ftp.printWorkingDirectory();
+ if (verbose) {
+ if (dir.startsWith("/") || workingDirectory == null) {
+ log("Creating directory: " + dir + " in /");
+ } else {
+ log("Creating directory: " + dir + " in " + workingDirectory);
+ }
+ }
+ if (dir.startsWith("/")) {
+ ftp.changeWorkingDirectory("/");
+ }
+ String subdir = "";
+ StringTokenizer st = new StringTokenizer(dir, "/");
+ while (st.hasMoreTokens()) {
+ subdir = st.nextToken();
+ log("Checking " + subdir, Project.MSG_DEBUG);
+ if (!ftp.changeWorkingDirectory(subdir)) {
+ if (!ftp.makeDirectory(subdir)) {
+ // codes 521, 550 and 553 can be produced by FTP Servers
+ // to indicate that an attempt to create a directory has
+ // failed because the directory already exists.
+ int rc = ftp.getReplyCode();
+ if (!(ignoreNoncriticalErrors
+ && (rc == CODE_550 || rc == CODE_553
+ || rc == CODE_521))) {
+ throw new BuildException("could not create directory: "
+ + ftp.getReplyString());
+ }
+ if (verbose) {
+ log("Directory already exists");
+ }
+ } else {
+ if (verbose) {
+ log("Directory created OK");
+ }
+ ftp.changeWorkingDirectory(subdir);
+ }
+ }
+ }
+ if (workingDirectory != null) {
+ ftp.changeWorkingDirectory(workingDirectory);
+ }
+ }
+
+ /**
+ * look at the response for a failed mkdir action, decide whether
+ * it matters or not. If it does, we throw an exception
+ * @param ftp current ftp connection
+ * @throws BuildException if this is an error to signal
+ */
+ private void handleMkDirFailure(FTPClient ftp)
+ throws BuildException {
+ int rc = ftp.getReplyCode();
+ if (!(ignoreNoncriticalErrors
+ && (rc == CODE_550 || rc == CODE_553 || rc == CODE_521))) {
+ throw new BuildException("could not create directory: "
+ + ftp.getReplyString());
+ }
+ }
+
+ /**
+ * Runs the task.
+ *
+ * @throws BuildException if the task fails or is not configured
+ * correctly.
+ */
+ public void execute() throws BuildException {
+ checkAttributes();
+
+ FTPClient ftp = null;
+
+ try {
+ log("Opening FTP connection to " + server, Project.MSG_VERBOSE);
+
+ ftp = new FTPClient();
+ if (this.isConfigurationSet) {
+ ftp = FTPConfigurator.configure(ftp, this);
+ }
+
+ ftp.setRemoteVerificationEnabled(enableRemoteVerification);
+ ftp.connect(server, port);
+ if (!FTPReply.isPositiveCompletion(ftp.getReplyCode())) {
+ throw new BuildException("FTP connection failed: "
+ + ftp.getReplyString());
+ }
+
+ log("connected", Project.MSG_VERBOSE);
+ log("logging in to FTP server", Project.MSG_VERBOSE);
+
+ if ((this.account != null && !ftp.login(userid, password, account))
+ || (this.account == null && !ftp.login(userid, password))) {
+ throw new BuildException("Could not login to FTP server");
+ }
+
+ log("login succeeded", Project.MSG_VERBOSE);
+
+ if (binary) {
+ ftp.setFileType(org.apache.commons.net.ftp.FTP.BINARY_FILE_TYPE);
+ if (!FTPReply.isPositiveCompletion(ftp.getReplyCode())) {
+ throw new BuildException("could not set transfer type: "
+ + ftp.getReplyString());
+ }
+ } else {
+ ftp.setFileType(org.apache.commons.net.ftp.FTP.ASCII_FILE_TYPE);
+ if (!FTPReply.isPositiveCompletion(ftp.getReplyCode())) {
+ throw new BuildException("could not set transfer type: "
+ + ftp.getReplyString());
+ }
+ }
+
+ if (passive) {
+ log("entering passive mode", Project.MSG_VERBOSE);
+ ftp.enterLocalPassiveMode();
+ if (!FTPReply.isPositiveCompletion(ftp.getReplyCode())) {
+ throw new BuildException("could not enter into passive "
+ + "mode: " + ftp.getReplyString());
+ }
+ }
+
+ // If an initial command was configured then send it.
+ // Some FTP servers offer different modes of operation,
+ // E.G. switching between a UNIX file system mode and
+ // a legacy file system.
+ if (this.initialSiteCommand != null) {
+ RetryHandler h = new RetryHandler(this.retriesAllowed, this);
+ final FTPClient lftp = ftp;
+ executeRetryable(h, new Retryable() {
+ public void execute() throws IOException {
+ doSiteCommand(lftp, FTP.this.initialSiteCommand);
+ }
+ }, "initial site command: " + this.initialSiteCommand);
+ }
+
+
+ // For a unix ftp server you can set the default mask for all files
+ // created.
+
+ if (umask != null) {
+ RetryHandler h = new RetryHandler(this.retriesAllowed, this);
+ final FTPClient lftp = ftp;
+ executeRetryable(h, new Retryable() {
+ public void execute() throws IOException {
+ doSiteCommand(lftp, "umask " + umask);
+ }
+ }, "umask " + umask);
+ }
+
+ // If the action is MK_DIR, then the specified remote
+ // directory is the directory to create.
+
+ if (action == MK_DIR) {
+ RetryHandler h = new RetryHandler(this.retriesAllowed, this);
+ final FTPClient lftp = ftp;
+ executeRetryable(h, new Retryable() {
+ public void execute() throws IOException {
+ makeRemoteDir(lftp, remotedir);
+ }
+ }, remotedir);
+ } else if (action == SITE_CMD) {
+ RetryHandler h = new RetryHandler(this.retriesAllowed, this);
+ final FTPClient lftp = ftp;
+ executeRetryable(h, new Retryable() {
+ public void execute() throws IOException {
+ doSiteCommand(lftp, FTP.this.siteCommand);
+ }
+ }, "Site Command: " + this.siteCommand);
+ } else {
+ if (remotedir != null) {
+ log("changing the remote directory to " + remotedir,
+ Project.MSG_VERBOSE);
+ ftp.changeWorkingDirectory(remotedir);
+ if (!FTPReply.isPositiveCompletion(ftp.getReplyCode())) {
+ throw new BuildException("could not change remote "
+ + "directory: " + ftp.getReplyString());
+ }
+ }
+ if (newerOnly && timeDiffAuto) {
+ // in this case we want to find how much time span there is between local
+ // and remote
+ timeDiffMillis = getTimeDiff(ftp);
+ }
+ log(ACTION_STRS[action] + " " + ACTION_TARGET_STRS[action]);
+ transferFiles(ftp);
+ }
+
+ } catch (IOException ex) {
+ throw new BuildException("error during FTP transfer: " + ex, ex);
+ } finally {
+ if (ftp != null && ftp.isConnected()) {
+ try {
+ log("disconnecting", Project.MSG_VERBOSE);
+ ftp.logout();
+ ftp.disconnect();
+ } catch (IOException ex) {
+ // ignore it
+ }
+ }
+ }
+ }
+
+
+ /**
+ * an action to perform, one of
+ * "send", "put", "recv", "get", "del", "delete", "list", "mkdir", "chmod",
+ * "rmdir"
+ */
+ public static class Action extends EnumeratedAttribute {
+
+ private static final String[] VALID_ACTIONS = {
+ "send", "put", "recv", "get", "del", "delete", "list", "mkdir",
+ "chmod", "rmdir", "site"
+ };
+
+
+ /**
+ * Get the valid values
+ *
+ * @return an array of the valid FTP actions.
+ */
+ public String[] getValues() {
+ return VALID_ACTIONS;
+ }
+
+
+ /**
+ * Get the symbolic equivalent of the action value.
+ *
+ * @return the SYMBOL representing the given action.
+ */
+ public int getAction() {
+ String actionL = getValue().toLowerCase(Locale.ENGLISH);
+ if (actionL.equals("send") || actionL.equals("put")) {
+ return SEND_FILES;
+ } else if (actionL.equals("recv") || actionL.equals("get")) {
+ return GET_FILES;
+ } else if (actionL.equals("del") || actionL.equals("delete")) {
+ return DEL_FILES;
+ } else if (actionL.equals("list")) {
+ return LIST_FILES;
+ } else if (actionL.equals("chmod")) {
+ return CHMOD;
+ } else if (actionL.equals("mkdir")) {
+ return MK_DIR;
+ } else if (actionL.equals("rmdir")) {
+ return RM_DIR;
+ } else if (actionL.equals("site")) {
+ return SITE_CMD;
+ }
+ return SEND_FILES;
+ }
+ }
+ /**
+ * represents one of the valid timestamp adjustment values
+ * recognized by the <code>timestampGranularity</code> attribute.<p>
+
+ * A timestamp adjustment may be used in file transfers for checking
+ * uptodateness. MINUTE means to add one minute to the server
+ * timestamp. This is done because FTP servers typically list
+ * timestamps HH:mm and client FileSystems typically use HH:mm:ss.
+ *
+ * The default is to use MINUTE for PUT actions and NONE for GET
+ * actions, since GETs have the <code>preserveLastModified</code>
+ * option, which takes care of the problem in most use cases where
+ * this level of granularity is an issue.
+ *
+ */
+ public static class Granularity extends EnumeratedAttribute {
+
+ private static final String[] VALID_GRANULARITIES = {
+ "", "MINUTE", "NONE"
+ };
+
+ /**
+ * Get the valid values.
+ * @return the list of valid Granularity values
+ */
+ public String[] getValues() {
+ return VALID_GRANULARITIES;
+ }
+ /**
+ * returns the number of milliseconds associated with
+ * the attribute, which can vary in some cases depending
+ * on the value of the action parameter.
+ * @param action SEND_FILES or GET_FILES
+ * @return the number of milliseconds associated with
+ * the attribute, in the context of the supplied action
+ */
+ public long getMilliseconds(int action) {
+ String granularityU = getValue().toUpperCase(Locale.ENGLISH);
+ if ("".equals(granularityU)) {
+ if (action == SEND_FILES) {
+ return GRANULARITY_MINUTE;
+ }
+ } else if ("MINUTE".equals(granularityU)) {
+ return GRANULARITY_MINUTE;
+ }
+ return 0L;
+ }
+ static final Granularity getDefault() {
+ Granularity g = new Granularity();
+ g.setValue("");
+ return g;
+ }
+
+ }
+ /**
+ * one of the valid system type keys recognized by the systemTypeKey
+ * attribute.
+ */
+ public static class FTPSystemType extends EnumeratedAttribute {
+
+ private static final String[] VALID_SYSTEM_TYPES = {
+ "", "UNIX", "VMS", "WINDOWS", "OS/2", "OS/400",
+ "MVS"
+ };
+
+
+ /**
+ * Get the valid values.
+ * @return the list of valid system types.
+ */
+ public String[] getValues() {
+ return VALID_SYSTEM_TYPES;
+ }
+
+ static final FTPSystemType getDefault() {
+ FTPSystemType ftpst = new FTPSystemType();
+ ftpst.setValue("");
+ return ftpst;
+ }
+ }
+ /**
+ * Enumerated class for languages.
+ */
+ public static class LanguageCode extends EnumeratedAttribute {
+
+
+ private static final String[] VALID_LANGUAGE_CODES =
+ getValidLanguageCodes();
+
+ private static String[] getValidLanguageCodes() {
+ Collection c = FTPClientConfig.getSupportedLanguageCodes();
+ String[] ret = new String[c.size() + 1];
+ int i = 0;
+ ret[i++] = "";
+ for (Iterator it = c.iterator(); it.hasNext(); i++) {
+ ret[i] = (String) it.next();
+ }
+ return ret;
+ }
+
+
+ /**
+ * Return the value values.
+ * @return the list of valid language types.
+ */
+ public String[] getValues() {
+ return VALID_LANGUAGE_CODES;
+ }
+
+ static final LanguageCode getDefault() {
+ LanguageCode lc = new LanguageCode();
+ lc.setValue("");
+ return lc;
+ }
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/net/FTPConfigurator.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/net/FTPConfigurator.java
new file mode 100644
index 00000000..0604dac9
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/net/FTPConfigurator.java
@@ -0,0 +1,99 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.net;
+import org.apache.commons.net.ftp.FTPClient;
+import org.apache.commons.net.ftp.FTPClientConfig;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+
+/**
+ * The sole purpose of this class is (note that it is package-private
+ * is to serve as a separate, static compilation unit for importing
+ * FTPClientConfig, to enable users who wish to use the FTP task
+ * without using its new features to avoid the need to
+ * upgrade to jakarta-commons-net 1.4.0, where FTPClientConfig was
+ * introduced.
+ */
+// CheckStyle:HideUtilityClassConstructorCheck OFF (bc)
+class FTPConfigurator {
+ /**
+ * configures the supplied FTPClient with the various
+ * attributes set in the supplied FTP task.
+ * @param client the FTPClient to be configured
+ * @param task the FTP task whose attributes are used to
+ * configure the client
+ * @return the client as configured.
+ */
+ static FTPClient configure(FTPClient client, FTPTaskConfig task) {
+ task.log("custom configuration", Project.MSG_VERBOSE);
+ FTPClientConfig config;
+ String systemTypeKey = task.getSystemTypeKey();
+ if (systemTypeKey != null && !"".equals(systemTypeKey)) {
+ config = new FTPClientConfig(systemTypeKey);
+ task.log("custom config: system key = "
+ + systemTypeKey, Project.MSG_VERBOSE);
+ } else {
+ config = new FTPClientConfig();
+ task.log("custom config: system key = default (UNIX)",
+ Project.MSG_VERBOSE);
+ }
+
+ String defaultDateFormatConfig = task.getDefaultDateFormatConfig();
+ if (defaultDateFormatConfig != null) {
+ config.setDefaultDateFormatStr(defaultDateFormatConfig);
+ task.log("custom config: default date format = "
+ + defaultDateFormatConfig, Project.MSG_VERBOSE);
+ }
+
+ String recentDateFormatConfig = task.getRecentDateFormatConfig();
+ if (recentDateFormatConfig != null) {
+ config.setRecentDateFormatStr(recentDateFormatConfig);
+ task.log("custom config: recent date format = "
+ + recentDateFormatConfig, Project.MSG_VERBOSE);
+ }
+
+ String serverLanguageCodeConfig = task.getServerLanguageCodeConfig();
+ if (serverLanguageCodeConfig != null) {
+ if (!"".equals(serverLanguageCodeConfig)
+ && !FTPClientConfig.getSupportedLanguageCodes()
+ .contains(serverLanguageCodeConfig)) {
+ throw new BuildException("unsupported language code" +
+ serverLanguageCodeConfig);
+ }
+ config.setServerLanguageCode(serverLanguageCodeConfig);
+ task.log("custom config: server language code = "
+ + serverLanguageCodeConfig, Project.MSG_VERBOSE);
+ }
+
+ String serverTimeZoneConfig = task.getServerTimeZoneConfig();
+ if (serverTimeZoneConfig != null) {
+ config.setServerTimeZoneId(serverTimeZoneConfig);
+ task.log("custom config: server time zone ID = "
+ + serverTimeZoneConfig, Project.MSG_VERBOSE);
+ }
+
+ String shortMonthNamesConfig = task.getShortMonthNamesConfig();
+ if (shortMonthNamesConfig != null) {
+ config.setShortMonthNames(shortMonthNamesConfig);
+ task.log("custom config: short month names = "
+ + shortMonthNamesConfig, Project.MSG_VERBOSE);
+ }
+ client.configure(config);
+ return client;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/net/FTPTask.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/net/FTPTask.java
new file mode 100644
index 00000000..79780c78
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/net/FTPTask.java
@@ -0,0 +1,965 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.net;
+
+import java.io.File;
+import java.lang.reflect.Constructor;
+import java.util.Locale;
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.types.EnumeratedAttribute;
+import org.apache.tools.ant.types.FileSet;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.util.LoaderUtils;
+import org.apache.tools.ant.util.Retryable;
+import org.apache.tools.ant.util.SplitClassLoader;
+
+/**
+ * Basic FTP client. Performs the following actions:
+ * <ul>
+ * <li> <strong>send</strong> - send files to a remote server. This is the
+ * default action.</li>
+ * <li> <strong>get</strong> - retrieve files from a remote server.</li>
+ * <li> <strong>del</strong> - delete files from a remote server.</li>
+ * <li> <strong>list</strong> - create a file listing.</li>
+ * <li> <strong>chmod</strong> - change unix file permissions.</li>
+ * <li> <strong>rmdir</strong> - remove directories, if empty, from a
+ * remote server.</li>
+ * </ul>
+ * <strong>Note:</strong> Some FTP servers - notably the Solaris server - seem
+ * to hold data ports open after a "retr" operation, allowing them to timeout
+ * instead of shutting them down cleanly. This happens in active or passive
+ * mode, and the ports will remain open even after ending the FTP session. FTP
+ * "send" operations seem to close ports immediately. This behavior may cause
+ * problems on some systems when downloading large sets of files.
+ *
+ * @since Ant 1.3
+ */
+public class FTPTask extends Task implements FTPTaskConfig {
+ public static final int SEND_FILES = 0;
+ public static final int GET_FILES = 1;
+ public static final int DEL_FILES = 2;
+ public static final int LIST_FILES = 3;
+ public static final int MK_DIR = 4;
+ public static final int CHMOD = 5;
+ public static final int RM_DIR = 6;
+ public static final int SITE_CMD = 7;
+
+ /** adjust uptodate calculations where server timestamps are HH:mm and client's
+ * are HH:mm:ss */
+ private static final long GRANULARITY_MINUTE = 60000L;
+
+ /** Default port for FTP */
+ public static final int DEFAULT_FTP_PORT = 21;
+
+ private String remotedir;
+ private String server;
+ private String userid;
+ private String password;
+ private String account;
+ private File listing;
+ private boolean binary = true;
+ private boolean passive = false;
+ private boolean verbose = false;
+ private boolean newerOnly = false;
+ private long timeDiffMillis = 0;
+ private long granularityMillis = 0L;
+ private boolean timeDiffAuto = false;
+ private int action = SEND_FILES;
+ private Vector filesets = new Vector();
+ private String remoteFileSep = "/";
+ private int port = DEFAULT_FTP_PORT;
+ private boolean skipFailedTransfers = false;
+ private boolean ignoreNoncriticalErrors = false;
+ private boolean preserveLastModified = false;
+ private String chmod = null;
+ private String umask = null;
+ private FTPSystemType systemTypeKey = FTPSystemType.getDefault();
+ private String defaultDateFormatConfig = null;
+ private String recentDateFormatConfig = null;
+ private String serverLanguageCodeConfig = null;
+ private String serverTimeZoneConfig = null;
+ private String shortMonthNamesConfig = null;
+ private Granularity timestampGranularity = Granularity.getDefault();
+ private boolean isConfigurationSet = false;
+ private int retriesAllowed = 0;
+ private String siteCommand = null;
+ private String initialSiteCommand = null;
+ private boolean enableRemoteVerification = true;
+
+ private Path classpath;
+ private ClassLoader mirrorLoader;
+ private FTPTaskMirror delegate = null;
+
+ public static final String[] ACTION_STRS = {
+ "sending",
+ "getting",
+ "deleting",
+ "listing",
+ "making directory",
+ "chmod",
+ "removing",
+ "site"
+ };
+
+ public static final String[] COMPLETED_ACTION_STRS = {
+ "sent",
+ "retrieved",
+ "deleted",
+ "listed",
+ "created directory",
+ "mode changed",
+ "removed",
+ "site command executed"
+ };
+
+ public static final String[] ACTION_TARGET_STRS = {
+ "files",
+ "files",
+ "files",
+ "files",
+ "directory",
+ "files",
+ "directories",
+ "site command"
+ };
+
+ /**
+ * Sets the remote directory where files will be placed. This may be a
+ * relative or absolute path, and must be in the path syntax expected by
+ * the remote server. No correction of path syntax will be performed.
+ *
+ * @param dir the remote directory name.
+ */
+ public void setRemotedir(String dir) {
+ this.remotedir = dir;
+ }
+
+ public String getRemotedir() {
+ return remotedir;
+ }
+
+ /**
+ * Sets the FTP server to send files to.
+ *
+ * @param server the remote server name.
+ */
+ public void setServer(String server) {
+ this.server = server;
+ }
+
+ public String getServer() {
+ return server;
+ }
+
+ /**
+ * Sets the FTP port used by the remote server.
+ *
+ * @param port the port on which the remote server is listening.
+ */
+ public void setPort(int port) {
+ this.port = port;
+ }
+
+ public int getPort() {
+ return port;
+ }
+
+ /**
+ * Sets the login user id to use on the specified server.
+ *
+ * @param userid remote system userid.
+ */
+ public void setUserid(String userid) {
+ this.userid = userid;
+ }
+
+ public String getUserid() {
+ return userid;
+ }
+
+ /**
+ * Sets the login password for the given user id.
+ *
+ * @param password the password on the remote system.
+ */
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ /**
+ * Sets the login account to use on the specified server.
+ *
+ * @param pAccount the account name on remote system
+ * @since Ant 1.7
+ */
+ public void setAccount(String pAccount) {
+ this.account = pAccount;
+ }
+
+ public String getAccount() {
+ return account;
+ }
+
+ /**
+ * If true, uses binary mode, otherwise text mode (default is binary).
+ *
+ * @param binary if true use binary mode in transfers.
+ */
+ public void setBinary(boolean binary) {
+ this.binary = binary;
+ }
+
+ public boolean isBinary() {
+ return binary;
+ }
+
+ /**
+ * Specifies whether to use passive mode. Set to true if you are behind a
+ * firewall and cannot connect without it. Passive mode is disabled by
+ * default.
+ *
+ * @param passive true is passive mode should be used.
+ */
+ public void setPassive(boolean passive) {
+ this.passive = passive;
+ }
+
+ public boolean isPassive() {
+ return passive;
+ }
+
+ /**
+ * Set to true to receive notification about each file as it is
+ * transferred.
+ *
+ * @param verbose true if verbose notifications are required.
+ */
+ public void setVerbose(boolean verbose) {
+ this.verbose = verbose;
+ }
+
+ public boolean isVerbose() {
+ return verbose;
+ }
+
+ /**
+ * A synonym for <tt>depends</tt>. Set to true to transmit only new
+ * or changed files.
+ *
+ * See the related attributes timediffmillis and timediffauto.
+ *
+ * @param newer if true only transfer newer files.
+ */
+ public void setNewer(boolean newer) {
+ this.newerOnly = newer;
+ }
+
+ public boolean isNewer() {
+ return newerOnly;
+ }
+
+ /**
+ * number of milliseconds to add to the time on the remote machine
+ * to get the time on the local machine.
+ *
+ * use in conjunction with <code>newer</code>
+ *
+ * @param timeDiffMillis number of milliseconds
+ *
+ * @since ant 1.6
+ */
+ public void setTimeDiffMillis(long timeDiffMillis) {
+ this.timeDiffMillis = timeDiffMillis;
+ }
+
+ public long getTimeDiffMillis() {
+ return timeDiffMillis;
+ }
+
+ /**
+ * &quot;true&quot; to find out automatically the time difference
+ * between local and remote machine.
+ *
+ * This requires right to create
+ * and delete a temporary file in the remote directory.
+ *
+ * @param timeDiffAuto true = find automatically the time diff
+ *
+ * @since ant 1.6
+ */
+ public void setTimeDiffAuto(boolean timeDiffAuto) {
+ this.timeDiffAuto = timeDiffAuto;
+ }
+
+ public boolean isTimeDiffAuto() {
+ return timeDiffAuto;
+ }
+
+ /**
+ * Set to true to preserve modification times for "gotten" files.
+ *
+ * @param preserveLastModified if true preserver modification times.
+ */
+ public void setPreserveLastModified(boolean preserveLastModified) {
+ this.preserveLastModified = preserveLastModified;
+ }
+
+ public boolean isPreserveLastModified() {
+ return preserveLastModified;
+ }
+
+ /**
+ * Set to true to transmit only files that are new or changed from their
+ * remote counterparts. The default is to transmit all files.
+ *
+ * @param depends if true only transfer newer files.
+ */
+ public void setDepends(boolean depends) {
+ this.newerOnly = depends;
+ }
+
+
+ /**
+ * Sets the remote file separator character. This normally defaults to the
+ * Unix standard forward slash, but can be manually overridden using this
+ * call if the remote server requires some other separator. Only the first
+ * character of the string is used.
+ *
+ * @param separator the file separator on the remote system.
+ */
+ public void setSeparator(String separator) {
+ remoteFileSep = separator;
+ }
+
+
+ public String getSeparator() {
+ return remoteFileSep;
+ }
+
+ /**
+ * Sets the file permission mode (Unix only) for files sent to the
+ * server.
+ *
+ * @param theMode unix style file mode for the files sent to the remote
+ * system.
+ */
+ public void setChmod(String theMode) {
+ this.chmod = theMode;
+ }
+
+ public String getChmod() {
+ return chmod;
+ }
+
+ /**
+ * Sets the default mask for file creation on a unix server.
+ *
+ * @param theUmask unix style umask for files created on the remote server.
+ */
+ public void setUmask(String theUmask) {
+ this.umask = theUmask;
+ }
+
+ public String getUmask() {
+ return umask;
+ }
+
+ /**
+ * A set of files to upload or download
+ *
+ * @param set the set of files to be added to the list of files to be
+ * transferred.
+ */
+ public void addFileset(FileSet set) {
+ filesets.addElement(set);
+ }
+
+ public Vector getFilesets() {
+ return filesets;
+ }
+
+ /**
+ * Sets the FTP action to be taken. Currently accepts "put", "get", "del",
+ * "mkdir", "chmod", "list", and "site".
+ *
+ * @deprecated since 1.5.x.
+ * setAction(String) is deprecated and is replaced with
+ * setAction(FTP.Action) to make Ant's Introspection mechanism do the
+ * work and also to encapsulate operations on the type in its own
+ * class.
+ * @ant.attribute ignore="true"
+ *
+ * @param action the FTP action to be performed.
+ *
+ * @throws BuildException if the action is not a valid action.
+ */
+ public void setAction(String action) throws BuildException {
+ log("DEPRECATED - The setAction(String) method has been deprecated."
+ + " Use setAction(FTP.Action) instead.");
+
+ Action a = new Action();
+
+ a.setValue(action);
+ this.action = a.getAction();
+ }
+
+
+ /**
+ * Sets the FTP action to be taken. Currently accepts "put", "get", "del",
+ * "mkdir", "chmod", "list", and "site".
+ *
+ * @param action the FTP action to be performed.
+ *
+ * @throws BuildException if the action is not a valid action.
+ */
+ public void setAction(Action action) throws BuildException {
+ this.action = action.getAction();
+ }
+
+ public int getAction() {
+ return this.action;
+ }
+
+ /**
+ * The output file for the "list" action. This attribute is ignored for
+ * any other actions.
+ *
+ * @param listing file in which to store the listing.
+ */
+ public void setListing(File listing) {
+ this.listing = listing;
+ }
+
+ public File getListing() {
+ return listing;
+ }
+
+ /**
+ * If true, enables unsuccessful file put, delete and get
+ * operations to be skipped with a warning and the remainder
+ * of the files still transferred.
+ *
+ * @param skipFailedTransfers true if failures in transfers are ignored.
+ */
+ public void setSkipFailedTransfers(boolean skipFailedTransfers) {
+ this.skipFailedTransfers = skipFailedTransfers;
+ }
+
+ public boolean isSkipFailedTransfers() {
+ return skipFailedTransfers;
+ }
+
+ /**
+ * set the flag to skip errors on directory creation.
+ * (and maybe later other server specific errors)
+ *
+ * @param ignoreNoncriticalErrors true if non-critical errors should not
+ * cause a failure.
+ */
+ public void setIgnoreNoncriticalErrors(boolean ignoreNoncriticalErrors) {
+ this.ignoreNoncriticalErrors = ignoreNoncriticalErrors;
+ }
+
+ public boolean isIgnoreNoncriticalErrors() {
+ return ignoreNoncriticalErrors;
+ }
+
+ private void configurationHasBeenSet() {
+ this.isConfigurationSet = true;
+ }
+
+ public boolean isConfigurationSet() {
+ return this.isConfigurationSet;
+ }
+
+ /**
+ * Sets the systemTypeKey attribute.
+ * Method for setting <code>FTPClientConfig</code> remote system key.
+ *
+ * @param systemKey the key to be set - BUT if blank
+ * the default value of null (which signifies "autodetect") will be kept.
+ * @see org.apache.commons.net.ftp.FTPClientConfig
+ */
+ public void setSystemTypeKey(FTPSystemType systemKey) {
+ if (systemKey != null && !systemKey.getValue().equals("")) {
+ this.systemTypeKey = systemKey;
+ configurationHasBeenSet();
+ }
+ }
+
+ /**
+ * Sets the defaultDateFormatConfig attribute.
+ * @param defaultDateFormat configuration to be set, unless it is
+ * null or empty string, in which case ignored.
+ * @see org.apache.commons.net.ftp.FTPClientConfig
+ */
+ public void setDefaultDateFormatConfig(String defaultDateFormat) {
+ if (defaultDateFormat != null && !defaultDateFormat.equals("")) {
+ this.defaultDateFormatConfig = defaultDateFormat;
+ configurationHasBeenSet();
+ }
+ }
+
+ /**
+ * Sets the recentDateFormatConfig attribute.
+ * @param recentDateFormat configuration to be set, unless it is
+ * null or empty string, in which case ignored.
+ * @see org.apache.commons.net.ftp.FTPClientConfig
+ */
+ public void setRecentDateFormatConfig(String recentDateFormat) {
+ if (recentDateFormat != null && !recentDateFormat.equals("")) {
+ this.recentDateFormatConfig = recentDateFormat;
+ configurationHasBeenSet();
+ }
+ }
+
+ /**
+ * Sets the serverLanguageCode attribute.
+ * @param serverLanguageCode configuration to be set, unless it is
+ * null or empty string, in which case ignored.
+ * @see org.apache.commons.net.ftp.FTPClientConfig
+ */
+ public void setServerLanguageCodeConfig(String serverLanguageCode) {
+ if (serverLanguageCode != null && !"".equals(serverLanguageCode)) {
+ this.serverLanguageCodeConfig = serverLanguageCode;
+ configurationHasBeenSet();
+ }
+ }
+
+ /**
+ * Sets the serverTimeZoneConfig attribute.
+ * @param serverTimeZoneId configuration to be set, unless it is
+ * null or empty string, in which case ignored.
+ * @see org.apache.commons.net.ftp.FTPClientConfig
+ */
+ public void setServerTimeZoneConfig(String serverTimeZoneId) {
+ if (serverTimeZoneId != null && !serverTimeZoneId.equals("")) {
+ this.serverTimeZoneConfig = serverTimeZoneId;
+ configurationHasBeenSet();
+ }
+ }
+
+ /**
+ * Sets the shortMonthNamesConfig attribute
+ *
+ * @param shortMonthNames configuration to be set, unless it is
+ * null or empty string, in which case ignored.
+ * @see org.apache.commons.net.ftp.FTPClientConfig
+ */
+ public void setShortMonthNamesConfig(String shortMonthNames) {
+ if (shortMonthNames != null && !shortMonthNames.equals("")) {
+ this.shortMonthNamesConfig = shortMonthNames;
+ configurationHasBeenSet();
+ }
+ }
+
+
+
+ /**
+ * Defines how many times to retry executing FTP command before giving up.
+ * Default is 0 - try once and if failure then give up.
+ *
+ * @param retriesAllowed number of retries to allow. -1 means
+ * keep trying forever. "forever" may also be specified as a
+ * synonym for -1.
+ */
+ public void setRetriesAllowed(String retriesAllowed) {
+ if ("FOREVER".equalsIgnoreCase(retriesAllowed)) {
+ this.retriesAllowed = Retryable.RETRY_FOREVER;
+ } else {
+ try {
+ int retries = Integer.parseInt(retriesAllowed);
+ if (retries < Retryable.RETRY_FOREVER) {
+ throw new BuildException(
+ "Invalid value for retriesAllowed attribute: "
+ + retriesAllowed);
+
+ }
+ this.retriesAllowed = retries;
+ } catch (NumberFormatException px) {
+ throw new BuildException(
+ "Invalid value for retriesAllowed attribute: "
+ + retriesAllowed);
+
+ }
+
+ }
+ }
+
+ public int getRetriesAllowed() {
+ return retriesAllowed;
+ }
+
+ /**
+ * @return Returns the systemTypeKey.
+ */
+ public String getSystemTypeKey() {
+ return systemTypeKey.getValue();
+ }
+ /**
+ * @return Returns the defaultDateFormatConfig.
+ */
+ public String getDefaultDateFormatConfig() {
+ return defaultDateFormatConfig;
+ }
+ /**
+ * @return Returns the recentDateFormatConfig.
+ */
+ public String getRecentDateFormatConfig() {
+ return recentDateFormatConfig;
+ }
+ /**
+ * @return Returns the serverLanguageCodeConfig.
+ */
+ public String getServerLanguageCodeConfig() {
+ return serverLanguageCodeConfig;
+ }
+ /**
+ * @return Returns the serverTimeZoneConfig.
+ */
+ public String getServerTimeZoneConfig() {
+ return serverTimeZoneConfig;
+ }
+ /**
+ * @return Returns the shortMonthNamesConfig.
+ */
+ public String getShortMonthNamesConfig() {
+ return shortMonthNamesConfig;
+ }
+ /**
+ * @return Returns the timestampGranularity.
+ */
+ public Granularity getTimestampGranularity() {
+ return timestampGranularity;
+ }
+ /**
+ * Sets the timestampGranularity attribute
+ * @param timestampGranularity The timestampGranularity to set.
+ */
+ public void setTimestampGranularity(Granularity timestampGranularity) {
+ if (null == timestampGranularity || "".equals(timestampGranularity.getValue())) {
+ return;
+ }
+ this.timestampGranularity = timestampGranularity;
+ }
+ /**
+ * Sets the siteCommand attribute. This attribute
+ * names the command that will be executed if the action
+ * is "site".
+ * @param siteCommand The siteCommand to set.
+ */
+ public void setSiteCommand(String siteCommand) {
+ this.siteCommand = siteCommand;
+ }
+
+ public String getSiteCommand() {
+ return siteCommand;
+ }
+
+ /**
+ * Sets the initialSiteCommand attribute. This attribute
+ * names a site command that will be executed immediately
+ * after connection.
+ * @param initialCommand The initialSiteCommand to set.
+ */
+ public void setInitialSiteCommand(String initialCommand) {
+ this.initialSiteCommand = initialCommand;
+ }
+
+ public String getInitialSiteCommand() {
+ return initialSiteCommand;
+ }
+
+ public long getGranularityMillis() {
+ return this.granularityMillis;
+ }
+
+ public void setGranularityMillis(long granularity) {
+ this.granularityMillis = granularity;
+ }
+
+ /**
+ * Whether to verify that data and control connections are
+ * connected to the same remote host.
+ *
+ * @since Ant 1.8.0
+ */
+ public void setEnableRemoteVerification(boolean b) {
+ enableRemoteVerification = b;
+ }
+
+ public boolean getEnableRemoteVerification() {
+ return enableRemoteVerification;
+ }
+
+ /**
+ * Checks to see that all required parameters are set.
+ *
+ * @throws BuildException if the configuration is not valid.
+ */
+ protected void checkAttributes() throws BuildException {
+ if (server == null) {
+ throw new BuildException("server attribute must be set!");
+ }
+ if (userid == null) {
+ throw new BuildException("userid attribute must be set!");
+ }
+ if (password == null) {
+ throw new BuildException("password attribute must be set!");
+ }
+
+ if ((action == LIST_FILES) && (listing == null)) {
+ throw new BuildException("listing attribute must be set for list "
+ + "action!");
+ }
+
+ if (action == MK_DIR && remotedir == null) {
+ throw new BuildException("remotedir attribute must be set for "
+ + "mkdir action!");
+ }
+
+ if (action == CHMOD && chmod == null) {
+ throw new BuildException("chmod attribute must be set for chmod "
+ + "action!");
+ }
+ if (action == SITE_CMD && siteCommand == null) {
+ throw new BuildException("sitecommand attribute must be set for site "
+ + "action!");
+ }
+
+
+ if (this.isConfigurationSet) {
+ try {
+ Class.forName("org.apache.commons.net.ftp.FTPClientConfig");
+ } catch (ClassNotFoundException e) {
+ throw new BuildException(
+ "commons-net.jar >= 1.4.0 is required for at least one"
+ + " of the attributes specified.");
+ }
+ }
+ }
+
+ /**
+ * Runs the task.
+ *
+ * @throws BuildException if the task fails or is not configured
+ * correctly.
+ */
+ public void execute() throws BuildException {
+ checkAttributes();
+ try {
+ setupFTPDelegate();
+ delegate.doFTP();
+ } finally {
+ if (mirrorLoader instanceof SplitClassLoader) {
+ ((SplitClassLoader) mirrorLoader).cleanup();
+ }
+ mirrorLoader = null;
+ }
+ }
+
+ public Path createClasspath() {
+ if (classpath == null) {
+ classpath = new Path(getProject());
+ }
+ return classpath;
+ }
+
+ protected void setupFTPDelegate() {
+ ClassLoader myLoader = FTPTask.class.getClassLoader();
+ if (mustSplit()) {
+ mirrorLoader =
+ new SplitClassLoader(myLoader, classpath, getProject(),
+ new String[] {
+ "FTPTaskMirrorImpl",
+ "FTPConfigurator"
+ });
+ } else {
+ mirrorLoader = myLoader;
+ }
+ delegate = createMirror(this, mirrorLoader);
+ }
+
+ private static boolean mustSplit() {
+ return LoaderUtils.getResourceSource(FTPTask.class.getClassLoader(),
+ "/org/apache/commons/net/"
+ + "ftp/FTP.class")
+ == null;
+ }
+
+ private static FTPTaskMirror createMirror(FTPTask task,
+ ClassLoader loader) {
+ try {
+ loader.loadClass("org.apache.commons.net.ftp.FTP"); // sanity check
+ } catch (ClassNotFoundException e) {
+ throw new BuildException("The <classpath> for <ftp> must include"
+ + " commons-net.jar if not in Ant's own "
+ + " classpath", e, task.getLocation());
+ }
+ try {
+ Class c = loader.loadClass(FTPTaskMirror.class.getName() + "Impl");
+ if (c.getClassLoader() != loader) {
+ throw new BuildException("Overdelegating loader",
+ task.getLocation());
+ }
+ Constructor cons = c.getConstructor(new Class[] {FTPTask.class});
+ return (FTPTaskMirror) cons.newInstance(new Object[] {task});
+ } catch (Exception e) {
+ throw new BuildException(e, task.getLocation());
+ }
+ }
+
+ /**
+ * an action to perform, one of
+ * "send", "put", "recv", "get", "del", "delete", "list", "mkdir", "chmod",
+ * "rmdir"
+ */
+ public static class Action extends EnumeratedAttribute {
+
+ private static final String[] VALID_ACTIONS = {
+ "send", "put", "recv", "get", "del", "delete", "list", "mkdir",
+ "chmod", "rmdir", "site"
+ };
+
+
+ /**
+ * Get the valid values
+ *
+ * @return an array of the valid FTP actions.
+ */
+ public String[] getValues() {
+ return VALID_ACTIONS;
+ }
+
+
+ /**
+ * Get the symbolic equivalent of the action value.
+ *
+ * @return the SYMBOL representing the given action.
+ */
+ public int getAction() {
+ String actionL = getValue().toLowerCase(Locale.ENGLISH);
+ if (actionL.equals("send") || actionL.equals("put")) {
+ return SEND_FILES;
+ } else if (actionL.equals("recv") || actionL.equals("get")) {
+ return GET_FILES;
+ } else if (actionL.equals("del") || actionL.equals("delete")) {
+ return DEL_FILES;
+ } else if (actionL.equals("list")) {
+ return LIST_FILES;
+ } else if (actionL.equals("chmod")) {
+ return CHMOD;
+ } else if (actionL.equals("mkdir")) {
+ return MK_DIR;
+ } else if (actionL.equals("rmdir")) {
+ return RM_DIR;
+ } else if (actionL.equals("site")) {
+ return SITE_CMD;
+ }
+ return SEND_FILES;
+ }
+ }
+ /**
+ * represents one of the valid timestamp adjustment values
+ * recognized by the <code>timestampGranularity</code> attribute.<p>
+
+ * A timestamp adjustment may be used in file transfers for checking
+ * uptodateness. MINUTE means to add one minute to the server
+ * timestamp. This is done because FTP servers typically list
+ * timestamps HH:mm and client FileSystems typically use HH:mm:ss.
+ *
+ * The default is to use MINUTE for PUT actions and NONE for GET
+ * actions, since GETs have the <code>preserveLastModified</code>
+ * option, which takes care of the problem in most use cases where
+ * this level of granularity is an issue.
+ *
+ */
+ public static class Granularity extends EnumeratedAttribute {
+
+ private static final String[] VALID_GRANULARITIES = {
+ "", "MINUTE", "NONE"
+ };
+
+ /**
+ * Get the valid values.
+ * @return the list of valid Granularity values
+ */
+ public String[] getValues() {
+ return VALID_GRANULARITIES;
+ }
+ /**
+ * returns the number of milliseconds associated with
+ * the attribute, which can vary in some cases depending
+ * on the value of the action parameter.
+ * @param action SEND_FILES or GET_FILES
+ * @return the number of milliseconds associated with
+ * the attribute, in the context of the supplied action
+ */
+ public long getMilliseconds(int action) {
+ String granularityU = getValue().toUpperCase(Locale.ENGLISH);
+ if ("".equals(granularityU)) {
+ if (action == SEND_FILES) {
+ return GRANULARITY_MINUTE;
+ }
+ } else if ("MINUTE".equals(granularityU)) {
+ return GRANULARITY_MINUTE;
+ }
+ return 0L;
+ }
+ static final Granularity getDefault() {
+ Granularity g = new Granularity();
+ g.setValue("");
+ return g;
+ }
+
+ }
+ /**
+ * one of the valid system type keys recognized by the systemTypeKey
+ * attribute.
+ */
+ public static class FTPSystemType extends EnumeratedAttribute {
+
+ private static final String[] VALID_SYSTEM_TYPES = {
+ "", "UNIX", "VMS", "WINDOWS", "OS/2", "OS/400",
+ "MVS"
+ };
+
+
+ /**
+ * Get the valid values.
+ * @return the list of valid system types.
+ */
+ public String[] getValues() {
+ return VALID_SYSTEM_TYPES;
+ }
+
+ static final FTPSystemType getDefault() {
+ FTPSystemType ftpst = new FTPSystemType();
+ ftpst.setValue("");
+ return ftpst;
+ }
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/net/FTPTaskConfig.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/net/FTPTaskConfig.java
new file mode 100644
index 00000000..006df61f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/net/FTPTaskConfig.java
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.net;
+
+interface FTPTaskConfig {
+ void log(String msg, int level);
+ String getSystemTypeKey();
+ String getDefaultDateFormatConfig();
+ String getRecentDateFormatConfig();
+ String getServerLanguageCodeConfig();
+ String getServerTimeZoneConfig();
+ String getShortMonthNamesConfig();
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/net/FTPTaskMirror.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/net/FTPTaskMirror.java
new file mode 100644
index 00000000..5d09e6f6
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/net/FTPTaskMirror.java
@@ -0,0 +1,24 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.net;
+
+import org.apache.tools.ant.BuildException;
+
+public interface FTPTaskMirror {
+ void doFTP() throws BuildException;
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/net/FTPTaskMirrorImpl.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/net/FTPTaskMirrorImpl.java
new file mode 100644
index 00000000..a4f24130
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/net/FTPTaskMirrorImpl.java
@@ -0,0 +1,1951 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.net;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Map;
+import java.util.Set;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import org.apache.commons.net.ftp.FTPClient;
+import org.apache.commons.net.ftp.FTPFile;
+import org.apache.commons.net.ftp.FTPReply;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.DirectoryScanner;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.Delete;
+import org.apache.tools.ant.types.FileSet;
+import org.apache.tools.ant.types.selectors.SelectorUtils;
+import org.apache.tools.ant.util.FileUtils;
+import org.apache.tools.ant.util.RetryHandler;
+import org.apache.tools.ant.util.Retryable;
+import org.apache.tools.ant.util.VectorSet;
+
+public class FTPTaskMirrorImpl implements FTPTaskMirror {
+
+ /** return code of ftp */
+ private static final int CODE_521 = 521;
+ private static final int CODE_550 = 550;
+ private static final int CODE_553 = 553;
+
+ /** Date formatter used in logging, note not thread safe! */
+ private static final SimpleDateFormat TIMESTAMP_LOGGING_SDF =
+ new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+
+ private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+
+ private final FTPTask task;
+ private Set dirCache = new HashSet();
+ private int transferred = 0;
+ private int skipped = 0;
+
+ /**
+ * Constructor.
+ * @param task the FTPTask that uses this mirror.
+ */
+ public FTPTaskMirrorImpl(FTPTask task) {
+ this.task = task;
+ }
+
+ /**
+ * internal class providing a File-like interface to some of the information
+ * available from the FTP server
+ *
+ */
+ protected static class FTPFileProxy extends File {
+
+ private final FTPFile file;
+ private final String[] parts;
+ private final String name;
+
+ /**
+ * creates a proxy to a FTP file
+ * @param file
+ */
+ public FTPFileProxy(FTPFile file) {
+ super(file.getName());
+ name = file.getName();
+ this.file = file;
+ parts = FileUtils.getPathStack(name);
+ }
+
+ /**
+ * creates a proxy to a FTP directory
+ * @param completePath the remote directory.
+ */
+ public FTPFileProxy(String completePath) {
+ super(completePath);
+ file = null;
+ name = completePath;
+ parts = FileUtils.getPathStack(completePath);
+ }
+
+
+ /* (non-Javadoc)
+ * @see java.io.File#exists()
+ */
+ public boolean exists() {
+ return true;
+ }
+
+
+ /* (non-Javadoc)
+ * @see java.io.File#getAbsolutePath()
+ */
+ public String getAbsolutePath() {
+ return name;
+ }
+
+
+ /* (non-Javadoc)
+ * @see java.io.File#getName()
+ */
+ public String getName() {
+ return parts.length > 0 ? parts[parts.length - 1] : name;
+ }
+
+
+ /* (non-Javadoc)
+ * @see java.io.File#getParent()
+ */
+ public String getParent() {
+ String result = "";
+ for(int i = 0; i < parts.length - 1; i++){
+ result += File.separatorChar + parts[i];
+ }
+ return result;
+ }
+
+
+ /* (non-Javadoc)
+ * @see java.io.File#getPath()
+ */
+ public String getPath() {
+ return name;
+ }
+
+
+ /**
+ * FTP files are stored as absolute paths
+ * @return true
+ */
+ public boolean isAbsolute() {
+ return true;
+ }
+
+
+ /* (non-Javadoc)
+ * @see java.io.File#isDirectory()
+ */
+ public boolean isDirectory() {
+ return file == null;
+ }
+
+
+ /* (non-Javadoc)
+ * @see java.io.File#isFile()
+ */
+ public boolean isFile() {
+ return file != null;
+ }
+
+
+ /**
+ * FTP files cannot be hidden
+ *
+ * @return false
+ */
+ public boolean isHidden() {
+ return false;
+ }
+
+
+ /* (non-Javadoc)
+ * @see java.io.File#lastModified()
+ */
+ public long lastModified() {
+ if (file != null) {
+ return file.getTimestamp().getTimeInMillis();
+ }
+ return 0;
+ }
+
+
+ /* (non-Javadoc)
+ * @see java.io.File#length()
+ */
+ public long length() {
+ if (file != null) {
+ return file.getSize();
+ }
+ return 0;
+ }
+ }
+
+ /**
+ * internal class allowing to read the contents of a remote file system
+ * using the FTP protocol
+ * used in particular for ftp get operations
+ * differences with DirectoryScanner
+ * "" (the root of the fileset) is never included in the included directories
+ * followSymlinks defaults to false
+ */
+ protected class FTPDirectoryScanner extends DirectoryScanner {
+ // CheckStyle:VisibilityModifier OFF - bc
+ protected FTPClient ftp = null;
+ // CheckStyle:VisibilityModifier ON
+
+ private String rootPath = null;
+
+ /**
+ * since ant 1.6
+ * this flag should be set to true on UNIX and can save scanning time
+ */
+ private boolean remoteSystemCaseSensitive = false;
+ private boolean remoteSensitivityChecked = false;
+
+ /**
+ * constructor
+ * @param ftp ftpclient object
+ */
+ public FTPDirectoryScanner(FTPClient ftp) {
+ super();
+ this.ftp = ftp;
+ this.setFollowSymlinks(false);
+ }
+
+
+ /**
+ * scans the remote directory,
+ * storing internally the included files, directories, ...
+ */
+ public void scan() {
+ if (includes == null) {
+ // No includes supplied, so set it to 'matches all'
+ includes = new String[1];
+ includes[0] = "**";
+ }
+ if (excludes == null) {
+ excludes = new String[0];
+ }
+
+ filesIncluded = new VectorSet();
+ filesNotIncluded = new Vector();
+ filesExcluded = new VectorSet();
+ dirsIncluded = new VectorSet();
+ dirsNotIncluded = new Vector();
+ dirsExcluded = new VectorSet();
+
+ try {
+ String cwd = ftp.printWorkingDirectory();
+ // always start from the current ftp working dir
+ forceRemoteSensitivityCheck();
+
+ checkIncludePatterns();
+ clearCaches();
+ ftp.changeWorkingDirectory(cwd);
+ } catch (IOException e) {
+ throw new BuildException("Unable to scan FTP server: ", e);
+ }
+ }
+
+
+ /**
+ * this routine is actually checking all the include patterns in
+ * order to avoid scanning everything under base dir
+ * @since ant1.6
+ */
+ private void checkIncludePatterns() {
+
+ Hashtable newroots = new Hashtable();
+ // put in the newroots vector the include patterns without
+ // wildcard tokens
+ for (int icounter = 0; icounter < includes.length; icounter++) {
+ String newpattern =
+ SelectorUtils.rtrimWildcardTokens(includes[icounter]);
+ newroots.put(newpattern, includes[icounter]);
+ }
+ if (task.getRemotedir() == null) {
+ try {
+ task.setRemotedir(ftp.printWorkingDirectory());
+ } catch (IOException e) {
+ throw new BuildException("could not read current ftp directory",
+ task.getLocation());
+ }
+ }
+ AntFTPFile baseFTPFile = new AntFTPRootFile(ftp, task.getRemotedir());
+ rootPath = baseFTPFile.getAbsolutePath();
+ // construct it
+ if (newroots.containsKey("")) {
+ // we are going to scan everything anyway
+ scandir(rootPath, "", true);
+ } else {
+ // only scan directories that can include matched files or
+ // directories
+ Enumeration enum2 = newroots.keys();
+
+ while (enum2.hasMoreElements()) {
+ String currentelement = (String) enum2.nextElement();
+ String originalpattern = (String) newroots.get(currentelement);
+ AntFTPFile myfile = new AntFTPFile(baseFTPFile, currentelement);
+ boolean isOK = true;
+ boolean traversesSymlinks = false;
+ String path = null;
+
+ if (myfile.exists()) {
+ forceRemoteSensitivityCheck();
+ if (remoteSensitivityChecked
+ && remoteSystemCaseSensitive && isFollowSymlinks()) {
+ // cool case,
+ //we do not need to scan all the subdirs in the relative path
+ path = myfile.getFastRelativePath();
+ } else {
+ // may be on a case insensitive file system. We want
+ // the results to show what's really on the disk, so
+ // we need to double check.
+ try {
+ path = myfile.getRelativePath();
+ traversesSymlinks = myfile.isTraverseSymlinks();
+ } catch (IOException be) {
+ throw new BuildException(be, task.getLocation());
+ } catch (BuildException be) {
+ isOK = false;
+ }
+ }
+ } else {
+ isOK = false;
+ }
+ if (isOK) {
+ currentelement = path.replace(task.getSeparator().charAt(0), File.separatorChar);
+ if (!isFollowSymlinks()
+ && traversesSymlinks) {
+ continue;
+ }
+
+ if (myfile.isDirectory()) {
+ if (isIncluded(currentelement)
+ && currentelement.length() > 0) {
+ accountForIncludedDir(currentelement, myfile, true);
+ } else {
+ if (currentelement.length() > 0) {
+ if (currentelement.charAt(currentelement
+ .length() - 1)
+ != File.separatorChar) {
+ currentelement =
+ currentelement + File.separatorChar;
+ }
+ }
+ scandir(myfile.getAbsolutePath(), currentelement, true);
+ }
+ } else {
+ if (isCaseSensitive
+ && originalpattern.equals(currentelement)) {
+ accountForIncludedFile(currentelement);
+ } else if (!isCaseSensitive
+ && originalpattern
+ .equalsIgnoreCase(currentelement)) {
+ accountForIncludedFile(currentelement);
+ }
+ }
+ }
+ }
+ }
+ }
+ /**
+ * scans a particular directory. populates the scannedDirs cache.
+ *
+ * @param dir directory to scan
+ * @param vpath relative path to the base directory of the remote fileset
+ * always ended with a File.separator
+ * @param fast seems to be always true in practice
+ */
+ protected void scandir(String dir, String vpath, boolean fast) {
+ // avoid double scanning of directories, can only happen in fast mode
+ if (fast && hasBeenScanned(vpath)) {
+ return;
+ }
+ try {
+ if (!ftp.changeWorkingDirectory(dir)) {
+ return;
+ }
+ String completePath = null;
+ if (!vpath.equals("")) {
+ completePath = rootPath + task.getSeparator()
+ + vpath.replace(File.separatorChar, task.getSeparator().charAt(0));
+ } else {
+ completePath = rootPath;
+ }
+ FTPFile[] newfiles = listFiles(completePath, false);
+
+ if (newfiles == null) {
+ ftp.changeToParentDirectory();
+ return;
+ }
+ for (int i = 0; i < newfiles.length; i++) {
+ FTPFile file = newfiles[i];
+ if (file != null
+ && !file.getName().equals(".")
+ && !file.getName().equals("..")) {
+ String name = vpath + file.getName();
+ scannedDirs.put(name, new FTPFileProxy(file));
+ if (isFunctioningAsDirectory(ftp, dir, file)) {
+ boolean slowScanAllowed = true;
+ if (!isFollowSymlinks() && file.isSymbolicLink()) {
+ dirsExcluded.addElement(name);
+ slowScanAllowed = false;
+ } else if (isIncluded(name)) {
+ accountForIncludedDir(name,
+ new AntFTPFile(ftp, file, completePath) , fast);
+ } else {
+ dirsNotIncluded.addElement(name);
+ if (fast && couldHoldIncluded(name)) {
+ scandir(file.getName(),
+ name + File.separator, fast);
+ }
+ }
+ if (!fast && slowScanAllowed) {
+ scandir(file.getName(),
+ name + File.separator, fast);
+ }
+ } else {
+ if (!isFollowSymlinks() && file.isSymbolicLink()) {
+ filesExcluded.addElement(name);
+ } else if (isFunctioningAsFile(ftp, dir, file)) {
+ accountForIncludedFile(name);
+ }
+ }
+ }
+ }
+ ftp.changeToParentDirectory();
+ } catch (IOException e) {
+ throw new BuildException("Error while communicating with FTP "
+ + "server: ", e);
+ }
+ }
+ /**
+ * process included file
+ * @param name path of the file relative to the directory of the fileset
+ */
+ private void accountForIncludedFile(String name) {
+ if (!filesIncluded.contains(name)
+ && !filesExcluded.contains(name)) {
+
+ if (isIncluded(name)) {
+ if (!isExcluded(name)
+ && isSelected(name, (File) scannedDirs.get(name))) {
+ filesIncluded.addElement(name);
+ } else {
+ filesExcluded.addElement(name);
+ }
+ } else {
+ filesNotIncluded.addElement(name);
+ }
+ }
+ }
+
+ /**
+ *
+ * @param name path of the directory relative to the directory of
+ * the fileset
+ * @param file directory as file
+ * @param fast
+ */
+ private void accountForIncludedDir(String name, AntFTPFile file, boolean fast) {
+ if (!dirsIncluded.contains(name)
+ && !dirsExcluded.contains(name)) {
+
+ if (!isExcluded(name)) {
+ if (fast) {
+ if (file.isSymbolicLink()) {
+ try {
+ file.getClient().changeWorkingDirectory(file.curpwd);
+ } catch (IOException ioe) {
+ throw new BuildException("could not change directory to curpwd");
+ }
+ scandir(file.getLink(),
+ name + File.separator, fast);
+ } else {
+ try {
+ file.getClient().changeWorkingDirectory(file.curpwd);
+ } catch (IOException ioe) {
+ throw new BuildException("could not change directory to curpwd");
+ }
+ scandir(file.getName(),
+ name + File.separator, fast);
+ }
+ }
+ dirsIncluded.addElement(name);
+ } else {
+ dirsExcluded.addElement(name);
+ if (fast && couldHoldIncluded(name)) {
+ try {
+ file.getClient().changeWorkingDirectory(file.curpwd);
+ } catch (IOException ioe) {
+ throw new BuildException("could not change directory to curpwd");
+ }
+ scandir(file.getName(),
+ name + File.separator, fast);
+ }
+ }
+ }
+ }
+ /**
+ * temporary table to speed up the various scanning methods below
+ *
+ * @since Ant 1.6
+ */
+ private Map fileListMap = new HashMap();
+ /**
+ * List of all scanned directories.
+ *
+ * @since Ant 1.6
+ */
+
+ private Map scannedDirs = new HashMap();
+
+ /**
+ * Has the directory with the given path relative to the base
+ * directory already been scanned?
+ *
+ * @since Ant 1.6
+ */
+ private boolean hasBeenScanned(String vpath) {
+ return scannedDirs.containsKey(vpath);
+ }
+
+ /**
+ * Clear internal caches.
+ *
+ * @since Ant 1.6
+ */
+ private void clearCaches() {
+ fileListMap.clear();
+ scannedDirs.clear();
+ }
+ /**
+ * list the files present in one directory.
+ * @param directory full path on the remote side
+ * @param changedir if true change to directory directory before listing
+ * @return array of FTPFile
+ */
+ public FTPFile[] listFiles(String directory, boolean changedir) {
+ //task.log("listing files in directory " + directory, Project.MSG_DEBUG);
+ String currentPath = directory;
+ if (changedir) {
+ try {
+ boolean result = ftp.changeWorkingDirectory(directory);
+ if (!result) {
+ return null;
+ }
+ currentPath = ftp.printWorkingDirectory();
+ } catch (IOException ioe) {
+ throw new BuildException(ioe, task.getLocation());
+ }
+ }
+ if (fileListMap.containsKey(currentPath)) {
+ task.log("filelist map used in listing files", Project.MSG_DEBUG);
+ return ((FTPFile[]) fileListMap.get(currentPath));
+ }
+ FTPFile[] result = null;
+ try {
+ result = ftp.listFiles();
+ } catch (IOException ioe) {
+ throw new BuildException(ioe, task.getLocation());
+ }
+ fileListMap.put(currentPath, result);
+ if (!remoteSensitivityChecked) {
+ checkRemoteSensitivity(result, directory);
+ }
+ return result;
+ }
+
+ private void forceRemoteSensitivityCheck() {
+ if (!remoteSensitivityChecked) {
+ try {
+ checkRemoteSensitivity(ftp.listFiles(), ftp.printWorkingDirectory());
+ } catch (IOException ioe) {
+ throw new BuildException(ioe, task.getLocation());
+ }
+ }
+ }
+ /**
+ * cd into one directory and
+ * list the files present in one directory.
+ * @param directory full path on the remote side
+ * @return array of FTPFile
+ */
+ public FTPFile[] listFiles(String directory) {
+ return listFiles(directory, true);
+ }
+ private void checkRemoteSensitivity(FTPFile[] array, String directory) {
+ if (array == null) {
+ return;
+ }
+ boolean candidateFound = false;
+ String target = null;
+ for (int icounter = 0; icounter < array.length; icounter++) {
+ if (array[icounter] != null && array[icounter].isDirectory()) {
+ if (!array[icounter].getName().equals(".")
+ && !array[icounter].getName().equals("..")) {
+ candidateFound = true;
+ target = fiddleName(array[icounter].getName());
+ task.log("will try to cd to "
+ + target + " where a directory called " + array[icounter].getName()
+ + " exists", Project.MSG_DEBUG);
+ for (int pcounter = 0; pcounter < array.length; pcounter++) {
+ if (array[pcounter] != null
+ && pcounter != icounter
+ && target.equals(array[pcounter].getName())) {
+ candidateFound = false;
+ break;
+ }
+ }
+ if (candidateFound) {
+ break;
+ }
+ }
+ }
+ }
+ if (candidateFound) {
+ try {
+ task.log("testing case sensitivity, attempting to cd to "
+ + target, Project.MSG_DEBUG);
+ remoteSystemCaseSensitive = !ftp.changeWorkingDirectory(target);
+ } catch (IOException ioe) {
+ remoteSystemCaseSensitive = true;
+ } finally {
+ try {
+ ftp.changeWorkingDirectory(directory);
+ } catch (IOException ioe) {
+ throw new BuildException(ioe, task.getLocation());
+ }
+ }
+ task.log("remote system is case sensitive : "
+ + remoteSystemCaseSensitive,
+ Project.MSG_VERBOSE);
+ remoteSensitivityChecked = true;
+ }
+ }
+ private String fiddleName(String origin) {
+ StringBuffer result = new StringBuffer();
+ for (int icounter = 0; icounter < origin.length(); icounter++) {
+ if (Character.isLowerCase(origin.charAt(icounter))) {
+ result.append(Character.toUpperCase(origin.charAt(icounter)));
+ } else if (Character.isUpperCase(origin.charAt(icounter))) {
+ result.append(Character.toLowerCase(origin.charAt(icounter)));
+ } else {
+ result.append(origin.charAt(icounter));
+ }
+ }
+ return result.toString();
+ }
+ /**
+ * an AntFTPFile is a representation of a remote file
+ * @since Ant 1.6
+ */
+ protected class AntFTPFile {
+ /**
+ * ftp client
+ */
+ private FTPClient client;
+ /**
+ * parent directory of the file
+ */
+ private String curpwd;
+ /**
+ * the file itself
+ */
+ private FTPFile ftpFile;
+ /**
+ *
+ */
+ private AntFTPFile parent = null;
+ private boolean relativePathCalculated = false;
+ private boolean traversesSymlinks = false;
+ private String relativePath = "";
+ /**
+ * constructor
+ * @param client ftp client variable
+ * @param ftpFile the file
+ * @param curpwd absolute remote path where the file is found
+ */
+ public AntFTPFile(FTPClient client, FTPFile ftpFile, String curpwd) {
+ this.client = client;
+ this.ftpFile = ftpFile;
+ this.curpwd = curpwd;
+ }
+ /**
+ * other constructor
+ * @param parent the parent file
+ * @param path a relative path to the parent file
+ */
+ public AntFTPFile(AntFTPFile parent, String path) {
+ this.parent = parent;
+ this.client = parent.client;
+ Vector pathElements = SelectorUtils.tokenizePath(path);
+ try {
+ boolean result = this.client.changeWorkingDirectory(parent.getAbsolutePath());
+ //this should not happen, except if parent has been deleted by another process
+ if (!result) {
+ return;
+ }
+ this.curpwd = parent.getAbsolutePath();
+ } catch (IOException ioe) {
+ throw new BuildException("could not change working dir to "
+ + parent.curpwd);
+ }
+ final int size = pathElements.size();
+ for (int fcount = 0; fcount < size - 1; fcount++) {
+ String currentPathElement = (String) pathElements.elementAt(fcount);
+ try {
+ boolean result = this.client.changeWorkingDirectory(currentPathElement);
+ if (!result && !isCaseSensitive()
+ && (remoteSystemCaseSensitive || !remoteSensitivityChecked)) {
+ currentPathElement = findPathElementCaseUnsensitive(this.curpwd,
+ currentPathElement);
+ if (currentPathElement == null) {
+ return;
+ }
+ } else if (!result) {
+ return;
+ }
+ this.curpwd = getCurpwdPlusFileSep()
+ + currentPathElement;
+ } catch (IOException ioe) {
+ throw new BuildException("could not change working dir to "
+ + (String) pathElements.elementAt(fcount)
+ + " from " + this.curpwd);
+ }
+
+ }
+ String lastpathelement = (String) pathElements.elementAt(size - 1);
+ FTPFile [] theFiles = listFiles(this.curpwd);
+ this.ftpFile = getFile(theFiles, lastpathelement);
+ }
+ /**
+ * find a file in a directory in case unsensitive way
+ * @param parentPath where we are
+ * @param soughtPathElement what is being sought
+ * @return the first file found or null if not found
+ */
+ private String findPathElementCaseUnsensitive(String parentPath,
+ String soughtPathElement) {
+ // we are already in the right path, so the second parameter
+ // is false
+ FTPFile[] theFiles = listFiles(parentPath, false);
+ if (theFiles == null) {
+ return null;
+ }
+ for (int icounter = 0; icounter < theFiles.length; icounter++) {
+ if (theFiles[icounter] != null
+ && theFiles[icounter].getName().equalsIgnoreCase(soughtPathElement)) {
+ return theFiles[icounter].getName();
+ }
+ }
+ return null;
+ }
+ /**
+ * find out if the file exists
+ * @return true if the file exists
+ */
+ public boolean exists() {
+ return (ftpFile != null);
+ }
+ /**
+ * if the file is a symbolic link, find out to what it is pointing
+ * @return the target of the symbolic link
+ */
+ public String getLink() {
+ return ftpFile.getLink();
+ }
+ /**
+ * get the name of the file
+ * @return the name of the file
+ */
+ public String getName() {
+ return ftpFile.getName();
+ }
+ /**
+ * find out the absolute path of the file
+ * @return absolute path as string
+ */
+ public String getAbsolutePath() {
+ return getCurpwdPlusFileSep() + ftpFile.getName();
+ }
+ /**
+ * find out the relative path assuming that the path used to construct
+ * this AntFTPFile was spelled properly with regards to case.
+ * This is OK on a case sensitive system such as UNIX
+ * @return relative path
+ */
+ public String getFastRelativePath() {
+ String absPath = getAbsolutePath();
+ if (absPath.startsWith(rootPath + task.getSeparator())) {
+ return absPath.substring(rootPath.length()
+ + task.getSeparator().length());
+ }
+ return null;
+ }
+ /**
+ * find out the relative path to the rootPath of the enclosing scanner.
+ * this relative path is spelled exactly like on disk,
+ * for instance if the AntFTPFile has been instantiated as ALPHA,
+ * but the file is really called alpha, this method will return alpha.
+ * If a symbolic link is encountered, it is followed, but the name of the link
+ * rather than the name of the target is returned.
+ * (ie does not behave like File.getCanonicalPath())
+ * @return relative path, separated by remoteFileSep
+ * @throws IOException if a change directory fails, ...
+ * @throws BuildException if one of the components of the relative path cannot
+ * be found.
+ */
+ public String getRelativePath() throws IOException, BuildException {
+ if (!relativePathCalculated) {
+ if (parent != null) {
+ traversesSymlinks = parent.isTraverseSymlinks();
+ relativePath = getRelativePath(parent.getAbsolutePath(),
+ parent.getRelativePath());
+ } else {
+ relativePath = getRelativePath(rootPath, "");
+ relativePathCalculated = true;
+ }
+ }
+ return relativePath;
+ }
+ /**
+ * get the relative path of this file
+ * @param currentPath base path
+ * @param currentRelativePath relative path of the base path with regards to remote dir
+ * @return relative path
+ */
+ private String getRelativePath(String currentPath, String currentRelativePath) {
+ Vector pathElements = SelectorUtils.tokenizePath(getAbsolutePath(), task.getSeparator());
+ Vector pathElements2 = SelectorUtils.tokenizePath(currentPath,
+ task.getSeparator());
+ String relPath = currentRelativePath;
+ final int size = pathElements.size();
+ for (int pcount = pathElements2.size(); pcount < size; pcount++) {
+ String currentElement = (String) pathElements.elementAt(pcount);
+ FTPFile[] theFiles = listFiles(currentPath);
+ FTPFile theFile = null;
+ if (theFiles != null) {
+ theFile = getFile(theFiles, currentElement);
+ }
+ if (!relPath.equals("")) {
+ relPath = relPath + task.getSeparator();
+ }
+ if (theFile == null) {
+ // hit a hidden file assume not a symlink
+ relPath = relPath + currentElement;
+ currentPath = currentPath + task.getSeparator()
+ + currentElement;
+ task.log("Hidden file " + relPath
+ + " assumed to not be a symlink.",
+ Project.MSG_VERBOSE);
+ } else {
+ traversesSymlinks = traversesSymlinks || theFile.isSymbolicLink();
+ relPath = relPath + theFile.getName();
+ currentPath = currentPath + task.getSeparator()
+ + theFile.getName();
+ }
+ }
+ return relPath;
+ }
+ /**
+ * find a file matching a string in an array of FTPFile.
+ * This method will find "alpha" when requested for "ALPHA"
+ * if and only if the caseSensitive attribute is set to false.
+ * When caseSensitive is set to true, only the exact match is returned.
+ * @param theFiles array of files
+ * @param lastpathelement the file name being sought
+ * @return null if the file cannot be found, otherwise return the matching file.
+ */
+ public FTPFile getFile(FTPFile[] theFiles, String lastpathelement) {
+ if (theFiles == null) {
+ return null;
+ }
+ for (int fcount = 0; fcount < theFiles.length; fcount++) {
+ if (theFiles[fcount] != null) {
+ if (theFiles[fcount].getName().equals(lastpathelement)) {
+ return theFiles[fcount];
+ } else if (!isCaseSensitive()
+ && theFiles[fcount].getName().equalsIgnoreCase(
+ lastpathelement)) {
+ return theFiles[fcount];
+ }
+ }
+ }
+ return null;
+ }
+ /**
+ * tell if a file is a directory.
+ * note that it will return false for symbolic links pointing to directories.
+ * @return <code>true</code> for directories
+ */
+ public boolean isDirectory() {
+ return ftpFile.isDirectory();
+ }
+ /**
+ * tell if a file is a symbolic link
+ * @return <code>true</code> for symbolic links
+ */
+ public boolean isSymbolicLink() {
+ return ftpFile.isSymbolicLink();
+ }
+ /**
+ * return the attached FTP client object.
+ * Warning : this instance is really shared with the enclosing class.
+ * @return FTP client
+ */
+ protected FTPClient getClient() {
+ return client;
+ }
+
+ /**
+ * sets the current path of an AntFTPFile
+ * @param curpwd the current path one wants to set
+ */
+ protected void setCurpwd(String curpwd) {
+ this.curpwd = curpwd;
+ }
+ /**
+ * returns the path of the directory containing the AntFTPFile.
+ * of the full path of the file itself in case of AntFTPRootFile
+ * @return parent directory of the AntFTPFile
+ */
+ public String getCurpwd() {
+ return curpwd;
+ }
+ /**
+ * returns the path of the directory containing the AntFTPFile.
+ * of the full path of the file itself in case of AntFTPRootFile
+ * and appends the remote file separator if necessary.
+ * @return parent directory of the AntFTPFile
+ * @since Ant 1.8.2
+ */
+ public String getCurpwdPlusFileSep() {
+ String sep = task.getSeparator();
+ return curpwd.endsWith(sep) ? curpwd : curpwd + sep;
+ }
+ /**
+ * find out if a symbolic link is encountered in the relative path of this file
+ * from rootPath.
+ * @return <code>true</code> if a symbolic link is encountered in the relative path.
+ * @throws IOException if one of the change directory or directory listing operations
+ * fails
+ * @throws BuildException if a path component in the relative path cannot be found.
+ */
+ public boolean isTraverseSymlinks() throws IOException, BuildException {
+ if (!relativePathCalculated) {
+ // getRelativePath also finds about symlinks
+ getRelativePath();
+ }
+ return traversesSymlinks;
+ }
+
+ /**
+ * Get a string rep of this object.
+ * @return a string containing the pwd and the file.
+ */
+ public String toString() {
+ return "AntFtpFile: " + curpwd + "%" + ftpFile;
+ }
+ }
+ /**
+ * special class to represent the remote directory itself
+ * @since Ant 1.6
+ */
+ protected class AntFTPRootFile extends AntFTPFile {
+ private String remotedir;
+ /**
+ * constructor
+ * @param aclient FTP client
+ * @param remotedir remote directory
+ */
+ public AntFTPRootFile(FTPClient aclient, String remotedir) {
+ super(aclient, null, remotedir);
+ this.remotedir = remotedir;
+ try {
+ this.getClient().changeWorkingDirectory(this.remotedir);
+ this.setCurpwd(this.getClient().printWorkingDirectory());
+ } catch (IOException ioe) {
+ throw new BuildException(ioe, task.getLocation());
+ }
+ }
+ /**
+ * find the absolute path
+ * @return absolute path
+ */
+ public String getAbsolutePath() {
+ return this.getCurpwd();
+ }
+ /**
+ * find out the relative path to root
+ * @return empty string
+ * @throws BuildException actually never
+ * @throws IOException actually never
+ */
+ public String getRelativePath() throws BuildException, IOException {
+ return "";
+ }
+ }
+ }
+ /**
+ * check FTPFiles to check whether they function as directories too
+ * the FTPFile API seem to make directory and symbolic links incompatible
+ * we want to find out if we can cd to a symbolic link
+ * @param dir the parent directory of the file to test
+ * @param file the file to test
+ * @return true if it is possible to cd to this directory
+ * @since ant 1.6
+ */
+ private boolean isFunctioningAsDirectory(FTPClient ftp, String dir, FTPFile file) {
+ boolean result = false;
+ String currentWorkingDir = null;
+ if (file.isDirectory()) {
+ return true;
+ } else if (file.isFile()) {
+ return false;
+ }
+ try {
+ currentWorkingDir = ftp.printWorkingDirectory();
+ } catch (IOException ioe) {
+ task.log("could not find current working directory " + dir
+ + " while checking a symlink", Project.MSG_DEBUG);
+ }
+ if (currentWorkingDir != null) {
+ try {
+ result = ftp.changeWorkingDirectory(file.getLink());
+ } catch (IOException ioe) {
+ task.log("could not cd to " + file.getLink()
+ + " while checking a symlink",
+ Project.MSG_DEBUG);
+ }
+ if (result) {
+ boolean comeback = false;
+ try {
+ comeback = ftp.changeWorkingDirectory(currentWorkingDir);
+ } catch (IOException ioe) {
+ task.log("could not cd back to " + dir + " while checking a symlink",
+ Project.MSG_ERR);
+ } finally {
+ if (!comeback) {
+ throw new BuildException("could not cd back to " + dir
+ + " while checking a symlink");
+ }
+ }
+ }
+ }
+ return result;
+ }
+ /**
+ * check FTPFiles to check whether they function as directories too
+ * the FTPFile API seem to make directory and symbolic links incompatible
+ * we want to find out if we can cd to a symbolic link
+ * @param dir the parent directory of the file to test
+ * @param file the file to test
+ * @return true if it is possible to cd to this directory
+ * @since ant 1.6
+ */
+ private boolean isFunctioningAsFile(FTPClient ftp, String dir, FTPFile file) {
+ if (file.isDirectory()) {
+ return false;
+ } else if (file.isFile()) {
+ return true;
+ }
+ return !isFunctioningAsDirectory(ftp, dir, file);
+ }
+
+ /**
+ * Executable a retryable object.
+ * @param h the retry handler.
+ * @param r the object that should be retried until it succeeds
+ * or the number of retrys is reached.
+ * @param descr a description of the command that is being run.
+ * @throws IOException if there is a problem.
+ */
+ protected void executeRetryable(RetryHandler h, Retryable r, String descr)
+ throws IOException {
+ h.execute(r, descr);
+ }
+
+
+ /**
+ * For each file in the fileset, do the appropriate action: send, get,
+ * delete, or list.
+ *
+ * @param ftp the FTPClient instance used to perform FTP actions
+ * @param fs the fileset on which the actions are performed.
+ *
+ * @return the number of files to be transferred.
+ *
+ * @throws IOException if there is a problem reading a file
+ * @throws BuildException if there is a problem in the configuration.
+ */
+ protected int transferFiles(final FTPClient ftp, FileSet fs)
+ throws IOException, BuildException {
+ DirectoryScanner ds;
+ if (task.getAction() == FTPTask.SEND_FILES) {
+ ds = fs.getDirectoryScanner(task.getProject());
+ } else {
+ ds = new FTPDirectoryScanner(ftp);
+ fs.setupDirectoryScanner(ds, task.getProject());
+ ds.setFollowSymlinks(fs.isFollowSymlinks());
+ ds.scan();
+ }
+
+ String[] dsfiles = null;
+ if (task.getAction() == FTPTask.RM_DIR) {
+ dsfiles = ds.getIncludedDirectories();
+ } else {
+ dsfiles = ds.getIncludedFiles();
+ }
+ String dir = null;
+
+ if ((ds.getBasedir() == null)
+ && ((task.getAction() == FTPTask.SEND_FILES) || (task.getAction() == FTPTask.GET_FILES))) {
+ throw new BuildException("the dir attribute must be set for send "
+ + "and get actions");
+ } else {
+ if ((task.getAction() == FTPTask.SEND_FILES) || (task.getAction() == FTPTask.GET_FILES)) {
+ dir = ds.getBasedir().getAbsolutePath();
+ }
+ }
+
+ // If we are doing a listing, we need the output stream created now.
+ BufferedWriter bw = null;
+
+ try {
+ if (task.getAction() == FTPTask.LIST_FILES) {
+ File pd = task.getListing().getParentFile();
+
+ if (!pd.exists()) {
+ pd.mkdirs();
+ }
+ bw = new BufferedWriter(new FileWriter(task.getListing()));
+ }
+ RetryHandler h = new RetryHandler(task.getRetriesAllowed(), task);
+ if (task.getAction() == FTPTask.RM_DIR) {
+ // to remove directories, start by the end of the list
+ // the trunk does not let itself be removed before the leaves
+ for (int i = dsfiles.length - 1; i >= 0; i--) {
+ final String dsfile = dsfiles[i];
+ executeRetryable(h, new Retryable() {
+ public void execute() throws IOException {
+ rmDir(ftp, dsfile);
+ }
+ }, dsfile);
+ }
+ } else {
+ final BufferedWriter fbw = bw;
+ final String fdir = dir;
+ if (task.isNewer()) {
+ task.setGranularityMillis(task.getTimestampGranularity()
+ .getMilliseconds(task.getAction()));
+ }
+ for (int i = 0; i < dsfiles.length; i++) {
+ final String dsfile = dsfiles[i];
+ executeRetryable(h, new Retryable() {
+ public void execute() throws IOException {
+ switch (task.getAction()) {
+ case FTPTask.SEND_FILES:
+ sendFile(ftp, fdir, dsfile);
+ break;
+ case FTPTask.GET_FILES:
+ getFile(ftp, fdir, dsfile);
+ break;
+ case FTPTask.DEL_FILES:
+ delFile(ftp, dsfile);
+ break;
+ case FTPTask.LIST_FILES:
+ listFile(ftp, fbw, dsfile);
+ break;
+ case FTPTask.CHMOD:
+ doSiteCommand(ftp, "chmod " + task.getChmod() + " "
+ + resolveFile(dsfile));
+ transferred++;
+ break;
+ default:
+ throw new BuildException("unknown ftp action "
+ + task.getAction());
+ }
+ }
+ }, dsfile);
+ }
+ }
+ } finally {
+ if (bw != null) {
+ bw.close();
+ }
+ }
+
+ return dsfiles.length;
+ }
+
+
+ /**
+ * Sends all files specified by the configured filesets to the remote
+ * server.
+ *
+ * @param ftp the FTPClient instance used to perform FTP actions
+ *
+ * @throws IOException if there is a problem reading a file
+ * @throws BuildException if there is a problem in the configuration.
+ */
+ protected void transferFiles(FTPClient ftp)
+ throws IOException, BuildException {
+ transferred = 0;
+ skipped = 0;
+
+ if (task.getFilesets().size() == 0) {
+ throw new BuildException("at least one fileset must be specified.");
+ } else {
+ // get files from filesets
+ final int size = task.getFilesets().size();
+ for (int i = 0; i < size; i++) {
+ FileSet fs = (FileSet) task.getFilesets().elementAt(i);
+
+ if (fs != null) {
+ transferFiles(ftp, fs);
+ }
+ }
+ }
+
+ task.log(transferred + " " + FTPTask.ACTION_TARGET_STRS[task.getAction()] + " "
+ + FTPTask.COMPLETED_ACTION_STRS[task.getAction()]);
+ if (skipped != 0) {
+ task.log(skipped + " " + FTPTask.ACTION_TARGET_STRS[task.getAction()]
+ + " were not successfully " + FTPTask.COMPLETED_ACTION_STRS[task.getAction()]);
+ }
+ }
+
+
+ /**
+ * Correct a file path to correspond to the remote host requirements. This
+ * implementation currently assumes that the remote end can handle
+ * Unix-style paths with forward-slash separators. This can be overridden
+ * with the <code>separator</code> task parameter. No attempt is made to
+ * determine what syntax is appropriate for the remote host.
+ *
+ * @param file the remote file name to be resolved
+ *
+ * @return the filename as it will appear on the server.
+ */
+ protected String resolveFile(String file) {
+ return file.replace(System.getProperty("file.separator").charAt(0),
+ task.getSeparator().charAt(0));
+ }
+
+
+ /**
+ * Creates all parent directories specified in a complete relative
+ * pathname. Attempts to create existing directories will not cause
+ * errors.
+ *
+ * @param ftp the FTP client instance to use to execute FTP actions on
+ * the remote server.
+ * @param filename the name of the file whose parents should be created.
+ * @throws IOException under non documented circumstances
+ * @throws BuildException if it is impossible to cd to a remote directory
+ *
+ */
+ protected void createParents(FTPClient ftp, String filename)
+ throws IOException, BuildException {
+
+ File dir = new File(filename);
+ if (dirCache.contains(dir)) {
+ return;
+ }
+
+ Vector parents = new Vector();
+ String dirname;
+
+ while ((dirname = dir.getParent()) != null) {
+ File checkDir = new File(dirname);
+ if (dirCache.contains(checkDir)) {
+ break;
+ }
+ dir = checkDir;
+ parents.addElement(dir);
+ }
+
+ // find first non cached dir
+ int i = parents.size() - 1;
+
+ if (i >= 0) {
+ String cwd = ftp.printWorkingDirectory();
+ String parent = dir.getParent();
+ if (parent != null) {
+ if (!ftp.changeWorkingDirectory(resolveFile(parent))) {
+ throw new BuildException("could not change to "
+ + "directory: " + ftp.getReplyString());
+ }
+ }
+
+ while (i >= 0) {
+ dir = (File) parents.elementAt(i--);
+ // check if dir exists by trying to change into it.
+ if (!ftp.changeWorkingDirectory(dir.getName())) {
+ // could not change to it - try to create it
+ task.log("creating remote directory "
+ + resolveFile(dir.getPath()), Project.MSG_VERBOSE);
+ if (!ftp.makeDirectory(dir.getName())) {
+ handleMkDirFailure(ftp);
+ }
+ if (!ftp.changeWorkingDirectory(dir.getName())) {
+ throw new BuildException("could not change to "
+ + "directory: " + ftp.getReplyString());
+ }
+ }
+ dirCache.add(dir);
+ }
+ ftp.changeWorkingDirectory(cwd);
+ }
+ }
+ /**
+ * auto find the time difference between local and remote
+ * @param ftp handle to ftp client
+ * @return number of millis to add to remote time to make it comparable to local time
+ * @since ant 1.6
+ */
+ private long getTimeDiff(FTPClient ftp) {
+ long returnValue = 0;
+ File tempFile = findFileName(ftp);
+ try {
+ // create a local temporary file
+ FILE_UTILS.createNewFile(tempFile);
+ long localTimeStamp = tempFile.lastModified();
+ BufferedInputStream instream = new BufferedInputStream(new FileInputStream(tempFile));
+ ftp.storeFile(tempFile.getName(), instream);
+ instream.close();
+ boolean success = FTPReply.isPositiveCompletion(ftp.getReplyCode());
+ if (success) {
+ FTPFile [] ftpFiles = ftp.listFiles(tempFile.getName());
+ if (ftpFiles.length == 1) {
+ long remoteTimeStamp = ftpFiles[0].getTimestamp().getTime().getTime();
+ returnValue = localTimeStamp - remoteTimeStamp;
+ }
+ ftp.deleteFile(ftpFiles[0].getName());
+ }
+ // delegate the deletion of the local temp file to the delete task
+ // because of race conditions occurring on Windows
+ Delete mydelete = new Delete();
+ mydelete.bindToOwner(task);
+ mydelete.setFile(tempFile.getCanonicalFile());
+ mydelete.execute();
+ } catch (Exception e) {
+ throw new BuildException(e, task.getLocation());
+ }
+ return returnValue;
+ }
+ /**
+ * find a suitable name for local and remote temporary file
+ */
+ private File findFileName(FTPClient ftp) {
+ FTPFile [] theFiles = null;
+ final int maxIterations = 1000;
+ for (int counter = 1; counter < maxIterations; counter++) {
+ File localFile = FILE_UTILS.createTempFile(
+ "ant" + Integer.toString(counter), ".tmp",
+ null, false, false);
+ String fileName = localFile.getName();
+ boolean found = false;
+ try {
+ if (theFiles == null) {
+ theFiles = ftp.listFiles();
+ }
+ for (int counter2 = 0; counter2 < theFiles.length; counter2++) {
+ if (theFiles[counter2] != null
+ && theFiles[counter2].getName().equals(fileName)) {
+ found = true;
+ break;
+ }
+ }
+ } catch (IOException ioe) {
+ throw new BuildException(ioe, task.getLocation());
+ }
+ if (!found) {
+ localFile.deleteOnExit();
+ return localFile;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Checks to see if the remote file is current as compared with the local
+ * file. Returns true if the target file is up to date.
+ * @param ftp ftpclient
+ * @param localFile local file
+ * @param remoteFile remote file
+ * @return true if the target file is up to date
+ * @throws IOException in unknown circumstances
+ * @throws BuildException if the date of the remote files cannot be found and the action is
+ * GET_FILES
+ */
+ protected boolean isUpToDate(FTPClient ftp, File localFile,
+ String remoteFile)
+ throws IOException, BuildException {
+ task.log("checking date for " + remoteFile, Project.MSG_VERBOSE);
+
+ FTPFile[] files = ftp.listFiles(remoteFile);
+
+ // For Microsoft's Ftp-Service an Array with length 0 is
+ // returned if configured to return listings in "MS-DOS"-Format
+ if (files == null || files.length == 0) {
+ // If we are sending files, then assume out of date.
+ // If we are getting files, then throw an error
+
+ if (task.getAction() == FTPTask.SEND_FILES) {
+ task.log("Could not date test remote file: " + remoteFile
+ + "assuming out of date.", Project.MSG_VERBOSE);
+ return false;
+ } else {
+ throw new BuildException("could not date test remote file: "
+ + ftp.getReplyString());
+ }
+ }
+
+ long remoteTimestamp = files[0].getTimestamp().getTime().getTime();
+ long localTimestamp = localFile.lastModified();
+ long adjustedRemoteTimestamp = remoteTimestamp + task.getTimeDiffMillis()
+ + task.getGranularityMillis();
+
+ StringBuffer msg;
+ synchronized(TIMESTAMP_LOGGING_SDF) {
+ msg = new StringBuffer(" [")
+ .append(TIMESTAMP_LOGGING_SDF.format(new Date(localTimestamp)))
+ .append("] local");
+ }
+ task.log(msg.toString(), Project.MSG_VERBOSE);
+
+ synchronized(TIMESTAMP_LOGGING_SDF) {
+ msg = new StringBuffer(" [")
+ .append(TIMESTAMP_LOGGING_SDF.format(new Date(adjustedRemoteTimestamp)))
+ .append("] remote");
+ }
+ if (remoteTimestamp != adjustedRemoteTimestamp) {
+ synchronized(TIMESTAMP_LOGGING_SDF) {
+ msg.append(" - (raw: ")
+ .append(TIMESTAMP_LOGGING_SDF.format(new Date(remoteTimestamp)))
+ .append(")");
+ }
+ }
+ task.log(msg.toString(), Project.MSG_VERBOSE);
+
+ if (task.getAction() == FTPTask.SEND_FILES) {
+ return adjustedRemoteTimestamp >= localTimestamp;
+ } else {
+ return localTimestamp >= adjustedRemoteTimestamp;
+ }
+ }
+
+
+ /**
+ * Sends a site command to the ftp server
+ * @param ftp ftp client
+ * @param theCMD command to execute
+ * @throws IOException in unknown circumstances
+ * @throws BuildException in unknown circumstances
+ */
+ protected void doSiteCommand(FTPClient ftp, String theCMD)
+ throws IOException, BuildException {
+ boolean rc;
+ String[] myReply = null;
+
+ task.log("Doing Site Command: " + theCMD, Project.MSG_VERBOSE);
+
+ rc = ftp.sendSiteCommand(theCMD);
+
+ if (!rc) {
+ task.log("Failed to issue Site Command: " + theCMD, Project.MSG_WARN);
+ } else {
+
+ myReply = ftp.getReplyStrings();
+
+ for (int x = 0; x < myReply.length; x++) {
+ if (myReply[x].indexOf("200") == -1) {
+ task.log(myReply[x], Project.MSG_WARN);
+ }
+ }
+ }
+ }
+
+
+ /**
+ * Sends a single file to the remote host. <code>filename</code> may
+ * contain a relative path specification. When this is the case, <code>sendFile</code>
+ * will attempt to create any necessary parent directories before sending
+ * the file. The file will then be sent using the entire relative path
+ * spec - no attempt is made to change directories. It is anticipated that
+ * this may eventually cause problems with some FTP servers, but it
+ * simplifies the coding.
+ * @param ftp ftp client
+ * @param dir base directory of the file to be sent (local)
+ * @param filename relative path of the file to be send
+ * locally relative to dir
+ * remotely relative to the remotedir attribute
+ * @throws IOException in unknown circumstances
+ * @throws BuildException in unknown circumstances
+ */
+ protected void sendFile(FTPClient ftp, String dir, String filename)
+ throws IOException, BuildException {
+ InputStream instream = null;
+
+ try {
+ // TODO - why not simply new File(dir, filename)?
+ File file = task.getProject().resolveFile(new File(dir, filename).getPath());
+
+ if (task.isNewer() && isUpToDate(ftp, file, resolveFile(filename))) {
+ return;
+ }
+
+ if (task.isVerbose()) {
+ task.log("transferring " + file.getAbsolutePath());
+ }
+
+ instream = new BufferedInputStream(new FileInputStream(file));
+
+ createParents(ftp, filename);
+
+ ftp.storeFile(resolveFile(filename), instream);
+
+ boolean success = FTPReply.isPositiveCompletion(ftp.getReplyCode());
+
+ if (!success) {
+ String s = "could not put file: " + ftp.getReplyString();
+
+ if (task.isSkipFailedTransfers()) {
+ task.log(s, Project.MSG_WARN);
+ skipped++;
+ } else {
+ throw new BuildException(s);
+ }
+
+ } else {
+ // see if we should issue a chmod command
+ if (task.getChmod() != null) {
+ doSiteCommand(ftp, "chmod " + task.getChmod() + " "
+ + resolveFile(filename));
+ }
+ task.log("File " + file.getAbsolutePath() + " copied to " + task.getServer(),
+ Project.MSG_VERBOSE);
+ transferred++;
+ }
+ } finally {
+ if (instream != null) {
+ try {
+ instream.close();
+ } catch (IOException ex) {
+ // ignore it
+ }
+ }
+ }
+ }
+
+
+ /**
+ * Delete a file from the remote host.
+ * @param ftp ftp client
+ * @param filename file to delete
+ * @throws IOException in unknown circumstances
+ * @throws BuildException if skipFailedTransfers is set to false
+ * and the deletion could not be done
+ */
+ protected void delFile(FTPClient ftp, String filename)
+ throws IOException, BuildException {
+ if (task.isVerbose()) {
+ task.log("deleting " + filename);
+ }
+
+ if (!ftp.deleteFile(resolveFile(filename))) {
+ String s = "could not delete file: " + ftp.getReplyString();
+
+ if (task.isSkipFailedTransfers()) {
+ task.log(s, Project.MSG_WARN);
+ skipped++;
+ } else {
+ throw new BuildException(s);
+ }
+ } else {
+ task.log("File " + filename + " deleted from " + task.getServer(),
+ Project.MSG_VERBOSE);
+ transferred++;
+ }
+ }
+
+ /**
+ * Delete a directory, if empty, from the remote host.
+ * @param ftp ftp client
+ * @param dirname directory to delete
+ * @throws IOException in unknown circumstances
+ * @throws BuildException if skipFailedTransfers is set to false
+ * and the deletion could not be done
+ */
+ protected void rmDir(FTPClient ftp, String dirname)
+ throws IOException, BuildException {
+ if (task.isVerbose()) {
+ task.log("removing " + dirname);
+ }
+
+ if (!ftp.removeDirectory(resolveFile(dirname))) {
+ String s = "could not remove directory: " + ftp.getReplyString();
+
+ if (task.isSkipFailedTransfers()) {
+ task.log(s, Project.MSG_WARN);
+ skipped++;
+ } else {
+ throw new BuildException(s);
+ }
+ } else {
+ task.log("Directory " + dirname + " removed from " + task.getServer(),
+ Project.MSG_VERBOSE);
+ transferred++;
+ }
+ }
+
+
+ /**
+ * Retrieve a single file from the remote host. <code>filename</code> may
+ * contain a relative path specification. <p>
+ *
+ * The file will then be retreived using the entire relative path spec -
+ * no attempt is made to change directories. It is anticipated that this
+ * may eventually cause problems with some FTP servers, but it simplifies
+ * the coding.</p>
+ * @param ftp the ftp client
+ * @param dir local base directory to which the file should go back
+ * @param filename relative path of the file based upon the ftp remote directory
+ * and/or the local base directory (dir)
+ * @throws IOException in unknown circumstances
+ * @throws BuildException if skipFailedTransfers is false
+ * and the file cannot be retrieved.
+ */
+ protected void getFile(FTPClient ftp, String dir, String filename)
+ throws IOException, BuildException {
+ OutputStream outstream = null;
+ try {
+ File file = task.getProject().resolveFile(new File(dir, filename).getPath());
+
+ if (task.isNewer() && isUpToDate(ftp, file, resolveFile(filename))) {
+ return;
+ }
+
+ if (task.isVerbose()) {
+ task.log("transferring " + filename + " to "
+ + file.getAbsolutePath());
+ }
+
+ File pdir = file.getParentFile();
+
+ if (!pdir.exists()) {
+ pdir.mkdirs();
+ }
+ outstream = new BufferedOutputStream(new FileOutputStream(file));
+ ftp.retrieveFile(resolveFile(filename), outstream);
+
+ if (!FTPReply.isPositiveCompletion(ftp.getReplyCode())) {
+ String s = "could not get file: " + ftp.getReplyString();
+
+ if (task.isSkipFailedTransfers()) {
+ task.log(s, Project.MSG_WARN);
+ skipped++;
+ } else {
+ throw new BuildException(s);
+ }
+
+ } else {
+ task.log(
+ "File " + file.getAbsolutePath() + " copied from "
+ + task.getServer(), Project.MSG_VERBOSE);
+ transferred++;
+ if (task.isPreserveLastModified()) {
+ outstream.close();
+ outstream = null;
+ FTPFile[] remote = ftp.listFiles(resolveFile(filename));
+ if (remote.length > 0) {
+ FILE_UTILS.setFileLastModified(file,
+ remote[0].getTimestamp()
+ .getTime().getTime());
+ }
+ }
+ }
+ } finally {
+ if (outstream != null) {
+ try {
+ outstream.close();
+ } catch (IOException ex) {
+ // ignore it
+ }
+ }
+ }
+ }
+
+
+ /**
+ * List information about a single file from the remote host. <code>filename</code>
+ * may contain a relative path specification. <p>
+ *
+ * The file listing will then be retrieved using the entire relative path
+ * spec - no attempt is made to change directories. It is anticipated that
+ * this may eventually cause problems with some FTP servers, but it
+ * simplifies the coding.</p>
+ * @param ftp ftp client
+ * @param bw buffered writer
+ * @param filename the directory one wants to list
+ * @throws IOException in unknown circumstances
+ * @throws BuildException in unknown circumstances
+ */
+ protected void listFile(FTPClient ftp, BufferedWriter bw, String filename)
+ throws IOException, BuildException {
+ if (task.isVerbose()) {
+ task.log("listing " + filename);
+ }
+ FTPFile[] ftpfiles = ftp.listFiles(resolveFile(filename));
+
+ if (ftpfiles != null && ftpfiles.length > 0) {
+ bw.write(ftpfiles[0].toString());
+ bw.newLine();
+ transferred++;
+ }
+ }
+
+
+ /**
+ * Create the specified directory on the remote host.
+ *
+ * @param ftp The FTP client connection
+ * @param dir The directory to create (format must be correct for host
+ * type)
+ * @throws IOException in unknown circumstances
+ * @throws BuildException if ignoreNoncriticalErrors has not been set to true
+ * and a directory could not be created, for instance because it was
+ * already existing. Precisely, the codes 521, 550 and 553 will trigger
+ * a BuildException
+ */
+ protected void makeRemoteDir(FTPClient ftp, String dir)
+ throws IOException, BuildException {
+ String workingDirectory = ftp.printWorkingDirectory();
+ if (task.isVerbose()) {
+ if (dir.startsWith("/") || workingDirectory == null) {
+ task.log("Creating directory: " + dir + " in /");
+ } else {
+ task.log("Creating directory: " + dir + " in " + workingDirectory);
+ }
+ }
+ if (dir.startsWith("/")) {
+ ftp.changeWorkingDirectory("/");
+ }
+ String subdir = "";
+ StringTokenizer st = new StringTokenizer(dir, "/");
+ while (st.hasMoreTokens()) {
+ subdir = st.nextToken();
+ task.log("Checking " + subdir, Project.MSG_DEBUG);
+ if (!ftp.changeWorkingDirectory(subdir)) {
+ if (!ftp.makeDirectory(subdir)) {
+ // codes 521, 550 and 553 can be produced by FTP Servers
+ // to indicate that an attempt to create a directory has
+ // failed because the directory already exists.
+ int rc = ftp.getReplyCode();
+ if (!(task.isIgnoreNoncriticalErrors() && (rc == CODE_550
+ || rc == CODE_553
+ || rc == CODE_521))) {
+ throw new BuildException("could not create directory: "
+ + ftp.getReplyString());
+ }
+ if (task.isVerbose()) {
+ task.log("Directory already exists");
+ }
+ } else {
+ if (task.isVerbose()) {
+ task.log("Directory created OK");
+ }
+ ftp.changeWorkingDirectory(subdir);
+ }
+ }
+ }
+ if (workingDirectory != null) {
+ ftp.changeWorkingDirectory(workingDirectory);
+ }
+ }
+
+ /**
+ * look at the response for a failed mkdir action, decide whether
+ * it matters or not. If it does, we throw an exception
+ * @param ftp current ftp connection
+ * @throws BuildException if this is an error to signal
+ */
+ private void handleMkDirFailure(FTPClient ftp)
+ throws BuildException {
+ int rc = ftp.getReplyCode();
+ if (!(task.isIgnoreNoncriticalErrors() && (rc == CODE_550
+ || rc == CODE_553
+ || rc == CODE_521))) {
+ throw new BuildException("could not create directory: "
+ + ftp.getReplyString());
+ }
+ }
+
+ public void doFTP() throws BuildException {
+ FTPClient ftp = null;
+
+ try {
+ task.log("Opening FTP connection to " + task.getServer(), Project.MSG_VERBOSE);
+
+ ftp = new FTPClient();
+ if (task.isConfigurationSet()) {
+ ftp = FTPConfigurator.configure(ftp, task);
+ }
+
+ ftp.setRemoteVerificationEnabled(task.getEnableRemoteVerification());
+ ftp.connect(task.getServer(), task.getPort());
+ if (!FTPReply.isPositiveCompletion(ftp.getReplyCode())) {
+ throw new BuildException("FTP connection failed: "
+ + ftp.getReplyString());
+ }
+
+ task.log("connected", Project.MSG_VERBOSE);
+ task.log("logging in to FTP server", Project.MSG_VERBOSE);
+
+ if ((task.getAccount() != null && !ftp.login(task.getUserid(), task.getPassword(), task.getAccount()))
+ || (task.getAccount() == null && !ftp.login(task.getUserid(), task.getPassword()))) {
+ throw new BuildException("Could not login to FTP server");
+ }
+
+ task.log("login succeeded", Project.MSG_VERBOSE);
+
+ if (task.isBinary()) {
+ ftp.setFileType(org.apache.commons.net.ftp.FTP.BINARY_FILE_TYPE);
+ if (!FTPReply.isPositiveCompletion(ftp.getReplyCode())) {
+ throw new BuildException("could not set transfer type: "
+ + ftp.getReplyString());
+ }
+ } else {
+ ftp.setFileType(org.apache.commons.net.ftp.FTP.ASCII_FILE_TYPE);
+ if (!FTPReply.isPositiveCompletion(ftp.getReplyCode())) {
+ throw new BuildException("could not set transfer type: "
+ + ftp.getReplyString());
+ }
+ }
+
+ if (task.isPassive()) {
+ task.log("entering passive mode", Project.MSG_VERBOSE);
+ ftp.enterLocalPassiveMode();
+ if (!FTPReply.isPositiveCompletion(ftp.getReplyCode())) {
+ throw new BuildException("could not enter into passive "
+ + "mode: " + ftp.getReplyString());
+ }
+ }
+
+ // If an initial command was configured then send it.
+ // Some FTP servers offer different modes of operation,
+ // E.G. switching between a UNIX file system mode and
+ // a legacy file system.
+ if (task.getInitialSiteCommand() != null) {
+ RetryHandler h = new RetryHandler(task.getRetriesAllowed(), task);
+ final FTPClient lftp = ftp;
+ executeRetryable(h, new Retryable() {
+ public void execute() throws IOException {
+ doSiteCommand(lftp, task.getInitialSiteCommand());
+ }
+ }, "initial site command: " + task.getInitialSiteCommand());
+ }
+
+
+ // For a unix ftp server you can set the default mask for all files
+ // created.
+
+ if (task.getUmask() != null) {
+ RetryHandler h = new RetryHandler(task.getRetriesAllowed(), task);
+ final FTPClient lftp = ftp;
+ executeRetryable(h, new Retryable() {
+ public void execute() throws IOException {
+ doSiteCommand(lftp, "umask " + task.getUmask());
+ }
+ }, "umask " + task.getUmask());
+ }
+
+ // If the action is MK_DIR, then the specified remote
+ // directory is the directory to create.
+
+ if (task.getAction() == FTPTask.MK_DIR) {
+ RetryHandler h = new RetryHandler(task.getRetriesAllowed(), task);
+ final FTPClient lftp = ftp;
+ executeRetryable(h, new Retryable() {
+ public void execute() throws IOException {
+ makeRemoteDir(lftp, task.getRemotedir());
+ }
+ }, task.getRemotedir());
+ } else if (task.getAction() == FTPTask.SITE_CMD) {
+ RetryHandler h = new RetryHandler(task.getRetriesAllowed(), task);
+ final FTPClient lftp = ftp;
+ executeRetryable(h, new Retryable() {
+ public void execute() throws IOException {
+ doSiteCommand(lftp, task.getSiteCommand());
+ }
+ }, "Site Command: " + task.getSiteCommand());
+ } else {
+ if (task.getRemotedir() != null) {
+ task.log("changing the remote directory", Project.MSG_VERBOSE);
+ ftp.changeWorkingDirectory(task.getRemotedir());
+ if (!FTPReply.isPositiveCompletion(ftp.getReplyCode())) {
+ throw new BuildException("could not change remote "
+ + "directory: " + ftp.getReplyString());
+ }
+ }
+ if (task.isNewer() && task.isTimeDiffAuto()) {
+ // in this case we want to find how much time span there is between local
+ // and remote
+ task.setTimeDiffMillis(getTimeDiff(ftp));
+ }
+ task.log(FTPTask.ACTION_STRS[task.getAction()] + " " + FTPTask.ACTION_TARGET_STRS[task.getAction()]);
+ transferFiles(ftp);
+ }
+
+ } catch (IOException ex) {
+ throw new BuildException("error during FTP transfer: " + ex, ex);
+ } finally {
+ if (ftp != null && ftp.isConnected()) {
+ try {
+ task.log("disconnecting", Project.MSG_VERBOSE);
+ ftp.logout();
+ ftp.disconnect();
+ } catch (IOException ex) {
+ // ignore it
+ }
+ }
+ }
+ }
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/net/MimeMail.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/net/MimeMail.java
new file mode 100644
index 00000000..fca4215e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/net/MimeMail.java
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.net;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.taskdefs.email.EmailTask;
+
+/**
+ * A task to send SMTP email; Use <tt>mail</tt> instead
+ *
+ * @deprecated since 1.6.x.
+ * Use {@link EmailTask} instead.
+ *
+ * @since Ant1.4
+ */
+public class MimeMail extends EmailTask {
+ /**
+ * Executes this build task.
+ *
+ * @exception BuildException On error.
+ */
+ public void execute()
+ throws BuildException {
+ log("DEPRECATED - The " + getTaskName() + " task is deprecated. "
+ + "Use the mail task instead.");
+ super.execute();
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/net/RExecTask.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/net/RExecTask.java
new file mode 100644
index 00000000..01cb4ba9
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/net/RExecTask.java
@@ -0,0 +1,479 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.net;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Calendar;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import org.apache.commons.net.bsd.RExecClient;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+
+/**
+ * Automates the rexec protocol.
+ *
+ * @since Ant 1.6
+ */
+
+public class RExecTask extends Task {
+
+ private static final int PAUSE_TIME = 250;
+
+ /**
+ * The userid to login with, if automated login is used
+ */
+ private String userid = null;
+
+ /**
+ * The password to login with, if automated login is used
+ */
+ private String password = null;
+
+ /**
+ * The command to execute
+ */
+ private String command = null;
+
+ /**
+ * The server to connect to.
+ */
+ private String server = null;
+
+ /**
+ * The tcp port to connect to.
+ */
+ private int port = RExecClient.DEFAULT_PORT;
+
+ /**
+ * The list of read/write commands for this session
+ */
+ private Vector rexecTasks = new Vector();
+
+ /**
+ * If true, adds a CR to beginning of login script
+ */
+ private boolean addCarriageReturn = false;
+
+ /**
+ * Default time allowed for waiting for a valid response
+ * for all child reads. A value of 0 means no limit.
+ */
+ private Integer defaultTimeout = null;
+
+ /**
+ * This class is the parent of the Read and Write tasks.
+ * It handles the common attributes for both.
+ */
+ public class RExecSubTask {
+ // CheckStyle:VisibilityModifier OFF - bc
+ protected String taskString = "";
+ // CheckStyle:VisibilityModifier ON
+
+ /**
+ * Execute the subtask.
+ * @param rexec the client
+ * @throws BuildException always as it is not allowed to instantiate this object
+ */
+ public void execute(AntRExecClient rexec)
+ throws BuildException {
+ throw new BuildException("Shouldn't be able instantiate a SubTask directly");
+ }
+
+ /**
+ * the message as nested text
+ * @param s the nested text
+ */
+ public void addText(String s) {
+ setString(getProject().replaceProperties(s));
+ }
+
+ /**
+ * the message as an attribute
+ * @param s a <code>String</code> value
+ */
+ public void setString(String s) {
+ taskString += s;
+ }
+ }
+
+ /**
+ * Sends text to the connected server
+ */
+ public class RExecWrite extends RExecSubTask {
+ private boolean echoString = true;
+ /**
+ * Execute the write exec task.
+ * @param rexec the task to use
+ * @throws BuildException on error
+ */
+ public void execute(AntRExecClient rexec)
+ throws BuildException {
+ rexec.sendString(taskString, echoString);
+ }
+
+ /**
+ * Whether or not the message should be echoed to the log.
+ * Defaults to <code>true</code>.
+ * @param b a <code>boolean</code> value
+ */
+ public void setEcho(boolean b) {
+ echoString = b;
+ }
+ }
+
+ /**
+ * Reads the output from the connected server
+ * until the required string is found or we time out.
+ */
+ public class RExecRead extends RExecSubTask {
+ private Integer timeout = null;
+ /**
+ * Execute the read exec task.
+ * @param rexec the task to use
+ * @throws BuildException on error
+ */
+ public void execute(AntRExecClient rexec)
+ throws BuildException {
+ rexec.waitForString(taskString, timeout);
+ }
+ /**
+ * a timeout value that overrides any task wide timeout.
+ * @param i an <code>Integer</code> value
+ */
+ public void setTimeout(Integer i) {
+ this.timeout = i;
+ }
+
+ /**
+ * Sets the default timeout if none has been set already
+ * @param defaultTimeout an <code>Integer</code> value
+ * @ant.attribute ignore="true"
+ */
+ public void setDefaultTimeout(Integer defaultTimeout) {
+ if (timeout == null) {
+ timeout = defaultTimeout;
+ }
+ }
+ }
+
+ /**
+ * This class handles the abstraction of the rexec protocol.
+ * Currently it is a wrapper around <a
+ * href="http://jakarta.apache.org/commons/net/index.html">Jakarta
+ * Commons Net</a>.
+ */
+ public class AntRExecClient extends RExecClient {
+ /**
+ * Read from the rexec session until the string we are
+ * waiting for is found
+ * @param s The string to wait on
+ */
+ public void waitForString(String s) {
+ waitForString(s, null);
+ }
+
+ /**
+ * Read from the rexec session until the string we are
+ * waiting for is found or the timeout has been reached
+ * @param s The string to wait on
+ * @param timeout The maximum number of seconds to wait
+ */
+ public void waitForString(String s, Integer timeout) {
+ InputStream is = this.getInputStream();
+ try {
+ StringBuffer sb = new StringBuffer();
+ int windowStart = -s.length();
+ if (timeout == null || timeout.intValue() == 0) {
+ while (windowStart < 0
+ || !sb.substring(windowStart).equals(s)) {
+ sb.append((char) is.read());
+ windowStart++;
+ }
+ } else {
+ Calendar endTime = Calendar.getInstance();
+ endTime.add(Calendar.SECOND, timeout.intValue());
+ while (windowStart < 0
+ || !sb.substring(windowStart).equals(s)) {
+ while (Calendar.getInstance().before(endTime)
+ && is.available() == 0) {
+ Thread.sleep(PAUSE_TIME);
+ }
+ if (is.available() == 0) {
+ throw new BuildException(
+ "Response timed-out waiting for \"" + s + '\"',
+ getLocation());
+ }
+ sb.append((char) is.read());
+ windowStart++;
+ }
+ }
+ log(sb.toString(), Project.MSG_INFO);
+ } catch (BuildException be) {
+ throw be;
+ } catch (Exception e) {
+ throw new BuildException(e, getLocation());
+ }
+ }
+
+ /**
+ * Write this string to the rexec session.
+ * @param s the string to write
+ * @param echoString if true log the string sent
+ */
+ public void sendString(String s, boolean echoString) {
+ OutputStream os = this.getOutputStream();
+ try {
+ os.write((s + "\n").getBytes());
+ if (echoString) {
+ log(s, Project.MSG_INFO);
+ }
+ os.flush();
+ } catch (Exception e) {
+ throw new BuildException(e, getLocation());
+ }
+ }
+ /**
+ * Read from the rexec session until the EOF is found or
+ * the timeout has been reached
+ * @param timeout The maximum number of seconds to wait
+ */
+ public void waitForEOF(Integer timeout) {
+ InputStream is = this.getInputStream();
+ try {
+ StringBuffer sb = new StringBuffer();
+ if (timeout == null || timeout.intValue() == 0) {
+ int read;
+ while ((read = is.read()) != -1) {
+ char c = (char) read;
+ sb.append(c);
+ if (c == '\n') {
+ log(sb.toString(), Project.MSG_INFO);
+ sb.delete(0, sb.length());
+ }
+ }
+ } else {
+ Calendar endTime = Calendar.getInstance();
+ endTime.add(Calendar.SECOND, timeout.intValue());
+ int read = 0;
+ while (read != -1) {
+ while (Calendar.getInstance().before(endTime) && is.available() == 0) {
+ Thread.sleep(PAUSE_TIME);
+ }
+ if (is.available() == 0) {
+ log(sb.toString(), Project.MSG_INFO);
+ throw new BuildException(
+ "Response timed-out waiting for EOF",
+ getLocation());
+ }
+ read = is.read();
+ if (read != -1) {
+ char c = (char) read;
+ sb.append(c);
+ if (c == '\n') {
+ log(sb.toString(), Project.MSG_INFO);
+ sb.delete(0, sb.length());
+ }
+ }
+ }
+ }
+ if (sb.length() > 0) {
+ log(sb.toString(), Project.MSG_INFO);
+ }
+ } catch (BuildException be) {
+ throw be;
+ } catch (Exception e) {
+ throw new BuildException(e, getLocation());
+ }
+ }
+
+ }
+ /**
+ * A string to wait for from the server.
+ * A subTask &lt;read&gt; tag was found. Create the object,
+ * Save it in our list, and return it.
+ * @return a read sub task
+ */
+
+ public RExecSubTask createRead() {
+ RExecSubTask task = (RExecSubTask) new RExecRead();
+ rexecTasks.addElement(task);
+ return task;
+ }
+ /**
+ * Add text to send to the server
+ * A subTask &lt;write&gt; tag was found. Create the object,
+ * Save it in our list, and return it.
+ * @return a write sub task
+ */
+ public RExecSubTask createWrite() {
+ RExecSubTask task = (RExecSubTask) new RExecWrite();
+ rexecTasks.addElement(task);
+ return task;
+ }
+ /**
+ * Verify that all parameters are included.
+ * Connect and possibly login.
+ * Iterate through the list of Reads and writes.
+ * @throws BuildException on error
+ */
+ public void execute() throws BuildException {
+ /** A server name is required to continue */
+ if (server == null) {
+ throw new BuildException("No Server Specified");
+ }
+ /** A userid and password must appear together
+ * if they appear. They are not required.
+ */
+ if (userid == null && password != null) {
+ throw new BuildException("No Userid Specified");
+ }
+ if (password == null && userid != null) {
+ throw new BuildException("No Password Specified");
+ }
+
+ /** Create the telnet client object */
+ AntRExecClient rexec = null;
+ try {
+ rexec = new AntRExecClient();
+ try {
+ rexec.connect(server, port);
+ } catch (IOException e) {
+ throw new BuildException("Can't connect to " + server);
+ }
+ if (userid != null && password != null && command != null
+ && rexecTasks.size() == 0) {
+ // simple one-shot execution
+ rexec.rexec(userid, password, command);
+ } else {
+ // need nested read/write elements
+ handleMultipleTasks(rexec);
+ }
+
+ /** Keep reading input stream until end of it or time-out */
+ rexec.waitForEOF(defaultTimeout);
+ } catch (IOException e) {
+ throw new BuildException("Error r-executing command", e);
+ } finally {
+ if (rexec != null && rexec.isConnected()) {
+ try {
+ rexec.disconnect();
+ } catch (IOException e) {
+ throw new BuildException("Error disconnecting from "
+ + server);
+ }
+ }
+ }
+ }
+ /**
+ * Process a 'typical' login. If it differs, use the read
+ * and write tasks explicitly
+ */
+ private void login(AntRExecClient rexec) {
+ if (addCarriageReturn) {
+ rexec.sendString("\n", true);
+ }
+ rexec.waitForString("ogin:");
+ rexec.sendString(userid, true);
+ rexec.waitForString("assword:");
+ rexec.sendString(password, false);
+ }
+ /**
+ * Set the the command to execute on the server;
+ * @param c a <code>String</code> value
+ */
+ public void setCommand(String c) {
+ this.command = c;
+ }
+
+ /**
+ * send a carriage return after connecting; optional, defaults to false.
+ * @param b a <code>boolean</code> value
+ */
+ public void setInitialCR(boolean b) {
+ this.addCarriageReturn = b;
+ }
+ /**
+ * Set the the login password to use
+ * required if <tt>userid</tt> is set.
+ * @param p a <code>String</code> value
+ */
+ public void setPassword(String p) {
+ this.password = p;
+ }
+
+ /**
+ * Set the tcp port to connect to; default is 23.
+ * @param p an <code>int</code> value
+ */
+ public void setPort(int p) {
+ this.port = p;
+ }
+
+ /**
+ * Set the hostname or address of the remote server.
+ * @param m a <code>String</code> value
+ */
+ public void setServer(String m) {
+ this.server = m;
+ }
+
+ /**
+ * set a default timeout in seconds to wait for a response,
+ * zero means forever (the default)
+ * @param i an <code>Integer</code> value
+ */
+ public void setTimeout(Integer i) {
+ this.defaultTimeout = i;
+ }
+ /**
+ * Set the the login id to use on the server;
+ * required if <tt>password</tt> is set.
+ * @param u a <code>String</code> value
+ */
+ public void setUserid(String u) {
+ this.userid = u;
+ }
+
+ /**
+ * Deals with multiple read/write calls.
+ *
+ * @since Ant 1.6.3
+ */
+ private void handleMultipleTasks(AntRExecClient rexec) {
+
+ /** Login if userid and password were specified */
+ if (userid != null && password != null) {
+ login(rexec);
+ }
+ /** Process each sub command */
+ Enumeration tasksToRun = rexecTasks.elements();
+ while (tasksToRun != null && tasksToRun.hasMoreElements()) {
+ RExecSubTask task = (RExecSubTask) tasksToRun.nextElement();
+ if (task instanceof RExecRead && defaultTimeout != null) {
+ ((RExecRead) task).setDefaultTimeout(defaultTimeout);
+ }
+ task.execute(rexec);
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/net/SetProxy.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/net/SetProxy.java
new file mode 100644
index 00000000..1e1f6591
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/net/SetProxy.java
@@ -0,0 +1,283 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.net;
+
+import java.net.Authenticator;
+import java.net.PasswordAuthentication;
+import java.util.Properties;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.util.ProxySetup;
+
+/**
+ * Sets Java's web proxy properties, so that tasks and code run in
+ * the same JVM can have through-the-firewall access to remote web sites,
+ * and remote ftp sites.
+ * You can nominate an http and ftp proxy, or a socks server, reset the server
+ * settings, or do nothing at all.
+ * <p>
+ * Examples
+ * <pre>&lt;setproxy/&gt;</pre>
+ * do nothing
+ * <pre>&lt;setproxy proxyhost="firewall"/&gt;</pre>
+ * set the proxy to firewall:80
+ * <pre>&lt;setproxy proxyhost="firewall" proxyport="81"/&gt;</pre>
+ * set the proxy to firewall:81
+ * <pre>&lt;setproxy proxyhost=""/&gt;</pre>
+ * stop using the http proxy; don't change the socks settings
+ * <pre>&lt;setproxy socksproxyhost="socksy"/&gt;</pre>
+ * use socks via socksy:1080
+ * <pre>&lt;setproxy socksproxyhost=""/&gt;</pre>
+ * stop using the socks server.
+ * <p>
+ * You can set a username and password for http with the <tt>proxyHost</tt>
+ * and <tt>proxyPassword</tt> attributes. These can also be
+ * used against SOCKS5 servers.
+ * </p>
+ * @see <a href="http://java.sun.com/j2se/1.5.0/docs/guide/net/properties.html">
+ * java 1.5 network property list</a>
+ *@since Ant 1.5
+ * @ant.task category="network"
+ */
+public class SetProxy extends Task {
+ private static final int HTTP_PORT = 80;
+ private static final int SOCKS_PORT = 1080;
+ // CheckStyle:VisibilityModifier OFF - bc
+ /**
+ * proxy details
+ */
+ protected String proxyHost = null;
+
+ /**
+ * name of proxy port
+ */
+ protected int proxyPort = HTTP_PORT;
+
+ // CheckStyle:VisibilityModifier ON
+
+ /**
+ * socks host.
+ */
+ private String socksProxyHost = null;
+
+ /**
+ * Socks proxy port. Default is 1080.
+ */
+ private int socksProxyPort = SOCKS_PORT;
+
+
+ /**
+ * list of non proxy hosts
+ */
+ private String nonProxyHosts = null;
+
+ /**
+ * user for http only
+ */
+ private String proxyUser = null;
+
+ /**
+ * password for http only
+ */
+ private String proxyPassword = null;
+
+ /**
+ * the HTTP/ftp proxy host. Set this to "" for the http proxy
+ * option to be disabled
+ *
+ * @param hostname the new proxy hostname
+ */
+ public void setProxyHost(String hostname) {
+ proxyHost = hostname;
+ }
+
+
+ /**
+ * the HTTP/ftp proxy port number; default is 80
+ *
+ * @param port port number of the proxy
+ */
+ public void setProxyPort(int port) {
+ proxyPort = port;
+ }
+
+ /**
+ * The name of a Socks server. Set to "" to turn socks
+ * proxying off.
+ *
+ * @param host The new SocksProxyHost value
+ */
+ public void setSocksProxyHost(String host) {
+ this.socksProxyHost = host;
+ }
+
+
+ /**
+ * Set the ProxyPort for socks connections. The default value is 1080
+ *
+ * @param port The new SocksProxyPort value
+ */
+ public void setSocksProxyPort(int port) {
+ this.socksProxyPort = port;
+ }
+
+
+ /**
+ * A list of hosts to bypass the proxy on. These should be separated
+ * with the vertical bar character '|'. Only in Java 1.4 does ftp use
+ * this list.
+ * e.g. fozbot.corp.sun.com|*.eng.sun.com
+ * @param nonProxyHosts lists of hosts to talk direct to
+ */
+ public void setNonProxyHosts(String nonProxyHosts) {
+ this.nonProxyHosts = nonProxyHosts;
+ }
+
+ /**
+ * set the proxy user. Probably requires a password to accompany this
+ * setting. Default=""
+ * @param proxyUser username
+ * @since Ant1.6
+ */
+ public void setProxyUser(String proxyUser) {
+ this.proxyUser = proxyUser;
+ }
+
+ /**
+ * Set the password for the proxy. Used only if the proxyUser is set.
+ * @param proxyPassword password to go with the username
+ * @since Ant1.6
+ */
+ public void setProxyPassword(String proxyPassword) {
+ this.proxyPassword = proxyPassword;
+ }
+
+ /**
+ * if the proxy port and host settings are not null, then the settings
+ * get applied these settings last beyond the life of the object and
+ * apply to all network connections
+ * Relevant docs: buglist #4183340
+ */
+
+ public void applyWebProxySettings() {
+ boolean settingsChanged = false;
+ boolean enablingProxy = false;
+ Properties sysprops = System.getProperties();
+ if (proxyHost != null) {
+ settingsChanged = true;
+ if (proxyHost.length() != 0) {
+ traceSettingInfo();
+ enablingProxy = true;
+ sysprops.put(ProxySetup.HTTP_PROXY_HOST, proxyHost);
+ String portString = Integer.toString(proxyPort);
+ sysprops.put(ProxySetup.HTTP_PROXY_PORT, portString);
+ sysprops.put(ProxySetup.HTTPS_PROXY_HOST, proxyHost);
+ sysprops.put(ProxySetup.HTTPS_PROXY_PORT, portString);
+ sysprops.put(ProxySetup.FTP_PROXY_HOST, proxyHost);
+ sysprops.put(ProxySetup.FTP_PROXY_PORT, portString);
+ if (nonProxyHosts != null) {
+ sysprops.put(ProxySetup.HTTP_NON_PROXY_HOSTS, nonProxyHosts);
+ sysprops.put(ProxySetup.HTTPS_NON_PROXY_HOSTS, nonProxyHosts);
+ sysprops.put(ProxySetup.FTP_NON_PROXY_HOSTS, nonProxyHosts);
+ }
+ if (proxyUser != null) {
+ sysprops.put(ProxySetup.HTTP_PROXY_USERNAME, proxyUser);
+ sysprops.put(ProxySetup.HTTP_PROXY_PASSWORD, proxyPassword);
+ }
+ } else {
+ log("resetting http proxy", Project.MSG_VERBOSE);
+ sysprops.remove(ProxySetup.HTTP_PROXY_HOST);
+ sysprops.remove(ProxySetup.HTTP_PROXY_PORT);
+ sysprops.remove(ProxySetup.HTTP_PROXY_USERNAME);
+ sysprops.remove(ProxySetup.HTTP_PROXY_PASSWORD);
+ sysprops.remove(ProxySetup.HTTPS_PROXY_HOST);
+ sysprops.remove(ProxySetup.HTTPS_PROXY_PORT);
+ sysprops.remove(ProxySetup.FTP_PROXY_HOST);
+ sysprops.remove(ProxySetup.FTP_PROXY_PORT);
+ }
+ }
+
+ //socks
+ if (socksProxyHost != null) {
+ settingsChanged = true;
+ if (socksProxyHost.length() != 0) {
+ enablingProxy = true;
+ sysprops.put(ProxySetup.SOCKS_PROXY_HOST, socksProxyHost);
+ sysprops.put(ProxySetup.SOCKS_PROXY_PORT, Integer.toString(socksProxyPort));
+ if (proxyUser != null) {
+ //this may be a java1.4 thingy only
+ sysprops.put(ProxySetup.SOCKS_PROXY_USERNAME, proxyUser);
+ sysprops.put(ProxySetup.SOCKS_PROXY_PASSWORD, proxyPassword);
+ }
+
+ } else {
+ log("resetting socks proxy", Project.MSG_VERBOSE);
+ sysprops.remove(ProxySetup.SOCKS_PROXY_HOST);
+ sysprops.remove(ProxySetup.SOCKS_PROXY_PORT);
+ sysprops.remove(ProxySetup.SOCKS_PROXY_USERNAME);
+ sysprops.remove(ProxySetup.SOCKS_PROXY_PASSWORD);
+ }
+ }
+
+ if (proxyUser != null) {
+ if (enablingProxy) {
+ Authenticator.setDefault(new ProxyAuth(proxyUser,
+ proxyPassword));
+ } else if (settingsChanged) {
+ Authenticator.setDefault(new ProxyAuth("", ""));
+ }
+ }
+ }
+
+ /**
+ * list out what is going on
+ */
+ private void traceSettingInfo() {
+ log("Setting proxy to "
+ + (proxyHost != null ? proxyHost : "''")
+ + ":" + proxyPort,
+ Project.MSG_VERBOSE);
+ }
+
+ /**
+ * Does the work.
+ *
+ * @exception BuildException thrown in unrecoverable error.
+ */
+ public void execute() throws BuildException {
+ applyWebProxySettings();
+ }
+
+ /**
+ * @since 1.6.3
+ */
+ private static final class ProxyAuth extends Authenticator {
+ private PasswordAuthentication auth;
+
+ private ProxyAuth(String user, String pass) {
+ auth = new PasswordAuthentication(user, pass.toCharArray());
+ }
+
+ protected PasswordAuthentication getPasswordAuthentication() {
+ return auth;
+ }
+ }
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/net/TelnetTask.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/net/TelnetTask.java
new file mode 100644
index 00000000..82625fa7
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/net/TelnetTask.java
@@ -0,0 +1,397 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.net;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Calendar;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import org.apache.commons.net.telnet.TelnetClient;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+
+/**
+ * Automates the telnet protocol.
+ *
+ */
+
+public class TelnetTask extends Task {
+ private static final int WAIT_INTERVAL = 250;
+ private static final int TELNET_PORT = 23;
+
+ /**
+ * The userid to login with, if automated login is used
+ */
+ private String userid = null;
+
+ /**
+ * The password to login with, if automated login is used
+ */
+ private String password = null;
+
+ /**
+ * The server to connect to.
+ */
+ private String server = null;
+
+ /**
+ * The tcp port to connect to.
+ */
+ private int port = TELNET_PORT;
+
+ /**
+ * The list of read/write commands for this session
+ */
+ private Vector telnetTasks = new Vector();
+
+ /**
+ * If true, adds a CR to beginning of login script
+ */
+ private boolean addCarriageReturn = false;
+
+ /**
+ * Default time allowed for waiting for a valid response
+ * for all child reads. A value of 0 means no limit.
+ */
+ private Integer defaultTimeout = null;
+
+ /**
+ * Verify that all parameters are included.
+ * Connect and possibly login
+ * Iterate through the list of Reads and writes
+ * @throws BuildException on error
+ */
+ public void execute() throws BuildException {
+ /** A server name is required to continue */
+ if (server == null) {
+ throw new BuildException("No Server Specified");
+ }
+ /** A userid and password must appear together
+ * if they appear. They are not required.
+ */
+ if (userid == null && password != null) {
+ throw new BuildException("No Userid Specified");
+ }
+ if (password == null && userid != null) {
+ throw new BuildException("No Password Specified");
+ }
+
+ /** Create the telnet client object */
+ AntTelnetClient telnet = null;
+ try {
+ telnet = new AntTelnetClient();
+ try {
+ telnet.connect(server, port);
+ } catch (IOException e) {
+ throw new BuildException("Can't connect to " + server);
+ }
+ /** Login if userid and password were specified */
+ if (userid != null && password != null) {
+ login(telnet);
+ }
+ /** Process each sub command */
+ Enumeration tasksToRun = telnetTasks.elements();
+ while (tasksToRun != null && tasksToRun.hasMoreElements()) {
+ TelnetSubTask task = (TelnetSubTask) tasksToRun.nextElement();
+ if (task instanceof TelnetRead && defaultTimeout != null) {
+ ((TelnetRead) task).setDefaultTimeout(defaultTimeout);
+ }
+ task.execute(telnet);
+ }
+ } finally {
+ if (telnet != null && telnet.isConnected()) {
+ try {
+ telnet.disconnect();
+ } catch (IOException e) {
+ throw new BuildException("Error disconnecting from "
+ + server);
+ }
+ }
+ }
+ }
+
+ /**
+ * Process a 'typical' login. If it differs, use the read
+ * and write tasks explicitly
+ */
+ private void login(AntTelnetClient telnet) {
+ if (addCarriageReturn) {
+ telnet.sendString("\n", true);
+ }
+ telnet.waitForString("ogin:");
+ telnet.sendString(userid, true);
+ telnet.waitForString("assword:");
+ telnet.sendString(password, false);
+ }
+
+ /**
+ * Set the the login id to use on the server;
+ * required if <tt>password</tt> is set.
+ * @param u a <code>String</code> value
+ */
+ public void setUserid(String u) {
+ this.userid = u;
+ }
+
+ /**
+ * Set the the login password to use
+ * required if <tt>userid</tt> is set.
+ * @param p a <code>String</code> value
+ */
+ public void setPassword(String p) {
+ this.password = p;
+ }
+
+ /**
+ * Set the hostname or address of the remote server.
+ * @param m a <code>String</code> value
+ */
+ public void setServer(String m) {
+ this.server = m;
+ }
+
+ /**
+ * Set the tcp port to connect to; default is 23.
+ * @param p an <code>int</code> value
+ */
+ public void setPort(int p) {
+ this.port = p;
+ }
+
+ /**
+ * send a carriage return after connecting; optional, defaults to false.
+ * @param b a <code>boolean</code> value
+ */
+ public void setInitialCR(boolean b) {
+ this.addCarriageReturn = b;
+ }
+
+ /**
+ * set a default timeout in seconds to wait for a response,
+ * zero means forever (the default)
+ * @param i an <code>Integer</code> value
+ */
+ public void setTimeout(Integer i) {
+ this.defaultTimeout = i;
+ }
+
+ /**
+ * A string to wait for from the server.
+ * A subTask &lt;read&gt; tag was found. Create the object,
+ * Save it in our list, and return it.
+ * @return a read telnet sub task
+ */
+
+ public TelnetSubTask createRead() {
+ TelnetSubTask task = (TelnetSubTask) new TelnetRead();
+ telnetTasks.addElement(task);
+ return task;
+ }
+
+ /**
+ * Add text to send to the server
+ * A subTask &lt;write&gt; tag was found. Create the object,
+ * Save it in our list, and return it.
+ * @return a write telnet sub task
+ */
+ public TelnetSubTask createWrite() {
+ TelnetSubTask task = (TelnetSubTask) new TelnetWrite();
+ telnetTasks.addElement(task);
+ return task;
+ }
+
+ /**
+ * This class is the parent of the Read and Write tasks.
+ * It handles the common attributes for both.
+ */
+ public class TelnetSubTask {
+ // CheckStyle:VisibilityModifier OFF - bc
+ protected String taskString = "";
+ // CheckStyle:VisibilityModifier ON
+ /**
+ * Execute the subtask.
+ * @param telnet the client
+ * @throws BuildException always as it is not allowed to instantiate this object
+ */
+ public void execute(AntTelnetClient telnet)
+ throws BuildException {
+ throw new BuildException("Shouldn't be able instantiate a SubTask directly");
+ }
+
+ /**
+ * the message as nested text
+ * @param s the nested text
+ */
+ public void addText(String s) {
+ setString(getProject().replaceProperties(s));
+ }
+
+ /**
+ * the message as an attribute
+ * @param s a <code>String</code> value
+ */
+ public void setString(String s) {
+ taskString += s;
+ }
+ }
+
+ /**
+ * Sends text to the connected server
+ */
+ public class TelnetWrite extends TelnetSubTask {
+ private boolean echoString = true;
+ /**
+ * Execute the write task.
+ * @param telnet the task to use
+ * @throws BuildException on error
+ */
+ public void execute(AntTelnetClient telnet)
+ throws BuildException {
+ telnet.sendString(taskString, echoString);
+ }
+
+ /**
+ * Whether or not the message should be echoed to the log.
+ * Defaults to <code>true</code>.
+ * @param b a <code>boolean</code> value
+ */
+ public void setEcho(boolean b) {
+ echoString = b;
+ }
+ }
+
+ /**
+ * Reads the output from the connected server
+ * until the required string is found or we time out.
+ */
+ public class TelnetRead extends TelnetSubTask {
+ private Integer timeout = null;
+ /**
+ * Execute the read task.
+ * @param telnet the task to use
+ * @throws BuildException on error
+ */
+ public void execute(AntTelnetClient telnet)
+ throws BuildException {
+ telnet.waitForString(taskString, timeout);
+ }
+ /**
+ * a timeout value that overrides any task wide timeout.
+ * @param i an <code>Integer</code> value
+ */
+ public void setTimeout(Integer i) {
+ this.timeout = i;
+ }
+
+ /**
+ * Sets the default timeout if none has been set already
+ * @param defaultTimeout an <code>Integer</code> value
+ * @ant.attribute ignore="true"
+ */
+ public void setDefaultTimeout(Integer defaultTimeout) {
+ if (timeout == null) {
+ timeout = defaultTimeout;
+ }
+ }
+ }
+
+ /**
+ * This class handles the abstraction of the telnet protocol.
+ * Currently it is a wrapper around <a
+ * href="http://jakarta.apache.org/commons/net/index.html">Jakarta
+ * Commons Net</a>.
+ */
+ public class AntTelnetClient extends TelnetClient {
+ /**
+ * Read from the telnet session until the string we are
+ * waiting for is found
+ * @param s The string to wait on
+ */
+ public void waitForString(String s) {
+ waitForString(s, null);
+ }
+
+ /**
+ * Read from the telnet session until the string we are
+ * waiting for is found or the timeout has been reached
+ * @param s The string to wait on
+ * @param timeout The maximum number of seconds to wait
+ */
+ public void waitForString(String s, Integer timeout) {
+ InputStream is = this.getInputStream();
+ try {
+ StringBuffer sb = new StringBuffer();
+ int windowStart = -s.length();
+ if (timeout == null || timeout.intValue() == 0) {
+ while (windowStart < 0
+ || !sb.substring(windowStart).equals(s)) {
+ sb.append((char) is.read());
+ windowStart++;
+ }
+ } else {
+ Calendar endTime = Calendar.getInstance();
+ endTime.add(Calendar.SECOND, timeout.intValue());
+ while (windowStart < 0
+ || !sb.substring(windowStart).equals(s)) {
+ while (Calendar.getInstance().before(endTime)
+ && is.available() == 0) {
+ Thread.sleep(WAIT_INTERVAL);
+ }
+ if (is.available() == 0) {
+ log("Read before running into timeout: "
+ + sb.toString(), Project.MSG_DEBUG);
+ throw new BuildException(
+ "Response timed-out waiting for \"" + s + '\"',
+ getLocation());
+ }
+ sb.append((char) is.read());
+ windowStart++;
+ }
+ }
+ log(sb.toString(), Project.MSG_INFO);
+ } catch (BuildException be) {
+ throw be;
+ } catch (Exception e) {
+ throw new BuildException(e, getLocation());
+ }
+ }
+
+ /**
+ * Write this string to the telnet session.
+ * @param s the string to write
+ * @param echoString if true log the string sent
+ */
+ public void sendString(String s, boolean echoString) {
+ OutputStream os = this.getOutputStream();
+ try {
+ os.write((s + "\n").getBytes());
+ if (echoString) {
+ log(s, Project.MSG_INFO);
+ }
+ os.flush();
+ } catch (Exception e) {
+ throw new BuildException(e, getLocation());
+ }
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/pvcs/Pvcs.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/pvcs/Pvcs.java
new file mode 100644
index 00000000..dd6016a8
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/pvcs/Pvcs.java
@@ -0,0 +1,675 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.pvcs;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.text.MessageFormat;
+import java.text.ParseException;
+import java.util.Enumeration;
+import java.util.Random;
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.Execute;
+import org.apache.tools.ant.taskdefs.ExecuteStreamHandler;
+import org.apache.tools.ant.taskdefs.LogOutputStream;
+import org.apache.tools.ant.taskdefs.LogStreamHandler;
+import org.apache.tools.ant.taskdefs.PumpStreamHandler;
+import org.apache.tools.ant.types.Commandline;
+import org.apache.tools.ant.util.FileUtils;
+
+/**
+ *
+ * Extracts the latest edition of the source code from a PVCS repository.
+ * PVCS is a version control system
+ * developed by <a href="http://www.merant.com/products/pvcs">Merant</a>.
+ * <br>
+ * Before using this tag, the user running ant must have access to the commands
+ * of PVCS (get and pcli) and must have access to the repository. Note that the way to specify
+ * the repository is platform dependent so use property to specify location of repository.
+ * <br>
+ * This version has been tested against PVCS version 6.5 and 6.6 under Windows and Solaris.
+
+ *
+ * <b>19-04-2001</b> <p>The task now has a more robust
+ * parser. It allows for platform independent file paths
+ * and supports file names with <i>()</i>. Thanks to Erik Husby for
+ * bringing the bug to my attention.
+ *
+ * <b>27-04-2001</b> <p>UNC paths are now handled properly.
+ * Fix provided by Don Jeffery. He also added an <i>UpdateOnly</i> flag
+ * that, when true, conditions the PVCS get using the -U option to only
+ * update those files that have a modification time (in PVCS) that is newer
+ * than the existing workfile.
+ *
+ * <b>25-10-2002</b> <p>Added a revision attribute that currently is a
+ * synonym for label, but in a future release the behavior of the label
+ * attribute will change to use the -v option of GET. See bug #13847 for
+ * discussion.
+ *
+ */
+public class Pvcs extends org.apache.tools.ant.Task {
+ // CheckStyle - magic numbers
+ // checking for "X:\ 0=dquote,1=letter,2=:,3=\
+ private static final int POS_1 = 1;
+ private static final int POS_2 = 2;
+ private static final int POS_3 = 3;
+
+ private String pvcsbin;
+ private String repository;
+ private String pvcsProject;
+ private Vector pvcsProjects;
+ private String workspace;
+ private String force;
+ private String promotiongroup;
+ private String label;
+ private String revision;
+ private boolean ignorerc;
+ private boolean updateOnly;
+ private String filenameFormat;
+ private String lineStart;
+ private String userId;
+ private String config;
+ /**
+ * Constant for the thing to execute
+ */
+ private static final String PCLI_EXE = "pcli";
+
+ /*
+ * Constant for the PCLI listversionedfiles recursive i a format "get" understands
+ */
+ // private static final String PCLI_LVF_ARGS = "lvf -z -aw";
+
+ /**
+ * Constant for the thing to execute
+ */
+ private static final String GET_EXE = "get";
+
+
+ /**
+ * Run the command.
+ * @param cmd the command line to use.
+ * @param out the output stream handler to use.
+ * @return the exit code of the command.
+ */
+ protected int runCmd(Commandline cmd, ExecuteStreamHandler out) {
+ try {
+ Project aProj = getProject();
+ Execute exe = new Execute(out);
+ exe.setAntRun(aProj);
+ exe.setWorkingDirectory(aProj.getBaseDir());
+ exe.setCommandline(cmd.getCommandline());
+ return exe.execute();
+ } catch (java.io.IOException e) {
+ String msg = "Failed executing: " + cmd.toString()
+ + ". Exception: " + e.getMessage();
+ throw new BuildException(msg, getLocation());
+ }
+ }
+
+ private String getExecutable(String exe) {
+ StringBuffer correctedExe = new StringBuffer();
+ if (getPvcsbin() != null) {
+ if (pvcsbin.endsWith(File.separator)) {
+ correctedExe.append(pvcsbin);
+ } else {
+ correctedExe.append(pvcsbin).append(File.separator);
+ }
+ }
+ return correctedExe.append(exe).toString();
+ }
+
+ /**
+ * @exception org.apache.tools.ant.BuildException Something is stopping the build...
+ */
+ public void execute() throws org.apache.tools.ant.BuildException {
+ int result = 0;
+
+ if (repository == null || repository.trim().equals("")) {
+ throw new BuildException("Required argument repository not specified");
+ }
+
+ // Check workspace exists
+ // Launch PCLI listversionedfiles -z -aw
+ // Capture output
+ // build the command line from what we got the format is
+ Commandline commandLine = new Commandline();
+ commandLine.setExecutable(getExecutable(PCLI_EXE));
+
+ commandLine.createArgument().setValue("lvf");
+ commandLine.createArgument().setValue("-z");
+ commandLine.createArgument().setValue("-aw");
+ if (getWorkspace() != null) {
+ commandLine.createArgument().setValue("-sp" + getWorkspace());
+ }
+ commandLine.createArgument().setValue("-pr" + getRepository());
+
+ String uid = getUserId();
+
+ if (uid != null) {
+ commandLine.createArgument().setValue("-id" + uid);
+ }
+
+ // default pvcs project is "/"
+ if (getPvcsproject() == null && getPvcsprojects().isEmpty()) {
+ pvcsProject = "/";
+ }
+
+ if (getPvcsproject() != null) {
+ commandLine.createArgument().setValue(getPvcsproject());
+ }
+ if (!getPvcsprojects().isEmpty()) {
+ Enumeration e = getPvcsprojects().elements();
+ while (e.hasMoreElements()) {
+ String projectName = ((PvcsProject) e.nextElement()).getName();
+ if (projectName == null || (projectName.trim()).equals("")) {
+ throw new BuildException("name is a required attribute "
+ + "of pvcsproject");
+ }
+ commandLine.createArgument().setValue(projectName);
+ }
+ }
+
+ File tmp = null;
+ File tmp2 = null;
+ try {
+ Random rand = new Random(System.currentTimeMillis());
+ tmp = new File("pvcs_ant_" + rand.nextLong() + ".log");
+ FileOutputStream fos = new FileOutputStream(tmp);
+ tmp2 = new File("pvcs_ant_" + rand.nextLong() + ".log");
+ log(commandLine.describeCommand(), Project.MSG_VERBOSE);
+ try {
+ result = runCmd(commandLine,
+ new PumpStreamHandler(fos,
+ new LogOutputStream(this,
+ Project.MSG_WARN)));
+ } finally {
+ FileUtils.close(fos);
+ }
+
+ if (Execute.isFailure(result) && !ignorerc) {
+ String msg = "Failed executing: " + commandLine.toString();
+ throw new BuildException(msg, getLocation());
+ }
+
+ if (!tmp.exists()) {
+ throw new BuildException("Communication between ant and pvcs "
+ + "failed. No output generated from executing PVCS "
+ + "commandline interface \"pcli\" and \"get\"");
+ }
+
+ // Create folders in workspace
+ log("Creating folders", Project.MSG_INFO);
+ createFolders(tmp);
+
+ // Massage PCLI lvf output transforming '\' to '/' so get command works appropriately
+ massagePCLI(tmp, tmp2);
+
+ // Launch get on output captured from PCLI lvf
+ commandLine.clearArgs();
+ commandLine.setExecutable(getExecutable(GET_EXE));
+
+ if (getConfig() != null && getConfig().length() > 0) {
+ commandLine.createArgument().setValue("-c" + getConfig());
+ }
+
+ if (getForce() != null && getForce().equals("yes")) {
+ commandLine.createArgument().setValue("-Y");
+ } else {
+ commandLine.createArgument().setValue("-N");
+ }
+
+ if (getPromotiongroup() != null) {
+ commandLine.createArgument().setValue("-G"
+ + getPromotiongroup());
+ } else {
+ if (getLabel() != null) {
+ commandLine.createArgument().setValue("-v" + getLabel());
+ } else {
+ if (getRevision() != null) {
+ commandLine.createArgument().setValue("-r"
+ + getRevision());
+ }
+ }
+ }
+
+ if (updateOnly) {
+ commandLine.createArgument().setValue("-U");
+ }
+
+ commandLine.createArgument().setValue("@" + tmp2.getAbsolutePath());
+ log("Getting files", Project.MSG_INFO);
+ log("Executing " + commandLine.toString(), Project.MSG_VERBOSE);
+ result = runCmd(commandLine,
+ new LogStreamHandler(this, Project.MSG_INFO, Project.MSG_WARN));
+ if (result != 0 && !ignorerc) {
+ String msg = "Failed executing: " + commandLine.toString()
+ + ". Return code was " + result;
+ throw new BuildException(msg, getLocation());
+ }
+
+ } catch (FileNotFoundException e) {
+ String msg = "Failed executing: " + commandLine.toString()
+ + ". Exception: " + e.getMessage();
+ throw new BuildException(msg, getLocation());
+ } catch (IOException e) {
+ String msg = "Failed executing: " + commandLine.toString()
+ + ". Exception: " + e.getMessage();
+ throw new BuildException(msg, getLocation());
+ } catch (ParseException e) {
+ String msg = "Failed executing: " + commandLine.toString()
+ + ". Exception: " + e.getMessage();
+ throw new BuildException(msg, getLocation());
+ } finally {
+ if (tmp != null) {
+ tmp.delete();
+ }
+ if (tmp2 != null) {
+ tmp2.delete();
+ }
+ }
+ }
+
+ /**
+ * Parses the file and creates the folders specified in the output section
+ */
+ private void createFolders(File file) throws IOException, ParseException {
+ BufferedReader in = null;
+ try {
+ in = new BufferedReader(new FileReader(file));
+ MessageFormat mf = new MessageFormat(getFilenameFormat());
+ String line = in.readLine();
+ while (line != null) {
+ log("Considering \"" + line + "\"", Project.MSG_VERBOSE);
+ if (line.startsWith("\"\\") // Checking for "\
+ || line.startsWith("\"/") // or "/
+ // or "X:\...
+ || (line.length() > POS_3 && line.startsWith("\"")
+ && Character.isLetter(line.charAt(POS_1))
+ && String.valueOf(line.charAt(POS_2)).equals(":")
+ && String.valueOf(line.charAt(POS_3)).equals("\\"))) {
+ Object[] objs = mf.parse(line);
+ String f = (String) objs[1];
+ // Extract the name of the directory from the filename
+ int index = f.lastIndexOf(File.separator);
+ if (index > -1) {
+ File dir = new File(f.substring(0, index));
+ if (!dir.exists()) {
+ log("Creating " + dir.getAbsolutePath(),
+ Project.MSG_VERBOSE);
+ if (dir.mkdirs() || dir.isDirectory()) {
+ log("Created " + dir.getAbsolutePath(),
+ Project.MSG_INFO);
+ } else {
+ log("Failed to create "
+ + dir.getAbsolutePath(),
+ Project.MSG_INFO);
+ }
+ } else {
+ log(dir.getAbsolutePath() + " exists. Skipping",
+ Project.MSG_VERBOSE);
+ }
+ } else {
+ log("File separator problem with " + line,
+ Project.MSG_WARN);
+ }
+ } else {
+ log("Skipped \"" + line + "\"", Project.MSG_VERBOSE);
+ }
+ line = in.readLine();
+ }
+ } finally {
+ FileUtils.close(in);
+ }
+ }
+
+
+ /**
+ * Simple hack to handle the PVCS command-line tools botch when
+ * handling UNC notation.
+ * @throws IOException if there is an error.
+ */
+ private void massagePCLI(File in, File out)
+ throws IOException {
+ BufferedReader inReader = null;
+ BufferedWriter outWriter = null;
+ try {
+ inReader = new BufferedReader(new FileReader(in));
+ outWriter = new BufferedWriter(new FileWriter(out));
+ String s = null;
+ while ((s = inReader.readLine()) != null) {
+ String sNormal = s.replace('\\', '/');
+ outWriter.write(sNormal);
+ outWriter.newLine();
+ }
+ } finally {
+ FileUtils.close(inReader);
+ FileUtils.close(outWriter);
+ }
+ }
+
+ /**
+ * Get network name of the PVCS repository
+ * @return String
+ */
+ public String getRepository() {
+ return repository;
+ }
+
+ /**
+ * The filenameFormat attribute defines a MessageFormat string used
+ * to parse the output of the pcli command. It defaults to
+ * <code>{0}-arc({1})</code>. Repositories where the archive
+ * extension is not -arc should set this.
+ * @return the filename format attribute.
+ */
+ public String getFilenameFormat() {
+ return filenameFormat;
+ }
+
+ /**
+ * The format of the folder names; optional.
+ * This must be in a format suitable for
+ * <code>java.text.MessageFormat</code>.
+ * Index 1 of the format will be used as the file name.
+ * Defaults to <code>{0}-arc({1})</code>
+ * @param f the format to use.
+ */
+ public void setFilenameFormat(String f) {
+ filenameFormat = f;
+ }
+
+ /**
+
+ * The lineStart attribute is used to parse the output of the pcli
+ * command. It defaults to <code>&quot;P:</code>. The parser already
+ * knows about / and \\, this property is useful in cases where the
+ * repository is accessed on a Windows platform via a drive letter
+ * mapping.
+ * @return the lineStart attribute.
+ */
+ public String getLineStart() {
+ return lineStart;
+ }
+
+ /**
+ * What a valid return value from PVCS looks like
+ * when it describes a file. Defaults to <code>&quot;P:</code>.
+ * If you are not using an UNC name for your repository and the
+ * drive letter <code>P</code> is incorrect for your setup, you may
+ * need to change this value, UNC names will always be
+ * accepted.
+ * @param l the value to use.
+ */
+ public void setLineStart(String l) {
+ lineStart = l;
+ }
+
+ /**
+ * The network name of the PVCS repository; required.
+ * @param repo String
+ */
+ public void setRepository(String repo) {
+ repository = repo;
+ }
+
+ /**
+ * Get name of the project in the PVCS repository
+ * @return String
+ */
+ public String getPvcsproject() {
+ return pvcsProject;
+ }
+
+ /**
+ * The project within the PVCS repository to extract files from;
+ * optional, default &quot;/&quot;
+ * @param prj String
+ */
+ public void setPvcsproject(String prj) {
+ pvcsProject = prj;
+ }
+
+ /**
+ * Get name of the project in the PVCS repository
+ * @return Vector
+ */
+ public Vector getPvcsprojects() {
+ return pvcsProjects;
+ }
+
+ /**
+ * Get name of the workspace to store the retrieved files
+ * @return String
+ */
+ public String getWorkspace() {
+ return workspace;
+ }
+
+ /**
+ * Workspace to use; optional.
+ * By specifying a workspace, the files are extracted to that location.
+ * A PVCS workspace is a name for a location of the workfiles and
+ * isn't as such the location itself.
+ * You define the location for a workspace using the PVCS GUI clients.
+ * If this isn't specified the default workspace for the current user is used.
+ * @param ws String
+ */
+ public void setWorkspace(String ws) {
+ workspace = ws;
+ }
+
+ /**
+ * Get name of the PVCS bin directory
+ * @return String
+ */
+ public String getPvcsbin() {
+ return pvcsbin;
+ }
+
+ /**
+ * Specifies the location of the PVCS bin directory; optional if on the PATH.
+ * On some systems the PVCS executables <i>pcli</i>
+ * and <i>get</i> are not found in the PATH. In such cases this attribute
+ * should be set to the bin directory of the PVCS installation containing
+ * the executables mentioned before. If this attribute isn't specified the
+ * tag expects the executables to be found using the PATH environment variable.
+ * @param bin PVCS bin directory
+ * @todo use a File setter and resolve paths.
+ */
+ public void setPvcsbin(String bin) {
+ pvcsbin = bin;
+ }
+
+ /**
+ * Get value of force
+ * @return String
+ */
+ public String getForce() {
+ return force;
+ }
+
+ /**
+ * Specifies the value of the force argument; optional.
+ * If set to <i>yes</i> all files that exists and are
+ * writable are overwritten. Default <i>no</i> causes the files
+ * that are writable to be ignored. This stops the PVCS command
+ * <i>get</i> to stop asking questions!
+ * @todo make a boolean setter
+ * @param f String (yes/no)
+ */
+ public void setForce(String f) {
+ if (f != null && f.equalsIgnoreCase("yes")) {
+ force = "yes";
+ } else {
+ force = "no";
+ }
+ }
+
+ /**
+ * Get value of promotiongroup
+ * @return String
+ */
+ public String getPromotiongroup() {
+ return promotiongroup;
+ }
+
+ /**
+ * Specifies the name of the promotiongroup argument
+ * @param w String
+ */
+ public void setPromotiongroup(String w) {
+ promotiongroup = w;
+ }
+
+ /**
+ * Get value of label
+ * @return String
+ */
+ public String getLabel() {
+ return label;
+ }
+
+ /**
+ * Only files marked with this label are extracted; optional.
+ * @param l String
+ */
+ public void setLabel(String l) {
+ label = l;
+ }
+
+ /**
+ * Get value of revision
+ * @return String
+ */
+ public String getRevision() {
+ return revision;
+ }
+
+ /**
+ * Only files with this revision are extract; optional.
+ * @param r String
+ */
+ public void setRevision(String r) {
+ revision = r;
+ }
+
+ /**
+ * Get value of ignorereturncode
+ * @return String
+ */
+ public boolean getIgnoreReturnCode() {
+ return ignorerc;
+ }
+
+ /**
+ * If set to true the return value from executing the pvcs
+ * commands are ignored; optional, default false.
+ * @param b a <code>boolean</code> value.
+ */
+ public void setIgnoreReturnCode(boolean b) {
+ ignorerc = b;
+ }
+
+ /**
+ * Specify a project within the PVCS repository to extract files from.
+ * @param p the pvcs project to use.
+ */
+ public void addPvcsproject(PvcsProject p) {
+ pvcsProjects.addElement(p);
+ }
+
+ /**
+ * get the updateOnly attribute.
+ * @return the updateOnly attribute.
+ */
+ public boolean getUpdateOnly() {
+ return updateOnly;
+ }
+
+ /**
+ * If set to <i>true</i> files are fetched only if
+ * newer than existing local files; optional, default false.
+ * @param l a <code>boolean</code> value.
+ */
+ public void setUpdateOnly(boolean l) {
+ updateOnly = l;
+ }
+
+ /**
+ * returns the path of the configuration file to be used
+ * @return the path of the config file
+ */
+ public String getConfig() {
+ return config;
+ }
+
+ /**
+ * Sets a configuration file other than the default to be used.
+ * These files have a .cfg extension and are often found in archive or pvcsprop folders.
+ * @param f config file - can be given absolute or relative to ant basedir
+ */
+ public void setConfig(File f) {
+ config = f.toString();
+ }
+
+
+ /**
+ * Get the userid.
+ * @return the userid.
+ */
+ public String getUserId() {
+ return userId;
+ }
+
+ /**
+ * User ID
+ * @param u the value to use.
+ */
+ public void setUserId(String u) {
+ userId = u;
+ }
+
+ /**
+ * Creates a Pvcs object
+ */
+ public Pvcs() {
+ super();
+ pvcsProject = null;
+ pvcsProjects = new Vector();
+ workspace = null;
+ repository = null;
+ pvcsbin = null;
+ force = null;
+ promotiongroup = null;
+ label = null;
+ ignorerc = false;
+ updateOnly = false;
+ lineStart = "\"P:";
+ filenameFormat = "{0}-arc({1})";
+ }
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/pvcs/PvcsProject.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/pvcs/PvcsProject.java
new file mode 100644
index 00000000..a8c6a2a1
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/pvcs/PvcsProject.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.pvcs;
+
+
+
+/**
+ * represents a project within the PVCS repository to extract files from.
+ */
+public class PvcsProject {
+ private String name;
+
+ /** no arg constructor */
+ public PvcsProject() {
+ super();
+ }
+
+ /**
+ * Set the name of the project
+ * @param name the value to use.
+ */
+ public void setName(String name) {
+ PvcsProject.this.name = name;
+ }
+
+ /**
+ * Get the name of the project
+ * @return the name of the project.
+ */
+ public String getName() {
+ return name;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/script/ScriptDef.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/script/ScriptDef.java
new file mode 100644
index 00000000..ac9eb88e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/script/ScriptDef.java
@@ -0,0 +1,397 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.script;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.tools.ant.AntTypeDefinition;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.ComponentHelper;
+import org.apache.tools.ant.MagicNames;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.ProjectHelper;
+import org.apache.tools.ant.taskdefs.DefBase;
+import org.apache.tools.ant.types.ResourceCollection;
+import org.apache.tools.ant.util.ClasspathUtils;
+import org.apache.tools.ant.util.ScriptRunnerBase;
+import org.apache.tools.ant.util.ScriptRunnerHelper;
+
+/**
+ * Define a task using a script
+ *
+ * @since Ant 1.6
+ */
+public class ScriptDef extends DefBase {
+ /**
+ * script runner helper
+ */
+ private ScriptRunnerHelper helper = new ScriptRunnerHelper();
+
+ /** the name by which this script will be activated */
+ private String name;
+
+ /** Attributes definitions of this script */
+ private List attributes = new ArrayList();
+
+ /** Nested Element definitions of this script */
+ private List nestedElements = new ArrayList();
+
+ /** The attribute names as a set */
+ private Set attributeSet;
+
+ /** The nested element definitions indexed by their names */
+ private Map nestedElementMap;
+
+ /**
+ * Set the project.
+ * @param project the project that this def belows to.
+ */
+ public void setProject(Project project) {
+ super.setProject(project);
+ helper.setProjectComponent(this);
+ helper.setSetBeans(false);
+ }
+
+ /**
+ * set the name under which this script will be activated in a build
+ * file
+ *
+ * @param name the name of the script
+ */
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ /**
+ * Indicates whether the task supports a given attribute name
+ *
+ * @param attributeName the name of the attribute.
+ *
+ * @return true if the attribute is supported by the script.
+ */
+ public boolean isAttributeSupported(String attributeName) {
+ return attributeSet.contains(attributeName);
+ }
+
+ /**
+ * Class representing an attribute definition
+ */
+ public static class Attribute {
+ /** The attribute name */
+ private String name;
+
+ /**
+ * Set the attribute name
+ *
+ * @param name the attribute name
+ */
+ public void setName(String name) {
+ this.name = name.toLowerCase(Locale.ENGLISH);
+ }
+ }
+
+ /**
+ * Add an attribute definition to this script.
+ *
+ * @param attribute the attribute definition.
+ */
+ public void addAttribute(Attribute attribute) {
+ attributes.add(attribute);
+ }
+
+ /**
+ * Class to represent a nested element definition
+ */
+ public static class NestedElement {
+ /** The name of the nested element */
+ private String name;
+
+ /** The Ant type to which this nested element corresponds. */
+ private String type;
+
+ /** The class to be created for this nested element */
+ private String className;
+
+ /**
+ * set the tag name for this nested element
+ *
+ * @param name the name of this nested element
+ */
+ public void setName(String name) {
+ this.name = name.toLowerCase(Locale.ENGLISH);
+ }
+
+ /**
+ * Set the type of this element. This is the name of an
+ * Ant task or type which is to be used when this element is to be
+ * created. This is an alternative to specifying the class name directly
+ *
+ * @param type the name of an Ant type, or task, to use for this nested
+ * element.
+ */
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ /**
+ * Set the classname of the class to be used for the nested element.
+ * This specifies the class directly and is an alternative to specifying
+ * the Ant type name.
+ *
+ * @param className the name of the class to use for this nested
+ * element.
+ */
+ public void setClassName(String className) {
+ this.className = className;
+ }
+ }
+
+ /**
+ * Add a nested element definition.
+ *
+ * @param nestedElement the nested element definition.
+ */
+ public void addElement(NestedElement nestedElement) {
+ nestedElements.add(nestedElement);
+ }
+
+ /**
+ * Define the script.
+ */
+ public void execute() {
+ if (name == null) {
+ throw new BuildException("scriptdef requires a name attribute to "
+ + "name the script");
+ }
+
+ if (helper.getLanguage() == null) {
+ throw new BuildException("<scriptdef> requires a language attribute "
+ + "to specify the script language");
+ }
+
+ // Check if need to set the loader
+ if (getAntlibClassLoader() != null || hasCpDelegate()) {
+ helper.setClassLoader(createLoader());
+ }
+
+ attributeSet = new HashSet();
+ for (Iterator i = attributes.iterator(); i.hasNext();) {
+ Attribute attribute = (Attribute) i.next();
+ if (attribute.name == null) {
+ throw new BuildException("scriptdef <attribute> elements "
+ + "must specify an attribute name");
+ }
+
+ if (attributeSet.contains(attribute.name)) {
+ throw new BuildException("scriptdef <" + name + "> declares "
+ + "the " + attribute.name + " attribute more than once");
+ }
+ attributeSet.add(attribute.name);
+ }
+
+ nestedElementMap = new HashMap();
+ for (Iterator i = nestedElements.iterator(); i.hasNext();) {
+ NestedElement nestedElement = (NestedElement) i.next();
+ if (nestedElement.name == null) {
+ throw new BuildException("scriptdef <element> elements "
+ + "must specify an element name");
+ }
+ if (nestedElementMap.containsKey(nestedElement.name)) {
+ throw new BuildException("scriptdef <" + name + "> declares "
+ + "the " + nestedElement.name + " nested element more "
+ + "than once");
+ }
+
+ if (nestedElement.className == null
+ && nestedElement.type == null) {
+ throw new BuildException("scriptdef <element> elements "
+ + "must specify either a classname or type attribute");
+ }
+ if (nestedElement.className != null
+ && nestedElement.type != null) {
+ throw new BuildException("scriptdef <element> elements "
+ + "must specify only one of the classname and type "
+ + "attributes");
+ }
+
+
+ nestedElementMap.put(nestedElement.name, nestedElement);
+ }
+
+ // find the script repository - it is stored in the project
+ Map scriptRepository = lookupScriptRepository();
+ name = ProjectHelper.genComponentName(getURI(), name);
+ scriptRepository.put(name, this);
+ AntTypeDefinition def = new AntTypeDefinition();
+ def.setName(name);
+ def.setClass(ScriptDefBase.class);
+ ComponentHelper.getComponentHelper(
+ getProject()).addDataTypeDefinition(def);
+ }
+
+ /**
+ * Find or create the script repository - it is stored in the project.
+ * This method is synchronized on the project under {@link MagicNames#SCRIPT_REPOSITORY}
+ * @return the current script repository registered as a reference.
+ */
+ private Map lookupScriptRepository() {
+ Map scriptRepository = null;
+ Project p = getProject();
+ synchronized (p) {
+ scriptRepository =
+ (Map) p.getReference(MagicNames.SCRIPT_REPOSITORY);
+ if (scriptRepository == null) {
+ scriptRepository = new HashMap();
+ p.addReference(MagicNames.SCRIPT_REPOSITORY,
+ scriptRepository);
+ }
+ }
+ return scriptRepository;
+ }
+
+ /**
+ * Create a nested element to be configured.
+ *
+ * @param elementName the name of the nested element.
+ * @return object representing the element name.
+ */
+ public Object createNestedElement(String elementName) {
+ NestedElement definition
+ = (NestedElement) nestedElementMap.get(elementName);
+ if (definition == null) {
+ throw new BuildException("<" + name + "> does not support "
+ + "the <" + elementName + "> nested element");
+ }
+
+ Object instance = null;
+ String classname = definition.className;
+ if (classname == null) {
+ instance = getProject().createTask(definition.type);
+ if (instance == null) {
+ instance = getProject().createDataType(definition.type);
+ }
+ } else {
+ /*
+ // try the context classloader
+ ClassLoader loader
+ = Thread.currentThread().getContextClassLoader();
+ */
+ ClassLoader loader = createLoader();
+
+ try {
+ instance = ClasspathUtils.newInstance(classname, loader);
+ } catch (BuildException e) {
+ instance = ClasspathUtils.newInstance(classname, ScriptDef.class.getClassLoader());
+ }
+
+ getProject().setProjectReference(instance);
+ }
+
+ if (instance == null) {
+ throw new BuildException("<" + name + "> is unable to create "
+ + "the <" + elementName + "> nested element");
+ }
+ return instance;
+ }
+
+ /**
+ * Execute the script.
+ *
+ * @param attributes collection of attributes
+ * @param elements a list of nested element values.
+ * @deprecated since 1.7.
+ * Use executeScript(attribute, elements, instance) instead.
+ */
+ public void executeScript(Map attributes, Map elements) {
+ executeScript(attributes, elements, null);
+ }
+
+ /**
+ * Execute the script.
+ * This is called by the script instance to execute the script for this
+ * definition.
+ *
+ * @param attributes collection of attributes
+ * @param elements a list of nested element values.
+ * @param instance the script instance; can be null
+ */
+ public void executeScript(Map attributes, Map elements, ScriptDefBase instance) {
+ ScriptRunnerBase runner = helper.getScriptRunner();
+ runner.addBean("attributes", attributes);
+ runner.addBean("elements", elements);
+ runner.addBean("project", getProject());
+ if (instance != null) {
+ runner.addBean("self", instance);
+ }
+ runner.executeScript("scriptdef_" + name);
+ }
+
+ /**
+ * Defines the manager.
+ *
+ * @param manager the scripting manager.
+ */
+ public void setManager(String manager) {
+ helper.setManager(manager);
+ }
+
+ /**
+ * Defines the language (required).
+ *
+ * @param language the scripting language name for the script.
+ */
+ public void setLanguage(String language) {
+ helper.setLanguage(language);
+ }
+
+ /**
+ * Load the script from an external file ; optional.
+ *
+ * @param file the file containing the script source.
+ */
+ public void setSrc(File file) {
+ helper.setSrc(file);
+ }
+
+ /**
+ * Set the script text.
+ *
+ * @param text a component of the script text to be added.
+ */
+ public void addText(String text) {
+ helper.addText(text);
+ }
+
+ /**
+ * Add any source resource.
+ * @since Ant1.7.1
+ * @param resource source of script
+ */
+ public void add(ResourceCollection resource) {
+ helper.add(resource);
+ }
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/script/ScriptDefBase.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/script/ScriptDefBase.java
new file mode 100644
index 00000000..95d15aa6
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/script/ScriptDefBase.java
@@ -0,0 +1,132 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.script;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.DynamicConfigurator;
+import org.apache.tools.ant.MagicNames;
+import org.apache.tools.ant.Task;
+
+/**
+ * The script execution class. This class finds the defining script task
+ * and passes control to that task's executeScript method.
+ *
+ * @since Ant 1.6
+ */
+public class ScriptDefBase extends Task implements DynamicConfigurator {
+
+ /** Nested elements */
+ private Map nestedElementMap = new HashMap();
+
+ /** Attributes */
+ private Map attributes = new HashMap();
+
+ private String text;
+
+ /**
+ * Locate the script defining task and execute the script by passing
+ * control to it
+ */
+ public void execute() {
+ getScript().executeScript(attributes, nestedElementMap, this);
+ }
+
+ private ScriptDef getScript() {
+ String name = getTaskType();
+ Map scriptRepository
+ = (Map) getProject().getReference(MagicNames.SCRIPT_REPOSITORY);
+ if (scriptRepository == null) {
+ throw new BuildException("Script repository not found for " + name);
+ }
+
+ ScriptDef definition = (ScriptDef) scriptRepository.get(getTaskType());
+ if (definition == null) {
+ throw new BuildException("Script definition not found for " + name);
+ }
+ return definition;
+ }
+
+ /**
+ * Create a nested element
+ *
+ * @param name the nested element name
+ * @return the element to be configured
+ */
+ public Object createDynamicElement(String name) {
+ List nestedElementList = (List) nestedElementMap.get(name);
+ if (nestedElementList == null) {
+ nestedElementList = new ArrayList();
+ nestedElementMap.put(name, nestedElementList);
+ }
+ Object element = getScript().createNestedElement(name);
+ nestedElementList.add(element);
+ return element;
+ }
+
+ /**
+ * Set a task attribute
+ *
+ * @param name the attribute name.
+ * @param value the attribute's string value
+ */
+ public void setDynamicAttribute(String name, String value) {
+ ScriptDef definition = getScript();
+ if (!definition.isAttributeSupported(name)) {
+ throw new BuildException("<" + getTaskType()
+ + "> does not support the \"" + name + "\" attribute");
+ }
+
+ attributes.put(name, value);
+ }
+
+ /**
+ * Set the script text.
+ *
+ * @param text a component of the script text to be added.
+ * @since ant1.7
+ */
+ public void addText(String text) {
+ this.text = getProject().replaceProperties(text);
+ }
+
+ /**
+ * get the text of this element; may be null
+ * @return text or null for no nested text
+ * @since ant1.7
+ */
+ public String getText() {
+ return text;
+ }
+
+ /**
+ * Utility method for nested scripts; throws a BuildException
+ * with the given message.
+ * @param message text to pass to the BuildException
+ * @throws BuildException always.
+ * @since ant1.7
+ */
+ public void fail(String message) {
+ throw new BuildException(message);
+ }
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/sos/SOS.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/sos/SOS.java
new file mode 100644
index 00000000..03031d5e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/sos/SOS.java
@@ -0,0 +1,479 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.sos;
+
+import java.io.File;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.taskdefs.Execute;
+import org.apache.tools.ant.taskdefs.LogStreamHandler;
+import org.apache.tools.ant.types.Commandline;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.util.FileUtils;
+
+/**
+ * A base class for creating tasks for executing commands on SourceOffSite.
+ *
+ * These tasks were inspired by the VSS tasks.
+ *
+ */
+
+public abstract class SOS extends Task implements SOSCmd {
+
+ private static final int ERROR_EXIT_STATUS = 255;
+
+ private String sosCmdDir = null;
+ private String sosUsername = null;
+ private String sosPassword = "";
+ private String projectPath = null;
+ private String vssServerPath = null;
+ private String sosServerPath = null;
+ private String sosHome = null;
+ private String localPath = null;
+ private String version = null;
+ private String label = null;
+ private String comment = null;
+ private String filename = null;
+
+ private boolean noCompress = false;
+ private boolean noCache = false;
+ private boolean recursive = false;
+ private boolean verbose = false;
+
+ // CheckStyle:VisibilityModifier OFF - bc
+ /** Commandline to be executed. */
+ protected Commandline commandLine;
+ // CheckStyle:VisibilityModifier ON
+
+ /**
+ * Flag to disable the cache when set.
+ * Required if SOSHOME is set as an environment variable.
+ * Defaults to false.
+ *
+ * @param nocache True to disable caching.
+ */
+ public final void setNoCache(boolean nocache) {
+ noCache = nocache;
+ }
+
+ /**
+ * Flag to disable compression when set. Defaults to false.
+ *
+ * @param nocompress True to disable compression.
+ */
+ public final void setNoCompress(boolean nocompress) {
+ noCompress = nocompress;
+ }
+
+ /**
+ * The directory where soscmd(.exe) is located.
+ * soscmd must be on the path if omitted.
+ *
+ * @param dir The new sosCmd value.
+ */
+ public final void setSosCmd(String dir) {
+ sosCmdDir = FileUtils.translatePath(dir);
+ }
+
+ /**
+ * The SourceSafe username.
+ *
+ * @param username The new username value.
+ *
+ * @ant.attribute group="required"
+ */
+ public final void setUsername(String username) {
+ sosUsername = username;
+ }
+
+ /**
+ * The SourceSafe password.
+ *
+ * @param password The new password value.
+ */
+ public final void setPassword(String password) {
+ sosPassword = password;
+ }
+
+ /**
+ * The SourceSafe project path.
+ *
+ * @param projectpath The new projectpath value.
+ *
+ * @ant.attribute group="required"
+ */
+ public final void setProjectPath(String projectpath) {
+ if (projectpath.startsWith(SOSCmd.PROJECT_PREFIX)) {
+ projectPath = projectpath;
+ } else {
+ projectPath = SOSCmd.PROJECT_PREFIX + projectpath;
+ }
+ }
+
+ /**
+ * The path to the location of the ss.ini file.
+ *
+ * @param vssServerPath The new vssServerPath value.
+ *
+ * @ant.attribute group="required"
+ */
+ public final void setVssServerPath(String vssServerPath) {
+ this.vssServerPath = vssServerPath;
+ }
+
+ /**
+ * Path to the SourceOffSite home directory.
+ *
+ * @param sosHome The new sosHome value.
+ */
+ public final void setSosHome(String sosHome) {
+ this.sosHome = sosHome;
+ }
+
+ /**
+ * The address and port of SourceOffSite Server,
+ * for example 192.168.0.1:8888.
+ *
+ * @param sosServerPath The new sosServerPath value.
+ *
+ * @ant.attribute group="required"
+ */
+ public final void setSosServerPath(String sosServerPath) {
+ this.sosServerPath = sosServerPath;
+ }
+
+ /**
+ * Override the working directory and get to the specified path.
+ *
+ * @param path The new localPath value.
+ */
+ public final void setLocalPath(Path path) {
+ localPath = path.toString();
+ }
+
+ /**
+ * Enable verbose output. Defaults to false.
+ *
+ * @param verbose True for verbose output.
+ */
+ public void setVerbose(boolean verbose) {
+ this.verbose = verbose;
+ }
+
+ // Special setters for the sub-classes
+
+ /**
+ * Set the file name.
+ * @param file the filename to use.
+ */
+ protected void setInternalFilename(String file) {
+ filename = file;
+ }
+
+ /**
+ * Set the recursive flag.
+ * @param recurse if true use the recursive flag on the command line.
+ */
+ protected void setInternalRecursive(boolean recurse) {
+ recursive = recurse;
+ }
+
+ /**
+ * Set the comment text.
+ * @param text the comment text to use.
+ */
+ protected void setInternalComment(String text) {
+ comment = text;
+ }
+
+ /**
+ * Set the label.
+ * @param text the label to use.
+ */
+ protected void setInternalLabel(String text) {
+ label = text;
+ }
+
+ /**
+ * Set the version.
+ * @param text the version to use.
+ */
+ protected void setInternalVersion(String text) {
+ version = text;
+ }
+
+ /**
+ * Get the executable to run. Add the path if it was specified in the build file
+ *
+ * @return the executable to run.
+ */
+ protected String getSosCommand() {
+ if (sosCmdDir == null) {
+ return COMMAND_SOS_EXE;
+ } else {
+ return sosCmdDir + File.separator + COMMAND_SOS_EXE;
+ }
+ }
+
+ /**
+ * Get the comment
+ * @return if it was set, null if not.
+ */
+ protected String getComment() {
+ return comment;
+ }
+
+ /**
+ * Get the version
+ * @return if it was set, null if not.
+ */
+ protected String getVersion() {
+ return version;
+ }
+
+ /**
+ * Get the label
+ * @return if it was set, null if not.
+ */
+ protected String getLabel() {
+ return label;
+ }
+
+ /**
+ * Get the username
+ * @return if it was set, null if not.
+ */
+ protected String getUsername() {
+ return sosUsername;
+ }
+
+ /**
+ * Get the password
+ * @return empty string if it wasn't set.
+ */
+ protected String getPassword() {
+ return sosPassword;
+ }
+
+ /**
+ * Get the project path
+ * @return if it was set, null if not.
+ */
+ protected String getProjectPath() {
+ return projectPath;
+ }
+
+ /**
+ * Get the VSS server path
+ * @return if it was set, null if not.
+ */
+ protected String getVssServerPath() {
+ return vssServerPath;
+ }
+
+ /**
+ * Get the SOS home directory.
+ * @return if it was set, null if not.
+ */
+ protected String getSosHome() {
+ return sosHome;
+ }
+
+ /**
+ * Get the SOS serve path.
+ * @return if it was set, null if not.
+ */
+ protected String getSosServerPath() {
+ return sosServerPath;
+ }
+
+ /**
+ * Get the filename to be acted upon.
+ * @return if it was set, null if not.
+ */
+ protected String getFilename() {
+ return filename;
+ }
+
+ /**
+ * Get the NoCompress flag.
+ *
+ * @return the 'nocompress' Flag if the attribute was 'true',
+ * otherwise an empty string.
+ */
+ protected String getNoCompress() {
+ return noCompress ? FLAG_NO_COMPRESSION : "";
+ }
+
+ /**
+ * Get the NoCache flag.
+ *
+ * @return the 'nocache' Flag if the attribute was 'true', otherwise an empty string.
+ */
+ protected String getNoCache() {
+ return noCache ? FLAG_NO_CACHE : "";
+ }
+
+ /**
+ * Get the 'verbose' Flag.
+ *
+ * @return the 'verbose' Flag if the attribute was 'true', otherwise an empty string.
+ */
+ protected String getVerbose() {
+ return verbose ? FLAG_VERBOSE : "";
+ }
+
+ /**
+ * Get the 'recursive' Flag.
+ *
+ * @return the 'recursive' Flag if the attribute was 'true', otherwise an empty string.
+ */
+ protected String getRecursive() {
+ return recursive ? FLAG_RECURSION : "";
+ }
+
+ /**
+ * Builds and returns the working directory.
+ * <p>
+ * The localpath is created if it didn't exist.
+ *
+ * @return the absolute path of the working directory.
+ */
+ protected String getLocalPath() {
+ if (localPath == null) {
+ return getProject().getBaseDir().getAbsolutePath();
+ } else {
+ // make sure localDir exists, create it if it doesn't
+ File dir = getProject().resolveFile(localPath);
+ if (!dir.exists()) {
+ boolean done = dir.mkdirs() || dir.isDirectory();
+ if (!done) {
+ String msg = "Directory " + localPath + " creation was not "
+ + "successful for an unknown reason";
+ throw new BuildException(msg, getLocation());
+ }
+ getProject().log("Created dir: " + dir.getAbsolutePath());
+ }
+ return dir.getAbsolutePath();
+ }
+ }
+
+ /**
+ * Subclasses implement the logic required to construct the command line.
+ *
+ * @return The command line to execute.
+ */
+ abstract Commandline buildCmdLine();
+
+
+ /**
+ * Execute the created command line.
+ *
+ * @throws BuildException on error.
+ */
+ public void execute()
+ throws BuildException {
+ int result = 0;
+ buildCmdLine();
+ result = run(commandLine);
+ if (result == ERROR_EXIT_STATUS) { // This is the exit status
+ String msg = "Failed executing: " + commandLine.toString();
+ throw new BuildException(msg, getLocation());
+ }
+ }
+
+ /**
+ * Execute the created command line.
+ *
+ * @param cmd The command line to run.
+ * @return int the exit code.
+ * @throws BuildException
+ */
+ protected int run(Commandline cmd) {
+ try {
+ Execute exe = new Execute(new LogStreamHandler(this,
+ Project.MSG_INFO,
+ Project.MSG_WARN));
+
+ exe.setAntRun(getProject());
+ exe.setWorkingDirectory(getProject().getBaseDir());
+ exe.setCommandline(cmd.getCommandline());
+ exe.setVMLauncher(false); // Use the OS VM launcher so we get environment variables
+ return exe.execute();
+ } catch (java.io.IOException e) {
+ throw new BuildException(e, getLocation());
+ }
+ }
+
+ /** Sets the executable and add the required attributes to the command line. */
+ protected void getRequiredAttributes() {
+ // Get the path to the soscmd(.exe)
+ commandLine.setExecutable(getSosCommand());
+ // SOS server address is required
+ if (getSosServerPath() == null) {
+ throw new BuildException("sosserverpath attribute must be set!", getLocation());
+ }
+ commandLine.createArgument().setValue(FLAG_SOS_SERVER);
+ commandLine.createArgument().setValue(getSosServerPath());
+ // Login info is required
+ if (getUsername() == null) {
+ throw new BuildException("username attribute must be set!", getLocation());
+ }
+ commandLine.createArgument().setValue(FLAG_USERNAME);
+ commandLine.createArgument().setValue(getUsername());
+ // The SOS class knows that the SOS server needs the password flag,
+ // even if there is no password ,so we send a " "
+ commandLine.createArgument().setValue(FLAG_PASSWORD);
+ commandLine.createArgument().setValue(getPassword());
+ // VSS Info is required
+ if (getVssServerPath() == null) {
+ throw new BuildException("vssserverpath attribute must be set!", getLocation());
+ }
+ commandLine.createArgument().setValue(FLAG_VSS_SERVER);
+ commandLine.createArgument().setValue(getVssServerPath());
+ // VSS project is required
+ if (getProjectPath() == null) {
+ throw new BuildException("projectpath attribute must be set!", getLocation());
+ }
+ commandLine.createArgument().setValue(FLAG_PROJECT);
+ commandLine.createArgument().setValue(getProjectPath());
+ }
+
+ /** Adds the optional attributes to the command line. */
+ protected void getOptionalAttributes() {
+ // -verbose
+ commandLine.createArgument().setValue(getVerbose());
+ // Disable Compression
+ commandLine.createArgument().setValue(getNoCompress());
+ // Path to the SourceOffSite home directory /home/user/.sos
+ if (getSosHome() == null) {
+ // If -soshome was not specified then we can look for nocache
+ commandLine.createArgument().setValue(getNoCache());
+ } else {
+ commandLine.createArgument().setValue(FLAG_SOS_HOME);
+ commandLine.createArgument().setValue(getSosHome());
+ }
+ //If a working directory was specified then add it to the command line
+ if (getLocalPath() != null) {
+ commandLine.createArgument().setValue(FLAG_WORKING_DIR);
+ commandLine.createArgument().setValue(getLocalPath());
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/sos/SOSCheckin.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/sos/SOSCheckin.java
new file mode 100644
index 00000000..9095f075
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/sos/SOSCheckin.java
@@ -0,0 +1,101 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.sos;
+
+import org.apache.tools.ant.types.Commandline;
+
+/**
+ * Commits and unlocks files in Visual SourceSafe via a SourceOffSite server.
+ *
+ * @ant.task name="soscheckin" category="scm"
+ */
+public class SOSCheckin extends SOS {
+
+ /**
+ * The filename to act upon.
+ * If no file is specified then the task
+ * acts upon the project.
+ *
+ * @param filename The new file value
+ */
+ public final void setFile(String filename) {
+ super.setInternalFilename(filename);
+ }
+
+ /**
+ * Flag to recursively apply the action. Defaults to false.
+ *
+ * @param recursive True for recursive operation.
+ */
+ public void setRecursive(boolean recursive) {
+ super.setInternalRecursive(recursive);
+ }
+
+ /**
+ * The comment to apply to all files being labelled.
+ *
+ * @param comment The new comment value
+ */
+ public void setComment(String comment) {
+ super.setInternalComment(comment);
+ }
+
+ /**
+ * Build the command line. <p>
+ *
+ * CheckInFile required parameters: -server -name -password -database -project
+ * -file<br>
+ * CheckInFile optional parameters: -workdir -log -verbose -nocache -nocompression
+ * -soshome<br>
+ * CheckInProject required parameters: -server -name -password -database
+ * -project<br>
+ * CheckInProject optional parameters: workdir -recursive -log -verbose
+ * -nocache -nocompression -soshome<br>
+ *
+ * @return Commandline the generated command to be executed
+ */
+ protected Commandline buildCmdLine() {
+ commandLine = new Commandline();
+
+ // If we find a "file" attribute then act on a file otherwise act on a project
+ if (getFilename() != null) {
+ // add -command CheckInFile to the commandline
+ commandLine.createArgument().setValue(SOSCmd.FLAG_COMMAND);
+ commandLine.createArgument().setValue(SOSCmd.COMMAND_CHECKIN_FILE);
+ // add -file xxxxx to the commandline
+ commandLine.createArgument().setValue(SOSCmd.FLAG_FILE);
+ commandLine.createArgument().setValue(getFilename());
+ } else {
+ // add -command CheckInProject to the commandline
+ commandLine.createArgument().setValue(SOSCmd.FLAG_COMMAND);
+ commandLine.createArgument().setValue(SOSCmd.COMMAND_CHECKIN_PROJECT);
+ // look for a recursive option
+ commandLine.createArgument().setValue(getRecursive());
+ }
+
+ getRequiredAttributes();
+ getOptionalAttributes();
+
+ // Look for a comment
+ if (getComment() != null) {
+ commandLine.createArgument().setValue(SOSCmd.FLAG_COMMENT);
+ commandLine.createArgument().setValue(getComment());
+ }
+ return commandLine;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/sos/SOSCheckout.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/sos/SOSCheckout.java
new file mode 100644
index 00000000..fab6fb9f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/sos/SOSCheckout.java
@@ -0,0 +1,85 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.sos;
+
+import org.apache.tools.ant.types.Commandline;
+
+/**
+ * Retrieves and locks files in Visual SourceSafe via a SourceOffSite server.
+ *
+ * @ant.task name="soscheckout" category="scm"
+ */
+public class SOSCheckout extends SOS {
+
+ /**
+ * The filename to act upon.
+ * If no file is specified then the task
+ * acts upon the project.
+ *
+ * @param filename The new file value
+ */
+ public final void setFile(String filename) {
+ super.setInternalFilename(filename);
+ }
+
+ /**
+ * Flag to recursively apply the action. Defaults to false.
+ *
+ * @param recursive True for recursive operation.
+ */
+ public void setRecursive(boolean recursive) {
+ super.setInternalRecursive(recursive);
+ }
+
+ /**
+ * Build the command line <br>
+ *
+ * CheckOutFile required parameters: -server -name -password -database -project -file<br>
+ * CheckOutFile optional parameters: -workdir -verbose -nocache -nocompression -soshome<br>
+ *
+ * CheckOutProject required parameters: -server -name -password -database -project<br>
+ * CheckOutProject optional parameters:-workdir -recursive -verbose -nocache
+ * -nocompression -soshome<br>
+ *
+ * @return Commandline the generated command to be executed
+ */
+ protected Commandline buildCmdLine() {
+ commandLine = new Commandline();
+
+ // If we find a "file" attribute then act on a file otherwise act on a project
+ if (getFilename() != null) {
+ // add -command CheckOutFile to the commandline
+ commandLine.createArgument().setValue(SOSCmd.FLAG_COMMAND);
+ commandLine.createArgument().setValue(SOSCmd.COMMAND_CHECKOUT_FILE);
+ // add -file xxxxx to the commandline
+ commandLine.createArgument().setValue(SOSCmd.FLAG_FILE);
+ commandLine.createArgument().setValue(getFilename());
+ } else {
+ // add -command CheckOutProject to the commandline
+ commandLine.createArgument().setValue(SOSCmd.FLAG_COMMAND);
+ commandLine.createArgument().setValue(SOSCmd.COMMAND_CHECKOUT_PROJECT);
+ // look for a recursive option
+ commandLine.createArgument().setValue(getRecursive());
+ }
+
+ getRequiredAttributes();
+ getOptionalAttributes();
+
+ return commandLine;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/sos/SOSCmd.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/sos/SOSCmd.java
new file mode 100644
index 00000000..3543c414
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/sos/SOSCmd.java
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.sos;
+
+/**
+ * Interface to hold constants used by the SOS tasks
+ *
+ */
+// CheckStyle:InterfaceIsTypeCheck OFF (bc)
+public interface SOSCmd {
+ // soscmd Command options
+ /** The sos executable */
+ String COMMAND_SOS_EXE = "soscmd";
+ /** The get file command */
+ String COMMAND_GET_FILE = "GetFile";
+ /** The get project command */
+ String COMMAND_GET_PROJECT = "GetProject";
+ /** The checkout file command */
+ String COMMAND_CHECKOUT_FILE = "CheckOutFile";
+ /** The checkout project command */
+ String COMMAND_CHECKOUT_PROJECT = "CheckOutProject";
+ /** The checkin file command */
+ String COMMAND_CHECKIN_FILE = "CheckInFile";
+ /** The checkin project command */
+ String COMMAND_CHECKIN_PROJECT = "CheckInProject";
+ /** The get history command */
+ String COMMAND_HISTORY = "GetFileHistory";
+ /** The add label command */
+ String COMMAND_LABEL = "AddLabel";
+ /** The project prefix */
+ String PROJECT_PREFIX = "$";
+
+ // soscmd Option flags
+ /** The command option */
+ String FLAG_COMMAND = "-command";
+ /** The database (vss server) option */
+ String FLAG_VSS_SERVER = "-database";
+ /** The username option */
+ String FLAG_USERNAME = "-name";
+ /** The password option */
+ String FLAG_PASSWORD = "-password";
+ /** The log option */
+ String FLAG_COMMENT = "-log";
+ /** The workdir option */
+ String FLAG_WORKING_DIR = "-workdir";
+ /** The recursive option */
+ String FLAG_RECURSION = "-recursive";
+ /** The revision option */
+ String FLAG_VERSION = "-revision";
+ /** The label option */
+ String FLAG_LABEL = "-label";
+ /** The no compression option */
+ String FLAG_NO_COMPRESSION = "-nocompress";
+ /** The no cache option */
+ String FLAG_NO_CACHE = "-nocache";
+ /** The server option */
+ String FLAG_SOS_SERVER = "-server";
+ /** The sos home option */
+ String FLAG_SOS_HOME = "-soshome";
+ /** The project option */
+ String FLAG_PROJECT = "-project";
+ /** The file option */
+ String FLAG_FILE = "-file";
+ /** The verbose option */
+ String FLAG_VERBOSE = "-verbose";
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/sos/SOSGet.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/sos/SOSGet.java
new file mode 100644
index 00000000..cdbf92bc
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/sos/SOSGet.java
@@ -0,0 +1,116 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.sos;
+
+import org.apache.tools.ant.types.Commandline;
+
+/**
+ * Retrieves a read-only copy of the specified project or file
+ * from Visual SourceSafe via a SourceOffSite server.
+ *
+ * @ant.task name="sosget" category="scm"
+ */
+public class SOSGet extends SOS {
+
+ /**
+ * The Filename to act upon.
+ * If no file is specified then the tasks
+ * act upon the project.
+ *
+ * @param filename The new file value
+ */
+ public final void setFile(String filename) {
+ super.setInternalFilename(filename);
+ }
+
+ /**
+ * Flag to recursively apply the action. Defaults to false
+ *
+ * @param recursive True for recursive operation.
+ */
+ public void setRecursive(boolean recursive) {
+ super.setInternalRecursive(recursive);
+ }
+
+ /**
+ * Set the version number to get -
+ * only works with SOSGet on a file.
+ *
+ * @param version The new version value
+ */
+ public void setVersion(String version) {
+ super.setInternalVersion(version);
+ }
+
+ /**
+ * The labeled version to operate on in SourceSafe.
+ *
+ * @param label The new label value
+ */
+ public void setLabel(String label) {
+ super.setInternalLabel(label);
+ }
+
+ /**
+ * Build the command line <br>
+ *
+ * GetFile required parameters: -server -name -password -database -project -file<br>
+ * GetFile optional parameters: -workdir -revision -verbose -nocache -nocompression -soshome<br>
+ *
+ * GetProject required parameters: -server -name -password -database -project<br>
+ * GetProject optional parameters: -label -workdir -recursive -verbose -nocache
+ * -nocompression -soshome<br>
+ *
+ * @return Commandline the generated command to be executed
+ */
+ protected Commandline buildCmdLine() {
+ commandLine = new Commandline();
+
+ // If we find a "file" attribute then act on a file otherwise act on a project
+ if (getFilename() != null) {
+ // add -command GetFile to the commandline
+ commandLine.createArgument().setValue(SOSCmd.FLAG_COMMAND);
+ commandLine.createArgument().setValue(SOSCmd.COMMAND_GET_FILE);
+ // add -file xxxxx to the commandline
+ commandLine.createArgument().setValue(SOSCmd.FLAG_FILE);
+ commandLine.createArgument().setValue(getFilename());
+ // look for a version attribute
+ if (getVersion() != null) {
+ //add -revision xxxxx to the commandline
+ commandLine.createArgument().setValue(SOSCmd.FLAG_VERSION);
+ commandLine.createArgument().setValue(getVersion());
+ }
+ } else {
+ // add -command GetProject to the commandline
+ commandLine.createArgument().setValue(SOSCmd.FLAG_COMMAND);
+ commandLine.createArgument().setValue(SOSCmd.COMMAND_GET_PROJECT);
+ // look for a recursive option
+ commandLine.createArgument().setValue(getRecursive());
+ // look for a label option
+ if (getLabel() != null) {
+ commandLine.createArgument().setValue(SOSCmd.FLAG_LABEL);
+ commandLine.createArgument().setValue(getLabel());
+ }
+ }
+
+ getRequiredAttributes();
+ getOptionalAttributes();
+
+ return commandLine;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/sos/SOSLabel.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/sos/SOSLabel.java
new file mode 100644
index 00000000..dd6b13a2
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/sos/SOSLabel.java
@@ -0,0 +1,91 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.sos;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.types.Commandline;
+
+/**
+ * Labels Visual SourceSafe files via a SourceOffSite server.
+ *
+ * @ant.task name="soslabel" category="scm"
+ */
+public class SOSLabel extends SOS {
+
+ /**
+ * The version number to label.
+ *
+ * @param version The new version value
+ */
+ public void setVersion(String version) {
+ super.setInternalVersion(version);
+ }
+
+ /**
+ * The label to apply the the files in SourceSafe.
+ *
+ * @param label The new label value
+ *
+ * @ant.attribute group="required"
+ */
+ public void setLabel(String label) {
+ super.setInternalLabel(label);
+ }
+
+ /**
+ * The comment to apply to all files being labelled.
+ *
+ * @param comment The new comment value
+ */
+ public void setComment(String comment) {
+ super.setInternalComment(comment);
+ }
+
+ /**
+ * Build the command line <br>
+ * AddLabel required parameters: -server -name -password -database -project -label<br>
+ * AddLabel optional parameters: -verbose -comment<br>
+ *
+ * @return Commandline the generated command to be executed
+ */
+ protected Commandline buildCmdLine() {
+ commandLine = new Commandline();
+
+ // add -command AddLabel to the commandline
+ commandLine.createArgument().setValue(SOSCmd.FLAG_COMMAND);
+ commandLine.createArgument().setValue(SOSCmd.COMMAND_LABEL);
+
+ getRequiredAttributes();
+
+ // a label is required
+ if (getLabel() == null) {
+ throw new BuildException("label attribute must be set!", getLocation());
+ }
+ commandLine.createArgument().setValue(SOSCmd.FLAG_LABEL);
+ commandLine.createArgument().setValue(getLabel());
+
+ // -verbose
+ commandLine.createArgument().setValue(getVerbose());
+ // Look for a comment
+ if (getComment() != null) {
+ commandLine.createArgument().setValue(SOSCmd.FLAG_COMMENT);
+ commandLine.createArgument().setValue(getComment());
+ }
+ return commandLine;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/sos/package.html b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/sos/package.html
new file mode 100644
index 00000000..a0538c21
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/sos/package.html
@@ -0,0 +1,29 @@
+<html>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<body>
+ <p>
+ Ant tasks for working with a SourceOffSite source control system.
+ </p>
+ <p>
+ The &lt;SOSGet&gt; Retreives file(s) from a SOS database<br>
+ The &lt;SOSCheckin&gt; Commits and unlocks file(s) in a SOS database<br>
+ The &lt;SOSCheckout&gt; Retreives and lock file(s) in a SOS database<br>
+ The &lt;SOSLabel&gt; Label a SOS database<br>
+ </p>
+</body>
+</html>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/sound/AntSoundPlayer.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/sound/AntSoundPlayer.java
new file mode 100644
index 00000000..7988bc60
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/sound/AntSoundPlayer.java
@@ -0,0 +1,251 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.sound;
+
+// ant includes
+import java.io.File;
+import java.io.IOException;
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.Clip;
+import javax.sound.sampled.DataLine;
+import javax.sound.sampled.Line;
+import javax.sound.sampled.LineEvent;
+import javax.sound.sampled.LineListener;
+import javax.sound.sampled.LineUnavailableException;
+import javax.sound.sampled.UnsupportedAudioFileException;
+
+import org.apache.tools.ant.BuildEvent;
+import org.apache.tools.ant.BuildListener;
+import org.apache.tools.ant.Project;
+
+
+
+/**
+ * This class is designed to be used by any AntTask that requires audio output.
+ *
+ * It implements the BuildListener interface to listen for BuildEvents
+ * and could be easily extended to provide audio output upon any
+ * specific build events occurring.
+ *
+ * I have only tested this with .WAV and .AIFF sound file formats. Both seem to work fine.
+ *
+ */
+
+public class AntSoundPlayer implements LineListener, BuildListener {
+
+ private File fileSuccess = null;
+ private int loopsSuccess = 0;
+ private Long durationSuccess = null;
+
+ private File fileFail = null;
+ private int loopsFail = 0;
+ private Long durationFail = null;
+
+ /** Constructor for AntSoundPlayer. */
+ public AntSoundPlayer() {
+ }
+
+ /**
+ * @param file the location of the audio file to be played when the
+ * build is successful
+ * @param loops the number of times the file should be played when
+ * the build is successful
+ * @param duration the number of milliseconds the file should be
+ * played when the build is successful
+ */
+ public void addBuildSuccessfulSound(File file, int loops, Long duration) {
+ this.fileSuccess = file;
+ this.loopsSuccess = loops;
+ this.durationSuccess = duration;
+ }
+
+
+ /**
+ * @param fileFail the location of the audio file to be played
+ * when the build fails
+ * @param loopsFail the number of times the file should be played
+ * when the build is fails
+ * @param durationFail the number of milliseconds the file should be
+ * played when the build fails
+ */
+ public void addBuildFailedSound(File fileFail, int loopsFail, Long durationFail) {
+ this.fileFail = fileFail;
+ this.loopsFail = loopsFail;
+ this.durationFail = durationFail;
+ }
+
+ /**
+ * Plays the file for duration milliseconds or loops.
+ */
+ private void play(Project project, File file, int loops, Long duration) {
+
+ Clip audioClip = null;
+
+ AudioInputStream audioInputStream = null;
+
+
+ try {
+ audioInputStream = AudioSystem.getAudioInputStream(file);
+ } catch (UnsupportedAudioFileException uafe) {
+ project.log("Audio format is not yet supported: "
+ + uafe.getMessage());
+ } catch (IOException ioe) {
+ ioe.printStackTrace();
+ }
+
+ if (audioInputStream != null) {
+ AudioFormat format = audioInputStream.getFormat();
+ DataLine.Info info = new DataLine.Info(Clip.class, format,
+ AudioSystem.NOT_SPECIFIED);
+ try {
+ audioClip = (Clip) AudioSystem.getLine(info);
+ audioClip.addLineListener(this);
+ audioClip.open(audioInputStream);
+ } catch (LineUnavailableException e) {
+ project.log("The sound device is currently unavailable");
+ return;
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ if (duration != null) {
+ playClip(audioClip, duration.longValue());
+ } else {
+ playClip(audioClip, loops);
+ }
+ audioClip.drain();
+ audioClip.close();
+ } else {
+ project.log("Can't get data from file " + file.getName());
+ }
+ }
+
+ private void playClip(Clip clip, int loops) {
+
+ clip.loop(loops);
+ do {
+ try {
+ long timeLeft =
+ (clip.getMicrosecondLength() - clip.getMicrosecondPosition())
+ / 1000;
+ if (timeLeft > 0) {
+ Thread.sleep(timeLeft);
+ }
+ } catch (InterruptedException e) {
+ break;
+ }
+ } while (clip.isRunning());
+
+ if (clip.isRunning()) {
+ clip.stop();
+ }
+ }
+
+ private void playClip(Clip clip, long duration) {
+ clip.loop(Clip.LOOP_CONTINUOUSLY);
+ try {
+ Thread.sleep(duration);
+ } catch (InterruptedException e) {
+ // Ignore Exception
+ }
+ clip.stop();
+ }
+
+ /**
+ * This is implemented to listen for any line events and closes the
+ * clip if required.
+ * @param event the line event to follow
+ */
+ public void update(LineEvent event) {
+ if (event.getType().equals(LineEvent.Type.STOP)) {
+ Line line = event.getLine();
+ line.close();
+ }
+ }
+
+
+ /**
+ * Fired before any targets are started.
+ * @param event ignored
+ */
+ public void buildStarted(BuildEvent event) {
+ }
+
+ /**
+ * Fired after the last target has finished. This event
+ * will still be thrown if an error occurred during the build.
+ * @param event the build finished event.
+ * @see BuildEvent#getException()
+ */
+ public void buildFinished(BuildEvent event) {
+ if (event.getException() == null && fileSuccess != null) {
+ // build successful!
+ play(event.getProject(), fileSuccess, loopsSuccess, durationSuccess);
+ } else if (event.getException() != null && fileFail != null) {
+ play(event.getProject(), fileFail, loopsFail, durationFail);
+ }
+ }
+
+ /**
+ * Fired when a target is started.
+ * @param event ignored.
+ * @see BuildEvent#getTarget()
+ */
+ public void targetStarted(BuildEvent event) {
+ }
+
+ /**
+ * Fired when a target has finished. This event will
+ * still be thrown if an error occurred during the build.
+ * @param event ignored.
+ * @see BuildEvent#getException()
+ */
+ public void targetFinished(BuildEvent event) {
+ }
+
+ /**
+ * Fired when a task is started.
+ * @param event ignored.
+ * @see BuildEvent#getTask()
+ */
+ public void taskStarted(BuildEvent event) {
+ }
+
+ /**
+ * Fired when a task has finished. This event will still
+ * be throw if an error occurred during the build.
+ * @param event ignored.
+ * @see BuildEvent#getException()
+ */
+ public void taskFinished(BuildEvent event) {
+ }
+
+ /**
+ * Fired whenever a message is logged.
+ * @param event the build event
+ * @see BuildEvent#getMessage()
+ * @see BuildEvent#getPriority()
+ */
+ public void messageLogged(BuildEvent event) {
+ }
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/sound/SoundTask.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/sound/SoundTask.java
new file mode 100644
index 00000000..dfb6e69a
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/sound/SoundTask.java
@@ -0,0 +1,193 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.sound;
+
+import java.io.File;
+import java.util.Random;
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+
+/**
+ * Plays a sound file at the end of the build, according to whether the build failed or succeeded.
+ *
+ * There are three attributes to be set:
+ *
+ * <code>source</code>: the location of the audio file to be played
+ * <code>duration</code>: play the sound file continuously until "duration" milliseconds has expired
+ * <code>loops</code>: the number of times the sound file should be played until stopped
+ *
+ * I have only tested this with .WAV and .AIFF sound file formats. Both seem
+ * to work fine.
+ *
+ * plans for the future:
+ * - use the midi api to define sounds (or drum beat etc) in xml and have
+ * Ant play them back
+ *
+ */
+
+public class SoundTask extends Task {
+
+ private BuildAlert success = null;
+ private BuildAlert fail = null;
+
+ /**
+ * add a sound when the build succeeds
+ * @return a BuildAlert to be configured
+ */
+ public BuildAlert createSuccess() {
+ success = new BuildAlert();
+ return success;
+ }
+
+ /**
+ * add a sound when the build fails
+ * @return a BuildAlert to be configured
+ */
+ public BuildAlert createFail() {
+ fail = new BuildAlert();
+ return fail;
+ }
+
+ /** Constructor for SoundTask. */
+ public SoundTask() {
+ }
+
+ /**
+ * Initialize the task.
+ */
+ public void init() {
+ }
+
+ /**
+ * Execute the task.
+ */
+ public void execute() {
+
+ AntSoundPlayer soundPlayer = new AntSoundPlayer();
+
+ if (success == null) {
+ log("No nested success element found.", Project.MSG_WARN);
+ } else {
+ soundPlayer.addBuildSuccessfulSound(success.getSource(),
+ success.getLoops(), success.getDuration());
+ }
+
+ if (fail == null) {
+ log("No nested failure element found.", Project.MSG_WARN);
+ } else {
+ soundPlayer.addBuildFailedSound(fail.getSource(),
+ fail.getLoops(), fail.getDuration());
+ }
+
+ getProject().addBuildListener(soundPlayer);
+
+ }
+
+ /**
+ * A class to be extended by any BuildAlert's that require the output
+ * of sound.
+ */
+ public class BuildAlert {
+ private File source = null;
+ private int loops = 0;
+ private Long duration = null;
+
+ /**
+ * Sets the duration in milliseconds the file should be played; optional.
+ * @param duration the duration in milliseconds
+ */
+ public void setDuration(Long duration) {
+ this.duration = duration;
+ }
+
+ /**
+ * Sets the location of the file to get the audio; required.
+ *
+ * @param source the name of a sound-file directory or of the audio file
+ */
+ public void setSource(File source) {
+ this.source = source;
+ }
+
+ /**
+ * Sets the number of times the source file should be played; optional.
+ *
+ * @param loops the number of loops to play the source file
+ */
+ public void setLoops(int loops) {
+ this.loops = loops;
+ }
+
+ /**
+ * Gets the location of the file to get the audio.
+ * @return the file location
+ */
+ public File getSource() {
+ File nofile = null;
+ // Check if source is a directory
+ if (source.exists()) {
+ if (source.isDirectory()) {
+ // get the list of files in the dir
+ String[] entries = source.list();
+ Vector files = new Vector();
+ for (int i = 0; i < entries.length; i++) {
+ File f = new File(source, entries[i]);
+ if (f.isFile()) {
+ files.addElement(f);
+ }
+ }
+ if (files.size() < 1) {
+ throw new BuildException("No files found in directory " + source);
+ }
+ int numfiles = files.size();
+ // get a random number between 0 and the number of files
+ Random rn = new Random();
+ int x = rn.nextInt(numfiles);
+ // set the source to the file at that location
+ this.source = (File) files.elementAt(x);
+ }
+ } else {
+ log(source + ": invalid path.", Project.MSG_WARN);
+ this.source = nofile;
+ }
+ return this.source;
+ }
+
+ /**
+ * Sets the number of times the source file should be played.
+ *
+ * @return the number of loops to play the source file
+ */
+ public int getLoops() {
+ return this.loops;
+ }
+
+ /**
+ * Gets the duration in milliseconds the file should be played.
+ * @return the duration in milliseconds
+ */
+ public Long getDuration() {
+ return this.duration;
+ }
+ }
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/splash/SplashScreen.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/splash/SplashScreen.java
new file mode 100644
index 00000000..5de84cca
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/splash/SplashScreen.java
@@ -0,0 +1,181 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.splash;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.Toolkit;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.swing.BorderFactory;
+import javax.swing.ImageIcon;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JProgressBar;
+import javax.swing.JWindow;
+
+import org.apache.tools.ant.BuildEvent;
+import org.apache.tools.ant.BuildListener;
+
+class SplashScreen extends JWindow implements ActionListener, BuildListener {
+ private static final int FONT_SIZE = 12;
+ private JLabel text;
+ private JProgressBar pb;
+ private int total;
+ private static final int MIN = 0;
+ private static final int MAX = 200;
+ private Pattern progressRegExpPattern;
+
+ public SplashScreen(String msg) {
+ this(msg, null, null);
+ }
+
+ public SplashScreen(ImageIcon img) {
+ this(img, null, null);
+ }
+
+ public SplashScreen(String msg, String progressRegExp, String displayText) {
+ init(null, progressRegExp, displayText);
+ setText(msg);
+ }
+
+ public SplashScreen(ImageIcon img, String progressRegExp,
+ String displayText) {
+ init(img, progressRegExp, displayText);
+ }
+
+ protected void init(ImageIcon img) {
+ init(img, null, null);
+ }
+
+ protected void init(ImageIcon img, String progressRegExp,
+ String displayText) {
+ if (progressRegExp != null) {
+ progressRegExpPattern = Pattern.compile(progressRegExp);
+ }
+
+ JPanel pan = (JPanel) getContentPane();
+ JLabel piccy;
+ if (img == null) {
+ piccy = new JLabel();
+ } else {
+ piccy = new JLabel(img);
+ }
+
+ piccy.setBorder(BorderFactory.createLineBorder(Color.black, 1));
+ if (displayText == null) {
+ displayText = "Building....";
+ }
+ text = new JLabel(displayText, JLabel.CENTER);
+ text.setFont(new Font("Sans-Serif", Font.BOLD, FONT_SIZE));
+ text.setBorder(BorderFactory.createEtchedBorder());
+
+ pb = new JProgressBar(MIN, MAX);
+ pb.setBorder(BorderFactory.createBevelBorder(javax.swing.border.BevelBorder.LOWERED));
+ JPanel pan2 = new JPanel();
+ pan2.setLayout(new BorderLayout());
+
+ pan2.add(text, BorderLayout.NORTH);
+ pan2.add(pb, BorderLayout.SOUTH);
+
+ pan.setLayout(new BorderLayout());
+ pan.add(piccy, BorderLayout.CENTER);
+ pan.add(pan2, BorderLayout.SOUTH);
+
+ pan.setBorder(BorderFactory.createBevelBorder(javax.swing.border.BevelBorder.RAISED));
+
+ pack();
+
+ Dimension size = getSize();
+ Dimension scr = Toolkit.getDefaultToolkit().getScreenSize();
+ int x = (scr.width - size.width) / 2;
+ int y = (scr.height - size.height) / 2;
+ setBounds(x, y, size.width, size.height);
+ }
+
+ public void setText(String txt) {
+ text.setText(txt);
+ }
+
+ public void actionPerformed(ActionEvent a) {
+ if (!hasProgressPattern()) {
+ if (total < MAX) {
+ total++;
+ } else {
+ total = MIN;
+ }
+ pb.setValue(total);
+ }
+ }
+
+ public void buildStarted(BuildEvent event) {
+ actionPerformed(null);
+ }
+
+ public void buildFinished(BuildEvent event) {
+ pb.setValue(MAX);
+ setVisible(false);
+ dispose();
+ }
+ public void targetStarted(BuildEvent event) {
+ actionPerformed(null);
+ }
+
+ public void targetFinished(BuildEvent event) {
+ actionPerformed(null);
+ }
+
+ public void taskStarted(BuildEvent event) {
+ actionPerformed(null);
+ }
+
+ public void taskFinished(BuildEvent event) {
+ actionPerformed(null);
+ }
+
+ public void messageLogged(BuildEvent event) {
+ actionPerformed(null);
+ if (hasProgressPattern()) {
+ String message = event.getMessage();
+ Matcher matcher = progressRegExpPattern.matcher(message);
+ if (matcher != null && matcher.matches()) {
+ String gr = matcher.group(1);
+ try {
+ int i = Math.min(new Integer(gr).intValue() * 2, MAX);
+ pb.setValue(i);
+ } catch (NumberFormatException e) {
+ //TODO: how to reach logger?!?
+ //log("Number parsing error in progressRegExp", Project.MSG_VERBOSE);
+
+ }
+ }
+ }
+ }
+
+ protected boolean hasProgressPattern() {
+ return progressRegExpPattern != null;
+ }
+
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/splash/SplashTask.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/splash/SplashTask.java
new file mode 100644
index 00000000..3a73bdf7
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/splash/SplashTask.java
@@ -0,0 +1,297 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.splash;
+
+import java.io.ByteArrayOutputStream;
+import java.io.DataInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.net.URLConnection;
+
+import javax.swing.ImageIcon;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.taskdefs.optional.net.SetProxy;
+import org.apache.tools.ant.util.Base64Converter;
+
+/**
+ * Creates a splash screen. The splash screen is displayed
+ * for the duration of the build and includes a handy progress bar as
+ * well. Use in conjunction with the sound task to provide interest
+ * whilst waiting for your builds to complete...
+ * @since Ant1.5
+ */
+public class SplashTask extends Task {
+ private static final int DEFAULT_SHOW_DURATION = 5000;
+
+ private String imgurl = null;
+ private String proxy = null;
+ private String user = null;
+ private String password = null;
+ private String port = "80";
+ private int showDuration = DEFAULT_SHOW_DURATION;
+ private boolean useProxy = false;
+ private String progressRegExp = null;
+ private String displayText = null;
+
+ private static SplashScreen splash = null;
+
+ /**
+ * A URL pointing to an image to display; optional, default antlogo.gif
+ * from the classpath.
+ * @param imgurl the url string pointing to the image
+ */
+ public void setImageURL(String imgurl) {
+ this.imgurl = imgurl;
+ }
+
+ /**
+ * flag to enable proxy settings; optional, deprecated : consider
+ * using &lt;setproxy&gt; instead
+ * @param useProxy if ture, enable proxy settings
+ * @deprecated since 1.5.x.
+ * Use org.apache.tools.ant.taskdefs.optional.net.SetProxy
+ */
+ @Deprecated
+ public void setUseproxy(boolean useProxy) {
+ this.useProxy = useProxy;
+ }
+
+ /**
+ * name of proxy; optional.
+ * @param proxy the name of the proxy host
+ * @deprecated since 1.5.x.
+ * Use org.apache.tools.ant.taskdefs.optional.net.SetProxy
+ */
+ @Deprecated
+ public void setProxy(String proxy) {
+ this.proxy = proxy;
+ }
+
+ /**
+ * Proxy port; optional, default 80.
+ * @param port the proxy port
+ * @deprecated since 1.5.x.
+ * Use org.apache.tools.ant.taskdefs.optional.net.SetProxy
+ */
+ @Deprecated
+ public void setPort(String port) {
+ this.port = port;
+ }
+
+ /**
+ * Proxy user; optional, default =none.
+ * @param user the proxy user
+ * @deprecated since 1.5.x.
+ * Use org.apache.tools.ant.taskdefs.optional.net.SetProxy
+ */
+ @Deprecated
+ public void setUser(String user) {
+ this.user = user;
+ }
+
+ /**
+ * Proxy password; required if <tt>user</tt> is set.
+ * @param password the proxy password
+ * @deprecated since 1.5.x.
+ * Use org.apache.tools.ant.taskdefs.optional.net.SetProxy
+ */
+ @Deprecated
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ /**
+ * how long to show the splash screen in milliseconds,
+ * optional; default 5000 ms.
+ * @param duration the splash duration in milliseconds
+ */
+ public void setShowduration(int duration) {
+ this.showDuration = duration;
+ }
+
+
+ /**
+ * Progress regular expression which is used to parse the output
+ * and dig out current progress optional; if not provided,
+ * progress is increased every action and log output line
+ * @param progressRegExp Progress regular expression, exactly one
+ * group pattern must exists, and it represents the progress
+ * number (0-100) (i.e "Progress: (.*)%")
+ * @since Ant 1.8.0
+ */
+ public void setProgressRegExp(String progressRegExp) {
+ this.progressRegExp = progressRegExp;
+ }
+
+ /**
+ * Sets the display text presented in the splash window.
+ * optional; defaults to "Building ..."
+ * @param displayText the display text presented the splash window
+ * @since Ant 1.8.0
+ */
+ public void setDisplayText(String displayText) {
+ this.displayText = displayText;
+ }
+
+ /**
+ * Execute the task.
+ * @throws BuildException on error
+ */
+ @Override
+ public void execute() throws BuildException {
+ if (splash != null) {
+ splash.setVisible(false);
+ getProject().removeBuildListener(splash);
+ splash.dispose();
+ splash = null;
+ }
+
+ log("Creating new SplashScreen", Project.MSG_VERBOSE);
+ InputStream in = null;
+
+ if (imgurl != null) {
+ try {
+ URLConnection conn = null;
+
+ SetProxy sp = new SetProxy();
+ sp.setProxyHost(proxy);
+ if (port != null) {
+ sp.setProxyPort(Integer.parseInt(port));
+ }
+ sp.setProxyUser(user);
+ sp.setProxyPassword(password);
+ sp.applyWebProxySettings();
+
+ if (useProxy && (proxy != null && proxy.length() > 0)
+ && (port != null && port.length() > 0)) {
+
+ log("Using proxied Connection", Project.MSG_DEBUG);
+ System.getProperties().put("http.proxySet", "true");
+
+ URL url = new URL(imgurl);
+
+ conn = url.openConnection();
+ if (user != null && user.length() > 0) {
+ // converted from sun internal classes to
+ // new Base64Converter
+ // utility class extracted from Get task
+ String encodedcreds =
+ new Base64Converter().encode(user + ":" + password);
+ conn.setRequestProperty("Proxy-Authorization",
+ encodedcreds);
+ }
+
+ } else {
+ System.getProperties().put("http.proxySet", "false");
+ log("Using Direction HTTP Connection", Project.MSG_DEBUG);
+ URL url = new URL(imgurl);
+ conn = url.openConnection();
+ }
+ conn.setDoInput(true);
+ conn.setDoOutput(false);
+
+ in = conn.getInputStream();
+
+ // Catch everything - some of the above return nulls,
+ // throw exceptions or generally misbehave
+ // in the event of a problem etc
+
+ } catch (Throwable ioe) {
+ log("Unable to download image, trying default Ant Logo",
+ Project.MSG_DEBUG);
+ log("(Exception was \"" + ioe.getMessage() + "\"",
+ Project.MSG_DEBUG);
+ }
+ }
+
+ if (in == null) {
+ ClassLoader cl = SplashTask.class.getClassLoader();
+ if (cl != null) {
+ in = cl.getResourceAsStream("images/ant_logo_large.gif");
+ } else {
+ in = ClassLoader
+ .getSystemResourceAsStream("images/ant_logo_large.gif");
+ }
+ }
+
+ boolean success = false;
+ if (in != null) {
+ DataInputStream din = new DataInputStream(in);
+ try {
+ ByteArrayOutputStream bout = new ByteArrayOutputStream();
+ int data;
+ while ((data = din.read()) != -1) {
+ bout.write((byte) data);
+ }
+
+ log("Got ByteArray, creating splash", Project.MSG_DEBUG);
+
+ try {
+ ImageIcon img = new ImageIcon(bout.toByteArray());
+ splash = new SplashScreen(img, progressRegExp, displayText);
+ success = true;
+ } catch (Throwable e) {
+ logHeadless(e);
+ }
+ } catch (Exception e) {
+ throw new BuildException(e);
+ } finally {
+ try {
+ din.close();
+ } catch (IOException ioe) {
+ // swallow if there was an error before so that
+ // original error will be passed up
+ if (success) {
+ throw new BuildException(ioe);
+ }
+ }
+ }
+ } else {
+ try {
+ splash = new SplashScreen("Image Unavailable.", progressRegExp,
+ displayText);
+ success = true;
+ } catch (Throwable e) {
+ logHeadless(e);
+ }
+ }
+
+ if (success) {
+ splash.setVisible(true);
+ splash.toFront();
+ getProject().addBuildListener(splash);
+ try {
+ Thread.sleep(showDuration);
+ } catch (InterruptedException e) {
+ // Ignore Exception
+ }
+ }
+ }
+
+ private void logHeadless(Throwable e) {
+ log("failed to display SplashScreen, caught "
+ + e.getClass().getName() + " with message: " + e.getMessage(),
+ Project.MSG_WARN);
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ssh/AbstractSshMessage.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ssh/AbstractSshMessage.java
new file mode 100644
index 00000000..9365e8cd
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ssh/AbstractSshMessage.java
@@ -0,0 +1,272 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.ssh;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.text.NumberFormat;
+
+import org.apache.tools.ant.BuildException;
+
+import com.jcraft.jsch.Channel;
+import com.jcraft.jsch.ChannelExec;
+import com.jcraft.jsch.ChannelSftp;
+import com.jcraft.jsch.JSchException;
+import com.jcraft.jsch.Session;
+import com.jcraft.jsch.SftpProgressMonitor;
+
+/**
+ * Abstract class for ssh upload and download
+ */
+public abstract class AbstractSshMessage {
+ private static final double ONE_SECOND = 1000.0;
+
+ private final Session session;
+ private final boolean verbose;
+ private LogListener listener = new LogListener() {
+ public void log(final String message) {
+ // do nothing;
+ }
+ };
+
+ /**
+ * Constructor for AbstractSshMessage
+ * @param session the ssh session to use
+ */
+ public AbstractSshMessage(final Session session) {
+ this(false, session);
+ }
+
+ /**
+ * Constructor for AbstractSshMessage
+ * @param verbose if true do verbose logging
+ * @param session the ssh session to use
+ * @since Ant 1.6.2
+ */
+ public AbstractSshMessage(final boolean verbose, final Session session) {
+ this.verbose = verbose;
+ this.session = session;
+ }
+
+ /**
+ * Open an ssh channel.
+ * @param command the command to use
+ * @return the channel
+ * @throws JSchException on error
+ */
+ protected Channel openExecChannel(final String command) throws JSchException {
+ final ChannelExec channel = (ChannelExec) session.openChannel("exec");
+ channel.setCommand(command);
+
+ return channel;
+ }
+
+ /**
+ * Open an ssh sftp channel.
+ * @return the channel
+ * @throws JSchException on error
+ */
+ protected ChannelSftp openSftpChannel() throws JSchException {
+ final ChannelSftp channel = (ChannelSftp) session.openChannel("sftp");
+
+ return channel;
+ }
+
+ /**
+ * Send an ack.
+ * @param out the output stream to use
+ * @throws IOException on error
+ */
+ protected void sendAck(final OutputStream out) throws IOException {
+ final byte[] buf = new byte[1];
+ buf[0] = 0;
+ out.write(buf);
+ out.flush();
+ }
+
+ /**
+ * Reads the response, throws a BuildException if the response
+ * indicates an error.
+ * @param in the input stream to use
+ * @throws IOException on I/O error
+ * @throws BuildException on other errors
+ */
+ protected void waitForAck(final InputStream in)
+ throws IOException, BuildException {
+ final int b = in.read();
+
+ // b may be 0 for success,
+ // 1 for error,
+ // 2 for fatal error,
+
+ if (b == -1) {
+ // didn't receive any response
+ throw new BuildException("No response from server");
+ } else if (b != 0) {
+ final StringBuffer sb = new StringBuffer();
+
+ int c = in.read();
+ while (c > 0 && c != '\n') {
+ sb.append((char) c);
+ c = in.read();
+ }
+
+ if (b == 1) {
+ throw new BuildException("server indicated an error: "
+ + sb.toString());
+ } else if (b == 2) {
+ throw new BuildException("server indicated a fatal error: "
+ + sb.toString());
+ } else {
+ throw new BuildException("unknown response, code " + b
+ + " message: " + sb.toString());
+ }
+ }
+ }
+
+ /**
+ * Carry out the transfer.
+ * @throws IOException on I/O errors
+ * @throws JSchException on ssh errors
+ */
+ public abstract void execute() throws IOException, JSchException;
+
+ /**
+ * Set a log listener.
+ * @param aListener the log listener
+ */
+ public void setLogListener(final LogListener aListener) {
+ listener = aListener;
+ }
+
+ /**
+ * Log a message to the log listener.
+ * @param message the message to log
+ */
+ protected void log(final String message) {
+ listener.log(message);
+ }
+
+ /**
+ * Log transfer stats to the log listener.
+ * @param timeStarted the time started
+ * @param timeEnded the finishing time
+ * @param totalLength the total length
+ */
+ protected void logStats(final long timeStarted,
+ final long timeEnded,
+ final long totalLength) {
+ final double duration = (timeEnded - timeStarted) / ONE_SECOND;
+ final NumberFormat format = NumberFormat.getNumberInstance();
+ format.setMaximumFractionDigits(2);
+ format.setMinimumFractionDigits(1);
+ listener.log("File transfer time: " + format.format(duration)
+ + " Average Rate: " + format.format(totalLength / duration)
+ + " B/s");
+ }
+
+ /**
+ * Is the verbose attribute set.
+ * @return true if the verbose attribute is set
+ * @since Ant 1.6.2
+ */
+ protected final boolean getVerbose() {
+ return verbose;
+ }
+
+ /**
+ * Track progress every 10% if 100kb < filesize < 1mb. For larger
+ * files track progress for every percent transmitted.
+ * @param filesize the size of the file been transmitted
+ * @param totalLength the total transmission size
+ * @param percentTransmitted the current percent transmitted
+ * @return the percent that the file is of the total
+ */
+ protected final int trackProgress(final long filesize, final long totalLength,
+ final int percentTransmitted) {
+
+ // CheckStyle:MagicNumber OFF
+ final int percent = (int) Math.round(Math.floor((totalLength
+ / (double) filesize) * 100));
+
+ if (percent > percentTransmitted) {
+ if (filesize < 1048576) {
+ if (percent % 10 == 0) {
+ if (percent == 100) {
+ System.out.println(" 100%");
+ } else {
+ System.out.print("*");
+ }
+ }
+ } else {
+ if (percent == 50) {
+ System.out.println(" 50%");
+ } else if (percent == 100) {
+ System.out.println(" 100%");
+ } else {
+ System.out.print(".");
+ }
+ }
+ }
+ // CheckStyle:MagicNumber ON
+
+ return percent;
+ }
+
+ private ProgressMonitor monitor = null;
+
+ /**
+ * Get the progress monitor.
+ * @return the progress monitor.
+ */
+ protected SftpProgressMonitor getProgressMonitor() {
+ if (monitor == null) {
+ monitor = new ProgressMonitor();
+ }
+ return monitor;
+ }
+
+ private class ProgressMonitor implements SftpProgressMonitor {
+ private long initFileSize = 0;
+ private long totalLength = 0;
+ private int percentTransmitted = 0;
+
+ public void init(final int op, final String src, final String dest, final long max) {
+ initFileSize = max;
+ totalLength = 0;
+ percentTransmitted = 0;
+ }
+
+ public boolean count(final long len) {
+ totalLength += len;
+ percentTransmitted = trackProgress(initFileSize,
+ totalLength,
+ percentTransmitted);
+ return true;
+ }
+
+ public void end() {
+ }
+
+ public long getTotalLength() {
+ return totalLength;
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ssh/Directory.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ssh/Directory.java
new file mode 100644
index 00000000..b5088a7d
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ssh/Directory.java
@@ -0,0 +1,196 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.ssh;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.Set;
+import java.util.StringTokenizer;
+
+/**
+ * A helper object for Scp representing a directory in a file system.
+ */
+public class Directory {
+
+ private File directory;
+ private Set childDirectories;
+ private ArrayList files;
+ private Directory parent;
+
+ /**
+ * Constructor for a Directory.
+ * @param directory a directory.
+ */
+ public Directory(File directory) {
+ this(directory, null);
+ }
+
+ /**
+ * Constructor for a Directory.
+ * @param directory a directory
+ * @param parent a parent Directory
+ */
+ public Directory(File directory , Directory parent) {
+ this.parent = parent;
+ this.childDirectories = new LinkedHashSet();
+ this.files = new ArrayList();
+ this.directory = directory;
+ }
+
+ /**
+ * Add a directory to the child directories.
+ * @param directory a Directory
+ */
+ public void addDirectory(Directory directory) {
+ if (!childDirectories.contains(directory)) {
+ childDirectories.add(directory);
+ }
+ }
+
+ /**
+ * Add a file to the list of files.
+ * @param file a file to add
+ */
+ public void addFile(File file) {
+ files.add(file);
+ }
+
+ /**
+ * Get an iterator over the child Directories.
+ * @return an iterator
+ */
+ public Iterator directoryIterator() {
+ return childDirectories.iterator();
+ }
+
+ /**
+ * Get an iterator over the files.
+ * @return an iterator
+ */
+ public Iterator filesIterator() {
+ return files.iterator();
+ }
+
+ /**
+ * Get the parent Directory.
+ * @return the parent Directory.
+ */
+ public Directory getParent() {
+ return parent;
+ }
+
+ /**
+ * Is this a root Directory?
+ * @return true if there is no parent Directory
+ */
+ public boolean isRoot() {
+ return parent == null;
+ }
+
+ /**
+ * Get the directory file.
+ * @return the directory file
+ */
+ public File getDirectory() {
+ return directory;
+ }
+
+ /**
+ * Get a child directory of this directory.
+ * @param dir the directory to look for
+ * @return the child directory, or null if not found
+ */
+ public Directory getChild(File dir) {
+ for (Iterator i = childDirectories.iterator(); i.hasNext();) {
+ Directory current = (Directory) i.next();
+ if (current.getDirectory().equals(dir)) {
+ return current;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * The equality method.
+ * This checks if the directory field is the same.
+ * @param obj the object to compare to
+ * @return true if this object has an equal directory field as the other object
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ }
+
+ if (!(obj instanceof Directory)) {
+ return false;
+ }
+
+ Directory d = (Directory) obj;
+
+ return this.directory.equals(d.directory);
+ }
+
+ /**
+ * The hashcode method.
+ * @return the hash code of the directory field
+ */
+ @Override
+ public int hashCode() {
+ return directory.hashCode();
+ }
+
+ /**
+ * Get the path components of this directory.
+ * @return the path components as an array of strings.
+ */
+ public String[] getPath() {
+ return getPath(directory.getAbsolutePath());
+ }
+
+ /**
+ * Convert a file path to an array of path components.
+ * This uses File.separator to split the file path string.
+ * @param thePath the file path string to convert
+ * @return an array of path components
+ */
+ public static String[] getPath(String thePath) {
+ StringTokenizer tokenizer = new StringTokenizer(thePath,
+ File.separator);
+ String[] path = new String[ tokenizer.countTokens() ];
+
+ int i = 0;
+ while (tokenizer.hasMoreTokens()) {
+ path[i] = tokenizer.nextToken();
+ i++;
+ }
+
+ return path;
+ }
+
+ /**
+ * Get the number of files in the files attribute.
+ * @return the number of files
+ */
+ public int fileSize() {
+ return files.size();
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ssh/LogListener.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ssh/LogListener.java
new file mode 100644
index 00000000..41209ceb
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ssh/LogListener.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.ssh;
+
+/**
+ * Interface for ssh log listeners to implement.
+ */
+public interface LogListener {
+ /**
+ * Method for the loglistener to implement to receive log messages.
+ * @param message the message to log
+ */
+ void log(String message);
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ssh/SSHBase.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ssh/SSHBase.java
new file mode 100644
index 00000000..68419a85
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ssh/SSHBase.java
@@ -0,0 +1,236 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.ssh;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+
+import com.jcraft.jsch.JSch;
+import com.jcraft.jsch.JSchException;
+import com.jcraft.jsch.Session;
+
+/**
+ * Base class for Ant tasks using jsch.
+ *
+ * @since Ant 1.6
+ */
+public abstract class SSHBase extends Task implements LogListener {
+
+ /** Default listen port for SSH daemon */
+ private static final int SSH_PORT = 22;
+
+ private String host;
+ private String knownHosts;
+ private int port = SSH_PORT;
+ private boolean failOnError = true;
+ private boolean verbose;
+ private final SSHUserInfo userInfo;
+
+ /**
+ * Constructor for SSHBase.
+ */
+ public SSHBase() {
+ super();
+ userInfo = new SSHUserInfo();
+ }
+
+ /**
+ * Remote host, either DNS name or IP.
+ *
+ * @param host The new host value
+ */
+ public void setHost(final String host) {
+ this.host = host;
+ }
+
+ /**
+ * Get the host.
+ * @return the host
+ */
+ public String getHost() {
+ return host;
+ }
+
+ /**
+ * Set the failonerror flag.
+ * Default is true
+ * @param failure if true throw a build exception when a failure occuries,
+ * otherwise just log the failure and continue
+ */
+ public void setFailonerror(final boolean failure) {
+ failOnError = failure;
+ }
+
+ /**
+ * Get the failonerror flag.
+ * @return the failonerror flag
+ */
+ public boolean getFailonerror() {
+ return failOnError;
+ }
+
+ /**
+ * Set the verbose flag.
+ * @param verbose if true output more verbose logging
+ * @since Ant 1.6.2
+ */
+ public void setVerbose(final boolean verbose) {
+ this.verbose = verbose;
+ }
+
+ /**
+ * Get the verbose flag.
+ * @return the verbose flag
+ * @since Ant 1.6.2
+ */
+ public boolean getVerbose() {
+ return verbose;
+ }
+
+ /**
+ * Username known to remote host.
+ *
+ * @param username The new username value
+ */
+ public void setUsername(final String username) {
+ userInfo.setName(username);
+ }
+
+
+ /**
+ * Sets the password for the user.
+ *
+ * @param password The new password value
+ */
+ public void setPassword(final String password) {
+ userInfo.setPassword(password);
+ }
+
+ /**
+ * Sets the keyfile for the user.
+ *
+ * @param keyfile The new keyfile value
+ */
+ public void setKeyfile(final String keyfile) {
+ userInfo.setKeyfile(keyfile);
+ }
+
+ /**
+ * Sets the passphrase for the users key.
+ *
+ * @param passphrase The new passphrase value
+ */
+ public void setPassphrase(final String passphrase) {
+ userInfo.setPassphrase(passphrase);
+ }
+
+ /**
+ * Sets the path to the file that has the identities of
+ * all known hosts. This is used by SSH protocol to validate
+ * the identity of the host. The default is
+ * <i>${user.home}/.ssh/known_hosts</i>.
+ *
+ * @param knownHosts a path to the known hosts file.
+ */
+ public void setKnownhosts(final String knownHosts) {
+ this.knownHosts = knownHosts;
+ }
+
+ /**
+ * Setting this to true trusts hosts whose identity is unknown.
+ *
+ * @param yesOrNo if true trust the identity of unknown hosts.
+ */
+ public void setTrust(final boolean yesOrNo) {
+ userInfo.setTrust(yesOrNo);
+ }
+
+ /**
+ * Changes the port used to connect to the remote host.
+ *
+ * @param port port number of remote host.
+ */
+ public void setPort(final int port) {
+ this.port = port;
+ }
+
+ /**
+ * Get the port attribute.
+ * @return the port
+ */
+ public int getPort() {
+ return port;
+ }
+
+ /**
+ * Initialize the task.
+ * This initializizs the known hosts and sets the default port.
+ * @throws BuildException on error
+ */
+ public void init() throws BuildException {
+ super.init();
+ this.knownHosts = System.getProperty("user.home") + "/.ssh/known_hosts";
+ this.port = SSH_PORT;
+ }
+
+ /**
+ * Open an ssh session.
+ * @return the opened session
+ * @throws JSchException on error
+ */
+ protected Session openSession() throws JSchException {
+ final JSch jsch = new JSch();
+ final SSHBase base = this;
+ if (verbose) {
+ JSch.setLogger(new com.jcraft.jsch.Logger(){
+ public boolean isEnabled(final int level){
+ return true;
+ }
+ public void log(final int level, final String message){
+ base.log(message, Project.MSG_INFO);
+ }
+ });
+ }
+ if (null != userInfo.getKeyfile()) {
+ jsch.addIdentity(userInfo.getKeyfile());
+ }
+
+ if (!userInfo.getTrust() && knownHosts != null) {
+ log("Using known hosts: " + knownHosts, Project.MSG_DEBUG);
+ jsch.setKnownHosts(knownHosts);
+ }
+
+ final Session session = jsch.getSession(userInfo.getName(), host, port);
+ session.setConfig("PreferredAuthentications",
+ "publickey,keyboard-interactive,password");
+ session.setUserInfo(userInfo);
+ log("Connecting to " + host + ":" + port);
+ session.connect();
+ return session;
+ }
+
+ /**
+ * Get the user information.
+ * @return the user information
+ */
+ protected SSHUserInfo getUserInfo() {
+ return userInfo;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ssh/SSHExec.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ssh/SSHExec.java
new file mode 100644
index 00000000..a04dfefa
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ssh/SSHExec.java
@@ -0,0 +1,519 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.ssh;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.StringReader;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.resources.FileResource;
+import org.apache.tools.ant.util.FileUtils;
+import org.apache.tools.ant.util.KeepAliveInputStream;
+import org.apache.tools.ant.util.KeepAliveOutputStream;
+import org.apache.tools.ant.util.TeeOutputStream;
+
+import com.jcraft.jsch.ChannelExec;
+import com.jcraft.jsch.JSchException;
+import com.jcraft.jsch.Session;
+
+/**
+ * Executes a command on a remote machine via ssh.
+ * @since Ant 1.6 (created February 2, 2003)
+ */
+public class SSHExec extends SSHBase {
+
+ private static final int BUFFER_SIZE = 8192;
+ private static final int RETRY_INTERVAL = 500;
+
+ /** the command to execute via ssh */
+ private String command = null;
+
+ /** units are milliseconds, default is 0=infinite */
+ private long maxwait = 0;
+
+ /** for waiting for the command to finish */
+ private Thread thread = null;
+
+ private String outputProperty = null; // like <exec>
+ private String errorProperty = null;
+ private String resultProperty = null;
+ private File outputFile = null; // like <exec>
+ private File errorFile = null;
+ private String inputProperty = null;
+ private String inputString = null; // like <exec>
+ private File inputFile = null; // like <exec>
+ private boolean append = false; // like <exec>
+ private boolean appenderr = false;
+ private boolean usePty = false;
+ private boolean useSystemIn = false;
+
+ private Resource commandResource = null;
+
+ private static final String TIMEOUT_MESSAGE =
+ "Timeout period exceeded, connection dropped.";
+
+ /**
+ * To suppress writing logs to System.out
+ */
+ private boolean suppressSystemOut = false;
+
+ /**
+ * To suppress writing logs to System.err
+ */
+ private boolean suppressSystemErr = false;
+
+ /**
+ * Constructor for SSHExecTask.
+ */
+ public SSHExec() {
+ super();
+ }
+
+ /**
+ * Sets the command to execute on the remote host.
+ *
+ * @param command The new command value
+ */
+ public void setCommand(final String command) {
+ this.command = command;
+ }
+
+ /**
+ * Sets a commandResource from a file
+ * @param f the value to use.
+ * @since Ant 1.7.1
+ */
+ public void setCommandResource(final String f) {
+ this.commandResource = new FileResource(new File(f));
+ }
+
+ /**
+ * The connection can be dropped after a specified number of
+ * milliseconds. This is sometimes useful when a connection may be
+ * flaky. Default is 0, which means &quot;wait forever&quot;.
+ *
+ * @param timeout The new timeout value in seconds
+ */
+ public void setTimeout(final long timeout) {
+ maxwait = timeout;
+ }
+
+ /**
+ * If used, stores the output of the command to the given file.
+ *
+ * @param output The file to write to.
+ */
+ public void setOutput(final File output) {
+ outputFile = output;
+ }
+
+ /**
+ * If used, stores the erroutput of the command to the given file.
+ *
+ * @param output The file to write to.
+ * @since Apache Ant 1.9.4
+ */
+ public void setErrorOutput(final File output) {
+ errorFile = output;
+ }
+
+ /**
+ * If used, the content of the file is piped to the remote command
+ *
+ * @param input The file which provides the input data for the remote command
+ *
+ * @since Ant 1.8.0
+ */
+ public void setInput(final File input) {
+ inputFile = input;
+ }
+
+ /**
+ * If used, the content of the property is piped to the remote command
+ *
+ * @param inputProperty The property which contains the input data
+ * for the remote command.
+ *
+ * @since Ant 1.8.0
+ */
+ public void setInputProperty(final String inputProperty) {
+ this.inputProperty = inputProperty;
+ }
+
+ /**
+ * If used, the string is piped to the remote command.
+ *
+ * @param inputString the input data for the remote command.
+ *
+ * @since Ant 1.8.3
+ */
+ public void setInputString(final String inputString) {
+ this.inputString = inputString;
+ }
+
+ /**
+ * Determines if the output is appended to the file given in
+ * <code>setOutput</code>. Default is false, that is, overwrite
+ * the file.
+ *
+ * @param append True to append to an existing file, false to overwrite.
+ */
+ public void setAppend(final boolean append) {
+ this.append = append;
+ }
+
+ /**
+ * Determines if the output is appended to the file given in
+ * <code>setErrorOutput</code>. Default is false, that is, overwrite
+ * the file.
+ *
+ * @param appenderr True to append to an existing file, false to overwrite.
+ * @since Apache Ant 1.9.4
+ */
+ public void setErrAppend(final boolean appenderr) {
+ this.appenderr = appenderr;
+ }
+
+ /**
+ * If set, the output of the command will be stored in the given property.
+ *
+ * @param property The name of the property in which the command output
+ * will be stored.
+ */
+ public void setOutputproperty(final String property) {
+ outputProperty = property;
+ }
+
+ /**
+ * If set, the erroroutput of the command will be stored in the given property.
+ *
+ * @param property The name of the property in which the command erroroutput
+ * will be stored.
+ * @since Apache Ant 1.9.4
+ */
+ public void setErrorproperty (final String property) {
+ errorProperty = property;
+ }
+
+ /**
+ * If set, the exitcode of the command will be stored in the given property.
+ *
+ * @param property The name of the property in which the exitcode
+ * will be stored.
+ * @since Apache Ant 1.9.4
+ */
+ public void setResultproperty(final String property) {
+ resultProperty = property;
+ }
+
+ /**
+ * Whether a pseudo-tty should be allocated.
+ * @since Apache Ant 1.8.3
+ */
+ public void setUsePty(final boolean b) {
+ usePty = b;
+ }
+
+ /**
+ * If set, input will be taken from System.in
+ *
+ * @param useSystemIn True to use System.in as InputStream, false otherwise
+ * @since Apache Ant 1.9.4
+ */
+ public void setUseSystemIn(final boolean useSystemIn) {
+ this.useSystemIn = useSystemIn;
+ }
+
+ /**
+ * If suppressSystemOut is <code>true</code>, output will not be sent to System.out<br/>
+ * If suppressSystemOut is <code>false</code>, normal behavior
+ * @since Ant 1.9.0
+ */
+ public void setSuppressSystemOut(final boolean suppressSystemOut) {
+ this.suppressSystemOut = suppressSystemOut;
+ }
+
+ /**
+ * If suppressSystemErr is <code>true</code>, output will not be sent to System.err<br/>
+ * If suppressSystemErr is <code>false</code>, normal behavior
+ * @since Ant 1.9.4
+ */
+ public void setSuppressSystemErr(final boolean suppressSystemErr) {
+ this.suppressSystemErr = suppressSystemErr;
+ }
+
+ /**
+ * Execute the command on the remote host.
+ *
+ * @exception BuildException Most likely a network error or bad parameter.
+ */
+ @Override
+ public void execute() throws BuildException {
+
+ if (getHost() == null) {
+ throw new BuildException("Host is required.");
+ }
+ if (getUserInfo().getName() == null) {
+ throw new BuildException("Username is required.");
+ }
+ if (getUserInfo().getKeyfile() == null
+ && getUserInfo().getPassword() == null) {
+ throw new BuildException("Password or Keyfile is required.");
+ }
+ if (command == null && commandResource == null) {
+ throw new BuildException("Command or commandResource is required.");
+ }
+
+ final int numberOfInputs = (inputFile != null ? 1 : 0)
+ + (inputProperty != null ? 1 : 0)
+ + (inputString != null ? 1 : 0);
+ if (numberOfInputs > 1) {
+ throw new BuildException("You can't specify more than one of"
+ + " inputFile, inputProperty and"
+ + " inputString.");
+ }
+ if (inputFile != null && !inputFile.exists()) {
+ throw new BuildException("The input file "
+ + inputFile.getAbsolutePath()
+ + " does not exist.");
+ }
+
+ Session session = null;
+ final StringBuffer output = new StringBuffer();
+ try {
+ session = openSession();
+ /* called once */
+ if (command != null) {
+ log("cmd : " + command, Project.MSG_INFO);
+ executeCommand(session, command, output);
+ } else { // read command resource and execute for each command
+ try {
+ final BufferedReader br = new BufferedReader(
+ new InputStreamReader(commandResource.getInputStream()));
+ String cmd;
+ while ((cmd = br.readLine()) != null) {
+ log("cmd : " + cmd, Project.MSG_INFO);
+ output.append(cmd).append(" : ");
+ executeCommand(session, cmd, output);
+ output.append("\n");
+ }
+ FileUtils.close(br);
+ } catch (final IOException e) {
+ if (getFailonerror()) {
+ throw new BuildException(e);
+ } else {
+ log("Caught exception: " + e.getMessage(),
+ Project.MSG_ERR);
+ }
+ }
+ }
+ } catch (final JSchException e) {
+ if (getFailonerror()) {
+ throw new BuildException(e);
+ } else {
+ log("Caught exception: " + e.getMessage(), Project.MSG_ERR);
+ }
+ } finally {
+ if (outputProperty != null) {
+ getProject().setNewProperty(outputProperty, output.toString());
+ }
+ if (session != null && session.isConnected()) {
+ session.disconnect();
+ }
+ }
+ }
+
+ private void executeCommand(final Session session, final String cmd, final StringBuffer sb)
+ throws BuildException {
+ final ByteArrayOutputStream out = new ByteArrayOutputStream();
+ final ByteArrayOutputStream errout = new ByteArrayOutputStream();
+ final OutputStream teeErr = suppressSystemErr ? errout : new TeeOutputStream(errout, KeepAliveOutputStream.wrapSystemErr());
+ final OutputStream tee = suppressSystemOut ? out : new TeeOutputStream(out, KeepAliveOutputStream.wrapSystemOut());
+
+ InputStream istream = null;
+ if (inputFile != null) {
+ try {
+ istream = new FileInputStream(inputFile);
+ } catch (final IOException e) {
+ // because we checked the existence before, this one
+ // shouldn't happen What if the file exists, but there
+ // are no read permissions?
+ log("Failed to read " + inputFile + " because of: "
+ + e.getMessage(), Project.MSG_WARN);
+ }
+ }
+ if (inputProperty != null) {
+ final String inputData = getProject().getProperty(inputProperty);
+ if (inputData != null) {
+ istream = new ByteArrayInputStream(inputData.getBytes());
+ }
+ }
+ if (inputString != null) {
+ istream = new ByteArrayInputStream(inputString.getBytes());
+ }
+
+ if (useSystemIn) {
+ istream = KeepAliveInputStream.wrapSystemIn();
+ }
+
+ try {
+ final ChannelExec channel;
+ session.setTimeout((int) maxwait);
+ /* execute the command */
+ channel = (ChannelExec) session.openChannel("exec");
+ channel.setCommand(cmd);
+ channel.setOutputStream(tee);
+ channel.setExtOutputStream(tee);
+ channel.setErrStream(teeErr);
+ if (istream != null) {
+ channel.setInputStream(istream);
+ }
+ channel.setPty(usePty);
+ channel.connect();
+ // wait for it to finish
+ thread =
+ new Thread() {
+ @Override
+ public void run() {
+ while (!channel.isClosed()) {
+ if (thread == null) {
+ return;
+ }
+ try {
+ sleep(RETRY_INTERVAL);
+ } catch (final Exception e) {
+ // ignored
+ }
+ }
+ }
+ };
+
+ thread.start();
+ thread.join(maxwait);
+
+ if (thread.isAlive()) {
+ // ran out of time
+ thread = null;
+ if (getFailonerror()) {
+ throw new BuildException(TIMEOUT_MESSAGE);
+ } else {
+ log(TIMEOUT_MESSAGE, Project.MSG_ERR);
+ }
+ } else {
+ // stdout to outputFile
+ if (outputFile != null) {
+ writeToFile(out.toString(), append, outputFile);
+ }
+ // set errorProperty
+ if (errorProperty != null) {
+ getProject().setNewProperty(errorProperty, errout.toString());
+ }
+ // stderr to errorFile
+ if (errorFile != null) {
+ writeToFile(errout.toString(), appenderr, errorFile);
+ }
+ // this is the wrong test if the remote OS is OpenVMS,
+ // but there doesn't seem to be a way to detect it.
+ final int ec = channel.getExitStatus();
+ // set resultproperty
+ if (resultProperty != null) {
+ getProject().setNewProperty(resultProperty, Integer.toString(ec));
+ }
+ if (ec != 0) {
+ final String msg = "Remote command failed with exit status " + ec;
+ if (getFailonerror()) {
+ throw new BuildException(msg);
+ } else {
+ log(msg, Project.MSG_ERR);
+ }
+ }
+ }
+ } catch (final BuildException e) {
+ throw e;
+ } catch (final JSchException e) {
+ if (e.getMessage().indexOf("session is down") >= 0) {
+ if (getFailonerror()) {
+ throw new BuildException(TIMEOUT_MESSAGE, e);
+ } else {
+ log(TIMEOUT_MESSAGE, Project.MSG_ERR);
+ }
+ } else {
+ if (getFailonerror()) {
+ throw new BuildException(e);
+ } else {
+ log("Caught exception: " + e.getMessage(),
+ Project.MSG_ERR);
+ }
+ }
+ } catch (final Exception e) {
+ if (getFailonerror()) {
+ throw new BuildException(e);
+ } else {
+ log("Caught exception: " + e.getMessage(), Project.MSG_ERR);
+ }
+ } finally {
+ sb.append(out.toString());
+ FileUtils.close(istream);
+ }
+ }
+
+ /**
+ * Writes a string to a file. If destination file exists, it may be
+ * overwritten depending on the "append" value.
+ *
+ * @param from string to write
+ * @param to file to write to
+ * @param append if true, append to existing file, else overwrite
+ * @exception Exception most likely an IOException
+ */
+ private void writeToFile(final String from, final boolean append, final File to)
+ throws IOException {
+ FileWriter out = null;
+ try {
+ out = new FileWriter(to.getAbsolutePath(), append);
+ final StringReader in = new StringReader(from);
+ final char[] buffer = new char[BUFFER_SIZE];
+ int bytesRead;
+ while (true) {
+ bytesRead = in.read(buffer);
+ if (bytesRead == -1) {
+ break;
+ }
+ out.write(buffer, 0, bytesRead);
+ }
+ out.flush();
+ } finally {
+ if (out != null) {
+ out.close();
+ }
+ }
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ssh/SSHSession.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ssh/SSHSession.java
new file mode 100644
index 00000000..e9f26757
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ssh/SSHSession.java
@@ -0,0 +1,333 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.ssh;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.TaskContainer;
+
+import com.jcraft.jsch.JSchException;
+import com.jcraft.jsch.Session;
+
+
+/**
+ * Establishes an ssh session with a remote machine, optionally
+ * establishing port forwarding, then executes any nested task(s)
+ * before closing the session.
+ * @since Ant 1.8.0
+ */
+public class SSHSession extends SSHBase {
+
+ /** units are milliseconds, default is 0=infinite */
+ private long maxwait = 0;
+
+ private final Vector localTunnels = new Vector();
+ private final Set localPortsUsed = new TreeSet();
+ private final Vector remoteTunnels = new Vector();
+ private final Set remotePortsUsed = new TreeSet();
+ private NestedSequential nestedSequential = null;
+
+ private static final String TIMEOUT_MESSAGE =
+ "Timeout period exceeded, connection dropped.";
+
+
+ /** Optional Vector holding the nested tasks */
+ private final Vector nestedTasks = new Vector();
+
+ /**
+ * Add a nested task to Sequential.
+ * <p>
+ * @param nestedTask Nested task to execute Sequential
+ * <p>
+ */
+ public void addTask(final Task nestedTask) {
+ nestedTasks.addElement(nestedTask);
+ }
+
+ /**
+ * The connection can be dropped after a specified number of
+ * milliseconds. This is sometimes useful when a connection may be
+ * flaky. Default is 0, which means &quot;wait forever&quot;.
+ *
+ * @param timeout The new timeout value in seconds
+ */
+ public void setTimeout(final long timeout) {
+ maxwait = timeout;
+ }
+
+ /**
+ * Changes the comma-delimited list of local tunnels to establish
+ * on the connection.
+ *
+ * @param tunnels a comma-delimited list of lport:rhost:rport
+ * tunnel specifications
+ */
+ public void setLocaltunnels(final String tunnels) {
+ final String[] specs = tunnels.split(", ");
+ for (int i = 0; i < specs.length; i++) {
+ if (specs[i].length() > 0) {
+ final String[] spec = specs[i].split(":", 3);
+ final int lport = Integer.parseInt(spec[0]);
+ final String rhost = spec[1];
+ final int rport = Integer.parseInt(spec[2]);
+ final LocalTunnel tunnel = createLocalTunnel();
+ tunnel.setLPort(lport);
+ tunnel.setRHost(rhost);
+ tunnel.setRPort(rport);
+ }
+ }
+ }
+
+ /**
+ * Changes the comma-delimited list of remote tunnels to establish
+ * on the connection.
+ *
+ * @param tunnels a comma-delimited list of rport:lhost:lport
+ * tunnel specifications
+ */
+ public void setRemotetunnels(final String tunnels) {
+ final String[] specs = tunnels.split(", ");
+ for (int i = 0; i < specs.length; i++) {
+ if (specs[i].length() > 0) {
+ final String[] spec = specs[i].split(":", 3);
+ final int rport = Integer.parseInt(spec[0]);
+ final String lhost = spec[1];
+ final int lport = Integer.parseInt(spec[2]);
+ final RemoteTunnel tunnel = createRemoteTunnel();
+ tunnel.setRPort(rport);
+ tunnel.setLHost(lhost);
+ tunnel.setLPort(lport);
+ }
+ }
+ }
+
+
+ /**
+ * Establish the ssh session and execute all nestedTasks
+ *
+ * @exception BuildException if one of the nested tasks fails, or
+ * network error or bad parameter.
+ */
+ @Override
+ public void execute() throws BuildException {
+ if (getHost() == null) {
+ throw new BuildException("Host is required.");
+ }
+ if (getUserInfo().getName() == null) {
+ throw new BuildException("Username is required.");
+ }
+ if (getUserInfo().getKeyfile() == null
+ && getUserInfo().getPassword() == null) {
+ throw new BuildException("Password or Keyfile is required.");
+ }
+ if (nestedSequential == null) {
+ throw new BuildException("Missing sequential element.");
+ }
+
+
+ Session session = null;
+ try {
+ // establish the session
+ session = openSession();
+ session.setTimeout((int) maxwait);
+
+ for (final Iterator i = localTunnels.iterator(); i.hasNext();) {
+ final LocalTunnel tunnel = (LocalTunnel) i.next();
+ session.setPortForwardingL(tunnel.getLPort(),
+ tunnel.getRHost(),
+ tunnel.getRPort());
+ }
+
+ for (final Iterator i = remoteTunnels.iterator(); i.hasNext();) {
+ final RemoteTunnel tunnel = (RemoteTunnel) i.next();
+ session.setPortForwardingR(tunnel.getRPort(),
+ tunnel.getLHost(),
+ tunnel.getLPort());
+ }
+
+ for (final Iterator i = nestedSequential.getNested().iterator();
+ i.hasNext();) {
+ final Task nestedTask = (Task) i.next();
+ nestedTask.perform();
+ }
+ // completed successfully
+
+ } catch (final JSchException e) {
+ if (e.getMessage().indexOf("session is down") >= 0) {
+ if (getFailonerror()) {
+ throw new BuildException(TIMEOUT_MESSAGE, e);
+ } else {
+ log(TIMEOUT_MESSAGE, Project.MSG_ERR);
+ }
+ } else {
+ if (getFailonerror()) {
+ throw new BuildException(e);
+ } else {
+ log("Caught exception: " + e.getMessage(),
+ Project.MSG_ERR);
+ }
+ }
+ } catch (final BuildException e) {
+ // avoid wrapping it into yet another BuildException further down
+ throw e;
+ } catch (final Exception e) {
+ if (getFailonerror()) {
+ throw new BuildException(e);
+ } else {
+ log("Caught exception: " + e.getMessage(), Project.MSG_ERR);
+ }
+ } finally {
+ if (session != null && session.isConnected()) {
+ session.disconnect();
+ }
+ }
+ }
+
+ public LocalTunnel createLocalTunnel() {
+ final LocalTunnel tunnel = new LocalTunnel();
+ localTunnels.add(tunnel);
+ return tunnel;
+ }
+
+ public RemoteTunnel createRemoteTunnel() {
+ final RemoteTunnel tunnel = new RemoteTunnel();
+ remoteTunnels.add(tunnel);
+ return tunnel;
+ }
+
+ public class LocalTunnel {
+ public LocalTunnel() {}
+
+ int lport = 0;
+ String rhost = null;
+ int rport = 0;
+ public void setLPort(final int lport) {
+ final Integer portKey = new Integer(lport);
+ if (localPortsUsed.contains(portKey)) {
+ throw new BuildException("Multiple local tunnels defined to"
+ + " use same local port " + lport);
+ }
+ localPortsUsed.add(portKey);
+ this.lport = lport;
+ }
+ public void setRHost(final String rhost) { this.rhost = rhost; }
+ public void setRPort(final int rport) { this.rport = rport; }
+ public int getLPort() {
+ if (lport == 0) {
+ throw new BuildException("lport is required for LocalTunnel.");
+ }
+ return lport;
+ }
+ public String getRHost() {
+ if (rhost == null) {
+ throw new BuildException("rhost is required for LocalTunnel.");
+ }
+ return rhost;
+ }
+ public int getRPort() {
+ if (rport == 0) {
+ throw new BuildException("rport is required for LocalTunnel.");
+ }
+ return rport;
+ }
+ }
+
+ public class RemoteTunnel {
+ public RemoteTunnel() {}
+
+ int lport = 0;
+ String lhost = null;
+ int rport = 0;
+ public void setLPort(final int lport) { this.lport = lport; }
+ public void setLHost(final String lhost) { this.lhost = lhost; }
+ public void setRPort(final int rport) {
+ final Integer portKey = new Integer(rport);
+ if (remotePortsUsed.contains(portKey)) {
+ throw new BuildException("Multiple remote tunnels defined to"
+ + " use same remote port " + rport);
+ }
+ remotePortsUsed.add(portKey);
+ this.rport = rport;
+ }
+ public int getLPort() {
+ if (lport == 0) {
+ throw new BuildException("lport is required for RemoteTunnel.");
+ }
+ return lport;
+ }
+ public String getLHost() {
+ if (lhost == null) {
+ throw new BuildException("lhost is required for RemoteTunnel.");
+ }
+ return lhost;
+ }
+ public int getRPort() {
+ if (rport == 0) {
+ throw new BuildException("rport is required for RemoteTunnel.");
+ }
+ return rport;
+ }
+ }
+
+ /**
+ * This is the sequential nested element of the macrodef.
+ *
+ * @return a sequential element to be configured.
+ */
+ public NestedSequential createSequential() {
+ if (this.nestedSequential != null) {
+ throw new BuildException("Only one sequential allowed");
+ }
+ this.nestedSequential = new NestedSequential();
+ return this.nestedSequential;
+ }
+
+ /**
+ * The class corresponding to the sequential nested element.
+ * This is a simple task container.
+ */
+ public static class NestedSequential implements TaskContainer {
+ private final List<Task> nested = new ArrayList<Task>();
+
+ /**
+ * Add a task or type to the container.
+ *
+ * @param task an unknown element.
+ */
+ public void addTask(final Task task) {
+ nested.add(task);
+ }
+
+ /**
+ * @return the list of unknown elements
+ */
+ public List<Task> getNested() {
+ return nested;
+ }
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ssh/SSHUserInfo.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ssh/SSHUserInfo.java
new file mode 100644
index 00000000..54e70293
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ssh/SSHUserInfo.java
@@ -0,0 +1,217 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.ssh;
+
+import com.jcraft.jsch.UIKeyboardInteractive;
+import com.jcraft.jsch.UserInfo;
+
+
+/**
+ * Class containing information on an SSH user.
+ */
+public class SSHUserInfo implements UserInfo, UIKeyboardInteractive {
+
+ private String name;
+ private String password = null;
+ private String keyfile;
+ private String passphrase = null;
+ private boolean trustAllCertificates;
+
+ /** Constructor for SSHUserInfo. */
+ public SSHUserInfo() {
+ super();
+ this.trustAllCertificates = false;
+ }
+
+ /**
+ * Constructor for SSHUserInfo.
+ * @param password the user's password
+ * @param trustAllCertificates if true trust hosts whose identity is unknown
+ */
+ public SSHUserInfo(String password, boolean trustAllCertificates) {
+ super();
+ this.password = password;
+ this.trustAllCertificates = trustAllCertificates;
+ }
+
+ /**
+ * Gets the user name.
+ * @return the user name
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Gets the pass phrase of the user.
+ * @param message a message
+ * @return the passphrase
+ */
+ public String getPassphrase(String message) {
+ return passphrase;
+ }
+
+ /**
+ * Gets the user's password.
+ * @return the user's password
+ */
+ public String getPassword() {
+ return password;
+ }
+
+ /**
+ * Prompts a string.
+ * @param str the string
+ * @return whether the string was prompted
+ */
+ public boolean prompt(String str) {
+ return false;
+ }
+
+ /**
+ * Indicates whether a retry was done.
+ * @return whether a retry was done
+ */
+ public boolean retry() {
+ return false;
+ }
+
+ /**
+ * Sets the name.
+ * @param name The name to set
+ */
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ /**
+ * Sets the passphrase.
+ * @param passphrase The passphrase to set
+ */
+ public void setPassphrase(String passphrase) {
+ this.passphrase = passphrase;
+ }
+
+ /**
+ * Sets the password.
+ * @param password The password to set
+ */
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ /**
+ * Sets the trust.
+ * @param trust whether to trust or not.
+ */
+ public void setTrust(boolean trust) {
+ this.trustAllCertificates = trust;
+ }
+
+ /**
+ * @return whether to trust or not.
+ */
+ public boolean getTrust() {
+ return this.trustAllCertificates;
+ }
+
+ /**
+ * Returns the passphrase.
+ * @return String
+ */
+ public String getPassphrase() {
+ return passphrase;
+ }
+
+ /**
+ * Returns the keyfile.
+ * @return String
+ */
+ public String getKeyfile() {
+ return keyfile;
+ }
+
+ /**
+ * Sets the keyfile.
+ * @param keyfile The keyfile to set
+ */
+ public void setKeyfile(String keyfile) {
+ this.keyfile = keyfile;
+ }
+
+ /**
+ * Implement the UserInfo interface.
+ * @param message ignored
+ * @return true always
+ */
+ public boolean promptPassphrase(String message) {
+ return true;
+ }
+
+ /**
+ * Implement the UserInfo interface.
+ * @param passwordPrompt ignored
+ * @return true the first time this is called, false otherwise
+ */
+ public boolean promptPassword(String passwordPrompt) {
+ return true;
+ }
+
+ /**
+ * Implement the UserInfo interface.
+ * @param message ignored
+ * @return the value of trustAllCertificates
+ */
+ public boolean promptYesNo(String message) {
+ return trustAllCertificates;
+ }
+
+//why do we do nothing?
+ /**
+ * Implement the UserInfo interface (noop).
+ * @param message ignored
+ */
+ public void showMessage(String message) {
+ //log(message, Project.MSG_DEBUG);
+ }
+
+ /**
+ * Implementation of UIKeyboardInteractive#promptKeyboardInteractive.
+ * @param destination not used.
+ * @param name not used.
+ * @param instruction not used.
+ * @param prompt the method checks if this is one in length.
+ * @param echo the method checks if the first element is false.
+ * @return the password in an size one array if there is a password
+ * and if the prompt and echo checks pass.
+ */
+ public String[] promptKeyboardInteractive(String destination,
+ String name,
+ String instruction,
+ String[] prompt,
+ boolean[] echo) {
+ if (prompt.length != 1 || echo[0] || this.password == null) {
+ return null;
+ }
+ String[] response = new String[1];
+ response[0] = this.password;
+ return response;
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ssh/Scp.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ssh/Scp.java
new file mode 100644
index 00000000..46e2ac64
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ssh/Scp.java
@@ -0,0 +1,486 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.ssh;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.DirectoryScanner;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.FileSet;
+
+import com.jcraft.jsch.JSchException;
+import com.jcraft.jsch.Session;
+
+/**
+ * Ant task for sending files to remote machine over ssh/scp.
+ *
+ * @since Ant 1.6
+ */
+public class Scp extends SSHBase {
+
+ private static final String[] FROM_ATTRS = {
+ "file", "localfile", "remotefile" };
+
+ private static final String[] TO_ATTRS = {
+ "todir", "localtodir", "remotetodir", "localtofile", "remotetofile" };
+
+ private String fromUri;
+ private String toUri;
+ private boolean preserveLastModified = false;
+ private List fileSets = null;
+ private boolean isFromRemote, isToRemote;
+ private boolean isSftp = false;
+ private Integer fileMode, dirMode;
+
+ /**
+ * Sets the file to be transferred. This can either be a remote
+ * file or a local file. Remote files take the form:<br>
+ * <i>user:password@host:/directory/path/file.example</i><br>
+ * Files to transfer can also include a wildcard to include all
+ * files in a remote directory. For example:<br>
+ * <i>user:password@host:/directory/path/*</i><br>
+ * @param aFromUri a string representing the file to transfer.
+ */
+ public void setFile(final String aFromUri) {
+ setFromUri(aFromUri);
+ this.isFromRemote = isRemoteUri(this.fromUri);
+ }
+
+ /**
+ * Sets the location where files will be transferred to.
+ * This can either be a remote directory or a local directory.
+ * Remote directories take the form of:<br>
+ * <i>user:password@host:/directory/path/</i><br>
+ * This parameter is required.
+
+ * @param aToUri a string representing the target of the copy.
+ */
+ public void setTodir(final String aToUri) {
+ setToUri(aToUri);
+ this.isToRemote = isRemoteUri(this.toUri);
+ }
+
+ /**
+ * Similar to {@link #setFile setFile} but explicitly states that
+ * the file is a local file. This is the only way to specify a
+ * local file with a @ character.
+ * @param aFromUri a string representing the source of the copy.
+ * @since Ant 1.6.2
+ */
+ public void setLocalFile(final String aFromUri) {
+ setFromUri(aFromUri);
+ this.isFromRemote = false;
+ }
+
+ /**
+ * Similar to {@link #setFile setFile} but explicitly states that
+ * the file is a remote file.
+ * @param aFromUri a string representing the source of the copy.
+ * @since Ant 1.6.2
+ */
+ public void setRemoteFile(final String aFromUri) {
+ validateRemoteUri("remoteFile", aFromUri);
+ setFromUri(aFromUri);
+ this.isFromRemote = true;
+ }
+
+ /**
+ * Similar to {@link #setTodir setTodir} but explicitly states
+ * that the directory is a local. This is the only way to specify
+ * a local directory with a @ character.
+ * @param aToUri a string representing the target of the copy.
+ * @since Ant 1.6.2
+ */
+ public void setLocalTodir(final String aToUri) {
+ setToUri(aToUri);
+ this.isToRemote = false;
+ }
+
+ /**
+ * Sets flag to determine if file timestamp from
+ * remote system is to be preserved during copy.
+ * @since Ant 1.8.0
+ */
+ public void setPreservelastmodified(final boolean yesOrNo) {
+ this.preserveLastModified = yesOrNo;
+ }
+
+ /**
+ * Similar to {@link #setTodir setTodir} but explicitly states
+ * that the directory is a remote.
+ * @param aToUri a string representing the target of the copy.
+ * @since Ant 1.6.2
+ */
+ public void setRemoteTodir(final String aToUri) {
+ validateRemoteUri("remoteToDir", aToUri);
+ setToUri(aToUri);
+ this.isToRemote = true;
+ }
+
+ private static void validateRemoteUri(final String type, final String aToUri) {
+ if (!isRemoteUri(aToUri)) {
+ throw new BuildException(type + " '" + aToUri + "' is invalid. "
+ + "The 'remoteToDir' attribute must "
+ + "have syntax like the "
+ + "following: user:password@host:/path"
+ + " - the :password part is optional");
+ }
+ }
+
+ /**
+ * Changes the file name to the given name while receiving it,
+ * only useful if receiving a single file.
+ * @param aToUri a string representing the target of the copy.
+ * @since Ant 1.6.2
+ */
+ public void setLocalTofile(final String aToUri) {
+ setToUri(aToUri);
+ this.isToRemote = false;
+ }
+
+ /**
+ * Changes the file name to the given name while sending it,
+ * only useful if sending a single file.
+ * @param aToUri a string representing the target of the copy.
+ * @since Ant 1.6.2
+ */
+ public void setRemoteTofile(final String aToUri) {
+ validateRemoteUri("remoteToFile", aToUri);
+ setToUri(aToUri);
+ this.isToRemote = true;
+ }
+
+ /**
+ * Setting this to true to use sftp protocol.
+ *
+ * @param yesOrNo if true sftp protocol will be used.
+ */
+ public void setSftp(final boolean yesOrNo) {
+ isSftp = yesOrNo;
+ }
+
+ /**
+ * Set the file mode, defaults to "644".
+ * @since Ant 1.9.5
+ */
+ public void setFileMode(String fileMode) {
+ this.fileMode = Integer.parseInt(fileMode, 8);
+ }
+
+ /**
+ * Set the dir mode, defaults to "755".
+ * @since Ant 1.9.5
+ */
+ public void setDirMode(String dirMode) {
+ this.dirMode = Integer.parseInt(dirMode, 8);
+ }
+
+ /**
+ * Adds a FileSet transfer to remote host. NOTE: Either
+ * addFileSet() or setFile() are required. But, not both.
+ *
+ * @param set FileSet to send to remote host.
+ */
+ public void addFileset(final FileSet set) {
+ if (fileSets == null) {
+ fileSets = new LinkedList();
+ }
+ fileSets.add(set);
+ }
+
+ /**
+ * Initialize this task.
+ * @throws BuildException on error
+ */
+ @Override
+ public void init() throws BuildException {
+ super.init();
+ this.toUri = null;
+ this.fromUri = null;
+ this.fileSets = null;
+ }
+
+ /**
+ * Execute this task.
+ * @throws BuildException on error
+ */
+ @Override
+ public void execute() throws BuildException {
+ if (toUri == null) {
+ throw exactlyOne(TO_ATTRS);
+ }
+ if (fromUri == null && fileSets == null) {
+ throw exactlyOne(FROM_ATTRS, "one or more nested filesets");
+ }
+ try {
+ if (isFromRemote && !isToRemote) {
+ download(fromUri, toUri);
+ } else if (!isFromRemote && isToRemote) {
+ if (fileSets != null) {
+ upload(fileSets, toUri);
+ } else {
+ upload(fromUri, toUri);
+ }
+ } else if (isFromRemote && isToRemote) {
+ throw new BuildException(
+ "Copying from a remote server to a remote server is not supported.");
+ } else {
+ throw new BuildException("'todir' and 'file' attributes "
+ + "must have syntax like the following: "
+ + "user:password@host:/path");
+ }
+ } catch (final Exception e) {
+ if (getFailonerror()) {
+ if(e instanceof BuildException) {
+ final BuildException be = (BuildException) e;
+ if(be.getLocation() == null) {
+ be.setLocation(getLocation());
+ }
+ throw be;
+ } else {
+ throw new BuildException(e);
+ }
+ } else {
+ log("Caught exception: " + e.getMessage(), Project.MSG_ERR);
+ }
+ }
+ }
+
+ private void download(final String fromSshUri, final String toPath)
+ throws JSchException, IOException {
+ final String file = parseUri(fromSshUri);
+
+ Session session = null;
+ try {
+ session = openSession();
+ ScpFromMessage message = null;
+ if (!isSftp) {
+ message =
+ new ScpFromMessage(getVerbose(), session, file,
+ getProject().resolveFile(toPath),
+ fromSshUri.endsWith("*"),
+ preserveLastModified);
+ } else {
+ message =
+ new ScpFromMessageBySftp(getVerbose(), session, file,
+ getProject().resolveFile(toPath),
+ fromSshUri.endsWith("*"),
+ preserveLastModified);
+ }
+ log("Receiving file: " + file);
+ message.setLogListener(this);
+ message.execute();
+ } finally {
+ if (session != null) {
+ session.disconnect();
+ }
+ }
+ }
+
+ private void upload(final List fileSet, final String toSshUri)
+ throws IOException, JSchException {
+ final String file = parseUri(toSshUri);
+
+ Session session = null;
+ try {
+ final List list = new ArrayList(fileSet.size());
+ for (final Iterator i = fileSet.iterator(); i.hasNext();) {
+ final FileSet set = (FileSet) i.next();
+ final Directory d = createDirectory(set);
+ if (d != null) {
+ list.add(d);
+ }
+ }
+ if (!list.isEmpty()) {
+ session = openSession();
+ ScpToMessage message = null;
+ if (!isSftp) {
+ message = new ScpToMessage(getVerbose(), session,
+ list, file);
+ } else {
+ message = new ScpToMessageBySftp(getVerbose(), session,
+ list, file);
+ }
+ message.setLogListener(this);
+ if (fileMode != null) {
+ message.setFileMode(fileMode.intValue());
+ }
+ if (dirMode != null) {
+ message.setDirMode(dirMode.intValue());
+ }
+ message.execute();
+ }
+ } finally {
+ if (session != null) {
+ session.disconnect();
+ }
+ }
+ }
+
+ private void upload(final String fromPath, final String toSshUri)
+ throws IOException, JSchException {
+ final String file = parseUri(toSshUri);
+
+ Session session = null;
+ try {
+ session = openSession();
+ ScpToMessage message = null;
+ if (!isSftp) {
+ message =
+ new ScpToMessage(getVerbose(), session,
+ getProject().resolveFile(fromPath), file);
+ } else {
+ message =
+ new ScpToMessageBySftp(getVerbose(), session,
+ getProject().resolveFile(fromPath),
+ file);
+ }
+ message.setLogListener(this);
+ if (fileMode != null) {
+ message.setFileMode(fileMode.intValue());
+ }
+ if (dirMode != null) {
+ message.setDirMode(dirMode.intValue());
+ }
+ message.execute();
+ } finally {
+ if (session != null) {
+ session.disconnect();
+ }
+ }
+ }
+
+ private String parseUri(final String uri) {
+
+ int indexOfAt = uri.indexOf('@');
+ final int indexOfColon = uri.indexOf(':');
+
+ if (indexOfColon > -1 && indexOfColon < indexOfAt) {
+ // user:password@host:/path notation
+ // everything upto the last @ before the last : is considered
+ // password. (so if the path contains an @ and a : it will not work)
+ int indexOfCurrentAt = indexOfAt;
+ final int indexOfLastColon = uri.lastIndexOf(':');
+ while (indexOfCurrentAt > -1 && indexOfCurrentAt < indexOfLastColon)
+ {
+ indexOfAt = indexOfCurrentAt;
+ indexOfCurrentAt = uri.indexOf('@', indexOfCurrentAt + 1);
+ }
+ setUsername(uri.substring(0, indexOfColon));
+ setPassword(uri.substring(indexOfColon + 1, indexOfAt));
+ } else if (indexOfAt > -1) {
+ // no password, will require keyfile
+ setUsername(uri.substring(0, indexOfAt));
+ } else {
+ throw new BuildException("no username was given. Can't authenticate.");
+ }
+
+ if (getUserInfo().getPassword() == null
+ && getUserInfo().getKeyfile() == null) {
+ throw new BuildException("neither password nor keyfile for user "
+ + getUserInfo().getName() + " has been "
+ + "given. Can't authenticate.");
+ }
+
+ final int indexOfPath = uri.indexOf(':', indexOfAt + 1);
+ if (indexOfPath == -1) {
+ throw new BuildException("no remote path in " + uri);
+ }
+
+ setHost(uri.substring(indexOfAt + 1, indexOfPath));
+ String remotePath = uri.substring(indexOfPath + 1);
+ if (remotePath.equals("")) {
+ remotePath = ".";
+ }
+ return remotePath;
+ }
+
+ private static boolean isRemoteUri(final String uri) {
+ boolean isRemote = true;
+ final int indexOfAt = uri.indexOf('@');
+ if (indexOfAt < 0) {
+ isRemote = false;
+ }
+ return isRemote;
+ }
+
+ private Directory createDirectory(final FileSet set) {
+ final DirectoryScanner scanner = set.getDirectoryScanner(getProject());
+ Directory root = new Directory(scanner.getBasedir());
+ final String[] files = scanner.getIncludedFiles();
+ if (files.length != 0) {
+ for (int j = 0; j < files.length; j++) {
+ final String[] path = Directory.getPath(files[j]);
+ Directory current = root;
+ File currentParent = scanner.getBasedir();
+ for (int i = 0; i < path.length; i++) {
+ final File file = new File(currentParent, path[i]);
+ if (file.isDirectory()) {
+ current.addDirectory(new Directory(file));
+ current = current.getChild(file);
+ currentParent = current.getDirectory();
+ } else if (file.isFile()) {
+ current.addFile(file);
+ }
+ }
+ }
+ } else {
+ // skip
+ root = null;
+ }
+ return root;
+ }
+
+ private void setFromUri(final String fromUri) {
+ if (this.fromUri != null) {
+ throw exactlyOne(FROM_ATTRS);
+ }
+ this.fromUri = fromUri;
+ }
+
+ private void setToUri(final String toUri) {
+ if (this.toUri != null) {
+ throw exactlyOne(TO_ATTRS);
+ }
+ this.toUri = toUri;
+ }
+
+ private BuildException exactlyOne(final String[] attrs) {
+ return exactlyOne(attrs, null);
+ }
+
+ private BuildException exactlyOne(final String[] attrs, final String alt) {
+ final StringBuffer buf = new StringBuffer("Exactly one of ").append(
+ '[').append(attrs[0]);
+ for (int i = 1; i < attrs.length; i++) {
+ buf.append('|').append(attrs[i]);
+ }
+ buf.append(']');
+ if (alt != null) {
+ buf.append(" or ").append(alt);
+ }
+ return new BuildException(buf.append(" is required.").toString());
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ssh/ScpFromMessage.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ssh/ScpFromMessage.java
new file mode 100644
index 00000000..b6d47379
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ssh/ScpFromMessage.java
@@ -0,0 +1,311 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.ssh;
+
+import java.io.ByteArrayOutputStream;
+import java.io.EOFException;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.apache.tools.ant.util.FileUtils;
+
+import com.jcraft.jsch.Channel;
+import com.jcraft.jsch.ChannelSftp;
+import com.jcraft.jsch.JSchException;
+import com.jcraft.jsch.Session;
+import com.jcraft.jsch.SftpATTRS;
+import com.jcraft.jsch.SftpException;
+
+/**
+ * A helper object representing an scp download.
+ */
+public class ScpFromMessage extends AbstractSshMessage {
+
+ private static final int HUNDRED_KILOBYTES = 102400;
+ private static final byte LINE_FEED = 0x0a;
+ private static final int BUFFER_SIZE = 100*1024;
+
+ private String remoteFile;
+ private File localFile;
+ private boolean isRecursive = false;
+ private boolean preserveLastModified = false;
+
+ /**
+ * Constructor for ScpFromMessage
+ * @param session the ssh session to use
+ */
+ public ScpFromMessage(final Session session) {
+ super(session);
+ }
+
+ /**
+ * Constructor for ScpFromMessage
+ * @param verbose if true do verbose logging
+ * @param session the ssh session to use
+ * @since Ant 1.7
+ */
+ public ScpFromMessage(final boolean verbose, final Session session) {
+ super(verbose, session);
+ }
+
+ /**
+ * Constructor for ScpFromMessage.
+ * @param verbose if true log extra information
+ * @param session the Scp session to use
+ * @param aRemoteFile the remote file name
+ * @param aLocalFile the local file
+ * @param recursive if true use recursion (-r option to scp)
+ * @since Ant 1.6.2
+ */
+ public ScpFromMessage(final boolean verbose,
+ final Session session,
+ final String aRemoteFile,
+ final File aLocalFile,
+ final boolean recursive) {
+ this(false, session, aRemoteFile, aLocalFile, recursive, false);
+ }
+
+ /**
+ * Constructor for ScpFromMessage.
+ * @param session the Scp session to use
+ * @param aRemoteFile the remote file name
+ * @param aLocalFile the local file
+ * @param recursive if true use recursion (-r option to scp)
+ */
+ public ScpFromMessage(final Session session,
+ final String aRemoteFile,
+ final File aLocalFile,
+ final boolean recursive) {
+ this(false, session, aRemoteFile, aLocalFile, recursive);
+ }
+
+ /**
+ * Constructor for ScpFromMessage.
+ * @param verbose if true log extra information
+ * @param session the Scp session to use
+ * @param aRemoteFile the remote file name
+ * @param aLocalFile the local file
+ * @param recursive if true use recursion (-r option to scp)
+ * @param preserveLastModified whether to preserve file
+ * modification times
+ * @since Ant 1.8.0
+ */
+ public ScpFromMessage(final boolean verbose,
+ final Session session,
+ final String aRemoteFile,
+ final File aLocalFile,
+ final boolean recursive,
+ final boolean preserveLastModified) {
+ super(verbose, session);
+ this.remoteFile = aRemoteFile;
+ this.localFile = aLocalFile;
+ this.isRecursive = recursive;
+ this.preserveLastModified = preserveLastModified;
+ }
+
+ /**
+ * Carry out the transfer.
+ * @throws IOException on i/o errors
+ * @throws JSchException on errors detected by scp
+ */
+ public void execute() throws IOException, JSchException {
+ String command = "scp -f ";
+ if (isRecursive) {
+ command += "-r ";
+ }
+ command += remoteFile;
+ final Channel channel = openExecChannel(command);
+ try {
+ // get I/O streams for remote scp
+ final OutputStream out = channel.getOutputStream();
+ final InputStream in = channel.getInputStream();
+
+ channel.connect();
+
+ sendAck(out);
+ startRemoteCpProtocol(in, out, localFile);
+ } finally {
+ if (channel != null) {
+ channel.disconnect();
+ }
+ }
+ log("done\n");
+ }
+
+ protected boolean getPreserveLastModified() {
+ return preserveLastModified;
+ }
+
+ private void startRemoteCpProtocol(final InputStream in,
+ final OutputStream out,
+ final File localFile)
+ throws IOException, JSchException {
+ File startFile = localFile;
+ while (true) {
+ // C0644 filesize filename - header for a regular file
+ // T time 0 time 0\n - present if perserve time.
+ // D directory - this is the header for a directory.
+ final ByteArrayOutputStream stream = new ByteArrayOutputStream();
+ while (true) {
+ final int read = in.read();
+ if (read < 0) {
+ return;
+ }
+ if ((byte) read == LINE_FEED) {
+ break;
+ }
+ stream.write(read);
+ }
+ final String serverResponse = stream.toString("UTF-8");
+ if (serverResponse.charAt(0) == 'C') {
+ parseAndFetchFile(serverResponse, startFile, out, in);
+ } else if (serverResponse.charAt(0) == 'D') {
+ startFile = parseAndCreateDirectory(serverResponse,
+ startFile);
+ sendAck(out);
+ } else if (serverResponse.charAt(0) == 'E') {
+ startFile = startFile.getParentFile();
+ sendAck(out);
+ } else if (serverResponse.charAt(0) == '\01'
+ || serverResponse.charAt(0) == '\02') {
+ // this indicates an error.
+ throw new IOException(serverResponse.substring(1));
+ }
+ }
+ }
+
+ private File parseAndCreateDirectory(final String serverResponse,
+ final File localFile) {
+ int start = serverResponse.indexOf(" ");
+ // appears that the next token is not used and it's zero.
+ start = serverResponse.indexOf(" ", start + 1);
+ final String directoryName = serverResponse.substring(start + 1);
+ if (localFile.isDirectory()) {
+ final File dir = new File(localFile, directoryName);
+ dir.mkdir();
+ log("Creating: " + dir);
+ return dir;
+ }
+ return null;
+ }
+
+ private void parseAndFetchFile(final String serverResponse,
+ final File localFile,
+ final OutputStream out,
+ final InputStream in)
+ throws IOException, JSchException {
+ int start = 0;
+ int end = serverResponse.indexOf(" ", start + 1);
+ start = end + 1;
+ end = serverResponse.indexOf(" ", start + 1);
+ final long filesize = Long.parseLong(serverResponse.substring(start, end));
+ final String filename = serverResponse.substring(end + 1);
+ log("Receiving: " + filename + " : " + filesize);
+ final File transferFile = (localFile.isDirectory())
+ ? new File(localFile, filename)
+ : localFile;
+ fetchFile(transferFile, filesize, out, in);
+ waitForAck(in);
+ sendAck(out);
+ }
+
+ private void fetchFile(final File localFile,
+ long filesize,
+ final OutputStream out,
+ final InputStream in)
+ throws IOException, JSchException {
+ final byte[] buf = new byte[BUFFER_SIZE];
+ sendAck(out);
+
+ // read a content of lfile
+ final FileOutputStream fos = new FileOutputStream(localFile);
+ int length;
+ long totalLength = 0;
+ final long startTime = System.currentTimeMillis();
+
+ // only track progress for files larger than 100kb in verbose mode
+ final boolean trackProgress = getVerbose() && filesize > HUNDRED_KILOBYTES;
+ // since filesize keeps on decreasing we have to store the
+ // initial filesize
+ final long initFilesize = filesize;
+ int percentTransmitted = 0;
+
+ try {
+ while (true) {
+ length = in.read(buf, 0,
+ (BUFFER_SIZE < filesize) ? BUFFER_SIZE
+ : (int) filesize);
+ if (length < 0) {
+ throw new EOFException("Unexpected end of stream.");
+ }
+ fos.write(buf, 0, length);
+ filesize -= length;
+ totalLength += length;
+ if (filesize == 0) {
+ break;
+ }
+
+ if (trackProgress) {
+ percentTransmitted = trackProgress(initFilesize,
+ totalLength,
+ percentTransmitted);
+ }
+ }
+ } finally {
+ final long endTime = System.currentTimeMillis();
+ logStats(startTime, endTime, totalLength);
+ fos.flush();
+ fos.close();
+ }
+
+ if (getPreserveLastModified()) {
+ setLastModified(localFile);
+ }
+ }
+
+ private void setLastModified(final File localFile) throws JSchException {
+ SftpATTRS fileAttributes = null;
+ final ChannelSftp channel = openSftpChannel();
+ channel.connect();
+ try {
+ fileAttributes = channel.lstat(remoteDir(remoteFile)
+ + localFile.getName());
+ } catch (final SftpException e) {
+ throw new JSchException("failed to stat remote file", e);
+ }
+ FileUtils.getFileUtils().setFileLastModified(localFile,
+ ((long) fileAttributes
+ .getMTime())
+ * 1000);
+ }
+
+ /**
+ * returns the directory part of the remote file, if any.
+ */
+ private static String remoteDir(final String remoteFile) {
+ int index = remoteFile.lastIndexOf("/");
+ if (index < 0) {
+ index = remoteFile.lastIndexOf("\\");
+ }
+ return index > -1 ? remoteFile.substring(0, index + 1) : "";
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ssh/ScpFromMessageBySftp.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ssh/ScpFromMessageBySftp.java
new file mode 100644
index 00000000..04f72d23
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ssh/ScpFromMessageBySftp.java
@@ -0,0 +1,205 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.ssh;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.tools.ant.util.FileUtils;
+
+import com.jcraft.jsch.ChannelSftp;
+import com.jcraft.jsch.JSchException;
+import com.jcraft.jsch.Session;
+import com.jcraft.jsch.SftpATTRS;
+import com.jcraft.jsch.SftpException;
+import com.jcraft.jsch.SftpProgressMonitor;
+
+/**
+ * A helper object representing an scp download.
+ */
+public class ScpFromMessageBySftp extends ScpFromMessage {
+
+ private static final int HUNDRED_KILOBYTES = 102400;
+
+ private String remoteFile;
+ private final File localFile;
+ private boolean isRecursive = false;
+ private boolean verbose = false;
+
+ /**
+ * Constructor for ScpFromMessageBySftp.
+ * @param verbose if true log extra information
+ * @param session the Scp session to use
+ * @param aRemoteFile the remote file name
+ * @param aLocalFile the local file
+ * @param recursive if true use recursion
+ * @since Ant 1.7
+ */
+ public ScpFromMessageBySftp(final boolean verbose,
+ final Session session,
+ final String aRemoteFile,
+ final File aLocalFile,
+ final boolean recursive) {
+ this(verbose, session, aRemoteFile, aLocalFile, recursive, false);
+ }
+
+ /**
+ * Constructor for ScpFromMessageBySftp.
+ * @param session the Scp session to use
+ * @param aRemoteFile the remote file name
+ * @param aLocalFile the local file
+ * @param recursive if true use recursion
+ */
+ public ScpFromMessageBySftp(final Session session,
+ final String aRemoteFile,
+ final File aLocalFile,
+ final boolean recursive) {
+ this(false, session, aRemoteFile, aLocalFile, recursive);
+ }
+
+ /**
+ * Constructor for ScpFromMessageBySftp.
+ * @param verbose if true log extra information
+ * @param session the Scp session to use
+ * @param aRemoteFile the remote file name
+ * @param aLocalFile the local file
+ * @param recursive if true use recursion
+ * @param preserveLastModified whether to preserve file
+ * modification times
+ * @since Ant 1.8.0
+ */
+ public ScpFromMessageBySftp(final boolean verbose,
+ final Session session,
+ final String aRemoteFile,
+ final File aLocalFile,
+ final boolean recursive,
+ final boolean preserveLastModified) {
+ super(verbose, session, aRemoteFile, aLocalFile, recursive,
+ preserveLastModified);
+ this.verbose = verbose;
+ this.remoteFile = aRemoteFile;
+ this.localFile = aLocalFile;
+ this.isRecursive = recursive;
+ }
+
+ /**
+ * Carry out the transfer.
+ * @throws IOException on i/o errors
+ * @throws JSchException on errors detected by scp
+ */
+ public void execute() throws IOException, JSchException {
+ final ChannelSftp channel = openSftpChannel();
+ try {
+ channel.connect();
+ try {
+ final SftpATTRS attrs = channel.stat(remoteFile);
+ if (attrs.isDir() && !remoteFile.endsWith("/")) {
+ remoteFile = remoteFile + "/";
+ }
+ } catch (final SftpException ee) {
+ // Ignored
+ }
+ getDir(channel, remoteFile, localFile);
+ } catch (final SftpException e) {
+ final JSchException schException = new JSchException("Could not get '"+ remoteFile
+ +"' to '"+localFile+"' - "
+ +e.toString());
+ schException.initCause(e);
+ throw schException;
+ } finally {
+ if (channel != null) {
+ channel.disconnect();
+ }
+ }
+ log("done\n");
+ }
+
+ private void getDir(final ChannelSftp channel,
+ final String remoteFile,
+ final File localFile) throws IOException, SftpException {
+ String pwd = remoteFile;
+ if (remoteFile.lastIndexOf('/') != -1) {
+ if (remoteFile.length() > 1) {
+ pwd = remoteFile.substring(0, remoteFile.lastIndexOf('/'));
+ }
+ }
+ channel.cd(pwd);
+ if (!localFile.exists()) {
+ localFile.mkdirs();
+ }
+ final java.util.Vector files = channel.ls(remoteFile);
+ final int size = files.size();
+ for (int i = 0; i < size; i++) {
+ final ChannelSftp.LsEntry le = (ChannelSftp.LsEntry) files.elementAt(i);
+ final String name = le.getFilename();
+ if (le.getAttrs().isDir()) {
+ if (name.equals(".") || name.equals("..")) {
+ continue;
+ }
+ getDir(channel,
+ channel.pwd() + "/" + name + "/",
+ new File(localFile, le.getFilename()));
+ } else {
+ getFile(channel, le, localFile);
+ }
+ }
+ channel.cd("..");
+ }
+
+ private void getFile(final ChannelSftp channel,
+ final ChannelSftp.LsEntry le,
+ File localFile) throws IOException, SftpException {
+ final String remoteFile = le.getFilename();
+ if (!localFile.exists()) {
+ final String path = localFile.getAbsolutePath();
+ final int i = path.lastIndexOf(File.pathSeparator);
+ if (i != -1) {
+ if (path.length() > File.pathSeparator.length()) {
+ new File(path.substring(0, i)).mkdirs();
+ }
+ }
+ }
+
+ if (localFile.isDirectory()) {
+ localFile = new File(localFile, remoteFile);
+ }
+
+ final long startTime = System.currentTimeMillis();
+ final long totalLength = le.getAttrs().getSize();
+
+ SftpProgressMonitor monitor = null;
+ final boolean trackProgress = getVerbose() && totalLength > HUNDRED_KILOBYTES;
+ if (trackProgress) {
+ monitor = getProgressMonitor();
+ }
+ try {
+ log("Receiving: " + remoteFile + " : " + le.getAttrs().getSize());
+ channel.get(remoteFile, localFile.getAbsolutePath(), monitor);
+ } finally {
+ final long endTime = System.currentTimeMillis();
+ logStats(startTime, endTime, (int) totalLength);
+ }
+ if (getPreserveLastModified()) {
+ FileUtils.getFileUtils().setFileLastModified(localFile,
+ ((long) le.getAttrs()
+ .getMTime())
+ * 1000);
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ssh/ScpToMessage.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ssh/ScpToMessage.java
new file mode 100644
index 00000000..5ba6b559
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ssh/ScpToMessage.java
@@ -0,0 +1,331 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.ssh;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Iterator;
+import java.util.List;
+
+import com.jcraft.jsch.Channel;
+import com.jcraft.jsch.JSchException;
+import com.jcraft.jsch.Session;
+
+/**
+ * Utility class to carry out an upload scp transfer.
+ */
+public class ScpToMessage extends AbstractSshMessage {
+
+ private static final int HUNDRED_KILOBYTES = 102400;
+ private static final int BUFFER_SIZE = 100*1024;
+ private static final int DEFAULT_DIR_MODE = 0755;
+ private static final int DEFAULT_FILE_MODE = 0644;
+
+ private File localFile;
+ private String remotePath;
+ private List directoryList;
+ private Integer fileMode, dirMode;
+
+ /**
+ * Constructor for ScpToMessage
+ * @param session the ssh session to use
+ */
+ public ScpToMessage(final Session session) {
+ super(session);
+ }
+
+ /**
+ * Constructor for ScpToMessage
+ * @param verbose if true do verbose logging
+ * @param session the ssh session to use
+ * @since Ant 1.7
+ */
+ public ScpToMessage(final boolean verbose, final Session session) {
+ super(verbose, session);
+ }
+
+ /**
+ * Constructor for a local file to remote.
+ * @param verbose if true do verbose logging
+ * @param session the scp session to use
+ * @param aLocalFile the local file
+ * @param aRemotePath the remote path
+ * @since Ant 1.6.2
+ */
+ public ScpToMessage(final boolean verbose,
+ final Session session,
+ final File aLocalFile,
+ final String aRemotePath) {
+ this(verbose, session, aRemotePath);
+
+ this.localFile = aLocalFile;
+ }
+
+ /**
+ * Constructor for a local directories to remote.
+ * @param verbose if true do verbose logging
+ * @param session the scp session to use
+ * @param aDirectoryList a list of directories
+ * @param aRemotePath the remote path
+ * @since Ant 1.6.2
+ */
+ public ScpToMessage(final boolean verbose,
+ final Session session,
+ final List aDirectoryList,
+ final String aRemotePath) {
+ this(verbose, session, aRemotePath);
+
+ this.directoryList = aDirectoryList;
+ }
+
+ /**
+ * Constructor for ScpToMessage.
+ * @param verbose if true do verbose logging
+ * @param session the scp session to use
+ * @param aRemotePath the remote path
+ * @since Ant 1.6.2
+ */
+ private ScpToMessage(final boolean verbose,
+ final Session session,
+ final String aRemotePath) {
+ super(verbose, session);
+ this.remotePath = aRemotePath;
+ }
+
+ /**
+ * Constructor for ScpToMessage.
+ * @param session the scp session to use
+ * @param aLocalFile the local file
+ * @param aRemotePath the remote path
+ */
+ public ScpToMessage(final Session session,
+ final File aLocalFile,
+ final String aRemotePath) {
+ this(false, session, aLocalFile, aRemotePath);
+ }
+
+ /**
+ * Constructor for ScpToMessage.
+ * @param session the scp session to use
+ * @param aDirectoryList a list of directories
+ * @param aRemotePath the remote path
+ */
+ public ScpToMessage(final Session session,
+ final List aDirectoryList,
+ final String aRemotePath) {
+ this(false, session, aDirectoryList, aRemotePath);
+ }
+
+ /**
+ * Carry out the transfer.
+ * @throws IOException on i/o errors
+ * @throws JSchException on errors detected by scp
+ */
+ @Override
+ public void execute() throws IOException, JSchException {
+ if (directoryList != null) {
+ doMultipleTransfer();
+ }
+ if (localFile != null) {
+ doSingleTransfer();
+ }
+ log("done.\n");
+ }
+
+ private void doSingleTransfer() throws IOException, JSchException {
+ final String cmd = "scp -t " + remotePath;
+ final Channel channel = openExecChannel(cmd);
+ try {
+
+ final OutputStream out = channel.getOutputStream();
+ final InputStream in = channel.getInputStream();
+
+ channel.connect();
+
+ waitForAck(in);
+ sendFileToRemote(localFile, in, out);
+ } finally {
+ if (channel != null) {
+ channel.disconnect();
+ }
+ }
+ }
+
+ private void doMultipleTransfer() throws IOException, JSchException {
+ final Channel channel = openExecChannel("scp -r -d -t " + remotePath);
+ try {
+ final OutputStream out = channel.getOutputStream();
+ final InputStream in = channel.getInputStream();
+
+ channel.connect();
+
+ waitForAck(in);
+ for (final Iterator i = directoryList.iterator(); i.hasNext();) {
+ final Directory current = (Directory) i.next();
+ sendDirectory(current, in, out);
+ }
+ } finally {
+ if (channel != null) {
+ channel.disconnect();
+ }
+ }
+ }
+
+ private void sendDirectory(final Directory current,
+ final InputStream in,
+ final OutputStream out) throws IOException {
+ for (final Iterator fileIt = current.filesIterator(); fileIt.hasNext();) {
+ sendFileToRemote((File) fileIt.next(), in, out);
+ }
+ for (final Iterator dirIt = current.directoryIterator(); dirIt.hasNext();) {
+ final Directory dir = (Directory) dirIt.next();
+ sendDirectoryToRemote(dir, in, out);
+ }
+ }
+
+ private void sendDirectoryToRemote(final Directory directory,
+ final InputStream in,
+ final OutputStream out) throws IOException {
+ String command = "D0";
+ command += Integer.toOctalString(getDirMode());
+ command += " 0 ";
+ command += directory.getDirectory().getName();
+ command += "\n";
+
+ out.write(command.getBytes());
+ out.flush();
+
+ waitForAck(in);
+ sendDirectory(directory, in, out);
+ out.write("E\n".getBytes());
+ out.flush();
+ waitForAck(in);
+ }
+
+ private void sendFileToRemote(final File localFile,
+ final InputStream in,
+ final OutputStream out) throws IOException {
+ // send "C0644 filesize filename", where filename should not include '/'
+ final long filesize = localFile.length();
+ String command = "C0";
+ command += Integer.toOctalString(getFileMode());
+ command += " " + filesize + " ";
+ command += localFile.getName();
+ command += "\n";
+
+ out.write(command.getBytes());
+ out.flush();
+
+ waitForAck(in);
+
+ // send a content of lfile
+ final FileInputStream fis = new FileInputStream(localFile);
+ final byte[] buf = new byte[BUFFER_SIZE];
+ final long startTime = System.currentTimeMillis();
+ long totalLength = 0;
+
+ // only track progress for files larger than 100kb in verbose mode
+ final boolean trackProgress = getVerbose() && filesize > HUNDRED_KILOBYTES;
+ // since filesize keeps on decreasing we have to store the
+ // initial filesize
+ final long initFilesize = filesize;
+ int percentTransmitted = 0;
+
+ try {
+ if (this.getVerbose()) {
+ log("Sending: " + localFile.getName() + " : " + localFile.length());
+ }
+ while (true) {
+ final int len = fis.read(buf, 0, buf.length);
+ if (len <= 0) {
+ break;
+ }
+ out.write(buf, 0, len);
+ totalLength += len;
+
+ if (trackProgress) {
+ percentTransmitted = trackProgress(initFilesize,
+ totalLength,
+ percentTransmitted);
+ }
+ }
+ out.flush();
+ sendAck(out);
+ waitForAck(in);
+ } finally {
+ if (this.getVerbose()) {
+ final long endTime = System.currentTimeMillis();
+ logStats(startTime, endTime, totalLength);
+ }
+ fis.close();
+ }
+ }
+
+ /**
+ * Get the local file
+ * @return the local file
+ */
+ public File getLocalFile() {
+ return localFile;
+ }
+
+ /**
+ * Get the remote path
+ * @return the remote path
+ */
+ public String getRemotePath() {
+ return remotePath;
+ }
+
+ /**
+ * Set the file mode, defaults to 0644.
+ * @since Ant 1.9.5
+ */
+ public void setFileMode(int fileMode) {
+ this.fileMode = fileMode;
+ }
+
+ /**
+ * Get the file mode.
+ * @since Ant 1.9.5
+ */
+ public int getFileMode() {
+ return fileMode != null ? fileMode.intValue() : DEFAULT_FILE_MODE;
+ }
+
+ /**
+ * Set the dir mode, defaults to 0755.
+ * @since Ant 1.9.5
+ */
+ public void setDirMode(int dirMode) {
+ this.dirMode = dirMode;
+ }
+
+ /**
+ * Get the dir mode.
+ * @since Ant 1.9.5
+ */
+ public int getDirMode() {
+ return dirMode != null ? dirMode.intValue() : DEFAULT_DIR_MODE;
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ssh/ScpToMessageBySftp.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ssh/ScpToMessageBySftp.java
new file mode 100644
index 00000000..2b32907d
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/ssh/ScpToMessageBySftp.java
@@ -0,0 +1,277 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.ssh;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.List;
+
+import com.jcraft.jsch.ChannelSftp;
+import com.jcraft.jsch.JSchException;
+import com.jcraft.jsch.Session;
+import com.jcraft.jsch.SftpException;
+import com.jcraft.jsch.SftpProgressMonitor;
+
+/**
+ * Utility class to carry out an upload by sftp.
+ */
+public class ScpToMessageBySftp extends ScpToMessage/*AbstractSshMessage*/ {
+
+ private static final int HUNDRED_KILOBYTES = 102400;
+
+ private File localFile;
+ private final String remotePath;
+ private List directoryList;
+
+ /**
+ * Constructor for a local file to remote.
+ * @param verbose if true do verbose logging
+ * @param session the scp session to use
+ * @param aLocalFile the local file
+ * @param aRemotePath the remote path
+ * @since Ant 1.7
+ */
+ public ScpToMessageBySftp(final boolean verbose,
+ final Session session,
+ final File aLocalFile,
+ final String aRemotePath) {
+ this(verbose, session, aRemotePath);
+
+ this.localFile = aLocalFile;
+ }
+
+ /**
+ * Constructor for a local directories to remote.
+ * @param verbose if true do verbose logging
+ * @param session the scp session to use
+ * @param aDirectoryList a list of directories
+ * @param aRemotePath the remote path
+ * @since Ant 1.7
+ */
+ public ScpToMessageBySftp(final boolean verbose,
+ final Session session,
+ final List aDirectoryList,
+ final String aRemotePath) {
+ this(verbose, session, aRemotePath);
+
+ this.directoryList = aDirectoryList;
+ }
+
+ /**
+ * Constructor for ScpToMessage.
+ * @param verbose if true do verbose logging
+ * @param session the scp session to use
+ * @param aRemotePath the remote path
+ * @since Ant 1.6.2
+ */
+ private ScpToMessageBySftp(final boolean verbose,
+ final Session session,
+ final String aRemotePath) {
+ super(verbose, session);
+ this.remotePath = aRemotePath;
+ }
+
+ /**
+ * Constructor for ScpToMessage.
+ * @param session the scp session to use
+ * @param aLocalFile the local file
+ * @param aRemotePath the remote path
+ */
+ public ScpToMessageBySftp(final Session session,
+ final File aLocalFile,
+ final String aRemotePath) {
+ this(false, session, aLocalFile, aRemotePath);
+ }
+
+ /**
+ * Constructor for ScpToMessage.
+ * @param session the scp session to use
+ * @param aDirectoryList a list of directories
+ * @param aRemotePath the remote path
+ */
+ public ScpToMessageBySftp(final Session session,
+ final List aDirectoryList,
+ final String aRemotePath) {
+ this(false, session, aDirectoryList, aRemotePath);
+ }
+
+ /**
+ * Carry out the transfer.
+ * @throws IOException on i/o errors
+ * @throws JSchException on errors detected by scp
+ */
+ @Override
+ public void execute() throws IOException, JSchException {
+ if (directoryList != null) {
+ doMultipleTransfer();
+ }
+ if (localFile != null) {
+ doSingleTransfer();
+ }
+ log("done.\n");
+ }
+
+ private void doSingleTransfer() throws IOException, JSchException {
+ final ChannelSftp channel = openSftpChannel();
+ try {
+ channel.connect();
+ try {
+ sendFileToRemote(channel, localFile, remotePath);
+ } catch (final SftpException e) {
+ final JSchException schException = new JSchException("Could not send '" + localFile
+ + "' to '" + remotePath + "' - "
+ + e.toString());
+ schException.initCause(e);
+ throw schException;
+ }
+ } finally {
+ if (channel != null) {
+ channel.disconnect();
+ }
+ }
+ }
+
+ private void doMultipleTransfer() throws IOException, JSchException {
+ final ChannelSftp channel = openSftpChannel();
+ try {
+ channel.connect();
+
+ try {
+ try {
+ channel.stat(remotePath);
+ } catch (final SftpException e) {
+ if (e.id == ChannelSftp.SSH_FX_NO_SUCH_FILE) {
+ // dir does not exist.
+ channel.mkdir(remotePath);
+ channel.chmod(getDirMode(), remotePath);
+ } else {
+ throw new JSchException("failed to access remote dir '"
+ + remotePath + "'", e);
+ }
+ }
+ channel.cd(remotePath);
+ } catch (final SftpException e) {
+ throw new JSchException("Could not CD to '" + remotePath
+ + "' - " + e.toString(), e);
+ }
+ Directory current = null;
+ try {
+ for (final Iterator i = directoryList.iterator(); i.hasNext();) {
+ current = (Directory) i.next();
+ if (getVerbose()) {
+ log("Sending directory " + current);
+ }
+ sendDirectory(channel, current);
+ }
+ } catch (final SftpException e) {
+ String msg = "Error sending directory";
+ if (current != null && current.getDirectory() != null) {
+ msg += " '" + current.getDirectory().getName() + "'";
+ }
+ throw new JSchException(msg, e);
+ }
+ } finally {
+ if (channel != null) {
+ channel.disconnect();
+ }
+ }
+ }
+
+ private void sendDirectory(final ChannelSftp channel,
+ final Directory current)
+ throws IOException, SftpException {
+ for (final Iterator fileIt = current.filesIterator(); fileIt.hasNext();) {
+ sendFileToRemote(channel, (File) fileIt.next(), null);
+ }
+ for (final Iterator dirIt = current.directoryIterator(); dirIt.hasNext();) {
+ final Directory dir = (Directory) dirIt.next();
+ sendDirectoryToRemote(channel, dir);
+ }
+ }
+
+ private void sendDirectoryToRemote(final ChannelSftp channel,
+ final Directory directory)
+ throws IOException, SftpException {
+ final String dir = directory.getDirectory().getName();
+ try {
+ channel.stat(dir);
+ } catch (final SftpException e) {
+ // dir does not exist.
+ if (e.id == ChannelSftp.SSH_FX_NO_SUCH_FILE) {
+ channel.mkdir(dir);
+ channel.chmod(getDirMode(), dir);
+ }
+ }
+ channel.cd(dir);
+ sendDirectory(channel, directory);
+ channel.cd("..");
+ }
+
+ private void sendFileToRemote(final ChannelSftp channel,
+ final File localFile,
+ String remotePath)
+ throws IOException, SftpException {
+ final long filesize = localFile.length();
+
+ if (remotePath == null) {
+ remotePath = localFile.getName();
+ }
+
+ final long startTime = System.currentTimeMillis();
+ final long totalLength = filesize;
+
+ // only track progress for files larger than 100kb in verbose mode
+ final boolean trackProgress = getVerbose() && filesize > HUNDRED_KILOBYTES;
+
+ SftpProgressMonitor monitor = null;
+ if (trackProgress) {
+ monitor = getProgressMonitor();
+ }
+
+ try {
+ if (this.getVerbose()) {
+ log("Sending: " + localFile.getName() + " : " + filesize);
+ }
+ channel.put(localFile.getAbsolutePath(), remotePath, monitor);
+ channel.chmod(getFileMode(), remotePath);
+ } finally {
+ if (this.getVerbose()) {
+ final long endTime = System.currentTimeMillis();
+ logStats(startTime, endTime, (int) totalLength);
+ }
+ }
+ }
+
+ /**
+ * Get the local file.
+ * @return the local file.
+ */
+ public File getLocalFile() {
+ return localFile;
+ }
+
+ /**
+ * Get the remote path.
+ * @return the remote path.
+ */
+ public String getRemotePath() {
+ return remotePath;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/testing/BlockFor.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/testing/BlockFor.java
new file mode 100644
index 00000000..4b2978ab
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/testing/BlockFor.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.testing;
+
+import org.apache.tools.ant.taskdefs.WaitFor;
+
+/**
+ * @since Ant 1.8
+ */
+
+public class BlockFor extends WaitFor {
+
+ /**
+ * Text to include in a message
+ */
+ private String text;
+
+
+ /**
+ * Constructor that takes the name of the task in the task name.
+ *
+ */
+ public BlockFor() {
+ super("blockfor");
+ text = getTaskName() + " timed out";
+ }
+
+ /**
+ * Constructor that takes the name of the task in the task name.
+ *
+ * @param taskName the name of the task.
+ */
+ public BlockFor(String taskName) {
+ super(taskName);
+ }
+
+ /**
+ * If the wait fails, a BuildException is thrown. All the superclasses actions are called first.
+ * @throws BuildTimeoutException on timeout, using the text in {@link #text}
+ *
+ */
+ protected void processTimeout() throws BuildTimeoutException {
+ super.processTimeout();
+ throw new BuildTimeoutException(text, getLocation());
+ }
+
+ /**
+ * Set the error text; all properties are expanded in the message.
+ *
+ * @param message the text to use in a failure message
+ */
+ public void addText(String message) {
+ text = getProject().replaceProperties(message);
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/testing/BuildTimeoutException.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/testing/BuildTimeoutException.java
new file mode 100644
index 00000000..143d08c9
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/testing/BuildTimeoutException.java
@@ -0,0 +1,114 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.testing;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Location;
+
+/**
+ *
+ * This exception is used to indicate timeouts.
+ * @since Ant1.8
+ *
+ */
+
+public class BuildTimeoutException extends BuildException {
+
+ private static final long serialVersionUID = -8057644603246297562L;
+
+ /**
+ * Constructs a build exception with no descriptive information.
+ */
+ public BuildTimeoutException() {
+ }
+
+ /**
+ * Constructs an exception with the given descriptive message.
+ *
+ * @param message A description of or information about the exception.
+ * Should not be <code>null</code>.
+ */
+ public BuildTimeoutException(String message) {
+ super(message);
+ }
+
+ /**
+ * Constructs an exception with the given message and exception as
+ * a root cause.
+ *
+ * @param message A description of or information about the exception.
+ * Should not be <code>null</code> unless a cause is specified.
+ * @param cause The exception that might have caused this one.
+ * May be <code>null</code>.
+ */
+ public BuildTimeoutException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ /**
+ * Constructs an exception with the given message and exception as
+ * a root cause and a location in a file.
+ *
+ * @param msg A description of or information about the exception.
+ * Should not be <code>null</code> unless a cause is specified.
+ * @param cause The exception that might have caused this one.
+ * May be <code>null</code>.
+ * @param location The location in the project file where the error
+ * occurred. Must not be <code>null</code>.
+ */
+ public BuildTimeoutException(String msg, Throwable cause, Location location) {
+ super(msg, cause, location);
+ }
+
+ /**
+ * Constructs an exception with the given exception as a root cause.
+ *
+ * @param cause The exception that might have caused this one.
+ * Should not be <code>null</code>.
+ */
+ public BuildTimeoutException(Throwable cause) {
+ super(cause);
+ }
+
+ /**
+ * Constructs an exception with the given descriptive message and a
+ * location in a file.
+ *
+ * @param message A description of or information about the exception.
+ * Should not be <code>null</code>.
+ * @param location The location in the project file where the error
+ * occurred. Must not be <code>null</code>.
+ */
+ public BuildTimeoutException(String message, Location location) {
+ super(message, location);
+ }
+
+ /**
+ * Constructs an exception with the given exception as
+ * a root cause and a location in a file.
+ *
+ * @param cause The exception that might have caused this one.
+ * Should not be <code>null</code>.
+ * @param location The location in the project file where the error
+ * occurred. Must not be <code>null</code>.
+ */
+ public BuildTimeoutException(Throwable cause, Location location) {
+ super(cause, location);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/testing/Funtest.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/testing/Funtest.java
new file mode 100644
index 00000000..2eb357a3
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/testing/Funtest.java
@@ -0,0 +1,577 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.testing;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.TaskAdapter;
+import org.apache.tools.ant.taskdefs.Parallel;
+import org.apache.tools.ant.taskdefs.Sequential;
+import org.apache.tools.ant.taskdefs.WaitFor;
+import org.apache.tools.ant.taskdefs.condition.Condition;
+import org.apache.tools.ant.taskdefs.condition.ConditionBase;
+import org.apache.tools.ant.util.WorkerAnt;
+
+/**
+ * Task to provide functional testing under Ant, with a fairly complex workflow of:
+ *
+ * <ul>
+ * <li>Conditional execution</li>
+ * <li>Application to start</li>
+ * <li>A probe to "waitfor" before running tests</li>
+ * <li>A tests sequence</li>
+ * <li>A reporting sequence that runs after the tests have finished</li>
+ * <li>A "teardown" clause that runs after the rest.</li>
+ * <li>Automated termination of the program it executes, if a timeout is not met</li>
+ * <li>Checking of a failure property and automatic raising of a fault
+ * (with the text in failureText)
+ * if test shutdown and reporting succeeded</li>
+ * </ul>
+ *
+ * The task is designed to be framework neutral; it will work with JUnit,
+ * TestNG and other test frameworks That can be
+ * executed from Ant. It bears a resemblance to the FunctionalTest task from
+ * SmartFrog, as the attribute names were
+ * chosen to make migration easier. However, this task benefits from the
+ * ability to tweak Ant's internals, and so
+ * simplify the workflow, and from the experience of using the SmartFrog task.
+ * No code has been shared.
+ *
+ * @since Ant 1.8
+ */
+
+public class Funtest extends Task {
+
+ /**
+ * A condition that must be true before the tests are run. This makes it
+ * easier to define complex tests that only
+ * run if certain conditions are met, such as OS or network state.
+ */
+
+ private NestedCondition condition;
+
+
+ /**
+ * Used internally to set the workflow up
+ */
+ private Parallel timedTests;
+
+ /**
+ * Setup runs if the condition is met. Once setup is complete, teardown
+ * will be run when the task finishes
+ */
+ private Sequential setup;
+
+ /**
+ * The application to run
+ */
+ private Sequential application;
+
+ /**
+ * A block that halts the tests until met.
+ */
+ private BlockFor block;
+
+ /**
+ * Tests to run
+ */
+ private Sequential tests;
+
+ /**
+ * Reporting only runs if the tests were executed. If the block stopped
+ * them, reporting is skipped.
+ */
+ private Sequential reporting;
+
+ /**
+ * Any teardown operations.
+ */
+ private Sequential teardown;
+
+ /**
+ * time for the tests to time out
+ */
+ private long timeout;
+
+ private long timeoutUnitMultiplier = WaitFor.ONE_MILLISECOND;
+
+ /**
+ * time for the execution to time out.
+ */
+ private long shutdownTime = 10 * WaitFor.ONE_SECOND;
+
+ private long shutdownUnitMultiplier = WaitFor.ONE_MILLISECOND;
+
+ /**
+ * Name of a property to look for
+ */
+ private String failureProperty;
+
+ /**
+ * Message to send when tests failed
+ */
+ private String failureMessage = "Tests failed";
+
+ /**
+ * Flag to set to true if you don't care about any shutdown errors.
+ * <p/>
+ * In that situation, errors raised during teardown are logged but not
+ * turned into BuildFault events. Similar to catching and ignoring
+ * <code>finally {}</code> clauses in Java/
+ */
+ private boolean failOnTeardownErrors = true;
+
+
+ /**
+ * What was thrown in the test run (including reporting)
+ */
+ private BuildException testException;
+ /**
+ * What got thrown during teardown
+ */
+ private BuildException teardownException;
+
+ /**
+ * Did the application throw an exception
+ */
+ private BuildException applicationException;
+
+ /**
+ * Did the task throw an exception
+ */
+ private BuildException taskException;
+
+ /** {@value} */
+ public static final String WARN_OVERRIDING = "Overriding previous definition of ";
+ /** {@value} */
+ public static final String APPLICATION_FORCIBLY_SHUT_DOWN = "Application forcibly shut down";
+ /** {@value} */
+ public static final String SHUTDOWN_INTERRUPTED = "Shutdown interrupted";
+ /** {@value} */
+ public static final String SKIPPING_TESTS
+ = "Condition failed -skipping tests";
+ /** Application exception : {@value} */
+ public static final String APPLICATION_EXCEPTION = "Application Exception";
+ /** Teardown exception : {@value} */
+ public static final String TEARDOWN_EXCEPTION = "Teardown Exception";
+
+ /**
+ * Log if the definition is overriding something
+ *
+ * @param name what is being defined
+ * @param definition what should be null if you don't want a warning
+ */
+ private void logOverride(String name, Object definition) {
+ if (definition != null) {
+ log(WARN_OVERRIDING + '<' + name + '>', Project.MSG_INFO);
+ }
+ }
+
+ /**
+ * Add a condition element.
+ * @return <code>ConditionBase</code>.
+ * @since Ant 1.6.2
+ */
+ public ConditionBase createCondition() {
+ logOverride("condition", condition);
+ condition = new NestedCondition();
+ return condition;
+ }
+
+ /**
+ * Add an application.
+ * @param sequence the application to add.
+ */
+ public void addApplication(Sequential sequence) {
+ logOverride("application", application);
+ application = sequence;
+ }
+
+ /**
+ * Add a setup sequence.
+ * @param sequence the setup sequence to add.
+ */
+ public void addSetup(Sequential sequence) {
+ logOverride("setup", setup);
+ setup = sequence;
+ }
+
+ /**
+ * Add a block.
+ * @param sequence the block for to add.
+ */
+ public void addBlock(BlockFor sequence) {
+ logOverride("block", block);
+ block = sequence;
+ }
+
+ /**
+ * add tests.
+ * @param sequence a sequence to add.
+ */
+ public void addTests(Sequential sequence) {
+ logOverride("tests", tests);
+ tests = sequence;
+ }
+
+ /**
+ * set reporting sequence of tasks.
+ * @param sequence a reporting sequence to use.
+ */
+ public void addReporting(Sequential sequence) {
+ logOverride("reporting", reporting);
+ reporting = sequence;
+ }
+
+ /**
+ * set teardown sequence of tasks.
+ * @param sequence a teardown sequence to use.
+ */
+ public void addTeardown(Sequential sequence) {
+ logOverride("teardown", teardown);
+ teardown = sequence;
+ }
+
+ /**
+ * Set the failOnTeardownErrors attribute.
+ * @param failOnTeardownErrors the value to use.
+ */
+ public void setFailOnTeardownErrors(boolean failOnTeardownErrors) {
+ this.failOnTeardownErrors = failOnTeardownErrors;
+ }
+
+ /**
+ * Set the failureMessage attribute.
+ * @param failureMessage the value to use.
+ */
+ public void setFailureMessage(String failureMessage) {
+ this.failureMessage = failureMessage;
+ }
+
+ /**
+ * Set the failureProperty attribute.
+ * @param failureProperty the value to use.
+ */
+ public void setFailureProperty(String failureProperty) {
+ this.failureProperty = failureProperty;
+ }
+
+ /**
+ * Set the shutdownTime attribute.
+ * @param shutdownTime the value to use.
+ */
+ public void setShutdownTime(long shutdownTime) {
+ this.shutdownTime = shutdownTime;
+ }
+
+ /**
+ * Set the timeout attribute.
+ * @param timeout the value to use.
+ */
+ public void setTimeout(long timeout) {
+ this.timeout = timeout;
+ }
+
+ /**
+ * Set the timeoutunit attribute.
+ * @param unit the value to use.
+ */
+ public void setTimeoutUnit(WaitFor.Unit unit) {
+ timeoutUnitMultiplier = unit.getMultiplier();
+ }
+
+ /**
+ * Set the shutdownunit attribute.
+ * @param unit the value to use.
+ */
+ public void setShutdownUnit(WaitFor.Unit unit) {
+ shutdownUnitMultiplier = unit.getMultiplier();
+ }
+
+
+ /**
+ * Get the application exception.
+ * @return the application exception.
+ */
+ public BuildException getApplicationException() {
+ return applicationException;
+ }
+
+ /**
+ * Get the teardown exception.
+ * @return the teardown exception.
+ */
+ public BuildException getTeardownException() {
+ return teardownException;
+ }
+
+ /**
+ * Get the test exception.
+ * @return the test exception.
+ */
+ public BuildException getTestException() {
+ return testException;
+ }
+
+ /**
+ * Get the task exception.
+ * @return the task exception.
+ */
+ public BuildException getTaskException() {
+ return taskException;
+ }
+
+ /**
+ * Bind and initialise a task
+ * @param task task to bind
+ */
+ private void bind(Task task) {
+ task.bindToOwner(this);
+ task.init();
+ }
+
+ /**
+ * Create a newly bound parallel instance
+ * @param parallelTimeout timeout
+ * @return a bound and initialised parallel instance.
+ */
+ private Parallel newParallel(long parallelTimeout) {
+ Parallel par = new Parallel();
+ bind(par);
+ par.setFailOnAny(true);
+ par.setTimeout(parallelTimeout);
+ return par;
+ }
+
+ /**
+ * Create a newly bound parallel instance with one child
+ * @param parallelTimeout timeout
+ * @param child task
+ * @return a bound and initialised parallel instance.
+ */
+ private Parallel newParallel(long parallelTimeout, Task child) {
+ Parallel par = newParallel(parallelTimeout);
+ par.addTask(child);
+ return par;
+ }
+
+ /**
+ * Add any task validation needed to ensure internal code quality
+ * @param task task
+ * @param role role of the task
+ */
+ private void validateTask(Task task, String role) {
+ if (task!=null && task.getProject() == null) {
+ throw new BuildException(role + " task is not bound to the project" + task);
+ }
+ }
+
+ /**
+ * Run the functional test sequence.
+ * <p>
+ * This is a fairly complex workflow -what is going on is that we try to clean up
+ * no matter how the run ended, and to retain the innermost exception that got thrown
+ * during cleanup. That is, if teardown fails after the tests themselves failed, it is the
+ * test failing that is more important.
+ * @throws BuildException if something was caught during the run or teardown.
+ */
+ public void execute() throws BuildException {
+
+ //validation
+ validateTask(setup, "setup");
+ validateTask(application, "application");
+ validateTask(tests, "tests");
+ validateTask(reporting, "reporting");
+ validateTask(teardown, "teardown");
+
+ //check the condition
+ //and bail out if it is defined but not true
+ if (condition != null && !condition.eval()) {
+ //we are skipping the test
+ log(SKIPPING_TESTS);
+ return;
+ }
+
+ long timeoutMillis = timeout * timeoutUnitMultiplier;
+
+ //set up the application to run in a separate thread
+ Parallel applicationRun = newParallel(timeoutMillis);
+ //with a worker which we can use to manage it
+ WorkerAnt worker = new WorkerAnt(applicationRun, null);
+ if (application != null) {
+ applicationRun.addTask(application);
+ }
+
+ //The test run consists of the block followed by the tests.
+ long testRunTimeout = 0;
+ Sequential testRun = new Sequential();
+ bind(testRun);
+ if (block != null) {
+ //waitfor is not a task, it needs to be adapted
+ TaskAdapter ta = new TaskAdapter(block);
+ ta.bindToOwner(this);
+ validateTask(ta, "block");
+ testRun.addTask(ta);
+ //add the block time to the total test run timeout
+ testRunTimeout = block.calculateMaxWaitMillis();
+ }
+
+ //add the tests and more delay
+ if (tests != null) {
+ testRun.addTask(tests);
+ testRunTimeout += timeoutMillis;
+ }
+ //add the reporting and more delay
+ if (reporting != null) {
+ testRun.addTask(reporting);
+ testRunTimeout += timeoutMillis;
+ }
+
+ //wrap this in a parallel purely to set up timeouts for the
+ //test run
+ timedTests = newParallel(testRunTimeout, testRun);
+
+ try {
+ //run any setup task
+ if (setup != null) {
+ Parallel setupRun = newParallel(timeoutMillis, setup);
+ setupRun.execute();
+ }
+ //start the worker thread and leave it running
+ worker.start();
+ //start the probe+test sequence
+ timedTests.execute();
+ } catch (BuildException e) {
+ //Record the exception and continue
+ testException = e;
+ } finally {
+ //teardown always runs; its faults are filed away
+ if (teardown != null) {
+ try {
+ Parallel teardownRun = newParallel(timeoutMillis, teardown);
+ teardownRun.execute();
+ } catch (BuildException e) {
+ teardownException = e;
+ }
+ }
+ }
+
+ //we get here whether or not the tests/teardown have thrown a BuildException.
+ //do a forced shutdown of the running application, before processing the faults
+
+ try {
+ //wait for the worker to have finished
+ long shutdownTimeMillis = shutdownTime * shutdownUnitMultiplier;
+ worker.waitUntilFinished(shutdownTimeMillis);
+ if (worker.isAlive()) {
+ //then, if it is still running, interrupt it a second time.
+ log(APPLICATION_FORCIBLY_SHUT_DOWN, Project.MSG_WARN);
+ worker.interrupt();
+ worker.waitUntilFinished(shutdownTimeMillis);
+ }
+ } catch (InterruptedException e) {
+ //success, something interrupted the shutdown. There may be a leaked
+ //worker;
+ log(SHUTDOWN_INTERRUPTED, e, Project.MSG_VERBOSE);
+ }
+ applicationException = worker.getBuildException();
+
+ //Now faults are analysed
+
+ processExceptions();
+ }
+
+ /**
+ * Now faults are analysed.
+ * <p> The priority is
+ * <ol>
+ * <li>testexceptions, except those indicating a build timeout when the application itself
+ failed.<br>
+ (because often it is the application fault that is more interesting than the probe
+ failure, which is usually triggered by the application not starting
+ </li><li>
+ Application exceptions (above test timeout exceptions)
+ </li><li>
+ Teardown exceptions -except when they are being ignored
+ </li><li>
+ Test failures as indicated by the failure property
+ </li></ol>
+
+ */
+ protected void processExceptions() {
+ taskException = testException;
+
+ //look for an application fault
+ if (applicationException != null) {
+ if (taskException == null || taskException instanceof BuildTimeoutException) {
+ taskException = applicationException;
+ } else {
+ ignoringThrowable(APPLICATION_EXCEPTION, applicationException);
+ }
+ }
+
+ //now look for teardown faults, which may be ignored
+ if (teardownException != null) {
+ if (taskException == null && failOnTeardownErrors) {
+ taskException = teardownException;
+ } else {
+ //don't let the cleanup exception get in the way of any other failure
+ ignoringThrowable(TEARDOWN_EXCEPTION, teardownException);
+ }
+ }
+
+ //now, analyse the tests
+ if (failureProperty != null
+ && getProject().getProperty(failureProperty) != null) {
+ //we've failed
+ log(failureMessage);
+ if (taskException == null) {
+ taskException = new BuildException(failureMessage);
+ }
+ }
+
+ //at this point taskException is null or not.
+ //if not, throw the exception
+ if (taskException != null) {
+ throw taskException;
+ }
+ }
+
+ /**
+ * log that we are ignoring something rather than rethrowing it.
+ * @param type name of exception
+ * @param thrown what was thrown
+ */
+ protected void ignoringThrowable(String type, Throwable thrown) {
+ log(type + ": " + thrown.toString(),
+ thrown,
+ Project.MSG_WARN);
+ }
+
+ private static class NestedCondition extends ConditionBase implements Condition {
+ public boolean eval() {
+ if (countConditions() != 1) {
+ throw new BuildException(
+ "A single nested condition is required.");
+ }
+ return ((Condition) (getConditions().nextElement())).eval();
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/unix/AbstractAccessTask.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/unix/AbstractAccessTask.java
new file mode 100644
index 00000000..d3385e6c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/unix/AbstractAccessTask.java
@@ -0,0 +1,110 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+/*
+ * Since the initial version of this file was deveolped on the clock on
+ * an NSF grant I should say the following boilerplate:
+ *
+ * This material is based upon work supported by the National Science
+ * Foundaton under Grant No. EIA-0196404. Any opinions, findings, and
+ * conclusions or recommendations expressed in this material are those
+ * of the author and do not necessarily reflect the views of the
+ * National Science Foundation.
+ */
+
+package org.apache.tools.ant.taskdefs.optional.unix;
+
+import java.io.File;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.taskdefs.condition.Os;
+import org.apache.tools.ant.types.Commandline;
+import org.apache.tools.ant.types.FileSet;
+
+/**
+ * @since Ant 1.6
+ *
+ * @ant.task category="filesystem"
+ */
+
+public abstract class AbstractAccessTask
+ extends org.apache.tools.ant.taskdefs.ExecuteOn {
+
+ /**
+ * Chmod task for setting file and directory permissions.
+ */
+ public AbstractAccessTask() {
+ super.setParallel(true);
+ super.setSkipEmptyFilesets(true);
+ }
+
+ /**
+ * Set the file which should have its access attributes modified.
+ * @param src the file to modify
+ */
+ public void setFile(File src) {
+ FileSet fs = new FileSet();
+ fs.setFile(src);
+ addFileset(fs);
+ }
+
+ /**
+ * Prevent the user from specifying a different command.
+ *
+ * @ant.attribute ignore="true"
+ * @param cmdl A user supplied command line that we won't accept.
+ */
+ public void setCommand(Commandline cmdl) {
+ throw new BuildException(getTaskType()
+ + " doesn\'t support the command attribute",
+ getLocation());
+ }
+
+ /**
+ * Prevent the skipping of empty filesets
+ *
+ * @ant.attribute ignore="true"
+ * @param skip A user supplied boolean we won't accept.
+ */
+ public void setSkipEmptyFilesets(boolean skip) {
+ throw new BuildException(getTaskType() + " doesn\'t support the "
+ + "skipemptyfileset attribute",
+ getLocation());
+ }
+
+ /**
+ * Prevent the use of the addsourcefile attribute.
+ *
+ * @ant.attribute ignore="true"
+ * @param b A user supplied boolean we won't accept.
+ */
+ public void setAddsourcefile(boolean b) {
+ throw new BuildException(getTaskType()
+ + " doesn\'t support the addsourcefile attribute", getLocation());
+ }
+
+ /**
+ * Automatically approve Unix OS's.
+ * @return true if a valid OS, for unix this is always true, otherwise
+ * use the superclasses' test (user set).
+ */
+ protected boolean isValidOs() {
+ return getOs() == null && getOsFamily() == null
+ ? Os.isFamily(Os.FAMILY_UNIX) : super.isValidOs();
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/unix/Chgrp.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/unix/Chgrp.java
new file mode 100644
index 00000000..1279a2c8
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/unix/Chgrp.java
@@ -0,0 +1,84 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+/*
+ * Since the initial version of this file was deveolped on the clock on
+ * an NSF grant I should say the following boilerplate:
+ *
+ * This material is based upon work supported by the National Science
+ * Foundaton under Grant No. EIA-0196404. Any opinions, findings, and
+ * conclusions or recommendations expressed in this material are those
+ * of the author and do not necessarily reflect the views of the
+ * National Science Foundation.
+ */
+
+package org.apache.tools.ant.taskdefs.optional.unix;
+
+import org.apache.tools.ant.BuildException;
+
+/**
+ * Chgrp equivalent for unix-like environments.
+ *
+ * @since Ant 1.6
+ *
+ * @ant.task category="filesystem"
+ */
+public class Chgrp extends AbstractAccessTask {
+
+ private boolean haveGroup = false;
+
+ /**
+ * Chgrp task for setting unix group of a file.
+ */
+ public Chgrp() {
+ super.setExecutable("chgrp");
+ }
+
+ /**
+ * Set the group attribute.
+ *
+ * @param group The new group for the file(s) or directory(ies)
+ */
+ public void setGroup(String group) {
+ createArg().setValue(group);
+ haveGroup = true;
+ }
+
+ /**
+ * Ensure that all the required arguments and other conditions have
+ * been set.
+ */
+ protected void checkConfiguration() {
+ if (!haveGroup) {
+ throw new BuildException("Required attribute group not set in "
+ + "chgrp", getLocation());
+ }
+ super.checkConfiguration();
+ }
+
+ /**
+ * We don't want to expose the executable attribute, so override it.
+ *
+ * @param e User supplied executable that we won't accept.
+ */
+ public void setExecutable(String e) {
+ throw new BuildException(getTaskType()
+ + " doesn\'t support the executable"
+ + " attribute", getLocation());
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/unix/Chown.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/unix/Chown.java
new file mode 100644
index 00000000..53f72536
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/unix/Chown.java
@@ -0,0 +1,84 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+/*
+ * Since the initial version of this file was deveolped on the clock on
+ * an NSF grant I should say the following boilerplate:
+ *
+ * This material is based upon work supported by the National Science
+ * Foundaton under Grant No. EIA-0196404. Any opinions, findings, and
+ * conclusions or recommendations expressed in this material are those
+ * of the author and do not necessarily reflect the views of the
+ * National Science Foundation.
+ */
+
+package org.apache.tools.ant.taskdefs.optional.unix;
+
+import org.apache.tools.ant.BuildException;
+
+/**
+ * Chown equivalent for unix-like environments.
+ *
+ * @since Ant 1.6
+ *
+ * @ant.task category="filesystem"
+ */
+public class Chown extends AbstractAccessTask {
+
+ private boolean haveOwner = false;
+
+ /**
+ * Chown task for setting file and directory permissions.
+ */
+ public Chown() {
+ super.setExecutable("chown");
+ }
+
+ /**
+ * Set the owner attribute.
+ *
+ * @param owner The new owner for the file(s) or directory(ies)
+ */
+ public void setOwner(String owner) {
+ createArg().setValue(owner);
+ haveOwner = true;
+ }
+
+ /**
+ * Ensure that all the required arguments and other conditions have
+ * been set.
+ */
+ protected void checkConfiguration() {
+ if (!haveOwner) {
+ throw new BuildException("Required attribute owner not set in"
+ + " chown", getLocation());
+ }
+ super.checkConfiguration();
+ }
+
+ /**
+ * We don't want to expose the executable attribute, so override it.
+ *
+ * @param e User supplied executable that we won't accept.
+ */
+ public void setExecutable(String e) {
+ throw new BuildException(getTaskType()
+ + " doesn\'t support the executable"
+ + " attribute", getLocation());
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/unix/Symlink.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/unix/Symlink.java
new file mode 100644
index 00000000..ad9aee8b
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/unix/Symlink.java
@@ -0,0 +1,600 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+/*
+ * Since the initial version of this file was developed on the clock on
+ * an NSF grant I should say the following boilerplate:
+ *
+ * This material is based upon work supported by the National Science
+ * Foundaton under Grant No. EIA-0196404. Any opinions, findings, and
+ * conclusions or recommendations expressed in this material are those
+ * of the author and do not necessarily reflect the views of the
+ * National Science Foundation.
+ */
+
+package org.apache.tools.ant.taskdefs.optional.unix;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintStream;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Properties;
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.DirectoryScanner;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.dispatch.DispatchTask;
+import org.apache.tools.ant.dispatch.DispatchUtils;
+import org.apache.tools.ant.taskdefs.Execute;
+import org.apache.tools.ant.taskdefs.LogOutputStream;
+import org.apache.tools.ant.types.FileSet;
+import org.apache.tools.ant.util.FileUtils;
+import org.apache.tools.ant.util.SymbolicLinkUtils;
+
+/**
+ * Creates, Deletes, Records and Restores Symlinks.
+ *
+ * <p> This task performs several related operations. In the most trivial
+ * and default usage, it creates a link specified in the link attribute to
+ * a resource specified in the resource attribute. The second usage of this
+ * task is to traverse a directory structure specified by a fileset,
+ * and write a properties file in each included directory describing the
+ * links found in that directory. The third usage is to traverse a
+ * directory structure specified by a fileset, looking for properties files
+ * (also specified as included in the fileset) and recreate the links
+ * that have been previously recorded for each directory. Finally, it can be
+ * used to remove a symlink without deleting the associated resource.
+ *
+ * <p> Usage examples:
+ *
+ * <p> Make a link named &quot;foo&quot; to a resource named
+ * &quot;bar.foo&quot; in subdir:
+ * <pre>
+ * &lt;symlink link=&quot;${dir.top}/foo&quot; resource=&quot;${dir.top}/subdir/bar.foo&quot;/&gt;
+ * </pre>
+ *
+ * <p> Record all links in subdir and its descendants in files named
+ * &quot;dir.links&quot;:
+ * <pre>
+ * &lt;symlink action=&quot;record&quot; linkfilename=&quot;dir.links&quot;&gt;
+ * &lt;fileset dir=&quot;${dir.top}&quot; includes=&quot;subdir&#47;**&quot; /&gt;
+ * &lt;/symlink&gt;
+ * </pre>
+ *
+ * <p> Recreate the links recorded in the previous example:
+ * <pre>
+ * &lt;symlink action=&quot;recreate&quot;&gt;
+ * &lt;fileset dir=&quot;${dir.top}&quot; includes=&quot;subdir&#47;**&#47;dir.links&quot; /&gt;
+ * &lt;/symlink&gt;
+ * </pre>
+ *
+ * <p> Delete a link named &quot;foo&quot; to a resource named
+ * &quot;bar.foo&quot; in subdir:
+ * <pre>
+ * &lt;symlink action=&quot;delete&quot; link=&quot;${dir.top}/foo&quot;/&gt;
+ * </pre>
+ *
+ * <p><strong>LIMITATIONS:</strong> Because Java has no direct support for
+ * handling symlinks this task divines them by comparing canonical and
+ * absolute paths. On non-unix systems this may cause false positives.
+ * Furthermore, any operating system on which the command
+ * <code>ln -s link resource</code> is not a valid command on the command line
+ * will not be able to use action=&quot;delete&quot;, action=&quot;single&quot;
+ * or action=&quot;recreate&quot;, but action=&quot;record&quot; should still
+ * work. Finally, the lack of support for symlinks in Java means that all links
+ * are recorded as links to the <strong>canonical</strong> resource name.
+ * Therefore the link: <code>link --> subdir/dir/../foo.bar</code> will be
+ * recorded as <code>link=subdir/foo.bar</code> and restored as
+ * <code>link --> subdir/foo.bar</code>.
+ *
+ */
+public class Symlink extends DispatchTask {
+ private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+ private static final SymbolicLinkUtils SYMLINK_UTILS =
+ SymbolicLinkUtils.getSymbolicLinkUtils();
+
+ private String resource;
+ private String link;
+ private Vector fileSets = new Vector();
+ private String linkFileName;
+ private boolean overwrite;
+ private boolean failonerror;
+ private boolean executing = false;
+
+ /**
+ * Initialize the task.
+ * @throws BuildException on error.
+ */
+ @Override
+ public void init() throws BuildException {
+ super.init();
+ setDefaults();
+ }
+
+ /**
+ * The standard method for executing any task.
+ * @throws BuildException on error.
+ */
+ @Override
+ public synchronized void execute() throws BuildException {
+ if (executing) {
+ throw new BuildException(
+ "Infinite recursion detected in Symlink.execute()");
+ }
+ try {
+ executing = true;
+ DispatchUtils.execute(this);
+ } finally {
+ executing = false;
+ }
+ }
+
+ /**
+ * Create a symlink.
+ * @throws BuildException on error.
+ * @since Ant 1.7
+ */
+ public void single() throws BuildException {
+ try {
+ if (resource == null) {
+ handleError("Must define the resource to symlink to!");
+ return;
+ }
+ if (link == null) {
+ handleError("Must define the link name for symlink!");
+ return;
+ }
+ doLink(resource, link);
+ } finally {
+ setDefaults();
+ }
+ }
+
+ /**
+ * Delete a symlink.
+ * @throws BuildException on error.
+ * @since Ant 1.7
+ */
+ public void delete() throws BuildException {
+ try {
+ if (link == null) {
+ handleError("Must define the link name for symlink!");
+ return;
+ }
+ log("Removing symlink: " + link);
+ SYMLINK_UTILS.deleteSymbolicLink(FILE_UTILS
+ .resolveFile(new File("."), link),
+ this);
+ } catch (FileNotFoundException fnfe) {
+ handleError(fnfe.toString());
+ } catch (IOException ioe) {
+ handleError(ioe.toString());
+ } finally {
+ setDefaults();
+ }
+ }
+
+ /**
+ * Restore symlinks.
+ * @throws BuildException on error.
+ * @since Ant 1.7
+ */
+ public void recreate() throws BuildException {
+ try {
+ if (fileSets.isEmpty()) {
+ handleError("File set identifying link file(s) "
+ + "required for action recreate");
+ return;
+ }
+ Properties links = loadLinks(fileSets);
+
+ for (Iterator kitr = links.keySet().iterator(); kitr.hasNext();) {
+ String lnk = (String) kitr.next();
+ String res = links.getProperty(lnk);
+ // handle the case where lnk points to a directory (bug 25181)
+ try {
+ File test = new File(lnk);
+ if (!SYMLINK_UTILS.isSymbolicLink(lnk)) {
+ doLink(res, lnk);
+ } else if (!test.getCanonicalPath().equals(
+ new File(res).getCanonicalPath())) {
+ SYMLINK_UTILS.deleteSymbolicLink(test, this);
+ doLink(res, lnk);
+ } // else lnk exists, do nothing
+ } catch (IOException ioe) {
+ handleError("IO exception while creating link");
+ }
+ }
+ } finally {
+ setDefaults();
+ }
+ }
+
+ /**
+ * Record symlinks.
+ * @throws BuildException on error.
+ * @since Ant 1.7
+ */
+ public void record() throws BuildException {
+ try {
+ if (fileSets.isEmpty()) {
+ handleError("Fileset identifying links to record required");
+ return;
+ }
+ if (linkFileName == null) {
+ handleError("Name of file to record links in required");
+ return;
+ }
+ // create a hashtable to group them by parent directory:
+ Hashtable byDir = new Hashtable();
+
+ // get an Iterator of file objects representing links (canonical):
+ for (Iterator litr = findLinks(fileSets).iterator();
+ litr.hasNext();) {
+ File thisLink = (File) litr.next();
+ File parent = thisLink.getParentFile();
+ Vector v = (Vector) byDir.get(parent);
+ if (v == null) {
+ v = new Vector();
+ byDir.put(parent, v);
+ }
+ v.addElement(thisLink);
+ }
+ // write a Properties file in each directory:
+ for (Iterator dirs = byDir.keySet().iterator(); dirs.hasNext();) {
+ File dir = (File) dirs.next();
+ Vector linksInDir = (Vector) byDir.get(dir);
+ Properties linksToStore = new Properties();
+
+ // fill up a Properties object with link and resource names:
+ for (Iterator dlnk = linksInDir.iterator(); dlnk.hasNext();) {
+ File lnk = (File) dlnk.next();
+ try {
+ linksToStore.put(lnk.getName(), lnk.getCanonicalPath());
+ } catch (IOException ioe) {
+ handleError("Couldn't get canonical name of parent link");
+ }
+ }
+ writePropertyFile(linksToStore, dir);
+ }
+ } finally {
+ setDefaults();
+ }
+ }
+
+ /**
+ * Return all variables to their default state for the next invocation.
+ * @since Ant 1.7
+ */
+ private void setDefaults() {
+ resource = null;
+ link = null;
+ linkFileName = null;
+ failonerror = true; // default behavior is to fail on an error
+ overwrite = false; // default behavior is to not overwrite
+ setAction("single"); // default behavior is make a single link
+ fileSets.clear();
+ }
+
+ /**
+ * Set overwrite mode. If set to false (default)
+ * the task will not overwrite existing links, and may stop the build
+ * if a link already exists depending on the setting of failonerror.
+ *
+ * @param owrite If true overwrite existing links.
+ */
+ public void setOverwrite(boolean owrite) {
+ this.overwrite = owrite;
+ }
+
+ /**
+ * Set failonerror mode. If set to true (default) the entire build fails
+ * upon error; otherwise the error is logged and the build will continue.
+ *
+ * @param foe If true throw BuildException on error, else log it.
+ */
+ public void setFailOnError(boolean foe) {
+ this.failonerror = foe;
+ }
+
+ /**
+ * Set the action to be performed. May be &quot;single&quot;,
+ * &quot;delete&quot;, &quot;recreate&quot; or &quot;record&quot;.
+ *
+ * @param action The action to perform.
+ */
+ @Override
+ public void setAction(String action) {
+ super.setAction(action);
+ }
+
+ /**
+ * Set the name of the link. Used when action = &quot;single&quot;.
+ *
+ * @param lnk The name for the link.
+ */
+ public void setLink(String lnk) {
+ this.link = lnk;
+ }
+
+ /**
+ * Set the name of the resource to which a link should be created.
+ * Used when action = &quot;single&quot;.
+ *
+ * @param src The resource to be linked.
+ */
+ public void setResource(String src) {
+ this.resource = src;
+ }
+
+ /**
+ * Set the name of the file to which links will be written.
+ * Used when action = &quot;record&quot;.
+ *
+ * @param lf The name of the file to write links to.
+ */
+ public void setLinkfilename(String lf) {
+ this.linkFileName = lf;
+ }
+
+ /**
+ * Add a fileset to this task.
+ *
+ * @param set The fileset to add.
+ */
+ public void addFileset(FileSet set) {
+ fileSets.addElement(set);
+ }
+
+ /**
+ * Delete a symlink (without deleting the associated resource).
+ *
+ * <p>This is a convenience method that simply invokes
+ * <code>deleteSymlink(java.io.File)</code>.
+ *
+ * @param path A string containing the path of the symlink to delete.
+ *
+ * @throws FileNotFoundException When the path results in a
+ * <code>File</code> that doesn't exist.
+ * @throws IOException If calls to <code>File.rename</code>
+ * or <code>File.delete</code> fail.
+ * @deprecated use
+ * org.apache.tools.ant.util.SymbolicLinkUtils#deleteSymbolicLink
+ * instead
+ */
+ @Deprecated
+ public static void deleteSymlink(String path)
+ throws IOException, FileNotFoundException {
+ SYMLINK_UTILS.deleteSymbolicLink(new File(path), null);
+ }
+
+ /**
+ * Delete a symlink (without deleting the associated resource).
+ *
+ * <p>This is a utility method that removes a unix symlink without removing
+ * the resource that the symlink points to. If it is accidentally invoked
+ * on a real file, the real file will not be harmed.</p>
+ *
+ * <p>This method works by
+ * getting the canonical path of the link, using the canonical path to
+ * rename the resource (breaking the link) and then deleting the link.
+ * The resource is then returned to its original name inside a finally
+ * block to ensure that the resource is unharmed even in the event of
+ * an exception.</p>
+ *
+ * <p>Since Ant 1.8.0 this method will try to delete the File object if
+ * it reports it wouldn't exist (as symlinks pointing nowhere usually do).
+ * Prior version would throw a FileNotFoundException in that case.</p>
+ *
+ * @param linkfil A <code>File</code> object of the symlink to delete.
+ *
+ * @throws IOException If calls to <code>File.rename</code>,
+ * <code>File.delete</code> or
+ * <code>File.getCanonicalPath</code>
+ * fail.
+ * @deprecated use
+ * org.apache.tools.ant.util.SymbolicLinkUtils#deleteSymbolicLink
+ * instead
+ */
+ @Deprecated
+ public static void deleteSymlink(File linkfil)
+ throws IOException {
+ SYMLINK_UTILS.deleteSymbolicLink(linkfil, null);
+ }
+
+ /**
+ * Write a properties file. This method uses <code>Properties.store</code>
+ * and thus may throw exceptions that occur while writing the file.
+ *
+ * @param properties The properties object to be written.
+ * @param dir The directory for which we are writing the links.
+ * @throws BuildException if the property file could not be written
+ */
+ private void writePropertyFile(Properties properties, File dir)
+ throws BuildException {
+ BufferedOutputStream bos = null;
+ try {
+ bos = new BufferedOutputStream(
+ new FileOutputStream(new File(dir, linkFileName)));
+ properties.store(bos, "Symlinks from " + dir);
+ } catch (IOException ioe) {
+ throw new BuildException(ioe, getLocation());
+ } finally {
+ FileUtils.close(bos);
+ }
+ }
+
+ /**
+ * Handle errors based on the setting of failonerror.
+ *
+ * @param msg The message to log, or include in the
+ * <code>BuildException</code>.
+ * @throws BuildException with the message if failonerror=true
+ */
+ private void handleError(String msg) {
+ if (failonerror) {
+ throw new BuildException(msg);
+ }
+ log(msg);
+ }
+
+ /**
+ * Conduct the actual construction of a link.
+ *
+ * <p> The link is constructed by calling <code>Execute.runCommand</code>.
+ *
+ * @param res The path of the resource we are linking to.
+ * @param lnk The name of the link we wish to make.
+ * @throws BuildException when things go wrong
+ */
+ private void doLink(String res, String lnk) throws BuildException {
+ File linkfil = new File(lnk);
+ String options = "-s";
+ if (overwrite) {
+ options += "f";
+ if (linkfil.exists()) {
+ try {
+ SYMLINK_UTILS.deleteSymbolicLink(linkfil, this);
+ } catch (FileNotFoundException fnfe) {
+ log("Symlink disappeared before it was deleted: " + lnk);
+ } catch (IOException ioe) {
+ log("Unable to overwrite preexisting link or file: " + lnk,
+ ioe, Project.MSG_INFO);
+ }
+ }
+ }
+ String[] cmd = new String[] {"ln", options, res, lnk};
+ try {
+ Execute.runCommand(this, cmd);
+ } catch (BuildException failedToExecute) {
+ if (failonerror) {
+ throw failedToExecute;
+ } else {
+ //log at the info level, and keep going.
+ log(failedToExecute.getMessage(), failedToExecute, Project.MSG_INFO);
+ }
+ }
+ }
+
+ /**
+ * Find all the links in all supplied filesets.
+ *
+ * <p> This method is invoked when the action attribute is
+ * &quot;record&quot;. This means that filesets are interpreted
+ * as the directories in which links may be found.
+ *
+ * @param v The filesets specified by the user.
+ * @return A HashSet of <code>File</code> objects containing the
+ * links (with canonical parent directories).
+ */
+ private HashSet findLinks(Vector v) {
+ HashSet result = new HashSet();
+ final int size = v.size();
+ for (int i = 0; i < size; i++) {
+ FileSet fs = (FileSet) v.get(i);
+ DirectoryScanner ds = fs.getDirectoryScanner(getProject());
+ String[][] fnd = new String[][]
+ {ds.getIncludedFiles(), ds.getIncludedDirectories()};
+ File dir = fs.getDir(getProject());
+ for (int j = 0; j < fnd.length; j++) {
+ for (int k = 0; k < fnd[j].length; k++) {
+ try {
+ File f = new File(dir, fnd[j][k]);
+ File pf = f.getParentFile();
+ String name = f.getName();
+ if (SYMLINK_UTILS.isSymbolicLink(pf, name)) {
+ result.add(new File(pf.getCanonicalFile(), name));
+ }
+ } catch (IOException e) {
+ handleError("IOException: " + fnd[j][k] + " omitted");
+ }
+ }
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Load links from properties files included in one or more FileSets.
+ *
+ * <p> This method is only invoked when the action attribute is set to
+ * &quot;recreate&quot;. The filesets passed in are assumed to specify the
+ * names of the property files with the link information and the
+ * subdirectories in which to look for them.
+ *
+ * @param v The <code>FileSet</code>s for this task.
+ * @return The links to be made.
+ */
+ private Properties loadLinks(Vector v) {
+ Properties finalList = new Properties();
+ // loop through the supplied file sets:
+ final int size = v.size();
+ for (int i = 0; i < size; i++) {
+ FileSet fs = (FileSet) v.elementAt(i);
+ DirectoryScanner ds = new DirectoryScanner();
+ fs.setupDirectoryScanner(ds, getProject());
+ ds.setFollowSymlinks(false);
+ ds.scan();
+ String[] incs = ds.getIncludedFiles();
+ File dir = fs.getDir(getProject());
+
+ // load included files as properties files:
+ for (int j = 0; j < incs.length; j++) {
+ File inc = new File(dir, incs[j]);
+ File pf = inc.getParentFile();
+ Properties lnks = new Properties();
+ InputStream is = null;
+ try {
+ is = new BufferedInputStream(new FileInputStream(inc));
+ lnks.load(is);
+ pf = pf.getCanonicalFile();
+ } catch (FileNotFoundException fnfe) {
+ handleError("Unable to find " + incs[j] + "; skipping it.");
+ continue;
+ } catch (IOException ioe) {
+ handleError("Unable to open " + incs[j]
+ + " or its parent dir; skipping it.");
+ continue;
+ } finally {
+ FileUtils.close(is);
+ }
+ lnks.list(new PrintStream(
+ new LogOutputStream(this, Project.MSG_INFO)));
+ // Write the contents to our master list of links
+ // This method assumes that all links are defined in
+ // terms of absolute paths, or paths relative to the
+ // working directory:
+ for (Iterator kitr = lnks.keySet().iterator(); kitr.hasNext();) {
+ String key = (String) kitr.next();
+ finalList.put(new File(pf, key).getAbsolutePath(),
+ lnks.getProperty(key));
+ }
+ }
+ }
+ return finalList;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/vss/MSVSS.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/vss/MSVSS.java
new file mode 100644
index 00000000..f514fc62
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/vss/MSVSS.java
@@ -0,0 +1,784 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.vss;
+
+import java.io.File;
+import java.io.IOException;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.GregorianCalendar;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.taskdefs.Execute;
+import org.apache.tools.ant.taskdefs.LogStreamHandler;
+import org.apache.tools.ant.types.Commandline;
+import org.apache.tools.ant.types.EnumeratedAttribute;
+import org.apache.tools.ant.util.FileUtils;
+
+/**
+ * A base class for creating tasks for executing commands on Visual SourceSafe.
+ * <p>
+ * The class extends the 'exec' task as it operates by executing the ss.exe program
+ * supplied with SourceSafe. By default the task expects ss.exe to be in the path,
+ * you can override this be specifying the ssdir attribute.
+ * </p>
+ * <p>
+ * This class provides set and get methods for 'login' and 'vsspath' attributes. It
+ * also contains constants for the flags that can be passed to SS.
+ * </p>
+ *
+ */
+public abstract class MSVSS extends Task implements MSVSSConstants {
+
+ private String ssDir = null;
+ private String vssLogin = null;
+ private String vssPath = null;
+ private String serverPath = null;
+
+ /** Version */
+ private String version = null;
+ /** Date */
+ private String date = null;
+ /** Label */
+ private String label = null;
+ /** Auto response */
+ private String autoResponse = null;
+ /** Local path */
+ private String localPath = null;
+ /** Comment */
+ private String comment = null;
+ /** From label */
+ private String fromLabel = null;
+ /** To label */
+ private String toLabel = null;
+ /** Output file name */
+ private String outputFileName = null;
+ /** User */
+ private String user = null;
+ /** From date */
+ private String fromDate = null;
+ /** To date */
+ private String toDate = null;
+ /** History style */
+ private String style = null;
+ /** Quiet defaults to false */
+ private boolean quiet = false;
+ /** Recursive defaults to false */
+ private boolean recursive = false;
+ /** Writable defaults to false */
+ private boolean writable = false;
+ /** Fail on error defaults to true */
+ private boolean failOnError = true;
+ /** Get local copy for checkout defaults to true */
+ private boolean getLocalCopy = true;
+ /** Number of days offset for History */
+ private int numDays = Integer.MIN_VALUE;
+ /** Date format for History */
+ private DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.SHORT);
+ /** Timestamp for retreived files */
+ private CurrentModUpdated timestamp = null;
+ /** Behaviour for writable files */
+ private WritableFiles writableFiles = null;
+
+ /**
+ * Each sub-class must implemnt this method and return the constructed
+ * command line to be executed. It is up to the sub-task to determine the
+ * required attrubutes and their order.
+ * @return The Constructed command line.
+ */
+ abstract Commandline buildCmdLine();
+
+ /**
+ * Directory where <code>ss.exe</code> resides.
+ * By default the task expects it to be in the PATH.
+ * @param dir The directory containing ss.exe.
+ */
+ public final void setSsdir(String dir) {
+ this.ssDir = FileUtils.translatePath(dir);
+ }
+
+ /**
+ * Login to use when accessing VSS, formatted as "username,password".
+ * <p>
+ * You can omit the password if your database is not password protected.
+ * If you have a password and omit it, Ant will hang.
+ * @param vssLogin The login string to use.
+ */
+ public final void setLogin(final String vssLogin) {
+ this.vssLogin = vssLogin;
+ }
+
+ /**
+ * SourceSafe path which specifies the project/file(s) you wish to perform
+ * the action on.
+ * <p>
+ * A prefix of 'vss://' will be removed if specified.
+ * @param vssPath The VSS project path.
+ * @ant.attribute group="required"
+ */
+ public final void setVsspath(final String vssPath) {
+ String projectPath;
+ // CheckStyle:MagicNumber OFF
+ if (vssPath.startsWith("vss://")) { //$NON-NLS-1$
+ projectPath = vssPath.substring(5);
+ } else {
+ projectPath = vssPath;
+ }
+ // CheckStyle:MagicNumber ON
+
+ if (projectPath.startsWith(PROJECT_PREFIX)) {
+ this.vssPath = projectPath;
+ } else {
+ this.vssPath = PROJECT_PREFIX + projectPath;
+ }
+ }
+
+ /**
+ * Directory where <code>srssafe.ini</code> resides.
+ * @param serverPath The path to the VSS server.
+ */
+ public final void setServerpath(final String serverPath) {
+ this.serverPath = serverPath;
+ }
+
+ /**
+ * Indicates if the build should fail if the Sourcesafe command does. Defaults to true.
+ * @param failOnError True if task should fail on any error.
+ */
+ public final void setFailOnError(final boolean failOnError) {
+ this.failOnError = failOnError;
+ }
+
+ /**
+ * Executes the task. <br>
+ * Builds a command line to execute ss.exe and then calls Exec's run method
+ * to execute the command line.
+ * @throws BuildException if the command cannot execute.
+ */
+ public void execute() throws BuildException {
+ int result = 0;
+ Commandline commandLine = buildCmdLine();
+ result = run(commandLine);
+ if (Execute.isFailure(result) && getFailOnError()) {
+ String msg = "Failed executing: " + formatCommandLine(commandLine)
+ + " With a return code of " + result;
+ throw new BuildException(msg, getLocation());
+ }
+ }
+
+ // Special setters for the sub-classes
+
+ /**
+ * Set the internal comment attribute.
+ * @param comment the value to use.
+ */
+ protected void setInternalComment(final String comment) {
+ this.comment = comment;
+ }
+
+ /**
+ * Set the auto response attribute.
+ * @param autoResponse the value to use.
+ */
+ protected void setInternalAutoResponse(final String autoResponse) {
+ this.autoResponse = autoResponse;
+ }
+
+ /**
+ * Set the date attribute.
+ * @param date the value to use.
+ */
+ protected void setInternalDate(final String date) {
+ this.date = date;
+ }
+
+ /**
+ * Set the date format attribute.
+ * @param dateFormat the value to use.
+ */
+ protected void setInternalDateFormat(final DateFormat dateFormat) {
+ this.dateFormat = dateFormat;
+ }
+
+ /**
+ * Set the failOnError attribute.
+ * @param failOnError the value to use.
+ */
+ protected void setInternalFailOnError(final boolean failOnError) {
+ this.failOnError = failOnError;
+ }
+
+ /**
+ * Set the from date attribute.
+ * @param fromDate the value to use.
+ */
+ protected void setInternalFromDate(final String fromDate) {
+ this.fromDate = fromDate;
+ }
+
+ /**
+ * Set the from label attribute.
+ * @param fromLabel the value to use.
+ */
+ protected void setInternalFromLabel(final String fromLabel) {
+ this.fromLabel = fromLabel;
+ }
+
+ /**
+ * Set the label attribute.
+ * @param label the value to use.
+ */
+ protected void setInternalLabel(final String label) {
+ this.label = label;
+ }
+
+ /**
+ * Set the local path comment attribute.
+ * @param localPath the value to use.
+ */
+ protected void setInternalLocalPath(final String localPath) {
+ this.localPath = localPath;
+ }
+
+ /**
+ * Set the num days attribute.
+ * @param numDays the value to use.
+ */
+ protected void setInternalNumDays(final int numDays) {
+ this.numDays = numDays;
+ }
+
+ /**
+ * Set the outputFileName comment attribute.
+ * @param outputFileName the value to use.
+ */
+ protected void setInternalOutputFilename(final String outputFileName) {
+ this.outputFileName = outputFileName;
+ }
+
+ /**
+ * Set the quiet attribute.
+ * @param quiet the value to use.
+ */
+ protected void setInternalQuiet(final boolean quiet) {
+ this.quiet = quiet;
+ }
+
+ /**
+ * Set the recursive attribute.
+ * @param recursive the value to use.
+ */
+ protected void setInternalRecursive(final boolean recursive) {
+ this.recursive = recursive;
+ }
+
+ /**
+ * Set the style attribute.
+ * @param style the value to use.
+ */
+ protected void setInternalStyle(final String style) {
+ this.style = style;
+ }
+
+ /**
+ * Set the to date attribute.
+ * @param toDate the value to use.
+ */
+ protected void setInternalToDate(final String toDate) {
+ this.toDate = toDate;
+ }
+
+ /**
+ * Set the to label attribute.
+ * @param toLabel the value to use.
+ */
+ protected void setInternalToLabel(final String toLabel) {
+ this.toLabel = toLabel;
+ }
+
+ /**
+ * Set the user attribute.
+ * @param user the value to use.
+ */
+ protected void setInternalUser(final String user) {
+ this.user = user;
+ }
+
+ /**
+ * Set the version attribute.
+ * @param version the value to use.
+ */
+ protected void setInternalVersion(final String version) {
+ this.version = version;
+ }
+
+ /**
+ * Set the writable attribute.
+ * @param writable the value to use.
+ */
+ protected void setInternalWritable(final boolean writable) {
+ this.writable = writable;
+ }
+
+ /**
+ * Set the timestamp attribute.
+ * @param timestamp the value to use.
+ */
+ protected void setInternalFileTimeStamp(final CurrentModUpdated timestamp) {
+ this.timestamp = timestamp;
+ }
+
+ /**
+ * Set the writableFiles attribute.
+ * @param writableFiles the value to use.
+ */
+ protected void setInternalWritableFiles(final WritableFiles writableFiles) {
+ this.writableFiles = writableFiles;
+ }
+
+ /**
+ * Set the getLocalCopy attribute.
+ * @param getLocalCopy the value to use.
+ */
+ protected void setInternalGetLocalCopy(final boolean getLocalCopy) {
+ this.getLocalCopy = getLocalCopy;
+ }
+
+ /**
+ * Gets the sscommand string. "ss" or "c:\path\to\ss"
+ * @return The path to ss.exe or just ss if sscommand is not set.
+ */
+ protected String getSSCommand() {
+ if (ssDir == null) {
+ return SS_EXE;
+ }
+ return ssDir.endsWith(File.separator) ? ssDir + SS_EXE : ssDir
+ + File.separator + SS_EXE;
+ }
+
+ /**
+ * Gets the vssserverpath string.
+ * @return null if vssserverpath is not set.
+ */
+ protected String getVsspath() {
+ return vssPath;
+ }
+
+ /**
+ * Gets the quiet string. -O-
+ * @return An empty string if quiet is not set or is false.
+ */
+ protected String getQuiet() {
+ return quiet ? FLAG_QUIET : "";
+ }
+
+ /**
+ * Gets the recursive string. "-R"
+ * @return An empty string if recursive is not set or is false.
+ */
+ protected String getRecursive() {
+ return recursive ? FLAG_RECURSION : "";
+ }
+
+ /**
+ * Gets the writable string. "-W"
+ * @return An empty string if writable is not set or is false.
+ */
+ protected String getWritable() {
+ return writable ? FLAG_WRITABLE : "";
+ }
+
+ /**
+ * Gets the label string. "-Lbuild1"
+ * Max label length is 32 chars
+ * @return An empty string if label is not set.
+ */
+ protected String getLabel() {
+ String shortLabel = "";
+ if (label != null && label.length() > 0) {
+ shortLabel = FLAG_LABEL + getShortLabel();
+ }
+ return shortLabel;
+ }
+ /**
+ * Return at most the 30 first chars of the label,
+ * logging a warning message about the truncation
+ * @return at most the 30 first chars of the label
+ */
+ private String getShortLabel() {
+ String shortLabel;
+ // CheckStyle:MagicNumber OFF
+ if (label != null && label.length() > 31) {
+ shortLabel = this.label.substring(0, 30);
+ log("Label is longer than 31 characters, truncated to: " + shortLabel,
+ Project.MSG_WARN);
+ } else {
+ shortLabel = label;
+ }
+ // CheckStyle:MagicNumber ON
+ return shortLabel;
+ }
+ /**
+ * Gets the style string. "-Lbuild1"
+ * @return An empty string if label is not set.
+ */
+ protected String getStyle() {
+ return style != null ? style : "";
+ }
+
+ /**
+ * Gets the version string. Returns the first specified of version "-V1.0",
+ * date "-Vd01.01.01", label "-Vlbuild1".
+ * @return An empty string if a version, date and label are not set.
+ */
+ protected String getVersionDateLabel() {
+ String versionDateLabel = "";
+ if (version != null) {
+ versionDateLabel = FLAG_VERSION + version;
+ } else if (date != null) {
+ versionDateLabel = FLAG_VERSION_DATE + date;
+ } else {
+ // Use getShortLabel() so labels longer then 30 char are truncated
+ // and the user is warned
+ String shortLabel = getShortLabel();
+ if (shortLabel != null && !shortLabel.equals("")) {
+ versionDateLabel = FLAG_VERSION_LABEL + shortLabel;
+ }
+ }
+ return versionDateLabel;
+ }
+
+ /**
+ * Gets the version string.
+ * @return An empty string if a version is not set.
+ */
+ protected String getVersion() {
+ return version != null ? FLAG_VERSION + version : "";
+ }
+
+ /**
+ * Gets the localpath string. "-GLc:\source" <p>
+ * The localpath is created if it didn't exist.
+ * @return An empty string if localpath is not set.
+ */
+ protected String getLocalpath() {
+ String lclPath = ""; //set to empty str if no local path return
+ if (localPath != null) {
+ //make sure m_LocalDir exists, create it if it doesn't
+ File dir = getProject().resolveFile(localPath);
+ if (!dir.exists()) {
+ boolean done = dir.mkdirs();
+ if (!done) {
+ String msg = "Directory " + localPath + " creation was not "
+ + "successful for an unknown reason";
+ throw new BuildException(msg, getLocation());
+ }
+ getProject().log("Created dir: " + dir.getAbsolutePath());
+ }
+ lclPath = FLAG_OVERRIDE_WORKING_DIR + localPath;
+ }
+ return lclPath;
+ }
+
+ /**
+ * Gets the comment string. "-Ccomment text"
+ * @return A comment of "-" if comment is not set.
+ */
+ protected String getComment() {
+ return comment != null ? FLAG_COMMENT + comment : FLAG_COMMENT + "-";
+ }
+
+ /**
+ * Gets the auto response string. This can be Y "-I-Y" or N "-I-N".
+ * @return The default value "-I-" if autoresponse is not set.
+ */
+ protected String getAutoresponse() {
+ if (autoResponse == null) {
+ return FLAG_AUTORESPONSE_DEF;
+ }
+ if (autoResponse.equalsIgnoreCase("Y")) {
+ return FLAG_AUTORESPONSE_YES;
+ } else if (autoResponse.equalsIgnoreCase("N")) {
+ return FLAG_AUTORESPONSE_NO;
+ } else {
+ return FLAG_AUTORESPONSE_DEF;
+ }
+ }
+
+ /**
+ * Gets the login string. This can be user and password, "-Yuser,password"
+ * or just user "-Yuser".
+ * @return An empty string if login is not set.
+ */
+ protected String getLogin() {
+ return vssLogin != null ? FLAG_LOGIN + vssLogin : "";
+ }
+
+ /**
+ * Gets the output file string. "-Ooutput.file"
+ * @return An empty string if user is not set.
+ */
+ protected String getOutput() {
+ return outputFileName != null ? FLAG_OUTPUT + outputFileName : "";
+ }
+
+ /**
+ * Gets the user string. "-Uusername"
+ * @return An empty string if user is not set.
+ */
+ protected String getUser() {
+ return user != null ? FLAG_USER + user : "";
+ }
+
+ /**
+ * Gets the version string. This can be to-from "-VLbuild2~Lbuild1", from
+ * "~Lbuild1" or to "-VLbuild2".
+ * @return An empty string if neither tolabel or fromlabel are set.
+ */
+ protected String getVersionLabel() {
+ if (fromLabel == null && toLabel == null) {
+ return "";
+ }
+ // CheckStyle:MagicNumber OFF
+ if (fromLabel != null && toLabel != null) {
+ if (fromLabel.length() > 31) {
+ fromLabel = fromLabel.substring(0, 30);
+ log("FromLabel is longer than 31 characters, truncated to: "
+ + fromLabel, Project.MSG_WARN);
+ }
+ if (toLabel.length() > 31) {
+ toLabel = toLabel.substring(0, 30);
+ log("ToLabel is longer than 31 characters, truncated to: "
+ + toLabel, Project.MSG_WARN);
+ }
+ return FLAG_VERSION_LABEL + toLabel + VALUE_FROMLABEL + fromLabel;
+ } else if (fromLabel != null) {
+ if (fromLabel.length() > 31) {
+ fromLabel = fromLabel.substring(0, 30);
+ log("FromLabel is longer than 31 characters, truncated to: "
+ + fromLabel, Project.MSG_WARN);
+ }
+ return FLAG_VERSION + VALUE_FROMLABEL + fromLabel;
+ } else {
+ if (toLabel.length() > 31) {
+ toLabel = toLabel.substring(0, 30);
+ log("ToLabel is longer than 31 characters, truncated to: "
+ + toLabel, Project.MSG_WARN);
+ }
+ return FLAG_VERSION_LABEL + toLabel;
+ }
+ // CheckStyle:MagicNumber ON
+ }
+
+ /**
+ * Gets the Version date string.
+ * @return An empty string if neither Todate or from date are set.
+ * @throws BuildException if there is an error.
+ */
+ protected String getVersionDate() throws BuildException {
+ if (fromDate == null && toDate == null
+ && numDays == Integer.MIN_VALUE) {
+ return "";
+ }
+ if (fromDate != null && toDate != null) {
+ return FLAG_VERSION_DATE + toDate + VALUE_FROMDATE + fromDate;
+ } else if (toDate != null && numDays != Integer.MIN_VALUE) {
+ try {
+ return FLAG_VERSION_DATE + toDate + VALUE_FROMDATE
+ + calcDate(toDate, numDays);
+ } catch (ParseException ex) {
+ String msg = "Error parsing date: " + toDate;
+ throw new BuildException(msg, getLocation());
+ }
+ } else if (fromDate != null && numDays != Integer.MIN_VALUE) {
+ try {
+ return FLAG_VERSION_DATE + calcDate(fromDate, numDays)
+ + VALUE_FROMDATE + fromDate;
+ } catch (ParseException ex) {
+ String msg = "Error parsing date: " + fromDate;
+ throw new BuildException(msg, getLocation());
+ }
+ } else {
+ return fromDate != null ? FLAG_VERSION + VALUE_FROMDATE
+ + fromDate : FLAG_VERSION_DATE + toDate;
+ }
+ }
+
+ /**
+ * Builds and returns the -G- flag if required.
+ * @return An empty string if get local copy is true.
+ */
+ protected String getGetLocalCopy() {
+ return (!getLocalCopy) ? FLAG_NO_GET : "";
+ }
+
+ /**
+ * Gets the value of the fail on error flag.
+ * @return True if the FailOnError flag has been set or if 'writablefiles=skip'.
+ */
+ private boolean getFailOnError() {
+ return getWritableFiles().equals(WRITABLE_SKIP) ? false : failOnError;
+ }
+
+
+ /**
+ * Gets the value set for the FileTimeStamp.
+ * if it equals "current" then we return -GTC
+ * if it equals "modified" then we return -GTM
+ * if it equals "updated" then we return -GTU
+ * otherwise we return -GTC
+ *
+ * @return The default file time flag, if not set.
+ */
+ public String getFileTimeStamp() {
+ if (timestamp == null) {
+ return "";
+ } else if (timestamp.getValue().equals(TIME_MODIFIED)) {
+ return FLAG_FILETIME_MODIFIED;
+ } else if (timestamp.getValue().equals(TIME_UPDATED)) {
+ return FLAG_FILETIME_UPDATED;
+ } else {
+ return FLAG_FILETIME_DEF;
+ }
+ }
+
+
+ /**
+ * Gets the value to determine the behaviour when encountering writable files.
+ * @return An empty String, if not set.
+ */
+ public String getWritableFiles() {
+ if (writableFiles == null) {
+ return "";
+ } else if (writableFiles.getValue().equals(WRITABLE_REPLACE)) {
+ return FLAG_REPLACE_WRITABLE;
+ } else if (writableFiles.getValue().equals(WRITABLE_SKIP)) {
+ // ss.exe exits with '100', when files have been skipped
+ // so we have to ignore the failure
+ failOnError = false;
+ return FLAG_SKIP_WRITABLE;
+ } else {
+ return "";
+ }
+ }
+
+ /**
+ * Sets up the required environment and executes the command line.
+ *
+ * @param cmd The command line to execute.
+ * @return The return code from the exec'd process.
+ */
+ private int run(Commandline cmd) {
+ try {
+ Execute exe = new Execute(new LogStreamHandler(this,
+ Project.MSG_INFO,
+ Project.MSG_WARN));
+
+ // If location of ss.ini is specified we need to set the
+ // environment-variable SSDIR to this value
+ if (serverPath != null) {
+ String[] env = exe.getEnvironment();
+ if (env == null) {
+ env = new String[0];
+ }
+ String[] newEnv = new String[env.length + 1];
+ System.arraycopy(env, 0, newEnv, 0, env.length);
+ newEnv[env.length] = "SSDIR=" + serverPath;
+
+ exe.setEnvironment(newEnv);
+ }
+
+ exe.setAntRun(getProject());
+ exe.setWorkingDirectory(getProject().getBaseDir());
+ exe.setCommandline(cmd.getCommandline());
+ // Use the OS launcher so we get environment variables
+ exe.setVMLauncher(false);
+ return exe.execute();
+ } catch (IOException e) {
+ throw new BuildException(e, getLocation());
+ }
+ }
+
+ /**
+ * Calculates the start date for version comparison.
+ * <p>
+ * Calculates the date numDay days earlier than startdate.
+ * @param startDate The start date.
+ * @param daysToAdd The number of days to add.
+ * @return The calculated date.
+ * @throws ParseException
+ */
+ private String calcDate(String startDate, int daysToAdd) throws ParseException {
+ Calendar calendar = new GregorianCalendar();
+ Date currentDate = dateFormat.parse(startDate);
+ calendar.setTime(currentDate);
+ calendar.add(Calendar.DATE, daysToAdd);
+ return dateFormat.format(calendar.getTime());
+ }
+
+ /**
+ * Changes the password to '***' so it isn't displayed on screen if the build fails
+ *
+ * @param cmd The command line to clean
+ * @return The command line as a string with out the password
+ */
+ private String formatCommandLine(Commandline cmd) {
+ StringBuffer sBuff = new StringBuffer(cmd.toString());
+ int indexUser = sBuff.substring(0).indexOf(FLAG_LOGIN);
+ if (indexUser > 0) {
+ int indexPass = sBuff.substring(0).indexOf(",", indexUser);
+ int indexAfterPass = sBuff.substring(0).indexOf(" ", indexPass);
+
+ for (int i = indexPass + 1; i < indexAfterPass; i++) {
+ sBuff.setCharAt(i, '*');
+ }
+ }
+ return sBuff.toString();
+ }
+
+ /**
+ * Extension of EnumeratedAttribute to hold the values for file time stamp.
+ */
+ public static class CurrentModUpdated extends EnumeratedAttribute {
+ /**
+ * Gets the list of allowable values.
+ * @return The values.
+ */
+ public String[] getValues() {
+ return new String[] {TIME_CURRENT, TIME_MODIFIED, TIME_UPDATED};
+ }
+ }
+
+ /**
+ * Extension of EnumeratedAttribute to hold the values for writable filess.
+ */
+ public static class WritableFiles extends EnumeratedAttribute {
+ /**
+ * Gets the list of allowable values.
+ * @return The values.
+ */
+ public String[] getValues() {
+ return new String[] {WRITABLE_REPLACE, WRITABLE_SKIP, WRITABLE_FAIL};
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/vss/MSVSSADD.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/vss/MSVSSADD.java
new file mode 100644
index 00000000..0241ee3c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/vss/MSVSSADD.java
@@ -0,0 +1,122 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.vss;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.types.Commandline;
+import org.apache.tools.ant.types.Path;
+
+/**
+ * Performs Add commands to Microsoft Visual SourceSafe.
+ *
+ * @ant.task name="vssadd" category="scm"
+ */
+public class MSVSSADD extends MSVSS {
+
+ private String localPath = null;
+
+ /**
+ * Builds a command line to execute ss.
+ * @return The constructed commandline.
+ */
+ protected Commandline buildCmdLine() {
+ Commandline commandLine = new Commandline();
+
+ // first off, make sure that we've got a command and a localPath ...
+ if (getLocalpath() == null) {
+ String msg = "localPath attribute must be set!";
+ throw new BuildException(msg, getLocation());
+ }
+
+ // build the command line from what we got the format is
+ // ss Add VSS items [-B] [-C] [-D-] [-H] [-I-] [-K] [-N] [-O] [-R] [-W] [-Y] [-?]
+ // as specified in the SS.EXE help
+ commandLine.setExecutable(getSSCommand());
+ commandLine.createArgument().setValue(COMMAND_ADD);
+
+ // VSS items
+ commandLine.createArgument().setValue(getLocalpath());
+ // -I- or -I-Y or -I-N
+ commandLine.createArgument().setValue(getAutoresponse());
+ // -R
+ commandLine.createArgument().setValue(getRecursive());
+ // -W
+ commandLine.createArgument().setValue(getWritable());
+ // -Y
+ commandLine.createArgument().setValue(getLogin());
+ // -C
+ commandLine.createArgument().setValue(getComment());
+
+ return commandLine;
+ }
+
+ /**
+ * Returns the local path without the flag.; required
+ * @todo See why this returns the local path without the flag.
+ * @return The local path value.
+ */
+ protected String getLocalpath() {
+ return localPath;
+ }
+
+ /**
+ * Add files recursively. Defaults to false.
+ *
+ * @param recursive The boolean value for recursive.
+ */
+ public void setRecursive(boolean recursive) {
+ super.setInternalRecursive(recursive);
+ }
+
+ /**
+ * Unset the READ-ONLY flag on local copies of files added to VSS. Defaults to false.
+ *
+ * @param writable The boolean value for writable.
+ */
+ public final void setWritable(boolean writable) {
+ super.setInternalWritable(writable);
+ }
+
+ /**
+ * Autoresponce behaviour. Valid options are Y and N.
+ *
+ * @param response The auto response value.
+ */
+ public void setAutoresponse(String response) {
+ super.setInternalAutoResponse(response);
+ }
+
+ /**
+ * Comment to apply to files added to SourceSafe.
+ *
+ * @param comment The comment to apply in SourceSafe
+ */
+ public void setComment(String comment) {
+ super.setInternalComment(comment);
+ }
+
+ /**
+ * Override the project working directory.
+ *
+ * @param localPath The path on disk.
+ */
+ public void setLocalpath(Path localPath) {
+ this.localPath = localPath.toString();
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/vss/MSVSSCHECKIN.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/vss/MSVSSCHECKIN.java
new file mode 100644
index 00000000..f9521aa0
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/vss/MSVSSCHECKIN.java
@@ -0,0 +1,114 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.vss;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.types.Commandline;
+import org.apache.tools.ant.types.Path;
+
+/**
+ * Performs CheckIn commands to Microsoft Visual SourceSafe.
+ *
+ * @ant.task name="vsscheckin" category="scm"
+ */
+public class MSVSSCHECKIN extends MSVSS {
+
+ /**
+ * Builds a command line to execute ss.
+ * @return The constructed commandline.
+ */
+ protected Commandline buildCmdLine() {
+ Commandline commandLine = new Commandline();
+
+ // first off, make sure that we've got a command and a vssdir ...
+ if (getVsspath() == null) {
+ String msg = "vsspath attribute must be set!";
+ throw new BuildException(msg, getLocation());
+ }
+
+ // build the command line from what we got the format is
+ // ss Checkin VSS items [-H] [-C] [-I-] [-N] [-O] [-R] [-W] [-Y] [-?]
+ // as specified in the SS.EXE help
+ commandLine.setExecutable(getSSCommand());
+ commandLine.createArgument().setValue(COMMAND_CHECKIN);
+
+ // VSS items
+ commandLine.createArgument().setValue(getVsspath());
+ // -GL
+ commandLine.createArgument().setValue(getLocalpath());
+ // -I- or -I-Y or -I-N
+ commandLine.createArgument().setValue(getAutoresponse());
+ // -R
+ commandLine.createArgument().setValue(getRecursive());
+ // -W
+ commandLine.createArgument().setValue(getWritable());
+ // -Y
+ commandLine.createArgument().setValue(getLogin());
+ // -C
+ commandLine.createArgument().setValue(getComment());
+
+ return commandLine;
+ }
+
+ /**
+ * Override the project working directory.
+ *
+ * @param localPath The path on disk.
+ */
+ public void setLocalpath(Path localPath) {
+ super.setInternalLocalPath(localPath.toString());
+ }
+
+ /**
+ * Check-in files recursively. Defaults to false.
+ *
+ * @param recursive The boolean value for recursive.
+ */
+ public void setRecursive(boolean recursive) {
+ super.setInternalRecursive(recursive);
+ }
+
+ /**
+ * Unset the READ-ONLY flag on local copies of files checked-in to VSS.
+ * Defaults to false.
+ *
+ * @param writable The boolean value for writable.
+ */
+ public final void setWritable(boolean writable) {
+ super.setInternalWritable(writable);
+ }
+
+ /**
+ * Autoresponce behaviour. Valid options are Y and N.
+ *
+ * @param response The auto response value.
+ */
+ public void setAutoresponse(String response) {
+ super.setInternalAutoResponse(response);
+ }
+
+ /**
+ * Comment to apply to files checked-in to SourceSafe.
+ *
+ * @param comment The comment to apply in SourceSafe
+ */
+ public void setComment(String comment) {
+ super.setInternalComment(comment);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/vss/MSVSSCHECKOUT.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/vss/MSVSSCHECKOUT.java
new file mode 100644
index 00000000..edbcde96
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/vss/MSVSSCHECKOUT.java
@@ -0,0 +1,165 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.vss;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.types.Commandline;
+import org.apache.tools.ant.types.Path;
+
+/**
+ * Performs CheckOut commands to Microsoft Visual SourceSafe.
+ *
+ * @ant.task name="vsscheckout" category="scm"
+ * @ant.attribute.group name="vdl" description="Only one of version, date or label"
+ */
+public class MSVSSCHECKOUT extends MSVSS {
+
+ /**
+ * Builds a command line to execute ss.
+ * @return The constructed commandline.
+ */
+ protected Commandline buildCmdLine() {
+ Commandline commandLine = new Commandline();
+
+ // first off, make sure that we've got a command and a vssdir ...
+ if (getVsspath() == null) {
+ String msg = "vsspath attribute must be set!";
+ throw new BuildException(msg, getLocation());
+ }
+
+ // build the command line from what we got the format is
+ // ss Checkout VSS items [-G] [-C] [-H] [-I-] [-N] [-O] [-R] [-V] [-Y] [-?]
+ // as specified in the SS.EXE help
+ commandLine.setExecutable(getSSCommand());
+ commandLine.createArgument().setValue(COMMAND_CHECKOUT);
+
+ // VSS items
+ commandLine.createArgument().setValue(getVsspath());
+ // -GL
+ commandLine.createArgument().setValue(getLocalpath());
+ // -I- or -I-Y or -I-N
+ commandLine.createArgument().setValue(getAutoresponse());
+ // -R
+ commandLine.createArgument().setValue(getRecursive());
+ // -V
+ commandLine.createArgument().setValue(getVersionDateLabel());
+ // -Y
+ commandLine.createArgument().setValue(getLogin());
+ // -G
+ commandLine.createArgument().setValue(getFileTimeStamp());
+ // -GWS or -GWR
+ commandLine.createArgument().setValue(getWritableFiles());
+ // -G-
+ commandLine.createArgument().setValue(getGetLocalCopy());
+
+ return commandLine;
+ }
+
+ /**
+ * Override the project working directory.
+ *
+ * @param localPath The path on disk.
+ */
+ public void setLocalpath(Path localPath) {
+ super.setInternalLocalPath(localPath.toString());
+ }
+
+ /**
+ * Check-out files recursively. Defaults to false.
+ *
+ * @param recursive The boolean value for recursive.
+ */
+ public void setRecursive(boolean recursive) {
+ super.setInternalRecursive(recursive);
+ }
+
+ /**
+ * Version to check-out.
+ *
+ * @param version The version to check-out.
+ *
+ * @ant.attribute group="vdl"
+ */
+ public void setVersion(String version) {
+ super.setInternalVersion(version);
+ }
+
+ /**
+ * Date to check-out.
+ *
+ * @param date The date to check-out.
+ *
+ * @ant.attribute group="vdl"
+ */
+ public void setDate(String date) {
+ super.setInternalDate(date);
+ }
+
+ /**
+ * Label to check-out.
+ *
+ * @param label The label to check-out.
+ *
+ * @ant.attribute group="vdl"
+ */
+ public void setLabel(String label) {
+ super.setInternalLabel(label);
+ }
+
+ /**
+ * Autoresponce behaviour. Valid options are Y and N.
+ *
+ * @param response The auto response value.
+ */
+ public void setAutoresponse(String response) {
+ super.setInternalAutoResponse(response);
+ }
+
+ /**
+ * Date and time stamp given to the local copy. Defaults to <code>current</code>.
+ *
+ * @param timestamp The file time stamping behaviour.
+ */
+ public void setFileTimeStamp(CurrentModUpdated timestamp) {
+ super.setInternalFileTimeStamp(timestamp);
+ }
+
+ /**
+ * Action taken when local files are writable. Defaults to <code>fail</code>.
+ * <p>
+ * Due to ss.exe returning with an exit code of '100' for both errors and when
+ * a file has been skipped, <code>failonerror</code> is set to false when using
+ * the <code>skip</code> option.
+ * </p>
+ *
+ * @param files The writable files behaviour
+ */
+ public void setWritableFiles(WritableFiles files) {
+ super.setInternalWritableFiles(files);
+ }
+
+ /**
+ * Retrieve a local copy during a checkout. Defaults to true.
+ *
+ * @param get The get local copy behaviour
+ */
+ public void setGetLocalCopy(boolean get) {
+ super.setInternalGetLocalCopy(get);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/vss/MSVSSCP.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/vss/MSVSSCP.java
new file mode 100644
index 00000000..ae2fcb7c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/vss/MSVSSCP.java
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.vss;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.types.Commandline;
+
+/**
+ * Performs CP (Change Project) commands to Microsoft Visual SourceSafe.
+ * <p>This task is typically used before a VssAdd in order to set the target project</p>
+ *
+ * @ant.task name="vsscp" category="scm"
+ */
+public class MSVSSCP extends MSVSS {
+
+ /**
+ * Builds a command line to execute ss.
+ * @return The constructed commandline.
+ */
+ protected Commandline buildCmdLine() {
+ Commandline commandLine = new Commandline();
+
+ // first off, make sure that we've got a command and a vssdir ...
+ if (getVsspath() == null) {
+ String msg = "vsspath attribute must be set!";
+ throw new BuildException(msg, getLocation());
+ }
+
+ // build the command line from what we got the format is
+ // ss CP VSS items [-H] [-I-] [-Y] [-?]
+ // as specified in the SS.EXE help
+ commandLine.setExecutable(getSSCommand());
+ commandLine.createArgument().setValue(COMMAND_CP);
+
+ // VSS items
+ commandLine.createArgument().setValue(getVsspath());
+ // -I- or -I-Y or -I-N
+ commandLine.createArgument().setValue(getAutoresponse());
+ // -Y
+ commandLine.createArgument().setValue(getLogin());
+
+ return commandLine;
+ }
+
+ /**
+ * Autoresponce behaviour. Valid options are Y and N.
+ *
+ * @param response The auto response value.
+ */
+ public void setAutoresponse(String response) {
+ super.setInternalAutoResponse(response);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/vss/MSVSSCREATE.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/vss/MSVSSCREATE.java
new file mode 100644
index 00000000..4f298c03
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/vss/MSVSSCREATE.java
@@ -0,0 +1,91 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.vss;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.types.Commandline;
+
+/**
+ * Creates a new project in Microsoft Visual SourceSafe.
+ *
+ * @ant.task name="vsscreate" category="scm"
+ */
+public class MSVSSCREATE extends MSVSS {
+
+ /**
+ * Builds a command line to execute ss.
+ * @return The constructed commandline.
+ */
+ Commandline buildCmdLine() {
+ Commandline commandLine = new Commandline();
+
+ // first off, make sure that we've got a command and a vssdir...
+ if (getVsspath() == null) {
+ String msg = "vsspath attribute must be set!";
+ throw new BuildException(msg, getLocation());
+ }
+
+ // build the command line from what we got
+ // the format is:
+ // ss Create VSS items [-C] [-H] [-I-] [-N] [-O] [-S] [-Y] [-?]
+ // as specified in the SS.EXE help
+ commandLine.setExecutable(getSSCommand());
+ commandLine.createArgument().setValue(COMMAND_CREATE);
+
+ // VSS items
+ commandLine.createArgument().setValue(getVsspath());
+ // -C
+ commandLine.createArgument().setValue(getComment());
+ // -I- or -I-Y or -I-N
+ commandLine.createArgument().setValue(getAutoresponse());
+ // -O-
+ commandLine.createArgument().setValue(getQuiet());
+ // -Y
+ commandLine.createArgument().setValue(getLogin());
+
+ return commandLine;
+ }
+
+ /**
+ * Comment to apply to the project created in SourceSafe.
+ *
+ * @param comment The comment to apply in SourceSafe
+ */
+ public void setComment(String comment) {
+ super.setInternalComment(comment);
+ }
+
+ /**
+ * Enable quiet mode. Defaults to false.
+ *
+ * @param quiet The boolean value for quiet.
+ */
+ public final void setQuiet (boolean quiet) {
+ super.setInternalQuiet(quiet);
+ }
+
+ /**
+ * Autoresponce behaviour. Valid options are Y and N.
+ *
+ * @param response The auto response value.
+ */
+ public void setAutoresponse(String response) {
+ super.setInternalAutoResponse(response);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/vss/MSVSSConstants.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/vss/MSVSSConstants.java
new file mode 100644
index 00000000..9e5ec606
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/vss/MSVSSConstants.java
@@ -0,0 +1,127 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.vss;
+
+/**
+ * Holds all the constants for the VSS tasks.
+ *
+ */
+// CheckStyle:InterfaceIsType OFF (bc)
+public interface MSVSSConstants {
+ /** Constant for the thing to execute */
+ String SS_EXE = "ss";
+ /** Dollar Sigh to prefix the project path */
+ String PROJECT_PREFIX = "$";
+
+ /** The 'CP' command */
+ String COMMAND_CP = "CP";
+ /** The 'Add' command */
+ String COMMAND_ADD = "Add";
+ /** The 'Get' command */
+ String COMMAND_GET = "Get";
+ /** The 'Checkout' command */
+ String COMMAND_CHECKOUT = "Checkout";
+ /** The 'Checkin' command */
+ String COMMAND_CHECKIN = "Checkin";
+ /** The 'Label' command */
+ String COMMAND_LABEL = "Label";
+ /** The 'History' command */
+ String COMMAND_HISTORY = "History";
+ /** The 'Create' command */
+ String COMMAND_CREATE = "Create";
+
+ /** The brief style flag */
+ String STYLE_BRIEF = "brief";
+ /** The codediff style flag */
+ String STYLE_CODEDIFF = "codediff";
+ /** The nofile style flag */
+ String STYLE_NOFILE = "nofile";
+ /** The default style flag */
+ String STYLE_DEFAULT = "default";
+
+ /** The text for current (default) timestamp */
+ String TIME_CURRENT = "current";
+ /** The text for modified timestamp */
+ String TIME_MODIFIED = "modified";
+ /** The text for updated timestamp */
+ String TIME_UPDATED = "updated";
+
+ /** The text for replacing writable files */
+ String WRITABLE_REPLACE = "replace";
+ /** The text for skipping writable files */
+ String WRITABLE_SKIP = "skip";
+ /** The text for failing on writable files */
+ String WRITABLE_FAIL = "fail";
+
+ /** -Y flag */
+ String FLAG_LOGIN = "-Y";
+ /** -GL flag */
+ String FLAG_OVERRIDE_WORKING_DIR = "-GL";
+ /** -I- flag */
+ String FLAG_AUTORESPONSE_DEF = "-I-";
+ /** -I-Y flag */
+ String FLAG_AUTORESPONSE_YES = "-I-Y";
+ /** -I-N flag */
+ String FLAG_AUTORESPONSE_NO = "-I-N";
+ /** -R flag */
+ String FLAG_RECURSION = "-R";
+ /** -V flag */
+ String FLAG_VERSION = "-V";
+ /** -Vd flag */
+ String FLAG_VERSION_DATE = "-Vd";
+ /** -VL flag */
+ String FLAG_VERSION_LABEL = "-VL";
+ /** -W flag */
+ String FLAG_WRITABLE = "-W";
+ /** -N flag */
+ String VALUE_NO = "-N";
+ /** -Y flag */
+ String VALUE_YES = "-Y";
+ /** -O- flag */
+ String FLAG_QUIET = "-O-";
+ /** -C flag */
+ String FLAG_COMMENT = "-C";
+ /** -L flag */
+ String FLAG_LABEL = "-L";
+ /** ~d flag */
+ String VALUE_FROMDATE = "~d";
+ /** ~L flag */
+ String VALUE_FROMLABEL = "~L";
+ /** -O flag */
+ String FLAG_OUTPUT = "-O";
+ /** -U flag */
+ String FLAG_USER = "-U";
+ /** -F- flag */
+ String FLAG_NO_FILE = "-F-";
+ /** -B flag */
+ String FLAG_BRIEF = "-B";
+ /** -D flag */
+ String FLAG_CODEDIFF = "-D";
+ /** -GTC flag */
+ String FLAG_FILETIME_DEF = "-GTC";
+ /** -GTM flag */
+ String FLAG_FILETIME_MODIFIED = "-GTM";
+ /** -GTU flag */
+ String FLAG_FILETIME_UPDATED = "-GTU";
+ /** -GWR flag */
+ String FLAG_REPLACE_WRITABLE = "-GWR";
+ /** -GWS flag */
+ String FLAG_SKIP_WRITABLE = "-GWS";
+ /** -G- flag */
+ String FLAG_NO_GET = "-G-";
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/vss/MSVSSGET.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/vss/MSVSSGET.java
new file mode 100644
index 00000000..fd5ed096
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/vss/MSVSSGET.java
@@ -0,0 +1,172 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.vss;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.types.Commandline;
+import org.apache.tools.ant.types.Path;
+
+/**
+ * Perform Get commands from Microsoft Visual SourceSafe.
+ *
+ * @ant.task name="vssget" category="scm"
+ * @ant.attribute.group name="vdl" description="Only one of version, date or label"
+ */
+public class MSVSSGET extends MSVSS {
+
+ /**
+ * Builds a command line to execute ss.
+ * @return The constructed commandline.
+ */
+ Commandline buildCmdLine() {
+ Commandline commandLine = new Commandline();
+
+ // build the command line from what we got the format is
+ // ss Get VSS items [-G] [-H] [-I-] [-N] [-O] [-R] [-V] [-W] [-Y] [-?]
+ // as specified in the SS.EXE help
+ commandLine.setExecutable(getSSCommand());
+ commandLine.createArgument().setValue(COMMAND_GET);
+
+ if (getVsspath() == null) {
+ throw new BuildException("vsspath attribute must be set!", getLocation());
+ }
+ commandLine.createArgument().setValue(getVsspath());
+
+ // -GL
+ commandLine.createArgument().setValue(getLocalpath());
+ // -I- or -I-Y or -I-N
+ commandLine.createArgument().setValue(getAutoresponse());
+ // -O-
+ commandLine.createArgument().setValue(getQuiet());
+ // -R
+ commandLine.createArgument().setValue(getRecursive());
+ // -V
+ commandLine.createArgument().setValue(getVersionDateLabel());
+ // -W
+ commandLine.createArgument().setValue(getWritable());
+ // -Y
+ commandLine.createArgument().setValue(getLogin());
+ // -G
+ commandLine.createArgument().setValue(getFileTimeStamp());
+ // -GWS or -GWR
+ commandLine.createArgument().setValue(getWritableFiles());
+
+ return commandLine;
+ }
+
+ /**
+ * Override the project working directory.
+ *
+ * @param localPath The path on disk.
+ */
+ public void setLocalpath(Path localPath) {
+ super.setInternalLocalPath(localPath.toString());
+ }
+
+ /**
+ * Get files recursively. Defaults to false.
+ *
+ * @param recursive The boolean value for recursive.
+ */
+ public final void setRecursive(boolean recursive) {
+ super.setInternalRecursive(recursive);
+ }
+
+ /**
+ * Enable quiet mode. Defaults to false.
+ *
+ * @param quiet The boolean value for quiet.
+ */
+ public final void setQuiet (boolean quiet) {
+ super.setInternalQuiet(quiet);
+ }
+
+ /**
+ * Unset the READ-ONLY flag on files retrieved from VSS. Defaults to false.
+ *
+ * @param writable The boolean value for writable.
+ */
+ public final void setWritable(boolean writable) {
+ super.setInternalWritable(writable);
+ }
+
+ /**
+ * Version to get.
+ *
+ * @param version The version to get.
+ *
+ * @ant.attribute group="vdl"
+ */
+ public void setVersion(String version) {
+ super.setInternalVersion(version);
+ }
+
+ /**
+ * Date to get.
+ *
+ * @param date The date to get.
+ *
+ * @ant.attribute group="vdl"
+ */
+ public void setDate(String date) {
+ super.setInternalDate(date);
+ }
+
+ /**
+ * Label to get.
+ *
+ * @param label The label to get.
+ *
+ * @ant.attribute group="vdl"
+ */
+ public void setLabel(String label) {
+ super.setInternalLabel(label);
+ }
+
+ /**
+ * Autoresponce behaviour. Valid options are Y and N.
+ *
+ * @param response The auto response value.
+ */
+ public void setAutoresponse(String response) {
+ super.setInternalAutoResponse(response);
+ }
+
+ /**
+ * Date and time stamp given to the local copy. Defaults to <code>current</code>.
+ *
+ * @param timestamp The file time stamping behaviour.
+ */
+ public void setFileTimeStamp(CurrentModUpdated timestamp) {
+ super.setInternalFileTimeStamp(timestamp);
+ }
+
+ /**
+ * Action taken when local files are writable. Defaults to <code>fail</code>.
+ * <p>
+ * Due to ss.exe returning with an exit code of '100' for both errors and when
+ * a file has been skipped, <code>failonerror</code> is set to false when using
+ * the <code>skip</code> option.
+ *
+ * @param files The action to take.
+ */
+ public void setWritableFiles(WritableFiles files) {
+ super.setInternalWritableFiles(files);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/vss/MSVSSHISTORY.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/vss/MSVSSHISTORY.java
new file mode 100644
index 00000000..05ec91c2
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/vss/MSVSSHISTORY.java
@@ -0,0 +1,199 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.vss;
+
+import java.io.File;
+import java.text.SimpleDateFormat;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.types.Commandline;
+import org.apache.tools.ant.types.EnumeratedAttribute;
+
+/**
+ * Performs History commands to Microsoft Visual SourceSafe.
+ *
+ * @ant.task name="vsshistory" category="scm"
+ */
+public class MSVSSHISTORY extends MSVSS {
+
+ /**
+ * Builds a command line to execute ss.
+ * @return The constructed commandline.
+ */
+ Commandline buildCmdLine() {
+ Commandline commandLine = new Commandline();
+
+ // first off, make sure that we've got a command and a vssdir and a label ...
+ if (getVsspath() == null) {
+ String msg = "vsspath attribute must be set!";
+ throw new BuildException(msg, getLocation());
+ }
+
+ // build the command line from what we got the format is
+ // ss History elements [-H] [-L] [-N] [-O] [-V] [-Y] [-#] [-?]
+ // as specified in the SS.EXE help
+ commandLine.setExecutable(getSSCommand());
+ commandLine.createArgument().setValue(COMMAND_HISTORY);
+
+ // VSS items
+ commandLine.createArgument().setValue(getVsspath());
+ // -I-
+ commandLine.createArgument().setValue(FLAG_AUTORESPONSE_DEF); // ignore all errors
+ // -Vd
+ commandLine.createArgument().setValue(getVersionDate());
+ // -VL
+ commandLine.createArgument().setValue(getVersionLabel());
+ // -R
+ commandLine.createArgument().setValue(getRecursive());
+ // -B / -D / -F-
+ commandLine.createArgument().setValue(getStyle());
+ // -Y
+ commandLine.createArgument().setValue(getLogin());
+ // -O
+ commandLine.createArgument().setValue(getOutput());
+
+ return commandLine;
+ }
+
+ /**
+ * Retrieve history recursively. Defaults to false.
+ *
+ * @param recursive The boolean value for recursive.
+ */
+ public void setRecursive(boolean recursive) {
+ super.setInternalRecursive(recursive);
+ }
+
+ /**
+ * Name of the user whose change history is generated.
+ *
+ * @param user The username.
+ */
+ public void setUser(String user) {
+ super.setInternalUser(user);
+ }
+
+ /**
+ * Date representing the 'start' of the range.
+ *
+ * @param fromDate The start date.
+ */
+ public void setFromDate(String fromDate) {
+ super.setInternalFromDate(fromDate);
+ }
+
+ /**
+ * Date representing the 'end' of the range.
+ *
+ * @param toDate The end date.
+ */
+ public void setToDate(String toDate) {
+ super.setInternalToDate(toDate);
+ }
+
+ /**
+ * Label representing the 'start' of the range.
+ *
+ * @param fromLabel The start label.
+ */
+ public void setFromLabel(String fromLabel) {
+ super.setInternalFromLabel(fromLabel);
+ }
+
+ /**
+ * Label representing the 'end' of the range.
+ *
+ * @param toLabel The end label.
+ */
+ public void setToLabel(String toLabel) {
+ super.setInternalToLabel(toLabel);
+ }
+
+ /**
+ * Number of days for comparison.
+ * Defaults to 2 days.
+ *
+ * @param numd The number of days.
+ */
+ public void setNumdays(int numd) {
+ super.setInternalNumDays(numd);
+ }
+
+ /**
+ * Output file name for the history.
+ *
+ * @param outfile The output file name.
+ */
+ public void setOutput(File outfile) {
+ if (outfile != null) {
+ super.setInternalOutputFilename(outfile.getAbsolutePath());
+ }
+ }
+
+ /**
+ * Format of dates in <code>fromDate</code and <code>toDate</code>.
+ * Used when calculating dates with the numdays attribute.
+ * This string uses the formatting rules of <code>SimpleDateFormat</code>.
+ * Defaults to <code>DateFormat.SHORT</code>.
+ *
+ * @param dateFormat The date format.
+ */
+ public void setDateFormat(String dateFormat) {
+ super.setInternalDateFormat(new SimpleDateFormat(dateFormat));
+ }
+
+ /**
+ * Output style. Valid options are:
+ * <ul>
+ * <li>brief: -B Display a brief history.
+ * <li>codediff: -D Display line-by-line file changes.
+ * <li>nofile: -F- Do not display individual file updates in the project history.
+ * <li>default: No option specified. Display in Source Safe's default format.
+ * </ul>
+ *
+ * @param attr The history style:
+ */
+ public void setStyle(BriefCodediffNofile attr) {
+ String option = attr.getValue();
+ if (option.equals(STYLE_BRIEF)) {
+ super.setInternalStyle(FLAG_BRIEF);
+ } else if (option.equals(STYLE_CODEDIFF)) {
+ super.setInternalStyle(FLAG_CODEDIFF);
+ } else if (option.equals(STYLE_DEFAULT)) {
+ super.setInternalStyle("");
+ } else if (option.equals(STYLE_NOFILE)) {
+ super.setInternalStyle(FLAG_NO_FILE);
+ } else {
+ throw new BuildException("Style " + attr + " unknown.", getLocation());
+ }
+ }
+
+ /**
+ * Extension of EnumeratedAttribute to hold the values for style.
+ */
+ public static class BriefCodediffNofile extends EnumeratedAttribute {
+ /**
+ * Gets the list of allowable values.
+ * @return The values.
+ */
+ public String[] getValues() {
+ return new String[] {STYLE_BRIEF, STYLE_CODEDIFF, STYLE_NOFILE, STYLE_DEFAULT};
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/vss/MSVSSLABEL.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/vss/MSVSSLABEL.java
new file mode 100644
index 00000000..4ba9d7b3
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/vss/MSVSSLABEL.java
@@ -0,0 +1,108 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.vss;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.types.Commandline;
+
+/**
+ * Performs Label commands to Microsoft Visual SourceSafe.
+ *
+ * @ant.task name="vsslabel" category="scm"
+ */
+public class MSVSSLABEL extends MSVSS {
+
+ /**
+ * Builds a command line to execute ss.
+ * @return The constructed commandline.
+ */
+ Commandline buildCmdLine() {
+ Commandline commandLine = new Commandline();
+
+ // first off, make sure that we've got a command and a vssdir and a label ...
+ if (getVsspath() == null) {
+ throw new BuildException("vsspath attribute must be set!", getLocation());
+ }
+
+ String label = getLabel();
+ if (label.equals("")) {
+ String msg = "label attribute must be set!";
+ throw new BuildException(msg, getLocation());
+ }
+
+ // build the command line from what we got the format is
+ // ss Label VSS items [-C] [-H] [-I-] [-Llabel] [-N] [-O] [-V] [-Y] [-?]
+ // as specified in the SS.EXE help
+ commandLine.setExecutable(getSSCommand());
+ commandLine.createArgument().setValue(COMMAND_LABEL);
+
+ // VSS items
+ commandLine.createArgument().setValue(getVsspath());
+ // -C
+ commandLine.createArgument().setValue(getComment());
+ // -I- or -I-Y or -I-N
+ commandLine.createArgument().setValue(getAutoresponse());
+ // -L Specify the new label on the command line (instead of being prompted)
+ commandLine.createArgument().setValue(label);
+ // -V Label an existing file or project version
+ commandLine.createArgument().setValue(getVersion());
+ // -Y
+ commandLine.createArgument().setValue(getLogin());
+
+ return commandLine;
+ }
+
+ /**
+ * Label to apply in SourceSafe.
+ *
+ * @param label The label to apply.
+ *
+ * @ant.attribute group="required"
+ */
+ public void setLabel(String label) {
+ super.setInternalLabel(label);
+ }
+
+ /**
+ * Version to label.
+ *
+ * @param version The version to label.
+ */
+ public void setVersion(String version) {
+ super.setInternalVersion(version);
+ }
+
+ /**
+ * Comment to apply to files labeled in SourceSafe.
+ *
+ * @param comment The comment to apply in SourceSafe
+ */
+ public void setComment(String comment) {
+ super.setInternalComment(comment);
+ }
+
+ /**
+ * Autoresponce behaviour. Valid options are Y and N.
+ *
+ * @param response The auto response value.
+ */
+ public void setAutoresponse(String response) {
+ super.setInternalAutoResponse(response);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/windows/Attrib.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/windows/Attrib.java
new file mode 100644
index 00000000..e0291914
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/optional/windows/Attrib.java
@@ -0,0 +1,196 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.windows;
+
+import java.io.File;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.taskdefs.ExecuteOn;
+import org.apache.tools.ant.taskdefs.condition.Os;
+import org.apache.tools.ant.types.FileSet;
+
+/**
+ * Attrib equivalent for Win32 environments.
+ * Note: Attrib parameters /S and /D are not handled.
+ *
+ * @since Ant 1.6
+ */
+public class Attrib extends ExecuteOn {
+
+ private static final String ATTR_READONLY = "R";
+ private static final String ATTR_ARCHIVE = "A";
+ private static final String ATTR_SYSTEM = "S";
+ private static final String ATTR_HIDDEN = "H";
+ private static final String SET = "+";
+ private static final String UNSET = "-";
+
+ private boolean haveAttr = false;
+
+ /** Constructor for Attrib. */
+ public Attrib() {
+ super.setExecutable("attrib");
+ super.setParallel(false);
+ }
+
+ /**
+ * A file to be attribed.
+ * @param src a file
+ */
+ public void setFile(File src) {
+ FileSet fs = new FileSet();
+ fs.setFile(src);
+ addFileset(fs);
+ }
+
+ /**
+ * Set the ReadOnly file attribute.
+ * @param value a <code>boolean</code> value
+ */
+ public void setReadonly(boolean value) {
+ addArg(value, ATTR_READONLY);
+ }
+
+ /**
+ * Set the Archive file attribute.
+ * @param value a <code>boolean</code> value
+ */
+ public void setArchive(boolean value) {
+ addArg(value, ATTR_ARCHIVE);
+ }
+
+ /**
+ * Set the System file attribute.
+ * @param value a <code>boolean</code> value
+ */
+ public void setSystem(boolean value) {
+ addArg(value, ATTR_SYSTEM);
+ }
+
+ /**
+ * Set the Hidden file attribute.
+ * @param value a <code>boolean</code> value
+ */
+ public void setHidden(boolean value) {
+ addArg(value, ATTR_HIDDEN);
+ }
+
+ /**
+ * Check the attributes.
+ */
+ protected void checkConfiguration() {
+ if (!haveAttr()) {
+ throw new BuildException("Missing attribute parameter",
+ getLocation());
+ }
+ super.checkConfiguration();
+ }
+
+ /**
+ * Set the executable.
+ * This is not allowed, and it always throws a BuildException.
+ * @param e ignored
+ * @ant.attribute ignore="true"
+ */
+ public void setExecutable(String e) {
+ throw new BuildException(getTaskType()
+ + " doesn\'t support the executable attribute", getLocation());
+ }
+
+ /**
+ * Set the executable.
+ * This is not allowed, and it always throws a BuildException.
+ * @param e ignored
+ * @ant.attribute ignore="true"
+ */
+ public void setCommand(String e) {
+ throw new BuildException(getTaskType()
+ + " doesn\'t support the command attribute", getLocation());
+ }
+
+ /**
+ * Add source file.
+ * This is not allowed, and it always throws a BuildException.
+ * @param b ignored
+ * @ant.attribute ignore="true"
+ */
+ public void setAddsourcefile(boolean b) {
+ throw new BuildException(getTaskType()
+ + " doesn\'t support the addsourcefile attribute", getLocation());
+ }
+
+ /**
+ * Set skip empty file sets.
+ * This is not allowed, and it always throws a BuildException.
+ * @param skip ignored
+ * @ant.attribute ignore="true"
+ */
+ public void setSkipEmptyFilesets(boolean skip) {
+ throw new BuildException(getTaskType() + " doesn\'t support the "
+ + "skipemptyfileset attribute",
+ getLocation());
+ }
+
+ /**
+ * Set parallel.
+ * This is not allowed, and it always throws a BuildException.
+ * @param parallel ignored
+ * @ant.attribute ignore="true"
+ */
+ public void setParallel(boolean parallel) {
+ throw new BuildException(getTaskType()
+ + " doesn\'t support the parallel attribute",
+ getLocation());
+ }
+
+ /**
+ * Set max parallel.
+ * This is not allowed, and it always throws a BuildException.
+ * @param max ignored
+ * @ant.attribute ignore="true"
+ */
+ public void setMaxParallel(int max) {
+ throw new BuildException(getTaskType()
+ + " doesn\'t support the maxparallel attribute",
+ getLocation());
+ }
+
+ /**
+ * Check if the os is valid.
+ * Default is to allow windows
+ * @return true if the os is valid.
+ */
+ protected boolean isValidOs() {
+ return getOs() == null && getOsFamily() == null ?
+ Os.isFamily(Os.FAMILY_WINDOWS) : super.isValidOs();
+ }
+
+ private static String getSignString(boolean attr) {
+ return (attr ? SET : UNSET);
+ }
+
+ private void addArg(boolean sign, String attribute) {
+ createArg().setValue(getSignString(sign) + attribute);
+ haveAttr = true;
+ }
+
+ private boolean haveAttr() {
+ return haveAttr;
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/rmic/DefaultRmicAdapter.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/rmic/DefaultRmicAdapter.java
new file mode 100644
index 00000000..bb2cfaab
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/rmic/DefaultRmicAdapter.java
@@ -0,0 +1,493 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.rmic;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+import java.util.Vector;
+
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.Rmic;
+import org.apache.tools.ant.types.Commandline;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.util.FileNameMapper;
+import org.apache.tools.ant.util.StringUtils;
+
+/**
+ * This is the default implementation for the RmicAdapter interface.
+ * Currently, this is a cut-and-paste of the original rmic task and
+ * DefaultCompilerAdapter.
+ *
+ * @since Ant 1.4
+ */
+public abstract class DefaultRmicAdapter implements RmicAdapter {
+
+ private Rmic attributes;
+ private FileNameMapper mapper;
+ private static final Random RAND = new Random();
+ /** suffix denoting a stub file: {@value} */
+ public static final String RMI_STUB_SUFFIX = "_Stub";
+ /** suffix denoting a skel file: {@value} */
+ public static final String RMI_SKEL_SUFFIX = "_Skel";
+ /** suffix denoting a tie file: {@value} */
+ public static final String RMI_TIE_SUFFIX = "_Tie";
+ /** arg for compat: {@value} */
+ public static final String STUB_COMPAT = "-vcompat";
+ /** arg for 1.1: {@value} */
+ public static final String STUB_1_1 = "-v1.1";
+ /** arg for 1.2: {@value} */
+ public static final String STUB_1_2 = "-v1.2";
+
+ /**
+ * option for stub 1.1 in the rmic task: {@value}
+ */
+ public static final String STUB_OPTION_1_1 = "1.1";
+ /**
+ * option for stub 1.2 in the rmic task: {@value}
+ */
+ public static final String STUB_OPTION_1_2 = "1.2";
+ /**
+ * option for stub compat in the rmic task: {@value}
+ */
+ public static final String STUB_OPTION_COMPAT = "compat";
+
+ /**
+ * Default constructor
+ */
+ public DefaultRmicAdapter() {
+ }
+
+ /**
+ * Sets Rmic attributes
+ * @param attributes the rmic attributes
+ */
+ public void setRmic(final Rmic attributes) {
+ this.attributes = attributes;
+ mapper = new RmicFileNameMapper();
+ }
+
+ /**
+ * Get the Rmic attributes
+ * @return the attributes as a Rmic taskdef
+ */
+ public Rmic getRmic() {
+ return attributes;
+ }
+
+ /**
+ * Gets the stub class suffix
+ * @return the stub suffix &quot;_Stub&quot;
+ */
+ protected String getStubClassSuffix() {
+ return RMI_STUB_SUFFIX;
+ }
+
+ /**
+ * Gets the skeleton class suffix
+ * @return the skeleton suffix &quot;_Skel&quot;
+ */
+ protected String getSkelClassSuffix() {
+ return RMI_SKEL_SUFFIX;
+ }
+
+ /**
+ * Gets the tie class suffix
+ * @return the tie suffix &quot;_Tie&quot;
+ */
+ protected String getTieClassSuffix() {
+ return RMI_TIE_SUFFIX;
+ }
+
+ /**
+ * This implementation returns a mapper that may return up to two
+ * file names.
+ *
+ * <ul>
+ * <li>for JRMP it will return *_getStubClassSuffix (and
+ * *_getSkelClassSuffix if JDK 1.1 is used)</li>
+ *
+ * <li>for IDL it will return a random name, causing &lt;rmic&gt; to
+ * always recompile.</li>
+ *
+ * <li>for IIOP it will return _*_getStubClassSuffix for
+ * interfaces and _*_getStubClassSuffix for non-interfaces (and
+ * determine the interface and create _*_Stub from that).</li>
+ * </ul>
+ * @return a <code>FileNameMapper</code>
+ */
+ public FileNameMapper getMapper() {
+ return mapper;
+ }
+
+ /**
+ * Gets the CLASSPATH this rmic process will use.
+ * @return the classpath
+ */
+ public Path getClasspath() {
+ return getCompileClasspath();
+ }
+
+ /**
+ * Builds the compilation classpath.
+ * @return the classpath
+ */
+ protected Path getCompileClasspath() {
+ Path classpath = new Path(attributes.getProject());
+ // add dest dir to classpath so that previously compiled and
+ // untouched classes are on classpath
+ classpath.setLocation(attributes.getBase());
+
+ // Combine the build classpath with the system classpath, in an
+ // order determined by the value of build.sysclasspath
+
+ Path cp = attributes.getClasspath();
+ if (cp == null) {
+ cp = new Path(attributes.getProject());
+ }
+ if (attributes.getIncludeantruntime()) {
+ classpath.addExisting(cp.concatSystemClasspath("last"));
+ } else {
+ classpath.addExisting(cp.concatSystemClasspath("ignore"));
+ }
+
+ if (attributes.getIncludejavaruntime()) {
+ classpath.addJavaRuntime();
+ }
+ return classpath;
+ }
+
+ /**
+ * Setup rmic argument for rmic.
+ * @return the command line
+ */
+ protected Commandline setupRmicCommand() {
+ return setupRmicCommand(null);
+ }
+
+ /**
+ * Setup rmic argument for rmic.
+ * @param options additional parameters needed by a specific
+ * implementation.
+ * @return the command line
+ */
+ protected Commandline setupRmicCommand(String[] options) {
+ Commandline cmd = new Commandline();
+
+ if (options != null) {
+ for (int i = 0; i < options.length; i++) {
+ cmd.createArgument().setValue(options[i]);
+ }
+ }
+
+ Path classpath = getCompileClasspath();
+
+ cmd.createArgument().setValue("-d");
+ cmd.createArgument().setFile(attributes.getOutputDir());
+
+ if (attributes.getExtdirs() != null) {
+ cmd.createArgument().setValue("-extdirs");
+ cmd.createArgument().setPath(attributes.getExtdirs());
+ }
+
+ cmd.createArgument().setValue("-classpath");
+ cmd.createArgument().setPath(classpath);
+ String stubOption = addStubVersionOptions();
+ if (stubOption != null) {
+ //set the non-null stubOption
+ cmd.createArgument().setValue(stubOption);
+ }
+
+
+ if (null != attributes.getSourceBase()) {
+ cmd.createArgument().setValue("-keepgenerated");
+ }
+
+ if (attributes.getIiop()) {
+ attributes.log("IIOP has been turned on.", Project.MSG_INFO);
+ cmd.createArgument().setValue("-iiop");
+ if (attributes.getIiopopts() != null) {
+ attributes.log("IIOP Options: " + attributes.getIiopopts(),
+ Project.MSG_INFO);
+ cmd.createArgument().setValue(attributes.getIiopopts());
+ }
+ }
+
+ if (attributes.getIdl()) {
+ cmd.createArgument().setValue("-idl");
+ attributes.log("IDL has been turned on.", Project.MSG_INFO);
+ if (attributes.getIdlopts() != null) {
+ cmd.createArgument().setValue(attributes.getIdlopts());
+ attributes.log("IDL Options: " + attributes.getIdlopts(),
+ Project.MSG_INFO);
+ }
+ }
+
+ if (attributes.getDebug()) {
+ cmd.createArgument().setValue("-g");
+ }
+
+ String[] compilerArgs = attributes.getCurrentCompilerArgs();
+ compilerArgs = preprocessCompilerArgs(compilerArgs);
+ cmd.addArguments(compilerArgs);
+
+ logAndAddFilesToCompile(cmd);
+ return cmd;
+ }
+
+ /**
+ * This is an override point; get the stub version off the rmic command and
+ * translate that into a compiler-specific argument
+ * @return a string to use for the stub version; can be null
+ * @since Ant1.7.1
+ */
+ protected String addStubVersionOptions() {
+ //handle the many different stub options.
+ String stubVersion = attributes.getStubVersion();
+ //default is compatibility
+ String stubOption = null;
+ if (null != stubVersion) {
+ if (STUB_OPTION_1_1.equals(stubVersion)) {
+ stubOption = STUB_1_1;
+ } else if (STUB_OPTION_1_2.equals(stubVersion)) {
+ stubOption = STUB_1_2;
+ } else if (STUB_OPTION_COMPAT.equals(stubVersion)) {
+ stubOption = STUB_COMPAT;
+ } else {
+ //anything else
+ attributes.log("Unknown stub option " + stubVersion);
+ //do nothing with the value? or go -v+stubVersion??
+ }
+ }
+ //for java1.5+, we generate compatible stubs, that is, unless
+ //the caller asked for IDL or IIOP support.
+ if (stubOption == null
+ && !attributes.getIiop()
+ && !attributes.getIdl()) {
+ stubOption = STUB_COMPAT;
+ }
+ return stubOption;
+ }
+
+ /**
+ * Preprocess the compiler arguments in any way you see fit.
+ * This is to allow compiler adapters to validate or filter the arguments.
+ * The base implementation returns the original compiler arguments unchanged.
+ * @param compilerArgs the original compiler arguments
+ * @return the filtered set.
+ */
+ protected String[] preprocessCompilerArgs(String[] compilerArgs) {
+ return compilerArgs;
+ }
+
+
+ /**
+ * Strip out all -J args from the command list. Invoke this from
+ * {@link #preprocessCompilerArgs(String[])} if you have a non-forking
+ * compiler.
+ * @param compilerArgs the original compiler arguments
+ * @return the filtered set.
+ */
+ protected String[] filterJvmCompilerArgs(String[] compilerArgs) {
+ int len = compilerArgs.length;
+ List args = new ArrayList(len);
+ for (int i = 0; i < len; i++) {
+ String arg = compilerArgs[i];
+ if (!arg.startsWith("-J")) {
+ args.add(arg);
+ } else {
+ attributes.log("Dropping " + arg + " from compiler arguments");
+ }
+ }
+ int count = args.size();
+ return (String[]) args.toArray(new String[count]);
+ }
+
+
+ /**
+ * Logs the compilation parameters, adds the files to compile and logs the
+ * &quot;niceSourceList&quot;
+ * @param cmd the commandline args
+ */
+ protected void logAndAddFilesToCompile(Commandline cmd) {
+ Vector compileList = attributes.getCompileList();
+
+ attributes.log("Compilation " + cmd.describeArguments(),
+ Project.MSG_VERBOSE);
+
+ StringBuffer niceSourceList = new StringBuffer("File");
+ int cListSize = compileList.size();
+ if (cListSize != 1) {
+ niceSourceList.append("s");
+ }
+ niceSourceList.append(" to be compiled:");
+
+ for (int i = 0; i < cListSize; i++) {
+ String arg = (String) compileList.elementAt(i);
+ cmd.createArgument().setValue(arg);
+ niceSourceList.append(" ");
+ niceSourceList.append(arg);
+ }
+
+ attributes.log(niceSourceList.toString(), Project.MSG_VERBOSE);
+ }
+
+ /**
+ * Mapper that may return up to two file names.
+ *
+ * <ul>
+ * <li>for JRMP it will return *_getStubClassSuffix (and
+ * *_getSkelClassSuffix if JDK 1.1 is used)</li>
+ *
+ * <li>for IDL it will return a random name, causing <rmic> to
+ * always recompile.</li>
+ *
+ * <li>for IIOP it will return _*_getStubClassSuffix for
+ * interfaces and _*_getStubClassSuffix for non-interfaces (and
+ * determine the interface and create _*_Stub from that).</li>
+ * </ul>
+ */
+ private class RmicFileNameMapper implements FileNameMapper {
+
+ RmicFileNameMapper() {
+ }
+
+ /**
+ * Empty implementation.
+ */
+ public void setFrom(String s) {
+ }
+ /**
+ * Empty implementation.
+ */
+ public void setTo(String s) {
+ }
+
+ public String[] mapFileName(String name) {
+ if (name == null
+ || !name.endsWith(".class")
+ || name.endsWith(getStubClassSuffix() + ".class")
+ || name.endsWith(getSkelClassSuffix() + ".class")
+ || name.endsWith(getTieClassSuffix() + ".class")) {
+ // Not a .class file or the one we'd generate
+ return null;
+ }
+
+ // we know that name.endsWith(".class")
+ String base = StringUtils.removeSuffix(name, ".class");
+
+ String classname = base.replace(File.separatorChar, '.');
+ if (attributes.getVerify()
+ && !attributes.isValidRmiRemote(classname)) {
+ return null;
+ }
+
+ /*
+ * fallback in case we have trouble loading the class or
+ * don't know how to handle it (there is no easy way to
+ * know what IDL mode would generate.
+ *
+ * This is supposed to make Ant always recompile the
+ * class, as a file of that name should not exist.
+ */
+ String[] target = new String[] {name + ".tmp." + RAND.nextLong()};
+
+ if (!attributes.getIiop() && !attributes.getIdl()) {
+ // JRMP with simple naming convention
+ if (STUB_OPTION_1_2.equals(attributes.getStubVersion())) {
+ target = new String[] {
+ base + getStubClassSuffix() + ".class"
+ };
+ } else {
+ target = new String[] {
+ base + getStubClassSuffix() + ".class",
+ base + getSkelClassSuffix() + ".class",
+ };
+ }
+ } else if (!attributes.getIdl()) {
+ int lastSlash = base.lastIndexOf(File.separatorChar);
+
+ String dirname = "";
+ /*
+ * I know, this is not necessary, but I prefer it explicit (SB)
+ */
+ int index = -1;
+ if (lastSlash == -1) {
+ // no package
+ index = 0;
+ } else {
+ index = lastSlash + 1;
+ dirname = base.substring(0, index);
+ }
+
+ String filename = base.substring(index);
+
+ try {
+ Class c = attributes.getLoader().loadClass(classname);
+
+ if (c.isInterface()) {
+ // only stub, no tie
+ target = new String[] {
+ dirname + "_" + filename + getStubClassSuffix()
+ + ".class"
+ };
+ } else {
+ /*
+ * stub is derived from implementation,
+ * tie from interface name.
+ */
+ Class interf = attributes.getRemoteInterface(c);
+ String iName = interf.getName();
+ String iDir = "";
+ int iIndex = -1;
+ int lastDot = iName.lastIndexOf(".");
+ if (lastDot == -1) {
+ // no package
+ iIndex = 0;
+ } else {
+ iIndex = lastDot + 1;
+ iDir = iName.substring(0, iIndex);
+ iDir = iDir.replace('.', File.separatorChar);
+ }
+
+ target = new String[] {
+ dirname + "_" + filename + getTieClassSuffix()
+ + ".class",
+ iDir + "_" + iName.substring(iIndex)
+ + getStubClassSuffix() + ".class"
+ };
+ }
+ } catch (ClassNotFoundException e) {
+ attributes.log("Unable to verify class " + classname
+ + ". It could not be found.",
+ Project.MSG_WARN);
+ } catch (NoClassDefFoundError e) {
+ attributes.log("Unable to verify class " + classname
+ + ". It is not defined.", Project.MSG_WARN);
+ } catch (Throwable t) {
+ attributes.log("Unable to verify class " + classname
+ + ". Loading caused Exception: "
+ + t.getMessage(), Project.MSG_WARN);
+ }
+ }
+ return target;
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/rmic/ForkingSunRmic.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/rmic/ForkingSunRmic.java
new file mode 100644
index 00000000..81bd7971
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/rmic/ForkingSunRmic.java
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+
+package org.apache.tools.ant.taskdefs.rmic;
+
+import java.io.IOException;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.Execute;
+import org.apache.tools.ant.taskdefs.LogStreamHandler;
+import org.apache.tools.ant.taskdefs.Rmic;
+import org.apache.tools.ant.types.Commandline;
+import org.apache.tools.ant.util.JavaEnvUtils;
+
+/**
+ * This is an extension of the sun rmic compiler, which forks rather than
+ * executes it inline. Why so? Because rmic is dog slow, but if you fork the
+ * compiler you can have multiple copies compiling different bits of your project
+ * at the same time. Which, on a multi-cpu system results in significant speedups.
+ *
+ * Also, Java1.6 behaves oddly with -XNew, so we switch it on here if needed.
+ * @since ant1.7
+ */
+public class ForkingSunRmic extends DefaultRmicAdapter {
+
+ /**
+ * the name of this adapter for users to select
+ */
+ public static final String COMPILER_NAME = "forking";
+
+ /**
+ * exec by creating a new command
+ * @return true if the command ran successfully
+ * @throws BuildException on error
+ */
+ public boolean execute() throws BuildException {
+ Rmic owner = getRmic();
+ Commandline cmd = setupRmicCommand();
+ Project project = owner.getProject();
+ String executable = owner.getExecutable();
+ if (executable == null) {
+ // no explicitly specified executable
+ // rely on RMIC being on the path
+ executable = JavaEnvUtils.getJdkExecutable(getExecutableName());
+ }
+ cmd.setExecutable(executable);
+
+ //set up the args
+ String[] args = cmd.getCommandline();
+
+ try {
+ Execute exe = new Execute(new LogStreamHandler(owner,
+ Project.MSG_INFO,
+ Project.MSG_WARN));
+ exe.setAntRun(project);
+ exe.setWorkingDirectory(project.getBaseDir());
+ exe.setCommandline(args);
+ exe.execute();
+ return !exe.isFailure();
+ } catch (IOException exception) {
+ throw new BuildException("Error running " + getExecutableName()
+ + " -maybe it is not on the path", exception);
+ }
+ }
+
+ /**
+ * Override point.
+ * @return the executable name.
+ */
+ protected String getExecutableName() {
+ return SunRmic.RMIC_EXECUTABLE;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/rmic/KaffeRmic.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/rmic/KaffeRmic.java
new file mode 100644
index 00000000..2108a68b
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/rmic/KaffeRmic.java
@@ -0,0 +1,104 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.rmic;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.ExecuteJava;
+import org.apache.tools.ant.types.Commandline;
+
+/**
+ * The implementation of the rmic for Kaffe
+ *
+ * @since Ant 1.4
+ */
+public class KaffeRmic extends DefaultRmicAdapter {
+ // sorted by newest Kaffe version first
+ private static final String[] RMIC_CLASSNAMES = new String[] {
+ "gnu.classpath.tools.rmi.rmic.RMIC",
+ // pre Kaffe 1.1.5
+ "gnu.java.rmi.rmic.RMIC",
+ // pre Kaffe 1.1.2
+ "kaffe.rmi.rmic.RMIC",
+ };
+
+ /**
+ * the name of this adapter for users to select
+ */
+ public static final String COMPILER_NAME = "kaffe";
+
+ /** {@inheritDoc} */
+ public boolean execute() throws BuildException {
+ getRmic().log("Using Kaffe rmic", Project.MSG_VERBOSE);
+ Commandline cmd = setupRmicCommand();
+
+ Class c = getRmicClass();
+ if (c == null) {
+ StringBuffer buf = new StringBuffer("Cannot use Kaffe rmic, as it"
+ + " is not available. None"
+ + " of ");
+ for (int i = 0; i < RMIC_CLASSNAMES.length; i++) {
+ if (i != 0) {
+ buf.append(", ");
+ }
+
+ buf.append(RMIC_CLASSNAMES[i]);
+ }
+ buf.append(" have been found. A common solution is to set the"
+ + " environment variable JAVA_HOME or CLASSPATH.");
+ throw new BuildException(buf.toString(),
+ getRmic().getLocation());
+ }
+
+ cmd.setExecutable(c.getName());
+ if (!c.getName().equals(RMIC_CLASSNAMES[RMIC_CLASSNAMES.length - 1])) {
+ // only supported since Kaffe 1.1.2
+ cmd.createArgument().setValue("-verbose");
+ getRmic().log(Commandline.describeCommand(cmd));
+ }
+ ExecuteJava ej = new ExecuteJava();
+ ej.setJavaCommand(cmd);
+ return ej.fork(getRmic()) == 0;
+ }
+
+ /**
+ * test for kaffe being on the system
+ * @return true if kaffe is on the current classpath
+ */
+ public static boolean isAvailable() {
+ return getRmicClass() != null;
+ }
+
+ /**
+ * tries to load Kaffe RMIC and falls back to the older class name
+ * if necessary.
+ *
+ * @return null if neither class can get loaded.
+ */
+ private static Class getRmicClass() {
+ for (int i = 0; i < RMIC_CLASSNAMES.length; i++) {
+ try {
+ return Class.forName(RMIC_CLASSNAMES[i]);
+ } catch (ClassNotFoundException cnfe) {
+ // Ignore
+ }
+ }
+ return null;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/rmic/RmicAdapter.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/rmic/RmicAdapter.java
new file mode 100644
index 00000000..2cabe2fa
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/rmic/RmicAdapter.java
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.rmic;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.taskdefs.Rmic;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.util.FileNameMapper;
+
+/**
+ * The interface that all rmic adapters must adhere to.
+ *
+ * <p>A rmic adapter is an adapter that interprets the rmic's
+ * parameters in preparation to be passed off to the compiler this
+ * adapter represents. As all the necessary values are stored in the
+ * Rmic task itself, the only thing all adapters need is the rmic
+ * task, the execute command and a parameterless constructor (for
+ * reflection).</p>
+ *
+ * @since Ant 1.4
+ */
+
+public interface RmicAdapter {
+
+ /**
+ * Sets the rmic attributes, which are stored in the Rmic task.
+ * @param attributes the rmic attributes to use
+ */
+ void setRmic(Rmic attributes);
+
+ /**
+ * Call the rmic compiler.
+ *
+ * @return true if has the compilation been successful
+ * @throws BuildException on error
+ */
+ boolean execute() throws BuildException;
+
+ /**
+ * Maps source class files to the files generated by this rmic
+ * implementation.
+ * @return the filename mapper used by this implementation
+ */
+ FileNameMapper getMapper();
+
+ /**
+ * The CLASSPATH this rmic process will use.
+ * @return the classpath this rmic process will use
+ */
+ Path getClasspath();
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/rmic/RmicAdapterFactory.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/rmic/RmicAdapterFactory.java
new file mode 100644
index 00000000..4a2708c7
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/rmic/RmicAdapterFactory.java
@@ -0,0 +1,135 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.rmic;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.util.ClasspathUtils;
+
+/**
+ * Creates the necessary rmic adapter, given basic criteria.
+ *
+ * @since 1.4
+ */
+public final class RmicAdapterFactory {
+ /** The error message to be used when the compiler cannot be found. */
+ public static final String ERROR_UNKNOWN_COMPILER = "Class not found: ";
+
+ /** The error message to be used when the class is not an rmic adapter. */
+ public static final String ERROR_NOT_RMIC_ADAPTER = "Class of unexpected Type: ";
+
+ /** If the compiler has this name use a default compiler. */
+ public static final String DEFAULT_COMPILER = "default";
+
+ /** This is a singleton -- can't create instances!! */
+ private RmicAdapterFactory() {
+ }
+
+ /**
+ * Based on the parameter passed in, this method creates the necessary
+ * factory desired.
+ *
+ * <p>The current mapping for rmic names are as follows:</p>
+ * <ul><li>sun = SUN's rmic
+ * <li>kaffe = Kaffe's rmic
+ * <li><i>a fully qualified classname</i> = the name of a rmic
+ * adapter
+ * <li>weblogic = weblogic compiler
+ * <li>forking = Sun's RMIC by forking a new JVM
+ * </ul>
+ *
+ * @param rmicType either the name of the desired rmic, or the
+ * full classname of the rmic's adapter.
+ * @param task a task to log through.
+ * @return the compiler adapter
+ * @throws BuildException if the rmic type could not be resolved into
+ * a rmic adapter.
+ */
+ public static RmicAdapter getRmic(String rmicType, Task task)
+ throws BuildException {
+ return getRmic(rmicType, task, null);
+ }
+
+ /**
+ * Based on the parameter passed in, this method creates the necessary
+ * factory desired.
+ *
+ * <p>The current mapping for rmic names are as follows:</p>
+ * <ul><li>sun = SUN's rmic
+ * <li>kaffe = Kaffe's rmic
+ * <li><i>a fully qualified classname</i> = the name of a rmic
+ * adapter
+ * <li>weblogic = weblogic compiler
+ * <li>forking = Sun's RMIC by forking a new JVM
+ * </ul>
+ *
+ * @param rmicType either the name of the desired rmic, or the
+ * full classname of the rmic's adapter.
+ * @param task a task to log through.
+ * @param classpath the classpath to use when looking up an
+ * adapter class
+ * @return the compiler adapter
+ * @throws BuildException if the rmic type could not be resolved into
+ * a rmic adapter.
+ * @since Ant 1.8.0
+ */
+ public static RmicAdapter getRmic(String rmicType, Task task,
+ Path classpath)
+ throws BuildException {
+ //handle default specially by choosing the sun or kaffe compiler
+ if (DEFAULT_COMPILER.equalsIgnoreCase(rmicType) || rmicType.length() == 0) {
+ rmicType = KaffeRmic.isAvailable()
+ ? KaffeRmic.COMPILER_NAME
+ : SunRmic.COMPILER_NAME;
+ }
+ if (SunRmic.COMPILER_NAME.equalsIgnoreCase(rmicType)) {
+ return new SunRmic();
+ } else if (KaffeRmic.COMPILER_NAME.equalsIgnoreCase(rmicType)) {
+ return new KaffeRmic();
+ } else if (WLRmic.COMPILER_NAME.equalsIgnoreCase(rmicType)) {
+ return new WLRmic();
+ } else if (ForkingSunRmic.COMPILER_NAME.equalsIgnoreCase(rmicType)) {
+ return new ForkingSunRmic();
+ } else if (XNewRmic.COMPILER_NAME.equalsIgnoreCase(rmicType)) {
+ return new XNewRmic();
+ }
+ //no match?
+ return resolveClassName(rmicType,
+ // Memory leak in line below
+ task.getProject().createClassLoader(classpath));
+ }
+
+ /**
+ * Tries to resolve the given classname into a rmic adapter.
+ * Throws a fit if it can't.
+ *
+ * @param className The fully qualified classname to be created.
+ * @param loader the classloader to use
+ * @throws BuildException This is the fit that is thrown if className
+ * isn't an instance of RmicAdapter.
+ */
+ private static RmicAdapter resolveClassName(String className,
+ ClassLoader loader)
+ throws BuildException {
+ return (RmicAdapter) ClasspathUtils.newInstance(className,
+ loader != null ? loader :
+ RmicAdapterFactory.class.getClassLoader(), RmicAdapter.class);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/rmic/SunRmic.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/rmic/SunRmic.java
new file mode 100644
index 00000000..07cbd306
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/rmic/SunRmic.java
@@ -0,0 +1,114 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.rmic;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.LogOutputStream;
+import org.apache.tools.ant.types.Commandline;
+
+/**
+ * The implementation of the rmic for SUN's JDK.
+ *
+ * @since Ant 1.4
+ */
+public class SunRmic extends DefaultRmicAdapter {
+
+ /**
+ * name of the class
+ */
+ public static final String RMIC_CLASSNAME = "sun.rmi.rmic.Main";
+
+ /**
+ * the name of this adapter for users to select
+ */
+ public static final String COMPILER_NAME = "sun";
+
+ /**
+ * name of the executable
+ */
+ public static final String RMIC_EXECUTABLE = "rmic";
+ /** Error message to use with the sun rmic is not the classpath. */
+ public static final String ERROR_NO_RMIC_ON_CLASSPATH = "Cannot use SUN rmic, as it is not "
+ + "available. A common solution is to "
+ + "set the environment variable "
+ + "JAVA_HOME";
+ /** Error message to use when there is an error starting the sun rmic compiler */
+ public static final String ERROR_RMIC_FAILED = "Error starting SUN rmic: ";
+
+ /**
+ * Run the rmic compiler.
+ * @return true if the compilation succeeded
+ * @throws BuildException on error
+ */
+ public boolean execute() throws BuildException {
+ getRmic().log("Using SUN rmic compiler", Project.MSG_VERBOSE);
+ Commandline cmd = setupRmicCommand();
+
+ // Create an instance of the rmic, redirecting output to
+ // the project log
+ LogOutputStream logstr = new LogOutputStream(getRmic(),
+ Project.MSG_WARN);
+
+ try {
+ Class c = Class.forName(RMIC_CLASSNAME);
+ Constructor cons
+ = c.getConstructor(new Class[] {OutputStream.class, String.class});
+ Object rmic = cons.newInstance(new Object[] {logstr, "rmic"});
+
+ Method doRmic = c.getMethod("compile",
+ new Class [] {String[].class});
+ Boolean ok =
+ (Boolean) doRmic.invoke(rmic,
+ (new Object[] {cmd.getArguments()}));
+ return ok.booleanValue();
+ } catch (ClassNotFoundException ex) {
+ throw new BuildException(ERROR_NO_RMIC_ON_CLASSPATH,
+ getRmic().getLocation());
+ } catch (Exception ex) {
+ if (ex instanceof BuildException) {
+ throw (BuildException) ex;
+ } else {
+ throw new BuildException(ERROR_RMIC_FAILED,
+ ex, getRmic().getLocation());
+ }
+ } finally {
+ try {
+ logstr.close();
+ } catch (IOException e) {
+ throw new BuildException(e);
+ }
+ }
+ }
+
+
+ /**
+ * Strip out all -J args from the command list.
+ * @param compilerArgs the original compiler arguments
+ * @return the filtered set.
+ */
+ protected String[] preprocessCompilerArgs(String[] compilerArgs) {
+ return filterJvmCompilerArgs(compilerArgs);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/rmic/WLRmic.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/rmic/WLRmic.java
new file mode 100644
index 00000000..3b1f2a19
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/rmic/WLRmic.java
@@ -0,0 +1,136 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.rmic;
+
+import java.lang.reflect.Method;
+
+import org.apache.tools.ant.AntClassLoader;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.Commandline;
+
+/**
+ * The implementation of the rmic for WebLogic
+ *
+ * @since Ant 1.4
+ */
+public class WLRmic extends DefaultRmicAdapter {
+ /** The classname of the weblogic rmic */
+ public static final String WLRMIC_CLASSNAME = "weblogic.rmic";
+ /**
+ * the name of this adapter for users to select
+ */
+ public static final String COMPILER_NAME = "weblogic";
+
+ /** The error string to use if not able to find the weblogic rmic */
+ public static final String ERROR_NO_WLRMIC_ON_CLASSPATH =
+ "Cannot use WebLogic rmic, as it is not "
+ + "available. Add it to Ant's classpath with the -lib option";
+
+ /** The error string to use if not able to start the weblogic rmic */
+ public static final String ERROR_WLRMIC_FAILED = "Error starting WebLogic rmic: ";
+ /** The stub suffix */
+ public static final String WL_RMI_STUB_SUFFIX = "_WLStub";
+ /** The skeleton suffix */
+ public static final String WL_RMI_SKEL_SUFFIX = "_WLSkel";
+ /** unsupported error message */
+ public static final String UNSUPPORTED_STUB_OPTION = "Unsupported stub option: ";
+
+ /**
+ * Carry out the rmic compilation.
+ * @return true if the compilation succeeded
+ * @throws BuildException on error
+ */
+ public boolean execute() throws BuildException {
+ getRmic().log("Using WebLogic rmic", Project.MSG_VERBOSE);
+ Commandline cmd = setupRmicCommand(new String[] {"-noexit"});
+
+ AntClassLoader loader = null;
+ try {
+ // Create an instance of the rmic
+ Class c = null;
+ if (getRmic().getClasspath() == null) {
+ c = Class.forName(WLRMIC_CLASSNAME);
+ } else {
+ loader
+ = getRmic().getProject().createClassLoader(getRmic().getClasspath());
+ c = Class.forName(WLRMIC_CLASSNAME, true, loader);
+ }
+ Method doRmic = c.getMethod("main",
+ new Class [] {String[].class});
+ doRmic.invoke(null, new Object[] {cmd.getArguments()});
+ return true;
+ } catch (ClassNotFoundException ex) {
+ throw new BuildException(ERROR_NO_WLRMIC_ON_CLASSPATH, getRmic().getLocation());
+ } catch (Exception ex) {
+ if (ex instanceof BuildException) {
+ throw (BuildException) ex;
+ } else {
+ throw new BuildException(ERROR_WLRMIC_FAILED, ex,
+ getRmic().getLocation());
+ }
+ } finally {
+ if (loader != null) {
+ loader.cleanup();
+ }
+ }
+ }
+
+ /**
+ * Get the suffix for the rmic stub classes
+ * @return the stub suffix
+ */
+ public String getStubClassSuffix() {
+ return WL_RMI_STUB_SUFFIX;
+ }
+
+ /**
+ * Get the suffix for the rmic skeleton classes
+ * @return the skeleton suffix
+ */
+ public String getSkelClassSuffix() {
+ return WL_RMI_SKEL_SUFFIX;
+ }
+
+ /**
+ * Strip out all -J args from the command list.
+ *
+ * @param compilerArgs the original compiler arguments
+ * @return the filtered set.
+ */
+ protected String[] preprocessCompilerArgs(String[] compilerArgs) {
+ return filterJvmCompilerArgs(compilerArgs);
+ }
+
+ /**
+ * This is an override point; no stub version is returned. If any
+ * stub option is set, a warning is printed.
+ * @return null, for no stub version
+ */
+ protected String addStubVersionOptions() {
+ //handle the many different stub options.
+ String stubVersion = getRmic().getStubVersion();
+ if (null != stubVersion) {
+ getRmic().log(UNSUPPORTED_STUB_OPTION + stubVersion,
+ Project.MSG_WARN);
+ }
+ return null;
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/rmic/XNewRmic.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/rmic/XNewRmic.java
new file mode 100644
index 00000000..559c7698
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/rmic/XNewRmic.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.rmic;
+
+import org.apache.tools.ant.types.Commandline;
+
+/**
+ * Run rmic in a new process with -Xnew set.
+ * This switches rmic to use a new compiler, one that doesn't work in-process
+ * on ant on java1.6.
+ * see: <a href="http://issues.apache.org/bugzilla/show_bug.cgi?id=38732">
+ * http://issues.apache.org/bugzilla/show_bug.cgi?id=38732</a>
+ */
+public class XNewRmic extends ForkingSunRmic {
+
+ /**
+ * the name of this adapter for users to select
+ */
+ public static final String COMPILER_NAME = "xnew";
+
+ /** No-arg constructor. */
+ public XNewRmic() {
+ }
+
+ /**
+ * Create a normal command line, then with -Xnew at the front
+ * @return a command line that hands off to thw
+ */
+ protected Commandline setupRmicCommand() {
+ String[] options = new String[] {
+ "-Xnew"
+ };
+ Commandline commandline = super.setupRmicCommand(options);
+ return commandline;
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/AbstractFileSet.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/AbstractFileSet.java
new file mode 100644
index 00000000..8f274a09
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/AbstractFileSet.java
@@ -0,0 +1,922 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.Stack;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.DirectoryScanner;
+import org.apache.tools.ant.FileScanner;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.selectors.AndSelector;
+import org.apache.tools.ant.types.selectors.ContainsRegexpSelector;
+import org.apache.tools.ant.types.selectors.ContainsSelector;
+import org.apache.tools.ant.types.selectors.DateSelector;
+import org.apache.tools.ant.types.selectors.DependSelector;
+import org.apache.tools.ant.types.selectors.DepthSelector;
+import org.apache.tools.ant.types.selectors.DifferentSelector;
+import org.apache.tools.ant.types.selectors.ExtendSelector;
+import org.apache.tools.ant.types.selectors.FileSelector;
+import org.apache.tools.ant.types.selectors.FilenameSelector;
+import org.apache.tools.ant.types.selectors.MajoritySelector;
+import org.apache.tools.ant.types.selectors.NoneSelector;
+import org.apache.tools.ant.types.selectors.NotSelector;
+import org.apache.tools.ant.types.selectors.OrSelector;
+import org.apache.tools.ant.types.selectors.PresentSelector;
+import org.apache.tools.ant.types.selectors.ReadableSelector;
+import org.apache.tools.ant.types.selectors.SelectSelector;
+import org.apache.tools.ant.types.selectors.SelectorContainer;
+import org.apache.tools.ant.types.selectors.SelectorScanner;
+import org.apache.tools.ant.types.selectors.SizeSelector;
+import org.apache.tools.ant.types.selectors.TypeSelector;
+import org.apache.tools.ant.types.selectors.WritableSelector;
+import org.apache.tools.ant.types.selectors.modifiedselector.ModifiedSelector;
+
+/**
+ * Class that holds an implicit patternset and supports nested
+ * patternsets and creates a DirectoryScanner using these patterns.
+ *
+ * <p>Common base class for DirSet and FileSet.</p>
+ *
+ */
+public abstract class AbstractFileSet extends DataType
+ implements Cloneable, SelectorContainer {
+
+ private PatternSet defaultPatterns = new PatternSet();
+ private List<PatternSet> additionalPatterns = new ArrayList<PatternSet>();
+ private List<FileSelector> selectors = new ArrayList<FileSelector>();
+
+ private File dir;
+ private boolean useDefaultExcludes = true;
+ private boolean caseSensitive = true;
+ private boolean followSymlinks = true;
+ private boolean errorOnMissingDir = true;
+ private int maxLevelsOfSymlinks = DirectoryScanner.MAX_LEVELS_OF_SYMLINKS;
+
+ /* cached DirectoryScanner instance for our own Project only */
+ private DirectoryScanner directoryScanner = null;
+
+ /**
+ * Construct a new <code>AbstractFileSet</code>.
+ */
+ public AbstractFileSet() {
+ super();
+ }
+
+ /**
+ * Construct a new <code>AbstractFileSet</code>, shallowly cloned
+ * from the specified <code>AbstractFileSet</code>.
+ * @param fileset the <code>AbstractFileSet</code> to use as a template.
+ */
+ protected AbstractFileSet(AbstractFileSet fileset) {
+ this.dir = fileset.dir;
+ this.defaultPatterns = fileset.defaultPatterns;
+ this.additionalPatterns = fileset.additionalPatterns;
+ this.selectors = fileset.selectors;
+ this.useDefaultExcludes = fileset.useDefaultExcludes;
+ this.caseSensitive = fileset.caseSensitive;
+ this.followSymlinks = fileset.followSymlinks;
+ this.errorOnMissingDir = fileset.errorOnMissingDir;
+ this.maxLevelsOfSymlinks = fileset.maxLevelsOfSymlinks;
+ setProject(fileset.getProject());
+ }
+
+ /**
+ * Makes this instance in effect a reference to another instance.
+ *
+ * <p>You must not set another attribute or nest elements inside
+ * this element if you make it a reference.</p>
+ * @param r the <code>Reference</code> to use.
+ * @throws BuildException on error
+ */
+ public void setRefid(Reference r) throws BuildException {
+ if (dir != null || defaultPatterns.hasPatterns(getProject())) {
+ throw tooManyAttributes();
+ }
+ if (!additionalPatterns.isEmpty()) {
+ throw noChildrenAllowed();
+ }
+ if (!selectors.isEmpty()) {
+ throw noChildrenAllowed();
+ }
+ super.setRefid(r);
+ }
+
+ /**
+ * Sets the base-directory for this instance.
+ * @param dir the directory's <code>File</code> instance.
+ * @throws BuildException on error
+ */
+ public synchronized void setDir(File dir) throws BuildException {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ this.dir = dir;
+ directoryScanner = null;
+ }
+
+ /**
+ * Retrieves the base-directory for this instance.
+ * @return <code>File</code>.
+ */
+ public File getDir() {
+ return getDir(getProject());
+ }
+
+ /**
+ * Retrieves the base-directory for this instance.
+ * @param p the <code>Project</code> against which the
+ * reference is resolved, if set.
+ * @return <code>File</code>.
+ */
+ public synchronized File getDir(Project p) {
+ if (isReference()) {
+ return getRef(p).getDir(p);
+ }
+ dieOnCircularReference();
+ return dir;
+ }
+
+ /**
+ * Creates a nested patternset.
+ * @return <code>PatternSet</code>.
+ */
+ public synchronized PatternSet createPatternSet() {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ PatternSet patterns = new PatternSet();
+ additionalPatterns.add(patterns);
+ directoryScanner = null;
+ return patterns;
+ }
+
+ /**
+ * Add a name entry to the include list.
+ * @return <code>PatternSet.NameEntry</code>.
+ */
+ public synchronized PatternSet.NameEntry createInclude() {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ directoryScanner = null;
+ return defaultPatterns.createInclude();
+ }
+
+ /**
+ * Add a name entry to the include files list.
+ * @return <code>PatternSet.NameEntry</code>.
+ */
+ public synchronized PatternSet.NameEntry createIncludesFile() {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ directoryScanner = null;
+ return defaultPatterns.createIncludesFile();
+ }
+
+ /**
+ * Add a name entry to the exclude list.
+ * @return <code>PatternSet.NameEntry</code>.
+ */
+ public synchronized PatternSet.NameEntry createExclude() {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ directoryScanner = null;
+ return defaultPatterns.createExclude();
+ }
+
+ /**
+ * Add a name entry to the excludes files list.
+ * @return <code>PatternSet.NameEntry</code>.
+ */
+ public synchronized PatternSet.NameEntry createExcludesFile() {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ directoryScanner = null;
+ return defaultPatterns.createExcludesFile();
+ }
+
+ /**
+ * Creates a single file fileset.
+ * @param file the single <code>File</code> included in this
+ * <code>AbstractFileSet</code>.
+ */
+ public synchronized void setFile(File file) {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ setDir(file.getParentFile());
+ createInclude().setName(file.getName());
+ }
+
+ /**
+ * Appends <code>includes</code> to the current list of include
+ * patterns.
+ *
+ * <p>Patterns may be separated by a comma or a space.</p>
+ *
+ * @param includes the <code>String</code> containing the include patterns.
+ */
+ public synchronized void setIncludes(String includes) {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ defaultPatterns.setIncludes(includes);
+ directoryScanner = null;
+ }
+
+ /**
+ * Appends <code>includes</code> to the current list of include
+ * patterns.
+ *
+ * @param includes array containing the include patterns.
+ * @since Ant 1.7
+ */
+ public synchronized void appendIncludes(String[] includes) {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ if (includes != null) {
+ for (int i = 0; i < includes.length; i++) {
+ defaultPatterns.createInclude().setName(includes[i]);
+ }
+ directoryScanner = null;
+ }
+ }
+
+ /**
+ * Appends <code>excludes</code> to the current list of exclude
+ * patterns.
+ *
+ * <p>Patterns may be separated by a comma or a space.</p>
+ *
+ * @param excludes the <code>String</code> containing the exclude patterns.
+ */
+ public synchronized void setExcludes(String excludes) {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ defaultPatterns.setExcludes(excludes);
+ directoryScanner = null;
+ }
+
+ /**
+ * Appends <code>excludes</code> to the current list of include
+ * patterns.
+ *
+ * @param excludes array containing the exclude patterns.
+ * @since Ant 1.7
+ */
+ public synchronized void appendExcludes(String[] excludes) {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ if (excludes != null) {
+ for (int i = 0; i < excludes.length; i++) {
+ defaultPatterns.createExclude().setName(excludes[i]);
+ }
+ directoryScanner = null;
+ }
+ }
+
+ /**
+ * Sets the <code>File</code> containing the includes patterns.
+ *
+ * @param incl <code>File</code> instance.
+ * @throws BuildException on error
+ */
+ public synchronized void setIncludesfile(File incl) throws BuildException {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ defaultPatterns.setIncludesfile(incl);
+ directoryScanner = null;
+ }
+
+ /**
+ * Sets the <code>File</code> containing the excludes patterns.
+ *
+ * @param excl <code>File</code> instance.
+ * @throws BuildException on error
+ */
+ public synchronized void setExcludesfile(File excl) throws BuildException {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ defaultPatterns.setExcludesfile(excl);
+ directoryScanner = null;
+ }
+
+ /**
+ * Sets whether default exclusions should be used or not.
+ *
+ * @param useDefaultExcludes <code>boolean</code>.
+ */
+ public synchronized void setDefaultexcludes(boolean useDefaultExcludes) {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ this.useDefaultExcludes = useDefaultExcludes;
+ directoryScanner = null;
+ }
+
+ /**
+ * Whether default exclusions should be used or not.
+ * @return the default exclusions value.
+ * @since Ant 1.6.3
+ */
+ public synchronized boolean getDefaultexcludes() {
+ if (isReference()) {
+ return getRef(getProject()).getDefaultexcludes();
+ }
+ dieOnCircularReference();
+ return useDefaultExcludes;
+ }
+
+ /**
+ * Sets case sensitivity of the file system.
+ *
+ * @param caseSensitive <code>boolean</code>.
+ */
+ public synchronized void setCaseSensitive(boolean caseSensitive) {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ this.caseSensitive = caseSensitive;
+ directoryScanner = null;
+ }
+
+ /**
+ * Find out if the fileset is case sensitive.
+ *
+ * @return <code>boolean</code> indicating whether the fileset is
+ * case sensitive.
+ *
+ * @since Ant 1.7
+ */
+ public synchronized boolean isCaseSensitive() {
+ if (isReference()) {
+ return getRef(getProject()).isCaseSensitive();
+ }
+ dieOnCircularReference();
+ return caseSensitive;
+ }
+
+ /**
+ * Sets whether or not symbolic links should be followed.
+ *
+ * @param followSymlinks whether or not symbolic links should be followed.
+ */
+ public synchronized void setFollowSymlinks(boolean followSymlinks) {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ this.followSymlinks = followSymlinks;
+ directoryScanner = null;
+ }
+
+ /**
+ * Find out if the fileset wants to follow symbolic links.
+ *
+ * @return <code>boolean</code> indicating whether symbolic links
+ * should be followed.
+ *
+ * @since Ant 1.6
+ */
+ public synchronized boolean isFollowSymlinks() {
+ if (isReference()) {
+ return getRef(getProject()).isCaseSensitive();
+ }
+ dieOnCircularReference();
+ return followSymlinks;
+ }
+
+ /**
+ * The maximum number of times a symbolic link may be followed
+ * during a scan.
+ *
+ * @since Ant 1.8.0
+ */
+ public void setMaxLevelsOfSymlinks(int max) {
+ maxLevelsOfSymlinks = max;
+ }
+
+ /**
+ * The maximum number of times a symbolic link may be followed
+ * during a scan.
+ *
+ * @since Ant 1.8.0
+ */
+ public int getMaxLevelsOfSymlinks() {
+ return maxLevelsOfSymlinks;
+ }
+
+ /**
+ * Sets whether an error is thrown if a directory does not exist.
+ *
+ * @param errorOnMissingDir true if missing directories cause errors,
+ * false if not.
+ */
+ public void setErrorOnMissingDir(boolean errorOnMissingDir) {
+ this.errorOnMissingDir = errorOnMissingDir;
+ }
+
+ /**
+ * Gets whether an error is/should be thrown if the base directory
+ * does not exist.
+ * @since Ant 1.8.2
+ */
+ public boolean getErrorOnMissingDir() {
+ return errorOnMissingDir;
+ }
+
+ /**
+ * Returns the directory scanner needed to access the files to process.
+ * @return a <code>DirectoryScanner</code> instance.
+ */
+ public DirectoryScanner getDirectoryScanner() {
+ return getDirectoryScanner(getProject());
+ }
+
+ /**
+ * Returns the directory scanner needed to access the files to process.
+ * @param p the Project against which the DirectoryScanner should be configured.
+ * @return a <code>DirectoryScanner</code> instance.
+ */
+ public DirectoryScanner getDirectoryScanner(Project p) {
+ if (isReference()) {
+ return getRef(p).getDirectoryScanner(p);
+ }
+ dieOnCircularReference();
+ DirectoryScanner ds = null;
+ synchronized (this) {
+ if (directoryScanner != null && p == getProject()) {
+ ds = directoryScanner;
+ } else {
+ if (dir == null) {
+ throw new BuildException("No directory specified for "
+ + getDataTypeName() + ".");
+ }
+ if (!dir.exists() && errorOnMissingDir) {
+ throw new BuildException(dir.getAbsolutePath()
+ + DirectoryScanner
+ .DOES_NOT_EXIST_POSTFIX);
+ }
+ if (!dir.isDirectory() && dir.exists()) {
+ throw new BuildException(dir.getAbsolutePath()
+ + " is not a directory.");
+ }
+ ds = new DirectoryScanner();
+ setupDirectoryScanner(ds, p);
+ ds.setFollowSymlinks(followSymlinks);
+ ds.setErrorOnMissingDir(errorOnMissingDir);
+ ds.setMaxLevelsOfSymlinks(maxLevelsOfSymlinks);
+ directoryScanner = (p == getProject()) ? ds : directoryScanner;
+ }
+ }
+ ds.scan();
+ return ds;
+ }
+
+ /**
+ * Set up the specified directory scanner against this
+ * AbstractFileSet's Project.
+ * @param ds a <code>FileScanner</code> instance.
+ */
+ public void setupDirectoryScanner(FileScanner ds) {
+ setupDirectoryScanner(ds, getProject());
+ }
+
+ /**
+ * Set up the specified directory scanner against the specified project.
+ * @param ds a <code>FileScanner</code> instance.
+ * @param p an Ant <code>Project</code> instance.
+ */
+ public synchronized void setupDirectoryScanner(FileScanner ds, Project p) {
+ if (isReference()) {
+ getRef(p).setupDirectoryScanner(ds, p);
+ return;
+ }
+ dieOnCircularReference(p);
+ if (ds == null) {
+ throw new IllegalArgumentException("ds cannot be null");
+ }
+ ds.setBasedir(dir);
+
+ PatternSet ps = mergePatterns(p);
+ p.log(getDataTypeName() + ": Setup scanner in dir " + dir
+ + " with " + ps, Project.MSG_DEBUG);
+
+ ds.setIncludes(ps.getIncludePatterns(p));
+ ds.setExcludes(ps.getExcludePatterns(p));
+ if (ds instanceof SelectorScanner) {
+ SelectorScanner ss = (SelectorScanner) ds;
+ ss.setSelectors(getSelectors(p));
+ }
+ if (useDefaultExcludes) {
+ ds.addDefaultExcludes();
+ }
+ ds.setCaseSensitive(caseSensitive);
+ }
+
+ /**
+ * Performs the check for circular references and returns the
+ * referenced FileSet.
+ * @param p the current project
+ * @return the referenced FileSet
+ */
+ protected AbstractFileSet getRef(Project p) {
+ return (AbstractFileSet) getCheckedRef(p);
+ }
+
+ // SelectorContainer methods
+
+ /**
+ * Indicates whether there are any selectors here.
+ *
+ * @return whether any selectors are in this container.
+ */
+ public synchronized boolean hasSelectors() {
+ if (isReference()) {
+ return getRef(getProject()).hasSelectors();
+ }
+ dieOnCircularReference();
+ return !(selectors.isEmpty());
+ }
+
+ /**
+ * Indicates whether there are any patterns here.
+ *
+ * @return whether any patterns are in this container.
+ */
+ public synchronized boolean hasPatterns() {
+ if (isReference() && getProject() != null) {
+ return getRef(getProject()).hasPatterns();
+ }
+ dieOnCircularReference();
+ if (defaultPatterns.hasPatterns(getProject())) {
+ return true;
+ }
+ for (PatternSet ps : additionalPatterns) {
+ if (ps.hasPatterns(getProject())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Gives the count of the number of selectors in this container.
+ *
+ * @return the number of selectors in this container as an <code>int</code>.
+ */
+ public synchronized int selectorCount() {
+ if (isReference()) {
+ return getRef(getProject()).selectorCount();
+ }
+ dieOnCircularReference();
+ return selectors.size();
+ }
+
+ /**
+ * Returns the set of selectors as an array.
+ * @param p the current project
+ * @return a <code>FileSelector[]</code> of the selectors in this container.
+ */
+ public synchronized FileSelector[] getSelectors(Project p) {
+ if (isReference()) {
+ return getRef(getProject()).getSelectors(p);
+ }
+ dieOnCircularReference(p);
+ return (FileSelector[]) (selectors.toArray(
+ new FileSelector[selectors.size()]));
+ }
+
+ /**
+ * Returns an enumerator for accessing the set of selectors.
+ *
+ * @return an <code>Enumeration</code> of selectors.
+ */
+ public synchronized Enumeration<FileSelector> selectorElements() {
+ if (isReference()) {
+ return getRef(getProject()).selectorElements();
+ }
+ dieOnCircularReference();
+ return Collections.enumeration(selectors);
+ }
+
+ /**
+ * Add a new selector into this container.
+ *
+ * @param selector the new <code>FileSelector</code> to add.
+ */
+ public synchronized void appendSelector(FileSelector selector) {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ selectors.add(selector);
+ directoryScanner = null;
+ setChecked(false);
+ }
+
+ /* Methods below all add specific selectors */
+
+ /**
+ * Add a "Select" selector entry on the selector list.
+ * @param selector the <code>SelectSelector</code> to add.
+ */
+ public void addSelector(SelectSelector selector) {
+ appendSelector(selector);
+ }
+
+ /**
+ * Add an "And" selector entry on the selector list.
+ * @param selector the <code>AndSelector</code> to add.
+ */
+ public void addAnd(AndSelector selector) {
+ appendSelector(selector);
+ }
+
+ /**
+ * Add an "Or" selector entry on the selector list.
+ * @param selector the <code>OrSelector</code> to add.
+ */
+ public void addOr(OrSelector selector) {
+ appendSelector(selector);
+ }
+
+ /**
+ * Add a "Not" selector entry on the selector list.
+ * @param selector the <code>NotSelector</code> to add.
+ */
+ public void addNot(NotSelector selector) {
+ appendSelector(selector);
+ }
+
+ /**
+ * Add a "None" selector entry on the selector list.
+ * @param selector the <code>NoneSelector</code> to add.
+ */
+ public void addNone(NoneSelector selector) {
+ appendSelector(selector);
+ }
+
+ /**
+ * Add a majority selector entry on the selector list.
+ * @param selector the <code>MajoritySelector</code> to add.
+ */
+ public void addMajority(MajoritySelector selector) {
+ appendSelector(selector);
+ }
+
+ /**
+ * Add a selector date entry on the selector list.
+ * @param selector the <code>DateSelector</code> to add.
+ */
+ public void addDate(DateSelector selector) {
+ appendSelector(selector);
+ }
+
+ /**
+ * Add a selector size entry on the selector list.
+ * @param selector the <code>SizeSelector</code> to add.
+ */
+ public void addSize(SizeSelector selector) {
+ appendSelector(selector);
+ }
+
+ /**
+ * Add a DifferentSelector entry on the selector list.
+ * @param selector the <code>DifferentSelector</code> to add.
+ */
+ public void addDifferent(DifferentSelector selector) {
+ appendSelector(selector);
+ }
+
+ /**
+ * Add a selector filename entry on the selector list.
+ * @param selector the <code>FilenameSelector</code> to add.
+ */
+ public void addFilename(FilenameSelector selector) {
+ appendSelector(selector);
+ }
+
+ /**
+ * Add a selector type entry on the selector list.
+ * @param selector the <code>TypeSelector</code> to add.
+ */
+ public void addType(TypeSelector selector) {
+ appendSelector(selector);
+ }
+
+ /**
+ * Add an extended selector entry on the selector list.
+ * @param selector the <code>ExtendSelector</code> to add.
+ */
+ public void addCustom(ExtendSelector selector) {
+ appendSelector(selector);
+ }
+
+ /**
+ * Add a contains selector entry on the selector list.
+ * @param selector the <code>ContainsSelector</code> to add.
+ */
+ public void addContains(ContainsSelector selector) {
+ appendSelector(selector);
+ }
+
+ /**
+ * Add a present selector entry on the selector list.
+ * @param selector the <code>PresentSelector</code> to add.
+ */
+ public void addPresent(PresentSelector selector) {
+ appendSelector(selector);
+ }
+
+ /**
+ * Add a depth selector entry on the selector list.
+ * @param selector the <code>DepthSelector</code> to add.
+ */
+ public void addDepth(DepthSelector selector) {
+ appendSelector(selector);
+ }
+
+ /**
+ * Add a depends selector entry on the selector list.
+ * @param selector the <code>DependSelector</code> to add.
+ */
+ public void addDepend(DependSelector selector) {
+ appendSelector(selector);
+ }
+
+ /**
+ * Add a regular expression selector entry on the selector list.
+ * @param selector the <code>ContainsRegexpSelector</code> to add.
+ */
+ public void addContainsRegexp(ContainsRegexpSelector selector) {
+ appendSelector(selector);
+ }
+
+ /**
+ * Add the modified selector.
+ * @param selector the <code>ModifiedSelector</code> to add.
+ * @since ant 1.6
+ */
+ public void addModified(ModifiedSelector selector) {
+ appendSelector(selector);
+ }
+
+ public void addReadable(ReadableSelector r) {
+ appendSelector(r);
+ }
+
+ public void addWritable(WritableSelector w) {
+ appendSelector(w);
+ }
+
+ /**
+ * Add an arbitrary selector.
+ * @param selector the <code>FileSelector</code> to add.
+ * @since Ant 1.6
+ */
+ public void add(FileSelector selector) {
+ appendSelector(selector);
+ }
+
+ /**
+ * Returns included files as a list of semicolon-separated filenames.
+ *
+ * @return a <code>String</code> of included filenames.
+ */
+ public String toString() {
+ if (isReference()) {
+ return getRef(getProject()).toString();
+ }
+ dieOnCircularReference();
+ DirectoryScanner ds = getDirectoryScanner(getProject());
+ String[] files = ds.getIncludedFiles();
+ StringBuffer sb = new StringBuffer();
+
+ for (int i = 0; i < files.length; i++) {
+ if (i > 0) {
+ sb.append(';');
+ }
+ sb.append(files[i]);
+ }
+ return sb.toString();
+ }
+
+ /**
+ * Creates a deep clone of this instance, except for the nested
+ * selectors (the list of selectors is a shallow clone of this
+ * instance's list).
+ * @return the cloned object
+ * @since Ant 1.6
+ */
+ public synchronized Object clone() {
+ if (isReference()) {
+ return (getRef(getProject())).clone();
+ } else {
+ try {
+ AbstractFileSet fs = (AbstractFileSet) super.clone();
+ fs.defaultPatterns = (PatternSet) defaultPatterns.clone();
+ fs.additionalPatterns = new ArrayList<PatternSet>(additionalPatterns.size());
+ for (PatternSet ps : additionalPatterns) {
+ fs.additionalPatterns.add((PatternSet) ps.clone());
+ }
+ fs.selectors = new ArrayList<FileSelector>(selectors);
+ return fs;
+ } catch (CloneNotSupportedException e) {
+ throw new BuildException(e);
+ }
+ }
+ }
+
+ /**
+ * Get the merged include patterns for this AbstractFileSet.
+ * @param p the project to use.
+ * @return the include patterns of the default pattern set and all
+ * nested patternsets.
+ *
+ * @since Ant 1.7
+ */
+ public String[] mergeIncludes(Project p) {
+ return mergePatterns(p).getIncludePatterns(p);
+ }
+
+ /**
+ * Get the merged exclude patterns for this AbstractFileSet.
+ * @param p the project to use.
+ * @return the exclude patterns of the default pattern set and all
+ * nested patternsets.
+ *
+ * @since Ant 1.7
+ */
+ public String[] mergeExcludes(Project p) {
+ return mergePatterns(p).getExcludePatterns(p);
+ }
+
+ /**
+ * Get the merged patterns for this AbstractFileSet.
+ * @param p the project to use.
+ * @return the default patternset merged with the additional sets
+ * in a new PatternSet instance.
+ *
+ * @since Ant 1.7
+ */
+ public synchronized PatternSet mergePatterns(Project p) {
+ if (isReference()) {
+ return getRef(p).mergePatterns(p);
+ }
+ dieOnCircularReference();
+ PatternSet ps = (PatternSet) defaultPatterns.clone();
+ final int count = additionalPatterns.size();
+ for (int i = 0; i < count; i++) {
+ ps.append(additionalPatterns.get(i), p);
+ }
+ return ps;
+ }
+
+ protected synchronized void dieOnCircularReference(Stack<Object> stk, Project p)
+ throws BuildException {
+ if (isChecked()) {
+ return;
+ }
+ if (isReference()) {
+ super.dieOnCircularReference(stk, p);
+ } else {
+ for (FileSelector fileSelector : selectors) {
+ if (fileSelector instanceof DataType) {
+ pushAndInvokeCircularReferenceCheck((DataType) fileSelector, stk, p);
+ }
+ }
+ for (PatternSet ps : additionalPatterns) {
+ pushAndInvokeCircularReferenceCheck(ps, stk, p);
+ }
+ setChecked(true);
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/AntFilterReader.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/AntFilterReader.java
new file mode 100644
index 00000000..20c41bc7
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/AntFilterReader.java
@@ -0,0 +1,178 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types;
+
+import java.util.Stack;
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+
+/**
+ * An AntFilterReader is a wrapper class that encloses the classname
+ * and configuration of a Configurable FilterReader.
+ */
+public final class AntFilterReader
+ extends DataType implements Cloneable {
+
+ private String className;
+
+ private final Vector<Parameter> parameters = new Vector<Parameter>();
+
+ private Path classpath;
+
+ /**
+ * Set the className attribute.
+ *
+ * @param className a <code>String</code> value
+ */
+ public void setClassName(final String className) {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ this.className = className;
+ }
+
+ /**
+ * Get the className attribute.
+ *
+ * @return a <code>String</code> value
+ */
+ public String getClassName() {
+ if (isReference()) {
+ return ((AntFilterReader) getCheckedRef()).getClassName();
+ }
+ dieOnCircularReference();
+ return className;
+ }
+
+ /**
+ * Add a Parameter.
+ *
+ * @param param a <code>Parameter</code> value
+ */
+ public void addParam(final Parameter param) {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ parameters.addElement(param);
+ }
+
+ /**
+ * Set the classpath to load the FilterReader through (attribute).
+ * @param classpath a classpath
+ */
+ public void setClasspath(Path classpath) {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ if (this.classpath == null) {
+ this.classpath = classpath;
+ } else {
+ this.classpath.append(classpath);
+ }
+ setChecked(false);
+ }
+
+ /**
+ * Set the classpath to load the FilterReader through (nested element).
+ * @return a classpath to be configured
+ */
+ public Path createClasspath() {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ if (this.classpath == null) {
+ this.classpath = new Path(getProject());
+ }
+ setChecked(false);
+ return this.classpath.createPath();
+ }
+
+ /**
+ * Get the classpath.
+ * @return the classpath
+ */
+ public Path getClasspath() {
+ if (isReference()) {
+ ((AntFilterReader) getCheckedRef()).getClasspath();
+ }
+ dieOnCircularReference();
+ return classpath;
+ }
+
+ /**
+ * Set the classpath to load the FilterReader through via
+ * reference (attribute).
+ * @param r a reference to a classpath
+ */
+ public void setClasspathRef(Reference r) {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ createClasspath().setRefid(r);
+ }
+
+ /**
+ * The parameters for this filter.
+ *
+ * @return a <code>Parameter[]</code> value
+ */
+ public Parameter[] getParams() {
+ if (isReference()) {
+ ((AntFilterReader) getCheckedRef()).getParams();
+ }
+ dieOnCircularReference();
+ Parameter[] params = new Parameter[parameters.size()];
+ parameters.copyInto(params);
+ return params;
+ }
+
+ /**
+ * Makes this instance in effect a reference to another AntFilterReader
+ * instance.
+ *
+ * <p>You must not set another attribute or nest elements inside
+ * this element if you make it a reference.</p>
+ *
+ * @param r the reference to which this instance is associated
+ * @exception BuildException if this instance already has been configured.
+ */
+ public void setRefid(Reference r) throws BuildException {
+ if (!parameters.isEmpty() || className != null
+ || classpath != null) {
+ throw tooManyAttributes();
+ }
+ super.setRefid(r);
+ }
+
+ protected synchronized void dieOnCircularReference(Stack<Object> stk, Project p)
+ throws BuildException {
+ if (isChecked()) {
+ return;
+ }
+ if (isReference()) {
+ super.dieOnCircularReference(stk, p);
+ } else {
+ if (classpath != null) {
+ pushAndInvokeCircularReferenceCheck(classpath, stk, p);
+ }
+ setChecked(true);
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/ArchiveFileSet.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/ArchiveFileSet.java
new file mode 100644
index 00000000..e9a07303
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/ArchiveFileSet.java
@@ -0,0 +1,596 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types;
+
+import java.io.File;
+import java.util.Iterator;
+import java.util.Stack;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.DirectoryScanner;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.resources.FileProvider;
+import org.apache.tools.ant.types.resources.FileResource;
+import org.apache.tools.zip.UnixStat;
+
+/**
+ * A ArchiveFileSet is a FileSet with extra attributes useful in the
+ * context of archiving tasks.
+ *
+ * It includes a prefix attribute which is prepended to each entry in
+ * the output archive file as well as a fullpath attribute. It also
+ * supports Unix file permissions for files and directories.
+ *
+ * @since Ant 1.7
+ */
+public abstract class ArchiveFileSet extends FileSet {
+
+ private static final int BASE_OCTAL = 8;
+
+ /**
+ * Default value for the dirmode attribute.
+ *
+ * @since Ant 1.5.2
+ */
+ public static final int DEFAULT_DIR_MODE =
+ UnixStat.DIR_FLAG | UnixStat.DEFAULT_DIR_PERM;
+
+ /**
+ * Default value for the filemode attribute.
+ *
+ * @since Ant 1.5.2
+ */
+ public static final int DEFAULT_FILE_MODE =
+ UnixStat.FILE_FLAG | UnixStat.DEFAULT_FILE_PERM;
+
+ private Resource src = null;
+ private String prefix = "";
+ private String fullpath = "";
+ private boolean hasDir = false;
+ private int fileMode = DEFAULT_FILE_MODE;
+ private int dirMode = DEFAULT_DIR_MODE;
+
+ private boolean fileModeHasBeenSet = false;
+ private boolean dirModeHasBeenSet = false;
+ private static final String ERROR_DIR_AND_SRC_ATTRIBUTES = "Cannot set both dir and src attributes";
+ private static final String ERROR_PATH_AND_PREFIX = "Cannot set both fullpath and prefix attributes";
+
+ private boolean errorOnMissingArchive = true;
+
+ private String encoding = null;
+
+ /** Constructor for ArchiveFileSet */
+ public ArchiveFileSet() {
+ super();
+ }
+
+ /**
+ * Constructor using a fileset argument.
+ * @param fileset the fileset to use
+ */
+ protected ArchiveFileSet(FileSet fileset) {
+ super(fileset);
+ }
+
+ /**
+ * Constructor using a archive fileset argument.
+ * @param fileset the archivefileset to use
+ */
+ protected ArchiveFileSet(ArchiveFileSet fileset) {
+ super(fileset);
+ src = fileset.src;
+ prefix = fileset.prefix;
+ fullpath = fileset.fullpath;
+ hasDir = fileset.hasDir;
+ fileMode = fileset.fileMode;
+ dirMode = fileset.dirMode;
+ fileModeHasBeenSet = fileset.fileModeHasBeenSet;
+ dirModeHasBeenSet = fileset.dirModeHasBeenSet;
+ errorOnMissingArchive = fileset.errorOnMissingArchive;
+ encoding = fileset.encoding;
+ }
+
+ /**
+ * Set the directory for the fileset.
+ * @param dir the directory for the fileset
+ * @throws BuildException on error
+ */
+ public void setDir(File dir) throws BuildException {
+ checkAttributesAllowed();
+ if (src != null) {
+ throw new BuildException(ERROR_DIR_AND_SRC_ATTRIBUTES);
+ }
+ super.setDir(dir);
+ hasDir = true;
+ }
+
+ /**
+ * Set the source Archive file for the archivefileset. Prevents both
+ * "dir" and "src" from being specified.
+ * @param a the archive as a single element Resource collection.
+ */
+ public void addConfigured(ResourceCollection a) {
+ checkChildrenAllowed();
+ if (a.size() != 1) {
+ throw new BuildException("only single argument resource collections"
+ + " are supported as archives");
+ }
+ setSrcResource(a.iterator().next());
+ }
+
+ /**
+ * Set the source Archive file for the archivefileset. Prevents both
+ * "dir" and "src" from being specified.
+ *
+ * @param srcFile The archive from which to extract entries.
+ */
+ public void setSrc(File srcFile) {
+ setSrcResource(new FileResource(srcFile));
+ }
+
+ /**
+ * Set the source Archive file for the archivefileset. Prevents both
+ * "dir" and "src" from being specified.
+ *
+ * @param src The archive from which to extract entries.
+ */
+ public void setSrcResource(Resource src) {
+ checkArchiveAttributesAllowed();
+ if (hasDir) {
+ throw new BuildException(ERROR_DIR_AND_SRC_ATTRIBUTES);
+ }
+ this.src = src;
+ setChecked(false);
+ }
+
+ /**
+ * Get the archive from which entries will be extracted.
+ * @param p the project to use
+ * @return the source file
+ */
+ public File getSrc(Project p) {
+ if (isReference()) {
+ return ((ArchiveFileSet) getRef(p)).getSrc(p);
+ }
+ return getSrc();
+ }
+
+ /**
+ * Sets whether an error is thrown if an archive does not exist.
+ *
+ * @param errorOnMissingArchive true if missing archives cause errors,
+ * false if not.
+ * @since Ant 1.8.0
+ */
+ public void setErrorOnMissingArchive(boolean errorOnMissingArchive) {
+ checkAttributesAllowed();
+ this.errorOnMissingArchive = errorOnMissingArchive;
+ }
+
+ /**
+ * Get the archive file from which entries will be extracted.
+ * @return the archive in case the archive is a file, null otherwise.
+ */
+ public File getSrc() {
+ if (isReference()) {
+ return ((ArchiveFileSet) getCheckedRef()).getSrc();
+ }
+ dieOnCircularReference();
+ if (src != null) {
+ FileProvider fp = src.as(FileProvider.class);
+ if (fp != null) {
+ return fp.getFile();
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Performs the check for circular references and returns the
+ * referenced object.
+ * This is an override which does not delegate to the superclass; instead it invokes
+ * {@link #getRef(Project)}, because that contains the special support for fileset
+ * references, which can be handled by all ArchiveFileSets.
+ * @param p the Ant Project instance against which to resolve references.
+ * @return the dereferenced object.
+ * @throws BuildException if the reference is invalid (circular ref, wrong class, etc).
+ * @since Ant 1.8
+ */
+ // TODO is the above true? AFAICT the calls look circular :/
+ protected Object getCheckedRef(Project p) {
+ return getRef(p);
+ }
+
+ /**
+ * Prepend this prefix to the path for each archive entry.
+ * Prevents both prefix and fullpath from being specified
+ *
+ * @param prefix The prefix to prepend to entries in the archive file.
+ */
+ public void setPrefix(String prefix) {
+ checkArchiveAttributesAllowed();
+ if (!"".equals(prefix) && !"".equals(fullpath)) {
+ throw new BuildException(ERROR_PATH_AND_PREFIX);
+ }
+ this.prefix = prefix;
+ }
+
+ /**
+ * Return the prefix prepended to entries in the archive file.
+ * @param p the project to use
+ * @return the prefix
+ */
+ public String getPrefix(Project p) {
+ if (isReference()) {
+ return ((ArchiveFileSet) getRef(p)).getPrefix(p);
+ }
+ dieOnCircularReference(p);
+ return prefix;
+ }
+
+ /**
+ * Set the full pathname of the single entry in this fileset.
+ * Prevents both prefix and fullpath from being specified
+ *
+ * @param fullpath the full pathname of the single entry in this fileset.
+ */
+ public void setFullpath(String fullpath) {
+ checkArchiveAttributesAllowed();
+ if (!"".equals(prefix) && !"".equals(fullpath)) {
+ throw new BuildException(ERROR_PATH_AND_PREFIX);
+ }
+ this.fullpath = fullpath;
+ }
+
+ /**
+ * Return the full pathname of the single entry in this fileset.
+ * @param p the project to use
+ * @return the full path
+ */
+ public String getFullpath(Project p) {
+ if (isReference()) {
+ return ((ArchiveFileSet) getRef(p)).getFullpath(p);
+ }
+ dieOnCircularReference(p);
+ return fullpath;
+ }
+
+ /**
+ * Set the encoding used for this ZipFileSet.
+ * @param enc encoding as String.
+ * @since Ant 1.9.5
+ */
+ public void setEncoding(String enc) {
+ checkAttributesAllowed();
+ this.encoding = enc;
+ }
+
+ /**
+ * Get the encoding used for this ZipFileSet.
+ * @return String encoding.
+ * @since Ant 1.9.5
+ */
+ public String getEncoding() {
+ if (isReference()) {
+ AbstractFileSet ref = getRef(getProject());
+ if (ref instanceof ArchiveFileSet) {
+ return ((ArchiveFileSet) ref).getEncoding();
+ } else {
+ return null;
+ }
+ }
+ return encoding;
+ }
+
+ /**
+ * Creates a scanner for this type of archive.
+ * @return the scanner.
+ */
+ protected abstract ArchiveScanner newArchiveScanner();
+
+ /**
+ * Return the DirectoryScanner associated with this FileSet.
+ * If the ArchiveFileSet defines a source Archive file, then an ArchiveScanner
+ * is returned instead.
+ * @param p the project to use
+ * @return a directory scanner
+ */
+ public DirectoryScanner getDirectoryScanner(Project p) {
+ if (isReference()) {
+ return getRef(p).getDirectoryScanner(p);
+ }
+ dieOnCircularReference();
+ if (src == null) {
+ return super.getDirectoryScanner(p);
+ }
+ if (!src.isExists() && errorOnMissingArchive) {
+ throw new BuildException(
+ "The archive " + src.getName() + " doesn't exist");
+ }
+ if (src.isDirectory()) {
+ throw new BuildException("The archive " + src.getName()
+ + " can't be a directory");
+ }
+ ArchiveScanner as = newArchiveScanner();
+ as.setErrorOnMissingArchive(errorOnMissingArchive);
+ as.setSrc(src);
+ super.setDir(p.getBaseDir());
+ setupDirectoryScanner(as, p);
+ as.init();
+ return as;
+ }
+
+ /**
+ * Fulfill the ResourceCollection contract.
+ * @return Iterator of Resources.
+ * @since Ant 1.7
+ */
+ public Iterator<Resource> iterator() {
+ if (isReference()) {
+ return ((ResourceCollection) (getRef(getProject()))).iterator();
+ }
+ if (src == null) {
+ return super.iterator();
+ }
+ ArchiveScanner as = (ArchiveScanner) getDirectoryScanner(getProject());
+ return as.getResourceFiles(getProject());
+ }
+
+ /**
+ * Fulfill the ResourceCollection contract.
+ * @return size of the collection as int.
+ * @since Ant 1.7
+ */
+ public int size() {
+ if (isReference()) {
+ return ((ResourceCollection) (getRef(getProject()))).size();
+ }
+ if (src == null) {
+ return super.size();
+ }
+ ArchiveScanner as = (ArchiveScanner) getDirectoryScanner(getProject());
+ return as.getIncludedFilesCount();
+ }
+
+ /**
+ * Indicate whether this ResourceCollection is composed entirely of
+ * Resources accessible via local filesystem conventions. If true,
+ * all Resources returned from this ResourceCollection should be
+ * instances of FileResource.
+ * @return whether this is a filesystem-only resource collection.
+ * @since Ant 1.7
+ */
+ public boolean isFilesystemOnly() {
+ if (isReference()) {
+ return ((ArchiveFileSet) getCheckedRef()).isFilesystemOnly();
+ }
+ dieOnCircularReference();
+ return src == null;
+ }
+
+ /**
+ * A 3 digit octal string, specify the user, group and
+ * other modes in the standard Unix fashion;
+ * optional, default=0644
+ * @param octalString a <code>String</code> value
+ */
+ public void setFileMode(String octalString) {
+ checkArchiveAttributesAllowed();
+ integerSetFileMode(Integer.parseInt(octalString, BASE_OCTAL));
+ }
+
+ /**
+ * specify the user, group and
+ * other modes in the standard Unix fashion;
+ * optional, default=0644
+ *
+ * <p>We use the strange name so this method doesn't appear in
+ * IntrospectionHelpers list of attribute setters.</p>
+ * @param mode a <code>int</code> value
+ * @since Ant 1.7
+ */
+ public void integerSetFileMode(int mode) {
+ fileModeHasBeenSet = true;
+ this.fileMode = UnixStat.FILE_FLAG | mode;
+ }
+
+ /**
+ * Get the mode of the archive fileset
+ * @param p the project to use
+ * @return the mode
+ */
+ public int getFileMode(Project p) {
+ if (isReference()) {
+ return ((ArchiveFileSet) getRef(p)).getFileMode(p);
+ }
+ dieOnCircularReference();
+ return fileMode;
+ }
+
+ /**
+ * Whether the user has specified the mode explicitly.
+ * @return true if it has been set
+ */
+ public boolean hasFileModeBeenSet() {
+ if (isReference()) {
+ return ((ArchiveFileSet) getRef(getProject())).hasFileModeBeenSet();
+ }
+ dieOnCircularReference();
+ return fileModeHasBeenSet;
+ }
+
+ /**
+ * A 3 digit octal string, specify the user, group and
+ * other modes in the standard Unix fashion;
+ * optional, default=0755
+ * @param octalString a <code>String</code> value
+ */
+ public void setDirMode(String octalString) {
+ checkArchiveAttributesAllowed();
+ integerSetDirMode(Integer.parseInt(octalString, BASE_OCTAL));
+ }
+
+ /**
+ * specify the user, group and
+ * other modes in the standard Unix fashion;
+ * optional, default=0755
+ * <p>We use the strange name so this method doesn't appear in
+ * IntrospectionHelpers list of attribute setters.</p>
+ * @param mode a <code>int</code> value
+ * @since Ant 1.7
+ */
+ public void integerSetDirMode(int mode) {
+ dirModeHasBeenSet = true;
+ this.dirMode = UnixStat.DIR_FLAG | mode;
+ }
+
+ /**
+ * Get the dir mode of the archive fileset
+ * @param p the project to use
+ * @return the mode
+ */
+ public int getDirMode(Project p) {
+ if (isReference()) {
+ return ((ArchiveFileSet) getRef(p)).getDirMode(p);
+ }
+ dieOnCircularReference();
+ return dirMode;
+ }
+
+ /**
+ * Whether the user has specified the mode explicitly.
+ *
+ * @return true if it has been set
+ */
+ public boolean hasDirModeBeenSet() {
+ if (isReference()) {
+ return ((ArchiveFileSet) getRef(getProject())).hasDirModeBeenSet();
+ }
+ dieOnCircularReference();
+ return dirModeHasBeenSet;
+ }
+
+ /**
+ * A ArchiveFileset accepts another ArchiveFileSet or a FileSet as reference
+ * FileSets are often used by the war task for the lib attribute
+ * @param zfs the project to use
+ */
+ protected void configureFileSet(ArchiveFileSet zfs) {
+ zfs.setPrefix(prefix);
+ zfs.setFullpath(fullpath);
+ zfs.fileModeHasBeenSet = fileModeHasBeenSet;
+ zfs.fileMode = fileMode;
+ zfs.dirModeHasBeenSet = dirModeHasBeenSet;
+ zfs.dirMode = dirMode;
+ }
+
+ /**
+ * Return a ArchiveFileSet that has the same properties
+ * as this one.
+ * @return the cloned archiveFileSet
+ * @since Ant 1.6
+ */
+ public Object clone() {
+ if (isReference()) {
+ return getCheckedRef(ArchiveFileSet.class, getDataTypeName(), getProject()).clone();
+ }
+ return super.clone();
+ }
+
+ /**
+ * For file-based archivefilesets, return the same as for normal filesets;
+ * else just return the path of the zip.
+ * @return for file based archivefilesets, included files as a list
+ * of semicolon-separated filenames. else just the name of the zip.
+ */
+ public String toString() {
+ if (hasDir && getProject() != null) {
+ return super.toString();
+ }
+ return src == null ? null : src.getName();
+ }
+
+ /**
+ * Return the prefix prepended to entries in the archive file.
+ * @return the prefix.
+ * @deprecated since 1.7.
+ */
+ public String getPrefix() {
+ return prefix;
+ }
+
+ /**
+ * Return the full pathname of the single entryZ in this fileset.
+ * @return the full pathname.
+ * @deprecated since 1.7.
+ */
+ public String getFullpath() {
+ return fullpath;
+ }
+
+ /**
+ * @return the file mode.
+ * @deprecated since 1.7.
+ */
+ public int getFileMode() {
+ return fileMode;
+ }
+
+ /**
+ * @return the dir mode.
+ * @deprecated since 1.7.
+ */
+ public int getDirMode() {
+ return dirMode;
+ }
+
+ /**
+ * A check attributes for archiveFileSet.
+ * If there is a reference, and
+ * it is a ArchiveFileSet, the archive fileset attributes
+ * cannot be used.
+ * (Note, we can only see if the reference is an archive
+ * fileset if the project has been set).
+ */
+ private void checkArchiveAttributesAllowed() {
+ if (getProject() == null
+ || (isReference()
+ && (getRefid().getReferencedObject(
+ getProject())
+ instanceof ArchiveFileSet))) {
+ checkAttributesAllowed();
+ }
+ }
+
+ protected synchronized void dieOnCircularReference(Stack<Object> stk, Project p)
+ throws BuildException {
+ if (isChecked()) {
+ return;
+ }
+
+ // takes care of nested selectors
+ super.dieOnCircularReference(stk, p);
+
+ if (!isReference()) {
+ if (src != null) {
+ pushAndInvokeCircularReferenceCheck(src, stk, p);
+ }
+ setChecked(true);
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/ArchiveScanner.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/ArchiveScanner.java
new file mode 100644
index 00000000..db5a8d46
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/ArchiveScanner.java
@@ -0,0 +1,363 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types;
+
+import java.io.File;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.TreeMap;
+
+import org.apache.tools.ant.DirectoryScanner;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.resources.FileProvider;
+import org.apache.tools.ant.types.resources.FileResource;
+import org.apache.tools.ant.types.resources.FileResourceIterator;
+
+/**
+ * ArchiveScanner accesses the pattern matching algorithm in DirectoryScanner,
+ * which are protected methods that can only be accessed by subclassing.
+ *
+ * This implementation of FileScanner defines getIncludedFiles to return
+ * the matching archive entries.
+ *
+ * @since Ant 1.7
+ */
+public abstract class ArchiveScanner extends DirectoryScanner {
+ // CheckStyle:VisibilityModifier OFF - bc
+
+ /**
+ * The archive file which should be scanned.
+ */
+ protected File srcFile;
+
+ // CheckStyle:VisibilityModifier ON
+
+ /**
+ * The archive resource which should be scanned.
+ */
+ private Resource src;
+
+ /**
+ * to record the last scanned zip file with its modification date
+ */
+ private Resource lastScannedResource;
+
+ /**
+ * record list of all file zip entries
+ */
+ private Map<String, Resource> fileEntries = new TreeMap<String, Resource>();
+
+ /**
+ * record list of all directory zip entries
+ */
+ private Map<String, Resource> dirEntries = new TreeMap<String, Resource>();
+
+ /**
+ * record list of matching file zip entries
+ */
+ private Map<String, Resource> matchFileEntries = new TreeMap<String, Resource>();
+
+ /**
+ * record list of matching directory zip entries
+ */
+ private Map<String, Resource> matchDirEntries = new TreeMap<String, Resource>();
+
+ /**
+ * encoding of file names.
+ *
+ * @since Ant 1.6
+ */
+ private String encoding;
+
+ /**
+ * @since Ant 1.8.0
+ */
+ private boolean errorOnMissingArchive = true;
+
+ /**
+ * Sets whether an error is thrown if an archive does not exist.
+ *
+ * @param errorOnMissingArchive true if missing archives cause errors,
+ * false if not.
+ * @since Ant 1.8.0
+ */
+ public void setErrorOnMissingArchive(boolean errorOnMissingArchive) {
+ this.errorOnMissingArchive = errorOnMissingArchive;
+ }
+
+ /**
+ * Don't scan when we have no zipfile.
+ * @since Ant 1.7
+ */
+ public void scan() {
+ if (src == null || (!src.isExists() && !errorOnMissingArchive)) {
+ return;
+ }
+ super.scan();
+ }
+
+ /**
+ * Sets the srcFile for scanning. This is the jar or zip file that
+ * is scanned for matching entries.
+ *
+ * @param srcFile the (non-null) archive file name for scanning
+ */
+ public void setSrc(File srcFile) {
+ setSrc(new FileResource(srcFile));
+ }
+
+ /**
+ * Sets the src for scanning. This is the jar or zip file that
+ * is scanned for matching entries.
+ *
+ * @param src the (non-null) archive resource
+ */
+ public void setSrc(Resource src) {
+ this.src = src;
+ FileProvider fp = src.as(FileProvider.class);
+ if (fp != null) {
+ srcFile = fp.getFile();
+ }
+ }
+
+ /**
+ * Sets encoding of file names.
+ * @param encoding the encoding format
+ * @since Ant 1.6
+ */
+ public void setEncoding(String encoding) {
+ this.encoding = encoding;
+ }
+
+ /**
+ * Returns the names of the files which matched at least one of the
+ * include patterns and none of the exclude patterns.
+ * The names are relative to the base directory.
+ *
+ * @return the names of the files which matched at least one of the
+ * include patterns and none of the exclude patterns.
+ */
+ public String[] getIncludedFiles() {
+ if (src == null) {
+ return super.getIncludedFiles();
+ }
+ scanme();
+ return matchFileEntries.keySet().toArray(new String[matchFileEntries.size()]);
+ }
+
+ /**
+ * Override parent implementation.
+ * @return count of included files.
+ * @since Ant 1.7
+ */
+ public int getIncludedFilesCount() {
+ if (src == null) {
+ return super.getIncludedFilesCount();
+ }
+ scanme();
+ return matchFileEntries.size();
+ }
+
+ /**
+ * Returns the names of the directories which matched at least one of the
+ * include patterns and none of the exclude patterns.
+ * The names are relative to the base directory.
+ *
+ * @return the names of the directories which matched at least one of the
+ * include patterns and none of the exclude patterns.
+ */
+ public String[] getIncludedDirectories() {
+ if (src == null) {
+ return super.getIncludedDirectories();
+ }
+ scanme();
+ return matchDirEntries.keySet().toArray(new String[matchDirEntries.size()]);
+ }
+
+ /**
+ * Override parent implementation.
+ * @return count of included directories.
+ * @since Ant 1.7
+ */
+ public int getIncludedDirsCount() {
+ if (src == null) {
+ return super.getIncludedDirsCount();
+ }
+ scanme();
+ return matchDirEntries.size();
+ }
+
+ /**
+ * Get the set of Resources that represent files.
+ * @param project since Ant 1.8
+ * @return an Iterator of Resources.
+ * @since Ant 1.7
+ */
+ /* package-private for now */ Iterator<Resource> getResourceFiles(Project project) {
+ if (src == null) {
+ return new FileResourceIterator(project, getBasedir(), getIncludedFiles());
+ }
+ scanme();
+ return matchFileEntries.values().iterator();
+ }
+
+ /**
+ * Get the set of Resources that represent directories.
+ * @param project since Ant 1.8
+ * @return an Iterator of Resources.
+ * @since Ant 1.7
+ */
+ /* package-private for now */ Iterator<Resource> getResourceDirectories(Project project) {
+ if (src == null) {
+ return new FileResourceIterator(project, getBasedir(), getIncludedDirectories());
+ }
+ scanme();
+ return matchDirEntries.values().iterator();
+ }
+
+ /**
+ * Initialize DirectoryScanner data structures.
+ */
+ public void init() {
+ if (includes == null) {
+ // No includes supplied, so set it to 'matches all'
+ includes = new String[1];
+ includes[0] = "**";
+ }
+ if (excludes == null) {
+ excludes = new String[0];
+ }
+ }
+
+ /**
+ * Matches a jar entry against the includes/excludes list,
+ * normalizing the path separator.
+ *
+ * @param path the (non-null) path name to test for inclusion
+ *
+ * @return <code>true</code> if the path should be included
+ * <code>false</code> otherwise.
+ */
+ public boolean match(String path) {
+ String vpath = path;
+ if (path.length() > 0) {
+ vpath = path.replace('/', File.separatorChar).
+ replace('\\', File.separatorChar);
+ if (vpath.charAt(0) == File.separatorChar) {
+ vpath = vpath.substring(1);
+ }
+ }
+ return isIncluded(vpath) && !isExcluded(vpath);
+ }
+
+ /**
+ * Get the named Resource.
+ * @param name path name of the file sought in the archive
+ * @return the resource
+ * @since Ant 1.5.2
+ */
+ public Resource getResource(String name) {
+ if (src == null) {
+ return super.getResource(name);
+ }
+ if (name.equals("")) {
+ // special case in ZIPs, we do not want this thing included
+ return new Resource("", true, Long.MAX_VALUE, true);
+ }
+ // first check if the archive needs to be scanned again
+ scanme();
+ if (fileEntries.containsKey(name)) {
+ return fileEntries.get(name);
+ }
+ name = trimSeparator(name);
+
+ if (dirEntries.containsKey(name)) {
+ return dirEntries.get(name);
+ }
+ return new Resource(name);
+ }
+
+ /**
+ * Fills the file and directory maps with resources read from the archive.
+ *
+ * @param archive the archive to scan.
+ * @param encoding encoding used to encode file names inside the archive.
+ * @param fileEntries Map (name to resource) of non-directory
+ * resources found inside the archive.
+ * @param matchFileEntries Map (name to resource) of non-directory
+ * resources found inside the archive that matched all include
+ * patterns and didn't match any exclude patterns.
+ * @param dirEntries Map (name to resource) of directory
+ * resources found inside the archive.
+ * @param matchDirEntries Map (name to resource) of directory
+ * resources found inside the archive that matched all include
+ * patterns and didn't match any exclude patterns.
+ */
+ protected abstract void fillMapsFromArchive(Resource archive,
+ String encoding,
+ Map<String, Resource> fileEntries,
+ Map<String, Resource> matchFileEntries,
+ Map<String, Resource> dirEntries,
+ Map<String, Resource> matchDirEntries);
+
+ /**
+ * if the datetime of the archive did not change since
+ * lastScannedResource was initialized returns immediately else if
+ * the archive has not been scanned yet, then all the zip entries
+ * are put into the appropriate tables.
+ */
+ private void scanme() {
+ if (!src.isExists() && !errorOnMissingArchive) {
+ return;
+ }
+
+ //do not use a FileResource b/c it pulls File info from the filesystem:
+ Resource thisresource = new Resource(src.getName(),
+ src.isExists(),
+ src.getLastModified());
+ // spare scanning again and again
+ if (lastScannedResource != null
+ && lastScannedResource.getName().equals(thisresource.getName())
+ && lastScannedResource.getLastModified()
+ == thisresource.getLastModified()) {
+ return;
+ }
+ init();
+
+ fileEntries.clear();
+ dirEntries.clear();
+ matchFileEntries.clear();
+ matchDirEntries.clear();
+ fillMapsFromArchive(src, encoding, fileEntries, matchFileEntries,
+ dirEntries, matchDirEntries);
+
+ // record data about the last scanned resource
+ lastScannedResource = thisresource;
+ }
+
+ /**
+ * Remove trailing slash if present.
+ * @param s the file name to trim.
+ * @return the trimmed file name.
+ */
+ protected static final String trimSeparator(String s) {
+ return s.endsWith("/") ? s.substring(0, s.length() - 1) : s;
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/Assertions.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/Assertions.java
new file mode 100644
index 00000000..a54db501
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/Assertions.java
@@ -0,0 +1,359 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.ListIterator;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+
+/**
+ * The assertion datatype. This type describes
+ * assertion settings for the &lt;java&gt; task and others.
+ * One can set the system assertions, and enable/disable those in
+ * packages and classes.
+ * Assertions can only be enabled or disabled when forking Java.
+ *
+ * Example: set system assertions and all org.apache packages except
+ * for ant, and the class org.apache.tools.ant.Main.
+ * <pre>
+ * &lt;assertions enableSystemAssertions="true" &gt;
+ * &lt;enable package="org.apache" /&gt;
+ * &lt;disable package="org.apache.ant" /&gt;
+ * &lt;enable class="org.apache.tools.ant.Main"/&gt;
+ * &lt;/assertions&gt;
+ *</pre>
+ * Disable system assertions; enable those in the anonymous package
+ * <pre>
+ * &lt;assertions enableSystemAssertions="false" &gt;
+ * &lt;enable package="..." /&gt;
+ * &lt;/assertions&gt;
+ * </pre>
+ * enable assertions in a class called Test
+ * <pre>
+ * &lt;assertions &gt;
+ * &lt;enable class="Test" /&gt;
+ * &lt;/assertions&gt;
+ * </pre>
+ * This type is a datatype, so you can declare assertions and use them later
+ *
+ * <pre>
+ * &lt;assertions id="project.assertions" &gt;
+ * &lt;enable project="org.apache.test" /&gt;
+ * &lt;/assertions&gt;
+ *
+ * &lt;assertions refid="project.assertions" /&gt;
+ *
+ * </pre>
+ * @since Ant 1.6
+ */
+public class Assertions extends DataType implements Cloneable {
+
+ /**
+ * enable/disable sys assertions; null means undefined
+ */
+ private Boolean enableSystemAssertions;
+
+ /**
+ * list of type BaseAssertion
+ */
+ private ArrayList<BaseAssertion> assertionList = new ArrayList<BaseAssertion>();
+
+
+ /**
+ * enable assertions
+ * @param assertion an enable assertion nested element
+ */
+ public void addEnable(EnabledAssertion assertion) {
+ checkChildrenAllowed();
+ assertionList.add(assertion);
+ }
+
+ /**
+ * disable assertions
+ * @param assertion a disable assertion nested element
+ */
+ public void addDisable(DisabledAssertion assertion) {
+ checkChildrenAllowed();
+ assertionList.add(assertion);
+ }
+
+ /**
+ * enable or disable system assertions.
+ * Default is not set (neither -enablesystemassersions or -disablesytemassertions
+ * are used on the command line).
+ * @param enableSystemAssertions if true enable system assertions
+ */
+ public void setEnableSystemAssertions(Boolean enableSystemAssertions) {
+ checkAttributesAllowed();
+ this.enableSystemAssertions = enableSystemAssertions;
+ }
+
+ /**
+ * Set the value of the refid attribute.
+ *
+ * <p>Subclasses may need to check whether any other attributes
+ * have been set as well or child elements have been created and
+ * thus override this method. if they do the must call
+ * <code>super.setRefid</code>.</p>
+ * @param ref the reference to use
+ */
+ public void setRefid(Reference ref) {
+ if (assertionList.size() > 0 || enableSystemAssertions != null) {
+ throw tooManyAttributes();
+ }
+ super.setRefid(ref);
+ }
+
+ /**
+ * get whatever we are referencing to. This could be ourself.
+ * @return the object that contains the assertion info
+ */
+ private Assertions getFinalReference() {
+ if (getRefid() == null) {
+ return this;
+ } else {
+ Object o = getRefid().getReferencedObject(getProject());
+ if (!(o instanceof Assertions)) {
+ throw new BuildException("reference is of wrong type");
+ }
+ return (Assertions) o;
+ }
+ }
+
+ /**
+ * how many assertions are made...will resolve references before returning
+ * @return total # of commands to make
+ */
+ public int size() {
+ Assertions clause = getFinalReference();
+ return clause.getFinalSize();
+ }
+
+
+ /**
+ * what is the final size of this object
+ * @return number of assertions
+ */
+ private int getFinalSize() {
+ return assertionList.size() + (enableSystemAssertions != null ? 1 : 0);
+ }
+
+ /**
+ * add the assertions to a list in a format suitable
+ * for adding to a command line
+ * @param commandList the command line to format
+ */
+ public void applyAssertions(List<String> commandList) {
+ getProject().log("Applying assertions", Project.MSG_DEBUG);
+ Assertions clause = getFinalReference();
+ //do the system assertions
+ if (Boolean.TRUE.equals(clause.enableSystemAssertions)) {
+ getProject().log("Enabling system assertions", Project.MSG_DEBUG);
+ commandList.add("-enablesystemassertions");
+ } else if (Boolean.FALSE.equals(clause.enableSystemAssertions)) {
+ getProject().log("disabling system assertions", Project.MSG_DEBUG);
+ commandList.add("-disablesystemassertions");
+ }
+
+ //now any inner assertions
+ for (BaseAssertion assertion : clause.assertionList) {
+ String arg = assertion.toCommand();
+ getProject().log("adding assertion " + arg, Project.MSG_DEBUG);
+ commandList.add(arg);
+ }
+ }
+
+ /**
+ * apply all the assertions to the command.
+ * @param command the command line to format
+ */
+ public void applyAssertions(CommandlineJava command) {
+ Assertions clause = getFinalReference();
+ //do the system assertions
+ if (Boolean.TRUE.equals(clause.enableSystemAssertions)) {
+ addVmArgument(command, "-enablesystemassertions");
+ } else if (Boolean.FALSE.equals(clause.enableSystemAssertions)) {
+ addVmArgument(command, "-disablesystemassertions");
+ }
+
+ //now any inner assertions
+ for (BaseAssertion assertion : clause.assertionList) {
+ String arg = assertion.toCommand();
+ addVmArgument(command, arg);
+ }
+ }
+
+ /**
+ * add the assertions to a list in a format suitable
+ * for adding to a command line
+ * @param commandIterator list of commands
+ */
+ public void applyAssertions(final ListIterator<String> commandIterator) {
+ getProject().log("Applying assertions", Project.MSG_DEBUG);
+ Assertions clause = getFinalReference();
+ //do the system assertions
+ if (Boolean.TRUE.equals(clause.enableSystemAssertions)) {
+ getProject().log("Enabling system assertions", Project.MSG_DEBUG);
+ commandIterator.add("-enablesystemassertions");
+ } else if (Boolean.FALSE.equals(clause.enableSystemAssertions)) {
+ getProject().log("disabling system assertions", Project.MSG_DEBUG);
+ commandIterator.add("-disablesystemassertions");
+ }
+
+ //now any inner assertions
+ for (BaseAssertion assertion : clause.assertionList) {
+ String arg = assertion.toCommand();
+ getProject().log("adding assertion " + arg, Project.MSG_DEBUG);
+ commandIterator.add(arg);
+ }
+ }
+
+ /**
+ * helper method to add a string JVM argument to a command
+ * @param command
+ * @param arg
+ */
+ private static void addVmArgument(CommandlineJava command, String arg) {
+ Commandline.Argument argument;
+ argument = command.createVmArgument();
+ argument.setValue(arg);
+ }
+
+ /**
+ * clone the objects.
+ * This is not a full depth clone; the list of assertions is cloned,
+ * but it does not clone the underlying assertions.
+ * @return a cli
+ * @throws CloneNotSupportedException if the super class does not support cloning
+ */
+ public Object clone() throws CloneNotSupportedException {
+ Assertions that = (Assertions) super.clone();
+ that.assertionList = new ArrayList<BaseAssertion>(assertionList);
+ return that;
+ }
+
+ /**
+ * base class for our assertion elements.
+ */
+
+ public abstract static class BaseAssertion {
+ private String packageName;
+ private String className;
+
+ /**
+ * name a class
+ * @param className a class name
+ */
+ public void setClass(String className) {
+ this.className = className;
+ }
+
+ /**
+ * name a package
+ * @param packageName a package name
+ */
+ public void setPackage(String packageName) {
+ this.packageName = packageName;
+ }
+
+ /**
+ * what is the class name?
+ * @return classname or null
+ * @see #setClass
+ */
+ protected String getClassName() {
+ return className;
+ }
+
+ /**
+ * what is the package name?
+ * @return package name or null
+ * @see #setPackage
+ */
+ protected String getPackageName() {
+ return packageName;
+ }
+
+ /**
+ * get the prefix used to begin the command; -ea or -da.
+ * @return prefix
+ */
+ public abstract String getCommandPrefix();
+
+ /**
+ * create a full command string from this class
+ * @throws BuildException in case of trouble
+ * @return The command string
+ */
+ public String toCommand() {
+ //catch invalidness
+ if (getPackageName() != null && getClassName() != null) {
+ throw new BuildException("Both package and class have been set");
+ }
+ StringBuffer command = new StringBuffer(getCommandPrefix());
+ //see if it is a package or a class
+ if (getPackageName() != null) {
+ //packages get a ... prefix
+ command.append(':');
+ command.append(getPackageName());
+ if (!command.toString().endsWith("...")) {
+ //append the ... suffix if not there already
+ command.append("...");
+ }
+ } else if (getClassName() != null) {
+ //classes just get the classname
+ command.append(':');
+ command.append(getClassName());
+ }
+ return command.toString();
+ }
+ }
+
+
+ /**
+ * an enabled assertion enables things
+ */
+ public static class EnabledAssertion extends BaseAssertion {
+ /**
+ * get the prefix used to begin the command; -ea or -da.
+ * @return prefix
+ */
+ public String getCommandPrefix() {
+ return "-ea";
+ }
+
+ }
+
+ /**
+ * A disabled assertion disables things
+ */
+ public static class DisabledAssertion extends BaseAssertion {
+ /**
+ * get the prefix used to begin the command; -ea or -da.
+ * @return prefix
+ */
+ public String getCommandPrefix() {
+ return "-da";
+ }
+
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/Commandline.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/Commandline.java
new file mode 100644
index 00000000..c273d7aa
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/Commandline.java
@@ -0,0 +1,689 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.StringTokenizer;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.ProjectComponent;
+import org.apache.tools.ant.taskdefs.condition.Os;
+import org.apache.tools.ant.util.StringUtils;
+
+/**
+ * Commandline objects help handling command lines specifying processes to
+ * execute.
+ *
+ * The class can be used to define a command line as nested elements or as a
+ * helper to define a command line by an application.
+ * <p>
+ * <code>
+ * &lt;someelement&gt;<br>
+ * &nbsp;&nbsp;&lt;acommandline executable="/executable/to/run"&gt;<br>
+ * &nbsp;&nbsp;&nbsp;&nbsp;&lt;argument value="argument 1" /&gt;<br>
+ * &nbsp;&nbsp;&nbsp;&nbsp;&lt;argument line="argument_1 argument_2 argument_3" /&gt;<br>
+ * &nbsp;&nbsp;&nbsp;&nbsp;&lt;argument value="argument 4" /&gt;<br>
+ * &nbsp;&nbsp;&lt;/acommandline&gt;<br>
+ * &lt;/someelement&gt;<br>
+ * </code>
+ * The element <code>someelement</code> must provide a method
+ * <code>createAcommandline</code> which returns an instance of this class.
+ *
+ */
+public class Commandline implements Cloneable {
+ /** win9x uses a (shudder) bat file (antRun.bat) for executing commands */
+ private static final boolean IS_WIN_9X = Os.isFamily("win9x");
+
+ /**
+ * The arguments of the command
+ */
+ private List<Argument> arguments = new ArrayList<Argument>();
+
+ /**
+ * the program to execute
+ */
+ private String executable = null;
+
+ protected static final String DISCLAIMER =
+ StringUtils.LINE_SEP
+ + "The \' characters around the executable and arguments are"
+ + StringUtils.LINE_SEP
+ + "not part of the command."
+ + StringUtils.LINE_SEP;
+
+ /**
+ * Create a command line from a string.
+ * @param toProcess the line: the first element becomes the executable, the rest
+ * the arguments.
+ */
+ public Commandline(String toProcess) {
+ super();
+ String[] tmp = translateCommandline(toProcess);
+ if (tmp != null && tmp.length > 0) {
+ setExecutable(tmp[0]);
+ for (int i = 1; i < tmp.length; i++) {
+ createArgument().setValue(tmp[i]);
+ }
+ }
+ }
+
+ /**
+ * Create an empty command line.
+ */
+ public Commandline() {
+ super();
+ }
+
+ /**
+ * Used for nested xml command line definitions.
+ */
+ public static class Argument extends ProjectComponent {
+
+ private String[] parts;
+
+ private String prefix = "";
+ private String suffix = "";
+
+ /**
+ * Set a single commandline argument.
+ *
+ * @param value a single commandline argument.
+ */
+ public void setValue(String value) {
+ parts = new String[] {value};
+ }
+
+ /**
+ * Set the line to split into several commandline arguments.
+ *
+ * @param line line to split into several commandline arguments.
+ */
+ public void setLine(String line) {
+ if (line == null) {
+ return;
+ }
+ parts = translateCommandline(line);
+ }
+
+ /**
+ * Set a single commandline argument and treats it like a
+ * PATH--ensuring the right separator for the local platform
+ * is used.
+ *
+ * @param value a single commandline argument.
+ */
+ public void setPath(Path value) {
+ parts = new String[] {value.toString()};
+ }
+
+ /**
+ * Set a single commandline argument from a reference to a
+ * path--ensuring the right separator for the local platform
+ * is used.
+ *
+ * @param value a single commandline argument.
+ */
+ public void setPathref(Reference value) {
+ Path p = new Path(getProject());
+ p.setRefid(value);
+ parts = new String[] {p.toString()};
+ }
+
+ /**
+ * Set a single commandline argument to the absolute filename
+ * of the given file.
+ *
+ * @param value a single commandline argument.
+ */
+ public void setFile(File value) {
+ parts = new String[] {value.getAbsolutePath()};
+ }
+
+ /**
+ * Set the prefix to be placed in front of every part of the
+ * argument.
+ *
+ * @param prefix fixed prefix string.
+ * @since Ant 1.8.0
+ */
+ public void setPrefix(String prefix) {
+ this.prefix = prefix != null ? prefix : "";
+ }
+
+ /**
+ * Set the suffix to be placed at the end of every part of the
+ * argument.
+ *
+ * @param suffix fixed suffix string.
+ * @since Ant 1.8.0
+ */
+ public void setSuffix(String suffix) {
+ this.suffix = suffix != null ? suffix : "";
+ }
+
+ /**
+ * Return the constituent parts of this Argument.
+ * @return an array of strings.
+ */
+ public String[] getParts() {
+ if (parts == null || parts.length == 0
+ || (prefix.length() == 0 && suffix.length() == 0)) {
+ return parts;
+ }
+ String[] fullParts = new String[parts.length];
+ for (int i = 0; i < fullParts.length; ++i) {
+ fullParts[i] = prefix + parts[i] + suffix;
+ }
+ return fullParts;
+ }
+ }
+
+ /**
+ * Class to keep track of the position of an Argument.
+ *
+ * <p>This class is there to support the srcfile and targetfile
+ * elements of &lt;apply&gt;.</p>
+ */
+ public class Marker {
+
+ private int position;
+ private int realPos = -1;
+ private String prefix = "";
+ private String suffix = "";
+
+ /**
+ * Construct a marker for the specified position.
+ * @param position the position to mark.
+ */
+ Marker(int position) {
+ this.position = position;
+ }
+
+ /**
+ * Return the number of arguments that preceded this marker.
+ *
+ * <p>The name of the executable -- if set -- is counted as the
+ * first argument.</p>
+ * @return the position of this marker.
+ */
+ public int getPosition() {
+ if (realPos == -1) {
+ realPos = (executable == null ? 0 : 1);
+ for (int i = 0; i < position; i++) {
+ Argument arg = (Argument) arguments.get(i);
+ realPos += arg.getParts().length;
+ }
+ }
+ return realPos;
+ }
+
+ /**
+ * Set the prefix to be placed in front of the inserted argument.
+ *
+ * @param prefix fixed prefix string.
+ * @since Ant 1.8.0
+ */
+ public void setPrefix(String prefix) {
+ this.prefix = prefix != null ? prefix : "";
+ }
+
+ /**
+ * Get the prefix to be placed in front of the inserted argument.
+ *
+ * @since Ant 1.8.0
+ */
+ public String getPrefix() {
+ return prefix;
+ }
+
+ /**
+ * Set the suffix to be placed at the end of the inserted argument.
+ *
+ * @param suffix fixed suffix string.
+ * @since Ant 1.8.0
+ */
+ public void setSuffix(String suffix) {
+ this.suffix = suffix != null ? suffix : "";
+ }
+
+ /**
+ * Get the suffix to be placed at the end of the inserted argument.
+ *
+ * @since Ant 1.8.0
+ */
+ public String getSuffix() {
+ return suffix;
+ }
+
+ }
+
+ /**
+ * Create an argument object.
+ *
+ * <p>Each commandline object has at most one instance of the
+ * argument class. This method calls
+ * <code>this.createArgument(false)</code>.</p>
+ *
+ * @see #createArgument(boolean)
+ * @return the argument object.
+ */
+ public Argument createArgument() {
+ return this.createArgument(false);
+ }
+
+ /**
+ * Create an argument object and add it to our list of args.
+ *
+ * <p>Each commandline object has at most one instance of the
+ * argument class.</p>
+ *
+ * @param insertAtStart if true, the argument is inserted at the
+ * beginning of the list of args, otherwise it is appended.
+ * @return an argument to be configured
+ */
+ public Argument createArgument(boolean insertAtStart) {
+ Argument argument = new Argument();
+ if (insertAtStart) {
+ arguments.add(0, argument);
+ } else {
+ arguments.add(argument);
+ }
+ return argument;
+ }
+
+ /**
+ * Set the executable to run. All file separators in the string
+ * are converted to the platform specific value.
+ * @param executable the String executable name.
+ */
+ public void setExecutable(String executable) {
+ if (executable == null || executable.length() == 0) {
+ return;
+ }
+ this.executable = executable.replace('/', File.separatorChar)
+ .replace('\\', File.separatorChar);
+ }
+
+ /**
+ * Get the executable.
+ * @return the program to run--null if not yet set.
+ */
+ public String getExecutable() {
+ return executable;
+ }
+
+ /**
+ * Append the arguments to the existing command.
+ * @param line an array of arguments to append.
+ */
+ public void addArguments(String[] line) {
+ for (int i = 0; i < line.length; i++) {
+ createArgument().setValue(line[i]);
+ }
+ }
+
+ /**
+ * Return the executable and all defined arguments.
+ * @return the commandline as an array of strings.
+ */
+ public String[] getCommandline() {
+ final List<String> commands = new LinkedList<String>();
+ addCommandToList(commands.listIterator());
+ return commands.toArray(new String[commands.size()]);
+ }
+
+ /**
+ * Add the entire command, including (optional) executable to a list.
+ * @param list the list to add to.
+ * @since Ant 1.6
+ */
+ public void addCommandToList(ListIterator<String> list) {
+ if (executable != null) {
+ list.add(executable);
+ }
+ addArgumentsToList(list);
+ }
+
+ /**
+ * Returns all arguments defined by <code>addLine</code>,
+ * <code>addValue</code> or the argument object.
+ * @return the arguments as an array of strings.
+ */
+ public String[] getArguments() {
+ List<String> result = new ArrayList<String>(arguments.size() * 2);
+ addArgumentsToList(result.listIterator());
+ return result.toArray(new String[result.size()]);
+ }
+
+ /**
+ * Append all the arguments to the tail of a supplied list.
+ * @param list the list of arguments.
+ * @since Ant 1.6
+ */
+ public void addArgumentsToList(ListIterator<String> list) {
+ final int size = arguments.size();
+ for (int i = 0; i < size; i++) {
+ Argument arg = arguments.get(i);
+ String[] s = arg.getParts();
+ if (s != null) {
+ for (int j = 0; j < s.length; j++) {
+ list.add(s[j]);
+ }
+ }
+ }
+ }
+
+ /**
+ * Return the command line as a string.
+ * @return the command line.
+ */
+ public String toString() {
+ return toString(getCommandline());
+ }
+
+ /**
+ * Put quotes around the given String if necessary.
+ *
+ * <p>If the argument doesn't include spaces or quotes, return it
+ * as is. If it contains double quotes, use single quotes - else
+ * surround the argument by double quotes.</p>
+ * @param argument the argument to quote if necessary.
+ * @return the quoted argument.
+ * @exception BuildException if the argument contains both, single
+ * and double quotes.
+ */
+ public static String quoteArgument(String argument) {
+ if (argument.indexOf("\"") > -1) {
+ if (argument.indexOf("\'") > -1) {
+ throw new BuildException("Can\'t handle single and double"
+ + " quotes in same argument");
+ } else {
+ return '\'' + argument + '\'';
+ }
+ } else if (argument.indexOf("\'") > -1
+ || argument.indexOf(" ") > -1
+ // WIN9x uses a bat file for executing commands
+ || (IS_WIN_9X && argument.indexOf(';') != -1)) {
+ return '\"' + argument + '\"';
+ } else {
+ return argument;
+ }
+ }
+
+ /**
+ * Quote the parts of the given array in way that makes them
+ * usable as command line arguments.
+ * @param line the list of arguments to quote.
+ * @return empty string for null or no command, else every argument split
+ * by spaces and quoted by quoting rules.
+ */
+ public static String toString(String[] line) {
+ // empty path return empty string
+ if (line == null || line.length == 0) {
+ return "";
+ }
+ // path containing one or more elements
+ final StringBuilder result = new StringBuilder();
+ for (int i = 0; i < line.length; i++) {
+ if (i > 0) {
+ result.append(' ');
+ }
+ result.append(quoteArgument(line[i]));
+ }
+ return result.toString();
+ }
+
+ /**
+ * Crack a command line.
+ * @param toProcess the command line to process.
+ * @return the command line broken into strings.
+ * An empty or null toProcess parameter results in a zero sized array.
+ */
+ public static String[] translateCommandline(String toProcess) {
+ if (toProcess == null || toProcess.length() == 0) {
+ //no command? no string
+ return new String[0];
+ }
+ // parse with a simple finite state machine
+
+ final int normal = 0;
+ final int inQuote = 1;
+ final int inDoubleQuote = 2;
+ int state = normal;
+ final StringTokenizer tok = new StringTokenizer(toProcess, "\"\' ", true);
+ final ArrayList<String> result = new ArrayList<String>();
+ final StringBuilder current = new StringBuilder();
+ boolean lastTokenHasBeenQuoted = false;
+
+ while (tok.hasMoreTokens()) {
+ String nextTok = tok.nextToken();
+ switch (state) {
+ case inQuote:
+ if ("\'".equals(nextTok)) {
+ lastTokenHasBeenQuoted = true;
+ state = normal;
+ } else {
+ current.append(nextTok);
+ }
+ break;
+ case inDoubleQuote:
+ if ("\"".equals(nextTok)) {
+ lastTokenHasBeenQuoted = true;
+ state = normal;
+ } else {
+ current.append(nextTok);
+ }
+ break;
+ default:
+ if ("\'".equals(nextTok)) {
+ state = inQuote;
+ } else if ("\"".equals(nextTok)) {
+ state = inDoubleQuote;
+ } else if (" ".equals(nextTok)) {
+ if (lastTokenHasBeenQuoted || current.length() != 0) {
+ result.add(current.toString());
+ current.setLength(0);
+ }
+ } else {
+ current.append(nextTok);
+ }
+ lastTokenHasBeenQuoted = false;
+ break;
+ }
+ }
+ if (lastTokenHasBeenQuoted || current.length() != 0) {
+ result.add(current.toString());
+ }
+ if (state == inQuote || state == inDoubleQuote) {
+ throw new BuildException("unbalanced quotes in " + toProcess);
+ }
+ return result.toArray(new String[result.size()]);
+ }
+
+ /**
+ * Size operator. This actually creates the command line, so it is not
+ * a zero cost operation.
+ * @return number of elements in the command, including the executable.
+ */
+ public int size() {
+ return getCommandline().length;
+ }
+
+ /**
+ * Generate a deep clone of the contained object.
+ * @return a clone of the contained object
+ */
+ public Object clone() {
+ try {
+ Commandline c = (Commandline) super.clone();
+ c.arguments = new ArrayList<Argument>(arguments);
+ return c;
+ } catch (CloneNotSupportedException e) {
+ throw new BuildException(e);
+ }
+ }
+
+ /**
+ * Clear out the whole command line.
+ */
+ public void clear() {
+ executable = null;
+ arguments.clear();
+ }
+
+ /**
+ * Clear out the arguments but leave the executable in place for
+ * another operation.
+ */
+ public void clearArgs() {
+ arguments.clear();
+ }
+
+ /**
+ * Return a marker.
+ *
+ * <p>This marker can be used to locate a position on the
+ * commandline--to insert something for example--when all
+ * parameters have been set.</p>
+ * @return a marker
+ */
+ public Marker createMarker() {
+ return new Marker(arguments.size());
+ }
+
+ /**
+ * Return a String that describes the command and arguments suitable for
+ * verbose output before a call to <code>Runtime.exec(String[])<code>.
+ * @return a string that describes the command and arguments.
+ * @since Ant 1.5
+ */
+ public String describeCommand() {
+ return describeCommand(this);
+ }
+
+ /**
+ * Return a String that describes the arguments suitable for
+ * verbose output before a call to <code>Runtime.exec(String[])<code>.
+ * @return a string that describes the arguments.
+ * @since Ant 1.5
+ */
+ public String describeArguments() {
+ return describeArguments(this);
+ }
+
+ /**
+ * Return a String that describes the command and arguments suitable for
+ * verbose output before a call to <code>Runtime.exec(String[])<code>.
+ * @param line the Commandline to describe.
+ * @return a string that describes the command and arguments.
+ * @since Ant 1.5
+ */
+ public static String describeCommand(Commandline line) {
+ return describeCommand(line.getCommandline());
+ }
+
+ /**
+ * Return a String that describes the arguments suitable for
+ * verbose output before a call to <code>Runtime.exec(String[])<code>.
+ * @param line the Commandline whose arguments to describe.
+ * @return a string that describes the arguments.
+ * @since Ant 1.5
+ */
+ public static String describeArguments(Commandline line) {
+ return describeArguments(line.getArguments());
+ }
+
+ /**
+ * Return a String that describes the command and arguments suitable for
+ * verbose output before a call to <code>Runtime.exec(String[])<code>.
+ *
+ * <p>This method assumes that the first entry in the array is the
+ * executable to run.</p>
+ * @param args the command line to describe as an array of strings
+ * @return a string that describes the command and arguments.
+ * @since Ant 1.5
+ */
+ public static String describeCommand(String[] args) {
+ if (args == null || args.length == 0) {
+ return "";
+ }
+ StringBuffer buf = new StringBuffer("Executing \'");
+ buf.append(args[0]);
+ buf.append("\'");
+ if (args.length > 1) {
+ buf.append(" with ");
+ buf.append(describeArguments(args, 1));
+ } else {
+ buf.append(DISCLAIMER);
+ }
+ return buf.toString();
+ }
+
+ /**
+ * Return a String that describes the arguments suitable for
+ * verbose output before a call to <code>Runtime.exec(String[])<code>.
+ * @param args the command line to describe as an array of strings.
+ * @return a string that describes the arguments.
+ * @since Ant 1.5
+ */
+ public static String describeArguments(String[] args) {
+ return describeArguments(args, 0);
+ }
+
+ /**
+ * Return a String that describes the arguments suitable for
+ * verbose output before a call to <code>Runtime.exec(String[])<code>.
+ *
+ * @param args the command line to describe as an array of strings.
+ * @param offset ignore entries before this index.
+ * @return a string that describes the arguments
+ *
+ * @since Ant 1.5
+ */
+ protected static String describeArguments(String[] args, int offset) {
+ if (args == null || args.length <= offset) {
+ return "";
+ }
+ StringBuffer buf = new StringBuffer("argument");
+ if (args.length > offset) {
+ buf.append("s");
+ }
+ buf.append(":").append(StringUtils.LINE_SEP);
+ for (int i = offset; i < args.length; i++) {
+ buf.append("\'").append(args[i]).append("\'")
+ .append(StringUtils.LINE_SEP);
+ }
+ buf.append(DISCLAIMER);
+ return buf.toString();
+ }
+
+ /**
+ * Get an iterator to the arguments list.
+ * @since Ant 1.7
+ * @return an Iterator.
+ */
+ public Iterator<Argument> iterator() {
+ return arguments.iterator();
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/CommandlineJava.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/CommandlineJava.java
new file mode 100644
index 00000000..9da354dd
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/CommandlineJava.java
@@ -0,0 +1,699 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types;
+
+import java.util.Enumeration;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Properties;
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.util.JavaEnvUtils;
+
+/**
+ * A representation of a Java command line that is
+ * a composite of 2 <tt>Commandline</tt>s. One is used for the
+ * vm/options and one for the classname/arguments. It provides
+ * specific methods for a Java command line.
+ *
+ */
+public class CommandlineJava implements Cloneable {
+
+ /**
+ * commands to the JVM
+ */
+ private Commandline vmCommand = new Commandline();
+ /**
+ * actual java commands
+ */
+ private Commandline javaCommand = new Commandline();
+ /**
+ * properties to add using -D
+ */
+ private SysProperties sysProperties = new SysProperties();
+ private Path classpath = null;
+ private Path bootclasspath = null;
+ private String vmVersion;
+ private String maxMemory = null;
+ /**
+ * any assertions to make? Currently only supported in forked JVMs
+ */
+ private Assertions assertions = null;
+
+ /**
+ * Indicate whether it will execute a jar file or not, in this case
+ * the first vm option must be a -jar and the 'executable' is a jar file.
+ */
+ private boolean executeJar = false;
+
+ /**
+ * Whether system properties and bootclasspath shall be cloned.
+ * @since Ant 1.7
+ */
+ private boolean cloneVm = false;
+
+ /**
+ * Specialized Environment class for System properties.
+ */
+ public static class SysProperties extends Environment implements Cloneable {
+ // CheckStyle:VisibilityModifier OFF - bc
+ /** the system properties. */
+ Properties sys = null;
+ // CheckStyle:VisibilityModifier ON
+ private Vector<PropertySet> propertySets = new Vector<PropertySet>();
+
+ /**
+ * Get the properties as an array; this is an override of the
+ * superclass, as it evaluates all the properties.
+ * @return the array of definitions; may be null.
+ * @throws BuildException on error.
+ */
+ public String[] getVariables() throws BuildException {
+
+ List<String> definitions = new LinkedList<String>();
+ addDefinitionsToList(definitions.listIterator());
+ if (definitions.size() == 0) {
+ return null;
+ } else {
+ return definitions.toArray(new String[definitions.size()]);
+ }
+ }
+
+ /**
+ * Add all definitions (including property sets) to a list.
+ * @param listIt list iterator supporting add method.
+ */
+ public void addDefinitionsToList(ListIterator<String> listIt) {
+ String[] props = super.getVariables();
+ if (props != null) {
+ for (int i = 0; i < props.length; i++) {
+ listIt.add("-D" + props[i]);
+ }
+ }
+ Properties propertySetProperties = mergePropertySets();
+ for (Enumeration<?> e = propertySetProperties.keys();
+ e.hasMoreElements();) {
+ String key = (String) e.nextElement();
+ String value = propertySetProperties.getProperty(key);
+ listIt.add("-D" + key + "=" + value);
+ }
+ }
+
+ /**
+ * Get the size of the sysproperties instance. This merges all
+ * property sets, so is not an O(1) operation.
+ * @return the size of the sysproperties instance.
+ */
+ public int size() {
+ Properties p = mergePropertySets();
+ return variables.size() + p.size();
+ }
+
+ /**
+ * Cache the system properties and set the system properties to the
+ * new values.
+ * @throws BuildException if Security prevented this operation.
+ */
+ public void setSystem() throws BuildException {
+ try {
+ sys = System.getProperties();
+ Properties p = new Properties();
+ for (Enumeration<?> e = sys.propertyNames(); e.hasMoreElements();) {
+ String name = (String) e.nextElement();
+ String value = sys.getProperty(name);
+ if (name != null && value != null) {
+ p.put(name, value);
+ }
+ }
+ p.putAll(mergePropertySets());
+ for (Environment.Variable v : variables) {
+ v.validate();
+ p.put(v.getKey(), v.getValue());
+ }
+ System.setProperties(p);
+ } catch (SecurityException e) {
+ throw new BuildException("Cannot modify system properties", e);
+ }
+ }
+
+ /**
+ * Restore the system properties to the cached value.
+ * @throws BuildException if Security prevented this operation, or
+ * there were no system properties to restore.
+ */
+ public void restoreSystem() throws BuildException {
+ if (sys == null) {
+ throw new BuildException("Unbalanced nesting of SysProperties");
+ }
+
+ try {
+ System.setProperties(sys);
+ sys = null;
+ } catch (SecurityException e) {
+ throw new BuildException("Cannot modify system properties", e);
+ }
+ }
+
+ /**
+ * Create a deep clone.
+ * @return a cloned instance of SysProperties.
+ * @exception CloneNotSupportedException for signature.
+ */
+ @SuppressWarnings("unchecked")
+ public Object clone() throws CloneNotSupportedException {
+ try {
+ SysProperties c = (SysProperties) super.clone();
+ c.variables = (Vector<Environment.Variable>) variables.clone();
+ c.propertySets = (Vector<PropertySet>) propertySets.clone();
+ return c;
+ } catch (CloneNotSupportedException e) {
+ return null;
+ }
+ }
+
+ /**
+ * Add a propertyset to the total set.
+ * @param ps the new property set.
+ */
+ public void addSyspropertyset(PropertySet ps) {
+ propertySets.addElement(ps);
+ }
+
+ /**
+ * Add a propertyset to the total set.
+ * @param ps the new property set.
+ * @since Ant 1.6.3
+ */
+ public void addSysproperties(SysProperties ps) {
+ variables.addAll(ps.variables);
+ propertySets.addAll(ps.propertySets);
+ }
+
+ /**
+ * Merge all property sets into a single Properties object.
+ * @return the merged object.
+ */
+ private Properties mergePropertySets() {
+ Properties p = new Properties();
+ for (PropertySet ps : propertySets) {
+ p.putAll(ps.getProperties());
+ }
+ return p;
+ }
+
+ }
+
+ /**
+ * Constructor uses the VM we are running on now.
+ */
+ public CommandlineJava() {
+ setVm(JavaEnvUtils.getJreExecutable("java"));
+ setVmversion(JavaEnvUtils.getJavaVersion());
+ }
+
+ /**
+ * Create a new argument to the java program.
+ * @return an argument to be configured.
+ */
+ public Commandline.Argument createArgument() {
+ return javaCommand.createArgument();
+ }
+
+ /**
+ * Create a new JVM argument.
+ * @return an argument to be configured.
+ */
+ public Commandline.Argument createVmArgument() {
+ return vmCommand.createArgument();
+ }
+
+ /**
+ * Add a system property.
+ * @param sysp a property to be set in the JVM.
+ */
+ public void addSysproperty(Environment.Variable sysp) {
+ sysProperties.addVariable(sysp);
+ }
+
+ /**
+ * Add a set of system properties.
+ * @param sysp a set of properties.
+ */
+ public void addSyspropertyset(PropertySet sysp) {
+ sysProperties.addSyspropertyset(sysp);
+ }
+
+ /**
+ * Add a set of system properties.
+ * @param sysp a set of properties.
+ * @since Ant 1.6.3
+ */
+ public void addSysproperties(SysProperties sysp) {
+ sysProperties.addSysproperties(sysp);
+ }
+
+ /**
+ * Set the executable used to start the new JVM.
+ * @param vm the executable to use.
+ */
+ public void setVm(String vm) {
+ vmCommand.setExecutable(vm);
+ }
+
+ /**
+ * Set the JVM version required.
+ * @param value the version required.
+ */
+ public void setVmversion(String value) {
+ vmVersion = value;
+ }
+
+ /**
+ * Set whether system properties will be copied to the cloned VM--as
+ * well as the bootclasspath unless you have explicitly specified
+ * a bootclasspath.
+ * @param cloneVm if true copy the system properties.
+ * @since Ant 1.7
+ */
+ public void setCloneVm(boolean cloneVm) {
+ this.cloneVm = cloneVm;
+ }
+
+ /**
+ * Get the current assertions.
+ * @return assertions or null.
+ */
+ public Assertions getAssertions() {
+ return assertions;
+ }
+
+ /**
+ * Add an assertion set to the command.
+ * @param assertions assertions to make.
+ */
+ public void setAssertions(Assertions assertions) {
+ this.assertions = assertions;
+ }
+
+ /**
+ * Set a jar file to execute via the -jar option.
+ * @param jarpathname the pathname of the jar to execute.
+ */
+ public void setJar(String jarpathname) {
+ javaCommand.setExecutable(jarpathname);
+ executeJar = true;
+ }
+
+ /**
+ * Get the name of the jar to be run.
+ * @return the pathname of the jar file to run via -jar option
+ * or <tt>null</tt> if there is no jar to run.
+ * @see #getClassname()
+ */
+ public String getJar() {
+ if (executeJar) {
+ return javaCommand.getExecutable();
+ }
+ return null;
+ }
+
+ /**
+ * Set the classname to execute.
+ * @param classname the fully qualified classname.
+ */
+ public void setClassname(String classname) {
+ javaCommand.setExecutable(classname);
+ executeJar = false;
+ }
+
+ /**
+ * Get the name of the class to be run.
+ * @return the name of the class to run or <tt>null</tt> if there is no class.
+ * @see #getJar()
+ */
+ public String getClassname() {
+ if (!executeJar) {
+ return javaCommand.getExecutable();
+ }
+ return null;
+ }
+
+ /**
+ * Create a classpath.
+ * @param p the project to use to create the path.
+ * @return a path to be configured.
+ */
+ public Path createClasspath(Project p) {
+ if (classpath == null) {
+ classpath = new Path(p);
+ }
+ return classpath;
+ }
+
+ /**
+ * Create a boot classpath.
+ * @param p the project to use to create the path.
+ * @return a path to be configured.
+ * @since Ant 1.6
+ */
+ public Path createBootclasspath(Project p) {
+ if (bootclasspath == null) {
+ bootclasspath = new Path(p);
+ }
+ return bootclasspath;
+ }
+
+ /**
+ * Get the vm version.
+ * @return the vm version.
+ */
+ public String getVmversion() {
+ return vmVersion;
+ }
+
+ /**
+ * Get the command line to run a Java vm.
+ * @return the list of all arguments necessary to run the vm.
+ */
+ public String[] getCommandline() {
+ //create the list
+ List<String> commands = new LinkedList<String>();
+ //fill it
+ addCommandsToList(commands.listIterator());
+ //convert to an array
+ return commands.toArray(new String[commands.size()]);
+ }
+
+ /**
+ * Add all the commands to a list identified by the iterator passed in.
+ * @param listIterator an iterator that supports the add method.
+ * @since Ant 1.6
+ */
+ private void addCommandsToList(final ListIterator<String> listIterator) {
+ //create the command to run Java, including user specified options
+ getActualVMCommand().addCommandToList(listIterator);
+ // properties are part of the vm options...
+ sysProperties.addDefinitionsToList(listIterator);
+
+ if (isCloneVm()) {
+ SysProperties clonedSysProperties = new SysProperties();
+ PropertySet ps = new PropertySet();
+ PropertySet.BuiltinPropertySetName sys =
+ new PropertySet.BuiltinPropertySetName();
+ sys.setValue("system");
+ ps.appendBuiltin(sys);
+ clonedSysProperties.addSyspropertyset(ps);
+ clonedSysProperties.addDefinitionsToList(listIterator);
+ }
+ //boot classpath
+ Path bcp = calculateBootclasspath(true);
+ if (bcp.size() > 0) {
+ listIterator.add("-Xbootclasspath:" + bcp.toString());
+ }
+ //main classpath
+ if (haveClasspath()) {
+ listIterator.add("-classpath");
+ listIterator.add(
+ classpath.concatSystemClasspath("ignore").toString());
+ }
+ //now any assertions are added
+ if (getAssertions() != null) {
+ getAssertions().applyAssertions(listIterator);
+ }
+ // JDK usage command line says that -jar must be the first option, as there is
+ // a bug in JDK < 1.4 that forces the jvm type to be specified as the first
+ // option, it is appended here as specified in the docs even though there is
+ // in fact no order.
+ if (executeJar) {
+ listIterator.add("-jar");
+ }
+ // this is the classname to run as well as its arguments.
+ // in case of 'executeJar', the executable is a jar file.
+ javaCommand.addCommandToList(listIterator);
+ }
+
+ /**
+ * Specify max memory of the JVM.
+ * -mx or -Xmx depending on VM version.
+ * @param max the string to pass to the jvm to specify the max memory.
+ */
+ public void setMaxmemory(String max) {
+ this.maxMemory = max;
+ }
+
+ /**
+ * Get a string description.
+ * @return the command line as a string.
+ */
+ public String toString() {
+ return Commandline.toString(getCommandline());
+ }
+
+ /**
+ * Return a String that describes the command and arguments suitable for
+ * verbose output before a call to <code>Runtime.exec(String[])<code>.
+ * @return the description string.
+ * @since Ant 1.5
+ */
+ public String describeCommand() {
+ return Commandline.describeCommand(getCommandline());
+ }
+
+ /**
+ * Return a String that describes the java command and arguments
+ * for in-VM executions.
+ *
+ * <p>The class name is the executable in this context.</p>
+ * @return the description string.
+ * @since Ant 1.5
+ */
+ public String describeJavaCommand() {
+ return Commandline.describeCommand(getJavaCommand());
+ }
+
+ /**
+ * Get the VM command parameters, including memory settings.
+ * @return the VM command parameters.
+ */
+ protected Commandline getActualVMCommand() {
+ Commandline actualVMCommand = (Commandline) vmCommand.clone();
+ if (maxMemory != null) {
+ if (vmVersion.startsWith("1.1")) {
+ actualVMCommand.createArgument().setValue("-mx" + maxMemory);
+ } else {
+ actualVMCommand.createArgument().setValue("-Xmx" + maxMemory);
+ }
+ }
+ return actualVMCommand;
+ }
+
+ /**
+ * Get the size of the java command line. This is a fairly intensive
+ * operation, as it has to evaluate the size of many components.
+ * @return the total number of arguments in the java command line.
+ * @see #getCommandline()
+ * @deprecated since 1.7.
+ * Please dont use this, it effectively creates the
+ * entire command.
+ */
+ public int size() {
+ int size = getActualVMCommand().size() + javaCommand.size()
+ + sysProperties.size();
+ // cloned system properties
+ if (isCloneVm()) {
+ size += System.getProperties().size();
+ }
+ // classpath is "-classpath <classpath>" -> 2 args
+ if (haveClasspath()) {
+ size += 2;
+ }
+ // bootclasspath is "-Xbootclasspath:<classpath>" -> 1 arg
+ if (calculateBootclasspath(true).size() > 0) {
+ size++;
+ }
+ // jar execution requires an additional -jar option
+ if (executeJar) {
+ size++;
+ }
+ //assertions take up space too
+ if (getAssertions() != null) {
+ size += getAssertions().size();
+ }
+ return size;
+ }
+
+ /**
+ * Get the Java command to be used.
+ * @return the java command--not a clone.
+ */
+ public Commandline getJavaCommand() {
+ return javaCommand;
+ }
+
+ /**
+ * Get the VM command, including memory.
+ * @return A deep clone of the instance's VM command, with memory settings added.
+ */
+ public Commandline getVmCommand() {
+ return getActualVMCommand();
+ }
+
+ /**
+ * Get the classpath for the command.
+ * @return the classpath or null.
+ */
+ public Path getClasspath() {
+ return classpath;
+ }
+
+ /**
+ * Get the boot classpath.
+ * @return boot classpath or null.
+ */
+ public Path getBootclasspath() {
+ return bootclasspath;
+ }
+
+ /**
+ * Cache current system properties and set them to those in this
+ * Java command.
+ * @throws BuildException if Security prevented this operation.
+ */
+ public void setSystemProperties() throws BuildException {
+ sysProperties.setSystem();
+ }
+
+ /**
+ * Restore the cached system properties.
+ * @throws BuildException if Security prevented this operation, or
+ * there was no system properties to restore
+ */
+ public void restoreSystemProperties() throws BuildException {
+ sysProperties.restoreSystem();
+ }
+
+ /**
+ * Get the system properties object.
+ * @return The system properties object.
+ */
+ public SysProperties getSystemProperties() {
+ return sysProperties;
+ }
+
+ /**
+ * Deep clone the object.
+ * @return a CommandlineJava object.
+ * @throws BuildException if anything went wrong.
+ * @throws CloneNotSupportedException never.
+ */
+ public Object clone() throws CloneNotSupportedException {
+ try {
+ CommandlineJava c = (CommandlineJava) super.clone();
+ c.vmCommand = (Commandline) vmCommand.clone();
+ c.javaCommand = (Commandline) javaCommand.clone();
+ c.sysProperties = (SysProperties) sysProperties.clone();
+ if (classpath != null) {
+ c.classpath = (Path) classpath.clone();
+ }
+ if (bootclasspath != null) {
+ c.bootclasspath = (Path) bootclasspath.clone();
+ }
+ if (assertions != null) {
+ c.assertions = (Assertions) assertions.clone();
+ }
+ return c;
+ } catch (CloneNotSupportedException e) {
+ throw new BuildException(e);
+ }
+ }
+
+ /**
+ * Clear out the java arguments.
+ */
+ public void clearJavaArgs() {
+ javaCommand.clearArgs();
+ }
+
+ /**
+ * Determine whether the classpath has been specified, and whether it shall
+ * really be used or be nulled by build.sysclasspath.
+ * @return true if the classpath is to be used.
+ * @since Ant 1.6
+ */
+ public boolean haveClasspath() {
+ Path fullClasspath = classpath != null
+ ? classpath.concatSystemClasspath("ignore") : null;
+ return fullClasspath != null
+ && fullClasspath.toString().trim().length() > 0;
+ }
+
+ /**
+ * Determine whether the bootclasspath has been specified, and whether it
+ * shall really be used (build.sysclasspath could be set or the VM may not
+ * support it).
+ *
+ * @param log whether to log a warning if a bootclasspath has been
+ * specified but will be ignored.
+ * @return true if the bootclasspath is to be used.
+ * @since Ant 1.6
+ */
+ protected boolean haveBootclasspath(boolean log) {
+ return calculateBootclasspath(log).size() > 0;
+ }
+
+ /**
+ * Calculate the bootclasspath based on the bootclasspath
+ * specified, the build.sysclasspath and ant.build.clonevm magic
+ * properties as well as the cloneVm attribute.
+ * @param log whether to write messages to the log.
+ * @since Ant 1.7
+ */
+ private Path calculateBootclasspath(boolean log) {
+ if (vmVersion.startsWith("1.1")) {
+ if (bootclasspath != null && log) {
+ bootclasspath.log("Ignoring bootclasspath as "
+ + "the target VM doesn't support it.");
+ }
+ } else {
+ Path b = bootclasspath;
+ if (b == null) {
+ b = new Path(null);
+ }
+ // even with no user-supplied bootclasspath
+ // build.sysclasspath could be set to something other than
+ // "ignore" and thus create one
+ return b.concatSystemBootClasspath(isCloneVm() ? "last" : "ignore");
+ }
+ return new Path(null);
+ }
+
+ /**
+ * Find out whether either of the cloneVm attribute or the magic property
+ * ant.build.clonevm has been set.
+ * @return <code>boolean</code>.
+ * @since 1.7
+ */
+ private boolean isCloneVm() {
+ return cloneVm
+ || "true".equals(System.getProperty("ant.build.clonevm"));
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/Comparison.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/Comparison.java
new file mode 100644
index 00000000..a057d0d7
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/Comparison.java
@@ -0,0 +1,95 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types;
+
+import java.util.Arrays;
+
+import org.apache.tools.ant.BuildException;
+
+/**
+ * EnumeratedAttribute for generic comparisons. Accepts values
+ * "equal", "greater", "more", "less", "ne" (not equal),
+ * "ge" (greater or equal), "le" (less or equal), "eq" (equal),
+ * "gt" (greater), "lt" (less).
+ * @since Ant 1.7
+ */
+public class Comparison extends EnumeratedAttribute {
+ private static final String[] VALUES
+ = new String[] {"equal", "greater", "less",
+ "ne", "ge", "le", "eq", "gt", "lt", "more"};
+
+ /** Equal Comparison. */
+ public static final Comparison EQUAL = new Comparison("equal");
+
+ /** Not-Equal Comparison. */
+ public static final Comparison NOT_EQUAL = new Comparison("ne");
+
+ /** Greater Comparison. */
+ public static final Comparison GREATER = new Comparison("greater");
+
+ /** Less Comparison. */
+ public static final Comparison LESS = new Comparison("less");
+
+ /** Greater-or-Equal Comparison. */
+ public static final Comparison GREATER_EQUAL = new Comparison("ge");
+
+ /** Less-or-Equal Comparison. */
+ public static final Comparison LESS_EQUAL = new Comparison("le");
+
+ private static final int[] EQUAL_INDEX = {0, 4, 5, 6};
+ private static final int[] LESS_INDEX = {2, 3, 5, 8};
+ private static final int[] GREATER_INDEX = {1, 3, 4, 7, 9};
+
+ /**
+ * Default constructor.
+ */
+ public Comparison() {
+ }
+
+ /**
+ * Construct a new Comparison with the specified value.
+ * @param value the EnumeratedAttribute value.
+ */
+ public Comparison(String value) {
+ setValue(value);
+ }
+
+ /**
+ * Return the possible values.
+ * @return String[] of EnumeratedAttribute values.
+ */
+ public String[] getValues() {
+ return VALUES;
+ }
+
+ /**
+ * Evaluate a comparison result as from Comparator.compare() or Comparable.compareTo().
+ * @param comparisonResult the result to evaluate.
+ * @return true if the comparison result fell within the parameters of this Comparison.
+ */
+ public boolean evaluate(int comparisonResult) {
+ if (getIndex() == -1) {
+ throw new BuildException("Comparison value not set.");
+ }
+ int[] i = comparisonResult < 0 ? LESS_INDEX
+ : comparisonResult > 0 ? GREATER_INDEX : EQUAL_INDEX;
+ return Arrays.binarySearch(i, getIndex()) >= 0;
+ }
+
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/DTDLocation.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/DTDLocation.java
new file mode 100644
index 00000000..9fdeee29
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/DTDLocation.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types;
+
+/**
+ * <p>Helper class to handle the DTD nested element. Instances of
+ * this class correspond to the <code>PUBLIC</code> catalog entry type
+ * of the <a
+ * href="http://oasis-open.org/committees/entity/spec-2001-08-06.html">
+ * OASIS "Open Catalog" standard</a>.</p>
+ *
+ * <p>Possible Future Enhancement: Bring the Ant element name into
+ * conformance with the OASIS standard.</p>
+ *
+ * @see org.apache.xml.resolver.Catalog
+ */
+public class DTDLocation extends ResourceLocation {
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/DataType.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/DataType.java
new file mode 100644
index 00000000..fda4af62
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/DataType.java
@@ -0,0 +1,367 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types;
+
+import java.util.Stack;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.ComponentHelper;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.ProjectComponent;
+import org.apache.tools.ant.util.IdentityStack;
+
+/**
+ * Base class for those classes that can appear inside the build file
+ * as stand alone data types.
+ *
+ * <p>This class handles the common description attribute and provides
+ * a default implementation for reference handling and checking for
+ * circular references that is appropriate for types that can not be
+ * nested inside elements of the same type (i.e. &lt;patternset&gt;
+ * but not &lt;path&gt;).</p>
+ *
+ */
+public abstract class DataType extends ProjectComponent implements Cloneable {
+ // CheckStyle:VisibilityModifier OFF
+
+ /**
+ * Value to the refid attribute.
+ *
+ * @deprecated since 1.7.
+ * The user should not be directly referencing
+ * variable. Please use {@link #getRefid} instead.
+ */
+ protected Reference ref;
+
+ /**
+ * Are we sure we don't hold circular references?
+ *
+ * <p>Subclasses are responsible for setting this value to false
+ * if we'd need to investigate this condition (usually because a
+ * child element has been added that is a subclass of
+ * DataType).</p>
+ *
+ * @deprecated since 1.7.
+ * The user should not be directly referencing
+ * variable. Please use {@link #setChecked} or
+ * {@link #isChecked} instead.
+ */
+ protected boolean checked = true;
+ // CheckStyle:VisibilityModifier ON
+
+ /**
+ * Has the refid attribute of this element been set?
+ * @return true if the refid attribute has been set
+ */
+ public boolean isReference() {
+ return ref != null;
+ }
+
+ /**
+ * Set the value of the refid attribute.
+ *
+ * <p>Subclasses may need to check whether any other attributes
+ * have been set as well or child elements have been created and
+ * thus override this method. if they do the must call
+ * <code>super.setRefid</code>.</p>
+ * @param ref the reference to use
+ */
+ public void setRefid(final Reference ref) {
+ this.ref = ref;
+ checked = false;
+ }
+
+ /**
+ * Gets as descriptive as possible a name used for this datatype instance.
+ * @return <code>String</code> name.
+ */
+ protected String getDataTypeName() {
+ return ComponentHelper.getElementName(getProject(), this, true);
+ }
+
+ /**
+ * Convenience method.
+ * @since Ant 1.7
+ */
+ protected void dieOnCircularReference() {
+ dieOnCircularReference(getProject());
+ }
+
+ /**
+ * Convenience method.
+ * @param p the Ant Project instance against which to resolve references.
+ * @since Ant 1.7
+ */
+ protected void dieOnCircularReference(Project p) {
+ if (checked || !isReference()) {
+ return;
+ }
+ dieOnCircularReference(new IdentityStack<Object>(this), p);
+ }
+
+ /**
+ * Check to see whether any DataType we hold references to is
+ * included in the Stack (which holds all DataType instances that
+ * directly or indirectly reference this instance, including this
+ * instance itself).
+ *
+ * <p>If one is included, throw a BuildException created by {@link
+ * #circularReference circularReference}.</p>
+ *
+ * <p>This implementation is appropriate only for a DataType that
+ * cannot hold other DataTypes as children.</p>
+ *
+ * <p>The general contract of this method is that it shouldn't do
+ * anything if {@link #checked <code>checked</code>} is true and
+ * set it to true on exit.</p>
+ * @param stack the stack of references to check.
+ * @param project the project to use to dereference the references.
+ * @throws BuildException on error.
+ */
+ protected void dieOnCircularReference(final Stack<Object> stack,
+ final Project project)
+ throws BuildException {
+
+ if (checked || !isReference()) {
+ return;
+ }
+ Object o = ref.getReferencedObject(project);
+
+ if (o instanceof DataType) {
+ IdentityStack<Object> id = IdentityStack.getInstance(stack);
+
+ if (id.contains(o)) {
+ throw circularReference();
+ } else {
+ id.push(o);
+ ((DataType) o).dieOnCircularReference(id, project);
+ id.pop();
+ }
+ }
+ checked = true;
+ }
+
+ /**
+ * Allow DataTypes outside org.apache.tools.ant.types to indirectly call
+ * dieOnCircularReference on nested DataTypes.
+ * @param dt the DataType to check.
+ * @param stk the stack of references to check.
+ * @param p the project to use to dereference the references.
+ * @throws BuildException on error.
+ * @since Ant 1.7
+ */
+ public static void invokeCircularReferenceCheck(DataType dt, Stack<Object> stk,
+ Project p) {
+ dt.dieOnCircularReference(stk, p);
+ }
+
+ /**
+ * Allow DataTypes outside org.apache.tools.ant.types to indirectly call
+ * dieOnCircularReference on nested DataTypes.
+ *
+ * <p>Pushes dt on the stack, runs dieOnCircularReference and pops
+ * it again.</p>
+ * @param dt the DataType to check.
+ * @param stk the stack of references to check.
+ * @param p the project to use to dereference the references.
+ * @throws BuildException on error.
+ * @since Ant 1.8.0
+ */
+ public static void pushAndInvokeCircularReferenceCheck(DataType dt,
+ Stack<Object> stk,
+ Project p) {
+ stk.push(dt);
+ dt.dieOnCircularReference(stk, p);
+ stk.pop();
+ }
+
+ /**
+ * Performs the check for circular references and returns the
+ * referenced object.
+ * @return the dereferenced object.
+ * @throws BuildException if the reference is invalid (circular ref, wrong class, etc).
+ * @since Ant 1.7
+ */
+ protected Object getCheckedRef() {
+ return getCheckedRef(getProject());
+ }
+
+ /**
+ * Performs the check for circular references and returns the
+ * referenced object.
+ * @param p the Ant Project instance against which to resolve references.
+ * @return the dereferenced object.
+ * @throws BuildException if the reference is invalid (circular ref, wrong class, etc).
+ * @since Ant 1.7
+ */
+ protected Object getCheckedRef(Project p) {
+ return getCheckedRef(getClass(), getDataTypeName(), p);
+ }
+
+ /**
+ * Performs the check for circular references and returns the
+ * referenced object.
+ * @param requiredClass the class that this reference should be a subclass of.
+ * @param dataTypeName the name of the datatype that the reference should be
+ * (error message use only).
+ * @return the dereferenced object.
+ * @throws BuildException if the reference is invalid (circular ref, wrong class, etc).
+ */
+ protected <T> T getCheckedRef(final Class<T> requiredClass,
+ final String dataTypeName) {
+ return getCheckedRef(requiredClass, dataTypeName, getProject());
+ }
+
+ /**
+ * Performs the check for circular references and returns the
+ * referenced object. This version allows the fallback Project instance to be specified.
+ * @param requiredClass the class that this reference should be a subclass of.
+ * @param dataTypeName the name of the datatype that the reference should be
+ * (error message use only).
+ * @param project the fallback Project instance for dereferencing.
+ * @return the dereferenced object.
+ * @throws BuildException if the reference is invalid (circular ref, wrong class, etc),
+ * or if <code>project</code> is <code>null</code>.
+ * @since Ant 1.7
+ */
+ protected <T> T getCheckedRef(final Class<T> requiredClass,
+ final String dataTypeName, final Project project) {
+ if (project == null) {
+ throw new BuildException("No Project specified");
+ }
+ dieOnCircularReference(project);
+ Object o = ref.getReferencedObject(project);
+ if (!(requiredClass.isAssignableFrom(o.getClass()))) {
+ log("Class " + displayName(o.getClass())
+ + " is not a subclass of "
+ + displayName(requiredClass),
+ Project.MSG_VERBOSE);
+ String msg = ref.getRefId() + " doesn\'t denote a " + dataTypeName;
+ throw new BuildException(msg);
+ }
+ @SuppressWarnings("unchecked")
+ final T result = (T) o;
+ return result;
+ }
+
+ /**
+ * Creates an exception that indicates that refid has to be the
+ * only attribute if it is set.
+ * @return the exception to throw
+ */
+ protected BuildException tooManyAttributes() {
+ return new BuildException("You must not specify more than one "
+ + "attribute when using refid");
+ }
+
+ /**
+ * Creates an exception that indicates that this XML element must
+ * not have child elements if the refid attribute is set.
+ * @return the exception to throw
+ */
+ protected BuildException noChildrenAllowed() {
+ return new BuildException("You must not specify nested elements "
+ + "when using refid");
+ }
+
+ /**
+ * Creates an exception that indicates the user has generated a
+ * loop of data types referencing each other.
+ * @return the exception to throw
+ */
+ protected BuildException circularReference() {
+ return new BuildException("This data type contains a circular "
+ + "reference.");
+ }
+
+ /**
+ * The flag that is used to indicate that circular references have been checked.
+ * @return true if circular references have been checked
+ */
+ protected boolean isChecked() {
+ return checked;
+ }
+
+ /**
+ * Set the flag that is used to indicate that circular references have been checked.
+ * @param checked if true, if circular references have been checked
+ */
+ protected void setChecked(final boolean checked) {
+ this.checked = checked;
+ }
+
+ /**
+ * get the reference set on this object
+ * @return the reference or null
+ */
+ public Reference getRefid() {
+ return ref;
+ }
+
+ /**
+ * check that it is ok to set attributes, i.e that no reference is defined
+ * @since Ant 1.6
+ * @throws BuildException if not allowed
+ */
+ protected void checkAttributesAllowed() {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ }
+
+ /**
+ * check that it is ok to add children, i.e that no reference is defined
+ * @since Ant 1.6
+ * @throws BuildException if not allowed
+ */
+ protected void checkChildrenAllowed() {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ }
+
+ /**
+ * Basic DataType toString().
+ * @return this DataType formatted as a String.
+ */
+ public String toString() {
+ String d = getDescription();
+ return d == null ? getDataTypeName() : getDataTypeName() + " " + d;
+ }
+
+ /**
+ * @since Ant 1.7
+ * @return a shallow copy of this DataType.
+ * @throws CloneNotSupportedException if there is a problem.
+ */
+ public Object clone() throws CloneNotSupportedException {
+ DataType dt = (DataType) super.clone();
+ dt.setDescription(getDescription());
+ if (getRefid() != null) {
+ dt.setRefid(getRefid());
+ }
+ dt.setChecked(isChecked());
+ return dt;
+ }
+
+ private String displayName(Class<?> clazz) {
+ return clazz.getName() + " (loaded via " + clazz.getClassLoader() +")";
+ }
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/Description.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/Description.java
new file mode 100644
index 00000000..d23f1d88
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/Description.java
@@ -0,0 +1,116 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.ProjectHelper;
+import org.apache.tools.ant.Target;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.UnknownElement;
+import org.apache.tools.ant.helper.ProjectHelper2;
+import org.apache.tools.ant.helper.ProjectHelperImpl;
+
+
+/**
+ * Description is used to provide a project-wide description element
+ * (that is, a description that applies to a buildfile as a whole).
+ * If present, the &lt;description&gt; element is printed out before the
+ * target descriptions.
+ *
+ * Description has no attributes, only text. There can only be one
+ * project description per project. A second description element will
+ * overwrite the first.
+ *
+ *
+ * @ant.datatype ignore="true"
+ */
+public class Description extends DataType {
+
+ /**
+ * Adds descriptive text to the project.
+ *
+ * @param text the descriptive text
+ */
+ public void addText(String text) {
+
+ ProjectHelper ph = getProject().getReference(ProjectHelper.PROJECTHELPER_REFERENCE);
+ if (!(ph instanceof ProjectHelperImpl)) {
+ // New behavior for delayed task creation. Description
+ // will be evaluated in Project.getDescription()
+ return;
+ }
+ String currentDescription = getProject().getDescription();
+ if (currentDescription == null) {
+ getProject().setDescription(text);
+ } else {
+ getProject().setDescription(currentDescription + text);
+ }
+ }
+
+ /**
+ * Return the descriptions from all the targets of
+ * a project.
+ *
+ * @param project the project to get the descriptions for.
+ * @return a string containing the concatenated descriptions of
+ * the targets.
+ */
+ public static String getDescription(Project project) {
+ List<Target> targets = project.getReference(ProjectHelper2.REFID_TARGETS);
+ if (targets == null) {
+ return null;
+ }
+ StringBuilder description = new StringBuilder();
+ for (Target t : targets) {
+ concatDescriptions(project, t, description);
+ }
+ return description.toString();
+ }
+
+ private static void concatDescriptions(Project project, Target t,
+ StringBuilder description) {
+ if (t == null) {
+ return;
+ }
+ for (Task task : findElementInTarget(project, t, "description")) {
+ if (!(task instanceof UnknownElement)) {
+ continue;
+ }
+ UnknownElement ue = ((UnknownElement) task);
+ String descComp = ue.getWrapper().getText().toString();
+ if (descComp != null) {
+ description.append(project.replaceProperties(descComp));
+ }
+ }
+ }
+
+ private static List<Task> findElementInTarget(Project project,
+ Target t, String name) {
+ final List<Task> elems = new ArrayList<Task>();
+ for (Task task : t.getTasks()) {
+ if (name.equals(task.getTaskName())) {
+ elems.add(task);
+ }
+ }
+ return elems;
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/DirSet.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/DirSet.java
new file mode 100644
index 00000000..35c02311
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/DirSet.java
@@ -0,0 +1,115 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types;
+
+import java.util.Iterator;
+
+import org.apache.tools.ant.DirectoryScanner;
+import org.apache.tools.ant.types.resources.FileResourceIterator;
+
+/**
+ * Subclass as hint for supporting tasks that the included directories
+ * instead of files should be used.
+ *
+ * @since Ant 1.5
+ */
+public class DirSet extends AbstractFileSet implements ResourceCollection {
+
+ /**
+ * Constructor for DirSet.
+ */
+ public DirSet() {
+ super();
+ }
+
+ /**
+ * Constructor for DirSet, with DirSet to shallowly clone.
+ * @param dirset the dirset to clone.
+ */
+ protected DirSet(DirSet dirset) {
+ super(dirset);
+ }
+
+ /**
+ * Return a DirSet that has the same basedir and same patternsets
+ * as this one.
+ * @return the cloned dirset.
+ */
+ public Object clone() {
+ if (isReference()) {
+ return ((DirSet) getRef(getProject())).clone();
+ } else {
+ return super.clone();
+ }
+ }
+
+ /**
+ * Fulfill the ResourceCollection contract.
+ * @return an Iterator of Resources.
+ * @since Ant 1.7
+ */
+ public Iterator<Resource> iterator() {
+ if (isReference()) {
+ return ((DirSet) getRef(getProject())).iterator();
+ }
+ return new FileResourceIterator(getProject(), getDir(getProject()),
+ getDirectoryScanner(getProject()).getIncludedDirectories());
+ }
+
+ /**
+ * Fulfill the ResourceCollection contract.
+ * @return number of elements as int.
+ * @since Ant 1.7
+ */
+ public int size() {
+ if (isReference()) {
+ return ((DirSet) getRef(getProject())).size();
+ }
+ return getDirectoryScanner(getProject()).getIncludedDirsCount();
+ }
+
+ /**
+ * Always returns true.
+ * @return true indicating that all elements will be FileResources.
+ * @since Ant 1.7
+ */
+ public boolean isFilesystemOnly() {
+ return true;
+ }
+
+ /**
+ * Returns included directories as a list of semicolon-separated paths.
+ *
+ * @return a <code>String</code> of included directories.
+ */
+ public String toString() {
+ DirectoryScanner ds = getDirectoryScanner(getProject());
+ String[] dirs = ds.getIncludedDirectories();
+ StringBuffer sb = new StringBuffer();
+
+ for (int i = 0; i < dirs.length; i++) {
+ if (i > 0) {
+ sb.append(';');
+ }
+ sb.append(dirs[i]);
+ }
+ return sb.toString();
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/EnumeratedAttribute.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/EnumeratedAttribute.java
new file mode 100644
index 00000000..bc893d8d
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/EnumeratedAttribute.java
@@ -0,0 +1,153 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types;
+
+import org.apache.tools.ant.BuildException;
+
+/**
+ * Helper class for attributes that can only take one of a fixed list
+ * of values.
+ *
+ * <p>See {@link org.apache.tools.ant.taskdefs.FixCRLF FixCRLF} for an
+ * example.
+ *
+ */
+public abstract class EnumeratedAttribute {
+ // CheckStyle:VisibilityModifier OFF - bc
+ /**
+ * The selected value in this enumeration.
+ */
+ protected String value;
+
+ // CheckStyle:VisibilityModifier ON
+
+ /**
+ * the index of the selected value in the array.
+ */
+ private int index = -1;
+
+ /**
+ * This is the only method a subclass needs to implement.
+ *
+ * @return an array holding all possible values of the enumeration.
+ * The order of elements must be fixed so that <tt>indexOfValue(String)</tt>
+ * always return the same index for the same value.
+ */
+ public abstract String[] getValues();
+
+ /** bean constructor */
+ protected EnumeratedAttribute() {
+ }
+
+ /**
+ * Factory method for instantiating EAs via API in a more
+ * developer friendly way.
+ * @param clazz Class, extending EA, which to instantiate
+ * @param value The value to set on that EA
+ * @return Configured EA
+ * @throws BuildException If the class could not be found or the value
+ * is not valid for the given EA-class.
+ * @see <a href="http://issues.apache.org/bugzilla/show_bug.cgi?id=14831">
+ * http://issues.apache.org/bugzilla/show_bug.cgi?id=14831</a>
+ */
+ public static EnumeratedAttribute getInstance(
+ Class<? extends EnumeratedAttribute> clazz,
+ String value) throws BuildException {
+ if (!EnumeratedAttribute.class.isAssignableFrom(clazz)) {
+ throw new BuildException(
+ "You have to provide a subclass from EnumeratedAttribut as clazz-parameter.");
+ }
+ EnumeratedAttribute ea = null;
+ try {
+ ea = clazz.newInstance();
+ } catch (Exception e) {
+ throw new BuildException(e);
+ }
+ ea.setValue(value);
+ return ea;
+ }
+
+ /**
+ * Invoked by {@link org.apache.tools.ant.IntrospectionHelper IntrospectionHelper}.
+ * @param value the <code>String</code> value of the attribute
+ * @throws BuildException if the value is not valid for the attribute
+ */
+ public final void setValue(String value) throws BuildException {
+ int idx = indexOfValue(value);
+ if (idx == -1) {
+ throw new BuildException(value + " is not a legal value for this attribute");
+ }
+ this.index = idx;
+ this.value = value;
+ }
+
+ /**
+ * Is this value included in the enumeration?
+ * @param value the <code>String</code> value to look up
+ * @return true if the value is valid
+ */
+ public final boolean containsValue(String value) {
+ return (indexOfValue(value) != -1);
+ }
+
+ /**
+ * get the index of a value in this enumeration.
+ * @param value the string value to look for.
+ * @return the index of the value in the array of strings
+ * or -1 if it cannot be found.
+ * @see #getValues()
+ */
+ public final int indexOfValue(String value) {
+ String[] values = getValues();
+ if (values == null || value == null) {
+ return -1;
+ }
+ for (int i = 0; i < values.length; i++) {
+ if (value.equals(values[i])) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * @return the selected value.
+ */
+ public final String getValue() {
+ return value;
+ }
+
+ /**
+ * @return the index of the selected value in the array.
+ * @see #getValues()
+ */
+ public final int getIndex() {
+ return index;
+ }
+
+ /**
+ * Convert the value to its string form.
+ *
+ * @return the string form of the value.
+ */
+ public String toString() {
+ return getValue();
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/Environment.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/Environment.java
new file mode 100644
index 00000000..5bc6d79e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/Environment.java
@@ -0,0 +1,177 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types;
+
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildException;
+
+/**
+ * Wrapper for environment variables.
+ *
+ */
+public class Environment {
+ // CheckStyle:VisibilityModifier OFF - bc
+
+ /**
+ * a vector of type Environment.Variable
+ * @see Variable
+ */
+ protected Vector<Variable> variables;
+
+ // CheckStyle:VisibilityModifier ON
+
+ /**
+ * representation of a single env value
+ */
+ public static class Variable {
+
+ /**
+ * env key and value pair; everything gets expanded to a string
+ * during assignment
+ */
+ private String key, value;
+
+ /**
+ * Constructor for variable
+ *
+ */
+ public Variable() {
+ super();
+ }
+
+ /**
+ * set the key
+ * @param key string
+ */
+ public void setKey(String key) {
+ this.key = key;
+ }
+
+ /**
+ * set the value
+ * @param value string value
+ */
+ public void setValue(String value) {
+ this.value = value;
+ }
+
+ /**
+ * key accessor
+ * @return key
+ */
+ public String getKey() {
+ return this.key;
+ }
+
+ /**
+ * value accessor
+ * @return value
+ */
+ public String getValue() {
+ return this.value;
+ }
+
+ /**
+ * stringify path and assign to the value.
+ * The value will contain all path elements separated by the appropriate
+ * separator
+ * @param path path
+ */
+ public void setPath(Path path) {
+ this.value = path.toString();
+ }
+
+ /**
+ * get the absolute path of a file and assign it to the value
+ * @param file file to use as the value
+ */
+ public void setFile(java.io.File file) {
+ this.value = file.getAbsolutePath();
+ }
+
+ /**
+ * get the assignment string
+ * This is not ready for insertion into a property file without following
+ * the escaping rules of the properties class.
+ * @return a string of the form key=value.
+ * @throws BuildException if key or value are unassigned
+ */
+ public String getContent() throws BuildException {
+ validate();
+ StringBuffer sb = new StringBuffer(key.trim());
+ sb.append("=").append(value.trim());
+ return sb.toString();
+ }
+
+ /**
+ * checks whether all required attributes have been specified.
+ * @throws BuildException if key or value are unassigned
+ */
+ public void validate() {
+ if (key == null || value == null) {
+ throw new BuildException("key and value must be specified "
+ + "for environment variables.");
+ }
+ }
+ }
+
+ /**
+ * constructor
+ */
+ public Environment() {
+ variables = new Vector<Variable>();
+ }
+
+ /**
+ * add a variable.
+ * Validity checking is <i>not</i> performed at this point. Duplicates
+ * are not caught either.
+ * @param var new variable.
+ */
+ public void addVariable(Variable var) {
+ variables.addElement(var);
+ }
+
+ /**
+ * get the variable list as an array
+ * @return array of key=value assignment strings
+ * @throws BuildException if any variable is misconfigured
+ */
+ public String[] getVariables() throws BuildException {
+ if (variables.size() == 0) {
+ return null;
+ }
+ String[] result = new String[variables.size()];
+ for (int i = 0; i < result.length; i++) {
+ result[i] = ((Variable) variables.elementAt(i)).getContent();
+ }
+ return result;
+ }
+
+ /**
+ * Get the raw vector of variables. This is not a clone.
+ * @return a potentially empty (but never null) vector of elements of type
+ * Variable
+ * @since Ant 1.7
+ */
+ public Vector<Variable> getVariablesVector() {
+ return variables;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/FileList.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/FileList.java
new file mode 100644
index 00000000..42e27635
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/FileList.java
@@ -0,0 +1,219 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.StringTokenizer;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.resources.FileResourceIterator;
+
+/**
+ * FileList represents an explicitly named list of files. FileLists
+ * are useful when you want to capture a list of files regardless of
+ * whether they currently exist. By contrast, FileSet operates as a
+ * filter, only returning the name of a matched file if it currently
+ * exists in the file system.
+ */
+public class FileList extends DataType implements ResourceCollection {
+
+ private List<String> filenames = new ArrayList<String>();
+ private File dir;
+
+ /**
+ * The default constructor.
+ *
+ */
+ public FileList() {
+ super();
+ }
+
+ /**
+ * A copy constructor.
+ *
+ * @param filelist a <code>FileList</code> value
+ */
+ protected FileList(FileList filelist) {
+ this.dir = filelist.dir;
+ this.filenames = filelist.filenames;
+ setProject(filelist.getProject());
+ }
+
+ /**
+ * Makes this instance in effect a reference to another FileList
+ * instance.
+ *
+ * <p>You must not set another attribute or nest elements inside
+ * this element if you make it a reference.</p>
+ * @param r the reference to another filelist.
+ * @exception BuildException if an error occurs.
+ */
+ public void setRefid(Reference r) throws BuildException {
+ if ((dir != null) || (filenames.size() != 0)) {
+ throw tooManyAttributes();
+ }
+ super.setRefid(r);
+ }
+
+ /**
+ * Set the dir attribute.
+ *
+ * @param dir the directory this filelist is relative to.
+ * @exception BuildException if an error occurs
+ */
+ public void setDir(File dir) throws BuildException {
+ checkAttributesAllowed();
+ this.dir = dir;
+ }
+
+ /**
+ * @param p the current project
+ * @return the directory attribute
+ */
+ public File getDir(Project p) {
+ if (isReference()) {
+ return getRef(p).getDir(p);
+ }
+ return dir;
+ }
+
+ /**
+ * Set the filenames attribute.
+ *
+ * @param filenames a string contains filenames, separated by , or
+ * by whitespace.
+ */
+ public void setFiles(String filenames) {
+ checkAttributesAllowed();
+ if (filenames != null && filenames.length() > 0) {
+ StringTokenizer tok = new StringTokenizer(
+ filenames, ", \t\n\r\f", false);
+ while (tok.hasMoreTokens()) {
+ this.filenames.add(tok.nextToken());
+ }
+ }
+ }
+
+ /**
+ * Returns the list of files represented by this FileList.
+ * @param p the current project
+ * @return the list of files represented by this FileList.
+ */
+ public String[] getFiles(Project p) {
+ if (isReference()) {
+ return getRef(p).getFiles(p);
+ }
+
+ if (dir == null) {
+ throw new BuildException("No directory specified for filelist.");
+ }
+
+ if (filenames.size() == 0) {
+ throw new BuildException("No files specified for filelist.");
+ }
+
+ return filenames.toArray(new String[filenames.size()]);
+ }
+
+ /**
+ * Performs the check for circular references and returns the
+ * referenced FileList.
+ * @param p the current project
+ * @return the FileList represented by a referenced filelist.
+ */
+ protected FileList getRef(Project p) {
+ return (FileList) getCheckedRef(p);
+ }
+
+ /**
+ * Inner class corresponding to the &lt;file&gt; nested element.
+ */
+ public static class FileName {
+ private String name;
+
+ /**
+ * The name attribute of the file element.
+ *
+ * @param name the name of a file to add to the file list.
+ */
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ /**
+ * @return the name of the file for this element.
+ */
+ public String getName() {
+ return name;
+ }
+ }
+
+ /**
+ * Add a nested &lt;file&gt; nested element.
+ *
+ * @param name a configured file element with a name.
+ * @since Ant 1.6.2
+ */
+ public void addConfiguredFile(FileName name) {
+ if (name.getName() == null) {
+ throw new BuildException(
+ "No name specified in nested file element");
+ }
+ filenames.add(name.getName());
+ }
+
+ /**
+ * Fulfill the ResourceCollection contract.
+ * @return an Iterator of Resources.
+ * @since Ant 1.7
+ */
+ public Iterator<Resource> iterator() {
+ if (isReference()) {
+ return getRef(getProject()).iterator();
+ }
+ return new FileResourceIterator(getProject(), dir,
+ filenames.toArray(new String[filenames.size()]));
+ }
+
+ /**
+ * Fulfill the ResourceCollection contract.
+ * @return number of elements as int.
+ * @since Ant 1.7
+ */
+ public int size() {
+ if (isReference()) {
+ return ((FileList) getRef(getProject())).size();
+ }
+ return filenames.size();
+ }
+
+ /**
+ * Always returns true.
+ * @return true indicating that all elements will be FileResources.
+ * @since Ant 1.7
+ */
+ public boolean isFilesystemOnly() {
+ return true;
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/FileSet.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/FileSet.java
new file mode 100644
index 00000000..c6d2127d
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/FileSet.java
@@ -0,0 +1,94 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types;
+
+import java.util.Iterator;
+
+import org.apache.tools.ant.types.resources.FileResourceIterator;
+
+/**
+ * Moved out of MatchingTask to make it a standalone object that could
+ * be referenced (by scripts for example).
+ *
+ */
+public class FileSet extends AbstractFileSet implements ResourceCollection {
+
+ /**
+ * Constructor for FileSet.
+ */
+ public FileSet() {
+ super();
+ }
+
+ /**
+ * Constructor for FileSet, with FileSet to shallowly clone.
+ * @param fileset the fileset to clone
+ */
+ protected FileSet(FileSet fileset) {
+ super(fileset);
+ }
+
+ /**
+ * Return a FileSet that has the same basedir and same patternsets
+ * as this one.
+ * @return the cloned fileset
+ */
+ public Object clone() {
+ if (isReference()) {
+ return ((FileSet) getRef(getProject())).clone();
+ } else {
+ return super.clone();
+ }
+ }
+
+ /**
+ * Fulfill the ResourceCollection contract.
+ * @return an Iterator of Resources.
+ * @since Ant 1.7
+ */
+ public Iterator<Resource> iterator() {
+ if (isReference()) {
+ return ((FileSet) getRef(getProject())).iterator();
+ }
+ return new FileResourceIterator(getProject(), getDir(getProject()),
+ getDirectoryScanner(getProject()).getIncludedFiles());
+ }
+
+ /**
+ * Fulfill the ResourceCollection contract.
+ * @return number of elements as int.
+ * @since Ant 1.7
+ */
+ public int size() {
+ if (isReference()) {
+ return ((FileSet) getRef(getProject())).size();
+ }
+ return getDirectoryScanner(getProject()).getIncludedFilesCount();
+ }
+
+ /**
+ * Always returns true.
+ * @return true indicating that all elements will be FileResources.
+ * @since Ant 1.7
+ */
+ public boolean isFilesystemOnly() {
+ return true;
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/FilterChain.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/FilterChain.java
new file mode 100644
index 00000000..b495a5a3
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/FilterChain.java
@@ -0,0 +1,418 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types;
+
+import java.util.Iterator;
+import java.util.Stack;
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.filters.ChainableReader;
+import org.apache.tools.ant.filters.ClassConstants;
+import org.apache.tools.ant.filters.EscapeUnicode;
+import org.apache.tools.ant.filters.ExpandProperties;
+import org.apache.tools.ant.filters.HeadFilter;
+import org.apache.tools.ant.filters.LineContains;
+import org.apache.tools.ant.filters.LineContainsRegExp;
+import org.apache.tools.ant.filters.PrefixLines;
+import org.apache.tools.ant.filters.ReplaceTokens;
+import org.apache.tools.ant.filters.StripJavaComments;
+import org.apache.tools.ant.filters.StripLineBreaks;
+import org.apache.tools.ant.filters.StripLineComments;
+import org.apache.tools.ant.filters.SuffixLines;
+import org.apache.tools.ant.filters.TabsToSpaces;
+import org.apache.tools.ant.filters.TailFilter;
+import org.apache.tools.ant.filters.TokenFilter;
+
+
+/**
+ * FilterChain may contain a chained set of filter readers.
+ *
+ */
+public class FilterChain extends DataType
+ implements Cloneable {
+
+ private Vector<Object> filterReaders = new Vector<Object>();
+
+ /**
+ * Add an AntFilterReader filter.
+ *
+ * @param filterReader an <code>AntFilterReader</code> value
+ */
+ public void addFilterReader(final AntFilterReader filterReader) {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ setChecked(false);
+ filterReaders.addElement(filterReader);
+ }
+
+ /**
+ * Return the filters.
+ *
+ * @return a <code>Vector</code> value containing the filters
+ */
+ public Vector<Object> getFilterReaders() {
+ if (isReference()) {
+ return ((FilterChain) getCheckedRef()).getFilterReaders();
+ }
+ dieOnCircularReference();
+ return filterReaders;
+ }
+
+ /**
+ * Add a ClassConstants filter.
+ *
+ * @param classConstants a <code>ClassConstants</code> value
+ */
+ public void addClassConstants(final ClassConstants classConstants) {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ setChecked(false);
+ filterReaders.addElement(classConstants);
+ }
+
+ /**
+ * Add an ExpandProperties filter.
+ *
+ * @param expandProperties an <code>ExpandProperties</code> value
+ */
+ public void addExpandProperties(final ExpandProperties expandProperties) {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ setChecked(false);
+ filterReaders.addElement(expandProperties);
+ }
+
+ /**
+ * Add a HeadFilter filter.
+ *
+ * @param headFilter a <code>HeadFilter</code> value
+ */
+ public void addHeadFilter(final HeadFilter headFilter) {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ setChecked(false);
+ filterReaders.addElement(headFilter);
+ }
+
+ /**
+ * Add a LineContains filter.
+ *
+ * @param lineContains a <code>LineContains</code> value
+ */
+ public void addLineContains(final LineContains lineContains) {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ setChecked(false);
+ filterReaders.addElement(lineContains);
+ }
+
+ /**
+ * Add a LineContainsRegExp filter.
+ *
+ * @param lineContainsRegExp a <code>LineContainsRegExp</code> value
+ */
+ public void addLineContainsRegExp(final LineContainsRegExp
+ lineContainsRegExp) {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ setChecked(false);
+ filterReaders.addElement(lineContainsRegExp);
+ }
+
+ /**
+ * Add a PrefixLines filter.
+ *
+ * @param prefixLines a <code>PrefixLines</code> value
+ */
+ public void addPrefixLines(final PrefixLines prefixLines) {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ setChecked(false);
+ filterReaders.addElement(prefixLines);
+ }
+
+ /**
+ * Add a SuffixLines filter.
+ *
+ * @param suffixLines a <code>SuffixLines</code> value
+ * @since Ant 1.8.0
+ */
+ public void addSuffixLines(final SuffixLines suffixLines) {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ setChecked(false);
+ filterReaders.addElement(suffixLines);
+ }
+
+ /**
+ * Add a ReplaceTokens filter.
+ *
+ * @param replaceTokens a <code>ReplaceTokens</code> value
+ */
+ public void addReplaceTokens(final ReplaceTokens replaceTokens) {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ setChecked(false);
+ filterReaders.addElement(replaceTokens);
+ }
+
+ /**
+ * Add a StripJavaCommands filter.
+ *
+ * @param stripJavaComments a <code>StripJavaComments</code> value
+ */
+ public void addStripJavaComments(final StripJavaComments
+ stripJavaComments) {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ setChecked(false);
+ filterReaders.addElement(stripJavaComments);
+ }
+
+ /**
+ * Add a StripLineBreaks filter.
+ *
+ * @param stripLineBreaks a <code>StripLineBreaks</code> value
+ */
+ public void addStripLineBreaks(final StripLineBreaks
+ stripLineBreaks) {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ setChecked(false);
+ filterReaders.addElement(stripLineBreaks);
+ }
+
+ /**
+ * Add a StripLineComments filter.
+ *
+ * @param stripLineComments a <code>StripLineComments</code> value
+ */
+ public void addStripLineComments(final StripLineComments
+ stripLineComments) {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ setChecked(false);
+ filterReaders.addElement(stripLineComments);
+ }
+
+ /**
+ * Add a TabsToSpaces filter.
+ *
+ * @param tabsToSpaces a <code>TabsToSpaces</code> value
+ */
+ public void addTabsToSpaces(final TabsToSpaces tabsToSpaces) {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ setChecked(false);
+ filterReaders.addElement(tabsToSpaces);
+ }
+
+ /**
+ * Add a TailFilter filter.
+ *
+ * @param tailFilter a <code>TailFilter</code> value
+ */
+ public void addTailFilter(final TailFilter tailFilter) {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ setChecked(false);
+ filterReaders.addElement(tailFilter);
+ }
+
+ /**
+ * Add an EscapeUnicode filter.
+ *
+ * @param escapeUnicode an <code>EscapeUnicode</code> value
+ * @since Ant 1.6
+ */
+ public void addEscapeUnicode(final EscapeUnicode escapeUnicode) {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ setChecked(false);
+ filterReaders.addElement(escapeUnicode);
+ }
+
+ /**
+ * Add a TokenFilter filter.
+ *
+ * @param tokenFilter a <code>TokenFilter</code> value
+ * @since Ant 1.6
+ */
+ public void addTokenFilter(final TokenFilter tokenFilter) {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ setChecked(false);
+ filterReaders.addElement(tokenFilter);
+ }
+
+ /**
+ * Add a delete characters filter.
+ *
+ * @param filter a <code>TokenFilter.DeleteCharacters</code> value
+ * @since Ant 1.6
+ */
+ public void addDeleteCharacters(TokenFilter.DeleteCharacters filter) {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ setChecked(false);
+ filterReaders.addElement(filter);
+ }
+
+ /**
+ * Add a containsregex filter.
+ *
+ * @param filter a <code>TokenFilter.ContainsRegex</code> value
+ * @since Ant 1.6
+ */
+ public void addContainsRegex(TokenFilter.ContainsRegex filter) {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ setChecked(false);
+ filterReaders.addElement(filter);
+ }
+
+ /**
+ * Add a replaceregex filter.
+ *
+ * @param filter a <code>TokenFilter.ReplaceRegex</code> value
+ */
+ public void addReplaceRegex(TokenFilter.ReplaceRegex filter) {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ setChecked(false);
+ filterReaders.addElement(filter);
+ }
+
+ /**
+ * Add a trim filter.
+ *
+ * @param filter a <code>TokenFilter.Trim</code> value
+ * @since Ant 1.6
+ */
+ public void addTrim(TokenFilter.Trim filter) {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ setChecked(false);
+ filterReaders.addElement(filter);
+ }
+
+ /**
+ * Add a replacestring filter.
+ *
+ * @param filter a <code>TokenFilter.ReplaceString</code> value
+ * @since Ant 1.6
+ */
+ public void addReplaceString(
+ TokenFilter.ReplaceString filter) {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ setChecked(false);
+ filterReaders.addElement(filter);
+ }
+
+ /**
+ * Add an ignoreBlank filter.
+ *
+ * @param filter a <code>TokenFilter.IgnoreBlank</code> value
+ * @since Ant 1.6
+ */
+ public void addIgnoreBlank(
+ TokenFilter.IgnoreBlank filter) {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ setChecked(false);
+ filterReaders.addElement(filter);
+ }
+
+
+ /**
+ * Makes this instance in effect a reference to another FilterChain
+ * instance.
+ *
+ * <p>You must not set another attribute or nest elements inside
+ * this element if you make it a reference.</p>
+ *
+ * @param r the reference to which this instance is associated
+ * @exception BuildException if this instance already has been configured.
+ */
+ @Override
+ public void setRefid(Reference r) throws BuildException {
+ if (!filterReaders.isEmpty()) {
+ throw tooManyAttributes();
+ }
+ super.setRefid(r);
+ }
+
+ /**
+ * Add a chainfilter filter.
+ *
+ * @param filter a <code>ChainableReader</code> value
+ * @since Ant 1.6
+ */
+
+ public void add(ChainableReader filter) {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ setChecked(false);
+ filterReaders.addElement(filter);
+ }
+
+ @Override
+ protected synchronized void dieOnCircularReference(Stack<Object> stk, Project p)
+ throws BuildException {
+ if (isChecked()) {
+ return;
+ }
+ if (isReference()) {
+ super.dieOnCircularReference(stk, p);
+ } else {
+ for (Iterator<Object> i = filterReaders.iterator(); i.hasNext();) {
+ Object o = i.next();
+ if (o instanceof DataType) {
+ pushAndInvokeCircularReferenceCheck((DataType) o, stk, p);
+ }
+ }
+ setChecked(true);
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/FilterSet.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/FilterSet.java
new file mode 100644
index 00000000..2c1f2e71
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/FilterSet.java
@@ -0,0 +1,654 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.util.FileUtils;
+import org.apache.tools.ant.util.VectorSet;
+
+/**
+ * A set of filters to be applied to something.
+ *
+ * A filter set may have begintoken and endtokens defined.
+ *
+ */
+public class FilterSet extends DataType implements Cloneable {
+
+ /**
+ * Individual filter component of filterset.
+ *
+ */
+ public static class Filter {
+ // CheckStyle:VisibilityModifier OFF - bc
+ /** Token which will be replaced in the filter operation. */
+ String token;
+
+ /** The value which will replace the token in the filtering operation. */
+ String value;
+ // CheckStyle:VisibilityModifier ON
+
+ /**
+ * Constructor for the Filter object.
+ *
+ * @param token The token which will be replaced when filtering.
+ * @param value The value which will replace the token when filtering.
+ */
+ public Filter(String token, String value) {
+ setToken(token);
+ setValue(value);
+ }
+
+ /**
+ * No-argument constructor.
+ */
+ public Filter() {
+ }
+
+ /**
+ * Sets the Token attribute of the Filter object.
+ *
+ * @param token The new Token value.
+ */
+ public void setToken(String token) {
+ this.token = token;
+ }
+
+ /**
+ * Sets the Value attribute of the Filter object.
+ *
+ * @param value The new Value value.
+ */
+ public void setValue(String value) {
+ this.value = value;
+ }
+
+ /**
+ * Gets the Token attribute of the Filter object.
+ *
+ * @return The Token value.
+ */
+ public String getToken() {
+ return token;
+ }
+
+ /**
+ * Gets the Value attribute of the Filter object.
+ *
+ * @return The Value value.
+ */
+ public String getValue() {
+ return value;
+ }
+ }
+
+ /**
+ * The filtersfile nested element.
+ *
+ */
+ public class FiltersFile {
+
+ /**
+ * Constructor for the FiltersFile object.
+ */
+ public FiltersFile() {
+ }
+
+ /**
+ * Sets the file from which filters will be read.
+ *
+ * @param file the file from which filters will be read.
+ */
+ public void setFile(File file) {
+ filtersFiles.add(file);
+ }
+ }
+
+ /**
+ * EnumeratedAttribute to set behavior WRT missing filtersfiles:
+ * "fail" (default), "warn", "ignore".
+ * @since Ant 1.7
+ */
+ public static class OnMissing extends EnumeratedAttribute {
+ private static final String[] VALUES
+ = new String[] {"fail", "warn", "ignore"};
+
+ /** Fail value */
+ public static final OnMissing FAIL = new OnMissing("fail");
+ /** Warn value */
+ public static final OnMissing WARN = new OnMissing("warn");
+ /** Ignore value */
+ public static final OnMissing IGNORE = new OnMissing("ignore");
+
+ private static final int FAIL_INDEX = 0;
+ private static final int WARN_INDEX = 1;
+ private static final int IGNORE_INDEX = 2;
+
+ /**
+ * Default constructor.
+ */
+ public OnMissing() {
+ }
+
+ /**
+ * Convenience constructor.
+ * @param value the value to set.
+ */
+ public OnMissing(String value) {
+ setValue(value);
+ }
+
+ //inherit doc
+ /** {@inheritDoc}. */
+ @Override
+ public String[] getValues() {
+ return VALUES;
+ }
+ }
+
+ /** The default token start string */
+ public static final String DEFAULT_TOKEN_START = "@";
+
+ /** The default token end string */
+ public static final String DEFAULT_TOKEN_END = "@";
+
+ private String startOfToken = DEFAULT_TOKEN_START;
+ private String endOfToken = DEFAULT_TOKEN_END;
+
+ /** Contains a list of parsed tokens */
+ private Vector<String> passedTokens;
+ /** if a duplicate token is found, this is set to true */
+ private boolean duplicateToken = false;
+
+ private boolean recurse = true;
+ private Hashtable<String, String> filterHash = null;
+ private Vector<File> filtersFiles = new Vector<File>();
+ private OnMissing onMissingFiltersFile = OnMissing.FAIL;
+ private boolean readingFiles = false;
+
+ private int recurseDepth = 0;
+
+ /**
+ * List of ordered filters and filter files.
+ */
+ private Vector<Filter> filters = new Vector<Filter>();
+
+ /**
+ * Default constructor.
+ */
+ public FilterSet() {
+ }
+
+ /**
+ * Create a Filterset from another filterset.
+ *
+ * @param filterset the filterset upon which this filterset will be based.
+ */
+ protected FilterSet(FilterSet filterset) {
+ super();
+ @SuppressWarnings("unchecked")
+ Vector<Filter> clone = (Vector<Filter>) filterset.getFilters().clone();
+ this.filters = clone;
+ }
+
+ /**
+ * Get the filters in the filter set.
+ *
+ * @return a Vector of Filter instances.
+ */
+ protected synchronized Vector<Filter> getFilters() {
+ if (isReference()) {
+ return getRef().getFilters();
+ }
+ dieOnCircularReference();
+ //silly hack to avoid stack overflow...
+ if (!readingFiles) {
+ readingFiles = true;
+ final int size = filtersFiles.size();
+ for (int i = 0; i < size; i++) {
+ readFiltersFromFile(filtersFiles.get(i));
+ }
+ filtersFiles.clear();
+ readingFiles = false;
+ }
+ return filters;
+ }
+
+ /**
+ * Get the referenced filter set.
+ *
+ * @return the filterset from the reference.
+ */
+ protected FilterSet getRef() {
+ return getCheckedRef(FilterSet.class, "filterset");
+ }
+
+ /**
+ * Gets the filter hash of the FilterSet.
+ *
+ * @return The hash of the tokens and values for quick lookup.
+ */
+ public synchronized Hashtable<String, String> getFilterHash() {
+ if (isReference()) {
+ return getRef().getFilterHash();
+ }
+ dieOnCircularReference();
+ if (filterHash == null) {
+ filterHash = new Hashtable<String, String>(getFilters().size());
+ for (Enumeration<Filter> e = getFilters().elements(); e.hasMoreElements();) {
+ Filter filter = e.nextElement();
+ filterHash.put(filter.getToken(), filter.getValue());
+ }
+ }
+ return filterHash;
+ }
+
+ /**
+ * Set the file containing the filters for this filterset.
+ *
+ * @param filtersFile sets the filter file from which to read filters
+ * for this filter set.
+ * @throws BuildException if there is an error.
+ */
+ public void setFiltersfile(File filtersFile) throws BuildException {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ filtersFiles.add(filtersFile);
+ }
+
+ /**
+ * Set the string used to id the beginning of a token.
+ *
+ * @param startOfToken The new Begintoken value.
+ */
+ public void setBeginToken(String startOfToken) {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ if (startOfToken == null || "".equals(startOfToken)) {
+ throw new BuildException("beginToken must not be empty");
+ }
+ this.startOfToken = startOfToken;
+ }
+
+ /**
+ * Get the begin token for this filterset.
+ *
+ * @return the filter set's begin token for filtering.
+ */
+ public String getBeginToken() {
+ if (isReference()) {
+ return getRef().getBeginToken();
+ }
+ return startOfToken;
+ }
+
+ /**
+ * Set the string used to id the end of a token.
+ *
+ * @param endOfToken The new Endtoken value.
+ */
+ public void setEndToken(String endOfToken) {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ if (endOfToken == null || "".equals(endOfToken)) {
+ throw new BuildException("endToken must not be empty");
+ }
+ this.endOfToken = endOfToken;
+ }
+
+ /**
+ * Get the end token for this filterset.
+ *
+ * @return the filter set's end token for replacement delimiting.
+ */
+ public String getEndToken() {
+ if (isReference()) {
+ return getRef().getEndToken();
+ }
+ return endOfToken;
+ }
+
+ /**
+ * Set whether recursive token expansion is enabled.
+ * @param recurse <code>boolean</code> whether to recurse.
+ */
+ public void setRecurse(boolean recurse) {
+ this.recurse = recurse;
+ }
+
+ /**
+ * Get whether recursive token expansion is enabled.
+ * @return <code>boolean</code> whether enabled.
+ */
+ public boolean isRecurse() {
+ return recurse;
+ }
+
+ /**
+ * Read the filters from the given file.
+ *
+ * @param filtersFile the file from which filters are read.
+ * @exception BuildException when the file cannot be read.
+ */
+ public synchronized void readFiltersFromFile(File filtersFile) throws BuildException {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ if (!filtersFile.exists()) {
+ handleMissingFile("Could not read filters from file "
+ + filtersFile + " as it doesn't exist.");
+ }
+ if (filtersFile.isFile()) {
+ log("Reading filters from " + filtersFile, Project.MSG_VERBOSE);
+ FileInputStream in = null;
+ try {
+ Properties props = new Properties();
+ in = new FileInputStream(filtersFile);
+ props.load(in);
+
+ Enumeration<?> e = props.propertyNames();
+ Vector<Filter> filts = getFilters();
+ while (e.hasMoreElements()) {
+ String strPropName = (String) e.nextElement();
+ String strValue = props.getProperty(strPropName);
+ filts.addElement(new Filter(strPropName, strValue));
+ }
+ } catch (Exception ex) {
+ throw new BuildException("Could not read filters from file: "
+ + filtersFile, ex);
+ } finally {
+ FileUtils.close(in);
+ }
+ } else {
+ handleMissingFile(
+ "Must specify a file rather than a directory in "
+ + "the filtersfile attribute:" + filtersFile);
+ }
+ filterHash = null;
+ }
+
+ /**
+ * Does replacement on the given string with token matching.
+ * This uses the defined begintoken and endtoken values which default
+ * to @ for both.
+ * This resets the passedTokens and calls iReplaceTokens to
+ * do the actual replacements.
+ *
+ * @param line The line in which to process embedded tokens.
+ * @return The input string after token replacement.
+ */
+ public synchronized String replaceTokens(String line) {
+ return iReplaceTokens(line);
+ }
+
+ /**
+ * Add a new filter.
+ *
+ * @param filter the filter to be added.
+ */
+ public synchronized void addFilter(Filter filter) {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ filters.addElement(filter);
+ filterHash = null;
+ }
+
+ /**
+ * Create a new FiltersFile.
+ *
+ * @return The filtersfile that was created.
+ */
+ public FiltersFile createFiltersfile() {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ return new FiltersFile();
+ }
+
+ /**
+ * Add a new filter made from the given token and value.
+ *
+ * @param token The token for the new filter.
+ * @param value The value for the new filter.
+ */
+ public synchronized void addFilter(String token, String value) {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ addFilter(new Filter(token, value));
+ }
+
+ /**
+ * Add a Filterset to this filter set.
+ *
+ * @param filterSet the filterset to be added to this filterset
+ */
+ public synchronized void addConfiguredFilterSet(FilterSet filterSet) {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ for (Filter filter : filterSet.getFilters()) {
+ addFilter(filter);
+ }
+ }
+
+ /**
+ * Adds the properties provided by the specified PropertySet to this filterset.
+ *
+ * @param propertySet the propertyset to be added to this propertyset
+ */
+ public synchronized void addConfiguredPropertySet(PropertySet propertySet) {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ Properties p = propertySet.getProperties();
+ Set<Map.Entry<Object,Object>> entries = p.entrySet();
+ for (Map.Entry<Object, Object> entry : entries) {
+ addFilter(new Filter(String.valueOf(entry.getKey()),
+ String.valueOf(entry.getValue())));
+ }
+ }
+
+ /**
+ * Test to see if this filter set has filters.
+ *
+ * @return Return true if there are filters in this set.
+ */
+ public synchronized boolean hasFilters() {
+ return getFilters().size() > 0;
+ }
+
+ /**
+ * Clone the filterset.
+ *
+ * @return a deep clone of this filterset.
+ *
+ * @throws BuildException if the clone cannot be performed.
+ */
+ @Override
+ public synchronized Object clone() throws BuildException {
+ if (isReference()) {
+ return getRef().clone();
+ }
+ try {
+ FilterSet fs = (FilterSet) super.clone();
+ @SuppressWarnings("unchecked")
+ Vector<Filter> clonedFilters = (Vector<Filter>) getFilters().clone();
+ fs.filters = clonedFilters;
+ fs.setProject(getProject());
+ return fs;
+ } catch (CloneNotSupportedException e) {
+ throw new BuildException(e);
+ }
+ }
+
+ /**
+ * Set the behavior WRT missing filtersfiles.
+ * @param onMissingFiltersFile the OnMissing describing the behavior.
+ */
+ public void setOnMissingFiltersFile(OnMissing onMissingFiltersFile) {
+ this.onMissingFiltersFile = onMissingFiltersFile;
+ }
+
+ /**
+ * Get the onMissingFiltersFile setting.
+ * @return the OnMissing instance.
+ */
+ public OnMissing getOnMissingFiltersFile() {
+ return onMissingFiltersFile;
+ }
+
+ /**
+ * Does replacement on the given string with token matching.
+ * This uses the defined begintoken and endtoken values which default
+ * to @ for both.
+ *
+ * @param line The line to process the tokens in.
+ * @return The string with the tokens replaced.
+ */
+ private synchronized String iReplaceTokens(String line) {
+ String beginToken = getBeginToken();
+ String endToken = getEndToken();
+ int index = line.indexOf(beginToken);
+
+ if (index > -1) {
+ Hashtable<String, String> tokens = getFilterHash();
+ try {
+ StringBuilder b = new StringBuilder();
+ int i = 0;
+ String token = null;
+ String value = null;
+
+ while (index > -1) {
+ //can't have zero-length token
+ int endIndex = line.indexOf(endToken,
+ index + beginToken.length() + 1);
+ if (endIndex == -1) {
+ break;
+ }
+ token
+ = line.substring(index + beginToken.length(), endIndex);
+ b.append(line.substring(i, index));
+ if (tokens.containsKey(token)) {
+ value = tokens.get(token);
+ if (recurse && !value.equals(token)) {
+ // we have another token, let's parse it.
+ value = replaceTokens(value, token);
+ }
+ log("Replacing: " + beginToken + token + endToken
+ + " -> " + value, Project.MSG_VERBOSE);
+ b.append(value);
+ i = index + beginToken.length() + token.length()
+ + endToken.length();
+ } else {
+ // just append first character of beginToken
+ // and search further
+ // we can't skip the complete beginToken since
+ // it may contain the start of another
+ // candidate begin token (Bugzilla 45094)
+ b.append(beginToken.charAt(0));
+ i = index + 1;
+ }
+ index = line.indexOf(beginToken, i);
+ }
+
+ b.append(line.substring(i));
+ return b.toString();
+ } catch (StringIndexOutOfBoundsException e) {
+ return line;
+ }
+ } else {
+ return line;
+ }
+ }
+
+ /**
+ * This parses tokens which point to tokens.
+ * It also maintains a list of currently used tokens, so we cannot
+ * get into an infinite loop.
+ * @param line the value / token to parse.
+ * @param parent the parent token (= the token it was parsed from).
+ */
+ private synchronized String replaceTokens(String line, String parent)
+ throws BuildException {
+ String beginToken = getBeginToken();
+ String endToken = getEndToken();
+ if (recurseDepth == 0) {
+ passedTokens = new VectorSet<String>();
+ }
+ recurseDepth++;
+ if (passedTokens.contains(parent) && !duplicateToken) {
+ duplicateToken = true;
+ System.out.println(
+ "Infinite loop in tokens. Currently known tokens : "
+ + passedTokens.toString() + "\nProblem token : " + beginToken
+ + parent + endToken + " called from " + beginToken
+ + passedTokens.lastElement().toString() + endToken);
+ recurseDepth--;
+ return parent;
+ }
+ passedTokens.addElement(parent);
+ String value = iReplaceTokens(line);
+ if (value.indexOf(beginToken) == -1 && !duplicateToken
+ && recurseDepth == 1) {
+ passedTokens = null;
+ } else if (duplicateToken) {
+ // should always be the case...
+ if (passedTokens.size() > 0) {
+ value = passedTokens.remove(passedTokens.size() - 1);
+ if (passedTokens.size() == 0) {
+ value = beginToken + value + endToken;
+ duplicateToken = false;
+ }
+ }
+ } else if (passedTokens.size() > 0) {
+ // remove last seen token when crawling out of recursion
+ passedTokens.remove(passedTokens.size() - 1);
+ }
+ recurseDepth--;
+ return value;
+ }
+
+ private void handleMissingFile(String message) {
+ switch (onMissingFiltersFile.getIndex()) {
+ case OnMissing.IGNORE_INDEX:
+ return;
+ case OnMissing.FAIL_INDEX:
+ throw new BuildException(message);
+ case OnMissing.WARN_INDEX:
+ log(message, Project.MSG_WARN);
+ return;
+ default:
+ throw new BuildException("Invalid value for onMissingFiltersFile");
+ }
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/FilterSetCollection.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/FilterSetCollection.java
new file mode 100644
index 00000000..8afb9631
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/FilterSetCollection.java
@@ -0,0 +1,88 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+/**
+ * A FilterSetCollection is a collection of filtersets each of which may have
+ * a different start/end token settings.
+ *
+ */
+public class FilterSetCollection {
+
+ private List<FilterSet> filterSets = new ArrayList<FilterSet>();
+
+ /**
+ * Constructor for a FilterSetCollection.
+ */
+ public FilterSetCollection() {
+ }
+
+ /**
+ * Constructor for a FilterSetCollection.
+ * @param filterSet a filterset to start the collection with
+ */
+ public FilterSetCollection(FilterSet filterSet) {
+ addFilterSet(filterSet);
+ }
+
+
+ /**
+ * Add a filterset to the collection.
+ *
+ * @param filterSet a <code>FilterSet</code> value
+ */
+ public void addFilterSet(FilterSet filterSet) {
+ filterSets.add(filterSet);
+ }
+
+ /**
+ * Does replacement on the given string with token matching.
+ * This uses the defined begintoken and endtoken values which default to @ for both.
+ *
+ * @param line The line to process the tokens in.
+ * @return The string with the tokens replaced.
+ */
+ public String replaceTokens(String line) {
+ String replacedLine = line;
+ for (FilterSet filterSet : filterSets) {
+ replacedLine = filterSet.replaceTokens(replacedLine);
+ }
+ return replacedLine;
+ }
+
+ /**
+ * Test to see if this filter set it empty.
+ *
+ * @return Return true if there are filter in this set otherwise false.
+ */
+ public boolean hasFilters() {
+ for (FilterSet filterSet : filterSets) {
+ if (filterSet.hasFilters()) {
+ return true;
+ }
+ }
+ return false;
+ }
+}
+
+
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/FlexInteger.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/FlexInteger.java
new file mode 100644
index 00000000..d757429f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/FlexInteger.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types;
+
+/**
+ * Helper class which can be used for Ant task attribute setter methods to allow
+ * the build file to specify an integer in either decimal, octal, or hexadecimal
+ * format.
+ *
+ * @see java.lang.Integer#decode(String)
+ */
+public class FlexInteger {
+ private Integer value;
+
+ /**
+ * Constructor used by Ant's introspection mechanism for attribute population
+ * @param value the value to decode
+ */
+ public FlexInteger(String value) {
+ this.value = Integer.decode(value);
+ }
+
+ /**
+ * Returns the decimal integer value
+ * @return the integer value
+ */
+ public int intValue() {
+ return value.intValue();
+ }
+
+ /**
+ * Overridden method to return the decimal value for display
+ * @return a string version of the integer
+ */
+ public String toString() {
+ return value.toString();
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/LogLevel.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/LogLevel.java
new file mode 100644
index 00000000..a02b948e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/LogLevel.java
@@ -0,0 +1,87 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types;
+
+import org.apache.tools.ant.Project;
+
+/**
+ * The enumerated values for Ant's log level.
+ */
+public class LogLevel extends EnumeratedAttribute {
+
+ /** ERR loglevel constant. */
+ public static final LogLevel ERR = new LogLevel("error");
+
+ /** WARN loglevel constant. */
+ public static final LogLevel WARN = new LogLevel("warn");
+
+ /** INFO loglevel constant. */
+ public static final LogLevel INFO = new LogLevel("info");
+
+ /** VERBOSE loglevel constant. */
+ public static final LogLevel VERBOSE = new LogLevel("verbose");
+
+ /** DEBUG loglevel constant. */
+ public static final LogLevel DEBUG = new LogLevel("debug");
+
+ /**
+ * Public constructor.
+ */
+ public LogLevel() {
+ }
+
+ private LogLevel(String value) {
+ this();
+ setValue(value);
+ }
+
+ /**
+ * @see EnumeratedAttribute#getValues
+ * @return the strings allowed for the level attribute
+ */
+ public String[] getValues() {
+ return new String[] {
+ "error",
+ "warn",
+ "warning",
+ "info",
+ "verbose",
+ "debug"};
+ }
+
+ /**
+ * mapping of enumerated values to log levels
+ */
+ private static int[] levels = {
+ Project.MSG_ERR,
+ Project.MSG_WARN,
+ Project.MSG_WARN,
+ Project.MSG_INFO,
+ Project.MSG_VERBOSE,
+ Project.MSG_DEBUG
+ };
+
+ /**
+ * get the level of the echo of the current value
+ * @return the level
+ */
+ public int getLevel() {
+ return levels[getIndex()];
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/Mapper.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/Mapper.java
new file mode 100644
index 00000000..941e8dd8
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/Mapper.java
@@ -0,0 +1,322 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types;
+
+import java.util.Properties;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.util.CompositeMapper;
+import org.apache.tools.ant.util.ContainerMapper;
+import org.apache.tools.ant.util.FileNameMapper;
+
+/**
+ * Element to define a FileNameMapper.
+ *
+ */
+public class Mapper extends DataType implements Cloneable {
+ // CheckStyle:VisibilityModifier OFF - bc
+
+ protected MapperType type = null;
+ protected String classname = null;
+ protected Path classpath = null;
+ protected String from = null;
+ protected String to = null;
+
+ // CheckStyle:VisibilityModifier ON
+
+ private ContainerMapper container = null;
+
+ /**
+ * Construct a new <code>Mapper</code> element.
+ * @param p the owning Ant <code>Project</code>.
+ */
+ public Mapper(Project p) {
+ setProject(p);
+ }
+
+ /**
+ * Set the type of <code>FileNameMapper</code> to use.
+ * @param type the <code>MapperType</code> enumerated attribute.
+ */
+ public void setType(MapperType type) {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ this.type = type;
+ }
+
+ /**
+ * Cannot mix add and addconfigured in same type, so
+ * provide this to override the add method.
+ * @param fileNameMapper the <code>FileNameMapper</code> to add.
+ */
+ public void addConfigured(FileNameMapper fileNameMapper) {
+ add(fileNameMapper);
+ }
+
+ /**
+ * Add a nested <code>FileNameMapper</code>.
+ * @param fileNameMapper the <code>FileNameMapper</code> to add.
+ */
+ public void add(FileNameMapper fileNameMapper) {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ if (container == null) {
+ if (type == null && classname == null) {
+ container = new CompositeMapper();
+ } else {
+ FileNameMapper m = getImplementation();
+ if (m instanceof ContainerMapper) {
+ container = (ContainerMapper) m;
+ } else {
+ throw new BuildException(String.valueOf(m)
+ + " mapper implementation does not support nested mappers!");
+ }
+ }
+ }
+ container.add(fileNameMapper);
+ setChecked(false);
+ }
+
+ /**
+ * Add a Mapper
+ * @param mapper the mapper to add
+ */
+ public void addConfiguredMapper(Mapper mapper) {
+ add(mapper.getImplementation());
+ }
+
+ /**
+ * Set the class name of the FileNameMapper to use.
+ * @param classname the name of the class
+ */
+ public void setClassname(String classname) {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ this.classname = classname;
+ }
+
+ /**
+ * Set the classpath to load the FileNameMapper through (attribute).
+ * @param classpath the classpath
+ */
+ public void setClasspath(Path classpath) {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ if (this.classpath == null) {
+ this.classpath = classpath;
+ } else {
+ this.classpath.append(classpath);
+ }
+ }
+
+ /**
+ * Set the classpath to load the FileNameMapper through (nested element).
+ * @return a path object to be configured
+ */
+ public Path createClasspath() {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ if (this.classpath == null) {
+ this.classpath = new Path(getProject());
+ }
+ setChecked(false);
+ return this.classpath.createPath();
+ }
+
+ /**
+ * Set the classpath to load the FileNameMapper through via
+ * reference (attribute).
+ * @param ref the reference to the FileNameMapper
+ */
+ public void setClasspathRef(Reference ref) {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ createClasspath().setRefid(ref);
+ }
+
+ /**
+ * Set the argument to FileNameMapper.setFrom
+ * @param from the from attribute to pass to the FileNameMapper
+ */
+ public void setFrom(String from) {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ this.from = from;
+ }
+
+ /**
+ * Set the argument to FileNameMapper.setTo
+ * @param to the to attribute to pass to the FileNameMapper
+ */
+ public void setTo(String to) {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ this.to = to;
+ }
+
+ /**
+ * Make this Mapper instance a reference to another Mapper.
+ *
+ * <p>You must not set any other attribute if you make it a
+ * reference.</p>
+ * @param r the reference to another mapper
+ * @throws BuildException if other attributes are set
+ */
+ public void setRefid(Reference r) throws BuildException {
+ if (type != null || from != null || to != null) {
+ throw tooManyAttributes();
+ }
+ super.setRefid(r);
+ }
+
+ /**
+ * Returns a fully configured FileNameMapper implementation.
+ * @return a FileNameMapper object to be configured
+ * @throws BuildException on error
+ */
+ public FileNameMapper getImplementation() throws BuildException {
+ if (isReference()) {
+ dieOnCircularReference();
+ Reference r = getRefid();
+ Object o = r.getReferencedObject(getProject());
+ if (o instanceof FileNameMapper) {
+ return (FileNameMapper) o;
+ }
+ if (o instanceof Mapper) {
+ return ((Mapper) o).getImplementation();
+ }
+ String od = o == null ? "null" : o.getClass().getName();
+ throw new BuildException(od + " at reference '"
+ + r.getRefId() + "' is not a valid mapper reference.");
+ }
+
+ if (type == null && classname == null && container == null) {
+ throw new BuildException(
+ "nested mapper or "
+ + "one of the attributes type or classname is required");
+ }
+
+ if (container != null) {
+ return container;
+ }
+
+ if (type != null && classname != null) {
+ throw new BuildException(
+ "must not specify both type and classname attribute");
+ }
+
+ try {
+ FileNameMapper m = getImplementationClass().newInstance();
+ final Project p = getProject();
+ if (p != null) {
+ p.setProjectReference(m);
+ }
+ m.setFrom(from);
+ m.setTo(to);
+
+ return m;
+ } catch (BuildException be) {
+ throw be;
+ } catch (Throwable t) {
+ throw new BuildException(t);
+ }
+ }
+
+ /**
+ * Gets the Class object associated with the mapper implementation.
+ * @return <code>Class</code>.
+ * @throws ClassNotFoundException if the class cannot be found
+ */
+ protected Class<? extends FileNameMapper> getImplementationClass() throws ClassNotFoundException {
+
+ String cName = this.classname;
+ if (type != null) {
+ cName = type.getImplementation();
+ }
+
+ ClassLoader loader = (classpath == null)
+ ? getClass().getClassLoader()
+ // Memory leak in line below
+ : getProject().createClassLoader(classpath);
+
+ return Class.forName(cName, true, loader).asSubclass(FileNameMapper.class);
+ }
+
+ /**
+ * Performs the check for circular references and returns the
+ * referenced Mapper.
+ * @deprecated since Ant 1.7.1 because a mapper might ref a
+ * FileNameMapper implementation directly.
+ * @return the referenced Mapper
+ */
+ protected Mapper getRef() {
+ return getCheckedRef(Mapper.class, getDataTypeName());
+ }
+
+ /**
+ * Class as Argument to FileNameMapper.setType.
+ */
+ public static class MapperType extends EnumeratedAttribute {
+ private Properties implementations;
+
+ /** Constructor for the MapperType enumeration */
+ public MapperType() {
+ implementations = new Properties();
+ implementations.put("identity",
+ "org.apache.tools.ant.util.IdentityMapper");
+ implementations.put("flatten",
+ "org.apache.tools.ant.util.FlatFileNameMapper");
+ implementations.put("glob",
+ "org.apache.tools.ant.util.GlobPatternMapper");
+ implementations.put("merge",
+ "org.apache.tools.ant.util.MergingMapper");
+ implementations.put("regexp",
+ "org.apache.tools.ant.util.RegexpPatternMapper");
+ implementations.put("package",
+ "org.apache.tools.ant.util.PackageNameMapper");
+ implementations.put("unpackage",
+ "org.apache.tools.ant.util.UnPackageNameMapper");
+ }
+
+ /**
+ * @return the filenamemapper names
+ */
+ public String[] getValues() {
+ return new String[] {"identity", "flatten", "glob",
+ "merge", "regexp", "package", "unpackage"};
+ }
+
+ /**
+ * @return the classname for the filenamemapper name
+ */
+ public String getImplementation() {
+ return implementations.getProperty(getValue());
+ }
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/Parameter.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/Parameter.java
new file mode 100644
index 00000000..6c16d2d9
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/Parameter.java
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types;
+
+/**
+ * A parameter is composed of a name, type and value.
+ *
+ */
+public final class Parameter {
+ private String name = null;
+ private String type = null;
+ private String value = null;
+
+ /**
+ * Set the name attribute.
+ *
+ * @param name a <code>String</code> value
+ */
+ public void setName(final String name) {
+ this.name = name;
+ }
+
+ /**
+ * Set the type attribute.
+ *
+ * @param type a <code>String</code> value
+ */
+ public void setType(final String type) {
+ this.type = type;
+ }
+
+ /**
+ * Set the value attribute.
+ *
+ * @param value a <code>String</code> value
+ */
+ public void setValue(final String value) {
+ this.value = value;
+ }
+
+ /**
+ * Get the name attribute.
+ *
+ * @return a <code>String</code> value
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Get the type attribute.
+ *
+ * @return a <code>String</code> value
+ */
+ public String getType() {
+ return type;
+ }
+
+ /**
+ * Get the value attribute.
+ *
+ * @return a <code>String</code> value
+ */
+ public String getValue() {
+ return value;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/Parameterizable.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/Parameterizable.java
new file mode 100644
index 00000000..7945a9a6
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/Parameterizable.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types;
+
+/**
+ * Parameterizable objects take generic key value pairs.
+ *
+ */
+public interface Parameterizable {
+ /**
+ * Set the parameters
+ *
+ * @param parameters an array of name/type/value parameters.
+ */
+ void setParameters(Parameter[] parameters);
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/Path.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/Path.java
new file mode 100644
index 00000000..db6f5e9f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/Path.java
@@ -0,0 +1,775 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types;
+
+import java.io.File;
+import java.lang.reflect.Method;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.Locale;
+import java.util.Stack;
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.MagicNames;
+import org.apache.tools.ant.PathTokenizer;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.resources.FileResourceIterator;
+import org.apache.tools.ant.types.resources.Union;
+import org.apache.tools.ant.util.FileUtils;
+import org.apache.tools.ant.util.JavaEnvUtils;
+
+/**
+ * This object represents a path as used by CLASSPATH or PATH
+ * environment variable. A path might also be described as a collection
+ * of unique filesystem resources.
+ * <p>
+ * <code>
+ * &lt;sometask&gt;<br>
+ * &nbsp;&nbsp;&lt;somepath&gt;<br>
+ * &nbsp;&nbsp;&nbsp;&nbsp;&lt;pathelement location="/path/to/file.jar" /&gt;<br>
+ * &nbsp;&nbsp;&nbsp;&nbsp;&lt;pathelement
+ * path="/path/to/file2.jar:/path/to/class2;/path/to/class3" /&gt;
+ * <br>
+ * &nbsp;&nbsp;&nbsp;&nbsp;&lt;pathelement location="/path/to/file3.jar" /&gt;<br>
+ * &nbsp;&nbsp;&nbsp;&nbsp;&lt;pathelement location="/path/to/file4.jar" /&gt;<br>
+ * &nbsp;&nbsp;&lt;/somepath&gt;<br>
+ * &lt;/sometask&gt;<br>
+ * </code>
+ * <p>
+ * The object implementation <code>sometask</code> must provide a method called
+ * <code>createSomepath</code> which returns an instance of <code>Path</code>.
+ * Nested path definitions are handled by the Path object and must be labeled
+ * <code>pathelement</code>.<p>
+ *
+ * The path element takes a parameter <code>path</code> which will be parsed
+ * and split into single elements. It will usually be used
+ * to define a path from an environment variable.
+ */
+
+public class Path extends DataType implements Cloneable, ResourceCollection {
+ // CheckStyle:VisibilityModifier OFF - bc
+
+ /** The system classpath as a Path object */
+ public static Path systemClasspath =
+ new Path(null, System.getProperty("java.class.path"));
+
+
+ /**
+ * The system bootclasspath as a Path object.
+ *
+ * @since Ant 1.6.2
+ */
+ public static Path systemBootClasspath =
+ new Path(null, System.getProperty("sun.boot.class.path"));
+
+ // CheckStyle:VisibilityModifier OFF - bc
+
+ /**
+ * Helper class, holds the nested <code>&lt;pathelement&gt;</code> values.
+ */
+ public class PathElement implements ResourceCollection {
+ private String[] parts;
+
+ /**
+ * Set the location.
+ *
+ * @param loc a <code>File</code> value
+ */
+ public void setLocation(File loc) {
+ parts = new String[] {translateFile(loc.getAbsolutePath())};
+ }
+
+ /**
+ * Set the path.
+ *
+ * @param path a <code>String</code> value
+ */
+ public void setPath(String path) {
+ parts = Path.translatePath(getProject(), path);
+ }
+
+ /**
+ * Return the converted pathelements.
+ *
+ * @return a <code>String[]</code> value
+ */
+ public String[] getParts() {
+ return parts;
+ }
+
+ /**
+ * Create an iterator.
+ * @return an iterator.
+ */
+ public Iterator<Resource> iterator() {
+ return new FileResourceIterator(getProject(), null, parts);
+ }
+
+ /**
+ * Check if this resource is only for filesystems.
+ * @return true.
+ */
+ public boolean isFilesystemOnly() {
+ return true;
+ }
+
+ /**
+ * Get the number of resources.
+ * @return the number of parts.
+ */
+ public int size() {
+ return parts == null ? 0 : parts.length;
+ }
+
+ }
+
+ private Boolean preserveBC;
+
+ private Union union = null;
+ private boolean cache = false;
+
+ /**
+ * Invoked by IntrospectionHelper for <code>setXXX(Path p)</code>
+ * attribute setters.
+ * @param p the <code>Project</code> for this path.
+ * @param path the <code>String</code> path definition.
+ */
+ public Path(Project p, String path) {
+ this(p);
+ createPathElement().setPath(path);
+ }
+
+ /**
+ * Construct an empty <code>Path</code>.
+ * @param project the <code>Project</code> for this path.
+ */
+ public Path(Project project) {
+ setProject(project);
+ }
+
+ /**
+ * Adds a element definition to the path.
+ * @param location the location of the element to add (must not be
+ * <code>null</code> nor empty.
+ * @throws BuildException on error
+ */
+ public void setLocation(File location) throws BuildException {
+ checkAttributesAllowed();
+ createPathElement().setLocation(location);
+ }
+
+ /**
+ * Parses a path definition and creates single PathElements.
+ * @param path the <code>String</code> path definition.
+ * @throws BuildException on error
+ */
+ public void setPath(String path) throws BuildException {
+ checkAttributesAllowed();
+ createPathElement().setPath(path);
+ }
+
+ /**
+ * Makes this instance in effect a reference to another Path instance.
+ *
+ * <p>You must not set another attribute or nest elements inside
+ * this element if you make it a reference.</p>
+ * @param r the reference to another Path
+ * @throws BuildException on error
+ */
+ public void setRefid(Reference r) throws BuildException {
+ if (union != null) {
+ throw tooManyAttributes();
+ }
+ super.setRefid(r);
+ }
+
+ /**
+ * Creates the nested <code>&lt;pathelement&gt;</code> element.
+ * @return the <code>PathElement</code> to be configured
+ * @throws BuildException on error
+ */
+ public PathElement createPathElement() throws BuildException {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ PathElement pe = new PathElement();
+ add(pe);
+ return pe;
+ }
+
+ /**
+ * Adds a nested <code>&lt;fileset&gt;</code> element.
+ * @param fs a <code>FileSet</code> to be added to the path
+ * @throws BuildException on error
+ */
+ public void addFileset(FileSet fs) throws BuildException {
+ if (fs.getProject() == null) {
+ fs.setProject(getProject());
+ }
+ add(fs);
+ }
+
+ /**
+ * Adds a nested <code>&lt;filelist&gt;</code> element.
+ * @param fl a <code>FileList</code> to be added to the path
+ * @throws BuildException on error
+ */
+ public void addFilelist(FileList fl) throws BuildException {
+ if (fl.getProject() == null) {
+ fl.setProject(getProject());
+ }
+ add(fl);
+ }
+
+ /**
+ * Adds a nested <code>&lt;dirset&gt;</code> element.
+ * @param dset a <code>DirSet</code> to be added to the path
+ * @throws BuildException on error
+ */
+ public void addDirset(DirSet dset) throws BuildException {
+ if (dset.getProject() == null) {
+ dset.setProject(getProject());
+ }
+ add(dset);
+ }
+
+ /**
+ * Adds a nested path
+ * @param path a <code>Path</code> to be added to the path
+ * @throws BuildException on error
+ * @since Ant 1.6
+ */
+ public void add(Path path) throws BuildException {
+ if (path == this) {
+ throw circularReference();
+ }
+ if (path.getProject() == null) {
+ path.setProject(getProject());
+ }
+ add((ResourceCollection) path);
+ }
+
+ /**
+ * Add a nested <code>ResourceCollection</code>.
+ * @param c the ResourceCollection to add.
+ * @since Ant 1.7
+ */
+ public void add(ResourceCollection c) {
+ checkChildrenAllowed();
+ if (c == null) {
+ return;
+ }
+ if (union == null) {
+ union = new Union();
+ union.setProject(getProject());
+ union.setCache(cache);
+ }
+ union.add(c);
+ setChecked(false);
+ }
+
+ /**
+ * Creates a nested <code>&lt;path&gt;</code> element.
+ * @return a <code>Path</code> to be configured
+ * @throws BuildException on error
+ */
+ public Path createPath() throws BuildException {
+ Path p = new Path(getProject());
+ add(p);
+ return p;
+ }
+
+ /**
+ * Append the contents of the other Path instance to this.
+ * @param other a <code>Path</code> to be added to the path
+ */
+ public void append(Path other) {
+ if (other == null) {
+ return;
+ }
+ add(other);
+ }
+
+ /**
+ * Adds the components on the given path which exist to this
+ * Path. Components that don't exist aren't added.
+ *
+ * @param source - source path whose components are examined for existence
+ */
+ public void addExisting(Path source) {
+ addExisting(source, false);
+ }
+
+ /**
+ * Same as addExisting, but support classpath behavior if tryUserDir
+ * is true. Classpaths are relative to user dir, not the project base.
+ * That used to break jspc test
+ *
+ * @param source the source path
+ * @param tryUserDir if true try the user directory if the file is not present
+ */
+ public void addExisting(Path source, boolean tryUserDir) {
+ String[] list = source.list();
+ File userDir = (tryUserDir) ? new File(System.getProperty("user.dir"))
+ : null;
+
+ for (int i = 0; i < list.length; i++) {
+ File f = resolveFile(getProject(), list[i]);
+
+ // probably not the best choice, but it solves the problem of
+ // relative paths in CLASSPATH
+ if (tryUserDir && !f.exists()) {
+ f = new File(userDir, list[i]);
+ }
+ if (f.exists()) {
+ setLocation(f);
+ } else if (f.getParentFile() != null && f.getParentFile().exists()
+ && containsWildcards(f.getName())) {
+ setLocation(f);
+ log("adding " + f + " which contains wildcards and may not"
+ + " do what you intend it to do depending on your OS or"
+ + " version of Java", Project.MSG_VERBOSE);
+ } else {
+ log("dropping " + f + " from path as it doesn't exist",
+ Project.MSG_VERBOSE);
+ }
+ }
+ }
+
+ /**
+ * Whether to cache the current path.
+ * @since Ant 1.8.0
+ */
+ public void setCache(boolean b) {
+ checkAttributesAllowed();
+ cache = b;
+ if (union != null) {
+ union.setCache(b);
+ }
+ }
+
+ /**
+ * Returns all path elements defined by this and nested path objects.
+ * @return list of path elements.
+ */
+ public String[] list() {
+ if (isReference()) {
+ return ((Path) getCheckedRef()).list();
+ }
+ return assertFilesystemOnly(union) == null
+ ? new String[0] : union.list();
+ }
+
+ /**
+ * Returns a textual representation of the path, which can be used as
+ * CLASSPATH or PATH environment variable definition.
+ * @return a textual representation of the path.
+ */
+ public String toString() {
+ return isReference() ? getCheckedRef().toString()
+ : union == null ? "" : union.toString();
+ }
+
+ /**
+ * Splits a PATH (with : or ; as separators) into its parts.
+ * @param project the project to use
+ * @param source a <code>String</code> value
+ * @return an array of strings, one for each path element
+ */
+ public static String[] translatePath(Project project, String source) {
+ final Vector<String> result = new Vector<String>();
+ if (source == null) {
+ return new String[0];
+ }
+ PathTokenizer tok = new PathTokenizer(source);
+ StringBuffer element = new StringBuffer();
+ while (tok.hasMoreTokens()) {
+ String pathElement = tok.nextToken();
+ try {
+ element.append(resolveFile(project, pathElement).getPath());
+ } catch (BuildException e) {
+ project.log("Dropping path element " + pathElement
+ + " as it is not valid relative to the project",
+ Project.MSG_VERBOSE);
+ }
+ for (int i = 0; i < element.length(); i++) {
+ translateFileSep(element, i);
+ }
+ result.addElement(element.toString());
+ element = new StringBuffer();
+ }
+ return result.toArray(new String[result.size()]);
+ }
+
+ /**
+ * Returns its argument with all file separator characters
+ * replaced so that they match the local OS conventions.
+ * @param source the path to convert
+ * @return the converted path
+ */
+ public static String translateFile(String source) {
+ if (source == null) {
+ return "";
+ }
+ final StringBuffer result = new StringBuffer(source);
+ for (int i = 0; i < result.length(); i++) {
+ translateFileSep(result, i);
+ }
+ return result.toString();
+ }
+
+ /**
+ * Translates occurrences at a position of / or \ to correct separator of the
+ * current platform and returns whether it had to do a
+ * replacement.
+ * @param buffer a buffer containing a string
+ * @param pos the position in the string buffer to convert
+ * @return true if the character was a / or \
+ */
+ protected static boolean translateFileSep(StringBuffer buffer, int pos) {
+ if (buffer.charAt(pos) == '/' || buffer.charAt(pos) == '\\') {
+ buffer.setCharAt(pos, File.separatorChar);
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Fulfill the ResourceCollection contract.
+ * @return number of elements as int.
+ */
+ public synchronized int size() {
+ if (isReference()) {
+ return ((Path) getCheckedRef()).size();
+ }
+ dieOnCircularReference();
+ return union == null ? 0 : assertFilesystemOnly(union).size();
+ }
+
+ /**
+ * Clone this Path.
+ * @return Path with shallowly cloned Resource children.
+ */
+ public Object clone() {
+ try {
+ Path result = (Path) super.clone();
+ result.union = union == null ? union : (Union) union.clone();
+ return result;
+ } catch (CloneNotSupportedException e) {
+ throw new BuildException(e);
+ }
+ }
+
+ /**
+ * Overrides the version of DataType to recurse on all DataType
+ * child elements that may have been added.
+ * @param stk the stack of data types to use (recursively).
+ * @param p the project to use to dereference the references.
+ * @throws BuildException on error.
+ */
+ protected synchronized void dieOnCircularReference(Stack<Object> stk, Project p)
+ throws BuildException {
+ if (isChecked()) {
+ return;
+ }
+ if (isReference()) {
+ super.dieOnCircularReference(stk, p);
+ } else {
+ if (union != null) {
+ pushAndInvokeCircularReferenceCheck(union, stk, p);
+ }
+ setChecked(true);
+ }
+ }
+
+ /**
+ * Resolve a filename with Project's help - if we know one that is.
+ */
+ private static File resolveFile(Project project, String relativeName) {
+ return FileUtils.getFileUtils().resolveFile(
+ (project == null) ? null : project.getBaseDir(), relativeName);
+ }
+
+ /**
+ * Concatenates the system class path in the order specified by
+ * the ${build.sysclasspath} property - using &quot;last&quot; as
+ * default value.
+ * @return the concatenated path
+ */
+ public Path concatSystemClasspath() {
+ return concatSystemClasspath("last");
+ }
+
+ /**
+ * Concatenates the system class path in the order specified by
+ * the ${build.sysclasspath} property - using the supplied value
+ * if ${build.sysclasspath} has not been set.
+ * @param defValue the order ("first", "last", "only")
+ * @return the concatenated path
+ */
+ public Path concatSystemClasspath(String defValue) {
+ return concatSpecialPath(defValue, Path.systemClasspath);
+ }
+
+ /**
+ * Concatenates the system boot class path in the order specified
+ * by the ${build.sysclasspath} property - using the supplied
+ * value if ${build.sysclasspath} has not been set.
+ * @param defValue the order ("first", "last", "only")
+ * @return the concatenated path
+ */
+ public Path concatSystemBootClasspath(String defValue) {
+ return concatSpecialPath(defValue, Path.systemBootClasspath);
+ }
+
+ /**
+ * Concatenates a class path in the order specified by the
+ * ${build.sysclasspath} property - using the supplied value if
+ * ${build.sysclasspath} has not been set.
+ */
+ private Path concatSpecialPath(String defValue, Path p) {
+ Path result = new Path(getProject());
+
+ String order = defValue;
+ String o = getProject() != null
+ ? getProject().getProperty(MagicNames.BUILD_SYSCLASSPATH)
+ : System.getProperty(MagicNames.BUILD_SYSCLASSPATH);
+ if (o != null) {
+ order = o;
+ }
+ if (order.equals("only")) {
+ // only: the developer knows what (s)he is doing
+ result.addExisting(p, true);
+
+ } else if (order.equals("first")) {
+ // first: developer could use a little help
+ result.addExisting(p, true);
+ result.addExisting(this);
+
+ } else if (order.equals("ignore")) {
+ // ignore: don't trust anyone
+ result.addExisting(this);
+
+ } else {
+ // last: don't trust the developer
+ if (!order.equals("last")) {
+ log("invalid value for " + MagicNames.BUILD_SYSCLASSPATH
+ + ": " + order,
+ Project.MSG_WARN);
+ }
+ result.addExisting(this);
+ result.addExisting(p, true);
+ }
+ return result;
+ }
+
+ /**
+ * Add the Java Runtime classes to this Path instance.
+ */
+ public void addJavaRuntime() {
+ if (JavaEnvUtils.isKaffe()) {
+ // newer versions of Kaffe (1.1.1+) won't have this,
+ // but this will be sorted by FileSet anyway.
+ File kaffeShare = new File(System.getProperty("java.home")
+ + File.separator + "share"
+ + File.separator + "kaffe");
+ if (kaffeShare.isDirectory()) {
+ FileSet kaffeJarFiles = new FileSet();
+ kaffeJarFiles.setDir(kaffeShare);
+ kaffeJarFiles.setIncludes("*.jar");
+ addFileset(kaffeJarFiles);
+ }
+ } else if ("GNU libgcj".equals(System.getProperty("java.vm.name"))) {
+ addExisting(systemBootClasspath);
+ }
+
+ if (System.getProperty("java.vendor").toLowerCase(Locale.ENGLISH).indexOf("microsoft") >= 0) {
+ // TODO is this code still necessary? is there any 1.2+ port?
+ // Pull in *.zip from packages directory
+ FileSet msZipFiles = new FileSet();
+ msZipFiles.setDir(new File(System.getProperty("java.home")
+ + File.separator + "Packages"));
+ msZipFiles.setIncludes("*.ZIP");
+ addFileset(msZipFiles);
+ } else {
+ // JDK 1.2+ seems to set java.home to the JRE directory.
+ addExisting(new Path(null,
+ System.getProperty("java.home")
+ + File.separator + "lib"
+ + File.separator + "rt.jar"));
+ // Just keep the old version as well and let addExisting
+ // sort it out.
+ addExisting(new Path(null,
+ System.getProperty("java.home")
+ + File.separator + "jre"
+ + File.separator + "lib"
+ + File.separator + "rt.jar"));
+
+ // Sun's and Apple's 1.4 have JCE and JSSE in separate jars.
+ String[] secJars = {"jce", "jsse"};
+ for (int i = 0; i < secJars.length; i++) {
+ addExisting(new Path(null,
+ System.getProperty("java.home")
+ + File.separator + "lib"
+ + File.separator + secJars[i] + ".jar"));
+ addExisting(new Path(null,
+ System.getProperty("java.home")
+ + File.separator + ".."
+ + File.separator + "Classes"
+ + File.separator + secJars[i] + ".jar"));
+ }
+
+ // IBM's 1.4 has rt.jar split into 4 smaller jars and a combined
+ // JCE/JSSE in security.jar.
+ String[] ibmJars
+ = {"core", "graphics", "security", "server", "xml"};
+ for (int i = 0; i < ibmJars.length; i++) {
+ addExisting(new Path(null,
+ System.getProperty("java.home")
+ + File.separator + "lib"
+ + File.separator + ibmJars[i] + ".jar"));
+ }
+
+ // Added for MacOS X
+ addExisting(new Path(null,
+ System.getProperty("java.home")
+ + File.separator + ".."
+ + File.separator + "Classes"
+ + File.separator + "classes.jar"));
+ addExisting(new Path(null,
+ System.getProperty("java.home")
+ + File.separator + ".."
+ + File.separator + "Classes"
+ + File.separator + "ui.jar"));
+ }
+ }
+
+ /**
+ * Emulation of extdirs feature in java >= 1.2.
+ * This method adds all files in the given
+ * directories (but not in sub-directories!) to the classpath,
+ * so that you don't have to specify them all one by one.
+ * @param extdirs - Path to append files to
+ */
+ public void addExtdirs(Path extdirs) {
+ if (extdirs == null) {
+ String extProp = System.getProperty("java.ext.dirs");
+ if (extProp != null) {
+ extdirs = new Path(getProject(), extProp);
+ } else {
+ return;
+ }
+ }
+
+ String[] dirs = extdirs.list();
+ for (int i = 0; i < dirs.length; i++) {
+ File dir = resolveFile(getProject(), dirs[i]);
+ if (dir.exists() && dir.isDirectory()) {
+ FileSet fs = new FileSet();
+ fs.setDir(dir);
+ fs.setIncludes("*");
+ addFileset(fs);
+ }
+ }
+ }
+
+ /**
+ * Fulfill the ResourceCollection contract. The Iterator returned
+ * will throw ConcurrentModificationExceptions if ResourceCollections
+ * are added to this container while the Iterator is in use.
+ * @return a "fail-fast" Iterator.
+ */
+ public final synchronized Iterator<Resource> iterator() {
+ if (isReference()) {
+ return ((Path) getCheckedRef()).iterator();
+ }
+ dieOnCircularReference();
+ if (getPreserveBC()) {
+ return new FileResourceIterator(getProject(), null, list());
+ }
+ return union == null ? Collections.<Resource> emptySet().iterator()
+ : assertFilesystemOnly(union).iterator();
+ }
+
+ /**
+ * Fulfill the ResourceCollection contract.
+ * @return whether this is a filesystem-only resource collection.
+ */
+ public synchronized boolean isFilesystemOnly() {
+ if (isReference()) {
+ return ((Path) getCheckedRef()).isFilesystemOnly();
+ }
+ dieOnCircularReference();
+ assertFilesystemOnly(union);
+ return true;
+ }
+
+ /**
+ * Verify the specified ResourceCollection is filesystem-only.
+ * @param rc the ResourceCollection to check.
+ * @throws BuildException if <code>rc</code> is not filesystem-only.
+ * @return the passed in ResourceCollection.
+ */
+ protected ResourceCollection assertFilesystemOnly(ResourceCollection rc) {
+ if (rc != null && !(rc.isFilesystemOnly())) {
+ throw new BuildException(getDataTypeName()
+ + " allows only filesystem resources.");
+ }
+ return rc;
+ }
+
+ /**
+ * Helps determine whether to preserve BC by calling <code>list()</code> on subclasses.
+ * The default behavior of this method is to return <code>true</code> for any subclass
+ * that implements <code>list()</code>; this can, of course, be avoided by overriding
+ * this method to return <code>false</code>. It is not expected that the result of this
+ * method should change over time, thus it is called only once.
+ * @return <code>true</code> if <code>iterator()</code> should delegate to <code>list()</code>.
+ */
+ protected boolean delegateIteratorToList() {
+ if (getClass().equals(Path.class)) {
+ return false;
+ }
+ try {
+ Method listMethod = getClass().getMethod("list", (Class[]) null);
+ return !listMethod.getDeclaringClass().equals(Path.class);
+ } catch (Exception e) {
+ //shouldn't happen, but
+ return false;
+ }
+ }
+
+ private synchronized boolean getPreserveBC() {
+ if (preserveBC == null) {
+ preserveBC = delegateIteratorToList() ? Boolean.TRUE : Boolean.FALSE;
+ }
+ return preserveBC.booleanValue();
+ }
+
+ /**
+ * Does the given file name contain wildcards?
+ * @since Ant 1.8.2
+ */
+ private static boolean containsWildcards(String path) {
+ return path != null
+ && (path.indexOf("*") > -1 || path.indexOf("?") > -1);
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/PatternSet.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/PatternSet.java
new file mode 100644
index 00000000..9fb94050
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/PatternSet.java
@@ -0,0 +1,541 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.StringTokenizer;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.PropertyHelper;
+import org.apache.tools.ant.util.FileUtils;
+
+/**
+ * Named collection of include/exclude tags.
+ *
+ * <p>Moved out of MatchingTask to make it a standalone object that
+ * could be referenced (by scripts for example).
+ *
+ */
+public class PatternSet extends DataType implements Cloneable {
+ private List<NameEntry> includeList = new ArrayList<NameEntry>();
+ private List<NameEntry> excludeList = new ArrayList<NameEntry>();
+ private List<NameEntry> includesFileList = new ArrayList<NameEntry>();
+ private List<NameEntry> excludesFileList = new ArrayList<NameEntry>();
+
+ /**
+ * inner class to hold a name on list. "If" and "Unless" attributes
+ * may be used to invalidate the entry based on the existence of a
+ * property (typically set thru the use of the Available task)
+ * or value of an expression.
+ */
+ public class NameEntry {
+ private String name;
+ private Object ifCond;
+ private Object unlessCond;
+
+ /**
+ * Sets the name pattern.
+ *
+ * @param name The pattern string.
+ */
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ /**
+ * Sets the if attribute. This attribute and the "unless"
+ * attribute are used to validate the name, based on the
+ * existence of the property or the value of the evaluated
+ * property expression.
+ *
+ * @param cond A property name or expression. If the
+ * expression evaluates to false or no property of
+ * its value is present, the name is invalid.
+ * @since Ant 1.8.0
+ */
+ public void setIf(Object cond) {
+ ifCond = cond;
+ }
+
+ /**
+ * Sets the if attribute. This attribute and the "unless"
+ * attribute are used to validate the name, based on the
+ * existence of the property or the value of the evaluated
+ * property expression.
+ *
+ * @param cond A property name or expression. If the
+ * expression evaluates to false or no property of
+ * its value is present, the name is invalid.
+ */
+ public void setIf(String cond) {
+ setIf((Object) cond);
+ }
+
+ /**
+ * Sets the unless attribute. This attribute and the "if"
+ * attribute are used to validate the name, based on the
+ * existence of the property or the value of the evaluated
+ * property expression.
+ *
+ * @param cond A property name or expression. If the
+ * expression evaluates to true or a property of
+ * its value is present, the name is invalid.
+ * @since Ant 1.8.0
+ */
+ public void setUnless(Object cond) {
+ unlessCond = cond;
+ }
+
+ /**
+ * Sets the unless attribute. This attribute and the "if"
+ * attribute are used to validate the name, based on the
+ * existence of the property or the value of the evaluated
+ * property expression.
+ *
+ * @param cond A property name or expression. If the
+ * expression evaluates to true or a property of
+ * its value is present, the name is invalid.
+ */
+ public void setUnless(String cond) {
+ setUnless((Object) cond);
+ }
+
+ /**
+ * @return the name attribute.
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * This validates the name - checks the if and unless
+ * properties.
+ *
+ * @param p the current project, used to check the presence or
+ * absence of a property.
+ * @return the name attribute or null if the "if" or "unless"
+ * properties are not/are set.
+ */
+ public String evalName(Project p) {
+ return valid(p) ? name : null;
+ }
+
+ private boolean valid(Project p) {
+ PropertyHelper ph = PropertyHelper.getPropertyHelper(p);
+ return ph.testIfCondition(ifCond)
+ && ph.testUnlessCondition(unlessCond);
+ }
+
+ /**
+ * @return a printable form of this object.
+ */
+ public String toString() {
+ StringBuffer buf = new StringBuffer();
+ if (name == null) {
+ buf.append("noname");
+ } else {
+ buf.append(name);
+ }
+ if ((ifCond != null) || (unlessCond != null)) {
+ buf.append(":");
+ String connector = "";
+
+ if (ifCond != null) {
+ buf.append("if->");
+ buf.append(ifCond);
+ connector = ";";
+ }
+ if (unlessCond != null) {
+ buf.append(connector);
+ buf.append("unless->");
+ buf.append(unlessCond);
+ }
+ }
+ return buf.toString();
+ }
+ }
+
+ private static final class InvertedPatternSet extends PatternSet {
+ private InvertedPatternSet(PatternSet p) {
+ setProject(p.getProject());
+ addConfiguredPatternset(p);
+ }
+ public String[] getIncludePatterns(Project p) {
+ return super.getExcludePatterns(p);
+ }
+ public String[] getExcludePatterns(Project p) {
+ return super.getIncludePatterns(p);
+ }
+ }
+
+ /**
+ * Creates a new <code>PatternSet</code> instance.
+ */
+ public PatternSet() {
+ super();
+ }
+
+ /**
+ * Makes this instance in effect a reference to another PatternSet
+ * instance.
+ *
+ * <p>You must not set another attribute or nest elements inside
+ * this element if you make it a reference.</p>
+ * @param r the reference to another patternset.
+ * @throws BuildException on error.
+ */
+ public void setRefid(Reference r) throws BuildException {
+ if (!includeList.isEmpty() || !excludeList.isEmpty()) {
+ throw tooManyAttributes();
+ }
+ super.setRefid(r);
+ }
+
+ /**
+ * This is a patternset nested element.
+ *
+ * @param p a configured patternset nested element.
+ */
+ public void addConfiguredPatternset(PatternSet p) {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ String[] nestedIncludes = p.getIncludePatterns(getProject());
+ String[] nestedExcludes = p.getExcludePatterns(getProject());
+
+ if (nestedIncludes != null) {
+ for (int i = 0; i < nestedIncludes.length; i++) {
+ createInclude().setName(nestedIncludes[i]);
+ }
+ }
+ if (nestedExcludes != null) {
+ for (int i = 0; i < nestedExcludes.length; i++) {
+ createExclude().setName(nestedExcludes[i]);
+ }
+ }
+ }
+
+ /**
+ * add a name entry on the include list
+ * @return a nested include element to be configured.
+ */
+ public NameEntry createInclude() {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ return addPatternToList(includeList);
+ }
+
+ /**
+ * add a name entry on the include files list
+ * @return a nested includesfile element to be configured.
+ */
+ public NameEntry createIncludesFile() {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ return addPatternToList(includesFileList);
+ }
+
+ /**
+ * add a name entry on the exclude list
+ * @return a nested exclude element to be configured.
+ */
+ public NameEntry createExclude() {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ return addPatternToList(excludeList);
+ }
+
+ /**
+ * add a name entry on the exclude files list
+ * @return a nested excludesfile element to be configured.
+ */
+ public NameEntry createExcludesFile() {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ return addPatternToList(excludesFileList);
+ }
+
+ /**
+ * Appends <code>includes</code> to the current list of include patterns.
+ * Patterns may be separated by a comma or a space.
+ *
+ * @param includes the string containing the include patterns
+ */
+ public void setIncludes(String includes) {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ if (includes != null && includes.length() > 0) {
+ StringTokenizer tok = new StringTokenizer(includes, ", ", false);
+ while (tok.hasMoreTokens()) {
+ createInclude().setName(tok.nextToken());
+ }
+ }
+ }
+
+ /**
+ * Appends <code>excludes</code> to the current list of exclude patterns.
+ * Patterns may be separated by a comma or a space.
+ *
+ * @param excludes the string containing the exclude patterns
+ */
+ public void setExcludes(String excludes) {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ if (excludes != null && excludes.length() > 0) {
+ StringTokenizer tok = new StringTokenizer(excludes, ", ", false);
+ while (tok.hasMoreTokens()) {
+ createExclude().setName(tok.nextToken());
+ }
+ }
+ }
+
+ /**
+ * add a name entry to the given list
+ */
+ private NameEntry addPatternToList(List<NameEntry> list) {
+ NameEntry result = new NameEntry();
+ list.add(result);
+ return result;
+ }
+
+ /**
+ * Sets the name of the file containing the includes patterns.
+ *
+ * @param includesFile The file to fetch the include patterns from.
+ * @throws BuildException on error.
+ */
+ public void setIncludesfile(File includesFile) throws BuildException {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ createIncludesFile().setName(includesFile.getAbsolutePath());
+ }
+
+ /**
+ * Sets the name of the file containing the excludes patterns.
+ *
+ * @param excludesFile The file to fetch the exclude patterns from.
+ * @throws BuildException on error.
+ */
+ public void setExcludesfile(File excludesFile) throws BuildException {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ createExcludesFile().setName(excludesFile.getAbsolutePath());
+ }
+
+ /**
+ * Reads path matching patterns from a file and adds them to the
+ * includes or excludes list (as appropriate).
+ */
+ private void readPatterns(File patternfile, List<NameEntry> patternlist, Project p)
+ throws BuildException {
+
+ BufferedReader patternReader = null;
+ try {
+ // Get a FileReader
+ patternReader = new BufferedReader(new FileReader(patternfile));
+
+ // Create one NameEntry in the appropriate pattern list for each
+ // line in the file.
+ String line = patternReader.readLine();
+ while (line != null) {
+ if (line.length() > 0) {
+ line = p.replaceProperties(line);
+ addPatternToList(patternlist).setName(line);
+ }
+ line = patternReader.readLine();
+ }
+ } catch (IOException ioe) {
+ throw new BuildException("An error occurred while reading from pattern file: "
+ + patternfile, ioe);
+ } finally {
+ FileUtils.close(patternReader);
+ }
+ }
+
+ /**
+ * Adds the patterns of the other instance to this set.
+ * @param other the other PatternSet instance.
+ * @param p the current project.
+ */
+ public void append(PatternSet other, Project p) {
+ if (isReference()) {
+ throw new BuildException("Cannot append to a reference");
+ }
+ dieOnCircularReference(p);
+ String[] incl = other.getIncludePatterns(p);
+ if (incl != null) {
+ for (int i = 0; i < incl.length; i++) {
+ createInclude().setName(incl[i]);
+ }
+ }
+ String[] excl = other.getExcludePatterns(p);
+ if (excl != null) {
+ for (int i = 0; i < excl.length; i++) {
+ createExclude().setName(excl[i]);
+ }
+ }
+ }
+
+ /**
+ * Returns the filtered include patterns.
+ * @param p the current project.
+ * @return the filtered included patterns.
+ */
+ public String[] getIncludePatterns(Project p) {
+ if (isReference()) {
+ return getRef(p).getIncludePatterns(p);
+ }
+ dieOnCircularReference(p);
+ readFiles(p);
+ return makeArray(includeList, p);
+ }
+
+ /**
+ * Returns the filtered include patterns.
+ * @param p the current project.
+ * @return the filtered excluded patterns.
+ */
+ public String[] getExcludePatterns(Project p) {
+ if (isReference()) {
+ return getRef(p).getExcludePatterns(p);
+ }
+ dieOnCircularReference(p);
+ readFiles(p);
+ return makeArray(excludeList, p);
+ }
+
+ /**
+ * Helper for FileSet classes.
+ * Check if there are patterns defined.
+ * @param p the current project.
+ * @return true if there are patterns.
+ */
+ public boolean hasPatterns(Project p) {
+ if (isReference()) {
+ return getRef(p).hasPatterns(p);
+ }
+ dieOnCircularReference(p);
+ return includesFileList.size() > 0 || excludesFileList.size() > 0
+ || includeList.size() > 0 || excludeList.size() > 0;
+ }
+
+ /**
+ * Performs the check for circular references and returns the
+ * referenced PatternSet.
+ */
+ private PatternSet getRef(Project p) {
+ return (PatternSet) getCheckedRef(p);
+ }
+
+ /**
+ * Convert a vector of NameEntry elements into an array of Strings.
+ */
+ private String[] makeArray(List<NameEntry> list, Project p) {
+ if (list.size() == 0) {
+ return null;
+ }
+ ArrayList<String> tmpNames = new ArrayList<String>();
+ for (NameEntry ne : list) {
+ String pattern = ne.evalName(p);
+ if (pattern != null && pattern.length() > 0) {
+ tmpNames.add(pattern);
+ }
+ }
+ return tmpNames.toArray(new String[tmpNames.size()]);
+ }
+
+ /**
+ * Read includesfile ot excludesfile if not already done so.
+ */
+ private void readFiles(Project p) {
+ if (includesFileList.size() > 0) {
+ for (NameEntry ne : includesFileList) {
+ String fileName = ne.evalName(p);
+ if (fileName != null) {
+ File inclFile = p.resolveFile(fileName);
+ if (!inclFile.exists()) {
+ throw new BuildException("Includesfile " + inclFile.getAbsolutePath()
+ + " not found.");
+ }
+ readPatterns(inclFile, includeList, p);
+ }
+ }
+ includesFileList.clear();
+ }
+ if (excludesFileList.size() > 0) {
+ for (NameEntry ne : excludesFileList) {
+ String fileName = ne.evalName(p);
+ if (fileName != null) {
+ File exclFile = p.resolveFile(fileName);
+ if (!exclFile.exists()) {
+ throw new BuildException("Excludesfile " + exclFile.getAbsolutePath()
+ + " not found.");
+ }
+ readPatterns(exclFile, excludeList, p);
+ }
+ }
+ excludesFileList.clear();
+ }
+ }
+
+ /**
+ * @return a printable form of this object.
+ */
+ public String toString() {
+ return "patternSet{ includes: " + includeList + " excludes: " + excludeList + " }";
+ }
+
+ /**
+ * @since Ant 1.6
+ * @return a clone of this patternset.
+ */
+ public Object clone() {
+ try {
+ PatternSet ps = (PatternSet) super.clone();
+ ps.includeList = new ArrayList<NameEntry>(includeList);
+ ps.excludeList = new ArrayList<NameEntry>(excludeList);
+ ps.includesFileList = new ArrayList<NameEntry>(includesFileList);
+ ps.excludesFileList = new ArrayList<NameEntry>(excludesFileList);
+ return ps;
+ } catch (CloneNotSupportedException e) {
+ throw new BuildException(e);
+ }
+ }
+
+ /**
+ * Add an inverted patternset.
+ * @param p the pattern to invert and add.
+ */
+ public void addConfiguredInvert(PatternSet p) {
+ addConfiguredPatternset(new InvertedPatternSet(p));
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/Permissions.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/Permissions.java
new file mode 100644
index 00000000..96da71bd
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/Permissions.java
@@ -0,0 +1,356 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types;
+
+import java.lang.reflect.Constructor;
+import java.security.UnresolvedPermission;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+import java.util.StringTokenizer;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.ExitException;
+
+/**
+ * This class implements a security manager meant for usage by tasks that run inside the
+ * Ant VM. An examples are the Java Task and JUnitTask.
+ *
+ * The basic functionality is that nothing (except for a base set of permissions) is allowed, unless
+ * the permission is granted either explicitly or implicitly.
+ * If a permission is granted this can be overruled by explicitly revoking the permission.
+ *
+ * It is not permissible to add permissions (either granted or revoked) while the Security Manager
+ * is active (after calling setSecurityManager() but before calling restoreSecurityManager()).
+ *
+ * @since Ant 1.6
+ */
+public class Permissions {
+
+ private final List<Permission> grantedPermissions = new LinkedList<Permission>();
+ private final List<Permission> revokedPermissions = new LinkedList<Permission>();
+ private java.security.Permissions granted = null;
+ private SecurityManager origSm = null;
+ private boolean active = false;
+ private final boolean delegateToOldSM;
+
+ // Mandatory constructor for permission object.
+ private static final Class<?>[] PARAMS = {String.class, String.class};
+
+ /**
+ * Create a set of Permissions. Equivalent to calling
+ * <code>new Permissions(false)</code>.
+ */
+ public Permissions() {
+ this(false);
+ }
+
+ /**
+ * Create a set of permissions.
+ * @param delegateToOldSM if <code>true</code> the old security manager
+ * will be used if the permission has not been explicitly granted or revoked
+ * in this instance.
+ */
+ public Permissions(final boolean delegateToOldSM) {
+ this.delegateToOldSM = delegateToOldSM;
+ }
+
+ /**
+ * Adds a permission to be granted.
+ * @param perm The Permissions.Permission to be granted.
+ */
+ public void addConfiguredGrant(final Permissions.Permission perm) {
+ grantedPermissions.add(perm);
+ }
+
+ /**
+ * Adds a permission to be revoked.
+ * @param perm The Permissions.Permission to be revoked
+ */
+ public void addConfiguredRevoke(final Permissions.Permission perm) {
+ revokedPermissions.add(perm);
+ }
+
+ /**
+ * To be used by tasks wishing to use this security model before executing the part to be
+ * subject to these Permissions. Note that setting the SecurityManager too early may
+ * prevent your part from starting, as for instance changing classloaders may be prohibited.
+ * The classloader for the new situation is supposed to be present.
+ * @throws BuildException on error
+ */
+ public synchronized void setSecurityManager() throws BuildException {
+ origSm = System.getSecurityManager();
+ init();
+ System.setSecurityManager(new MySM());
+ active = true;
+ }
+
+ /**
+ * Initializes the list of granted permissions, checks the list of revoked permissions.
+ */
+ private void init() throws BuildException {
+ granted = new java.security.Permissions();
+ for (final Permissions.Permission p : revokedPermissions) {
+ if (p.getClassName() == null) {
+ throw new BuildException("Revoked permission " + p + " does not contain a class.");
+ }
+ }
+ for (final Permissions.Permission p : grantedPermissions) {
+ if (p.getClassName() == null) {
+ throw new BuildException("Granted permission " + p
+ + " does not contain a class.");
+ } else {
+ final java.security.Permission perm = createPermission(p);
+ granted.add(perm);
+ }
+ }
+ // Add base set of permissions
+ granted.add(new java.net.SocketPermission("localhost:1024-", "listen"));
+ granted.add(new java.util.PropertyPermission("java.version", "read"));
+ granted.add(new java.util.PropertyPermission("java.vendor", "read"));
+ granted.add(new java.util.PropertyPermission("java.vendor.url", "read"));
+ granted.add(new java.util.PropertyPermission("java.class.version", "read"));
+ granted.add(new java.util.PropertyPermission("os.name", "read"));
+ granted.add(new java.util.PropertyPermission("os.version", "read"));
+ granted.add(new java.util.PropertyPermission("os.arch", "read"));
+ granted.add(new java.util.PropertyPermission("file.encoding", "read"));
+ granted.add(new java.util.PropertyPermission("file.separator", "read"));
+ granted.add(new java.util.PropertyPermission("path.separator", "read"));
+ granted.add(new java.util.PropertyPermission("line.separator", "read"));
+ granted.add(new java.util.PropertyPermission("java.specification.version", "read"));
+ granted.add(new java.util.PropertyPermission("java.specification.vendor", "read"));
+ granted.add(new java.util.PropertyPermission("java.specification.name", "read"));
+ granted.add(new java.util.PropertyPermission("java.vm.specification.version", "read"));
+ granted.add(new java.util.PropertyPermission("java.vm.specification.vendor", "read"));
+ granted.add(new java.util.PropertyPermission("java.vm.specification.name", "read"));
+ granted.add(new java.util.PropertyPermission("java.vm.version", "read"));
+ granted.add(new java.util.PropertyPermission("java.vm.vendor", "read"));
+ granted.add(new java.util.PropertyPermission("java.vm.name", "read"));
+ }
+
+ private java.security.Permission createPermission(
+ final Permissions.Permission permission) {
+ try {
+ // First add explicitly already resolved permissions will not be
+ // resolved when added as unresolved permission.
+ final Class<? extends java.security.Permission> clazz = Class.forName(
+ permission.getClassName()).asSubclass(java.security.Permission.class);
+ final String name = permission.getName();
+ final String actions = permission.getActions();
+ final Constructor<? extends java.security.Permission> ctr = clazz.getConstructor(PARAMS);
+ return ctr.newInstance(new Object[] {name, actions});
+ } catch (final Exception e) {
+ // Let the UnresolvedPermission handle it.
+ return new UnresolvedPermission(permission.getClassName(),
+ permission.getName(), permission.getActions(), null);
+ }
+ }
+
+ /**
+ * To be used by tasks that just finished executing the parts subject to these permissions.
+ */
+ public synchronized void restoreSecurityManager() {
+ active = false;
+ System.setSecurityManager(origSm);
+ }
+
+ /**
+ * This inner class implements the actual SecurityManager that can be used by tasks
+ * supporting Permissions.
+ */
+ private class MySM extends SecurityManager {
+
+ /**
+ * Exit is treated in a special way in order to be able to return the exit code
+ * towards tasks.
+ * An ExitException is thrown instead of a simple SecurityException to indicate the exit
+ * code.
+ * Overridden from java.lang.SecurityManager
+ * @param status The exit status requested.
+ */
+ @Override
+ public void checkExit(final int status) {
+ final java.security.Permission perm = new java.lang.RuntimePermission("exitVM", null);
+ try {
+ checkPermission(perm);
+ } catch (final SecurityException e) {
+ throw new ExitException(e.getMessage(), status);
+ }
+ }
+
+ /**
+ * The central point in checking permissions.
+ * Overridden from java.lang.SecurityManager
+ *
+ * @param perm The permission requested.
+ */
+ @Override
+ public void checkPermission(final java.security.Permission perm) {
+ if (active) {
+ if (delegateToOldSM && !perm.getName().equals("exitVM")) {
+ boolean permOK = false;
+ if (granted.implies(perm)) {
+ permOK = true;
+ }
+ checkRevoked(perm);
+ /*
+ if the permission was not explicitly granted or revoked
+ the original security manager will do its work
+ */
+ if (!permOK && origSm != null) {
+ origSm.checkPermission(perm);
+ }
+ } else {
+ if (!granted.implies(perm)) {
+ throw new SecurityException("Permission " + perm + " was not granted.");
+ }
+ checkRevoked(perm);
+ }
+ }
+ }
+
+ /**
+ * throws an exception if this permission is revoked
+ * @param perm the permission being checked
+ */
+ private void checkRevoked(final java.security.Permission perm) {
+ for (final Permissions.Permission revoked : revokedPermissions) {
+ if (revoked.matches(perm)) {
+ throw new SecurityException("Permission " + perm + " was revoked.");
+ }
+ }
+ }
+ }
+
+ /** Represents a permission. */
+ public static class Permission {
+ private String className;
+ private String name;
+ private String actionString;
+ private Set<String> actions;
+
+ /**
+ * Set the class, mandatory.
+ * @param aClass The class name of the permission.
+ */
+ public void setClass(final String aClass) {
+ className = aClass.trim();
+ }
+
+ /**
+ * Get the class of the permission.
+ * @return The class name of the permission.
+ */
+ public String getClassName() {
+ return className;
+ }
+
+ /**
+ * Set the name of the permission.
+ * @param aName The name of the permission.
+ */
+ public void setName(final String aName) {
+ name = aName.trim();
+ }
+
+ /**
+ * Get the name of the permission.
+ * @return The name of the permission.
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Set the actions.
+ * @param actions The actions of the permission.
+ */
+ public void setActions(final String actions) {
+ actionString = actions;
+ if (actions.length() > 0) {
+ this.actions = parseActions(actions);
+ }
+ }
+
+ /**
+ * Get the actions.
+ * @return The actions of the permission.
+ */
+ public String getActions() {
+ return actionString;
+ }
+
+ /**
+ * Learn whether the permission matches in case of a revoked permission.
+ * @param perm The permission to check against.
+ */
+ boolean matches(final java.security.Permission perm) {
+ if (!className.equals(perm.getClass().getName())) {
+ return false;
+ }
+ if (name != null) {
+ if (name.endsWith("*")) {
+ if (!perm.getName().startsWith(name.substring(0, name.length() - 1))) {
+ return false;
+ }
+ } else {
+ if (!name.equals(perm.getName())) {
+ return false;
+ }
+ }
+ }
+ if (actions != null) {
+ final Set<String> as = parseActions(perm.getActions());
+ final int size = as.size();
+ as.removeAll(actions);
+ if (as.size() == size) {
+ // None of the actions revoked, so all allowed.
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Parses the actions into a set of separate strings.
+ * @param actions The actions to be parsed.
+ */
+ private Set<String> parseActions(final String actions) {
+ final Set<String> result = new HashSet<String>();
+ final StringTokenizer tk = new StringTokenizer(actions, ",");
+ while (tk.hasMoreTokens()) {
+ final String item = tk.nextToken().trim();
+ if (!item.equals("")) {
+ result.add(item);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Get a string description of the permissions.
+ * @return string description of the permissions.
+ */
+ @Override
+ public String toString() {
+ return ("Permission: " + className + " (\"" + name + "\", \"" + actions + "\")");
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/PropertySet.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/PropertySet.java
new file mode 100644
index 00000000..f5992044
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/PropertySet.java
@@ -0,0 +1,577 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types;
+
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Properties;
+import java.util.Set;
+import java.util.Stack;
+import java.util.TreeMap;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.resources.MappedResource;
+import org.apache.tools.ant.types.resources.PropertyResource;
+import org.apache.tools.ant.util.FileNameMapper;
+import org.apache.tools.ant.util.regexp.RegexpMatcher;
+import org.apache.tools.ant.util.regexp.RegexpMatcherFactory;
+
+/**
+ * A set of properties.
+ *
+ * @since Ant 1.6
+ */
+public class PropertySet extends DataType implements ResourceCollection {
+
+ private boolean dynamic = true;
+ private boolean negate = false;
+ private Set<String> cachedNames;
+ private List<PropertyRef> ptyRefs = new ArrayList<PropertyRef>();
+ private List<PropertySet> setRefs = new ArrayList<PropertySet>();
+ private Mapper mapper;
+
+ /**
+ * This is a nested class containing a reference to some properties
+ * and optionally a source of properties.
+ */
+ public static class PropertyRef {
+
+ private int count;
+ private String name;
+ private String regex;
+ private String prefix;
+ private String builtin;
+
+ /**
+ * Set the name.
+ * @param name a <code>String</code> value.
+ */
+ public void setName(String name) {
+ assertValid("name", name);
+ this.name = name;
+ }
+
+ /**
+ * Set the regular expression to use to filter the properties.
+ * @param regex a regular expression.
+ */
+ public void setRegex(String regex) {
+ assertValid("regex", regex);
+ this.regex = regex;
+ }
+
+ /**
+ * Set the prefix to use.
+ * @param prefix a <code>String</code> value.
+ */
+ public void setPrefix(String prefix) {
+ assertValid("prefix", prefix);
+ this.prefix = prefix;
+ }
+
+ /**
+ * Builtin property names - all, system or commandline.
+ * @param b an enumerated <code>BuildinPropertySetName</code> value.
+ */
+ public void setBuiltin(BuiltinPropertySetName b) {
+ String pBuiltIn = b.getValue();
+ assertValid("builtin", pBuiltIn);
+ this.builtin = pBuiltIn;
+ }
+
+ private void assertValid(String attr, String value) {
+ if (value == null || value.length() < 1) {
+ throw new BuildException("Invalid attribute: " + attr);
+ }
+
+ if (++count != 1) {
+ throw new BuildException("Attributes name, regex, and "
+ + "prefix are mutually exclusive");
+ }
+ }
+
+ /**
+ * A debug toString().
+ * @return a string version of this object.
+ */
+ public String toString() {
+ return "name=" + name + ", regex=" + regex + ", prefix=" + prefix
+ + ", builtin=" + builtin;
+ }
+
+ } //end nested class
+
+ /**
+ * Allow properties of a particular name in the set.
+ * @param name the property name to allow.
+ */
+ public void appendName(String name) {
+ PropertyRef r = new PropertyRef();
+ r.setName(name);
+ addPropertyref(r);
+ }
+
+ /**
+ * Allow properties whose names match a regex in the set.
+ * @param regex the regular expression to use.
+ */
+ public void appendRegex(String regex) {
+ PropertyRef r = new PropertyRef();
+ r.setRegex(regex);
+ addPropertyref(r);
+ }
+
+ /**
+ * Allow properties whose names start with a prefix in the set.
+ * @param prefix the prefix to use.
+ */
+ public void appendPrefix(String prefix) {
+ PropertyRef r = new PropertyRef();
+ r.setPrefix(prefix);
+ addPropertyref(r);
+ }
+
+ /**
+ * Allow builtin (all, system or commandline) properties in the set.
+ * @param b the type of builtin properties.
+ */
+ public void appendBuiltin(BuiltinPropertySetName b) {
+ PropertyRef r = new PropertyRef();
+ r.setBuiltin(b);
+ addPropertyref(r);
+ }
+
+ /**
+ * Set a mapper to change property names.
+ * @param type mapper type.
+ * @param from source pattern.
+ * @param to output pattern.
+ */
+ public void setMapper(String type, String from, String to) {
+ Mapper m = createMapper();
+ Mapper.MapperType mapperType = new Mapper.MapperType();
+ mapperType.setValue(type);
+ m.setType(mapperType);
+ m.setFrom(from);
+ m.setTo(to);
+ }
+
+ /**
+ * Add a property reference (nested element) to the references to be used.
+ * @param ref a property reference.
+ */
+ public void addPropertyref(PropertyRef ref) {
+ assertNotReference();
+ setChecked(false);
+ ptyRefs.add(ref);
+ }
+
+ /**
+ * Add another property set to this set.
+ * @param ref another property set.
+ */
+ public void addPropertyset(PropertySet ref) {
+ assertNotReference();
+ setChecked(false);
+ setRefs.add(ref);
+ }
+
+ /**
+ * Create a mapper to map the property names.
+ * @return a mapper to be configured.
+ */
+ public Mapper createMapper() {
+ assertNotReference();
+ if (mapper != null) {
+ throw new BuildException("Too many <mapper>s!");
+ }
+ mapper = new Mapper(getProject());
+ setChecked(false);
+ return mapper;
+ }
+
+ /**
+ * Add a nested FileNameMapper.
+ * @param fileNameMapper the mapper to add.
+ * @since Ant 1.6.3
+ */
+ public void add(FileNameMapper fileNameMapper) {
+ createMapper().add(fileNameMapper);
+ }
+
+ /**
+ * Set whether to reevaluate the set every time the set is used.
+ * Default is true.
+ *
+ * @param dynamic if true, reevaluate the property set each time
+ * the set is used. if false cache the property set
+ * the first time and use the cached set on subsequent
+ * occasions.
+ */
+ public void setDynamic(boolean dynamic) {
+ assertNotReference();
+ this.dynamic = dynamic;
+ }
+
+ /**
+ * Set whether to negate results.
+ * If "true", all properties not selected by nested elements will be returned.
+ * Default is "false".
+ * @param negate if true, negate the selection criteria.
+ */
+ public void setNegate(boolean negate) {
+ assertNotReference();
+ this.negate = negate;
+ }
+
+ /**
+ * Get the dynamic attribute.
+ * @return true if the property set is to be evaluated each time it is used.
+ */
+ public boolean getDynamic() {
+ if (isReference()) {
+ return getRef().dynamic;
+ }
+ dieOnCircularReference();
+ return dynamic;
+ }
+
+ /**
+ * Get the mapper attribute.
+ * @return the mapper attribute.
+ */
+ public Mapper getMapper() {
+ if (isReference()) {
+ return getRef().mapper;
+ }
+ dieOnCircularReference();
+ return mapper;
+ }
+
+ /**
+ * Convert the system properties to a hashtable.
+ * Use propertynames to get the list of properties (including
+ * default ones).
+ */
+ private Hashtable<String, Object> getAllSystemProperties() {
+ Hashtable<String, Object> ret = new Hashtable<String, Object>();
+ for (Enumeration<?> e = System.getProperties().propertyNames();
+ e.hasMoreElements();) {
+ String name = (String) e.nextElement();
+ ret.put(name, System.getProperties().getProperty(name));
+ }
+ return ret;
+ }
+
+ /**
+ * This is the operation to get the existing or recalculated properties.
+ * @return the properties for this propertyset.
+ */
+ public Properties getProperties() {
+ final Properties result = new Properties();
+ result.putAll(getPropertyMap());
+ return result;
+ }
+
+ /**
+ *
+ * @return Map
+ * @since 1.9.0
+ */
+ private Map<String, Object> getPropertyMap() {
+ if (isReference()) {
+ return getRef().getPropertyMap();
+ }
+ dieOnCircularReference();
+ final Mapper myMapper = getMapper();
+ final FileNameMapper m = myMapper == null ? null : myMapper.getImplementation();
+
+ final Map<String, Object> effectiveProperties = getEffectiveProperties();
+ final Set<String> propertyNames = getPropertyNames(effectiveProperties);
+ final Map<String, Object> result = new HashMap<String, Object>();
+
+ //iterate through the names, get the matching values
+ for (String name : propertyNames) {
+ Object value = effectiveProperties.get(name);
+ // TODO should we include null properties?
+ // TODO should we query the PropertyHelper for property value to grab potentially shadowed values?
+ if (value != null) {
+ // may be null if a system property has been added
+ // after the project instance has been initialized
+ if (m != null) {
+ //map the names
+ String[] newname = m.mapFileName(name);
+ if (newname != null) {
+ name = newname[0];
+ }
+ }
+ result.put(name, value);
+ }
+ }
+ return result;
+
+ }
+
+ private Map<String, Object> getEffectiveProperties() {
+ final Project prj = getProject();
+ final Map<String, Object> result = prj == null ? getAllSystemProperties() : prj.getProperties();
+ //quick & dirty, to make nested mapped p-sets work:
+ for (PropertySet set : setRefs) {
+ result.putAll(set.getPropertyMap());
+ }
+ return result;
+ }
+
+ private Set<String> getPropertyNames(Map<String, Object> props) {
+ Set<String> names;
+ if (getDynamic() || cachedNames == null) {
+ names = new HashSet<String>();
+ addPropertyNames(names, props);
+ // Add this PropertySet's nested PropertySets' property names.
+ for (PropertySet set : setRefs) {
+ names.addAll(set.getPropertyMap().keySet());
+ }
+ if (negate) {
+ //make a copy...
+ HashSet<String> complement = new HashSet<String>(props.keySet());
+ complement.removeAll(names);
+ names = complement;
+ }
+ if (!getDynamic()) {
+ cachedNames = names;
+ }
+ } else {
+ names = cachedNames;
+ }
+ return names;
+ }
+
+ /**
+ * @param names the output Set to fill with the property names
+ * matching this PropertySet selection criteria.
+ * @param props the current Project properties, passed in to
+ * avoid needless duplication of the Hashtable during recursion.
+ */
+ private void addPropertyNames(Set<String> names, Map<String, Object> props) {
+ if (isReference()) {
+ getRef().addPropertyNames(names, props);
+ }
+ dieOnCircularReference();
+ // Add this PropertySet's property names.
+ for (PropertyRef r : ptyRefs) {
+ if (r.name != null) {
+ if (props.get(r.name) != null) {
+ names.add(r.name);
+ }
+ } else if (r.prefix != null) {
+ for (String name : props.keySet()) {
+ if (name.startsWith(r.prefix)) {
+ names.add(name);
+ }
+ }
+ } else if (r.regex != null) {
+ RegexpMatcherFactory matchMaker = new RegexpMatcherFactory();
+ RegexpMatcher matcher = matchMaker.newRegexpMatcher();
+ matcher.setPattern(r.regex);
+ for (String name : props.keySet()) {
+ if (matcher.matches(name)) {
+ names.add(name);
+ }
+ }
+ } else if (r.builtin != null) {
+
+ if (r.builtin.equals(BuiltinPropertySetName.ALL)) {
+ names.addAll(props.keySet());
+ } else if (r.builtin.equals(BuiltinPropertySetName.SYSTEM)) {
+ names.addAll(getAllSystemProperties().keySet());
+ } else if (r.builtin.equals(BuiltinPropertySetName
+ .COMMANDLINE)) {
+ names.addAll(getProject().getUserProperties().keySet());
+ } else {
+ throw new BuildException("Impossible: Invalid builtin "
+ + "attribute!");
+ }
+ } else {
+ throw new BuildException("Impossible: Invalid PropertyRef!");
+ }
+ }
+ }
+
+ /**
+ * Performs the check for circular references and returns the
+ * referenced PropertySet.
+ * @return the referenced PropertySet.
+ */
+ protected PropertySet getRef() {
+ return (PropertySet) getCheckedRef(PropertySet.class, "propertyset");
+ }
+
+ /**
+ * Sets the value of the refid attribute.
+ *
+ * @param r the reference this datatype should point to.
+ * @throws BuildException if another attribute was set, since
+ * refid and all other attributes are mutually exclusive.
+ */
+ public final void setRefid(Reference r) {
+ if (!noAttributeSet) {
+ throw tooManyAttributes();
+ }
+ super.setRefid(r);
+ }
+
+ /**
+ * Ensures this data type is not a reference.
+ *
+ * <p>Calling this method as the first line of every bean method of
+ * this data type (setXyz, addXyz, createXyz) ensure proper handling
+ * of the refid attribute.</p>
+ *
+ * @throws BuildException if the refid attribute was already set, since
+ * refid and all other attributes are mutually exclusive.
+ */
+ protected final void assertNotReference() {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ noAttributeSet = false;
+ }
+
+ /**
+ * Flag which tracks whether any attribute has been set; used by
+ * {@link #assertNotReference()} and {@link #setRefid(Reference)}.
+ */
+ private boolean noAttributeSet = true;
+
+ /**
+ * Used for propertyref's builtin attribute.
+ */
+ public static class BuiltinPropertySetName extends EnumeratedAttribute {
+ static final String ALL = "all";
+ static final String SYSTEM = "system";
+ static final String COMMANDLINE = "commandline";
+ /** {@inheritDoc}. */
+ public String[] getValues() {
+ return new String[] {ALL, SYSTEM, COMMANDLINE};
+ }
+ }
+
+ /**
+ * A debug toString.
+ * This gets a comma separated list of key=value pairs for
+ * the properties in the set.
+ * The output order is sorted according to the keys' <i>natural order</i>.
+ * @return a string rep of this object.
+ */
+ public String toString() {
+ if (isReference()) {
+ return getRef().toString();
+ }
+ dieOnCircularReference();
+ StringBuilder b = new StringBuilder();
+ TreeMap<String, Object> sorted = new TreeMap<String, Object>(getPropertyMap());
+ for (Entry<String, Object> e : sorted.entrySet()) {
+ if (b.length() != 0) {
+ b.append(", ");
+ }
+ b.append(e.getKey());
+ b.append("=");
+ b.append(e.getValue());
+ }
+ return b.toString();
+ }
+
+ /**
+ * Fulfill the ResourceCollection interface.
+ * @return an Iterator of Resources.
+ * @since Ant 1.7
+ */
+ public Iterator<Resource> iterator() {
+ if (isReference()) {
+ return getRef().iterator();
+ }
+ dieOnCircularReference();
+ final Set<String> names = getPropertyNames(getEffectiveProperties());
+
+ Mapper myMapper = getMapper();
+ final FileNameMapper m = myMapper == null ? null : myMapper.getImplementation();
+ final Iterator<String> iter = names.iterator();
+
+ return new Iterator<Resource>() {
+ public boolean hasNext() {
+ return iter.hasNext();
+ }
+ public Resource next() {
+ PropertyResource p = new PropertyResource(getProject(), iter.next());
+ return m == null ? (Resource) p : new MappedResource(p, m);
+ }
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+ };
+ }
+
+ /**
+ * Fulfill the ResourceCollection contract.
+ * @return the size of this ResourceCollection.
+ */
+ public int size() {
+ return isReference() ? getRef().size() : getProperties().size();
+ }
+
+ /**
+ * Fulfill the ResourceCollection contract.
+ * @return whether this is a filesystem-only resource collection.
+ */
+ public boolean isFilesystemOnly() {
+ if (isReference()) {
+ return getRef().isFilesystemOnly();
+ }
+ dieOnCircularReference();
+ return false;
+ }
+
+ protected synchronized void dieOnCircularReference(Stack<Object> stk, Project p)
+ throws BuildException {
+ if (isChecked()) {
+ return;
+ }
+ if (isReference()) {
+ super.dieOnCircularReference(stk, p);
+ } else {
+ if (mapper != null) {
+ pushAndInvokeCircularReferenceCheck(mapper, stk, p);
+ }
+ for (PropertySet propertySet : setRefs) {
+ pushAndInvokeCircularReferenceCheck(propertySet, stk,
+ p);
+ }
+ setChecked(true);
+ }
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/Quantifier.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/Quantifier.java
new file mode 100644
index 00000000..ac1b84ce
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/Quantifier.java
@@ -0,0 +1,146 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types;
+
+import org.apache.tools.ant.BuildException;
+
+/**
+ * EnumeratedAttribute for quantifier comparisons. Evaluates a
+ * <code>boolean[]</code> or raw <code>true</code> and <code>false</code>
+ * counts. Accepts the following values:<ul>
+ * <li>"all"</li> - none <code>false</code>
+ * <li>"each"</li> - none <code>false</code>
+ * <li>"every"</li> - none <code>false</code>
+ * <li>"any"</li> - at least one <code>true</code>
+ * <li>"some"</li> - at least one <code>true</code>
+ * <li>"one"</li> - exactly one <code>true</code>
+ * <li>"majority"</li> - more <code>true</code> than <code>false</code>
+ * <li>"most"</li> - more <code>true</code> than <code>false</code>
+ * <li>"none"</li> - none <code>true</code>
+ * </ul>
+ * @since Ant 1.7
+ */
+public class Quantifier extends EnumeratedAttribute {
+ private static final String[] VALUES
+ = new String[] {"all", "each", "every", "any", "some", "one",
+ "majority", "most", "none"};
+
+ /** ALL instance */
+ public static final Quantifier ALL = new Quantifier("all");
+ /** ANY instance */
+ public static final Quantifier ANY = new Quantifier("any");
+ /** ONE instance */
+ public static final Quantifier ONE = new Quantifier("one");
+ /** MAJORITY instance */
+ public static final Quantifier MAJORITY = new Quantifier("majority");
+ /** NONE instance */
+ public static final Quantifier NONE = new Quantifier("none");
+
+ private abstract static class Predicate {
+ abstract boolean eval(int t, int f);
+ }
+
+ private static final Predicate ALL_PRED = new Predicate() {
+ boolean eval(int t, int f) { return f == 0; }
+ };
+
+ private static final Predicate ANY_PRED = new Predicate() {
+ boolean eval(int t, int f) { return t > 0; }
+ };
+
+ private static final Predicate ONE_PRED = new Predicate() {
+ boolean eval(int t, int f) { return t == 1; }
+ };
+
+ private static final Predicate MAJORITY_PRED = new Predicate() {
+ boolean eval(int t, int f) { return t > f; }
+ };
+
+ private static final Predicate NONE_PRED = new Predicate() {
+ boolean eval(int t, int f) { return t == 0; }
+ };
+
+ private static final Predicate[] PREDS = new Predicate[VALUES.length];
+
+ static {
+ // CheckStyle:MagicNumber OFF
+ PREDS[0] = ALL_PRED;
+ PREDS[1] = ALL_PRED;
+ PREDS[2] = ALL_PRED;
+ PREDS[3] = ANY_PRED;
+ PREDS[4] = ANY_PRED;
+ PREDS[5] = ONE_PRED;
+ PREDS[6] = MAJORITY_PRED;
+ PREDS[7] = MAJORITY_PRED;
+ PREDS[8] = NONE_PRED;
+ // CheckStyle:MagicNumber ON
+ }
+
+ /**
+ * Default constructor.
+ */
+ public Quantifier() {
+ }
+
+ /**
+ * Construct a new Quantifier with the specified value.
+ * @param value the EnumeratedAttribute value.
+ */
+ public Quantifier(String value) {
+ setValue(value);
+ }
+
+ /**
+ * Return the possible values.
+ * @return String[] of EnumeratedAttribute values.
+ */
+ public String[] getValues() {
+ return VALUES;
+ }
+
+ /**
+ * Evaluate a <code>boolean<code> array.
+ * @param b the <code>boolean[]</code> to evaluate.
+ * @return true if the argument fell within the parameters of this Quantifier.
+ */
+ public boolean evaluate(boolean[] b) {
+ int t = 0;
+ for (int i = 0; i < b.length; i++) {
+ if (b[i]) {
+ t++;
+ }
+ }
+ return evaluate(t, b.length - t);
+ }
+
+ /**
+ * Evaluate integer <code>true</code> vs. <code>false</code> counts.
+ * @param t the number of <code>true</code> values.
+ * @param f the number of <code>false</code> values.
+ * @return true if the arguments fell within the parameters of this Quantifier.
+ */
+ public boolean evaluate(int t, int f) {
+ int index = getIndex();
+ if (index == -1) {
+ throw new BuildException("Quantifier value not set.");
+ }
+ return PREDS[index].eval(t, f);
+ }
+
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/RedirectorElement.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/RedirectorElement.java
new file mode 100644
index 00000000..d27b199c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/RedirectorElement.java
@@ -0,0 +1,630 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Stack;
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.Redirector;
+
+/**
+ * Element representation of a <code>Redirector</code>.
+ * @since Ant 1.6.2
+ */
+public class RedirectorElement extends DataType {
+
+ /**
+ * Whether the input mapper was set via <code>setOutput</code>.
+ */
+ private boolean usingInput = false;
+
+ /**
+ * Whether the output mapper was set via <code>setOutput</code>.
+ */
+ private boolean usingOutput = false;
+
+ /**
+ * Whether the error mapper was set via <code>setError</code>.
+ */
+ private boolean usingError = false;
+
+ /**
+ * Indicates if standard error should be logged to Ant's log system
+ * rather than the output. This has no effect if standard error is
+ * redirected to a file or property.
+ */
+ private Boolean logError;
+
+ /** The name of the property into which output is to be stored */
+ private String outputProperty;
+
+ /** The name of the property into which error output is to be stored */
+ private String errorProperty;
+
+ /** String from which input is taken */
+ private String inputString;
+
+ /** Flag which indicates if error and output files are to be appended. */
+ private Boolean append;
+
+ /** Flag which indicates that output should be always sent to the log */
+ private Boolean alwaysLog;
+
+ /** Flag which indicates whether files should be created even if empty. */
+ private Boolean createEmptyFiles;
+
+ /** Input file mapper. */
+ private Mapper inputMapper;
+
+ /** Output file mapper. */
+ private Mapper outputMapper;
+
+ /** Error file mapper. */
+ private Mapper errorMapper;
+
+ /** input filter chains. */
+ private Vector<FilterChain> inputFilterChains = new Vector<FilterChain>();
+
+ /** output filter chains. */
+ private Vector<FilterChain> outputFilterChains = new Vector<FilterChain>();
+
+ /** error filter chains. */
+ private Vector<FilterChain> errorFilterChains = new Vector<FilterChain>();
+
+ /** The output encoding */
+ private String outputEncoding;
+
+ /** The error encoding */
+ private String errorEncoding;
+
+ /** The input encoding */
+ private String inputEncoding;
+
+ /** whether to log the inputstring */
+ private Boolean logInputString;
+
+ /** Is the output binary or can we safely split it into lines? */
+ private boolean outputIsBinary = false;
+
+ /**
+ * Add the input file mapper.
+ * @param inputMapper <code>Mapper</code>.
+ */
+ public void addConfiguredInputMapper(Mapper inputMapper) {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ if (this.inputMapper != null) {
+ if (usingInput) {
+ throw new BuildException("attribute \"input\""
+ + " cannot coexist with a nested <inputmapper>");
+ } else {
+ throw new BuildException("Cannot have > 1 <inputmapper>");
+ }
+ }
+ setChecked(false);
+ this.inputMapper = inputMapper;
+ }
+
+ /**
+ * Add the output file mapper.
+ * @param outputMapper <code>Mapper</code>.
+ */
+ public void addConfiguredOutputMapper(Mapper outputMapper) {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ if (this.outputMapper != null) {
+ if (usingOutput) {
+ throw new BuildException("attribute \"output\""
+ + " cannot coexist with a nested <outputmapper>");
+ } else {
+ throw new BuildException("Cannot have > 1 <outputmapper>");
+ }
+ }
+ setChecked(false);
+ this.outputMapper = outputMapper;
+ }
+
+ /**
+ * Add the error file mapper.
+ * @param errorMapper <code>Mapper</code>.
+ */
+ public void addConfiguredErrorMapper(Mapper errorMapper) {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ if (this.errorMapper != null) {
+ if (usingError) {
+ throw new BuildException("attribute \"error\""
+ + " cannot coexist with a nested <errormapper>");
+ } else {
+ throw new BuildException("Cannot have > 1 <errormapper>");
+ }
+ }
+ setChecked(false);
+ this.errorMapper = errorMapper;
+ }
+
+ /**
+ * Make this instance in effect a reference to another instance.
+ *
+ * <p>You must not set another attribute or nest elements inside
+ * this element if you make it a reference.</p>
+ * @param r the reference to use.
+ * @throws BuildException on error.
+ */
+ public void setRefid(Reference r) throws BuildException {
+ if (usingInput
+ || usingOutput
+ || usingError
+ || inputString != null
+ || logError != null
+ || append != null
+ || createEmptyFiles != null
+ || inputEncoding != null
+ || outputEncoding != null
+ || errorEncoding != null
+ || outputProperty != null
+ || errorProperty != null
+ || logInputString != null) {
+ throw tooManyAttributes();
+ }
+ super.setRefid(r);
+ }
+
+ /**
+ * Set the input to use for the task.
+ * @param input the file from which input is read.
+ */
+ public void setInput(File input) {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ if (inputString != null) {
+ throw new BuildException("The \"input\" and \"inputstring\" "
+ + "attributes cannot both be specified");
+ }
+ usingInput = true;
+ inputMapper = createMergeMapper(input);
+ }
+
+ /**
+ * Set the string to use as input
+ * @param inputString the string which is used as the input source
+ */
+ public void setInputString(String inputString) {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ if (usingInput) {
+ throw new BuildException("The \"input\" and \"inputstring\" "
+ + "attributes cannot both be specified");
+ }
+ this.inputString = inputString;
+ }
+
+ /**
+ * Set whether to include the value of the input string in log messages.
+ * Defaults to true.
+ * @param logInputString true or false.
+ * @since Ant 1.7
+ */
+ public void setLogInputString(boolean logInputString) {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ this.logInputString = logInputString ? Boolean.TRUE : Boolean.FALSE;
+ }
+
+ /**
+ * File the output of the process is redirected to. If error is not
+ * redirected, it too will appear in the output.
+ *
+ * @param out the file to which output stream is written.
+ */
+ public void setOutput(File out) {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ if (out == null) {
+ throw new IllegalArgumentException("output file specified as null");
+ }
+ usingOutput = true;
+ outputMapper = createMergeMapper(out);
+ }
+
+ /**
+ * Set the output encoding.
+ * @param outputEncoding <code>String</code>.
+ */
+ public void setOutputEncoding(String outputEncoding) {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ this.outputEncoding = outputEncoding;
+ }
+
+ /**
+ * Set the error encoding.
+ *
+ * @param errorEncoding <code>String</code>.
+ */
+ public void setErrorEncoding(String errorEncoding) {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ this.errorEncoding = errorEncoding;
+ }
+
+ /**
+ * Set the input encoding.
+ * @param inputEncoding <code>String</code>.
+ */
+ public void setInputEncoding(String inputEncoding) {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ this.inputEncoding = inputEncoding;
+ }
+
+ /**
+ * Controls whether error output of exec is logged. This is only useful
+ * when output is being redirected and error output is desired in the
+ * Ant log.
+ * @param logError if true the standard error is sent to the Ant log system
+ * and not sent to output.
+ */
+ public void setLogError(boolean logError) {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ this.logError = ((logError) ? Boolean.TRUE : Boolean.FALSE);
+ }
+
+ /**
+ * Set the file to which standard error is to be redirected.
+ * @param error the file to which error is to be written.
+ */
+ public void setError(File error) {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ if (error == null) {
+ throw new IllegalArgumentException("error file specified as null");
+ }
+ usingError = true;
+ errorMapper = createMergeMapper(error);
+ }
+
+ /**
+ * Property name whose value should be set to the output of
+ * the process.
+ * @param outputProperty the name of the property to be set with the
+ * task's output.
+ */
+ public void setOutputProperty(String outputProperty) {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ this.outputProperty = outputProperty;
+ }
+
+ /**
+ * Whether output should be appended to or overwrite an existing file.
+ * Defaults to false.
+ * @param append if true output and error streams are appended to their
+ * respective files, if specified.
+ */
+ public void setAppend(boolean append) {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ this.append = ((append) ? Boolean.TRUE : Boolean.FALSE);
+ }
+
+ /**
+ * If true, (error and non-error) output will be "teed", redirected
+ * as specified while being sent to Ant's logging mechanism as if no
+ * redirection had taken place. Defaults to false.
+ * @param alwaysLog <code>boolean</code>
+ * @since Ant 1.6.3
+ */
+ public void setAlwaysLog(boolean alwaysLog) {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ this.alwaysLog = ((alwaysLog) ? Boolean.TRUE : Boolean.FALSE);
+ }
+
+ /**
+ * Whether output and error files should be created even when empty.
+ * Defaults to true.
+ * @param createEmptyFiles <code>boolean</code>.
+ */
+ public void setCreateEmptyFiles(boolean createEmptyFiles) {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ this.createEmptyFiles = ((createEmptyFiles)
+ ? Boolean.TRUE : Boolean.FALSE);
+ }
+
+ /**
+ * Property name whose value should be set to the error of
+ * the process.
+ * @param errorProperty the name of the property to be set
+ * with the error output.
+ */
+ public void setErrorProperty(String errorProperty) {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ this.errorProperty = errorProperty;
+ }
+
+ /**
+ * Create a nested input <code>FilterChain</code>.
+ * @return <code>FilterChain</code>.
+ */
+ public FilterChain createInputFilterChain() {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ FilterChain result = new FilterChain();
+ result.setProject(getProject());
+ inputFilterChains.add(result);
+ setChecked(false);
+ return result;
+ }
+
+ /**
+ * Create a nested output <code>FilterChain</code>.
+ * @return <code>FilterChain</code>.
+ */
+ public FilterChain createOutputFilterChain() {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ FilterChain result = new FilterChain();
+ result.setProject(getProject());
+ outputFilterChains.add(result);
+ setChecked(false);
+ return result;
+ }
+
+ /**
+ * Create a nested error <code>FilterChain</code>.
+ * @return <code>FilterChain</code>.
+ */
+ public FilterChain createErrorFilterChain() {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ FilterChain result = new FilterChain();
+ result.setProject(getProject());
+ errorFilterChains.add(result);
+ setChecked(false);
+ return result;
+ }
+
+ /**
+ * Whether to consider the output created by the process binary.
+ *
+ * <p>Binary output will not be split into lines which may make
+ * error and normal output look mixed up when they get written to
+ * the same stream.</p>
+ * @since 1.9.4
+ */
+ public void setBinaryOutput(boolean b) {
+ outputIsBinary = b;
+ }
+
+ /**
+ * Configure the specified <code>Redirector</code>.
+ * @param redirector <code>Redirector</code>.
+ */
+ public void configure(Redirector redirector) {
+ configure(redirector, null);
+ }
+
+ /**
+ * Configure the specified <code>Redirector</code>
+ * for the specified sourcefile.
+ * @param redirector <code>Redirector</code>.
+ * @param sourcefile <code>String</code>.
+ */
+ public void configure(Redirector redirector, String sourcefile) {
+ if (isReference()) {
+ getRef().configure(redirector, sourcefile);
+ return;
+ }
+ dieOnCircularReference();
+ if (alwaysLog != null) {
+ redirector.setAlwaysLog(alwaysLog.booleanValue());
+ }
+ if (logError != null) {
+ redirector.setLogError(logError.booleanValue());
+ }
+ if (append != null) {
+ redirector.setAppend(append.booleanValue());
+ }
+ if (createEmptyFiles != null) {
+ redirector.setCreateEmptyFiles(createEmptyFiles.booleanValue());
+ }
+ if (outputProperty != null) {
+ redirector.setOutputProperty(outputProperty);
+ }
+ if (errorProperty != null) {
+ redirector.setErrorProperty(errorProperty);
+ }
+ if (inputString != null) {
+ redirector.setInputString(inputString);
+ }
+ if (logInputString != null) {
+ redirector.setLogInputString(logInputString.booleanValue());
+ }
+ if (inputMapper != null) {
+ String[] inputTargets = null;
+ try {
+ inputTargets =
+ inputMapper.getImplementation().mapFileName(sourcefile);
+ } catch (NullPointerException enPeaEx) {
+ if (sourcefile != null) {
+ throw enPeaEx;
+ }
+ }
+ if (inputTargets != null && inputTargets.length > 0) {
+ redirector.setInput(toFileArray(inputTargets));
+ }
+ }
+ if (outputMapper != null) {
+ String[] outputTargets = null;
+ try {
+ outputTargets =
+ outputMapper.getImplementation().mapFileName(sourcefile);
+ } catch (NullPointerException enPeaEx) {
+ if (sourcefile != null) {
+ throw enPeaEx;
+ }
+ }
+ if (outputTargets != null && outputTargets.length > 0) {
+ redirector.setOutput(toFileArray(outputTargets));
+ }
+ }
+ if (errorMapper != null) {
+ String[] errorTargets = null;
+ try {
+ errorTargets =
+ errorMapper.getImplementation().mapFileName(sourcefile);
+ } catch (NullPointerException enPeaEx) {
+ if (sourcefile != null) {
+ throw enPeaEx;
+ }
+ }
+ if (errorTargets != null && errorTargets.length > 0) {
+ redirector.setError(toFileArray(errorTargets));
+ }
+ }
+ if (inputFilterChains.size() > 0) {
+ redirector.setInputFilterChains(inputFilterChains);
+ }
+ if (outputFilterChains.size() > 0) {
+ redirector.setOutputFilterChains(outputFilterChains);
+ }
+ if (errorFilterChains.size() > 0) {
+ redirector.setErrorFilterChains(errorFilterChains);
+ }
+ if (inputEncoding != null) {
+ redirector.setInputEncoding(inputEncoding);
+ }
+ if (outputEncoding != null) {
+ redirector.setOutputEncoding(outputEncoding);
+ }
+ if (errorEncoding != null) {
+ redirector.setErrorEncoding(errorEncoding);
+ }
+ redirector.setBinaryOutput(outputIsBinary);
+ }
+
+ /**
+ * Create a merge mapper pointing to the specified destination file.
+ * @param destfile <code>File</code>
+ * @return <code>Mapper</code>.
+ */
+ protected Mapper createMergeMapper(File destfile) {
+ Mapper result = new Mapper(getProject());
+ result.setClassname(
+ org.apache.tools.ant.util.MergingMapper.class.getName());
+ result.setTo(destfile.getAbsolutePath());
+ return result;
+ }
+
+ /**
+ * Return a <code>File[]</code> from the specified set of filenames.
+ * @param name <code>String[]</code>
+ * @return <code>File[]</code>.
+ */
+ protected File[] toFileArray(String[] name) {
+ if (name == null) {
+ return null;
+ }
+ //remove any null elements
+ ArrayList<File> list = new ArrayList<File>(name.length);
+ for (int i = 0; i < name.length; i++) {
+ if (name[i] != null) {
+ list.add(getProject().resolveFile(name[i]));
+ }
+ }
+ return (File[]) (list.toArray(new File[list.size()]));
+ }
+
+ /**
+ * Overrides the version of DataType to recurse on all DataType
+ * child elements that may have been added.
+ * @param stk the stack of data types to use (recursively).
+ * @param p the project to use to dereference the references.
+ * @throws BuildException on error.
+ */
+ protected void dieOnCircularReference(Stack<Object> stk, Project p)
+ throws BuildException {
+ if (isChecked()) {
+ return;
+ }
+ if (isReference()) {
+ super.dieOnCircularReference(stk, p);
+ } else {
+ Mapper[] m = new Mapper[] {inputMapper, outputMapper, errorMapper};
+ for (int i = 0; i < m.length; i++) {
+ if (m[i] != null) {
+ stk.push(m[i]);
+ m[i].dieOnCircularReference(stk, p);
+ stk.pop();
+ }
+ }
+ @SuppressWarnings("unchecked")
+ final List<? extends List<FilterChain>> filterChainLists = Arrays
+ .<List<FilterChain>> asList(inputFilterChains, outputFilterChains,
+ errorFilterChains);
+ for (List<FilterChain> filterChains : filterChainLists) {
+ if (filterChains != null) {
+ for (FilterChain fc : filterChains) {
+ pushAndInvokeCircularReferenceCheck(fc, stk, p);
+ }
+ }
+ }
+ setChecked(true);
+ }
+ }
+
+ /**
+ * Perform the check for circular references, returning the
+ * referenced RedirectorElement.
+ * @return the referenced RedirectorElement.
+ */
+ private RedirectorElement getRef() {
+ return (RedirectorElement) getCheckedRef();
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/Reference.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/Reference.java
new file mode 100644
index 00000000..e5e9b25c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/Reference.java
@@ -0,0 +1,134 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+
+/**
+ * Class to hold a reference to another object in the project.
+ *
+ */
+public class Reference {
+
+ private String refid;
+ private Project project;
+
+ /**
+ * Create a reference.
+ * @deprecated since 1.7.
+ * Please use {@link Reference#Reference(Project,String)}
+ * instead.
+ */
+ public Reference() {
+ }
+
+ /**
+ * Create a reference to a named ID.
+ * @param id the name of this reference
+ * @deprecated since 1.7.
+ * Please use {@link Reference#Reference(Project,String)}
+ * instead.
+ */
+ public Reference(String id) {
+ setRefId(id);
+ }
+
+ /**
+ * Create a reference to a named ID in a particular project.
+ * @param p the project this reference is associated with
+ * @param id the name of this reference
+ * @since Ant 1.6.3
+ */
+ public Reference(Project p, String id) {
+ setRefId(id);
+ setProject(p);
+ }
+
+ /**
+ * Set the reference id. Should not normally be necessary;
+ * use {@link Reference#Reference(Project, String)}.
+ * @param id the reference id to use
+ */
+ public void setRefId(String id) {
+ refid = id;
+ }
+
+ /**
+ * Get the reference id of this reference.
+ * @return the reference id
+ */
+ public String getRefId() {
+ return refid;
+ }
+
+ /**
+ * Set the associated project. Should not normally be necessary;
+ * use {@link Reference#Reference(Project,String)}.
+ * @param p the project to use
+ * @since Ant 1.6.3
+ */
+ public void setProject(Project p) {
+ this.project = p;
+ }
+
+ /**
+ * Get the associated project, if any; may be null.
+ * @return the associated project
+ * @since Ant 1.6.3
+ */
+ public Project getProject() {
+ return project;
+ }
+
+ /**
+ * Resolve the reference, using the associated project if
+ * it set, otherwise use the passed in project.
+ * @param fallback the fallback project to use if the project attribute of
+ * reference is not set.
+ * @return the dereferenced object.
+ * @throws BuildException if the reference cannot be dereferenced.
+ */
+ public Object getReferencedObject(Project fallback) throws BuildException {
+ if (refid == null) {
+ throw new BuildException("No reference specified");
+ }
+
+ Object o = project == null ? fallback.getReference(refid) : project.getReference(refid);
+ if (o == null) {
+ throw new BuildException("Reference " + refid + " not found.");
+ }
+ return o;
+ }
+
+ /**
+ * Resolve the reference, looking in the associated project.
+ * @see Project#getReference
+ * @return the dereferenced object.
+ * @throws BuildException if the project is null or the reference cannot be dereferenced
+ * @since Ant 1.6.3
+ */
+ public Object getReferencedObject() throws BuildException {
+ if (project == null) {
+ throw new BuildException("No project set on reference to " + refid);
+ }
+ return getReferencedObject(project);
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/RegularExpression.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/RegularExpression.java
new file mode 100644
index 00000000..18ee3f1f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/RegularExpression.java
@@ -0,0 +1,141 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types;
+
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.util.regexp.Regexp;
+import org.apache.tools.ant.util.regexp.RegexpFactory;
+
+/**
+ * A regular expression datatype. Keeps an instance of the
+ * compiled expression for speed purposes. This compiled
+ * expression is lazily evaluated (it is compiled the first
+ * time it is needed). The syntax is the dependent on which
+ * regular expression type you are using. The system property
+ * "ant.regexp.regexpimpl" will be the classname of the implementation
+ * that will be used.
+ *
+ * <pre>
+ * Available implementations:
+ *
+ * org.apache.tools.ant.util.regexp.Jdk14RegexpRegexp (default)
+ * Based on the JDK's built-in regular expression package
+ *
+ * org.apache.tools.ant.util.regexp.JakartaOroRegexp
+ * Based on the jakarta-oro package
+ *
+ * org.apache.tools.ant.util.regexp.JakartaRegexpRegexp
+ * Based on the jakarta-regexp package
+ * </pre>
+ *
+ * <pre>
+ * &lt;regexp [ [id="id"] pattern="expression" | refid="id" ]
+ * /&gt;
+ * </pre>
+ *
+ * @see org.apache.oro.text.regex.Perl5Compiler
+ * @see org.apache.regexp.RE
+ * @see java.util.regex.Pattern
+ *
+ * @see org.apache.tools.ant.util.regexp.Regexp
+ *
+ * @ant.datatype name="regexp"
+ */
+public class RegularExpression extends DataType {
+ /** Name of this data type */
+ public static final String DATA_TYPE_NAME = "regexp";
+ private boolean alreadyInit = false;
+
+ // The regular expression factory
+ private static final RegexpFactory FACTORY = new RegexpFactory();
+
+ private Regexp regexp = null;
+ // temporary variable
+ private String myPattern;
+ private boolean setPatternPending = false;
+
+ /**
+ * default constructor
+ */
+ public RegularExpression() {
+ }
+
+ private void init(Project p) {
+ if (!alreadyInit) {
+ this.regexp = FACTORY.newRegexp(p);
+ alreadyInit = true;
+ }
+ }
+ private void setPattern() {
+ if (setPatternPending) {
+ regexp.setPattern(myPattern);
+ setPatternPending = false;
+ }
+ }
+ /**
+ * sets the regular expression pattern
+ * @param pattern regular expression pattern
+ */
+ public void setPattern(String pattern) {
+ if (regexp == null) {
+ myPattern = pattern;
+ setPatternPending = true;
+ } else {
+ regexp.setPattern(pattern);
+ }
+ }
+
+ /***
+ * Gets the pattern string for this RegularExpression in the
+ * given project.
+ * @param p project
+ * @return pattern
+ */
+ public String getPattern(Project p) {
+ init(p);
+ if (isReference()) {
+ return getRef(p).getPattern(p);
+ }
+ setPattern();
+ return regexp.getPattern();
+ }
+
+ /**
+ * provides a reference to the Regexp contained in this
+ * @param p project
+ * @return Regexp instance associated with this RegularExpression instance
+ */
+ public Regexp getRegexp(Project p) {
+ init(p);
+ if (isReference()) {
+ return getRef(p).getRegexp(p);
+ }
+ setPattern();
+ return this.regexp;
+ }
+
+ /***
+ * Get the RegularExpression this reference refers to in
+ * the given project. Check for circular references too
+ * @param p project
+ * @return resolved RegularExpression instance
+ */
+ public RegularExpression getRef(Project p) {
+ return (RegularExpression) getCheckedRef(p);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/Resource.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/Resource.java
new file mode 100644
index 00000000..426a5b9e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/Resource.java
@@ -0,0 +1,439 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.math.BigInteger;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+import org.apache.tools.ant.types.resources.FileProvider;
+
+/**
+ * Describes a "File-like" resource (File, ZipEntry, etc.).
+ *
+ * This class is meant to be used by classes needing to record path
+ * and date/time information about a file, a zip entry or some similar
+ * resource (URL, archive in a version control repository, ...).
+ *
+ * @since Ant 1.5.2
+ * @see org.apache.tools.ant.types.resources.Touchable
+ */
+public class Resource extends DataType implements Comparable<Resource>, ResourceCollection {
+
+ /** Constant unknown size */
+ public static final long UNKNOWN_SIZE = -1;
+
+ /** Constant unknown datetime for getLastModified */
+ public static final long UNKNOWN_DATETIME = 0L;
+
+ /** Magic number */
+ protected static final int MAGIC = getMagicNumber("Resource".getBytes());
+
+ private static final int NULL_NAME = getMagicNumber("null name".getBytes());
+
+ /**
+ * Create a "magic number" for use in hashCode calculations.
+ * @param seed byte[] to seed with.
+ * @return a magic number as int.
+ */
+ protected static int getMagicNumber(byte[] seed) {
+ return new BigInteger(seed).intValue();
+ }
+
+ private String name = null;
+ private Boolean exists = null;
+ private Long lastmodified = null;
+ private Boolean directory = null;
+ private Long size = null;
+
+ /**
+ * Default constructor.
+ */
+ public Resource() {
+ }
+
+ /**
+ * Only sets the name.
+ *
+ * <p>This is a dummy, used for not existing resources.</p>
+ *
+ * @param name relative path of the resource. Expects
+ * &quot;/&quot; to be used as the directory separator.
+ */
+ public Resource(String name) {
+ this(name, false, 0, false);
+ }
+
+ /**
+ * Sets the name, lastmodified flag, and exists flag.
+ *
+ * @param name relative path of the resource. Expects
+ * &quot;/&quot; to be used as the directory separator.
+ * @param exists if true, this resource exists.
+ * @param lastmodified the last modification time of this resource.
+ */
+ public Resource(String name, boolean exists, long lastmodified) {
+ this(name, exists, lastmodified, false);
+ }
+
+ /**
+ * Sets the name, lastmodified flag, exists flag, and directory flag.
+ *
+ * @param name relative path of the resource. Expects
+ * &quot;/&quot; to be used as the directory separator.
+ * @param exists if true the resource exists
+ * @param lastmodified the last modification time of the resource
+ * @param directory if true, this resource is a directory
+ */
+ public Resource(String name, boolean exists, long lastmodified, boolean directory) {
+ this(name, exists, lastmodified, directory, UNKNOWN_SIZE);
+ }
+
+ /**
+ * Sets the name, lastmodified flag, exists flag, directory flag, and size.
+ *
+ * @param name relative path of the resource. Expects
+ * &quot;/&quot; to be used as the directory separator.
+ * @param exists if true the resource exists
+ * @param lastmodified the last modification time of the resource
+ * @param directory if true, this resource is a directory
+ * @param size the size of this resource.
+ */
+ public Resource(String name, boolean exists, long lastmodified, boolean directory, long size) {
+ this.name = name;
+ setName(name);
+ setExists(exists);
+ setLastModified(lastmodified);
+ setDirectory(directory);
+ setSize(size);
+ }
+
+ /**
+ * Name attribute will contain the path of a file relative to the
+ * root directory of its fileset or the recorded path of a zip
+ * entry.
+ *
+ * <p>example for a file with fullpath /var/opt/adm/resource.txt
+ * in a file set with root dir /var/opt it will be
+ * adm/resource.txt.</p>
+ *
+ * <p>&quot;/&quot; will be used as the directory separator.</p>
+ * @return the name of this resource.
+ */
+ public String getName() {
+ return isReference() ? ((Resource) getCheckedRef()).getName() : name;
+ }
+
+ /**
+ * Set the name of this Resource.
+ * @param name relative path of the resource. Expects
+ * &quot;/&quot; to be used as the directory separator.
+ */
+ public void setName(String name) {
+ checkAttributesAllowed();
+ this.name = name;
+ }
+
+ /**
+ * The exists attribute tells whether a resource exists.
+ * @return true if this resource exists.
+ */
+ public boolean isExists() {
+ if (isReference()) {
+ return ((Resource) getCheckedRef()).isExists();
+ }
+ //default true:
+ return exists == null || exists.booleanValue();
+ }
+
+ /**
+ * Set the exists attribute.
+ * @param exists if true, this resource exists.
+ */
+ public void setExists(boolean exists) {
+ checkAttributesAllowed();
+ this.exists = exists ? Boolean.TRUE : Boolean.FALSE;
+ }
+
+ /**
+ * Tells the modification time in milliseconds since 01.01.1970 (the "epoch").
+ *
+ * @return the modification time, if that is meaningful
+ * (e.g. for a file resource which exists);
+ * 0 if the resource does not exist, to mirror the behavior
+ * of {@link java.io.File#lastModified};
+ * or 0 if the notion of modification time is meaningless for this class
+ * of resource (e.g. an inline string)
+ */
+ public long getLastModified() {
+ if (isReference()) {
+ return ((Resource) getCheckedRef()).getLastModified();
+ }
+ if (!isExists() || lastmodified == null) {
+ return UNKNOWN_DATETIME;
+ }
+ long result = lastmodified.longValue();
+ return result < UNKNOWN_DATETIME ? UNKNOWN_DATETIME : result;
+ }
+
+ /**
+ * Set the last modification attribute.
+ * @param lastmodified the modification time in milliseconds since 01.01.1970.
+ */
+ public void setLastModified(long lastmodified) {
+ checkAttributesAllowed();
+ this.lastmodified = new Long(lastmodified);
+ }
+
+ /**
+ * Tells if the resource is a directory.
+ * @return boolean flag indicating if the resource is a directory.
+ */
+ public boolean isDirectory() {
+ if (isReference()) {
+ return ((Resource) getCheckedRef()).isDirectory();
+ }
+ //default false:
+ return directory != null && directory.booleanValue();
+ }
+
+ /**
+ * Set the directory attribute.
+ * @param directory if true, this resource is a directory.
+ */
+ public void setDirectory(boolean directory) {
+ checkAttributesAllowed();
+ this.directory = directory ? Boolean.TRUE : Boolean.FALSE;
+ }
+
+ /**
+ * Set the size of this Resource.
+ * @param size the size, as a long.
+ * @since Ant 1.6.3
+ */
+ public void setSize(long size) {
+ checkAttributesAllowed();
+ this.size = new Long(size > UNKNOWN_SIZE ? size : UNKNOWN_SIZE);
+ }
+
+ /**
+ * Get the size of this Resource.
+ * @return the size, as a long, 0 if the Resource does not exist (for
+ * compatibility with java.io.File), or UNKNOWN_SIZE if not known.
+ * @since Ant 1.6.3
+ */
+ public long getSize() {
+ if (isReference()) {
+ return ((Resource) getCheckedRef()).getSize();
+ }
+ return isExists()
+ ? (size != null ? size.longValue() : UNKNOWN_SIZE)
+ : 0L;
+ }
+
+ /**
+ * Clone this Resource.
+ * @return copy of this.
+ */
+ public Object clone() {
+ try {
+ return super.clone();
+ } catch (CloneNotSupportedException e) {
+ throw new UnsupportedOperationException(
+ "CloneNotSupportedException for a Resource caught. "
+ + "Derived classes must support cloning.");
+ }
+ }
+
+ /**
+ * Delegates to a comparison of names.
+ * @param other the object to compare to.
+ * @return a negative integer, zero, or a positive integer as this Resource
+ * is less than, equal to, or greater than the specified Resource.
+ * @since Ant 1.6
+ */
+ public int compareTo(Resource other) {
+ if (isReference()) {
+ return ((Resource) getCheckedRef()).compareTo(other);
+ }
+ return toString().compareTo(other.toString());
+ }
+
+ /**
+ * Implement basic Resource equality.
+ * @param other the object to check against.
+ * @return true if the specified Object is equal to this Resource.
+ * @since Ant 1.7
+ */
+ public boolean equals(Object other) {
+ if (isReference()) {
+ return getCheckedRef().equals(other);
+ }
+ return other != null && other.getClass().equals(getClass())
+ && compareTo((Resource) other) == 0;
+ }
+
+ /**
+ * Get the hash code for this Resource.
+ * @return hash code as int.
+ * @since Ant 1.7
+ */
+ public int hashCode() {
+ if (isReference()) {
+ return getCheckedRef().hashCode();
+ }
+ String name = getName();
+ return MAGIC * (name == null ? NULL_NAME : name.hashCode());
+ }
+
+ /**
+ * Get an InputStream for the Resource.
+ * @return an InputStream containing this Resource's content.
+ * @throws IOException if unable to provide the content of this
+ * Resource as a stream.
+ * @throws UnsupportedOperationException if InputStreams are not
+ * supported for this Resource type.
+ * @since Ant 1.7
+ */
+ public InputStream getInputStream() throws IOException {
+ if (isReference()) {
+ return ((Resource) getCheckedRef()).getInputStream();
+ }
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Get an OutputStream for the Resource.
+ * @return an OutputStream to which content can be written.
+ * @throws IOException if unable to provide the content of this
+ * Resource as a stream.
+ * @throws UnsupportedOperationException if OutputStreams are not
+ * supported for this Resource type.
+ * @since Ant 1.7
+ */
+ public OutputStream getOutputStream() throws IOException {
+ if (isReference()) {
+ return ((Resource) getCheckedRef()).getOutputStream();
+ }
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Fulfill the ResourceCollection contract.
+ * @return an Iterator of Resources.
+ * @since Ant 1.7
+ */
+ public Iterator<Resource> iterator() {
+ return isReference() ? ((Resource) getCheckedRef()).iterator()
+ : new Iterator<Resource>() {
+ private boolean done = false;
+ public boolean hasNext() {
+ return !done;
+ }
+ public Resource next() {
+ if (done) {
+ throw new NoSuchElementException();
+ }
+ done = true;
+ return Resource.this;
+ }
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+ };
+ }
+
+ /**
+ * Fulfill the ResourceCollection contract.
+ * @return the size of this ResourceCollection.
+ * @since Ant 1.7
+ */
+ public int size() {
+ return isReference() ? ((Resource) getCheckedRef()).size() : 1;
+ }
+
+ /**
+ * Fulfill the ResourceCollection contract.
+ * @return whether this Resource is a FileProvider.
+ * @since Ant 1.7
+ */
+ public boolean isFilesystemOnly() {
+ return (isReference() && ((Resource) getCheckedRef()).isFilesystemOnly())
+ || this.as(FileProvider.class) != null;
+ }
+
+ /**
+ * Get the string representation of this Resource.
+ * @return this Resource formatted as a String.
+ * @since Ant 1.7
+ */
+ public String toString() {
+ if (isReference()) {
+ return getCheckedRef().toString();
+ }
+ String n = getName();
+ return n == null ? "(anonymous)" : n;
+ }
+
+ /**
+ * Get a long String representation of this Resource.
+ * This typically should be the value of <code>toString()</code>
+ * prefixed by a type description.
+ * @return this Resource formatted as a long String.
+ * @since Ant 1.7
+ */
+ public final String toLongString() {
+ return isReference() ? ((Resource) getCheckedRef()).toLongString()
+ : getDataTypeName() + " \"" + toString() + '"';
+ }
+
+ /**
+ * Overrides the base version.
+ * @param r the Reference to set.
+ */
+ public void setRefid(Reference r) {
+ if (name != null
+ || exists != null
+ || lastmodified != null
+ || directory != null
+ || size != null) {
+ throw tooManyAttributes();
+ }
+ super.setRefid(r);
+ }
+
+ /**
+ * Returns a view of this resource that implements the interface
+ * given as the argument or null if there is no such view.
+ *
+ * <p>This allows extension interfaces to be added to resources
+ * without growing the number of permutations of interfaces
+ * decorators/adapters need to implement.</p>
+ *
+ * <p>This implementation of the method will return the current
+ * instance itself if it can be assigned to the given class.</p>
+ *
+ * @since Ant 1.8.0
+ */
+ public <T> T as(Class<T> clazz) {
+ return clazz.isAssignableFrom(getClass()) ? clazz.cast(this) : null;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/ResourceCollection.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/ResourceCollection.java
new file mode 100644
index 00000000..a82c8b59
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/ResourceCollection.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types;
+
+import java.util.Iterator;
+
+/**
+ * Interface describing a collection of Resources.
+ * @since Ant 1.7
+ */
+public interface ResourceCollection extends Iterable<Resource> {
+
+ /**
+ * Gets the contents of this collection.
+ * @return all resources in the collection
+ */
+ Iterator<Resource> iterator();
+
+ /**
+ * Learn the number of contained Resources.
+ * @return number of elements as int.
+ */
+ int size();
+
+ /**
+ * Indicate whether this ResourceCollection is composed entirely of
+ * Resources accessible via local filesystem conventions. If true,
+ * all resources returned from this collection should
+ * respond with a {@link org.apache.tools.ant.types.resources.FileProvider}
+ * when asked via {@link Resource#as}.
+ * @return whether this is a filesystem-only resource collection.
+ */
+ boolean isFilesystemOnly();
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/ResourceFactory.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/ResourceFactory.java
new file mode 100644
index 00000000..515318ef
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/ResourceFactory.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types;
+
+/**
+ * this interface should be implemented by classes (Scanners) needing
+ * to deliver information about resources.
+ *
+ * @since Ant 1.5.2
+ */
+public interface ResourceFactory {
+
+ /**
+ * Query a resource (file, zipentry, ...) by name
+ *
+ * @param name relative path of the resource about which
+ * information is sought. Expects &quot;/&quot; to be used as the
+ * directory separator.
+ * @return instance of Resource; the exists attribute of Resource
+ * will tell whether the sought resource exists
+ */
+ Resource getResource(String name);
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/ResourceLocation.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/ResourceLocation.java
new file mode 100644
index 00000000..c5a44ea2
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/ResourceLocation.java
@@ -0,0 +1,106 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types;
+
+import java.net.URL;
+
+/**
+ * <p>Helper class to handle the <code>&lt;dtd&gt;</code> and
+ * <code>&lt;entity&gt;</code> nested elements. These correspond to
+ * the <code>PUBLIC</code> and <code>URI</code> catalog entry types,
+ * respectively, as defined in the <a
+ * href="http://oasis-open.org/committees/entity/spec-2001-08-06.html">
+ * OASIS "Open Catalog" standard</a>.</p>
+ *
+ * <p>Possible Future Enhancements:
+ * <ul>
+ * <li>Bring the Ant element names into conformance with the OASIS standard</li>
+ * <li>Add support for additional OASIS catalog entry types</li>
+ * </ul>
+ * </p>
+ *
+ * @see org.apache.xml.resolver.Catalog
+ * @since Ant 1.6
+ */
+public class ResourceLocation {
+
+ //-- Fields ----------------------------------------------------------------
+ /** publicId of the dtd/entity. */
+ private String publicId = null;
+
+ /** location of the dtd/entity - a file/resource/URL. */
+ private String location = null;
+
+ /**
+ * base URL of the dtd/entity, or null. If null, the Ant project
+ * basedir is assumed. If the location specifies a relative
+ * URL/pathname, it is resolved using the base. The default base
+ * for an external catalog file is the directory in which it is
+ * located.
+ */
+ private URL base = null;
+
+ //-- Methods ---------------------------------------------------------------
+
+ /**
+ * @param publicId uniquely identifies the resource.
+ */
+ public void setPublicId(String publicId) {
+ this.publicId = publicId;
+ }
+
+ /**
+ * @param location the location of the resource associated with the
+ * publicId.
+ */
+ public void setLocation(String location) {
+ this.location = location;
+ }
+
+ /**
+ * @param base the base URL of the resource associated with the
+ * publicId. If the location specifies a relative URL/pathname,
+ * it is resolved using the base. The default base for an
+ * external catalog file is the directory in which it is located.
+ */
+ public void setBase(URL base) {
+ this.base = base;
+ }
+
+ /**
+ * @return the publicId of the resource.
+ */
+ public String getPublicId() {
+ return publicId;
+ }
+
+ /**
+ * @return the location of the resource identified by the publicId.
+ */
+ public String getLocation() {
+ return location;
+ }
+
+ /**
+ * @return the base of the resource identified by the publicId.
+ */
+ public URL getBase() {
+ return base;
+ }
+
+} //-- ResourceLocation
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/Substitution.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/Substitution.java
new file mode 100644
index 00000000..343f4c49
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/Substitution.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types;
+
+
+import org.apache.tools.ant.Project;
+
+/***
+ * A regular expression substitution datatype. It is an expression
+ * that is meant to replace a regular expression.
+ *
+ * <pre>
+ * &lt;substitution [ [id="id"] expression="expression" | refid="id" ]
+ * /&gt;
+ * </pre>
+ *
+ * @see org.apache.oro.text.regex.Perl5Substitution
+ */
+public class Substitution extends DataType {
+ /** The name of this data type */
+ public static final String DATA_TYPE_NAME = "substitution";
+
+ private String expression;
+
+ /** Constructor for Substitution. */
+ public Substitution() {
+ this.expression = null;
+ }
+
+ /**
+ * Set the pattern string for this regular expression substitution.
+ * @param expression the regular expression to use
+ */
+ public void setExpression(String expression) {
+ this.expression = expression;
+ }
+
+ /***
+ * Gets the pattern string for this RegularExpression in the
+ * given project.
+ * @param p the project to look for the regular expression if this object is
+ * a reference
+ * @return the pattern string
+ */
+ public String getExpression(Project p) {
+ if (isReference()) {
+ return getRef(p).getExpression(p);
+ }
+
+ return expression;
+ }
+
+ /***
+ * Get the RegularExpression this reference refers to in
+ * the given project. Check for circular references too.
+ * @param p the project to look for the regular expression reference
+ * @return the resolved reference
+ */
+ public Substitution getRef(Project p) {
+ return (Substitution) getCheckedRef(p);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/TarFileSet.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/TarFileSet.java
new file mode 100644
index 00000000..6446e9bf
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/TarFileSet.java
@@ -0,0 +1,269 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+
+/**
+ * A TarFileSet is a FileSet with extra attributes useful in the context of
+ * Tar/Jar tasks.
+ *
+ * A TarFileSet extends FileSets with the ability to extract a subset of the
+ * entries of a Tar file for inclusion in another Tar file. It also includes
+ * a prefix attribute which is prepended to each entry in the output Tar file.
+ *
+ */
+public class TarFileSet extends ArchiveFileSet {
+
+ private boolean userNameSet;
+ private boolean groupNameSet;
+ private boolean userIdSet;
+ private boolean groupIdSet;
+
+ private String userName = "";
+ private String groupName = "";
+ private int uid;
+ private int gid;
+
+ /** Constructor for TarFileSet */
+ public TarFileSet() {
+ super();
+ }
+
+ /**
+ * Constructor using a fileset argument.
+ * @param fileset the fileset to use
+ */
+ protected TarFileSet(FileSet fileset) {
+ super(fileset);
+ }
+
+ /**
+ * Constructor using a tarfileset argument.
+ * @param fileset the tarfileset to use
+ */
+ protected TarFileSet(TarFileSet fileset) {
+ super(fileset);
+ }
+
+ /**
+ * The username for the tar entry
+ * This is not the same as the UID.
+ * @param userName the user name for the tar entry.
+ */
+ public void setUserName(String userName) {
+ checkTarFileSetAttributesAllowed();
+ userNameSet = true;
+ this.userName = userName;
+ }
+
+ /**
+ * @return the user name for the tar entry
+ */
+ public String getUserName() {
+ if (isReference()) {
+ return ((TarFileSet) getCheckedRef()).getUserName();
+ }
+ return userName;
+ }
+
+ /**
+ * @return whether the user name has been explicitly set.
+ */
+ public boolean hasUserNameBeenSet() {
+ return userNameSet;
+ }
+
+ /**
+ * The uid for the tar entry
+ * This is not the same as the User name.
+ * @param uid the id of the user for the tar entry.
+ */
+ public void setUid(int uid) {
+ checkTarFileSetAttributesAllowed();
+ userIdSet = true;
+ this.uid = uid;
+ }
+
+ /**
+ * @return the uid for the tar entry
+ */
+ public int getUid() {
+ if (isReference()) {
+ return ((TarFileSet) getCheckedRef()).getUid();
+ }
+ return uid;
+ }
+
+ /**
+ * @return whether the user id has been explicitly set.
+ */
+ public boolean hasUserIdBeenSet() {
+ return userIdSet;
+ }
+
+ /**
+ * The groupname for the tar entry; optional, default=""
+ * This is not the same as the GID.
+ * @param groupName the group name string.
+ */
+ public void setGroup(String groupName) {
+ checkTarFileSetAttributesAllowed();
+ groupNameSet = true;
+ this.groupName = groupName;
+ }
+
+ /**
+ * @return the group name string.
+ */
+ public String getGroup() {
+ if (isReference()) {
+ return ((TarFileSet) getCheckedRef()).getGroup();
+ }
+ return groupName;
+ }
+
+ /**
+ * @return whether the group name has been explicitly set.
+ */
+ public boolean hasGroupBeenSet() {
+ return groupNameSet;
+ }
+
+ /**
+ * The GID for the tar entry; optional, default="0"
+ * This is not the same as the group name.
+ * @param gid the group id.
+ */
+ public void setGid(int gid) {
+ checkTarFileSetAttributesAllowed();
+ groupIdSet = true;
+ this.gid = gid;
+ }
+
+ /**
+ * @return the group identifier.
+ */
+ public int getGid() {
+ if (isReference()) {
+ return ((TarFileSet) getCheckedRef()).getGid();
+ }
+ return gid;
+ }
+
+ /**
+ * @return whether the group id has been explicitly set.
+ */
+ public boolean hasGroupIdBeenSet() {
+ return groupIdSet;
+ }
+
+ /**
+ * Create a new scanner.
+ * @return the created scanner.
+ */
+ protected ArchiveScanner newArchiveScanner() {
+ TarScanner zs = new TarScanner();
+ zs.setEncoding(getEncoding());
+ return zs;
+ }
+
+ /**
+ * Makes this instance in effect a reference to another instance.
+ *
+ * <p>You must not set another attribute or nest elements inside
+ * this element if you make it a reference.</p>
+ * @param r the <code>Reference</code> to use.
+ * @throws BuildException on error
+ */
+ public void setRefid(Reference r) throws BuildException {
+ if (userNameSet || userIdSet || groupNameSet || groupIdSet) {
+ throw tooManyAttributes();
+ }
+ super.setRefid(r);
+ }
+
+ /**
+ * A TarFileset accepts another TarFileSet or a FileSet as reference
+ * FileSets are often used by the war task for the lib attribute
+ * @param p the project to use
+ * @return the abstract fileset instance
+ */
+ protected AbstractFileSet getRef(Project p) {
+ dieOnCircularReference(p);
+ Object o = getRefid().getReferencedObject(p);
+ if (o instanceof TarFileSet) {
+ return (AbstractFileSet) o;
+ } else if (o instanceof FileSet) {
+ TarFileSet zfs = new TarFileSet((FileSet) o);
+ configureFileSet(zfs);
+ return zfs;
+ } else {
+ String msg = getRefid().getRefId() + " doesn\'t denote a tarfileset or a fileset";
+ throw new BuildException(msg);
+ }
+ }
+
+ /**
+ * Configure a fileset based on this fileset.
+ * If the fileset is a TarFileSet copy in the tarfileset
+ * specific attributes.
+ * @param zfs the archive fileset to configure.
+ */
+ protected void configureFileSet(ArchiveFileSet zfs) {
+ super.configureFileSet(zfs);
+ if (zfs instanceof TarFileSet) {
+ TarFileSet tfs = (TarFileSet) zfs;
+ tfs.setUserName(userName);
+ tfs.setGroup(groupName);
+ tfs.setUid(uid);
+ tfs.setGid(gid);
+ }
+ }
+
+ /**
+ * Return a TarFileSet that has the same properties
+ * as this one.
+ * @return the cloned tarFileSet
+ */
+ public Object clone() {
+ if (isReference()) {
+ return ((TarFileSet) getRef(getProject())).clone();
+ } else {
+ return super.clone();
+ }
+ }
+
+ /**
+ * A check attributes for TarFileSet.
+ * If there is a reference, and
+ * it is a TarFileSet, the tar fileset attributes
+ * cannot be used.
+ */
+ private void checkTarFileSetAttributesAllowed() {
+ if (getProject() == null
+ || (isReference()
+ && (getRefid().getReferencedObject(
+ getProject())
+ instanceof TarFileSet))) {
+ checkAttributesAllowed();
+ }
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/TarScanner.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/TarScanner.java
new file mode 100644
index 00000000..a3c7f6d5
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/TarScanner.java
@@ -0,0 +1,87 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types;
+
+import java.io.IOException;
+import java.util.Map;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.types.resources.TarResource;
+import org.apache.tools.ant.util.FileUtils;
+import org.apache.tools.tar.TarEntry;
+import org.apache.tools.tar.TarInputStream;
+
+/**
+ * Scans tar archives for resources.
+ */
+public class TarScanner extends ArchiveScanner {
+
+ /**
+ * Fills the file and directory maps with resources read from the
+ * archive.
+ *
+ * @param src the archive to scan.
+ * @param encoding encoding used to encode file names inside the archive.
+ * @param fileEntries Map (name to resource) of non-directory
+ * resources found inside the archive.
+ * @param matchFileEntries Map (name to resource) of non-directory
+ * resources found inside the archive that matched all include
+ * patterns and didn't match any exclude patterns.
+ * @param dirEntries Map (name to resource) of directory
+ * resources found inside the archive.
+ * @param matchDirEntries Map (name to resource) of directory
+ * resources found inside the archive that matched all include
+ * patterns and didn't match any exclude patterns.
+ */
+ protected void fillMapsFromArchive(Resource src, String encoding,
+ Map<String, Resource> fileEntries, Map<String, Resource> matchFileEntries,
+ Map<String, Resource> dirEntries, Map<String, Resource> matchDirEntries) {
+
+ TarEntry entry = null;
+ TarInputStream ti = null;
+
+ try {
+ try {
+ ti = new TarInputStream(src.getInputStream(), encoding);
+ } catch (IOException ex) {
+ throw new BuildException("problem opening " + srcFile, ex);
+ }
+ while ((entry = ti.getNextEntry()) != null) {
+ Resource r = new TarResource(src, entry);
+ String name = entry.getName();
+ if (entry.isDirectory()) {
+ name = trimSeparator(name);
+ dirEntries.put(name, r);
+ if (match(name)) {
+ matchDirEntries.put(name, r);
+ }
+ } else {
+ fileEntries.put(name, r);
+ if (match(name)) {
+ matchFileEntries.put(name, r);
+ }
+ }
+ }
+ } catch (IOException ex) {
+ throw new BuildException("problem reading " + srcFile, ex);
+ } finally {
+ FileUtils.close(ti);
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/TimeComparison.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/TimeComparison.java
new file mode 100644
index 00000000..15c136e6
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/TimeComparison.java
@@ -0,0 +1,122 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.util.FileUtils;
+
+/**
+ * EnumeratedAttribute for time comparisons. Accepts values
+ * "before", "after", "equal".
+ * @since Ant 1.7
+ */
+public class TimeComparison extends EnumeratedAttribute {
+ private static final String[] VALUES
+ = new String[] {"before", "after", "equal"};
+
+ private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+
+ /** Before Comparison. */
+ public static final TimeComparison BEFORE = new TimeComparison("before");
+
+ /** After Comparison. */
+ public static final TimeComparison AFTER = new TimeComparison("after");
+
+ /** Equal Comparison. */
+ public static final TimeComparison EQUAL = new TimeComparison("equal");
+
+ /**
+ * Default constructor.
+ */
+ public TimeComparison() {
+ }
+
+ /**
+ * Construct a new TimeComparison with the specified value.
+ * @param value the EnumeratedAttribute value.
+ */
+ public TimeComparison(String value) {
+ setValue(value);
+ }
+
+ /**
+ * Return the possible values.
+ * @return String[] of EnumeratedAttribute values.
+ */
+ public String[] getValues() {
+ return VALUES;
+ }
+
+ /**
+ * Evaluate two times against this TimeComparison.
+ * @param t1 the first time to compare.
+ * @param t2 the second time to compare.
+ * @return true if the comparison result fell within the parameters of this TimeComparison.
+ */
+ public boolean evaluate(long t1, long t2) {
+ return evaluate(t1, t2, FILE_UTILS.getFileTimestampGranularity());
+ }
+
+ /**
+ * Evaluate two times against this TimeComparison.
+ * @param t1 the first time to compare.
+ * @param t2 the second time to compare.
+ * @param g the timestamp granularity.
+ * @return true if the comparison result fell within the parameters of this TimeComparison.
+ */
+ public boolean evaluate(long t1, long t2, long g) {
+ int cmp = getIndex();
+ if (cmp == -1) {
+ throw new BuildException("TimeComparison value not set.");
+ }
+ if (cmp == 0) {
+ return t1 - g < t2;
+ }
+ if (cmp == 1) {
+ return t1 + g > t2;
+ }
+ return Math.abs(t1 - t2) <= g;
+ }
+
+ /**
+ * Compare two times.
+ * @param t1 the first time to compare.
+ * @param t2 the second time to compare.
+ * @return a negative integer, a positive integer, or zero as t1 is
+ * before, after, or equal to t2 accounting for the default granularity.
+ */
+ public static int compare(long t1, long t2) {
+ return compare(t1, t2, FILE_UTILS.getFileTimestampGranularity());
+ }
+
+ /**
+ * Compare two times.
+ * @param t1 the first time to compare.
+ * @param t2 the second time to compare.
+ * @param g the timestamp granularity.
+ * @return a negative integer, a positive integer, or zero as t1 is
+ * before, after, or equal to t2 accounting for the specified granularity.
+ */
+ public static int compare(long t1, long t2, long g) {
+ long diff = t1 - t2;
+ long abs = Math.abs(diff);
+ return abs > Math.abs(g) ? (int) (diff / abs) : 0;
+ }
+
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/XMLCatalog.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/XMLCatalog.java
new file mode 100644
index 00000000..bd9be431
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/XMLCatalog.java
@@ -0,0 +1,1128 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.Method;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.Stack;
+import java.util.Vector;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParserFactory;
+import javax.xml.transform.Source;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.URIResolver;
+import javax.xml.transform.sax.SAXSource;
+
+import org.apache.tools.ant.AntClassLoader;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.util.FileUtils;
+import org.apache.tools.ant.util.JAXPUtils;
+import org.xml.sax.EntityResolver;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.XMLReader;
+
+
+
+/**
+ * <p>This data type provides a catalog of resource locations (such as
+ * DTDs and XML entities), based on the <a
+ * href="http://oasis-open.org/committees/entity/spec-2001-08-06.html">
+ * OASIS "Open Catalog" standard</a>. The catalog entries are used
+ * both for Entity resolution and URI resolution, in accordance with
+ * the {@link org.xml.sax.EntityResolver EntityResolver} and {@link
+ * javax.xml.transform.URIResolver URIResolver} interfaces as defined
+ * in the <a href="http://java.sun.com/xml/jaxp">Java API for XML
+ * Processing Specification</a>.</p>
+ *
+ * <p>Resource locations can be specified either in-line or in
+ * external catalog file(s), or both. In order to use an external
+ * catalog file, the xml-commons resolver library ("resolver.jar")
+ * must be in your classpath. External catalog files may be either <a
+ * href="http://oasis-open.org/committees/entity/background/9401.html">
+ * plain text format</a> or <a
+ * href="http://www.oasis-open.org/committees/entity/spec-2001-08-06.html">
+ * XML format</a>. If the xml-commons resolver library is not found
+ * in the classpath, external catalog files, specified in
+ * <code>&lt;catalogpath&gt;</code> paths, will be ignored and a warning will
+ * be logged. In this case, however, processing of inline entries will proceed
+ * normally.</p>
+ *
+ * <p>Currently, only <code>&lt;dtd&gt;</code> and
+ * <code>&lt;entity&gt;</code> elements may be specified inline; these
+ * correspond to OASIS catalog entry types <code>PUBLIC</code> and
+ * <code>URI</code> respectively.</p>
+ *
+ * <p>The following is a usage example:</p>
+ *
+ * <code>
+ * &lt;xmlcatalog&gt;<br>
+ * &nbsp;&nbsp;&lt;dtd publicId="" location="/path/to/file.jar" /&gt;<br>
+ * &nbsp;&nbsp;&lt;dtd publicId="" location="/path/to/file2.jar" /&gt;<br>
+ * &nbsp;&nbsp;&lt;entity publicId="" location="/path/to/file3.jar" /&gt;<br>
+ * &nbsp;&nbsp;&lt;entity publicId="" location="/path/to/file4.jar" /&gt;<br>
+ * &nbsp;&nbsp;&lt;catalogpath&gt;<br>
+ * &nbsp;&nbsp;&nbsp;&nbsp;&lt;pathelement location="/etc/sgml/catalog"/&gt;<br>
+ * &nbsp;&nbsp;&lt;/catalogpath&gt;<br>
+ * &nbsp;&nbsp;&lt;catalogfiles dir="/opt/catalogs/" includes="**\catalog.xml" /&gt;<br>
+ * &lt;/xmlcatalog&gt;<br>
+ * </code>
+ * <p>
+ * Tasks wishing to use <code>&lt;xmlcatalog&gt;</code> must provide a method called
+ * <code>createXMLCatalog</code> which returns an instance of
+ * <code>XMLCatalog</code>. Nested DTD and entity definitions are handled by
+ * the XMLCatalog object and must be labeled <code>dtd</code> and
+ * <code>entity</code> respectively.</p>
+ *
+ * <p>The following is a description of the resolution algorithm:
+ * entities/URIs/dtds are looked up in each of the following contexts,
+ * stopping when a valid and readable resource is found:
+ * <ol>
+ * <li>In the local filesystem</li>
+ * <li>In the classpath</li>
+ * <li>Using the Apache xml-commons resolver (if it is available)</li>
+ * <li>In URL-space</li>
+ * </ol>
+ * </p>
+ *
+ * <p>See {@link
+ * org.apache.tools.ant.taskdefs.optional.XMLValidateTask
+ * XMLValidateTask} for an example of a task that has integrated
+ * support for XMLCatalogs.</p>
+ *
+ * <p>Possible future extension could provide for additional OASIS
+ * entry types to be specified inline.</p>
+ *
+ */
+public class XMLCatalog extends DataType
+ implements Cloneable, EntityResolver, URIResolver {
+
+ /** helper for some File.toURL connversions */
+ private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+
+ //-- Fields ----------------------------------------------------------------
+
+ /** Holds dtd/entity objects until needed. */
+ private Vector<ResourceLocation> elements = new Vector<ResourceLocation>();
+
+ /**
+ * Classpath in which to attempt to resolve resources.
+ */
+ private Path classpath;
+
+ /**
+ * Path listing external catalog files to search when resolving entities
+ */
+ private Path catalogPath;
+
+ /**
+ * The name of the bridge to the Apache xml-commons resolver
+ * class, used to determine whether resolver.jar is present in the
+ * classpath.
+ */
+ public static final String APACHE_RESOLVER
+ = "org.apache.tools.ant.types.resolver.ApacheCatalogResolver";
+
+ /**
+ * Resolver base class
+ */
+ public static final String CATALOG_RESOLVER
+ = "org.apache.xml.resolver.tools.CatalogResolver";
+
+ //-- Methods ---------------------------------------------------------------
+
+ /**
+ * Default constructor
+ */
+ public XMLCatalog() {
+ setChecked(false);
+ }
+
+ /**
+ * Returns the elements of the catalog - ResourceLocation objects.
+ *
+ * @return the elements of the catalog - ResourceLocation objects
+ */
+ private Vector<ResourceLocation> getElements() {
+ return getRef().elements;
+ }
+
+ /**
+ * Returns the classpath in which to attempt to resolve resources.
+ *
+ * @return the classpath
+ */
+ private Path getClasspath() {
+ return getRef().classpath;
+ }
+
+ /**
+ * Allows nested classpath elements. Not allowed if this catalog
+ * is itself a reference to another catalog -- that is, a catalog
+ * cannot both refer to another <em>and</em> contain elements or
+ * other attributes.
+ *
+ * @return a Path instance to be configured.
+ */
+ public Path createClasspath() {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ if (this.classpath == null) {
+ this.classpath = new Path(getProject());
+ }
+ setChecked(false);
+ return this.classpath.createPath();
+ }
+
+ /**
+ * Allows simple classpath string. Not allowed if this catalog is
+ * itself a reference to another catalog -- that is, a catalog
+ * cannot both refer to another <em>and</em> contain elements or
+ * other attributes.
+ *
+ * @param classpath the classpath to use to look up entities.
+ */
+ public void setClasspath(Path classpath) {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ if (this.classpath == null) {
+ this.classpath = classpath;
+ } else {
+ this.classpath.append(classpath);
+ }
+ setChecked(false);
+ }
+
+ /**
+ * Allows classpath reference. Not allowed if this catalog is
+ * itself a reference to another catalog -- that is, a catalog
+ * cannot both refer to another <em>and</em> contain elements or
+ * other attributes.
+ *
+ * @param r an Ant reference containing a classpath.
+ */
+ public void setClasspathRef(Reference r) {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ createClasspath().setRefid(r);
+ setChecked(false);
+ }
+
+ /** Creates a nested <code>&lt;catalogpath&gt;</code> element.
+ * Not allowed if this catalog is itself a reference to another
+ * catalog -- that is, a catalog cannot both refer to another
+ * <em>and</em> contain elements or other attributes.
+ *
+ * @return a path to be configured as the catalog path.
+ * @exception BuildException
+ * if this is a reference and no nested elements are allowed.
+ */
+ public Path createCatalogPath() {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ if (this.catalogPath == null) {
+ this.catalogPath = new Path(getProject());
+ }
+ setChecked(false);
+ return this.catalogPath.createPath();
+ }
+
+ /**
+ * Allows catalogpath reference. Not allowed if this catalog is
+ * itself a reference to another catalog -- that is, a catalog
+ * cannot both refer to another <em>and</em> contain elements or
+ * other attributes.
+ *
+ * @param r an Ant reference containing a classpath to be used as
+ * the catalog path.
+ */
+ public void setCatalogPathRef(Reference r) {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ createCatalogPath().setRefid(r);
+ setChecked(false);
+ }
+
+
+ /**
+ * Returns the catalog path in which to attempt to resolve DTDs.
+ *
+ * @return the catalog path
+ */
+ public Path getCatalogPath() {
+ return getRef().catalogPath;
+ }
+
+
+ /**
+ * Creates the nested <code>&lt;dtd&gt;</code> element. Not
+ * allowed if this catalog is itself a reference to another
+ * catalog -- that is, a catalog cannot both refer to another
+ * <em>and</em> contain elements or other attributes.
+ *
+ * @param dtd the information about the PUBLIC resource mapping to
+ * be added to the catalog
+ * @exception BuildException if this is a reference and no nested
+ * elements are allowed.
+ */
+ public void addDTD(ResourceLocation dtd) throws BuildException {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+
+ getElements().addElement(dtd);
+ setChecked(false);
+ }
+
+ /**
+ * Creates the nested <code>&lt;entity&gt;</code> element. Not
+ * allowed if this catalog is itself a reference to another
+ * catalog -- that is, a catalog cannot both refer to another
+ * <em>and</em> contain elements or other attributes.
+ *
+ * @param entity the information about the URI resource mapping to be
+ * added to the catalog.
+ * @exception BuildException if this is a reference and no nested
+ * elements are allowed.
+ */
+ public void addEntity(ResourceLocation entity) throws BuildException {
+ addDTD(entity);
+ }
+
+ /**
+ * Loads a nested <code>&lt;xmlcatalog&gt;</code> into our
+ * definition. Not allowed if this catalog is itself a reference
+ * to another catalog -- that is, a catalog cannot both refer to
+ * another <em>and</em> contain elements or other attributes.
+ *
+ * @param catalog Nested XMLCatalog
+ */
+ public void addConfiguredXMLCatalog(XMLCatalog catalog) {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+
+ // Add all nested elements to our catalog
+ getElements().addAll(catalog.getElements());
+
+ // Append the classpath of the nested catalog
+ Path nestedClasspath = catalog.getClasspath();
+ createClasspath().append(nestedClasspath);
+
+ // Append the catalog path of the nested catalog
+ Path nestedCatalogPath = catalog.getCatalogPath();
+ createCatalogPath().append(nestedCatalogPath);
+ setChecked(false);
+ }
+
+ /**
+ * Makes this instance in effect a reference to another XMLCatalog
+ * instance.
+ *
+ * <p>You must not set another attribute or nest elements inside
+ * this element if you make it a reference. That is, a catalog
+ * cannot both refer to another <em>and</em> contain elements or
+ * attributes.</p>
+ *
+ * @param r the reference to which this catalog instance is associated
+ * @exception BuildException if this instance already has been configured.
+ */
+ public void setRefid(Reference r) throws BuildException {
+ if (!elements.isEmpty()) {
+ throw tooManyAttributes();
+ }
+ super.setRefid(r);
+ }
+
+ /**
+ * Implements the EntityResolver.resolveEntity() interface method.
+ * @param publicId the public id to resolve.
+ * @param systemId the system id to resolve.
+ * @throws SAXException if there is a parsing problem.
+ * @throws IOException if there is an IO problem.
+ * @return the resolved entity.
+ * @see org.xml.sax.EntityResolver#resolveEntity
+ */
+ public InputSource resolveEntity(String publicId, String systemId)
+ throws SAXException, IOException {
+
+ if (isReference()) {
+ return getRef().resolveEntity(publicId, systemId);
+ }
+
+ dieOnCircularReference();
+
+ log("resolveEntity: '" + publicId + "': '" + systemId + "'",
+ Project.MSG_DEBUG);
+
+ InputSource inputSource =
+ getCatalogResolver().resolveEntity(publicId, systemId);
+
+ if (inputSource == null) {
+ log("No matching catalog entry found, parser will use: '"
+ + systemId + "'", Project.MSG_DEBUG);
+ }
+
+ return inputSource;
+ }
+
+ /**
+ * Implements the URIResolver.resolve() interface method.
+ * @param href an href attribute.
+ * @param base the base URI.
+ * @return a Source object, or null if href cannot be resolved.
+ * @throws TransformerException if an error occurs.
+ * @see javax.xml.transform.URIResolver#resolve
+ */
+ public Source resolve(String href, String base)
+ throws TransformerException {
+
+ if (isReference()) {
+ return getRef().resolve(href, base);
+ }
+
+ dieOnCircularReference();
+
+ SAXSource source = null;
+
+ String uri = removeFragment(href);
+
+ log("resolve: '" + uri + "' with base: '" + base + "'", Project.MSG_DEBUG);
+
+ source = (SAXSource) getCatalogResolver().resolve(uri, base);
+
+ if (source == null) {
+ log("No matching catalog entry found, parser will use: '"
+ + href + "'", Project.MSG_DEBUG);
+ //
+ // Cannot return a null source, because we have to call
+ // setEntityResolver (see setEntityResolver javadoc comment)
+ //
+ source = new SAXSource();
+ URL baseURL = null;
+ try {
+ if (base == null) {
+ baseURL = FILE_UTILS.getFileURL(getProject().getBaseDir());
+ } else {
+ baseURL = new URL(base);
+ }
+ URL url = (uri.length() == 0 ? baseURL : new URL(baseURL, uri));
+ source.setInputSource(new InputSource(url.toString()));
+ } catch (MalformedURLException ex) {
+ // At this point we are probably in failure mode, but
+ // try to use the bare URI as a last gasp
+ source.setInputSource(new InputSource(uri));
+ }
+ }
+
+ setEntityResolver(source);
+ return source;
+ }
+
+ protected synchronized void dieOnCircularReference(Stack<Object> stk, Project p)
+ throws BuildException {
+ if (isChecked()) {
+ return;
+ }
+ if (isReference()) {
+ super.dieOnCircularReference(stk, p);
+ } else {
+ if (classpath != null) {
+ pushAndInvokeCircularReferenceCheck(classpath, stk, p);
+ }
+ if (catalogPath != null) {
+ pushAndInvokeCircularReferenceCheck(catalogPath, stk, p);
+ }
+ setChecked(true);
+ }
+ }
+
+ /**
+ * @since Ant 1.6
+ */
+ private XMLCatalog getRef() {
+ if (!isReference()) {
+ return this;
+ }
+ return getCheckedRef(XMLCatalog.class, "xmlcatalog");
+ }
+
+ /**
+ * The instance of the CatalogResolver strategy to use.
+ */
+ private CatalogResolver catalogResolver = null;
+
+ /**
+ * Factory method for creating the appropriate CatalogResolver
+ * strategy implementation.
+ * <p> Until we query the classpath, we don't know whether the Apache
+ * resolver (Norm Walsh's library from xml-commons) is available or not.
+ * This method determines whether the library is available and creates the
+ * appropriate implementation of CatalogResolver based on the answer.</p>
+ * <p>This is an application of the Gang of Four Strategy Pattern
+ * combined with Template Method.</p>
+ */
+ private CatalogResolver getCatalogResolver() {
+
+ if (catalogResolver == null) {
+
+ AntClassLoader loader = null;
+ // Memory-Leak in line below
+ loader = getProject().createClassLoader(Path.systemClasspath);
+
+ try {
+ Class<?> clazz = Class.forName(APACHE_RESOLVER, true, loader);
+
+ // The Apache resolver is present - Need to check if it can
+ // be seen by the catalog resolver class. Start by getting
+ // the actual loader
+ ClassLoader apacheResolverLoader = clazz.getClassLoader();
+
+ // load the base class through this loader.
+ Class<?> baseResolverClass
+ = Class.forName(CATALOG_RESOLVER, true, apacheResolverLoader);
+
+ // and find its actual loader
+ ClassLoader baseResolverLoader
+ = baseResolverClass.getClassLoader();
+
+ // We have the loader which is being used to load the
+ // CatalogResolver. Can it see the ApacheResolver? The
+ // base resolver will only be able to create the ApacheResolver
+ // if it can see it - doesn't use the context loader.
+ clazz = Class.forName(APACHE_RESOLVER, true, baseResolverLoader);
+
+ Object obj = clazz.newInstance();
+ //
+ // Success! The xml-commons resolver library is
+ // available, so use it.
+ //
+ catalogResolver = new ExternalResolver(clazz, obj);
+ } catch (Throwable ex) {
+ //
+ // The xml-commons resolver library is not
+ // available, so we can't use it.
+ //
+ catalogResolver = new InternalResolver();
+ if (getCatalogPath() != null
+ && getCatalogPath().list().length != 0) {
+ log("Warning: XML resolver not found; external catalogs"
+ + " will be ignored", Project.MSG_WARN);
+ }
+ log("Failed to load Apache resolver: " + ex, Project.MSG_DEBUG);
+ }
+ }
+ return catalogResolver;
+ }
+
+ /**
+ * <p>This is called from the URIResolver to set an EntityResolver
+ * on the SAX parser to be used for new XML documents that are
+ * encountered as a result of the document() function, xsl:import,
+ * or xsl:include. This is done because the XSLT processor calls
+ * out to the SAXParserFactory itself to create a new SAXParser to
+ * parse the new document. The new parser does not automatically
+ * inherit the EntityResolver of the original (although arguably
+ * it should). See below:</p>
+ *
+ * <tt>"If an application wants to set the ErrorHandler or
+ * EntityResolver for an XMLReader used during a transformation,
+ * it should use a URIResolver to return the SAXSource which
+ * provides (with getXMLReader) a reference to the XMLReader"</tt>
+ *
+ * <p>...quoted from page 118 of the Java API for XML
+ * Processing 1.1 specification</p>
+ *
+ */
+ private void setEntityResolver(SAXSource source) throws TransformerException {
+
+ XMLReader reader = source.getXMLReader();
+ if (reader == null) {
+ SAXParserFactory spFactory = SAXParserFactory.newInstance();
+ spFactory.setNamespaceAware(true);
+ try {
+ reader = spFactory.newSAXParser().getXMLReader();
+ } catch (ParserConfigurationException ex) {
+ throw new TransformerException(ex);
+ } catch (SAXException ex) {
+ throw new TransformerException(ex);
+ }
+ }
+ reader.setEntityResolver(this);
+ source.setXMLReader(reader);
+ }
+
+ /**
+ * Find a ResourceLocation instance for the given publicId.
+ *
+ * @param publicId the publicId of the Resource for which local information
+ * is required.
+ * @return a ResourceLocation instance with information on the local location
+ * of the Resource or null if no such information is available.
+ */
+ private ResourceLocation findMatchingEntry(String publicId) {
+ for (ResourceLocation element : getElements()) {
+ if (element.getPublicId().equals(publicId)) {
+ return element;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Utility method to remove trailing fragment from a URI.
+ * For example,
+ * <code>http://java.sun.com/index.html#chapter1</code>
+ * would return <code>http://java.sun.com/index.html</code>.
+ *
+ * @param uri The URI to process. It may or may not contain a
+ * fragment.
+ * @return The URI sans fragment.
+ */
+ private String removeFragment(String uri) {
+ String result = uri;
+ int hashPos = uri.indexOf("#");
+ if (hashPos >= 0) {
+ result = uri.substring(0, hashPos);
+ }
+ return result;
+ }
+
+ /**
+ * Utility method to lookup a ResourceLocation in the filesystem.
+ *
+ * @return An InputSource for reading the file, or <code>null</code>
+ * if the file does not exist or is not readable.
+ */
+ private InputSource filesystemLookup(ResourceLocation matchingEntry) {
+
+ String uri = matchingEntry.getLocation();
+ // the following line seems to be necessary on Windows under JDK 1.2
+ uri = uri.replace(File.separatorChar, '/');
+ URL baseURL = null;
+
+ //
+ // The ResourceLocation may specify a relative path for its
+ // location attribute. This is resolved using the appropriate
+ // base.
+ //
+ if (matchingEntry.getBase() != null) {
+ baseURL = matchingEntry.getBase();
+ } else {
+ try {
+ baseURL = FILE_UTILS.getFileURL(getProject().getBaseDir());
+ } catch (MalformedURLException ex) {
+ throw new BuildException("Project basedir cannot be converted to a URL");
+ }
+ }
+
+ InputSource source = null;
+ URL url = null;
+ try {
+ url = new URL(baseURL, uri);
+ } catch (MalformedURLException ex) {
+ // this processing is useful under Windows when the location of the DTD
+ // has been given as an absolute path
+ // see Bugzilla Report 23913
+ File testFile = new File(uri);
+ if (testFile.exists() && testFile.canRead()) {
+ log("uri : '"
+ + uri + "' matches a readable file", Project.MSG_DEBUG);
+ try {
+ url = FILE_UTILS.getFileURL(testFile);
+ } catch (MalformedURLException ex1) {
+ throw new BuildException(
+ "could not find an URL for :" + testFile.getAbsolutePath());
+ }
+ } else {
+ log("uri : '"
+ + uri + "' does not match a readable file", Project.MSG_DEBUG);
+
+ }
+ }
+
+ if (url != null && url.getProtocol().equals("file")) {
+ String fileName = FILE_UTILS.fromURI(url.toString());
+ if (fileName != null) {
+ log("fileName " + fileName, Project.MSG_DEBUG);
+ File resFile = new File(fileName);
+ if (resFile.exists() && resFile.canRead()) {
+ try {
+ source = new InputSource(new FileInputStream(resFile));
+ String sysid = JAXPUtils.getSystemId(resFile);
+ source.setSystemId(sysid);
+ log("catalog entry matched a readable file: '"
+ + sysid + "'", Project.MSG_DEBUG);
+ } catch (IOException ex) {
+ // ignore
+ }
+ }
+ }
+ }
+ return source;
+ }
+
+ /**
+ * Utility method to lookup a ResourceLocation in the classpath.
+ *
+ * @return An InputSource for reading the resource, or <code>null</code>
+ * if the resource does not exist in the classpath or is not readable.
+ */
+ private InputSource classpathLookup(ResourceLocation matchingEntry) {
+
+ InputSource source = null;
+
+ AntClassLoader loader = null;
+ Path cp = classpath;
+ if (cp != null) {
+ cp = classpath.concatSystemClasspath("ignore");
+ } else {
+ cp = (new Path(getProject())).concatSystemClasspath("last");
+ }
+ loader = getProject().createClassLoader(cp);
+
+ //
+ // for classpath lookup we ignore the base directory
+ //
+ InputStream is
+ = loader.getResourceAsStream(matchingEntry.getLocation());
+
+ if (is != null) {
+ source = new InputSource(is);
+ URL entryURL = loader.getResource(matchingEntry.getLocation());
+ String sysid = entryURL.toExternalForm();
+ source.setSystemId(sysid);
+ log("catalog entry matched a resource in the classpath: '"
+ + sysid + "'", Project.MSG_DEBUG);
+ }
+
+ return source;
+ }
+
+ /**
+ * Utility method to lookup a ResourceLocation in URL-space.
+ *
+ * @return An InputSource for reading the resource, or <code>null</code>
+ * if the resource does not identify a valid URL or is not readable.
+ */
+ private InputSource urlLookup(ResourceLocation matchingEntry) {
+
+ String uri = matchingEntry.getLocation();
+ URL baseURL = null;
+
+ //
+ // The ResourceLocation may specify a relative url for its
+ // location attribute. This is resolved using the appropriate
+ // base.
+ //
+ if (matchingEntry.getBase() != null) {
+ baseURL = matchingEntry.getBase();
+ } else {
+ try {
+ baseURL = FILE_UTILS.getFileURL(getProject().getBaseDir());
+ } catch (MalformedURLException ex) {
+ throw new BuildException("Project basedir cannot be converted to a URL");
+ }
+ }
+
+ InputSource source = null;
+ URL url = null;
+
+ try {
+ url = new URL(baseURL, uri);
+ } catch (MalformedURLException ex) {
+ // ignore
+ }
+
+ if (url != null) {
+ try {
+ InputStream is = null;
+ URLConnection conn = url.openConnection();
+ if (conn != null) {
+ conn.setUseCaches(false);
+ is = conn.getInputStream();
+ }
+ if (is != null) {
+ source = new InputSource(is);
+ String sysid = url.toExternalForm();
+ source.setSystemId(sysid);
+ log("catalog entry matched as a URL: '"
+ + sysid + "'", Project.MSG_DEBUG);
+ }
+ } catch (IOException ex) {
+ // ignore
+ }
+ }
+
+ return source;
+
+ }
+
+ /**
+ * Interface implemented by both the InternalResolver strategy and
+ * the ExternalResolver strategy.
+ */
+ private interface CatalogResolver extends URIResolver, EntityResolver {
+
+ InputSource resolveEntity(String publicId, String systemId);
+
+ Source resolve(String href, String base) throws TransformerException;
+ }
+
+ /**
+ * The InternalResolver strategy is used if the Apache resolver
+ * library (Norm Walsh's library from xml-commons) is not
+ * available. In this case, external catalog files will be
+ * ignored.
+ *
+ */
+ private class InternalResolver implements CatalogResolver {
+
+ public InternalResolver() {
+ log("Apache resolver library not found, internal resolver will be used",
+ Project.MSG_VERBOSE);
+ }
+
+ public InputSource resolveEntity(String publicId,
+ String systemId) {
+ InputSource result = null;
+ ResourceLocation matchingEntry = findMatchingEntry(publicId);
+
+ if (matchingEntry != null) {
+
+ log("Matching catalog entry found for publicId: '"
+ + matchingEntry.getPublicId() + "' location: '"
+ + matchingEntry.getLocation() + "'",
+ Project.MSG_DEBUG);
+
+ result = filesystemLookup(matchingEntry);
+
+ if (result == null) {
+ result = classpathLookup(matchingEntry);
+ }
+
+ if (result == null) {
+ result = urlLookup(matchingEntry);
+ }
+ }
+ return result;
+ }
+
+ public Source resolve(String href, String base)
+ throws TransformerException {
+
+ SAXSource result = null;
+ InputSource source = null;
+
+ ResourceLocation matchingEntry = findMatchingEntry(href);
+
+ if (matchingEntry != null) {
+
+ log("Matching catalog entry found for uri: '"
+ + matchingEntry.getPublicId() + "' location: '"
+ + matchingEntry.getLocation() + "'",
+ Project.MSG_DEBUG);
+
+ //
+ // Use the passed in base in preference to the base
+ // from matchingEntry, which is either null or the
+ // directory in which the external catalog file from
+ // which it was obtained is located. We make a copy
+ // so matchingEntry's original base is untouched.
+ //
+ // This is the standard behavior as per my reading of
+ // the JAXP and XML Catalog specs. CKS 11/7/2002
+ //
+ ResourceLocation entryCopy = matchingEntry;
+ if (base != null) {
+ try {
+ URL baseURL = new URL(base);
+ entryCopy = new ResourceLocation();
+ entryCopy.setBase(baseURL);
+ } catch (MalformedURLException ex) {
+ // ignore
+ }
+ }
+ entryCopy.setPublicId(matchingEntry.getPublicId());
+ entryCopy.setLocation(matchingEntry.getLocation());
+
+ source = filesystemLookup(entryCopy);
+
+ if (source == null) {
+ source = classpathLookup(entryCopy);
+ }
+
+ if (source == null) {
+ source = urlLookup(entryCopy);
+ }
+
+ if (source != null) {
+ result = new SAXSource(source);
+ }
+ }
+ return result;
+ }
+ }
+
+ /**
+ * The ExternalResolver strategy is used if the Apache resolver
+ * library (Norm Walsh's library from xml-commons) is available in
+ * the classpath. The ExternalResolver is a essentially a superset
+ * of the InternalResolver.
+ *
+ */
+ private class ExternalResolver implements CatalogResolver {
+
+ private Method setXMLCatalog = null;
+ private Method parseCatalog = null;
+ private Method resolveEntity = null;
+ private Method resolve = null;
+
+ /** The instance of the ApacheCatalogResolver bridge class */
+ private Object resolverImpl = null;
+
+ private boolean externalCatalogsProcessed = false;
+
+ public ExternalResolver(Class<?> resolverImplClass,
+ Object resolverImpl) {
+
+ this.resolverImpl = resolverImpl;
+
+ //
+ // Get Method instances for each of the methods we need to
+ // call on the resolverImpl using reflection. We can't
+ // call them directly, because they require on the
+ // xml-commons resolver library which may not be available
+ // in the classpath.
+ //
+ try {
+ setXMLCatalog =
+ resolverImplClass.getMethod("setXMLCatalog",
+ new Class[] {XMLCatalog.class});
+
+ parseCatalog =
+ resolverImplClass.getMethod("parseCatalog",
+ new Class[] {String.class});
+
+ resolveEntity =
+ resolverImplClass.getMethod("resolveEntity",
+ new Class[] {String.class, String.class});
+
+ resolve =
+ resolverImplClass.getMethod("resolve",
+ new Class[] {String.class, String.class});
+ } catch (NoSuchMethodException ex) {
+ throw new BuildException(ex);
+ }
+
+ log("Apache resolver library found, xml-commons resolver will be used",
+ Project.MSG_VERBOSE);
+ }
+
+ public InputSource resolveEntity(String publicId,
+ String systemId) {
+ InputSource result = null;
+
+ processExternalCatalogs();
+
+ ResourceLocation matchingEntry = findMatchingEntry(publicId);
+
+ if (matchingEntry != null) {
+
+ log("Matching catalog entry found for publicId: '"
+ + matchingEntry.getPublicId() + "' location: '"
+ + matchingEntry.getLocation() + "'",
+ Project.MSG_DEBUG);
+
+ result = filesystemLookup(matchingEntry);
+
+ if (result == null) {
+ result = classpathLookup(matchingEntry);
+ }
+
+ if (result == null) {
+ try {
+ result =
+ (InputSource) resolveEntity.invoke(resolverImpl,
+ new Object[] {publicId, systemId});
+ } catch (Exception ex) {
+ throw new BuildException(ex);
+ }
+ }
+ } else {
+ //
+ // We didn't match a ResourceLocation, but since we
+ // only support PUBLIC and URI entry types internally,
+ // it is still possible that there is another entry in
+ // an external catalog that will match. We call
+ // Apache resolver's resolveEntity method to cover
+ // this possibility.
+ //
+ try {
+ result =
+ (InputSource) resolveEntity.invoke(resolverImpl,
+ new Object[] {publicId, systemId});
+ } catch (Exception ex) {
+ throw new BuildException(ex);
+ }
+ }
+
+ return result;
+ }
+
+ public Source resolve(String href, String base)
+ throws TransformerException {
+
+ SAXSource result = null;
+ InputSource source = null;
+
+ processExternalCatalogs();
+
+ ResourceLocation matchingEntry = findMatchingEntry(href);
+
+ if (matchingEntry != null) {
+
+ log("Matching catalog entry found for uri: '"
+ + matchingEntry.getPublicId() + "' location: '"
+ + matchingEntry.getLocation() + "'",
+ Project.MSG_DEBUG);
+
+ //
+ // Use the passed in base in preference to the base
+ // from matchingEntry, which is either null or the
+ // directory in which the external catalog file from
+ // which it was obtained is located. We make a copy
+ // so matchingEntry's original base is untouched. Of
+ // course, if there is no base, no need to make a
+ // copy...
+ //
+ // This is the standard behavior as per my reading of
+ // the JAXP and XML Catalog specs. CKS 11/7/2002
+ //
+ ResourceLocation entryCopy = matchingEntry;
+ if (base != null) {
+ try {
+ URL baseURL = new URL(base);
+ entryCopy = new ResourceLocation();
+ entryCopy.setBase(baseURL);
+ } catch (MalformedURLException ex) {
+ // ignore
+ }
+ }
+ entryCopy.setPublicId(matchingEntry.getPublicId());
+ entryCopy.setLocation(matchingEntry.getLocation());
+
+ source = filesystemLookup(entryCopy);
+
+ if (source == null) {
+ source = classpathLookup(entryCopy);
+ }
+
+ if (source != null) {
+ result = new SAXSource(source);
+ } else {
+ try {
+ result =
+ (SAXSource) resolve.invoke(resolverImpl,
+ new Object[] {href, base});
+ } catch (Exception ex) {
+ throw new BuildException(ex);
+ }
+ }
+ } else {
+ //
+ // We didn't match a ResourceLocation, but since we
+ // only support PUBLIC and URI entry types internally,
+ // it is still possible that there is another entry in
+ // an external catalog that will match. We call
+ // Apache resolver's resolveEntity method to cover
+ // this possibility.
+ //
+ if (base == null) {
+ try {
+ base = FILE_UTILS.getFileURL(getProject().getBaseDir()).toString();
+ } catch (MalformedURLException x) {
+ throw new TransformerException(x);
+ }
+ }
+ try {
+ result =
+ (SAXSource) resolve.invoke(resolverImpl,
+ new Object[] {href, base});
+ } catch (Exception ex) {
+ throw new BuildException(ex);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Process each external catalog file specified in a
+ * <code>&lt;catalogpath&gt;</code>. It will be
+ * parsed by the resolver library, and the individual elements
+ * will be added back to us (that is, the controlling
+ * XMLCatalog instance) via a callback mechanism.
+ */
+ private void processExternalCatalogs() {
+
+ if (!externalCatalogsProcessed) {
+
+ try {
+ setXMLCatalog.invoke(resolverImpl,
+ new Object[] {XMLCatalog.this});
+ } catch (Exception ex) {
+ throw new BuildException(ex);
+ }
+
+ // Parse each catalog listed in nested <catalogpath> elements
+ Path catPath = getCatalogPath();
+ if (catPath != null) {
+ log("Using catalogpath '" + getCatalogPath() + "'",
+ Project.MSG_DEBUG);
+ String[] catPathList = getCatalogPath().list();
+
+ for (int i = 0; i < catPathList.length; i++) {
+ File catFile = new File(catPathList[i]);
+ log("Parsing " + catFile, Project.MSG_DEBUG);
+ try {
+ parseCatalog.invoke(resolverImpl,
+ new Object[] {catFile.getPath()});
+ } catch (Exception ex) {
+ throw new BuildException(ex);
+ }
+ }
+ }
+ }
+ externalCatalogsProcessed = true;
+ }
+ }
+} //-- XMLCatalog
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/ZipFileSet.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/ZipFileSet.java
new file mode 100644
index 00000000..24f0ccd5
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/ZipFileSet.java
@@ -0,0 +1,117 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+
+/**
+ * A ZipFileSet is a FileSet with extra attributes useful in the context of
+ * Zip/Jar tasks.
+ *
+ * A ZipFileSet extends FileSets with the ability to extract a subset of the
+ * entries of a Zip file for inclusion in another Zip file. It also includes
+ * a prefix attribute which is prepended to each entry in the output Zip file.
+ *
+ * Since ant 1.6 ZipFileSet can be defined with an id and referenced in packaging tasks
+ *
+ */
+public class ZipFileSet extends ArchiveFileSet {
+
+ /** Constructor for ZipFileSet */
+ public ZipFileSet() {
+ super();
+ }
+
+ /**
+ * Constructor using a fileset argument.
+ * @param fileset the fileset to use
+ */
+ protected ZipFileSet(FileSet fileset) {
+ super(fileset);
+ }
+
+ /**
+ * Constructor using a zipfileset argument.
+ * @param fileset the zipfileset to use
+ */
+ protected ZipFileSet(ZipFileSet fileset) {
+ super(fileset);
+ }
+
+ /**
+ * Return a new archive scanner based on this one.
+ * @return a new ZipScanner with the same encoding as this one.
+ */
+ protected ArchiveScanner newArchiveScanner() {
+ ZipScanner zs = new ZipScanner();
+ zs.setEncoding(getEncoding());
+ return zs;
+ }
+
+ /**
+ * A ZipFileset accepts another ZipFileSet or a FileSet as reference
+ * FileSets are often used by the war task for the lib attribute
+ * @param p the project to use
+ * @return the abstract fileset instance
+ */
+ protected AbstractFileSet getRef(Project p) {
+ dieOnCircularReference(p);
+ Object o = getRefid().getReferencedObject(p);
+ if (o instanceof ZipFileSet) {
+ return (AbstractFileSet) o;
+ } else if (o instanceof FileSet) {
+ ZipFileSet zfs = new ZipFileSet((FileSet) o);
+ configureFileSet(zfs);
+ return zfs;
+ } else {
+ String msg = getRefid().getRefId() + " doesn\'t denote a zipfileset or a fileset";
+ throw new BuildException(msg);
+ }
+ }
+
+ /**
+ * Return a ZipFileSet that has the same properties
+ * as this one.
+ * @return the cloned zipFileSet
+ */
+ public Object clone() {
+ if (isReference()) {
+ return ((ZipFileSet) getRef(getProject())).clone();
+ } else {
+ return super.clone();
+ }
+ }
+
+ /**
+ * A check attributes for zipFileSet.
+ * If there is a reference, and
+ * it is a ZipFileSet, the zip fileset attributes
+ * cannot be used.
+ */
+ private void checkZipFileSetAttributesAllowed() {
+ if (getProject() == null
+ || (isReference()
+ && (getRefid().getReferencedObject(
+ getProject())
+ instanceof ZipFileSet))) {
+ checkAttributesAllowed();
+ }
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/ZipScanner.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/ZipScanner.java
new file mode 100644
index 00000000..e64b7172
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/ZipScanner.java
@@ -0,0 +1,99 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.Map;
+import java.util.zip.ZipException;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.types.resources.FileProvider;
+import org.apache.tools.ant.types.resources.ZipResource;
+import org.apache.tools.zip.ZipEntry;
+import org.apache.tools.zip.ZipFile;
+
+/**
+ * Scans zip archives for resources.
+ */
+public class ZipScanner extends ArchiveScanner {
+
+ /**
+ * Fills the file and directory maps with resources read from the
+ * archive.
+ *
+ * @param src the archive to scan.
+ * @param encoding encoding used to encode file names inside the archive.
+ * @param fileEntries Map (name to resource) of non-directory
+ * resources found inside the archive.
+ * @param matchFileEntries Map (name to resource) of non-directory
+ * resources found inside the archive that matched all include
+ * patterns and didn't match any exclude patterns.
+ * @param dirEntries Map (name to resource) of directory
+ * resources found inside the archive.
+ * @param matchDirEntries Map (name to resource) of directory
+ * resources found inside the archive that matched all include
+ * patterns and didn't match any exclude patterns.
+ */
+ protected void fillMapsFromArchive(Resource src, String encoding,
+ Map<String, Resource> fileEntries, Map<String, Resource> matchFileEntries,
+ Map<String, Resource> dirEntries, Map<String, Resource> matchDirEntries) {
+ ZipEntry entry = null;
+ ZipFile zf = null;
+
+ File srcFile = null;
+ FileProvider fp = src.as(FileProvider.class);
+ if (fp != null) {
+ srcFile = fp.getFile();
+ } else {
+ throw new BuildException("Only file provider resources are supported");
+ }
+
+ try {
+ try {
+ zf = new ZipFile(srcFile, encoding);
+ } catch (ZipException ex) {
+ throw new BuildException("Problem reading " + srcFile, ex);
+ } catch (IOException ex) {
+ throw new BuildException("Problem opening " + srcFile, ex);
+ }
+ Enumeration<ZipEntry> e = zf.getEntries();
+ while (e.hasMoreElements()) {
+ entry = e.nextElement();
+ Resource r = new ZipResource(srcFile, encoding, entry);
+ String name = entry.getName();
+ if (entry.isDirectory()) {
+ name = trimSeparator(name);
+ dirEntries.put(name, r);
+ if (match(name)) {
+ matchDirEntries.put(name, r);
+ }
+ } else {
+ fileEntries.put(name, r);
+ if (match(name)) {
+ matchFileEntries.put(name, r);
+ }
+ }
+ }
+ } finally {
+ ZipFile.closeQuietly(zf);
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/conditions/antlib.xml b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/conditions/antlib.xml
new file mode 100644
index 00000000..ff407b28
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/conditions/antlib.xml
@@ -0,0 +1,93 @@
+<?xml version="1.0"?>
+<antlib>
+ <!--
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+ -->
+ <!-- Ant 1.6+ antlib declaration for conditions:
+ Use with the declaration xmlns:cond="antlib:org.apache.tools.ant.types.conditions"
+ to
+ trigger Ant's autoload of this file into namespace 'cond' (or whatever name
+ suits).
+
+ Please keep this list in alphabetical order; it is easier to verify that way.
+
+ Additionally, ConditionBase uses this antlib to discover built-in conditions.
+ Prior to Ant 1.7, a new built-in condition required an addXXX method to be
+ added to ConditionBase. Conditions added in or after version 1.7 need only
+ to be added to this antlib.
+ -->
+
+ <typedef name="and" onerror="ignore"
+ classname="org.apache.tools.ant.taskdefs.condition.And"/>
+ <typedef name="antversion" onerror="ignore"
+ classname="org.apache.tools.ant.taskdefs.condition.AntVersion"/>
+ <typedef name="contains" onerror="ignore"
+ classname="org.apache.tools.ant.taskdefs.condition.Contains"/>
+ <typedef name="equals" onerror="ignore"
+ classname="org.apache.tools.ant.taskdefs.condition.Equals"/>
+ <typedef name="filesmatch" onerror="ignore"
+ classname="org.apache.tools.ant.taskdefs.condition.FilesMatch"/>
+ <typedef name="hasfreespace" onerror="ignore"
+ classname="org.apache.tools.ant.taskdefs.condition.HasFreeSpace"/>
+ <typedef name="http" onerror="ignore"
+ classname="org.apache.tools.ant.taskdefs.condition.Http"/>
+ <typedef name="isfailure" onerror="ignore"
+ classname="org.apache.tools.ant.taskdefs.condition.IsFailure"/>
+ <typedef name="isfalse" onerror="ignore"
+ classname="org.apache.tools.ant.taskdefs.condition.IsFalse"/>
+ <typedef name="isfileselected" onerror="ignore"
+ classname="org.apache.tools.ant.taskdefs.condition.IsFileSelected"/>
+ <typedef name="islastmodified" onerror="ignore"
+ classname="org.apache.tools.ant.taskdefs.condition.IsLastModified"/>
+ <typedef name="isreachable" onerror="ignore"
+ classname="org.apache.tools.ant.taskdefs.condition.IsReachable"/>
+ <typedef name="isreference" onerror="ignore"
+ classname="org.apache.tools.ant.taskdefs.condition.IsReference"/>
+ <typedef name="isset" onerror="ignore"
+ classname="org.apache.tools.ant.taskdefs.condition.IsSet"/>
+ <typedef name="issigned" onerror="ignore"
+ classname="org.apache.tools.ant.taskdefs.condition.IsSigned"/>
+ <typedef name="istrue" onerror="ignore"
+ classname="org.apache.tools.ant.taskdefs.condition.IsTrue"/>
+ <typedef name="not" onerror="ignore"
+ classname="org.apache.tools.ant.taskdefs.condition.Not"/>
+ <typedef name="matches" onerror="ignore"
+ classname="org.apache.tools.ant.taskdefs.condition.Matches"/>
+ <typedef name="or" onerror="ignore"
+ classname="org.apache.tools.ant.taskdefs.condition.Or"/>
+ <typedef name="os" onerror="ignore"
+ classname="org.apache.tools.ant.taskdefs.condition.Os"/>
+ <typedef name="parsersupports" onerror="ignore"
+ classname="org.apache.tools.ant.taskdefs.condition.ParserSupports"/>
+ <typedef name="resourceexists" onerror="ignore"
+ classname="org.apache.tools.ant.taskdefs.condition.ResourceExists"/>
+ <typedef name="resourcesmatch" onerror="ignore"
+ classname="org.apache.tools.ant.taskdefs.condition.ResourcesMatch"/>
+ <typedef name="resourcecontains" onerror="ignore"
+ classname="org.apache.tools.ant.taskdefs.condition.ResourceContains"/>
+ <typedef name="scriptcondition" onerror="ignore"
+ classname="org.apache.tools.ant.types.optional.ScriptCondition"/>
+ <typedef name="socket" onerror="ignore"
+ classname="org.apache.tools.ant.taskdefs.condition.Socket"/>
+ <typedef name="typefound" onerror="ignore"
+ classname="org.apache.tools.ant.taskdefs.condition.TypeFound"/>
+ <typedef name="xor" onerror="ignore"
+ classname="org.apache.tools.ant.taskdefs.condition.Xor"/>
+</antlib>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/defaults.properties b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/defaults.properties
new file mode 100644
index 00000000..29771dbb
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/defaults.properties
@@ -0,0 +1,101 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+description=org.apache.tools.ant.types.Description
+filterchain=org.apache.tools.ant.types.FilterChain
+filterreader=org.apache.tools.ant.types.AntFilterReader
+filterset=org.apache.tools.ant.types.FilterSet
+mapper=org.apache.tools.ant.types.Mapper
+redirector=org.apache.tools.ant.types.RedirectorElement
+patternset=org.apache.tools.ant.types.PatternSet
+regexp=org.apache.tools.ant.types.RegularExpression
+substitution=org.apache.tools.ant.types.Substitution
+xmlcatalog=org.apache.tools.ant.types.XMLCatalog
+extensionSet=org.apache.tools.ant.taskdefs.optional.extension.ExtensionSet
+extension=org.apache.tools.ant.taskdefs.optional.extension.ExtensionAdapter
+selector=org.apache.tools.ant.types.selectors.SelectSelector
+signedselector=org.apache.tools.ant.types.selectors.SignedSelector
+scriptfilter=org.apache.tools.ant.types.optional.ScriptFilter
+assertions=org.apache.tools.ant.types.Assertions
+concatfilter=org.apache.tools.ant.filters.ConcatFilter
+mavenrepository=org.apache.tools.ant.taskdefs.repository.MavenRepository
+scriptselector=org.apache.tools.ant.types.optional.ScriptSelector
+scriptmapper=org.apache.tools.ant.types.optional.ScriptMapper
+
+# different filename mappers
+identitymapper=org.apache.tools.ant.util.IdentityMapper
+flattenmapper=org.apache.tools.ant.util.FlatFileNameMapper
+globmapper=org.apache.tools.ant.util.GlobPatternMapper
+mergemapper=org.apache.tools.ant.util.MergingMapper
+regexpmapper=org.apache.tools.ant.util.RegexpPatternMapper
+packagemapper=org.apache.tools.ant.util.PackageNameMapper
+unpackagemapper=org.apache.tools.ant.util.UnPackageNameMapper
+compositemapper=org.apache.tools.ant.util.CompositeMapper
+chainedmapper=org.apache.tools.ant.util.ChainedMapper
+filtermapper=org.apache.tools.ant.types.mappers.FilterMapper
+firstmatchmapper=org.apache.tools.ant.util.FirstMatchMapper
+cutdirsmapper=org.apache.tools.ant.types.mappers.CutDirsMapper
+
+#this condition is in here because it is the sole
+#condition defined in Ant1.6
+#please add new conditions to oata.types.conditions/antlib.xml instead of
+#here, to avoid namespace clash with things like selectors.
+isfileselected=org.apache.tools.ant.taskdefs.condition.IsFileSelected
+scriptcondition=org.apache.tools.ant.types.optional.ScriptCondition
+
+#ResourceCollections:
+dirset=org.apache.tools.ant.types.DirSet
+filelist=org.apache.tools.ant.types.FileList
+fileset=org.apache.tools.ant.types.FileSet
+path=org.apache.tools.ant.types.Path
+propertyset=org.apache.tools.ant.types.PropertySet
+zipfileset=org.apache.tools.ant.types.ZipFileSet
+classfileset=org.apache.tools.ant.types.optional.depend.ClassfileSet
+libfileset=org.apache.tools.ant.taskdefs.optional.extension.LibFileSet
+files=org.apache.tools.ant.types.resources.Files
+restrict=org.apache.tools.ant.types.resources.Restrict
+union=org.apache.tools.ant.types.resources.Union
+difference=org.apache.tools.ant.types.resources.Difference
+intersect=org.apache.tools.ant.types.resources.Intersect
+sort=org.apache.tools.ant.types.resources.Sort
+resources=org.apache.tools.ant.types.resources.Resources
+allbutfirst=org.apache.tools.ant.types.resources.AllButFirst
+allbutlast=org.apache.tools.ant.types.resources.AllButLast
+first=org.apache.tools.ant.types.resources.First
+last=org.apache.tools.ant.types.resources.Last
+tarfileset=org.apache.tools.ant.types.TarFileSet
+tokens=org.apache.tools.ant.types.resources.Tokens
+mappedresources=org.apache.tools.ant.types.resources.MappedResourceCollection
+archives=org.apache.tools.ant.types.resources.Archives
+resourcelist=org.apache.tools.ant.types.resources.ResourceList
+
+#Resources (single-element ResourceCollections):
+resource=org.apache.tools.ant.types.Resource
+file=org.apache.tools.ant.types.resources.FileResource
+url=org.apache.tools.ant.types.resources.URLResource
+string=org.apache.tools.ant.types.resources.StringResource
+zipentry=org.apache.tools.ant.types.resources.ZipResource
+propertyresource=org.apache.tools.ant.types.resources.PropertyResource
+tarentry=org.apache.tools.ant.types.resources.TarResource
+gzipresource=org.apache.tools.ant.types.resources.GZipResource
+bzip2resource=org.apache.tools.ant.types.resources.BZip2Resource
+javaresource=org.apache.tools.ant.types.resources.JavaResource
+multirootfileset=org.apache.tools.ant.types.resources.MultiRootFileSet
+javaconstant=org.apache.tools.ant.types.resources.JavaConstantResource
+
+#tokenizer implementations
+linetokenizer=org.apache.tools.ant.util.LineTokenizer
+stringtokenizer=org.apache.tools.ant.util.StringTokenizer
+filetokenizer=org.apache.tools.ant.util.FileTokenizer
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/mappers/CutDirsMapper.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/mappers/CutDirsMapper.java
new file mode 100644
index 00000000..b9e7cfb4
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/mappers/CutDirsMapper.java
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.mappers;
+
+import java.io.File;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.util.FileNameMapper;
+
+/**
+ * A mapper that strips of the a configurable number of leading
+ * directories from a file name.
+ *
+ * <p>This mapper was inspired by a user-list thread that mentioned
+ * wget's --cut-dirs option.</p>
+ *
+ * @see <a href="http://mail-archives.apache.org/mod_mbox/ant-user/201009.mbox/%3C51772743BEA5D44A9EA5BF52AADDD6FB010E96F6@hammai008.delphi.local%3E">
+ * simplify copy with regexpmapper</a>
+ */
+public class CutDirsMapper implements FileNameMapper {
+ private int dirs = 0;
+
+ /**
+ * The number of leading directories to cut.
+ */
+ public void setDirs(final int dirs) {
+ this.dirs = dirs;
+ }
+
+ /**
+ * Empty implementation.
+ * @param ignore ignored.
+ */
+ public void setFrom(final String ignore) {
+ }
+
+ /**
+ * Empty implementation.
+ * @param ignore ignored.
+ */
+ public void setTo(final String ignore) {
+ }
+
+ /** {@inheritDoc}. */
+ public String[] mapFileName(final String sourceFileName) {
+ if (dirs <= 0) {
+ throw new BuildException("dirs must be set to a positive number");
+ }
+ final char fileSep = File.separatorChar;
+ final String fileSepCorrected =
+ sourceFileName.replace('/', fileSep).replace('\\', fileSep);
+ int nthMatch = fileSepCorrected.indexOf(fileSep);
+ for (int n = 1; nthMatch > -1 && n < dirs; n++) {
+ nthMatch = fileSepCorrected.indexOf(fileSep, nthMatch + 1);
+ }
+ if (nthMatch == -1) {
+ return null;
+ }
+ return new String[] {sourceFileName.substring(nthMatch + 1)};
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/mappers/FilterMapper.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/mappers/FilterMapper.java
new file mode 100644
index 00000000..501da500
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/mappers/FilterMapper.java
@@ -0,0 +1,87 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types.mappers;
+
+import java.io.Reader;
+import java.io.StringReader;
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.UnsupportedAttributeException;
+import org.apache.tools.ant.filters.util.ChainReaderHelper;
+import org.apache.tools.ant.types.FilterChain;
+import org.apache.tools.ant.util.FileNameMapper;
+import org.apache.tools.ant.util.FileUtils;
+
+/**
+ * This is a FileNameMapper based on a FilterChain.
+ */
+public class FilterMapper extends FilterChain implements FileNameMapper {
+
+ private static final int BUFFER_SIZE = 8192;
+
+ /**
+ * From attribute not supported.
+ * @param from a string
+ * @throws BuildException always
+ */
+ public void setFrom(String from) {
+ throw new UnsupportedAttributeException(
+ "filtermapper doesn't support the \"from\" attribute.", "from");
+ }
+
+ /**
+ * From attribute not supported.
+ * @param to a string
+ * @throws BuildException always
+ */
+ public void setTo(String to) {
+ throw new UnsupportedAttributeException(
+ "filtermapper doesn't support the \"to\" attribute.", "to");
+ }
+
+ /**
+ * Return the result of the filters on the sourcefilename.
+ * @param sourceFileName the filename to map
+ * @return a one-element array of converted filenames, or null if
+ * the filterchain returns an empty string.
+ */
+ public String[] mapFileName(String sourceFileName) {
+ try {
+ Reader stringReader = new StringReader(sourceFileName);
+ ChainReaderHelper helper = new ChainReaderHelper();
+ helper.setBufferSize(BUFFER_SIZE);
+ helper.setPrimaryReader(stringReader);
+ helper.setProject(getProject());
+ Vector<FilterChain> filterChains = new Vector<FilterChain>();
+ filterChains.add(this);
+ helper.setFilterChains(filterChains);
+ String result = FileUtils.safeReadFully(helper.getAssembledReader());
+ if (result.length() == 0) {
+ return null;
+ } else {
+ return new String[] {result};
+ }
+ } catch (BuildException ex) {
+ throw ex;
+ } catch (Exception ex) {
+ throw new BuildException(ex);
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/optional/AbstractScriptComponent.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/optional/AbstractScriptComponent.java
new file mode 100644
index 00000000..df5a3cec
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/optional/AbstractScriptComponent.java
@@ -0,0 +1,158 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.optional;
+
+import java.io.File;
+
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.ProjectComponent;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.types.Reference;
+import org.apache.tools.ant.util.ScriptRunnerBase;
+import org.apache.tools.ant.util.ScriptRunnerHelper;
+
+/**
+ * This is a {@link ProjectComponent} that has script support built in
+ * Use it as a foundation for scriptable things.
+ */
+public abstract class AbstractScriptComponent extends ProjectComponent {
+ /**
+ * script runner helper
+ */
+ private ScriptRunnerHelper helper = new ScriptRunnerHelper();
+
+ /**
+ * script runner.
+ */
+ private ScriptRunnerBase runner = null;
+
+ /**
+ * Set the project.
+ * @param project the owner of this component.
+ */
+ public void setProject(Project project) {
+ super.setProject(project);
+ helper.setProjectComponent(this);
+ }
+
+ /**
+ * Get our script runner
+ * @return the runner
+ */
+ public ScriptRunnerBase getRunner() {
+ initScriptRunner();
+ return runner;
+ }
+
+ /**
+ * Load the script from an external file ; optional.
+ *
+ * @param file the file containing the script source.
+ */
+ public void setSrc(File file) {
+ helper.setSrc(file);
+ }
+
+ /**
+ * The script text.
+ *
+ * @param text a component of the script text to be added.
+ */
+ public void addText(String text) {
+ helper.addText(text);
+ }
+
+ /**
+ * Defines the manager.
+ *
+ * @param manager the scripting manager.
+ */
+ public void setManager(String manager) {
+ helper.setManager(manager);
+ }
+
+ /**
+ * Defines the language (required).
+ *
+ * @param language the scripting language name for the script.
+ */
+ public void setLanguage(String language) {
+ helper.setLanguage(language);
+ }
+
+ /**
+ * Initialize the script runner. Calls this before running the system
+ */
+ protected void initScriptRunner() {
+ if (runner != null) {
+ return;
+ }
+ helper.setProjectComponent(this);
+ runner = helper.getScriptRunner();
+ }
+ /**
+ * Set the classpath to be used when searching for classes and resources.
+ *
+ * @param classpath an Ant Path object containing the search path.
+ */
+ public void setClasspath(Path classpath) {
+ helper.setClasspath(classpath);
+ }
+
+ /**
+ * Classpath to be used when searching for classes and resources.
+ *
+ * @return an empty Path instance to be configured by Ant.
+ */
+ public Path createClasspath() {
+ return helper.createClasspath();
+ }
+
+ /**
+ * Set the classpath by reference.
+ *
+ * @param r a Reference to a Path instance to be used as the classpath
+ * value.
+ */
+ public void setClasspathRef(Reference r) {
+ helper.setClasspathRef(r);
+ }
+
+ /**
+ * Run a script
+ * @param execName name of the script
+ */
+ protected void executeScript(String execName) {
+ getRunner().executeScript(execName);
+ }
+
+ /**
+ * Set the setbeans attribute.
+ * If this is true, &lt;script&gt; will create variables in the
+ * script instance for all
+ * properties, targets and references of the current project.
+ * It this is false, only the project and self variables will
+ * be set.
+ * The default is true.
+ * @param setBeans the value to set.
+ * @since Ant 1.8.0
+ */
+ public void setSetBeans(boolean setBeans) {
+ helper.setSetBeans(setBeans);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/optional/ScriptCondition.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/optional/ScriptCondition.java
new file mode 100644
index 00000000..fac02bfa
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/optional/ScriptCondition.java
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.optional;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.taskdefs.condition.Condition;
+
+/**
+ * A condition that lets you include script.
+ * The condition component sets a bean "self", whose attribute "value"
+ * must be set to true for the condition to succeed, false to fail.
+ * The default is 'false'
+ */
+public class ScriptCondition extends AbstractScriptComponent implements Condition {
+
+ /**
+ * result field
+ */
+ private boolean value = false;
+
+ /**
+ * Is this condition true?
+ *
+ * @return true if the condition is true
+ *
+ * @throws org.apache.tools.ant.BuildException
+ * if an error occurs
+ */
+ public boolean eval() throws BuildException {
+ initScriptRunner();
+ executeScript("ant_condition");
+ return getValue();
+ }
+
+ /**
+ * get the current value of the condition
+ * @return true if the condition
+ */
+ public boolean getValue() {
+ return value;
+ }
+
+ /**
+ * set the value of the condition.
+ * This is used by the script to pass the return value.
+ * It can be used by an attribute, in which case it sets the default
+ * value
+ * @param value the value to set the condition to
+ */
+ public void setValue(boolean value) {
+ this.value = value;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/optional/ScriptFilter.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/optional/ScriptFilter.java
new file mode 100644
index 00000000..3f6ec88f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/optional/ScriptFilter.java
@@ -0,0 +1,183 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types.optional;
+
+import java.io.File;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.filters.TokenFilter;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.types.Reference;
+import org.apache.tools.ant.util.ScriptRunnerBase;
+import org.apache.tools.ant.util.ScriptRunnerHelper;
+
+/**
+ * Most of this is CAP (Cut And Paste) from the Script task
+ * ScriptFilter class, implements TokenFilter.Filter
+ * for scripts to use.
+ * This provides the same beans as the Script Task
+ * to a script.
+ * The script is meant to use get self.token and
+ * set self.token in the reply.
+ *
+ * @since Ant 1.6
+ */
+public class ScriptFilter extends TokenFilter.ChainableReaderFilter {
+ /** script runner helper */
+ private ScriptRunnerHelper helper = new ScriptRunnerHelper();
+
+ /** script runner. */
+ private ScriptRunnerBase runner = null;
+
+ /** the token used by the script */
+ private String token;
+
+ /**
+ * Set the project.
+ * @param project the owner of this component.
+ */
+ public void setProject(Project project) {
+ super.setProject(project);
+ helper.setProjectComponent(this);
+ }
+
+ /**
+ * Defines the language (required).
+ *
+ * @param language the scripting language name for the script.
+ */
+ public void setLanguage(String language) {
+ helper.setLanguage(language);
+ }
+
+ /**
+ * Initialize.
+ *
+ * @exception BuildException if someting goes wrong
+ */
+ private void init() throws BuildException {
+ if (runner != null) {
+ return;
+ }
+ runner = helper.getScriptRunner();
+ }
+
+ /**
+ * The current token
+ *
+ * @param token the string filtered by the script
+ */
+ public void setToken(String token) {
+ this.token = token;
+ }
+
+ /**
+ * The current token
+ *
+ * @return the string filtered by the script
+ */
+ public String getToken() {
+ return token;
+ }
+
+ /**
+ * Called filter the token.
+ * This sets the token in this object, calls
+ * the script and returns the token.
+ *
+ * @param token the token to be filtered
+ * @return the filtered token
+ */
+ public String filter(String token) {
+ init();
+ setToken(token);
+ runner.executeScript("ant_filter");
+ return getToken();
+ }
+
+ /**
+ * Load the script from an external file ; optional.
+ *
+ * @param file the file containing the script source.
+ */
+ public void setSrc(File file) {
+ helper.setSrc(file);
+ }
+
+ /**
+ * The script text.
+ *
+ * @param text a component of the script text to be added.
+ */
+ public void addText(String text) {
+ helper.addText(text);
+ }
+
+ /**
+ * Defines the manager.
+ *
+ * @param manager the scripting manager.
+ */
+ public void setManager(String manager) {
+ helper.setManager(manager);
+ }
+ /**
+ * Set the classpath to be used when searching for classes and resources.
+ *
+ * @param classpath an Ant Path object containing the search path.
+ */
+ public void setClasspath(Path classpath) {
+ helper.setClasspath(classpath);
+ }
+
+ /**
+ * Classpath to be used when searching for classes and resources.
+ *
+ * @return an empty Path instance to be configured by Ant.
+ */
+ public Path createClasspath() {
+ return helper.createClasspath();
+ }
+
+ /**
+ * Set the classpath by reference.
+ *
+ * @param r a Reference to a Path instance to be used as the classpath
+ * value.
+ */
+ public void setClasspathRef(Reference r) {
+ helper.setClasspathRef(r);
+ }
+
+ /**
+ * Set the setbeans attribute.
+ * If this is true, &lt;script&gt; will create variables in the
+ * script instance for all
+ * properties, targets and references of the current project.
+ * It this is false, only the project and self variables will
+ * be set.
+ * The default is true.
+ * @param setBeans the value to set.
+ * @since Ant 1.8.0
+ */
+ public void setSetBeans(boolean setBeans) {
+ helper.setSetBeans(setBeans);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/optional/ScriptMapper.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/optional/ScriptMapper.java
new file mode 100644
index 00000000..38dab0bb
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/optional/ScriptMapper.java
@@ -0,0 +1,91 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.optional;
+
+import java.util.ArrayList;
+
+import org.apache.tools.ant.util.FileNameMapper;
+
+/**
+ * Script support at map time.
+ * @since Ant1.7
+ */
+public class ScriptMapper extends AbstractScriptComponent implements FileNameMapper {
+
+ private ArrayList<String> files;
+
+
+ /**
+ * Sets the from part of the transformation rule.
+ *
+ * @param from a string.
+ */
+ public void setFrom(String from) {
+
+ }
+
+ /**
+ * Sets the to part of the transformation rule.
+ *
+ * @param to a string.
+ */
+ public void setTo(String to) {
+
+ }
+
+ /**
+ * Reset the list of files
+ */
+ public void clear() {
+ files = new ArrayList<String>(1);
+ }
+
+ /**
+ * Add a mapped name
+ * @param mapping the value to use.
+ */
+ public void addMappedName(String mapping) {
+ files.add(mapping);
+ }
+
+ /**
+ * Returns an array containing the target filename(s) for the given source
+ * file.
+ * <p/>
+ * <p>if the given rule doesn't apply to the source file, implementation
+ * must return null. SourceFileScanner will then omit the source file in
+ * question.</p>
+ *
+ * @param sourceFileName the name of the source file relative to some given
+ * basedirectory.
+ * @return an array of strings if the rule applies to the source file, or
+ * null if it does not.
+ */
+
+ public String[] mapFileName(String sourceFileName) {
+ initScriptRunner();
+ getRunner().addBean("source", sourceFileName);
+ clear();
+ executeScript("ant_mapper");
+ if (files.size() == 0) {
+ return null;
+ } else {
+ return files.toArray(new String[files.size()]);
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/optional/ScriptSelector.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/optional/ScriptSelector.java
new file mode 100644
index 00000000..ca28f69f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/optional/ScriptSelector.java
@@ -0,0 +1,223 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.optional;
+
+import java.io.File;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.types.Reference;
+import org.apache.tools.ant.types.selectors.BaseSelector;
+import org.apache.tools.ant.util.ScriptRunnerBase;
+import org.apache.tools.ant.util.ScriptRunnerHelper;
+
+/**
+ * Selector that lets you run a script with selection logic inline
+ * @since Ant1.7
+ */
+public class ScriptSelector extends BaseSelector {
+
+ /**
+ * script runner helper
+ */
+ private ScriptRunnerHelper helper = new ScriptRunnerHelper();
+
+ /**
+ * script runner
+ */
+ private ScriptRunnerBase runner;
+
+ /**
+ * fields updated for every selection
+ */
+ private File basedir;
+ private String filename;
+ private File file;
+
+ /**
+ * selected flag
+ */
+ private boolean selected;
+
+ /**
+ * Set the project.
+ * @param project the owner of this component.
+ */
+ public void setProject(Project project) {
+ super.setProject(project);
+ helper.setProjectComponent(this);
+ }
+
+ /**
+ * Defines the manager.
+ *
+ * @param manager the scripting manager.
+ */
+ public void setManager(String manager) {
+ helper.setManager(manager);
+ }
+
+ /**
+ * Defines the language (required).
+ *
+ * @param language the scripting language name for the script.
+ */
+ public void setLanguage(String language) {
+ helper.setLanguage(language);
+ }
+
+ /**
+ * Initialize on demand.
+ *
+ * @throws org.apache.tools.ant.BuildException
+ * if someting goes wrong
+ */
+ private void init() throws BuildException {
+ if (runner != null) {
+ return;
+ }
+ runner = helper.getScriptRunner();
+ }
+
+ /**
+ * Load the script from an external file ; optional.
+ *
+ * @param file the file containing the script source.
+ */
+ public void setSrc(File file) {
+ helper.setSrc(file);
+ }
+
+ /**
+ * The script text.
+ *
+ * @param text a component of the script text to be added.
+ */
+ public void addText(String text) {
+ helper.addText(text);
+ }
+
+ /**
+ * Set the classpath to be used when searching for classes and resources.
+ *
+ * @param classpath an Ant Path object containing the search path.
+ */
+ public void setClasspath(Path classpath) {
+ helper.setClasspath(classpath);
+ }
+
+ /**
+ * Classpath to be used when searching for classes and resources.
+ *
+ * @return an empty Path instance to be configured by Ant.
+ */
+ public Path createClasspath() {
+ return helper.createClasspath();
+ }
+
+ /**
+ * Set the classpath by reference.
+ *
+ * @param r a Reference to a Path instance to be used as the classpath
+ * value.
+ */
+ public void setClasspathRef(Reference r) {
+ helper.setClasspathRef(r);
+ }
+
+ /**
+ * Set the setbeans attribute.
+ * If this is true, &lt;script&gt; will create variables in the
+ * script instance for all
+ * properties, targets and references of the current project.
+ * It this is false, only the project and self variables will
+ * be set.
+ * The default is true.
+ * @param setBeans the value to set.
+ */
+ public void setSetBeans(boolean setBeans) {
+ helper.setSetBeans(setBeans);
+ }
+
+ /**
+ * Method that each selector will implement to create their selection
+ * behaviour. If there is a problem with the setup of a selector, it can
+ * throw a BuildException to indicate the problem.
+ *
+ * @param basedir A java.io.File object for the base directory
+ * @param filename The name of the file to check
+ * @param file A File object for this filename
+ *
+ * @return whether the file should be selected or not
+ */
+ public boolean isSelected(File basedir, String filename, File file) {
+ init();
+ setSelected(true);
+ this.file = file;
+ this.basedir = basedir;
+ this.filename = filename;
+ runner.addBean("basedir", basedir);
+ runner.addBean("filename", filename);
+ runner.addBean("file", file);
+ runner.executeScript("ant_selector");
+ return isSelected();
+ }
+
+ /**
+ * get the base directory
+ * @return the base directory
+ */
+ public File getBasedir() {
+ return basedir;
+ }
+
+ /**
+ * get the filename of the file
+ * @return the filename of the file that is currently been tested
+ */
+ public String getFilename() {
+ return filename;
+ }
+
+ /**
+ * get the file that is currently to be tested
+ * @return the file that is currently been tested
+ */
+ public File getFile() {
+ return file;
+ }
+
+ /**
+ * get state of selected flag
+ * @return the selected flag
+ */
+ public boolean isSelected() {
+ return selected;
+ }
+
+ /**
+ * set the selected state
+ * Intended for script use, not as an Ant attribute
+ * @param selected the selected state
+ */
+ public void setSelected(boolean selected) {
+ this.selected = selected;
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/optional/depend/ClassfileSet.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/optional/depend/ClassfileSet.java
new file mode 100644
index 00000000..f2fe69b1
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/optional/depend/ClassfileSet.java
@@ -0,0 +1,183 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.optional.depend;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Stack;
+import java.util.Vector;
+
+import org.apache.tools.ant.DirectoryScanner;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.FileSet;
+import org.apache.tools.ant.util.StringUtils;
+
+/**
+ * A ClassfileSet is a FileSet that enlists all classes that depend on a
+ * certain set of root classes.
+ *
+ * ClassfileSet extends FileSet, its inherited properties
+ * defining the domain searched for dependent classes.
+ *
+ */
+public class ClassfileSet extends FileSet {
+ /**
+ * The list of root classes for this class file set. These are the
+ * classes which must be included in the fileset and which are the
+ * starting point for the dependency search.
+ */
+ private List<String> rootClasses = new ArrayList<String>();
+
+ /**
+ * The list of filesets which contain root classes.
+ */
+ private List<FileSet> rootFileSets = new ArrayList<FileSet>();
+
+ /**
+ * Inner class used to contain info about root classes.
+ */
+ public static class ClassRoot {
+ /** The name of the root class */
+ private String rootClass;
+
+ /**
+ * Set the root class name.
+ *
+ * @param name the name of the root class.
+ */
+ public void setClassname(String name) {
+ this.rootClass = name;
+ }
+
+ /**
+ * Get the name of the root class.
+ *
+ * @return the name of the root class.
+ */
+ public String getClassname() {
+ return rootClass;
+ }
+ }
+
+ /**
+ * Default constructor.
+ */
+ public ClassfileSet() {
+ }
+
+ /**
+ * Add a fileset to which contains a collection of root classes used to
+ * drive the search from classes.
+ *
+ * @param rootFileSet a root file set to be used to search for dependent
+ * classes.
+ */
+ public void addRootFileset(FileSet rootFileSet) {
+ rootFileSets.add(rootFileSet);
+ setChecked(false);
+ }
+
+ /**
+ * Create a ClassfileSet from another ClassfileSet.
+ *
+ * @param s the other classfileset.
+ */
+ protected ClassfileSet(ClassfileSet s) {
+ super(s);
+ rootClasses.addAll(s.rootClasses);
+ }
+
+ /**
+ * Set the root class attribute.
+ *
+ * @param rootClass the name of the root class.
+ */
+ public void setRootClass(String rootClass) {
+ rootClasses.add(rootClass);
+ }
+
+ /**
+ * Return the DirectoryScanner associated with this FileSet.
+ *
+ * @param p the project used to resolve dirs, etc.
+ *
+ * @return a dependency scanner.
+ */
+ public DirectoryScanner getDirectoryScanner(Project p) {
+ if (isReference()) {
+ return getRef(p).getDirectoryScanner(p);
+ }
+ dieOnCircularReference(p);
+ DirectoryScanner parentScanner = super.getDirectoryScanner(p);
+ DependScanner scanner = new DependScanner(parentScanner);
+ final Vector<String> allRootClasses = new Vector<String>(rootClasses);
+ for (FileSet additionalRootSet : rootFileSets) {
+ DirectoryScanner additionalScanner
+ = additionalRootSet.getDirectoryScanner(p);
+ String[] files = additionalScanner.getIncludedFiles();
+ for (int i = 0; i < files.length; ++i) {
+ if (files[i].endsWith(".class")) {
+ String classFilePath = StringUtils.removeSuffix(files[i], ".class");
+ String className
+ = classFilePath.replace('/', '.').replace('\\', '.');
+ allRootClasses.addElement(className);
+ }
+ }
+ scanner.addBasedir(additionalRootSet.getDir(p));
+ }
+ scanner.setBasedir(getDir(p));
+ scanner.setRootClasses(allRootClasses);
+ scanner.scan();
+ return scanner;
+ }
+
+ /**
+ * Add a nested root class definition to this class file set.
+ *
+ * @param root the configured class root.
+ */
+ public void addConfiguredRoot(ClassRoot root) {
+ rootClasses.add(root.getClassname());
+ }
+
+ /**
+ * Clone this data type.
+ *
+ * @return a clone of the class file set.
+ */
+ public Object clone() {
+ return new ClassfileSet(isReference()
+ ? (ClassfileSet) (getRef(getProject())) : this);
+ }
+
+ protected synchronized void dieOnCircularReference(Stack<Object> stk, Project p) {
+ if (isChecked()) {
+ return;
+ }
+
+ // takes care of nested selectors
+ super.dieOnCircularReference(stk, p);
+
+ if (!isReference()) {
+ for (FileSet additionalRootSet : rootFileSets) {
+ pushAndInvokeCircularReferenceCheck(additionalRootSet, stk, p);
+ }
+ setChecked(true);
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/optional/depend/DependScanner.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/optional/depend/DependScanner.java
new file mode 100644
index 00000000..bb3cf54b
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/optional/depend/DependScanner.java
@@ -0,0 +1,225 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.optional.depend;
+
+import java.io.File;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.DirectoryScanner;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.util.depend.DependencyAnalyzer;
+
+
+/**
+ * DirectoryScanner for finding class dependencies.
+ */
+public class DependScanner extends DirectoryScanner {
+ /**
+ * The name of the analyzer to use by default.
+ */
+ public static final String DEFAULT_ANALYZER_CLASS
+ = "org.apache.tools.ant.util.depend.bcel.FullAnalyzer";
+
+ /**
+ * The root classes to drive the search for dependent classes.
+ */
+ private Vector<String> rootClasses;
+
+ /**
+ * The names of the classes to include in the fileset.
+ */
+ private Vector<String> included;
+
+ private Vector<File> additionalBaseDirs = new Vector<File>();
+
+ /**
+ * The parent scanner which gives the basic set of files. Only files which
+ * are in this set and which can be reached from a root class will end
+ * up being included in the result set.
+ */
+ private DirectoryScanner parentScanner;
+
+ /**
+ * Create a DependScanner, using the given scanner to provide the basic
+ * set of files from which class files come.
+ *
+ * @param parentScanner the DirectoryScanner which returns the files from
+ * which class files must come.
+ */
+ public DependScanner(DirectoryScanner parentScanner) {
+ this.parentScanner = parentScanner;
+ }
+
+ /**
+ * Sets the root classes to be used to drive the scan.
+ *
+ * @param rootClasses the rootClasses to be used for this scan.
+ */
+ public synchronized void setRootClasses(Vector<String> rootClasses) {
+ this.rootClasses = rootClasses;
+ }
+
+ /**
+ * Get the names of the class files on which baseClass depends.
+ *
+ * @return the names of the files.
+ */
+ public String[] getIncludedFiles() {
+ String[] files = new String[getIncludedFilesCount()];
+ for (int i = 0; i < files.length; i++) {
+ files[i] = (String) included.elementAt(i);
+ }
+ return files;
+ }
+
+ /** {@inheritDoc}. */
+ public synchronized int getIncludedFilesCount() {
+ if (included == null) {
+ throw new IllegalStateException();
+ }
+ return included.size();
+ }
+
+ /**
+ * Scans the base directory for files on which baseClass depends.
+ *
+ * @exception IllegalStateException when basedir was set incorrectly.
+ */
+ public synchronized void scan() throws IllegalStateException {
+ included = new Vector<String>();
+ String analyzerClassName = DEFAULT_ANALYZER_CLASS;
+ DependencyAnalyzer analyzer = null;
+ try {
+ Class<? extends DependencyAnalyzer> analyzerClass = Class.forName(analyzerClassName)
+ .asSubclass(DependencyAnalyzer.class);
+ analyzer = analyzerClass.newInstance();
+ } catch (Exception e) {
+ throw new BuildException("Unable to load dependency analyzer: "
+ + analyzerClassName, e);
+ }
+ analyzer.addClassPath(new Path(null, basedir.getPath()));
+ for (Enumeration<File> e = additionalBaseDirs.elements(); e.hasMoreElements();) {
+ File additionalBaseDir = e.nextElement();
+ analyzer.addClassPath(new Path(null, additionalBaseDir.getPath()));
+ }
+
+ for (Enumeration<String> e = rootClasses.elements(); e.hasMoreElements();) {
+ String rootClass = e.nextElement();
+ analyzer.addRootClass(rootClass);
+ }
+ Enumeration<String> e = analyzer.getClassDependencies();
+
+ String[] parentFiles = parentScanner.getIncludedFiles();
+ Hashtable<String, String> parentSet = new Hashtable<String, String>();
+ for (int i = 0; i < parentFiles.length; ++i) {
+ parentSet.put(parentFiles[i], parentFiles[i]);
+ }
+ while (e.hasMoreElements()) {
+ String classname = (String) e.nextElement();
+ String filename = classname.replace('.', File.separatorChar);
+ filename = filename + ".class";
+ File depFile = new File(basedir, filename);
+ if (depFile.exists() && parentSet.containsKey(filename)) {
+ // This is included
+ included.addElement(filename);
+ }
+ }
+ }
+
+ /**
+ * @see DirectoryScanner#addDefaultExcludes
+ */
+ public void addDefaultExcludes() {
+ }
+
+ /**
+ * @see DirectoryScanner#getExcludedDirectories
+ */
+ /** {@inheritDoc}. */
+ public String[] getExcludedDirectories() {
+ return null;
+ }
+
+ /**
+ * @see DirectoryScanner#getExcludedFiles
+ */
+ /** {@inheritDoc}. */
+ public String[] getExcludedFiles() {
+ return null;
+ }
+
+ /**
+ * @see DirectoryScanner#getIncludedDirectories
+ */
+ /** {@inheritDoc}. */
+ public String[] getIncludedDirectories() {
+ return new String[0];
+ }
+
+ /**
+ * @see DirectoryScanner#getIncludedDirsCount
+ */
+ /** {@inheritDoc}. */
+ public int getIncludedDirsCount() {
+ return 0;
+ }
+
+ /**
+ * @see DirectoryScanner#getNotIncludedDirectories
+ */
+ /** {@inheritDoc}. */
+ public String[] getNotIncludedDirectories() {
+ return null;
+ }
+
+ /**
+ * @see DirectoryScanner#getNotIncludedFiles
+ */
+ /** {@inheritDoc}. */
+ public String[] getNotIncludedFiles() {
+ return null;
+ }
+
+ /**
+ * @see DirectoryScanner#setExcludes
+ */
+ /** {@inheritDoc}. */
+ public void setExcludes(String[] excludes) {
+ }
+
+ /**
+ * @see DirectoryScanner#setIncludes
+ */
+ /** {@inheritDoc}. */
+ public void setIncludes(String[] includes) {
+ }
+
+ /**
+ * @see DirectoryScanner#setCaseSensitive
+ */
+ /** {@inheritDoc}. */
+ public void setCaseSensitive(boolean isCaseSensitive) {
+ }
+
+ public void addBasedir(File baseDir) {
+ additionalBaseDirs.addElement(baseDir);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/optional/image/Arc.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/optional/image/Arc.java
new file mode 100644
index 00000000..3d8b29b2
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/optional/image/Arc.java
@@ -0,0 +1,123 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.optional.image;
+
+import java.awt.BasicStroke;
+import java.awt.Graphics2D;
+import java.awt.geom.Arc2D;
+import java.awt.image.BufferedImage;
+
+import javax.media.jai.PlanarImage;
+
+/**
+ * Draw an arc.
+ */
+public class Arc extends BasicShape implements DrawOperation {
+ // CheckStyle:VisibilityModifier OFF - bc
+ protected int width = 0;
+ protected int height = 0;
+ protected int start = 0;
+ protected int stop = 0;
+ protected int type = Arc2D.OPEN;
+ // CheckStyle:VisibilityModifier ON
+
+ /**
+ * Set the width.
+ * @param width the width of the arc.
+ */
+ public void setWidth(int width) {
+ this.width = width;
+ }
+
+ /**
+ * Set the height.
+ * @param height the height of the arc.
+ */
+ public void setHeight(int height) {
+ this.height = height;
+ }
+
+ /**
+ * Set the start of the arc.
+ * @param start the start of the arc.
+ */
+ public void setStart(int start) {
+ this.start = start;
+ }
+
+ /**
+ * Set the stop of the arc.
+ * @param stop the stop of the arc.
+ */
+ public void setStop(int stop) {
+ this.stop = stop;
+ }
+
+ /**
+ * Set the type of arc.
+ * @param strType the type to use - open, pie or chord.
+ * @todo refactor using an EnumeratedAttribute
+ */
+ public void setType(String strType) {
+ if (strType.equalsIgnoreCase("open")) {
+ type = Arc2D.OPEN;
+ } else if (strType.equalsIgnoreCase("pie")) {
+ type = Arc2D.PIE;
+ } else if (strType.equalsIgnoreCase("chord")) {
+ type = Arc2D.CHORD;
+ }
+ }
+
+ /** {@inheritDoc}. */
+ public PlanarImage executeDrawOperation() {
+ BufferedImage bi = new BufferedImage(width + (stroke_width * 2),
+ height + (stroke_width * 2), BufferedImage.TYPE_4BYTE_ABGR_PRE);
+
+ Graphics2D graphics = (Graphics2D) bi.getGraphics();
+
+ if (!stroke.equals("transparent")) {
+ BasicStroke bStroke = new BasicStroke(stroke_width);
+ graphics.setColor(ColorMapper.getColorByName(stroke));
+ graphics.setStroke(bStroke);
+ graphics.draw(new Arc2D.Double(stroke_width, stroke_width, width,
+ height, start, stop, type));
+ }
+
+ if (!fill.equals("transparent")) {
+ graphics.setColor(ColorMapper.getColorByName(fill));
+ graphics.fill(new Arc2D.Double(stroke_width, stroke_width,
+ width, height, start, stop, type));
+ }
+
+
+ final int size = instructions.size();
+ for (int i = 0; i < size; i++) {
+ ImageOperation instr = ((ImageOperation) instructions.elementAt(i));
+ if (instr instanceof DrawOperation) {
+ PlanarImage img = ((DrawOperation) instr).executeDrawOperation();
+ graphics.drawImage(img.getAsBufferedImage(), null, 0, 0);
+ } else if (instr instanceof TransformOperation) {
+ graphics = (Graphics2D) bi.getGraphics();
+ PlanarImage image = ((TransformOperation) instr)
+ .executeTransformOperation(PlanarImage.wrapRenderedImage(bi));
+ bi = image.getAsBufferedImage();
+ }
+ }
+ return PlanarImage.wrapRenderedImage(bi);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/optional/image/BasicShape.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/optional/image/BasicShape.java
new file mode 100644
index 00000000..ee2113a7
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/optional/image/BasicShape.java
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.optional.image;
+
+
+/** Draw a basic shape */
+public abstract class BasicShape extends ImageOperation implements DrawOperation {
+ // CheckStyle:VisibilityModifier OFF - bc
+ // CheckStyle:MemberNameCheck OFF - bc
+ protected int stroke_width = 0;
+ // CheckStyle:MemberNameCheck ON
+ protected String fill = "transparent";
+ protected String stroke = "black";
+ // CheckStyle:VisibilityModifier ON
+
+
+ /**
+ * Set the fill attribute.
+ * @param col the color value to use.
+ */
+ public void setFill(String col) {
+ fill = col;
+ }
+
+ /**
+ * Set the stroke attribute.
+ * @param col the color value to use.
+ */
+ public void setStroke(String col) {
+ stroke = col;
+ }
+
+ /**
+ * Set the stroke width attribute.
+ * @param width the value to use.
+ */
+ public void setStrokewidth(int width) {
+ stroke_width = width;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/optional/image/ColorMapper.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/optional/image/ColorMapper.java
new file mode 100644
index 00000000..88e2871a
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/optional/image/ColorMapper.java
@@ -0,0 +1,102 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.optional.image;
+
+import java.awt.Color;
+
+/**
+ *
+ * @see org.apache.tools.ant.taskdefs.optional.image.Image
+ */
+public final class ColorMapper {
+ /** private constructor for Utility class */
+ private ColorMapper() {
+ }
+
+ /** black string */
+ public static final String COLOR_BLACK = "black";
+ /** blue string */
+ public static final String COLOR_BLUE = "blue";
+ /** cyan string */
+ public static final String COLOR_CYAN = "cyan";
+ /** black string */
+ public static final String COLOR_DARKGRAY = "darkgray";
+ /** gray string */
+ public static final String COLOR_GRAY = "gray";
+ /** lightgray string */
+ public static final String COLOR_LIGHTGRAY = "lightgray";
+ // Gotta at least put in the proper spelling :-P
+ /** darkgrey string */
+ public static final String COLOR_DARKGREY = "darkgrey";
+ /** grey string */
+ public static final String COLOR_GREY = "grey";
+ /** lightgrey string */
+ public static final String COLOR_LIGHTGREY = "lightgrey";
+ /** green string */
+ public static final String COLOR_GREEN = "green";
+ /** magenta string */
+ public static final String COLOR_MAGENTA = "magenta";
+ /** orange string */
+ public static final String COLOR_ORANGE = "orange";
+ /** pink string */
+ public static final String COLOR_PINK = "pink";
+ /** reg string */
+ public static final String COLOR_RED = "red";
+ /** white string */
+ public static final String COLOR_WHITE = "white";
+ /** yellow string */
+ public static final String COLOR_YELLOW = "yellow";
+
+ /**
+ * Convert a color name to a color value.
+ * @param colorName a string repr of the color.
+ * @return the color value.
+ * @todo refactor to use an EnumeratedAttribute (maybe?)
+ */
+ public static Color getColorByName(String colorName) {
+ if (colorName.equalsIgnoreCase(COLOR_BLACK)) {
+ return Color.black;
+ } else if (colorName.equalsIgnoreCase(COLOR_BLUE)) {
+ return Color.blue;
+ } else if (colorName.equalsIgnoreCase(COLOR_CYAN)) {
+ return Color.cyan;
+ } else if (colorName.equalsIgnoreCase(COLOR_DARKGRAY) || colorName.equalsIgnoreCase(COLOR_DARKGREY)) {
+ return Color.darkGray;
+ } else if (colorName.equalsIgnoreCase(COLOR_GRAY) || colorName.equalsIgnoreCase(COLOR_GREY)) {
+ return Color.gray;
+ } else if (colorName.equalsIgnoreCase(COLOR_LIGHTGRAY) || colorName.equalsIgnoreCase(COLOR_LIGHTGREY)) {
+ return Color.lightGray;
+ } else if (colorName.equalsIgnoreCase(COLOR_GREEN)) {
+ return Color.green;
+ } else if (colorName.equalsIgnoreCase(COLOR_MAGENTA)) {
+ return Color.magenta;
+ } else if (colorName.equalsIgnoreCase(COLOR_ORANGE)) {
+ return Color.orange;
+ } else if (colorName.equalsIgnoreCase(COLOR_PINK)) {
+ return Color.pink;
+ } else if (colorName.equalsIgnoreCase(COLOR_RED)) {
+ return Color.red;
+ } else if (colorName.equalsIgnoreCase(COLOR_WHITE)) {
+ return Color.white;
+ } else if (colorName.equalsIgnoreCase(COLOR_YELLOW)) {
+ return Color.yellow;
+ }
+ return Color.black;
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/optional/image/Draw.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/optional/image/Draw.java
new file mode 100644
index 00000000..2f097d5d
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/optional/image/Draw.java
@@ -0,0 +1,102 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.optional.image;
+
+import java.awt.Graphics2D;
+import java.awt.image.BufferedImage;
+
+import javax.media.jai.PlanarImage;
+
+/**
+ *
+ * @see org.apache.tools.ant.taskdefs.optional.image.Image
+ */
+public class Draw extends TransformOperation {
+ // CheckStyle:VisibilityModifier OFF - bc
+ protected int xloc = 0;
+ protected int yloc = 0;
+ // CheckStyle:VisibilityModifier ON
+
+ /**
+ * Set the X location.
+ * @param x the value to use.
+ */
+ public void setXloc(int x) {
+ xloc = x;
+ }
+
+ /**
+ * Set the Y location.
+ * @param y the value to use.
+ */
+ public void setYloc(int y) {
+ yloc = y;
+ }
+
+ /** {@inheritDoc}. */
+ public void addRectangle(Rectangle rect) {
+ instructions.add(rect);
+ }
+
+ /** {@inheritDoc}. */
+ public void addText(Text text) {
+ instructions.add(text);
+ }
+
+ /**
+ * Add an ellipse.
+ * @param elip the ellipse to add.
+ */
+ public void addEllipse(Ellipse elip) {
+ instructions.add(elip);
+ }
+
+ /**
+ * Add an arc.
+ * @param arc the arc to add.
+ */
+ public void addArc(Arc arc) {
+ instructions.add(arc);
+ }
+
+ /** {@inheritDoc}. */
+ public PlanarImage executeTransformOperation(PlanarImage image) {
+ BufferedImage bi = image.getAsBufferedImage();
+ Graphics2D graphics = (Graphics2D) bi.getGraphics();
+
+ final int size = instructions.size();
+ for (int i = 0; i < size; i++) {
+ ImageOperation instr = ((ImageOperation) instructions.elementAt(i));
+ if (instr instanceof DrawOperation) {
+ PlanarImage op = ((DrawOperation) instr).executeDrawOperation();
+ log("\tDrawing to x=" + xloc + " y=" + yloc);
+ graphics.drawImage(op.getAsBufferedImage(), null, xloc, yloc);
+ } else if (instr instanceof TransformOperation) {
+ PlanarImage op
+ = ((TransformOperation) instr).executeTransformOperation(null);
+ BufferedImage child = op.getAsBufferedImage();
+ log("\tDrawing to x=" + xloc + " y=" + yloc);
+ graphics.drawImage(child, null, xloc, yloc);
+ PlanarImage.wrapRenderedImage(bi);
+ }
+ }
+ image = PlanarImage.wrapRenderedImage(bi);
+
+ return image;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/optional/image/DrawOperation.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/optional/image/DrawOperation.java
new file mode 100644
index 00000000..4f6410ca
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/optional/image/DrawOperation.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.optional.image;
+
+import javax.media.jai.PlanarImage;
+
+
+/**
+ * Interface which represents an Operation which is "drawable", such
+ * as a Rectangle, Circle or Text. The Operation is responsible for
+ * creating its own image buffer and drawing itself into it, then
+ * wrapping and returning it as a PlanarImage. This allows multible
+ * "drawable" objects to be nested.
+ *
+ * @see org.apache.tools.ant.taskdefs.optional.image.Image
+ */
+public interface DrawOperation {
+ /**
+ * Abstract method which is intended to create an image buffer
+ * and return it so it can be drawn into another object. Use
+ * an Alpha channel for a "transparent" background.
+ * @return a planar image
+ */
+ PlanarImage executeDrawOperation();
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/optional/image/Ellipse.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/optional/image/Ellipse.java
new file mode 100644
index 00000000..9924d906
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/optional/image/Ellipse.java
@@ -0,0 +1,87 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.optional.image;
+
+import java.awt.BasicStroke;
+import java.awt.Graphics2D;
+import java.awt.geom.Ellipse2D;
+import java.awt.image.BufferedImage;
+
+import javax.media.jai.PlanarImage;
+
+/**
+ * Draw an ellipse.
+ * @see org.apache.tools.ant.taskdefs.optional.image.Image
+ */
+public class Ellipse extends BasicShape implements DrawOperation {
+ // CheckStyle:VisibilityModifier OFF - bc
+ protected int width = 0;
+ protected int height = 0;
+ // CheckStyle:VisibilityModifier ON
+
+ /**
+ * Set the width.
+ * @param width the width of the elipse.
+ */
+ public void setWidth(int width) {
+ this.width = width;
+ }
+
+ /**
+ * Set the height.
+ * @param height the height of the ellipse.
+ */
+ public void setHeight(int height) {
+ this.height = height;
+ }
+
+ /** {@inheritDoc}. */
+ public PlanarImage executeDrawOperation() {
+ BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_4BYTE_ABGR_PRE);
+
+ Graphics2D graphics = (Graphics2D) bi.getGraphics();
+
+ if (!stroke.equals("transparent")) {
+ BasicStroke bStroke = new BasicStroke(stroke_width);
+ graphics.setColor(ColorMapper.getColorByName(stroke));
+ graphics.setStroke(bStroke);
+ graphics.draw(new Ellipse2D.Double(0, 0, width, height));
+ }
+
+ if (!fill.equals("transparent")) {
+ graphics.setColor(ColorMapper.getColorByName(fill));
+ graphics.fill(new Ellipse2D.Double(0, 0, width, height));
+ }
+
+
+ final int size = instructions.size();
+ for (int i = 0; i < size; i++) {
+ ImageOperation instr = ((ImageOperation) instructions.elementAt(i));
+ if (instr instanceof DrawOperation) {
+ PlanarImage img = ((DrawOperation) instr).executeDrawOperation();
+ graphics.drawImage(img.getAsBufferedImage(), null, 0, 0);
+ } else if (instr instanceof TransformOperation) {
+ graphics = (Graphics2D) bi.getGraphics();
+ PlanarImage image = ((TransformOperation) instr)
+ .executeTransformOperation(PlanarImage.wrapRenderedImage(bi));
+ bi = image.getAsBufferedImage();
+ }
+ }
+ return PlanarImage.wrapRenderedImage(bi);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/optional/image/ImageOperation.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/optional/image/ImageOperation.java
new file mode 100644
index 00000000..d72fe049
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/optional/image/ImageOperation.java
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.optional.image;
+
+import java.util.Vector;
+
+import org.apache.tools.ant.types.DataType;
+
+/**
+ *
+ * @see org.apache.tools.ant.taskdefs.optional.image.Image
+ */
+public abstract class ImageOperation extends DataType {
+ // CheckStyle:VisibilityModifier OFF - bc
+ protected Vector<ImageOperation> instructions = new Vector<ImageOperation>();
+ // CheckStyle:VisibilityModifier ON
+
+ /**
+ * Add a rotate to the operation.
+ * @param instr the rotate to add.
+ */
+ public void addRotate(Rotate instr) {
+ instructions.add(instr);
+ }
+
+ /**
+ * Add a draw to the operation.
+ * @param instr the draw to add.
+ */
+ public void addDraw(Draw instr) {
+ instructions.add(instr);
+ }
+
+ /**
+ * Add a rectangle to the operation.
+ * @param instr the rectangle to add.
+ */
+ public void addRectangle(Rectangle instr) {
+ instructions.add(instr);
+ }
+
+ /**
+ * Add text to the operation.
+ * @param instr the text to add.
+ */
+ public void addText(Text instr) {
+ instructions.add(instr);
+ }
+
+ /**
+ * Add a scale to the operation.
+ * @param instr the scale to add.
+ */
+ public void addScale(Scale instr) {
+ instructions.add(instr);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/optional/image/Rectangle.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/optional/image/Rectangle.java
new file mode 100644
index 00000000..e2d5bb1b
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/optional/image/Rectangle.java
@@ -0,0 +1,119 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.optional.image;
+
+import java.awt.BasicStroke;
+import java.awt.Graphics2D;
+import java.awt.image.BufferedImage;
+
+import javax.media.jai.PlanarImage;
+
+/**
+ *
+ * @see org.apache.tools.ant.taskdefs.optional.image.Image
+ */
+public class Rectangle extends BasicShape implements DrawOperation {
+ // CheckStyle:VisibilityModifier OFF - bc
+ protected int width = 0;
+ protected int height = 0;
+ protected int arcwidth = 0;
+ protected int archeight = 0;
+ // CheckStyle:VisibilityModifier ON
+
+ /**
+ * Set the width.
+ * @param w the value to use.
+ */
+ public void setWidth(int w) {
+ width = w;
+ }
+
+ /**
+ * Set the height.
+ * @param h the value to use.
+ */
+ public void setHeight(int h) {
+ height = h;
+ }
+
+ /**
+ * Set the arc width.
+ * @param w the value to use.
+ */
+ public void setArcwidth(int w) {
+ arcwidth = w;
+ }
+
+ /**
+ * Set the arc height.
+ * @param h the value to use.
+ */
+ public void setArcheight(int h) {
+ archeight = h;
+ }
+
+ /** {@inheritDoc}. */
+ public PlanarImage executeDrawOperation() {
+ log("\tCreating Rectangle w=" + width + " h=" + height + " arcw="
+ + arcwidth + " arch=" + archeight);
+ BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_4BYTE_ABGR_PRE);
+
+ Graphics2D graphics = (Graphics2D) bi.getGraphics();
+
+ if (!stroke.equals("transparent")) {
+ BasicStroke bStroke = new BasicStroke(stroke_width);
+ graphics.setColor(ColorMapper.getColorByName(stroke));
+ graphics.setStroke(bStroke);
+
+ if ((arcwidth != 0) || (archeight != 0)) {
+ graphics.drawRoundRect(0, 0, width, height, arcwidth, archeight);
+ } else {
+ graphics.drawRect(0, 0, width, height);
+ }
+ }
+
+ if (!fill.equals("transparent")) {
+ graphics.setColor(ColorMapper.getColorByName(fill));
+ if ((arcwidth != 0) || (archeight != 0)) {
+ graphics.fillRoundRect(stroke_width, stroke_width,
+ width - (stroke_width * 2), height - (stroke_width * 2),
+ arcwidth, archeight);
+ } else {
+ graphics.fillRect(stroke_width, stroke_width,
+ width - (stroke_width * 2), height - (stroke_width * 2));
+ }
+ }
+
+
+ final int size = instructions.size();
+ for (int i = 0; i < size; i++) {
+ ImageOperation instr = ((ImageOperation) instructions.elementAt(i));
+ if (instr instanceof DrawOperation) {
+ PlanarImage img = ((DrawOperation) instr).executeDrawOperation();
+ graphics.drawImage(img.getAsBufferedImage(), null, 0, 0);
+ } else if (instr instanceof TransformOperation) {
+ graphics = (Graphics2D) bi.getGraphics();
+ PlanarImage image
+ = ((TransformOperation) instr)
+ .executeTransformOperation(PlanarImage.wrapRenderedImage(bi));
+ bi = image.getAsBufferedImage();
+ }
+ }
+ return PlanarImage.wrapRenderedImage(bi);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/optional/image/Rotate.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/optional/image/Rotate.java
new file mode 100644
index 00000000..3013bde4
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/optional/image/Rotate.java
@@ -0,0 +1,118 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.optional.image;
+
+import java.awt.image.BufferedImage;
+import java.awt.image.renderable.ParameterBlock;
+
+import javax.media.jai.InterpolationNearest;
+import javax.media.jai.JAI;
+import javax.media.jai.PlanarImage;
+
+/**
+ * ImageOperation to rotate an image by a certain degree
+ *
+ * @see org.apache.tools.ant.taskdefs.optional.image.Image
+ */
+public class Rotate extends TransformOperation implements DrawOperation {
+ private static final float HALF_CIRCLE = 180.0F;
+
+ // CheckStyle:VisibilityModifier OFF - bc
+ protected float angle = 0.0F;
+ // CheckStyle:VisibilityModifier ON
+
+ /**
+ * Sets the angle of rotation in degrees.
+ * @param ang The angle at which to rotate the image
+ */
+ public void setAngle(String ang) {
+ angle = Float.parseFloat(ang);
+ }
+
+
+ /**
+ * Rotate an image.
+ * @param image the image to rotate.
+ * @return the rotated image.
+ */
+ public PlanarImage performRotate(PlanarImage image) {
+ float tAngle = (float) (angle * (Math.PI / HALF_CIRCLE));
+ ParameterBlock pb = new ParameterBlock();
+ pb.addSource(image);
+ pb.add(0.0F);
+ pb.add(0.0F);
+ pb.add(tAngle);
+ pb.add(new InterpolationNearest());
+ return JAI.create("Rotate", pb, null);
+ }
+
+
+ /**
+ * Performs the image rotation when being handled as a TransformOperation.
+ * @param image The image to perform the transformation on.
+ * @return the transformed image.
+ */
+ public PlanarImage executeTransformOperation(PlanarImage image) {
+ BufferedImage bi = null;
+ final int size = instructions.size();
+ for (int i = 0; i < size; i++) {
+ ImageOperation instr = ((ImageOperation) instructions.elementAt(i));
+ if (instr instanceof DrawOperation) {
+ // If this TransformOperation has DrawOperation children
+ // then Rotate the first child and return.
+ System.out.println("Execing Draws");
+ PlanarImage op = ((DrawOperation) instr).executeDrawOperation();
+ image = performRotate(op);
+ return image;
+ } else if (instr instanceof TransformOperation) {
+ bi = image.getAsBufferedImage();
+ System.out.println("Execing Transforms");
+ image = ((TransformOperation) instr)
+ .executeTransformOperation(PlanarImage.wrapRenderedImage(bi));
+ bi = image.getAsBufferedImage();
+ }
+ }
+ System.out.println("Execing as TransformOperation");
+ image = performRotate(image);
+ System.out.println(image);
+ return image;
+ }
+
+ /**
+ * Performs the image rotation when being handled as a DrawOperation.
+ * It absolutely requires that there be a DrawOperation nested beneath it,
+ * but only the FIRST DrawOperation will be handled since it can only return
+ * ONE image.
+ * @return the image.
+ */
+ public PlanarImage executeDrawOperation() {
+ final int size = instructions.size();
+ for (int i = 0; i < size; i++) {
+ ImageOperation instr = ((ImageOperation) instructions.elementAt(i));
+ if (instr instanceof DrawOperation) {
+ // If this TransformOperation has DrawOperation children
+ // then Rotate the first child and return.
+ PlanarImage op = ((DrawOperation) instr).executeDrawOperation();
+ op = performRotate(op);
+ return op;
+ }
+ }
+ return null;
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/optional/image/Scale.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/optional/image/Scale.java
new file mode 100644
index 00000000..532694d6
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/optional/image/Scale.java
@@ -0,0 +1,181 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.optional.image;
+
+import java.awt.image.BufferedImage;
+import java.awt.image.renderable.ParameterBlock;
+
+import javax.media.jai.JAI;
+import javax.media.jai.PlanarImage;
+
+import org.apache.tools.ant.types.EnumeratedAttribute;
+
+/**
+ *
+ * @see org.apache.tools.ant.taskdefs.optional.image.Image
+ */
+public class Scale extends TransformOperation implements DrawOperation {
+ private static final int HUNDRED = 100;
+
+ private String widthStr = "100%";
+ private String heightStr = "100%";
+ private boolean xPercent = true;
+ private boolean yPercent = true;
+ private String proportions = "ignore";
+
+ /** Enumerated class for proportions attribute. */
+ public static class ProportionsAttribute extends EnumeratedAttribute {
+ /** {@inheritDoc}. */
+ public String[] getValues() {
+ return new String[] {"ignore", "width", "height", "cover", "fit"};
+ }
+ }
+
+ /**
+ * Sets the behaviour regarding the image proportions.
+ * @param pa the enumerated value.
+ */
+ public void setProportions(ProportionsAttribute pa) {
+ proportions = pa.getValue();
+ }
+
+ /**
+ * Sets the width of the image, either as an integer or a %.
+ * Defaults to 100%.
+ * @param width the value to use.
+ */
+ public void setWidth(String width) {
+ widthStr = width;
+ }
+
+ /**
+ * Sets the height of the image, either as an integer or a %. Defaults to 100%.
+ * @param height the value to use.
+ */
+ public void setHeight(String height) {
+ heightStr = height;
+ }
+
+ /**
+ * Get the width.
+ * @return the value converted from the width string.
+ */
+ public float getWidth() {
+ float width = 0.0F;
+ int percIndex = widthStr.indexOf('%');
+ if (percIndex > 0) {
+ width = Float.parseFloat(widthStr.substring(0, percIndex));
+ xPercent = true;
+ return width / HUNDRED;
+ } else {
+ xPercent = false;
+ return Float.parseFloat(widthStr);
+ }
+ }
+
+ /**
+ * Get the height.
+ * @return the value converted from the height string.
+ */
+ public float getHeight() {
+ int percIndex = heightStr.indexOf('%');
+ if (percIndex > 0) {
+ float height = Float.parseFloat(heightStr.substring(0, percIndex));
+ yPercent = true;
+ return height / HUNDRED;
+ } else {
+ yPercent = false;
+ return Float.parseFloat(heightStr);
+ }
+ }
+
+ /**
+ * Scale an image.
+ * @param image the image to scale.
+ * @return the scaled image.
+ */
+ public PlanarImage performScale(PlanarImage image) {
+ ParameterBlock pb = new ParameterBlock();
+ pb.addSource(image);
+ float xFl = getWidth();
+ float yFl = getHeight();
+
+ if (!xPercent) {
+ xFl = (xFl / image.getWidth());
+ }
+ if (!yPercent) {
+ yFl = (yFl / image.getHeight());
+ }
+
+ if ("width".equals(proportions)) {
+ yFl = xFl;
+ } else if ("height".equals(proportions)) {
+ xFl = yFl;
+ } else if ("fit".equals(proportions)) {
+ yFl = Math.min(xFl, yFl);
+ xFl = yFl;
+ } else if ("cover".equals(proportions)) {
+ yFl = Math.max(xFl, yFl);
+ xFl = yFl;
+ }
+
+ pb.add(new Float(xFl));
+ pb.add(new Float(yFl));
+
+ log("\tScaling to " + (xFl * HUNDRED) + "% x "
+ + (yFl * HUNDRED) + "%");
+
+ return JAI.create("scale", pb);
+ }
+
+
+ /** {@inheritDoc}. */
+ public PlanarImage executeTransformOperation(PlanarImage image) {
+ BufferedImage bi = null;
+ final int size = instructions.size();
+ for (int i = 0; i < size; i++) {
+ ImageOperation instr = ((ImageOperation) instructions.elementAt(i));
+ if (instr instanceof DrawOperation) {
+ return performScale(image);
+ } else if (instr instanceof TransformOperation) {
+ bi = image.getAsBufferedImage();
+ image = ((TransformOperation) instr)
+ .executeTransformOperation(PlanarImage.wrapRenderedImage(bi));
+ bi = image.getAsBufferedImage();
+ }
+ }
+ return performScale(image);
+ }
+
+
+ /** {@inheritDoc}. */
+ public PlanarImage executeDrawOperation() {
+ final int size = instructions.size();
+ for (int i = 0; i < size; i++) {
+ ImageOperation instr = ((ImageOperation) instructions.elementAt(i));
+ if (instr instanceof DrawOperation) {
+ PlanarImage image = null;
+ // If this TransformOperation has DrawOperation children
+ // then Rotate the first child and return.
+ performScale(image);
+ return image;
+ }
+ }
+ return null;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/optional/image/Text.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/optional/image/Text.java
new file mode 100644
index 00000000..869fbac1
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/optional/image/Text.java
@@ -0,0 +1,128 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.optional.image;
+
+import java.awt.Color;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Graphics2D;
+import java.awt.RenderingHints;
+import java.awt.image.BufferedImage;
+
+import javax.media.jai.PlanarImage;
+
+/**
+ *
+ * @see org.apache.tools.ant.taskdefs.optional.image.Image
+ */
+public class Text extends ImageOperation implements DrawOperation {
+ private static final int DEFAULT_POINT = 10;
+
+ private String strText = "";
+ private String font = "Arial";
+ private int point = DEFAULT_POINT;
+ private boolean bold = false;
+ private boolean italic = false;
+ private String color = "black";
+
+ /**
+ * Set the string to be used as text.
+ * @param str the string to be used.
+ */
+ public void setString(String str) {
+ strText = str;
+ }
+
+ /**
+ * Set the font to be used to draw the text.
+ * @param f the font to be used.
+ */
+ public void setFont(String f) {
+ font = f;
+ }
+
+ /**
+ * Set the number of points to be used.
+ * @param p an integer value as a string.
+ */
+ public void setPoint(String p) {
+ point = Integer.parseInt(p);
+ }
+
+ /**
+ * Set the color of the text.
+ * @param c the color name.
+ */
+ public void setColor(String c) {
+ color = c;
+ }
+
+ /**
+ * @todo is this used?
+ * @param state not used at the moment.
+ */
+ public void setBold(boolean state) {
+ bold = state;
+ }
+
+ /**
+ * @todo is this used?
+ * @param state not used at the moment.
+ */
+ public void setItalic(boolean state) {
+ italic = state;
+ }
+
+ /**
+ * Draw the text.
+ * @return the resultant image.
+ */
+ public PlanarImage executeDrawOperation() {
+ log("\tCreating Text \"" + strText + "\"");
+
+ Color couloir = ColorMapper.getColorByName(color);
+ int width = 1;
+ int height = 1;
+
+ BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_4BYTE_ABGR_PRE);
+ Graphics2D graphics = (Graphics2D) bi.getGraphics();
+ graphics.setRenderingHint(
+ RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+ graphics.setRenderingHint(
+ RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
+ Font f = new Font(font, Font.PLAIN, point);
+ FontMetrics fmetrics = graphics.getFontMetrics(f);
+ height = fmetrics.getMaxAscent() + fmetrics.getMaxDescent();
+ width = fmetrics.stringWidth(strText);
+
+
+ bi = new BufferedImage(width, height, BufferedImage.TYPE_4BYTE_ABGR_PRE);
+ graphics = (Graphics2D) bi.getGraphics();
+
+ graphics.setRenderingHint(
+ RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+ graphics.setRenderingHint(
+ RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
+
+ graphics.setFont(f);
+ graphics.setColor(couloir);
+ graphics.drawString(strText, 0, height - fmetrics.getMaxDescent());
+ PlanarImage image = PlanarImage.wrapRenderedImage(bi);
+ return image;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/optional/image/TransformOperation.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/optional/image/TransformOperation.java
new file mode 100644
index 00000000..896e5d10
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/optional/image/TransformOperation.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.optional.image;
+
+import javax.media.jai.PlanarImage;
+
+/**
+ *
+ * @see org.apache.tools.ant.taskdefs.optional.image.Image
+ */
+public abstract class TransformOperation extends ImageOperation {
+ /**
+ * Performs the transformations.
+ * @param img The image to perform the transformation on.
+ * @return the transformed image.
+ */
+ public abstract PlanarImage executeTransformOperation(PlanarImage img);
+
+ /** {@inheritDoc}. */
+ public void addRectangle(Rectangle instr) {
+ instructions.add(instr);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resolver/ApacheCatalog.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resolver/ApacheCatalog.java
new file mode 100644
index 00000000..cbf3f3fe
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resolver/ApacheCatalog.java
@@ -0,0 +1,121 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types.resolver;
+
+import org.apache.xml.resolver.Catalog;
+import org.apache.xml.resolver.CatalogEntry;
+import org.apache.xml.resolver.helpers.PublicId;
+
+
+/**
+ * This class extends the Catalog class provided by Norman Walsh's
+ * resolver library in xml-commons in order to add classpath entity
+ * and URI resolution. Since XMLCatalog already does classpath
+ * resolution, we simply add all CatalogEntry instances back to the
+ * controlling XMLCatalog instance. This is done via a callback
+ * mechanism. ApacheCatalog is <em>only</em> used for external
+ * catalog files. Inline entries (currently <code>&lt;dtd&gt;</code>
+ * and <code>&lt;entity&gt;</code>) are not added to ApacheCatalog.
+ * See XMLCatalog.java for the details of the entity and URI
+ * resolution algorithms.
+ *
+ * @see org.apache.tools.ant.types.XMLCatalog.CatalogResolver
+ * @since Ant 1.6
+ */
+public class ApacheCatalog extends Catalog {
+
+ /** The resolver object to callback. */
+ private ApacheCatalogResolver resolver = null;
+
+ /**
+ * <p>Create a new ApacheCatalog instance.</p>
+ *
+ * <p>This method overrides the superclass method of the same name
+ * in order to set the resolver object for callbacks. The reason
+ * we have to do this is that internally Catalog creates a new
+ * instance of itself for each external catalog file processed.
+ * That is, if two external catalog files are processed, there
+ * will be a total of two ApacheCatalog instances, and so on.</p>
+ * @return the catalog.
+ */
+ protected Catalog newCatalog() {
+ final ApacheCatalog cat = (ApacheCatalog) super.newCatalog();
+ cat.setResolver(resolver);
+ return cat;
+ }
+
+ /**
+ * Set the resolver object to callback.
+ * @param resolver the apache catalog resolver.
+ */
+ public void setResolver(final ApacheCatalogResolver resolver) {
+ this.resolver = resolver;
+ }
+
+ /**
+ * <p>This method overrides the superclass method of the same name
+ * in order to add catalog entries back to the controlling
+ * XMLCatalog instance. In this way, we can add classpath lookup
+ * for these entries.</p>
+ *
+ * <p>When we add an external catalog file, the entries inside it
+ * get parsed by this method. Therefore, we override it to add
+ * each of them back to the controlling XMLCatalog instance. This
+ * is done by performing a callback to the ApacheCatalogResolver,
+ * which in turn calls the XMLCatalog.</p>
+ *
+ * <p>XMLCatalog currently only understands <code>PUBLIC</code>
+ * and <code>URI</code> entry types, so we ignore the other types.</p>
+ *
+ * @param entry The CatalogEntry to process.
+ */
+ public void addEntry(final CatalogEntry entry) {
+
+ final int type = entry.getEntryType();
+
+ if (type == PUBLIC) {
+
+ final String publicid = PublicId.normalize(entry.getEntryArg(0));
+ final String systemid = normalizeURI(entry.getEntryArg(1));
+
+ if (resolver == null) {
+ catalogManager.debug
+ .message(1, "Internal Error: null ApacheCatalogResolver");
+ } else {
+ resolver.addPublicEntry(publicid, systemid, base);
+ }
+
+ } else if (type == URI) {
+
+ final String uri = normalizeURI(entry.getEntryArg(0));
+ final String altURI = normalizeURI(entry.getEntryArg(1));
+
+ if (resolver == null) {
+ catalogManager.debug
+ .message(1, "Internal Error: null ApacheCatalogResolver");
+ } else {
+ resolver.addURIEntry(uri, altURI, base);
+ }
+
+ }
+
+ super.addEntry(entry);
+ }
+
+} //- ApacheCatalog
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resolver/ApacheCatalogResolver.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resolver/ApacheCatalogResolver.java
new file mode 100644
index 00000000..2312d3dc
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resolver/ApacheCatalogResolver.java
@@ -0,0 +1,174 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types.resolver;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.types.ResourceLocation;
+import org.apache.tools.ant.types.XMLCatalog;
+import org.apache.xml.resolver.Catalog;
+import org.apache.xml.resolver.CatalogManager;
+import org.apache.xml.resolver.tools.CatalogResolver;
+
+
+/**
+ * <p>This class extends the CatalogResolver class provided by Norman
+ * Walsh's resolver library in xml-commons. It provides the bridge
+ * between the Ant XMLCatalog datatype and the xml-commons Catalog
+ * class. XMLCatalog calls methods in this class using Reflection in
+ * order to avoid requiring the xml-commons resolver library in the
+ * path.</p>
+ *
+ * <p>The {@link org.apache.tools.ant.types.resolver.ApacheCatalog
+ * ApacheCatalog} class is used to parse external catalog files, which
+ * can be in either <a
+ * href="http://oasis-open.org/committees/entity/background/9401.html">
+ * plain text format</a> or <a
+ * href="http://www.oasis-open.org/committees/entity/spec-2001-08-06.html">
+ * XML format</a>.</p>
+ *
+ * <p>For each entry found in an external catalog file, if any, an
+ * instance of {@link org.apache.tools.ant.types.ResourceLocation
+ * ResourceLocation} is created and added to the controlling
+ * XMLCatalog datatype. In this way, these entries will be included
+ * in XMLCatalog's lookup algorithm. See XMLCatalog.java for more
+ * details.</p>
+ *
+ * @see org.apache.tools.ant.types.XMLCatalog.CatalogResolver
+ * @see org.apache.xml.resolver.CatalogManager
+ * @since Ant 1.6
+ */
+
+public class ApacheCatalogResolver extends CatalogResolver {
+
+ /** The XMLCatalog object to callback. */
+ private XMLCatalog xmlCatalog = null;
+
+ static {
+ //
+ // If you don't do this, you get all sorts of annoying
+ // warnings about a missing properties file. However, it
+ // seems to work just fine with default values. Ultimately,
+ // we should probably include a "CatalogManager.properties"
+ // file in the ant jarfile with some default property
+ // settings. See CatalogManager.java for more details.
+ //
+ CatalogManager.getStaticManager().setIgnoreMissingProperties(true);
+
+ //
+ // Make sure CatalogResolver instantiates ApacheCatalog,
+ // rather than a plain Catalog
+ //
+ System.getProperties().put("xml.catalog.className",
+ ApacheCatalog.class.getName());
+
+ CatalogManager.getStaticManager().setUseStaticCatalog(false);
+
+ // debug
+ // CatalogManager.getStaticManager().setVerbosity(4);
+ }
+
+ /**
+ * Set the XMLCatalog object to callback.
+ * @param xmlCatalog the XMLCatalog to use.
+ */
+ public void setXMLCatalog(final XMLCatalog xmlCatalog) {
+ this.xmlCatalog = xmlCatalog;
+ }
+
+ /**
+ * XMLCatalog calls this to add an external catalog file for each
+ * file within a <code>&lt;catalogfiles&gt;</code> fileset.
+ * @param file the external catalog file.
+ */
+ public void parseCatalog(final String file) {
+
+ final Catalog catalog = getCatalog();
+ if (!(catalog instanceof ApacheCatalog)) {
+ throw new BuildException("Wrong catalog type found: " + catalog.getClass().getName());
+ }
+ final ApacheCatalog apacheCatalog = (ApacheCatalog) catalog;
+
+ // Pass in reference to ourselves so we can be called back.
+ apacheCatalog.setResolver(this);
+
+ try {
+ apacheCatalog.parseCatalog(file);
+ } catch (final MalformedURLException ex) {
+ throw new BuildException(ex);
+ } catch (final IOException ex) {
+ throw new BuildException(ex);
+ }
+ }
+
+ /**
+ * <p>Add a PUBLIC catalog entry to the controlling XMLCatalog instance.
+ * ApacheCatalog calls this for each PUBLIC entry found in an external
+ * catalog file.</p>
+ *
+ * @param publicid The public ID of the resource
+ * @param systemid The system ID (aka location) of the resource
+ * @param base The base URL of the resource. If the systemid
+ * specifies a relative URL/pathname, it is resolved using the
+ * base. The default base for an external catalog file is the
+ * directory in which the catalog is located.
+ *
+ */
+ public void addPublicEntry(final String publicid,
+ final String systemid,
+ final URL base) {
+
+ final ResourceLocation dtd = new ResourceLocation();
+ dtd.setBase(base);
+ dtd.setPublicId(publicid);
+ dtd.setLocation(systemid);
+
+ xmlCatalog.addDTD(dtd);
+ }
+
+ /**
+ * <p>Add a URI catalog entry to the controlling XMLCatalog instance.
+ * ApacheCatalog calls this for each URI entry found in an external
+ * catalog file.</p>
+ *
+ * @param uri The URI of the resource
+ * @param altURI The URI to which the resource should be mapped
+ * (aka the location)
+ * @param base The base URL of the resource. If the altURI
+ * specifies a relative URL/pathname, it is resolved using the
+ * base. The default base for an external catalog file is the
+ * directory in which the catalog is located.
+ *
+ */
+ public void addURIEntry(final String uri,
+ final String altURI,
+ final URL base) {
+
+ final ResourceLocation entity = new ResourceLocation();
+ entity.setBase(base);
+ entity.setPublicId(uri);
+ entity.setLocation(altURI);
+
+ xmlCatalog.addEntity(entity);
+ }
+
+} //-- ApacheCatalogResolver
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resolver/package.html b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resolver/package.html
new file mode 100644
index 00000000..11b3c773
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resolver/package.html
@@ -0,0 +1,35 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<body>
+Ant integration with xml-commons resolver.
+
+<p>These classes enhance the <code>&lt;xmlcatalog&gt;</code> datatype
+to support external catalog files using the xml-commons resolver, in
+accordance with the
+<a href="http://oasis-open.org/committees/entity/spec-2001-08-06.html">
+OASIS "Open Catalog" standard</a>. They will be used if and only if
+the xml-commons resolver library is available on the classpath.</p>
+
+@see <A HREF="http://xml.apache.org/commons">Apache xml-commons Project</A>
+
+@see org.apache.tools.ant.types.XMLCatalog
+@see org.apache.tools.ant.types.resolver.ApacheCatalogResolver
+@see org.apache.tools.ant.types.resolver.ApacheCatalog
+
+@author <A HREF="mailto:cstrong@arielpartners.com">Craeg Strong</A>
+
+</body>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/AbstractClasspathResource.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/AbstractClasspathResource.java
new file mode 100644
index 00000000..417da9a7
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/AbstractClasspathResource.java
@@ -0,0 +1,265 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.resources;
+
+import java.io.FilterInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Stack;
+
+import org.apache.tools.ant.AntClassLoader;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.types.Reference;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.util.FileUtils;
+
+/**
+ *
+ * A Resource representation of anything that is accessed via a Java classloader.
+ * The core methods to set/resolve the classpath are provided.
+ * @since Ant 1.8.0
+ *
+ */
+
+public abstract class AbstractClasspathResource extends Resource {
+ private Path classpath;
+ private Reference loader;
+ private boolean parentFirst = true;
+
+ /**
+ * Set the classpath to use when looking up a resource.
+ * @param classpath to add to any existing classpath
+ */
+ public void setClasspath(Path classpath) {
+ checkAttributesAllowed();
+ if (this.classpath == null) {
+ this.classpath = classpath;
+ } else {
+ this.classpath.append(classpath);
+ }
+ setChecked(false);
+ }
+
+ /**
+ * Add a classpath to use when looking up a resource.
+ * @return The classpath to be configured
+ */
+ public Path createClasspath() {
+ checkChildrenAllowed();
+ if (classpath == null) {
+ classpath = new Path(getProject());
+ }
+ setChecked(false);
+ return classpath.createPath();
+ }
+
+ /**
+ * Set the classpath to use when looking up a resource,
+ * given as reference to a &lt;path&gt; defined elsewhere
+ * @param r The reference value
+ */
+ public void setClasspathRef(Reference r) {
+ checkAttributesAllowed();
+ createClasspath().setRefid(r);
+ }
+
+ /**
+ * get the classpath used by this <code>LoadProperties</code>.
+ * @return The classpath
+ */
+ public Path getClasspath() {
+ if (isReference()) {
+ return ((AbstractClasspathResource) getCheckedRef()).getClasspath();
+ }
+ dieOnCircularReference();
+ return classpath;
+ }
+
+ /**
+ * Get the loader.
+ * @return the loader.
+ */
+ public Reference getLoader() {
+ if (isReference()) {
+ return ((AbstractClasspathResource) getCheckedRef()).getLoader();
+ }
+ dieOnCircularReference();
+ return loader;
+ }
+
+ /**
+ * Use the reference to locate the loader. If the loader is not
+ * found, taskdef will use the specified classpath and register it
+ * with the specified name.
+ *
+ * This allow multiple taskdef/typedef to use the same class loader,
+ * so they can be used together. It eliminate the need to
+ * put them in the CLASSPATH.
+ *
+ * @param r the reference to locate the loader.
+ */
+ public void setLoaderRef(Reference r) {
+ checkAttributesAllowed();
+ loader = r;
+ }
+
+ /**
+ * Whether to consult the parent classloader first.
+ *
+ * <p>Only relevant if a classpath has been specified.</p>
+ *
+ * @since Ant 1.8.0
+ */
+ public void setParentFirst(boolean b) {
+ parentFirst = b;
+ }
+
+ /**
+ * Overrides the super version.
+ * @param r the Reference to set.
+ */
+ public void setRefid(Reference r) {
+ if (loader != null || classpath != null) {
+ throw tooManyAttributes();
+ }
+ super.setRefid(r);
+ }
+
+ /**
+ * Learn whether this resource exists. This implementation opens the input stream
+ * as the test.
+ * @return true if this resource exists.
+ */
+ public boolean isExists() {
+ if (isReference()) {
+ return ((Resource) getCheckedRef()).isExists();
+ }
+ dieOnCircularReference();
+ InputStream is = null;
+ try {
+ is = getInputStream();
+ return is != null;
+ } catch (IOException ex) {
+ return false;
+ } finally {
+ FileUtils.close(is);
+ }
+ }
+
+ /**
+ * Return an InputStream for reading the contents of this Resource.
+ * @return an InputStream object.
+ * @throws IOException if an error occurs.
+ */
+ public InputStream getInputStream() throws IOException {
+ if (isReference()) {
+ return ((Resource) getCheckedRef()).getInputStream();
+ }
+ dieOnCircularReference();
+
+ final ClassLoaderWithFlag classLoader = getClassLoader();
+ return !classLoader.needsCleanup()
+ ? openInputStream(classLoader.getLoader())
+ : new FilterInputStream(openInputStream(classLoader.getLoader())) {
+ public void close() throws IOException {
+ FileUtils.close(in);
+ classLoader.cleanup();
+ }
+ protected void finalize() throws Throwable {
+ try {
+ close();
+ } finally {
+ super.finalize();
+ }
+ }
+ };
+ }
+
+ /**
+ * combines the various ways that could specify a ClassLoader and
+ * potentially creates one that needs to be cleaned up when it is
+ * no longer needed so that classes can get garbage collected.
+ */
+ protected ClassLoaderWithFlag getClassLoader() {
+ ClassLoader cl = null;
+ boolean clNeedsCleanup = false;
+ if (loader != null) {
+ cl = (ClassLoader) loader.getReferencedObject();
+ }
+ if (cl == null) {
+ if (getClasspath() != null) {
+ Path p = getClasspath().concatSystemClasspath("ignore");
+ if (parentFirst) {
+ cl = getProject().createClassLoader(p);
+ } else {
+ cl = AntClassLoader.newAntClassLoader(getProject()
+ .getCoreLoader(),
+ getProject(),
+ p, false);
+ }
+ clNeedsCleanup = loader == null;
+ } else {
+ cl = JavaResource.class.getClassLoader();
+ }
+ if (loader != null && cl != null) {
+ getProject().addReference(loader.getRefId(), cl);
+ }
+ }
+ return new ClassLoaderWithFlag(cl, clNeedsCleanup);
+ }
+
+ /**
+ * open the input stream from a specific classloader
+ * @param cl the classloader to use. Will be null if the system classloader is used
+ * @return an open input stream for the resource
+ * @throws IOException if an error occurs.
+ */
+ protected abstract InputStream openInputStream(ClassLoader cl) throws IOException;
+
+ protected synchronized void dieOnCircularReference(Stack<Object> stk, Project p) {
+ if (isChecked()) {
+ return;
+ }
+ if (isReference()) {
+ super.dieOnCircularReference(stk, p);
+ } else {
+ if (classpath != null) {
+ pushAndInvokeCircularReferenceCheck(classpath, stk, p);
+ }
+ setChecked(true);
+ }
+ }
+
+ public static class ClassLoaderWithFlag {
+ private final ClassLoader loader;
+ private final boolean cleanup;
+
+ ClassLoaderWithFlag(ClassLoader l, boolean needsCleanup) {
+ loader = l;
+ cleanup = needsCleanup && l instanceof AntClassLoader;
+ }
+ public ClassLoader getLoader() { return loader; }
+ public boolean needsCleanup() { return cleanup; }
+ public void cleanup() {
+ if (cleanup) {
+ ((AntClassLoader) loader).cleanup();
+ }
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/AbstractResourceCollectionWrapper.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/AbstractResourceCollectionWrapper.java
new file mode 100644
index 00000000..5e4c3a3f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/AbstractResourceCollectionWrapper.java
@@ -0,0 +1,209 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.resources;
+
+import java.io.File;
+import java.util.Iterator;
+import java.util.Stack;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.DataType;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.ResourceCollection;
+
+/**
+ * Base class for a ResourceCollection that wraps a single nested
+ * ResourceCollection.
+ * @since Ant 1.8.2
+ */
+public abstract class AbstractResourceCollectionWrapper
+ extends DataType implements ResourceCollection, Cloneable {
+ private static final String ONE_NESTED_MESSAGE
+ = " expects exactly one nested resource collection.";
+
+ private ResourceCollection rc;
+ private boolean cache = true;
+
+ /**
+ * Set whether to cache collections.
+ * @param b boolean cache flag.
+ */
+ public synchronized void setCache(boolean b) {
+ cache = b;
+ }
+
+ /**
+ * Learn whether to cache collections. Default is <code>true</code>.
+ * @return boolean cache flag.
+ */
+ public synchronized boolean isCache() {
+ return cache;
+ }
+
+ /**
+ * Add a ResourceCollection to the container.
+ * @param c the ResourceCollection to add.
+ * @throws BuildException on error.
+ */
+ public synchronized void add(ResourceCollection c) throws BuildException {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ if (c == null) {
+ return;
+ }
+ if (rc != null) {
+ throw oneNested();
+ }
+ rc = c;
+ if (Project.getProject(rc) == null) {
+ Project p = getProject();
+ if (p != null) {
+ p.setProjectReference(rc);
+ }
+ }
+ setChecked(false);
+ }
+
+ /**
+ * Fulfill the ResourceCollection contract.
+ * @return an Iterator of Resources.
+ */
+ public final synchronized Iterator<Resource> iterator() {
+ if (isReference()) {
+ return ((AbstractResourceCollectionWrapper) getCheckedRef()).iterator();
+ }
+ dieOnCircularReference();
+ return new FailFast(this, createIterator());
+ }
+
+ /**
+ * Do create an iterator on the resource collection. The creation
+ * of the iterator is allowed to not be thread safe whereas the iterator
+ * itself should. The returned iterator will be wrapped into the FailFast
+ * one.
+ *
+ * @return the iterator on the resource collection
+ */
+ protected abstract Iterator<Resource> createIterator();
+
+ /**
+ * Fulfill the ResourceCollection contract.
+ * @return number of elements as int.
+ */
+ public synchronized int size() {
+ if (isReference()) {
+ return ((AbstractResourceCollectionWrapper) getCheckedRef()).size();
+ }
+ dieOnCircularReference();
+ return getSize();
+ }
+
+ /**
+ * Do compute the size of the resource collection. The implementation of
+ * this function is allowed to be not thread safe.
+ *
+ * @return size of resource collection.
+ */
+ protected abstract int getSize();
+
+ /**
+ * Fulfill the ResourceCollection contract.
+ * @return whether this is a filesystem-only resource collection.
+ */
+ public synchronized boolean isFilesystemOnly() {
+ if (isReference()) {
+ return ((BaseResourceCollectionContainer) getCheckedRef()).isFilesystemOnly();
+ }
+ dieOnCircularReference();
+
+ if (rc == null || rc.isFilesystemOnly()) {
+ return true;
+ }
+ /* now check each Resource in case the child only
+ lets through files from any children IT may have: */
+ for (Resource r : this) {
+ if (r.as(FileProvider.class) == null) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Overrides the version of DataType to recurse on all DataType
+ * child elements that may have been added.
+ * @param stk the stack of data types to use (recursively).
+ * @param p the project to use to dereference the references.
+ * @throws BuildException on error.
+ */
+ protected synchronized void dieOnCircularReference(Stack<Object> stk, Project p)
+ throws BuildException {
+ if (isChecked()) {
+ return;
+ }
+ if (isReference()) {
+ super.dieOnCircularReference(stk, p);
+ } else {
+ if (rc instanceof DataType) {
+ pushAndInvokeCircularReferenceCheck((DataType) rc, stk, p);
+ }
+ setChecked(true);
+ }
+ }
+
+ /**
+ * Get the nested ResourceCollection.
+ * @return a ResourceCollection.
+ * @throws BuildException if no nested ResourceCollection has been provided.
+ */
+ protected final synchronized ResourceCollection getResourceCollection() {
+ dieOnCircularReference();
+ if (rc == null) {
+ throw oneNested();
+ }
+ return rc;
+ }
+
+ /**
+ * Format this BaseResourceCollectionWrapper as a String.
+ * @return a descriptive <code>String</code>.
+ */
+ public synchronized String toString() {
+ if (isReference()) {
+ return getCheckedRef().toString();
+ }
+ if (getSize() == 0) {
+ return "";
+ }
+ StringBuilder sb = new StringBuilder();
+ for (Resource resource : this) {
+ if (sb.length() > 0) {
+ sb.append(File.pathSeparatorChar);
+ }
+ sb.append(resource);
+ }
+ return sb.toString();
+ }
+
+ private BuildException oneNested() {
+ return new BuildException(super.toString() + ONE_NESTED_MESSAGE);
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/AllButFirst.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/AllButFirst.java
new file mode 100644
index 00000000..ffa665f8
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/AllButFirst.java
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.resources;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.tools.ant.types.Resource;
+
+/**
+ * ResourceCollection that contains all resources of another
+ * collection except for the first <code>count</code> elements, a la
+ * the UNIX tail command with parameter <code>-n +count</code>.
+ * @since Ant 1.9.5
+ */
+public class AllButFirst extends SizeLimitCollection {
+
+ /**
+ * Take all elements except for the first <code>count</code> elements.
+ * @return a Collection of Resources.
+ */
+ protected Collection<Resource> getCollection() {
+ int ct = getValidCount();
+ Iterator<Resource> iter = getResourceCollection().iterator();
+ List<Resource> al = new ArrayList<Resource>();
+ for (int i = 0; i < ct && iter.hasNext(); i++) {
+ // discard
+ iter.next();
+ }
+ while (iter.hasNext()) {
+ al.add(iter.next());
+ }
+ return al;
+ }
+
+ @Override
+ public synchronized int size() {
+ int sz = getResourceCollection().size();
+ int ct = getValidCount();
+ return sz > ct ? sz - ct : 0;
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/AllButLast.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/AllButLast.java
new file mode 100644
index 00000000..a1e6a984
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/AllButLast.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.resources;
+
+import java.util.Collection;
+import java.util.List;
+
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.util.CollectionUtils;
+
+/**
+ * ResourceCollection that contains all resources of another
+ * collection except for the last <code>count</code> elements, a la
+ * the UNIX head command with parameter <code>-n -count</code>.
+ * @since Ant 1.9.5
+ */
+public class AllButLast extends SizeLimitCollection {
+
+ /**
+ * Take all elements except for the last <code>count</code> elements.
+ * @return a Collection of Resources.
+ */
+ protected Collection<Resource> getCollection() {
+ int ct = getValidCount();
+ List<Resource> result =
+ (List<Resource>) CollectionUtils.asCollection(getResourceCollection()
+ .iterator());
+ return result.subList(0, result.size() - ct);
+ }
+
+ @Override
+ public synchronized int size() {
+ int sz = getResourceCollection().size();
+ int ct = getValidCount();
+ return sz > ct ? sz - ct : 0;
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/Appendable.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/Appendable.java
new file mode 100644
index 00000000..14f4711a
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/Appendable.java
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.resources;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * Interface to be implemented by "appendable" resources.
+ * @since Ant 1.8
+ */
+public interface Appendable {
+
+ /**
+ * Get an appending OutputStream.
+ * @return OutputStream
+ * @throws IOException if anything goes wrong
+ */
+ OutputStream getAppendOutputStream() throws IOException;
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/ArchiveResource.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/ArchiveResource.java
new file mode 100644
index 00000000..308de03e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/ArchiveResource.java
@@ -0,0 +1,293 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.resources;
+
+import java.io.File;
+import java.util.Stack;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.Reference;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.ResourceCollection;
+
+/**
+ * A Resource representation of an entry inside an archive.
+ * @since Ant 1.7
+ */
+public abstract class ArchiveResource extends Resource {
+ private static final int NULL_ARCHIVE
+ = Resource.getMagicNumber("null archive".getBytes());
+
+ private Resource archive;
+ private boolean haveEntry = false;
+ private boolean modeSet = false;
+ private int mode = 0;
+
+ /**
+ * Default constructor.
+ */
+ protected ArchiveResource() {
+ }
+
+ /**
+ * Construct a ArchiveResource representing the specified
+ * entry in the specified archive.
+ * @param a the archive as File.
+ */
+ protected ArchiveResource(File a) {
+ this(a, false);
+ }
+
+ /**
+ * Construct a ArchiveResource representing the specified
+ * entry in the specified archive.
+ * @param a the archive as File.
+ * @param withEntry if the entry has been specified.
+ */
+ protected ArchiveResource(File a, boolean withEntry) {
+ setArchive(a);
+ haveEntry = withEntry;
+ }
+
+ /**
+ * Construct a ArchiveResource representing the specified
+ * entry in the specified archive.
+ * @param a the archive as Resource.
+ * @param withEntry if the entry has been specified.
+ */
+ protected ArchiveResource(Resource a, boolean withEntry) {
+ addConfigured(a);
+ haveEntry = withEntry;
+ }
+
+ /**
+ * Set the archive that holds this Resource.
+ * @param a the archive as a File.
+ */
+ public void setArchive(File a) {
+ checkAttributesAllowed();
+ archive = new FileResource(a);
+ }
+
+ /**
+ * Sets the file or dir mode for this resource.
+ * @param mode integer representation of Unix permission mask.
+ */
+ public void setMode(int mode) {
+ checkAttributesAllowed();
+ this.mode = mode;
+ modeSet = true;
+ }
+
+ /**
+ * Sets the archive that holds this as a single element Resource
+ * collection.
+ * @param a the archive as a single element Resource collection.
+ */
+ public void addConfigured(ResourceCollection a) {
+ checkChildrenAllowed();
+ if (archive != null) {
+ throw new BuildException("you must not specify more than one"
+ + " archive");
+ }
+ if (a.size() != 1) {
+ throw new BuildException("only single argument resource collections"
+ + " are supported as archives");
+ }
+ archive = a.iterator().next();
+ }
+
+ /**
+ * Get the archive that holds this Resource.
+ * @return the archive as a Resource.
+ */
+ public Resource getArchive() {
+ return isReference()
+ ? ((ArchiveResource) getCheckedRef()).getArchive() : archive;
+ }
+
+ /**
+ * Get the last modified date of this Resource.
+ * @return the last modification date.
+ */
+ public long getLastModified() {
+ if (isReference()) {
+ return ((Resource) getCheckedRef()).getLastModified();
+ }
+ checkEntry();
+ return super.getLastModified();
+ }
+
+ /**
+ * Get the size of this Resource.
+ * @return the long size of this Resource.
+ */
+ public long getSize() {
+ if (isReference()) {
+ return ((Resource) getCheckedRef()).getSize();
+ }
+ checkEntry();
+ return super.getSize();
+ }
+
+ /**
+ * Learn whether this Resource represents a directory.
+ * @return boolean flag indicating whether the entry is a directory.
+ */
+ public boolean isDirectory() {
+ if (isReference()) {
+ return ((Resource) getCheckedRef()).isDirectory();
+ }
+ checkEntry();
+ return super.isDirectory();
+ }
+
+ /**
+ * Find out whether this Resource represents an existing Resource.
+ * @return boolean existence flag.
+ */
+ public boolean isExists() {
+ if (isReference()) {
+ return ((Resource) getCheckedRef()).isExists();
+ }
+ checkEntry();
+ return super.isExists();
+ }
+
+ /**
+ * Get the file or dir mode for this Resource.
+ * @return integer representation of Unix permission mask.
+ */
+ public int getMode() {
+ if (isReference()) {
+ return ((ArchiveResource) getCheckedRef()).getMode();
+ }
+ checkEntry();
+ return mode;
+ }
+
+ /**
+ * Overrides the super version.
+ * @param r the Reference to set.
+ */
+ public void setRefid(Reference r) {
+ if (archive != null || modeSet) {
+ throw tooManyAttributes();
+ }
+ super.setRefid(r);
+ }
+
+ /**
+ * Compare this ArchiveResource to another Resource.
+ * @param another the other Resource against which to compare.
+ * @return a negative integer, zero, or a positive integer as this Resource
+ * is less than, equal to, or greater than the specified Resource.
+ */
+ public int compareTo(Resource another) {
+ return this.equals(another) ? 0 : super.compareTo(another);
+ }
+
+ /**
+ * Compare another Object to this ArchiveResource for equality.
+ * @param another the other Object to compare.
+ * @return true if another is a Resource representing
+ * the same entry in the same archive.
+ */
+ public boolean equals(Object another) {
+ if (this == another) {
+ return true;
+ }
+ if (isReference()) {
+ return getCheckedRef().equals(another);
+ }
+ if (another == null || !(another.getClass().equals(getClass()))) {
+ return false;
+ }
+ ArchiveResource r = (ArchiveResource) another;
+ return getArchive().equals(r.getArchive())
+ && getName().equals(r.getName());
+ }
+
+ /**
+ * Get the hash code for this Resource.
+ * @return hash code as int.
+ */
+ public int hashCode() {
+ return super.hashCode()
+ * (getArchive() == null ? NULL_ARCHIVE : getArchive().hashCode());
+ }
+
+ /**
+ * Format this Resource as a String.
+ * @return String representatation of this Resource.
+ */
+ public String toString() {
+ return isReference() ? getCheckedRef().toString()
+ : getArchive().toString() + ':' + getName();
+ }
+
+ /**
+ * Validate settings and ensure that the represented "archive entry"
+ * has been established.
+ */
+ protected final synchronized void checkEntry() throws BuildException {
+ dieOnCircularReference();
+ if (haveEntry) {
+ return;
+ }
+ String name = getName();
+ if (name == null) {
+ throw new BuildException("entry name not set");
+ }
+ Resource r = getArchive();
+ if (r == null) {
+ throw new BuildException("archive attribute not set");
+ }
+ if (!r.isExists()) {
+ throw new BuildException(r.toString() + " does not exist.");
+ }
+ if (r.isDirectory()) {
+ throw new BuildException(r + " denotes a directory.");
+ }
+ fetchEntry();
+ haveEntry = true;
+ }
+
+ /**
+ * Fetch information from the named entry inside the archive.
+ */
+ protected abstract void fetchEntry();
+
+ /**
+ * {@inheritDoc}
+ */
+ protected synchronized void dieOnCircularReference(Stack<Object> stk, Project p) {
+ if (isChecked()) {
+ return;
+ }
+ if (isReference()) {
+ super.dieOnCircularReference(stk, p);
+ } else {
+ if (archive != null) {
+ pushAndInvokeCircularReferenceCheck(archive, stk, p);
+ }
+ setChecked(true);
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/Archives.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/Archives.java
new file mode 100644
index 00000000..4b0d51c6
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/Archives.java
@@ -0,0 +1,194 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.resources;
+
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Stack;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.ArchiveFileSet;
+import org.apache.tools.ant.types.DataType;
+import org.apache.tools.ant.types.Reference;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.ResourceCollection;
+import org.apache.tools.ant.types.TarFileSet;
+import org.apache.tools.ant.types.ZipFileSet;
+import org.apache.tools.ant.util.CollectionUtils;
+
+/**
+ * A resource collection that treats all nested resources as archives
+ * and returns the contents of the archives as its content.
+ *
+ * @since Ant 1.8.0
+ */
+public class Archives extends DataType
+ implements ResourceCollection, Cloneable {
+
+ private Union zips = new Union();
+ private Union tars = new Union();
+
+ /**
+ * Wrapper to identify nested resource collections as ZIP
+ * archives.
+ */
+ public Union createZips() {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ setChecked(false);
+ return zips;
+ }
+
+ /**
+ * Wrapper to identify nested resource collections as ZIP
+ * archives.
+ */
+ public Union createTars() {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ setChecked(false);
+ return tars;
+ }
+
+ /**
+ * Sums the sizes of nested archives.
+ */
+ public int size() {
+ if (isReference()) {
+ return ((Archives) getCheckedRef()).size();
+ }
+ dieOnCircularReference();
+ int total = 0;
+ for (final Iterator<ArchiveFileSet> i = grabArchives(); i.hasNext();) {
+ total += i.next().size();
+ }
+ return total;
+ }
+
+ /**
+ * Merges the nested collections.
+ */
+ public Iterator<Resource> iterator() {
+ if (isReference()) {
+ return ((Archives) getCheckedRef()).iterator();
+ }
+ dieOnCircularReference();
+ final List<Resource> l = new LinkedList<Resource>();
+ for (final Iterator<ArchiveFileSet> i = grabArchives(); i.hasNext();) {
+ l.addAll(CollectionUtils
+ .asCollection(i.next().iterator()));
+ }
+ return l.iterator();
+ }
+
+ /**
+ * @return false
+ */
+ public boolean isFilesystemOnly() {
+ if (isReference()) {
+ return ((Archives) getCheckedRef()).isFilesystemOnly();
+ }
+ dieOnCircularReference();
+ return false;
+ }
+
+ /**
+ * Overrides the base version.
+ * @param r the Reference to set.
+ */
+ @Override
+ public void setRefid(final Reference r) {
+ if (zips.getResourceCollections().size() > 0
+ || tars.getResourceCollections().size() > 0) {
+ throw tooManyAttributes();
+ }
+ super.setRefid(r);
+ }
+
+ /**
+ * Implement clone. The nested resource collections are cloned as
+ * well.
+ * @return a cloned instance.
+ */
+ @Override
+ public Object clone() {
+ try {
+ final Archives a = (Archives) super.clone();
+ a.zips = (Union) zips.clone();
+ a.tars = (Union) tars.clone();
+ return a;
+ } catch (final CloneNotSupportedException e) {
+ throw new BuildException(e);
+ }
+ }
+
+ // TODO this is a pretty expensive operation and so the result
+ // should be cached.
+ /**
+ * Turns all nested resources into corresponding ArchiveFileSets
+ * and returns an iterator over the collected archives.
+ */
+ protected Iterator<ArchiveFileSet> grabArchives() {
+ final List<ArchiveFileSet> l = new LinkedList<ArchiveFileSet>();
+ for (final Resource r : zips) {
+ l.add(configureArchive(new ZipFileSet(), r));
+ }
+ for (final Resource r : tars) {
+ l.add(configureArchive(new TarFileSet(), r));
+ }
+ return l.iterator();
+ }
+
+ /**
+ * Configures the archivefileset based on this type's settings,
+ * set the source.
+ */
+ protected ArchiveFileSet configureArchive(final ArchiveFileSet afs,
+ final Resource src) {
+ afs.setProject(getProject());
+ afs.setSrcResource(src);
+ return afs;
+ }
+
+ /**
+ * Overrides the version of DataType to recurse on all DataType
+ * child elements that may have been added.
+ * @param stk the stack of data types to use (recursively).
+ * @param p the project to use to dereference the references.
+ * @throws BuildException on error.
+ */
+ @Override
+ protected synchronized void dieOnCircularReference(final Stack<Object> stk, final Project p)
+ throws BuildException {
+ if (isChecked()) {
+ return;
+ }
+ if (isReference()) {
+ super.dieOnCircularReference(stk, p);
+ } else {
+ pushAndInvokeCircularReferenceCheck(zips, stk, p);
+ pushAndInvokeCircularReferenceCheck(tars, stk, p);
+ setChecked(true);
+ }
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/BCFileSet.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/BCFileSet.java
new file mode 100644
index 00000000..aa99a4a3
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/BCFileSet.java
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.resources;
+
+import java.util.Iterator;
+
+import org.apache.tools.ant.types.FileSet;
+import org.apache.tools.ant.types.Resource;
+
+/**
+ * Utility FileSet that includes directories for backwards-compatibility
+ * with certain tasks e.g. Delete.
+ * @since Ant 1.7
+ */
+public class BCFileSet extends FileSet {
+ /**
+ * Default constructor.
+ */
+ public BCFileSet() {
+ }
+
+ /**
+ * Construct a new BCFileSet from the specified FileSet.
+ * @param fs the FileSet from which to inherit config.
+ */
+ public BCFileSet(FileSet fs) {
+ super(fs);
+ }
+
+ /**
+ * Fulfill the ResourceCollection contract.
+ * @return an Iterator of Resources.
+ * @since Ant 1.7
+ */
+ public Iterator<Resource> iterator() {
+ if (isReference()) {
+ return ((FileSet) getRef(getProject())).iterator();
+ }
+ FileResourceIterator result = new FileResourceIterator(getProject(), getDir());
+ result.addFiles(getDirectoryScanner().getIncludedFiles());
+ result.addFiles(getDirectoryScanner().getIncludedDirectories());
+ return result;
+ }
+
+ /**
+ * Fulfill the ResourceCollection contract.
+ * @return number of elements as int.
+ * @since Ant 1.7
+ */
+ public int size() {
+ if (isReference()) {
+ return ((FileSet) getRef(getProject())).size();
+ }
+ return getDirectoryScanner().getIncludedFilesCount()
+ + getDirectoryScanner().getIncludedDirsCount();
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/BZip2Resource.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/BZip2Resource.java
new file mode 100644
index 00000000..0c2dd4be
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/BZip2Resource.java
@@ -0,0 +1,85 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.resources;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.apache.tools.bzip2.CBZip2InputStream;
+import org.apache.tools.bzip2.CBZip2OutputStream;
+
+/**
+ * A Bzip2 compressed resource.
+ *
+ * <p>Wraps around another resource, delegates all queries to that
+ * other resource but uncompresses/compresses streams on the fly.</p>
+ *
+ * @since Ant 1.7
+ */
+public class BZip2Resource extends CompressedResource {
+ private static final char[] MAGIC = new char[] {'B', 'Z'};
+
+ /** A no-arg constructor */
+ public BZip2Resource() {
+ }
+
+ /**
+ * Constructor with another resource to wrap.
+ * @param other the resource to wrap.
+ */
+ public BZip2Resource(org.apache.tools.ant.types.ResourceCollection other) {
+ super(other);
+ }
+
+ /**
+ * Decompress on the fly using {@link CBZip2InputStream}.
+ * @param in the stream to wrap.
+ * @return the wrapped stream.
+ * @throws IOException if there is a problem.
+ */
+ protected InputStream wrapStream(InputStream in) throws IOException {
+ for (int i = 0; i < MAGIC.length; i++) {
+ if (in.read() != MAGIC[i]) {
+ throw new IOException("Invalid bz2 stream.");
+ }
+ }
+ return new CBZip2InputStream(in);
+ }
+
+ /**
+ * Compress on the fly using {@link CBZip2OutputStream}.
+ * @param out the stream to wrap.
+ * @return the wrapped stream.
+ * @throws IOException if there is a problem.
+ */
+ protected OutputStream wrapStream(OutputStream out) throws IOException {
+ for (int i = 0; i < MAGIC.length; i++) {
+ out.write(MAGIC[i]);
+ }
+ return new CBZip2OutputStream(out);
+ }
+
+ /**
+ * Get the name of the compression method.
+ * @return the string "Bzip2".
+ */
+ protected String getCompressionName() {
+ return "Bzip2";
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/BaseResourceCollectionContainer.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/BaseResourceCollectionContainer.java
new file mode 100644
index 00000000..281fa0f1
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/BaseResourceCollectionContainer.java
@@ -0,0 +1,268 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.resources;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Stack;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.DataType;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.ResourceCollection;
+
+/**
+ * Base class for ResourceCollections that nest multiple ResourceCollections.
+ * @since Ant 1.7
+ */
+public abstract class BaseResourceCollectionContainer
+ extends DataType implements ResourceCollection, Cloneable {
+ private List<ResourceCollection> rc = new ArrayList<ResourceCollection>();
+ private Collection<Resource> coll = null;
+ private boolean cache = true;
+
+ /**
+ * Create a new BaseResourceCollectionContainer.
+ */
+ public BaseResourceCollectionContainer() {
+ // TODO Auto-generated constructor stub
+ }
+
+ /**
+ * Create a new BaseResourceCollectionContainer.
+ * @since Ant 1.8
+ */
+ public BaseResourceCollectionContainer(Project project) {
+ setProject(project);
+ }
+
+ /**
+ * Set whether to cache collections.
+ * @param b boolean cache flag.
+ */
+ public synchronized void setCache(boolean b) {
+ cache = b;
+ }
+
+ /**
+ * Learn whether to cache collections. Default is <code>true</code>.
+ * @return boolean cache flag.
+ */
+ public synchronized boolean isCache() {
+ return cache;
+ }
+
+ /**
+ * Clear the container.
+ * @throws BuildException on error.
+ */
+ public synchronized void clear() throws BuildException {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ rc.clear();
+ FailFast.invalidate(this);
+ coll = null;
+ setChecked(false);
+ }
+
+ /**
+ * Add a ResourceCollection to the container.
+ * @param c the ResourceCollection to add.
+ * @throws BuildException on error.
+ */
+ public synchronized void add(ResourceCollection c) throws BuildException {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ if (c == null) {
+ return;
+ }
+ if (Project.getProject(c) == null) {
+ Project p = getProject();
+ if (p != null) {
+ p.setProjectReference(c);
+ }
+ }
+ rc.add(c);
+ FailFast.invalidate(this);
+ coll = null;
+ setChecked(false);
+ }
+
+ /**
+ * Add the Collection of ResourceCollections to the container.
+ * @param c the Collection whose elements to add.
+ * @throws BuildException on error.
+ */
+ public synchronized void addAll(Collection<? extends ResourceCollection> c) throws BuildException {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ try {
+ for (ResourceCollection resourceCollection : c) {
+ add(resourceCollection);
+ }
+ } catch (ClassCastException e) {
+ throw new BuildException(e);
+ }
+ }
+
+ /**
+ * Fulfill the ResourceCollection contract. The Iterator returned
+ * will throw ConcurrentModificationExceptions if ResourceCollections
+ * are added to this container while the Iterator is in use.
+ * @return a "fail-fast" Iterator.
+ */
+ public final synchronized Iterator<Resource> iterator() {
+ if (isReference()) {
+ return ((BaseResourceCollectionContainer) getCheckedRef()).iterator();
+ }
+ dieOnCircularReference();
+ return new FailFast(this, cacheCollection().iterator());
+ }
+
+ /**
+ * Fulfill the ResourceCollection contract.
+ * @return number of elements as int.
+ */
+ public synchronized int size() {
+ if (isReference()) {
+ return getCheckedRef(BaseResourceCollectionContainer.class, getDataTypeName()).size();
+ }
+ dieOnCircularReference();
+ return cacheCollection().size();
+ }
+
+ /**
+ * Fulfill the ResourceCollection contract.
+ * @return whether this is a filesystem-only resource collection.
+ */
+ public synchronized boolean isFilesystemOnly() {
+ if (isReference()) {
+ return ((BaseResourceCollectionContainer) getCheckedRef()).isFilesystemOnly();
+ }
+ dieOnCircularReference();
+ //first the easy way, if all children are filesystem-only, return true:
+ boolean goEarly = true;
+ for (Iterator<ResourceCollection> i = rc.iterator(); goEarly && i.hasNext();) {
+ goEarly = i.next().isFilesystemOnly();
+ }
+ if (goEarly) {
+ return true;
+ }
+ /* now check each Resource in case the child only
+ lets through files from any children IT may have: */
+ for (Resource r : cacheCollection()) {
+ if (r.as(FileProvider.class) == null) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Overrides the version of DataType to recurse on all DataType
+ * child elements that may have been added.
+ * @param stk the stack of data types to use (recursively).
+ * @param p the project to use to dereference the references.
+ * @throws BuildException on error.
+ */
+ protected synchronized void dieOnCircularReference(Stack<Object> stk, Project p)
+ throws BuildException {
+ if (isChecked()) {
+ return;
+ }
+ if (isReference()) {
+ super.dieOnCircularReference(stk, p);
+ } else {
+ for (ResourceCollection resourceCollection : rc) {
+ if (resourceCollection instanceof DataType) {
+ pushAndInvokeCircularReferenceCheck((DataType) resourceCollection, stk, p);
+ }
+ }
+ setChecked(true);
+ }
+ }
+
+ /**
+ * Get the nested ResourceCollections.
+ * @return List.
+ */
+ public final synchronized List<ResourceCollection> getResourceCollections() {
+ dieOnCircularReference();
+ return Collections.unmodifiableList(rc);
+ }
+
+ /**
+ * Template method for subclasses to return a Collection object of Resources.
+ * @return Collection.
+ */
+ protected abstract Collection<Resource> getCollection();
+
+ /**
+ * Implement clone. The set of nested resource
+ * collections is shallowly cloned.
+ * @return a cloned instance.
+ */
+ public Object clone() {
+ try {
+ BaseResourceCollectionContainer c
+ = (BaseResourceCollectionContainer) super.clone();
+ c.rc = new ArrayList<ResourceCollection>(rc);
+ c.coll = null;
+ return c;
+ } catch (CloneNotSupportedException e) {
+ throw new BuildException(e);
+ }
+ }
+
+ /**
+ * Format this BaseResourceCollectionContainer as a String.
+ * @return a descriptive <code>String</code>.
+ */
+ public synchronized String toString() {
+ if (isReference()) {
+ return getCheckedRef().toString();
+ }
+ if (cacheCollection().size() == 0) {
+ return "";
+ }
+ StringBuilder sb = new StringBuilder();
+ for (Resource resource : coll) {
+ if (sb.length() > 0) {
+ sb.append(File.pathSeparatorChar);
+ }
+ sb.append(resource);
+ }
+ return sb.toString();
+ }
+
+ private synchronized Collection<Resource> cacheCollection() {
+ if (coll == null || !isCache()) {
+ coll = getCollection();
+ }
+ return coll;
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/BaseResourceCollectionWrapper.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/BaseResourceCollectionWrapper.java
new file mode 100644
index 00000000..78ba95ee
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/BaseResourceCollectionWrapper.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.resources;
+
+import java.util.Collection;
+import java.util.Iterator;
+
+import org.apache.tools.ant.types.Resource;
+
+/**
+ * Base class for a ResourceCollection that wraps a single nested
+ * ResourceCollection.
+ * @since Ant 1.7
+ */
+public abstract class BaseResourceCollectionWrapper
+ extends AbstractResourceCollectionWrapper {
+
+ private Collection<Resource> coll = null;
+
+ protected Iterator<Resource> createIterator() {
+ return cacheCollection().iterator();
+ }
+
+ protected int getSize() {
+ return cacheCollection().size();
+ }
+
+ /**
+ * Template method for subclasses to return a Collection of Resources.
+ * @return Collection.
+ */
+ protected abstract Collection<Resource> getCollection();
+
+ private synchronized Collection<Resource> cacheCollection() {
+ if (coll == null || !isCache()) {
+ coll = getCollection();
+ }
+ return coll;
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/CompressedResource.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/CompressedResource.java
new file mode 100644
index 00000000..2c72c26f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/CompressedResource.java
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.resources;
+
+import org.apache.tools.ant.types.ResourceCollection;
+
+/**
+ * A compressed resource.
+ *
+ * <p>Wraps around another resource, delegates all queries (except
+ * getSize) to that other resource but uncompresses/compresses streams
+ * on the fly.</p>
+ *
+ * @since Ant 1.7
+ */
+public abstract class CompressedResource extends ContentTransformingResource {
+
+ /** no arg constructor */
+ protected CompressedResource() {
+ }
+
+ /**
+ * Constructor with another resource to wrap.
+ * @param other the resource to wrap.
+ */
+ protected CompressedResource(ResourceCollection other) {
+ addConfigured(other);
+ }
+
+ /**
+ * Get the string representation of this Resource.
+ * @return this Resource formatted as a String.
+ * @since Ant 1.7
+ */
+ public String toString() {
+ return getCompressionName() + " compressed " + super.toString();
+ }
+
+ /**
+ * Get the name of the compression method used.
+ * @return the name of the compression method.
+ */
+ protected abstract String getCompressionName();
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/ContentTransformingResource.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/ContentTransformingResource.java
new file mode 100644
index 00000000..79445bfd
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/ContentTransformingResource.java
@@ -0,0 +1,177 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.resources;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.types.ResourceCollection;
+import org.apache.tools.ant.util.FileUtils;
+
+/**
+ * A resource that transforms the content of another resource.
+ *
+ * <p>Wraps around another resource, delegates all queries (except
+ * getSize) to that other resource but transforms stream content
+ * on the fly.</p>
+ *
+ * @since Ant 1.8
+ */
+public abstract class ContentTransformingResource extends ResourceDecorator {
+
+ private static final int BUFFER_SIZE = 8192;
+
+ /** no arg constructor */
+ protected ContentTransformingResource() {
+ }
+
+ /**
+ * Constructor with another resource to wrap.
+ * @param other the resource to wrap.
+ */
+ protected ContentTransformingResource(final ResourceCollection other) {
+ super(other);
+ }
+
+ /**
+ * Get the size of this Resource.
+ * @return the size, as a long, 0 if the Resource does not exist (for
+ * compatibility with java.io.File), or UNKNOWN_SIZE if not known.
+ */
+ @Override
+ public long getSize() {
+ if (isExists()) {
+ InputStream in = null;
+ try {
+ in = getInputStream();
+ final byte[] buf = new byte[BUFFER_SIZE];
+ int size = 0;
+ int readNow;
+ while ((readNow = in.read(buf, 0, buf.length)) > 0) {
+ size += readNow;
+ }
+ return size;
+ } catch (final IOException ex) {
+ throw new BuildException("caught exception while reading "
+ + getName(), ex);
+ } finally {
+ FileUtils.close(in);
+ }
+ } else {
+ return 0;
+ }
+ }
+
+ /**
+ * Get an InputStream for the Resource.
+ * @return an InputStream containing this Resource's content.
+ * @throws IOException if unable to provide the content of this
+ * Resource as a stream.
+ * @throws UnsupportedOperationException if InputStreams are not
+ * supported for this Resource type.
+ */
+ @Override
+ public InputStream getInputStream() throws IOException {
+ InputStream in = getResource().getInputStream();
+ if (in != null) {
+ in = wrapStream(in);
+ }
+ return in;
+ }
+
+ /**
+ * Get an OutputStream for the Resource.
+ * @return an OutputStream to which content can be written.
+ * @throws IOException if unable to provide the content of this
+ * Resource as a stream.
+ * @throws UnsupportedOperationException if OutputStreams are not
+ * supported for this Resource type.
+ */
+ @Override
+ public OutputStream getOutputStream() throws IOException {
+ OutputStream out = getResource().getOutputStream();
+ if (out != null) {
+ out = wrapStream(out);
+ }
+ return out;
+ }
+
+ /**
+ * Suppress FileProvider, re-implement Appendable
+ */
+ @Override
+ public <T> T as(final Class<T> clazz) {
+ if (Appendable.class.isAssignableFrom(clazz)) {
+ if (isAppendSupported()) {
+ final Appendable a =
+ getResource().as(Appendable.class);
+ if (a != null) {
+ return clazz.cast(new Appendable() {
+ public OutputStream getAppendOutputStream()
+ throws IOException {
+ OutputStream out = a.getAppendOutputStream();
+ if (out != null) {
+ out = wrapStream(out);
+ }
+ return out;
+ }
+ });
+ }
+ }
+ return null;
+ }
+
+ return FileProvider.class.isAssignableFrom(clazz)
+ ? null : getResource().as(clazz);
+ }
+
+ /**
+ * Learn whether the transformation performed allows appends.
+ *
+ * <p>In general compressed outputs will become invalid if they
+ * are appended to, for example.</p>
+ *
+ * <p>This implementations returns false.</p>
+ */
+ protected boolean isAppendSupported() {
+ return false;
+ }
+
+ /**
+ * Get a content-filtering/transforming InputStream.
+ *
+ * @param in InputStream to wrap, will never be null.
+ * @return a compressed inputstream.
+ * @throws IOException if there is a problem.
+ */
+ protected abstract InputStream wrapStream(InputStream in)
+ throws IOException;
+
+ /**
+ * Get a content-filtering/transforming OutputStream.
+ *
+ * @param out OutputStream to wrap, will never be null.
+ * @return a compressed outputstream.
+ * @throws IOException if there is a problem.
+ */
+ protected abstract OutputStream wrapStream(OutputStream out)
+ throws IOException;
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/Difference.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/Difference.java
new file mode 100644
index 00000000..3f3c983c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/Difference.java
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.resources;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.ResourceCollection;
+
+/**
+ * ResourceCollection representing the difference between
+ * two or more nested ResourceCollections.
+ * @since Ant 1.7
+ */
+public class Difference extends BaseResourceCollectionContainer {
+
+ /**
+ * Calculate the difference of the nested ResourceCollections.
+ * @return a Collection of Resources.
+ */
+ protected Collection<Resource> getCollection() {
+ List<ResourceCollection> rcs = getResourceCollections();
+ int size = rcs.size();
+ if (size < 2) {
+ throw new BuildException("The difference of " + size
+ + " resource collection" + ((size == 1) ? "" : "s")
+ + " is undefined.");
+ }
+ Set<Resource> hs = new HashSet<Resource>();
+ List<Resource> al = new ArrayList<Resource>();
+ for (ResourceCollection rc : rcs) {
+ for (Resource r : rc) {
+ if (hs.add(r)) {
+ al.add(r);
+ } else {
+ al.remove(r);
+ }
+ }
+ }
+ return al;
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/FailFast.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/FailFast.java
new file mode 100644
index 00000000..dc962bb4
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/FailFast.java
@@ -0,0 +1,135 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.resources;
+
+import java.util.ConcurrentModificationException;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.Set;
+import java.util.WeakHashMap;
+
+import org.apache.tools.ant.types.Resource;
+
+/**
+ * Helper class for ResourceCollections to return Iterators
+ * that fail on changes to the object.
+ * @since Ant 1.7
+ */
+/*package-private*/ class FailFast implements Iterator<Resource> {
+ private static final WeakHashMap<Object, Set<FailFast>> MAP = new WeakHashMap<Object, Set<FailFast>>();
+
+ /**
+ * Invalidate any in-use Iterators from the specified Object.
+ * @param o the parent Object.
+ */
+ static synchronized void invalidate(Object o) {
+ Set<FailFast> s = MAP.get(o);
+ if (s != null) {
+ s.clear();
+ }
+ }
+
+ private static synchronized void add(FailFast f) {
+ Set<FailFast> s = MAP.get(f.parent);
+ if (s == null) {
+ s = new HashSet<FailFast>();
+ MAP.put(f.parent, s);
+ }
+ s.add(f);
+ }
+
+ private static synchronized void remove(FailFast f) {
+ Set<FailFast> s = MAP.get(f.parent);
+ if (s != null) {
+ s.remove(f);
+ }
+ }
+
+ private static synchronized void failFast(FailFast f) {
+ Set<FailFast> s = MAP.get(f.parent);
+ if (!s.contains(f)) {
+ throw new ConcurrentModificationException();
+ }
+ }
+
+ private final Object parent;
+ private Iterator<Resource> wrapped;
+
+ /**
+ * Construct a new FailFast Iterator wrapping the specified Iterator
+ * and dependent upon the specified parent Object.
+ * @param o the parent Object.
+ * @param i the wrapped Iterator.
+ */
+ FailFast(Object o, Iterator<Resource> i) {
+ if (o == null) {
+ throw new IllegalArgumentException("parent object is null");
+ }
+ if (i == null) {
+ throw new IllegalArgumentException("cannot wrap null iterator");
+ }
+ parent = o;
+ if (i.hasNext()) {
+ wrapped = i;
+ add(this);
+ }
+ }
+
+ /**
+ * Fulfill the Iterator contract.
+ * @return true if there are more elements.
+ */
+ public boolean hasNext() {
+ if (wrapped == null) {
+ return false;
+ }
+ failFast(this);
+ return wrapped.hasNext();
+ }
+
+ /**
+ * Fulfill the Iterator contract.
+ * @return the next element.
+ * @throws NoSuchElementException if no more elements.
+ */
+ public Resource next() {
+ if (wrapped == null || !wrapped.hasNext()) {
+ throw new NoSuchElementException();
+ }
+ failFast(this);
+ try {
+ return wrapped.next();
+ } finally {
+ if (!wrapped.hasNext()) {
+ wrapped = null;
+ remove(this);
+ }
+ }
+ }
+
+ /**
+ * Fulfill the Iterator contract.
+ * @throws UnsupportedOperationException always.
+ */
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/FileProvider.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/FileProvider.java
new file mode 100644
index 00000000..aa283004
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/FileProvider.java
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types.resources;
+
+import java.io.File;
+
+/**
+ * This is an interface that resources that can provide a file should implement.
+ * This is a refactoring of {@link FileResource}, to allow other resources
+ * to act as sources of files (and to make components that only support
+ * file-based resources from only support FileResource resources.
+ * @since Ant 1.8
+ */
+public interface FileProvider {
+ /**
+ * Get the file represented by this Resource.
+ * @return the file.
+ */
+ File getFile();
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/FileResource.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/FileResource.java
new file mode 100644
index 00000000..3ed49b81
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/FileResource.java
@@ -0,0 +1,392 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.resources;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.Reference;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.ResourceFactory;
+import org.apache.tools.ant.util.FileUtils;
+
+/**
+ * A Resource representation of a File.
+ * @since Ant 1.7
+ */
+public class FileResource extends Resource implements Touchable, FileProvider,
+ ResourceFactory, Appendable {
+
+ private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+ private static final int NULL_FILE
+ = Resource.getMagicNumber("null file".getBytes());
+
+ private File file;
+ private File baseDir;
+
+ /**
+ * Default constructor.
+ */
+ public FileResource() {
+ }
+
+ /**
+ * Construct a new FileResource using the specified basedir and relative name.
+ * @param b the basedir as File.
+ * @param name the relative filename.
+ */
+ public FileResource(File b, String name) {
+ this.baseDir = b;
+ this.file = FILE_UTILS.resolveFile(b, name);
+ }
+
+ /**
+ * Construct a new FileResource from a File.
+ * @param f the File represented.
+ */
+ public FileResource(File f) {
+ setFile(f);
+ }
+
+ /**
+ * Create a new FileResource.
+ * @param p Project
+ * @param f File represented
+ * @since Ant 1.8
+ */
+ public FileResource(Project p, File f) {
+ this(f);
+ setProject(p);
+ }
+
+ /**
+ * Constructor for Ant attribute introspection.
+ * @param p the Project against which to resolve <code>s</code>.
+ * @param s the absolute or Project-relative filename as a String.
+ * @see org.apache.tools.ant.IntrospectionHelper
+ */
+ public FileResource(Project p, String s) {
+ this(p, p.resolveFile(s));
+ }
+
+ /**
+ * Set the File for this FileResource.
+ * @param f the File to be represented.
+ */
+ public void setFile(File f) {
+ checkAttributesAllowed();
+ file = f;
+ if (f != null && (getBaseDir() == null || !FILE_UTILS.isLeadingPath(getBaseDir(), f))) {
+ setBaseDir(f.getParentFile());
+ }
+ }
+
+ /**
+ * Get the file represented by this FileResource.
+ * @return the File.
+ */
+ public File getFile() {
+ if (isReference()) {
+ return ((FileResource) getCheckedRef()).getFile();
+ }
+ dieOnCircularReference();
+ synchronized (this) {
+ if (file == null) {
+ //try to resolve file set via basedir/name property setters:
+ File d = getBaseDir();
+ String n = super.getName();
+ if (n != null) {
+ setFile(FILE_UTILS.resolveFile(d, n));
+ }
+ }
+ }
+ return file;
+ }
+
+ /**
+ * Set the basedir for this FileResource.
+ * @param b the basedir as File.
+ */
+ public void setBaseDir(File b) {
+ checkAttributesAllowed();
+ baseDir = b;
+ }
+
+ /**
+ * Return the basedir to which the name is relative.
+ * @return the basedir as File.
+ */
+ public File getBaseDir() {
+ if (isReference()) {
+ return ((FileResource) getCheckedRef()).getBaseDir();
+ }
+ dieOnCircularReference();
+ return baseDir;
+ }
+
+ /**
+ * Overrides the super version.
+ * @param r the Reference to set.
+ */
+ public void setRefid(Reference r) {
+ if (file != null || baseDir != null) {
+ throw tooManyAttributes();
+ }
+ super.setRefid(r);
+ }
+
+ /**
+ * Get the name of this FileResource. If the basedir is set,
+ * the name will be relative to that. Otherwise the basename
+ * only will be returned.
+ * @return the name of this resource.
+ */
+ public String getName() {
+ if (isReference()) {
+ return ((Resource) getCheckedRef()).getName();
+ }
+ File b = getBaseDir();
+ return b == null ? getNotNullFile().getName()
+ : FILE_UTILS.removeLeadingPath(b, getNotNullFile());
+ }
+
+ /**
+ * Learn whether this file exists.
+ * @return true if this resource exists.
+ */
+ public boolean isExists() {
+ return isReference() ? ((Resource) getCheckedRef()).isExists()
+ : getNotNullFile().exists();
+ }
+
+ /**
+ * Get the modification time in milliseconds since 01.01.1970 .
+ * @return 0 if the resource does not exist.
+ */
+ public long getLastModified() {
+ return isReference()
+ ? ((Resource) getCheckedRef()).getLastModified()
+ : getNotNullFile().lastModified();
+ }
+
+ /**
+ * Learn whether the resource is a directory.
+ * @return boolean flag indicating if the resource is a directory.
+ */
+ public boolean isDirectory() {
+ return isReference() ? ((Resource) getCheckedRef()).isDirectory()
+ : getNotNullFile().isDirectory();
+ }
+
+ /**
+ * Get the size of this Resource.
+ * @return the size, as a long, 0 if the Resource does not exist.
+ */
+ public long getSize() {
+ return isReference() ? ((Resource) getCheckedRef()).getSize()
+ : getNotNullFile().length();
+ }
+
+ /**
+ * Return an InputStream for reading the contents of this Resource.
+ * @return an InputStream object.
+ * @throws IOException if an error occurs.
+ */
+ public InputStream getInputStream() throws IOException {
+ return isReference()
+ ? ((Resource) getCheckedRef()).getInputStream()
+ : new FileInputStream(getNotNullFile());
+ }
+
+ /**
+ * Get an OutputStream for the Resource.
+ * @return an OutputStream to which content can be written.
+ * @throws IOException if unable to provide the content of this
+ * Resource as a stream.
+ * @throws UnsupportedOperationException if OutputStreams are not
+ * supported for this Resource type.
+ */
+ public OutputStream getOutputStream() throws IOException {
+ if (isReference()) {
+ return ((FileResource) getCheckedRef()).getOutputStream();
+ }
+ return getOutputStream(false);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public OutputStream getAppendOutputStream() throws IOException {
+ if (isReference()) {
+ return ((FileResource) getCheckedRef()).getAppendOutputStream();
+ }
+ return getOutputStream(true);
+ }
+
+ private OutputStream getOutputStream(boolean append) throws IOException {
+ File f = getNotNullFile();
+ if (f.exists()) {
+ if (f.isFile() && !append) {
+ f.delete();
+ }
+ } else {
+ File p = f.getParentFile();
+ if (p != null && !(p.exists())) {
+ p.mkdirs();
+ }
+ }
+ return append ? new FileOutputStream(f.getAbsolutePath(), true) : new FileOutputStream(f);
+ }
+
+ /**
+ * Compare this FileResource to another Resource.
+ * @param another the other Resource against which to compare.
+ * @return a negative integer, zero, or a positive integer as this FileResource
+ * is less than, equal to, or greater than the specified Resource.
+ */
+ public int compareTo(Resource another) {
+ if (isReference()) {
+ return ((Resource) getCheckedRef()).compareTo(another);
+ }
+ if (this.equals(another)) {
+ return 0;
+ }
+ FileProvider otherFP = another.as(FileProvider.class);
+ if (otherFP != null) {
+ File f = getFile();
+ if (f == null) {
+ return -1;
+ }
+ File of = otherFP.getFile();
+ if (of == null) {
+ return 1;
+ }
+ return f.compareTo(of);
+ }
+ return super.compareTo(another);
+ }
+
+ /**
+ * Compare another Object to this FileResource for equality.
+ * @param another the other Object to compare.
+ * @return true if another is a FileResource representing the same file.
+ */
+ public boolean equals(Object another) {
+ if (this == another) {
+ return true;
+ }
+ if (isReference()) {
+ return getCheckedRef().equals(another);
+ }
+ if (another == null || !(another.getClass().equals(getClass()))) {
+ return false;
+ }
+ FileResource otherfr = (FileResource) another;
+ return getFile() == null
+ ? otherfr.getFile() == null
+ : getFile().equals(otherfr.getFile());
+ }
+
+ /**
+ * Get the hash code for this Resource.
+ * @return hash code as int.
+ */
+ public int hashCode() {
+ if (isReference()) {
+ return getCheckedRef().hashCode();
+ }
+ return MAGIC * (getFile() == null ? NULL_FILE : getFile().hashCode());
+ }
+
+ /**
+ * Get the string representation of this Resource.
+ * @return this FileResource formatted as a String.
+ */
+ public String toString() {
+ if (isReference()) {
+ return getCheckedRef().toString();
+ }
+ if (file == null) {
+ return "(unbound file resource)";
+ }
+ String absolutePath = file.getAbsolutePath();
+ return FILE_UTILS.normalize(absolutePath).getAbsolutePath();
+ }
+
+ /**
+ * Fulfill the ResourceCollection contract.
+ * @return whether this Resource is a FileResource.
+ */
+ public boolean isFilesystemOnly() {
+ if (isReference()) {
+ return ((FileResource) getCheckedRef()).isFilesystemOnly();
+ }
+ dieOnCircularReference();
+ return true;
+ }
+
+ /**
+ * Implement the Touchable interface.
+ * @param modTime new last modification time.
+ */
+ public void touch(long modTime) {
+ if (isReference()) {
+ ((FileResource) getCheckedRef()).touch(modTime);
+ return;
+ }
+ if (!getNotNullFile().setLastModified(modTime)) {
+ log("Failed to change file modification time", Project.MSG_WARN);
+ }
+ }
+
+ /**
+ * Get the file represented by this FileResource, ensuring it is not null.
+ * @return the not-null File.
+ * @throws BuildException if file is null.
+ */
+ protected File getNotNullFile() {
+ if (getFile() == null) {
+ throw new BuildException("file attribute is null!");
+ }
+ dieOnCircularReference();
+ return getFile();
+ }
+
+ /**
+ * Create a new resource that matches a relative or absolute path.
+ * If the current instance has a compatible baseDir attribute, it is copied.
+ * @param path relative/absolute path to a resource
+ * @return a new resource of type FileResource
+ * @throws BuildException if desired
+ * @since Ant1.8
+ */
+ public Resource getResource(String path) {
+ File newfile = FILE_UTILS.resolveFile(getFile(), path);
+ FileResource fileResource = new FileResource(newfile);
+ if (FILE_UTILS.isLeadingPath(getBaseDir(), newfile)) {
+ fileResource.setBaseDir(getBaseDir());
+ }
+ return fileResource;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/FileResourceIterator.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/FileResourceIterator.java
new file mode 100644
index 00000000..6d8849ce
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/FileResourceIterator.java
@@ -0,0 +1,149 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.resources;
+
+import java.io.File;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.Resource;
+
+/**
+ * Iterator of FileResources from filenames.
+ * @since Ant 1.7
+ */
+public class FileResourceIterator implements Iterator<Resource> {
+ private Project project;
+ private File basedir;
+ private String[] files;
+ private int pos = 0;
+
+ /**
+ * Construct a new FileResourceIterator.
+ * @deprecated in favor of {@link FileResourceIterator#FileResourceIterator(Project)}
+ */
+ public FileResourceIterator() {
+ }
+
+ /**
+ * Create a new FileResourceIterator.
+ * @param project associated Project instance
+ * @since Ant 1.8
+ */
+ public FileResourceIterator(Project project) {
+ this.project = project;
+ }
+
+ /**
+ * Construct a new FileResourceIterator relative to the specified
+ * base directory.
+ * @param basedir the base directory of this instance.
+ * @deprecated in favor of {@link FileResourceIterator#FileResourceIterator(Project, File)}
+ */
+ public FileResourceIterator(File basedir) {
+ this(null, basedir);
+ }
+
+ /**
+ * Construct a new FileResourceIterator relative to the specified
+ * base directory.
+ * @param project associated Project instance
+ * @param basedir the base directory of this instance.
+ * @since Ant 1.8
+ */
+ public FileResourceIterator(Project project, File basedir) {
+ this(project);
+ this.basedir = basedir;
+ }
+
+ /**
+ * Construct a new FileResourceIterator over the specified filenames,
+ * relative to the specified base directory.
+ * @param basedir the base directory of this instance.
+ * @param filenames the String[] of filenames.
+ * @deprecated in favor of {@link FileResourceIterator#FileResourceIterator(Project, File, String[])}
+ */
+ public FileResourceIterator(File basedir, String[] filenames) {
+ this(null, basedir, filenames);
+ }
+
+ /**
+ * Construct a new FileResourceIterator over the specified filenames,
+ * relative to the specified base directory.
+ * @param project associated Project instance
+ * @param basedir the base directory of this instance.
+ * @param filenames the String[] of filenames.
+ * @since Ant 1.8
+ */
+ public FileResourceIterator(Project project, File basedir, String[] filenames) {
+ this(project, basedir);
+ addFiles(filenames);
+ }
+
+ /**
+ * Add an array of filenames to this FileResourceIterator.
+ * @param s the filenames to add.
+ */
+ public void addFiles(String[] s) {
+ int start = (files == null) ? 0 : files.length;
+ String[] newfiles = new String[start + s.length];
+ if (start > 0) {
+ System.arraycopy(files, 0, newfiles, 0, start);
+ }
+ files = newfiles;
+ System.arraycopy(s, 0, files, start, s.length);
+ }
+
+ /**
+ * Find out whether this FileResourceIterator has more elements.
+ * @return whether there are more Resources to iterate over.
+ */
+ public boolean hasNext() {
+ return pos < files.length;
+ }
+
+ /**
+ * Get the next element from this FileResourceIterator.
+ * @return the next Object.
+ */
+ public Resource next() {
+ return nextResource();
+ }
+
+ /**
+ * Not implemented.
+ */
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Convenience method to return the next resource.
+ * @return the next File.
+ */
+ public FileResource nextResource() {
+ if (!hasNext()) {
+ throw new NoSuchElementException();
+ }
+ FileResource result = new FileResource(basedir, files[pos++]);
+ result.setProject(project);
+ return result;
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/Files.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/Files.java
new file mode 100644
index 00000000..521bcc8d
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/Files.java
@@ -0,0 +1,503 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.resources;
+
+import java.io.File;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.DirectoryScanner;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.PatternSet;
+import org.apache.tools.ant.types.Reference;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.ResourceCollection;
+import org.apache.tools.ant.types.selectors.AbstractSelectorContainer;
+import org.apache.tools.ant.types.selectors.FileSelector;
+
+/**
+ * ResourceCollection implementation; like AbstractFileSet with absolute paths.
+ * @since Ant 1.7
+ */
+public class Files extends AbstractSelectorContainer
+ implements ResourceCollection {
+
+ private static final Iterator<Resource> EMPTY_ITERATOR
+ = Collections.<Resource>emptySet().iterator();
+
+ private PatternSet defaultPatterns = new PatternSet();
+ private Vector<PatternSet> additionalPatterns = new Vector<PatternSet>();
+
+ private boolean useDefaultExcludes = true;
+ private boolean caseSensitive = true;
+ private boolean followSymlinks = true;
+
+ /* cached DirectoryScanner instance */
+ private DirectoryScanner ds = null;
+
+ /**
+ * Construct a new <code>Files</code> collection.
+ */
+ public Files() {
+ super();
+ }
+
+ /**
+ * Construct a new <code>Files</code> collection, shallowly cloned
+ * from the specified <code>Files</code>.
+ * @param f the <code>Files</code> to use as a template.
+ */
+ protected Files(Files f) {
+ this.defaultPatterns = f.defaultPatterns;
+ this.additionalPatterns = f.additionalPatterns;
+ this.useDefaultExcludes = f.useDefaultExcludes;
+ this.caseSensitive = f.caseSensitive;
+ this.followSymlinks = f.followSymlinks;
+ this.ds = f.ds;
+ setProject(f.getProject());
+ }
+
+ /**
+ * Make this instance in effect a reference to another instance.
+ *
+ * <p>You must not set another attribute or nest elements inside
+ * this element if you make it a reference.</p>
+ * @param r the <code>Reference</code> to use.
+ * @throws BuildException if there is a problem.
+ */
+ public void setRefid(Reference r) throws BuildException {
+ if (hasPatterns(defaultPatterns)) {
+ throw tooManyAttributes();
+ }
+ if (!additionalPatterns.isEmpty()) {
+ throw noChildrenAllowed();
+ }
+ if (hasSelectors()) {
+ throw noChildrenAllowed();
+ }
+ super.setRefid(r);
+ }
+
+ /**
+ * Create a nested patternset.
+ * @return <code>PatternSet</code>.
+ */
+ public synchronized PatternSet createPatternSet() {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ PatternSet patterns = new PatternSet();
+ additionalPatterns.addElement(patterns);
+ ds = null;
+ setChecked(false);
+ return patterns;
+ }
+
+ /**
+ * Add a name entry to the include list.
+ * @return <code>PatternSet.NameEntry</code>.
+ */
+ public synchronized PatternSet.NameEntry createInclude() {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ ds = null;
+ return defaultPatterns.createInclude();
+ }
+
+ /**
+ * Add a name entry to the include files list.
+ * @return <code>PatternSet.NameEntry</code>.
+ */
+ public synchronized PatternSet.NameEntry createIncludesFile() {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ ds = null;
+ return defaultPatterns.createIncludesFile();
+ }
+
+ /**
+ * Add a name entry to the exclude list.
+ * @return <code>PatternSet.NameEntry</code>.
+ */
+ public synchronized PatternSet.NameEntry createExclude() {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ ds = null;
+ return defaultPatterns.createExclude();
+ }
+
+ /**
+ * Add a name entry to the excludes files list.
+ * @return <code>PatternSet.NameEntry</code>.
+ */
+ public synchronized PatternSet.NameEntry createExcludesFile() {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ ds = null;
+ return defaultPatterns.createExcludesFile();
+ }
+
+ /**
+ * Append <code>includes</code> to the current list of include
+ * patterns.
+ *
+ * <p>Patterns may be separated by a comma or a space.</p>
+ *
+ * @param includes the <code>String</code> containing the include patterns.
+ */
+ public synchronized void setIncludes(String includes) {
+ checkAttributesAllowed();
+ defaultPatterns.setIncludes(includes);
+ ds = null;
+ }
+
+ /**
+ * Append <code>includes</code> to the current list of include
+ * patterns.
+ *
+ * @param includes array containing the include patterns.
+ */
+ public synchronized void appendIncludes(String[] includes) {
+ checkAttributesAllowed();
+ if (includes != null) {
+ for (int i = 0; i < includes.length; i++) {
+ defaultPatterns.createInclude().setName(includes[i]);
+ }
+ ds = null;
+ }
+ }
+
+ /**
+ * Append <code>excludes</code> to the current list of exclude
+ * patterns.
+ *
+ * <p>Patterns may be separated by a comma or a space.</p>
+ *
+ * @param excludes the <code>String</code> containing the exclude patterns.
+ */
+ public synchronized void setExcludes(String excludes) {
+ checkAttributesAllowed();
+ defaultPatterns.setExcludes(excludes);
+ ds = null;
+ }
+
+ /**
+ * Append <code>excludes</code> to the current list of include
+ * patterns.
+ *
+ * @param excludes array containing the exclude patterns.
+ */
+ public synchronized void appendExcludes(String[] excludes) {
+ checkAttributesAllowed();
+ if (excludes != null) {
+ for (int i = 0; i < excludes.length; i++) {
+ defaultPatterns.createExclude().setName(excludes[i]);
+ }
+ ds = null;
+ }
+ }
+
+ /**
+ * Set the <code>File</code> containing the includes patterns.
+ *
+ * @param incl <code>File</code> instance.
+ * @throws BuildException if there is a problem.
+ */
+ public synchronized void setIncludesfile(File incl) throws BuildException {
+ checkAttributesAllowed();
+ defaultPatterns.setIncludesfile(incl);
+ ds = null;
+ }
+
+ /**
+ * Set the <code>File</code> containing the excludes patterns.
+ *
+ * @param excl <code>File</code> instance.
+ * @throws BuildException if there is a problem.
+ */
+ public synchronized void setExcludesfile(File excl) throws BuildException {
+ checkAttributesAllowed();
+ defaultPatterns.setExcludesfile(excl);
+ ds = null;
+ }
+
+ /**
+ * Set whether default exclusions should be used or not.
+ *
+ * @param useDefaultExcludes <code>boolean</code>.
+ */
+ public synchronized void setDefaultexcludes(boolean useDefaultExcludes) {
+ checkAttributesAllowed();
+ this.useDefaultExcludes = useDefaultExcludes;
+ ds = null;
+ }
+
+ /**
+ * Get whether default exclusions should be used or not.
+ * @return the defaultexclusions value.
+ */
+ public synchronized boolean getDefaultexcludes() {
+ return (isReference())
+ ? getRef().getDefaultexcludes() : useDefaultExcludes;
+ }
+
+ /**
+ * Set case-sensitivity of the Files collection.
+ *
+ * @param caseSensitive <code>boolean</code>.
+ */
+ public synchronized void setCaseSensitive(boolean caseSensitive) {
+ checkAttributesAllowed();
+ this.caseSensitive = caseSensitive;
+ ds = null;
+ }
+
+ /**
+ * Find out if this Files collection is case-sensitive.
+ *
+ * @return <code>boolean</code> indicating whether the Files
+ * collection is case-sensitive.
+ */
+ public synchronized boolean isCaseSensitive() {
+ return (isReference())
+ ? getRef().isCaseSensitive() : caseSensitive;
+ }
+
+ /**
+ * Set whether or not symbolic links should be followed.
+ *
+ * @param followSymlinks whether or not symbolic links should be followed.
+ */
+ public synchronized void setFollowSymlinks(boolean followSymlinks) {
+ checkAttributesAllowed();
+ this.followSymlinks = followSymlinks;
+ ds = null;
+ }
+
+ /**
+ * Find out whether symbolic links should be followed.
+ *
+ * @return <code>boolean</code> indicating whether symbolic links
+ * should be followed.
+ */
+ public synchronized boolean isFollowSymlinks() {
+ return (isReference())
+ ? getRef().isFollowSymlinks() : followSymlinks;
+ }
+
+ /**
+ * Fulfill the ResourceCollection contract.
+ * @return an Iterator of Resources.
+ */
+ public synchronized Iterator<Resource> iterator() {
+ if (isReference()) {
+ return getRef().iterator();
+ }
+ ensureDirectoryScannerSetup();
+ ds.scan();
+ int fct = ds.getIncludedFilesCount();
+ int dct = ds.getIncludedDirsCount();
+ if (fct + dct == 0) {
+ return EMPTY_ITERATOR;
+ }
+ FileResourceIterator result = new FileResourceIterator(getProject());
+ if (fct > 0) {
+ result.addFiles(ds.getIncludedFiles());
+ }
+ if (dct > 0) {
+ result.addFiles(ds.getIncludedDirectories());
+ }
+ return result;
+ }
+
+ /**
+ * Fulfill the ResourceCollection contract.
+ * @return number of elements as int.
+ */
+ public synchronized int size() {
+ if (isReference()) {
+ return getRef().size();
+ }
+ ensureDirectoryScannerSetup();
+ ds.scan();
+ return ds.getIncludedFilesCount() + ds.getIncludedDirsCount();
+ }
+
+ /**
+ * Find out whether this Files collection has patterns.
+ *
+ * @return whether any patterns are in this container.
+ */
+ public synchronized boolean hasPatterns() {
+ if (isReference()) {
+ return getRef().hasPatterns();
+ }
+ dieOnCircularReference();
+ if (hasPatterns(defaultPatterns)) {
+ return true;
+ }
+ for (PatternSet patternSet : additionalPatterns) {
+ if (hasPatterns(patternSet)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Add a new selector into this container.
+ *
+ * @param selector the new <code>FileSelector</code> to add.
+ */
+ public synchronized void appendSelector(FileSelector selector) {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ super.appendSelector(selector);
+ ds = null;
+ }
+
+ /**
+ * Format this Files collection as a String.
+ * @return a descriptive <code>String</code>.
+ */
+ public String toString() {
+ if (isReference()) {
+ return getRef().toString();
+ }
+ Iterator<Resource> i = iterator();
+ if (!i.hasNext()) {
+ return "";
+ }
+ StringBuffer sb = new StringBuffer();
+ while (i.hasNext()) {
+ if (sb.length() > 0) {
+ sb.append(File.pathSeparatorChar);
+ }
+ sb.append(i.next());
+ }
+ return sb.toString();
+ }
+
+ /**
+ * Create a deep clone of this instance, except for the nested selectors
+ * (the list of selectors is a shallow clone of this instance's list).
+ * @return a cloned Object.
+ */
+ public synchronized Object clone() {
+ if (isReference()) {
+ return getRef().clone();
+ }
+ Files f = (Files) super.clone();
+ f.defaultPatterns = (PatternSet) defaultPatterns.clone();
+ f.additionalPatterns = new Vector<PatternSet>(additionalPatterns.size());
+ for (PatternSet ps : additionalPatterns) {
+ f.additionalPatterns.add((PatternSet) ps.clone());
+ }
+ return f;
+ }
+
+ /**
+ * Get the merged include patterns for this Files collection.
+ * @param p Project instance.
+ * @return the include patterns of the default pattern set and all
+ * nested patternsets.
+ */
+ public String[] mergeIncludes(Project p) {
+ return mergePatterns(p).getIncludePatterns(p);
+ }
+
+ /**
+ * Get the merged exclude patterns for this Files collection.
+ * @param p Project instance.
+ * @return the exclude patterns of the default pattern set and all
+ * nested patternsets.
+ */
+ public String[] mergeExcludes(Project p) {
+ return mergePatterns(p).getExcludePatterns(p);
+ }
+
+ /**
+ * Get the merged patterns for this Files collection.
+ * @param p Project instance.
+ * @return the default patternset merged with the additional sets
+ * in a new PatternSet instance.
+ */
+ public synchronized PatternSet mergePatterns(Project p) {
+ if (isReference()) {
+ return getRef().mergePatterns(p);
+ }
+ dieOnCircularReference();
+ PatternSet ps = new PatternSet();
+ ps.append(defaultPatterns, p);
+ final int count = additionalPatterns.size();
+ for (int i = 0; i < count; i++) {
+ Object o = additionalPatterns.elementAt(i);
+ ps.append((PatternSet) o, p);
+ }
+ return ps;
+ }
+
+ /**
+ * Always returns true.
+ * @return true indicating that all elements of a Files collection
+ * will be FileResources.
+ */
+ public boolean isFilesystemOnly() {
+ return true;
+ }
+
+ /**
+ * Perform the check for circular references and return the
+ * referenced Files collection.
+ * @return <code>FileCollection</code>.
+ */
+ protected Files getRef() {
+ return (Files) getCheckedRef();
+ }
+
+ private synchronized void ensureDirectoryScannerSetup() {
+ dieOnCircularReference();
+ if (ds == null) {
+ ds = new DirectoryScanner();
+ PatternSet ps = mergePatterns(getProject());
+ ds.setIncludes(ps.getIncludePatterns(getProject()));
+ ds.setExcludes(ps.getExcludePatterns(getProject()));
+ ds.setSelectors(getSelectors(getProject()));
+ if (useDefaultExcludes) {
+ ds.addDefaultExcludes();
+ }
+ ds.setCaseSensitive(caseSensitive);
+ ds.setFollowSymlinks(followSymlinks);
+ }
+ }
+
+ private boolean hasPatterns(PatternSet ps) {
+ String[] includePatterns = ps.getIncludePatterns(getProject());
+ String[] excludePatterns = ps.getExcludePatterns(getProject());
+ return (includePatterns != null && includePatterns.length > 0)
+ || (includePatterns != null && excludePatterns.length > 0);
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/First.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/First.java
new file mode 100644
index 00000000..ea9e7d0a
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/First.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.resources;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.tools.ant.types.Resource;
+
+/**
+ * ResourceCollection that contains the first <code>count</code> elements of
+ * another ResourceCollection, a la the UNIX head command.
+ * @since Ant 1.7
+ */
+public class First extends SizeLimitCollection {
+
+ /**
+ * Take the first <code>count</code> elements.
+ * @return a Collection of Resources.
+ */
+ protected Collection<Resource> getCollection() {
+ int ct = getValidCount();
+ Iterator<Resource> iter = getResourceCollection().iterator();
+ List<Resource> al = new ArrayList<Resource>(ct);
+ for (int i = 0; i < ct && iter.hasNext(); i++) {
+ al.add(iter.next());
+ }
+ return al;
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/GZipResource.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/GZipResource.java
new file mode 100644
index 00000000..3f95a698
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/GZipResource.java
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.resources;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.zip.GZIPInputStream;
+import java.util.zip.GZIPOutputStream;
+
+/**
+ * A GZip compressed resource.
+ *
+ * <p>Wraps around another resource, delegates all queries to that
+ * other resource but uncompresses/compresses streams on the fly.</p>
+ *
+ * @since Ant 1.7
+ */
+public class GZipResource extends CompressedResource {
+
+ /** A no-arg constructor */
+ public GZipResource() {
+ }
+
+ /**
+ * Constructor with another resource to wrap.
+ * @param other the resource to wrap.
+ */
+ public GZipResource(org.apache.tools.ant.types.ResourceCollection other) {
+ super(other);
+ }
+
+ /**
+ * Decompress on the fly using java.util.zip.GZIPInputStream.
+ * @param in the stream to wrap.
+ * @return the wrapped stream.
+ * @throws IOException if there is a problem.
+ */
+ protected InputStream wrapStream(InputStream in) throws IOException {
+ return new GZIPInputStream(in);
+ }
+
+ /**
+ * Compress on the fly using java.util.zip.GZIPOutStream.
+ * @param out the stream to wrap.
+ * @return the wrapped stream.
+ * @throws IOException if there is a problem.
+ */
+ protected OutputStream wrapStream(OutputStream out) throws IOException {
+ return new GZIPOutputStream(out);
+ }
+
+ /**
+ * Get the name of the compression method.
+ * @return the string "GZip".
+ */
+ protected String getCompressionName() {
+ return "GZip";
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/ImmutableResourceException.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/ImmutableResourceException.java
new file mode 100644
index 00000000..9dce7154
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/ImmutableResourceException.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types.resources;
+
+import java.io.IOException;
+
+/**
+ * Exception thrown when an attempt is made to get an OutputStream
+ * from an immutable Resource.
+ * @since Ant 1.7
+ */
+public class ImmutableResourceException extends IOException {
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Default constructor.
+ */
+ public ImmutableResourceException() {
+ super();
+ }
+
+ /**
+ * Construct a new ImmutableResourceException with the specified message.
+ * @param s the message String.
+ */
+ public ImmutableResourceException(String s) {
+ super(s);
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/Intersect.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/Intersect.java
new file mode 100644
index 00000000..cdbeed0f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/Intersect.java
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.resources;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.ResourceCollection;
+
+/**
+ * ResourceCollection representing the intersection
+ * of multiple nested ResourceCollections.
+ * @since Ant 1.7
+ */
+public class Intersect extends BaseResourceCollectionContainer {
+
+ /**
+ * Calculate the intersection of the nested ResourceCollections.
+ * @return a Collection of Resources.
+ */
+ protected Collection<Resource> getCollection() {
+ List<ResourceCollection> rcs = getResourceCollections();
+ int size = rcs.size();
+ if (size < 2) {
+ throw new BuildException("The intersection of " + size
+ + " resource collection" + ((size == 1) ? "" : "s")
+ + " is undefined.");
+ }
+ Iterator<ResourceCollection> rc = rcs.iterator();
+ Set<Resource> s = new LinkedHashSet<Resource>(collect(rc.next()));
+ while (rc.hasNext()) {
+ s.retainAll(collect(rc.next()));
+ }
+ return s;
+ }
+
+ private Set<Resource> collect(ResourceCollection rc) {
+ Set<Resource> result = new LinkedHashSet<Resource>();
+ for (Resource r : rc) {
+ result.add(r);
+ }
+ return result;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/JavaConstantResource.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/JavaConstantResource.java
new file mode 100644
index 00000000..e8c8f02c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/JavaConstantResource.java
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.resources;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.Field;
+
+/**
+ * A resource that is a java constant.
+ * This lets you extract values off the classpath and use them elsewhere
+ * @since Ant 1.7
+ */
+public class JavaConstantResource extends AbstractClasspathResource {
+
+ /**
+ * open the input stream from a specific classloader
+ *
+ * @param cl the classloader to use. Will be null if the system classloader is used
+ * @return an open input stream for the resource
+ * @throws IOException if an error occurs.
+ */
+ protected InputStream openInputStream(ClassLoader cl) throws IOException {
+ String constant = getName();
+ if (constant == null) {
+ throw new IOException("Attribute 'name' must be set.");
+ }
+ int index = constant.lastIndexOf('.');
+ if (index < 0) {
+ throw new IOException("No class name in " + constant);
+ }
+ String classname = constant.substring(0, index);
+ String fieldname = constant.substring(index + 1, constant.length());
+ try {
+ Class<?> clazz =
+ cl != null
+ ? Class.forName(classname, true, cl)
+ : Class.forName(classname);
+ Field field = clazz.getField(fieldname);
+ String value = field.get(null).toString();
+ return new ByteArrayInputStream(value.getBytes("UTF-8"));
+ } catch (ClassNotFoundException e) {
+ throw new IOException("Class not found:" + classname);
+ } catch (NoSuchFieldException e) {
+ throw new IOException(
+ "Field not found:" + fieldname + " in " + classname);
+ } catch (IllegalAccessException e) {
+ throw new IOException("Illegal access to :" + fieldname + " in " + classname);
+ } catch (NullPointerException npe) {
+ throw new IOException("Not a static field: " + fieldname + " in " + classname);
+ }
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/JavaResource.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/JavaResource.java
new file mode 100644
index 00000000..a927d3fb
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/JavaResource.java
@@ -0,0 +1,141 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.resources;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.types.Resource;
+
+/**
+ * A Resource representation of something loadable via a Java classloader.
+ * @since Ant 1.7
+ */
+public class JavaResource extends AbstractClasspathResource
+ implements URLProvider {
+
+ /**
+ * Default constructor.
+ */
+ public JavaResource() {
+ }
+
+ /**
+ * Construct a new JavaResource using the specified name and
+ * classpath.
+ *
+ * @param name the resource name.
+ * @param path the classpath.
+ */
+ public JavaResource(String name, Path path) {
+ setName(name);
+ setClasspath(path);
+ }
+
+ /**
+ * open the input stream from a specific classloader
+ * @param cl the classloader to use. Will be null if the system
+ * classloader is used
+ * @return an open input stream for the resource
+ * @throws IOException if an error occurs.
+ */
+ protected InputStream openInputStream(ClassLoader cl) throws IOException {
+ InputStream inputStream;
+ if (cl == null) {
+ inputStream = ClassLoader.getSystemResourceAsStream(getName());
+ if (inputStream == null) {
+ throw new FileNotFoundException("No resource " + getName()
+ + " on Ant's classpath");
+ }
+ } else {
+ inputStream = cl.getResourceAsStream(getName());
+ if (inputStream == null) {
+ throw new FileNotFoundException("No resource " + getName()
+ + " on the classpath " + cl);
+ }
+ }
+ return inputStream;
+ }
+
+ /**
+ * Get the URL represented by this Resource.
+ * @since Ant 1.8.0
+ */
+ public URL getURL() {
+ if (isReference()) {
+ return ((JavaResource) getCheckedRef()).getURL();
+ }
+ AbstractClasspathResource.ClassLoaderWithFlag classLoader =
+ getClassLoader();
+ if (classLoader.getLoader() == null) {
+ return ClassLoader.getSystemResource(getName());
+ } else {
+ try {
+ return classLoader.getLoader().getResource(getName());
+ } finally {
+ classLoader.cleanup();
+ }
+ }
+ }
+
+ /**
+ * Compare this JavaResource to another Resource.
+ * @param another the other Resource against which to compare.
+ * @return a negative integer, zero, or a positive integer as this
+ * JavaResource is less than, equal to, or greater than the
+ * specified Resource.
+ */
+ public int compareTo(Resource another) {
+ if (isReference()) {
+ return ((Resource) getCheckedRef()).compareTo(another);
+ }
+ if (another.getClass().equals(getClass())) {
+ JavaResource otherjr = (JavaResource) another;
+ if (!getName().equals(otherjr.getName())) {
+ return getName().compareTo(otherjr.getName());
+ }
+ if (getLoader() != otherjr.getLoader()) {
+ if (getLoader() == null) {
+ return -1;
+ }
+ if (otherjr.getLoader() == null) {
+ return 1;
+ }
+ return getLoader().getRefId()
+ .compareTo(otherjr.getLoader().getRefId());
+ }
+ Path p = getClasspath();
+ Path op = otherjr.getClasspath();
+ if (p != op) {
+ if (p == null) {
+ return -1;
+ }
+ if (op == null) {
+ return 1;
+ }
+ return p.toString().compareTo(op.toString());
+ }
+ return 0;
+ }
+ return super.compareTo(another);
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/Last.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/Last.java
new file mode 100644
index 00000000..312271b2
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/Last.java
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.resources;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.ResourceCollection;
+
+/**
+ * ResourceCollection that contains the last <code>count</code> elements of
+ * another ResourceCollection, a la the UNIX tail command.
+ * @since Ant 1.7.1
+ */
+public class Last extends SizeLimitCollection {
+
+ /**
+ * Take the last <code>count</code> elements.
+ * @return a Collection of Resources.
+ */
+ protected Collection<Resource> getCollection() {
+ int count = getValidCount();
+ ResourceCollection rc = getResourceCollection();
+ int i = count;
+ Iterator<Resource> iter = rc.iterator();
+ int size = rc.size();
+ for (; i < size; i++) {
+ iter.next();
+ }
+
+ List<Resource> al = new ArrayList<Resource>(count);
+ for (; iter.hasNext(); i++) {
+ al.add(iter.next());
+ }
+ int found = al.size();
+ if (found == count || (size < count && found == size)) {
+ return al;
+ }
+
+ //mismatch:
+ String msg = "Resource collection " + rc + " reports size " + size
+ + " but returns " + i + " elements.";
+
+ //size was understated -> too many results; warn and continue:
+ if (found > count) {
+ log(msg, Project.MSG_WARN);
+ return al.subList(found - count, found);
+ }
+ //size was overstated; we missed some and are now in error-land:
+ throw new BuildException(msg);
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/LazyResourceCollectionWrapper.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/LazyResourceCollectionWrapper.java
new file mode 100644
index 00000000..4f9acd32
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/LazyResourceCollectionWrapper.java
@@ -0,0 +1,176 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.resources;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+
+import org.apache.tools.ant.types.Resource;
+
+/**
+ * Resource collection which load underlying resource collection only on demand
+ * with support for caching
+ */
+public class LazyResourceCollectionWrapper extends
+ AbstractResourceCollectionWrapper {
+
+ /** List of cached resources */
+ private final List<Resource> cachedResources = new ArrayList<Resource>();
+
+ private FilteringIterator filteringIterator;
+
+ @Override
+ protected Iterator<Resource> createIterator() {
+ Iterator<Resource> iterator;
+ if (isCache()) {
+ if (filteringIterator == null) {
+ // no worry of thread safety here, see function's contract
+ filteringIterator = new FilteringIterator(
+ getResourceCollection().iterator());
+ }
+ iterator = new CachedIterator(filteringIterator);
+ } else {
+ iterator = new FilteringIterator(getResourceCollection().iterator());
+ }
+ return iterator;
+ }
+
+ @Override
+ protected int getSize() {
+ // to compute the size, just iterate: the iterator will take care of
+ // caching
+ final Iterator<Resource> it = createIterator();
+ int size = 0;
+ while (it.hasNext()) {
+ it.next();
+ size++;
+ }
+ return size;
+ }
+
+ /**
+ * Specify if the resource should be filtered or not. This function should
+ * be overrided in order to define the filtering algorithm
+ *
+ * @param r resource considered for filtration
+ * @return whether the resource should be filtered or not
+ */
+ protected boolean filterResource(final Resource r) {
+ return false;
+ }
+
+ private class FilteringIterator implements Iterator<Resource> {
+
+ Resource next = null;
+
+ boolean ended = false;
+
+ protected final Iterator<Resource> it;
+
+ public FilteringIterator(final Iterator<Resource> it) {
+ this.it = it;
+ }
+
+ public boolean hasNext() {
+ if (ended) {
+ return false;
+ }
+ while (next == null) {
+ if (!it.hasNext()) {
+ ended = true;
+ return false;
+ }
+ next = it.next();
+ if (filterResource(next)) {
+ next = null;
+ }
+ }
+ return true;
+ }
+
+ public Resource next() {
+ if (!hasNext()) {
+ throw new UnsupportedOperationException();
+ }
+ final Resource r = next;
+ next = null;
+ return r;
+ }
+
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ /**
+ * Iterator that will put in the shared cache array list the selected
+ * resources
+ */
+ private class CachedIterator implements Iterator<Resource> {
+
+ int cusrsor = 0;
+
+ private final Iterator<Resource> it;
+
+ /**
+ * Default constructor
+ *
+ * @param it
+ * the iterator which will provide the resources to put in
+ * cache
+ */
+ public CachedIterator(final Iterator<Resource> it) {
+ this.it = it;
+ }
+
+ public boolean hasNext() {
+ synchronized (cachedResources) {
+ // have we already cached the next entry ?
+ if (cachedResources.size() > cusrsor) {
+ return true;
+ }
+ // does the wrapped iterator any more resource ?
+ if (!it.hasNext()) {
+ return false;
+ }
+ // put in cache the next resource
+ final Resource r = it.next();
+ cachedResources.add(r);
+ }
+ return true;
+ }
+
+ public Resource next() {
+ // first check that we have some to deliver
+ if (!hasNext()) {
+ throw new NoSuchElementException();
+ }
+ synchronized (cachedResources) {
+ // return the cached entry as hasNext should have put one for
+ // this iterator
+ return cachedResources.get(cusrsor++);
+ }
+ }
+
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/LogOutputResource.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/LogOutputResource.java
new file mode 100644
index 00000000..cd19c9c7
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/LogOutputResource.java
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.resources;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import org.apache.tools.ant.ProjectComponent;
+import org.apache.tools.ant.taskdefs.LogOutputStream;
+import org.apache.tools.ant.types.Resource;
+
+/**
+ * Output-only Resource that always appends to Ant's log.
+ * @since Ant 1.8
+ */
+public class LogOutputResource extends Resource implements Appendable {
+ private static final String NAME = "[Ant log]";
+
+ private LogOutputStream outputStream;
+
+ /**
+ * Create a new LogOutputResource.
+ * @param managingComponent
+ */
+ public LogOutputResource(ProjectComponent managingComponent) {
+ super(NAME);
+ outputStream = new LogOutputStream(managingComponent);
+ }
+
+ /**
+ * Create a new LogOutputResource.
+ * @param managingComponent owning log content
+ * @param level log level
+ */
+ public LogOutputResource(ProjectComponent managingComponent, int level) {
+ super(NAME);
+ outputStream = new LogOutputStream(managingComponent, level);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public OutputStream getAppendOutputStream() throws IOException {
+ return outputStream;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public OutputStream getOutputStream() throws IOException {
+ return outputStream;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/MappedResource.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/MappedResource.java
new file mode 100644
index 00000000..339c88bf
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/MappedResource.java
@@ -0,0 +1,116 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.resources;
+
+import org.apache.tools.ant.types.Reference;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.util.FileNameMapper;
+
+/**
+ * A decorator around a different resource that uses a mapper to
+ * dynamically remap the resource's name.
+ *
+ * <p>Strips the FileProvider interface from decorated resources since
+ * it may be used to circumvent name mapping.</p>
+ *
+ * @since Ant 1.8.0
+ */
+public class MappedResource extends ResourceDecorator {
+ private final FileNameMapper mapper;
+
+ /**
+ * Wraps an existing resource.
+ * @param r Resource to wrap
+ * @param m FileNameMapper that handles mapping
+ */
+ public MappedResource(Resource r, FileNameMapper m) {
+ super(r);
+ mapper = m;
+ }
+
+ /**
+ * Maps the name.
+ */
+ @Override
+ public String getName() {
+ String name = getResource().getName();
+ if (isReference()) {
+ return name;
+ }
+ String[] mapped = mapper.mapFileName(name);
+ return mapped != null && mapped.length > 0 ? mapped[0] : null;
+ }
+
+ /**
+ * Not really supported since mapper is never null.
+ * @param r reference to set
+ */
+ @Override
+ public void setRefid(Reference r) {
+ if (mapper != null) {
+ throw noChildrenAllowed();
+ }
+ super.setRefid(r);
+ }
+
+ /**
+ * Suppress FileProvider
+ * @param clazz the type to implement
+ */
+ @Override
+ public <T> T as(Class<T> clazz) {
+ return FileProvider.class.isAssignableFrom(clazz)
+ ? null : getResource().as(clazz);
+ }
+
+ /**
+ * Get the hash code for this Resource.
+ * @since Ant 1.8.1
+ */
+ @Override
+ public int hashCode() {
+ String n = getName();
+ return n == null ? super.hashCode() : n.hashCode();
+ }
+
+ /**
+ * Equality check based on the resource's name in addition to the
+ * resource itself.
+ * @since Ant 1.8.1
+ */
+ @Override
+ public boolean equals(Object other) {
+ if (other == null || !other.getClass().equals(getClass())) {
+ return false;
+ }
+ MappedResource m = (MappedResource) other;
+ String myName = getName();
+ String otherName = m.getName();
+ return (myName == null ? otherName == null : myName.equals(otherName))
+ && getResource().equals(m.getResource());
+ }
+
+ @Override
+ public String toString() {
+ if (isReference()) {
+ return getCheckedRef().toString();
+ }
+ return getName();
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/MappedResourceCollection.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/MappedResourceCollection.java
new file mode 100644
index 00000000..2f1a926b
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/MappedResourceCollection.java
@@ -0,0 +1,267 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.resources;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Stack;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.DataType;
+import org.apache.tools.ant.types.Mapper;
+import org.apache.tools.ant.types.Reference;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.ResourceCollection;
+import org.apache.tools.ant.util.FileNameMapper;
+import org.apache.tools.ant.util.IdentityMapper;
+import org.apache.tools.ant.util.MergingMapper;
+
+/**
+ * Wrapper around a resource collections that maps the names of the
+ * other collection using a configured mapper.
+ * @since Ant 1.8.0
+ */
+public class MappedResourceCollection
+ extends DataType implements ResourceCollection, Cloneable {
+
+ private ResourceCollection nested = null;
+ private Mapper mapper = null;
+ private boolean enableMultipleMappings = false;
+ private boolean cache = false;
+ private Collection<Resource> cachedColl = null;
+
+ /**
+ * Adds the required nested ResourceCollection.
+ * @param c the ResourceCollection to add.
+ * @throws BuildException on error.
+ */
+ public synchronized void add(ResourceCollection c) throws BuildException {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ if (nested != null) {
+ throw new BuildException("Only one resource collection can be"
+ + " nested into mappedresources",
+ getLocation());
+ }
+ setChecked(false);
+ cachedColl = null;
+ nested = c;
+ }
+
+ /**
+ * Define the mapper to map source to destination files.
+ * @return a mapper to be configured.
+ * @exception BuildException if more than one mapper is defined.
+ */
+ public Mapper createMapper() throws BuildException {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ if (mapper != null) {
+ throw new BuildException("Cannot define more than one mapper",
+ getLocation());
+ }
+ setChecked(false);
+ mapper = new Mapper(getProject());
+ cachedColl = null;
+ return mapper;
+ }
+
+ /**
+ * Add a nested filenamemapper.
+ * @param fileNameMapper the mapper to add.
+ * @since Ant 1.6.3
+ */
+ public void add(FileNameMapper fileNameMapper) {
+ createMapper().add(fileNameMapper);
+ }
+
+ /**
+ * Set method of handling mappers that return multiple
+ * mappings for a given source path.
+ * @param enableMultipleMappings If true the type will
+ * use all the mappings for a given source path, if
+ * false, only the first mapped name is
+ * processed.
+ * By default, this setting is false to provide backward
+ * compatibility with earlier releases.
+ * @since Ant 1.8.1
+ */
+ public void setEnableMultipleMappings(boolean enableMultipleMappings) {
+ this.enableMultipleMappings = enableMultipleMappings;
+ }
+
+ /**
+ * Set whether to cache collections.
+ * @since Ant 1.8.1
+ */
+ public void setCache(boolean cache) {
+ this.cache = cache;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isFilesystemOnly() {
+ if (isReference()) {
+ return ((MappedResourceCollection) getCheckedRef())
+ .isFilesystemOnly();
+ }
+ checkInitialized();
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public int size() {
+ if (isReference()) {
+ return ((MappedResourceCollection) getCheckedRef()).size();
+ }
+ checkInitialized();
+ return cacheCollection().size();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Iterator<Resource> iterator() {
+ if (isReference()) {
+ return ((MappedResourceCollection) getCheckedRef()).iterator();
+ }
+ checkInitialized();
+ return cacheCollection().iterator();
+ }
+
+ /**
+ * Overrides the base version.
+ * @param r the Reference to set.
+ */
+ public void setRefid(Reference r) {
+ if (nested != null || mapper != null) {
+ throw tooManyAttributes();
+ }
+ super.setRefid(r);
+ }
+
+ /**
+ * Implement clone. The nested resource collection and mapper are copied.
+ * @return a cloned instance.
+ */
+ public Object clone() {
+ try {
+ MappedResourceCollection c =
+ (MappedResourceCollection) super.clone();
+ c.nested = nested;
+ c.mapper = mapper;
+ c.cachedColl = null;
+ return c;
+ } catch (CloneNotSupportedException e) {
+ throw new BuildException(e);
+ }
+ }
+
+ /**
+ * Overrides the version of DataType to recurse on all DataType
+ * child elements that may have been added.
+ * @param stk the stack of data types to use (recursively).
+ * @param p the project to use to dereference the references.
+ * @throws BuildException on error.
+ */
+ protected synchronized void dieOnCircularReference(Stack<Object> stk, Project p)
+ throws BuildException {
+ if (isChecked()) {
+ return;
+ }
+ if (isReference()) {
+ super.dieOnCircularReference(stk, p);
+ } else {
+ checkInitialized();
+ if (mapper != null) {
+ pushAndInvokeCircularReferenceCheck(mapper, stk, p);
+ }
+ if (nested instanceof DataType) {
+ pushAndInvokeCircularReferenceCheck((DataType) nested, stk, p);
+ }
+ setChecked(true);
+ }
+ }
+
+ private void checkInitialized() {
+ if (nested == null) {
+ throw new BuildException("A nested resource collection element is"
+ + " required", getLocation());
+ }
+ dieOnCircularReference();
+ }
+
+ private synchronized Collection<Resource> cacheCollection() {
+ if (cachedColl == null || !cache) {
+ cachedColl = getCollection();
+ }
+ return cachedColl;
+ }
+
+ private Collection<Resource> getCollection() {
+ Collection<Resource> collected = new ArrayList<Resource>();
+ FileNameMapper m =
+ mapper != null ? mapper.getImplementation() : new IdentityMapper();
+ for (Resource r : nested) {
+ if (enableMultipleMappings) {
+ String[] n = m.mapFileName(r.getName());
+ if (n != null) {
+ for (int i = 0; i < n.length; i++) {
+ collected.add(new MappedResource(r,
+ new MergingMapper(n[i]))
+ );
+ }
+ }
+ } else {
+ collected.add(new MappedResource(r, m));
+ }
+ }
+ return collected;
+ }
+
+ /**
+ * Format this resource collection as a String.
+ * @return a descriptive <code>String</code>.
+ */
+ public String toString() {
+ if (isReference()) {
+ return getCheckedRef().toString();
+ }
+ Iterator<Resource> i = iterator();
+ if (!i.hasNext()) {
+ return "";
+ }
+ StringBuffer sb = new StringBuffer();
+ while (i.hasNext()) {
+ if (sb.length() > 0) {
+ sb.append(File.pathSeparatorChar);
+ }
+ sb.append(i.next());
+ }
+ return sb.toString();
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/MultiRootFileSet.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/MultiRootFileSet.java
new file mode 100644
index 00000000..d7938908
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/MultiRootFileSet.java
@@ -0,0 +1,237 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types.resources;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.DirectoryScanner;
+import org.apache.tools.ant.types.AbstractFileSet;
+import org.apache.tools.ant.types.Reference;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.ResourceCollection;
+
+/**
+ * Union of file/dirsets that share the same patterns and selectors
+ * but have different roots.
+ * @since Ant 1.9.4
+ */
+public class MultiRootFileSet extends AbstractFileSet
+ implements ResourceCollection {
+
+ private SetType type = SetType.file;
+ private boolean cache = true;
+ private List<File> baseDirs = new ArrayList<File>();
+ private Union union;
+
+ @Override
+ public void setDir(final File dir) {
+ throw new BuildException(getDataTypeName()
+ + " doesn't support the dir attribute");
+ }
+
+ /**
+ * Determines the types of resources to return.
+ * @param type the types of resources to return
+ */
+ public void setType(final SetType type) {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ this.type = type;
+ }
+
+ /**
+ * Set whether to cache collections.
+ * @param b boolean cache flag.
+ */
+ public synchronized void setCache(final boolean b) {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ cache = b;
+ }
+
+ /**
+ * Adds basedirs as a comma separated list.
+ * @param dirs directories as CSV
+ */
+ public void setBaseDirs(final String dirs) {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ if (dirs != null && dirs.length() > 0) {
+ final String[] ds = dirs.split(",");
+ for (final String d : ds) {
+ baseDirs.add(getProject().resolveFile(d));
+ }
+ }
+ }
+
+ /**
+ * Adds a basedir as nested element.
+ * @param r basedir
+ */
+ public void addConfiguredBaseDir(final FileResource r) {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ baseDirs.add(r.getFile());
+ }
+
+ @Override
+ public void setRefid(final Reference r) {
+ if (!baseDirs.isEmpty()) {
+ throw tooManyAttributes();
+ }
+ super.setRefid(r);
+ }
+
+ /**
+ * Return a MultiRootFileSet that has the same basedirs and same patternsets
+ * as this one.
+ * @return the cloned MultiRootFileSet.
+ */
+ @Override
+ public Object clone() {
+ if (isReference()) {
+ return ((MultiRootFileSet) getRef(getProject())).clone();
+ } else {
+ final MultiRootFileSet fs = (MultiRootFileSet) super.clone();
+ fs.baseDirs = new ArrayList<File>(baseDirs);
+ fs.union = null;
+ return fs;
+ }
+ }
+
+ /**
+ * Fulfill the ResourceCollection contract.
+ * @return an Iterator of Resources.
+ */
+ public Iterator<Resource> iterator() {
+ if (isReference()) {
+ return ((MultiRootFileSet) getRef(getProject())).iterator();
+ }
+ return merge().iterator();
+ }
+
+ /**
+ * Fulfill the ResourceCollection contract.
+ * @return number of elements as int.
+ */
+ public int size() {
+ if (isReference()) {
+ return ((MultiRootFileSet) getRef(getProject())).size();
+ }
+ return merge().size();
+ }
+
+ /**
+ * Always returns true.
+ * @return true indicating that all elements will be FileResources.
+ */
+ public boolean isFilesystemOnly() {
+ return true;
+ }
+
+ /**
+ * Returns included directories as a list of semicolon-separated paths.
+ *
+ * @return a <code>String</code> of included directories.
+ */
+ @Override
+ public String toString() {
+ if (isReference()) {
+ return ((MultiRootFileSet) getRef(getProject())).toString();
+ }
+ return merge().toString();
+ }
+
+ private synchronized Union merge() {
+ if (cache && union != null) {
+ return union;
+ }
+ final Union u = new Union();
+ setup(u);
+ if (cache) {
+ union = u;
+ }
+ return u;
+ }
+
+ private void setup(final Union u) {
+ for (final File d : baseDirs) {
+ u.add(new Worker(this, type, d));
+ }
+ }
+
+ /**
+ * What to return from the set: files, directories or both.
+ */
+ public static enum SetType {
+ file, dir, both
+ }
+
+ private static class Worker extends AbstractFileSet
+ implements ResourceCollection {
+
+ private final SetType type;
+
+ private Worker(final MultiRootFileSet fs, final SetType type, final File dir) {
+ super(fs);
+ this.type = type;
+ setDir(dir);
+ }
+
+ public boolean isFilesystemOnly() {
+ return true;
+ }
+
+ public Iterator<Resource> iterator() {
+ final DirectoryScanner ds = getDirectoryScanner(getProject());
+ String[] names = type == SetType.file
+ ? ds.getIncludedFiles()
+ : ds.getIncludedDirectories();
+ if (type == SetType.both) {
+ final String[] files = ds.getIncludedFiles();
+ final String[] merged = new String[names.length + files.length];
+ System.arraycopy(names, 0, merged, 0, names.length);
+ System.arraycopy(files, 0, merged, names.length, files.length);
+ names = merged;
+ }
+ return new FileResourceIterator(getProject(), getDir(getProject()),
+ names);
+ }
+
+ public int size() {
+ final DirectoryScanner ds = getDirectoryScanner(getProject());
+ int count = type == SetType.file
+ ? ds.getIncludedFilesCount()
+ : ds.getIncludedDirsCount();
+ if (type == SetType.both) {
+ count += ds.getIncludedFilesCount();
+ }
+ return count;
+ }
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/PropertyResource.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/PropertyResource.java
new file mode 100644
index 00000000..a7cecb4b
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/PropertyResource.java
@@ -0,0 +1,206 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types.resources;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.PropertyHelper;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.util.PropertyOutputStream;
+
+/**
+ * Exposes an Ant property as a Resource.
+ * @since Ant 1.7
+ */
+public class PropertyResource extends Resource {
+
+ /** Magic number */
+ private static final int PROPERTY_MAGIC
+ = Resource.getMagicNumber("PropertyResource".getBytes());
+
+ private static final InputStream UNSET = new InputStream() {
+ public int read() {
+ return -1;
+ }
+ };
+
+ /**
+ * Default constructor.
+ */
+ public PropertyResource() {
+ }
+
+ /**
+ * Construct a new PropertyResource with the specified name.
+ * @param p the project to use.
+ * @param n the String name of this PropertyResource (Ant property name/key).
+ */
+ public PropertyResource(Project p, String n) {
+ super(n);
+ setProject(p);
+ }
+
+ /**
+ * Get the value of this PropertyResource.
+ * @return the value of the specified Property.
+ */
+ public String getValue() {
+ if (isReference()) {
+ return ((PropertyResource) getCheckedRef()).getValue();
+ }
+ Project p = getProject();
+ return p == null ? null : p.getProperty(getName());
+ }
+
+ /**
+ * Get the Object value of this PropertyResource.
+ * @return the Object value of the specified Property.
+ * @since Ant 1.8.1
+ */
+ public Object getObjectValue() {
+ if (isReference()) {
+ return ((PropertyResource) getCheckedRef()).getObjectValue();
+ }
+ Project p = getProject();
+ return p == null ? null : PropertyHelper.getProperty(p, getName());
+ }
+
+ /**
+ * Find out whether this Resource exists.
+ * @return true if the Property is set, false otherwise.
+ */
+ public boolean isExists() {
+ if (isReferenceOrProxy()) {
+ return getReferencedOrProxied().isExists();
+ }
+ return getObjectValue() != null;
+ }
+
+ /**
+ * Get the size of this Resource.
+ * @return the size, as a long, 0 if the Resource does not exist (for
+ * compatibility with java.io.File), or UNKNOWN_SIZE if not known.
+ */
+ public long getSize() {
+ if (isReferenceOrProxy()) {
+ return getReferencedOrProxied().getSize();
+ }
+ Object o = getObjectValue();
+ return o == null ? 0L : (long) String.valueOf(o).length();
+ }
+
+ /**
+ * Override to implement equality with equivalent Resources,
+ * since we are capable of proxying them.
+ * @param o object to compare
+ * @return true if equal to o
+ */
+ public boolean equals(Object o) {
+ if (super.equals(o)) {
+ return true;
+ }
+ return isReferenceOrProxy() && getReferencedOrProxied().equals(o);
+ }
+
+ /**
+ * Get the hash code for this Resource.
+ * @return hash code as int.
+ */
+ public int hashCode() {
+ if (isReferenceOrProxy()) {
+ return getReferencedOrProxied().hashCode();
+ }
+ return super.hashCode() * PROPERTY_MAGIC;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String toString() {
+ if (isReferenceOrProxy()) {
+ return getReferencedOrProxied().toString();
+ }
+ return getValue();
+ }
+
+ /**
+ * Get an InputStream for the Resource.
+ * @return an InputStream containing this Resource's content.
+ * @throws IOException if unable to provide the content of this
+ * Resource as a stream.
+ * @throws UnsupportedOperationException if InputStreams are not
+ * supported for this Resource type.
+ */
+ public InputStream getInputStream() throws IOException {
+ if (isReferenceOrProxy()) {
+ return getReferencedOrProxied().getInputStream();
+ }
+ Object o = getObjectValue();
+ return o == null ? UNSET : new ByteArrayInputStream(String.valueOf(o).getBytes());
+ }
+
+ /**
+ * Get an OutputStream for the Resource.
+ * @return an OutputStream to which content can be written.
+ * @throws IOException if unable to provide the content of this
+ * Resource as a stream.
+ * @throws UnsupportedOperationException if OutputStreams are not
+ * supported for this Resource type.
+ */
+ public OutputStream getOutputStream() throws IOException {
+ if (isReferenceOrProxy()) {
+ return getReferencedOrProxied().getOutputStream();
+ }
+ if (isExists()) {
+ throw new ImmutableResourceException();
+ }
+ return new PropertyOutputStream(getProject(), getName());
+ }
+
+ /**
+ * Learn whether this PropertyResource either refers to another Resource
+ * or proxies another Resource due to its object property value being said Resource.
+ * @return boolean
+ */
+ protected boolean isReferenceOrProxy() {
+ return isReference() || getObjectValue() instanceof Resource;
+ }
+
+ /**
+ * Get the referenced or proxied Resource, if applicable.
+ * @return Resource
+ * @throws IllegalStateException if this PropertyResource neither proxies nor
+ * references another Resource.
+ */
+ protected Resource getReferencedOrProxied() {
+ if (isReference()) {
+ return (Resource) getCheckedRef(Resource.class, "resource");
+ }
+ Object o = getObjectValue();
+ if (o instanceof Resource) {
+ return (Resource) o;
+ }
+ throw new IllegalStateException(
+ "This PropertyResource does not reference or proxy another Resource");
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/ResourceDecorator.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/ResourceDecorator.java
new file mode 100644
index 00000000..3806cf2c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/ResourceDecorator.java
@@ -0,0 +1,270 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.resources;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Stack;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.Reference;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.ResourceCollection;
+
+/**
+ * Abstract class that delegates all reading methods of Resource to
+ * its wrapped resource and deals with reference handling.
+ *
+ * <p>Overwrites all setters to throw exceptions.</p>
+ *
+ * @since Ant 1.8.0
+ */
+public abstract class ResourceDecorator extends Resource {
+
+ private Resource resource;
+
+ /** no arg constructor */
+ protected ResourceDecorator() {
+ }
+
+ /**
+ * Constructor with another resource to wrap.
+ * @param other the resource to wrap.
+ */
+ protected ResourceDecorator(ResourceCollection other) {
+ addConfigured(other);
+ }
+
+ /**
+ * Sets the resource to wrap using a single-element collection.
+ * @param a the resource to wrap as a single element Resource collection.
+ */
+ public final void addConfigured(ResourceCollection a) {
+ checkChildrenAllowed();
+ if (resource != null) {
+ throw new BuildException("you must not specify more than one"
+ + " resource");
+ }
+ if (a.size() != 1) {
+ throw new BuildException("only single argument resource collections"
+ + " are supported");
+ }
+ setChecked(false);
+ resource = a.iterator().next();
+ }
+
+ /**
+ * Get the name of the resource.
+ * @return the name of the wrapped resource.
+ */
+ public String getName() {
+ return getResource().getName();
+ }
+
+ /**
+ * The exists attribute tells whether a file exists.
+ * @return true if this resource exists.
+ */
+ public boolean isExists() {
+ return getResource().isExists();
+ }
+
+ /**
+ * Tells the modification time in milliseconds since 01.01.1970 .
+ *
+ * @return 0 if the resource does not exist to mirror the behavior
+ * of {@link java.io.File File}.
+ */
+ public long getLastModified() {
+ return getResource().getLastModified();
+ }
+
+ /**
+ * Tells if the resource is a directory.
+ * @return boolean flag indicating if the resource is a directory.
+ */
+ public boolean isDirectory() {
+ return getResource().isDirectory();
+ }
+
+ /**
+ * Get the size of this Resource.
+ * @return the size, as a long, 0 if the Resource does not exist (for
+ * compatibility with java.io.File), or UNKNOWN_SIZE if not known.
+ */
+ public long getSize() {
+ return getResource().getSize();
+ }
+
+ /**
+ * Get an InputStream for the Resource.
+ * @return an InputStream containing this Resource's content.
+ * @throws IOException if unable to provide the content of this
+ * Resource as a stream.
+ * @throws UnsupportedOperationException if InputStreams are not
+ * supported for this Resource type.
+ */
+ public InputStream getInputStream() throws IOException {
+ return getResource().getInputStream();
+ }
+
+ /**
+ * Get an OutputStream for the Resource.
+ * @return an OutputStream to which content can be written.
+ * @throws IOException if unable to provide the content of this
+ * Resource as a stream.
+ * @throws UnsupportedOperationException if OutputStreams are not
+ * supported for this Resource type.
+ */
+ public OutputStream getOutputStream() throws IOException {
+ return getResource().getOutputStream();
+ }
+
+ /**
+ * Fulfill the ResourceCollection contract.
+ * @return whether this Resource is a FileProvider.
+ */
+ public boolean isFilesystemOnly() {
+ return as(FileProvider.class) != null;
+ }
+
+ /**
+ * Overrides the base version.
+ * @param r the Reference to set.
+ */
+ public void setRefid(Reference r) {
+ if (resource != null) {
+ throw noChildrenAllowed();
+ }
+ super.setRefid(r);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public <T> T as(Class<T> clazz) {
+ return getResource().as(clazz);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public int compareTo(Resource other) {
+ if (other == this) {
+ return 0;
+ }
+ if (other instanceof ResourceDecorator) {
+ return getResource().compareTo(
+ ((ResourceDecorator) other).getResource());
+ }
+ return getResource().compareTo(other);
+ }
+
+ /**
+ * Get the hash code for this Resource.
+ * @return hash code as int.
+ */
+ public int hashCode() {
+ return (getClass().hashCode() << 4) | getResource().hashCode();
+ }
+
+ /**
+ * De-references refids if any, ensures a wrapped resource has
+ * been specified.
+ */
+ protected final Resource getResource() {
+ if (isReference()) {
+ return (Resource) getCheckedRef();
+ }
+ if (resource == null) {
+ throw new BuildException("no resource specified");
+ }
+ dieOnCircularReference();
+ return resource;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected void dieOnCircularReference(final Stack<Object> stack,
+ final Project project)
+ throws BuildException {
+ if (isChecked()) {
+ return;
+ }
+ if (isReference()) {
+ super.dieOnCircularReference(stack, project);
+ } else {
+ pushAndInvokeCircularReferenceCheck(resource, stack, project);
+ setChecked(true);
+ }
+ }
+
+ // disable modification
+
+ /**
+ * Overridden, not allowed to set the name of the resource.
+ * @param name not used.
+ * @throws BuildException always.
+ */
+ public void setName(String name) throws BuildException {
+ throw new BuildException("you can't change the name of a "
+ + getDataTypeName());
+ }
+
+ /**
+ * Set the exists attribute.
+ * @param exists if true, this resource exists.
+ */
+ public void setExists(boolean exists) {
+ throw new BuildException("you can't change the exists state of a "
+ + getDataTypeName());
+ }
+
+ /**
+ * Override setLastModified.
+ * @param lastmodified not used.
+ * @throws BuildException always.
+ */
+ public void setLastModified(long lastmodified) throws BuildException {
+ throw new BuildException("you can't change the timestamp of a "
+ + getDataTypeName());
+ }
+
+ /**
+ * Override setDirectory.
+ * @param directory not used.
+ * @throws BuildException always.
+ */
+ public void setDirectory(boolean directory) throws BuildException {
+ throw new BuildException("you can't change the directory state of a "
+ + getDataTypeName());
+ }
+
+ /**
+ * Override setSize.
+ * @param size not used.
+ * @throws BuildException always.
+ */
+ public void setSize(long size) throws BuildException {
+ throw new BuildException("you can't change the size of a "
+ + getDataTypeName());
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/ResourceList.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/ResourceList.java
new file mode 100644
index 00000000..8b77e1bb
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/ResourceList.java
@@ -0,0 +1,239 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.resources;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.Stack;
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.PropertyHelper;
+import org.apache.tools.ant.filters.util.ChainReaderHelper;
+import org.apache.tools.ant.types.DataType;
+import org.apache.tools.ant.types.FilterChain;
+import org.apache.tools.ant.types.Reference;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.ResourceCollection;
+import org.apache.tools.ant.util.FileUtils;
+
+/**
+ * Reads a resource as text document and creates a resource for each
+ * line.
+ * @since Ant 1.8.0
+ */
+public class ResourceList extends DataType implements ResourceCollection {
+ private final Vector<FilterChain> filterChains = new Vector<FilterChain>();
+ private final ArrayList<ResourceCollection> textDocuments = new ArrayList<ResourceCollection>();
+ private final Union cachedResources = new Union();
+ private volatile boolean cached = false;
+ private String encoding = null;
+
+ public ResourceList() {
+ cachedResources.setCache(true);
+ }
+
+ /**
+ * Adds a source.
+ */
+ public void add(ResourceCollection rc) {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ textDocuments.add(rc);
+ setChecked(false);
+ }
+
+ /**
+ * Adds a FilterChain.
+ */
+ public final void addFilterChain(FilterChain filter) {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ filterChains.add(filter);
+ setChecked(false);
+ }
+
+ /**
+ * Encoding to use for input, defaults to the platform's default
+ * encoding. <p>
+ *
+ * For a list of possible values see
+ * <a href="http://java.sun.com/j2se/1.5.0/docs/guide/intl/encoding.doc.html">
+ * http://java.sun.com/j2se/1.5.0/docs/guide/intl/encoding.doc.html
+ * </a>.</p>
+ */
+ public final void setEncoding(String encoding) {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ this.encoding = encoding;
+ }
+
+ /**
+ * Makes this instance in effect a reference to another ResourceList
+ * instance.
+ */
+ public void setRefid(Reference r) throws BuildException {
+ if (encoding != null) {
+ throw tooManyAttributes();
+ }
+ if (filterChains.size() > 0 || textDocuments.size() > 0) {
+ throw noChildrenAllowed();
+ }
+ super.setRefid(r);
+ }
+
+ /**
+ * Fulfill the ResourceCollection contract. The Iterator returned
+ * will throw ConcurrentModificationExceptions if ResourceCollections
+ * are added to this container while the Iterator is in use.
+ * @return a "fail-fast" Iterator.
+ */
+ public final synchronized Iterator<Resource> iterator() {
+ if (isReference()) {
+ return ((ResourceList) getCheckedRef()).iterator();
+ }
+ return cache().iterator();
+ }
+
+ /**
+ * Fulfill the ResourceCollection contract.
+ * @return number of elements as int.
+ */
+ public synchronized int size() {
+ if (isReference()) {
+ return ((ResourceList) getCheckedRef()).size();
+ }
+ return cache().size();
+ }
+
+ /**
+ * Fulfill the ResourceCollection contract.
+ * @return whether this is a filesystem-only resource collection.
+ */
+ public synchronized boolean isFilesystemOnly() {
+ if (isReference()) {
+ return ((ResourceList) getCheckedRef()).isFilesystemOnly();
+ }
+ return cache().isFilesystemOnly();
+ }
+
+ /**
+ * Overrides the version of DataType to recurse on all DataType
+ * child elements that may have been added.
+ * @param stk the stack of data types to use (recursively).
+ * @param p the project to use to dereference the references.
+ * @throws BuildException on error.
+ */
+ protected synchronized void dieOnCircularReference(Stack<Object> stk, Project p)
+ throws BuildException {
+ if (isChecked()) {
+ return;
+ }
+ if (isReference()) {
+ super.dieOnCircularReference(stk, p);
+ } else {
+ for (ResourceCollection resourceCollection : textDocuments) {
+ if (resourceCollection instanceof DataType) {
+ pushAndInvokeCircularReferenceCheck((DataType) resourceCollection, stk, p);
+ }
+ }
+ for (FilterChain filterChain : filterChains) {
+ pushAndInvokeCircularReferenceCheck(filterChain, stk, p);
+ }
+ setChecked(true);
+ }
+ }
+
+ private synchronized ResourceCollection cache() {
+ if (!cached) {
+ dieOnCircularReference();
+ for (ResourceCollection rc : textDocuments) {
+ for (Resource r : rc) {
+ cachedResources.add(read(r));
+ }
+ }
+ cached = true;
+ }
+ return cachedResources;
+ }
+
+ private ResourceCollection read(Resource r) {
+ BufferedInputStream bis = null;
+ try {
+ bis = new BufferedInputStream(r.getInputStream());
+ Reader input = null;
+ if (encoding == null) {
+ input = new InputStreamReader(bis);
+ } else {
+ input = new InputStreamReader(bis, encoding);
+ }
+ ChainReaderHelper crh = new ChainReaderHelper();
+ crh.setPrimaryReader(input);
+ crh.setFilterChains(filterChains);
+ crh.setProject(getProject());
+ BufferedReader reader = new BufferedReader(crh.getAssembledReader());
+
+ Union streamResources = new Union();
+ streamResources.setCache(true);
+
+ String line = null;
+ while ((line = reader.readLine()) != null) {
+ streamResources.add(parse(line));
+ }
+
+ return streamResources;
+ } catch (final IOException ioe) {
+ throw new BuildException("Unable to read resource " + r.getName()
+ + ": " + ioe, ioe, getLocation());
+ } finally {
+ FileUtils.close(bis);
+ }
+ }
+
+ private Resource parse(final String line) {
+ PropertyHelper propertyHelper
+ = (PropertyHelper) PropertyHelper.getPropertyHelper(getProject());
+ Object expanded = propertyHelper.parseProperties(line);
+ if (expanded instanceof Resource) {
+ return (Resource) expanded;
+ }
+ String expandedLine = expanded.toString();
+ int colon = expandedLine.indexOf(":");
+ if (colon != -1) {
+ // could be an URL or an absolute file on an OS with drives
+ try {
+ return new URLResource(expandedLine);
+ } catch (BuildException mfe) {
+ // a translated MalformedURLException
+
+ // probably it's an absolute path fall back to file
+ // resource
+ }
+ }
+ return new FileResource(getProject(), expandedLine);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/Resources.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/Resources.java
new file mode 100644
index 00000000..1dd888d4
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/Resources.java
@@ -0,0 +1,274 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types.resources;
+
+import java.io.File;
+import java.util.AbstractCollection;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+import java.util.Stack;
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.DataType;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.ResourceCollection;
+import org.apache.tools.ant.util.CollectionUtils;
+
+/**
+ * Generic ResourceCollection: Either stores nested ResourceCollections,
+ * making no attempt to remove duplicates, or references another ResourceCollection.
+ * @since Ant 1.7
+ */
+public class Resources extends DataType implements ResourceCollection {
+ /** static empty ResourceCollection */
+ public static final ResourceCollection NONE = new ResourceCollection() {
+ public boolean isFilesystemOnly() {
+ return true;
+ }
+ public Iterator<Resource> iterator() {
+ return EMPTY_ITERATOR;
+ }
+ public int size() {
+ return 0;
+ }
+ };
+
+ /** static empty Iterator */
+ public static final Iterator<Resource> EMPTY_ITERATOR = new Iterator<Resource>() {
+ public Resource next() {
+ throw new NoSuchElementException();
+ }
+ public boolean hasNext() {
+ return false;
+ }
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+ };
+
+ private class MyCollection extends AbstractCollection<Resource> {
+ private Collection<Resource> cached;
+
+ MyCollection() {
+ }
+ public int size() {
+ return getCache().size();
+ }
+ public Iterator<Resource> iterator() {
+ return getCache().iterator();
+ }
+ private synchronized Collection<Resource> getCache() {
+ Collection<Resource> coll = cached;
+ if (coll == null) {
+ coll = CollectionUtils.asCollection(new MyIterator());
+ if (cache) {
+ cached = coll;
+ }
+ }
+ return coll;
+ }
+ private class MyIterator implements Iterator<Resource> {
+ private Iterator<ResourceCollection> rci = getNested().iterator();
+ private Iterator<Resource> ri = null;
+
+ public boolean hasNext() {
+ boolean result = ri != null && ri.hasNext();
+ while (!result && rci.hasNext()) {
+ ri = ((ResourceCollection) rci.next()).iterator();
+ result = ri.hasNext();
+ }
+ return result;
+ }
+ public Resource next() {
+ if (!hasNext()) {
+ throw new NoSuchElementException();
+ }
+ return ri.next();
+ }
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+ }
+ }
+
+ private Vector<ResourceCollection> rc;
+ private Collection<Resource> coll;
+ private boolean cache = false;
+
+ /**
+ * Create a new Resources.
+ */
+ public Resources() {
+ }
+
+ /**
+ * Create a new Resources.
+ * @since Ant 1.8
+ */
+ public Resources(Project project) {
+ setProject(project);
+ }
+
+ /**
+ * Set whether to cache collections.
+ * @param b boolean cache flag.
+ * @since Ant 1.8.0
+ */
+ public synchronized void setCache(boolean b) {
+ cache = b;
+ }
+
+ /**
+ * Add a ResourceCollection.
+ * @param c the ResourceCollection to add.
+ */
+ public synchronized void add(ResourceCollection c) {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ if (c == null) {
+ return;
+ }
+ if (rc == null) {
+ rc = new Vector<ResourceCollection>();
+ }
+ rc.add(c);
+ invalidateExistingIterators();
+ coll = null;
+ setChecked(false);
+ }
+
+ /**
+ * Fulfill the ResourceCollection contract.
+ * @return an Iterator of Resources.
+ */
+ public synchronized Iterator<Resource> iterator() {
+ if (isReference()) {
+ return getRef().iterator();
+ }
+ validate();
+ return new FailFast(this, coll.iterator());
+ }
+
+ /**
+ * Fulfill the ResourceCollection contract.
+ * @return number of elements as int.
+ */
+ public synchronized int size() {
+ if (isReference()) {
+ return getRef().size();
+ }
+ validate();
+ return coll.size();
+ }
+
+ /**
+ * Fulfill the ResourceCollection contract.
+ * @return true if all Resources represent files.
+ */
+ public boolean isFilesystemOnly() {
+ if (isReference()) {
+ return getRef().isFilesystemOnly();
+ }
+ validate();
+
+ for (Iterator<ResourceCollection> i = getNested().iterator(); i.hasNext();) {
+ if (!i.next().isFilesystemOnly()) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Format this <code>Resources</code> as a String.
+ * @return a descriptive <code>String</code>.
+ */
+ public synchronized String toString() {
+ if (isReference()) {
+ return getCheckedRef().toString();
+ }
+ validate();
+ if (coll == null || coll.isEmpty()) {
+ return "";
+ }
+ StringBuffer sb = new StringBuffer();
+ for (Resource r : coll) {
+ if (sb.length() > 0) {
+ sb.append(File.pathSeparatorChar);
+ }
+ sb.append(r);
+ }
+ return sb.toString();
+ }
+
+ /**
+ * Overrides the version of DataType to recurse on all DataType
+ * child elements that may have been added.
+ * @param stk the stack of data types to use (recursively).
+ * @param p the project to use to dereference the references.
+ * @throws BuildException on error.
+ */
+ protected void dieOnCircularReference(Stack<Object> stk, Project p)
+ throws BuildException {
+ if (isChecked()) {
+ return;
+ }
+ if (isReference()) {
+ super.dieOnCircularReference(stk, p);
+ } else {
+ for (ResourceCollection resourceCollection : getNested()) {
+ if (resourceCollection instanceof DataType) {
+ pushAndInvokeCircularReferenceCheck((DataType) resourceCollection, stk, p);
+ }
+ }
+ setChecked(true);
+ }
+ }
+
+ /**
+ * Allow subclasses to notify existing Iterators they have experienced concurrent modification.
+ */
+ protected void invalidateExistingIterators() {
+ FailFast.invalidate(this);
+ }
+
+ /**
+ * Resolves references, allowing any ResourceCollection.
+ * @return the referenced ResourceCollection.
+ */
+ private ResourceCollection getRef() {
+ return (ResourceCollection) getCheckedRef(
+ ResourceCollection.class, "ResourceCollection");
+ }
+
+ private synchronized void validate() {
+ dieOnCircularReference();
+ coll = (coll == null) ? new MyCollection() : coll;
+ }
+
+ private synchronized List<ResourceCollection> getNested() {
+ return rc == null ? Collections.<ResourceCollection> emptyList() : rc;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/Restrict.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/Restrict.java
new file mode 100644
index 00000000..2ea1a861
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/Restrict.java
@@ -0,0 +1,156 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.resources;
+
+import java.util.Iterator;
+import java.util.Stack;
+
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.ResourceCollection;
+import org.apache.tools.ant.types.resources.selectors.ResourceSelector;
+import org.apache.tools.ant.types.resources.selectors.ResourceSelectorContainer;
+
+/**
+ * ResourceCollection that allows a number of selectors to be
+ * applied to a single ResourceCollection for the purposes of
+ * restricting or narrowing results.
+ * @since Ant 1.7
+ */
+public class Restrict
+ extends ResourceSelectorContainer implements ResourceCollection {
+
+ private LazyResourceCollectionWrapper w = new LazyResourceCollectionWrapper() {
+ /**
+ * Restrict the nested ResourceCollection based on the nested selectors.
+ */
+ protected boolean filterResource(Resource r) {
+ for (Iterator<ResourceSelector> i = getSelectors(); i.hasNext();) {
+ if (!i.next().isSelected(r)) {
+ return true;
+ }
+ }
+ return false;
+ }
+ };
+
+ /**
+ * Add the ResourceCollection.
+ * @param c the ResourceCollection to add.
+ */
+ public synchronized void add(ResourceCollection c) {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ if (c == null) {
+ return;
+ }
+ w.add(c);
+ setChecked(false);
+ }
+
+ /**
+ * Set whether to cache collections.
+ * @param b boolean cache flag.
+ */
+ public synchronized void setCache(boolean b) {
+ w.setCache(b);
+ }
+
+ /**
+ * Learn whether to cache collections. Default is <code>true</code>.
+ * @return boolean cache flag.
+ */
+ public synchronized boolean isCache() {
+ return w.isCache();
+ }
+
+ /**
+ * Add a ResourceSelector.
+ * @param s the ResourceSelector to add.
+ */
+ public synchronized void add(ResourceSelector s) {
+ if (s == null) {
+ return;
+ }
+ super.add(s);
+ FailFast.invalidate(this);
+ }
+
+ /**
+ * Fulfill the ResourceCollection contract.
+ * @return an Iterator of Resources.
+ */
+ public final synchronized Iterator<Resource> iterator() {
+ if (isReference()) {
+ return ((Restrict) getCheckedRef()).iterator();
+ }
+ dieOnCircularReference();
+ return w.iterator();
+ }
+
+ /**
+ * Fulfill the ResourceCollection contract.
+ * @return number of elements as int.
+ */
+ public synchronized int size() {
+ if (isReference()) {
+ return ((Restrict) getCheckedRef()).size();
+ }
+ dieOnCircularReference();
+ return w.size();
+ }
+
+ /**
+ * Fulfill the ResourceCollection contract.
+ * @return whether this is a filesystem-only resource collection.
+ */
+ public synchronized boolean isFilesystemOnly() {
+ if (isReference()) {
+ return ((Restrict) getCheckedRef()).isFilesystemOnly();
+ }
+ dieOnCircularReference();
+ return w.isFilesystemOnly();
+ }
+
+ /**
+ * Format this Restrict collection as a String.
+ * @return the String value of this collection.
+ */
+ public synchronized String toString() {
+ if (isReference()) {
+ return getCheckedRef().toString();
+ }
+ dieOnCircularReference();
+ return w.toString();
+ }
+
+ protected synchronized void dieOnCircularReference(Stack<Object> stk, Project p) {
+ if (isChecked()) {
+ return;
+ }
+
+ // takes care of Selectors
+ super.dieOnCircularReference(stk, p);
+
+ if (!isReference()) {
+ pushAndInvokeCircularReferenceCheck(w, stk, p);
+ setChecked(true);
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/SizeLimitCollection.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/SizeLimitCollection.java
new file mode 100644
index 00000000..c8e772be
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/SizeLimitCollection.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.resources;
+
+import org.apache.tools.ant.BuildException;
+
+/**
+ * ResourceCollection that imposes a size limit on another ResourceCollection.
+ * @since Ant 1.7.1
+ */
+public abstract class SizeLimitCollection extends BaseResourceCollectionWrapper {
+ private static final String BAD_COUNT
+ = "size-limited collection count should be set to an int >= 0";
+
+ private int count = 1;
+
+ /**
+ * Set the number of resources to be included.
+ * @param i the count as <code>int</count>.
+ */
+ public synchronized void setCount(int i) {
+ checkAttributesAllowed();
+ count = i;
+ }
+
+ /**
+ * Get the number of resources to be included. Default is 1.
+ * @return the count as <code>int</count>.
+ */
+ public synchronized int getCount() {
+ return count;
+ }
+
+ /**
+ * Efficient size implementation.
+ * @return int size
+ */
+ public synchronized int size() {
+ int sz = getResourceCollection().size();
+ int ct = getValidCount();
+ return sz < ct ? sz : ct;
+ }
+
+ /**
+ * Get the count, verifying it is >= 0.
+ * @return int count
+ */
+ protected int getValidCount() {
+ int ct = getCount();
+ if (ct < 0) {
+ throw new BuildException(BAD_COUNT);
+ }
+ return ct;
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/Sort.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/Sort.java
new file mode 100644
index 00000000..b4dc88c2
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/Sort.java
@@ -0,0 +1,98 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.resources;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Stack;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.DataType;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.ResourceCollection;
+import org.apache.tools.ant.types.resources.comparators.DelegatedResourceComparator;
+import org.apache.tools.ant.types.resources.comparators.ResourceComparator;
+import org.apache.tools.ant.util.CollectionUtils;
+
+/**
+ * ResourceCollection that sorts another ResourceCollection.
+ *
+ * Note that Sort must not be used in cases where the ordering of the objects
+ * being sorted might change during the sorting process.
+ *
+ * @since Ant 1.7
+ */
+public class Sort extends BaseResourceCollectionWrapper {
+
+ private DelegatedResourceComparator comp = new DelegatedResourceComparator();
+
+ /**
+ * Sort the contained elements.
+ * @return a Collection of Resources.
+ */
+ protected synchronized Collection<Resource> getCollection() {
+ ResourceCollection rc = getResourceCollection();
+ Iterator<Resource> iter = rc.iterator();
+ if (!(iter.hasNext())) {
+ return Collections.emptySet();
+ }
+ List<Resource> result = (List<Resource>) CollectionUtils.asCollection(iter);
+ Collections.sort(result, comp);
+ return result;
+ }
+
+ /**
+ * Add a ResourceComparator to this Sort ResourceCollection.
+ * If multiple ResourceComparators are added, they will be processed in LIFO order.
+ * @param c the ResourceComparator to add.
+ */
+ public synchronized void add(ResourceComparator c) {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ comp.add(c);
+ FailFast.invalidate(this);
+ setChecked(false);
+ }
+
+ /**
+ * Overrides the BaseResourceCollectionContainer version
+ * to recurse on nested ResourceComparators.
+ * @param stk the stack of data types to use (recursively).
+ * @param p the project to use to dereference the references.
+ * @throws BuildException on error.
+ */
+ protected synchronized void dieOnCircularReference(Stack<Object> stk, Project p)
+ throws BuildException {
+ if (isChecked()) {
+ return;
+ }
+
+ // check nested collection
+ super.dieOnCircularReference(stk, p);
+
+ if (!isReference()) {
+ DataType.pushAndInvokeCircularReferenceCheck(comp, stk, p);
+ setChecked(true);
+ }
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/StringResource.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/StringResource.java
new file mode 100644
index 00000000..b12a2e14
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/StringResource.java
@@ -0,0 +1,261 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.resources;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.FilterOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.Reference;
+import org.apache.tools.ant.types.Resource;
+
+/**
+ * Exposes a string as a Resource.
+ * @since Ant 1.7
+ */
+public class StringResource extends Resource {
+
+ /** Magic number */
+ private static final int STRING_MAGIC
+ = Resource.getMagicNumber("StringResource".getBytes());
+
+ private static final String DEFAULT_ENCODING = "UTF-8";
+ private String encoding = DEFAULT_ENCODING;
+
+ /**
+ * Default constructor.
+ */
+ public StringResource() {
+ }
+
+ /**
+ * Construct a StringResource with the supplied value.
+ * @param value the value of this StringResource.
+ */
+ public StringResource(String value) {
+ this(null, value);
+ }
+
+ /**
+ * Construct a StringResource with the supplied project and value,
+ * doing property replacement against the project if non-null.
+ * @param project the owning Project.
+ * @param value the value of this StringResource.
+ */
+ public StringResource(Project project, String value) {
+ setProject(project);
+ setValue(project == null ? value : project.replaceProperties(value));
+ }
+
+ /**
+ * Enforce String immutability.
+ * @param s the new name/value for this StringResource.
+ */
+ public synchronized void setName(String s) {
+ if (getName() != null) {
+ throw new BuildException(new ImmutableResourceException());
+ }
+ super.setName(s);
+ }
+
+ /**
+ * The value attribute is a semantically superior alias for the name attribute.
+ * @param s the String's value.
+ */
+ public synchronized void setValue(String s) {
+ setName(s);
+ }
+
+ /**
+ * Synchronize access.
+ * @return the name/value of this StringResource.
+ */
+ public synchronized String getName() {
+ return super.getName();
+ }
+
+ /**
+ * Get the value of this StringResource, resolving to the root reference if needed.
+ * @return the represented String.
+ */
+ public synchronized String getValue() {
+ return getName();
+ }
+
+ /**
+ * The exists attribute tells whether a resource exists.
+ *
+ * @return true if this resource exists.
+ */
+ public boolean isExists() {
+ return getValue() != null;
+ }
+
+ /**
+ * Add nested text to this resource.
+ * Properties will be expanded during this process.
+ * @since Ant 1.7.1
+ * @param text text to use as the string resource
+ */
+ public void addText(String text) {
+ checkChildrenAllowed();
+ setValue(getProject().replaceProperties(text));
+ }
+
+ /**
+ * Set the encoding to be used for this StringResource.
+ * @param s the encoding name.
+ */
+ public synchronized void setEncoding(String s) {
+ checkAttributesAllowed();
+ encoding = s;
+ }
+
+ /**
+ * Get the encoding used by this StringResource.
+ * @return the encoding name.
+ */
+ public synchronized String getEncoding() {
+ return encoding;
+ }
+
+ /**
+ * Get the size of this Resource.
+ * @return the size, as a long, 0 if the Resource does not exist (for
+ * compatibility with java.io.File), or UNKNOWN_SIZE if not known.
+ */
+ public synchronized long getSize() {
+ return isReference() ? ((Resource) getCheckedRef()).getSize()
+ : getContent().length();
+ }
+
+ /**
+ * Get the hash code for this Resource.
+ * @return hash code as int.
+ */
+ public synchronized int hashCode() {
+ if (isReference()) {
+ return getCheckedRef().hashCode();
+ }
+ return super.hashCode() * STRING_MAGIC;
+ }
+
+ /**
+ * Get the string. See {@link #getContent()}
+ *
+ * @return the string contents of the resource.
+ * @since Ant 1.7
+ */
+ public String toString() {
+ return String.valueOf(getContent());
+ }
+
+ /**
+ * Get an InputStream for the Resource.
+ * @return an InputStream containing this Resource's content.
+ * @throws IOException if unable to provide the content of this
+ * Resource as a stream.
+ * @throws UnsupportedOperationException if InputStreams are not
+ * supported for this Resource type.
+ */
+ public synchronized InputStream getInputStream() throws IOException {
+ if (isReference()) {
+ return ((Resource) getCheckedRef()).getInputStream();
+ }
+ String content = getContent();
+ if (content == null) {
+ throw new IllegalStateException("unset string value");
+ }
+ return new ByteArrayInputStream(encoding == null
+ ? content.getBytes() : content.getBytes(encoding));
+ }
+
+ /**
+ * Get an OutputStream for the Resource.
+ * @return an OutputStream to which content can be written.
+ * @throws IOException if unable to provide the content of this
+ * Resource as a stream.
+ * @throws UnsupportedOperationException if OutputStreams are not
+ * supported for this Resource type.
+ */
+ public synchronized OutputStream getOutputStream() throws IOException {
+ if (isReference()) {
+ return ((Resource) getCheckedRef()).getOutputStream();
+ }
+ if (getValue() != null) {
+ throw new ImmutableResourceException();
+ }
+ return new StringResourceFilterOutputStream();
+ }
+
+ /**
+ * Overrides the super version.
+ * @param r the Reference to set.
+ */
+ public void setRefid(Reference r) {
+ if (encoding != DEFAULT_ENCODING) {
+ throw tooManyAttributes();
+ }
+ super.setRefid(r);
+ }
+
+ /**
+ * Get the content of this StringResource. See {@link #getValue()}
+ * @return a String or null if there is no value.
+ */
+ protected synchronized String getContent() {
+ return getValue();
+ }
+
+ /**
+ * This method is only for use by our private helper output stream.
+ * It contains specific logic for expanding properties.
+ * @param output the output
+ */
+ private void setValueFromOutputStream(String output) {
+ String value;
+ if (getProject() != null) {
+ value = getProject().replaceProperties(output);
+ } else {
+ value = output;
+ }
+ setValue(value);
+ }
+
+ private class StringResourceFilterOutputStream extends FilterOutputStream {
+ private final ByteArrayOutputStream baos;
+
+ public StringResourceFilterOutputStream() {
+ super(new ByteArrayOutputStream());
+ baos = (ByteArrayOutputStream) out;
+ }
+
+ public void close() throws IOException {
+ super.close();
+ String result = encoding == null
+ ? baos.toString() : baos.toString(encoding);
+
+ StringResource.this.setValueFromOutputStream(result);
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/TarResource.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/TarResource.java
new file mode 100644
index 00000000..62f1f267
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/TarResource.java
@@ -0,0 +1,198 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.resources;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.util.FileUtils;
+import org.apache.tools.tar.TarEntry;
+import org.apache.tools.tar.TarInputStream;
+
+/**
+ * A Resource representation of an entry in a tar archive.
+ * @since Ant 1.7
+ */
+public class TarResource extends ArchiveResource {
+
+ private String userName = "";
+ private String groupName = "";
+ private int uid;
+ private int gid;
+
+ /**
+ * Default constructor.
+ */
+ public TarResource() {
+ }
+
+ /**
+ * Construct a TarResource representing the specified
+ * entry in the specified archive.
+ * @param a the archive as File.
+ * @param e the TarEntry.
+ */
+ public TarResource(File a, TarEntry e) {
+ super(a, true);
+ setEntry(e);
+ }
+
+ /**
+ * Construct a TarResource representing the specified
+ * entry in the specified archive.
+ * @param a the archive as Resource.
+ * @param e the TarEntry.
+ */
+ public TarResource(Resource a, TarEntry e) {
+ super(a, true);
+ setEntry(e);
+ }
+
+ /**
+ * Return an InputStream for reading the contents of this Resource.
+ * @return an InputStream object.
+ * @throws IOException if the tar file cannot be opened,
+ * or the entry cannot be read.
+ */
+ public InputStream getInputStream() throws IOException {
+ if (isReference()) {
+ return ((Resource) getCheckedRef()).getInputStream();
+ }
+ Resource archive = getArchive();
+ final TarInputStream i = new TarInputStream(archive.getInputStream());
+ TarEntry te = null;
+ while ((te = i.getNextEntry()) != null) {
+ if (te.getName().equals(getName())) {
+ return i;
+ }
+ }
+
+ FileUtils.close(i);
+ throw new BuildException("no entry " + getName() + " in "
+ + getArchive());
+ }
+
+ /**
+ * Get an OutputStream for the Resource.
+ * @return an OutputStream to which content can be written.
+ * @throws IOException if unable to provide the content of this
+ * Resource as a stream.
+ * @throws UnsupportedOperationException if OutputStreams are not
+ * supported for this Resource type.
+ */
+ public OutputStream getOutputStream() throws IOException {
+ if (isReference()) {
+ return ((Resource) getCheckedRef()).getOutputStream();
+ }
+ throw new UnsupportedOperationException(
+ "Use the tar task for tar output.");
+ }
+
+ /**
+ * @return the user name for the tar entry
+ */
+ public String getUserName() {
+ if (isReference()) {
+ return ((TarResource) getCheckedRef()).getUserName();
+ }
+ checkEntry();
+ return userName;
+ }
+
+ /**
+ * @return the group name for the tar entry
+ */
+ public String getGroup() {
+ if (isReference()) {
+ return ((TarResource) getCheckedRef()).getGroup();
+ }
+ checkEntry();
+ return groupName;
+ }
+
+ /**
+ * @return the uid for the tar entry
+ */
+ public int getUid() {
+ if (isReference()) {
+ return ((TarResource) getCheckedRef()).getUid();
+ }
+ checkEntry();
+ return uid;
+ }
+
+ /**
+ * @return the gid for the tar entry
+ */
+ public int getGid() {
+ if (isReference()) {
+ return ((TarResource) getCheckedRef()).getGid();
+ }
+ checkEntry();
+ return gid;
+ }
+
+ /**
+ * fetches information from the named entry inside the archive.
+ */
+ protected void fetchEntry() {
+ Resource archive = getArchive();
+ TarInputStream i = null;
+ try {
+ i = new TarInputStream(archive.getInputStream());
+ TarEntry te = null;
+ while ((te = i.getNextEntry()) != null) {
+ if (te.getName().equals(getName())) {
+ setEntry(te);
+ return;
+ }
+ }
+ } catch (IOException e) {
+ log(e.getMessage(), Project.MSG_DEBUG);
+ throw new BuildException(e);
+ } finally {
+ if (i != null) {
+ FileUtils.close(i);
+ }
+ }
+ setEntry(null);
+ }
+
+ private void setEntry(TarEntry e) {
+ if (e == null) {
+ setExists(false);
+ return;
+ }
+ setName(e.getName());
+ setExists(true);
+ setLastModified(e.getModTime().getTime());
+ setDirectory(e.isDirectory());
+ setSize(e.getSize());
+ setMode(e.getMode());
+ userName = e.getUserName();
+ groupName = e.getGroupName();
+ uid = e.getUserId();
+ gid = e.getGroupId();
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/Tokens.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/Tokens.java
new file mode 100644
index 00000000..0a518c3d
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/Tokens.java
@@ -0,0 +1,137 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.resources;
+
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Stack;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.DataType;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.ResourceCollection;
+import org.apache.tools.ant.util.ConcatResourceInputStream;
+import org.apache.tools.ant.util.FileUtils;
+import org.apache.tools.ant.util.LineTokenizer;
+import org.apache.tools.ant.util.Tokenizer;
+
+/**
+ * ResourceCollection consisting of StringResources gathered from tokenizing
+ * another ResourceCollection with a Tokenizer implementation.
+ * @since Ant 1.7
+ */
+public class Tokens extends BaseResourceCollectionWrapper {
+
+ private Tokenizer tokenizer;
+ private String encoding;
+
+ /**
+ * Sort the contained elements.
+ * @return a Collection of Resources.
+ */
+ protected synchronized Collection<Resource> getCollection() {
+ ResourceCollection rc = getResourceCollection();
+ if (rc.size() == 0) {
+ return Collections.emptySet();
+ }
+ if (tokenizer == null) {
+ tokenizer = new LineTokenizer();
+ }
+ ConcatResourceInputStream cat = new ConcatResourceInputStream(rc);
+ cat.setManagingComponent(this);
+
+ try {
+ InputStreamReader rdr = null;
+ if (encoding == null) {
+ rdr = new InputStreamReader(cat);
+ } else {
+ try {
+ rdr = new InputStreamReader(cat, encoding);
+ } catch (UnsupportedEncodingException e) {
+ throw new BuildException(e);
+ }
+ }
+ ArrayList<Resource> result = new ArrayList<Resource>();
+ for (String s = tokenizer.getToken(rdr); s != null; s = tokenizer.getToken(rdr)) {
+ StringResource resource = new StringResource(s);
+ resource.setProject(getProject());
+ result.add(resource);
+ }
+ return result;
+ } catch (IOException e) {
+ throw new BuildException("Error reading tokens", e);
+ } finally {
+ FileUtils.close(cat);
+ }
+ }
+
+ /**
+ * Set the encoding used to create the tokens.
+ * @param encoding the encoding to use.
+ */
+ public synchronized void setEncoding(String encoding) {
+ this.encoding = encoding;
+ }
+
+ /**
+ * Add the nested Tokenizer to this Tokens ResourceCollection.
+ * A LineTokenizer will be used by default.
+ * @param tokenizer the tokenizer to add.
+ */
+ public synchronized void add(Tokenizer tokenizer) {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ if (this.tokenizer != null) {
+ throw new BuildException("Only one nested tokenizer allowed.");
+ }
+ this.tokenizer = tokenizer;
+ setChecked(false);
+ }
+
+ /**
+ * Overrides the BaseResourceCollectionContainer version
+ * to check the nested Tokenizer.
+ * @param stk the stack of data types to use (recursively).
+ * @param p the project to use to dereference the references.
+ * @throws BuildException on error.
+ */
+ protected synchronized void dieOnCircularReference(Stack<Object> stk, Project p)
+ throws BuildException {
+ if (isChecked()) {
+ return;
+ }
+
+ // check nested collection
+ super.dieOnCircularReference(stk, p);
+
+ if (!isReference()) {
+ if (tokenizer instanceof DataType) {
+ pushAndInvokeCircularReferenceCheck((DataType) tokenizer, stk,
+ p);
+ }
+ setChecked(true);
+ }
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/Touchable.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/Touchable.java
new file mode 100644
index 00000000..3a54a693
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/Touchable.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.resources;
+
+/**
+ * Interface to be implemented by "touchable" resources;
+ * that is, those whose modification time can be altered.
+ * @since Ant 1.7
+ */
+public interface Touchable {
+ /**
+ * Method called to "touch" the resource.
+ * @param modTime the time to set the modified "field" of the resource,
+ * measured in milliseconds since the epoch.
+ */
+ void touch(long modTime);
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/URLProvider.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/URLProvider.java
new file mode 100644
index 00000000..81bb6697
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/URLProvider.java
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types.resources;
+
+import java.net.URL;
+
+/**
+ * This is an interface that resources that can provide an URL should implement.
+ * This is a refactoring of {@link URLResource}, to allow other resources
+ * to act as sources of URLs.
+ * @since Ant 1.8
+ */
+public interface URLProvider {
+ /**
+ * Get the URL represented by this Resource.
+ * @return the file.
+ */
+ URL getURL();
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/URLResource.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/URLResource.java
new file mode 100644
index 00000000..70d6c9ba
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/URLResource.java
@@ -0,0 +1,454 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types.resources;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLConnection;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.Reference;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.util.FileUtils;
+
+/**
+ * Exposes a URL as a Resource.
+ * @since Ant 1.7
+ */
+public class URLResource extends Resource implements URLProvider {
+ private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+ private static final int NULL_URL
+ = Resource.getMagicNumber("null URL".getBytes());
+
+ private URL url;
+ private URLConnection conn;
+ private URL baseURL;
+ private String relPath;
+
+ /**
+ * Default constructor.
+ */
+ public URLResource() {
+ }
+
+ /**
+ * Convenience constructor.
+ * @param u the URL to expose.
+ */
+ public URLResource(URL u) {
+ setURL(u);
+ }
+
+ /**
+ * Convenience constructor.
+ * @param u holds the URL to expose.
+ */
+ public URLResource(URLProvider u) {
+ setURL(u.getURL());
+ }
+
+ /**
+ * Convenience constructor.
+ * @param f the File to set as a URL.
+ */
+ public URLResource(File f) {
+ setFile(f);
+ }
+
+ /**
+ * String constructor for Ant attribute introspection.
+ * @param u String representation of this URL.
+ * @see org.apache.tools.ant.IntrospectionHelper
+ */
+ public URLResource(String u) {
+ this(newURL(u));
+ }
+
+ /**
+ * Set the URL for this URLResource.
+ * @param u the URL to expose.
+ */
+ public synchronized void setURL(URL u) {
+ checkAttributesAllowed();
+ url = u;
+ }
+
+ /**
+ * Set the URL from a File.
+ * @param f the File to set as a URL.
+ */
+ public synchronized void setFile(File f) {
+ try {
+ setURL(FILE_UTILS.getFileURL(f));
+ } catch (MalformedURLException e) {
+ throw new BuildException(e);
+ }
+ }
+
+ /**
+ * Base URL which combined with the relativePath attribute defines
+ * the URL.
+ * @since Ant 1.8.0
+ */
+ public synchronized void setBaseURL(URL base) {
+ checkAttributesAllowed();
+ if (url != null) {
+ throw new BuildException("can't define URL and baseURL attribute");
+ }
+ baseURL = base;
+ }
+
+ /**
+ * Relative path which combined with the baseURL attribute defines
+ * the URL.
+ * @since Ant 1.8.0
+ */
+ public synchronized void setRelativePath(String r) {
+ checkAttributesAllowed();
+ if (url != null) {
+ throw new BuildException("can't define URL and relativePath"
+ + " attribute");
+ }
+ relPath = r;
+ }
+
+
+ /**
+ * Get the URL used by this URLResource.
+ * @return a URL object.
+ */
+ public synchronized URL getURL() {
+ if (isReference()) {
+ return ((URLResource) getCheckedRef()).getURL();
+ }
+ if (url == null) {
+ if (baseURL != null) {
+ if (relPath == null) {
+ throw new BuildException("must provide relativePath"
+ + " attribute when using baseURL.");
+ }
+ try {
+ url = new URL(baseURL, relPath);
+ } catch (MalformedURLException e) {
+ throw new BuildException(e);
+ }
+ }
+ }
+ return url;
+ }
+
+ /**
+ * Overrides the super version.
+ * @param r the Reference to set.
+ */
+ public synchronized void setRefid(Reference r) {
+ //not using the accessor in this case to avoid side effects
+ if (url != null || baseURL != null || relPath != null) {
+ throw tooManyAttributes();
+ }
+ super.setRefid(r);
+ }
+
+ /**
+ * Get the name of this URLResource
+ * (its file component minus the leading separator).
+ * @return the name of this resource.
+ */
+ public synchronized String getName() {
+ if (isReference()) {
+ return ((Resource) getCheckedRef()).getName();
+ }
+ String name = getURL().getFile();
+ return "".equals(name) ? name : name.substring(1);
+ }
+
+ /**
+ * Return this URLResource formatted as a String.
+ * @return a String representation of this URLResource.
+ */
+ public synchronized String toString() {
+ return isReference()
+ ? getCheckedRef().toString() : String.valueOf(getURL());
+ }
+
+ /**
+ * Find out whether the URL exists .
+ * @return true if this resource exists.
+ */
+ public synchronized boolean isExists() {
+ if (isReference()) {
+ return ((Resource) getCheckedRef()).isExists();
+ }
+ return isExists(false);
+ }
+
+ /**
+ * Find out whether the URL exists, and close the connection
+ * opened to the URL if closeConnection is true.
+ *
+ * Note that this method does ensure that if:
+ * - the resource exists (if it returns true)
+ * - and if the current object is not a reference
+ * (isReference() returns false)
+ * - and if it was called with closeConnection to false,
+ *
+ * then the connection to the URL (stored in the conn
+ * private field) will be opened, and require to be closed
+ * by the caller.
+ *
+ * @param closeConnection true if the connection should be closed
+ * after the call, false if it should stay open.
+ * @return true if this resource exists.
+ */
+ private synchronized boolean isExists(boolean closeConnection) {
+ if (getURL() == null) {
+ return false;
+ }
+ try {
+ connect(Project.MSG_VERBOSE);
+ if (conn instanceof HttpURLConnection) {
+ int sc = ((HttpURLConnection) conn).getResponseCode();
+ // treating inaccessible resources as non-existent
+ return sc < 400;
+ } else if (url.getProtocol().startsWith("ftp")) {
+ closeConnection = true;
+ InputStream in = null;
+ try {
+ in = conn.getInputStream();
+ } finally {
+ FileUtils.close(in);
+ }
+ }
+ return true;
+ } catch (IOException e) {
+ return false;
+ } finally {
+ if (closeConnection) {
+ close();
+ }
+ }
+ }
+
+
+ /**
+ * Tells the modification time in milliseconds since 01.01.1970 .
+ *
+ * @return 0 if the resource does not exist to mirror the behavior
+ * of {@link java.io.File File}.
+ */
+ public synchronized long getLastModified() {
+ if (isReference()) {
+ return ((Resource) getCheckedRef()).getLastModified();
+ }
+ if (!isExists(false)) {
+ return UNKNOWN_DATETIME;
+ }
+ return withConnection(new ConnectionUser() {
+ public long useConnection(URLConnection c) {
+ return conn.getLastModified();
+ }
+ }, UNKNOWN_DATETIME);
+ }
+
+ /**
+ * Tells if the resource is a directory.
+ * @return boolean whether the resource is a directory.
+ */
+ public synchronized boolean isDirectory() {
+ return isReference()
+ ? ((Resource) getCheckedRef()).isDirectory()
+ : getName().endsWith("/");
+ }
+
+ /**
+ * Get the size of this Resource.
+ * @return the size, as a long, 0 if the Resource does not exist (for
+ * compatibility with java.io.File), or UNKNOWN_SIZE if not known.
+ */
+ public synchronized long getSize() {
+ if (isReference()) {
+ return ((Resource) getCheckedRef()).getSize();
+ }
+ if (!isExists(false)) {
+ return 0L;
+ }
+ return withConnection(new ConnectionUser() {
+ public long useConnection(URLConnection c) {
+ return conn.getContentLength();
+ }
+ }, UNKNOWN_SIZE);
+ }
+
+ /**
+ * Test whether an Object equals this URLResource.
+ * @param another the other Object to compare.
+ * @return true if the specified Object is equal to this Resource.
+ */
+ public synchronized boolean equals(Object another) {
+ if (this == another) {
+ return true;
+ }
+ if (isReference()) {
+ return getCheckedRef().equals(another);
+ }
+ if (another == null || !(another.getClass().equals(getClass()))) {
+ return false;
+ }
+ URLResource otheru = (URLResource) another;
+ return getURL() == null
+ ? otheru.getURL() == null
+ : getURL().equals(otheru.getURL());
+ }
+
+ /**
+ * Get the hash code for this Resource.
+ * @return hash code as int.
+ */
+ public synchronized int hashCode() {
+ if (isReference()) {
+ return getCheckedRef().hashCode();
+ }
+ return MAGIC * ((getURL() == null) ? NULL_URL : getURL().hashCode());
+ }
+
+ /**
+ * Get an InputStream for the Resource.
+ * @return an InputStream containing this Resource's content.
+ * @throws IOException if unable to provide the content of this
+ * Resource as a stream.
+ * @throws UnsupportedOperationException if InputStreams are not
+ * supported for this Resource type.
+ */
+ public synchronized InputStream getInputStream() throws IOException {
+ if (isReference()) {
+ return ((Resource) getCheckedRef()).getInputStream();
+ }
+ connect();
+ try {
+ return conn.getInputStream();
+ } finally {
+ conn = null;
+ }
+ }
+
+ /**
+ * Get an OutputStream for the Resource.
+ * @return an OutputStream to which content can be written.
+ * @throws IOException if unable to provide the content of this
+ * Resource as a stream.
+ * @throws UnsupportedOperationException if OutputStreams are not
+ * supported for this Resource type.
+ * @throws IOException if the URL cannot be opened.
+ */
+ public synchronized OutputStream getOutputStream() throws IOException {
+ if (isReference()) {
+ return ((Resource) getCheckedRef()).getOutputStream();
+ }
+ connect();
+ try {
+ return conn.getOutputStream();
+ } finally {
+ conn = null;
+ }
+ }
+
+ /**
+ * Ensure that we have a connection.
+ * @throws IOException if the connection cannot be established.
+ */
+ protected void connect() throws IOException {
+ connect(Project.MSG_ERR);
+ }
+
+ /**
+ * Ensure that we have a connection.
+ * @param logLevel severity to use when logging connection errors.
+ * Should be one of the <code>MSG_</code> constants in {@link
+ * Project Project}.
+ * @throws IOException if the connection cannot be established.
+ * @since Ant 1.8.2
+ */
+ protected synchronized void connect(int logLevel) throws IOException {
+ URL u = getURL();
+ if (u == null) {
+ throw new BuildException("URL not set");
+ }
+ if (conn == null) {
+ try {
+ conn = u.openConnection();
+ conn.connect();
+ } catch (IOException e) {
+ log(e.toString(), logLevel);
+ conn = null;
+ throw e;
+ }
+ }
+ }
+
+ /**
+ * Closes the URL connection if:
+ * - it is opened (i.e. the field conn is not null)
+ * - this type of URLConnection supports some sort of close mechanism
+ *
+ * This method ensures the field conn will be null after the call.
+ *
+ */
+ private synchronized void close() {
+ try {
+ FileUtils.close(conn);
+ } finally {
+ conn = null;
+ }
+ }
+
+ private static URL newURL(String u) {
+ try {
+ return new URL(u);
+ } catch (MalformedURLException e) {
+ throw new BuildException(e);
+ }
+ }
+
+ private interface ConnectionUser {
+ long useConnection(URLConnection c);
+ }
+
+ private long withConnection(ConnectionUser u, long defaultValue) {
+ try {
+ if (conn != null) {
+ return u.useConnection(conn);
+ } else {
+ try {
+ connect();
+ return u.useConnection(conn);
+ } finally {
+ close();
+ }
+ }
+ } catch (IOException ex) {
+ return defaultValue;
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/Union.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/Union.java
new file mode 100644
index 00000000..e2f2f9f2
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/Union.java
@@ -0,0 +1,156 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.resources;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.ResourceCollection;
+
+/**
+ * ResourceCollection representing the union of multiple nested ResourceCollections.
+ * @since Ant 1.7
+ */
+public class Union extends BaseResourceCollectionContainer {
+
+ /**
+ * Static convenience method to union an arbitrary set of Resources.
+ * @param rc a ResourceCollection.
+ * @return a Union.
+ */
+ public static Union getInstance(ResourceCollection rc) {
+ return rc instanceof Union ? (Union) rc : new Union(rc);
+ }
+
+ /**
+ * Default constructor.
+ */
+ public Union() {
+ }
+
+ /**
+ * Create a new Union.
+ * @param project owning Project
+ */
+ public Union(Project project) {
+ super(project);
+ }
+
+ /**
+ * Convenience constructor.
+ * @param rc the ResourceCollection to add.
+ */
+ public Union(ResourceCollection rc) {
+ this(Project.getProject(rc), rc);
+ }
+
+ /**
+ * Convenience constructor.
+ * @param project owning Project
+ * @param rc the ResourceCollection to add.
+ */
+ public Union(Project project, ResourceCollection rc) {
+ super(project);
+ add(rc);
+ }
+
+ /**
+ * Returns all Resources in String format. Provided for
+ * convenience in implementing Path.
+ * @return String array of Resources.
+ */
+ public String[] list() {
+ if (isReference()) {
+ return getCheckedRef(Union.class, getDataTypeName()).list();
+ }
+ final Collection<String> result = getAllToStrings();
+ return result.toArray(new String[result.size()]);
+ }
+
+ /**
+ * Convenience method.
+ * @return Resource[]
+ */
+ public Resource[] listResources() {
+ if (isReference()) {
+ return getCheckedRef(Union.class, getDataTypeName()).listResources();
+ }
+ final Collection<Resource> result = getAllResources();
+ return result.toArray(new Resource[result.size()]);
+ }
+
+ /**
+ * Unify the contained Resources.
+ * @return a Collection of Resources.
+ */
+ protected Collection<Resource> getCollection() {
+ return getAllResources();
+ }
+
+ /**
+ * Unify the contained Resources.
+ * @param asString indicates whether the resulting Collection
+ * should contain Strings instead of Resources.
+ * @return a Collection of Resources.
+ */
+ @Deprecated
+ @SuppressWarnings("unchecked")
+ protected <T> Collection<T> getCollection(boolean asString) { // TODO untypable
+ return asString ? (Collection<T>) getAllToStrings() : (Collection<T>) getAllResources();
+ }
+
+ /**
+ * Get a collection of strings representing the unified resource set (strings may duplicate).
+ * @return Collection<String>
+ */
+ protected Collection<String> getAllToStrings() {
+ final Set<Resource> allResources = getAllResources();
+ final ArrayList<String> result = new ArrayList<String>(allResources.size());
+ for (Resource r : allResources) {
+ result.add(r.toString());
+ }
+ return result;
+ }
+
+ /**
+ * Get the unified set of contained Resources.
+ * @return Set<Resource>
+ */
+ protected Set<Resource> getAllResources() {
+ final List<ResourceCollection> resourceCollections = getResourceCollections();
+ if (resourceCollections.isEmpty()) {
+ return Collections.emptySet();
+ }
+ final LinkedHashSet<Resource> result = new LinkedHashSet<Resource>(
+ resourceCollections.size() * 2);
+ for (ResourceCollection resourceCollection : resourceCollections) {
+ for (Resource r : resourceCollection) {
+ result.add(r);
+ }
+ }
+ return result;
+ }
+
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/ZipResource.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/ZipResource.java
new file mode 100644
index 00000000..37fc98ec
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/ZipResource.java
@@ -0,0 +1,226 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.resources;
+
+import java.io.File;
+import java.io.FilterInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.Reference;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.ResourceCollection;
+import org.apache.tools.ant.util.FileUtils;
+import org.apache.tools.zip.ZipEntry;
+import org.apache.tools.zip.ZipExtraField;
+import org.apache.tools.zip.ZipFile;
+
+/**
+ * A Resource representation of an entry in a zipfile.
+ * @since Ant 1.7
+ */
+public class ZipResource extends ArchiveResource {
+
+ private String encoding;
+ private ZipExtraField[] extras;
+ private int method;
+
+ /**
+ * Default constructor.
+ */
+ public ZipResource() {
+ }
+
+ /**
+ * Construct a ZipResource representing the specified
+ * entry in the specified zipfile.
+ * @param z the zipfile as File.
+ * @param enc the encoding used for filenames.
+ * @param e the ZipEntry.
+ */
+ public ZipResource(File z, String enc, ZipEntry e) {
+ super(z, true);
+ setEncoding(enc);
+ setEntry(e);
+ }
+
+ /**
+ * Set the zipfile that holds this ZipResource.
+ * @param z the zipfile as a File.
+ */
+ public void setZipfile(File z) {
+ setArchive(z);
+ }
+
+ /**
+ * Get the zipfile that holds this ZipResource.
+ * @return the zipfile as a File.
+ */
+ public File getZipfile() {
+ FileProvider fp = getArchive().as(FileProvider.class);
+ return fp.getFile();
+ }
+
+ /**
+ * Sets the archive that holds this as a single element Resource
+ * collection.
+ * @param a the archive as a single element Resource collection.
+ */
+ public void addConfigured(ResourceCollection a) {
+ super.addConfigured(a);
+ if (!a.isFilesystemOnly()) {
+ throw new BuildException("only filesystem resources are supported");
+ }
+ }
+
+ /**
+ * Set the encoding to use with the zipfile.
+ * @param enc the String encoding.
+ */
+ public void setEncoding(String enc) {
+ checkAttributesAllowed();
+ encoding = enc;
+ }
+
+ /**
+ * Get the encoding to use with the zipfile.
+ * @return String encoding.
+ */
+ public String getEncoding() {
+ return isReference()
+ ? ((ZipResource) getCheckedRef()).getEncoding() : encoding;
+ }
+
+ /**
+ * Overrides the super version.
+ * @param r the Reference to set.
+ */
+ public void setRefid(Reference r) {
+ if (encoding != null) {
+ throw tooManyAttributes();
+ }
+ super.setRefid(r);
+ }
+
+ /**
+ * Return an InputStream for reading the contents of this Resource.
+ * @return an InputStream object.
+ * @throws IOException if the zip file cannot be opened,
+ * or the entry cannot be read.
+ */
+ public InputStream getInputStream() throws IOException {
+ if (isReference()) {
+ return ((Resource) getCheckedRef()).getInputStream();
+ }
+ final ZipFile z = new ZipFile(getZipfile(), getEncoding());
+ ZipEntry ze = z.getEntry(getName());
+ if (ze == null) {
+ z.close();
+ throw new BuildException("no entry " + getName() + " in "
+ + getArchive());
+ }
+ return new FilterInputStream(z.getInputStream(ze)) {
+ public void close() throws IOException {
+ FileUtils.close(in);
+ z.close();
+ }
+ protected void finalize() throws Throwable {
+ try {
+ close();
+ } finally {
+ super.finalize();
+ }
+ }
+ };
+ }
+
+ /**
+ * Get an OutputStream for the Resource.
+ * @return an OutputStream to which content can be written.
+ * @throws IOException if unable to provide the content of this
+ * Resource as a stream.
+ * @throws UnsupportedOperationException if OutputStreams are not
+ * supported for this Resource type.
+ */
+ public OutputStream getOutputStream() throws IOException {
+ if (isReference()) {
+ return ((Resource) getCheckedRef()).getOutputStream();
+ }
+ throw new UnsupportedOperationException(
+ "Use the zip task for zip output.");
+ }
+
+ /**
+ * Retrieves extra fields.
+ * @return an array of the extra fields
+ * @since Ant 1.8.0
+ */
+ public ZipExtraField[] getExtraFields() {
+ if (isReference()) {
+ return ((ZipResource) getCheckedRef()).getExtraFields();
+ }
+ checkEntry();
+ if (extras == null) {
+ return new ZipExtraField[0];
+ }
+ return extras;
+ }
+
+ /**
+ * The compression method that has been used.
+ * @since Ant 1.8.0
+ */
+ public int getMethod() {
+ return method;
+ }
+
+ /**
+ * fetches information from the named entry inside the archive.
+ */
+ protected void fetchEntry() {
+ ZipFile z = null;
+ try {
+ z = new ZipFile(getZipfile(), getEncoding());
+ setEntry(z.getEntry(getName()));
+ } catch (IOException e) {
+ log(e.getMessage(), Project.MSG_DEBUG);
+ throw new BuildException(e);
+ } finally {
+ ZipFile.closeQuietly(z);
+ }
+ }
+
+ private void setEntry(ZipEntry e) {
+ if (e == null) {
+ setExists(false);
+ return;
+ }
+ setName(e.getName());
+ setExists(true);
+ setLastModified(e.getTime());
+ setDirectory(e.isDirectory());
+ setSize(e.getSize());
+ setMode(e.getUnixMode());
+ extras = e.getExtraFields(true);
+ method = e.getMethod();
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/comparators/Content.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/comparators/Content.java
new file mode 100644
index 00000000..1810b640
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/comparators/Content.java
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.resources.comparators;
+
+import java.io.IOException;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.util.ResourceUtils;
+
+/**
+ * Compares Resources by content.
+ * @since Ant 1.7
+ */
+public class Content extends ResourceComparator {
+
+ private boolean binary = true;
+
+ /**
+ * Set binary mode for this Content ResourceComparator. If this
+ * attribute is set to false, Resource content will be compared
+ * ignoring platform line-ending conventions.
+ * Default is <code>true</code>.
+ * @param b whether to compare content in binary mode.
+ */
+ public void setBinary(boolean b) {
+ binary = b;
+ }
+
+ /**
+ * Learn whether this Content ResourceComparator is operating in binary mode.
+ * @return boolean binary flag.
+ */
+ public boolean isBinary() {
+ return binary;
+ }
+
+ /**
+ * Compare two Resources by content.
+ * @param foo the first Resource.
+ * @param bar the second Resource.
+ * @return a negative integer, zero, or a positive integer as the first
+ * argument is less than, equal to, or greater than the second.
+ * @throws BuildException if I/O errors occur.
+ * @see org.apache.tools.ant.util.ResourceUtils#compareContent(Resource, Resource, boolean).
+ */
+ protected int resourceCompare(Resource foo, Resource bar) {
+ try {
+ return ResourceUtils.compareContent(foo, bar, !binary);
+ } catch (IOException e) {
+ throw new BuildException(e);
+ }
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/comparators/Date.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/comparators/Date.java
new file mode 100644
index 00000000..b6be66bb
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/comparators/Date.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.resources.comparators;
+
+import org.apache.tools.ant.types.Resource;
+
+/**
+ * Compares Resources by last modification date.
+ * @since Ant 1.7
+ */
+public class Date extends ResourceComparator {
+ /**
+ * Compare two Resources.
+ * @param foo the first Resource.
+ * @param bar the second Resource.
+ * @return a negative integer, zero, or a positive integer as the first
+ * argument is less than, equal to, or greater than the second.
+ */
+ protected int resourceCompare(Resource foo, Resource bar) {
+ long diff = foo.getLastModified() - bar.getLastModified();
+ if (diff > 0) {
+ return +1;
+ } else if (diff < 0) {
+ return -1;
+ } else {
+ return 0;
+ }
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/comparators/DelegatedResourceComparator.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/comparators/DelegatedResourceComparator.java
new file mode 100644
index 00000000..aa2f55a8
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/comparators/DelegatedResourceComparator.java
@@ -0,0 +1,125 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.resources.comparators;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.Stack;
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.DataType;
+import org.apache.tools.ant.types.Resource;
+
+/**
+ * Delegates to other ResourceComparators or, if none specified,
+ * uses Resources' natural ordering.
+ * @since Ant 1.7
+ */
+public class DelegatedResourceComparator extends ResourceComparator {
+
+ private List<ResourceComparator> resourceComparators = null;
+
+ /**
+ * Add a delegate ResourceComparator.
+ * @param c the next delegate ResourceComparator.
+ */
+ public synchronized void add(ResourceComparator c) {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ if (c == null) {
+ return;
+ }
+ resourceComparators = (resourceComparators == null) ? new Vector<ResourceComparator>() : resourceComparators;
+ resourceComparators.add(c);
+ setChecked(false);
+ }
+
+ /**
+ * Equality method based on the vector of resources,
+ * or if a reference, the referredto object.
+ * @param o the object to check against.
+ * @return true if there is equality.
+ */
+ public synchronized boolean equals(Object o) {
+ if (o == this) {
+ return true;
+ }
+ if (isReference()) {
+ return getCheckedRef().equals(o);
+ }
+ if (!(o instanceof DelegatedResourceComparator)) {
+ return false;
+ }
+ List<ResourceComparator> ov = ((DelegatedResourceComparator) o).resourceComparators;
+ return resourceComparators == null ? ov == null : resourceComparators.equals(ov);
+ }
+
+ /**
+ * Hashcode based on the rules for equality.
+ * @return a hashcode.
+ */
+ public synchronized int hashCode() {
+ if (isReference()) {
+ return getCheckedRef().hashCode();
+ }
+ return resourceComparators == null ? 0 : resourceComparators.hashCode();
+ }
+
+ /** {@inheritDoc} */
+ protected synchronized int resourceCompare(Resource foo, Resource bar) {
+ //if no nested, natural order:
+ if (resourceComparators == null || resourceComparators.isEmpty()) {
+ return foo.compareTo(bar);
+ }
+ int result = 0;
+ for (Iterator<ResourceComparator> i = resourceComparators.iterator(); result == 0 && i.hasNext();) {
+ result = i.next().resourceCompare(foo, bar);
+ }
+ return result;
+ }
+
+ /**
+ * Overrides the version from DataType to recurse on nested ResourceSelector
+s.
+ * @param stk the Stack of references.
+ * @param p the Project to resolve against.
+ * @throws BuildException on error.
+ */
+ protected void dieOnCircularReference(Stack<Object> stk, Project p)
+ throws BuildException {
+ if (isChecked()) {
+ return;
+ }
+ if (isReference()) {
+ super.dieOnCircularReference(stk, p);
+ } else {
+ if (!(resourceComparators == null || resourceComparators.isEmpty())) {
+ for (ResourceComparator resourceComparator : resourceComparators) {
+ if (resourceComparator instanceof DataType) {
+ pushAndInvokeCircularReferenceCheck((DataType) resourceComparator, stk,
+ p);
+ }
+ }
+ }
+ setChecked(true);
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/comparators/Exists.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/comparators/Exists.java
new file mode 100644
index 00000000..58321502
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/comparators/Exists.java
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.resources.comparators;
+
+import org.apache.tools.ant.types.Resource;
+
+/**
+ * Compares Resources by existence. Not existing is "less than" existing.
+ * @since Ant 1.7
+ */
+public class Exists extends ResourceComparator {
+
+ /**
+ * Compare two Resources.
+ * @param foo the first Resource.
+ * @param bar the second Resource.
+ * @return a negative integer, zero, or a positive integer as the first
+ * argument is less than, equal to, or greater than the second.
+ */
+ protected int resourceCompare(Resource foo, Resource bar) {
+ boolean f = foo.isExists();
+ if (f == bar.isExists()) {
+ return 0;
+ }
+ return f ? 1 : -1;
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/comparators/FileSystem.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/comparators/FileSystem.java
new file mode 100644
index 00000000..7eafeb94
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/comparators/FileSystem.java
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.resources.comparators;
+
+import java.io.File;
+
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.resources.FileProvider;
+import org.apache.tools.ant.util.FileUtils;
+
+/**
+ * Compares filesystem Resources.
+ * @since Ant 1.7
+ */
+public class FileSystem extends ResourceComparator {
+ private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+
+ /**
+ * Compare two Resources.
+ * @param foo the first Resource.
+ * @param bar the second Resource.
+ * @return a negative integer, zero, or a positive integer as the first
+ * argument is less than, equal to, or greater than the second.
+ * @throws ClassCastException if either resource is not an instance of FileResource.
+ */
+ protected int resourceCompare(Resource foo, Resource bar) {
+ FileProvider fooFP = foo.as(FileProvider.class);
+ if (fooFP == null) {
+ throw new ClassCastException(foo.getClass()
+ + " doesn't provide files");
+ }
+ File foofile = fooFP.getFile();
+ FileProvider barFP = bar.as(FileProvider.class);
+ if (barFP == null) {
+ throw new ClassCastException(bar.getClass()
+ + " doesn't provide files");
+ }
+ File barfile = barFP.getFile();
+ return foofile.equals(barfile) ? 0
+ : FILE_UTILS.isLeadingPath(foofile, barfile) ? -1
+ : FILE_UTILS.normalize(foofile.getAbsolutePath()).compareTo(
+ FILE_UTILS.normalize(barfile.getAbsolutePath()));
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/comparators/Name.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/comparators/Name.java
new file mode 100644
index 00000000..d048ac01
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/comparators/Name.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.resources.comparators;
+
+import org.apache.tools.ant.types.Resource;
+
+/**
+ * Compares Resources by name.
+ * @since Ant 1.7
+ */
+public class Name extends ResourceComparator {
+ /**
+ * Compare two Resources.
+ * @param foo the first Resource.
+ * @param bar the second Resource.
+ * @return a negative integer, zero, or a positive integer as the first
+ * argument is less than, equal to, or greater than the second.
+ */
+ protected int resourceCompare(Resource foo, Resource bar) {
+ return foo.getName().compareTo(bar.getName());
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/comparators/ResourceComparator.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/comparators/ResourceComparator.java
new file mode 100644
index 00000000..3bfc9c70
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/comparators/ResourceComparator.java
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.resources.comparators;
+
+import java.util.Comparator;
+
+import org.apache.tools.ant.types.DataType;
+import org.apache.tools.ant.types.Resource;
+
+/**
+ * Abstract Resource Comparator.
+ * @since Ant 1.7
+ */
+public abstract class ResourceComparator extends DataType implements Comparator<Resource> {
+
+ /**
+ * Compare two objects.
+ * @param foo the first Object.
+ * @param bar the second Object.
+ * @return a negative integer, zero, or a positive integer as the first
+ * argument is less than, equal to, or greater than the second.
+ * @throws ClassCastException if either argument is null.
+ */
+ public final int compare(Resource foo, Resource bar) {
+ dieOnCircularReference();
+ ResourceComparator c =
+ isReference() ? (ResourceComparator) getCheckedRef() : this;
+ return c.resourceCompare(foo, bar);
+ }
+
+ /**
+ * Test for equality with this ResourceComparator.
+ * @param o the Object to compare against.
+ * @return true if the specified Object equals this one.
+ */
+ public boolean equals(Object o) {
+ if (isReference()) {
+ return getCheckedRef().equals(o);
+ }
+ if (o == null) {
+ return false;
+ }
+ return o == this || o.getClass().equals(getClass());
+ }
+
+ /**
+ * Hashcode based on the rules for equality.
+ * @return a hashcode.
+ */
+ public synchronized int hashCode() {
+ if (isReference()) {
+ return getCheckedRef().hashCode();
+ }
+ return getClass().hashCode();
+ }
+
+ /**
+ * Compare two Resources.
+ * @param foo the first Resource.
+ * @param bar the second Resource.
+ * @return a negative integer, zero, or a positive integer as the first
+ * argument is less than, equal to, or greater than the second.
+ */
+ protected abstract int resourceCompare(Resource foo, Resource bar);
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/comparators/Reverse.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/comparators/Reverse.java
new file mode 100644
index 00000000..c787a765
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/comparators/Reverse.java
@@ -0,0 +1,91 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.resources.comparators;
+
+import java.util.Stack;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.DataType;
+import org.apache.tools.ant.types.Resource;
+
+/**
+ * Reverses another ResourceComparator. If no nested ResourceComparator
+ * is supplied, the compared Resources' natural order will be reversed.
+ * @since Ant 1.7
+ */
+public class Reverse extends ResourceComparator {
+ private static final String ONE_NESTED
+ = "You must not nest more than one ResourceComparator for reversal.";
+
+ private ResourceComparator nested;
+
+ /**
+ * Default constructor.
+ */
+ public Reverse() {
+ }
+
+ /**
+ * Construct a new Reverse, supplying the ResourceComparator to be reversed.
+ * @param c the ResourceComparator to reverse.
+ */
+ public Reverse(ResourceComparator c) {
+ add(c);
+ }
+
+ /**
+ * Add the ResourceComparator to reverse.
+ * @param c the ResourceComparator to add.
+ */
+ public void add(ResourceComparator c) {
+ if (nested != null) {
+ throw new BuildException(ONE_NESTED);
+ }
+ nested = c;
+ setChecked(false);
+ }
+
+ /**
+ * Compare two Resources.
+ * @param foo the first Resource.
+ * @param bar the second Resource.
+ * @return a negative integer, zero, or a positive integer as the first
+ * argument is greater than, equal to, or less than the second.
+ */
+ protected int resourceCompare(Resource foo, Resource bar) {
+ return -1 * (nested == null
+ ? foo.compareTo(bar) : nested.compare(foo, bar));
+ }
+
+ protected void dieOnCircularReference(Stack<Object> stk, Project p)
+ throws BuildException {
+ if (isChecked()) {
+ return;
+ }
+ if (isReference()) {
+ super.dieOnCircularReference(stk, p);
+ } else {
+ if (nested instanceof DataType) {
+ pushAndInvokeCircularReferenceCheck((DataType) nested, stk,
+ p);
+ }
+ setChecked(true);
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/comparators/Size.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/comparators/Size.java
new file mode 100644
index 00000000..b94f250b
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/comparators/Size.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.resources.comparators;
+
+import org.apache.tools.ant.types.Resource;
+
+/**
+ * Compares Resources by size.
+ * @since Ant 1.7
+ */
+public class Size extends ResourceComparator {
+ /**
+ * Compare two Resources.
+ * @param foo the first Resource.
+ * @param bar the second Resource.
+ * @return a negative integer, zero, or a positive integer as the first
+ * argument is less than, equal to, or greater than the second.
+ */
+ protected int resourceCompare(Resource foo, Resource bar) {
+ long diff = foo.getSize() - bar.getSize();
+ return diff > 0 ? 1 : (diff == 0 ? 0 : -1);
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/comparators/Type.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/comparators/Type.java
new file mode 100644
index 00000000..6c082ef6
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/comparators/Type.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.resources.comparators;
+
+import org.apache.tools.ant.types.Resource;
+
+/**
+ * Compares Resources by is-directory status. As a container
+ * of files, a directory is deemed "greater" than a file.
+ * @since Ant 1.7
+ */
+public class Type extends ResourceComparator {
+
+ /**
+ * Compare two Resources.
+ * @param foo the first Resource.
+ * @param bar the second Resource.
+ * @return a negative integer, zero, or a positive integer as the first
+ * argument is less than, equal to, or greater than the second.
+ */
+ protected int resourceCompare(Resource foo, Resource bar) {
+ boolean f = foo.isDirectory();
+ if (f == bar.isDirectory()) {
+ return 0;
+ }
+ return f ? 1 : -1;
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/selectors/And.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/selectors/And.java
new file mode 100644
index 00000000..409ed661
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/selectors/And.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.resources.selectors;
+
+import java.util.Iterator;
+
+import org.apache.tools.ant.types.Resource;
+
+/**
+ * And ResourceSelector.
+ * @since Ant 1.7
+ */
+public class And extends ResourceSelectorContainer implements ResourceSelector {
+
+ /**
+ * Default constructor.
+ */
+ public And() {
+ }
+
+ /**
+ * Convenience constructor.
+ * @param r the ResourceSelector[] to add.
+ */
+ public And(ResourceSelector[] r) {
+ super(r);
+ }
+
+ /**
+ * Return true if this Resource is selected.
+ * @param r the Resource to check.
+ * @return whether the Resource was selected.
+ */
+ public boolean isSelected(Resource r) {
+ for (Iterator<ResourceSelector> i = getSelectors(); i.hasNext();) {
+ if (!i.next().isSelected(r)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/selectors/Compare.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/selectors/Compare.java
new file mode 100644
index 00000000..f345c278
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/selectors/Compare.java
@@ -0,0 +1,149 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.resources.selectors;
+
+import java.util.Stack;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.Comparison;
+import org.apache.tools.ant.types.DataType;
+import org.apache.tools.ant.types.Quantifier;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.ResourceCollection;
+import org.apache.tools.ant.types.resources.Union;
+import org.apache.tools.ant.types.resources.comparators.DelegatedResourceComparator;
+import org.apache.tools.ant.types.resources.comparators.ResourceComparator;
+
+/**
+ * ResourceSelector that compares against "control" Resource(s)
+ * using ResourceComparators.
+ * @since Ant 1.7
+ */
+public class Compare extends DataType implements ResourceSelector {
+
+ private static final String ONE_CONTROL_MESSAGE
+ = " the <control> element should be specified exactly once.";
+
+ private DelegatedResourceComparator comp = new DelegatedResourceComparator();
+ private Quantifier against = Quantifier.ALL;
+
+ private Comparison when = Comparison.EQUAL;
+
+ private Union control;
+
+ /**
+ * Add a ResourceComparator to this Compare selector.
+ * If multiple ResourceComparators are added, they will be processed in LIFO order.
+ * @param c the ResourceComparator to add.
+ */
+ public synchronized void add(ResourceComparator c) {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ comp.add(c);
+ setChecked(false);
+ }
+
+ /**
+ * Set the quantifier to be used. Default "all".
+ * @param against the Quantifier EnumeratedAttribute to use.
+ */
+ public synchronized void setAgainst(Quantifier against) {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ this.against = against;
+ }
+
+ /**
+ * Set the comparison to be used. Default "equal".
+ * @param when the Comparison EnumeratedAttribute to use.
+ */
+ public synchronized void setWhen(Comparison when) {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ this.when = when;
+ }
+
+ /**
+ * Create the nested control element. These are the
+ * resources to compare against.
+ * @return ResourceCollection.
+ */
+ public synchronized ResourceCollection createControl() {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ if (control != null) {
+ throw oneControl();
+ }
+ control = new Union();
+ setChecked(false);
+ return control;
+ }
+
+ //implement ResourceSelector; inherit doc
+ /** {@inheritDoc} */
+ public synchronized boolean isSelected(Resource r) {
+ if (isReference()) {
+ return ((ResourceSelector) getCheckedRef()).isSelected(r);
+ }
+ if (control == null) {
+ throw oneControl();
+ }
+ dieOnCircularReference();
+ int t = 0, f = 0;
+ for (Resource res : control) {
+ if (when.evaluate(comp.compare(r, res))) {
+ t++;
+ } else {
+ f++;
+ }
+ }
+ return against.evaluate(t, f);
+ }
+
+ /**
+ * Overrides the version from DataType
+ * to recurse on nested ResourceComparators.
+ * @param stk the stack of data types to use (recursively).
+ * @param p the project to use to dereference the references.
+ * @throws BuildException on error.
+ */
+ protected synchronized void dieOnCircularReference(Stack<Object> stk, Project p)
+ throws BuildException {
+ if (isChecked()) {
+ return;
+ }
+ if (isReference()) {
+ super.dieOnCircularReference(stk, p);
+ } else {
+ if (control != null) {
+ DataType.pushAndInvokeCircularReferenceCheck(control, stk, p);
+ }
+ DataType.pushAndInvokeCircularReferenceCheck(comp, stk, p);
+ setChecked(true);
+ }
+ }
+
+ private BuildException oneControl() {
+ return new BuildException(super.toString() + ONE_CONTROL_MESSAGE);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/selectors/Date.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/selectors/Date.java
new file mode 100644
index 00000000..8541e858
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/selectors/Date.java
@@ -0,0 +1,162 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.resources.selectors;
+
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Locale;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.TimeComparison;
+import org.apache.tools.ant.util.FileUtils;
+
+/**
+ * Date ResourceSelector. Based on the date FileSelector, with the most
+ * notable difference being the lack of support for the includedirs attribute.
+ * It is recommended that the effect of includeDirs = "false" be achieved for
+ * resources by enclosing a "dir" Type ResourceSelector and a Date
+ * ResourceSelector in an Or ResourceSelector.
+ * @since Ant 1.7
+ */
+public class Date implements ResourceSelector {
+ private static final String MILLIS_OR_DATETIME
+ = "Either the millis or the datetime attribute must be set.";
+ private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+
+ private Long millis = null;
+ private String dateTime = null;
+ private String pattern = null;
+ private TimeComparison when = TimeComparison.EQUAL;
+ private long granularity = FILE_UTILS.getFileTimestampGranularity();
+
+ /**
+ * Set the date/time in milliseconds since 1970.
+ * @param m the number of millis.
+ */
+ public synchronized void setMillis(long m) {
+ millis = new Long(m);
+ }
+
+ /**
+ * Get the date/time in ms.
+ * @return long number of millis since 1970.
+ */
+ public synchronized long getMillis() {
+ return millis == null ? -1L : millis.longValue();
+ }
+
+ /**
+ * Set the date and time as a String.
+ * @param s the date and time to use.
+ */
+ public synchronized void setDateTime(String s) {
+ dateTime = s;
+ millis = null;
+ }
+
+ /**
+ * Get the date and time in String format.
+ * @return a String representing a date and time.
+ */
+ public synchronized String getDatetime() {
+ return dateTime;
+ }
+
+ /**
+ * Set the granularity to use for this ResourceSelector.
+ * @param g the timestamp granularity.
+ */
+ public synchronized void setGranularity(long g) {
+ granularity = g;
+ }
+
+ /**
+ * Get the timestamp granularity used by this ResourceSelector.
+ * @return the long granularity.
+ */
+ public synchronized long getGranularity() {
+ return granularity;
+ }
+
+ /**
+ * Set the optional pattern to use with the datetime attribute.
+ * @param p the SimpleDateFormat-compatible pattern string.
+ */
+ public synchronized void setPattern(String p) {
+ pattern = p;
+ }
+
+ /**
+ * Get the pattern for use with the datetime attribute.
+ * @return a SimpleDateFormat-compatible pattern string.
+ */
+ public synchronized String getPattern() {
+ return pattern;
+ }
+
+ /**
+ * Set the comparison mode.
+ * @param c a TimeComparison object.
+ */
+ public synchronized void setWhen(TimeComparison c) {
+ when = c;
+ }
+
+ /**
+ * Get the comparison mode.
+ * @return a TimeComparison object.
+ */
+ public synchronized TimeComparison getWhen() {
+ return when;
+ }
+
+ /**
+ * Return true if this Resource is selected.
+ * @param r the Resource to check.
+ * @return whether the Resource was selected.
+ */
+ public synchronized boolean isSelected(Resource r) {
+ if (dateTime == null && millis == null) {
+ throw new BuildException(MILLIS_OR_DATETIME);
+ }
+ if (millis == null) {
+ DateFormat df = ((pattern == null)
+ ? DateFormat.getDateTimeInstance(
+ DateFormat.SHORT, DateFormat.SHORT, Locale.US)
+ : new SimpleDateFormat(pattern));
+ try {
+ long m = df.parse(dateTime).getTime();
+ if (m < 0) {
+ throw new BuildException("Date of " + dateTime
+ + " results in negative milliseconds value"
+ + " relative to epoch (January 1, 1970, 00:00:00 GMT).");
+ }
+ setMillis(m);
+ } catch (ParseException pe) {
+ throw new BuildException("Date of " + dateTime
+ + " Cannot be parsed correctly. It should be in"
+ + (pattern == null
+ ? " MM/DD/YYYY HH:MM AM_PM" : pattern) + " format.");
+ }
+ }
+ return when.evaluate(r.getLastModified(), millis.longValue(), granularity);
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/selectors/Exists.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/selectors/Exists.java
new file mode 100644
index 00000000..1b498bca
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/selectors/Exists.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.resources.selectors;
+
+import org.apache.tools.ant.types.Resource;
+
+/**
+ * Exists ResourceSelector.
+ * @since Ant 1.7
+ */
+public class Exists implements ResourceSelector {
+
+ /**
+ * Return true if this Resource is selected.
+ * @param r the Resource to check.
+ * @return whether the Resource was selected.
+ */
+ public boolean isSelected(Resource r) {
+ return r.isExists();
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/selectors/InstanceOf.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/selectors/InstanceOf.java
new file mode 100644
index 00000000..39b31088
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/selectors/InstanceOf.java
@@ -0,0 +1,130 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types.resources.selectors;
+
+import org.apache.tools.ant.AntTypeDefinition;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.ComponentHelper;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.ProjectHelper;
+import org.apache.tools.ant.types.Resource;
+
+/**
+ * InstanceOf ResourceSelector.
+ * @since Ant 1.7
+ */
+public class InstanceOf implements ResourceSelector {
+ private static final String ONE_ONLY = "Exactly one of class|type must be set.";
+
+ private Project project;
+ private Class<?> clazz;
+ private String type;
+ private String uri;
+
+ /**
+ * Set the Project instance for this InstanceOf selector.
+ * @param p the Project instance used for type comparisons.
+ */
+ public void setProject(Project p) {
+ project = p;
+ }
+
+ /**
+ * Set the class to compare against.
+ * @param c the class.
+ */
+ public void setClass(Class<?> c) {
+ if (clazz != null) {
+ throw new BuildException("The class attribute has already been set.");
+ }
+ clazz = c;
+ }
+
+ /**
+ * Set the Ant type to compare against.
+ * @param s the type name.
+ */
+ public void setType(String s) {
+ type = s;
+ }
+
+ /**
+ * Set the URI in which the Ant type, if specified, should be defined.
+ * @param u the URI.
+ */
+ public void setURI(String u) {
+ uri = u;
+ }
+
+ /**
+ * Get the comparison class.
+ * @return the Class object.
+ */
+ public Class<?> getCheckClass() {
+ return clazz;
+ }
+
+ /**
+ * Get the comparison type.
+ * @return the String typename.
+ */
+ public String getType() {
+ return type;
+ }
+
+ /**
+ * Get the type's URI.
+ * @return the String URI.
+ */
+ public String getURI() {
+ return uri;
+ }
+
+ /**
+ * Return true if this Resource is selected.
+ * @param r the Resource to check.
+ * @return whether the Resource was selected.
+ * @throws BuildException if an error occurs.
+ */
+ public boolean isSelected(Resource r) {
+ if ((clazz == null) == (type == null)) {
+ throw new BuildException(ONE_ONLY);
+ }
+ Class<?> c = clazz;
+ if (type != null) {
+ if (project == null) {
+ throw new BuildException(
+ "No project set for InstanceOf ResourceSelector; "
+ + "the type attribute is invalid.");
+ }
+ AntTypeDefinition d = ComponentHelper.getComponentHelper(
+ project).getDefinition(ProjectHelper.genComponentName(uri, type));
+ if (d == null) {
+ throw new BuildException("type " + type + " not found.");
+ }
+ try {
+ c = d.innerGetTypeClass();
+ } catch (ClassNotFoundException e) {
+ throw new BuildException(e);
+ }
+ }
+ return c.isAssignableFrom(r.getClass());
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/selectors/Majority.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/selectors/Majority.java
new file mode 100644
index 00000000..5a7a95c0
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/selectors/Majority.java
@@ -0,0 +1,84 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.resources.selectors;
+
+import java.util.Iterator;
+
+import org.apache.tools.ant.types.Resource;
+
+/**
+ * Majority ResourceSelector.
+ * @since Ant 1.7
+ */
+public class Majority
+ extends ResourceSelectorContainer implements ResourceSelector {
+
+ private boolean tie = true;
+
+ /**
+ * Default constructor.
+ */
+ public Majority() {
+ }
+
+ /**
+ * Convenience constructor.
+ * @param r the ResourceSelector[] to add.
+ */
+ public Majority(ResourceSelector[] r) {
+ super(r);
+ }
+
+ /**
+ * Set whether ties are allowed.
+ * @param b whether a tie is a pass.
+ */
+ public synchronized void setAllowtie(boolean b) {
+ tie = b;
+ }
+
+ /**
+ * Return true if this Resource is selected.
+ * @param r the Resource to check.
+ * @return whether the Resource was selected.
+ */
+ public synchronized boolean isSelected(Resource r) {
+ int passed = 0;
+ int failed = 0;
+ int count = selectorCount();
+ boolean even = count % 2 == 0;
+ int threshold = count / 2;
+
+ for (Iterator<ResourceSelector> i = getSelectors(); i.hasNext();) {
+ if (i.next().isSelected(r)) {
+ ++passed;
+ if (passed > threshold || (even && tie && passed == threshold)) {
+ return true;
+ }
+ } else {
+ ++failed;
+ if (failed > threshold || (even && !tie && failed == threshold)) {
+ return false;
+ }
+ }
+ }
+ //dummy
+ return false;
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/selectors/Name.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/selectors/Name.java
new file mode 100644
index 00000000..50c242a2
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/selectors/Name.java
@@ -0,0 +1,151 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.resources.selectors;
+
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.RegularExpression;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.selectors.SelectorUtils;
+import org.apache.tools.ant.util.regexp.Regexp;
+import org.apache.tools.ant.util.regexp.RegexpUtil;
+
+/**
+ * Name ResourceSelector.
+ * @since Ant 1.7
+ */
+public class Name implements ResourceSelector {
+ private String regex = null;
+ private String pattern;
+ private boolean cs = true;
+ private boolean handleDirSep = false;
+
+ // caches for performance reasons
+ private RegularExpression reg;
+ private Regexp expression;
+
+ private Project project;
+
+ public void setProject(Project p) {
+ project = p;
+ }
+
+ /**
+ * Set the pattern to compare names against.
+ * @param n the pattern String to set.
+ */
+ public void setName(String n) {
+ pattern = n;
+ }
+
+ /**
+ * Get the pattern used by this Name ResourceSelector.
+ * @return the String selection pattern.
+ */
+ public String getName() {
+ return pattern;
+ }
+
+ /**
+ * Set the regular expression to compare names against.
+ * @param r the regex to set.
+ * @since Ant 1.8.0
+ */
+ public void setRegex(String r) {
+ regex = r;
+ reg = null;
+ }
+
+ /**
+ * Get the regular expression used by this Name ResourceSelector.
+ * @return the String selection pattern.
+ * @since Ant 1.8.0
+ */
+ public String getRegex() {
+ return regex;
+ }
+
+ /**
+ * Set whether the name comparisons are case-sensitive.
+ * @param b boolean case-sensitivity flag.
+ */
+ public void setCaseSensitive(boolean b) {
+ cs = b;
+ }
+
+ /**
+ * Learn whether this Name ResourceSelector is case-sensitive.
+ * @return boolean case-sensitivity flag.
+ */
+ public boolean isCaseSensitive() {
+ return cs;
+ }
+
+ /**
+ * Attribute specifying whether to ignore the difference
+ * between / and \ (the two common directory characters).
+ * @param handleDirSep a boolean, default is false.
+ * @since Ant 1.8.0
+ */
+ public void setHandleDirSep(boolean handleDirSep) {
+ this.handleDirSep = handleDirSep;
+ }
+
+ /**
+ * Whether the difference between / and \ (the two common
+ * directory characters) is ignored.
+ *
+ * @since Ant 1.8.0
+ */
+ public boolean doesHandledirSep() {
+ return handleDirSep;
+ }
+
+ /**
+ * Return true if this Resource is selected.
+ * @param r the Resource to check.
+ * @return whether the Resource was selected.
+ */
+ public boolean isSelected(Resource r) {
+ String n = r.getName();
+ if (matches(n)) {
+ return true;
+ }
+ String s = r.toString();
+ return s.equals(n) ? false : matches(s);
+ }
+
+ private boolean matches(String name) {
+ if (pattern != null) {
+ return SelectorUtils.match(modify(pattern), modify(name), cs);
+ } else {
+ if (reg == null) {
+ reg = new RegularExpression();
+ reg.setPattern(regex);
+ expression = reg.getRegexp(project);
+ }
+ return expression.matches(modify(name), RegexpUtil.asOptions(cs));
+ }
+ }
+
+ private String modify(String s) {
+ if (s == null || !handleDirSep || s.indexOf("\\") == -1) {
+ return s;
+ }
+ return s.replace('\\', '/');
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/selectors/None.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/selectors/None.java
new file mode 100644
index 00000000..0de86236
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/selectors/None.java
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.resources.selectors;
+
+import java.util.Iterator;
+
+import org.apache.tools.ant.types.Resource;
+
+/**
+ * None ResourceSelector.
+ * @since Ant 1.7
+ */
+public class None
+ extends ResourceSelectorContainer implements ResourceSelector {
+
+ /**
+ * Default constructor.
+ */
+ public None() {
+ }
+
+ /**
+ * Convenience constructor.
+ * @param r the ResourceSelector[] to add.
+ */
+ public None(ResourceSelector[] r) {
+ super(r);
+ }
+
+ /**
+ * Return true if this Resource is selected.
+ * @param r the Resource to check.
+ * @return whether the Resource was selected.
+ */
+ public boolean isSelected(Resource r) {
+ for (Iterator<ResourceSelector> i = getSelectors(); i.hasNext();) {
+ if (i.next().isSelected(r)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/selectors/Not.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/selectors/Not.java
new file mode 100644
index 00000000..dc67da1f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/selectors/Not.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.resources.selectors;
+
+import org.apache.tools.ant.types.Resource;
+
+/**
+ * Not ResourceSelector.
+ * @since Ant 1.7
+ */
+public class Not implements ResourceSelector {
+
+ private ResourceSelector sel;
+
+ /**
+ * Default constructor.
+ */
+ public Not() {
+ }
+
+ /**
+ * Convenience constructor.
+ * @param s the ResourceSelector to negate.
+ */
+ public Not(ResourceSelector s) {
+ add(s);
+ }
+
+ /**
+ * Set the ResourceSelector.
+ * @param s the ResourceSelector to negate.
+ * @throws IllegalStateException if already set.
+ */
+ public void add(ResourceSelector s) {
+ if (sel != null) {
+ throw new IllegalStateException(
+ "The Not ResourceSelector accepts a single nested ResourceSelector");
+ }
+ sel = s;
+ }
+
+ /**
+ * Return true if this Resource is selected.
+ * @param r the Resource to check.
+ * @return whether the Resource was selected.
+ */
+ public boolean isSelected(Resource r) {
+ return !(sel.isSelected(r));
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/selectors/Or.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/selectors/Or.java
new file mode 100644
index 00000000..b22303a4
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/selectors/Or.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.resources.selectors;
+
+import java.util.Iterator;
+
+import org.apache.tools.ant.types.Resource;
+
+/**
+ * Or ResourceSelector.
+ * @since Ant 1.7
+ */
+public class Or extends ResourceSelectorContainer implements ResourceSelector {
+
+ /**
+ * Default constructor.
+ */
+ public Or() {
+ }
+
+ /**
+ * Convenience constructor.
+ * @param r the ResourceSelector[] to add.
+ */
+ public Or(ResourceSelector[] r) {
+ super(r);
+ }
+
+ /**
+ * Return true if this Resource is selected.
+ * @param r the Resource to check.
+ * @return whether the Resource was selected.
+ */
+ public boolean isSelected(Resource r) {
+ for (Iterator<ResourceSelector> i = getSelectors(); i.hasNext();) {
+ if (i.next().isSelected(r)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/selectors/ResourceSelector.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/selectors/ResourceSelector.java
new file mode 100644
index 00000000..37151ecd
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/selectors/ResourceSelector.java
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.resources.selectors;
+
+import org.apache.tools.ant.types.Resource;
+
+/**
+ * Interface for a Resource selector.
+ * @since Ant 1.7
+ */
+public interface ResourceSelector {
+
+ /**
+ * Return true if this Resource is selected.
+ * @param r the Resource to check.
+ * @return whether the Resource was selected.
+ */
+ boolean isSelected(Resource r);
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/selectors/ResourceSelectorContainer.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/selectors/ResourceSelectorContainer.java
new file mode 100644
index 00000000..6b1c8002
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/selectors/ResourceSelectorContainer.java
@@ -0,0 +1,128 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.resources.selectors;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Stack;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.DataType;
+
+/**
+ * ResourceSelector container.
+ * @since Ant 1.7
+ */
+public class ResourceSelectorContainer extends DataType {
+
+ private final List<ResourceSelector> resourceSelectors = new ArrayList<ResourceSelector>();
+
+ /**
+ * Default constructor.
+ */
+ public ResourceSelectorContainer() {
+ }
+
+ /**
+ * Construct a new ResourceSelectorContainer with the specified array of selectors.
+ * @param r the ResourceSelector[] to add.
+ */
+ public ResourceSelectorContainer(ResourceSelector[] r) {
+ for (int i = 0; i < r.length; i++) {
+ add(r[i]);
+ }
+ }
+
+ /**
+ * Add a ResourceSelector to the container.
+ * @param s the ResourceSelector to add.
+ */
+ public void add(ResourceSelector s) {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ if (s == null) {
+ return;
+ }
+ resourceSelectors.add(s);
+ setChecked(false);
+ }
+
+ /**
+ * Learn whether this ResourceSelectorContainer has selectors.
+ * @return boolean indicating whether selectors have been added to the container.
+ */
+ public boolean hasSelectors() {
+ if (isReference()) {
+ return ((ResourceSelectorContainer) getCheckedRef()).hasSelectors();
+ }
+ dieOnCircularReference();
+ return !resourceSelectors.isEmpty();
+ }
+
+ /**
+ * Get the count of nested selectors.
+ * @return the selector count as int.
+ */
+ public int selectorCount() {
+ if (isReference()) {
+ return ((ResourceSelectorContainer) getCheckedRef()).selectorCount();
+ }
+ dieOnCircularReference();
+ return resourceSelectors.size();
+ }
+
+ /**
+ * Return an Iterator over the nested selectors.
+ * @return Iterator of ResourceSelectors.
+ */
+ public Iterator<ResourceSelector> getSelectors() {
+ if (isReference()) {
+ return ((ResourceSelectorContainer) getCheckedRef()).getSelectors();
+ }
+ dieOnCircularReference();
+ return Collections.unmodifiableList(resourceSelectors).iterator();
+ }
+
+ /**
+ * Overrides the version from DataType to recurse on nested ResourceSelectors.
+ * @param stk the Stack of references.
+ * @param p the Project to resolve against.
+ * @throws BuildException on error.
+ */
+ protected void dieOnCircularReference(Stack<Object> stk, Project p)
+ throws BuildException {
+ if (isChecked()) {
+ return;
+ }
+ if (isReference()) {
+ super.dieOnCircularReference(stk, p);
+ } else {
+ for (ResourceSelector resourceSelector : resourceSelectors) {
+ if (resourceSelector instanceof DataType) {
+ pushAndInvokeCircularReferenceCheck((DataType) resourceSelector, stk, p);
+ }
+ }
+ setChecked(true);
+ }
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/selectors/Size.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/selectors/Size.java
new file mode 100644
index 00000000..4d6c87e2
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/selectors/Size.java
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.resources.selectors;
+
+import org.apache.tools.ant.types.Comparison;
+import org.apache.tools.ant.types.Resource;
+
+/**
+ * Size ResourceSelector.
+ * @since Ant 1.7
+ */
+public class Size implements ResourceSelector {
+ private long size = -1;
+ private Comparison when = Comparison.EQUAL;
+
+ /**
+ * Set the size to compare against.
+ * @param l the long resource size.
+ */
+ public void setSize(long l) {
+ size = l;
+ }
+
+ /**
+ * Get the size compared to by this Size ResourceSelector.
+ * @return the long resource size.
+ */
+ public long getSize() {
+ return size;
+ }
+
+ /**
+ * Set the comparison mode.
+ * @param c a Comparison object.
+ */
+ public void setWhen(Comparison c) {
+ when = c;
+ }
+
+ /**
+ * Get the comparison mode.
+ * @return a Comparison object.
+ */
+ public Comparison getWhen() {
+ return when;
+ }
+
+ /**
+ * Return true if this Resource is selected.
+ * @param r the Resource to check.
+ * @return whether the Resource was selected.
+ */
+ public boolean isSelected(Resource r) {
+ long diff = r.getSize() - size;
+ return when.evaluate(diff == 0 ? 0 : (int) (diff / Math.abs(diff)));
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/selectors/Type.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/selectors/Type.java
new file mode 100644
index 00000000..65d4a577
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/resources/selectors/Type.java
@@ -0,0 +1,110 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.resources.selectors;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.types.EnumeratedAttribute;
+import org.apache.tools.ant.types.Resource;
+
+/**
+ * Type file/dir ResourceSelector.
+ * @since Ant 1.7
+ */
+public class Type implements ResourceSelector {
+
+ private static final String FILE_ATTR = "file";
+ private static final String DIR_ATTR = "dir";
+ private static final String ANY_ATTR = "any";
+
+ /** Static file type selector. */
+ public static final Type FILE = new Type(new FileDir(FILE_ATTR));
+
+ /** Static dir type selector. */
+ public static final Type DIR = new Type(new FileDir(DIR_ATTR));
+
+ /** Static any type selector. Since Ant 1.8. */
+ public static final Type ANY = new Type(new FileDir(ANY_ATTR));
+
+ /**
+ * Implements the type attribute.
+ */
+ public static class FileDir extends EnumeratedAttribute {
+ private static final String[] VALUES = new String[] {FILE_ATTR, DIR_ATTR, ANY_ATTR};
+
+ /**
+ * Default constructor.
+ */
+ public FileDir() {
+ }
+
+ /**
+ * Convenience constructor.
+ * @param value the String EnumeratedAttribute value.
+ */
+ public FileDir(final String value) {
+ setValue(value);
+ }
+
+ /**
+ * Return the possible values.
+ * @return a String array.
+ */
+ @Override
+ public String[] getValues() {
+ return VALUES;
+ }
+ }
+
+ private FileDir type = null;
+
+ /**
+ * Default constructor.
+ */
+ public Type() {
+ }
+
+ /**
+ * Convenience constructor.
+ * @param fd the FileDir type.
+ */
+ public Type(final FileDir fd) {
+ setType(fd);
+ }
+
+ /**
+ * Set type; file|dir.
+ * @param fd a FileDir object.
+ */
+ public void setType(final FileDir fd) {
+ type = fd;
+ }
+
+ /**
+ * Return true if this Resource is selected.
+ * @param r the Resource to check.
+ * @return whether the Resource was selected.
+ */
+ public boolean isSelected(final Resource r) {
+ if (type == null) {
+ throw new BuildException("The type attribute is required.");
+ }
+ final int i = type.getIndex();
+ return i == 2 || (r.isDirectory() ? i == 1 : i == 0);
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/AbstractSelectorContainer.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/AbstractSelectorContainer.java
new file mode 100644
index 00000000..b80816da
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/AbstractSelectorContainer.java
@@ -0,0 +1,353 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types.selectors;
+
+import java.util.Enumeration;
+import java.util.Stack;
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.DataType;
+import org.apache.tools.ant.types.selectors.modifiedselector.ModifiedSelector;
+
+/**
+ * This is the a base class a container of selectors - it does
+ * not need do be a selector itself.
+ *
+ * @since 1.7
+ */
+public abstract class AbstractSelectorContainer extends DataType
+ implements Cloneable, SelectorContainer {
+
+ private Vector<FileSelector> selectorsList = new Vector<FileSelector>();
+
+ /**
+ * Indicates whether there are any selectors here.
+ * @return true if there are selectors
+ */
+ public boolean hasSelectors() {
+ if (isReference()) {
+ return ((AbstractSelectorContainer) getCheckedRef()).hasSelectors();
+ }
+ dieOnCircularReference();
+ return !(selectorsList.isEmpty());
+ }
+
+ /**
+ * Gives the count of the number of selectors in this container
+ * @return the number of selectors
+ */
+ public int selectorCount() {
+ if (isReference()) {
+ return ((AbstractSelectorContainer) getCheckedRef()).selectorCount();
+ }
+ dieOnCircularReference();
+ return selectorsList.size();
+ }
+
+ /**
+ * Returns the set of selectors as an array.
+ * @param p the current project
+ * @return an array of selectors
+ */
+ public FileSelector[] getSelectors(Project p) {
+ if (isReference()) {
+ return ((AbstractSelectorContainer) getCheckedRef(p))
+ .getSelectors(p);
+ }
+ dieOnCircularReference(p);
+ FileSelector[] result = new FileSelector[selectorsList.size()];
+ selectorsList.copyInto(result);
+ return result;
+ }
+
+ /**
+ * Returns an enumerator for accessing the set of selectors.
+ * @return an enumerator for the selectors
+ */
+ public Enumeration<FileSelector> selectorElements() {
+ if (isReference()) {
+ return ((AbstractSelectorContainer) getCheckedRef())
+ .selectorElements();
+ }
+ dieOnCircularReference();
+ return selectorsList.elements();
+ }
+
+ /**
+ * Convert the Selectors within this container to a string. This will
+ * just be a helper class for the subclasses that put their own name
+ * around the contents listed here.
+ *
+ * @return comma separated list of Selectors contained in this one
+ */
+ public String toString() {
+ StringBuilder buf = new StringBuilder();
+ Enumeration<FileSelector> e = selectorElements();
+ if (e.hasMoreElements()) {
+ while (e.hasMoreElements()) {
+ buf.append(e.nextElement().toString());
+ if (e.hasMoreElements()) {
+ buf.append(", ");
+ }
+ }
+ }
+
+ return buf.toString();
+ }
+
+ /**
+ * Add a new selector into this container.
+ *
+ * @param selector the new selector to add
+ */
+ public void appendSelector(FileSelector selector) {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ selectorsList.addElement(selector);
+ setChecked(false);
+ }
+
+ /**
+ * <p>
+ * This validates each contained selector
+ * provided that the selector implements the validate interface.
+ * </p>
+ * <p>Ordinarily, this will validate all the elements of a selector
+ * container even if the isSelected() method of some elements is
+ * never called. This has two effects:</p>
+ * <ul>
+ * <li>Validation will often occur twice.
+ * <li>Since it is not required that selectors derive from
+ * BaseSelector, there could be selectors in the container whose
+ * error conditions are not detected if their isSelected() call
+ * is never made.
+ * </ul>
+ */
+ public void validate() {
+ if (isReference()) {
+ ((AbstractSelectorContainer) getCheckedRef()).validate();
+ }
+ dieOnCircularReference();
+ Enumeration<FileSelector> e = selectorElements();
+ while (e.hasMoreElements()) {
+ Object o = e.nextElement();
+ if (o instanceof BaseSelector) {
+ ((BaseSelector) o).validate();
+ }
+ }
+ }
+
+
+ /* Methods below all add specific selectors */
+
+ /**
+ * add a "Select" selector entry on the selector list
+ * @param selector the selector to add
+ */
+ public void addSelector(SelectSelector selector) {
+ appendSelector(selector);
+ }
+
+ /**
+ * add an "And" selector entry on the selector list
+ * @param selector the selector to add
+ */
+ public void addAnd(AndSelector selector) {
+ appendSelector(selector);
+ }
+
+ /**
+ * add an "Or" selector entry on the selector list
+ * @param selector the selector to add
+ */
+ public void addOr(OrSelector selector) {
+ appendSelector(selector);
+ }
+
+ /**
+ * add a "Not" selector entry on the selector list
+ * @param selector the selector to add
+ */
+ public void addNot(NotSelector selector) {
+ appendSelector(selector);
+ }
+
+ /**
+ * add a "None" selector entry on the selector list
+ * @param selector the selector to add
+ */
+ public void addNone(NoneSelector selector) {
+ appendSelector(selector);
+ }
+
+ /**
+ * add a majority selector entry on the selector list
+ * @param selector the selector to add
+ */
+ public void addMajority(MajoritySelector selector) {
+ appendSelector(selector);
+ }
+
+ /**
+ * add a selector date entry on the selector list
+ * @param selector the selector to add
+ */
+ public void addDate(DateSelector selector) {
+ appendSelector(selector);
+ }
+
+ /**
+ * add a selector size entry on the selector list
+ * @param selector the selector to add
+ */
+ public void addSize(SizeSelector selector) {
+ appendSelector(selector);
+ }
+
+ /**
+ * add a selector filename entry on the selector list
+ * @param selector the selector to add
+ */
+ public void addFilename(FilenameSelector selector) {
+ appendSelector(selector);
+ }
+
+ /**
+ * add an extended selector entry on the selector list
+ * @param selector the selector to add
+ */
+ public void addCustom(ExtendSelector selector) {
+ appendSelector(selector);
+ }
+
+ /**
+ * add a contains selector entry on the selector list
+ * @param selector the selector to add
+ */
+ public void addContains(ContainsSelector selector) {
+ appendSelector(selector);
+ }
+
+ /**
+ * add a present selector entry on the selector list
+ * @param selector the selector to add
+ */
+ public void addPresent(PresentSelector selector) {
+ appendSelector(selector);
+ }
+
+ /**
+ * add a depth selector entry on the selector list
+ * @param selector the selector to add
+ */
+ public void addDepth(DepthSelector selector) {
+ appendSelector(selector);
+ }
+
+ /**
+ * add a depends selector entry on the selector list
+ * @param selector the selector to add
+ */
+ public void addDepend(DependSelector selector) {
+ appendSelector(selector);
+ }
+
+ /**
+ * adds a different selector to the selector list
+ * @param selector the selector to add
+ */
+ public void addDifferent(DifferentSelector selector) {
+ appendSelector(selector);
+ }
+
+ /**
+ * adds a type selector to the selector list
+ * @param selector the selector to add
+ */
+ public void addType(TypeSelector selector) {
+ appendSelector(selector);
+ }
+
+ /**
+ * add a regular expression selector entry on the selector list
+ * @param selector the selector to add
+ */
+ public void addContainsRegexp(ContainsRegexpSelector selector) {
+ appendSelector(selector);
+ }
+
+ /**
+ * add the modified selector
+ * @param selector the selector to add
+ * @since ant 1.6
+ */
+ public void addModified(ModifiedSelector selector) {
+ appendSelector(selector);
+ }
+
+ public void addReadable(ReadableSelector r) {
+ appendSelector(r);
+ }
+
+ public void addWritable(WritableSelector w) {
+ appendSelector(w);
+ }
+
+ /**
+ * add an arbitrary selector
+ * @param selector the selector to add
+ * @since Ant 1.6
+ */
+ public void add(FileSelector selector) {
+ appendSelector(selector);
+ }
+
+ protected synchronized void dieOnCircularReference(Stack<Object> stk, Project p) {
+ if (isChecked()) {
+ return;
+ }
+ if (isReference()) {
+ super.dieOnCircularReference(stk, p);
+ } else {
+ for (FileSelector fileSelector : selectorsList) {
+ if (fileSelector instanceof DataType) {
+ pushAndInvokeCircularReferenceCheck((DataType) fileSelector, stk, p);
+ }
+ }
+ setChecked(true);
+ }
+ }
+
+ public synchronized Object clone() {
+ if (isReference()) {
+ return ((AbstractSelectorContainer) getCheckedRef()).clone();
+ }
+ try {
+ AbstractSelectorContainer sc =
+ (AbstractSelectorContainer) super.clone();
+ sc.selectorsList = new Vector<FileSelector>(selectorsList);
+ return sc;
+ } catch (CloneNotSupportedException e) {
+ throw new BuildException(e);
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/AndSelector.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/AndSelector.java
new file mode 100644
index 00000000..c8e96a04
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/AndSelector.java
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types.selectors;
+
+import java.io.File;
+import java.util.Enumeration;
+
+/**
+ * This selector has a collection of other selectors, all of which have to
+ * select a file in order for this selector to select it.
+ *
+ * @since 1.5
+ */
+public class AndSelector extends BaseSelectorContainer {
+
+ /**
+ * Default constructor.
+ */
+ public AndSelector() {
+ }
+
+ /**
+ * @return a string representation of the selector
+ */
+ public String toString() {
+ StringBuilder buf = new StringBuilder();
+ if (hasSelectors()) {
+ buf.append("{andselect: ");
+ buf.append(super.toString());
+ buf.append("}");
+ }
+ return buf.toString();
+ }
+
+ /**
+ * Returns true (the file is selected) only if all other selectors
+ * agree that the file should be selected.
+ *
+ * @param basedir the base directory the scan is being done from
+ * @param filename the name of the file to check
+ * @param file a java.io.File object for the filename that the selector
+ * can use
+ * @return whether the file should be selected or not
+ */
+ public boolean isSelected(File basedir, String filename, File file) {
+ validate();
+ Enumeration<FileSelector> e = selectorElements();
+
+ while (e.hasMoreElements()) {
+ if (!e.nextElement().isSelected(basedir, filename, file)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/BaseExtendSelector.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/BaseExtendSelector.java
new file mode 100644
index 00000000..f17ca027
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/BaseExtendSelector.java
@@ -0,0 +1,87 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.selectors;
+
+import java.io.File;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.types.Parameter;
+
+/**
+ * Convenience base class for all selectors accessed through ExtendSelector.
+ * It provides support for gathering the parameters together as well as for
+ * assigning an error message and throwing a build exception if an error is
+ * detected.
+ *
+ * @since 1.5
+ */
+public abstract class BaseExtendSelector
+ extends BaseSelector
+ implements ExtendFileSelector {
+
+ // CheckStyle:VisibilityModifier OFF - bc
+
+ /** The passed in parameter array. */
+ protected Parameter[] parameters = null;
+
+ // CheckStyle:VisibilityModifier ON
+
+ /**
+ * Default constructor.
+ */
+ public BaseExtendSelector() {
+ }
+
+ /**
+ * Set all the Parameters for this custom selector, collected by
+ * the ExtendSelector class.
+ *
+ * @param parameters the complete set of parameters for this selector
+ */
+ public void setParameters(Parameter[] parameters) {
+ this.parameters = parameters;
+ }
+
+ /**
+ * Allows access to the parameters gathered and set within the
+ * &lt;custom&gt; tag.
+ *
+ * @return the set of parameters defined for this selector
+ */
+ protected Parameter[] getParameters() {
+ return parameters;
+ }
+
+ /**
+ * Method that each selector will implement to create their
+ * selection behaviour. If there is a problem with the setup
+ * of a selector, it can throw a BuildException to indicate
+ * the problem.
+ *
+ * @param basedir A java.io.File object for the base directory
+ * @param filename The name of the file to check
+ * @param file A File object for this filename
+ * @return whether the file should be selected or not
+ * @exception BuildException if an error occurs
+ */
+ public abstract boolean isSelected(File basedir, String filename,
+ File file)
+ throws BuildException;
+
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/BaseSelector.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/BaseSelector.java
new file mode 100644
index 00000000..61d7a1a2
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/BaseSelector.java
@@ -0,0 +1,113 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types.selectors;
+
+import java.io.File;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.types.DataType;
+
+/**
+ * A convenience base class that you can subclass Selectors from. It
+ * provides some helpful common behaviour. Note that there is no need
+ * for Selectors to inherit from this class, it is only necessary that
+ * they implement FileSelector.
+ *
+ * @since 1.5
+ */
+public abstract class BaseSelector extends DataType implements FileSelector {
+
+ private String errmsg = null;
+
+
+ /**
+ * Do nothing constructor.
+ */
+ public BaseSelector() {
+ }
+
+ /**
+ * Allows all selectors to indicate a setup error. Note that only
+ * the first error message is recorded.
+ *
+ * @param msg The error message any BuildException should throw.
+ */
+ public void setError(String msg) {
+ if (errmsg == null) {
+ errmsg = msg;
+ }
+ }
+
+ /**
+ * Returns any error messages that have been set.
+ *
+ * @return the error condition
+ */
+ public String getError() {
+ return errmsg;
+ }
+
+
+ /**
+ * <p>Subclasses can override this method to provide checking of their
+ * state. So long as they call validate() from isSelected(), this will
+ * be called automatically (unless they override validate()).</p>
+ * <p>Implementations should check for incorrect settings and call
+ * setError() as necessary.</p>
+ */
+ public void verifySettings() {
+ if (isReference()) {
+ ((BaseSelector) getCheckedRef()).verifySettings();
+ }
+ }
+
+
+ /**
+ * Subclasses can use this to throw the requisite exception
+ * in isSelected() in the case of an error condition.
+ */
+ public void validate() {
+ if (getError() == null) {
+ verifySettings();
+ }
+ if (getError() != null) {
+ throw new BuildException(errmsg);
+ }
+ if (!isReference()) {
+ dieOnCircularReference();
+ }
+ }
+
+ /**
+ * Method that each selector will implement to create their
+ * selection behaviour. If there is a problem with the setup
+ * of a selector, it can throw a BuildException to indicate
+ * the problem.
+ *
+ * @param basedir A java.io.File object for the base directory
+ * @param filename The name of the file to check
+ * @param file A File object for this filename
+ * @return whether the file should be selected or not
+ */
+ public abstract boolean isSelected(File basedir, String filename,
+ File file);
+
+}
+
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/BaseSelectorContainer.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/BaseSelectorContainer.java
new file mode 100644
index 00000000..1edf0857
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/BaseSelectorContainer.java
@@ -0,0 +1,343 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types.selectors;
+
+import java.io.File;
+import java.util.Enumeration;
+import java.util.Stack;
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.DataType;
+import org.apache.tools.ant.types.selectors.modifiedselector.ModifiedSelector;
+
+/**
+ * This is the base class for selectors that can contain other selectors.
+ *
+ * @since 1.5
+ */
+public abstract class BaseSelectorContainer extends BaseSelector
+ implements SelectorContainer {
+
+ private Vector<FileSelector> selectorsList = new Vector<FileSelector>();
+
+ /**
+ * Default constructor.
+ */
+ public BaseSelectorContainer() {
+ }
+
+ /**
+ * Indicates whether there are any selectors here.
+ * @return true if there are selectors
+ */
+ public boolean hasSelectors() {
+ dieOnCircularReference();
+ return !(selectorsList.isEmpty());
+ }
+
+ /**
+ * Gives the count of the number of selectors in this container
+ * @return the number of selectors
+ */
+ public int selectorCount() {
+ dieOnCircularReference();
+ return selectorsList.size();
+ }
+
+ /**
+ * Returns the set of selectors as an array.
+ * @param p the current project
+ * @return an array of selectors
+ */
+ public FileSelector[] getSelectors(Project p) {
+ dieOnCircularReference();
+ FileSelector[] result = new FileSelector[selectorsList.size()];
+ selectorsList.copyInto(result);
+ return result;
+ }
+
+ /**
+ * Returns an enumerator for accessing the set of selectors.
+ * @return an enumerator for the selectors
+ */
+ public Enumeration<FileSelector> selectorElements() {
+ dieOnCircularReference();
+ return selectorsList.elements();
+ }
+
+ /**
+ * Convert the Selectors within this container to a string. This will
+ * just be a helper class for the subclasses that put their own name
+ * around the contents listed here.
+ *
+ * @return comma separated list of Selectors contained in this one
+ */
+ public String toString() {
+ dieOnCircularReference();
+ StringBuilder buf = new StringBuilder();
+ Enumeration<FileSelector> e = selectorElements();
+ while (e.hasMoreElements()) {
+ buf.append(e.nextElement().toString());
+ if (e.hasMoreElements()) {
+ buf.append(", ");
+ }
+ }
+ return buf.toString();
+ }
+
+ /**
+ * Add a new selector into this container.
+ *
+ * @param selector the new selector to add
+ */
+ public void appendSelector(FileSelector selector) {
+ selectorsList.addElement(selector);
+ setChecked(false);
+ }
+
+ /**
+ * <p>This implementation validates the container by calling
+ * verifySettings() and then validates each contained selector
+ * provided that the selector implements the validate interface.
+ * </p>
+ * <p>Ordinarily, this will validate all the elements of a selector
+ * container even if the isSelected() method of some elements is
+ * never called. This has two effects:</p>
+ * <ul>
+ * <li>Validation will often occur twice.
+ * <li>Since it is not required that selectors derive from
+ * BaseSelector, there could be selectors in the container whose
+ * error conditions are not detected if their isSelected() call
+ * is never made.
+ * </ul>
+ */
+ public void validate() {
+ verifySettings();
+ dieOnCircularReference();
+ String errmsg = getError();
+ if (errmsg != null) {
+ throw new BuildException(errmsg);
+ }
+ Enumeration<FileSelector> e = selectorElements();
+ while (e.hasMoreElements()) {
+ Object o = e.nextElement();
+ if (o instanceof BaseSelector) {
+ ((BaseSelector) o).validate();
+ }
+ }
+ }
+
+
+ /**
+ * Method that each selector will implement to create their selection
+ * behaviour. This is what makes SelectorContainer abstract.
+ *
+ * @param basedir the base directory the scan is being done from
+ * @param filename the name of the file to check
+ * @param file a java.io.File object for the filename that the selector
+ * can use
+ * @return whether the file should be selected or not
+ */
+ public abstract boolean isSelected(File basedir, String filename,
+ File file);
+
+
+ /* Methods below all add specific selectors */
+
+ /**
+ * add a "Select" selector entry on the selector list
+ * @param selector the selector to add
+ */
+ public void addSelector(SelectSelector selector) {
+ appendSelector(selector);
+ }
+
+ /**
+ * add an "And" selector entry on the selector list
+ * @param selector the selector to add
+ */
+ public void addAnd(AndSelector selector) {
+ appendSelector(selector);
+ }
+
+ /**
+ * add an "Or" selector entry on the selector list
+ * @param selector the selector to add
+ */
+ public void addOr(OrSelector selector) {
+ appendSelector(selector);
+ }
+
+ /**
+ * add a "Not" selector entry on the selector list
+ * @param selector the selector to add
+ */
+ public void addNot(NotSelector selector) {
+ appendSelector(selector);
+ }
+
+ /**
+ * add a "None" selector entry on the selector list
+ * @param selector the selector to add
+ */
+ public void addNone(NoneSelector selector) {
+ appendSelector(selector);
+ }
+
+ /**
+ * add a majority selector entry on the selector list
+ * @param selector the selector to add
+ */
+ public void addMajority(MajoritySelector selector) {
+ appendSelector(selector);
+ }
+
+ /**
+ * add a selector date entry on the selector list
+ * @param selector the selector to add
+ */
+ public void addDate(DateSelector selector) {
+ appendSelector(selector);
+ }
+
+ /**
+ * add a selector size entry on the selector list
+ * @param selector the selector to add
+ */
+ public void addSize(SizeSelector selector) {
+ appendSelector(selector);
+ }
+
+ /**
+ * add a selector filename entry on the selector list
+ * @param selector the selector to add
+ */
+ public void addFilename(FilenameSelector selector) {
+ appendSelector(selector);
+ }
+
+ /**
+ * add an extended selector entry on the selector list
+ * @param selector the selector to add
+ */
+ public void addCustom(ExtendSelector selector) {
+ appendSelector(selector);
+ }
+
+ /**
+ * add a contains selector entry on the selector list
+ * @param selector the selector to add
+ */
+ public void addContains(ContainsSelector selector) {
+ appendSelector(selector);
+ }
+
+ /**
+ * add a present selector entry on the selector list
+ * @param selector the selector to add
+ */
+ public void addPresent(PresentSelector selector) {
+ appendSelector(selector);
+ }
+
+ /**
+ * add a depth selector entry on the selector list
+ * @param selector the selector to add
+ */
+ public void addDepth(DepthSelector selector) {
+ appendSelector(selector);
+ }
+
+ /**
+ * add a depends selector entry on the selector list
+ * @param selector the selector to add
+ */
+ public void addDepend(DependSelector selector) {
+ appendSelector(selector);
+ }
+
+ /**
+ * adds a different selector to the selector list
+ * @param selector the selector to add
+ */
+ public void addDifferent(DifferentSelector selector) {
+ appendSelector(selector);
+ }
+
+ /**
+ * adds a type selector to the selector list
+ * @param selector the selector to add
+ */
+ public void addType(TypeSelector selector) {
+ appendSelector(selector);
+ }
+
+ /**
+ * add a regular expression selector entry on the selector list
+ * @param selector the selector to add
+ */
+ public void addContainsRegexp(ContainsRegexpSelector selector) {
+ appendSelector(selector);
+ }
+
+ /**
+ * add the modified selector
+ * @param selector the selector to add
+ * @since ant 1.6
+ */
+ public void addModified(ModifiedSelector selector) {
+ appendSelector(selector);
+ }
+
+ public void addReadable(ReadableSelector r) {
+ appendSelector(r);
+ }
+
+ public void addWritable(WritableSelector w) {
+ appendSelector(w);
+ }
+
+ /**
+ * add an arbitrary selector
+ * @param selector the selector to add
+ * @since Ant 1.6
+ */
+ public void add(FileSelector selector) {
+ appendSelector(selector);
+ }
+
+ protected synchronized void dieOnCircularReference(Stack<Object> stk, Project p)
+ throws BuildException {
+ if (isChecked()) {
+ return;
+ }
+ if (isReference()) {
+ super.dieOnCircularReference(stk, p);
+ } else {
+ for (FileSelector fileSelector : selectorsList) {
+ if (fileSelector instanceof DataType) {
+ pushAndInvokeCircularReferenceCheck((DataType) fileSelector, stk, p);
+ }
+ }
+ setChecked(true);
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/ContainsRegexpSelector.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/ContainsRegexpSelector.java
new file mode 100644
index 00000000..4da3b6ff
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/ContainsRegexpSelector.java
@@ -0,0 +1,219 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types.selectors;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.Parameter;
+import org.apache.tools.ant.types.RegularExpression;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.resources.FileResource;
+import org.apache.tools.ant.types.resources.selectors.ResourceSelector;
+import org.apache.tools.ant.util.regexp.Regexp;
+import org.apache.tools.ant.util.regexp.RegexpUtil;
+
+/**
+ * Selector that filters files based on a regular expression.
+ *
+ * @since Ant 1.6
+ */
+public class ContainsRegexpSelector extends BaseExtendSelector
+ implements ResourceSelector {
+
+ private String userProvidedExpression = null;
+ private RegularExpression myRegExp = null;
+ private Regexp myExpression = null;
+ private boolean caseSensitive = true;
+ private boolean multiLine = false;
+ private boolean singleLine = false;
+ /** Key to used for parameterized custom selector */
+ public static final String EXPRESSION_KEY = "expression";
+ /** Parameter name for the casesensitive attribute. */
+ private static final String CS_KEY = "casesensitive";
+ /** Parameter name for the multiline attribute. */
+ private static final String ML_KEY = "multiline";
+ /** Parameter name for the singleline attribute. */
+ private static final String SL_KEY = "singleline";
+
+ /**
+ * Creates a new <code>ContainsRegexpSelector</code> instance.
+ */
+ public ContainsRegexpSelector() {
+ }
+
+ /**
+ * @return a string describing this object
+ */
+ public String toString() {
+ StringBuilder buf = new StringBuilder(
+ "{containsregexpselector expression: ");
+ buf.append(userProvidedExpression);
+ buf.append("}");
+ return buf.toString();
+ }
+
+ /**
+ * The regular expression used to search the file.
+ *
+ * @param theexpression this must match a line in the file to be selected.
+ */
+ public void setExpression(String theexpression) {
+ this.userProvidedExpression = theexpression;
+ }
+
+ /**
+ * Whether to ignore case or not.
+ * @param b if false, ignore case.
+ * @since Ant 1.8.2
+ */
+ public void setCaseSensitive(boolean b) {
+ caseSensitive = b;
+ }
+
+ /**
+ * Whether to match should be multiline.
+ * @param b the value to set.
+ * @since Ant 1.8.2
+ */
+ public void setMultiLine(boolean b) {
+ multiLine = b;
+ }
+
+ /**
+ * Whether to treat input as singleline ('.' matches newline).
+ * Corresponds to java.util.regex.Pattern.DOTALL.
+ * @param b the value to set.
+ * @since Ant 1.8.2
+ */
+ public void setSingleLine(boolean b) {
+ singleLine = b;
+ }
+
+ /**
+ * When using this as a custom selector, this method will be called.
+ * It translates each parameter into the appropriate setXXX() call.
+ *
+ * @param parameters the complete set of parameters for this selector
+ */
+ public void setParameters(Parameter[] parameters) {
+ super.setParameters(parameters);
+ if (parameters != null) {
+ for (int i = 0; i < parameters.length; i++) {
+ String paramname = parameters[i].getName();
+ if (EXPRESSION_KEY.equalsIgnoreCase(paramname)) {
+ setExpression(parameters[i].getValue());
+ } else if (CS_KEY.equalsIgnoreCase(paramname)) {
+ setCaseSensitive(Project
+ .toBoolean(parameters[i].getValue()));
+ } else if (ML_KEY.equalsIgnoreCase(paramname)) {
+ setMultiLine(Project.toBoolean(parameters[i].getValue()));
+ } else if (SL_KEY.equalsIgnoreCase(paramname)) {
+ setSingleLine(Project.toBoolean(parameters[i].getValue()));
+ } else {
+ setError("Invalid parameter " + paramname);
+ }
+ }
+ }
+ }
+
+ /**
+ * Checks that an expression was specified.
+ *
+ */
+ public void verifySettings() {
+ if (userProvidedExpression == null) {
+ setError("The expression attribute is required");
+ }
+ }
+
+ /**
+ * Tests a regular expression against each line of text in the file.
+ *
+ * @param basedir the base directory the scan is being done from
+ * @param filename is the name of the file to check
+ * @param file is a java.io.File object the selector can use
+ * @return whether the file should be selected or not
+ */
+ public boolean isSelected(File basedir, String filename, File file) {
+ return isSelected(new FileResource(file));
+ }
+
+ /**
+ * Tests a regular expression against each line of text in a Resource.
+ *
+ * @param r the Resource to check.
+ * @return whether the Resource is selected or not
+ */
+ public boolean isSelected(Resource r) {
+ String teststr = null;
+ BufferedReader in = null;
+
+ // throw BuildException on error
+
+ validate();
+
+ if (r.isDirectory()) {
+ return true;
+ }
+
+ if (myRegExp == null) {
+ myRegExp = new RegularExpression();
+ myRegExp.setPattern(userProvidedExpression);
+ myExpression = myRegExp.getRegexp(getProject());
+ }
+
+ try {
+ in = new BufferedReader(new InputStreamReader(r.getInputStream()));
+ } catch (Exception e) {
+ throw new BuildException("Could not get InputStream from "
+ + r.toLongString(), e);
+ }
+ try {
+ teststr = in.readLine();
+
+ while (teststr != null) {
+
+ if (myExpression.matches(teststr,
+ RegexpUtil.asOptions(caseSensitive,
+ multiLine,
+ singleLine))) {
+ return true;
+ }
+ teststr = in.readLine();
+ }
+
+ return false;
+ } catch (IOException ioe) {
+ throw new BuildException("Could not read " + r.toLongString());
+ } finally {
+ try {
+ in.close();
+ } catch (Exception e) {
+ throw new BuildException("Could not close "
+ + r.toLongString());
+ }
+ }
+ }
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/ContainsSelector.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/ContainsSelector.java
new file mode 100644
index 00000000..6dabaf4c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/ContainsSelector.java
@@ -0,0 +1,221 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types.selectors;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.Parameter;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.resources.FileResource;
+import org.apache.tools.ant.types.resources.selectors.ResourceSelector;
+import org.apache.tools.ant.util.FileUtils;
+
+/**
+ * Selector that filters files/resources based on whether they contain a
+ * particular string.
+ *
+ * @since 1.5
+ */
+public class ContainsSelector extends BaseExtendSelector implements ResourceSelector {
+
+ private String contains = null;
+ private boolean casesensitive = true;
+ private boolean ignorewhitespace = false;
+ private String encoding = null;
+ /** Key to used for parameterized custom selector */
+ public static final String EXPRESSION_KEY = "expression";
+ /** Used for parameterized custom selector */
+ public static final String CONTAINS_KEY = "text";
+ /** Used for parameterized custom selector */
+ public static final String CASE_KEY = "casesensitive";
+ /** Used for parameterized custom selector */
+ public static final String WHITESPACE_KEY = "ignorewhitespace";
+
+
+ /**
+ * Creates a new <code>ContainsSelector</code> instance.
+ *
+ */
+ public ContainsSelector() {
+ }
+
+ /**
+ * @return a string describing this object
+ */
+ public String toString() {
+ StringBuilder buf = new StringBuilder("{containsselector text: ");
+ buf.append('"').append(contains).append('"');
+ buf.append(" casesensitive: ");
+ buf.append(casesensitive ? "true" : "false");
+ buf.append(" ignorewhitespace: ");
+ buf.append(ignorewhitespace ? "true" : "false");
+ buf.append("}");
+ return buf.toString();
+ }
+
+ /**
+ * The string to search for within a file.
+ *
+ * @param contains the string that a file must contain to be selected.
+ */
+ public void setText(String contains) {
+ this.contains = contains;
+ }
+
+ /**
+ * The encoding of the resources processed
+ * @since Ant 1.9.0
+ * @param encoding encoding of the resources processed
+ */
+ public void setEncoding(String encoding) {
+ this.encoding = encoding;
+ }
+
+ /**
+ * Whether to ignore case in the string being searched.
+ *
+ * @param casesensitive whether to pay attention to case sensitivity
+ */
+ public void setCasesensitive(boolean casesensitive) {
+ this.casesensitive = casesensitive;
+ }
+
+ /**
+ * Whether to ignore whitespace in the string being searched.
+ *
+ * @param ignorewhitespace whether to ignore any whitespace
+ * (spaces, tabs, etc.) in the searchstring
+ */
+ public void setIgnorewhitespace(boolean ignorewhitespace) {
+ this.ignorewhitespace = ignorewhitespace;
+ }
+
+ /**
+ * When using this as a custom selector, this method will be called.
+ * It translates each parameter into the appropriate setXXX() call.
+ *
+ * @param parameters the complete set of parameters for this selector
+ */
+ public void setParameters(Parameter[] parameters) {
+ super.setParameters(parameters);
+ if (parameters != null) {
+ for (int i = 0; i < parameters.length; i++) {
+ String paramname = parameters[i].getName();
+ if (CONTAINS_KEY.equalsIgnoreCase(paramname)) {
+ setText(parameters[i].getValue());
+ } else if (CASE_KEY.equalsIgnoreCase(paramname)) {
+ setCasesensitive(Project.toBoolean(
+ parameters[i].getValue()));
+ } else if (WHITESPACE_KEY.equalsIgnoreCase(paramname)) {
+ setIgnorewhitespace(Project.toBoolean(
+ parameters[i].getValue()));
+ } else {
+ setError("Invalid parameter " + paramname);
+ }
+ }
+ }
+ }
+
+ /**
+ * Checks to make sure all settings are kosher. In this case, it
+ * means that the pattern attribute has been set.
+ *
+ */
+ public void verifySettings() {
+ if (contains == null) {
+ setError("The text attribute is required");
+ }
+ }
+
+ /**
+ * The heart of the matter. This is where the selector gets to decide
+ * on the inclusion of a file in a particular fileset.
+ *
+ * @param basedir the base directory the scan is being done from
+ * @param filename is the name of the file to check
+ * @param file is a java.io.File object the selector can use
+ * @return whether the file should be selected or not
+ */
+ public boolean isSelected(File basedir, String filename, File file) {
+ return isSelected(new FileResource(file));
+ }
+
+ /**
+ * The heart of the matter. This is where the selector gets to decide
+ * on the inclusion of a Resource.
+ *
+ * @param r the Resource to check.
+ * @return whether the Resource is selected.
+ */
+ public boolean isSelected(Resource r) {
+
+ // throw BuildException on error
+ validate();
+
+ if (r.isDirectory() || contains.length() == 0) {
+ return true;
+ }
+
+ String userstr = contains;
+ if (!casesensitive) {
+ userstr = contains.toLowerCase();
+ }
+ if (ignorewhitespace) {
+ userstr = SelectorUtils.removeWhitespace(userstr);
+ }
+ BufferedReader in = null;
+ try {
+ if (encoding != null) {
+ in = new BufferedReader(new InputStreamReader(r.getInputStream(), encoding));
+ } else {
+ in = new BufferedReader(new InputStreamReader(r.getInputStream()));
+ }
+ } catch (Exception e) {
+ throw new BuildException("Could not get InputStream from "
+ + r.toLongString(), e);
+ }
+ try {
+ String teststr = in.readLine();
+ while (teststr != null) {
+ if (!casesensitive) {
+ teststr = teststr.toLowerCase();
+ }
+ if (ignorewhitespace) {
+ teststr = SelectorUtils.removeWhitespace(teststr);
+ }
+ if (teststr.indexOf(userstr) > -1) {
+ return true;
+ }
+ teststr = in.readLine();
+ }
+ return false;
+ } catch (IOException ioe) {
+ throw new BuildException("Could not read " + r.toLongString());
+ } finally {
+ FileUtils.close(in);
+ }
+ }
+
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/DateSelector.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/DateSelector.java
new file mode 100644
index 00000000..aea94a8b
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/DateSelector.java
@@ -0,0 +1,260 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types.selectors;
+
+import java.io.File;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Locale;
+
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.Parameter;
+import org.apache.tools.ant.types.TimeComparison;
+import org.apache.tools.ant.util.FileUtils;
+
+/**
+ * Selector that chooses files based on their last modified date.
+ *
+ * @since 1.5
+ */
+public class DateSelector extends BaseExtendSelector {
+
+ /** Utilities used for file operations */
+ private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+
+ private long millis = -1;
+ private String dateTime = null;
+ private boolean includeDirs = false;
+ private long granularity = 0;
+ private String pattern;
+ private TimeComparison when = TimeComparison.EQUAL;
+
+ /** Key to used for parameterized custom selector */
+ public static final String MILLIS_KEY = "millis";
+ /** Key to used for parameterized custom selector */
+ public static final String DATETIME_KEY = "datetime";
+ /** Key to used for parameterized custom selector */
+ public static final String CHECKDIRS_KEY = "checkdirs";
+ /** Key to used for parameterized custom selector */
+ public static final String GRANULARITY_KEY = "granularity";
+ /** Key to used for parameterized custom selector */
+ public static final String WHEN_KEY = "when";
+ /** Key to used for parameterized custom selector */
+ public static final String PATTERN_KEY = "pattern";
+
+ /**
+ * Creates a new <code>DateSelector</code> instance.
+ *
+ */
+ public DateSelector() {
+ granularity = FILE_UTILS.getFileTimestampGranularity();
+ }
+
+ /**
+ * @return a string describing this object
+ */
+ public String toString() {
+ StringBuilder buf = new StringBuilder("{dateselector date: ");
+ buf.append(dateTime);
+ buf.append(" compare: ").append(when.getValue());
+ buf.append(" granularity: ");
+ buf.append(granularity);
+ if (pattern != null) {
+ buf.append(" pattern: ").append(pattern);
+ }
+ buf.append("}");
+ return buf.toString();
+ }
+
+ /**
+ * Set the time; for users who prefer to express time in ms since 1970.
+ *
+ * @param millis the time to compare file's last modified date to,
+ * expressed in milliseconds.
+ */
+ public void setMillis(long millis) {
+ this.millis = millis;
+ }
+
+ /**
+ * Returns the millisecond value the selector is set for.
+ * @return the millisecond value.
+ */
+ public long getMillis() {
+ if (dateTime != null) {
+ validate();
+ }
+ return millis;
+ }
+
+ /**
+ * Sets the date. The user must supply it in MM/DD/YYYY HH:MM AM_PM format,
+ * unless an alternate pattern is specified via the pattern attribute.
+ *
+ * @param dateTime a formatted date <code>String</code>.
+ */
+ public void setDatetime(String dateTime) {
+ this.dateTime = dateTime;
+ millis = -1;
+ }
+
+ /**
+ * Set whether to check dates on directories.
+ *
+ * @param includeDirs whether to check the timestamp on directories.
+ */
+ public void setCheckdirs(boolean includeDirs) {
+ this.includeDirs = includeDirs;
+ }
+
+ /**
+ * Sets the number of milliseconds leeway we will give before we consider
+ * a file not to have matched a date.
+ * @param granularity the number of milliseconds leeway.
+ */
+ public void setGranularity(int granularity) {
+ this.granularity = granularity;
+ }
+
+ /**
+ * Sets the type of comparison to be done on the file's last modified
+ * date.
+ *
+ * @param tcmp The comparison to perform, an EnumeratedAttribute.
+ */
+ public void setWhen(TimeComparisons tcmp) {
+ setWhen((TimeComparison) tcmp);
+ }
+
+ /**
+ * Set the comparison type.
+ * @param t TimeComparison object.
+ */
+ public void setWhen(TimeComparison t) {
+ when = t;
+ }
+
+ /**
+ * Sets the pattern to be used for the SimpleDateFormat.
+ *
+ * @param pattern the pattern that defines the date format.
+ */
+ public void setPattern(String pattern) {
+ this.pattern = pattern;
+ }
+
+ /**
+ * When using this as a custom selector, this method will be called.
+ * It translates each parameter into the appropriate setXXX() call.
+ *
+ * @param parameters the complete set of parameters for this selector.
+ */
+ public void setParameters(Parameter[] parameters) {
+ super.setParameters(parameters);
+ if (parameters != null) {
+ for (int i = 0; i < parameters.length; i++) {
+ String paramname = parameters[i].getName();
+ if (MILLIS_KEY.equalsIgnoreCase(paramname)) {
+ try {
+ setMillis(Long.parseLong(parameters[i].getValue()));
+ } catch (NumberFormatException nfe) {
+ setError("Invalid millisecond setting "
+ + parameters[i].getValue());
+ }
+ } else if (DATETIME_KEY.equalsIgnoreCase(paramname)) {
+ setDatetime(parameters[i].getValue());
+ } else if (CHECKDIRS_KEY.equalsIgnoreCase(paramname)) {
+ setCheckdirs(Project.toBoolean(parameters[i].getValue()));
+ } else if (GRANULARITY_KEY.equalsIgnoreCase(paramname)) {
+ try {
+ setGranularity(Integer.parseInt(parameters[i].getValue()));
+ } catch (NumberFormatException nfe) {
+ setError("Invalid granularity setting "
+ + parameters[i].getValue());
+ }
+ } else if (WHEN_KEY.equalsIgnoreCase(paramname)) {
+ setWhen(new TimeComparison(parameters[i].getValue()));
+ } else if (PATTERN_KEY.equalsIgnoreCase(paramname)) {
+ setPattern(parameters[i].getValue());
+ } else {
+ setError("Invalid parameter " + paramname);
+ }
+ }
+ }
+ }
+
+ /**
+ * This is a consistency check to ensure the selector's required
+ * values have been set.
+ */
+ public void verifySettings() {
+ if (dateTime == null && millis < 0) {
+ setError("You must provide a datetime or the number of "
+ + "milliseconds.");
+ } else if (millis < 0 && dateTime != null) {
+ // check millis and only set it once.
+ DateFormat df = ((pattern == null)
+ ? DateFormat.getDateTimeInstance(
+ DateFormat.SHORT, DateFormat.SHORT, Locale.US)
+ : new SimpleDateFormat(pattern));
+
+ try {
+ setMillis(df.parse(dateTime).getTime());
+ if (millis < 0) {
+ setError("Date of " + dateTime
+ + " results in negative milliseconds value"
+ + " relative to epoch (January 1, 1970, 00:00:00 GMT).");
+ }
+ } catch (ParseException pe) {
+ setError("Date of " + dateTime
+ + " Cannot be parsed correctly. It should be in"
+ + ((pattern == null)
+ ? " MM/DD/YYYY HH:MM AM_PM" : pattern) + " format.");
+ }
+ }
+ }
+
+ /**
+ * The heart of the matter. This is where the selector gets to decide
+ * on the inclusion of a file in a particular fileset.
+ *
+ * @param basedir the base directory from which the scan is being performed.
+ * @param filename is the name of the file to check.
+ * @param file is a java.io.File object the selector can use.
+ * @return whether the file is selected.
+ */
+ public boolean isSelected(File basedir, String filename, File file) {
+
+ validate();
+
+ return (file.isDirectory() && !includeDirs)
+ || when.evaluate(file.lastModified(), millis, granularity);
+ }
+
+ /**
+ * Enumerated attribute with the values for time comparison.
+ * <p>
+ */
+ public static class TimeComparisons extends TimeComparison {
+ }
+
+}
+
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/DependSelector.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/DependSelector.java
new file mode 100644
index 00000000..01ac2379
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/DependSelector.java
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types.selectors;
+
+import java.io.File;
+
+/**
+ * Selector that filters files based on whether they are newer than
+ * a matching file in another directory tree. It can contain a mapper
+ * element, so isn't available as an ExtendSelector (since those
+ * parameters can't hold other elements).
+ *
+ * @since 1.5
+ */
+public class DependSelector extends MappingSelector {
+
+ /**
+ * Creates a new <code>DependSelector</code> instance.
+ *
+ */
+ public DependSelector() {
+
+ }
+
+ /**
+ * @return a string describing this object
+ */
+ public String toString() {
+ StringBuilder buf = new StringBuilder("{dependselector targetdir: ");
+ if (targetdir == null) {
+ buf.append("NOT YET SET");
+ } else {
+ buf.append(targetdir.getName());
+ }
+ buf.append(" granularity: ");
+ buf.append(granularity);
+ if (map != null) {
+ buf.append(" mapper: ");
+ buf.append(map.toString());
+ } else if (mapperElement != null) {
+ buf.append(" mapper: ");
+ buf.append(mapperElement.toString());
+ }
+ buf.append("}");
+ return buf.toString();
+ }
+
+
+ /**
+ * this test is our selection test that compared the file with the destfile
+ * @param srcfile the source file
+ * @param destfile the destination file
+ * @return true if destination is out of date
+ */
+ public boolean selectionTest(File srcfile, File destfile) {
+ boolean selected = SelectorUtils.isOutOfDate(srcfile, destfile,
+ granularity);
+ return selected;
+ }
+
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/DepthSelector.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/DepthSelector.java
new file mode 100644
index 00000000..a80f9aa9
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/DepthSelector.java
@@ -0,0 +1,185 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types.selectors;
+
+import java.io.File;
+import java.util.StringTokenizer;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.types.Parameter;
+
+/**
+ * Selector that filters files based on the how deep in the directory
+ * tree they are.
+ *
+ * @since 1.5
+ */
+public class DepthSelector extends BaseExtendSelector {
+
+ // CheckStyle:VisibilityModifier OFF - bc
+
+ /** min attribute */
+ public int min = -1;
+ /** max attribute */
+ public int max = -1;
+
+ // CheckStyle:VisibilityModifier ON
+
+ /** Used for parameterized custom selector */
+ public static final String MIN_KEY = "min";
+ /** Used for parameterized custom selector */
+ public static final String MAX_KEY = "max";
+
+ /**
+ * Creates a new <code>DepthSelector</code> instance.
+ *
+ */
+ public DepthSelector() {
+ }
+
+ /**
+ * @return a string describing this object
+ */
+ public String toString() {
+ StringBuilder buf = new StringBuilder("{depthselector min: ");
+ buf.append(min);
+ buf.append(" max: ");
+ buf.append(max);
+ buf.append("}");
+ return buf.toString();
+ }
+
+ /**
+ * The minimum depth below the basedir before a file is selected.
+ *
+ * @param min minimum directory levels below basedir to go
+ */
+ public void setMin(int min) {
+ this.min = min;
+ }
+
+ /**
+ * The minimum depth below the basedir before a file is selected.
+ *
+ * @param max maximum directory levels below basedir to go
+ */
+ public void setMax(int max) {
+ this.max = max;
+ }
+
+ /**
+ * When using this as a custom selector, this method will be called.
+ * It translates each parameter into the appropriate setXXX() call.
+ *
+ * @param parameters the complete set of parameters for this selector
+ */
+ public void setParameters(Parameter[] parameters) {
+ super.setParameters(parameters);
+ if (parameters != null) {
+ for (int i = 0; i < parameters.length; i++) {
+ String paramname = parameters[i].getName();
+ if (MIN_KEY.equalsIgnoreCase(paramname)) {
+ try {
+ setMin(Integer.parseInt(parameters[i].getValue()));
+ } catch (NumberFormatException nfe1) {
+ setError("Invalid minimum value "
+ + parameters[i].getValue());
+ }
+ } else if (MAX_KEY.equalsIgnoreCase(paramname)) {
+ try {
+ setMax(Integer.parseInt(parameters[i].getValue()));
+ } catch (NumberFormatException nfe1) {
+ setError("Invalid maximum value "
+ + parameters[i].getValue());
+ }
+ } else {
+ setError("Invalid parameter " + paramname);
+ }
+ }
+ }
+ }
+
+ /**
+ * Checks to make sure all settings are kosher. In this case, it
+ * means that the max depth is not lower than the min depth.
+ */
+ public void verifySettings() {
+ if (min < 0 && max < 0) {
+ setError("You must set at least one of the min or the "
+ + "max levels.");
+ }
+ if (max < min && max > -1) {
+ setError("The maximum depth is lower than the minimum.");
+ }
+ }
+
+ /**
+ * The heart of the matter. This is where the selector gets to decide
+ * on the inclusion of a file in a particular fileset. Most of the work
+ * for this selector is offloaded into SelectorUtils, a static class
+ * that provides the same services for both FilenameSelector and
+ * DirectoryScanner.
+ *
+ * @param basedir the base directory the scan is being done from
+ * @param filename is the name of the file to check
+ * @param file is a java.io.File object the selector can use
+ * @return whether the file should be selected or not
+ */
+ public boolean isSelected(File basedir, String filename, File file) {
+
+ // throw BuildException on error
+ validate();
+
+ int depth = -1;
+ // If you felt daring, you could cache the basedir absolute path
+ String absBase = basedir.getAbsolutePath();
+ String absFile = file.getAbsolutePath();
+ StringTokenizer tokBase = new StringTokenizer(absBase,
+ File.separator);
+ StringTokenizer tokFile = new StringTokenizer(absFile,
+ File.separator);
+ while (tokFile.hasMoreTokens()) {
+ String filetoken = tokFile.nextToken();
+ if (tokBase.hasMoreTokens()) {
+ String basetoken = tokBase.nextToken();
+ // Sanity check. Ditch it if you want faster performance
+ if (!basetoken.equals(filetoken)) {
+ throw new BuildException("File " + filename
+ + " does not appear within " + absBase
+ + "directory");
+ }
+ } else {
+ depth += 1;
+ if (max > -1 && depth > max) {
+ return false;
+ }
+ }
+ }
+ if (tokBase.hasMoreTokens()) {
+ throw new BuildException("File " + filename
+ + " is outside of " + absBase + "directory tree");
+ }
+ if (min > -1 && depth < min) {
+ return false;
+ }
+ return true;
+ }
+
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/DifferentSelector.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/DifferentSelector.java
new file mode 100644
index 00000000..c701fb84
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/DifferentSelector.java
@@ -0,0 +1,114 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types.selectors;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.util.FileUtils;
+
+/**
+ * This selector selects files against a mapped set of target files, selecting
+ * all those files which are different.
+ * Files with different lengths are deemed different
+ * automatically
+ * Files with identical timestamps are viewed as matching by
+ * default, unless you specify otherwise.
+ * Contents are compared if the lengths are the same
+ * and the timestamps are ignored or the same,
+ * except if you decide to ignore contents to gain speed.
+ * <p>
+ * This is a useful selector to work with programs and tasks that don't handle
+ * dependency checking properly; Even if a predecessor task always creates its
+ * output files, followup tasks can be driven off copies made with a different
+ * selector, so their dependencies are driven on the absolute state of the
+ * files, not a timestamp.
+ * <p>
+ * Clearly, however, bulk file comparisons is inefficient; anything that can
+ * use timestamps is to be preferred. If this selector must be used, use it
+ * over as few files as possible, perhaps following it with an &lt;uptodate;&gt
+ * to keep the descendant routines conditional.
+ *
+ */
+public class DifferentSelector extends MappingSelector {
+
+ private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+
+ private boolean ignoreFileTimes = true;
+ private boolean ignoreContents = false;
+
+
+ /**
+ * This flag tells the selector to ignore file times in the comparison
+ * @param ignoreFileTimes if true ignore file times
+ */
+ public void setIgnoreFileTimes(boolean ignoreFileTimes) {
+ this.ignoreFileTimes = ignoreFileTimes;
+ }
+ /**
+ * This flag tells the selector to ignore contents
+ * @param ignoreContents if true ignore contents
+ * @since ant 1.6.3
+ */
+ public void setIgnoreContents(boolean ignoreContents) {
+ this.ignoreContents = ignoreContents;
+ }
+ /**
+ * this test is our selection test that compared the file with the destfile
+ * @param srcfile the source file
+ * @param destfile the destination file
+ * @return true if the files are different
+ */
+ protected boolean selectionTest(File srcfile, File destfile) {
+
+ //if either of them is missing, they are different
+ if (srcfile.exists() != destfile.exists()) {
+ return true;
+ }
+
+ if (srcfile.length() != destfile.length()) {
+ // different size =>different files
+ return true;
+ }
+
+ if (!ignoreFileTimes) {
+ //same date if dest timestamp is within granularity of the srcfile
+ boolean sameDate;
+ sameDate = destfile.lastModified() >= srcfile.lastModified() - granularity
+ && destfile.lastModified() <= srcfile.lastModified() + granularity;
+
+ // different dates => different files
+ if (!sameDate) {
+ return true;
+ }
+ }
+ if (!ignoreContents) {
+ //here do a bulk comparison
+ try {
+ return !FILE_UTILS.contentEquals(srcfile, destfile);
+ } catch (IOException e) {
+ throw new BuildException("while comparing " + srcfile + " and "
+ + destfile, e);
+ }
+ } else {
+ return false;
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/ExtendFileSelector.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/ExtendFileSelector.java
new file mode 100644
index 00000000..fe974065
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/ExtendFileSelector.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types.selectors;
+
+import org.apache.tools.ant.types.Parameterizable;
+
+/**
+ * This is the interface to be used by all custom selectors, those that are
+ * called through the &lt;custom&gt; tag. It is the amalgamation of two
+ * interfaces, the FileSelector and the Parameterizable interface. Note that
+ * you will almost certainly want the default behaviour for handling
+ * Parameters, so you probably want to use the BaseExtendSelector class
+ * as the base class for your custom selector rather than implementing
+ * this interface from scratch.
+ *
+ * @since 1.5
+ */
+public interface ExtendFileSelector extends FileSelector, Parameterizable {
+
+ // No further methods necessary. This is just an amalgamation of two other
+ // interfaces.
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/ExtendSelector.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/ExtendSelector.java
new file mode 100644
index 00000000..af8c920f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/ExtendSelector.java
@@ -0,0 +1,201 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types.selectors;
+
+import java.io.File;
+import java.util.Vector;
+
+import org.apache.tools.ant.AntClassLoader;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.Parameter;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.types.Reference;
+
+/**
+ * Selector that selects files by forwarding the request on to other classes.
+ *
+ * @since 1.5
+ */
+public class ExtendSelector extends BaseSelector {
+
+ private String classname = null;
+ private FileSelector dynselector = null;
+ private Vector<Parameter> paramVec = new Vector<Parameter>();
+ private Path classpath = null;
+
+ /**
+ * Default constructor.
+ */
+ public ExtendSelector() {
+ }
+
+ /**
+ * Sets the classname of the custom selector.
+ *
+ * @param classname is the class which implements this selector
+ */
+ public void setClassname(String classname) {
+ this.classname = classname;
+ }
+
+ /**
+ * Instantiates the identified custom selector class.
+ */
+ public void selectorCreate() {
+ if (classname != null && classname.length() > 0) {
+ try {
+ Class<?> c = null;
+ if (classpath == null) {
+ c = Class.forName(classname);
+ } else {
+ // Memory-Leak in line below
+ AntClassLoader al
+ = getProject().createClassLoader(classpath);
+ c = Class.forName(classname, true, al);
+ }
+ dynselector = c.asSubclass(FileSelector.class).newInstance();
+ final Project p = getProject();
+ if (p != null) {
+ p.setProjectReference(dynselector);
+ }
+ } catch (ClassNotFoundException cnfexcept) {
+ setError("Selector " + classname
+ + " not initialized, no such class");
+ } catch (InstantiationException iexcept) {
+ setError("Selector " + classname
+ + " not initialized, could not create class");
+ } catch (IllegalAccessException iaexcept) {
+ setError("Selector " + classname
+ + " not initialized, class not accessible");
+ }
+ } else {
+ setError("There is no classname specified");
+ }
+ }
+
+ /**
+ * Create new parameters to pass to custom selector.
+ *
+ * @param p The new Parameter object
+ */
+ public void addParam(Parameter p) {
+ paramVec.addElement(p);
+ }
+
+
+ /**
+ * Set the classpath to load the classname specified using an attribute.
+ * @param classpath the classpath to use
+ */
+ public final void setClasspath(Path classpath) {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ if (this.classpath == null) {
+ this.classpath = classpath;
+ } else {
+ this.classpath.append(classpath);
+ }
+ }
+
+ /**
+ * Specify the classpath to use to load the Selector (nested element).
+ * @return a classpath to be configured
+ */
+ public final Path createClasspath() {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ if (this.classpath == null) {
+ this.classpath = new Path(getProject());
+ }
+ return this.classpath.createPath();
+ }
+
+ /**
+ * Get the classpath
+ * @return the classpath
+ */
+ public final Path getClasspath() {
+ return classpath;
+ }
+
+ /**
+ * Set the classpath to use for loading a custom selector by using
+ * a reference.
+ * @param r a reference to the classpath
+ */
+ public void setClasspathref(Reference r) {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ createClasspath().setRefid(r);
+ }
+
+ /**
+ * These are errors specific to ExtendSelector only. If there are
+ * errors in the custom selector, it should throw a BuildException
+ * when isSelected() is called.
+ */
+ public void verifySettings() {
+ // Creation is done here rather than in isSelected() because some
+ // containers may do a validation pass before running isSelected(),
+ // but we need to check for the existence of the created class.
+ if (dynselector == null) {
+ selectorCreate();
+ }
+ if (classname == null || classname.length() < 1) {
+ setError("The classname attribute is required");
+ } else if (dynselector == null) {
+ setError("Internal Error: The custom selector was not created");
+ } else if (!(dynselector instanceof ExtendFileSelector)
+ && (paramVec.size() > 0)) {
+ setError("Cannot set parameters on custom selector that does not "
+ + "implement ExtendFileSelector");
+ }
+ }
+
+
+ /**
+ * Allows the custom selector to choose whether to select a file. This
+ * is also where the Parameters are passed to the custom selector,
+ * since we know we must have them all by now. And since we must know
+ * both classpath and classname, creating the class is deferred to here
+ * as well.
+ * @param basedir The the base directory.
+ * @param filename The name of the file to check.
+ * @param file A File object for this filename.
+ * @return whether the file should be selected or not.
+ * @exception BuildException if an error occurs.
+ */
+ public boolean isSelected(File basedir, String filename, File file)
+ throws BuildException {
+ validate();
+ if (paramVec.size() > 0 && dynselector instanceof ExtendFileSelector) {
+ Parameter[] paramArray = new Parameter[paramVec.size()];
+ paramVec.copyInto(paramArray);
+ // We know that dynselector must be non-null if no error message
+ ((ExtendFileSelector) dynselector).setParameters(paramArray);
+ }
+ return dynselector.isSelected(basedir, filename, file);
+ }
+
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/FileSelector.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/FileSelector.java
new file mode 100644
index 00000000..614a9706
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/FileSelector.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types.selectors;
+
+import java.io.File;
+
+import org.apache.tools.ant.BuildException;
+
+/**
+ * This is the interface to be used by all selectors.
+ *
+ * @since 1.5
+ */
+public interface FileSelector {
+
+ /**
+ * Method that each selector will implement to create their
+ * selection behaviour. If there is a problem with the setup
+ * of a selector, it can throw a BuildException to indicate
+ * the problem.
+ *
+ * @param basedir A java.io.File object for the base directory
+ * @param filename The name of the file to check
+ * @param file A File object for this filename
+ * @return whether the file should be selected or not
+ * @exception BuildException if the selector was not configured correctly
+ */
+ boolean isSelected(File basedir, String filename, File file)
+ throws BuildException;
+
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/FilenameSelector.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/FilenameSelector.java
new file mode 100644
index 00000000..1b998f9f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/FilenameSelector.java
@@ -0,0 +1,195 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types.selectors;
+
+import java.io.File;
+
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.Parameter;
+import org.apache.tools.ant.types.RegularExpression;
+import org.apache.tools.ant.util.regexp.Regexp;
+import org.apache.tools.ant.util.regexp.RegexpUtil;
+
+/**
+ * Selector that filters files based on the filename.
+ *
+ * @since 1.5
+ */
+public class FilenameSelector extends BaseExtendSelector {
+
+ private String pattern = null;
+ private String regex = null;
+ private boolean casesensitive = true;
+
+ private boolean negated = false;
+ /** Used for parameterized custom selector */
+ public static final String NAME_KEY = "name";
+ /** Used for parameterized custom selector */
+ public static final String CASE_KEY = "casesensitive";
+ /** Used for parameterized custom selector */
+ public static final String NEGATE_KEY = "negate";
+ /** Used for parameterized custom selector */
+ public static final String REGEX_KEY = "regex";
+
+ // caches for performance reasons
+ private RegularExpression reg;
+ private Regexp expression;
+
+ /**
+ * Creates a new <code>FilenameSelector</code> instance.
+ *
+ */
+ public FilenameSelector() {
+ }
+
+ /**
+ * @return a string describing this object
+ */
+ public String toString() {
+ StringBuilder buf = new StringBuilder("{filenameselector name: ");
+ if (pattern != null) {
+ buf.append(pattern);
+ }
+ if (regex != null) {
+ buf.append(regex).append(" [as regular expression]");
+ }
+ buf.append(" negate: ").append(negated);
+ buf.append(" casesensitive: ").append(casesensitive);
+ buf.append("}");
+ return buf.toString();
+ }
+
+ /**
+ * The name of the file, or the pattern for the name, that
+ * should be used for selection.
+ *
+ * @param pattern the file pattern that any filename must match
+ * against in order to be selected.
+ */
+ public void setName(String pattern) {
+ pattern = pattern.replace('/', File.separatorChar).replace('\\',
+ File.separatorChar);
+ if (pattern.endsWith(File.separator)) {
+ pattern += "**";
+ }
+ this.pattern = pattern;
+ }
+
+ /**
+ * The regular expression the file name will be matched against.
+ *
+ * @param pattern the regular expression that any filename must match
+ * against in order to be selected.
+ */
+ public void setRegex(String pattern) {
+ this.regex = pattern;
+ this.reg = null;
+ }
+
+ /**
+ * Whether to ignore case when checking filenames.
+ *
+ * @param casesensitive whether to pay attention to case sensitivity
+ */
+ public void setCasesensitive(boolean casesensitive) {
+ this.casesensitive = casesensitive;
+ }
+
+ /**
+ * You can optionally reverse the selection of this selector,
+ * thereby emulating an &lt;exclude&gt; tag, by setting the attribute
+ * negate to true. This is identical to surrounding the selector
+ * with &lt;not&gt;&lt;/not&gt;.
+ *
+ * @param negated whether to negate this selection
+ */
+ public void setNegate(boolean negated) {
+ this.negated = negated;
+ }
+
+ /**
+ * When using this as a custom selector, this method will be called.
+ * It translates each parameter into the appropriate setXXX() call.
+ *
+ * @param parameters the complete set of parameters for this selector
+ */
+ public void setParameters(Parameter[] parameters) {
+ super.setParameters(parameters);
+ if (parameters != null) {
+ for (int i = 0; i < parameters.length; i++) {
+ String paramname = parameters[i].getName();
+ if (NAME_KEY.equalsIgnoreCase(paramname)) {
+ setName(parameters[i].getValue());
+ } else if (CASE_KEY.equalsIgnoreCase(paramname)) {
+ setCasesensitive(Project.toBoolean(
+ parameters[i].getValue()));
+ } else if (NEGATE_KEY.equalsIgnoreCase(paramname)) {
+ setNegate(Project.toBoolean(parameters[i].getValue()));
+ } else if (REGEX_KEY.equalsIgnoreCase(paramname)) {
+ setRegex(parameters[i].getValue());
+ } else {
+ setError("Invalid parameter " + paramname);
+ }
+ }
+ }
+ }
+
+ /**
+ * Checks to make sure all settings are kosher. In this case, it
+ * means that the name attribute has been set.
+ *
+ */
+ public void verifySettings() {
+ if (pattern == null && regex == null) {
+ setError("The name or regex attribute is required");
+ } else if (pattern != null && regex != null) {
+ setError("Only one of name and regex attribute is allowed");
+ }
+ }
+
+ /**
+ * The heart of the matter. This is where the selector gets to decide
+ * on the inclusion of a file in a particular fileset. Most of the work
+ * for this selector is offloaded into SelectorUtils, a static class
+ * that provides the same services for both FilenameSelector and
+ * DirectoryScanner.
+ *
+ * @param basedir the base directory the scan is being done from
+ * @param filename is the name of the file to check
+ * @param file is a java.io.File object the selector can use
+ * @return whether the file should be selected or not
+ */
+ public boolean isSelected(File basedir, String filename, File file) {
+ validate();
+ if (pattern != null) {
+ return (SelectorUtils.matchPath(pattern, filename,
+ casesensitive) == !(negated));
+ } else {
+ if (reg == null) {
+ reg = new RegularExpression();
+ reg.setPattern(regex);
+ expression = reg.getRegexp(getProject());
+ }
+ int options = RegexpUtil.asOptions(casesensitive);
+ return expression.matches(filename, options) == !negated;
+ }
+ }
+
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/MajoritySelector.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/MajoritySelector.java
new file mode 100644
index 00000000..842258fb
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/MajoritySelector.java
@@ -0,0 +1,103 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types.selectors;
+
+import java.io.File;
+import java.util.Enumeration;
+
+/**
+ * This selector is here just to shake up your thinking a bit. Don't get
+ * too caught up in boolean, there are other ways you can evaluate a
+ * collection of selectors. This one takes a vote of the selectors it
+ * contains, and majority wins. You could also have an "all-but-one"
+ * selector, a "weighted-average" selector, and so on. These are left
+ * as exercises for the reader (as are the usecases where this would
+ * be necessary).
+ *
+ * @since 1.5
+ */
+public class MajoritySelector extends BaseSelectorContainer {
+
+ private boolean allowtie = true;
+
+ /**
+ * Default constructor.
+ */
+ public MajoritySelector() {
+ }
+
+ /**
+ * @return a string describing this object
+ */
+ public String toString() {
+ StringBuilder buf = new StringBuilder();
+ if (hasSelectors()) {
+ buf.append("{majorityselect: ");
+ buf.append(super.toString());
+ buf.append("}");
+ }
+ return buf.toString();
+ }
+
+ /**
+ * A attribute to specify what will happen if number
+ * of yes votes is the same as the number of no votes
+ * defaults to true
+ *
+ * @param tiebreaker the value to give if there is a tie
+ */
+ public void setAllowtie(boolean tiebreaker) {
+ allowtie = tiebreaker;
+ }
+
+ /**
+ * Returns true (the file is selected) if most of the other selectors
+ * agree. In case of a tie, go by the allowtie setting. That defaults
+ * to true, meaning in case of a tie, the file is selected.
+ *
+ * @param basedir the base directory the scan is being done from
+ * @param filename is the name of the file to check
+ * @param file is a java.io.File object for the filename that the selector
+ * can use
+ * @return whether the file should be selected or not
+ */
+ public boolean isSelected(File basedir, String filename, File file) {
+ validate();
+ int yesvotes = 0;
+ int novotes = 0;
+ Enumeration<FileSelector> e = selectorElements();
+
+ while (e.hasMoreElements()) {
+ if (e.nextElement().isSelected(basedir,
+ filename, file)) {
+ yesvotes++;
+ } else {
+ novotes++;
+ }
+ }
+ if (yesvotes > novotes) {
+ return true;
+ } else if (novotes > yesvotes) {
+ return false;
+ }
+ // At this point, we know we have a tie.
+ return allowtie;
+ }
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/MappingSelector.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/MappingSelector.java
new file mode 100644
index 00000000..1a274949
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/MappingSelector.java
@@ -0,0 +1,165 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types.selectors;
+
+import java.io.File;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.types.Mapper;
+import org.apache.tools.ant.util.FileNameMapper;
+import org.apache.tools.ant.util.FileUtils;
+import org.apache.tools.ant.util.IdentityMapper;
+
+/**
+ * A mapping selector is an abstract class adding mapping support to the base
+ * selector
+ */
+public abstract class MappingSelector extends BaseSelector {
+
+ /** Utilities used for file operations */
+ private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+
+ // CheckStyle:VisibilityModifier OFF - bc
+
+ protected File targetdir = null;
+ protected Mapper mapperElement = null;
+ protected FileNameMapper map = null;
+ protected int granularity = 0;
+
+ // CheckStyle:VisibilityModifier ON
+
+ /**
+ * Creates a new <code>MappingSelector</code> instance.
+ *
+ */
+ public MappingSelector() {
+ granularity = (int) FILE_UTILS.getFileTimestampGranularity();
+ }
+
+
+ /**
+ * The name of the file or directory which is checked for out-of-date
+ * files.
+ *
+ * @param targetdir the directory to scan looking for files.
+ */
+ public void setTargetdir(File targetdir) {
+ this.targetdir = targetdir;
+ }
+
+ /**
+ * Defines the FileNameMapper to use (nested mapper element).
+ * @return a mapper to be configured
+ * @throws BuildException if more than one mapper defined
+ */
+ public Mapper createMapper() throws BuildException {
+ if (map != null || mapperElement != null) {
+ throw new BuildException("Cannot define more than one mapper");
+ }
+ mapperElement = new Mapper(getProject());
+ return mapperElement;
+ }
+
+ /**
+ * Add a configured FileNameMapper instance.
+ * @param fileNameMapper the FileNameMapper to add
+ * @throws BuildException if more than one mapper defined
+ * @since Ant 1.8.0
+ */
+ public void addConfigured(FileNameMapper fileNameMapper) {
+ if (map != null || mapperElement != null) {
+ throw new BuildException("Cannot define more than one mapper");
+ }
+ this.map = fileNameMapper;
+ }
+
+ /**
+ * Checks to make sure all settings are kosher. In this case, it
+ * means that the dest attribute has been set and we have a mapper.
+ */
+ @Override
+ public void verifySettings() {
+ if (targetdir == null) {
+ setError("The targetdir attribute is required.");
+ }
+ if (map == null) {
+ if (mapperElement == null) {
+ map = new IdentityMapper();
+ } else {
+ map = mapperElement.getImplementation();
+ if (map == null) {
+ setError("Could not set <mapper> element.");
+ }
+ }
+ }
+ }
+
+ /**
+ * The heart of the matter. This is where the selector gets to decide
+ * on the inclusion of a file in a particular fileset.
+ *
+ * @param basedir the base directory the scan is being done from
+ * @param filename is the name of the file to check
+ * @param file is a java.io.File object the selector can use
+ * @return whether the file should be selected or not
+ */
+ @Override
+ public boolean isSelected(File basedir, String filename, File file) {
+
+ // throw BuildException on error
+ validate();
+
+ // Determine file whose out-of-dateness is to be checked
+ String[] destfiles = map.mapFileName(filename);
+ // If filename does not match the To attribute of the mapper
+ // then filter it out of the files we are considering
+ if (destfiles == null) {
+ return false;
+ }
+ // Sanity check
+ if (destfiles.length != 1 || destfiles[0] == null) {
+ throw new BuildException("Invalid destination file results for "
+ + targetdir.getName() + " with filename " + filename);
+ }
+ String destname = destfiles[0];
+ File destfile = FILE_UTILS.resolveFile(targetdir, destname);
+
+ boolean selected = selectionTest(file, destfile);
+ return selected;
+ }
+
+ /**
+ * this test is our selection test that compared the file with the destfile
+ * @param srcfile file to test; may be null
+ * @param destfile destination file
+ * @return true if source file compares with destination file
+ */
+ protected abstract boolean selectionTest(File srcfile, File destfile);
+
+ /**
+ * Sets the number of milliseconds leeway we will give before we consider
+ * a file out of date. Defaults to 2000 on MS-DOS derivatives and 1000 on
+ * others.
+ * @param granularity the leeway in milliseconds
+ */
+ public void setGranularity(int granularity) {
+ this.granularity = granularity;
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/NoneSelector.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/NoneSelector.java
new file mode 100644
index 00000000..536b5b5f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/NoneSelector.java
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types.selectors;
+
+import java.io.File;
+import java.util.Enumeration;
+
+/**
+ * This selector has a collection of other selectors. All of those selectors
+ * must refuse to select a file before the file is considered selected by
+ * this selector.
+ *
+ * @since 1.5
+ */
+public class NoneSelector extends BaseSelectorContainer {
+
+ /**
+ * Default constructor.
+ */
+ public NoneSelector() {
+ }
+
+ /**
+ * @return a string representation of the selector
+ */
+ public String toString() {
+ StringBuilder buf = new StringBuilder();
+ if (hasSelectors()) {
+ buf.append("{noneselect: ");
+ buf.append(super.toString());
+ buf.append("}");
+ }
+ return buf.toString();
+ }
+
+ /**
+ * Returns true (the file is selected) only if all other selectors
+ * agree that the file should not be selected.
+ *
+ * @param basedir the base directory the scan is being done from
+ * @param filename is the name of the file to check
+ * @param file is a java.io.File object for the filename that the selector
+ * can use
+ * @return whether the file should be selected or not
+ */
+ public boolean isSelected(File basedir, String filename, File file) {
+ validate();
+ Enumeration<FileSelector> e = selectorElements();
+
+ while (e.hasMoreElements()) {
+ if (e.nextElement().isSelected(basedir, filename, file)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/NotSelector.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/NotSelector.java
new file mode 100644
index 00000000..71c3940f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/NotSelector.java
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types.selectors;
+
+
+/**
+ * This selector has one other selectors whose meaning it inverts. It
+ * actually relies on NoneSelector for its implementation of the
+ * isSelected() method, but it adds a check to ensure there is only one
+ * other selector contained within.
+ *
+ * @since 1.5
+ */
+public class NotSelector extends NoneSelector {
+
+ /**
+ * Default constructor.
+ */
+ public NotSelector() {
+ }
+
+ /**
+ * Constructor that inverts the meaning of its argument.
+ * @param other the selector to invert
+ * @since Ant 1.7
+ */
+ public NotSelector(FileSelector other) {
+ this();
+ appendSelector(other);
+ }
+
+ /**
+ * @return a string representation of the selector
+ */
+ public String toString() {
+ StringBuilder buf = new StringBuilder();
+ if (hasSelectors()) {
+ buf.append("{notselect: ");
+ buf.append(super.toString());
+ buf.append("}");
+ }
+ return buf.toString();
+ }
+
+ /**
+ * Makes sure that there is only one entry, sets an error message if
+ * not.
+ */
+ public void verifySettings() {
+ if (selectorCount() != 1) {
+ setError("One and only one selector is allowed within the "
+ + "<not> tag");
+ }
+ }
+
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/OrSelector.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/OrSelector.java
new file mode 100644
index 00000000..b0777445
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/OrSelector.java
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types.selectors;
+
+import java.io.File;
+import java.util.Enumeration;
+
+/**
+ * This selector has a collection of other selectors, any of which have to
+ * select a file in order for this selector to select it.
+ *
+ * @since 1.5
+ */
+public class OrSelector extends BaseSelectorContainer {
+
+ /**
+ * Default constructor.
+ */
+ public OrSelector() {
+ }
+
+ /**
+ * @return a string representation of the selector
+ */
+ public String toString() {
+ StringBuilder buf = new StringBuilder();
+ if (hasSelectors()) {
+ buf.append("{orselect: ");
+ buf.append(super.toString());
+ buf.append("}");
+ }
+ return buf.toString();
+ }
+
+ /**
+ * Returns true (the file is selected) if any of the other selectors
+ * agree that the file should be selected.
+ *
+ * @param basedir the base directory the scan is being done from
+ * @param filename the name of the file to check
+ * @param file a java.io.File object for the filename that the selector
+ * can use
+ * @return whether the file should be selected or not
+ */
+ public boolean isSelected(File basedir, String filename, File file) {
+ validate();
+ Enumeration<FileSelector> e = selectorElements();
+
+ // First, check that all elements are correctly configured
+ while (e.hasMoreElements()) {
+ if (e.nextElement().isSelected(basedir, filename, file)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/PresentSelector.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/PresentSelector.java
new file mode 100644
index 00000000..1c0c000c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/PresentSelector.java
@@ -0,0 +1,198 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types.selectors;
+
+import java.io.File;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.types.EnumeratedAttribute;
+import org.apache.tools.ant.types.Mapper;
+import org.apache.tools.ant.util.FileNameMapper;
+import org.apache.tools.ant.util.FileUtils;
+import org.apache.tools.ant.util.IdentityMapper;
+
+/**
+ * Selector that filters files based on whether they appear in another
+ * directory tree. It can contain a mapper element, so isn't available
+ * as an ExtendSelector (since those parameters can't hold other
+ * elements).
+ *
+ * @since 1.5
+ */
+public class PresentSelector extends BaseSelector {
+ private File targetdir = null;
+ private Mapper mapperElement = null;
+ private FileNameMapper map = null;
+ private boolean destmustexist = true;
+
+ /**
+ * Creates a new <code>PresentSelector</code> instance.
+ *
+ */
+ public PresentSelector() {
+ }
+
+ /**
+ * @return a string describing this object
+ */
+ @Override
+ public String toString() {
+ final StringBuilder buf = new StringBuilder("{presentselector targetdir: ");
+ if (targetdir == null) {
+ buf.append("NOT YET SET");
+ } else {
+ buf.append(targetdir.getName());
+ }
+ buf.append(" present: ");
+ if (destmustexist) {
+ buf.append("both");
+ } else {
+ buf.append("srconly");
+ }
+ if (map != null) {
+ buf.append(map.toString());
+ } else if (mapperElement != null) {
+ buf.append(mapperElement.toString());
+ }
+ buf.append("}");
+ return buf.toString();
+ }
+
+ /**
+ * The name of the file or directory which is checked for matching
+ * files.
+ *
+ * @param targetdir the directory to scan looking for matching files.
+ */
+ public void setTargetdir(final File targetdir) {
+ this.targetdir = targetdir;
+ }
+
+ /**
+ * Defines the FileNameMapper to use (nested mapper element).
+ * @return a mapper to be configured
+ * @throws BuildException if more than one mapper defined
+ */
+ public Mapper createMapper() throws BuildException {
+ if (map != null || mapperElement != null) {
+ throw new BuildException("Cannot define more than one mapper");
+ }
+ mapperElement = new Mapper(getProject());
+ return mapperElement;
+ }
+
+ /**
+ * Add a configured FileNameMapper instance.
+ * @param fileNameMapper the FileNameMapper to add
+ * @throws BuildException if more than one mapper defined
+ * @since Ant 1.8.0
+ */
+ public void addConfigured(final FileNameMapper fileNameMapper) {
+ if (map != null || mapperElement != null) {
+ throw new BuildException("Cannot define more than one mapper");
+ }
+ this.map = fileNameMapper;
+ }
+
+ /**
+ * This sets whether to select a file if its dest file is present.
+ * It could be a <code>negate</code> boolean, but by doing things
+ * this way, we get some documentation on how the system works.
+ * A user looking at the documentation should clearly understand
+ * that the ONLY files whose presence is being tested are those
+ * that already exist in the source directory, hence the lack of
+ * a <code>destonly</code> option.
+ *
+ * @param fp An attribute set to either <code>srconly</code or
+ * <code>both</code>.
+ */
+ public void setPresent(final FilePresence fp) {
+ if (fp.getIndex() == 0) {
+ destmustexist = false;
+ }
+ }
+
+ /**
+ * Checks to make sure all settings are kosher. In this case, it
+ * means that the targetdir attribute has been set and we have a mapper.
+ */
+ @Override
+ public void verifySettings() {
+ if (targetdir == null) {
+ setError("The targetdir attribute is required.");
+ }
+ if (map == null) {
+ if (mapperElement == null) {
+ map = new IdentityMapper();
+ } else {
+ map = mapperElement.getImplementation();
+ if (map == null) {
+ setError("Could not set <mapper> element.");
+ }
+ }
+ }
+ }
+
+ /**
+ * The heart of the matter. This is where the selector gets to decide
+ * on the inclusion of a file in a particular fileset.
+ *
+ * @param basedir the base directory the scan is being done from
+ * @param filename is the name of the file to check
+ * @param file is a java.io.File object the selector can use
+ * @return whether the file should be selected or not
+ */
+ @Override
+ public boolean isSelected(final File basedir, final String filename, final File file) {
+
+ // throw BuildException on error
+ validate();
+
+ // Determine file whose existence is to be checked
+ final String[] destfiles = map.mapFileName(filename);
+ // If filename does not match the To attribute of the mapper
+ // then filter it out of the files we are considering
+ if (destfiles == null) {
+ return false;
+ }
+ // Sanity check
+ if (destfiles.length != 1 || destfiles[0] == null) {
+ throw new BuildException("Invalid destination file results for "
+ + targetdir + " with filename " + filename);
+ }
+ final String destname = destfiles[0];
+ final File destfile = FileUtils.getFileUtils().resolveFile(targetdir, destname);
+ return destfile.exists() == destmustexist;
+ }
+
+ /**
+ * Enumerated attribute with the values for indicating where a file's
+ * presence is allowed and required.
+ */
+ public static class FilePresence extends EnumeratedAttribute {
+ /**
+ * @return the values as an array of strings
+ */
+ @Override
+ public String[] getValues() {
+ return new String[] {"srconly", "both"};
+ }
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/ReadableSelector.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/ReadableSelector.java
new file mode 100644
index 00000000..20471188
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/ReadableSelector.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types.selectors;
+
+import java.io.File;
+
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.resources.FileProvider;
+import org.apache.tools.ant.types.resources.selectors.ResourceSelector;
+
+/**
+ * A selector that selects readable files.
+ *
+ * <p>Readable is defined in terms of java.io.File#canRead, this
+ * means the selector will accept any file that exists and is readable
+ * by the application.</p>
+ *
+ * @since Ant 1.8.0
+ */
+public class ReadableSelector implements FileSelector, ResourceSelector {
+
+ public boolean isSelected(File basedir, String filename, File file) {
+ return file != null && file.canRead();
+ }
+
+ public boolean isSelected(Resource r) {
+ FileProvider fp = r.as(FileProvider.class);
+ if (fp != null) {
+ return isSelected(null, null, fp.getFile());
+ }
+ return false;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/SelectSelector.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/SelectSelector.java
new file mode 100644
index 00000000..2089012c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/SelectSelector.java
@@ -0,0 +1,231 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types.selectors;
+
+import java.io.File;
+import java.util.Enumeration;
+
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.PropertyHelper;
+
+/**
+ * This selector just holds one other selector and forwards all
+ * requests to it. It exists so that there is a single selector
+ * type that can exist outside of any targets, as an element of
+ * project. It overrides all of the reference stuff so that it
+ * works as expected. Note that this is the only selector you
+ * can reference.
+ *
+ * @since 1.5
+ */
+public class SelectSelector extends BaseSelectorContainer {
+
+ private Object ifCondition;
+ private Object unlessCondition;
+
+ /**
+ * Default constructor.
+ */
+ public SelectSelector() {
+ }
+
+ /**
+ * @return a string describing this object
+ */
+ public String toString() {
+ StringBuffer buf = new StringBuffer();
+ if (hasSelectors()) {
+ buf.append("{select");
+ if (ifCondition != null) {
+ buf.append(" if: ");
+ buf.append(ifCondition);
+ }
+ if (unlessCondition != null) {
+ buf.append(" unless: ");
+ buf.append(unlessCondition);
+ }
+ buf.append(" ");
+ buf.append(super.toString());
+ buf.append("}");
+ }
+ return buf.toString();
+ }
+
+ /**
+ * Performs the check for circular references and returns the
+ * referenced Selector.
+ */
+ private SelectSelector getRef() {
+ Object o = getCheckedRef(this.getClass(), "SelectSelector");
+ return (SelectSelector) o;
+ }
+
+ /**
+ * Indicates whether there are any selectors here.
+ * @return whether any selectors are in this container
+ */
+ public boolean hasSelectors() {
+ if (isReference()) {
+ return getRef().hasSelectors();
+ }
+ return super.hasSelectors();
+ }
+
+ /**
+ * Gives the count of the number of selectors in this container
+ * @return the number of selectors in this container
+ */
+ public int selectorCount() {
+ if (isReference()) {
+ return getRef().selectorCount();
+ }
+ return super.selectorCount();
+ }
+
+ /**
+ * Returns the set of selectors as an array.
+ * @param p the current project
+ * @return an array of selectors in this container
+ */
+ public FileSelector[] getSelectors(Project p) {
+ if (isReference()) {
+ return getRef().getSelectors(p);
+ }
+ return super.getSelectors(p);
+ }
+
+ /**
+ * Returns an enumerator for accessing the set of selectors.
+ * @return an enumerator that goes through each of the selectors
+ */
+ public Enumeration<FileSelector> selectorElements() {
+ if (isReference()) {
+ return getRef().selectorElements();
+ }
+ return super.selectorElements();
+ }
+
+ /**
+ * Add a new selector into this container.
+ *
+ * @param selector the new selector to add
+ */
+ public void appendSelector(FileSelector selector) {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ super.appendSelector(selector);
+ }
+
+
+ /**
+ * Makes sure that there is only one entry, sets an error message if
+ * not.
+ */
+ public void verifySettings() {
+ int cnt = selectorCount();
+ if (cnt < 0 || cnt > 1) {
+ setError("Only one selector is allowed within the "
+ + "<selector> tag");
+ }
+ }
+
+ /**
+ * Ensures that the selector passes the conditions placed
+ * on it with <code>if</code> and <code>unless</code>.
+ * @return true if conditions are passed
+ */
+ public boolean passesConditions() {
+ PropertyHelper ph = PropertyHelper.getPropertyHelper(getProject());
+ return ph.testIfCondition(ifCondition)
+ && ph.testUnlessCondition(unlessCondition);
+ }
+
+ /**
+ * Sets the if attribute to an expression which must evaluate to
+ * true or the name of an existing property for the
+ * selector to select any files.
+ * @param ifProperty the expression to check
+ * @since Ant 1.8.0
+ */
+ public void setIf(Object ifProperty) {
+ this.ifCondition = ifProperty;
+ }
+
+ /**
+ * Sets the if attribute to an expression which must evaluate to
+ * true or the name of an existing property for the
+ * selector to select any files.
+ * @param ifProperty the expression to check
+ */
+ public void setIf(String ifProperty) {
+ setIf((Object) ifProperty);
+ }
+
+ /**
+ * Sets the unless attribute to an expression which must evaluate to
+ * false or the name of a property which cannot exist for the
+ * selector to select any files.
+ * @param unlessProperty the expression to check
+ * @since Ant 1.8.0
+ */
+ public void setUnless(Object unlessProperty) {
+ this.unlessCondition = unlessProperty;
+ }
+
+ /**
+ * Sets the unless attribute to an expression which must evaluate to
+ * false or the name of a property which cannot exist for the
+ * selector to select any files.
+ * @param unlessProperty the expression to check
+ */
+ public void setUnless(String unlessProperty) {
+ setUnless((Object) unlessProperty);
+ }
+
+ /**
+ * Returns true (the file is selected) only if the if property (if any)
+ * exists, the unless property (if any) doesn't exist, and the
+ * contained selector (if any) selects the file. If there is no contained
+ * selector, return true (because we assume that the point was to test
+ * the if and unless conditions).
+ *
+ * @param basedir the base directory the scan is being done from
+ * @param filename the name of the file to check
+ * @param file a java.io.File object for the filename that the selector
+ * can use
+ * @return whether the file should be selected or not
+ */
+ public boolean isSelected(File basedir, String filename, File file) {
+ validate();
+
+ // Deal with if and unless properties first
+ if (!(passesConditions())) {
+ return false;
+ }
+
+ Enumeration<FileSelector> e = selectorElements();
+ if (!e.hasMoreElements()) {
+ return true;
+ }
+ FileSelector f = e.nextElement();
+ return f.isSelected(basedir, filename, file);
+ }
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/SelectorContainer.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/SelectorContainer.java
new file mode 100644
index 00000000..47e4e4fd
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/SelectorContainer.java
@@ -0,0 +1,187 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types.selectors;
+
+import java.util.Enumeration;
+
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.selectors.modifiedselector.ModifiedSelector;
+
+/**
+ * This is the interface for selectors that can contain other selectors.
+ *
+ * @since 1.5
+ */
+public interface SelectorContainer {
+
+ /**
+ * Indicates whether there are any selectors here.
+ *
+ * @return whether any selectors are in this container
+ */
+ boolean hasSelectors();
+
+ /**
+ * Gives the count of the number of selectors in this container
+ *
+ * @return the number of selectors in this container
+ */
+ int selectorCount();
+
+ /**
+ * Returns the set of selectors as an array.
+ * @param p the current project
+ * @return an array of selectors in this container
+ */
+ FileSelector[] getSelectors(Project p);
+
+ /**
+ * Returns an enumerator for accessing the set of selectors.
+ *
+ * @return an enumerator that goes through each of the selectors
+ */
+ Enumeration<FileSelector> selectorElements();
+
+ /**
+ * Add a new selector into this container.
+ *
+ * @param selector the new selector to add
+ */
+ void appendSelector(FileSelector selector);
+
+ /* Methods below all add specific selectors */
+
+ /**
+ * add a "Select" selector entry on the selector list
+ * @param selector the selector to add
+ */
+ void addSelector(SelectSelector selector);
+
+ /**
+ * add an "And" selector entry on the selector list
+ * @param selector the selector to add
+ */
+ void addAnd(AndSelector selector);
+
+ /**
+ * add an "Or" selector entry on the selector list
+ * @param selector the selector to add
+ */
+ void addOr(OrSelector selector);
+
+ /**
+ * add a "Not" selector entry on the selector list
+ * @param selector the selector to add
+ */
+ void addNot(NotSelector selector);
+
+ /**
+ * add a "None" selector entry on the selector list
+ * @param selector the selector to add
+ */
+ void addNone(NoneSelector selector);
+
+ /**
+ * add a majority selector entry on the selector list
+ * @param selector the selector to add
+ */
+ void addMajority(MajoritySelector selector);
+
+ /**
+ * add a selector date entry on the selector list
+ * @param selector the selector to add
+ */
+ void addDate(DateSelector selector);
+
+ /**
+ * add a selector size entry on the selector list
+ * @param selector the selector to add
+ */
+ void addSize(SizeSelector selector);
+
+ /**
+ * add a selector filename entry on the selector list
+ * @param selector the selector to add
+ */
+ void addFilename(FilenameSelector selector);
+
+ /**
+ * add an extended selector entry on the selector list
+ * @param selector the selector to add
+ */
+ void addCustom(ExtendSelector selector);
+
+ /**
+ * add a contains selector entry on the selector list
+ * @param selector the selector to add
+ */
+ void addContains(ContainsSelector selector);
+
+ /**
+ * add a present selector entry on the selector list
+ * @param selector the selector to add
+ */
+ void addPresent(PresentSelector selector);
+
+ /**
+ * add a depth selector entry on the selector list
+ * @param selector the selector to add
+ */
+ void addDepth(DepthSelector selector);
+
+ /**
+ * add a depends selector entry on the selector list
+ * @param selector the selector to add
+ */
+ void addDepend(DependSelector selector);
+
+ /**
+ * add a regular expression selector entry on the selector list
+ * @param selector the selector to add
+ */
+ void addContainsRegexp(ContainsRegexpSelector selector);
+
+ /**
+ * add the type selector
+ * @param selector the selector to add
+ * @since ant 1.6
+ */
+ void addType(TypeSelector selector);
+
+ /**
+ * add the different selector
+ * @param selector the selector to add
+ * @since ant 1.6
+ */
+ void addDifferent(DifferentSelector selector);
+
+ /**
+ * add the modified selector
+ * @param selector the selector to add
+ * @since ant 1.6
+ */
+ void addModified(ModifiedSelector selector);
+
+ /**
+ * add an arbitrary selector
+ * @param selector the selector to add
+ * @since Ant 1.6
+ */
+ void add(FileSelector selector);
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/SelectorScanner.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/SelectorScanner.java
new file mode 100644
index 00000000..df9f8a40
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/SelectorScanner.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.selectors;
+
+/**
+ * An interface used to describe the actions required by any type of
+ * directory scanner that supports Selectors.
+ *
+ * @since 1.5
+ */
+public interface SelectorScanner {
+ /**
+ * Sets the selectors the scanner should use.
+ *
+ * @param selectors the list of selectors
+ */
+ void setSelectors(FileSelector[] selectors);
+
+ /**
+ * Directories which were selected out of a scan.
+ *
+ * @return list of directories not selected
+ */
+ String[] getDeselectedDirectories();
+
+ /**
+ * Files which were selected out of a scan.
+ *
+ * @return list of files not selected
+ */
+ String[] getDeselectedFiles();
+
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/SelectorUtils.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/SelectorUtils.java
new file mode 100644
index 00000000..277470b7
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/SelectorUtils.java
@@ -0,0 +1,695 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types.selectors;
+
+import java.io.File;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.util.FileUtils;
+
+/**
+ * <p>This is a utility class used by selectors and DirectoryScanner. The
+ * functionality more properly belongs just to selectors, but unfortunately
+ * DirectoryScanner exposed these as protected methods. Thus we have to
+ * support any subclasses of DirectoryScanner that may access these methods.
+ * </p>
+ * <p>This is a Singleton.</p>
+ *
+ * @since 1.5
+ */
+public final class SelectorUtils {
+
+ /**
+ * The pattern that matches an arbitrary number of directories.
+ * @since Ant 1.8.0
+ */
+ public static final String DEEP_TREE_MATCH = "**";
+
+ private static final SelectorUtils instance = new SelectorUtils();
+ private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+
+ /**
+ * Private Constructor
+ */
+ private SelectorUtils() {
+ }
+
+ /**
+ * Retrieves the instance of the Singleton.
+ * @return singleton instance
+ */
+ public static SelectorUtils getInstance() {
+ return instance;
+ }
+
+ /**
+ * Tests whether or not a given path matches the start of a given
+ * pattern up to the first "**".
+ * <p>
+ * This is not a general purpose test and should only be used if you
+ * can live with false positives. For example, <code>pattern=**\a</code>
+ * and <code>str=b</code> will yield <code>true</code>.
+ *
+ * @param pattern The pattern to match against. Must not be
+ * <code>null</code>.
+ * @param str The path to match, as a String. Must not be
+ * <code>null</code>.
+ *
+ * @return whether or not a given path matches the start of a given
+ * pattern up to the first "**".
+ */
+ public static boolean matchPatternStart(String pattern, String str) {
+ return matchPatternStart(pattern, str, true);
+ }
+
+ /**
+ * Tests whether or not a given path matches the start of a given
+ * pattern up to the first "**".
+ * <p>
+ * This is not a general purpose test and should only be used if you
+ * can live with false positives. For example, <code>pattern=**\a</code>
+ * and <code>str=b</code> will yield <code>true</code>.
+ *
+ * @param pattern The pattern to match against. Must not be
+ * <code>null</code>.
+ * @param str The path to match, as a String. Must not be
+ * <code>null</code>.
+ * @param isCaseSensitive Whether or not matching should be performed
+ * case sensitively.
+ *
+ * @return whether or not a given path matches the start of a given
+ * pattern up to the first "**".
+ */
+ public static boolean matchPatternStart(String pattern, String str,
+ boolean isCaseSensitive) {
+ // When str starts with a File.separator, pattern has to start with a
+ // File.separator.
+ // When pattern starts with a File.separator, str has to start with a
+ // File.separator.
+ if (str.startsWith(File.separator)
+ != pattern.startsWith(File.separator)) {
+ return false;
+ }
+
+ String[] patDirs = tokenizePathAsArray(pattern);
+ String[] strDirs = tokenizePathAsArray(str);
+ return matchPatternStart(patDirs, strDirs, isCaseSensitive);
+ }
+
+
+ /**
+ * Tests whether or not a given path matches the start of a given
+ * pattern up to the first "**".
+ * <p>
+ * This is not a general purpose test and should only be used if you
+ * can live with false positives. For example, <code>pattern=**\a</code>
+ * and <code>str=b</code> will yield <code>true</code>.
+ *
+ * @param patDirs The tokenized pattern to match against. Must not be
+ * <code>null</code>.
+ * @param strDirs The tokenized path to match. Must not be
+ * <code>null</code>.
+ * @param isCaseSensitive Whether or not matching should be performed
+ * case sensitively.
+ *
+ * @return whether or not a given path matches the start of a given
+ * pattern up to the first "**".
+ */
+ static boolean matchPatternStart(String[] patDirs, String[] strDirs,
+ boolean isCaseSensitive) {
+ int patIdxStart = 0;
+ int patIdxEnd = patDirs.length - 1;
+ int strIdxStart = 0;
+ int strIdxEnd = strDirs.length - 1;
+
+ // up to first '**'
+ while (patIdxStart <= patIdxEnd && strIdxStart <= strIdxEnd) {
+ String patDir = patDirs[patIdxStart];
+ if (patDir.equals(DEEP_TREE_MATCH)) {
+ break;
+ }
+ if (!match(patDir, strDirs[strIdxStart], isCaseSensitive)) {
+ return false;
+ }
+ patIdxStart++;
+ strIdxStart++;
+ }
+
+ // CheckStyle:SimplifyBooleanReturnCheck OFF
+ // Check turned off as the code needs the comments for the various
+ // code paths.
+ if (strIdxStart > strIdxEnd) {
+ // String is exhausted
+ return true;
+ } else if (patIdxStart > patIdxEnd) {
+ // String not exhausted, but pattern is. Failure.
+ return false;
+ } else {
+ // pattern now holds ** while string is not exhausted
+ // this will generate false positives but we can live with that.
+ return true;
+ }
+ }
+
+ /**
+ * Tests whether or not a given path matches a given pattern.
+ *
+ * If you need to call this method multiple times with the same
+ * pattern you should rather use TokenizedPath
+ *
+ * @see TokenizedPath
+ *
+ * @param pattern The pattern to match against. Must not be
+ * <code>null</code>.
+ * @param str The path to match, as a String. Must not be
+ * <code>null</code>.
+ *
+ * @return <code>true</code> if the pattern matches against the string,
+ * or <code>false</code> otherwise.
+ */
+ public static boolean matchPath(String pattern, String str) {
+ String[] patDirs = tokenizePathAsArray(pattern);
+ return matchPath(patDirs, tokenizePathAsArray(str), true);
+ }
+
+ /**
+ * Tests whether or not a given path matches a given pattern.
+ *
+ * If you need to call this method multiple times with the same
+ * pattern you should rather use TokenizedPattern
+ *
+ * @see TokenizedPattern
+ *
+ * @param pattern The pattern to match against. Must not be
+ * <code>null</code>.
+ * @param str The path to match, as a String. Must not be
+ * <code>null</code>.
+ * @param isCaseSensitive Whether or not matching should be performed
+ * case sensitively.
+ *
+ * @return <code>true</code> if the pattern matches against the string,
+ * or <code>false</code> otherwise.
+ */
+ public static boolean matchPath(String pattern, String str,
+ boolean isCaseSensitive) {
+ String[] patDirs = tokenizePathAsArray(pattern);
+ return matchPath(patDirs, tokenizePathAsArray(str), isCaseSensitive);
+ }
+
+ /**
+ * Core implementation of matchPath. It is isolated so that it
+ * can be called from TokenizedPattern.
+ */
+ static boolean matchPath(String[] tokenizedPattern, String[] strDirs,
+ boolean isCaseSensitive) {
+ int patIdxStart = 0;
+ int patIdxEnd = tokenizedPattern.length - 1;
+ int strIdxStart = 0;
+ int strIdxEnd = strDirs.length - 1;
+
+ // up to first '**'
+ while (patIdxStart <= patIdxEnd && strIdxStart <= strIdxEnd) {
+ String patDir = tokenizedPattern[patIdxStart];
+ if (patDir.equals(DEEP_TREE_MATCH)) {
+ break;
+ }
+ if (!match(patDir, strDirs[strIdxStart], isCaseSensitive)) {
+ return false;
+ }
+ patIdxStart++;
+ strIdxStart++;
+ }
+ if (strIdxStart > strIdxEnd) {
+ // String is exhausted
+ for (int i = patIdxStart; i <= patIdxEnd; i++) {
+ if (!tokenizedPattern[i].equals(DEEP_TREE_MATCH)) {
+ return false;
+ }
+ }
+ return true;
+ } else {
+ if (patIdxStart > patIdxEnd) {
+ // String not exhausted, but pattern is. Failure.
+ return false;
+ }
+ }
+
+ // up to last '**'
+ while (patIdxStart <= patIdxEnd && strIdxStart <= strIdxEnd) {
+ String patDir = tokenizedPattern[patIdxEnd];
+ if (patDir.equals(DEEP_TREE_MATCH)) {
+ break;
+ }
+ if (!match(patDir, strDirs[strIdxEnd], isCaseSensitive)) {
+ return false;
+ }
+ patIdxEnd--;
+ strIdxEnd--;
+ }
+ if (strIdxStart > strIdxEnd) {
+ // String is exhausted
+ for (int i = patIdxStart; i <= patIdxEnd; i++) {
+ if (!tokenizedPattern[i].equals(DEEP_TREE_MATCH)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ while (patIdxStart != patIdxEnd && strIdxStart <= strIdxEnd) {
+ int patIdxTmp = -1;
+ for (int i = patIdxStart + 1; i <= patIdxEnd; i++) {
+ if (tokenizedPattern[i].equals(DEEP_TREE_MATCH)) {
+ patIdxTmp = i;
+ break;
+ }
+ }
+ if (patIdxTmp == patIdxStart + 1) {
+ // '**/**' situation, so skip one
+ patIdxStart++;
+ continue;
+ }
+ // Find the pattern between padIdxStart & padIdxTmp in str between
+ // strIdxStart & strIdxEnd
+ int patLength = (patIdxTmp - patIdxStart - 1);
+ int strLength = (strIdxEnd - strIdxStart + 1);
+ int foundIdx = -1;
+ strLoop:
+ for (int i = 0; i <= strLength - patLength; i++) {
+ for (int j = 0; j < patLength; j++) {
+ String subPat = tokenizedPattern[patIdxStart + j + 1];
+ String subStr = strDirs[strIdxStart + i + j];
+ if (!match(subPat, subStr, isCaseSensitive)) {
+ continue strLoop;
+ }
+ }
+
+ foundIdx = strIdxStart + i;
+ break;
+ }
+
+ if (foundIdx == -1) {
+ return false;
+ }
+
+ patIdxStart = patIdxTmp;
+ strIdxStart = foundIdx + patLength;
+ }
+
+ for (int i = patIdxStart; i <= patIdxEnd; i++) {
+ if (!tokenizedPattern[i].equals(DEEP_TREE_MATCH)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Tests whether or not a string matches against a pattern.
+ * The pattern may contain two special characters:<br>
+ * '*' means zero or more characters<br>
+ * '?' means one and only one character
+ *
+ * @param pattern The pattern to match against.
+ * Must not be <code>null</code>.
+ * @param str The string which must be matched against the pattern.
+ * Must not be <code>null</code>.
+ *
+ * @return <code>true</code> if the string matches against the pattern,
+ * or <code>false</code> otherwise.
+ */
+ public static boolean match(String pattern, String str) {
+ return match(pattern, str, true);
+ }
+
+ /**
+ * Tests whether or not a string matches against a pattern.
+ * The pattern may contain two special characters:<br>
+ * '*' means zero or more characters<br>
+ * '?' means one and only one character
+ *
+ * @param pattern The pattern to match against.
+ * Must not be <code>null</code>.
+ * @param str The string which must be matched against the pattern.
+ * Must not be <code>null</code>.
+ * @param caseSensitive Whether or not matching should be performed
+ * case sensitively.
+ *
+ *
+ * @return <code>true</code> if the string matches against the pattern,
+ * or <code>false</code> otherwise.
+ */
+ public static boolean match(String pattern, String str,
+ boolean caseSensitive) {
+ char[] patArr = pattern.toCharArray();
+ char[] strArr = str.toCharArray();
+ int patIdxStart = 0;
+ int patIdxEnd = patArr.length - 1;
+ int strIdxStart = 0;
+ int strIdxEnd = strArr.length - 1;
+ char ch;
+
+ boolean containsStar = false;
+ for (int i = 0; i < patArr.length; i++) {
+ if (patArr[i] == '*') {
+ containsStar = true;
+ break;
+ }
+ }
+
+ if (!containsStar) {
+ // No '*'s, so we make a shortcut
+ if (patIdxEnd != strIdxEnd) {
+ return false; // Pattern and string do not have the same size
+ }
+ for (int i = 0; i <= patIdxEnd; i++) {
+ ch = patArr[i];
+ if (ch != '?') {
+ if (different(caseSensitive, ch, strArr[i])) {
+ return false; // Character mismatch
+ }
+ }
+ }
+ return true; // String matches against pattern
+ }
+
+ if (patIdxEnd == 0) {
+ return true; // Pattern contains only '*', which matches anything
+ }
+
+ // Process characters before first star
+ while (true) {
+ ch = patArr[patIdxStart];
+ if (ch == '*' || strIdxStart > strIdxEnd) {
+ break;
+ }
+ if (ch != '?') {
+ if (different(caseSensitive, ch, strArr[strIdxStart])) {
+ return false; // Character mismatch
+ }
+ }
+ patIdxStart++;
+ strIdxStart++;
+ }
+ if (strIdxStart > strIdxEnd) {
+ // All characters in the string are used. Check if only '*'s are
+ // left in the pattern. If so, we succeeded. Otherwise failure.
+ return allStars(patArr, patIdxStart, patIdxEnd);
+ }
+
+ // Process characters after last star
+ while (true) {
+ ch = patArr[patIdxEnd];
+ if (ch == '*' || strIdxStart > strIdxEnd) {
+ break;
+ }
+ if (ch != '?') {
+ if (different(caseSensitive, ch, strArr[strIdxEnd])) {
+ return false; // Character mismatch
+ }
+ }
+ patIdxEnd--;
+ strIdxEnd--;
+ }
+ if (strIdxStart > strIdxEnd) {
+ // All characters in the string are used. Check if only '*'s are
+ // left in the pattern. If so, we succeeded. Otherwise failure.
+ return allStars(patArr, patIdxStart, patIdxEnd);
+ }
+
+ // process pattern between stars. padIdxStart and patIdxEnd point
+ // always to a '*'.
+ while (patIdxStart != patIdxEnd && strIdxStart <= strIdxEnd) {
+ int patIdxTmp = -1;
+ for (int i = patIdxStart + 1; i <= patIdxEnd; i++) {
+ if (patArr[i] == '*') {
+ patIdxTmp = i;
+ break;
+ }
+ }
+ if (patIdxTmp == patIdxStart + 1) {
+ // Two stars next to each other, skip the first one.
+ patIdxStart++;
+ continue;
+ }
+ // Find the pattern between padIdxStart & padIdxTmp in str between
+ // strIdxStart & strIdxEnd
+ int patLength = (patIdxTmp - patIdxStart - 1);
+ int strLength = (strIdxEnd - strIdxStart + 1);
+ int foundIdx = -1;
+ strLoop:
+ for (int i = 0; i <= strLength - patLength; i++) {
+ for (int j = 0; j < patLength; j++) {
+ ch = patArr[patIdxStart + j + 1];
+ if (ch != '?') {
+ if (different(caseSensitive, ch,
+ strArr[strIdxStart + i + j])) {
+ continue strLoop;
+ }
+ }
+ }
+
+ foundIdx = strIdxStart + i;
+ break;
+ }
+
+ if (foundIdx == -1) {
+ return false;
+ }
+
+ patIdxStart = patIdxTmp;
+ strIdxStart = foundIdx + patLength;
+ }
+
+ // All characters in the string are used. Check if only '*'s are left
+ // in the pattern. If so, we succeeded. Otherwise failure.
+ return allStars(patArr, patIdxStart, patIdxEnd);
+ }
+
+ private static boolean allStars(char[] chars, int start, int end) {
+ for (int i = start; i <= end; ++i) {
+ if (chars[i] != '*') {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private static boolean different(
+ boolean caseSensitive, char ch, char other) {
+ return caseSensitive
+ ? ch != other
+ : Character.toUpperCase(ch) != Character.toUpperCase(other);
+ }
+
+ /**
+ * Breaks a path up into a Vector of path elements, tokenizing on
+ * <code>File.separator</code>.
+ *
+ * @param path Path to tokenize. Must not be <code>null</code>.
+ *
+ * @return a Vector of path elements from the tokenized path
+ */
+ public static Vector<String> tokenizePath(String path) {
+ return tokenizePath(path, File.separator);
+ }
+
+ /**
+ * Breaks a path up into a Vector of path elements, tokenizing on
+ *
+ * @param path Path to tokenize. Must not be <code>null</code>.
+ * @param separator the separator against which to tokenize.
+ *
+ * @return a Vector of path elements from the tokenized path
+ * @since Ant 1.6
+ */
+ public static Vector<String> tokenizePath(String path, String separator) {
+ Vector<String> ret = new Vector<String>();
+ if (FileUtils.isAbsolutePath(path)) {
+ String[] s = FILE_UTILS.dissect(path);
+ ret.add(s[0]);
+ path = s[1];
+ }
+ StringTokenizer st = new StringTokenizer(path, separator);
+ while (st.hasMoreTokens()) {
+ ret.addElement(st.nextToken());
+ }
+ return ret;
+ }
+
+ /**
+ * Same as {@link #tokenizePath tokenizePath} but hopefully faster.
+ */
+ /*package*/ static String[] tokenizePathAsArray(String path) {
+ String root = null;
+ if (FileUtils.isAbsolutePath(path)) {
+ String[] s = FILE_UTILS.dissect(path);
+ root = s[0];
+ path = s[1];
+ }
+ char sep = File.separatorChar;
+ int start = 0;
+ int len = path.length();
+ int count = 0;
+ for (int pos = 0; pos < len; pos++) {
+ if (path.charAt(pos) == sep) {
+ if (pos != start) {
+ count++;
+ }
+ start = pos + 1;
+ }
+ }
+ if (len != start) {
+ count++;
+ }
+ String[] l = new String[count + ((root == null) ? 0 : 1)];
+
+ if (root != null) {
+ l[0] = root;
+ count = 1;
+ } else {
+ count = 0;
+ }
+ start = 0;
+ for (int pos = 0; pos < len; pos++) {
+ if (path.charAt(pos) == sep) {
+ if (pos != start) {
+ String tok = path.substring(start, pos);
+ l[count++] = tok;
+ }
+ start = pos + 1;
+ }
+ }
+ if (len != start) {
+ String tok = path.substring(start);
+ l[count/*++*/] = tok;
+ }
+ return l;
+ }
+
+ /**
+ * Returns dependency information on these two files. If src has been
+ * modified later than target, it returns true. If target doesn't exist,
+ * it likewise returns true. Otherwise, target is newer than src and
+ * is not out of date, thus the method returns false. It also returns
+ * false if the src file doesn't even exist, since how could the
+ * target then be out of date.
+ *
+ * @param src the original file
+ * @param target the file being compared against
+ * @param granularity the amount in seconds of slack we will give in
+ * determining out of dateness
+ * @return whether the target is out of date
+ */
+ public static boolean isOutOfDate(File src, File target, int granularity) {
+ if (!src.exists()) {
+ return false;
+ }
+ if (!target.exists()) {
+ return true;
+ }
+ if ((src.lastModified() - granularity) > target.lastModified()) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Returns dependency information on these two resources. If src has been
+ * modified later than target, it returns true. If target doesn't exist,
+ * it likewise returns true. Otherwise, target is newer than src and
+ * is not out of date, thus the method returns false. It also returns
+ * false if the src file doesn't even exist, since how could the
+ * target then be out of date.
+ *
+ * @param src the original resource
+ * @param target the resource being compared against
+ * @param granularity the int amount in seconds of slack we will give in
+ * determining out of dateness
+ * @return whether the target is out of date
+ */
+ public static boolean isOutOfDate(Resource src, Resource target,
+ int granularity) {
+ return isOutOfDate(src, target, (long) granularity);
+ }
+
+ /**
+ * Returns dependency information on these two resources. If src has been
+ * modified later than target, it returns true. If target doesn't exist,
+ * it likewise returns true. Otherwise, target is newer than src and
+ * is not out of date, thus the method returns false. It also returns
+ * false if the src file doesn't even exist, since how could the
+ * target then be out of date.
+ *
+ * @param src the original resource
+ * @param target the resource being compared against
+ * @param granularity the long amount in seconds of slack we will give in
+ * determining out of dateness
+ * @return whether the target is out of date
+ */
+ public static boolean isOutOfDate(Resource src, Resource target, long granularity) {
+ long sourceLastModified = src.getLastModified();
+ long targetLastModified = target.getLastModified();
+ return src.isExists()
+ && (sourceLastModified == Resource.UNKNOWN_DATETIME
+ || targetLastModified == Resource.UNKNOWN_DATETIME
+ || (sourceLastModified - granularity) > targetLastModified);
+ }
+
+ /**
+ * "Flattens" a string by removing all whitespace (space, tab, linefeed,
+ * carriage return, and formfeed). This uses StringTokenizer and the
+ * default set of tokens as documented in the single argument constructor.
+ *
+ * @param input a String to remove all whitespace.
+ * @return a String that has had all whitespace removed.
+ */
+ public static String removeWhitespace(String input) {
+ StringBuffer result = new StringBuffer();
+ if (input != null) {
+ StringTokenizer st = new StringTokenizer(input);
+ while (st.hasMoreTokens()) {
+ result.append(st.nextToken());
+ }
+ }
+ return result.toString();
+ }
+
+ /**
+ * Tests if a string contains stars or question marks
+ * @param input a String which one wants to test for containing wildcard
+ * @return true if the string contains at least a star or a question mark
+ */
+ public static boolean hasWildcards(String input) {
+ return (input.indexOf('*') != -1 || input.indexOf('?') != -1);
+ }
+
+ /**
+ * removes from a pattern all tokens to the right containing wildcards
+ * @param input the input string
+ * @return the leftmost part of the pattern without wildcards
+ */
+ public static String rtrimWildcardTokens(String input) {
+ return new TokenizedPattern(input).rtrimWildcardTokens().toString();
+ }
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/SignedSelector.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/SignedSelector.java
new file mode 100644
index 00000000..cd515022
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/SignedSelector.java
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types.selectors;
+import java.io.File;
+
+import org.apache.tools.ant.taskdefs.condition.IsSigned;
+import org.apache.tools.ant.types.DataType;
+
+/**
+ * Selector that chooses files based on whether they are signed or not.
+ *
+ * @since 1.7
+ */
+public class SignedSelector extends DataType implements FileSelector {
+ private IsSigned isSigned = new IsSigned();
+
+ /**
+ * The signature name to check jarfile for.
+ *
+ * @param name signature to look for.
+ */
+ public void setName(String name) {
+ isSigned.setName(name);
+ }
+
+ /**
+ * The heart of the matter. This is where the selector gets to decide
+ * on the inclusion of a file in a particular fileset.
+ *
+ * @param basedir not used by this selector
+ * @param filename not used by this selector
+ * @param file path to file to be selected
+ * @return whether the file should be selected or not
+ */
+ public boolean isSelected(File basedir, String filename, File file) {
+ if (file.isDirectory()) {
+ return false; // Quick return: directories cannot be signed
+ }
+ isSigned.setProject(getProject());
+ isSigned.setFile(file);
+ return isSigned.eval();
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/SizeSelector.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/SizeSelector.java
new file mode 100644
index 00000000..9ff91ad9
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/SizeSelector.java
@@ -0,0 +1,279 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types.selectors;
+
+import java.io.File;
+
+import org.apache.tools.ant.types.Comparison;
+import org.apache.tools.ant.types.EnumeratedAttribute;
+import org.apache.tools.ant.types.Parameter;
+
+/**
+ * Selector that filters files based on their size.
+ *
+ * @since 1.5
+ */
+public class SizeSelector extends BaseExtendSelector {
+
+ /** Constants for kilo, kibi etc */
+ private static final int KILO = 1000;
+ private static final int KIBI = 1024;
+ private static final int KIBI_POS = 4;
+ private static final int MEGA = 1000000;
+ private static final int MEGA_POS = 9;
+ private static final int MEBI = 1048576;
+ private static final int MEBI_POS = 13;
+ private static final long GIGA = 1000000000L;
+ private static final int GIGA_POS = 18;
+ private static final long GIBI = 1073741824L;
+ private static final int GIBI_POS = 22;
+ private static final long TERA = 1000000000000L;
+ private static final int TERA_POS = 27;
+ private static final long TEBI = 1099511627776L;
+ private static final int TEBI_POS = 31;
+ private static final int END_POS = 36;
+
+ /** Used for parameterized custom selector */
+ public static final String SIZE_KEY = "value";
+ /** Used for parameterized custom selector */
+ public static final String UNITS_KEY = "units";
+ /** Used for parameterized custom selector */
+ public static final String WHEN_KEY = "when";
+
+ private long size = -1;
+ private long multiplier = 1;
+ private long sizelimit = -1;
+ private Comparison when = Comparison.EQUAL;
+
+ /**
+ * Creates a new <code>SizeSelector</code> instance.
+ *
+ */
+ public SizeSelector() {
+ }
+
+ /**
+ * Returns a <code>String</code> object representing the specified
+ * SizeSelector. This is "{sizeselector value: " + <"compare",
+ * "less", "more", "equal"> + "}".
+ * @return a string describing this object
+ */
+ public String toString() {
+ StringBuilder buf = new StringBuilder("{sizeselector value: ");
+ buf.append(sizelimit);
+ buf.append("compare: ").append(when.getValue());
+ buf.append("}");
+ return buf.toString();
+ }
+
+ /**
+ * A size selector needs to know what size to base its selecting on.
+ * This will be further modified by the multiplier to get an
+ * actual size limit.
+ *
+ * @param size the size to select against expressed in units.
+ */
+ public void setValue(long size) {
+ this.size = size;
+ if (multiplier != 0 && size > -1) {
+ sizelimit = size * multiplier;
+ }
+ }
+
+ /**
+ * Sets the units to use for the comparison. This is a little
+ * complicated because common usage has created standards that
+ * play havoc with capitalization rules. Thus, some people will
+ * use "K" for indicating 1000's, when the SI standard calls for
+ * "k". Others have tried to introduce "K" as a multiple of 1024,
+ * but that falls down when you reach "M", since "m" is already
+ * defined as 0.001.
+ * <p>
+ * To get around this complexity, a number of standards bodies
+ * have proposed the 2^10 standard, and at least one has adopted
+ * it. But we are still left with a populace that isn't clear on
+ * how capitalization should work.
+ * <p>
+ * We therefore ignore capitalization as much as possible.
+ * Completely mixed case is not possible, but all upper and lower
+ * forms are accepted for all long and short forms. Since we have
+ * no need to work with the 0.001 case, this practice works here.
+ * <p>
+ * This function translates all the long and short forms that a
+ * unit prefix can occur in and translates them into a single
+ * multiplier.
+ *
+ * @param units The units to compare the size to, using an
+ * EnumeratedAttribute.
+ */
+ public void setUnits(ByteUnits units) {
+ int i = units.getIndex();
+ multiplier = 0;
+ if (i > -1 && i < KIBI_POS) {
+ multiplier = KILO;
+ } else if (i < MEGA_POS) {
+ multiplier = KIBI;
+ } else if (i < MEBI_POS) {
+ multiplier = MEGA;
+ } else if (i < GIGA_POS) {
+ multiplier = MEBI;
+ } else if (i < GIBI_POS) {
+ multiplier = GIGA;
+ } else if (i < TERA_POS) {
+ multiplier = GIBI;
+ } else if (i < TEBI_POS) {
+ multiplier = TERA;
+ } else if (i < END_POS) {
+ multiplier = TEBI;
+ }
+ if (multiplier > 0 && size > -1) {
+ sizelimit = size * multiplier;
+ }
+ }
+
+ /**
+ * This specifies when the file should be selected, whether it be
+ * when the file matches a particular size, when it is smaller,
+ * or whether it is larger.
+ *
+ * @param when The comparison to perform, an EnumeratedAttribute.
+ */
+ public void setWhen(SizeComparisons when) {
+ this.when = when;
+ }
+
+ /**
+ * When using this as a custom selector, this method will be called.
+ * It translates each parameter into the appropriate setXXX() call.
+ *
+ * @param parameters the complete set of parameters for this selector.
+ */
+ public void setParameters(Parameter[] parameters) {
+ super.setParameters(parameters);
+ if (parameters != null) {
+ for (int i = 0; i < parameters.length; i++) {
+ String paramname = parameters[i].getName();
+ if (SIZE_KEY.equalsIgnoreCase(paramname)) {
+ try {
+ setValue(Long.parseLong(parameters[i].getValue()));
+ } catch (NumberFormatException nfe) {
+ setError("Invalid size setting "
+ + parameters[i].getValue());
+ }
+ } else if (UNITS_KEY.equalsIgnoreCase(paramname)) {
+ ByteUnits units = new ByteUnits();
+ units.setValue(parameters[i].getValue());
+ setUnits(units);
+ } else if (WHEN_KEY.equalsIgnoreCase(paramname)) {
+ SizeComparisons scmp = new SizeComparisons();
+ scmp.setValue(parameters[i].getValue());
+ setWhen(scmp);
+ } else {
+ setError("Invalid parameter " + paramname);
+ }
+ }
+ }
+ }
+
+ /**
+ * <p>Checks to make sure all settings are kosher. In this case, it
+ * means that the size attribute has been set (to a positive value),
+ * that the multiplier has a valid setting, and that the size limit
+ * is valid. Since the latter is a calculated value, this can only
+ * fail due to a programming error.
+ * </p>
+ * <p>If a problem is detected, the setError() method is called.
+ * </p>
+ */
+ public void verifySettings() {
+ if (size < 0) {
+ setError("The value attribute is required, and must be positive");
+ } else if (multiplier < 1) {
+ setError("Invalid Units supplied, must be K,Ki,M,Mi,G,Gi,T,or Ti");
+ } else if (sizelimit < 0) {
+ setError("Internal error: Code is not setting sizelimit correctly");
+ }
+ }
+
+ /**
+ * The heart of the matter. This is where the selector gets to decide
+ * on the inclusion of a file in a particular fileset.
+ *
+ * @param basedir A java.io.File object for the base directory.
+ * @param filename The name of the file to check.
+ * @param file A File object for this filename.
+ * @return whether the file should be selected or not.
+ */
+ public boolean isSelected(File basedir, String filename, File file) {
+
+ // throw BuildException on error
+ validate();
+
+ // Directory size never selected for
+ if (file.isDirectory()) {
+ return true;
+ }
+ long diff = file.length() - sizelimit;
+ return when.evaluate(diff == 0 ? 0 : (int) (diff / Math.abs(diff)));
+ }
+
+
+ /**
+ * Enumerated attribute with the values for units.
+ * <p>
+ * This treats the standard SI units as representing powers of ten,
+ * as they should. If you want the powers of 2 that approximate
+ * the SI units, use the first two characters followed by a
+ * <code>bi</code>. So 1024 (2^10) becomes <code>kibi</code>,
+ * 1048576 (2^20) becomes <code>mebi</code>, 1073741824 (2^30)
+ * becomes <code>gibi</code>, and so on. The symbols are also
+ * accepted, and these are the first letter capitalized followed
+ * by an <code>i</code>. <code>Ki</code>, <code>Mi</code>,
+ * <code>Gi</code>, and so on. Capitalization variations on these
+ * are also accepted.
+ * <p>
+ * This binary prefix system is approved by the IEC and appears on
+ * its way for approval by other agencies, but it is not an SI
+ * standard. It disambiguates things for us, though.
+ */
+ public static class ByteUnits extends EnumeratedAttribute {
+ /**
+ * @return the values as an array of strings
+ */
+ public String[] getValues() {
+ return new String[]{"K", "k", "kilo", "KILO",
+ "Ki", "KI", "ki", "kibi", "KIBI",
+ "M", "m", "mega", "MEGA",
+ "Mi", "MI", "mi", "mebi", "MEBI",
+ "G", "g", "giga", "GIGA",
+ "Gi", "GI", "gi", "gibi", "GIBI",
+ "T", "t", "tera", "TERA",
+ /* You wish! */ "Ti", "TI", "ti", "tebi", "TEBI"
+ };
+ }
+ }
+
+ /**
+ * Enumerated attribute with the values for size comparison.
+ */
+ public static class SizeComparisons extends Comparison {
+ }
+
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/TokenizedPath.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/TokenizedPath.java
new file mode 100644
index 00000000..a712759c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/TokenizedPath.java
@@ -0,0 +1,222 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types.selectors;
+
+import java.io.File;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.util.FileUtils;
+import org.apache.tools.ant.util.SymbolicLinkUtils;
+
+/**
+ * Container for a path that has been split into its components.
+ * @since 1.8.0
+ */
+public class TokenizedPath {
+
+ /**
+ * Instance that holds no tokens at all.
+ */
+ public static final TokenizedPath EMPTY_PATH =
+ new TokenizedPath("", new String[0]);
+
+ /** Helper. */
+ private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+ /** Helper. */
+ private static final SymbolicLinkUtils SYMLINK_UTILS =
+ SymbolicLinkUtils.getSymbolicLinkUtils();
+ /** iterations for case-sensitive scanning. */
+ private static final boolean[] CS_SCAN_ONLY = new boolean[] {true};
+ /** iterations for non-case-sensitive scanning. */
+ private static final boolean[] CS_THEN_NON_CS = new boolean[] {true, false};
+
+ private final String path;
+ private final String[] tokenizedPath;
+
+ /**
+ * Initialize the TokenizedPath by parsing it.
+ * @param path The path to tokenize. Must not be
+ * <code>null</code>.
+ */
+ public TokenizedPath(String path) {
+ this(path, SelectorUtils.tokenizePathAsArray(path));
+ }
+
+ /**
+ * Creates a new path as a child of another path.
+ *
+ * @param parent the parent path
+ * @param child the child, must not contain the file separator
+ */
+ public TokenizedPath(TokenizedPath parent, String child) {
+ if (parent.path.length() > 0
+ && parent.path.charAt(parent.path.length() - 1)
+ != File.separatorChar) {
+ path = parent.path + File.separatorChar + child;
+ } else {
+ path = parent.path + child;
+ }
+ tokenizedPath = new String[parent.tokenizedPath.length + 1];
+ System.arraycopy(parent.tokenizedPath, 0, tokenizedPath, 0,
+ parent.tokenizedPath.length);
+ tokenizedPath[parent.tokenizedPath.length] = child;
+ }
+
+ /* package */ TokenizedPath(String path, String[] tokens) {
+ this.path = path;
+ this.tokenizedPath = tokens;
+ }
+
+ /**
+ * @return The original path String
+ */
+ @Override
+ public String toString() {
+ return path;
+ }
+
+ /**
+ * The depth (or length) of a path.
+ */
+ public int depth() {
+ return tokenizedPath.length;
+ }
+
+ /* package */ String[] getTokens() {
+ return tokenizedPath;
+ }
+
+ /**
+ * From <code>base</code> traverse the filesystem in order to find
+ * a file that matches the given name.
+ *
+ * @param base base File (dir).
+ * @param cs whether to scan case-sensitively.
+ * @return File object that points to the file in question or null.
+ */
+ public File findFile(File base, final boolean cs) {
+ String[] tokens = tokenizedPath;
+ if (FileUtils.isAbsolutePath(path)) {
+ if (base == null) {
+ String[] s = FILE_UTILS.dissect(path);
+ base = new File(s[0]);
+ tokens = SelectorUtils.tokenizePathAsArray(s[1]);
+ } else {
+ File f = FILE_UTILS.normalize(path);
+ String s = FILE_UTILS.removeLeadingPath(base, f);
+ if (s.equals(f.getAbsolutePath())) {
+ //removing base from path yields no change; path
+ //not child of base
+ return null;
+ }
+ tokens = SelectorUtils.tokenizePathAsArray(s);
+ }
+ }
+ return findFile(base, tokens, cs);
+ }
+
+ /**
+ * Do we have to traverse a symlink when trying to reach path from
+ * basedir?
+ * @param base base File (dir).
+ */
+ public boolean isSymlink(File base) {
+ for (int i = 0; i < tokenizedPath.length; i++) {
+ try {
+ if ((base != null
+ && SYMLINK_UTILS.isSymbolicLink(base, tokenizedPath[i]))
+ ||
+ (base == null
+ && SYMLINK_UTILS.isSymbolicLink(tokenizedPath[i]))
+ ) {
+ return true;
+ }
+ base = new File(base, tokenizedPath[i]);
+ } catch (java.io.IOException ioe) {
+ String msg = "IOException caught while checking "
+ + "for links, couldn't get canonical path!";
+ // will be caught and redirected to Ant's logging system
+ System.err.println(msg);
+ }
+ }
+ return false;
+ }
+
+ /**
+ * true if the original paths are equal.
+ */
+ @Override
+ public boolean equals(Object o) {
+ return o instanceof TokenizedPath
+ && path.equals(((TokenizedPath) o).path);
+ }
+
+ @Override
+ public int hashCode() {
+ return path.hashCode();
+ }
+
+ /**
+ * From <code>base</code> traverse the filesystem in order to find
+ * a file that matches the given stack of names.
+ *
+ * @param base base File (dir) - must not be null.
+ * @param pathElements array of path elements (dirs...file).
+ * @param cs whether to scan case-sensitively.
+ * @return File object that points to the file in question or null.
+ */
+ private static File findFile(File base, final String[] pathElements,
+ final boolean cs) {
+ for (int current = 0; current < pathElements.length; current++) {
+ if (!base.isDirectory()) {
+ return null;
+ }
+ String[] files = base.list();
+ if (files == null) {
+ throw new BuildException("IO error scanning directory "
+ + base.getAbsolutePath());
+ }
+ boolean found = false;
+ boolean[] matchCase = cs ? CS_SCAN_ONLY : CS_THEN_NON_CS;
+ for (int i = 0; !found && i < matchCase.length; i++) {
+ for (int j = 0; !found && j < files.length; j++) {
+ if (matchCase[i]
+ ? files[j].equals(pathElements[current])
+ : files[j].equalsIgnoreCase(pathElements[current])) {
+ base = new File(base, files[j]);
+ found = true;
+ }
+ }
+ }
+ if (!found) {
+ return null;
+ }
+ }
+ return pathElements.length == 0 && !base.isDirectory() ? null : base;
+ }
+
+ /**
+ * Creates a TokenizedPattern from the same tokens that make up
+ * this path.
+ */
+ public TokenizedPattern toPattern() {
+ return new TokenizedPattern(path, tokenizedPath);
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/TokenizedPattern.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/TokenizedPattern.java
new file mode 100644
index 00000000..dbe7ec81
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/TokenizedPattern.java
@@ -0,0 +1,177 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types.selectors;
+
+import java.io.File;
+
+/**
+ * Provides reusable path pattern matching. PathPattern is preferable
+ * to equivalent SelectorUtils methods if you need to execute multiple
+ * matching with the same pattern because here the pattern itself will
+ * be parsed only once.
+ * @see SelectorUtils#matchPath(String, String)
+ * @see SelectorUtils#matchPath(String, String, boolean)
+ * @since 1.8.0
+ */
+public class TokenizedPattern {
+
+ /**
+ * Instance that holds no tokens at all.
+ */
+ public static final TokenizedPattern EMPTY_PATTERN =
+ new TokenizedPattern("", new String[0]);
+
+ private final String pattern;
+ private final String[] tokenizedPattern;
+
+ /**
+ * Initialize the PathPattern by parsing it.
+ * @param pattern The pattern to match against. Must not be
+ * <code>null</code>.
+ */
+ public TokenizedPattern(String pattern) {
+ this(pattern, SelectorUtils.tokenizePathAsArray(pattern));
+ }
+
+ TokenizedPattern(String pattern, String[] tokens) {
+ this.pattern = pattern;
+ this.tokenizedPattern = tokens;
+ }
+
+ /**
+ * Tests whether or not a given path matches a given pattern.
+ *
+ * @param path The path to match, as a String. Must not be
+ * <code>null</code>.
+ * @param isCaseSensitive Whether or not matching should be performed
+ * case sensitively.
+ *
+ * @return <code>true</code> if the pattern matches against the string,
+ * or <code>false</code> otherwise.
+ */
+ public boolean matchPath(TokenizedPath path, boolean isCaseSensitive) {
+ return SelectorUtils.matchPath(tokenizedPattern, path.getTokens(),
+ isCaseSensitive);
+ }
+
+ /**
+ * Tests whether or not this pattern matches the start of
+ * a path.
+ */
+ public boolean matchStartOf(TokenizedPath path,
+ boolean caseSensitive) {
+ return SelectorUtils.matchPatternStart(tokenizedPattern,
+ path.getTokens(), caseSensitive);
+ }
+
+ /**
+ * @return The pattern String
+ */
+ public String toString() {
+ return pattern;
+ }
+
+ public String getPattern() {
+ return pattern;
+ }
+
+ /**
+ * true if the original patterns are equal.
+ */
+ public boolean equals(Object o) {
+ return o instanceof TokenizedPattern
+ && pattern.equals(((TokenizedPattern) o).pattern);
+ }
+
+ public int hashCode() {
+ return pattern.hashCode();
+ }
+
+ /**
+ * The depth (or length) of a pattern.
+ */
+ public int depth() {
+ return tokenizedPattern.length;
+ }
+
+ /**
+ * Does the tokenized pattern contain the given string?
+ */
+ public boolean containsPattern(String pat) {
+ for (int i = 0; i < tokenizedPattern.length; i++) {
+ if (tokenizedPattern[i].equals(pat)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Returns a new TokenizedPath where all tokens of this pattern to
+ * the right containing wildcards have been removed
+ * @return the leftmost part of the pattern without wildcards
+ */
+ public TokenizedPath rtrimWildcardTokens() {
+ StringBuilder sb = new StringBuilder();
+ int newLen = 0;
+ for (; newLen < tokenizedPattern.length; newLen++) {
+ if (SelectorUtils.hasWildcards(tokenizedPattern[newLen])) {
+ break;
+ }
+ if (newLen > 0
+ && sb.charAt(sb.length() - 1) != File.separatorChar) {
+ sb.append(File.separator);
+ }
+ sb.append(tokenizedPattern[newLen]);
+ }
+ if (newLen == 0) {
+ return TokenizedPath.EMPTY_PATH;
+ }
+ String[] newPats = new String[newLen];
+ System.arraycopy(tokenizedPattern, 0, newPats, 0, newLen);
+ return new TokenizedPath(sb.toString(), newPats);
+ }
+
+ /**
+ * true if the last token equals the given string.
+ */
+ public boolean endsWith(String s) {
+ return tokenizedPattern.length > 0
+ && tokenizedPattern[tokenizedPattern.length - 1].equals(s);
+ }
+
+ /**
+ * Returns a new pattern without the last token of this pattern.
+ */
+ public TokenizedPattern withoutLastToken() {
+ if (tokenizedPattern.length == 0) {
+ throw new IllegalStateException("can't strip a token from nothing");
+ } else if (tokenizedPattern.length == 1) {
+ return EMPTY_PATTERN;
+ } else {
+ String toStrip = tokenizedPattern[tokenizedPattern.length - 1];
+ int index = pattern.lastIndexOf(toStrip);
+ String[] tokens = new String[tokenizedPattern.length - 1];
+ System.arraycopy(tokenizedPattern, 0, tokens, 0,
+ tokenizedPattern.length - 1);
+ return new TokenizedPattern(pattern.substring(0, index), tokens);
+ }
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/TypeSelector.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/TypeSelector.java
new file mode 100644
index 00000000..fd3684d6
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/TypeSelector.java
@@ -0,0 +1,135 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types.selectors;
+
+import java.io.File;
+
+import org.apache.tools.ant.types.EnumeratedAttribute;
+import org.apache.tools.ant.types.Parameter;
+
+/**
+ * Selector that selects a certain kind of file: directory or regular.
+ *
+ * @since 1.6
+ */
+public class TypeSelector extends BaseExtendSelector {
+
+ private String type = null;
+
+ /** Key to used for parameterized custom selector */
+ public static final String TYPE_KEY = "type";
+
+ /**
+ * Creates a new <code>TypeSelector</code> instance.
+ *
+ */
+ public TypeSelector() {
+ }
+
+ /**
+ * @return a string describing this object
+ */
+ public String toString() {
+ StringBuilder buf = new StringBuilder("{typeselector type: ");
+ buf.append(type);
+ buf.append("}");
+ return buf.toString();
+ }
+
+ /**
+ * Set the type of file to require.
+ * @param fileTypes the type of file - file or dir
+ */
+ public void setType(FileType fileTypes) {
+ this.type = fileTypes.getValue();
+ }
+
+ /**
+ * When using this as a custom selector, this method will be called.
+ * It translates each parameter into the appropriate setXXX() call.
+ *
+ * @param parameters the complete set of parameters for this selector
+ */
+ public void setParameters(Parameter[] parameters) {
+ super.setParameters(parameters);
+ if (parameters != null) {
+ for (int i = 0; i < parameters.length; i++) {
+ String paramname = parameters[i].getName();
+ if (TYPE_KEY.equalsIgnoreCase(paramname)) {
+ FileType t = new FileType();
+ t.setValue(parameters[i].getValue());
+ setType(t);
+ } else {
+ setError("Invalid parameter " + paramname);
+ }
+ }
+ }
+ }
+
+ /**
+ * Checks to make sure all settings are kosher. In this case, it
+ * means that the pattern attribute has been set.
+ *
+ */
+ public void verifySettings() {
+ if (type == null) {
+ setError("The type attribute is required");
+ }
+ }
+
+ /**
+ * The heart of the matter. This is where the selector gets to decide
+ * on the inclusion of a file in a particular fileset.
+ *
+ * @param basedir the base directory the scan is being done from
+ * @param filename is the name of the file to check
+ * @param file is a java.io.File object the selector can use
+ * @return whether the file should be selected or not
+ */
+ public boolean isSelected(File basedir, String filename, File file) {
+
+ // throw BuildException on error
+ validate();
+
+ if (file.isDirectory()) {
+ return type.equals(FileType.DIR);
+ } else {
+ return type.equals(FileType.FILE);
+ }
+ }
+
+ /**
+ * Enumerated attribute with the values for types of file
+ */
+ public static class FileType extends EnumeratedAttribute {
+ /** the string value for file */
+ public static final String FILE = "file";
+ /** the string value for dir */
+ public static final String DIR = "dir";
+
+ /**
+ * @return the values as an array of strings
+ */
+ public String[] getValues() {
+ return new String[]{FILE, DIR};
+ }
+ }
+
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/WritableSelector.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/WritableSelector.java
new file mode 100644
index 00000000..c7391f02
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/WritableSelector.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types.selectors;
+
+import java.io.File;
+
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.resources.FileProvider;
+import org.apache.tools.ant.types.resources.selectors.ResourceSelector;
+
+/**
+ * A selector that selects writable files.
+ *
+ * <p>Writable is defined in terms of java.io.File#canWrite, this
+ * means the selector will accept any file that exists and is
+ * writable by the application.</p>
+ *
+ * @since Ant 1.8.0
+ */
+public class WritableSelector implements FileSelector, ResourceSelector {
+
+ public boolean isSelected(File basedir, String filename, File file) {
+ return file != null && file.canWrite();
+ }
+
+ public boolean isSelected(Resource r) {
+ FileProvider fp = r.as(FileProvider.class);
+ return fp != null && isSelected(null, null, fp.getFile());
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/modifiedselector/Algorithm.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/modifiedselector/Algorithm.java
new file mode 100644
index 00000000..82e043b5
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/modifiedselector/Algorithm.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types.selectors.modifiedselector;
+
+
+import java.io.File;
+
+
+/**
+ * The <i>Algorithm</i> defines how a value for a file is computed.
+ * It must be sure that multiple calls for the same file results in the
+ * same value.
+ * The implementing class should implement a useful toString() method.
+ *
+ * @version 2003-09-13
+ * @since Ant 1.6
+ */
+public interface Algorithm {
+
+ /**
+ * Checks its prerequisites.
+ * @return <i>true</i> if all is ok, otherwise <i>false</i>.
+ */
+ boolean isValid();
+
+ /**
+ * Get the value for a file.
+ * @param file File object for which the value should be evaluated.
+ * @return The value for that file
+ */
+ String getValue(File file);
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/modifiedselector/Cache.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/modifiedselector/Cache.java
new file mode 100644
index 00000000..13c74c2b
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/modifiedselector/Cache.java
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types.selectors.modifiedselector;
+
+
+import java.util.Iterator;
+
+
+/**
+ * A Cache let the user store key-value-pairs in a permanent manner and access
+ * them.
+ * It is possible that a client uses get() before load() therefore the
+ * implementation must ensure that no error occurred because of the wrong
+ * <i>order</i>.
+ * The implementing class should implement a useful toString() method.
+ *
+ * @version 2003-09-13
+ * @since Ant 1.6
+ */
+public interface Cache {
+
+ /**
+ * Checks its prerequisites.
+ * @return <i>true</i> if all is ok, otherwise <i>false</i>.
+ */
+ boolean isValid();
+
+ /** Deletes the cache. If file based the file has to be deleted also. */
+ void delete();
+
+ /** Loads the cache, must handle not existing cache. */
+ void load();
+
+ /** Saves modification of the cache. */
+ void save();
+
+ /**
+ * Returns a value for a given key from the cache.
+ * @param key the key
+ * @return the stored value
+ */
+ Object get(Object key);
+
+ /**
+ * Saves a key-value-pair in the cache.
+ * @param key the key
+ * @param value the value
+ */
+ void put(Object key, Object value);
+
+ /**
+ * Returns an iterator over the keys in the cache.
+ * @return An iterator over the keys.
+ */
+ Iterator<String> iterator();
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/modifiedselector/ChecksumAlgorithm.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/modifiedselector/ChecksumAlgorithm.java
new file mode 100644
index 00000000..210d5dc9
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/modifiedselector/ChecksumAlgorithm.java
@@ -0,0 +1,151 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types.selectors.modifiedselector;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.security.NoSuchAlgorithmException;
+import java.util.Locale;
+import java.util.zip.Adler32;
+import java.util.zip.CRC32;
+import java.util.zip.CheckedInputStream;
+import java.util.zip.Checksum;
+
+import org.apache.tools.ant.BuildException;
+
+
+/**
+ * Computes a 'checksum' for the content of file using
+ * java.util.zip.CRC32 and java.util.zip.Adler32.
+ * Use of this algorithm doesn't require any additional nested <param>s.
+ * Supported <param>s are:
+ * <table>
+ * <tr>
+ * <th>name</th><th>values</th><th>description</th><th>required</th>
+ * </tr>
+ * <tr>
+ * <td> algorithm.algorithm </td>
+ * <td> ADLER | CRC ( default ) </td>
+ * <td> name of the algorithm the checksum should use </td>
+ * <td> no, defaults to CRC </td>
+ * </tr>
+ * </table>
+ *
+ * @version 2004-06-17
+ * @since Ant 1.7
+ */
+public class ChecksumAlgorithm implements Algorithm {
+
+
+ // ----- member variables -----
+
+
+ /**
+ * Checksum algorithm to be used.
+ */
+ private String algorithm = "CRC";
+
+ /**
+ * Checksum interface instance
+ */
+ private Checksum checksum = null;
+
+
+ // ----- Algorithm-Configuration -----
+
+
+ /**
+ * Specifies the algorithm to be used to compute the checksum.
+ * Defaults to "CRC". Other popular algorithms like "ADLER" may be used as well.
+ * @param algorithm the digest algorithm to use
+ */
+ public void setAlgorithm(String algorithm) {
+ this.algorithm =
+ algorithm != null ? algorithm.toUpperCase(Locale.ENGLISH) : null;
+ }
+
+
+ /** Initialize the checksum interface. */
+ public void initChecksum() {
+ if (checksum != null) {
+ return;
+ }
+ if ("CRC".equals(algorithm)) {
+ checksum = new CRC32();
+ } else if ("ADLER".equals(algorithm)) {
+ checksum = new Adler32();
+ } else {
+ throw new BuildException(new NoSuchAlgorithmException());
+ }
+ }
+
+
+ // ----- Logic -----
+
+
+ /**
+ * This algorithm supports only CRC and Adler.
+ * @return <i>true</i> if all is ok, otherwise <i>false</i>.
+ */
+ public boolean isValid() {
+ return "CRC".equals(algorithm) || "ADLER".equals(algorithm);
+ }
+
+
+ /**
+ * Computes a value for a file content with the specified checksum algorithm.
+ * @param file File object for which the value should be evaluated.
+ * @return The value for that file
+ */
+ public String getValue(File file) {
+ initChecksum();
+ String rval = null;
+
+ try {
+ if (file.canRead()) {
+ checksum.reset();
+ FileInputStream fis = new FileInputStream(file);
+ CheckedInputStream check = new CheckedInputStream(fis, checksum);
+ BufferedInputStream in = new BufferedInputStream(check);
+ while (in.read() != -1) {
+ // Read the file
+ }
+ rval = Long.toString(check.getChecksum().getValue());
+ in.close();
+ }
+ } catch (Exception e) {
+ rval = null;
+ }
+ return rval;
+ }
+
+
+ /**
+ * Override Object.toString().
+ * @return some information about this algorithm.
+ */
+ public String toString() {
+ StringBuilder buf = new StringBuilder();
+ buf.append("<ChecksumAlgorithm:");
+ buf.append("algorithm=").append(algorithm);
+ buf.append(">");
+ return buf.toString();
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/modifiedselector/DigestAlgorithm.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/modifiedselector/DigestAlgorithm.java
new file mode 100644
index 00000000..085b4fe7
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/modifiedselector/DigestAlgorithm.java
@@ -0,0 +1,208 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types.selectors.modifiedselector;
+
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.security.DigestInputStream;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.util.Locale;
+
+import org.apache.tools.ant.BuildException;
+
+
+/**
+ * Computes a 'hashvalue' for the content of file using
+ * java.security.MessageDigest.
+ * Use of this algorithm doesn't require any additional nested <param>s.
+ * Supported <param>s are:
+ * <table>
+ * <tr>
+ * <th>name</th><th>values</th><th>description</th><th>required</th>
+ * </tr>
+ * <tr>
+ * <td> algorithm.algorithm </td>
+ * <td> MD5 | SHA (default provider) </td>
+ * <td> name of the algorithm the provider should use </td>
+ * <td> no, defaults to MD5 </td>
+ * </tr>
+ * <tr>
+ * <td> algorithm.provider </td>
+ * <td> </td>
+ * <td> name of the provider to use </td>
+ * <td> no, defaults to <i>null</i> </td>
+ * </tr>
+ * </table>
+ *
+ * @version 2004-07-08
+ * @since Ant 1.6
+ */
+public class DigestAlgorithm implements Algorithm {
+
+ private static final int BYTE_MASK = 0xFF;
+ private static final int BUFFER_SIZE = 8192;
+
+ // ----- member variables -----
+
+
+ /**
+ * MessageDigest algorithm to be used.
+ */
+ private String algorithm = "MD5";
+
+ /**
+ * MessageDigest Algorithm provider
+ */
+ private String provider = null;
+
+ /**
+ * Message Digest instance
+ */
+ private MessageDigest messageDigest = null;
+
+ /**
+ * Size of the read buffer to use.
+ */
+ private int readBufferSize = BUFFER_SIZE;
+
+
+ // ----- Algorithm-Configuration -----
+
+
+ /**
+ * Specifies the algorithm to be used to compute the checksum.
+ * Defaults to "MD5". Other popular algorithms like "SHA" may be used as well.
+ * @param algorithm the digest algorithm to use
+ */
+ public void setAlgorithm(String algorithm) {
+ this.algorithm = algorithm != null
+ ? algorithm.toUpperCase(Locale.ENGLISH) : null;
+ }
+
+
+ /**
+ * Sets the MessageDigest algorithm provider to be used
+ * to calculate the checksum.
+ * @param provider provider to use
+ */
+ public void setProvider(String provider) {
+ this.provider = provider;
+ }
+
+
+ /** Initialize the security message digest. */
+ public void initMessageDigest() {
+ if (messageDigest != null) {
+ return;
+ }
+
+ if ((provider != null) && !"".equals(provider) && !"null".equals(provider)) {
+ try {
+ messageDigest = MessageDigest.getInstance(algorithm, provider);
+ } catch (NoSuchAlgorithmException noalgo) {
+ throw new BuildException(noalgo);
+ } catch (NoSuchProviderException noprovider) {
+ throw new BuildException(noprovider);
+ }
+ } else {
+ try {
+ messageDigest = MessageDigest.getInstance(algorithm);
+ } catch (NoSuchAlgorithmException noalgo) {
+ throw new BuildException(noalgo);
+ }
+ }
+ }
+
+
+ // ----- Logic -----
+
+
+ /**
+ * This algorithm supports only MD5 and SHA.
+ * @return <i>true</i> if all is ok, otherwise <i>false</i>.
+ */
+ public boolean isValid() {
+ return "SHA".equals(algorithm) || "MD5".equals(algorithm);
+ }
+
+
+ /**
+ * Computes a value for a file content with the specified digest algorithm.
+ * @param file File object for which the value should be evaluated.
+ * @return The value for that file
+ */
+ // implementation adapted from ...taskdefs.Checksum, thanks to Magesh for hint
+ public String getValue(File file) {
+ initMessageDigest();
+ String checksum = null;
+ try {
+ if (!file.canRead()) {
+ return null;
+ }
+ FileInputStream fis = null;
+
+ byte[] buf = new byte[readBufferSize];
+ try {
+ messageDigest.reset();
+ fis = new FileInputStream(file);
+ DigestInputStream dis = new DigestInputStream(fis,
+ messageDigest);
+ while (dis.read(buf, 0, readBufferSize) != -1) {
+ // do nothing
+ }
+ dis.close();
+ fis.close();
+ fis = null;
+ byte[] fileDigest = messageDigest.digest();
+ StringBuffer checksumSb = new StringBuffer();
+ for (int i = 0; i < fileDigest.length; i++) {
+ String hexStr
+ = Integer.toHexString(BYTE_MASK & fileDigest[i]);
+ if (hexStr.length() < 2) {
+ checksumSb.append("0");
+ }
+ checksumSb.append(hexStr);
+ }
+ checksum = checksumSb.toString();
+ } catch (Exception e) {
+ return null;
+ }
+ } catch (Exception e) {
+ return null;
+ }
+ return checksum;
+ }
+
+
+ /**
+ * Override Object.toString().
+ * @return some information about this algorithm.
+ */
+ public String toString() {
+ StringBuilder buf = new StringBuilder();
+ buf.append("<DigestAlgorithm:");
+ buf.append("algorithm=").append(algorithm);
+ buf.append(";provider=").append(provider);
+ buf.append(">");
+ return buf.toString();
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/modifiedselector/EqualComparator.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/modifiedselector/EqualComparator.java
new file mode 100644
index 00000000..94fb9351
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/modifiedselector/EqualComparator.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types.selectors.modifiedselector;
+
+
+import java.util.Comparator;
+
+
+/**
+ * Simple implementation of Comparator for use in CacheSelector.
+ * compare() returns '0' (should not be selected) if both parameter
+ * are equal otherwise '1' (should be selected).
+ *
+ * @version 2003-09-13
+ * @since Ant 1.6
+ */
+public class EqualComparator implements Comparator<Object> {
+
+ /**
+ * Implements Comparator.compare().
+ * @param o1 the first object
+ * @param o2 the second object
+ * @return 0, if both are equal, otherwise 1
+ */
+ public int compare(Object o1, Object o2) {
+ if (o1 == null) {
+ if (o2 == null) {
+ return 1;
+ }
+ return 0;
+ }
+ return (o1.equals(o2)) ? 0 : 1;
+ }
+
+ /**
+ * Override Object.toString().
+ * @return information about this comparator
+ */
+ public String toString() {
+ return "EqualComparator";
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/modifiedselector/HashvalueAlgorithm.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/modifiedselector/HashvalueAlgorithm.java
new file mode 100644
index 00000000..8af9d12e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/modifiedselector/HashvalueAlgorithm.java
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types.selectors.modifiedselector;
+
+import java.io.File;
+import java.io.FileReader;
+import java.io.Reader;
+
+import org.apache.tools.ant.util.FileUtils;
+
+/**
+ * Computes a 'hashvalue' for the content of file using String.hashValue().
+ * Use of this algorithm doesn't require any additional nested <param>s and
+ * doesn't support any.
+ *
+ * @version 2003-09-13
+ * @since Ant 1.6
+ */
+public class HashvalueAlgorithm implements Algorithm {
+
+ /**
+ * This algorithm doesn't need any configuration.
+ * Therefore it's always valid.
+ * @return always true
+ */
+ public boolean isValid() {
+ return true;
+ }
+
+ /**
+ * Computes a 'hashvalue' for a file content.
+ * It reads the content of a file, convert that to String and use the
+ * String.hashCode() method.
+ * @param file The file for which the value should be computed
+ * @return the hashvalue or <i>null</i> if the file couldn't be read
+ */
+ // Because the content is only read the file will not be damaged. I tested
+ // with JPG, ZIP and PDF as binary files.
+ public String getValue(File file) {
+ Reader r = null;
+ try {
+ if (!file.canRead()) {
+ return null;
+ }
+ r = new FileReader(file);
+ int hash = FileUtils.readFully(r).hashCode();
+ return Integer.toString(hash);
+ } catch (Exception e) {
+ return null;
+ } finally {
+ FileUtils.close(r);
+ }
+ }
+
+
+ /**
+ * Override Object.toString().
+ * @return information about this comparator
+ */
+ public String toString() {
+ return "HashvalueAlgorithm";
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/modifiedselector/ModifiedSelector.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/modifiedselector/ModifiedSelector.java
new file mode 100644
index 00000000..9f538098
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/modifiedselector/ModifiedSelector.java
@@ -0,0 +1,971 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types.selectors.modifiedselector;
+
+
+// Java
+import java.io.File;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildEvent;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.BuildListener;
+import org.apache.tools.ant.IntrospectionHelper;
+// Ant
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.EnumeratedAttribute;
+import org.apache.tools.ant.types.Parameter;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.resources.FileResource;
+import org.apache.tools.ant.types.resources.selectors.ResourceSelector;
+import org.apache.tools.ant.types.selectors.BaseExtendSelector;
+import org.apache.tools.ant.util.FileUtils;
+import org.apache.tools.ant.util.ResourceUtils;
+
+
+/**
+ * <p>Selector class that uses <i>Algorithm</i>, <i>Cache</i> and <i>Comparator</i>
+ * for its work.
+ * The <i>Algorithm</i> is used for computing a hashvalue for a file.
+ * The <i>Comparator</i> decides whether to select or not.
+ * The <i>Cache</i> stores the other value for comparison by the <i>Comparator</i>
+ * in a persistent manner.</p>
+ *
+ * <p>The ModifiedSelector is implemented as a <b>CoreSelector</b> and uses default
+ * values for all its attributes therefore the simplest example is <pre>
+ * &lt;copy todir="dest"&gt;
+ * &lt;filelist dir="src"&gt;
+ * &lt;modified/&gt;
+ * &lt;/filelist&gt;
+ * &lt;/copy&gt;
+ * </pre></p>
+ *
+ * <p>The same example rewritten as CoreSelector with setting the all values
+ * (same as defaults are) would be <pre>
+ * &lt;copy todir="dest"&gt;
+ * &lt;filelist dir="src"&gt;
+ * &lt;modified update="true"
+ * cache="propertyfile"
+ * algorithm="digest"
+ * comparator="equal"&gt;
+ * &lt;param name="cache.cachefile" value="cache.properties"/&gt;
+ * &lt;param name="algorithm.algorithm" value="MD5"/&gt;
+ * &lt;/modified&gt;
+ * &lt;/filelist&gt;
+ * &lt;/copy&gt;
+ * </pre></p>
+ *
+ * <p>And the same rewritten as CustomSelector would be<pre>
+ * &lt;copy todir="dest"&gt;
+ * &lt;filelist dir="src"&gt;
+ * &lt;custom class="org.apache.tools.ant.type.selectors.ModifiedSelector"&gt;
+ * &lt;param name="update" value="true"/&gt;
+ * &lt;param name="cache" value="propertyfile"/&gt;
+ * &lt;param name="algorithm" value="digest"/&gt;
+ * &lt;param name="comparator" value="equal"/&gt;
+ * &lt;param name="cache.cachefile" value="cache.properties"/&gt;
+ * &lt;param name="algorithm.algorithm" value="MD5"/&gt;
+ * &lt;/custom&gt;
+ * &lt;/filelist&gt;
+ * &lt;/copy&gt;
+ * </pre></p>
+ *
+ * <p>If you want to provide your own interface implementation you can do
+ * that via the *classname attributes. If the classes are not on Ant's core
+ * classpath, you will have to provide the path via nested &lt;classpath&gt;
+ * element, so that the selector can find the classes. <pre>
+ * &lt;modified cacheclassname="com.mycompany.MyCache"&gt;
+ * &lt;classpath&gt;
+ * &lt;pathelement location="lib/mycompany-antutil.jar"/&gt;
+ * &lt;/classpath&gt;
+ * &lt;/modified&gt;
+ * </pre></p>
+ *
+ * <p>All these three examples copy the files from <i>src</i> to <i>dest</i>
+ * using the ModifiedSelector. The ModifiedSelector uses the <i>PropertyfileCache
+ * </i>, the <i>DigestAlgorithm</i> and the <i>EqualComparator</i> for its
+ * work. The PropertyfileCache stores key-value-pairs in a simple java
+ * properties file. The filename is <i>cache.properties</i>. The <i>update</i>
+ * flag lets the selector update the values in the cache (and on first call
+ * creates the cache). The <i>DigestAlgorithm</i> computes a hashvalue using the
+ * java.security.MessageDigest class with its MD5-Algorithm and its standard
+ * provider. The new computed hashvalue and the stored one are compared by
+ * the <i>EqualComparator</i> which returns 'true' (more correct a value not
+ * equals zero (1)) if the values are not the same using simple String
+ * comparison.</p>
+ *
+ * <p>A useful scenario for this selector is inside a build environment
+ * for homepage generation (e.g. with <a href="http://forrest.apache.org/">
+ * Apache Forrest</a>). <pre>
+ * &lt;target name="generate-and-upload-site"&gt;
+ * &lt;echo&gt; generate the site using forrest &lt;/echo&gt;
+ * &lt;antcall target="site"/&gt;
+ *
+ * &lt;echo&gt; upload the changed files &lt;/echo&gt;
+ * &lt;ftp server="${ftp.server}" userid="${ftp.user}" password="${ftp.pwd}"&gt;
+ * &lt;fileset dir="htdocs/manual"&gt;
+ * &lt;modified/&gt;
+ * &lt;/fileset&gt;
+ * &lt;/ftp&gt;
+ * &lt;/target&gt;
+ * </pre> Here all <b>changed</b> files are uploaded to the server. The
+ * ModifiedSelector saves therefore much upload time.</p>
+ *
+ *
+ * <p>This selector uses reflection for setting the values of its three interfaces
+ * (using org.apache.tools.ant.IntrospectionHelper) therefore no special
+ * 'configuration interfaces' has to be implemented by new caches, algorithms or
+ * comparators. All present <i>set</i>XX methods can be used. E.g. the DigestAlgorithm
+ * can use a specified provider for computing its value. For selecting this
+ * there is a <i>setProvider(String providername)</i> method. So you can use
+ * a nested <i>&lt;param name="algorithm.provider" value="MyProvider"/&gt;</i>.
+ *
+ *
+ * @since Ant 1.6
+ */
+public class ModifiedSelector extends BaseExtendSelector
+ implements BuildListener, ResourceSelector {
+
+ private static final String CACHE_PREFIX = "cache.";
+ private static final String ALGORITHM_PREFIX = "algorithm.";
+ private static final String COMPARATOR_PREFIX = "comparator.";
+
+
+ // ----- attributes -----
+
+
+ /** Cache name for later instantiation. */
+ private CacheName cacheName = null;
+
+ /** User specified classname for Cache. */
+ private String cacheClass;
+
+ /** Algorithm name for later instantiation. */
+ private AlgorithmName algoName = null;
+
+ /** User specified classname for Algorithm. */
+ private String algorithmClass;
+
+ /** Comparator name for later instantiation. */
+ private ComparatorName compName = null;
+
+ /** User specified classname for Comparator. */
+ private String comparatorClass;
+
+ /** Should the cache be updated? */
+ private boolean update = true;
+
+ /** Are directories selected? */
+ private boolean selectDirectories = true;
+
+ /**
+ * Should Resources whithout an InputStream, and
+ * therefore without checking, be selected?
+ */
+ private boolean selectResourcesWithoutInputStream = true;
+
+ /** Delay the writing of the cache file */
+ private boolean delayUpdate = true;
+
+
+ // ----- internal member variables -----
+
+
+ /** How should the cached value and the new one compared? */
+ private Comparator<? super String> comparator = null;
+
+ /** Algorithm for computing new values and updating the cache. */
+ private Algorithm algorithm = null;
+
+ /** The Cache containing the old values. */
+ private Cache cache = null;
+
+ /** Count of modified properties */
+ private int modified = 0;
+
+ /** Flag whether this object is configured. Configuration is only done once. */
+ private boolean isConfigured = false;
+
+ /**
+ * Parameter vector with parameters for later initialization.
+ * @see #configure
+ */
+ private Vector<Parameter> configParameter = new Vector<Parameter>();
+
+ /**
+ * Parameter vector with special parameters for later initialization.
+ * The names have the pattern '*.*', e.g. 'cache.cachefile'.
+ * These parameters are used <b>after</b> the parameters with the pattern '*'.
+ * @see #configure
+ */
+ private Vector<Parameter> specialParameter = new Vector<Parameter>();
+
+ /** The classloader of this class. */
+ private ClassLoader myClassLoader = null;
+
+ /** provided classpath for the classloader */
+ private Path classpath = null;
+
+
+ // ----- constructors -----
+
+
+ /** Bean-Constructor. */
+ public ModifiedSelector() {
+ }
+
+
+ // ----- configuration -----
+
+
+ /** Overrides BaseSelector.verifySettings(). */
+ public void verifySettings() {
+ configure();
+ if (cache == null) {
+ setError("Cache must be set.");
+ } else if (algorithm == null) {
+ setError("Algorithm must be set.");
+ } else if (!cache.isValid()) {
+ setError("Cache must be proper configured.");
+ } else if (!algorithm.isValid()) {
+ setError("Algorithm must be proper configured.");
+ }
+ }
+
+
+ /**
+ * Configures this Selector.
+ * Does this work only once per Selector object.
+ * <p>Because some problems while configuring from <custom>Selector
+ * the configuration is done in the following order:<ol>
+ * <li> collect the configuration data </li>
+ * <li> wait for the first isSelected() call </li>
+ * <li> set the default values </li>
+ * <li> set values for name pattern '*': update, cache, algorithm, comparator </li>
+ * <li> set values for name pattern '*.*: cache.cachefile, ... </li>
+ * </ol></p>
+ * <p>This configuration algorithm is needed because you don't know
+ * the order of arriving config-data. E.g. if you first set the
+ * <i>cache.cachefilename</i> and after that the <i>cache</i> itself,
+ * the default value for cachefilename is used, because setting the
+ * cache implies creating a new Cache instance - with its defaults.</p>
+ */
+ public void configure() {
+ //
+ // ----- The "Singleton" -----
+ //
+ if (isConfigured) {
+ return;
+ }
+ isConfigured = true;
+
+ //
+ // ----- Set default values -----
+ //
+ Project p = getProject();
+ String filename = "cache.properties";
+ File cachefile = null;
+ if (p != null) {
+ // normal use inside Ant
+ cachefile = new File(p.getBaseDir(), filename);
+
+ // set self as a BuildListener to delay cachefile saves
+ getProject().addBuildListener(this);
+ } else {
+ // no reference to project - e.g. during normal JUnit tests
+ cachefile = new File(filename);
+ setDelayUpdate(false);
+ }
+ Cache defaultCache = new PropertiesfileCache(cachefile);
+ Algorithm defaultAlgorithm = new DigestAlgorithm();
+ Comparator<? super String> defaultComparator = new EqualComparator();
+
+ //
+ // ----- Set the main attributes, pattern '*' -----
+ //
+ for (Parameter parameter : configParameter) {
+ if (parameter.getName().indexOf(".") > 0) {
+ // this is a *.* parameter for later use
+ specialParameter.add(parameter);
+ } else {
+ useParameter(parameter);
+ }
+ }
+ configParameter = new Vector<Parameter>();
+
+ // specify the algorithm classname
+ if (algoName != null) {
+ // use Algorithm defined via name
+ if ("hashvalue".equals(algoName.getValue())) {
+ algorithm = new HashvalueAlgorithm();
+ } else if ("digest".equals(algoName.getValue())) {
+ algorithm = new DigestAlgorithm();
+ } else if ("checksum".equals(algoName.getValue())) {
+ algorithm = new ChecksumAlgorithm();
+ }
+ } else {
+ if (algorithmClass != null) {
+ // use Algorithm specified by classname
+ algorithm = loadClass(
+ algorithmClass,
+ "is not an Algorithm.",
+ Algorithm.class);
+ } else {
+ // nothing specified - use default
+ algorithm = defaultAlgorithm;
+ }
+ }
+
+ // specify the cache classname
+ if (cacheName != null) {
+ // use Cache defined via name
+ if ("propertyfile".equals(cacheName.getValue())) {
+ cache = new PropertiesfileCache();
+ }
+ } else {
+ if (cacheClass != null) {
+ // use Cache specified by classname
+ cache = loadClass(cacheClass, "is not a Cache.", Cache.class);
+ } else {
+ // nothing specified - use default
+ cache = defaultCache;
+ }
+ }
+
+ // specify the comparator classname
+ if (compName != null) {
+ // use Algorithm defined via name
+ if ("equal".equals(compName.getValue())) {
+ comparator = new EqualComparator();
+ } else if ("rule".equals(compName.getValue())) {
+ // TODO there is a problem with the constructor for the RBC.
+ // you have to provide the rules in the constructors - no setters
+ // available.
+ throw new BuildException("RuleBasedCollator not yet supported.");
+ // Have to think about lazy initialization here... JHM
+ // comparator = new java.text.RuleBasedCollator();
+ }
+ } else {
+ if (comparatorClass != null) {
+ // use Algorithm specified by classname
+ @SuppressWarnings("unchecked")
+ Comparator<? super String> localComparator = loadClass(comparatorClass, "is not a Comparator.", Comparator.class);
+ comparator = localComparator;
+ } else {
+ // nothing specified - use default
+ comparator = defaultComparator;
+ }
+ }
+
+ //
+ // ----- Set the special attributes, pattern '*.*' -----
+ //
+ for (Iterator<Parameter> itSpecial = specialParameter.iterator(); itSpecial.hasNext();) {
+ Parameter par = itSpecial.next();
+ useParameter(par);
+ }
+ specialParameter = new Vector<Parameter>();
+ }
+
+
+ /**
+ * Loads the specified class and initializes an object of that class.
+ * Throws a BuildException using the given message if an error occurs during
+ * loading/instantiation or if the object is not from the given type.
+ * @param classname the classname
+ * @param msg the message-part for the BuildException
+ * @param type the type to check against
+ * @return a castable object
+ */
+ protected <T> T loadClass(String classname, String msg, Class<? extends T> type) {
+ try {
+ // load the specified class
+ ClassLoader cl = getClassLoader();
+ Class<?> clazz = null;
+ if (cl != null) {
+ clazz = cl.loadClass(classname);
+ } else {
+ clazz = Class.forName(classname);
+ }
+
+ Object rv = clazz.newInstance();
+
+ if (!type.isInstance(rv)) {
+ throw new BuildException("Specified class (" + classname + ") " + msg);
+ }
+ return (T) rv;
+ } catch (ClassNotFoundException e) {
+ throw new BuildException("Specified class (" + classname + ") not found.");
+ } catch (Exception e) {
+ throw new BuildException(e);
+ }
+ }
+
+
+ // ----- the selection work -----
+
+
+ /**
+ * Implementation of ResourceSelector.isSelected().
+ *
+ * @param resource The resource to check
+ * @return whether the resource is selected
+ * @see ResourceSelector#isSelected(Resource)
+ */
+ public boolean isSelected(Resource resource) {
+ if (resource.isFilesystemOnly()) {
+ // We have a 'resourced' file, so reconvert it and use
+ // the 'old' implementation.
+ FileResource fileResource = (FileResource) resource;
+ File file = fileResource.getFile();
+ String filename = fileResource.getName();
+ File basedir = fileResource.getBaseDir();
+ return isSelected(basedir, filename, file);
+ } else {
+ try {
+ // How to handle non-file-Resources? I copy temporarily the
+ // resource to a file and use the file-implementation.
+ FileUtils fu = FileUtils.getFileUtils();
+ File tmpFile = fu.createTempFile("modified-", ".tmp", null, true, false);
+ Resource tmpResource = new FileResource(tmpFile);
+ ResourceUtils.copyResource(resource, tmpResource);
+ boolean isSelected = isSelected(tmpFile.getParentFile(),
+ tmpFile.getName(),
+ resource.toLongString());
+ tmpFile.delete();
+ return isSelected;
+ } catch (UnsupportedOperationException uoe) {
+ log("The resource '"
+ + resource.getName()
+ + "' does not provide an InputStream, so it is not checked. "
+ + "Akkording to 'selres' attribute value it is "
+ + ((selectResourcesWithoutInputStream) ? "" : " not")
+ + "selected.", Project.MSG_INFO);
+ return selectResourcesWithoutInputStream;
+ } catch (Exception e) {
+ throw new BuildException(e);
+ }
+ }
+ }
+
+
+ /**
+ * Implementation of BaseExtendSelector.isSelected().
+ *
+ * @param basedir as described in BaseExtendSelector
+ * @param filename as described in BaseExtendSelector
+ * @param file as described in BaseExtendSelector
+ * @return as described in BaseExtendSelector
+ */
+ public boolean isSelected(File basedir, String filename, File file) {
+ return isSelected(basedir, filename, file.getAbsolutePath());
+ }
+
+
+ /**
+ * The business logic of this selector for use as ResourceSelector of
+ * FileSelector.
+ *
+ * @param basedir as described in BaseExtendSelector
+ * @param filename as described in BaseExtendSelector
+ * @param cacheKey the name for the key for storing the hashvalue
+ * @return <tt>true</tt> if the file is selected otherwise <tt>false</tt>
+ */
+ private boolean isSelected(File basedir, String filename, String cacheKey) {
+ validate();
+ File f = new File(basedir, filename);
+
+ // You can not compute a value for a directory
+ if (f.isDirectory()) {
+ return selectDirectories;
+ }
+
+ // Get the values and do the comparison
+ String cachedValue = String.valueOf(cache.get(f.getAbsolutePath()));
+ String newValue = algorithm.getValue(f);
+
+ boolean rv = (comparator.compare(cachedValue, newValue) != 0);
+
+ // Maybe update the cache
+ if (update && rv) {
+ cache.put(f.getAbsolutePath(), newValue);
+ setModified(getModified() + 1);
+ if (!getDelayUpdate()) {
+ saveCache();
+ }
+ }
+
+ return rv;
+ }
+
+
+ /**
+ * save the cache file
+ */
+ protected void saveCache() {
+ if (getModified() > 0) {
+ cache.save();
+ setModified(0);
+ }
+ }
+
+
+ // ----- attribute and nested element support -----
+
+
+ /**
+ * Setter for algorithmClass.
+ * @param classname new value
+ */
+ public void setAlgorithmClass(String classname) {
+ algorithmClass = classname;
+ }
+
+
+ /**
+ * Setter for comparatorClass.
+ * @param classname new value
+ */
+ public void setComparatorClass(String classname) {
+ comparatorClass = classname;
+ }
+
+
+ /**
+ * Setter for cacheClass.
+ * @param classname new value
+ */
+ public void setCacheClass(String classname) {
+ cacheClass = classname;
+ }
+
+
+ /**
+ * Support for <i>update</i> attribute.
+ * @param update new value
+ */
+ public void setUpdate(boolean update) {
+ this.update = update;
+ }
+
+
+ /**
+ * Support for <i>seldirs</i> attribute.
+ * @param seldirs new value
+ */
+ public void setSeldirs(boolean seldirs) {
+ selectDirectories = seldirs;
+ }
+
+
+ /**
+ * Support for <i>selres</i> attribute.
+ * @param newValue the new value
+ */
+ public void setSelres(boolean newValue) {
+ this.selectResourcesWithoutInputStream = newValue;
+ }
+
+
+ /**
+ * Getter for the modified count
+ * @return modified count
+ */
+ public int getModified() {
+ return modified;
+ }
+
+
+ /**
+ * Setter for the modified count
+ * @param modified count
+ */
+ public void setModified(int modified) {
+ this.modified = modified;
+ }
+
+
+ /**
+ * Getter for the delay update
+ * @return true if we should delay for performance
+ */
+ public boolean getDelayUpdate() {
+ return delayUpdate;
+ }
+
+
+ /**
+ * Setter for the delay update
+ * @param delayUpdate true if we should delay for performance
+ */
+ public void setDelayUpdate(boolean delayUpdate) {
+ this.delayUpdate = delayUpdate;
+ }
+
+
+ /**
+ * Add the classpath.
+ * @param path the classpath
+ */
+ public void addClasspath(Path path) {
+ if (classpath != null) {
+ throw new BuildException("<classpath> can be set only once.");
+ }
+ classpath = path;
+ }
+
+
+ /**
+ * Returns and initializes the classloader for this class.
+ * @return the classloader
+ */
+ public ClassLoader getClassLoader() {
+ if (myClassLoader == null) {
+ myClassLoader = (classpath == null)
+ // the usual classloader
+ ? getClass().getClassLoader()
+ // additional use the provided classpath
+ // Memory leak in line below
+ : getProject().createClassLoader(classpath);
+ }
+ return myClassLoader;
+ }
+
+
+ /**
+ * Set the used ClassLoader.
+ * If you invoke this selector by API (e.g. inside some testcases) the selector
+ * will use a different classloader for loading the interface implementations than
+ * the caller. Therefore you will get a ClassCastException if you get the
+ * implementations from the selector and cast them.
+ * @param loader the ClassLoader to use
+ */
+ public void setClassLoader(ClassLoader loader) {
+ myClassLoader = loader;
+ }
+
+
+ /**
+ * Support for nested &lt;param&gt; tags.
+ * @param key the key of the parameter
+ * @param value the value of the parameter
+ */
+ public void addParam(String key, Object value) {
+ Parameter par = new Parameter();
+ par.setName(key);
+ par.setValue(String.valueOf(value));
+ configParameter.add(par);
+ }
+
+
+ /**
+ * Support for nested &lt;param&gt; tags.
+ * @param parameter the parameter object
+ */
+ public void addParam(Parameter parameter) {
+ configParameter.add(parameter);
+ }
+
+
+ /**
+ * Defined in org.apache.tools.ant.types.Parameterizable.
+ * Overwrite implementation in superclass because only special
+ * parameters are valid.
+ * @see #addParam(String,Object).
+ * @param parameters the parameters to set.
+ */
+ public void setParameters(Parameter[] parameters) {
+ if (parameters != null) {
+ for (int i = 0; i < parameters.length; i++) {
+ configParameter.add(parameters[i]);
+ }
+ }
+ }
+
+
+ /**
+ * Support for nested <param name="" value=""/> tags.
+ * Parameter named <i>cache</i>, <i>algorithm</i>,
+ * <i>comparator</i> or <i>update</i> are mapped to
+ * the respective set-Method.
+ * Parameter which names starts with <i>cache.</i> or
+ * <i>algorithm.</i> or <i>comparator.</i> are tried
+ * to set on the appropriate object via its set-methods.
+ * Other parameters are invalid and an BuildException will
+ * be thrown.
+ *
+ * @param parameter Key and value as parameter object
+ */
+ public void useParameter(Parameter parameter) {
+ String key = parameter.getName();
+ String value = parameter.getValue();
+ if ("cache".equals(key)) {
+ CacheName cn = new CacheName();
+ cn.setValue(value);
+ setCache(cn);
+ } else if ("algorithm".equals(key)) {
+ AlgorithmName an = new AlgorithmName();
+ an.setValue(value);
+ setAlgorithm(an);
+ } else if ("comparator".equals(key)) {
+ ComparatorName cn = new ComparatorName();
+ cn.setValue(value);
+ setComparator(cn);
+ } else if ("update".equals(key)) {
+ boolean updateValue =
+ ("true".equalsIgnoreCase(value))
+ ? true
+ : false;
+ setUpdate(updateValue);
+ } else if ("delayupdate".equals(key)) {
+ boolean updateValue =
+ ("true".equalsIgnoreCase(value))
+ ? true
+ : false;
+ setDelayUpdate(updateValue);
+ } else if ("seldirs".equals(key)) {
+ boolean sdValue =
+ ("true".equalsIgnoreCase(value))
+ ? true
+ : false;
+ setSeldirs(sdValue);
+ } else if (key.startsWith(CACHE_PREFIX)) {
+ String name = key.substring(CACHE_PREFIX.length());
+ tryToSetAParameter(cache, name, value);
+ } else if (key.startsWith(ALGORITHM_PREFIX)) {
+ String name = key.substring(ALGORITHM_PREFIX.length());
+ tryToSetAParameter(algorithm, name, value);
+ } else if (key.startsWith(COMPARATOR_PREFIX)) {
+ String name = key.substring(COMPARATOR_PREFIX.length());
+ tryToSetAParameter(comparator, name, value);
+ } else {
+ setError("Invalid parameter " + key);
+ }
+ }
+
+
+ /**
+ * Try to set a value on an object using reflection.
+ * Helper method for easier access to IntrospectionHelper.setAttribute().
+ * @param obj the object on which the attribute should be set
+ * @param name the attributename
+ * @param value the new value
+ */
+ protected void tryToSetAParameter(Object obj, String name, String value) {
+ Project prj = (getProject() != null) ? getProject() : new Project();
+ IntrospectionHelper iHelper
+ = IntrospectionHelper.getHelper(prj, obj.getClass());
+ try {
+ iHelper.setAttribute(prj, obj, name, value);
+ } catch (org.apache.tools.ant.BuildException e) {
+ // no-op
+ }
+ }
+
+
+ // ----- 'beautiful' output -----
+
+
+ /**
+ * Override Object.toString().
+ * @return information about this selector
+ */
+ public String toString() {
+ StringBuffer buf = new StringBuffer("{modifiedselector");
+ buf.append(" update=").append(update);
+ buf.append(" seldirs=").append(selectDirectories);
+ buf.append(" cache=").append(cache);
+ buf.append(" algorithm=").append(algorithm);
+ buf.append(" comparator=").append(comparator);
+ buf.append("}");
+ return buf.toString();
+ }
+
+
+ // ----- BuildListener interface methods -----
+
+
+ /**
+ * Signals that the last target has finished.
+ * @param event received BuildEvent
+ */
+ public void buildFinished(BuildEvent event) {
+ if (getDelayUpdate()) {
+ saveCache();
+ }
+ }
+
+
+ /**
+ * Signals that a target has finished.
+ * @param event received BuildEvent
+ */
+ public void targetFinished(BuildEvent event) {
+ if (getDelayUpdate()) {
+ saveCache();
+ }
+ }
+
+
+ /**
+ * Signals that a task has finished.
+ * @param event received BuildEvent
+ */
+ public void taskFinished(BuildEvent event) {
+ if (getDelayUpdate()) {
+ saveCache();
+ }
+ }
+
+
+ /**
+ * Signals that a build has started.
+ * @param event received BuildEvent
+ */
+ public void buildStarted(BuildEvent event) {
+ // no-op
+ }
+
+
+ /**
+ * Signals that a target is starting.
+ * @param event received BuildEvent
+ */
+ public void targetStarted(BuildEvent event) {
+ // no-op
+ }
+
+
+
+ /**
+ * Signals that a task is starting.
+ * @param event received BuildEvent
+ */
+ public void taskStarted(BuildEvent event) {
+ // no-op
+ }
+
+
+ /**
+ * Signals a message logging event.
+ * @param event received BuildEvent
+ */
+ public void messageLogged(BuildEvent event) {
+ // no-op
+ }
+
+
+ // The EnumeratedAttributes for the three interface implementations.
+ // Name-Classname mapping is done in the configure() method.
+
+
+ /**
+ * Get the cache type to use.
+ * @return the enumerated cache type
+ */
+ public Cache getCache() {
+ return cache;
+ }
+
+ /**
+ * Set the cache type to use.
+ * @param name an enumerated cache type.
+ */
+ public void setCache(CacheName name) {
+ cacheName = name;
+ }
+
+ /**
+ * The enumerated type for cache.
+ * The values are "propertyfile".
+ */
+ public static class CacheName extends EnumeratedAttribute {
+ /**
+ * {@inheritDoc}
+ * @see EnumeratedAttribute#getValues()
+ */
+ public String[] getValues() {
+ return new String[] {"propertyfile" };
+ }
+ }
+
+ /**
+ * Get the algorithm type to use.
+ * @return the enumerated algorithm type
+ */
+ public Algorithm getAlgorithm() {
+ return algorithm;
+ }
+
+ /**
+ * Set the algorithm type to use.
+ * @param name an enumerated algorithm type.
+ */
+ public void setAlgorithm(AlgorithmName name) {
+ algoName = name;
+ }
+
+ /**
+ * The enumerated type for algorithm.
+ * The values are "hashValue", "digest" and "checksum".
+ */
+ public static class AlgorithmName extends EnumeratedAttribute {
+ /**
+ * {@inheritDoc}
+ * @see EnumeratedAttribute#getValues()
+ */
+ public String[] getValues() {
+ return new String[] {"hashvalue", "digest", "checksum" };
+ }
+ }
+
+ /**
+ * Get the comparator type to use.
+ * @return the enumerated comparator type
+ */
+ public Comparator<? super String> getComparator() {
+ return comparator;
+ }
+
+ /**
+ * Set the comparator type to use.
+ * @param name an enumerated comparator type.
+ */
+ public void setComparator(ComparatorName name) {
+ compName = name;
+ }
+
+ /**
+ * The enumerated type for algorithm.
+ * The values are "equal" and "rule".
+ */
+ public static class ComparatorName extends EnumeratedAttribute {
+ /**
+ * {@inheritDoc}
+ * @see EnumeratedAttribute#getValues()
+ */
+ public String[] getValues() {
+ return new String[] {"equal", "rule" };
+ }
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/modifiedselector/PropertiesfileCache.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/modifiedselector/PropertiesfileCache.java
new file mode 100644
index 00000000..1446e890
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/selectors/modifiedselector/PropertiesfileCache.java
@@ -0,0 +1,236 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types.selectors.modifiedselector;
+
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.Properties;
+import java.util.Vector;
+
+
+/**
+ * Use java.util.Properties for storing the values.
+ * The use of this Cache-implementation requires the use of the parameter
+ * <param name="cache.cachefile" .../> for defining, where to store the
+ * properties file.
+ *
+ * The ModifiedSelector sets the <i>cachefile</i> to the default value
+ * <i>cache.properties</i>.
+ *
+ * Supported <param>s are:
+ * <table>
+ * <tr>
+ * <th>name</th><th>values</th><th>description</th><th>required</th>
+ * </tr>
+ * <tr>
+ * <td> cache.cachefile </td>
+ * <td> <i>path to file</i> </td>
+ * <td> the name of the properties file </td>
+ * <td> yes </td>
+ * </tr>
+ * </table>
+ *
+ * @version 2003-09-13
+ * @since Ant 1.6
+ */
+public class PropertiesfileCache implements Cache {
+
+
+ // ----- member variables - configuration -----
+
+
+ /** Where to store the properties? */
+ private File cachefile = null;
+
+ /** Object for storing the key-value-pairs. */
+ private Properties cache = new Properties();
+
+
+ // ----- member variables - internal use -----
+
+
+ /** Is the cache already loaded? Prevents from multiple load operations. */
+ private boolean cacheLoaded = false;
+
+ /** Must the cache be saved? Prevents from multiple save operations. */
+ private boolean cacheDirty = true;
+
+
+ // ----- Constructors -----
+
+
+ /** Bean-Constructor. */
+ public PropertiesfileCache() {
+ }
+
+ /**
+ * Constructor.
+ * @param cachefile set the cachefile
+ */
+ public PropertiesfileCache(File cachefile) {
+ this.cachefile = cachefile;
+ }
+
+
+ // ----- Cache-Configuration -----
+
+
+ /**
+ * Setter.
+ * @param file new value
+ */
+ public void setCachefile(File file) {
+ cachefile = file;
+ }
+
+
+ /**
+ * Getter.
+ * @return the cachefile
+ */
+ public File getCachefile() {
+ return cachefile;
+ }
+
+ /**
+ * This cache is valid if the cachefile is set.
+ * @return true if all is ok false otherwise
+ */
+ public boolean isValid() {
+ return (cachefile != null);
+ }
+
+
+ // ----- Data Access
+
+
+ /**
+ * Load the cache from underlying properties file.
+ */
+ public void load() {
+ if ((cachefile != null) && cachefile.isFile() && cachefile.canRead()) {
+ try {
+ BufferedInputStream bis = new BufferedInputStream(
+ new FileInputStream(cachefile));
+ cache.load(bis);
+ bis.close();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ // after loading the cache is up to date with the file
+ cacheLoaded = true;
+ cacheDirty = false;
+ }
+
+ /**
+ * Saves modification of the cache.
+ * Cache is only saved if there is one ore more entries.
+ * Because entries can not be deleted by this API, this Cache
+ * implementation checks the existence of entries before creating the file
+ * for performance optimisation.
+ */
+ public void save() {
+ if (!cacheDirty) {
+ return;
+ }
+ if ((cachefile != null) && cache.propertyNames().hasMoreElements()) {
+ try {
+ BufferedOutputStream bos = new BufferedOutputStream(
+ new FileOutputStream(cachefile));
+ cache.store(bos, null);
+ bos.flush();
+ bos.close();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ cacheDirty = false;
+ }
+
+ /** Deletes the cache and its underlying file. */
+ public void delete() {
+ cache = new Properties();
+ cachefile.delete();
+ cacheLoaded = true;
+ cacheDirty = false;
+ }
+
+ /**
+ * Returns a value for a given key from the cache.
+ * @param key the key
+ * @return the stored value
+ */
+ public Object get(Object key) {
+ if (!cacheLoaded) {
+ load();
+ }
+ try {
+ return cache.getProperty(String.valueOf(key));
+ } catch (ClassCastException e) {
+ return null;
+ }
+ }
+
+ /**
+ * Saves a key-value-pair in the cache.
+ * @param key the key
+ * @param value the value
+ */
+ public void put(Object key, Object value) {
+ cache.put(String.valueOf(key), String.valueOf(value));
+ cacheDirty = true;
+ }
+
+ /**
+ * Returns an iterator over the keys in the cache.
+ * @return An iterator over the keys.
+ */
+ public Iterator<String> iterator() {
+ Vector<String> v = new Vector<String>();
+ Enumeration<?> en = cache.propertyNames();
+ while (en.hasMoreElements()) {
+ v.add(en.nextElement().toString());
+ }
+ return v.iterator();
+ }
+
+
+ // ----- additional -----
+
+
+ /**
+ * Override Object.toString().
+ * @return information about this cache
+ */
+ public String toString() {
+ StringBuffer buf = new StringBuffer();
+ buf.append("<PropertiesfileCache:");
+ buf.append("cachefile=").append(cachefile);
+ buf.append(";noOfEntries=").append(cache.size());
+ buf.append(">");
+ return buf.toString();
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/spi/Provider.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/spi/Provider.java
new file mode 100644
index 00000000..f73b0191
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/spi/Provider.java
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.spi;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.ProjectComponent;
+
+/**
+ * ANT Jar-Task SPI extension
+ * This class corresponds to the nested element
+ * &lt;provider type="type"&gt; in the &lt;service type=""&gt;
+ * nested element of the jar task.
+ * @see <a href="http://issues.apache.org/bugzilla/show_bug.cgi?id=31520">
+ * http://issues.apache.org/bugzilla/show_bug.cgi?id=31520</a>
+ */
+public class Provider extends ProjectComponent {
+ private String type;
+
+ /**
+ * @return the class name for
+ */
+ public String getClassName() {
+ return type;
+ }
+
+ /**
+ * Set the provider classname.
+ * @param type the value to set.
+ */
+ public void setClassName(String type) {
+ this.type = type;
+ }
+
+ /**
+ * Check if the component has been configured correctly.
+ */
+ public void check() {
+ if (type == null) {
+ throw new BuildException(
+ "classname attribute must be set for provider element",
+ getLocation());
+ }
+ if (type.length() == 0) {
+ throw new BuildException(
+ "Invalid empty classname", getLocation());
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/spi/Service.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/spi/Service.java
new file mode 100644
index 00000000..96c8e4e5
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/spi/Service.java
@@ -0,0 +1,116 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.spi;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.ProjectComponent;
+
+/**
+ * ANT Jar-Task SPI extension
+ *
+ * @see <a href="http://issues.apache.org/bugzilla/show_bug.cgi?id=31520">
+ * http://issues.apache.org/bugzilla/show_bug.cgi?id=31520</a>
+ */
+public class Service extends ProjectComponent {
+ private List<Provider> providerList = new ArrayList<Provider>();
+ private String type;
+
+ /**
+ * Set the provider classname.
+ * @param className the classname of a provider of this service.
+ */
+ public void setProvider(String className) {
+ Provider provider = new Provider();
+ provider.setClassName(className);
+ providerList.add(provider);
+ }
+
+ /**
+ * Add a nested provider element.
+ * @param provider a provider element.
+ */
+ public void addConfiguredProvider(Provider provider) {
+ provider.check();
+ providerList.add(provider);
+ }
+
+ /**
+ * @return the service type.
+ */
+ public String getType() {
+ return type;
+ }
+
+ /**
+ * Set the service type.
+ * @param type the service type, a classname of
+ * an interface or a class (normally
+ * abstract).
+ */
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ /**
+ * Return the implementations of this
+ * services as an inputstream.
+ * @return an inputstream of the classname names
+ * encoded as UTF-8.
+ * @throws IOException if there is an error.
+ */
+ public InputStream getAsStream() throws IOException {
+ ByteArrayOutputStream arrayOut = new ByteArrayOutputStream();
+ Writer writer = new OutputStreamWriter(arrayOut, "UTF-8");
+ for (Provider provider : providerList) {
+ writer.write(provider.getClassName());
+ writer.write("\n");
+ }
+ writer.close();
+ return new ByteArrayInputStream(arrayOut.toByteArray());
+ }
+
+ /**
+ * Check if this object is configured correctly as a nested
+ * element.
+ */
+ public void check() {
+ if (type == null) {
+ throw new BuildException(
+ "type attribute must be set for service element",
+ getLocation());
+ }
+ if (type.length() == 0) {
+ throw new BuildException(
+ "Invalid empty type classname", getLocation());
+ }
+ if (providerList.size() == 0) {
+ throw new BuildException(
+ "provider attribute or nested provider element must be set!",
+ getLocation());
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/Base64Converter.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/Base64Converter.java
new file mode 100644
index 00000000..5d60a145
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/Base64Converter.java
@@ -0,0 +1,124 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.util;
+
+/**
+ * BASE 64 encoding of a String or an array of bytes.
+ *
+ * Based on RFC 1421.
+ *
+ **/
+public class Base64Converter {
+
+ private static final int BYTE = 8;
+ private static final int WORD = 16;
+ private static final int BYTE_MASK = 0xFF;
+ private static final int POS_0_MASK = 0x0000003F;
+ private static final int POS_1_MASK = 0x00000FC0;
+ private static final int POS_1_SHIFT = 6;
+ private static final int POS_2_MASK = 0x0003F000;
+ private static final int POS_2_SHIFT = 12;
+ private static final int POS_3_MASK = 0x00FC0000;
+ private static final int POS_3_SHIFT = 18;
+
+
+ private static final char[] ALPHABET = {
+ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', // 0 to 7
+ 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', // 8 to 15
+ 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', // 16 to 23
+ 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', // 24 to 31
+ 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', // 32 to 39
+ 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', // 40 to 47
+ 'w', 'x', 'y', 'z', '0', '1', '2', '3', // 48 to 55
+ '4', '5', '6', '7', '8', '9', '+', '/'}; // 56 to 63
+
+ // CheckStyle:ConstantNameCheck OFF - bc
+ /** Provided for BC purposes */
+ public static final char[] alphabet = ALPHABET;
+ // CheckStyle:ConstantNameCheck ON
+
+
+ /**
+ * Encode a string into base64 encoding.
+ * @param s the string to encode.
+ * @return the encoded string.
+ */
+ public String encode(String s) {
+ return encode(s.getBytes());
+ }
+
+ /**
+ * Encode a byte array into base64 encoding.
+ * @param octetString the byte array to encode.
+ * @return the encoded string.
+ */
+ public String encode(byte[] octetString) {
+ int bits24;
+ int bits6;
+
+ // CheckStyle:MagicNumber OFF
+ char[] out = new char[((octetString.length - 1) / 3 + 1) * 4];
+ // CheckStyle:MagicNumber ON
+ int outIndex = 0;
+ int i = 0;
+
+ // CheckStyle:MagicNumber OFF
+ while ((i + 3) <= octetString.length) {
+ // CheckStyle:MagicNumber ON
+ // store the octets
+ bits24 = (octetString[i++] & BYTE_MASK) << WORD;
+ bits24 |= (octetString[i++] & BYTE_MASK) << BYTE;
+ bits24 |= octetString[i++] & BYTE_MASK;
+
+ bits6 = (bits24 & POS_3_MASK) >> POS_3_SHIFT;
+ out[outIndex++] = ALPHABET[bits6];
+ bits6 = (bits24 & POS_2_MASK) >> POS_2_SHIFT;
+ out[outIndex++] = ALPHABET[bits6];
+ bits6 = (bits24 & POS_1_MASK) >> POS_1_SHIFT;
+ out[outIndex++] = ALPHABET[bits6];
+ bits6 = (bits24 & POS_0_MASK);
+ out[outIndex++] = ALPHABET[bits6];
+ }
+ if (octetString.length - i == 2) {
+ // store the octets
+ bits24 = (octetString[i] & BYTE_MASK) << WORD;
+ bits24 |= (octetString[i + 1] & BYTE_MASK) << BYTE;
+ bits6 = (bits24 & POS_3_MASK) >> POS_3_SHIFT;
+ out[outIndex++] = ALPHABET[bits6];
+ bits6 = (bits24 & POS_2_MASK) >> POS_2_SHIFT;
+ out[outIndex++] = ALPHABET[bits6];
+ bits6 = (bits24 & POS_1_MASK) >> POS_1_SHIFT;
+ out[outIndex++] = ALPHABET[bits6];
+
+ // padding
+ out[outIndex++] = '=';
+ } else if (octetString.length - i == 1) {
+ // store the octets
+ bits24 = (octetString[i] & BYTE_MASK) << WORD;
+ bits6 = (bits24 & POS_3_MASK) >> POS_3_SHIFT;
+ out[outIndex++] = ALPHABET[bits6];
+ bits6 = (bits24 & POS_2_MASK) >> POS_2_SHIFT;
+ out[outIndex++] = ALPHABET[bits6];
+
+ // padding
+ out[outIndex++] = '=';
+ out[outIndex++] = '=';
+ }
+ return new String(out);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/ChainedMapper.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/ChainedMapper.java
new file mode 100644
index 00000000..635a0538
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/ChainedMapper.java
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.util;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * A <code>ContainerMapper</code> that chains the results of the first
+ * nested <code>FileNameMapper</code>s into sourcefiles for the second,
+ * the second to the third, and so on, returning the resulting mapped
+ * filenames from the last nested <code>FileNameMapper</code>.
+ */
+public class ChainedMapper extends ContainerMapper {
+
+ /** {@inheritDoc}. */
+ public String[] mapFileName(String sourceFileName) {
+ List inputs = new ArrayList();
+ List results = new ArrayList();
+ results.add(sourceFileName);
+ FileNameMapper mapper = null;
+
+ for (Iterator mIter = getMappers().iterator(); mIter.hasNext();) {
+ mapper = (FileNameMapper) (mIter.next());
+ if (mapper != null) {
+ inputs.clear();
+ inputs.addAll(results);
+ results.clear();
+
+ for (Iterator it = inputs.iterator(); it.hasNext();) {
+ String[] mapped = mapper.mapFileName((String) (it.next()));
+ if (mapped != null) {
+ results.addAll(Arrays.asList(mapped));
+ }
+ }
+ }
+ }
+ return (results.size() == 0) ? null
+ : (String[]) results.toArray(new String[results.size()]);
+ }
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/ClasspathUtils.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/ClasspathUtils.java
new file mode 100644
index 00000000..309860e9
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/ClasspathUtils.java
@@ -0,0 +1,463 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.util;
+
+import org.apache.tools.ant.AntClassLoader;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.MagicNames;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.ProjectComponent;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.types.Reference;
+
+// CheckStyle:HideUtilityClassConstructorCheck OFF - bc
+
+/**
+ * Offers some helper methods on the Path structure in ant.
+ *
+ * <p>The basic idea behind this utility class is to use it from inside the
+ * different Ant objects (and user defined objects) that need classLoading
+ * for their operation.
+ * Normally those would have a setClasspathRef() {for the @classpathref}
+ * and/or a createClasspath() {for the nested &lt;classpath&gt;}
+ * Typically one would have in your Ant Task or DataType</p>
+ *
+ * <pre><code>
+ * ClasspathUtils.Delegate cpDelegate;
+ *
+ * public void init() {
+ * this.cpDelegate = ClasspathUtils.getDelegate(this);
+ * super.init();
+ * }
+ *
+ * public void setClasspathRef(Reference r) {
+ * this.cpDelegate.setClasspathRef(r);
+ * }
+ *
+ * public Path createClasspath() {
+ * return this.cpDelegate.createClasspath();
+ * }
+ *
+ * public void setClassname(String fqcn) {
+ * this.cpDelegate.setClassname(fqcn);
+ * }
+ * </code></pre>
+ *
+ * <p>At execution time, when you actually need the classloading
+ * you can just:</p>
+ *
+ * <pre><code>
+ * Object o = this.cpDelegate.newInstance();
+ * </code></pre>
+ *
+ * @since Ant 1.6
+ */
+public class ClasspathUtils {
+
+ /**
+ * Name of the magic property that controls classloader reuse in Ant 1.4.
+ */
+ public static final String REUSE_LOADER_REF = MagicNames.REFID_CLASSPATH_REUSE_LOADER;
+
+ /**
+ * Convenience overloaded version of {@link
+ * #getClassLoaderForPath(Project, Reference, boolean)}.
+ *
+ * <p>Assumes the logical 'false' for the reverseLoader.</p>
+ *
+ * @param p the project
+ * @param ref the reference
+ * @return The class loader
+ */
+ public static ClassLoader getClassLoaderForPath(Project p, Reference ref) {
+ return getClassLoaderForPath(p, ref, false);
+ }
+
+ /**
+ * Convenience overloaded version of {@link #getClassLoaderForPath(Project, Path,
+ * String, boolean)}.
+ *
+ * <p>Delegates to the other one after extracting the referenced
+ * Path from the Project. This checks also that the passed
+ * Reference is pointing to a Path all right.</p>
+ * @param p current Ant project
+ * @param ref Reference to Path structure
+ * @param reverseLoader if set to true this new loader will take
+ * precedence over its parent (which is contra the regular
+ * classloader behaviour)
+ * @return The class loader
+ */
+ public static ClassLoader getClassLoaderForPath(
+ Project p, Reference ref, boolean reverseLoader) {
+ String pathId = ref.getRefId();
+ Object path = p.getReference(pathId);
+ if (!(path instanceof Path)) {
+ throw new BuildException("The specified classpathref " + pathId
+ + " does not reference a Path.");
+ }
+ String loaderId = MagicNames.REFID_CLASSPATH_LOADER_PREFIX + pathId;
+ return getClassLoaderForPath(p, (Path) path, loaderId, reverseLoader);
+ }
+
+ /**
+ * Convenience overloaded version of {@link
+ * #getClassLoaderForPath(Project, Path, String, boolean)}.
+ *
+ * <p>Assumes the logical 'false' for the reverseLoader.</p>
+ *
+ * @param p current Ant project
+ * @param path the path
+ * @param loaderId the loader id string
+ * @return The class loader
+ */
+ public static ClassLoader getClassLoaderForPath(Project p, Path path, String loaderId) {
+ return getClassLoaderForPath(p, path, loaderId, false);
+ }
+
+ /**
+ * Convenience overloaded version of {@link
+ * #getClassLoaderForPath(Project, Path, String, boolean, boolean)}.
+ *
+ * <p>Sets value for 'reuseLoader' to true if the magic property
+ * has been set.</p>
+ *
+ * @param p the project
+ * @param path the path
+ * @param loaderId the loader id string
+ * @param reverseLoader if set to true this new loader will take
+ * precedence over its parent (which is contra the regular
+ * classloader behaviour)
+ * @return The class loader
+ */
+ public static ClassLoader getClassLoaderForPath(
+ Project p, Path path, String loaderId, boolean reverseLoader) {
+ return getClassLoaderForPath(p, path, loaderId, reverseLoader, isMagicPropertySet(p));
+ }
+
+ /**
+ * Gets a classloader that loads classes from the classpath
+ * defined in the path argument.
+ *
+ * <p>Based on the setting of the magic property
+ * 'ant.reuse.loader' this will try to reuse the previously
+ * created loader with that id, and of course store it there upon
+ * creation.</p>
+ * @param p Ant Project where the handled components are living in.
+ * @param path Path object to be used as classpath for this classloader
+ * @param loaderId identification for this Loader,
+ * @param reverseLoader if set to true this new loader will take
+ * precedence over its parent (which is contra the regular
+ * classloader behaviour)
+ * @param reuseLoader if true reuse the loader if it is found
+ * @return ClassLoader that uses the Path as its classpath.
+ */
+ public static ClassLoader getClassLoaderForPath(
+ Project p, Path path, String loaderId, boolean reverseLoader, boolean reuseLoader) {
+ ClassLoader cl = null;
+
+ // magic property
+ if (loaderId != null && reuseLoader) {
+ Object reusedLoader = p.getReference(loaderId);
+ if (reusedLoader != null && !(reusedLoader instanceof ClassLoader)) {
+ throw new BuildException("The specified loader id " + loaderId
+ + " does not reference a class loader");
+ }
+ cl = (ClassLoader) reusedLoader;
+ }
+ if (cl == null) {
+ cl = getUniqueClassLoaderForPath(p, path, reverseLoader);
+ if (loaderId != null && reuseLoader) {
+ p.addReference(loaderId, cl);
+ }
+ }
+ return cl;
+ }
+
+ /**
+ * Gets a fresh, different, previously unused classloader that uses the
+ * passed path as its classpath.
+ *
+ * <p>This method completely ignores the ant.reuse.loader magic
+ * property and should be used with caution.</p>
+ * @param p Ant Project where the handled components are living in.
+ * @param path the classpath for this loader
+ * @param reverseLoader if set to true this new loader will take
+ * precedence over its parent (which is contra the regular
+ * classloader behaviour)
+ * @return The fresh, different, previously unused class loader.
+ */
+ public static ClassLoader getUniqueClassLoaderForPath(Project p, Path path,
+ boolean reverseLoader) {
+ AntClassLoader acl = p.createClassLoader(path);
+ if (reverseLoader) {
+ acl.setParentFirst(false);
+ acl.addJavaLibraries();
+ }
+ return acl;
+ }
+
+ /**
+ * Creates a fresh object instance of the specified classname.
+ *
+ * <p> This uses the userDefinedLoader to load the specified class,
+ * and then makes an instance using the default no-argument constructor.
+ * </p>
+ *
+ * @param className the full qualified class name to load.
+ * @param userDefinedLoader the classloader to use.
+ * @return The fresh object instance
+ * @throws BuildException when loading or instantiation failed.
+ */
+ public static Object newInstance(String className, ClassLoader userDefinedLoader) {
+ return newInstance(className, userDefinedLoader, Object.class);
+ }
+
+ /**
+ * Creates a fresh object instance of the specified classname.
+ *
+ * <p> This uses the userDefinedLoader to load the specified class,
+ * and then makes an instance using the default no-argument constructor.
+ * </p>
+ *
+ * @param className the full qualified class name to load.
+ * @param userDefinedLoader the classloader to use.
+ * @param expectedType the Class that the result should be assignment
+ * compatible with. (No ClassCastException will be thrown in case
+ * the result of this method is casted to the expectedType)
+ * @return The fresh object instance
+ * @throws BuildException when loading or instantiation failed.
+ * @since Ant 1.7
+ */
+ public static Object newInstance(String className, ClassLoader userDefinedLoader,
+ Class expectedType) {
+ try {
+ Class clazz = Class.forName(className, true, userDefinedLoader);
+ Object o = clazz.newInstance();
+ if (!expectedType.isInstance(o)) {
+ throw new BuildException("Class of unexpected Type: " + className + " expected :"
+ + expectedType);
+ }
+ return o;
+ } catch (ClassNotFoundException e) {
+ throw new BuildException("Class not found: " + className, e);
+ } catch (InstantiationException e) {
+ throw new BuildException("Could not instantiate " + className
+ + ". Specified class should have a no " + "argument constructor.", e);
+ } catch (IllegalAccessException e) {
+ throw new BuildException("Could not instantiate " + className
+ + ". Specified class should have a " + "public constructor.", e);
+ } catch (LinkageError e) {
+ throw new BuildException("Class " + className
+ + " could not be loaded because of an invalid dependency.", e);
+ }
+ }
+
+ /**
+ * Obtains a delegate that helps out with classic classpath configuration.
+ *
+ * @param component your projectComponent that needs the assistence
+ * @return the helper, delegate.
+ * @see ClasspathUtils.Delegate
+ */
+ public static Delegate getDelegate(ProjectComponent component) {
+ return new Delegate(component);
+ }
+
+ /**
+ * Checks for the magic property that enables class loader reuse
+ * for <taskdef> and <typedef> in Ant 1.5 and earlier.
+ */
+ private static boolean isMagicPropertySet(Project p) {
+ return p.getProperty(REUSE_LOADER_REF) != null;
+ }
+
+ /**
+ * Delegate that helps out any specific ProjectComponent that needs
+ * dynamic classloading.
+ *
+ * <p>Ant ProjectComponents that need a to be able to dynamically load
+ * Classes and instantiate them often expose the following ant syntax
+ * sugar: </p>
+ *
+ * <ul><li> nested &lt;classpath&gt; </li>
+ * <li> attribute @classpathref </li>
+ * <li> attribute @classname </li></ul>
+ *
+ * <p> This class functions as a delegate handling the configuration
+ * issues for this recurring pattern. Its usage pattern, as the name
+ * suggests, is delegation rather than inheritance. </p>
+ *
+ * @since Ant 1.6
+ */
+ public static class Delegate {
+ private final ProjectComponent component;
+ private Path classpath;
+ private String classpathId;
+ private String className;
+ private String loaderId;
+ private boolean reverseLoader = false;
+
+ /**
+ * Construct a Delegate
+ * @param component the ProjectComponent this delegate is for.
+ */
+ Delegate(ProjectComponent component) {
+ this.component = component;
+ }
+
+ /**
+ * This method is a Delegate method handling the @classpath attribute.
+ *
+ * <p>This attribute can set a path to add to the classpath.</p>
+ *
+ * @param classpath the path to use for the classpath.
+ */
+ public void setClasspath(Path classpath) {
+ if (this.classpath == null) {
+ this.classpath = classpath;
+ } else {
+ this.classpath.append(classpath);
+ }
+ }
+
+ /**
+ * Delegate method handling the &lt;classpath&gt; tag.
+ *
+ * <p>This nested path-like structure can set a path to add to the
+ * classpath.</p>
+ *
+ * @return the created path.
+ */
+ public Path createClasspath() {
+ if (this.classpath == null) {
+ this.classpath = new Path(component.getProject());
+ }
+ return this.classpath.createPath();
+ }
+
+ /**
+ * Delegate method handling the @classname attribute.
+ *
+ * <p>This attribute sets the full qualified class name of the class
+ * to load and instantiate.</p>
+ *
+ * @param fcqn the name of the class to load.
+ */
+ public void setClassname(String fcqn) {
+ this.className = fcqn;
+ }
+
+ /**
+ * Delegate method handling the @classpathref attribute.
+ *
+ * <p>This attribute can add a referenced path-like structure to the
+ * classpath.</p>
+ *
+ * @param r the reference to the classpath.
+ */
+ public void setClasspathref(Reference r) {
+ this.classpathId = r.getRefId();
+ createClasspath().setRefid(r);
+ }
+
+ /**
+ * Delegate method handling the @reverseLoader attribute.
+ *
+ * <p>This attribute can set a boolean indicating that the used
+ * classloader should NOT follow the classical parent-first scheme.
+ * </p>
+ *
+ * <p>By default this is supposed to be false.</p>
+ *
+ * <p>Caution: this behaviour is contradictory to the normal way
+ * classloaders work. Do not let your ProjectComponent use it if
+ * you are not really sure.</p>
+ *
+ * @param reverseLoader if true reverse the order of looking up a class.
+ */
+ public void setReverseLoader(boolean reverseLoader) {
+ this.reverseLoader = reverseLoader;
+ }
+
+ /**
+ * Sets the loaderRef.
+ * @param r the reference to the loader.
+ */
+ public void setLoaderRef(Reference r) {
+ this.loaderId = r.getRefId();
+ }
+
+
+ /**
+ * Finds or creates the classloader for this object.
+ * @return The class loader.
+ */
+ public ClassLoader getClassLoader() {
+ return getClassLoaderForPath(getContextProject(), classpath, getClassLoadId(),
+ reverseLoader, loaderId != null || isMagicPropertySet(getContextProject()));
+ }
+
+ /**
+ * The project of the ProjectComponent we are working for.
+ */
+ private Project getContextProject() {
+ return component.getProject();
+ }
+
+ /**
+ * Computes the loaderId based on the configuration of the component.
+ * @return a loader identifier.
+ */
+ public String getClassLoadId() {
+ if (loaderId == null && classpathId != null) {
+ return MagicNames.REFID_CLASSPATH_LOADER_PREFIX + classpathId;
+ } else {
+ return loaderId;
+ }
+ }
+
+ /**
+ * Helper method obtaining a fresh instance of the class specified
+ * in the @classname and using the specified classpath.
+ *
+ * @return the fresh instantiated object.
+ */
+ public Object newInstance() {
+ return ClasspathUtils.newInstance(this.className, getClassLoader());
+ }
+
+ /**
+ * The classpath.
+ * @return the classpath.
+ */
+ public Path getClasspath() {
+ return classpath;
+ }
+
+ /**
+ * Get the reverseLoader setting.
+ * @return true if looking up in reverse order.
+ */
+ public boolean isReverseLoader() {
+ return reverseLoader;
+ }
+
+ //TODO no methods yet for getClassname
+ //TODO no method for newInstance using a reverse-classloader
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/CollectionUtils.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/CollectionUtils.java
new file mode 100644
index 00000000..03c48d93
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/CollectionUtils.java
@@ -0,0 +1,278 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.util;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+import java.util.Vector;
+
+// CheckStyle:HideUtilityClassConstructorCheck OFF - bc
+
+/**
+ * A set of helper methods related to collection manipulation.
+ *
+ * @since Ant 1.5
+ */
+public class CollectionUtils {
+
+ /**
+ * Collections.emptyList() is Java5+.
+ */
+ @SuppressWarnings("rawtypes")
+ @Deprecated
+ public static final List EMPTY_LIST = Collections.EMPTY_LIST;
+
+ /**
+ * Please use Vector.equals() or List.equals().
+ * @param v1 the first vector.
+ * @param v2 the second vector.
+ * @return true if the vectors are equal.
+ * @since Ant 1.5
+ * @deprecated since 1.6.x.
+ */
+ public static boolean equals(Vector<?> v1, Vector<?> v2) {
+ if (v1 == v2) {
+ return true;
+ }
+
+ if (v1 == null || v2 == null) {
+ return false;
+ }
+
+ return v1.equals(v2);
+ }
+
+ /**
+ * Dictionary does not have an equals.
+ * Please use Map.equals().
+ *
+ * <p>Follows the equals contract of Java 2's Map.</p>
+ * @param d1 the first directory.
+ * @param d2 the second directory.
+ * @return true if the directories are equal.
+ * @since Ant 1.5
+ * @deprecated since 1.6.x.
+ */
+ public static boolean equals(Dictionary<?, ?> d1, Dictionary<?, ?> d2) {
+ if (d1 == d2) {
+ return true;
+ }
+
+ if (d1 == null || d2 == null) {
+ return false;
+ }
+
+ if (d1.size() != d2.size()) {
+ return false;
+ }
+
+ Enumeration<?> e1 = d1.keys();
+ while (e1.hasMoreElements()) {
+ Object key = e1.nextElement();
+ Object value1 = d1.get(key);
+ Object value2 = d2.get(key);
+ if (value2 == null || !value1.equals(value2)) {
+ return false;
+ }
+ }
+
+ // don't need the opposite check as the Dictionaries have the
+ // same size, so we've also covered all keys of d2 already.
+
+ return true;
+ }
+
+ /**
+ * Creates a comma separated list of all values held in the given
+ * collection.
+ *
+ * @param c collection to transform
+ * @return string representation of the collection
+ * @since Ant 1.8.0
+ */
+ public static String flattenToString(Collection<?> c) {
+ final StringBuilder sb = new StringBuilder();
+ for (Object o : c) {
+ if (sb.length() != 0) {
+ sb.append(",");
+ }
+ sb.append(o);
+ }
+ return sb.toString();
+ }
+
+ /**
+ * Dictionary does not know the putAll method. Please use Map.putAll().
+ * @param m1 the to directory.
+ * @param m2 the from directory.
+ * @param <K> type of the key
+ * @param <V> type of the value
+ * @since Ant 1.6
+ * @deprecated since 1.6.x.
+ */
+ public static <K, V> void putAll(Dictionary<? super K, ? super V> m1, Dictionary<? extends K, ? extends V> m2) {
+ for (Enumeration<? extends K> it = m2.keys(); it.hasMoreElements();) {
+ K key = it.nextElement();
+ m1.put(key, m2.get(key));
+ }
+ }
+
+ /**
+ * An empty enumeration.
+ * @since Ant 1.6
+ */
+ public static final class EmptyEnumeration<E> implements Enumeration<E> {
+ /** Constructor for the EmptyEnumeration */
+ public EmptyEnumeration() {
+ }
+
+ /**
+ * @return false always.
+ */
+ public boolean hasMoreElements() {
+ return false;
+ }
+
+ /**
+ * @return nothing.
+ * @throws NoSuchElementException always.
+ */
+ public E nextElement() throws NoSuchElementException {
+ throw new NoSuchElementException();
+ }
+ }
+
+ /**
+ * Append one enumeration to another.
+ * Elements are evaluated lazily.
+ * @param e1 the first enumeration.
+ * @param e2 the subsequent enumeration.
+ * @param <E> element type
+ * @return an enumeration representing e1 followed by e2.
+ * @since Ant 1.6.3
+ */
+ public static <E> Enumeration<E> append(Enumeration<E> e1, Enumeration<E> e2) {
+ return new CompoundEnumeration<E>(e1, e2);
+ }
+
+ /**
+ * Adapt the specified Iterator to the Enumeration interface.
+ * @param iter the Iterator to adapt.
+ * @param <E> element type
+ * @return an Enumeration.
+ */
+ public static <E> Enumeration<E> asEnumeration(final Iterator<E> iter) {
+ return new Enumeration<E>() {
+ public boolean hasMoreElements() {
+ return iter.hasNext();
+ }
+ public E nextElement() {
+ return iter.next();
+ }
+ };
+ }
+
+ /**
+ * Adapt the specified Enumeration to the Iterator interface.
+ * @param e the Enumeration to adapt.
+ * @param <E> element type
+ * @return an Iterator.
+ */
+ public static <E> Iterator<E> asIterator(final Enumeration<E> e) {
+ return new Iterator<E>() {
+ public boolean hasNext() {
+ return e.hasMoreElements();
+ }
+ public E next() {
+ return e.nextElement();
+ }
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+ };
+ }
+
+ /**
+ * Returns a collection containing all elements of the iterator.
+ *
+ * @param iter the Iterator to convert
+ * @param <T> element type
+ * @return the collection
+ * @since Ant 1.8.0
+ */
+ public static <T> Collection<T> asCollection(final Iterator<? extends T> iter) {
+ List<T> l = new ArrayList<T>();
+ while (iter.hasNext()) {
+ l.add(iter.next());
+ }
+ return l;
+ }
+
+ private static final class CompoundEnumeration<E> implements Enumeration<E> {
+
+ private final Enumeration<E> e1, e2;
+
+ public CompoundEnumeration(Enumeration<E> e1, Enumeration<E> e2) {
+ this.e1 = e1;
+ this.e2 = e2;
+ }
+
+ public boolean hasMoreElements() {
+ return e1.hasMoreElements() || e2.hasMoreElements();
+ }
+
+ public E nextElement() throws NoSuchElementException {
+ if (e1.hasMoreElements()) {
+ return e1.nextElement();
+ } else {
+ return e2.nextElement();
+ }
+ }
+
+ }
+
+ /**
+ * Counts how often the given Object occurs in the given
+ * collection using equals() for comparison.
+ *
+ * @param c collection in which to search
+ * @param o object to search
+ * @return frequency
+ * @since Ant 1.8.0
+ */
+ public static int frequency(Collection<?> c, Object o) {
+ // same as Collections.frequency introduced with JDK 1.5
+ int freq = 0;
+ if (c != null) {
+ for (Iterator<?> i = c.iterator(); i.hasNext();) {
+ Object test = i.next();
+ if (o == null ? test == null : o.equals(test)) {
+ freq++;
+ }
+ }
+ }
+ return freq;
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/CompositeMapper.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/CompositeMapper.java
new file mode 100644
index 00000000..d04a5fc9
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/CompositeMapper.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.util;
+
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+
+/**
+ * A <code>ContainerMapper</code> that unites the results of its constituent
+ * <code>FileNameMapper</code>s into a single set of result filenames.
+ */
+public class CompositeMapper extends ContainerMapper {
+
+ /** {@inheritDoc}. */
+ public String[] mapFileName(String sourceFileName) {
+ LinkedHashSet results = new LinkedHashSet();
+
+ FileNameMapper mapper = null;
+ for (Iterator mIter = getMappers().iterator(); mIter.hasNext();) {
+ mapper = (FileNameMapper) (mIter.next());
+ if (mapper != null) {
+ String[] mapped = mapper.mapFileName(sourceFileName);
+ if (mapped != null) {
+ for (int i = 0; i < mapped.length; i++) {
+ results.add(mapped[i]);
+ }
+ }
+ }
+ }
+ return (results.size() == 0) ? null
+ : (String[]) results.toArray(new String[results.size()]);
+ }
+
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/ConcatFileInputStream.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/ConcatFileInputStream.java
new file mode 100644
index 00000000..22dcb7fb
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/ConcatFileInputStream.java
@@ -0,0 +1,136 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.util;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.ProjectComponent;
+import org.apache.tools.ant.Task;
+
+/**
+ * Special <code>InputStream</code> that will
+ * concatenate the contents of an array of files.
+ */
+public class ConcatFileInputStream extends InputStream {
+
+ private static final int EOF = -1;
+ private int currentIndex = -1;
+ private boolean eof = false;
+ private File[] file;
+ private InputStream currentStream;
+ private ProjectComponent managingPc;
+
+ /**
+ * Construct a new <code>ConcatFileInputStream</code>
+ * with the specified <code>File[]</code>.
+ * @param file <code>File[]</code>.
+ * @throws IOException if I/O errors occur.
+ */
+ public ConcatFileInputStream(File[] file) throws IOException {
+ this.file = file;
+ }
+
+ /**
+ * Close the stream.
+ * @throws IOException if there is an error.
+ */
+ public void close() throws IOException {
+ closeCurrent();
+ eof = true;
+ }
+
+ /**
+ * Read a byte.
+ * @return the byte (0 - 255) or -1 if this is the end of the stream.
+ * @throws IOException if there is an error.
+ */
+ public int read() throws IOException {
+ int result = readCurrent();
+ if (result == EOF && !eof) {
+ openFile(++currentIndex);
+ result = readCurrent();
+ }
+ return result;
+ }
+
+ /**
+ * Set a managing <code>Task</code> for
+ * this <code>ConcatFileInputStream</code>.
+ * @param task the managing <code>Task</code>.
+ */
+ public void setManagingTask(Task task) {
+ setManagingComponent(task);
+ }
+
+ /**
+ * Set a managing <code>Task</code> for
+ * this <code>ConcatFileInputStream</code>.
+ * @param pc the managing <code>Task</code>.
+ */
+ public void setManagingComponent(ProjectComponent pc) {
+ this.managingPc = pc;
+ }
+
+ /**
+ * Log a message with the specified logging level.
+ * @param message the <code>String</code> message.
+ * @param loglevel the <code>int</code> logging level.
+ */
+ public void log(String message, int loglevel) {
+ if (managingPc != null) {
+ managingPc.log(message, loglevel);
+ } else {
+ if (loglevel > Project.MSG_WARN) {
+ System.out.println(message);
+ } else {
+ System.err.println(message);
+ }
+ }
+ }
+
+ private int readCurrent() throws IOException {
+ return (eof || currentStream == null) ? EOF : currentStream.read();
+ }
+
+ private void openFile(int index) throws IOException {
+ closeCurrent();
+ if (file != null && index < file.length) {
+ log("Opening " + file[index], Project.MSG_VERBOSE);
+ try {
+ currentStream = new BufferedInputStream(
+ new FileInputStream(file[index]));
+ } catch (IOException eyeOhEx) {
+ log("Failed to open " + file[index], Project.MSG_ERR);
+ throw eyeOhEx;
+ }
+ } else {
+ eof = true;
+ }
+ }
+
+ private void closeCurrent() {
+ FileUtils.close(currentStream);
+ currentStream = null;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/ConcatResourceInputStream.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/ConcatResourceInputStream.java
new file mode 100644
index 00000000..7bae58e5
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/ConcatResourceInputStream.java
@@ -0,0 +1,147 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.util;
+
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Iterator;
+
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.ProjectComponent;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.ResourceCollection;
+
+/**
+ * Special <code>InputStream</code> that will
+ * concatenate the contents of Resources from a single ResourceCollection.
+ * @since Ant 1.7
+ */
+public class ConcatResourceInputStream extends InputStream {
+
+ private static final int EOF = -1;
+ private boolean eof = false;
+ private Iterator<Resource> iter;
+ private InputStream currentStream;
+ private ProjectComponent managingPc;
+ private boolean ignoreErrors = false;
+
+ /**
+ * Construct a new ConcatResourceInputStream
+ * for the specified ResourceCollection.
+ * @param rc the ResourceCollection to combine.
+ */
+ public ConcatResourceInputStream(ResourceCollection rc) {
+ iter = rc.iterator();
+ }
+
+ /**
+ * Set whether this ConcatResourceInputStream ignores errors.
+ * @param b whether to ignore errors.
+ */
+ public void setIgnoreErrors(boolean b) {
+ ignoreErrors = b;
+ }
+
+ /**
+ * Find out whether this ConcatResourceInputStream ignores errors.
+ * @return boolean ignore-errors flag.
+ */
+ public boolean isIgnoreErrors() {
+ return ignoreErrors;
+ }
+
+ /**
+ * Close the stream.
+ * @throws IOException if there is an error.
+ */
+ public void close() throws IOException {
+ closeCurrent();
+ eof = true;
+ }
+
+ /**
+ * Read a byte.
+ * @return the byte (0 - 255) or -1 if this is the end of the stream.
+ * @throws IOException if there is an error.
+ */
+ public int read() throws IOException {
+ if (eof) {
+ return EOF;
+ }
+ int result = readCurrent();
+ if (result == EOF) {
+ nextResource();
+ result = readCurrent();
+ }
+ return result;
+ }
+
+ /**
+ * Set a managing <code>ProjectComponent</code> for
+ * this <code>ConcatResourceInputStream</code>.
+ * @param pc the managing <code>ProjectComponent</code>.
+ */
+ public void setManagingComponent(ProjectComponent pc) {
+ this.managingPc = pc;
+ }
+
+ /**
+ * Log a message with the specified logging level.
+ * @param message the <code>String</code> message.
+ * @param loglevel the <code>int</code> logging level.
+ */
+ public void log(String message, int loglevel) {
+ if (managingPc != null) {
+ managingPc.log(message, loglevel);
+ } else {
+ (loglevel > Project.MSG_WARN ? System.out : System.err).println(message);
+ }
+ }
+
+ private int readCurrent() throws IOException {
+ return eof || currentStream == null ? EOF : currentStream.read();
+ }
+
+ private void nextResource() throws IOException {
+ closeCurrent();
+ while (iter.hasNext()) {
+ Resource r = (Resource) iter.next();
+ if (!r.isExists()) {
+ continue;
+ }
+ log("Concating " + r.toLongString(), Project.MSG_VERBOSE);
+ try {
+ currentStream = new BufferedInputStream(r.getInputStream());
+ return;
+ } catch (IOException eyeOhEx) {
+ if (!ignoreErrors) {
+ log("Failed to get input stream for " + r, Project.MSG_ERR);
+ throw eyeOhEx;
+ }
+ }
+ }
+ eof = true;
+ }
+
+ private void closeCurrent() {
+ FileUtils.close(currentStream);
+ currentStream = null;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/ContainerMapper.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/ContainerMapper.java
new file mode 100644
index 00000000..990ee148
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/ContainerMapper.java
@@ -0,0 +1,119 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.util;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.tools.ant.types.Mapper;
+
+/**
+ * A <code>FileNameMapper</code> that contains
+ * other <code>FileNameMapper</code>s.
+ * @see FileNameMapper
+ */
+public abstract class ContainerMapper implements FileNameMapper {
+
+ private List mappers = new ArrayList();
+
+ /**
+ * Add a <code>Mapper</code>.
+ * @param mapper the <code>Mapper</code> to add.
+ */
+ public void addConfiguredMapper(Mapper mapper) {
+ add(mapper.getImplementation());
+ }
+
+ /**
+ * An add configured version of the add method.
+ * This class used to contain an add method and an
+ * addConfiguredMapper method. Dur to ordering,
+ * the add method was always called first. This
+ * addConfigured method has been added to allow
+ * chaining to work correctly.
+ * @param fileNameMapper a <code>FileNameMapper</code>.
+ */
+ public void addConfigured(FileNameMapper fileNameMapper) {
+ add(fileNameMapper);
+ }
+
+ /**
+ * Add a <code>FileNameMapper</code>.
+ * @param fileNameMapper a <code>FileNameMapper</code>.
+ * @throws IllegalArgumentException if attempting to add this
+ * <code>ContainerMapper</code> to itself, or if the specified
+ * <code>FileNameMapper</code> is itself a <code>ContainerMapper</code>
+ * that contains this <code>ContainerMapper</code>.
+ */
+ public synchronized void add(FileNameMapper fileNameMapper) {
+ if (this == fileNameMapper
+ || (fileNameMapper instanceof ContainerMapper
+ && ((ContainerMapper) fileNameMapper).contains(this))) {
+ throw new IllegalArgumentException(
+ "Circular mapper containment condition detected");
+ } else {
+ mappers.add(fileNameMapper);
+ }
+ }
+
+ /**
+ * Return <code>true</code> if this <code>ContainerMapper</code> or any of
+ * its sub-elements contains the specified <code>FileNameMapper</code>.
+ * @param fileNameMapper the <code>FileNameMapper</code> to search for.
+ * @return <code>boolean</code>.
+ */
+ protected synchronized boolean contains(FileNameMapper fileNameMapper) {
+ boolean foundit = false;
+ for (Iterator iter = mappers.iterator(); iter.hasNext() && !foundit;) {
+ FileNameMapper next = (FileNameMapper) (iter.next());
+ foundit = (next == fileNameMapper
+ || (next instanceof ContainerMapper
+ && ((ContainerMapper) next).contains(fileNameMapper)));
+ }
+ return foundit;
+ }
+
+ /**
+ * Get the <code>List</code> of <code>FileNameMapper</code>s.
+ * @return <code>List</code>.
+ */
+ public synchronized List getMappers() {
+ return Collections.unmodifiableList(mappers);
+ }
+
+ /**
+ * Empty implementation.
+ * @param ignore ignored.
+ */
+ public void setFrom(String ignore) {
+ //Empty
+ }
+
+ /**
+ * Empty implementation.
+ * @param ignore ignored.
+ */
+ public void setTo(String ignore) {
+ //Empty
+ }
+
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/DOMElementWriter.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/DOMElementWriter.java
new file mode 100644
index 00000000..14cbaee2
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/DOMElementWriter.java
@@ -0,0 +1,640 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.util;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+
+import org.w3c.dom.Attr;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.Text;
+
+/**
+ * Writes a DOM tree to a given Writer.
+ * warning: this utility currently does not declare XML Namespaces.
+ * <p>Utility class used by {@link org.apache.tools.ant.XmlLogger
+ * XmlLogger} and
+ * org.apache.tools.ant.taskdefs.optional.junit.XMLJUnitResultFormatter
+ * XMLJUnitResultFormatter}.</p>
+ *
+ */
+public class DOMElementWriter {
+
+ private static final int HEX = 16;
+
+ private static final String[] WS_ENTITIES = new String['\r' - '\t' + 1];
+ static {
+ for (int i = '\t'; i < '\r' + 1; i++) {
+ WS_ENTITIES[i - '\t'] = "&#x" + Integer.toHexString(i) + ";";
+ }
+ }
+
+ /** prefix for generated prefixes */
+ private static final String NS = "ns";
+
+ /** xml declaration is on by default */
+ private boolean xmlDeclaration = true;
+
+ /**
+ * XML Namespaces are ignored by default.
+ */
+ private XmlNamespacePolicy namespacePolicy = XmlNamespacePolicy.IGNORE;
+
+ /**
+ * Map (URI to prefix) of known namespaces.
+ */
+ private HashMap nsPrefixMap = new HashMap();
+
+ /**
+ * Number of generated prefix to use next.
+ */
+ private int nextPrefix = 0;
+
+ /**
+ * Map (Element to URI) of namespaces defined on a given element.
+ */
+ private HashMap nsURIByElement = new HashMap();
+
+ /**
+ * Whether namespaces should be ignored for elements and attributes.
+ *
+ * @since Ant 1.7
+ */
+ public static class XmlNamespacePolicy {
+ private boolean qualifyElements;
+ private boolean qualifyAttributes;
+
+ /**
+ * Ignores namespaces for elements and attributes, the default.
+ */
+ public static final XmlNamespacePolicy IGNORE =
+ new XmlNamespacePolicy(false, false);
+
+ /**
+ * Ignores namespaces for attributes.
+ */
+ public static final XmlNamespacePolicy ONLY_QUALIFY_ELEMENTS =
+ new XmlNamespacePolicy(true, false);
+
+ /**
+ * Qualifies namespaces for elements and attributes.
+ */
+ public static final XmlNamespacePolicy QUALIFY_ALL =
+ new XmlNamespacePolicy(true, true);
+
+ /**
+ * @param qualifyElements whether to qualify elements
+ * @param qualifyAttributes whether to qualify elements
+ */
+ public XmlNamespacePolicy(boolean qualifyElements,
+ boolean qualifyAttributes) {
+ this.qualifyElements = qualifyElements;
+ this.qualifyAttributes = qualifyAttributes;
+ }
+ }
+
+ /**
+ * Create an element writer.
+ * The ?xml? declaration will be included, namespaces ignored.
+ */
+ public DOMElementWriter() {
+ }
+
+ /**
+ * Create an element writer
+ * XML namespaces will be ignored.
+ * @param xmlDeclaration flag to indicate whether the ?xml? declaration
+ * should be included.
+ * @since Ant1.7
+ */
+ public DOMElementWriter(boolean xmlDeclaration) {
+ this(xmlDeclaration, XmlNamespacePolicy.IGNORE);
+ }
+
+ /**
+ * Create an element writer
+ * XML namespaces will be ignored.
+ * @param xmlDeclaration flag to indicate whether the ?xml? declaration
+ * should be included.
+ * @param namespacePolicy the policy to use.
+ * @since Ant1.7
+ */
+ public DOMElementWriter(boolean xmlDeclaration,
+ XmlNamespacePolicy namespacePolicy) {
+ this.xmlDeclaration = xmlDeclaration;
+ this.namespacePolicy = namespacePolicy;
+ }
+
+ private static String lSep = System.getProperty("line.separator");
+
+ // CheckStyle:VisibilityModifier OFF - bc
+ /**
+ * Don't try to be too smart but at least recognize the predefined
+ * entities.
+ */
+ protected String[] knownEntities = {"gt", "amp", "lt", "apos", "quot"};
+ // CheckStyle:VisibilityModifier ON
+
+
+ /**
+ * Writes a DOM tree to a stream in UTF8 encoding. Note that
+ * it prepends the &lt;?xml version='1.0' encoding='UTF-8'?&gt; if
+ * the xmlDeclaration field is true.
+ * The indent number is set to 0 and a 2-space indent.
+ * @param root the root element of the DOM tree.
+ * @param out the outputstream to write to.
+ * @throws IOException if an error happens while writing to the stream.
+ */
+ public void write(Element root, OutputStream out) throws IOException {
+ Writer wri = new OutputStreamWriter(out, "UTF8");
+ writeXMLDeclaration(wri);
+ write(root, wri, 0, " ");
+ wri.flush();
+ }
+
+ /**
+ * Writes the XML declaration if xmlDeclaration is true.
+ * @param wri the writer to write to.
+ * @throws IOException if there is an error.
+ * @since Ant 1.7.0
+ */
+ public void writeXMLDeclaration(Writer wri) throws IOException {
+ if (xmlDeclaration) {
+ wri.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
+ }
+ }
+
+ /**
+ * Writes a DOM tree to a stream.
+ *
+ * @param element the Root DOM element of the tree
+ * @param out where to send the output
+ * @param indent number of
+ * @param indentWith string that should be used to indent the
+ * corresponding tag.
+ * @throws IOException if an error happens while writing to the stream.
+ */
+ public void write(Element element, Writer out, int indent,
+ String indentWith)
+ throws IOException {
+
+ // Write child elements and text
+ NodeList children = element.getChildNodes();
+ boolean hasChildren = (children.getLength() > 0);
+ boolean hasChildElements = false;
+ openElement(element, out, indent, indentWith, hasChildren);
+
+ if (hasChildren) {
+ for (int i = 0; i < children.getLength(); i++) {
+ Node child = children.item(i);
+
+ switch (child.getNodeType()) {
+
+ case Node.ELEMENT_NODE:
+ hasChildElements = true;
+ if (i == 0) {
+ out.write(lSep);
+ }
+ write((Element) child, out, indent + 1, indentWith);
+ break;
+
+ case Node.TEXT_NODE:
+ out.write(encode(child.getNodeValue()));
+ break;
+
+ case Node.COMMENT_NODE:
+ out.write("<!--");
+ out.write(encode(child.getNodeValue()));
+ out.write("-->");
+ break;
+
+ case Node.CDATA_SECTION_NODE:
+ out.write("<![CDATA[");
+ encodedata(out, ((Text) child).getData());
+ out.write("]]>");
+ break;
+
+ case Node.ENTITY_REFERENCE_NODE:
+ out.write('&');
+ out.write(child.getNodeName());
+ out.write(';');
+ break;
+
+ case Node.PROCESSING_INSTRUCTION_NODE:
+ out.write("<?");
+ out.write(child.getNodeName());
+ String data = child.getNodeValue();
+ if (data != null && data.length() > 0) {
+ out.write(' ');
+ out.write(data);
+ }
+ out.write("?>");
+ break;
+ default:
+ // Do nothing
+ }
+ }
+ closeElement(element, out, indent, indentWith, hasChildElements);
+ }
+ }
+
+ /**
+ * Writes the opening tag - including all attributes -
+ * corresponding to a DOM element.
+ *
+ * @param element the DOM element to write
+ * @param out where to send the output
+ * @param indent number of
+ * @param indentWith string that should be used to indent the
+ * corresponding tag.
+ * @throws IOException if an error happens while writing to the stream.
+ */
+ public void openElement(Element element, Writer out, int indent,
+ String indentWith)
+ throws IOException {
+ openElement(element, out, indent, indentWith, true);
+ }
+
+ /**
+ * Writes the opening tag - including all attributes -
+ * corresponding to a DOM element.
+ *
+ * @param element the DOM element to write
+ * @param out where to send the output
+ * @param indent number of
+ * @param indentWith string that should be used to indent the
+ * corresponding tag.
+ * @param hasChildren whether this element has children.
+ * @throws IOException if an error happens while writing to the stream.
+ * @since Ant 1.7
+ */
+ public void openElement(Element element, Writer out, int indent,
+ String indentWith, boolean hasChildren)
+ throws IOException {
+ // Write indent characters
+ for (int i = 0; i < indent; i++) {
+ out.write(indentWith);
+ }
+
+ // Write element
+ out.write("<");
+ if (namespacePolicy.qualifyElements) {
+ String uri = getNamespaceURI(element);
+ String prefix = (String) nsPrefixMap.get(uri);
+ if (prefix == null) {
+ if (nsPrefixMap.isEmpty()) {
+ // steal default namespace
+ prefix = "";
+ } else {
+ prefix = NS + (nextPrefix++);
+ }
+ nsPrefixMap.put(uri, prefix);
+ addNSDefinition(element, uri);
+ }
+ if (!"".equals(prefix)) {
+ out.write(prefix);
+ out.write(":");
+ }
+ }
+ out.write(element.getTagName());
+
+ // Write attributes
+ NamedNodeMap attrs = element.getAttributes();
+ for (int i = 0; i < attrs.getLength(); i++) {
+ Attr attr = (Attr) attrs.item(i);
+ out.write(" ");
+ if (namespacePolicy.qualifyAttributes) {
+ String uri = getNamespaceURI(attr);
+ String prefix = (String) nsPrefixMap.get(uri);
+ if (prefix == null) {
+ prefix = NS + (nextPrefix++);
+ nsPrefixMap.put(uri, prefix);
+ addNSDefinition(element, uri);
+ }
+ out.write(prefix);
+ out.write(":");
+ }
+ out.write(attr.getName());
+ out.write("=\"");
+ out.write(encodeAttributeValue(attr.getValue()));
+ out.write("\"");
+ }
+
+ // write namespace declarations
+ ArrayList al = (ArrayList) nsURIByElement.get(element);
+ if (al != null) {
+ Iterator iter = al.iterator();
+ while (iter.hasNext()) {
+ String uri = (String) iter.next();
+ String prefix = (String) nsPrefixMap.get(uri);
+ out.write(" xmlns");
+ if (!"".equals(prefix)) {
+ out.write(":");
+ out.write(prefix);
+ }
+ out.write("=\"");
+ out.write(uri);
+ out.write("\"");
+ }
+ }
+
+ if (hasChildren) {
+ out.write(">");
+ } else {
+ removeNSDefinitions(element);
+ out.write(" />");
+ out.write(lSep);
+ out.flush();
+ }
+ }
+
+ /**
+ * Writes a DOM tree to a stream.
+ *
+ * @param element the Root DOM element of the tree
+ * @param out where to send the output
+ * @param indent number of
+ * @param indentWith string that should be used to indent the
+ * corresponding tag.
+ * @param hasChildren if true indent.
+ * @throws IOException if an error happens while writing to the stream.
+ */
+ public void closeElement(Element element, Writer out, int indent,
+ String indentWith, boolean hasChildren)
+ throws IOException {
+ // If we had child elements, we need to indent before we close
+ // the element, otherwise we're on the same line and don't need
+ // to indent
+ if (hasChildren) {
+ for (int i = 0; i < indent; i++) {
+ out.write(indentWith);
+ }
+ }
+
+ // Write element close
+ out.write("</");
+ if (namespacePolicy.qualifyElements) {
+ String uri = getNamespaceURI(element);
+ String prefix = (String) nsPrefixMap.get(uri);
+ if (prefix != null && !"".equals(prefix)) {
+ out.write(prefix);
+ out.write(":");
+ }
+ removeNSDefinitions(element);
+ }
+ out.write(element.getTagName());
+ out.write(">");
+ out.write(lSep);
+ out.flush();
+ }
+
+ /**
+ * Escape &lt;, &gt; &amp; &apos;, &quot; as their entities and
+ * drop characters that are illegal in XML documents.
+ * @param value the string to encode.
+ * @return the encoded string.
+ */
+ public String encode(String value) {
+ return encode(value, false);
+ }
+
+ /**
+ * Escape &lt;, &gt; &amp; &apos;, &quot; as their entities, \n,
+ * \r and \t as numeric entities and drop characters that are
+ * illegal in XML documents.
+ * @param value the string to encode.
+ * @return the encoded string.
+ */
+ public String encodeAttributeValue(String value) {
+ return encode(value, true);
+ }
+
+ private String encode(final String value, final boolean encodeWhitespace) {
+ final int len = value.length();
+ final StringBuffer sb = new StringBuffer(len);
+ for (int i = 0; i < len; i++) {
+ final char c = value.charAt(i);
+ switch (c) {
+ case '<':
+ sb.append("&lt;");
+ break;
+ case '>':
+ sb.append("&gt;");
+ break;
+ case '\'':
+ sb.append("&apos;");
+ break;
+ case '\"':
+ sb.append("&quot;");
+ break;
+ case '&':
+ sb.append("&amp;");
+ break;
+ case '\r':
+ case '\n':
+ case '\t':
+ if (encodeWhitespace) {
+ sb.append(WS_ENTITIES[c - '\t']);
+ } else {
+ sb.append(c);
+ }
+ break;
+ default:
+ if (isLegalCharacter(c)) {
+ sb.append(c);
+ }
+ break;
+ }
+ }
+ return sb.substring(0);
+ }
+
+ /**
+ * Drop characters that are illegal in XML documents.
+ *
+ * <p>Also ensure that we are not including an <code>]]&gt;</code>
+ * marker by replacing that sequence with
+ * <code>&amp;#x5d;&amp;#x5d;&amp;gt;</code>.</p>
+ *
+ * <p>See XML 1.0 2.2 <a
+ * href="http://www.w3.org/TR/1998/REC-xml-19980210#charsets">
+ * http://www.w3.org/TR/1998/REC-xml-19980210#charsets</a> and
+ * 2.7 <a
+ * href="http://www.w3.org/TR/1998/REC-xml-19980210#sec-cdata-sect">http://www.w3.org/TR/1998/REC-xml-19980210#sec-cdata-sect</a>.</p>
+ * @param value the value to be encoded.
+ * @return the encoded value.
+ */
+ public String encodedata(final String value) {
+ final StringWriter out = new StringWriter();
+ try {
+ encodedata(out, value);
+ } catch (IOException ex) {
+ throw new RuntimeException(ex);
+ }
+ return out.toString();
+ }
+
+ /**
+ * Drop characters that are illegal in XML documents and write the
+ * rest to the given writer.
+ *
+ * <p>Also ensure that we are not including an <code>]]&gt;</code>
+ * marker by replacing that sequence with
+ * <code>&amp;#x5d;&amp;#x5d;&amp;gt;</code>.</p>
+ *
+ * <p>See XML 1.0 2.2 <a
+ * href="http://www.w3.org/TR/1998/REC-xml-19980210#charsets">
+ * http://www.w3.org/TR/1998/REC-xml-19980210#charsets</a> and
+ * 2.7 <a
+ * href="http://www.w3.org/TR/1998/REC-xml-19980210#sec-cdata-sect">http://www.w3.org/TR/1998/REC-xml-19980210#sec-cdata-sect</a>.</p>
+ * @param value the value to be encoded.
+ * @param out where to write the encoded data to.
+ */
+ public void encodedata(final Writer out, final String value) throws IOException {
+ final int len = value.length();
+ int prevEnd = 0, cdataEndPos = value.indexOf("]]>");
+ while (prevEnd < len) {
+ final int end = (cdataEndPos < 0 ? len : cdataEndPos);
+ // Write out stretches of legal characters in the range [prevEnd, end).
+ for (int prevLegalCharPos = prevEnd; prevLegalCharPos < end;/*empty*/) {
+ int illegalCharPos;
+ for (illegalCharPos = prevLegalCharPos; true; ++illegalCharPos) {
+ if (illegalCharPos >= end
+ || !isLegalCharacter(value.charAt(illegalCharPos))) {
+ break;
+ }
+ }
+ out.write(value, prevLegalCharPos, illegalCharPos - prevLegalCharPos);
+ prevLegalCharPos = illegalCharPos + 1;
+ }
+
+ if (cdataEndPos >= 0) {
+ out.write("]]]]><![CDATA[>");
+ prevEnd = cdataEndPos + 3;
+ cdataEndPos = value.indexOf("]]>", prevEnd);
+ } else {
+ prevEnd = end;
+ }
+ }
+ }
+
+ /**
+ * Is the given argument a character or entity reference?
+ * @param ent the value to be checked.
+ * @return true if it is an entity.
+ */
+ public boolean isReference(String ent) {
+ if (!(ent.charAt(0) == '&') || !ent.endsWith(";")) {
+ return false;
+ }
+
+ if (ent.charAt(1) == '#') {
+ if (ent.charAt(2) == 'x') {
+ try {
+ // CheckStyle:MagicNumber OFF
+ Integer.parseInt(ent.substring(3, ent.length() - 1), HEX);
+ // CheckStyle:MagicNumber ON
+ return true;
+ } catch (NumberFormatException nfe) {
+ return false;
+ }
+ } else {
+ try {
+ Integer.parseInt(ent.substring(2, ent.length() - 1));
+ return true;
+ } catch (NumberFormatException nfe) {
+ return false;
+ }
+ }
+ }
+
+ String name = ent.substring(1, ent.length() - 1);
+ for (int i = 0; i < knownEntities.length; i++) {
+ if (name.equals(knownEntities[i])) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Is the given character allowed inside an XML document?
+ *
+ * <p>See XML 1.0 2.2 <a
+ * href="http://www.w3.org/TR/1998/REC-xml-19980210#charsets">
+ * http://www.w3.org/TR/1998/REC-xml-19980210#charsets</a>.</p>
+ * @param c the character to test.
+ * @return true if the character is allowed.
+ * @since 1.10, Ant 1.5
+ */
+ public boolean isLegalCharacter(final char c) {
+ // CheckStyle:MagicNumber OFF
+ if (c == 0x9 || c == 0xA || c == 0xD) {
+ return true;
+ } else if (c < 0x20) {
+ return false;
+ } else if (c <= 0xD7FF) {
+ return true;
+ } else if (c < 0xE000) {
+ return false;
+ } else if (c <= 0xFFFD) {
+ return true;
+ }
+ // CheckStyle:MagicNumber ON
+ return false;
+ }
+
+ private void removeNSDefinitions(Element element) {
+ ArrayList al = (ArrayList) nsURIByElement.get(element);
+ if (al != null) {
+ Iterator iter = al.iterator();
+ while (iter.hasNext()) {
+ nsPrefixMap.remove(iter.next());
+ }
+ nsURIByElement.remove(element);
+ }
+ }
+
+ private void addNSDefinition(Element element, String uri) {
+ ArrayList al = (ArrayList) nsURIByElement.get(element);
+ if (al == null) {
+ al = new ArrayList();
+ nsURIByElement.put(element, al);
+ }
+ al.add(uri);
+ }
+
+ private static String getNamespaceURI(Node n) {
+ String uri = n.getNamespaceURI();
+ if (uri == null) {
+ // FIXME: Is "No Namespace is Empty Namespace" really OK?
+ uri = "";
+ }
+ return uri;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/DOMUtils.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/DOMUtils.java
new file mode 100644
index 00000000..db00213d
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/DOMUtils.java
@@ -0,0 +1,163 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.util;
+
+import org.w3c.dom.CDATASection;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Text;
+
+// CheckStyle:HideUtilityClassConstructorCheck OFF - bc
+
+/**
+ * Some utility methods for common tasks when building DOM trees in memory.
+ *
+ * <p>In this documentation <code>&lt;a&gt;</code> means an {@link
+ * org.w3c.dom.Element Element} instance with name <code>a</code>.</p>
+ *
+ * @since Ant 1.6.3
+ */
+public class DOMUtils {
+
+ /**
+ * Get a new Document instance,
+ * @return the document.
+ * @since Ant 1.6.3
+ */
+ public static Document newDocument() {
+ return JAXPUtils.getDocumentBuilder().newDocument();
+ }
+
+ /**
+ * Creates a named Element and appends it to the given element,
+ * returns it.
+ *
+ * <p>This means
+ * <pre>createChildElement(&lt;a&gt;, "b")</pre>
+ * creates
+ * <pre>
+ * &lt;a&gt;
+ * &lt;b/&gt;
+ * &lt;/a&gt;
+ * </pre>
+ * and returns <code>&lt;b&gt;</code>.
+ *
+ * @param parent element that will receive the new element as child.
+ * @param name name of the new element.
+ * @return the new element.
+ *
+ * @since Ant 1.6.3
+ */
+ public static Element createChildElement(Element parent, String name) {
+ Document doc = parent.getOwnerDocument();
+ Element e = doc.createElement(name);
+ parent.appendChild(e);
+ return e;
+ }
+
+ /**
+ * Adds nested text.
+ *
+ * <p>This means
+ * <pre>appendText(&lt;a&gt;, "b")</pre>
+ * creates
+ * <pre>
+ * &lt;a&gt;b&lt;/a&gt;
+ * </pre>
+ *
+ * @param parent element that will receive the new element as child.
+ * @param content text content.
+ *
+ * @since Ant 1.6.3
+ */
+ public static void appendText(Element parent, String content) {
+ Document doc = parent.getOwnerDocument();
+ Text t = doc.createTextNode(content);
+ parent.appendChild(t);
+ }
+
+ /**
+ * Adds a nested CDATA section.
+ *
+ * <p>This means
+ * <pre>appendCDATA(&lt;a&gt;, "b")</pre>
+ * creates
+ * <pre>
+ * &lt;a&gt;&lt;[!CDATA[b]]&gt;&lt;/a&gt;
+ * </pre>
+ *
+ * @param parent element that will receive the new element as child.
+ * @param content text content.
+ *
+ * @since Ant 1.6.3
+ */
+ public static void appendCDATA(Element parent, String content) {
+ Document doc = parent.getOwnerDocument();
+ CDATASection c = doc.createCDATASection(content);
+ parent.appendChild(c);
+ }
+
+ /**
+ * Adds nested text in a new child element.
+ *
+ * <p>This means
+ * <pre>appendTextElement(&lt;a&gt;, "b", "c")</pre>
+ * creates
+ * <pre>
+ * &lt;a&gt;
+ * &lt;b&gt;c&lt;/b&gt;
+ * &lt;/a&gt;
+ * </pre>
+ *
+ * @param parent element that will receive the new element as child.
+ * @param name of the child element.
+ * @param content text content.
+ *
+ * @since Ant 1.6.3
+ */
+ public static void appendTextElement(Element parent, String name,
+ String content) {
+ Element e = createChildElement(parent, name);
+ appendText(e, content);
+ }
+
+ /**
+ * Adds a nested CDATA section in a new child element.
+ *
+ * <p>This means
+ * <pre>appendCDATAElement(&lt;a&gt;, "b", "c")</pre>
+ * creates
+ * <pre>
+ * &lt;a&gt;
+ * &lt;b&gt;&lt;![CDATA[c]]&gt;&lt;/b&gt;
+ * &lt;/a&gt;
+ * </pre>
+ *
+ * @param parent element that will receive the new element as child.
+ * @param name of the child element.
+ * @param content text content.
+ *
+ * @since Ant 1.6.3
+ */
+ public static void appendCDATAElement(Element parent, String name,
+ String content) {
+ Element e = createChildElement(parent, name);
+ appendCDATA(e, content);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/DateUtils.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/DateUtils.java
new file mode 100644
index 00000000..9ce737b0
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/DateUtils.java
@@ -0,0 +1,301 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.util;
+
+import java.text.ChoiceFormat;
+import java.text.DateFormat;
+import java.text.MessageFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.Locale;
+import java.util.TimeZone;
+
+/**
+ * Helper methods to deal with date/time formatting with a specific
+ * defined format (<a href="http://www.w3.org/TR/NOTE-datetime">ISO8601</a>)
+ * or a plurialization correct elapsed time in minutes and seconds.
+ *
+ * @since Ant 1.5
+ *
+ */
+public final class DateUtils {
+
+ private static final int ONE_SECOND = 1000;
+ private static final int ONE_MINUTE = 60;
+ private static final int ONE_HOUR = 60;
+ private static final int TEN = 10;
+ /**
+ * ISO8601-like pattern for date-time. It does not support timezone.
+ * <tt>yyyy-MM-ddTHH:mm:ss</tt>
+ */
+ public static final String ISO8601_DATETIME_PATTERN
+ = "yyyy-MM-dd'T'HH:mm:ss";
+
+ /**
+ * ISO8601-like pattern for date. <tt>yyyy-MM-dd</tt>
+ */
+ public static final String ISO8601_DATE_PATTERN
+ = "yyyy-MM-dd";
+
+ /**
+ * ISO8601-like pattern for time. <tt>HH:mm:ss</tt>
+ */
+ public static final String ISO8601_TIME_PATTERN
+ = "HH:mm:ss";
+
+ /**
+ * Format used for SMTP (and probably other) Date headers.
+ * @deprecated DateFormat is not thread safe, and we cannot guarantee that
+ * some other code is using the format in parallel.
+ * Deprecated since ant 1.8
+ */
+ public static final DateFormat DATE_HEADER_FORMAT
+ = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss ", Locale.US);
+
+ private static final DateFormat DATE_HEADER_FORMAT_INT
+ = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss ", Locale.US);
+
+
+// code from Magesh moved from DefaultLogger and slightly modified
+ private static final MessageFormat MINUTE_SECONDS
+ = new MessageFormat("{0}{1}");
+
+ private static final double[] LIMITS = {0, 1, 2};
+
+ private static final String[] MINUTES_PART = {"", "1 minute ", "{0,number,###############} minutes "};
+
+ private static final String[] SECONDS_PART = {"0 seconds", "1 second", "{1,number} seconds"};
+
+ private static final ChoiceFormat MINUTES_FORMAT =
+ new ChoiceFormat(LIMITS, MINUTES_PART);
+
+ private static final ChoiceFormat SECONDS_FORMAT =
+ new ChoiceFormat(LIMITS, SECONDS_PART);
+
+ static {
+ MINUTE_SECONDS.setFormat(0, MINUTES_FORMAT);
+ MINUTE_SECONDS.setFormat(1, SECONDS_FORMAT);
+ }
+
+ /** private constructor */
+ private DateUtils() {
+ }
+
+
+ /**
+ * Format a date/time into a specific pattern.
+ * @param date the date to format expressed in milliseconds.
+ * @param pattern the pattern to use to format the date.
+ * @return the formatted date.
+ */
+ public static String format(long date, String pattern) {
+ return format(new Date(date), pattern);
+ }
+
+
+ /**
+ * Format a date/time into a specific pattern.
+ * @param date the date to format expressed in milliseconds.
+ * @param pattern the pattern to use to format the date.
+ * @return the formatted date.
+ */
+ public static String format(Date date, String pattern) {
+ DateFormat df = createDateFormat(pattern);
+ return df.format(date);
+ }
+
+
+ /**
+ * Format an elapsed time into a plurialization correct string.
+ * It is limited only to report elapsed time in minutes and
+ * seconds and has the following behavior.
+ * <ul>
+ * <li>minutes are not displayed when 0. (ie: "45 seconds")</li>
+ * <li>seconds are always displayed in plural form (ie "0 seconds" or
+ * "10 seconds") except for 1 (ie "1 second")</li>
+ * </ul>
+ * @param millis the elapsed time to report in milliseconds.
+ * @return the formatted text in minutes/seconds.
+ */
+ public static String formatElapsedTime(long millis) {
+ long seconds = millis / ONE_SECOND;
+ long minutes = seconds / ONE_MINUTE;
+ Object[] args = {new Long(minutes), new Long(seconds % ONE_MINUTE)};
+ return MINUTE_SECONDS.format(args);
+ }
+
+ /**
+ * return a lenient date format set to GMT time zone.
+ * @param pattern the pattern used for date/time formatting.
+ * @return the configured format for this pattern.
+ */
+ private static DateFormat createDateFormat(String pattern) {
+ SimpleDateFormat sdf = new SimpleDateFormat(pattern);
+ TimeZone gmt = TimeZone.getTimeZone("GMT");
+ sdf.setTimeZone(gmt);
+ sdf.setLenient(true);
+ return sdf;
+ }
+
+ /**
+ * Calculate the phase of the moon for a given date.
+ *
+ * <p>Code heavily influenced by hacklib.c in <a
+ * href="http://www.nethack.org/">Nethack</a></p>
+ *
+ * <p>The Algorithm:
+ *
+ * <pre>
+ * moon period = 29.53058 days ~= 30, year = 365.2422 days
+ *
+ * days moon phase advances on first day of year compared to preceding year
+ * = 365.2422 - 12*29.53058 ~= 11
+ *
+ * years in Metonic cycle (time until same phases fall on the same days of
+ * the month) = 18.6 ~= 19
+ *
+ * moon phase on first day of year (epact) ~= (11*(year%19) + 18) % 30
+ * (18 as initial condition for 1900)
+ *
+ * current phase in days = first day phase + days elapsed in year
+ *
+ * 6 moons ~= 177 days
+ * 177 ~= 8 reported phases * 22
+ * + 11/22 for rounding
+ * </pre>
+ *
+ * @param cal the calendar.
+ *
+ * @return The phase of the moon as a number between 0 and 7 with
+ * 0 meaning new moon and 4 meaning full moon.
+ *
+ * @since 1.2, Ant 1.5
+ */
+ public static int getPhaseOfMoon(Calendar cal) {
+ // CheckStyle:MagicNumber OFF
+ int dayOfTheYear = cal.get(Calendar.DAY_OF_YEAR);
+ int yearInMetonicCycle = ((cal.get(Calendar.YEAR) - 1900) % 19) + 1;
+ int epact = (11 * yearInMetonicCycle + 18) % 30;
+ if ((epact == 25 && yearInMetonicCycle > 11) || epact == 24) {
+ epact++;
+ }
+ return (((((dayOfTheYear + epact) * 6) + 11) % 177) / 22) & 7;
+ // CheckStyle:MagicNumber ON
+ }
+
+ /**
+ * Returns the current Date in a format suitable for a SMTP date
+ * header.
+ * @return the current date.
+ * @since Ant 1.5.2
+ */
+ public static String getDateForHeader() {
+ Calendar cal = Calendar.getInstance();
+ TimeZone tz = cal.getTimeZone();
+ int offset = tz.getOffset(cal.get(Calendar.ERA),
+ cal.get(Calendar.YEAR),
+ cal.get(Calendar.MONTH),
+ cal.get(Calendar.DAY_OF_MONTH),
+ cal.get(Calendar.DAY_OF_WEEK),
+ cal.get(Calendar.MILLISECOND));
+ StringBuffer tzMarker = new StringBuffer(offset < 0 ? "-" : "+");
+ offset = Math.abs(offset);
+ int hours = offset / (ONE_HOUR * ONE_MINUTE * ONE_SECOND);
+ int minutes = offset / (ONE_MINUTE * ONE_SECOND) - ONE_HOUR * hours;
+ if (hours < TEN) {
+ tzMarker.append("0");
+ }
+ tzMarker.append(hours);
+ if (minutes < TEN) {
+ tzMarker.append("0");
+ }
+ tzMarker.append(minutes);
+ synchronized (DATE_HEADER_FORMAT_INT) {
+ return DATE_HEADER_FORMAT_INT.format(cal.getTime()) + tzMarker.toString();
+ }
+ }
+
+ /**
+ * Parses the string in a format suitable for a SMTP date header.
+ *
+ * @param datestr string to be parsed
+ *
+ * @return a java.util.Date object as parsed by the format.
+ * @exception ParseException if the supplied string cannot be parsed by
+ * this pattern.
+ * @since Ant 1.8.0
+ */
+ public static Date parseDateFromHeader(String datestr) throws ParseException {
+ synchronized (DATE_HEADER_FORMAT_INT) {
+ return DATE_HEADER_FORMAT_INT.parse(datestr);
+ }
+ }
+
+ /**
+ * Parse a string as a datetime using the ISO8601_DATETIME format which is
+ * <code>yyyy-MM-dd'T'HH:mm:ss</code>
+ *
+ * @param datestr string to be parsed
+ *
+ * @return a java.util.Date object as parsed by the format.
+ * @exception ParseException if the supplied string cannot be parsed by
+ * this pattern.
+ * @since Ant 1.6
+ */
+ public static Date parseIso8601DateTime(String datestr)
+ throws ParseException {
+ return new SimpleDateFormat(ISO8601_DATETIME_PATTERN).parse(datestr);
+ }
+
+ /**
+ * Parse a string as a date using the ISO8601_DATE format which is
+ * <code>yyyy-MM-dd</code>
+ *
+ * @param datestr string to be parsed
+ *
+ * @return a java.util.Date object as parsed by the format.
+ * @exception ParseException if the supplied string cannot be parsed by
+ * this pattern.
+ * @since Ant 1.6
+ */
+ public static Date parseIso8601Date(String datestr) throws ParseException {
+ return new SimpleDateFormat(ISO8601_DATE_PATTERN).parse(datestr);
+ }
+
+ /**
+ * Parse a string as a date using the either the ISO8601_DATETIME
+ * or ISO8601_DATE formats.
+ *
+ * @param datestr string to be parsed
+ *
+ * @return a java.util.Date object as parsed by the formats.
+ * @exception ParseException if the supplied string cannot be parsed by
+ * either of these patterns.
+ * @since Ant 1.6
+ */
+ public static Date parseIso8601DateTimeOrDate(String datestr)
+ throws ParseException {
+ try {
+ return parseIso8601DateTime(datestr);
+ } catch (ParseException px) {
+ return parseIso8601Date(datestr);
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/DeweyDecimal.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/DeweyDecimal.java
new file mode 100644
index 00000000..003f1406
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/DeweyDecimal.java
@@ -0,0 +1,237 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.util;
+
+import java.util.StringTokenizer;
+
+/**
+ * Utility class to contain version numbers in "Dewey Decimal"
+ * syntax. Numbers in the "Dewey Decimal" syntax consist of positive
+ * decimal integers separated by periods ".". For example, "2.0" or
+ * "1.2.3.4.5.6.7". This allows an extensible number to be used to
+ * represent major, minor, micro, etc versions. The version number
+ * must begin with a number.
+ *
+ */
+public class DeweyDecimal implements Comparable<DeweyDecimal> {
+
+ /** Array of components that make up DeweyDecimal */
+ private final int[] components;
+
+ /**
+ * Construct a DeweyDecimal from an array of integer components.
+ *
+ * @param components an array of integer components.
+ */
+ public DeweyDecimal(final int[] components) {
+ this.components = new int[components.length];
+ System.arraycopy(components, 0, this.components, 0, components.length);
+ }
+
+ /**
+ * Construct a DeweyDecimal from string in DeweyDecimal format.
+ *
+ * @param string the string in dewey decimal format
+ * @exception NumberFormatException if string is malformed
+ */
+ public DeweyDecimal(final String string)
+ throws NumberFormatException {
+ final StringTokenizer tokenizer = new StringTokenizer(string, ".", true);
+ final int size = tokenizer.countTokens();
+
+ components = new int[ (size + 1) / 2 ];
+
+ for (int i = 0; i < components.length; i++) {
+ final String component = tokenizer.nextToken();
+ if (component.length() == 0) {
+ throw new NumberFormatException("Empty component in string");
+ }
+
+ components[ i ] = Integer.parseInt(component);
+
+ //Strip '.' token
+ if (tokenizer.hasMoreTokens()) {
+ tokenizer.nextToken();
+
+ //If it ended in a dot, throw an exception
+ if (!tokenizer.hasMoreTokens()) {
+ throw new NumberFormatException("DeweyDecimal ended in a '.'");
+ }
+ }
+ }
+ }
+
+ /**
+ * Return number of components in <code>DeweyDecimal</code>.
+ *
+ * @return the number of components in dewey decimal
+ */
+ public int getSize() {
+ return components.length;
+ }
+
+ /**
+ * Return the component at specified index.
+ *
+ * @param index the index of components
+ * @return the value of component at index
+ */
+ public int get(final int index) {
+ return components[ index ];
+ }
+
+ /**
+ * Return <code>true</code> if this <code>DeweyDecimal</code> is
+ * equal to the other <code>DeweyDecimal</code>.
+ *
+ * @param other the other DeweyDecimal
+ * @return true if equal to other DeweyDecimal, false otherwise
+ */
+ public boolean isEqual(final DeweyDecimal other) {
+ final int max = Math.max(other.components.length, components.length);
+
+ for (int i = 0; i < max; i++) {
+ final int component1 = (i < components.length) ? components[ i ] : 0;
+ final int component2 = (i < other.components.length) ? other.components[ i ] : 0;
+
+ if (component2 != component1) {
+ return false;
+ }
+ }
+
+ return true; // Exact match
+ }
+
+ /**
+ * Return <code>true</code> if this <code>DeweyDecimal</code> is
+ * less than the other <code>DeweyDecimal</code>.
+ *
+ * @param other the other DeweyDecimal
+ * @return true if less than other DeweyDecimal, false otherwise
+ */
+ public boolean isLessThan(final DeweyDecimal other) {
+ return !isGreaterThanOrEqual(other);
+ }
+
+ /**
+ * Return <code>true</code> if this <code>DeweyDecimal</code> is
+ * less than or equal to the other <code>DeweyDecimal</code>.
+ *
+ * @param other the other DeweyDecimal
+ * @return true if less than or equal to other DeweyDecimal, false otherwise
+ */
+ public boolean isLessThanOrEqual(final DeweyDecimal other) {
+ return !isGreaterThan(other);
+ }
+
+ /**
+ * Return <code>true</code> if this <code>DeweyDecimal</code> is
+ * greater than the other <code>DeweyDecimal</code>.
+ *
+ * @param other the other DeweyDecimal
+ * @return true if greater than other DeweyDecimal, false otherwise
+ */
+ public boolean isGreaterThan(final DeweyDecimal other) {
+ final int max = Math.max(other.components.length, components.length);
+
+ for (int i = 0; i < max; i++) {
+ final int component1 = (i < components.length) ? components[ i ] : 0;
+ final int component2 = (i < other.components.length) ? other.components[ i ] : 0;
+
+ if (component2 > component1) {
+ return false;
+ }
+ if (component2 < component1) {
+ return true;
+ }
+ }
+
+ return false; // Exact match
+ }
+
+ /**
+ * Return <code>true</code> if this <code>DeweyDecimal</code> is
+ * greater than or equal to the other <code>DeweyDecimal</code>.
+ *
+ * @param other the other DeweyDecimal
+ * @return true if greater than or equal to other DeweyDecimal, false otherwise
+ */
+ public boolean isGreaterThanOrEqual(final DeweyDecimal other) {
+ final int max = Math.max(other.components.length, components.length);
+
+ for (int i = 0; i < max; i++) {
+ final int component1 = (i < components.length) ? components[ i ] : 0;
+ final int component2 = (i < other.components.length) ? other.components[ i ] : 0;
+
+ if (component2 > component1) {
+ return false;
+ }
+ if (component2 < component1) {
+ return true;
+ }
+ }
+
+ return true; // Exact match
+ }
+
+ /**
+ * Return string representation of <code>DeweyDecimal</code>.
+ *
+ * @return the string representation of DeweyDecimal.
+ */
+ @Override public String toString() {
+ final StringBuffer sb = new StringBuffer();
+
+ for (int i = 0; i < components.length; i++) {
+ if (i != 0) {
+ sb.append('.');
+ }
+ sb.append(components[ i ]);
+ }
+
+ return sb.toString();
+ }
+
+ /**
+ * Compares this DeweyDecimal with another one.
+ *
+ * @param other another DeweyDecimal to compare with
+ * @return result
+ * @see java.lang.Comparable#compareTo(Object)
+ */
+ public int compareTo(DeweyDecimal other) {
+ final int max = Math.max(other.components.length, components.length);
+ for (int i = 0; i < max; i++) {
+ final int component1 = (i < components.length) ? components[ i ] : 0;
+ final int component2 = (i < other.components.length) ? other.components[ i ] : 0;
+ if (component1 != component2) {
+ return component1 - component2;
+ }
+ }
+ return 0;
+ }
+
+ @Override public int hashCode() {
+ return toString().hashCode();
+ }
+
+ @Override public boolean equals(Object o) {
+ return o instanceof DeweyDecimal && isEqual((DeweyDecimal) o);
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/FileNameMapper.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/FileNameMapper.java
new file mode 100644
index 00000000..bbd82614
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/FileNameMapper.java
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.util;
+
+/**
+ * Interface to be used by SourceFileScanner.
+ *
+ * <p>Used to find the name of the target file(s) corresponding to a
+ * source file.</p>
+ *
+ * <p>The rule by which the file names are transformed is specified
+ * via the setFrom and setTo methods. The exact meaning of these is
+ * implementation dependent.</p>
+ *
+ */
+public interface FileNameMapper {
+
+ /**
+ * Sets the from part of the transformation rule.
+ * @param from a string.
+ */
+ void setFrom(String from);
+
+ /**
+ * Sets the to part of the transformation rule.
+ * @param to a string.
+ */
+ void setTo(String to);
+
+ /**
+ * Returns an array containing the target filename(s) for the
+ * given source file.
+ *
+ * <p>if the given rule doesn't apply to the source file,
+ * implementation must return null. SourceFileScanner will then
+ * omit the source file in question.</p>
+ *
+ * @param sourceFileName the name of the source file relative to
+ * some given basedirectory.
+ * @return an array of strings if the rule applies to the source file, or
+ * null if it does not.
+ */
+ String[] mapFileName(String sourceFileName);
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/FileTokenizer.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/FileTokenizer.java
new file mode 100644
index 00000000..2807aa42
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/FileTokenizer.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.util;
+
+import java.io.IOException;
+import java.io.Reader;
+
+import org.apache.tools.ant.ProjectComponent;
+
+/**
+ * Class to read the complete input into a string.
+ * @since Ant 1.7
+ */
+public class FileTokenizer extends ProjectComponent implements Tokenizer {
+
+ /**
+ * Get the complete input as a string
+ * @param in the reader object
+ * @return the complete input
+ * @throws IOException if error reading
+ */
+ public String getToken(Reader in) throws IOException {
+ return FileUtils.readFully(in);
+ }
+
+ /**
+ * Return the intra-token string
+ * @return an empty string always
+ */
+ public String getPostToken() {
+ return "";
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/FileUtils.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/FileUtils.java
new file mode 100644
index 00000000..bcef5ecf
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/FileUtils.java
@@ -0,0 +1,1722 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.util;
+
+import java.io.File;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.io.Writer;
+import java.net.HttpURLConnection;
+import java.net.JarURLConnection;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.nio.channels.Channel;
+import java.text.DecimalFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Random;
+import java.util.Stack;
+import java.util.StringTokenizer;
+import java.util.Vector;
+import java.util.jar.JarFile;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.PathTokenizer;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.launch.Locator;
+import org.apache.tools.ant.taskdefs.condition.Os;
+import org.apache.tools.ant.types.FilterSetCollection;
+import org.apache.tools.ant.types.resources.FileResource;
+
+/**
+ * This class also encapsulates methods which allow Files to be
+ * referred to using abstract path names which are translated to native
+ * system file paths at runtime as well as copying files or setting
+ * their last modification time.
+ *
+ */
+public class FileUtils {
+ private static final int DELETE_RETRY_SLEEP_MILLIS = 10;
+ private static final int EXPAND_SPACE = 50;
+ private static final FileUtils PRIMARY_INSTANCE = new FileUtils();
+
+ //get some non-crypto-grade randomness from various places.
+ private static Random rand = new Random(System.currentTimeMillis()
+ + Runtime.getRuntime().freeMemory());
+
+ private static final boolean ON_NETWARE = Os.isFamily("netware");
+ private static final boolean ON_DOS = Os.isFamily("dos");
+ private static final boolean ON_WIN9X = Os.isFamily("win9x");
+ private static final boolean ON_WINDOWS = Os.isFamily("windows");
+
+ static final int BUF_SIZE = 8192;
+
+
+ /**
+ * The granularity of timestamps under FAT.
+ */
+ public static final long FAT_FILE_TIMESTAMP_GRANULARITY = 2000;
+
+ /**
+ * The granularity of timestamps under Unix.
+ */
+ public static final long UNIX_FILE_TIMESTAMP_GRANULARITY = 1000;
+
+ /**
+ * The granularity of timestamps under the NT File System.
+ * NTFS has a granularity of 100 nanoseconds, which is less
+ * than 1 millisecond, so we round this up to 1 millisecond.
+ */
+ public static final long NTFS_FILE_TIMESTAMP_GRANULARITY = 1;
+
+ /**
+ * A one item cache for fromUri.
+ * fromUri is called for each element when parseing ant build
+ * files. It is a costly operation. This just caches the result
+ * of the last call.
+ */
+ private Object cacheFromUriLock = new Object();
+ private String cacheFromUriRequest = null;
+ private String cacheFromUriResponse = null;
+
+ /**
+ * Factory method.
+ *
+ * @return a new instance of FileUtils.
+ * @deprecated since 1.7.
+ * Use getFileUtils instead,
+ * FileUtils do not have state.
+ */
+ public static FileUtils newFileUtils() {
+ return new FileUtils();
+ }
+
+ /**
+ * Method to retrieve The FileUtils, which is shared by all users of this
+ * method.
+ * @return an instance of FileUtils.
+ * @since Ant 1.6.3
+ */
+ public static FileUtils getFileUtils() {
+ return PRIMARY_INSTANCE;
+ }
+
+ /**
+ * Empty constructor.
+ */
+ protected FileUtils() {
+ }
+
+ /**
+ * Get the URL for a file taking into account # characters.
+ *
+ * @param file the file whose URL representation is required.
+ * @return The FileURL value.
+ * @throws MalformedURLException if the URL representation cannot be
+ * formed.
+ */
+ public URL getFileURL(File file) throws MalformedURLException {
+ return new URL(file.toURI().toASCIIString());
+ }
+
+ /**
+ * Convenience method to copy a file from a source to a destination.
+ * No filtering is performed.
+ *
+ * @param sourceFile Name of file to copy from.
+ * Must not be <code>null</code>.
+ * @param destFile Name of file to copy to.
+ * Must not be <code>null</code>.
+ *
+ * @throws IOException if the copying fails.
+ */
+ public void copyFile(String sourceFile, String destFile) throws IOException {
+ copyFile(new File(sourceFile), new File(destFile), null, false, false);
+ }
+
+ /**
+ * Convenience method to copy a file from a source to a destination
+ * specifying if token filtering must be used.
+ *
+ * @param sourceFile Name of file to copy from.
+ * Must not be <code>null</code>.
+ * @param destFile Name of file to copy to.
+ * Must not be <code>null</code>.
+ * @param filters the collection of filters to apply to this copy.
+ *
+ * @throws IOException if the copying fails.
+ */
+ public void copyFile(String sourceFile, String destFile, FilterSetCollection filters)
+ throws IOException {
+ copyFile(new File(sourceFile), new File(destFile), filters, false, false);
+ }
+
+ /**
+ * Convenience method to copy a file from a source to a destination specifying if token
+ * filtering must be used and if source files may overwrite newer destination files.
+ *
+ * @param sourceFile Name of file to copy from. Must not be <code>null</code>.
+ * @param destFile Name of file to copy to. Must not be <code>null</code>.
+ * @param filters the collection of filters to apply to this copy.
+ * @param overwrite Whether or not the destination file should be overwritten if it already
+ * exists.
+ *
+ * @throws IOException if the copying fails.
+ */
+ public void copyFile(String sourceFile, String destFile, FilterSetCollection filters,
+ boolean overwrite) throws IOException {
+ copyFile(new File(sourceFile), new File(destFile), filters, overwrite, false);
+ }
+
+ /**
+ * Convenience method to copy a file from a source to a destination
+ * specifying if token
+ * filtering must be used, if source files may overwrite newer destination
+ * files and the last
+ * modified time of <code>destFile</code> file should be made equal to
+ * the last modified time
+ * of <code>sourceFile</code>.
+ *
+ * @param sourceFile Name of file to copy from. Must not be <code>null</code>.
+ * @param destFile Name of file to copy to. Must not be <code>null</code>.
+ * @param filters the collection of filters to apply to this copy.
+ * @param overwrite Whether or not the destination file should be
+ * overwritten if it already exists.
+ * @param preserveLastModified Whether or not the last modified time of
+ * the resulting file
+ * should be set to that of the source file.
+ *
+ * @throws IOException if the copying fails.
+ */
+ public void copyFile(String sourceFile, String destFile,
+ FilterSetCollection filters,
+ boolean overwrite, boolean preserveLastModified)
+ throws IOException {
+ copyFile(new File(sourceFile), new File(destFile), filters, overwrite,
+ preserveLastModified);
+ }
+
+ /**
+ * Convenience method to copy a file from a source to a destination specifying if token
+ * filtering must be used, if source files may overwrite newer destination files and the last
+ * modified time of <code>destFile</code> file should be made equal to the last modified time
+ * of <code>sourceFile</code>.
+ *
+ * @param sourceFile Name of file to copy from. Must not be <code>null</code>.
+ * @param destFile Name of file to copy to. Must not be <code>null</code>.
+ * @param filters the collection of filters to apply to this copy.
+ * @param overwrite Whether or not the destination file should be overwritten if it already
+ * exists.
+ * @param preserveLastModified Whether or not the last modified time of the resulting file
+ * should be set to that of the source file.
+ * @param encoding the encoding used to read and write the files.
+ *
+ * @throws IOException if the copying fails.
+ *
+ * @since Ant 1.5
+ */
+ public void copyFile(String sourceFile, String destFile,
+ FilterSetCollection filters, boolean overwrite,
+ boolean preserveLastModified, String encoding) throws IOException {
+ copyFile(new File(sourceFile), new File(destFile), filters,
+ overwrite, preserveLastModified, encoding);
+ }
+
+ // CheckStyle:ParameterNumberCheck OFF - bc
+ /**
+ * Convenience method to copy a file from a source to a
+ * destination specifying if token filtering must be used, if
+ * filter chains must be used, if source files may overwrite
+ * newer destination files and the last modified time of
+ * <code>destFile</code> file should be made equal
+ * to the last modified time of <code>sourceFile</code>.
+ *
+ * @param sourceFile Name of file to copy from.
+ * Must not be <code>null</code>.
+ * @param destFile Name of file to copy to.
+ * Must not be <code>null</code>.
+ * @param filters the collection of filters to apply to this copy.
+ * @param filterChains filterChains to apply during the copy.
+ * @param overwrite Whether or not the destination file should be
+ * overwritten if it already exists.
+ * @param preserveLastModified Whether or not the last modified time of
+ * the resulting file should be set to that
+ * of the source file.
+ * @param encoding the encoding used to read and write the files.
+ * @param project the project instance.
+ *
+ * @throws IOException if the copying fails.
+ *
+ * @since Ant 1.5
+ */
+ public void copyFile(String sourceFile, String destFile,
+ FilterSetCollection filters, Vector filterChains,
+ boolean overwrite, boolean preserveLastModified,
+ String encoding, Project project) throws IOException {
+ copyFile(new File(sourceFile), new File(destFile), filters, filterChains, overwrite,
+ preserveLastModified, encoding, project);
+ }
+
+ /**
+ * Convenience method to copy a file from a source to a destination specifying if token
+ * filtering must be used, if filter chains must be used, if source files may overwrite newer
+ * destination files and the last modified time of <code>destFile</code> file should be made
+ * equal to the last modified time of <code>sourceFile</code>.
+ *
+ * @param sourceFile Name of file to copy from. Must not be <code>null</code>.
+ * @param destFile Name of file to copy to. Must not be <code>null</code>.
+ * @param filters the collection of filters to apply to this copy.
+ * @param filterChains filterChains to apply during the copy.
+ * @param overwrite Whether or not the destination file should be overwritten if it already
+ * exists.
+ * @param preserveLastModified Whether or not the last modified time of the resulting file
+ * should be set to that of the source file.
+ * @param inputEncoding the encoding used to read the files.
+ * @param outputEncoding the encoding used to write the files.
+ * @param project the project instance.
+ *
+ * @throws IOException if the copying fails.
+ *
+ * @since Ant 1.6
+ */
+ public void copyFile(String sourceFile, String destFile,
+ FilterSetCollection filters, Vector filterChains,
+ boolean overwrite, boolean preserveLastModified,
+ String inputEncoding, String outputEncoding,
+ Project project) throws IOException {
+ copyFile(new File(sourceFile), new File(destFile), filters, filterChains, overwrite,
+ preserveLastModified, inputEncoding, outputEncoding, project);
+ }
+
+ /**
+ * Convenience method to copy a file from a source to a destination. No filtering is performed.
+ *
+ * @param sourceFile the file to copy from. Must not be <code>null</code>.
+ * @param destFile the file to copy to. Must not be <code>null</code>.
+ *
+ * @throws IOException if the copying fails.
+ */
+ public void copyFile(File sourceFile, File destFile) throws IOException {
+ copyFile(sourceFile, destFile, null, false, false);
+ }
+
+ /**
+ * Convenience method to copy a file from a source to a destination
+ * specifying if token filtering must be used.
+ *
+ * @param sourceFile the file to copy from.
+ * Must not be <code>null</code>.
+ * @param destFile the file to copy to.
+ * Must not be <code>null</code>.
+ * @param filters the collection of filters to apply to this copy.
+ *
+ * @throws IOException if the copying fails.
+ */
+ public void copyFile(File sourceFile, File destFile, FilterSetCollection filters)
+ throws IOException {
+ copyFile(sourceFile, destFile, filters, false, false);
+ }
+
+ /**
+ * Convenience method to copy a file from a source to a
+ * destination specifying if token filtering must be used and if
+ * source files may overwrite newer destination files.
+ *
+ * @param sourceFile the file to copy from.
+ * Must not be <code>null</code>.
+ * @param destFile the file to copy to.
+ * Must not be <code>null</code>.
+ * @param filters the collection of filters to apply to this copy.
+ * @param overwrite Whether or not the destination file should be
+ * overwritten if it already exists.
+ *
+ * @throws IOException if the copying fails.
+ */
+ public void copyFile(File sourceFile, File destFile, FilterSetCollection filters,
+ boolean overwrite) throws IOException {
+ copyFile(sourceFile, destFile, filters, overwrite, false);
+ }
+
+ /**
+ * Convenience method to copy a file from a source to a
+ * destination specifying if token filtering must be used, if
+ * source files may overwrite newer destination files and the
+ * last modified time of <code>destFile</code> file should be made equal
+ * to the last modified time of <code>sourceFile</code>.
+ *
+ * @param sourceFile the file to copy from.
+ * Must not be <code>null</code>.
+ * @param destFile the file to copy to.
+ * Must not be <code>null</code>.
+ * @param filters the collection of filters to apply to this copy.
+ * @param overwrite Whether or not the destination file should be
+ * overwritten if it already exists.
+ * @param preserveLastModified Whether or not the last modified time of
+ * the resulting file should be set to that
+ * of the source file.
+ *
+ * @throws IOException if the copying fails.
+ */
+ public void copyFile(File sourceFile, File destFile, FilterSetCollection filters,
+ boolean overwrite, boolean preserveLastModified) throws IOException {
+ copyFile(sourceFile, destFile, filters, overwrite, preserveLastModified, null);
+ }
+
+ /**
+ * Convenience method to copy a file from a source to a destination specifying if token
+ * filtering must be used, if source files may overwrite newer destination files, the last
+ * modified time of <code>destFile</code> file should be made equal to the last modified time
+ * of <code>sourceFile</code> and which character encoding to assume.
+ *
+ * @param sourceFile the file to copy from. Must not be <code>null</code>.
+ * @param destFile the file to copy to. Must not be <code>null</code>.
+ * @param filters the collection of filters to apply to this copy.
+ * @param overwrite Whether or not the destination file should be overwritten if it already
+ * exists.
+ * @param preserveLastModified Whether or not the last modified time of the resulting file
+ * should be set to that of the source file.
+ * @param encoding the encoding used to read and write the files.
+ *
+ * @throws IOException if the copying fails.
+ *
+ * @since Ant 1.5
+ */
+ public void copyFile(File sourceFile, File destFile,
+ FilterSetCollection filters, boolean overwrite,
+ boolean preserveLastModified, String encoding) throws IOException {
+ copyFile(sourceFile, destFile, filters, null, overwrite,
+ preserveLastModified, encoding, null);
+ }
+
+ /**
+ * Convenience method to copy a file from a source to a
+ * destination specifying if token filtering must be used, if
+ * filter chains must be used, if source files may overwrite
+ * newer destination files and the last modified time of
+ * <code>destFile</code> file should be made equal
+ * to the last modified time of <code>sourceFile</code>.
+ *
+ * @param sourceFile the file to copy from.
+ * Must not be <code>null</code>.
+ * @param destFile the file to copy to.
+ * Must not be <code>null</code>.
+ * @param filters the collection of filters to apply to this copy.
+ * @param filterChains filterChains to apply during the copy.
+ * @param overwrite Whether or not the destination file should be
+ * overwritten if it already exists.
+ * @param preserveLastModified Whether or not the last modified time of
+ * the resulting file should be set to that
+ * of the source file.
+ * @param encoding the encoding used to read and write the files.
+ * @param project the project instance.
+ *
+ * @throws IOException if the copying fails.
+ *
+ * @since Ant 1.5
+ */
+ public void copyFile(File sourceFile, File destFile,
+ FilterSetCollection filters, Vector filterChains,
+ boolean overwrite, boolean preserveLastModified,
+ String encoding, Project project) throws IOException {
+ copyFile(sourceFile, destFile, filters, filterChains,
+ overwrite, preserveLastModified, encoding, encoding, project);
+ }
+
+ /**
+ * Convenience method to copy a file from a source to a
+ * destination specifying if token filtering must be used, if
+ * filter chains must be used, if source files may overwrite
+ * newer destination files and the last modified time of
+ * <code>destFile</code> file should be made equal
+ * to the last modified time of <code>sourceFile</code>.
+ *
+ * @param sourceFile the file to copy from.
+ * Must not be <code>null</code>.
+ * @param destFile the file to copy to.
+ * Must not be <code>null</code>.
+ * @param filters the collection of filters to apply to this copy.
+ * @param filterChains filterChains to apply during the copy.
+ * @param overwrite Whether or not the destination file should be
+ * overwritten if it already exists.
+ * @param preserveLastModified Whether or not the last modified time of
+ * the resulting file should be set to that
+ * of the source file.
+ * @param inputEncoding the encoding used to read the files.
+ * @param outputEncoding the encoding used to write the files.
+ * @param project the project instance.
+ *
+ *
+ * @throws IOException if the copying fails.
+ *
+ * @since Ant 1.6
+ */
+ public void copyFile(File sourceFile, File destFile,
+ FilterSetCollection filters, Vector filterChains,
+ boolean overwrite, boolean preserveLastModified,
+ String inputEncoding, String outputEncoding,
+ Project project) throws IOException {
+ copyFile(sourceFile, destFile, filters, filterChains, overwrite, preserveLastModified,
+ false, inputEncoding, outputEncoding, project);
+ }
+
+ /**
+ * Convenience method to copy a file from a source to a
+ * destination specifying if token filtering must be used, if
+ * filter chains must be used, if source files may overwrite
+ * newer destination files and the last modified time of
+ * <code>destFile</code> file should be made equal
+ * to the last modified time of <code>sourceFile</code>.
+ *
+ * @param sourceFile the file to copy from.
+ * Must not be <code>null</code>.
+ * @param destFile the file to copy to.
+ * Must not be <code>null</code>.
+ * @param filters the collection of filters to apply to this copy.
+ * @param filterChains filterChains to apply during the copy.
+ * @param overwrite Whether or not the destination file should be
+ * overwritten if it already exists.
+ * @param preserveLastModified Whether or not the last modified time of
+ * the resulting file should be set to that
+ * of the source file.
+ * @param append whether to append to the destination file.
+ * @param inputEncoding the encoding used to read the files.
+ * @param outputEncoding the encoding used to write the files.
+ * @param project the project instance.
+ *
+ *
+ * @throws IOException if the copying fails.
+ *
+ * @since Ant 1.8
+ */
+ public void copyFile(File sourceFile, File destFile,
+ FilterSetCollection filters, Vector filterChains,
+ boolean overwrite, boolean preserveLastModified,
+ boolean append,
+ String inputEncoding, String outputEncoding,
+ Project project) throws IOException {
+ copyFile(sourceFile, destFile, filters, filterChains, overwrite,
+ preserveLastModified, append, inputEncoding, outputEncoding,
+ project, /* force: */ false);
+ }
+
+ /**
+ * Convenience method to copy a file from a source to a
+ * destination specifying if token filtering must be used, if
+ * filter chains must be used, if source files may overwrite
+ * newer destination files and the last modified time of
+ * <code>destFile</code> file should be made equal
+ * to the last modified time of <code>sourceFile</code>.
+ *
+ * @param sourceFile the file to copy from.
+ * Must not be <code>null</code>.
+ * @param destFile the file to copy to.
+ * Must not be <code>null</code>.
+ * @param filters the collection of filters to apply to this copy.
+ * @param filterChains filterChains to apply during the copy.
+ * @param overwrite Whether or not the destination file should be
+ * overwritten if it already exists.
+ * @param preserveLastModified Whether or not the last modified time of
+ * the resulting file should be set to that
+ * of the source file.
+ * @param append whether to append to the destination file.
+ * @param inputEncoding the encoding used to read the files.
+ * @param outputEncoding the encoding used to write the files.
+ * @param project the project instance.
+ * @param force whether to overwrite read-only destination files.
+ *
+ * @throws IOException if the copying fails.
+ *
+ * @since Ant 1.8.2
+ */
+ public void copyFile(File sourceFile, File destFile,
+ FilterSetCollection filters, Vector filterChains,
+ boolean overwrite, boolean preserveLastModified,
+ boolean append,
+ String inputEncoding, String outputEncoding,
+ Project project, boolean force) throws IOException {
+ ResourceUtils.copyResource(new FileResource(sourceFile),
+ new FileResource(destFile),
+ filters, filterChains, overwrite,
+ preserveLastModified, append, inputEncoding,
+ outputEncoding, project, force);
+ }
+
+ // CheckStyle:ParameterNumberCheck ON
+
+ /**
+ * Calls File.setLastModified(long time). Originally written to
+ * to dynamically bind to that call on Java1.2+.
+ *
+ * @param file the file whose modified time is to be set
+ * @param time the time to which the last modified time is to be set.
+ * if this is -1, the current time is used.
+ */
+ public void setFileLastModified(File file, long time) {
+ ResourceUtils.setLastModified(new FileResource(file), time);
+ }
+
+ /**
+ * Interpret the filename as a file relative to the given file
+ * unless the filename already represents an absolute filename.
+ * Differs from <code>new File(file, filename)</code> in that
+ * the resulting File's path will always be a normalized,
+ * absolute pathname. Also, if it is determined that
+ * <code>filename</code> is context-relative, <code>file</code>
+ * will be discarded and the reference will be resolved using
+ * available context/state information about the filesystem.
+ *
+ * @param file the "reference" file for relative paths. This
+ * instance must be an absolute file and must not contain
+ * &quot;./&quot; or &quot;../&quot; sequences (same for \ instead
+ * of /). If it is null, this call is equivalent to
+ * <code>new java.io.File(filename).getAbsoluteFile()</code>.
+ *
+ * @param filename a file name.
+ *
+ * @return an absolute file.
+ * @throws java.lang.NullPointerException if filename is null.
+ */
+ public File resolveFile(File file, String filename) {
+ if (!isAbsolutePath(filename)) {
+ char sep = File.separatorChar;
+ filename = filename.replace('/', sep).replace('\\', sep);
+ if (isContextRelativePath(filename)) {
+ file = null;
+ // on cygwin, our current directory can be a UNC;
+ // assume user.dir is absolute or all hell breaks loose...
+ String udir = System.getProperty("user.dir");
+ if (filename.charAt(0) == sep && udir.charAt(0) == sep) {
+ filename = dissect(udir)[0] + filename.substring(1);
+ }
+ }
+ filename = new File(file, filename).getAbsolutePath();
+ }
+ return normalize(filename);
+ }
+
+ /**
+ * On DOS and NetWare, the evaluation of certain file
+ * specifications is context-dependent. These are filenames
+ * beginning with a single separator (relative to current root directory)
+ * and filenames with a drive specification and no intervening separator
+ * (relative to current directory of the specified root).
+ * @param filename the filename to evaluate.
+ * @return true if the filename is relative to system context.
+ * @throws java.lang.NullPointerException if filename is null.
+ * @since Ant 1.7
+ */
+ public static boolean isContextRelativePath(String filename) {
+ if (!(ON_DOS || ON_NETWARE) || filename.length() == 0) {
+ return false;
+ }
+ char sep = File.separatorChar;
+ filename = filename.replace('/', sep).replace('\\', sep);
+ char c = filename.charAt(0);
+ int len = filename.length();
+ return (c == sep && (len == 1 || filename.charAt(1) != sep))
+ || (Character.isLetter(c) && len > 1
+ && filename.charAt(1) == ':'
+ && (len == 2 || filename.charAt(2) != sep));
+ }
+
+ /**
+ * Verifies that the specified filename represents an absolute path.
+ * Differs from new java.io.File("filename").isAbsolute() in that a path
+ * beginning with a double file separator--signifying a Windows UNC--must
+ * at minimum match "\\a\b" to be considered an absolute path.
+ * @param filename the filename to be checked.
+ * @return true if the filename represents an absolute path.
+ * @throws java.lang.NullPointerException if filename is null.
+ * @since Ant 1.6.3
+ */
+ public static boolean isAbsolutePath(String filename) {
+ int len = filename.length();
+ if (len == 0) {
+ return false;
+ }
+ char sep = File.separatorChar;
+ filename = filename.replace('/', sep).replace('\\', sep);
+ char c = filename.charAt(0);
+ if (!(ON_DOS || ON_NETWARE)) {
+ return (c == sep);
+ }
+ if (c == sep) {
+ // CheckStyle:MagicNumber OFF
+ if (!(ON_DOS && len > 4 && filename.charAt(1) == sep)) {
+ return false;
+ }
+ // CheckStyle:MagicNumber ON
+ int nextsep = filename.indexOf(sep, 2);
+ return nextsep > 2 && nextsep + 1 < len;
+ }
+ int colon = filename.indexOf(':');
+ return (Character.isLetter(c) && colon == 1
+ && filename.length() > 2 && filename.charAt(2) == sep)
+ || (ON_NETWARE && colon > 0);
+ }
+
+ /**
+ * Translate a path into its native (platform specific) format.
+ * <p>
+ * This method uses PathTokenizer to separate the input path
+ * into its components. This handles DOS style paths in a relatively
+ * sensible way. The file separators are then converted to their platform
+ * specific versions.
+ *
+ * @param toProcess The path to be translated.
+ * May be <code>null</code>.
+ *
+ * @return the native version of the specified path or
+ * an empty string if the path is <code>null</code> or empty.
+ *
+ * @since ant 1.7
+ * @see PathTokenizer
+ */
+ public static String translatePath(String toProcess) {
+ if (toProcess == null || toProcess.length() == 0) {
+ return "";
+ }
+ StringBuffer path = new StringBuffer(toProcess.length() + EXPAND_SPACE);
+ PathTokenizer tokenizer = new PathTokenizer(toProcess);
+ while (tokenizer.hasMoreTokens()) {
+ String pathComponent = tokenizer.nextToken();
+ pathComponent = pathComponent.replace('/', File.separatorChar);
+ pathComponent = pathComponent.replace('\\', File.separatorChar);
+ if (path.length() != 0) {
+ path.append(File.pathSeparatorChar);
+ }
+ path.append(pathComponent);
+ }
+ return path.toString();
+ }
+
+ /**
+ * &quot;Normalize&quot; the given absolute path.
+ *
+ * <p>This includes:
+ * <ul>
+ * <li>Uppercase the drive letter if there is one.</li>
+ * <li>Remove redundant slashes after the drive spec.</li>
+ * <li>Resolve all ./, .\, ../ and ..\ sequences.</li>
+ * <li>DOS style paths that start with a drive letter will have
+ * \ as the separator.</li>
+ * </ul>
+ * Unlike {@link File#getCanonicalPath()} this method
+ * specifically does not resolve symbolic links.
+ *
+ * @param path the path to be normalized.
+ * @return the normalized version of the path.
+ *
+ * @throws java.lang.NullPointerException if path is null.
+ */
+ public File normalize(final String path) {
+ Stack s = new Stack();
+ String[] dissect = dissect(path);
+ s.push(dissect[0]);
+
+ StringTokenizer tok = new StringTokenizer(dissect[1], File.separator);
+ while (tok.hasMoreTokens()) {
+ String thisToken = tok.nextToken();
+ if (".".equals(thisToken)) {
+ continue;
+ }
+ if ("..".equals(thisToken)) {
+ if (s.size() < 2) {
+ // Cannot resolve it, so skip it.
+ return new File(path);
+ }
+ s.pop();
+ } else { // plain component
+ s.push(thisToken);
+ }
+ }
+ StringBuffer sb = new StringBuffer();
+ final int size = s.size();
+ for (int i = 0; i < size; i++) {
+ if (i > 1) {
+ // not before the filesystem root and not after it, since root
+ // already contains one
+ sb.append(File.separatorChar);
+ }
+ sb.append(s.elementAt(i));
+ }
+ return new File(sb.toString());
+ }
+
+ /**
+ * Dissect the specified absolute path.
+ * @param path the path to dissect.
+ * @return String[] {root, remaining path}.
+ * @throws java.lang.NullPointerException if path is null.
+ * @since Ant 1.7
+ */
+ public String[] dissect(String path) {
+ char sep = File.separatorChar;
+ path = path.replace('/', sep).replace('\\', sep);
+
+ // make sure we are dealing with an absolute path
+ if (!isAbsolutePath(path)) {
+ throw new BuildException(path + " is not an absolute path");
+ }
+ String root = null;
+ int colon = path.indexOf(':');
+ if (colon > 0 && (ON_DOS || ON_NETWARE)) {
+
+ int next = colon + 1;
+ root = path.substring(0, next);
+ char[] ca = path.toCharArray();
+ root += sep;
+ //remove the initial separator; the root has it.
+ next = (ca[next] == sep) ? next + 1 : next;
+
+ StringBuffer sbPath = new StringBuffer();
+ // Eliminate consecutive slashes after the drive spec:
+ for (int i = next; i < ca.length; i++) {
+ if (ca[i] != sep || ca[i - 1] != sep) {
+ sbPath.append(ca[i]);
+ }
+ }
+ path = sbPath.toString();
+ } else if (path.length() > 1 && path.charAt(1) == sep) {
+ // UNC drive
+ int nextsep = path.indexOf(sep, 2);
+ nextsep = path.indexOf(sep, nextsep + 1);
+ root = (nextsep > 2) ? path.substring(0, nextsep + 1) : path;
+ path = path.substring(root.length());
+ } else {
+ root = File.separator;
+ path = path.substring(1);
+ }
+ return new String[] {root, path};
+ }
+
+ /**
+ * Returns a VMS String representation of a <code>File</code> object.
+ * This is useful since the JVM by default internally converts VMS paths
+ * to Unix style.
+ * The returned String is always an absolute path.
+ *
+ * @param f The <code>File</code> to get the VMS path for.
+ * @return The absolute VMS path to <code>f</code>.
+ */
+ public String toVMSPath(File f) {
+ // format: "DEVICE:[DIR.SUBDIR]FILE"
+ String osPath;
+ String path = normalize(f.getAbsolutePath()).getPath();
+ String name = f.getName();
+ boolean isAbsolute = path.charAt(0) == File.separatorChar;
+ // treat directories specified using .DIR syntax as files
+ // CheckStyle:MagicNumber OFF
+ boolean isDirectory = f.isDirectory()
+ && !name.regionMatches(true, name.length() - 4, ".DIR", 0, 4);
+ // CheckStyle:MagicNumber ON
+ String device = null;
+ StringBuffer directory = null;
+ String file = null;
+
+ int index = 0;
+
+ if (isAbsolute) {
+ index = path.indexOf(File.separatorChar, 1);
+ if (index == -1) {
+ return path.substring(1) + ":[000000]";
+ }
+ device = path.substring(1, index++);
+ }
+ if (isDirectory) {
+ directory = new StringBuffer(path.substring(index).replace(File.separatorChar, '.'));
+ } else {
+ int dirEnd = path.lastIndexOf(File.separatorChar, path.length());
+ if (dirEnd == -1 || dirEnd < index) {
+ file = path.substring(index);
+ } else {
+ directory = new StringBuffer(path.substring(index, dirEnd).
+ replace(File.separatorChar, '.'));
+ index = dirEnd + 1;
+ if (path.length() > index) {
+ file = path.substring(index);
+ }
+ }
+ }
+ if (!isAbsolute && directory != null) {
+ directory.insert(0, '.');
+ }
+ osPath = ((device != null) ? device + ":" : "")
+ + ((directory != null) ? "[" + directory + "]" : "")
+ + ((file != null) ? file : "");
+ return osPath;
+ }
+
+ /**
+ * Create a File object for a temporary file in a given directory. Without
+ * actually creating the file.
+ *
+ * <p>
+ * The file denoted by the returned abstract pathname did not exist before
+ * this method was invoked, any subsequent invocation of this method will
+ * yield a different file name.
+ * </p>
+ * <p>
+ * The filename is prefixNNNNNsuffix where NNNN is a random number.
+ * </p>
+ *
+ * @param prefix
+ * prefix before the random number.
+ * @param suffix
+ * file extension; include the '.'.
+ * @param parentDir
+ * Directory to create the temporary file in; java.io.tmpdir used
+ * if not specified.
+ *
+ * @deprecated since ant 1.7.1 use createTempFile(String, String, File,
+ * boolean, boolean) instead.
+ * @return a File reference to the new, nonexistent temporary file.
+ */
+ public File createTempFile(String prefix, String suffix, File parentDir) {
+ return createTempFile(prefix, suffix, parentDir, false, false);
+ }
+
+ private static final String NULL_PLACEHOLDER = "null";
+
+ /**
+ * Create a temporary file in a given directory.
+ *
+ * <p>The file denoted by the returned abstract pathname did not
+ * exist before this method was invoked, any subsequent invocation
+ * of this method will yield a different file name.</p>
+ *
+ * @param prefix prefix before the random number.
+ * @param suffix file extension; include the '.'.
+ * @param parentDir Directory to create the temporary file in;
+ * java.io.tmpdir used if not specified.
+ * @param deleteOnExit whether to set the tempfile for deletion on
+ * normal VM exit.
+ * @param createFile true if the file must actually be created. If false
+ * chances exist that a file with the same name is created in the time
+ * between invoking this method and the moment the file is actually created.
+ * If possible set to true.
+ *
+ * @return a File reference to the new temporary file.
+ * @since Ant 1.7.1
+ */
+ public File createTempFile(String prefix, String suffix, File parentDir,
+ boolean deleteOnExit, boolean createFile) {
+ File result = null;
+ String parent = (parentDir == null)
+ ? System.getProperty("java.io.tmpdir")
+ : parentDir.getPath();
+ if (prefix == null) {
+ prefix = NULL_PLACEHOLDER;
+ }
+ if (suffix == null) {
+ suffix = NULL_PLACEHOLDER;
+ }
+
+ if (createFile) {
+ try {
+ result = File.createTempFile(prefix, suffix, new File(parent));
+ } catch (IOException e) {
+ throw new BuildException("Could not create tempfile in "
+ + parent, e);
+ }
+ } else {
+ DecimalFormat fmt = new DecimalFormat("#####");
+ synchronized (rand) {
+ do {
+ result = new File(parent, prefix
+ + fmt.format(rand.nextInt(Integer.MAX_VALUE)) + suffix);
+ } while (result.exists());
+ }
+ }
+
+ if (deleteOnExit) {
+ result.deleteOnExit();
+ }
+ return result;
+ }
+
+ /**
+ * Create a File object for a temporary file in a given directory. Without
+ * actually creating the file.
+ *
+ * <p>
+ * The file denoted by the returned abstract pathname did not exist before
+ * this method was invoked, any subsequent invocation of this method will
+ * yield a different file name.
+ * </p>
+ * <p>
+ * The filename is prefixNNNNNsuffix where NNNN is a random number.
+ * </p>
+ *
+ * @param prefix
+ * prefix before the random number.
+ * @param suffix
+ * file extension; include the '.'.
+ * @param parentDir
+ * Directory to create the temporary file in; java.io.tmpdir used
+ * if not specified.
+ * @param deleteOnExit
+ * whether to set the tempfile for deletion on normal VM exit.
+ *
+ * @deprecated since ant 1.7.1 use createTempFile(String, String, File,
+ * boolean, boolean) instead.
+ * @return a File reference to the new, nonexistent temporary file.
+ */
+ public File createTempFile(String prefix, String suffix,
+ File parentDir, boolean deleteOnExit) {
+ return createTempFile(prefix, suffix, parentDir, deleteOnExit, false);
+ }
+
+ /**
+ * Compares the contents of two files.
+ *
+ * @param f1 the file whose content is to be compared.
+ * @param f2 the other file whose content is to be compared.
+ *
+ * @return true if the content of the files is the same.
+ *
+ * @throws IOException if the files cannot be read.
+ */
+ public boolean contentEquals(File f1, File f2) throws IOException {
+ return contentEquals(f1, f2, false);
+ }
+
+ /**
+ * Compares the contents of two files.
+ *
+ * @param f1 the file whose content is to be compared.
+ * @param f2 the other file whose content is to be compared.
+ * @param textfile true if the file is to be treated as a text file and
+ * differences in kind of line break are to be ignored.
+ *
+ * @return true if the content of the files is the same.
+ *
+ * @throws IOException if the files cannot be read.
+ * @since Ant 1.6.3
+ */
+ public boolean contentEquals(File f1, File f2, boolean textfile) throws IOException {
+ return ResourceUtils.contentEquals(new FileResource(f1), new FileResource(f2), textfile);
+ }
+
+ /**
+ * This was originally an emulation of {@link File#getParentFile} for JDK 1.1, but it is now
+ * implemented using that method (Ant 1.6.3 onwards).
+ *
+ * @param f the file whose parent is required.
+ * @return the given file's parent, or null if the file does not have a parent.
+ * @since 1.10
+ * @deprecated since 1.7. Just use {@link File#getParentFile} directly.
+ */
+ public File getParentFile(File f) {
+ return (f == null) ? null : f.getParentFile();
+ }
+
+ /**
+ * Read from reader till EOF.
+ * @param rdr the reader from which to read.
+ * @return the contents read out of the given reader.
+ *
+ * @throws IOException if the contents could not be read out from the
+ * reader.
+ */
+ public static String readFully(Reader rdr) throws IOException {
+ return readFully(rdr, BUF_SIZE);
+ }
+
+ /**
+ * Read from reader till EOF.
+ *
+ * @param rdr the reader from which to read.
+ * @param bufferSize the buffer size to use when reading.
+ *
+ * @return the contents read out of the given reader.
+ *
+ * @throws IOException if the contents could not be read out from the
+ * reader.
+ */
+ public static String readFully(Reader rdr, int bufferSize)
+ throws IOException {
+ if (bufferSize <= 0) {
+ throw new IllegalArgumentException("Buffer size must be greater "
+ + "than 0");
+ }
+ final char[] buffer = new char[bufferSize];
+ int bufferLength = 0;
+ StringBuffer textBuffer = null;
+ while (bufferLength != -1) {
+ bufferLength = rdr.read(buffer);
+ if (bufferLength > 0) {
+ textBuffer = (textBuffer == null) ? new StringBuffer() : textBuffer;
+ textBuffer.append(new String(buffer, 0, bufferLength));
+ }
+ }
+ return (textBuffer == null) ? null : textBuffer.toString();
+ }
+
+ /**
+ * Safe read fully - do not return a null for an empty reader.
+ * @param reader the input to read from.
+ * @return the string.
+ * @throws IOException if unable to read from reader.
+ * @since Ant 1.7.1
+ */
+ public static String safeReadFully(Reader reader) throws IOException {
+ String ret = readFully(reader);
+ return ret == null ? "" : ret;
+ }
+
+ /**
+ * This was originally an emulation of File.createNewFile for JDK 1.1,
+ * but it is now implemented using that method (Ant 1.6.3 onwards).
+ *
+ * <p>This method has historically <strong>not</strong> guaranteed that the
+ * operation was atomic. In its current implementation it is.
+ *
+ * @param f the file to be created.
+ * @return true if the file did not exist already.
+ * @throws IOException on error.
+ * @since Ant 1.5
+ */
+ public boolean createNewFile(File f) throws IOException {
+ return f.createNewFile();
+ }
+
+ /**
+ * Create a new file, optionally creating parent directories.
+ *
+ * @param f the file to be created.
+ * @param mkdirs <code>boolean</code> whether to create parent directories.
+ * @return true if the file did not exist already.
+ * @throws IOException on error.
+ * @since Ant 1.6.3
+ */
+ public boolean createNewFile(File f, boolean mkdirs) throws IOException {
+ File parent = f.getParentFile();
+ if (mkdirs && !(parent.exists())) {
+ parent.mkdirs();
+ }
+ return f.createNewFile();
+ }
+
+ /**
+ * Checks whether a given file is a symbolic link.
+ *
+ * <p>It doesn't really test for symbolic links but whether the
+ * canonical and absolute paths of the file are identical--this
+ * may lead to false positives on some platforms.</p>
+ *
+ * @param parent the parent directory of the file to test
+ * @param name the name of the file to test.
+ *
+ * @return true if the file is a symbolic link.
+ * @throws IOException on error.
+ * @since Ant 1.5
+ * @deprecated use SymbolicLinkUtils instead
+ */
+ public boolean isSymbolicLink(File parent, String name)
+ throws IOException {
+ SymbolicLinkUtils u = SymbolicLinkUtils.getSymbolicLinkUtils();
+ if (parent == null) {
+ return u.isSymbolicLink(name);
+ }
+ return u.isSymbolicLink(parent, name);
+ }
+
+ /**
+ * Removes a leading path from a second path.
+ *
+ * @param leading The leading path, must not be null, must be absolute.
+ * @param path The path to remove from, must not be null, must be absolute.
+ *
+ * @return path's normalized absolute if it doesn't start with
+ * leading; path's path with leading's path removed otherwise.
+ *
+ * @since Ant 1.5
+ */
+ public String removeLeadingPath(File leading, File path) {
+ String l = normalize(leading.getAbsolutePath()).getAbsolutePath();
+ String p = normalize(path.getAbsolutePath()).getAbsolutePath();
+ if (l.equals(p)) {
+ return "";
+ }
+ // ensure that l ends with a /
+ // so we never think /foo was a parent directory of /foobar
+ if (!l.endsWith(File.separator)) {
+ l += File.separator;
+ }
+ return (p.startsWith(l)) ? p.substring(l.length()) : p;
+ }
+
+ /**
+ * Learn whether one path "leads" another.
+ * @param leading The leading path, must not be null, must be absolute.
+ * @param path The path to remove from, must not be null, must be absolute.
+ * @return true if path starts with leading; false otherwise.
+ * @since Ant 1.7
+ */
+ public boolean isLeadingPath(File leading, File path) {
+ String l = normalize(leading.getAbsolutePath()).getAbsolutePath();
+ String p = normalize(path.getAbsolutePath()).getAbsolutePath();
+ if (l.equals(p)) {
+ return true;
+ }
+ // ensure that l ends with a /
+ // so we never think /foo was a parent directory of /foobar
+ if (!l.endsWith(File.separator)) {
+ l += File.separator;
+ }
+ return p.startsWith(l);
+ }
+
+ /**
+ * Constructs a <code>file:</code> URI that represents the
+ * external form of the given pathname.
+ *
+ * <p>Will be an absolute URI if the given path is absolute.</p>
+ *
+ * <p>This code encodes non ASCII characters too.</p>
+ *
+ * <p>The coding of the output is the same as what File.toURI().toASCIIString() produces</p>
+ *
+ * See <a href="http://www.w3.org/TR/xml11/#dt-sysid">dt-sysid</a>
+ * which makes some mention of how
+ * characters not supported by URI Reference syntax should be escaped.
+ *
+ * @param path the path in the local file system.
+ * @return the URI version of the local path.
+ * @since Ant 1.6
+ */
+ public String toURI(String path) {
+ return new File(path).toURI().toASCIIString();
+ }
+
+ /**
+ * Constructs a file path from a <code>file:</code> URI.
+ *
+ * <p>Will be an absolute path if the given URI is absolute.</p>
+ *
+ * <p>Swallows '%' that are not followed by two characters,
+ * doesn't deal with non-ASCII characters.</p>
+ *
+ * @param uri the URI designating a file in the local filesystem.
+ * @return the local file system path for the file.
+ * @since Ant 1.6
+ */
+ public String fromURI(String uri) {
+ synchronized (cacheFromUriLock) {
+ if (uri.equals(cacheFromUriRequest)) {
+ return cacheFromUriResponse;
+ }
+ String path = Locator.fromURI(uri);
+ String ret = isAbsolutePath(path) ? normalize(path).getAbsolutePath() : path;
+ cacheFromUriRequest = uri;
+ cacheFromUriResponse = ret;
+ return ret;
+ }
+ }
+
+ /**
+ * Compares two filenames.
+ *
+ * <p>Unlike java.io.File#equals this method will try to compare
+ * the absolute paths and &quot;normalize&quot; the filenames
+ * before comparing them.</p>
+ *
+ * @param f1 the file whose name is to be compared.
+ * @param f2 the other file whose name is to be compared.
+ *
+ * @return true if the file are for the same file.
+ *
+ * @since Ant 1.5.3
+ */
+ public boolean fileNameEquals(File f1, File f2) {
+ return normalize(f1.getAbsolutePath()).getAbsolutePath().equals(
+ normalize(f2.getAbsolutePath()).getAbsolutePath());
+ }
+
+ /**
+ * Are the two File instances pointing to the same object on the
+ * file system?
+ * @since Ant 1.8.2
+ */
+ public boolean areSame(File f1, File f2) throws IOException {
+ if (f1 == null && f2 == null) {
+ return true;
+ }
+ if (f1 == null || f2 == null) {
+ return false;
+ }
+ File f1Normalized = normalize(f1.getAbsolutePath());
+ File f2Normalized = normalize(f2.getAbsolutePath());
+ return f1Normalized.equals(f2Normalized)
+ || f1Normalized.getCanonicalFile().equals(f2Normalized
+ .getCanonicalFile());
+ }
+
+ /**
+ * Renames a file, even if that involves crossing file system boundaries.
+ *
+ * <p>This will remove <code>to</code> (if it exists), ensure that
+ * <code>to</code>'s parent directory exists and move
+ * <code>from</code>, which involves deleting <code>from</code> as
+ * well.</p>
+ *
+ * @param from the file to move.
+ * @param to the new file name.
+ *
+ * @throws IOException if anything bad happens during this
+ * process. Note that <code>to</code> may have been deleted
+ * already when this happens.
+ *
+ * @since Ant 1.6
+ */
+ public void rename(File from, File to) throws IOException {
+ // identical logic lives in Move.renameFile():
+ from = normalize(from.getAbsolutePath()).getCanonicalFile();
+ to = normalize(to.getAbsolutePath());
+ if (!from.exists()) {
+ System.err.println("Cannot rename nonexistent file " + from);
+ return;
+ }
+ if (from.getAbsolutePath().equals(to.getAbsolutePath())) {
+ System.err.println("Rename of " + from + " to " + to + " is a no-op.");
+ return;
+ }
+ if (to.exists() && !(areSame(from, to) || tryHardToDelete(to))) {
+ throw new IOException("Failed to delete " + to + " while trying to rename " + from);
+ }
+ File parent = to.getParentFile();
+ if (parent != null && !parent.isDirectory()
+ && !(parent.mkdirs() || parent.isDirectory())) {
+ throw new IOException("Failed to create directory " + parent
+ + " while trying to rename " + from);
+ }
+ if (!from.renameTo(to)) {
+ copyFile(from, to);
+ if (!tryHardToDelete(from)) {
+ throw new IOException("Failed to delete " + from + " while trying to rename it.");
+ }
+ }
+ }
+
+ /**
+ * Get the granularity of file timestamps. The choice is made based on OS, which is
+ * incorrect--it should really be by filesystem. We do not have an easy way to probe for file
+ * systems, however, so this heuristic gives us a decent default.
+ *
+ * @return the difference, in milliseconds, which two file timestamps must have in order for the
+ * two files to be considered to have different timestamps.
+ */
+ public long getFileTimestampGranularity() {
+ if (ON_WIN9X) {
+ return FAT_FILE_TIMESTAMP_GRANULARITY;
+ }
+ if (ON_WINDOWS) {
+ return NTFS_FILE_TIMESTAMP_GRANULARITY;
+ }
+ if (ON_DOS) {
+ return FAT_FILE_TIMESTAMP_GRANULARITY;
+ }
+ return UNIX_FILE_TIMESTAMP_GRANULARITY;
+ }
+
+ /**
+ * test whether a file or directory exists, with an error in the
+ * upper/lower case spelling of the name.
+ * Using this method is only interesting on case insensitive file systems
+ * (Windows).<br>
+ * It will return true only if 3 conditions are met :
+ * <br>
+ * <ul>
+ * <li>operating system is case insensitive</li>
+ * <li>file exists</li>
+ * <li>actual name from directory reading is different from the
+ * supplied argument</li>
+ * </ul>
+ * <br>
+ * the purpose is to identify files or directories on case-insensitive
+ * filesystems whose case is not what is expected.<br>
+ * Possibly to rename them afterwards to the desired upper/lowercase
+ * combination.
+ *
+ * @param localFile file to test
+ * @return true if the file exists and the case of the actual file
+ * is not the case of the parameter
+ * @since Ant 1.7.1
+ */
+ public boolean hasErrorInCase(File localFile) {
+ localFile = normalize(localFile.getAbsolutePath());
+ if (!localFile.exists()) {
+ return false;
+ }
+ final String localFileName = localFile.getName();
+ FilenameFilter ff = new FilenameFilter () {
+ public boolean accept(File dir, String name) {
+ return name.equalsIgnoreCase(localFileName) && (!name.equals(localFileName));
+ }
+ };
+ String[] names = localFile.getParentFile().list(ff);
+ return names != null && names.length == 1;
+ }
+
+ /**
+ * Returns true if the source is older than the dest.
+ * If the dest file does not exist, then the test returns false; it is
+ * implicitly not up do date.
+ * @param source source file (should be the older).
+ * @param dest dest file (should be the newer).
+ * @param granularity an offset added to the source time.
+ * @return true if the source is older than the dest after accounting
+ * for granularity.
+ * @since Ant 1.6.3
+ */
+ public boolean isUpToDate(File source, File dest, long granularity) {
+ //do a check for the destination file existing
+ if (!dest.exists()) {
+ //if it does not, then the file is not up to date.
+ return false;
+ }
+ long sourceTime = source.lastModified();
+ long destTime = dest.lastModified();
+ return isUpToDate(sourceTime, destTime, granularity);
+ }
+
+ /**
+ * Returns true if the source is older than the dest.
+ * @param source source file (should be the older).
+ * @param dest dest file (should be the newer).
+ * @return true if the source is older than the dest, taking the granularity into account.
+ * @since Ant 1.6.3
+ */
+ public boolean isUpToDate(File source, File dest) {
+ return isUpToDate(source, dest, getFileTimestampGranularity());
+ }
+
+ /**
+ * Compare two timestamps for being up to date using
+ * the specified granularity.
+ *
+ * @param sourceTime timestamp of source file.
+ * @param destTime timestamp of dest file.
+ * @param granularity os/filesys granularity.
+ * @return true if the dest file is considered up to date.
+ */
+ public boolean isUpToDate(long sourceTime, long destTime, long granularity) {
+ return destTime != -1 && destTime >= sourceTime + granularity;
+ }
+
+ /**
+ * Compare two timestamps for being up to date using the
+ * current granularity.
+ *
+ * @param sourceTime timestamp of source file.
+ * @param destTime timestamp of dest file.
+ * @return true if the dest file is considered up to date.
+ */
+ public boolean isUpToDate(long sourceTime, long destTime) {
+ return isUpToDate(sourceTime, destTime, getFileTimestampGranularity());
+ }
+
+ /**
+ * Close a Writer without throwing any exception if something went wrong.
+ * Do not attempt to close it if the argument is null.
+ * @param device output writer, can be null.
+ */
+ public static void close(Writer device) {
+ if (null != device) {
+ try {
+ device.close();
+ } catch (IOException e) {
+ //ignore
+ }
+ }
+ }
+
+ /**
+ * Close a Reader without throwing any exception if something went wrong.
+ * Do not attempt to close it if the argument is null.
+ *
+ * @param device Reader, can be null.
+ */
+ public static void close(Reader device) {
+ if (null != device) {
+ try {
+ device.close();
+ } catch (IOException e) {
+ //ignore
+ }
+ }
+ }
+
+ /**
+ * Close a stream without throwing any exception if something went wrong.
+ * Do not attempt to close it if the argument is null.
+ *
+ * @param device stream, can be null.
+ */
+ public static void close(OutputStream device) {
+ if (null != device) {
+ try {
+ device.close();
+ } catch (IOException e) {
+ //ignore
+ }
+ }
+ }
+
+ /**
+ * Close a stream without throwing any exception if something went wrong.
+ * Do not attempt to close it if the argument is null.
+ *
+ * @param device stream, can be null.
+ */
+ public static void close(InputStream device) {
+ if (null != device) {
+ try {
+ device.close();
+ } catch (IOException e) {
+ //ignore
+ }
+ }
+ }
+
+ /**
+ * Close a Channel without throwing any exception if something went wrong.
+ * Do not attempt to close it if the argument is null.
+ *
+ * @param device channel, can be null.
+ * @since Ant 1.8.0
+ */
+ public static void close(Channel device) {
+ if (null != device) {
+ try {
+ device.close();
+ } catch (IOException e) {
+ //ignore
+ }
+ }
+ }
+
+ /**
+ * Closes an URLConnection if its concrete implementation provides
+ * a way to close it that Ant knows of.
+ *
+ * @param conn connection, can be null
+ * @since Ant 1.8.0
+ */
+ public static void close(URLConnection conn) {
+ if (conn != null) {
+ try {
+ if (conn instanceof JarURLConnection) {
+ JarURLConnection juc = (JarURLConnection) conn;
+ JarFile jf = juc.getJarFile();
+ jf.close();
+ jf = null;
+ } else if (conn instanceof HttpURLConnection) {
+ ((HttpURLConnection) conn).disconnect();
+ }
+ } catch (IOException exc) {
+ //ignore
+ }
+ }
+ }
+
+ /**
+ * Delete the file with {@link File#delete()} if the argument is not null.
+ * Do nothing on a null argument.
+ * @param file file to delete.
+ */
+ public static void delete(File file) {
+ if (file != null) {
+ file.delete();
+ }
+ }
+
+ /**
+ * Accommodate Windows bug encountered in both Sun and IBM JDKs.
+ * Others possible. If the delete does not work, call System.gc(),
+ * wait a little and try again.
+ *
+ * @return whether deletion was successful
+ * @since Ant 1.8.0
+ */
+ public boolean tryHardToDelete(File f) {
+ return tryHardToDelete(f, ON_WINDOWS);
+ }
+
+ /**
+ * If delete does not work, call System.gc() if asked to, wait a
+ * little and try again.
+ *
+ * @return whether deletion was successful
+ * @since Ant 1.8.3
+ */
+ public boolean tryHardToDelete(File f, boolean runGC) {
+ if (!f.delete()) {
+ if (runGC) {
+ System.gc();
+ }
+ try {
+ Thread.sleep(DELETE_RETRY_SLEEP_MILLIS);
+ } catch (InterruptedException ex) {
+ // Ignore Exception
+ }
+ return f.delete();
+ }
+ return true;
+ }
+
+ /**
+ * Calculates the relative path between two files.
+ * <p>
+ * Implementation note:<br>This function may throw an IOException if an I/O error occurs
+ * because its use of the canonical pathname may require filesystem queries.
+ * </p>
+ *
+ * @param fromFile the <code>File</code> to calculate the path from
+ * @param toFile the <code>File</code> to calculate the path to
+ * @return the relative path between the files
+ * @throws Exception for undocumented reasons
+ * @see File#getCanonicalPath()
+ *
+ * @since Ant 1.7
+ */
+ public static String getRelativePath(File fromFile, File toFile) throws Exception {
+ String fromPath = fromFile.getCanonicalPath();
+ String toPath = toFile.getCanonicalPath();
+
+ // build the path stack info to compare
+ String[] fromPathStack = getPathStack(fromPath);
+ String[] toPathStack = getPathStack(toPath);
+
+ if (0 < toPathStack.length && 0 < fromPathStack.length) {
+ if (!fromPathStack[0].equals(toPathStack[0])) {
+ // not the same device (would be "" on Linux/Unix)
+
+ return getPath(Arrays.asList(toPathStack));
+ }
+ } else {
+ // no comparison possible
+ return getPath(Arrays.asList(toPathStack));
+ }
+
+ int minLength = Math.min(fromPathStack.length, toPathStack.length);
+ int same = 1; // Used outside the for loop
+
+ // get index of parts which are equal
+ for (;
+ same < minLength && fromPathStack[same].equals(toPathStack[same]);
+ same++) {
+ // Do nothing
+ }
+
+ List relativePathStack = new ArrayList();
+
+ // if "from" part is longer, fill it up with ".."
+ // to reach path which is equal to both paths
+ for (int i = same; i < fromPathStack.length; i++) {
+ relativePathStack.add("..");
+ }
+
+ // fill it up path with parts which were not equal
+ for (int i = same; i < toPathStack.length; i++) {
+ relativePathStack.add(toPathStack[i]);
+ }
+
+ return getPath(relativePathStack);
+ }
+
+ /**
+ * Gets all names of the path as an array of <code>String</code>s.
+ *
+ * @param path to get names from
+ * @return <code>String</code>s, never <code>null</code>
+ *
+ * @since Ant 1.7
+ */
+ public static String[] getPathStack(String path) {
+ String normalizedPath = path.replace(File.separatorChar, '/');
+
+ return normalizedPath.split("/");
+ }
+
+ /**
+ * Gets path from a <code>List</code> of <code>String</code>s.
+ *
+ * @param pathStack <code>List</code> of <code>String</code>s to be concatenated as a path.
+ * @return <code>String</code>, never <code>null</code>
+ *
+ * @since Ant 1.7
+ */
+ public static String getPath(List pathStack) {
+ // can safely use '/' because Windows understands '/' as separator
+ return getPath(pathStack, '/');
+ }
+
+ /**
+ * Gets path from a <code>List</code> of <code>String</code>s.
+ *
+ * @param pathStack <code>List</code> of <code>String</code>s to be concated as a path.
+ * @param separatorChar <code>char</code> to be used as separator between names in path
+ * @return <code>String</code>, never <code>null</code>
+ *
+ * @since Ant 1.7
+ */
+ public static String getPath(final List pathStack, final char separatorChar) {
+ final StringBuffer buffer = new StringBuffer();
+
+ final Iterator iter = pathStack.iterator();
+ if (iter.hasNext()) {
+ buffer.append(iter.next());
+ }
+ while (iter.hasNext()) {
+ buffer.append(separatorChar);
+ buffer.append(iter.next());
+ }
+ return buffer.toString();
+ }
+
+ /**
+ * Get the default encoding.
+ * This is done by opening an InputStreamReader on
+ * a dummy InputStream and getting the encoding.
+ * Could use System.getProperty("file.encoding"), but cannot
+ * see where this is documented.
+ * @return the default file encoding.
+ */
+ public String getDefaultEncoding() {
+ InputStreamReader is = new InputStreamReader(
+ new InputStream() {
+ public int read() {
+ return -1;
+ }
+ });
+ try {
+ return is.getEncoding();
+ } finally {
+ close(is);
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/FirstMatchMapper.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/FirstMatchMapper.java
new file mode 100644
index 00000000..b0e47f29
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/FirstMatchMapper.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.util;
+
+import java.util.Iterator;
+
+/**
+ * A <code>ContainerMapper</code> that returns the results of its
+ * first constituent <code>FileNameMapper</code>s that matches.
+ *
+ * @since Ant 1.8.0
+ */
+public class FirstMatchMapper extends ContainerMapper {
+
+ /** {@inheritDoc}. */
+ public String[] mapFileName(String sourceFileName) {
+ for (Iterator iter = getMappers().iterator(); iter.hasNext();) {
+ FileNameMapper mapper = (FileNameMapper) iter.next();
+ if (mapper != null) {
+ String[] mapped = mapper.mapFileName(sourceFileName);
+ if (mapped != null) {
+ return mapped;
+ }
+ }
+ }
+ return null;
+ }
+
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/FlatFileNameMapper.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/FlatFileNameMapper.java
new file mode 100644
index 00000000..420ccc6c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/FlatFileNameMapper.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.util;
+
+/**
+ * Implementation of FileNameMapper that always returns the source
+ * file name without any leading directory information.
+ *
+ * <p>This is the default FileNameMapper for the copy and move
+ * tasks if the flatten attribute has been set.</p>
+ *
+ */
+public class FlatFileNameMapper implements FileNameMapper {
+
+ /**
+ * Ignored.
+ * @param from ignored.
+ */
+ public void setFrom(String from) {
+ }
+
+ /**
+ * Ignored.
+ * @param to ignored.
+ */
+ public void setTo(String to) {
+ }
+
+ /**
+ * Returns an one-element array containing the source file name
+ * without any leading directory information.
+ * @param sourceFileName the name to map.
+ * @return the file name in a one-element array.
+ */
+ public String[] mapFileName(String sourceFileName) {
+ return new String[] {new java.io.File(sourceFileName).getName()};
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/GlobPatternMapper.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/GlobPatternMapper.java
new file mode 100644
index 00000000..da2a0f16
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/GlobPatternMapper.java
@@ -0,0 +1,203 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.util;
+
+import org.apache.tools.ant.BuildException;
+
+/**
+ * Implementation of FileNameMapper that does simple wildcard pattern
+ * replacements.
+ *
+ * <p>This does simple translations like *.foo -&gt; *.bar where the
+ * prefix to .foo will be left unchanged. It only handles a single *
+ * character, use regular expressions for more complicated
+ * situations.</p>
+ *
+ * <p>This is one of the more useful Mappers, it is used by javac for
+ * example.</p>
+ *
+ */
+public class GlobPatternMapper implements FileNameMapper {
+
+ // CheckStyle:VisibilityModifier OFF - bc
+ /**
+ * Part of &quot;from&quot; pattern before the *.
+ */
+ protected String fromPrefix = null;
+
+ /**
+ * Part of &quot;from&quot; pattern after the *.
+ */
+ protected String fromPostfix = null;
+
+ /**
+ * Length of the prefix (&quot;from&quot; pattern).
+ */
+ protected int prefixLength;
+
+ /**
+ * Length of the postfix (&quot;from&quot; pattern).
+ */
+ protected int postfixLength;
+
+ /**
+ * Part of &quot;to&quot; pattern before the *.
+ */
+ protected String toPrefix = null;
+
+ /**
+ * Part of &quot;to&quot; pattern after the *.
+ */
+ protected String toPostfix = null;
+
+ // CheckStyle:VisibilityModifier ON
+
+ private boolean fromContainsStar = false;
+ private boolean toContainsStar = false;
+ private boolean handleDirSep = false;
+ private boolean caseSensitive = true;
+
+ /**
+ * Attribute specifying whether to ignore the difference
+ * between / and \ (the two common directory characters).
+ * @param handleDirSep a boolean, default is false.
+ * @since Ant 1.6.3
+ */
+ public void setHandleDirSep(boolean handleDirSep) {
+ this.handleDirSep = handleDirSep;
+ }
+
+ /**
+ * Attribute specifying whether to ignore the difference
+ * between / and \ (the two common directory characters).
+ * @since Ant 1.8.3
+ */
+ public boolean getHandleDirSep() {
+ return handleDirSep;
+ }
+
+ /**
+ * Attribute specifying whether to ignore the case difference
+ * in the names.
+ *
+ * @param caseSensitive a boolean, default is false.
+ * @since Ant 1.6.3
+ */
+ public void setCaseSensitive(boolean caseSensitive) {
+ this.caseSensitive = caseSensitive;
+ }
+
+ /**
+ * Sets the &quot;from&quot; pattern. Required.
+ * @param from a string
+ */
+ public void setFrom(String from) {
+ if (from != null) {
+ int index = from.lastIndexOf("*");
+ if (index == -1) {
+ fromPrefix = from;
+ fromPostfix = "";
+ } else {
+ fromPrefix = from.substring(0, index);
+ fromPostfix = from.substring(index + 1);
+ fromContainsStar = true;
+ }
+ prefixLength = fromPrefix.length();
+ postfixLength = fromPostfix.length();
+ } else {
+ throw new BuildException("this mapper requires a 'from' attribute");
+ }
+ }
+
+ /**
+ * Sets the &quot;to&quot; pattern. Required.
+ * @param to a string
+ */
+ public void setTo(String to) {
+ if (to != null) {
+ int index = to.lastIndexOf("*");
+ if (index == -1) {
+ toPrefix = to;
+ toPostfix = "";
+ } else {
+ toPrefix = to.substring(0, index);
+ toPostfix = to.substring(index + 1);
+ toContainsStar = true;
+ }
+ } else {
+ throw new BuildException("this mapper requires a 'to' attribute");
+ }
+ }
+
+ /**
+ * Returns null if the source file name doesn't match the
+ * &quot;from&quot; pattern, an one-element array containing the
+ * translated file otherwise.
+ * @param sourceFileName the filename to map
+ * @return a list of converted filenames
+ */
+ public String[] mapFileName(String sourceFileName) {
+ String modName = modifyName(sourceFileName);
+ if (fromPrefix == null
+ || (sourceFileName.length() < (prefixLength + postfixLength))
+ || (!fromContainsStar
+ && !modName.equals(modifyName(fromPrefix))
+ )
+ || (fromContainsStar
+ && (!modName.startsWith(modifyName(fromPrefix))
+ || !modName.endsWith(modifyName(fromPostfix)))
+ )
+ ) {
+ return null;
+ }
+ return new String[] {toPrefix
+ + (toContainsStar
+ ? extractVariablePart(sourceFileName)
+ + toPostfix
+ : "")};
+ }
+
+ /**
+ * Returns the part of the given string that matches the * in the
+ * &quot;from&quot; pattern.
+ * @param name the source file name
+ * @return the variable part of the name
+ */
+ protected String extractVariablePart(String name) {
+ return name.substring(prefixLength,
+ name.length() - postfixLength);
+ }
+
+ /**
+ * modify string based on dir char mapping and case sensitivity
+ * @param name the name to convert
+ * @return the converted name
+ */
+ private String modifyName(String name) {
+ if (!caseSensitive) {
+ name = name.toLowerCase();
+ }
+ if (handleDirSep) {
+ if (name.indexOf('\\') != -1) {
+ name = name.replace('\\', '/');
+ }
+ }
+ return name;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/IdentityMapper.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/IdentityMapper.java
new file mode 100644
index 00000000..22c6c7ea
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/IdentityMapper.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.util;
+
+/**
+ * Implementation of FileNameMapper that always returns the source file name.
+ *
+ * <p>This is the default FileNameMapper for the copy and move
+ * tasks.</p>
+ *
+ */
+public class IdentityMapper implements FileNameMapper {
+
+ /**
+ * Ignored.
+ * @param from ignored.
+ */
+ public void setFrom(String from) {
+ }
+
+ /**
+ * Ignored.
+ * @param to ignored.
+ */
+ public void setTo(String to) {
+ }
+
+ /**
+ * Returns an one-element array containing the source file name.
+ * @param sourceFileName the name to map.
+ * @return the source filename in a one-element array.
+ */
+ public String[] mapFileName(String sourceFileName) {
+ return new String[] {sourceFileName};
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/IdentityStack.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/IdentityStack.java
new file mode 100644
index 00000000..ac806d78
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/IdentityStack.java
@@ -0,0 +1,130 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.util;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.IdentityHashMap;
+import java.util.Set;
+import java.util.Stack;
+
+/**
+ * Identity Stack.
+ * @since Ant 1.7
+ */
+public class IdentityStack<E> extends Stack<E> {
+
+ private static final long serialVersionUID = -5555522620060077046L;
+
+ /**
+ * Get an IdentityStack containing the contents of the specified Stack.
+ * @param s the Stack to copy; ignored if null.
+ * @return an IdentityStack instance.
+ */
+ public static <E> IdentityStack<E> getInstance(Stack<E> s) {
+ if (s instanceof IdentityStack) {
+ return (IdentityStack<E>) s;
+ }
+ IdentityStack<E> result = new IdentityStack<E>();
+ if (s != null) {
+ result.addAll(s);
+ }
+ return result;
+ }
+
+ /**
+ * Default constructor.
+ */
+ public IdentityStack() {
+ }
+
+ /**
+ * Construct a new IdentityStack with the specified Object
+ * as the bottom element.
+ * @param o the bottom element.
+ */
+ public IdentityStack(E o) {
+ super();
+ push(o);
+ }
+
+ /**
+ * Override methods that use <code>.equals()</code> comparisons on elements.
+ * @param o the Object to search for.
+ * @return true if the stack contains the object.
+ * @see java.util.Vector#contains(Object)
+ */
+ public synchronized boolean contains(Object o) {
+ return indexOf(o) >= 0;
+ }
+
+ /**
+ * Override methods that use <code>.equals()</code> comparisons on elements.
+ * @param o the Object to search for.
+ * @param pos the position from which to search.
+ * @return the position of the object, -1 if not found.
+ * @see java.util.Vector#indexOf(Object, int)
+ */
+ public synchronized int indexOf(Object o, int pos) {
+ final int size = size();
+ for (int i = pos; i < size; i++) {
+ if (get(i) == o) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * Override methods that use <code>.equals()</code> comparisons on elements.
+ * @param o the Object to search for.
+ * @param pos the position from which to search (backward).
+ * @return the position of the object, -1 if not found.
+ * @see java.util.Vector#indexOf(Object, int)
+ */
+ public synchronized int lastIndexOf(Object o, int pos) {
+ for (int i = pos; i >= 0; i--) {
+ if (get(i) == o) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ public synchronized boolean removeAll(Collection<?> c) {
+ if (!(c instanceof Set)) {
+ c = new HashSet(c);
+ }
+ return super.removeAll(c);
+ }
+
+ public synchronized boolean retainAll(Collection c) {
+ if (!(c instanceof Set)) {
+ c = new HashSet(c);
+ }
+ return super.retainAll(c);
+ }
+
+ public synchronized boolean containsAll(Collection<?> c) {
+ IdentityHashMap map = new IdentityHashMap();
+ for (Object e : this) {
+ map.put(e, Boolean.TRUE);
+ }
+ return map.keySet().containsAll(c);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/JAXPUtils.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/JAXPUtils.java
new file mode 100644
index 00000000..76460ae2
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/JAXPUtils.java
@@ -0,0 +1,260 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.util;
+
+import java.io.File;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.FactoryConfigurationError;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+import org.apache.tools.ant.BuildException;
+import org.xml.sax.Parser;
+import org.xml.sax.SAXException;
+import org.xml.sax.XMLReader;
+
+// CheckStyle:HideUtilityClassConstructorCheck OFF - bc
+
+/**
+ * Collection of helper methods that retrieve a ParserFactory or
+ * Parsers and Readers.
+ *
+ * <p>This class will create only a single factory instance.</p>
+ *
+ * @since Ant 1.5
+ */
+public class JAXPUtils {
+
+ /**
+ * Helper for systemId.
+ *
+ * @since Ant 1.6
+ */
+ private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+
+ /**
+ * Parser factory to use to create parsers.
+ * @see #getParserFactory
+ *
+ * @since Ant 1.5
+ */
+ private static SAXParserFactory parserFactory = null;
+
+ /**
+ * Parser Factory to create Namespace aware parsers.
+ *
+ * @since Ant 1.6
+ */
+ private static SAXParserFactory nsParserFactory = null;
+
+ /**
+ * Parser factory to use to create document builders.
+ *
+ * @since Ant 1.6
+ */
+ private static DocumentBuilderFactory builderFactory = null;
+
+ /**
+ * Returns the parser factory to use. Only one parser factory is
+ * ever created by this method and is then cached for future use.
+ *
+ * @return a SAXParserFactory to use.
+ * @throws BuildException on error.
+ *
+ * @since Ant 1.5
+ */
+ public static synchronized SAXParserFactory getParserFactory()
+ throws BuildException {
+
+ if (parserFactory == null) {
+ parserFactory = newParserFactory();
+ }
+ return parserFactory;
+ }
+
+ /**
+ * Returns the parser factory to use to create namespace aware parsers.
+ *
+ * @return a SAXParserFactory to use which supports manufacture of
+ * namespace aware parsers.
+ * @throws BuildException on error.
+ *
+ * @since Ant 1.6
+ */
+ public static synchronized SAXParserFactory getNSParserFactory()
+ throws BuildException {
+
+ if (nsParserFactory == null) {
+ nsParserFactory = newParserFactory();
+ nsParserFactory.setNamespaceAware(true);
+ }
+ return nsParserFactory;
+ }
+
+ /**
+ * Returns a new parser factory instance.
+ *
+ * @return the parser factory.
+ * @throws BuildException on error.
+ * @since Ant 1.5
+ */
+ public static SAXParserFactory newParserFactory() throws BuildException {
+
+ try {
+ return SAXParserFactory.newInstance();
+ } catch (FactoryConfigurationError e) {
+ throw new BuildException("XML parser factory has not been "
+ + "configured correctly: "
+ + e.getMessage(), e);
+ }
+ }
+
+ /**
+ * Returns a newly created SAX 1 Parser, using the default parser
+ * factory.
+ *
+ * @return a SAX 1 Parser.
+ * @throws BuildException on error.
+ * @see #getParserFactory
+ * @since Ant 1.5
+ */
+ public static Parser getParser() throws BuildException {
+ try {
+ return newSAXParser(getParserFactory()).getParser();
+ } catch (SAXException e) {
+ throw convertToBuildException(e);
+ }
+ }
+
+ /**
+ * Returns a newly created SAX 2 XMLReader, using the default parser
+ * factory.
+ *
+ * @return a SAX 2 XMLReader.
+ * @throws BuildException on error.
+ * @see #getParserFactory
+ * @since Ant 1.5
+ */
+ public static XMLReader getXMLReader() throws BuildException {
+ try {
+ return newSAXParser(getParserFactory()).getXMLReader();
+ } catch (SAXException e) {
+ throw convertToBuildException(e);
+ }
+ }
+
+ /**
+ * Returns a newly created SAX 2 XMLReader, which is namespace aware
+ *
+ * @return a SAX 2 XMLReader.
+ * @throws BuildException on error.
+ * @see #getParserFactory
+ * @since Ant 1.6
+ */
+ public static XMLReader getNamespaceXMLReader() throws BuildException {
+ try {
+ return newSAXParser(getNSParserFactory()).getXMLReader();
+ } catch (SAXException e) {
+ throw convertToBuildException(e);
+ }
+ }
+
+ /**
+ * This is a best attempt to provide a URL.toExternalForm() from
+ * a file URL. Some parsers like Crimson choke on uri that are made of
+ * backslashed paths (ie windows) as it is does not conform
+ * URI specifications.
+ * @param file the file to create the system id from.
+ * @return the systemid corresponding to the given file.
+ * @since Ant 1.5.2
+ */
+ public static String getSystemId(File file) {
+ return FILE_UTILS.toURI(file.getAbsolutePath());
+ }
+
+ /**
+ * Returns a newly created DocumentBuilder.
+ *
+ * @return a DocumentBuilder.
+ * @throws BuildException on error.
+ * @since Ant 1.6
+ */
+ public static DocumentBuilder getDocumentBuilder() throws BuildException {
+ try {
+ return getDocumentBuilderFactory().newDocumentBuilder();
+ } catch (ParserConfigurationException e) {
+ throw new BuildException(e);
+ }
+ }
+
+ /**
+ * @return a new SAXParser instance as helper for getParser and
+ * getXMLReader.
+ *
+ * @since Ant 1.5
+ */
+ private static SAXParser newSAXParser(SAXParserFactory factory)
+ throws BuildException {
+ try {
+ return factory.newSAXParser();
+ } catch (ParserConfigurationException e) {
+ throw new BuildException("Cannot create parser for the given "
+ + "configuration: " + e.getMessage(), e);
+ } catch (SAXException e) {
+ throw convertToBuildException(e);
+ }
+ }
+
+ /**
+ * Translate a SAXException into a BuildException
+ *
+ * @since Ant 1.5
+ */
+ private static BuildException convertToBuildException(SAXException e) {
+ Exception nested = e.getException();
+ if (nested != null) {
+ return new BuildException(nested);
+ } else {
+ return new BuildException(e);
+ }
+ }
+
+ /**
+ * Obtains the default builder factory if not already.
+ *
+ * @since Ant 1.6
+ */
+ private static synchronized
+ DocumentBuilderFactory getDocumentBuilderFactory()
+ throws BuildException {
+ if (builderFactory == null) {
+ try {
+ builderFactory = DocumentBuilderFactory.newInstance();
+ } catch (FactoryConfigurationError e) {
+ throw new BuildException("Document builder factory has not "
+ + "been configured correctly: "
+ + e.getMessage(), e);
+ }
+ }
+ return builderFactory;
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/JavaEnvUtils.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/JavaEnvUtils.java
new file mode 100644
index 00000000..df778208
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/JavaEnvUtils.java
@@ -0,0 +1,573 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.util;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.Vector;
+
+import org.apache.tools.ant.taskdefs.condition.Os;
+
+/**
+ * A set of helper methods related to locating executables or checking
+ * conditions of a given Java installation.
+ *
+ * @since Ant 1.5
+ */
+public final class JavaEnvUtils {
+
+ private JavaEnvUtils() {
+ }
+
+ /** Are we on a DOS-based system */
+ private static final boolean IS_DOS = Os.isFamily("dos");
+ /** Are we on Novell NetWare */
+ private static final boolean IS_NETWARE = Os.isName("netware");
+ /** Are we on AIX */
+ private static final boolean IS_AIX = Os.isName("aix");
+
+ /** shortcut for System.getProperty("java.home") */
+ private static final String JAVA_HOME = System.getProperty("java.home");
+
+ /** FileUtils instance for path normalization */
+ private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+
+ /** Version of currently running VM. */
+ private static String javaVersion;
+
+ /** floating version of the JVM */
+ private static int javaVersionNumber;
+
+ /** Version constant for Java 1.0 */
+ public static final String JAVA_1_0 = "1.0";
+ /** Number Version constant for Java 1.0 */
+ public static final int VERSION_1_0 = 10;
+
+ /** Version constant for Java 1.1 */
+ public static final String JAVA_1_1 = "1.1";
+ /** Number Version constant for Java 1.1 */
+ public static final int VERSION_1_1 = 11;
+
+ /** Version constant for Java 1.2 */
+ public static final String JAVA_1_2 = "1.2";
+ /** Number Version constant for Java 1.2 */
+ public static final int VERSION_1_2 = 12;
+
+ /** Version constant for Java 1.3 */
+ public static final String JAVA_1_3 = "1.3";
+ /** Number Version constant for Java 1.3 */
+ public static final int VERSION_1_3 = 13;
+
+ /** Version constant for Java 1.4 */
+ public static final String JAVA_1_4 = "1.4";
+ /** Number Version constant for Java 1.4 */
+ public static final int VERSION_1_4 = 14;
+
+ /** Version constant for Java 1.5 */
+ public static final String JAVA_1_5 = "1.5";
+ /** Number Version constant for Java 1.5 */
+ public static final int VERSION_1_5 = 15;
+
+ /** Version constant for Java 1.6 */
+ public static final String JAVA_1_6 = "1.6";
+ /** Number Version constant for Java 1.6 */
+ public static final int VERSION_1_6 = 16;
+
+ /** Version constant for Java 1.7 */
+ public static final String JAVA_1_7 = "1.7";
+ /** Number Version constant for Java 1.7 */
+ public static final int VERSION_1_7 = 17;
+
+ /** Version constant for Java 1.8 */
+ public static final String JAVA_1_8 = "1.8";
+ /** Number Version constant for Java 1.8 */
+ public static final int VERSION_1_8 = 18;
+
+ /** Version constant for Java 1.9 */
+ public static final String JAVA_1_9 = "1.9";
+ /** Number Version constant for Java 1.9 */
+ public static final int VERSION_1_9 = 19;
+
+ /** Whether this is the Kaffe VM */
+ private static boolean kaffeDetected;
+
+ /** Wheter this is a GNU Classpath based VM */
+ private static boolean classpathDetected;
+
+ /** Whether this is the GNU VM (gcj/gij) */
+ private static boolean gijDetected;
+
+ /** Whether this is Apache Harmony */
+ private static boolean harmonyDetected;
+
+ /** array of packages in the runtime */
+ private static Vector<String> jrePackages;
+
+
+ static {
+
+ // Determine the Java version by looking at available classes
+ // java.net.Proxy was introduced in JDK 1.5
+ // java.lang.CharSequence was introduced in JDK 1.4
+ // java.lang.StrictMath was introduced in JDK 1.3
+ // java.lang.ThreadLocal was introduced in JDK 1.2
+ // java.lang.Void was introduced in JDK 1.1
+ // Count up version until a NoClassDefFoundError ends the try
+
+ try {
+ javaVersion = JAVA_1_0;
+ javaVersionNumber = VERSION_1_0;
+ Class.forName("java.lang.Void");
+ javaVersion = JAVA_1_1;
+ javaVersionNumber++;
+ Class.forName("java.lang.ThreadLocal");
+ javaVersion = JAVA_1_2;
+ javaVersionNumber++;
+ Class.forName("java.lang.StrictMath");
+ javaVersion = JAVA_1_3;
+ javaVersionNumber++;
+ Class.forName("java.lang.CharSequence");
+ javaVersion = JAVA_1_4;
+ javaVersionNumber++;
+ Class.forName("java.net.Proxy");
+ javaVersion = JAVA_1_5;
+ javaVersionNumber++;
+ Class.forName("java.net.CookieStore");
+ javaVersion = JAVA_1_6;
+ javaVersionNumber++;
+ Class.forName("java.nio.file.FileSystem");
+ javaVersion = JAVA_1_7;
+ javaVersionNumber++;
+ Class.forName("java.lang.reflect.Executable");
+ javaVersion = JAVA_1_8;
+ javaVersionNumber++;
+ checkForJava9();
+ javaVersion = JAVA_1_9;
+ javaVersionNumber++;
+ } catch (Throwable t) {
+ // swallow as we've hit the max class version that
+ // we have
+ }
+ kaffeDetected = false;
+ try {
+ Class.forName("kaffe.util.NotImplemented");
+ kaffeDetected = true;
+ } catch (Throwable t) {
+ // swallow as this simply doesn't seem to be Kaffe
+ }
+ classpathDetected = false;
+ try {
+ Class.forName("gnu.classpath.Configuration");
+ classpathDetected = true;
+ } catch (Throwable t) {
+ // swallow as this simply doesn't seem to be GNU classpath based.
+ }
+ gijDetected = false;
+ try {
+ Class.forName("gnu.gcj.Core");
+ gijDetected = true;
+ } catch (Throwable t) {
+ // swallow as this simply doesn't seem to be gcj/gij
+ }
+ harmonyDetected = false;
+ try {
+ Class.forName("org.apache.harmony.luni.util.Base64");
+ harmonyDetected = true;
+ } catch (Throwable t) {
+ // swallow as this simply doesn't seem to be Apache Harmony
+ }
+ }
+
+ /**
+ * Returns the version of Java this class is running under.
+ * @return the version of Java as a String, e.g. "1.6"
+ */
+ public static String getJavaVersion() {
+ return javaVersion;
+ }
+
+
+ /**
+ * Checks for a give Java 9 runtime.
+ * At the time of writing the actual version of the JDK was 1.9.0_b06.
+ * Searching for new classes gave no hits, so we need another aproach.
+ * Searching for changes (grep -r -i -n "@since 1.9" .) in the sources gave
+ * only one hit: a new constant in the class SourceVersion.
+ * So we have to check that ...
+ *
+ * @throws Exception if we can't load the class or don't find the new constant.
+ * This is the behavior when searching for new features on older versions.
+ * @since Ant 1.9.4
+ */
+ private static void checkForJava9() throws Exception {
+ Class<?> clazz = Class.forName("javax.lang.model.SourceVersion");
+ clazz.getDeclaredField("RELEASE_9");
+ }
+
+
+ /**
+ * Returns the version of Java this class is running under.
+ * This number can be used for comparisons; it will always be
+ * @return the version of Java as a number 10x the major/minor,
+ * e.g Java1.5 has a value of 15
+ */
+ public static int getJavaVersionNumber() {
+ return javaVersionNumber;
+ }
+
+ /**
+ * Compares the current Java version to the passed in String -
+ * assumes the argument is one of the constants defined in this
+ * class.
+ * Note that Ant now requires JDK 1.5+ so {@link #JAVA_1_0} through
+ * {@link #JAVA_1_4} need no longer be tested for.
+ * @param version the version to check against the current version.
+ * @return true if the version of Java is the same as the given version.
+ * @since Ant 1.5
+ */
+ public static boolean isJavaVersion(String version) {
+ return javaVersion.equals(version);
+ }
+
+ /**
+ * Compares the current Java version to the passed in String -
+ * assumes the argument is one of the constants defined in this
+ * class.
+ * Note that Ant now requires JDK 1.5+ so {@link #JAVA_1_0} through
+ * {@link #JAVA_1_4} need no longer be tested for.
+ * @param version the version to check against the current version.
+ * @return true if the version of Java is the same or higher than the
+ * given version.
+ * @since Ant 1.7
+ */
+ public static boolean isAtLeastJavaVersion(String version) {
+ return javaVersion.compareTo(version) >= 0;
+ }
+
+ /**
+ * Checks whether the current Java VM is Kaffe.
+ * @return true if the current Java VM is Kaffe.
+ * @since Ant 1.6.3
+ * @see <a href="http://www.kaffe.org/">http://www.kaffe.org/</a>
+ */
+ public static boolean isKaffe() {
+ return kaffeDetected;
+ }
+
+ /**
+ * Checks whether the current Java VM is GNU Classpath
+ * @since Ant 1.9.1
+ * @return true if the version of Java is GNU Classpath
+ */
+ public static boolean isClasspathBased() {
+ return classpathDetected;
+ }
+
+ /**
+ * Checks whether the current Java VM is the GNU interpreter gij
+ * or we are running in a gcj precompiled binary.
+ * @since Ant 1.8.2
+ * @return true if the current Java VM is gcj/gij.
+ */
+ public static boolean isGij() {
+ return gijDetected;
+ }
+
+ /**
+ * Checks whether the current VM is Apache Harmony.
+ * @since Ant 1.8.2
+ * @return true if the current VM is Apache Harmony.
+ */
+ public static boolean isApacheHarmony() {
+ return harmonyDetected;
+ }
+
+ /**
+ * Finds an executable that is part of a JRE installation based on
+ * the java.home system property.
+ *
+ * <p><code>java</code>, <code>keytool</code>,
+ * <code>policytool</code>, <code>orbd</code>, <code>rmid</code>,
+ * <code>rmiregistry</code>, <code>servertool</code> and
+ * <code>tnameserv</code> are JRE executables on Sun based
+ * JRE's.</p>
+ *
+ * <p>You typically find them in <code>JAVA_HOME/jre/bin</code> if
+ * <code>JAVA_HOME</code> points to your JDK installation. JDK
+ * &lt; 1.2 has them in the same directory as the JDK
+ * executables.</p>
+ * @param command the java executable to find.
+ * @return the path to the command.
+ * @since Ant 1.5
+ */
+ public static String getJreExecutable(String command) {
+ if (IS_NETWARE) {
+ // Extrapolating from:
+ // "NetWare may have a "java" in that directory, but 99% of
+ // the time, you don't want to execute it" -- Jeff Tulley
+ // <JTULLEY@novell.com>
+ return command;
+ }
+
+ File jExecutable = null;
+
+ if (IS_AIX) {
+ // On IBM's JDK 1.2 the directory layout is different, 1.3 follows
+ // Sun's layout.
+ jExecutable = findInDir(JAVA_HOME + "/sh", command);
+ }
+
+ if (jExecutable == null) {
+ jExecutable = findInDir(JAVA_HOME + "/bin", command);
+ }
+
+ if (jExecutable != null) {
+ return jExecutable.getAbsolutePath();
+ } else {
+ // Unfortunately on Windows java.home doesn't always refer
+ // to the correct location, so we need to fall back to
+ // assuming java is somewhere on the PATH.
+ return addExtension(command);
+ }
+ }
+
+ /**
+ * Finds an executable that is part of a JDK installation based on
+ * the java.home system property.
+ *
+ * <p>You typically find them in <code>JAVA_HOME/bin</code> if
+ * <code>JAVA_HOME</code> points to your JDK installation.</p>
+ * @param command the java executable to find.
+ * @return the path to the command.
+ * @since Ant 1.5
+ */
+ public static String getJdkExecutable(String command) {
+ if (IS_NETWARE) {
+ // Extrapolating from:
+ // "NetWare may have a "java" in that directory, but 99% of
+ // the time, you don't want to execute it" -- Jeff Tulley
+ // <JTULLEY@novell.com>
+ return command;
+ }
+
+ File jExecutable = null;
+
+ if (IS_AIX) {
+ // On IBM's JDK 1.2 the directory layout is different, 1.3 follows
+ // Sun's layout.
+ jExecutable = findInDir(JAVA_HOME + "/../sh", command);
+ }
+
+ if (jExecutable == null) {
+ jExecutable = findInDir(JAVA_HOME + "/../bin", command);
+ }
+
+ if (jExecutable != null) {
+ return jExecutable.getAbsolutePath();
+ } else {
+ // fall back to JRE bin directory, also catches JDK 1.0 and 1.1
+ // where java.home points to the root of the JDK and Mac OS X where
+ // the whole directory layout is different from Sun's
+ // and also catches JDK 1.9 (and probably later) which
+ // merged JDK and JRE dirs
+ return getJreExecutable(command);
+ }
+ }
+
+ /**
+ * Adds a system specific extension to the name of an executable.
+ *
+ * @since Ant 1.5
+ */
+ private static String addExtension(String command) {
+ // This is the most common extension case - exe for windows and OS/2,
+ // nothing for *nix.
+ return command + (IS_DOS ? ".exe" : "");
+ }
+
+ /**
+ * Look for an executable in a given directory.
+ *
+ * @return null if the executable cannot be found.
+ */
+ private static File findInDir(String dirName, String commandName) {
+ File dir = FILE_UTILS.normalize(dirName);
+ File executable = null;
+ if (dir.exists()) {
+ executable = new File(dir, addExtension(commandName));
+ if (!executable.exists()) {
+ executable = null;
+ }
+ }
+ return executable;
+ }
+
+ /**
+ * demand creation of the package list.
+ * When you add a new package, add a new test below.
+ */
+
+ private static void buildJrePackages() {
+ jrePackages = new Vector<String>();
+ switch(javaVersionNumber) {
+ case VERSION_1_9:
+ case VERSION_1_8:
+ case VERSION_1_7:
+ case VERSION_1_6:
+ case VERSION_1_5:
+ //In Java1.5, the apache stuff moved.
+ jrePackages.addElement("com.sun.org.apache");
+ //fall through.
+ case VERSION_1_4:
+ if (javaVersionNumber == VERSION_1_4) {
+ jrePackages.addElement("org.apache.crimson");
+ jrePackages.addElement("org.apache.xalan");
+ jrePackages.addElement("org.apache.xml");
+ jrePackages.addElement("org.apache.xpath");
+ }
+ jrePackages.addElement("org.ietf.jgss");
+ jrePackages.addElement("org.w3c.dom");
+ jrePackages.addElement("org.xml.sax");
+ // fall through
+ case VERSION_1_3:
+ jrePackages.addElement("org.omg");
+ jrePackages.addElement("com.sun.corba");
+ jrePackages.addElement("com.sun.jndi");
+ jrePackages.addElement("com.sun.media");
+ jrePackages.addElement("com.sun.naming");
+ jrePackages.addElement("com.sun.org.omg");
+ jrePackages.addElement("com.sun.rmi");
+ jrePackages.addElement("sunw.io");
+ jrePackages.addElement("sunw.util");
+ // fall through
+ case VERSION_1_2:
+ jrePackages.addElement("com.sun.java");
+ jrePackages.addElement("com.sun.image");
+ // are there any here that we forgot?
+ // fall through
+ case VERSION_1_1:
+ default:
+ //things like sun.reflection, sun.misc, sun.net
+ jrePackages.addElement("sun");
+ jrePackages.addElement("java");
+ jrePackages.addElement("javax");
+ break;
+ }
+ }
+
+ /**
+ * Testing helper method; kept here for unification of changes.
+ * @return a list of test classes depending on the java version.
+ */
+ public static Vector<String> getJrePackageTestCases() {
+ Vector<String> tests = new Vector<String>();
+ tests.addElement("java.lang.Object");
+ switch(javaVersionNumber) {
+ case VERSION_1_9:
+ case VERSION_1_8:
+ case VERSION_1_7:
+ case VERSION_1_6:
+ case VERSION_1_5:
+ tests.addElement(
+ "com.sun.org.apache.xerces.internal.jaxp.datatype.DatatypeFactoryImpl ");
+ // Fall through
+ case VERSION_1_4:
+ tests.addElement("sun.audio.AudioPlayer");
+ if (javaVersionNumber == VERSION_1_4) {
+ // only for 1.4, not for higher versions which fall through
+ tests.addElement("org.apache.crimson.parser.ContentModel");
+ tests.addElement("org.apache.xalan.processor.ProcessorImport");
+ tests.addElement("org.apache.xml.utils.URI");
+ tests.addElement("org.apache.xpath.XPathFactory");
+ }
+ tests.addElement("org.ietf.jgss.Oid");
+ tests.addElement("org.w3c.dom.Attr");
+ tests.addElement("org.xml.sax.XMLReader");
+ // fall through
+ case VERSION_1_3:
+ tests.addElement("org.omg.CORBA.Any");
+ tests.addElement("com.sun.corba.se.internal.corba.AnyImpl");
+ tests.addElement("com.sun.jndi.ldap.LdapURL");
+ tests.addElement("com.sun.media.sound.Printer");
+ tests.addElement("com.sun.naming.internal.VersionHelper");
+ tests.addElement("com.sun.org.omg.CORBA.Initializer");
+ tests.addElement("sunw.io.Serializable");
+ tests.addElement("sunw.util.EventListener");
+ // fall through
+ case VERSION_1_2:
+ tests.addElement("javax.accessibility.Accessible");
+ tests.addElement("sun.misc.BASE64Encoder");
+ tests.addElement("com.sun.image.codec.jpeg.JPEGCodec");
+ // fall through
+ case VERSION_1_1:
+ default:
+ //things like sun.reflection, sun.misc, sun.net
+ tests.addElement("sun.reflect.SerializationConstructorAccessorImpl");
+ tests.addElement("sun.net.www.http.HttpClient");
+ tests.addElement("sun.audio.AudioPlayer");
+ break;
+ }
+ return tests;
+ }
+ /**
+ * get a vector of strings of packages built into
+ * that platforms runtime jar(s)
+ * @return list of packages.
+ */
+ public static Vector<String> getJrePackages() {
+ if (jrePackages == null) {
+ buildJrePackages();
+ }
+ return jrePackages;
+ }
+
+ /**
+ *
+ * Writes the command into a temporary DCL script and returns the
+ * corresponding File object.
+ * It is the job of the caller to delete the file on exit.
+ * @param cmd the command.
+ * @return the file containing the command.
+ * @throws IOException if there is an error writing to the file.
+ */
+ public static File createVmsJavaOptionFile(String[] cmd)
+ throws IOException {
+ File script = FILE_UTILS.createTempFile("ANT", ".JAVA_OPTS", null, false, true);
+ BufferedWriter out = null;
+ try {
+ out = new BufferedWriter(new FileWriter(script));
+ for (int i = 0; i < cmd.length; i++) {
+ out.write(cmd[i]);
+ out.newLine();
+ }
+ } finally {
+ FileUtils.close(out);
+ }
+ return script;
+ }
+
+ /**
+ * Return the value of ${java.home}
+ * @return the java home value.
+ */
+ public static String getJavaHome() {
+ return JAVA_HOME;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/KeepAliveInputStream.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/KeepAliveInputStream.java
new file mode 100644
index 00000000..debde59a
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/KeepAliveInputStream.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.util;
+
+import java.io.FilterInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Class that can be used to wrap <tt>System.in</tt>
+ * without getting anxious about any client closing the stream.
+ *
+ * <p>
+ * In code-language it means that it is not necessary to do:
+ * <pre>
+ * if (out != System.in) {
+ * in.close();
+ * }
+ * </pre>
+ *
+ * @since Ant 1.6
+ */
+public class KeepAliveInputStream extends FilterInputStream {
+
+ /**
+ * Constructor of KeepAliveInputStream.
+ *
+ * @param in an InputStream value, it should be standard input.
+ */
+ public KeepAliveInputStream(InputStream in) {
+ super(in);
+ }
+
+ /**
+ * This method does nothing.
+ * @throws IOException as we are overriding FilterInputStream.
+ */
+ public void close() throws IOException {
+ // do not close the stream
+ }
+
+ /**
+ * Convenience factory method that returns a non-closing
+ * InputStream around System.in.
+ *
+ * @since Ant 1.8.0
+ */
+ public static InputStream wrapSystemIn() {
+ return new KeepAliveInputStream(System.in);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/KeepAliveOutputStream.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/KeepAliveOutputStream.java
new file mode 100644
index 00000000..27f3d7e4
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/KeepAliveOutputStream.java
@@ -0,0 +1,83 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.util;
+
+import java.io.FilterOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintStream;
+
+/**
+ * Class that can be used to wrap <tt>System.out</tt> and <tt>System.err</tt>
+ * without getting anxious about any client closing the stream.
+ *
+ * <p>
+ * In code-language it means that it is not necessary to do:
+ * <pre>
+ * if (out != System.out &amp;&amp; out != System.err) {
+ * out.close();
+ * }
+ * </pre>
+ *
+ */
+public class KeepAliveOutputStream extends FilterOutputStream {
+
+ /**
+ * Constructor of KeepAliveOutputStream.
+ *
+ * @param out an OutputStream value, it should be standard output.
+ */
+ public KeepAliveOutputStream(OutputStream out) {
+ super(out);
+ }
+
+ /**
+ * This method does nothing.
+ * @throws IOException as we are overriding FilterOutputStream.
+ */
+ public void close() throws IOException {
+ // do not close the stream
+ }
+
+ /**
+ * Convenience factory method that returns a non-closing
+ * PrintStream around System.out.
+ *
+ * @since Ant 1.8.0
+ */
+ public static PrintStream wrapSystemOut() {
+ return wrap(System.out);
+ }
+
+ /**
+ * Convenience factory method that returns a non-closing
+ * PrintStream around System.err.
+ *
+ * @since Ant 1.8.0
+ */
+ public static PrintStream wrapSystemErr() {
+ return wrap(System.err);
+ }
+
+ /**
+ * @since Ant 1.8.0
+ */
+ private static PrintStream wrap(PrintStream ps) {
+ return new PrintStream(new KeepAliveOutputStream(ps));
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/LayoutPreservingProperties.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/LayoutPreservingProperties.java
new file mode 100644
index 00000000..aed6f371
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/LayoutPreservingProperties.java
@@ -0,0 +1,775 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.util;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.PrintStream;
+import java.io.PushbackReader;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Properties;
+
+/**
+ * <p>A Properties collection which preserves comments and whitespace
+ * present in the input stream from which it was loaded.</p>
+ * <p>The class defers the usual work of the <a href="http://java.sun.com/j2se/1.3/docs/api/java/util/Properties.html">java.util.Properties</a>
+ * class to there, but it also keeps track of the contents of the
+ * input stream from which it was loaded (if applicable), so that it can
+ * write out the properties in as close a form as possible to the input.</p>
+ * <p>If no changes occur to property values, the output should be the same
+ * as the input, except for the leading date stamp, as normal for a
+ * properties file. Properties added are appended to the file. Properties
+ * whose values are changed are changed in place. Properties that are
+ * removed are excised. If the <code>removeComments</code> flag is set,
+ * then the comments immediately preceding the property are also removed.</p>
+ * <p>If a second set of properties is loaded into an existing set, the
+ * lines of the second set are added to the end. Note however, that if a
+ * property already stored is present in a stream subsequently loaded, then
+ * that property is removed before the new value is set. For example,
+ * consider the file</p>
+ * <pre> # the first line
+ * alpha=one
+ *
+ * # the second line
+ * beta=two</pre>
+ * <p>This file is loaded, and then the following is also loaded into the
+ * same <code>LayoutPreservingProperties</code> object</p>
+ * <pre> # association
+ * beta=band
+ *
+ * # and finally
+ * gamma=rays</pre>
+ * <p>The resulting collection sequence of logical lines depends on whether
+ * or not <code>removeComments</code> was set at the time the second stream
+ * is loaded. If it is set, then the resulting list of lines is</p>
+ * <pre> # the first line
+ * alpha=one
+ *
+ * # association
+ * beta=band
+ *
+ * # and finally
+ * gamma=rays</pre>
+ * <p>If the flag is not set, then the comment "the second line" is retained,
+ * although the key-value pair <code>beta=two</code> is removed.</p>
+ */
+public class LayoutPreservingProperties extends Properties {
+ private String LS = StringUtils.LINE_SEP;
+
+ /**
+ * Logical lines have escaping and line continuation taken care
+ * of. Comments and blank lines are logical lines; they are not
+ * removed.
+ */
+ private ArrayList logicalLines = new ArrayList();
+
+ /**
+ * Position in the <code>logicalLines</code> list, keyed by property name.
+ */
+ private HashMap keyedPairLines = new HashMap();
+
+ /**
+ * Flag to indicate that, when we remove a property from the file, we
+ * also want to remove the comments that precede it.
+ */
+ private boolean removeComments;
+
+ /**
+ * Create a new, empty, Properties collection, with no defaults.
+ */
+ public LayoutPreservingProperties() {
+ super();
+ }
+
+ /**
+ * Create a new, empty, Properties collection, with the specified defaults.
+ * @param defaults the default property values
+ */
+ public LayoutPreservingProperties(final Properties defaults) {
+ super(defaults);
+ }
+
+ /**
+ * Returns <code>true</code> if comments are removed along with
+ * properties, or <code>false</code> otherwise. If
+ * <code>true</code>, then when a property is removed, the comment
+ * preceding it in the original file is removed also.
+ * @return <code>true</code> if leading comments are removed when
+ * a property is removed; <code>false</code> otherwise
+ */
+ public boolean isRemoveComments() {
+ return removeComments;
+ }
+
+ /**
+ * Sets the behaviour for comments accompanying properties that
+ * are being removed. If <code>true</code>, then when a property
+ * is removed, the comment preceding it in the original file is
+ * removed also.
+ * @param val <code>true</code> if leading comments are to be
+ * removed when a property is removed; <code>false</code>
+ * otherwise
+ */
+ public void setRemoveComments(final boolean val) {
+ removeComments = val;
+ }
+
+ @Override
+ public void load(final InputStream inStream) throws IOException {
+ final String s = readLines(inStream);
+ final byte[] ba = s.getBytes(ResourceUtils.ISO_8859_1);
+ final ByteArrayInputStream bais = new ByteArrayInputStream(ba);
+ super.load(bais);
+ }
+
+ @Override
+ public Object put(final Object key, final Object value) throws NullPointerException {
+ final Object obj = super.put(key, value);
+ // the above call will have failed if key or value are null
+ innerSetProperty(key.toString(), value.toString());
+ return obj;
+ }
+
+ @Override
+ public Object setProperty(final String key, final String value)
+ throws NullPointerException {
+ final Object obj = super.setProperty(key, value);
+ // the above call will have failed if key or value are null
+ innerSetProperty(key, value);
+ return obj;
+ }
+
+ /**
+ * Store a new key-value pair, or add a new one. The normal
+ * functionality is taken care of by the superclass in the call to
+ * {@link #setProperty}; this method takes care of this classes
+ * extensions.
+ * @param key the key of the property to be stored
+ * @param value the value to be stored
+ */
+ private void innerSetProperty(String key, String value) {
+ value = escapeValue(value);
+
+ if (keyedPairLines.containsKey(key)) {
+ final Integer i = (Integer) keyedPairLines.get(key);
+ final Pair p = (Pair) logicalLines.get(i.intValue());
+ p.setValue(value);
+ } else {
+ key = escapeName(key);
+ final Pair p = new Pair(key, value);
+ p.setNew(true);
+ keyedPairLines.put(key, new Integer(logicalLines.size()));
+ logicalLines.add(p);
+ }
+ }
+
+ @Override
+ public void clear() {
+ super.clear();
+ keyedPairLines.clear();
+ logicalLines.clear();
+ }
+
+ @Override
+ public Object remove(final Object key) {
+ final Object obj = super.remove(key);
+ final Integer i = (Integer) keyedPairLines.remove(key);
+ if (null != i) {
+ if (removeComments) {
+ removeCommentsEndingAt(i.intValue());
+ }
+ logicalLines.set(i.intValue(), null);
+ }
+ return obj;
+ }
+
+ @Override
+ public Object clone() {
+ final LayoutPreservingProperties dolly =
+ (LayoutPreservingProperties) super.clone();
+ dolly.keyedPairLines = (HashMap) this.keyedPairLines.clone();
+ dolly.logicalLines = (ArrayList) this.logicalLines.clone();
+ final int size = dolly.logicalLines.size();
+ for (int j = 0; j < size; j++) {
+ final LogicalLine line = (LogicalLine) dolly.logicalLines.get(j);
+ if (line instanceof Pair) {
+ final Pair p = (Pair) line;
+ dolly.logicalLines.set(j, p.clone());
+ }
+ // no reason to clone other lines are they are immutable
+ }
+ return dolly;
+ }
+
+ /**
+ * Echo the lines of the properties (including blanks and comments) to the
+ * stream.
+ * @param out the stream to write to
+ */
+ public void listLines(final PrintStream out) {
+ out.println("-- logical lines --");
+ final Iterator i = logicalLines.iterator();
+ while (i.hasNext()) {
+ final LogicalLine line = (LogicalLine) i.next();
+ if (line instanceof Blank) {
+ out.println("blank: \"" + line + "\"");
+ } else if (line instanceof Comment) {
+ out.println("comment: \"" + line + "\"");
+ } else if (line instanceof Pair) {
+ out.println("pair: \"" + line + "\"");
+ }
+ }
+ }
+
+ /**
+ * Save the properties to a file.
+ * @param dest the file to write to
+ */
+ public void saveAs(final File dest) throws IOException {
+ final FileOutputStream fos = new FileOutputStream(dest);
+ store(fos, null);
+ fos.close();
+ }
+
+ @Override
+ public void store(final OutputStream out, final String header) throws IOException {
+ final OutputStreamWriter osw = new OutputStreamWriter(out, ResourceUtils.ISO_8859_1);
+
+ int skipLines = 0;
+ final int totalLines = logicalLines.size();
+
+ if (header != null) {
+ osw.write("#" + header + LS);
+ if (totalLines > 0
+ && logicalLines.get(0) instanceof Comment
+ && header.equals(logicalLines.get(0).toString().substring(1))) {
+ skipLines = 1;
+ }
+ }
+
+ // we may be updatiung a file written by this class, replace
+ // the date comment instead of adding a new one and preserving
+ // the one written last time
+ if (totalLines > skipLines
+ && logicalLines.get(skipLines) instanceof Comment) {
+ try {
+ DateUtils.parseDateFromHeader(logicalLines
+ .get(skipLines)
+ .toString().substring(1));
+ skipLines++;
+ } catch (final java.text.ParseException pe) {
+ // not an existing date comment
+ }
+ }
+ osw.write("#" + DateUtils.getDateForHeader() + LS);
+
+ boolean writtenSep = false;
+ for (final Iterator i = logicalLines.subList(skipLines, totalLines).iterator();
+ i.hasNext();) {
+ final LogicalLine line = (LogicalLine) i.next();
+ if (line instanceof Pair) {
+ if (((Pair)line).isNew()) {
+ if (!writtenSep) {
+ osw.write(LS);
+ writtenSep = true;
+ }
+ }
+ osw.write(line.toString() + LS);
+ } else if (line != null) {
+ osw.write(line.toString() + LS);
+ }
+ }
+ osw.close();
+ }
+
+ /**
+ * Reads a properties file into an internally maintained
+ * collection of logical lines (possibly spanning physcial lines),
+ * which make up the comments, blank lines and properties of the
+ * file.
+ * @param is the stream from which to read the data
+ */
+ private String readLines(final InputStream is) throws IOException {
+ final InputStreamReader isr = new InputStreamReader(is, ResourceUtils.ISO_8859_1);
+ final PushbackReader pbr = new PushbackReader(isr, 1);
+
+ if (logicalLines.size() > 0) {
+ // we add a blank line for spacing
+ logicalLines.add(new Blank());
+ }
+
+ String s = readFirstLine(pbr);
+ final BufferedReader br = new BufferedReader(pbr);
+
+ boolean continuation = false;
+ boolean comment = false;
+ final StringBuffer fileBuffer = new StringBuffer();
+ final StringBuffer logicalLineBuffer = new StringBuffer();
+ while (s != null) {
+ fileBuffer.append(s).append(LS);
+
+ if (continuation) {
+ // put in the line feed that was removed
+ s = "\n" + s;
+ } else {
+ // could be a comment, if first non-whitespace is a # or !
+ comment = s.matches("^( |\t|\f)*(#|!).*");
+ }
+
+ // continuation if not a comment and the line ends is an
+ // odd number of backslashes
+ if (!comment) {
+ continuation = requiresContinuation(s);
+ }
+
+ logicalLineBuffer.append(s);
+
+ if (!continuation) {
+ LogicalLine line = null;
+ if (comment) {
+ line = new Comment(logicalLineBuffer.toString());
+ } else if (logicalLineBuffer.toString().trim().length() == 0) {
+ line = new Blank();
+ } else {
+ line = new Pair(logicalLineBuffer.toString());
+ final String key = unescape(((Pair)line).getName());
+ if (keyedPairLines.containsKey(key)) {
+ // this key is already present, so we remove it and add
+ // the new one
+ remove(key);
+ }
+ keyedPairLines.put(key, new Integer(logicalLines.size()));
+ }
+ logicalLines.add(line);
+ logicalLineBuffer.setLength(0);
+ }
+ s = br.readLine();
+ }
+ return fileBuffer.toString();
+ }
+
+ /**
+ * Reads the first line and determines the EOL-style of the file
+ * (relies on the style to be consistent, of course).
+ *
+ * <p>Sets LS as a side-effect.</p>
+ *
+ * @return the first line without any line separator, leaves the
+ * reader positioned after the first line separator
+ *
+ * @since Ant 1.8.2
+ */
+ private String readFirstLine(final PushbackReader r) throws IOException {
+ final StringBuffer sb = new StringBuffer(80);
+ int ch = r.read();
+ boolean hasCR = false;
+ // when reaching EOF before the first EOL, assume native line
+ // feeds
+ LS = StringUtils.LINE_SEP;
+
+ while (ch >= 0) {
+ if (hasCR && ch != '\n') {
+ // line feed is sole CR
+ r.unread(ch);
+ break;
+ }
+
+ if (ch == '\r') {
+ LS = "\r";
+ hasCR = true;
+ } else if (ch == '\n') {
+ LS = hasCR ? "\r\n" : "\n";
+ break;
+ } else {
+ sb.append((char) ch);
+ }
+ ch = r.read();
+ }
+ return sb.toString();
+ }
+
+ /**
+ * Returns <code>true</code> if the line represented by
+ * <code>s</code> is to be continued on the next line of the file,
+ * or <code>false</code> otherwise.
+ * @param s the contents of the line to examine
+ * @return <code>true</code> if the line is to be continued,
+ * <code>false</code> otherwise
+ */
+ private boolean requiresContinuation(final String s) {
+ final char[] ca = s.toCharArray();
+ int i = ca.length - 1;
+ while (i > 0 && ca[i] == '\\') {
+ i--;
+ }
+ // trailing backslashes
+ final int tb = ca.length - i - 1;
+ return tb % 2 == 1;
+ }
+
+ /**
+ * Unescape the string according to the rules for a Properites
+ * file, as laid out in the docs for <a
+ * href="http://java.sun.com/j2se/1.3/docs/api/java/util/Properties.html">java.util.Properties</a>.
+ * @param s the string to unescape (coming from the source file)
+ * @return the unescaped string
+ */
+ private String unescape(final String s) {
+ /*
+ * The following combinations are converted:
+ * \n newline
+ * \r carraige return
+ * \f form feed
+ * \t tab
+ * \\ backslash
+ * \u0000 unicode character
+ * Any other slash is ignored, so
+ * \b becomes 'b'.
+ */
+
+ final char[] ch = new char[s.length() + 1];
+ s.getChars(0, s.length(), ch, 0);
+ ch[s.length()] = '\n';
+ final StringBuffer buffy = new StringBuffer(s.length());
+ for (int i = 0; i < ch.length; i++) {
+ char c = ch[i];
+ if (c == '\n') {
+ // we have hit out end-of-string marker
+ break;
+ } else if (c == '\\') {
+ // possibly an escape sequence
+ c = ch[++i];
+ if (c == 'n') {
+ buffy.append('\n');
+ } else if (c == 'r') {
+ buffy.append('\r');
+ } else if (c == 'f') {
+ buffy.append('\f');
+ } else if (c == 't') {
+ buffy.append('\t');
+ } else if (c == 'u') {
+ // handle unicode escapes
+ c = unescapeUnicode(ch, i+1);
+ i += 4;
+ buffy.append(c);
+ } else {
+ buffy.append(c);
+ }
+ } else {
+ buffy.append(c);
+ }
+ }
+ return buffy.toString();
+ }
+
+ /**
+ * Retrieve the unicode character whose code is listed at position
+ * <code>i</code> in the character array <code>ch</code>.
+ * @param ch the character array containing the unicode character code
+ * @return the character extracted
+ */
+ private char unescapeUnicode(final char[] ch, final int i) {
+ final String s = new String(ch, i, 4);
+ return (char) Integer.parseInt(s, 16);
+ }
+
+ /**
+ * Escape the string <code>s</code> according to the rules in the
+ * docs for <a
+ * href="http://java.sun.com/j2se/1.3/docs/api/java/util/Properties.html">java.util.Properties</a>.
+ * @param s the string to escape
+ * @return the escaped string
+ */
+ private String escapeValue(final String s) {
+ return escape(s, false);
+ }
+
+ /**
+ * Escape the string <code>s</code> according to the rules in the
+ * docs for <a
+ * href="http://java.sun.com/j2se/1.3/docs/api/java/util/Properties.html">java.util.Properties</a>.
+ * This method escapes all the whitespace, not just the stuff at
+ * the beginning.
+ * @param s the string to escape
+ * @return the escaped string
+ */
+ private String escapeName(final String s) {
+ return escape(s, true);
+ }
+
+ /**
+ * Escape the string <code>s</code> according to the rules in the
+ * docs for <a
+ * href="http://java.sun.com/j2se/1.3/docs/api/java/util/Properties.html">java.util.Properties</a>.
+ * @param s the string to escape
+ * @param escapeAllSpaces if <code>true</code> the method escapes
+ * all the spaces, if <code>false</code>, it escapes only the
+ * leading whitespace
+ * @return the escaped string
+ */
+ private String escape(final String s, final boolean escapeAllSpaces) {
+ if (s == null) {
+ return null;
+ }
+
+ final char[] ch = new char[s.length()];
+ s.getChars(0, s.length(), ch, 0);
+ final String forEscaping = "\t\f\r\n\\:=#!";
+ final String escaped = "tfrn\\:=#!";
+ final StringBuffer buffy = new StringBuffer(s.length());
+ boolean leadingSpace = true;
+ for (int i = 0; i < ch.length; i++) {
+ final char c = ch[i];
+ if (c == ' ') {
+ if (escapeAllSpaces || leadingSpace) {
+ buffy.append("\\");
+ }
+ } else {
+ leadingSpace = false;
+ }
+ final int p = forEscaping.indexOf(c);
+ if (p != -1) {
+ buffy.append("\\").append(escaped.substring(p,p+1));
+ } else if (c < 0x0020 || c > 0x007e) {
+ buffy.append(escapeUnicode(c));
+ } else {
+ buffy.append(c);
+ }
+ }
+ return buffy.toString();
+ }
+
+ /**
+ * Return the unicode escape sequence for a character, in the form
+ * \u005CuNNNN.
+ * @param ch the character to encode
+ * @return the unicode escape sequence
+ */
+ private String escapeUnicode(final char ch) {
+ return "\\" + UnicodeUtil.EscapeUnicode(ch);
+ }
+
+ /**
+ * Remove the comments in the leading up the {@link logicalLines}
+ * list leading up to line <code>pos</code>.
+ * @param pos the line number to which the comments lead
+ */
+ private void removeCommentsEndingAt(int pos) {
+ /* We want to remove comments preceding this position. Step
+ * back counting blank lines (call this range B1) until we hit
+ * something non-blank. If what we hit is not a comment, then
+ * exit. If what we hit is a comment, then step back counting
+ * comment lines (call this range C1). Nullify lines in C1 and
+ * B1.
+ */
+
+ final int end = pos - 1;
+
+ // step pos back until it hits something non-blank
+ for (pos = end; pos > 0; pos--) {
+ if (!(logicalLines.get(pos) instanceof Blank)) {
+ break;
+ }
+ }
+
+ // if the thing it hits is not a comment, then we have nothing
+ // to remove
+ if (!(logicalLines.get(pos) instanceof Comment)) {
+ return;
+ }
+
+ // step back until we hit the start of the comment
+ for (; pos >= 0; pos--) {
+ if (!(logicalLines.get(pos) instanceof Comment)) {
+ break;
+ }
+ }
+
+ // now we want to delete from pos+1 to end
+ for (pos++; pos <= end; pos++) {
+ logicalLines.set(pos, null);
+ }
+ }
+
+ /**
+ * A logical line of the properties input stream.
+ */
+ private abstract static class LogicalLine {
+ private String text;
+
+ public LogicalLine(final String text) {
+ this.text = text;
+ }
+
+ public void setText(final String text) {
+ this.text = text;
+ }
+
+ @Override
+ public String toString() {
+ return text;
+ }
+ }
+
+ /**
+ * A blank line of the input stream.
+ */
+ private static class Blank extends LogicalLine {
+ public Blank() {
+ super("");
+ }
+ }
+
+ /**
+ * A comment line of the input stream.
+ */
+ private class Comment extends LogicalLine {
+ public Comment(final String text) {
+ super(text);
+ }
+ }
+
+ /**
+ * A key-value pair from the input stream. This may span more than
+ * one physical line, but it is constitutes as a single logical
+ * line.
+ */
+ private static class Pair extends LogicalLine implements Cloneable {
+ private String name;
+ private String value;
+ private boolean added;
+
+ public Pair(final String text) {
+ super(text);
+ parsePair(text);
+ }
+
+ public Pair(final String name, final String value) {
+ this(name + "=" + value);
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ public void setValue(final String value) {
+ this.value = value;
+ setText(name + "=" + value);
+ }
+
+ public boolean isNew() {
+ return added;
+ }
+
+ public void setNew(final boolean val) {
+ added = val;
+ }
+
+ @Override
+ public Object clone() {
+ Object dolly = null;
+ try {
+ dolly = super.clone();
+ } catch (final CloneNotSupportedException e) {
+ // should be fine
+ e.printStackTrace();
+ }
+ return dolly;
+ }
+
+ private void parsePair(final String text) {
+ // need to find first non-escaped '=', ':', '\t' or ' '.
+ final int pos = findFirstSeparator(text);
+ if (pos == -1) {
+ // trim leading whitespace only
+ name = text;
+ value = null;
+ } else {
+ name = text.substring(0, pos);
+ value = text.substring(pos+1, text.length());
+ }
+ // trim leading whitespace only
+ name = stripStart(name, " \t\f");
+ }
+
+ private String stripStart(final String s, final String chars) {
+ if (s == null) {
+ return null;
+ }
+
+ int i = 0;
+ for (;i < s.length(); i++) {
+ if (chars.indexOf(s.charAt(i)) == -1) {
+ break;
+ }
+ }
+ if (i == s.length()) {
+ return "";
+ }
+ return s.substring(i);
+ }
+
+ private int findFirstSeparator(String s) {
+ // Replace double backslashes with underscores so that they don't
+ // confuse us looking for '\t' or '\=', for example, but they also
+ // don't change the position of other characters
+ s = s.replaceAll("\\\\\\\\", "__");
+
+ // Replace single backslashes followed by separators, so we don't
+ // pick them up
+ s = s.replaceAll("\\\\=", "__");
+ s = s.replaceAll("\\\\:", "__");
+ s = s.replaceAll("\\\\ ", "__");
+ s = s.replaceAll("\\\\t", "__");
+
+ // Now only the unescaped separators are left
+ return indexOfAny(s, " :=\t");
+ }
+
+ private int indexOfAny(final String s, final String chars) {
+ if (s == null || chars == null) {
+ return -1;
+ }
+
+ int p = s.length() + 1;
+ for (int i = 0; i < chars.length(); i++) {
+ final int x = s.indexOf(chars.charAt(i));
+ if (x != -1 && x < p) {
+ p = x;
+ }
+ }
+ if (p == s.length() + 1) {
+ return -1;
+ }
+ return p;
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/LazyFileOutputStream.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/LazyFileOutputStream.java
new file mode 100644
index 00000000..7e5bf786
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/LazyFileOutputStream.java
@@ -0,0 +1,162 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.util;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * Class that delays opening the output file until the first bytes
+ * shall be written or the method {@link #open open} has been invoked
+ * explicitly.
+ *
+ * @since Ant 1.6
+ */
+public class LazyFileOutputStream extends OutputStream {
+
+ private FileOutputStream fos;
+ private File file;
+ private boolean append;
+ private boolean alwaysCreate;
+ private boolean opened = false;
+ private boolean closed = false;
+
+ /**
+ * Creates a stream that will eventually write to the file with
+ * the given name and replace it.
+ * @param name the filename.
+ */
+ public LazyFileOutputStream(String name) {
+ this(name, false);
+ }
+
+ /**
+ * Creates a stream that will eventually write to the file with
+ * the given name and optionally append to instead of replacing
+ * it.
+ * @param name the filename.
+ * @param append if true append rather than replace.
+ */
+ public LazyFileOutputStream(String name, boolean append) {
+ this(new File(name), append);
+ }
+
+ /**
+ * Creates a stream that will eventually write to the file with
+ * the given name and replace it.
+ * @param f the file to create.
+ */
+ public LazyFileOutputStream(File f) {
+ this(f, false);
+ }
+
+ /**
+ * Creates a stream that will eventually write to the file with
+ * the given name and optionally append to instead of replacing
+ * it.
+ * @param file the file to create.
+ * @param append if true append rather than replace.
+ */
+ public LazyFileOutputStream(File file, boolean append) {
+ this(file, append, false);
+ }
+
+ /**
+ * Creates a stream that will eventually write to the file with
+ * the given name, optionally append to instead of replacing
+ * it, and optionally always create a file (even if zero length).
+ * @param file the file to create.
+ * @param append if true append rather than replace.
+ * @param alwaysCreate if true create the file even if nothing to write.
+ */
+ public LazyFileOutputStream(File file, boolean append,
+ boolean alwaysCreate) {
+ this.file = file;
+ this.append = append;
+ this.alwaysCreate = alwaysCreate;
+ }
+
+ /**
+ * Explicitly open the file for writing.
+ *
+ * <p>Returns silently if the file has already been opened.</p>
+ * @throws IOException if there is an error.
+ */
+ public void open() throws IOException {
+ ensureOpened();
+ }
+
+ /**
+ * Close the file.
+ * @throws IOException if there is an error.
+ */
+ public synchronized void close() throws IOException {
+ if (alwaysCreate && !closed) {
+ ensureOpened();
+ }
+ if (opened) {
+ fos.close();
+ }
+ closed = true;
+ }
+
+ /**
+ * Delegates to the three-arg version.
+ * @param b the bytearray to write.
+ * @throws IOException if there is a problem.
+ */
+ public void write(byte[] b) throws IOException {
+ write(b, 0, b.length);
+ }
+
+ /**
+ * Write part of a byte array.
+ * @param b the byte array.
+ * @param offset write from this index.
+ * @param len the number of bytes to write.
+ * @throws IOException if there is a problem.
+ */
+ public synchronized void write(byte[] b, int offset, int len)
+ throws IOException {
+ ensureOpened();
+ fos.write(b, offset, len);
+ }
+
+ /**
+ * Write a byte.
+ * @param b the byte to write.
+ * @throws IOException if there is a problem.
+ */
+ public synchronized void write(int b) throws IOException {
+ ensureOpened();
+ fos.write(b);
+ }
+
+ private synchronized void ensureOpened() throws IOException {
+ if (closed) {
+ throw new IOException(file + " has already been closed.");
+ }
+
+ if (!opened) {
+ fos = new FileOutputStream(file.getAbsolutePath(), append);
+ opened = true;
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/LazyHashtable.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/LazyHashtable.java
new file mode 100644
index 00000000..1df953cf
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/LazyHashtable.java
@@ -0,0 +1,120 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.util;
+
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+/** Hashtable implementation that allows delayed construction
+ * of expensive objects
+ *
+ * All operations that need access to the full list of objects
+ * will call initAll() first. Get and put are cheap.
+ *
+ * @since Ant 1.6
+ */
+public class LazyHashtable extends Hashtable {
+ // CheckStyle:VisibilityModifier OFF - bc
+ protected boolean initAllDone = false;
+ // CheckStyle:VisibilityModifier OFF - bc
+
+ /** No arg constructor. */
+ public LazyHashtable() {
+ super();
+ }
+
+ /** Used to be part of init. It must be done once - but
+ * we delay it until we do need _all_ tasks. Otherwise we
+ * just get the tasks that we need, and avoid costly init.
+ */
+ protected void initAll() {
+ if (initAllDone) {
+ return;
+ }
+ initAllDone = true;
+ }
+
+
+ /**
+ * Get a enumeration over the elements.
+ * @return an enumeration.
+ */
+ public Enumeration elements() {
+ initAll();
+ return super.elements();
+ }
+
+ /**
+ * Check if the table is empty.
+ * @return true if it is.
+ */
+ public boolean isEmpty() {
+ initAll();
+ return super.isEmpty();
+ }
+
+ /**
+ * Get the size of the table.
+ * @return the size.
+ */
+ public int size() {
+ initAll();
+ return super.size();
+ }
+
+ /**
+ * Check if the table contains a particular value.
+ * @param value the value to look for.
+ * @return true if the table contains the value.
+ */
+ public boolean contains(Object value) {
+ initAll();
+ return super.contains(value);
+ }
+
+ /**
+ * Check if the table contains a particular key.
+ * @param value the key to look for.
+ * @return true if the table contains key.
+ */
+ public boolean containsKey(Object value) {
+ initAll();
+ return super.containsKey(value);
+ }
+
+ /**
+ * Delegates to {@link #contains contains}.
+ * @param value the value to look for.
+ * @return true if the table contains the value.
+ */
+ public boolean containsValue(Object value) {
+ return contains(value);
+ }
+
+ /**
+ * Get an enumeration over the keys.
+ * @return an enumeration.
+ */
+ public Enumeration keys() {
+ initAll();
+ return super.keys();
+ }
+
+ // TODO Unfortunately JDK1.2 adds entrySet(), keySet(), values() -
+ // implementing this requires a small hack, we can add it later.
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/LeadPipeInputStream.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/LeadPipeInputStream.java
new file mode 100644
index 00000000..00819128
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/LeadPipeInputStream.java
@@ -0,0 +1,161 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.util;
+
+import java.io.IOException;
+import java.io.PipedInputStream;
+import java.io.PipedOutputStream;
+
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.ProjectComponent;
+import org.apache.tools.ant.Task;
+
+/**
+ * Special <code>PipedInputStream</code> that will not die
+ * when the writing <code>Thread</code> is no longer alive.
+ * @since Ant 1.6.2
+ */
+public class LeadPipeInputStream extends PipedInputStream {
+ private static final int BYTE_MASK = 0xFF;
+ private ProjectComponent managingPc;
+
+ /**
+ * Construct a new <code>LeadPipeInputStream</code>.
+ */
+ public LeadPipeInputStream() {
+ super();
+ }
+
+ /**
+ * Construct a new <code>LeadPipeInputStream</code>
+ * with the specified buffer size.
+ * @param size the size of the circular buffer.
+ */
+ public LeadPipeInputStream(int size) {
+ super();
+ setBufferSize(size);
+ }
+
+ /**
+ * Construct a new <code>LeadPipeInputStream</code> to pull
+ * from the specified <code>PipedOutputStream</code>.
+ * @param src the <code>PipedOutputStream</code> source.
+ * @throws IOException if unable to construct the stream.
+ */
+ public LeadPipeInputStream(PipedOutputStream src) throws IOException {
+ super(src);
+ }
+
+ /**
+ * Construct a new <code>LeadPipeInputStream</code> to pull
+ * from the specified <code>PipedOutputStream</code>, using a
+ * circular buffer of the specified size.
+ * @param src the <code>PipedOutputStream</code> source.
+ * @param size the size of the circular buffer.
+ * @throws IOException if there is an error.
+ */
+ public LeadPipeInputStream(PipedOutputStream src, int size) throws IOException {
+ super(src);
+ setBufferSize(size);
+ }
+
+ //inherit doc
+ /**
+ * Read a byte from the stream.
+ * @return the byte (0 to 255) or -1 if there are no more.
+ * @throws IOException if there is an error.
+ */
+ public synchronized int read() throws IOException {
+ int result = -1;
+ try {
+ result = super.read();
+ } catch (IOException eyeOhEx) {
+ String msg = eyeOhEx.getMessage();
+ if ("write end dead".equalsIgnoreCase(msg)
+ || "pipe broken".equalsIgnoreCase(msg)) {
+ if (super.in > 0 && super.out < super.buffer.length
+ && super.out > super.in) {
+ result = super.buffer[super.out++] & BYTE_MASK;
+ }
+ } else {
+ log("error at LeadPipeInputStream.read(): " + msg,
+ Project.MSG_INFO);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Set the size of the buffer.
+ * @param size the new buffer size. Ignored if &lt;= current size.
+ */
+ public synchronized void setBufferSize(int size) {
+ if (size > buffer.length) {
+ byte[] newBuffer = new byte[size];
+ if (in >= 0) {
+ if (in > out) {
+ System.arraycopy(buffer, out, newBuffer, out, in - out);
+ } else {
+ int outlen = buffer.length - out;
+ System.arraycopy(buffer, out, newBuffer, 0, outlen);
+ System.arraycopy(buffer, 0, newBuffer, outlen, in);
+ in += outlen;
+ out = 0;
+ }
+ }
+ buffer = newBuffer;
+ }
+ }
+
+ /**
+ * Set a managing <code>Task</code> for
+ * this <code>LeadPipeInputStream</code>.
+ * @param task the managing <code>Task</code>.
+ */
+ public void setManagingTask(Task task) {
+ setManagingComponent(task);
+ }
+
+ /**
+ * Set a managing <code>ProjectComponent</code> for
+ * this <code>LeadPipeInputStream</code>.
+ * @param pc the managing <code>ProjectComponent</code>.
+ */
+ public void setManagingComponent(ProjectComponent pc) {
+ this.managingPc = pc;
+ }
+
+ /**
+ * Log a message with the specified logging level.
+ * @param message the <code>String</code> message.
+ * @param loglevel the <code>int</code> logging level.
+ */
+ public void log(String message, int loglevel) {
+ if (managingPc != null) {
+ managingPc.log(message, loglevel);
+ } else {
+ if (loglevel > Project.MSG_WARN) {
+ System.out.println(message);
+ } else {
+ System.err.println(message);
+ }
+ }
+ }
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/LineOrientedOutputStream.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/LineOrientedOutputStream.java
new file mode 100644
index 00000000..073a89f1
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/LineOrientedOutputStream.java
@@ -0,0 +1,158 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.util;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * Invokes {@link #processLine processLine} whenever a full line has
+ * been written to this stream.
+ *
+ * <p>Tries to be smart about line separators.</p>
+ */
+public abstract class LineOrientedOutputStream extends OutputStream {
+
+ /** Initial buffer size. */
+ private static final int INITIAL_SIZE = 132;
+
+ /** Carriage return */
+ private static final int CR = 0x0d;
+
+ /** Linefeed */
+ private static final int LF = 0x0a;
+
+ private ByteArrayOutputStream buffer
+ = new ByteArrayOutputStream(INITIAL_SIZE);
+ private boolean skip = false;
+
+ /**
+ * Write the data to the buffer and flush the buffer, if a line
+ * separator is detected.
+ *
+ * @param cc data to log (byte).
+ * @throws IOException if there is an error.
+ */
+ @Override
+ public final void write(int cc) throws IOException {
+ final byte c = (byte) cc;
+ if ((c == LF) || (c == CR)) {
+ if (!skip) {
+ processBuffer();
+ }
+ } else {
+ buffer.write(cc);
+ }
+ skip = (c == CR);
+ }
+
+ /**
+ * Flush this log stream
+ * @throws IOException if there is an error.
+ */
+ @Override
+ public void flush() throws IOException {
+ }
+
+ /**
+ * Converts the buffer to a byte[] and sends it to
+ * <code>processLine</code>
+ * @throws IOException if there is an error.
+ */
+ protected void processBuffer() throws IOException {
+ try {
+ processLine(buffer.toByteArray());
+ } finally {
+ buffer.reset();
+ }
+ }
+
+ /**
+ * Processes a line.
+ *
+ * @param line the line to log.
+ * @throws IOException if there is an error.
+ */
+ protected abstract void processLine(String line) throws IOException;
+
+ /**
+ * Processes a line.
+ *
+ * <p>This implementations invokes the string-arg version
+ * converting the byte array using the default encoding.
+ * Subclasses are encouraged to override this method (and provide
+ * a dummy implementation of the String-arg version) so they don't
+ * interfere with the encoding of the underlying stream.</p>
+ *
+ * @param line the line to log.
+ * @throws IOException if there is an error.
+ * @since Ant 1.8.3
+ */
+ protected void processLine(byte[] line) throws IOException {
+ processLine(new String(line));
+ }
+
+ /**
+ * Writes all remaining
+ * @throws IOException if there is an error.
+ */
+ @Override
+ public void close() throws IOException {
+ if (buffer.size() > 0) {
+ processBuffer();
+ }
+ super.close();
+ }
+
+ /**
+ * Write a block of characters to the output stream
+ *
+ * @param b the array containing the data
+ * @param off the offset into the array where data starts
+ * @param len the length of block
+ *
+ * @throws IOException if the data cannot be written into the stream.
+ */
+ @Override
+ public final void write(byte[] b, int off, int len) throws IOException {
+ // find the line breaks and pass other chars through in blocks
+ int offset = off;
+ int blockStartOffset = offset;
+ int remaining = len;
+ while (remaining > 0) {
+ while (remaining > 0 && b[offset] != LF && b[offset] != CR) {
+ offset++;
+ remaining--;
+ }
+ // either end of buffer or a line separator char
+ int blockLength = offset - blockStartOffset;
+ if (blockLength > 0) {
+ buffer.write(b, blockStartOffset, blockLength);
+ }
+ while (remaining > 0 && (b[offset] == LF || b[offset] == CR)) {
+ write(b[offset]);
+ offset++;
+ remaining--;
+ }
+ blockStartOffset = offset;
+ }
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/LineOrientedOutputStreamRedirector.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/LineOrientedOutputStreamRedirector.java
new file mode 100644
index 00000000..48bad5cc
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/LineOrientedOutputStreamRedirector.java
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.util;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * Output stream which buffer and redirect a stream line by line.
+ * <p>
+ * If the source stream doesn't end with a end of line, one will be added. This
+ * is particularly useful in combination with the OutputStreamFunneler so each
+ * funneled stream get its line.
+ *
+ * @since Ant 1.8.3
+ */
+public class LineOrientedOutputStreamRedirector
+ extends LineOrientedOutputStream {
+
+ private OutputStream stream;
+
+ // these should be in the ASCII range and hopefully are single bytes
+ // (for LF and CR respectively) for any encoding thrown at this class
+ private static final byte[] EOL =
+ System.getProperty("line.separator").getBytes();
+
+ public LineOrientedOutputStreamRedirector(OutputStream stream) {
+ this.stream = stream;
+ }
+
+ @Override
+ protected void processLine(byte[] b) throws IOException {
+ stream.write(b);
+ stream.write(EOL);
+ }
+
+ @Override
+ protected void processLine(String line) throws IOException {
+ stream.write((line + System.getProperty("line.separator")).getBytes());
+ }
+
+ @Override
+ public void close() throws IOException {
+ super.close();
+ stream.close();
+ }
+
+ @Override
+ public void flush() throws IOException {
+ super.flush();
+ stream.flush();
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/LineTokenizer.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/LineTokenizer.java
new file mode 100644
index 00000000..778606dd
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/LineTokenizer.java
@@ -0,0 +1,115 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.util;
+
+import java.io.IOException;
+import java.io.Reader;
+
+import org.apache.tools.ant.ProjectComponent;
+
+/**
+ * class to tokenize the input as lines separated
+ * by \r (mac style), \r\n (dos/windows style) or \n (unix style)
+ * @since Ant 1.6
+ */
+public class LineTokenizer extends ProjectComponent
+ implements Tokenizer {
+ private static final int NOT_A_CHAR = -2;
+ private String lineEnd = "";
+ private int pushed = NOT_A_CHAR;
+ private boolean includeDelims = false;
+
+ /**
+ * attribute includedelims - whether to include
+ * the line ending with the line, or to return
+ * it in the posttoken
+ * default false
+ * @param includeDelims if true include /r and /n in the line
+ */
+
+ public void setIncludeDelims(boolean includeDelims) {
+ this.includeDelims = includeDelims;
+ }
+
+ /**
+ * get the next line from the input
+ *
+ * @param in the input reader
+ * @return the line excluding /r or /n, unless includedelims is set
+ * @exception IOException if an error occurs reading
+ */
+ public String getToken(Reader in) throws IOException {
+ int ch = -1;
+ if (pushed != NOT_A_CHAR) {
+ ch = pushed;
+ pushed = NOT_A_CHAR;
+ } else {
+ ch = in.read();
+ }
+ if (ch == -1) {
+ return null;
+ }
+
+ lineEnd = "";
+ StringBuffer line = new StringBuffer();
+
+ int state = 0;
+ while (ch != -1) {
+ if (state == 0) {
+ if (ch == '\r') {
+ state = 1;
+ } else if (ch == '\n') {
+ lineEnd = "\n";
+ break;
+ } else {
+ line.append((char) ch);
+ }
+ } else {
+ state = 0;
+ if (ch == '\n') {
+ lineEnd = "\r\n";
+ } else {
+ pushed = ch;
+ lineEnd = "\r";
+ }
+ break;
+ }
+ ch = in.read();
+ }
+ if (ch == -1 && state == 1) {
+ lineEnd = "\r";
+ }
+
+ if (includeDelims) {
+ line.append(lineEnd);
+ }
+ return line.toString();
+ }
+
+ /**
+ * @return the line ending character(s) for the current line
+ */
+ public String getPostToken() {
+ if (includeDelims) {
+ return "";
+ }
+ return lineEnd;
+ }
+
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/LinkedHashtable.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/LinkedHashtable.java
new file mode 100644
index 00000000..73fc83c6
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/LinkedHashtable.java
@@ -0,0 +1,132 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.util;
+
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Subclass of Hashtable that wraps a LinkedHashMap to provide
+ * predictable iteration order.
+ *
+ * <p>This is not a general purpose class but has been written because
+ * the protected members of {@link org.apache.tools.ant.taskdefs.Copy
+ * Copy} prohibited later revisions from using a more predictable
+ * collection.</p>
+ *
+ * <p>Methods are synchronized to keep Hashtable's contract.</p>
+ *
+ * @since Ant 1.8.2
+ */
+public class LinkedHashtable<K, V> extends Hashtable<K, V> {
+ private static final long serialVersionUID = 1L;
+
+ private final LinkedHashMap<K, V> map;
+
+ public LinkedHashtable() {
+ map = new LinkedHashMap<K, V>();
+ }
+
+ public LinkedHashtable(int initialCapacity) {
+ map = new LinkedHashMap<K, V>(initialCapacity);
+ }
+
+ public LinkedHashtable(int initialCapacity, float loadFactor) {
+ map = new LinkedHashMap<K, V>(initialCapacity, loadFactor);
+ }
+
+ public LinkedHashtable(Map<K, V> m) {
+ map = new LinkedHashMap<K, V>(m);
+ }
+
+ public synchronized void clear() {
+ map.clear();
+ }
+
+ public boolean contains(Object value) {
+ return containsKey(value);
+ }
+
+ public synchronized boolean containsKey(Object value) {
+ return map.containsKey(value);
+ }
+
+ public synchronized boolean containsValue(Object value) {
+ return map.containsValue(value);
+ }
+
+ public Enumeration<V> elements() {
+ return CollectionUtils.asEnumeration(values().iterator());
+ }
+
+ public synchronized Set<Map.Entry<K, V>> entrySet() {
+ return map.entrySet();
+ }
+
+ public synchronized boolean equals(Object o) {
+ return map.equals(o);
+ }
+
+ public synchronized V get(Object k) {
+ return map.get(k);
+ }
+
+ public synchronized int hashCode() {
+ return map.hashCode();
+ }
+
+ public synchronized boolean isEmpty() {
+ return map.isEmpty();
+ }
+
+ public Enumeration<K> keys() {
+ return CollectionUtils.asEnumeration(keySet().iterator());
+ }
+
+ public synchronized Set<K> keySet() {
+ return map.keySet();
+ }
+
+ public synchronized V put(K k, V v) {
+ return map.put(k, v);
+ }
+
+ public synchronized void putAll(Map<? extends K, ? extends V> m) {
+ map.putAll(m);
+ }
+
+ public synchronized V remove(Object k) {
+ return map.remove(k);
+ }
+
+ public synchronized int size() {
+ return map.size();
+ }
+
+ public synchronized String toString() {
+ return map.toString();
+ }
+
+ public synchronized Collection<V> values() {
+ return map.values();
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/LoaderUtils.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/LoaderUtils.java
new file mode 100644
index 00000000..e0514f65
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/LoaderUtils.java
@@ -0,0 +1,140 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.util;
+
+import java.io.File;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.launch.Locator;
+
+// CheckStyle:HideUtilityClassConstructorCheck OFF - bc
+
+/**
+ * ClassLoader utility methods
+ *
+ */
+public class LoaderUtils {
+
+ /** Utilities used for file operations */
+ private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+
+ /**
+ * Set the context classloader
+ *
+ * @param loader the ClassLoader to be used as the context class loader
+ * on the current thread.
+ */
+ public static void setContextClassLoader(ClassLoader loader) {
+ Thread currentThread = Thread.currentThread();
+ currentThread.setContextClassLoader(loader);
+ }
+
+
+ /**
+ * JDK1.1 compatible access to set the context class loader.
+ *
+ * @return the ClassLoader instance being used as the context
+ * classloader on the current thread. Returns null on JDK 1.1
+ */
+ public static ClassLoader getContextClassLoader() {
+ Thread currentThread = Thread.currentThread();
+ return currentThread.getContextClassLoader();
+ }
+
+ /**
+ * Indicates if the context class loader methods are available
+ *
+ * @return true if the get and set methods dealing with the context
+ * classloader are available.
+ */
+ public static boolean isContextLoaderAvailable() {
+ return true;
+ }
+
+ /**
+ * Normalize a source location
+ *
+ * @param source the source location to be normalized.
+ *
+ * @return the normalized source location.
+ */
+ private static File normalizeSource(File source) {
+ if (source != null) {
+ try {
+ source = FILE_UTILS.normalize(source.getAbsolutePath());
+ } catch (BuildException e) {
+ // relative path
+ }
+ }
+
+ return source;
+ }
+
+ /**
+ * Find the directory or jar file the class has been loaded from.
+ *
+ * @param c the class whose location is required.
+ * @return the file or jar with the class or null if we cannot
+ * determine the location.
+ *
+ * @since Ant 1.6
+ */
+ public static File getClassSource(Class c) {
+ return normalizeSource(Locator.getClassSource(c));
+ }
+
+ /**
+ * Find the directory or a give resource has been loaded from.
+ *
+ * @param c the classloader to be consulted for the source
+ * @param resource the resource whose location is required.
+ *
+ * @return the file with the resource source or null if
+ * we cannot determine the location.
+ *
+ * @since Ant 1.6
+ */
+ public static File getResourceSource(ClassLoader c, String resource) {
+ if (c == null) {
+ c = LoaderUtils.class.getClassLoader();
+ }
+ return normalizeSource(Locator.getResourceSource(c, resource));
+ }
+
+ /**
+ * Return the resource name of a class name.
+ * @param className the name of the class to convert.
+ * @return the corresponding resource name.
+ * @since Ant 1.7.0.
+ */
+ public static String classNameToResource(String className) {
+ return className.replace('.', '/') + ".class";
+ }
+
+ /**
+ * Check if a classloader has a classname resource.
+ * @param loader the classloader to look it.
+ * @param className the name of the class to look for.
+ * @return true if the classexists, false otherwise
+ * @since Ant 1.7.0.
+ */
+ public static boolean classExists(ClassLoader loader, String className) {
+ return loader.getResource(classNameToResource(className)) != null;
+ }
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/MergingMapper.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/MergingMapper.java
new file mode 100644
index 00000000..7f158dbf
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/MergingMapper.java
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.util;
+
+/**
+ * Implementation of FileNameMapper that always returns the same
+ * target file name.
+ *
+ * <p>This is the default FileNameMapper for the archiving tasks and
+ * uptodate.</p>
+ *
+ */
+public class MergingMapper implements FileNameMapper {
+ // CheckStyle:VisibilityModifier OFF - bc
+ protected String[] mergedFile = null;
+ // CheckStyle:VisibilityModifier ON
+
+ public MergingMapper() {}
+
+ /**
+ * @since Ant 1.8.0
+ */
+ public MergingMapper(String to) {
+ setTo(to);
+ }
+
+ /**
+ * Ignored.
+ * @param from ignored.
+ */
+ public void setFrom(String from) {
+ }
+
+ /**
+ * Sets the name of the merged file.
+ * @param to the name of the merged file.
+ */
+ public void setTo(String to) {
+ mergedFile = new String[] {to};
+ }
+
+ /**
+ * Returns an one-element array containing the file name set via setTo.
+ * @param sourceFileName ignored.
+ * @return a one-element array containing the merged filename.
+ */
+ public String[] mapFileName(String sourceFileName) {
+ return mergedFile;
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/OutputStreamFunneler.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/OutputStreamFunneler.java
new file mode 100644
index 00000000..6694c3f0
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/OutputStreamFunneler.java
@@ -0,0 +1,176 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.util;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * Manages a set of <code>OutputStream</code>s to
+ * write to a single underlying stream, which is
+ * closed only when the last &quot;funnel&quot;
+ * has been closed.
+ */
+public class OutputStreamFunneler {
+
+ /**
+ * Default timeout.
+ * @see #setTimeout(long)
+ */
+ public static final long DEFAULT_TIMEOUT_MILLIS = 1000;
+
+ private final class Funnel extends OutputStream {
+ private boolean closed = false;
+
+ private Funnel() {
+ synchronized (OutputStreamFunneler.this) {
+ ++count;
+ }
+ }
+
+ public void flush() throws IOException {
+ synchronized (OutputStreamFunneler.this) {
+ dieIfClosed();
+ out.flush();
+ }
+ }
+
+ public void write(int b) throws IOException {
+ synchronized (OutputStreamFunneler.this) {
+ dieIfClosed();
+ out.write(b);
+ }
+ }
+
+ public void write(byte[] b) throws IOException {
+ synchronized (OutputStreamFunneler.this) {
+ dieIfClosed();
+ out.write(b);
+ }
+ }
+
+ public void write(byte[] b, int off, int len) throws IOException {
+ synchronized (OutputStreamFunneler.this) {
+ dieIfClosed();
+ out.write(b, off, len);
+ }
+ }
+
+ public void close() throws IOException {
+ release(this);
+ }
+ }
+
+ private OutputStream out;
+ private int count = 0;
+ private boolean closed;
+ private long timeoutMillis;
+
+ /**
+ * Create a new <code>OutputStreamFunneler</code> for
+ * the specified <code>OutputStream</code>.
+ * @param out <code>OutputStream</code>.
+ */
+ public OutputStreamFunneler(OutputStream out) {
+ this(out, DEFAULT_TIMEOUT_MILLIS);
+ }
+
+ /**
+ * Create a new <code>OutputStreamFunneler</code> for
+ * the specified <code>OutputStream</code>, with the
+ * specified timeout value.
+ * @param out <code>OutputStream</code>.
+ * @param timeoutMillis <code>long</code>.
+ * @see #setTimeout(long)
+ */
+ public OutputStreamFunneler(OutputStream out, long timeoutMillis) {
+ if (out == null) {
+ throw new IllegalArgumentException(
+ "OutputStreamFunneler.<init>: out == null");
+ }
+ this.out = out;
+ this.closed = false; //as far as we know
+ setTimeout(timeoutMillis);
+ }
+
+ /**
+ * Set the timeout for this <code>OutputStreamFunneler</code>.
+ * This is the maximum time that may elapse between the closure
+ * of the last &quot;funnel&quot; and the next call to
+ * <code>getOutputStream()</code> without closing the
+ * underlying stream.
+ * @param timeoutMillis <code>long</code> timeout value.
+ */
+ public synchronized void setTimeout(long timeoutMillis) {
+ this.timeoutMillis = timeoutMillis;
+ }
+
+ /**
+ * Get a &quot;funnel&quot; <code>OutputStream</code> instance to
+ * write to this <code>OutputStreamFunneler</code>'s underlying
+ * <code>OutputStream</code>.
+ * @return <code>OutputStream</code>.
+ * @throws IOException if unable to create the funnel.
+ */
+ public synchronized OutputStream getFunnelInstance()
+ throws IOException {
+ dieIfClosed();
+ try {
+ return new Funnel();
+ } finally {
+ notifyAll();
+ }
+ }
+
+ private synchronized void release(Funnel funnel) throws IOException {
+ //ignore release of an already-closed funnel
+ if (!funnel.closed) {
+ try {
+ if (timeoutMillis > 0) {
+ try {
+ wait(timeoutMillis);
+ } catch (InterruptedException eyeEx) {
+ //ignore
+ }
+ }
+ if (--count == 0) {
+ close();
+ }
+ } finally {
+ funnel.closed = true;
+ }
+ }
+ }
+
+ private synchronized void close() throws IOException {
+ try {
+ dieIfClosed();
+ out.close();
+ } finally {
+ closed = true;
+ }
+ }
+
+ private synchronized void dieIfClosed() throws IOException {
+ if (closed) {
+ throw new IOException("The funneled OutputStream has been closed.");
+ }
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/PackageNameMapper.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/PackageNameMapper.java
new file mode 100644
index 00000000..30256670
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/PackageNameMapper.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.util;
+
+import java.io.File;
+
+/**
+ * Maps directory name matches into a dotted package name. This is
+ * useful for matching JUnit test cases against their XML formatter
+ * results.
+ * <pre>
+ * &lt;mapper classname="org.apache.tools.ant.util.PackageNameMapper"
+ * from="*Test.java" to="${test.data.dir}/TEST-*Test.xml"/&gt;
+ * </pre>
+ *
+ */
+public class PackageNameMapper extends GlobPatternMapper {
+ /**
+ * Returns the part of the given string that matches the * in the
+ * &quot;from&quot; pattern replacing file separators with dots
+ *
+ *@param name Source filename
+ *@return Replaced variable part
+ */
+ protected String extractVariablePart(String name) {
+ String var = name.substring(prefixLength,
+ name.length() - postfixLength);
+ if (getHandleDirSep()) {
+ var = var.replace('/', '.').replace('\\', '.');
+ }
+ return var.replace(File.separatorChar, '.');
+ }
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/ProcessUtil.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/ProcessUtil.java
new file mode 100644
index 00000000..f6e71b12
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/ProcessUtil.java
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.util;
+
+import java.lang.management.ManagementFactory;
+
+/**
+ * Process Utilities
+ * @since Ant 1.9.4
+ */
+public class ProcessUtil {
+
+ private ProcessUtil() {
+ }
+
+ /**
+ * provide id of the current process
+ * @param fallback
+ * @return current process id
+ */
+ public static String getProcessId(final String fallback) {
+ // Note: may fail in some JVM implementations
+ // therefore fallback has to be provided
+
+ // something like '<pid>@<hostname>', at least in SUN / Oracle JVMs
+ final String jvmName = ManagementFactory.getRuntimeMXBean().getName();
+ final int index = jvmName.indexOf('@');
+
+ if (index < 1) {
+ // part before '@' empty (index = 0) / '@' not found (index = -1)
+ return fallback;
+ }
+
+ try {
+ return Long.toString(Long.parseLong(jvmName.substring(0, index)));
+ } catch (NumberFormatException e) {
+ // ignore
+ }
+ return fallback;
+ }
+
+ public static void main(String [] args) {
+ System.out.println(getProcessId("<PID>"));
+ try {
+ Thread.sleep(120000);
+ } catch (Exception exc) {
+ // ignore
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/PropertyOutputStream.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/PropertyOutputStream.java
new file mode 100644
index 00000000..59a1b7e8
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/PropertyOutputStream.java
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.util;
+
+import java.io.ByteArrayOutputStream;
+
+import org.apache.tools.ant.Project;
+
+/**
+ * Exception thrown when an attempt is made to get an OutputStream
+ * from an immutable Resource.
+ * @since Ant 1.7
+ */
+public class PropertyOutputStream extends ByteArrayOutputStream {
+ private Project project;
+ private String property;
+ private boolean trim;
+
+ /**
+ * Construct a new PropertyOutputStream for the specified Project
+ * and property name, trimming the property value.
+ * @param p the associated Ant Project.
+ * @param s the String property name.
+ */
+ public PropertyOutputStream(Project p, String s) {
+ this(p, s, true);
+ }
+
+ /**
+ * Construct a new PropertyOutputStream for
+ * the specified Project, property name, and trim mode.
+ * @param p the associated Ant Project.
+ * @param s the String property name.
+ * @param b the boolean trim mode.
+ */
+ public PropertyOutputStream(Project p, String s, boolean b) {
+ project = p;
+ property = s;
+ trim = b;
+ }
+
+ /**
+ * Close the PropertyOutputStream, storing the property.
+ */
+ public void close() {
+ if (project != null && property != null) {
+ String s = new String(toByteArray());
+ project.setNewProperty(property, trim ? s.trim() : s);
+ }
+ }
+
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/ProxySetup.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/ProxySetup.java
new file mode 100644
index 00000000..f077f87c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/ProxySetup.java
@@ -0,0 +1,115 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.util;
+
+import org.apache.tools.ant.Project;
+
+/**
+ * Code to do proxy setup. This is just factored out of the main system just to
+ * keep everything else less convoluted.
+ * @since Ant1.7
+ */
+
+public class ProxySetup {
+
+ /**
+ * owner project; used for logging and extracting properties
+ */
+ private Project owner;
+
+ /**
+ * Java1.5 property that enables use of system proxies.
+ */
+ public static final String USE_SYSTEM_PROXIES = "java.net.useSystemProxies";
+ /** the http proxyhost property */
+ public static final String HTTP_PROXY_HOST = "http.proxyHost";
+ /** the http proxyport property */
+ public static final String HTTP_PROXY_PORT = "http.proxyPort";
+ /** the https proxyhost property */
+ public static final String HTTPS_PROXY_HOST = "https.proxyHost";
+ /** the https proxyport property */
+ public static final String HTTPS_PROXY_PORT = "https.proxyPort";
+ /** the ftp proxyhost property */
+ public static final String FTP_PROXY_HOST = "ftp.proxyHost";
+ /** the ftp proxyport property */
+ public static final String FTP_PROXY_PORT = "ftp.proxyPort";
+ /** the ftp proxyport property */
+ public static final String HTTP_NON_PROXY_HOSTS = "http.nonProxyHosts";
+ /** the http hosts not to be proxied property */
+ public static final String HTTPS_NON_PROXY_HOSTS = "https.nonProxyHosts";
+ /** the ftp hosts not to be proxied property */
+ public static final String FTP_NON_PROXY_HOSTS = "ftp.nonProxyHosts";
+ /** the http proxy username property */
+ public static final String HTTP_PROXY_USERNAME = "http.proxyUser";
+ /** the http proxy password property */
+ public static final String HTTP_PROXY_PASSWORD = "http.proxyPassword";
+ /** the socks proxy host property */
+ public static final String SOCKS_PROXY_HOST = "socksProxyHost";
+ /** the socks proxy port property */
+ public static final String SOCKS_PROXY_PORT = "socksProxyPort";
+ /** the socks proxy username property */
+ public static final String SOCKS_PROXY_USERNAME = "java.net.socks.username";
+ /** the socks proxy password property */
+ public static final String SOCKS_PROXY_PASSWORD = "java.net.socks.password";
+
+ /**
+ * create a proxy setup class bound to this project
+ * @param owner the project that owns this setup.
+ */
+ public ProxySetup(Project owner) {
+ this.owner = owner;
+ }
+
+ /**
+ * Get the current system property settings
+ * @return current value; null for none or no access
+ */
+ public static String getSystemProxySetting() {
+ try {
+ return System.getProperty(USE_SYSTEM_PROXIES);
+ } catch (SecurityException e) {
+ //if you cannot read it, you won't be able to write it either
+ return null;
+ }
+ }
+
+ /**
+ * turn proxies on;
+ * if the proxy key is already set to some value: leave alone.
+ * if an ant property of the value {@link #USE_SYSTEM_PROXIES}
+ * is set, use that instead. Else set to "true".
+ */
+ public void enableProxies() {
+ if (!(getSystemProxySetting() != null)) {
+ String proxies = owner.getProperty(USE_SYSTEM_PROXIES);
+ if (proxies == null || Project.toBoolean(proxies)) {
+ proxies = "true";
+ }
+ String message = "setting " + USE_SYSTEM_PROXIES + " to " + proxies;
+ try {
+ owner.log(message, Project.MSG_DEBUG);
+ System.setProperty(USE_SYSTEM_PROXIES, proxies);
+ } catch (SecurityException e) {
+ //log security exceptions and continue; it aint that
+ //important and may be quite common running Ant embedded.
+ owner.log("Security Exception when " + message);
+ }
+ }
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/ReaderInputStream.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/ReaderInputStream.java
new file mode 100644
index 00000000..620af8d5
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/ReaderInputStream.java
@@ -0,0 +1,205 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.util;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+
+/**
+ * Adapts a <code>Reader</code> as an <code>InputStream</code>.
+ * Adapted from <code>StringInputStream</code>.
+ *
+ */
+public class ReaderInputStream extends InputStream {
+ private static final int BYTE_MASK = 0xFF;
+
+ /** Source Reader */
+ private Reader in;
+
+ private String encoding = System.getProperty("file.encoding");
+
+ private byte[] slack;
+
+ private int begin;
+
+ /**
+ * Construct a <code>ReaderInputStream</code>
+ * for the specified <code>Reader</code>.
+ *
+ * @param reader <code>Reader</code>. Must not be <code>null</code>.
+ */
+ public ReaderInputStream(Reader reader) {
+ in = reader;
+ }
+
+ /**
+ * Construct a <code>ReaderInputStream</code>
+ * for the specified <code>Reader</code>,
+ * with the specified encoding.
+ *
+ * @param reader non-null <code>Reader</code>.
+ * @param encoding non-null <code>String</code> encoding.
+ */
+ public ReaderInputStream(Reader reader, String encoding) {
+ this(reader);
+ if (encoding == null) {
+ throw new IllegalArgumentException("encoding must not be null");
+ } else {
+ this.encoding = encoding;
+ }
+ }
+
+ /**
+ * Reads from the <code>Reader</code>, returning the same value.
+ *
+ * @return the value of the next character in the <code>Reader</code>.
+ *
+ * @exception IOException if the original <code>Reader</code> fails to be read
+ */
+ public synchronized int read() throws IOException {
+ if (in == null) {
+ throw new IOException("Stream Closed");
+ }
+
+ byte result;
+ if (slack != null && begin < slack.length) {
+ result = slack[begin];
+ if (++begin == slack.length) {
+ slack = null;
+ }
+ } else {
+ byte[] buf = new byte[1];
+ if (read(buf, 0, 1) <= 0) {
+ return -1;
+ } else {
+ result = buf[0];
+ }
+ }
+ return result & BYTE_MASK;
+ }
+
+ /**
+ * Reads from the <code>Reader</code> into a byte array
+ *
+ * @param b the byte array to read into
+ * @param off the offset in the byte array
+ * @param len the length in the byte array to fill
+ * @return the actual number read into the byte array, -1 at
+ * the end of the stream
+ * @exception IOException if an error occurs
+ */
+ public synchronized int read(byte[] b, int off, int len)
+ throws IOException {
+ if (in == null) {
+ throw new IOException("Stream Closed");
+ }
+ if (len == 0) {
+ return 0;
+ }
+ while (slack == null) {
+ char[] buf = new char[len]; // might read too much
+ int n = in.read(buf);
+ if (n == -1) {
+ return -1;
+ }
+ if (n > 0) {
+ slack = new String(buf, 0, n).getBytes(encoding);
+ begin = 0;
+ }
+ }
+
+ if (len > slack.length - begin) {
+ len = slack.length - begin;
+ }
+
+ System.arraycopy(slack, begin, b, off, len);
+
+ begin += len;
+ if (begin >= slack.length) {
+ slack = null;
+ }
+
+ return len;
+ }
+
+ /**
+ * Marks the read limit of the Reader.
+ *
+ * @param limit the maximum limit of bytes that can be read before the
+ * mark position becomes invalid
+ */
+ public synchronized void mark(final int limit) {
+ try {
+ in.mark(limit);
+ } catch (IOException ioe) {
+ throw new RuntimeException(ioe.getMessage());
+ }
+ }
+
+
+ /**
+ * @return the current number of bytes ready for reading
+ * @exception IOException if an error occurs
+ */
+ public synchronized int available() throws IOException {
+ if (in == null) {
+ throw new IOException("Stream Closed");
+ }
+ if (slack != null) {
+ return slack.length - begin;
+ }
+ if (in.ready()) {
+ return 1;
+ }
+ return 0;
+ }
+
+ /**
+ * @return false - mark is not supported
+ */
+ public boolean markSupported () {
+ return false; // would be imprecise
+ }
+
+ /**
+ * Resets the Reader.
+ *
+ * @exception IOException if the Reader fails to be reset
+ */
+ public synchronized void reset() throws IOException {
+ if (in == null) {
+ throw new IOException("Stream Closed");
+ }
+ slack = null;
+ in.reset();
+ }
+
+ /**
+ * Closes the Reader.
+ *
+ * @exception IOException if the original Reader fails to be closed
+ */
+ public synchronized void close() throws IOException {
+ if (in != null) {
+ in.close();
+ slack = null;
+ in = null;
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/ReflectUtil.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/ReflectUtil.java
new file mode 100644
index 00000000..88b7911e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/ReflectUtil.java
@@ -0,0 +1,212 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.util;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+import org.apache.tools.ant.BuildException;
+
+/**
+ * Utility class to handle reflection on java objects.
+ * The class contains static methods to call reflection
+ * methods, catch any exceptions, converting them
+ * to BuildExceptions.
+ */
+// CheckStyle:FinalClassCheck OFF - backward compatible
+public class ReflectUtil {
+
+ /** private constructor */
+ private ReflectUtil() {
+ }
+
+ /**
+ * Create an instance of a class using the constructor matching
+ * the given arguments.
+ * @since Ant 1.8.0
+ */
+ public static <T> T newInstance(Class<T> ofClass,
+ Class<?>[] argTypes,
+ Object[] args) {
+ try {
+ Constructor<T> con = ofClass.getConstructor(argTypes);
+ return con.newInstance(args);
+ } catch (Exception t) {
+ throwBuildException(t);
+ return null; // NotReached
+ }
+ }
+
+ /**
+ * Call a method on the object with no parameters.
+ * @param obj the object to invoke the method on.
+ * @param methodName the name of the method to call
+ * @return the object returned by the method
+ */
+ public static Object invoke(Object obj, String methodName) {
+ try {
+ Method method;
+ method = obj.getClass().getMethod(
+ methodName, (Class[]) null);
+ return method.invoke(obj, (Object[]) null);
+ } catch (Exception t) {
+ throwBuildException(t);
+ return null; // NotReached
+ }
+ }
+
+ /**
+ * Call a method on the object with no parameters.
+ * Note: Unlike the invoke method above, this
+ * calls class or static methods, not instance methods.
+ * @param obj the object to invoke the method on.
+ * @param methodName the name of the method to call
+ * @return the object returned by the method
+ */
+ public static Object invokeStatic(Object obj, String methodName) {
+ try {
+ Method method;
+ method = ((Class<?>) obj).getMethod(
+ methodName, (Class[]) null);
+ return method.invoke(obj, (Object[]) null);
+ } catch (Exception t) {
+ throwBuildException(t);
+ return null; // NotReached
+ }
+ }
+
+ /**
+ * Call a method on the object with one argument.
+ * @param obj the object to invoke the method on.
+ * @param methodName the name of the method to call
+ * @param argType the type of argument.
+ * @param arg the value of the argument.
+ * @return the object returned by the method
+ */
+ public static Object invoke(
+ Object obj, String methodName, Class<?> argType, Object arg) {
+ try {
+ Method method;
+ method = obj.getClass().getMethod(
+ methodName, new Class[] {argType});
+ return method.invoke(obj, new Object[] {arg});
+ } catch (Exception t) {
+ throwBuildException(t);
+ return null; // NotReached
+ }
+ }
+
+ /**
+ * Call a method on the object with two argument.
+ * @param obj the object to invoke the method on.
+ * @param methodName the name of the method to call
+ * @param argType1 the type of the first argument.
+ * @param arg1 the value of the first argument.
+ * @param argType2 the type of the second argument.
+ * @param arg2 the value of the second argument.
+ * @return the object returned by the method
+ */
+ public static Object invoke(
+ Object obj, String methodName, Class<?> argType1, Object arg1,
+ Class<?> argType2, Object arg2) {
+ try {
+ Method method;
+ method = obj.getClass().getMethod(
+ methodName, new Class[] {argType1, argType2});
+ return method.invoke(obj, new Object[] {arg1, arg2});
+ } catch (Exception t) {
+ throwBuildException(t);
+ return null; // NotReached
+ }
+ }
+
+ /**
+ * Get the value of a field in an object.
+ * @param obj the object to look at.
+ * @param fieldName the name of the field in the object.
+ * @return the value of the field.
+ * @throws BuildException if there is an error.
+ */
+ public static Object getField(Object obj, String fieldName)
+ throws BuildException {
+ try {
+ Field field = obj.getClass().getDeclaredField(fieldName);
+ field.setAccessible(true);
+ return field.get(obj);
+ } catch (Exception t) {
+ throwBuildException(t);
+ return null; // NotReached
+ }
+ }
+
+ /**
+ * A method to convert an invocationTargetException to
+ * a buildexception and throw it.
+ * @param t the invocation target exception.
+ * @throws BuildException the converted exception.
+ */
+ public static void throwBuildException(Exception t)
+ throws BuildException {
+ throw toBuildException(t);
+ }
+
+ /**
+ * A method to convert an invocationTargetException to
+ * a buildexception.
+ * @param t the invocation target exception.
+ * @return the converted exception.
+ * @since ant 1.7.1
+ */
+ public static BuildException toBuildException(Exception t) {
+ if (t instanceof InvocationTargetException) {
+ Throwable t2 = ((InvocationTargetException) t)
+ .getTargetException();
+ if (t2 instanceof BuildException) {
+ return (BuildException) t2;
+ }
+ return new BuildException(t2);
+ } else {
+ return new BuildException(t);
+ }
+ }
+
+ /**
+ * A method to test if an object responds to a given
+ * message (method call)
+ * @param o the object
+ * @param methodName the method to check for
+ * @return true if the object has the method.
+ * @throws BuildException if there is a problem.
+ */
+ public static boolean respondsTo(Object o, String methodName)
+ throws BuildException {
+ try {
+ Method[] methods = o.getClass().getMethods();
+ for (int i = 0; i < methods.length; i++) {
+ if (methods[i].getName().equals(methodName)) {
+ return true;
+ }
+ }
+ return false;
+ } catch (Exception t) {
+ throw toBuildException(t);
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/ReflectWrapper.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/ReflectWrapper.java
new file mode 100644
index 00000000..e34363ea
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/ReflectWrapper.java
@@ -0,0 +1,99 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.util;
+
+import java.lang.reflect.Constructor;
+
+/**
+ * Utility class to handle reflection on java objects.
+ * The class is a holder class for an object and
+ * uses java reflection to call methods on the objects.
+ * If things go wrong, BuildExceptions are thrown.
+ */
+
+public class ReflectWrapper {
+ private Object obj;
+ /**
+ * Construct a wrapped object using the no arg constructor.
+ * @param loader the classloader to use to construct the class.
+ * @param name the classname of the object to construct.
+ */
+ public ReflectWrapper(ClassLoader loader, String name) {
+ try {
+ Class clazz;
+ clazz = Class.forName(name, true, loader);
+ Constructor constructor;
+ constructor = clazz.getConstructor((Class[]) null);
+ obj = constructor.newInstance((Object[]) null);
+ } catch (Exception t) {
+ ReflectUtil.throwBuildException(t);
+ }
+ }
+
+ /**
+ * Constructor using a passed in object.
+ * @param obj the object to wrap.
+ */
+ public ReflectWrapper(Object obj) {
+ this.obj = obj;
+ }
+
+ /**
+ * @return the wrapped object.
+ */
+ public Object getObject() {
+ return obj;
+ }
+
+ /**
+ * Call a method on the object with no parameters.
+ * @param methodName the name of the method to call
+ * @return the object returned by the method
+ */
+ public Object invoke(String methodName) {
+ return ReflectUtil.invoke(obj, methodName);
+ }
+
+ /**
+ * Call a method on the object with one argument.
+ * @param methodName the name of the method to call
+ * @param argType the type of argument.
+ * @param arg the value of the argument.
+ * @return the object returned by the method
+ */
+ public Object invoke(
+ String methodName, Class argType, Object arg) {
+ return ReflectUtil.invoke(obj, methodName, argType, arg);
+ }
+
+ /**
+ * Call a method on the object with one argument.
+ * @param methodName the name of the method to call
+ * @param argType1 the type of the first argument.
+ * @param arg1 the value of the first argument.
+ * @param argType2 the type of the second argument.
+ * @param arg2 the value of the second argument.
+ * @return the object returned by the method
+ */
+ public Object invoke(
+ String methodName, Class argType1, Object arg1,
+ Class argType2, Object arg2) {
+ return ReflectUtil.invoke(
+ obj, methodName, argType1, arg1, argType2, arg2);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/RegexpPatternMapper.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/RegexpPatternMapper.java
new file mode 100644
index 00000000..fa620d9a
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/RegexpPatternMapper.java
@@ -0,0 +1,159 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.util;
+
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.util.regexp.RegexpMatcher;
+import org.apache.tools.ant.util.regexp.RegexpMatcherFactory;
+import org.apache.tools.ant.util.regexp.RegexpUtil;
+
+/**
+ * Implementation of FileNameMapper that does regular expression
+ * replacements.
+ *
+ */
+public class RegexpPatternMapper implements FileNameMapper {
+
+ private static final int DECIMAL = 10;
+
+ // CheckStyle:VisibilityModifier OFF - bc
+ protected RegexpMatcher reg = null;
+ protected char[] to = null;
+ protected StringBuffer result = new StringBuffer();
+ // CheckStyle:VisibilityModifier ON
+
+ /**
+ * Constructor for RegexpPatternMapper.
+ * @throws BuildException on error.
+ */
+ public RegexpPatternMapper() throws BuildException {
+ reg = (new RegexpMatcherFactory()).newRegexpMatcher();
+ }
+
+ private boolean handleDirSep = false;
+ private int regexpOptions = 0;
+
+ /**
+ * Attribute specifying whether to ignore the difference
+ * between / and \ (the two common directory characters).
+ * @param handleDirSep a boolean, default is false.
+ * @since Ant 1.6.3
+ */
+ public void setHandleDirSep(boolean handleDirSep) {
+ this.handleDirSep = handleDirSep;
+ }
+
+ /**
+ * Attribute specifying whether to ignore the case difference
+ * in the names.
+ *
+ * @param caseSensitive a boolean, default is false.
+ * @since Ant 1.6.3
+ */
+ public void setCaseSensitive(boolean caseSensitive) {
+ regexpOptions = RegexpUtil.asOptions(caseSensitive);
+ }
+
+ /**
+ * Sets the &quot;from&quot; pattern. Required.
+ * @param from the from pattern.
+ * @throws BuildException on error.
+ */
+ public void setFrom(String from) throws BuildException {
+ if (from != null) {
+ try {
+ reg.setPattern(from);
+ } catch (NoClassDefFoundError e) {
+ // depending on the implementation the actual RE won't
+ // get instantiated in the constructor.
+ throw new BuildException("Cannot load regular expression matcher",
+ e);
+ }
+ } else {
+ throw new BuildException("this mapper requires a 'from' attribute");
+ }
+ }
+
+ /**
+ * Sets the &quot;to&quot; pattern. Required.
+ * @param to the to pattern.
+ * @throws BuildException on error.
+ */
+ public void setTo(String to) {
+ if (to != null) {
+ this.to = to.toCharArray();
+ } else {
+ throw new BuildException("this mapper requires a 'to' attribute");
+ }
+ }
+
+ /**
+ * Returns null if the source file name doesn't match the
+ * &quot;from&quot; pattern, an one-element array containing the
+ * translated file otherwise.
+ * @param sourceFileName the source file name
+ * @return a one-element array containing the translated file or
+ * null if the to pattern did not match
+ */
+ public String[] mapFileName(String sourceFileName) {
+ if (handleDirSep) {
+ if (sourceFileName.indexOf("\\") != -1) {
+ sourceFileName = sourceFileName.replace('\\', '/');
+ }
+ }
+ if (reg == null || to == null
+ || !reg.matches(sourceFileName, regexpOptions)) {
+ return null;
+ }
+ return new String[] {replaceReferences(sourceFileName)};
+ }
+
+ /**
+ * Replace all backreferences in the to pattern with the matched
+ * groups of the source.
+ * @param source the source file name.
+ * @return the translated file name.
+ */
+ protected String replaceReferences(String source) {
+ Vector v = reg.getGroups(source, regexpOptions);
+
+ result.setLength(0);
+ for (int i = 0; i < to.length; i++) {
+ if (to[i] == '\\') {
+ if (++i < to.length) {
+ int value = Character.digit(to[i], DECIMAL);
+ if (value > -1) {
+ result.append((String) v.elementAt(value));
+ } else {
+ result.append(to[i]);
+ }
+ } else {
+ // TODO - should throw an exception instead?
+ result.append('\\');
+ }
+ } else {
+ result.append(to[i]);
+ }
+ }
+ return result.substring(0);
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/ResourceUtils.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/ResourceUtils.java
new file mode 100644
index 00000000..6397f714
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/ResourceUtils.java
@@ -0,0 +1,860 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.util;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Reader;
+import java.nio.channels.FileChannel;
+import java.util.Arrays;
+import java.util.Vector;
+
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.ProjectComponent;
+import org.apache.tools.ant.filters.util.ChainReaderHelper;
+import org.apache.tools.ant.types.FilterSetCollection;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.ResourceCollection;
+import org.apache.tools.ant.types.ResourceFactory;
+import org.apache.tools.ant.types.TimeComparison;
+import org.apache.tools.ant.types.resources.Appendable;
+import org.apache.tools.ant.types.resources.FileProvider;
+import org.apache.tools.ant.types.resources.FileResource;
+import org.apache.tools.ant.types.resources.Resources;
+import org.apache.tools.ant.types.resources.Restrict;
+import org.apache.tools.ant.types.resources.StringResource;
+import org.apache.tools.ant.types.resources.Touchable;
+import org.apache.tools.ant.types.resources.Union;
+import org.apache.tools.ant.types.resources.selectors.Date;
+import org.apache.tools.ant.types.resources.selectors.ResourceSelector;
+import org.apache.tools.ant.types.selectors.SelectorUtils;
+
+// CheckStyle:HideUtilityClassConstructorCheck OFF - bc
+
+/**
+ * This class provides utility methods to process Resources.
+ *
+ * @since Ant 1.5.2
+ */
+public class ResourceUtils {
+
+ /** Utilities used for file operations */
+ private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+
+ /**
+ * Name of charset "ISO Latin Alphabet No. 1, a.k.a. ISO-LATIN-1".
+ *
+ * @since Ant 1.8.1
+ */
+ public static final String ISO_8859_1 = "ISO-8859-1";
+
+ private static final long MAX_IO_CHUNK_SIZE = 16*1024*1024; // 16 MB
+
+ /**
+ * Tells which source files should be reprocessed based on the
+ * last modification date of target files.
+ * @param logTo where to send (more or less) interesting output.
+ * @param source array of resources bearing relative path and last
+ * modification date.
+ * @param mapper filename mapper indicating how to find the target
+ * files.
+ * @param targets object able to map as a resource a relative path
+ * at <b>destination</b>.
+ * @return array containing the source files which need to be
+ * copied or processed, because the targets are out of date or do
+ * not exist.
+ */
+ public static Resource[] selectOutOfDateSources(final ProjectComponent logTo,
+ final Resource[] source,
+ final FileNameMapper mapper,
+ final ResourceFactory targets) {
+ return selectOutOfDateSources(logTo, source, mapper, targets,
+ FILE_UTILS.getFileTimestampGranularity());
+ }
+
+ /**
+ * Tells which source files should be reprocessed based on the
+ * last modification date of target files.
+ * @param logTo where to send (more or less) interesting output.
+ * @param source array of resources bearing relative path and last
+ * modification date.
+ * @param mapper filename mapper indicating how to find the target
+ * files.
+ * @param targets object able to map as a resource a relative path
+ * at <b>destination</b>.
+ * @param granularity The number of milliseconds leeway to give
+ * before deciding a target is out of date.
+ * @return array containing the source files which need to be
+ * copied or processed, because the targets are out of date or do
+ * not exist.
+ * @since Ant 1.6.2
+ */
+ public static Resource[] selectOutOfDateSources(final ProjectComponent logTo,
+ final Resource[] source,
+ final FileNameMapper mapper,
+ final ResourceFactory targets,
+ final long granularity) {
+ final Union u = new Union();
+ u.addAll(Arrays.asList(source));
+ final ResourceCollection rc
+ = selectOutOfDateSources(logTo, u, mapper, targets, granularity);
+ return rc.size() == 0 ? new Resource[0] : ((Union) rc).listResources();
+ }
+
+ /**
+ * Tells which sources should be reprocessed based on the
+ * last modification date of targets.
+ * @param logTo where to send (more or less) interesting output.
+ * @param source ResourceCollection.
+ * @param mapper filename mapper indicating how to find the target Resources.
+ * @param targets object able to map a relative path as a Resource.
+ * @param granularity The number of milliseconds leeway to give
+ * before deciding a target is out of date.
+ * @return ResourceCollection.
+ * @since Ant 1.7
+ */
+ public static ResourceCollection selectOutOfDateSources(final ProjectComponent logTo,
+ final ResourceCollection source,
+ final FileNameMapper mapper,
+ final ResourceFactory targets,
+ final long granularity) {
+ logFuture(logTo, source, granularity);
+ final ResourceSelectorProvider p =
+ new ResourceSelectorProvider() {
+ public ResourceSelector
+ getTargetSelectorForSource(final Resource sr) {
+ return new ResourceSelector() {
+ public boolean isSelected(final Resource target) {
+ /* Extra I/O, probably wasted:
+ if (target.isDirectory()) {
+ return false;
+ }
+ */
+ return SelectorUtils.isOutOfDate(sr, target,
+ granularity);
+ }
+ };
+ }
+ };
+ return selectSources(logTo, source, mapper, targets, p);
+ }
+
+ /**
+ * Tells which sources should be reprocessed because the given
+ * selector selects at least one target.
+ *
+ * @param logTo where to send (more or less) interesting output.
+ * @param source ResourceCollection.
+ * @param mapper filename mapper indicating how to find the target Resources.
+ * @param targets object able to map a relative path as a Resource.
+ * @param selector returns a selector that is applied to target
+ * files. If it selects at least one target the source will be
+ * added to the returned collection.
+ * @return ResourceCollection.
+ * @since Ant 1.8.0
+ */
+ public static ResourceCollection selectSources(final ProjectComponent logTo,
+ ResourceCollection source,
+ final FileNameMapper mapper,
+ final ResourceFactory targets,
+ final ResourceSelectorProvider selector) {
+ if (source.size() == 0) {
+ logTo.log("No sources found.", Project.MSG_VERBOSE);
+ return Resources.NONE;
+ }
+ source = Union.getInstance(source);
+
+ final Union result = new Union();
+ for (final Resource sr : source) {
+ String srName = sr.getName();
+ srName = srName == null
+ ? srName : srName.replace('/', File.separatorChar);
+
+ String[] targetnames = null;
+ try {
+ targetnames = mapper.mapFileName(srName);
+ } catch (final Exception e) {
+ logTo.log("Caught " + e + " mapping resource " + sr,
+ Project.MSG_VERBOSE);
+ }
+ if (targetnames == null || targetnames.length == 0) {
+ logTo.log(sr + " skipped - don\'t know how to handle it",
+ Project.MSG_VERBOSE);
+ continue;
+ }
+ for (int i = 0; i < targetnames.length; i++) {
+ if (targetnames[i] == null) {
+ targetnames[i] = "(no name)";
+ }
+ }
+ final Union targetColl = new Union();
+ for (int i = 0; i < targetnames.length; i++) {
+ targetColl.add(targets.getResource(
+ targetnames[i].replace(File.separatorChar, '/')));
+ }
+ //find the out-of-date targets:
+ final Restrict r = new Restrict();
+ r.add(selector.getTargetSelectorForSource(sr));
+ r.add(targetColl);
+ if (r.size() > 0) {
+ result.add(sr);
+ final Resource t = r.iterator().next();
+ logTo.log(sr.getName() + " added as " + t.getName()
+ + (t.isExists() ? " is outdated." : " doesn\'t exist."),
+ Project.MSG_VERBOSE);
+ continue;
+ }
+ //log uptodateness of all targets:
+ logTo.log(sr.getName()
+ + " omitted as " + targetColl.toString()
+ + (targetColl.size() == 1 ? " is" : " are ")
+ + " up to date.", Project.MSG_VERBOSE);
+ }
+ return result;
+ }
+
+ /**
+ * Convenience method to copy content from one Resource to another.
+ * No filtering is performed.
+ *
+ * @param source the Resource to copy from.
+ * Must not be <code>null</code>.
+ * @param dest the Resource to copy to.
+ * Must not be <code>null</code>.
+ *
+ * @throws IOException if the copying fails.
+ *
+ * @since Ant 1.7
+ */
+ public static void copyResource(final Resource source, final Resource dest) throws IOException {
+ copyResource(source, dest, null);
+ }
+
+ /**
+ * Convenience method to copy content from one Resource to another.
+ * No filtering is performed.
+ *
+ * @param source the Resource to copy from.
+ * Must not be <code>null</code>.
+ * @param dest the Resource to copy to.
+ * Must not be <code>null</code>.
+ * @param project the project instance.
+ *
+ * @throws IOException if the copying fails.
+ *
+ * @since Ant 1.7
+ */
+ public static void copyResource(final Resource source, final Resource dest, final Project project)
+ throws IOException {
+ copyResource(source, dest, null, null, false,
+ false, null, null, project);
+ }
+
+ // CheckStyle:ParameterNumberCheck OFF - bc
+ /**
+ * Convenience method to copy content from one Resource to another
+ * specifying whether token filtering must be used, whether filter chains
+ * must be used, whether newer destination files may be overwritten and
+ * whether the last modified time of <code>dest</code> file should be made
+ * equal to the last modified time of <code>source</code>.
+ *
+ * @param source the Resource to copy from.
+ * Must not be <code>null</code>.
+ * @param dest the Resource to copy to.
+ * Must not be <code>null</code>.
+ * @param filters the collection of filters to apply to this copy.
+ * @param filterChains filterChains to apply during the copy.
+ * @param overwrite Whether or not the destination Resource should be
+ * overwritten if it already exists.
+ * @param preserveLastModified Whether or not the last modified time of
+ * the destination Resource should be set to that
+ * of the source.
+ * @param inputEncoding the encoding used to read the files.
+ * @param outputEncoding the encoding used to write the files.
+ * @param project the project instance.
+ *
+ * @throws IOException if the copying fails.
+ *
+ * @since Ant 1.7
+ */
+ public static void copyResource(final Resource source, final Resource dest,
+ final FilterSetCollection filters, final Vector filterChains,
+ final boolean overwrite, final boolean preserveLastModified,
+ final String inputEncoding, final String outputEncoding,
+ final Project project)
+ throws IOException {
+ copyResource(source, dest, filters, filterChains, overwrite, preserveLastModified, false, inputEncoding, outputEncoding, project);
+ }
+
+ // CheckStyle:ParameterNumberCheck OFF - bc
+ /**
+ * Convenience method to copy content from one Resource to another
+ * specifying whether token filtering must be used, whether filter chains
+ * must be used, whether newer destination files may be overwritten and
+ * whether the last modified time of <code>dest</code> file should be made
+ * equal to the last modified time of <code>source</code>.
+ *
+ * @param source the Resource to copy from.
+ * Must not be <code>null</code>.
+ * @param dest the Resource to copy to.
+ * Must not be <code>null</code>.
+ * @param filters the collection of filters to apply to this copy.
+ * @param filterChains filterChains to apply during the copy.
+ * @param overwrite Whether or not the destination Resource should be
+ * overwritten if it already exists.
+ * @param preserveLastModified Whether or not the last modified time of
+ * the destination Resource should be set to that
+ * of the source.
+ * @param append Whether to append to an Appendable Resource.
+ * @param inputEncoding the encoding used to read the files.
+ * @param outputEncoding the encoding used to write the files.
+ * @param project the project instance.
+ *
+ * @throws IOException if the copying fails.
+ *
+ * @since Ant 1.8
+ */
+ public static void copyResource(final Resource source, final Resource dest,
+ final FilterSetCollection filters, final Vector filterChains,
+ final boolean overwrite, final boolean preserveLastModified,
+ final boolean append,
+ final String inputEncoding, final String outputEncoding,
+ final Project project)
+ throws IOException {
+ copyResource(source, dest, filters, filterChains, overwrite,
+ preserveLastModified, append, inputEncoding,
+ outputEncoding, project, /* force: */ false);
+ }
+
+ /**
+ * Convenience method to copy content from one Resource to another
+ * specifying whether token filtering must be used, whether filter chains
+ * must be used, whether newer destination files may be overwritten and
+ * whether the last modified time of <code>dest</code> file should be made
+ * equal to the last modified time of <code>source</code>.
+ *
+ * @param source the Resource to copy from.
+ * Must not be <code>null</code>.
+ * @param dest the Resource to copy to.
+ * Must not be <code>null</code>.
+ * @param filters the collection of filters to apply to this copy.
+ * @param filterChains filterChains to apply during the copy.
+ * @param overwrite Whether or not the destination Resource should be
+ * overwritten if it already exists.
+ * @param preserveLastModified Whether or not the last modified time of
+ * the destination Resource should be set to that
+ * of the source.
+ * @param append Whether to append to an Appendable Resource.
+ * @param inputEncoding the encoding used to read the files.
+ * @param outputEncoding the encoding used to write the files.
+ * @param project the project instance.
+ * @param force whether read-only target files will be overwritten
+ *
+ * @throws IOException if the copying fails.
+ *
+ * @since Ant 1.8.2
+ */
+ public static void copyResource(final Resource source, final Resource dest,
+ final FilterSetCollection filters, final Vector filterChains,
+ final boolean overwrite, final boolean preserveLastModified,
+ final boolean append,
+ final String inputEncoding, final String outputEncoding,
+ final Project project, final boolean force)
+ throws IOException {
+ if (!(overwrite || SelectorUtils.isOutOfDate(source, dest, FileUtils.getFileUtils()
+ .getFileTimestampGranularity()))) {
+ return;
+ }
+ final boolean filterSetsAvailable = (filters != null
+ && filters.hasFilters());
+ final boolean filterChainsAvailable = (filterChains != null
+ && filterChains.size() > 0);
+ String effectiveInputEncoding = null;
+ if (source instanceof StringResource) {
+ effectiveInputEncoding = ((StringResource) source).getEncoding();
+ } else {
+ effectiveInputEncoding = inputEncoding;
+ }
+ File destFile = null;
+ if (dest.as(FileProvider.class) != null) {
+ destFile = dest.as(FileProvider.class).getFile();
+ }
+ if (destFile != null && destFile.isFile() && !destFile.canWrite()) {
+ if (!force) {
+ throw new ReadOnlyTargetFileException(destFile);
+ } else if (!FILE_UTILS.tryHardToDelete(destFile)) {
+ throw new IOException("failed to delete read-only "
+ + "destination file " + destFile);
+ }
+ }
+
+ if (filterSetsAvailable) {
+ copyWithFilterSets(source, dest, filters, filterChains,
+ filterChainsAvailable, append,
+ effectiveInputEncoding, outputEncoding,
+ project);
+ } else if (filterChainsAvailable
+ || (effectiveInputEncoding != null
+ && !effectiveInputEncoding.equals(outputEncoding))
+ || (effectiveInputEncoding == null && outputEncoding != null)) {
+ copyWithFilterChainsOrTranscoding(source, dest, filterChains,
+ filterChainsAvailable, append,
+ effectiveInputEncoding,
+ outputEncoding, project);
+ } else {
+ boolean copied = false;
+ if (source.as(FileProvider.class) != null
+ && destFile != null && !append) {
+ final File sourceFile =
+ source.as(FileProvider.class).getFile();
+ try {
+ copyUsingFileChannels(sourceFile, destFile);
+ copied = true;
+ } catch (final IOException ex) {
+ String msg = "Attempt to copy " + sourceFile
+ + " to " + destFile + " using NIO Channels"
+ + " failed due to '" + ex.getMessage()
+ + "'. Falling back to streams.";
+ if (project != null) {
+ project.log(msg, Project.MSG_WARN);
+ } else {
+ System.err.println(msg);
+ }
+ }
+ }
+ if (!copied) {
+ copyUsingStreams(source, dest, append, project);
+ }
+ }
+ if (preserveLastModified) {
+ final Touchable t = dest.as(Touchable.class);
+ if (t != null) {
+ setLastModified(t, source.getLastModified());
+ }
+ }
+ }
+ // CheckStyle:ParameterNumberCheck ON
+
+ /**
+ * Set the last modified time of an object implementing
+ * org.apache.tools.ant.types.resources.Touchable .
+ *
+ * @param t the Touchable whose modified time is to be set.
+ * @param time the time to which the last modified time is to be set.
+ * if this is -1, the current time is used.
+ * @since Ant 1.7
+ */
+ public static void setLastModified(final Touchable t, final long time) {
+ t.touch((time < 0) ? System.currentTimeMillis() : time);
+ }
+
+ /**
+ * Compares the contents of two Resources.
+ *
+ * @param r1 the Resource whose content is to be compared.
+ * @param r2 the other Resource whose content is to be compared.
+ * @param text true if the content is to be treated as text and
+ * differences in kind of line break are to be ignored.
+ *
+ * @return true if the content of the Resources is the same.
+ *
+ * @throws IOException if the Resources cannot be read.
+ * @since Ant 1.7
+ */
+ public static boolean contentEquals(final Resource r1, final Resource r2, final boolean text) throws IOException {
+ if (r1.isExists() != r2.isExists()) {
+ return false;
+ }
+ if (!r1.isExists()) {
+ // two not existing files are equal
+ return true;
+ }
+ // should the following two be switched? If r1 and r2 refer to the same file,
+ // isn't their content equal regardless of whether that file is a directory?
+ if (r1.isDirectory() || r2.isDirectory()) {
+ // don't want to compare directory contents for now
+ return false;
+ }
+ if (r1.equals(r2)) {
+ return true;
+ }
+ if (!text) {
+ final long s1 = r1.getSize();
+ final long s2 = r2.getSize();
+ if (s1 != Resource.UNKNOWN_SIZE && s2 != Resource.UNKNOWN_SIZE
+ && s1 != s2) {
+ return false;
+ }
+ }
+ return compareContent(r1, r2, text) == 0;
+ }
+
+ /**
+ * Compare the content of two Resources. A nonexistent Resource's
+ * content is "less than" that of an existing Resource; a directory-type
+ * Resource's content is "less than" that of a file-type Resource.
+ * @param r1 the Resource whose content is to be compared.
+ * @param r2 the other Resource whose content is to be compared.
+ * @param text true if the content is to be treated as text and
+ * differences in kind of line break are to be ignored.
+ * @return a negative integer, zero, or a positive integer as the first
+ * argument is less than, equal to, or greater than the second.
+ * @throws IOException if the Resources cannot be read.
+ * @since Ant 1.7
+ */
+ public static int compareContent(final Resource r1, final Resource r2, final boolean text) throws IOException {
+ if (r1.equals(r2)) {
+ return 0;
+ }
+ final boolean e1 = r1.isExists();
+ final boolean e2 = r2.isExists();
+ if (!(e1 || e2)) {
+ return 0;
+ }
+ if (e1 != e2) {
+ return e1 ? 1 : -1;
+ }
+ final boolean d1 = r1.isDirectory();
+ final boolean d2 = r2.isDirectory();
+ if (d1 && d2) {
+ return 0;
+ }
+ if (d1 || d2) {
+ return d1 ? -1 : 1;
+ }
+ return text ? textCompare(r1, r2) : binaryCompare(r1, r2);
+ }
+
+ /**
+ * Convenience method to turn any fileProvider into a basic
+ * FileResource with the file's immediate parent as the basedir,
+ * for tasks that need one.
+ * @param fileProvider input
+ * @return fileProvider if it is a FileResource instance, or a new
+ * FileResource with fileProvider's file.
+ * @since Ant 1.8
+ */
+ public static FileResource asFileResource(final FileProvider fileProvider) {
+ if (fileProvider instanceof FileResource || fileProvider == null) {
+ return (FileResource) fileProvider;
+ }
+ final FileResource result = new FileResource(fileProvider.getFile());
+ result.setProject(Project.getProject(fileProvider));
+ return result;
+ }
+
+ /**
+ * Binary compares the contents of two Resources.
+ * <p>
+ * simple but sub-optimal comparison algorithm. written for working
+ * rather than fast. Better would be a block read into buffers followed
+ * by long comparisons apart from the final 1-7 bytes.
+ * </p>
+ *
+ * @param r1 the Resource whose content is to be compared.
+ * @param r2 the other Resource whose content is to be compared.
+ * @return a negative integer, zero, or a positive integer as the first
+ * argument is less than, equal to, or greater than the second.
+ * @throws IOException if the Resources cannot be read.
+ * @since Ant 1.7
+ */
+ private static int binaryCompare(final Resource r1, final Resource r2) throws IOException {
+ InputStream in1 = null;
+ InputStream in2 = null;
+ try {
+ in1 = new BufferedInputStream(r1.getInputStream());
+ in2 = new BufferedInputStream(r2.getInputStream());
+
+ for (int b1 = in1.read(); b1 != -1; b1 = in1.read()) {
+ final int b2 = in2.read();
+ if (b1 != b2) {
+ return b1 > b2 ? 1 : -1;
+ }
+ }
+ return in2.read() == -1 ? 0 : -1;
+ } finally {
+ FileUtils.close(in1);
+ FileUtils.close(in2);
+ }
+ }
+
+ /**
+ * Text compares the contents of two Resources.
+ * Ignores different kinds of line endings.
+ * @param r1 the Resource whose content is to be compared.
+ * @param r2 the other Resource whose content is to be compared.
+ * @return a negative integer, zero, or a positive integer as the first
+ * argument is less than, equal to, or greater than the second.
+ * @throws IOException if the Resources cannot be read.
+ * @since Ant 1.7
+ */
+ private static int textCompare(final Resource r1, final Resource r2) throws IOException {
+ BufferedReader in1 = null;
+ BufferedReader in2 = null;
+ try {
+ in1 = new BufferedReader(new InputStreamReader(r1.getInputStream()));
+ in2 = new BufferedReader(new InputStreamReader(r2.getInputStream()));
+
+ String expected = in1.readLine();
+ while (expected != null) {
+ final String actual = in2.readLine();
+ if (!expected.equals(actual)) {
+ if (actual == null) {
+ return 1;
+ }
+ return expected.compareTo(actual);
+ }
+ expected = in1.readLine();
+ }
+ return in2.readLine() == null ? 0 : -1;
+ } finally {
+ FileUtils.close(in1);
+ FileUtils.close(in2);
+ }
+ }
+
+ /**
+ * Log which Resources (if any) have been modified in the future.
+ * @param logTo the ProjectComponent to do the logging.
+ * @param rc the collection of Resources to check.
+ * @param granularity the timestamp granularity to use.
+ * @since Ant 1.7
+ */
+ private static void logFuture(final ProjectComponent logTo,
+ final ResourceCollection rc, final long granularity) {
+ final long now = System.currentTimeMillis() + granularity;
+ final Date sel = new Date();
+ sel.setMillis(now);
+ sel.setWhen(TimeComparison.AFTER);
+ final Restrict future = new Restrict();
+ future.add(sel);
+ future.add(rc);
+ for (final Resource r : future) {
+ logTo.log("Warning: " + r.getName() + " modified in the future.", Project.MSG_WARN);
+ }
+ }
+
+ private static void copyWithFilterSets(final Resource source, final Resource dest,
+ final FilterSetCollection filters,
+ final Vector filterChains,
+ final boolean filterChainsAvailable,
+ final boolean append, final String inputEncoding,
+ final String outputEncoding,
+ final Project project)
+ throws IOException {
+ BufferedReader in = null;
+ BufferedWriter out = null;
+ try {
+ InputStreamReader isr = null;
+ if (inputEncoding == null) {
+ isr = new InputStreamReader(source.getInputStream());
+ } else {
+ isr = new InputStreamReader(source.getInputStream(),
+ inputEncoding);
+ }
+ in = new BufferedReader(isr);
+ final OutputStream os = getOutputStream(dest, append, project);
+ OutputStreamWriter osw;
+ if (outputEncoding == null) {
+ osw = new OutputStreamWriter(os);
+ } else {
+ osw = new OutputStreamWriter(os, outputEncoding);
+ }
+ out = new BufferedWriter(osw);
+ if (filterChainsAvailable) {
+ final ChainReaderHelper crh = new ChainReaderHelper();
+ crh.setBufferSize(FileUtils.BUF_SIZE);
+ crh.setPrimaryReader(in);
+ crh.setFilterChains(filterChains);
+ crh.setProject(project);
+ final Reader rdr = crh.getAssembledReader();
+ in = new BufferedReader(rdr);
+ }
+ final LineTokenizer lineTokenizer = new LineTokenizer();
+ lineTokenizer.setIncludeDelims(true);
+ String newline = null;
+ String line = lineTokenizer.getToken(in);
+ while (line != null) {
+ if (line.length() == 0) {
+ // this should not happen, because the lines are
+ // returned with the end of line delimiter
+ out.newLine();
+ } else {
+ newline = filters.replaceTokens(line);
+ out.write(newline);
+ }
+ line = lineTokenizer.getToken(in);
+ }
+ } finally {
+ FileUtils.close(out);
+ FileUtils.close(in);
+ }
+ }
+
+ private static void copyWithFilterChainsOrTranscoding(final Resource source,
+ final Resource dest,
+ final Vector filterChains,
+ final boolean filterChainsAvailable,
+ final boolean append,
+ final String inputEncoding,
+ final String outputEncoding,
+ final Project project)
+ throws IOException {
+ BufferedReader in = null;
+ BufferedWriter out = null;
+ try {
+ InputStreamReader isr = null;
+ if (inputEncoding == null) {
+ isr = new InputStreamReader(source.getInputStream());
+ } else {
+ isr = new InputStreamReader(source.getInputStream(),
+ inputEncoding);
+ }
+ in = new BufferedReader(isr);
+ final OutputStream os = getOutputStream(dest, append, project);
+ OutputStreamWriter osw;
+ if (outputEncoding == null) {
+ osw = new OutputStreamWriter(os);
+ } else {
+ osw = new OutputStreamWriter(os, outputEncoding);
+ }
+ out = new BufferedWriter(osw);
+ if (filterChainsAvailable) {
+ final ChainReaderHelper crh = new ChainReaderHelper();
+ crh.setBufferSize(FileUtils.BUF_SIZE);
+ crh.setPrimaryReader(in);
+ crh.setFilterChains(filterChains);
+ crh.setProject(project);
+ final Reader rdr = crh.getAssembledReader();
+ in = new BufferedReader(rdr);
+ }
+ final char[] buffer = new char[FileUtils.BUF_SIZE];
+ while (true) {
+ final int nRead = in.read(buffer, 0, buffer.length);
+ if (nRead == -1) {
+ break;
+ }
+ out.write(buffer, 0, nRead);
+ }
+ } finally {
+ FileUtils.close(out);
+ FileUtils.close(in);
+ }
+ }
+
+ private static void copyUsingFileChannels(final File sourceFile,
+ final File destFile)
+ throws IOException {
+
+ final File parent = destFile.getParentFile();
+ if (parent != null && !parent.isDirectory()
+ && !(parent.mkdirs() || parent.isDirectory())) {
+ throw new IOException("failed to create the parent directory"
+ + " for " + destFile);
+ }
+
+ FileInputStream in = null;
+ FileOutputStream out = null;
+ FileChannel srcChannel = null;
+ FileChannel destChannel = null;
+
+ try {
+ in = new FileInputStream(sourceFile);
+ out = new FileOutputStream(destFile);
+
+ srcChannel = in.getChannel();
+ destChannel = out.getChannel();
+
+ long position = 0;
+ final long count = srcChannel.size();
+ while (position < count) {
+ final long chunk = Math.min(MAX_IO_CHUNK_SIZE, count - position);
+ position +=
+ destChannel.transferFrom(srcChannel, position, chunk);
+ }
+ } finally {
+ FileUtils.close(srcChannel);
+ FileUtils.close(destChannel);
+ FileUtils.close(out);
+ FileUtils.close(in);
+ }
+ }
+
+ private static void copyUsingStreams(final Resource source, final Resource dest,
+ final boolean append, final Project project)
+ throws IOException {
+ InputStream in = null;
+ OutputStream out = null;
+ try {
+ in = source.getInputStream();
+ out = getOutputStream(dest, append, project);
+
+ final byte[] buffer = new byte[FileUtils.BUF_SIZE];
+ int count = 0;
+ do {
+ out.write(buffer, 0, count);
+ count = in.read(buffer, 0, buffer.length);
+ } while (count != -1);
+ } finally {
+ FileUtils.close(out);
+ FileUtils.close(in);
+ }
+ }
+
+ private static OutputStream getOutputStream(final Resource resource, final boolean append, final Project project)
+ throws IOException {
+ if (append) {
+ final Appendable a = resource.as(Appendable.class);
+ if (a != null) {
+ return a.getAppendOutputStream();
+ }
+ String msg = "Appendable OutputStream not available for non-appendable resource "
+ + resource + "; using plain OutputStream";
+ if (project != null) {
+ project.log(msg, Project.MSG_VERBOSE);
+ } else {
+ System.out.println(msg);
+ }
+ }
+ return resource.getOutputStream();
+ }
+
+ public interface ResourceSelectorProvider {
+ ResourceSelector getTargetSelectorForSource(Resource source);
+ }
+
+ /**
+ * @since Ant 1.9.4
+ */
+ public static class ReadOnlyTargetFileException extends IOException {
+ private static final long serialVersionUID = 1L;
+
+ public ReadOnlyTargetFileException(final File destFile) {
+ super("can't write to read-only destination file " + destFile);
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/RetryHandler.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/RetryHandler.java
new file mode 100644
index 00000000..dd62bc27
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/RetryHandler.java
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.util;
+
+import java.io.IOException;
+
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+
+/**
+ * A simple utility class to take a piece of code (that implements
+ * <code>Retryable</code> interface) and executes that with possibility to
+ * retry the execution in case of IOException.
+ */
+public class RetryHandler {
+
+ private int retriesAllowed = 0;
+ private Task task;
+
+ /**
+ * Create a new RetryingHandler.
+ *
+ * @param retriesAllowed how many times to retry
+ * @param task the Ant task that is is executed from, used for logging only
+ */
+ public RetryHandler(int retriesAllowed, Task task) {
+ this.retriesAllowed = retriesAllowed;
+ this.task = task;
+ }
+
+ /**
+ * Execute the <code>Retryable</code> code with specified number of retries.
+ *
+ * @param exe the code to execute
+ * @param desc some descriptive text for this piece of code, used for logging
+ * @throws IOException if the number of retries has exceeded the allowed limit
+ */
+ public void execute(Retryable exe, String desc) throws IOException {
+ int retries = 0;
+ while (true) {
+ try {
+ exe.execute();
+ break;
+ } catch (IOException e) {
+ retries++;
+ if (retries > this.retriesAllowed && this.retriesAllowed > -1) {
+ task.log("try #" + retries + ": IO error ("
+ + desc + "), number of maximum retries reached ("
+ + this.retriesAllowed + "), giving up", Project.MSG_WARN);
+ throw e;
+ } else {
+ task.log("try #" + retries + ": IO error (" + desc
+ + "), retrying", Project.MSG_WARN);
+ }
+ }
+ }
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/Retryable.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/Retryable.java
new file mode 100644
index 00000000..537244a1
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/Retryable.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.util;
+
+import java.io.IOException;
+
+
+/**
+ * Simple interface for executing a piece of code. Used for writing anonymous inner
+ * classes in FTP task for retry-on-IOException behaviour.
+ *
+ * @see RetryHandler
+ */
+public interface Retryable {
+ /** The value to use to never give up. */
+ int RETRY_FOREVER = -1;
+ /**
+ * Called to execute the code.
+ * @throws IOException if there is a problem.
+ */
+ void execute() throws IOException;
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/ScriptFixBSFPath.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/ScriptFixBSFPath.java
new file mode 100644
index 00000000..ca76e56b
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/ScriptFixBSFPath.java
@@ -0,0 +1,147 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.util;
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.tools.ant.AntClassLoader;
+import org.apache.tools.ant.BuildException;
+
+
+/**
+ * A class to modify a classloader to
+ * support BSF language support.
+ */
+public class ScriptFixBSFPath {
+ private static final String UTIL_OPTIONAL_PACKAGE
+ = "org.apache.tools.ant.util.optional";
+
+ private static final String BSF_PACKAGE = "org.apache.bsf";
+ private static final String BSF_MANAGER = BSF_PACKAGE + ".BSFManager";
+ private static final String BSF_SCRIPT_RUNNER
+ = UTIL_OPTIONAL_PACKAGE + ".ScriptRunner";
+
+ /**
+ * The following are languages that have
+ * scripting engines embedded in bsf.jar.
+ * The array is converted to a map of
+ * languagename->classname.
+ */
+ private static final String[] BSF_LANGUAGES =
+ new String[] {
+ "js", "org.mozilla.javascript.Scriptable",
+ "javascript", "org.mozilla.javascript.Scriptable",
+ "jacl", "tcl.lang.Interp",
+ "netrexx", "netrexx.lang.Rexx",
+ "nrx", "netrexx.lang.Rexx",
+ "jython", "org.python.core.Py",
+ "py", "org.python.core.Py",
+ "xslt", "org.apache.xpath.objects.XObject"};
+
+ /** A map of languages for which the engine in located in bsf */
+ private static final Map BSF_LANGUAGE_MAP = new HashMap();
+ static {
+ for (int i = 0; i < BSF_LANGUAGES.length; i = i + 2) {
+ BSF_LANGUAGE_MAP.put(BSF_LANGUAGES[i], BSF_LANGUAGES[i + 1]);
+ }
+ }
+
+ private File getClassSource(ClassLoader loader, String className) {
+ return LoaderUtils.getResourceSource(
+ loader,
+ LoaderUtils.classNameToResource(className));
+ }
+
+ private File getClassSource(String className) {
+ return getClassSource(getClass().getClassLoader(), className);
+ }
+
+ /**
+ * Check if need to mess about with the classloader.
+ * The class loader will need to be modified for two
+ * reasons:
+ * <ol>
+ * <li>language is at a higher level than bsf for engines in bsf,
+ * move bsf.
+ * </li>
+ * <li>bsf is at a higher level than oata.util.optional.ScriptRunner
+ * </li>
+ * </ol>
+ *
+ * Assume a simple model for the loader:
+ * thisloader&lt;-customloader
+ * or
+ * thisloader
+ *
+ * @param loader the classloader to fix.
+ * @param language the language to use.
+ */
+ public void fixClassLoader(ClassLoader loader, String language) {
+ if (loader == getClass().getClassLoader()
+ || !(loader instanceof AntClassLoader)) {
+ return;
+ }
+ ClassLoader myLoader = getClass().getClassLoader();
+ AntClassLoader fixLoader = (AntClassLoader) loader;
+
+ // Check for location of bsf in this classloader
+ File bsfSource = getClassSource(BSF_MANAGER);
+
+ // If bsf is not in the classloader for this, need to move
+ // runner.
+ boolean needMoveRunner = (bsfSource == null);
+
+ // Check for location of language
+ String languageClassName = (String) BSF_LANGUAGE_MAP.get(language);
+
+ // Check if need to need to move bsf
+ boolean needMoveBsf =
+ bsfSource != null
+ && languageClassName != null
+ && !LoaderUtils.classExists(myLoader, languageClassName)
+ && LoaderUtils.classExists(loader, languageClassName);
+
+ // Update need to move runner
+ needMoveRunner = needMoveRunner || needMoveBsf;
+
+ // Check if bsf in place
+ if (bsfSource == null) {
+ bsfSource = getClassSource(loader, BSF_MANAGER);
+ }
+
+ if (bsfSource == null) {
+ throw new BuildException(
+ "Unable to find BSF classes for scripting");
+ }
+
+ if (needMoveBsf) {
+ fixLoader.addPathComponent(bsfSource);
+ fixLoader.addLoaderPackageRoot(BSF_PACKAGE);
+ }
+
+ if (needMoveRunner) {
+ fixLoader.addPathComponent(
+ LoaderUtils.getResourceSource(
+ fixLoader,
+ LoaderUtils.classNameToResource(BSF_SCRIPT_RUNNER)));
+ fixLoader.addLoaderPackageRoot(UTIL_OPTIONAL_PACKAGE);
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/ScriptRunner.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/ScriptRunner.java
new file mode 100644
index 00000000..735e5555
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/ScriptRunner.java
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.util;
+
+/**
+ * This class is here for backwards compatibility.
+ * @deprecated Implementation moved to another location. Use
+ * that org.apache.tools.ant.types.optional.ScriptRunner instead.
+ */
+public class ScriptRunner
+ extends org.apache.tools.ant.util.optional.ScriptRunner {
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/ScriptRunnerBase.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/ScriptRunnerBase.java
new file mode 100644
index 00000000..b8aa01a8
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/ScriptRunnerBase.java
@@ -0,0 +1,360 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.util;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.ProjectComponent;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.ResourceCollection;
+
+/**
+ * This is a common abstract base case for script runners.
+ * These classes need to implement executeScript, evaluateScript
+ * and supportsLanguage.
+ * @since Ant 1.7.0
+ */
+public abstract class ScriptRunnerBase {
+ /** Whether to keep the engine between calls to execute/eval */
+ private boolean keepEngine = false;
+
+ /** Script language */
+ private String language;
+
+ /** Script content */
+ private String script = "";
+
+ /** Project this runner is used in */
+ private Project project;
+
+ /** Classloader to be used when running the script. */
+ private ClassLoader scriptLoader;
+
+ /** Beans to be provided to the script */
+ private Map beans = new HashMap();
+
+ /**
+ * Add a list of named objects to the list to be exported to the script
+ *
+ * @param dictionary a map of objects to be placed into the script context
+ * indexed by String names.
+ */
+ public void addBeans(Map dictionary) {
+ for (Iterator i = dictionary.keySet().iterator(); i.hasNext();) {
+ String key = (String) i.next();
+ try {
+ Object val = dictionary.get(key);
+ addBean(key, val);
+ } catch (BuildException ex) {
+ // The key is in the dictionary but cannot be retrieved
+ // This is usually due references that refer to tasks
+ // that have not been taskdefed in the current run.
+ // Ignore
+ }
+ }
+ }
+
+ /**
+ * Add a single object into the script context.
+ *
+ * @param key the name in the context this object is to stored under.
+ * @param bean the object to be stored in the script context.
+ */
+ public void addBean(String key, Object bean) {
+ boolean isValid = key.length() > 0
+ && Character.isJavaIdentifierStart(key.charAt(0));
+
+ for (int i = 1; isValid && i < key.length(); i++) {
+ isValid = Character.isJavaIdentifierPart(key.charAt(i));
+ }
+
+ if (isValid) {
+ beans.put(key, bean);
+ }
+ }
+
+ /**
+ * Get the beans used for the script.
+ * @return the map of beans.
+ */
+ protected Map getBeans() {
+ return beans;
+ }
+
+ /**
+ * Do the work.
+ * @param execName the name that will be passed to BSF for this script
+ * execution.
+ */
+ public abstract void executeScript(String execName);
+
+ /**
+ * Evaluate the script.
+ * @param execName the name that will be passed to the
+ * scripting engine for this script execution.
+ * @return the result of evaluating the script.
+ */
+ public abstract Object evaluateScript(String execName);
+
+ /**
+ * Check if a script engine can be created for
+ * this language.
+ * @return true if a script engine can be created, false
+ * otherwise.
+ */
+ public abstract boolean supportsLanguage();
+
+ /**
+ * Get the name of the manager prefix used for this
+ * scriptrunner.
+ * @return the prefix string.
+ */
+ public abstract String getManagerName();
+
+ /**
+ * Defines the language (required).
+ * @param language the scripting language name for the script.
+ */
+ public void setLanguage(String language) {
+ this.language = language;
+ }
+
+ /**
+ * Get the script language
+ * @return the script language
+ */
+ public String getLanguage() {
+ return language;
+ }
+
+ /**
+ * Set the script classloader.
+ * @param classLoader the classloader to use.
+ */
+ public void setScriptClassLoader(ClassLoader classLoader) {
+ this.scriptLoader = classLoader;
+ }
+
+ /**
+ * Get the classloader used to load the script engine.
+ * @return the classloader.
+ */
+ protected ClassLoader getScriptClassLoader() {
+ return scriptLoader;
+ }
+
+ /**
+ * Whether to keep the script engine between calls.
+ * @param keepEngine if true, keep the engine.
+ */
+ public void setKeepEngine(boolean keepEngine) {
+ this.keepEngine = keepEngine;
+ }
+
+ /**
+ * Get the keep engine attribute.
+ * @return the attribute.
+ */
+ public boolean getKeepEngine() {
+ return keepEngine;
+ }
+
+ /**
+ * Load the script from an external file; optional.
+ * @param file the file containing the script source.
+ */
+ public void setSrc(File file) {
+ String filename = file.getPath();
+ if (!file.exists()) {
+ throw new BuildException("file " + filename + " not found.");
+ }
+ try {
+ readSource(new FileReader(file), filename);
+ } catch (FileNotFoundException e) {
+ //this can only happen if the file got deleted a short moment ago
+ throw new BuildException("file " + filename + " not found.");
+ }
+ }
+
+ /**
+ * Read some source in from the given reader
+ * @param reader the reader; this is closed afterwards.
+ * @param name the name to use in error messages
+ */
+ private void readSource(Reader reader, String name) {
+ BufferedReader in = null;
+ try {
+ in = new BufferedReader(reader);
+ script += FileUtils.safeReadFully(in);
+ } catch (IOException ex) {
+ throw new BuildException("Failed to read " + name, ex);
+ } finally {
+ FileUtils.close(in);
+ }
+ }
+
+
+ /**
+ * Add a resource to the source list.
+ * @since Ant 1.7.1
+ * @param sourceResource the resource to load
+ * @throws BuildException if the resource cannot be read
+ */
+ public void loadResource(Resource sourceResource) {
+ String name = sourceResource.toLongString();
+ InputStream in = null;
+ try {
+ in = sourceResource.getInputStream();
+ } catch (IOException e) {
+ throw new BuildException("Failed to open " + name, e);
+ } catch (UnsupportedOperationException e) {
+ throw new BuildException(
+ "Failed to open " + name + " -it is not readable", e);
+ }
+ readSource(new InputStreamReader(in), name);
+ }
+
+ /**
+ * Add all resources in a resource collection to the source list.
+ * @since Ant 1.7.1
+ * @param collection the resource to load
+ * @throws BuildException if a resource cannot be read
+ */
+ public void loadResources(ResourceCollection collection) {
+ for (Resource resource : collection) {
+ loadResource(resource);
+ }
+ }
+
+ /**
+ * Set the script text. Properties in the text are not expanded!
+ *
+ * @param text a component of the script text to be added.
+ */
+ public void addText(String text) {
+ script += text;
+ }
+
+ /**
+ * Get the current script text content.
+ * @return the script text.
+ */
+ public String getScript() {
+ return script;
+ }
+
+ /**
+ * Clear the current script text content.
+ */
+ public void clearScript() {
+ this.script = "";
+ }
+
+ /**
+ * Set the project for this runner.
+ * @param project the project.
+ */
+ public void setProject(Project project) {
+ this.project = project;
+ }
+
+ /**
+ * Get the project for this runner.
+ * @return the project.
+ */
+ public Project getProject() {
+ return project;
+ }
+
+ /**
+ * Bind the runner to a project component.
+ * Properties, targets and references are all added as beans;
+ * project is bound to project, and self to the component.
+ * @param component to become <code>self</code>
+ */
+ public void bindToComponent(ProjectComponent component) {
+ project = component.getProject();
+ addBeans(project.getProperties());
+ addBeans(project.getUserProperties());
+ addBeans(project.getCopyOfTargets());
+ addBeans(project.getCopyOfReferences());
+ addBean("project", project);
+ addBean("self", component);
+ }
+
+ /**
+ * Bind the runner to a project component.
+ * The project and self are the only beans set.
+ * @param component to become <code>self</code>
+ */
+ public void bindToComponentMinimum(ProjectComponent component) {
+ project = component.getProject();
+ addBean("project", project);
+ addBean("self", component);
+ }
+
+ /**
+ * Check if the language attribute is set.
+ * @throws BuildException if it is not.
+ */
+ protected void checkLanguage() {
+ if (language == null) {
+ throw new BuildException(
+ "script language must be specified");
+ }
+ }
+
+ /**
+ * Replace the current context classloader with the
+ * script context classloader.
+ * @return the current context classloader.
+ */
+ protected ClassLoader replaceContextLoader() {
+ ClassLoader origContextClassLoader =
+ Thread.currentThread().getContextClassLoader();
+ if (getScriptClassLoader() == null) {
+ setScriptClassLoader(getClass().getClassLoader());
+ }
+ Thread.currentThread().setContextClassLoader(getScriptClassLoader());
+ return origContextClassLoader;
+ }
+
+ /**
+ * Restore the context loader with the original context classloader.
+ *
+ * script context loader.
+ * @param origLoader the original context classloader.
+ */
+ protected void restoreContextLoader(ClassLoader origLoader) {
+ Thread.currentThread().setContextClassLoader(
+ origLoader);
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/ScriptRunnerCreator.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/ScriptRunnerCreator.java
new file mode 100644
index 00000000..77e9ee73
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/ScriptRunnerCreator.java
@@ -0,0 +1,133 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.util;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+
+/**
+ * This is a helper class used by ScriptRunnerHelper to
+ * create a ScriptRunner based on a classloader and on a language.
+ */
+public class ScriptRunnerCreator {
+ private static final String AUTO = "auto";
+ private static final String OATAU = "org.apache.tools.ant.util";
+ private static final String UTIL_OPT = OATAU + ".optional";
+
+ private static final String BSF = "bsf";
+ private static final String BSF_PACK = "org.apache.bsf";
+ private static final String BSF_MANAGER = BSF_PACK + ".BSFManager";
+ private static final String BSF_RUNNER = UTIL_OPT + ".ScriptRunner";
+
+ private static final String JAVAX = "javax";
+ private static final String JAVAX_MANAGER = "javax.script.ScriptEngineManager";
+ private static final String JAVAX_RUNNER = UTIL_OPT + ".JavaxScriptRunner";
+
+ private Project project;
+ private String manager;
+ private String language;
+ private ClassLoader scriptLoader = null;
+
+ /**
+ * Constructor for creator.
+ * @param project the current project.
+ */
+ public ScriptRunnerCreator(Project project) {
+ this.project = project;
+ }
+
+ /**
+ * Create a ScriptRunner.
+ * @param manager the script manager ("auto" | "bsf" | "javax")
+ * @param language the language.
+ * @param classLoader the classloader to use
+ * @return the created script runner.
+ * @throws BuildException if unable to create the ScriptRunner.
+ */
+ public synchronized ScriptRunnerBase createRunner(
+ String manager, String language, ClassLoader classLoader) {
+ this.manager = manager;
+ this.language = language;
+ this.scriptLoader = classLoader;
+
+ if (language == null) {
+ throw new BuildException("script language must be specified");
+ }
+ if (!manager.equals(AUTO) && !manager.equals(JAVAX) && !manager.equals(BSF)) {
+ throw new BuildException("Unsupported language prefix " + manager);
+ }
+
+ // Check for bsf first then javax
+ // This version does not check if the scriptManager
+ // supports the language.
+
+ ScriptRunnerBase ret = null;
+ ret = createRunner(BSF, BSF_MANAGER, BSF_RUNNER);
+ if (ret == null) {
+ ret = createRunner(JAVAX, JAVAX_MANAGER, JAVAX_RUNNER);
+ }
+ if (ret != null) {
+ return ret;
+ }
+ if (JAVAX.equals(manager)) {
+ throw new BuildException(
+ "Unable to load the script engine manager " + "(" + JAVAX_MANAGER + ")");
+ }
+ if (BSF.equals(manager)) {
+ throw new BuildException(
+ "Unable to load the BSF script engine manager " + "(" + BSF_MANAGER + ")");
+ }
+ throw new BuildException("Unable to load a script engine manager "
+ + "(" + BSF_MANAGER + " or " + JAVAX_MANAGER + ")");
+ }
+
+ /**
+ * Create a script runner if the scriptManager matches the passed
+ * in manager.
+ * This checks if the script manager exists in the scriptLoader
+ * classloader and if so it creates and returns the script runner.
+ * @param checkManager check if the manager matchs this value.
+ * @param managerClass the name of the script manager class.
+ * @param runnerClass the name of ant's script runner for this manager.
+ * @return the script runner class.
+ * @throws BuildException if there is a problem creating the runner class.
+ */
+ private ScriptRunnerBase createRunner(
+ String checkManager, String managerClass, String runnerClass) {
+ ScriptRunnerBase runner = null;
+ if (!manager.equals(AUTO) && !manager.equals(checkManager)) {
+ return null;
+ }
+ if (scriptLoader.getResource(LoaderUtils.classNameToResource(managerClass)) == null) {
+ return null;
+ }
+ if (managerClass.equals(BSF_MANAGER)) {
+ new ScriptFixBSFPath().fixClassLoader(scriptLoader, language);
+ }
+ try {
+ runner = (ScriptRunnerBase) Class.forName(
+ runnerClass, true, scriptLoader).newInstance();
+ runner.setProject(project);
+ } catch (Exception ex) {
+ throw ReflectUtil.toBuildException(ex);
+ }
+ runner.setLanguage(language);
+ runner.setScriptClassLoader(scriptLoader);
+ return runner;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/ScriptRunnerHelper.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/ScriptRunnerHelper.java
new file mode 100644
index 00000000..9e814d96
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/ScriptRunnerHelper.java
@@ -0,0 +1,206 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.util;
+
+import java.io.File;
+
+import org.apache.tools.ant.ProjectComponent;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.types.Reference;
+import org.apache.tools.ant.types.ResourceCollection;
+import org.apache.tools.ant.types.resources.Union;
+
+/**
+ * A class to help in creating, setting and getting script runners.
+ */
+public class ScriptRunnerHelper {
+ private ClasspathUtils.Delegate cpDelegate = null;
+ private File srcFile;
+ private String manager = "auto";
+ private String language;
+ private String text;
+ private boolean setBeans = true;
+ private ProjectComponent projectComponent;
+ private ClassLoader scriptLoader = null;
+ private Union resources = new Union();
+
+ /**
+ * Set the project component associated with this helper.
+ * @param component the project component that owns this helper.
+ */
+ public void setProjectComponent(ProjectComponent component) {
+ this.projectComponent = component;
+ }
+
+ /**
+ * Create and set text on a script.
+ * @return the created or reused script runner.
+ */
+ public ScriptRunnerBase getScriptRunner() {
+ ScriptRunnerBase runner = getRunner();
+ if (srcFile != null) {
+ runner.setSrc(srcFile);
+ }
+ if (text != null) {
+ runner.addText(text);
+ }
+ if (resources != null) {
+ runner.loadResources(resources);
+ }
+ if (setBeans) {
+ runner.bindToComponent(projectComponent);
+ } else {
+ runner.bindToComponentMinimum(projectComponent);
+ }
+ return runner;
+ }
+
+ /**
+ * Classpath to be used when searching for classes and resources.
+ *
+ * @return an empty Path instance to be configured by Ant.
+ */
+ public Path createClasspath() {
+ return getClassPathDelegate().createClasspath();
+ }
+
+ /**
+ * Set the classpath to be used when searching for classes and resources.
+ *
+ * @param classpath an Ant Path object containing the search path.
+ */
+ public void setClasspath(Path classpath) {
+ getClassPathDelegate().setClasspath(classpath);
+ }
+
+ /**
+ * Set the classpath by reference.
+ *
+ * @param r a Reference to a Path instance to be used as the classpath
+ * value.
+ */
+ public void setClasspathRef(Reference r) {
+ getClassPathDelegate().setClasspathref(r);
+ }
+
+ /**
+ * Load the script from an external file ; optional.
+ *
+ * @param file the file containing the script source.
+ */
+ public void setSrc(File file) {
+ this.srcFile = file;
+ }
+
+ /**
+ * Add script text.
+ *
+ * @param text a component of the script text to be added.
+ */
+ public void addText(String text) {
+ this.text = text;
+ }
+
+ /**
+ * Defines the script manager - defaults to "auto".
+ *
+ * @param manager the scripting manager - "bsf" or "javax" or "auto"
+ */
+ public void setManager(String manager) {
+ this.manager = manager;
+ }
+
+ /**
+ * Defines the language (required).
+ *
+ * @param language the scripting language name for the script.
+ */
+ public void setLanguage(String language) {
+ this.language = language;
+ }
+
+ /**
+ * Get the language.
+ * @return the scripting language.
+ */
+ public String getLanguage() {
+ return language;
+ }
+
+ /**
+ * Set the setbeans attribute.
+ * If this is true, &lt;script&gt; will create variables in the
+ * script instance for all
+ * properties, targets and references of the current project.
+ * It this is false, only the project and self variables will
+ * be set.
+ * The default is true.
+ * @param setBeans the value to set.
+ */
+ public void setSetBeans(boolean setBeans) {
+ this.setBeans = setBeans;
+ }
+
+ /**
+ * Used when called by scriptdef.
+ * @param loader the loader used by scriptdef.
+ */
+ public void setClassLoader(ClassLoader loader) {
+ scriptLoader = loader;
+ }
+
+ private synchronized ClassLoader generateClassLoader() {
+ if (scriptLoader != null) {
+ return scriptLoader;
+ }
+ if (cpDelegate == null) {
+ scriptLoader = getClass().getClassLoader();
+ return scriptLoader;
+ }
+ scriptLoader = cpDelegate.getClassLoader();
+ return scriptLoader;
+ }
+
+ private ClasspathUtils.Delegate getClassPathDelegate() {
+ if (cpDelegate == null) {
+ if (projectComponent == null) {
+ throw new IllegalStateException("Can't access classpath without a project component");
+ }
+ cpDelegate = ClasspathUtils.getDelegate(projectComponent);
+ }
+ return cpDelegate;
+ }
+
+ /**
+ * Get a script runner.
+ */
+ private ScriptRunnerBase getRunner() {
+ return new ScriptRunnerCreator(projectComponent.getProject()).createRunner(
+ manager, language, generateClassLoader());
+ }
+
+ /**
+ * Add any source resource.
+ *
+ * @param resource source of script
+ * @since Ant 1.7.1
+ */
+ public void add(ResourceCollection resource) {
+ resources.add(resource);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/SourceFileScanner.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/SourceFileScanner.java
new file mode 100644
index 00000000..c79f0347
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/SourceFileScanner.java
@@ -0,0 +1,173 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.util;
+
+import java.io.File;
+import java.util.Vector;
+
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.ResourceFactory;
+import org.apache.tools.ant.types.resources.FileResource;
+
+/**
+ * Utility class that collects the functionality of the various
+ * scanDir methods that have been scattered in several tasks before.
+ *
+ * <p>The only method returns an array of source files. The array is a
+ * subset of the files given as a parameter and holds only those that
+ * are newer than their corresponding target files.</p>
+ *
+ */
+public class SourceFileScanner implements ResourceFactory {
+
+ // CheckStyle:VisibilityModifier OFF - bc
+ protected Task task;
+ // CheckStyle:VisibilityModifier ON
+
+ private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+ private File destDir; // base directory of the fileset
+
+ /**
+ * Construct a new SourceFileScanner.
+ * @param task The task we should log messages through.
+ */
+ public SourceFileScanner(Task task) {
+ this.task = task;
+ }
+
+ /**
+ * Restrict the given set of files to those that are newer than
+ * their corresponding target files.
+ *
+ * @param files the original set of files.
+ * @param srcDir all files are relative to this directory.
+ * @param destDir target files live here. if null file names
+ * returned by the mapper are assumed to be absolute.
+ * @param mapper knows how to construct a target file names from
+ * source file names.
+ * @return an array of filenames.
+ */
+ public String[] restrict(String[] files, File srcDir, File destDir,
+ FileNameMapper mapper) {
+ return restrict(files, srcDir, destDir, mapper,
+ FILE_UTILS.getFileTimestampGranularity());
+ }
+
+ /**
+ * Restrict the given set of files to those that are newer than
+ * their corresponding target files.
+ *
+ * @param files the original set of files.
+ * @param srcDir all files are relative to this directory.
+ * @param destDir target files live here. If null file names
+ * returned by the mapper are assumed to be absolute.
+ * @param mapper knows how to construct a target file names from
+ * source file names.
+ * @param granularity The number of milliseconds leeway to give
+ * before deciding a target is out of date.
+ * @return an array of filenames.
+ *
+ * @since Ant 1.6.2
+ */
+ public String[] restrict(String[] files, File srcDir, File destDir,
+ FileNameMapper mapper, long granularity) {
+ // record destdir for later use in getResource
+ this.destDir = destDir;
+ Vector v = new Vector();
+ for (int i = 0; i < files.length; i++) {
+ final String name = files[i];
+ v.addElement(new FileResource(srcDir, name) {
+ public String getName() {
+ return name;
+ }
+ });
+ }
+ Resource[] sourceresources = new Resource[v.size()];
+ v.copyInto(sourceresources);
+
+ // build the list of sources which are out of date with
+ // respect to the target
+ Resource[] outofdate =
+ ResourceUtils.selectOutOfDateSources(task, sourceresources,
+ mapper, this, granularity);
+ String[] result = new String[outofdate.length];
+ for (int counter = 0; counter < outofdate.length; counter++) {
+ result[counter] = outofdate[counter].getName();
+ }
+ return result;
+ }
+
+ /**
+ * Convenience layer on top of restrict that returns the source
+ * files as File objects (containing absolute paths if srcDir is
+ * absolute).
+ * @param files the original set of files.
+ * @param srcDir all files are relative to this directory.
+ * @param destDir target files live here. If null file names
+ * returned by the mapper are assumed to be absolute.
+ * @param mapper knows how to construct a target file names from
+ * source file names.
+ * @return an array of files.
+ */
+ public File[] restrictAsFiles(String[] files, File srcDir, File destDir,
+ FileNameMapper mapper) {
+ return restrictAsFiles(files, srcDir, destDir, mapper,
+ FILE_UTILS.getFileTimestampGranularity());
+ }
+
+ /**
+ * Convenience layer on top of restrict that returns the source
+ * files as File objects (containing absolute paths if srcDir is
+ * absolute).
+ *
+ * @param files the original set of files.
+ * @param srcDir all files are relative to this directory.
+ * @param destDir target files live here. If null file names
+ * returned by the mapper are assumed to be absolute.
+ * @param mapper knows how to construct a target file names from
+ * source file names.
+ * @param granularity The number of milliseconds leeway to give
+ * before deciding a target is out of date.
+ * @return an array of files.
+ * @since Ant 1.6.2
+ */
+ public File[] restrictAsFiles(String[] files, File srcDir, File destDir,
+ FileNameMapper mapper, long granularity) {
+ String[] res = restrict(files, srcDir, destDir, mapper, granularity);
+ File[] result = new File[res.length];
+ for (int i = 0; i < res.length; i++) {
+ result[i] = new File(srcDir, res[i]);
+ }
+ return result;
+ }
+
+ /**
+ * Returns resource information for a file at destination.
+ * @param name relative path of file at destination.
+ * @return data concerning a file whose relative path to destDir is name.
+ *
+ * @since Ant 1.5.2
+ */
+ public Resource getResource(String name) {
+ return new FileResource(destDir, name);
+ }
+
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/SplitClassLoader.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/SplitClassLoader.java
new file mode 100644
index 00000000..f48d3d3e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/SplitClassLoader.java
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.util;
+
+import org.apache.tools.ant.AntClassLoader;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.Path;
+
+/**
+ * Specialized classloader for tasks that need finer grained control
+ * over which classes are to be loaded via Ant's classloader and which
+ * should not even if they are available.
+ */
+public final class SplitClassLoader extends AntClassLoader {
+
+ private final String[] splitClasses;
+
+ /**
+ * @param splitClasses classes contained herin will not be loaded
+ * via Ant's classloader
+ */
+ public SplitClassLoader(ClassLoader parent, Path path, Project project,
+ String[] splitClasses) {
+ super(parent, project, path, true);
+ this.splitClasses = splitClasses;
+ }
+
+ // forceLoadClass is not convenient here since it would not
+ // properly deal with inner classes of these classes.
+ protected synchronized Class loadClass(String classname, boolean resolve)
+ throws ClassNotFoundException {
+ Class theClass = findLoadedClass(classname);
+ if (theClass != null) {
+ return theClass;
+ }
+ if (isSplit(classname)) {
+ theClass = findClass(classname);
+ if (resolve) {
+ resolveClass(theClass);
+ }
+ return theClass;
+ } else {
+ return super.loadClass(classname, resolve);
+ }
+ }
+
+ private boolean isSplit(String classname) {
+ String simplename = classname.substring(classname.lastIndexOf('.') + 1);
+ for (int i = 0; i < splitClasses.length; i++) {
+ if (simplename.equals(splitClasses[i])
+ || simplename.startsWith(splitClasses[i] + '$')) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/StringTokenizer.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/StringTokenizer.java
new file mode 100644
index 00000000..7addf310
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/StringTokenizer.java
@@ -0,0 +1,154 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.util;
+
+import java.io.IOException;
+import java.io.Reader;
+
+import org.apache.tools.ant.ProjectComponent;
+
+/**
+ * Class to tokenize the input as areas separated
+ * by white space, or by a specified list of
+ * delim characters. Behaves like java.util.StringTokenizer.
+ * If the stream starts with delim characters, the first
+ * token will be an empty string (unless the treat delims
+ * as tokens flag is set).
+ * @since Ant 1.7
+ */
+public class StringTokenizer extends ProjectComponent implements Tokenizer {
+ private static final int NOT_A_CHAR = -2;
+ private String intraString = "";
+ private int pushed = NOT_A_CHAR;
+ private char[] delims = null;
+ private boolean delimsAreTokens = false;
+ private boolean suppressDelims = false;
+ private boolean includeDelims = false;
+
+ /**
+ * attribute delims - the delimiter characters
+ * @param delims a string containing the delimiter characters
+ */
+ public void setDelims(String delims) {
+ this.delims = StringUtils.resolveBackSlash(delims).toCharArray();
+ }
+
+ /**
+ * attribute delimsaretokens - treat delimiters as
+ * separate tokens.
+ * @param delimsAreTokens true if delimiters are to be separate
+ */
+
+ public void setDelimsAreTokens(boolean delimsAreTokens) {
+ this.delimsAreTokens = delimsAreTokens;
+ }
+ /**
+ * attribute suppressdelims - suppress delimiters.
+ * default - false
+ * @param suppressDelims if true do not report delimiters
+ */
+ public void setSuppressDelims(boolean suppressDelims) {
+ this.suppressDelims = suppressDelims;
+ }
+
+ /**
+ * attribute includedelims - treat delimiters as part
+ * of the token.
+ * default - false
+ * @param includeDelims if true add delimiters to the token
+ */
+ public void setIncludeDelims(boolean includeDelims) {
+ this.includeDelims = includeDelims;
+ }
+
+ /**
+ * find and return the next token
+ *
+ * @param in the input stream
+ * @return the token
+ * @exception IOException if an error occurs reading
+ */
+ public String getToken(Reader in) throws IOException {
+ int ch = -1;
+ if (pushed != NOT_A_CHAR) {
+ ch = pushed;
+ pushed = NOT_A_CHAR;
+ } else {
+ ch = in.read();
+ }
+ if (ch == -1) {
+ return null;
+ }
+ boolean inToken = true;
+ intraString = "";
+ StringBuffer word = new StringBuffer();
+ StringBuffer padding = new StringBuffer();
+ while (ch != -1) {
+ char c = (char) ch;
+ boolean isDelim = isDelim(c);
+ if (inToken) {
+ if (isDelim) {
+ if (delimsAreTokens) {
+ if (word.length() == 0) {
+ word.append(c);
+ } else {
+ pushed = ch;
+ }
+ break;
+ }
+ padding.append(c);
+ inToken = false;
+ } else {
+ word.append(c);
+ }
+ } else {
+ if (isDelim) {
+ padding.append(c);
+ } else {
+ pushed = ch;
+ break;
+ }
+ }
+ ch = in.read();
+ }
+ intraString = padding.toString();
+ if (includeDelims) {
+ word.append(intraString);
+ }
+ return word.toString();
+ }
+
+ /**
+ * @return the intratoken string
+ */
+ public String getPostToken() {
+ return suppressDelims || includeDelims ? "" : intraString;
+ }
+
+ private boolean isDelim(char ch) {
+ if (delims == null) {
+ return Character.isWhitespace(ch);
+ }
+ for (int i = 0; i < delims.length; ++i) {
+ if (delims[i] == ch) {
+ return true;
+ }
+ }
+ return false;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/StringUtils.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/StringUtils.java
new file mode 100644
index 00000000..626fb224
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/StringUtils.java
@@ -0,0 +1,273 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.util;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildException;
+
+/**
+ * A set of helper methods related to string manipulation.
+ *
+ */
+public final class StringUtils {
+ private static final long KILOBYTE = 1024;
+ private static final long MEGABYTE = KILOBYTE * 1024;
+ private static final long GIGABYTE = MEGABYTE * 1024;
+ private static final long TERABYTE = GIGABYTE * 1024;
+ private static final long PETABYTE = TERABYTE * 1024;
+
+ /**
+ * constructor to stop anyone instantiating the class
+ */
+ private StringUtils() {
+ }
+
+ /** the line separator for this OS */
+ public static final String LINE_SEP = System.getProperty("line.separator");
+
+ /**
+ * Splits up a string into a list of lines. It is equivalent
+ * to <tt>split(data, '\n')</tt>.
+ * @param data the string to split up into lines.
+ * @return the list of lines available in the string.
+ */
+ public static Vector<String> lineSplit(String data) {
+ return split(data, '\n');
+ }
+
+ /**
+ * Splits up a string where elements are separated by a specific
+ * character and return all elements.
+ * @param data the string to split up.
+ * @param ch the separator character.
+ * @return the list of elements.
+ */
+ public static Vector<String> split(String data, int ch) {
+ Vector<String> elems = new Vector<String>();
+ int pos = -1;
+ int i = 0;
+ while ((pos = data.indexOf(ch, i)) != -1) {
+ String elem = data.substring(i, pos);
+ elems.addElement(elem);
+ i = pos + 1;
+ }
+ elems.addElement(data.substring(i));
+ return elems;
+ }
+
+ /**
+ * Replace occurrences into a string.
+ * @param data the string to replace occurrences into
+ * @param from the occurrence to replace.
+ * @param to the occurrence to be used as a replacement.
+ * @return the new string with replaced occurrences.
+ * @deprecated Use {@link String#replace(CharSequence, CharSequence)} now.
+ */
+ public static String replace(String data, String from, String to) {
+ return data.replace(from, to);
+ }
+
+ /**
+ * Convenient method to retrieve the full stacktrace from a given exception.
+ * @param t the exception to get the stacktrace from.
+ * @return the stacktrace from the given exception.
+ */
+ public static String getStackTrace(Throwable t) {
+ StringWriter sw = new StringWriter();
+ PrintWriter pw = new PrintWriter(sw, true);
+ t.printStackTrace(pw);
+ pw.flush();
+ pw.close();
+ return sw.toString();
+ }
+
+ /**
+ * Checks that a string buffer ends up with a given string. It may sound
+ * trivial with the existing
+ * JDK API but the various implementation among JDKs can make those
+ * methods extremely resource intensive
+ * and perform poorly due to massive memory allocation and copying. See
+ * @param buffer the buffer to perform the check on
+ * @param suffix the suffix
+ * @return <code>true</code> if the character sequence represented by the
+ * argument is a suffix of the character sequence represented by
+ * the StringBuffer object; <code>false</code> otherwise. Note that the
+ * result will be <code>true</code> if the argument is the
+ * empty string.
+ */
+ public static boolean endsWith(StringBuffer buffer, String suffix) {
+ if (suffix.length() > buffer.length()) {
+ return false;
+ }
+ // this loop is done on purpose to avoid memory allocation performance
+ // problems on various JDKs
+ // StringBuffer.lastIndexOf() was introduced in jdk 1.4 and
+ // implementation is ok though does allocation/copying
+ // StringBuffer.toString().endsWith() does massive memory
+ // allocation/copying on JDK 1.5
+ // See http://issues.apache.org/bugzilla/show_bug.cgi?id=37169
+ int endIndex = suffix.length() - 1;
+ int bufferIndex = buffer.length() - 1;
+ while (endIndex >= 0) {
+ if (buffer.charAt(bufferIndex) != suffix.charAt(endIndex)) {
+ return false;
+ }
+ bufferIndex--;
+ endIndex--;
+ }
+ return true;
+ }
+
+ /**
+ * xml does not do "c" like interpretation of strings.
+ * i.e. \n\r\t etc.
+ * this method processes \n, \r, \t, \f, \\
+ * also subs \s -&gt; " \n\r\t\f"
+ * a trailing '\' will be ignored
+ *
+ * @param input raw string with possible embedded '\'s
+ * @return converted string
+ * @since Ant 1.7
+ */
+ public static String resolveBackSlash(String input) {
+ StringBuffer b = new StringBuffer();
+ boolean backSlashSeen = false;
+ for (int i = 0; i < input.length(); ++i) {
+ char c = input.charAt(i);
+ if (!backSlashSeen) {
+ if (c == '\\') {
+ backSlashSeen = true;
+ } else {
+ b.append(c);
+ }
+ } else {
+ switch (c) {
+ case '\\':
+ b.append((char) '\\');
+ break;
+ case 'n':
+ b.append((char) '\n');
+ break;
+ case 'r':
+ b.append((char) '\r');
+ break;
+ case 't':
+ b.append((char) '\t');
+ break;
+ case 'f':
+ b.append((char) '\f');
+ break;
+ case 's':
+ b.append(" \t\n\r\f");
+ break;
+ default:
+ b.append(c);
+ }
+ backSlashSeen = false;
+ }
+ }
+ return b.toString();
+ }
+
+ /**
+ * Takes a human readable size representation eg 10K
+ * a long value. Doesn't support 1.1K or other rational values.
+ * @param humanSize the amount as a human readable string.
+ * @return a long value representation
+ * @throws Exception if there is a problem.
+ * @since Ant 1.7
+ */
+ public static long parseHumanSizes(String humanSize) throws Exception {
+ long factor = 1L;
+ char s = humanSize.charAt(0);
+ switch (s) {
+ case '+':
+ humanSize = humanSize.substring(1);
+ break;
+ case '-':
+ factor = -1L;
+ humanSize = humanSize.substring(1);
+ break;
+ default:
+ break;
+ }
+ //last character isn't a digit
+ char c = humanSize.charAt(humanSize.length() - 1);
+ if (!Character.isDigit(c)) {
+ int trim = 1;
+ switch (c) {
+ case 'K':
+ factor *= KILOBYTE;
+ break;
+ case 'M':
+ factor *= MEGABYTE;
+ break;
+ case 'G':
+ factor *= GIGABYTE;
+ break;
+ case 'T':
+ factor *= TERABYTE;
+ break;
+ case 'P':
+ factor *= PETABYTE;
+ break;
+ default:
+ trim = 0;
+ }
+ humanSize = humanSize.substring(0, humanSize.length() - trim);
+ }
+ try {
+ return factor * Long.parseLong(humanSize);
+ } catch (NumberFormatException e) {
+ throw new BuildException("Failed to parse \"" + humanSize + "\"", e);
+ }
+ }
+
+ /**
+ * Removes the suffix from a given string, if the string contains
+ * that suffix.
+ * @param string String for check
+ * @param suffix Suffix to remove
+ * @return the <i>string</i> with the <i>suffix</i>
+ */
+ public static String removeSuffix(String string, String suffix) {
+ if (string.endsWith(suffix)) {
+ return string.substring(0, string.length() - suffix.length());
+ } else {
+ return string;
+ }
+ }
+
+ /**
+ * Removes the prefix from a given string, if the string contains
+ * that prefix.
+ * @param string String for check
+ * @param prefix Prefix to remove
+ * @return the <i>string</i> with the <i>prefix</i>
+ */
+ public static String removePrefix(String string, String prefix) {
+ if (string.startsWith(prefix)) {
+ return string.substring(prefix.length());
+ } else {
+ return string;
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/SymbolicLinkUtils.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/SymbolicLinkUtils.java
new file mode 100644
index 00000000..3bc9918e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/SymbolicLinkUtils.java
@@ -0,0 +1,296 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.util;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FilenameFilter;
+import java.io.IOException;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.taskdefs.Execute;
+
+/**
+ * Contains methods related to symbolic links - or what Ant thinks is
+ * a symbolic link based on the absent support for them in Java.
+ *
+ * @since Ant 1.8.0
+ */
+public class SymbolicLinkUtils {
+ private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+
+ /**
+ * Shared instance.
+ */
+ private static final SymbolicLinkUtils PRIMARY_INSTANCE =
+ new SymbolicLinkUtils();
+
+ /**
+ * Method to retrieve The SymbolicLinkUtils, which is shared by
+ * all users of this method.
+ * @return an instance of SymbolicLinkUtils.
+ */
+ public static SymbolicLinkUtils getSymbolicLinkUtils() {
+ // keep the door open for Java X.Y specific subclass if symbolic
+ // links ever become supported in the classlib
+ return PRIMARY_INSTANCE;
+ }
+
+ /**
+ * Empty constructor.
+ */
+ protected SymbolicLinkUtils() {
+ }
+
+ /**
+ * Checks whether a given file is a symbolic link.
+ *
+ * <p>It doesn't really test for symbolic links but whether the
+ * canonical and absolute paths of the file are identical--this
+ * may lead to false positives on some platforms.</p>
+ *
+ * @param file the file to test. Must not be null.
+ *
+ * @return true if the file is a symbolic link.
+ * @throws IOException on error.
+ */
+ public boolean isSymbolicLink(final File file) throws IOException {
+ return isSymbolicLink(file.getParentFile(), file.getName());
+ }
+
+ /**
+ * Checks whether a given file is a symbolic link.
+ *
+ * <p>It doesn't really test for symbolic links but whether the
+ * canonical and absolute paths of the file are identical--this
+ * may lead to false positives on some platforms.</p>
+ *
+ * @param name the name of the file to test.
+ *
+ * @return true if the file is a symbolic link.
+ * @throws IOException on error.
+ */
+ public boolean isSymbolicLink(final String name) throws IOException {
+ return isSymbolicLink(new File(name));
+ }
+
+ /**
+ * Checks whether a given file is a symbolic link.
+ *
+ * <p>It doesn't really test for symbolic links but whether the
+ * canonical and absolute paths of the file are identical--this
+ * may lead to false positives on some platforms.</p>
+ *
+ * @param parent the parent directory of the file to test
+ * @param name the name of the file to test.
+ *
+ * @return true if the file is a symbolic link.
+ * @throws IOException on error.
+ */
+ public boolean isSymbolicLink(final File parent, final String name)
+ throws IOException {
+ final File toTest = parent != null
+ ? new File(parent.getCanonicalPath(), name)
+ : new File(name);
+ return !toTest.getAbsolutePath().equals(toTest.getCanonicalPath());
+ }
+
+ /**
+ * Checks whether a given file is a broken symbolic link.
+ *
+ * <p>It doesn't really test for symbolic links but whether Java
+ * reports that the File doesn't exist but its parent's child list
+ * contains it--this may lead to false positives on some
+ * platforms.</p>
+ *
+ * <p>Note that #isSymbolicLink returns false if this method
+ * returns true since Java won't produce a canonical name
+ * different from the abolute one if the link is broken.</p>
+ *
+ * @param name the name of the file to test.
+ *
+ * @return true if the file is a broken symbolic link.
+ * @throws IOException on error.
+ */
+ public boolean isDanglingSymbolicLink(final String name) throws IOException {
+ return isDanglingSymbolicLink(new File(name));
+ }
+
+ /**
+ * Checks whether a given file is a broken symbolic link.
+ *
+ * <p>It doesn't really test for symbolic links but whether Java
+ * reports that the File doesn't exist but its parent's child list
+ * contains it--this may lead to false positives on some
+ * platforms.</p>
+ *
+ * <p>Note that #isSymbolicLink returns false if this method
+ * returns true since Java won't produce a canonical name
+ * different from the abolute one if the link is broken.</p>
+ *
+ * @param file the file to test.
+ *
+ * @return true if the file is a broken symbolic link.
+ * @throws IOException on error.
+ */
+ public boolean isDanglingSymbolicLink(final File file) throws IOException {
+ return isDanglingSymbolicLink(file.getParentFile(), file.getName());
+ }
+
+ /**
+ * Checks whether a given file is a broken symbolic link.
+ *
+ * <p>It doesn't really test for symbolic links but whether Java
+ * reports that the File doesn't exist but its parent's child list
+ * contains it--this may lead to false positives on some
+ * platforms.</p>
+ *
+ * <p>Note that #isSymbolicLink returns false if this method
+ * returns true since Java won't produce a canonical name
+ * different from the abolute one if the link is broken.</p>
+ *
+ * @param parent the parent directory of the file to test
+ * @param name the name of the file to test.
+ *
+ * @return true if the file is a broken symbolic link.
+ * @throws IOException on error.
+ */
+ public boolean isDanglingSymbolicLink(final File parent, final String name)
+ throws IOException {
+ final File f = new File(parent, name);
+ if (!f.exists()) {
+ final String localName = f.getName();
+ final String[] c = parent.list(new FilenameFilter() {
+ public boolean accept(final File d, final String n) {
+ return localName.equals(n);
+ }
+ });
+ return c != null && c.length > 0;
+ }
+ return false;
+ }
+
+ /**
+ * Delete a symlink (without deleting the associated resource).
+ *
+ * <p>This is a utility method that removes a unix symlink without
+ * removing the resource that the symlink points to. If it is
+ * accidentally invoked on a real file, the real file will not be
+ * harmed, but silently ignored.</p>
+ *
+ * <p>Normally this method works by
+ * getting the canonical path of the link, using the canonical path to
+ * rename the resource (breaking the link) and then deleting the link.
+ * The resource is then returned to its original name inside a finally
+ * block to ensure that the resource is unharmed even in the event of
+ * an exception.</p>
+ *
+ * <p>There may be cases where the algorithm described above doesn't work,
+ * in that case the method tries to use the native "rm" command on
+ * the symlink instead.</p>
+ *
+ * @param link A <code>File</code> object of the symlink to delete.
+ * @param task An Ant Task required if "rm" needs to be invoked.
+ *
+ * @throws IOException If calls to <code>File.rename</code>,
+ * <code>File.delete</code> or <code>File.getCanonicalPath</code>
+ * fail.
+ * @throws BuildException if the execution of "rm" failed.
+ */
+ public void deleteSymbolicLink(File link, final Task task)
+ throws IOException {
+ if (isDanglingSymbolicLink(link)) {
+ if (!link.delete()) {
+ throw new IOException("failed to remove dangling symbolic link "
+ + link);
+ }
+ return;
+ }
+
+ if (!isSymbolicLink(link)) {
+ // plain file, not a link
+ return;
+ }
+
+ if (!link.exists()) {
+ throw new FileNotFoundException("No such symbolic link: " + link);
+ }
+
+ // find the resource of the existing link:
+ final File target = link.getCanonicalFile();
+
+ // no reason to try the renaming algorithm if we aren't allowed to
+ // write to the target's parent directory. Let's hope that
+ // File.canWrite works on all platforms.
+
+ if (task == null || target.getParentFile().canWrite()) {
+
+ // rename the resource, thus breaking the link:
+ final File temp = FILE_UTILS.createTempFile("symlink", ".tmp",
+ target.getParentFile(), false,
+ false);
+
+ if (FILE_UTILS.isLeadingPath(target, link)) {
+ // link points to a parent directory, renaming the parent
+ // will rename the file
+ link = new File(temp,
+ FILE_UTILS.removeLeadingPath(target, link));
+ }
+
+ boolean renamedTarget = false;
+ try {
+ try {
+ FILE_UTILS.rename(target, temp);
+ renamedTarget = true;
+ } catch (final IOException e) {
+ throw new IOException("Couldn't rename resource when "
+ + "attempting to delete '" + link
+ + "'. Reason: " + e.getMessage());
+ }
+ // delete the (now) broken link:
+ if (!link.delete()) {
+ throw new IOException("Couldn't delete symlink: "
+ + link
+ + " (was it a real file? is this "
+ + "not a UNIX system?)");
+ }
+ } finally {
+ if (renamedTarget) {
+ // return the resource to its original name:
+ try {
+ FILE_UTILS.rename(temp, target);
+ } catch (final IOException e) {
+ throw new IOException("Couldn't return resource "
+ + temp
+ + " to its original name: "
+ + target.getAbsolutePath()
+ + ". Reason: " + e.getMessage()
+ + "\n THE RESOURCE'S NAME ON DISK"
+ + " HAS BEEN CHANGED BY THIS"
+ + " ERROR!\n");
+ }
+ }
+ }
+ } else {
+ Execute.runCommand(task,
+ new String[] {"rm", link.getAbsolutePath()});
+ }
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/TaskLogger.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/TaskLogger.java
new file mode 100644
index 00000000..9ce5c512
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/TaskLogger.java
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.util;
+
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+
+/**
+ * A facade that makes logging nicer to use.
+ */
+public final class TaskLogger {
+ /**
+ * Task to use to do logging.
+ */
+ private Task task;
+
+ /**
+ * Constructor for the TaskLogger
+ * @param task the task
+ */
+ public TaskLogger(final Task task) {
+ this.task = task;
+ }
+
+ /**
+ * Log a message with <code>MSG_INFO</code> priority
+ * @param message the message to log
+ */
+ public void info(final String message) {
+ task.log(message, Project.MSG_INFO);
+ }
+
+ /**
+ * Log a message with <code>MSG_ERR</code> priority
+ * @param message the message to log
+ */
+ public void error(final String message) {
+ task.log(message, Project.MSG_ERR);
+ }
+
+ /**
+ * Log a message with <code>MSG_WARN</code> priority
+ * @param message the message to log
+ */
+ public void warning(final String message) {
+ task.log(message, Project.MSG_WARN);
+ }
+
+ /**
+ * Log a message with <code>MSG_VERBOSE</code> priority
+ * @param message the message to log
+ */
+ public void verbose(final String message) {
+ task.log(message, Project.MSG_VERBOSE);
+ }
+
+ /**
+ * Log a message with <code>MSG_DEBUG</code> priority
+ * @param message the message to log
+ */
+ public void debug(final String message) {
+ task.log(message, Project.MSG_DEBUG);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/TeeOutputStream.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/TeeOutputStream.java
new file mode 100644
index 00000000..eb8da3fa
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/TeeOutputStream.java
@@ -0,0 +1,95 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.util;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * A simple T-piece to replicate an output stream into two separate streams
+ *
+ */
+public class TeeOutputStream extends OutputStream {
+ private OutputStream left;
+ private OutputStream right;
+
+ /**
+ * Constructor for TeeOutputStream.
+ * @param left one of the output streams.
+ * @param right the other output stream.
+ */
+ public TeeOutputStream(OutputStream left, OutputStream right) {
+ this.left = left;
+ this.right = right;
+ }
+
+ /**
+ * Close both output streams.
+ * @throws IOException on error.
+ */
+ public void close() throws IOException {
+ try {
+ left.close();
+ } finally {
+ right.close();
+ }
+ }
+
+ /**
+ * Flush both output streams.
+ * @throws IOException on error
+ */
+ public void flush() throws IOException {
+ left.flush();
+ right.flush();
+ }
+
+ /**
+ * Write a byte array to both output streams.
+ * @param b an array of bytes.
+ * @throws IOException on error.
+ */
+ public void write(byte[] b) throws IOException {
+ left.write(b);
+ right.write(b);
+ }
+
+ /**
+ * Write a byte array to both output streams.
+ * @param b the data.
+ * @param off the start offset in the data.
+ * @param len the number of bytes to write.
+ * @throws IOException on error.
+ */
+ public void write(byte[] b, int off, int len) throws IOException {
+ left.write(b, off, len);
+ right.write(b, off, len);
+ }
+
+ /**
+ * Write a byte to both output streams.
+ * @param b the byte to write.
+ * @throws IOException on error.
+ */
+ public void write(int b) throws IOException {
+ left.write(b);
+ right.write(b);
+ }
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/TimeoutObserver.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/TimeoutObserver.java
new file mode 100644
index 00000000..ba2e0c76
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/TimeoutObserver.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.util;
+
+/**
+ * Interface for classes that want to be notified by Watchdog.
+ *
+ * @since Ant 1.5
+ *
+ * @see org.apache.tools.ant.util.Watchdog
+ *
+ */
+public interface TimeoutObserver {
+
+ /**
+ * Called when the watchdow times out.
+ *
+ * @param w the watchdog that timed out.
+ */
+ void timeoutOccured(Watchdog w);
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/Tokenizer.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/Tokenizer.java
new file mode 100644
index 00000000..25f89650
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/Tokenizer.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.util;
+
+import java.io.IOException;
+import java.io.Reader;
+
+/**
+ * input stream tokenizers implement this interface
+ *
+ * @version Ant 1.6
+ */
+public interface Tokenizer {
+ /**
+ * get the next token from the input stream
+ * @param in the input stream
+ * @return the next token, or null for the end
+ * of the stream
+ * @throws IOException if an error occurs
+ */
+ String getToken(Reader in) throws IOException;
+
+ /**
+ * return the string between tokens, after the
+ * previous token.
+ * @return the intra-token string
+ */
+ String getPostToken();
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/UUEncoder.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/UUEncoder.java
new file mode 100644
index 00000000..77e1bee1
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/UUEncoder.java
@@ -0,0 +1,148 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.util;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintStream;
+
+/**
+ * UUEncoding of an input stream placed into an outputstream.
+ * This class is meant to be a drop in replacement for
+ * sun.misc.UUEncoder, which was previously used by Ant.
+ * The uuencode algorithm code has been copied from the
+ * geronimo project.
+ **/
+
+public class UUEncoder {
+ protected static final int DEFAULT_MODE = 644;
+ private static final int MAX_CHARS_PER_LINE = 45;
+ private static final int INPUT_BUFFER_SIZE = MAX_CHARS_PER_LINE * 100;
+ private OutputStream out;
+ private String name;
+
+ /**
+ * Constructor specifying a name for the encoded buffer, begin
+ * line will be:
+ * <pre>
+ * begin 644 [NAME]
+ * </pre>
+ * @param name the name of the encoded buffer.
+ */
+ public UUEncoder(String name) {
+ this.name = name;
+ }
+
+ /**
+ * UUEncode bytes from the input stream, and write them as text characters
+ * to the output stream. This method will run until it exhausts the
+ * input stream.
+ * @param is the input stream.
+ * @param out the output stream.
+ * @throws IOException if there is an error.
+ */
+ public void encode(InputStream is, OutputStream out)
+ throws IOException {
+ this.out = out;
+ encodeBegin();
+ byte[] buffer = new byte[INPUT_BUFFER_SIZE];
+ int count;
+ while ((count = is.read(buffer, 0, buffer.length)) != -1) {
+ int pos = 0;
+ while (count > 0) {
+ int num = count > MAX_CHARS_PER_LINE
+ ? MAX_CHARS_PER_LINE
+ : count;
+ encodeLine(buffer, pos, num, out);
+ pos += num;
+ count -= num;
+ }
+ }
+ out.flush();
+ encodeEnd();
+ }
+
+ /**
+ * Encode a string to the output.
+ */
+ private void encodeString(String n) throws IOException {
+ PrintStream writer = new PrintStream(out);
+ writer.print(n);
+ writer.flush();
+ }
+
+ private void encodeBegin() throws IOException {
+ encodeString("begin " + DEFAULT_MODE + " " + name + "\n");
+ }
+
+ private void encodeEnd() throws IOException {
+ encodeString(" \nend\n");
+ }
+
+ /**
+ * Encode a single line of data (less than or equal to 45 characters).
+ *
+ * @param data The array of byte data.
+ * @param off The starting offset within the data.
+ * @param length Length of the data to encode.
+ * @param out The output stream the encoded data is written to.
+ *
+ * @exception IOException
+ */
+ private void encodeLine(
+ byte[] data, int offset, int length, OutputStream out)
+ throws IOException {
+ // write out the number of characters encoded in this line.
+ // CheckStyle:MagicNumber OFF
+ out.write((byte) ((length & 0x3F) + ' '));
+ // CheckStyle:MagicNumber ON
+ byte a;
+ byte b;
+ byte c;
+
+ for (int i = 0; i < length;) {
+ // set the padding defaults
+ b = 1;
+ c = 1;
+ // get the next 3 bytes (if we have them)
+ a = data[offset + i++];
+ if (i < length) {
+ b = data[offset + i++];
+ if (i < length) {
+ c = data[offset + i++];
+ }
+ }
+
+ // CheckStyle:MagicNumber OFF
+ byte d1 = (byte) (((a >>> 2) & 0x3F) + ' ');
+ byte d2 = (byte) ((((a << 4) & 0x30) | ((b >>> 4) & 0x0F)) + ' ');
+ byte d3 = (byte) ((((b << 2) & 0x3C) | ((c >>> 6) & 0x3)) + ' ');
+ byte d4 = (byte) ((c & 0x3F) + ' ');
+ // CheckStyle:MagicNumber ON
+
+ out.write(d1);
+ out.write(d2);
+ out.write(d3);
+ out.write(d4);
+ }
+
+ // terminate with a linefeed alone
+ out.write('\n');
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/UnPackageNameMapper.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/UnPackageNameMapper.java
new file mode 100644
index 00000000..1777279d
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/UnPackageNameMapper.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.util;
+
+import java.io.File;
+
+/**
+ * Maps dotted package name matches to a directory name.
+ * This is the inverse of the package mapper.
+ * This is useful for matching XML formatter results against their JUnit test
+ * cases.
+ * <pre>
+ * &lt;mapper classname="org.apache.tools.ant.util.UnPackageNameMapper"
+ * from="${test.data.dir}/TEST-*Test.xml" to="*Test.java"&gt;
+ * </pre>
+ *
+ *
+ */
+public class UnPackageNameMapper extends GlobPatternMapper {
+ /**
+ * Returns the part of the given string that matches the * in the
+ * &quot;from&quot; pattern replacing dots with file separators
+ *
+ *@param name Source filename
+ *@return Replaced variable part
+ */
+ protected String extractVariablePart(String name) {
+ String var = name.substring(prefixLength,
+ name.length() - postfixLength);
+ return var.replace('.', File.separatorChar);
+ }
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/UnicodeUtil.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/UnicodeUtil.java
new file mode 100644
index 00000000..d3e5eec3
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/UnicodeUtil.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.util;
+
+/**
+ * Contains one helper method to create a backslash u escape
+ *
+ * @since Ant 1.8.3
+ */
+public class UnicodeUtil {
+
+ private UnicodeUtil() {
+ }
+
+ /**
+ * returns the unicode representation of a char without the leading backslash
+ * @param ch
+ * @return unicode representation of a char for property files
+ */
+ public static StringBuffer EscapeUnicode(char ch) {
+ StringBuffer unicodeBuf = new StringBuffer("u0000");
+ String s = Integer.toHexString(ch);
+ //replace the last 0s by the chars contained in s
+ for (int i = 0; i < s.length(); i++) {
+ unicodeBuf.setCharAt(unicodeBuf.length()
+ - s.length() + i,
+ s.charAt(i));
+ }
+ return unicodeBuf;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/VectorSet.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/VectorSet.java
new file mode 100644
index 00000000..db13129d
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/VectorSet.java
@@ -0,0 +1,242 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.util;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.Set;
+import java.util.Vector;
+
+/**
+ * Subclass of Vector that won't store duplicate entries and shows
+ * HashSet's constant time performance characteristics for the
+ * contains method.
+ *
+ * <p>This is not a general purpose class but has been written because
+ * the protected members of {@link
+ * org.apache.tools.ant.DirectoryScanner DirectoryScanner} prohibited
+ * later revisions from using a more efficient collection.</p>
+ *
+ * <p>Methods are synchronized to keep Vector's contract.</p>
+ *
+ * @since Ant 1.8.0
+ */
+public final class VectorSet<E> extends Vector<E> {
+ private static final long serialVersionUID = 1L;
+
+ private final HashSet<E> set = new HashSet<E>();
+
+ public VectorSet() { super(); }
+
+ public VectorSet(int initialCapacity) { super(initialCapacity); }
+
+ public VectorSet(int initialCapacity, int capacityIncrement) {
+ super(initialCapacity, capacityIncrement);
+ }
+
+ public VectorSet(Collection<? extends E> c) {
+ if (c != null) {
+ for (E e : c) {
+ add(e);
+ }
+ }
+ }
+
+ public synchronized boolean add(E o) {
+ if (!set.contains(o)) {
+ doAdd(size(), o);
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * This implementation may not add the element at the given index
+ * if it is already contained in the collection.
+ */
+ public void add(int index, E o) {
+ doAdd(index, o);
+ }
+
+ private synchronized void doAdd(int index, E o) {
+ // Vector.add seems to delegate to insertElementAt, but this
+ // is not documented so we may better implement it ourselves
+ if (set.add(o)) {
+ int count = size();
+ ensureCapacity(count + 1);
+ if (index != count) {
+ System.arraycopy(elementData, index, elementData, index + 1,
+ count - index);
+ }
+ elementData[index] = o;
+ elementCount++;
+ }
+ }
+
+ public synchronized void addElement(E o) {
+ doAdd(size(), o);
+ }
+
+ public synchronized boolean addAll(Collection<? extends E> c) {
+ boolean changed = false;
+ for (E e : c) {
+ changed |= add(e);
+ }
+ return changed;
+ }
+
+ /**
+ * This implementation may not add all elements at the given index
+ * if any of them are already contained in the collection.
+ */
+ public synchronized boolean addAll(int index, Collection<? extends E> c) {
+ LinkedList toAdd = new LinkedList();
+ for (E e : c) {
+ if (set.add(e)) {
+ toAdd.add(e);
+ }
+ }
+ if (toAdd.isEmpty()) {
+ return false;
+ }
+ int count = size();
+ ensureCapacity(count + toAdd.size());
+ if (index != count) {
+ System.arraycopy(elementData, index, elementData, index + toAdd.size(),
+ count - index);
+ }
+ for (Object o : toAdd) {
+ elementData[index++] = o;
+ }
+ elementCount += toAdd.size();
+ return true;
+ }
+
+ public synchronized void clear() {
+ super.clear();
+ set.clear();
+ }
+
+ public Object clone() {
+ @SuppressWarnings("unchecked")
+ final VectorSet<E> vs = (VectorSet<E>) super.clone();
+ vs.set.addAll(set);
+ return vs;
+ }
+
+ public synchronized boolean contains(Object o) {
+ return set.contains(o);
+ }
+
+ public synchronized boolean containsAll(Collection<?> c) {
+ return set.containsAll(c);
+ }
+
+ public void insertElementAt(E o, int index) {
+ doAdd(index, o);
+ }
+
+ public synchronized E remove(int index) {
+ E o = get(index);
+ remove(o);
+ return o;
+ }
+
+ public boolean remove(Object o) {
+ return doRemove(o);
+ }
+
+ private synchronized boolean doRemove(Object o) {
+ // again, remove seems to delegate to removeElement, but we
+ // shouldn't trust it
+ if (set.remove(o)) {
+ int index = indexOf(o);
+ if (index < elementData.length - 1) {
+ System.arraycopy(elementData, index + 1, elementData, index,
+ elementData.length - index - 1);
+ }
+ elementCount--;
+ return true;
+ }
+ return false;
+ }
+
+ public synchronized boolean removeAll(Collection<?> c) {
+ boolean changed = false;
+ for (Object o : c) {
+ changed |= remove(o);
+ }
+ return changed;
+ }
+
+ public synchronized void removeAllElements() {
+ set.clear();
+ super.removeAllElements();
+ }
+
+ public boolean removeElement(Object o) {
+ return doRemove(o);
+ }
+
+ public synchronized void removeElementAt(int index) {
+ remove(get(index));
+ }
+
+ public synchronized void removeRange(final int fromIndex, int toIndex) {
+ while (toIndex > fromIndex) {
+ remove(--toIndex);
+ }
+ }
+
+ public synchronized boolean retainAll(Collection<?> c) {
+ if (!(c instanceof Set)) {
+ c = new HashSet<Object>(c);
+ }
+ LinkedList<E> l = new LinkedList<E>();
+ for (E o : this) {
+ if (!c.contains(o)) {
+ l.addLast(o);
+ }
+ }
+ if (!l.isEmpty()) {
+ removeAll(l);
+ return true;
+ }
+ return false;
+ }
+
+ public synchronized E set(int index, E o) {
+ E orig = get(index);
+ if (set.add(o)) {
+ elementData[index] = o;
+ set.remove(orig);
+ } else {
+ int oldIndexOfO = indexOf(o);
+ remove(o);
+ remove(orig);
+ add(oldIndexOfO > index ? index : index - 1, o);
+ }
+ return orig;
+ }
+
+ public void setElementAt(E o, int index) {
+ set(index, o);
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/Watchdog.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/Watchdog.java
new file mode 100644
index 00000000..318b5264
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/Watchdog.java
@@ -0,0 +1,128 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.util;
+
+import java.util.Enumeration;
+import java.util.Vector;
+
+/**
+ * Generalization of <code>ExecuteWatchdog</code>
+ *
+ * @since Ant 1.5
+ *
+ * @see org.apache.tools.ant.taskdefs.ExecuteWatchdog
+ *
+ */
+public class Watchdog implements Runnable {
+
+ private Vector observers = new Vector(1);
+ private long timeout = -1;
+ /**
+ * marked as volatile to stop the compiler caching values or (in java1.5+,
+ * reordering access)
+ */
+ private volatile boolean stopped = false;
+ /**
+ * Error string.
+ * {@value}
+ */
+ public static final String ERROR_INVALID_TIMEOUT = "timeout less than 1.";
+
+ /**
+ * Constructor for Watchdog.
+ * @param timeout the timeout to use in milliseconds (must be &gt;= 1).
+ */
+ public Watchdog(long timeout) {
+ if (timeout < 1) {
+ throw new IllegalArgumentException(ERROR_INVALID_TIMEOUT);
+ }
+ this.timeout = timeout;
+ }
+
+ /**
+ * Add a timeout observer.
+ * @param to the timeout observer to add.
+ */
+ public void addTimeoutObserver(TimeoutObserver to) {
+ //no need to synchronize, as Vector is always synchronized
+ observers.addElement(to);
+ }
+
+ /**
+ * Remove a timeout observer.
+ * @param to the timeout observer to remove.
+ */
+ public void removeTimeoutObserver(TimeoutObserver to) {
+ //no need to synchronize, as Vector is always synchronized
+ observers.removeElement(to);
+ }
+
+ /**
+ * Inform the observers that a timeout has occurred.
+ * This happens in the watchdog thread.
+ */
+ protected final void fireTimeoutOccured() {
+ Enumeration e = observers.elements();
+ while (e.hasMoreElements()) {
+ ((TimeoutObserver) e.nextElement()).timeoutOccured(this);
+ }
+ }
+
+ /**
+ * Start the watch dog.
+ */
+ public synchronized void start() {
+ stopped = false;
+ Thread t = new Thread(this, "WATCHDOG");
+ t.setDaemon(true);
+ t.start();
+ }
+
+ /**
+ * Stop the watch dog.
+ */
+ public synchronized void stop() {
+ stopped = true;
+ notifyAll();
+ }
+
+ /**
+ * The run method of the watch dog thread.
+ * This simply does a wait for the timeout time, and
+ * if the stop flag has not been set when the wait has returned or
+ * has been interrupted, the watch dog listeners are informed.
+ */
+ public synchronized void run() {
+ long now = System.currentTimeMillis();
+ final long until = now + timeout;
+
+ try {
+ while (!stopped && until > now) {
+ wait(until - now);
+ now = System.currentTimeMillis();
+ }
+ } catch (InterruptedException e) {
+ // Ignore exception
+ }
+ if (!stopped) {
+ fireTimeoutOccured();
+ }
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/WeakishReference.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/WeakishReference.java
new file mode 100644
index 00000000..92f322fb
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/WeakishReference.java
@@ -0,0 +1,91 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.util;
+
+
+import java.lang.ref.WeakReference;
+
+/**
+ * These classes are part of some code to reduce memory leaks by only
+ * retaining weak references to things
+ * on Java1.2+, and yet still work (with leaky hard references) on Java1.1.
+ * Now that Ant is 1.2+ only,
+ * life is simpler and none of the classes are needed any more.
+ *
+ * They are only retained in case a third-party task uses them
+ * @since ant1.6
+ * @see org.apache.tools.ant.util.optional.WeakishReference12
+ * @deprecated deprecated 1.7; will be removed in Ant1.8
+ * Just use {@link java.lang.ref.WeakReference} directly.
+ */
+public class WeakishReference {
+
+
+ private WeakReference weakref;
+
+ /**
+ * create a new soft reference, which is bound to a
+ * Weak reference inside
+ *
+ * @param reference
+ * @see java.lang.ref.WeakReference
+ */
+ WeakishReference(Object reference) {
+ this.weakref = new WeakReference(reference);
+ }
+
+ /**
+ * Returns this reference object's referent. If this reference object has
+ * been cleared, then this method returns <code>null</code>.
+ *
+ * @return The object to which this reference refers, or
+ * <code>null</code> if this reference object has been cleared.
+ */
+ public Object get() {
+ return weakref.get();
+ }
+
+ /**
+ * create the appropriate type of reference for the java version
+ * @param object the object that the reference will refer to.
+ * @return reference to the Object.
+ */
+ public static WeakishReference createReference(Object object) {
+ return new WeakishReference(object);
+ }
+
+
+ /**
+ * This was a hard reference for Java 1.1. Since Ant1.7,
+ * @deprecated since 1.7.
+ * Hopefully nobody is using this.
+ */
+ public static class HardReference extends WeakishReference {
+
+ /**
+ * constructor.
+ * @param object the object that the reference will refer to.
+ */
+ public HardReference(Object object) {
+ super(object);
+ }
+
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/WorkerAnt.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/WorkerAnt.java
new file mode 100644
index 00000000..288d74dd
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/WorkerAnt.java
@@ -0,0 +1,172 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.util;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Task;
+
+/**
+ * A worker ant executes a single task in a background thread.
+ * After the run, any exception thrown is turned into a buildexception, which can be
+ * rethrown, the finished attribute is set, then notifyAll() is called,
+ * so that anyone waiting on the same notify object gets woken up.
+ * <p>
+ * This class is effectively a superset of
+ * {@link org.apache.tools.ant.taskdefs.Parallel.TaskRunnable}
+ *
+ * @since Ant 1.8
+ */
+
+public class WorkerAnt extends Thread {
+
+ private Task task;
+ private Object notify;
+ private volatile boolean finished = false;
+ private volatile BuildException buildException;
+ private volatile Throwable exception;
+
+ /**
+ * Error message if invoked with no task
+ */
+ public static final String ERROR_NO_TASK = "No task defined";
+
+
+ /**
+ * Create the worker.
+ * <p>
+ * This does not start the thread, merely configures it.
+ * @param task the task
+ * @param notify what to notify
+ */
+ public WorkerAnt(Task task, Object notify) {
+ this.task = task;
+ this.notify = notify != null ? notify : this;
+ }
+
+ /**
+ * Create the worker, using the worker as the notification point.
+ * <p>
+ * This does not start the thread, merely configures it.
+ * @param task the task
+ */
+ public WorkerAnt(Task task) {
+ this(task, null);
+ }
+
+ /**
+ * Get any build exception.
+ * This would seem to be oversynchronised, but know that Java pre-1.5 can
+ * reorder volatile access.
+ * The synchronized attribute is to force an ordering.
+ *
+ * @return the exception or null
+ */
+ public synchronized BuildException getBuildException() {
+ return buildException;
+ }
+
+ /**
+ * Get whatever was thrown, which may or may not be a buildException.
+ * Assertion: getException() instanceof BuildException &lt;=&gt; getBuildException()==getException()
+ * @return the exception.
+ */
+ public synchronized Throwable getException() {
+ return exception;
+ }
+
+
+ /**
+ * Get the task
+ * @return the task
+ */
+ public Task getTask() {
+ return task;
+ }
+
+
+ /**
+ * Query the task/thread for being finished.
+ * This would seem to be oversynchronised, but know that Java pre-1.5 can
+ * reorder volatile access.
+ * The synchronized attribute is to force an ordering.
+ * @return true if the task is finished.
+ */
+ public synchronized boolean isFinished() {
+ return finished;
+ }
+
+ /**
+ * Block on the notify object and so wait until the thread is finished.
+ * @param timeout timeout in milliseconds
+ * @throws InterruptedException if the execution was interrupted
+ */
+ public void waitUntilFinished(long timeout) throws InterruptedException {
+ synchronized (notify) {
+ if (!finished) {
+ notify.wait(timeout);
+ }
+ }
+ }
+
+ /**
+ * Raise an exception if one was caught
+ *
+ * @throws BuildException if one has been picked up
+ */
+ public void rethrowAnyBuildException() {
+ BuildException ex = getBuildException();
+ if (ex != null) {
+ throw ex;
+ }
+ }
+
+
+ /**
+ * Handle a caught exception, by recording it and possibly wrapping it
+ * in a BuildException for later rethrowing.
+ * @param thrown what was caught earlier
+ */
+ private synchronized void caught(Throwable thrown) {
+ exception = thrown;
+ buildException = (thrown instanceof BuildException)
+ ? (BuildException) thrown
+ : new BuildException(thrown);
+ }
+
+ /**
+ * Run the task, which is skipped if null.
+ * When invoked again, the task is re-run.
+ */
+ public void run() {
+ try {
+ if (task != null) {
+ task.execute();
+ }
+ } catch (Throwable thrown) {
+ caught(thrown);
+ } finally {
+ synchronized (notify) {
+ finished = true;
+ //reset the task.
+ //wake up our owner, if it is waiting
+ notify.notifyAll();
+ }
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/XMLFragment.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/XMLFragment.java
new file mode 100644
index 00000000..36a6158e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/XMLFragment.java
@@ -0,0 +1,155 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.util;
+
+import org.apache.tools.ant.DynamicConfiguratorNS;
+import org.apache.tools.ant.DynamicElementNS;
+import org.apache.tools.ant.ProjectComponent;
+import org.w3c.dom.Document;
+import org.w3c.dom.DocumentFragment;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.Text;
+
+/**
+ * Use this class as a nested element if you want to get a literal DOM
+ * fragment of something nested into your task/type.
+ *
+ * <p>This is useful for tasks that want to deal with the "real" XML
+ * from the build file instead of objects.</p>
+ *
+ * <p>Code heavily influenced by code written by Dominique Devienne.</p>
+ *
+ * @since Ant 1.7
+ */
+public class XMLFragment extends ProjectComponent implements DynamicElementNS {
+
+ private Document doc;
+ private DocumentFragment fragment;
+
+ /**
+ * Constructor for XMLFragment object.
+ */
+ public XMLFragment() {
+ doc = JAXPUtils.getDocumentBuilder().newDocument();
+ fragment = doc.createDocumentFragment();
+ }
+
+ /**
+ * @return the DocumentFragment that corresponds to the nested
+ * structure.
+ */
+ public DocumentFragment getFragment() {
+ return fragment;
+ }
+
+ /**
+ * Add nested text, expanding properties as we go
+ * @param s the text to add
+ */
+ public void addText(String s) {
+ addText(fragment, s);
+ }
+
+ /**
+ * Creates a nested element.
+ * @param uri the uri of the nested element
+ * @param name the localname of the nested element
+ * @param qName the qualified name of the nested element
+ * @return an object that the element is applied to
+ */
+ public Object createDynamicElement(String uri, String name, String qName) {
+ Element e = null;
+ if (uri.equals("")) {
+ e = doc.createElement(name);
+ } else {
+ e = doc.createElementNS(uri, qName);
+ }
+ fragment.appendChild(e);
+ return new Child(e);
+ }
+
+ /**
+ * Add text to a node.
+ * @param n node
+ * @param s value
+ */
+ private void addText(Node n, String s) {
+ s = getProject().replaceProperties(s);
+ //only text nodes that are non null after property expansion are added
+ if (s != null && !s.trim().equals("")) {
+ Text t = doc.createTextNode(s.trim());
+ n.appendChild(t);
+ }
+ }
+
+ /**
+ * An object to handle (recursively) nested elements.
+ */
+ public class Child implements DynamicConfiguratorNS {
+ private Element e;
+
+ Child(Element e) {
+ this.e = e;
+ }
+
+ /**
+ * Add nested text.
+ * @param s the text to add
+ */
+ public void addText(String s) {
+ XMLFragment.this.addText(e, s);
+ }
+
+ /**
+ * Sets the attribute
+ * @param uri the uri of the attribute
+ * @param name the localname of the attribute
+ * @param qName the qualified name of the attribute
+ * @param value the value of the attribute
+ */
+ public void setDynamicAttribute(
+ String uri, String name, String qName, String value) {
+ if (uri.equals("")) {
+ e.setAttribute(name, value);
+ } else {
+ e.setAttributeNS(uri, qName, value);
+ }
+ }
+
+ /**
+ * Creates a nested element.
+ * @param uri the uri of the nested element
+ * @param name the localname of the nested element
+ * @param qName the qualified name of the nested element
+ * @return an object that the element is applied to
+ */
+ public Object createDynamicElement(String uri, String name, String qName) {
+ Element e2 = null;
+ if (uri.equals("")) {
+ e2 = doc.createElement(name);
+ } else {
+ e2 = doc.createElementNS(uri, qName);
+ }
+ e.appendChild(e2);
+ return new Child(e2);
+ }
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/XmlConstants.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/XmlConstants.java
new file mode 100644
index 00000000..d8eaa02e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/XmlConstants.java
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.util;
+
+/**
+ * XML Parser constants, all kept in one place for ease of reuse
+ * @see <a href="http://xml.apache.org/xerces-j/features.html">Xerces features</a>
+ * @see <a href="http://xml.apache.org/xerces-j/properties.html">Xerces properties</a>
+ * @see <a href=
+ * "http://www.saxproject.org/apidoc/org/xml/sax/package-summary.html#package_description"
+ * >SAX.</a>
+ */
+
+public class XmlConstants {
+
+ private XmlConstants() {
+ }
+
+ /** property for location of xml schema */
+ public static final String PROPERTY_SCHEMA_LOCATION =
+ "http://apache.org/xml/properties/schema/external-schemaLocation";
+ /** property for location of no-name schema */
+ public static final String PROPERTY_NO_NAMESPACE_SCHEMA_LOCATION =
+ "http://apache.org/xml/properties/schema/external-noNamespaceSchemaLocation";
+ /** property for full validation */
+ public static final String FEATURE_XSD_FULL_VALIDATION =
+ "http://apache.org/xml/features/validation/schema-full-checking";
+ /** property for xsd */
+ public static final String FEATURE_XSD = "http://apache.org/xml/features/validation/schema";
+
+ /** property for validation */
+ public static final String FEATURE_VALIDATION = "http://xml.org/sax/features/validation";
+ /** property for namespace support */
+ public static final String FEATURE_NAMESPACES = "http://xml.org/sax/features/namespaces";
+ /** property for schema language */
+ public static final String FEATURE_JAXP12_SCHEMA_LANGUAGE =
+ "http://java.sun.com/xml/jaxp/properties/schemaLanguage";
+ /** property for schema source */
+ public static final String FEATURE_JAXP12_SCHEMA_SOURCE =
+ "http://java.sun.com/xml/jaxp/properties/schemaSource";
+ /** the namespace for XML schema */
+ public static final String URI_XSD =
+ "http://www.w3.org/2001/XMLSchema";
+ /** the sax external entities feature */
+ public static final String FEATURE_EXTERNAL_ENTITIES =
+ "http://xml.org/sax/features/external-general-entities";
+ /** the apache.org/xml disallow doctype decl feature */
+ public static final String FEATURE_DISALLOW_DTD =
+ "http://apache.org/xml/features/disallow-doctype-decl";
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/depend/AbstractAnalyzer.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/depend/AbstractAnalyzer.java
new file mode 100644
index 00000000..5c95d75b
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/depend/AbstractAnalyzer.java
@@ -0,0 +1,286 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.util.depend;
+import java.io.File;
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.Vector;
+import java.util.zip.ZipFile;
+
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.util.VectorSet;
+
+/**
+ * An abstract implementation of the analyzer interface providing support
+ * for the bulk of interface methods.
+ *
+ */
+public abstract class AbstractAnalyzer implements DependencyAnalyzer {
+ /** Maximum number of loops for looking for indirect dependencies. */
+ public static final int MAX_LOOPS = 1000;
+
+ /** The source path for the source files */
+ private Path sourcePath = new Path(null);
+
+ /** The classpath containg dirs and jars of class files */
+ private Path classPath = new Path(null);
+
+ /** The list of root classes */
+ private final Vector<String> rootClasses = new VectorSet<String>();
+
+ /** true if dependencies have been determined */
+ private boolean determined = false;
+
+ /** the list of File objects that the root classes depend upon */
+ private Vector<File> fileDependencies;
+ /** the list of java classes the root classes depend upon */
+ private Vector<String> classDependencies;
+
+ /** true if indirect dependencies should be gathered */
+ private boolean closure = true;
+
+ /** Setup the analyzer */
+ protected AbstractAnalyzer() {
+ reset();
+ }
+
+ /**
+ * Set the closure flag. If this flag is true the analyzer will traverse
+ * all class relationships until it has collected the entire set of
+ * direct and indirect dependencies
+ *
+ * @param closure true if dependencies should be traversed to determine
+ * indirect dependencies.
+ */
+ public void setClosure(boolean closure) {
+ this.closure = closure;
+ }
+
+ /**
+ * Get the list of files in the file system upon which the root classes
+ * depend. The files will be either the classfiles or jar files upon
+ * which the root classes depend.
+ *
+ * @return an enumeration of File instances.
+ */
+ public Enumeration<File> getFileDependencies() {
+ if (!supportsFileDependencies()) {
+ throw new RuntimeException("File dependencies are not supported "
+ + "by this analyzer");
+ }
+ if (!determined) {
+ determineDependencies(fileDependencies, classDependencies);
+ }
+ return fileDependencies.elements();
+ }
+
+ /**
+ * Get the list of classes upon which root classes depend. This is a
+ * list of Java classnames in dot notation.
+ *
+ * @return an enumeration of Strings, each being the name of a Java
+ * class in dot notation.
+ */
+ public Enumeration<String> getClassDependencies() {
+ if (!determined) {
+ determineDependencies(fileDependencies, classDependencies);
+ }
+ return classDependencies.elements();
+ }
+
+ /**
+ * Get the file that contains the class definition
+ *
+ * @param classname the name of the required class
+ * @return the file instance, zip or class, containing the
+ * class or null if the class could not be found.
+ * @exception IOException if the files in the classpath cannot be read.
+ */
+ public File getClassContainer(String classname) throws IOException {
+ String classLocation = classname.replace('.', '/') + ".class";
+ // we look through the classpath elements. If the element is a dir
+ // we look for the file. IF it is a zip, we look for the zip entry
+ return getResourceContainer(classLocation, classPath.list());
+ }
+
+ /**
+ * Get the file that contains the class source.
+ *
+ * @param classname the name of the required class
+ * @return the file instance, zip or java, containing the
+ * source or null if the source for the class could not be found.
+ * @exception IOException if the files in the sourcepath cannot be read.
+ */
+ public File getSourceContainer(String classname) throws IOException {
+ String sourceLocation = classname.replace('.', '/') + ".java";
+
+ // we look through the source path elements. If the element is a dir
+ // we look for the file. If it is a zip, we look for the zip entry.
+ // This isn't normal for source paths but we get it for free
+ return getResourceContainer(sourceLocation, sourcePath.list());
+ }
+
+ /**
+ * Add a source path to the source path used by this analyzer. The
+ * elements in the given path contain the source files for the classes
+ * being analyzed. Not all analyzers will use this information.
+ *
+ * @param sourcePath The Path instance specifying the source path
+ * elements.
+ */
+ public void addSourcePath(Path sourcePath) {
+ if (sourcePath == null) {
+ return;
+ }
+ this.sourcePath.append(sourcePath);
+ this.sourcePath.setProject(sourcePath.getProject());
+ }
+
+ /**
+ * Add a classpath to the classpath being used by the analyzer. The
+ * classpath contains the binary classfiles for the classes being
+ * analyzed The elements may either be the directories or jar files.Not
+ * all analyzers will use this information.
+ *
+ * @param classPath the Path instance specifying the classpath elements
+ */
+ public void addClassPath(Path classPath) {
+ if (classPath == null) {
+ return;
+ }
+
+ this.classPath.append(classPath);
+ this.classPath.setProject(classPath.getProject());
+ }
+
+ /**
+ * Add a root class. The root classes are used to drive the
+ * determination of dependency information. The analyzer will start at
+ * the root classes and add dependencies from there.
+ *
+ * @param className the name of the class in Java dot notation.
+ */
+ public void addRootClass(String className) {
+ if (className == null) {
+ return;
+ }
+ if (!rootClasses.contains(className)) {
+ rootClasses.addElement(className);
+ }
+ }
+
+ /**
+ * Configure an aspect of the analyzer. The set of aspects that are
+ * supported is specific to each analyzer instance.
+ *
+ * @param name the name of the aspect being configured
+ * @param info the configuration info.
+ */
+ public void config(String name, Object info) {
+ // do nothing by default
+ }
+
+ /**
+ * Reset the dependency list. This will reset the determined
+ * dependencies and the also list of root classes.
+ */
+ public void reset() {
+ rootClasses.removeAllElements();
+ determined = false;
+ fileDependencies = new Vector<File>();
+ classDependencies = new Vector<String>();
+ }
+
+ /**
+ * Get an enumeration of the root classes
+ *
+ * @return an enumeration of Strings, each of which is a class name
+ * for a root class.
+ */
+ protected Enumeration<String> getRootClasses() {
+ return rootClasses.elements();
+ }
+
+ /**
+ * Indicate if the analyzer is required to follow
+ * indirect class relationships.
+ *
+ * @return true if indirect relationships should be followed.
+ */
+ protected boolean isClosureRequired() {
+ return closure;
+ }
+
+ /**
+ * Determine the dependencies of the current set of root classes
+ *
+ * @param files a vector into which Files upon which the root classes
+ * depend should be placed.
+ * @param classes a vector of Strings into which the names of classes
+ * upon which the root classes depend should be placed.
+ */
+ protected abstract void determineDependencies(Vector<File> files, Vector<String> classes);
+
+ /**
+ * Indicate if the particular subclass supports file dependency
+ * information.
+ *
+ * @return true if file dependencies are supported.
+ */
+ protected abstract boolean supportsFileDependencies();
+
+ /**
+ * Get the file that contains the resource
+ *
+ * @param resourceLocation the name of the required resource.
+ * @param paths the paths which will be searched for the resource.
+ * @return the file instance, zip or class, containing the
+ * class or null if the class could not be found.
+ * @exception IOException if the files in the given paths cannot be read.
+ */
+ private File getResourceContainer(String resourceLocation, String[] paths)
+ throws IOException {
+ for (int i = 0; i < paths.length; ++i) {
+ File element = new File(paths[i]);
+ if (!element.exists()) {
+ continue;
+ }
+ if (element.isDirectory()) {
+ File resource = new File(element, resourceLocation);
+ if (resource.exists()) {
+ return resource;
+ }
+ } else {
+ // must be a zip of some sort
+ ZipFile zipFile = null;
+ try {
+ zipFile = new ZipFile(element);
+ if (zipFile.getEntry(resourceLocation) != null) {
+ return element;
+ }
+ } finally {
+ if (zipFile != null) {
+ zipFile.close();
+ }
+ }
+ }
+ }
+ return null;
+ }
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/depend/DependencyAnalyzer.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/depend/DependencyAnalyzer.java
new file mode 100644
index 00000000..1415e2e4
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/depend/DependencyAnalyzer.java
@@ -0,0 +1,130 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.util.depend;
+import java.io.File;
+import java.io.IOException;
+import java.util.Enumeration;
+
+import org.apache.tools.ant.types.Path;
+
+/**
+ * A dependency analyzer analyzes dependencies between Java classes to
+ * determine the minimal set of classes which are required by a set of
+ * &quot;root&quot; classes. Different implementations of this interface can
+ * use different strategies and libraries to determine the required set. For
+ * example, some analyzers will use class files while others might use
+ * source files. Analyzer specific configuration is catered for through a
+ * generic configure method
+ *
+ */
+public interface DependencyAnalyzer {
+ /**
+ * Add a source path to the source path used by this analyzer. The
+ * elements in the given path contain the source files for the classes
+ * being analyzed. Not all analyzers will use this information.
+ *
+ * @param sourcePath The Path instance specifying the source path
+ * elements.
+ */
+ void addSourcePath(Path sourcePath);
+
+ /**
+ * Add a classpath to the classpath being used by the analyzer. The
+ * classpath contains the binary classfiles for the classes being
+ * analyzed The elements may either be the directories or jar files.Not
+ * all analyzers will use this information.
+ *
+ * @param classpath the Path instance specifying the classpath elements
+ */
+ void addClassPath(Path classpath);
+
+ /**
+ * Add a root class. The root classes are used to drive the
+ * determination of dependency information. The analyzer will start at
+ * the root classes and add dependencies from there.
+ *
+ * @param classname the name of the class in Java dot notation.
+ */
+ void addRootClass(String classname);
+
+ /**
+ * Get the list of files in the file system upon which the root classes
+ * depend. The files will be either the classfiles or jar files upon
+ * which the root classes depend.
+ *
+ * @return an enumeration of File instances.
+ */
+ Enumeration<File> getFileDependencies();
+
+ /**
+ * Get the list of classes upon which root classes depend. This is a
+ * list of Java classnames in dot notation.
+ *
+ * @return an enumeration of Strings, each being the name of a Java
+ * class in dot notation.
+ */
+ Enumeration<String> getClassDependencies();
+
+
+ /**
+ * Reset the dependency list. This will reset the determined
+ * dependencies and the also list of root classes.
+ */
+ void reset();
+
+ /**
+ * Configure an aspect of the analyzer. The set of aspects that are
+ * supported is specific to each analyzer instance.
+ *
+ * @param name the name of the aspect being configured
+ * @param info the configuration information.
+ */
+ void config(String name, Object info);
+
+ /**
+ * Set the closure flag. If this flag is true the analyzer will traverse
+ * all class relationships until it has collected the entire set of
+ * direct and indirect dependencies
+ *
+ * @param closure true if dependencies should be traversed to determine
+ * indirect dependencies.
+ */
+ void setClosure(boolean closure);
+
+
+ /**
+ * Get the file that contains the class definition
+ *
+ * @param classname the name of the required class
+ * @return the file instance, zip or class, containing the
+ * class or null if the class could not be found.
+ * @exception IOException if the files in the classpath cannot be read.
+ */
+ File getClassContainer(String classname) throws IOException;
+
+ /**
+ * Get the file that contains the class source.
+ *
+ * @param classname the name of the required class
+ * @return the file instance, zip or java, containing the
+ * source or null if the source for the class could not be found.
+ * @exception IOException if the files in the sourcepath cannot be read.
+ */
+ File getSourceContainer(String classname) throws IOException;
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/depend/bcel/AncestorAnalyzer.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/depend/bcel/AncestorAnalyzer.java
new file mode 100644
index 00000000..2bd2a6cf
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/depend/bcel/AncestorAnalyzer.java
@@ -0,0 +1,144 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.util.depend.bcel;
+import java.io.File;
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Vector;
+import org.apache.bcel.classfile.ClassParser;
+import org.apache.bcel.classfile.JavaClass;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.util.depend.AbstractAnalyzer;
+
+/**
+ * A dependency analyzer which returns superclass and superinterface
+ * dependencies.
+ *
+ */
+public class AncestorAnalyzer extends AbstractAnalyzer {
+
+ /**
+ * Default constructor
+ *
+ * Causes the BCEL classes to load to ensure BCEL dependencies can
+ * be satisfied
+ */
+ public AncestorAnalyzer() {
+ // force BCEL classes to load now
+ try {
+ new ClassParser("force");
+ } catch (Exception e) {
+ // all released versions of BCEL may throw an IOException
+ // here, but BCEL's trunk does no longer declare to do so
+ if (!(e instanceof IOException)) {
+ throw new BuildException(e);
+ }
+ // ignore IOException like we've always done
+ }
+ }
+
+ /**
+ * Determine the dependencies of the configured root classes.
+ *
+ * @param files a vector to be populated with the files which contain
+ * the dependency classes
+ * @param classes a vector to be populated with the names of the
+ * dependency classes.
+ */
+ protected void determineDependencies(Vector<File> files, Vector<String> classes) {
+ // we get the root classes and build up a set of
+ // classes upon which they depend
+ Hashtable<String, String> dependencies = new Hashtable<String, String>();
+ Hashtable<File, File> containers = new Hashtable<File, File>();
+ Hashtable<String, String> toAnalyze = new Hashtable<String, String>();
+ Hashtable<String, String> nextAnalyze = new Hashtable<String, String>();
+
+ for (Enumeration<String> e = getRootClasses(); e.hasMoreElements();) {
+ String classname = e.nextElement();
+ toAnalyze.put(classname, classname);
+ }
+
+ int count = 0;
+ int maxCount = isClosureRequired() ? MAX_LOOPS : 2;
+ while (toAnalyze.size() != 0 && count++ < maxCount) {
+ nextAnalyze.clear();
+ for (String classname : toAnalyze.keySet()) {
+ dependencies.put(classname, classname);
+ try {
+ File container = getClassContainer(classname);
+ if (container == null) {
+ continue;
+ }
+ containers.put(container, container);
+
+ ClassParser parser = null;
+ if (container.getName().endsWith(".class")) {
+ parser = new ClassParser(container.getPath());
+ } else {
+ parser = new ClassParser(container.getPath(),
+ classname.replace('.', '/') + ".class");
+ }
+
+ JavaClass javaClass = parser.parse();
+ String[] interfaces = javaClass.getInterfaceNames();
+ for (int i = 0; i < interfaces.length; ++i) {
+ String interfaceName = interfaces[i];
+ if (!dependencies.containsKey(interfaceName)) {
+ nextAnalyze.put(interfaceName, interfaceName);
+ }
+ }
+
+ if (javaClass.isClass()) {
+ String superClass = javaClass.getSuperclassName();
+ if (!dependencies.containsKey(superClass)) {
+ nextAnalyze.put(superClass, superClass);
+ }
+ }
+ } catch (IOException ioe) {
+ // ignore
+ }
+ }
+
+ Hashtable<String, String> temp = toAnalyze;
+ toAnalyze = nextAnalyze;
+ nextAnalyze = temp;
+ }
+
+ files.removeAllElements();
+ for (File f : containers.keySet()) {
+ files.add(f);
+ }
+
+ classes.removeAllElements();
+ for (String dependency : dependencies.keySet()) {
+ classes.add(dependency);
+ }
+ }
+
+ /**
+ * Indicate if this analyzer can determine dependent files.
+ *
+ * @return true if the analyzer provides dependency file information.
+ */
+ protected boolean supportsFileDependencies() {
+ return true;
+ }
+
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/depend/bcel/DependencyVisitor.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/depend/bcel/DependencyVisitor.java
new file mode 100644
index 00000000..d31d4534
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/depend/bcel/DependencyVisitor.java
@@ -0,0 +1,192 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.util.depend.bcel;
+
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.StringTokenizer;
+
+import org.apache.bcel.classfile.ConstantClass;
+import org.apache.bcel.classfile.ConstantNameAndType;
+import org.apache.bcel.classfile.ConstantPool;
+import org.apache.bcel.classfile.EmptyVisitor;
+import org.apache.bcel.classfile.Field;
+import org.apache.bcel.classfile.JavaClass;
+import org.apache.bcel.classfile.Method;
+
+/**
+ * A BCEL visitor implementation to collect class dependency information
+ *
+ */
+public class DependencyVisitor extends EmptyVisitor {
+ /** The collected dependencies */
+ private final Hashtable<String, String> dependencies = new Hashtable<String, String>();
+ /**
+ * The current class's constant pool - used to determine class names
+ * from class references.
+ */
+ private ConstantPool constantPool;
+
+ /**
+ * Get the dependencies collected by this visitor
+ *
+ * @return a Enumeration of classnames, being the classes upon which the
+ * visited classes depend.
+ */
+ public Enumeration<String> getDependencies() {
+ return dependencies.keys();
+ }
+
+ /** Clear the current set of collected dependencies. */
+ public void clearDependencies() {
+ dependencies.clear();
+ }
+
+ /**
+ * Visit the constant pool of a class
+ *
+ * @param constantPool the constant pool of the class being visited.
+ */
+ public void visitConstantPool(final ConstantPool constantPool) {
+ this.constantPool = constantPool;
+ }
+
+ /**
+ * Visit a class reference
+ *
+ * @param constantClass the constantClass entry for the class reference
+ */
+ public void visitConstantClass(final ConstantClass constantClass) {
+ final String classname
+ = constantClass.getConstantValue(constantPool).toString();
+ addSlashClass(classname);
+ }
+
+ /**
+ * Visit a name and type ref
+ *
+ * Look for class references in this
+ *
+ * @param obj the name and type reference being visited.
+ */
+ public void visitConstantNameAndType(final ConstantNameAndType obj) {
+ final String name = obj.getName(constantPool);
+ if (obj.getSignature(constantPool).equals("Ljava/lang/Class;")
+ && name.startsWith("class$")) {
+ String classname
+ = name.substring("class$".length()).replace('$', '.');
+ // does the class have a package structure
+ final int index = classname.lastIndexOf(".");
+ if (index > 0) {
+ char start;
+ // check if the package structure is more than 1 level deep
+ final int index2 = classname.lastIndexOf(".", index - 1);
+ if (index2 != -1) {
+ // class name has more than 1 package level 'com.company.Class'
+ start = classname.charAt(index2 + 1);
+ } else {
+ // class name has only 1 package level 'package.Class'
+ start = classname.charAt(0);
+ }
+ // Check to see if it's an inner class 'com.company.Class$Inner'
+ // CheckStyle:MagicNumber OFF
+ if ((start > 0x40) && (start < 0x5B)) {
+ // first letter of the previous segment of the class name 'Class'
+ // is upper case ascii. so according to the spec it's an inner class
+ classname = classname.substring(0, index) + "$"
+ + classname.substring(index + 1);
+ addClass(classname);
+ } else {
+ // Add the class in dotted notation 'com.company.Class'
+ addClass(classname);
+ }
+ // CheckStyle:MagicNumber ON
+ } else {
+ // Add a class with no package 'Class'
+ addClass(classname);
+ }
+ }
+ }
+
+ /**
+ * Visit a field of the class.
+ *
+ * @param field the field being visited
+ */
+ public void visitField(final Field field) {
+ addClasses(field.getSignature());
+ }
+
+ /**
+ * Visit a Java class
+ *
+ * @param javaClass the class being visited.
+ */
+ public void visitJavaClass(final JavaClass javaClass) {
+ addClass(javaClass.getClassName());
+ }
+
+ /**
+ * Visit a method of the current class
+ *
+ * @param method the method being visited.
+ */
+ public void visitMethod(final Method method) {
+ final String signature = method.getSignature();
+ final int pos = signature.indexOf(")");
+ addClasses(signature.substring(1, pos));
+ addClasses(signature.substring(pos + 1));
+ }
+
+ /**
+ * Add a classname to the list of dependency classes
+ *
+ * @param classname the class to be added to the list of dependencies.
+ */
+ void addClass(final String classname) {
+ dependencies.put(classname, classname);
+ }
+
+ /**
+ * Add all the classes from a descriptor string.
+ *
+ * @param string the descriptor string, being descriptors separated by
+ * ';' characters.
+ */
+ private void addClasses(final String string) {
+ final StringTokenizer tokens = new StringTokenizer(string, ";");
+ while (tokens.hasMoreTokens()) {
+ final String descriptor = tokens.nextToken();
+ final int pos = descriptor.indexOf('L');
+ if (pos != -1) {
+ addSlashClass(descriptor.substring(pos + 1));
+ }
+ }
+ }
+
+ /**
+ * Adds a class name in slash format
+ * (for example org/apache/tools/ant/Main).
+ *
+ * @param classname the class name in slash format
+ */
+ private void addSlashClass(final String classname) {
+ addClass(classname.replace('/', '.'));
+ }
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/depend/bcel/FullAnalyzer.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/depend/bcel/FullAnalyzer.java
new file mode 100644
index 00000000..f270fd48
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/depend/bcel/FullAnalyzer.java
@@ -0,0 +1,136 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.util.depend.bcel;
+import java.io.File;
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Vector;
+import org.apache.bcel.classfile.ClassParser;
+import org.apache.bcel.classfile.DescendingVisitor;
+import org.apache.bcel.classfile.JavaClass;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.util.depend.AbstractAnalyzer;
+
+/**
+ * An analyzer capable fo traversing all class - class relationships.
+ *
+ */
+public class FullAnalyzer extends AbstractAnalyzer {
+ /**
+ * Default constructor
+ *
+ * Causes the BCEL classes to load to ensure BCEL dependencies can
+ * be satisfied
+ */
+ public FullAnalyzer() {
+ // force BCEL classes to load now
+ try {
+ new ClassParser("force");
+ } catch (Exception e) {
+ // all released versions of BCEL may throw an IOException
+ // here, but BCEL's trunk does no longer declare to do so
+ if (!(e instanceof IOException)) {
+ throw new BuildException(e);
+ }
+ // ignore IOException like we've always done
+ }
+ }
+
+ /**
+ * Determine the dependencies of the configured root classes.
+ *
+ * @param files a vector to be populated with the files which contain
+ * the dependency classes
+ * @param classes a vector to be populated with the names of the
+ * dependency classes.
+ */
+ protected void determineDependencies(Vector<File> files, Vector<String> classes) {
+ // we get the root classes and build up a set of
+ // classes upon which they depend
+ Hashtable<String, String> dependencies = new Hashtable<String, String>();
+ Hashtable<File, File> containers = new Hashtable<File, File>();
+ Hashtable<String, String> toAnalyze = new Hashtable<String, String>();
+ for (Enumeration<String> e = getRootClasses(); e.hasMoreElements();) {
+ String classname = e.nextElement();
+ toAnalyze.put(classname, classname);
+ }
+
+ int count = 0;
+ int maxCount = isClosureRequired() ? MAX_LOOPS : 2;
+ while (toAnalyze.size() != 0 && count++ < maxCount) {
+ DependencyVisitor dependencyVisitor = new DependencyVisitor();
+ for (String classname : toAnalyze.keySet()) {
+ dependencies.put(classname, classname);
+ try {
+ File container = getClassContainer(classname);
+ if (container == null) {
+ continue;
+ }
+ containers.put(container, container);
+
+ ClassParser parser = null;
+ if (container.getName().endsWith(".class")) {
+ parser = new ClassParser(container.getPath());
+ } else {
+ parser = new ClassParser(container.getPath(),
+ classname.replace('.', '/') + ".class");
+ }
+
+ JavaClass javaClass = parser.parse();
+ DescendingVisitor traverser
+ = new DescendingVisitor(javaClass, dependencyVisitor);
+ traverser.visit();
+ } catch (IOException ioe) {
+ // ignore
+ }
+ }
+
+ toAnalyze.clear();
+
+ // now recover all the dependencies collected and add to the list.
+ Enumeration<String> depsEnum = dependencyVisitor.getDependencies();
+ while (depsEnum.hasMoreElements()) {
+ String className = depsEnum.nextElement();
+ if (!dependencies.containsKey(className)) {
+ toAnalyze.put(className, className);
+ }
+ }
+ }
+
+ files.removeAllElements();
+ for (File f : containers.keySet()) {
+ files.add(f);
+ }
+
+ classes.removeAllElements();
+ for (String dependency : dependencies.keySet()) {
+ classes.add(dependency);
+ }
+ }
+
+ /**
+ * Indicate if this analyzer can determine dependent files.
+ *
+ * @return true if the analyzer provides dependency file information.
+ */
+ protected boolean supportsFileDependencies() {
+ return true;
+ }
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/facade/FacadeTaskHelper.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/facade/FacadeTaskHelper.java
new file mode 100644
index 00000000..4fb4341b
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/facade/FacadeTaskHelper.java
@@ -0,0 +1,165 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.util.facade;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.Path;
+
+/**
+ * Helper class for facade implementations - encapsulates treatment of
+ * explicit implementation choices, magic properties and
+ * implementation specific command line arguments.
+ *
+ *
+ * @since Ant 1.5
+ */
+public class FacadeTaskHelper {
+
+ /**
+ * Command line arguments.
+ */
+ private List<ImplementationSpecificArgument> args = new ArrayList<ImplementationSpecificArgument>();
+
+ /**
+ * The explicitly chosen implementation.
+ */
+ private String userChoice;
+
+ /**
+ * The magic property to consult.
+ */
+ private String magicValue;
+
+ /**
+ * The default value.
+ */
+ private String defaultValue;
+
+ /**
+ * User specified path used as classpath when loading the implementation.
+ */
+ private Path implementationClasspath;
+
+ /**
+ * @param defaultValue The default value for the implementation.
+ * Must not be null.
+ */
+ public FacadeTaskHelper(String defaultValue) {
+ this(defaultValue, null);
+ }
+
+ /**
+ * @param defaultValue The default value for the implementation.
+ * Must not be null.
+ * @param magicValue the value of a magic property that may hold a user.
+ * choice. May be null.
+ */
+ public FacadeTaskHelper(String defaultValue, String magicValue) {
+ this.defaultValue = defaultValue;
+ this.magicValue = magicValue;
+ }
+
+ /**
+ * Used to set the value of the magic property.
+ * @param magicValue the value of a magic property that may hold a user.
+ */
+ public void setMagicValue(String magicValue) {
+ this.magicValue = magicValue;
+ }
+
+ /**
+ * Used for explicit user choices.
+ * @param userChoice the explicitly chosen implementation.
+ */
+ public void setImplementation(String userChoice) {
+ this.userChoice = userChoice;
+ }
+
+ /**
+ * Retrieves the implementation.
+ * @return the implementation.
+ */
+ public String getImplementation() {
+ return userChoice != null ? userChoice
+ : (magicValue != null ? magicValue
+ : defaultValue);
+ }
+
+ /**
+ * Retrieves the explicit user choice.
+ * @return the explicit user choice.
+ */
+ public String getExplicitChoice() {
+ return userChoice;
+ }
+
+ /**
+ * Command line argument.
+ * @param arg an argument to add.
+ */
+ public void addImplementationArgument(ImplementationSpecificArgument arg) {
+ args.add(arg);
+ }
+
+ /**
+ * Retrieves the command line arguments enabled for the current
+ * facade implementation.
+ * @return an array of command line arguments.
+ */
+ public String[] getArgs() {
+ List<String> tmp = new ArrayList<String>(args.size());
+ for (ImplementationSpecificArgument arg : args) {
+ String[] curr = arg.getParts(getImplementation());
+ if (curr != null) {
+ for (int i = 0; i < curr.length; i++) {
+ tmp.add(curr[i]);
+ }
+ }
+ }
+ String[] res = new String[tmp.size()];
+ return (String[]) tmp.toArray(res);
+ }
+
+ /**
+ * Tests whether the implementation has been chosen by the user
+ * (either via a magic property or explicitly.
+ * @return true if magic or user choice has be set.
+ * @since Ant 1.5.2
+ */
+ public boolean hasBeenSet() {
+ return userChoice != null || magicValue != null;
+ }
+
+ /**
+ * The classpath to use when loading the implementation.
+ *
+ * @param project the current project
+ * @return a Path instance that may be appended to
+ * @since Ant 1.8.0
+ */
+ public Path getImplementationClasspath(Project project) {
+ if (implementationClasspath == null) {
+ implementationClasspath = new Path(project);
+ }
+ return implementationClasspath;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/facade/ImplementationSpecificArgument.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/facade/ImplementationSpecificArgument.java
new file mode 100644
index 00000000..ba7f14a0
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/facade/ImplementationSpecificArgument.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.util.facade;
+
+import org.apache.tools.ant.types.Commandline;
+
+/**
+ * Extension of Commandline.Argument with a new attribute that chooses
+ * a specific implementation of the facade.
+ *
+ *
+ * @since Ant 1.5
+ */
+public class ImplementationSpecificArgument extends Commandline.Argument {
+ private String impl;
+
+ /** Constructor for ImplementationSpecificArgument. */
+ public ImplementationSpecificArgument() {
+ super();
+ }
+
+ /**
+ * Set the implementation this argument is for.
+ * @param impl the implementation this command line argument is for.
+ */
+ public void setImplementation(String impl) {
+ this.impl = impl;
+ }
+
+ /**
+ * Return the parts this Argument consists of, if the
+ * implementation matches the chosen implementation.
+ * @see org.apache.tools.ant.types.Commandline.Argument#getParts()
+ * @param chosenImpl the implementation to check against.
+ * @return the parts if the implementation matches or an zero length
+ * array if not.
+ */
+ public final String[] getParts(String chosenImpl) {
+ if (impl == null || impl.equals(chosenImpl)) {
+ return super.getParts();
+ } else {
+ return new String[0];
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/java15/ProxyDiagnostics.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/java15/ProxyDiagnostics.java
new file mode 100644
index 00000000..bd2e7cac
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/java15/ProxyDiagnostics.java
@@ -0,0 +1,108 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.util.java15;
+
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.Proxy;
+import java.net.ProxySelector;
+import java.net.SocketAddress;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.tools.ant.BuildException;
+
+/**
+ * This class exists to create a string that tells diagnostics about the current
+ * state of proxy diagnostics.
+ * It does this in its toString operator.
+ * Java1.5+ is needed to compile this class; its interface is classic typeless
+ * Java.
+ * @since Ant 1.7
+ */
+public class ProxyDiagnostics {
+
+ private String destination;
+
+ private URI destURI;
+
+ /** {@value} */
+ public static final String DEFAULT_DESTINATION = "http://ant.apache.org/";
+
+ /**
+ * create a diagnostics binding for a specific URI
+ * @param destination dest to bind to
+ * @throws BuildException if the URI is malformed.
+ */
+ public ProxyDiagnostics(String destination) {
+ this.destination = destination;
+ try {
+ this.destURI = new URI(destination);
+ } catch (URISyntaxException e) {
+ throw new BuildException(e);
+ }
+ }
+
+ /**
+ * create a proxy diagnostics tool bound to
+ * {@link #DEFAULT_DESTINATION}
+ */
+ public ProxyDiagnostics() {
+ this(DEFAULT_DESTINATION);
+ }
+
+ /**
+ * Get the diagnostics for proxy information.
+ * @return the information.
+ */
+ public String toString() {
+ ProxySelector selector = ProxySelector.getDefault();
+ List list = selector.select(destURI);
+ StringBuffer result = new StringBuffer();
+ Iterator proxies = list.listIterator();
+ while (proxies.hasNext()) {
+ Proxy proxy = (Proxy) proxies.next();
+ SocketAddress address = proxy.address();
+ if (address == null) {
+ result.append("Direct connection\n");
+ } else {
+ result.append(proxy.toString());
+ if (address instanceof InetSocketAddress) {
+ InetSocketAddress ina = (InetSocketAddress) address;
+ result.append(' ');
+ result.append(ina.getHostName());
+ result.append(':');
+ result.append(ina.getPort());
+ if (ina.isUnresolved()) {
+ result.append(" [unresolved]");
+ } else {
+ InetAddress addr = ina.getAddress();
+ result.append(" [");
+ result.append(addr.getHostAddress());
+ result.append(']');
+ }
+ }
+ result.append('\n');
+ }
+ }
+ return result.toString();
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/optional/JavaxScriptRunner.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/optional/JavaxScriptRunner.java
new file mode 100644
index 00000000..a24537ac
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/optional/JavaxScriptRunner.java
@@ -0,0 +1,163 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.util.optional;
+
+import java.util.Iterator;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.util.ReflectWrapper;
+import org.apache.tools.ant.util.ScriptRunnerBase;
+
+/**
+ * This class is used to run scripts using JSR 223.
+ * @since Ant 1.7.0
+ */
+public class JavaxScriptRunner extends ScriptRunnerBase {
+ private ReflectWrapper engine;
+
+ /**
+ * Get the name of the manager prefix.
+ * @return "javax"
+ */
+ public String getManagerName() {
+ return "javax";
+ }
+
+ /** {@inheritDoc}. */
+ public boolean supportsLanguage() {
+ if (engine != null) {
+ return true;
+ }
+ checkLanguage();
+ ClassLoader origLoader = replaceContextLoader();
+ try {
+ return createEngine() != null;
+ } catch (Exception ex) {
+ return false;
+ } finally {
+ restoreContextLoader(origLoader);
+ }
+ }
+
+ /**
+ * Do the work to run the script.
+ *
+ * @param execName the name that will be passed to the
+ * scripting engine for this script execution.
+ *
+ * @exception BuildException if something goes wrong executing the script.
+ */
+ public void executeScript(String execName) throws BuildException {
+ evaluateScript(execName);
+ }
+
+ /**
+ * Do the work to eval the script.
+ *
+ * @param execName the name that will be passed to the
+ * scripting engine for this script execution.
+ * @return the result of the evaluation
+ * @exception BuildException if something goes wrong executing the script.
+ */
+ public Object evaluateScript(String execName) throws BuildException {
+ checkLanguage();
+ ClassLoader origLoader = replaceContextLoader();
+ try {
+ ReflectWrapper engine = createEngine();
+ if (engine == null) {
+ throw new BuildException(
+ "Unable to create javax script engine for "
+ + getLanguage());
+ }
+ for (Iterator i = getBeans().keySet().iterator(); i.hasNext();) {
+ String key = (String) i.next();
+ Object value = getBeans().get(key);
+ if ("FX".equalsIgnoreCase(getLanguage())) {
+ engine.invoke(
+ "put", String.class, key
+ + ":" + value.getClass().getName(),
+ Object.class, value);
+ } else {
+ engine.invoke(
+ "put", String.class, key,
+ Object.class, value);
+ }
+ }
+ // execute the script
+ return engine.invoke("eval", String.class, getScript());
+ } catch (BuildException be) {
+ //catch and rethrow build exceptions
+
+ // this may be a BuildException wrapping a ScriptException
+ // deeply wrapping yet another BuildException - for
+ // example because of self.fail() - see
+ // https://issues.apache.org/bugzilla/show_bug.cgi?id=47509
+ throw unwrap(be);
+ } catch (Exception be) {
+ //any other exception? Get its cause
+ Throwable t = be;
+ Throwable te = be.getCause();
+ if (te != null) {
+ if (te instanceof BuildException) {
+ throw (BuildException) te;
+ } else {
+ t = te;
+ }
+ }
+ throw new BuildException(t);
+ } finally {
+ restoreContextLoader(origLoader);
+ }
+ }
+
+ private ReflectWrapper createEngine() throws Exception {
+ if (engine != null) {
+ return engine;
+ }
+ ReflectWrapper manager = new ReflectWrapper(
+ getClass().getClassLoader(), "javax.script.ScriptEngineManager");
+ Object e = manager.invoke(
+ "getEngineByName", String.class, getLanguage());
+ if (e == null) {
+ return null;
+ }
+ ReflectWrapper ret = new ReflectWrapper(e);
+ if (getKeepEngine()) {
+ this.engine = ret;
+ }
+ return ret;
+ }
+
+ /**
+ * Traverse a Throwable's cause(s) and return the BuildException
+ * most deeply nested into it - if any.
+ */
+ private static BuildException unwrap(Throwable t) {
+ BuildException deepest =
+ t instanceof BuildException ? (BuildException) t : null;
+ Throwable current = t;
+ while (current.getCause() != null) {
+ current = current.getCause();
+ if (current instanceof BuildException) {
+ deepest = (BuildException) current;
+ }
+ }
+ return deepest;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/optional/NoExitSecurityManager.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/optional/NoExitSecurityManager.java
new file mode 100644
index 00000000..e704ab29
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/optional/NoExitSecurityManager.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.util.optional;
+
+import java.security.Permission;
+
+import org.apache.tools.ant.ExitException;
+
+/**
+ * This is intended as a replacement for the default system manager.
+ * The goal is to intercept System.exit calls and make it throw an
+ * exception instead so that a System.exit in a task does not
+ * fully terminate Ant.
+ *
+ * @see ExitException
+ */
+public class NoExitSecurityManager extends SecurityManager {
+
+ /**
+ * Override SecurityManager#checkExit.
+ * This throws an ExitException(status) exception.
+ * @param status the exit status
+ */
+ public void checkExit(int status) {
+ throw new ExitException(status);
+ }
+
+ /**
+ * Override SecurityManager#checkPermission.
+ * This does nothing.
+ * @param perm the requested permission.
+ */
+ public void checkPermission(Permission perm) {
+ // no permission here
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/optional/ScriptRunner.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/optional/ScriptRunner.java
new file mode 100644
index 00000000..0f4cd1f9
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/optional/ScriptRunner.java
@@ -0,0 +1,177 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.util.optional;
+
+import java.util.Hashtable;
+import java.util.Iterator;
+
+import org.apache.bsf.BSFEngine;
+import org.apache.bsf.BSFException;
+import org.apache.bsf.BSFManager;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.util.ReflectUtil;
+import org.apache.tools.ant.util.ScriptRunnerBase;
+
+/**
+ * This class is used to run BSF scripts
+ *
+ */
+public class ScriptRunner extends ScriptRunnerBase {
+ // Register Groovy ourselves, since BSF did not
+ // natively support it in versions previous to 1.2.4.
+ static {
+ BSFManager.registerScriptingEngine(
+ "groovy",
+ "org.codehaus.groovy.bsf.GroovyEngine",
+ new String[] {"groovy", "gy"});
+ }
+
+ private BSFEngine engine;
+ private BSFManager manager;
+
+ /**
+ * Get the name of the manager prefix.
+ * @return "bsf"
+ */
+ public String getManagerName() {
+ return "bsf";
+ }
+
+ /**
+ * Check if bsf supports the language.
+ * @return true if bsf can create an engine for this language.
+ */
+ public boolean supportsLanguage() {
+ Hashtable table = (Hashtable) ReflectUtil.getField(
+ new BSFManager(), "registeredEngines");
+ String engineClassName = (String) table.get(getLanguage());
+ if (engineClassName == null) {
+ getProject().log(
+ "This is no BSF engine class for language '"
+ + getLanguage() + "'",
+ Project.MSG_VERBOSE);
+ return false;
+ }
+ try {
+ getScriptClassLoader().loadClass(engineClassName);
+ return true;
+ } catch (Throwable ex) {
+ getProject().log(
+ "unable to create BSF engine class for language '"
+ + getLanguage() + "'",
+ ex,
+ Project.MSG_VERBOSE);
+ return false;
+ }
+ }
+
+ /**
+ * Do the work.
+ *
+ * @param execName the name that will be passed to BSF for this script execution.
+ * @exception BuildException if something goes wrong executing the script.
+ */
+ public void executeScript(String execName) throws BuildException {
+ checkLanguage();
+ ClassLoader origLoader = replaceContextLoader();
+ try {
+ BSFManager m = createManager();
+ declareBeans(m);
+ // execute the script
+ if (engine == null) {
+ m.exec(getLanguage(), execName, 0, 0, getScript());
+ } else {
+ engine.exec(execName, 0, 0, getScript());
+ }
+ } catch (BSFException be) {
+ throw getBuildException(be);
+ } finally {
+ restoreContextLoader(origLoader);
+ }
+ }
+
+ /**
+ * Evaluate the script.
+ *
+ * @param execName the name that will be passed to BSF for this script execution.
+ * @return the result of the evaluation
+ * @exception BuildException if something goes wrong executing the script.
+ */
+ public Object evaluateScript(String execName) throws BuildException {
+ checkLanguage();
+ ClassLoader origLoader = replaceContextLoader();
+ try {
+ BSFManager m = createManager();
+ declareBeans(m);
+ // execute the script
+ if (engine == null) {
+ return m.eval(getLanguage(), execName, 0, 0, getScript());
+ }
+ return engine.eval(execName, 0, 0, getScript());
+ } catch (BSFException be) {
+ throw getBuildException(be);
+ } finally {
+ restoreContextLoader(origLoader);
+ }
+ }
+
+ /**
+ * Get/create a BuildException from a BSFException.
+ * @param be BSFException to convert.
+ * @return BuildException the converted exception.
+ */
+ private BuildException getBuildException(BSFException be) {
+ Throwable t = be;
+ Throwable te = be.getTargetException();
+ if (te instanceof BuildException) {
+ return (BuildException) te;
+ }
+ return new BuildException(te == null ? t : te);
+ }
+
+ private void declareBeans(BSFManager m) throws BSFException {
+ for (Iterator i = getBeans().keySet().iterator(); i.hasNext();) {
+ String key = (String) i.next();
+ Object value = getBeans().get(key);
+ if (value != null) {
+ m.declareBean(key, value, value.getClass());
+ } else {
+ // BSF uses a hashtable to store values
+ // so cannot declareBean with a null value
+ // So need to remove any bean of this name as
+ // that bean should not be visible
+ m.undeclareBean(key);
+ }
+ }
+ }
+
+ private BSFManager createManager() throws BSFException {
+ if (manager != null) {
+ return manager;
+ }
+ BSFManager m = new BSFManager();
+ m.setClassLoader(getScriptClassLoader());
+ if (getKeepEngine()) {
+ BSFEngine e = manager.loadScriptingEngine(getLanguage());
+ this.manager = m;
+ this.engine = e;
+ }
+ return m;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/optional/WeakishReference12.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/optional/WeakishReference12.java
new file mode 100644
index 00000000..4cd12788
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/optional/WeakishReference12.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.util.optional;
+
+import org.apache.tools.ant.util.WeakishReference;
+
+/**
+ * This is a reference that really is is Weak, as it uses the
+ * appropriate java.lang.ref class.
+ * @deprecated since 1.7.
+ * Just use {@link java.lang.ref.WeakReference} directly.
+ * Note that in ant1.7 is parent was changed to extend HardReference.
+ * This is because the latter has access to the (package scoped)
+ * WeakishReference(Object) constructor, and both that and this are thin
+ * facades on the underlying no-longer-abstract base class.
+ */
+public class WeakishReference12 extends WeakishReference.HardReference {
+
+
+ /**
+ * create a new soft reference, which is bound to a
+ * Weak reference inside
+ * @param reference the object to reference.
+ * @see java.lang.ref.WeakReference
+ */
+ public WeakishReference12(Object reference) {
+ super(reference);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/regexp/JakartaOroMatcher.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/regexp/JakartaOroMatcher.java
new file mode 100644
index 00000000..5c43376c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/regexp/JakartaOroMatcher.java
@@ -0,0 +1,170 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.util.regexp;
+
+import java.util.Vector;
+
+import org.apache.oro.text.regex.MatchResult;
+import org.apache.oro.text.regex.Pattern;
+import org.apache.oro.text.regex.Perl5Compiler;
+import org.apache.oro.text.regex.Perl5Matcher;
+import org.apache.tools.ant.BuildException;
+
+
+/**
+ * Implementation of RegexpMatcher for Jakarta-ORO.
+ *
+ */
+public class JakartaOroMatcher implements RegexpMatcher {
+
+ private String pattern;
+ // CheckStyle:VisibilityModifier OFF - bc
+ protected final Perl5Compiler compiler = new Perl5Compiler();
+ protected final Perl5Matcher matcher = new Perl5Matcher();
+ // CheckStyle:VisibilityModifier ON
+
+ /**
+ * Constructor for JakartaOroMatcher.
+ */
+ public JakartaOroMatcher() {
+ }
+
+ /**
+ * Set the regexp pattern from the String description.
+ * @param pattern the pattern to match
+ */
+ public void setPattern(final String pattern) {
+ this.pattern = pattern;
+ }
+
+ /**
+ * Get a String representation of the regexp pattern
+ * @return the pattern
+ */
+ public String getPattern() {
+ return this.pattern;
+ }
+
+ /**
+ * Get a compiled representation of the regexp pattern
+ * @param options the options
+ * @return the compiled pattern
+ * @throws BuildException on error
+ */
+ protected Pattern getCompiledPattern(final int options)
+ throws BuildException {
+ try {
+ // compute the compiler options based on the input options first
+ final Pattern p = compiler.compile(pattern, getCompilerOptions(options));
+ return p;
+ } catch (final Exception e) {
+ throw new BuildException(e);
+ }
+ }
+
+ /**
+ * Does the given argument match the pattern using default options?
+ * @param argument the string to match against
+ * @return true if the pattern matches
+ * @throws BuildException on error
+ */
+ public boolean matches(final String argument) throws BuildException {
+ return matches(argument, MATCH_DEFAULT);
+ }
+
+ /**
+ * Does the given argument match the pattern?
+ * @param input the string to match against
+ * @param options the regex options to use
+ * @return true if the pattern matches
+ * @throws BuildException on error
+ */
+ public boolean matches(final String input, final int options)
+ throws BuildException {
+ final Pattern p = getCompiledPattern(options);
+ return matcher.contains(input, p);
+ }
+
+ /**
+ * Returns a Vector of matched groups found in the argument
+ * using default options.
+ *
+ * <p>Group 0 will be the full match, the rest are the
+ * parenthesized subexpressions</p>.
+ *
+ * @param argument the string to match against
+ * @return the vector of groups
+ * @throws BuildException on error
+ */
+ public Vector getGroups(final String argument) throws BuildException {
+ return getGroups(argument, MATCH_DEFAULT);
+ }
+
+ /**
+ * Returns a Vector of matched groups found in the argument.
+ *
+ * <p>Group 0 will be the full match, the rest are the
+ * parenthesized subexpressions</p>.
+ *
+ * @param input the string to match against
+ * @param options the regex options to use
+ * @return the vector of groups
+ * @throws BuildException on error
+ */
+ public Vector getGroups(final String input, final int options)
+ throws BuildException {
+ if (!matches(input, options)) {
+ return null;
+ }
+ final Vector v = new Vector();
+ final MatchResult mr = matcher.getMatch();
+ final int cnt = mr.groups();
+ for (int i = 0; i < cnt; i++) {
+ String match = mr.group(i);
+ // treat non-matching groups as empty matches
+ if (match == null) {
+ match = "";
+ }
+ v.addElement(match);
+ }
+ return v;
+ }
+
+ /**
+ * Convert the generic options to the regex compiler specific options.
+ * @param options the generic options
+ * @return the specific options
+ */
+ protected int getCompilerOptions(final int options) {
+ int cOptions = Perl5Compiler.DEFAULT_MASK;
+
+ if (RegexpUtil.hasFlag(options, MATCH_CASE_INSENSITIVE)) {
+ cOptions |= Perl5Compiler.CASE_INSENSITIVE_MASK;
+ }
+ if (RegexpUtil.hasFlag(options, MATCH_MULTILINE)) {
+ cOptions |= Perl5Compiler.MULTILINE_MASK;
+ }
+ if (RegexpUtil.hasFlag(options, MATCH_SINGLELINE)) {
+ cOptions |= Perl5Compiler.SINGLELINE_MASK;
+ }
+
+ return cOptions;
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/regexp/JakartaOroRegexp.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/regexp/JakartaOroRegexp.java
new file mode 100644
index 00000000..529a78ae
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/regexp/JakartaOroRegexp.java
@@ -0,0 +1,98 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.util.regexp;
+
+import org.apache.oro.text.regex.Perl5Substitution;
+import org.apache.oro.text.regex.Substitution;
+import org.apache.oro.text.regex.Util;
+import org.apache.tools.ant.BuildException;
+
+/***
+ * Regular expression implementation using the Jakarta Oro package
+ */
+public class JakartaOroRegexp extends JakartaOroMatcher implements Regexp {
+
+ private static final int DECIMAL = 10;
+
+ /** Constructor for JakartaOroRegexp */
+ public JakartaOroRegexp() {
+ super();
+ }
+
+ /**
+ * Perform a substitution on the regular expression.
+ * @param input The string to substitute on
+ * @param argument The string which defines the substitution
+ * @param options The list of options for the match and replace.
+ * @return the result of the operation
+ * @throws BuildException on error
+ */
+ public String substitute(final String input, final String argument, final int options)
+ throws BuildException {
+ // translate \1 to $1 so that the Perl5Substitution will work
+ final StringBuffer subst = new StringBuffer();
+ for (int i = 0; i < argument.length(); i++) {
+ char c = argument.charAt(i);
+ if (c == '$') {
+ subst.append('\\');
+ subst.append('$');
+ } else if (c == '\\') {
+ if (++i < argument.length()) {
+ c = argument.charAt(i);
+ final int value = Character.digit(c, DECIMAL);
+ if (value > -1) {
+ subst.append("$").append(value);
+ } else {
+ subst.append(c);
+ }
+ } else {
+ // TODO - should throw an exception instead?
+ subst.append('\\');
+ }
+ } else {
+ subst.append(c);
+ }
+ }
+
+ // Do the substitution
+ final Substitution s =
+ new Perl5Substitution(subst.toString(),
+ Perl5Substitution.INTERPOLATE_ALL);
+ return Util.substitute(matcher,
+ getCompiledPattern(options),
+ s,
+ input,
+ getSubsOptions(options));
+ }
+
+ /**
+ * Convert ant regexp substitution option to oro options.
+ *
+ * @param options the ant regexp options
+ * @return the oro substition options
+ */
+ protected int getSubsOptions(final int options) {
+ final boolean replaceAll = RegexpUtil.hasFlag(options, REPLACE_ALL);
+ int subsOptions = 1;
+ if (replaceAll) {
+ subsOptions = Util.SUBSTITUTE_ALL;
+ }
+ return subsOptions;
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/regexp/JakartaRegexpMatcher.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/regexp/JakartaRegexpMatcher.java
new file mode 100644
index 00000000..3e14415d
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/regexp/JakartaRegexpMatcher.java
@@ -0,0 +1,161 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.util.regexp;
+
+import java.util.Vector;
+import org.apache.regexp.RE;
+import org.apache.regexp.RESyntaxException;
+import org.apache.tools.ant.BuildException;
+
+/**
+ * Implementation of RegexpMatcher for Jakarta-Regexp.
+ *
+ */
+public class JakartaRegexpMatcher implements RegexpMatcher {
+
+ private String pattern;
+
+ /**
+ * Set the regexp pattern from the String description.
+ * @param pattern the pattern to match
+ */
+ public void setPattern(String pattern) {
+ this.pattern = pattern;
+ }
+
+ /**
+ * Get a String representation of the regexp pattern
+ * @return the pattern
+ */
+ public String getPattern() {
+ return pattern;
+ }
+
+ /**
+ * Compile the pattern.
+ *
+ * @param options the ant regexp options
+ * @return a compiled pattern
+ * @exception BuildException if an error occurs
+ */
+ protected RE getCompiledPattern(int options)
+ throws BuildException {
+ int cOptions = getCompilerOptions(options);
+ try {
+ RE reg = new RE(pattern);
+ reg.setMatchFlags(cOptions);
+ return reg;
+ } catch (RESyntaxException e) {
+ throw new BuildException(e);
+ }
+ }
+
+ /**
+ * Does the given argument match the pattern?
+ * @param argument the string to match against
+ * @return true if the pattern matches
+ * @throws BuildException on error
+ */
+ public boolean matches(String argument) throws BuildException {
+ return matches(argument, MATCH_DEFAULT);
+ }
+
+ /**
+ * Does the given argument match the pattern?
+ * @param input the string to match against
+ * @param options the regex options to use
+ * @return true if the pattern matches
+ * @throws BuildException on error
+ */
+ public boolean matches(String input, int options)
+ throws BuildException {
+ return matches(input, getCompiledPattern(options));
+ }
+
+ private boolean matches(String input, RE reg) {
+ return reg.match(input);
+ }
+
+ /**
+ * Returns a Vector of matched groups found in the argument
+ * using default options.
+ *
+ * <p>Group 0 will be the full match, the rest are the
+ * parenthesized subexpressions</p>.
+ *
+ * @param argument the string to match against
+ * @return the vector of groups
+ * @throws BuildException on error
+ */
+ public Vector getGroups(String argument) throws BuildException {
+ return getGroups(argument, MATCH_DEFAULT);
+ }
+
+ /**
+ * Returns a Vector of matched groups found in the argument.
+ *
+ * <p>Group 0 will be the full match, the rest are the
+ * parenthesized subexpressions</p>.
+ *
+ * @param input the string to match against
+ * @param options the regex options to use
+ * @return the vector of groups
+ * @throws BuildException on error
+ */
+ public Vector getGroups(String input, int options)
+ throws BuildException {
+ RE reg = getCompiledPattern(options);
+ if (!matches(input, reg)) {
+ return null;
+ }
+ Vector v = new Vector();
+ int cnt = reg.getParenCount();
+ for (int i = 0; i < cnt; i++) {
+ String match = reg.getParen(i);
+ // treat non-matching groups as empty matches
+ if (match == null) {
+ match = "";
+ }
+ v.addElement(match);
+ }
+ return v;
+ }
+
+ /**
+ * Convert the generic options to the regex compiler specific options.
+ * @param options the generic options
+ * @return the specific options
+ */
+ protected int getCompilerOptions(int options) {
+ int cOptions = RE.MATCH_NORMAL;
+
+ if (RegexpUtil.hasFlag(options, MATCH_CASE_INSENSITIVE)) {
+ cOptions |= RE.MATCH_CASEINDEPENDENT;
+ }
+ if (RegexpUtil.hasFlag(options, MATCH_MULTILINE)) {
+ cOptions |= RE.MATCH_MULTILINE;
+ }
+ if (RegexpUtil.hasFlag(options, MATCH_SINGLELINE)) {
+ cOptions |= RE.MATCH_SINGLELINE;
+ }
+
+ return cOptions;
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/regexp/JakartaRegexpRegexp.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/regexp/JakartaRegexpRegexp.java
new file mode 100644
index 00000000..865f424a
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/regexp/JakartaRegexpRegexp.java
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.util.regexp;
+
+import java.util.Vector;
+import org.apache.regexp.RE;
+import org.apache.tools.ant.BuildException;
+
+/***
+ * Regular expression implementation using the Jakarta Regexp package
+ */
+public class JakartaRegexpRegexp extends JakartaRegexpMatcher
+ implements Regexp {
+
+ private static final int DECIMAL = 10;
+
+ /** Constructor for JakartaRegexpRegexp */
+ public JakartaRegexpRegexp() {
+ super();
+ }
+
+ /**
+ * Convert ant regexp substitution option to apache regex options.
+ *
+ * @param options the ant regexp options
+ * @return the apache regex substition options
+ */
+ protected int getSubsOptions(int options) {
+ int subsOptions = RE.REPLACE_FIRSTONLY;
+ if (RegexpUtil.hasFlag(options, REPLACE_ALL)) {
+ subsOptions = RE.REPLACE_ALL;
+ }
+ return subsOptions;
+ }
+
+ /**
+ * Perform a substitution on the regular expression.
+ * @param input The string to substitute on
+ * @param argument The string which defines the substitution
+ * @param options The list of options for the match and replace.
+ * @return the result of the operation
+ * @throws BuildException on error
+ */
+ public String substitute(String input, String argument, int options)
+ throws BuildException {
+ Vector v = getGroups(input, options);
+
+ // replace \1 with the corresponding group
+ StringBuffer result = new StringBuffer();
+ for (int i = 0; i < argument.length(); i++) {
+ char c = argument.charAt(i);
+ if (c == '\\') {
+ if (++i < argument.length()) {
+ c = argument.charAt(i);
+ int value = Character.digit(c, DECIMAL);
+ if (value > -1) {
+ result.append((String) v.elementAt(value));
+ } else {
+ result.append(c);
+ }
+ } else {
+ // TODO - should throw an exception instead?
+ result.append('\\');
+ }
+ } else {
+ result.append(c);
+ }
+ }
+ argument = result.toString();
+
+ RE reg = getCompiledPattern(options);
+ int sOptions = getSubsOptions(options);
+ return reg.subst(input, argument, sOptions);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/regexp/Jdk14RegexpMatcher.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/regexp/Jdk14RegexpMatcher.java
new file mode 100644
index 00000000..8c241d4e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/regexp/Jdk14RegexpMatcher.java
@@ -0,0 +1,170 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.util.regexp;
+
+import java.util.Vector;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.regex.PatternSyntaxException;
+
+import org.apache.tools.ant.BuildException;
+
+/**
+ * Implementation of RegexpMatcher for the built-in regexp matcher of
+ * JDK 1.4. UNIX_LINES option is enabled as a default.
+ *
+ */
+public class Jdk14RegexpMatcher implements RegexpMatcher {
+
+ private String pattern;
+
+ /** Constructor for JakartaOroRegexp */
+ public Jdk14RegexpMatcher() {
+ }
+
+ /**
+ * Set the regexp pattern from the String description.
+ * @param pattern the pattern to match
+ */
+ public void setPattern(String pattern) {
+ this.pattern = pattern;
+ }
+
+ /**
+ * Get a String representation of the regexp pattern
+ * @return the pattern
+ * @throws BuildException on error
+ */
+ public String getPattern() {
+ return pattern;
+ }
+
+ /**
+ * Get a compiled representation of the regexp pattern
+ * @param options the options
+ * @return the compiled pattern
+ * @throws BuildException on error
+ */
+ protected Pattern getCompiledPattern(int options)
+ throws BuildException {
+ int cOptions = getCompilerOptions(options);
+ try {
+ Pattern p = Pattern.compile(this.pattern, cOptions);
+ return p;
+ } catch (PatternSyntaxException e) {
+ throw new BuildException(e);
+ }
+ }
+
+ /**
+ * Does the given argument match the pattern using default options?
+ * @param argument the string to match against
+ * @return true if the pattern matches
+ * @throws BuildException on error
+ */
+ public boolean matches(String argument) throws BuildException {
+ return matches(argument, MATCH_DEFAULT);
+ }
+
+ /**
+ * Does the given argument match the pattern?
+ * @param input the string to match against
+ * @param options the regex options to use
+ * @return true if the pattern matches
+ * @throws BuildException on error
+ */
+ public boolean matches(String input, int options)
+ throws BuildException {
+ try {
+ Pattern p = getCompiledPattern(options);
+ return p.matcher(input).find();
+ } catch (Exception e) {
+ throw new BuildException(e);
+ }
+ }
+
+ /**
+ * Returns a Vector of matched groups found in the argument
+ * using default options.
+ *
+ * <p>Group 0 will be the full match, the rest are the
+ * parenthesized subexpressions</p>.
+ *
+ * @param argument the string to match against
+ * @return the vector of groups
+ * @throws BuildException on error
+ */
+ public Vector getGroups(String argument) throws BuildException {
+ return getGroups(argument, MATCH_DEFAULT);
+ }
+
+ /**
+ * Returns a Vector of matched groups found in the argument.
+ *
+ * <p>Group 0 will be the full match, the rest are the
+ * parenthesized subexpressions</p>.
+ *
+ * @param input the string to match against
+ * @param options the regex options to use
+ * @return the vector of groups
+ * @throws BuildException on error
+ */
+ public Vector getGroups(String input, int options)
+ throws BuildException {
+ Pattern p = getCompiledPattern(options);
+ Matcher matcher = p.matcher(input);
+ if (!matcher.find()) {
+ return null;
+ }
+ Vector v = new Vector();
+ int cnt = matcher.groupCount();
+ for (int i = 0; i <= cnt; i++) {
+ String match = matcher.group(i);
+ // treat non-matching groups as empty matches
+ if (match == null) {
+ match = "";
+ }
+ v.addElement(match);
+ }
+ return v;
+ }
+
+ /**
+ * Convert the generic options to the regex compiler specific options.
+ * @param options the generic options
+ * @return the specific options
+ */
+ protected int getCompilerOptions(int options) {
+ // be strict about line separator
+ int cOptions = Pattern.UNIX_LINES;
+
+ if (RegexpUtil.hasFlag(options, MATCH_CASE_INSENSITIVE)) {
+ cOptions |= Pattern.CASE_INSENSITIVE;
+ }
+ if (RegexpUtil.hasFlag(options, MATCH_MULTILINE)) {
+ cOptions |= Pattern.MULTILINE;
+ }
+ if (RegexpUtil.hasFlag(options, MATCH_SINGLELINE)) {
+ cOptions |= Pattern.DOTALL;
+ }
+
+ return cOptions;
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/regexp/Jdk14RegexpRegexp.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/regexp/Jdk14RegexpRegexp.java
new file mode 100644
index 00000000..3ca80706
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/regexp/Jdk14RegexpRegexp.java
@@ -0,0 +1,105 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.util.regexp;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.tools.ant.BuildException;
+
+/***
+ * Regular expression implementation using the JDK 1.4 regular expression package
+ */
+public class Jdk14RegexpRegexp extends Jdk14RegexpMatcher implements Regexp {
+
+ private static final int DECIMAL = 10;
+
+ /** Constructor for Jdk14RegexpRegexp */
+ public Jdk14RegexpRegexp() {
+ super();
+ }
+
+ /**
+ * Convert ant regexp substitution option to jdk1.4 options.
+ *
+ * @param options the ant regexp options
+ * @return the jdk14 substition options
+ */
+ protected int getSubsOptions(int options) {
+ int subsOptions = REPLACE_FIRST;
+ if (RegexpUtil.hasFlag(options, REPLACE_ALL)) {
+ subsOptions = REPLACE_ALL;
+ }
+ return subsOptions;
+ }
+
+ /**
+ * Perform a substitution on the regular expression.
+ * @param input The string to substitute on
+ * @param argument The string which defines the substitution
+ * @param options The list of options for the match and replace.
+ * @return the result of the operation
+ * @throws BuildException on error
+ */
+ public String substitute(String input, String argument, int options)
+ throws BuildException {
+ // translate \1 to $(1) so that the Matcher will work
+ StringBuffer subst = new StringBuffer();
+ for (int i = 0; i < argument.length(); i++) {
+ char c = argument.charAt(i);
+ if (c == '$') {
+ subst.append('\\');
+ subst.append('$');
+ } else if (c == '\\') {
+ if (++i < argument.length()) {
+ c = argument.charAt(i);
+ int value = Character.digit(c, DECIMAL);
+ if (value > -1) {
+ subst.append("$").append(value);
+ } else {
+ subst.append(c);
+ }
+ } else {
+ // TODO - should throw an exception instead?
+ subst.append('\\');
+ }
+ } else {
+ subst.append(c);
+ }
+ }
+ argument = subst.toString();
+
+ int sOptions = getSubsOptions(options);
+ Pattern p = getCompiledPattern(options);
+ StringBuffer sb = new StringBuffer();
+
+ Matcher m = p.matcher(input);
+ if (RegexpUtil.hasFlag(sOptions, REPLACE_ALL)) {
+ sb.append(m.replaceAll(argument));
+ } else {
+ boolean res = m.find();
+ if (res) {
+ m.appendReplacement(sb, argument);
+ m.appendTail(sb);
+ } else {
+ sb.append(input);
+ }
+ }
+ return sb.toString();
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/regexp/Regexp.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/regexp/Regexp.java
new file mode 100644
index 00000000..1c7816a1
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/regexp/Regexp.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.util.regexp;
+
+import org.apache.tools.ant.BuildException;
+
+/***
+ * Interface which represents a regular expression, and the operations
+ * that can be performed on it.
+ *
+ */
+public interface Regexp extends RegexpMatcher {
+
+ /**
+ * Replace only the first occurrence of the regular expression
+ */
+ int REPLACE_FIRST = 0x00000001;
+
+ /**
+ * Replace all occurrences of the regular expression
+ */
+ int REPLACE_ALL = 0x00000010;
+
+ /**
+ * Perform a substitution on the regular expression.
+ * @param input The string to substitute on
+ * @param argument The string which defines the substitution
+ * @param options The list of options for the match and replace. See the
+ * MATCH_ and REPLACE_ constants above.
+ * @return the result of the operation
+ * @throws BuildException on error
+ */
+ String substitute(String input, String argument, int options)
+ throws BuildException;
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/regexp/RegexpFactory.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/regexp/RegexpFactory.java
new file mode 100644
index 00000000..7077a216
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/regexp/RegexpFactory.java
@@ -0,0 +1,85 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.util.regexp;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.MagicNames;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.util.ClasspathUtils;
+
+/***
+ * Regular expression factory, which will create Regexp objects. The
+ * actual implementation class depends on the System or Ant Property:
+ * <code>ant.regexp.regexpimpl</code>.
+ *
+ */
+public class RegexpFactory extends RegexpMatcherFactory {
+
+ /** Constructor for RegexpFactory */
+ public RegexpFactory() {
+ }
+
+ /***
+ * Create a new regular expression matcher instance.
+ * @return the matcher instance
+ * @throws BuildException on error
+ */
+ public Regexp newRegexp() throws BuildException {
+ return newRegexp(null);
+ }
+
+ /***
+ * Create a new regular expression matcher instance.
+ *
+ * @param p Project whose ant.regexp.regexpimpl property will be used.
+ * @return the matcher instance
+ * @throws BuildException on error
+ */
+ public Regexp newRegexp(Project p) throws BuildException {
+ String systemDefault = null;
+ if (p == null) {
+ systemDefault = System.getProperty(MagicNames.REGEXP_IMPL);
+ } else {
+ systemDefault = p.getProperty(MagicNames.REGEXP_IMPL);
+ }
+
+ if (systemDefault != null) {
+ return createRegexpInstance(systemDefault);
+ // TODO should we silently catch possible exceptions and try to
+ // load a different implementation?
+ }
+
+ return new Jdk14RegexpRegexp();
+ }
+
+ /**
+ * Wrapper over RegexpMatcherFactory.createInstance that ensures that
+ * we are dealing with a Regexp implementation.
+ * @param classname the name of the class to use.
+ * @return the instance.
+ * @throws BuildException if there is a problem.
+ * @since 1.3
+ *
+ * @see RegexpMatcherFactory#createInstance(String)
+ */
+ protected Regexp createRegexpInstance(String classname) throws BuildException {
+ return (Regexp) ClasspathUtils.newInstance(classname, RegexpFactory.class.getClassLoader(),
+ Regexp.class);
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/regexp/RegexpMatcher.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/regexp/RegexpMatcher.java
new file mode 100644
index 00000000..7938d8be
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/regexp/RegexpMatcher.java
@@ -0,0 +1,110 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.util.regexp;
+
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildException;
+
+/**
+ * Interface describing a regular expression matcher.
+ *
+ */
+public interface RegexpMatcher {
+
+ /***
+ * Default Mask (case insensitive, neither multiline nor
+ * singleline specified).
+ */
+ int MATCH_DEFAULT = 0x00000000;
+
+ /***
+ * Perform a case insensitive match
+ */
+ int MATCH_CASE_INSENSITIVE = 0x00000100;
+
+ /***
+ * Treat the input as a multiline input
+ */
+ int MATCH_MULTILINE = 0x00001000;
+
+ /***
+ * Treat the input as singleline input ('.' matches newline)
+ */
+ int MATCH_SINGLELINE = 0x00010000;
+
+
+ /**
+ * Set the regexp pattern from the String description.
+ * @param pattern the pattern to match
+ * @throws BuildException on error
+ */
+ void setPattern(String pattern) throws BuildException;
+
+ /**
+ * Get a String representation of the regexp pattern
+ * @return the pattern
+ * @throws BuildException on error
+ */
+ String getPattern() throws BuildException;
+
+ /**
+ * Does the given argument match the pattern?
+ * @param argument the string to match against
+ * @return true if the pattern matches
+ * @throws BuildException on error
+ */
+ boolean matches(String argument) throws BuildException;
+
+ /**
+ * Returns a Vector of matched groups found in the argument
+ * using default options.
+ *
+ * <p>Group 0 will be the full match, the rest are the
+ * parenthesized subexpressions</p>.
+ *
+ * @param argument the string to match against
+ * @return the vector of groups
+ * @throws BuildException on error
+ */
+ Vector getGroups(String argument) throws BuildException;
+
+ /***
+ * Does this regular expression match the input, given
+ * certain options
+ * @param input The string to check for a match
+ * @param options The list of options for the match. See the
+ * MATCH_ constants above.
+ * @return true if the pattern matches
+ * @throws BuildException on error
+ */
+ boolean matches(String input, int options) throws BuildException;
+
+ /***
+ * Get the match groups from this regular expression. The return
+ * type of the elements is always String.
+ * @param input The string to check for a match
+ * @param options The list of options for the match. See the
+ * MATCH_ constants above.
+ * @return the vector of groups
+ * @throws BuildException on error
+ */
+ Vector getGroups(String input, int options) throws BuildException;
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/regexp/RegexpMatcherFactory.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/regexp/RegexpMatcherFactory.java
new file mode 100644
index 00000000..a0a8a155
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/regexp/RegexpMatcherFactory.java
@@ -0,0 +1,114 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.util.regexp;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.MagicNames;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.util.ClasspathUtils;
+
+/**
+ * Simple Factory Class that produces an implementation of RegexpMatcher based on the system
+ * property <code>ant.regexp.regexpimpl</code> and the classes available.
+ *
+ * <p>
+ * In a more general framework this class would be abstract and have a static newInstance method.
+ * </p>
+ *
+ */
+public class RegexpMatcherFactory {
+
+ /** Constructor for RegexpMatcherFactory. */
+ public RegexpMatcherFactory() {
+ }
+
+ /***
+ * Create a new regular expression instance.
+ * @return the matcher
+ * @throws BuildException on error
+ */
+ public RegexpMatcher newRegexpMatcher() throws BuildException {
+ return newRegexpMatcher(null);
+ }
+
+ /***
+ * Create a new regular expression instance.
+ *
+ * @param p Project whose ant.regexp.regexpimpl property will be used.
+ * @return the matcher
+ * @throws BuildException on error
+ */
+ public RegexpMatcher newRegexpMatcher(Project p) throws BuildException {
+ String systemDefault = null;
+ if (p == null) {
+ systemDefault = System.getProperty(MagicNames.REGEXP_IMPL);
+ } else {
+ systemDefault = p.getProperty(MagicNames.REGEXP_IMPL);
+ }
+
+ if (systemDefault != null) {
+ return createInstance(systemDefault);
+ // TODO should we silently catch possible exceptions and try to
+ // load a different implementation?
+ }
+
+ return new Jdk14RegexpMatcher();
+ }
+
+ /**
+ * Create an instance of a matcher from a classname.
+ *
+ * @param className a <code>String</code> value
+ * @return a <code>RegexpMatcher</code> value
+ * @exception BuildException if an error occurs
+ */
+ protected RegexpMatcher createInstance(String className) throws BuildException {
+ return (RegexpMatcher) ClasspathUtils.newInstance(className, RegexpMatcherFactory.class
+ .getClassLoader(), RegexpMatcher.class);
+ }
+
+ /**
+ * Test if a particular class is available to be used.
+ *
+ * @param className a <code>String</code> value
+ * @exception BuildException if an error occurs
+ */
+ protected void testAvailability(String className) throws BuildException {
+ try {
+ Class.forName(className);
+ } catch (Throwable t) {
+ throw new BuildException(t);
+ }
+ }
+
+ /**
+ * Checks if a RegExp-Matcher is available.
+ * @param project The project to check for (may be <code>null</code>)
+ * @return <code>true</code> if available otherwise <code>false</code>
+ */
+ public static boolean regexpMatcherPresent(Project project) {
+ try {
+ // The factory throws a BuildException if no usable matcher
+ // cannot be instantiated. We dont need the matcher itself here.
+ new RegexpMatcherFactory().newRegexpMatcher(project);
+ return true;
+ } catch (Throwable ex) {
+ return false;
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/regexp/RegexpUtil.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/regexp/RegexpUtil.java
new file mode 100644
index 00000000..ebd85fab
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/util/regexp/RegexpUtil.java
@@ -0,0 +1,109 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.util.regexp;
+
+// CheckStyle:HideUtilityClassConstructorCheck OFF - bc
+
+/***
+ * Regular expression utilities class which handles flag operations.
+ *
+ */
+public class RegexpUtil {
+
+ /**
+ * Check the options has a particular flag set.
+ *
+ * @param options an <code>int</code> value
+ * @param flag an <code>int</code> value
+ * @return true if the flag is set
+ */
+ public static boolean hasFlag(int options, int flag) {
+ return ((options & flag) > 0);
+ }
+
+ /**
+ * Remove a particular flag from an int value contains the option flags.
+ *
+ * @param options an <code>int</code> value
+ * @param flag an <code>int</code> value
+ * @return the options with the flag unset
+ */
+ public static int removeFlag(int options, int flag) {
+ return (options & (0xFFFFFFFF - flag));
+ }
+
+ /**
+ * convert regex option flag characters to regex options
+ * <dl>
+ * <li>g - Regexp.REPLACE_ALL</li>
+ * <li>i - RegexpMatcher.MATCH_CASE_INSENSITIVE</li>
+ * <li>m - RegexpMatcher.MATCH_MULTILINE</li>
+ * <li>s - RegexpMatcher.MATCH_SINGLELINE</li>
+ * </dl>
+ * @param flags the string containing the flags
+ * @return the Regexp option bits
+ * @since Ant 1.8.2
+ */
+ public static int asOptions(String flags) {
+ int options = RegexpMatcher.MATCH_DEFAULT;
+ if (flags != null) {
+ options = asOptions(flags.indexOf('i') == -1,
+ flags.indexOf('m') != -1,
+ flags.indexOf('s') != -1);
+ if (flags.indexOf('g') != -1) {
+ options |= Regexp.REPLACE_ALL;
+ }
+ }
+ return options;
+ }
+
+ /**
+ * Convert flag to regex options.
+ *
+ * @param caseSensitive opposite of RegexpMatcher.MATCH_CASE_INSENSITIVE
+ * @return the Regexp option bits
+ * @since Ant 1.8.2
+ */
+ public static int asOptions(boolean caseSensitive) {
+ return asOptions(caseSensitive, false, false);
+ }
+
+ /**
+ * Convert flags to regex options.
+ *
+ * @param caseSensitive opposite of RegexpMatcher.MATCH_CASE_INSENSITIVE
+ * @param multiLine RegexpMatcher.MATCH_MULTILINE
+ * @param singleLine RegexpMatcher.MATCH_SINGLELINE
+ * @return the Regexp option bits
+ * @since Ant 1.8.2
+ */
+ public static int asOptions(boolean caseSensitive, boolean multiLine,
+ boolean singleLine) {
+ int options = RegexpMatcher.MATCH_DEFAULT;
+ if (!caseSensitive) {
+ options = options | RegexpMatcher.MATCH_CASE_INSENSITIVE;
+ }
+ if (multiLine) {
+ options = options | RegexpMatcher.MATCH_MULTILINE;
+ }
+ if (singleLine) {
+ options = options | RegexpMatcher.MATCH_SINGLELINE;
+ }
+ return options;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/version.txt b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/version.txt
new file mode 100644
index 00000000..0496e181
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/version.txt
@@ -0,0 +1,2 @@
+VERSION=${project.version}
+DATE=${TODAY}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/bzip2/BZip2Constants.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/bzip2/BZip2Constants.java
new file mode 100644
index 00000000..3a511a7a
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/bzip2/BZip2Constants.java
@@ -0,0 +1,109 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+/*
+ * This package is based on the work done by Keiron Liddle, Aftex Software
+ * <keiron@aftexsw.com> to whom the Ant project is very grateful for his
+ * great code.
+ */
+
+package org.apache.tools.bzip2;
+
+/**
+ * Base class for both the compress and decompress classes.
+ * Holds common arrays, and static data.
+ * <p>
+ * This interface is public for historical purposes.
+ * You should have no need to use it.
+ * </p>
+ */
+public interface BZip2Constants {
+
+ int baseBlockSize = 100000;
+ int MAX_ALPHA_SIZE = 258;
+ int MAX_CODE_LEN = 23;
+ int RUNA = 0;
+ int RUNB = 1;
+ int N_GROUPS = 6;
+ int G_SIZE = 50;
+ int N_ITERS = 4;
+ int MAX_SELECTORS = (2 + (900000 / G_SIZE));
+ int NUM_OVERSHOOT_BYTES = 20;
+
+ /**
+ * This array really shouldn't be here.
+ * Again, for historical purposes it is.
+ *
+ * <p>FIXME: This array should be in a private or package private
+ * location, since it could be modified by malicious code.</p>
+ */
+ int[] rNums = {
+ 619, 720, 127, 481, 931, 816, 813, 233, 566, 247,
+ 985, 724, 205, 454, 863, 491, 741, 242, 949, 214,
+ 733, 859, 335, 708, 621, 574, 73, 654, 730, 472,
+ 419, 436, 278, 496, 867, 210, 399, 680, 480, 51,
+ 878, 465, 811, 169, 869, 675, 611, 697, 867, 561,
+ 862, 687, 507, 283, 482, 129, 807, 591, 733, 623,
+ 150, 238, 59, 379, 684, 877, 625, 169, 643, 105,
+ 170, 607, 520, 932, 727, 476, 693, 425, 174, 647,
+ 73, 122, 335, 530, 442, 853, 695, 249, 445, 515,
+ 909, 545, 703, 919, 874, 474, 882, 500, 594, 612,
+ 641, 801, 220, 162, 819, 984, 589, 513, 495, 799,
+ 161, 604, 958, 533, 221, 400, 386, 867, 600, 782,
+ 382, 596, 414, 171, 516, 375, 682, 485, 911, 276,
+ 98, 553, 163, 354, 666, 933, 424, 341, 533, 870,
+ 227, 730, 475, 186, 263, 647, 537, 686, 600, 224,
+ 469, 68, 770, 919, 190, 373, 294, 822, 808, 206,
+ 184, 943, 795, 384, 383, 461, 404, 758, 839, 887,
+ 715, 67, 618, 276, 204, 918, 873, 777, 604, 560,
+ 951, 160, 578, 722, 79, 804, 96, 409, 713, 940,
+ 652, 934, 970, 447, 318, 353, 859, 672, 112, 785,
+ 645, 863, 803, 350, 139, 93, 354, 99, 820, 908,
+ 609, 772, 154, 274, 580, 184, 79, 626, 630, 742,
+ 653, 282, 762, 623, 680, 81, 927, 626, 789, 125,
+ 411, 521, 938, 300, 821, 78, 343, 175, 128, 250,
+ 170, 774, 972, 275, 999, 639, 495, 78, 352, 126,
+ 857, 956, 358, 619, 580, 124, 737, 594, 701, 612,
+ 669, 112, 134, 694, 363, 992, 809, 743, 168, 974,
+ 944, 375, 748, 52, 600, 747, 642, 182, 862, 81,
+ 344, 805, 988, 739, 511, 655, 814, 334, 249, 515,
+ 897, 955, 664, 981, 649, 113, 974, 459, 893, 228,
+ 433, 837, 553, 268, 926, 240, 102, 654, 459, 51,
+ 686, 754, 806, 760, 493, 403, 415, 394, 687, 700,
+ 946, 670, 656, 610, 738, 392, 760, 799, 887, 653,
+ 978, 321, 576, 617, 626, 502, 894, 679, 243, 440,
+ 680, 879, 194, 572, 640, 724, 926, 56, 204, 700,
+ 707, 151, 457, 449, 797, 195, 791, 558, 945, 679,
+ 297, 59, 87, 824, 713, 663, 412, 693, 342, 606,
+ 134, 108, 571, 364, 631, 212, 174, 643, 304, 329,
+ 343, 97, 430, 751, 497, 314, 983, 374, 822, 928,
+ 140, 206, 73, 263, 980, 736, 876, 478, 430, 305,
+ 170, 514, 364, 692, 829, 82, 855, 953, 676, 246,
+ 369, 970, 294, 750, 807, 827, 150, 790, 288, 923,
+ 804, 378, 215, 828, 592, 281, 565, 555, 710, 82,
+ 896, 831, 547, 261, 524, 462, 293, 465, 502, 56,
+ 661, 821, 976, 991, 658, 869, 905, 758, 745, 193,
+ 768, 550, 608, 933, 378, 286, 215, 979, 792, 961,
+ 61, 688, 793, 644, 986, 403, 106, 366, 905, 644,
+ 372, 567, 466, 434, 645, 210, 389, 550, 919, 135,
+ 780, 773, 635, 389, 707, 100, 626, 958, 165, 504,
+ 920, 176, 193, 713, 857, 265, 203, 50, 668, 108,
+ 645, 990, 626, 197, 510, 357, 358, 850, 858, 364,
+ 936, 638
+ };
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/bzip2/BlockSort.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/bzip2/BlockSort.java
new file mode 100644
index 00000000..eb9066ee
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/bzip2/BlockSort.java
@@ -0,0 +1,1081 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tools.bzip2;
+
+import java.util.BitSet;
+
+/**
+ * Encapsulates the Burrows-Wheeler sorting algorithm needed by {@link
+ * CBZip2OutputStream}.
+ *
+ * <p>This class is based on a Java port of Julian Seward's
+ * blocksort.c in his libbzip2</p>
+ *
+ * <p>The Burrows-Wheeler transform is a reversible transform of the
+ * original data that is supposed to group similar bytes close to
+ * each other. The idea is to sort all permutations of the input and
+ * only keep the last byte of each permutation. E.g. for "Commons
+ * Compress" you'd get:</p>
+ *
+ * <pre>
+ * CompressCommons
+ * Commons Compress
+ * CompressCommons
+ * essCommons Compr
+ * mmons CompressCo
+ * mons CompressCom
+ * mpressCommons Co
+ * ns CompressCommo
+ * ommons CompressC
+ * ompressCommons C
+ * ons CompressComm
+ * pressCommons Com
+ * ressCommons Comp
+ * s CompressCommon
+ * sCommons Compres
+ * ssCommons Compre
+ * </pre>
+ *
+ * <p>Which results in a new text "ss romooCCmmpnse", in adition the
+ * index of the first line that contained the original text is kept -
+ * in this case it is 1. The idea is that in a long English text all
+ * permutations that start with "he" are likely suffixes of a "the" and
+ * thus they end in "t" leading to a larger block of "t"s that can
+ * better be compressed by the subsequent Move-to-Front, run-length
+ * und Huffman encoding steps.</p>
+ *
+ * <p>For more information see for example:</p>
+ * <ul>
+ * <li><a
+ * href="http://www.hpl.hp.com/techreports/Compaq-DEC/SRC-RR-124.pdf">Burrows,
+ * M. and Wheeler, D.: A Block-sorting Lossless Data Compression
+ * Algorithm</a></li>
+ * <li><a href="http://webglimpse.net/pubs/suffix.pdf">Manber, U. and
+ * Myers, G.: Suffix arrays: A new method for on-line string
+ * searches</a></li>
+ * <li><a
+ * href="http://www.cs.tufts.edu/~nr/comp150fp/archive/bob-sedgewick/fast-strings.pdf">Bentley,
+ * J.L. and Sedgewick, R.: Fast Algorithms for Sorting and Searching
+ * Strings</a></li>
+ * </ul>
+ *
+ * @NotThreadSafe
+ */
+class BlockSort {
+
+ /*
+ * Some of the constructs used in the C code cannot be ported
+ * literally to Java - for example macros, unsigned types. Some
+ * code has been hand-tuned to improve performance. In order to
+ * avoid memory pressure some structures are reused for several
+ * blocks and some memory is even shared between sorting and the
+ * MTF stage even though either algorithm uses it for its own
+ * purpose.
+ *
+ * Comments preserved from the actual C code are prefixed with
+ * "LBZ2:".
+ */
+
+ /*
+ * 2012-05-20 Stefan Bodewig:
+ *
+ * This class seems to mix several revisions of libbzip2's code.
+ * The mainSort function and those used by it look closer to the
+ * 0.9.5 version but show some variations introduced later. At
+ * the same time the logic of Compress 1.4 to randomize the block
+ * on bad input has been dropped after libbzip2 0.9.0 and replaced
+ * by a fallback sorting algorithm.
+ *
+ * I've added the fallbackSort function of 1.0.6 and tried to
+ * integrate it with the existing code without touching too much.
+ * I've also removed the now unused randomization code.
+ */
+
+ /*
+ * LBZ2: If you are ever unlucky/improbable enough to get a stack
+ * overflow whilst sorting, increase the following constant and
+ * try again. In practice I have never seen the stack go above 27
+ * elems, so the following limit seems very generous.
+ */
+ private static final int QSORT_STACK_SIZE = 1000;
+
+ private static final int FALLBACK_QSORT_STACK_SIZE = 100;
+
+ private static final int STACK_SIZE =
+ QSORT_STACK_SIZE < FALLBACK_QSORT_STACK_SIZE
+ ? FALLBACK_QSORT_STACK_SIZE : QSORT_STACK_SIZE;
+
+ /*
+ * Used when sorting. If too many long comparisons happen, we stop sorting,
+ * and use fallbackSort instead.
+ */
+ private int workDone;
+ private int workLimit;
+ private boolean firstAttempt;
+
+ private final int[] stack_ll = new int[STACK_SIZE]; // 4000 byte
+ private final int[] stack_hh = new int[STACK_SIZE]; // 4000 byte
+ private final int[] stack_dd = new int[QSORT_STACK_SIZE]; // 4000 byte
+
+ private final int[] mainSort_runningOrder = new int[256]; // 1024 byte
+ private final int[] mainSort_copy = new int[256]; // 1024 byte
+ private final boolean[] mainSort_bigDone = new boolean[256]; // 256 byte
+
+ private final int[] ftab = new int[65537]; // 262148 byte
+
+ /**
+ * Array instance identical to Data's sfmap, both are used only
+ * temporarily and indepently, so we do not need to allocate
+ * additional memory.
+ */
+ private final char[] quadrant;
+
+ BlockSort(final CBZip2OutputStream.Data data) {
+ this.quadrant = data.sfmap;
+ }
+
+ void blockSort(final CBZip2OutputStream.Data data, final int last) {
+ this.workLimit = WORK_FACTOR * last;
+ this.workDone = 0;
+ this.firstAttempt = true;
+
+ if (last + 1 < 10000) {
+ fallbackSort(data, last);
+ } else {
+ mainSort(data, last);
+
+ if (this.firstAttempt && (this.workDone > this.workLimit)) {
+ fallbackSort(data, last);
+ }
+ }
+
+ final int[] fmap = data.fmap;
+ data.origPtr = -1;
+ for (int i = 0; i <= last; i++) {
+ if (fmap[i] == 0) {
+ data.origPtr = i;
+ break;
+ }
+ }
+
+ // assert (data.origPtr != -1) : data.origPtr;
+ }
+
+ /**
+ * Adapt fallbackSort to the expected interface of the rest of the
+ * code, in particular deal with the fact that block starts at
+ * offset 1 (in libbzip2 1.0.6 it starts at 0).
+ */
+ final void fallbackSort(final CBZip2OutputStream.Data data,
+ final int last) {
+ data.block[0] = data.block[last + 1];
+ fallbackSort(data.fmap, data.block, last + 1);
+ for (int i = 0; i < last + 1; i++) {
+ --data.fmap[i];
+ }
+ for (int i = 0; i < last + 1; i++) {
+ if (data.fmap[i] == -1) {
+ data.fmap[i] = last;
+ break;
+ }
+ }
+ }
+
+/*---------------------------------------------*/
+
+/*---------------------------------------------*/
+/*--- LBZ2: Fallback O(N log(N)^2) sorting ---*/
+/*--- algorithm, for repetitive blocks ---*/
+/*---------------------------------------------*/
+
+ /*
+ * This is the fallback sorting algorithm libbzip2 1.0.6 uses for
+ * repetitive or very short inputs.
+ *
+ * The idea is inspired by Manber-Myers string suffix sorting
+ * algorithm. First a bucket sort places each permutation of the
+ * block into a bucket based on its first byte. Permutations are
+ * represented by pointers to their first character kept in
+ * (partially) sorted order inside the array ftab.
+ *
+ * The next step visits all buckets in order and performs a
+ * quicksort on all permutations of the bucket based on the index
+ * of the bucket the second byte of the permutation belongs to,
+ * thereby forming new buckets. When arrived here the
+ * permutations are sorted up to the second character and we have
+ * buckets of permutations that are identical up to two
+ * characters.
+ *
+ * Repeat the step of quicksorting each bucket, now based on the
+ * bucket holding the sequence of the third and forth character
+ * leading to four byte buckets. Repeat this doubling of bucket
+ * sizes until all buckets only contain single permutations or the
+ * bucket size exceeds the block size.
+ *
+ * I.e.
+ *
+ * "abraba" form three buckets for the chars "a", "b", and "r" in
+ * the first step with
+ *
+ * fmap = { 'a:' 5, 3, 0, 'b:' 4, 1, 'r', 2 }
+ *
+ * when looking at the bucket of "a"s the second characters are in
+ * the buckets that start with fmap-index 0 (rolled over), 3 and 3
+ * respectively, forming two new buckets "aa" and "ab", so we get
+ *
+ * fmap = { 'aa:' 5, 'ab:' 3, 0, 'ba:' 4, 'br': 1, 'ra:' 2 }
+ *
+ * since the last bucket only contained a single item it didn't
+ * have to be sorted at all.
+ *
+ * There now is just one bucket with more than one permutation
+ * that remains to be sorted. For the permutation that starts
+ * with index 3 the third and forth char are in bucket 'aa' at
+ * index 0 and for the one starting at block index 0 they are in
+ * bucket 'ra' with sort index 5. The fully sorted order then becomes.
+ *
+ * fmap = { 5, 3, 0, 4, 1, 2 }
+ *
+ */
+
+ /**
+ * @param fmap points to the index of the starting point of a
+ * permutation inside the block of data in the current
+ * partially sorted order
+ * @param eclass points from the index of a character inside the
+ * block to the first index in fmap that contains the
+ * bucket of its suffix that is sorted in this step.
+ * @param lo lower boundary of the fmap-interval to be sorted
+ * @param hi upper boundary of the fmap-interval to be sorted
+ */
+ private void fallbackSimpleSort(int[] fmap,
+ int[] eclass,
+ int lo,
+ int hi) {
+ if (lo == hi) {
+ return;
+ }
+
+ int j;
+ if (hi - lo > 3) {
+ for (int i = hi - 4; i >= lo; i--) {
+ int tmp = fmap[i];
+ int ec_tmp = eclass[tmp];
+ for (j = i + 4; j <= hi && ec_tmp > eclass[fmap[j]];
+ j += 4) {
+ fmap[j - 4] = fmap[j];
+ }
+ fmap[j - 4] = tmp;
+ }
+ }
+
+ for (int i = hi - 1; i >= lo; i--) {
+ int tmp = fmap[i];
+ int ec_tmp = eclass[tmp];
+ for (j = i + 1; j <= hi && ec_tmp > eclass[fmap[j]]; j++) {
+ fmap[j - 1] = fmap[j];
+ }
+ fmap[j-1] = tmp;
+ }
+ }
+
+ private static final int FALLBACK_QSORT_SMALL_THRESH = 10;
+
+ /**
+ * swaps two values in fmap
+ */
+ private void fswap(int[] fmap, int zz1, int zz2) {
+ int zztmp = fmap[zz1];
+ fmap[zz1] = fmap[zz2];
+ fmap[zz2] = zztmp;
+ }
+
+ /**
+ * swaps two intervals starting at yyp1 and yyp2 of length yyn inside fmap.
+ */
+ private void fvswap(int[] fmap, int yyp1, int yyp2, int yyn) {
+ while (yyn > 0) {
+ fswap(fmap, yyp1, yyp2);
+ yyp1++; yyp2++; yyn--;
+ }
+ }
+
+ private int fmin(int a, int b) {
+ return a < b ? a : b;
+ }
+
+ private void fpush(int sp, int lz, int hz) {
+ stack_ll[sp] = lz;
+ stack_hh[sp] = hz;
+ }
+
+ private int[] fpop(int sp) {
+ return new int[] { stack_ll[sp], stack_hh[sp] };
+ }
+
+ /**
+ * @param fmap points to the index of the starting point of a
+ * permutation inside the block of data in the current
+ * partially sorted order
+ * @param eclass points from the index of a character inside the
+ * block to the first index in fmap that contains the
+ * bucket of its suffix that is sorted in this step.
+ * @param loSt lower boundary of the fmap-interval to be sorted
+ * @param hiSt upper boundary of the fmap-interval to be sorted
+ */
+ private void fallbackQSort3(int[] fmap,
+ int[] eclass,
+ int loSt,
+ int hiSt) {
+ int lo, unLo, ltLo, hi, unHi, gtHi, n;
+
+ long r = 0;
+ int sp = 0;
+ fpush(sp++, loSt, hiSt);
+
+ while (sp > 0) {
+ int[] s = fpop(--sp);
+ lo = s[0]; hi = s[1];
+
+ if (hi - lo < FALLBACK_QSORT_SMALL_THRESH) {
+ fallbackSimpleSort(fmap, eclass, lo, hi);
+ continue;
+ }
+
+ /* LBZ2: Random partitioning. Median of 3 sometimes fails to
+ avoid bad cases. Median of 9 seems to help but
+ looks rather expensive. This too seems to work but
+ is cheaper. Guidance for the magic constants
+ 7621 and 32768 is taken from Sedgewick's algorithms
+ book, chapter 35.
+ */
+ r = ((r * 7621) + 1) % 32768;
+ long r3 = r % 3, med;
+ if (r3 == 0) {
+ med = eclass[fmap[lo]];
+ } else if (r3 == 1) {
+ med = eclass[fmap[(lo + hi) >>> 1]];
+ } else {
+ med = eclass[fmap[hi]];
+ }
+
+ unLo = ltLo = lo;
+ unHi = gtHi = hi;
+
+ // looks like the ternary partition attributed to Wegner
+ // in the cited Sedgewick paper
+ while (true) {
+ while (true) {
+ if (unLo > unHi) {
+ break;
+ }
+ n = eclass[fmap[unLo]] - (int) med;
+ if (n == 0) {
+ fswap(fmap, unLo, ltLo);
+ ltLo++; unLo++;
+ continue;
+ }
+ if (n > 0) {
+ break;
+ }
+ unLo++;
+ }
+ while (true) {
+ if (unLo > unHi) {
+ break;
+ }
+ n = eclass[fmap[unHi]] - (int) med;
+ if (n == 0) {
+ fswap(fmap, unHi, gtHi);
+ gtHi--; unHi--;
+ continue;
+ }
+ if (n < 0) {
+ break;
+ }
+ unHi--;
+ }
+ if (unLo > unHi) {
+ break;
+ }
+ fswap(fmap, unLo, unHi); unLo++; unHi--;
+ }
+
+ if (gtHi < ltLo) {
+ continue;
+ }
+
+ n = fmin(ltLo - lo, unLo - ltLo);
+ fvswap(fmap, lo, unLo - n, n);
+ int m = fmin(hi - gtHi, gtHi - unHi);
+ fvswap(fmap, unHi + 1, hi - m + 1, m);
+
+ n = lo + unLo - ltLo - 1;
+ m = hi - (gtHi - unHi) + 1;
+
+ if (n - lo > hi - m) {
+ fpush(sp++, lo, n);
+ fpush(sp++, m, hi);
+ } else {
+ fpush(sp++, m, hi);
+ fpush(sp++, lo, n);
+ }
+ }
+ }
+
+
+/*---------------------------------------------*/
+
+ private int[] eclass;
+
+ private int[] getEclass() {
+ return eclass == null
+ ? (eclass = new int[quadrant.length / 2]) : eclass;
+ }
+
+ /*
+ * The C code uses an array of ints (each int holding 32 flags) to
+ * represents the bucket-start flags (bhtab). It also contains
+ * optimizations to skip over 32 consecutively set or
+ * consecutively unset bits on word boundaries at once. For now
+ * I've chosen to use the simpler but potentially slower code
+ * using BitSet - also in the hope that using the BitSet#nextXXX
+ * methods may be fast enough.
+ */
+
+ /**
+ * @param fmap points to the index of the starting point of a
+ * permutation inside the block of data in the current
+ * partially sorted order
+ * @param block the original data
+ * @param nblock size of the block
+ * @param off offset of first byte to sort in block
+ */
+ final void fallbackSort(int[] fmap, byte[] block, int nblock) {
+ final int[] ftab = new int[257];
+ int H, i, j, k, l, r, cc, cc1;
+ int nNotDone;
+ int nBhtab;
+ final int[] eclass = getEclass();
+
+ for (i = 0; i < nblock; i++) {
+ eclass[i] = 0;
+ }
+ /*--
+ LBZ2: Initial 1-char radix sort to generate
+ initial fmap and initial BH bits.
+ --*/
+ for (i = 0; i < nblock; i++) {
+ ftab[block[i] & 0xff]++;
+ }
+ for (i = 1; i < 257; i++) {
+ ftab[i] += ftab[i - 1];
+ }
+
+ for (i = 0; i < nblock; i++) {
+ j = block[i] & 0xff;
+ k = ftab[j] - 1;
+ ftab[j] = k;
+ fmap[k] = i;
+ }
+
+ nBhtab = 64 + nblock;
+ BitSet bhtab = new BitSet(nBhtab);
+ for (i = 0; i < 256; i++) {
+ bhtab.set(ftab[i]);
+ }
+
+ /*--
+ LBZ2: Inductively refine the buckets. Kind-of an
+ "exponential radix sort" (!), inspired by the
+ Manber-Myers suffix array construction algorithm.
+ --*/
+
+ /*-- LBZ2: set sentinel bits for block-end detection --*/
+ for (i = 0; i < 32; i++) {
+ bhtab.set(nblock + 2 * i);
+ bhtab.clear(nblock + 2 * i + 1);
+ }
+
+ /*-- LBZ2: the log(N) loop --*/
+ H = 1;
+ while (true) {
+
+ j = 0;
+ for (i = 0; i < nblock; i++) {
+ if (bhtab.get(i)) {
+ j = i;
+ }
+ k = fmap[i] - H;
+ if (k < 0) {
+ k += nblock;
+ }
+ eclass[k] = j;
+ }
+
+ nNotDone = 0;
+ r = -1;
+ while (true) {
+
+ /*-- LBZ2: find the next non-singleton bucket --*/
+ k = r + 1;
+ k = bhtab.nextClearBit(k);
+ l = k - 1;
+ if (l >= nblock) {
+ break;
+ }
+ k = bhtab.nextSetBit(k + 1);
+ r = k - 1;
+ if (r >= nblock) {
+ break;
+ }
+
+ /*-- LBZ2: now [l, r] bracket current bucket --*/
+ if (r > l) {
+ nNotDone += (r - l + 1);
+ fallbackQSort3(fmap, eclass, l, r);
+
+ /*-- LBZ2: scan bucket and generate header bits-- */
+ cc = -1;
+ for (i = l; i <= r; i++) {
+ cc1 = eclass[fmap[i]];
+ if (cc != cc1) {
+ bhtab.set(i);
+ cc = cc1;
+ }
+ }
+ }
+ }
+
+ H *= 2;
+ if (H > nblock || nNotDone == 0) {
+ break;
+ }
+ }
+ }
+
+/*---------------------------------------------*/
+
+ /*
+ * LBZ2: Knuth's increments seem to work better than Incerpi-Sedgewick here.
+ * Possibly because the number of elems to sort is usually small, typically
+ * &lt;= 20.
+ */
+ private static final int[] INCS = { 1, 4, 13, 40, 121, 364, 1093, 3280,
+ 9841, 29524, 88573, 265720, 797161,
+ 2391484 };
+
+ /**
+ * This is the most hammered method of this class.
+ *
+ * <p>
+ * This is the version using unrolled loops. Normally I never use such ones
+ * in Java code. The unrolling has shown a noticeable performance improvement
+ * on JRE 1.4.2 (Linux i586 / HotSpot Client). Of course it depends on the
+ * JIT compiler of the vm.
+ * </p>
+ */
+ private boolean mainSimpleSort(final CBZip2OutputStream.Data dataShadow,
+ final int lo, final int hi, final int d,
+ final int lastShadow) {
+ final int bigN = hi - lo + 1;
+ if (bigN < 2) {
+ return this.firstAttempt && (this.workDone > this.workLimit);
+ }
+
+ int hp = 0;
+ while (INCS[hp] < bigN) {
+ hp++;
+ }
+
+ final int[] fmap = dataShadow.fmap;
+ final char[] quadrant = this.quadrant;
+ final byte[] block = dataShadow.block;
+ final int lastPlus1 = lastShadow + 1;
+ final boolean firstAttemptShadow = this.firstAttempt;
+ final int workLimitShadow = this.workLimit;
+ int workDoneShadow = this.workDone;
+
+ // Following block contains unrolled code which could be shortened by
+ // coding it in additional loops.
+
+ HP: while (--hp >= 0) {
+ final int h = INCS[hp];
+ final int mj = lo + h - 1;
+
+ for (int i = lo + h; i <= hi;) {
+ // copy
+ for (int k = 3; (i <= hi) && (--k >= 0); i++) {
+ final int v = fmap[i];
+ final int vd = v + d;
+ int j = i;
+
+ // for (int a;
+ // (j > mj) && mainGtU((a = fmap[j - h]) + d, vd,
+ // block, quadrant, lastShadow);
+ // j -= h) {
+ // fmap[j] = a;
+ // }
+ //
+ // unrolled version:
+
+ // start inline mainGTU
+ boolean onceRunned = false;
+ int a = 0;
+
+ HAMMER: while (true) {
+ if (onceRunned) {
+ fmap[j] = a;
+ if ((j -= h) <= mj) {
+ break HAMMER;
+ }
+ } else {
+ onceRunned = true;
+ }
+
+ a = fmap[j - h];
+ int i1 = a + d;
+ int i2 = vd;
+
+ // following could be done in a loop, but
+ // unrolled it for performance:
+ if (block[i1 + 1] == block[i2 + 1]) {
+ if (block[i1 + 2] == block[i2 + 2]) {
+ if (block[i1 + 3] == block[i2 + 3]) {
+ if (block[i1 + 4] == block[i2 + 4]) {
+ if (block[i1 + 5] == block[i2 + 5]) {
+ if (block[(i1 += 6)] == block[(i2 += 6)]) {
+ int x = lastShadow;
+ X: while (x > 0) {
+ x -= 4;
+
+ if (block[i1 + 1] == block[i2 + 1]) {
+ if (quadrant[i1] == quadrant[i2]) {
+ if (block[i1 + 2] == block[i2 + 2]) {
+ if (quadrant[i1 + 1] == quadrant[i2 + 1]) {
+ if (block[i1 + 3] == block[i2 + 3]) {
+ if (quadrant[i1 + 2] == quadrant[i2 + 2]) {
+ if (block[i1 + 4] == block[i2 + 4]) {
+ if (quadrant[i1 + 3] == quadrant[i2 + 3]) {
+ if ((i1 += 4) >= lastPlus1) {
+ i1 -= lastPlus1;
+ }
+ if ((i2 += 4) >= lastPlus1) {
+ i2 -= lastPlus1;
+ }
+ workDoneShadow++;
+ continue X;
+ } else if ((quadrant[i1 + 3] > quadrant[i2 + 3])) {
+ continue HAMMER;
+ } else {
+ break HAMMER;
+ }
+ } else if ((block[i1 + 4] & 0xff) > (block[i2 + 4] & 0xff)) {
+ continue HAMMER;
+ } else {
+ break HAMMER;
+ }
+ } else if ((quadrant[i1 + 2] > quadrant[i2 + 2])) {
+ continue HAMMER;
+ } else {
+ break HAMMER;
+ }
+ } else if ((block[i1 + 3] & 0xff) > (block[i2 + 3] & 0xff)) {
+ continue HAMMER;
+ } else {
+ break HAMMER;
+ }
+ } else if ((quadrant[i1 + 1] > quadrant[i2 + 1])) {
+ continue HAMMER;
+ } else {
+ break HAMMER;
+ }
+ } else if ((block[i1 + 2] & 0xff) > (block[i2 + 2] & 0xff)) {
+ continue HAMMER;
+ } else {
+ break HAMMER;
+ }
+ } else if ((quadrant[i1] > quadrant[i2])) {
+ continue HAMMER;
+ } else {
+ break HAMMER;
+ }
+ } else if ((block[i1 + 1] & 0xff) > (block[i2 + 1] & 0xff)) {
+ continue HAMMER;
+ } else {
+ break HAMMER;
+ }
+
+ }
+ break HAMMER;
+ } // while x > 0
+ else {
+ if ((block[i1] & 0xff) > (block[i2] & 0xff)) {
+ continue HAMMER;
+ } else {
+ break HAMMER;
+ }
+ }
+ } else if ((block[i1 + 5] & 0xff) > (block[i2 + 5] & 0xff)) {
+ continue HAMMER;
+ } else {
+ break HAMMER;
+ }
+ } else if ((block[i1 + 4] & 0xff) > (block[i2 + 4] & 0xff)) {
+ continue HAMMER;
+ } else {
+ break HAMMER;
+ }
+ } else if ((block[i1 + 3] & 0xff) > (block[i2 + 3] & 0xff)) {
+ continue HAMMER;
+ } else {
+ break HAMMER;
+ }
+ } else if ((block[i1 + 2] & 0xff) > (block[i2 + 2] & 0xff)) {
+ continue HAMMER;
+ } else {
+ break HAMMER;
+ }
+ } else if ((block[i1 + 1] & 0xff) > (block[i2 + 1] & 0xff)) {
+ continue HAMMER;
+ } else {
+ break HAMMER;
+ }
+
+ } // HAMMER
+ // end inline mainGTU
+
+ fmap[j] = v;
+ }
+
+ if (firstAttemptShadow && (i <= hi)
+ && (workDoneShadow > workLimitShadow)) {
+ break HP;
+ }
+ }
+ }
+
+ this.workDone = workDoneShadow;
+ return firstAttemptShadow && (workDoneShadow > workLimitShadow);
+ }
+
+/*--
+ LBZ2: The following is an implementation of
+ an elegant 3-way quicksort for strings,
+ described in a paper "Fast Algorithms for
+ Sorting and Searching Strings", by Robert
+ Sedgewick and Jon L. Bentley.
+--*/
+
+ private static void vswap(int[] fmap, int p1, int p2, int n) {
+ n += p1;
+ while (p1 < n) {
+ int t = fmap[p1];
+ fmap[p1++] = fmap[p2];
+ fmap[p2++] = t;
+ }
+ }
+
+ private static byte med3(byte a, byte b, byte c) {
+ return (a < b) ? (b < c ? b : a < c ? c : a) : (b > c ? b : a > c ? c
+ : a);
+ }
+
+ private static final int SMALL_THRESH = 20;
+ private static final int DEPTH_THRESH = 10;
+ private static final int WORK_FACTOR = 30;
+
+ /**
+ * Method "mainQSort3", file "blocksort.c", BZip2 1.0.2
+ */
+ private void mainQSort3(final CBZip2OutputStream.Data dataShadow,
+ final int loSt, final int hiSt, final int dSt,
+ final int last) {
+ final int[] stack_ll = this.stack_ll;
+ final int[] stack_hh = this.stack_hh;
+ final int[] stack_dd = this.stack_dd;
+ final int[] fmap = dataShadow.fmap;
+ final byte[] block = dataShadow.block;
+
+ stack_ll[0] = loSt;
+ stack_hh[0] = hiSt;
+ stack_dd[0] = dSt;
+
+ for (int sp = 1; --sp >= 0;) {
+ final int lo = stack_ll[sp];
+ final int hi = stack_hh[sp];
+ final int d = stack_dd[sp];
+
+ if ((hi - lo < SMALL_THRESH) || (d > DEPTH_THRESH)) {
+ if (mainSimpleSort(dataShadow, lo, hi, d, last)) {
+ return;
+ }
+ } else {
+ final int d1 = d + 1;
+ final int med = med3(block[fmap[lo] + d1],
+ block[fmap[hi] + d1], block[fmap[(lo + hi) >>> 1] + d1]) & 0xff;
+
+ int unLo = lo;
+ int unHi = hi;
+ int ltLo = lo;
+ int gtHi = hi;
+
+ while (true) {
+ while (unLo <= unHi) {
+ final int n = (block[fmap[unLo] + d1] & 0xff)
+ - med;
+ if (n == 0) {
+ final int temp = fmap[unLo];
+ fmap[unLo++] = fmap[ltLo];
+ fmap[ltLo++] = temp;
+ } else if (n < 0) {
+ unLo++;
+ } else {
+ break;
+ }
+ }
+
+ while (unLo <= unHi) {
+ final int n = (block[fmap[unHi] + d1] & 0xff)
+ - med;
+ if (n == 0) {
+ final int temp = fmap[unHi];
+ fmap[unHi--] = fmap[gtHi];
+ fmap[gtHi--] = temp;
+ } else if (n > 0) {
+ unHi--;
+ } else {
+ break;
+ }
+ }
+
+ if (unLo <= unHi) {
+ final int temp = fmap[unLo];
+ fmap[unLo++] = fmap[unHi];
+ fmap[unHi--] = temp;
+ } else {
+ break;
+ }
+ }
+
+ if (gtHi < ltLo) {
+ stack_ll[sp] = lo;
+ stack_hh[sp] = hi;
+ stack_dd[sp] = d1;
+ sp++;
+ } else {
+ int n = ((ltLo - lo) < (unLo - ltLo)) ? (ltLo - lo)
+ : (unLo - ltLo);
+ vswap(fmap, lo, unLo - n, n);
+ int m = ((hi - gtHi) < (gtHi - unHi)) ? (hi - gtHi)
+ : (gtHi - unHi);
+ vswap(fmap, unLo, hi - m + 1, m);
+
+ n = lo + unLo - ltLo - 1;
+ m = hi - (gtHi - unHi) + 1;
+
+ stack_ll[sp] = lo;
+ stack_hh[sp] = n;
+ stack_dd[sp] = d;
+ sp++;
+
+ stack_ll[sp] = n + 1;
+ stack_hh[sp] = m - 1;
+ stack_dd[sp] = d1;
+ sp++;
+
+ stack_ll[sp] = m;
+ stack_hh[sp] = hi;
+ stack_dd[sp] = d;
+ sp++;
+ }
+ }
+ }
+ }
+
+ private static final int SETMASK = (1 << 21);
+ private static final int CLEARMASK = (~SETMASK);
+
+ final void mainSort(final CBZip2OutputStream.Data dataShadow,
+ final int lastShadow) {
+ final int[] runningOrder = this.mainSort_runningOrder;
+ final int[] copy = this.mainSort_copy;
+ final boolean[] bigDone = this.mainSort_bigDone;
+ final int[] ftab = this.ftab;
+ final byte[] block = dataShadow.block;
+ final int[] fmap = dataShadow.fmap;
+ final char[] quadrant = this.quadrant;
+ final int workLimitShadow = this.workLimit;
+ final boolean firstAttemptShadow = this.firstAttempt;
+
+ // LBZ2: Set up the 2-byte frequency table
+ for (int i = 65537; --i >= 0;) {
+ ftab[i] = 0;
+ }
+
+ /*
+ * In the various block-sized structures, live data runs from 0 to
+ * last+NUM_OVERSHOOT_BYTES inclusive. First, set up the overshoot area
+ * for block.
+ */
+ for (int i = 0; i < BZip2Constants.NUM_OVERSHOOT_BYTES; i++) {
+ block[lastShadow + i + 2] = block[(i % (lastShadow + 1)) + 1];
+ }
+ for (int i = lastShadow + BZip2Constants.NUM_OVERSHOOT_BYTES +1; --i >= 0;) {
+ quadrant[i] = 0;
+ }
+ block[0] = block[lastShadow + 1];
+
+ // LBZ2: Complete the initial radix sort:
+
+ int c1 = block[0] & 0xff;
+ for (int i = 0; i <= lastShadow; i++) {
+ final int c2 = block[i + 1] & 0xff;
+ ftab[(c1 << 8) + c2]++;
+ c1 = c2;
+ }
+
+ for (int i = 1; i <= 65536; i++) {
+ ftab[i] += ftab[i - 1];
+ }
+
+ c1 = block[1] & 0xff;
+ for (int i = 0; i < lastShadow; i++) {
+ final int c2 = block[i + 2] & 0xff;
+ fmap[--ftab[(c1 << 8) + c2]] = i;
+ c1 = c2;
+ }
+
+ fmap[--ftab[((block[lastShadow + 1] & 0xff) << 8) + (block[1] & 0xff)]] = lastShadow;
+
+ /*
+ * LBZ2: Now ftab contains the first loc of every small bucket. Calculate the
+ * running order, from smallest to largest big bucket.
+ */
+ for (int i = 256; --i >= 0;) {
+ bigDone[i] = false;
+ runningOrder[i] = i;
+ }
+
+ for (int h = 364; h != 1;) {
+ h /= 3;
+ for (int i = h; i <= 255; i++) {
+ final int vv = runningOrder[i];
+ final int a = ftab[(vv + 1) << 8] - ftab[vv << 8];
+ final int b = h - 1;
+ int j = i;
+ for (int ro = runningOrder[j - h]; (ftab[(ro + 1) << 8] - ftab[ro << 8]) > a; ro = runningOrder[j
+ - h]) {
+ runningOrder[j] = ro;
+ j -= h;
+ if (j <= b) {
+ break;
+ }
+ }
+ runningOrder[j] = vv;
+ }
+ }
+
+ /*
+ * LBZ2: The main sorting loop.
+ */
+ for (int i = 0; i <= 255; i++) {
+ /*
+ * LBZ2: Process big buckets, starting with the least full.
+ */
+ final int ss = runningOrder[i];
+
+ // Step 1:
+ /*
+ * LBZ2: Complete the big bucket [ss] by quicksorting any unsorted small
+ * buckets [ss, j]. Hopefully previous pointer-scanning phases have
+ * already completed many of the small buckets [ss, j], so we don't
+ * have to sort them at all.
+ */
+ for (int j = 0; j <= 255; j++) {
+ final int sb = (ss << 8) + j;
+ final int ftab_sb = ftab[sb];
+ if ((ftab_sb & SETMASK) != SETMASK) {
+ final int lo = ftab_sb & CLEARMASK;
+ final int hi = (ftab[sb + 1] & CLEARMASK) - 1;
+ if (hi > lo) {
+ mainQSort3(dataShadow, lo, hi, 2, lastShadow);
+ if (firstAttemptShadow
+ && (this.workDone > workLimitShadow)) {
+ return;
+ }
+ }
+ ftab[sb] = ftab_sb | SETMASK;
+ }
+ }
+
+ // Step 2:
+ // LBZ2: Now scan this big bucket so as to synthesise the
+ // sorted order for small buckets [t, ss] for all t != ss.
+
+ for (int j = 0; j <= 255; j++) {
+ copy[j] = ftab[(j << 8) + ss] & CLEARMASK;
+ }
+
+ for (int j = ftab[ss << 8] & CLEARMASK, hj = (ftab[(ss + 1) << 8] & CLEARMASK); j < hj; j++) {
+ final int fmap_j = fmap[j];
+ c1 = block[fmap_j] & 0xff;
+ if (!bigDone[c1]) {
+ fmap[copy[c1]] = (fmap_j == 0) ? lastShadow : (fmap_j - 1);
+ copy[c1]++;
+ }
+ }
+
+ for (int j = 256; --j >= 0;) {
+ ftab[(j << 8) + ss] |= SETMASK;
+ }
+
+ // Step 3:
+ /*
+ * LBZ2: The ss big bucket is now done. Record this fact, and update the
+ * quadrant descriptors. Remember to update quadrants in the
+ * overshoot area too, if necessary. The "if (i < 255)" test merely
+ * skips this updating for the last bucket processed, since updating
+ * for the last bucket is pointless.
+ */
+ bigDone[ss] = true;
+
+ if (i < 255) {
+ final int bbStart = ftab[ss << 8] & CLEARMASK;
+ final int bbSize = (ftab[(ss + 1) << 8] & CLEARMASK) - bbStart;
+ int shifts = 0;
+
+ while ((bbSize >> shifts) > 65534) {
+ shifts++;
+ }
+
+ for (int j = 0; j < bbSize; j++) {
+ final int a2update = fmap[bbStart + j];
+ final char qVal = (char) (j >> shifts);
+ quadrant[a2update] = qVal;
+ if (a2update < BZip2Constants.NUM_OVERSHOOT_BYTES) {
+ quadrant[a2update + lastShadow + 1] = qVal;
+ }
+ }
+ }
+
+ }
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/bzip2/CBZip2InputStream.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/bzip2/CBZip2InputStream.java
new file mode 100644
index 00000000..62315d12
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/bzip2/CBZip2InputStream.java
@@ -0,0 +1,1062 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+/*
+ * This package is based on the work done by Keiron Liddle, Aftex Software
+ * <keiron@aftexsw.com> to whom the Ant project is very grateful for his
+ * great code.
+ */
+package org.apache.tools.bzip2;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * An input stream that decompresses from the BZip2 format (without the file
+ * header chars) to be read as any other stream.
+ *
+ * <p>The decompression requires large amounts of memory. Thus you
+ * should call the {@link #close() close()} method as soon as
+ * possible, to force <tt>CBZip2InputStream</tt> to release the
+ * allocated memory. See {@link CBZip2OutputStream
+ * CBZip2OutputStream} for information about memory usage.</p>
+ *
+ * <p><tt>CBZip2InputStream</tt> reads bytes from the compressed
+ * source stream via the single byte {@link java.io.InputStream#read()
+ * read()} method exclusively. Thus you should consider to use a
+ * buffered source stream.</p>
+ *
+ * <p>Instances of this class are not threadsafe.</p>
+ */
+public class CBZip2InputStream extends InputStream implements BZip2Constants {
+
+ /**
+ * Index of the last char in the block, so the block size == last + 1.
+ */
+ private int last;
+
+ /**
+ * Index in zptr[] of original string after sorting.
+ */
+ private int origPtr;
+
+ /**
+ * always: in the range 0 .. 9.
+ * The current block size is 100000 * this number.
+ */
+ private int blockSize100k;
+
+ private boolean blockRandomised;
+
+ private int bsBuff;
+ private int bsLive;
+ private final CRC crc = new CRC();
+
+ private int nInUse;
+
+ private InputStream in;
+ private final boolean decompressConcatenated;
+
+ private int currentChar = -1;
+
+ private static final int EOF = 0;
+ private static final int START_BLOCK_STATE = 1;
+ private static final int RAND_PART_A_STATE = 2;
+ private static final int RAND_PART_B_STATE = 3;
+ private static final int RAND_PART_C_STATE = 4;
+ private static final int NO_RAND_PART_A_STATE = 5;
+ private static final int NO_RAND_PART_B_STATE = 6;
+ private static final int NO_RAND_PART_C_STATE = 7;
+
+ private int currentState = START_BLOCK_STATE;
+
+ private int storedBlockCRC, storedCombinedCRC;
+ private int computedBlockCRC, computedCombinedCRC;
+
+ // Variables used by setup* methods exclusively
+
+ private int su_count;
+ private int su_ch2;
+ private int su_chPrev;
+ private int su_i2;
+ private int su_j2;
+ private int su_rNToGo;
+ private int su_rTPos;
+ private int su_tPos;
+ private char su_z;
+
+ /**
+ * All memory intensive stuff.
+ * This field is initialized by initBlock().
+ */
+ private CBZip2InputStream.Data data;
+
+ /**
+ * Constructs a new CBZip2InputStream which decompresses bytes read from
+ * the specified stream. This doesn't suppprt decompressing
+ * concatenated .bz2 files.
+ *
+ * <p>Although BZip2 headers are marked with the magic
+ * <tt>"Bz"</tt> this constructor expects the next byte in the
+ * stream to be the first one after the magic. Thus callers have
+ * to skip the first two bytes. Otherwise this constructor will
+ * throw an exception. </p>
+ *
+ * @throws IOException
+ * if the stream content is malformed or an I/O error occurs.
+ * @throws NullPointerException
+ * if <tt>in == null</tt>
+ */
+ public CBZip2InputStream(final InputStream in) throws IOException {
+ this(in, false);
+ }
+
+ /**
+ * Constructs a new CBZip2InputStream which decompresses bytes
+ * read from the specified stream.
+ *
+ * <p>Although BZip2 headers are marked with the magic
+ * <tt>"Bz"</tt> this constructor expects the next byte in the
+ * stream to be the first one after the magic. Thus callers have
+ * to skip the first two bytes. Otherwise this constructor will
+ * throw an exception. </p>
+ *
+ * @param in the InputStream from which this object should be created
+ * @param decompressConcatenated
+ * if true, decompress until the end of the input;
+ * if false, stop after the first .bz2 stream and
+ * leave the input position to point to the next
+ * byte after the .bz2 stream
+ *
+ * @throws IOException
+ * if the stream content is malformed or an I/O error occurs.
+ * @throws NullPointerException
+ * if <tt>in == null</tt>
+ */
+ public CBZip2InputStream(final InputStream in,
+ final boolean decompressConcatenated)
+ throws IOException {
+ super();
+
+ this.in = in;
+ this.decompressConcatenated = decompressConcatenated;
+
+ init(true);
+ initBlock();
+ setupBlock();
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public int read() throws IOException {
+ if (this.in != null) {
+ return read0();
+ } else {
+ throw new IOException("stream closed");
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.io.InputStream#read(byte[], int, int)
+ */
+ @Override
+ public int read(final byte[] dest, final int offs, final int len)
+ throws IOException {
+ if (offs < 0) {
+ throw new IndexOutOfBoundsException("offs(" + offs + ") < 0.");
+ }
+ if (len < 0) {
+ throw new IndexOutOfBoundsException("len(" + len + ") < 0.");
+ }
+ if (offs + len > dest.length) {
+ throw new IndexOutOfBoundsException("offs(" + offs + ") + len("
+ + len + ") > dest.length("
+ + dest.length + ").");
+ }
+ if (this.in == null) {
+ throw new IOException("stream closed");
+ }
+
+ final int hi = offs + len;
+ int destOffs = offs;
+ for (int b; (destOffs < hi) && ((b = read0()) >= 0);) {
+ dest[destOffs++] = (byte) b;
+ }
+
+ return (destOffs == offs) ? -1 : (destOffs - offs);
+ }
+
+ private void makeMaps() {
+ final boolean[] inUse = this.data.inUse;
+ final byte[] seqToUnseq = this.data.seqToUnseq;
+
+ int nInUseShadow = 0;
+
+ for (int i = 0; i < 256; i++) {
+ if (inUse[i]) {
+ seqToUnseq[nInUseShadow++] = (byte) i;
+ }
+ }
+
+ this.nInUse = nInUseShadow;
+ }
+
+ private int read0() throws IOException {
+ final int retChar = this.currentChar;
+
+ switch (this.currentState) {
+ case EOF:
+ return -1;
+
+ case START_BLOCK_STATE:
+ throw new IllegalStateException();
+
+ case RAND_PART_A_STATE:
+ throw new IllegalStateException();
+
+ case RAND_PART_B_STATE:
+ setupRandPartB();
+ break;
+
+ case RAND_PART_C_STATE:
+ setupRandPartC();
+ break;
+
+ case NO_RAND_PART_A_STATE:
+ throw new IllegalStateException();
+
+ case NO_RAND_PART_B_STATE:
+ setupNoRandPartB();
+ break;
+
+ case NO_RAND_PART_C_STATE:
+ setupNoRandPartC();
+ break;
+
+ default:
+ throw new IllegalStateException();
+ }
+
+ return retChar;
+ }
+
+ private boolean init(boolean isFirstStream) throws IOException {
+ if (null == in) {
+ throw new IOException("No InputStream");
+ }
+
+ if (isFirstStream) {
+ if (in.available() == 0) {
+ throw new IOException("Empty InputStream");
+ }
+ } else {
+ int magic0 = this.in.read();
+ if (magic0 == -1) {
+ return false;
+ }
+ int magic1 = this.in.read();
+ if (magic0 != 'B' || magic1 != 'Z') {
+ throw new IOException("Garbage after a valid BZip2 stream");
+ }
+ }
+
+ int magic2 = this.in.read();
+ if (magic2 != 'h') {
+ throw new IOException(isFirstStream
+ ? "Stream is not in the BZip2 format"
+ : "Garbage after a valid BZip2 stream");
+ }
+
+ int blockSize = this.in.read();
+ if ((blockSize < '1') || (blockSize > '9')) {
+ throw new IOException("Stream is not BZip2 formatted: illegal "
+ + "blocksize " + (char) blockSize);
+ }
+
+ this.blockSize100k = blockSize - '0';
+
+ this.bsLive = 0;
+ this.computedCombinedCRC = 0;
+
+ return true;
+ }
+
+ private void initBlock() throws IOException {
+ char magic0;
+ char magic1;
+ char magic2;
+ char magic3;
+ char magic4;
+ char magic5;
+
+ while (true) {
+ // Get the block magic bytes.
+ magic0 = bsGetUByte();
+ magic1 = bsGetUByte();
+ magic2 = bsGetUByte();
+ magic3 = bsGetUByte();
+ magic4 = bsGetUByte();
+ magic5 = bsGetUByte();
+
+ // If isn't end of stream magic, break out of the loop.
+ if (magic0 != 0x17 || magic1 != 0x72 || magic2 != 0x45
+ || magic3 != 0x38 || magic4 != 0x50 || magic5 != 0x90) {
+ break;
+ }
+
+ // End of stream was reached. Check the combined CRC and
+ // advance to the next .bz2 stream if decoding concatenated
+ // streams.
+ if (complete()) {
+ return;
+ }
+ }
+
+ if (magic0 != 0x31 || // '1'
+ magic1 != 0x41 || // ')'
+ magic2 != 0x59 || // 'Y'
+ magic3 != 0x26 || // '&'
+ magic4 != 0x53 || // 'S'
+ magic5 != 0x59 // 'Y'
+ ) {
+ this.currentState = EOF;
+ throw new IOException("bad block header");
+ } else {
+ this.storedBlockCRC = bsGetInt();
+ this.blockRandomised = bsR(1) == 1;
+
+ /**
+ * Allocate data here instead in constructor, so we do not
+ * allocate it if the input file is empty.
+ */
+ if (this.data == null) {
+ this.data = new Data(this.blockSize100k);
+ }
+
+ // currBlockNo++;
+ getAndMoveToFrontDecode();
+
+ this.crc.initialiseCRC();
+ this.currentState = START_BLOCK_STATE;
+ }
+ }
+
+ private void endBlock() throws IOException {
+ this.computedBlockCRC = this.crc.getFinalCRC();
+
+ // A bad CRC is considered a fatal error.
+ if (this.storedBlockCRC != this.computedBlockCRC) {
+ // make next blocks readable without error
+ // (repair feature, not yet documented, not tested)
+ this.computedCombinedCRC
+ = (this.storedCombinedCRC << 1)
+ | (this.storedCombinedCRC >>> 31);
+ this.computedCombinedCRC ^= this.storedBlockCRC;
+
+ reportCRCError();
+ }
+
+ this.computedCombinedCRC
+ = (this.computedCombinedCRC << 1)
+ | (this.computedCombinedCRC >>> 31);
+ this.computedCombinedCRC ^= this.computedBlockCRC;
+ }
+
+ private boolean complete() throws IOException {
+ this.storedCombinedCRC = bsGetInt();
+ this.currentState = EOF;
+ this.data = null;
+
+ if (this.storedCombinedCRC != this.computedCombinedCRC) {
+ reportCRCError();
+ }
+
+ // Look for the next .bz2 stream if decompressing
+ // concatenated files.
+ return !decompressConcatenated || !init(false);
+ }
+
+ @Override
+ public void close() throws IOException {
+ InputStream inShadow = this.in;
+ if (inShadow != null) {
+ try {
+ if (inShadow != System.in) {
+ inShadow.close();
+ }
+ } finally {
+ this.data = null;
+ this.in = null;
+ }
+ }
+ }
+
+ private int bsR(final int n) throws IOException {
+ int bsLiveShadow = this.bsLive;
+ int bsBuffShadow = this.bsBuff;
+
+ if (bsLiveShadow < n) {
+ final InputStream inShadow = this.in;
+ do {
+ int thech = inShadow.read();
+
+ if (thech < 0) {
+ throw new IOException("unexpected end of stream");
+ }
+
+ bsBuffShadow = (bsBuffShadow << 8) | thech;
+ bsLiveShadow += 8;
+ } while (bsLiveShadow < n);
+
+ this.bsBuff = bsBuffShadow;
+ }
+
+ this.bsLive = bsLiveShadow - n;
+ return (bsBuffShadow >> (bsLiveShadow - n)) & ((1 << n) - 1);
+ }
+
+ private boolean bsGetBit() throws IOException {
+ int bsLiveShadow = this.bsLive;
+ int bsBuffShadow = this.bsBuff;
+
+ if (bsLiveShadow < 1) {
+ int thech = this.in.read();
+
+ if (thech < 0) {
+ throw new IOException("unexpected end of stream");
+ }
+
+ bsBuffShadow = (bsBuffShadow << 8) | thech;
+ bsLiveShadow += 8;
+ this.bsBuff = bsBuffShadow;
+ }
+
+ this.bsLive = bsLiveShadow - 1;
+ return ((bsBuffShadow >> (bsLiveShadow - 1)) & 1) != 0;
+ }
+
+ private char bsGetUByte() throws IOException {
+ return (char) bsR(8);
+ }
+
+ private int bsGetInt() throws IOException {
+ return (((((bsR(8) << 8) | bsR(8)) << 8) | bsR(8)) << 8) | bsR(8);
+ }
+
+ /**
+ * Called by createHuffmanDecodingTables() exclusively.
+ */
+ private static void hbCreateDecodeTables(final int[] limit,
+ final int[] base,
+ final int[] perm,
+ final char[] length,
+ final int minLen,
+ final int maxLen,
+ final int alphaSize) {
+ for (int i = minLen, pp = 0; i <= maxLen; i++) {
+ for (int j = 0; j < alphaSize; j++) {
+ if (length[j] == i) {
+ perm[pp++] = j;
+ }
+ }
+ }
+
+ for (int i = MAX_CODE_LEN; --i > 0;) {
+ base[i] = 0;
+ limit[i] = 0;
+ }
+
+ for (int i = 0; i < alphaSize; i++) {
+ base[length[i] + 1]++;
+ }
+
+ for (int i = 1, b = base[0]; i < MAX_CODE_LEN; i++) {
+ b += base[i];
+ base[i] = b;
+ }
+
+ for (int i = minLen, vec = 0, b = base[i]; i <= maxLen; i++) {
+ final int nb = base[i + 1];
+ vec += nb - b;
+ b = nb;
+ limit[i] = vec - 1;
+ vec <<= 1;
+ }
+
+ for (int i = minLen + 1; i <= maxLen; i++) {
+ base[i] = ((limit[i - 1] + 1) << 1) - base[i];
+ }
+ }
+
+ private void recvDecodingTables() throws IOException {
+ final Data dataShadow = this.data;
+ final boolean[] inUse = dataShadow.inUse;
+ final byte[] pos = dataShadow.recvDecodingTables_pos;
+ final byte[] selector = dataShadow.selector;
+ final byte[] selectorMtf = dataShadow.selectorMtf;
+
+ int inUse16 = 0;
+
+ /* Receive the mapping table */
+ for (int i = 0; i < 16; i++) {
+ if (bsGetBit()) {
+ inUse16 |= 1 << i;
+ }
+ }
+
+ for (int i = 256; --i >= 0;) {
+ inUse[i] = false;
+ }
+
+ for (int i = 0; i < 16; i++) {
+ if ((inUse16 & (1 << i)) != 0) {
+ final int i16 = i << 4;
+ for (int j = 0; j < 16; j++) {
+ if (bsGetBit()) {
+ inUse[i16 + j] = true;
+ }
+ }
+ }
+ }
+
+ makeMaps();
+ final int alphaSize = this.nInUse + 2;
+
+ /* Now the selectors */
+ final int nGroups = bsR(3);
+ final int nSelectors = bsR(15);
+
+ for (int i = 0; i < nSelectors; i++) {
+ int j = 0;
+ while (bsGetBit()) {
+ j++;
+ }
+ selectorMtf[i] = (byte) j;
+ }
+
+ /* Undo the MTF values for the selectors. */
+ for (int v = nGroups; --v >= 0;) {
+ pos[v] = (byte) v;
+ }
+
+ for (int i = 0; i < nSelectors; i++) {
+ int v = selectorMtf[i] & 0xff;
+ final byte tmp = pos[v];
+ while (v > 0) {
+ // nearly all times v is zero, 4 in most other cases
+ pos[v] = pos[v - 1];
+ v--;
+ }
+ pos[0] = tmp;
+ selector[i] = tmp;
+ }
+
+ final char[][] len = dataShadow.temp_charArray2d;
+
+ /* Now the coding tables */
+ for (int t = 0; t < nGroups; t++) {
+ int curr = bsR(5);
+ final char[] len_t = len[t];
+ for (int i = 0; i < alphaSize; i++) {
+ while (bsGetBit()) {
+ curr += bsGetBit() ? -1 : 1;
+ }
+ len_t[i] = (char) curr;
+ }
+ }
+
+ // finally create the Huffman tables
+ createHuffmanDecodingTables(alphaSize, nGroups);
+ }
+
+ /**
+ * Called by recvDecodingTables() exclusively.
+ */
+ private void createHuffmanDecodingTables(final int alphaSize,
+ final int nGroups) {
+ final Data dataShadow = this.data;
+ final char[][] len = dataShadow.temp_charArray2d;
+ final int[] minLens = dataShadow.minLens;
+ final int[][] limit = dataShadow.limit;
+ final int[][] base = dataShadow.base;
+ final int[][] perm = dataShadow.perm;
+
+ for (int t = 0; t < nGroups; t++) {
+ int minLen = 32;
+ int maxLen = 0;
+ final char[] len_t = len[t];
+ for (int i = alphaSize; --i >= 0;) {
+ final char lent = len_t[i];
+ if (lent > maxLen) {
+ maxLen = lent;
+ }
+ if (lent < minLen) {
+ minLen = lent;
+ }
+ }
+ hbCreateDecodeTables(limit[t], base[t], perm[t], len[t], minLen,
+ maxLen, alphaSize);
+ minLens[t] = minLen;
+ }
+ }
+
+ private void getAndMoveToFrontDecode() throws IOException {
+ this.origPtr = bsR(24);
+ recvDecodingTables();
+
+ final InputStream inShadow = this.in;
+ final Data dataShadow = this.data;
+ final byte[] ll8 = dataShadow.ll8;
+ final int[] unzftab = dataShadow.unzftab;
+ final byte[] selector = dataShadow.selector;
+ final byte[] seqToUnseq = dataShadow.seqToUnseq;
+ final char[] yy = dataShadow.getAndMoveToFrontDecode_yy;
+ final int[] minLens = dataShadow.minLens;
+ final int[][] limit = dataShadow.limit;
+ final int[][] base = dataShadow.base;
+ final int[][] perm = dataShadow.perm;
+ final int limitLast = this.blockSize100k * 100000;
+
+ /*
+ Setting up the unzftab entries here is not strictly
+ necessary, but it does save having to do it later
+ in a separate pass, and so saves a block's worth of
+ cache misses.
+ */
+ for (int i = 256; --i >= 0;) {
+ yy[i] = (char) i;
+ unzftab[i] = 0;
+ }
+
+ int groupNo = 0;
+ int groupPos = G_SIZE - 1;
+ final int eob = this.nInUse + 1;
+ int nextSym = getAndMoveToFrontDecode0(0);
+ int bsBuffShadow = this.bsBuff;
+ int bsLiveShadow = this.bsLive;
+ int lastShadow = -1;
+ int zt = selector[groupNo] & 0xff;
+ int[] base_zt = base[zt];
+ int[] limit_zt = limit[zt];
+ int[] perm_zt = perm[zt];
+ int minLens_zt = minLens[zt];
+
+ while (nextSym != eob) {
+ if ((nextSym == RUNA) || (nextSym == RUNB)) {
+ int s = -1;
+
+ for (int n = 1; true; n <<= 1) {
+ if (nextSym == RUNA) {
+ s += n;
+ } else if (nextSym == RUNB) {
+ s += n << 1;
+ } else {
+ break;
+ }
+
+ if (groupPos == 0) {
+ groupPos = G_SIZE - 1;
+ zt = selector[++groupNo] & 0xff;
+ base_zt = base[zt];
+ limit_zt = limit[zt];
+ perm_zt = perm[zt];
+ minLens_zt = minLens[zt];
+ } else {
+ groupPos--;
+ }
+
+ int zn = minLens_zt;
+
+ // Inlined:
+ // int zvec = bsR(zn);
+ while (bsLiveShadow < zn) {
+ final int thech = inShadow.read();
+ if (thech >= 0) {
+ bsBuffShadow = (bsBuffShadow << 8) | thech;
+ bsLiveShadow += 8;
+ continue;
+ } else {
+ throw new IOException("unexpected end of stream");
+ }
+ }
+ int zvec = (bsBuffShadow >> (bsLiveShadow - zn)) & ((1 << zn) - 1);
+ bsLiveShadow -= zn;
+
+ while (zvec > limit_zt[zn]) {
+ zn++;
+ while (bsLiveShadow < 1) {
+ final int thech = inShadow.read();
+ if (thech >= 0) {
+ bsBuffShadow = (bsBuffShadow << 8) | thech;
+ bsLiveShadow += 8;
+ continue;
+ } else {
+ throw new IOException("unexpected end of stream");
+ }
+ }
+ bsLiveShadow--;
+ zvec = (zvec << 1) | ((bsBuffShadow >> bsLiveShadow) & 1);
+ }
+ nextSym = perm_zt[zvec - base_zt[zn]];
+ }
+
+ final byte ch = seqToUnseq[yy[0]];
+ unzftab[ch & 0xff] += s + 1;
+
+ while (s-- >= 0) {
+ ll8[++lastShadow] = ch;
+ }
+
+ if (lastShadow >= limitLast) {
+ throw new IOException("block overrun");
+ }
+ } else {
+ if (++lastShadow >= limitLast) {
+ throw new IOException("block overrun");
+ }
+
+ final char tmp = yy[nextSym - 1];
+ unzftab[seqToUnseq[tmp] & 0xff]++;
+ ll8[lastShadow] = seqToUnseq[tmp];
+
+ /*
+ This loop is hammered during decompression,
+ hence avoid native method call overhead of
+ System.arraycopy for very small ranges to copy.
+ */
+ if (nextSym <= 16) {
+ for (int j = nextSym - 1; j > 0;) {
+ yy[j] = yy[--j];
+ }
+ } else {
+ System.arraycopy(yy, 0, yy, 1, nextSym - 1);
+ }
+
+ yy[0] = tmp;
+
+ if (groupPos == 0) {
+ groupPos = G_SIZE - 1;
+ zt = selector[++groupNo] & 0xff;
+ base_zt = base[zt];
+ limit_zt = limit[zt];
+ perm_zt = perm[zt];
+ minLens_zt = minLens[zt];
+ } else {
+ groupPos--;
+ }
+
+ int zn = minLens_zt;
+
+ // Inlined:
+ // int zvec = bsR(zn);
+ while (bsLiveShadow < zn) {
+ final int thech = inShadow.read();
+ if (thech >= 0) {
+ bsBuffShadow = (bsBuffShadow << 8) | thech;
+ bsLiveShadow += 8;
+ continue;
+ } else {
+ throw new IOException("unexpected end of stream");
+ }
+ }
+ int zvec = (bsBuffShadow >> (bsLiveShadow - zn)) & ((1 << zn) - 1);
+ bsLiveShadow -= zn;
+
+ while (zvec > limit_zt[zn]) {
+ zn++;
+ while (bsLiveShadow < 1) {
+ final int thech = inShadow.read();
+ if (thech >= 0) {
+ bsBuffShadow = (bsBuffShadow << 8) | thech;
+ bsLiveShadow += 8;
+ continue;
+ } else {
+ throw new IOException("unexpected end of stream");
+ }
+ }
+ bsLiveShadow--;
+ zvec = (zvec << 1) | ((bsBuffShadow >> bsLiveShadow) & 1);
+ }
+ nextSym = perm_zt[zvec - base_zt[zn]];
+ }
+ }
+
+ this.last = lastShadow;
+ this.bsLive = bsLiveShadow;
+ this.bsBuff = bsBuffShadow;
+ }
+
+ private int getAndMoveToFrontDecode0(final int groupNo)
+ throws IOException {
+ final InputStream inShadow = this.in;
+ final Data dataShadow = this.data;
+ final int zt = dataShadow.selector[groupNo] & 0xff;
+ final int[] limit_zt = dataShadow.limit[zt];
+ int zn = dataShadow.minLens[zt];
+ int zvec = bsR(zn);
+ int bsLiveShadow = this.bsLive;
+ int bsBuffShadow = this.bsBuff;
+
+ while (zvec > limit_zt[zn]) {
+ zn++;
+ while (bsLiveShadow < 1) {
+ final int thech = inShadow.read();
+
+ if (thech >= 0) {
+ bsBuffShadow = (bsBuffShadow << 8) | thech;
+ bsLiveShadow += 8;
+ continue;
+ } else {
+ throw new IOException("unexpected end of stream");
+ }
+ }
+ bsLiveShadow--;
+ zvec = (zvec << 1) | ((bsBuffShadow >> bsLiveShadow) & 1);
+ }
+
+ this.bsLive = bsLiveShadow;
+ this.bsBuff = bsBuffShadow;
+
+ return dataShadow.perm[zt][zvec - dataShadow.base[zt][zn]];
+ }
+
+ private void setupBlock() throws IOException {
+ if (this.data == null) {
+ return;
+ }
+
+ final int[] cftab = this.data.cftab;
+ final int[] tt = this.data.initTT(this.last + 1);
+ final byte[] ll8 = this.data.ll8;
+ cftab[0] = 0;
+ System.arraycopy(this.data.unzftab, 0, cftab, 1, 256);
+
+ for (int i = 1, c = cftab[0]; i <= 256; i++) {
+ c += cftab[i];
+ cftab[i] = c;
+ }
+
+ for (int i = 0, lastShadow = this.last; i <= lastShadow; i++) {
+ tt[cftab[ll8[i] & 0xff]++] = i;
+ }
+
+ if ((this.origPtr < 0) || (this.origPtr >= tt.length)) {
+ throw new IOException("stream corrupted");
+ }
+
+ this.su_tPos = tt[this.origPtr];
+ this.su_count = 0;
+ this.su_i2 = 0;
+ this.su_ch2 = 256; /* not a char and not EOF */
+
+ if (this.blockRandomised) {
+ this.su_rNToGo = 0;
+ this.su_rTPos = 0;
+ setupRandPartA();
+ } else {
+ setupNoRandPartA();
+ }
+ }
+
+ private void setupRandPartA() throws IOException {
+ if (this.su_i2 <= this.last) {
+ this.su_chPrev = this.su_ch2;
+ int su_ch2Shadow = this.data.ll8[this.su_tPos] & 0xff;
+ this.su_tPos = this.data.tt[this.su_tPos];
+ if (this.su_rNToGo == 0) {
+ this.su_rNToGo = BZip2Constants.rNums[this.su_rTPos] - 1;
+ if (++this.su_rTPos == 512) {
+ this.su_rTPos = 0;
+ }
+ } else {
+ this.su_rNToGo--;
+ }
+ this.su_ch2 = su_ch2Shadow ^= (this.su_rNToGo == 1) ? 1 : 0;
+ this.su_i2++;
+ this.currentChar = su_ch2Shadow;
+ this.currentState = RAND_PART_B_STATE;
+ this.crc.updateCRC(su_ch2Shadow);
+ } else {
+ endBlock();
+ initBlock();
+ setupBlock();
+ }
+ }
+
+ private void setupNoRandPartA() throws IOException {
+ if (this.su_i2 <= this.last) {
+ this.su_chPrev = this.su_ch2;
+ int su_ch2Shadow = this.data.ll8[this.su_tPos] & 0xff;
+ this.su_ch2 = su_ch2Shadow;
+ this.su_tPos = this.data.tt[this.su_tPos];
+ this.su_i2++;
+ this.currentChar = su_ch2Shadow;
+ this.currentState = NO_RAND_PART_B_STATE;
+ this.crc.updateCRC(su_ch2Shadow);
+ } else {
+ this.currentState = NO_RAND_PART_A_STATE;
+ endBlock();
+ initBlock();
+ setupBlock();
+ }
+ }
+
+ private void setupRandPartB() throws IOException {
+ if (this.su_ch2 != this.su_chPrev) {
+ this.currentState = RAND_PART_A_STATE;
+ this.su_count = 1;
+ setupRandPartA();
+ } else if (++this.su_count >= 4) {
+ this.su_z = (char) (this.data.ll8[this.su_tPos] & 0xff);
+ this.su_tPos = this.data.tt[this.su_tPos];
+ if (this.su_rNToGo == 0) {
+ this.su_rNToGo = BZip2Constants.rNums[this.su_rTPos] - 1;
+ if (++this.su_rTPos == 512) {
+ this.su_rTPos = 0;
+ }
+ } else {
+ this.su_rNToGo--;
+ }
+ this.su_j2 = 0;
+ this.currentState = RAND_PART_C_STATE;
+ if (this.su_rNToGo == 1) {
+ this.su_z ^= 1;
+ }
+ setupRandPartC();
+ } else {
+ this.currentState = RAND_PART_A_STATE;
+ setupRandPartA();
+ }
+ }
+
+ private void setupRandPartC() throws IOException {
+ if (this.su_j2 < this.su_z) {
+ this.currentChar = this.su_ch2;
+ this.crc.updateCRC(this.su_ch2);
+ this.su_j2++;
+ } else {
+ this.currentState = RAND_PART_A_STATE;
+ this.su_i2++;
+ this.su_count = 0;
+ setupRandPartA();
+ }
+ }
+
+ private void setupNoRandPartB() throws IOException {
+ if (this.su_ch2 != this.su_chPrev) {
+ this.su_count = 1;
+ setupNoRandPartA();
+ } else if (++this.su_count >= 4) {
+ this.su_z = (char) (this.data.ll8[this.su_tPos] & 0xff);
+ this.su_tPos = this.data.tt[this.su_tPos];
+ this.su_j2 = 0;
+ setupNoRandPartC();
+ } else {
+ setupNoRandPartA();
+ }
+ }
+
+ private void setupNoRandPartC() throws IOException {
+ if (this.su_j2 < this.su_z) {
+ int su_ch2Shadow = this.su_ch2;
+ this.currentChar = su_ch2Shadow;
+ this.crc.updateCRC(su_ch2Shadow);
+ this.su_j2++;
+ this.currentState = NO_RAND_PART_C_STATE;
+ } else {
+ this.su_i2++;
+ this.su_count = 0;
+ setupNoRandPartA();
+ }
+ }
+
+ private static final class Data extends Object {
+
+ // (with blockSize 900k)
+ final boolean[] inUse = new boolean[256]; // 256 byte
+
+ final byte[] seqToUnseq = new byte[256]; // 256 byte
+ final byte[] selector = new byte[MAX_SELECTORS]; // 18002 byte
+ final byte[] selectorMtf = new byte[MAX_SELECTORS]; // 18002 byte
+
+ /**
+ * Freq table collected to save a pass over the data during
+ * decompression.
+ */
+ final int[] unzftab = new int[256]; // 1024 byte
+
+ final int[][] limit = new int[N_GROUPS][MAX_ALPHA_SIZE]; // 6192 byte
+ final int[][] base = new int[N_GROUPS][MAX_ALPHA_SIZE]; // 6192 byte
+ final int[][] perm = new int[N_GROUPS][MAX_ALPHA_SIZE]; // 6192 byte
+ final int[] minLens = new int[N_GROUPS]; // 24 byte
+
+ final int[] cftab = new int[257]; // 1028 byte
+ final char[] getAndMoveToFrontDecode_yy = new char[256]; // 512 byte
+ final char[][] temp_charArray2d = new char[N_GROUPS][MAX_ALPHA_SIZE]; // 3096 byte
+ final byte[] recvDecodingTables_pos = new byte[N_GROUPS]; // 6 byte
+ //---------------
+ // 60798 byte
+
+ int[] tt; // 3600000 byte
+ byte[] ll8; // 900000 byte
+ //---------------
+ // 4560782 byte
+ //===============
+
+ Data(int blockSize100k) {
+ super();
+
+ this.ll8 = new byte[blockSize100k * BZip2Constants.baseBlockSize];
+ }
+
+ /**
+ * Initializes the {@link #tt} array.
+ *
+ * This method is called when the required length of the array
+ * is known. I don't initialize it at construction time to
+ * avoid unnecessary memory allocation when compressing small
+ * files.
+ */
+ final int[] initTT(int length) {
+ int[] ttShadow = this.tt;
+
+ // tt.length should always be >= length, but theoretically
+ // it can happen, if the compressor mixed small and large
+ // blocks. Normally only the last block will be smaller
+ // than others.
+ if ((ttShadow == null) || (ttShadow.length < length)) {
+ this.tt = ttShadow = new int[length];
+ }
+
+ return ttShadow;
+ }
+
+ }
+
+ private static void reportCRCError() throws IOException {
+ // The clean way would be to throw an exception.
+ //throw new IOException("crc error");
+
+ // Just print a message, like the previous versions of this class did
+ System.err.println("BZip2 CRC error");
+ }
+
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/bzip2/CBZip2OutputStream.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/bzip2/CBZip2OutputStream.java
new file mode 100644
index 00000000..01e23424
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/bzip2/CBZip2OutputStream.java
@@ -0,0 +1,1580 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+/*
+ * This package is based on the work done by Keiron Liddle, Aftex Software
+ * <keiron@aftexsw.com> to whom the Ant project is very grateful for his
+ * great code.
+ */
+
+package org.apache.tools.bzip2;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * An output stream that compresses into the BZip2 format (without the file
+ * header chars) into another stream.
+ *
+ * <p>
+ * The compression requires large amounts of memory. Thus you should call the
+ * {@link #close() close()} method as soon as possible, to force
+ * <tt>CBZip2OutputStream</tt> to release the allocated memory.
+ * </p>
+ *
+ * <p> You can shrink the amount of allocated memory and maybe raise
+ * the compression speed by choosing a lower blocksize, which in turn
+ * may cause a lower compression ratio. You can avoid unnecessary
+ * memory allocation by avoiding using a blocksize which is bigger
+ * than the size of the input. </p>
+ *
+ * <p> You can compute the memory usage for compressing by the
+ * following formula: </p>
+ *
+ * <pre>
+ * &lt;code&gt;400k + (9 * blocksize)&lt;/code&gt;.
+ * </pre>
+ *
+ * <p> To get the memory required for decompression by {@link
+ * CBZip2InputStream CBZip2InputStream} use </p>
+ *
+ * <pre>
+ * &lt;code&gt;65k + (5 * blocksize)&lt;/code&gt;.
+ * </pre>
+ *
+ * <table width="100%" border="1">
+ * <colgroup> <col width="33%" /> <col width="33%" /> <col width="33%" />
+ * </colgroup>
+ * <tr>
+ * <th colspan="3">Memory usage by blocksize</th>
+ * </tr>
+ * <tr>
+ * <th align="right">Blocksize</th> <th align="right">Compression<br>
+ * memory usage</th> <th align="right">Decompression<br>
+ * memory usage</th>
+ * </tr>
+ * <tr>
+ * <td align="right">100k</td>
+ * <td align="right">1300k</td>
+ * <td align="right">565k</td>
+ * </tr>
+ * <tr>
+ * <td align="right">200k</td>
+ * <td align="right">2200k</td>
+ * <td align="right">1065k</td>
+ * </tr>
+ * <tr>
+ * <td align="right">300k</td>
+ * <td align="right">3100k</td>
+ * <td align="right">1565k</td>
+ * </tr>
+ * <tr>
+ * <td align="right">400k</td>
+ * <td align="right">4000k</td>
+ * <td align="right">2065k</td>
+ * </tr>
+ * <tr>
+ * <td align="right">500k</td>
+ * <td align="right">4900k</td>
+ * <td align="right">2565k</td>
+ * </tr>
+ * <tr>
+ * <td align="right">600k</td>
+ * <td align="right">5800k</td>
+ * <td align="right">3065k</td>
+ * </tr>
+ * <tr>
+ * <td align="right">700k</td>
+ * <td align="right">6700k</td>
+ * <td align="right">3565k</td>
+ * </tr>
+ * <tr>
+ * <td align="right">800k</td>
+ * <td align="right">7600k</td>
+ * <td align="right">4065k</td>
+ * </tr>
+ * <tr>
+ * <td align="right">900k</td>
+ * <td align="right">8500k</td>
+ * <td align="right">4565k</td>
+ * </tr>
+ * </table>
+ *
+ * <p>
+ * For decompression <tt>CBZip2InputStream</tt> allocates less memory if the
+ * bzipped input is smaller than one block.
+ * </p>
+ *
+ * <p>
+ * Instances of this class are not threadsafe.
+ * </p>
+ *
+ * <p>
+ * TODO: Update to BZip2 1.0.1
+ * </p>
+ *
+ */
+public class CBZip2OutputStream extends OutputStream
+ implements BZip2Constants {
+
+ /**
+ * The minimum supported blocksize <tt> == 1</tt>.
+ */
+ public static final int MIN_BLOCKSIZE = 1;
+
+ /**
+ * The maximum supported blocksize <tt> == 9</tt>.
+ */
+ public static final int MAX_BLOCKSIZE = 9;
+
+ /**
+ * This constant is accessible by subclasses for historical
+ * purposes. If you don't know what it means then you don't need
+ * it.
+ */
+ protected static final int SETMASK = (1 << 21);
+
+ /**
+ * This constant is accessible by subclasses for historical
+ * purposes. If you don't know what it means then you don't need
+ * it.
+ */
+ protected static final int CLEARMASK = (~SETMASK);
+
+ /**
+ * This constant is accessible by subclasses for historical
+ * purposes. If you don't know what it means then you don't need
+ * it.
+ */
+ protected static final int GREATER_ICOST = 15;
+
+ /**
+ * This constant is accessible by subclasses for historical
+ * purposes. If you don't know what it means then you don't need
+ * it.
+ */
+ protected static final int LESSER_ICOST = 0;
+
+ /**
+ * This constant is accessible by subclasses for historical
+ * purposes. If you don't know what it means then you don't need
+ * it.
+ */
+ protected static final int SMALL_THRESH = 20;
+
+ /**
+ * This constant is accessible by subclasses for historical
+ * purposes. If you don't know what it means then you don't need
+ * it.
+ */
+ protected static final int DEPTH_THRESH = 10;
+
+ /**
+ * This constant is accessible by subclasses for historical
+ * purposes. If you don't know what it means then you don't need
+ * it.
+ */
+ protected static final int WORK_FACTOR = 30;
+
+ /**
+ * This constant is accessible by subclasses for historical
+ * purposes. If you don't know what it means then you don't need
+ * it.
+ * <p> If you are ever unlucky/improbable enough to get a stack
+ * overflow whilst sorting, increase the following constant and
+ * try again. In practice I have never seen the stack go above 27
+ * elems, so the following limit seems very generous. </p>
+ */
+ protected static final int QSORT_STACK_SIZE = 1000;
+
+ /**
+ * Knuth's increments seem to work better than Incerpi-Sedgewick here.
+ * Possibly because the number of elems to sort is usually small, typically
+ * &lt;= 20.
+ */
+ private static final int[] INCS = { 1, 4, 13, 40, 121, 364, 1093, 3280,
+ 9841, 29524, 88573, 265720, 797161,
+ 2391484 };
+
+ /**
+ * This method is accessible by subclasses for historical
+ * purposes. If you don't know what it does then you don't need
+ * it.
+ */
+ protected static void hbMakeCodeLengths(char[] len, int[] freq,
+ int alphaSize, int maxLen) {
+ /*
+ * Nodes and heap entries run from 1. Entry 0 for both the heap and
+ * nodes is a sentinel.
+ */
+ final int[] heap = new int[MAX_ALPHA_SIZE * 2];
+ final int[] weight = new int[MAX_ALPHA_SIZE * 2];
+ final int[] parent = new int[MAX_ALPHA_SIZE * 2];
+
+ for (int i = alphaSize; --i >= 0;) {
+ weight[i + 1] = (freq[i] == 0 ? 1 : freq[i]) << 8;
+ }
+
+ for (boolean tooLong = true; tooLong;) {
+ tooLong = false;
+
+ int nNodes = alphaSize;
+ int nHeap = 0;
+ heap[0] = 0;
+ weight[0] = 0;
+ parent[0] = -2;
+
+ for (int i = 1; i <= alphaSize; i++) {
+ parent[i] = -1;
+ nHeap++;
+ heap[nHeap] = i;
+
+ int zz = nHeap;
+ int tmp = heap[zz];
+ while (weight[tmp] < weight[heap[zz >> 1]]) {
+ heap[zz] = heap[zz >> 1];
+ zz >>= 1;
+ }
+ heap[zz] = tmp;
+ }
+
+ // assert (nHeap < (MAX_ALPHA_SIZE + 2)) : nHeap;
+
+ while (nHeap > 1) {
+ int n1 = heap[1];
+ heap[1] = heap[nHeap];
+ nHeap--;
+
+ int yy = 0;
+ int zz = 1;
+ int tmp = heap[1];
+
+ while (true) {
+ yy = zz << 1;
+
+ if (yy > nHeap) {
+ break;
+ }
+
+ if ((yy < nHeap)
+ && (weight[heap[yy + 1]] < weight[heap[yy]])) {
+ yy++;
+ }
+
+ if (weight[tmp] < weight[heap[yy]]) {
+ break;
+ }
+
+ heap[zz] = heap[yy];
+ zz = yy;
+ }
+
+ heap[zz] = tmp;
+
+ int n2 = heap[1];
+ heap[1] = heap[nHeap];
+ nHeap--;
+
+ yy = 0;
+ zz = 1;
+ tmp = heap[1];
+
+ while (true) {
+ yy = zz << 1;
+
+ if (yy > nHeap) {
+ break;
+ }
+
+ if ((yy < nHeap)
+ && (weight[heap[yy + 1]] < weight[heap[yy]])) {
+ yy++;
+ }
+
+ if (weight[tmp] < weight[heap[yy]]) {
+ break;
+ }
+
+ heap[zz] = heap[yy];
+ zz = yy;
+ }
+
+ heap[zz] = tmp;
+ nNodes++;
+ parent[n1] = parent[n2] = nNodes;
+
+ final int weight_n1 = weight[n1];
+ final int weight_n2 = weight[n2];
+ weight[nNodes] = (((weight_n1 & 0xffffff00)
+ + (weight_n2 & 0xffffff00))
+ |
+ (1 + (((weight_n1 & 0x000000ff)
+ > (weight_n2 & 0x000000ff))
+ ? (weight_n1 & 0x000000ff)
+ : (weight_n2 & 0x000000ff))
+ ));
+
+ parent[nNodes] = -1;
+ nHeap++;
+ heap[nHeap] = nNodes;
+
+ tmp = 0;
+ zz = nHeap;
+ tmp = heap[zz];
+ final int weight_tmp = weight[tmp];
+ while (weight_tmp < weight[heap[zz >> 1]]) {
+ heap[zz] = heap[zz >> 1];
+ zz >>= 1;
+ }
+ heap[zz] = tmp;
+
+ }
+
+ // assert (nNodes < (MAX_ALPHA_SIZE * 2)) : nNodes;
+
+ for (int i = 1; i <= alphaSize; i++) {
+ int j = 0;
+ int k = i;
+
+ for (int parent_k; (parent_k = parent[k]) >= 0;) {
+ k = parent_k;
+ j++;
+ }
+
+ len[i - 1] = (char) j;
+ if (j > maxLen) {
+ tooLong = true;
+ }
+ }
+
+ if (tooLong) {
+ for (int i = 1; i < alphaSize; i++) {
+ int j = weight[i] >> 8;
+ j = 1 + (j >> 1);
+ weight[i] = j << 8;
+ }
+ }
+ }
+ }
+
+ private static void hbMakeCodeLengths(final byte[] len, final int[] freq,
+ final Data dat, final int alphaSize,
+ final int maxLen) {
+ /*
+ * Nodes and heap entries run from 1. Entry 0 for both the heap and
+ * nodes is a sentinel.
+ */
+ final int[] heap = dat.heap;
+ final int[] weight = dat.weight;
+ final int[] parent = dat.parent;
+
+ for (int i = alphaSize; --i >= 0;) {
+ weight[i + 1] = (freq[i] == 0 ? 1 : freq[i]) << 8;
+ }
+
+ for (boolean tooLong = true; tooLong;) {
+ tooLong = false;
+
+ int nNodes = alphaSize;
+ int nHeap = 0;
+ heap[0] = 0;
+ weight[0] = 0;
+ parent[0] = -2;
+
+ for (int i = 1; i <= alphaSize; i++) {
+ parent[i] = -1;
+ nHeap++;
+ heap[nHeap] = i;
+
+ int zz = nHeap;
+ int tmp = heap[zz];
+ while (weight[tmp] < weight[heap[zz >> 1]]) {
+ heap[zz] = heap[zz >> 1];
+ zz >>= 1;
+ }
+ heap[zz] = tmp;
+ }
+
+ while (nHeap > 1) {
+ int n1 = heap[1];
+ heap[1] = heap[nHeap];
+ nHeap--;
+
+ int yy = 0;
+ int zz = 1;
+ int tmp = heap[1];
+
+ while (true) {
+ yy = zz << 1;
+
+ if (yy > nHeap) {
+ break;
+ }
+
+ if ((yy < nHeap)
+ && (weight[heap[yy + 1]] < weight[heap[yy]])) {
+ yy++;
+ }
+
+ if (weight[tmp] < weight[heap[yy]]) {
+ break;
+ }
+
+ heap[zz] = heap[yy];
+ zz = yy;
+ }
+
+ heap[zz] = tmp;
+
+ int n2 = heap[1];
+ heap[1] = heap[nHeap];
+ nHeap--;
+
+ yy = 0;
+ zz = 1;
+ tmp = heap[1];
+
+ while (true) {
+ yy = zz << 1;
+
+ if (yy > nHeap) {
+ break;
+ }
+
+ if ((yy < nHeap)
+ && (weight[heap[yy + 1]] < weight[heap[yy]])) {
+ yy++;
+ }
+
+ if (weight[tmp] < weight[heap[yy]]) {
+ break;
+ }
+
+ heap[zz] = heap[yy];
+ zz = yy;
+ }
+
+ heap[zz] = tmp;
+ nNodes++;
+ parent[n1] = parent[n2] = nNodes;
+
+ final int weight_n1 = weight[n1];
+ final int weight_n2 = weight[n2];
+ weight[nNodes] = ((weight_n1 & 0xffffff00)
+ + (weight_n2 & 0xffffff00))
+ | (1 + (((weight_n1 & 0x000000ff)
+ > (weight_n2 & 0x000000ff))
+ ? (weight_n1 & 0x000000ff)
+ : (weight_n2 & 0x000000ff)));
+
+ parent[nNodes] = -1;
+ nHeap++;
+ heap[nHeap] = nNodes;
+
+ tmp = 0;
+ zz = nHeap;
+ tmp = heap[zz];
+ final int weight_tmp = weight[tmp];
+ while (weight_tmp < weight[heap[zz >> 1]]) {
+ heap[zz] = heap[zz >> 1];
+ zz >>= 1;
+ }
+ heap[zz] = tmp;
+
+ }
+
+ for (int i = 1; i <= alphaSize; i++) {
+ int j = 0;
+ int k = i;
+
+ for (int parent_k; (parent_k = parent[k]) >= 0;) {
+ k = parent_k;
+ j++;
+ }
+
+ len[i - 1] = (byte) j;
+ if (j > maxLen) {
+ tooLong = true;
+ }
+ }
+
+ if (tooLong) {
+ for (int i = 1; i < alphaSize; i++) {
+ int j = weight[i] >> 8;
+ j = 1 + (j >> 1);
+ weight[i] = j << 8;
+ }
+ }
+ }
+ }
+
+ /**
+ * Index of the last char in the block, so the block size == last + 1.
+ */
+ private int last;
+
+ /**
+ * Always: in the range 0 .. 9. The current block size is 100000 * this
+ * number.
+ */
+ private final int blockSize100k;
+
+ private int bsBuff;
+ private int bsLive;
+ private final CRC crc = new CRC();
+
+ private int nInUse;
+
+ private int nMTF;
+
+ private int currentChar = -1;
+ private int runLength = 0;
+
+ private int blockCRC;
+ private int combinedCRC;
+ private final int allowableBlockSize;
+
+ /**
+ * All memory intensive stuff.
+ */
+ private Data data;
+ private BlockSort blockSorter;
+
+ private OutputStream out;
+
+ /**
+ * Chooses a blocksize based on the given length of the data to compress.
+ *
+ * @return The blocksize, between {@link #MIN_BLOCKSIZE} and
+ * {@link #MAX_BLOCKSIZE} both inclusive. For a negative
+ * <tt>inputLength</tt> this method returns <tt>MAX_BLOCKSIZE</tt>
+ * always.
+ *
+ * @param inputLength
+ * The length of the data which will be compressed by
+ * <tt>CBZip2OutputStream</tt>.
+ */
+ public static int chooseBlockSize(long inputLength) {
+ return (inputLength > 0) ? (int) Math
+ .min((inputLength / 132000) + 1, 9) : MAX_BLOCKSIZE;
+ }
+
+ /**
+ * Constructs a new <tt>CBZip2OutputStream</tt> with a blocksize of 900k.
+ *
+ * <p>
+ * <b>Attention: </b>The caller is responsible to write the two BZip2 magic
+ * bytes <tt>"BZ"</tt> to the specified stream prior to calling this
+ * constructor.
+ * </p>
+ *
+ * @param out *
+ * the destination stream.
+ *
+ * @throws IOException
+ * if an I/O error occurs in the specified stream.
+ * @throws NullPointerException
+ * if <code>out == null</code>.
+ */
+ public CBZip2OutputStream(final OutputStream out) throws IOException {
+ this(out, MAX_BLOCKSIZE);
+ }
+
+ /**
+ * Constructs a new <tt>CBZip2OutputStream</tt> with specified blocksize.
+ *
+ * <p>
+ * <b>Attention: </b>The caller is responsible to write the two BZip2 magic
+ * bytes <tt>"BZ"</tt> to the specified stream prior to calling this
+ * constructor.
+ * </p>
+ *
+ *
+ * @param out
+ * the destination stream.
+ * @param blockSize
+ * the blockSize as 100k units.
+ *
+ * @throws IOException
+ * if an I/O error occurs in the specified stream.
+ * @throws IllegalArgumentException
+ * if <code>(blockSize &lt; 1) || (blockSize &gt; 9)</code>.
+ * @throws NullPointerException
+ * if <code>out == null</code>.
+ *
+ * @see #MIN_BLOCKSIZE
+ * @see #MAX_BLOCKSIZE
+ */
+ public CBZip2OutputStream(final OutputStream out, final int blockSize)
+ throws IOException {
+ super();
+
+ if (blockSize < 1) {
+ throw new IllegalArgumentException("blockSize(" + blockSize
+ + ") < 1");
+ }
+ if (blockSize > 9) {
+ throw new IllegalArgumentException("blockSize(" + blockSize
+ + ") > 9");
+ }
+
+ this.blockSize100k = blockSize;
+ this.out = out;
+
+ /* 20 is just a paranoia constant */
+ this.allowableBlockSize = (this.blockSize100k * BZip2Constants.baseBlockSize) - 20;
+ init();
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void write(final int b) throws IOException {
+ if (this.out != null) {
+ write0(b);
+ } else {
+ throw new IOException("closed");
+ }
+ }
+
+ /**
+ * Writes the current byte to the buffer, run-length encoding it
+ * if it has been repeated at least four times (the first step
+ * RLEs sequences of four identical bytes).
+ *
+ * <p>Flushes the current block before writing data if it is
+ * full.</p>
+ *
+ * <p>"write to the buffer" means adding to data.buffer starting
+ * two steps "after" this.last - initially starting at index 1
+ * (not 0) - and updating this.last to point to the last index
+ * written minus 1.</p>
+ */
+ private void writeRun() throws IOException {
+ final int lastShadow = this.last;
+
+ if (lastShadow < this.allowableBlockSize) {
+ final int currentCharShadow = this.currentChar;
+ final Data dataShadow = this.data;
+ dataShadow.inUse[currentCharShadow] = true;
+ final byte ch = (byte) currentCharShadow;
+
+ int runLengthShadow = this.runLength;
+ this.crc.updateCRC(currentCharShadow, runLengthShadow);
+
+ switch (runLengthShadow) {
+ case 1:
+ dataShadow.block[lastShadow + 2] = ch;
+ this.last = lastShadow + 1;
+ break;
+
+ case 2:
+ dataShadow.block[lastShadow + 2] = ch;
+ dataShadow.block[lastShadow + 3] = ch;
+ this.last = lastShadow + 2;
+ break;
+
+ case 3: {
+ final byte[] block = dataShadow.block;
+ block[lastShadow + 2] = ch;
+ block[lastShadow + 3] = ch;
+ block[lastShadow + 4] = ch;
+ this.last = lastShadow + 3;
+ }
+ break;
+
+ default: {
+ runLengthShadow -= 4;
+ dataShadow.inUse[runLengthShadow] = true;
+ final byte[] block = dataShadow.block;
+ block[lastShadow + 2] = ch;
+ block[lastShadow + 3] = ch;
+ block[lastShadow + 4] = ch;
+ block[lastShadow + 5] = ch;
+ block[lastShadow + 6] = (byte) runLengthShadow;
+ this.last = lastShadow + 5;
+ }
+ break;
+
+ }
+ } else {
+ endBlock();
+ initBlock();
+ writeRun();
+ }
+ }
+
+ /**
+ * Overridden to close the stream.
+ */
+ @Override
+ protected void finalize() throws Throwable {
+ finish();
+ super.finalize();
+ }
+
+
+ public void finish() throws IOException {
+ if (out != null) {
+ try {
+ if (this.runLength > 0) {
+ writeRun();
+ }
+ this.currentChar = -1;
+ endBlock();
+ endCompression();
+ } finally {
+ this.out = null;
+ this.data = null;
+ this.blockSorter = null;
+ }
+ }
+ }
+
+ @Override
+ public void close() throws IOException {
+ if (out != null) {
+ OutputStream outShadow = this.out;
+ finish();
+ outShadow.close();
+ }
+ }
+
+ @Override
+ public void flush() throws IOException {
+ OutputStream outShadow = this.out;
+ if (outShadow != null) {
+ outShadow.flush();
+ }
+ }
+
+ private void init() throws IOException {
+ // write magic: done by caller who created this stream
+ // this.out.write('B');
+ // this.out.write('Z');
+
+ this.data = new Data(this.blockSize100k);
+ this.blockSorter = new BlockSort(this.data);
+
+ /*
+ * Write `magic' bytes h indicating file-format == huffmanised, followed
+ * by a digit indicating blockSize100k.
+ */
+ bsPutUByte('h');
+ bsPutUByte('0' + this.blockSize100k);
+
+ this.combinedCRC = 0;
+ initBlock();
+ }
+
+ private void initBlock() {
+ // blockNo++;
+ this.crc.initialiseCRC();
+ this.last = -1;
+ // ch = 0;
+
+ boolean[] inUse = this.data.inUse;
+ for (int i = 256; --i >= 0;) {
+ inUse[i] = false;
+ }
+ }
+
+ private void endBlock() throws IOException {
+ this.blockCRC = this.crc.getFinalCRC();
+ this.combinedCRC = (this.combinedCRC << 1) | (this.combinedCRC >>> 31);
+ this.combinedCRC ^= this.blockCRC;
+
+ // empty block at end of file
+ if (this.last == -1) {
+ return;
+ }
+
+ /* sort the block and establish posn of original string */
+ blockSort();
+
+ /*
+ * A 6-byte block header, the value chosen arbitrarily as 0x314159265359
+ * :-). A 32 bit value does not really give a strong enough guarantee
+ * that the value will not appear by chance in the compressed
+ * datastream. Worst-case probability of this event, for a 900k block,
+ * is about 2.0e-3 for 32 bits, 1.0e-5 for 40 bits and 4.0e-8 for 48
+ * bits. For a compressed file of size 100Gb -- about 100000 blocks --
+ * only a 48-bit marker will do. NB: normal compression/ decompression
+ * donot rely on these statistical properties. They are only important
+ * when trying to recover blocks from damaged files.
+ */
+ bsPutUByte(0x31);
+ bsPutUByte(0x41);
+ bsPutUByte(0x59);
+ bsPutUByte(0x26);
+ bsPutUByte(0x53);
+ bsPutUByte(0x59);
+
+ /* Now the block's CRC, so it is in a known place. */
+ bsPutInt(this.blockCRC);
+
+ /* Now a single bit indicating no randomisation. */
+ bsW(1, 0);
+
+ /* Finally, block's contents proper. */
+ moveToFrontCodeAndSend();
+ }
+
+ private void endCompression() throws IOException {
+ /*
+ * Now another magic 48-bit number, 0x177245385090, to indicate the end
+ * of the last block. (sqrt(pi), if you want to know. I did want to use
+ * e, but it contains too much repetition -- 27 18 28 18 28 46 -- for me
+ * to feel statistically comfortable. Call me paranoid.)
+ */
+ bsPutUByte(0x17);
+ bsPutUByte(0x72);
+ bsPutUByte(0x45);
+ bsPutUByte(0x38);
+ bsPutUByte(0x50);
+ bsPutUByte(0x90);
+
+ bsPutInt(this.combinedCRC);
+ bsFinishedWithStream();
+ }
+
+ /**
+ * Returns the blocksize parameter specified at construction time.
+ */
+ public final int getBlockSize() {
+ return this.blockSize100k;
+ }
+
+ @Override
+ public void write(final byte[] buf, int offs, final int len)
+ throws IOException {
+ if (offs < 0) {
+ throw new IndexOutOfBoundsException("offs(" + offs + ") < 0.");
+ }
+ if (len < 0) {
+ throw new IndexOutOfBoundsException("len(" + len + ") < 0.");
+ }
+ if (offs + len > buf.length) {
+ throw new IndexOutOfBoundsException("offs(" + offs + ") + len("
+ + len + ") > buf.length("
+ + buf.length + ").");
+ }
+ if (this.out == null) {
+ throw new IOException("stream closed");
+ }
+
+ for (int hi = offs + len; offs < hi;) {
+ write0(buf[offs++]);
+ }
+ }
+
+ /**
+ * Keeps track of the last bytes written and implicitly performs
+ * run-length encoding as the first step of the bzip2 algorithm.
+ */
+ private void write0(int b) throws IOException {
+ if (this.currentChar != -1) {
+ b &= 0xff;
+ if (this.currentChar == b) {
+ if (++this.runLength > 254) {
+ writeRun();
+ this.currentChar = -1;
+ this.runLength = 0;
+ }
+ // else nothing to do
+ } else {
+ writeRun();
+ this.runLength = 1;
+ this.currentChar = b;
+ }
+ } else {
+ this.currentChar = b & 0xff;
+ this.runLength++;
+ }
+ }
+
+ private static void hbAssignCodes(final int[] code, final byte[] length,
+ final int minLen, final int maxLen,
+ final int alphaSize) {
+ int vec = 0;
+ for (int n = minLen; n <= maxLen; n++) {
+ for (int i = 0; i < alphaSize; i++) {
+ if ((length[i] & 0xff) == n) {
+ code[i] = vec;
+ vec++;
+ }
+ }
+ vec <<= 1;
+ }
+ }
+
+ private void bsFinishedWithStream() throws IOException {
+ while (this.bsLive > 0) {
+ int ch = this.bsBuff >> 24;
+ this.out.write(ch); // write 8-bit
+ this.bsBuff <<= 8;
+ this.bsLive -= 8;
+ }
+ }
+
+ private void bsW(final int n, final int v) throws IOException {
+ final OutputStream outShadow = this.out;
+ int bsLiveShadow = this.bsLive;
+ int bsBuffShadow = this.bsBuff;
+
+ while (bsLiveShadow >= 8) {
+ outShadow.write(bsBuffShadow >> 24); // write 8-bit
+ bsBuffShadow <<= 8;
+ bsLiveShadow -= 8;
+ }
+
+ this.bsBuff = bsBuffShadow | (v << (32 - bsLiveShadow - n));
+ this.bsLive = bsLiveShadow + n;
+ }
+
+ private void bsPutUByte(final int c) throws IOException {
+ bsW(8, c);
+ }
+
+ private void bsPutInt(final int u) throws IOException {
+ bsW(8, (u >> 24) & 0xff);
+ bsW(8, (u >> 16) & 0xff);
+ bsW(8, (u >> 8) & 0xff);
+ bsW(8, u & 0xff);
+ }
+
+ private void sendMTFValues() throws IOException {
+ final byte[][] len = this.data.sendMTFValues_len;
+ final int alphaSize = this.nInUse + 2;
+
+ for (int t = N_GROUPS; --t >= 0;) {
+ byte[] len_t = len[t];
+ for (int v = alphaSize; --v >= 0;) {
+ len_t[v] = GREATER_ICOST;
+ }
+ }
+
+ /* Decide how many coding tables to use */
+ // assert (this.nMTF > 0) : this.nMTF;
+ final int nGroups = (this.nMTF < 200) ? 2 : (this.nMTF < 600) ? 3
+ : (this.nMTF < 1200) ? 4 : (this.nMTF < 2400) ? 5 : 6;
+
+ /* Generate an initial set of coding tables */
+ sendMTFValues0(nGroups, alphaSize);
+
+ /*
+ * Iterate up to N_ITERS times to improve the tables.
+ */
+ final int nSelectors = sendMTFValues1(nGroups, alphaSize);
+
+ /* Compute MTF values for the selectors. */
+ sendMTFValues2(nGroups, nSelectors);
+
+ /* Assign actual codes for the tables. */
+ sendMTFValues3(nGroups, alphaSize);
+
+ /* Transmit the mapping table. */
+ sendMTFValues4();
+
+ /* Now the selectors. */
+ sendMTFValues5(nGroups, nSelectors);
+
+ /* Now the coding tables. */
+ sendMTFValues6(nGroups, alphaSize);
+
+ /* And finally, the block data proper */
+ sendMTFValues7();
+ }
+
+ private void sendMTFValues0(final int nGroups, final int alphaSize) {
+ final byte[][] len = this.data.sendMTFValues_len;
+ final int[] mtfFreq = this.data.mtfFreq;
+
+ int remF = this.nMTF;
+ int gs = 0;
+
+ for (int nPart = nGroups; nPart > 0; nPart--) {
+ final int tFreq = remF / nPart;
+ int ge = gs - 1;
+ int aFreq = 0;
+
+ for (final int a = alphaSize - 1; (aFreq < tFreq) && (ge < a);) {
+ aFreq += mtfFreq[++ge];
+ }
+
+ if ((ge > gs) && (nPart != nGroups) && (nPart != 1)
+ && (((nGroups - nPart) & 1) != 0)) {
+ aFreq -= mtfFreq[ge--];
+ }
+
+ final byte[] len_np = len[nPart - 1];
+ for (int v = alphaSize; --v >= 0;) {
+ if ((v >= gs) && (v <= ge)) {
+ len_np[v] = LESSER_ICOST;
+ } else {
+ len_np[v] = GREATER_ICOST;
+ }
+ }
+
+ gs = ge + 1;
+ remF -= aFreq;
+ }
+ }
+
+ private int sendMTFValues1(final int nGroups, final int alphaSize) {
+ final Data dataShadow = this.data;
+ final int[][] rfreq = dataShadow.sendMTFValues_rfreq;
+ final int[] fave = dataShadow.sendMTFValues_fave;
+ final short[] cost = dataShadow.sendMTFValues_cost;
+ final char[] sfmap = dataShadow.sfmap;
+ final byte[] selector = dataShadow.selector;
+ final byte[][] len = dataShadow.sendMTFValues_len;
+ final byte[] len_0 = len[0];
+ final byte[] len_1 = len[1];
+ final byte[] len_2 = len[2];
+ final byte[] len_3 = len[3];
+ final byte[] len_4 = len[4];
+ final byte[] len_5 = len[5];
+ final int nMTFShadow = this.nMTF;
+
+ int nSelectors = 0;
+
+ for (int iter = 0; iter < N_ITERS; iter++) {
+ for (int t = nGroups; --t >= 0;) {
+ fave[t] = 0;
+ int[] rfreqt = rfreq[t];
+ for (int i = alphaSize; --i >= 0;) {
+ rfreqt[i] = 0;
+ }
+ }
+
+ nSelectors = 0;
+
+ for (int gs = 0; gs < this.nMTF;) {
+ /* Set group start & end marks. */
+
+ /*
+ * Calculate the cost of this group as coded by each of the
+ * coding tables.
+ */
+
+ final int ge = Math.min(gs + G_SIZE - 1, nMTFShadow - 1);
+
+ if (nGroups == N_GROUPS) {
+ // unrolled version of the else-block
+
+ short cost0 = 0;
+ short cost1 = 0;
+ short cost2 = 0;
+ short cost3 = 0;
+ short cost4 = 0;
+ short cost5 = 0;
+
+ for (int i = gs; i <= ge; i++) {
+ final int icv = sfmap[i];
+ cost0 += len_0[icv] & 0xff;
+ cost1 += len_1[icv] & 0xff;
+ cost2 += len_2[icv] & 0xff;
+ cost3 += len_3[icv] & 0xff;
+ cost4 += len_4[icv] & 0xff;
+ cost5 += len_5[icv] & 0xff;
+ }
+
+ cost[0] = cost0;
+ cost[1] = cost1;
+ cost[2] = cost2;
+ cost[3] = cost3;
+ cost[4] = cost4;
+ cost[5] = cost5;
+
+ } else {
+ for (int t = nGroups; --t >= 0;) {
+ cost[t] = 0;
+ }
+
+ for (int i = gs; i <= ge; i++) {
+ final int icv = sfmap[i];
+ for (int t = nGroups; --t >= 0;) {
+ cost[t] += len[t][icv] & 0xff;
+ }
+ }
+ }
+
+ /*
+ * Find the coding table which is best for this group, and
+ * record its identity in the selector table.
+ */
+ int bt = -1;
+ for (int t = nGroups, bc = 999999999; --t >= 0;) {
+ final int cost_t = cost[t];
+ if (cost_t < bc) {
+ bc = cost_t;
+ bt = t;
+ }
+ }
+
+ fave[bt]++;
+ selector[nSelectors] = (byte) bt;
+ nSelectors++;
+
+ /*
+ * Increment the symbol frequencies for the selected table.
+ */
+ final int[] rfreq_bt = rfreq[bt];
+ for (int i = gs; i <= ge; i++) {
+ rfreq_bt[sfmap[i]]++;
+ }
+
+ gs = ge + 1;
+ }
+
+ /*
+ * Recompute the tables based on the accumulated frequencies.
+ */
+ for (int t = 0; t < nGroups; t++) {
+ hbMakeCodeLengths(len[t], rfreq[t], this.data, alphaSize, 20);
+ }
+ }
+
+ return nSelectors;
+ }
+
+ private void sendMTFValues2(final int nGroups, final int nSelectors) {
+ // assert (nGroups < 8) : nGroups;
+
+ final Data dataShadow = this.data;
+ byte[] pos = dataShadow.sendMTFValues2_pos;
+
+ for (int i = nGroups; --i >= 0;) {
+ pos[i] = (byte) i;
+ }
+
+ for (int i = 0; i < nSelectors; i++) {
+ final byte ll_i = dataShadow.selector[i];
+ byte tmp = pos[0];
+ int j = 0;
+
+ while (ll_i != tmp) {
+ j++;
+ byte tmp2 = tmp;
+ tmp = pos[j];
+ pos[j] = tmp2;
+ }
+
+ pos[0] = tmp;
+ dataShadow.selectorMtf[i] = (byte) j;
+ }
+ }
+
+ private void sendMTFValues3(final int nGroups, final int alphaSize) {
+ int[][] code = this.data.sendMTFValues_code;
+ byte[][] len = this.data.sendMTFValues_len;
+
+ for (int t = 0; t < nGroups; t++) {
+ int minLen = 32;
+ int maxLen = 0;
+ final byte[] len_t = len[t];
+ for (int i = alphaSize; --i >= 0;) {
+ final int l = len_t[i] & 0xff;
+ if (l > maxLen) {
+ maxLen = l;
+ }
+ if (l < minLen) {
+ minLen = l;
+ }
+ }
+
+ // assert (maxLen <= 20) : maxLen;
+ // assert (minLen >= 1) : minLen;
+
+ hbAssignCodes(code[t], len[t], minLen, maxLen, alphaSize);
+ }
+ }
+
+ private void sendMTFValues4() throws IOException {
+ final boolean[] inUse = this.data.inUse;
+ final boolean[] inUse16 = this.data.sentMTFValues4_inUse16;
+
+ for (int i = 16; --i >= 0;) {
+ inUse16[i] = false;
+ final int i16 = i * 16;
+ for (int j = 16; --j >= 0;) {
+ if (inUse[i16 + j]) {
+ inUse16[i] = true;
+ }
+ }
+ }
+
+ for (int i = 0; i < 16; i++) {
+ bsW(1, inUse16[i] ? 1 : 0);
+ }
+
+ final OutputStream outShadow = this.out;
+ int bsLiveShadow = this.bsLive;
+ int bsBuffShadow = this.bsBuff;
+
+ for (int i = 0; i < 16; i++) {
+ if (inUse16[i]) {
+ final int i16 = i * 16;
+ for (int j = 0; j < 16; j++) {
+ // inlined: bsW(1, inUse[i16 + j] ? 1 : 0);
+ while (bsLiveShadow >= 8) {
+ outShadow.write(bsBuffShadow >> 24); // write 8-bit
+ bsBuffShadow <<= 8;
+ bsLiveShadow -= 8;
+ }
+ if (inUse[i16 + j]) {
+ bsBuffShadow |= 1 << (32 - bsLiveShadow - 1);
+ }
+ bsLiveShadow++;
+ }
+ }
+ }
+
+ this.bsBuff = bsBuffShadow;
+ this.bsLive = bsLiveShadow;
+ }
+
+ private void sendMTFValues5(final int nGroups, final int nSelectors)
+ throws IOException {
+ bsW(3, nGroups);
+ bsW(15, nSelectors);
+
+ final OutputStream outShadow = this.out;
+ final byte[] selectorMtf = this.data.selectorMtf;
+
+ int bsLiveShadow = this.bsLive;
+ int bsBuffShadow = this.bsBuff;
+
+ for (int i = 0; i < nSelectors; i++) {
+ for (int j = 0, hj = selectorMtf[i] & 0xff; j < hj; j++) {
+ // inlined: bsW(1, 1);
+ while (bsLiveShadow >= 8) {
+ outShadow.write(bsBuffShadow >> 24);
+ bsBuffShadow <<= 8;
+ bsLiveShadow -= 8;
+ }
+ bsBuffShadow |= 1 << (32 - bsLiveShadow - 1);
+ bsLiveShadow++;
+ }
+
+ // inlined: bsW(1, 0);
+ while (bsLiveShadow >= 8) {
+ outShadow.write(bsBuffShadow >> 24);
+ bsBuffShadow <<= 8;
+ bsLiveShadow -= 8;
+ }
+ // bsBuffShadow |= 0 << (32 - bsLiveShadow - 1);
+ bsLiveShadow++;
+ }
+
+ this.bsBuff = bsBuffShadow;
+ this.bsLive = bsLiveShadow;
+ }
+
+ private void sendMTFValues6(final int nGroups, final int alphaSize)
+ throws IOException {
+ final byte[][] len = this.data.sendMTFValues_len;
+ final OutputStream outShadow = this.out;
+
+ int bsLiveShadow = this.bsLive;
+ int bsBuffShadow = this.bsBuff;
+
+ for (int t = 0; t < nGroups; t++) {
+ byte[] len_t = len[t];
+ int curr = len_t[0] & 0xff;
+
+ // inlined: bsW(5, curr);
+ while (bsLiveShadow >= 8) {
+ outShadow.write(bsBuffShadow >> 24); // write 8-bit
+ bsBuffShadow <<= 8;
+ bsLiveShadow -= 8;
+ }
+ bsBuffShadow |= curr << (32 - bsLiveShadow - 5);
+ bsLiveShadow += 5;
+
+ for (int i = 0; i < alphaSize; i++) {
+ int lti = len_t[i] & 0xff;
+ while (curr < lti) {
+ // inlined: bsW(2, 2);
+ while (bsLiveShadow >= 8) {
+ outShadow.write(bsBuffShadow >> 24); // write 8-bit
+ bsBuffShadow <<= 8;
+ bsLiveShadow -= 8;
+ }
+ bsBuffShadow |= 2 << (32 - bsLiveShadow - 2);
+ bsLiveShadow += 2;
+
+ curr++; /* 10 */
+ }
+
+ while (curr > lti) {
+ // inlined: bsW(2, 3);
+ while (bsLiveShadow >= 8) {
+ outShadow.write(bsBuffShadow >> 24); // write 8-bit
+ bsBuffShadow <<= 8;
+ bsLiveShadow -= 8;
+ }
+ bsBuffShadow |= 3 << (32 - bsLiveShadow - 2);
+ bsLiveShadow += 2;
+
+ curr--; /* 11 */
+ }
+
+ // inlined: bsW(1, 0);
+ while (bsLiveShadow >= 8) {
+ outShadow.write(bsBuffShadow >> 24); // write 8-bit
+ bsBuffShadow <<= 8;
+ bsLiveShadow -= 8;
+ }
+ // bsBuffShadow |= 0 << (32 - bsLiveShadow - 1);
+ bsLiveShadow++;
+ }
+ }
+
+ this.bsBuff = bsBuffShadow;
+ this.bsLive = bsLiveShadow;
+ }
+
+ private void sendMTFValues7() throws IOException {
+ final Data dataShadow = this.data;
+ final byte[][] len = dataShadow.sendMTFValues_len;
+ final int[][] code = dataShadow.sendMTFValues_code;
+ final OutputStream outShadow = this.out;
+ final byte[] selector = dataShadow.selector;
+ final char[] sfmap = dataShadow.sfmap;
+ final int nMTFShadow = this.nMTF;
+
+ int selCtr = 0;
+
+ int bsLiveShadow = this.bsLive;
+ int bsBuffShadow = this.bsBuff;
+
+ for (int gs = 0; gs < nMTFShadow;) {
+ final int ge = Math.min(gs + G_SIZE - 1, nMTFShadow - 1);
+ final int selector_selCtr = selector[selCtr] & 0xff;
+ final int[] code_selCtr = code[selector_selCtr];
+ final byte[] len_selCtr = len[selector_selCtr];
+
+ while (gs <= ge) {
+ final int sfmap_i = sfmap[gs];
+
+ //
+ // inlined: bsW(len_selCtr[sfmap_i] & 0xff,
+ // code_selCtr[sfmap_i]);
+ //
+ while (bsLiveShadow >= 8) {
+ outShadow.write(bsBuffShadow >> 24);
+ bsBuffShadow <<= 8;
+ bsLiveShadow -= 8;
+ }
+ final int n = len_selCtr[sfmap_i] & 0xFF;
+ bsBuffShadow |= code_selCtr[sfmap_i] << (32 - bsLiveShadow - n);
+ bsLiveShadow += n;
+
+ gs++;
+ }
+
+ gs = ge + 1;
+ selCtr++;
+ }
+
+ this.bsBuff = bsBuffShadow;
+ this.bsLive = bsLiveShadow;
+ }
+
+ private void moveToFrontCodeAndSend() throws IOException {
+ bsW(24, this.data.origPtr);
+ generateMTFValues();
+ sendMTFValues();
+ }
+
+ private void blockSort() {
+ blockSorter.blockSort(data, last);
+ }
+
+ /*
+ * Performs Move-To-Front on the Burrows-Wheeler transformed
+ * buffer, storing the MTFed data in data.sfmap in RUNA/RUNB
+ * run-length-encoded form.
+ *
+ * <p>Keeps track of byte frequencies in data.mtfFreq at the same time.</p>
+ */
+ private void generateMTFValues() {
+ final int lastShadow = this.last;
+ final Data dataShadow = this.data;
+ final boolean[] inUse = dataShadow.inUse;
+ final byte[] block = dataShadow.block;
+ final int[] fmap = dataShadow.fmap;
+ final char[] sfmap = dataShadow.sfmap;
+ final int[] mtfFreq = dataShadow.mtfFreq;
+ final byte[] unseqToSeq = dataShadow.unseqToSeq;
+ final byte[] yy = dataShadow.generateMTFValues_yy;
+
+ // make maps
+ int nInUseShadow = 0;
+ for (int i = 0; i < 256; i++) {
+ if (inUse[i]) {
+ unseqToSeq[i] = (byte) nInUseShadow;
+ nInUseShadow++;
+ }
+ }
+ this.nInUse = nInUseShadow;
+
+ final int eob = nInUseShadow + 1;
+
+ for (int i = eob; i >= 0; i--) {
+ mtfFreq[i] = 0;
+ }
+
+ for (int i = nInUseShadow; --i >= 0;) {
+ yy[i] = (byte) i;
+ }
+
+ int wr = 0;
+ int zPend = 0;
+
+ for (int i = 0; i <= lastShadow; i++) {
+ final byte ll_i = unseqToSeq[block[fmap[i]] & 0xff];
+ byte tmp = yy[0];
+ int j = 0;
+
+ while (ll_i != tmp) {
+ j++;
+ byte tmp2 = tmp;
+ tmp = yy[j];
+ yy[j] = tmp2;
+ }
+ yy[0] = tmp;
+
+ if (j == 0) {
+ zPend++;
+ } else {
+ if (zPend > 0) {
+ zPend--;
+ while (true) {
+ if ((zPend & 1) == 0) {
+ sfmap[wr] = RUNA;
+ wr++;
+ mtfFreq[RUNA]++;
+ } else {
+ sfmap[wr] = RUNB;
+ wr++;
+ mtfFreq[RUNB]++;
+ }
+
+ if (zPend >= 2) {
+ zPend = (zPend - 2) >> 1;
+ } else {
+ break;
+ }
+ }
+ zPend = 0;
+ }
+ sfmap[wr] = (char) (j + 1);
+ wr++;
+ mtfFreq[j + 1]++;
+ }
+ }
+
+ if (zPend > 0) {
+ zPend--;
+ while (true) {
+ if ((zPend & 1) == 0) {
+ sfmap[wr] = RUNA;
+ wr++;
+ mtfFreq[RUNA]++;
+ } else {
+ sfmap[wr] = RUNB;
+ wr++;
+ mtfFreq[RUNB]++;
+ }
+
+ if (zPend >= 2) {
+ zPend = (zPend - 2) >> 1;
+ } else {
+ break;
+ }
+ }
+ }
+
+ sfmap[wr] = (char) eob;
+ mtfFreq[eob]++;
+ this.nMTF = wr + 1;
+ }
+
+ static final class Data extends Object {
+
+ // with blockSize 900k
+ /* maps unsigned byte => "does it occur in block" */
+ final boolean[] inUse = new boolean[256]; // 256 byte
+ final byte[] unseqToSeq = new byte[256]; // 256 byte
+ final int[] mtfFreq = new int[MAX_ALPHA_SIZE]; // 1032 byte
+ final byte[] selector = new byte[MAX_SELECTORS]; // 18002 byte
+ final byte[] selectorMtf = new byte[MAX_SELECTORS]; // 18002 byte
+
+ final byte[] generateMTFValues_yy = new byte[256]; // 256 byte
+ final byte[][] sendMTFValues_len = new byte[N_GROUPS][MAX_ALPHA_SIZE]; // 1548
+ // byte
+ final int[][] sendMTFValues_rfreq = new int[N_GROUPS][MAX_ALPHA_SIZE]; // 6192
+ // byte
+ final int[] sendMTFValues_fave = new int[N_GROUPS]; // 24 byte
+ final short[] sendMTFValues_cost = new short[N_GROUPS]; // 12 byte
+ final int[][] sendMTFValues_code = new int[N_GROUPS][MAX_ALPHA_SIZE]; // 6192
+ // byte
+ final byte[] sendMTFValues2_pos = new byte[N_GROUPS]; // 6 byte
+ final boolean[] sentMTFValues4_inUse16 = new boolean[16]; // 16 byte
+
+ final int[] heap = new int[MAX_ALPHA_SIZE + 2]; // 1040 byte
+ final int[] weight = new int[MAX_ALPHA_SIZE * 2]; // 2064 byte
+ final int[] parent = new int[MAX_ALPHA_SIZE * 2]; // 2064 byte
+
+ // ------------
+ // 333408 byte
+
+ /* holds the RLEd block of original data starting at index 1.
+ * After sorting the last byte added to the buffer is at index
+ * 0. */
+ final byte[] block; // 900021 byte
+ /* maps index in Burrows-Wheeler transformed block => index of
+ * byte in original block */
+ final int[] fmap; // 3600000 byte
+ final char[] sfmap; // 3600000 byte
+ // ------------
+ // 8433529 byte
+ // ============
+
+ /**
+ * Index of original line in Burrows-Wheeler table.
+ *
+ * <p>This is the index in fmap that points to the last byte
+ * of the original data.</p>
+ */
+ int origPtr;
+
+ Data(int blockSize100k) {
+ super();
+
+ final int n = blockSize100k * BZip2Constants.baseBlockSize;
+ this.block = new byte[(n + 1 + NUM_OVERSHOOT_BYTES)];
+ this.fmap = new int[n];
+ this.sfmap = new char[2 * n];
+ }
+
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/bzip2/CRC.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/bzip2/CRC.java
new file mode 100644
index 00000000..0102c8e3
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/bzip2/CRC.java
@@ -0,0 +1,141 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+/*
+ * This package is based on the work done by Keiron Liddle, Aftex Software
+ * <keiron@aftexsw.com> to whom the Ant project is very grateful for his
+ * great code.
+ */
+
+package org.apache.tools.bzip2;
+
+/**
+ * A simple class the hold and calculate the CRC for sanity checking
+ * of the data.
+ *
+ */
+final class CRC {
+ static final int crc32Table[] = {
+ 0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9,
+ 0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005,
+ 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
+ 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd,
+ 0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9,
+ 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
+ 0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011,
+ 0x791d4014, 0x7ddc5da3, 0x709f7b7a, 0x745e66cd,
+ 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
+ 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5,
+ 0xbe2b5b58, 0xbaea46ef, 0xb7a96036, 0xb3687d81,
+ 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
+ 0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49,
+ 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
+ 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,
+ 0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d,
+ 0x34867077, 0x30476dc0, 0x3d044b19, 0x39c556ae,
+ 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
+ 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16,
+ 0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca,
+ 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,
+ 0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02,
+ 0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, 0x53dc6066,
+ 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
+ 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e,
+ 0xbfa1b04b, 0xbb60adfc, 0xb6238b25, 0xb2e29692,
+ 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
+ 0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a,
+ 0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e,
+ 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
+ 0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686,
+ 0xd5b88683, 0xd1799b34, 0xdc3abded, 0xd8fba05a,
+ 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,
+ 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb,
+ 0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f,
+ 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
+ 0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47,
+ 0x36194d42, 0x32d850f5, 0x3f9b762c, 0x3b5a6b9b,
+ 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
+ 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623,
+ 0xf12f560e, 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7,
+ 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
+ 0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f,
+ 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
+ 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,
+ 0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b,
+ 0x9b3660c6, 0x9ff77d71, 0x92b45ba8, 0x9675461f,
+ 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
+ 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640,
+ 0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c,
+ 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,
+ 0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24,
+ 0x119b4be9, 0x155a565e, 0x18197087, 0x1cd86d30,
+ 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
+ 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088,
+ 0x2497d08d, 0x2056cd3a, 0x2d15ebe3, 0x29d4f654,
+ 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,
+ 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c,
+ 0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18,
+ 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
+ 0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0,
+ 0x9abc8bd5, 0x9e7d9662, 0x933eb0bb, 0x97ffad0c,
+ 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
+ 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
+ };
+
+ CRC() {
+ initialiseCRC();
+ }
+
+ void initialiseCRC() {
+ globalCrc = 0xffffffff;
+ }
+
+ int getFinalCRC() {
+ return ~globalCrc;
+ }
+
+ int getGlobalCRC() {
+ return globalCrc;
+ }
+
+ void setGlobalCRC(int newCrc) {
+ globalCrc = newCrc;
+ }
+
+ void updateCRC(int inCh) {
+ int temp = (globalCrc >> 24) ^ inCh;
+ if (temp < 0) {
+ temp = 256 + temp;
+ }
+ globalCrc = (globalCrc << 8) ^ CRC.crc32Table[temp];
+ }
+
+ void updateCRC(int inCh, int repeat) {
+ int globalCrcShadow = this.globalCrc;
+ while (repeat-- > 0) {
+ int temp = (globalCrcShadow >> 24) ^ inCh;
+ globalCrcShadow = (globalCrcShadow << 8) ^ crc32Table[(temp >= 0)
+ ? temp
+ : (temp + 256)];
+ }
+ this.globalCrc = globalCrcShadow;
+ }
+
+ int globalCrc;
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/mail/ErrorInQuitException.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/mail/ErrorInQuitException.java
new file mode 100644
index 00000000..6f78a142
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/mail/ErrorInQuitException.java
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.mail;
+
+import java.io.IOException;
+
+/**
+ * Specialized IOException that get thrown if SMTP's QUIT command fails.
+ *
+ * <p>This seems to happen with some version of MS Exchange that
+ * doesn't respond with a 221 code immediately. See <a
+ * href="http://nagoya.apache.org/bugzilla/show_bug.cgi?id=5273">Bug
+ * report 5273</a>.</p>
+ *
+ */
+public class ErrorInQuitException extends IOException {
+
+ /**
+ * Initialise from an IOException
+ *
+ * @param e the IO Exception.
+ */
+ public ErrorInQuitException(IOException e) {
+ super(e.getMessage());
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/mail/MailMessage.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/mail/MailMessage.java
new file mode 100644
index 00000000..b4173a96
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/mail/MailMessage.java
@@ -0,0 +1,526 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+/*
+ * The original version of this class was donated by Jason Hunter,
+ * who wrote the class as part of the com.oreilly.servlet
+ * package for his book "Java Servlet Programming" (O'Reilly).
+ * See http://www.servlets.com.
+ *
+ */
+
+package org.apache.tools.mail;
+
+import java.io.BufferedOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.util.Enumeration;
+import java.util.Vector;
+
+/**
+ * A class to help send SMTP email.
+ * This class is an improvement on the sun.net.smtp.SmtpClient class
+ * found in the JDK. This version has extra functionality, and can be used
+ * with JVMs that did not extend from the JDK. It's not as robust as
+ * the JavaMail Standard Extension classes, but it's easier to use and
+ * easier to install, and has an Open Source license.
+ * <p>
+ * It can be used like this:
+ * <blockquote><pre>
+ * String mailhost = "localhost"; // or another mail host
+ * String from = "Mail Message Servlet &lt;MailMessage@server.com&gt;";
+ * String to = "to@you.com";
+ * String cc1 = "cc1@you.com";
+ * String cc2 = "cc2@you.com";
+ * String bcc = "bcc@you.com";
+ * &nbsp;
+ * MailMessage msg = new MailMessage(mailhost);
+ * msg.setPort(25);
+ * msg.from(from);
+ * msg.to(to);
+ * msg.cc(cc1);
+ * msg.cc(cc2);
+ * msg.bcc(bcc);
+ * msg.setSubject("Test subject");
+ * PrintStream out = msg.getPrintStream();
+ * &nbsp;
+ * Enumeration enum = req.getParameterNames();
+ * while (enum.hasMoreElements()) {
+ * String name = (String)enum.nextElement();
+ * String value = req.getParameter(name);
+ * out.println(name + " = " + value);
+ * }
+ * &nbsp;
+ * msg.sendAndClose();
+ * </pre></blockquote>
+ * <p>
+ * Be sure to set the from address, then set the recipient
+ * addresses, then set the subject and other headers, then get the
+ * PrintStream, then write the message, and finally send and close.
+ * The class does minimal error checking internally; it counts on the mail
+ * host to complain if there's any malformatted input or out of order
+ * execution.
+ * <p>
+ * An attachment mechanism based on RFC 1521 could be implemented on top of
+ * this class. In the meanwhile, JavaMail is the best solution for sending
+ * email with attachments.
+ * <p>
+ * Still to do:
+ * <ul>
+ * <li>Figure out how to close the connection in case of error
+ * </ul>
+ *
+ * @version 1.1, 2000/03/19, added angle brackets to address, helps some servers
+ * version 1.0, 1999/12/29
+ */
+public class MailMessage {
+
+ /** default mailhost */
+ public static final String DEFAULT_HOST = "localhost";
+
+ /** default port for SMTP: 25 */
+ public static final int DEFAULT_PORT = 25;
+
+ /** host name for the mail server */
+ private String host;
+
+ /** host port for the mail server */
+ private int port = DEFAULT_PORT;
+
+ /** sender email address */
+ private String from;
+
+ /** list of email addresses to reply to */
+ private Vector replyto;
+
+ /** list of email addresses to send to */
+ private Vector to;
+
+ /** list of email addresses to cc to */
+ private Vector cc;
+
+ /** headers to send in the mail */
+ private Vector headersKeys;
+ private Vector headersValues;
+
+ private MailPrintStream out;
+
+ private SmtpResponseReader in;
+
+ private Socket socket;
+ private static final int OK_READY = 220;
+ private static final int OK_HELO = 250;
+ private static final int OK_FROM = 250;
+ private static final int OK_RCPT_1 = 250;
+ private static final int OK_RCPT_2 = 251;
+ private static final int OK_DATA = 354;
+ private static final int OK_DOT = 250;
+ private static final int OK_QUIT = 221;
+
+ /**
+ * Constructs a new MailMessage to send an email.
+ * Use localhost as the mail server with port 25.
+ *
+ * @exception IOException if there's any problem contacting the mail server
+ */
+ public MailMessage() throws IOException {
+ this(DEFAULT_HOST, DEFAULT_PORT);
+ }
+
+ /**
+ * Constructs a new MailMessage to send an email.
+ * Use the given host as the mail server with port 25.
+ *
+ * @param host the mail server to use
+ * @exception IOException if there's any problem contacting the mail server
+ */
+ public MailMessage(String host) throws IOException {
+ this(host, DEFAULT_PORT);
+ }
+
+ /**
+ * Constructs a new MailMessage to send an email.
+ * Use the given host and port as the mail server.
+ *
+ * @param host the mail server to use
+ * @param port the port to connect to
+ * @exception IOException if there's any problem contacting the mail server
+ */
+ public MailMessage(String host, int port) throws IOException {
+ this.port = port;
+ this.host = host;
+ replyto = new Vector();
+ to = new Vector();
+ cc = new Vector();
+ headersKeys = new Vector();
+ headersValues = new Vector();
+ connect();
+ sendHelo();
+ }
+
+ /**
+ * Set the port to connect to the SMTP host.
+ * @param port the port to use for connection.
+ * @see #DEFAULT_PORT
+ */
+ public void setPort(int port) {
+ this.port = port;
+ }
+
+ /**
+ * Sets the from address. Also sets the "From" header. This method should
+ * be called only once.
+ * @param from the from address
+ * @exception IOException if there's any problem reported by the mail server
+ */
+ public void from(String from) throws IOException {
+ sendFrom(from);
+ this.from = from;
+ }
+
+ /**
+ * Sets the replyto address
+ * This method may be
+ * called multiple times.
+ * @param rto the replyto address
+ *
+ */
+ public void replyto(String rto) {
+ this.replyto.addElement(rto);
+ }
+
+ /**
+ * Sets the to address. Also sets the "To" header. This method may be
+ * called multiple times.
+ *
+ * @param to the to address
+ * @exception IOException if there's any problem reported by the mail server
+ */
+ public void to(String to) throws IOException {
+ sendRcpt(to);
+ this.to.addElement(to);
+ }
+
+ /**
+ * Sets the cc address. Also sets the "Cc" header. This method may be
+ * called multiple times.
+ *
+ * @param cc the cc address
+ * @exception IOException if there's any problem reported by the mail server
+ */
+ public void cc(String cc) throws IOException {
+ sendRcpt(cc);
+ this.cc.addElement(cc);
+ }
+
+ /**
+ * Sets the bcc address. Does NOT set any header since it's a *blind* copy.
+ * This method may be called multiple times.
+ *
+ * @param bcc the bcc address
+ * @exception IOException if there's any problem reported by the mail server
+ */
+ public void bcc(String bcc) throws IOException {
+ sendRcpt(bcc);
+ // No need to keep track of Bcc'd addresses
+ }
+
+ /**
+ * Sets the subject of the mail message. Actually sets the "Subject"
+ * header.
+ * @param subj the subject of the mail message
+ */
+ public void setSubject(String subj) {
+ setHeader("Subject", subj);
+ }
+
+ /**
+ * Sets the named header to the given value. RFC 822 provides the rules for
+ * what text may constitute a header name and value.
+ * @param name name of the header
+ * @param value contents of the header
+ */
+ public void setHeader(String name, String value) {
+ // Blindly trust the user doesn't set any invalid headers
+ headersKeys.add(name);
+ headersValues.add(value);
+ }
+
+ /**
+ * Returns a PrintStream that can be used to write the body of the message.
+ * A stream is used since email bodies are byte-oriented. A writer can
+ * be wrapped on top if necessary for internationalization.
+ * This is actually done in Message.java
+ *
+ * @return a printstream containing the data and the headers of the email
+ * @exception IOException if there's any problem reported by the mail server
+ * @see org.apache.tools.ant.taskdefs.email.Message
+ */
+ public PrintStream getPrintStream() throws IOException {
+ setFromHeader();
+ setReplyToHeader();
+ setToHeader();
+ setCcHeader();
+ setHeader("X-Mailer", "org.apache.tools.mail.MailMessage (ant.apache.org)");
+ sendData();
+ flushHeaders();
+ return out;
+ }
+
+
+ // RFC 822 s4.1: "From:" header must be sent
+ // We rely on error checking by the MTA
+ void setFromHeader() {
+ setHeader("From", from);
+ }
+
+ // RFC 822 s4.1: "Reply-To:" header is optional
+ void setReplyToHeader() {
+ if (!replyto.isEmpty()) {
+ setHeader("Reply-To", vectorToList(replyto));
+ }
+ }
+
+ void setToHeader() {
+ if (!to.isEmpty()) {
+ setHeader("To", vectorToList(to));
+ }
+ }
+
+ void setCcHeader() {
+ if (!cc.isEmpty()) {
+ setHeader("Cc", vectorToList(cc));
+ }
+ }
+
+ String vectorToList(Vector v) {
+ StringBuffer buf = new StringBuffer();
+ Enumeration e = v.elements();
+ while (e.hasMoreElements()) {
+ buf.append(e.nextElement());
+ if (e.hasMoreElements()) {
+ buf.append(", ");
+ }
+ }
+ return buf.toString();
+ }
+
+ void flushHeaders() throws IOException {
+ // RFC 822 s4.1:
+ // "Header fields are NOT required to occur in any particular order,
+ // except that the message body MUST occur AFTER the headers"
+ // (the same section specifies a recommended order, which we ignore)
+ final int size = headersKeys.size();
+ for (int i = 0; i < size; i++) {
+ String name = (String) headersKeys.elementAt(i);
+ String value = (String) headersValues.elementAt(i);
+ out.println(name + ": " + value);
+ }
+ out.println();
+ out.flush();
+ }
+
+ /**
+ * Sends the message and closes the connection to the server.
+ * The MailMessage object cannot be reused.
+ *
+ * @exception IOException if there's any problem reported by the mail server
+ */
+ public void sendAndClose() throws IOException {
+ try {
+ sendDot();
+ sendQuit();
+ } finally {
+ disconnect();
+ }
+ }
+
+ // Make a limited attempt to extract a sanitized email address
+ // Prefer text in <brackets>, ignore anything in (parentheses)
+ static String sanitizeAddress(String s) {
+ int paramDepth = 0;
+ int start = 0;
+ int end = 0;
+ int len = s.length();
+
+ for (int i = 0; i < len; i++) {
+ char c = s.charAt(i);
+ if (c == '(') {
+ paramDepth++;
+ if (start == 0) {
+ end = i; // support "address (name)"
+ }
+ } else if (c == ')') {
+ paramDepth--;
+ if (end == 0) {
+ start = i + 1; // support "(name) address"
+ }
+ } else if (paramDepth == 0 && c == '<') {
+ start = i + 1;
+ } else if (paramDepth == 0 && c == '>') {
+ end = i;
+ }
+ }
+
+ if (end == 0) {
+ end = len;
+ }
+
+ return s.substring(start, end);
+ }
+
+ // * * * * * Raw protocol methods below here * * * * *
+
+ void connect() throws IOException {
+ socket = new Socket(host, port);
+ out = new MailPrintStream(
+ new BufferedOutputStream(
+ socket.getOutputStream()));
+ in = new SmtpResponseReader(socket.getInputStream());
+ getReady();
+ }
+
+ void getReady() throws IOException {
+ String response = in.getResponse();
+ int[] ok = {OK_READY};
+ if (!isResponseOK(response, ok)) {
+ throw new IOException(
+ "Didn't get introduction from server: " + response);
+ }
+ }
+ void sendHelo() throws IOException {
+ String local = InetAddress.getLocalHost().getHostName();
+ int[] ok = {OK_HELO};
+ send("HELO " + local, ok);
+ }
+ void sendFrom(String from) throws IOException {
+ int[] ok = {OK_FROM};
+ send("MAIL FROM: " + "<" + sanitizeAddress(from) + ">", ok);
+ }
+ void sendRcpt(String rcpt) throws IOException {
+ int[] ok = {OK_RCPT_1, OK_RCPT_2};
+ send("RCPT TO: " + "<" + sanitizeAddress(rcpt) + ">", ok);
+ }
+
+ void sendData() throws IOException {
+ int[] ok = {OK_DATA};
+ send("DATA", ok);
+ }
+
+ void sendDot() throws IOException {
+ int[] ok = {OK_DOT};
+ send("\r\n.", ok); // make sure dot is on new line
+ }
+
+ void sendQuit() throws IOException {
+ int[] ok = {OK_QUIT};
+ try {
+ send("QUIT", ok);
+ } catch (IOException e) {
+ throw new ErrorInQuitException(e);
+ }
+ }
+
+ void send(String msg, int[] ok) throws IOException {
+ out.rawPrint(msg + "\r\n"); // raw supports <CRLF>.<CRLF>
+ String response = in.getResponse();
+ if (!isResponseOK(response, ok)) {
+ throw new IOException("Unexpected reply to command: "
+ + msg + ": " + response);
+ }
+ }
+
+ boolean isResponseOK(String response, int[] ok) {
+ // Check that the response is one of the valid codes
+ for (int i = 0; i < ok.length; i++) {
+ if (response.startsWith("" + ok[i])) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ void disconnect() throws IOException {
+ if (out != null) {
+ out.close();
+ }
+ if (in != null) {
+ try {
+ in.close();
+ } catch (IOException e) {
+ // ignore
+ }
+ }
+ if (socket != null) {
+ try {
+ socket.close();
+ } catch (IOException e) {
+ // ignore
+ }
+ }
+ }
+}
+
+/**
+ * This PrintStream subclass makes sure that <CRLF>. becomes <CRLF>..
+ * per RFC 821. It also ensures that new lines are always \r\n.
+*/
+class MailPrintStream extends PrintStream {
+
+ private int lastChar;
+
+ public MailPrintStream(OutputStream out) {
+ super(out, true); // deprecated, but email is byte-oriented
+ }
+
+ // Mac does \n\r, but that's tough to distinguish from Windows \r\n\r\n.
+ // Don't tackle that problem right now.
+ public void write(int b) {
+ if (b == '\n' && lastChar != '\r') {
+ rawWrite('\r'); // ensure always \r\n
+ rawWrite(b);
+ } else if (b == '.' && lastChar == '\n') {
+ rawWrite('.'); // add extra dot
+ rawWrite(b);
+ } else {
+ rawWrite(b);
+ }
+ lastChar = b;
+ }
+
+ public void write(byte[] buf, int off, int len) {
+ for (int i = 0; i < len; i++) {
+ write(buf[off + i]);
+ }
+ }
+
+ void rawWrite(int b) {
+ super.write(b);
+ }
+
+ void rawPrint(String s) {
+ int len = s.length();
+ for (int i = 0; i < len; i++) {
+ rawWrite(s.charAt(i));
+ }
+ }
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/mail/SmtpResponseReader.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/mail/SmtpResponseReader.java
new file mode 100644
index 00000000..c1693f49
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/mail/SmtpResponseReader.java
@@ -0,0 +1,106 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.mail;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+
+/**
+ * A wrapper around the raw input from the SMTP server that assembles
+ * multi line responses into a single String.
+ *
+ * <p>The same rules used here would apply to FTP and other Telnet
+ * based protocols as well.</p>
+ *
+ */
+public class SmtpResponseReader {
+ // CheckStyle:VisibilityModifier OFF - bc
+ protected BufferedReader reader = null;
+ // CheckStyle:VisibilityModifier ON
+ private StringBuffer result = new StringBuffer();
+
+ /**
+ * Wrap this input stream.
+ * @param in the stream to wrap.
+ */
+ public SmtpResponseReader(InputStream in) {
+ reader = new BufferedReader(new InputStreamReader(in));
+ }
+
+ /**
+ * Read until the server indicates that the response is complete.
+ *
+ * @return Responsecode (3 digits) + Blank + Text from all
+ * response line concatenated (with blanks replacing the \r\n
+ * sequences).
+ * @throws IOException on error.
+ */
+ public String getResponse() throws IOException {
+ result.setLength(0);
+ String line = reader.readLine();
+ // CheckStyle:MagicNumber OFF
+ if (line != null && line.length() >= 3) {
+ result.append(line.substring(0, 3));
+ result.append(" ");
+ }
+ // CheckStyle:MagicNumber ON
+
+ while (line != null) {
+ append(line);
+ if (!hasMoreLines(line)) {
+ break;
+ }
+ line = reader.readLine();
+ }
+ return result.toString().trim();
+ }
+
+ /**
+ * Closes the underlying stream.
+ * @throws IOException on error.
+ */
+ public void close() throws IOException {
+ reader.close();
+ }
+
+ /**
+ * Should we expect more input?
+ * @param line the line to check.
+ * @return true if there are more lines to check.
+ */
+ protected boolean hasMoreLines(String line) {
+ // CheckStyle:MagicNumber OFF
+ return line.length() > 3 && line.charAt(3) == '-';
+ // CheckStyle:MagicNumber ON
+ }
+
+ /**
+ * Append the text from this line of the resonse.
+ */
+ private void append(String line) {
+ // CheckStyle:MagicNumber OFF
+ if (line.length() > 4) {
+ result.append(line.substring(4));
+ result.append(" ");
+ }
+ // CheckStyle:MagicNumber ON
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/tar/TarArchiveSparseEntry.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/tar/TarArchiveSparseEntry.java
new file mode 100644
index 00000000..2e76fb69
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/tar/TarArchiveSparseEntry.java
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tools.tar;
+
+import java.io.IOException;
+
+/**
+ * This class represents a sparse entry in a Tar archive.
+ *
+ * <p>
+ * The C structure for a sparse entry is:
+ * <pre>
+ * struct posix_header {
+ * struct sparse sp[21]; // TarConstants.SPARSELEN_GNU_SPARSE - offset 0
+ * char isextended; // TarConstants.ISEXTENDEDLEN_GNU_SPARSE - offset 504
+ * };
+ * </pre>
+ * Whereas, "struct sparse" is:
+ * <pre>
+ * struct sparse {
+ * char offset[12]; // offset 0
+ * char numbytes[12]; // offset 12
+ * };
+ * </pre>
+ */
+
+public class TarArchiveSparseEntry implements TarConstants {
+ /** If an extension sparse header follows. */
+ private boolean isExtended;
+
+ /**
+ * Construct an entry from an archive's header bytes. File is set
+ * to null.
+ *
+ * @param headerBuf The header bytes from a tar archive entry.
+ * @throws IOException on unknown format
+ */
+ public TarArchiveSparseEntry(byte[] headerBuf) throws IOException {
+ int offset = 0;
+ offset += SPARSELEN_GNU_SPARSE;
+ isExtended = TarUtils.parseBoolean(headerBuf, offset);
+ }
+
+ public boolean isExtended() {
+ return isExtended;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/tar/TarBuffer.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/tar/TarBuffer.java
new file mode 100644
index 00000000..b089d9bf
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/tar/TarBuffer.java
@@ -0,0 +1,463 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+/*
+ * This package is based on the work done by Timothy Gerard Endres
+ * (time@ice.com) to whom the Ant project is very grateful for his great code.
+ */
+
+package org.apache.tools.tar;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Arrays;
+
+/**
+ * The TarBuffer class implements the tar archive concept
+ * of a buffered input stream. This concept goes back to the
+ * days of blocked tape drives and special io devices. In the
+ * Java universe, the only real function that this class
+ * performs is to ensure that files have the correct "block"
+ * size, or other tars will complain.
+ * <p>
+ * You should never have a need to access this class directly.
+ * TarBuffers are created by Tar IO Streams.
+ *
+ */
+
+public class TarBuffer {
+
+ /** Default record size */
+ public static final int DEFAULT_RCDSIZE = (512);
+
+ /** Default block size */
+ public static final int DEFAULT_BLKSIZE = (DEFAULT_RCDSIZE * 20);
+
+ private InputStream inStream;
+ private OutputStream outStream;
+ private final int blockSize;
+ private final int recordSize;
+ private final int recsPerBlock;
+ private final byte[] blockBuffer;
+
+ private int currBlkIdx;
+ private int currRecIdx;
+ private boolean debug;
+
+ /**
+ * Constructor for a TarBuffer on an input stream.
+ * @param inStream the input stream to use
+ */
+ public TarBuffer(InputStream inStream) {
+ this(inStream, TarBuffer.DEFAULT_BLKSIZE);
+ }
+
+ /**
+ * Constructor for a TarBuffer on an input stream.
+ * @param inStream the input stream to use
+ * @param blockSize the block size to use
+ */
+ public TarBuffer(InputStream inStream, int blockSize) {
+ this(inStream, blockSize, TarBuffer.DEFAULT_RCDSIZE);
+ }
+
+ /**
+ * Constructor for a TarBuffer on an input stream.
+ * @param inStream the input stream to use
+ * @param blockSize the block size to use
+ * @param recordSize the record size to use
+ */
+ public TarBuffer(InputStream inStream, int blockSize, int recordSize) {
+ this(inStream, null, blockSize, recordSize);
+ }
+
+ /**
+ * Constructor for a TarBuffer on an output stream.
+ * @param outStream the output stream to use
+ */
+ public TarBuffer(OutputStream outStream) {
+ this(outStream, TarBuffer.DEFAULT_BLKSIZE);
+ }
+
+ /**
+ * Constructor for a TarBuffer on an output stream.
+ * @param outStream the output stream to use
+ * @param blockSize the block size to use
+ */
+ public TarBuffer(OutputStream outStream, int blockSize) {
+ this(outStream, blockSize, TarBuffer.DEFAULT_RCDSIZE);
+ }
+
+ /**
+ * Constructor for a TarBuffer on an output stream.
+ * @param outStream the output stream to use
+ * @param blockSize the block size to use
+ * @param recordSize the record size to use
+ */
+ public TarBuffer(OutputStream outStream, int blockSize, int recordSize) {
+ this(null, outStream, blockSize, recordSize);
+ }
+
+ /**
+ * Private constructor to perform common setup.
+ */
+ private TarBuffer(InputStream inStream, OutputStream outStream, int blockSize, int recordSize) {
+ this.inStream = inStream;
+ this.outStream = outStream;
+ this.debug = false;
+ this.blockSize = blockSize;
+ this.recordSize = recordSize;
+ this.recsPerBlock = (this.blockSize / this.recordSize);
+ this.blockBuffer = new byte[this.blockSize];
+
+ if (this.inStream != null) {
+ this.currBlkIdx = -1;
+ this.currRecIdx = this.recsPerBlock;
+ } else {
+ this.currBlkIdx = 0;
+ this.currRecIdx = 0;
+ }
+ }
+
+ /**
+ * Get the TAR Buffer's block size. Blocks consist of multiple records.
+ * @return the block size
+ */
+ public int getBlockSize() {
+ return this.blockSize;
+ }
+
+ /**
+ * Get the TAR Buffer's record size.
+ * @return the record size
+ */
+ public int getRecordSize() {
+ return this.recordSize;
+ }
+
+ /**
+ * Set the debugging flag for the buffer.
+ *
+ * @param debug If true, print debugging output.
+ */
+ public void setDebug(boolean debug) {
+ this.debug = debug;
+ }
+
+ /**
+ * Determine if an archive record indicate End of Archive. End of
+ * archive is indicated by a record that consists entirely of null bytes.
+ *
+ * @param record The record data to check.
+ * @return true if the record data is an End of Archive
+ */
+ public boolean isEOFRecord(byte[] record) {
+ for (int i = 0, sz = getRecordSize(); i < sz; ++i) {
+ if (record[i] != 0) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Skip over a record on the input stream.
+ * @throws IOException on error
+ */
+ public void skipRecord() throws IOException {
+ if (debug) {
+ System.err.println("SkipRecord: recIdx = " + currRecIdx
+ + " blkIdx = " + currBlkIdx);
+ }
+
+ if (inStream == null) {
+ throw new IOException("reading (via skip) from an output buffer");
+ }
+
+ if (currRecIdx >= recsPerBlock && !readBlock()) {
+ return; // UNDONE
+ }
+
+ currRecIdx++;
+ }
+
+ /**
+ * Read a record from the input stream and return the data.
+ *
+ * @return The record data.
+ * @throws IOException on error
+ */
+ public byte[] readRecord() throws IOException {
+ if (debug) {
+ System.err.println("ReadRecord: recIdx = " + currRecIdx
+ + " blkIdx = " + currBlkIdx);
+ }
+
+ if (inStream == null) {
+ if (outStream == null) {
+ throw new IOException("input buffer is closed");
+ }
+ throw new IOException("reading from an output buffer");
+ }
+
+ if (currRecIdx >= recsPerBlock && !readBlock()) {
+ return null;
+ }
+
+ byte[] result = new byte[recordSize];
+
+ System.arraycopy(blockBuffer,
+ (currRecIdx * recordSize), result, 0,
+ recordSize);
+
+ currRecIdx++;
+
+ return result;
+ }
+
+ /**
+ * @return false if End-Of-File, else true
+ */
+ private boolean readBlock() throws IOException {
+ if (debug) {
+ System.err.println("ReadBlock: blkIdx = " + currBlkIdx);
+ }
+
+ if (inStream == null) {
+ throw new IOException("reading from an output buffer");
+ }
+
+ currRecIdx = 0;
+
+ int offset = 0;
+ int bytesNeeded = blockSize;
+
+ while (bytesNeeded > 0) {
+ long numBytes = inStream.read(blockBuffer, offset,
+ bytesNeeded);
+
+ //
+ // NOTE
+ // We have fit EOF, and the block is not full!
+ //
+ // This is a broken archive. It does not follow the standard
+ // blocking algorithm. However, because we are generous, and
+ // it requires little effort, we will simply ignore the error
+ // and continue as if the entire block were read. This does
+ // not appear to break anything upstream. We used to return
+ // false in this case.
+ //
+ // Thanks to 'Yohann.Roussel@alcatel.fr' for this fix.
+ //
+ if (numBytes == -1) {
+ if (offset == 0) {
+ // Ensure that we do not read gigabytes of zeros
+ // for a corrupt tar file.
+ // See http://issues.apache.org/bugzilla/show_bug.cgi?id=39924
+ return false;
+ }
+ // However, just leaving the unread portion of the buffer dirty does
+ // cause problems in some cases. This problem is described in
+ // http://issues.apache.org/bugzilla/show_bug.cgi?id=29877
+ //
+ // The solution is to fill the unused portion of the buffer with zeros.
+
+ Arrays.fill(blockBuffer, offset, offset + bytesNeeded, (byte) 0);
+
+ break;
+ }
+
+ offset += numBytes;
+ bytesNeeded -= numBytes;
+
+ if (numBytes != blockSize) {
+ if (debug) {
+ System.err.println("ReadBlock: INCOMPLETE READ "
+ + numBytes + " of " + blockSize
+ + " bytes read.");
+ }
+ }
+ }
+
+ currBlkIdx++;
+
+ return true;
+ }
+
+ /**
+ * Get the current block number, zero based.
+ *
+ * @return The current zero based block number.
+ */
+ public int getCurrentBlockNum() {
+ return currBlkIdx;
+ }
+
+ /**
+ * Get the current record number, within the current block, zero based.
+ * Thus, current offset = (currentBlockNum * recsPerBlk) + currentRecNum.
+ *
+ * @return The current zero based record number.
+ */
+ public int getCurrentRecordNum() {
+ return currRecIdx - 1;
+ }
+
+ /**
+ * Write an archive record to the archive.
+ *
+ * @param record The record data to write to the archive.
+ * @throws IOException on error
+ */
+ public void writeRecord(byte[] record) throws IOException {
+ if (debug) {
+ System.err.println("WriteRecord: recIdx = " + currRecIdx
+ + " blkIdx = " + currBlkIdx);
+ }
+
+ if (outStream == null) {
+ if (inStream == null){
+ throw new IOException("Output buffer is closed");
+ }
+ throw new IOException("writing to an input buffer");
+ }
+
+ if (record.length != recordSize) {
+ throw new IOException("record to write has length '"
+ + record.length
+ + "' which is not the record size of '"
+ + recordSize + "'");
+ }
+
+ if (currRecIdx >= recsPerBlock) {
+ writeBlock();
+ }
+
+ System.arraycopy(record, 0, blockBuffer,
+ (currRecIdx * recordSize),
+ recordSize);
+
+ currRecIdx++;
+ }
+
+ /**
+ * Write an archive record to the archive, where the record may be
+ * inside of a larger array buffer. The buffer must be "offset plus
+ * record size" long.
+ *
+ * @param buf The buffer containing the record data to write.
+ * @param offset The offset of the record data within buf.
+ * @throws IOException on error
+ */
+ public void writeRecord(byte[] buf, int offset) throws IOException {
+ if (debug) {
+ System.err.println("WriteRecord: recIdx = " + currRecIdx
+ + " blkIdx = " + currBlkIdx);
+ }
+
+ if (outStream == null) {
+ if (inStream == null){
+ throw new IOException("Output buffer is closed");
+ }
+ throw new IOException("writing to an input buffer");
+ }
+
+ if ((offset + recordSize) > buf.length) {
+ throw new IOException("record has length '" + buf.length
+ + "' with offset '" + offset
+ + "' which is less than the record size of '"
+ + recordSize + "'");
+ }
+
+ if (currRecIdx >= recsPerBlock) {
+ writeBlock();
+ }
+
+ System.arraycopy(buf, offset, blockBuffer,
+ (currRecIdx * recordSize),
+ recordSize);
+
+ currRecIdx++;
+ }
+
+ /**
+ * Write a TarBuffer block to the archive.
+ */
+ private void writeBlock() throws IOException {
+ if (debug) {
+ System.err.println("WriteBlock: blkIdx = " + currBlkIdx);
+ }
+
+ if (outStream == null) {
+ throw new IOException("writing to an input buffer");
+ }
+
+ outStream.write(blockBuffer, 0, blockSize);
+ outStream.flush();
+
+ currRecIdx = 0;
+ currBlkIdx++;
+ Arrays.fill(blockBuffer, (byte) 0);
+ }
+
+ /**
+ * Flush the current data block if it has any data in it.
+ */
+ void flushBlock() throws IOException {
+ if (debug) {
+ System.err.println("TarBuffer.flushBlock() called.");
+ }
+
+ if (outStream == null) {
+ throw new IOException("writing to an input buffer");
+ }
+
+ if (currRecIdx > 0) {
+ writeBlock();
+ }
+ }
+
+ /**
+ * Close the TarBuffer. If this is an output buffer, also flush the
+ * current block before closing.
+ * @throws IOException on error
+ */
+ public void close() throws IOException {
+ if (debug) {
+ System.err.println("TarBuffer.closeBuffer().");
+ }
+
+ if (outStream != null) {
+ flushBlock();
+
+ if (outStream != System.out
+ && outStream != System.err) {
+ outStream.close();
+
+ outStream = null;
+ }
+ } else if (inStream != null) {
+ if (inStream != System.in) {
+ inStream.close();
+ }
+ inStream = null;
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/tar/TarConstants.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/tar/TarConstants.java
new file mode 100644
index 00000000..06d0faca
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/tar/TarConstants.java
@@ -0,0 +1,293 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+/*
+ * This package is based on the work done by Timothy Gerard Endres
+ * (time@ice.com) to whom the Ant project is very grateful for his great code.
+ */
+
+package org.apache.tools.tar;
+
+/**
+ * This interface contains all the definitions used in the package.
+ *
+ * For tar formats (FORMAT_OLDGNU, FORMAT_POSIX, etc.) see GNU tar
+ * <I>tar.h</I> type <I>enum archive_format</I>
+ */
+// CheckStyle:InterfaceIsTypeCheck OFF (bc)
+public interface TarConstants {
+
+ /**
+ * GNU format as per before tar 1.12.
+ */
+ int FORMAT_OLDGNU = 2;
+
+ /**
+ * Pure Posix format.
+ */
+ int FORMAT_POSIX = 3;
+
+ /**
+ * The length of the name field in a header buffer.
+ */
+ int NAMELEN = 100;
+
+ /**
+ * The length of the mode field in a header buffer.
+ */
+ int MODELEN = 8;
+
+ /**
+ * The length of the user id field in a header buffer.
+ */
+ int UIDLEN = 8;
+
+ /**
+ * The length of the group id field in a header buffer.
+ */
+ int GIDLEN = 8;
+
+ /**
+ * The maximum value of gid/uid in a tar archive which can
+ * be expressed in octal char notation (that's 7 sevens, octal).
+ */
+ long MAXID = 07777777L;
+
+ /**
+ * The length of the checksum field in a header buffer.
+ */
+ int CHKSUMLEN = 8;
+
+ /**
+ * The length of the size field in a header buffer.
+ * Includes the trailing space or NUL.
+ */
+ int SIZELEN = 12;
+
+ /**
+ * The maximum size of a file in a tar archive
+ * which can be expressed in octal char notation (that's 11 sevens, octal).
+ */
+ long MAXSIZE = 077777777777L;
+
+ /** Offset of start of magic field within header record */
+ int MAGIC_OFFSET = 257;
+ /**
+ * The length of the magic field in a header buffer including the version.
+ */
+ int MAGICLEN = 8;
+
+ /**
+ * The length of the magic field in a header buffer.
+ */
+ int PURE_MAGICLEN = 6;
+
+ /** Offset of start of magic field within header record */
+ int VERSION_OFFSET = 263;
+ /**
+ * Previously this was regarded as part of "magic" field, but it
+ * is separate.
+ */
+ int VERSIONLEN = 2;
+
+ /**
+ * The length of the modification time field in a header buffer.
+ */
+ int MODTIMELEN = 12;
+
+ /**
+ * The length of the user name field in a header buffer.
+ */
+ int UNAMELEN = 32;
+
+ /**
+ * The length of the group name field in a header buffer.
+ */
+ int GNAMELEN = 32;
+
+ /**
+ * The length of each of the device fields (major and minor) in a header buffer.
+ */
+ int DEVLEN = 8;
+
+ /**
+ * Length of the prefix field.
+ *
+ */
+ int PREFIXLEN = 155;
+
+ /**
+ * The length of the access time field in an old GNU header buffer.
+ *
+ */
+ int ATIMELEN_GNU = 12;
+
+ /**
+ * The length of the created time field in an old GNU header buffer.
+ *
+ */
+ int CTIMELEN_GNU = 12;
+
+ /**
+ * The length of the multivolume start offset field in an old GNU header buffer.
+ *
+ */
+ int OFFSETLEN_GNU = 12;
+
+ /**
+ * The length of the long names field in an old GNU header buffer.
+ *
+ */
+ int LONGNAMESLEN_GNU = 4;
+
+ /**
+ * The length of the padding field in an old GNU header buffer.
+ *
+ */
+ int PAD2LEN_GNU = 1;
+
+ /**
+ * The sum of the length of all sparse headers in an old GNU header buffer.
+ *
+ */
+ int SPARSELEN_GNU = 96;
+
+ /**
+ * The length of the is extension field in an old GNU header buffer.
+ *
+ */
+ int ISEXTENDEDLEN_GNU = 1;
+
+ /**
+ * The length of the real size field in an old GNU header buffer.
+ *
+ */
+ int REALSIZELEN_GNU = 12;
+
+ /**
+ * The sum of the length of all sparse headers in a sparse header buffer.
+ *
+ */
+ int SPARSELEN_GNU_SPARSE = 504;
+
+ /**
+ * The length of the is extension field in a sparse header buffer.
+ *
+ */
+ int ISEXTENDEDLEN_GNU_SPARSE = 1;
+
+ /**
+ * LF_ constants represent the "link flag" of an entry, or more commonly,
+ * the "entry type". This is the "old way" of indicating a normal file.
+ */
+ byte LF_OLDNORM = 0;
+
+ /**
+ * Normal file type.
+ */
+ byte LF_NORMAL = (byte) '0';
+
+ /**
+ * Link file type.
+ */
+ byte LF_LINK = (byte) '1';
+
+ /**
+ * Symbolic link file type.
+ */
+ byte LF_SYMLINK = (byte) '2';
+
+ /**
+ * Character device file type.
+ */
+ byte LF_CHR = (byte) '3';
+
+ /**
+ * Block device file type.
+ */
+ byte LF_BLK = (byte) '4';
+
+ /**
+ * Directory file type.
+ */
+ byte LF_DIR = (byte) '5';
+
+ /**
+ * FIFO (pipe) file type.
+ */
+ byte LF_FIFO = (byte) '6';
+
+ /**
+ * Contiguous file type.
+ */
+ byte LF_CONTIG = (byte) '7';
+
+ /**
+ * Identifies the *next* file on the tape as having a long linkname.
+ */
+ byte LF_GNUTYPE_LONGLINK = (byte) 'K';
+
+ /**
+ * Identifies the *next* file on the tape as having a long name.
+ */
+ byte LF_GNUTYPE_LONGNAME = (byte) 'L';
+
+ /**
+ * Sparse file type.
+ */
+ byte LF_GNUTYPE_SPARSE = (byte) 'S';
+
+ // See "http://www.opengroup.org/onlinepubs/009695399/utilities/pax.html#tag_04_100_13_02"
+
+ /**
+ * Identifies the entry as a Pax extended header.
+ */
+ byte LF_PAX_EXTENDED_HEADER_LC = (byte) 'x';
+
+ /**
+ * Identifies the entry as a Pax extended header (SunOS tar -E).
+ */
+ byte LF_PAX_EXTENDED_HEADER_UC = (byte) 'X';
+
+ /**
+ * Identifies the entry as a Pax global extended header.
+ */
+ byte LF_PAX_GLOBAL_EXTENDED_HEADER = (byte) 'g';
+
+ String TMAGIC = "ustar";
+
+ /**
+ * The magic tag representing a POSIX tar archive.
+ */
+ String MAGIC_POSIX = "ustar\0";
+ String VERSION_POSIX = "00";
+
+ /**
+ * The magic tag representing a GNU tar archive.
+ */
+ String GNU_TMAGIC = "ustar ";
+ // Appear to be two possible GNU versions
+ String VERSION_GNU_SPACE = " \0";
+ String VERSION_GNU_ZERO = "0\0";
+
+ /**
+ * The name of the GNU tar entry which contains a long name.
+ */
+ String GNU_LONGLINK = "././@LongLink";
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/tar/TarEntry.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/tar/TarEntry.java
new file mode 100644
index 00000000..a9c96f13
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/tar/TarEntry.java
@@ -0,0 +1,1149 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+/*
+ * This package is based on the work done by Timothy Gerard Endres
+ * (time@ice.com) to whom the Ant project is very grateful for his great code.
+ */
+
+package org.apache.tools.tar;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.util.Date;
+import java.util.Locale;
+
+import org.apache.tools.zip.ZipEncoding;
+
+/**
+ * This class represents an entry in a Tar archive. It consists
+ * of the entry's header, as well as the entry's File. Entries
+ * can be instantiated in one of three ways, depending on how
+ * they are to be used.
+ * <p>
+ * TarEntries that are created from the header bytes read from
+ * an archive are instantiated with the TarEntry( byte[] )
+ * constructor. These entries will be used when extracting from
+ * or listing the contents of an archive. These entries have their
+ * header filled in using the header bytes. They also set the File
+ * to null, since they reference an archive entry not a file.
+ * <p>
+ * TarEntries that are created from Files that are to be written
+ * into an archive are instantiated with the TarEntry( File )
+ * constructor. These entries have their header filled in using
+ * the File's information. They also keep a reference to the File
+ * for convenience when writing entries.
+ * <p>
+ * Finally, TarEntries can be constructed from nothing but a name.
+ * This allows the programmer to construct the entry by hand, for
+ * instance when only an InputStream is available for writing to
+ * the archive, and the header information is constructed from
+ * other information. In this case the header fields are set to
+ * defaults and the File is set to null.
+ *
+ * <p>
+ * The C structure for a Tar Entry's header is:
+ * <pre>
+ * struct header {
+ * char name[NAMSIZ];
+ * char mode[8];
+ * char uid[8];
+ * char gid[8];
+ * char size[12];
+ * char mtime[12];
+ * char chksum[8];
+ * char linkflag;
+ * char linkname[NAMSIZ];
+ * char magic[8];
+ * char uname[TUNMLEN];
+ * char gname[TGNMLEN];
+ * char devmajor[8];
+ * char devminor[8];
+ * } header;
+ * All unused bytes are set to null.
+ * New-style GNU tar files are slightly different from the above.
+ * For values of size larger than 077777777777L (11 7s)
+ * or uid and gid larger than 07777777L (7 7s)
+ * the sign bit of the first byte is set, and the rest of the
+ * field is the binary representation of the number.
+ * See TarUtils.parseOctalOrBinary.
+ * </pre>
+ *
+ * <p>
+ * The C structure for a old GNU Tar Entry's header is:
+ * <pre>
+ * struct oldgnu_header {
+ * char unused_pad1[345]; // TarConstants.PAD1LEN_GNU - offset 0
+ * char atime[12]; // TarConstants.ATIMELEN_GNU - offset 345
+ * char ctime[12]; // TarConstants.CTIMELEN_GNU - offset 357
+ * char offset[12]; // TarConstants.OFFSETLEN_GNU - offset 369
+ * char longnames[4]; // TarConstants.LONGNAMESLEN_GNU - offset 381
+ * char unused_pad2; // TarConstants.PAD2LEN_GNU - offset 385
+ * struct sparse sp[4]; // TarConstants.SPARSELEN_GNU - offset 386
+ * char isextended; // TarConstants.ISEXTENDEDLEN_GNU - offset 482
+ * char realsize[12]; // TarConstants.REALSIZELEN_GNU - offset 483
+ * char unused_pad[17]; // TarConstants.PAD3LEN_GNU - offset 495
+ * };
+ * </pre>
+ * Whereas, "struct sparse" is:
+ * <pre>
+ * struct sparse {
+ * char offset[12]; // offset 0
+ * char numbytes[12]; // offset 12
+ * };
+ * </pre>
+ *
+ */
+
+public class TarEntry implements TarConstants {
+ /** The entry's name. */
+ private String name;
+
+ /** The entry's permission mode. */
+ private int mode;
+
+ /** The entry's user id. */
+ private long userId;
+
+ /** The entry's group id. */
+ private long groupId;
+
+ /** The entry's size. */
+ private long size;
+
+ /** The entry's modification time. */
+ private long modTime;
+
+ /** The entry's link flag. */
+ private byte linkFlag;
+
+ /** The entry's link name. */
+ private String linkName;
+
+ /** The entry's magic tag. */
+ private String magic;
+ /** The version of the format */
+ private String version;
+
+ /** The entry's user name. */
+ private String userName;
+
+ /** The entry's group name. */
+ private String groupName;
+
+ /** The entry's major device number. */
+ private int devMajor;
+
+ /** The entry's minor device number. */
+ private int devMinor;
+
+ /** If an extension sparse header follows. */
+ private boolean isExtended;
+
+ /** The entry's real size in case of a sparse file. */
+ private long realSize;
+
+ /** The entry's file reference */
+ private File file;
+
+ /** Maximum length of a user's name in the tar file */
+ public static final int MAX_NAMELEN = 31;
+
+ /** Default permissions bits for directories */
+ public static final int DEFAULT_DIR_MODE = 040755;
+
+ /** Default permissions bits for files */
+ public static final int DEFAULT_FILE_MODE = 0100644;
+
+ /** Convert millis to seconds */
+ public static final int MILLIS_PER_SECOND = 1000;
+
+ /**
+ * Construct an empty entry and prepares the header values.
+ */
+ private TarEntry() {
+ this.magic = MAGIC_POSIX;
+ this.version = VERSION_POSIX;
+ this.name = "";
+ this.linkName = "";
+
+ String user = System.getProperty("user.name", "");
+
+ if (user.length() > MAX_NAMELEN) {
+ user = user.substring(0, MAX_NAMELEN);
+ }
+
+ this.userId = 0;
+ this.groupId = 0;
+ this.userName = user;
+ this.groupName = "";
+ this.file = null;
+ }
+
+ /**
+ * Construct an entry with only a name. This allows the programmer
+ * to construct the entry's header "by hand". File is set to null.
+ *
+ * @param name the entry name
+ */
+ public TarEntry(String name) {
+ this(name, false);
+ }
+
+ /**
+ * Construct an entry with only a name. This allows the programmer
+ * to construct the entry's header "by hand". File is set to null.
+ *
+ * @param name the entry name
+ * @param preserveLeadingSlashes whether to allow leading slashes
+ * in the name.
+ */
+ public TarEntry(String name, boolean preserveLeadingSlashes) {
+ this();
+
+ name = normalizeFileName(name, preserveLeadingSlashes);
+ boolean isDir = name.endsWith("/");
+
+ this.devMajor = 0;
+ this.devMinor = 0;
+ this.name = name;
+ this.mode = isDir ? DEFAULT_DIR_MODE : DEFAULT_FILE_MODE;
+ this.linkFlag = isDir ? LF_DIR : LF_NORMAL;
+ this.userId = 0;
+ this.groupId = 0;
+ this.size = 0;
+ this.modTime = (new Date()).getTime() / MILLIS_PER_SECOND;
+ this.linkName = "";
+ this.userName = "";
+ this.groupName = "";
+ }
+
+ /**
+ * Construct an entry with a name and a link flag.
+ *
+ * @param name the entry name
+ * @param linkFlag the entry link flag.
+ */
+ public TarEntry(String name, byte linkFlag) {
+ this(name);
+ this.linkFlag = linkFlag;
+ if (linkFlag == LF_GNUTYPE_LONGNAME) {
+ magic = GNU_TMAGIC;
+ version = VERSION_GNU_SPACE;
+ }
+ }
+
+ /**
+ * Construct an entry for a file. File is set to file, and the
+ * header is constructed from information from the file.
+ * The name is set from the normalized file path.
+ *
+ * @param file The file that the entry represents.
+ */
+ public TarEntry(File file) {
+ this(file, file.getPath());
+ }
+
+ /**
+ * Construct an entry for a file. File is set to file, and the
+ * header is constructed from information from the file.
+ *
+ * @param file The file that the entry represents.
+ * @param fileName the name to be used for the entry.
+ */
+ public TarEntry(File file, String fileName) {
+ this();
+
+ String normalizedName = normalizeFileName(fileName, false);
+ this.file = file;
+
+ this.linkName = "";
+
+ if (file.isDirectory()) {
+ this.mode = DEFAULT_DIR_MODE;
+ this.linkFlag = LF_DIR;
+
+ int nameLength = normalizedName.length();
+ if (nameLength == 0 || normalizedName.charAt(nameLength - 1) != '/') {
+ this.name = normalizedName + "/";
+ } else {
+ this.name = normalizedName;
+ }
+ this.size = 0;
+ } else {
+ this.mode = DEFAULT_FILE_MODE;
+ this.linkFlag = LF_NORMAL;
+ this.size = file.length();
+ this.name = normalizedName;
+ }
+
+ this.modTime = file.lastModified() / MILLIS_PER_SECOND;
+ this.devMajor = 0;
+ this.devMinor = 0;
+ }
+
+ /**
+ * Construct an entry from an archive's header bytes. File is set
+ * to null.
+ *
+ * @param headerBuf The header bytes from a tar archive entry.
+ * @throws IllegalArgumentException if any of the numeric fields have an invalid format
+ */
+ public TarEntry(byte[] headerBuf) {
+ this();
+ parseTarHeader(headerBuf);
+ }
+
+ /**
+ * Construct an entry from an archive's header bytes. File is set
+ * to null.
+ *
+ * @param headerBuf The header bytes from a tar archive entry.
+ * @param encoding encoding to use for file names
+ * @throws IllegalArgumentException if any of the numeric fields have an invalid format
+ * @throws IOException if an error occurs during reading the archive
+ */
+ public TarEntry(byte[] headerBuf, ZipEncoding encoding)
+ throws IOException {
+ this();
+ parseTarHeader(headerBuf, encoding);
+ }
+
+ /**
+ * Determine if the two entries are equal. Equality is determined
+ * by the header names being equal.
+ *
+ * @param it Entry to be checked for equality.
+ * @return True if the entries are equal.
+ */
+ public boolean equals(TarEntry it) {
+ return getName().equals(it.getName());
+ }
+
+ /**
+ * Determine if the two entries are equal. Equality is determined
+ * by the header names being equal.
+ *
+ * @param it Entry to be checked for equality.
+ * @return True if the entries are equal.
+ */
+ @Override
+ public boolean equals(Object it) {
+ if (it == null || getClass() != it.getClass()) {
+ return false;
+ }
+ return equals((TarEntry) it);
+ }
+
+ /**
+ * Hashcodes are based on entry names.
+ *
+ * @return the entry hashcode
+ */
+ @Override
+ public int hashCode() {
+ return getName().hashCode();
+ }
+
+ /**
+ * Determine if the given entry is a descendant of this entry.
+ * Descendancy is determined by the name of the descendant
+ * starting with this entry's name.
+ *
+ * @param desc Entry to be checked as a descendant of this.
+ * @return True if entry is a descendant of this.
+ */
+ public boolean isDescendent(TarEntry desc) {
+ return desc.getName().startsWith(getName());
+ }
+
+ /**
+ * Get this entry's name.
+ *
+ * @return This entry's name.
+ */
+ public String getName() {
+ return name.toString();
+ }
+
+ /**
+ * Set this entry's name.
+ *
+ * @param name This entry's new name.
+ */
+ public void setName(String name) {
+ this.name = normalizeFileName(name, false);
+ }
+
+ /**
+ * Set the mode for this entry
+ *
+ * @param mode the mode for this entry
+ */
+ public void setMode(int mode) {
+ this.mode = mode;
+ }
+
+ /**
+ * Get this entry's link name.
+ *
+ * @return This entry's link name.
+ */
+ public String getLinkName() {
+ return linkName.toString();
+ }
+
+ /**
+ * Set this entry's link name.
+ *
+ * @param link the link name to use.
+ */
+ public void setLinkName(String link) {
+ this.linkName = link;
+ }
+
+ /**
+ * Get this entry's user id.
+ *
+ * @return This entry's user id.
+ * @deprecated use #getLongUserId instead as user ids can be
+ * bigger than {@link Integer#MAX_VALUE}
+ */
+ @Deprecated
+ public int getUserId() {
+ return (int) (userId & 0xffffffff);
+ }
+
+ /**
+ * Set this entry's user id.
+ *
+ * @param userId This entry's new user id.
+ */
+ public void setUserId(int userId) {
+ setUserId((long) userId);
+ }
+
+ /**
+ * Get this entry's user id.
+ *
+ * @return This entry's user id.
+ * @since 1.9.5
+ */
+ public long getLongUserId() {
+ return userId;
+ }
+
+ /**
+ * Set this entry's user id.
+ *
+ * @param userId This entry's new user id.
+ * @since 1.9.5
+ */
+ public void setUserId(long userId) {
+ this.userId = userId;
+ }
+
+ /**
+ * Get this entry's group id.
+ *
+ * @return This entry's group id.
+ * @deprecated use #getLongGroupId instead as group ids can be
+ * bigger than {@link Integer#MAX_VALUE}
+ */
+ @Deprecated
+ public int getGroupId() {
+ return (int) (groupId & 0xffffffff);
+ }
+
+ /**
+ * Set this entry's group id.
+ *
+ * @param groupId This entry's new group id.
+ */
+ public void setGroupId(int groupId) {
+ setGroupId((long) groupId);
+ }
+
+ /**
+ * Get this entry's group id.
+ *
+ * @return This entry's group id.
+ * @since 1.9.5
+ */
+ public long getLongGroupId() {
+ return groupId;
+ }
+
+ /**
+ * Set this entry's group id.
+ *
+ * @param groupId This entry's new group id.
+ * @since 1.9.5
+ */
+ public void setGroupId(long groupId) {
+ this.groupId = groupId;
+ }
+
+ /**
+ * Get this entry's user name.
+ *
+ * @return This entry's user name.
+ */
+ public String getUserName() {
+ return userName.toString();
+ }
+
+ /**
+ * Set this entry's user name.
+ *
+ * @param userName This entry's new user name.
+ */
+ public void setUserName(String userName) {
+ this.userName = userName;
+ }
+
+ /**
+ * Get this entry's group name.
+ *
+ * @return This entry's group name.
+ */
+ public String getGroupName() {
+ return groupName.toString();
+ }
+
+ /**
+ * Set this entry's group name.
+ *
+ * @param groupName This entry's new group name.
+ */
+ public void setGroupName(String groupName) {
+ this.groupName = groupName;
+ }
+
+ /**
+ * Convenience method to set this entry's group and user ids.
+ *
+ * @param userId This entry's new user id.
+ * @param groupId This entry's new group id.
+ */
+ public void setIds(int userId, int groupId) {
+ setUserId(userId);
+ setGroupId(groupId);
+ }
+
+ /**
+ * Convenience method to set this entry's group and user names.
+ *
+ * @param userName This entry's new user name.
+ * @param groupName This entry's new group name.
+ */
+ public void setNames(String userName, String groupName) {
+ setUserName(userName);
+ setGroupName(groupName);
+ }
+
+ /**
+ * Set this entry's modification time. The parameter passed
+ * to this method is in "Java time".
+ *
+ * @param time This entry's new modification time.
+ */
+ public void setModTime(long time) {
+ modTime = time / MILLIS_PER_SECOND;
+ }
+
+ /**
+ * Set this entry's modification time.
+ *
+ * @param time This entry's new modification time.
+ */
+ public void setModTime(Date time) {
+ modTime = time.getTime() / MILLIS_PER_SECOND;
+ }
+
+ /**
+ * Set this entry's modification time.
+ *
+ * @return time This entry's new modification time.
+ */
+ public Date getModTime() {
+ return new Date(modTime * MILLIS_PER_SECOND);
+ }
+
+ /**
+ * Get this entry's file.
+ *
+ * @return This entry's file.
+ */
+ public File getFile() {
+ return file;
+ }
+
+ /**
+ * Get this entry's mode.
+ *
+ * @return This entry's mode.
+ */
+ public int getMode() {
+ return mode;
+ }
+
+ /**
+ * Get this entry's file size.
+ *
+ * @return This entry's file size.
+ */
+ public long getSize() {
+ return size;
+ }
+
+ /**
+ * Set this entry's file size.
+ *
+ * @param size This entry's new file size.
+ * @throws IllegalArgumentException if the size is &lt; 0.
+ */
+ public void setSize(long size) {
+ if (size < 0) {
+ throw new IllegalArgumentException("Size is out of range: " + size);
+ }
+ this.size = size;
+ }
+
+ /**
+ * Get this entry's major device number.
+ *
+ * @return This entry's major device number.
+ */
+ public int getDevMajor() {
+ return devMajor;
+ }
+
+ /**
+ * Set this entry's major device number.
+ *
+ * @param devNo This entry's major device number.
+ * @throws IllegalArgumentException if the devNo is &lt; 0.
+ */
+ public void setDevMajor(int devNo) {
+ if (devNo < 0) {
+ throw new IllegalArgumentException("Major device number is out of "
+ + "range: " + devNo);
+ }
+ this.devMajor = devNo;
+ }
+
+ /**
+ * Get this entry's minor device number.
+ *
+ * @return This entry's minor device number.
+ */
+ public int getDevMinor() {
+ return devMinor;
+ }
+
+ /**
+ * Set this entry's minor device number.
+ *
+ * @param devNo This entry's minor device number.
+ * @throws IllegalArgumentException if the devNo is &lt; 0.
+ */
+ public void setDevMinor(int devNo) {
+ if (devNo < 0) {
+ throw new IllegalArgumentException("Minor device number is out of "
+ + "range: " + devNo);
+ }
+ this.devMinor = devNo;
+ }
+
+ /**
+ * Indicates in case of a sparse file if an extension sparse header
+ * follows.
+ *
+ * @return true if an extension sparse header follows.
+ */
+ public boolean isExtended() {
+ return isExtended;
+ }
+
+ /**
+ * Get this entry's real file size in case of a sparse file.
+ *
+ * @return This entry's real file size.
+ */
+ public long getRealSize() {
+ return realSize;
+ }
+
+ /**
+ * Indicate if this entry is a GNU sparse block.
+ *
+ * @return true if this is a sparse extension provided by GNU tar
+ */
+ public boolean isGNUSparse() {
+ return linkFlag == LF_GNUTYPE_SPARSE;
+ }
+
+ /**
+ * Indicate if this entry is a GNU long linkname block
+ *
+ * @return true if this is a long name extension provided by GNU tar
+ */
+ public boolean isGNULongLinkEntry() {
+ return linkFlag == LF_GNUTYPE_LONGLINK
+ && name.equals(GNU_LONGLINK);
+ }
+
+ /**
+ * Indicate if this entry is a GNU long name block
+ *
+ * @return true if this is a long name extension provided by GNU tar
+ */
+ public boolean isGNULongNameEntry() {
+ return linkFlag == LF_GNUTYPE_LONGNAME
+ && name.equals(GNU_LONGLINK);
+ }
+
+ /**
+ * Check if this is a Pax header.
+ *
+ * @return {@code true} if this is a Pax header.
+ */
+ public boolean isPaxHeader() {
+ return linkFlag == LF_PAX_EXTENDED_HEADER_LC
+ || linkFlag == LF_PAX_EXTENDED_HEADER_UC;
+ }
+
+ /**
+ * Check if this is a Pax header.
+ *
+ * @return {@code true} if this is a Pax header.
+ */
+ public boolean isGlobalPaxHeader() {
+ return linkFlag == LF_PAX_GLOBAL_EXTENDED_HEADER;
+ }
+
+ /**
+ * Return whether or not this entry represents a directory.
+ *
+ * @return True if this entry is a directory.
+ */
+ public boolean isDirectory() {
+ if (file != null) {
+ return file.isDirectory();
+ }
+
+ if (linkFlag == LF_DIR) {
+ return true;
+ }
+
+ if (getName().endsWith("/")) {
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Check if this is a "normal file".
+ * @return <i>true</i> if it is a 'normal' file
+ */
+ public boolean isFile() {
+ if (file != null) {
+ return file.isFile();
+ }
+ if (linkFlag == LF_OLDNORM || linkFlag == LF_NORMAL) {
+ return true;
+ }
+ return !getName().endsWith("/");
+ }
+
+ /**
+ * Check if this is a symbolic link entry.
+ * @return <i>true</i> if it is a symlink
+ */
+ public boolean isSymbolicLink() {
+ return linkFlag == LF_SYMLINK;
+ }
+
+ /**
+ * Check if this is a link entry.
+ * @return <i>true</i> if it is a link
+ */
+ public boolean isLink() {
+ return linkFlag == LF_LINK;
+ }
+
+ /**
+ * Check if this is a character device entry.
+ * @return <i>true</i> if it is a character device entry
+ */
+ public boolean isCharacterDevice() {
+ return linkFlag == LF_CHR;
+ }
+
+ /**
+ * @return <i>true</i> if this is a block device entry.
+ */
+ public boolean isBlockDevice() {
+ return linkFlag == LF_BLK;
+ }
+
+ /**
+ * @return <i>true</i> if this is a FIFO (pipe) entry.
+ */
+ public boolean isFIFO() {
+ return linkFlag == LF_FIFO;
+ }
+
+ /**
+ * If this entry represents a file, and the file is a directory, return
+ * an array of TarEntries for this entry's children.
+ *
+ * @return An array of TarEntry's for this entry's children.
+ */
+ public TarEntry[] getDirectoryEntries() {
+ if (file == null || !file.isDirectory()) {
+ return new TarEntry[0];
+ }
+
+ String[] list = file.list();
+ TarEntry[] result = new TarEntry[list.length];
+
+ for (int i = 0; i < list.length; ++i) {
+ result[i] = new TarEntry(new File(file, list[i]));
+ }
+
+ return result;
+ }
+
+ /**
+ * Write an entry's header information to a header buffer.
+ *
+ * <p>This method does not use the star/GNU tar/BSD tar extensions.</p>
+ *
+ * @param outbuf The tar entry header buffer to fill in.
+ */
+ public void writeEntryHeader(byte[] outbuf) {
+ try {
+ writeEntryHeader(outbuf, TarUtils.DEFAULT_ENCODING, false);
+ } catch (IOException ex) {
+ try {
+ writeEntryHeader(outbuf, TarUtils.FALLBACK_ENCODING, false);
+ } catch (IOException ex2) {
+ // impossible
+ throw new RuntimeException(ex2);
+ }
+ }
+ }
+
+ /**
+ * Write an entry's header information to a header buffer.
+ *
+ * @param outbuf The tar entry header buffer to fill in.
+ * @param encoding encoding to use when writing the file name.
+ * @param starMode whether to use the star/GNU tar/BSD tar
+ * extension for numeric fields if their value doesn't fit in the
+ * maximum size of standard tar archives
+ * @throws IOException if an error occurs while writing the archive
+ */
+ public void writeEntryHeader(byte[] outbuf, ZipEncoding encoding,
+ boolean starMode) throws IOException {
+ int offset = 0;
+
+ offset = TarUtils.formatNameBytes(name, outbuf, offset, NAMELEN,
+ encoding);
+ offset = writeEntryHeaderField(mode, outbuf, offset, MODELEN, starMode);
+ offset = writeEntryHeaderField(userId, outbuf, offset, UIDLEN,
+ starMode);
+ offset = writeEntryHeaderField(groupId, outbuf, offset, GIDLEN,
+ starMode);
+ offset = writeEntryHeaderField(size, outbuf, offset, SIZELEN, starMode);
+ offset = writeEntryHeaderField(modTime, outbuf, offset, MODTIMELEN,
+ starMode);
+
+ int csOffset = offset;
+
+ for (int c = 0; c < CHKSUMLEN; ++c) {
+ outbuf[offset++] = (byte) ' ';
+ }
+
+ outbuf[offset++] = linkFlag;
+ offset = TarUtils.formatNameBytes(linkName, outbuf, offset, NAMELEN,
+ encoding);
+ offset = TarUtils.formatNameBytes(magic, outbuf, offset, PURE_MAGICLEN);
+ offset = TarUtils.formatNameBytes(version, outbuf, offset, VERSIONLEN);
+ offset = TarUtils.formatNameBytes(userName, outbuf, offset, UNAMELEN,
+ encoding);
+ offset = TarUtils.formatNameBytes(groupName, outbuf, offset, GNAMELEN,
+ encoding);
+ offset = writeEntryHeaderField(devMajor, outbuf, offset, DEVLEN,
+ starMode);
+ offset = writeEntryHeaderField(devMinor, outbuf, offset, DEVLEN,
+ starMode);
+
+ while (offset < outbuf.length) {
+ outbuf[offset++] = 0;
+ }
+
+ long chk = TarUtils.computeCheckSum(outbuf);
+
+ TarUtils.formatCheckSumOctalBytes(chk, outbuf, csOffset, CHKSUMLEN);
+ }
+
+ private int writeEntryHeaderField(long value, byte[] outbuf, int offset,
+ int length, boolean starMode) {
+ if (!starMode && (value < 0
+ || value >= (1L << (3 * (length - 1))))) {
+ // value doesn't fit into field when written as octal
+ // number, will be written to PAX header or causes an
+ // error
+ return TarUtils.formatLongOctalBytes(0, outbuf, offset, length);
+ }
+ return TarUtils.formatLongOctalOrBinaryBytes(value, outbuf, offset,
+ length);
+ }
+
+ /**
+ * Parse an entry's header information from a header buffer.
+ *
+ * @param header The tar entry header buffer to get information from.
+ * @throws IllegalArgumentException if any of the numeric fields have an invalid format
+ */
+ public void parseTarHeader(byte[] header) {
+ try {
+ parseTarHeader(header, TarUtils.DEFAULT_ENCODING);
+ } catch (IOException ex) {
+ try {
+ parseTarHeader(header, TarUtils.DEFAULT_ENCODING, true);
+ } catch (IOException ex2) {
+ // not really possible
+ throw new RuntimeException(ex2);
+ }
+ }
+ }
+
+ /**
+ * Parse an entry's header information from a header buffer.
+ *
+ * @param header The tar entry header buffer to get information from.
+ * @param encoding encoding to use for file names
+ * @throws IllegalArgumentException if any of the numeric fields
+ * have an invalid format
+ * @throws IOException if an error occurs while reading the archive
+ */
+ public void parseTarHeader(byte[] header, ZipEncoding encoding)
+ throws IOException {
+ parseTarHeader(header, encoding, false);
+ }
+
+ private void parseTarHeader(byte[] header, ZipEncoding encoding,
+ final boolean oldStyle)
+ throws IOException {
+ int offset = 0;
+
+ name = oldStyle ? TarUtils.parseName(header, offset, NAMELEN)
+ : TarUtils.parseName(header, offset, NAMELEN, encoding);
+ offset += NAMELEN;
+ mode = (int) TarUtils.parseOctalOrBinary(header, offset, MODELEN);
+ offset += MODELEN;
+ userId = (int) TarUtils.parseOctalOrBinary(header, offset, UIDLEN);
+ offset += UIDLEN;
+ groupId = (int) TarUtils.parseOctalOrBinary(header, offset, GIDLEN);
+ offset += GIDLEN;
+ size = TarUtils.parseOctalOrBinary(header, offset, SIZELEN);
+ offset += SIZELEN;
+ modTime = TarUtils.parseOctalOrBinary(header, offset, MODTIMELEN);
+ offset += MODTIMELEN;
+ offset += CHKSUMLEN;
+ linkFlag = header[offset++];
+ linkName = oldStyle ? TarUtils.parseName(header, offset, NAMELEN)
+ : TarUtils.parseName(header, offset, NAMELEN, encoding);
+ offset += NAMELEN;
+ magic = TarUtils.parseName(header, offset, PURE_MAGICLEN);
+ offset += PURE_MAGICLEN;
+ version = TarUtils.parseName(header, offset, VERSIONLEN);
+ offset += VERSIONLEN;
+ userName = oldStyle ? TarUtils.parseName(header, offset, UNAMELEN)
+ : TarUtils.parseName(header, offset, UNAMELEN, encoding);
+ offset += UNAMELEN;
+ groupName = oldStyle ? TarUtils.parseName(header, offset, GNAMELEN)
+ : TarUtils.parseName(header, offset, GNAMELEN, encoding);
+ offset += GNAMELEN;
+ devMajor = (int) TarUtils.parseOctalOrBinary(header, offset, DEVLEN);
+ offset += DEVLEN;
+ devMinor = (int) TarUtils.parseOctalOrBinary(header, offset, DEVLEN);
+ offset += DEVLEN;
+
+ int type = evaluateType(header);
+ switch (type) {
+ case FORMAT_OLDGNU: {
+ offset += ATIMELEN_GNU;
+ offset += CTIMELEN_GNU;
+ offset += OFFSETLEN_GNU;
+ offset += LONGNAMESLEN_GNU;
+ offset += PAD2LEN_GNU;
+ offset += SPARSELEN_GNU;
+ isExtended = TarUtils.parseBoolean(header, offset);
+ offset += ISEXTENDEDLEN_GNU;
+ realSize = TarUtils.parseOctal(header, offset, REALSIZELEN_GNU);
+ offset += REALSIZELEN_GNU;
+ break;
+ }
+ case FORMAT_POSIX:
+ default: {
+ String prefix = oldStyle
+ ? TarUtils.parseName(header, offset, PREFIXLEN)
+ : TarUtils.parseName(header, offset, PREFIXLEN, encoding);
+ // SunOS tar -E does not add / to directory names, so fix
+ // up to be consistent
+ if (isDirectory() && !name.endsWith("/")) {
+ name = name + "/";
+ }
+ if (prefix.length() > 0) {
+ name = prefix + "/" + name;
+ }
+ }
+ }
+ }
+
+ /**
+ * Strips Windows' drive letter as well as any leading slashes,
+ * turns path separators into forward slahes.
+ */
+ private static String normalizeFileName(String fileName,
+ boolean preserveLeadingSlashes) {
+ String osname = System.getProperty("os.name").toLowerCase(Locale.ENGLISH);
+
+ if (osname != null) {
+
+ // Strip off drive letters!
+ // REVIEW Would a better check be "(File.separator == '\')"?
+
+ if (osname.startsWith("windows")) {
+ if (fileName.length() > 2) {
+ char ch1 = fileName.charAt(0);
+ char ch2 = fileName.charAt(1);
+
+ if (ch2 == ':'
+ && ((ch1 >= 'a' && ch1 <= 'z')
+ || (ch1 >= 'A' && ch1 <= 'Z'))) {
+ fileName = fileName.substring(2);
+ }
+ }
+ } else if (osname.indexOf("netware") > -1) {
+ int colon = fileName.indexOf(':');
+ if (colon != -1) {
+ fileName = fileName.substring(colon + 1);
+ }
+ }
+ }
+
+ fileName = fileName.replace(File.separatorChar, '/');
+
+ // No absolute pathnames
+ // Windows (and Posix?) paths can start with "\\NetworkDrive\",
+ // so we loop on starting /'s.
+ while (!preserveLeadingSlashes && fileName.startsWith("/")) {
+ fileName = fileName.substring(1);
+ }
+ return fileName;
+ }
+
+ /**
+ * Evaluate an entry's header format from a header buffer.
+ *
+ * @param header The tar entry header buffer to evaluate the format for.
+ * @return format type
+ */
+ private int evaluateType(byte[] header) {
+ if (matchAsciiBuffer(GNU_TMAGIC, header, MAGIC_OFFSET, PURE_MAGICLEN)) {
+ return FORMAT_OLDGNU;
+ }
+ if (matchAsciiBuffer(MAGIC_POSIX, header, MAGIC_OFFSET, PURE_MAGICLEN)) {
+ return FORMAT_POSIX;
+ }
+ return 0;
+ }
+
+ /**
+ * Check if buffer contents matches Ascii String.
+ *
+ * @param expected
+ * @param buffer
+ * @param offset
+ * @param length
+ * @return {@code true} if buffer is the same as the expected string
+ */
+ private static boolean matchAsciiBuffer(String expected, byte[] buffer,
+ int offset, int length) {
+ byte[] buffer1;
+ try {
+ buffer1 = expected.getBytes("ASCII");
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException(e); // Should not happen
+ }
+ return isEqual(buffer1, 0, buffer1.length, buffer, offset, length,
+ false);
+ }
+
+ /**
+ * Compare byte buffers, optionally ignoring trailing nulls
+ *
+ * @param buffer1
+ * @param offset1
+ * @param length1
+ * @param buffer2
+ * @param offset2
+ * @param length2
+ * @param ignoreTrailingNulls
+ * @return {@code true} if buffer1 and buffer2 have same contents, having regard to trailing nulls
+ */
+ private static boolean isEqual(
+ final byte[] buffer1, final int offset1, final int length1,
+ final byte[] buffer2, final int offset2, final int length2,
+ boolean ignoreTrailingNulls) {
+ int minLen=length1 < length2 ? length1 : length2;
+ for (int i=0; i < minLen; i++) {
+ if (buffer1[offset1+i] != buffer2[offset2+i]) {
+ return false;
+ }
+ }
+ if (length1 == length2) {
+ return true;
+ }
+ if (ignoreTrailingNulls) {
+ if (length1 > length2){
+ for(int i = length2; i < length1; i++){
+ if (buffer1[offset1+i] != 0) {
+ return false;
+ }
+ }
+ } else {
+ for (int i = length1; i < length2; i++){
+ if (buffer2[offset2+i] != 0) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/tar/TarInputStream.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/tar/TarInputStream.java
new file mode 100644
index 00000000..57827a2c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/tar/TarInputStream.java
@@ -0,0 +1,660 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+/*
+ * This package is based on the work done by Timothy Gerard Endres
+ * (time@ice.com) to whom the Ant project is very grateful for his great code.
+ */
+
+package org.apache.tools.tar;
+
+import java.io.ByteArrayOutputStream;
+import java.io.FilterInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.apache.tools.zip.ZipEncoding;
+import org.apache.tools.zip.ZipEncodingHelper;
+
+/**
+ * The TarInputStream reads a UNIX tar archive as an InputStream.
+ * methods are provided to position at each successive entry in
+ * the archive, and the read each entry as a normal input stream
+ * using read().
+ *
+ */
+public class TarInputStream extends FilterInputStream {
+ private static final int SMALL_BUFFER_SIZE = 256;
+ private static final int BUFFER_SIZE = 8 * 1024;
+ private static final int LARGE_BUFFER_SIZE = 32 * 1024;
+ private static final int BYTE_MASK = 0xFF;
+
+ private final byte[] SKIP_BUF = new byte[BUFFER_SIZE];
+ private final byte[] SMALL_BUF = new byte[SMALL_BUFFER_SIZE];
+
+ // CheckStyle:VisibilityModifier OFF - bc
+ protected boolean debug;
+ protected boolean hasHitEOF;
+ protected long entrySize;
+ protected long entryOffset;
+ protected byte[] readBuf;
+ protected TarBuffer buffer;
+ protected TarEntry currEntry;
+
+ /**
+ * This contents of this array is not used at all in this class,
+ * it is only here to avoid repreated object creation during calls
+ * to the no-arg read method.
+ */
+ protected byte[] oneBuf;
+
+ // CheckStyle:VisibilityModifier ON
+
+ private final ZipEncoding encoding;
+
+ /**
+ * Constructor for TarInputStream.
+ * @param is the input stream to use
+ */
+ public TarInputStream(InputStream is) {
+ this(is, TarBuffer.DEFAULT_BLKSIZE, TarBuffer.DEFAULT_RCDSIZE);
+ }
+
+ /**
+ * Constructor for TarInputStream.
+ * @param is the input stream to use
+ * @param encoding name of the encoding to use for file names
+ */
+ public TarInputStream(InputStream is, String encoding) {
+ this(is, TarBuffer.DEFAULT_BLKSIZE, TarBuffer.DEFAULT_RCDSIZE, encoding);
+ }
+
+ /**
+ * Constructor for TarInputStream.
+ * @param is the input stream to use
+ * @param blockSize the block size to use
+ */
+ public TarInputStream(InputStream is, int blockSize) {
+ this(is, blockSize, TarBuffer.DEFAULT_RCDSIZE);
+ }
+
+ /**
+ * Constructor for TarInputStream.
+ * @param is the input stream to use
+ * @param blockSize the block size to use
+ * @param encoding name of the encoding to use for file names
+ */
+ public TarInputStream(InputStream is, int blockSize, String encoding) {
+ this(is, blockSize, TarBuffer.DEFAULT_RCDSIZE, encoding);
+ }
+
+ /**
+ * Constructor for TarInputStream.
+ * @param is the input stream to use
+ * @param blockSize the block size to use
+ * @param recordSize the record size to use
+ */
+ public TarInputStream(InputStream is, int blockSize, int recordSize) {
+ this(is, blockSize, recordSize, null);
+ }
+
+ /**
+ * Constructor for TarInputStream.
+ * @param is the input stream to use
+ * @param blockSize the block size to use
+ * @param recordSize the record size to use
+ * @param encoding name of the encoding to use for file names
+ */
+ public TarInputStream(InputStream is, int blockSize, int recordSize,
+ String encoding) {
+ super(is);
+ this.buffer = new TarBuffer(is, blockSize, recordSize);
+ this.readBuf = null;
+ this.oneBuf = new byte[1];
+ this.debug = false;
+ this.hasHitEOF = false;
+ this.encoding = ZipEncodingHelper.getZipEncoding(encoding);
+ }
+
+ /**
+ * Sets the debugging flag.
+ *
+ * @param debug True to turn on debugging.
+ */
+ public void setDebug(boolean debug) {
+ this.debug = debug;
+ buffer.setDebug(debug);
+ }
+
+ /**
+ * Closes this stream. Calls the TarBuffer's close() method.
+ * @throws IOException on error
+ */
+ @Override
+ public void close() throws IOException {
+ buffer.close();
+ }
+
+ /**
+ * Get the record size being used by this stream's TarBuffer.
+ *
+ * @return The TarBuffer record size.
+ */
+ public int getRecordSize() {
+ return buffer.getRecordSize();
+ }
+
+ /**
+ * Get the available data that can be read from the current
+ * entry in the archive. This does not indicate how much data
+ * is left in the entire archive, only in the current entry.
+ * This value is determined from the entry's size header field
+ * and the amount of data already read from the current entry.
+ * Integer.MAX_VALUE is returned in case more than Integer.MAX_VALUE
+ * bytes are left in the current entry in the archive.
+ *
+ * @return The number of available bytes for the current entry.
+ * @throws IOException for signature
+ */
+ @Override
+ public int available() throws IOException {
+ if (entrySize - entryOffset > Integer.MAX_VALUE) {
+ return Integer.MAX_VALUE;
+ }
+ return (int) (entrySize - entryOffset);
+ }
+
+ /**
+ * Skip bytes in the input buffer. This skips bytes in the
+ * current entry's data, not the entire archive, and will
+ * stop at the end of the current entry's data if the number
+ * to skip extends beyond that point.
+ *
+ * @param numToSkip The number of bytes to skip.
+ * @return the number actually skipped
+ * @throws IOException on error
+ */
+ @Override
+ public long skip(long numToSkip) throws IOException {
+ // REVIEW
+ // This is horribly inefficient, but it ensures that we
+ // properly skip over bytes via the TarBuffer...
+ //
+ long skip = numToSkip;
+ while (skip > 0) {
+ int realSkip = (int) (skip > SKIP_BUF.length
+ ? SKIP_BUF.length : skip);
+ int numRead = read(SKIP_BUF, 0, realSkip);
+ if (numRead == -1) {
+ break;
+ }
+ skip -= numRead;
+ }
+ return (numToSkip - skip);
+ }
+
+ /**
+ * Since we do not support marking just yet, we return false.
+ *
+ * @return False.
+ */
+ @Override
+ public boolean markSupported() {
+ return false;
+ }
+
+ /**
+ * Since we do not support marking just yet, we do nothing.
+ *
+ * @param markLimit The limit to mark.
+ */
+ @Override
+ public void mark(int markLimit) {
+ }
+
+ /**
+ * Since we do not support marking just yet, we do nothing.
+ */
+ @Override
+ public void reset() {
+ }
+
+ /**
+ * Get the next entry in this tar archive. This will skip
+ * over any remaining data in the current entry, if there
+ * is one, and place the input stream at the header of the
+ * next entry, and read the header and instantiate a new
+ * TarEntry from the header bytes and return that entry.
+ * If there are no more entries in the archive, null will
+ * be returned to indicate that the end of the archive has
+ * been reached.
+ *
+ * @return The next TarEntry in the archive, or null.
+ * @throws IOException on error
+ */
+ public TarEntry getNextEntry() throws IOException {
+ if (hasHitEOF) {
+ return null;
+ }
+
+ if (currEntry != null) {
+ long numToSkip = entrySize - entryOffset;
+
+ if (debug) {
+ System.err.println("TarInputStream: SKIP currENTRY '"
+ + currEntry.getName() + "' SZ "
+ + entrySize + " OFF "
+ + entryOffset + " skipping "
+ + numToSkip + " bytes");
+ }
+
+ while (numToSkip > 0) {
+ long skipped = skip(numToSkip);
+ if (skipped <= 0) {
+ throw new RuntimeException("failed to skip current tar"
+ + " entry");
+ }
+ numToSkip -= skipped;
+ }
+
+ readBuf = null;
+ }
+
+ byte[] headerBuf = getRecord();
+
+ if (hasHitEOF) {
+ currEntry = null;
+ return null;
+ }
+
+ try {
+ currEntry = new TarEntry(headerBuf, encoding);
+ } catch (IllegalArgumentException e) {
+ IOException ioe = new IOException("Error detected parsing the header");
+ ioe.initCause(e);
+ throw ioe;
+ }
+ if (debug) {
+ System.err.println("TarInputStream: SET CURRENTRY '"
+ + currEntry.getName()
+ + "' size = "
+ + currEntry.getSize());
+ }
+
+ entryOffset = 0;
+ entrySize = currEntry.getSize();
+
+ if (currEntry.isGNULongLinkEntry()) {
+ byte[] longLinkData = getLongNameData();
+ if (longLinkData == null) {
+ // Bugzilla: 40334
+ // Malformed tar file - long link entry name not followed by
+ // entry
+ return null;
+ }
+ currEntry.setLinkName(encoding.decode(longLinkData));
+ }
+
+ if (currEntry.isGNULongNameEntry()) {
+ byte[] longNameData = getLongNameData();
+ if (longNameData == null) {
+ // Bugzilla: 40334
+ // Malformed tar file - long entry name not followed by
+ // entry
+ return null;
+ }
+ currEntry.setName(encoding.decode(longNameData));
+ }
+
+ if (currEntry.isPaxHeader()){ // Process Pax headers
+ paxHeaders();
+ }
+
+ if (currEntry.isGNUSparse()){ // Process sparse files
+ readGNUSparse();
+ }
+
+ // If the size of the next element in the archive has changed
+ // due to a new size being reported in the posix header
+ // information, we update entrySize here so that it contains
+ // the correct value.
+ entrySize = currEntry.getSize();
+ return currEntry;
+ }
+
+ /**
+ * Get the next entry in this tar archive as longname data.
+ *
+ * @return The next entry in the archive as longname data, or null.
+ * @throws IOException on error
+ */
+ protected byte[] getLongNameData() throws IOException {
+ // read in the name
+ ByteArrayOutputStream longName = new ByteArrayOutputStream();
+ int length = 0;
+ while ((length = read(SMALL_BUF)) >= 0) {
+ longName.write(SMALL_BUF, 0, length);
+ }
+ getNextEntry();
+ if (currEntry == null) {
+ // Bugzilla: 40334
+ // Malformed tar file - long entry name not followed by entry
+ return null;
+ }
+ byte[] longNameData = longName.toByteArray();
+ // remove trailing null terminator(s)
+ length = longNameData.length;
+ while (length > 0 && longNameData[length - 1] == 0) {
+ --length;
+ }
+ if (length != longNameData.length) {
+ byte[] l = new byte[length];
+ System.arraycopy(longNameData, 0, l, 0, length);
+ longNameData = l;
+ }
+ return longNameData;
+ }
+
+ /**
+ * Get the next record in this tar archive. This will skip
+ * over any remaining data in the current entry, if there
+ * is one, and place the input stream at the header of the
+ * next entry.
+ * If there are no more entries in the archive, null will
+ * be returned to indicate that the end of the archive has
+ * been reached.
+ *
+ * @return The next header in the archive, or null.
+ * @throws IOException on error
+ */
+ private byte[] getRecord() throws IOException {
+ if (hasHitEOF) {
+ return null;
+ }
+
+ byte[] headerBuf = buffer.readRecord();
+
+ if (headerBuf == null) {
+ if (debug) {
+ System.err.println("READ NULL RECORD");
+ }
+ hasHitEOF = true;
+ } else if (buffer.isEOFRecord(headerBuf)) {
+ if (debug) {
+ System.err.println("READ EOF RECORD");
+ }
+ hasHitEOF = true;
+ }
+
+ return hasHitEOF ? null : headerBuf;
+ }
+
+ private void paxHeaders() throws IOException{
+ Map<String, String> headers = parsePaxHeaders(this);
+ getNextEntry(); // Get the actual file entry
+ applyPaxHeadersToCurrentEntry(headers);
+ }
+
+ Map<String, String> parsePaxHeaders(InputStream i) throws IOException {
+ Map<String, String> headers = new HashMap<String, String>();
+ // Format is "length keyword=value\n";
+ while(true){ // get length
+ int ch;
+ int len = 0;
+ int read = 0;
+ while((ch = i.read()) != -1) {
+ read++;
+ if (ch == ' '){ // End of length string
+ // Get keyword
+ ByteArrayOutputStream coll = new ByteArrayOutputStream();
+ while((ch = i.read()) != -1) {
+ read++;
+ if (ch == '='){ // end of keyword
+ String keyword = coll.toString("UTF-8");
+ // Get rest of entry
+ final int restLen = len - read;
+ byte[] rest = new byte[restLen];
+ int got = 0;
+ while (got < restLen && (ch = i.read()) != -1) {
+ rest[got++] = (byte) ch;
+ }
+ if (got != restLen) {
+ throw new IOException("Failed to read "
+ + "Paxheader. Expected "
+ + restLen
+ + " bytes, read "
+ + got);
+ }
+ // Drop trailing NL
+ String value = new String(rest, 0,
+ restLen - 1, "UTF-8");
+ headers.put(keyword, value);
+ break;
+ }
+ coll.write((byte) ch);
+ }
+ break; // Processed single header
+ }
+ len *= 10;
+ len += ch - '0';
+ }
+ if (ch == -1){ // EOF
+ break;
+ }
+ }
+ return headers;
+ }
+
+ private void applyPaxHeadersToCurrentEntry(Map<String, String> headers) {
+ /*
+ * The following headers are defined for Pax.
+ * atime, ctime, charset: cannot use these without changing TarEntry fields
+ * mtime
+ * comment
+ * gid, gname
+ * linkpath
+ * size
+ * uid,uname
+ * SCHILY.devminor, SCHILY.devmajor: don't have setters/getters for those
+ */
+ for (Entry<String, String> ent : headers.entrySet()){
+ String key = ent.getKey();
+ String val = ent.getValue();
+ if ("path".equals(key)){
+ currEntry.setName(val);
+ } else if ("linkpath".equals(key)){
+ currEntry.setLinkName(val);
+ } else if ("gid".equals(key)){
+ currEntry.setGroupId(Long.parseLong(val));
+ } else if ("gname".equals(key)){
+ currEntry.setGroupName(val);
+ } else if ("uid".equals(key)){
+ currEntry.setUserId(Long.parseLong(val));
+ } else if ("uname".equals(key)){
+ currEntry.setUserName(val);
+ } else if ("size".equals(key)){
+ currEntry.setSize(Long.parseLong(val));
+ } else if ("mtime".equals(key)){
+ currEntry.setModTime((long) (Double.parseDouble(val) * 1000));
+ } else if ("SCHILY.devminor".equals(key)){
+ currEntry.setDevMinor(Integer.parseInt(val));
+ } else if ("SCHILY.devmajor".equals(key)){
+ currEntry.setDevMajor(Integer.parseInt(val));
+ }
+ }
+ }
+
+ /**
+ * Adds the sparse chunks from the current entry to the sparse chunks,
+ * including any additional sparse entries following the current entry.
+ *
+ * @throws IOException on error
+ *
+ * @todo Sparse files get not yet really processed.
+ */
+ private void readGNUSparse() throws IOException {
+ /* we do not really process sparse files yet
+ sparses = new ArrayList();
+ sparses.addAll(currEntry.getSparses());
+ */
+ if (currEntry.isExtended()) {
+ TarArchiveSparseEntry entry;
+ do {
+ byte[] headerBuf = getRecord();
+ if (hasHitEOF) {
+ currEntry = null;
+ break;
+ }
+ entry = new TarArchiveSparseEntry(headerBuf);
+ /* we do not really process sparse files yet
+ sparses.addAll(entry.getSparses());
+ */
+ } while (entry.isExtended());
+ }
+ }
+
+ /**
+ * Reads a byte from the current tar archive entry.
+ *
+ * This method simply calls read( byte[], int, int ).
+ *
+ * @return The byte read, or -1 at EOF.
+ * @throws IOException on error
+ */
+ @Override
+ public int read() throws IOException {
+ int num = read(oneBuf, 0, 1);
+ return num == -1 ? -1 : (oneBuf[0]) & BYTE_MASK;
+ }
+
+ /**
+ * Reads bytes from the current tar archive entry.
+ *
+ * This method is aware of the boundaries of the current
+ * entry in the archive and will deal with them as if they
+ * were this stream's start and EOF.
+ *
+ * @param buf The buffer into which to place bytes read.
+ * @param offset The offset at which to place bytes read.
+ * @param numToRead The number of bytes to read.
+ * @return The number of bytes read, or -1 at EOF.
+ * @throws IOException on error
+ */
+ @Override
+ public int read(byte[] buf, int offset, int numToRead) throws IOException {
+ int totalRead = 0;
+
+ if (entryOffset >= entrySize) {
+ return -1;
+ }
+
+ if ((numToRead + entryOffset) > entrySize) {
+ numToRead = (int) (entrySize - entryOffset);
+ }
+
+ if (readBuf != null) {
+ int sz = (numToRead > readBuf.length) ? readBuf.length
+ : numToRead;
+
+ System.arraycopy(readBuf, 0, buf, offset, sz);
+
+ if (sz >= readBuf.length) {
+ readBuf = null;
+ } else {
+ int newLen = readBuf.length - sz;
+ byte[] newBuf = new byte[newLen];
+
+ System.arraycopy(readBuf, sz, newBuf, 0, newLen);
+
+ readBuf = newBuf;
+ }
+
+ totalRead += sz;
+ numToRead -= sz;
+ offset += sz;
+ }
+
+ while (numToRead > 0) {
+ byte[] rec = buffer.readRecord();
+
+ if (rec == null) {
+ // Unexpected EOF!
+ throw new IOException("unexpected EOF with " + numToRead
+ + " bytes unread");
+ }
+
+ int sz = numToRead;
+ int recLen = rec.length;
+
+ if (recLen > sz) {
+ System.arraycopy(rec, 0, buf, offset, sz);
+
+ readBuf = new byte[recLen - sz];
+
+ System.arraycopy(rec, sz, readBuf, 0, recLen - sz);
+ } else {
+ sz = recLen;
+
+ System.arraycopy(rec, 0, buf, offset, recLen);
+ }
+
+ totalRead += sz;
+ numToRead -= sz;
+ offset += sz;
+ }
+
+ entryOffset += totalRead;
+
+ return totalRead;
+ }
+
+ /**
+ * Copies the contents of the current tar archive entry directly into
+ * an output stream.
+ *
+ * @param out The OutputStream into which to write the entry's data.
+ * @throws IOException on error
+ */
+ public void copyEntryContents(OutputStream out) throws IOException {
+ byte[] buf = new byte[LARGE_BUFFER_SIZE];
+
+ while (true) {
+ int numRead = read(buf, 0, buf.length);
+
+ if (numRead == -1) {
+ break;
+ }
+
+ out.write(buf, 0, numRead);
+ }
+ }
+
+ /**
+ * Whether this class is able to read the given entry.
+ *
+ * <p>May return false if the current entry is a sparse file.</p>
+ */
+ public boolean canReadEntryData(TarEntry te) {
+ return !te.isGNUSparse();
+ }
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/tar/TarOutputStream.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/tar/TarOutputStream.java
new file mode 100644
index 00000000..032f7254
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/tar/TarOutputStream.java
@@ -0,0 +1,657 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+/*
+ * This package is based on the work done by Timothy Gerard Endres
+ * (time@ice.com) to whom the Ant project is very grateful for his great code.
+ */
+
+package org.apache.tools.tar;
+
+import java.io.FilterOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.StringWriter;
+import java.nio.ByteBuffer;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.tools.zip.ZipEncoding;
+import org.apache.tools.zip.ZipEncodingHelper;
+
+/**
+ * The TarOutputStream writes a UNIX tar archive as an OutputStream.
+ * Methods are provided to put entries, and then write their contents
+ * by writing to this stream using write().
+ *
+ */
+public class TarOutputStream extends FilterOutputStream {
+ /** Fail if a long file name is required in the archive. */
+ public static final int LONGFILE_ERROR = 0;
+
+ /** Long paths will be truncated in the archive. */
+ public static final int LONGFILE_TRUNCATE = 1;
+
+ /** GNU tar extensions are used to store long file names in the archive. */
+ public static final int LONGFILE_GNU = 2;
+
+ /** POSIX/PAX extensions are used to store long file names in the archive. */
+ public static final int LONGFILE_POSIX = 3;
+
+ /** Fail if a big number (e.g. size &gt; 8GiB) is required in the archive. */
+ public static final int BIGNUMBER_ERROR = 0;
+
+ /** star/GNU tar/BSD tar extensions are used to store big number in the archive. */
+ public static final int BIGNUMBER_STAR = 1;
+
+ /** POSIX/PAX extensions are used to store big numbers in the archive. */
+ public static final int BIGNUMBER_POSIX = 2;
+
+ // CheckStyle:VisibilityModifier OFF - bc
+ protected boolean debug;
+ protected long currSize;
+ protected String currName;
+ protected long currBytes;
+ protected byte[] oneBuf;
+ protected byte[] recordBuf;
+ protected int assemLen;
+ protected byte[] assemBuf;
+ protected TarBuffer buffer;
+ protected int longFileMode = LONGFILE_ERROR;
+ // CheckStyle:VisibilityModifier ON
+
+ private int bigNumberMode = BIGNUMBER_ERROR;
+
+ private boolean closed = false;
+
+ /** Indicates if putNextEntry has been called without closeEntry */
+ private boolean haveUnclosedEntry = false;
+
+ /** indicates if this archive is finished */
+ private boolean finished = false;
+
+ private final ZipEncoding encoding;
+
+ private boolean addPaxHeadersForNonAsciiNames = false;
+ private static final ZipEncoding ASCII =
+ ZipEncodingHelper.getZipEncoding("ASCII");
+
+ /**
+ * Constructor for TarInputStream.
+ * @param os the output stream to use
+ */
+ public TarOutputStream(OutputStream os) {
+ this(os, TarBuffer.DEFAULT_BLKSIZE, TarBuffer.DEFAULT_RCDSIZE);
+ }
+
+ /**
+ * Constructor for TarInputStream.
+ * @param os the output stream to use
+ * @param encoding name of the encoding to use for file names
+ */
+ public TarOutputStream(OutputStream os, String encoding) {
+ this(os, TarBuffer.DEFAULT_BLKSIZE, TarBuffer.DEFAULT_RCDSIZE, encoding);
+ }
+
+ /**
+ * Constructor for TarInputStream.
+ * @param os the output stream to use
+ * @param blockSize the block size to use
+ */
+ public TarOutputStream(OutputStream os, int blockSize) {
+ this(os, blockSize, TarBuffer.DEFAULT_RCDSIZE);
+ }
+
+ /**
+ * Constructor for TarInputStream.
+ * @param os the output stream to use
+ * @param blockSize the block size to use
+ * @param encoding name of the encoding to use for file names
+ */
+ public TarOutputStream(OutputStream os, int blockSize, String encoding) {
+ this(os, blockSize, TarBuffer.DEFAULT_RCDSIZE, encoding);
+ }
+
+ /**
+ * Constructor for TarInputStream.
+ * @param os the output stream to use
+ * @param blockSize the block size to use
+ * @param recordSize the record size to use
+ */
+ public TarOutputStream(OutputStream os, int blockSize, int recordSize) {
+ this(os, blockSize, recordSize, null);
+ }
+
+ /**
+ * Constructor for TarInputStream.
+ * @param os the output stream to use
+ * @param blockSize the block size to use
+ * @param recordSize the record size to use
+ * @param encoding name of the encoding to use for file names
+ */
+ public TarOutputStream(OutputStream os, int blockSize, int recordSize,
+ String encoding) {
+ super(os);
+ this.encoding = ZipEncodingHelper.getZipEncoding(encoding);
+
+ this.buffer = new TarBuffer(os, blockSize, recordSize);
+ this.debug = false;
+ this.assemLen = 0;
+ this.assemBuf = new byte[recordSize];
+ this.recordBuf = new byte[recordSize];
+ this.oneBuf = new byte[1];
+ }
+
+ /**
+ * Set the long file mode.
+ * This can be LONGFILE_ERROR(0), LONGFILE_TRUNCATE(1) or LONGFILE_GNU(2).
+ * This specifies the treatment of long file names (names &gt;= TarConstants.NAMELEN).
+ * Default is LONGFILE_ERROR.
+ * @param longFileMode the mode to use
+ */
+ public void setLongFileMode(int longFileMode) {
+ this.longFileMode = longFileMode;
+ }
+
+ /**
+ * Set the big number mode.
+ * This can be BIGNUMBER_ERROR(0), BIGNUMBER_POSIX(1) or BIGNUMBER_STAR(2).
+ * This specifies the treatment of big files (sizes &gt; TarConstants.MAXSIZE) and other numeric values to big to fit into a traditional tar header.
+ * Default is BIGNUMBER_ERROR.
+ * @param bigNumberMode the mode to use
+ */
+ public void setBigNumberMode(int bigNumberMode) {
+ this.bigNumberMode = bigNumberMode;
+ }
+
+ /**
+ * Whether to add a PAX extension header for non-ASCII file names.
+ */
+ public void setAddPaxHeadersForNonAsciiNames(boolean b) {
+ addPaxHeadersForNonAsciiNames = b;
+ }
+
+ /**
+ * Sets the debugging flag.
+ *
+ * @param debugF True to turn on debugging.
+ */
+ public void setDebug(boolean debugF) {
+ this.debug = debugF;
+ }
+
+ /**
+ * Sets the debugging flag in this stream's TarBuffer.
+ *
+ * @param debug True to turn on debugging.
+ */
+ public void setBufferDebug(boolean debug) {
+ buffer.setDebug(debug);
+ }
+
+ /**
+ * Ends the TAR archive without closing the underlying OutputStream.
+ *
+ * An archive consists of a series of file entries terminated by an
+ * end-of-archive entry, which consists of two 512 blocks of zero bytes.
+ * POSIX.1 requires two EOF records, like some other implementations.
+ *
+ * @throws IOException on error
+ */
+ public void finish() throws IOException {
+ if (finished) {
+ throw new IOException("This archive has already been finished");
+ }
+
+ if (haveUnclosedEntry) {
+ throw new IOException("This archives contains unclosed entries.");
+ }
+ writeEOFRecord();
+ writeEOFRecord();
+ buffer.flushBlock();
+ finished = true;
+ }
+
+ /**
+ * Ends the TAR archive and closes the underlying OutputStream.
+ * This means that finish() is called followed by calling the
+ * TarBuffer's close().
+ * @throws IOException on error
+ */
+ @Override
+ public void close() throws IOException {
+ if(!finished) {
+ finish();
+ }
+
+ if (!closed) {
+ buffer.close();
+ out.close();
+ closed = true;
+ }
+ }
+
+ /**
+ * Get the record size being used by this stream's TarBuffer.
+ *
+ * @return The TarBuffer record size.
+ */
+ public int getRecordSize() {
+ return buffer.getRecordSize();
+ }
+
+ /**
+ * Put an entry on the output stream. This writes the entry's
+ * header record and positions the output stream for writing
+ * the contents of the entry. Once this method is called, the
+ * stream is ready for calls to write() to write the entry's
+ * contents. Once the contents are written, closeEntry()
+ * <B>MUST</B> be called to ensure that all buffered data
+ * is completely written to the output stream.
+ *
+ * @param entry The TarEntry to be written to the archive.
+ * @throws IOException on error
+ */
+ public void putNextEntry(TarEntry entry) throws IOException {
+ if(finished) {
+ throw new IOException("Stream has already been finished");
+ }
+ Map<String, String> paxHeaders = new HashMap<String, String>();
+ final String entryName = entry.getName();
+ boolean paxHeaderContainsPath = handleLongName(entry, entryName, paxHeaders, "path",
+ TarConstants.LF_GNUTYPE_LONGNAME, "file name");
+
+ final String linkName = entry.getLinkName();
+ boolean paxHeaderContainsLinkPath = linkName != null && linkName.length() > 0
+ && handleLongName(entry, linkName, paxHeaders, "linkpath",
+ TarConstants.LF_GNUTYPE_LONGLINK, "link name");
+
+ if (bigNumberMode == BIGNUMBER_POSIX) {
+ addPaxHeadersForBigNumbers(paxHeaders, entry);
+ } else if (bigNumberMode != BIGNUMBER_STAR) {
+ failForBigNumbers(entry);
+ }
+
+ if (addPaxHeadersForNonAsciiNames && !paxHeaderContainsPath
+ && !ASCII.canEncode(entryName)) {
+ paxHeaders.put("path", entryName);
+ }
+
+ if (addPaxHeadersForNonAsciiNames && !paxHeaderContainsLinkPath
+ && (entry.isLink() || entry.isSymbolicLink())
+ && !ASCII.canEncode(linkName)) {
+ paxHeaders.put("linkpath", linkName);
+ }
+
+ if (paxHeaders.size() > 0) {
+ writePaxHeaders(entry, entryName, paxHeaders);
+ }
+
+ entry.writeEntryHeader(recordBuf, encoding,
+ bigNumberMode == BIGNUMBER_STAR);
+ buffer.writeRecord(recordBuf);
+
+ currBytes = 0;
+
+ if (entry.isDirectory()) {
+ currSize = 0;
+ } else {
+ currSize = entry.getSize();
+ }
+ currName = entryName;
+ haveUnclosedEntry = true;
+ }
+
+ /**
+ * Close an entry. This method MUST be called for all file
+ * entries that contain data. The reason is that we must
+ * buffer data written to the stream in order to satisfy
+ * the buffer's record based writes. Thus, there may be
+ * data fragments still being assembled that must be written
+ * to the output stream before this entry is closed and the
+ * next entry written.
+ * @throws IOException on error
+ */
+ public void closeEntry() throws IOException {
+ if (finished) {
+ throw new IOException("Stream has already been finished");
+ }
+ if (!haveUnclosedEntry){
+ throw new IOException("No current entry to close");
+ }
+ if (assemLen > 0) {
+ for (int i = assemLen; i < assemBuf.length; ++i) {
+ assemBuf[i] = 0;
+ }
+
+ buffer.writeRecord(assemBuf);
+
+ currBytes += assemLen;
+ assemLen = 0;
+ }
+
+ if (currBytes < currSize) {
+ throw new IOException("entry '" + currName + "' closed at '"
+ + currBytes
+ + "' before the '" + currSize
+ + "' bytes specified in the header were written");
+ }
+ haveUnclosedEntry = false;
+ }
+
+ /**
+ * Writes a byte to the current tar archive entry.
+ *
+ * This method simply calls read( byte[], int, int ).
+ *
+ * @param b The byte written.
+ * @throws IOException on error
+ */
+ @Override
+ public void write(int b) throws IOException {
+ oneBuf[0] = (byte) b;
+
+ write(oneBuf, 0, 1);
+ }
+
+ /**
+ * Writes bytes to the current tar archive entry.
+ *
+ * This method simply calls write( byte[], int, int ).
+ *
+ * @param wBuf The buffer to write to the archive.
+ * @throws IOException on error
+ */
+ @Override
+ public void write(byte[] wBuf) throws IOException {
+ write(wBuf, 0, wBuf.length);
+ }
+
+ /**
+ * Writes bytes to the current tar archive entry. This method
+ * is aware of the current entry and will throw an exception if
+ * you attempt to write bytes past the length specified for the
+ * current entry. The method is also (painfully) aware of the
+ * record buffering required by TarBuffer, and manages buffers
+ * that are not a multiple of recordsize in length, including
+ * assembling records from small buffers.
+ *
+ * @param wBuf The buffer to write to the archive.
+ * @param wOffset The offset in the buffer from which to get bytes.
+ * @param numToWrite The number of bytes to write.
+ * @throws IOException on error
+ */
+ @Override
+ public void write(byte[] wBuf, int wOffset, int numToWrite) throws IOException {
+ if ((currBytes + numToWrite) > currSize) {
+ throw new IOException("request to write '" + numToWrite
+ + "' bytes exceeds size in header of '"
+ + currSize + "' bytes for entry '"
+ + currName + "'");
+
+ //
+ // We have to deal with assembly!!!
+ // The programmer can be writing little 32 byte chunks for all
+ // we know, and we must assemble complete records for writing.
+ // REVIEW Maybe this should be in TarBuffer? Could that help to
+ // eliminate some of the buffer copying.
+ //
+ }
+
+ if (assemLen > 0) {
+ if ((assemLen + numToWrite) >= recordBuf.length) {
+ int aLen = recordBuf.length - assemLen;
+
+ System.arraycopy(assemBuf, 0, recordBuf, 0,
+ assemLen);
+ System.arraycopy(wBuf, wOffset, recordBuf,
+ assemLen, aLen);
+ buffer.writeRecord(recordBuf);
+
+ currBytes += recordBuf.length;
+ wOffset += aLen;
+ numToWrite -= aLen;
+ assemLen = 0;
+ } else {
+ System.arraycopy(wBuf, wOffset, assemBuf, assemLen,
+ numToWrite);
+
+ wOffset += numToWrite;
+ assemLen += numToWrite;
+ numToWrite = 0;
+ }
+ }
+
+ //
+ // When we get here we have EITHER:
+ // o An empty "assemble" buffer.
+ // o No bytes to write (numToWrite == 0)
+ //
+ while (numToWrite > 0) {
+ if (numToWrite < recordBuf.length) {
+ System.arraycopy(wBuf, wOffset, assemBuf, assemLen,
+ numToWrite);
+
+ assemLen += numToWrite;
+
+ break;
+ }
+
+ buffer.writeRecord(wBuf, wOffset);
+
+ int num = recordBuf.length;
+
+ currBytes += num;
+ numToWrite -= num;
+ wOffset += num;
+ }
+ }
+
+ /**
+ * Writes a PAX extended header with the given map as contents.
+ */
+ void writePaxHeaders(TarEntry entry,
+ String entryName,
+ Map<String, String> headers) throws IOException {
+ String name = "./PaxHeaders.X/" + stripTo7Bits(entryName);
+ if (name.length() >= TarConstants.NAMELEN) {
+ name = name.substring(0, TarConstants.NAMELEN - 1);
+ }
+ while (name.endsWith("/")) {
+ // TarEntry's constructor would think this is a directory
+ // and not allow any data to be written
+ name = name.substring(0, name.length() - 1);
+ }
+ TarEntry pex = new TarEntry(name,
+ TarConstants.LF_PAX_EXTENDED_HEADER_LC);
+ transferModTime(entry, pex);
+
+ StringWriter w = new StringWriter();
+ for (Map.Entry<String, String> h : headers.entrySet()) {
+ String key = h.getKey();
+ String value = h.getValue();
+ int len = key.length() + value.length()
+ + 3 /* blank, equals and newline */
+ + 2 /* guess 9 < actual length < 100 */;
+ String line = len + " " + key + "=" + value + "\n";
+ int actualLength = line.getBytes("UTF-8").length;
+ while (len != actualLength) {
+ // Adjust for cases where length < 10 or > 100
+ // or where UTF-8 encoding isn't a single octet
+ // per character.
+ // Must be in loop as size may go from 99 to 100 in
+ // first pass so we'd need a second.
+ len = actualLength;
+ line = len + " " + key + "=" + value + "\n";
+ actualLength = line.getBytes("UTF-8").length;
+ }
+ w.write(line);
+ }
+ byte[] data = w.toString().getBytes("UTF-8");
+ pex.setSize(data.length);
+ putNextEntry(pex);
+ write(data);
+ closeEntry();
+ }
+
+ private String stripTo7Bits(String name) {
+ final int length = name.length();
+ StringBuilder result = new StringBuilder(length);
+ for (int i = 0; i < length; i++) {
+ char stripped = (char) (name.charAt(i) & 0x7F);
+ if (stripped != 0) { // would be read as Trailing null
+ result.append(stripped);
+ }
+ }
+ return result.toString();
+ }
+
+ /**
+ * Write an EOF (end of archive) record to the tar archive.
+ * An EOF record consists of a record of all zeros.
+ */
+ private void writeEOFRecord() throws IOException {
+ for (int i = 0; i < recordBuf.length; ++i) {
+ recordBuf[i] = 0;
+ }
+
+ buffer.writeRecord(recordBuf);
+ }
+
+ private void addPaxHeadersForBigNumbers(Map<String, String> paxHeaders,
+ TarEntry entry) {
+ addPaxHeaderForBigNumber(paxHeaders, "size", entry.getSize(),
+ TarConstants.MAXSIZE);
+ addPaxHeaderForBigNumber(paxHeaders, "gid", entry.getLongGroupId(),
+ TarConstants.MAXID);
+ addPaxHeaderForBigNumber(paxHeaders, "mtime",
+ entry.getModTime().getTime() / 1000,
+ TarConstants.MAXSIZE);
+ addPaxHeaderForBigNumber(paxHeaders, "uid", entry.getLongUserId(),
+ TarConstants.MAXID);
+ // star extensions by J\u00f6rg Schilling
+ addPaxHeaderForBigNumber(paxHeaders, "SCHILY.devmajor",
+ entry.getDevMajor(), TarConstants.MAXID);
+ addPaxHeaderForBigNumber(paxHeaders, "SCHILY.devminor",
+ entry.getDevMinor(), TarConstants.MAXID);
+ // there is no PAX header for file mode
+ failForBigNumber("mode", entry.getMode(), TarConstants.MAXID);
+ }
+
+ private void addPaxHeaderForBigNumber(Map<String, String> paxHeaders,
+ String header, long value,
+ long maxValue) {
+ if (value < 0 || value > maxValue) {
+ paxHeaders.put(header, String.valueOf(value));
+ }
+ }
+
+ private void failForBigNumbers(TarEntry entry) {
+ failForBigNumber("entry size", entry.getSize(), TarConstants.MAXSIZE);
+ failForBigNumberWithPosixMessage("group id", entry.getLongGroupId(), TarConstants.MAXID);
+ failForBigNumber("last modification time",
+ entry.getModTime().getTime() / 1000,
+ TarConstants.MAXSIZE);
+ failForBigNumber("user id", entry.getLongUserId(), TarConstants.MAXID);
+ failForBigNumber("mode", entry.getMode(), TarConstants.MAXID);
+ failForBigNumber("major device number", entry.getDevMajor(),
+ TarConstants.MAXID);
+ failForBigNumber("minor device number", entry.getDevMinor(),
+ TarConstants.MAXID);
+ }
+
+ private void failForBigNumber(String field, long value, long maxValue) {
+ failForBigNumber(field, value, maxValue, "");
+ }
+
+ private void failForBigNumberWithPosixMessage(String field, long value, long maxValue) {
+ failForBigNumber(field, value, maxValue, " Use STAR or POSIX extensions to overcome this limit");
+ }
+
+ private void failForBigNumber(String field, long value, long maxValue, String additionalMsg) {
+ if (value < 0 || value > maxValue) {
+ throw new RuntimeException(field + " '" + value
+ + "' is too big ( > "
+ + maxValue + " )");
+ }
+ }
+
+ /**
+ * Handles long file or link names according to the longFileMode setting.
+ *
+ * <p>I.e. if the given name is too long to be written to a plain
+ * tar header then
+ * <ul>
+ * <li>it creates a pax header who's name is given by the
+ * paxHeaderName parameter if longFileMode is POSIX</li>
+ * <li>it creates a GNU longlink entry who's type is given by
+ * the linkType parameter if longFileMode is GNU</li>
+ * <li>it throws an exception if longFileMode is ERROR</li>
+ * <li>it truncates the name if longFileMode is TRUNCATE</li>
+ * </ul></p>
+ *
+ * @param entry entry the name belongs to
+ * @param name the name to write
+ * @param paxHeaders current map of pax headers
+ * @param paxHeaderName name of the pax header to write
+ * @param linkType type of the GNU entry to write
+ * @param fieldName the name of the field
+ * @return whether a pax header has been written.
+ */
+ private boolean handleLongName(TarEntry entry , String name,
+ Map<String, String> paxHeaders,
+ String paxHeaderName, byte linkType, String fieldName)
+ throws IOException {
+ final ByteBuffer encodedName = encoding.encode(name);
+ final int len = encodedName.limit() - encodedName.position();
+ if (len >= TarConstants.NAMELEN) {
+
+ if (longFileMode == LONGFILE_POSIX) {
+ paxHeaders.put(paxHeaderName, name);
+ return true;
+ } else if (longFileMode == LONGFILE_GNU) {
+ // create a TarEntry for the LongLink, the contents
+ // of which are the link's name
+ TarEntry longLinkEntry =
+ new TarEntry(TarConstants.GNU_LONGLINK, linkType);
+
+ longLinkEntry.setSize(len + 1); // +1 for NUL
+ transferModTime(entry, longLinkEntry);
+ putNextEntry(longLinkEntry);
+ write(encodedName.array(), encodedName.arrayOffset(), len);
+ write(0); // NUL terminator
+ closeEntry();
+ } else if (longFileMode != LONGFILE_TRUNCATE) {
+ throw new RuntimeException(fieldName + " '" + name
+ + "' is too long ( > "
+ + TarConstants.NAMELEN + " bytes)");
+ }
+ }
+ return false;
+ }
+
+ private void transferModTime(TarEntry from, TarEntry to) {
+ Date fromModTime = from.getModTime();
+ long fromModTimeSeconds = fromModTime.getTime() / 1000;
+ if (fromModTimeSeconds < 0 || fromModTimeSeconds > TarConstants.MAXSIZE) {
+ fromModTime = new Date(0);
+ }
+ to.setModTime(fromModTime);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/tar/TarUtils.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/tar/TarUtils.java
new file mode 100644
index 00000000..12bd1da3
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/tar/TarUtils.java
@@ -0,0 +1,564 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+/*
+ * This package is based on the work done by Timothy Gerard Endres
+ * (time@ice.com) to whom the Ant project is very grateful for his great code.
+ */
+
+package org.apache.tools.tar;
+
+import java.io.IOException;
+import java.math.BigInteger;
+import java.nio.ByteBuffer;
+
+import org.apache.tools.zip.ZipEncoding;
+import org.apache.tools.zip.ZipEncodingHelper;
+
+/**
+ * This class provides static utility methods to work with byte streams.
+ *
+ */
+// CheckStyle:HideUtilityClassConstructorCheck OFF (bc)
+public class TarUtils {
+
+ private static final int BYTE_MASK = 255;
+
+ static final ZipEncoding DEFAULT_ENCODING =
+ ZipEncodingHelper.getZipEncoding(null);
+
+ /**
+ * Encapsulates the algorithms used up to Ant 1.8 as ZipEncoding.
+ */
+ static final ZipEncoding FALLBACK_ENCODING = new ZipEncoding() {
+ public boolean canEncode(final String name) { return true; }
+
+ public ByteBuffer encode(final String name) {
+ final int length = name.length();
+ final byte[] buf = new byte[length];
+
+ // copy until end of input or output is reached.
+ for (int i = 0; i < length; ++i) {
+ buf[i] = (byte) name.charAt(i);
+ }
+ return ByteBuffer.wrap(buf);
+ }
+
+ public String decode(final byte[] buffer) {
+ final int length = buffer.length;
+ final StringBuilder result = new StringBuilder(length);
+
+ for (int i = 0; i < length; ++i) {
+ final byte b = buffer[i];
+ if (b == 0) { // Trailing null
+ break;
+ }
+ result.append((char) (b & 0xFF)); // Allow for sign-extension
+ }
+
+ return result.toString();
+ }
+ };
+
+ /** Private constructor to prevent instantiation of this utility class. */
+ private TarUtils(){
+ }
+
+ /**
+ * Parse an octal string from a buffer.
+ *
+ * <p>Leading spaces are ignored.
+ * The buffer must contain a trailing space or NUL,
+ * and may contain an additional trailing space or NUL.</p>
+ *
+ * <p>The input buffer is allowed to contain all NULs,
+ * in which case the method returns 0L
+ * (this allows for missing fields).</p>
+ *
+ * <p>To work-around some tar implementations that insert a
+ * leading NUL this method returns 0 if it detects a leading NUL
+ * since Ant 1.9.</p>
+ *
+ * @param buffer The buffer from which to parse.
+ * @param offset The offset into the buffer from which to parse.
+ * @param length The maximum number of bytes to parse - must be at least 2 bytes.
+ * @return The long value of the octal string.
+ * @throws IllegalArgumentException if the trailing space/NUL is missing or if a invalid byte is detected.
+ */
+ public static long parseOctal(final byte[] buffer, final int offset, final int length) {
+ long result = 0;
+ int end = offset + length;
+ int start = offset;
+
+ if (length < 2){
+ throw new IllegalArgumentException("Length "+length+" must be at least 2");
+ }
+
+ if (buffer[start] == 0) {
+ return 0L;
+ }
+
+ // Skip leading spaces
+ while (start < end){
+ if (buffer[start] == ' '){
+ start++;
+ } else {
+ break;
+ }
+ }
+
+ // Trim all trailing NULs and spaces.
+ // The ustar and POSIX tar specs require a trailing NUL or
+ // space but some implementations use the extra digit for big
+ // sizes/uids/gids ...
+ byte trailer = buffer[end - 1];
+ while (start < end && (trailer == 0 || trailer == ' ')) {
+ end--;
+ trailer = buffer[end - 1];
+ }
+
+ for ( ;start < end; start++) {
+ final byte currentByte = buffer[start];
+ // CheckStyle:MagicNumber OFF
+ if (currentByte < '0' || currentByte > '7'){
+ throw new IllegalArgumentException(
+ exceptionMessage(buffer, offset, length, start, currentByte));
+ }
+ result = (result << 3) + (currentByte - '0'); // convert from ASCII
+ // CheckStyle:MagicNumber ON
+ }
+
+ return result;
+ }
+
+ /**
+ * Compute the value contained in a byte buffer. If the most
+ * significant bit of the first byte in the buffer is set, this
+ * bit is ignored and the rest of the buffer is interpreted as a
+ * binary number. Otherwise, the buffer is interpreted as an
+ * octal number as per the parseOctal function above.
+ *
+ * @param buffer The buffer from which to parse.
+ * @param offset The offset into the buffer from which to parse.
+ * @param length The maximum number of bytes to parse.
+ * @return The long value of the octal or binary string.
+ * @throws IllegalArgumentException if the trailing space/NUL is
+ * missing or an invalid byte is detected in an octal number, or
+ * if a binary number would exceed the size of a signed long
+ * 64-bit integer.
+ */
+ public static long parseOctalOrBinary(final byte[] buffer, final int offset,
+ final int length) {
+
+ if ((buffer[offset] & 0x80) == 0) {
+ return parseOctal(buffer, offset, length);
+ }
+ final boolean negative = buffer[offset] == (byte) 0xff;
+ if (length < 9) {
+ return parseBinaryLong(buffer, offset, length, negative);
+ }
+ return parseBinaryBigInteger(buffer, offset, length, negative);
+ }
+
+ private static long parseBinaryLong(final byte[] buffer, final int offset,
+ final int length,
+ final boolean negative) {
+ if (length >= 9) {
+ throw new IllegalArgumentException("At offset " + offset + ", "
+ + length + " byte binary number"
+ + " exceeds maximum signed long"
+ + " value");
+ }
+ long val = 0;
+ for (int i = 1; i < length; i++) {
+ val = (val << 8) + (buffer[offset + i] & 0xff);
+ }
+ if (negative) {
+ // 2's complement
+ val--;
+ val ^= (long) Math.pow(2, (length - 1) * 8) - 1;
+ }
+ return negative ? -val : val;
+ }
+
+ private static long parseBinaryBigInteger(final byte[] buffer,
+ final int offset,
+ final int length,
+ final boolean negative) {
+ final byte[] remainder = new byte[length - 1];
+ System.arraycopy(buffer, offset + 1, remainder, 0, length - 1);
+ BigInteger val = new BigInteger(remainder);
+ if (negative) {
+ // 2's complement
+ val = val.add(BigInteger.valueOf(-1)).not();
+ }
+ if (val.bitLength() > 63) {
+ throw new IllegalArgumentException("At offset " + offset + ", "
+ + length + " byte binary number"
+ + " exceeds maximum signed long"
+ + " value");
+ }
+ return negative ? -val.longValue() : val.longValue();
+ }
+
+ /**
+ * Parse a boolean byte from a buffer.
+ * Leading spaces and NUL are ignored.
+ * The buffer may contain trailing spaces or NULs.
+ *
+ * @param buffer The buffer from which to parse.
+ * @param offset The offset into the buffer from which to parse.
+ * @return The boolean value of the bytes.
+ * @throws IllegalArgumentException if an invalid byte is detected.
+ */
+ public static boolean parseBoolean(final byte[] buffer, final int offset) {
+ return buffer[offset] == 1;
+ }
+
+ // Helper method to generate the exception message
+ private static String exceptionMessage(final byte[] buffer, final int offset,
+ final int length, final int current, final byte currentByte) {
+ // default charset is good enough for an exception message,
+ //
+ // the alternative was to modify parseOctal and
+ // parseOctalOrBinary to receive the ZipEncoding of the
+ // archive (deprecating the existing public methods, of
+ // course) and dealing with the fact that ZipEncoding#decode
+ // can throw an IOException which parseOctal* doesn't declare
+ String string = new String(buffer, offset, length);
+
+ string=string.replaceAll("\0", "{NUL}"); // Replace NULs to allow string to be printed
+ final String s = "Invalid byte "+currentByte+" at offset "+(current-offset)+" in '"+string+"' len="+length;
+ return s;
+ }
+
+ /**
+ * Parse an entry name from a buffer.
+ * Parsing stops when a NUL is found
+ * or the buffer length is reached.
+ *
+ * @param buffer The buffer from which to parse.
+ * @param offset The offset into the buffer from which to parse.
+ * @param length The maximum number of bytes to parse.
+ * @return The entry name.
+ */
+ public static String parseName(final byte[] buffer, final int offset, final int length) {
+ try {
+ return parseName(buffer, offset, length, DEFAULT_ENCODING);
+ } catch (final IOException ex) {
+ try {
+ return parseName(buffer, offset, length, FALLBACK_ENCODING);
+ } catch (final IOException ex2) {
+ // impossible
+ throw new RuntimeException(ex2);
+ }
+ }
+ }
+
+ /**
+ * Parse an entry name from a buffer.
+ * Parsing stops when a NUL is found
+ * or the buffer length is reached.
+ *
+ * @param buffer The buffer from which to parse.
+ * @param offset The offset into the buffer from which to parse.
+ * @param length The maximum number of bytes to parse.
+ * @param encoding name of the encoding to use for file names
+ * @return The entry name.
+ */
+ public static String parseName(final byte[] buffer, final int offset,
+ final int length,
+ final ZipEncoding encoding)
+ throws IOException {
+
+ int len = length;
+ for (; len > 0; len--) {
+ if (buffer[offset + len - 1] != 0) {
+ break;
+ }
+ }
+ if (len > 0) {
+ final byte[] b = new byte[len];
+ System.arraycopy(buffer, offset, b, 0, len);
+ return encoding.decode(b);
+ }
+ return "";
+ }
+
+ /**
+ * Copy a name into a buffer.
+ * Copies characters from the name into the buffer
+ * starting at the specified offset.
+ * If the buffer is longer than the name, the buffer
+ * is filled with trailing NULs.
+ * If the name is longer than the buffer,
+ * the output is truncated.
+ *
+ * @param name The header name from which to copy the characters.
+ * @param buf The buffer where the name is to be stored.
+ * @param offset The starting offset into the buffer
+ * @param length The maximum number of header bytes to copy.
+ * @return The updated offset, i.e. offset + length
+ */
+ public static int formatNameBytes(final String name, final byte[] buf, final int offset, final int length) {
+ try {
+ return formatNameBytes(name, buf, offset, length, DEFAULT_ENCODING);
+ } catch (final IOException ex) {
+ try {
+ return formatNameBytes(name, buf, offset, length,
+ FALLBACK_ENCODING);
+ } catch (final IOException ex2) {
+ // impossible
+ throw new RuntimeException(ex2);
+ }
+ }
+ }
+
+ /**
+ * Copy a name into a buffer.
+ * Copies characters from the name into the buffer
+ * starting at the specified offset.
+ * If the buffer is longer than the name, the buffer
+ * is filled with trailing NULs.
+ * If the name is longer than the buffer,
+ * the output is truncated.
+ *
+ * @param name The header name from which to copy the characters.
+ * @param buf The buffer where the name is to be stored.
+ * @param offset The starting offset into the buffer
+ * @param length The maximum number of header bytes to copy.
+ * @param encoding name of the encoding to use for file names
+ * @return The updated offset, i.e. offset + length
+ */
+ public static int formatNameBytes(final String name, final byte[] buf, final int offset,
+ final int length,
+ final ZipEncoding encoding)
+ throws IOException {
+ int len = name.length();
+ ByteBuffer b = encoding.encode(name);
+ while (b.limit() > length && len > 0) {
+ b = encoding.encode(name.substring(0, --len));
+ }
+ final int limit = b.limit() - b.position();
+ System.arraycopy(b.array(), b.arrayOffset(), buf, offset, limit);
+
+ // Pad any remaining output bytes with NUL
+ for (int i = limit; i < length; ++i) {
+ buf[offset + i] = 0;
+ }
+
+ return offset + length;
+ }
+
+ /**
+ * Fill buffer with unsigned octal number, padded with leading zeroes.
+ *
+ * @param value number to convert to octal - treated as unsigned
+ * @param buffer destination buffer
+ * @param offset starting offset in buffer
+ * @param length length of buffer to fill
+ * @throws IllegalArgumentException if the value will not fit in the buffer
+ */
+ public static void formatUnsignedOctalString(final long value, final byte[] buffer,
+ final int offset, final int length) {
+ int remaining = length;
+ remaining--;
+ if (value == 0) {
+ buffer[offset + remaining--] = (byte) '0';
+ } else {
+ long val = value;
+ for (; remaining >= 0 && val != 0; --remaining) {
+ // CheckStyle:MagicNumber OFF
+ buffer[offset + remaining] = (byte) ((byte) '0' + (byte) (val & 7));
+ val = val >>> 3;
+ // CheckStyle:MagicNumber ON
+ }
+ if (val != 0){
+ throw new IllegalArgumentException
+ (value+"="+Long.toOctalString(value)+ " will not fit in octal number buffer of length "+length);
+ }
+ }
+
+ for (; remaining >= 0; --remaining) { // leading zeros
+ buffer[offset + remaining] = (byte) '0';
+ }
+ }
+
+ /**
+ * Write an octal integer into a buffer.
+ *
+ * Uses {@link #formatUnsignedOctalString} to format
+ * the value as an octal string with leading zeros.
+ * The converted number is followed by space and NUL
+ *
+ * @param value The value to write
+ * @param buf The buffer to receive the output
+ * @param offset The starting offset into the buffer
+ * @param length The size of the output buffer
+ * @return The updated offset, i.e offset+length
+ * @throws IllegalArgumentException if the value (and trailer) will not fit in the buffer
+ */
+ public static int formatOctalBytes(final long value, final byte[] buf, final int offset, final int length) {
+
+ int idx=length-2; // For space and trailing null
+ formatUnsignedOctalString(value, buf, offset, idx);
+
+ buf[offset + idx++] = (byte) ' '; // Trailing space
+ buf[offset + idx] = 0; // Trailing null
+
+ return offset + length;
+ }
+
+ /**
+ * Write an octal long integer into a buffer.
+ *
+ * Uses {@link #formatUnsignedOctalString} to format
+ * the value as an octal string with leading zeros.
+ * The converted number is followed by a space.
+ *
+ * @param value The value to write as octal
+ * @param buf The destinationbuffer.
+ * @param offset The starting offset into the buffer.
+ * @param length The length of the buffer
+ * @return The updated offset
+ * @throws IllegalArgumentException if the value (and trailer) will not fit in the buffer
+ */
+ public static int formatLongOctalBytes(final long value, final byte[] buf, final int offset, final int length) {
+
+ final int idx=length-1; // For space
+
+ formatUnsignedOctalString(value, buf, offset, idx);
+ buf[offset + idx] = (byte) ' '; // Trailing space
+
+ return offset + length;
+ }
+
+ /**
+ * Write an long integer into a buffer as an octal string if this
+ * will fit, or as a binary number otherwise.
+ *
+ * Uses {@link #formatUnsignedOctalString} to format
+ * the value as an octal string with leading zeros.
+ * The converted number is followed by a space.
+ *
+ * @param value The value to write into the buffer.
+ * @param buf The destination buffer.
+ * @param offset The starting offset into the buffer.
+ * @param length The length of the buffer.
+ * @return The updated offset.
+ * @throws IllegalArgumentException if the value (and trailer)
+ * will not fit in the buffer.
+ */
+ public static int formatLongOctalOrBinaryBytes(
+ final long value, final byte[] buf, final int offset, final int length) {
+
+ // Check whether we are dealing with UID/GID or SIZE field
+ final long maxAsOctalChar = length == TarConstants.UIDLEN ? TarConstants.MAXID : TarConstants.MAXSIZE;
+
+ final boolean negative = value < 0;
+ if (!negative && value <= maxAsOctalChar) { // OK to store as octal chars
+ return formatLongOctalBytes(value, buf, offset, length);
+ }
+
+ if (length < 9) {
+ formatLongBinary(value, buf, offset, length, negative);
+ }
+ formatBigIntegerBinary(value, buf, offset, length, negative);
+
+ buf[offset] = (byte) (negative ? 0xff : 0x80);
+ return offset + length;
+ }
+
+ private static void formatLongBinary(final long value, final byte[] buf,
+ final int offset, final int length,
+ final boolean negative) {
+ final int bits = (length - 1) * 8;
+ final long max = 1L << bits;
+ long val = Math.abs(value);
+ if (val >= max) {
+ throw new IllegalArgumentException("Value " + value +
+ " is too large for " + length + " byte field.");
+ }
+ if (negative) {
+ val ^= max - 1;
+ val |= 0xff << bits;
+ val++;
+ }
+ for (int i = offset + length - 1; i >= offset; i--) {
+ buf[i] = (byte) val;
+ val >>= 8;
+ }
+ }
+
+ private static void formatBigIntegerBinary(final long value, final byte[] buf,
+ final int offset,
+ final int length,
+ final boolean negative) {
+ final BigInteger val = BigInteger.valueOf(value);
+ final byte[] b = val.toByteArray();
+ final int len = b.length;
+ final int off = offset + length - len;
+ System.arraycopy(b, 0, buf, off, len);
+ final byte fill = (byte) (negative ? 0xff : 0);
+ for (int i = offset + 1; i < off; i++) {
+ buf[i] = fill;
+ }
+ }
+
+ /**
+ * Writes an octal value into a buffer.
+ *
+ * Uses {@link #formatUnsignedOctalString} to format
+ * the value as an octal string with leading zeros.
+ * The converted number is followed by NUL and then space.
+ *
+ * @param value The value to convert
+ * @param buf The destination buffer
+ * @param offset The starting offset into the buffer.
+ * @param length The size of the buffer.
+ * @return The updated value of offset, i.e. offset+length
+ * @throws IllegalArgumentException if the value (and trailer) will not fit in the buffer
+ */
+ public static int formatCheckSumOctalBytes(final long value, final byte[] buf, final int offset, final int length) {
+
+ int idx=length-2; // for NUL and space
+ formatUnsignedOctalString(value, buf, offset, idx);
+
+ buf[offset + idx++] = 0; // Trailing null
+ buf[offset + idx] = (byte) ' '; // Trailing space
+
+ return offset + length;
+ }
+
+ /**
+ * Compute the checksum of a tar entry header.
+ *
+ * @param buf The tar entry's header buffer.
+ * @return The computed checksum.
+ */
+ public static long computeCheckSum(final byte[] buf) {
+ long sum = 0;
+
+ for (final byte element : buf) {
+ sum += BYTE_MASK & element;
+ }
+
+ return sum;
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/AbstractUnicodeExtraField.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/AbstractUnicodeExtraField.java
new file mode 100644
index 00000000..1014787d
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/AbstractUnicodeExtraField.java
@@ -0,0 +1,183 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.zip;
+
+import java.io.UnsupportedEncodingException;
+import java.util.zip.CRC32;
+import java.util.zip.ZipException;
+
+/**
+ * A common base class for Unicode extra information extra fields.
+ */
+public abstract class AbstractUnicodeExtraField implements ZipExtraField {
+ private long nameCRC32;
+ private byte[] unicodeName;
+ private byte[] data;
+
+ protected AbstractUnicodeExtraField() {
+ }
+
+ /**
+ * Assemble as unicode extension from the name/comment and
+ * encoding of the original zip entry.
+ *
+ * @param text The file name or comment.
+ * @param bytes The encoded of the filename or comment in the zip
+ * file.
+ * @param off The offset of the encoded filename or comment in
+ * <code>bytes</code>.
+ * @param len The length of the encoded filename or commentin
+ * <code>bytes</code>.
+ */
+ protected AbstractUnicodeExtraField(final String text, final byte[] bytes, final int off,
+ final int len) {
+ final CRC32 crc32 = new CRC32();
+ crc32.update(bytes, off, len);
+ nameCRC32 = crc32.getValue();
+
+ try {
+ unicodeName = text.getBytes("UTF-8");
+ } catch (final UnsupportedEncodingException e) {
+ throw new RuntimeException("FATAL: UTF-8 encoding not supported.",
+ e);
+ }
+ }
+
+ /**
+ * Assemble as unicode extension from the name/comment and
+ * encoding of the original zip entry.
+ *
+ * @param text The file name or comment.
+ * @param bytes The encoded of the filename or comment in the zip
+ * file.
+ */
+ protected AbstractUnicodeExtraField(final String text, final byte[] bytes) {
+
+ this(text, bytes, 0, bytes.length);
+ }
+
+ private void assembleData() {
+ if (unicodeName == null) {
+ return;
+ }
+
+ data = new byte[5 + unicodeName.length];
+ // version 1
+ data[0] = 0x01;
+ System.arraycopy(ZipLong.getBytes(nameCRC32), 0, data, 1, 4);
+ System.arraycopy(unicodeName, 0, data, 5, unicodeName.length);
+ }
+
+ /**
+ * @return The CRC32 checksum of the filename or comment as
+ * encoded in the central directory of the zip file.
+ */
+ public long getNameCRC32() {
+ return nameCRC32;
+ }
+
+ /**
+ * @param nameCRC32 The CRC32 checksum of the filename as encoded
+ * in the central directory of the zip file to set.
+ */
+ public void setNameCRC32(final long nameCRC32) {
+ this.nameCRC32 = nameCRC32;
+ data = null;
+ }
+
+ /**
+ * @return The utf-8 encoded name.
+ */
+ public byte[] getUnicodeName() {
+ byte[] b = null;
+ if (unicodeName != null) {
+ b = new byte[unicodeName.length];
+ System.arraycopy(unicodeName, 0, b, 0, b.length);
+ }
+ return b;
+ }
+
+ /**
+ * @param unicodeName The utf-8 encoded name to set.
+ */
+ public void setUnicodeName(final byte[] unicodeName) {
+ if (unicodeName != null) {
+ this.unicodeName = new byte[unicodeName.length];
+ System.arraycopy(unicodeName, 0, this.unicodeName, 0,
+ unicodeName.length);
+ } else {
+ this.unicodeName = null;
+ }
+ data = null;
+ }
+
+ /** {@inheritDoc} */
+ public byte[] getCentralDirectoryData() {
+ if (data == null) {
+ this.assembleData();
+ }
+ byte[] b = null;
+ if (data != null) {
+ b = new byte[data.length];
+ System.arraycopy(data, 0, b, 0, b.length);
+ }
+ return b;
+ }
+
+ /** {@inheritDoc} */
+ public ZipShort getCentralDirectoryLength() {
+ if (data == null) {
+ assembleData();
+ }
+ return new ZipShort(data.length);
+ }
+
+ /** {@inheritDoc} */
+ public byte[] getLocalFileDataData() {
+ return getCentralDirectoryData();
+ }
+
+ /** {@inheritDoc} */
+ public ZipShort getLocalFileDataLength() {
+ return getCentralDirectoryLength();
+ }
+
+ /** {@inheritDoc} */
+ public void parseFromLocalFileData(final byte[] buffer, final int offset, final int length)
+ throws ZipException {
+
+ if (length < 5) {
+ throw new ZipException("UniCode path extra data must have at least"
+ + " 5 bytes.");
+ }
+
+ final int version = buffer[offset];
+
+ if (version != 0x01) {
+ throw new ZipException("Unsupported version [" + version
+ + "] for UniCode path extra data.");
+ }
+
+ nameCRC32 = ZipLong.getValue(buffer, offset + 1);
+ unicodeName = new byte[length - 5];
+ System.arraycopy(buffer, offset + 5, unicodeName, 0, length - 5);
+ data = null;
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/AsiExtraField.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/AsiExtraField.java
new file mode 100644
index 00000000..d2ca6910
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/AsiExtraField.java
@@ -0,0 +1,352 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.zip;
+
+import java.util.zip.CRC32;
+import java.util.zip.ZipException;
+
+/**
+ * Adds Unix file permission and UID/GID fields as well as symbolic
+ * link handling.
+ *
+ * <p>This class uses the ASi extra field in the format:
+ * <pre>
+ * Value Size Description
+ * ----- ---- -----------
+ * (Unix3) 0x756e Short tag for this extra block type
+ * TSize Short total data size for this block
+ * CRC Long CRC-32 of the remaining data
+ * Mode Short file permissions
+ * SizDev Long symlink'd size OR major/minor dev num
+ * UID Short user ID
+ * GID Short group ID
+ * (var.) variable symbolic link filename
+ * </pre>
+ * taken from appnote.iz (Info-ZIP note, 981119) found at <a
+ * href="ftp://ftp.uu.net/pub/archiving/zip/doc/">ftp://ftp.uu.net/pub/archiving/zip/doc/</a></p>
+
+ *
+ * <p>Short is two bytes and Long is four bytes in big endian byte and
+ * word order, device numbers are currently not supported.</p>
+ *
+ * <p>Since the documentation this class is based upon doesn't mention
+ * the character encoding of the file name at all, it is assumed that
+ * it uses the current platform's default encoding.</p>
+ */
+public class AsiExtraField implements ZipExtraField, UnixStat, Cloneable {
+
+ private static final ZipShort HEADER_ID = new ZipShort(0x756E);
+ private static final int WORD = 4;
+ /**
+ * Standard Unix stat(2) file mode.
+ *
+ * @since 1.1
+ */
+ private int mode = 0;
+ /**
+ * User ID.
+ *
+ * @since 1.1
+ */
+ private int uid = 0;
+ /**
+ * Group ID.
+ *
+ * @since 1.1
+ */
+ private int gid = 0;
+ /**
+ * File this entry points to, if it is a symbolic link.
+ *
+ * <p>empty string - if entry is not a symbolic link.</p>
+ *
+ * @since 1.1
+ */
+ private String link = "";
+ /**
+ * Is this an entry for a directory?
+ *
+ * @since 1.1
+ */
+ private boolean dirFlag = false;
+
+ /**
+ * Instance used to calculate checksums.
+ *
+ * @since 1.1
+ */
+ private CRC32 crc = new CRC32();
+
+ /** Constructor for AsiExtraField. */
+ public AsiExtraField() {
+ }
+
+ /**
+ * The Header-ID.
+ * @return the value for the header id for this extrafield
+ * @since 1.1
+ */
+ public ZipShort getHeaderId() {
+ return HEADER_ID;
+ }
+
+ /**
+ * Length of the extra field in the local file data - without
+ * Header-ID or length specifier.
+ * @return a <code>ZipShort</code> for the length of the data of this extra field
+ * @since 1.1
+ */
+ public ZipShort getLocalFileDataLength() {
+ return new ZipShort(WORD // CRC
+ + 2 // Mode
+ + WORD // SizDev
+ + 2 // UID
+ + 2 // GID
+ + getLinkedFile().getBytes().length);
+ // Uses default charset - see class Javadoc
+ }
+
+ /**
+ * Delegate to local file data.
+ * @return the centralDirectory length
+ * @since 1.1
+ */
+ public ZipShort getCentralDirectoryLength() {
+ return getLocalFileDataLength();
+ }
+
+ /**
+ * The actual data to put into local file data - without Header-ID
+ * or length specifier.
+ * @return get the data
+ * @since 1.1
+ */
+ public byte[] getLocalFileDataData() {
+ // CRC will be added later
+ byte[] data = new byte[getLocalFileDataLength().getValue() - WORD];
+ System.arraycopy(ZipShort.getBytes(getMode()), 0, data, 0, 2);
+
+ byte[] linkArray = getLinkedFile().getBytes(); // Uses default charset - see class Javadoc
+ // CheckStyle:MagicNumber OFF
+ System.arraycopy(ZipLong.getBytes(linkArray.length),
+ 0, data, 2, WORD);
+
+ System.arraycopy(ZipShort.getBytes(getUserId()),
+ 0, data, 6, 2);
+ System.arraycopy(ZipShort.getBytes(getGroupId()),
+ 0, data, 8, 2);
+
+ System.arraycopy(linkArray, 0, data, 10, linkArray.length);
+ // CheckStyle:MagicNumber ON
+
+ crc.reset();
+ crc.update(data);
+ long checksum = crc.getValue();
+
+ byte[] result = new byte[data.length + WORD];
+ System.arraycopy(ZipLong.getBytes(checksum), 0, result, 0, WORD);
+ System.arraycopy(data, 0, result, WORD, data.length);
+ return result;
+ }
+
+ /**
+ * Delegate to local file data.
+ * @return the local file data
+ * @since 1.1
+ */
+ public byte[] getCentralDirectoryData() {
+ return getLocalFileDataData();
+ }
+
+ /**
+ * Set the user id.
+ * @param uid the user id
+ * @since 1.1
+ */
+ public void setUserId(int uid) {
+ this.uid = uid;
+ }
+
+ /**
+ * Get the user id.
+ * @return the user id
+ * @since 1.1
+ */
+ public int getUserId() {
+ return uid;
+ }
+
+ /**
+ * Set the group id.
+ * @param gid the group id
+ * @since 1.1
+ */
+ public void setGroupId(int gid) {
+ this.gid = gid;
+ }
+
+ /**
+ * Get the group id.
+ * @return the group id
+ * @since 1.1
+ */
+ public int getGroupId() {
+ return gid;
+ }
+
+ /**
+ * Indicate that this entry is a symbolic link to the given filename.
+ *
+ * @param name Name of the file this entry links to, empty String
+ * if it is not a symbolic link.
+ *
+ * @since 1.1
+ */
+ public void setLinkedFile(String name) {
+ link = name;
+ mode = getMode(mode);
+ }
+
+ /**
+ * Name of linked file
+ *
+ * @return name of the file this entry links to if it is a
+ * symbolic link, the empty string otherwise.
+ *
+ * @since 1.1
+ */
+ public String getLinkedFile() {
+ return link;
+ }
+
+ /**
+ * Is this entry a symbolic link?
+ * @return true if this is a symbolic link
+ * @since 1.1
+ */
+ public boolean isLink() {
+ return getLinkedFile().length() != 0;
+ }
+
+ /**
+ * File mode of this file.
+ * @param mode the file mode
+ * @since 1.1
+ */
+ public void setMode(int mode) {
+ this.mode = getMode(mode);
+ }
+
+ /**
+ * File mode of this file.
+ * @return the file mode
+ * @since 1.1
+ */
+ public int getMode() {
+ return mode;
+ }
+
+ /**
+ * Indicate whether this entry is a directory.
+ * @param dirFlag if true, this entry is a directory
+ * @since 1.1
+ */
+ public void setDirectory(boolean dirFlag) {
+ this.dirFlag = dirFlag;
+ mode = getMode(mode);
+ }
+
+ /**
+ * Is this entry a directory?
+ * @return true if this entry is a directory
+ * @since 1.1
+ */
+ public boolean isDirectory() {
+ return dirFlag && !isLink();
+ }
+
+ /**
+ * Populate data from this array as if it was in local file data.
+ * @param data an array of bytes
+ * @param offset the start offset
+ * @param length the number of bytes in the array from offset
+ * @since 1.1
+ * @throws ZipException on error
+ */
+ public void parseFromLocalFileData(byte[] data, int offset, int length)
+ throws ZipException {
+
+ long givenChecksum = ZipLong.getValue(data, offset);
+ byte[] tmp = new byte[length - WORD];
+ System.arraycopy(data, offset + WORD, tmp, 0, length - WORD);
+ crc.reset();
+ crc.update(tmp);
+ long realChecksum = crc.getValue();
+ if (givenChecksum != realChecksum) {
+ throw new ZipException("bad CRC checksum "
+ + Long.toHexString(givenChecksum)
+ + " instead of "
+ + Long.toHexString(realChecksum));
+ }
+
+ int newMode = ZipShort.getValue(tmp, 0);
+ // CheckStyle:MagicNumber OFF
+ byte[] linkArray = new byte[(int) ZipLong.getValue(tmp, 2)];
+ uid = ZipShort.getValue(tmp, 6);
+ gid = ZipShort.getValue(tmp, 8);
+
+ if (linkArray.length == 0) {
+ link = "";
+ } else {
+ System.arraycopy(tmp, 10, linkArray, 0, linkArray.length);
+ link = new String(linkArray); // Uses default charset - see class Javadoc
+ }
+ // CheckStyle:MagicNumber ON
+ setDirectory((newMode & DIR_FLAG) != 0);
+ setMode(newMode);
+ }
+
+ /**
+ * Get the file mode for given permissions with the correct file type.
+ * @param mode the mode
+ * @return the type with the mode
+ * @since 1.1
+ */
+ protected int getMode(int mode) {
+ int type = FILE_FLAG;
+ if (isLink()) {
+ type = LINK_FLAG;
+ } else if (isDirectory()) {
+ type = DIR_FLAG;
+ }
+ return type | (mode & PERM_MASK);
+ }
+
+ @Override
+ public Object clone() {
+ try {
+ AsiExtraField cloned = (AsiExtraField) super.clone();
+ cloned.crc = new CRC32();
+ return cloned;
+ } catch (CloneNotSupportedException cnfe) {
+ // impossible
+ throw new RuntimeException(cnfe);
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/CentralDirectoryParsingZipExtraField.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/CentralDirectoryParsingZipExtraField.java
new file mode 100644
index 00000000..738ed625
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/CentralDirectoryParsingZipExtraField.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.zip;
+
+import java.util.zip.ZipException;
+
+/**
+ * {@link ZipExtraField ZipExtraField} that knows how to parse central
+ * directory data.
+ *
+ * @since Ant 1.8.0
+ */
+public interface CentralDirectoryParsingZipExtraField extends ZipExtraField {
+ /**
+ * Populate data from this array as if it was in central directory data.
+ * @param data an array of bytes
+ * @param offset the start offset
+ * @param length the number of bytes in the array from offset
+ *
+ * @throws ZipException on error
+ */
+ void parseFromCentralDirectoryData(byte[] data, int offset, int length)
+ throws ZipException;
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/ExtraFieldUtils.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/ExtraFieldUtils.java
new file mode 100644
index 00000000..a6c0118f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/ExtraFieldUtils.java
@@ -0,0 +1,314 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.zip;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.zip.ZipException;
+
+/**
+ * ZipExtraField related methods
+ *
+ */
+// CheckStyle:HideUtilityClassConstructorCheck OFF (bc)
+public class ExtraFieldUtils {
+
+ private static final int WORD = 4;
+
+ /**
+ * Static registry of known extra fields.
+ *
+ * @since 1.1
+ */
+ private static final Map<ZipShort, Class<?>> implementations;
+
+ static {
+ implementations = new ConcurrentHashMap<ZipShort, Class<?>>();
+ register(AsiExtraField.class);
+ register(JarMarker.class);
+ register(UnicodePathExtraField.class);
+ register(UnicodeCommentExtraField.class);
+ register(Zip64ExtendedInformationExtraField.class);
+ }
+
+ /**
+ * Register a ZipExtraField implementation.
+ *
+ * <p>The given class must have a no-arg constructor and implement
+ * the {@link ZipExtraField ZipExtraField interface}.</p>
+ * @param c the class to register
+ *
+ * @since 1.1
+ */
+ public static void register(Class<?> c) {
+ try {
+ ZipExtraField ze = (ZipExtraField) c.newInstance();
+ implementations.put(ze.getHeaderId(), c);
+ } catch (ClassCastException cc) {
+ throw new RuntimeException(c + " doesn\'t implement ZipExtraField");
+ } catch (InstantiationException ie) {
+ throw new RuntimeException(c + " is not a concrete class");
+ } catch (IllegalAccessException ie) {
+ throw new RuntimeException(c + "\'s no-arg constructor is not public");
+ }
+ }
+
+ /**
+ * Create an instance of the appropriate ExtraField, falls back to
+ * {@link UnrecognizedExtraField UnrecognizedExtraField}.
+ * @param headerId the header identifier
+ * @return an instance of the appropriate ExtraField
+ * @exception InstantiationException if unable to instantiate the class
+ * @exception IllegalAccessException if not allowed to instantiate the class
+ * @since 1.1
+ */
+ public static ZipExtraField createExtraField(ZipShort headerId)
+ throws InstantiationException, IllegalAccessException {
+ Class<?> c = implementations.get(headerId);
+ if (c != null) {
+ return (ZipExtraField) c.newInstance();
+ }
+ UnrecognizedExtraField u = new UnrecognizedExtraField();
+ u.setHeaderId(headerId);
+ return u;
+ }
+
+ /**
+ * Split the array into ExtraFields and populate them with the
+ * given data as local file data, throwing an exception if the
+ * data cannot be parsed.
+ * @param data an array of bytes as it appears in local file data
+ * @return an array of ExtraFields
+ * @throws ZipException on error
+ */
+ public static ZipExtraField[] parse(byte[] data) throws ZipException {
+ return parse(data, true, UnparseableExtraField.THROW);
+ }
+
+ /**
+ * Split the array into ExtraFields and populate them with the
+ * given data, throwing an exception if the data cannot be parsed.
+ * @param data an array of bytes
+ * @param local whether data originates from the local file data
+ * or the central directory
+ * @return an array of ExtraFields
+ * @since 1.1
+ * @throws ZipException on error
+ */
+ public static ZipExtraField[] parse(byte[] data, boolean local)
+ throws ZipException {
+ return parse(data, local, UnparseableExtraField.THROW);
+ }
+
+ /**
+ * Split the array into ExtraFields and populate them with the
+ * given data.
+ * @param data an array of bytes
+ * @param local whether data originates from the local file data
+ * or the central directory
+ * @param onUnparseableData what to do if the extra field data
+ * cannot be parsed.
+ * @return an array of ExtraFields
+ * @throws ZipException on error
+ * @since Ant 1.8.1
+ */
+ public static ZipExtraField[] parse(byte[] data, boolean local,
+ UnparseableExtraField onUnparseableData)
+ throws ZipException {
+ List<ZipExtraField> v = new ArrayList<ZipExtraField>();
+ int start = 0;
+ LOOP:
+ while (start <= data.length - WORD) {
+ ZipShort headerId = new ZipShort(data, start);
+ int length = (new ZipShort(data, start + 2)).getValue();
+ if (start + WORD + length > data.length) {
+ switch(onUnparseableData.getKey()) {
+ case UnparseableExtraField.THROW_KEY:
+ throw new ZipException("bad extra field starting at "
+ + start + ". Block length of "
+ + length + " bytes exceeds remaining"
+ + " data of "
+ + (data.length - start - WORD)
+ + " bytes.");
+ case UnparseableExtraField.READ_KEY:
+ UnparseableExtraFieldData field =
+ new UnparseableExtraFieldData();
+ if (local) {
+ field.parseFromLocalFileData(data, start,
+ data.length - start);
+ } else {
+ field.parseFromCentralDirectoryData(data, start,
+ data.length - start);
+ }
+ v.add(field);
+ //$FALL-THROUGH$
+ case UnparseableExtraField.SKIP_KEY:
+ // since we cannot parse the data we must assume
+ // the extra field consumes the whole rest of the
+ // available data
+ break LOOP;
+ default:
+ throw new ZipException("unknown UnparseableExtraField key: "
+ + onUnparseableData.getKey());
+ }
+ }
+ try {
+ ZipExtraField ze = createExtraField(headerId);
+ if (local
+ || !(ze instanceof CentralDirectoryParsingZipExtraField)) {
+ ze.parseFromLocalFileData(data, start + WORD, length);
+ } else {
+ ((CentralDirectoryParsingZipExtraField) ze)
+ .parseFromCentralDirectoryData(data, start + WORD,
+ length);
+ }
+ v.add(ze);
+ } catch (InstantiationException ie) {
+ throw new ZipException(ie.getMessage());
+ } catch (IllegalAccessException iae) {
+ throw new ZipException(iae.getMessage());
+ }
+ start += (length + WORD);
+ }
+
+ ZipExtraField[] result = new ZipExtraField[v.size()];
+ return v.toArray(result);
+ }
+
+ /**
+ * Merges the local file data fields of the given ZipExtraFields.
+ * @param data an array of ExtraFiles
+ * @return an array of bytes
+ * @since 1.1
+ */
+ public static byte[] mergeLocalFileDataData(ZipExtraField[] data) {
+ final boolean lastIsUnparseableHolder = data.length > 0
+ && data[data.length - 1] instanceof UnparseableExtraFieldData;
+ int regularExtraFieldCount =
+ lastIsUnparseableHolder ? data.length - 1 : data.length;
+
+ int sum = WORD * regularExtraFieldCount;
+ for (ZipExtraField element : data) {
+ sum += element.getLocalFileDataLength().getValue();
+ }
+
+ byte[] result = new byte[sum];
+ int start = 0;
+ for (int i = 0; i < regularExtraFieldCount; i++) {
+ System.arraycopy(data[i].getHeaderId().getBytes(),
+ 0, result, start, 2);
+ System.arraycopy(data[i].getLocalFileDataLength().getBytes(),
+ 0, result, start + 2, 2);
+ byte[] local = data[i].getLocalFileDataData();
+ System.arraycopy(local, 0, result, start + WORD, local.length);
+ start += (local.length + WORD);
+ }
+ if (lastIsUnparseableHolder) {
+ byte[] local = data[data.length - 1].getLocalFileDataData();
+ System.arraycopy(local, 0, result, start, local.length);
+ }
+ return result;
+ }
+
+ /**
+ * Merges the central directory fields of the given ZipExtraFields.
+ * @param data an array of ExtraFields
+ * @return an array of bytes
+ * @since 1.1
+ */
+ public static byte[] mergeCentralDirectoryData(ZipExtraField[] data) {
+ final boolean lastIsUnparseableHolder = data.length > 0
+ && data[data.length - 1] instanceof UnparseableExtraFieldData;
+ int regularExtraFieldCount =
+ lastIsUnparseableHolder ? data.length - 1 : data.length;
+
+ int sum = WORD * regularExtraFieldCount;
+ for (ZipExtraField element : data) {
+ sum += element.getCentralDirectoryLength().getValue();
+ }
+ byte[] result = new byte[sum];
+ int start = 0;
+ for (int i = 0; i < regularExtraFieldCount; i++) {
+ System.arraycopy(data[i].getHeaderId().getBytes(),
+ 0, result, start, 2);
+ System.arraycopy(data[i].getCentralDirectoryLength().getBytes(),
+ 0, result, start + 2, 2);
+ byte[] local = data[i].getCentralDirectoryData();
+ System.arraycopy(local, 0, result, start + WORD, local.length);
+ start += (local.length + WORD);
+ }
+ if (lastIsUnparseableHolder) {
+ byte[] local = data[data.length - 1].getCentralDirectoryData();
+ System.arraycopy(local, 0, result, start, local.length);
+ }
+ return result;
+ }
+
+ /**
+ * "enum" for the possible actions to take if the extra field
+ * cannot be parsed.
+ */
+ public static final class UnparseableExtraField {
+ /**
+ * Key for "throw an exception" action.
+ */
+ public static final int THROW_KEY = 0;
+ /**
+ * Key for "skip" action.
+ */
+ public static final int SKIP_KEY = 1;
+ /**
+ * Key for "read" action.
+ */
+ public static final int READ_KEY = 2;
+
+ /**
+ * Throw an exception if field cannot be parsed.
+ */
+ public static final UnparseableExtraField THROW
+ = new UnparseableExtraField(THROW_KEY);
+
+ /**
+ * Skip the extra field entirely and don't make its data
+ * available - effectively removing the extra field data.
+ */
+ public static final UnparseableExtraField SKIP
+ = new UnparseableExtraField(SKIP_KEY);
+
+ /**
+ * Read the extra field data into an instance of {@link
+ * UnparseableExtraFieldData UnparseableExtraFieldData}.
+ */
+ public static final UnparseableExtraField READ
+ = new UnparseableExtraField(READ_KEY);
+
+ private final int key;
+
+ private UnparseableExtraField(int k) {
+ key = k;
+ }
+
+ /**
+ * Key of the action to take.
+ */
+ public int getKey() { return key; }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/FallbackZipEncoding.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/FallbackZipEncoding.java
new file mode 100644
index 00000000..3edbb8e1
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/FallbackZipEncoding.java
@@ -0,0 +1,94 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tools.zip;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+/**
+ * A fallback ZipEncoding, which uses a java.io means to encode names.
+ *
+ * <p>This implementation is not favorable for encodings other than
+ * utf-8, because java.io encodes unmappable character as question
+ * marks leading to unreadable ZIP entries on some operating
+ * systems.</p>
+ *
+ * <p>Furthermore this implementation is unable to tell whether a
+ * given name can be safely encoded or not.</p>
+ *
+ * <p>This implementation acts as a last resort implementation, when
+ * neither {@link Simple8BitZipEnoding} nor {@link NioZipEncoding} is
+ * available.</p>
+ *
+ * <p>The methods of this class are reentrant.</p>
+ */
+class FallbackZipEncoding implements ZipEncoding {
+ private final String charset;
+
+ /**
+ * Construct a fallback zip encoding, which uses the platform's
+ * default charset.
+ */
+ public FallbackZipEncoding() {
+ this.charset = null;
+ }
+
+ /**
+ * Construct a fallback zip encoding, which uses the given charset.
+ *
+ * @param charset The name of the charset or {@code null} for
+ * the platform's default character set.
+ */
+ public FallbackZipEncoding(final String charset) {
+ this.charset = charset;
+ }
+
+ /**
+ * @see
+ * org.apache.tools.zip.ZipEncoding#canEncode(java.lang.String)
+ */
+ public boolean canEncode(final String name) {
+ return true;
+ }
+
+ /**
+ * @see
+ * org.apache.tools.zip.ZipEncoding#encode(java.lang.String)
+ */
+ public ByteBuffer encode(final String name) throws IOException {
+ if (this.charset == null) { // i.e. use default charset, see no-args constructor
+ return ByteBuffer.wrap(name.getBytes());
+ } else {
+ return ByteBuffer.wrap(name.getBytes(this.charset));
+ }
+ }
+
+ /**
+ * @see
+ * org.apache.tools.zip.ZipEncoding#decode(byte[])
+ */
+ public String decode(final byte[] data) throws IOException {
+ if (this.charset == null) { // i.e. use default charset, see no-args constructor
+ return new String(data);
+ } else {
+ return new String(data,this.charset);
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/GeneralPurposeBit.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/GeneralPurposeBit.java
new file mode 100644
index 00000000..1d2255fa
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/GeneralPurposeBit.java
@@ -0,0 +1,194 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.zip;
+
+/**
+ * Parser/encoder for the "general purpose bit" field in ZIP's local
+ * file and central directory headers.
+ *
+ * @since Ant 1.9.0
+ */
+public final class GeneralPurposeBit implements Cloneable {
+ /**
+ * Indicates that the file is encrypted.
+ */
+ private static final int ENCRYPTION_FLAG = 1 << 0;
+
+ /**
+ * Indicates that a data descriptor stored after the file contents
+ * will hold CRC and size information.
+ */
+ private static final int DATA_DESCRIPTOR_FLAG = 1 << 3;
+
+ /**
+ * Indicates strong encryption.
+ */
+ private static final int STRONG_ENCRYPTION_FLAG = 1 << 6;
+
+ /**
+ * Indicates that filenames are written in utf-8.
+ *
+ * <p>The only reason this is public is that {@link
+ * ZipOutputStream#EFS_FLAG} was public in several versions of
+ * Apache Ant and we needed a substitute for it.</p>
+ */
+ public static final int UFT8_NAMES_FLAG = 1 << 11;
+
+ private boolean languageEncodingFlag = false;
+ private boolean dataDescriptorFlag = false;
+ private boolean encryptionFlag = false;
+ private boolean strongEncryptionFlag = false;
+
+ public GeneralPurposeBit() {
+ }
+
+ /**
+ * whether the current entry uses UTF8 for file name and comment.
+ */
+ public boolean usesUTF8ForNames() {
+ return languageEncodingFlag;
+ }
+
+ /**
+ * whether the current entry will use UTF8 for file name and comment.
+ */
+ public void useUTF8ForNames(boolean b) {
+ languageEncodingFlag = b;
+ }
+
+ /**
+ * whether the current entry uses the data descriptor to store CRC
+ * and size information
+ */
+ public boolean usesDataDescriptor() {
+ return dataDescriptorFlag;
+ }
+
+ /**
+ * whether the current entry will use the data descriptor to store
+ * CRC and size information
+ */
+ public void useDataDescriptor(boolean b) {
+ dataDescriptorFlag = b;
+ }
+
+ /**
+ * whether the current entry is encrypted
+ */
+ public boolean usesEncryption() {
+ return encryptionFlag;
+ }
+
+ /**
+ * whether the current entry will be encrypted
+ */
+ public void useEncryption(boolean b) {
+ encryptionFlag = b;
+ }
+
+ /**
+ * whether the current entry is encrypted using strong encryption
+ */
+ public boolean usesStrongEncryption() {
+ return encryptionFlag && strongEncryptionFlag;
+ }
+
+ /**
+ * whether the current entry will be encrypted using strong encryption
+ */
+ public void useStrongEncryption(boolean b) {
+ strongEncryptionFlag = b;
+ if (b) {
+ useEncryption(true);
+ }
+ }
+
+ /**
+ * Encodes the set bits in a form suitable for ZIP archives.
+ */
+ public byte[] encode() {
+ byte[] result = new byte[2];
+ encode(result, 0);
+ return result;
+ }
+
+ /**
+ * Encodes the set bits in a form suitable for ZIP archives.
+ *
+ * @param buf the output buffer
+ * @param offset
+ * The offset within the output buffer of the first byte to be written.
+ * must be non-negative and no larger than <tt>buf.length-2</tt>
+ */
+ public void encode(byte[] buf, int offset) {
+ ZipShort.putShort((dataDescriptorFlag ? DATA_DESCRIPTOR_FLAG : 0)
+ |
+ (languageEncodingFlag ? UFT8_NAMES_FLAG : 0)
+ |
+ (encryptionFlag ? ENCRYPTION_FLAG : 0)
+ |
+ (strongEncryptionFlag ? STRONG_ENCRYPTION_FLAG : 0)
+ , buf, offset);
+ }
+
+ /**
+ * Parses the supported flags from the given archive data.
+ * @param data local file header or a central directory entry.
+ * @param offset offset at which the general purpose bit starts
+ */
+ public static GeneralPurposeBit parse(final byte[] data, final int offset) {
+ final int generalPurposeFlag = ZipShort.getValue(data, offset);
+ GeneralPurposeBit b = new GeneralPurposeBit();
+ b.useDataDescriptor((generalPurposeFlag & DATA_DESCRIPTOR_FLAG) != 0);
+ b.useUTF8ForNames((generalPurposeFlag & UFT8_NAMES_FLAG) != 0);
+ b.useStrongEncryption((generalPurposeFlag & STRONG_ENCRYPTION_FLAG)
+ != 0);
+ b.useEncryption((generalPurposeFlag & ENCRYPTION_FLAG) != 0);
+ return b;
+ }
+
+ @Override
+ public int hashCode() {
+ return 3 * (7 * (13 * (17 * (encryptionFlag ? 1 : 0)
+ + (strongEncryptionFlag ? 1 : 0))
+ + (languageEncodingFlag ? 1 : 0))
+ + (dataDescriptorFlag ? 1 : 0));
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof GeneralPurposeBit)) {
+ return false;
+ }
+ GeneralPurposeBit g = (GeneralPurposeBit) o;
+ return g.encryptionFlag == encryptionFlag
+ && g.strongEncryptionFlag == strongEncryptionFlag
+ && g.languageEncodingFlag == languageEncodingFlag
+ && g.dataDescriptorFlag == dataDescriptorFlag;
+ }
+
+ @Override
+ public Object clone() {
+ try {
+ return super.clone();
+ } catch (CloneNotSupportedException ex) {
+ // impossible
+ throw new RuntimeException("GeneralPurposeBit is not Cloneable?", ex);
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/JarMarker.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/JarMarker.java
new file mode 100644
index 00000000..c0633539
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/JarMarker.java
@@ -0,0 +1,108 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.zip;
+
+import java.util.zip.ZipException;
+
+/**
+ * If this extra field is added as the very first extra field of the
+ * archive, Solaris will consider it an executable jar file.
+ *
+ * @since Ant 1.6.3
+ */
+public final class JarMarker implements ZipExtraField {
+
+ private static final ZipShort ID = new ZipShort(0xCAFE);
+ private static final ZipShort NULL = new ZipShort(0);
+ private static final byte[] NO_BYTES = new byte[0];
+ private static final JarMarker DEFAULT = new JarMarker();
+
+ /** No-arg constructor */
+ public JarMarker() {
+ // empty
+ }
+
+ /**
+ * Since JarMarker is stateless we can always use the same instance.
+ * @return the DEFAULT jarmaker.
+ */
+ public static JarMarker getInstance() {
+ return DEFAULT;
+ }
+
+ /**
+ * The Header-ID.
+ * @return the header id
+ */
+ public ZipShort getHeaderId() {
+ return ID;
+ }
+
+ /**
+ * Length of the extra field in the local file data - without
+ * Header-ID or length specifier.
+ * @return 0
+ */
+ public ZipShort getLocalFileDataLength() {
+ return NULL;
+ }
+
+ /**
+ * Length of the extra field in the central directory - without
+ * Header-ID or length specifier.
+ * @return 0
+ */
+ public ZipShort getCentralDirectoryLength() {
+ return NULL;
+ }
+
+ /**
+ * The actual data to put into local file data - without Header-ID
+ * or length specifier.
+ * @return the data
+ * @since 1.1
+ */
+ public byte[] getLocalFileDataData() {
+ return NO_BYTES;
+ }
+
+ /**
+ * The actual data to put central directory - without Header-ID or
+ * length specifier.
+ * @return the data
+ */
+ public byte[] getCentralDirectoryData() {
+ return NO_BYTES;
+ }
+
+ /**
+ * Populate data from this array as if it was in local file data.
+ * @param data an array of bytes
+ * @param offset the start offset
+ * @param length the number of bytes in the array from offset
+ *
+ * @throws ZipException on error
+ */
+ public void parseFromLocalFileData(byte[] data, int offset, int length)
+ throws ZipException {
+ if (length != 0) {
+ throw new ZipException("JarMarker doesn't expect any data");
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/NioZipEncoding.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/NioZipEncoding.java
new file mode 100644
index 00000000..63d33ff5
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/NioZipEncoding.java
@@ -0,0 +1,122 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tools.zip;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetEncoder;
+import java.nio.charset.CoderResult;
+import java.nio.charset.CodingErrorAction;
+
+/**
+ * A ZipEncoding, which uses a java.nio {@link
+ * java.nio.charset.Charset Charset} to encode names.
+ *
+ * <p>This implementation works for all cases under java-1.5 or
+ * later. However, in java-1.4, some charsets don't have a java.nio
+ * implementation, most notably the default ZIP encoding Cp437.</p>
+ *
+ * <p>The methods of this class are reentrant.</p>
+ */
+class NioZipEncoding implements ZipEncoding {
+ private final Charset charset;
+
+ /**
+ * Construct an NIO based zip encoding, which wraps the given
+ * charset.
+ *
+ * @param charset The NIO charset to wrap.
+ */
+ public NioZipEncoding(final Charset charset) {
+ this.charset = charset;
+ }
+
+ /**
+ * @see
+ * org.apache.tools.zip.ZipEncoding#canEncode(java.lang.String)
+ */
+ public boolean canEncode(final String name) {
+ final CharsetEncoder enc = this.charset.newEncoder();
+ enc.onMalformedInput(CodingErrorAction.REPORT);
+ enc.onUnmappableCharacter(CodingErrorAction.REPORT);
+
+ return enc.canEncode(name);
+ }
+
+ /**
+ * @see
+ * org.apache.tools.zip.ZipEncoding#encode(java.lang.String)
+ */
+ public ByteBuffer encode(final String name) {
+ final CharsetEncoder enc = this.charset.newEncoder();
+
+ enc.onMalformedInput(CodingErrorAction.REPORT);
+ enc.onUnmappableCharacter(CodingErrorAction.REPORT);
+
+ final CharBuffer cb = CharBuffer.wrap(name);
+ ByteBuffer out = ByteBuffer.allocate(name.length()
+ + (name.length() + 1) / 2);
+
+ while (cb.remaining() > 0) {
+ final CoderResult res = enc.encode(cb, out,true);
+
+ if (res.isUnmappable() || res.isMalformed()) {
+
+ // write the unmappable characters in utf-16
+ // pseudo-URL encoding style to ByteBuffer.
+ if (res.length() * 6 > out.remaining()) {
+ out = ZipEncodingHelper.growBuffer(out, out.position()
+ + res.length() * 6);
+ }
+
+ for (int i=0; i<res.length(); ++i) {
+ ZipEncodingHelper.appendSurrogate(out,cb.get());
+ }
+
+ } else if (res.isOverflow()) {
+
+ out = ZipEncodingHelper.growBuffer(out, 0);
+
+ } else if (res.isUnderflow()) {
+
+ enc.flush(out);
+ break;
+
+ }
+ }
+
+ out.limit(out.position());
+ out.rewind();
+ return out;
+ }
+
+ /**
+ * @see
+ * org.apache.tools.zip.ZipEncoding#decode(byte[])
+ */
+ public String decode(final byte[] data) throws IOException {
+ return this.charset.newDecoder()
+ .onMalformedInput(CodingErrorAction.REPORT)
+ .onUnmappableCharacter(CodingErrorAction.REPORT)
+ .decode(ByteBuffer.wrap(data)).toString();
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/Simple8BitZipEncoding.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/Simple8BitZipEncoding.java
new file mode 100644
index 00000000..57a838ca
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/Simple8BitZipEncoding.java
@@ -0,0 +1,274 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tools.zip;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * This ZipEncoding implementation implements a simple 8bit character
+ * set, which mets the following restrictions:
+ *
+ * <ul>
+ * <li>Characters 0x0000 to 0x007f are encoded as the corresponding
+ * byte values 0x00 to 0x7f.</li>
+ * <li>All byte codes from 0x80 to 0xff are mapped to a unique unicode
+ * character in the range 0x0080 to 0x7fff. (No support for
+ * UTF-16 surrogates)
+ * </ul>
+ *
+ * <p>These restrictions most notably apply to the most prominent
+ * omissions of java-1.4's {@link java.nio.charset.Charset Charset}
+ * implementation, Cp437 and Cp850.</p>
+ *
+ * <p>The methods of this class are reentrant.</p>
+ */
+class Simple8BitZipEncoding implements ZipEncoding {
+
+ /**
+ * A character entity, which is put to the reverse mapping table
+ * of a simple encoding.
+ */
+ private static final class Simple8BitChar implements Comparable<Simple8BitChar> {
+ public final char unicode;
+ public final byte code;
+
+ Simple8BitChar(final byte code, final char unicode) {
+ this.code = code;
+ this.unicode = unicode;
+ }
+
+ public int compareTo(final Simple8BitChar a) {
+ return this.unicode - a.unicode;
+ }
+
+ @Override
+ public String toString() {
+ return "0x" + Integer.toHexString(0xffff & unicode)
+ + "->0x" + Integer.toHexString(0xff & code);
+ }
+
+ @Override
+ public boolean equals(final Object o) {
+ if (o instanceof Simple8BitChar) {
+ final Simple8BitChar other = (Simple8BitChar) o;
+ return unicode == other.unicode && code == other.code;
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ return unicode;
+ }
+ }
+
+ /**
+ * The characters for byte values of 128 to 255 stored as an array of
+ * 128 chars.
+ */
+ private final char[] highChars;
+
+ /**
+ * A list of {@link Simple8BitChar} objects sorted by the unicode
+ * field. This list is used to binary search reverse mapping of
+ * unicode characters with a character code greater than 127.
+ */
+ private final List<Simple8BitChar> reverseMapping;
+
+ /**
+ * @param highChars The characters for byte values of 128 to 255
+ * stored as an array of 128 chars.
+ */
+ public Simple8BitZipEncoding(final char[] highChars) {
+ this.highChars = highChars.clone();
+ final List<Simple8BitChar> temp =
+ new ArrayList<Simple8BitChar>(this.highChars.length);
+
+ byte code = 127;
+
+ for (int i = 0; i < this.highChars.length; ++i) {
+ temp.add(new Simple8BitChar(++code, this.highChars[i]));
+ }
+
+ Collections.sort(temp);
+ this.reverseMapping = Collections.unmodifiableList(temp);
+ }
+
+ /**
+ * Return the character code for a given encoded byte.
+ *
+ * @param b The byte to decode.
+ * @return The associated character value.
+ */
+ public char decodeByte(final byte b) {
+ // code 0-127
+ if (b >= 0) {
+ return (char) b;
+ }
+
+ // byte is signed, so 128 == -128 and 255 == -1
+ return this.highChars[128 + b];
+ }
+
+ /**
+ * @param c The character to encode.
+ * @return Whether the given unicode character is covered by this encoding.
+ */
+ public boolean canEncodeChar(final char c) {
+
+ if (c >= 0 && c < 128) {
+ return true;
+ }
+
+ final Simple8BitChar r = this.encodeHighChar(c);
+ return r != null;
+ }
+
+ /**
+ * Pushes the encoded form of the given character to the given byte buffer.
+ *
+ * @param bb The byte buffer to write to.
+ * @param c The character to encode.
+ * @return Whether the given unicode character is covered by this encoding.
+ * If {@code false} is returned, nothing is pushed to the
+ * byte buffer.
+ */
+ public boolean pushEncodedChar(final ByteBuffer bb, final char c) {
+
+ if (c >= 0 && c < 128) {
+ bb.put((byte) c);
+ return true;
+ }
+
+ final Simple8BitChar r = this.encodeHighChar(c);
+ if (r == null) {
+ return false;
+ }
+ bb.put(r.code);
+ return true;
+ }
+
+ /**
+ * @param c A unicode character in the range from 0x0080 to 0x7f00
+ * @return A Simple8BitChar, if this character is covered by this encoding.
+ * A {@code null} value is returned, if this character is not
+ * covered by this encoding.
+ */
+ private Simple8BitChar encodeHighChar(final char c) {
+ // for performance an simplicity, yet another reincarnation of
+ // binary search...
+ int i0 = 0;
+ int i1 = this.reverseMapping.size();
+
+ while (i1 > i0) {
+
+ final int i = i0 + (i1 - i0) / 2;
+
+ final Simple8BitChar m = this.reverseMapping.get(i);
+
+ if (m.unicode == c) {
+ return m;
+ }
+
+ if (m.unicode < c) {
+ i0 = i + 1;
+ } else {
+ i1 = i;
+ }
+ }
+
+ if (i0 >= this.reverseMapping.size()) {
+ return null;
+ }
+
+ final Simple8BitChar r = this.reverseMapping.get(i0);
+
+ if (r.unicode != c) {
+ return null;
+ }
+
+ return r;
+ }
+
+ /**
+ * @see
+ * org.apache.tools.zip.ZipEncoding#canEncode(java.lang.String)
+ */
+ public boolean canEncode(final String name) {
+
+ for (int i=0;i<name.length();++i) {
+
+ final char c = name.charAt(i);
+
+ if (!this.canEncodeChar(c)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * @see
+ * org.apache.tools.zip.ZipEncoding#encode(java.lang.String)
+ */
+ public ByteBuffer encode(final String name) {
+ ByteBuffer out = ByteBuffer.allocate(name.length()
+ + 6 + (name.length() + 1) / 2);
+
+ for (int i=0;i<name.length();++i) {
+
+ final char c = name.charAt(i);
+
+ if (out.remaining() < 6) {
+ out = ZipEncodingHelper.growBuffer(out,out.position() + 6);
+ }
+
+ if (!this.pushEncodedChar(out,c)) {
+
+ ZipEncodingHelper.appendSurrogate(out,c);
+ }
+ }
+
+ out.limit(out.position());
+ out.rewind();
+ return out;
+ }
+
+ /**
+ * @see
+ * org.apache.tools.zip.ZipEncoding#decode(byte[])
+ */
+ public String decode(final byte[] data) throws IOException {
+ final char [] ret = new char[data.length];
+
+ for (int i=0;i<data.length;++i) {
+ ret[i] = this.decodeByte(data[i]);
+ }
+
+ return new String(ret);
+ }
+
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/UnicodeCommentExtraField.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/UnicodeCommentExtraField.java
new file mode 100644
index 00000000..51550fe7
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/UnicodeCommentExtraField.java
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.zip;
+
+/**
+ * Info-ZIP Unicode Comment Extra Field (0x6375):
+ *
+ * <p>Stores the UTF-8 version of the file comment as stored in the
+ * central directory header.</p>
+ *
+ * <p>See {@link
+ * "http://www.pkware.com/documents/casestudies/APPNOTE.TXT PKWARE's
+ * APPNOTE.TXT, section 4.6.8"}.</p>
+ *
+ */
+public class UnicodeCommentExtraField extends AbstractUnicodeExtraField {
+
+ public static final ZipShort UCOM_ID = new ZipShort(0x6375);
+
+ public UnicodeCommentExtraField () {
+ }
+
+ /**
+ * Assemble as unicode comment extension from the name given as
+ * text as well as the encoded bytes actually written to the archive.
+ *
+ * @param text The file name
+ * @param bytes the bytes actually written to the archive
+ * @param off The offset of the encoded comment in <code>bytes</code>.
+ * @param len The length of the encoded comment or comment in
+ * <code>bytes</code>.
+ */
+ public UnicodeCommentExtraField(final String text, final byte[] bytes, final int off,
+ final int len) {
+ super(text, bytes, off, len);
+ }
+
+ /**
+ * Assemble as unicode comment extension from the comment given as
+ * text as well as the bytes actually written to the archive.
+ *
+ * @param comment The file comment
+ * @param bytes the bytes actually written to the archive
+ */
+ public UnicodeCommentExtraField(final String comment, final byte[] bytes) {
+ super(comment, bytes);
+ }
+
+ /** {@inheritDoc} */
+ public ZipShort getHeaderId() {
+ return UCOM_ID;
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/UnicodePathExtraField.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/UnicodePathExtraField.java
new file mode 100644
index 00000000..8b045a1e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/UnicodePathExtraField.java
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.zip;
+
+/**
+ * Info-ZIP Unicode Path Extra Field (0x7075):
+ *
+ * <p>Stores the UTF-8 version of the file name field as stored in the
+ * local header and central directory header.</p>
+ *
+ * <p>See {@link
+ * "http://www.pkware.com/documents/casestudies/APPNOTE.TXT PKWARE's
+ * APPNOTE.TXT, section 4.6.9"}.</p>
+ */
+public class UnicodePathExtraField extends AbstractUnicodeExtraField {
+
+ public static final ZipShort UPATH_ID = new ZipShort(0x7075);
+
+ public UnicodePathExtraField () {
+ }
+
+ /**
+ * Assemble as unicode path extension from the name given as
+ * text as well as the encoded bytes actually written to the archive.
+ *
+ * @param text The file name
+ * @param bytes the bytes actually written to the archive
+ * @param off The offset of the encoded filename in <code>bytes</code>.
+ * @param len The length of the encoded filename or comment in
+ * <code>bytes</code>.
+ */
+ public UnicodePathExtraField(final String text, final byte[] bytes, final int off, final int len) {
+ super(text, bytes, off, len);
+ }
+
+ /**
+ * Assemble as unicode path extension from the name given as
+ * text as well as the encoded bytes actually written to the archive.
+ *
+ * @param name The file name
+ * @param bytes the bytes actually written to the archive
+ */
+ public UnicodePathExtraField(final String name, final byte[] bytes) {
+ super(name, bytes);
+ }
+
+ /** {@inheritDoc} */
+ public ZipShort getHeaderId() {
+ return UPATH_ID;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/UnixStat.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/UnixStat.java
new file mode 100644
index 00000000..2ca0674b
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/UnixStat.java
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.zip;
+
+/**
+ * Constants from stat.h on Unix systems.
+ *
+ */
+// CheckStyle:InterfaceIsTypeCheck OFF - backward compatible
+public interface UnixStat {
+
+ /**
+ * Bits used for permissions (and sticky bit)
+ *
+ * @since 1.1
+ */
+ int PERM_MASK = 07777;
+ /**
+ * Indicates symbolic links.
+ *
+ * @since 1.1
+ */
+ int LINK_FLAG = 0120000;
+ /**
+ * Indicates plain files.
+ *
+ * @since 1.1
+ */
+ int FILE_FLAG = 0100000;
+ /**
+ * Indicates directories.
+ *
+ * @since 1.1
+ */
+ int DIR_FLAG = 040000;
+
+ // ----------------------------------------------------------
+ // somewhat arbitrary choices that are quite common for shared
+ // installations
+ // -----------------------------------------------------------
+
+ /**
+ * Default permissions for symbolic links.
+ *
+ * @since 1.1
+ */
+ int DEFAULT_LINK_PERM = 0777;
+ /**
+ * Default permissions for directories.
+ *
+ * @since 1.1
+ */
+ int DEFAULT_DIR_PERM = 0755;
+ /**
+ * Default permissions for plain files.
+ *
+ * @since 1.1
+ */
+ int DEFAULT_FILE_PERM = 0644;
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/UnparseableExtraFieldData.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/UnparseableExtraFieldData.java
new file mode 100644
index 00000000..92d30020
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/UnparseableExtraFieldData.java
@@ -0,0 +1,115 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tools.zip;
+
+/**
+ * Wrapper for extra field data that doesn't conform to the recommended format of header-tag + size + data.
+ *
+ * <p>The header-id is artificial (and not listed as a known ID in
+ * {@link <a href="http://www.pkware.com/documents/casestudies/APPNOTE.TXT">
+ * APPNOTE.TXT</a>}). Since it isn't used anywhere except to satisfy the
+ * ZipExtraField contract it shouldn't matter anyway.</p>
+ *
+ * @since Ant 1.8.1
+ */
+public final class UnparseableExtraFieldData
+ implements CentralDirectoryParsingZipExtraField {
+
+ private static final ZipShort HEADER_ID = new ZipShort(0xACC1);
+
+ private byte[] localFileData;
+ private byte[] centralDirectoryData;
+
+ /**
+ * The Header-ID.
+ *
+ * @return a completely arbitrary value that should be ignored.
+ */
+ public ZipShort getHeaderId() {
+ return HEADER_ID;
+ }
+
+ /**
+ * Length of the complete extra field in the local file data.
+ *
+ * @return The LocalFileDataLength value
+ */
+ public ZipShort getLocalFileDataLength() {
+ return new ZipShort(localFileData == null ? 0 : localFileData.length);
+ }
+
+ /**
+ * Length of the complete extra field in the central directory.
+ *
+ * @return The CentralDirectoryLength value
+ */
+ public ZipShort getCentralDirectoryLength() {
+ return centralDirectoryData == null
+ ? getLocalFileDataLength()
+ : new ZipShort(centralDirectoryData.length);
+ }
+
+ /**
+ * The actual data to put into local file data.
+ *
+ * @return The LocalFileDataData value
+ */
+ public byte[] getLocalFileDataData() {
+ return ZipUtil.copy(localFileData);
+ }
+
+ /**
+ * The actual data to put into central directory.
+ *
+ * @return The CentralDirectoryData value
+ */
+ public byte[] getCentralDirectoryData() {
+ return centralDirectoryData == null
+ ? getLocalFileDataData() : ZipUtil.copy(centralDirectoryData);
+ }
+
+ /**
+ * Populate data from this array as if it was in local file data.
+ *
+ * @param buffer the buffer to read data from
+ * @param offset offset into buffer to read data
+ * @param length the length of data
+ */
+ public void parseFromLocalFileData(byte[] buffer, int offset, int length) {
+ localFileData = new byte[length];
+ System.arraycopy(buffer, offset, localFileData, 0, length);
+ }
+
+ /**
+ * Populate data from this array as if it was in central directory data.
+ *
+ * @param buffer the buffer to read data from
+ * @param offset offset into buffer to read data
+ * @param length the length of data
+ */
+ public void parseFromCentralDirectoryData(byte[] buffer, int offset,
+ int length) {
+ centralDirectoryData = new byte[length];
+ System.arraycopy(buffer, offset, centralDirectoryData, 0, length);
+ if (localFileData == null) {
+ parseFromLocalFileData(buffer, offset, length);
+ }
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/UnrecognizedExtraField.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/UnrecognizedExtraField.java
new file mode 100644
index 00000000..0e4262de
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/UnrecognizedExtraField.java
@@ -0,0 +1,154 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.zip;
+
+/**
+ * Simple placeholder for all those extra fields we don't want to deal
+ * with.
+ *
+ * <p>Assumes local file data and central directory entries are
+ * identical - unless told the opposite.</p>
+ *
+ */
+public class UnrecognizedExtraField
+ implements CentralDirectoryParsingZipExtraField {
+
+ /**
+ * The Header-ID.
+ *
+ * @since 1.1
+ */
+ private ZipShort headerId;
+
+ /**
+ * Set the header id.
+ * @param headerId the header id to use
+ */
+ public void setHeaderId(ZipShort headerId) {
+ this.headerId = headerId;
+ }
+
+ /**
+ * Get the header id.
+ * @return the header id
+ */
+ public ZipShort getHeaderId() {
+ return headerId;
+ }
+
+ /**
+ * Extra field data in local file data - without
+ * Header-ID or length specifier.
+ *
+ * @since 1.1
+ */
+ private byte[] localData;
+
+ /**
+ * Set the extra field data in the local file data -
+ * without Header-ID or length specifier.
+ * @param data the field data to use
+ */
+ public void setLocalFileDataData(byte[] data) {
+ localData = ZipUtil.copy(data);
+ }
+
+ /**
+ * Get the length of the local data.
+ * @return the length of the local data
+ */
+ public ZipShort getLocalFileDataLength() {
+ return new ZipShort(localData.length);
+ }
+
+ /**
+ * Get the local data.
+ * @return the local data
+ */
+ public byte[] getLocalFileDataData() {
+ return ZipUtil.copy(localData);
+ }
+
+ /**
+ * Extra field data in central directory - without
+ * Header-ID or length specifier.
+ *
+ * @since 1.1
+ */
+ private byte[] centralData;
+
+ /**
+ * Set the extra field data in central directory.
+ * @param data the data to use
+ */
+ public void setCentralDirectoryData(byte[] data) {
+ centralData = ZipUtil.copy(data);
+ }
+
+ /**
+ * Get the central data length.
+ * If there is no central data, get the local file data length.
+ * @return the central data length
+ */
+ public ZipShort getCentralDirectoryLength() {
+ if (centralData != null) {
+ return new ZipShort(centralData.length);
+ }
+ return getLocalFileDataLength();
+ }
+
+ /**
+ * Get the central data.
+ * @return the central data if present, else return the local file data
+ */
+ public byte[] getCentralDirectoryData() {
+ if (centralData != null) {
+ return ZipUtil.copy(centralData);
+ }
+ return getLocalFileDataData();
+ }
+
+ /**
+ * @param data the array of bytes.
+ * @param offset the source location in the data array.
+ * @param length the number of bytes to use in the data array.
+ * @see ZipExtraField#parseFromLocalFileData(byte[], int, int)
+ */
+ public void parseFromLocalFileData(byte[] data, int offset, int length) {
+ byte[] tmp = new byte[length];
+ System.arraycopy(data, offset, tmp, 0, length);
+ setLocalFileDataData(tmp);
+ }
+
+ /**
+ * @param data the array of bytes.
+ * @param offset the source location in the data array.
+ * @param length the number of bytes to use in the data array.
+ */
+ public void parseFromCentralDirectoryData(byte[] data, int offset,
+ int length) {
+ byte[] tmp = new byte[length];
+ System.arraycopy(data, offset, tmp, 0, length);
+ setCentralDirectoryData(tmp);
+ if (localData == null) {
+ setLocalFileDataData(tmp);
+ }
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/UnsupportedZipFeatureException.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/UnsupportedZipFeatureException.java
new file mode 100644
index 00000000..534bb165
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/UnsupportedZipFeatureException.java
@@ -0,0 +1,89 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.zip;
+
+import java.util.zip.ZipException;
+
+/**
+ * Exception thrown when attempting to read or write data for a zip
+ * entry that uses ZIP features not supported by this library.
+ * @since Ant 1.9.0
+ */
+public class UnsupportedZipFeatureException extends ZipException {
+
+ private final Feature reason;
+ private final ZipEntry entry;
+ private static final long serialVersionUID = 4430521921766595597L;
+
+ /**
+ * Creates an exception.
+ * @param reason the feature that is not supported
+ * @param entry the entry using the feature
+ */
+ public UnsupportedZipFeatureException(Feature reason,
+ ZipEntry entry) {
+ super("unsupported feature " + reason + " used in entry "
+ + entry.getName());
+ this.reason = reason;
+ this.entry = entry;
+ }
+
+ /**
+ * The unsupported feature that has been used.
+ */
+ public Feature getFeature() {
+ return reason;
+ }
+
+ /**
+ * The entry using the unsupported feature.
+ */
+ public ZipEntry getEntry() {
+ return entry;
+ }
+
+ /**
+ * ZIP Features that may or may not be supported.
+ */
+ public static class Feature {
+ /**
+ * The entry is encrypted.
+ */
+ public static final Feature ENCRYPTION = new Feature("encryption");
+ /**
+ * The entry used an unsupported compression method.
+ */
+ public static final Feature METHOD = new Feature("compression method");
+ /**
+ * The entry uses a data descriptor.
+ */
+ public static final Feature DATA_DESCRIPTOR = new Feature("data descriptor");
+
+ private final String name;
+
+ private Feature(String name) {
+ this.name = name;
+ }
+
+ @Override
+ public String toString() {
+ return name;
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/Zip64ExtendedInformationExtraField.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/Zip64ExtendedInformationExtraField.java
new file mode 100644
index 00000000..16502ac6
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/Zip64ExtendedInformationExtraField.java
@@ -0,0 +1,322 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tools.zip;
+
+import static org.apache.tools.zip.ZipConstants.DWORD;
+import static org.apache.tools.zip.ZipConstants.WORD;
+
+import java.util.zip.ZipException;
+
+/**
+ * Holds size and other extended information for entries that use Zip64
+ * features.
+ *
+ * <p>See {@link
+ * "http://www.pkware.com/documents/casestudies/APPNOTE.TXT PKWARE's
+ * APPNOTE.TXT, section 4.5.3"}.</p>
+ *
+ * <p>Currently Ant doesn't support encrypting the
+ * central directory so the note about masking doesn't apply.</p>
+ *
+ * <p>The implementation relies on data being read from the local file
+ * header and assumes that both size values are always present.</p>
+ *
+ * @since Ant 1.9.0
+ */
+public class Zip64ExtendedInformationExtraField
+ implements CentralDirectoryParsingZipExtraField {
+
+ static final ZipShort HEADER_ID = new ZipShort(0x0001);
+
+ private static final String LFH_MUST_HAVE_BOTH_SIZES_MSG =
+ "Zip64 extended information must contain"
+ + " both size values in the local file header.";
+ private static final byte[] EMPTY = new byte[0];
+
+ private ZipEightByteInteger size, compressedSize, relativeHeaderOffset;
+ private ZipLong diskStart;
+
+ /**
+ * Stored in {@link #parseFromCentralDirectoryData
+ * parseFromCentralDirectoryData} so it can be reused when ZipFile
+ * calls {@link #reparseCentralDirectoryData
+ * reparseCentralDirectoryData}.
+ *
+ * <p>Not used for anything else</p>
+ */
+ private byte[] rawCentralDirectoryData;
+
+ /**
+ * This constructor should only be used by the code that reads
+ * archives inside of Ant.
+ */
+ public Zip64ExtendedInformationExtraField() { }
+
+ /**
+ * Creates an extra field based on the original and compressed size.
+ *
+ * @param size the entry's original size
+ * @param compressedSize the entry's compressed size
+ *
+ * @throws IllegalArgumentException if size or compressedSize is null
+ */
+ public Zip64ExtendedInformationExtraField(ZipEightByteInteger size,
+ ZipEightByteInteger compressedSize) {
+ this(size, compressedSize, null, null);
+ }
+
+ /**
+ * Creates an extra field based on all four possible values.
+ *
+ * @param size the entry's original size
+ * @param compressedSize the entry's compressed size
+ *
+ * @throws IllegalArgumentException if size or compressedSize is null
+ */
+ public Zip64ExtendedInformationExtraField(ZipEightByteInteger size,
+ ZipEightByteInteger compressedSize,
+ ZipEightByteInteger relativeHeaderOffset,
+ ZipLong diskStart) {
+ this.size = size;
+ this.compressedSize = compressedSize;
+ this.relativeHeaderOffset = relativeHeaderOffset;
+ this.diskStart = diskStart;
+ }
+
+ /** {@inheritDoc} */
+ public ZipShort getHeaderId() {
+ return HEADER_ID;
+ }
+
+ /** {@inheritDoc} */
+ public ZipShort getLocalFileDataLength() {
+ return new ZipShort(size != null ? 2 * DWORD : 0);
+ }
+
+ /** {@inheritDoc} */
+ public ZipShort getCentralDirectoryLength() {
+ return new ZipShort((size != null ? DWORD : 0)
+ + (compressedSize != null ? DWORD : 0)
+ + (relativeHeaderOffset != null ? DWORD : 0)
+ + (diskStart != null ? WORD : 0));
+ }
+
+ /** {@inheritDoc} */
+ public byte[] getLocalFileDataData() {
+ if (size != null || compressedSize != null) {
+ if (size == null || compressedSize == null) {
+ throw new IllegalArgumentException(LFH_MUST_HAVE_BOTH_SIZES_MSG);
+ }
+ byte[] data = new byte[2 * DWORD];
+ addSizes(data);
+ return data;
+ }
+ return EMPTY;
+ }
+
+ /** {@inheritDoc} */
+ public byte[] getCentralDirectoryData() {
+ byte[] data = new byte[getCentralDirectoryLength().getValue()];
+ int off = addSizes(data);
+ if (relativeHeaderOffset != null) {
+ System.arraycopy(relativeHeaderOffset.getBytes(), 0, data, off, DWORD);
+ off += DWORD;
+ }
+ if (diskStart != null) {
+ System.arraycopy(diskStart.getBytes(), 0, data, off, WORD);
+ off += WORD;
+ }
+ return data;
+ }
+
+ /** {@inheritDoc} */
+ public void parseFromLocalFileData(byte[] buffer, int offset, int length)
+ throws ZipException {
+ if (length == 0) {
+ // no local file data at all, may happen if an archive
+ // only holds a ZIP64 extended information extra field
+ // inside the central directory but not inside the local
+ // file header
+ return;
+ }
+ if (length < 2 * DWORD) {
+ throw new ZipException(LFH_MUST_HAVE_BOTH_SIZES_MSG);
+ }
+ size = new ZipEightByteInteger(buffer, offset);
+ offset += DWORD;
+ compressedSize = new ZipEightByteInteger(buffer, offset);
+ offset += DWORD;
+ int remaining = length - 2 * DWORD;
+ if (remaining >= DWORD) {
+ relativeHeaderOffset = new ZipEightByteInteger(buffer, offset);
+ offset += DWORD;
+ remaining -= DWORD;
+ }
+ if (remaining >= WORD) {
+ diskStart = new ZipLong(buffer, offset);
+ offset += WORD;
+ remaining -= WORD;
+ }
+ }
+
+ /** {@inheritDoc} */
+ public void parseFromCentralDirectoryData(byte[] buffer, int offset,
+ int length)
+ throws ZipException {
+ // store for processing in reparseCentralDirectoryData
+ rawCentralDirectoryData = new byte[length];
+ System.arraycopy(buffer, offset, rawCentralDirectoryData, 0, length);
+
+ // if there is no size information in here, we are screwed and
+ // can only hope things will get resolved by LFH data later
+ // But there are some cases that can be detected
+ // * all data is there
+ // * length == 24 -> both sizes and offset
+ // * length % 8 == 4 -> at least we can identify the diskStart field
+ if (length >= 3 * DWORD + WORD) {
+ parseFromLocalFileData(buffer, offset, length);
+ } else if (length == 3 * DWORD) {
+ size = new ZipEightByteInteger(buffer, offset);
+ offset += DWORD;
+ compressedSize = new ZipEightByteInteger(buffer, offset);
+ offset += DWORD;
+ relativeHeaderOffset = new ZipEightByteInteger(buffer, offset);
+ } else if (length % DWORD == WORD) {
+ diskStart = new ZipLong(buffer, offset + length - WORD);
+ }
+ }
+
+ /**
+ * Parses the raw bytes read from the central directory extra
+ * field with knowledge which fields are expected to be there.
+ *
+ * <p>All four fields inside the zip64 extended information extra
+ * field are optional and must only be present if their corresponding
+ * entry inside the central directory contains the correct magic
+ * value.</p>
+ */
+ public void reparseCentralDirectoryData(boolean hasUncompressedSize,
+ boolean hasCompressedSize,
+ boolean hasRelativeHeaderOffset,
+ boolean hasDiskStart)
+ throws ZipException {
+ if (rawCentralDirectoryData != null) {
+ int expectedLength = (hasUncompressedSize ? DWORD : 0)
+ + (hasCompressedSize ? DWORD : 0)
+ + (hasRelativeHeaderOffset ? DWORD : 0)
+ + (hasDiskStart ? WORD : 0);
+ if (rawCentralDirectoryData.length < expectedLength) {
+ throw new ZipException("central directory zip64 extended"
+ + " information extra field's length"
+ + " doesn't match central directory"
+ + " data. Expected length "
+ + expectedLength + " but is "
+ + rawCentralDirectoryData.length);
+ }
+ int offset = 0;
+ if (hasUncompressedSize) {
+ size = new ZipEightByteInteger(rawCentralDirectoryData, offset);
+ offset += DWORD;
+ }
+ if (hasCompressedSize) {
+ compressedSize = new ZipEightByteInteger(rawCentralDirectoryData,
+ offset);
+ offset += DWORD;
+ }
+ if (hasRelativeHeaderOffset) {
+ relativeHeaderOffset =
+ new ZipEightByteInteger(rawCentralDirectoryData, offset);
+ offset += DWORD;
+ }
+ if (hasDiskStart) {
+ diskStart = new ZipLong(rawCentralDirectoryData, offset);
+ offset += WORD;
+ }
+ }
+ }
+
+ /**
+ * The uncompressed size stored in this extra field.
+ */
+ public ZipEightByteInteger getSize() {
+ return size;
+ }
+
+ /**
+ * The uncompressed size stored in this extra field.
+ */
+ public void setSize(ZipEightByteInteger size) {
+ this.size = size;
+ }
+
+ /**
+ * The compressed size stored in this extra field.
+ */
+ public ZipEightByteInteger getCompressedSize() {
+ return compressedSize;
+ }
+
+ /**
+ * The uncompressed size stored in this extra field.
+ */
+ public void setCompressedSize(ZipEightByteInteger compressedSize) {
+ this.compressedSize = compressedSize;
+ }
+
+ /**
+ * The relative header offset stored in this extra field.
+ */
+ public ZipEightByteInteger getRelativeHeaderOffset() {
+ return relativeHeaderOffset;
+ }
+
+ /**
+ * The relative header offset stored in this extra field.
+ */
+ public void setRelativeHeaderOffset(ZipEightByteInteger rho) {
+ relativeHeaderOffset = rho;
+ }
+
+ /**
+ * The disk start number stored in this extra field.
+ */
+ public ZipLong getDiskStartNumber() {
+ return diskStart;
+ }
+
+ /**
+ * The disk start number stored in this extra field.
+ */
+ public void setDiskStartNumber(ZipLong ds) {
+ diskStart = ds;
+ }
+
+ private int addSizes(byte[] data) {
+ int off = 0;
+ if (size != null) {
+ System.arraycopy(size.getBytes(), 0, data, 0, DWORD);
+ off += DWORD;
+ }
+ if (compressedSize != null) {
+ System.arraycopy(compressedSize.getBytes(), 0, data, off, DWORD);
+ off += DWORD;
+ }
+ return off;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/Zip64Mode.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/Zip64Mode.java
new file mode 100644
index 00000000..30d9f1cb
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/Zip64Mode.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.zip;
+
+/**
+ * The different modes {@link ZipOutputStream} can operate in.
+ *
+ * @see ZipOutputStream#setUseZip64
+ *
+ * @since Ant 1.9.0
+ */
+public enum Zip64Mode {
+ /**
+ * Use Zip64 extensions for all entries, even if it is clear it is
+ * not required.
+ */
+ Always,
+ /**
+ * Don't use Zip64 extensions for any entries.
+ *
+ * <p>This will cause a {@link Zip64RequiredException} to be
+ * thrown if {@link ZipOutputStream} detects it needs Zip64
+ * support.</p>
+ */
+ Never,
+ /**
+ * Use Zip64 extensions for all entries where they are required,
+ * don't use them for entries that clearly don't require them.
+ */
+ AsNeeded
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/Zip64RequiredException.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/Zip64RequiredException.java
new file mode 100644
index 00000000..f7fb7790
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/Zip64RequiredException.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.zip;
+
+import java.util.zip.ZipException;
+
+/**
+ * Exception thrown when attempting to write data that requires Zip64
+ * support to an archive and {@link ZipOutputStream#setUseZip64
+ * UseZip64} has been set to {@link Zip64Mode#Never Never}.
+ * @since Ant 1.9.0
+ */
+public class Zip64RequiredException extends ZipException {
+
+ private static final long serialVersionUID = 20110809L;
+
+ /**
+ * Helper to format "entry too big" messages.
+ */
+ static String getEntryTooBigMessage(ZipEntry ze) {
+ return ze.getName() + "'s size exceeds the limit of 4GByte.";
+ }
+
+ static final String ARCHIVE_TOO_BIG_MESSAGE =
+ "archive's size exceeds the limit of 4GByte.";
+
+ static final String TOO_MANY_ENTRIES_MESSAGE =
+ "archive contains more than 65535 entries.";
+
+ public Zip64RequiredException(String reason) {
+ super(reason);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/ZipConstants.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/ZipConstants.java
new file mode 100644
index 00000000..83ae9569
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/ZipConstants.java
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.zip;
+
+/**
+ * Various constants used throughout the package.
+ */
+final class ZipConstants {
+ private ZipConstants() { }
+
+ /** Masks last eight bits */
+ static final int BYTE_MASK = 0xFF;
+
+ /** length of a ZipShort in bytes */
+ static final int SHORT = 2;
+
+ /** length of a ZipLong in bytes */
+ static final int WORD = 4;
+
+ /** length of a ZipEightByteInteger in bytes */
+ static final int DWORD = 8;
+
+ /** Initial ZIP specification version */
+ static final int INITIAL_VERSION = 10;
+
+ /** ZIP specification version that introduced data descriptor method */
+ static final int DATA_DESCRIPTOR_MIN_VERSION = 20;
+
+ /** ZIP specification version that introduced ZIP64 */
+ static final int ZIP64_MIN_VERSION = 45;
+
+ /**
+ * Value stored in two-byte size and similar fields if ZIP64
+ * extensions are used.
+ */
+ static final int ZIP64_MAGIC_SHORT = 0xFFFF;
+
+ /**
+ * Value stored in four-byte size and similar fields if ZIP64
+ * extensions are used.
+ */
+ static final long ZIP64_MAGIC = 0xFFFFFFFFL;
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/ZipEightByteInteger.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/ZipEightByteInteger.java
new file mode 100644
index 00000000..8d582dd8
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/ZipEightByteInteger.java
@@ -0,0 +1,229 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.zip;
+
+import static org.apache.tools.zip.ZipConstants.BYTE_MASK;
+
+import java.math.BigInteger;
+
+/**
+ * Utility class that represents an eight byte integer with conversion
+ * rules for the big endian byte order of ZIP files.
+ */
+public final class ZipEightByteInteger {
+
+ private static final int BYTE_1 = 1;
+ private static final int BYTE_1_MASK = 0xFF00;
+ private static final int BYTE_1_SHIFT = 8;
+
+ private static final int BYTE_2 = 2;
+ private static final int BYTE_2_MASK = 0xFF0000;
+ private static final int BYTE_2_SHIFT = 16;
+
+ private static final int BYTE_3 = 3;
+ private static final long BYTE_3_MASK = 0xFF000000L;
+ private static final int BYTE_3_SHIFT = 24;
+
+ private static final int BYTE_4 = 4;
+ private static final long BYTE_4_MASK = 0xFF00000000L;
+ private static final int BYTE_4_SHIFT = 32;
+
+ private static final int BYTE_5 = 5;
+ private static final long BYTE_5_MASK = 0xFF0000000000L;
+ private static final int BYTE_5_SHIFT = 40;
+
+ private static final int BYTE_6 = 6;
+ private static final long BYTE_6_MASK = 0xFF000000000000L;
+ private static final int BYTE_6_SHIFT = 48;
+
+ private static final int BYTE_7 = 7;
+ private static final long BYTE_7_MASK = 0x7F00000000000000L;
+ private static final int BYTE_7_SHIFT = 56;
+
+ private static final int LEFTMOST_BIT_SHIFT = 63;
+ private static final byte LEFTMOST_BIT = (byte) 0x80;
+
+ private final BigInteger value;
+
+ public static final ZipEightByteInteger ZERO = new ZipEightByteInteger(0);
+
+ /**
+ * Create instance from a number.
+ * @param value the long to store as a ZipEightByteInteger
+ */
+ public ZipEightByteInteger(long value) {
+ this(BigInteger.valueOf(value));
+ }
+
+ /**
+ * Create instance from a number.
+ * @param value the BigInteger to store as a ZipEightByteInteger
+ */
+ public ZipEightByteInteger(BigInteger value) {
+ this.value = value;
+ }
+
+ /**
+ * Create instance from bytes.
+ * @param bytes the bytes to store as a ZipEightByteInteger
+ */
+ public ZipEightByteInteger (byte[] bytes) {
+ this(bytes, 0);
+ }
+
+ /**
+ * Create instance from the eight bytes starting at offset.
+ * @param bytes the bytes to store as a ZipEightByteInteger
+ * @param offset the offset to start
+ */
+ public ZipEightByteInteger (byte[] bytes, int offset) {
+ value = ZipEightByteInteger.getValue(bytes, offset);
+ }
+
+ /**
+ * Get value as eight bytes in big endian byte order.
+ * @return value as eight bytes in big endian order
+ */
+ public byte[] getBytes() {
+ return ZipEightByteInteger.getBytes(value);
+ }
+
+ /**
+ * Get value as Java long.
+ * @return value as a long
+ */
+ public long getLongValue() {
+ return value.longValue();
+ }
+
+ /**
+ * Get value as Java long.
+ * @return value as a long
+ */
+ public BigInteger getValue() {
+ return value;
+ }
+
+ /**
+ * Get value as eight bytes in big endian byte order.
+ * @param value the value to convert
+ * @return value as eight bytes in big endian byte order
+ */
+ public static byte[] getBytes(long value) {
+ return getBytes(BigInteger.valueOf(value));
+ }
+
+ /**
+ * Get value as eight bytes in big endian byte order.
+ * @param value the value to convert
+ * @return value as eight bytes in big endian byte order
+ */
+ public static byte[] getBytes(BigInteger value) {
+ byte[] result = new byte[8];
+ long val = value.longValue();
+ result[0] = (byte) ((val & BYTE_MASK));
+ result[BYTE_1] = (byte) ((val & BYTE_1_MASK) >> BYTE_1_SHIFT);
+ result[BYTE_2] = (byte) ((val & BYTE_2_MASK) >> BYTE_2_SHIFT);
+ result[BYTE_3] = (byte) ((val & BYTE_3_MASK) >> BYTE_3_SHIFT);
+ result[BYTE_4] = (byte) ((val & BYTE_4_MASK) >> BYTE_4_SHIFT);
+ result[BYTE_5] = (byte) ((val & BYTE_5_MASK) >> BYTE_5_SHIFT);
+ result[BYTE_6] = (byte) ((val & BYTE_6_MASK) >> BYTE_6_SHIFT);
+ result[BYTE_7] = (byte) ((val & BYTE_7_MASK) >> BYTE_7_SHIFT);
+ if (value.testBit(LEFTMOST_BIT_SHIFT)) {
+ result[BYTE_7] |= LEFTMOST_BIT;
+ }
+ return result;
+ }
+
+ /**
+ * Helper method to get the value as a Java long from eight bytes
+ * starting at given array offset
+ * @param bytes the array of bytes
+ * @param offset the offset to start
+ * @return the corresponding Java long value
+ */
+ public static long getLongValue(byte[] bytes, int offset) {
+ return getValue(bytes, offset).longValue();
+ }
+
+ /**
+ * Helper method to get the value as a Java BigInteger from eight
+ * bytes starting at given array offset
+ * @param bytes the array of bytes
+ * @param offset the offset to start
+ * @return the corresponding Java BigInteger value
+ */
+ public static BigInteger getValue(byte[] bytes, int offset) {
+ long value = ((long) bytes[offset + BYTE_7] << BYTE_7_SHIFT) & BYTE_7_MASK;
+ value += ((long) bytes[offset + BYTE_6] << BYTE_6_SHIFT) & BYTE_6_MASK;
+ value += ((long) bytes[offset + BYTE_5] << BYTE_5_SHIFT) & BYTE_5_MASK;
+ value += ((long) bytes[offset + BYTE_4] << BYTE_4_SHIFT) & BYTE_4_MASK;
+ value += ((long) bytes[offset + BYTE_3] << BYTE_3_SHIFT) & BYTE_3_MASK;
+ value += ((long) bytes[offset + BYTE_2] << BYTE_2_SHIFT) & BYTE_2_MASK;
+ value += ((long) bytes[offset + BYTE_1] << BYTE_1_SHIFT) & BYTE_1_MASK;
+ value += ((long) bytes[offset] & BYTE_MASK);
+ BigInteger val = BigInteger.valueOf(value);
+ return (bytes[offset + BYTE_7] & LEFTMOST_BIT) == LEFTMOST_BIT
+ ? val.setBit(LEFTMOST_BIT_SHIFT) : val;
+ }
+
+ /**
+ * Helper method to get the value as a Java long from an eight-byte array
+ * @param bytes the array of bytes
+ * @return the corresponding Java long value
+ */
+ public static long getLongValue(byte[] bytes) {
+ return getLongValue(bytes, 0);
+ }
+
+ /**
+ * Helper method to get the value as a Java long from an eight-byte array
+ * @param bytes the array of bytes
+ * @return the corresponding Java BigInteger value
+ */
+ public static BigInteger getValue(byte[] bytes) {
+ return getValue(bytes, 0);
+ }
+
+ /**
+ * Override to make two instances with same value equal.
+ * @param o an object to compare
+ * @return true if the objects are equal
+ */
+ @Override
+ public boolean equals(Object o) {
+ if (o == null || !(o instanceof ZipEightByteInteger)) {
+ return false;
+ }
+ return value.equals(((ZipEightByteInteger) o).getValue());
+ }
+
+ /**
+ * Override to make two instances with same value equal.
+ * @return the hashCode of the value stored in the ZipEightByteInteger
+ */
+ @Override
+ public int hashCode() {
+ return value.hashCode();
+ }
+
+ @Override
+ public String toString() {
+ return "ZipEightByteInteger value: " + value;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/ZipEncoding.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/ZipEncoding.java
new file mode 100644
index 00000000..72653834
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/ZipEncoding.java
@@ -0,0 +1,84 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tools.zip;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+/**
+ * An interface for encoders that do a pretty encoding of ZIP
+ * filenames.
+ *
+ * <p>There are mostly two implementations, one that uses java.nio
+ * {@link java.nio.charset.Charset Charset} and one implementation,
+ * which copes with simple 8 bit charsets, because java-1.4 did not
+ * support Cp437 in java.nio.</p>
+ *
+ * <p>The main reason for defining an own encoding layer comes from
+ * the problems with {@link java.lang.String#getBytes(String)
+ * String.getBytes}, which encodes unknown characters as ASCII
+ * quotation marks ('?'). Quotation marks are per definition an
+ * invalid filename on some operating systems like Windows, which
+ * leads to ignored ZIP entries.</p>
+ *
+ * <p>All implementations should implement this interface in a
+ * reentrant way.</p>
+ */
+public interface ZipEncoding {
+ /**
+ * Check, whether the given string may be losslessly encoded using this
+ * encoding.
+ *
+ * @param name A filename or ZIP comment.
+ * @return Whether the given name may be encoded with out any losses.
+ */
+ boolean canEncode(String name);
+
+ /**
+ * Encode a filename or a comment to a byte array suitable for
+ * storing it to a serialized zip entry.
+ *
+ * <p>Examples for CP 437 (in pseudo-notation, right hand side is
+ * C-style notation):</p>
+ * <pre>
+ * encode("\u20AC_for_Dollar.txt") = "%U20AC_for_Dollar.txt"
+ * encode("\u00D6lf\u00E4sser.txt") = "\231lf\204sser.txt"
+ * </pre>
+ *
+ * @param name A filename or ZIP comment.
+ * @return A byte buffer with a backing array containing the
+ * encoded name. Unmappable characters or malformed
+ * character sequences are mapped to a sequence of utf-16
+ * words encoded in the format <code>%Uxxxx</code>. It is
+ * assumed, that the byte buffer is positioned at the
+ * beginning of the encoded result, the byte buffer has a
+ * backing array and the limit of the byte buffer points
+ * to the end of the encoded result.
+ * @throws IOException
+ */
+ ByteBuffer encode(String name) throws IOException;
+
+ /**
+ * @param data The byte values to decode.
+ * @return The decoded string.
+ * @throws IOException
+ */
+ String decode(byte [] data) throws IOException;
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/ZipEncodingHelper.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/ZipEncodingHelper.java
new file mode 100644
index 00000000..4d3dab95
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/ZipEncodingHelper.java
@@ -0,0 +1,252 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.zip;
+
+import java.nio.ByteBuffer;
+import java.nio.charset.Charset;
+import java.nio.charset.UnsupportedCharsetException;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Static helper functions for robustly encoding filenames in zip files.
+ */
+public abstract class ZipEncodingHelper {
+
+ /**
+ * A class, which holds the high characters of a simple encoding
+ * and lazily instantiates a Simple8BitZipEncoding instance in a
+ * thread-safe manner.
+ */
+ private static class SimpleEncodingHolder {
+
+ private final char [] highChars;
+ private Simple8BitZipEncoding encoding;
+
+ /**
+ * Instantiate a simple encoding holder.
+ *
+ * @param highChars The characters for byte codes 128 to 255.
+ *
+ * @see Simple8BitZipEncoding#Simple8BitZipEncoding(char[])
+ */
+ SimpleEncodingHolder(final char [] highChars) {
+ this.highChars = highChars;
+ }
+
+ /**
+ * @return The associated {@link Simple8BitZipEncoding}, which
+ * is instantiated if not done so far.
+ */
+ public synchronized Simple8BitZipEncoding getEncoding() {
+ if (this.encoding == null) {
+ this.encoding = new Simple8BitZipEncoding(this.highChars);
+ }
+ return this.encoding;
+ }
+ }
+
+ private static final Map<String, SimpleEncodingHolder> simpleEncodings;
+
+ static {
+ final Map<String, SimpleEncodingHolder> se =
+ new HashMap<String, SimpleEncodingHolder>();
+
+ final char[] cp437_high_chars =
+ new char[] {0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0,
+ 0x00e5, 0x00e7, 0x00ea, 0x00eb, 0x00e8, 0x00ef,
+ 0x00ee, 0x00ec, 0x00c4, 0x00c5, 0x00c9, 0x00e6,
+ 0x00c6, 0x00f4, 0x00f6, 0x00f2, 0x00fb, 0x00f9,
+ 0x00ff, 0x00d6, 0x00dc, 0x00a2, 0x00a3, 0x00a5,
+ 0x20a7, 0x0192, 0x00e1, 0x00ed, 0x00f3, 0x00fa,
+ 0x00f1, 0x00d1, 0x00aa, 0x00ba, 0x00bf, 0x2310,
+ 0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb,
+ 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561,
+ 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557,
+ 0x255d, 0x255c, 0x255b, 0x2510, 0x2514, 0x2534,
+ 0x252c, 0x251c, 0x2500, 0x253c, 0x255e, 0x255f,
+ 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550,
+ 0x256c, 0x2567, 0x2568, 0x2564, 0x2565, 0x2559,
+ 0x2558, 0x2552, 0x2553, 0x256b, 0x256a, 0x2518,
+ 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580,
+ 0x03b1, 0x00df, 0x0393, 0x03c0, 0x03a3, 0x03c3,
+ 0x00b5, 0x03c4, 0x03a6, 0x0398, 0x03a9, 0x03b4,
+ 0x221e, 0x03c6, 0x03b5, 0x2229, 0x2261, 0x00b1,
+ 0x2265, 0x2264, 0x2320, 0x2321, 0x00f7, 0x2248,
+ 0x00b0, 0x2219, 0x00b7, 0x221a, 0x207f, 0x00b2,
+ 0x25a0, 0x00a0};
+
+ final SimpleEncodingHolder cp437 = new SimpleEncodingHolder(cp437_high_chars);
+
+ se.put("CP437", cp437);
+ se.put("Cp437", cp437);
+ se.put("cp437", cp437);
+ se.put("IBM437", cp437);
+ se.put("ibm437", cp437);
+
+ final char[] cp850_high_chars =
+ new char[] {0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0,
+ 0x00e5, 0x00e7, 0x00ea, 0x00eb, 0x00e8, 0x00ef,
+ 0x00ee, 0x00ec, 0x00c4, 0x00c5, 0x00c9, 0x00e6,
+ 0x00c6, 0x00f4, 0x00f6, 0x00f2, 0x00fb, 0x00f9,
+ 0x00ff, 0x00d6, 0x00dc, 0x00f8, 0x00a3, 0x00d8,
+ 0x00d7, 0x0192, 0x00e1, 0x00ed, 0x00f3, 0x00fa,
+ 0x00f1, 0x00d1, 0x00aa, 0x00ba, 0x00bf, 0x00ae,
+ 0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb,
+ 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00c1,
+ 0x00c2, 0x00c0, 0x00a9, 0x2563, 0x2551, 0x2557,
+ 0x255d, 0x00a2, 0x00a5, 0x2510, 0x2514, 0x2534,
+ 0x252c, 0x251c, 0x2500, 0x253c, 0x00e3, 0x00c3,
+ 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550,
+ 0x256c, 0x00a4, 0x00f0, 0x00d0, 0x00ca, 0x00cb,
+ 0x00c8, 0x0131, 0x00cd, 0x00ce, 0x00cf, 0x2518,
+ 0x250c, 0x2588, 0x2584, 0x00a6, 0x00cc, 0x2580,
+ 0x00d3, 0x00df, 0x00d4, 0x00d2, 0x00f5, 0x00d5,
+ 0x00b5, 0x00fe, 0x00de, 0x00da, 0x00db, 0x00d9,
+ 0x00fd, 0x00dd, 0x00af, 0x00b4, 0x00ad, 0x00b1,
+ 0x2017, 0x00be, 0x00b6, 0x00a7, 0x00f7, 0x00b8,
+ 0x00b0, 0x00a8, 0x00b7, 0x00b9, 0x00b3, 0x00b2,
+ 0x25a0, 0x00a0};
+
+ final SimpleEncodingHolder cp850 = new SimpleEncodingHolder(cp850_high_chars);
+
+ se.put("CP850", cp850);
+ se.put("Cp850", cp850);
+ se.put("cp850", cp850);
+ se.put("IBM850", cp850);
+ se.put("ibm850", cp850);
+ simpleEncodings = Collections.unmodifiableMap(se);
+ }
+
+ /**
+ * Grow a byte buffer, so it has a minimal capacity or at least
+ * the double capacity of the original buffer
+ *
+ * @param b The original buffer.
+ * @param newCapacity The minimal requested new capacity.
+ * @return A byte buffer <code>r</code> with
+ * <code>r.capacity() = max(b.capacity()*2,newCapacity)</code> and
+ * all the data contained in <code>b</code> copied to the beginning
+ * of <code>r</code>.
+ *
+ */
+ static ByteBuffer growBuffer(final ByteBuffer b, final int newCapacity) {
+ b.limit(b.position());
+ b.rewind();
+
+ final int c2 = b.capacity() * 2;
+ final ByteBuffer on = ByteBuffer.allocate(c2 < newCapacity ? newCapacity : c2);
+
+ on.put(b);
+ return on;
+ }
+
+
+ /**
+ * The hexadecimal digits <code>0,...,9,A,...,F</code> encoded as
+ * ASCII bytes.
+ */
+ private static final byte[] HEX_DIGITS =
+ new byte [] {
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x41,
+ 0x42, 0x43, 0x44, 0x45, 0x46
+ };
+
+ /**
+ * Append <code>%Uxxxx</code> to the given byte buffer.
+ * The caller must assure, that <code>bb.remaining()&gt;=6</code>.
+ *
+ * @param bb The byte buffer to write to.
+ * @param c The character to write.
+ */
+ static void appendSurrogate(final ByteBuffer bb, final char c) {
+
+ bb.put((byte) '%');
+ bb.put((byte) 'U');
+
+ bb.put(HEX_DIGITS[(c >> 12)&0x0f]);
+ bb.put(HEX_DIGITS[(c >> 8)&0x0f]);
+ bb.put(HEX_DIGITS[(c >> 4)&0x0f]);
+ bb.put(HEX_DIGITS[c & 0x0f]);
+ }
+
+
+ /**
+ * name of the encoding UTF-8
+ */
+ static final String UTF8 = "UTF8";
+
+ /**
+ * variant name of the encoding UTF-8 used for comparisons.
+ */
+ private static final String UTF_DASH_8 = "utf-8";
+
+ /**
+ * name of the encoding UTF-8
+ */
+ static final ZipEncoding UTF8_ZIP_ENCODING = new FallbackZipEncoding(UTF8);
+
+ /**
+ * Instantiates a zip encoding.
+ *
+ * @param name The name of the zip encoding. Specify {@code null} for
+ * the platform's default encoding.
+ * @return A zip encoding for the given encoding name.
+ */
+ public static ZipEncoding getZipEncoding(final String name) {
+
+ // fallback encoding is good enough for utf-8.
+ if (isUTF8(name)) {
+ return UTF8_ZIP_ENCODING;
+ }
+
+ if (name == null) {
+ return new FallbackZipEncoding();
+ }
+
+ final SimpleEncodingHolder h = simpleEncodings.get(name);
+
+ if (h!=null) {
+ return h.getEncoding();
+ }
+
+ try {
+
+ final Charset cs = Charset.forName(name);
+ return new NioZipEncoding(cs);
+
+ } catch (final UnsupportedCharsetException e) {
+ return new FallbackZipEncoding(name);
+ }
+ }
+
+ /**
+ * Whether a given encoding - or the platform's default encoding
+ * if the parameter is null - is UTF-8.
+ */
+ static boolean isUTF8(String encoding) {
+ if (encoding == null) {
+ // check platform's default encoding
+ encoding = System.getProperty("file.encoding");
+ }
+ return UTF8.equalsIgnoreCase(encoding)
+ || UTF_DASH_8.equalsIgnoreCase(encoding);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/ZipEntry.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/ZipEntry.java
new file mode 100644
index 00000000..30a8155b
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/ZipEntry.java
@@ -0,0 +1,786 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.zip;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.List;
+import java.util.zip.ZipException;
+
+/**
+ * Extension that adds better handling of extra fields and provides
+ * access to the internal and external file attributes.
+ *
+ * <p>The extra data is expected to follow the recommendation of
+ * {@link <a href="http://www.pkware.com/documents/casestudies/APPNOTE.TXT">
+ * APPNOTE.txt</a>}:</p>
+ * <ul>
+ * <li>the extra byte array consists of a sequence of extra fields</li>
+ * <li>each extra fields starts by a two byte header id followed by
+ * a two byte sequence holding the length of the remainder of
+ * data.</li>
+ * </ul>
+ *
+ * <p>Any extra data that cannot be parsed by the rules above will be
+ * consumed as "unparseable" extra data and treated differently by the
+ * methods of this class. Older versions would have thrown an
+ * exception if any attempt was made to read or write extra data not
+ * conforming to the recommendation.</p>
+ *
+ */
+public class ZipEntry extends java.util.zip.ZipEntry implements Cloneable {
+
+ public static final int PLATFORM_UNIX = 3;
+ public static final int PLATFORM_FAT = 0;
+ public static final int CRC_UNKNOWN = -1;
+ private static final int SHORT_MASK = 0xFFFF;
+ private static final int SHORT_SHIFT = 16;
+ private static final byte[] EMPTY = new byte[0];
+
+ /**
+ * The {@link java.util.zip.ZipEntry} base class only supports
+ * the compression methods STORED and DEFLATED. We override the
+ * field so that any compression methods can be used.
+ * <p>
+ * The default value -1 means that the method has not been specified.
+ */
+ private int method = -1;
+
+ /**
+ * The {@link java.util.zip.ZipEntry#setSize} method in the base
+ * class throws an IllegalArgumentException if the size is bigger
+ * than 2GB for Java versions < 7. Need to keep our own size
+ * information for Zip64 support.
+ */
+ private long size = -1;
+
+ private int internalAttributes = 0;
+ private int platform = PLATFORM_FAT;
+ private long externalAttributes = 0;
+ private ZipExtraField[] extraFields;
+ private UnparseableExtraFieldData unparseableExtra = null;
+ private String name = null;
+ private byte[] rawName = null;
+ private GeneralPurposeBit gpb = new GeneralPurposeBit();
+ private static final ZipExtraField[] noExtraFields = new ZipExtraField[0];
+
+ /**
+ * Creates a new zip entry with the specified name.
+ *
+ * <p>Assumes the entry represents a directory if and only if the
+ * name ends with a forward slash "/".</p>
+ *
+ * @param name the name of the entry
+ * @since 1.1
+ */
+ public ZipEntry(final String name) {
+ super(name);
+ setName(name);
+ }
+
+ /**
+ * Creates a new zip entry with fields taken from the specified zip entry.
+ *
+ * <p>Assumes the entry represents a directory if and only if the
+ * name ends with a forward slash "/".</p>
+ *
+ * @param entry the entry to get fields from
+ * @since 1.1
+ * @throws ZipException on error
+ */
+ public ZipEntry(final java.util.zip.ZipEntry entry) throws ZipException {
+ super(entry);
+ setName(entry.getName());
+ final byte[] extra = entry.getExtra();
+ if (extra != null) {
+ setExtraFields(ExtraFieldUtils.parse(extra, true,
+ ExtraFieldUtils
+ .UnparseableExtraField.READ));
+ } else {
+ // initializes extra data to an empty byte array
+ setExtra();
+ }
+ setMethod(entry.getMethod());
+ this.size = entry.getSize();
+ }
+
+ /**
+ * Creates a new zip entry with fields taken from the specified zip entry.
+ *
+ * <p>Assumes the entry represents a directory if and only if the
+ * name ends with a forward slash "/".</p>
+ *
+ * @param entry the entry to get fields from
+ * @throws ZipException on error
+ * @since 1.1
+ */
+ public ZipEntry(final ZipEntry entry) throws ZipException {
+ this((java.util.zip.ZipEntry) entry);
+ setInternalAttributes(entry.getInternalAttributes());
+ setExternalAttributes(entry.getExternalAttributes());
+ setExtraFields(getAllExtraFieldsNoCopy());
+ setPlatform(entry.getPlatform());
+ GeneralPurposeBit other = entry.getGeneralPurposeBit();
+ setGeneralPurposeBit(other == null ? null :
+ (GeneralPurposeBit) other.clone());
+ }
+
+ /**
+ * @since 1.9
+ */
+ protected ZipEntry() {
+ this("");
+ }
+
+ /**
+ * Creates a new zip entry taking some information from the given
+ * file and using the provided name.
+ *
+ * <p>The name will be adjusted to end with a forward slash "/" if
+ * the file is a directory. If the file is not a directory a
+ * potential trailing forward slash will be stripped from the
+ * entry name.</p>
+ */
+ public ZipEntry(final File inputFile, final String entryName) {
+ this(inputFile.isDirectory() && !entryName.endsWith("/") ?
+ entryName + "/" : entryName);
+ if (inputFile.isFile()){
+ setSize(inputFile.length());
+ }
+ setTime(inputFile.lastModified());
+ // TODO are there any other fields we can set here?
+ }
+
+ /**
+ * Overwrite clone.
+ * @return a cloned copy of this ZipEntry
+ * @since 1.1
+ */
+ @Override
+ public Object clone() {
+ final ZipEntry e = (ZipEntry) super.clone();
+
+ e.setInternalAttributes(getInternalAttributes());
+ e.setExternalAttributes(getExternalAttributes());
+ e.setExtraFields(getAllExtraFieldsNoCopy());
+ return e;
+ }
+
+ /**
+ * Returns the compression method of this entry, or -1 if the
+ * compression method has not been specified.
+ *
+ * @return compression method
+ */
+ @Override
+ public int getMethod() {
+ return method;
+ }
+
+ /**
+ * Sets the compression method of this entry.
+ *
+ * @param method compression method
+ */
+ @Override
+ public void setMethod(final int method) {
+ if (method < 0) {
+ throw new IllegalArgumentException(
+ "ZIP compression method can not be negative: " + method);
+ }
+ this.method = method;
+ }
+
+ /**
+ * Retrieves the internal file attributes.
+ *
+ * @return the internal file attributes
+ * @since 1.1
+ */
+ public int getInternalAttributes() {
+ return internalAttributes;
+ }
+
+ /**
+ * Sets the internal file attributes.
+ * @param value an <code>int</code> value
+ * @since 1.1
+ */
+ public void setInternalAttributes(final int value) {
+ internalAttributes = value;
+ }
+
+ /**
+ * Retrieves the external file attributes.
+ * @return the external file attributes
+ * @since 1.1
+ */
+ public long getExternalAttributes() {
+ return externalAttributes;
+ }
+
+ /**
+ * Sets the external file attributes.
+ * @param value an <code>long</code> value
+ * @since 1.1
+ */
+ public void setExternalAttributes(final long value) {
+ externalAttributes = value;
+ }
+
+ /**
+ * Sets Unix permissions in a way that is understood by Info-Zip's
+ * unzip command.
+ * @param mode an <code>int</code> value
+ * @since Ant 1.5.2
+ */
+ public void setUnixMode(final int mode) {
+ // CheckStyle:MagicNumberCheck OFF - no point
+ setExternalAttributes((mode << SHORT_SHIFT)
+ // MS-DOS read-only attribute
+ | ((mode & 0200) == 0 ? 1 : 0)
+ // MS-DOS directory flag
+ | (isDirectory() ? 0x10 : 0));
+ // CheckStyle:MagicNumberCheck ON
+ platform = PLATFORM_UNIX;
+ }
+
+ /**
+ * Unix permission.
+ * @return the unix permissions
+ * @since Ant 1.6
+ */
+ public int getUnixMode() {
+ return platform != PLATFORM_UNIX ? 0 :
+ (int) ((getExternalAttributes() >> SHORT_SHIFT) & SHORT_MASK);
+ }
+
+ /**
+ * Platform specification to put into the &quot;version made
+ * by&quot; part of the central file header.
+ *
+ * @return PLATFORM_FAT unless {@link #setUnixMode setUnixMode}
+ * has been called, in which case PLATFORM_UNIX will be returned.
+ *
+ * @since Ant 1.5.2
+ */
+ public int getPlatform() {
+ return platform;
+ }
+
+ /**
+ * Set the platform (UNIX or FAT).
+ * @param platform an <code>int</code> value - 0 is FAT, 3 is UNIX
+ * @since 1.9
+ */
+ protected void setPlatform(final int platform) {
+ this.platform = platform;
+ }
+
+ /**
+ * Replaces all currently attached extra fields with the new array.
+ * @param fields an array of extra fields
+ * @since 1.1
+ */
+ public void setExtraFields(final ZipExtraField[] fields) {
+ List<ZipExtraField> newFields = new ArrayList<ZipExtraField>();
+ for (ZipExtraField field : fields) {
+ if (field instanceof UnparseableExtraFieldData) {
+ unparseableExtra = (UnparseableExtraFieldData) field;
+ } else {
+ newFields.add( field);
+ }
+ }
+ extraFields = newFields.toArray(new ZipExtraField[newFields.size()]);
+ setExtra();
+ }
+
+ /**
+ * Retrieves all extra fields that have been parsed successfully.
+ * @return an array of the extra fields
+ */
+ public ZipExtraField[] getExtraFields() {
+ return getParseableExtraFields();
+ }
+
+ /**
+ * Retrieves extra fields.
+ * @param includeUnparseable whether to also return unparseable
+ * extra fields as {@link UnparseableExtraFieldData} if such data
+ * exists.
+ * @return an array of the extra fields
+ * @since 1.1
+ */
+ public ZipExtraField[] getExtraFields(final boolean includeUnparseable) {
+ return includeUnparseable ?
+ getAllExtraFields() :
+ getParseableExtraFields();
+ }
+
+ private ZipExtraField[] getParseableExtraFieldsNoCopy() {
+ if (extraFields == null) {
+ return noExtraFields;
+ }
+ return extraFields;
+ }
+
+ private ZipExtraField[] getParseableExtraFields() {
+ final ZipExtraField[] parseableExtraFields = getParseableExtraFieldsNoCopy();
+ return (parseableExtraFields == extraFields)
+ ? copyOf(parseableExtraFields) : parseableExtraFields;
+ }
+
+ private ZipExtraField[] copyOf(ZipExtraField[] src){
+ return copyOf(src, src.length);
+ }
+
+ private ZipExtraField[] copyOf(ZipExtraField[] src, int length){
+ ZipExtraField[] cpy = new ZipExtraField[length];
+ System.arraycopy(src, 0, cpy, 0, Math.min(src.length, length));
+ return cpy;
+ }
+
+ private ZipExtraField[] getMergedFields() {
+ final ZipExtraField[] zipExtraFields =
+ copyOf(extraFields, extraFields.length + 1);
+ zipExtraFields[extraFields.length] = unparseableExtra;
+ return zipExtraFields;
+ }
+
+ private ZipExtraField[] getUnparseableOnly() {
+ return unparseableExtra == null
+ ? noExtraFields : new ZipExtraField[] { unparseableExtra };
+ }
+
+ private ZipExtraField[] getAllExtraFields() {
+ final ZipExtraField[] allExtraFieldsNoCopy = getAllExtraFieldsNoCopy();
+ return (allExtraFieldsNoCopy == extraFields)
+ ? copyOf(allExtraFieldsNoCopy) : allExtraFieldsNoCopy;
+ }
+
+ /**
+ * Get all extra fields, including unparseable ones.
+ * @return An array of all extra fields. Not necessarily a copy of internal data structures, hence private method
+ */
+ private ZipExtraField[] getAllExtraFieldsNoCopy() {
+ if (extraFields == null) {
+ return getUnparseableOnly();
+ }
+ return unparseableExtra != null ? getMergedFields() : extraFields;
+ }
+
+ /**
+ * Adds an extra field - replacing an already present extra field
+ * of the same type.
+ *
+ * <p>If no extra field of the same type exists, the field will be
+ * added as last field.</p>
+ * @param ze an extra field
+ * @since 1.1
+ */
+ public void addExtraField(final ZipExtraField ze) {
+ if (ze instanceof UnparseableExtraFieldData) {
+ unparseableExtra = (UnparseableExtraFieldData) ze;
+ } else {
+ if (extraFields == null) {
+ extraFields = new ZipExtraField[] {ze};
+ } else {
+ if (getExtraField(ze.getHeaderId()) != null){
+ removeExtraField(ze.getHeaderId());
+ }
+ final ZipExtraField[] zipExtraFields =
+ copyOf(extraFields, extraFields.length + 1);
+ zipExtraFields[extraFields.length] = ze;
+ extraFields = zipExtraFields;
+ }
+ }
+ setExtra();
+ }
+
+ /**
+ * Adds an extra field - replacing an already present extra field
+ * of the same type.
+ *
+ * <p>The new extra field will be the first one.</p>
+ * @param ze an extra field
+ * @since 1.1
+ */
+ public void addAsFirstExtraField(final ZipExtraField ze) {
+ if (ze instanceof UnparseableExtraFieldData) {
+ unparseableExtra = (UnparseableExtraFieldData) ze;
+ } else {
+ if (getExtraField(ze.getHeaderId()) != null){
+ removeExtraField(ze.getHeaderId());
+ }
+ ZipExtraField[] copy = extraFields;
+ int newLen = extraFields != null ? extraFields.length + 1: 1;
+ extraFields = new ZipExtraField[newLen];
+ extraFields[0] = ze;
+ if (copy != null){
+ System.arraycopy(copy, 0, extraFields, 1, extraFields.length - 1);
+ }
+ }
+ setExtra();
+ }
+
+ /**
+ * Remove an extra field.
+ * @param type the type of extra field to remove
+ * @since 1.1
+ */
+ public void removeExtraField(final ZipShort type) {
+ if (extraFields == null) {
+ throw new java.util.NoSuchElementException();
+ }
+ List<ZipExtraField> newResult = new ArrayList<ZipExtraField>();
+ for (ZipExtraField extraField : extraFields) {
+ if (!type.equals(extraField.getHeaderId())){
+ newResult.add(extraField);
+ }
+ }
+ if (extraFields.length == newResult.size()) {
+ throw new java.util.NoSuchElementException();
+ }
+ extraFields = newResult.toArray(new ZipExtraField[newResult.size()]);
+ setExtra();
+ }
+
+ /**
+ * Removes unparseable extra field data.
+ */
+ public void removeUnparseableExtraFieldData() {
+ if (unparseableExtra == null) {
+ throw new java.util.NoSuchElementException();
+ }
+ unparseableExtra = null;
+ setExtra();
+ }
+
+ /**
+ * Looks up an extra field by its header id.
+ *
+ * @return null if no such field exists.
+ */
+ public ZipExtraField getExtraField(final ZipShort type) {
+ if (extraFields != null) {
+ for (ZipExtraField extraField : extraFields) {
+ if (type.equals(extraField.getHeaderId())) {
+ return extraField;
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Looks up extra field data that couldn't be parsed correctly.
+ *
+ * @return null if no such field exists.
+ */
+ public UnparseableExtraFieldData getUnparseableExtraFieldData() {
+ return unparseableExtra;
+ }
+
+ /**
+ * Parses the given bytes as extra field data and consumes any
+ * unparseable data as an {@link UnparseableExtraFieldData}
+ * instance.
+ * @param extra an array of bytes to be parsed into extra fields
+ * @throws RuntimeException if the bytes cannot be parsed
+ * @since 1.1
+ * @throws RuntimeException on error
+ */
+ @Override
+ public void setExtra(final byte[] extra) throws RuntimeException {
+ try {
+ final ZipExtraField[] local =
+ ExtraFieldUtils.parse(extra, true,
+ ExtraFieldUtils.UnparseableExtraField.READ);
+ mergeExtraFields(local, true);
+ } catch (final ZipException e) {
+ // actually this is not be possible as of Ant 1.8.1
+ throw new RuntimeException("Error parsing extra fields for entry: "
+ + getName() + " - " + e.getMessage(), e);
+ }
+ }
+
+ /**
+ * Unfortunately {@link java.util.zip.ZipOutputStream
+ * java.util.zip.ZipOutputStream} seems to access the extra data
+ * directly, so overriding getExtra doesn't help - we need to
+ * modify super's data directly.
+ *
+ * @since 1.1
+ */
+ protected void setExtra() {
+ super.setExtra(ExtraFieldUtils.mergeLocalFileDataData(getExtraFields(true)));
+ }
+
+ /**
+ * Sets the central directory part of extra fields.
+ */
+ public void setCentralDirectoryExtra(final byte[] b) {
+ try {
+ final ZipExtraField[] central =
+ ExtraFieldUtils.parse(b, false,
+ ExtraFieldUtils.UnparseableExtraField.READ);
+ mergeExtraFields(central, false);
+ } catch (final ZipException e) {
+ throw new RuntimeException(e.getMessage(), e);
+ }
+ }
+
+ /**
+ * Retrieves the extra data for the local file data.
+ * @return the extra data for local file
+ * @since 1.1
+ */
+ public byte[] getLocalFileDataExtra() {
+ final byte[] extra = getExtra();
+ return extra != null ? extra : EMPTY;
+ }
+
+ /**
+ * Retrieves the extra data for the central directory.
+ * @return the central directory extra data
+ * @since 1.1
+ */
+ public byte[] getCentralDirectoryExtra() {
+ return ExtraFieldUtils.mergeCentralDirectoryData(getExtraFields(true));
+ }
+
+ /**
+ * Make this class work in JDK 1.1 like a 1.2 class.
+ *
+ * <p>This either stores the size for later usage or invokes
+ * setCompressedSize via reflection.</p>
+ * @param size the size to use
+ * @deprecated since 1.7.
+ * Use setCompressedSize directly.
+ * @since 1.2
+ */
+ @Deprecated
+ public void setComprSize(final long size) {
+ setCompressedSize(size);
+ }
+
+ /**
+ * Get the name of the entry.
+ * @return the entry name
+ * @since 1.9
+ */
+ @Override
+ public String getName() {
+ return name == null ? super.getName() : name;
+ }
+
+ /**
+ * Is this entry a directory?
+ * @return true if the entry is a directory
+ * @since 1.10
+ */
+ @Override
+ public boolean isDirectory() {
+ return getName().endsWith("/");
+ }
+
+ /**
+ * Set the name of the entry.
+ * @param name the name to use
+ */
+ protected void setName(String name) {
+ if (name != null && getPlatform() == PLATFORM_FAT
+ && name.indexOf("/") == -1) {
+ name = name.replace('\\', '/');
+ }
+ this.name = name;
+ }
+
+ /**
+ * Gets the uncompressed size of the entry data.
+ * @return the entry size
+ */
+ @Override
+ public long getSize() {
+ return size;
+ }
+
+ /**
+ * Sets the uncompressed size of the entry data.
+ * @param size the uncompressed size in bytes
+ * @exception IllegalArgumentException if the specified size is less
+ * than 0
+ */
+ @Override
+ public void setSize(final long size) {
+ if (size < 0) {
+ throw new IllegalArgumentException("invalid entry size");
+ }
+ this.size = size;
+ }
+
+ /**
+ * Sets the name using the raw bytes and the string created from
+ * it by guessing or using the configured encoding.
+ * @param name the name to use created from the raw bytes using
+ * the guessed or configured encoding
+ * @param rawName the bytes originally read as name from the
+ * archive
+ */
+ protected void setName(final String name, final byte[] rawName) {
+ setName(name);
+ this.rawName = rawName;
+ }
+
+ /**
+ * Returns the raw bytes that made up the name before it has been
+ * converted using the configured or guessed encoding.
+ *
+ * <p>This method will return null if this instance has not been
+ * read from an archive.</p>
+ */
+ public byte[] getRawName() {
+ if (rawName != null) {
+ final byte[] b = new byte[rawName.length];
+ System.arraycopy(rawName, 0, b, 0, rawName.length);
+ return b;
+ }
+ return null;
+ }
+
+ /**
+ * Get the hashCode of the entry.
+ * This uses the name as the hashcode.
+ * @return a hashcode.
+ * @since Ant 1.7
+ */
+ @Override
+ public int hashCode() {
+ // this method has severe consequences on performance. We cannot rely
+ // on the super.hashCode() method since super.getName() always return
+ // the empty string in the current implemention (there's no setter)
+ // so it is basically draining the performance of a hashmap lookup
+ return getName().hashCode();
+ }
+
+ /**
+ * The "general purpose bit" field.
+ */
+ public GeneralPurposeBit getGeneralPurposeBit() {
+ return gpb;
+ }
+
+ /**
+ * The "general purpose bit" field.
+ */
+ public void setGeneralPurposeBit(final GeneralPurposeBit b) {
+ gpb = b;
+ }
+
+ /**
+ * If there are no extra fields, use the given fields as new extra
+ * data - otherwise merge the fields assuming the existing fields
+ * and the new fields stem from different locations inside the
+ * archive.
+ * @param f the extra fields to merge
+ * @param local whether the new fields originate from local data
+ */
+ private void mergeExtraFields(final ZipExtraField[] f, final boolean local)
+ throws ZipException {
+ if (extraFields == null) {
+ setExtraFields(f);
+ } else {
+ for (final ZipExtraField element : f) {
+ ZipExtraField existing;
+ if (element instanceof UnparseableExtraFieldData) {
+ existing = unparseableExtra;
+ } else {
+ existing = getExtraField(element.getHeaderId());
+ }
+ if (existing == null) {
+ addExtraField(element);
+ } else {
+ if (local
+ || !(existing
+ instanceof CentralDirectoryParsingZipExtraField)) {
+ final byte[] b = element.getLocalFileDataData();
+ existing.parseFromLocalFileData(b, 0, b.length);
+ } else {
+ final byte[] b = element.getCentralDirectoryData();
+ ((CentralDirectoryParsingZipExtraField) existing)
+ .parseFromCentralDirectoryData(b, 0, b.length);
+ }
+ }
+ }
+ setExtra();
+ }
+ }
+
+ /** {@inheritDoc} */
+ public Date getLastModifiedDate() {
+ return new Date(getTime());
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(final Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null || getClass() != obj.getClass()) {
+ return false;
+ }
+ final ZipEntry other = (ZipEntry) obj;
+ final String myName = getName();
+ final String otherName = other.getName();
+ if (myName == null) {
+ if (otherName != null) {
+ return false;
+ }
+ } else if (!myName.equals(otherName)) {
+ return false;
+ }
+ String myComment = getComment();
+ String otherComment = other.getComment();
+ if (myComment == null) {
+ myComment = "";
+ }
+ if (otherComment == null) {
+ otherComment = "";
+ }
+ return getTime() == other.getTime()
+ && myComment.equals(otherComment)
+ && getInternalAttributes() == other.getInternalAttributes()
+ && getPlatform() == other.getPlatform()
+ && getExternalAttributes() == other.getExternalAttributes()
+ && getMethod() == other.getMethod()
+ && getSize() == other.getSize()
+ && getCrc() == other.getCrc()
+ && getCompressedSize() == other.getCompressedSize()
+ && Arrays.equals(getCentralDirectoryExtra(),
+ other.getCentralDirectoryExtra())
+ && Arrays.equals(getLocalFileDataExtra(),
+ other.getLocalFileDataExtra())
+ && gpb.equals(other.gpb);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/ZipExtraField.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/ZipExtraField.java
new file mode 100644
index 00000000..649fca00
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/ZipExtraField.java
@@ -0,0 +1,85 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.zip;
+
+import java.util.zip.ZipException;
+
+/**
+ * General format of extra field data.
+ *
+ * <p>Extra fields usually appear twice per file, once in the local
+ * file data and once in the central directory. Usually they are the
+ * same, but they don't have to be. {@link
+ * java.util.zip.ZipOutputStream java.util.zip.ZipOutputStream} will
+ * only use the local file data in both places.</p>
+ *
+ */
+public interface ZipExtraField {
+
+ /**
+ * The Header-ID.
+ * @return the header id
+ * @since 1.1
+ */
+ ZipShort getHeaderId();
+
+ /**
+ * Length of the extra field in the local file data - without
+ * Header-ID or length specifier.
+ * @return the length of the field in the local file data
+ * @since 1.1
+ */
+ ZipShort getLocalFileDataLength();
+
+ /**
+ * Length of the extra field in the central directory - without
+ * Header-ID or length specifier.
+ * @return the length of the field in the central directory
+ * @since 1.1
+ */
+ ZipShort getCentralDirectoryLength();
+
+ /**
+ * The actual data to put into local file data - without Header-ID
+ * or length specifier.
+ * @return the data
+ * @since 1.1
+ */
+ byte[] getLocalFileDataData();
+
+ /**
+ * The actual data to put into central directory - without Header-ID or
+ * length specifier.
+ * @return the data
+ * @since 1.1
+ */
+ byte[] getCentralDirectoryData();
+
+ /**
+ * Populate data from this array as if it was in local file data.
+ * @param data an array of bytes
+ * @param offset the start offset
+ * @param length the number of bytes in the array from offset
+ *
+ * @since 1.1
+ * @throws ZipException on error
+ */
+ void parseFromLocalFileData(byte[] data, int offset, int length)
+ throws ZipException;
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/ZipFile.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/ZipFile.java
new file mode 100644
index 00000000..7a2c9926
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/ZipFile.java
@@ -0,0 +1,1048 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.zip;
+
+import static org.apache.tools.zip.ZipConstants.DWORD;
+import static org.apache.tools.zip.ZipConstants.SHORT;
+import static org.apache.tools.zip.ZipConstants.WORD;
+import static org.apache.tools.zip.ZipConstants.ZIP64_MAGIC;
+import static org.apache.tools.zip.ZipConstants.ZIP64_MAGIC_SHORT;
+
+import java.io.EOFException;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.RandomAccessFile;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.zip.Inflater;
+import java.util.zip.InflaterInputStream;
+import java.util.zip.ZipException;
+
+/**
+ * Replacement for <code>java.util.ZipFile</code>.
+ *
+ * <p>This class adds support for file name encodings other than UTF-8
+ * (which is required to work on ZIP files created by native zip tools
+ * and is able to skip a preamble like the one found in self
+ * extracting archives. Furthermore it returns instances of
+ * <code>org.apache.tools.zip.ZipEntry</code> instead of
+ * <code>java.util.zip.ZipEntry</code>.</p>
+ *
+ * <p>It doesn't extend <code>java.util.zip.ZipFile</code> as it would
+ * have to reimplement all methods anyway. Like
+ * <code>java.util.ZipFile</code>, it uses RandomAccessFile under the
+ * covers and supports compressed and uncompressed entries. As of
+ * Apache Ant 1.9.0 it also transparently supports Zip64
+ * extensions and thus individual entries and archives larger than 4
+ * GB or with more than 65536 entries.</p>
+ *
+ * <p>The method signatures mimic the ones of
+ * <code>java.util.zip.ZipFile</code>, with a couple of exceptions:
+ *
+ * <ul>
+ * <li>There is no getName method.</li>
+ * <li>entries has been renamed to getEntries.</li>
+ * <li>getEntries and getEntry return
+ * <code>org.apache.tools.zip.ZipEntry</code> instances.</li>
+ * <li>close is allowed to throw IOException.</li>
+ * </ul>
+ *
+ */
+public class ZipFile {
+ private static final int HASH_SIZE = 509;
+ static final int NIBLET_MASK = 0x0f;
+ static final int BYTE_SHIFT = 8;
+ private static final int POS_0 = 0;
+ private static final int POS_1 = 1;
+ private static final int POS_2 = 2;
+ private static final int POS_3 = 3;
+
+ /**
+ * List of entries in the order they appear inside the central
+ * directory.
+ */
+ private final List<ZipEntry> entries = new LinkedList<ZipEntry>();
+
+ /**
+ * Maps String to list of ZipEntrys, name -> actual entries.
+ */
+ private final Map<String, LinkedList<ZipEntry>> nameMap =
+ new HashMap<String, LinkedList<ZipEntry>>(HASH_SIZE);
+
+ private static final class OffsetEntry {
+ private long headerOffset = -1;
+ private long dataOffset = -1;
+ }
+
+ /**
+ * The encoding to use for filenames and the file comment.
+ *
+ * <p>For a list of possible values see <a
+ * href="http://java.sun.com/j2se/1.5.0/docs/guide/intl/encoding.doc.html">http://java.sun.com/j2se/1.5.0/docs/guide/intl/encoding.doc.html</a>.
+ * Defaults to the platform's default character encoding.</p>
+ */
+ private final String encoding;
+
+ /**
+ * The zip encoding to use for filenames and the file comment.
+ */
+ private final ZipEncoding zipEncoding;
+
+ /**
+ * File name of actual source.
+ */
+ private final String archiveName;
+
+ /**
+ * The actual data source.
+ */
+ private final RandomAccessFile archive;
+
+ /**
+ * Whether to look for and use Unicode extra fields.
+ */
+ private final boolean useUnicodeExtraFields;
+
+ /**
+ * Whether the file is closed.
+ */
+ private volatile boolean closed;
+
+ // cached buffers
+ private final byte[] DWORD_BUF = new byte[DWORD];
+ private final byte[] WORD_BUF = new byte[WORD];
+ private final byte[] CFH_BUF = new byte[CFH_LEN];
+ private final byte[] SHORT_BUF = new byte[SHORT];
+
+ /**
+ * Opens the given file for reading, assuming the platform's
+ * native encoding for file names.
+ *
+ * @param f the archive.
+ *
+ * @throws IOException if an error occurs while reading the file.
+ */
+ public ZipFile(final File f) throws IOException {
+ this(f, null);
+ }
+
+ /**
+ * Opens the given file for reading, assuming the platform's
+ * native encoding for file names.
+ *
+ * @param name name of the archive.
+ *
+ * @throws IOException if an error occurs while reading the file.
+ */
+ public ZipFile(final String name) throws IOException {
+ this(new File(name), null);
+ }
+
+ /**
+ * Opens the given file for reading, assuming the specified
+ * encoding for file names, scanning unicode extra fields.
+ *
+ * @param name name of the archive.
+ * @param encoding the encoding to use for file names, use null
+ * for the platform's default encoding
+ *
+ * @throws IOException if an error occurs while reading the file.
+ */
+ public ZipFile(final String name, final String encoding) throws IOException {
+ this(new File(name), encoding, true);
+ }
+
+ /**
+ * Opens the given file for reading, assuming the specified
+ * encoding for file names and scanning for unicode extra fields.
+ *
+ * @param f the archive.
+ * @param encoding the encoding to use for file names, use null
+ * for the platform's default encoding
+ *
+ * @throws IOException if an error occurs while reading the file.
+ */
+ public ZipFile(final File f, final String encoding) throws IOException {
+ this(f, encoding, true);
+ }
+
+ /**
+ * Opens the given file for reading, assuming the specified
+ * encoding for file names.
+ *
+ * @param f the archive.
+ * @param encoding the encoding to use for file names, use null
+ * for the platform's default encoding
+ * @param useUnicodeExtraFields whether to use InfoZIP Unicode
+ * Extra Fields (if present) to set the file names.
+ *
+ * @throws IOException if an error occurs while reading the file.
+ */
+ public ZipFile(final File f, final String encoding, final boolean useUnicodeExtraFields)
+ throws IOException {
+ this.archiveName = f.getAbsolutePath();
+ this.encoding = encoding;
+ this.zipEncoding = ZipEncodingHelper.getZipEncoding(encoding);
+ this.useUnicodeExtraFields = useUnicodeExtraFields;
+ archive = new RandomAccessFile(f, "r");
+ boolean success = false;
+ try {
+ final Map<ZipEntry, NameAndComment> entriesWithoutUTF8Flag =
+ populateFromCentralDirectory();
+ resolveLocalFileHeaderData(entriesWithoutUTF8Flag);
+ success = true;
+ } finally {
+ closed = !success;
+ if (!success) {
+ try {
+ archive.close();
+ } catch (final IOException e2) {
+ // swallow, throw the original exception instead
+ }
+ }
+ }
+ }
+
+ /**
+ * The encoding to use for filenames and the file comment.
+ *
+ * @return null if using the platform's default character encoding.
+ */
+ public String getEncoding() {
+ return encoding;
+ }
+
+ /**
+ * Closes the archive.
+ * @throws IOException if an error occurs closing the archive.
+ */
+ public void close() throws IOException {
+ // this flag is only written here and read in finalize() which
+ // can never be run in parallel.
+ // no synchronization needed.
+ closed = true;
+
+ archive.close();
+ }
+
+ /**
+ * close a zipfile quietly; throw no io fault, do nothing
+ * on a null parameter
+ * @param zipfile file to close, can be null
+ */
+ public static void closeQuietly(final ZipFile zipfile) {
+ if (zipfile != null) {
+ try {
+ zipfile.close();
+ } catch (final IOException e) {
+ //ignore
+ }
+ }
+ }
+
+ /**
+ * Returns all entries.
+ *
+ * <p>Entries will be returned in the same order they appear
+ * within the archive's central directory.</p>
+ *
+ * @return all entries as {@link ZipEntry} instances
+ */
+ public Enumeration<ZipEntry> getEntries() {
+ return Collections.enumeration(entries);
+ }
+
+ /**
+ * Returns all entries in physical order.
+ *
+ * <p>Entries will be returned in the same order their contents
+ * appear within the archive.</p>
+ *
+ * @return all entries as {@link ZipEntry} instances
+ *
+ * @since Ant 1.9.0
+ */
+ public Enumeration<ZipEntry> getEntriesInPhysicalOrder() {
+ final ZipEntry[] allEntries = entries.toArray(new ZipEntry[0]);
+ Arrays.sort(allEntries, OFFSET_COMPARATOR);
+ return Collections.enumeration(Arrays.asList(allEntries));
+ }
+
+ /**
+ * Returns a named entry - or {@code null} if no entry by
+ * that name exists.
+ *
+ * <p>If multiple entries with the same name exist the first entry
+ * in the archive's central directory by that name is
+ * returned.</p>
+ *
+ * @param name name of the entry.
+ * @return the ZipEntry corresponding to the given name - or
+ * {@code null} if not present.
+ */
+ public ZipEntry getEntry(final String name) {
+ final LinkedList<ZipEntry> entriesOfThatName = nameMap.get(name);
+ return entriesOfThatName != null ? entriesOfThatName.getFirst() : null;
+ }
+
+ /**
+ * Returns all named entries in the same order they appear within
+ * the archive's central directory.
+ *
+ * @param name name of the entry.
+ * @return the Iterable<ZipEntry> corresponding to the
+ * given name
+ * @since 1.9.2
+ */
+ public Iterable<ZipEntry> getEntries(final String name) {
+ final List<ZipEntry> entriesOfThatName = nameMap.get(name);
+ return entriesOfThatName != null ? entriesOfThatName
+ : Collections.<ZipEntry>emptyList();
+ }
+
+ /**
+ * Returns all named entries in the same order their contents
+ * appear within the archive.
+ *
+ * @param name name of the entry.
+ * @return the Iterable<ZipEntry> corresponding to the
+ * given name
+ * @since 1.9.2
+ */
+ public Iterable<ZipEntry> getEntriesInPhysicalOrder(final String name) {
+ ZipEntry[] entriesOfThatName = new ZipEntry[0];
+ if (nameMap.containsKey(name)) {
+ entriesOfThatName = nameMap.get(name).toArray(entriesOfThatName);
+ Arrays.sort(entriesOfThatName, OFFSET_COMPARATOR);
+ }
+ return Arrays.asList(entriesOfThatName);
+ }
+
+ /**
+ * Whether this class is able to read the given entry.
+ *
+ * <p>May return false if it is set up to use encryption or a
+ * compression method that hasn't been implemented yet.</p>
+ */
+ public boolean canReadEntryData(final ZipEntry ze) {
+ return ZipUtil.canHandleEntryData(ze);
+ }
+
+ /**
+ * Returns an InputStream for reading the contents of the given entry.
+ *
+ * @param ze the entry to get the stream for.
+ * @return a stream to read the entry from.
+ * @throws IOException if unable to create an input stream from the zipentry
+ * @throws ZipException if the zipentry uses an unsupported feature
+ */
+ public InputStream getInputStream(final ZipEntry ze)
+ throws IOException, ZipException {
+ if (!(ze instanceof Entry)) {
+ return null;
+ }
+ // cast valididty is checked just above
+ final OffsetEntry offsetEntry = ((Entry) ze).getOffsetEntry();
+ ZipUtil.checkRequestedFeatures(ze);
+ final long start = offsetEntry.dataOffset;
+ final BoundedInputStream bis =
+ new BoundedInputStream(start, ze.getCompressedSize());
+ switch (ze.getMethod()) {
+ case ZipEntry.STORED:
+ return bis;
+ case ZipEntry.DEFLATED:
+ bis.addDummy();
+ final Inflater inflater = new Inflater(true);
+ return new InflaterInputStream(bis, inflater) {
+ @Override
+ public void close() throws IOException {
+ super.close();
+ inflater.end();
+ }
+ };
+ default:
+ throw new ZipException("Found unsupported compression method "
+ + ze.getMethod());
+ }
+ }
+
+ /**
+ * Ensures that the close method of this zipfile is called when
+ * there are no more references to it.
+ * @see #close()
+ */
+ @Override
+ protected void finalize() throws Throwable {
+ try {
+ if (!closed) {
+ System.err.println("Cleaning up unclosed ZipFile for archive "
+ + archiveName);
+ close();
+ }
+ } finally {
+ super.finalize();
+ }
+ }
+
+ /**
+ * Length of a "central directory" entry structure without file
+ * name, extra fields or comment.
+ */
+ private static final int CFH_LEN =
+ /* version made by */ SHORT
+ /* version needed to extract */ + SHORT
+ /* general purpose bit flag */ + SHORT
+ /* compression method */ + SHORT
+ /* last mod file time */ + SHORT
+ /* last mod file date */ + SHORT
+ /* crc-32 */ + WORD
+ /* compressed size */ + WORD
+ /* uncompressed size */ + WORD
+ /* filename length */ + SHORT
+ /* extra field length */ + SHORT
+ /* file comment length */ + SHORT
+ /* disk number start */ + SHORT
+ /* internal file attributes */ + SHORT
+ /* external file attributes */ + WORD
+ /* relative offset of local header */ + WORD;
+
+ private static final long CFH_SIG =
+ ZipLong.getValue(ZipOutputStream.CFH_SIG);
+
+ /**
+ * Reads the central directory of the given archive and populates
+ * the internal tables with ZipEntry instances.
+ *
+ * <p>The ZipEntrys will know all data that can be obtained from
+ * the central directory alone, but not the data that requires the
+ * local file header or additional data to be read.</p>
+ *
+ * @return a map of zipentries that didn't have the language
+ * encoding flag set when read.
+ */
+ private Map<ZipEntry, NameAndComment> populateFromCentralDirectory()
+ throws IOException {
+ final HashMap<ZipEntry, NameAndComment> noUTF8Flag =
+ new HashMap<ZipEntry, NameAndComment>();
+
+ positionAtCentralDirectory();
+
+ archive.readFully(WORD_BUF);
+ long sig = ZipLong.getValue(WORD_BUF);
+
+ if (sig != CFH_SIG && startsWithLocalFileHeader()) {
+ throw new IOException("central directory is empty, can't expand"
+ + " corrupt archive.");
+ }
+
+ while (sig == CFH_SIG) {
+ readCentralDirectoryEntry(noUTF8Flag);
+ archive.readFully(WORD_BUF);
+ sig = ZipLong.getValue(WORD_BUF);
+ }
+ return noUTF8Flag;
+ }
+
+ /**
+ * Reads an individual entry of the central directory, creats an
+ * ZipEntry from it and adds it to the global maps.
+ *
+ * @param noUTF8Flag map used to collect entries that don't have
+ * their UTF-8 flag set and whose name will be set by data read
+ * from the local file header later. The current entry may be
+ * added to this map.
+ */
+ private void
+ readCentralDirectoryEntry(final Map<ZipEntry, NameAndComment> noUTF8Flag)
+ throws IOException {
+ archive.readFully(CFH_BUF);
+ int off = 0;
+ final OffsetEntry offset = new OffsetEntry();
+ final Entry ze = new Entry(offset);
+
+ final int versionMadeBy = ZipShort.getValue(CFH_BUF, off);
+ off += SHORT;
+ ze.setPlatform((versionMadeBy >> BYTE_SHIFT) & NIBLET_MASK);
+
+ off += SHORT; // skip version info
+
+ final GeneralPurposeBit gpFlag = GeneralPurposeBit.parse(CFH_BUF, off);
+ final boolean hasUTF8Flag = gpFlag.usesUTF8ForNames();
+ final ZipEncoding entryEncoding =
+ hasUTF8Flag ? ZipEncodingHelper.UTF8_ZIP_ENCODING : zipEncoding;
+ ze.setGeneralPurposeBit(gpFlag);
+
+ off += SHORT;
+
+ ze.setMethod(ZipShort.getValue(CFH_BUF, off));
+ off += SHORT;
+
+ final long time = ZipUtil.dosToJavaTime(ZipLong.getValue(CFH_BUF, off));
+ ze.setTime(time);
+ off += WORD;
+
+ ze.setCrc(ZipLong.getValue(CFH_BUF, off));
+ off += WORD;
+
+ ze.setCompressedSize(ZipLong.getValue(CFH_BUF, off));
+ off += WORD;
+
+ ze.setSize(ZipLong.getValue(CFH_BUF, off));
+ off += WORD;
+
+ final int fileNameLen = ZipShort.getValue(CFH_BUF, off);
+ off += SHORT;
+
+ final int extraLen = ZipShort.getValue(CFH_BUF, off);
+ off += SHORT;
+
+ final int commentLen = ZipShort.getValue(CFH_BUF, off);
+ off += SHORT;
+
+ final int diskStart = ZipShort.getValue(CFH_BUF, off);
+ off += SHORT;
+
+ ze.setInternalAttributes(ZipShort.getValue(CFH_BUF, off));
+ off += SHORT;
+
+ ze.setExternalAttributes(ZipLong.getValue(CFH_BUF, off));
+ off += WORD;
+
+ final byte[] fileName = new byte[fileNameLen];
+ archive.readFully(fileName);
+ ze.setName(entryEncoding.decode(fileName), fileName);
+
+ // LFH offset,
+ offset.headerOffset = ZipLong.getValue(CFH_BUF, off);
+ // data offset will be filled later
+ entries.add(ze);
+
+ final byte[] cdExtraData = new byte[extraLen];
+ archive.readFully(cdExtraData);
+ ze.setCentralDirectoryExtra(cdExtraData);
+
+ setSizesAndOffsetFromZip64Extra(ze, offset, diskStart);
+
+ final byte[] comment = new byte[commentLen];
+ archive.readFully(comment);
+ ze.setComment(entryEncoding.decode(comment));
+
+ if (!hasUTF8Flag && useUnicodeExtraFields) {
+ noUTF8Flag.put(ze, new NameAndComment(fileName, comment));
+ }
+ }
+
+ /**
+ * If the entry holds a Zip64 extended information extra field,
+ * read sizes from there if the entry's sizes are set to
+ * 0xFFFFFFFFF, do the same for the offset of the local file
+ * header.
+ *
+ * <p>Ensures the Zip64 extra either knows both compressed and
+ * uncompressed size or neither of both as the internal logic in
+ * ExtraFieldUtils forces the field to create local header data
+ * even if they are never used - and here a field with only one
+ * size would be invalid.</p>
+ */
+ private void setSizesAndOffsetFromZip64Extra(final ZipEntry ze,
+ final OffsetEntry offset,
+ final int diskStart)
+ throws IOException {
+ final Zip64ExtendedInformationExtraField z64 =
+ (Zip64ExtendedInformationExtraField)
+ ze.getExtraField(Zip64ExtendedInformationExtraField.HEADER_ID);
+ if (z64 != null) {
+ final boolean hasUncompressedSize = ze.getSize() == ZIP64_MAGIC;
+ final boolean hasCompressedSize = ze.getCompressedSize() == ZIP64_MAGIC;
+ final boolean hasRelativeHeaderOffset =
+ offset.headerOffset == ZIP64_MAGIC;
+ z64.reparseCentralDirectoryData(hasUncompressedSize,
+ hasCompressedSize,
+ hasRelativeHeaderOffset,
+ diskStart == ZIP64_MAGIC_SHORT);
+
+ if (hasUncompressedSize) {
+ ze.setSize(z64.getSize().getLongValue());
+ } else if (hasCompressedSize) {
+ z64.setSize(new ZipEightByteInteger(ze.getSize()));
+ }
+
+ if (hasCompressedSize) {
+ ze.setCompressedSize(z64.getCompressedSize().getLongValue());
+ } else if (hasUncompressedSize) {
+ z64.setCompressedSize(new ZipEightByteInteger(ze.getCompressedSize()));
+ }
+
+ if (hasRelativeHeaderOffset) {
+ offset.headerOffset =
+ z64.getRelativeHeaderOffset().getLongValue();
+ }
+ }
+ }
+
+ /**
+ * Length of the "End of central directory record" - which is
+ * supposed to be the last structure of the archive - without file
+ * comment.
+ */
+ private static final int MIN_EOCD_SIZE =
+ /* end of central dir signature */ WORD
+ /* number of this disk */ + SHORT
+ /* number of the disk with the */
+ /* start of the central directory */ + SHORT
+ /* total number of entries in */
+ /* the central dir on this disk */ + SHORT
+ /* total number of entries in */
+ /* the central dir */ + SHORT
+ /* size of the central directory */ + WORD
+ /* offset of start of central */
+ /* directory with respect to */
+ /* the starting disk number */ + WORD
+ /* zipfile comment length */ + SHORT;
+
+ /**
+ * Maximum length of the "End of central directory record" with a
+ * file comment.
+ */
+ private static final int MAX_EOCD_SIZE = MIN_EOCD_SIZE
+ /* maximum length of zipfile comment */ + ZIP64_MAGIC_SHORT;
+
+ /**
+ * Offset of the field that holds the location of the first
+ * central directory entry inside the "End of central directory
+ * record" relative to the start of the "End of central directory
+ * record".
+ */
+ private static final int CFD_LOCATOR_OFFSET =
+ /* end of central dir signature */ WORD
+ /* number of this disk */ + SHORT
+ /* number of the disk with the */
+ /* start of the central directory */ + SHORT
+ /* total number of entries in */
+ /* the central dir on this disk */ + SHORT
+ /* total number of entries in */
+ /* the central dir */ + SHORT
+ /* size of the central directory */ + WORD;
+
+ /**
+ * Length of the "Zip64 end of central directory locator" - which
+ * should be right in front of the "end of central directory
+ * record" if one is present at all.
+ */
+ private static final int ZIP64_EOCDL_LENGTH =
+ /* zip64 end of central dir locator sig */ WORD
+ /* number of the disk with the start */
+ /* start of the zip64 end of */
+ /* central directory */ + WORD
+ /* relative offset of the zip64 */
+ /* end of central directory record */ + DWORD
+ /* total number of disks */ + WORD;
+
+ /**
+ * Offset of the field that holds the location of the "Zip64 end
+ * of central directory record" inside the "Zip64 end of central
+ * directory locator" relative to the start of the "Zip64 end of
+ * central directory locator".
+ */
+ private static final int ZIP64_EOCDL_LOCATOR_OFFSET =
+ /* zip64 end of central dir locator sig */ WORD
+ /* number of the disk with the start */
+ /* start of the zip64 end of */
+ /* central directory */ + WORD;
+
+ /**
+ * Offset of the field that holds the location of the first
+ * central directory entry inside the "Zip64 end of central
+ * directory record" relative to the start of the "Zip64 end of
+ * central directory record".
+ */
+ private static final int ZIP64_EOCD_CFD_LOCATOR_OFFSET =
+ /* zip64 end of central dir */
+ /* signature */ WORD
+ /* size of zip64 end of central */
+ /* directory record */ + DWORD
+ /* version made by */ + SHORT
+ /* version needed to extract */ + SHORT
+ /* number of this disk */ + WORD
+ /* number of the disk with the */
+ /* start of the central directory */ + WORD
+ /* total number of entries in the */
+ /* central directory on this disk */ + DWORD
+ /* total number of entries in the */
+ /* central directory */ + DWORD
+ /* size of the central directory */ + DWORD;
+
+ /**
+ * Searches for either the &quot;Zip64 end of central directory
+ * locator&quot; or the &quot;End of central dir record&quot;, parses
+ * it and positions the stream at the first central directory
+ * record.
+ */
+ private void positionAtCentralDirectory()
+ throws IOException {
+ positionAtEndOfCentralDirectoryRecord();
+ boolean found = false;
+ final boolean searchedForZip64EOCD =
+ archive.getFilePointer() > ZIP64_EOCDL_LENGTH;
+ if (searchedForZip64EOCD) {
+ archive.seek(archive.getFilePointer() - ZIP64_EOCDL_LENGTH);
+ archive.readFully(WORD_BUF);
+ found = Arrays.equals(ZipOutputStream.ZIP64_EOCD_LOC_SIG, WORD_BUF);
+ }
+ if (!found) {
+ // not a ZIP64 archive
+ if (searchedForZip64EOCD) {
+ skipBytes(ZIP64_EOCDL_LENGTH - WORD);
+ }
+ positionAtCentralDirectory32();
+ } else {
+ positionAtCentralDirectory64();
+ }
+ }
+
+ /**
+ * Parses the &quot;Zip64 end of central directory locator&quot;,
+ * finds the &quot;Zip64 end of central directory record&quot; using the
+ * parsed information, parses that and positions the stream at the
+ * first central directory record.
+ */
+ private void positionAtCentralDirectory64()
+ throws IOException {
+ skipBytes(ZIP64_EOCDL_LOCATOR_OFFSET
+ - WORD /* signature has already been read */);
+ archive.readFully(DWORD_BUF);
+ archive.seek(ZipEightByteInteger.getLongValue(DWORD_BUF));
+ archive.readFully(WORD_BUF);
+ if (!Arrays.equals(WORD_BUF, ZipOutputStream.ZIP64_EOCD_SIG)) {
+ throw new ZipException("archive's ZIP64 end of central "
+ + "directory locator is corrupt.");
+ }
+ skipBytes(ZIP64_EOCD_CFD_LOCATOR_OFFSET
+ - WORD /* signature has already been read */);
+ archive.readFully(DWORD_BUF);
+ archive.seek(ZipEightByteInteger.getLongValue(DWORD_BUF));
+ }
+
+ /**
+ * Searches for the &quot;End of central dir record&quot;, parses
+ * it and positions the stream at the first central directory
+ * record.
+ */
+ private void positionAtCentralDirectory32()
+ throws IOException {
+ skipBytes(CFD_LOCATOR_OFFSET);
+ archive.readFully(WORD_BUF);
+ archive.seek(ZipLong.getValue(WORD_BUF));
+ }
+
+ /**
+ * Searches for the and positions the stream at the start of the
+ * &quot;End of central dir record&quot;.
+ */
+ private void positionAtEndOfCentralDirectoryRecord()
+ throws IOException {
+ final boolean found = tryToLocateSignature(MIN_EOCD_SIZE, MAX_EOCD_SIZE,
+ ZipOutputStream.EOCD_SIG);
+ if (!found) {
+ throw new ZipException("archive is not a ZIP archive");
+ }
+ }
+
+ /**
+ * Searches the archive backwards from minDistance to maxDistance
+ * for the given signature, positions the RandomaccessFile right
+ * at the signature if it has been found.
+ */
+ private boolean tryToLocateSignature(final long minDistanceFromEnd,
+ final long maxDistanceFromEnd,
+ final byte[] sig) throws IOException {
+ boolean found = false;
+ long off = archive.length() - minDistanceFromEnd;
+ final long stopSearching =
+ Math.max(0L, archive.length() - maxDistanceFromEnd);
+ if (off >= 0) {
+ for (; off >= stopSearching; off--) {
+ archive.seek(off);
+ int curr = archive.read();
+ if (curr == -1) {
+ break;
+ }
+ if (curr == sig[POS_0]) {
+ curr = archive.read();
+ if (curr == sig[POS_1]) {
+ curr = archive.read();
+ if (curr == sig[POS_2]) {
+ curr = archive.read();
+ if (curr == sig[POS_3]) {
+ found = true;
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ if (found) {
+ archive.seek(off);
+ }
+ return found;
+ }
+
+ /**
+ * Skips the given number of bytes or throws an EOFException if
+ * skipping failed.
+ */
+ private void skipBytes(final int count) throws IOException {
+ int totalSkipped = 0;
+ while (totalSkipped < count) {
+ final int skippedNow = archive.skipBytes(count - totalSkipped);
+ if (skippedNow <= 0) {
+ throw new EOFException();
+ }
+ totalSkipped += skippedNow;
+ }
+ }
+
+ /**
+ * Number of bytes in local file header up to the &quot;length of
+ * filename&quot; entry.
+ */
+ private static final long LFH_OFFSET_FOR_FILENAME_LENGTH =
+ /* local file header signature */ WORD
+ /* version needed to extract */ + SHORT
+ /* general purpose bit flag */ + SHORT
+ /* compression method */ + SHORT
+ /* last mod file time */ + SHORT
+ /* last mod file date */ + SHORT
+ /* crc-32 */ + WORD
+ /* compressed size */ + WORD
+ /* uncompressed size */ + WORD;
+
+ /**
+ * Walks through all recorded entries and adds the data available
+ * from the local file header.
+ *
+ * <p>Also records the offsets for the data to read from the
+ * entries.</p>
+ */
+ private void resolveLocalFileHeaderData(final Map<ZipEntry, NameAndComment>
+ entriesWithoutUTF8Flag)
+ throws IOException {
+ for (final Iterator<ZipEntry> it = entries.iterator(); it.hasNext();) {
+ // entries is filled in populateFromCentralDirectory and
+ // never modified
+ final Entry ze = (Entry) it.next();
+ final OffsetEntry offsetEntry = ze.getOffsetEntry();
+ final long offset = offsetEntry.headerOffset;
+ archive.seek(offset + LFH_OFFSET_FOR_FILENAME_LENGTH);
+ archive.readFully(SHORT_BUF);
+ final int fileNameLen = ZipShort.getValue(SHORT_BUF);
+ archive.readFully(SHORT_BUF);
+ final int extraFieldLen = ZipShort.getValue(SHORT_BUF);
+ int lenToSkip = fileNameLen;
+ while (lenToSkip > 0) {
+ final int skipped = archive.skipBytes(lenToSkip);
+ if (skipped <= 0) {
+ throw new IOException("failed to skip file name in"
+ + " local file header");
+ }
+ lenToSkip -= skipped;
+ }
+ final byte[] localExtraData = new byte[extraFieldLen];
+ archive.readFully(localExtraData);
+ ze.setExtra(localExtraData);
+ offsetEntry.dataOffset = offset + LFH_OFFSET_FOR_FILENAME_LENGTH
+ + SHORT + SHORT + fileNameLen + extraFieldLen;
+
+ if (entriesWithoutUTF8Flag.containsKey(ze)) {
+ final NameAndComment nc = entriesWithoutUTF8Flag.get(ze);
+ ZipUtil.setNameAndCommentFromExtraFields(ze, nc.name,
+ nc.comment);
+ }
+
+ final String name = ze.getName();
+ LinkedList<ZipEntry> entriesOfThatName = nameMap.get(name);
+ if (entriesOfThatName == null) {
+ entriesOfThatName = new LinkedList<ZipEntry>();
+ nameMap.put(name, entriesOfThatName);
+ }
+ entriesOfThatName.addLast(ze);
+ }
+ }
+
+ /**
+ * Checks whether the archive starts with a LFH. If it doesn't,
+ * it may be an empty archive.
+ */
+ private boolean startsWithLocalFileHeader() throws IOException {
+ archive.seek(0);
+ archive.readFully(WORD_BUF);
+ return Arrays.equals(WORD_BUF, ZipOutputStream.LFH_SIG);
+ }
+
+ /**
+ * InputStream that delegates requests to the underlying
+ * RandomAccessFile, making sure that only bytes from a certain
+ * range can be read.
+ */
+ private class BoundedInputStream extends InputStream {
+ private long remaining;
+ private long loc;
+ private boolean addDummyByte = false;
+
+ BoundedInputStream(final long start, final long remaining) {
+ this.remaining = remaining;
+ loc = start;
+ }
+
+ @Override
+ public int read() throws IOException {
+ if (remaining-- <= 0) {
+ if (addDummyByte) {
+ addDummyByte = false;
+ return 0;
+ }
+ return -1;
+ }
+ synchronized (archive) {
+ archive.seek(loc++);
+ return archive.read();
+ }
+ }
+
+ @Override
+ public int read(final byte[] b, final int off, int len) throws IOException {
+ if (remaining <= 0) {
+ if (addDummyByte) {
+ addDummyByte = false;
+ b[off] = 0;
+ return 1;
+ }
+ return -1;
+ }
+
+ if (len <= 0) {
+ return 0;
+ }
+
+ if (len > remaining) {
+ len = (int) remaining;
+ }
+ int ret = -1;
+ synchronized (archive) {
+ archive.seek(loc);
+ ret = archive.read(b, off, len);
+ }
+ if (ret > 0) {
+ loc += ret;
+ remaining -= ret;
+ }
+ return ret;
+ }
+
+ /**
+ * Inflater needs an extra dummy byte for nowrap - see
+ * Inflater's javadocs.
+ */
+ void addDummy() {
+ addDummyByte = true;
+ }
+ }
+
+ private static final class NameAndComment {
+ private final byte[] name;
+ private final byte[] comment;
+ private NameAndComment(final byte[] name, final byte[] comment) {
+ this.name = name;
+ this.comment = comment;
+ }
+ }
+
+ /**
+ * Compares two ZipEntries based on their offset within the archive.
+ *
+ * <p>Won't return any meaningful results if one of the entries
+ * isn't part of the archive at all.</p>
+ *
+ * @since Ant 1.9.0
+ */
+ private final Comparator<ZipEntry> OFFSET_COMPARATOR =
+ new Comparator<ZipEntry>() {
+ public int compare(final ZipEntry e1, final ZipEntry e2) {
+ if (e1 == e2) {
+ return 0;
+ }
+
+ final Entry ent1 = e1 instanceof Entry ? (Entry) e1 : null;
+ final Entry ent2 = e2 instanceof Entry ? (Entry) e2 : null;
+ if (ent1 == null) {
+ return 1;
+ }
+ if (ent2 == null) {
+ return -1;
+ }
+ final long val = (ent1.getOffsetEntry().headerOffset
+ - ent2.getOffsetEntry().headerOffset);
+ return val == 0 ? 0 : val < 0 ? -1 : +1;
+ }
+ };
+
+ /**
+ * Extends ZipEntry to store the offset within the archive.
+ */
+ private static class Entry extends ZipEntry {
+
+ private final OffsetEntry offsetEntry;
+
+ Entry(final OffsetEntry offset) {
+ this.offsetEntry = offset;
+ }
+
+ OffsetEntry getOffsetEntry() {
+ return offsetEntry;
+ }
+
+ @Override
+ public int hashCode() {
+ return 3 * super.hashCode()
+ + (int) (offsetEntry.headerOffset % Integer.MAX_VALUE);
+ }
+
+ @Override
+ public boolean equals(final Object other) {
+ if (super.equals(other)) {
+ // super.equals would return false if other were not an Entry
+ final Entry otherEntry = (Entry) other;
+ return offsetEntry.headerOffset
+ == otherEntry.offsetEntry.headerOffset
+ && offsetEntry.dataOffset
+ == otherEntry.offsetEntry.dataOffset;
+ }
+ return false;
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/ZipLong.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/ZipLong.java
new file mode 100644
index 00000000..72af84db
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/ZipLong.java
@@ -0,0 +1,201 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.zip;
+
+import static org.apache.tools.zip.ZipConstants.BYTE_MASK;
+import static org.apache.tools.zip.ZipConstants.WORD;
+
+/**
+ * Utility class that represents a four byte integer with conversion
+ * rules for the big endian byte order of ZIP files.
+ *
+ */
+public final class ZipLong implements Cloneable {
+
+ //private static final int BYTE_BIT_SIZE = 8;
+
+ private static final int BYTE_1 = 1;
+ private static final int BYTE_1_MASK = 0xFF00;
+ private static final int BYTE_1_SHIFT = 8;
+
+ private static final int BYTE_2 = 2;
+ private static final int BYTE_2_MASK = 0xFF0000;
+ private static final int BYTE_2_SHIFT = 16;
+
+ private static final int BYTE_3 = 3;
+ private static final long BYTE_3_MASK = 0xFF000000L;
+ private static final int BYTE_3_SHIFT = 24;
+
+ private final long value;
+
+ /** Central File Header Signature */
+ public static final ZipLong CFH_SIG = new ZipLong(0X02014B50L);
+
+ /** Local File Header Signature */
+ public static final ZipLong LFH_SIG = new ZipLong(0X04034B50L);
+
+ /**
+ * Data Descriptor signature
+ */
+ public static final ZipLong DD_SIG = new ZipLong(0X08074B50L);
+
+ /**
+ * Value stored in size and similar fields if ZIP64 extensions are
+ * used.
+ */
+ static final ZipLong ZIP64_MAGIC = new ZipLong(ZipConstants.ZIP64_MAGIC);
+
+ /**
+ * Create instance from a number.
+ * @param value the long to store as a ZipLong
+ * @since 1.1
+ */
+ public ZipLong(long value) {
+ this.value = value;
+ }
+
+ /**
+ * Create instance from bytes.
+ * @param bytes the bytes to store as a ZipLong
+ * @since 1.1
+ */
+ public ZipLong (byte[] bytes) {
+ this(bytes, 0);
+ }
+
+ /**
+ * Create instance from the four bytes starting at offset.
+ * @param bytes the bytes to store as a ZipLong
+ * @param offset the offset to start
+ * @since 1.1
+ */
+ public ZipLong (byte[] bytes, int offset) {
+ value = ZipLong.getValue(bytes, offset);
+ }
+
+ /**
+ * Get value as four bytes in big endian byte order.
+ * @since 1.1
+ * @return value as four bytes in big endian order
+ */
+ public byte[] getBytes() {
+ return ZipLong.getBytes(value);
+ }
+
+ /**
+ * Get value as Java long.
+ * @since 1.1
+ * @return value as a long
+ */
+ public long getValue() {
+ return value;
+ }
+
+ /**
+ * Get value as four bytes in big endian byte order.
+ * @param value the value to convert
+ * @return value as four bytes in big endian byte order
+ */
+ public static byte[] getBytes(long value) {
+ byte[] result = new byte[WORD];
+ putLong(value, result, 0);
+ return result;
+ }
+
+ /**
+ * put the value as four bytes in big endian byte order.
+ * @param value the Java long to convert to bytes
+ * @param buf the output buffer
+ * @param offset
+ * The offset within the output buffer of the first byte to be written.
+ * must be non-negative and no larger than <tt>buf.length-4</tt>
+ */
+ public static void putLong(long value, byte[] buf, int offset) {
+ buf[offset++] = (byte) ((value & BYTE_MASK));
+ buf[offset++] = (byte) ((value & BYTE_1_MASK) >> BYTE_1_SHIFT);
+ buf[offset++] = (byte) ((value & BYTE_2_MASK) >> BYTE_2_SHIFT);
+ buf[offset] = (byte) ((value & BYTE_3_MASK) >> BYTE_3_SHIFT);
+ }
+
+ public void putLong(byte[] buf, int offset) {
+ putLong(value, buf, offset);
+ }
+
+ /**
+ * Helper method to get the value as a Java long from four bytes starting at given array offset
+ * @param bytes the array of bytes
+ * @param offset the offset to start
+ * @return the corresponding Java long value
+ */
+ public static long getValue(byte[] bytes, int offset) {
+ long value = (bytes[offset + BYTE_3] << BYTE_3_SHIFT) & BYTE_3_MASK;
+ value += (bytes[offset + BYTE_2] << BYTE_2_SHIFT) & BYTE_2_MASK;
+ value += (bytes[offset + BYTE_1] << BYTE_1_SHIFT) & BYTE_1_MASK;
+ value += (bytes[offset] & BYTE_MASK);
+ return value;
+ }
+
+ /**
+ * Helper method to get the value as a Java long from a four-byte array
+ * @param bytes the array of bytes
+ * @return the corresponding Java long value
+ */
+ public static long getValue(byte[] bytes) {
+ return getValue(bytes, 0);
+ }
+
+ /**
+ * Override to make two instances with same value equal.
+ * @param o an object to compare
+ * @return true if the objects are equal
+ * @since 1.1
+ */
+ @Override
+ public boolean equals(Object o) {
+ if (o == null || !(o instanceof ZipLong)) {
+ return false;
+ }
+ return value == ((ZipLong) o).getValue();
+ }
+
+ /**
+ * Override to make two instances with same value equal.
+ * @return the value stored in the ZipLong
+ * @since 1.1
+ */
+ @Override
+ public int hashCode() {
+ return (int) value;
+ }
+
+ @Override
+ public Object clone() {
+ try {
+ return super.clone();
+ } catch (CloneNotSupportedException cnfe) {
+ // impossible
+ throw new RuntimeException(cnfe);
+ }
+ }
+
+ @Override
+ public String toString() {
+ return "ZipLong value: " + value;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/ZipOutputStream.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/ZipOutputStream.java
new file mode 100644
index 00000000..261c717e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/ZipOutputStream.java
@@ -0,0 +1,1674 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.zip;
+
+import static org.apache.tools.zip.ZipConstants.DATA_DESCRIPTOR_MIN_VERSION;
+import static org.apache.tools.zip.ZipConstants.DWORD;
+import static org.apache.tools.zip.ZipConstants.INITIAL_VERSION;
+import static org.apache.tools.zip.ZipConstants.SHORT;
+import static org.apache.tools.zip.ZipConstants.WORD;
+import static org.apache.tools.zip.ZipConstants.ZIP64_MAGIC;
+import static org.apache.tools.zip.ZipConstants.ZIP64_MAGIC_SHORT;
+import static org.apache.tools.zip.ZipConstants.ZIP64_MIN_VERSION;
+import static org.apache.tools.zip.ZipLong.putLong;
+import static org.apache.tools.zip.ZipShort.putShort;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.FilterOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.RandomAccessFile;
+import java.nio.ByteBuffer;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.zip.CRC32;
+import java.util.zip.Deflater;
+import java.util.zip.ZipException;
+
+/**
+ * Reimplementation of {@link java.util.zip.ZipOutputStream
+ * java.util.zip.ZipOutputStream} that does handle the extended
+ * functionality of this package, especially internal/external file
+ * attributes and extra fields with different layouts for local file
+ * data and central directory entries.
+ *
+ * <p>This class will try to use {@link java.io.RandomAccessFile
+ * RandomAccessFile} when you know that the output is going to go to a
+ * file.</p>
+ *
+ * <p>If RandomAccessFile cannot be used, this implementation will use
+ * a Data Descriptor to store size and CRC information for {@link
+ * #DEFLATED DEFLATED} entries, this means, you don't need to
+ * calculate them yourself. Unfortunately this is not possible for
+ * the {@link #STORED STORED} method, here setting the CRC and
+ * uncompressed size information is required before {@link
+ * #putNextEntry putNextEntry} can be called.</p>
+ *
+ * <p>As of Apache Ant 1.9.0 it transparently supports Zip64
+ * extensions and thus individual entries and archives larger than 4
+ * GB or with more than 65536 entries in most cases but explicit
+ * control is provided via {@link #setUseZip64}. If the stream can not
+ * user RandomAccessFile and you try to write a ZipEntry of
+ * unknown size then Zip64 extensions will be disabled by default.</p>
+ */
+public class ZipOutputStream extends FilterOutputStream {
+
+ private static final int BUFFER_SIZE = 512;
+ private static final int LFH_SIG_OFFSET = 0;
+ private static final int LFH_VERSION_NEEDED_OFFSET = 4;
+ private static final int LFH_GPB_OFFSET = 6;
+ private static final int LFH_METHOD_OFFSET = 8;
+ private static final int LFH_TIME_OFFSET = 10;
+ private static final int LFH_CRC_OFFSET = 14;
+ private static final int LFH_COMPRESSED_SIZE_OFFSET = 18;
+ private static final int LFH_ORIGINAL_SIZE_OFFSET = 22;
+ private static final int LFH_FILENAME_LENGTH_OFFSET = 26;
+ private static final int LFH_EXTRA_LENGTH_OFFSET = 28;
+ private static final int LFH_FILENAME_OFFSET = 30;
+ private static final int CFH_SIG_OFFSET = 0;
+ private static final int CFH_VERSION_MADE_BY_OFFSET = 4;
+ private static final int CFH_VERSION_NEEDED_OFFSET = 6;
+ private static final int CFH_GPB_OFFSET = 8;
+ private static final int CFH_METHOD_OFFSET = 10;
+ private static final int CFH_TIME_OFFSET = 12;
+ private static final int CFH_CRC_OFFSET = 16;
+ private static final int CFH_COMPRESSED_SIZE_OFFSET = 20;
+ private static final int CFH_ORIGINAL_SIZE_OFFSET = 24;
+ private static final int CFH_FILENAME_LENGTH_OFFSET = 28;
+ private static final int CFH_EXTRA_LENGTH_OFFSET = 30;
+ private static final int CFH_COMMENT_LENGTH_OFFSET = 32;
+ private static final int CFH_DISK_NUMBER_OFFSET = 34;
+ private static final int CFH_INTERNAL_ATTRIBUTES_OFFSET = 36;
+ private static final int CFH_EXTERNAL_ATTRIBUTES_OFFSET = 38;
+ private static final int CFH_LFH_OFFSET = 42;
+ private static final int CFH_FILENAME_OFFSET = 46;
+
+ /**
+ * indicates if this archive is finished.
+ */
+ private boolean finished = false;
+
+ /*
+ * Apparently Deflater.setInput gets slowed down a lot on Sun JVMs
+ * when it gets handed a really big buffer. See
+ * https://issues.apache.org/bugzilla/show_bug.cgi?id=45396
+ *
+ * Using a buffer size of 8 kB proved to be a good compromise
+ */
+ private static final int DEFLATER_BLOCK_SIZE = 8192;
+
+ /**
+ * Compression method for deflated entries.
+ *
+ * @since 1.1
+ */
+ public static final int DEFLATED = java.util.zip.ZipEntry.DEFLATED;
+
+ /**
+ * Default compression level for deflated entries.
+ *
+ * @since Ant 1.7
+ */
+ public static final int DEFAULT_COMPRESSION = Deflater.DEFAULT_COMPRESSION;
+
+ /**
+ * Compression method for stored entries.
+ *
+ * @since 1.1
+ */
+ public static final int STORED = java.util.zip.ZipEntry.STORED;
+
+ /**
+ * default encoding for file names and comment.
+ */
+ static final String DEFAULT_ENCODING = null;
+
+ /**
+ * General purpose flag, which indicates that filenames are
+ * written in utf-8.
+ * @deprecated use {@link GeneralPurposeBit#UFT8_NAMES_FLAG} instead
+ */
+ @Deprecated
+ public static final int EFS_FLAG = GeneralPurposeBit.UFT8_NAMES_FLAG;
+
+ private static final byte[] EMPTY = new byte[0];
+
+ /**
+ * Current entry.
+ *
+ * @since 1.1
+ */
+ private CurrentEntry entry;
+
+ /**
+ * The file comment.
+ *
+ * @since 1.1
+ */
+ private String comment = "";
+
+ /**
+ * Compression level for next entry.
+ *
+ * @since 1.1
+ */
+ private int level = DEFAULT_COMPRESSION;
+
+ /**
+ * Has the compression level changed when compared to the last
+ * entry?
+ *
+ * @since 1.5
+ */
+ private boolean hasCompressionLevelChanged = false;
+
+ /**
+ * Default compression method for next entry.
+ *
+ * @since 1.1
+ */
+ private int method = java.util.zip.ZipEntry.DEFLATED;
+
+ /**
+ * List of ZipEntries written so far.
+ *
+ * @since 1.1
+ */
+ private final List<ZipEntry> entries = new LinkedList<ZipEntry>();
+
+ /**
+ * CRC instance to avoid parsing DEFLATED data twice.
+ *
+ * @since 1.1
+ */
+ private final CRC32 crc = new CRC32();
+
+ /**
+ * Count the bytes written to out.
+ *
+ * @since 1.1
+ */
+ private long written = 0;
+
+ /**
+ * Start of central directory.
+ *
+ * @since 1.1
+ */
+ private long cdOffset = 0;
+
+ /**
+ * Length of central directory.
+ *
+ * @since 1.1
+ */
+ private long cdLength = 0;
+
+ /**
+ * Helper, a 0 as ZipShort.
+ *
+ * @since 1.1
+ */
+ private static final byte[] ZERO = {0, 0};
+
+ /**
+ * Helper, a 0 as ZipLong.
+ *
+ * @since 1.1
+ */
+ private static final byte[] LZERO = {0, 0, 0, 0};
+
+ private static final byte[] ONE = ZipLong.getBytes(1L);
+
+ /**
+ * Holds the offsets of the LFH starts for each entry.
+ *
+ * @since 1.1
+ */
+ private final Map<ZipEntry, Long> offsets = new HashMap<ZipEntry, Long>();
+
+ /**
+ * The encoding to use for filenames and the file comment.
+ *
+ * <p>For a list of possible values see <a
+ * href="http://java.sun.com/j2se/1.5.0/docs/guide/intl/encoding.doc.html">http://java.sun.com/j2se/1.5.0/docs/guide/intl/encoding.doc.html</a>.
+ * Defaults to the platform's default character encoding.</p>
+ *
+ * @since 1.3
+ */
+ private String encoding = null;
+
+ /**
+ * The zip encoding to use for filenames and the file comment.
+ *
+ * This field is of internal use and will be set in {@link
+ * #setEncoding(String)}.
+ */
+ private ZipEncoding zipEncoding =
+ ZipEncodingHelper.getZipEncoding(DEFAULT_ENCODING);
+
+ // CheckStyle:VisibilityModifier OFF - bc
+
+ /**
+ * This Deflater object is used for output.
+ *
+ */
+ protected final Deflater def = new Deflater(level, true);
+
+ /**
+ * This buffer serves as a Deflater.
+ *
+ * <p>This attribute is only protected to provide a level of API
+ * backwards compatibility. This class used to extend {@link
+ * java.util.zip.DeflaterOutputStream DeflaterOutputStream} up to
+ * Revision 1.13.</p>
+ *
+ * @since 1.14
+ */
+ protected byte[] buf = new byte[BUFFER_SIZE];
+
+ // CheckStyle:VisibilityModifier ON
+
+ /**
+ * Optional random access output.
+ *
+ * @since 1.14
+ */
+ private final RandomAccessFile raf;
+
+ /**
+ * whether to use the general purpose bit flag when writing UTF-8
+ * filenames or not.
+ */
+ private boolean useUTF8Flag = true;
+
+ /**
+ * Whether to encode non-encodable file names as UTF-8.
+ */
+ private boolean fallbackToUTF8 = false;
+
+ /**
+ * whether to create UnicodePathExtraField-s for each entry.
+ */
+ private UnicodeExtraFieldPolicy createUnicodeExtraFields = UnicodeExtraFieldPolicy.NEVER;
+
+ /**
+ * Whether anything inside this archive has used a ZIP64 feature.
+ */
+ private boolean hasUsedZip64 = false;
+
+ private Zip64Mode zip64Mode = Zip64Mode.AsNeeded;
+
+ private final Calendar calendarInstance = Calendar.getInstance();
+
+ /**
+ * Creates a new ZIP OutputStream filtering the underlying stream.
+ * @param out the outputstream to zip
+ * @since 1.1
+ */
+ public ZipOutputStream(OutputStream out) {
+ super(out);
+ this.raf = null;
+ }
+
+ /**
+ * Creates a new ZIP OutputStream writing to a File. Will use
+ * random access if possible.
+ * @param file the file to zip to
+ * @since 1.14
+ * @throws IOException on error
+ */
+ public ZipOutputStream(File file) throws IOException {
+ super(null);
+ RandomAccessFile _raf = null;
+ try {
+ _raf = new RandomAccessFile(file, "rw");
+ _raf.setLength(0);
+ } catch (IOException e) {
+ if (_raf != null) {
+ try {
+ _raf.close();
+ } catch (IOException inner) { // NOPMD
+ // ignore
+ }
+ _raf = null;
+ }
+ out = new FileOutputStream(file);
+ }
+ raf = _raf;
+ }
+
+ /**
+ * This method indicates whether this archive is writing to a
+ * seekable stream (i.e., to a random access file).
+ *
+ * <p>For seekable streams, you don't need to calculate the CRC or
+ * uncompressed size for {@link #STORED} entries before
+ * invoking {@link #putNextEntry}.
+ * @return true if seekable
+ * @since 1.17
+ */
+ public boolean isSeekable() {
+ return raf != null;
+ }
+
+ /**
+ * The encoding to use for filenames and the file comment.
+ *
+ * <p>For a list of possible values see <a
+ * href="http://java.sun.com/j2se/1.5.0/docs/guide/intl/encoding.doc.html">http://java.sun.com/j2se/1.5.0/docs/guide/intl/encoding.doc.html</a>.
+ * Defaults to the platform's default character encoding.</p>
+ * @param encoding the encoding value
+ * @since 1.3
+ */
+ public void setEncoding(final String encoding) {
+ this.encoding = encoding;
+ this.zipEncoding = ZipEncodingHelper.getZipEncoding(encoding);
+ if (useUTF8Flag && !ZipEncodingHelper.isUTF8(encoding)) {
+ useUTF8Flag = false;
+ }
+ }
+
+ /**
+ * The encoding to use for filenames and the file comment.
+ *
+ * @return null if using the platform's default character encoding.
+ *
+ * @since 1.3
+ */
+ public String getEncoding() {
+ return encoding;
+ }
+
+ /**
+ * Whether to set the language encoding flag if the file name
+ * encoding is UTF-8.
+ *
+ * <p>Defaults to true.</p>
+ */
+ public void setUseLanguageEncodingFlag(boolean b) {
+ useUTF8Flag = b && ZipEncodingHelper.isUTF8(encoding);
+ }
+
+ /**
+ * Whether to create Unicode Extra Fields.
+ *
+ * <p>Defaults to NEVER.</p>
+ */
+ public void setCreateUnicodeExtraFields(UnicodeExtraFieldPolicy b) {
+ createUnicodeExtraFields = b;
+ }
+
+ /**
+ * Whether to fall back to UTF and the language encoding flag if
+ * the file name cannot be encoded using the specified encoding.
+ *
+ * <p>Defaults to false.</p>
+ */
+ public void setFallbackToUTF8(boolean b) {
+ fallbackToUTF8 = b;
+ }
+
+ /**
+ * Whether Zip64 extensions will be used.
+ *
+ * <p>When setting the mode to {@link Zip64Mode#Never Never},
+ * {@link #putNextEntry}, {@link #closeEntry}, {@link
+ * #finish} or {@link #close} may throw a {@link
+ * Zip64RequiredException} if the entry's size or the total size
+ * of the archive exceeds 4GB or there are more than 65536 entries
+ * inside the archive. Any archive created in this mode will be
+ * readable by implementations that don't support Zip64.</p>
+ *
+ * <p>When setting the mode to {@link Zip64Mode#Always Always},
+ * Zip64 extensions will be used for all entries. Any archive
+ * created in this mode may be unreadable by implementations that
+ * don't support Zip64 even if all its contents would be.</p>
+ *
+ * <p>When setting the mode to {@link Zip64Mode#AsNeeded
+ * AsNeeded}, Zip64 extensions will transparently be used for
+ * those entries that require them. This mode can only be used if
+ * the uncompressed size of the {@link ZipEntry} is known
+ * when calling {@link #putNextEntry} or the archive is written
+ * to a seekable output (i.e. you have used the {@link
+ * #ZipOutputStream(java.io.File) File-arg constructor}) -
+ * this mode is not valid when the output stream is not seekable
+ * and the uncompressed size is unknown when {@link
+ * #putNextEntry} is called.</p>
+ *
+ * <p>If no entry inside the resulting archive requires Zip64
+ * extensions then {@link Zip64Mode#Never Never} will create the
+ * smallest archive. {@link Zip64Mode#AsNeeded AsNeeded} will
+ * create a slightly bigger archive if the uncompressed size of
+ * any entry has initially been unknown and create an archive
+ * identical to {@link Zip64Mode#Never Never} otherwise. {@link
+ * Zip64Mode#Always Always} will create an archive that is at
+ * least 24 bytes per entry bigger than the one {@link
+ * Zip64Mode#Never Never} would create.</p>
+ *
+ * <p>Defaults to {@link Zip64Mode#AsNeeded AsNeeded} unless
+ * {@link #putNextEntry} is called with an entry of unknown
+ * size and data is written to a non-seekable stream - in this
+ * case the default is {@link Zip64Mode#Never Never}.</p>
+ *
+ * @since 1.3
+ */
+ public void setUseZip64(Zip64Mode mode) {
+ zip64Mode = mode;
+ }
+
+ /**
+ * {@inheritDoc}
+ * @throws Zip64RequiredException if the archive's size exceeds 4
+ * GByte or there are more than 65535 entries inside the archive
+ * and {@link #setUseZip64} is {@link Zip64Mode#Never}.
+ */
+ public void finish() throws IOException {
+ if (finished) {
+ throw new IOException("This archive has already been finished");
+ }
+
+ if (entry != null) {
+ closeEntry();
+ }
+
+ cdOffset = written;
+ writeCentralDirectoryInChunks();
+ cdLength = written - cdOffset;
+ writeZip64CentralDirectory();
+ writeCentralDirectoryEnd();
+ offsets.clear();
+ entries.clear();
+ def.end();
+ finished = true;
+ }
+
+ private void writeCentralDirectoryInChunks() throws IOException {
+ final int NUM_PER_WRITE = 1000;
+ final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(70 * NUM_PER_WRITE);
+ int count = 0;
+ for (ZipEntry ze : entries) {
+ byteArrayOutputStream.write(createCentralFileHeader(ze));
+ if (++count > NUM_PER_WRITE){
+ writeCounted(byteArrayOutputStream.toByteArray());
+ byteArrayOutputStream.reset();
+ count = 0;
+ }
+ }
+ writeCounted(byteArrayOutputStream.toByteArray());
+ }
+
+ /**
+ * Writes all necessary data for this entry.
+ *
+ * @since 1.1
+ * @throws IOException on error
+ * @throws Zip64RequiredException if the entry's uncompressed or
+ * compressed size exceeds 4 GByte and {@link #setUseZip64}
+ * is {@link Zip64Mode#Never}.
+ */
+ public void closeEntry() throws IOException {
+ preClose();
+
+ flushDeflater();
+
+ final Zip64Mode effectiveMode = getEffectiveZip64Mode(entry.entry);
+ long bytesWritten = written - entry.dataStart;
+ long realCrc = crc.getValue();
+ crc.reset();
+
+ final boolean actuallyNeedsZip64 =
+ handleSizesAndCrc(bytesWritten, realCrc, effectiveMode);
+
+ closeEntry(actuallyNeedsZip64);
+ }
+
+ private void closeEntry(boolean actuallyNeedsZip64) throws IOException {
+ if (raf != null) {
+ rewriteSizesAndCrc(actuallyNeedsZip64);
+ }
+
+ writeDataDescriptor(entry.entry);
+ entry = null;
+ }
+
+ private void preClose() throws IOException {
+ if (finished) {
+ throw new IOException("Stream has already been finished");
+ }
+
+ if (entry == null) {
+ throw new IOException("No current entry to close");
+ }
+
+ if (!entry.hasWritten) {
+ write(EMPTY, 0, 0);
+ }
+ }
+
+ /**
+ * Ensures all bytes sent to the deflater are written to the stream.
+ */
+ private void flushDeflater() throws IOException {
+ if (entry.entry.getMethod() == DEFLATED) {
+ def.finish();
+ while (!def.finished()) {
+ deflate();
+ }
+ }
+ }
+
+ /**
+ * Ensures the current entry's size and CRC information is set to
+ * the values just written, verifies it isn't too big in the
+ * Zip64Mode.Never case and returns whether the entry would
+ * require a Zip64 extra field.
+ */
+ private boolean handleSizesAndCrc(long bytesWritten, long crc,
+ Zip64Mode effectiveMode)
+ throws ZipException {
+ if (entry.entry.getMethod() == DEFLATED) {
+ /* It turns out def.getBytesRead() returns wrong values if
+ * the size exceeds 4 GB on Java < Java7
+ entry.entry.setSize(def.getBytesRead());
+ */
+ entry.entry.setSize(entry.bytesRead);
+ entry.entry.setCompressedSize(bytesWritten);
+ entry.entry.setCrc(crc);
+
+ def.reset();
+ } else if (raf == null) {
+ if (entry.entry.getCrc() != crc) {
+ throw new ZipException("bad CRC checksum for entry "
+ + entry.entry.getName() + ": "
+ + Long.toHexString(entry.entry.getCrc())
+ + " instead of "
+ + Long.toHexString(crc));
+ }
+
+ if (entry.entry.getSize() != bytesWritten) {
+ throw new ZipException("bad size for entry "
+ + entry.entry.getName() + ": "
+ + entry.entry.getSize()
+ + " instead of "
+ + bytesWritten);
+ }
+ } else { /* method is STORED and we used RandomAccessFile */
+ entry.entry.setSize(bytesWritten);
+ entry.entry.setCompressedSize(bytesWritten);
+ entry.entry.setCrc(crc);
+ }
+
+ return checkIfNeedsZip64(effectiveMode);
+ }
+
+ /**
+ * Ensures the current entry's size and CRC information is set to
+ * the values just written, verifies it isn't too big in the
+ * Zip64Mode.Never case and returns whether the entry would
+ * require a Zip64 extra field.
+ */
+ private boolean checkIfNeedsZip64(Zip64Mode effectiveMode)
+ throws ZipException {
+ final boolean actuallyNeedsZip64 = isZip64Required(entry.entry,
+ effectiveMode);
+ if (actuallyNeedsZip64 && effectiveMode == Zip64Mode.Never) {
+ throw new Zip64RequiredException(Zip64RequiredException
+ .getEntryTooBigMessage(entry.entry));
+ }
+ return actuallyNeedsZip64;
+ }
+
+ private boolean isZip64Required(ZipEntry entry1, Zip64Mode requestedMode) {
+ return requestedMode == Zip64Mode.Always || isTooLageForZip32(entry1);
+ }
+
+ private boolean isTooLageForZip32(ZipEntry zipArchiveEntry){
+ return zipArchiveEntry.getSize() >= ZIP64_MAGIC
+ || zipArchiveEntry.getCompressedSize() >= ZIP64_MAGIC;
+ }
+
+ /**
+ * When using random access output, write the local file header
+ * and potentiall the ZIP64 extra containing the correct CRC and
+ * compressed/uncompressed sizes.
+ */
+ private void rewriteSizesAndCrc(boolean actuallyNeedsZip64)
+ throws IOException {
+ long save = raf.getFilePointer();
+
+ raf.seek(entry.localDataStart);
+ writeOut(ZipLong.getBytes(entry.entry.getCrc()));
+ if (!hasZip64Extra(entry.entry) || !actuallyNeedsZip64) {
+ writeOut(ZipLong.getBytes(entry.entry.getCompressedSize()));
+ writeOut(ZipLong.getBytes(entry.entry.getSize()));
+ } else {
+ writeOut(ZipLong.ZIP64_MAGIC.getBytes());
+ writeOut(ZipLong.ZIP64_MAGIC.getBytes());
+ }
+
+ if (hasZip64Extra(entry.entry)) {
+ // seek to ZIP64 extra, skip header and size information
+ raf.seek(entry.localDataStart + 3 * WORD + 2 * SHORT
+ + getName(entry.entry).limit() + 2 * SHORT);
+ // inside the ZIP64 extra uncompressed size comes
+ // first, unlike the LFH, CD or data descriptor
+ writeOut(ZipEightByteInteger.getBytes(entry.entry.getSize()));
+ writeOut(ZipEightByteInteger.getBytes(entry.entry.getCompressedSize()));
+
+ if (!actuallyNeedsZip64) {
+ // do some cleanup:
+ // * rewrite version needed to extract
+ raf.seek(entry.localDataStart - 5 * SHORT);
+ writeOut(ZipShort.getBytes(INITIAL_VERSION));
+
+ // * remove ZIP64 extra so it doesn't get written
+ // to the central directory
+ entry.entry.removeExtraField(Zip64ExtendedInformationExtraField
+ .HEADER_ID);
+ entry.entry.setExtra();
+
+ // * reset hasUsedZip64 if it has been set because
+ // of this entry
+ if (entry.causedUseOfZip64) {
+ hasUsedZip64 = false;
+ }
+ }
+ }
+ raf.seek(save);
+ }
+
+ /**
+ * {@inheritDoc}
+ * @throws Zip64RequiredException if the entry's uncompressed or
+ * compressed size is known to exceed 4 GByte and {@link #setUseZip64}
+ * is {@link Zip64Mode#Never}.
+ */
+ public void putNextEntry(ZipEntry archiveEntry) throws IOException {
+ if (finished) {
+ throw new IOException("Stream has already been finished");
+ }
+
+ if (entry != null) {
+ closeEntry();
+ }
+
+ entry = new CurrentEntry(archiveEntry);
+ entries.add(entry.entry);
+
+ setDefaults(entry.entry);
+
+ final Zip64Mode effectiveMode = getEffectiveZip64Mode(entry.entry);
+ validateSizeInformation(effectiveMode);
+
+ if (shouldAddZip64Extra(entry.entry, effectiveMode)) {
+
+ Zip64ExtendedInformationExtraField z64 = getZip64Extra(entry.entry);
+
+ // just a placeholder, real data will be in data
+ // descriptor or inserted later via RandomAccessFile
+ ZipEightByteInteger size = ZipEightByteInteger.ZERO;
+ ZipEightByteInteger compressedSize = ZipEightByteInteger.ZERO;
+ if (entry.entry.getMethod() == STORED
+ && entry.entry.getSize() != -1) {
+ // actually, we already know the sizes
+ size = new ZipEightByteInteger(entry.entry.getSize());
+ compressedSize = size;
+ }
+ z64.setSize(size);
+ z64.setCompressedSize(compressedSize);
+ entry.entry.setExtra();
+ }
+
+ if (entry.entry.getMethod() == DEFLATED && hasCompressionLevelChanged) {
+ def.setLevel(level);
+ hasCompressionLevelChanged = false;
+ }
+ writeLocalFileHeader(entry.entry);
+ }
+
+ /**
+ * Provides default values for compression method and last
+ * modification time.
+ */
+ private void setDefaults(ZipEntry entry) {
+ if (entry.getMethod() == -1) { // not specified
+ entry.setMethod(method);
+ }
+
+ if (entry.getTime() == -1) { // not specified
+ entry.setTime(System.currentTimeMillis());
+ }
+ }
+
+ /**
+ * Throws an exception if the size is unknown for a stored entry
+ * that is written to a non-seekable output or the entry is too
+ * big to be written without Zip64 extra but the mode has been set
+ * to Never.
+ */
+ private void validateSizeInformation(Zip64Mode effectiveMode)
+ throws ZipException {
+ // Size/CRC not required if RandomAccessFile is used
+ if (entry.entry.getMethod() == STORED && raf == null) {
+ if (entry.entry.getSize() == -1) {
+ throw new ZipException("uncompressed size is required for"
+ + " STORED method when not writing to a"
+ + " file");
+ }
+ if (entry.entry.getCrc() == -1) {
+ throw new ZipException("crc checksum is required for STORED"
+ + " method when not writing to a file");
+ }
+ entry.entry.setCompressedSize(entry.entry.getSize());
+ }
+
+ if ((entry.entry.getSize() >= ZIP64_MAGIC
+ || entry.entry.getCompressedSize() >= ZIP64_MAGIC)
+ && effectiveMode == Zip64Mode.Never) {
+ throw new Zip64RequiredException(Zip64RequiredException
+ .getEntryTooBigMessage(entry.entry));
+ }
+ }
+
+ /**
+ * Whether to addd a Zip64 extended information extra field to the
+ * local file header.
+ *
+ * <p>Returns true if</p>
+ *
+ * <ul>
+ * <li>mode is Always</li>
+ * <li>or we already know it is going to be needed</li>
+ * <li>or the size is unknown and we can ensure it won't hurt
+ * other implementations if we add it (i.e. we can erase its
+ * usage</li>
+ * </ul>
+ */
+ private boolean shouldAddZip64Extra(ZipEntry entry, Zip64Mode mode) {
+ return mode == Zip64Mode.Always
+ || entry.getSize() >= ZIP64_MAGIC
+ || entry.getCompressedSize() >= ZIP64_MAGIC
+ || (entry.getSize() == -1
+ && raf != null && mode != Zip64Mode.Never);
+ }
+
+ /**
+ * Set the file comment.
+ * @param comment the comment
+ */
+ public void setComment(String comment) {
+ this.comment = comment;
+ }
+
+ /**
+ * Sets the compression level for subsequent entries.
+ *
+ * <p>Default is Deflater.DEFAULT_COMPRESSION.</p>
+ * @param level the compression level.
+ * @throws IllegalArgumentException if an invalid compression
+ * level is specified.
+ * @since 1.1
+ */
+ public void setLevel(int level) {
+ if (level < Deflater.DEFAULT_COMPRESSION
+ || level > Deflater.BEST_COMPRESSION) {
+ throw new IllegalArgumentException("Invalid compression level: "
+ + level);
+ }
+ hasCompressionLevelChanged = (this.level != level);
+ this.level = level;
+ }
+
+ /**
+ * Sets the default compression method for subsequent entries.
+ *
+ * <p>Default is DEFLATED.</p>
+ * @param method an <code>int</code> from java.util.zip.ZipEntry
+ * @since 1.1
+ */
+ public void setMethod(int method) {
+ this.method = method;
+ }
+
+ /**
+ * Whether this stream is able to write the given entry.
+ *
+ * <p>May return false if it is set up to use encryption or a
+ * compression method that hasn't been implemented yet.</p>
+ */
+ public boolean canWriteEntryData(ZipEntry ae) {
+ return ZipUtil.canHandleEntryData(ae);
+ }
+
+ /**
+ * Writes bytes to ZIP entry.
+ * @param b the byte array to write
+ * @param offset the start position to write from
+ * @param length the number of bytes to write
+ * @throws IOException on error
+ */
+ @Override
+ public void write(byte[] b, int offset, int length) throws IOException {
+ if (entry == null) {
+ throw new IllegalStateException("No current entry");
+ }
+ ZipUtil.checkRequestedFeatures(entry.entry);
+ entry.hasWritten = true;
+ if (entry.entry.getMethod() == DEFLATED) {
+ writeDeflated(b, offset, length);
+ } else {
+ writeCounted(b, offset, length);
+ }
+ crc.update(b, offset, length);
+ }
+
+ /**
+ * Write bytes to output or random access file.
+ * @param data the byte array to write
+ * @throws IOException on error
+ */
+ private void writeCounted(byte[] data) throws IOException {
+ writeCounted(data, 0, data.length);
+ }
+
+ private void writeCounted(byte[] data, int offset, int length) throws IOException {
+ writeOut(data, offset, length);
+ written += length;
+ }
+
+ /**
+ * write implementation for DEFLATED entries.
+ */
+ private void writeDeflated(byte[]b, int offset, int length)
+ throws IOException {
+ if (length > 0 && !def.finished()) {
+ entry.bytesRead += length;
+ if (length <= DEFLATER_BLOCK_SIZE) {
+ def.setInput(b, offset, length);
+ deflateUntilInputIsNeeded();
+ } else {
+ final int fullblocks = length / DEFLATER_BLOCK_SIZE;
+ for (int i = 0; i < fullblocks; i++) {
+ def.setInput(b, offset + i * DEFLATER_BLOCK_SIZE,
+ DEFLATER_BLOCK_SIZE);
+ deflateUntilInputIsNeeded();
+ }
+ final int done = fullblocks * DEFLATER_BLOCK_SIZE;
+ if (done < length) {
+ def.setInput(b, offset + done, length - done);
+ deflateUntilInputIsNeeded();
+ }
+ }
+ }
+ }
+
+ /**
+ * Closes this output stream and releases any system resources
+ * associated with the stream.
+ *
+ * @exception IOException if an I/O error occurs.
+ * @throws Zip64RequiredException if the archive's size exceeds 4
+ * GByte or there are more than 65535 entries inside the archive
+ * and {@link #setUseZip64} is {@link Zip64Mode#Never}.
+ */
+ @Override
+ public void close() throws IOException {
+ if (!finished) {
+ finish();
+ }
+ destroy();
+ }
+
+ /**
+ * Flushes this output stream and forces any buffered output bytes
+ * to be written out to the stream.
+ *
+ * @exception IOException if an I/O error occurs.
+ */
+ @Override
+ public void flush() throws IOException {
+ if (out != null) {
+ out.flush();
+ }
+ }
+
+ /*
+ * Various ZIP constants
+ */
+ /**
+ * local file header signature
+ *
+ * @since 1.1
+ */
+ protected static final byte[] LFH_SIG = ZipLong.LFH_SIG.getBytes();
+ /**
+ * data descriptor signature
+ *
+ * @since 1.1
+ */
+ protected static final byte[] DD_SIG = ZipLong.DD_SIG.getBytes();
+ /**
+ * central file header signature
+ *
+ * @since 1.1
+ */
+ protected static final byte[] CFH_SIG = ZipLong.CFH_SIG.getBytes();
+ /**
+ * end of central dir signature
+ *
+ * @since 1.1
+ */
+ protected static final byte[] EOCD_SIG = ZipLong.getBytes(0X06054B50L);
+ /**
+ * ZIP64 end of central dir signature
+ */
+ static final byte[] ZIP64_EOCD_SIG = ZipLong.getBytes(0X06064B50L);
+ /**
+ * ZIP64 end of central dir locator signature
+ */
+ static final byte[] ZIP64_EOCD_LOC_SIG = ZipLong.getBytes(0X07064B50L);
+
+ /**
+ * Writes next block of compressed data to the output stream.
+ * @throws IOException on error
+ *
+ * @since 1.14
+ */
+ protected final void deflate() throws IOException {
+ int len = def.deflate(buf, 0, buf.length);
+ if (len > 0) {
+ writeCounted(buf, 0, len);
+ }
+ }
+
+ /**
+ * Writes the local file header entry
+ * @param ze the entry to write
+ * @throws IOException on error
+ *
+ * @since 1.1
+ */
+ protected void writeLocalFileHeader(ZipEntry ze) throws IOException {
+
+ boolean encodable = zipEncoding.canEncode(ze.getName());
+ ByteBuffer name = getName(ze);
+
+ if (createUnicodeExtraFields != UnicodeExtraFieldPolicy.NEVER) {
+ addUnicodeExtraFields(ze, encodable, name);
+ }
+
+ final byte[] localHeader = createLocalFileHeader(ze, name, encodable);
+ final long localHeaderStart = written;
+ offsets.put(ze, localHeaderStart);
+ entry.localDataStart = localHeaderStart + LFH_CRC_OFFSET; // At crc offset
+ writeCounted(localHeader);
+ entry.dataStart = written;
+ }
+
+ private byte[] createLocalFileHeader(ZipEntry ze, ByteBuffer name, boolean encodable) {
+ byte[] extra = ze.getLocalFileDataExtra();
+ final int nameLen = name.limit() - name.position();
+ int len= LFH_FILENAME_OFFSET + nameLen + extra.length;
+ byte[] buf = new byte[len];
+
+ System.arraycopy(LFH_SIG, 0, buf, LFH_SIG_OFFSET, WORD);
+
+ //store method in local variable to prevent multiple method calls
+ final int zipMethod = ze.getMethod();
+
+ putShort(versionNeededToExtract(zipMethod, hasZip64Extra(ze)),
+ buf, LFH_VERSION_NEEDED_OFFSET);
+
+ GeneralPurposeBit generalPurposeBit =
+ getGeneralPurposeBits(zipMethod, !encodable && fallbackToUTF8);
+ generalPurposeBit.encode(buf, LFH_GPB_OFFSET);
+
+ // compression method
+ putShort(zipMethod, buf, LFH_METHOD_OFFSET);
+
+ ZipUtil.toDosTime(calendarInstance, ze.getTime(), buf, LFH_TIME_OFFSET);
+
+ // CRC
+ if (zipMethod == DEFLATED || raf != null) {
+ System.arraycopy(LZERO, 0, buf, LFH_CRC_OFFSET, WORD);
+ } else {
+ putLong(ze.getCrc(), buf, LFH_CRC_OFFSET);
+ }
+
+ // compressed length
+ // uncompressed length
+ if (hasZip64Extra(entry.entry)){
+ // point to ZIP64 extended information extra field for
+ // sizes, may get rewritten once sizes are known if
+ // stream is seekable
+ ZipLong.ZIP64_MAGIC.putLong(buf, LFH_COMPRESSED_SIZE_OFFSET);
+ ZipLong.ZIP64_MAGIC.putLong(buf, LFH_ORIGINAL_SIZE_OFFSET);
+ } else if (zipMethod == DEFLATED || raf != null) {
+ System.arraycopy(LZERO, 0, buf, LFH_COMPRESSED_SIZE_OFFSET, WORD);
+ System.arraycopy(LZERO, 0, buf, LFH_ORIGINAL_SIZE_OFFSET, WORD);
+ } else { // Stored
+ putLong(ze.getSize(), buf, LFH_COMPRESSED_SIZE_OFFSET);
+ putLong(ze.getSize(), buf, LFH_ORIGINAL_SIZE_OFFSET);
+ }
+ // file name length
+ putShort(nameLen, buf, LFH_FILENAME_LENGTH_OFFSET);
+
+ // extra field length
+ putShort(extra.length, buf, LFH_EXTRA_LENGTH_OFFSET);
+
+ // file name
+ System.arraycopy(name.array(), name.arrayOffset(), buf,
+ LFH_FILENAME_OFFSET, nameLen);
+
+ System.arraycopy(extra, 0, buf, LFH_FILENAME_OFFSET + nameLen, extra.length);
+ return buf;
+ }
+
+ /**
+ * Adds UnicodeExtra fields for name and file comment if mode is
+ * ALWAYS or the data cannot be encoded using the configured
+ * encoding.
+ */
+ private void addUnicodeExtraFields(ZipEntry ze, boolean encodable,
+ ByteBuffer name)
+ throws IOException {
+ if (createUnicodeExtraFields == UnicodeExtraFieldPolicy.ALWAYS
+ || !encodable) {
+ ze.addExtraField(new UnicodePathExtraField(ze.getName(),
+ name.array(),
+ name.arrayOffset(),
+ name.limit()
+ - name.position()));
+ }
+
+ String comm = ze.getComment();
+ if (comm != null && !"".equals(comm)) {
+
+ boolean commentEncodable = zipEncoding.canEncode(comm);
+
+ if (createUnicodeExtraFields == UnicodeExtraFieldPolicy.ALWAYS
+ || !commentEncodable) {
+ ByteBuffer commentB = getEntryEncoding(ze).encode(comm);
+ ze.addExtraField(new UnicodeCommentExtraField(comm,
+ commentB.array(),
+ commentB.arrayOffset(),
+ commentB.limit()
+ - commentB.position())
+ );
+ }
+ }
+ }
+
+ /**
+ * Writes the data descriptor entry.
+ * @param ze the entry to write
+ * @throws IOException on error
+ *
+ * @since 1.1
+ */
+ protected void writeDataDescriptor(ZipEntry ze) throws IOException {
+ if (ze.getMethod() != DEFLATED || raf != null) {
+ return;
+ }
+ writeCounted(DD_SIG);
+ writeCounted(ZipLong.getBytes(ze.getCrc()));
+ if (!hasZip64Extra(ze)) {
+ writeCounted(ZipLong.getBytes(ze.getCompressedSize()));
+ writeCounted(ZipLong.getBytes(ze.getSize()));
+ } else {
+ writeCounted(ZipEightByteInteger.getBytes(ze.getCompressedSize()));
+ writeCounted(ZipEightByteInteger.getBytes(ze.getSize()));
+ }
+ }
+
+ /**
+ * Writes the central file header entry.
+ * @param ze the entry to write
+ * @throws IOException on error
+ * @throws Zip64RequiredException if the archive's size exceeds 4
+ * GByte and {@link Zip64Mode #setUseZip64} is {@link
+ * Zip64Mode#Never}.
+ */
+ protected void writeCentralFileHeader(ZipEntry ze) throws IOException {
+ byte[] centralFileHeader = createCentralFileHeader(ze);
+ writeCounted(centralFileHeader);
+ }
+
+ private byte[] createCentralFileHeader(ZipEntry ze) throws IOException {
+ final long lfhOffset = offsets.get(ze);
+ final boolean needsZip64Extra = hasZip64Extra(ze)
+ || ze.getCompressedSize() >= ZIP64_MAGIC
+ || ze.getSize() >= ZIP64_MAGIC
+ || lfhOffset >= ZIP64_MAGIC;
+
+ if (needsZip64Extra && zip64Mode == Zip64Mode.Never) {
+ // must be the offset that is too big, otherwise an
+ // exception would have been throw in putArchiveEntry or
+ // closeArchiveEntry
+ throw new Zip64RequiredException(Zip64RequiredException
+ .ARCHIVE_TOO_BIG_MESSAGE);
+ }
+
+
+ handleZip64Extra(ze, lfhOffset, needsZip64Extra);
+
+ return createCentralFileHeader(ze, getName(ze), lfhOffset, needsZip64Extra);
+ }
+
+ /**
+ * Writes the central file header entry.
+ * @param ze the entry to write
+ * @param name The encoded name
+ * @param lfhOffset Local file header offset for this file
+ * @throws IOException on error
+ */
+ private byte[] createCentralFileHeader(ZipEntry ze, ByteBuffer name, long lfhOffset,
+ boolean needsZip64Extra) throws IOException {
+ byte[] extra = ze.getCentralDirectoryExtra();
+
+ // file comment length
+ String comm = ze.getComment();
+ if (comm == null) {
+ comm = "";
+ }
+
+ ByteBuffer commentB = getEntryEncoding(ze).encode(comm);
+ final int nameLen = name.limit() - name.position();
+ final int commentLen = commentB.limit() - commentB.position();
+ int len= CFH_FILENAME_OFFSET + nameLen + extra.length + commentLen;
+ byte[] buf = new byte[len];
+
+ System.arraycopy(CFH_SIG, 0, buf, CFH_SIG_OFFSET, WORD);
+
+ // version made by
+ // CheckStyle:MagicNumber OFF
+ putShort((ze.getPlatform() << 8) | (!hasUsedZip64 ? DATA_DESCRIPTOR_MIN_VERSION : ZIP64_MIN_VERSION),
+ buf, CFH_VERSION_MADE_BY_OFFSET);
+
+ final int zipMethod = ze.getMethod();
+ final boolean encodable = zipEncoding.canEncode(ze.getName());
+ putShort(versionNeededToExtract(zipMethod, needsZip64Extra), buf, CFH_VERSION_NEEDED_OFFSET);
+ getGeneralPurposeBits(zipMethod, !encodable && fallbackToUTF8).encode(buf, CFH_GPB_OFFSET);
+
+ // compression method
+ putShort(zipMethod, buf, CFH_METHOD_OFFSET);
+
+
+ // last mod. time and date
+ ZipUtil.toDosTime(calendarInstance, ze.getTime(), buf, CFH_TIME_OFFSET);
+
+ // CRC
+ // compressed length
+ // uncompressed length
+ putLong(ze.getCrc(), buf, CFH_CRC_OFFSET);
+ if (ze.getCompressedSize() >= ZIP64_MAGIC
+ || ze.getSize() >= ZIP64_MAGIC) {
+ ZipLong.ZIP64_MAGIC.putLong(buf, CFH_COMPRESSED_SIZE_OFFSET);
+ ZipLong.ZIP64_MAGIC.putLong(buf, CFH_ORIGINAL_SIZE_OFFSET);
+ } else {
+ putLong(ze.getCompressedSize(), buf, CFH_COMPRESSED_SIZE_OFFSET);
+ putLong(ze.getSize(), buf, CFH_ORIGINAL_SIZE_OFFSET);
+ }
+
+ putShort(nameLen, buf, CFH_FILENAME_LENGTH_OFFSET);
+
+ // extra field length
+ putShort(extra.length, buf, CFH_EXTRA_LENGTH_OFFSET);
+
+ putShort(commentLen, buf, CFH_COMMENT_LENGTH_OFFSET);
+
+ // disk number start
+ System.arraycopy(ZERO, 0, buf, CFH_DISK_NUMBER_OFFSET, SHORT);
+
+ // internal file attributes
+ putShort(ze.getInternalAttributes(), buf, CFH_INTERNAL_ATTRIBUTES_OFFSET);
+
+ // external file attributes
+ putLong(ze.getExternalAttributes(), buf, CFH_EXTERNAL_ATTRIBUTES_OFFSET);
+
+ // relative offset of LFH
+ putLong(Math.min(lfhOffset, ZIP64_MAGIC), buf, CFH_LFH_OFFSET);
+
+ // file name
+ System.arraycopy(name.array(), name.arrayOffset(), buf, CFH_FILENAME_OFFSET, nameLen);
+
+ int extraStart = CFH_FILENAME_OFFSET + nameLen;
+ System.arraycopy(extra, 0, buf, extraStart, extra.length);
+
+ int commentStart = extraStart + commentLen;
+
+ // file comment
+ System.arraycopy(commentB.array(), commentB.arrayOffset(), buf, commentStart, commentLen);
+ return buf;
+ }
+
+ /**
+ * If the entry needs Zip64 extra information inside the central
+ * directory then configure its data.
+ */
+ private void handleZip64Extra(ZipEntry ze, long lfhOffset,
+ boolean needsZip64Extra) {
+ if (needsZip64Extra) {
+ Zip64ExtendedInformationExtraField z64 = getZip64Extra(ze);
+ if (ze.getCompressedSize() >= ZIP64_MAGIC
+ || ze.getSize() >= ZIP64_MAGIC) {
+ z64.setCompressedSize(new ZipEightByteInteger(ze.getCompressedSize()));
+ z64.setSize(new ZipEightByteInteger(ze.getSize()));
+ } else {
+ // reset value that may have been set for LFH
+ z64.setCompressedSize(null);
+ z64.setSize(null);
+ }
+ if (lfhOffset >= ZIP64_MAGIC) {
+ z64.setRelativeHeaderOffset(new ZipEightByteInteger(lfhOffset));
+ }
+ ze.setExtra();
+ }
+ }
+
+ /**
+ * Writes the &quot;End of central dir record&quot;.
+ * @throws IOException on error
+ * @throws Zip64RequiredException if the archive's size exceeds 4
+ * GByte or there are more than 65535 entries inside the archive
+ * and {@link Zip64Mode #setUseZip64} is {@link Zip64Mode#Never}.
+ */
+ protected void writeCentralDirectoryEnd() throws IOException {
+ writeCounted(EOCD_SIG);
+
+ // disk numbers
+ writeCounted(ZERO);
+ writeCounted(ZERO);
+
+ // number of entries
+ int numberOfEntries = entries.size();
+ if (numberOfEntries > ZIP64_MAGIC_SHORT
+ && zip64Mode == Zip64Mode.Never) {
+ throw new Zip64RequiredException(Zip64RequiredException
+ .TOO_MANY_ENTRIES_MESSAGE);
+ }
+ if (cdOffset > ZIP64_MAGIC && zip64Mode == Zip64Mode.Never) {
+ throw new Zip64RequiredException(Zip64RequiredException
+ .ARCHIVE_TOO_BIG_MESSAGE);
+ }
+
+ byte[] num = ZipShort.getBytes(Math.min(numberOfEntries,
+ ZIP64_MAGIC_SHORT));
+ writeCounted(num);
+ writeCounted(num);
+
+ // length and location of CD
+ writeCounted(ZipLong.getBytes(Math.min(cdLength, ZIP64_MAGIC)));
+ writeCounted(ZipLong.getBytes(Math.min(cdOffset, ZIP64_MAGIC)));
+
+ // ZIP file comment
+ ByteBuffer data = this.zipEncoding.encode(comment);
+ int dataLen = data.limit() - data.position();
+ writeCounted(ZipShort.getBytes(dataLen));
+ writeCounted(data.array(), data.arrayOffset(), dataLen);
+ }
+
+ /**
+ * Convert a Date object to a DOS date/time field.
+ * @param time the <code>Date</code> to convert
+ * @return the date as a <code>ZipLong</code>
+ * @since 1.1
+ * @deprecated use ZipUtil#toDosTime
+ */
+ @Deprecated
+ protected static ZipLong toDosTime(Date time) {
+ return ZipUtil.toDosTime(time);
+ }
+
+ /**
+ * Convert a Date object to a DOS date/time field.
+ *
+ * <p>Stolen from InfoZip's <code>fileio.c</code></p>
+ * @param t number of milliseconds since the epoch
+ * @return the date as a byte array
+ * @since 1.26
+ * @deprecated use ZipUtil#toDosTime
+ */
+ @Deprecated
+ protected static byte[] toDosTime(long t) {
+ return ZipUtil.toDosTime(t);
+ }
+
+ /**
+ * Retrieve the bytes for the given String in the encoding set for
+ * this Stream.
+ * @param name the string to get bytes from
+ * @return the bytes as a byte array
+ * @throws ZipException on error
+ *
+ * @since 1.3
+ */
+ protected byte[] getBytes(String name) throws ZipException {
+ try {
+ ByteBuffer b =
+ ZipEncodingHelper.getZipEncoding(encoding).encode(name);
+ byte[] result = new byte[b.limit()];
+ System.arraycopy(b.array(), b.arrayOffset(), result, 0,
+ result.length);
+ return result;
+ } catch (IOException ex) {
+ throw new ZipException("Failed to encode name: " + ex.getMessage());
+ }
+ }
+
+ /**
+ * Writes the &quot;ZIP64 End of central dir record&quot; and
+ * &quot;ZIP64 End of central dir locator&quot;.
+ * @throws IOException on error
+ */
+ protected void writeZip64CentralDirectory() throws IOException {
+ if (zip64Mode == Zip64Mode.Never) {
+ return;
+ }
+
+ if (!hasUsedZip64
+ && (cdOffset >= ZIP64_MAGIC || cdLength >= ZIP64_MAGIC
+ || entries.size() >= ZIP64_MAGIC_SHORT)) {
+ // actually "will use"
+ hasUsedZip64 = true;
+ }
+
+ if (!hasUsedZip64) {
+ return;
+ }
+
+ long offset = written;
+
+ writeOut(ZIP64_EOCD_SIG);
+ // size, we don't have any variable length as we don't support
+ // the extensible data sector, yet
+ writeOut(ZipEightByteInteger
+ .getBytes(SHORT /* version made by */
+ + SHORT /* version needed to extract */
+ + WORD /* disk number */
+ + WORD /* disk with central directory */
+ + DWORD /* number of entries in CD on this disk */
+ + DWORD /* total number of entries */
+ + DWORD /* size of CD */
+ + DWORD /* offset of CD */
+ ));
+
+ // version made by and version needed to extract
+ writeOut(ZipShort.getBytes(ZIP64_MIN_VERSION));
+ writeOut(ZipShort.getBytes(ZIP64_MIN_VERSION));
+
+ // disk numbers - four bytes this time
+ writeOut(LZERO);
+ writeOut(LZERO);
+
+ // number of entries
+ byte[] num = ZipEightByteInteger.getBytes(entries.size());
+ writeOut(num);
+ writeOut(num);
+
+ // length and location of CD
+ writeOut(ZipEightByteInteger.getBytes(cdLength));
+ writeOut(ZipEightByteInteger.getBytes(cdOffset));
+
+ // no "zip64 extensible data sector" for now
+
+ // and now the "ZIP64 end of central directory locator"
+ writeOut(ZIP64_EOCD_LOC_SIG);
+
+ // disk number holding the ZIP64 EOCD record
+ writeOut(LZERO);
+ // relative offset of ZIP64 EOCD record
+ writeOut(ZipEightByteInteger.getBytes(offset));
+ // total number of disks
+ writeOut(ONE);
+ }
+
+ /**
+ * Write bytes to output or random access file.
+ * @param data the byte array to write
+ * @throws IOException on error
+ *
+ * @since 1.14
+ */
+ protected final void writeOut(byte[] data) throws IOException {
+ writeOut(data, 0, data.length);
+ }
+
+ /**
+ * Write bytes to output or random access file.
+ * @param data the byte array to write
+ * @param offset the start position to write from
+ * @param length the number of bytes to write
+ * @throws IOException on error
+ *
+ * @since 1.14
+ */
+ protected final void writeOut(byte[] data, int offset, int length)
+ throws IOException {
+ if (raf != null) {
+ raf.write(data, offset, length);
+ } else {
+ out.write(data, offset, length);
+ }
+ }
+
+ /**
+ * Assumes a negative integer really is a positive integer that
+ * has wrapped around and re-creates the original value.
+ * @param i the value to treat as unsigned int.
+ * @return the unsigned int as a long.
+ * @since 1.34
+ * @deprecated use ZipUtil#adjustToLong
+ */
+ @Deprecated
+ protected static long adjustToLong(int i) {
+ return ZipUtil.adjustToLong(i);
+ }
+
+ private void deflateUntilInputIsNeeded() throws IOException {
+ while (!def.needsInput()) {
+ deflate();
+ }
+ }
+
+ private GeneralPurposeBit getGeneralPurposeBits(final int zipMethod, final boolean utfFallback) {
+ GeneralPurposeBit b = new GeneralPurposeBit();
+ b.useUTF8ForNames(useUTF8Flag || utfFallback);
+ if (isDeflatedToOutputStream(zipMethod)) {
+ b.useDataDescriptor(true);
+ }
+ return b;
+ }
+
+ private int versionNeededToExtract(final int zipMethod, final boolean zip64) {
+ if (zip64) {
+ return ZIP64_MIN_VERSION;
+ }
+ // requires version 2 as we are going to store length info
+ // in the data descriptor
+ return (isDeflatedToOutputStream(zipMethod)) ?
+ DATA_DESCRIPTOR_MIN_VERSION :
+ INITIAL_VERSION;
+ }
+
+ private boolean isDeflatedToOutputStream(int zipMethod) {
+ return zipMethod == DEFLATED && raf == null;
+ }
+
+ /**
+ * Get the existing ZIP64 extended information extra field or
+ * create a new one and add it to the entry.
+ */
+ private Zip64ExtendedInformationExtraField getZip64Extra(ZipEntry ze) {
+ if (entry != null) {
+ entry.causedUseOfZip64 = !hasUsedZip64;
+ }
+ hasUsedZip64 = true;
+ Zip64ExtendedInformationExtraField z64 =
+ (Zip64ExtendedInformationExtraField)
+ ze.getExtraField(Zip64ExtendedInformationExtraField
+ .HEADER_ID);
+ if (z64 == null) {
+ /*
+ System.err.println("Adding z64 for " + ze.getName()
+ + ", method: " + ze.getMethod()
+ + " (" + (ze.getMethod() == STORED) + ")"
+ + ", raf: " + (raf != null));
+ */
+ z64 = new Zip64ExtendedInformationExtraField();
+ }
+
+ // even if the field is there already, make sure it is the first one
+ ze.addAsFirstExtraField(z64);
+
+ return z64;
+ }
+
+ /**
+ * Is there a ZIP64 extended information extra field for the
+ * entry?
+ */
+ private boolean hasZip64Extra(ZipEntry ze) {
+ return ze.getExtraField(Zip64ExtendedInformationExtraField
+ .HEADER_ID)
+ != null;
+ }
+
+ /**
+ * If the mode is AsNeeded and the entry is a compressed entry of
+ * unknown size that gets written to a non-seekable stream the
+ * change the default to Never.
+ */
+ private Zip64Mode getEffectiveZip64Mode(ZipEntry ze) {
+ if (zip64Mode != Zip64Mode.AsNeeded
+ || raf != null
+ || ze.getMethod() != DEFLATED
+ || ze.getSize() != -1) {
+ return zip64Mode;
+ }
+ return Zip64Mode.Never;
+ }
+
+ private ZipEncoding getEntryEncoding(ZipEntry ze) {
+ boolean encodable = zipEncoding.canEncode(ze.getName());
+ return !encodable && fallbackToUTF8
+ ? ZipEncodingHelper.UTF8_ZIP_ENCODING : zipEncoding;
+ }
+
+ private ByteBuffer getName(ZipEntry ze) throws IOException {
+ return getEntryEncoding(ze).encode(ze.getName());
+ }
+
+ /**
+ * Closes the underlying stream/file without finishing the
+ * archive, the result will likely be a corrupt archive.
+ *
+ * <p>This method only exists to support tests that generate
+ * corrupt archives so they can clean up any temporary files.</p>
+ */
+ void destroy() throws IOException {
+ if (raf != null) {
+ raf.close();
+ }
+ if (out != null) {
+ out.close();
+ }
+ }
+
+ /**
+ * enum that represents the possible policies for creating Unicode
+ * extra fields.
+ */
+ public static final class UnicodeExtraFieldPolicy {
+ /**
+ * Always create Unicode extra fields.
+ */
+ public static final UnicodeExtraFieldPolicy ALWAYS =
+ new UnicodeExtraFieldPolicy("always");
+ /**
+ * Never create Unicode extra fields.
+ */
+ public static final UnicodeExtraFieldPolicy NEVER =
+ new UnicodeExtraFieldPolicy("never");
+ /**
+ * Create Unicode extra fields for filenames that cannot be
+ * encoded using the specified encoding.
+ */
+ public static final UnicodeExtraFieldPolicy NOT_ENCODEABLE =
+ new UnicodeExtraFieldPolicy("not encodeable");
+
+ private final String name;
+ private UnicodeExtraFieldPolicy(String n) {
+ name = n;
+ }
+ @Override
+ public String toString() {
+ return name;
+ }
+ }
+
+ /**
+ * Structure collecting information for the entry that is
+ * currently being written.
+ */
+ private static final class CurrentEntry {
+ private CurrentEntry(ZipEntry entry) {
+ this.entry = entry;
+ }
+ /**
+ * Current ZIP entry.
+ */
+ private final ZipEntry entry;
+ /**
+ * Offset for CRC entry in the local file header data for the
+ * current entry starts here.
+ */
+ private long localDataStart = 0;
+ /**
+ * Data for local header data
+ */
+ private long dataStart = 0;
+ /**
+ * Number of bytes read for the current entry (can't rely on
+ * Deflater#getBytesRead) when using DEFLATED.
+ */
+ private long bytesRead = 0;
+ /**
+ * Whether current entry was the first one using ZIP64 features.
+ */
+ private boolean causedUseOfZip64 = false;
+ /**
+ * Whether write() has been called at all.
+ *
+ * <p>In order to create a valid archive {@link
+ * #closeEntry closeEntry} will write an empty
+ * array to get the CRC right if nothing has been written to
+ * the stream at all.</p>
+ */
+ private boolean hasWritten;
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/ZipShort.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/ZipShort.java
new file mode 100644
index 00000000..e52c570d
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/ZipShort.java
@@ -0,0 +1,166 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.zip;
+
+import static org.apache.tools.zip.ZipConstants.BYTE_MASK;
+
+/**
+ * Utility class that represents a two byte integer with conversion
+ * rules for the big endian byte order of ZIP files.
+ *
+ */
+public final class ZipShort implements Cloneable {
+ private static final int BYTE_1_MASK = 0xFF00;
+ private static final int BYTE_1_SHIFT = 8;
+
+ private final int value;
+
+ /**
+ * Create instance from a number.
+ * @param value the int to store as a ZipShort
+ * @since 1.1
+ */
+ public ZipShort (int value) {
+ this.value = value;
+ }
+
+ /**
+ * Create instance from bytes.
+ * @param bytes the bytes to store as a ZipShort
+ * @since 1.1
+ */
+ public ZipShort (byte[] bytes) {
+ this(bytes, 0);
+ }
+
+ /**
+ * Create instance from the two bytes starting at offset.
+ * @param bytes the bytes to store as a ZipShort
+ * @param offset the offset to start
+ * @since 1.1
+ */
+ public ZipShort (byte[] bytes, int offset) {
+ value = ZipShort.getValue(bytes, offset);
+ }
+
+ /**
+ * Get value as two bytes in big endian byte order.
+ * @return the value as a a two byte array in big endian byte order
+ * @since 1.1
+ */
+ public byte[] getBytes() {
+ byte[] result = new byte[2];
+ putShort(value, result, 0);
+ return result;
+ }
+
+ /**
+ * put the value as two bytes in big endian byte order.
+ * @param value the Java int to convert to bytes
+ * @param buf the output buffer
+ * @param offset
+ * The offset within the output buffer of the first byte to be written.
+ * must be non-negative and no larger than <tt>buf.length-2</tt>
+ */
+ public static void putShort(int value, byte[] buf, int offset) {
+ buf[offset] = (byte) (value & BYTE_MASK);
+ buf[offset+1] = (byte) ((value & BYTE_1_MASK) >> BYTE_1_SHIFT);
+ }
+
+ /**
+ * Get value as Java int.
+ * @return value as a Java int
+ * @since 1.1
+ */
+ public int getValue() {
+ return value;
+ }
+
+ /**
+ * Get value as two bytes in big endian byte order.
+ * @param value the Java int to convert to bytes
+ * @return the converted int as a byte array in big endian byte order
+ */
+ public static byte[] getBytes(int value) {
+ byte[] result = new byte[2];
+ result[0] = (byte) (value & BYTE_MASK);
+ result[1] = (byte) ((value & BYTE_1_MASK) >> BYTE_1_SHIFT);
+ return result;
+ }
+
+ /**
+ * Helper method to get the value as a java int from two bytes starting at given array offset
+ * @param bytes the array of bytes
+ * @param offset the offset to start
+ * @return the corresponding java int value
+ */
+ public static int getValue(byte[] bytes, int offset) {
+ int value = (bytes[offset + 1] << BYTE_1_SHIFT) & BYTE_1_MASK;
+ value += (bytes[offset] & BYTE_MASK);
+ return value;
+ }
+
+ /**
+ * Helper method to get the value as a java int from a two-byte array
+ * @param bytes the array of bytes
+ * @return the corresponding java int value
+ */
+ public static int getValue(byte[] bytes) {
+ return getValue(bytes, 0);
+ }
+
+ /**
+ * Override to make two instances with same value equal.
+ * @param o an object to compare
+ * @return true if the objects are equal
+ * @since 1.1
+ */
+ @Override
+ public boolean equals(Object o) {
+ if (o == null || !(o instanceof ZipShort)) {
+ return false;
+ }
+ return value == ((ZipShort) o).getValue();
+ }
+
+ /**
+ * Override to make two instances with same value equal.
+ * @return the value stored in the ZipShort
+ * @since 1.1
+ */
+ @Override
+ public int hashCode() {
+ return value;
+ }
+
+ @Override
+ public Object clone() {
+ try {
+ return super.clone();
+ } catch (CloneNotSupportedException cnfe) {
+ // impossible
+ throw new RuntimeException(cnfe);
+ }
+ }
+
+ @Override
+ public String toString() {
+ return "ZipShort value: " + value;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/ZipUtil.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/ZipUtil.java
new file mode 100644
index 00000000..c25b8c7f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/zip/ZipUtil.java
@@ -0,0 +1,252 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.zip;
+
+import java.io.IOException;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.zip.CRC32;
+
+/**
+ * Utility class for handling DOS and Java time conversions.
+ * @since Ant 1.8.1
+ */
+public abstract class ZipUtil {
+ /**
+ * Smallest date/time ZIP can handle.
+ */
+ private static final byte[] DOS_TIME_MIN = ZipLong.getBytes(0x00002100L);
+
+ /**
+ * Convert a Date object to a DOS date/time field.
+ * @param time the <code>Date</code> to convert
+ * @return the date as a <code>ZipLong</code>
+ */
+ public static ZipLong toDosTime(Date time) {
+ return new ZipLong(toDosTime(time.getTime()));
+ }
+
+ /**
+ * Convert a Date object to a DOS date/time field.
+ *
+ * <p>Stolen from InfoZip's <code>fileio.c</code></p>
+ * @param t number of milliseconds since the epoch
+ * @return the date as a byte array
+ */
+ public static byte[] toDosTime(long t) {
+ byte[] result = new byte[4];
+ toDosTime(t, result, 0);
+ return result;
+ }
+
+ /**
+ * Convert a Date object to a DOS date/time field.
+ *
+ * <p>Stolen from InfoZip's <code>fileio.c</code></p>
+ * @param t number of milliseconds since the epoch
+ * @param buf the output buffer
+ * @param offset
+ * The offset within the output buffer of the first byte to be written.
+ * must be non-negative and no larger than <tt>buf.length-4</tt>
+ */
+ public static void toDosTime(long t, byte[] buf, int offset) {
+ toDosTime(Calendar.getInstance(), t, buf, offset);
+ }
+
+ static void toDosTime(Calendar c, long t, byte[] buf, int offset) {
+ c.setTimeInMillis(t);
+
+ int year = c.get(Calendar.YEAR);
+ if (year < 1980) {
+ System.arraycopy(DOS_TIME_MIN, 0, buf, offset, DOS_TIME_MIN.length);// stop callers from changing the array
+ return;
+ }
+ int month = c.get(Calendar.MONTH) + 1;
+ long value = ((year - 1980) << 25)
+ | (month << 21)
+ | (c.get(Calendar.DAY_OF_MONTH) << 16)
+ | (c.get(Calendar.HOUR_OF_DAY) << 11)
+ | (c.get(Calendar.MINUTE) << 5)
+ | (c.get(Calendar.SECOND) >> 1);
+ ZipLong.putLong(value, buf, offset);
+ }
+
+ /**
+ * Assumes a negative integer really is a positive integer that
+ * has wrapped around and re-creates the original value.
+ *
+ * <p>This methods is no longer used as of Apache Ant 1.9.0</p>
+ *
+ * @param i the value to treat as unsigned int.
+ * @return the unsigned int as a long.
+ */
+ public static long adjustToLong(int i) {
+ if (i < 0) {
+ return 2 * ((long) Integer.MAX_VALUE) + 2 + i;
+ } else {
+ return i;
+ }
+ }
+
+ /**
+ * Convert a DOS date/time field to a Date object.
+ *
+ * @param zipDosTime contains the stored DOS time.
+ * @return a Date instance corresponding to the given time.
+ */
+ public static Date fromDosTime(ZipLong zipDosTime) {
+ long dosTime = zipDosTime.getValue();
+ return new Date(dosToJavaTime(dosTime));
+ }
+
+ /**
+ * Converts DOS time to Java time (number of milliseconds since
+ * epoch).
+ */
+ public static long dosToJavaTime(long dosTime) {
+ Calendar cal = Calendar.getInstance();
+ // CheckStyle:MagicNumberCheck OFF - no point
+ cal.set(Calendar.YEAR, (int) ((dosTime >> 25) & 0x7f) + 1980);
+ cal.set(Calendar.MONTH, (int) ((dosTime >> 21) & 0x0f) - 1);
+ cal.set(Calendar.DATE, (int) (dosTime >> 16) & 0x1f);
+ cal.set(Calendar.HOUR_OF_DAY, (int) (dosTime >> 11) & 0x1f);
+ cal.set(Calendar.MINUTE, (int) (dosTime >> 5) & 0x3f);
+ cal.set(Calendar.SECOND, (int) (dosTime << 1) & 0x3e);
+ cal.set(Calendar.MILLISECOND, 0);
+ // CheckStyle:MagicNumberCheck ON
+ return cal.getTime().getTime();
+ }
+
+ /**
+ * If the entry has Unicode*ExtraFields and the CRCs of the
+ * names/comments match those of the extra fields, transfer the
+ * known Unicode values from the extra field.
+ */
+ static void setNameAndCommentFromExtraFields(ZipEntry ze,
+ byte[] originalNameBytes,
+ byte[] commentBytes) {
+ UnicodePathExtraField name = (UnicodePathExtraField)
+ ze.getExtraField(UnicodePathExtraField.UPATH_ID);
+ String originalName = ze.getName();
+ String newName = getUnicodeStringIfOriginalMatches(name,
+ originalNameBytes);
+ if (newName != null && !originalName.equals(newName)) {
+ ze.setName(newName);
+ }
+
+ if (commentBytes != null && commentBytes.length > 0) {
+ UnicodeCommentExtraField cmt = (UnicodeCommentExtraField)
+ ze.getExtraField(UnicodeCommentExtraField.UCOM_ID);
+ String newComment =
+ getUnicodeStringIfOriginalMatches(cmt, commentBytes);
+ if (newComment != null) {
+ ze.setComment(newComment);
+ }
+ }
+ }
+
+ /**
+ * If the stored CRC matches the one of the given name, return the
+ * Unicode name of the given field.
+ *
+ * <p>If the field is null or the CRCs don't match, return null
+ * instead.</p>
+ */
+ private static
+ String getUnicodeStringIfOriginalMatches(AbstractUnicodeExtraField f,
+ byte[] orig) {
+ if (f != null) {
+ CRC32 crc32 = new CRC32();
+ crc32.update(orig);
+ long origCRC32 = crc32.getValue();
+
+ if (origCRC32 == f.getNameCRC32()) {
+ try {
+ return ZipEncodingHelper
+ .UTF8_ZIP_ENCODING.decode(f.getUnicodeName());
+ } catch (IOException ex) {
+ // UTF-8 unsupported? should be impossible the
+ // Unicode*ExtraField must contain some bad bytes
+
+ // TODO log this anywhere?
+ return null;
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Create a copy of the given array - or return null if the
+ * argument is null.
+ */
+ static byte[] copy(byte[] from) {
+ if (from != null) {
+ byte[] to = new byte[from.length];
+ System.arraycopy(from, 0, to, 0, to.length);
+ return to;
+ }
+ return null;
+ }
+
+ /**
+ * Whether this library is able to read or write the given entry.
+ */
+ static boolean canHandleEntryData(ZipEntry entry) {
+ return supportsEncryptionOf(entry) && supportsMethodOf(entry);
+ }
+
+ /**
+ * Whether this library supports the encryption used by the given
+ * entry.
+ *
+ * @return true if the entry isn't encrypted at all
+ */
+ private static boolean supportsEncryptionOf(ZipEntry entry) {
+ return !entry.getGeneralPurposeBit().usesEncryption();
+ }
+
+ /**
+ * Whether this library supports the compression method used by
+ * the given entry.
+ *
+ * @return true if the compression method is STORED or DEFLATED
+ */
+ private static boolean supportsMethodOf(ZipEntry entry) {
+ return entry.getMethod() == ZipEntry.STORED
+ || entry.getMethod() == ZipEntry.DEFLATED;
+ }
+
+ /**
+ * Checks whether the entry requires features not (yet) supported
+ * by the library and throws an exception if it does.
+ */
+ static void checkRequestedFeatures(ZipEntry ze)
+ throws UnsupportedZipFeatureException {
+ if (!supportsEncryptionOf(ze)) {
+ throw
+ new UnsupportedZipFeatureException(UnsupportedZipFeatureException
+ .Feature.ENCRYPTION, ze);
+ }
+ if (!supportsMethodOf(ze)) {
+ throw
+ new UnsupportedZipFeatureException(UnsupportedZipFeatureException
+ .Feature.METHOD, ze);
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/resources/org/apache/tools/ant/taskdefs/javadoc-frame-injections-fix.txt b/framework/src/ant/apache-ant-1.9.6/src/resources/org/apache/tools/ant/taskdefs/javadoc-frame-injections-fix.txt
new file mode 100644
index 00000000..1f8c97a6
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/resources/org/apache/tools/ant/taskdefs/javadoc-frame-injections-fix.txt
@@ -0,0 +1,37 @@
+ if (targetPage != "" && !validURL(targetPage))
+ targetPage = "undefined";
+ function validURL(url) {
+ var pos = url.indexOf(".html");
+ if (pos == -1 || pos != url.length - 5)
+ return false;
+ var allowNumber = false;
+ var allowSep = false;
+ var seenDot = false;
+ for (var i = 0; i < url.length - 5; i++) {
+ var ch = url.charAt(i);
+ if ('a' <= ch && ch <= 'z' ||
+ 'A' <= ch && ch <= 'Z' ||
+ ch == '$' ||
+ ch == '_') {
+ allowNumber = true;
+ allowSep = true;
+ } else if ('0' <= ch && ch <= '9'
+ || ch == '-') {
+ if (!allowNumber)
+ return false;
+ } else if (ch == '/' || ch == '.') {
+ if (!allowSep)
+ return false;
+ allowNumber = false;
+ allowSep = false;
+ if (ch == '.')
+ seenDot = true;
+ if (ch == '/' && seenDot)
+ return false;
+ } else {
+ return false;
+ }
+ }
+ return true;
+ }
+ function loadFrames() {
diff --git a/framework/src/ant/apache-ant-1.9.6/src/resources/org/apache/tools/ant/types/resources/comparators/antlib.xml b/framework/src/ant/apache-ant-1.9.6/src/resources/org/apache/tools/ant/types/resources/comparators/antlib.xml
new file mode 100644
index 00000000..ae61b9dc
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/resources/org/apache/tools/ant/types/resources/comparators/antlib.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<antlib>
+ <typedef name="name"
+ classname="org.apache.tools.ant.types.resources.comparators.Name" />
+ <typedef name="size"
+ classname="org.apache.tools.ant.types.resources.comparators.Size" />
+ <typedef name="date"
+ classname="org.apache.tools.ant.types.resources.comparators.Date" />
+ <typedef name="exists"
+ classname="org.apache.tools.ant.types.resources.comparators.Exists" />
+ <typedef name="type"
+ classname="org.apache.tools.ant.types.resources.comparators.Type" />
+ <typedef name="content"
+ classname="org.apache.tools.ant.types.resources.comparators.Content" />
+ <typedef name="reverse"
+ classname="org.apache.tools.ant.types.resources.comparators.Reverse" />
+</antlib>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/resources/org/apache/tools/ant/types/resources/selectors/antlib.xml b/framework/src/ant/apache-ant-1.9.6/src/resources/org/apache/tools/ant/types/resources/selectors/antlib.xml
new file mode 100644
index 00000000..0d0e5024
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/resources/org/apache/tools/ant/types/resources/selectors/antlib.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<antlib>
+ <typedef name="and"
+ classname="org.apache.tools.ant.types.resources.selectors.And" />
+ <typedef name="compare"
+ classname="org.apache.tools.ant.types.resources.selectors.Compare" />
+ <typedef name="contains"
+ classname="org.apache.tools.ant.types.selectors.ContainsSelector" />
+ <typedef name="containsregexp"
+ classname="org.apache.tools.ant.types.selectors.ContainsRegexpSelector" />
+ <typedef name="date"
+ classname="org.apache.tools.ant.types.resources.selectors.Date" />
+ <typedef name="exists"
+ classname="org.apache.tools.ant.types.resources.selectors.Exists" />
+ <typedef name="instanceof"
+ classname="org.apache.tools.ant.types.resources.selectors.InstanceOf" />
+ <typedef name="majority"
+ classname="org.apache.tools.ant.types.resources.selectors.Majority" />
+ <typedef name="modified"
+ classname="org.apache.tools.ant.types.selectors.modifiedselector.ModifiedSelector" />
+ <typedef name="name"
+ classname="org.apache.tools.ant.types.resources.selectors.Name" />
+ <typedef name="none"
+ classname="org.apache.tools.ant.types.resources.selectors.None" />
+ <typedef name="not"
+ classname="org.apache.tools.ant.types.resources.selectors.Not" />
+ <typedef name="or"
+ classname="org.apache.tools.ant.types.resources.selectors.Or" />
+ <typedef name="readable"
+ classname="org.apache.tools.ant.types.selectors.ReadableSelector" />
+ <typedef name="size"
+ classname="org.apache.tools.ant.types.resources.selectors.Size" />
+ <typedef name="type"
+ classname="org.apache.tools.ant.types.resources.selectors.Type" />
+ <typedef name="writable"
+ classname="org.apache.tools.ant.types.selectors.WritableSelector" />
+</antlib>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/script/ant b/framework/src/ant/apache-ant-1.9.6/src/script/ant
new file mode 100644
index 00000000..b5ed5be6
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/script/ant
@@ -0,0 +1,336 @@
+#! /bin/sh
+
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Extract launch and ant arguments, (see details below).
+ant_exec_args=
+no_config=false
+use_jikes_default=false
+ant_exec_debug=false
+show_help=false
+for arg in "$@" ; do
+ if [ "$arg" = "--noconfig" ] ; then
+ no_config=true
+ elif [ "$arg" = "--usejikes" ] ; then
+ use_jikes_default=true
+ elif [ "$arg" = "--execdebug" ] ; then
+ ant_exec_debug=true
+ elif [ my"$arg" = my"--h" -o my"$arg" = my"--help" ] ; then
+ show_help=true
+ ant_exec_args="$ant_exec_args -h"
+ else
+ if [ my"$arg" = my"-h" -o my"$arg" = my"-help" ] ; then
+ show_help=true
+ fi
+ ant_exec_args="$ant_exec_args \"$arg\""
+ fi
+done
+
+# Source/default ant configuration
+if $no_config ; then
+ rpm_mode=false
+ usejikes=$use_jikes_default
+else
+ # load system-wide ant configuration (ONLY if ANT_HOME has NOT been set)
+ if [ -z "$ANT_HOME" -o "$ANT_HOME" = "/usr/share/ant" ]; then
+ if [ -f "/etc/ant.conf" ] ; then
+ . /etc/ant.conf
+ fi
+ fi
+
+ # load user ant configuration
+ if [ -f "$HOME/.ant/ant.conf" ] ; then
+ . $HOME/.ant/ant.conf
+ fi
+ if [ -f "$HOME/.antrc" ] ; then
+ . "$HOME/.antrc"
+ fi
+
+ # provide default configuration values
+ if [ -z "$rpm_mode" ] ; then
+ rpm_mode=false
+ fi
+ if [ -z "$usejikes" ] ; then
+ usejikes=$use_jikes_default
+ fi
+fi
+
+# Setup Java environment in rpm mode
+if $rpm_mode ; then
+ if [ -f /usr/share/java-utils/java-functions ] ; then
+ . /usr/share/java-utils/java-functions
+ set_jvm
+ set_javacmd
+ fi
+fi
+
+# OS specific support. $var _must_ be set to either true or false.
+cygwin=false;
+darwin=false;
+mingw=false;
+case "`uname`" in
+ CYGWIN*) cygwin=true ;;
+ Darwin*) darwin=true
+ if [ -z "$JAVA_HOME" ] ; then
+ if [ -x '/usr/libexec/java_home' ] ; then
+ JAVA_HOME=`/usr/libexec/java_home`
+ elif [ -d "/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home" ]; then
+ JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home
+ fi
+ fi
+ ;;
+ MINGW*) mingw=true ;;
+esac
+
+if [ -z "$ANT_HOME" -o ! -d "$ANT_HOME" ] ; then
+ ## resolve links - $0 may be a link to ant's home
+ PRG="$0"
+ progname=`basename "$0"`
+
+ # need this for relative symlinks
+ while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+ done
+
+ ANT_HOME=`dirname "$PRG"`/..
+
+ # make it fully qualified
+ ANT_HOME=`cd "$ANT_HOME" > /dev/null && pwd`
+fi
+
+# For Cygwin and Mingw, ensure paths are in UNIX format before
+# anything is touched
+if $cygwin ; then
+ [ -n "$ANT_HOME" ] &&
+ ANT_HOME=`cygpath --unix "$ANT_HOME"`
+ [ -n "$JAVA_HOME" ] &&
+ JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+if $mingw ; then
+ [ -n "$ANT_HOME" ] &&
+ ANT_HOME="`(cd "$ANT_HOME"; pwd)`"
+ [ -n "$JAVA_HOME" ] &&
+ JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
+fi
+
+# set ANT_LIB location
+ANT_LIB="${ANT_HOME}/lib"
+
+if [ -z "$JAVACMD" ] ; then
+ if [ -n "$JAVA_HOME" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ elif [ -x "$JAVA_HOME/jre/bin/java" ] ; then
+ JAVACMD="$JAVA_HOME/jre/bin/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ else
+ JAVACMD=`which java 2> /dev/null `
+ if [ -z "$JAVACMD" ] ; then
+ JAVACMD=java
+ fi
+ fi
+fi
+
+if [ ! -x "$JAVACMD" ] ; then
+ echo "Error: JAVA_HOME is not defined correctly."
+ echo " We cannot execute $JAVACMD"
+ exit 1
+fi
+
+# Build local classpath using just the launcher in non-rpm mode or
+# use the Jpackage helper in rpm mode with basic and default jars
+# specified in the ant.conf configuration. Because the launcher is
+# used, libraries linked in ANT_HOME/lib will also be included, but this
+# is discouraged as it is not java-version safe. A user should
+# request optional jars and their dependencies via the OPT_JAR_LIST
+# variable
+if $rpm_mode && [ -x /usr/bin/build-classpath ] ; then
+ LOCALCLASSPATH="$(/usr/bin/build-classpath ant ant-launcher jaxp_parser_impl xml-commons-apis)"
+
+ # If no optional jars have been specified then build the default list
+ if [ -z "$OPT_JAR_LIST" ] ; then
+ for file in /etc/ant.d/*; do
+ if [ -f "$file" ]; then
+ case "$file" in
+ *~) ;;
+ *#*) ;;
+ *.rpmsave) ;;
+ *.rpmnew) ;;
+ *)
+ for dep in `cat "$file"`; do
+ OPT_JAR_LIST="$OPT_JAR_LIST${OPT_JAR_LIST:+ }$dep"
+ done
+ esac
+ fi
+ done
+ fi
+
+ # If the user requested to try to add some other jars to the classpath
+ if [ -n "$OPT_JAR_LIST" ] ; then
+ _OPTCLASSPATH="$(/usr/bin/build-classpath $OPT_JAR_LIST 2> /dev/null)"
+ if [ -n "$_OPTCLASSPATH" ] ; then
+ LOCALCLASSPATH="$LOCALCLASSPATH:$_OPTCLASSPATH"
+ fi
+ fi
+
+ # Explicitly add javac path to classpath, assume JAVA_HOME set
+ # properly in rpm mode
+ if [ -f "$JAVA_HOME/lib/tools.jar" ] ; then
+ LOCALCLASSPATH="$LOCALCLASSPATH:$JAVA_HOME/lib/tools.jar"
+ fi
+ if [ -f "$JAVA_HOME/lib/classes.zip" ] ; then
+ LOCALCLASSPATH="$LOCALCLASSPATH:$JAVA_HOME/lib/classes.zip"
+ fi
+
+ # if CLASSPATH_OVERRIDE env var is set, LOCALCLASSPATH will be
+ # user CLASSPATH first and ant-found jars after.
+ # In that case, the user CLASSPATH will override ant-found jars
+ #
+ # if CLASSPATH_OVERRIDE is not set, we'll have the normal behaviour
+ # with ant-found jars first and user CLASSPATH after
+ if [ -n "$CLASSPATH" ] ; then
+ # merge local and specified classpath
+ if [ -z "$LOCALCLASSPATH" ] ; then
+ LOCALCLASSPATH="$CLASSPATH"
+ elif [ -n "$CLASSPATH_OVERRIDE" ] ; then
+ LOCALCLASSPATH="$CLASSPATH:$LOCALCLASSPATH"
+ else
+ LOCALCLASSPATH="$LOCALCLASSPATH:$CLASSPATH"
+ fi
+
+ # remove class path from launcher -cp option
+ CLASSPATH=""
+ fi
+else
+ # not using rpm_mode; use launcher to determine classpaths
+ if [ -z "$LOCALCLASSPATH" ] ; then
+ LOCALCLASSPATH=$ANT_LIB/ant-launcher.jar
+ else
+ LOCALCLASSPATH=$ANT_LIB/ant-launcher.jar:$LOCALCLASSPATH
+ fi
+fi
+
+if [ -n "$JAVA_HOME" ] ; then
+ # OSX hack to make Ant work with jikes
+ if $darwin ; then
+ OSXHACK="${JAVA_HOME}/../Classes"
+ if [ -d "${OSXHACK}" ] ; then
+ for i in "${OSXHACK}"/*.jar
+ do
+ JIKESPATH="$JIKESPATH:$i"
+ done
+ fi
+ fi
+fi
+
+# Allow Jikes support (off by default)
+if $usejikes; then
+ ANT_OPTS="$ANT_OPTS -Dbuild.compiler=jikes"
+fi
+
+# For Cygwin, switch paths to appropriate format before running java
+# For PATHs convert to unix format first, then to windows format to ensure
+# both formats are supported. Probably this will fail on directories with ;
+# in the name in the path. Let's assume that paths containing ; are more
+# rare than windows style paths on cygwin.
+if $cygwin; then
+ if [ "$OS" = "Windows_NT" ] && cygpath -m .>/dev/null 2>/dev/null ; then
+ format=mixed
+ else
+ format=windows
+ fi
+ [ -n "$ANT_HOME" ] && ANT_HOME=`cygpath --$format "$ANT_HOME"`
+ ANT_LIB=`cygpath --$format "$ANT_LIB"`
+ [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --$format "$JAVA_HOME"`
+ LCP_TEMP=`cygpath --path --unix "$LOCALCLASSPATH"`
+ LOCALCLASSPATH=`cygpath --path --$format "$LCP_TEMP"`
+ if [ -n "$CLASSPATH" ] ; then
+ CP_TEMP=`cygpath --path --unix "$CLASSPATH"`
+ CLASSPATH=`cygpath --path --$format "$CP_TEMP"`
+ fi
+ CYGHOME=`cygpath --$format "$HOME"`
+fi
+
+# Show script help if requested
+if $show_help ; then
+ echo $0 '[script options] [options] [target [target2 [target3] ..]]'
+ echo 'Script Options:'
+ echo ' --help, --h print this message and ant help'
+ echo ' --noconfig suppress sourcing of /etc/ant.conf,'
+ echo ' $HOME/.ant/ant.conf, and $HOME/.antrc'
+ echo ' configuration files'
+ echo ' --usejikes enable use of jikes by default, unless'
+ echo ' set explicitly in configuration files'
+ echo ' --execdebug print ant exec line generated by this'
+ echo ' launch script'
+ echo ' '
+fi
+# add a second backslash to variables terminated by a backslash under cygwin
+if $cygwin; then
+ case "$ANT_HOME" in
+ *\\ )
+ ANT_HOME="$ANT_HOME\\"
+ ;;
+ esac
+ case "$CYGHOME" in
+ *\\ )
+ CYGHOME="$CYGHOME\\"
+ ;;
+ esac
+ case "$JIKESPATH" in
+ *\\ )
+ JIKESPATH="$JIKESPATH\\"
+ ;;
+ esac
+ case "$LOCALCLASSPATH" in
+ *\\ )
+ LOCALCLASSPATH="$LOCALCLASSPATH\\"
+ ;;
+ esac
+ case "$CLASSPATH" in
+ *\\ )
+ CLASSPATH="$CLASSPATH\\"
+ ;;
+ esac
+fi
+# Execute ant using eval/exec to preserve spaces in paths,
+# java options, and ant args
+ant_sys_opts=
+if [ -n "$CYGHOME" ]; then
+ if [ -n "$JIKESPATH" ]; then
+ ant_sys_opts="-Djikes.class.path=\"$JIKESPATH\" -Dcygwin.user.home=\"$CYGHOME\""
+ else
+ ant_sys_opts="-Dcygwin.user.home=\"$CYGHOME\""
+ fi
+else
+ if [ -n "$JIKESPATH" ]; then
+ ant_sys_opts="-Djikes.class.path=\"$JIKESPATH\""
+ fi
+fi
+ant_exec_command="exec \"$JAVACMD\" $ANT_OPTS -classpath \"$LOCALCLASSPATH\" -Dant.home=\"$ANT_HOME\" -Dant.library.dir=\"$ANT_LIB\" $ant_sys_opts org.apache.tools.ant.launch.Launcher $ANT_ARGS -cp \"$CLASSPATH\""
+if $ant_exec_debug ; then
+ echo $ant_exec_command $ant_exec_args
+fi
+eval $ant_exec_command "$ant_exec_args"
diff --git a/framework/src/ant/apache-ant-1.9.6/src/script/ant.bat b/framework/src/ant/apache-ant-1.9.6/src/script/ant.bat
new file mode 100644
index 00000000..9f18b82a
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/script/ant.bat
@@ -0,0 +1,218 @@
+@echo off
+
+REM Licensed to the Apache Software Foundation (ASF) under one or more
+REM contributor license agreements. See the NOTICE file distributed with
+REM this work for additional information regarding copyright ownership.
+REM The ASF licenses this file to You under the Apache License, Version 2.0
+REM (the "License"); you may not use this file except in compliance with
+REM the License. You may obtain a copy of the License at
+REM
+REM http://www.apache.org/licenses/LICENSE-2.0
+REM
+REM Unless required by applicable law or agreed to in writing, software
+REM distributed under the License is distributed on an "AS IS" BASIS,
+REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+REM See the License for the specific language governing permissions and
+REM limitations under the License.
+
+REM This is an inordinately troublesome piece of code, particularly because it
+REM tries to work on both Win9x and WinNT-based systems. If we could abandon '9x
+REM support, things would be much easier, but sadly, it is not yet time.
+REM Be cautious about editing this, and only add WinNT specific stuff in code that
+REM only runs on WinNT.
+
+if "%HOME%"=="" goto homeDrivePathPre
+if exist "%HOME%\antrc_pre.bat" call "%HOME%\antrc_pre.bat"
+
+:homeDrivePathPre
+if "%HOMEDRIVE%%HOMEPATH%"=="" goto userProfilePre
+if "%HOMEDRIVE%%HOMEPATH%"=="%HOME%" goto userProfilePre
+if exist "%HOMEDRIVE%%HOMEPATH%\antrc_pre.bat" call "%HOMEDRIVE%%HOMEPATH%\antrc_pre.bat"
+
+:userProfilePre
+if "%USERPROFILE%"=="" goto alpha
+if "%USERPROFILE%"=="%HOME%" goto alpha
+if "%USERPROFILE%"=="%HOMEDRIVE%%HOMEPATH%" goto alpha
+if exist "%USERPROFILE%\antrc_pre.bat" call "%USERPROFILE%\antrc_pre.bat"
+
+:alpha
+
+if "%OS%"=="Windows_NT" @setlocal
+if "%OS%"=="WINNT" @setlocal
+
+if "%ANT_HOME%"=="" goto setDefaultAntHome
+
+:stripAntHome
+if not _%ANT_HOME:~-1%==_\ goto checkClasspath
+set ANT_HOME=%ANT_HOME:~0,-1%
+goto stripAntHome
+
+:setDefaultAntHome
+rem %~dp0 is expanded pathname of the current script under NT
+set ANT_HOME=%~dp0..
+
+:checkClasspath
+set _USE_CLASSPATH=yes
+rem CLASSPATH must not be used if it is equal to ""
+if "%CLASSPATH%"=="""" set _USE_CLASSPATH=no
+if "%CLASSPATH%"=="" set _USE_CLASSPATH=no
+
+rem Slurp the command line arguments. This loop allows for an unlimited number
+rem of arguments (up to the command line limit, anyway).
+set ANT_CMD_LINE_ARGS=
+:setupArgs
+if ""%1""=="""" goto doneStart
+if ""%1""==""-noclasspath"" goto clearclasspath
+set ANT_CMD_LINE_ARGS=%ANT_CMD_LINE_ARGS% %1
+shift
+goto setupArgs
+
+rem here is there is a -noclasspath in the options
+:clearclasspath
+set _USE_CLASSPATH=no
+shift
+goto setupArgs
+
+rem This label provides a place for the argument list loop to break out
+rem and for NT handling to skip to.
+
+:doneStart
+
+if "%_USE_CLASSPATH%"=="no" goto findAntHome
+
+:stripClasspath
+if not _%CLASSPATH:~-1%==_\ goto findAntHome
+set CLASSPATH=%CLASSPATH:~0,-1%
+goto stripClasspath
+
+:findAntHome
+rem find ANT_HOME if it does not exist due to either an invalid value passed
+rem by the user or the %0 problem on Windows 9x
+if exist "%ANT_HOME%\lib\ant.jar" goto checkJava
+
+rem check for ant in Program Files
+if not exist "%ProgramFiles%\ant" goto checkSystemDrive
+set ANT_HOME=%ProgramFiles%\ant
+goto checkJava
+
+:checkSystemDrive
+rem check for ant in root directory of system drive
+if not exist %SystemDrive%\ant\lib\ant.jar goto checkCDrive
+set ANT_HOME=%SystemDrive%\ant
+goto checkJava
+
+:checkCDrive
+rem check for ant in C:\ant for Win9X users
+if not exist C:\ant\lib\ant.jar goto noAntHome
+set ANT_HOME=C:\ant
+goto checkJava
+
+:noAntHome
+echo ANT_HOME is set incorrectly or ant could not be located. Please set ANT_HOME.
+goto end
+
+:checkJava
+set _JAVACMD=%JAVACMD%
+
+if "%JAVA_HOME%" == "" goto noJavaHome
+if not exist "%JAVA_HOME%\bin\java.exe" goto noJavaHome
+if "%_JAVACMD%" == "" set _JAVACMD=%JAVA_HOME%\bin\java.exe
+goto checkJikes
+
+:noJavaHome
+if "%_JAVACMD%" == "" set _JAVACMD=java.exe
+
+:checkJikes
+if not "%JIKESPATH%"=="" goto runAntWithJikes
+
+:runAnt
+if "%_USE_CLASSPATH%"=="no" goto runAntNoClasspath
+:runAntWithClasspath
+"%_JAVACMD%" %ANT_OPTS% -classpath "%ANT_HOME%\lib\ant-launcher.jar" "-Dant.home=%ANT_HOME%" org.apache.tools.ant.launch.Launcher %ANT_ARGS% -cp "%CLASSPATH%" %ANT_CMD_LINE_ARGS%
+rem Check the error code of the Ant build
+if not "%OS%"=="Windows_NT" goto onError
+set ANT_ERROR=%ERRORLEVEL%
+goto end
+
+:runAntNoClasspath
+"%_JAVACMD%" %ANT_OPTS% -classpath "%ANT_HOME%\lib\ant-launcher.jar" "-Dant.home=%ANT_HOME%" org.apache.tools.ant.launch.Launcher %ANT_ARGS% %ANT_CMD_LINE_ARGS%
+rem Check the error code of the Ant build
+if not "%OS%"=="Windows_NT" goto onError
+set ANT_ERROR=%ERRORLEVEL%
+goto end
+
+:runAntWithJikes
+
+if not _%JIKESPATH:~-1%==_\ goto checkJikesAndClasspath
+set JIKESPATH=%JIKESPATH:~0,-1%
+goto runAntWithJikes
+
+:checkJikesAndClasspath
+
+if "%_USE_CLASSPATH%"=="no" goto runAntWithJikesNoClasspath
+
+:runAntWithJikesAndClasspath
+"%_JAVACMD%" %ANT_OPTS% -classpath "%ANT_HOME%\lib\ant-launcher.jar" "-Dant.home=%ANT_HOME%" "-Djikes.class.path=%JIKESPATH%" org.apache.tools.ant.launch.Launcher %ANT_ARGS% -cp "%CLASSPATH%" %ANT_CMD_LINE_ARGS%
+rem Check the error code of the Ant build
+if not "%OS%"=="Windows_NT" goto onError
+set ANT_ERROR=%ERRORLEVEL%
+goto end
+
+:runAntWithJikesNoClasspath
+"%_JAVACMD%" %ANT_OPTS% -classpath "%ANT_HOME%\lib\ant-launcher.jar" "-Dant.home=%ANT_HOME%" "-Djikes.class.path=%JIKESPATH%" org.apache.tools.ant.launch.Launcher %ANT_ARGS% %ANT_CMD_LINE_ARGS%
+rem Check the error code of the Ant build
+if not "%OS%"=="Windows_NT" goto onError
+set ANT_ERROR=%ERRORLEVEL%
+goto end
+
+:onError
+rem Windows 9x way of checking the error code. It matches via brute force.
+for %%i in (1 10 100) do set err%%i=
+for %%i in (0 1 2) do if errorlevel %%i00 set err100=%%i
+if %err100%==2 goto onError200
+if %err100%==0 set err100=
+for %%i in (0 1 2 3 4 5 6 7 8 9) do if errorlevel %err100%%%i0 set err10=%%i
+if "%err100%"=="" if %err10%==0 set err10=
+:onError1
+for %%i in (0 1 2 3 4 5 6 7 8 9) do if errorlevel %err100%%err10%%%i set err1=%%i
+goto onErrorEnd
+:onError200
+for %%i in (0 1 2 3 4 5) do if errorlevel 2%%i0 set err10=%%i
+if err10==5 for %%i in (0 1 2 3 4 5) do if errorlevel 25%%i set err1=%%i
+if not err10==5 goto onError1
+:onErrorEnd
+set ANT_ERROR=%err100%%err10%%err1%
+for %%i in (1 10 100) do set err%%i=
+
+:end
+rem bug ID 32069: resetting an undefined env variable changes the errorlevel.
+if not "%_JAVACMD%"=="" set _JAVACMD=
+if not "%_ANT_CMD_LINE_ARGS%"=="" set ANT_CMD_LINE_ARGS=
+
+if "%ANT_ERROR%"=="0" goto mainEnd
+
+goto omega
+
+:mainEnd
+
+rem If there were no errors, we run the post script.
+if "%OS%"=="Windows_NT" @endlocal
+if "%OS%"=="WINNT" @endlocal
+
+if "%HOME%"=="" goto homeDrivePathPost
+if exist "%HOME%\antrc_post.bat" call "%HOME%\antrc_post.bat"
+
+:homeDrivePathPost
+if "%HOMEDRIVE%%HOMEPATH%"=="" goto userProfilePost
+if "%HOMEDRIVE%%HOMEPATH%"=="%HOME%" goto userProfilePost
+if exist "%HOMEDRIVE%%HOMEPATH%\antrc_post.bat" call "%HOMEDRIVE%%HOMEPATH%\antrc_post.bat"
+
+:userProfilePost
+if "%USERPROFILE%"=="" goto omega
+if "%USERPROFILE%"=="%HOME%" goto omega
+if "%USERPROFILE%"=="%HOMEDRIVE%%HOMEPATH%" goto omega
+if exist "%USERPROFILE%\antrc_post.bat" call "%USERPROFILE%\antrc_post.bat"
+
+:omega
+
+exit /b %ANT_ERROR%
diff --git a/framework/src/ant/apache-ant-1.9.6/src/script/ant.cmd b/framework/src/ant/apache-ant-1.9.6/src/script/ant.cmd
new file mode 100644
index 00000000..70665c00
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/script/ant.cmd
@@ -0,0 +1,93 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+ Run ant
+*/
+
+'@echo off'
+parse arg mode envarg '::' antarg
+
+if mode\='.' & mode\='..' & mode\='/' then do
+ envarg = mode envarg
+ mode = ''
+end
+
+if antarg = '' then do
+ antarg = envarg
+ envarg = ''
+end
+
+x = setlocal()
+
+env="OS2ENVIRONMENT"
+antenv = _getenv_('antenv')
+if _testenv_() = 0 then interpret 'call "' || antenv || '"' '"' || envarg || '"'
+
+if mode = '' then mode = _getenv_('ANT_MODE' '..')
+if mode \= '/' then do
+ runrc = _getenv_('runrc')
+ antrc = _getenv_('antrc' 'antrc.cmd')
+ if mode = '..' then mode = '-r'
+ else mode = ''
+ interpret 'call "' || runrc || '"' antrc '"' || mode || '"'
+end
+
+if _testenv_() = 0 then do
+ say 'Ant environment is not set properly'
+ x = endlocal()
+ exit 16
+end
+
+settings = '-Dant.home=' || ANT_HOME '-Djava.home=' || JAVA_HOME
+
+java = _getenv_('javacmd' 'java')
+opts = value('ANT_OPTS',,env)
+args = value('ANT_ARGS',,env)
+lcp = value('LOCALCLASSPATH',,env)
+cp = value('CLASSPATH',,env)
+if value('ANT_USE_CP',,env) \= '' then do
+ if lcp \= '' & right(lcp, 1) \= ';' then lcp = lcp || ';'
+ lcp = lcp || cp
+ 'SET CLASSPATH='
+end
+if lcp\='' then lcp = '-classpath' lcp
+
+cmd = java opts lcp '-jar' ANT_HOME ||'\lib\ant-launcher.jar' settings args antarg
+launcher = stream(ANT_HOME ||'\lib\ant-launcher.jar', 'C', 'query exists')
+if launcher = '' then entry = 'org.apache.tools.ant.Main'
+else entry = 'org.apache.tools.ant.launch.Launcher'
+java opts lcp entry settings args antarg
+
+x = endlocal()
+
+return rc
+
+_testenv_: procedure expose env ANT_HOME JAVA_HOME
+ANT_HOME = value('ANT_HOME',,env)
+if ANT_HOME = '' then return 0
+JAVA_HOME = value('JAVA_HOME',,env)
+if JAVA_HOME = '' then return 0
+cp = translate(value('CLASSPATH',,env))
+if pos(translate(ANT_HOME), cp) = 0 then return 0
+if pos(translate(JAVA_HOME), cp) = 0 then return 0
+return 1
+
+_getenv_: procedure expose env
+parse arg envar default
+if default = '' then default = envar
+var = value(translate(envar),,env)
+if var = '' then var = default
+return var
diff --git a/framework/src/ant/apache-ant-1.9.6/src/script/antRun b/framework/src/ant/apache-ant-1.9.6/src/script/antRun
new file mode 100644
index 00000000..8110f86e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/script/antRun
@@ -0,0 +1,24 @@
+#! /bin/sh
+
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Args: DIR command
+cd "$1"
+CMD="$2"
+shift
+shift
+
+exec "$CMD" "$@"
diff --git a/framework/src/ant/apache-ant-1.9.6/src/script/antRun.bat b/framework/src/ant/apache-ant-1.9.6/src/script/antRun.bat
new file mode 100644
index 00000000..c7d90f03
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/script/antRun.bat
@@ -0,0 +1,50 @@
+@echo off
+
+REM Licensed to the Apache Software Foundation (ASF) under one or more
+REM contributor license agreements. See the NOTICE file distributed with
+REM this work for additional information regarding copyright ownership.
+REM The ASF licenses this file to You under the Apache License, Version 2.0
+REM (the "License"); you may not use this file except in compliance with
+REM the License. You may obtain a copy of the License at
+REM
+REM http://www.apache.org/licenses/LICENSE-2.0
+REM
+REM Unless required by applicable law or agreed to in writing, software
+REM distributed under the License is distributed on an "AS IS" BASIS,
+REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+REM See the License for the specific language governing permissions and
+REM limitations under the License.
+
+if "%OS%"=="Windows_NT" @setlocal
+if "%OS%"=="WINNT" @setlocal
+
+if ""%1""=="""" goto runCommand
+
+rem Change drive and directory to %1
+if "%OS%"=="Windows_NT" goto nt_cd
+if "%OS%"=="WINNT" goto nt_cd
+cd ""%1""
+goto end_cd
+:nt_cd
+cd /d ""%1""
+:end_cd
+shift
+
+rem Slurp the command line arguments. This loop allows for an unlimited number
+rem of arguments (up to the command line limit, anyway).
+set ANT_RUN_CMD=%1
+if ""%1""=="""" goto runCommand
+shift
+:loop
+if ""%1""=="""" goto runCommand
+set ANT_RUN_CMD=%ANT_RUN_CMD% %1
+shift
+goto loop
+
+:runCommand
+rem echo %ANT_RUN_CMD%
+%ANT_RUN_CMD%
+
+if "%OS%"=="Windows_NT" @endlocal
+if "%OS%"=="WINNT" @endlocal
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/script/antRun.pl b/framework/src/ant/apache-ant-1.9.6/src/script/antRun.pl
new file mode 100644
index 00000000..0bc5cc5e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/script/antRun.pl
@@ -0,0 +1,63 @@
+#!/usr/bin/perl
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+#######################################################################
+#
+# antRun.pl
+#
+# wrapper script for invoking commands on a platform with Perl installed
+# this is akin to antRun.bat, and antRun the SH script
+#######################################################################
+#be fussy about variables
+use strict;
+
+#turn warnings on during dev; generates a few spurious uninitialised var access warnings
+#use warnings;
+
+#and set $debug to 1 to turn on trace info (currently unused)
+my $debug=1;
+
+#######################################################################
+# change drive and directory to "%1"
+my $ANT_RUN_CMD = @ARGV[0];
+
+# assign current run command to "%2"
+chdir (@ARGV[0]) || die "Can't cd to $ARGV[0]: $!\n";
+if ($^O eq "NetWare") {
+ # There is a bug in Perl 5 on NetWare, where chdir does not
+ # do anything. On NetWare, the following path-prefixed form should
+ # always work. (afaict)
+ $ANT_RUN_CMD .= "/".@ARGV[1];
+}
+else {
+ $ANT_RUN_CMD = @ARGV[1];
+}
+
+# dispose of the first two arguments, leaving only the command's args.
+shift;
+shift;
+
+# run the command
+my $returnValue = system $ANT_RUN_CMD, @ARGV;
+if ($returnValue eq 0) {
+ exit 0;
+}
+else {
+ # only 0 and 1 are widely recognized as exit values
+ # so change the exit value to 1
+ exit 1;
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/script/antenv.cmd b/framework/src/ant/apache-ant-1.9.6/src/script/antenv.cmd
new file mode 100644
index 00000000..04602665
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/script/antenv.cmd
@@ -0,0 +1,98 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+'@echo off'
+call RxFuncAdd "SysLoadFuncs", "RexxUtil", "SysLoadFuncs"
+call SysLoadFuncs
+
+/* Prepare the parameters for later use */
+parse arg argv
+mode = ''
+args = ''
+opts = ''
+cp = ''
+lcp = ''
+
+do i = 1 to words(argv)
+ param = word(argv, i)
+ select
+ when param='-lcp' then mode = 'l'
+ when param='-cp' | param='-classpath' then mode = 'c'
+ when abbrev('-opts', param, 4) then mode = 'o'
+ when abbrev('-args', param, 4) then mode = 'a'
+ otherwise
+ select
+ when mode = 'a' then args = space(args param, 1)
+ when mode = 'c' then cp = space(cp param, 1)
+ when mode = 'l' then lcp = space(lcp param, 1)
+ when mode = 'o' then opts = space(opts param, 1)
+ otherwise
+ say 'Option' param 'ignored'
+ end
+ end
+end
+
+env="OS2ENVIRONMENT"
+antconf = _getenv_('antconf' 'antconf.cmd')
+runrc = _getenv_('runrc')
+interpret 'call "' || runrc || '"' '"' || antconf || '"' 'ETC'
+ANT_HOME = value('ANT_HOME',,env)
+JAVA_HOME = value('JAVA_HOME',,env)
+classpath = value('CLASSPATH',,env)
+classes = stream(JAVA_HOME || "\lib\classes.zip", "C", "QUERY EXISTS")
+if classes \= '' then classpath = prepend(classpath classes)
+classes = stream(JAVA_HOME || "\lib\tools.jar", "C", "QUERY EXISTS")
+if classes \= '' then classpath = prepend(classpath classes)
+
+classpath = prepend(classpath ANT_HOME || '\lib\ant-launcher.jar')
+'SET CLASSPATH=' || classpath
+
+/* Setting classpathes, options and arguments */
+envset = _getenv_('envset')
+if cp\='' then interpret 'call "' || envset || '"' '"; CLASSPATH"' '"' || cp || '"'
+if lcp\='' then interpret 'call "' || envset || '"' '"; LOCALCLASSPATH"' '"' || lcp || '"'
+if opts\='' then interpret 'call "' || envset || '"' '"-D ANT_OPTS"' '"' || opts || '"'
+if args\='' then interpret 'call "' || envset || '"' '"ANT_ARGS"' '"' || args || '"'
+
+exit 0
+
+addpath: procedure
+parse arg path elem
+if elem = '' then do
+ if path\='' & right(path, 1)\=';' then path = path || ';'
+ return path
+end
+if substr(path, length(path)) = ';' then glue = ''
+else glue = ';'
+if pos(translate(elem), translate(path)) = 0 then path = path || glue || elem || ';'
+return path
+
+prepend: procedure
+parse arg path elem
+if elem = '' then do
+ if path\='' & right(path, 1)\=';' then path = path || ';'
+ return path
+end
+if pos(translate(elem), translate(path)) = 0 then path = elem || ';' || path
+return path
+
+_getenv_: procedure expose env
+parse arg envar default
+if default = '' then default = envar
+var = value(translate(envar),,env)
+if var = '' then var = default
+return var
diff --git a/framework/src/ant/apache-ant-1.9.6/src/script/complete-ant-cmd.pl b/framework/src/ant/apache-ant-1.9.6/src/script/complete-ant-cmd.pl
new file mode 100644
index 00000000..40c5a9ad
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/script/complete-ant-cmd.pl
@@ -0,0 +1,115 @@
+#!/usr/bin/perl
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# A script to allow Bash or Z-Shell to complete an Ant command-line.
+#
+# To install for Bash 2.0 or better, add the following to ~/.bashrc:
+#
+# complete -C complete-ant-cmd.pl ant build.sh
+#
+# To install for Z-Shell 2.5 or better, add the following to ~/.zshrc:
+#
+# function ant_complete () {
+# local args_line args
+# read -l args_line
+# set -A args $args_line
+# set -A reply $(COMP_LINE=$args_line complete-ant-cmd.pl ${args[1]} $1)
+# }
+# compctl -K ant_complete ant build.sh
+
+my $cmdLine = "$ENV{'ANT_ARGS'} $ENV{'COMP_LINE'}";
+my $antCmd = $ARGV[0];
+my $word = $ARGV[1];
+
+my @completions;
+if ($word =~ /^-/) {
+ list( restrict( $word, getArguments() ));
+} elsif ($cmdLine =~ /-(f|file|buildfile)\s+\S*$/) {
+ list( getBuildFiles($word) );
+} else {
+ list( restrict( $word, getTargets() ));
+}
+
+exit(0);
+
+sub list {
+ for (@_) {
+ print "$_\n";
+ }
+}
+
+sub restrict {
+ my ($word, @completions) = @_;
+ grep( /^\Q$word\E/, @completions );
+}
+
+sub getArguments {
+ qw(-buildfile -debug -emacs -f -file -find -help -listener -logfile
+ -logger -projecthelp -quiet -verbose -version);
+}
+
+
+sub getBuildFiles {
+ my ($word) = @_;
+ grep( /\.xml$/, glob( "$word*" ));
+}
+
+sub getTargets {
+
+ # Look for build-file
+ my $buildFile = 'build.xml';
+ if ($cmdLine =~ /-(f|file|buildfile)\s+(\S+)(?!.*\s-(f|file|buildfile)\s)/) {
+ $buildFile = $2;
+ }
+ return () unless (-f $buildFile);
+
+ # Run "ant -projecthelp -debug" to list targets (-debug is required to get
+ # "Other targets", i.e. targets without a description). Keep a cache of
+ # results in a cache-file.
+ my $cacheFile = $buildFile;
+ $cacheFile =~ s|(.*/)?(.*)|${1}.ant-targets-${2}|;
+ if ((!-e $cacheFile) || (-z $cacheFile) || (-M $buildFile) < (-M $cacheFile)) {
+ open( CACHE, '>'.$cacheFile ) || die "can\'t write $cacheFile: $!\n";
+ open( HELP, "$antCmd -projecthelp -debug -buildfile '$buildFile'|" ) || return();
+ my %targets;
+ while( <HELP> ) {
+ # Exclude target names starting with dash, because they cannot be
+ # specified on the command line.
+ if (/^\s+\+Target:\s+(?!-)(\S+)/) {
+ $targets{$1}++;
+ }
+ }
+ my @targets = sort keys %targets;
+ for (@targets) { print CACHE "$_\n"; }
+ return @targets;
+ }
+
+ # Read the target-cache
+ open( CACHE, $cacheFile ) || die "can\'t read $cacheFile: $!\n";
+ my @targets;
+ while (<CACHE>) {
+ chop;
+ s/\r$//; # for Cygwin
+ push( @targets, $_ );
+ }
+ close( CACHE );
+ @targets;
+
+}
+
+
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/script/envset.cmd b/framework/src/ant/apache-ant-1.9.6/src/script/envset.cmd
new file mode 100644
index 00000000..3149be4c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/script/envset.cmd
@@ -0,0 +1,131 @@
+/*
+
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+SET environment variables
+First optional parameter:
+ ; parameters are considered parts of a path variable, semicolons are
+ appended to each element if not already present
+ -D parameters are properties for Java or Makefile etc., -D will be
+ prepended and the parameters will be separated by a space
+ =D the same as above but equal sign is not required
+ , parameters should be comma separated in the environment variable
+ - parameters should be separated by the next parameter
+ Other values mean that the first parameter is missing and the environment
+ variable will be set to the space separated parameters
+
+Second parameter: name of the environment variable
+
+Next parameters: values
+; implies that the equal sign is considered a part of the parameter and is
+not interpreted
+
+-D requires parameters in the form name=value. If the equal sign is not found,
+the parameters are changed to name=expanded_name
+
+Other options have optional equal sign. If it is found, only the part after
+the equal sign will be oprionally expanded.
+
+If the parameter is the minus sign, the next parameter will not be expanded.
+If the parameter is a single dot, it will be replaced with the value of the
+environment variable as it existed before envset was invoked.
+
+For other parameters the batch looks for the environment variable with the
+same name (in uppercase). If it is found, it forms the expanded_name. If
+the environment variable with such a name does not exist, the expanded_name
+will hold the parameter name without case conversion.
+*/
+
+parse arg mode envar args
+
+equal = 0
+sep = ' '
+
+/* Parse command line parameters */
+select
+ when mode='-' then do
+ sep = envar
+ parse var args envar args
+ end
+ when mode=';' then do
+ sep = ''
+ equal = -1
+ end
+ when mode='-D' then equal = 1
+ when mode='=D' then mode = '-D'
+ when mode=',' then sep = ','
+otherwise
+ args = envar args
+ envar = mode
+ mode = ''
+end
+
+env = 'OS2ENVIRONMENT'
+envar = translate(envar)
+orig = value(envar,,env)
+newval = ''
+expand = 1
+
+/* for each parameter... */
+do i = 1 to words(args)
+ if expand > 0 & word(args, i) = '-' then expand = 0
+ else call addval word(args, i)
+end
+
+/* Optionally enclose path variable by quotes */
+if mode = ';' & pos(' ', newval) > 0 then newval = '"' || newval || '"'
+
+/* Set the new value, 'SET' cannot be used since it does not allow '=' */
+x = value(envar, newval, env)
+exit 0
+
+addval: procedure expose sep equal orig expand newval mode env
+parse arg var
+
+if var = '.' then expvar = orig
+else do
+ if equal >= 0 then do
+ parse var var name '=' val
+ if val = '' then var = name
+ else var = val
+ end
+ if expand = 0 then expvar = var
+ else expvar = value(translate(var),,env)
+ if expvar = '' then expvar = var
+ if equal >= 0 then do
+ if val = '' then do
+ parse var expvar key '=' val
+ if val <> '' then name = key
+ else do
+ if equal > 0 then val = key
+ else name = key
+ end
+ end
+ else val = expvar
+ if pos(' ', val) > 0 | pos('=', val) > 0 then val = '"' || val || '"'
+ if val = '' then expvar = name
+ else expvar = name || '=' || val
+ end
+ if mode = '-D' then expvar = '-D' || expvar
+ if mode = ';' then do
+ if right(expvar, 1) <> ';' then expvar = expvar || ';'
+ end
+end
+
+if newval = '' then newval = expvar
+else newval = newval || sep || expvar
+expand = 1
+return
diff --git a/framework/src/ant/apache-ant-1.9.6/src/script/lcp.bat b/framework/src/ant/apache-ant-1.9.6/src/script/lcp.bat
new file mode 100644
index 00000000..dc7e9bf5
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/script/lcp.bat
@@ -0,0 +1,31 @@
+REM
+REM Licensed to the Apache Software Foundation (ASF) under one or more
+REM contributor license agreements. See the NOTICE file distributed with
+REM this work for additional information regarding copyright ownership.
+REM The ASF licenses this file to You under the Apache License, Version 2.0
+REM (the "License"); you may not use this file except in compliance with
+REM the License. You may obtain a copy of the License at
+REM
+REM http://www.apache.org/licenses/LICENSE-2.0
+REM
+REM Unless required by applicable law or agreed to in writing, software
+REM distributed under the License is distributed on an "AS IS" BASIS,
+REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+REM See the License for the specific language governing permissions and
+REM limitations under the License.
+REM
+REM
+
+set _CLASSPATHCOMPONENT=%1
+if ""%1""=="""" goto gotAllArgs
+shift
+
+:argCheck
+if ""%1""=="""" goto gotAllArgs
+set _CLASSPATHCOMPONENT=%_CLASSPATHCOMPONENT% %1
+shift
+goto argCheck
+
+:gotAllArgs
+set LOCALCLASSPATH=%LOCALCLASSPATH%;%_CLASSPATHCOMPONENT%
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/script/runant.pl b/framework/src/ant/apache-ant-1.9.6/src/script/runant.pl
new file mode 100644
index 00000000..fc26faa5
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/script/runant.pl
@@ -0,0 +1,150 @@
+#!/usr/bin/perl
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+#######################################################################
+#
+# runant.pl
+#
+# wrapper script for invoking ant in a platform with Perl installed
+# this may include cgi-bin invocation, which is considered somewhat daft.
+# (slo: that should be a separate file which can be derived from this
+# and returns the XML formatted output)
+#
+# the code is not totally portable due to classpath and directory splitting
+# issues. oops. (NB, use File::Spec::Functions will help and the code is
+# structured for the catfile() call, but because of perl version funnies
+# the code is not included.
+#######################################################################
+#
+# Assumptions:
+#
+# - the "java" executable/script is on the command path
+# - ANT_HOME has been set
+# - target platform uses ":" as classpath separator or perl indicates it is dos/win32
+# - target platform uses "/" as directory separator.
+
+#be fussy about variables
+use strict;
+
+#platform specifics (disabled)
+#use File::Spec::Functions;
+
+#turn warnings on during dev; generates a few spurious uninitialised var access warnings
+#use warnings;
+
+#and set $debug to 1 to turn on trace info
+my $debug=1;
+
+#######################################################################
+#
+# check to make sure environment is setup
+#
+
+my $HOME = $ENV{ANT_HOME};
+if ($HOME eq "")
+ {
+ die "\n\nANT_HOME *MUST* be set!\n\n";
+ }
+
+my $JAVACMD = $ENV{JAVACMD};
+$JAVACMD = "java" if $JAVACMD eq "";
+
+my $onnetware = 0;
+if ($^O eq "NetWare")
+{
+ $onnetware = 1;
+}
+
+my $oncygwin = ($^O eq "cygwin");
+
+#ISSUE: what java wants to split up classpath varies from platform to platform
+#and perl is not too hot at hinting which box it is on.
+#here I assume ":" 'cept on win32, dos, and netware. Add extra tests here as needed.
+my $s=":";
+if(($^O eq "MSWin32") || ($^O eq "dos") || ($^O eq "cygwin") ||
+ ($onnetware == 1))
+ {
+ $s=";";
+ }
+
+#build up standard classpath
+my $localpath = "$HOME/lib/ant-launcher.jar";
+#set JVM options and Ant arguments, if any
+my @ANT_OPTS=split(" ", $ENV{ANT_OPTS});
+my @ANT_ARGS=split(" ", $ENV{ANT_ARGS});
+
+#jikes
+if($ENV{JIKESPATH} ne "")
+ {
+ push @ANT_OPTS, "-Djikes.class.path=$ENV{JIKESPATH}";
+ }
+
+#construct arguments to java
+my @ARGS;
+push @ARGS, @ANT_OPTS;
+
+my $CYGHOME = "";
+
+my $classpath=$ENV{CLASSPATH};
+if ($oncygwin == 1) {
+ $localpath = `cygpath --path --windows $localpath`;
+ chomp ($localpath);
+ if (! $classpath eq "")
+ {
+ $classpath = `cygpath --path --windows "$classpath"`;
+ chomp ($classpath);
+ }
+ $HOME = `cygpath --path --windows $HOME`;
+ chomp ($HOME);
+ $CYGHOME = `cygpath --path --windows $ENV{HOME}`;
+ chomp ($CYGHOME);
+}
+push @ARGS, "-classpath", "$localpath";
+push @ARGS, "-Dant.home=$HOME";
+if ( ! $CYGHOME eq "" )
+{
+ push @ARGS, "-Dcygwin.user.home=\"$CYGHOME\""
+}
+push @ARGS, "org.apache.tools.ant.launch.Launcher", @ANT_ARGS;
+push @ARGS, @ARGV;
+if (! $classpath eq "")
+{
+ if ($onnetware == 1)
+ {
+ # make classpath literally $CLASSPATH
+ # this is to avoid pushing us over the 512 character limit
+ # even skip the ; - that is already in $localpath
+ push @ARGS, "-lib", "\$CLASSPATH";
+ }
+ else
+ {
+ push @ARGS, "-lib", "$classpath";
+ }
+}
+print "\n $JAVACMD @ARGS\n\n" if ($debug);
+
+my $returnValue = system $JAVACMD, @ARGS;
+if ($returnValue eq 0)
+ {
+ exit 0;
+ }
+else
+ {
+ # only 0 and 1 are widely recognized as exit values
+ # so change the exit value to 1
+ exit 1;
+ }
diff --git a/framework/src/ant/apache-ant-1.9.6/src/script/runant.py b/framework/src/ant/apache-ant-1.9.6/src/script/runant.py
new file mode 100644
index 00000000..a0b27645
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/script/runant.py
@@ -0,0 +1,105 @@
+#!/usr/bin/python
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+"""
+
+ runant.py
+
+ This script is a translation of the runant.pl
+ It runs ant with/out arguments, it should be quite portable (thanks to
+ the python os library)
+ This script has been tested with Python2.0/Win2K
+
+ Assumptions:
+
+ - the "java" executable/script is on the command path
+"""
+import os, os.path, string, sys
+
+# Change it to 1 to get extra debug information
+debug = 0
+
+#######################################################################
+
+# If ANT_HOME is not set default to script's parent directory
+if os.environ.has_key('ANT_HOME'):
+ ANT_HOME = os.environ['ANT_HOME']
+else:
+ ANT_HOME = os.path.dirname(os.path.dirname(os.path.abspath(sys.argv[0])))
+
+# set ANT_LIB location
+ANT_LIB = os.path.join(ANT_HOME, 'lib')
+
+# set JAVACMD (check variables JAVACMD and JAVA_HOME)
+JAVACMD = None
+if not os.environ.has_key('JAVACMD'):
+ if os.environ.has_key('JAVA_HOME'):
+ if not os.path.exists(os.environ['JAVA_HOME']):
+ print "Warning: JAVA_HOME is not defined correctly."
+ else:
+ JAVA_HOME = os.environ['JAVA_HOME']
+ while JAVA_HOME[0] == JAVA_HOME[-1] == "\"":
+ JAVA_HOME = JAVA_HOME[1:-1]
+ JAVACMD = os.path.join(JAVA_HOME, 'bin', 'java')
+ else:
+ print "Warning: JAVA_HOME not set."
+else:
+ JAVACMD = os.environ['JAVACMD']
+if not JAVACMD:
+ JAVACMD = 'java'
+
+launcher_jar = os.path.join(ANT_LIB, 'ant-launcher.jar')
+if not os.path.exists(launcher_jar):
+ print 'Warning: Unable to locate ant-launcher.jar. Expected to find it in %s' % \
+ ANT_LIB
+
+# Build up standard classpath (LOCALCLASSPATH)
+LOCALCLASSPATH = launcher_jar
+if os.environ.has_key('LOCALCLASSPATH'):
+ LOCALCLASSPATH += os.pathsep + os.environ['LOCALCLASSPATH']
+
+ANT_OPTS = ""
+if os.environ.has_key('ANT_OPTS'):
+ ANT_OPTS = os.environ['ANT_OPTS']
+
+OPTS = ""
+if os.environ.has_key('JIKESPATH'):
+ OPTS = '-Djikes.class.path=\"%s\"' % os.environ['JIKESPATH']
+
+ANT_ARGS = ""
+if os.environ.has_key('ANT_ARGS'):
+ ANT_ARGS = os.environ['ANT_ARGS']
+
+CLASSPATH = ""
+if os.environ.has_key('CLASSPATH'):
+ CLASSPATH = "-lib " + os.environ['CLASSPATH']
+
+while JAVACMD[0] == JAVACMD[-1] == "\"":
+ JAVACMD = JAVACMD[1:-1]
+
+# Builds the commandline
+cmdline = ('"%s" %s -classpath %s -Dant.home=%s %s ' + \
+ 'org.apache.tools.ant.launch.Launcher %s %s %s') \
+ % (JAVACMD, ANT_OPTS, LOCALCLASSPATH, ANT_HOME, OPTS, ANT_ARGS, \
+ CLASSPATH, string.join(sys.argv[1:], ' '))
+
+if debug:
+ print '\n%s\n\n' % (cmdline)
+sys.stdout.flush()
+
+# Run the biniou!
+os.system(cmdline)
diff --git a/framework/src/ant/apache-ant-1.9.6/src/script/runrc.cmd b/framework/src/ant/apache-ant-1.9.6/src/script/runrc.cmd
new file mode 100644
index 00000000..34b4f5d5
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/script/runrc.cmd
@@ -0,0 +1,60 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+ Run RC file, name is in the first arg, second arg is either PATH
+ ENV or -r or nothing
+*/
+
+parse arg name path rest
+
+if name = '' then do
+ say 'RC file name is missing'
+ exit 1
+end
+
+if rest \= '' then do
+ say 'Too many parameters'
+ exit 1
+end
+
+call runit name path
+exit 0
+
+runit: procedure
+parse arg name path dir
+
+if path \= '' & path \= '-r' then do
+ dir = value(translate(path),,'OS2ENVIRONMENT')
+ if dir = '' then return
+ dir = translate(dir, '\', '/') /* change UNIX-like path to OS/2 */
+end
+
+if dir = '' then dir = directory()
+
+if path = '-r' then do /* recursive call */
+ subdir = filespec('path', dir)
+ if subdir \= '\' then do
+ subdir = left(subdir, length(subdir)-1)
+ call runit name path filespec('drive', dir) || subdir
+ end
+end
+
+/* Look for the file and run it */
+if right(dir, 1) \= '\' then dir = dir || '\'
+rcfile = stream(dir || name, 'c', 'query exists')
+if rcfile \= '' then interpret 'call "' || rcfile || '"'
+
+return
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/antunit-base.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/antunit-base.xml
new file mode 100644
index 00000000..80b289ca
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/antunit-base.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="antunit-base">
+
+ <property name="antunit.tmpdir" location="${java.io.tmpdir}"/>
+ <property name="input" location="${antunit.tmpdir}/testinput"/>
+ <property name="output" location="${antunit.tmpdir}/testoutput"/>
+ <property name="resources" location="${antunit.tmpdir}/resources"/>
+ <property name="test.jar" location="${antunit.tmpdir}/test.jar"/>
+ <property name="test1.jar" location="${antunit.tmpdir}/test1.jar"/>
+ <property name="test2.jar" location="${antunit.tmpdir}/test2.jar"/>
+ <property name="test3.jar" location="${antunit.tmpdir}/test3.jar"/>
+ <property name="test4.jar" location="${antunit.tmpdir}/test4.jar"/>
+ <property name="test5.jar" location="${antunit.tmpdir}/test5.jar"/>
+ <condition property="jdk1.9+">
+ <contains string="${java.version}" substring="1.9."/>
+ </condition>
+ <available property="jdk1.8+" classname="java.lang.reflect.Executable"/>
+ <available property="jdk1.7+" classname="java.nio.file.FileSystem"/>
+ <available property="jdk1.6+" classname="java.net.CookieStore"/>
+ <available property="jdk1.5+" classname="java.net.Proxy"/>
+ <condition property="build.sysclasspath.only">
+ <equals arg1="${build.sysclasspath}" arg2="only"/>
+ </condition>
+
+ <target name="tearDown">
+ <delete dir="${input}"/>
+ <delete dir="${output}"/>
+ <delete dir="${resources}"/>
+ <delete file="${test.jar}" failonerror="false" deleteonexit="true"/>
+ <delete file="${test1.jar}" failonerror="false" deleteonexit="true"/>
+ <delete file="${test2.jar}" failonerror="false" deleteonexit="true"/>
+ <delete file="${test3.jar}" failonerror="false" deleteonexit="true"/>
+ <delete file="${test4.jar}" failonerror="false" deleteonexit="true"/>
+ <delete file="${test5.jar}" failonerror="false" deleteonexit="true"/>
+ </target>
+
+ <target name="antunit">
+ <antunit xmlns="antlib:org.apache.ant.antunit">
+ <plainlistener />
+ <file file="${ant.file}" xmlns="antlib:org.apache.tools.ant" />
+ </antunit>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/bugfixes/README.txt b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/bugfixes/README.txt
new file mode 100644
index 00000000..c2b5e5df
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/bugfixes/README.txt
@@ -0,0 +1,2 @@
+This directory contains tests for the bugs
+that have been fixed.
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/bugfixes/br50866/br50866-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/bugfixes/br50866/br50866-test.xml
new file mode 100644
index 00000000..9e2d2037
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/bugfixes/br50866/br50866-test.xml
@@ -0,0 +1,13 @@
+<project name="br50866" default="antunit" xmlns:au="antlib:org.apache.ant.antunit">
+
+ <import file="../../antunit-base.xml" />
+
+ <include file="middle.xml" />
+
+ <target name="testinclude" depends="middle.common,middle.middle">
+ <au:assertPropertyEquals name="prop-common-init" value="br50866"/>
+ <au:assertPropertyEquals name="prop-common" value="br50866"/>
+ <au:assertPropertyEquals name="prop-middle" value="br50866"/>
+ </target>
+
+</project> \ No newline at end of file
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/bugfixes/br50866/common.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/bugfixes/br50866/common.xml
new file mode 100644
index 00000000..7417c0de
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/bugfixes/br50866/common.xml
@@ -0,0 +1,8 @@
+<project name="common" default="default">
+ <target name="common-init">
+ <property name="prop-common-init" value="br50866" />
+ </target>
+ <target name="common" depends="common-init">
+ <property name="prop-common" value="br50866" />
+ </target>
+</project> \ No newline at end of file
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/bugfixes/br50866/middle.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/bugfixes/br50866/middle.xml
new file mode 100644
index 00000000..b387f931
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/bugfixes/br50866/middle.xml
@@ -0,0 +1,7 @@
+<project name="middle" default="default">
+ <import file="common.xml" optional="true" />
+
+ <target name="middle" depends="common-init">
+ <property name="prop-middle" value="br50866" />
+ </target>
+</project> \ No newline at end of file
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/bugfixes/bugzilla-43324-stackoverflow-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/bugfixes/bugzilla-43324-stackoverflow-test.xml
new file mode 100644
index 00000000..d706b8fc
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/bugfixes/bugzilla-43324-stackoverflow-test.xml
@@ -0,0 +1,68 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="length-test" default="antunit"
+ xmlns:au="antlib:org.apache.ant.antunit">
+
+ <import file="../antunit-base.xml" />
+
+ <target name="testnested">
+ <macrodef name="root-macro">
+ <element name="sub-tasks" optional="false" />
+
+ <sequential>
+ <!-- do stuff -->
+ <sub-tasks />
+ </sequential>
+ </macrodef>
+
+ <macrodef name="used-macro-a">
+ <element name="a-sub-tasks" optional="false" implicit="true" />
+
+ <sequential>
+ <root-macro>
+ <sub-tasks>
+ <!-- do stuff -->
+ <a-sub-tasks />
+ </sub-tasks>
+ </root-macro>
+ </sequential>
+ </macrodef>
+
+ <macrodef name="used-macro-b">
+ <element name="b-sub-tasks" optional="false" implicit="true" />
+
+ <sequential>
+ <used-macro-a>
+ <root-macro>
+ <sub-tasks>
+ <!-- do stuff -->
+ <b-sub-tasks />
+ </sub-tasks>
+ </root-macro>
+ </used-macro-a>
+ </sequential>
+ </macrodef>
+
+ <used-macro-b>
+ <echo message="Test B" />
+ </used-macro-b>
+
+ <au:assertLogContains text="Test B"/>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/ant-attribute-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/ant-attribute-test.xml
new file mode 100644
index 00000000..6f6dc51d
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/ant-attribute-test.xml
@@ -0,0 +1,74 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="ant-attribute-test" default="antunit"
+ xmlns:au="antlib:org.apache.ant.antunit"
+ xmlns:if="ant:if"
+ xmlns:unless="ant:unless"
+ >
+
+ <import file="../antunit-base.xml" />
+
+ <target name="test-if-set">
+ <echo message="message1" if:set="not-set"/>
+ <au:assertLogDoesntContain text="message1"/>
+ </target>
+
+ <target name="test-unless-set">
+ <echo message="message2" unless:set="not-set"/>
+ <au:assertLogContains text="message2"/>
+ </target>
+
+ <target name="test-if-true">
+ <property name="sample" value="true"/>
+ <echo message="message3" if:true="${sample}"/>
+ <au:assertLogContains text="message3"/>
+ </target>
+
+ <target name="test-if-true-false">
+ <property name="sample-1" value="false"/>
+ <echo message="message4" if:true="${sample-1}"/>
+ <au:assertLogDoesntContain text="message4"/>
+ </target>
+
+ <target name="test-unless-true-false">
+ <property name="sample-1" value="false"/>
+ <echo message="message5" unless:true="${sample-1}"/>
+ <au:assertLogContains text="message5"/>
+ </target>
+
+ <target name="test-if-blank">
+ <property name="sample-1" value=""/>
+ <echo message="message6" if:blank="${sample-1}"/>
+ <au:assertLogContains text="message6"/>
+ </target>
+
+
+
+
+ <target name="test-macrodef">
+ <property name="verbose" value="true"/>
+ <macrodef name="sayhi">
+ <sequential>
+ <echo>hi</echo>
+ </sequential>
+ </macrodef>
+ <sayhi if:set="verbose" />
+ <au:assertLogContains text="hi"/>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/bindtargets-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/bindtargets-test.xml
new file mode 100644
index 00000000..0279a2cc
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/bindtargets-test.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project xmlns:au="antlib:org.apache.ant.antunit" default="antunit">
+
+ <import file="../antunit-base.xml"/>
+
+ <target name="bound">
+ <property name="test-bound" value="ok" />
+ </target>
+
+ <target name="bound2">
+ <property name="test-bound2" value="ok" />
+ </target>
+
+ <extension-point name="extension" />
+
+ <bindtargets targets="bound,bound2" extensionPoint="extension" />
+
+ <target name="testBind" depends="extension">
+ <au:assertPropertyEquals name="test-bound" value="ok"/>
+ <au:assertPropertyEquals name="test-bound2" value="ok"/>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/classloader-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/classloader-test.xml
new file mode 100644
index 00000000..4af0040e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/classloader-test.xml
@@ -0,0 +1,88 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project xmlns:au="antlib:org.apache.ant.antunit" default="antunit">
+
+ <import file="../antunit-base.xml"/>
+
+ <target name="setUp">
+ <mkdir dir="${input}"/>
+ <mkdir dir="${output}"/>
+ <condition property="gump">
+ <available classname="org.apache.xerces.jaxp.DocumentBuilderFactoryImpl"/>
+ </condition>
+ </target>
+
+ <target name="testGetResource"
+ description="https://issues.apache.org/bugzilla/show_bug.cgi?id=44103"
+ depends="setUp"
+ unless="gump">
+ <echo file="${input}/A.java"><![CDATA[
+public class A {
+ public static void main(String[] args) {
+ if (A.class.getClassLoader().getResource("org/apache/xerces/jaxp/DocumentBuilderFactoryImpl.class") != null) {
+ throw new RuntimeException("Didn't expect to find DocumentBuilderImpl");
+ }
+ }
+}
+]]></echo>
+ <javac srcdir="${input}" destdir="${output}"/>
+ <java classname="A" failonerror="true" fork="false">
+ <classpath location="${output}"/>
+ </java>
+ </target>
+
+ <target name="testLoadClass"
+ description="https://issues.apache.org/bugzilla/show_bug.cgi?id=44103"
+ depends="setUp">
+ <echo file="${input}/A.java"><![CDATA[
+public class A {
+ public static void main(String[] args) {
+ try {
+ A.class.getClassLoader().loadClass("org.apache.xerces.jaxp.DocumentBuilderFactoryImpl");
+ throw new RuntimeException("Didn't expect to find DocumentBuilderImpl");
+ } catch (ClassNotFoundException cnfe) {
+ }
+ }
+}
+]]></echo>
+ <javac srcdir="${input}" destdir="${output}"/>
+ <java classname="A" failonerror="true" fork="false">
+ <classpath location="${output}"/>
+ </java>
+ </target>
+
+ <target name="testGetResourceAsStream"
+ description="https://issues.apache.org/bugzilla/show_bug.cgi?id=44103"
+ depends="setUp"
+ unless="gump">
+ <echo file="${input}/A.java"><![CDATA[
+public class A {
+ public static void main(String[] args) {
+ if (A.class.getClassLoader().getResourceAsStream("org/apache/xerces/jaxp/DocumentBuilderFactoryImpl.class") != null) {
+ throw new RuntimeException("Didn't expect to find DocumentBuilderImpl");
+ }
+ }
+}
+]]></echo>
+ <javac srcdir="${input}" destdir="${output}"/>
+ <java classname="A" failonerror="true" fork="false">
+ <classpath location="${output}"/>
+ </java>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/createtask-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/createtask-test.xml
new file mode 100644
index 00000000..b69633b3
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/createtask-test.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project xmlns:au="antlib:org.apache.ant.antunit" default="antunit">
+
+ <import file="../antunit-base.xml"/>
+
+ <target name="setUp">
+ <mkdir dir="${input}"/>
+ <mkdir dir="${output}"/>
+ </target>
+
+ <target name="-create-task" depends="setUp">
+ <mkdir dir="${input}/org/apache/ant/example"/>
+ <echo file="${input}/org/apache/ant/example/Foo.java"><![CDATA[
+package org.apache.ant.example;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+public class Foo extends Task {
+ public void execute() {
+ new Project().createTask("Delete");
+ }
+}
+]]></echo>
+ <javac srcdir="${input}" destdir="${output}"/>
+ <taskdef name="foo" classname="org.apache.ant.example.Foo">
+ <classpath location="${output}"/>
+ </taskdef>
+ </target>
+
+ <target name="testCreateTaskInFreshProject"
+ description="https://issues.apache.org/bugzilla/show_bug.cgi?id=50788"
+ depends="-create-task">
+ <foo/>
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/dirscanner-symlinks-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/dirscanner-symlinks-test.xml
new file mode 100644
index 00000000..0645946a
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/dirscanner-symlinks-test.xml
@@ -0,0 +1,200 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project xmlns:au="antlib:org.apache.ant.antunit" default="antunit">
+
+ <import file="../antunit-base.xml"/>
+
+ <target name="setUp">
+ <property name="base" location="${input}/base"/>
+ <mkdir dir="${base}"/>
+ </target>
+
+ <target name="checkOs">
+ <condition property="unix"><os family="unix"/></condition>
+ </target>
+
+ <macrodef name="assertDirIsEmpty">
+ <attribute name="dir" default="${output}"/>
+ <sequential>
+ <local name="resources"/>
+ <resourcecount property="resources">
+ <fileset dir="@{dir}"/>
+ </resourcecount>
+ <au:assertEquals expected="0" actual="${resources}"/>
+ </sequential>
+ </macrodef>
+
+ <target name="testSymlinkToSiblingFollow"
+ depends="checkOs, setUp, -sibling"
+ if="unix">
+ <copy todir="${output}">
+ <fileset dir="${base}" followsymlinks="true"/>
+ </copy>
+ <au:assertFileExists file="${output}/B/file.txt"/>
+ </target>
+
+ <target name="testSymlinkToSiblingNoFollow"
+ depends="checkOs, setUp, -sibling"
+ if="unix">
+ <copy todir="${output}">
+ <fileset dir="${base}" followsymlinks="false"/>
+ </copy>
+ <au:assertFileDoesntExist file="${output}/B/file.txt"/>
+ </target>
+
+ <target name="testBasedirIsSymlinkFollow"
+ depends="checkOs, setUp, -basedir-as-symlink"
+ if="unix">
+ <copy todir="${output}">
+ <fileset dir="${base}" followsymlinks="true"/>
+ </copy>
+ <au:assertFileExists file="${output}/file.txt"/>
+ </target>
+
+ <target name="testBasedirIsSymlinkNoFollow"
+ depends="checkOs, setUp, -basedir-as-symlink"
+ if="unix">
+ <copy todir="${output}">
+ <fileset dir="${base}" followsymlinks="false"/>
+ </copy>
+ <au:assertFileDoesntExist file="${output}/file.txt"/>
+ </target>
+
+ <target name="testLinkToParentFollow"
+ depends="checkOs, setUp, -link-to-parent"
+ if="unix">
+ <copy todir="${output}">
+ <fileset dir="${base}" followsymlinks="true" maxLevelsOfSymlinks="1"/>
+ </copy>
+ <symlink action="delete" link="${base}/A"/>
+ <au:assertFileExists file="${output}/A/B/file.txt"/>
+ <au:assertFileDoesntExist file="${output}/A/base/A/B/file.txt"/>
+ </target>
+
+ <target name="testLinkToParentFollowMax2"
+ depends="checkOs, setUp, -link-to-parent"
+ if="unix">
+ <copy todir="${output}">
+ <fileset dir="${base}" followsymlinks="true" maxLevelsOfSymlinks="2"/>
+ </copy>
+ <symlink action="delete" link="${base}/A"/>
+ <au:assertFileExists file="${output}/A/B/file.txt"/>
+ <au:assertFileExists file="${output}/A/base/A/B/file.txt"/>
+ </target>
+
+ <target name="testLinkToParentFollowWithInclude"
+ depends="checkOs, setUp, -link-to-parent"
+ if="unix">
+ <copy todir="${output}">
+ <fileset dir="${base}" followsymlinks="true">
+ <include name="A/B/*"/>
+ </fileset>
+ </copy>
+ <symlink action="delete" link="${base}/A"/>
+ <au:assertFileExists file="${output}/A/B/file.txt"/>
+ </target>
+
+ <!-- supposed to fail? -->
+ <target name="testLinkToParentFollowWithIncludeMultiFollow"
+ depends="checkOs, setUp, -link-to-parent"
+ if="unix">
+ <copy todir="${output}">
+ <fileset dir="${base}" followsymlinks="true">
+ <include name="A/base/A/B/*"/>
+ </fileset>
+ </copy>
+ <symlink action="delete" link="${base}/A"/>
+ <au:assertFileExists file="${output}/A/base/A/B/file.txt"/>
+ </target>
+
+ <target name="testLinkToParentNoFollow"
+ depends="checkOs, setUp, -link-to-parent"
+ if="unix">
+ <copy todir="${output}">
+ <fileset dir="${base}" followsymlinks="false"/>
+ </copy>
+ <symlink action="delete" link="${base}/A"/>
+ <au:assertFileDoesntExist file="${output}/A/B/file.txt"/>
+ </target>
+
+ <target name="testSillyLoopFollow"
+ depends="checkOs, setUp, -silly-loop"
+ if="unix">
+ <copy todir="${output}">
+ <fileset dir="${base}" followsymlinks="true"/>
+ </copy>
+ <symlink action="delete" link="${base}"/>
+ <assertDirIsEmpty/>
+ </target>
+
+ <target name="testSillyLoopNoFollow"
+ depends="checkOs, setUp, -silly-loop"
+ if="unix">
+ <copy todir="${output}">
+ <fileset dir="${base}" followsymlinks="false"/>
+ </copy>
+ <symlink action="delete" link="${base}"/>
+ <au:assertFileDoesntExist file="${output}"/>
+ </target>
+
+ <target name="testRepeatedName"
+ depends="setUp">
+ <mkdir dir="${base}/A/A/A/A"/>
+ <touch file="${base}/A/A/A/A/file.txt"/>
+ <copy todir="${output}">
+ <fileset dir="${base}" followsymlinks="true" maxLevelsOfSymlinks="1"/>
+ </copy>
+ <au:assertFileExists file="${output}/A/A/A/A/file.txt"/>
+ </target>
+
+ <target name="testRepeatedNameWithLinkButNoLoop"
+ depends="checkOs, setUp"
+ if="unix">
+ <mkdir dir="${base}/A/A/A/B"/>
+ <touch file="${base}/A/A/A/B/file.txt"/>
+ <symlink link="${base}/A/A/A/A" resource="${base}/A/A/A/B"/>
+ <copy todir="${output}">
+ <fileset dir="${base}" followsymlinks="true" maxLevelsOfSymlinks="1"/>
+ </copy>
+ <au:assertFileExists file="${output}/A/A/A/A/file.txt"/>
+ </target>
+
+ <target name="-sibling" if="unix">
+ <mkdir dir="${base}/A"/>
+ <touch file="${base}/A/file.txt"/>
+ <symlink link="${base}/B" resource="${base}/A"/>
+ </target>
+
+ <target name="-basedir-as-symlink" if="unix">
+ <delete dir="${base}"/>
+ <mkdir dir="${input}/realdir"/>
+ <touch file="${input}/realdir/file.txt"/>
+ <symlink link="${base}" resource="${input}/realdir"/>
+ </target>
+
+ <target name="-link-to-parent" if="unix">
+ <mkdir dir="${input}/B"/>
+ <touch file="${input}/B/file.txt"/>
+ <symlink link="${base}/A" resource="${input}"/>
+ </target>
+
+ <target name="-silly-loop" if="unix">
+ <delete dir="${base}"/>
+ <symlink link="${base}" resource="${input}"/>
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/extension-point-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/extension-point-test.xml
new file mode 100644
index 00000000..8c0dbdb9
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/extension-point-test.xml
@@ -0,0 +1,210 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project xmlns:au="antlib:org.apache.ant.antunit" default="antunit">
+
+ <import file="../antunit-base.xml"/>
+
+ <extension-point name="testExtensionPointWorksLikeTarget"
+ depends="setProperty, assertProperty"/>
+
+ <target name="setProperty">
+ <property name="foo" value="bar"/>
+ </target>
+
+ <target name="assertProperty">
+ <au:assertPropertyEquals name="foo" value="bar"/>
+ </target>
+
+ <target name="testExtensionPointMustBeEmpty">
+ <mkdir dir="${output}"/>
+ <echo file="${output}/build.xml"><![CDATA[
+<project>
+ <extension-point name="foo">
+ <echo>bar</echo>
+ </extension-point>
+</project>]]></echo>
+ <au:expectfailure
+ expectedMessage="you must not nest child elements into an extension-point">
+ <ant dir="${output}"/>
+ </au:expectfailure>
+ </target>
+
+ <target name="testAddToExtensionPoint">
+ <mkdir dir="${output}"/>
+ <echo file="${output}/build.xml"><![CDATA[
+<project default="foo">
+ <extension-point name="foo"/>
+ <target name="bar" extensionOf="foo">
+ <echo>In target bar</echo>
+ </target>
+</project>]]></echo>
+ <ant dir="${output}"/>
+ <au:assertLogContains text="In target bar"/>
+ </target>
+
+ <target name="testCantAddToPlainTarget">
+ <mkdir dir="${output}"/>
+ <echo file="${output}/build.xml"><![CDATA[
+<project default="foo">
+ <target name="foo"/>
+ <target name="bar" extensionOf="foo"/>
+</project>]]></echo>
+ <au:expectfailure
+ expectedMessage="referenced target foo is not an extension-point">
+ <ant dir="${output}"/>
+ </au:expectfailure>
+ </target>
+
+ <target name="testExtensionPointInImportedBuildfile" description="Bug 48804">
+ <mkdir dir="${output}"/>
+ <echo file="${output}/master.xml"><![CDATA[
+<project default="bar">
+ <extension-point name="foo"/>
+ <target name="bar" depends="foo"/>
+</project>]]></echo>
+ <echo file="${output}/build.xml"><![CDATA[
+<project>
+ <import file="master.xml"/>
+ <target name="prepare" extensionOf="foo">
+ <echo>in target prepare</echo>
+ </target>
+</project>]]></echo>
+ <ant dir="${output}" target="bar"/>
+ <au:assertLogContains text="in target prepare"/>
+ </target>
+
+ <target name="testExtensionPointInIncludedBuildfileWithNestedInclude">
+ <mkdir dir="${output}"/>
+ <echo file="${output}/abstract-compile.xml"><![CDATA[
+<project name="abstract-compile">
+ <extension-point name="compile"/>
+</project>]]></echo>
+ <echo file="${output}/compile-java.xml"><![CDATA[
+<project name="compile-java">
+ <include file="abstract-compile.xml" as="abstract-compile"/>
+ <target name="compile-java" extensionOf="abstract-compile.compile">
+ <echo>in compile java</echo>
+ </target>
+</project>]]></echo>
+ <echo file="${output}/build.xml"><![CDATA[
+<project name="master">
+ <include file="compile-java.xml" as="compile"/>
+</project>]]></echo>
+ <!-- here prefix should be concatened from each include first
+ "compile" then "abstract-compile"-->
+ <ant dir="${output}" target="compile.abstract-compile.compile"/>
+ <au:assertLogContains text="in compile java"/>
+
+ </target>
+
+ <target name="testExtensionPointInIncludedBuildfileWithNestedImport">
+ <mkdir dir="${output}"/>
+ <echo file="${output}/abstract-compile.xml"><![CDATA[
+<project name="abstract-compile">
+ <extension-point name="compile"/>
+</project>]]></echo>
+ <echo file="${output}/compile-java.xml"><![CDATA[
+<project name="compile-java">
+ <import file="abstract-compile.xml"/>
+ <target name="compile-java" extensionOf="compile">
+ <echo>in compile java</echo>
+ </target>
+</project>]]></echo>
+ <echo file="${output}/build.xml"><![CDATA[
+<project name="master">
+ <include file="compile-java.xml" as="compile"/>
+</project>]]></echo>
+ <!-- here the prefix should be "compile" as the import containing
+ the extension point is done inside an include using "compile"
+ as prefix -->
+ <ant dir="${output}" target="compile.compile"/>
+ <au:assertLogContains text="in compile java"/>
+
+ </target>
+
+ <target name="testExtensionPointInImportedBuildfileWithNestedImport">
+ <mkdir dir="${output}"/>
+ <echo file="${output}/abstract-compile.xml"><![CDATA[
+<project name="abstract-compile">
+ <extension-point name="compile"/>
+</project>]]></echo>
+ <echo file="${output}/compile-java.xml"><![CDATA[
+<project name="compile-java">
+ <import file="abstract-compile.xml"/>
+ <target name="compile-java" extensionOf="compile">
+ <echo>in compile java</echo>
+ </target>
+</project>]]></echo>
+ <echo file="${output}/build.xml"><![CDATA[
+<project name="master">
+ <import file="compile-java.xml"/>
+</project>]]></echo>
+ <!-- here extension point should not be prefixed at all -->
+ <ant dir="${output}" target="compile"/>
+ <au:assertLogContains text="in compile java"/>
+
+ </target>
+
+
+
+ <target name="testMissingExtensionPointCausesError">
+ <mkdir dir="${output}"/>
+ <echo file="${output}/build.xml"><![CDATA[
+<project default="bar">
+ <target name="bar" extensionOf="foo"/>
+</project>]]></echo>
+ <au:expectfailure
+ expectedMessage="can't add target bar to extension-point foo because the extension-point is unknown">
+ <ant dir="${output}" target="bar"/>
+ </au:expectfailure>
+ </target>
+
+ <target name="testMissingExtensionPointCausesWarningWhenConfigured">
+ <mkdir dir="${output}"/>
+ <echo file="${output}/build.xml"><![CDATA[
+<project default="bar">
+ <target name="bar" extensionOf="foo" onMissingExtensionPoint="warn"/>
+</project>]]></echo>
+ <ant dir="${output}" target="bar"/>
+ <au:assertLogContains level="warning"
+ text="can't add target bar to extension-point foo because the extension-point is unknown" />
+ </target>
+
+ <target name="testMissingExtensionPointIgnoredWhenConfigured">
+ <mkdir dir="${output}"/>
+ <echo file="${output}/build.xml"><![CDATA[
+<project default="bar">
+ <target name="bar" extensionOf="foo" onMissingExtensionPoint="ignore"/>
+</project>]]></echo>
+ <ant dir="${output}" target="bar"/>
+ <au:assertLogDoesntContain level="warning"
+ text="can't add target bar to extension-point foo because the extension-point is unknown" />
+ </target>
+
+ <target name="testOnlyAllowsExtensionPointMissingAttributeWhenExtensionOfPresent">
+ <mkdir dir="${output}"/>
+ <echo file="${output}/build.xml"><![CDATA[
+<project default="bar">
+ <target name="bar" onMissingExtensionPoint="ignore"/>
+</project>]]></echo>
+ <au:expectfailure
+ expectedMessage="onMissingExtensionPoint attribute cannot be specified unless extensionOf is specified">
+ <ant dir="${output}" target="bar"/>
+ </au:expectfailure>
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/extension/include-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/extension/include-test.xml
new file mode 100644
index 00000000..4d3b6748
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/extension/include-test.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project xmlns:au="antlib:org.apache.ant.antunit" default="antunit">
+
+ <import file="../../antunit-base.xml" />
+
+ <!-- declare a target that depends on the extension point -->
+ <target name="compile" depends="all.compile" />
+
+ <!-- declare our extension point -->
+ <extension-point name="all.compile" />
+
+ <!-- import all our modules -->
+ <import file="module1.xml" as="module1" />
+
+ <target name="testImport" depends="compile">
+ <au:assertLogContains text="In module1 compile. Yay!" />
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/extension/module1.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/extension/module1.xml
new file mode 100644
index 00000000..3b6312f6
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/extension/module1.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="module1">
+
+ <!-- declare a target with the same name as one in the master -->
+ <target name="compile" extensionOf="all.compile">
+ <echo message="In module1 compile. Yay!"/>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/location/location.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/location/location.xml
new file mode 100644
index 00000000..091d6f33
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/location/location.xml
@@ -0,0 +1,93 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="location-test" basedir="." default="all"
+ xmlns:au="antlib:org.apache.ant.antunit">
+
+ <property name="ant.build.dir" location="../../../../../build"/>
+ <property name="working.dir"
+ location="${ant.build.dir}/ant-unit/location-dir"/>
+ <property name="classes.dir" location="${working.dir}/classes"/>
+
+ <target name="all">
+ <au:antunit>
+ <fileset file="${ant.file}"/>
+ <au:plainlistener/>
+ </au:antunit>
+ </target>
+
+ <target name="setUp">
+ <mkdir dir="${classes.dir}"/>
+ <javac srcdir="src" destdir="${classes.dir}" debug="yes"/>
+ <taskdef name="echo-location" classname="task.EchoLocation"
+ classpath="${classes.dir}"/>
+ </target>
+
+ <target name="define">
+ <taskdef name="echoloc"
+ classname="task.EchoLocation">
+ <classpath>
+ <pathelement location="${classes.dir}" />
+ <pathelement path="${java.class.path}"/>
+ </classpath>
+ </taskdef>
+ </target>
+
+ <target name="macrodef" depends="define">
+ <macrodef name="echoloc2" backtrace="false">
+ <sequential>
+ <echoloc/>
+ </sequential>
+ </macrodef>
+ </target>
+
+ <target name="presetdef" depends="define">
+ <presetdef name="echoloc3">
+ <echoloc/>
+ </presetdef>
+ </target>
+
+ <target name="tearDown">
+ <delete dir="${working.dir}"/>
+ </target>
+
+ <target name="test-plain-task">
+ <echo id="echo">Hello</echo>
+ <au:assertLogContains text="Hello"/>
+ </target>
+
+ <target name="test-standalone-type">
+ <!-- TODO -->
+ </target>
+
+ <target name="test-condition-task">
+ <!-- TODO -->
+ </target>
+
+ <target name="test-macrodef-wrapped-task" depends="macrodef">
+ <echo id="echo3">Hello</echo>
+ <echoloc2/>
+ <au:assertLogContains text="Line: "/>
+ </target>
+
+ <target name="test-presetdef-wrapped-task" depends="presetdef">
+ <echo id="echo4">Hello</echo>
+ <echoloc3/>
+ <au:assertLogContains text="Line: "/>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/location/src/task/EchoLocation.java b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/location/src/task/EchoLocation.java
new file mode 100644
index 00000000..e306357d
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/location/src/task/EchoLocation.java
@@ -0,0 +1,26 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+package task;
+
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+
+public class EchoLocation extends Task {
+ public void execute() {
+ log("Line: " + getLocation().getLineNumber(), Project.MSG_INFO);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/magic-names-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/magic-names-test.xml
new file mode 100644
index 00000000..88d8b2ea
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/magic-names-test.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project xmlns:au="antlib:org.apache.ant.antunit"
+ name="magicnames-test"
+ default="default target">
+
+ <target name="default target"/>
+
+ <target name="setUp"
+ description="only here to force a second target into testInvokedTargets' list"/>
+
+ <target name="testProjectName">
+ <au:assertPropertyEquals
+ name="ant.project.name" value="magicnames-test"/>
+ </target>
+
+ <target name="testDefaultTarget">
+ <au:assertPropertyEquals
+ name="ant.project.default-target" value="default target"/>
+ </target>
+
+ <target name="testInvokedTargets">
+ <au:assertPropertyEquals
+ name="ant.project.invoked-targets" value="setUp,testInvokedTargets"/>
+ </target>
+
+ <target name="nested">
+ <au:assertPropertyEquals
+ name="ant.project.invoked-targets" value="nested"/>
+ </target>
+
+ <target name="testInvokedTargetsWithNestedAntcall">
+ <antcall target="nested"/>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/nested-elements-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/nested-elements-test.xml
new file mode 100644
index 00000000..e031c41b
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/nested-elements-test.xml
@@ -0,0 +1,125 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project xmlns:au="antlib:org.apache.ant.antunit" default="antunit">
+
+ <import file="../antunit-base.xml"/>
+
+ <target name="testConditionBaseAndTaskContainer">
+ <mkdir dir="${input}"/>
+ <mkdir dir="${output}"/>
+ <echo file="${input}/ConditionRun.java">
+import org.apache.tools.ant.*;
+import org.apache.tools.ant.taskdefs.condition.*;
+import java.util.*;
+
+public class ConditionRun extends ConditionBase implements TaskContainer {
+ private List tasks = new ArrayList();
+
+ public void addTask(Task task) {
+ tasks.add(task);
+ }
+
+ public void execute() {
+ for (Iterator iter = tasks.iterator(); iter.hasNext(); ) {
+ Task t = (Task) iter.next();
+ t.perform();
+ }
+ }
+}
+ </echo>
+ <javac destdir="${output}"
+ srcdir="${input}"/>
+ <taskdef name="conditionrun" classpath="${output}"
+ classname="ConditionRun"/>
+ <conditionrun>
+ <echo>Hello</echo>
+ </conditionrun>
+ <au:assertLogContains text="Hello"/>
+ </target>
+
+ <target name="testDynamicElementAndTaskContainer">
+ <mkdir dir="${input}"/>
+ <mkdir dir="${output}"/>
+ <echo file="${input}/Dynamic.java">
+import org.apache.tools.ant.*;
+import java.util.*;
+
+public class Dynamic implements TaskContainer, DynamicElement {
+ private List tasks = new ArrayList();
+
+ public void addTask(Task task) {
+ tasks.add(task);
+ }
+
+ public void execute() {
+ for (Iterator iter = tasks.iterator(); iter.hasNext(); ) {
+ Task t = (Task) iter.next();
+ t.perform();
+ }
+ }
+ public Object createDynamicElement(String name) {
+ return null;
+ }
+}
+ </echo>
+ <javac destdir="${output}"
+ srcdir="${input}"/>
+ <taskdef name="dyn" classpath="${output}"
+ classname="Dynamic"/>
+ <dyn>
+ <echo>Hello</echo>
+ </dyn>
+ <au:assertLogContains text="Hello"/>
+ </target>
+
+ <target name="testDynamicElementNSAndTaskContainer">
+ <mkdir dir="${input}"/>
+ <mkdir dir="${output}"/>
+ <echo file="${input}/Dynamic.java">
+import org.apache.tools.ant.*;
+import java.util.*;
+
+public class Dynamic implements TaskContainer, DynamicElementNS {
+ private List tasks = new ArrayList();
+
+ public void addTask(Task task) {
+ tasks.add(task);
+ }
+
+ public void execute() {
+ for (Iterator iter = tasks.iterator(); iter.hasNext(); ) {
+ Task t = (Task) iter.next();
+ t.perform();
+ }
+ }
+ public Object createDynamicElement(String uri, String localName,
+ String qName) {
+ return null;
+ }
+}
+ </echo>
+ <javac destdir="${output}"
+ srcdir="${input}"/>
+ <taskdef name="dyn" classpath="${output}"
+ classname="Dynamic"/>
+ <dyn>
+ <echo>Hello</echo>
+ </dyn>
+ <au:assertLogContains text="Hello"/>
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/nested-text-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/nested-text-test.xml
new file mode 100644
index 00000000..05fb4c85
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/nested-text-test.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project xmlns:au="antlib:org.apache.ant.antunit" default="antunit">
+
+ <import file="../antunit-base.xml"/>
+
+ <target name="testAcceptNested">
+ <echo>foo</echo>
+ </target>
+
+ <target name="testRejectNested">
+ <typedef name="object" classname="java.lang.Object" />
+ <au:expectfailure expectedMessage="The &lt;object&gt; type doesn't support nested text data (&quot;foo&quot;).">
+ <object>foo</object>
+ </au:expectfailure>
+ </target>
+
+ <!-- https://issues.apache.org/bugzilla/show_bug.cgi?id=46285 -->
+ <target name="testNumericEntities">
+ <echo encoding="UTF-8" file="${output}/abc.txt">&#xe4;&#169;</echo>
+ <loadresource property="foo" encoding="UTF-8">
+ <file file="${output}/abc.txt"/>
+ </loadresource>
+ <au:assertPropertyEquals name="foo" value="ä©"/>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/projecthelpers-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/projecthelpers-test.xml
new file mode 100644
index 00000000..9e9000dd
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/projecthelpers-test.xml
@@ -0,0 +1,86 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project xmlns:au="antlib:org.apache.ant.antunit" default="antunit">
+
+ <import file="../antunit-base.xml"/>
+
+ <property name="projecthelperin" location="${input}"/>
+ <property name="projecthelperout" location="${output}"/>
+
+ <target name="compileHelpers">
+ <mkdir dir="${projecthelperin}/org/apache/tools/ant"/>
+ <mkdir dir="${projecthelperout}/org/apache/tools/ant"/>
+
+ <echo file="${projecthelperin}/org/apache/tools/ant/ReferencerProjectHelper.java">
+<!-- helper that just delegate the parsing to the xml build with the proper name -->
+<![CDATA[
+ package org.apache.tools.ant;
+
+ import org.apache.tools.ant.helper.ProjectHelper2;
+ import org.apache.tools.ant.types.Resource;
+ import org.apache.tools.ant.types.resources.FileResource;
+
+ public class ReferencerProjectHelper extends ProjectHelper2 {
+
+ public boolean canParseBuildFile(Resource buildFile) {
+ return buildFile instanceof FileResource && buildFile.getName().endsWith(".xmlref");
+ }
+
+ public String getDefaultBuildFile() {
+ return "build.xmlref";
+ }
+
+ public boolean canParseAntlibDescriptor(Resource resource) {
+ return resource instanceof FileResource && resource.getName().endsWith(".xmlref");
+ }
+
+ public void parse(Project project, Object source, RootHandler handler)
+ throws BuildException {
+ FileResource file = (FileResource) source;
+ String name = file.getName();
+ Resource actual = new FileResource(file.getFile().getParentFile(), name.substring(0, name.length() - 3));
+ // switch to the parsing of the xml build file
+ super.parse(project, actual, handler);
+ }
+ }
+]]></echo>
+ <javac srcdir="${projecthelperin}" destdir="${projecthelperout}"/>
+ </target>
+
+ <target name="defineHelpers" depends="compileHelpers">
+ <typedef name="referencerhelper" classname="org.apache.tools.ant.ReferencerProjectHelper">
+ <classpath location="${projecthelperout}"/>
+ </typedef>
+ <projecthelper>
+ <referencerhelper/>
+ </projecthelper>
+ </target>
+
+ <target name="testCrossTargets" depends="defineHelpers">
+ <ant antfile="projecthelpers/build-cross-targets.xml" />
+ </target>
+
+ <target name="testManyImport" depends="defineHelpers">
+ <ant antfile="projecthelpers/build-many-import.xml" />
+ </target>
+
+ <target name="testCrossExtension" depends="defineHelpers">
+ <ant antfile="projecthelpers/build-cross-extension.xml" />
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/projecthelpers/build-cross-extension-ref.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/projecthelpers/build-cross-extension-ref.xml
new file mode 100644
index 00000000..67837a04
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/projecthelpers/build-cross-extension-ref.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project>
+ <extension-point name="extension-ref" />
+ <target name="setbar" extensionOf="extension">
+ <property name="bar" value="hello" />
+ </target>
+ <target name="setfoo" depends="init,extension-ref">
+ <property name="foo" value="hello" />
+ </target>
+</project> \ No newline at end of file
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/projecthelpers/build-cross-extension-ref.xmlref b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/projecthelpers/build-cross-extension-ref.xmlref
new file mode 100644
index 00000000..f81d3dbd
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/projecthelpers/build-cross-extension-ref.xmlref
@@ -0,0 +1,14 @@
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/projecthelpers/build-cross-extension.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/projecthelpers/build-cross-extension.xml
new file mode 100644
index 00000000..f8f1220b
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/projecthelpers/build-cross-extension.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="end" xmlns:au="antlib:org.apache.ant.antunit">
+ <import file="build-cross-extension-ref.xmlref" />
+ <target name="init">
+ <property name="start" value="true" />
+ </target>
+
+ <target name="setprop" extensionOf="extension-ref">
+ <property name="prop" value="ok" />
+ </target>
+
+ <extension-point name="extension" />
+
+ <target name="end" depends="setfoo,extension">
+ <au:assertPropertyEquals name="start" value="true" />
+ <au:assertPropertyEquals name="foo" value="hello" />
+ <au:assertPropertyEquals name="bar" value="hello" />
+ <au:assertPropertyEquals name="prop" value="ok" />
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/projecthelpers/build-cross-targets-ref.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/projecthelpers/build-cross-targets-ref.xml
new file mode 100644
index 00000000..c16d989d
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/projecthelpers/build-cross-targets-ref.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project>
+ <target name="setfoo" depends="init">
+ <property name="foo" value="hello" />
+ </target>
+</project> \ No newline at end of file
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/projecthelpers/build-cross-targets-ref.xmlref b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/projecthelpers/build-cross-targets-ref.xmlref
new file mode 100644
index 00000000..f81d3dbd
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/projecthelpers/build-cross-targets-ref.xmlref
@@ -0,0 +1,14 @@
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/projecthelpers/build-cross-targets.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/projecthelpers/build-cross-targets.xml
new file mode 100644
index 00000000..c4c7ca76
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/projecthelpers/build-cross-targets.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="end" xmlns:au="antlib:org.apache.ant.antunit">
+ <import file="build-cross-targets-ref.xmlref" />
+ <target name="init">
+ <property name="start" value="true" />
+ </target>
+ <target name="end" depends="setfoo">
+ <au:assertPropertyEquals name="start" value="true" />
+ <au:assertPropertyEquals name="foo" value="hello" />
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/projecthelpers/build-many-import-common.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/projecthelpers/build-many-import-common.xml
new file mode 100644
index 00000000..243de8cc
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/projecthelpers/build-many-import-common.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project>
+ <!-- build file imported by every other build -->
+ <target name="common" depends="init">
+ <property name="common" value="ok" />
+ </target>
+</project> \ No newline at end of file
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/projecthelpers/build-many-import-commonref.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/projecthelpers/build-many-import-commonref.xml
new file mode 100644
index 00000000..38b50ada
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/projecthelpers/build-many-import-commonref.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project>
+ <!-- build file imported by bot referenced build -->
+ <target name="commonref" depends="init">
+ <property name="commonref" value="ok" />
+ </target>
+</project> \ No newline at end of file
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/projecthelpers/build-many-import-ref.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/projecthelpers/build-many-import-ref.xml
new file mode 100644
index 00000000..c9c02fe8
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/projecthelpers/build-many-import-ref.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project>
+ <import file="build-many-import-common.xml" />
+ <import file="build-many-import-commonref.xml" />
+ <target name="setfoo" depends="init">
+ <property name="foo" value="hello" />
+ </target>
+</project> \ No newline at end of file
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/projecthelpers/build-many-import-ref.xmlref b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/projecthelpers/build-many-import-ref.xmlref
new file mode 100644
index 00000000..f81d3dbd
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/projecthelpers/build-many-import-ref.xmlref
@@ -0,0 +1,14 @@
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/projecthelpers/build-many-import.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/projecthelpers/build-many-import.xml
new file mode 100644
index 00000000..792fb56e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/projecthelpers/build-many-import.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="end" xmlns:au="antlib:org.apache.ant.antunit">
+ <import file="build-many-import-ref.xmlref" />
+ <import file="build-many-import2-ref.xmlref" />
+ <import file="build-many-import-common.xml" />
+ <target name="init">
+ <property name="start" value="true" />
+ </target>
+ <target name="end" depends="setfoo,setbar,common,commonref">
+ <au:assertPropertyEquals name="start" value="true" />
+ <au:assertPropertyEquals name="foo" value="hello" />
+ <au:assertPropertyEquals name="bar" value="hello" />
+ <au:assertPropertyEquals name="common" value="ok" />
+ <au:assertPropertyEquals name="commonref" value="ok" />
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/projecthelpers/build-many-import2-ref.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/projecthelpers/build-many-import2-ref.xml
new file mode 100644
index 00000000..d32cf17a
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/projecthelpers/build-many-import2-ref.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project>
+ <import file="build-many-import-ref.xmlref" />
+ <import file="build-many-import-common.xml" />
+ <import file="build-many-import-commonref.xml" />
+ <target name="setbar" depends="init,common">
+ <property name="bar" value="hello" />
+ </target>
+</project> \ No newline at end of file
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/projecthelpers/build-many-import2-ref.xmlref b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/projecthelpers/build-many-import2-ref.xmlref
new file mode 100644
index 00000000..f81d3dbd
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/projecthelpers/build-many-import2-ref.xmlref
@@ -0,0 +1,14 @@
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/ref-propertyhelper-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/ref-propertyhelper-test.xml
new file mode 100644
index 00000000..b3bc39ce
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/ref-propertyhelper-test.xml
@@ -0,0 +1,104 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project xmlns:au="antlib:org.apache.ant.antunit" default="antunit">
+ <import file="../antunit-base.xml"/>
+
+ <path id="foo" location="x.y"/>
+
+ <target name="testToString">
+ <echo message="${toString:foo}"/>
+ <au:assertLogContains
+ text="antunit${file.separator}core${file.separator}x.y"/>
+ </target>
+
+ <target name="testImplicitToString">
+ <echo message="${ant.refid:foo}"/>
+ <au:assertLogContains
+ text="antunit${file.separator}core${file.separator}x.y"/>
+ </target>
+
+ <target name="testPathObject">
+ <mkdir dir="${input}/org/example"/>
+ <mkdir dir="${output}"/>
+ <echo file="${input}/org/example/Task.java"><![CDATA[
+package org.example;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.Path;
+
+public class Task {
+ private Project project;
+ public void setProject(Project p) {
+ project = p;
+ }
+ private boolean set = false;
+ public void setPath(Path p) {
+ if (p != (Path) project.getReference("foo")) {
+ throw new BuildException("this is not my path");
+ }
+ set = true;
+ }
+ public void execute() {
+ if (!set) {
+ throw new BuildException("expected my path attribute to be set");
+ }
+ }
+}
+]]></echo>
+ <javac srcdir="${input}" destdir="${output}"/>
+ <taskdef name="x" classname="org.example.Task"
+ classpath="${output}"/>
+ <x path="${ant.refid:foo}"/>
+ </target>
+
+ <target name="testManualExample">
+ <mkdir dir="${input}/org/example"/>
+ <mkdir dir="${output}"/>
+ <echo file="${input}/org/example/Task.java"><![CDATA[
+package org.example;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.resources.URLResource;
+
+public class Task {
+ private Resource r;
+ private boolean set = false;
+ public void setAttr(Resource r) {
+ this.r = r;
+ }
+ public void execute() {
+ if (r instanceof URLResource) {
+ System.out.println("URL is: " + ((URLResource) r).getURL());
+ } else {
+ throw new BuildException("Expected an URLResource but got: "
+ + (r != null ? r.getClass().getName()
+ : "nothing"));
+ }
+ }
+}
+]]></echo>
+ <javac srcdir="${input}" destdir="${output}"/>
+ <taskdef name="x" classname="org.example.Task"
+ classpath="${output}"/>
+ <url url="http://ant.apache.org/" id="anturl"/>
+ <x attr="${ant.refid:anturl}"/>
+ <au:assertLogContains text="URL is: http://ant.apache.org/"/>
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/ref-psyntax-hint-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/ref-psyntax-hint-test.xml
new file mode 100644
index 00000000..de324113
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/ref-psyntax-hint-test.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project xmlns:au="antlib:org.apache.ant.antunit" default="antunit">
+ <import file="../antunit-base.xml"/>
+
+ <target name="testIt">
+ <au:expectfailure>
+ <pathconvert refid="${foo}" />
+ </au:expectfailure>
+ <au:assertLogContains level="warning"
+ text="Unresolvable reference $${foo} might be a misuse of property expansion syntax." />
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/target-test-helper.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/target-test-helper.xml
new file mode 100644
index 00000000..6ca2452f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/target-test-helper.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project>
+
+ <target name="if-true" if="${ant.refid:true}">
+ <echo>if-true called</echo>
+ </target>
+
+ <target name="unless-true" unless="${ant.refid:true}">
+ <echo>unless-true called</echo>
+ </target>
+
+ <target name="if-false" if="${ant.refid:false}">
+ <echo>if-false called</echo>
+ </target>
+
+ <target name="unless-false" unless="${ant.refid:false}">
+ <echo>unless-false called</echo>
+ </target>
+
+ <target name="if-string-true" if="${true}">
+ <echo>if-string-true called</echo>
+ </target>
+
+ <target name="unless-string-true" unless="${true}">
+ <echo>unless-string-true called</echo>
+ </target>
+
+ <target name="if-string-false" if="${false}">
+ <echo>if-string-false called</echo>
+ </target>
+
+ <target name="unless-string-false" unless="${false}">
+ <echo>unless-string-false called</echo>
+ </target>
+
+ <target name="all"
+ depends="if-true,unless-true,if-false,unless-false,
+ if-string-true,unless-string-true,
+ if-string-false,unless-string-false"/>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/target-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/target-test.xml
new file mode 100644
index 00000000..3e656be7
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/target-test.xml
@@ -0,0 +1,82 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project xmlns:au="antlib:org.apache.ant.antunit" default="antunit">
+
+ <import file="../antunit-base.xml"/>
+
+ <target name="setUp">
+ <mkdir dir="${input}/org/example"/>
+ <mkdir dir="${output}"/>
+ <echo file="${input}/org/example/CreateBoolean.java"><![CDATA[
+package org.example;
+
+import org.apache.tools.ant.ProjectComponent;
+
+public class CreateBoolean extends ProjectComponent {
+ public void execute() {
+ getProject().addReference("true", Boolean.TRUE);
+ getProject().addReference("false", Boolean.FALSE);
+ }
+}]]></echo>
+ <javac srcdir="${input}" destdir="${output}"/>
+ <taskdef name="cb" classname="org.example.CreateBoolean"
+ classpath="${output}"/>
+ <cb/>
+ </target>
+
+ <target name="testReferencesNotSet" depends="setUp">
+ <ant antfile="target-test-helper.xml" target="all"
+ inheritrefs="false"/>
+ <au:assertLogContains text="unless-true called"/>
+ <au:assertLogContains text="unless-false called"/>
+ <au:assertLogDoesntContain text="if-true called"/>
+ <au:assertLogDoesntContain text="if-false called"/>
+ <au:assertLogContains text="unless-string-true called"/>
+ <au:assertLogContains text="unless-string-false called"/>
+ <au:assertLogDoesntContain text="if-string-true called"/>
+ <au:assertLogDoesntContain text="if-string-false called"/>
+ </target>
+
+ <target name="testReferencesSet" depends="setUp">
+ <ant antfile="target-test-helper.xml" target="all"
+ inheritrefs="true"/>
+ <au:assertLogDoesntContain text="unless-true called"/>
+ <au:assertLogContains text="unless-false called"/>
+ <au:assertLogContains text="if-true called"/>
+ <au:assertLogDoesntContain text="if-false called"/>
+ <au:assertLogContains text="unless-string-true called"/>
+ <au:assertLogContains text="unless-string-false called"/>
+ <au:assertLogDoesntContain text="if-string-true called"/>
+ <au:assertLogDoesntContain text="if-string-false called"/>
+ </target>
+
+ <target name="testProperttiesSet">
+ <ant antfile="target-test-helper.xml" target="all">
+ <property name="true" value="true"/>
+ <property name="false" value="false"/>
+ </ant>
+ <au:assertLogDoesntContain text="unless-string-true called"/>
+ <au:assertLogContains text="unless-string-false called"/>
+ <au:assertLogContains text="if-string-true called"/>
+ <au:assertLogDoesntContain text="if-string-false called"/>
+ <au:assertLogContains text="unless-true called"/>
+ <au:assertLogContains text="unless-false called"/>
+ <au:assertLogDoesntContain text="if-true called"/>
+ <au:assertLogDoesntContain text="if-false called"/>
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/uuencode/src/task/BaseTask.java b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/uuencode/src/task/BaseTask.java
new file mode 100644
index 00000000..22fb70e3
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/uuencode/src/task/BaseTask.java
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package task;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.util.FileUtils;
+import java.io.File;
+import java.io.BufferedInputStream;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+/**
+ * Base class for the uuencode/decode test tasks.
+ */
+abstract public class BaseTask extends Task {
+ private final static FileUtils FILE_UTILS = FileUtils.getFileUtils();
+ private File inFile;
+ private File outFile;
+
+ public void setInFile(File inFile) {
+ this.inFile = inFile;
+ }
+ protected File getInFile() {
+ return inFile;
+ }
+ public void setOutFile(File outFile) {
+ this.outFile = outFile;
+ }
+ protected File getOutFile() {
+ return outFile;
+ }
+ public void execute() {
+ assertAttribute(inFile, "inFile");
+ assertAttribute(outFile, "outFile");
+ InputStream inputStream = null;
+ OutputStream outputStream = null;
+ try {
+ inputStream = new BufferedInputStream(
+ new FileInputStream(getInFile()));
+ outputStream = new FileOutputStream(getOutFile());
+ doit(inputStream, outputStream);
+ } catch (Exception ex) {
+ throw new BuildException(ex);
+ } finally {
+ FILE_UTILS.close(inputStream);
+ FILE_UTILS.close(outputStream);
+ }
+ }
+
+ abstract protected void doit(
+ InputStream is, OutputStream os) throws Exception;
+
+ private void assertAttribute(File file, String attributeName) {
+ if (file == null) {
+ throw new BuildException("Required attribute " + attributeName
+ + " not set");
+ }
+ }
+}
+
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/uuencode/src/task/UUDecodeTask.java b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/uuencode/src/task/UUDecodeTask.java
new file mode 100644
index 00000000..8423f8ce
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/uuencode/src/task/UUDecodeTask.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package task;
+import java.io.InputStream;
+import java.io.OutputStream;
+import sun.misc.UUDecoder;
+
+/**
+ * Decodes a uuencoded file using sun.misc.UUDecoder.
+ */
+public class UUDecodeTask extends BaseTask {
+ protected void doit(InputStream is, OutputStream os) throws Exception {
+ new UUDecoder().decodeBuffer(is, os);
+ }
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/uuencode/src/task/UUEncodeTask.java b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/uuencode/src/task/UUEncodeTask.java
new file mode 100644
index 00000000..2b878f8c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/uuencode/src/task/UUEncodeTask.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package task;
+import org.apache.tools.ant.util.UUEncoder;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+/**
+ * UUEncodes a file using org.apache.tools.ant.util.UUEncoder.
+ */
+public class UUEncodeTask extends BaseTask {
+ protected void doit(InputStream is, OutputStream os) throws Exception {
+ new UUEncoder(getInFile().getName()).encode(is, os);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/uuencode/uuencode-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/uuencode/uuencode-test.xml
new file mode 100644
index 00000000..2d68ab0b
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/core/uuencode/uuencode-test.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="antunit" xmlns:au="antlib:org.apache.ant.antunit">
+ <import file="../../antunit-base.xml"/>
+
+ <target name="setUp">
+ <mkdir dir="${input}"/>
+ <mkdir dir="${output}"/>
+ <available property="sun.uudecode.avail" classname="sun.misc.UUDecoder"/>
+ </target>
+
+ <target name="define" if="sun.uudecode.avail">
+ <javac srcdir="src" destdir="${output}" debug="yes"/>
+ <taskdef name="uuencode" classname="task.UUEncodeTask"
+ classpath="${output}"/>
+ <taskdef name="uudecode" classname="task.UUDecodeTask"
+ classpath="${output}"/>
+ </target>
+
+ <target name="test-simple" depends="define" if="sun.uudecode.avail">
+ <uuencode infile="${ant.file}"
+ outfile="${input}/uuencoded"/>
+ <uudecode infile="${input}/uuencoded"
+ outfile="${input}/decoded"/>
+ <au:assertTrue>
+ <filesmatch file1="${ant.file}" file2="${input}/decoded"/>
+ </au:assertTrue>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/filters/expandproperties-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/filters/expandproperties-test.xml
new file mode 100644
index 00000000..5dff8320
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/filters/expandproperties-test.xml
@@ -0,0 +1,92 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+<project default="antunit" xmlns:au="antlib:org.apache.ant.antunit">
+ <import file="../antunit-base.xml" />
+
+ <property name="foo" value="FOO" />
+ <property name="bar" value="BAR" />
+ <property name="baz" value="BAZ" />
+
+ <target name="testClassic">
+ <au:assertTrue>
+ <resourcesmatch>
+ <string value="FOO BAR BAZ" />
+ <concat>
+ <string value="$${foo} $${bar} $${baz}" />
+ <filterchain>
+ <expandproperties />
+ </filterchain>
+ </concat>
+ </resourcesmatch>
+ </au:assertTrue>
+ </target>
+
+ <target name="testSubset">
+ <au:assertTrue>
+ <resourcesmatch>
+ <string value="FOO $${bar} BAZ" />
+ <concat>
+ <string value="$${foo} $${bar} $${baz}" />
+ <filterchain>
+ <expandproperties>
+ <propertyset>
+ <propertyref name="foo" />
+ <propertyref name="baz" />
+ </propertyset>
+ </expandproperties>
+ </filterchain>
+ </concat>
+ </resourcesmatch>
+ </au:assertTrue>
+ </target>
+
+ <target name="testMappedPropertySet">
+ <au:assertTrue>
+ <resourcesmatch>
+ <string value="FOO BAR BAZ" />
+ <concat>
+ <string value="$${food} $${bard} $${bazd}" />
+ <filterchain>
+ <expandproperties>
+ <propertyset>
+ <propertyref builtin="all" />
+ <globmapper from="*" to="*d" />
+ </propertyset>
+ </expandproperties>
+ </filterchain>
+ </concat>
+ </resourcesmatch>
+ </au:assertTrue>
+ </target>
+
+ <target name="testEmptyResource"
+ description="https://issues.apache.org/bugzilla/show_bug.cgi?id=53626">
+ <au:assertTrue>
+ <resourcesmatch>
+ <string value="" />
+ <concat>
+ <string value="" />
+ <filterchain>
+ <expandproperties />
+ </filterchain>
+ </concat>
+ </resourcesmatch>
+ </au:assertTrue>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/filters/expected/sort.sortComparator.test b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/filters/expected/sort.sortComparator.test
new file mode 100644
index 00000000..a93e4f48
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/filters/expected/sort.sortComparator.test
@@ -0,0 +1,10 @@
+Line 2
+Line 4
+Line 6
+Line 8
+Line 10
+Line 1
+Line 3
+Line 5
+Line 7
+Line 9
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/filters/expected/sort.sortDefault.test b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/filters/expected/sort.sortDefault.test
new file mode 100644
index 00000000..43d44e57
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/filters/expected/sort.sortDefault.test
@@ -0,0 +1,10 @@
+Line 1
+Line 2
+Line 3
+Line 4
+Line 5
+Line 6
+Line 7
+Line 8
+Line 9
+Line 10
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/filters/expected/sort.sortReverse.test b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/filters/expected/sort.sortReverse.test
new file mode 100644
index 00000000..a847cc10
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/filters/expected/sort.sortReverse.test
@@ -0,0 +1,10 @@
+Line 10
+Line 9
+Line 8
+Line 7
+Line 6
+Line 5
+Line 4
+Line 3
+Line 2
+Line 1
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/filters/expected/sortuniq.txt b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/filters/expected/sortuniq.txt
new file mode 100644
index 00000000..7dc51acc
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/filters/expected/sortuniq.txt
@@ -0,0 +1,4 @@
+A
+AA
+B
+C
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/filters/expected/uniq.txt b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/filters/expected/uniq.txt
new file mode 100644
index 00000000..e9d0f3db
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/filters/expected/uniq.txt
@@ -0,0 +1,5 @@
+A
+AA
+B
+C
+B
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/filters/expected/unique-columns.txt b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/filters/expected/unique-columns.txt
new file mode 100644
index 00000000..81f684e7
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/filters/expected/unique-columns.txt
@@ -0,0 +1 @@
+A B C B
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/filters/input/sort.sortDefault.test b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/filters/input/sort.sortDefault.test
new file mode 100644
index 00000000..05661185
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/filters/input/sort.sortDefault.test
@@ -0,0 +1,10 @@
+Line 10
+Line 1
+Line 9
+Line 6
+Line 3
+Line 2
+Line 4
+Line 5
+Line 7
+Line 8
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/filters/input/uniq.txt b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/filters/input/uniq.txt
new file mode 100644
index 00000000..9baebe55
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/filters/input/uniq.txt
@@ -0,0 +1,6 @@
+A
+AA
+AA
+B
+C
+B
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/filters/input/unique-columns.txt b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/filters/input/unique-columns.txt
new file mode 100644
index 00000000..ef797259
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/filters/input/unique-columns.txt
@@ -0,0 +1 @@
+A A B C B
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/filters/replacetokens-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/filters/replacetokens-test.xml
new file mode 100644
index 00000000..c1f98ab6
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/filters/replacetokens-test.xml
@@ -0,0 +1,68 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="antunit" xmlns:au="antlib:org.apache.ant.antunit">
+ <import file="../antunit-base.xml" />
+
+ <import file="../propertyhelpers.xml" as="ph"/>
+
+ <target name="tearDown" depends="antunit-base.tearDown">
+ <delete dir="foo"/>
+ </target>
+
+ <target name="setUp">
+ <mkdir dir="${input}"/>
+ <echo file="${input}/text.txt"><![CDATA[
+Hello, @world@!
+]]></echo>
+ </target>
+
+ <target name="testPropertiesResource" depends="setUp,ph.defineHelpers">
+ <mkdir dir="${output}"/>
+ <mkdir dir="foo"/>
+ <echo file="foo/foo.properties"><![CDATA[
+world=Ant
+]]></echo>
+ <copy todir="${output}">
+ <fileset dir="${input}"/>
+ <filterchain>
+ <replacetokens propertiesResource="${java:foo!foo.properties}"/>
+ </filterchain>
+ </copy>
+ <au:assertResourceContains
+ resource="${output}/text.txt" value="Hello, Ant!"/>
+ </target>
+
+ <target name="testFileEndsWithToken"
+ description="https://issues.apache.org/bugzilla/show_bug.cgi?id=47306"
+ depends="setUp">
+ <mkdir dir="${output}"/>
+ <echo file="${input}/test47306.txt">Hello@</echo>
+ <copy todir="${output}">
+ <fileset dir="${input}"/>
+ <filterchain>
+ <replacetokens>
+ <token key="foo" value="bar"/>
+ </replacetokens>
+ </filterchain>
+ </copy>
+ <au:assertFilesMatch
+ expected="${input}/test47306.txt"
+ actual="${output}/test47306.txt"/>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/filters/sort-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/filters/sort-test.xml
new file mode 100644
index 00000000..8c2a88b5
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/filters/sort-test.xml
@@ -0,0 +1,126 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+<project default="antunit" xmlns:au="antlib:org.apache.ant.antunit">
+ <import file="../antunit-base.xml" />
+
+ <target name="setUp">
+ <mkdir dir="${output}"/>
+ </target>
+
+ <target name="testSortFilterNoArgs" depends="setUp">
+ <copy file="input/sort.sortDefault.test"
+ tofile="${output}/sort.sortDefault.test">
+ <filterchain>
+ <sortfilter/>
+ </filterchain>
+ </copy>
+ <au:assertFilesMatch
+ expected="expected/sort.sortDefault.test"
+ actual="${output}/sort.sortDefault.test"/>
+ </target>
+
+ <target name="testSortFilterNoArgsLong" depends="setUp">
+ <copy file="input/sort.sortDefault.test"
+ tofile="${output}/sort.sortDefault.test">
+ <filterchain>
+ <filterreader classname="org.apache.tools.ant.filters.SortFilter"/>
+ </filterchain>
+ </copy>
+ <au:assertFilesMatch
+ expected="expected/sort.sortDefault.test"
+ actual="${output}/sort.sortDefault.test"/>
+ </target>
+
+ <target name="testSortFilterReverse" depends="setUp">
+ <copy file="input/sort.sortDefault.test"
+ tofile="${output}/sort.sortReverse.test">
+ <filterchain>
+ <sortfilter reverse="true"/>
+ </filterchain>
+ </copy>
+ <au:assertFilesMatch
+ expected="expected/sort.sortReverse.test"
+ actual="${output}/sort.sortReverse.test"/>
+ </target>
+
+ <target name="testSortFilterReverseLong" depends="setUp">
+ <copy file="input/sort.sortDefault.test"
+ tofile="${output}/sort.sortReverse.test">
+ <filterchain>
+ <filterreader classname="org.apache.tools.ant.filters.SortFilter">
+ <param name="reverse" value="true"/>
+ </filterreader>
+ </filterchain>
+ </copy>
+ <au:assertFilesMatch
+ expected="expected/sort.sortReverse.test"
+ actual="${output}/sort.sortReverse.test"/>
+ </target>
+
+ <target name="-setUpEvenFirst" depends="setUp">
+ <mkdir dir="${input}/src/org/apache/tools/ant/filters"/>
+ <echo file="${input}/src/org/apache/tools/ant/filters/EvenFirstCmp.java"><![CDATA[
+package org.apache.tools.ant.filters;
+
+import java.util.Comparator;
+
+public final class EvenFirstCmp implements Comparator {
+
+ public int compare(Object o1, Object o2) {
+ String s1 = ((String) o1).substring(5).trim();
+ String s2 = ((String) o2).substring(5).trim();
+ int n1 = Integer.parseInt(s1);
+ int n2 = Integer.parseInt(s2);
+ if (n1 % 2 == 0) {
+ if (n2 % 2 == 0) {
+ return n1 - n2;
+ } else {
+ return -1;
+ }
+ } else {
+ if (n2 % 2 == 0) {
+ return 1;
+ } else {
+ return n1 - n2;
+ }
+ }
+ }
+}
+]]></echo>
+ <mkdir dir="${input}/build"/>
+ <javac srcdir="${input}/src" destdir="${input}/build"/>
+ <typedef classname="org.apache.tools.ant.filters.EvenFirstCmp"
+ name="evenfirst">
+ <classpath location="${input}/build"/>
+ </typedef>
+ </target>
+
+ <target name="testSortFilterComparator" depends="-setUpEvenFirst">
+ <copy file="input/sort.sortDefault.test"
+ tofile="${output}/sort.sortComparator.test">
+ <filterchain>
+ <sortfilter>
+ <evenfirst/>
+ </sortfilter>
+ </filterchain>
+ </copy>
+ <au:assertFilesMatch
+ expected="expected/sort.sortComparator.test"
+ actual="${output}/sort.sortComparator.test"/>
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/filters/striplinecomments-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/filters/striplinecomments-test.xml
new file mode 100644
index 00000000..2af0f013
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/filters/striplinecomments-test.xml
@@ -0,0 +1,85 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="antunit" xmlns:au="antlib:org.apache.ant.antunit">
+ <import file="../antunit-base.xml" />
+
+ <property name="br" value="${line.separator}" />
+
+ <string id="input">foo
+#pound
+bar
+//java sl
+baz
+REMark
+</string>
+
+ <macrodef name="test">
+ <attribute name="lines" />
+ <element name="comments" implicit="true" />
+ <sequential>
+ <au:assertTrue>
+ <resourcecount count="@{lines}">
+ <tokens>
+ <concat>
+ <resource refid="input" />
+ <filterchain>
+ <striplinecomments>
+ <comments />
+ </striplinecomments>
+ <ignoreblank />
+ </filterchain>
+ </concat>
+ </tokens>
+ </resourcecount>
+ </au:assertTrue>
+ </sequential>
+ </macrodef>
+
+ <target name="testBasic">
+ <test lines="5">
+ <comment value="#" />
+ </test>
+ </target>
+
+ <target name="testMultiple">
+ <test lines="3">
+ <comment value="#" />
+ <comment value="//" />
+ <comment value="REM" />
+ </test>
+ </target>
+
+ <target name="testNestedText">
+ <test lines="3">
+ <comment>#</comment>
+ <comment>//</comment>
+ <comment>REM</comment>
+ </test>
+ </target>
+
+ <target name="testExclusivity">
+ <au:expectfailure>
+ <filterchain>
+ <striplinecomments>
+ <comment value="#">#"</comment>
+ </striplinecomments>
+ </filterchain>
+ </au:expectfailure>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/filters/suffix-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/filters/suffix-test.xml
new file mode 100644
index 00000000..a0a9403c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/filters/suffix-test.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+<project default="antunit" xmlns:au="antlib:org.apache.ant.antunit">
+ <import file="../antunit-base.xml" />
+
+ <target name="setUp">
+ <mkdir dir="${input}"/>
+ <mkdir dir="${output}"/>
+ </target>
+
+ <target name="testSimple">
+ <echo file="${input}/a.txt">a
+b
+c</echo>
+ <echo file="${input}/b.txt">aFoo
+bFoo
+cFoo</echo>
+ <copy todir="${output}">
+ <fileset dir="${input}"/>
+ <filterchain>
+ <suffixlines suffix="Foo"/>
+ </filterchain>
+ </copy>
+ <au:assertFilesMatch expected="${input}/b.txt"
+ actual="${output}/a.txt"/>
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/filters/uniq-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/filters/uniq-test.xml
new file mode 100644
index 00000000..832ec944
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/filters/uniq-test.xml
@@ -0,0 +1,81 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+<project default="antunit" xmlns:au="antlib:org.apache.ant.antunit">
+ <import file="../antunit-base.xml" />
+
+ <target name="setUp">
+ <mkdir dir="${output}"/>
+ </target>
+
+ <target name="testUniqFilter" depends="setUp">
+ <copy file="input/uniq.txt"
+ tofile="${output}/uniq.txt">
+ <filterchain>
+ <uniqfilter/>
+ </filterchain>
+ </copy>
+ <au:assertFilesMatch
+ expected="expected/uniq.txt"
+ actual="${output}/uniq.txt"/>
+ </target>
+
+ <target name="testUniqTokenFilter" depends="setUp">
+ <copy file="input/uniq.txt"
+ tofile="${output}/uniq.txt">
+ <filterchain>
+ <tokenfilter>
+ <uniqfilter/>
+ </tokenfilter>
+ </filterchain>
+ </copy>
+ <au:assertFilesMatch
+ expected="expected/uniq.txt"
+ actual="${output}/uniq.txt"/>
+ </target>
+
+ <target name="testSortUniq" depends="setUp">
+ <copy file="input/uniq.txt"
+ tofile="${output}/uniq.txt">
+ <filterchain>
+ <sortfilter/>
+ <tokenfilter>
+ <uniqfilter/>
+ </tokenfilter>
+ </filterchain>
+ </copy>
+ <au:assertFilesMatch
+ expected="expected/sortuniq.txt"
+ actual="${output}/uniq.txt"/>
+ </target>
+
+ <target name="testUniqueColumns" depends="setUp">
+ <copy file="input/unique-columns.txt"
+ tofile="${output}/unique-columns.txt">
+ <filterchain>
+ <tokenfilter>
+ <stringtokenizer/>
+ <uniqfilter/>
+ </tokenfilter>
+ </filterchain>
+ </copy>
+ <au:assertFilesMatch
+ expected="expected/unique-columns.txt"
+ actual="${output}/unique-columns.txt"/>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/junit-frames.xsl b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/junit-frames.xsl
new file mode 100644
index 00000000..9fab2854
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/junit-frames.xsl
@@ -0,0 +1,889 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
+ xmlns:lxslt="http://xml.apache.org/xslt"
+ xmlns:redirect="http://xml.apache.org/xalan/redirect"
+ xmlns:stringutils="xalan://org.apache.tools.ant.util.StringUtils"
+ extension-element-prefixes="redirect">
+<xsl:output method="html" indent="yes" encoding="US-ASCII"/>
+<xsl:decimal-format decimal-separator="." grouping-separator=","/>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<!--
+
+ Sample stylesheet to be used with Ant JUnitReport output.
+
+ It creates a set of HTML files a la javadoc where you can browse easily
+ through all directories and projects.
+
+-->
+<xsl:param name="output.dir" select="'.'"/>
+
+
+<xsl:template match="testsuites">
+ <!-- create the index.html -->
+ <redirect:write file="{$output.dir}/index.html">
+ <xsl:call-template name="index.html"/>
+ </redirect:write>
+
+ <!-- create the stylesheet.css -->
+ <redirect:write file="{$output.dir}/stylesheet.css">
+ <xsl:call-template name="stylesheet.css"/>
+ </redirect:write>
+
+ <!-- create the overview-directories.html at the root -->
+ <redirect:write file="{$output.dir}/overview-summary.html">
+ <xsl:apply-templates select="." mode="overview.directories"/>
+ </redirect:write>
+
+ <!-- create the all-directories.html at the root -->
+ <redirect:write file="{$output.dir}/overview-frame.html">
+ <xsl:apply-templates select="." mode="all.directories"/>
+ </redirect:write>
+
+ <!-- create the all-projects.html at the root -->
+ <redirect:write file="{$output.dir}/allprojects-frame.html">
+ <xsl:apply-templates select="." mode="all.projects"/>
+ </redirect:write>
+
+ <!-- create the all-tests.html at the root -->
+ <redirect:write file="{$output.dir}/all-tests.html">
+ <xsl:apply-templates select="." mode="all.tests"/>
+ </redirect:write>
+
+ <!-- create the alltests-fails.html at the root -->
+ <redirect:write file="{$output.dir}/alltests-fails.html">
+ <xsl:apply-templates select="." mode="all.tests">
+ <xsl:with-param name="type" select="'fails'"/>
+ </xsl:apply-templates>
+ </redirect:write>
+
+ <!-- create the alltests-errors.html at the root -->
+ <redirect:write file="{$output.dir}/alltests-errors.html">
+ <xsl:apply-templates select="." mode="all.tests">
+ <xsl:with-param name="type" select="'errors'"/>
+ </xsl:apply-templates>
+ </redirect:write>
+
+ <!-- process all directories -->
+ <xsl:for-each select="./testsuite[not(./@package = preceding-sibling::testsuite/@package)]">
+ <xsl:call-template name="directory">
+ <xsl:with-param name="name" select="@package"/>
+ </xsl:call-template>
+ </xsl:for-each>
+</xsl:template>
+
+
+<xsl:template name="directory">
+ <xsl:param name="name"/>
+ <xsl:variable name="directory.dir">
+ <xsl:if test="not($name = '')"><xsl:value-of select="translate($name,'.','/')"/></xsl:if>
+ <xsl:if test="$name = ''">.</xsl:if>
+ </xsl:variable>
+ <!--Processing directory <xsl:value-of select="@name"/> in <xsl:value-of select="$output.dir"/> -->
+ <!-- create a projects-list.html in the directory directory -->
+ <redirect:write file="{$output.dir}/{$directory.dir}/directory-frame.html">
+ <xsl:call-template name="projects.list">
+ <xsl:with-param name="name" select="$name"/>
+ </xsl:call-template>
+ </redirect:write>
+
+ <!-- create a directory-summary.html in the directory directory -->
+ <redirect:write file="{$output.dir}/{$directory.dir}/directory-summary.html">
+ <xsl:call-template name="directory.summary">
+ <xsl:with-param name="name" select="$name"/>
+ </xsl:call-template>
+ </redirect:write>
+
+ <!-- for each project, creates a @name.html -->
+ <!-- @bug there will be a problem with inner projects having the same name, it will be overwritten -->
+ <xsl:for-each select="/testsuites/testsuite[@package = $name]">
+ <redirect:write file="{$output.dir}/{$directory.dir}/{@id}_{@name}.html">
+ <xsl:apply-templates select="." mode="project.details"/>
+ </redirect:write>
+ <xsl:if test="string-length(./system-out)!=0">
+ <redirect:write file="{$output.dir}/{$directory.dir}/{@id}_{@name}-out.txt">
+ <xsl:value-of disable-output-escaping="yes" select="./system-out"/>
+ </redirect:write>
+ </xsl:if>
+ <xsl:if test="string-length(./system-err)!=0">
+ <redirect:write file="{$output.dir}/{$directory.dir}/{@id}_{@name}-err.txt">
+ <xsl:value-of disable-output-escaping="yes" select="./system-err"/>
+ </redirect:write>
+ </xsl:if>
+ <xsl:if test="failures/text() != 0">
+ <redirect:write file="{$output.dir}/{$directory.dir}/{@id}_{@name}-fails.html">
+ <xsl:apply-templates select="." mode="project.details">
+ <xsl:with-param name="type" select="'fails'"/>
+ </xsl:apply-templates>
+ </redirect:write>
+ </xsl:if>
+ <xsl:if test="errors/text() != 0">
+ <redirect:write file="{$output.dir}/{$directory.dir}/{@id}_{@name}-errors.html">
+ <xsl:apply-templates select="." mode="project.details">
+ <xsl:with-param name="type" select="'errors'"/>
+ </xsl:apply-templates>
+ </redirect:write>
+ </xsl:if>
+ </xsl:for-each>
+</xsl:template>
+
+<xsl:template name="index.html">
+<html>
+ <head>
+ <title>AntUnit Test Results.</title>
+ </head>
+ <frameset cols="20%,80%">
+ <frameset rows="30%,70%">
+ <frame src="overview-frame.html" name="directoryListFrame"/>
+ <frame src="allprojects-frame.html" name="projectListFrame"/>
+ </frameset>
+ <frame src="overview-summary.html" name="projectFrame"/>
+ <noframes>
+ <h2>Frame Alert</h2>
+ <p>
+ This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client.
+ </p>
+ </noframes>
+ </frameset>
+</html>
+</xsl:template>
+
+<!-- this is the stylesheet css to use for nearly everything -->
+<xsl:template name="stylesheet.css">
+body {
+ font:normal 68% verdana,arial,helvetica;
+ color:#000000;
+}
+table tr td, table tr th {
+ font-size: 68%;
+}
+table.details tr th{
+ font-weight: bold;
+ text-align:left;
+ background:#a6caf0;
+}
+table.details tr td{
+ background:#eeeee0;
+}
+
+p {
+ line-height:1.5em;
+ margin-top:0.5em; margin-bottom:1.0em;
+}
+h1 {
+ margin: 0px 0px 5px; font: 165% verdana,arial,helvetica
+}
+h2 {
+ margin-top: 1em; margin-bottom: 0.5em; font: bold 125% verdana,arial,helvetica
+}
+h3 {
+ margin-bottom: 0.5em; font: bold 115% verdana,arial,helvetica
+}
+h4 {
+ margin-bottom: 0.5em; font: bold 100% verdana,arial,helvetica
+}
+h5 {
+ margin-bottom: 0.5em; font: bold 100% verdana,arial,helvetica
+}
+h6 {
+ margin-bottom: 0.5em; font: bold 100% verdana,arial,helvetica
+}
+.Error {
+ font-weight:bold; color:red;
+}
+.Failure {
+ font-weight:bold; color:purple;
+}
+.Properties {
+ text-align:right;
+}
+</xsl:template>
+
+<!-- Create list of all/failed/errored tests -->
+<xsl:template match="testsuites" mode="all.tests">
+ <xsl:param name="type" select="'all'"/>
+ <html>
+ <xsl:variable name="title">
+ <xsl:choose>
+ <xsl:when test="$type = 'fails'">
+ <xsl:text>All Failures</xsl:text>
+ </xsl:when>
+ <xsl:when test="$type = 'errors'">
+ <xsl:text>All Errors</xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>All Tests</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <head>
+ <title>AntUnit Test Results: <xsl:value-of select="$title"/></title>
+ <xsl:call-template name="create.stylesheet.link">
+ <xsl:with-param name="directory.name"/>
+ </xsl:call-template>
+ </head>
+ <body>
+ <xsl:attribute name="onload">open('allprojects-frame.html','projectListFrame')</xsl:attribute>
+ <xsl:call-template name="pageHeader"/>
+ <h2><xsl:value-of select="$title"/></h2>
+
+ <table class="details" border="0" cellpadding="5" cellspacing="2" width="95%">
+ <xsl:call-template name="testcase.test.header">
+ <xsl:with-param name="show.project" select="'yes'"/>
+ </xsl:call-template>
+ <!--
+ test can even not be started at all (failure to load the project)
+ so report the error directly
+ -->
+ <xsl:if test="./error">
+ <tr class="Error">
+ <td colspan="4">
+ <xsl:apply-templates select="./error"/>
+ </td>
+ </tr>
+ </xsl:if>
+ <xsl:choose>
+ <xsl:when test="$type = 'fails'">
+ <xsl:apply-templates select=".//testcase[failure]" mode="print.test">
+ <xsl:with-param name="show.project" select="'yes'"/>
+ </xsl:apply-templates>
+ </xsl:when>
+ <xsl:when test="$type = 'errors'">
+ <xsl:apply-templates select=".//testcase[error]" mode="print.test">
+ <xsl:with-param name="show.project" select="'yes'"/>
+ </xsl:apply-templates>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:apply-templates select=".//testcase" mode="print.test">
+ <xsl:with-param name="show.project" select="'yes'"/>
+ </xsl:apply-templates>
+ </xsl:otherwise>
+ </xsl:choose>
+ </table>
+ </body>
+ </html>
+</xsl:template>
+
+
+<!-- ======================================================================
+ This page is created for every testsuite project.
+ It prints a summary of the testsuite and detailed information about
+ testcase methods.
+ ====================================================================== -->
+<xsl:template match="testsuite" mode="project.details">
+ <xsl:param name="type" select="'all'"/>
+ <xsl:variable name="directory.name" select="@package"/>
+ <xsl:variable name="project.name"><xsl:if test="not($directory.name = '')"><xsl:value-of select="$directory.name"/>.</xsl:if><xsl:value-of select="@name"/></xsl:variable>
+ <html>
+ <head>
+ <title>AntUnit Test Results: <xsl:value-of select="$project.name"/></title>
+ <xsl:call-template name="create.stylesheet.link">
+ <xsl:with-param name="directory.name" select="$directory.name"/>
+ </xsl:call-template>
+ <script type="text/javascript" language="JavaScript">
+ var TestCases = new Array();
+ var cur;
+ <xsl:apply-templates select="properties"/>
+ </script>
+ <script type="text/javascript" language="JavaScript"><![CDATA[
+ function displayProperties (name) {
+ var win = window.open('','JUnitSystemProperties','scrollbars=1,resizable=1');
+ var doc = win.document;
+ doc.open();
+ doc.write("<html><head><title>Properties of " + name + "</title>");
+ doc.write("<style type=\"text/css\">");
+ doc.write("body {font:normal 68% verdana,arial,helvetica; color:#000000; }");
+ doc.write("table tr td, table tr th { font-size: 68%; }");
+ doc.write("table.properties { border-collapse:collapse; border-left:solid 1 #cccccc; border-top:solid 1 #cccccc; padding:5px; }");
+ doc.write("table.properties th { text-align:left; border-right:solid 1 #cccccc; border-bottom:solid 1 #cccccc; background-color:#eeeeee; }");
+ doc.write("table.properties td { font:normal; text-align:left; border-right:solid 1 #cccccc; border-bottom:solid 1 #cccccc; background-color:#fffffff; }");
+ doc.write("h3 { margin-bottom: 0.5em; font: bold 115% verdana,arial,helvetica }");
+ doc.write("</style>");
+ doc.write("</head><body>");
+ doc.write("<h3>Properties of " + name + "</h3>");
+ doc.write("<div align=\"right\"><a href=\"javascript:window.close();\">Close</a></div>");
+ doc.write("<table class='properties'>");
+ doc.write("<tr><th>Name</th><th>Value</th></tr>");
+ for (prop in TestCases[name]) {
+ doc.write("<tr><th>" + prop + "</th><td>" + TestCases[name][prop] + "</td></tr>");
+ }
+ doc.write("</table>");
+ doc.write("</body></html>");
+ doc.close();
+ win.focus();
+ }
+ ]]>
+ </script>
+ </head>
+ <body>
+ <xsl:call-template name="pageHeader"/>
+ <h3>Project <xsl:value-of select="$project.name"/></h3>
+
+
+ <table class="details" border="0" cellpadding="5" cellspacing="2" width="95%">
+ <xsl:call-template name="testsuite.test.header"/>
+ <xsl:apply-templates select="." mode="print.test"/>
+ </table>
+
+ <xsl:choose>
+ <xsl:when test="$type = 'fails'">
+ <h2>Failures</h2>
+ </xsl:when>
+ <xsl:when test="$type = 'errors'">
+ <h2>Errors</h2>
+ </xsl:when>
+ <xsl:otherwise>
+ <h2>Tests</h2>
+ </xsl:otherwise>
+ </xsl:choose>
+ <table class="details" border="0" cellpadding="5" cellspacing="2" width="95%">
+ <xsl:call-template name="testcase.test.header"/>
+ <!--
+ test can even not be started at all (failure to load the project)
+ so report the error directly
+ -->
+ <xsl:if test="./error">
+ <tr class="Error">
+ <td colspan="4"><xsl:apply-templates select="./error"/></td>
+ </tr>
+ </xsl:if>
+ <xsl:choose>
+ <xsl:when test="$type = 'fails'">
+ <xsl:apply-templates select="./testcase[failure]" mode="print.test"/>
+ </xsl:when>
+ <xsl:when test="$type = 'errors'">
+ <xsl:apply-templates select="./testcase[error]" mode="print.test"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:apply-templates select="./testcase" mode="print.test"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </table>
+ <!--div class="Properties">
+ <a>
+ <xsl:attribute name="href">javascript:displayProperties('<xsl:value-of select="@package"/>.<xsl:value-of select="@name"/>');</xsl:attribute>
+ Properties &#187;
+ </a>
+ </div>
+ <xsl:if test="string-length(./system-out)!=0">
+ <div class="Properties">
+ <a>
+ <xsl:attribute name="href">./<xsl:value-of select="@id"/>_<xsl:value-of select="@name"/>-out.txt</xsl:attribute>
+ System.out &#187;
+ </a>
+ </div>
+ </xsl:if>
+ <xsl:if test="string-length(./system-err)!=0">
+ <div class="Properties">
+ <a>
+ <xsl:attribute name="href">./<xsl:value-of select="@id"/>_<xsl:value-of select="@name"/>-err.txt</xsl:attribute>
+ System.err &#187;
+ </a>
+ </div>
+ </xsl:if-->
+ </body>
+ </html>
+</xsl:template>
+
+ <!--
+ Write properties into a JavaScript data structure.
+ This is based on the original idea by Erik Hatcher (ehatcher@apache.org)
+ -->
+ <xsl:template match="properties">
+ cur = TestCases['<xsl:value-of select="../@package"/>.<xsl:value-of select="../@name"/>'] = new Array();
+ <xsl:for-each select="property">
+ <xsl:sort select="@name"/>
+ cur['<xsl:value-of select="@name"/>'] = '<xsl:call-template name="JS-escape"><xsl:with-param name="string" select="@value"/></xsl:call-template>';
+ </xsl:for-each>
+ </xsl:template>
+
+
+<!-- ======================================================================
+ This page is created for every directory.
+ It prints the name of all projects that belongs to this directory.
+ @param name the directory name to print projects.
+ ====================================================================== -->
+<!-- list of projects in a directory -->
+<xsl:template name="projects.list">
+ <xsl:param name="name"/>
+ <html>
+ <head>
+ <title>AntUnit Test Projects: <xsl:value-of select="$name"/></title>
+ <xsl:call-template name="create.stylesheet.link">
+ <xsl:with-param name="directory.name" select="$name"/>
+ </xsl:call-template>
+ </head>
+ <body>
+ <table width="100%">
+ <tr>
+ <td nowrap="nowrap">
+ <h2><a href="directory-summary.html" target="projectFrame">
+ <xsl:value-of select="$name"/>
+ <xsl:if test="$name = ''">&lt;none&gt;</xsl:if>
+ </a></h2>
+ </td>
+ </tr>
+ </table>
+
+ <h2>Projects</h2>
+ <table width="100%">
+ <xsl:for-each select="/testsuites/testsuite[./@package = $name]">
+ <xsl:sort select="@name"/>
+ <tr>
+ <td nowrap="nowrap">
+ <a href="{@id}_{@name}.html" target="projectFrame"><xsl:value-of select="@name"/></a>
+ </td>
+ </tr>
+ </xsl:for-each>
+ </table>
+ </body>
+ </html>
+</xsl:template>
+
+
+<!--
+ Creates an all-projects.html file that contains a link to all directory-summary.html
+ on each project.
+-->
+<xsl:template match="testsuites" mode="all.projects">
+ <html>
+ <head>
+ <title>All AntUnit Test Projects</title>
+ <xsl:call-template name="create.stylesheet.link">
+ <xsl:with-param name="directory.name"/>
+ </xsl:call-template>
+ </head>
+ <body>
+ <h2>Projects</h2>
+ <table width="100%">
+ <xsl:apply-templates select="testsuite" mode="all.projects">
+ <xsl:sort select="@name"/>
+ </xsl:apply-templates>
+ </table>
+ </body>
+ </html>
+</xsl:template>
+
+<xsl:template match="testsuite" mode="all.projects">
+ <xsl:variable name="directory.name" select="@package"/>
+ <tr>
+ <td nowrap="nowrap">
+ <a target="projectFrame">
+ <xsl:attribute name="href">
+ <xsl:if test="not($directory.name='')">
+ <xsl:value-of select="translate($directory.name,'.','/')"/><xsl:text>/</xsl:text>
+ </xsl:if><xsl:value-of select="@id"/>_<xsl:value-of select="@name"/><xsl:text>.html</xsl:text>
+ </xsl:attribute>
+ <xsl:value-of select="@name"/>
+ </a>
+ </td>
+ </tr>
+</xsl:template>
+
+
+<!--
+ Creates an html file that contains a link to all directory-summary.html files on
+ each directory existing on testsuites.
+ @bug there will be a problem here, I don't know yet how to handle unnamed directory :(
+-->
+<xsl:template match="testsuites" mode="all.directories">
+ <html>
+ <head>
+ <title>All AntUnit Test Directories</title>
+ <xsl:call-template name="create.stylesheet.link">
+ <xsl:with-param name="directory.name"/>
+ </xsl:call-template>
+ </head>
+ <body>
+ <h2><a href="overview-summary.html" target="projectFrame">Home</a></h2>
+ <h2>Directories</h2>
+ <table width="100%">
+ <xsl:apply-templates select="testsuite[not(./@package = preceding-sibling::testsuite/@package)]" mode="all.directories">
+ <xsl:sort select="@package"/>
+ </xsl:apply-templates>
+ </table>
+ </body>
+ </html>
+</xsl:template>
+
+<xsl:template match="testsuite" mode="all.directories">
+ <tr>
+ <td nowrap="nowrap">
+ <a href="./{translate(@package,'.','/')}/directory-summary.html" target="projectFrame">
+ <xsl:value-of select="@package"/>
+ <xsl:if test="@package = ''">&lt;none&gt;</xsl:if>
+ </a>
+ </td>
+ </tr>
+</xsl:template>
+
+
+<xsl:template match="testsuites" mode="overview.directories">
+ <html>
+ <head>
+ <title>AntUnit Test Results: Summary</title>
+ <xsl:call-template name="create.stylesheet.link">
+ <xsl:with-param name="directory.name"/>
+ </xsl:call-template>
+ </head>
+ <body>
+ <xsl:attribute name="onload">open('allprojects-frame.html','projectListFrame')</xsl:attribute>
+ <xsl:call-template name="pageHeader"/>
+ <h2>Summary</h2>
+ <xsl:variable name="testCount" select="sum(testsuite/tests/text())"/>
+ <xsl:variable name="errorCount" select="sum(testsuite/errors/text())"/>
+ <xsl:variable name="failureCount" select="sum(testsuite/failures/text())"/>
+ <xsl:variable name="timeCount" select="sum(testsuite/time/text())"/>
+ <xsl:variable name="successRate" select="($testCount - $failureCount - $errorCount) div $testCount"/>
+ <table class="details" border="0" cellpadding="5" cellspacing="2" width="95%">
+ <tr valign="top">
+ <th>Tests</th>
+ <th>Failures</th>
+ <th>Errors</th>
+ <th>Success rate</th>
+ <th>Time</th>
+ </tr>
+ <tr valign="top">
+ <xsl:attribute name="class">
+ <xsl:choose>
+ <xsl:when test="$errorCount &gt; 0">Error</xsl:when>
+ <xsl:when test="$failureCount &gt; 0">Failure</xsl:when>
+ <xsl:otherwise>Pass</xsl:otherwise>
+ </xsl:choose>
+ </xsl:attribute>
+ <td><a title="Display all tests" href="all-tests.html"><xsl:value-of select="$testCount"/></a></td>
+ <td><a title="Display all failures" href="alltests-fails.html"><xsl:value-of select="$failureCount"/></a></td>
+ <td><a title="Display all errors" href="alltests-errors.html"><xsl:value-of select="$errorCount"/></a></td>
+ <td>
+ <xsl:call-template name="display-percent">
+ <xsl:with-param name="value" select="$successRate"/>
+ </xsl:call-template>
+ </td>
+ <td>
+ <xsl:call-template name="display-time">
+ <xsl:with-param name="value" select="$timeCount"/>
+ </xsl:call-template>
+ </td>
+ </tr>
+ </table>
+ <table border="0" width="95%">
+ <tr>
+ <td style="text-align: justify;">
+ Note: <em>failures</em> are anticipated and checked for with assertions while <em>errors</em> are unanticipated.
+ </td>
+ </tr>
+ </table>
+
+ <h2>Directories</h2>
+ <table class="details" border="0" cellpadding="5" cellspacing="2" width="95%">
+ <xsl:call-template name="testsuite.test.header"/>
+ <xsl:for-each select="testsuite[not(./@package = preceding-sibling::testsuite/@package)]">
+ <xsl:sort select="@package" order="ascending"/>
+ <!-- get the node set containing all testsuites that have the same directory -->
+ <xsl:variable name="insamedirectory" select="/testsuites/testsuite[./@package = current()/@package]"/>
+ <tr valign="top">
+ <!-- display a failure if there is any failure/error in the directory -->
+ <xsl:attribute name="class">
+ <xsl:choose>
+ <xsl:when test="sum($insamedirectory/errors/text()) &gt; 0">Error</xsl:when>
+ <xsl:when test="sum($insamedirectory/failures/text()) &gt; 0">Failure</xsl:when>
+ <xsl:otherwise>Pass</xsl:otherwise>
+ </xsl:choose>
+ </xsl:attribute>
+ <td><a href="./{translate(@package,'.','/')}/directory-summary.html">
+ <xsl:value-of select="@package"/>
+ <xsl:if test="@package = ''">&lt;none&gt;</xsl:if>
+ </a></td>
+ <td><xsl:value-of select="sum($insamedirectory/tests/text())"/></td>
+ <td><xsl:value-of select="sum($insamedirectory/errors/text())"/></td>
+ <td><xsl:value-of select="sum($insamedirectory/failures/text())"/></td>
+ <td>
+ <xsl:call-template name="display-time">
+ <xsl:with-param name="value" select="sum($insamedirectory/time/text())"/>
+ </xsl:call-template>
+ </td>
+ <td><xsl:value-of select="$insamedirectory/@timestamp"/></td>
+ <td><xsl:value-of select="$insamedirectory/@hostname"/></td>
+ </tr>
+ </xsl:for-each>
+ </table>
+ </body>
+ </html>
+</xsl:template>
+
+
+<xsl:template name="directory.summary">
+ <xsl:param name="name"/>
+ <html>
+ <head>
+ <xsl:call-template name="create.stylesheet.link">
+ <xsl:with-param name="directory.name" select="$name"/>
+ </xsl:call-template>
+ </head>
+ <body>
+ <xsl:attribute name="onload">open('directory-frame.html','projectListFrame')</xsl:attribute>
+ <xsl:call-template name="pageHeader"/>
+ <h3>Directory <xsl:value-of select="$name"/></h3>
+
+ <!--table border="0" cellpadding="5" cellspacing="2" width="95%">
+ <xsl:call-template name="project.metrics.header"/>
+ <xsl:apply-templates select="." mode="print.metrics"/>
+ </table-->
+
+ <xsl:variable name="insamedirectory" select="/testsuites/testsuite[./@package = $name]"/>
+ <xsl:if test="count($insamedirectory) &gt; 0">
+ <h2>Projects</h2>
+ <p>
+ <table class="details" border="0" cellpadding="5" cellspacing="2" width="95%">
+ <xsl:call-template name="testsuite.test.header"/>
+ <xsl:apply-templates select="$insamedirectory" mode="print.test">
+ <xsl:sort select="@name"/>
+ </xsl:apply-templates>
+ </table>
+ </p>
+ </xsl:if>
+ </body>
+ </html>
+</xsl:template>
+
+
+<!--
+ transform string like a.b.c to ../../../
+ @param path the path to transform into a descending directory path
+-->
+<xsl:template name="path">
+ <xsl:param name="path"/>
+ <xsl:if test="contains($path,'.')">
+ <xsl:text>../</xsl:text>
+ <xsl:call-template name="path">
+ <xsl:with-param name="path"><xsl:value-of select="substring-after($path,'.')"/></xsl:with-param>
+ </xsl:call-template>
+ </xsl:if>
+ <xsl:if test="not(contains($path,'.')) and not($path = '')">
+ <xsl:text>../</xsl:text>
+ </xsl:if>
+</xsl:template>
+
+
+<!-- create the link to the stylesheet based on the directory name -->
+<xsl:template name="create.stylesheet.link">
+ <xsl:param name="directory.name"/>
+ <link rel="stylesheet" type="text/css" title="Style"><xsl:attribute name="href"><xsl:if test="not($directory.name = 'unnamed directory')"><xsl:call-template name="path"><xsl:with-param name="path" select="$directory.name"/></xsl:call-template></xsl:if>stylesheet.css</xsl:attribute></link>
+</xsl:template>
+
+
+<!-- Page HEADER -->
+<xsl:template name="pageHeader">
+ <h1>AntUnit Test Results</h1>
+ <table width="100%">
+ <tr>
+ <td align="left"></td>
+ <td align="right">Designed for use with <a href="http://ant.apache.org/antlibs/antunit/">AntUnit</a> and <a href="http://ant.apache.org/">Ant</a>.</td>
+ </tr>
+ </table>
+ <hr size="1"/>
+</xsl:template>
+
+<!-- project header -->
+<xsl:template name="testsuite.test.header">
+ <tr valign="top">
+ <th width="80%">Name</th>
+ <th>Tests</th>
+ <th>Errors</th>
+ <th>Failures</th>
+ <th nowrap="nowrap">Time(s)</th>
+ <th nowrap="nowrap">Time Stamp</th>
+ <th>Host</th>
+ </tr>
+</xsl:template>
+
+<!-- method header -->
+<xsl:template name="testcase.test.header">
+ <xsl:param name="show.project" select="''"/>
+ <tr valign="top">
+ <xsl:if test="boolean($show.project)">
+ <th>Project</th>
+ </xsl:if>
+ <th>Name</th>
+ <th>Status</th>
+ <th width="80%">Type</th>
+ <th nowrap="nowrap">Time(s)</th>
+ </tr>
+</xsl:template>
+
+
+<!-- project information -->
+<xsl:template match="testsuite" mode="print.test">
+ <tr valign="top">
+ <xsl:attribute name="class">
+ <xsl:choose>
+ <xsl:when test="errors/text()[.&gt; 0]">Error</xsl:when>
+ <xsl:when test="failures/text()[.&gt; 0]">Failure</xsl:when>
+ <xsl:otherwise>Pass</xsl:otherwise>
+ </xsl:choose>
+ </xsl:attribute>
+ <td><a title="Display all tests" href="{@id}_{@name}.html"><xsl:value-of select="@name"/></a></td>
+ <td><a title="Display all tests" href="{@id}_{@name}.html"><xsl:apply-templates select="tests/text()"/></a></td>
+ <td>
+ <xsl:choose>
+ <xsl:when test="errors/text() != 0">
+ <a title="Display only errors" href="{@id}_{@name}-errors.html"><xsl:apply-templates select="errors/text()"/></a>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:apply-templates select="errors/text()"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </td>
+ <td>
+ <xsl:choose>
+ <xsl:when test="failures/text() != 0">
+ <a title="Display only failures" href="{@id}_{@name}-fails.html"><xsl:apply-templates select="failures/text()"/></a>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:apply-templates select="failures/text()"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </td>
+ <td><xsl:call-template name="display-time">
+ <xsl:with-param name="value" select="time/text()"/>
+ </xsl:call-template>
+ </td>
+ <td><xsl:apply-templates select="@timestamp"/></td>
+ <td><xsl:apply-templates select="@hostname"/></td>
+ </tr>
+</xsl:template>
+
+<xsl:template match="testcase" mode="print.test">
+ <xsl:param name="show.project" select="''"/>
+ <tr valign="top">
+ <xsl:attribute name="class">
+ <xsl:choose>
+ <xsl:when test="error">Error</xsl:when>
+ <xsl:when test="failure">Failure</xsl:when>
+ <xsl:otherwise>TableRowColor</xsl:otherwise>
+ </xsl:choose>
+ </xsl:attribute>
+ <xsl:variable name="project.href">
+ <xsl:value-of select="concat(translate(../@package,'.','/'), '/', ../@id, '_', ../@name, '.html')"/>
+ </xsl:variable>
+ <xsl:if test="boolean($show.project)">
+ <td><a href="{$project.href}"><xsl:value-of select="../@name"/></a></td>
+ </xsl:if>
+ <td>
+ <a name="{@name}"/>
+ <xsl:choose>
+ <xsl:when test="boolean($show.project)">
+ <a href="{concat($project.href, '#', @name)}"><xsl:value-of select="@name"/></a>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="@name"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </td>
+ <xsl:choose>
+ <xsl:when test="failure">
+ <td>Failure</td>
+ <td><xsl:apply-templates select="failure"/></td>
+ </xsl:when>
+ <xsl:when test="error">
+ <td>Error</td>
+ <td><xsl:apply-templates select="error"/></td>
+ </xsl:when>
+ <xsl:otherwise>
+ <td>Success</td>
+ <td></td>
+ </xsl:otherwise>
+ </xsl:choose>
+ <td>
+ <xsl:call-template name="display-time">
+ <xsl:with-param name="value" select="time/text()"/>
+ </xsl:call-template>
+ </td>
+ </tr>
+</xsl:template>
+
+
+<!-- Note : the below template error and failure are the same style
+ so just call the same style store in the toolkit template -->
+<xsl:template match="failure">
+ <xsl:call-template name="display-failures"/>
+</xsl:template>
+
+<xsl:template match="error">
+ <xsl:call-template name="display-failures"/>
+ <!-- display the stacktrace -->
+ <br/><br/>
+ <code>
+ <xsl:call-template name="br-replace">
+ <xsl:with-param name="word" select="."/>
+ </xsl:call-template>
+ </code>
+ <!-- the latter is better but might be problematic for non-21" monitors... -->
+ <!--pre><xsl:value-of select="."/></pre-->
+</xsl:template>
+
+<!-- Style for the error and failure in the testcase template -->
+<xsl:template name="display-failures">
+ <xsl:choose>
+ <xsl:when test="not(@message)">N/A</xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="@message"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ <xsl:choose>
+ <xsl:when test="@linenumber">
+ <br></br>
+ at line <xsl:value-of select="@linenumber"/>
+ <xsl:choose>
+ <xsl:when test="@columnnumber">
+ , column <xsl:value-of select="@columnnumber"/>
+ </xsl:when>
+ </xsl:choose>
+ </xsl:when>
+ </xsl:choose>
+</xsl:template>
+
+<xsl:template name="JS-escape">
+ <xsl:param name="string"/>
+ <xsl:param name="tmp1" select="stringutils:replace(string($string),'\','\\')"/>
+ <xsl:param name="tmp2" select="stringutils:replace(string($tmp1),&quot;'&quot;,&quot;\&apos;&quot;)"/>
+ <xsl:value-of select="$tmp2"/>
+</xsl:template>
+
+
+<!--
+ template that will convert a carriage return into a br tag
+ @param word the text from which to convert CR to BR tag
+-->
+<xsl:template name="br-replace">
+ <xsl:param name="word"/>
+ <xsl:value-of disable-output-escaping="yes" select='stringutils:replace(string($word),"&#xA;","&lt;br/>")'/>
+</xsl:template>
+
+<xsl:template name="display-time">
+ <xsl:param name="value"/>
+ <xsl:value-of select="format-number($value,'0.000')"/>
+</xsl:template>
+
+<xsl:template name="display-percent">
+ <xsl:param name="value"/>
+ <xsl:value-of select="format-number($value,'0.00%')"/>
+</xsl:template>
+</xsl:stylesheet>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/junit-noframes.xsl b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/junit-noframes.xsl
new file mode 100644
index 00000000..255046a8
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/junit-noframes.xsl
@@ -0,0 +1,485 @@
+<?xml version="1.0"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
+ xmlns:lxslt="http://xml.apache.org/xslt"
+ xmlns:stringutils="xalan://org.apache.tools.ant.util.StringUtils">
+<xsl:output method="html" indent="yes" encoding="US-ASCII"
+ doctype-public="-//W3C//DTD HTML 4.01 Transitional//EN" />
+<xsl:decimal-format decimal-separator="." grouping-separator="," />
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+<!--
+
+ Sample stylesheet to be used with Ant JUnitReport output.
+
+ It creates a non-framed report that can be useful to send via
+ e-mail or such.
+
+-->
+<xsl:template match="testsuites">
+ <html>
+ <head>
+ <title>AntUnit Test Results</title>
+ <style type="text/css">
+ body {
+ font:normal 68% verdana,arial,helvetica;
+ color:#000000;
+ }
+ table tr td, table tr th {
+ font-size: 68%;
+ }
+ table.details tr th{
+ font-weight: bold;
+ text-align:left;
+ background:#a6caf0;
+ }
+ table.details tr td{
+ background:#eeeee0;
+ }
+
+ p {
+ line-height:1.5em;
+ margin-top:0.5em; margin-bottom:1.0em;
+ }
+ h1 {
+ margin: 0px 0px 5px; font: 165% verdana,arial,helvetica
+ }
+ h2 {
+ margin-top: 1em; margin-bottom: 0.5em; font: bold 125% verdana,arial,helvetica
+ }
+ h3 {
+ margin-bottom: 0.5em; font: bold 115% verdana,arial,helvetica
+ }
+ h4 {
+ margin-bottom: 0.5em; font: bold 100% verdana,arial,helvetica
+ }
+ h5 {
+ margin-bottom: 0.5em; font: bold 100% verdana,arial,helvetica
+ }
+ h6 {
+ margin-bottom: 0.5em; font: bold 100% verdana,arial,helvetica
+ }
+ .Error {
+ font-weight:bold; color:red;
+ }
+ .Failure {
+ font-weight:bold; color:purple;
+ }
+ .Properties {
+ text-align:right;
+ }
+ </style>
+ <!--
+ <script type="text/javascript" language="JavaScript">
+ var Projects = new Array();
+ var cur;
+ <xsl:for-each select="./testsuite">
+ <xsl:apply-templates select="properties"/>
+ </xsl:for-each>
+
+ </script>
+ <script type="text/javascript" language="JavaScript"><![CDATA[
+ function displayProperties (name) {
+ var win = window.open('','JUnitSystemProperties','scrollbars=1,resizable=1');
+ var doc = win.document;
+ doc.open();
+ doc.write("<html><head><title>Properties of " + name + "</title>");
+ doc.write("<style>")
+ doc.write("body {font:normal 68% verdana,arial,helvetica; color:#000000; }");
+ doc.write("table tr td, table tr th { font-size: 68%; }");
+ doc.write("table.properties { border-collapse:collapse; border-left:solid 1 #cccccc; border-top:solid 1 #cccccc; padding:5px; }");
+ doc.write("table.properties th { text-align:left; border-right:solid 1 #cccccc; border-bottom:solid 1 #cccccc; background-color:#eeeeee; }");
+ doc.write("table.properties td { font:normal; text-align:left; border-right:solid 1 #cccccc; border-bottom:solid 1 #cccccc; background-color:#fffffff; }");
+ doc.write("h3 { margin-bottom: 0.5em; font: bold 115% verdana,arial,helvetica }");
+ doc.write("</style>");
+ doc.write("</head><body>");
+ doc.write("<h3>Properties of " + name + "</h3>");
+ doc.write("<div align=\"right\"><a href=\"javascript:window.close();\">Close</a></div>");
+ doc.write("<table class='properties'>");
+ doc.write("<tr><th>Name</th><th>Value</th></tr>");
+ for (prop in Projects[name]) {
+ doc.write("<tr><th>" + prop + "</th><td>" + Projects[name][prop] + "</td></tr>");
+ }
+ doc.write("</table>");
+ doc.write("</body></html>");
+ doc.close();
+ win.focus();
+ }
+ ]]>
+ </script>
+ -->
+ </head>
+ <body>
+ <a name="top"></a>
+ <xsl:call-template name="pageHeader"/>
+
+ <!-- Summary part -->
+ <xsl:call-template name="summary"/>
+ <hr size="1" width="95%" align="left"/>
+
+ <!-- Directory List part -->
+ <xsl:call-template name="directorylist"/>
+ <hr size="1" width="95%" align="left"/>
+
+ <!-- For each directory create its part -->
+ <xsl:call-template name="directories"/>
+ <hr size="1" width="95%" align="left"/>
+
+ <!-- For each class create the part -->
+ <xsl:call-template name="classes"/>
+
+ </body>
+ </html>
+</xsl:template>
+
+
+
+ <!-- ================================================================== -->
+ <!-- Write a list of all directories with an hyperlink to the anchor of -->
+ <!-- of the directory name. -->
+ <!-- ================================================================== -->
+ <xsl:template name="directorylist">
+ <h2>Directories</h2>
+ Note: directory statistics are not computed recursively, they only sum up all of its testsuites numbers.
+ <table class="details" border="0" cellpadding="5" cellspacing="2" width="95%">
+ <xsl:call-template name="testsuite.test.header"/>
+ <!-- list all directories recursively -->
+ <xsl:for-each select="./testsuite[not(./@package = preceding-sibling::testsuite/@package)]">
+ <xsl:sort select="@package"/>
+ <xsl:variable name="testsuites-in-directory" select="/testsuites/testsuite[./@package = current()/@package]"/>
+ <xsl:variable name="testCount" select="sum($testsuites-in-directory/tests/text())"/>
+ <xsl:variable name="errorCount" select="sum($testsuites-in-directory/errors/text())"/>
+ <xsl:variable name="failureCount" select="sum($testsuites-in-directory/failures/text())"/>
+ <xsl:variable name="timeCount" select="sum($testsuites-in-directory/time/text())"/>
+
+ <!-- write a summary for the directory -->
+ <tr valign="top">
+ <!-- set a nice color depending if there is an error/failure -->
+ <xsl:attribute name="class">
+ <xsl:choose>
+ <xsl:when test="$failureCount &gt; 0">Failure</xsl:when>
+ <xsl:when test="$errorCount &gt; 0">Error</xsl:when>
+ </xsl:choose>
+ </xsl:attribute>
+ <td><a href="#{@package}"><xsl:value-of select="@package"/></a></td>
+ <td><xsl:value-of select="$testCount"/></td>
+ <td><xsl:value-of select="$errorCount"/></td>
+ <td><xsl:value-of select="$failureCount"/></td>
+ <td>
+ <xsl:call-template name="display-time">
+ <xsl:with-param name="value" select="$timeCount"/>
+ </xsl:call-template>
+ </td>
+ <td><xsl:value-of select="$testsuites-in-directory/@timestamp"/></td>
+ <td><xsl:value-of select="$testsuites-in-directory/@hostname"/></td>
+ </tr>
+ </xsl:for-each>
+ </table>
+ </xsl:template>
+
+
+ <!-- ================================================================== -->
+ <!-- Write a directory level report -->
+ <!-- It creates a table with values from the document: -->
+ <!-- Name | Tests | Errors | Failures | Time -->
+ <!-- ================================================================== -->
+ <xsl:template name="directories">
+ <!-- create an anchor to this directory name -->
+ <xsl:for-each select="/testsuites/testsuite[not(./@package = preceding-sibling::testsuite/@package)]">
+ <xsl:sort select="@package"/>
+ <a name="{@package}"></a>
+ <h3>Directory <xsl:value-of select="@package"/></h3>
+
+ <table class="details" border="0" cellpadding="5" cellspacing="2" width="95%">
+ <xsl:call-template name="testsuite.test.header"/>
+
+ <!-- match the testsuites of this directory -->
+ <xsl:apply-templates select="/testsuites/testsuite[./@package = current()/@package]" mode="print.test"/>
+ </table>
+ <a href="#top">Back to top</a>
+ <p/>
+ <p/>
+ </xsl:for-each>
+ </xsl:template>
+
+ <xsl:template name="classes">
+ <xsl:for-each select="testsuite">
+ <xsl:sort select="@name"/>
+ <!-- create an anchor to this class name -->
+ <a name="{@name}"></a>
+ <h3>Project <xsl:value-of select="@name"/></h3>
+
+ <table class="details" border="0" cellpadding="5" cellspacing="2" width="95%">
+ <xsl:call-template name="testcase.test.header"/>
+ <!--
+ test can even not be started at all (failure to load the class)
+ so report the error directly
+ -->
+ <xsl:if test="./error">
+ <tr class="Error">
+ <td colspan="4"><xsl:apply-templates select="./error"/></td>
+ </tr>
+ </xsl:if>
+ <xsl:apply-templates select="./testcase" mode="print.test"/>
+ </table>
+ <!--
+ <div class="Properties">
+ <a>
+ <xsl:attribute name="href">javascript:displayProperties('<xsl:value-of select="@package"/>.<xsl:value-of select="@name"/>');</xsl:attribute>
+ Properties &#187;
+ </a>
+ </div>
+ -->
+ <p/>
+
+ <a href="#top">Back to top</a>
+ </xsl:for-each>
+ </xsl:template>
+
+ <xsl:template name="summary">
+ <h2>Summary</h2>
+ <xsl:variable name="testCount" select="sum(testsuite/tests/text())"/>
+ <xsl:variable name="errorCount" select="sum(testsuite/errors/text())"/>
+ <xsl:variable name="failureCount" select="sum(testsuite/failures/text())"/>
+ <xsl:variable name="timeCount" select="sum(testsuite/time/text())"/>
+ <xsl:variable name="successRate" select="($testCount - $failureCount - $errorCount) div $testCount"/>
+ <table class="details" border="0" cellpadding="5" cellspacing="2" width="95%">
+ <tr valign="top">
+ <th>Tests</th>
+ <th>Failures</th>
+ <th>Errors</th>
+ <th>Success rate</th>
+ <th>Time</th>
+ </tr>
+ <tr valign="top">
+ <xsl:attribute name="class">
+ <xsl:choose>
+ <xsl:when test="$failureCount &gt; 0">Failure</xsl:when>
+ <xsl:when test="$errorCount &gt; 0">Error</xsl:when>
+ </xsl:choose>
+ </xsl:attribute>
+ <td><xsl:value-of select="$testCount"/></td>
+ <td><xsl:value-of select="$failureCount"/></td>
+ <td><xsl:value-of select="$errorCount"/></td>
+ <td>
+ <xsl:call-template name="display-percent">
+ <xsl:with-param name="value" select="$successRate"/>
+ </xsl:call-template>
+ </td>
+ <td>
+ <xsl:call-template name="display-time">
+ <xsl:with-param name="value" select="$timeCount"/>
+ </xsl:call-template>
+ </td>
+
+ </tr>
+ </table>
+ <table border="0" width="95%">
+ <tr>
+ <td style="text-align: justify;">
+ Note: <i>failures</i> are anticipated and checked for with assertions while <i>errors</i> are unanticipated.
+ </td>
+ </tr>
+ </table>
+ </xsl:template>
+
+ <!--
+ Write properties into a JavaScript data structure.
+ This is based on the original idea by Erik Hatcher (ehatcher@apache.org)
+ -->
+ <!--
+ <xsl:template match="properties">
+ cur = Projects['<xsl:value-of select="../@package"/>.<xsl:value-of select="../@name"/>'] = new Array();
+ <xsl:for-each select="property">
+ <xsl:sort select="@name"/>
+ cur['<xsl:value-of select="@name"/>'] = '<xsl:call-template name="JS-escape"><xsl:with-param name="string" select="@value"/></xsl:call-template>';
+ </xsl:for-each>
+ </xsl:template>
+ -->
+
+<!-- Page HEADER -->
+<xsl:template name="pageHeader">
+ <h1>Unit Test Results</h1>
+ <table width="100%">
+ <tr>
+ <td align="left"></td>
+ <td align="right">Designed for use with <a href='http://ant.apache.org/antlibs/antunit/'>AntUnit</a> and <a href='http://ant.apache.org/'>Ant</a>.</td>
+ </tr>
+ </table>
+ <hr size="1"/>
+</xsl:template>
+
+<xsl:template match="testsuite" mode="header">
+ <tr valign="top">
+ <th width="80%">Name</th>
+ <th>Tests</th>
+ <th>Errors</th>
+ <th>Failures</th>
+ <th nowrap="nowrap">Time(s)</th>
+ </tr>
+</xsl:template>
+
+<!-- class header -->
+<xsl:template name="testsuite.test.header">
+ <tr valign="top">
+ <th width="80%">Name</th>
+ <th>Tests</th>
+ <th>Errors</th>
+ <th>Failures</th>
+ <th nowrap="nowrap">Time(s)</th>
+ <th nowrap="nowrap">Time Stamp</th>
+ <th>Host</th>
+ </tr>
+</xsl:template>
+
+<!-- method header -->
+<xsl:template name="testcase.test.header">
+ <tr valign="top">
+ <th>Name</th>
+ <th>Status</th>
+ <th width="80%">Type</th>
+ <th nowrap="nowrap">Time(s)</th>
+ </tr>
+</xsl:template>
+
+
+<!-- class information -->
+<xsl:template match="testsuite" mode="print.test">
+ <tr valign="top">
+ <!-- set a nice color depending if there is an error/failure -->
+ <xsl:attribute name="class">
+ <xsl:choose>
+ <xsl:when test="failures/text()[.&gt; 0]">Failure</xsl:when>
+ <xsl:when test="errors/text()[.&gt; 0]">Error</xsl:when>
+ </xsl:choose>
+ </xsl:attribute>
+
+ <!-- print testsuite information -->
+ <td><a href="#{@name}"><xsl:value-of select="@name"/></a></td>
+ <td><xsl:value-of select="tests/text()"/></td>
+ <td><xsl:value-of select="errors/text()"/></td>
+ <td><xsl:value-of select="failures/text()"/></td>
+ <td>
+ <xsl:call-template name="display-time">
+ <xsl:with-param name="value" select="time/text()"/>
+ </xsl:call-template>
+ </td>
+ <td><xsl:apply-templates select="@timestamp"/></td>
+ <td><xsl:apply-templates select="@hostname"/></td>
+ </tr>
+</xsl:template>
+
+<xsl:template match="testcase" mode="print.test">
+ <tr valign="top">
+ <xsl:attribute name="class">
+ <xsl:choose>
+ <xsl:when test="error">Error</xsl:when>
+ <xsl:when test="failure">Failure</xsl:when>
+ <xsl:otherwise>TableRowColor</xsl:otherwise>
+ </xsl:choose>
+ </xsl:attribute>
+ <td><xsl:value-of select="@name"/></td>
+ <xsl:choose>
+ <xsl:when test="failure">
+ <td>Failure</td>
+ <td><xsl:apply-templates select="failure"/></td>
+ </xsl:when>
+ <xsl:when test="error">
+ <td>Error</td>
+ <td><xsl:apply-templates select="error"/></td>
+ </xsl:when>
+ <xsl:otherwise>
+ <td>Success</td>
+ <td></td>
+ </xsl:otherwise>
+ </xsl:choose>
+ <td>
+ <xsl:call-template name="display-time">
+ <xsl:with-param name="value" select="time/text()"/>
+ </xsl:call-template>
+ </td>
+ </tr>
+</xsl:template>
+
+
+<xsl:template match="failure">
+ <xsl:call-template name="display-failures"/>
+</xsl:template>
+
+<xsl:template match="error">
+ <xsl:call-template name="display-failures"/>
+ <!-- display the stacktrace -->
+ <br/><br/>
+ <code>
+ <xsl:call-template name="br-replace">
+ <xsl:with-param name="word" select="."/>
+ </xsl:call-template>
+ </code>
+ <!-- the latter is better but might be problematic for non-21" monitors... -->
+ <!--pre><xsl:value-of select="."/></pre-->
+</xsl:template>
+
+<!-- Style for the error and failure in the tescase template -->
+<xsl:template name="display-failures">
+ <xsl:choose>
+ <xsl:when test="not(@message)">N/A</xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="@message"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ <xsl:choose>
+ <xsl:when test="@linenumber">
+ <br></br>
+ at line <xsl:value-of select="@linenumber"/>
+ <xsl:choose>
+ <xsl:when test="@columnnumber">
+ , column <xsl:value-of select="@columnnumber"/>
+ </xsl:when>
+ </xsl:choose>
+ </xsl:when>
+ </xsl:choose>
+</xsl:template>
+
+<xsl:template name="JS-escape">
+ <xsl:param name="string"/>
+ <xsl:param name="tmp1" select="stringutils:replace(string($string),'\','\\')"/>
+ <xsl:param name="tmp2" select="stringutils:replace(string($tmp1),&quot;'&quot;,&quot;\&apos;&quot;)"/>
+ <xsl:value-of select="$tmp2"/>
+</xsl:template>
+
+
+<!--
+ template that will convert a carriage return into a br tag
+ @param word the text from which to convert CR to BR tag
+-->
+<xsl:template name="br-replace">
+ <xsl:param name="word"/>
+ <xsl:value-of disable-output-escaping="yes" select='stringutils:replace(string($word),"&#xA;","&lt;br/>")'/>
+</xsl:template>
+
+<xsl:template name="display-time">
+ <xsl:param name="value"/>
+ <xsl:value-of select="format-number($value,'0.000')"/>
+</xsl:template>
+
+<xsl:template name="display-percent">
+ <xsl:param name="value"/>
+ <xsl:value-of select="format-number($value,'0.00%')"/>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/propertyhelpers.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/propertyhelpers.xml
new file mode 100644
index 00000000..287f00c3
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/propertyhelpers.xml
@@ -0,0 +1,88 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project>
+ <import file="antunit-base.xml"/>
+
+ <target name="compileHelpers">
+ <mkdir dir="${input}/org/apache/ant/propertyhelper"/>
+ <mkdir dir="${output}/org/apache/ant/propertyhelper"/>
+
+ <echo file="${input}/org/apache/ant/propertyhelper/URLHelper.java"><![CDATA[
+package org.apache.ant.propertyhelper;
+
+import org.apache.tools.ant.PropertyHelper;
+import org.apache.tools.ant.types.resources.URLResource;
+
+public class URLHelper implements PropertyHelper.PropertyEvaluator {
+ private String prefix = "url:";
+ public Object evaluate(String property, PropertyHelper propertyHelper) {
+ if (property.startsWith(prefix)) {
+ String s = property.substring(prefix.length());
+ return new URLResource(s);
+ }
+ return null;
+ }
+}
+]]></echo>
+ <echo file="${input}/org/apache/ant/propertyhelper/JavaHelper.java"><![CDATA[
+package org.apache.ant.propertyhelper;
+
+import java.io.File;
+import org.apache.tools.ant.ProjectComponent;
+import org.apache.tools.ant.PropertyHelper;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.types.resources.JavaResource;
+
+public class JavaHelper extends ProjectComponent
+ implements PropertyHelper.PropertyEvaluator {
+
+ private String prefix = "java:";
+ public Object evaluate(String property, PropertyHelper propertyHelper) {
+ if (property.startsWith(prefix)) {
+ String s = property.substring(prefix.length());
+ int index = s.indexOf("!");
+
+ Path p = new Path(getProject());
+ p.setPath(s.substring(0, index));
+
+ JavaResource r = new JavaResource(s.substring(index + 1), p);
+ r.setProject(getProject());
+ return r;
+ }
+ return null;
+ }
+}
+]]></echo>
+ <javac srcdir="${input}" destdir="${output}"/>
+ </target>
+
+ <target name="defineHelpers" depends="compileHelpers">
+ <componentdef name="urlhelper"
+ classname="org.apache.ant.propertyhelper.URLHelper">
+ <classpath location="${output}"/>
+ </componentdef>
+ <componentdef name="javahelper"
+ classname="org.apache.ant.propertyhelper.JavaHelper">
+ <classpath location="${output}"/>
+ </componentdef>
+ <propertyhelper>
+ <urlhelper/>
+ <javahelper/>
+ </propertyhelper>
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/ant-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/ant-test.xml
new file mode 100644
index 00000000..c3ee56b7
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/ant-test.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="antunit" xmlns:au="antlib:org.apache.ant.antunit">
+ <import file="../antunit-base.xml" />
+
+ <target name="testLastPropertyWins">
+ <ant antfile="antcall-test.xml" target="checkB">
+ <property name="b" value="1"/>
+ <property name="b" value="2"/>
+ <property name="expected" value="2"/>
+ </ant>
+ </target>
+
+ <target name="makePropertiesFile">
+ <ant antfile="antcall-test.xml" target="makePropertiesFile"/>
+ </target>
+
+ <target name="testPropertiesLoadedFromFile" depends="makePropertiesFile">
+ <ant antfile="antcall-test.xml" target="checkB">
+ <property name="expected" value="2"/>
+ <property file="${input}/ant.properties"/>
+ </ant>
+ </target>
+
+ <target name="testFileSeesExternalProperty" depends="makePropertiesFile">
+ <property name="a" value="x"/>
+ <ant antfile="antcall-test.xml" target="checkB">
+ <property name="expected" value="x"/>
+ <property file="${input}/ant.properties"/>
+ </ant>
+ </target>
+
+ <target name="testFileSeesInternalProperty" depends="makePropertiesFile">
+ <ant antfile="antcall-test.xml" target="checkB">
+ <property name="a" value="y"/>
+ <property name="expected" value="y"/>
+ <property file="${input}/ant.properties"/>
+ </ant>
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/antcall-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/antcall-test.xml
new file mode 100644
index 00000000..9767185d
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/antcall-test.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="antunit" xmlns:au="antlib:org.apache.ant.antunit">
+ <import file="../antunit-base.xml" />
+
+ <target name="checkB">
+ <au:assertPropertyEquals name="b" value="${expected}"/>
+ </target>
+
+ <target name="testLastParamWins">
+ <antcall target="checkB">
+ <param name="b" value="1"/>
+ <param name="b" value="2"/>
+ <param name="expected" value="2"/>
+ </antcall>
+ </target>
+
+ <target name="makePropertiesFile">
+ <mkdir dir="${input}"/>
+ <echo file="${input}/ant.properties"><![CDATA[
+a=2
+b=$${a}
+]]></echo>
+ </target>
+
+ <target name="testPropertiesLoadedFromFile" depends="makePropertiesFile">
+ <antcall target="checkB">
+ <param name="expected" value="2"/>
+ <param file="${input}/ant.properties"/>
+ </antcall>
+ </target>
+
+ <target name="testFileSeesExternalProperty" depends="makePropertiesFile">
+ <property name="a" value="x"/>
+ <antcall target="checkB">
+ <param name="expected" value="x"/>
+ <param file="${input}/ant.properties"/>
+ </antcall>
+ </target>
+
+ <target name="testFileSeesInternalParam" depends="makePropertiesFile">
+ <antcall target="checkB">
+ <param name="a" value="y"/>
+ <param name="expected" value="y"/>
+ <param file="${input}/ant.properties"/>
+ </antcall>
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/apt-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/apt-test.xml
new file mode 100644
index 00000000..9b240011
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/apt-test.xml
@@ -0,0 +1,158 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="antunit" xmlns:au="antlib:org.apache.ant.antunit">
+ <import file="../antunit-base.xml" />
+ <!-- apt tests -->
+
+ <property name="build.dir" location="aptbuild" />
+ <property name="classes.dir" location="${build.dir}/classes" />
+ <property name="classes2.dir" location="${build.dir}/classes2" />
+ <property name="preprocess.dir" location="${build.dir}/source" />
+ <property name="src" location="apt" />
+
+ <property name="AptExample.class" location="${classes.dir}/AptExample.class" />
+
+ <macrodef name="assertCompiled">
+ <attribute name="file" />
+ <sequential >
+ <fail message="not found: @{file}">
+ <condition>
+ <not>
+ <available file="@{file}" />
+ </not>
+ </condition>
+ </fail>
+ </sequential>
+ </macrodef>
+
+ <macrodef name="assertProcessed">
+ <sequential>
+ <au:assertLogContains text="DistributedAnnotationProcessor-is-go"/>
+ <au:assertLogContains text="[-Abuild.dir="/>
+ <au:assertLogContains text="visiting DistributedAnnotationFactory"/>
+ </sequential>
+ </macrodef>
+
+ <presetdef name="assertAptExampleCompiled">
+ <assertCompiled file="${AptExample.class}"/>
+ </presetdef>
+
+ <target name="tearDown" depends="antunit-base.tearDown">
+ <delete dir="${build.dir}"/>
+ </target>
+
+ <target name="setUp">
+ <mkdir dir="${classes.dir}"/>
+ <mkdir dir="${classes2.dir}"/>
+ <mkdir dir="${preprocess.dir}"/>
+ </target>
+
+ <target name="testApt" depends="setUp" unless="jdk1.8+">
+ <apt srcdir="${src}"
+ destdir="${classes.dir}"
+ debug="on"
+ compile="true"
+ preprocessdir="${preprocess.dir}">
+ </apt>
+ <assertAptExampleCompiled />
+ </target>
+
+ <target name="testAptFork" depends="setUp" unless="jdk1.8+">
+ <apt srcdir="${src}"
+ destdir="${classes.dir}"
+ debug="on"
+ compile="true"
+ fork="true"
+ preprocessdir="${preprocess.dir}">
+ </apt>
+ <assertAptExampleCompiled />
+ </target>
+
+ <target name="testAptForkFalse" depends="setUp" unless="jdk1.8+">
+ <apt srcdir="${src}"
+ destdir="${classes.dir}"
+ debug="on"
+ compile="true"
+ fork="false"
+ preprocessdir="${preprocess.dir}">
+ </apt>
+ <assertAptExampleCompiled />
+ <au:assertLogContains text="Apt only runs in its own JVM; fork=false option ignored"/>
+
+ </target>
+
+ <target name="testListAnnotationTypes" depends="setUp" unless="jdk1.8+">
+ <apt srcdir="${src}"
+ destdir="${classes.dir}"
+ debug="on"
+ compile="true"
+ preprocessdir="${preprocess.dir}">
+ <compilerarg value="-XListAnnotationTypes" />
+ <compilerarg value="-Xlint:deprecation" />
+ </apt>
+
+ <assertAptExampleCompiled />
+ <au:assertLogContains text="Set of annotations found:"/>
+ <au:assertLogContains text="Distributed"/>
+ </target>
+
+
+ <!-- use the factory we compiled. To avoid trouble
+ we deliver into a version in a new classpath, otherwise
+ the dependency logic will not run Apt-->
+ <target name="testAptNewFactory" depends="testApt" unless="jdk1.8+">
+ <apt srcdir="${src}"
+ destdir="${classes2.dir}"
+ debug="on"
+ compile="true"
+ factory="DistributedAnnotationFactory"
+ preprocessdir="${preprocess.dir}">
+ <factorypath path="${classes.dir}" />
+ <option name="build.dir" value="${build.dir}" />
+ </apt>
+ <assertAptExampleCompiled />
+ <assertProcessed />
+ </target>
+
+ <target name="testAptNewFactoryFork" depends="testApt" unless="jdk1.8+">
+ <apt srcdir="${src}"
+ destdir="${classes2.dir}"
+ debug="on"
+ compile="true"
+ fork="true"
+ factory="DistributedAnnotationFactory"
+ preprocessdir="${preprocess.dir}">
+ <factorypath path="${classes.dir}" />
+ <option name="build.dir" value="${build.dir}" />
+ </apt>
+ <assertAptExampleCompiled />
+ <assertProcessed />
+ </target>
+
+ <target name="testAptUnderJDK18" if="jdk1.8+">
+ <au:expectfailure expectedMessage="apt does not exist under Java 1.8 and higher">
+ <apt srcdir="${src}"
+ destdir="${classes.dir}"
+ debug="on"
+ compile="true"
+ fork="true"
+ preprocessdir="${preprocess.dir}">
+ </apt>
+ </au:expectfailure>
+ </target>
+</project> \ No newline at end of file
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/apt/AptExample.java b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/apt/AptExample.java
new file mode 100644
index 00000000..9d6fcba8
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/apt/AptExample.java
@@ -0,0 +1,25 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+/**
+ */
+@Distributed(
+ protocol="CORBA",
+ distribution=Distributed.DistributionTypes.FEDERATED
+ )
+public class AptExample {
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/apt/Distributed.java b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/apt/Distributed.java
new file mode 100644
index 00000000..ebc3467a
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/apt/Distributed.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+import java.lang.annotation.Annotation;
+import java.lang.annotation.Target;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ */
+@Documented
+@Retention(value = RetentionPolicy.RUNTIME)
+@Target(value = ElementType.TYPE)
+public @interface Distributed {
+
+ public DistributionTypes distribution() default DistributionTypes.LOCAL;
+
+ public String protocol() default "RMI";
+
+ public enum DistributionTypes { SINGLETON, LOCAL, FAULT_TOLERANT, FEDERATED, MOBILE};
+
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/apt/DistributedAnnotationFactory.java b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/apt/DistributedAnnotationFactory.java
new file mode 100644
index 00000000..a8fb6331
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/apt/DistributedAnnotationFactory.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+import com.sun.mirror.apt.AnnotationProcessorFactory;
+import com.sun.mirror.apt.AnnotationProcessor;
+import com.sun.mirror.apt.AnnotationProcessorEnvironment;
+
+import java.util.Collection;
+import java.util.Set;
+import java.util.Arrays;
+import java.util.Collections;
+
+
+/**
+ * This was the first piece of Java1.5 code in the source tree.
+ * @since 20050-03-09T21:29:25Z
+ */
+public class DistributedAnnotationFactory implements AnnotationProcessorFactory {
+
+ private static final Collection<String> supportedAnnotations
+ = Collections.unmodifiableCollection(Arrays.asList("*"));
+
+ public Collection<String> supportedOptions() {
+ return Collections.emptySet();
+ }
+
+ public Collection<String> supportedAnnotationTypes() {
+ return supportedAnnotations;
+ }
+
+ public AnnotationProcessor getProcessorFor(
+ Set<com.sun.mirror.declaration.AnnotationTypeDeclaration> annotationTypeDeclarations,
+ AnnotationProcessorEnvironment env) {
+ return new DistributedAnnotationProcessor(env);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/apt/DistributedAnnotationProcessor.java b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/apt/DistributedAnnotationProcessor.java
new file mode 100644
index 00000000..f94ff7f7
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/apt/DistributedAnnotationProcessor.java
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+//found in tools.jar, not the JRE runtime.
+import com.sun.mirror.apt.AnnotationProcessor;
+import com.sun.mirror.apt.AnnotationProcessorEnvironment;
+import com.sun.mirror.declaration.TypeDeclaration;
+import com.sun.mirror.declaration.ClassDeclaration;
+import com.sun.mirror.util.SimpleDeclarationVisitor;
+import static com.sun.mirror.util.DeclarationVisitors.*;
+
+import java.util.Map;
+
+/**
+ * Annotation processor outputs stuff
+ */
+
+public class DistributedAnnotationProcessor implements AnnotationProcessor {
+
+ public AnnotationProcessorEnvironment env;
+
+ public DistributedAnnotationProcessor(AnnotationProcessorEnvironment env) {
+ this.env = env;
+ }
+
+ public void echo(String text) {
+ env.getMessager().printNotice(text);
+ }
+
+ public void process() {
+ echo("DistributedAnnotationProcessor-is-go");
+
+ Map<String, String> options=env.getOptions();
+ for(String key:options.keySet()) {
+ echo("Option ["+key+"] = "+options.get(key));
+ }
+
+ //work time
+ for (TypeDeclaration typeDecl : env.getSpecifiedTypeDeclarations()) {
+ typeDecl.accept(getDeclarationScanner(new ClassVisitor(),
+ NO_OP));
+ }
+ }
+
+ private class ClassVisitor extends SimpleDeclarationVisitor {
+ public void visitClassDeclaration(ClassDeclaration d) {
+ echo("visiting "+ d.getQualifiedName());
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/augment-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/augment-test.xml
new file mode 100644
index 00000000..2e6f3354
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/augment-test.xml
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="augment-test" default="antunit" xmlns:au="antlib:org.apache.ant.antunit">
+ <import file="../antunit-base.xml"/>
+
+ <target name="setUp">
+ <mkdir dir="${input}" />
+ <touch>
+ <filelist id="filelist" dir="${input}" files="foo,bar,baz" />
+ </touch>
+ <fileset id="input-fs" dir="${input}" />
+ <au:assertTrue>
+ <resourcecount refid="input-fs" count="3" />
+ </au:assertTrue>
+ </target>
+
+ <target name="test-augment-attribute" depends="setUp">
+ <augment id="input-fs" excludes="foo" />
+ <au:assertTrue>
+ <resourcecount refid="input-fs" count="2" />
+ </au:assertTrue>
+ </target>
+
+ <target name="test-augment-element" depends="setUp">
+ <augment id="input-fs">
+ <filename name="bar" />
+ </augment>
+ <au:assertTrue>
+ <resourcecount refid="input-fs" count="1" />
+ </au:assertTrue>
+ </target>
+
+ <target name="test-noref">
+ <au:expectfailure expectedMessage="Unknown reference &quot;nosuchreference&quot;">
+ <augment id="nosuchreference" />
+ </au:expectfailure>
+ </target>
+
+ <target name="test-id-not-set">
+ <au:expectfailure expectedMessage="augment attribute 'id' unset">
+ <augment foo="bar" />
+ </au:expectfailure>
+ </target>
+
+ <target name="test-illegal-attribute" depends="setUp">
+ <au:expectfailure expectedMessage="augmented reference &quot;input-fs&quot; doesn't support the &quot;filesetwillmostlikelyneversupportthisattribute&quot; attribute">
+ <augment id="input-fs" filesetwillmostlikelyneversupportthisattribute="blah" />
+ </au:expectfailure>
+ </target>
+
+ <target name="test-illegal-element" depends="setUp">
+ <au:expectfailure expectedMessage="augmented reference &quot;input-fs&quot; doesn't support the nested &quot;filesetwillmostlikelyneversupportthiselement&quot; element">
+ <augment id="input-fs">
+ <filesetwillmostlikelyneversupportthiselement />
+ </augment>
+ </au:expectfailure>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/broken_cd.zip b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/broken_cd.zip
new file mode 100644
index 00000000..721fb450
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/broken_cd.zip
Binary files differ
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/bunzip2-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/bunzip2-test.xml
new file mode 100644
index 00000000..a9ca4237
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/bunzip2-test.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="antunit" xmlns:au="antlib:org.apache.ant.antunit">
+ <import file="../antunit-base.xml" />
+
+ <target name="testExpandArchiveWithMultipleStreams">
+ <mkdir dir="${output}"/>
+ <bunzip2 src="bzip2/multiple.bz2" dest="${output}"/>
+ <au:assertFilesMatch expected="bzip2/expected"
+ actual="${output}/multiple"/>
+ </target>
+
+</project> \ No newline at end of file
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/bzip2/expected b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/bzip2/expected
new file mode 100644
index 00000000..9ae9e86b
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/bzip2/expected
@@ -0,0 +1 @@
+ab \ No newline at end of file
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/bzip2/multiple.bz2 b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/bzip2/multiple.bz2
new file mode 100644
index 00000000..26dc3a75
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/bzip2/multiple.bz2
Binary files differ
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/checksum-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/checksum-test.xml
new file mode 100644
index 00000000..8341f425
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/checksum-test.xml
@@ -0,0 +1,83 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="antunit" xmlns:au="antlib:org.apache.ant.antunit">
+ <import file="../antunit-base.xml" />
+
+ <target name="testChecksumConditionWithFileSet">
+ <mkdir dir="${output}"/>
+ <checksum todir="${output}">
+ <fileset dir="."/>
+ </checksum>
+ <condition property="checksumsMatch">
+ <checksum todir="${output}">
+ <fileset dir="."/>
+ </checksum>
+ </condition>
+ <au:assertPropertySet name="checksumsMatch"/>
+ </target>
+
+ <target name="testTotalPropertyAcrossPlatforms"
+ description="testcase for
+ https://issues.apache.org/bugzilla/show_bug.cgi?id=36748">
+ <mkdir dir="${input}"/>
+ <echo file="${input}/a.txt">abc</echo>
+ <echo file="${input}/subdir/A.txt">def</echo>
+ <echo file="${input}/B.txt">xyz</echo>
+ <checksum totalproperty="total">
+ <fileset dir="${input}"/>
+ </checksum>
+ <au:assertPropertyEquals name="total"
+ value="f4d688789d32e6ca6bc93c504dbc6b46"/>
+ </target>
+
+ <target name="testChecksumPattern2">
+ <mkdir dir="${output}"/>
+ <mkdir dir="${input}"/>
+ <echo file="${input}/a.txt">abc</echo>
+ <checksum todir="${output}" pattern="{2}">
+ <fileset dir="${input}"/>
+ </checksum>
+ <au:assertResourceContains
+ resource="${output}/a.txt.MD5"
+ value="../testinput/a.txt"/>
+ </target>
+
+ <target name="testChecksumPattern3">
+ <mkdir dir="${output}"/>
+ <checksum todir="${output}" pattern="{3}">
+ <fileset dir=".." includes="types/fileset-test.xml"/>
+ </checksum>
+ <au:assertResourceContains
+ resource="${output}/types/fileset-test.xml.MD5"
+ value="../types/fileset-test.xml"/>
+ </target>
+
+ <target name="testChecksumPattern4">
+ <mkdir dir="${output}"/>
+ <mkdir dir="${input}"/>
+ <property name="a" location="${input}/a.txt"/>
+ <echo file="${a}">abc</echo>
+ <checksum todir="${output}" pattern="{4}">
+ <fileset dir="${input}"/>
+ </checksum>
+ <au:assertResourceContains
+ resource="${output}/a.txt.MD5"
+ value="${a}"/>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/commandlauncher/commandlauncher-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/commandlauncher/commandlauncher-test.xml
new file mode 100644
index 00000000..49519bd8
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/commandlauncher/commandlauncher-test.xml
@@ -0,0 +1,87 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project xmlns:au="antlib:org.apache.ant.antunit" default="antunit">
+ <import file="../../antunit-base.xml" />
+
+ <target name="testCommandLauncherTask">
+ <echo message="${input}"/>
+ <mkdir dir="${input}"/>
+ <mkdir dir="${output}"/>
+ <echo file="${input}/MyCommandLauncher.java">
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.Execute;
+import org.apache.tools.ant.taskdefs.launcher.Java13CommandLauncher;
+
+public class MyCommandLauncher extends Java13CommandLauncher {
+ public MyCommandLauncher() throws NoSuchMethodException {
+ super();
+ }
+
+
+
+ @Override
+ public Process exec(Project project, String[] cmd, String[] env, File workingDir) throws IOException {
+ Process p = super.exec(project, cmd, env, workingDir);
+ System.out.println("Hello World From CommandLauncher");
+ return p;
+ }
+
+}
+
+ </echo>
+ <echo file="${input}/MyJavaExecutable.java">
+public class MyJavaExecutable {
+ public static void main(String[] args) {
+
+ }
+}
+
+ </echo>
+ <javac destdir="${output}"
+ srcdir="${input}"/>
+ <typedef
+ name="my-command-launcher"
+ classname="MyCommandLauncher" classpath="${output}"/>
+
+ <commandlauncher vmlauncher="true">
+ <my-command-launcher/>
+ </commandlauncher>
+
+ <condition property="java"
+ value="${java.home}/bin/java.exe"
+ else="${java.home}/bin/java">
+ <os family="dos"/>
+ </condition>
+
+ <exec executable="${java}" failonerror="true">
+ <arg value="-cp"/>
+ <arg value="${output}"/>
+ <arg value="MyJavaExecutable"/>
+ </exec>
+
+
+ <au:assertLogContains text="Hello World From CommandLauncher"/>
+ </target>
+
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/concat-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/concat-test.xml
new file mode 100644
index 00000000..4b285e38
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/concat-test.xml
@@ -0,0 +1,202 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="antunit" xmlns:au="antlib:org.apache.ant.antunit">
+ <import file="../antunit-base.xml" />
+
+ <target name="tearDown" depends="antunit-base.tearDown">
+ <delete file="concat.resources" />
+ </target>
+
+ <property name="encodeStringDest" location="${output}/encodeStringDest" />
+
+ <target name="testBinaryAppend">
+ <property name="binaryAppendDest" location="${output}/binaryAppendDest" />
+ <mkdir dir="${output}" />
+ <au:assertTrue message="prerequisite conditions unmet">
+ <length length="0">
+ <!-- allow for nonexistent OR zero-length: -->
+ <fileset file="${binaryAppendDest}" />
+ </length>
+ </au:assertTrue>
+ <echo file="${binaryAppendDest}">x</echo>
+ <au:assertTrue message="destfile setup failed">
+ <length length="1" file="${binaryAppendDest}" />
+ </au:assertTrue>
+ <concat append="true" destfile="${binaryAppendDest}" binary="true">
+ <string value="x" />
+ </concat>
+ <au:assertTrue message="expected length 2">
+ <length file="${binaryAppendDest}" length="2" />
+ </au:assertTrue>
+ </target>
+
+ <target name="testStringEncoding" if="os.unix">
+ <property name="br" value="${line.separator}" />
+ <concat destfile="${encodeStringDest}" outputEncoding="utf-16">foo${br}bar${br}baz${br}</concat>
+ <au:assertTrue>
+ <resourcesmatch astext="true">
+ <file file="utf-16.expected" />
+ <file file="${encodeStringDest}" />
+ </resourcesmatch>
+ </au:assertTrue>
+ </target>
+
+ <target name="testStringEncodingWindows" if="os.windows">
+ <property name="br" value="${line.separator}" />
+ <concat destfile="${encodeStringDest}" outputEncoding="utf-16">foo${br}bar${br}baz${br}</concat>
+ <au:assertTrue>
+ <resourcesmatch astext="true">
+ <file file="utf-16.expected.windows" />
+ <file file="${encodeStringDest}" />
+ </resourcesmatch>
+ </au:assertTrue>
+ </target>
+
+ <target name="testDoNotFixNestedText" description="Bugzilla 42369">
+ <au:assertTrue>
+ <resourcesmatch>
+ <string>foo</string>
+ <concat fixlastline="true">foo</concat>
+ </resourcesmatch>
+ </au:assertTrue>
+ </target>
+
+ <target name="-fixlastline-setup">
+ <mkdir dir="${input}"/>
+ <mkdir dir="${output}"/>
+ <echo file="${input}/1">1</echo>
+ <echo file="${input}/2">2</echo>
+ </target>
+
+ <target name="testFixLastLineActuallyFixes" depends="-fixlastline-setup">
+ <au:assertTrue>
+ <resourcesmatch>
+ <string>1${line.separator}2${line.separator}</string>
+ <concat fixlastline="true">
+ <filelist dir="${input}">
+ <file name="1"/>
+ <file name="2"/>
+ </filelist>
+ </concat>
+ </resourcesmatch>
+ </au:assertTrue>
+ </target>
+
+ <target name="testFixLastLineActuallyFixesWithFilterChain"
+ depends="-fixlastline-setup"
+ description="https://issues.apache.org/bugzilla/show_bug.cgi?id=54672">
+ <au:assertTrue>
+ <resourcesmatch>
+ <string>1${line.separator}2${line.separator}</string>
+ <concat fixlastline="true">
+ <filelist dir="${input}">
+ <file name="1"/>
+ <file name="2"/>
+ </filelist>
+ <filterchain>
+ <tokenfilter>
+ <ignoreblank/>
+ </tokenfilter>
+ </filterchain>
+ </concat>
+ </resourcesmatch>
+ </au:assertTrue>
+ </target>
+
+ <target name="testIgnoreEmptyFalseFileIsCreated">
+ <mkdir dir="${input}" />
+ <mkdir dir="${output}" />
+ <concat destfile="${output}/TESTDEST" append="true" ignoreEmpty="false">
+ <filelist dir="${input}" files="thisfiledoesnotexist" />
+ </concat>
+ <au:assertFileExists file="${output}/TESTDEST" />
+ </target>
+
+ <target name="testIgnoreEmptyTrueFileIsNotCreated">
+ <mkdir dir="${input}" />
+ <mkdir dir="${output}" />
+ <concat destfile="${output}/TESTDEST" append="true" ignoreEmpty="true">
+ <filelist dir="${input}" files="thisfiledoesnotexist" />
+ </concat>
+ <au:assertFileDoesntExist file="${output}/TESTDEST" />
+ </target>
+
+ <target name="testIgnoreEmptyFalseFileIsCreatedIncludesHeader">
+ <mkdir dir="${input}" />
+ <mkdir dir="${output}" />
+ <concat destfile="${output}/TESTDEST" ignoreEmpty="false">
+ <filelist dir="${input}" files="thisfiledoesnotexist" />
+ <header filtering="false" trim="yes">
+ header
+ </header>
+ </concat>
+ <au:assertFileExists file="${output}/TESTDEST" />
+ <au:assertResourceContains resource="${output}/TESTDEST" value="header" />
+ </target>
+
+ <target name="testIgnoreEmptyFalseFileIsCreatedIncludesFooter">
+ <mkdir dir="${input}" />
+ <mkdir dir="${output}" />
+ <concat destfile="${output}/TESTDEST" ignoreEmpty="false">
+ <filelist dir="${input}" files="thisfiledoesnotexist" />
+ <footer filtering="no">footer</footer>
+ </concat>
+ <au:assertFileExists file="${output}/TESTDEST" />
+ <au:assertResourceContains resource="${output}/TESTDEST" value="footer" />
+ </target>
+
+ <target name="testResources">
+ <string id="s1">The Quick Brown Fox</string>
+ <string id="s2">Jumped Over The Lazy Dog.</string>
+
+ <concat destfile="concat.resources" binary="true">
+ <resource refid="s1" />
+ <resource refid="s2" />
+ </concat>
+ <length property="expected">
+ <resources>
+ <resource refid="s1" />
+ <resource refid="s2" />
+ </resources>
+ </length>
+ <length property="actual">
+ <file file="concat.resources" />
+ </length>
+ <fail>
+ <condition>
+ <or>
+ <equals arg1="${actual}" arg2="0" />
+ <not>
+ <equals arg1="${actual}" arg2="${expected}" />
+ </not>
+ </or>
+ </condition>
+ </fail>
+ </target>
+
+ <target name="testBug48816">
+ <concat>
+ <resources id="48816" />
+ <string value="x" />
+ </concat>
+ <au:assertTrue>
+ <resourcecount refid="48816" count="0" />
+ </au:assertTrue>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/condition/antversion-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/condition/antversion-test.xml
new file mode 100644
index 00000000..89c2d7eb
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/condition/antversion-test.xml
@@ -0,0 +1,70 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="antversion-test" default="all" basedir="." xmlns:au="antlib:org.apache.ant.antunit">
+
+ <target name="test-atleast">
+ <au:assertTrue message="Expected antversion of ${ant.version} to be at least 1.7.0">
+ <!-- AntVersion was introduced like AntUnit in 1.7 - so this must be true -->
+ <antversion atleast="1.7.0" />
+ </au:assertTrue>
+ </target>
+
+ <target name="test-exactly">
+ <antversion property="ant.actual.version" />
+ <au:assertTrue message="Expected antversion of ${ant.actual.version}">
+ <antversion exactly="${ant.actual.version}" />
+ </au:assertTrue>
+ </target>
+
+ <target name="test-atleast-fail">
+ <property name="version" value="1.8.9" />
+ <au:assertFalse>
+ <antversion atleast="1.1000.0" />
+ </au:assertFalse>
+ </target>
+
+ <target name="test-task">
+ <antversion property="antversion" />
+ <au:assertPropertySet name="antversion" message="Property 'antversion' should be set." />
+ <echo>AntVersion=${antversion}</echo>
+ </target>
+
+ <target name="test-property-conditional1">
+ <antversion property="antversion" atleast="2.0.0" />
+ <au:assertTrue message="Property 'antversion' should not be set because this is not Ant 2.0.0+.">
+ <not>
+ <isset property="antversion" />
+ </not>
+ </au:assertTrue>
+ </target>
+
+ <target name="test-property-conditional2">
+ <antversion property="antversion" atleast="1.7.0" />
+ <au:assertTrue message="Property 'antversion' should be set because we should have Ant 1.7.0+ (${ant.version}).">
+ <isset property="antversion" />
+ </au:assertTrue>
+ </target>
+
+ <target name="all">
+ <au:antunit>
+ <fileset file="${ant.file}" />
+ <au:plainlistener />
+ </au:antunit>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/condition/equals-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/condition/equals-test.xml
new file mode 100644
index 00000000..8888d396
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/condition/equals-test.xml
@@ -0,0 +1,80 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="equals-test" xmlns:au="antlib:org.apache.ant.antunit"
+ default="antunit">
+
+ <import file="../../antunit-base.xml" />
+
+ <target name="test-noforcestring">
+ <string id="s" value="foo" />
+ <au:assertFalse>
+ <equals arg1="foo" arg2="${ant.refid:s}" />
+ </au:assertFalse>
+ </target>
+
+ <target name="test-forcestring">
+ <string id="s" value="foo" />
+ <au:assertTrue>
+ <equals arg1="foo" arg2="${ant.refid:s}" forcestring="true" />
+ </au:assertTrue>
+ </target>
+
+ <target name="test-forcestring-notrim">
+ <string id="s" value=" foo " />
+ <au:assertFalse>
+ <equals arg1="foo" arg2="${ant.refid:s}" forcestring="true" />
+ </au:assertFalse>
+ </target>
+
+ <target name="test-forcestring-trim">
+ <string id="s" value=" foo " />
+ <au:assertTrue>
+ <equals arg1="foo" arg2="${ant.refid:s}" forcestring="true" trim="true" />
+ </au:assertTrue>
+ </target>
+
+ <target name="test-forcestring-cs">
+ <string id="s" value="Foo" />
+ <au:assertFalse>
+ <equals arg1="foo" arg2="${ant.refid:s}" forcestring="true" />
+ </au:assertFalse>
+ </target>
+
+ <target name="test-forcestring-nocs">
+ <string id="s" value="Foo" />
+ <au:assertTrue>
+ <equals arg1="foo" arg2="${ant.refid:s}" forcestring="true" casesensitive="false" />
+ </au:assertTrue>
+ </target>
+
+ <target name="test-forcestring-trim-cs">
+ <string id="s" value=" Foo " />
+ <au:assertFalse>
+ <equals arg1="foo" arg2="${ant.refid:s}" forcestring="true" trim="true" />
+ </au:assertFalse>
+ </target>
+
+ <target name="test-forcestring-trim-nocs">
+ <string id="s" value=" Foo " />
+ <au:assertTrue>
+ <equals arg1="foo" arg2="${ant.refid:s}" forcestring="true"
+ trim="true" casesensitive="false" />
+ </au:assertTrue>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/condition/filesmatch-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/condition/filesmatch-test.xml
new file mode 100644
index 00000000..67e7c00f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/condition/filesmatch-test.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="antunit" xmlns:au="antlib:org.apache.ant.antunit">
+ <import file="../../antunit-base.xml" />
+
+ <target name="setUp">
+ <mkdir dir="${input}"/>
+ </target>
+
+ <target name="testMatchWithSmallerFile2"
+ description="https://issues.apache.org/bugzilla/show_bug.cgi?id=48715"
+ depends="setUp">
+ <property name="file1" location="${input}/LS.properties"/>
+ <property name="file2" location="${input}/LS.properties.old"/>
+ <echo file="${file1}"><![CDATA[foo=foo
+bar=bar
+
+]]></echo>
+ <echo file="${file2}"><![CDATA[foo=foo
+]]></echo>
+ <au:assertFalse>
+ <filesmatch file1="${file1}" file2="${file2}" textfile="true"/>
+ </au:assertFalse>
+ </target>
+
+ <target name="testBinaryMatchWithSmallerFile2"
+ description="https://issues.apache.org/bugzilla/show_bug.cgi?id=48715"
+ depends="setUp">
+ <property name="file1" location="${input}/LS.properties"/>
+ <property name="file2" location="${input}/LS.properties.old"/>
+ <echo file="${file1}"><![CDATA[foo=foo
+bar=bar
+
+]]></echo>
+ <echo file="${file2}"><![CDATA[foo=foo
+]]></echo>
+ <au:assertFalse>
+ <filesmatch file1="${file1}" file2="${file2}" textfile="false"/>
+ </au:assertFalse>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/condition/hasfreespace-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/condition/hasfreespace-test.xml
new file mode 100644
index 00000000..01f18098
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/condition/hasfreespace-test.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="hasfreespace-test" default="all" basedir="." xmlns:au="antlib:org.apache.ant.antunit">
+
+ <available property="jdk6.available" classname="java.util.ServiceLoader" />
+
+ <property name="partition" value="${user.home}" />
+
+
+ <target name="test-not-enough-space-human" if="jdk6.available">
+ <au:assertFalse>
+ <hasfreespace partition="${partition}" needed="1P" />
+ </au:assertFalse>
+ </target>
+
+ <target name="test-enough-space-human" if="jdk6.available">
+ <au:assertTrue>
+ <hasfreespace partition="${partition}" needed="1K" />
+ </au:assertTrue>
+ </target>
+
+ <target name="test-not-enough-space" if="jdk6.available">
+ <property name="long.max-value" value="9223372036854775807" />
+ <au:assertFalse>
+ <hasfreespace partition="${partition}" needed="${long.max-value}" />
+ </au:assertFalse>
+ </target>
+
+ <target name="test-enough-space" if="jdk6.available">
+ <au:assertTrue>
+ <hasfreespace partition="${partition}" needed="1" />
+ </au:assertTrue>
+ </target>
+
+ <target name="all">
+ <au:antunit>
+ <fileset file="${ant.file}" />
+ <au:plainlistener />
+ </au:antunit>
+ </target>
+
+</project> \ No newline at end of file
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/condition/hasmethod-text.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/condition/hasmethod-text.xml
new file mode 100644
index 00000000..9ae9b323
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/condition/hasmethod-text.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="equals-test" xmlns:au="antlib:org.apache.ant.antunit"
+ default="antunit">
+
+ <import file="../../antunit-base.xml" />
+
+ <target name="test-missingclass">
+ <au:expectfailure
+ expectedMessage='class "org.example.somepackage.Foo" was not found'>
+ <condition property="foo">
+ <hasmethod classname="org.example.somepackage.Foo"
+ method="bar"/>
+ </condition>
+ </au:expectfailure>
+ </target>
+
+ <target name="test-missingclass-no-sysclasspath">
+ <au:expectfailure
+ expectedMessage='class "org.example.somepackage.Foo" was not found'>
+ <condition property="foo">
+ <hasmethod classname="org.example.somepackage.Foo"
+ ignoreSystemClasses="true"
+ method="bar"/>
+ </condition>
+ </au:expectfailure>
+ </target>
+
+ <target name="test-restricted-class">
+ <au:assertFalse>
+ <hasmethod classname="java.lang.String"
+ method="bar"/>
+ </au:assertFalse>
+ </target>
+
+ <target name="test-restricted-class-no-sysclasspath">
+ <au:expectfailure
+ expectedMessage='class "java.lang.String" was found but a SecurityException has been raised while loading it'>
+ <condition property="foo">
+ <hasmethod classname="java.lang.String"
+ classpath="${java.home}/lib/rt.jar"
+ ignoreSystemClasses="true"
+ method="bar"/>
+ </condition>
+ </au:expectfailure>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/condition/islastmodified-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/condition/islastmodified-test.xml
new file mode 100644
index 00000000..429e3f81
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/condition/islastmodified-test.xml
@@ -0,0 +1,118 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project xmlns:au="antlib:org.apache.ant.antunit" default="antunit"
+ xmlns:cond="antlib:org.apache.tools.ant.types.conditions">
+
+ <import file="../../antunit-base.xml"/>
+
+ <target name="setUp">
+ <mkdir dir="${output}"/>
+ <property name="file" location="${output}/test.txt"/>
+ <touch file="${file}" dateTime="08/18/2009 04:41:20 AM"/>
+ </target>
+
+ <target name="testEquals" depends="setUp">
+ <au:assertFalse>
+ <cond:islastmodified dateTime="08/18/2009 04:41:19 AM">
+ <file file="${file}"/>
+ </cond:islastmodified>
+ </au:assertFalse>
+ <au:assertTrue>
+ <cond:islastmodified dateTime="08/18/2009 04:41:20 AM">
+ <file file="${file}"/>
+ </cond:islastmodified>
+ </au:assertTrue>
+ <au:assertFalse>
+ <cond:islastmodified dateTime="08/18/2009 04:41:21 AM">
+ <file file="${file}"/>
+ </cond:islastmodified>
+ </au:assertFalse>
+ </target>
+
+ <target name="testBefore" depends="setUp">
+ <au:assertFalse>
+ <cond:islastmodified dateTime="08/18/2009 04:41:19 AM" mode="before">
+ <file file="${file}"/>
+ </cond:islastmodified>
+ </au:assertFalse>
+ <au:assertFalse>
+ <cond:islastmodified dateTime="08/18/2009 04:41:20 AM" mode="before">
+ <file file="${file}"/>
+ </cond:islastmodified>
+ </au:assertFalse>
+ <au:assertTrue>
+ <cond:islastmodified dateTime="08/18/2009 04:41:21 AM" mode="before">
+ <file file="${file}"/>
+ </cond:islastmodified>
+ </au:assertTrue>
+ </target>
+
+ <target name="testAfter" depends="setUp">
+ <au:assertTrue>
+ <cond:islastmodified dateTime="08/18/2009 04:41:19 AM" mode="after">
+ <file file="${file}"/>
+ </cond:islastmodified>
+ </au:assertTrue>
+ <au:assertFalse>
+ <cond:islastmodified dateTime="08/18/2009 04:41:20 AM" mode="after">
+ <file file="${file}"/>
+ </cond:islastmodified>
+ </au:assertFalse>
+ <au:assertFalse>
+ <cond:islastmodified dateTime="08/18/2009 04:41:21 AM" mode="after">
+ <file file="${file}"/>
+ </cond:islastmodified>
+ </au:assertFalse>
+ </target>
+
+ <target name="testNotBefore" depends="setUp">
+ <au:assertTrue>
+ <cond:islastmodified dateTime="08/18/2009 04:41:19 AM" mode="not-before">
+ <file file="${file}"/>
+ </cond:islastmodified>
+ </au:assertTrue>
+ <au:assertTrue>
+ <cond:islastmodified dateTime="08/18/2009 04:41:20 AM" mode="not-before">
+ <file file="${file}"/>
+ </cond:islastmodified>
+ </au:assertTrue>
+ <au:assertFalse>
+ <cond:islastmodified dateTime="08/18/2009 04:41:21 AM" mode="not-before">
+ <file file="${file}"/>
+ </cond:islastmodified>
+ </au:assertFalse>
+ </target>
+
+ <target name="testNotAfter" depends="setUp">
+ <au:assertFalse>
+ <cond:islastmodified dateTime="08/18/2009 04:41:19 AM" mode="not-after">
+ <file file="${file}"/>
+ </cond:islastmodified>
+ </au:assertFalse>
+ <au:assertTrue>
+ <cond:islastmodified dateTime="08/18/2009 04:41:20 AM" mode="not-after">
+ <file file="${file}"/>
+ </cond:islastmodified>
+ </au:assertTrue>
+ <au:assertTrue>
+ <cond:islastmodified dateTime="08/18/2009 04:41:21 AM" mode="not-after">
+ <file file="${file}"/>
+ </cond:islastmodified>
+ </au:assertTrue>
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/condition/resourcecontains-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/condition/resourcecontains-test.xml
new file mode 100644
index 00000000..11c6a9ed
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/condition/resourcecontains-test.xml
@@ -0,0 +1,139 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="resourcecontains-test" default="antunit" xmlns:au="antlib:org.apache.ant.antunit">
+
+ <import file="../../antunit-base.xml"/>
+
+ <target name="setUp">
+ <mkdir dir="${output}"/>
+ <property name="file" location="${output}/test-resource.txt"/>
+ <echo file="${file}" message="loads of text!"/>
+ </target>
+
+ <target name="testcontains">
+ <au:assertTrue message="Should have found the text in the resource">
+ <resourcecontains resource="${file}" substring="text"/>
+ </au:assertTrue>
+ </target>
+
+ <target name="testContainsLowerNonCS">
+ <echo file="${file}" message="LOADS OF TEXT!"/>
+ <au:assertTrue message="Should have found the text in the resource">
+ <resourcecontains resource="${file}" substring="text"
+ casesensitive="false"/>
+ </au:assertTrue>
+ </target>
+
+ <target name="testContainsUpperNonCS">
+ <au:assertTrue message="Should have found the text in the resource">
+ <resourcecontains resource="${file}" substring="TEXT"
+ casesensitive="false"/>
+ </au:assertTrue>
+ </target>
+
+ <target name="testContainsEmptyString">
+ <au:assertTrue message="Should have found the text in the resource">
+ <resourcecontains resource="${file}" substring="" />
+ </au:assertTrue>
+ </target>
+
+ <target name="testContainsEmptyProperty">
+ <property name="testContainsEmptyProperty" value="" />
+ <au:assertTrue message="Should have found the text in the resource">
+ <resourcecontains resource="${file}"
+ substring="${testContainsEmptyProperty}" />
+ </au:assertTrue>
+ </target>
+
+ <target name="testwithemptyfile">
+ <truncate file="${file}"/>
+ <au:assertFalse message="Should have found nothing as file is empty">
+ <resourcecontains resource="${file}" substring="text"/>
+ </au:assertFalse>
+ </target>
+
+ <target name="testWithEmptyFileAndSubstring">
+ <truncate file="${file}"/>
+ <au:assertTrue message="Empty resource should contain empty string">
+ <resourcecontains resource="${file}" substring=""/>
+ </au:assertTrue>
+ </target>
+
+ <target name="testdoesntcontain">
+ <au:assertFalse message="Should have found nothing as file is empty">
+ <resourcecontains resource="${file}" substring="futurama"/>
+ </au:assertFalse>
+ </target>
+
+ <target name="testFileRefContains">
+ <file id="file" file="${file}" />
+ <au:assertTrue message="Should have found the text in the resource">
+ <resourcecontains refid="file" substring="text"/>
+ </au:assertTrue>
+ </target>
+
+ <target name="testStringRefContains">
+ <string id="string">loads of text!</string>
+ <au:assertTrue message="Should have found the text in the resource">
+ <resourcecontains refid="string" substring="text"/>
+ </au:assertTrue>
+ </target>
+
+ <target name="testTextConcatRefContains">
+ <resources id="concat">
+ <concat>loads of text!</concat>
+ </resources>
+ <au:assertTrue message="Should have found the text in the resource">
+ <resourcecontains refid="concat" substring="text"/>
+ </au:assertTrue>
+ </target>
+
+ <target name="testFileConcatRefContains">
+ <resources id="concat">
+ <concat><file file="${file}" /></concat>
+ </resources>
+ <au:assertTrue message="Should have found the text in the resource">
+ <resourcecontains refid="concat" substring="text"/>
+ </au:assertTrue>
+ </target>
+
+ <target name="testMultiConcatRefContains">
+ <resources id="concat">
+ <concat>
+ <header>HEADER</header>
+ <footer>FOOTER</footer>
+ <string>foo</string>
+ <file file="${file}" />
+ <string>bar</string>
+ </concat>
+ </resources>
+ <au:assertTrue message="Should have found the text in the resource">
+ <resourcecontains refid="concat" substring="text"/>
+ </au:assertTrue>
+ </target>
+
+ <target name="testFirstRefContains">
+ <first id="first">
+ <fileset dir="${basedir}" includes="*-test.xml" />
+ </first>
+ <au:assertTrue message="Should have found the text in the resource">
+ <resourcecontains refid="first" substring="project"/>
+ </au:assertTrue>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/condition/resourceexists-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/condition/resourceexists-test.xml
new file mode 100644
index 00000000..bdf40c2a
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/condition/resourceexists-test.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project xmlns:au="antlib:org.apache.ant.antunit" default="antunit"
+ xmlns:cond="antlib:org.apache.tools.ant.types.conditions">
+
+ <import file="../../antunit-base.xml"/>
+
+ <target name="test-yes">
+ <au:assertTrue>
+ <cond:resourceexists>
+ <file file="resourceexists-test.xml"/>
+ </cond:resourceexists>
+ </au:assertTrue>
+ </target>
+
+ <target name="test-no">
+ <au:assertFalse>
+ <cond:resourceexists>
+ <file file="resourceexists-test-not-there.xml"/>
+ </cond:resourceexists>
+ </au:assertFalse>
+ </target>
+
+ <target name="testURL">
+ <au:assertTrue>
+ <cond:resourceexists>
+ <url url="http://ant.apache.org/index.html"/>
+ </cond:resourceexists>
+ </au:assertTrue>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/copy-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/copy-test.xml
new file mode 100644
index 00000000..51c6277c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/copy-test.xml
@@ -0,0 +1,471 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="antunit" xmlns:au="antlib:org.apache.ant.antunit">
+ <import file="../antunit-base.xml" />
+
+ <target name="-fileResourceSetup">
+ <mkdir dir="${input}"/>
+ <mkdir dir="${output}"/>
+ <touch file="${input}/file.txt"/>
+ </target>
+
+ <target name="testCopyFileFlatten" depends="-fileResourceSetup">
+ <au:assertFileDoesntExist file="${output}/file.txt"/>
+ <copy todir="${output}" flatten="true">
+ <file file="${input}/file.txt"/>
+ </copy>
+ <au:assertFileExists file="${output}/file.txt"/>
+ </target>
+
+ <target name="testCopyFileInResourcesFlatten" depends="-fileResourceSetup">
+ <au:assertFileDoesntExist file="${output}/file.txt"/>
+ <copy todir="${output}" flatten="true">
+ <resources>
+ <file file="${input}/file.txt"/>
+ </resources>
+ </copy>
+ <au:assertFileExists file="${output}/file.txt"/>
+ </target>
+
+ <target name="-setupNullByteStreamResource">
+ <mkdir dir="${input}"/>
+ <echo file="${input}/NullByteStreamResource.java"><![CDATA[
+import org.apache.tools.ant.types.Resource;
+import java.io.*;
+public class NullByteStreamResource extends Resource {
+ private long length = 1024;
+
+ public boolean isExists() {
+ return true;
+ }
+
+ public long getLastModified() {
+ return UNKNOWN_DATETIME;
+ }
+
+ public void setLength(long length) {
+ this.length = length;
+ }
+
+ public InputStream getInputStream() {
+ return new InputStream() {
+ int readSoFar = 0;
+
+ public int read() {
+ return readSoFar++ > length ? -1 : 0;
+ }
+ };
+ }
+}
+]]></echo>
+ <mkdir dir="${output}"/>
+ <javac srcdir="${input}" destdir="${output}"/>
+ <typedef name="nullstream" classname="NullByteStreamResource">
+ <classpath>
+ <pathelement location="${output}"/>
+ </classpath>
+ </typedef>
+ </target>
+
+ <target name="testResourceWithoutName"
+ depends="-setupNullByteStreamResource">
+ <au:expectfailure>
+ <copy todir="${output}">
+ <nullstream/>
+ </copy>
+ </au:expectfailure>
+ </target>
+
+ <target name="testResourceWithoutNameWithMergeMapper"
+ depends="-setupNullByteStreamResource">
+ <copy todir="${output}">
+ <nullstream/>
+ <mergemapper to="foo"/>
+ </copy>
+ <au:assertFileExists file="${output}/foo"/>
+ </target>
+
+ <target name="testMappedResources">
+ <mkdir dir="${input}"/>
+ <mkdir dir="${output}"/>
+ <echo file="${input}/foo.txt">Hello, world!</echo>
+ <copy todir="${output}">
+ <mappedresources>
+ <fileset dir="${input}"/>
+ <globmapper from="foo.*" to="bar.*"/>
+ </mappedresources>
+ </copy>
+ <au:assertFileDoesntExist file="${output}/foo.txt"/>
+ <au:assertFileExists file="${output}/bar.txt"/>
+ <au:assertFilesMatch expected="${input}/foo.txt"
+ actual="${output}/bar.txt"/>
+ </target>
+
+ <target name="testMappedResourcesMultipleTrue">
+ <mkdir dir="${input}"/>
+ <mkdir dir="${output}"/>
+ <echo file="${input}/foo.txt">Hello, world!</echo>
+ <copy todir="${output}">
+ <mappedresources enableMultipleMappings="true">
+ <fileset dir="${input}"/>
+ <compositemapper>
+ <globmapper from="foo.*" to="bar.*"/>
+ <globmapper from="foo.*" to="baz.*"/>
+ </compositemapper>
+ </mappedresources>
+ </copy>
+ <au:assertFileDoesntExist file="${output}/foo.txt"/>
+ <au:assertFileExists file="${output}/bar.txt"/>
+ <au:assertFileExists file="${output}/baz.txt"/>
+ <au:assertFilesMatch expected="${input}/foo.txt"
+ actual="${output}/bar.txt"/>
+ <au:assertFilesMatch expected="${input}/foo.txt"
+ actual="${output}/baz.txt"/>
+ </target>
+
+ <target name="testMappedResourcesMultipleFalse">
+ <mkdir dir="${input}"/>
+ <mkdir dir="${output}"/>
+ <echo file="${input}/foo.txt">Hello, world!</echo>
+ <copy todir="${output}">
+ <mappedresources enableMultipleMappings="false">
+ <fileset dir="${input}"/>
+ <compositemapper>
+ <globmapper from="foo.*" to="bar.*"/>
+ <globmapper from="foo.*" to="baz.*"/>
+ </compositemapper>
+ </mappedresources>
+ </copy>
+ <au:assertFileDoesntExist file="${output}/foo.txt"/>
+ <au:assertFileExists file="${output}/bar.txt"/>
+ <au:assertFileDoesntExist file="${output}/baz.txt"/>
+ <au:assertFilesMatch expected="${input}/foo.txt"
+ actual="${output}/bar.txt"/>
+ </target>
+
+ <target name="testIncludeEmptyDirsDefaultsToTrue"
+ description="https://issues.apache.org/bugzilla/show_bug.cgi?id=47168">
+ <mkdir dir="${input}/foo"/>
+ <mkdir dir="${output}"/>
+ <copy todir="${output}">
+ <fileset dir="${input}"/>
+ </copy>
+ <au:assertFileExists file="${output}/foo"/>
+ </target>
+
+ <target name="XtestIncludeEmptyDirsAndZipfileset"
+ description="https://issues.apache.org/bugzilla/show_bug.cgi?id=47168">
+ <mkdir dir="${input}/foo"/>
+ <mkdir dir="${output}/final"/>
+ <zip destfile="${output}/zipfile.zip">
+ <fileset dir="${input}"/>
+ </zip>
+ <copy todir="${output}/final">
+ <zipfileset src="${output}/zipfile.zip"/>
+ </copy>
+ <au:assertFileExists file="${output}/final/foo"/>
+ </target>
+
+ <target name="testFailOnURLConnectionError"
+ description="https://issues.apache.org/bugzilla/show_bug.cgi?id=47362">
+ <mkdir dir="${output}"/>
+ <au:expectfailure>
+ <copy todir="${output}" failonerror="true" flatten="true">
+ <resources>
+ <url url="http://i-do-not-exist/"/>
+ </resources>
+ </copy>
+ </au:expectfailure>
+ </target>
+
+ <target name="testNotModifiedSelector"
+ description="https://issues.apache.org/bugzilla/show_bug.cgi?id=43574"
+ >
+ <mkdir dir="${input}/images"/>
+ <mkdir dir="${input}/cache"/>
+ <touch file="${input}/images/foo.jpg"/>
+ <mkdir dir="${output}"/>
+ <selector id="cache.selector">
+ <not>
+ <modified update="true"
+ seldirs="false"
+ cache="propertyfile"
+ algorithm="digest"
+ comparator="equal">
+ <param name="cache.cachefile"
+ value="${input}/cache/cache.properties"/>
+ <param name="algorithm.algorithm" value="MD5"/>
+ </modified>
+ </not>
+ </selector>
+ <au:assertFileDoesntExist file="${input}/cache/cache.properties"/>
+ <copy todir="${output}" overwrite="true">
+ <fileset dir="${input}/images">
+ <include name="*.jpg" />
+ <selector refid="cache.selector" />
+ </fileset>
+ </copy>
+ <au:assertFileExists file="${input}/cache/cache.properties"/>
+ <au:assertFileDoesntExist file="${output}/foo.jpg"/>
+ <copy todir="${output}" overwrite="true">
+ <fileset dir="${input}/images">
+ <include name="*.jpg" />
+ <selector refid="cache.selector" />
+ </fileset>
+ </copy>
+ <au:assertFileExists file="${output}/foo.jpg"/>
+ </target>
+
+ <target name="testMissingFileUsingFileAttribute">
+ <mkdir dir="${output}"/>
+ <mkdir dir="${input}"/>
+ <au:expectfailure expectedMessage="Could not find file">
+ <copy file="${input}/not-there.txt" todir="${output}"/>
+ </au:expectfailure>
+ <copy file="${input}/not-there.txt" todir="${output}"
+ failonerror="false"/>
+ </target>
+
+ <target name="testQuiet">
+ <mkdir dir="${output}"/>
+ <mkdir dir="${input}"/>
+ <copy file="${input}/not-there.txt" todir="${output}" failonerror="false" quiet="true" />
+ <au:assertLogDoesntContain text="Could not find file" />
+ </target>
+
+ <target name="testMissingFilesetRoot">
+ <mkdir dir="${output}"/>
+ <au:expectfailure expectedMessage="does not exist">
+ <copy todir="${output}">
+ <fileset dir="${input}">
+ <include name="not-there.txt"/>
+ </fileset>
+ </copy>
+ </au:expectfailure>
+ <copy todir="${output}" failonerror="false">
+ <fileset dir="${input}">
+ <include name="not-there.txt"/>
+ </fileset>
+ </copy>
+ </target>
+
+ <target name="testMissingFileUsingFilesetInclude"
+ description="https://issues.apache.org/bugzilla/show_bug.cgi?id=49070">
+ <mkdir dir="${output}"/>
+ <mkdir dir="${input}"/>
+ <au:expectfailure
+ expectedMessage="Cannot perform operation from directory to file.">
+ <copy tofile="${output}/foo.txt">
+ <fileset dir="${input}">
+ <include name="not-there.txt"/>
+ </fileset>
+ </copy>
+ </au:expectfailure>
+ <copy tofile="${output}/foo.txt" failonerror="false">
+ <fileset dir="${input}">
+ <include name="not-there.txt"/>
+ </fileset>
+ </copy>
+ </target>
+
+ <target name="testMissingFileUsingFilesetFilename"
+ description="https://issues.apache.org/bugzilla/show_bug.cgi?id=49070">
+ <mkdir dir="${output}"/>
+ <mkdir dir="${input}"/>
+ <au:expectfailure
+ expectedMessage="Cannot perform operation from directory to file.">
+ <copy tofile="${output}/foo.txt">
+ <fileset dir="${input}">
+ <filename name="not-there.txt"/>
+ </fileset>
+ </copy>
+ </au:expectfailure>
+ <copy tofile="${output}/foo.txt" failonerror="false">
+ <fileset dir="${input}">
+ <filename name="not-there.txt"/>
+ </fileset>
+ </copy>
+ </target>
+
+ <!-- stolen from ../types/readwrite-test.xml - create a read-only file -->
+ <property name="file" value="testfile"/>
+ <condition property="unix">
+ <os family="unix"/>
+ </condition>
+ <target name="createTestdir">
+ <mkdir dir="${output}"/>
+ <mkdir dir="${input}"/>
+ <touch file="${output}/${file}"/>
+ </target>
+ <target name="makeFileUnwritable"
+ depends="createTestdir,makeFileUnwritable-Unix,makeFileUnwritable-Windows"/>
+ <target name="makeFileUnwritable-Unix" id="unix">
+ <chmod file="${output}/${file}" perm="444"/>
+ </target>
+ <target name="makeFileUnwritable-Windows" unless="unix">
+ <attrib file="${output}/${file}" readonly="true"/>
+ </target>
+
+ <target name="testCopyOverReadOnlyFile" depends="makeFileUnwritable">
+ <sleep seconds="2"/>
+ <touch file="${input}/${file}"/>
+ <au:expectfailure
+ expectedMessage="can't write to read-only destination file ">
+ <copy toDir="${output}">
+ <fileset dir="${input}"/>
+ </copy>
+ </au:expectfailure>
+ </target>
+
+ <target name="testFilteredCopyOverReadOnlyFile" depends="makeFileUnwritable">
+ <sleep seconds="2"/>
+ <touch file="${input}/${file}"/>
+ <au:expectfailure
+ expectedMessage="can't write to read-only destination file ">
+ <copy toDir="${output}">
+ <fileset dir="${input}"/>
+ <filterset>
+ <filter token="foo" value="bar"/>
+ </filterset>
+ </copy>
+ </au:expectfailure>
+ </target>
+
+ <target name="testCopyOverReadOnlyFileWithOverwrite"
+ depends="makeFileUnwritable">
+ <touch file="${input}/${file}"/>
+ <au:expectfailure
+ expectedMessage="can't write to read-only destination file ">
+ <copy toDir="${output}" overwrite="true">
+ <fileset dir="${input}"/>
+ </copy>
+ </au:expectfailure>
+ </target>
+
+ <target name="testFilteredCopyOverReadOnlyFileWithOverwrite"
+ depends="makeFileUnwritable">
+ <touch file="${input}/${file}"/>
+ <au:expectfailure
+ expectedMessage="can't write to read-only destination file ">
+ <copy toDir="${output}" overwrite="true">
+ <fileset dir="${input}"/>
+ <filterset>
+ <filter token="foo" value="bar"/>
+ </filterset>
+ </copy>
+ </au:expectfailure>
+ </target>
+
+ <target name="testForcedCopyOverReadOnlyFile" depends="makeFileUnwritable">
+ <sleep seconds="2"/>
+ <touch file="${input}/${file}"/>
+ <copy toDir="${output}" force="true">
+ <fileset dir="${input}"/>
+ </copy>
+ </target>
+
+ <target name="testForcedFilteredCopyOverReadOnlyFile"
+ depends="makeFileUnwritable">
+ <sleep seconds="2"/>
+ <touch file="${input}/${file}"/>
+ <copy toDir="${output}" force="true">
+ <fileset dir="${input}"/>
+ <filterset>
+ <filter token="foo" value="bar"/>
+ </filterset>
+ </copy>
+ </target>
+
+ <target name="testForcedCopyOverReadOnlyFileWithOverwrite"
+ depends="makeFileUnwritable">
+ <touch file="${input}/${file}"/>
+ <copy toDir="${output}" overwrite="true" force="true">
+ <fileset dir="${input}"/>
+ </copy>
+ </target>
+
+ <target name="testForcedFilteredCopyOverReadOnlyFileWithOverwrite"
+ depends="makeFileUnwritable">
+ <touch file="${input}/${file}"/>
+ <copy toDir="${output}" overwrite="true" force="true">
+ <fileset dir="${input}"/>
+ <filterset>
+ <filter token="foo" value="bar"/>
+ </filterset>
+ </copy>
+ </target>
+
+ <target name="testCopyWithResourceAndFile"
+ description="https://issues.apache.org/bugzilla/show_bug.cgi?id=49756"
+ >
+ <mkdir dir="${input}"/>
+ <au:assertFileDoesntExist file="${input}/somefile"/>
+ <copy tofile="${input}/somefile">
+ <first>
+ <union>
+ <restrict>
+ <exists/>
+ <fileset file="${input}/somefile"/>
+ </restrict>
+ <string value="default contents"/>
+ </union>
+ </first>
+ </copy>
+ <au:assertFileExists file="${input}/somefile"/>
+ <au:assertResourceContains resource="${input}/somefile"
+ value="default contents"/>
+ <delete file="${input}/somefile"/>
+ <touch file="${input}/somefile"/>
+ <copy tofile="${input}/somefile">
+ <first>
+ <union>
+ <restrict>
+ <exists/>
+ <fileset file="${input}/somefile"/>
+ </restrict>
+ <string value="default contents"/>
+ </union>
+ </first>
+ </copy>
+ <au:assertFileExists file="${input}/somefile"/>
+ <au:assertResourceDoesntContain resource="${input}/somefile"
+ value="default contents"/>
+ </target>
+
+ <target name="testCopyDoesntDeleteReadonlyTargetWhenCopyFails"
+ description="https://issues.apache.org/bugzilla/show_bug.cgi?id=53095">
+ <mkdir dir="${input}"/>
+ <mkdir dir="${output}"/>
+ <touch file="${input}/somefile"/>
+ <touch file="${output}/somefile"/>
+ <exec executable="chmod" osfamily="unix">
+ <arg value="-w"/>
+ <arg file="${output}/somefile"/>
+ </exec>
+ <exec executable="attrib" osfamily="dos">
+ <arg value="+r"/>
+ <arg file="${output}/somefile"/>
+ </exec>
+ <au:expectfailure>
+ <copy todir="${output}" file="${input}/somefile"
+ overwrite="true"/>
+ </au:expectfailure>
+ <au:assertFileExists file="${input}/somefile"/>
+ <au:assertFileExists file="${output}/somefile"/>
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/cvs.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/cvs.xml
new file mode 100644
index 00000000..564e5875
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/cvs.xml
@@ -0,0 +1,169 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<!-- this file is not executed by the automated tests since it
+ requires a working CVS client. -->
+
+<project default="antunit" xmlns:au="antlib:org.apache.ant.antunit">
+ <import file="../../antunit-base.xml" />
+
+ <property name="cvsrootloc" location="repository"/>
+ <property name="cvsroot" value=":local:${cvsrootloc}"/>
+
+ <target name="testVersion">
+ <cvsversion clientversionproperty="client" cvsroot="${cvsroot}"/>
+ <au:assertPropertySet name="client"/>
+ </target>
+
+ <target name="testBug38583">
+ <mkdir dir="${output}"/>
+ <cvs cvsroot="${cvsroot}" package="antmodule1" dest="${output}"/>
+ <cvschangelog dir="${output}/antmodule1"
+ destfile="${output}/report.xml"/>
+ <au:assertFileExists file="${output}/report.xml"/>
+ </target>
+
+ <target name="testRemoteChangelog">
+ <mkdir dir="${output}"/>
+ <cvschangelog cvsroot="${cvsroot}" package="antmodule3"
+ remote="true"
+ destfile="${output}/report.xml"/>
+ <au:assertFileExists file="${output}/report.xml"/>
+ <au:assertResourceContains resource="${output}/report.xml"
+ value="[yet another test.txt]"/>
+ </target>
+
+ <target name="testRemoteChangelogNestedModule">
+ <mkdir dir="${output}"/>
+ <cvschangelog cvsroot="${cvsroot}"
+ remote="true"
+ destfile="${output}/report.xml">
+ <module name="antmodule3"/>
+ </cvschangelog>
+ <au:assertFileExists file="${output}/report.xml"/>
+ <au:assertResourceContains resource="${output}/report.xml"
+ value="[yet another test.txt]"/>
+ </target>
+
+ <target name="xtestRemoteChangelogStartTag">
+ <mkdir dir="${output}"/>
+ <cvschangelog cvsroot="${cvsroot}"
+ remote="true" startTag="testtag1"
+ destfile="${output}/report.xml">
+ <module name="antmodule3"/>
+ </cvschangelog>
+ <au:assertFileExists file="${output}/report.xml"/>
+ <au:assertResourceContains resource="${output}/report.xml"
+ value="[yet another test.txt]"/>
+ </target>
+
+ <target name="testRemoteChangelogEndTag">
+ <mkdir dir="${output}"/>
+ <cvschangelog cvsroot="${cvsroot}"
+ remote="true" endTag="testtag2"
+ destfile="${output}/report.xml">
+ <module name="antmodule3"/>
+ </cvschangelog>
+ <au:assertFileExists file="${output}/report.xml"/>
+ <au:assertResourceContains resource="${output}/report.xml"
+ value="[yet another test.txt]"/>
+ </target>
+
+ <target name="testRemoteChangelogWithTags">
+ <mkdir dir="${output}"/>
+ <cvschangelog cvsroot="${cvsroot}"
+ remote="true" endTag="testtag2" startTag="testtag1"
+ destfile="${output}/report.xml">
+ <module name="antmodule3"/>
+ </cvschangelog>
+ <au:assertFileExists file="${output}/report.xml"/>
+ <au:assertResourceContains resource="${output}/report.xml"
+ value="[yet another test.txt]"/>
+ </target>
+
+ <target name="xtestLocalChangelogStartTag">
+ <mkdir dir="${output}"/>
+ <cvs cvsroot="${cvsroot}" package="antmodule3" dest="${output}"/>
+ <cvschangelog dir="${output}/antmodule3"
+ remote="false" startTag="testtag1"
+ destfile="${output}/report.xml"/>
+ <au:assertFileExists file="${output}/report.xml"/>
+ <au:assertResourceContains resource="${output}/report.xml"
+ value="[yet another test.txt]"/>
+ </target>
+
+ <target name="testLocalChangelogEndTag">
+ <mkdir dir="${output}"/>
+ <cvs cvsroot="${cvsroot}" package="antmodule3" dest="${output}"/>
+ <cvschangelog dir="${output}/antmodule3"
+ remote="false" endTag="testtag2"
+ destfile="${output}/report.xml"/>
+ <au:assertFileExists file="${output}/report.xml"/>
+ <au:assertResourceContains resource="${output}/report.xml"
+ value="[yet another test.txt]"/>
+ </target>
+
+ <target name="testLocalChangelogWithTags">
+ <mkdir dir="${output}"/>
+ <cvs cvsroot="${cvsroot}" package="antmodule3" dest="${output}"/>
+ <cvschangelog dir="${output}/antmodule3"
+ remote="false" endTag="testtag2" startTag="testtag1"
+ destfile="${output}/report.xml"/>
+ <au:assertFileExists file="${output}/report.xml"/>
+ <au:assertResourceContains resource="${output}/report.xml"
+ value="[yet another test.txt]"/>
+ </target>
+
+ <target name="testCvsWithSpaceInModule">
+ <mkdir dir="${output}"/>
+ <cvs cvsroot="${cvsroot}" dest="${output}">
+ <module name="ant module 2"/>
+ </cvs>
+ <au:assertFileExists file="${output}/ant module 2/test.txt"/>
+ <cvschangelog dir="${output}/ant module 2"
+ destfile="${output}/report.xml"/>
+ <au:assertFileExists file="${output}/report.xml"/>
+ </target>
+
+ <target name="testCvsTagDiffWithSpaceInModule">
+ <mkdir dir="${output}"/>
+ <cvstagdiff cvsroot="${cvsroot}"
+ startDate="2008-01-01"
+ endDate="2009-01-01"
+ destfile="${output}/tagdiff.xml">
+ <module name="ant module 2"/>
+ </cvstagdiff>
+ <au:assertFileExists file="${output}/tagdiff.xml"/>
+ <au:assertResourceContains resource="${output}/tagdiff.xml"
+ value="[test.txt]"/>
+ </target>
+
+ <target name="testCvsTagDiffWithMultipleModules">
+ <mkdir dir="${output}"/>
+ <cvstagdiff cvsroot="${cvsroot}"
+ startDate="2008-01-01"
+ endDate="2009-01-01"
+ destfile="${output}/tagdiff.xml"
+ package="antmodule1 antmodule3"/>
+ <au:assertFileExists file="${output}/tagdiff.xml"/>
+ <au:assertResourceContains resource="${output}/tagdiff.xml"
+ value="[foo.txt]"/>
+ <au:assertResourceContains resource="${output}/tagdiff.xml"
+ value="[yet another test.txt]"/>
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/checkoutlist b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/checkoutlist
new file mode 100644
index 00000000..2921bffc
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/checkoutlist
@@ -0,0 +1,13 @@
+# The "checkoutlist" file is used to support additional version controlled
+# administrative files in $CVSROOT/CVSROOT, such as template files.
+#
+# The first entry on a line is a filename which will be checked out from
+# the corresponding RCS file in the $CVSROOT/CVSROOT directory.
+# The remainder of the line is an error message to use if the file cannot
+# be checked out.
+#
+# File format:
+#
+# [<whitespace>]<filename>[<whitespace><error message>]<end-of-line>
+#
+# comment lines begin with '#'
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/checkoutlist,v b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/checkoutlist,v
new file mode 100644
index 00000000..4f0410b6
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/checkoutlist,v
@@ -0,0 +1,37 @@
+head 1.1;
+access ;
+symbols ;
+locks ; strict;
+comment @# @;
+
+
+1.1
+date 2008.10.16.12.52.41; author stefan; state Exp;
+branches;
+next ;
+commitid f9748f739194567;
+
+desc
+@@
+
+
+
+1.1
+log
+@initial checkin@
+text
+@# The "checkoutlist" file is used to support additional version controlled
+# administrative files in $CVSROOT/CVSROOT, such as template files.
+#
+# The first entry on a line is a filename which will be checked out from
+# the corresponding RCS file in the $CVSROOT/CVSROOT directory.
+# The remainder of the line is an error message to use if the file cannot
+# be checked out.
+#
+# File format:
+#
+# [<whitespace>]<filename>[<whitespace><error message>]<end-of-line>
+#
+# comment lines begin with '#'
+@
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/commitinfo b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/commitinfo
new file mode 100644
index 00000000..3903ceec
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/commitinfo
@@ -0,0 +1,26 @@
+# The "commitinfo" file is used to control pre-commit checks.
+# The filter on the right is invoked with the repository and a list
+# of files to check. A non-zero exit of the filter program will
+# cause the commit to be aborted.
+#
+# The first entry on a line is a regular expression which is tested
+# against the directory that the change is being committed to, relative
+# to the $CVSROOT. For the first match that is found, then the remainder
+# of the line is the name of the filter to run.
+#
+# Format strings present in the filter will be replaced as follows:
+# %c = canonical name of the command being executed
+# %R = the name of the referrer, if any, otherwise the value NONE
+# %p = path relative to repository
+# %r = repository (path portion of $CVSROOT)
+# %{s} = file name, file name, ...
+#
+# If no format strings are present in the filter string, a default of
+# " %r %s" will be appended to the filter string, but this usage is
+# deprecated.
+#
+# If the repository name does not match any of the regular expressions in this
+# file, the "DEFAULT" line is used, if it is specified.
+#
+# If the name "ALL" appears as a regular expression it is always used
+# in addition to the first matching regex or "DEFAULT".
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/commitinfo,v b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/commitinfo,v
new file mode 100644
index 00000000..7cc0771c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/commitinfo,v
@@ -0,0 +1,50 @@
+head 1.1;
+access ;
+symbols ;
+locks ; strict;
+comment @# @;
+
+
+1.1
+date 2008.10.16.12.52.41; author stefan; state Exp;
+branches;
+next ;
+commitid f9748f739194567;
+
+desc
+@@
+
+
+
+1.1
+log
+@initial checkin@
+text
+@# The "commitinfo" file is used to control pre-commit checks.
+# The filter on the right is invoked with the repository and a list
+# of files to check. A non-zero exit of the filter program will
+# cause the commit to be aborted.
+#
+# The first entry on a line is a regular expression which is tested
+# against the directory that the change is being committed to, relative
+# to the $CVSROOT. For the first match that is found, then the remainder
+# of the line is the name of the filter to run.
+#
+# Format strings present in the filter will be replaced as follows:
+# %c = canonical name of the command being executed
+# %R = the name of the referrer, if any, otherwise the value NONE
+# %p = path relative to repository
+# %r = repository (path portion of $CVSROOT)
+# %{s} = file name, file name, ...
+#
+# If no format strings are present in the filter string, a default of
+# " %r %s" will be appended to the filter string, but this usage is
+# deprecated.
+#
+# If the repository name does not match any of the regular expressions in this
+# file, the "DEFAULT" line is used, if it is specified.
+#
+# If the name "ALL" appears as a regular expression it is always used
+# in addition to the first matching regex or "DEFAULT".
+@
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/config b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/config
new file mode 100644
index 00000000..50d85b5f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/config
@@ -0,0 +1,97 @@
+# Set `SystemAuth' to `no' if pserver shouldn't check system users/passwords.
+#SystemAuth=no
+
+# Set `LocalKeyword' to specify a local alias for a standard keyword.
+#LocalKeyword=MYCVS=CVSHeader
+
+# Set `KeywordExpand' to `i' followed by a list of keywords to expand or
+# `e' followed by a list of keywords to not expand.
+#KeywordExpand=iMYCVS,Name,Date
+#KeywordExpand=eCVSHeader
+
+# Set `TopLevelAdmin' to `yes' to create a CVS directory at the top
+# level of the new working directory when using the `cvs checkout'
+# command.
+#TopLevelAdmin=no
+
+# Put CVS lock files in this directory rather than directly in the repository.
+#LockDir=/var/lock/cvs
+
+# Set `LogHistory' to `all' or `TOEFWUPCGMAR' to log all transactions to the
+# history file, or a subset as needed (ie `TMAR' logs all write operations)
+#LogHistory=TOEFWUPCGMAR
+
+# Set `RereadLogAfterVerify' to `always' (the default) to allow the verifymsg
+# script to change the log message. Set it to `stat' to force CVS to verify
+# that the file has changed before reading it (this can take up to an extra
+# second per directory being committed, so it is not recommended for large
+# repositories. Set it to `never' (the previous CVS behavior) to prevent
+# verifymsg scripts from changing the log message.
+#RereadLogAfterVerify=always
+
+# Set `UserAdminOptions' to the list of `cvs admin' commands (options)
+# that users not in the `cvsadmin' group are allowed to run. This
+# defaults to `k', or only allowing the changing of the default
+# keyword expansion mode for files for users not in the `cvsadmin' group.
+# This value is ignored if the `cvsadmin' group does not exist.
+#
+# The following string would enable all `cvs admin' commands for all
+# users:
+#UserAdminOptions=aAbceIklLmnNostuU
+
+# Set `UseNewInfoFmtStrings' to `no' if you must support a legacy system by
+# enabling the deprecated old style info file command line format strings.
+# Be warned that these strings could be disabled in any new version of CVS.
+UseNewInfoFmtStrings=yes
+
+# Set `ImportNewFilesToVendorBranchOnly' to `yes' if you wish to force
+# every `cvs import' command to behave as if the `-X' flag was
+# specified.
+#ImportNewFilesToVendorBranchOnly=no
+
+# Set `PrimaryServer' to the CVSROOT to the primary, or write, server when
+# establishing one or more read-only mirrors which serve as proxies for
+# the write server in write mode or redirect the client to the primary for
+# write requests.
+#
+# For example:
+#
+# PrimaryServer=:fork:localhost/cvsroot
+
+# Set `MaxProxyBufferSize' to the the maximum allowable secondary
+# buffer memory cache size before the buffer begins being stored to disk, in
+# bytes. Must be a positive integer but may end in `k', `M', `G', or `T' (for
+# kiilo, mega, giga, & tera, respectively). If an otherwise valid number you
+# specify is greater than the SIZE_MAX defined by your system's C compiler,
+# then it will be resolved to SIZE_MAX without a warning. Defaults to 8M (8
+# megabytes).
+#
+# High values for MaxProxyBufferSize may speed up a secondary server
+# with old hardware and a lot of available memory but can actually slow a
+# modern system down slightly.
+#
+# For example:
+#
+# MaxProxyBufferSize=1G
+
+# Set `MaxCommentLeaderLength' to the maximum length permitted for the
+# automagically determined comment leader used when expanding the Log
+# keyword, in bytes. CVS's behavior when the automagically determined
+# comment leader exceeds this length is dependant on the value of
+# `UseArchiveCommentLeader' set in this file. `unlimited' is a valid
+# setting for this value. Defaults to 20 bytes.
+#
+# For example:
+#
+# MaxCommentLeaderLength=20
+
+# Set `UseArchiveCommentLeader' to `yes' to cause CVS to fall back on
+# the comment leader set in the RCS archive file, if any, when the
+# automagically determined comment leader exceeds `MaxCommentLeaderLength'
+# bytes. If `UseArchiveCommentLeader' is not set and a comment leader
+# greater than `MaxCommentLeaderLength' is calculated, the Log keyword
+# being examined will not be expanded. Defaults to `no'.
+#
+# For example:
+#
+# UseArchiveCommentLeader=no
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/config,v b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/config,v
new file mode 100644
index 00000000..d220b452
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/config,v
@@ -0,0 +1,121 @@
+head 1.1;
+access ;
+symbols ;
+locks ; strict;
+comment @# @;
+
+
+1.1
+date 2008.10.16.12.52.41; author stefan; state Exp;
+branches;
+next ;
+commitid f9748f739194567;
+
+desc
+@@
+
+
+
+1.1
+log
+@initial checkin@
+text
+@# Set `SystemAuth' to `no' if pserver shouldn't check system users/passwords.
+#SystemAuth=no
+
+# Set `LocalKeyword' to specify a local alias for a standard keyword.
+#LocalKeyword=MYCVS=CVSHeader
+
+# Set `KeywordExpand' to `i' followed by a list of keywords to expand or
+# `e' followed by a list of keywords to not expand.
+#KeywordExpand=iMYCVS,Name,Date
+#KeywordExpand=eCVSHeader
+
+# Set `TopLevelAdmin' to `yes' to create a CVS directory at the top
+# level of the new working directory when using the `cvs checkout'
+# command.
+#TopLevelAdmin=no
+
+# Put CVS lock files in this directory rather than directly in the repository.
+#LockDir=/var/lock/cvs
+
+# Set `LogHistory' to `all' or `TOEFWUPCGMAR' to log all transactions to the
+# history file, or a subset as needed (ie `TMAR' logs all write operations)
+#LogHistory=TOEFWUPCGMAR
+
+# Set `RereadLogAfterVerify' to `always' (the default) to allow the verifymsg
+# script to change the log message. Set it to `stat' to force CVS to verify
+# that the file has changed before reading it (this can take up to an extra
+# second per directory being committed, so it is not recommended for large
+# repositories. Set it to `never' (the previous CVS behavior) to prevent
+# verifymsg scripts from changing the log message.
+#RereadLogAfterVerify=always
+
+# Set `UserAdminOptions' to the list of `cvs admin' commands (options)
+# that users not in the `cvsadmin' group are allowed to run. This
+# defaults to `k', or only allowing the changing of the default
+# keyword expansion mode for files for users not in the `cvsadmin' group.
+# This value is ignored if the `cvsadmin' group does not exist.
+#
+# The following string would enable all `cvs admin' commands for all
+# users:
+#UserAdminOptions=aAbceIklLmnNostuU
+
+# Set `UseNewInfoFmtStrings' to `no' if you must support a legacy system by
+# enabling the deprecated old style info file command line format strings.
+# Be warned that these strings could be disabled in any new version of CVS.
+UseNewInfoFmtStrings=yes
+
+# Set `ImportNewFilesToVendorBranchOnly' to `yes' if you wish to force
+# every `cvs import' command to behave as if the `-X' flag was
+# specified.
+#ImportNewFilesToVendorBranchOnly=no
+
+# Set `PrimaryServer' to the CVSROOT to the primary, or write, server when
+# establishing one or more read-only mirrors which serve as proxies for
+# the write server in write mode or redirect the client to the primary for
+# write requests.
+#
+# For example:
+#
+# PrimaryServer=:fork:localhost/cvsroot
+
+# Set `MaxProxyBufferSize' to the the maximum allowable secondary
+# buffer memory cache size before the buffer begins being stored to disk, in
+# bytes. Must be a positive integer but may end in `k', `M', `G', or `T' (for
+# kiilo, mega, giga, & tera, respectively). If an otherwise valid number you
+# specify is greater than the SIZE_MAX defined by your system's C compiler,
+# then it will be resolved to SIZE_MAX without a warning. Defaults to 8M (8
+# megabytes).
+#
+# High values for MaxProxyBufferSize may speed up a secondary server
+# with old hardware and a lot of available memory but can actually slow a
+# modern system down slightly.
+#
+# For example:
+#
+# MaxProxyBufferSize=1G
+
+# Set `MaxCommentLeaderLength' to the maximum length permitted for the
+# automagically determined comment leader used when expanding the Log
+# keyword, in bytes. CVS's behavior when the automagically determined
+# comment leader exceeds this length is dependant on the value of
+# `UseArchiveCommentLeader' set in this file. `unlimited' is a valid
+# setting for this value. Defaults to 20 bytes.
+#
+# For example:
+#
+# MaxCommentLeaderLength=20
+
+# Set `UseArchiveCommentLeader' to `yes' to cause CVS to fall back on
+# the comment leader set in the RCS archive file, if any, when the
+# automagically determined comment leader exceeds `MaxCommentLeaderLength'
+# bytes. If `UseArchiveCommentLeader' is not set and a comment leader
+# greater than `MaxCommentLeaderLength' is calculated, the Log keyword
+# being examined will not be expanded. Defaults to `no'.
+#
+# For example:
+#
+# UseArchiveCommentLeader=no
+@
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/cvswrappers b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/cvswrappers
new file mode 100644
index 00000000..e989b754
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/cvswrappers
@@ -0,0 +1,19 @@
+# This file affects handling of files based on their names.
+#
+# The -m option specifies whether CVS attempts to merge files.
+#
+# The -k option specifies keyword expansion (e.g. -kb for binary).
+#
+# Format of wrapper file ($CVSROOT/CVSROOT/cvswrappers or .cvswrappers)
+#
+# wildcard [option value][option value]...
+#
+# where option is one of
+# -f from cvs filter value: path to filter
+# -t to cvs filter value: path to filter
+# -m update methodology value: MERGE or COPY
+# -k expansion mode value: b, o, kkv, &c
+#
+# and value is a single-quote delimited value.
+# For example:
+#*.gif -k 'b'
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/cvswrappers,v b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/cvswrappers,v
new file mode 100644
index 00000000..00bd795c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/cvswrappers,v
@@ -0,0 +1,43 @@
+head 1.1;
+access ;
+symbols ;
+locks ; strict;
+comment @# @;
+
+
+1.1
+date 2008.10.16.12.52.41; author stefan; state Exp;
+branches;
+next ;
+commitid f9748f739194567;
+
+desc
+@@
+
+
+
+1.1
+log
+@initial checkin@
+text
+@# This file affects handling of files based on their names.
+#
+# The -m option specifies whether CVS attempts to merge files.
+#
+# The -k option specifies keyword expansion (e.g. -kb for binary).
+#
+# Format of wrapper file ($CVSROOT/CVSROOT/cvswrappers or .cvswrappers)
+#
+# wildcard [option value][option value]...
+#
+# where option is one of
+# -f from cvs filter value: path to filter
+# -t to cvs filter value: path to filter
+# -m update methodology value: MERGE or COPY
+# -k expansion mode value: b, o, kkv, &c
+#
+# and value is a single-quote delimited value.
+# For example:
+#*.gif -k 'b'
+@
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/history b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/history
new file mode 100644
index 00000000..f0ec96fa
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/history
@@ -0,0 +1,65 @@
+O48f739fd|stefan|~/ASF/ant/ant-HEAD/src/tests/antunit/taskdefs/cvs/*0|antmodule1||antmodule1
+O48f747b5|stefan|~/ASF/ant/ant-HEAD/src/tests/antunit/taskdefs/cvs/*0|antmodule1||antmodule1
+M48f747fb|stefan|~/ASF/ant/ant-HEAD/src/tests/antunit/taskdefs/cvs/*0|antmodule1|1.2|foo.txt
+M48f7480b|stefan|~/ASF/ant/ant-HEAD/src/tests/antunit/taskdefs/cvs/*0|antmodule1|1.3|foo.txt
+O48f748cb|stefan|/tmp/testoutput/*0|antmodule1||antmodule1
+O48f74940|stefan|/tmp/testoutput/*0|antmodule1||antmodule1
+O48f749a9|stefan|/tmp/testoutput/*0|antmodule1||antmodule1
+O48f74a02|stefan|/tmp/testoutput/*0|antmodule1||antmodule1
+M48f74a39|stefan|/tmp/testoutput/*0|antmodule1|1.4|foo.txt
+O48f74a62|stefan|/tmp/testoutput/*0|antmodule1||antmodule1
+O48f75161|stefan|/tmp/testoutput/*0|ant module 2||ant module 2
+O48f75185|stefan|/tmp/testoutput/*0|ant module 2||ant module 2
+O48f75186|stefan|/tmp/testoutput/*0|antmodule1||antmodule1
+O48f75196|stefan|/tmp/testoutput/*0|ant module 2||ant module 2
+O48f75279|stefan|/tmp/testoutput/*0|ant module 2||ant module 2
+O48f75282|stefan|/tmp/testoutput/*0|ant module 2||ant module 2
+O48f75d32|stefan|/tmp/testoutput/*0|ant module 2||ant module 2
+O48f75d34|stefan|/tmp/testoutput/*0|antmodule1||antmodule1
+O48f80394|stefan|/tmp/testoutput/*0|ant module 2||ant module 2
+O48f80395|stefan|/tmp/testoutput/*0|antmodule1||antmodule1
+O48f80ad6|stefan|/tmp/testoutput/*0|ant module 2||ant module 2
+O48f80ad7|stefan|/tmp/testoutput/*0|antmodule1||antmodule1
+O48f8a1d1|stefan|/tmp/testoutput/*0|ant module 2||ant module 2
+O48f8a1d2|stefan|/tmp/testoutput/*0|antmodule1||antmodule1
+O48f8a6a4|stefan|/tmp/testoutput/*0|ant module 2||ant module 2
+O48f8a6a6|stefan|/tmp/testoutput/*0|antmodule1||antmodule1
+O48f8a764|stefan|/tmp/testoutput/*0|ant module 2||ant module 2
+O48f8a766|stefan|/tmp/testoutput/*0|antmodule1||antmodule1
+O48f8abf0|stefan|/tmp/testoutput/*0|ant module 2||ant module 2
+O48f8abf2|stefan|/tmp/testoutput/*0|antmodule1||antmodule1
+O48f8ad8b|stefan|~/ASF/ant/ant-HEAD/*0|antmodule3||antmodule3
+M48f8add7|stefan|~/ASF/ant/ant-HEAD/*0|antmodule3|1.2|yet another test.txt
+O48f8ae09|stefan|/tmp/testoutput/*0|ant module 2||ant module 2
+O48f8ae0a|stefan|/tmp/testoutput/*0|antmodule1||antmodule1
+O48f8b07c|stefan|/tmp/testoutput/*0|antmodule3||antmodule3
+O48f8b07d|stefan|/tmp/testoutput/*0|antmodule3||antmodule3
+O48f8b07e|stefan|/tmp/testoutput/*0|antmodule1||antmodule1
+O48f8b07f|stefan|/tmp/testoutput/*0|antmodule3||antmodule3
+O48f8b082|stefan|/tmp/testoutput/*0|ant module 2||ant module 2
+O48f8b141|stefan|/tmp/testoutput/*0|antmodule3||antmodule3
+O48f8b14c|stefan|/tmp/testoutput/*0|antmodule3||antmodule3
+O48f8b1c3|stefan|/tmp/testoutput/*0|antmodule3||antmodule3
+O48f8b1cd|stefan|/tmp/testoutput/*0|antmodule3||antmodule3
+O48f8b20c|stefan|/tmp/testoutput/*0|antmodule3||antmodule3
+O48f8b217|stefan|/tmp/testoutput/*0|antmodule3||antmodule3
+O48f8b301|stefan|/tmp/testoutput/*0|antmodule3||antmodule3
+O48f8b302|stefan|/tmp/testoutput/*0|antmodule1||antmodule1
+O48f8b303|stefan|/tmp/testoutput/*0|antmodule3||antmodule3
+O48f8b307|stefan|/tmp/testoutput/*0|ant module 2||ant module 2
+O48f8b308|stefan|/tmp/testoutput/*0|antmodule3||antmodule3
+O48f8b328|stefan|/tmp/testoutput/*0|antmodule3||antmodule3
+O48f8b329|stefan|/tmp/testoutput/*0|antmodule1||antmodule1
+O48f8b32b|stefan|/tmp/testoutput/*0|ant module 2||ant module 2
+O48f8b32c|stefan|/tmp/testoutput/*0|antmodule3||antmodule3
+O48fc5e01|stefan|/tmp/testoutput/*0|antmodule3||antmodule3
+O48fc5e03|stefan|/tmp/testoutput/*0|antmodule1||antmodule1
+O48fc5e05|stefan|/tmp/testoutput/*0|ant module 2||ant module 2
+O48fc5e06|stefan|/tmp/testoutput/*0|antmodule3||antmodule3
+O4936994c|stefan|/tmp/testoutput/*0|antmodule1||antmodule1
+M493699c6|stefan|/tmp/testoutput/*0|antmodule1|1.5|foo.txt
+O49369a09|stefan|/tmp/testoutput/*0|antmodule1||antmodule1
+O49369b73|stefan|/tmp/testoutput/*0|antmodule3||antmodule3
+O49369b74|stefan|/tmp/testoutput/*0|antmodule1||antmodule1
+O49369b76|stefan|/tmp/testoutput/*0|ant module 2||ant module 2
+O49369b77|stefan|/tmp/testoutput/*0|antmodule3||antmodule3
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/loginfo b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/loginfo
new file mode 100644
index 00000000..6a1580d8
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/loginfo
@@ -0,0 +1,36 @@
+# The "loginfo" file controls where "cvs commit" log information is
+# sent. The first entry on a line is a regular expression which must
+# match the directory that the change is being made to, relative to the
+# $CVSROOT. If a match is found, then the remainder of the line is a
+# filter program that should expect log information on its standard input.
+#
+# If the repository name does not match any of the regular expressions in this
+# file, the "DEFAULT" line is used, if it is specified.
+#
+# If the name ALL appears as a regular expression it is always used
+# in addition to the first matching regex or DEFAULT.
+#
+# If any format strings are present in the filter, they will be replaced
+# as follows:
+# %c = canonical name of the command being executed
+# %R = the name of the referrer, if any, otherwise the value NONE
+# %p = path relative to repository
+# %r = repository (path portion of $CVSROOT)
+# %{sVv} = attribute list = file name, old version number (pre-checkin),
+# new version number (post-checkin). When either old or new revision
+# is unknown, doesn't exist, or isn't applicable, the string "NONE"
+# will be placed on the command line instead.
+#
+# Note that %{sVv} is a list operator and not all elements are necessary.
+# Thus %{sv} is a legal format string, but will only be replaced with
+# file name and new revision.
+# It also generates multiple arguments for each file being operated upon.
+# That is, if two files, file1 & file2, are being commited from 1.1 to
+# version 1.1.2.1 and from 1.1.2.2 to 1.1.2.3, respectively, %{sVv} will
+# generate the following six arguments in this order:
+# file1, 1.1, 1.1.2.1, file2, 1.1.2.2, 1.1.2.3.
+#
+# For example:
+#DEFAULT (echo ""; id; echo %s; date; cat) >> $CVSROOT/CVSROOT/commitlog
+# or
+#DEFAULT (echo ""; id; echo %{sVv}; date; cat) >> $CVSROOT/CVSROOT/commitlog
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/loginfo,v b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/loginfo,v
new file mode 100644
index 00000000..5a6b8255
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/loginfo,v
@@ -0,0 +1,60 @@
+head 1.1;
+access ;
+symbols ;
+locks ; strict;
+comment @# @;
+
+
+1.1
+date 2008.10.16.12.52.41; author stefan; state Exp;
+branches;
+next ;
+commitid f9748f739194567;
+
+desc
+@@
+
+
+
+1.1
+log
+@initial checkin@
+text
+@# The "loginfo" file controls where "cvs commit" log information is
+# sent. The first entry on a line is a regular expression which must
+# match the directory that the change is being made to, relative to the
+# $CVSROOT. If a match is found, then the remainder of the line is a
+# filter program that should expect log information on its standard input.
+#
+# If the repository name does not match any of the regular expressions in this
+# file, the "DEFAULT" line is used, if it is specified.
+#
+# If the name ALL appears as a regular expression it is always used
+# in addition to the first matching regex or DEFAULT.
+#
+# If any format strings are present in the filter, they will be replaced
+# as follows:
+# %c = canonical name of the command being executed
+# %R = the name of the referrer, if any, otherwise the value NONE
+# %p = path relative to repository
+# %r = repository (path portion of $CVSROOT)
+# %{sVv} = attribute list = file name, old version number (pre-checkin),
+# new version number (post-checkin). When either old or new revision
+# is unknown, doesn't exist, or isn't applicable, the string "NONE"
+# will be placed on the command line instead.
+#
+# Note that %{sVv} is a list operator and not all elements are necessary.
+# Thus %{sv} is a legal format string, but will only be replaced with
+# file name and new revision.
+# It also generates multiple arguments for each file being operated upon.
+# That is, if two files, file1 & file2, are being commited from 1.1 to
+# version 1.1.2.1 and from 1.1.2.2 to 1.1.2.3, respectively, %{sVv} will
+# generate the following six arguments in this order:
+# file1, 1.1, 1.1.2.1, file2, 1.1.2.2, 1.1.2.3.
+#
+# For example:
+#DEFAULT (echo ""; id; echo %s; date; cat) >> $CVSROOT/CVSROOT/commitlog
+# or
+#DEFAULT (echo ""; id; echo %{sVv}; date; cat) >> $CVSROOT/CVSROOT/commitlog
+@
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/modules b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/modules
new file mode 100644
index 00000000..cb9e9efc
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/modules
@@ -0,0 +1,26 @@
+# Three different line formats are valid:
+# key -a aliases...
+# key [options] directory
+# key [options] directory files...
+#
+# Where "options" are composed of:
+# -i prog Run "prog" on "cvs commit" from top-level of module.
+# -o prog Run "prog" on "cvs checkout" of module.
+# -e prog Run "prog" on "cvs export" of module.
+# -t prog Run "prog" on "cvs rtag" of module.
+# -u prog Run "prog" on "cvs update" of module.
+# -d dir Place module in directory "dir" instead of module name.
+# -l Top-level directory only -- do not recurse.
+#
+# NOTE: If you change any of the "Run" options above, you'll have to
+# release and re-checkout any working directories of these modules.
+#
+# And "directory" is a path to a directory relative to $CVSROOT.
+#
+# The "-a" option specifies an alias. An alias is interpreted as if
+# everything on the right of the "-a" had been typed on the command line.
+#
+# You can encode a module within a module by using the special '&'
+# character to interpose another module into the current module. This
+# can be useful for creating a module that consists of many directories
+# spread out over the entire source repository.
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/modules,v b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/modules,v
new file mode 100644
index 00000000..ca44716c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/modules,v
@@ -0,0 +1,50 @@
+head 1.1;
+access ;
+symbols ;
+locks ; strict;
+comment @# @;
+
+
+1.1
+date 2008.10.16.12.52.41; author stefan; state Exp;
+branches;
+next ;
+commitid f9748f739194567;
+
+desc
+@@
+
+
+
+1.1
+log
+@initial checkin@
+text
+@# Three different line formats are valid:
+# key -a aliases...
+# key [options] directory
+# key [options] directory files...
+#
+# Where "options" are composed of:
+# -i prog Run "prog" on "cvs commit" from top-level of module.
+# -o prog Run "prog" on "cvs checkout" of module.
+# -e prog Run "prog" on "cvs export" of module.
+# -t prog Run "prog" on "cvs rtag" of module.
+# -u prog Run "prog" on "cvs update" of module.
+# -d dir Place module in directory "dir" instead of module name.
+# -l Top-level directory only -- do not recurse.
+#
+# NOTE: If you change any of the "Run" options above, you'll have to
+# release and re-checkout any working directories of these modules.
+#
+# And "directory" is a path to a directory relative to $CVSROOT.
+#
+# The "-a" option specifies an alias. An alias is interpreted as if
+# everything on the right of the "-a" had been typed on the command line.
+#
+# You can encode a module within a module by using the special '&'
+# character to interpose another module into the current module. This
+# can be useful for creating a module that consists of many directories
+# spread out over the entire source repository.
+@
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/notify b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/notify
new file mode 100644
index 00000000..aaf98c59
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/notify
@@ -0,0 +1,19 @@
+# The "notify" file controls where notifications from watches set by
+# "cvs watch add" or "cvs edit" are sent. The first entry on a line is
+# a regular expression which is tested against the directory that the
+# change is being made to, relative to the $CVSROOT. If it matches,
+# then the remainder of the line is a filter program that should contain
+# one occurrence of %s for the user to notify, and information on its
+# standard input.
+#
+# "ALL" or "DEFAULT" can be used in place of the regular expression.
+#
+# format strings are replaceed as follows:
+# %c = canonical name of the command being executed
+# %R = the name of the referrer, if any, otherwise the value NONE
+# %p = path relative to repository
+# %r = repository (path portion of $CVSROOT)
+# %s = user to notify
+#
+# For example:
+#ALL (echo Committed to %r/%p; cat) |mail %s -s "CVS notification"
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/notify,v b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/notify,v
new file mode 100644
index 00000000..c0a02f98
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/notify,v
@@ -0,0 +1,43 @@
+head 1.1;
+access ;
+symbols ;
+locks ; strict;
+comment @# @;
+
+
+1.1
+date 2008.10.16.12.52.41; author stefan; state Exp;
+branches;
+next ;
+commitid f9748f739194567;
+
+desc
+@@
+
+
+
+1.1
+log
+@initial checkin@
+text
+@# The "notify" file controls where notifications from watches set by
+# "cvs watch add" or "cvs edit" are sent. The first entry on a line is
+# a regular expression which is tested against the directory that the
+# change is being made to, relative to the $CVSROOT. If it matches,
+# then the remainder of the line is a filter program that should contain
+# one occurrence of %s for the user to notify, and information on its
+# standard input.
+#
+# "ALL" or "DEFAULT" can be used in place of the regular expression.
+#
+# format strings are replaceed as follows:
+# %c = canonical name of the command being executed
+# %R = the name of the referrer, if any, otherwise the value NONE
+# %p = path relative to repository
+# %r = repository (path portion of $CVSROOT)
+# %s = user to notify
+#
+# For example:
+#ALL (echo Committed to %r/%p; cat) |mail %s -s "CVS notification"
+@
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/postadmin b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/postadmin
new file mode 100644
index 00000000..a1a08128
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/postadmin
@@ -0,0 +1,20 @@
+# The "postadmin" file is called after the "admin" command finishes
+# processing a directory.
+#
+# If any format strings are present in the filter, they will be replaced
+# as follows:
+# %c = canonical name of the command being executed
+# %R = the name of the referrer, if any, otherwise the value NONE
+# %p = path relative to repository
+# %r = repository (path portion of $CVSROOT)
+#
+# The first entry on a line is a regular expression which is tested
+# against the directory that the change is being committed to, relative
+# to the $CVSROOT. For the first match that is found, then the remainder
+# of the line is the name of the filter to run.
+#
+# If the repository name does not match any of the regular expressions in this
+# file, the "DEFAULT" line is used, if it is specified.
+#
+# If the name "ALL" appears as a regular expression it is always used
+# in addition to the first matching regex or "DEFAULT".
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/postadmin,v b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/postadmin,v
new file mode 100644
index 00000000..db853edc
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/postadmin,v
@@ -0,0 +1,44 @@
+head 1.1;
+access ;
+symbols ;
+locks ; strict;
+comment @# @;
+
+
+1.1
+date 2008.10.16.12.52.41; author stefan; state Exp;
+branches;
+next ;
+commitid f9748f739194567;
+
+desc
+@@
+
+
+
+1.1
+log
+@initial checkin@
+text
+@# The "postadmin" file is called after the "admin" command finishes
+# processing a directory.
+#
+# If any format strings are present in the filter, they will be replaced
+# as follows:
+# %c = canonical name of the command being executed
+# %R = the name of the referrer, if any, otherwise the value NONE
+# %p = path relative to repository
+# %r = repository (path portion of $CVSROOT)
+#
+# The first entry on a line is a regular expression which is tested
+# against the directory that the change is being committed to, relative
+# to the $CVSROOT. For the first match that is found, then the remainder
+# of the line is the name of the filter to run.
+#
+# If the repository name does not match any of the regular expressions in this
+# file, the "DEFAULT" line is used, if it is specified.
+#
+# If the name "ALL" appears as a regular expression it is always used
+# in addition to the first matching regex or "DEFAULT".
+@
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/postproxy b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/postproxy
new file mode 100644
index 00000000..49c6cfb0
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/postproxy
@@ -0,0 +1,22 @@
+# The "postproxy" file is called from a secondary server as soon as
+# the secondary server closes its connection to the primary server.
+# This script might, for example, be used to shut down a dial up
+# or VPN connection to the primary server's network.
+#
+# If any format strings are present in the filter, they will be replaced
+# as follows:
+# %c = canonical name of the command being executed
+# %R = the name of the referrer, if any, otherwise the value NONE
+# %p = path relative to repository (currently always ".")
+# %r = repository (path portion of $CVSROOT)
+#
+# The first entry on a line is a regular expression which is tested
+# against the directory that the change is being committed to, relative
+# to the $CVSROOT. For the first match that is found, then the remainder
+# of the line is the name of the filter to run.
+#
+# If the repository name does not match any of the regular expressions in this
+# file, the "DEFAULT" line is used, if it is specified.
+#
+# If the name "ALL" appears as a regular expression it is always used
+# in addition to the first matching regex or "DEFAULT".
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/postproxy,v b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/postproxy,v
new file mode 100644
index 00000000..454d19d7
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/postproxy,v
@@ -0,0 +1,46 @@
+head 1.1;
+access ;
+symbols ;
+locks ; strict;
+comment @# @;
+
+
+1.1
+date 2008.10.16.12.52.41; author stefan; state Exp;
+branches;
+next ;
+commitid f9748f739194567;
+
+desc
+@@
+
+
+
+1.1
+log
+@initial checkin@
+text
+@# The "postproxy" file is called from a secondary server as soon as
+# the secondary server closes its connection to the primary server.
+# This script might, for example, be used to shut down a dial up
+# or VPN connection to the primary server's network.
+#
+# If any format strings are present in the filter, they will be replaced
+# as follows:
+# %c = canonical name of the command being executed
+# %R = the name of the referrer, if any, otherwise the value NONE
+# %p = path relative to repository (currently always ".")
+# %r = repository (path portion of $CVSROOT)
+#
+# The first entry on a line is a regular expression which is tested
+# against the directory that the change is being committed to, relative
+# to the $CVSROOT. For the first match that is found, then the remainder
+# of the line is the name of the filter to run.
+#
+# If the repository name does not match any of the regular expressions in this
+# file, the "DEFAULT" line is used, if it is specified.
+#
+# If the name "ALL" appears as a regular expression it is always used
+# in addition to the first matching regex or "DEFAULT".
+@
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/posttag b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/posttag
new file mode 100644
index 00000000..7f369e38
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/posttag
@@ -0,0 +1,37 @@
+# The "posttag" file is called after the "tag" command finishes
+# processing a directory.
+#
+# If any format strings are present in the filter, they will be replaced
+# as follows:
+# %b = branch mode = "?" (delete ops - unknown) | "T" (branch)
+# | "N" (not branch)
+# %o = operation = "add" | "mov" | "del"
+# %c = canonical name of the command being executed
+# %R = the name of the referrer, if any, otherwise the value NONE
+# %p = path relative to repository
+# %r = repository (path portion of $CVSROOT)
+# %t = tagname
+# %{sVv} = attribute list = file name, old version tag will be deleted
+# from, new version tag will be added to (or deleted from, but
+# this feature is deprecated. When either old or new revision is
+# unknown, doesn't exist, or isn't applicable, the string "NONE"
+# will be placed on the command line.
+#
+# Note that %{sVv} is a list operator and not all elements are necessary.
+# Thus %{sV} is a legal format string, but will only be replaced with file
+# name and old revision. it also generates multiple arguments for each file
+# being operated upon. i.e. if two files, file1 & file2, are having a tag
+# moved from version 1.1 to version 1.1.2.9, %{sVv} will generate the
+# following six arguments in this order:
+# file1, 1.1, 1.1.2.9, file2, 1.1, 1.1.2.9.
+#
+# The first entry on a line is a regular expression which is tested
+# against the directory that the change is being committed to, relative
+# to the $CVSROOT. For the first match that is found, then the remainder
+# of the line is the name of the filter to run.
+#
+# If the repository name does not match any of the regular expressions in this
+# file, the "DEFAULT" line is used, if it is specified.
+#
+# If the name "ALL" appears as a regular expression it is always used
+# in addition to the first matching regex or "DEFAULT".
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/posttag,v b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/posttag,v
new file mode 100644
index 00000000..31c7024d
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/posttag,v
@@ -0,0 +1,61 @@
+head 1.1;
+access ;
+symbols ;
+locks ; strict;
+comment @# @;
+
+
+1.1
+date 2008.10.16.12.52.41; author stefan; state Exp;
+branches;
+next ;
+commitid f9748f739194567;
+
+desc
+@@
+
+
+
+1.1
+log
+@initial checkin@
+text
+@# The "posttag" file is called after the "tag" command finishes
+# processing a directory.
+#
+# If any format strings are present in the filter, they will be replaced
+# as follows:
+# %b = branch mode = "?" (delete ops - unknown) | "T" (branch)
+# | "N" (not branch)
+# %o = operation = "add" | "mov" | "del"
+# %c = canonical name of the command being executed
+# %R = the name of the referrer, if any, otherwise the value NONE
+# %p = path relative to repository
+# %r = repository (path portion of $CVSROOT)
+# %t = tagname
+# %{sVv} = attribute list = file name, old version tag will be deleted
+# from, new version tag will be added to (or deleted from, but
+# this feature is deprecated. When either old or new revision is
+# unknown, doesn't exist, or isn't applicable, the string "NONE"
+# will be placed on the command line.
+#
+# Note that %{sVv} is a list operator and not all elements are necessary.
+# Thus %{sV} is a legal format string, but will only be replaced with file
+# name and old revision. it also generates multiple arguments for each file
+# being operated upon. i.e. if two files, file1 & file2, are having a tag
+# moved from version 1.1 to version 1.1.2.9, %{sVv} will generate the
+# following six arguments in this order:
+# file1, 1.1, 1.1.2.9, file2, 1.1, 1.1.2.9.
+#
+# The first entry on a line is a regular expression which is tested
+# against the directory that the change is being committed to, relative
+# to the $CVSROOT. For the first match that is found, then the remainder
+# of the line is the name of the filter to run.
+#
+# If the repository name does not match any of the regular expressions in this
+# file, the "DEFAULT" line is used, if it is specified.
+#
+# If the name "ALL" appears as a regular expression it is always used
+# in addition to the first matching regex or "DEFAULT".
+@
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/postwatch b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/postwatch
new file mode 100644
index 00000000..5b001b12
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/postwatch
@@ -0,0 +1,20 @@
+# The "postwatch" file is called after any command finishes writing new
+# file attibute (watch/edit) information in a directory.
+#
+# If any format strings are present in the filter, they will be replaced
+# as follows:
+# %c = canonical name of the command being executed
+# %R = the name of the referrer, if any, otherwise the value NONE
+# %p = path relative to repository
+# %r = repository (path portion of $CVSROOT)
+#
+# The first entry on a line is a regular expression which is tested
+# against the directory that the change is being committed to, relative
+# to the $CVSROOT. For the first match that is found, then the remainder
+# of the line is the name of the filter to run.
+#
+# If the repository name does not match any of the regular expressions in this
+# file, the "DEFAULT" line is used, if it is specified.
+#
+# If the name "ALL" appears as a regular expression it is always used
+# in addition to the first matching regex or "DEFAULT".
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/postwatch,v b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/postwatch,v
new file mode 100644
index 00000000..8e3825cb
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/postwatch,v
@@ -0,0 +1,44 @@
+head 1.1;
+access ;
+symbols ;
+locks ; strict;
+comment @# @;
+
+
+1.1
+date 2008.10.16.12.52.41; author stefan; state Exp;
+branches;
+next ;
+commitid f9748f739194567;
+
+desc
+@@
+
+
+
+1.1
+log
+@initial checkin@
+text
+@# The "postwatch" file is called after any command finishes writing new
+# file attibute (watch/edit) information in a directory.
+#
+# If any format strings are present in the filter, they will be replaced
+# as follows:
+# %c = canonical name of the command being executed
+# %R = the name of the referrer, if any, otherwise the value NONE
+# %p = path relative to repository
+# %r = repository (path portion of $CVSROOT)
+#
+# The first entry on a line is a regular expression which is tested
+# against the directory that the change is being committed to, relative
+# to the $CVSROOT. For the first match that is found, then the remainder
+# of the line is the name of the filter to run.
+#
+# If the repository name does not match any of the regular expressions in this
+# file, the "DEFAULT" line is used, if it is specified.
+#
+# If the name "ALL" appears as a regular expression it is always used
+# in addition to the first matching regex or "DEFAULT".
+@
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/preproxy b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/preproxy
new file mode 100644
index 00000000..a9f514f4
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/preproxy
@@ -0,0 +1,24 @@
+# The "preproxy" file is called form the secondary server as soon as
+# the secondary server determines that it will be proxying a write
+# command to a primary server and immediately before it opens a
+# connection to the primary server. This script might, for example, be
+# used to launch a dial up or VPN connection to the primary server's
+# network.
+#
+# If any format strings are present in the filter, they will be replaced
+# as follows:
+# %c = canonical name of the command being executed
+# %R = the name of the referrer, if any, otherwise the value NONE
+# %p = path relative to repository (currently always ".")
+# %r = repository (path portion of $CVSROOT)
+#
+# The first entry on a line is a regular expression which is tested
+# against the directory that the change is being committed to, relative
+# to the $CVSROOT. For the first match that is found, then the remainder
+# of the line is the name of the filter to run.
+#
+# If the repository name does not match any of the regular expressions in this
+# file, the "DEFAULT" line is used, if it is specified.
+#
+# If the name "ALL" appears as a regular expression it is always used
+# in addition to the first matching regex or "DEFAULT".
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/preproxy,v b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/preproxy,v
new file mode 100644
index 00000000..5dcaa279
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/preproxy,v
@@ -0,0 +1,48 @@
+head 1.1;
+access ;
+symbols ;
+locks ; strict;
+comment @# @;
+
+
+1.1
+date 2008.10.16.12.52.41; author stefan; state Exp;
+branches;
+next ;
+commitid f9748f739194567;
+
+desc
+@@
+
+
+
+1.1
+log
+@initial checkin@
+text
+@# The "preproxy" file is called form the secondary server as soon as
+# the secondary server determines that it will be proxying a write
+# command to a primary server and immediately before it opens a
+# connection to the primary server. This script might, for example, be
+# used to launch a dial up or VPN connection to the primary server's
+# network.
+#
+# If any format strings are present in the filter, they will be replaced
+# as follows:
+# %c = canonical name of the command being executed
+# %R = the name of the referrer, if any, otherwise the value NONE
+# %p = path relative to repository (currently always ".")
+# %r = repository (path portion of $CVSROOT)
+#
+# The first entry on a line is a regular expression which is tested
+# against the directory that the change is being committed to, relative
+# to the $CVSROOT. For the first match that is found, then the remainder
+# of the line is the name of the filter to run.
+#
+# If the repository name does not match any of the regular expressions in this
+# file, the "DEFAULT" line is used, if it is specified.
+#
+# If the name "ALL" appears as a regular expression it is always used
+# in addition to the first matching regex or "DEFAULT".
+@
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/rcsinfo b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/rcsinfo
new file mode 100644
index 00000000..49e59f4d
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/rcsinfo
@@ -0,0 +1,13 @@
+# The "rcsinfo" file is used to control templates with which the editor
+# is invoked on commit and import.
+#
+# The first entry on a line is a regular expression which is tested
+# against the directory that the change is being made to, relative to the
+# $CVSROOT. For the first match that is found, then the remainder of the
+# line is the name of the file that contains the template.
+#
+# If the repository name does not match any of the regular expressions in this
+# file, the "DEFAULT" line is used, if it is specified.
+#
+# If the name "ALL" appears as a regular expression it is always used
+# in addition to the first matching regex or "DEFAULT".
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/rcsinfo,v b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/rcsinfo,v
new file mode 100644
index 00000000..df61bfb3
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/rcsinfo,v
@@ -0,0 +1,37 @@
+head 1.1;
+access ;
+symbols ;
+locks ; strict;
+comment @# @;
+
+
+1.1
+date 2008.10.16.12.52.41; author stefan; state Exp;
+branches;
+next ;
+commitid f9748f739194567;
+
+desc
+@@
+
+
+
+1.1
+log
+@initial checkin@
+text
+@# The "rcsinfo" file is used to control templates with which the editor
+# is invoked on commit and import.
+#
+# The first entry on a line is a regular expression which is tested
+# against the directory that the change is being made to, relative to the
+# $CVSROOT. For the first match that is found, then the remainder of the
+# line is the name of the file that contains the template.
+#
+# If the repository name does not match any of the regular expressions in this
+# file, the "DEFAULT" line is used, if it is specified.
+#
+# If the name "ALL" appears as a regular expression it is always used
+# in addition to the first matching regex or "DEFAULT".
+@
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/taginfo b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/taginfo
new file mode 100644
index 00000000..ce9d0dea
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/taginfo
@@ -0,0 +1,46 @@
+# The "taginfo" file is used to control pre-tag checks.
+# The filter on the right is invoked with the following arguments
+# if no format strings are present:
+#
+# $1 -- tagname
+# $2 -- operation "add" for tag, "mov" for tag -F, and "del" for tag -d
+# $3 -- tagtype "?" on delete, "T" for branch, "N" for static
+# $4 -- repository
+# $5-> file revision [file revision ...]
+#
+# If any format strings are present in the filter, they will be replaced
+# as follows:
+# %b = branch mode = "?" (delete ops - unknown) | "T" (branch)
+# | "N" (not branch)
+# %o = operation = "add" | "mov" | "del"
+# %c = canonical name of the command being executed
+# %R = the name of the referrer, if any, otherwise the value NONE
+# %p = path relative to repository
+# %r = repository (path portion of $CVSROOT)
+# %t = tagname
+# %{sVv} = attribute list = file name, old version tag will be deleted
+# from, new version tag will be added to (or deleted from, but
+# this feature is deprecated. When either old or new revision is
+# unknown, doesn't exist, or isn't applicable, the string "NONE"
+# will be placed on the command line.
+#
+# Note that %{sVv} is a list operator and not all elements are necessary.
+# Thus %{sV} is a legal format string, but will only be replaced with file
+# name and old revision. it also generates multiple arguments for each file
+# being operated upon. i.e. if two files, file1 & file2, are having a tag
+# moved from version 1.1 to version 1.1.2.9, %{sVv} will generate the
+# following six arguments in this order:
+# file1, 1.1, 1.1.2.9, file2, 1.1, 1.1.2.9.
+#
+# A non-zero exit of the filter program will cause the tag to be aborted.
+#
+# The first entry on a line is a regular expression which is tested
+# against the directory that the change is being committed to, relative
+# to the $CVSROOT. For the first match that is found, then the remainder
+# of the line is the name of the filter to run.
+#
+# If the repository name does not match any of the regular expressions in this
+# file, the "DEFAULT" line is used, if it is specified.
+#
+# If the name "ALL" appears as a regular expression it is always used
+# in addition to the first matching regex or "DEFAULT".
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/taginfo,v b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/taginfo,v
new file mode 100644
index 00000000..82c87f25
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/taginfo,v
@@ -0,0 +1,70 @@
+head 1.1;
+access ;
+symbols ;
+locks ; strict;
+comment @# @;
+
+
+1.1
+date 2008.10.16.12.52.41; author stefan; state Exp;
+branches;
+next ;
+commitid f9748f739194567;
+
+desc
+@@
+
+
+
+1.1
+log
+@initial checkin@
+text
+@# The "taginfo" file is used to control pre-tag checks.
+# The filter on the right is invoked with the following arguments
+# if no format strings are present:
+#
+# $1 -- tagname
+# $2 -- operation "add" for tag, "mov" for tag -F, and "del" for tag -d
+# $3 -- tagtype "?" on delete, "T" for branch, "N" for static
+# $4 -- repository
+# $5-> file revision [file revision ...]
+#
+# If any format strings are present in the filter, they will be replaced
+# as follows:
+# %b = branch mode = "?" (delete ops - unknown) | "T" (branch)
+# | "N" (not branch)
+# %o = operation = "add" | "mov" | "del"
+# %c = canonical name of the command being executed
+# %R = the name of the referrer, if any, otherwise the value NONE
+# %p = path relative to repository
+# %r = repository (path portion of $CVSROOT)
+# %t = tagname
+# %{sVv} = attribute list = file name, old version tag will be deleted
+# from, new version tag will be added to (or deleted from, but
+# this feature is deprecated. When either old or new revision is
+# unknown, doesn't exist, or isn't applicable, the string "NONE"
+# will be placed on the command line.
+#
+# Note that %{sVv} is a list operator and not all elements are necessary.
+# Thus %{sV} is a legal format string, but will only be replaced with file
+# name and old revision. it also generates multiple arguments for each file
+# being operated upon. i.e. if two files, file1 & file2, are having a tag
+# moved from version 1.1 to version 1.1.2.9, %{sVv} will generate the
+# following six arguments in this order:
+# file1, 1.1, 1.1.2.9, file2, 1.1, 1.1.2.9.
+#
+# A non-zero exit of the filter program will cause the tag to be aborted.
+#
+# The first entry on a line is a regular expression which is tested
+# against the directory that the change is being committed to, relative
+# to the $CVSROOT. For the first match that is found, then the remainder
+# of the line is the name of the filter to run.
+#
+# If the repository name does not match any of the regular expressions in this
+# file, the "DEFAULT" line is used, if it is specified.
+#
+# If the name "ALL" appears as a regular expression it is always used
+# in addition to the first matching regex or "DEFAULT".
+@
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/val-tags b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/val-tags
new file mode 100644
index 00000000..a76de202
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/val-tags
@@ -0,0 +1,2 @@
+testtag1 y
+testtag2 y
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/verifymsg b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/verifymsg
new file mode 100644
index 00000000..357a0b03
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/verifymsg
@@ -0,0 +1,31 @@
+# The "verifymsg" file is used to allow verification of logging
+# information. It works best when a template (as specified in the
+# rcsinfo file) is provided for the logging procedure. Given a
+# template with locations for, a bug-id number, a list of people who
+# reviewed the code before it can be checked in, and an external
+# process to catalog the differences that were code reviewed, the
+# following test can be applied to the code:
+#
+# Making sure that the entered bug-id number is correct.
+# Validating that the code that was reviewed is indeed the code being
+# checked in (using the bug-id number or a seperate review
+# number to identify this particular code set.).
+#
+# If any of the above test failed, then the commit would be aborted.
+#
+# Format strings present in the filter will be replaced as follows:
+# %c = canonical name of the command being executed
+# %R = the name of the referrer, if any, otherwise the value NONE
+# %p = path relative to repository
+# %r = repository (path portion of $CVSROOT)
+# %l = name of log file to be verified.
+#
+# If no format strings are present in the filter, a default " %l" will
+# be appended to the filter, but this usage is deprecated.
+#
+# Actions such as mailing a copy of the report to each reviewer are
+# better handled by an entry in the loginfo file.
+#
+# One thing that should be noted is the the ALL keyword is not
+# supported. There can be only one entry that matches a given
+# repository.
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/verifymsg,v b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/verifymsg,v
new file mode 100644
index 00000000..d80fd099
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/CVSROOT/verifymsg,v
@@ -0,0 +1,55 @@
+head 1.1;
+access ;
+symbols ;
+locks ; strict;
+comment @# @;
+
+
+1.1
+date 2008.10.16.12.52.41; author stefan; state Exp;
+branches;
+next ;
+commitid f9748f739194567;
+
+desc
+@@
+
+
+
+1.1
+log
+@initial checkin@
+text
+@# The "verifymsg" file is used to allow verification of logging
+# information. It works best when a template (as specified in the
+# rcsinfo file) is provided for the logging procedure. Given a
+# template with locations for, a bug-id number, a list of people who
+# reviewed the code before it can be checked in, and an external
+# process to catalog the differences that were code reviewed, the
+# following test can be applied to the code:
+#
+# Making sure that the entered bug-id number is correct.
+# Validating that the code that was reviewed is indeed the code being
+# checked in (using the bug-id number or a seperate review
+# number to identify this particular code set.).
+#
+# If any of the above test failed, then the commit would be aborted.
+#
+# Format strings present in the filter will be replaced as follows:
+# %c = canonical name of the command being executed
+# %R = the name of the referrer, if any, otherwise the value NONE
+# %p = path relative to repository
+# %r = repository (path portion of $CVSROOT)
+# %l = name of log file to be verified.
+#
+# If no format strings are present in the filter, a default " %l" will
+# be appended to the filter, but this usage is deprecated.
+#
+# Actions such as mailing a copy of the report to each reviewer are
+# better handled by an entry in the loginfo file.
+#
+# One thing that should be noted is the the ALL keyword is not
+# supported. There can be only one entry that matches a given
+# repository.
+@
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/ant module 2/test.txt,v b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/ant module 2/test.txt,v
new file mode 100644
index 00000000..b91d6968
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/ant module 2/test.txt,v
@@ -0,0 +1,41 @@
+head 1.1;
+branch 1.1.1;
+access ;
+symbols start:1.1.1.1 ant:1.1.1;
+locks ; strict;
+comment @# @;
+
+
+1.1
+date 2008.10.16.14.14.17; author stefan; state Exp;
+branches 1.1.1.1;
+next ;
+commitid cdf48f74c394567;
+
+1.1.1.1
+date 2008.10.16.14.14.17; author stefan; state Exp;
+branches ;
+next ;
+commitid cdf48f74c394567;
+
+
+desc
+@@
+
+
+
+1.1
+log
+@Initial revision
+@
+text
+@What a nice file.
+@
+
+
+1.1.1.1
+log
+@module with space in it's name
+@
+text
+@@
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/antmodule1/foo.txt,v b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/antmodule1/foo.txt,v
new file mode 100644
index 00000000..47669791
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/antmodule1/foo.txt,v
@@ -0,0 +1,108 @@
+head 1.5;
+access;
+symbols
+ start:1.1.1.1 ant:1.1.1;
+locks; strict;
+comment @# @;
+
+
+1.5
+date 2008.12.03.14.37.58; author stefan; state Exp;
+branches;
+next 1.4;
+commitid 2ca3493699c64567;
+
+1.4
+date 2008.10.16.14.05.45; author stefan; state Exp;
+branches;
+next 1.3;
+commitid 761748f74a394567;
+
+1.3
+date 2008.10.16.13.56.27; author stefan; state Exp;
+branches;
+next 1.2;
+commitid 4dcd48f7480b4567;
+
+1.2
+date 2008.10.16.13.56.11; author stefan; state Exp;
+branches;
+next 1.1;
+commitid 4dae48f747fb4567;
+
+1.1
+date 2008.10.16.12.56.07; author stefan; state Exp;
+branches
+ 1.1.1.1;
+next ;
+commitid 17ca48f739e74567;
+
+1.1.1.1
+date 2008.10.16.12.56.07; author stefan; state Exp;
+branches;
+next ;
+commitid 17ca48f739e74567;
+
+
+desc
+@@
+
+
+1.5
+log
+@add yet another line
+@
+text
+@This is a text.
+Added a line.
+and one more line.
+and another line.
+@
+
+
+1.4
+log
+@----------------------------
+@
+text
+@d4 1
+@
+
+
+1.3
+log
+@typo
+@
+text
+@d3 1
+@
+
+
+1.2
+log
+@--------------------
+@
+text
+@d2 1
+a2 1
+added a line.
+@
+
+
+1.1
+log
+@Initial revision
+@
+text
+@d2 1
+a2 1
+
+@
+
+
+1.1.1.1
+log
+@Initial import
+@
+text
+@@
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/antmodule3/yet another test.txt,v b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/antmodule3/yet another test.txt,v
new file mode 100644
index 00000000..08f13b00
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/cvs/repository/antmodule3/yet another test.txt,v
@@ -0,0 +1,60 @@
+head 1.2;
+access;
+symbols
+ testtag2:1.2
+ testtag1:1.1.1.1
+ start:1.1.1.1
+ ant:1.1.1;
+locks; strict;
+comment @# @;
+
+
+1.2
+date 2008.10.17.15.23.03; author stefan; state Exp;
+branches;
+next 1.1;
+commitid 7ddc48f8add74567;
+
+1.1
+date 2008.10.16.14.51.11; author stefan; state Exp;
+branches
+ 1.1.1.1;
+next ;
+commitid 7f8d48f754df4567;
+
+1.1.1.1
+date 2008.10.16.14.51.11; author stefan; state Exp;
+branches;
+next ;
+commitid 7f8d48f754df4567;
+
+
+desc
+@@
+
+
+1.2
+log
+@update weather report
+@
+text
+@dark and cloudy.
+a bit brighter today.
+@
+
+
+1.1
+log
+@Initial revision
+@
+text
+@d2 1
+@
+
+
+1.1.1.1
+log
+@three times is a charm
+@
+text
+@@
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/defaultexcludes-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/defaultexcludes-test.xml
new file mode 100644
index 00000000..cbea93c2
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/defaultexcludes-test.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="antunit" xmlns:au="antlib:org.apache.ant.antunit">
+ <import file="../antunit-base.xml" />
+
+ <target name="setUp">
+ <mkdir dir="${output}"/>
+ <available property="in working copy" file=".svn"/>
+ </target>
+
+ <target name="testCopyNoExplicitExcludes" depends="setUp"
+ if="in working copy">
+ <copy todir="${output}">
+ <fileset dir="."/>
+ </copy>
+ <au:assertFileExists file="${output}/defaultexcludes-test.xml"/>
+ <au:assertFileDoesntExist file="${output}/.svn/entries"/>
+ </target>
+
+ <target name="testCopyExplicitExcludes" depends="setUp"
+ if="in working copy">
+ <copy todir="${output}">
+ <fileset dir="." defaultexcludes="true"/>
+ </copy>
+ <au:assertFileExists file="${output}/defaultexcludes-test.xml"/>
+ <au:assertFileDoesntExist file="${output}/.svn/entries"/>
+ </target>
+
+ <target name="testCopyExplicitNoExcludes" depends="setUp"
+ if="in working copy">
+ <copy todir="${output}">
+ <fileset dir="." defaultexcludes="false"/>
+ </copy>
+ <au:assertFileExists file="${output}/defaultexcludes-test.xml"/>
+ <au:assertFileExists file="${output}/.svn/entries"/>
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/delete-and-symlinks-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/delete-and-symlinks-test.xml
new file mode 100644
index 00000000..ac789940
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/delete-and-symlinks-test.xml
@@ -0,0 +1,84 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<project name="delete-test" basedir="." default="antunit"
+ xmlns:au="antlib:org.apache.ant.antunit">
+
+ <import file="../antunit-base.xml" />
+
+ <condition property="unix">
+ <os family="unix" />
+ </condition>
+
+ <target name="tearDown" depends="removelink, antunit-base.tearDown"/>
+
+ <target name="removelink" if="link">
+ <symlink action="delete" link="${link}"/>
+ </target>
+
+ <target name="setUp" if="unix">
+ <mkdir dir="${input}/A/B"/>
+ <mkdir dir="${input}/C"/>
+ <property name="link" location="${input}/A/B/C"/>
+ <symlink link="${link}" resource="${input}/C"/>
+ </target>
+
+ <target name="testNotFollowedLink" if="unix" depends="setUp">
+ <delete>
+ <fileset dir="${input}" followSymlinks="false"/>
+ </delete>
+ <au:assertFileExists file="${input}/A/B/C"/>
+ </target>
+
+ <target name="testRemoveNotFollowedLink" if="unix" depends="setUp">
+ <delete removeNotFollowedSymlinks="true">
+ <fileset dir="${input}/A" followSymlinks="false"/>
+ </delete>
+ <au:assertFileDoesntExist file="${input}/A/B/C"/>
+ <au:assertFileExists file="${input}/C"/>
+ </target>
+
+ <target name="testRemoveNotFollowedLinkHonorsIncludesOnFiles"
+ depends="setUp" if="unix"
+ description="https://issues.apache.org/bugzilla/show_bug.cgi?id=53959">
+ <delete dir="${input}/C"/>
+ <touch file="${input}/C"/>
+ <delete removeNotFollowedSymlinks="true">
+ <fileset dir="${input}/A" followSymlinks="false" includes="**/D"/>
+ </delete>
+ <au:assertFileExists file="${input}/A/B/C"/>
+ </target>
+
+ <target name="testRemoveNotFollowedLinkDeletesNotIncludedDirs"
+ depends="setUp" if="unix"
+ description="https://issues.apache.org/bugzilla/show_bug.cgi?id=53959">
+ <delete removeNotFollowedSymlinks="true">
+ <fileset dir="${input}/A" followSymlinks="false" includes="**/D"/>
+ </delete>
+ <au:assertFileDoesntExist file="${input}/A/B/C"/>
+ <au:assertFileExists file="${input}/C"/>
+ </target>
+
+ <target name="testRemoveNotFollowedLinkHonorsExcludes" if="unix"
+ depends="setUp">
+ <delete removeNotFollowedSymlinks="true">
+ <fileset dir="${input}/A" followSymlinks="false" excludes="**/C/**"/>
+ </delete>
+ <au:assertFileExists file="${input}/A/B/C"/>
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/delete-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/delete-test.xml
new file mode 100644
index 00000000..554f08fe
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/delete-test.xml
@@ -0,0 +1,141 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<project name="delete-test" basedir="." default="antunit"
+ xmlns:au="antlib:org.apache.ant.antunit">
+
+ <import file="../antunit-base.xml" />
+
+ <property name="existing.dir" location="${output}/exists"/>
+ <property name="nonexistent.dir" location="${output}/nonexists"/>
+
+ <target name="init">
+ <delete dir="${output}"/>
+ <mkdir dir="${output}"/>
+ <mkdir dir="${existing.dir}"/>
+ </target>
+
+ <!--test that you can delete a fileset with a nonexistent dir without failure-->
+ <target name="testdelfileset" depends="init">
+ <delete quiet="true" includeEmptyDirs="true">
+ <fileset dir="${nonexistent.dir}"/>
+ </delete>
+
+ <au:assertFileExists file="${existing.dir}" />
+
+ <delete quiet="true" includeEmptyDirs="true">
+ <fileset dir="${existing.dir}"/>
+ </delete>
+
+ <au:assertFileDoesntExist file="${existing.dir}" />
+
+
+ <mkdir dir="${existing.dir}"/>
+
+ <delete quiet="true" includeEmptyDirs="true">
+ <fileset dir="${nonexistent.dir}"/>
+ <fileset dir="${existing.dir}"/>
+ </delete>
+
+
+ <au:assertFileDoesntExist file="${existing.dir}" />
+
+ <mkdir dir="${existing.dir}"/>
+
+ <delete quiet="true" includeEmptyDirs="true">
+ <fileset dir="${existing.dir}"/>
+ <fileset dir="${nonexistent.dir}"/>
+ </delete>
+
+
+ <au:assertFileDoesntExist file="${existing.dir}" />
+
+ </target>
+
+ <target name="checkOs">
+ <condition property="unix">
+ <os family="unix" />
+ </condition>
+ </target>
+
+ <target name="testDanglingSymlinkInDir" if="unix" depends="checkOs,init">
+ <touch file="${output}/foo"/>
+ <symlink link="${existing.dir}/link"
+ resource="${output}/foo"/>
+ <delete file="${output}/foo"/>
+ <delete dir="${existing.dir}"/>
+ <au:assertFileDoesntExist file="${existing.dir}" />
+ </target>
+
+ <target name="testDanglingSymlink" if="unix" depends="checkOs,init">
+ <touch file="${output}/foo"/>
+ <symlink link="${output}/link"
+ resource="${output}/foo"/>
+ <delete file="${output}/foo"/>
+ <delete file="${output}/link"/>
+
+ <!-- since File.exists returns false for dangling links, recreate
+ the file so that assertFileDoesntExist can actually work -->
+ <touch file="${output}/foo"/>
+ <au:assertFileDoesntExist file="${output}/link" />
+ </target>
+
+ <target name="testNotModifiedSelector"
+ description="https://issues.apache.org/bugzilla/show_bug.cgi?id=43574"
+ >
+ <mkdir dir="${input}/images"/>
+ <mkdir dir="${input}/cache"/>
+ <touch file="${input}/images/foo.jpg"/>
+ <selector id="cache.selector">
+ <not>
+ <modified update="true"
+ seldirs="false"
+ cache="propertyfile"
+ algorithm="digest"
+ comparator="equal">
+ <param name="cache.cachefile"
+ value="${input}/cache/cache.properties"/>
+ <param name="algorithm.algorithm" value="MD5"/>
+ </modified>
+ </not>
+ </selector>
+ <au:assertFileDoesntExist file="${input}/cache/cache.properties"/>
+ <delete>
+ <fileset dir="${input}/images">
+ <include name="*.jpg" />
+ <selector refid="cache.selector" />
+ </fileset>
+ </delete>
+ <au:assertFileExists file="${input}/cache/cache.properties"/>
+ <au:assertFileExists file="${input}/images/foo.jpg"/>
+ <delete>
+ <fileset dir="${input}/images">
+ <include name="*.jpg" />
+ <selector refid="cache.selector" />
+ </fileset>
+ </delete>
+ <au:assertFileDoesntExist file="${input}/images/foo.jpg"/>
+ </target>
+
+ <target name="testFilesetWithMissingButIgnoredDir"
+ description="https://issues.apache.org/bugzilla/show_bug.cgi?id=50124">
+ <delete>
+ <fileset dir="${input}/not-there" errorOnMissingDir="false"/>
+ </delete>
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/dependset-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/dependset-test.xml
new file mode 100644
index 00000000..55252593
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/dependset-test.xml
@@ -0,0 +1,196 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<project name="dependset-test" xmlns:au="antlib:org.apache.ant.antunit" default="antunit">
+
+ <import file="../antunit-base.xml" />
+
+ <target name="setUp">
+ <mkdir dir="${input}" />
+ <mkdir dir="${output}" />
+ </target>
+
+ <target name="testNoSourcesOrTargets">
+ <au:expectfailure expectedMessage="At least one set of source resources must be specified">
+ <dependset />
+ </au:expectfailure>
+ </target>
+
+ <target name="testNoTargets">
+ <au:expectfailure expectedMessage="At least one set of target files must be specified">
+ <dependset>
+ <srcfilelist dir="." files="test2.tmp" />
+ </dependset>
+ </au:expectfailure>
+ </target>
+
+ <target name="testNoSources">
+ <au:expectfailure expectedMessage="At least one set of source resources must be specified">
+ <dependset>
+ <targetfileset dir="." includes="test3.tmp" />
+ </dependset>
+ </au:expectfailure>
+ </target>
+
+ <target name="testMissingTargets" depends="setUp">
+ <touch file="${input}/test4.tmp" />
+ <dependset>
+ <srcfilelist dir="${input}" files="test4.tmp" />
+ <targetfileset id="targetfs" dir="${output}" includes="i-do-not-exist" />
+ </dependset>
+ <au:assertLogDoesntContain text="Deleting all target files." level="verbose" />
+ </target>
+
+ <target name="testMoreRecentSourceFile" depends="setUp">
+ <touch file="${output}/older.tmp" />
+ <sleep seconds="3" />
+ <touch file="${input}/newer.tmp" />
+ <dependset>
+ <srcfilelist dir="${input}" files="newer.tmp" />
+ <targetfilelist dir="${output}" files="older.tmp" />
+ </dependset>
+ <au:assertLogContains text="older.tmp&quot; is oldest target file" level="verbose" />
+ <au:assertLogContains text="newer.tmp&quot; is newest source" level="verbose" />
+ <au:assertLogContains text="Deleting all target files." level="verbose" />
+ <au:assertLogDoesntContain text="Deleting" level="info" />
+ <au:assertFileDoesntExist file="${output}/older.tmp" />
+ </target>
+
+ <target name="testMoreRecentSourceFileVerbose" depends="setUp">
+ <touch file="${output}/older.tmp" />
+ <sleep seconds="3" />
+ <touch file="${input}/newer.tmp" />
+ <dependset verbose="true">
+ <srcfilelist dir="${input}" files="newer.tmp" />
+ <targetfilelist dir="${output}" files="older.tmp" />
+ </dependset>
+ <au:assertLogContains text="older.tmp&quot; is oldest target file" level="info" />
+ <au:assertLogContains text="newer.tmp&quot; is newest source" level="info" />
+ <au:assertLogContains text="Deleting all target files." level="verbose" />
+ <au:assertLogContains text="Deleting" level="info" />
+ <au:assertFileDoesntExist file="${output}/older.tmp" />
+ </target>
+
+ <target name="testMultipleFiles" depends="setUp">
+ <touch file="${input}/sourceset_1.tmp" />
+ <touch file="${output}/targetset_1.tmp" />
+ <sleep seconds="3" />
+ <touch file="${input}/sourceset_2.tmp" />
+ <touch file="${output}/targetset_2.tmp" />
+ <sleep seconds="2" />
+ <dependset>
+ <sources>
+ <filelist dir="${input}" files="sourceset_1.tmp,sourceset_2.tmp" />
+ </sources>
+ <targets>
+ <filelist dir="${output}/" files="targetset_1.tmp,targetset_2.tmp" />
+ </targets>
+ </dependset>
+ <au:assertLogContains text="targetset_1.tmp&quot; is oldest target file" level="verbose" />
+ <au:assertLogContains text="sourceset_2.tmp&quot; is newest source" level="verbose" />
+ <au:assertLogContains text="Deleting all target files." level="verbose" />
+ <au:assertLogDoesntContain text="Deleting" level="info" />
+ <au:assertFileDoesntExist file="${output}/targetset_1.tmp" />
+ <au:assertFileDoesntExist file="${output}/targetset_2.tmp" />
+ </target>
+
+ <target name="testMultipleFilesVerbose" depends="setUp">
+ <touch file="${input}/sourceset_1.tmp" />
+ <touch file="${output}/targetset_1.tmp" />
+ <sleep seconds="3" />
+ <touch file="${input}/sourceset_2.tmp" />
+ <touch file="${output}/targetset_2.tmp" />
+ <sleep seconds="2" />
+ <dependset verbose="true">
+ <sources>
+ <filelist dir="${input}" files="sourceset_1.tmp,sourceset_2.tmp" />
+ </sources>
+ <targets>
+ <filelist dir="${output}/" files="targetset_1.tmp,targetset_2.tmp" />
+ </targets>
+ </dependset>
+ <au:assertLogContains text="targetset_1.tmp&quot; is oldest target file" level="info" />
+ <au:assertLogContains text="sourceset_2.tmp&quot; is newest source" level="info" />
+ <au:assertLogContains text="Deleting all target files." level="verbose" />
+ <au:assertLogContains text="Deleting" level="info" />
+ <au:assertFileDoesntExist file="${output}/targetset_1.tmp" />
+ <au:assertFileDoesntExist file="${output}/targetset_2.tmp" />
+ </target>
+
+ <target name="testMissingSourceResource" depends="setUp">
+ <touch file="${output}/older.tmp" />
+ <dependset>
+ <sources>
+ <propertyresource name="thereisnosuchproperty" />
+ </sources>
+ <targets>
+ <filelist dir="${output}" files="older.tmp" />
+ </targets>
+ </dependset>
+ <au:assertLogContains text="1 nonexistent sources" level="verbose" />
+ <au:assertLogContains text="Deleting all target files." level="verbose" />
+ <au:assertLogDoesntContain text="Deleting" level="info" />
+ <au:assertLogDoesntContain text="Expected source propertyresource &quot;null&quot; is missing." level="info" />
+ <au:assertFileDoesntExist file="${output}/older.tmp" />
+ </target>
+
+ <target name="testMissingSourceResourceVerbose" depends="setUp">
+ <touch file="${output}/older.tmp" />
+ <dependset verbose="true">
+ <sources>
+ <propertyresource name="thereisnosuchproperty" />
+ </sources>
+ <targets>
+ <filelist dir="${output}" files="older.tmp" />
+ </targets>
+ </dependset>
+ <au:assertLogContains text="1 nonexistent sources" level="verbose" />
+ <au:assertLogContains text="Deleting all target files." level="verbose" />
+ <au:assertLogContains text="Deleting" level="info" />
+ <au:assertLogContains text="Expected source propertyresource &quot;null&quot; is missing." level="info" />
+ <au:assertFileDoesntExist file="${output}/older.tmp" />
+ </target>
+
+ <target name="testExistingSourceResource" depends="setUp">
+ <touch file="${output}/older.tmp" />
+ <property name="foo" value="bar" />
+ <dependset>
+ <sources>
+ <propertyresource name="foo" />
+ </sources>
+ <targets>
+ <filelist dir="${output}" files="older.tmp" />
+ </targets>
+ </dependset>
+ <au:assertLogDoesntContain text="Deleting all target files." level="verbose" />
+ <au:assertFileExists file="${output}/older.tmp" />
+ </target>
+
+ <target name="testMissingTargetDirectory" depends="setUp">
+ <au:assertFalse>
+ <available file="${output}/test9dir" type="dir" />
+ </au:assertFalse>
+ <touch file="${input}/test9.tmp" />
+ <dependset>
+ <srcfileset dir="." includes="test9.tmp" />
+ <targetfileset dir="${output}/test9dir" />
+ </dependset>
+ <au:assertLogDoesntContain text="Deleting all target files." level="verbose" />
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/dirname-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/dirname-test.xml
new file mode 100644
index 00000000..60caaf1a
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/dirname-test.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="dirname-test" basedir="." default="antunit" xmlns:au="antlib:org.apache.ant.antunit">
+
+ <import file="../antunit-base.xml"/>
+
+ <target name="test1">
+ <au:expectfailure expectedmessage="property attribute required">
+ <dirname/>
+ </au:expectfailure>
+ </target>
+
+ <target name="test2">
+ <au:expectfailure expectedmessage="file attribute required">
+ <dirname property="propname"/>
+ </au:expectfailure>
+ </target>
+
+ <target name="test3">
+ <au:expectfailure expectedmessage="property attribute required">
+ <dirname file="filename"/>
+ </au:expectfailure>
+ </target>
+
+ <target name="init-test4">
+ <condition property="valid.os">
+ <and>
+ <not><os family="dos"/></not><not><os family="netware"/></not>
+ </and>
+ </condition>
+ </target>
+
+ <target name="test4" depends="init-test4" if="valid.os">
+ <dirname property="local.dir" file="/usr/local/foo.txt"/>
+ <au:assertPropertyEquals name="local.dir"
+ value="${file.separator}usr${file.separator}local"/>
+ </target>
+
+ <target name="test5">
+ <dirname property="base.dir" file="foo.txt"/>
+ <au:assertPropertyEquals name="base.dir" value="${basedir}"/>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/ear-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/ear-test.xml
new file mode 100644
index 00000000..239c501a
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/ear-test.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project xmlns:au="antlib:org.apache.ant.antunit" default="antunit">
+ <import file="../antunit-base.xml" />
+
+ <target name="testOnlyOneAppXml">
+ <mkdir dir="${input}/META-INF"/>
+ <mkdir dir="${output}"/>
+ <touch file="${input}/META-INF/application.xml"/>
+ <touch file="${input}/x.xml"/>
+ <ear destfile="${output}/test.ear" appxml="${input}/x.xml">
+ <fileset dir="${input}"/>
+ </ear>
+ <au:assertLogContains text="Warning: selected ear files include a META-INF/application.xml which will be ignored (please use appxml attribute to ear task)"/>
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/echo-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/echo-test.xml
new file mode 100644
index 00000000..bd1fc05e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/echo-test.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<project name="echo-test" default="antunit" xmlns:au="antlib:org.apache.ant.antunit">
+ <import file="../antunit-base.xml" />
+
+ <target name="setUp">
+ <mkdir dir="${output}" />
+ </target>
+
+ <target name="test1">
+ <echo/>
+ <au:assertTrue>
+ <length length="0">
+ <au:logcontent />
+ </length>
+ </au:assertTrue>
+ </target>
+
+ <target name="test2">
+ <echo message="OUTPUT OF ECHO"/>
+ <au:assertLogContains text="OUTPUT OF ECHO" />
+ </target>
+
+ <target name="test3">
+ <echo>
+ This
+ is
+ a
+ multiline
+ message
+ </echo>
+ <au:assertTrue>
+ <resourcecount count="1">
+ <restrict>
+ <au:logcontent />
+ <contains text="This" />
+ <contains text="is" />
+ <contains text="a" />
+ <contains text="multiline" />
+ <contains text="message" />
+ </restrict>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testFile">
+ <echo file="${output}/echo.txt">Simple text</echo>
+ <au:assertTrue>
+ <resourcecount count="1">
+ <restrict>
+ <file file="${output}/echo.txt" />
+ <contains text="Simple text" />
+ </restrict>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testOutputFile">
+ <echo output="${output}/echo.txt">Simple text</echo>
+ <au:assertTrue>
+ <resourcecount count="1">
+ <restrict>
+ <file file="${output}/echo.txt" />
+ <contains text="Simple text" />
+ </restrict>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testAppend">
+ <echo file="${output}/echo.txt">Simple text</echo>
+ <echo file="${output}/echo.txt" append="true">Appended</echo>
+ <concat>
+ <file file="${output}/echo.txt" />
+ </concat>
+ <au:assertTrue>
+ <resourcecount count="1">
+ <restrict>
+ <file file="${output}/echo.txt" />
+ <contains text="Simple text" />
+ <contains text="Appended" />
+ </restrict>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testEmptyEncoding">
+ <echo file="${output}/echo.txt" encoding="">Simple text</echo>
+ <au:assertTrue>
+ <resourcecount count="1">
+ <restrict>
+ <file file="${output}/echo.txt" />
+ <contains text="Simple text" />
+ </restrict>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testUTF16Encoding">
+ <property name="char" value="&#169;" />
+ <echo file="${output}/echo16.txt" encoding="UTF-16">${char}</echo>
+ <loadfile property="out.16" srcfile="${output}/echo16.txt"
+ encoding="UTF-16"/>
+ <au:assertEquals expected="${char}" actual="${out.16}"/>
+ </target>
+
+ <target name="testUTF8Encoding">
+ <property name="char" value="&#169;" />
+ <echo file="${output}/echo8.txt" encoding="UTF8">${char}</echo>
+ <au:assertTrue>
+ <resourcecount count="1">
+ <restrict>
+ <concat encoding="UTF-8">
+ <file file="${output}/echo8.txt"/>
+ </concat>
+ <contains text="${char}" encoding="UTF-8"/>
+ </restrict>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/echoxml-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/echoxml-test.xml
new file mode 100644
index 00000000..d461d3d8
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/echoxml-test.xml
@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="antunit" xmlns:au="antlib:org.apache.ant.antunit">
+
+ <!-- note relies on antunit 1.1 -->
+ <import file="../antunit-base.xml"/>
+
+ <target name="setUp">
+ <property name="file" location="${output}/echoed.xml"/>
+ <mkdir dir="${output}"/>
+ <echoxml file="${file}">
+ <project>
+ <property name="foo" value="bar" />
+ <fail message="$$$${foo}=$${foo}">
+ <condition>
+ <istrue value="${mustfail}" />
+ </condition>
+ </fail>
+ </project>
+ </echoxml>
+ </target>
+
+ <target name="testPass">
+ <ant antfile="${file}"/>
+ </target>
+
+ <target name="testFail">
+ <au:expectfailure expectedmessage="${foo}=bar" message="Should have thrown an exception">
+ <ant antfile="${file}">
+ <property name="mustfail" value="true" />
+ </ant>
+ </au:expectfailure>
+ </target>
+
+ <target name="testEmpty">
+ <au:expectfailure expectedmessage="No nested XML specified" message="Should have thrown an exception">
+ <echoxml />
+ </au:expectfailure>
+ </target>
+
+ <!-- comment this and the next targets if you don't have the svn
+ trunk of antunit -->
+ <target name="test-ns-all">
+ <echoxml file="${file}" xmlns:a="antlib:a"
+ namespacepolicy="all">
+ <a:something a:foo="bar"/>
+ </echoxml>
+ <au:assertResourceContains resource="${file}" value="a:something"/>
+ <au:assertResourceContains resource="${file}" value="antlib:a"/>
+ </target>
+
+ <target name="test-ns-elementsOnly">
+ <echoxml file="${file}" xmlns:a="antlib:a"
+ namespacepolicy="elementsOnly">
+ <a:something a:foo="bar"/>
+ </echoxml>
+ <au:assertResourceContains resource="${file}" value="a:something"/>
+ <au:assertResourceContains resource="${file}" value="antlib:a"/>
+ </target>
+
+ <target name="test-ns-ignore">
+ <echoxml file="${file}" xmlns:a="antlib:a"
+ namespacepolicy="ignore">
+ <a:something a:foo="bar"/>
+ </echoxml>
+ <au:assertResourceContains resource="${file}" value="a:something"/>
+ <au:assertFalse message="Didn't expecte ${file} to contain antlib:a">
+ <resourcecontains resource="${file}" substring="antlib:a"/>
+ </au:assertFalse>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/exec/apply-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/exec/apply-test.xml
new file mode 100644
index 00000000..1b5a661a
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/exec/apply-test.xml
@@ -0,0 +1,792 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="apply-test" default="antunit"
+ xmlns:au="antlib:org.apache.ant.antunit">
+ <import file="../../antunit-base.xml" />
+
+ <property environment="env" />
+ <!-- UNIX -->
+ <available file="sh" filepath="${env.PATH}" property="sh.executable" />
+ <!-- CYGWIN -->
+ <available file="sh.exe" filepath="${env.PATH}" property="sh.exe.executable" />
+ <condition property="test.can.run">
+ <or>
+ <isset property="sh.executable" />
+ <isset property="sh.exe.executable" />
+ </or>
+ </condition>
+ <!-- UNIX -->
+ <available file="sed" filepath="${env.PATH}" property="sed.executable" />
+ <!-- CYGWIN -->
+ <available file="sed.exe" filepath="${env.PATH}" property="sed.exe.executable" />
+ <condition property="sed.can.run">
+ <or>
+ <isset property="sed.executable" />
+ <isset property="sed.exe.executable" />
+ </or>
+ </condition>
+ <!-- UNIX -->
+ <available file="echo" filepath="${env.PATH}" property="echo.executable" />
+ <!-- CYGWIN -->
+ <available file="echo.exe" filepath="${env.PATH}" property="echo.exe.executable" />
+ <condition property="echo.can.run">
+ <or>
+ <isset property="echo.executable" />
+ <isset property="echo.exe.executable" />
+ </or>
+ </condition>
+
+ <!-- UNIX -->
+ <available file="ls" filepath="${env.PATH}" property="ls.executable" />
+ <!-- CYGWIN -->
+ <available file="ls.exe" filepath="${env.PATH}" property="ls.exe.executable" />
+ <!-- piggyback the name of the executable here -->
+ <condition property="ls.can.run" value="ls">
+ <isset property="ls.executable" />
+ </condition>
+ <condition property="ls.can.run" value="ls.exe">
+ <isset property="ls.exe.executable" />
+ </condition>
+
+ <property name="eol" value="${line.separator}" />
+
+ <macrodef name="rcat">
+ <attribute name="refid" />
+ <sequential>
+ <echo>@@{refid}=@{refid}</echo>
+ <concat><resources refid="@{refid}" /></concat>
+ </sequential>
+ </macrodef>
+
+ <macrodef name="assertEmptyFile">
+ <attribute name="file" />
+ <sequential>
+ <au:assertTrue>
+ <and>
+ <available file="@{file}" type="file" />
+ <length length="0" file="@{file}" />
+ </and>
+ </au:assertTrue>
+ </sequential>
+ </macrodef>
+
+ <target name="xyz">
+ <mkdir dir="${input}"/>
+ <mkdir dir="${output}"/>
+ <echo file="${input}/x">s/x/blah/g${eol}</echo>
+ <echo file="${input}/y">s/y/blah/g${eol}</echo>
+ <echo file="${input}/z">s/z/blah/g${eol}</echo>
+ <fileset id="xyz" dir="${input}" includes="x,y,z" />
+ <filelist id="xyzlist" dir="${input}" files="x,y,z" />
+ <property name="x" location="${input}/x" />
+ <property name="y" location="${input}/y" />
+ <property name="z" location="${input}/z" />
+ </target>
+
+ <target name="testNoRedirect" depends="xyz" if="test.can.run">
+ <apply executable="sh">
+ <arg value="parrot.sh" />
+ <fileset refid="xyz" />
+ </apply>
+
+ <au:assertLogContains text="${x} out" />
+ <au:assertLogContains text="${y} out" />
+ <au:assertLogContains text="${z} out" />
+ <au:assertLogContains text="${x} err" />
+ <au:assertLogContains text="${y} err" />
+ <au:assertLogContains text="${z} err" />
+
+ <!--
+
+ The original junit test also verified that x out happened before
+ y out, and y out happened before z out; likewise with err output.
+ I added the antunit:logcontent resource hoping that would help,
+ but I think we need a way to filter (copy) resources first.
+ THAT necessitates the string-to-resource coding we are currently
+ discussing on the dev list IMO. MJB, 9/22/2006
+
+ -->
+
+ </target>
+
+ <target name="testRedirect1" depends="xyz" if="test.can.run">
+ <apply executable="sh" output="${output}/redirect.out" append="true">
+ <arg value="parrot.sh" />
+ <fileset refid="xyz" />
+ </apply>
+
+ <au:assertTrue>
+ <resourcecount count="1">
+ <restrict id="results">
+ <file file="${output}/redirect.out" />
+ <and xmlns="antlib:org.apache.tools.ant.types.resources.selectors">
+ <contains text="${x} out" />
+ <contains text="${y} out" />
+ <contains text="${z} out" />
+ <contains text="${x} err" />
+ <contains text="${y} err" />
+ <contains text="${z} err" />
+ </and>
+ </restrict>
+ </resourcecount>
+ </au:assertTrue>
+
+ </target>
+
+ <target name="testRedirect2" depends="xyz" if="test.can.run">
+ <apply executable="sh" output="${output}/redirect.out"
+ error="${output}/redirect.err" append="true">
+ <arg value="parrot.sh" />
+ <fileset refid="xyz" />
+ </apply>
+
+ <au:assertTrue>
+ <and>
+ <resourcesmatch astext="true">
+ <string value="${x} out${eol}${y} out${eol}${z} out" />
+ <file file="${output}/redirect.out" />
+ </resourcesmatch>
+ <resourcesmatch astext="true">
+ <string value="${x} err${eol}${y} err${eol}${z} err" />
+ <file file="${output}/redirect.err" />
+ </resourcesmatch>
+ </and>
+ </au:assertTrue>
+ </target>
+
+ <target name="testRedirect3" depends="xyz" if="test.can.run">
+ <apply executable="sh" logerror="true" append="true"
+ output="${output}/redirect.out" outputproperty="redirect3.out">
+ <arg value="parrot.sh" />
+ <fileset refid="xyz" />
+ </apply>
+
+ <au:assertTrue>
+ <resourcesmatch astext="true">
+ <string value="${x} out${eol}${y} out${eol}${z} out" />
+ <file file="${output}/redirect.out" />
+ <propertyresource name="redirect3.out" />
+ </resourcesmatch>
+ </au:assertTrue>
+
+ <au:assertLogContains text="${x} err" />
+ <au:assertLogContains text="${y} err" />
+ <au:assertLogContains text="${z} err" />
+ </target>
+
+ <target name="testRedirect4" depends="xyz" if="test.can.run">
+ <apply executable="sh" append="true"
+ error="${output}/redirect.err" errorproperty="redirect4.err"
+ output="${output}/redirect.out" outputproperty="redirect4.out">
+ <arg value="parrot.sh" />
+ <fileset refid="xyz" />
+ </apply>
+
+ <au:assertTrue>
+ <and>
+ <resourcesmatch astext="true">
+ <string value="${x} out${eol}${y} out${eol}${z} out" />
+ <file file="${output}/redirect.out" />
+ <propertyresource name="redirect4.out" />
+ </resourcesmatch>
+ <resourcesmatch astext="true">
+ <string value="${x} err${eol}${y} err${eol}${z} err" />
+ <file file="${output}/redirect.err" />
+ <propertyresource name="redirect4.err" />
+ </resourcesmatch>
+ </and>
+ </au:assertTrue>
+ </target>
+
+ <target name="testRedirect5" depends="xyz" if="sed.can.run">
+ <apply executable="sed" inputstring="x y z${eol}" append="true"
+ error="${output}/redirect.err" errorproperty="redirect5.err"
+ output="${output}/redirect.out" outputproperty="redirect5.out">
+ <arg value="-f" />
+ <fileset refid="xyz" />
+ </apply>
+
+ <au:assertTrue>
+ <and>
+ <resourcesmatch astext="true">
+ <propertyresource name="redirect5.out" />
+ <string value="blah y z${eol}x blah z${eol}x y blah" />
+ <file file="${output}/redirect.out" />
+ </resourcesmatch>
+ <equals arg1="${redirect5.err}" arg2="" />
+ </and>
+ </au:assertTrue>
+ <assertEmptyFile file="${output}/redirect.err" />
+ </target>
+
+ <target name="testRedirect6" depends="xyz" if="sed.can.run">
+ <echo file="${input}/redirect.in">x y z${eol}</echo>
+ <apply executable="sed" input="${input}/redirect.in" append="true"
+ error="${output}/redirect.err" errorproperty="redirect6.err"
+ output="${output}/redirect.out" outputproperty="redirect6.out">
+ <arg value="-f" />
+ <filelist refid="xyzlist" />
+ </apply>
+
+ <au:assertTrue>
+ <and>
+ <resourcesmatch astext="true">
+ <propertyresource name="redirect6.out" />
+ <string value="blah y z${eol}x blah z${eol}x y blah" />
+ <file file="${output}/redirect.out" />
+ </resourcesmatch>
+ <equals arg1="${redirect6.err}" arg2="" />
+ <length length="0"><file file="${output}/redirect.err" /></length>
+ </and>
+ </au:assertTrue>
+ </target>
+
+ <target name="testRedirect7" depends="xyz" if="sed.can.run">
+ <apply executable="sed" inputstring="x y z${eol}"
+ error="${output}/redirect.err" output="${output}/redirect.out"
+ outputproperty="redirect7.out">
+ <arg value="-f" />
+ <fileset refid="xyz" />
+ </apply>
+
+ <au:assertTrue>
+ <and>
+ <equals arg1="${redirect7.out}" arg2="blah y z" />
+ <resourcesmatch astext="true">
+ <file file="${output}/redirect.out" />
+ <string value="x y blah" />
+ </resourcesmatch>
+ </and>
+ </au:assertTrue>
+ <assertEmptyFile file="${output}/redirect.err" />
+ </target>
+
+ <target name="testRedirector1" description="fail"
+ depends="xyz" if="test.can.run">
+ <au:expectfailure
+ expectedmessage="cannot have &gt; 1 nested &lt;redirector&gt;s">
+ <apply executable="sh">
+ <arg value="parrot.sh" />
+ <fileset refid="xyz" />
+ <redirector output="${output}/redirector.out" />
+ <redirector output="${output}/whocares" />
+ </apply>
+ </au:expectfailure>
+ </target>
+
+ <target name="testRedirector2" depends="xyz" if="test.can.run">
+ <apply executable="sh">
+ <arg value="parrot.sh" />
+ <fileset refid="xyz" />
+ <redirector output="${output}/redirector.out" append="true" />
+ </apply>
+ <au:assertTrue>
+ <resourcecount count="1">
+ <restrict id="results">
+ <file file="${output}/redirector.out" />
+ <and xmlns="antlib:org.apache.tools.ant.types.resources.selectors">
+ <contains text="${x} out" />
+ <contains text="${y} out" />
+ <contains text="${z} out" />
+ <contains text="${x} err" />
+ <contains text="${y} err" />
+ <contains text="${z} err" />
+ </and>
+ </restrict>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testRedirector3" depends="xyz" if="test.can.run">
+ <apply executable="sh">
+ <arg value="parrot.sh" />
+ <fileset refid="xyz" />
+ <redirector append="true"
+ output="${output}/redirector.out"
+ error="${output}/redirector.err" />
+ </apply>
+ <au:assertTrue>
+ <and>
+ <resourcesmatch astext="true">
+ <string value="${x} out${eol}${y} out${eol}${z} out" />
+ <file file="${output}/redirector.out" />
+ </resourcesmatch>
+ <resourcesmatch astext="true">
+ <string value="${x} err${eol}${y} err${eol}${z} err" />
+ <file file="${output}/redirector.err" />
+ </resourcesmatch>
+ </and>
+ </au:assertTrue>
+ </target>
+
+ <target name="testRedirector4" depends="xyz" if="test.can.run">
+ <apply executable="sh">
+ <arg value="parrot.sh" />
+ <fileset refid="xyz" />
+ <redirector output="${output}/redirector.out" logerror="true"
+ append="true" outputproperty="redirector4.out" />
+ </apply>
+
+ <au:assertTrue>
+ <resourcesmatch astext="true">
+ <string value="${x} out${eol}${y} out${eol}${z} out" />
+ <file file="${output}/redirector.out" />
+ <propertyresource name="redirector4.out" />
+ </resourcesmatch>
+ </au:assertTrue>
+
+ <au:assertLogContains text="${x} err" />
+ <au:assertLogContains text="${y} err" />
+ <au:assertLogContains text="${z} err" />
+ </target>
+
+ <target name="testRedirector5" depends="xyz" if="test.can.run">
+ <apply executable="sh">
+ <redirector error="${output}/redirector.err"
+ errorproperty="redirector5.err"
+ output="${output}/redirector.out"
+ outputproperty="redirector5.out"
+ append="true" />
+ <arg value="parrot.sh" />
+ <fileset refid="xyz" />
+ </apply>
+ <au:assertTrue>
+ <and>
+ <resourcesmatch astext="true">
+ <string value="${x} out${eol}${y} out${eol}${z} out" />
+ <file file="${output}/redirector.out" />
+ <propertyresource name="redirector5.out" />
+ </resourcesmatch>
+ <resourcesmatch astext="true">
+ <string value="${x} err${eol}${y} err${eol}${z} err" />
+ <file file="${output}/redirector.err" />
+ <propertyresource name="redirector5.err" />
+ </resourcesmatch>
+ </and>
+ </au:assertTrue>
+ </target>
+
+ <target name="testRedirector6" depends="xyz" if="test.can.run">
+ <apply executable="sh">
+ <redirector append="true" outputproperty="redirector6.out"
+ errorproperty="redirector6.err">
+ <outputmapper type="merge" to="${output}/redirector.out" />
+ <errormapper type="merge" to="${output}/redirector.err" />
+ </redirector>
+ <arg value="parrot.sh" />
+ <filelist refid="xyzlist" />
+ </apply>
+
+ <au:assertTrue>
+ <and>
+ <resourcesmatch astext="true">
+ <string value="${x} out${eol}${y} out${eol}${z} out" />
+ <file file="${output}/redirector.out" />
+ <propertyresource name="redirector6.out" />
+ </resourcesmatch>
+ <resourcesmatch astext="true">
+ <string value="${x} err${eol}${y} err${eol}${z} err" />
+ <file file="${output}/redirector.err" />
+ <propertyresource name="redirector6.err" />
+ </resourcesmatch>
+ </and>
+ </au:assertTrue>
+ </target>
+
+ <target name="testRedirector7" depends="xyz" if="test.can.run">
+ <apply executable="sh">
+ <redirector append="true" outputproperty="redirector7.out"
+ errorproperty="redirector7.err">
+ <outputmapper type="merge" to="${output}/redirector.out" />
+ <errormapper type="merge" to="${output}/redirector.err" />
+ <errorfilterchain>
+ <replacestring from="err" to="ERROR!!!" />
+ </errorfilterchain>
+ </redirector>
+ <arg value="parrot.sh" />
+ <fileset refid="xyz" />
+ </apply>
+
+ <au:assertTrue>
+ <and>
+ <resourcesmatch astext="true">
+ <string value="${x} out${eol}${y} out${eol}${z} out" />
+ <file file="${output}/redirector.out" />
+ <propertyresource name="redirector7.out" />
+ </resourcesmatch>
+ <resourcesmatch astext="true">
+ <string value="${x} ERROR!!!${eol}${y} ERROR!!!${eol}${z} ERROR!!!" />
+ <file file="${output}/redirector.err" />
+ <propertyresource name="redirector7.err" />
+ </resourcesmatch>
+ </and>
+ </au:assertTrue>
+ </target>
+
+ <target name="testRedirector8" depends="xyz" if="sed.can.run">
+ <echo file="${input}/redirector.in">x y z${eol}</echo>
+ <apply executable="sed">
+ <redirector append="true" outputproperty="redirector8.out"
+ errorproperty="redirector8.err">
+ <inputmapper type="merge" to="${input}/redirector.in" />
+ <outputmapper type="merge" to="${output}/redirector.out" />
+ <errormapper type="merge" to="${output}/redirector.err" />
+ </redirector>
+ <arg value="-f" />
+ <fileset refid="xyz" />
+ </apply>
+
+ <au:assertTrue>
+ <and>
+ <resourcesmatch astext="true">
+ <propertyresource name="redirector8.out" />
+ <string value="blah y z${eol}x blah z${eol}x y blah" />
+ <file file="${output}/redirector.out" />
+ </resourcesmatch>
+ <equals arg1="${redirector8.err}" arg2="" />
+ </and>
+ </au:assertTrue>
+ <assertEmptyFile file="${output}/redirector.err" />
+ </target>
+
+ <macrodef name="valRor9-12">
+ <attribute name="n" />
+ <sequential>
+ <au:assertTrue>
+ <and>
+ <equals arg1="" arg2="${redirector@{n}.err}" />
+ <resourcesmatch astext="true">
+ <string value="blah after y after z${eol}x after blah after z${eol}x after y after blah" />
+ <propertyresource name="redirector@{n}.out" />
+ <file file="${output}/redirector.out" />
+ </resourcesmatch>
+ </and>
+ </au:assertTrue>
+ <assertEmptyFile file="${output}/redirector.err" />
+ </sequential>
+ </macrodef>
+
+ <target name="testRedirector9" depends="xyz" if="sed.can.run">
+ <echo file="${input}/redirector.in">x before y before z${eol}</echo>
+ <apply executable="sed">
+ <redirector outputproperty="redirector9.out"
+ errorproperty="redirector9.err" append="true">
+ <inputfilterchain>
+ <replacestring from="before" to="after" />
+ </inputfilterchain>
+ <inputmapper type="merge" to="${input}/redirector.in" />
+ <outputmapper type="merge" to="${output}/redirector.out" />
+ <errormapper type="merge" to="${output}/redirector.err" />
+ </redirector>
+ <arg value="-f" />
+ <fileset refid="xyz" />
+ </apply>
+
+ <valRor9-12 n="9" />
+ </target>
+
+ <target name="testRedirector10" depends="xyz" if="sed.can.run">
+ <echo file="${input}/redirector.in">x before y before z${eol}</echo>
+ <apply executable="sed">
+ <redirector outputproperty="redirector10.out"
+ errorproperty="redirector10.err" append="true">
+ <outputfilterchain>
+ <replacestring from="before" to="after" />
+ </outputfilterchain>
+ <outputmapper type="merge" to="${output}/redirector.out" />
+ <errormapper type="merge" to="${output}/redirector.err" />
+ </redirector>
+ <arg value="-f" />
+ <srcfile />
+ <arg value="${input}/redirector.in" />
+ <filelist refid="xyzlist" />
+ </apply>
+
+ <valRor9-12 n="10" />
+ </target>
+
+ <target name="testRedirector11" depends="xyz" if="sed.can.run">
+ <apply executable="sed">
+ <redirector outputproperty="redirector11.out"
+ errorproperty="redirector11.err"
+ inputstring="x before y before z${eol}"
+ append="true">
+ <inputfilterchain>
+ <replacestring from="before" to="after" />
+ </inputfilterchain>
+ <outputmapper type="merge" to="${output}/redirector.out" />
+ <errormapper type="merge" to="${output}/redirector.err" />
+ </redirector>
+ <arg value="-f" />
+ <fileset refid="xyz" />
+ </apply>
+
+ <valRor9-12 n="11" />
+ </target>
+
+ <target name="testRedirector12" depends="xyz" if="sed.can.run">
+ <echo file="${input}/redirector.in">x before y before z${eol}</echo>
+ <apply executable="sed" output="${output}/redirector.out"
+ error="${output}/redirector.err">
+ <redirector outputproperty="redirector12.out"
+ errorproperty="redirector12.err" append="true">
+ <outputfilterchain>
+ <replacestring from="before" to="after" />
+ </outputfilterchain>
+ <outputmapper type="glob" from="nomatch" to="nomatchout" />
+ <errormapper type="glob" from="nomatch" to="nomatcherr" />
+ </redirector>
+ <arg value="-f" />
+ <srcfile />
+ <arg value="${input}/redirector.in" />
+ <filelist refid="xyzlist" />
+ </apply>
+
+ <valRor9-12 n="12" />
+ </target>
+
+ <target name="testRedirector13" depends="xyz" if="test.can.run">
+ <apply executable="sh">
+ <redirector>
+ <outputfilterchain>
+ <replacestring from="out" to="OUTPUT???" />
+ </outputfilterchain>
+ <errorfilterchain>
+ <replacestring from="err" to="ERROR!!!" />
+ </errorfilterchain>
+ </redirector>
+ <arg value="parrot.sh" />
+ <fileset refid="xyz" />
+ </apply>
+
+ <au:assertLogContains text="${x} OUTPUT???" />
+ <au:assertLogContains text="${y} OUTPUT???" />
+ <au:assertLogContains text="${z} OUTPUT???" />
+ <au:assertLogContains text="${x} ERROR!!!" />
+ <au:assertLogContains text="${y} ERROR!!!" />
+ <au:assertLogContains text="${z} ERROR!!!" />
+ </target>
+
+ <target name="testRedirector14" depends="xyz" if="sed.can.run">
+ <echo file="${input}/redirector.in">z before y before x${eol}</echo>
+ <apply executable="sed">
+ <redirector append="true"
+ inputstring="x before y before z${eol}">
+ <outputfilterchain>
+ <replacestring from="before" to="after" />
+ </outputfilterchain>
+ <inputmapper type="glob" from="x" to="${input}/redirector.in" />
+ <outputmapper type="glob" from="y" to="${output}/redirector.out" />
+ <errormapper type="glob" from="z" to="${output}/redirector.err" />
+ </redirector>
+ <arg value="-f" />
+ <fileset refid="xyz" />
+ </apply>
+
+ <assertEmptyFile file="${output}/redirector.err" />
+
+ <au:assertTrue>
+ <and>
+ <resourcesmatch astext="true">
+ <string value="x after blah after z" />
+ <file file="${output}/redirector.out" />
+ </resourcesmatch>
+ </and>
+ </au:assertTrue>
+ <au:assertLogContains text="z after y after blahx after y after blah"/>
+ </target>
+
+ <target name="pad">
+ <condition property="pad" value="">
+ <or>
+ <not>
+ <os family="dos" />
+ </not>
+ <not>
+ <or>
+ <equals arg1="${ant.java.version}" arg2="1.1" />
+ <equals arg1="${ant.java.version}" arg2="1.2" />
+ </or>
+ </not>
+ </or>
+ </condition>
+
+ <condition property="pad" value=" ">
+ <and>
+ <os family="dos" />
+ <or>
+ <equals arg1="${ant.java.version}" arg2="1.2" />
+ </or>
+ </and>
+ </condition>
+
+ </target>
+
+ <target name="testIgnoreMissing" depends="xyz,pad" if="echo.can.run">
+ <filelist id="xylist" dir="${input}" files="x,y" />
+ <delete file="${input}/z" />
+
+ <pathconvert property="xy" pathsep="${pad}${eol}" refid="xylist" />
+
+ <pathconvert property="xyz" pathsep="${pad}${eol}" refid="xyzlist" />
+
+ <apply executable="echo" ignoremissing="true"
+ outputproperty="ignoretrue" append="true">
+ <filelist refid="xyzlist" />
+ </apply>
+
+ <apply executable="echo" ignoremissing="false"
+ outputproperty="ignorefalse" append="true">
+ <filelist refid="xyzlist" />
+ </apply>
+
+ <au:assertTrue>
+ <and>
+ <equals arg1="${xy}${pad}" arg2="${ignoretrue}" />
+ <equals arg1="${xyz}${pad}" arg2="${ignorefalse}" />
+ </and>
+ </au:assertTrue>
+ </target>
+
+ <target name="testForce" depends="xyz,pad" if="echo.can.run">
+ <presetdef name="ekko">
+ <apply executable="echo" append="true" dest="${input}">
+ <filelist refid="xyzlist" />
+ <mapper type="identity" />
+ </apply>
+ </presetdef>
+
+ <pathconvert property="xyz" pathsep="${pad}${eol}" refid="xyzlist" />
+
+ <ekko outputproperty="foo" />
+ <ekko outputproperty="bar" force="true" />
+
+ <au:assertTrue>
+ <and>
+ <equals arg1="${foo}" arg2="" />
+ <equals arg1="${bar}" arg2="${xyz}" />
+ </and>
+ </au:assertTrue>
+ </target>
+
+ <target name="testNoDest" depends="xyz" if="echo.can.run">
+ <presetdef name="ekko">
+ <apply executable="echo" addsourcefile="false" force="true">
+ <filelist dir="${input}" files="x" />
+ <globmapper from="*" to="${input}/*" />
+ <targetfile />
+ </apply>
+ </presetdef>
+ <ekko outputproperty="dest" dest="${input}" />
+ <ekko outputproperty="nodest" />
+
+ <au:assertFileDoesntExist file="${dest}" />
+ <au:assertFileExists file="${nodest}" />
+ </target>
+
+ <target name="testLsPath" if="ls.can.run" depends="xyz">
+ <apply executable="ls" parallel="false" outputproperty="lsPathOut"
+ force="true" dest="${input}" append="true" type="both">
+ <path path="${env.PATH}" />
+ <identitymapper/>
+ </apply>
+ <au:assertTrue>
+ <resourcecount count="1">
+ <restrict>
+ <propertyresource name="lsPathOut" />
+ <containsregexp expression="^${ls.can.run}$"
+ xmlns="antlib:org.apache.tools.ant.types.resources.selectors" />
+ </restrict>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testLsPathParallel" if="ls.can.run" depends="xyz">
+ <apply executable="ls" parallel="true" outputproperty="lsPathParallelOut"
+ force="true" dest="${input}" append="true" type="both">
+ <path path="${env.PATH}" />
+ <identitymapper/>
+ </apply>
+ <au:assertTrue>
+ <resourcecount count="1">
+ <restrict>
+ <propertyresource name="lsPathParallelOut" />
+ <containsregexp expression="^${ls.can.run}$"
+ xmlns="antlib:org.apache.tools.ant.types.resources.selectors" />
+ </restrict>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testSrcfilePrefix" if="test.can.run" depends="xyz">
+ <apply executable="sh" force="true">
+ <arg value="parrot.sh" />
+ <srcfile prefix="-Dfoo="/>
+ <fileset refid="xyz" />
+ </apply>
+ <au:assertLogContains text="-Dfoo=${x} out" />
+ <au:assertLogContains text="-Dfoo=${y} out" />
+ <au:assertLogContains text="-Dfoo=${z} out" />
+ </target>
+
+ <target name="testTargetfileSuffix" if="test.can.run" depends="xyz">
+ <apply executable="sh" addsourcefile="false" dest="${input}">
+ <arg value="parrot.sh" />
+ <targetfile suffix=",x"/>
+ <fileset refid="xyz" />
+ <globmapper from="*" to="*.bar"/>
+ </apply>
+ <au:assertLogContains text="${x}.bar,x out" />
+ <au:assertLogContains text="${y}.bar,x out" />
+ <au:assertLogContains text="${z}.bar,x out" />
+ </target>
+
+ <target name="testRedirectorWithParallel" if="test.can.run" depends="xyz">
+ <apply executable="sh" dest="${input}" parallel="true" addsourcefile="yes">
+ <arg value="parrot.sh" />
+ <targetfile/>
+ <fileset refid="xyz" />
+ <globmapper from="*" to="*.bar"/>
+ <redirector output="${output}/all_out.txt" append="yes"/>
+ </apply>
+ <au:assertResourceContains resource="${output}/all_out.txt"
+ value="x.bar out"/>
+ <au:assertResourceContains resource="${output}/all_out.txt"
+ value="x.bar err"/>
+ <au:assertResourceContains resource="${output}/all_out.txt"
+ value="x out"/>
+ <au:assertResourceContains resource="${output}/all_out.txt"
+ value="x err"/>
+ <au:assertResourceContains resource="${output}/all_out.txt"
+ value="y.bar out"/>
+ <au:assertResourceContains resource="${output}/all_out.txt"
+ value="y.bar err"/>
+ <au:assertResourceContains resource="${output}/all_out.txt"
+ value="y out"/>
+ <au:assertResourceContains resource="${output}/all_out.txt"
+ value="y err"/>
+ <au:assertResourceContains resource="${output}/all_out.txt"
+ value="z.bar out"/>
+ <au:assertResourceContains resource="${output}/all_out.txt"
+ value="z.bar err"/>
+ <au:assertResourceContains resource="${output}/all_out.txt"
+ value="z out"/>
+ <au:assertResourceContains resource="${output}/all_out.txt"
+ value="z err"/>
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/exec/exec-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/exec/exec-test.xml
new file mode 100644
index 00000000..25b00889
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/exec/exec-test.xml
@@ -0,0 +1,710 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="exec-test" default="antunit" xmlns:au="antlib:org.apache.ant.antunit">
+ <import file="../../antunit-base.xml" />
+
+ <macrodef name="assert-trimmed-resource-content">
+ <attribute name="content" />
+ <attribute name="astext" default="true" />
+ <element name="resource" implicit="true" />
+ <sequential>
+ <au:assertTrue>
+ <resourcesmatch astext="@{astext}">
+ <string value="@{content}" />
+ <concat>
+ <resource />
+ <filterchain>
+ <trim />
+ </filterchain>
+ </concat>
+ </resourcesmatch>
+ </au:assertTrue>
+ </sequential>
+ </macrodef>
+
+ <target name="setUp">
+ <mkdir dir="${input}" />
+ <mkdir dir="${output}" />
+ <property environment="env" />
+ <!-- UNIX -->
+ <available file="sh" filepath="${env.PATH}" property="sh.executable" />
+ <!-- CYGWIN -->
+ <available file="sh.exe" filepath="${env.PATH}" property="sh.exe.executable" />
+ <condition property="test.can.run">
+ <or>
+ <isset property="sh.executable" />
+ <isset property="sh.exe.executable" />
+ </or>
+ </condition>
+ <!-- UNIX -->
+ <available file="wc" filepath="${env.PATH}" property="wc.executable" />
+ <!-- CYGWIN -->
+ <available file="wc.exe" filepath="${env.PATH}" property="wc.exe.executable" />
+ <condition property="wc.can.run">
+ <or>
+ <isset property="wc.executable" />
+ <isset property="wc.exe.executable" />
+ </or>
+ </condition>
+ <!-- UNIX -->
+ <available file="cat" filepath="${env.PATH}" property="cat.executable" />
+ <!-- CYGWIN -->
+ <available file="cat.exe" filepath="${env.PATH}" property="cat.exe.executable" />
+ <condition property="cat.can.run">
+ <or>
+ <isset property="cat.executable" />
+ <isset property="cat.exe.executable" />
+ </or>
+ </condition>
+ </target>
+
+ <target name="test-no-redirect" depends="setUp" if="test.can.run">
+ <exec executable="sh">
+ <arg value="parrot.sh" />
+ <arg value="${ant.file}" />
+ </exec>
+ <au:assertLogContains text="${ant.file} out" />
+ <au:assertLogContains text="${ant.file} err" />
+ </target>
+
+ <target name="test-redirect-output" depends="setUp" if="test.can.run">
+ <exec executable="sh" output="${output}/redirect.out">
+ <arg value="parrot.sh" />
+ <arg value="${ant.file}" />
+ </exec>
+ <au:assertTrue>
+ <resourcesmatch astext="true">
+ <string>${ant.file} out${line.separator}${ant.file} err</string>
+ <file file="${output}/redirect.out" />
+ </resourcesmatch>
+ </au:assertTrue>
+ </target>
+
+ <target name="test-redirect-output-error" depends="setUp" if="test.can.run">
+ <exec executable="sh" output="${output}/redirect.out" error="${output}/redirect.err">
+ <arg value="parrot.sh" />
+ <arg value="${ant.file}" />
+ </exec>
+ <au:assertTrue>
+ <resourcesmatch astext="true">
+ <string>${ant.file} out</string>
+ <file file="${output}/redirect.out" />
+ </resourcesmatch>
+ </au:assertTrue>
+ <au:assertTrue>
+ <resourcesmatch astext="true">
+ <string>${ant.file} err</string>
+ <file file="${output}/redirect.err" />
+ </resourcesmatch>
+ </au:assertTrue>
+ </target>
+
+ <target name="test-redirect-output-outputproperty-logerror" depends="setUp" if="test.can.run">
+ <exec executable="sh" logerror="true"
+ output="${output}/redirect.out" outputproperty="redirect.out">
+ <arg value="parrot.sh" />
+ <arg value="${ant.file}" />
+ </exec>
+ <au:assertTrue>
+ <resourcesmatch astext="true">
+ <string>${ant.file} out</string>
+ <file file="${output}/redirect.out" />
+ <propertyresource name="redirect.out" />
+ </resourcesmatch>
+ </au:assertTrue>
+ <au:assertLogContains text="${ant.file} err" />
+ </target>
+
+ <target name="test-redirect-output-outputproperty-error-errorproperty"
+ depends="setUp" if="test.can.run">
+ <exec executable="sh"
+ error="${output}/redirect.err" errorproperty="redirect.err"
+ output="${output}/redirect.out" outputproperty="redirect.out">
+ <arg value="parrot.sh" />
+ <arg value="${ant.file}" />
+ </exec>
+ <au:assertTrue>
+ <resourcesmatch astext="true">
+ <string>${ant.file} out</string>
+ <file file="${output}/redirect.out" />
+ <propertyresource name="redirect.out" />
+ </resourcesmatch>
+ </au:assertTrue>
+ <au:assertTrue>
+ <resourcesmatch astext="true">
+ <string>${ant.file} err</string>
+ <file file="${output}/redirect.err" />
+ <propertyresource name="redirect.err" />
+ </resourcesmatch>
+ </au:assertTrue>
+ </target>
+
+ <target name="test-redirect-inputstring-output-outputproperty-error-errorproperty"
+ depends="setUp" if="wc.can.run">
+ <exec executable="wc" inputstring="x y z"
+ error="${output}/redirect.err" errorproperty="redirect.err"
+ output="${output}/redirect.out" outputproperty="redirect.out">
+ <arg value="-w" />
+ </exec>
+ <au:assertTrue>
+ <length length="0">
+ <file file="${output}/redirect.err" />
+ <propertyresource name="redirect.err" />
+ </length>
+ </au:assertTrue>
+ <assert-trimmed-resource-content content="3">
+ <file file="${output}/redirect.out" />
+ </assert-trimmed-resource-content>
+ <assert-trimmed-resource-content content="3">
+ <propertyresource name="redirect.out" />
+ </assert-trimmed-resource-content>
+ </target>
+
+ <target name="test-redirect-input-output-outputproperty-error-errorproperty"
+ depends="setUp" if="wc.can.run">
+ <echo file="${input}/redirect.in">x y z</echo>
+ <exec executable="wc" input="${input}/redirect.in"
+ error="${output}/redirect.err" errorproperty="redirect.err"
+ output="${output}/redirect.out" outputproperty="redirect.out">
+ <arg value="-w" />
+ </exec>
+ <au:assertTrue>
+ <length length="0">
+ <file file="${output}/redirect.err" />
+ <propertyresource name="redirect.err" />
+ </length>
+ </au:assertTrue>
+ <assert-trimmed-resource-content content="3">
+ <file file="${output}/redirect.out" />
+ </assert-trimmed-resource-content>
+ <assert-trimmed-resource-content content="3">
+ <propertyresource name="redirect.out" />
+ </assert-trimmed-resource-content>
+ </target>
+
+ <target name="test-redirect-input-output-outputproperty-error"
+ depends="setUp" if="wc.can.run">
+ <exec executable="wc" inputstring="x y z"
+ error="${output}/redirect.err"
+ output="${output}/redirect.out" outputproperty="redirect.out">
+ <arg value="-w" />
+ </exec>
+ <au:assertTrue>
+ <length length="0">
+ <file file="${output}/redirect.err" />
+ </length>
+ </au:assertTrue>
+ <concat>
+ <file file="${output}/redirect.out" />
+ <propertyresource name="redirect.out" />
+ </concat>
+ <assert-trimmed-resource-content content="3">
+ <file file="${output}/redirect.out" />
+ </assert-trimmed-resource-content>
+ <assert-trimmed-resource-content content="3">
+ <propertyresource name="redirect.out" />
+ </assert-trimmed-resource-content>
+ </target>
+
+ <target name="test-multiple-redirectors" description="fail"
+ depends="setUp" if="test.can.run">
+ <au:expectfailure>
+ <exec executable="sh">
+ <arg value="parrot.sh" />
+ <arg value="${ant.file}" />
+ <redirector output="${output}/redirector.out" />
+ <redirector output="whocares" />
+ </exec>
+ </au:expectfailure>
+ </target>
+
+ <target name="test-redirector-output" depends="setUp" if="test.can.run">
+ <exec executable="sh">
+ <arg value="parrot.sh" />
+ <arg value="${ant.file}" />
+ <redirector output="${output}/redirector.out" />
+ </exec>
+ <au:assertTrue>
+ <resourcesmatch astext="true">
+ <string>${ant.file} out${line.separator}${ant.file} err</string>
+ <file file="${output}/redirector.out" />
+ </resourcesmatch>
+ </au:assertTrue>
+ </target>
+
+ <target name="test-redirector-output-error" depends="setUp" if="test.can.run">
+ <exec executable="sh">
+ <arg value="parrot.sh" />
+ <arg value="${ant.file}" />
+ <redirector output="${output}/redirector.out" error="${output}/redirector.err" />
+ </exec>
+ <au:assertTrue>
+ <resourcesmatch astext="true">
+ <string>${ant.file} out</string>
+ <file file="${output}/redirector.out" />
+ </resourcesmatch>
+ </au:assertTrue>
+ <au:assertTrue>
+ <resourcesmatch astext="true">
+ <string>${ant.file} err</string>
+ <file file="${output}/redirector.err" />
+ </resourcesmatch>
+ </au:assertTrue>
+ </target>
+
+ <target name="test-redirector-output-outputproperty-logerror" depends="setUp" if="test.can.run">
+ <exec executable="sh">
+ <arg value="parrot.sh" />
+ <arg value="${ant.file}" />
+ <redirector output="${output}/redirector.out" logerror="true"
+ outputproperty="redirector.out" />
+ </exec>
+ <au:assertTrue>
+ <resourcesmatch astext="true">
+ <string>${ant.file} out</string>
+ <file file="${output}/redirector.out" />
+ <propertyresource name="redirector.out" />
+ </resourcesmatch>
+ </au:assertTrue>
+ <au:assertLogContains text="${ant.file} err" />
+ </target>
+
+ <target name="test-redirector-output-outputproperty-error-errorproperty"
+ depends="setUp" if="test.can.run">
+ <exec executable="sh">
+ <redirector error="${output}/redirector.err" errorproperty="redirector.err"
+ output="${output}/redirector.out" outputproperty="redirector.out" />
+ <arg value="parrot.sh" />
+ <arg value="${ant.file}" />
+ </exec>
+ <au:assertTrue>
+ <resourcesmatch astext="true">
+ <string>${ant.file} out</string>
+ <file file="${output}/redirector.out" />
+ <propertyresource name="redirector.out" />
+ </resourcesmatch>
+ </au:assertTrue>
+ <au:assertTrue>
+ <resourcesmatch astext="true">
+ <string>${ant.file} err</string>
+ <file file="${output}/redirector.err" />
+ <propertyresource name="redirector.err" />
+ </resourcesmatch>
+ </au:assertTrue>
+ </target>
+
+ <target name="test-redirector-outputproperty-errorproperty-outputmapper-errormapper"
+ depends="setUp" if="test.can.run">
+ <exec executable="sh">
+ <redirector outputproperty="redirector.out"
+ errorproperty="redirector.err">
+ <outputmapper type="merge" to="${output}/redirector.out" />
+ <errormapper type="merge" to="${output}/redirector.err" />
+ </redirector>
+ <arg value="parrot.sh" />
+ <arg value="${ant.file}" />
+ </exec>
+ <au:assertTrue>
+ <resourcesmatch astext="true">
+ <string>${ant.file} out</string>
+ <file file="${output}/redirector.out" />
+ <propertyresource name="redirector.out" />
+ </resourcesmatch>
+ </au:assertTrue>
+ <au:assertTrue>
+ <resourcesmatch astext="true">
+ <string>${ant.file} err</string>
+ <file file="${output}/redirector.err" />
+ <propertyresource name="redirector.err" />
+ </resourcesmatch>
+ </au:assertTrue>
+ </target>
+
+ <target name="test-redirector-outputproperty-errorproperty-outputmapper-errormapper-errorfilterchain"
+ depends="setUp" if="test.can.run">
+ <exec executable="sh">
+ <redirector outputproperty="redirector.out"
+ errorproperty="redirector.err">
+ <outputmapper type="merge" to="${output}/redirector.out" />
+ <errormapper type="merge" to="${output}/redirector.err" />
+ <errorfilterchain>
+ <replacestring from="err" to="ERROR!!!" />
+ </errorfilterchain>
+ </redirector>
+ <arg value="parrot.sh" />
+ <arg value="${ant.file}" />
+ </exec>
+ <au:assertTrue>
+ <resourcesmatch astext="true">
+ <string>${ant.file} out</string>
+ <file file="${output}/redirector.out" />
+ <propertyresource name="redirector.out" />
+ </resourcesmatch>
+ </au:assertTrue>
+ <au:assertTrue>
+ <resourcesmatch astext="true">
+ <string>${ant.file} ERROR!!!</string>
+ <file file="${output}/redirector.err" />
+ <propertyresource name="redirector.err" />
+ </resourcesmatch>
+ </au:assertTrue>
+ </target>
+
+ <target name="test-redirector-outputproperty-errorproperty-inputmapper-outputmapper-errormapper"
+ depends="setUp" if="wc.can.run">
+ <echo file="${input}/redirector.in">x y z</echo>
+ <exec executable="wc">
+ <redirector outputproperty="redirector.out"
+ errorproperty="redirector.err">
+ <inputmapper type="merge" to="${input}/redirector.in" />
+ <outputmapper type="merge" to="${output}/redirector.out" />
+ <errormapper type="merge" to="${output}/redirector.err" />
+ </redirector>
+ <arg value="-w" />
+ </exec>
+ <assert-trimmed-resource-content content="3">
+ <file file="${output}/redirector.out" />
+ </assert-trimmed-resource-content>
+ <assert-trimmed-resource-content content="3">
+ <propertyresource name="redirector.out" />
+ </assert-trimmed-resource-content>
+ <au:assertTrue>
+ <length length="0">
+ <file file="${output}/redirector.err" />
+ <propertyresource name="redirector.err" />
+ </length>
+ </au:assertTrue>
+ </target>
+
+ <target name="test-redirector-outputproperty-errorproperty-inputfilterchain-inputmapper-outputmapper-errormapper"
+ depends="setUp" if="cat.can.run">
+ <echo file="${input}/redirector.in">blah before blah</echo>
+ <exec executable="cat">
+ <redirector outputproperty="redirector.out"
+ errorproperty="redirector.err">
+ <inputfilterchain>
+ <replacestring from="before" to="after" />
+ </inputfilterchain>
+ <inputmapper type="merge" to="${input}/redirector.in" />
+ <outputmapper type="merge" to="${output}/redirector.out" />
+ <errormapper type="merge" to="${output}/redirector.err" />
+ </redirector>
+ </exec>
+ <au:assertTrue>
+ <resourcesmatch astext="true">
+ <string value="blah after blah" />
+ <file file="${output}/redirector.out" />
+ <propertyresource name="redirector.out" />
+ </resourcesmatch>
+ </au:assertTrue>
+ <au:assertTrue>
+ <length length="0">
+ <file file="${output}/redirector.err" />
+ <propertyresource name="redirector.err" />
+ </length>
+ </au:assertTrue>
+ </target>
+
+ <target name="test-redirector-outputproperty-errorproperty-outputfilterchain-outputmapper-errormapper"
+ depends="setUp" if="cat.can.run">
+ <echo file="${input}/redirector.in">blah before blah</echo>
+ <exec executable="cat">
+ <redirector outputproperty="redirector.out"
+ errorproperty="redirector.err">
+ <outputfilterchain>
+ <replacestring from="before" to="after" />
+ </outputfilterchain>
+ <outputmapper type="merge" to="${output}/redirector.out" />
+ <errormapper type="merge" to="${output}/redirector.err" />
+ </redirector>
+ <arg value="${input}/redirector.in" />
+ </exec>
+ <au:assertTrue>
+ <resourcesmatch astext="true">
+ <string value="blah after blah" />
+ <file file="${output}/redirector.out" />
+ <propertyresource name="redirector.out" />
+ </resourcesmatch>
+ </au:assertTrue>
+ <au:assertTrue>
+ <length length="0">
+ <file file="${output}/redirector.err" />
+ <propertyresource name="redirector.err" />
+ </length>
+ </au:assertTrue>
+ </target>
+
+ <target name="test-redirector-outputproperty-errorproperty-inputstring-inputfilterchain-outputmapper-errormapper"
+ depends="setUp" if="cat.can.run">
+ <exec executable="cat">
+ <redirector outputproperty="redirector.out"
+ errorproperty="redirector.err"
+ inputstring="blah before blah">
+ <inputfilterchain>
+ <replacestring from="before" to="after" />
+ </inputfilterchain>
+ <outputmapper type="merge" to="${output}/redirector.out" />
+ <errormapper type="merge" to="${output}/redirector.err" />
+ </redirector>
+ </exec>
+ <au:assertTrue>
+ <resourcesmatch astext="true">
+ <string value="blah after blah" />
+ <file file="${output}/redirector.out" />
+ <propertyresource name="redirector.out" />
+ </resourcesmatch>
+ </au:assertTrue>
+ <au:assertTrue>
+ <length length="0">
+ <file file="${output}/redirector.err" />
+ <propertyresource name="redirector.err" />
+ </length>
+ </au:assertTrue>
+ </target>
+
+ <target name="test-redirect-output-error-redirector-outputproperty-errorproperty-outputfilterchain-invalid-outputmapper-invalid-errormapper"
+ depends="setUp" if="cat.can.run">
+ <echo file="${input}/redirector.in">blah before blah</echo>
+ <exec executable="cat" output="${output}/redirector.out" error="${output}/redirector.err">
+ <redirector outputproperty="redirector.out"
+ errorproperty="redirector.err">
+ <outputfilterchain>
+ <replacestring from="before" to="after" />
+ </outputfilterchain>
+ <outputmapper type="glob" from="nomatch" to="${output}/nomatchout" />
+ <errormapper type="glob" from="nomatch" to="${output}/nomatcherr" />
+ </redirector>
+ <arg value="${input}/redirector.in" />
+ </exec>
+ <au:assertTrue>
+ <resourcesmatch astext="true">
+ <string value="blah after blah" />
+ <file file="${output}/redirector.out" />
+ <propertyresource name="redirector.out" />
+ </resourcesmatch>
+ </au:assertTrue>
+ <au:assertTrue>
+ <length length="0">
+ <file file="${output}/redirector.err" />
+ <propertyresource name="redirector.err" />
+ </length>
+ </au:assertTrue>
+ <au:assertTrue>
+ <resourcecount count="0">
+ <fileset dir="${output}" includes="nomatch???" />
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="test-redirector-outputfilterchain-errorfilterchain"
+ depends="setUp" if="test.can.run">
+ <exec executable="sh">
+ <redirector>
+ <outputfilterchain>
+ <replacestring from="out" to="OUTPUT???" />
+ </outputfilterchain>
+ <errorfilterchain>
+ <replacestring from="err" to="ERROR!!!" />
+ </errorfilterchain>
+ </redirector>
+ <arg value="parrot.sh" />
+ <arg value="${ant.file}" />
+ </exec>
+ <au:assertLogContains text="${ant.file} OUTPUT???" />
+ <au:assertLogContains text="${ant.file} ERROR!!!" />
+ </target>
+
+ <target name="test-redirector-inputstring-outputfilterchain-outputmapper-errormapper"
+ depends="setUp" if="cat.can.run">
+ <exec executable="cat">
+ <redirector inputstring="blah before blah">
+ <outputfilterchain>
+ <replacestring from="before" to="after" />
+ </outputfilterchain>
+ <outputmapper type="glob" from="nomatch" to="nomatchout" />
+ <errormapper type="glob" from="nomatch" to="nomatcherr" />
+ </redirector>
+ </exec>
+ <au:assertLogContains text="blah after blah" />
+ </target>
+
+ <target name="test-redirector-input-output-inputencoding-outputencoding"
+ depends="setUp" if="cat.can.run">
+ <exec executable="cat">
+ <redirector input="input/iso8859-1" output="${output}/redirector.out"
+ inputencoding="ISO8859_1" outputencoding="UTF8" />
+ </exec>
+ <au:assertTrue>
+ <resourcesmatch astext="true">
+ <file file="${output}/redirector.out" />
+ <file file="expected/utf-8" />
+ </resourcesmatch>
+ </au:assertTrue>
+ </target>
+
+ <target name="test-redirector-inputstring-output-error" depends="setUp" if="test.can.run">
+ <exec executable="sh">
+ <redirector inputstring="exit"
+ output="${output}/redirector.out" error="${output}/redirector.err" />
+ </exec>
+ <au:assertTrue>
+ <and>
+ <available file="${output}/redirector.out" type="file" />
+ <available file="${output}/redirector.err" type="file" />
+ </and>
+ </au:assertTrue>
+ </target>
+
+ <target name="test-redirector-inputstring-nocreateempty-output-error"
+ depends="setUp" if="test.can.run">
+ <exec executable="sh">
+ <redirector inputstring="exit" createemptyfiles="false"
+ output="${output}/redirector.out" error="${output}/redirector.err" />
+ </exec>
+ <au:assertTrue>
+ <not>
+ <or>
+ <available file="${output}/redirector.out" type="file" />
+ <available file="${output}/redirector.err" type="file" />
+ </or>
+ </not>
+ </au:assertTrue>
+ </target>
+
+ <target name="test-redirector-alwayslog-outputproperty" depends="setUp" if="test.can.run">
+ <exec executable="sh">
+ <arg value="parrot.sh" />
+ <arg value="${ant.file}" />
+ <redirector alwayslog="true" logerror="true"
+ outputproperty="redirector.out" />
+ </exec>
+ <au:assertTrue>
+ <equals arg1="${ant.file} out" arg2="${redirector.out}" />
+ </au:assertTrue>
+ <au:assertLogContains text="${ant.file} out" />
+ </target>
+
+ <!-- test will succeed as the OS wont match-->
+ <target name="testExecUnknownOS">
+ <exec executable="nonexistent-program-we-expect"
+ failonerror="true"
+ os="ZX81">
+ </exec>
+ </target>
+
+ <target name="testExecOSFamily">
+ <exec executable="uptime"
+ failonerror="true"
+ osFamily="unix">
+ </exec>
+ <exec executable="cmd.exe"
+ failonerror="true"
+ osFamily="winnt">
+ <arg value="/c" />
+ <arg value="time /t" />
+ </exec>
+ </target>
+
+ <target name="testExecInconsistentSettings">
+ <exec executable="nonexistent-program-we-expect"
+ failonerror="true"
+ osFamily="WIN9X"
+ os="linux unix">
+ </exec>
+ </target>
+
+ <target name="testDoesntWaitForChildren"
+ description="https://issues.apache.org/bugzilla/show_bug.cgi?id=5003">
+ <condition property="java"
+ value="${java.home}/bin/java.exe"
+ else="${java.home}/bin/java">
+ <os family="dos"/>
+ </condition>
+ <mkdir dir="${input}/org/example"/>
+ <pathconvert dirsep="/" property="out">
+ <path location="${output}"/>
+ </pathconvert>
+ <pathconvert dirsep="/" property="javaP">
+ <path location="${java}"/>
+ </pathconvert>
+ <echo file="${input}/org/example/CallHello.java"><![CDATA[
+package org.example;
+public class CallHello {
+ public static void main(String[] args)
+ throws Exception {
+ String[] cmd = new String[] {
+ "${javaP}", "-cp", "${out}", "org.example.Hello"
+ };
+ Runtime.getRuntime().exec(cmd);
+ Thread.sleep(1 * 1000);
+ System.out.println("finished");
+ }
+}]]></echo>
+ <echo file="${input}/org/example/Hello.java"><![CDATA[
+package org.example;
+public class Hello {
+ public static void main(String[] args)
+ throws Exception {
+ for (int i = 0; i < 20; ++i) {
+ System.out.println("Hello " + i);
+ System.out.flush();
+ Thread.sleep(1 * 1000);
+ }
+ }
+}]]></echo>
+ <mkdir dir="${output}"/>
+ <javac srcdir="${input}" destdir="${output}"/>
+ <exec executable="${java}" failonerror="true">
+ <arg value="-cp"/>
+ <arg value="${output}"/>
+ <arg value="org.example.CallHello"/>
+ </exec>
+ <au:assertLogContains text="finished"/>
+ <au:assertLogDoesntContain text="Hello 20"/>
+ </target>
+
+ <target name="test-output-is-split-into-lines" if="cat.can.run" depends="setUp">
+ <echo file="${input}/redirector.in">1&#xa;2&#xd;&#xa;3</echo>
+ <echo file="${output}/expected">1${line.separator}2${line.separator}3</echo>
+ <exec executable="cat">
+ <redirector output="${output}/redirector.out"
+ input="${input}/redirector.in"/>
+ </exec>
+ <au:assertTrue>
+ <resourcesmatch astext="true">
+ <file file="${output}/redirector.out" />
+ <file file="${output}/expected" />
+ </resourcesmatch>
+ </au:assertTrue>
+ </target>
+
+ <target name="test-binary-output-is-not-split-into-lines" if="cat.can.run" depends="setUp">
+ <echo file="${input}/redirector.in">1&#xa;2&#xd;&#xa;3</echo>
+ <exec executable="cat">
+ <redirector output="${output}/redirector.out" binaryOutput="true"
+ input="${input}/redirector.in"/>
+ </exec>
+ <au:assertTrue>
+ <resourcesmatch astext="true">
+ <file file="${output}/redirector.out" />
+ <file file="${input}/redirector.in" />
+ </resourcesmatch>
+ </au:assertTrue>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/exec/expected/utf-8 b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/exec/expected/utf-8
new file mode 100644
index 00000000..c1949bc1
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/exec/expected/utf-8
@@ -0,0 +1 @@
+äöüÄÖÜß
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/exec/input/iso8859-1 b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/exec/input/iso8859-1
new file mode 100644
index 00000000..09044014
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/exec/input/iso8859-1
@@ -0,0 +1 @@
+äöüÄÖÜß
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/exec/parrot.sh b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/exec/parrot.sh
new file mode 100644
index 00000000..2467f23a
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/exec/parrot.sh
@@ -0,0 +1,19 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+for arg in "$@" ; do
+ echo $arg out
+ sleep 1
+ echo $arg err>&2
+done
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/fail-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/fail-test.xml
new file mode 100644
index 00000000..d525b731
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/fail-test.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<project name="echo-test" default="antunit"
+ xmlns:au="antlib:org.apache.ant.antunit">
+ <import file="../antunit-base.xml" />
+
+ <target name="testIfNotSet">
+ <au:expectfailure>
+ <fail unless="${if}"/>
+ </au:expectfailure>
+ <fail if="${if}"/>
+ </target>
+
+ <target name="testIfSet">
+ <property name="if" value="whatever"/>
+ <au:expectfailure>
+ <fail unless="${if}"/>
+ </au:expectfailure>
+ <fail if="${if}"/>
+
+ <fail unless="if"/>
+ <au:expectfailure>
+ <fail if="if"/>
+ </au:expectfailure>
+ </target>
+
+ <target name="testIfTrue">
+ <property name="if" value="true"/>
+ <fail unless="${if}"/>
+ <au:expectfailure>
+ <fail if="${if}"/>
+ </au:expectfailure>
+ </target>
+
+ <target name="testIfFalse">
+ <property name="if" value="false"/>
+ <au:expectfailure>
+ <fail unless="${if}"/>
+ </au:expectfailure>
+ <fail if="${if}"/>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/get-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/get-test.xml
new file mode 100644
index 00000000..0bca337c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/get-test.xml
@@ -0,0 +1,125 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<project name="get-test" default="antunit" xmlns:au="antlib:org.apache.ant.antunit">
+ <import file="../antunit-base.xml" />
+
+ <property name="location" value="http://ant.apache.org/webtest/gettest" />
+
+ <target name="setUp">
+ <mkdir dir="${output}" />
+ </target>
+
+ <target name="testSeeOtherRedirect">
+ <get src="${location}/other.txt" dest="${output}/other.tmp"/>
+ <au:assertTrue>
+ <resourcecount count="1">
+ <restrict>
+ <file file="${output}/other.tmp" />
+ <contains text="seeother redirect succeeded" />
+ </restrict>
+ </resourcecount>
+ </au:assertTrue>
+ <au:assertLogContains text="other.txt moved to http" />
+ </target>
+
+ <target name="testPermanentRedirect">
+ <get src="${location}/permanent.txt" dest="${output}/permanent.tmp"/>
+ <au:assertTrue>
+ <resourcecount count="1">
+ <restrict>
+ <file file="${output}/permanent.tmp" />
+ <contains text="permanent redirect succeeded" />
+ </restrict>
+ </resourcecount>
+ </au:assertTrue>
+ <au:assertLogContains text="permanent.txt permanently moved to http" />
+ </target>
+
+ <target name="testTemporaryRedirect">
+ <get src="${location}/temp.txt" dest="${output}/temp.txt"/>
+ <au:assertTrue>
+ <resourcecount count="1">
+ <restrict>
+ <file file="${output}/temp.txt" />
+ <contains text="temporary redirect succeeded" />
+ </restrict>
+ </resourcecount>
+ </au:assertTrue>
+ <au:assertLogContains text="temp.txt moved to http" />
+ </target>
+
+ <target name="testStatusCode307Redirect">
+ <get src="${location}/307.txt" dest="${output}/307.txt"/>
+ <au:assertTrue>
+ <resourcecount count="1">
+ <restrict>
+ <file file="${output}/307.txt" />
+ <contains text="307 status code redirect succeeded" />
+ </restrict>
+ </resourcecount>
+ </au:assertTrue>
+ <au:assertLogContains text="307.txt moved to http" />
+ </target>
+
+ <target name="test5LevelsOfRedirect">
+ <get src="${location}/redir5.txt" dest="${output}/redir5.tmp"/>
+ <au:assertTrue>
+ <resourcecount count="1">
+ <restrict>
+ <file file="${output}/redir5.tmp" />
+ <contains text="5 levels of redirect succeeded" />
+ </restrict>
+ </resourcecount>
+ </au:assertTrue>
+
+ <au:assertLogContains text="redir5.txt moved to http" />
+
+ <au:assertLogContains text="redir5-4.txt moved to http" />
+ </target>
+
+
+ <target name="testInfiniteRedirect">
+ <au:expectfailure expectedmessage="More than 25 times redirected, giving up">
+ <get src="${location}/infinite.txt" dest="${output}/infinite.tmp"/>
+ </au:expectfailure>
+ </target>
+
+
+ <target name="testNestedResources">
+ <get dest="${output}/downloads">
+ <url url="http://ant.apache.org/index.html"/>
+ <url url="http://ant.apache.org/faq.html"/>
+ </get>
+ <au:assertFileExists file="${output}/downloads/index.html"/>
+ <au:assertFileExists file="${output}/downloads/faq.html"/>
+ </target>
+
+ <target name="XtestRelativeRedirect">
+ <get src="${location}/local.cgi" dest="${output}/other.tmp"/>
+ <au:assertTrue>
+ <resourcecount count="1">
+ <restrict>
+ <file file="${output}/other.tmp" />
+ <contains text="local redirect succeeded"/>
+ </restrict>
+ </resourcecount>
+ </au:assertTrue>
+ <au:assertLogContains text="local.cgi moved to http" />
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/gzip-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/gzip-test.xml
new file mode 100644
index 00000000..38f0a7a6
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/gzip-test.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="antunit" xmlns:au="antlib:org.apache.ant.antunit">
+
+ <!-- note relies on antunit 1.1 -->
+ <import file="../antunit-base.xml" />
+
+ <target name="setUp">
+ <mkdir dir="${output}" />
+ <mkdir dir="${output}/empty" />
+ <touch file="${output}/fileone" />
+ <touch file="${output}/filetwo" />
+ </target>
+
+ <target name="testFailNone">
+ <au:expectfailure expectedmessage="No resource selected, gzip needs exactly one resource." message="Should have thrown an exception">
+ <gzip destfile="${output}/file.gz">
+ <fileset dir="${output}/empty" />
+ </gzip>
+ </au:expectfailure>
+ </target>
+
+ <target name="testFailTwo">
+ <au:expectfailure expectedmessage="gzip cannot handle multiple resources at once. (2 resources were selected.)" message="Should have thrown an exception">
+ <gzip destfile="${output}/file.gz">
+ <fileset dir="${output}" />
+ </gzip>
+ </au:expectfailure>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/hostinfo-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/hostinfo-test.xml
new file mode 100644
index 00000000..a044b9b1
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/hostinfo-test.xml
@@ -0,0 +1,64 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="hostinfo-test" default="antunit"
+ xmlns:au="antlib:org.apache.ant.antunit">
+
+ <import file="../antunit-base.xml" />
+
+ <property name="undef-name" value="nonexistenthost.nonexistentdomain" />
+ <property name="undef-hostname" value="nonexistenthost" />
+ <property name="undef-domainname" value="nonexistentdomain" />
+
+ <property name="undef-ip4" value="0.0.0.0" />
+ <property name="undef-ip6" value="::" />
+
+ <property name="xs4all-hostname" value="www.xs4all.nl" />
+ <property name="xs4all-domain" value="xs4all.nl" />
+ <property name="xs4all-realhost" value="www" />
+ <property name="xs4all-ip4" value="194.109.6.92" />
+
+ <target name="setUp">
+ </target>
+
+ <target name="testLocal" depends="setUp">
+ <hostinfo prefix="local" />
+ <!-- Do not know what to expect here, machine dependent -->
+ </target>
+
+ <target name="testForward" depends="setUp">
+ <hostinfo host="${xs4all-hostname}"/>
+ <au:assertEquals expected="${xs4all-realhost}" actual="${NAME}"/>
+ <au:assertEquals expected="${xs4all-domain}" actual="${DOMAIN}"/>
+ <au:assertEquals expected="${xs4all-ip4}" actual="${ADDR4}"/>
+ </target>
+
+ <target name="testReverse" depends="setUp">
+ <hostinfo prefix="reverse" host="${xs4all-ip4}"/>
+ <au:assertEquals expected="${xs4all-realhost}" actual="${reverse.NAME}"/>
+ <au:assertEquals expected="${xs4all-domain}" actual="${reverse.DOMAIN}"/>
+ <au:assertEquals expected="${xs4all-ip4}" actual="${reverse.ADDR4}"/>
+ </target>
+
+ <target name="testUndef" depends="setUp">
+ <hostinfo prefix="undef" host="${undef-name}"/>
+ <au:assertEquals expected="${undef-hostname}" actual="${undef.NAME}"/>
+ <au:assertEquals expected="${undef-domainname}" actual="${undef.DOMAIN}"/>
+ <au:assertEquals expected="${undef-ip4}" actual="${undef.ADDR4}"/>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/import-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/import-test.xml
new file mode 100644
index 00000000..f9e4b055
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/import-test.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="antunit" xmlns:au="antlib:org.apache.ant.antunit">
+ <import file="../antunit-base.xml" />
+
+ <import>
+ <file file="importtests/a.xml"/>
+ </import>
+ <import file="importtests/b.xml" as="c"/>
+
+ <target name="testNoExplicitPrefix" depends="a.a">
+ <au:assertEquals expected="bar" actual="${foo}"/>
+ </target>
+
+ <target name="testExplicitPrefix" depends="c.b">
+ <au:assertEquals expected="baz" actual="${foo}"/>
+ </target>
+
+ <target name="testNoExplicitPrefixUsedWithoutPrefix" depends="a">
+ <au:assertEquals expected="bar" actual="${foo}"/>
+ </target>
+
+ <target name="testExplicitPrefixUsedWithoutPrefix" depends="b">
+ <au:assertEquals expected="baz" actual="${foo}"/>
+ </target>
+
+ <import>
+ <javaresource name="override.xml">
+ <classpath location="importtests"/>
+ </javaresource>
+ </import>
+
+ <target name="setProperty">
+ <property name="prop" value="in including/importing"/>
+ </target>
+
+ <target name="testOverride" depends="override.dummy">
+ <au:assertEquals expected="in including/importing" actual="${prop}"/>
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/import-url-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/import-url-test.xml
new file mode 100644
index 00000000..103ece3e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/import-url-test.xml
@@ -0,0 +1,101 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="antunit" xmlns:au="antlib:org.apache.ant.antunit">
+ <import file="../antunit-base.xml" />
+
+ <mkdir dir="${output}"/>
+ <mkdir dir="${input}/a/b"/>
+ <mkdir dir="${input}/a/c"/>
+ <echo file="${input}/a/b/outer.xml"><![CDATA[
+<project name="outer">
+ <import file="../c/inner.xml"/>
+</project>
+]]></echo>
+ <echo file="${input}/a/c/inner.xml"><![CDATA[
+<project name="inner">
+ <target name="foo">
+ <echo>In inner</echo>
+ <echo>ant.file.inner is ${ant.file.inner}</echo>
+ <echo>type is ${ant.file.type.inner}</echo>
+ <loadproperties>
+ <url baseUrl="${ant.file.inner}" relativePath="test.properties"/>
+ </loadproperties>
+ <echo>foo is ${foo}</echo>
+ </target>
+</project>]]></echo>
+ <echo file="${input}/a/c/test.properties"><![CDATA[
+foo=bar
+]]></echo>
+ <echo file="${input}/a/b/external-import.xml"><![CDATA[
+<project name="external-import">
+ <import file="${output}/imported.xml"/>
+</project>
+]]></echo>
+ <echo file="${output}/imported.xml"><![CDATA[
+<project name="imported">
+ <target name="bar">
+ <echo>In imported</echo>
+ </target>
+</project>
+]]></echo>
+ <jar destfile="${test.jar}">
+ <fileset dir="${input}"/>
+ </jar>
+ <delete dir="${input}"/>
+
+ <import>
+ <javaresource name="a/b/outer.xml">
+ <classpath location="${test.jar}"/>
+ </javaresource>
+ </import>
+ <import>
+ <javaresource name="a/b/outer.xml">
+ <classpath location="${test.jar}"/>
+ </javaresource>
+ </import>
+ <import>
+ <javaresource name="a/b/external-import.xml">
+ <classpath location="${test.jar}"/>
+ </javaresource>
+ </import>
+
+ <target name="testImportOfNestedFile" depends="foo">
+ <au:assertLogContains text="In inner"/>
+ <au:assertLogContains text="type is url"/>
+ <au:assertLogContains text="foo is bar"/>
+ </target>
+
+ <target name="testImportOfNestedFileWithAbsolutePath" depends="bar"
+ description="https://issues.apache.org/bugzilla/show_bug.cgi?id=50953">
+ <au:assertLogContains text="In imported"/>
+ </target>
+
+ <target name="tearDown">
+ <taskdef name="close"
+ classname="org.apache.tools.ant.taskdefs.CloseResources"/>
+ <close>
+ <javaresource name="a/b/outer.xml">
+ <classpath location="${test.jar}"/>
+ </javaresource>
+ </close>
+ <delete file="${test.jar}" quiet="true" deleteonexit="true"/>
+ <!-- Calling antunit-base.tearDown sometimes causes ISEs in <import> in Ant-Build-Matrix: -->
+ <delete dir="${input}"/>
+ <delete dir="${output}"/>
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/importtests/a.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/importtests/a.xml
new file mode 100644
index 00000000..6082990f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/importtests/a.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="a">
+ <target name="a">
+ <property name="foo" value="bar"/>
+ </target>
+</project>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/importtests/b.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/importtests/b.xml
new file mode 100644
index 00000000..546badf5
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/importtests/b.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="b">
+ <target name="b">
+ <property name="foo" value="baz"/>
+ </target>
+</project>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/importtests/nested.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/importtests/nested.xml
new file mode 100644
index 00000000..28d7ad4b
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/importtests/nested.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project>
+ <include file="b.xml" as="b" prefixSeparator="::"/>
+ <include file="a.xml" as="a" prefixSeparator=""/>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/importtests/override.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/importtests/override.xml
new file mode 100644
index 00000000..97fd320b
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/importtests/override.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="override">
+ <target name="setProperty">
+ <property name="prop" value="in included/imported"/>
+ </target>
+
+ <target name="dummy" depends="setProperty"/>
+</project>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/importtests/w.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/importtests/w.xml
new file mode 100644
index 00000000..e400c501
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/importtests/w.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="w">
+ <echo>${ant.file.w}</echo>
+ <include file="x.xml"/>
+ <target name="ww" depends="x.xx, x.y.yy, x.y.z.zz"/>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/importtests/x.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/importtests/x.xml
new file mode 100644
index 00000000..a509e574
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/importtests/x.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="x">
+ <echo>${ant.file.x}</echo>
+ <include file="y.xml"/>
+ <target name="xx" depends="y.yy, y.z.zz"/>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/importtests/y.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/importtests/y.xml
new file mode 100644
index 00000000..0e54fa83
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/importtests/y.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="y">
+ <echo>${ant.file.y}</echo>
+ <include file="z.xml" as="z"/>
+ <target name="yy" depends="z.zz"/>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/importtests/z.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/importtests/z.xml
new file mode 100644
index 00000000..607dee7e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/importtests/z.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="z">
+ <echo>${ant.file.z}</echo>
+ <target name="zz"/>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/include-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/include-test.xml
new file mode 100644
index 00000000..7e1a4523
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/include-test.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="antunit" xmlns:au="antlib:org.apache.ant.antunit">
+ <import file="../antunit-base.xml" />
+
+ <include>
+ <file file="importtests/a.xml"/>
+</include>
+ <include file="importtests/b.xml" as="c"/>
+
+ <target name="testNoExplicitPrefix" depends="a.a">
+ <au:assertEquals expected="bar" actual="${foo}"/>
+ </target>
+
+ <target name="testExplicitPrefix" depends="c.b">
+ <au:assertEquals expected="baz" actual="${foo}"/>
+ </target>
+
+ <include file="importtests/override.xml"/>
+
+ <target name="setProperty">
+ <property name="prop" value="in including/importing"/>
+ </target>
+
+ <target name="testNoOverride" depends="override.dummy">
+ <au:assertEquals expected="in included/imported" actual="${prop}"/>
+ </target>
+
+ <include as="nested">
+ <javaresource name="nested.xml">
+ <classpath location="importtests"/>
+ </javaresource>
+ </include>
+
+ <!-- really only tests that the targets have the expected names by
+ forcing an exception if the dependencies don't exist -->
+ <target name="testNesting" depends="nested.b::b, nested.aa"/>
+ <target name="testNoExplicitPrefixNested">
+ <ant target="x.y.z.zz" antfile="importtests/w.xml"/>
+ </target>
+
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/jar-spi-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/jar-spi-test.xml
new file mode 100644
index 00000000..c05311aa
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/jar-spi-test.xml
@@ -0,0 +1,149 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project xmlns:au="antlib:org.apache.ant.antunit">
+ <property name="jar.dir" location="jar_spi_dir"/>
+ <property name="jar.src.dir" location="jar_spi_dir/src"/>
+ <property name="jar.src.file" location="jar_spi_dir/src/a_file"/>
+
+ <available property="jdk1.4+" classname="java.lang.CharSequence"/>
+ <condition property="some.regexp.support">
+ <or>
+ <isset property="jdk1.4+"/>
+ <isset property="apache.regexp.present"/>
+ <isset property="apache.oro.present"/>
+ </or>
+ </condition>
+
+ <target name="init">
+ <mkdir dir="${jar.src.dir}"/>
+ <delete quiet="yes" file="${jar.src.file}"/>
+ <touch file="${jar.src.file}"/>
+ <delete quiet="yes" file="${jar.dir}/file.jar"/>
+ <delete quiet="yes" dir="${jar.dir}/output"/>
+ </target>
+
+ <target name="test-simple" depends="init" if="some.regexp.support">
+
+ <jar jarfile="${jar.dir}/file.jar">
+ <fileset dir="${jar.src.dir}"/>
+ <service type="a.b.c" provider="a.b.c.d"/>
+ </jar>
+
+ <unjar src="${jar.dir}/file.jar"
+ dest="${jar.dir}/output"/>
+
+ <loadfile property="simple"
+ srcfile="${jar.dir}/output/META-INF/services/a.b.c"
+ encoding="UTF-8"/>
+
+ <au:assertTrue>
+ <matches string="${simple}" pattern="^a\.b\.c\.d$"/>
+ </au:assertTrue>
+
+ </target>
+
+ <target name="test-providers" depends="init" if="some.regexp.support">
+
+ <jar jarfile="${jar.dir}/file.jar">
+ <fileset dir="${jar.src.dir}"/>
+ <service type="a.b.c">
+ <provider classname="a.X"/>
+ <provider classname="a.D"/>
+ </service>
+ </jar>
+
+ <unjar src="${jar.dir}/file.jar"
+ dest="${jar.dir}/output"/>
+
+ <loadfile property="providers"
+ srcfile="${jar.dir}/output/META-INF/services/a.b.c"
+ encoding="UTF-8"/>
+ <au:assertTrue>
+ <matches string="${providers}" pattern="^a\.X\na\.D$"/>
+ </au:assertTrue>
+
+ </target>
+
+ <target name="test-multi" depends="init" if="some.regexp.support">
+
+ <jar jarfile="${jar.dir}/file.jar">
+ <fileset dir="${jar.src.dir}"/>
+ <service type="a.b.c">
+ <provider classname="a.X"/>
+ <provider classname="a.D"/>
+ </service>
+ <service type="javax.a.service">
+ <provider classname="a.O.T"/>
+ <provider classname="a.B"/>
+ </service>
+ </jar>
+
+ <unjar src="${jar.dir}/file.jar"
+ dest="${jar.dir}/output"/>
+
+ <loadfile property="multi-a"
+ srcfile="${jar.dir}/output/META-INF/services/a.b.c"
+ encoding="UTF-8"/>
+
+ <au:assertTrue>
+ <matches string="${multi-a}" pattern="^a\.X\na\.D$"/>
+ </au:assertTrue>
+
+ <loadfile property="multi-b"
+ srcfile="${jar.dir}/output/META-INF/services/javax.a.service"
+ encoding="UTF-8"/>
+
+ <au:assertTrue>
+ <matches string="${multi-b}" pattern="^a\.O\.T\na\.B$"/>
+ </au:assertTrue>
+
+ </target>
+
+ <target name="test-reject-no-type" depends="init">
+ <au:expectfailure>
+ <jar jarfile="${jar.dir}/file.jar">
+ <fileset dir="${jar.src.dir}"/>
+ <service provider="a.X"/>
+ </jar>
+ </au:expectfailure>
+ </target>
+
+ <target name="test-reject-no-provider" depends="init">
+ <au:expectfailure>
+ <jar jarfile="${jar.dir}/file.jar">
+ <fileset dir="${jar.src.dir}"/>
+ <service type="a.X"/>
+ </jar>
+ </au:expectfailure>
+ </target>
+
+ <target name="test-reject-no-classname" depends="init">
+ <au:expectfailure>
+ <jar jarfile="${jar.dir}/file.jar">
+ <fileset dir="${jar.src.dir}"/>
+ <service type="a.X">
+ <provider/>
+ </service>
+ </jar>
+ </au:expectfailure>
+ </target>
+
+ <target name="tearDown">
+ <delete quiet="yes" dir="${jar.dir}"/>
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/jar-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/jar-test.xml
new file mode 100644
index 00000000..c2c8834e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/jar-test.xml
@@ -0,0 +1,252 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="antunit" xmlns:au="antlib:org.apache.ant.antunit">
+ <import file="../antunit-base.xml" />
+
+ <target name="testIndexOnlyUpdate">
+ <mkdir dir="${output}"/>
+ <property name="index.jar" location="${output}/index.jar" />
+
+ <jar destfile="${index.jar}" index="false">
+ <fileset dir="${basedir}" includes="*-test.xml" />
+ </jar>
+ <au:assertTrue>
+ <resourcecount count="0">
+ <restrict>
+ <zipentry zipfile="${index.jar}" name="META-INF/INDEX.LIST" />
+ <exists />
+ </restrict>
+ </resourcecount>
+ </au:assertTrue>
+ <jar destfile="${index.jar}" index="true" update="true">
+ <fileset dir="${basedir}" includes="*-test.xml" />
+ </jar>
+ <au:assertTrue>
+ <resourcecount count="1">
+ <restrict>
+ <zipentry zipfile="${index.jar}" name="META-INF/INDEX.LIST" />
+ <exists />
+ </restrict>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testResourcesOnly"
+ description="https://issues.apache.org/bugzilla/show_bug.cgi?id=47470">
+ <mkdir dir="${input}"/>
+ <mkdir dir="${output}"/>
+ <touch file="${input}/foo"/>
+ <touch file="${output}/bar"/>
+ <jar destfile="${output}/foo.jar">
+ <union>
+ <fileset dir="${input}"/>
+ <fileset dir="${output}" excludes="foo.jar"/>
+ </union>
+ </jar>
+ <au:assertLogDoesntContain text="skipping jar archive"/>
+ </target>
+
+ <target name="-metainf-setup">
+ <mkdir dir="${input}/services"/>
+ <touch file="${input}/services/foo"/>
+ <mkdir dir="${output}"/>
+ </target>
+
+ <target name="testIndexNoMetaInf" depends="-metainf-setup">
+ <jar index="true" destfile="${output}/test.jar">
+ <metainf dir="${input}"/>
+ </jar>
+ <unjar src="${output}/test.jar" dest="${output}"/>
+ <au:assertFileExists file="${output}/META-INF/INDEX.LIST"/>
+ <au:assertResourceDoesntContain value="META-INF"
+ resource="${output}/META-INF/INDEX.LIST"/>
+ </target>
+
+ <target name="testIndexMetaInf" depends="-metainf-setup">
+ <jar index="true" destfile="${output}/test.jar" indexMetaInf="true">
+ <metainf dir="${input}"/>
+ </jar>
+ <unjar src="${output}/test.jar" dest="${output}"/>
+ <au:assertFileExists file="${output}/META-INF/INDEX.LIST"/>
+ <au:assertResourceContains value="META-INF"
+ resource="${output}/META-INF/INDEX.LIST"/>
+ </target>
+
+ <target name="testMergeWithoutMain"
+ description="https://issues.apache.org/bugzilla/show_bug.cgi?id=29731">
+ <mkdir dir="${input}"/>
+ <mkdir dir="${output}"/>
+ <jar destfile="${input}/first.jar">
+ <manifest>
+ <attribute name="First" value="Main Section"/>
+ <section name="Nested">
+ <attribute name="First" value="Nested Section"/>
+ </section>
+ </manifest>
+ </jar>
+ <jar destfile="${output}/second.jar" filesetmanifest="mergewithoutmain">
+ <manifest>
+ <attribute name="Second" value="Main Section"/>
+ <section name="Nested">
+ <attribute name="Second" value="Nested Section"/>
+ </section>
+ </manifest>
+ <zipgroupfileset dir="${input}" includes="first.jar"/>
+ </jar>
+ <unjar src="${output}/second.jar" dest="${output}"/>
+ <au:assertFileExists file="${output}/META-INF/MANIFEST.MF"/>
+ <au:assertResourceContains value="First: Nested Section"
+ resource="${output}/META-INF/MANIFEST.MF"/>
+ <au:assertResourceContains value="Second: Nested Section"
+ resource="${output}/META-INF/MANIFEST.MF"/>
+ <au:assertResourceDoesntContain
+ value="First: Main Section"
+ resource="${output}/META-INF/MANIFEST.MF"/>
+ <au:assertResourceContains value="Second: Main Section"
+ resource="${output}/META-INF/MANIFEST.MF"/>
+ </target>
+
+ <target name="testWhenManifestOnly"
+ description="https://issues.apache.org/bugzilla/show_bug.cgi?id=43946">
+ <mkdir dir="${input}"/>
+ <mkdir dir="${output}"/>
+ <jar destfile="${output}/first.jar">
+ <fileset dir="${input}"/>
+ </jar>
+ <au:assertFileExists file="${output}/first.jar"/>
+ <au:assertLogDoesntContain text="skipping jar archive"/>
+ <jar destfile="${output}/second.jar" whenmanifestonly="create">
+ <fileset dir="${input}"/>
+ </jar>
+ <au:assertFileExists file="${output}/second.jar"/>
+ <au:assertLogDoesntContain text="skipping jar archive"/>
+ <jar destfile="${output}/third.jar" whenmanifestonly="skip">
+ <fileset dir="${input}"/>
+ </jar>
+ <au:assertFileDoesntExist file="${output}/third.jar"/>
+ <au:assertLogContains text="skipping jar archive"/>
+ <au:expectfailure>
+ <jar destfile="${output}/forth.jar" whenmanifestonly="fail">
+ <fileset dir="${input}"/>
+ </jar>
+ </au:expectfailure>
+ </target>
+
+ <target name="test-update-and-filesetmanifest"
+ description="https://issues.apache.org/bugzilla/show_bug.cgi?id=30751">
+ <mkdir dir="${input}"/>
+ <mkdir dir="${output}"/>
+ <jar destfile="${input}/manifest.jar">
+ <manifest>
+ <attribute name="Origin" value="manifest.jar"/>
+ </manifest>
+ </jar>
+
+ <touch file="${input}/foo"/>
+ <jar destfile="${output}/test.jar">
+ <fileset dir="${input}" excludes="*.jar"/>
+ <manifest>
+ <attribute name="Second-Origin" value="test.jar"/>
+ </manifest>
+ </jar>
+
+ <touch file="${input}/bar"/>
+ <jar destfile="${output}/test.jar" update="true" filesetmanifest="merge">
+ <fileset dir="${input}" excludes="*.jar"/>
+ <zipgroupfileset dir="${input}" includes="*.jar"/>
+ </jar>
+
+ <unjar src="${output}/test.jar" dest="${output}"/>
+ <au:assertFileExists file="${output}/foo"/>
+ <au:assertFileExists file="${output}/bar"/>
+ <au:assertResourceContains value="Origin: manifest.jar"
+ resource="${output}/META-INF/MANIFEST.MF"/>
+ <au:assertResourceContains value="Second-Origin: test.jar"
+ resource="${output}/META-INF/MANIFEST.MF"/>
+ </target>
+
+ <target name="testDuplicateFail">
+ <mkdir dir="${input}/1"/>
+ <mkdir dir="${input}/2"/>
+ <mkdir dir="${output}"/>
+ <touch file="${input}/1/a.txt"/>
+ <touch file="${input}/2/a.txt"/>
+ <au:expectfailure message="Duplicate file">
+ <jar destfile="${output}/test.jar" duplicate="fail">
+ <fileset dir="${input}/1"/>
+ <fileset dir="${input}/2"/>
+ </jar>
+ </au:expectfailure>
+ </target>
+
+ <target name="testFileSetMerge"
+ description="https://issues.apache.org/bugzilla/show_bug.cgi?id=49090">
+ <mkdir dir="${input}/META-INF"/>
+ <mkdir dir="${output}"/>
+ <echo file="${input}/META-INF/MANIFEST.MF"><![CDATA[Test: Header
+]]></echo>
+ <jar destfile="${output}/test.jar" filesetmanifest="merge">
+ <fileset dir="${input}"/>
+ </jar>
+ <unjar src="${output}/test.jar" dest="${output}"/>
+ <au:assertResourceContains value="Test: Header"
+ resource="${output}/META-INF/MANIFEST.MF"/>
+ </target>
+
+ <target name="testZipfilesetMerge"
+ description="https://issues.apache.org/bugzilla/show_bug.cgi?id=49605">
+ <mkdir dir="${input}"/>
+ <mkdir dir="${output}"/>
+ <echo file="${input}/MANIFEST.MF">Manifest-Version: 1.0
+Main-Class: MyClass
+
+</echo>
+ <jar destfile="${input}/manifesttest.jar"
+ filesetmanifest="merge">
+ <zipfileset file="${input}/MANIFEST.MF" prefix="META-INF"/>
+ </jar>
+ <unjar src="${input}/manifesttest.jar" dest="${output}"/>
+ <au:assertFileExists file="${output}/META-INF/MANIFEST.MF"/>
+ <au:assertResourceContains value="Main-Class: MyClass"
+ resource="${output}/META-INF/MANIFEST.MF"/>
+ </target>
+
+ <target name="testMergeWithoutMainWithoutExplicitManifest"
+ description="https://issues.apache.org/bugzilla/show_bug.cgi?id=54171">
+ <mkdir dir="${input}"/>
+ <mkdir dir="${output}"/>
+ <jar destfile="${input}/input.jar">
+ <manifest>
+ <attribute name="Foo" value="Main Section"/>
+ </manifest>
+ <fileset dir="."/>
+ </jar>
+ <jar destfile="${input}/test.jar"
+ filesetmanifest="mergewithoutmain">
+ <zipgroupfileset dir="${input}">
+ <include name="input.jar"/>
+ </zipgroupfileset>
+ </jar>
+ <unjar src="${input}/test.jar" dest="${output}"/>
+ <au:assertFileExists file="${output}/META-INF/MANIFEST.MF"/>
+ <au:assertResourceDoesntContain
+ value="Foo: Main Section"
+ resource="${output}/META-INF/MANIFEST.MF"/>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/java-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/java-test.xml
new file mode 100644
index 00000000..db673161
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/java-test.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="antunit" xmlns:au="antlib:org.apache.ant.antunit">
+ <import file="../antunit-base.xml" />
+
+ <target name="-setUpWriterClass">
+ <mkdir dir="${input}"/>
+ <echo file="${input}/A.java"><![CDATA[
+public class A {
+ public static void main(String[] args) {
+ System.err.println("to System.err");
+ System.out.println("to System.out");
+ }
+}]]></echo>
+ <mkdir dir="${output}"/>
+ <javac srcdir="${input}" destdir="${output}"/>
+ </target>
+
+ <target name="testOutputProperty"
+ description="https://issues.apache.org/bugzilla/show_bug.cgi?id=47602"
+ depends="-setUpWriterClass">
+ <java fork="false" classname="A" outputproperty="out"
+ errorproperty="err">
+ <classpath location="${output}"/>
+ </java>
+ <au:assertPropertyEquals name="out" value="to System.out"/>
+ <au:assertPropertyEquals name="err" value="to System.err"/>
+ </target>
+
+ <target name="testLogErrorNoInput"
+ description="https://issues.apache.org/bugzilla/show_bug.cgi?id=47844"
+ depends="-setUpWriterClass">
+ <property name="stdout" location="${output}/standard.txt"/>
+ <java fork="false" classname="A" output="${stdout}" logError="true">
+ <classpath location="${output}"/>
+ </java>
+ <au:assertResourceContains resource="${stdout}"
+ value="to System.out"/>
+ <au:assertResourceDoesntContain resource="${stdout}"
+ value="to System.err"/>
+ <au:assertLogContains text="to System.err"/>
+ </target>
+
+ <target name="testLogErrorWithInput"
+ description="https://issues.apache.org/bugzilla/show_bug.cgi?id=47844"
+ depends="-setUpWriterClass">
+ <property name="stdout" location="${output}/standard.txt"/>
+ <java fork="false" classname="A" output="${stdout}"
+ logError="true" inputstring="">
+ <classpath location="${output}"/>
+ </java>
+ <au:assertResourceContains resource="${stdout}"
+ value="to System.out"/>
+ <au:assertResourceDoesntContain resource="${stdout}"
+ value="to System.err"/>
+ <au:assertLogContains text="to System.err"/>
+ </target>
+
+</project>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/javac-dir/bad-src/Bad.java b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/javac-dir/bad-src/Bad.java
new file mode 100644
index 00000000..3b749f88
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/javac-dir/bad-src/Bad.java
@@ -0,0 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+/** a simple class with a bug */
+public class Simple {
+ // should get a not-terminated error
+ String s = ";
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/javac-dir/good-src/Simple.java b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/javac-dir/good-src/Simple.java
new file mode 100644
index 00000000..9c08f568
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/javac-dir/good-src/Simple.java
@@ -0,0 +1,20 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+/** a simple do nothing class */
+public class Simple {
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/javac-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/javac-test.xml
new file mode 100644
index 00000000..3c4d8489
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/javac-test.xml
@@ -0,0 +1,316 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="antunit" xmlns:au="antlib:org.apache.ant.antunit">
+ <import file="../antunit-base.xml" />
+
+ <property name="javac-dir" location="${output}/javac-dir" />
+ <property name="build-dir" location="${javac-dir}/build" />
+
+ <target name="test-includeDestClasses">
+ <property name="DATE" value="09/10/1999 4:30 pm" />
+ <delete dir="${javac-dir}/src" />
+ <mkdir dir="${javac-dir}/src" />
+ <echo file="${javac-dir}/src/A.java">
+ public class A { B b;}
+ </echo>
+ <echo file="${javac-dir}/src/B.java">
+ public class B { }
+ </echo>
+ <delete dir="${javac-dir}/classes" quiet="yes" />
+ <mkdir dir="${javac-dir}/classes" />
+ <javac srcdir="${javac-dir}/src" destdir="${javac-dir}/classes" />
+ <touch file="${javac-dir}/src/B.java" datetime="${DATE}" />
+ <touch file="${javac-dir}/classes/B.class" datetime="${DATE}" />
+ <!-- following should not update B.class -->
+ <delete quiet="yes" file="${javac-dir}/classes/A.class" />
+ <javac srcdir="${javac-dir}/src" destdir="${javac-dir}/classes" />
+ <au:assertTrue>
+ <isfileselected file="${javac-dir}/classes/B.class">
+ <date datetime="${DATE}" when="equal" />
+ </isfileselected>
+ </au:assertTrue>
+ <!-- following should update B.class -->
+ <delete quiet="yes" file="${javac-dir}/classes/A.class" />
+ <javac srcdir="${javac-dir}/src" destdir="${javac-dir}/classes" includeDestClasses="no" />
+ <au:assertFalse>
+ <isfileselected file="${javac-dir}/classes/B.class">
+ <date datetime="${DATE}" when="equal" />
+ </isfileselected>
+ </au:assertFalse>
+ </target>
+
+ <target name="test-updated-property">
+ <delete quiet="yes" dir="${build-dir}" />
+ <mkdir dir="${build-dir}" />
+ <javac srcdir="javac-dir/good-src" destdir="${build-dir}" updatedProperty="classes-updated" />
+ <au:assertTrue>
+ <equals arg1="${classes-updated}" arg2="true" />
+ </au:assertTrue>
+ <javac srcdir="javac-dir/good-src" destdir="${build-dir}" updatedProperty="classes-updated-2" />
+ <au:assertFalse>
+ <isset property="classes-updated-2" />
+ </au:assertFalse>
+ </target>
+
+ <target name="test-error-property">
+ <delete quiet="yes" dir="${build-dir}" />
+ <mkdir dir="${build-dir}" />
+ <javac srcdir="javac-dir/good-src" destdir="${build-dir}" failOnError="false" errorProperty="compile-failed" />
+ <au:assertTrue>
+ <equals arg1="${compile-failed}" arg2="${compile-failed}" />
+ </au:assertTrue>
+ <javac srcdir="javac-dir/bad-src" destdir="${build-dir}" failOnError="false" errorProperty="compile-failed" />
+ <au:assertTrue>
+ <equals arg1="${compile-failed}" arg2="true" />
+ </au:assertTrue>
+ </target>
+
+ <target name="setUpForPackageInfoJava">
+ <mkdir dir="${javac-dir}/src/a" />
+ <mkdir dir="${build-dir}" />
+ <echo file="${javac-dir}/src/a/package-info.java">
+ <![CDATA[
+/**
+ * Some test javadocs at the package level.
+ */
+]]>
+ </echo>
+ <javac srcdir="${javac-dir}/src" destdir="${build-dir}" updatedProperty="first-pass" />
+ <au:assertPropertyEquals name="first-pass" value="true" />
+ </target>
+
+ <target name="testPackageInfoJava"
+ depends="setUpForPackageInfoJava"
+ description="https://issues.apache.org/bugzilla/show_bug.cgi?id=43114">
+ <!-- no changes, shouldn't recompile, the initial bug -->
+ <javac srcdir="${javac-dir}/src" destdir="${build-dir}" updatedProperty="second-pass" />
+ <au:assertFalse>
+ <isset property="second-pass" />
+ </au:assertFalse>
+ <sleep seconds="2" />
+
+ <!-- change package-info.java but make containing target dir even
+ more recent - the regression in Ant 1.7.1 -->
+ <touch file="${javac-dir}/src/a/package-info.java" />
+ <sleep seconds="2" />
+ <touch>
+ <file file="${build-dir}/a" />
+ </touch>
+ <javac srcdir="${javac-dir}/src" destdir="${build-dir}" updatedProperty="third-pass" />
+ <au:assertPropertyEquals name="third-pass" value="true" />
+ </target>
+
+ <target name="testPackageInfoJavaNoDest"
+ depends="setUpForPackageInfoJava"
+ description="https://issues.apache.org/bugzilla/show_bug.cgi?id=51947">
+ <javac srcdir="${javac-dir}/src" updatedProperty="first-pass" />
+ <au:assertPropertyEquals name="first-pass" value="true" />
+
+ <!-- no changes, shouldn't recompile, the initial bug -->
+ <javac srcdir="${javac-dir}/src" updatedProperty="second-pass" />
+ <au:assertFalse>
+ <isset property="second-pass" />
+ </au:assertFalse>
+ <sleep seconds="2" />
+
+ <!-- change package-info.java but make containing target dir even
+ more recent - the regression in Ant 1.7.1 -->
+ <touch file="${javac-dir}/src/a/package-info.java" />
+ <sleep seconds="2" />
+ <touch>
+ <file file="${javac-dir}/src/a" />
+ </touch>
+ <javac srcdir="${javac-dir}/src" updatedProperty="third-pass" />
+ <au:assertPropertyEquals name="third-pass" value="true" />
+ </target>
+
+ <target name="testSuppressPackageInfoClass"
+ depends="setUpForPackageInfoJava"
+ description="https://issues.apache.org/bugzilla/show_bug.cgi?id=52096">
+ <au:assertFileExists file="${build-dir}/a/package-info.class"/>
+ <delete file="${build-dir}/a/package-info.class"/>
+ <javac srcdir="${javac-dir}/src" destdir="${build-dir}"
+ createMissingPackageInfoClass="false"
+ updatedProperty="second-pass" />
+ <au:assertPropertyEquals name="second-pass" value="true" />
+ <au:assertFileDoesntExist file="${build-dir}/a/package-info.class"/>
+ </target>
+
+ <target name="-create-javac-adapter">
+ <property name="adapter.dir" location="${output}/adapter" />
+ <mkdir dir="${input}/org/example" />
+ <echo file="${input}/org/example/Adapter.java">
+ <![CDATA[
+package org.example;
+import org.apache.tools.ant.taskdefs.compilers.CompilerAdapter;
+import org.apache.tools.ant.taskdefs.Javac;
+
+public class Adapter implements CompilerAdapter {
+ public void setJavac(Javac attributes) {}
+ public boolean execute() {
+ System.err.println("adapter called");
+ return true;
+ }
+}]]>
+ </echo>
+ <mkdir dir="${resources}" />
+ <javac srcdir="${input}" destdir="${resources}" />
+ </target>
+
+ <target name="testCompilerNotFound" depends="-create-javac-adapter">
+ <au:expectfailure>
+ <javac srcdir="${input}" destdir="${output}" compiler="org.example.Adapter" />
+ </au:expectfailure>
+ <au:assertLogDoesntContain text="adapter called" />
+ </target>
+
+ <target name="testCompilerClasspath" depends="-create-javac-adapter" description="https://issues.apache.org/bugzilla/show_bug.cgi?id=11143">
+ <mkdir dir="${output}" />
+ <javac srcdir="${input}" destdir="${output}" compiler="org.example.Adapter">
+ <compilerclasspath location="${resources}" />
+ </javac>
+ <au:assertLogContains text="adapter called" />
+ </target>
+
+ <target name="testCompilerAsNestedElement" depends="-create-javac-adapter">
+ <componentdef classname="org.example.Adapter" name="myjavac">
+ <classpath location="${resources}" />
+ </componentdef>
+ <mkdir dir="${output}" />
+ <javac srcdir="${input}" destdir="${output}">
+ <myjavac />
+ </javac>
+ <au:assertLogContains text="adapter called" />
+ </target>
+
+ <target name="testSourceAttributes" xmlns:if="ant:if" xmlns:unless="ant:unless">
+ <delete dir="${javac-dir}/src" />
+ <mkdir dir="${javac-dir}/src" />
+ <mkdir dir="${javac-dir}/classes" />
+ <echo file="${javac-dir}/src/A.java">
+ public class A { }
+ </echo>
+ <presetdef name="testJavac">
+ <javac srcdir="${javac-dir}/src" destdir="${javac-dir}/classes" includeantruntime="false"/>
+ </presetdef>
+
+ <au:expectfailure>
+ <testJavac source="notValid"/>
+ </au:expectfailure>
+
+ <sequential unless:set="jdk1.9+">
+ <echo>JDK 1.4+</echo>
+ <testJavac source="1.4"/>
+ <delete dir="${javac-dir}/classes"/>
+ <mkdir dir="${javac-dir}/classes"/>
+ </sequential>
+
+ <sequential unless:set="jdk1.9+">
+ <echo>JDK 1.5+</echo>
+ <testJavac source="1.5"/>
+ <delete dir="${javac-dir}/classes"/>
+ <mkdir dir="${javac-dir}/classes"/>
+ </sequential>
+
+ <sequential if:set="jdk1.6+">
+ <echo>JDK 1.6+</echo>
+ <testJavac source="1.6"/>
+ <delete dir="${javac-dir}/classes"/>
+ <mkdir dir="${javac-dir}/classes"/>
+ </sequential>
+
+ <sequential if:set="jdk1.7+">
+ <echo>JDK 1.7+</echo>
+ <testJavac source="1.7"/>
+ <delete dir="${javac-dir}/classes"/>
+ <mkdir dir="${javac-dir}/classes"/>
+ </sequential>
+
+ <sequential if:set="jdk1.8+">
+ <echo>JDK 1.8+</echo>
+ <testJavac source="1.8"/>
+ <delete dir="${javac-dir}/classes"/>
+ <mkdir dir="${javac-dir}/classes"/>
+ </sequential>
+
+ <sequential if:set="jdk1.9+">
+ <echo>JDK 1.9+</echo>
+ <testJavac source="1.9"/>
+ <delete dir="${javac-dir}/classes"/>
+ <mkdir dir="${javac-dir}/classes"/>
+ </sequential>
+ </target>
+
+ <target name="testTargetAttributes" xmlns:if="ant:if" xmlns:unless="ant:unless">
+ <delete dir="${javac-dir}/src" />
+ <mkdir dir="${javac-dir}/src" />
+ <mkdir dir="${javac-dir}/classes" />
+ <echo file="${javac-dir}/src/A.java">
+ public class A { }
+ </echo>
+ <presetdef name="testJavac">
+ <javac srcdir="${javac-dir}/src" destdir="${javac-dir}/classes" includeantruntime="false"/>
+ </presetdef>
+
+ <au:expectfailure>
+ <testJavac target="notValid"/>
+ </au:expectfailure>
+
+ <sequential unless:set="jdk1.9+">
+ <echo>JDK 1.4+</echo>
+ <testJavac source="1.4" target="1.4"/>
+ <delete dir="${javac-dir}/classes"/>
+ <mkdir dir="${javac-dir}/classes"/>
+ </sequential>
+
+ <sequential unless:set="jdk1.9+">
+ <echo>JDK 1.5+</echo>
+ <testJavac source="1.5" target="1.5"/>
+ <delete dir="${javac-dir}/classes"/>
+ <mkdir dir="${javac-dir}/classes"/>
+ </sequential>
+
+ <sequential if:set="jdk1.6+">
+ <echo>JDK 1.6+</echo>
+ <testJavac source="1.6" target="1.6"/>
+ <delete dir="${javac-dir}/classes"/>
+ <mkdir dir="${javac-dir}/classes"/>
+ </sequential>
+
+ <sequential if:set="jdk1.7+">
+ <echo>JDK 1.7+</echo>
+ <testJavac source="1.7" target="1.7"/>
+ <delete dir="${javac-dir}/classes"/>
+ <mkdir dir="${javac-dir}/classes"/>
+ </sequential>
+
+ <sequential if:set="jdk1.8+">
+ <echo>JDK 1.8+</echo>
+ <testJavac source="1.8" target="1.8"/>
+ <delete dir="${javac-dir}/classes"/>
+ <mkdir dir="${javac-dir}/classes"/>
+ </sequential>
+
+ <sequential if:set="jdk1.9+">
+ <echo>JDK 1.9+</echo>
+ <testJavac source="1.9" target="1.9"/>
+ <delete dir="${javac-dir}/classes"/>
+ <mkdir dir="${javac-dir}/classes"/>
+ </sequential>
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/javadoc-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/javadoc-test.xml
new file mode 100644
index 00000000..200082ba
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/javadoc-test.xml
@@ -0,0 +1,157 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="antunit" xmlns:au="antlib:org.apache.ant.antunit">
+ <import file="../antunit-base.xml" />
+
+ <target name="-makeTestClass">
+ <macrodef name="mktest">
+ <attribute name="package"/>
+ <attribute name="class"/>
+ <sequential>
+ <mkdir dir="${input}/@{package}"/>
+ <echo file="${input}/@{package}/@{class}.java"><![CDATA[
+package @{package};
+
+/**
+ * This is a test class.
+ */
+public class @{class} {
+ /**
+ * With a test method.
+ */
+ public void foo(String bar) {}
+}
+]]></echo>
+ </sequential>
+ </macrodef>
+ <mktest package="test" class="A"/>
+ </target>
+
+ <target name="-makeTwoTestClasses" depends="-makeTestClass">
+ <mktest package="test2" class="B"/>
+ </target>
+
+ <target name="testBottomWithLineBreaksWithFile" depends="-makeTestClass">
+ <javadoc destdir="${output}" useexternalfile="true">
+ <fileset dir="${input}"/>
+ <bottom><![CDATA[
+<hr/>
+Hello World
+]]></bottom>
+ </javadoc>
+ <au:assertFileExists file="${output}/test/A.html"/>
+ </target>
+
+ <target name="-setUpDocFilesTests" depends="-makeTestClass">
+ <mkdir dir="${input}/test/doc-files/a"/>
+ <mkdir dir="${input}/test/doc-files/b"/>
+ <macrodef name="mkfoo">
+ <attribute name="file"/>
+ <sequential>
+ <echo file="@{file}"><![CDATA[<p>Hello, world!</p>]]></echo>
+ </sequential>
+ </macrodef>
+ <mkfoo file="${input}/test/doc-files/foo.html"/>
+ <mkfoo file="${input}/test/doc-files/a/foo.html"/>
+ <mkfoo file="${input}/test/doc-files/b/foo.html"/>
+ </target>
+
+ <target name="-create-file-with-warning">
+ <mkdir dir="${input}/test"/>
+ <echo file="${input}/test/Foo.java"><![CDATA[
+package test;
+
+/**
+ * This is a test class.
+ */
+public class Foo {
+ /**
+ * With a test method.
+ * @param baz wrong parameter name should cause warning.
+ */
+ public void foo(String bar) {}
+}
+]]></echo>
+ </target>
+
+ <target name="testPackageSetNoExcludes" depends="-makeTwoTestClasses">
+ <javadoc destdir="${output}">
+ <packageset dir="${input}"/>
+ </javadoc>
+ <au:assertFileExists file="${output}/test/A.html"/>
+ <au:assertFileExists file="${output}/test2/B.html"/>
+ </target>
+
+ <target name="testPackageSetWithExcludes"
+ depends="-makeTwoTestClasses"
+ description="https://issues.apache.org/bugzilla/show_bug.cgi?id=47196">
+ <javadoc destdir="${output}">
+ <packageset dir="${input}">
+ <exclude name="test2"/>
+ </packageset>
+ </javadoc>
+ <au:assertFileExists file="${output}/test/A.html"/>
+ <au:assertFileDoesntExist file="${output}/test2/B.html"/>
+ </target>
+
+ <!-- basically tests no exception is thrown -->
+ <target name="testDontFailOnWarning"
+ depends="-create-file-with-warning">
+ <javadoc destdir="${output}">
+ <packageset dir="${input}"/>
+ </javadoc>
+ </target>
+
+ <target name="testFailOnWarning"
+ description="https://issues.apache.org/bugzilla/show_bug.cgi?id=55015"
+ depends="-create-file-with-warning">
+ <au:expectfailure>
+ <javadoc destdir="${output}" failonwarning="true">
+ <packageset dir="${input}"/>
+ </javadoc>
+ </au:expectfailure>
+ </target>
+
+ <target name="XtestNoDocFiles" depends="-setUpDocFilesTests">
+ <javadoc destdir="${output}">
+ <packageset dir="${input}"/>
+ </javadoc>
+ <au:assertFileExists file="${output}/test/doc-files/foo.html"/>
+ <au:assertFileDoesntExist file="${output}/test/doc-files/a/foo.html"/>
+ </target>
+
+ <target name="XtestDocFiles" depends="-setUpDocFilesTests">
+ <javadoc destdir="${output}" docfilessubdirs="true">
+ <packageset dir="${input}"/>
+ </javadoc>
+ <au:assertFileExists file="${output}/test/doc-files/foo.html"/>
+ <au:assertFileExists file="${output}/test/doc-files/a/foo.html"/>
+ <au:assertFileExists file="${output}/test/doc-files/b/foo.html"/>
+ </target>
+
+ <target name="XtestDocFilesWithExclude" depends="-setUpDocFilesTests">
+ <javadoc destdir="${output}" docfilessubdirs="true"
+ excludedocfilessubdir="a">
+ <packageset dir="${input}"/>
+ </javadoc>
+ <au:assertFileExists file="${output}/test/doc-files/foo.html"/>
+ <au:assertFileDoesntExist file="${output}/test/doc-files/a/foo.html"/>
+ <au:assertFileExists file="${output}/test/doc-files/b/foo.html"/>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/length-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/length-test.xml
new file mode 100644
index 00000000..acd5310b
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/length-test.xml
@@ -0,0 +1,240 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="length-test" default="antunit"
+ xmlns:au="antlib:org.apache.ant.antunit">
+
+ <import file="../antunit-base.xml" />
+
+ <property name="dir.a" location="${input}/a" />
+ <property name="dir.b" location="${input}/b" />
+ <property name="zipfile" location="${output}/lengthtest.zip" />
+
+ <target name="setUp">
+ <mkdir dir="${output}" />
+ <mkdir dir="${dir.a}" />
+ <mkdir dir="${dir.b}" />
+ <property name="foo" location="${dir.a}/foo" />
+ <property name="bar" location="${dir.b}/bar" />
+ <echo file="${foo}" message="foo" />
+ <echo file="${bar}" message="bar" />
+ </target>
+
+ <target name="testEach" depends="setUp">
+ <length mode="each" property="length.each">
+ <fileset id="fs" dir="${input}" />
+ </length>
+ <length string="${length.each}" property="length.length.each" />
+ <length string="${foo}${bar}........${line.separator}"
+ property="length.expected" />
+
+ <au:assertTrue>
+ <!-- test that both files are represented, and that the
+ output is the expected length; do not assume order. -->
+ <and>
+ <contains string="${length.each}" substring="${foo} : 3" />
+ <contains string="${length.each}" substring="${bar} : 3" />
+ <equals arg1="${length.length.each}" arg2="${length.expected}" />
+ </and>
+ </au:assertTrue>
+ </target>
+
+ <target name="testEachCondition" depends="setUp">
+ <length mode="each" property="length.each">
+ <fileset id="fs" dir="${input}" />
+ </length>
+ <length string="${foo}${bar}........${line.separator}"
+ property="length.expected" />
+ <au:assertTrue>
+ <!-- test that both files are represented, and that the
+ output is the expected length; do not assume order. -->
+ <and>
+ <contains string="${length.each}" substring="${foo} : 3" />
+ <contains string="${length.each}" substring="${bar} : 3" />
+ <length string="${length.each}" length="${length.expected}" />
+ </and>
+ </au:assertTrue>
+ </target>
+
+ <target name="testAll" depends="setUp">
+ <length property="length.all">
+ <fileset id="foo" file="${dir.a}/foo" />
+ <fileset id="bar" file="${dir.b}/bar" />
+ </length>
+ <au:assertTrue>
+ <equals arg1="6" arg2="${length.all}" />
+ </au:assertTrue>
+ </target>
+
+ <target name="testAllCondition" depends="setUp">
+ <au:assertTrue>
+ <length length="6">
+ <fileset id="foo" file="${dir.a}/foo" />
+ <fileset id="bar" file="${dir.b}/bar" />
+ </length>
+ </au:assertTrue>
+ </target>
+
+ <target name="testFile" depends="setUp">
+ <length property="length.foo" file="${dir.a}/foo" />
+ <au:assertTrue>
+ <equals arg1="3" arg2="${length.foo}" />
+ </au:assertTrue>
+ </target>
+
+ <target name="testFileCondition" depends="setUp">
+ <au:assertTrue>
+ <length length="3" file="${dir.a}/foo" />
+ </au:assertTrue>
+ </target>
+
+ <target name="testBoth" depends="setUp">
+ <length property="length.foo" file="${dir.a}/foo">
+ <fileset file="${dir.b}/bar" />
+ </length>
+ <au:assertTrue>
+ <equals arg1="6" arg2="${length.foo}" />
+ </au:assertTrue>
+ </target>
+
+ <target name="testBothCondition" depends="setUp">
+ <au:assertTrue>
+ <length length="6" file="${dir.a}/foo">
+ <fileset file="${dir.b}/bar" />
+ </length>
+ </au:assertTrue>
+ </target>
+
+ <target name="testDupes" depends="setUp">
+ <length property="length.foo" file="${dir.a}/foo">
+ <fileset dir="${input}" />
+ </length>
+ <au:assertTrue>
+ <equals arg1="9" arg2="${length.foo}" />
+ </au:assertTrue>
+ </target>
+
+ <target name="testDupesCondition" depends="setUp">
+ <au:assertTrue>
+ <length length="9" file="${dir.a}/foo">
+ <fileset dir="${input}" />
+ </length>
+ </au:assertTrue>
+ </target>
+
+ <target name="testString">
+ <length string="foo" property="length.string" />
+ <au:assertTrue>
+ <equals arg1="3" arg2="${length.string}" />
+ </au:assertTrue>
+ </target>
+
+ <target name="testStringCondition">
+ <au:assertTrue>
+ <length string="foo" length="3" />
+ </au:assertTrue>
+ </target>
+
+ <target name="testTrimString">
+ <length string=" foo " trim="true" property="length.string" />
+ <au:assertTrue>
+ <equals arg1="3" arg2="${length.string}" />
+ </au:assertTrue>
+ </target>
+
+ <target name="testTrimStringCondition">
+ <au:assertTrue>
+ <length string=" foo " trim="true" length="3" />
+ </au:assertTrue>
+ </target>
+
+ <target name="testNoTrimString">
+ <length string=" foo " property="length.string" />
+ <au:assertTrue>
+ <equals arg1="5" arg2="${length.string}" />
+ </au:assertTrue>
+ </target>
+
+ <target name="testNoTrimStringCondition">
+ <au:assertTrue>
+ <length string=" foo " length="5" />
+ </au:assertTrue>
+ </target>
+
+ <target name="testTrimFile" description="should fail">
+ <au:expectfailure>
+ <length file="${ant.file}" trim="false" />
+ </au:expectfailure>
+ </target>
+
+ <target name="testStringFile" description="should fail">
+ <au:expectfailure>
+ <length string="foo" file="${ant.file}" />
+ </au:expectfailure>
+ </target>
+
+ <target name="testImmutable">
+ <length string="foo" property="length.string" />
+ <length string="foobar" property="length.string" />
+ <au:assertTrue>
+ <equals arg1="3" arg2="${length.string}" />
+ </au:assertTrue>
+ </target>
+
+ <target name="zip" depends="setUp">
+ <zip destfile="${zipfile}">
+ <fileset file="${foo}" />
+ <fileset file="${bar}" />
+ </zip>
+ </target>
+
+ <target name="testZipFileSet" depends="zip">
+ <length property="length.zipfile1">
+ <zipfileset src="${zipfile}" />
+ </length>
+ <length property="length.zipfile2">
+ <zipfileset src="${zipfile}" includes="bar" />
+ </length>
+ <au:assertTrue>
+ <and>
+ <equals arg1="6" arg2="${length.zipfile1}" />
+ <equals arg1="3" arg2="${length.zipfile2}" />
+ </and>
+ </au:assertTrue>
+ </target>
+
+ <target name="testZipFileSetCondition" depends="zip">
+ <au:assertTrue>
+ <and>
+ <length length="6">
+ <zipfileset src="${zipfile}" />
+ </length>
+ <length length="3">
+ <zipfileset src="${zipfile}" includes="bar" />
+ </length>
+ </and>
+ </au:assertTrue>
+ </target>
+
+ <target name="testResourceAttribute">
+ <string id="s" value="foo-bar-baz" />
+ <au:assertTrue>
+ <length length="11" resource="${ant.refid:s}" />
+ </au:assertTrue>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/loadproperties-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/loadproperties-test.xml
new file mode 100644
index 00000000..04b53f11
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/loadproperties-test.xml
@@ -0,0 +1,192 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="loadproperties-test" default="antunit" xmlns:au="antlib:org.apache.ant.antunit">
+
+ <import file="../antunit-base.xml" />
+
+ <target name="setUp">
+ <mkdir dir="${input}" />
+ <property name="properties.tmp" location="${input}/properties.tmp" />
+ </target>
+
+ <target name="test-basic">
+ <loadproperties>
+ <string>basic.foo=foo
+basic.bar=bar
+basic.baz=baz</string>
+ </loadproperties>
+ <au:assertPropertyEquals name="basic.foo" value="foo" />
+ <au:assertPropertyEquals name="basic.bar" value="bar" />
+ <au:assertPropertyEquals name="basic.baz" value="baz" />
+ </target>
+
+ <target name="test-xref">
+ <loadproperties>
+ <string>xref.foo=foo
+xref.bar=$${xref.foo}
+xref.baz=$${xref.bar}</string>
+ </loadproperties>
+ <au:assertPropertyEquals name="xref.foo" value="foo" />
+ <au:assertPropertyEquals name="xref.bar" value="foo" />
+ <au:assertPropertyEquals name="xref.baz" value="foo" />
+ </target>
+
+ <target name="test-xref-complex">
+ <loadproperties>
+ <string>xref-complex.a=$$
+xref-complex.b={
+xref-complex.c=}
+xref-complex.d=x
+xref-complex.e=$${xref-complex.a}$${xref-complex.b}xref-complex.d$${xref-complex.c}
+xref-complex.f=$${xref-complex.e}</string>
+ </loadproperties>
+ <au:assertPropertyEquals name="xref-complex.a" value="$$" />
+ <au:assertPropertyEquals name="xref-complex.b" value="{" />
+ <au:assertPropertyEquals name="xref-complex.c" value="}" />
+ <au:assertPropertyEquals name="xref-complex.d" value="x" />
+ <au:assertPropertyEquals name="xref-complex.e" value="$${xref-complex.d}" />
+ <au:assertPropertyEquals name="xref-complex.f" value="$${xref-complex.d}" />
+ </target>
+
+ <target name="testEncoding"
+ description="https://issues.apache.org/bugzilla/show_bug.cgi?id=47382">
+ <mkdir dir="${input}"/>
+ <echo file="${input}/ebcdic.properties" encoding="Cp1047">
+a=Hello world in EBCDIC
+ </echo>
+ <loadproperties srcfile="${input}/ebcdic.properties" encoding="Cp1047"/>
+ <au:assertPropertyEquals name="a" value="Hello world in EBCDIC"/>
+ </target>
+
+ <target name="testPrefixedProperties" depends="setUp">
+ <property name="server" value="localhost"/>
+ <echo file="${properties.tmp}">
+#http.@PORT@ = 90
+http.@PORT@ = 80
+http.@SERVER@ = ${server}
+ </echo>
+ <loadproperties srcFile="${properties.tmp}">
+ <filterchain>
+ <striplinecomments>
+ <comment value="#"/>
+ </striplinecomments>
+ <prefixlines prefix="server1."/>
+ <replacetokens>
+ <token key="PORT" value="port"/>
+ <token key="SERVER" value="server"/>
+ </replacetokens>
+ <expandproperties/>
+ </filterchain>
+ </loadproperties>
+ <property name="server1.http.url"
+ value="http://${server1.http.server}:${server1.http.port}"/>
+ </target>
+
+ <target name="testLineCommentsWithoutFiltering">
+ <loadproperties>
+ <string value="#foo=bar" />
+ </loadproperties>
+ <au:assertFalse>
+ <isset property="foo" />
+ </au:assertFalse>
+ </target>
+
+ <target name="testPrefixAttributeProperties">
+ <loadproperties prefix="prefixFromAttribute.">
+ <string>foo=foo
+bar=bar
+baz=${foo} ${bar}
+ </string>
+ </loadproperties>
+ <au:assertTrue>
+ <and>
+ <equals arg1="foo" arg2="${prefixFromAttribute.foo}" />
+ <equals arg1="bar" arg2="${prefixFromAttribute.bar}" />
+ <equals arg1="foo bar" arg2="${prefixFromAttribute.baz}" />
+ </and>
+ </au:assertTrue>
+ </target>
+
+ <target name="testSelfContainedPrefixFilterFailure"
+ description="Show why the prefix attribute is needed">
+ <loadproperties>
+ <string>foo=foo
+bar=bar
+baz=${foo} ${bar}
+ </string>
+ <filterchain>
+ <prefixlines prefix="prefixFromFilter." />
+ </filterchain>
+ </loadproperties>
+ <au:assertTrue>
+ <and>
+ <equals arg1="$${foo} $${bar}" arg2="${prefixFromFilter.baz}" />
+ <isset property="prefixFromFilter." />
+ </and>
+ </au:assertTrue>
+ </target>
+
+ <target name="write properties.tmp" depends="setUp">
+ <echo file="${properties.tmp}">
+#tpfr.a=a
+tpfr.a=A
+tpfr.b=b\
+ e
+tpfr.c=@C@
+ </echo>
+ </target>
+
+ <presetdef name="assertPropertiesFromResourceOkay">
+ <au:assertTrue>
+ <equals arg1="Abesea" arg2="${tpfr.a}${tpfr.b}${tpfr.c}" />
+ </au:assertTrue>
+ </presetdef>
+
+ <target name="testPropertiesFromResource" depends="write properties.tmp">
+ <loadproperties resource="properties.tmp" classpath="${input}">
+ <filterchain>
+ <replacetokens>
+ <token key="C" value="sea"/>
+ </replacetokens>
+ </filterchain>
+ </loadproperties>
+ </target>
+
+ <target name="testPropertiesFromFileSet" depends="write properties.tmp">
+ <loadproperties>
+ <fileset file="${properties.tmp}" />
+ <filterchain>
+ <replacetokens>
+ <token key="C" value="sea"/>
+ </replacetokens>
+ </filterchain>
+ </loadproperties>
+ <assertPropertiesFromResourceOkay />
+ </target>
+
+ <target name="testLastPropertyWins">
+ <loadproperties>
+ <string>foo=foo
+foo=bar</string>
+ </loadproperties>
+ <au:assertTrue>
+ <equals arg1="bar" arg2="${foo}" />
+ </au:assertTrue>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/loadresource-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/loadresource-test.xml
new file mode 100644
index 00000000..814ded5b
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/loadresource-test.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="antunit" xmlns:au="antlib:org.apache.ant.antunit">
+
+ <import file="../antunit-base.xml" />
+
+ <target name="test-resourceString">
+ <loadresource property="p">
+ <string value="one"/>
+ </loadresource >
+ <au:assertPropertyEquals name="p" value="one"/>
+ </target>
+
+ <target name="test-resourceSizeZero" description="Bug 42319">
+ <loadresource property="p">
+ <string value=""/>
+ </loadresource >
+ <au:assertTrue>
+ <not>
+ <isset property="p"/>
+ </not>
+ </au:assertTrue>
+ <au:assertLogContains text="Do not set property p as its length is 0."/>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/local-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/local-test.xml
new file mode 100644
index 00000000..9c4e7b7e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/local-test.xml
@@ -0,0 +1,96 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="antunit" xmlns:au="antlib:org.apache.ant.antunit">
+ <import file="../antunit-base.xml" />
+
+ <property name="foo" value="foo" />
+
+ <local name="bar" />
+ <property name="bar" value="bar" />
+ <au:assertPropertyEquals name="bar" value="bar" />
+
+ <target name="testGlobalLocal">
+ <au:assertFalse>
+ <isset property="bar" />
+ </au:assertFalse>
+ </target>
+
+ <target name="testBaseline">
+ <au:assertPropertyEquals name="foo" value="foo" />
+ </target>
+
+ <target name="testTarget">
+ <au:assertPropertyEquals name="foo" value="foo" />
+ <local name="foo" />
+ <property name="foo" value="foo.target" />
+ <au:assertPropertyEquals name="foo" value="foo.target" />
+ </target>
+
+ <target name="testSequential">
+ <sequential>
+ <local name="foo" />
+ <property name="foo" value="foo.1" />
+ <sequential>
+ <local name="foo" />
+ <property name="foo" value="foo.2" />
+ <au:assertPropertyEquals name="foo" value="foo.2" />
+ </sequential>
+ <au:assertPropertyEquals name="foo" value="foo.1" />
+ </sequential>
+ <au:assertPropertyEquals name="foo" value="foo" />
+ </target>
+
+ <target name="testParallel">
+ <macrodef name="p">
+ <attribute name="value" />
+ <attribute name="sleep" default="0" />
+ <sequential>
+ <local name="foo" />
+ <sleep seconds="@{sleep}" />
+ <property name="foo" value="@{value}" />
+ <au:assertPropertyEquals name="foo" value="@{value}" />
+ </sequential>
+ </macrodef>
+ <parallel>
+ <p sleep="2" value="foo.a" />
+ <au:assertPropertyEquals name="foo" value="foo" />
+ <p sleep="1" value="foo.b" />
+ <au:assertPropertyEquals name="foo" value="foo" />
+ <p sleep="0" value="foo.c" />
+ <au:assertPropertyEquals name="foo" value="foo" />
+ </parallel>
+ <au:assertPropertyEquals name="foo" value="foo" />
+ </target>
+
+ <target name="testMacrodef">
+ <macrodef name="m">
+ <sequential>
+ <local name="foo" />
+ <property name="foo" value="foo.x" />
+ <au:assertPropertyEquals name="foo" value="foo.x" />
+ </sequential>
+ </macrodef>
+ <m />
+ <au:assertPropertyEquals name="foo" value="foo" />
+ <m />
+ <au:assertPropertyEquals name="foo" value="foo" />
+ <m />
+ <au:assertPropertyEquals name="foo" value="foo" />
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/macrodef-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/macrodef-test.xml
new file mode 100644
index 00000000..b12e6f75
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/macrodef-test.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="length-test" default="antunit"
+ xmlns:au="antlib:org.apache.ant.antunit">
+
+ <import file="../antunit-base.xml" />
+
+ <target name="testDefaultTest">
+ <macrodef name="test-log">
+ <text name="log" default="DEFAULT-LOG-VALUE"/>
+ <sequential>
+ <concat>@{log}</concat>
+ </sequential>
+ </macrodef>
+ <test-log/>
+ <au:assertLogContains text="DEFAULT-LOG-VALUE"/>
+ <test-log>THIS IS NOT DEFAULT LOG</test-log>
+ <au:assertLogContains text="THIS IS NOT DEFAULT LOG"/>
+ </target>
+
+ <target name="testDisableDoubleExpandedProperties"
+ description="https://issues.apache.org/bugzilla/show_bug.cgi?id=42046">
+ <macrodef name="indirect">
+ <attribute name="value" doubleexpanding="false"/>
+ <sequential>
+ <echo message="@{value}"/>
+ </sequential>
+ </macrodef>
+ <indirect value="$${basedir}"/>
+ <au:assertLogContains text="{basedir}"/>
+ </target>
+
+ <target name="testEnableDoubleExpandedProperties"
+ description="https://issues.apache.org/bugzilla/show_bug.cgi?id=52621">
+ <macrodef name="indirect">
+ <attribute name="value"/>
+ <sequential>
+ <echo message="@{value}"/>
+ </sequential>
+ </macrodef>
+ <indirect value="$${basedir}"/>
+ <au:assertLogDoesntContain text="{basedir}"/>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/manifest-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/manifest-test.xml
new file mode 100644
index 00000000..4247ef2d
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/manifest-test.xml
@@ -0,0 +1,180 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="antunit"
+ xmlns:au="antlib:org.apache.ant.antunit">
+
+ <import file="../antunit-base.xml" />
+
+ <target name="setUp">
+ <mkdir dir="${output}"/>
+ <property name="file" location="${output}/test.mf"/>
+ </target>
+
+ <target name="test8IsAllowed"
+ description="https://issues.apache.org/bugzilla/show_bug.cgi?id=45675"
+ depends="setUp">
+ <manifest file="${file}">
+ <attribute name="attrib8" value="test attribute"/>
+ </manifest>
+ </target>
+
+ <target name="testMergeOverrides" depends="setUp">
+ <manifest file="${file}">
+ <attribute name="foo" value="value1"/>
+ <attribute name="bar" value="value1"/>
+ <section name="bar">
+ <attribute name="foo" value="value2"/>
+ </section>
+ </manifest>
+ <manifest file="${file}" mode="update">
+ <attribute name="foo" value="value3"/>
+ <section name="bar">
+ <attribute name="foo" value="value5"/>
+ </section>
+ </manifest>
+ <au:assertResourceContains
+ resource="${file}"
+ value="foo: value3&#13;&#10;"/>
+ <au:assertResourceContains
+ resource="${file}"
+ value="bar: value1&#13;&#10;"/>
+ <au:assertResourceContains
+ resource="${file}"
+ value="foo: value5&#13;&#10;"/>
+ <au:assertResourceDoesntContain
+ resource="${file}"
+ value="foo: value1&#13;&#10;"/>
+ <au:assertResourceDoesntContain
+ resource="${file}"
+ value="foo: value2&#13;&#10;"/>
+ </target>
+
+ <target name="testMergeOverridesClassPath" depends="setUp">
+ <manifest file="${file}">
+ <attribute name="Class-Path" value="foo"/>
+ </manifest>
+ <manifest file="${file}" mode="update">
+ <attribute name="Class-Path" value="bar"/>
+ </manifest>
+ <au:assertResourceContains
+ resource="${file}"
+ value="Class-Path: bar&#13;&#10;"/>
+ <au:assertResourceDoesntContain
+ resource="${file}"
+ value="Class-Path: foo&#13;&#10;"/>
+ </target>
+
+ <target name="testMultipleClassPathAttributes" depends="setUp">
+ <manifest file="${file}">
+ <attribute name="Class-Path" value="foo"/>
+ <attribute name="Class-Path" value="bar"/>
+ </manifest>
+ <au:assertResourceContains
+ resource="${file}"
+ value="Class-Path: foo&#13;&#10;"/>
+ <au:assertResourceContains
+ resource="${file}"
+ value="Class-Path: bar&#13;&#10;"/>
+ </target>
+
+ <target name="testMergeClassPathAttributes" depends="setUp">
+ <manifest file="${file}">
+ <attribute name="Class-Path" value="foo"/>
+ <attribute name="Class-Path" value="bar"/>
+ </manifest>
+ <manifest file="${file}" mergeClassPathAttributes="true" mode="update">
+ <attribute name="Class-Path" value="baz"/>
+ </manifest>
+ <au:assertResourceContains
+ resource="${file}"
+ value="Class-Path: foo&#13;&#10;"/>
+ <au:assertResourceContains
+ resource="${file}"
+ value="Class-Path: bar&#13;&#10;"/>
+ <au:assertResourceContains
+ resource="${file}"
+ value="Class-Path: baz&#13;&#10;"/>
+ </target>
+
+ <target name="testFlattenMultipleClassPathAttributes" depends="setUp">
+ <manifest file="${file}" flattenAttributes="true">
+ <attribute name="Class-Path" value="foo"/>
+ <attribute name="Class-Path" value="bar"/>
+ </manifest>
+ <au:assertResourceContains
+ resource="${file}"
+ value="Class-Path: foo bar&#13;&#10;"/>
+ </target>
+
+ <target name="testMergeAndFlattenClassPathAttributes" depends="setUp">
+ <manifest file="${file}">
+ <attribute name="Class-Path" value="foo"/>
+ <attribute name="Class-Path" value="bar"/>
+ </manifest>
+ <manifest file="${file}"
+ mergeClassPathAttributes="true"
+ flattenAttributes="true"
+ mode="update">
+ <attribute name="Class-Path" value="baz"/>
+ </manifest>
+ <au:assertResourceContains
+ resource="${file}"
+ value="Class-Path: baz foo bar&#13;&#10;"/>
+ </target>
+
+ <target name="-prepareJava5JarTest" depends="setUp">
+ <mkdir dir="${output}/bin"/>
+ <mkdir dir="${input}/org/example"/>
+ <echo file="${input}/org/example/AntFail.java"><![CDATA[
+package org.example;
+
+public class AntFail {
+ public static
+ void main(String[] args) {
+ System.out.println(System.getProperty("java.version"));
+ }
+ }
+]]></echo>
+ <javac srcdir="${input}" destdir="${output}/bin" includeantruntime="no" />
+ </target>
+
+ <target name="testJava5JarProblemManifestInSeparateTask"
+ depends="-prepareJava5JarTest"
+ description="https://issues.apache.org/bugzilla/show_bug.cgi?id=54762">
+ <manifest file="${output}/MANIFEST.MF">
+ <attribute name="Main-Class" value="org.example.AntFail" />
+ </manifest>
+
+ <jar manifest="${output}/MANIFEST.MF" destfile="${output}/antfail.jar"
+ basedir="${output}/bin" />
+ <java jar="${output}/antfail.jar" fork="true" failonerror="true"/>
+ </target>
+
+ <target name="testJava5JarProblemManifestAsNestedElement"
+ depends="-prepareJava5JarTest"
+ description="https://issues.apache.org/bugzilla/show_bug.cgi?id=54762">
+
+ <jar destfile="${output}/antfail.jar"
+ basedir="${output}/bin">
+ <manifest>
+ <attribute name="Main-Class" value="org.example.AntFail" />
+ </manifest>
+ </jar>
+ <java jar="${output}/antfail.jar" fork="true" failonerror="true"/>
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/manifestclasspath-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/manifestclasspath-test.xml
new file mode 100644
index 00000000..612990b6
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/manifestclasspath-test.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="antunit"
+ xmlns:au="antlib:org.apache.ant.antunit">
+
+ <import file="../antunit-base.xml" />
+
+ <target name="testRelativePathOfParentDir">
+ <manifestclasspath property="jar.classpath"
+ jarfile="${basedir}/foo.jar">
+ <classpath path="${basedir}"/>
+ </manifestclasspath>
+ <au:assertPropertyEquals name="jar.classpath" value="./"/>
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/move-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/move-test.xml
new file mode 100644
index 00000000..9acac749
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/move-test.xml
@@ -0,0 +1,234 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="antunit" xmlns:au="antlib:org.apache.ant.antunit">
+ <import file="../antunit-base.xml" />
+
+ <target name="test-move-caseonly">
+ <!-- this test is inspired by bugzilla 41948 -->
+ <!-- Especially interesting if executed on case-insensitive file systems -->
+ <mkdir dir="${output}"/>
+ <touch file="${output}/abc"/>
+ <move file="${output}/abc" tofile="${output}/aBc"/>
+ <fileset dir="${output}" id="myfs">
+ <include name="aBc"/>
+ </fileset>
+ <pathconvert refid="myfs" property="myproperty" setonempty="false"/>
+ <au:assertPropertySet name="myproperty" message="abc was not renamed aBc"/>
+ </target>
+
+ <target name="test-regex-mapper"
+ description="https://issues.apache.org/bugzilla/show_bug.cgi?id=18656">
+ <mkdir dir="${input}/AAA/foo"/>
+ <touch file="${input}/AAA/foo/bar.txt"/>
+ <mkdir dir="${input}/foo/AAA"/>
+ <touch file="${input}/foo/bar.txt"/>
+ <touch file="${input}/foo/AAA/bar.txt"/>
+ <mkdir dir="${input}/foo/bar"/>
+ <touch file="${input}/foo/bar/AAA.txt"/>
+ <touch file="${input}/foo/bar/baz.txt"/>
+
+ <mkdir dir="${output}"/>
+
+ <move todir="${output}">
+ <fileset dir="${input}"/>
+ <firstmatchmapper>
+ <regexpmapper from="(.*)AAA(.*)" to="\1BBB\2"/>
+ <identitymapper/>
+ </firstmatchmapper>
+ </move>
+
+ <au:assertFileExists file="${output}/BBB/foo/bar.txt"/>
+ <au:assertFileExists file="${output}/foo/bar.txt"/>
+ <au:assertFileExists file="${output}/foo/BBB/bar.txt"/>
+ <au:assertFileExists file="${output}/foo/bar/BBB.txt"/>
+ <au:assertFileExists file="${output}/foo/bar/baz.txt"/>
+ </target>
+
+ <target name="testNotModifiedSelector"
+ description="https://issues.apache.org/bugzilla/show_bug.cgi?id=43574"
+ >
+ <mkdir dir="${input}/images"/>
+ <mkdir dir="${input}/cache"/>
+ <touch file="${input}/images/foo.jpg"/>
+ <mkdir dir="${output}"/>
+ <selector id="cache.selector">
+ <not>
+ <modified update="true"
+ seldirs="false"
+ cache="propertyfile"
+ algorithm="digest"
+ comparator="equal">
+ <param name="cache.cachefile"
+ value="${input}/cache/cache.properties"/>
+ <param name="algorithm.algorithm" value="MD5"/>
+ </modified>
+ </not>
+ </selector>
+ <au:assertFileDoesntExist file="${input}/cache/cache.properties"/>
+ <move todir="${output}" overwrite="true">
+ <fileset dir="${input}/images">
+ <include name="*.jpg" />
+ <selector refid="cache.selector" />
+ </fileset>
+ </move>
+ <au:assertFileExists file="${input}/cache/cache.properties"/>
+ <au:assertFileExists file="${input}/images/foo.jpg"/>
+ <au:assertFileDoesntExist file="${output}/foo.jpg"/>
+ <move todir="${output}" overwrite="true">
+ <fileset dir="${input}/images">
+ <include name="*.jpg" />
+ <selector refid="cache.selector" />
+ </fileset>
+ </move>
+ <au:assertFileDoesntExist file="${input}/images/foo.jpg"/>
+ <au:assertFileExists file="${output}/foo.jpg"/>
+ </target>
+
+ <target name="testOverwriteIsTrueByDefault">
+ <mkdir dir="${input}"/>
+ <mkdir dir="${output}"/>
+ <echo file="${input}/x.txt">X</echo>
+ <sleep seconds="2"/>
+ <echo file="${output}/y.txt">Y</echo>
+ <move file="${input}/x.txt" tofile="${output}/y.txt"/>
+ <au:assertFileDoesntExist file="${input}/x.txt"/>
+ <au:assertResourceContains resource="${output}/y.txt"
+ value="X"/>
+ </target>
+
+ <target name="testOverwriteIsHonored"
+ description="https://issues.apache.org/bugzilla/show_bug.cgi?id=47755">
+ <mkdir dir="${input}"/>
+ <mkdir dir="${output}"/>
+ <echo file="${input}/x.txt">X</echo>
+ <sleep seconds="2"/>
+ <echo file="${output}/y.txt">Y</echo>
+ <move file="${input}/x.txt" tofile="${output}/y.txt" overwrite="false"/>
+ <au:assertFileExists file="${input}/x.txt"/>
+ <au:assertResourceContains resource="${output}/y.txt"
+ value="Y"/>
+ </target>
+
+ <!-- stolen from ../types/readwrite-test.xml - create a read-only file -->
+ <property name="file" value="testfile"/>
+ <condition property="unix">
+ <os family="unix"/>
+ </condition>
+ <target name="createTestdir">
+ <mkdir dir="${output}"/>
+ <mkdir dir="${input}"/>
+ <touch file="${output}/${file}"/>
+ </target>
+ <target name="makeFileUnwritable"
+ depends="createTestdir,makeFileUnwritable-Unix,makeFileUnwritable-Windows"/>
+ <target name="makeFileUnwritable-Unix" id="unix">
+ <chmod file="${output}/${file}" perm="444"/>
+ </target>
+ <target name="makeFileUnwritable-Windows" unless="unix">
+ <attrib file="${output}/${file}" readonly="true"/>
+ </target>
+
+ <target name="testMoveOverReadOnlyFile" depends="makeFileUnwritable">
+ <sleep seconds="2"/>
+ <touch file="${input}/${file}"/>
+ <au:expectfailure
+ expectedMessage="can't replace read-only destination file ">
+ <move toDir="${output}">
+ <fileset dir="${input}"/>
+ </move>
+ </au:expectfailure>
+ </target>
+
+ <target name="testFilteredMoveOverReadOnlyFile" depends="makeFileUnwritable">
+ <sleep seconds="2"/>
+ <touch file="${input}/${file}"/>
+ <au:expectfailure
+ expectedMessage="can't write to read-only destination file ">
+ <move toDir="${output}">
+ <fileset dir="${input}"/>
+ <filterset>
+ <filter token="foo" value="bar"/>
+ </filterset>
+ </move>
+ </au:expectfailure>
+ </target>
+
+ <target name="testMoveOverReadOnlyFileWithOverwrite"
+ depends="makeFileUnwritable">
+ <touch file="${input}/${file}"/>
+ <au:expectfailure
+ expectedMessage="can't replace read-only destination file ">
+ <move toDir="${output}" overwrite="true">
+ <fileset dir="${input}"/>
+ </move>
+ </au:expectfailure>
+ </target>
+
+ <target name="testFilteredMoveOverReadOnlyFileWithOverwrite"
+ depends="makeFileUnwritable">
+ <touch file="${input}/${file}"/>
+ <au:expectfailure
+ expectedMessage="can't write to read-only destination file ">
+ <move toDir="${output}" overwrite="true">
+ <fileset dir="${input}"/>
+ <filterset>
+ <filter token="foo" value="bar"/>
+ </filterset>
+ </move>
+ </au:expectfailure>
+ </target>
+
+ <target name="testForcedMoveOverReadOnlyFile" depends="makeFileUnwritable">
+ <sleep seconds="2"/>
+ <touch file="${input}/${file}"/>
+ <move toDir="${output}" force="true">
+ <fileset dir="${input}"/>
+ </move>
+ </target>
+
+ <target name="testForcedFilteredMoveOverReadOnlyFile"
+ depends="makeFileUnwritable">
+ <sleep seconds="2"/>
+ <touch file="${input}/${file}"/>
+ <move toDir="${output}" force="true">
+ <fileset dir="${input}"/>
+ <filterset>
+ <filter token="foo" value="bar"/>
+ </filterset>
+ </move>
+ </target>
+
+ <target name="testForcedMoveOverReadOnlyFileWithOverwrite"
+ depends="makeFileUnwritable">
+ <touch file="${input}/${file}"/>
+ <move toDir="${output}" overwrite="true" force="true">
+ <fileset dir="${input}"/>
+ </move>
+ </target>
+
+ <target name="testForcedFilteredMoveOverReadOnlyFileWithOverwrite"
+ depends="makeFileUnwritable">
+ <touch file="${input}/${file}"/>
+ <move toDir="${output}" overwrite="true" force="true">
+ <fileset dir="${input}"/>
+ <filterset>
+ <filter token="foo" value="bar"/>
+ </filterset>
+ </move>
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/optional/depend/depend-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/optional/depend/depend-test.xml
new file mode 100644
index 00000000..48f94aa3
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/optional/depend/depend-test.xml
@@ -0,0 +1,131 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="antunit" xmlns:au="antlib:org.apache.ant.antunit">
+ <import file="../../../antunit-base.xml" />
+
+ <property name="src1" location="${input}/src1"/>
+ <property name="src2" location="${input}/src2"/>
+
+ <target name="setUp">
+ <mkdir dir="${src1}"/>
+ <mkdir dir="${output}"/>
+ <mkdir dir="${src1}/a"/>
+ <echo file="${src1}/a/B.java"><![CDATA[
+package a;
+public class B {
+ public static String hello() {
+ return "Hello";
+ }
+}
+]]></echo>
+ <mkdir dir="${src2}/b"/>
+ </target>
+
+ <target name="testBug45916" depends="setUp">
+ <echo file="${src2}/b/Main.java"><![CDATA[
+package b;
+
+import a.B;
+
+public class Main {
+
+ public static void main(String[] args) {
+ new Runnable() {
+ public void run() {
+ System.err.println(B.hello());
+ }
+ }.run();
+ }
+
+}
+]]></echo>
+ <javac srcdir="${src1}:${src2}"
+ destdir="${output}"/>
+
+ <!--to ensure that the classfiles generated in the previous step
+ will be outdated-->
+ <sleep seconds="3" />
+ <touch file="${src1}/a/B.java" />
+ <javac srcdir="${src1}" destdir="${output}"/>
+ <jar destfile="${output}/A.jar" basedir="${output}" includes="a/**"/>
+ <delete dir="${output}/a"/>
+
+ <depend srcDir="${src1}"
+ destDir="${output}" cache="${output}"
+ classpath="${output}/A.jar"/>
+ <au:assertFileExists file="${output}/b/Main$1.class"/>
+ </target>
+
+ <target name="classpathTestSetUp" depends="setUp">
+ <echo file="${src2}/b/Main.java"><![CDATA[
+package b;
+
+import a.B;
+
+public class Main {
+
+ public static void main(String[] args) {
+ System.err.println(B.hello());
+ }
+
+}
+]]></echo>
+
+ <property name="dest2" location="${output}/dest2"/>
+
+ <mkdir dir="${resources}"/>
+ <mkdir dir="${dest2}"/>
+
+ <javac srcdir="${src1}" destdir="${resources}"/>
+ <javac srcdir="${src2}" destdir="${dest2}" classpath="${resources}"/>
+ <sleep seconds="3" />
+ <touch file="${src1}/a/B.java" />
+ <javac srcdir="${src1}" destdir="${resources}"/>
+ <au:assertFileExists file="${dest2}/b/Main.class"/>
+ </target>
+
+ <target name="testClasspathJar" depends="classpathTestSetUp">
+
+ <jar destfile="${test.jar}" basedir="${resources}"/>
+ <delete dir="${resources}"/>
+ <path id="resources-id">
+ <pathelement location="${test.jar}"/>
+ </path>
+
+ <depend srcDir="${src2}"
+ destDir="${dest2}" cache="${output}"
+ classpathref="resources-id"
+ />
+ <au:assertFileDoesntExist file="${dest2}/b/Main.class"/>
+
+ </target>
+
+ <target name="testClasspathDir" depends="classpathTestSetUp">
+
+ <path id="resources-id">
+ <pathelement location="${resources}"/>
+ </path>
+
+ <depend srcDir="${src2}"
+ destDir="${dest2}" cache="${output}"
+ classpathref="resources-id"
+ />
+ <au:assertFileDoesntExist file="${dest2}/b/Main.class"/>
+
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/optional/funtest-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/optional/funtest-test.xml
new file mode 100644
index 00000000..6baa4f7e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/optional/funtest-test.xml
@@ -0,0 +1,128 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="antunit" xmlns:au="antlib:org.apache.ant.antunit">
+ <import file="../../antunit-base.xml"/>
+
+ <!-- three presets for state-->
+ <presetdef name="p1">
+ <property name="p1" value="true"/>
+ </presetdef>
+ <presetdef name="p2">
+ <property name="p2" value="true"/>
+ </presetdef>
+ <presetdef name="p3">
+ <property name="p3" value="true"/>
+ </presetdef>
+ <presetdef name="p4">
+ <property name="p4" value="true"/>
+ </presetdef>
+ <presetdef name="p5">
+ <property name="p5" value="true"/>
+ </presetdef>
+
+ <presetdef name="assertP1">
+ <au:assertPropertySet name="p1"/>
+ </presetdef>
+ <presetdef name="assertP2">
+ <au:assertPropertySet name="p2"/>
+ </presetdef>
+ <presetdef name="assertP3">
+ <au:assertPropertySet name="p3"/>
+ </presetdef>
+ <presetdef name="assertP4">
+ <au:assertPropertySet name="p4"/>
+ </presetdef>
+ <presetdef name="assertP5">
+ <au:assertPropertySet name="p5"/>
+ </presetdef>
+
+ <target name="setUp">
+ <taskdef name="funtest"
+ classname="org.apache.tools.ant.taskdefs.optional.testing.Funtest"/>
+ </target>
+
+ <target name="testPresets"
+ description="test the presets behave">
+ <p1/>
+ <assertP1/>
+ <p2/>
+ <assertP2/>
+ <p3/>
+ <assertP3/>
+ <p4/>
+ <assertP4/>
+ <p5/>
+ <assertP5/>
+ </target>
+
+ <target name="testToSuccess">
+ <funtest>
+ <setup>
+ <p1/>
+ </setup>
+ <application>
+ <assertP1/>
+ <p2/>
+ </application>
+ <block>
+ <isset property="p2"/>
+ </block>
+ <tests>
+ <assertP1/>
+ <assertP2/>
+ <p3/>
+ </tests>
+ <reporting>
+ <assertP3/>
+ <p4/>
+ </reporting>
+ <teardown>
+ <assertP4/>
+ <p5/>
+ </teardown>
+ </funtest>
+ <assertP5/>
+ </target>
+
+ <target name="testCondition">
+ <funtest >
+ <condition>
+ <isset property="unset"/>
+ </condition>
+ <setup>
+ <fail>should not be reached</fail>
+ </setup>
+ </funtest>
+ </target>
+
+ <target name="testSetupFailureSkipsTeardown">
+ <au:expectfailure message="setup failed">
+ <funtest>
+ <setup>
+ <p1/>
+ <fail>setup failed</fail>
+ </setup>
+ <teardown>
+ <p5/>
+ </teardown>
+ </funtest>
+ </au:expectfailure>
+ <assertP1/>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/optional/javah-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/optional/javah-test.xml
new file mode 100644
index 00000000..e85293e2
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/optional/javah-test.xml
@@ -0,0 +1,65 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="antunit" xmlns:au="antlib:org.apache.ant.antunit">
+ <import file="../../antunit-base.xml" />
+
+ <target name="-create-javah-adapter">
+ <mkdir dir="${input}/org/example" />
+ <echo file="${input}/org/example/Adapter.java">
+ <![CDATA[
+package org.example;
+import org.apache.tools.ant.taskdefs.optional.javah.JavahAdapter;
+import org.apache.tools.ant.taskdefs.optional.Javah;
+
+public class Adapter implements JavahAdapter {
+ public boolean compile(Javah javah) {
+ System.err.println("adapter called");
+ return true;
+ }
+}]]>
+ </echo>
+ <mkdir dir="${resources}" />
+ <javac srcdir="${input}" destdir="${resources}" />
+ </target>
+
+ <target name="testAdapterNotFound" depends="-create-javah-adapter">
+ <au:expectfailure>
+ <javah class="org.example.Adapter" destdir="${output}" implementation="org.example.Adapter" />
+ </au:expectfailure>
+ <au:assertLogDoesntContain text="adapter called" />
+ </target>
+
+ <target name="testImplementationClasspath" depends="-create-javah-adapter" description="https://issues.apache.org/bugzilla/show_bug.cgi?id=11143">
+ <mkdir dir="${output}" />
+ <javah class="org.example.Adapter" destdir="${output}" implementation="org.example.Adapter">
+ <implementationclasspath location="${resources}" />
+ </javah>
+ <au:assertLogContains text="adapter called" />
+ </target>
+
+ <target name="testImplementationAsNestedElement" depends="-create-javah-adapter">
+ <componentdef classname="org.example.Adapter" name="myjavac">
+ <classpath location="${resources}" />
+ </componentdef>
+ <mkdir dir="${output}" />
+ <javah class="org.example.Adapter" destdir="${output}">
+ <myjavac />
+ </javah>
+ <au:assertLogContains text="adapter called" />
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/optional/junit/junit-formatter-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/optional/junit/junit-formatter-test.xml
new file mode 100644
index 00000000..b9a63c94
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/optional/junit/junit-formatter-test.xml
@@ -0,0 +1,93 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="antunit" xmlns:au="antlib:org.apache.ant.antunit">
+ <import file="../../../antunit-base.xml" />
+
+ <path id="junit">
+ <fileset dir="../../../../../../lib/optional" includes="junit*"/>
+ </path>
+
+ <target name="setUp">
+ <mkdir dir="${input}"/>
+ <mkdir dir="${output}"/>
+ <echo file="${input}/ATest.java"><![CDATA[
+package test;
+import junit.framework.TestCase;
+
+public class ATest extends TestCase {
+ public void testEmpty() {}
+}
+]]></echo>
+ <javac srcdir="${input}" destdir="${output}">
+ <classpath refid="junit"/>
+ </javac>
+ <macrodef name="j">
+ <sequential>
+ <junit fork="true" forkMode="perBatch">
+ <classpath refid="junit"/>
+ <classpath location="${output}"/>
+ <batchtest todir="${output}">
+ <fileset dir="${output}">
+ <include name="**/*Test.class" />
+ </fileset>
+ </batchtest>
+ <formatter type="plain" if="${if}" extension=".dollar_if"/>
+ <formatter type="plain" if="if" extension=".if"/>
+ <formatter type="plain" unless="${if}" extension=".dollar_unless"/>
+ <formatter type="plain" unless="if" extension=".unless"/>
+ </junit>
+ </sequential>
+ </macrodef>
+ </target>
+
+ <target name="testPropertyNotSet" depends="setUp">
+ <j/>
+ <au:assertFileDoesntExist file="${output}/TEST-test.ATest.dollar_if"/>
+ <au:assertFileDoesntExist file="${output}/TEST-test.ATest.if"/>
+ <au:assertFileExists file="${output}/TEST-test.ATest.dollar_unless"/>
+ <au:assertFileExists file="${output}/TEST-test.ATest.unless"/>
+ </target>
+
+ <target name="testPropertySet" depends="setUp">
+ <property name="if" value="whatever"/>
+ <j/>
+ <au:assertFileDoesntExist file="${output}/TEST-test.ATest.dollar_if"/>
+ <au:assertFileExists file="${output}/TEST-test.ATest.if"/>
+ <au:assertFileExists file="${output}/TEST-test.ATest.dollar_unless"/>
+ <au:assertFileDoesntExist file="${output}/TEST-test.ATest.unless"/>
+ </target>
+
+ <target name="testPropertyTrue" depends="setUp">
+ <property name="if" value="true"/>
+ <j/>
+ <au:assertFileExists file="${output}/TEST-test.ATest.dollar_if"/>
+ <au:assertFileExists file="${output}/TEST-test.ATest.if"/>
+ <au:assertFileDoesntExist file="${output}/TEST-test.ATest.dollar_unless"/>
+ <au:assertFileDoesntExist file="${output}/TEST-test.ATest.unless"/>
+ </target>
+
+ <target name="testPropertyFalse" depends="setUp">
+ <property name="if" value="false"/>
+ <j/>
+ <au:assertFileDoesntExist file="${output}/TEST-test.ATest.dollar_if"/>
+ <au:assertFileExists file="${output}/TEST-test.ATest.if"/>
+ <au:assertFileExists file="${output}/TEST-test.ATest.dollar_unless"/>
+ <au:assertFileDoesntExist file="${output}/TEST-test.ATest.unless"/>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/optional/junit/junit-outputtoformatters-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/optional/junit/junit-outputtoformatters-test.xml
new file mode 100644
index 00000000..29068e48
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/optional/junit/junit-outputtoformatters-test.xml
@@ -0,0 +1,137 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="all" xmlns:au="antlib:org.apache.ant.antunit">
+ <import file="../../../antunit-base.xml" />
+ <property name="ant-build" location="../../../../../../build"/>
+ <property name="build-junit-dir" location="${ant-build}/ant-unit/junit-dir"/>
+ <property name="reports.dir" location="${build-junit-dir}/report"/>
+
+ <macrodef name="assert-file-not-contains" backtrace="no">
+ <sequential>
+ <au:assertFalse>
+ <isfileselected file="${reports.dir}/TEST-ExampleTest.txt">
+ <contains text="Hello From Test"/>
+ </isfileselected>
+ </au:assertFalse>
+ </sequential>
+ </macrodef>
+
+ <macrodef name="assert-file-contains" backtrace="no">
+ <sequential>
+ <au:assertTrue>
+ <isfileselected file="${reports.dir}/TEST-ExampleTest.txt">
+ <contains text="Hello From Test"/>
+ </isfileselected>
+ </au:assertTrue>
+ </sequential>
+ </macrodef>
+
+ <macrodef name="assert-log-not-contains" backtrace="no">
+ <sequential>
+ <au:assertLogDoesntContain text="Hello From Test" />
+ </sequential>
+ </macrodef>
+
+ <macrodef name="assert-log-contains" backtrace="no">
+ <sequential>
+ <au:assertLogContains text="Hello From Test"/>
+ </sequential>
+ </macrodef>
+
+ <macrodef name="run-junit">
+ <attribute name="fork"/>
+ <attribute name="showoutput"/>
+ <attribute name="outputtoformatters"/>
+ <sequential>
+ <junit fork="@{fork}" haltonfailure="no" showoutput="@{showoutput}"
+ outputtoformatters="@{outputtoformatters}">
+ <test name="ExampleTest" todir="${reports.dir}"/>
+ <classpath path="${resources}"/>
+ <formatter type="plain" usefile="yes"/>
+ </junit>
+ </sequential>
+ </macrodef>
+
+ <target name="init">
+ <delete quiet="yes" dir="${build-junit-dir}"/>
+ <mkdir dir="${resources}"/>
+ <mkdir dir="${reports.dir}"/>
+ </target>
+
+ <target name="compile" depends="init">
+ <javac srcdir="src" destdir="${resources}" debug="yes"/>
+ </target>
+
+ <target name="test-show-yes-formatters-yes" depends="compile">
+ <run-junit fork="yes" showoutput="yes"
+ outputtoformatters="yes"/>
+ <assert-log-contains/>
+ <assert-file-contains/>
+ </target>
+
+ <target name="test-show-yes-formatters-no" depends="compile">
+ <run-junit fork="yes" showoutput="yes"
+ outputtoformatters="no"/>
+ <assert-log-contains/>
+ <assert-file-not-contains/>
+ </target>
+
+ <target name="test-show-yes-formatters-no-forkno" depends="compile">
+ <run-junit fork="no" showoutput="yes"
+ outputtoformatters="no"/>
+ <assert-log-contains/>
+ <assert-file-not-contains/>
+ </target>
+
+ <target name="test-show-no-formatters-no" depends="compile">
+ <run-junit fork="yes" showoutput="no"
+ outputtoformatters="no"/>
+ <assert-log-not-contains/>
+ <assert-file-not-contains/>
+ </target>
+
+ <target name="test-show-no-formatters-no-fork-no" depends="compile">
+ <run-junit fork="no" showoutput="no"
+ outputtoformatters="no"/>
+ <assert-log-not-contains/>
+ <assert-file-not-contains/>
+ </target>
+
+ <target name="test-show-no-formatters-yes" depends="compile">
+ <run-junit fork="yes" showoutput="no"
+ outputtoformatters="yes"/>
+ <assert-log-not-contains/>
+ <assert-file-contains/>
+ </target>
+
+ <target name="test-show-no-formatters-yes-fork-no" depends="compile">
+ <run-junit fork="no" showoutput="no"
+ outputtoformatters="yes"/>
+ <assert-log-not-contains/>
+ <assert-file-contains/>
+ </target>
+
+ <target name="all">
+ <au:antunit>
+ <fileset file="${ant.file}"/>
+ <au:plainlistener/>
+ </au:antunit>
+ </target>
+
+</project>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/optional/junit/junit-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/optional/junit/junit-test.xml
new file mode 100644
index 00000000..e6aa794c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/optional/junit/junit-test.xml
@@ -0,0 +1,372 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="antunit" xmlns:au="antlib:org.apache.ant.antunit">
+ <import file="../../../antunit-base.xml" />
+
+ <path id="junit">
+ <fileset dir="../../../../../../lib/optional" includes="junit*" />
+ <fileset dir="../../../../../../lib/optional" includes="hamcrest-core*" />
+ </path>
+
+ <macrodef name="empty-test">
+ <attribute name="classname" />
+ <attribute name="package" default="test" />
+ <sequential>
+ <echo file="${input}/@{classname}.java">
+ <![CDATA[
+package @{package};
+import junit.framework.TestCase;
+
+public class @{classname} extends TestCase {
+ public void testEmpty() {}
+}
+]]>
+ </echo>
+ </sequential>
+ </macrodef>
+
+ <target name="setUp">
+ <mkdir dir="${input}" />
+ <mkdir dir="${output}" />
+ </target>
+
+ <target name="testTimeoutLogOfBatchTests">
+ <mkdir dir="${input}" />
+ <mkdir dir="${output}" />
+ <empty-test classname="ATest" package="org.apache.ant.test" />
+ <echo file="${input}/BTest.java">
+ <![CDATA[
+package org.apache.ant.test;
+import junit.framework.TestCase;
+
+public class BTest extends TestCase {
+ public void testEmpty() throws Exception {
+ Thread.sleep(20 * 1000);
+ }
+}
+]]>
+ </echo>
+ <empty-test classname="CTest" package="org.apache.ant.test" />
+ <empty-test classname="DTest" package="org.apache.ant.test" />
+ <javac srcdir="${input}" destdir="${output}">
+ <classpath refid="junit" />
+ </javac>
+ <junit fork="true" forkMode="perBatch" timeout="5000" printsummary="yes">
+ <classpath refid="junit" />
+ <classpath location="${output}" />
+ <batchtest>
+ <fileset dir="${output}">
+ <include name="**/*Test.class" />
+ </fileset>
+ </batchtest>
+ </junit>
+ <au:assertLogContains text="ATest" />
+ <au:assertLogContains text="BTest" />
+ <au:assertLogContains text="org.apache.ant.test.Batch-With-Multiple-Tests" />
+ <au:assertLogDoesntContain text="CTest" />
+ <au:assertLogDoesntContain text="DTest" />
+ </target>
+
+ <target name="testFailurePropertyOnTestCase">
+ <mkdir dir="${input}" />
+ <mkdir dir="${output}" />
+ <echo file="${input}/ATest.java">
+ <![CDATA[
+package test;
+import junit.framework.TestCase;
+
+public class ATest extends TestCase {
+ public void testFail() {
+ assertTrue(false);
+ }
+}
+]]>
+ </echo>
+ <javac srcdir="${input}" destdir="${output}">
+ <classpath refid="junit" />
+ </javac>
+ <junit failureProperty="testcase.failed" haltonfailure="false">
+ <classpath refid="junit" />
+ <classpath location="${output}" />
+ <batchtest>
+ <fileset dir="${output}">
+ <include name="**/*Test.class" />
+ </fileset>
+ </batchtest>
+ </junit>
+ <au:assertPropertySet name="testcase.failed" />
+ </target>
+
+ <target name="testFailurePropertyOnTestSuite">
+ <mkdir dir="${input}" />
+ <mkdir dir="${output}" />
+ <echo file="${input}/ATest.java">
+ <![CDATA[
+package test;
+import junit.framework.Assert;
+import junit.framework.TestSuite;
+
+public class ATest extends TestSuite {
+ public ATest() {
+ super(test.ATest.class);
+ }
+ public void testFail() {
+ Assert.assertTrue(false);
+ }
+}
+]]>
+ </echo>
+ <javac srcdir="${input}" destdir="${output}">
+ <classpath refid="junit" />
+ </javac>
+ <junit failureProperty="testsuite.failed" haltonfailure="false">
+ <classpath refid="junit" />
+ <classpath location="${output}" />
+ <batchtest>
+ <fileset dir="${output}">
+ <include name="**/*Test.class" />
+ </fileset>
+ </batchtest>
+ </junit>
+ <au:assertPropertySet name="testsuite.failed" />
+ </target>
+
+ <target name="testTimeoutAndFormattersForkPerTest">
+ <antcall target="runTimeoutAndFormattersTest">
+ <param name="forkMode" value="perTest" />
+ </antcall>
+ <au:assertFileExists file="${output}/TEST-test.CTest.txt" />
+ <au:assertFileExists file="${output}/TEST-test.CTest.xml" />
+ <au:assertFileExists file="${output}/TEST-test.DTest.txt" />
+ <au:assertFileExists file="${output}/TEST-test.DTest.xml" />
+ </target>
+
+ <target name="testTimeoutAndFormattersForkOnce">
+ <antcall target="runTimeoutAndFormattersTest">
+ <param name="forkMode" value="once" />
+ </antcall>
+ <au:assertFileDoesntExist file="${output}/TEST-test.CTest.txt" />
+ <au:assertFileDoesntExist file="${output}/TEST-test.CTest.xml" />
+ <au:assertFileDoesntExist file="${output}/TEST-test.DTest.txt" />
+ <au:assertFileDoesntExist file="${output}/TEST-test.DTest.xml" />
+ </target>
+
+ <target name="runTimeoutAndFormattersTest" description="https://issues.apache.org/bugzilla/show_bug.cgi?id=35634">
+ <mkdir dir="${input}" />
+ <mkdir dir="${output}" />
+ <empty-test classname="ATest" />
+ <echo file="${input}/BTest.java">
+ <![CDATA[
+package test;
+import junit.framework.TestCase;
+
+public class BTest extends TestCase {
+ public void testEmpty() throws Exception {
+ Thread.sleep(20 * 1000);
+ }
+}
+]]>
+ </echo>
+ <empty-test classname="CTest" />
+ <empty-test classname="DTest" />
+ <javac srcdir="${input}" destdir="${output}">
+ <classpath refid="junit" />
+ </javac>
+ <junit fork="true" timeout="5000" forkmode="${forkMode}">
+ <classpath refid="junit" />
+ <classpath location="${output}" />
+ <batchtest todir="${output}">
+ <fileset dir="${output}">
+ <include name="**/*Test.class" />
+ </fileset>
+ </batchtest>
+ <formatter type="brief" />
+ <formatter type="xml" />
+ </junit>
+ <au:assertFileExists file="${output}/TEST-test.ATest.txt" />
+ <au:assertFileExists file="${output}/TEST-test.ATest.xml" />
+ <!--
+ <au:assertFileExists file="${output}/TEST-test.BTest.txt" />
+ <au:assertFileExists file="${output}/TEST-test.BTest.xml" />
+
+ These files should only exist if something was written to the log by te runner.
+ The test previously passed even though the files were empty, which isn't a meaningful result.
+ TODO we should probably improve the testing around reporting of tests that have timed-out
+ -->
+ </target>
+
+ <target name="-ifUnlessSetup" depends="setUp">
+ <empty-test classname="ATest" />
+ <empty-test classname="BTest" />
+ <empty-test classname="CTest" />
+ <empty-test classname="DTest" />
+ <empty-test classname="ETest" />
+ <empty-test classname="FTest" />
+ <empty-test classname="GTest" />
+ <empty-test classname="HTest" />
+ <javac srcdir="${input}" destdir="${output}">
+ <classpath refid="junit" />
+ </javac>
+ <macrodef name="j">
+ <sequential>
+ <junit fork="true" forkMode="perBatch" printsummary="yes">
+ <classpath refid="junit" />
+ <classpath location="${output}" />
+ <test name="test.ATest" if="${if}" />
+ <test name="test.BTest" if="if" />
+ <test name="test.CTest" unless="${if}" />
+ <test name="test.DTest" unless="if" />
+ <batchtest if="${if}">
+ <fileset dir="${output}">
+ <include name="**/ETest.class" />
+ </fileset>
+ </batchtest>
+ <batchtest if="if">
+ <fileset dir="${output}">
+ <include name="**/FTest.class" />
+ </fileset>
+ </batchtest>
+ <batchtest unless="${if}">
+ <fileset dir="${output}">
+ <include name="**/GTest.class" />
+ </fileset>
+ </batchtest>
+ <batchtest unless="if">
+ <fileset dir="${output}">
+ <include name="**/HTest.class" />
+ </fileset>
+ </batchtest>
+ </junit>
+ </sequential>
+ </macrodef>
+ </target>
+
+ <target name="testPropertiesNotSet" depends="-ifUnlessSetup">
+ <j />
+ <au:assertLogDoesntContain text="Running test.ATest" />
+ <au:assertLogDoesntContain text="Running test.BTest" />
+ <au:assertLogContains text="Running test.CTest" />
+ <au:assertLogContains text="Running test.DTest" />
+ <au:assertLogDoesntContain text="Running test.ETest" />
+ <au:assertLogDoesntContain text="Running test.FTest" />
+ <au:assertLogContains text="Running test.GTest" />
+ <au:assertLogContains text="Running test.HTest" />
+ </target>
+
+ <target name="testPropertiesSet" depends="-ifUnlessSetup">
+ <property name="if" value="whatever" />
+ <j />
+ <au:assertLogDoesntContain text="Running test.ATest" />
+ <au:assertLogContains text="Running test.BTest" />
+ <au:assertLogContains text="Running test.CTest" />
+ <au:assertLogDoesntContain text="Running test.DTest" />
+ <au:assertLogDoesntContain text="Running test.ETest" />
+ <au:assertLogContains text="Running test.FTest" />
+ <au:assertLogContains text="Running test.GTest" />
+ <au:assertLogDoesntContain text="Running test.HTest" />
+ </target>
+
+ <target name="testPropertiesTrue" depends="-ifUnlessSetup">
+ <property name="if" value="true" />
+ <j />
+ <au:assertLogContains text="Running test.ATest" />
+ <au:assertLogContains text="Running test.BTest" />
+ <au:assertLogDoesntContain text="Running test.CTest" />
+ <au:assertLogDoesntContain text="Running test.DTest" />
+ <au:assertLogContains text="Running test.ETest" />
+ <au:assertLogContains text="Running test.FTest" />
+ <au:assertLogDoesntContain text="Running test.GTest" />
+ <au:assertLogDoesntContain text="Running test.HTest" />
+ </target>
+
+ <target name="testPropertiesFalse" depends="-ifUnlessSetup">
+ <property name="if" value="false" />
+ <j />
+ <au:assertLogDoesntContain text="Running test.ATest" />
+ <au:assertLogContains text="Running test.BTest" />
+ <au:assertLogContains text="Running test.CTest" />
+ <au:assertLogDoesntContain text="Running test.DTest" />
+ <au:assertLogDoesntContain text="Running test.ETest" />
+ <au:assertLogContains text="Running test.FTest" />
+ <au:assertLogContains text="Running test.GTest" />
+ <au:assertLogDoesntContain text="Running test.HTest" />
+ </target>
+
+ <target name="testMissingTestName">
+ <property name="test.name" value="null" />
+ <au:expectfailure message="test name must be specified">
+ <junit fork="false">
+ <test name="${test.name}" />
+ </junit>
+ </au:expectfailure>
+ </target>
+
+ <target name="testTestMethods">
+ <condition property="source" value="6">
+ <isset property="jdk1.6+"/>
+ </condition>
+ <property name="source" value="5"/>
+ <echo file="${input}/T1.java">public class T1 extends
+ junit.framework.TestCase {
+ public void testOK() {}
+ public void testBad() {throw new RuntimeException("failed");}
+ }</echo>
+ <echo file="${input}/T2.java">
+ import org.junit.Test;
+ public class T2 {
+ @Test
+ public void ok() {}
+ @Test
+ public void bad() {
+ throw new RuntimeException("failed");}
+ }</echo>
+ <javac srcdir="${input}" destdir="${output}" includes="T1.java,T2.java" source="${source}" includeantruntime="false">
+ <classpath>
+ <path refid="junit" />
+ </classpath>
+ </javac>
+ <junit fork="true" printsummary="true" haltonerror="true">
+ <classpath>
+ <pathelement location="${output}" />
+ <path refid="junit" />
+ </classpath>
+ <test name="T1" methods="testOK" />
+ <test name="T2" methods="ok" />
+ </junit>
+ </target>
+
+ <target name="testClasspathBuildingSurvivesNonZips" depends="setUp"
+ description="https://issues.apache.org/bugzilla/show_bug.cgi?id=53964">
+ <empty-test classname="ATest" package="org.apache.ant.test" />
+ <javac srcdir="${input}" destdir="${output}">
+ <classpath refid="junit" />
+ </javac>
+ <junit fork="true" printsummary="true" haltonerror="true">
+ <classpath>
+ <pathelement location="${output}" />
+ <pathelement location="${ant.file}" />
+ <path refid="junit" />
+ </classpath>
+ <batchtest>
+ <fileset dir="${output}">
+ <include name="**/*Test.class" />
+ </fileset>
+ </batchtest>
+ </junit>
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/optional/junit/src/ExampleTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/optional/junit/src/ExampleTest.java
new file mode 100644
index 00000000..f1e5ca2b
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/optional/junit/src/ExampleTest.java
@@ -0,0 +1,23 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+import junit.framework.TestCase;
+
+public class ExampleTest extends TestCase {
+ public void testHello() {
+ System.out.println("Hello From Test");
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/optional/junit/xmlformatter-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/optional/junit/xmlformatter-test.xml
new file mode 100644
index 00000000..4aa6e4da
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/optional/junit/xmlformatter-test.xml
@@ -0,0 +1,126 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="antunit" xmlns:au="antlib:org.apache.ant.antunit">
+ <import file="../../../antunit-base.xml"/>
+
+ <path id="junit">
+ <fileset dir="../../../../../../lib/optional" includes="junit*"/>
+ </path>
+
+ <target name="test0Character">
+ <mkdir dir="${input}/org/example"/>
+ <echo file="${input}/org/example/A.java"><![CDATA[
+package org.example;
+import junit.framework.TestCase;
+public class A extends TestCase {
+ public void testX() {
+ System.err.println("Here comes the zero: \u0000");
+ }
+}
+]]></echo>
+ <mkdir dir="${output}"/>
+ <javac srcdir="${input}" destdir="${output}">
+ <classpath refid="junit"/>
+ </javac>
+ <junit fork="true">
+ <classpath refid="junit"/>
+ <classpath location="${output}"/>
+ <batchtest todir="${output}">
+ <fileset dir="${output}">
+ <include name="**/A.class" />
+ </fileset>
+ </batchtest>
+ <formatter type="xml"/>
+ </junit>
+ <xmlvalidate file="${output}/TEST-org.example.A.xml"
+ lenient="true"/>
+ </target>
+
+ <target name="testEntities"
+ description="https://issues.apache.org/bugzilla/show_bug.cgi?id=49404">
+ <mkdir dir="${input}/org/example"/>
+ <echo file="${input}/org/example/A.java"><![CDATA[
+package org.example;
+import junit.framework.TestCase;
+public class A extends TestCase {
+ public void testX() {
+ assertTrue("&amp;&", false);
+ }
+}
+]]></echo>
+ <mkdir dir="${output}"/>
+ <javac srcdir="${input}" destdir="${output}">
+ <classpath refid="junit"/>
+ </javac>
+ <junit fork="true">
+ <classpath refid="junit"/>
+ <classpath location="${output}"/>
+ <batchtest todir="${output}">
+ <fileset dir="${output}">
+ <include name="**/A.class" />
+ </fileset>
+ </batchtest>
+ <formatter type="xml"/>
+ </junit>
+ <xmlvalidate file="${output}/TEST-org.example.A.xml"
+ lenient="true"/>
+ <au:assertResourceContains
+ resource="${output}/TEST-org.example.A.xml"
+ value="message=&quot;&amp;amp;amp;&amp;amp;"/>
+ <au:assertResourceContains
+ resource="${output}/TEST-org.example.A.xml"
+ value="AssertionFailedError: &amp;amp;amp;&amp;"/>
+ </target>
+
+ <target name="testMessageWithTheWordMore">
+ <mkdir dir="${input}/org/example"/>
+ <echo file="${input}/org/example/A.java"><![CDATA[
+package org.example;
+import junit.framework.TestCase;
+public class A extends TestCase {
+ public void testX() {
+ assertTrue("Expected more than one result", 0 > 1);
+ }
+ public void testY() {
+ assertTrue("Expected less than one result", 2 < 1);
+ }
+}
+]]></echo>
+ <mkdir dir="${output}"/>
+ <javac srcdir="${input}" destdir="${output}">
+ <classpath refid="junit"/>
+ </javac>
+ <junit fork="true">
+ <classpath refid="junit"/>
+ <classpath location="${output}"/>
+ <batchtest todir="${output}">
+ <fileset dir="${output}">
+ <include name="**/A.class" />
+ </fileset>
+ </batchtest>
+ <formatter type="xml"/>
+ </junit>
+ <au:assertResourceContains
+ resource="${output}/TEST-org.example.A.xml"
+ value="junit.framework.AssertionFailedError: Expected less than one result"/>
+ <au:assertResourceContains
+ resource="${output}/TEST-org.example.A.xml"
+ value="junit.framework.AssertionFailedError: Expected more than one result"/>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/optional/native2ascii-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/optional/native2ascii-test.xml
new file mode 100644
index 00000000..7a30df79
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/optional/native2ascii-test.xml
@@ -0,0 +1,68 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="antunit" xmlns:au="antlib:org.apache.ant.antunit">
+ <import file="../../antunit-base.xml" />
+
+ <target name="-create-native2ascii-adapter">
+ <mkdir dir="${input}/org/example"/>
+ <echo file="${input}/org/example/Adapter.java"><![CDATA[
+package org.example;
+import java.io.File;
+import org.apache.tools.ant.taskdefs.optional.native2ascii.Native2AsciiAdapter;
+import org.apache.tools.ant.taskdefs.optional.Native2Ascii;
+
+public class Adapter implements Native2AsciiAdapter {
+ public boolean convert(Native2Ascii native2ascii, File f1, File f2) {
+ System.err.println("adapter called");
+ return true;
+ }
+}]]></echo>
+ <mkdir dir="${resources}"/>
+ <javac srcdir="${input}" destdir="${resources}"/>
+ </target>
+
+ <target name="testAdapterNotFound" depends="-create-native2ascii-adapter" unless="build.sysclasspath.only">
+ <!-- under gump the failure will not happen because the ${resources} directory is systematically on the classpath
+ what would be cool would be a task which removes a path element from the classpath. Do we have that ? -->
+ <au:expectfailure>
+ <native2ascii src="${input}" dest="${output}" includes="**/*.java"
+ implementation="org.example.Adapter"/>
+ </au:expectfailure>
+ <au:assertLogDoesntContain text="adapter called"/>
+ </target>
+
+ <target name="testImplementationClasspath" depends="-create-native2ascii-adapter"
+ description="https://issues.apache.org/bugzilla/show_bug.cgi?id=11143">
+ <native2ascii src="${input}" dest="${output}" includes="**/*.java"
+ implementation="org.example.Adapter">
+ <implementationclasspath location="${resources}"/>
+ </native2ascii>
+ <au:assertLogContains text="adapter called"/>
+ </target>
+
+ <target name="testImplementationAsNestedElement"
+ depends="-create-native2ascii-adapter">
+ <componentdef classname="org.example.Adapter" name="myjavac">
+ <classpath location="${resources}"/>
+ </componentdef>
+ <native2ascii src="${input}" dest="${output}" includes="**/*.java">
+ <myjavac/>
+ </native2ascii>
+ <au:assertLogContains text="adapter called"/>
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/optional/propertyfile-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/optional/propertyfile-test.xml
new file mode 100644
index 00000000..0ea70513
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/optional/propertyfile-test.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="antunit" xmlns:au="antlib:org.apache.ant.antunit">
+ <import file="../../antunit-base.xml" />
+
+ <target name="setUp">
+ <mkdir dir="${output}"/>
+ </target>
+
+ <target name="testReadWithPrefix" depends="setUp"
+ description="https://issues.apache.org/bugzilla/show_bug.cgi?id=48768">
+ <property name="test.txt" location="${output}/test.txt"/>
+ <echo file="${test.txt}"><![CDATA[
+bbb=val2
+aaa=val1
+]]></echo>
+
+ <property file="${test.txt}"/>
+ <au:assertPropertyEquals name="aaa" value="val1"/>
+ <au:assertPropertyEquals name="bbb" value="val2"/>
+ <propertyfile file="${test.txt}">
+ <entry key="bbb" value="dummy"/>
+ </propertyfile>
+
+ <property file="${test.txt}" prefix="xxx"/>
+ <au:assertPropertyEquals name="xxx.aaa" value="val1"/>
+ <au:assertPropertyEquals name="xxx.bbb" value="dummy"/>
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/optional/propertyfilelayout-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/optional/propertyfilelayout-test.xml
new file mode 100644
index 00000000..f1b367f9
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/optional/propertyfilelayout-test.xml
@@ -0,0 +1,289 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="antunit" xmlns:au="antlib:org.apache.ant.antunit">
+ <import file="../../antunit-base.xml" />
+
+ <target name="setUp">
+ <mkdir dir="${input}"/>
+ <mkdir dir="${output}"/>
+ <echo file="${input}/initial.properties"><![CDATA[#my comment
+foo=bar
+#second comment
+x=1
+]]></echo>
+ <fixcrlf file="${input}/initial.properties"/>
+ <presetdef name="pf">
+ <propertyfile file="${output}/created.properties">
+ <entry key="foo" value="bar"/>
+ <entry key="x" value="1" type="int"/>
+ </propertyfile>
+ </presetdef>
+ </target>
+
+ <target name="testCreateWithoutComment" depends="setUp">
+ <pf/>
+ <local name="head.in"/>
+ <local name="head.out"/>
+ <local name="tail.in"/>
+ <local name="tail.out"/>
+ <!-- skip comment -->
+ <loadfile srcfile="${input}/initial.properties" property="head.in">
+ <filterchain>
+ <headfilter lines="1" skip="1"/>
+ </filterchain>
+ </loadfile>
+ <loadfile srcfile="${input}/initial.properties" property="tail.in">
+ <filterchain>
+ <tailfilter lines="1"/>
+ </filterchain>
+ </loadfile>
+ <!-- skip date and blank line -->
+ <loadfile srcfile="${output}/created.properties" property="head.out">
+ <filterchain>
+ <headfilter lines="1" skip="2"/>
+ </filterchain>
+ </loadfile>
+ <loadfile srcfile="${output}/created.properties" property="tail.out">
+ <filterchain>
+ <tailfilter lines="1"/>
+ </filterchain>
+ </loadfile>
+ <au:assertPropertyEquals name="head.out" value="${head.in}"/>
+ <au:assertPropertyEquals name="tail.out" value="${tail.in}"/>
+ </target>
+
+ <target name="testCreateWithComment" depends="setUp">
+ <pf comment="my comment"/>
+ <local name="head.in"/>
+ <local name="head.out"/>
+ <local name="middle.in"/>
+ <local name="middle.out"/>
+ <local name="tail.in"/>
+ <local name="tail.out"/>
+ <!-- just comment -->
+ <loadfile srcfile="${input}/initial.properties" property="head.in">
+ <filterchain>
+ <headfilter lines="1"/>
+ </filterchain>
+ </loadfile>
+ <!-- skip comment -->
+ <loadfile srcfile="${input}/initial.properties" property="middle.in">
+ <filterchain>
+ <headfilter lines="1" skip="1"/>
+ </filterchain>
+ </loadfile>
+ <loadfile srcfile="${input}/initial.properties" property="tail.in">
+ <filterchain>
+ <tailfilter lines="1"/>
+ </filterchain>
+ </loadfile>
+ <!-- just comment -->
+ <loadfile srcfile="${output}/created.properties" property="head.out">
+ <filterchain>
+ <headfilter lines="1"/>
+ </filterchain>
+ </loadfile>
+ <!-- skip comment, date and blank line -->
+ <loadfile srcfile="${output}/created.properties" property="middle.out">
+ <filterchain>
+ <headfilter lines="1" skip="3"/>
+ </filterchain>
+ </loadfile>
+ <loadfile srcfile="${output}/created.properties" property="tail.out">
+ <filterchain>
+ <tailfilter lines="1"/>
+ </filterchain>
+ </loadfile>
+ <au:assertPropertyEquals name="head.out" value="${head.in}"/>
+ <au:assertPropertyEquals name="middle.out" value="${middle.in}"/>
+ <au:assertPropertyEquals name="tail.out" value="${tail.in}"/>
+ </target>
+
+ <target name="-updateSetUp" depends="setUp">
+ <copy file="${input}/initial.properties"
+ tofile="${output}/created.properties"/>
+ </target>
+
+ <target name="testUpdateWithoutComment" depends="-updateSetUp">
+ <pf/>
+ <local name="head.in"/>
+ <local name="head.out"/>
+ <loadfile srcfile="${input}/initial.properties" property="head.in"/>
+ <!-- skip date -->
+ <loadfile srcfile="${output}/created.properties" property="head.out">
+ <filterchain>
+ <headfilter skip="1"/>
+ </filterchain>
+ </loadfile>
+ <au:assertPropertyEquals name="head.out" value="${head.in}"/>
+ </target>
+
+ <target name="testUpdateWithNewComment" depends="-updateSetUp">
+ <pf comment="new comment"/>
+ <local name="head.in"/>
+ <local name="head.out"/>
+ <local name="tail.in"/>
+ <local name="tail.out"/>
+ <property name="head.in" value="#new comment${line.separator}"/>
+ <!-- just comment -->
+ <loadfile srcfile="${output}/created.properties" property="head.out">
+ <filterchain>
+ <headfilter lines="1"/>
+ </filterchain>
+ </loadfile>
+ <loadfile srcfile="${input}/initial.properties" property="tail.in"/>
+ <!-- skip new comment and date -->
+ <loadfile srcfile="${output}/created.properties" property="tail.out">
+ <filterchain>
+ <headfilter skip="2"/>
+ </filterchain>
+ </loadfile>
+ <au:assertPropertyEquals name="head.out" value="${head.in}"/>
+ <au:assertPropertyEquals name="tail.out" value="${tail.in}"/>
+ </target>
+
+ <target name="testUpdateWithSameComment" depends="-updateSetUp">
+ <pf comment="my comment"/>
+ <local name="head.in"/>
+ <local name="head.out"/>
+ <local name="tail.in"/>
+ <local name="tail.out"/>
+ <!-- just comment -->
+ <loadfile srcfile="${input}/initial.properties" property="head.in">
+ <filterchain>
+ <headfilter lines="1"/>
+ </filterchain>
+ </loadfile>
+ <!-- just comment -->
+ <loadfile srcfile="${output}/created.properties" property="head.out">
+ <filterchain>
+ <headfilter lines="1"/>
+ </filterchain>
+ </loadfile>
+ <!-- skip comment -->
+ <loadfile srcfile="${input}/initial.properties" property="tail.in">
+ <filterchain>
+ <headfilter skip="1"/>
+ </filterchain>
+ </loadfile>
+ <!-- skip comment and date -->
+ <loadfile srcfile="${output}/created.properties" property="tail.out">
+ <filterchain>
+ <headfilter skip="2"/>
+ </filterchain>
+ </loadfile>
+ <au:assertPropertyEquals name="head.out" value="${head.in}"/>
+ <au:assertPropertyEquals name="tail.out" value="${tail.in}"/>
+ </target>
+
+ <target name="testRepeatedUpdateWithoutComment" depends="-updateSetUp">
+ <pf/>
+ <pf/>
+ <local name="head.in"/>
+ <local name="head.out"/>
+ <loadfile srcfile="${input}/initial.properties" property="head.in"/>
+ <!-- skip date -->
+ <loadfile srcfile="${output}/created.properties" property="head.out">
+ <filterchain>
+ <headfilter skip="1"/>
+ </filterchain>
+ </loadfile>
+ <au:assertPropertyEquals name="head.out" value="${head.in}"/>
+ </target>
+
+ <target name="testRepeatedUpdateWithSameComment" depends="-updateSetUp">
+ <pf comment="my comment"/>
+ <pf comment="my comment"/>
+ <local name="head.in"/>
+ <local name="head.out"/>
+ <local name="tail.in"/>
+ <local name="tail.out"/>
+ <!-- just comment -->
+ <loadfile srcfile="${input}/initial.properties" property="head.in">
+ <filterchain>
+ <headfilter lines="1"/>
+ </filterchain>
+ </loadfile>
+ <!-- just comment -->
+ <loadfile srcfile="${output}/created.properties" property="head.out">
+ <filterchain>
+ <headfilter lines="1"/>
+ </filterchain>
+ </loadfile>
+ <!-- skip comment -->
+ <loadfile srcfile="${input}/initial.properties" property="tail.in">
+ <filterchain>
+ <headfilter skip="1"/>
+ </filterchain>
+ </loadfile>
+ <!-- skip comment and date -->
+ <loadfile srcfile="${output}/created.properties" property="tail.out">
+ <filterchain>
+ <headfilter skip="2"/>
+ </filterchain>
+ </loadfile>
+ <au:assertPropertyEquals name="head.out" value="${head.in}"/>
+ <au:assertPropertyEquals name="tail.out" value="${tail.in}"/>
+ </target>
+
+
+ <target name="testPreservesDosLineEnds" depends="setUp"
+ description="https://issues.apache.org/bugzilla/show_bug.cgi?id=50049">
+ <property name="test.txt" location="${output}/test.txt"/>
+ <echo file="${test.txt}"><![CDATA[
+bbb=val2
+aaa=val1
+]]></echo>
+ <fixcrlf eol="dos" file="${test.txt}"/>
+ <propertyfile file="${test.txt}" comment="${header}"/>
+ <copy file="${test.txt}" tofile="${test.txt}.expected"/>
+ <fixcrlf eol="dos" file="${test.txt}.expected"/>
+ <au:assertFilesMatch expected="${test.txt}.expected"
+ actual="${test.txt}"/>
+ </target>
+
+ <target name="testPreservesUnixLineEnds" depends="setUp"
+ description="https://issues.apache.org/bugzilla/show_bug.cgi?id=50049">
+ <property name="test.txt" location="${output}/test.txt"/>
+ <echo file="${test.txt}"><![CDATA[
+bbb=val2
+aaa=val1
+]]></echo>
+ <fixcrlf eol="unix" file="${test.txt}"/>
+ <propertyfile file="${test.txt}" comment="${header}"/>
+ <copy file="${test.txt}" tofile="${test.txt}.expected"/>
+ <fixcrlf eol="unix" file="${test.txt}.expected"/>
+ <au:assertFilesMatch expected="${test.txt}.expected"
+ actual="${test.txt}"/>
+ </target>
+
+ <target name="testPreservesMacLineEnds" depends="setUp"
+ description="https://issues.apache.org/bugzilla/show_bug.cgi?id=50049">
+ <property name="test.txt" location="${output}/test.txt"/>
+ <echo file="${test.txt}"><![CDATA[
+bbb=val2
+aaa=val1
+]]></echo>
+ <fixcrlf eol="mac" file="${test.txt}"/>
+ <propertyfile file="${test.txt}" comment="${header}"/>
+ <copy file="${test.txt}" tofile="${test.txt}.expected"/>
+ <fixcrlf eol="mac" file="${test.txt}.expected"/>
+ <au:assertFilesMatch expected="${test.txt}.expected"
+ actual="${test.txt}"/>
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/optional/replaceregexp-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/optional/replaceregexp-test.xml
new file mode 100644
index 00000000..2d64ce7a
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/optional/replaceregexp-test.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="antunit" xmlns:au="antlib:org.apache.ant.antunit">
+ <import file="../../antunit-base.xml" />
+
+ <target name="testRCSupport">
+ <mkdir dir="${output}"/>
+ <echo file="${output}/text.txt"><![CDATA[
+Hello, world!
+]]></echo>
+ <replaceregexp match="world" replace="Ant">
+ <file file="${output}/text.txt"/>
+ </replaceregexp>
+ <au:assertResourceContains
+ resource="${output}/text.txt" value="Hello, Ant!"/>
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/optional/script/scriptdef-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/optional/script/scriptdef-test.xml
new file mode 100644
index 00000000..da78e427
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/optional/script/scriptdef-test.xml
@@ -0,0 +1,131 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="antunit" xmlns:au="antlib:org.apache.ant.antunit">
+
+ <import file="../../../antunit-base.xml" />
+
+ <description>
+ In which we test interesting aspects of scripting.
+ The targeted language is javascript; this lets us run without
+ additions on Java6+.
+ </description>
+
+ <condition property="prereqs-ok">
+ <or>
+ <and>
+ <available classname="org.apache.bsf.BSFManager" />
+ <available classname="org.apache.bsf.engines.javascript.JavaScriptEngine" />
+ </and>
+ <available classname="javax.script.ScriptEngineManager" />
+ </or>
+ </condition>
+
+ <!-- auto doesn't verify the language is supported and selects BSF
+ even if the JavaScriptEngine is not there -->
+ <condition property="script.manager" value="javax">
+ <and>
+ <not>
+ <available classname="org.apache.bsf.engines.javascript.JavaScriptEngine" />
+ </not>
+ <isset property="prereqs-ok"/>
+ </and>
+ </condition>
+ <property name="script.manager" value="auto" />
+
+ <string id="script.code">
+ self.log("Ant version =${ant.version}");
+ project.setNewProperty("property","live");
+ </string>
+
+ <presetdef name="js">
+ <scriptdef language="javascript" name="scripttest" manager="${script.manager}">
+ <!-- optional property attribute-->
+ <attribute name="property" />
+ </scriptdef>
+ </presetdef>
+
+ <property name="prop" value='self.log("Ant version =${ant.version}");project.setNewProperty("property","live");' />
+
+ <presetdef name="assertPropSet">
+ <au:assertPropertyEquals name="property" value="live" />
+ </presetdef>
+
+
+ <!--purely to test that everything works -->
+ <target name="testInline" if="prereqs-ok">
+ <js>self.log("Hello");</js>
+ <scripttest />
+ </target>
+
+ <target name="testStringResource" if="prereqs-ok">
+ <js>
+ <string value='self.log("Ant version =${ant.version}");' />
+ </js>
+ <scripttest />
+ </target>
+
+ <target name="testStringResourceRef" if="prereqs-ok">
+ <js>
+ <string refid="script.code" />
+ </js>
+ <scripttest />
+ <assertPropSet />
+ </target>
+
+ <target name="testStringResourceInline" if="prereqs-ok">
+ <js>
+ <string>
+ self.log("Ant version =${ant.version}");
+ project.setNewProperty("property","live");
+ </string>
+ </js>
+ <scripttest />
+ <assertPropSet />
+ </target>
+
+ <target name="testPropertyResource" if="prereqs-ok">
+ <js>
+ <propertyresource name="prop" />
+ </js>
+ <scripttest />
+ <assertPropSet />
+ </target>
+
+ <target name="testMixedResources" if="prereqs-ok">
+ <js>
+ <string refid="script.code" />
+ <propertyresource name="prop" />
+ <string>
+ project.setNewProperty("property2","live");
+ </string>
+ </js>
+ <scripttest />
+ <assertPropSet name="property2" />
+ </target>
+
+ <target name="testExceptionNesting" description="https://issues.apache.org/bugzilla/show_bug.cgi?id=47509" if="prereqs-ok">
+ <scriptdef name="quickfail" language="javascript">
+ <![CDATA[
+ self.fail("I failed!");
+ ]]>
+ </scriptdef>
+ <au:expectfailure message="I failed!">
+ <quickfail />
+ </au:expectfailure>
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/optional/unix/symlink-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/optional/unix/symlink-test.xml
new file mode 100644
index 00000000..90c57f43
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/optional/unix/symlink-test.xml
@@ -0,0 +1,109 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="symlink-test"
+ default="antunit" xmlns:au="antlib:org.apache.ant.antunit">
+ <import file="../../../antunit-base.xml"/>
+
+ <target name="setUp">
+ <condition property="isUnix">
+ <os family="unix" />
+ </condition>
+ </target>
+
+ <target name="tearDown" depends="antunit-base.tearDown"
+ if="chmod.tmp">
+ <chmod dir="${chmod.tmp}" perm="755"/>
+ <delete dir="${chmod.tmp}"/>
+ </target>
+
+ <target name="os">
+
+ <mkdir dir="${output}" />
+ <condition property="unix">
+ <os family="unix" />
+ </condition>
+ <property name="file_ref"
+ location="${output}/file"/>
+ <property name="hanging_ref"
+ location="${output}/hanging_ref"/>
+ </target>
+
+ <target name="init" depends="os" if="unix">
+ <touch file="${file_ref}" />
+ </target>
+
+ <target name="testCreateDouble" depends="init" if="unix">
+ <symlink overwrite="true" link="${output}/link"
+ resource="${file_ref}"/>
+ <symlink overwrite="true" link="${output}/link"
+ resource="${file_ref}"/>
+ </target>
+
+
+ <target name="testCreateDoubleHanging" depends="init" if="unix">
+ <symlink overwrite="true" link="${output}/link2"
+ resource="${hanging_ref}"/>
+ <symlink overwrite="true" link="${output}/link2"
+ resource="${hanging_ref}"/>
+ </target>
+
+ <target name="testCreateOverFile" depends="init" if="unix">
+ <touch file="${output}/link3" />
+ <symlink overwrite="true" link="${output}/link3"
+ resource="${file_ref}"/>
+ </target>
+
+ <target name="testDeleteOfBrokenLink" depends="init" if="unix">
+ <symlink link="${output}/link" resource="${file_ref}"/>
+ <delete file="${file_ref}"/>
+ <symlink link="${output}/link" action="delete"/>
+ <au:assertFileDoesntExist file="${output}/link"/>
+ </target>
+
+ <target name="testDeleteLinkToParent" depends="init" if="unix">
+ <symlink link="${output}/link" resource="${output}"/>
+ <symlink link="${output}/link" action="delete"/>
+ <au:assertFileDoesntExist file="${output}/link"/>
+ </target>
+
+ <target name="testDeleteWithNoPermissionToRenameTarget"
+ depends="init" if="unix">
+ <!-- must be outside of ${output} or "base" tearDown will fail -->
+ <property name="chmod.tmp" location="${output}/../ant-symlink-test"/>
+ <mkdir dir="${chmod.tmp}/A"/>
+ <chmod perm="555" dir="${chmod.tmp}"/>
+ <symlink link="${output}/link" resource="${chmod.tmp}/A"/>
+ <symlink link="${output}/link" action="delete"/>
+ <au:assertFileDoesntExist file="${output}/link"/>
+ </target>
+
+ <target name="testDeleteLinkInSameDirAsBuildFile" depends="setUp" if="isUnix"
+ description="https://issues.apache.org/bugzilla/show_bug.cgi?id=49137">
+ <mkdir dir="${output}/Templates"/>
+ <mkdir dir="${output}/project1"/>
+ <symlink action="single" link="${output}/project1/Templates"
+ resource="../Templates"/>
+ <echo file="${output}/project1/build.xml"><![CDATA[
+<project name="project1" default="build" basedir=".">
+ <target name="build">
+ <symlink action="delete" link="Templates"/>
+ </target>
+</project>]]></echo>
+ <ant antfile="${output}/project1/build.xml"/>
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/optional/windows/attrib-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/optional/windows/attrib-test.xml
new file mode 100644
index 00000000..d5cea2b5
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/optional/windows/attrib-test.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="antunit" xmlns:au="antlib:org.apache.ant.antunit">
+ <import file="../../../antunit-base.xml" />
+
+ <target name="setUp">
+ <condition property="windows?">
+ <os family="windows"/>
+ </condition>
+ <mkdir dir="${input}"/>
+ </target>
+
+ <target name="testPerformance" depends="setUp" if="windows?"
+ description="https://issues.apache.org/bugzilla/show_bug.cgi?id=48734">
+ <touch file="${input}/0.tld"/>
+ <touch file="${input}/1.tld"/>
+ <touch file="${input}/2.tld"/>
+ <touch file="${input}/3.tld"/>
+ <touch file="${input}/4.tld"/>
+ <touch file="${input}/5.tld"/>
+ <touch file="${input}/6.tld"/>
+ <touch file="${input}/7.tld"/>
+ <touch file="${input}/8.tld"/>
+ <touch file="${input}/9.tld"/>
+ <attrib readonly="false">
+ <fileset dir="${input}">
+ <include name="*.tld" />
+ </fileset>
+ </attrib>
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/parallel-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/parallel-test.xml
new file mode 100644
index 00000000..72e4828d
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/parallel-test.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<project default="antunit"
+ xmlns:au="antlib:org.apache.ant.antunit">
+
+ <import file="../antunit-base.xml" />
+
+ <target name="testTimeout"
+ description="https://issues.apache.org/bugzilla/show_bug.cgi?id=49527">
+ <au:expectfailure message="Parallel execution timed out">
+ <parallel timeout="2000">
+ <sequential>
+ <echo message="Before sleep" />
+ <sleep seconds="10" />
+ <echo message="After sleep" />
+ </sequential>
+ </parallel>
+ </au:expectfailure>
+ <au:assertLogDoesntContain text="After sleep"/>
+ </target>
+</project> \ No newline at end of file
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/pathconvert-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/pathconvert-test.xml
new file mode 100644
index 00000000..3683affe
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/pathconvert-test.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="antunit" xmlns:au="antlib:org.apache.ant.antunit">
+ <import file="../antunit-base.xml" />
+
+ <target name="test-dir-char">
+ <pathconvert property="def|ghi" dirsep="|">
+ <map from="${basedir}/abc/" to=''/>
+ <path location="abc/def/ghi"/>
+ </pathconvert>
+ <au:assertTrue>
+ <equals arg1="${def|ghi}" arg2="def|ghi"/>
+ </au:assertTrue>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/property-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/property-test.xml
new file mode 100644
index 00000000..2eb0e18f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/property-test.xml
@@ -0,0 +1,171 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+<project default="antunit" xmlns:au="antlib:org.apache.ant.antunit">
+
+ <import file="../antunit-base.xml" />
+
+ <target name="testNestedText">
+ <property name="foo">bar</property>
+ <au:assertPropertyEquals name="foo" value="bar"/>
+ </target>
+
+ <target name="testNoNestedTextButValueAttribute">
+ <property name="foo" value="bar">
+ </property>
+ <au:assertPropertyEquals name="foo" value="bar"/>
+ </target>
+
+ <target name="testNestedTextAndValueAttribute">
+ <au:expectfailure>
+ <property name="foo" value="bar">
+ hello
+ </property>
+ </au:expectfailure>
+ </target>
+
+ <!-- Ensure we have platform dependent path separator -->
+ <property name="base" location="${basedir}"/>
+ <!-- an existing file as anchor for calculating paths -->
+ <property name="testfile" value="condition${file.separator}antversion-test.xml"/>
+
+ <target name="testLocation">
+ <property name="foo" location="${testfile}"/>
+ <au:assertPropertyEquals name="foo" value="${base}${file.separator}${testfile}"/>
+ </target>
+
+ <target name="testLocationWithRecursive">
+ <property name="foo" location="${testfile}" relative="false"/>
+ <au:assertPropertyEquals name="foo" value="${base}${file.separator}${testfile}"/>
+ </target>
+
+ <target name="testRelative">
+ <property name="foo" location="${testfile}" relative="true"/>
+ <au:assertPropertyEquals name="foo" value="${testfile}"/>
+ </target>
+
+ <target name="testRelativeBase">
+ <property name="foo" location="${testfile}" relative="true" basedir="${base}"/>
+ <au:assertPropertyEquals name="foo" value="${testfile}"/>
+ </target>
+
+ <target name="testRelativeUnderBase">
+ <property name="foo" location="${testfile}" relative="true" basedir="condition"/>
+ <au:assertPropertyEquals name="foo" value="antversion-test.xml"/>
+ </target>
+
+ <target name="testRelativeUnderBase2">
+ <property name="foo" location="${testfile}" relative="true" basedir="cvs"/>
+ <au:assertPropertyEquals name="foo" value="..${file.separator}condition${file.separator}antversion-test.xml"/>
+ </target>
+
+ <target name="testRelativeOverBase">
+ <property name="foo" location="${testfile}" relative="true" basedir=".."/>
+ <au:assertPropertyEquals name="foo" value="taskdefs${file.separator}${testfile}"/>
+ </target>
+
+ <target name="testNestedExpansionHonorsImmutability">
+ <mkdir dir="${input}"/>
+ <property name="x" value="x"/>
+ <echo file="${input}/x.properties"><![CDATA[
+x=y
+y=$${x}
+]]></echo>
+ <property file="${input}/x.properties"/>
+ <au:assertPropertyEquals name="y" value="x"/>
+ <echo file="${input}/y.properties"><![CDATA[
+x=y
+y=$${x}
+]]></echo>
+ <property file="${input}/y.properties" prefix="foo"/>
+ <!-- passes in Ant 1.8.0 and 1.7.1, fails in 1.8.1 -->
+ <au:assertPropertyEquals name="foo.y" value="x"/>
+ <echo file="${input}/z.properties"><![CDATA[
+x=y
+y=$${bar.x}
+]]></echo>
+ <property file="${input}/z.properties" prefix="bar"/>
+ <!-- passes in Ant 1.7.1 and 1.8.1, fails in 1.8.0 -->
+ <!--echo>bar.y is ${bar.y}</echo>
+ <au:assertLogContains text="bar.y is y"/>
+ <au:assertPropertyEquals name="bar.y" value="y"/-->
+ </target>
+
+ <!-- passes in Ant 1.7.1 and 1.8.1, fails in 1.8.0 -->
+ <target name="testMultiplePrefixes"
+ description="https://issues.apache.org/bugzilla/show_bug.cgi?id=48768">
+ <mkdir dir="${input}"/>
+ <echo file="${input}/x.properties"><![CDATA[
+x=1
+y=2
+]]></echo>
+ <property file="${input}/x.properties"/>
+ <au:assertPropertyEquals name="x" value="1"/>
+ <au:assertPropertyEquals name="y" value="2"/>
+ <echo file="${input}/y.properties"><![CDATA[
+x=3
+]]></echo>
+ <property file="${input}/y.properties" prefix="foo"/>
+ <au:assertPropertyEquals name="foo.x" value="3"/>
+ </target>
+
+ <!-- passes in Ant 1.7.1 and 1.8.0, fails in 1.8.1 -->
+ <target name="testNestedExpansionDoesntUsePrefix"
+ description="https://issues.apache.org/bugzilla/show_bug.cgi?id=49373">
+ <mkdir dir="${input}"/>
+ <property name="x" value="x"/>
+ <echo file="${input}/x.properties"><![CDATA[
+x=y
+y=$${x}
+]]></echo>
+ <property file="${input}/x.properties" prefix="foo"/>
+ <au:assertPropertyEquals name="foo.y" value="x"/>
+ </target>
+
+ <target name="testInternalExpansionWithPrefixOnlyExpandsWhenPrefixValuesIsTrue"
+ description="https://issues.apache.org/bugzilla/show_bug.cgi?id=54769">
+ <mkdir dir="${input}"/>
+ <echo file="${input}/x.properties"><![CDATA[
+a=A
+b=$${a}
+]]></echo>
+ <property file="${input}/x.properties" prefix="foo" prefixValues="true"/>
+ <au:assertPropertyEquals name="foo.b" value="A"/>
+ <property file="${input}/x.properties" prefix="bar" prefixValues="false"/>
+ <au:assertPropertyEquals name="bar.b" value="$${a}"/>
+ <property file="${input}/x.properties" prefix="baz"/>
+ <au:assertPropertyEquals name="baz.b" value="$${a}"/>
+ </target>
+
+ <!--
+ Problems with @-sign discussed on the mailinglist.
+ Seems to work.
+ http://mail-archives.apache.org/mod_mbox/ant-user/201412.mbox/%3CCAPxjwW%2BQKFFj45O-ZbCGOnAkJXe9KJ5qKtVQCvS2x7hObRJmkQ%40mail.gmail.com%3E
+ -->
+ <target name="testAtSign">
+ <mkdir dir="${input}"/>
+ <echo file="${input}/x.properties"><![CDATA[
+once=@
+double=@@
+triple=@@@
+]]></echo>
+ <property file="${input}/x.properties"/>
+ <au:assertPropertyEquals name="once" value="@"/>
+ <au:assertPropertyEquals name="double" value="@@"/>
+ <au:assertPropertyEquals name="triple" value="@@@"/>
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/propertyfile-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/propertyfile-test.xml
new file mode 100644
index 00000000..b02cfa4c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/propertyfile-test.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+<project default="antunit" xmlns:au="antlib:org.apache.ant.antunit">
+
+ <import file="../antunit-base.xml" />
+
+ <target name="-fileResourceSetup">
+ <mkdir dir="${output}"/>
+ </target>
+
+ <target name="testInternationalText" depends="-fileResourceSetup"
+ description="https://issues.apache.org/bugzilla/show_bug.cgi?id=50515">
+ <property name="line1" value="č¬ ĺ© éŁź ĺ“ ć‰ą 發 ĺ…¬ 司" />
+ <property name="line2" value="TEL: (123)123-1234" />
+ <propertyfile file="${output}/test.properties">
+ <entry key="line1" value="${line1}" />
+ <entry key="line2" value="${line2}" />
+ </propertyfile>
+ <loadproperties prefix="rereading" srcfile="${output}/test.properties"/>
+ <au:assertTrue message="${line2}">
+ <equals arg1="${line2}" arg2="${rereading.line2}" />
+ </au:assertTrue>
+ <au:assertTrue message="${line1}">
+ <equals arg1="${line1}" arg2="${rereading.line1}" />
+ </au:assertTrue>
+
+ </target>
+
+</project> \ No newline at end of file
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/propertyhelper-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/propertyhelper-test.xml
new file mode 100644
index 00000000..f86342e1
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/propertyhelper-test.xml
@@ -0,0 +1,151 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="antunit" xmlns:au="antlib:org.apache.ant.antunit">
+ <!-- each test verifies that the PropertyEvaluator delegate works -->
+ <import file="../antunit-base.xml" />
+
+ <condition property="prereqs-ok">
+ <and>
+ <available classname="org.apache.bsf.BSFManager"/>
+ <available classname="bsh.util.BeanShellBSFEngine"/>
+ </and>
+ </condition>
+
+ <target name="setUp" unless="setup.complete" if="prereqs-ok">
+ <script language="beanshell" manager="bsf">
+ import org.apache.tools.ant.PropertyHelper;
+ public class MapEvaluator implements PropertyHelper.PropertyEvaluator {
+ HashMap map = new HashMap();
+ public MapEvaluator() {
+ map.put("string", "string");
+ map.put("object", new Object());
+ map.put("int", new Integer(1));
+ map.put("null", null);
+ }
+ public Object evaluate(String property, PropertyHelper propertyHelper) {
+ return map.get(property.toLowerCase());
+ }
+ }
+ project.addReference("mapEvaluator", new MapEvaluator());
+ </script>
+ <propertyhelper>
+ <delegate refid="mapEvaluator" />
+ </propertyhelper>
+ <property name="setup.complete" value="true" />
+ </target>
+
+ <target name="testValueTypes" depends="setUp" if="prereqs-ok">
+ <!-- verify BC, strings -->
+ <au:assertPropertyEquals name="string" value="${STRING}" />
+
+ <!-- verify non-string properties -->
+ <au:assertPropertyEquals name="object" value="${OBJECT}" />
+ <au:assertPropertyEquals name="int" value="${INT}" />
+
+ <!-- verify that a string containing nothing but a property reference is a valid value -->
+ <property name="string2" value="${string}" />
+ <au:assertPropertyEquals name="string2" value="${string}" />
+
+ <property name="object2" value="${object}" />
+ <!-- demonstrate that equals args can be non-string -->
+ <au:assertPropertyEquals name="object2" value="${object}" />
+
+ <property name="int2" value="${int}" />
+ <au:assertPropertyEquals name="int2" value="${int}" />
+ </target>
+
+ <target name="testNull" depends="setUp" if="prereqs-ok">
+ <!-- demonstrate that a null value always implies a nonexistent property -->
+ <au:assertFalse>
+ <isset property="null" />
+ </au:assertFalse>
+ </target>
+
+ <target name="testAvailable" depends="setUp" if="prereqs-ok">
+ <!-- verify the available task can set a non-string property -->
+ <available file="${ant.file}" type="file" property="available.string" value="bc" />
+ <au:assertPropertyEquals name="available.string" value="bc" />
+ <available file="${ant.file}" type="file" property="available.object" value="${object}" />
+ <au:assertPropertyEquals name="available.object" value="${OBJECT}" />
+ </target>
+
+ <target name="testCondition" depends="setUp" if="prereqs-ok">
+ <!-- verify the condition task can set a non-string property -->
+ <echo>$${ant.file}=${ant.file}</echo>
+ <condition property="condition.true.string">
+ <available file="${ant.file}" type="file" />
+ </condition>
+ <au:assertPropertyEquals name="condition.true.string" value="true" />
+ <condition property="condition.else.string" value="true" else="false">
+ <not><available file="${ant.file}" type="file" /></not>
+ </condition>
+ <au:assertPropertyEquals name="condition.else.string" value="false" />
+ <condition property="condition.true.object" value="${object}">
+ <available file="${ant.file}" type="file" />
+ </condition>
+ <au:assertPropertyEquals name="condition.true.object" value="${OBJECT}" />
+ <condition property="condition.else.int" value="${object}" else="${int}">
+ <not><available file="${ant.file}" type="file" /></not>
+ </condition>
+ <au:assertPropertyEquals name="condition.else.int" value="${INT}" />
+ </target>
+
+ <target name="testEmbeddedNonString" if="prereqs-ok">
+ <!-- verify that a property embedded in a string is a substring -->
+ <au:assertTrue>
+ <equals arg1="@${int}@" arg2="@1@" />
+ </au:assertTrue>
+ </target>
+
+ <target name="XtestLoadPropertiesWithObjects" if="prereqs-ok" depends="setUp">
+ <au:assertFalse>
+ <isset property="object2" />
+ </au:assertFalse>
+ <string id="props" value="object2=$${object}" />
+ <!-- verify the property is not yet expanded -->
+ <au:assertTrue>
+ <length length="17">
+ <resource refid="props" />
+ </length>
+ </au:assertTrue>
+ <loadproperties>
+ <resource refid="props" />
+ </loadproperties>
+ <au:assertPropertyEquals name="object2" value="${object}" />
+ <au:assertPropertyEquals name="object2" value="${OBJECT}" />
+ </target>
+
+ <target name="testLoadPropertiesWithStrings" if="prereqs-ok" depends="setUp">
+ <au:assertFalse>
+ <isset property="string2" />
+ </au:assertFalse>
+ <string id="props" value="string2=$${string}" />
+ <!-- verify the property is not yet expanded -->
+ <au:assertTrue>
+ <length length="17">
+ <resource refid="props" />
+ </length>
+ </au:assertTrue>
+ <loadproperties>
+ <resource refid="props" />
+ </loadproperties>
+ <au:assertPropertyEquals name="string2" value="${string}" />
+ <au:assertPropertyEquals name="string2" value="${STRING}" />
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/replace-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/replace-test.xml
new file mode 100644
index 00000000..dd1617a6
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/replace-test.xml
@@ -0,0 +1,103 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="antunit" xmlns:au="antlib:org.apache.ant.antunit">
+ <import file="../antunit-base.xml" />
+
+ <import file="../propertyhelpers.xml" as="ph"/>
+
+ <target name="tearDown" depends="antunit-base.tearDown">
+ <delete dir="foo"/>
+ </target>
+
+ <target name="setUp">
+ <mkdir dir="${output}"/>
+ <echo file="${output}/text.txt"><![CDATA[
+Hello, world!
+]]></echo>
+ </target>
+
+ <target name="testRCSupport" depends="setUp">
+ <replace token="world" value="Ant">
+ <file file="${output}/text.txt"/>
+ </replace>
+ <au:assertResourceContains
+ resource="${output}/text.txt" value="Hello, Ant!"/>
+ </target>
+
+ <target name="testNestedElementsOfFilter" depends="setUp">
+ <replace>
+ <file file="${output}/text.txt"/>
+ <replacefilter>
+ <replacetoken>world</replacetoken>
+ <replacevalue>Ant</replacevalue>
+ </replacefilter>
+ </replace>
+ <au:assertResourceContains
+ resource="${output}/text.txt" value="Hello, Ant!"/>
+ </target>
+
+ <target name="testNoPropertyExpansion" depends="setUp">
+ <property name="ant" value="Ant"/>
+ <replace>
+ <file file="${output}/text.txt"/>
+ <replacetoken>world</replacetoken>
+ <replacevalue>${ant}</replacevalue>
+ </replace>
+ <au:assertResourceDoesntContain
+ resource="${output}/text.txt" value="Hello, Ant!"/>
+ </target>
+
+ <target name="testPropertyExpansion" depends="setUp">
+ <property name="ant" value="Ant"/>
+ <replace>
+ <file file="${output}/text.txt"/>
+ <replacetoken>world</replacetoken>
+ <replacevalue expandproperties="true">${ant}</replacevalue>
+ </replace>
+ <au:assertResourceContains
+ resource="${output}/text.txt" value="Hello, Ant!"/>
+ </target>
+
+ <target name="testNoReplace" depends="setUp">
+ <replace token="ant" value="ant" summary="true">
+ <file file="${output}/text.txt"/>
+ </replace>
+ <au:assertLogContains text="Replaced 0 occurrences in 0 files."/>
+ </target>
+
+ <target name="testFailOnNoReplace" depends="setUp">
+ <au:expectfailure expectedMessage="didn't replace anything">
+ <replace token="ant" value="ant" failOnNoReplacements="true">
+ <file file="${output}/text.txt"/>
+ </replace>
+ </au:expectfailure>
+ </target>
+
+ <target name="testPropertyFilterResource" depends="setUp,ph.defineHelpers">
+ <mkdir dir="foo"/>
+ <echo file="foo/foo.properties"><![CDATA[
+world=Ant
+]]></echo>
+ <replace replacefilterresource="${java:foo!foo.properties}">
+ <file file="${output}/text.txt"/>
+ </replace>
+ <au:assertResourceContains
+ resource="${output}/text.txt" value="Hello, Ant!"/>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/retry-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/retry-test.xml
new file mode 100644
index 00000000..e81853b8
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/retry-test.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="retry-test" default="antunit" xmlns:au="antlib:org.apache.ant.antunit">
+ <import file="../antunit-base.xml"/>
+
+ <target name="setUp">
+ <property name="i" value="3"/>
+ <mkdir dir="${output}"/>
+ <property name="dest" value="${output}/dest"/>
+ </target>
+
+ <target name="test-fail-and-retry" depends="setUp">
+ <!-- just in case this ever becomes a legit url... -->
+ <property name="src" value="http://iojasodjojaosdj"/>
+ <au:expectfailure expectedmessage="Task [get] failed after [${i}] attempts; giving up">
+ <retry retrycount="${i}">
+ <get src="${src}" dest="${dest}"/>
+ </retry>
+ </au:expectfailure>
+ <au:assertLogContains text="Attempt [1]: error occurred; retrying..."/>
+ </target>
+
+ <target name="test-success" depends="setUp">
+ <retry retrycount="${i}">
+ <touch file="${dest}"/>
+ </retry>
+ <au:assertLogDoesntContain text="Attempt [1]: error occurred; retrying..."/>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/rmic-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/rmic-test.xml
new file mode 100644
index 00000000..67b4afc3
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/rmic-test.xml
@@ -0,0 +1,105 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="antunit" xmlns:au="antlib:org.apache.ant.antunit">
+ <import file="../antunit-base.xml" />
+
+ <target name="-create-rmic-adapter">
+ <mkdir dir="${input}/org/example"/>
+ <echo file="${input}/org/example/Adapter.java"><![CDATA[
+package org.example;
+import org.apache.tools.ant.taskdefs.rmic.RmicAdapter;
+import org.apache.tools.ant.taskdefs.Rmic;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.util.FileNameMapper;
+import org.apache.tools.ant.util.GlobPatternMapper;
+
+public class Adapter implements RmicAdapter {
+ public void setRmic(Rmic attributes) {}
+ public boolean execute() {
+ System.err.println("adapter called");
+ return true;
+ }
+ public FileNameMapper getMapper() {
+ GlobPatternMapper m = new GlobPatternMapper();
+ m.setFrom("*.class");
+ m.setTo("*_foo.class");
+ return m;
+ }
+
+ public Path getClasspath() {
+ return new Path(null);
+ }
+}]]></echo>
+ <mkdir dir="${resources}"/>
+ <javac srcdir="${input}" destdir="${resources}"/>
+ </target>
+
+ <target name="testCompilerNotFound" depends="-create-rmic-adapter" unless="build.sysclasspath.only">
+ <au:expectfailure>
+ <rmic base="${resources}" includes="**/*.class"
+ compiler="org.example.Adapter"/>
+ </au:expectfailure>
+ <au:assertLogDoesntContain text="adapter called"/>
+ </target>
+
+ <target name="testCompilerClasspath" depends="-create-rmic-adapter"
+ description="https://issues.apache.org/bugzilla/show_bug.cgi?id=11143">
+ <rmic base="${resources}" includes="**/*.class"
+ compiler="org.example.Adapter">
+ <compilerclasspath location="${resources}"/>
+ </rmic>
+ <au:assertLogContains text="adapter called"/>
+ </target>
+
+ <target name="testCompilerAsNestedElement" depends="-create-rmic-adapter">
+ <componentdef classname="org.example.Adapter" name="myjavac">
+ <classpath location="${resources}"/>
+ </componentdef>
+ <rmic base="${resources}" includes="**/*.class">
+ <myjavac/>
+ </rmic>
+ <au:assertLogContains text="adapter called"/>
+ </target>
+
+ <target name="testSourceBase"
+ description="https://issues.apache.org/bugzilla/show_bug.cgi?id=48970">
+ <mkdir dir="${input}/org/example"/>
+ <mkdir dir="${output}"/>
+ <echo file="${input}/org/example/Foo.java"><![CDATA[
+package org.example;
+import java.rmi.Remote;
+import java.rmi.RemoteException;
+public interface Foo extends Remote {
+ long bar() throws RemoteException ;
+}]]></echo>
+ <echo file="${input}/org/example/FooImpl.java"><![CDATA[
+package org.example;
+import java.rmi.RemoteException;
+public class FooImpl implements Foo {
+ public long bar() throws RemoteException {
+ return 0;
+ }
+}]]></echo>
+ <javac srcdir="${input}" destdir="${output}"/>
+ <rmic sourcebase="${input}" base="${output}">
+ <include name="**/*Impl.class"/>
+ </rmic>
+ <au:assertFileExists file="${input}/org/example/FooImpl_Stub.java"/>
+ <au:assertFileDoesntExist file="${output}/org/example/FooImpl_Stub.java"/>
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/secure-input.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/secure-input.xml
new file mode 100644
index 00000000..8311ce9c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/secure-input.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="test-input" default="antunit" xmlns:au="antlib:org.apache.ant.antunit">
+
+ <import file="../antunit-base.xml" />
+
+ <target name="setUp">
+ </target>
+
+ <target name="test-secure-input" if="jdk1.6+">
+ <input message="secure-input:>" addproperty="the.password">
+ <handler classname="org.apache.tools.ant.input.SecureInputHandler" />
+ </input>
+ <au:assertPropertySet name="the.password" />
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/signjar-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/signjar-test.xml
new file mode 100644
index 00000000..0f03bc58
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/signjar-test.xml
@@ -0,0 +1,272 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="antunit" xmlns:au="antlib:org.apache.ant.antunit">
+
+ <import file="../antunit-base.xml" />
+
+ <property name="classes.dir" value="../../../../build/classes" />
+ <property name="sign.dir" location="${output}" />
+ <property name="subdir" location="${sign.dir}/subdir" />
+ <property name="signtest.jar" location="${sign.dir}/signtest.jar" />
+ <property name="subdirsigntest.jar" location="${subdir}/signtest.jar" />
+ <property name="testkeystore" location="../../../etc/testcases/testkeystore" />
+
+ <macrodef name="assertSigned">
+ <attribute name="jar" default="${signtest.jar}" />
+ <sequential>
+ <au:assertTrue message="not signed: @{jar}">
+ <issigned file="@{jar}" />
+ </au:assertTrue>
+ </sequential>
+ </macrodef>
+
+ <presetdef name="sign-base">
+ <signjar alias="testonly" keystore="${testkeystore}" storepass="apacheant" />
+ </presetdef>
+
+ <presetdef name="verify-base">
+ <verifyjar keystore="${testkeystore}" storepass="apacheant" />
+ </presetdef>
+
+ <presetdef name="sign">
+ <sign-base jar="${signtest.jar}" />
+ </presetdef>
+
+ <target name="setUp">
+ <mkdir dir="${sign.dir}" />
+ <mkdir dir="${subdir}" />
+ </target>
+
+ <target name="jar" depends="setUp">
+ <jar jarfile="${signtest.jar}" basedir="${classes.dir}" includes="**/Task.class" />
+ </target>
+
+ <target name="basic" depends="jar">
+ <sign />
+ </target>
+
+ <target name="testBasic" depends="basic">
+ <assertSigned />
+ </target>
+
+ <target name="testMaxmemory" depends="jar">
+ <sign maxmemory="128m" />
+ <assertSigned />
+ </target>
+
+ <target name="testPreserveLastModified" depends="jar">
+ <touch file="${signtest.jar}" datetime="06/28/2000 2:02 pm" />
+ <sign preservelastmodified="true" />
+ <assertSigned />
+ <fail message="preserveLastModified did not preserve the last modified time">
+ <condition>
+ <not>
+ <isfileselected file="${signtest.jar}">
+ <date datetime="06/28/2000 2:02 pm" when="equal" />
+ </isfileselected>
+ </not>
+ </condition>
+ </fail>
+ </target>
+
+ <target name="testFileset" depends="jar">
+ <sign-base>
+ <fileset file="${signtest.jar}" />
+ </sign-base>
+ <assertSigned />
+ </target>
+
+ <target name="testFilesetAndJar" depends="jar">
+ <sign-base jar="${signtest.jar}" lazy="true">
+ <fileset file="${signtest.jar}" />
+ </sign-base>
+ <assertSigned />
+ </target>
+
+ <target name="testFilesetAndSignedJar" depends="jar">
+ <au:expectfailure expectedMessage="You cannot specify the signed JAR when using paths or filesets">
+ <sign-base signedjar="${sign.dir}/newfile.jar">
+ <fileset file="${signtest.jar}" />
+ </sign-base>
+ </au:expectfailure>
+ </target>
+
+ <target name="testPath" depends="jar">
+ <sign-base>
+ <path>
+ <fileset file="${signtest.jar}" />
+ </path>
+ </sign-base>
+ <assertSigned />
+ </target>
+
+ <target name="testPathAndJar" depends="jar">
+ <sign-base jar="${signtest.jar}" lazy="true">
+ <path>
+ <fileset file="${signtest.jar}" />
+ </path>
+ </sign-base>
+ <assertSigned />
+ </target>
+
+ <target name="testPathAndSignedJar" depends="jar">
+ <au:expectfailure expectedMessage="You cannot specify the signed JAR when using paths or filesets">
+ <sign-base signedjar="${sign.dir}/newfile.jar">
+ <path>
+ <fileset file="${signtest.jar}" />
+ </path>
+ </sign-base>
+ </au:expectfailure>
+ </target>
+
+ <target name="testSignedJar" depends="jar">
+ <sign signedjar="${subdirsigntest.jar}" />
+ <assertSigned jar="${subdirsigntest.jar}" />
+ </target>
+
+ <target name="testDestDirAndSignedJar" depends="jar">
+ <au:expectfailure expectedMessage="'destdir' and 'signedjar' cannot both be set">
+ <sign destDir="${subdir}" signedjar="${sign.dir}/newfile.jar" />
+ </au:expectfailure>
+ </target>
+
+ <target name="testDestDir" depends="jar">
+ <sign destDir="${subdir}" />
+ <assertSigned jar="${subdirsigntest.jar}" />
+ </target>
+
+ <target name="testDestDirFileset" depends="jar">
+ <sign-base destDir="${subdir}">
+ <fileset file="${signtest.jar}" />
+ </sign-base>
+ <assertSigned jar="${subdirsigntest.jar}" />
+ </target>
+
+ <target name="testDestDirPath" depends="jar">
+ <sign-base destDir="${subdir}">
+ <path>
+ <fileset file="${signtest.jar}" />
+ </path>
+ </sign-base>
+ <assertSigned jar="${subdirsigntest.jar}" />
+ </target>
+
+ <target name="testMapperNoDest" depends="jar">
+ <au:expectfailure expectedMessage="The destDir attribute is required if a mapper is set">
+ <sign-base>
+ <flattenmapper />
+ <fileset file="${signtest.jar}" />
+ </sign-base>
+ </au:expectfailure>
+ </target>
+
+ <target name="testMapperFileset" depends="jar">
+ <sign-base destDir="${subdir}">
+ <fileset file="${signtest.jar}" />
+ <flattenmapper />
+ </sign-base>
+ <assertSigned jar="${subdirsigntest.jar}" />
+ </target>
+
+ <target name="testMapperPath" depends="jar">
+ <sign-base destDir="${subdir}">
+ <path>
+ <pathelement location="${signtest.jar}" />
+ </path>
+ <flattenmapper />
+ </sign-base>
+ <assertSigned jar="${subdirsigntest.jar}" />
+ </target>
+
+ <target name="testTwoMappers" depends="jar">
+ <au:expectfailure expectedMessage="Too many mappers">
+ <sign-base destDir="${subdir}">
+ <fileset file="${signtest.jar}" />
+ <flattenmapper />
+ <flattenmapper />
+ </sign-base>
+ </au:expectfailure>
+ </target>
+
+ <target name="testNoAlias" depends="jar">
+ <au:expectfailure expectedMessage="alias attribute must be set">
+ <signjar keystore="${testkeystore}" jar="${signtest.jar}" storepass="apacheant" />
+ </au:expectfailure>
+ </target>
+
+ <target name="testNoFiles">
+ <au:expectfailure expectedMessage="jar must be set through jar attribute">
+ <sign-base />
+ </au:expectfailure>
+ </target>
+
+ <target name="testNoStorePass" depends="jar">
+ <au:expectfailure expectedMessage="storepass attribute must be set">
+ <signjar keystore="${testkeystore}" alias="testonly" jar="${signtest.jar}" />
+ </au:expectfailure>
+ </target>
+
+ <target name="testSysProperty" depends="jar">
+ <sign>
+ <sysproperty key="ant.home" value="${ant.home}" />
+ </sign>
+ <assertSigned />
+ </target>
+
+ <target name="testVerifyJar" depends="basic">
+ <verify-base jar="${signtest.jar}" />
+ </target>
+
+ <target name="testVerifyJarCertificates" depends="basic">
+ <verify-base jar="${signtest.jar}" certificates="true" verbose="true" />
+ </target>
+
+ <target name="testVerifyJarUnsigned" depends="jar">
+ <au:expectfailure expectedMessage="Failed to verify ${signtest.jar}">
+ <verify-base jar="${signtest.jar}" />
+ </au:expectfailure>
+ </target>
+
+ <target name="NOtestVerifyJarNotInKeystore" depends="basic">
+ <au:expectfailure>
+ <verifyjar jar="${signtest.jar}" certificates="true" verbose="true" />
+ </au:expectfailure>
+ </target>
+
+ <target name="testVerifyFileset" depends="basic">
+ <verify-base>
+ <fileset file="${signtest.jar}" />
+ </verify-base>
+ </target>
+
+ <target name="testVerifyPath" depends="basic">
+ <verify-base>
+ <path>
+ <pathelement location="${signtest.jar}" />
+ </path>
+ </verify-base>
+ </target>
+
+ <target name="testVerifyNoArgs">
+ <au:expectfailure expectedMessage="jar must be set through jar attribute">
+ <verify-base />
+ </au:expectfailure>
+ </target>
+
+</project>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/subant-helper/echo.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/subant-helper/echo.xml
new file mode 100644
index 00000000..24f445cc
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/subant-helper/echo.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project xmlns:au="antlib:org.apache.ant.antunit">
+ <au:assertMatches string="${basedir}" pattern=".*subant-helper$"/>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/subant-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/subant-test.xml
new file mode 100644
index 00000000..3bc44059
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/subant-test.xml
@@ -0,0 +1,111 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="antunit" xmlns:au="antlib:org.apache.ant.antunit">
+
+ <description>
+ Test that subant properly sets various properties
+ </description>
+ <import file="../antunit-base.xml" />
+
+ <target name="assertProperties">
+ <au:assertPropertySet name="ant.version" />
+ <au:assertPropertySet name="java.home" />
+ <au:assertPropertySet name="java.class.path" />
+ </target>
+
+ <target name="testAntVersion">
+ <subant inheritall="false" target="assertProperties">
+ <fileset file="${ant.file}" />
+ </subant>
+ </target>
+
+ <!-- four testcases for bug 30542, the last one failed -->
+ <target name="testSubAntDoesntSetBasedir">
+ <subant antfile="echo.xml">
+ <dirset dir="." includes="subant-helper"/>
+ </subant>
+ </target>
+
+ <target name="testSubAntDoesntSetBasedirAfterAntCall">
+ <antcall target="testSubAntDoesntSetBasedir"/>
+ </target>
+
+ <target name="testSubAntDoesntSetBasedirAfterAnt">
+ <ant antfile="${ant.file}" target="testSubAntDoesntSetBasedir"/>
+ </target>
+
+ <target name="testSubAntDoesntSetBasedirAfterAntWithDir">
+ <ant antfile="${ant.file}" dir="${basedir}"
+ target="testSubAntDoesntSetBasedir"/>
+ </target>
+
+ <target name="testSubAntDoesntSetBasedirAfterAntWithDirWhenNativeDir">
+ <ant antfile="${ant.file}" dir="${basedir}"
+ target="testSubAntDoesntSetBasedir"
+ useNativeBaseDir="true"/>
+ </target>
+
+ <target name="testLastPropertyWins">
+ <subant target="checkB">
+ <file file="antcall-test.xml"/>
+ <property name="b" value="1"/>
+ <property name="b" value="2"/>
+ <property name="expected" value="2"/>
+ </subant>
+ </target>
+
+ <target name="makePropertiesFile">
+ <ant antfile="antcall-test.xml" target="makePropertiesFile"/>
+ </target>
+
+ <target name="testPropertiesLoadedFromFile" depends="makePropertiesFile">
+ <subant target="checkB">
+ <file file="antcall-test.xml"/>
+ <property name="expected" value="2"/>
+ <property file="${input}/ant.properties"/>
+ </subant>
+ </target>
+
+ <target name="testFileDoesntSeeExternalProperty" depends="makePropertiesFile">
+ <property name="a" value="x"/>
+ <subant target="checkB">
+ <file file="antcall-test.xml"/>
+ <property name="expected" value="2"/>
+ <property file="${input}/ant.properties"/>
+ </subant>
+ </target>
+
+ <target name="testFileSeesExternalPropertyWhenInheritAll"
+ depends="makePropertiesFile">
+ <property name="a" value="x"/>
+ <subant target="checkB" inheritall="true">
+ <file file="antcall-test.xml"/>
+ <property name="expected" value="x"/>
+ <property file="${input}/ant.properties"/>
+ </subant>
+ </target>
+
+ <target name="testFileSeesInternalProperty" depends="makePropertiesFile">
+ <subant target="checkB">
+ <file file="antcall-test.xml"/>
+ <property name="a" value="y"/>
+ <property name="expected" value="y"/>
+ <property file="${input}/ant.properties"/>
+ </subant>
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/sync-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/sync-test.xml
new file mode 100644
index 00000000..21a14426
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/sync-test.xml
@@ -0,0 +1,175 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="antunit" xmlns:au="antlib:org.apache.ant.antunit">
+ <import file="../antunit-base.xml" />
+
+ <target name="setUp">
+ <mkdir dir="${input}/a"/>
+ <mkdir dir="${input}/d"/>
+ <mkdir dir="${output}/a"/>
+ <mkdir dir="${output}/d"/>
+ <mkdir dir="${output}/b/c"/>
+ <touch file="${input}/a/foo.txt"/>
+ <touch file="${output}/a/bar.txt"/>
+ <touch file="${output}/b/baz.txt"/>
+ </target>
+
+ <target name="testIncludeEmptyPreservesEmptyDirs" depends="setUp">
+
+ <sync todir="${output}" includeemptydirs="true">
+ <fileset dir="${input}"/>
+ <preserveintarget>
+ <include name="**/b/**"/>
+ </preserveintarget>
+ </sync>
+
+ <au:assertFileDoesntExist file="${output}/a/bar.txt"/>
+ <au:assertFileExists file="${output}/a/foo.txt"/>
+ <au:assertFileExists file="${output}/b/baz.txt"/>
+ <au:assertFileExists file="${output}/b/c"/>
+ <au:assertFileExists file="${output}/d"/>
+ </target>
+
+ <target name="testDefaultDoesntPreserveEmptyDirs" depends="setUp">
+
+ <sync todir="${output}">
+ <fileset dir="${input}"/>
+ <preserveintarget>
+ <include name="**/b/**"/>
+ </preserveintarget>
+ </sync>
+
+ <au:assertFileDoesntExist file="${output}/a/bar.txt"/>
+ <au:assertFileExists file="${output}/a/foo.txt"/>
+ <au:assertFileExists file="${output}/b/baz.txt"/>
+ <au:assertFileDoesntExist file="${output}/b/c"/>
+ <au:assertFileDoesntExist file="${output}/d"/>
+ </target>
+
+ <target name="testPreserveEmptyOverridesDefault" depends="setUp">
+
+ <sync todir="${output}">
+ <fileset dir="${input}"/>
+ <preserveintarget preserveEmptyDirs="true">
+ <include name="**/b/**"/>
+ </preserveintarget>
+ </sync>
+
+ <au:assertFileDoesntExist file="${output}/a/bar.txt"/>
+ <au:assertFileExists file="${output}/a/foo.txt"/>
+ <au:assertFileExists file="${output}/b/baz.txt"/>
+ <au:assertFileExists file="${output}/b/c"/>
+ <au:assertFileDoesntExist file="${output}/d"/>
+ </target>
+
+ <target name="testPreserveEmptyOverrulesIncludeEmpty" depends="setUp">
+
+ <sync todir="${output}" includeEmptyDirs="true">
+ <fileset dir="${input}"/>
+ <preserveintarget preserveEmptyDirs="false">
+ <include name="**/b/**"/>
+ </preserveintarget>
+ </sync>
+
+ <au:assertFileDoesntExist file="${output}/a/bar.txt"/>
+ <au:assertFileExists file="${output}/a/foo.txt"/>
+ <au:assertFileExists file="${output}/b/baz.txt"/>
+ <au:assertFileDoesntExist file="${output}/b/c"/>
+ <au:assertFileExists file="${output}/d"/>
+ </target>
+
+ <target name="testPreserveEmptyAndIncludeEmptyFalse" depends="setUp">
+
+ <sync todir="${output}" includeEmptyDirs="false">
+ <fileset dir="${input}"/>
+ <preserveintarget preserveEmptyDirs="false">
+ <include name="**/b/**"/>
+ </preserveintarget>
+ </sync>
+
+ <au:assertFileDoesntExist file="${output}/a/bar.txt"/>
+ <au:assertFileExists file="${output}/a/foo.txt"/>
+ <au:assertFileExists file="${output}/b/baz.txt"/>
+ <au:assertFileDoesntExist file="${output}/b/c"/>
+ <au:assertFileDoesntExist file="${output}/d"/>
+ </target>
+
+ <target name="testPreserveEmptyAndIncludeEmptyTrue" depends="setUp">
+
+ <sync todir="${output}" includeEmptyDirs="true">
+ <fileset dir="${input}"/>
+ <preserveintarget preserveEmptyDirs="true">
+ <include name="**/b/**"/>
+ </preserveintarget>
+ </sync>
+
+ <au:assertFileDoesntExist file="${output}/a/bar.txt"/>
+ <au:assertFileExists file="${output}/a/foo.txt"/>
+ <au:assertFileExists file="${output}/b/baz.txt"/>
+ <au:assertFileExists file="${output}/b/c"/>
+ <au:assertFileExists file="${output}/d"/>
+ </target>
+
+ <target name="testPreserveEmptyDirsWithNonRecursiveExclude" depends="setUp">
+
+ <sync todir="${output}">
+ <fileset dir="${input}"/>
+ <preserveintarget preserveEmptyDirs="true">
+ <include name="**/b"/>
+ </preserveintarget>
+ </sync>
+
+ <au:assertFileDoesntExist file="${output}/a/bar.txt"/>
+ <au:assertFileExists file="${output}/a/foo.txt"/>
+ <au:assertFileExists file="${output}/b"/>
+ <au:assertFileDoesntExist file="${output}/b/baz.txt"/>
+ <au:assertFileDoesntExist file="${output}/b/c"/>
+ <au:assertFileDoesntExist file="${output}/d"/>
+ </target>
+
+ <!-- really only tests no exception is thrown -->
+ <target name="testCanAddMultipleResources" depends="setUp"
+ description="https://issues.apache.org/bugzilla/show_bug.cgi?id=51462">
+ <sync todir="${output}">
+ <file file="${input}/x"/>
+ <file file="${input}/y"/>
+ </sync>
+ </target>
+
+ <target name="testSyncWithResources" depends="setUp"
+ description="https://issues.apache.org/bugzilla/show_bug.cgi?id=51462">
+ <sync todir="${output}">
+ <mappedresources>
+ <fileset dir="${input}"/>
+ <globmapper from="*" to="test/*"/>
+ </mappedresources>
+ </sync>
+ <au:assertFileDoesntExist file="${output}/bar.txt"/>
+ <au:assertFileExists file="${output}/test/a/foo.txt"/>
+
+ <sync todir="${output}">
+ <mappedresources>
+ <fileset dir="${input}"/>
+ <globmapper from="*" to="test/*"/>
+ </mappedresources>
+ </sync>
+ <au:assertFileDoesntExist file="${output}/bar.txt"/>
+ <au:assertFileExists file="${output}/test/a/foo.txt"/>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/tar-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/tar-test.xml
new file mode 100644
index 00000000..1aac9a8d
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/tar-test.xml
@@ -0,0 +1,118 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<project name="tar-test" default="antunit"
+ xmlns:cond="antlib:org.apache.tools.ant.types.conditions"
+ xmlns:au="antlib:org.apache.ant.antunit">
+ <import file="../antunit-base.xml" />
+
+ <target name="setUp">
+ <mkdir dir="${input}" />
+ <mkdir dir="${output}" />
+ </target>
+
+ <target name="testTarFilesetHandlesFilesetReferences" depends="setUp">
+ <fileset id="xml.fileset" dir="." includes="*.xml" />
+ <tar destfile="${output}/testtar.tar">
+ <tarfileset prefix="pre" refid="xml.fileset" />
+ </tar>
+ </target>
+
+ <target name="testRemoveLeadingSlashes" depends="setUp">
+ <tar destfile="${output}/testtar.tar">
+ <tarfileset file="${ant.file}" fullpath="/foo.xml"/>
+ </tar>
+ <au:assertTrue>
+ <cond:resourceexists>
+ <tarentry name="foo.xml">
+ <file file="${output}/testtar.tar"/>
+ </tarentry>
+ </cond:resourceexists>
+ </au:assertTrue>
+ <au:assertFalse>
+ <cond:resourceexists>
+ <tarentry name="/foo.xml">
+ <file file="${output}/testtar.tar"/>
+ </tarentry>
+ </cond:resourceexists>
+ </au:assertFalse>
+ </target>
+
+ <target name="testPreserveLeadingSlashes" depends="setUp">
+ <tar destfile="${output}/testtar.tar">
+ <tarfileset file="${ant.file}" fullpath="/foo.xml"
+ preserveleadingslashes="true"/>
+ </tar>
+ <au:assertTrue>
+ <cond:resourceexists>
+ <tarentry name="/foo.xml">
+ <file file="${output}/testtar.tar"/>
+ </tarentry>
+ </cond:resourceexists>
+ </au:assertTrue>
+ <au:assertFalse>
+ <cond:resourceexists>
+ <tarentry name="foo.xml">
+ <file file="${output}/testtar.tar"/>
+ </tarentry>
+ </cond:resourceexists>
+ </au:assertFalse>
+ </target>
+
+ <target name="testSingleFile" depends="setUp"
+ description="https://issues.apache.org/bugzilla/show_bug.cgi?id=48035">
+ <touch file="${input}/foo.txt"/>
+ <tar destfile="${output}/foo.tar">
+ <file file="${input}/foo.txt"/>
+ </tar>
+ <au:assertFileExists file="${output}/foo.tar"/>
+ <copy file="${output}/foo.tar" tofile="${output}/bar.tar"
+ preservelastmodified="true"/>
+ <sleep seconds="2"/>
+ <touch file="${input}/foo.txt"/>
+ <tar destfile="${output}/foo.tar">
+ <file file="${input}/foo.txt"/>
+ </tar>
+ <au:assertDestIsOutofdate src="${output}/foo.tar" dest="${output}/bar.tar"/>
+ </target>
+
+ <target name="-longfileSetup" depends="setUp">
+ <property name="longfile.dir.name"
+ value="this/path/name/contains/more/than/one/hundred/characters/in/order/to/test/the/GNU/and/POSIX/long/file/name/capability/round"/>
+ <property name="longfile.file.name"
+ value="${longfile.dir.name}/tripped"/>
+ <mkdir dir="${input}/${longfile.dir.name}"/>
+ <touch file="${input}/${longfile.file.name}"/>
+ </target>
+
+ <target name="testLongfileGNU" depends="-longfileSetup">
+ <tar destfile="${output}/x.tar" longfile="gnu">
+ <fileset dir="${input}"/>
+ </tar>
+ <untar dest="${output}" src="${output}/x.tar"/>
+ <au:assertFileExists file="${output}/${longfile.file.name}"/>
+ </target>
+
+ <target name="testLongfilePOSIX" depends="-longfileSetup">
+ <tar destfile="${output}/x.tar" longfile="posix">
+ <fileset dir="${input}"/>
+ </tar>
+ <untar dest="${output}" src="${output}/x.tar"/>
+ <au:assertFileExists file="${output}/${longfile.file.name}"/>
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/taskdef-antlib-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/taskdef-antlib-test.xml
new file mode 100644
index 00000000..58d01f06
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/taskdef-antlib-test.xml
@@ -0,0 +1,64 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="antunit" xmlns:au="antlib:org.apache.ant.antunit">
+ <import file="../antunit-base.xml" />
+
+ <!-- Java5 has some trouble with the recursive Antlib lookup -->
+
+ <target name="setUp" if="jdk1.6+">
+ <mkdir dir="${input}/org/example" />
+ <property name="tmpdir" location="../../../../build/ant-unit/taskdef" />
+ <mkdir dir="${tmpdir}" />
+ <echo file="${input}/org/example/antlib.xml">
+ <![CDATA[<antlib xmlns:e="ant:current">
+ <macrodef name="echoo" backtrace="false">
+ <attribute name="message" />
+ <sequential>
+ <echo message="@{message}@{message}" />
+ </sequential>
+ </macrodef>
+ <macrodef name="echoooo" backtrace="false">
+ <attribute name="message" />
+ <sequential>
+ <e:echoo message="@{message}@{message}" />
+ </sequential>
+ </macrodef>
+ </antlib>]]>
+ </echo>
+ <jar destfile="${test.jar}">
+ <fileset dir="${input}" />
+ </jar>
+ <sleep seconds="1"/>
+ </target>
+
+ <target name="testAntlib" depends="setUp" if="jdk1.6+">
+ <taskdef classpath="${test.jar}" uri="antlib:org.example"
+ loaderref="loader1"/>
+ <echoooo xmlns="antlib:org.example" message="exemple" />
+ <au:assertLogContains text="exempleexempleexempleexemple" />
+ </target>
+
+ <target name="testURI" depends="setUp" if="jdk1.6+">
+ <taskdef classpath="${test.jar}" uri="urn:my:exemple"
+ loaderref="loader2"
+ resource="org/example/antlib.xml" />
+ <echoooo xmlns="urn:my:exemple" message="exemple" />
+ <au:assertLogContains text="exempleexempleexempleexemple" />
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/taskdef-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/taskdef-test.xml
new file mode 100644
index 00000000..95745082
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/taskdef-test.xml
@@ -0,0 +1,99 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="antunit" xmlns:au="antlib:org.apache.ant.antunit">
+ <import file="../antunit-base.xml" />
+
+ <target name="setUp">
+ <mkdir dir="${input}/org/example"/>
+ <property name="tmpdir" location="../../../../build/ant-unit/taskdef"/>
+ <mkdir dir="${tmpdir}"/>
+ <echoxml file="${input}/org/example/antlib.xml">
+ <antlib>
+ <taskdef name="echooo"
+ classname="org.apache.tools.ant.taskdefs.Echo"/>
+ </antlib>
+ </echoxml>
+ </target>
+
+ <target name="testPlainDir" depends="setUp">
+ <jar destfile="${test1.jar}">
+ <fileset dir="${input}"/>
+ </jar>
+ <taskdef resource="org/example/antlib.xml"
+ classpath="${test1.jar}"
+ uri="urn:test:plain"/>
+ <echooo xmlns="urn:test:plain">Hello</echooo>
+ <au:assertLogContains text="Hello"/>
+ </target>
+
+ <target name="testDirWithPling" depends="setUp" if="jdk1.6+"
+ description="https://issues.apache.org/bugzilla/show_bug.cgi?id=50007">
+ <property name="dir" location="${tmpdir}/pl!ng"/>
+ <mkdir dir="${dir}"/>
+ <jar destfile="${test2.jar}">
+ <fileset dir="${input}"/>
+ </jar>
+ <taskdef resource="org/example/antlib.xml"
+ classpath="${test2.jar}"
+ uri="urn:test:indir"/>
+ <echooo xmlns="urn:test:indir">Hello</echooo>
+ <au:assertLogContains text="Hello"/>
+ </target>
+
+ <!-- fails because URLConnection.connect() fails on the JAR URL returned
+ by ClassLoader.getResources() -->
+ <target name="NOtestDirWithPlingAtEnd" depends="setUp"
+ description="https://issues.apache.org/bugzilla/show_bug.cgi?id=50007">
+ <property name="dir" location="${tmpdir}/pling!"/>
+ <mkdir dir="${dir}"/>
+ <jar destfile="${test3.jar}">
+ <fileset dir="${input}"/>
+ </jar>
+ <taskdef resource="org/example/antlib.xml"
+ classpath="${test3.jar}"
+ uri="urn:test:atend"/>
+ <echooo xmlns="urn:test:atend">Hello</echooo>
+ <au:assertLogContains text="Hello"/>
+ </target>
+
+ <target name="testPlingInJar" depends="setUp">
+ <move file="${input}/org/example/antlib.xml"
+ tofile="${input}/org/examp!e/antlib.xml"/>
+ <jar destfile="${test4.jar}">
+ <fileset dir="${input}"/>
+ </jar>
+ <taskdef resource="org/examp!e/antlib.xml"
+ classpath="${test4.jar}"
+ uri="urn:test:injar"/>
+ <echooo xmlns="urn:test:injar">Hello</echooo>
+ <au:assertLogContains text="Hello"/>
+ </target>
+
+ <target name="testPlingInJarAtEnd" depends="setUp">
+ <move file="${input}/org/example/antlib.xml"
+ tofile="${input}/org/example!/antlib.xml"/>
+ <jar destfile="${test5.jar}">
+ <fileset dir="${input}"/>
+ </jar>
+ <taskdef resource="org/example!/antlib.xml"
+ classpath="${test5.jar}"
+ uri="urn:test:injaratend"/>
+ <echooo xmlns="urn:test:injaratend">Hello</echooo>
+ <au:assertLogContains text="Hello"/>
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/tempfile-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/tempfile-test.xml
new file mode 100644
index 00000000..1132007a
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/tempfile-test.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="antunit" xmlns:au="antlib:org.apache.ant.antunit">
+ <import file="../antunit-base.xml" />
+
+ <target name="tearDown" depends="antunit-base.tearDown">
+ <delete file="${tmp}" quiet="true"/>
+ </target>
+
+ <target name="testCreateWithoutPrefix"
+ description="https://issues.apache.org/bugzilla/show_bug.cgi?id=49755">
+ <tempfile property="tmp" createfile="true"/>
+ <au:assertFileExists file="${tmp}"/>
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/touch-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/touch-test.xml
new file mode 100644
index 00000000..a9327ed8
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/touch-test.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="touch-test" default="antunit" xmlns:au="antlib:org.apache.ant.antunit">
+ <import file="../antunit-base.xml"/>
+
+ <target name="test-no-child">
+ <au:expectfailure>
+ <touch />
+ </au:expectfailure>
+ </target>
+
+ <target name="test-no-match">
+ <touch>
+ <fileset file="${ant.file}">
+ <filename name="IDONOTMATCH" />
+ </fileset>
+ </touch>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/truncate/truncate-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/truncate/truncate-test.xml
new file mode 100644
index 00000000..86f896c6
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/truncate/truncate-test.xml
@@ -0,0 +1,145 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="truncate-test" default="default"
+ xmlns:au="antlib:org.apache.ant.antunit">
+
+ <target name="default">
+ <au:antunit>
+ <file file="${ant.file}" />
+ </au:antunit>
+ </target>
+
+ <target name="tearDown">
+ <delete file="foo" />
+ <delete file="bar" />
+ <delete dir="baz" />
+ </target>
+
+ <target name="test-basic">
+ <truncate file="foo" />
+ <au:assertTrue>
+ <length file="foo" length="0" />
+ </au:assertTrue>
+ </target>
+
+ <target name="test-explicit">
+ <truncate file="foo" length="1034" />
+ <au:assertTrue>
+ <length file="foo" length="1034" />
+ </au:assertTrue>
+ </target>
+
+ <target name="test-extend">
+ <truncate file="foo" length="5" />
+ <au:assertTrue>
+ <length file="foo" length="5" />
+ </au:assertTrue>
+ <truncate file="foo" adjust="5" />
+ <au:assertTrue>
+ <length file="foo" length="10" />
+ </au:assertTrue>
+ </target>
+
+ <target name="test-truncate">
+ <truncate file="foo" length="5" />
+ <au:assertTrue>
+ <length file="foo" length="5" />
+ </au:assertTrue>
+ <truncate file="foo" adjust="-5" />
+ <au:assertTrue>
+ <length file="foo" length="0" />
+ </au:assertTrue>
+ </target>
+
+ <target name="test-bigger">
+ <truncate file="foo" length="1K" />
+ <au:assertTrue>
+ <and>
+ <length file="foo" length="1K" />
+ <length file="foo" length="1024" />
+ </and>
+ </au:assertTrue>
+ </target>
+
+ <target name="truncate-bigger">
+ <truncate file="foo" length="3K" />
+ <au:assertTrue>
+ <length file="foo" length="3K" />
+ </au:assertTrue>
+ <truncate file="foo" adjust="-2K" />
+ <au:assertTrue>
+ <length file="foo" length="1K" />
+ </au:assertTrue>
+ </target>
+
+ <target name="test-no-create">
+ <au:assertFileDoesntExist file="foo" />
+ <truncate file="foo" create="false" length="0" />
+ <au:assertFileDoesntExist file="foo" />
+ </target>
+
+ <target name="test-mkdirs">
+ <au:assertFileDoesntExist file="baz" />
+ <truncate file="baz/foo" mkdirs="true" length="0" />
+ <au:assertTrue>
+ <length file="baz/foo" length="0" />
+ </au:assertTrue>
+ </target>
+
+ <target name="test-rc">
+ <truncate length="10">
+ <resources>
+ <file file="foo" />
+ <file file="bar" />
+ </resources>
+ </truncate>
+ <au:assertTrue>
+ <and>
+ <length file="foo" length="10" />
+ <length file="bar" length="10" />
+ </and>
+ </au:assertTrue>
+ </target>
+
+ <target name="test-bad-resource">
+ <au:expectfailure>
+ <truncate length="1P">
+ <string value="blah" />
+ </truncate>
+ </au:expectfailure>
+ </target>
+
+ <target name="test-invalid-attrs">
+ <au:expectfailure>
+ <truncate file="foo" length="0" adjust="0" />
+ </au:expectfailure>
+ </target>
+
+ <target name="test-bad-length">
+ <au:expectfailure>
+ <truncate file="foo" length="-1P" />
+ </au:expectfailure>
+ </target>
+
+ <target name="test-no-files">
+ <au:expectfailure>
+ <truncate length="0" />
+ </au:expectfailure>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/unzip-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/unzip-test.xml
new file mode 100644
index 00000000..b2c2105d
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/unzip-test.xml
@@ -0,0 +1,70 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<project name="unzip-test" default="antunit"
+ xmlns:au="antlib:org.apache.ant.antunit">
+ <import file="../antunit-base.xml" />
+
+ <target name="setUp">
+ <mkdir dir="${output}" />
+ </target>
+
+ <target name="testFailureOnBrokenCentralDirectoryStructure">
+ <au:expectfailure
+ expectedmessage="central directory is empty, can't expand corrupt archive.">
+ <unzip src="broken_cd.zip" dest="${output}"/>
+ </au:expectfailure>
+ </target>
+
+ <!-- Issue 28911 -->
+ <target name="testStrippingOfPathsep">
+ <mkdir dir="${input}"/>
+ <mkdir dir="${output}"/>
+ <touch file="${input}/file"/>
+ <zip destfile="${output}/a.zip">
+ <zipfileset dir="${input}" prefix="/foo"/>
+ </zip>
+ <unzip src="${output}/a.zip" stripAbsolutePathSpec="true"
+ dest="${output}"/>
+ <au:assertFileExists file="${output}/foo/file"/>
+ </target>
+
+ <target name="testTwoByteExtraFieldInLFH"
+ description="https://issues.apache.org/bugzilla/show_bug.cgi?id=42940"
+ >
+ <mkdir dir="${input}"/>
+ <mkdir dir="${output}"/>
+ <copy file="zip/Bugzilla-42940.zip" tofile="${input}/test.zip"/>
+ <unzip src="${input}/test.zip" dest="${output}"/>
+ <au:assertFileExists file="${output}/META-INF/MANIFEST.MF"/>
+ </target>
+
+ <target name="testArchiveIsClosedForInvalidZips"
+ description="https://issues.apache.org/bugzilla/show_bug.cgi?id=46559"
+ >
+ <mkdir dir="${input}"/>
+ <mkdir dir="${output}"/>
+ <copy file="broken_cd.zip" tofile="${input}/test.zip"/>
+ <au:expectfailure>
+ <unzip src="${input}/test.zip" dest="${output}"/>
+ </au:expectfailure>
+ <delete file="${input}/test.zip" quiet="true"/>
+ <!-- failed on Windows and other OSes with implicit file locking -->
+ <au:assertFileDoesntExist file="${input}/test.zip"/>
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/uptodate-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/uptodate-test.xml
new file mode 100644
index 00000000..e477803e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/uptodate-test.xml
@@ -0,0 +1,86 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="antunit" xmlns:au="antlib:org.apache.ant.antunit">
+ <import file="../antunit-base.xml" />
+
+ <target name="testModifiedDirectories"
+ description="https://issues.apache.org/bugzilla/show_bug.cgi?id=39122
+ and
+ https://issues.apache.org/bugzilla/show_bug.cgi?id=44430">
+ <mkdir dir="${input}/source"/>
+ <mkdir dir="${output}"/>
+ <sleep seconds="2"/>
+ <touch file="${input}/source/file"/>
+ <au:assertFalse>
+ <uptodate>
+ <srcresources>
+ <fileset dir="${input}"/>
+ <dirset dir="${input}"/>
+ </srcresources>
+ <globmapper from="*" to="${output}/*"/>
+ </uptodate>
+ </au:assertFalse>
+ <mkdir dir="${output}/source"/>
+ <touch file="${output}/source/file"/>
+ <au:assertTrue>
+ <uptodate targetfile="${output}">
+ <srcresources>
+ <fileset dir="${input}"/>
+ <dirset dir="${input}"/>
+ </srcresources>
+ <globmapper from="*" to="${output}/*"/>
+ </uptodate>
+ </au:assertTrue>
+ <sleep seconds="2"/>
+ <touch>
+ <file file="${input}/source"/>
+ </touch>
+ <au:assertFalse>
+ <uptodate targetfile="${output}">
+ <srcresources>
+ <fileset dir="${input}"/>
+ <dirset dir="${input}"/>
+ </srcresources>
+ <globmapper from="*" to="${output}/*"/>
+ </uptodate>
+ </au:assertFalse>
+ <touch>
+ <file file="${output}/source"/>
+ </touch>
+ <au:assertTrue>
+ <uptodate targetfile="${output}">
+ <srcresources>
+ <fileset dir="${input}"/>
+ <dirset dir="${input}"/>
+ </srcresources>
+ <globmapper from="*" to="${output}/*"/>
+ </uptodate>
+ </au:assertTrue>
+ <sleep seconds="2"/>
+ <delete file="${input}/source/file"/>
+ <au:assertFalse>
+ <uptodate targetfile="${output}">
+ <srcresources>
+ <fileset dir="${input}"/>
+ <dirset dir="${input}"/>
+ </srcresources>
+ <globmapper from="*" to="${output}/*"/>
+ </uptodate>
+ </au:assertFalse>
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/utf-16.expected b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/utf-16.expected
new file mode 100644
index 00000000..7c7c2a78
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/utf-16.expected
Binary files differ
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/utf-16.expected.windows b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/utf-16.expected.windows
new file mode 100644
index 00000000..1e138e81
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/utf-16.expected.windows
Binary files differ
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/war-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/war-test.xml
new file mode 100644
index 00000000..e264ebda
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/war-test.xml
@@ -0,0 +1,194 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<project name="war-test" default="antunit"
+ xmlns:au="antlib:org.apache.ant.antunit">
+
+ <import file="../antunit-base.xml" />
+
+ <target name="setUp">
+ <mkdir dir="${input}"/>
+ <property name="warfile" location="${input}/test.war"/>
+ <property name="web.xml" location="web.xml"/>
+ <property name="webxml.generated" location="${input}/WEB-INF/web.xml"/>
+
+ <!--failing on duplicates is half our testing-->
+ <presetdef name="mkwar">
+ <war destfile="${warfile}" duplicate="fail"/>
+ </presetdef>
+ <presetdef name="expandwar">
+ <unzip src="${input}/test.war" dest="${input}"/>
+ </presetdef>
+ </target>
+
+ <!--test that you can patch a fileset reference into a lib element-->
+ <target name="testlibrefs" depends="setUp">
+ <mkwar webxml="${web.xml}">
+ <fileset id="test" dir="." includes="web.xml"/>
+ <lib refid="test"/>
+ </mkwar>
+ <expandwar/>
+ <au:assertFileExists file="${webxml.generated}" />
+ </target>
+
+ <!--
+ This checks that as of Java EE 5, the web.xml attr is optional.
+ Here there is a web.xml, in the webinf fileset, rather than a fileset
+ -->
+ <target name="testWebXmlInWebinf" depends="setUp">
+ <mkwar>
+ <webinf dir="." includes="web.xml"/>
+ </mkwar>
+ <expandwar/>
+ <au:assertFileExists file="${webxml.generated}" />
+ </target>
+
+ <target name="testWebXmlMissingFromUpdate" depends="setUp">
+ <mkwar webxml="${web.xml}" />
+ <!-- there is no web.xml file, but that is ok, as
+ we are updating -->
+ <mkwar update="true">
+ <classes dir="." includes="web.xml"/>
+ </mkwar>
+ <expandwar/>
+ <au:assertFileExists file="${webxml.generated}" />
+ </target>
+
+ <target name="testWebXmlInImplicitUpdate" depends="setUp">
+ <mkwar webxml="${web.xml}" />
+ <!-- when we are implicitly updating, the web.xml file does not get
+ pulled in, but the command still succeeds.-->
+ <mkwar webxml="${web.xml}" >
+ <classes dir="." includes="web.xml"/>
+ </mkwar>
+ <expandwar/>
+ <au:assertFileExists file="${webxml.generated}" />
+ </target>
+
+ <target name="NotestWebXmlFilesetInImplicitUpdate" depends="setUp">
+ <mkwar webxml="${web.xml}" />
+ <!-- when we are implicitly updating, the web.xml file does not get
+ pulled in, but the command still succeeds.-->
+ <mkwar >
+ <webinf dir="." includes="web.xml"/>
+ </mkwar>
+ <expandwar/>
+ <au:assertFileExists file="${webxml.generated}" />
+ </target>
+
+
+ <target name="testDuplicateWebXml" depends="setUp">
+ <mkwar webxml="${web.xml}" >
+ <webinf dir="." includes="web.xml"/>
+ <webinf file="${web.xml}"/>
+ <zipfileset file="${web.xml}" prefix="WEB-INF"/>
+ </mkwar>
+ <expandwar/>
+ <au:assertFileExists file="${webxml.generated}" />
+ </target>
+
+ <target name="testDifferentDuplicateWebXml" depends="setUp">
+ <copy file="${web.xml}" todir="${input}" />
+ <mkwar webxml="${web.xml}" >
+ <webinf dir="${input}" includes="web.xml"/>
+ <webinf file="${web.xml}"/>
+ <zipfileset file="${web.xml}" prefix="WEB-INF"/>
+ </mkwar>
+ <expandwar/>
+ <au:assertFileExists file="${webxml.generated}" />
+ <au:assertLogContains text="The duplicate entry is"/>
+ </target>
+
+
+ <!--
+ this target does not have a web.xml file.
+ Instead it pulls in
+ -->
+ <target name="testWebXmlOptional" depends="setUp">
+ <mkwar needxmlfile="false">
+ <classes dir="." includes="web.xml"/>
+ </mkwar>
+ <expandwar/>
+ <au:assertFileExists file="${input}/WEB-INF/classes/web.xml" />
+ <au:assertFalse>
+ <available file="${webxml.generated}" />
+ </au:assertFalse>
+ </target>
+
+ <target name="testWebXmlOptionalFailure" depends="setUp">
+ <au:expectfailure>
+ <mkwar >
+ <classes dir="." includes="web.xml"/>
+ </mkwar>
+ </au:expectfailure>
+ </target>
+
+ <target name="testWebXmlOptionalFailure2" depends="setUp">
+ <au:expectfailure>
+ <mkwar needxmlfile="true">
+ <classes dir="." includes="web.xml"/>
+ </mkwar>
+ </au:expectfailure>
+ </target>
+
+ <target name="testClassesElement" depends="setUp">
+ <mkwar needxmlfile="false">
+ <classes dir="." includes="web.xml"/>
+ </mkwar>
+ <expandwar/>
+ <au:assertFileExists file="${input}/WEB-INF/classes/web.xml" />
+ </target>
+
+ <target name="testLibElement" depends="setUp">
+ <mkwar needxmlfile="false">
+ <lib dir="." includes="web.xml"/>
+ </mkwar>
+ <expandwar/>
+ <au:assertFileExists file="${input}/WEB-INF/lib/web.xml" />
+ </target>
+
+ <target name="testMappedClasspathFromManual">
+ <mkdir dir="${input}"/>
+ <mkdir dir="${output}/out"/>
+ <war destfile="${output}/test.war" webxml="${ant.file}">
+ <mappedresources>
+ <restrict>
+ <path path="${java.class.path}"/>
+ <type type="file"/>
+ </restrict>
+ <chainedmapper>
+ <flattenmapper/>
+ <globmapper from="*" to="WEB-INF/lib/*"/>
+ </chainedmapper>
+ </mappedresources>
+ </war>
+ <unzip src="${output}/test.war" dest="${output}/out"/>
+ <au:assertFileExists file="${output}/out/WEB-INF/lib/ant.jar"/>
+ </target>
+
+ <target name="testOnlyOneWebXml">
+ <mkdir dir="${input}/WEB-INF"/>
+ <mkdir dir="${output}"/>
+ <touch file="${input}/WEB-INF/web.xml"/>
+ <touch file="${input}/x.xml"/>
+ <war destfile="${output}/test.war" webxml="${input}/x.xml">
+ <fileset dir="${input}"/>
+ </war>
+ <au:assertLogContains text="Warning: selected war files include a second WEB-INF/web.xml which will be ignored."/>
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/web.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/web.xml
new file mode 100644
index 00000000..414625ae
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/web.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<web-app xmlns="http://java.sun.com/xml/ns/javaee"
+ version="2.5" metadata-complete="true">
+
+</web-app>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/whichresource-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/whichresource-test.xml
new file mode 100644
index 00000000..6bf5a881
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/whichresource-test.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="antunit" xmlns:au="antlib:org.apache.ant.antunit">
+ <import file="../antunit-base.xml" />
+
+ <target name="init">
+ <delete quiet="yes" dir="${output}"/>
+ <mkdir dir="${output}"/>
+ <javac srcdir="javac-dir/good-src" destdir="${output}"/>
+ <path id="whichresource-build" path="${output}"/>
+ </target>
+
+ <target name="test-reference" depends="init">
+ <whichresource
+ property="whichresource.prop"
+ class="Simple"
+ classpathref="whichresource-build"/>
+
+ <au:assertTrue>
+ <contains string="${whichresource.prop}"
+ substring="Simple.class"/>
+ </au:assertTrue>
+ </target>
+
+ <target name="test-not-present" depends="init">
+ <whichresource
+ property="whichresource2.prop"
+ class="ClassNotPresent"
+ classpathref="whichresource-build"/>
+
+ <au:assertFalse>
+ <isset property="whichresource.prop2"/>
+ </au:assertFalse>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/xmlproperty-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/xmlproperty-test.xml
new file mode 100644
index 00000000..5be04207
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/xmlproperty-test.xml
@@ -0,0 +1,144 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="antunit" xmlns:au="antlib:org.apache.ant.antunit">
+ <description/>
+
+ <import file="../antunit-base.xml" />
+
+ <target name="test-empty">
+ <xmlproperty file="xmlproperty-test.xml"/>
+ <au:assertTrue>
+ <equals arg1="" arg2="${project.description}"/>
+ </au:assertTrue>
+ </target>
+
+ <target name="test-multi">
+ <property name="root.element.value" value="original"/>
+ <xmlproperty file="xmlproperty.multi.xml" collapseAttributes="yes"/>
+ <au:assertTrue>
+ <equals arg1="original" arg2="${root.element.value}"/>
+ </au:assertTrue>
+ </target>
+
+ <target name="load">
+ <xmlproperty
+ file="xmlproperty.inline-expansion.xml"
+ collapseAttributes="true"
+ keepRoot="false"
+ semanticAttributes="true"/>
+ <echo>
+ element expected actual
+ p $${app.n} ${app.p}
+ n n ${app.n}
+ o n ${app.o}
+ m n ${app.m}
+ </echo>
+ </target>
+
+ <target name="NotestInlineExpansion" depends="load">
+ <au:assertPropertyEquals name="app.m" value="n"/>
+ <au:assertPropertyEquals name="app.n" value="n"/>
+ <au:assertPropertyEquals name="app.o" value="n"/>
+ <au:assertPropertyEquals name="app.p" value="$${app.n}"/>
+ <property name="sequence" value="${app.m}${app.n}${app.o}${app.p}"/>
+ <fail>
+ xml attributes are not expanding correctly
+ expected: mnop=nnn$${app.n}
+ actual mnop=${sequence}
+ <condition>
+ <not>
+ <equals arg1="${sequence}" arg2="nnn${app.n}"/>
+ </not>
+ </condition>
+ </fail>
+ </target>
+
+ <target name="createDocExample">
+ <mkdir dir="${input}"/>
+ <echoxml file="${input}/example.xml">
+ <root-tag>
+ <version value="0.0.1"/>
+ <build folder="build">
+ <classes id="build.classes" location="${build.folder}/classes"/>
+ <reference refid="build.classes"/>
+ </build>
+ <compile>
+ <classpath pathid="compile.classpath">
+ <pathelement location="${build.classes}"/>
+ </classpath>
+ </compile>
+ <run-time>
+ <jars>*.jar</jars>
+ <classpath pathid="run-time.classpath">
+ <path refid="compile.classpath"/>
+ <pathelement path="${run-time.jars}"/>
+ </classpath>
+ </run-time>
+ </root-tag>
+ </echoxml>
+ </target>
+
+ <target name="testSemanticLoadingDocExample" depends="createDocExample">
+ <xmlproperty file="${input}/example.xml" semanticAttributes="true"
+ keepRoot="false"/>
+
+ <au:assertPropertyEquals name="version" value="0.0.1"/>
+ <au:assertPropertyEquals name="build.folder" value="build"/>
+ <property name="b.c" location="${build.folder}/classes"/>
+ <au:assertPropertyEquals name="build.classes" value="${b.c}"/>
+ <au:assertReferenceSet refid="build.classes"/>
+ <property name="b.c.r" refid="build.classes"/>
+ <au:assertPropertyEquals name="b.c.r" value="${b.c}"/>
+ <au:assertPropertyEquals name="build.reference" value="${b.c}"/>
+ <au:assertPropertyEquals name="run-time.jars" value="*.jar"/>
+ <au:assertReferenceIsType refid="compile.classpath" type="path"/>
+ <au:assertReferenceIsType refid="run-time.classpath" type="path"/>
+ <property name="c.c" refid="compile.classpath"/>
+ <au:assertPropertyEquals name="c.c" value="${b.c}"/>
+ <property name="rt.c" refid="run-time.classpath"/>
+ <property name="glob.dot.jar" location="*.jar"/>
+ <au:assertPropertyEquals name="rt.c"
+ value="${b.c}${path.separator}${glob.dot.jar}"/>
+ </target>
+
+ <target name="testIncludeSemanticDocExample" depends="createDocExample">
+ <xmlproperty file="${input}/example.xml" semanticAttributes="true"
+ keepRoot="false" includeSemanticAttribute="true"/>
+
+ <au:assertPropertyEquals name="version.value" value="0.0.1"/>
+ <au:assertPropertyEquals name="build.folder" value="build"/>
+ <property name="b.c" location="${build.folder}/classes"/>
+ <au:assertPropertyEquals name="build.classes.location" value="${b.c}"/>
+ <au:assertReferenceSet refid="build.classes"/>
+ <property name="b.c.r" refid="build.classes"/>
+ <au:assertPropertyEquals name="b.c.r" value="${b.c}"/>
+ <au:assertPropertyEquals name="build.reference" value="${b.c}"/>
+ <au:assertPropertyEquals name="run-time.jars" value="*.jar"/>
+ <au:assertReferenceIsType refid="compile.classpath" type="path"/>
+ <au:assertReferenceIsType refid="run-time.classpath" type="path"/>
+ <property name="c.c" refid="compile.classpath"/>
+ <!-- not set at all because property's name is build.classes.refid now -->
+ <property name="b.c.loc" location="${build.classes}"/>
+ <au:assertPropertyEquals name="c.c" value="${b.c.loc}"/>
+ <property name="rt.c" refid="run-time.classpath"/>
+ <property name="glob.dot.jar" location="*.jar"/>
+ <au:assertPropertyEquals name="rt.c"
+ value="${b.c.loc}${path.separator}${glob.dot.jar}"/>
+ </target>
+</project>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/xmlproperty.inline-expansion.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/xmlproperty.inline-expansion.xml
new file mode 100644
index 00000000..a9151799
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/xmlproperty.inline-expansion.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<root-tag>
+ <!--used to check that the ordering of attribute expansion/eval is the order of
+ declaration in the build file, not alphabetical
+
+ expectations are
+ p : ${app.n}
+ n : n
+ o : n
+ m : n
+ -->
+ <app
+ p="${app.n}"
+ n="n"
+ o="${app.n}"
+ m="${app.n}"/>
+</root-tag> \ No newline at end of file
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/xmlproperty.multi.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/xmlproperty.multi.xml
new file mode 100644
index 00000000..9899c586
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/xmlproperty.multi.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<root>
+ <element value="a" />
+ <element value="b" />
+</root>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/xslt-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/xslt-test.xml
new file mode 100644
index 00000000..d6f6d668
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/xslt-test.xml
@@ -0,0 +1,260 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="antunit" xmlns:au="antlib:org.apache.ant.antunit">
+ <import file="../antunit-base.xml" />
+
+ <target name="setUp">
+ <mkdir dir="${output}"/>
+ <property name="legacy.dir"
+ location="../../../etc/testcases/taskdefs/style/"/>
+ </target>
+
+ <target name="testParameterPropagation" depends="setUp">
+ <xslt in="${legacy.dir}/data.xml"
+ out="${output}/out.xml"
+ style="${legacy.dir}/printParams.xsl">
+ <param name="set" expression="myvalue"/>
+ </xslt>
+ <au:assertResourceContains
+ resource="${output}/out.xml"
+ value="set='myvalue'"/>
+ </target>
+
+ <target name="testParameterTypes" depends="setUp" description="parameters of various data types and XPath expressions">
+
+ <property name="antProperty1" value="ANT_PROPERTY_1"/>
+ <property name="antProperty2" value="ANT_PROPERTY_2"/>
+ <property name="antProperty3" value="3"/>
+ <property name="antProperty4" value="substring-before"/>
+
+ <xslt in="${legacy.dir}/data.xml"
+ out="${output}/out.xml">
+ <param name="p1" expression="123" type="INT"/>
+ <param name="p2" expression="64 * 64 div 128 + 10" type="XPATH_NUMBER"/>
+ <param name="p3" expression="${antProperty4}($antProperty2, '_')" type="XPATH_STRING"/>
+
+ <style>
+ <string><![CDATA[<xsl:stylesheet
+ version="1.0"
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:fo="http://www.w3.org/1999/XSL/Format">
+
+<!-- get the xsl-parameter -->
+<xsl:param name="p1"/>
+<xsl:param name="p2"/>
+<xsl:param name="p3"/>
+
+<!-- use the xsl-parameter -->
+<xsl:template match="/">
+p1_result='<xsl:value-of select="$p1 + 321"/>'
+p2_result='<xsl:value-of select="$p2"/>'
+p3_result='<xsl:value-of select="$p3"/>'
+</xsl:template>
+
+</xsl:stylesheet>
+]]></string>
+ </style>
+ </xslt>
+ <au:assertResourceContains resource="${output}/out.xml" value="p1_result='444'"/>
+ <au:assertResourceContains resource="${output}/out.xml" value="p2_result='42'"/>
+ <au:assertResourceContains resource="${output}/out.xml" value="p3_result='ANT'"/>
+ </target>
+
+ <target name="testInlineStyleSheet" depends="setUp">
+ <xslt in="${legacy.dir}/data.xml"
+ out="${output}/out.xml">
+ <param name="set" expression="somevalue"/>
+ <style>
+ <string><![CDATA[<xsl:stylesheet
+ version="1.0"
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:fo="http://www.w3.org/1999/XSL/Format">
+
+<!-- get the xsl-parameter -->
+<xsl:param name="set">set default value</xsl:param>
+<xsl:param name="empty">empty default value</xsl:param>
+<xsl:param name="undefined">undefined default value</xsl:param>
+
+<!-- use the xsl-parameter -->
+<xsl:template match="/">
+set='<xsl:value-of select="$set"/>'
+empty='<xsl:value-of select="$empty"/>'
+undefined='<xsl:value-of select="$undefined"/>'
+</xsl:template>
+
+</xsl:stylesheet>
+]]></string>
+ </style>
+ </xslt>
+ <au:assertResourceContains
+ resource="${output}/out.xml"
+ value="set='somevalue'"/>
+ </target>
+
+ <target name="testStyleDoesntExist" depends="setUp">
+ <au:expectfailure expectedmessage="i-m-not-there.xslt doesn't exist.">
+ <xslt in="${legacy.dir}/data.xml"
+ out="${output}/out.xml"
+ style="i-m-not-there.xslt"/>
+ </au:expectfailure>
+ </target>
+
+ <target name="testStyleDoesntExistNoError" depends="setUp">
+ <xslt in="${legacy.dir}/data.xml"
+ out="${output}/out.xml"
+ style="i-m-not-there.xslt"
+ failOnError="false"/>
+ <au:assertFileDoesntExist file="${output}/out.xml"/>
+ </target>
+
+ <target name="testStyleDoesntExistNoTransformationError" depends="setUp">
+ <au:expectfailure expectedmessage="i-m-not-there.xslt doesn't exist.">
+ <xslt in="${legacy.dir}/data.xml"
+ out="${output}/out.xml"
+ style="i-m-not-there.xslt"
+ failOnTransformationError="false"/>
+ </au:expectfailure>
+ </target>
+
+ <target name="testTransformationError" depends="setUp">
+ <au:expectfailure expectedmessage="Fatal error during transformation">
+ <xslt in="${legacy.dir}/data.xml"
+ out="${output}/out.xml"
+ style="xslt/printParams-invalid.xsl"
+ />
+ </au:expectfailure>
+ </target>
+
+ <target name="testTransformationErrorNoFail" depends="setUp">
+ <xslt in="${legacy.dir}/data.xml"
+ out="${output}/out.xml"
+ style="xslt/printParams-invalid.xsl"
+ failOnError="false"/>
+ <au:assertFileDoesntExist file="${output}/out.xml"/>
+ </target>
+
+ <target name="testTransformationErrorNoFailOnTransformation" depends="setUp">
+ <xslt in="${legacy.dir}/../input.stdin"
+ out="${output}/out.xml"
+ style="${legacy.dir}/printParams.xsl"
+ failOnTransformationError="false"/>
+ <au:assertFileDoesntExist file="${output}/out.xml"/>
+ </target>
+
+ <target name="testNoResources" depends="setUp">
+ <au:expectfailure expectedmessage="no resources specified">
+ <xslt destdir="${output}" style="${legacy.dir}/printParams.xsl"
+ useImplicitFileset="false">
+ <fileset dir=".">
+ <include name="I don't exist"/>
+ </fileset>
+ </xslt>
+ </au:expectfailure>
+ </target>
+
+ <target name="testNoResourcesNoFail" depends="setUp">
+ <xslt destdir="${output}" style="${legacy.dir}/printParams.xsl"
+ useImplicitFileset="false"
+ failOnNoResources="false">
+ <fileset dir=".">
+ <include name="I don't exist"/>
+ </fileset>
+ </xslt>
+ </target>
+
+ <target name="testNoResourcesNoError" depends="setUp">
+ <xslt destdir="${output}" style="${legacy.dir}/printParams.xsl"
+ useImplicitFileset="false"
+ failOnError="false">
+ <fileset dir=".">
+ <include name="I don't exist"/>
+ </fileset>
+ </xslt>
+ </target>
+
+
+ <target name="testTraceJdk14" unless="jdk1.5+" depends="setUp">
+ <xslt in="${legacy.dir}/data.xml"
+ out="${output}/out.xml"
+ style="${legacy.dir}/printParams.xsl">
+ <param name="set" expression="myvalue"/>
+ <trace templates="true"/>
+ </xslt>
+ <au:assertLogContains text="Failed to enable tracing" level="warning"/>
+ </target>
+
+ <target name="testTraceJdk15+" if="jdk1.5+" depends="setUp">
+ <xslt in="${legacy.dir}/data.xml"
+ out="${output}/out.xml"
+ style="${legacy.dir}/printParams.xsl">
+ <param name="set" expression="myvalue"/>
+ <trace templates="true" elements="true" generation="true"
+ selection="true" extension="true"/>
+ </xslt>
+ <au:assertLogDoesntContain text="Failed to enable tracing"/>
+ </target>
+
+ <target name="setUpIfUnlessTests" depends="setUp">
+ <macrodef name="xs">
+ <sequential>
+ <xslt in="${legacy.dir}/data.xml" out="${output}/out.xml"
+ style="${legacy.dir}/printParams.xsl">
+ <param name="set" expression="if-value" if="${if}"/>
+ <param name="set" expression="unless-value" unless="${if}"/>
+ <param name="empty" expression="if-value" if="if"/>
+ <param name="empty" expression="unless-value" unless="if"/>
+ </xslt>
+ </sequential>
+ </macrodef>
+ </target>
+
+ <target name="testPropertiesNotSet" depends="setUpIfUnlessTests">
+ <xs/>
+ <au:assertResourceContains resource="${output}/out.xml"
+ value="set='unless-value'"/>
+ <au:assertResourceContains resource="${output}/out.xml"
+ value="empty='unless-value'"/>
+ </target>
+
+ <target name="testPropertiesSet" depends="setUpIfUnlessTests">
+ <property name="if" value="whatever"/>
+ <xs/>
+ <au:assertResourceContains resource="${output}/out.xml"
+ value="set='unless-value'"/>
+ <au:assertResourceContains resource="${output}/out.xml"
+ value="empty='if-value'"/>
+ </target>
+
+ <target name="testIfTrue" depends="setUpIfUnlessTests">
+ <property name="if" value="true"/>
+ <xs/>
+ <au:assertResourceContains resource="${output}/out.xml"
+ value="set='if-value'"/>
+ <au:assertResourceContains resource="${output}/out.xml"
+ value="empty='if-value'"/>
+ </target>
+
+ <target name="testIfFalse" depends="setUpIfUnlessTests">
+ <property name="if" value="false"/>
+ <xs/>
+ <au:assertResourceContains resource="${output}/out.xml"
+ value="set='unless-value'"/>
+ <au:assertResourceContains resource="${output}/out.xml"
+ value="empty='if-value'"/>
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/xslt/printParams-invalid.xsl b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/xslt/printParams-invalid.xsl
new file mode 100644
index 00000000..36d404e8
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/xslt/printParams-invalid.xsl
@@ -0,0 +1,36 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<xsl:stylesheet
+ version="1.0"
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:fo="http://www.w3.org/1999/XSL/Format">
+
+<!-- get the xsl-parameter -->
+<xsl:param name="set">set default value</xsl:param>
+<xsl:param name="empty">empty default value</xsl:param>
+<xsl:param name="undefined">undefined default value</xsl:param>
+
+<!-- use the xsl-parameter -->
+<xsl:template match="'">
+set='<xsl:value-of select="$set"/>'
+empty='<xsl:value-of select="$empty"/>'
+undefined='<xsl:value-of select="$undefined"/>'
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/zip-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/zip-test.xml
new file mode 100644
index 00000000..6a054f13
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/zip-test.xml
@@ -0,0 +1,185 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="antunit" xmlns:au="antlib:org.apache.ant.antunit">
+ <import file="../antunit-base.xml" />
+
+ <target name="testEmptyDirs">
+ <mkdir dir="${input}/foo"/>
+ <mkdir dir="${output}/bar"/>
+ <zip destfile="${output}/test.zip">
+ <fileset dir="${input}"/>
+ </zip>
+ <unzip src="${output}/test.zip" dest="${output}/bar"/>
+ <au:assertFileExists file="${output}/bar/foo"/>
+ </target>
+
+ <target name="testMappedResources">
+ <mkdir dir="${input}"/>
+ <mkdir dir="${output}/out"/>
+ <echo file="${input}/foo.txt">Hello, world!</echo>
+ <zip destfile="${output}/test.zip">
+ <mappedresources>
+ <fileset dir="${input}"/>
+ <globmapper from="foo.*" to="bar.*"/>
+ </mappedresources>
+ </zip>
+ <unzip src="${output}/test.zip" dest="${output}/out"/>
+ <au:assertFileDoesntExist file="${output}/out/foo.txt"/>
+ <au:assertFileExists file="${output}/out/bar.txt"/>
+ <au:assertFilesMatch expected="${input}/foo.txt"
+ actual="${output}/out/bar.txt"/>
+ </target>
+
+ <target name="test-54026">
+ <mkdir dir="${input}"/>
+ <touch file="${input}/test1"/>
+ <mkdir dir="${input}/subdir"/>
+ <touch file="${input}/subdir/test2"/>
+ <zip destfile="${output}/br54026-destzip.zip">
+ <mappedresources>
+ <fileset dir="${input}"/>
+ <globmapper from="subdir/*" to="subdir.orig/*"/>
+ </mappedresources>
+ </zip>
+
+ <au:assertFileExists file="${output}/br54026-destzip.zip"/>
+ </target>
+
+ <target name="testMappedClasspath">
+ <mkdir dir="${input}"/>
+ <mkdir dir="${output}/out"/>
+ <zip destfile="${output}/test.zip">
+ <mappedresources>
+ <path path="${java.class.path}"/>
+ <chainedmapper>
+ <flattenmapper/>
+ <globmapper from="*" to="WEB-INF/lib/*"/>
+ </chainedmapper>
+ </mappedresources>
+ </zip>
+ <unzip src="${output}/test.zip" dest="${output}/out"/>
+ <au:assertFileExists file="${output}/out/WEB-INF/lib/ant.jar"/>
+ </target>
+
+ <target name="testIssue45902"
+ description="https://issues.apache.org/bugzilla/show_bug.cgi?id=45902">
+ <mkdir dir="${input}/src/p"/>
+ <mkdir dir="${output}"/>
+ <touch file="${input}/src/p/X.java"/>
+ <touch file="${input}/src/p/x.properties"/>
+ <mkdir dir="${input}/build"/>
+ <copy todir="${input}/build">
+ <fileset dir="${input}/src" includes="**/*.java"/>
+ </copy>
+
+ <jar jarfile="${output}/jar.jar">
+ <fileset dir="${input}/build"/>
+ <fileset dir="${input}/src" excludes="**/*.java"/>
+ </jar>
+ <copy file="${output}/jar.jar" tofile="${output}/reference.jar"/>
+
+ <sleep seconds="1"/>
+ <touch file="${input}/src/p/y.properties"/>
+ <sleep seconds="1"/>
+ <delete file="${input}/src/p/y.properties"/>
+ <jar jarfile="${output}/jar.jar">
+ <fileset dir="${input}/build"/>
+ <fileset dir="${input}/src" excludes="**/*.java"/>
+ </jar>
+ <au:assertDestIsUptodate src="${output}/jar.jar"
+ dest="${output}/reference.jar"/>
+
+ <sleep seconds="1"/>
+ <jar jarfile="${output}/jar.jar">
+ <fileset dir="${input}/build"/>
+ <fileset dir="${input}/src" excludes="**/*.java"/>
+ </jar>
+ <au:assertDestIsUptodate src="${output}/jar.jar"
+ dest="${output}/reference.jar"/>
+
+ <jar jarfile="${output}/jar.jar">
+ <fileset dir="${input}/build"/>
+ <fileset dir="${input}/src" excludes="**/*.java"/>
+ </jar>
+ <au:assertDestIsUptodate src="${output}/jar.jar"
+ dest="${output}/reference.jar"/>
+ </target>
+
+ <target name="testNewEmptyDirUpdatesArchive">
+ <mkdir dir="${input}"/>
+ <touch file="${input}/x"/>
+ <mkdir dir="${output}"/>
+ <jar jarfile="${output}/jar.jar">
+ <fileset dir="${input}"/>
+ </jar>
+ <copy file="${output}/jar.jar" tofile="${output}/reference.jar"/>
+
+ <mkdir dir="${input}/y"/>
+ <sleep seconds="2"/>
+ <jar jarfile="${output}/jar.jar">
+ <fileset dir="${input}"/>
+ </jar>
+ <au:assertDestIsOutofdate src="${output}/jar.jar"
+ dest="${output}/reference.jar"/>
+ </target>
+
+ <target name="testFilesetInsideResources"
+ description="https://issues.apache.org/bugzilla/show_bug.cgi?id=50115">
+ <mkdir dir="${input}/test2"/>
+ <touch file="${input}/test1.txt"/>
+ <mkdir dir="${output}"/>
+ <mkdir dir="${output}/expand"/>
+ <zip destfile="${output}/test.zip" whenempty="skip">
+ <resources>
+ <fileset dir="${input}" includes="test**"/>
+ </resources>
+ </zip>
+ <au:assertLogDoesntContain text="skipping zip archive"/>
+ <unzip src="${output}/test.zip" dest="${output}/expand"/>
+ <au:assertFileExists file="${output}/expand/test1.txt"/>
+ <!--au:assertFileExists file="${output}/expand/test2"/-->
+ </target>
+
+ <target name="testWhenEmptyChecksNonFileSets"
+ description="https://issues.apache.org/bugzilla/show_bug.cgi?id=50115">
+ <mkdir dir="${input}/"/>
+ <touch file="${input}/test1.txt"/>
+ <mkdir dir="${output}"/>
+ <mkdir dir="${output}/expand"/>
+ <zip destfile="${output}/test.zip" whenempty="fail">
+ <resources>
+ <fileset dir="${input}" includes="test**"/>
+ </resources>
+ </zip>
+ <unzip src="${output}/test.zip" dest="${output}/expand"/>
+ <au:assertFileExists file="${output}/expand/test1.txt"/>
+ </target>
+
+ <target name="testUpdateZipWithDuplicateEntries"
+ description="https://issues.apache.org/bugzilla/show_bug.cgi?id=54967">
+ <mkdir dir="${input}/"/>
+ <touch file="${input}/test1.txt"/>
+ <mkdir dir="${output}"/>
+ <zip destfile="${output}/test.zip" basedir="${input}">
+ <fileset dir="${input}"/>
+ </zip>
+ <zip destfile="${output}/test.zip" update="true">
+ <fileset dir="${basedir}" includes="zip-test.xml"/>
+ </zip>
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/zip/Bugzilla-42940.zip b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/zip/Bugzilla-42940.zip
new file mode 100644
index 00000000..2f756608
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/taskdefs/zip/Bugzilla-42940.zip
Binary files differ
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/build-embedded-ref.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/build-embedded-ref.xml
new file mode 100644
index 00000000..f2cbd2ad
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/build-embedded-ref.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="all">
+ <target name="all"/>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/conditions/isreference-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/conditions/isreference-test.xml
new file mode 100644
index 00000000..8929e901
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/conditions/isreference-test.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="isreference-test" default="antunit"
+ xmlns:au="antlib:org.apache.ant.antunit">
+
+ <import file="../../antunit-base.xml" />
+
+ <target name="out-of-band">
+ <path id="out-of-band" path="."/>
+ </target>
+
+ <target name="testOutOfBand">
+ <au:assertFalse>
+ <isreference refid="out-of-band"/>
+ </au:assertFalse>
+ </target>
+
+ <target name="testInBand">
+ <path id="in-band" path="."/>
+ <au:assertTrue>
+ <isreference refid="in-band"/>
+ </au:assertTrue>
+ </target>
+</project>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/conditions/matches-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/conditions/matches-test.xml
new file mode 100644
index 00000000..5d174613
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/conditions/matches-test.xml
@@ -0,0 +1,114 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project xmlns:au="antlib:org.apache.ant.antunit">
+ <!-- NB: ant's interface to JDK14 regex enables UNIX_LINES -->
+ <property name="NL" value="&#10;"/>
+ <regexp id="myid" pattern="^[a-z]{3,4}$"/>
+
+ <available property="jdk1.4+" classname="java.lang.CharSequence"/>
+ <condition property="some.regexp.support">
+ <or>
+ <isset property="jdk1.4+"/>
+ <isset property="apache.regexp.present"/>
+ <isset property="apache.oro.present"/>
+ </or>
+ </condition>
+
+ <target name="test-refid" if="some.regexp.support">
+ <au:assertTrue>
+ <matches string="abc">
+ <regexp refid="myid"/>
+ </matches>
+ </au:assertTrue>
+ </target>
+
+ <target name="test-simple" if="some.regexp.support">
+ <au:assertTrue>
+ <matches string="abc" pattern="^[a-z]{3,4}$"/>
+ </au:assertTrue>
+ </target>
+
+ <target name="test-nomatch" if="some.regexp.support">
+ <au:assertFalse>
+ <matches string="abc" pattern="^b.*" />
+ </au:assertFalse>
+ </target>
+
+ <target name="test-date" if="some.regexp.support">
+ <tstamp>
+ <format property="today" pattern="dd-MM-yyyy" locale="en"/>
+ </tstamp>
+ <au:assertTrue>
+ <matches string="${today}">
+ <regexp pattern="^[0123]\d-[01]\d-[12]\d\d\d$" />
+ </matches>
+ </au:assertTrue>
+ </target>
+
+ <target name="test-abc" if="some.regexp.support">
+ <au:assertTrue>
+ <matches string="abc" pattern="ab?"/>
+ </au:assertTrue>
+ <au:assertTrue>
+ <matches string="abc" pattern="ab."/>
+ </au:assertTrue>
+ <au:assertTrue>
+ <matches string="ab" pattern="ab?"/>
+ </au:assertTrue>
+ <au:assertTrue>
+ <matches string="ab" pattern="ab"/>
+ </au:assertTrue>
+ <au:assertTrue>
+ <matches string="acb" pattern="ab?"/>
+ </au:assertTrue>
+ <au:assertFalse>
+ <matches string="acb" pattern="ab."/>
+ </au:assertFalse>
+ </target>
+
+ <target name="test-caseinsensitive" if="some.regexp.support">
+ <au:assertTrue>
+ <matches string="ABC" pattern="ab?" casesensitive="false"/>
+ </au:assertTrue>
+ </target>
+
+ <target name="test-singleline" if="some.regexp.support">
+ <au:assertTrue>
+ <matches string="AB${line.separator}C" pattern="^ab.*C$"
+ casesensitive="false"
+ singleline="true"/>
+ </au:assertTrue>
+ <au:assertFalse>
+ <matches string="AB${line.separator}C" pattern="^ab.*C$"
+ casesensitive="false"
+ singleline="false"/>
+ </au:assertFalse>
+ </target>
+
+ <target name="test-multiline" if="some.regexp.support">
+ <au:assertTrue>
+ <matches string="AB${NL}C" pattern="^C$"
+ multiline="true"/>
+ </au:assertTrue>
+ <au:assertTrue>
+ <matches string="AB${NL}C" pattern="^AB$"
+ multiline="true"/>
+ </au:assertTrue>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/cutdirs-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/cutdirs-test.xml
new file mode 100644
index 00000000..64f0652b
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/cutdirs-test.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project xmlns:au="antlib:org.apache.ant.antunit"
+ name="firstmatch-test"
+ default="antunit">
+
+ <import file="../antunit-base.xml" />
+
+ <target name="setUp">
+ <mkdir dir="${input}"/>
+ <mkdir dir="${output}"/>
+ </target>
+
+ <target name="testCut" depends="setUp">
+ <mkdir dir="${input}/a/b/c"/>
+ <touch file="${input}/a/b/D"/>
+ <touch file="${input}/a/b/c/E"/>
+ <copy todir="${output}">
+ <fileset dir="${input}"/>
+ <cutdirsmapper dirs="2"/>
+ </copy>
+ <au:assertFileExists file="${output}/D"/>
+ <au:assertFileExists file="${output}/c/E"/>
+ </target>
+
+ <target name="testCutTooManyLevels" depends="setUp">
+ <mkdir dir="${input}/a/b/c"/>
+ <touch file="${input}/a/b/D"/>
+ <touch file="${input}/a/b/c/E"/>
+ <copy todir="${output}">
+ <fileset dir="${input}"/>
+ <cutdirsmapper dirs="5"/>
+ </copy>
+ <au:assertTrue>
+ <resourcecount count="0">
+ <fileset dir="${output}"/>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+</project> \ No newline at end of file
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/defer-reference-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/defer-reference-test.xml
new file mode 100644
index 00000000..a67ad3b7
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/defer-reference-test.xml
@@ -0,0 +1,69 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="all" xmlns:au="antlib:org.apache.ant.antunit">
+ <target name="notcalled">
+ <filelist id="ref1" dir="${basedir}" files="xxx" />
+ </target>
+
+ <target name="test-macrodef-embedded-ref">
+ <!-- bug 34458 -->
+ <macrodef name="foo">
+ <element name="nested" implicit="yes" optional="yes"/>
+ <sequential>
+ <fileset id="abc" dir=".">
+ <nested/>
+ </fileset>
+ </sequential>
+ </macrodef>
+
+ <ant antfile="build-embedded-ref.xml" inheritRefs="true"/>
+ </target>
+
+ <condition property="allow.script">
+ <and>
+ <available classname="org.apache.bsf.BSFManager" />
+ <available classname="bsh.StringUtil" />
+ </and>
+ </condition>
+
+ <target name="test-script" if="allow.script">
+ <!-- bugzilla: 37688 -->
+ <macrodef name="compileMapper" >
+ <attribute name="objDir" />
+ <attribute name="id" default="compileMapperID" />
+ <sequential>
+ <mkdir dir="@{objDir}"/>
+ <mapper id="@{id}">
+ <chainedmapper >
+ <flattenmapper/>
+ <globmapper from="*" to="@{objDir}/*.o"/>
+ </chainedmapper>
+ </mapper>
+ </sequential>
+ </macrodef>
+ <script language="beanshell"/>
+ </target>
+
+ <target name="all">
+ <au:antunit>
+ <fileset file="${ant.file}"/>
+ <au:plainlistener/>
+ </au:antunit>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/fileset-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/fileset-test.xml
new file mode 100644
index 00000000..9580a1ce
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/fileset-test.xml
@@ -0,0 +1,67 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project xmlns:au="antlib:org.apache.ant.antunit" default="antunit">
+
+ <import file="../antunit-base.xml"/>
+
+ <target name="test-fileset-missing-dir">
+ <path id="missing.path.id">
+ <fileset id="missing.dir.fs" dir="not present"
+ erroronmissingdir="false"/>
+ </path>
+ <au:assertTrue>
+ <and>
+ <equals arg1="" arg2="${toString:missing.path.id}"/>
+ <resourcecount count="0" refid="missing.dir.fs" />
+ </and>
+ </au:assertTrue>
+ </target>
+
+ <target name="test-fileset-missing-dir-exception">
+ <mkdir dir="${output}"/>
+ <au:expectfailure expectedmessage="not present does not exist">
+ <copy todir="${output}">
+ <fileset dir="not present" />
+ </copy>
+ </au:expectfailure>
+ </target>
+
+ <target name="test-fileset-with-if">
+ <fileset id="this.xml" dir=".">
+ <include if="trigger.include" name="fileset-test.xml"/>
+ </fileset>
+ <pathconvert refid="this.xml" property="this.xml.prop" pathsep="${line.separator}" setonempty="false"/>
+ <au:assertTrue message="fileset this.xml should not contain anything but contains ${this.xml.prop}">
+ <not>
+ <isset property="this.xml.prop"/>
+ </not>
+ </au:assertTrue>
+ </target>
+
+ <target name="test-fileset-with-if-property-set">
+ <property name="trigger.include" value="true"/>
+ <fileset id="this.xml" dir=".">
+ <include if="trigger.include" name="fileset-test.xml"/>
+ </fileset>
+ <pathconvert refid="this.xml" property="this.xml.prop" pathsep="${line.separator}" setonempty="false"/>
+ <au:assertPropertySet name="this.xml.prop" message="fileset should contain one file"/>
+ <echo>${this.xml.prop}</echo>
+ <au:assertLogContains text="fileset-test.xml"/>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/filterset-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/filterset-test.xml
new file mode 100644
index 00000000..f1654f6d
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/filterset-test.xml
@@ -0,0 +1,96 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project xmlns:au="antlib:org.apache.ant.antunit" default="antunit">
+
+ <import file="../antunit-base.xml" />
+
+ <property name="br" value="${line.separator}" />
+
+ <target name="testRecursionRegression">
+ <mkdir dir="${output}"/>
+ <copy todir="${output}">
+ <string value="@a@${br}@b@${br}@c@${br}@d@${br}" />
+ <mergemapper to="filterset-output.txt" />
+ <filterset>
+ <filter token="a" value="aaa" />
+ <filter token="b" value="bbb" />
+ <filter token="c" value="@a@:@b@" />
+ <filter token="d" value="@c@:@c@" />
+ </filterset>
+ </copy>
+
+ <loadfile property="afterfiltering" srcFile="${output}/filterset-output.txt"/>
+
+ <au:assertEquals
+ expected="aaa${br}bbb${br}aaa:bbb${br}aaa:bbb:aaa:bbb${br}"
+ actual="${afterfiltering}"/>
+ </target>
+
+ <!-- https://issues.apache.org/bugzilla/show_bug.cgi?id=45094 -->
+ <target name="testOverlappingMulticharToken">
+ <mkdir dir="${output}"/>
+ <copy todir="${output}">
+ <string value="@@USER@@@@@HOST@@" />
+ <mergemapper to="filterset-output.txt" />
+ <filterset begintoken="@@" endtoken="@@">
+ <filter token="USER" value="user" />
+ <filter token="HOST" value="host" />
+ </filterset>
+ </copy>
+
+ <loadfile property="afterfiltering" srcFile="${output}/filterset-output.txt"/>
+
+ <au:assertEquals
+ expected="user@host"
+ actual="${afterfiltering}"/>
+ </target>
+
+ <target name="testNestedPropertySet">
+ <mkdir dir="${output}"/>
+ <mkdir dir="${input}"/>
+ <echo file="${input}/src.txt">
+Filter with property set test
+@foo.x@ - should change
+@foo.y@ - should change
+@bar.x@ - should not change
+@cccc@ - should not change
+ </echo>
+ <echo file="${output}/expected.txt">
+Filter with property set test
+1111 - should change
+2222 - should change
+@bar.x@ - should not change
+@cccc@ - should not change
+ </echo>
+ <property name="foo.x" value="1111" />
+ <property name="foo.y" value="2222" />
+ <copy todir="${output}">
+ <fileset dir="${input}"/>
+ <filterset>
+ <propertyset>
+ <propertyref prefix="foo." />
+ </propertyset>
+ </filterset>
+ </copy>
+ <au:assertFilesMatch
+ actual="${output}/src.txt"
+ expected="${output}/expected.txt"
+ />
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/firstmatch-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/firstmatch-test.xml
new file mode 100644
index 00000000..68c332b2
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/firstmatch-test.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project xmlns:au="antlib:org.apache.ant.antunit"
+ name="firstmatch-test"
+ default="antunit">
+
+ <import file="../antunit-base.xml" />
+
+ <target name="testMatch">
+ <mkdir dir="${input}"/>
+ <touch file="${input}/A"/>
+ <touch file="${input}/B"/>
+ <mkdir dir="${output}"/>
+ <copy todir="${output}" enablemultiplemappings="true">
+ <fileset dir="${input}"/>
+ <firstmatchmapper>
+ <globmapper from="A" to="A.txt"/>
+ <identitymapper/>
+ </firstmatchmapper>
+ </copy>
+ <au:assertFileExists file="${output}/A.txt"/>
+ <au:assertFileExists file="${output}/B"/>
+ <au:assertFileDoesntExist file="${output}/A"/>
+ <au:assertFileDoesntExist file="${output}/B.txt"/>
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/javaresource-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/javaresource-test.xml
new file mode 100644
index 00000000..d0e99e00
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/javaresource-test.xml
@@ -0,0 +1,62 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="antunit" xmlns:au="antlib:org.apache.ant.antunit">
+ <import file="../antunit-base.xml" />
+
+ <target name="setUp">
+ <mkdir dir="${resources}"/>
+ <echo file="${resources}/foo.txt">Hello, world</echo>
+ <echo file="${resources}/x.properties">a=b</echo>
+ </target>
+
+ <target name="testReadFromFile" depends="setUp">
+ <concat>
+ <javaresource name="foo.txt">
+ <classpath location="${resources}"/>
+ </javaresource>
+ </concat>
+ <au:assertLogContains text="Hello, world"/>
+ <loadproperties>
+ <javaresource name="x.properties">
+ <classpath location="${resources}"/>
+ </javaresource>
+ </loadproperties>
+ <au:assertPropertyEquals name="a" value="b"/>
+ </target>
+
+ <target name="testReadFromJar" depends="setUp">
+ <jar destfile="${test.jar}">
+ <fileset dir="${resources}"/>
+ </jar>
+ <delete dir="${resources}"/>
+ <concat>
+ <javaresource name="foo.txt">
+ <classpath location="${test.jar}"/>
+ </javaresource>
+ </concat>
+ <au:assertLogContains text="Hello, world"/>
+ <loadproperties>
+ <javaresource name="x.properties">
+ <classpath location="${test.jar}"/>
+ </javaresource>
+ </loadproperties>
+ <au:assertPropertyEquals name="a" value="b"/>
+ </target>
+</project>
+
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/mapper-ref.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/mapper-ref.xml
new file mode 100644
index 00000000..3ada7f3b
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/mapper-ref.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!-- does not address/replace the circular reference checks, etc.
+ in MapperTest.java (yet).
+ -->
+
+<project xmlns:au="antlib:org.apache.ant.antunit">
+ <macrodef name="test">
+ <sequential>
+ <pathconvert property="dest">
+ <string value="foo" />
+ <mapper refid="mapper" />
+ </pathconvert>
+ <au:assertTrue>
+ <equals arg1="${dest}" arg2="bar" />
+ </au:assertTrue>
+ </sequential>
+ </macrodef>
+
+ <target name="testBasic" description="success">
+ <mapper id="mapper" type="merge" to="bar" />
+ <test />
+ </target>
+
+ <target name="testFileNameMapper" description="success">
+ <mergemapper id="mapper" to="bar" />
+ <test />
+ </target>
+
+ <target name="testWrongType" description="failure">
+ <path id="mapper" path="whocares" />
+ <au:expectfailure
+ expectedMessage="org.apache.tools.ant.types.Path at reference 'mapper' is not a valid mapper reference.">
+ <test />
+ </au:expectfailure>
+ </target>
+
+ <target name="all" depends="testBasic,testFileNameMapper,testWrongType" />
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/mappers/glob-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/mappers/glob-test.xml
new file mode 100644
index 00000000..c4d92da2
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/mappers/glob-test.xml
@@ -0,0 +1,80 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!-- A test for bugzilla 44731 -->
+<project xmlns:au="antlib:org.apache.ant.antunit"
+ name="glob-test"
+ default="antunit">
+
+ <import file="../../antunit-base.xml" />
+
+ <target name="setUp">
+ <mkdir dir="${input}"/>
+ <mkdir dir="${output}"/>
+ </target>
+
+ <target name="test-overlapping-patterns" depends="setUp">
+ <!-- shouldn't be moved because pre- and postfix of from pattern
+ overlap -->
+ <touch file="${input}/foobar-1.2.3.jar"/>
+
+ <touch file="${input}/foobar-janfu-1.2.3.jar"/>
+ <touch file="${input}/foobar--1.2.3.jar"/>
+ <touch file="${input}/foobar-x-1.2.3.jar"/>
+ <move todir="${output}">
+ <fileset dir="${input}">
+ <include name="**/*.jar"/>
+ </fileset>
+ <mapper type="glob" from="foobar-*-1.2.3.jar" to="*.jar"/>
+ </move>
+ <au:assertFileExists file="${input}/foobar-1.2.3.jar"/>
+ <au:assertFileExists file="${output}/janfu.jar"/>
+ <au:assertFileExists file="${output}/.jar"/>
+ <au:assertFileExists file="${output}/x.jar"/>
+ </target>
+
+ <target name="test-no-*-in-to" depends="setUp"
+ description="https://issues.apache.org/bugzilla/show_bug.cgi?id=46506">
+ <touch file="${input}/a-b.jar"/>
+ <copy todir="${output}">
+ <fileset dir="${input}"/>
+ <mapper type="glob" from="a*.jar" to="c.jar"/>
+ </copy>
+ <au:assertFileDoesntExist file="${output}/c.jar-b"/>
+ <au:assertFileExists file="${output}/c.jar"/>
+ </target>
+
+ <target name="test-*-at-end-of-to" depends="setUp">
+ <touch file="${input}/a-b.jar"/>
+ <copy todir="${output}">
+ <fileset dir="${input}"/>
+ <mapper type="glob" from="a*.jar" to="c.jar*"/>
+ </copy>
+ <au:assertFileDoesntExist file="${output}/c.jar"/>
+ <au:assertFileExists file="${output}/c.jar-b"/>
+ </target>
+
+ <target name="test-no-*-in-from" depends="setUp">
+ <touch file="${input}/a-b.jar"/>
+ <copy todir="${output}">
+ <fileset dir="${input}"/>
+ <mapper type="glob" from="a-b" to="c.jar"/>
+ </copy>
+ <au:assertFileDoesntExist file="${output}/c.jar"/>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/mappers/packagemapper-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/mappers/packagemapper-test.xml
new file mode 100644
index 00000000..cad01464
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/mappers/packagemapper-test.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project xmlns:au="antlib:org.apache.ant.antunit"
+ default="antunit">
+
+ <import file="../../antunit-base.xml" />
+
+ <target name="testHandleDirSep"
+ description="https://issues.apache.org/bugzilla/show_bug.cgi?id=51086">
+ <pathconvert property="p1">
+ <string>foo/bar</string>
+ <packagemapper from="*" to="*" handledirsep="true"/>
+ </pathconvert>
+ <au:assertPropertyEquals name="p1" value="foo.bar"/>
+ <pathconvert property="p2">
+ <string>foo\bar</string>
+ <packagemapper from="*" to="*" handledirsep="true"/>
+ </pathconvert>
+ <au:assertPropertyEquals name="p2" value="foo.bar"/>
+ </target>
+
+ <target name="testMapsOnlySubstring"
+ description="https://issues.apache.org/bugzilla/show_bug.cgi?id=53399">
+ <pathconvert property="p1">
+ <string>xyzzy${file.separator}foo${file.separator}bar</string>
+ <packagemapper from="xyzzy${file.separator}*" to="*" handledirsep="false"/>
+ </pathconvert>
+ <au:assertPropertyEquals name="p1" value="foo.bar"/>
+ <pathconvert property="p2">
+ <string>xyzzy${file.separator}foo${file.separator}bar</string>
+ <packagemapper from="xyzzy/*" to="*" handledirsep="true"/>
+ </pathconvert>
+ <au:assertPropertyEquals name="p2" value="foo.bar"/>
+ </target>
+</project> \ No newline at end of file
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/modified-selector-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/modified-selector-test.xml
new file mode 100644
index 00000000..16688ca9
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/modified-selector-test.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project xmlns:au="antlib:org.apache.ant.antunit" default="antunit">
+
+ <import file="../antunit-base.xml"/>
+
+ <target name="test-one-file">
+ <delete dir="${output}"/>
+ <mkdir dir="${output}"/>
+ <copy todir="${output}" overwrite="yes">
+ <fileset dir="." includes="modified-selector-test.xml">
+ <modified update="true">
+ <param name="cache.cachefile" value="${output}/cc.properties"/>
+ </modified>
+ </fileset>
+ </copy>
+
+ <au:assertTrue>
+ <available file="${output}/cc.properties"/>
+ </au:assertTrue>
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/path-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/path-test.xml
new file mode 100644
index 00000000..4f4be9ab
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/path-test.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project xmlns:au="antlib:org.apache.ant.antunit" default="antunit">
+
+ <import file="../antunit-base.xml" />
+
+ <property name="existingFile" value="${basedir}/build.xml" />
+
+ <files id="files">
+ <include name="${existingFile}" />
+ </files>
+
+ <target name="test-directUse" description="Bug 42397 - works fine">
+ <path id="path">
+ <files>
+ <include name="${existingFile}" />
+ </files>
+ </path>
+ </target>
+
+ <target name="test-refid" description="Bug 42397">
+ <path id="path">
+ <files refid="files" />
+ </path>
+ </target>
+
+ <target name="test-wildcard"
+ description="https://issues.apache.org/bugzilla/show_bug.cgi?id=46842">
+ <path id="with-wildcard">
+ <pathelement location="*"/>
+ </path>
+ <au:assertEquals expected="${basedir}${file.separator}*"
+ actual="${toString:with-wildcard}"/>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/patternset-invert-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/patternset-invert-test.xml
new file mode 100644
index 00000000..7c0912e7
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/patternset-invert-test.xml
@@ -0,0 +1,66 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="all" xmlns:au="antlib:org.apache.ant.antunit">
+
+ <macrodef name="test">
+ <sequential>
+ <au:assertTrue>
+ <resourcecount count="0">
+ <intersect>
+ <fileset dir="${basedir}">
+ <patternset refid="plus" />
+ </fileset>
+ <fileset dir="${basedir}">
+ <patternset refid="minus" />
+ </fileset>
+ </intersect>
+ </resourcecount>
+ </au:assertTrue>
+ </sequential>
+ </macrodef>
+
+ <target name="testInvertNested">
+ <basename property="basename" file="${ant.file}" />
+ <echo>$${basename}=${basename}</echo>
+ <patternset id="plus" includes="${basename}" />
+ <patternset id="minus">
+ <invert>
+ <patternset refid="plus" />
+ </invert>
+ </patternset>
+ <test />
+ </target>
+
+ <target name="testInvertRefid">
+ <basename property="basename" file="${ant.file}" />
+ <echo>$${basename}=${basename}</echo>
+ <patternset id="plus" includes="${basename}" />
+ <patternset id="minus">
+ <invert refid="plus" />
+ </patternset>
+ <test />
+ </target>
+
+ <target name="all">
+ <au:antunit>
+ <fileset file="${ant.file}"/>
+ <au:plainlistener />
+ </au:antunit>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/patternset-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/patternset-test.xml
new file mode 100644
index 00000000..60690d49
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/patternset-test.xml
@@ -0,0 +1,78 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project xmlns:au="antlib:org.apache.ant.antunit" default="antunit">
+
+ <import file="../antunit-base.xml" />
+
+ <target name="setUp">
+ <mkdir dir="${input}"/>
+ <touch file="${input}/A"/>
+ <touch file="${input}/B"/>
+ <touch file="${input}/C"/>
+ <touch file="${input}/D"/>
+ <mkdir dir="${output}"/>
+ <macrodef name="cp">
+ <sequential>
+ <copy todir="${output}">
+ <fileset dir="${input}">
+ <include name="A" if="${if}"/>
+ <include name="B" unless="${if}"/>
+ <include name="C" if="if"/>
+ <include name="D" unless="if"/>
+ </fileset>
+ </copy>
+ </sequential>
+ </macrodef>
+ </target>
+
+ <target name="testIfNotSet" depends="setUp">
+ <cp/>
+ <au:assertFileDoesntExist file="${output}/A"/>
+ <au:assertFileExists file="${output}/B"/>
+ <au:assertFileDoesntExist file="${output}/C"/>
+ <au:assertFileExists file="${output}/D"/>
+ </target>
+
+ <target name="testIfSet" depends="setUp">
+ <property name="if" value="whatever"/>
+ <cp/>
+ <au:assertFileDoesntExist file="${output}/A"/>
+ <au:assertFileExists file="${output}/B"/>
+ <au:assertFileExists file="${output}/C"/>
+ <au:assertFileDoesntExist file="${output}/D"/>
+ </target>
+
+ <target name="testIfTrue" depends="setUp">
+ <property name="if" value="true"/>
+ <cp/>
+ <au:assertFileExists file="${output}/A"/>
+ <au:assertFileDoesntExist file="${output}/B"/>
+ <au:assertFileExists file="${output}/C"/>
+ <au:assertFileDoesntExist file="${output}/D"/>
+ </target>
+
+ <target name="testIfFalse" depends="setUp">
+ <property name="if" value="false"/>
+ <cp/>
+ <au:assertFileDoesntExist file="${output}/A"/>
+ <au:assertFileExists file="${output}/B"/>
+ <au:assertFileExists file="${output}/C"/>
+ <au:assertFileDoesntExist file="${output}/D"/>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/propertyset-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/propertyset-test.xml
new file mode 100644
index 00000000..0b7e236c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/propertyset-test.xml
@@ -0,0 +1,125 @@
+<?xml version="1.0"?>
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+-->
+
+<project name="test-propertyset" basedir="." default="antunit"
+ xmlns:au="antlib:org.apache.ant.antunit">
+
+ <import file="../antunit-base.xml" />
+
+ <property name="fooA" value="FooA"/>
+ <property name="barB" value="BarB"/>
+
+ <propertyset id="properties-starting-with-foo">
+ <propertyref prefix="foo"/>
+ </propertyset>
+ <propertyset id="properties-starting-with-bar">
+ <propertyref prefix="bar"/>
+ </propertyset>
+ <propertyset id="my-set">
+ <propertyset refid="properties-starting-with-foo"/>
+ <propertyset refid="properties-starting-with-bar"/>
+ </propertyset>
+
+ <macrodef name="expect.equals">
+ <attribute name="test"/>
+ <attribute name="exp"/>
+ <attribute name="got"/>
+ <sequential>
+ <fail message=
+ "@{test} failed: expected &quot;@{exp}&quot; got &quot;@{got}&quot;">
+ <condition>
+ <not>
+ <equals arg1="@{exp}" arg2="@{got}"/>
+ </not>
+ </condition>
+ </fail>
+ </sequential>
+ </macrodef>
+
+ <target name="test-reference-to-two-references">
+ <expect.equals
+ test="reference to two references"
+ exp="barB=BarB, fooA=FooA"
+ got="${toString:my-set}"/>
+ </target>
+
+ <target name="test-nested-mapped">
+ <propertyset id="nested-mapped">
+ <propertyset>
+ <propertyset refid="properties-starting-with-foo"/>
+ <globmapper from="foo*" to="boo*" />
+ </propertyset>
+ <propertyset>
+ <propertyset refid="properties-starting-with-bar"/>
+ <globmapper from="bar*" to="far*" />
+ </propertyset>
+ </propertyset>
+ <expect.equals
+ test="nested mapped propertysets"
+ exp="booA=FooA, farB=BarB"
+ got="${toString:nested-mapped}"/>
+ </target>
+
+ <target name="test-nested-mapped-mapped">
+ <propertyset id="nested-mapped-mapped">
+ <propertyset>
+ <propertyset refid="properties-starting-with-foo"/>
+ <globmapper from="foo*" to="boo*" />
+ </propertyset>
+ <propertyset>
+ <propertyset refid="properties-starting-with-bar"/>
+ <globmapper from="bar*" to="far*" />
+ </propertyset>
+ <mapper>
+ <globmapper from="boo*" to="hoo*" />
+ <globmapper from="far*" to="near*" />
+ </mapper>
+ </propertyset>
+ <expect.equals
+ test="nested mapped propertysets"
+ exp="hooA=FooA, nearB=BarB"
+ got="${toString:nested-mapped-mapped}"/>
+ </target>
+
+ <target name="testResources">
+ <au:assertTrue>
+ <resourcecount count="2">
+ <restrict>
+ <exists />
+ <resources refid="my-set" />
+ </restrict>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testMappedResources">
+ <au:assertTrue>
+ <resourcecount count="2">
+ <restrict>
+ <exists />
+ <propertyset>
+ <propertyset refid="my-set" />
+ <globmapper from="bar*" to="far*" />
+ </propertyset>
+ </restrict>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/resources/archives-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/resources/archives-test.xml
new file mode 100644
index 00000000..961effc7
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/resources/archives-test.xml
@@ -0,0 +1,136 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="antunit" xmlns:au="antlib:org.apache.ant.antunit">
+
+ <import file="../../antunit-base.xml"/>
+
+ <target name="testExtractJars">
+ <mkdir dir="${output}"/>
+ <copy todir="${output}">
+ <archives>
+ <zips>
+ <fileset dir="${ant.home}/lib"
+ includes="ant-*.jar"/>
+ </zips>
+ </archives>
+ </copy>
+ <au:assertFileExists
+ file="${output}/org/apache/tools/ant/launch/Launcher.class"/>
+ <au:assertFileExists
+ file="${output}/org/apache/tools/ant/BuildFileTest.class"/>
+ </target>
+
+ <target name="testMixingZipsAndTars">
+ <mkdir dir="${output}"/>
+ <tar destfile="${output}/test.tar.gz" compression="gzip">
+ <fileset file="${ant.file}"/>
+ </tar>
+ <copy todir="${output}">
+ <archives>
+ <zips>
+ <fileset dir="${ant.home}/lib"
+ includes="ant-launcher.jar"/>
+ </zips>
+ <tars>
+ <gzipresource>
+ <file file="${output}/test.tar.gz"/>
+ </gzipresource>
+ </tars>
+ </archives>
+ </copy>
+ <au:assertFileExists
+ file="${output}/org/apache/tools/ant/launch/Launcher.class"/>
+ <basename property="filename" file="${ant.file}"/>
+ <au:assertFileExists file="${output}/${filename}"/>
+ </target>
+
+ <target name="testReference">
+ <mkdir dir="${output}"/>
+ <archives id="ref">
+ <zips>
+ <fileset dir="${ant.home}/lib"
+ includes="ant-launcher.jar"/>
+ </zips>
+ </archives>
+ <copy todir="${output}">
+ <archives refid="ref"/>
+ </copy>
+ <au:assertFileExists
+ file="${output}/org/apache/tools/ant/launch/Launcher.class"/>
+ </target>
+
+ <target name="testCircularReference">
+ <au:expectfailure
+ message="This data type contains a circular reference.">
+ <copy todir="${output}">
+ <archives id="ref">
+ <zips>
+ <archives refid="ref"/>
+ </zips>
+ </archives>
+ </copy>
+ </au:expectfailure>
+ <au:expectfailure
+ message="This data type contains a circular reference.">
+ <copy todir="${output}">
+ <archives refid="ref"/>
+ </copy>
+ </au:expectfailure>
+ </target>
+
+ <!-- works but takes a veeeeeery long time -->
+ <target name="XtestResourcesManualExample">
+ <mkdir dir="${output}"/>
+ <copy todir="${output}">
+ <archives>
+ <zips>
+ <restrict>
+ <path path="${java.class.path}"/>
+ <name name="*.jar"/>
+ </restrict>
+ </zips>
+ </archives>
+ </copy>
+ <au:assertFileExists
+ file="${output}/org/apache/tools/ant/launch/Launcher.class"/>
+ </target>
+
+ <target name="testZipManualExample">
+ <mkdir dir="${output}/control"/>
+ <mkdir dir="${input}/htdocs/manual"/>
+ <touch file="${input}/htdocs/manual/foo.txt"/>
+ <zip destfile="${input}/examples-a.zip">
+ <fileset dir="." includes="*.xml"/>
+ </zip>
+ <zip destfile="${output}/manual.zip">
+ <mappedresources>
+ <fileset dir="${input}/htdocs/manual"/>
+ <globmapper from="*" to="docs/user-guide/*"/>
+ </mappedresources>
+ <archives>
+ <zips>
+ <fileset dir="${input}" includes="examples*.zip"/>
+ </zips>
+ </archives>
+ </zip>
+ <unzip src="${output}/manual.zip" dest="${output}/control"/>
+ <au:assertFileExists file="${output}/control/archives-test.xml"/>
+ <au:assertFileExists file="${output}/control/docs/user-guide/foo.txt"/>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/resources/comparators/test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/resources/comparators/test.xml
new file mode 100644
index 00000000..524f67a1
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/resources/comparators/test.xml
@@ -0,0 +1,299 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="antunit"
+ xmlns:au="antlib:org.apache.ant.antunit"
+ xmlns:rcmp="antlib:org.apache.tools.ant.types.resources.comparators">
+
+ <import file="../../../antunit-base.xml" />
+
+ <property name="dirname" value="work" />
+ <property name="dir" location="${output}/${dirname}" />
+ <property name="echolevel" value="debug" />
+
+ <target name="tearDown">
+ <delete dir="${dir}" />
+ <delete file="${zip}" />
+ <delete file="${jar}" deleteonexit="true" />
+ <delete file="${file}" />
+ </target>
+
+ <target name="setUp">
+ <mkdir dir="${dir}" />
+
+ <echo file="${dir}/b" message="yyy" />
+ <echo file="${dir}/e" message="aaa" />
+ <sleep seconds="2" />
+ <echo file="${dir}/c" message="x" />
+ <echo file="${dir}/d" message="x" />
+ <sleep seconds="2" />
+ <echo file="${dir}/a" message="zz" />
+ <echo file="${dir}/f" message="zz" />
+
+ <mkdir dir="${dir}/a.dir" />
+ <mkdir dir="${dir}/b.dir" />
+ <mkdir dir="${dir}/c.dir" />
+
+ <macrodef name="mysort">
+ <attribute name="property" />
+ <attribute name="separator" default="," />
+ <element name="cmp" optional="true" implicit="true" />
+ <sequential>
+ <pathconvert property="@{property}" pathsep="@{separator}">
+ <sort>
+ <fileset dir="${dir}" includes="a,b,c" />
+ <cmp />
+ </sort>
+ <flattenmapper />
+ </pathconvert>
+ <echo level="${echolevel}">@{property}=${@{property}}</echo>
+ </sequential>
+ </macrodef>
+ </target>
+
+ <target name="testsortdefault" depends="setUp">
+ <mysort property="sortdf" />
+ <au:assertTrue>
+ <equals arg1="${sortdf}" arg2="a,b,c" />
+ </au:assertTrue>
+ </target>
+
+ <target name="testrvdefault" depends="setUp">
+ <mysort property="sortdf-rev">
+ <rcmp:reverse />
+ </mysort>
+ <au:assertTrue>
+ <equals arg1="${sortdf-rev}" arg2="c,b,a" />
+ </au:assertTrue>
+ </target>
+
+ <target name="testname" depends="setUp">
+ <mysort property="sortnm">
+ <rcmp:name />
+ </mysort>
+ <au:assertTrue>
+ <equals arg1="${sortnm}" arg2="a,b,c" />
+ </au:assertTrue>
+ </target>
+
+ <target name="testrvname" depends="setUp">
+ <mysort property="sortnm-rev">
+ <rcmp:reverse>
+ <rcmp:name />
+ </rcmp:reverse>
+ </mysort>
+ <au:assertTrue>
+ <equals arg1="${sortnm-rev}" arg2="c,b,a" />
+ </au:assertTrue>
+ </target>
+
+ <target name="testdate" depends="setUp">
+ <mysort property="sortlm">
+ <rcmp:date />
+ </mysort>
+ <au:assertTrue>
+ <equals arg1="${sortlm}" arg2="b,c,a" />
+ </au:assertTrue>
+ </target>
+
+ <target name="testrvdate" depends="setUp">
+ <mysort property="sortlm-rev">
+ <rcmp:reverse>
+ <rcmp:date />
+ </rcmp:reverse>
+ </mysort>
+ <au:assertTrue>
+ <equals arg1="${sortlm-rev}" arg2="a,c,b" />
+ </au:assertTrue>
+ </target>
+
+ <target name="testsize" depends="setUp">
+ <mysort property="sortsz">
+ <rcmp:size />
+ </mysort>
+ <au:assertTrue>
+ <equals arg1="${sortsz}" arg2="c,a,b" />
+ </au:assertTrue>
+ </target>
+
+ <target name="testrvsize" depends="setUp">
+ <mysort property="sortsz-rev">
+ <rcmp:reverse>
+ <rcmp:size />
+ </rcmp:reverse>
+ </mysort>
+ <au:assertTrue>
+ <equals arg1="${sortsz-rev}" arg2="b,a,c" />
+ </au:assertTrue>
+ </target>
+
+ <target name="testcontent" depends="setUp">
+ <mysort property="sortct">
+ <rcmp:content />
+ </mysort>
+ <au:assertTrue>
+ <equals arg1="${sortct}" arg2="c,b,a" />
+ </au:assertTrue>
+ </target>
+
+ <target name="testrvcontent" depends="setUp">
+ <mysort property="sortct-rev">
+ <rcmp:reverse>
+ <rcmp:content />
+ </rcmp:reverse>
+ </mysort>
+ <au:assertTrue>
+ <equals arg1="${sortct-rev}" arg2="a,b,c" />
+ </au:assertTrue>
+ </target>
+
+ <target name="testexists" depends="setUp">
+ <pathconvert property="sortex" pathsep=",">
+ <sort>
+ <resources>
+ <file file="${dir}/a" />
+ <resource name="redherring" exists="false" />
+ </resources>
+ <rcmp:exists />
+ </sort>
+ <flattenmapper />
+ </pathconvert>
+ <au:assertTrue>
+ <equals arg1="${sortex}" arg2="redherring,a" />
+ </au:assertTrue>
+ </target>
+
+ <target name="testrvexists" depends="setUp">
+ <pathconvert property="sortex-rev" pathsep=",">
+ <sort>
+ <resources>
+ <file file="${dir}/a" />
+ <resource name="redherring" exists="false" />
+ </resources>
+ <rcmp:reverse>
+ <rcmp:exists />
+ </rcmp:reverse>
+ </sort>
+ <flattenmapper />
+ </pathconvert>
+ <au:assertTrue>
+ <equals arg1="${sortex-rev}" arg2="a,redherring" />
+ </au:assertTrue>
+ </target>
+
+ <target name="testtype" depends="setUp">
+ <pathconvert property="sorttp" pathsep=",">
+ <sort>
+ <resources>
+ <file file="${dir}/a" />
+ <file file="${dir}/a.dir" />
+ </resources>
+ <rcmp:type />
+ </sort>
+ <flattenmapper />
+ </pathconvert>
+ <au:assertPropertyEquals name="sorttp" value="a,a.dir" />
+ </target>
+
+ <target name="testrvtype" depends="setUp">
+ <pathconvert property="sorttp-rev" pathsep=",">
+ <sort>
+ <resources>
+ <file file="${dir}/a" />
+ <file file="${dir}/a.dir" />
+ </resources>
+ <rcmp:reverse>
+ <rcmp:type />
+ </rcmp:reverse>
+ </sort>
+ <flattenmapper />
+ </pathconvert>
+ <au:assertTrue>
+ <equals arg1="${sorttp-rev}" arg2="a.dir,a" />
+ </au:assertTrue>
+ </target>
+
+ <target name="forwardsort"
+ depends="testsortdefault,testname,testdate,testsize,testcontent,testexists,testtype" />
+
+ <target name="reversesort"
+ depends="testrvdefault,testrvname,testrvdate,testrvsize,testrvcontent,testrvexists,testrvtype" />
+
+ <target name="testcompoundsort1" depends="setUp">
+ <pathconvert property="sortcmp1" pathsep=",">
+ <sort>
+ <resources>
+ <file file="${dir}/c" />
+ <file file="${dir}/b.dir" />
+ <file file="${dir}/a" />
+ <file file="${dir}/c.dir" />
+ <file file="${dir}/b" />
+ <file file="${dir}/a.dir" />
+ </resources>
+ <rcmp:reverse>
+ <rcmp:type />
+ </rcmp:reverse>
+ <rcmp:name />
+ </sort>
+ <flattenmapper />
+ </pathconvert>
+ <au:assertPropertyEquals name="sortcmp1" value="a.dir,b.dir,c.dir,a,b,c" />
+ </target>
+
+ <target name="testcompoundsort2" depends="setUp">
+ <pathconvert property="sortcmp2" pathsep=",">
+ <sort>
+ <fileset dir="${dir}" includes="?"/>
+ <rcmp:size />
+ <rcmp:content />
+ <rcmp:reverse>
+ <rcmp:name />
+ </rcmp:reverse>
+ </sort>
+ <flattenmapper />
+ </pathconvert>
+ <au:assertPropertyEquals name="sortcmp2" value="d,c,f,a,e,b" />
+ </target>
+
+ <target name="compoundsort" depends="testcompoundsort1,testcompoundsort2" />
+
+ <target name="sort" depends="forwardsort,reversesort,compoundsort" />
+
+ <target name="testEquals">
+ <!-- test for PR 46527 -->
+ <sort id="testEquals">
+ <resources>
+ <string>foo</string>
+ <string>foo</string>
+ <string>foo</string>
+ </resources>
+ </sort>
+
+ <au:assertTrue>
+ <resourcecount refid="testEquals" count="3" />
+ </au:assertTrue>
+
+ <pathconvert refid="testEquals" property="testEquals" pathsep="" preserveduplicates="true">
+ <mergemapper to="X" />
+ </pathconvert>
+
+ <au:assertTrue>
+ <length string="${testEquals}" length="3" />
+ </au:assertTrue>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/resources/concat-resource-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/resources/concat-resource-test.xml
new file mode 100644
index 00000000..554c13d2
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/resources/concat-resource-test.xml
@@ -0,0 +1,160 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<project name="test-concat" basedir="." default="antunit"
+ xmlns:au="antlib:org.apache.ant.antunit">
+
+ <import file="../../antunit-base.xml" />
+
+ <property name="br" value="${line.separator}" />
+ <property name="world" value="World" />
+
+ <target name="testCountEquals1">
+ <au:assertTrue>
+ <resourcecount count="1">
+ <concat>Hello, ${world}!</concat>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testReplacement">
+ <au:assertTrue>
+ <resourcesmatch>
+ <string>Hello, ${world}!</string>
+ <concat>Hello, ${world}!</concat>
+ </resourcesmatch>
+ </au:assertTrue>
+ </target>
+
+ <target name="testResources">
+ <au:assertTrue>
+ <resourcesmatch>
+ <string>foobarbaz</string>
+ <concat>
+ <string value="foo" />
+ <string value="bar" />
+ <string value="baz" />
+ </concat>
+ </resourcesmatch>
+ </au:assertTrue>
+ </target>
+
+ <target name="testFixLastLineResources">
+ <au:assertTrue>
+ <resourcesmatch>
+ <string>foo${line.separator}bar${line.separator}baz${line.separator}</string>
+ <concat fixlastline="true">
+ <string value="foo" />
+ <string value="bar" />
+ <string value="baz" />
+ </concat>
+ </resourcesmatch>
+ </au:assertTrue>
+ </target>
+
+ <target name="testEncoding">
+ <mkdir dir="${output}"/>
+ <copy file="utf-16.in" toDir="${output}" encoding="utf-16">
+ <filterchain>
+ <fixcrlf/>
+ </filterchain>
+ </copy>
+ <au:assertTrue>
+ <resourcesmatch astext="true">
+ <file file="${output}/utf-16.in" />
+ <concat outputEncoding="utf-16">foo${br}bar${br}baz${br}</concat>
+ <concat outputEncoding="utf-16" fixlastline="true">
+ <string value="foo" />
+ <string value="bar" />
+ <string value="baz" />
+ </concat>
+ </resourcesmatch>
+ </au:assertTrue>
+ </target>
+
+ <target name="testFiltering">
+ <au:assertTrue>
+ <resourcesmatch astext="true">
+ <concat>foo${br}bar${br}baz${br}</concat>
+ <concat>
+foo
+#comment 1
+bar
+#comment 2
+baz
+#comment 3
+ <filterchain>
+ <striplinecomments>
+ <comment value="#" />
+ </striplinecomments>
+ <ignoreblank />
+ </filterchain>
+ </concat>
+ </resourcesmatch>
+ </au:assertTrue>
+ </target>
+
+ <target name="testReference">
+ <resources id="concat">
+ <concat>foo</concat>
+ </resources>
+ <au:assertTrue>
+ <and>
+ <resourcecount count="1" refid="concat" />
+ <resourcesmatch>
+ <string>foo</string>
+ <resources refid="concat" />
+ <!-- purposely hit it twice to see what happens -->
+ <resources refid="concat" />
+ </resourcesmatch>
+ </and>
+ </au:assertTrue>
+ </target>
+
+ <target name="testNonexistent">
+ <au:assertTrue>
+ <resourcesmatch>
+ <string>foobar</string>
+ <concat>
+ <string>foo</string>
+ <propertyresource name="someunsetproperty" />
+ <string>bar</string>
+ </concat>
+ </resourcesmatch>
+ </au:assertTrue>
+ </target>
+
+ <target name="testResourceName">
+ <au:assertTrue>
+ <resourcecount count="1">
+ <restrict>
+ <name name="snicklefritz" />
+ <resources>
+ <concat resourceName="snicklefritz">
+ whatever
+ </concat>
+ <concat>
+ whatever
+ </concat>
+ </resources>
+ </restrict>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/resources/fileresource-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/resources/fileresource-test.xml
new file mode 100644
index 00000000..71141193
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/resources/fileresource-test.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="antunit" xmlns:au="antlib:org.apache.ant.antunit">
+
+ <import file="../../antunit-base.xml" />
+
+ <!-- using restrict/exists to force getFile() to be called -->
+
+ <target name="testFileAsBaseline">
+ <au:assertTrue>
+ <resourcecount when="ge" count="0">
+ <restrict>
+ <exists />
+ <file name="foo" />
+ </restrict>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testNameOnly">
+ <au:assertTrue>
+ <resourcecount when="ge" count="0">
+ <restrict>
+ <exists />
+ <file name="foo" />
+ </restrict>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testNameAndBasedir">
+ <au:assertTrue>
+ <resourcecount when="ge" count="0">
+ <restrict>
+ <exists />
+ <file basedir="${basedir}" name="foo" />
+ </restrict>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/resources/files-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/resources/files-test.xml
new file mode 100644
index 00000000..447a2623
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/resources/files-test.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="files-test" default="antunit" xmlns:au="antlib:org.apache.ant.antunit">
+
+ <target name="antunit">
+ <au:antunit>
+ <au:plainlistener/>
+ <file file="${ant.file}"/>
+ </au:antunit>
+ </target>
+
+ <target name="setUp">
+ <property name="out" value="out"/>
+ </target>
+
+ <target name="tearDown">
+ <delete dir="${out}"/>
+ </target>
+
+ <target name="testEmptyReference" description="Bug43048">
+ <files id="foo"/>
+ <mkdir dir="${out}"/>
+ <copy todir="${out}">
+ <!-- threw a java.lang.NullPointerException -->
+ <files refid="foo"/>
+ </copy>
+ </target>
+
+ <target name="testEmptyFiles" description="Bug43048">
+ <mkdir dir="${out}"/>
+ <copy todir="${out}">
+ <files/>
+ </copy>
+ </target>
+
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/resources/first-last-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/resources/first-last-test.xml
new file mode 100644
index 00000000..e7fc831b
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/resources/first-last-test.xml
@@ -0,0 +1,280 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project xmlns:au="antlib:org.apache.ant.antunit" default="antunit">
+
+ <import file="../../antunit-base.xml" />
+
+ <tokens id="testrc">
+ <string value="1,2,3,4,5" />
+ <stringtokenizer delims="," />
+ </tokens>
+
+ <target name="testfirst0">
+ <au:assertTrue>
+ <resourcecount count="0">
+ <first count="0"><resources refid="testrc" /></first>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testfirst1">
+ <au:assertTrue>
+ <resourcecount count="0">
+ <difference>
+ <first><resources refid="testrc" /></first>
+ <string value="1" />
+ </difference>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testfirst2">
+ <au:assertTrue>
+ <resourcecount count="0">
+ <difference>
+ <first count="2"><resources refid="testrc" /></first>
+ <resources>
+ <string value="1" />
+ <string value="2" />
+ </resources>
+ </difference>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testfirst5">
+ <au:assertTrue>
+ <resourcecount count="0">
+ <difference>
+ <first count="5"><resources refid="testrc" /></first>
+ <resources refid="testrc" />
+ </difference>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testfirst6">
+ <au:assertTrue>
+ <resourcecount count="0">
+ <difference>
+ <first count="6"><resources refid="testrc" /></first>
+ <resources refid="testrc" />
+ </difference>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testfirst-1">
+ <au:expectfailure expectedmessage="size-limited collection count should be set to an int &gt;= 0">
+ <resourcecount>
+ <first count="-1"><resources refid="testrc" /></first>
+ </resourcecount>
+ </au:expectfailure>
+ </target>
+
+ <target name="testlast0">
+ <au:assertTrue>
+ <resourcecount count="0">
+ <last count="0"><resources refid="testrc" /></last>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testlast1">
+ <au:assertTrue>
+ <resourcecount count="0">
+ <difference>
+ <last><resources refid="testrc" /></last>
+ <string value="5" />
+ </difference>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testlast2">
+ <au:assertTrue>
+ <resourcecount count="0">
+ <difference>
+ <last count="2"><resources refid="testrc" /></last>
+ <resources>
+ <string value="4" />
+ <string value="5" />
+ </resources>
+ </difference>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testlast5">
+ <au:assertTrue>
+ <resourcecount count="0">
+ <difference>
+ <last count="5"><resources refid="testrc" /></last>
+ <resources refid="testrc" />
+ </difference>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testlast6">
+ <au:assertTrue>
+ <resourcecount count="0">
+ <difference>
+ <last count="6"><resources refid="testrc" /></last>
+ <resources refid="testrc" />
+ </difference>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testlast-1">
+ <au:expectfailure expectedmessage="size-limited collection count should be set to an int &gt;= 0">
+ <resourcecount>
+ <last count="-1"><resources refid="testrc" /></last>
+ </resourcecount>
+ </au:expectfailure>
+ </target>
+
+ <target name="testallbutfirst5">
+ <au:assertTrue>
+ <resourcecount count="0">
+ <allbutfirst count="5"><resources refid="testrc" /></allbutfirst>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testallbutfirst4">
+ <au:assertTrue>
+ <resourcecount count="0">
+ <difference>
+ <allbutfirst count="4"><resources refid="testrc" /></allbutfirst>
+ <string value="5" />
+ </difference>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testallbutfirst3">
+ <au:assertTrue>
+ <resourcecount count="0">
+ <difference>
+ <allbutfirst count="3"><resources refid="testrc" /></allbutfirst>
+ <resources>
+ <string value="4" />
+ <string value="5" />
+ </resources>
+ </difference>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testallbutfirst">
+ <au:assertTrue>
+ <resourcecount count="0">
+ <difference>
+ <allbutfirst><resources refid="testrc" /></allbutfirst>
+ <resources>
+ <string value="2" />
+ <string value="3" />
+ <string value="4" />
+ <string value="5" />
+ </resources>
+ </difference>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testallbutfirst6">
+ <au:assertTrue>
+ <resourcecount count="0">
+ <allbutfirst count="6"><resources refid="testrc" /></allbutfirst>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testallbutfirst-1">
+ <au:expectfailure expectedmessage="size-limited collection count should be set to an int &gt;= 0">
+ <resourcecount>
+ <allbutfirst count="-1"><resources refid="testrc" /></allbutfirst>
+ </resourcecount>
+ </au:expectfailure>
+ </target>
+
+ <target name="testallbutlast5">
+ <au:assertTrue>
+ <resourcecount count="0">
+ <allbutlast count="5"><resources refid="testrc" /></allbutlast>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testallbutlast4">
+ <au:assertTrue>
+ <resourcecount count="0">
+ <difference>
+ <allbutlast count="4"><resources refid="testrc" /></allbutlast>
+ <string value="1" />
+ </difference>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testallbutlast1">
+ <au:assertTrue>
+ <resourcecount count="0">
+ <difference>
+ <allbutlast><resources refid="testrc" /></allbutlast>
+ <resources>
+ <string value="1" />
+ <string value="2" />
+ <string value="3" />
+ <string value="4" />
+ </resources>
+ </difference>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testallbutlast0">
+ <au:assertTrue>
+ <resourcecount count="0">
+ <difference>
+ <allbutlast count="0"><resources refid="testrc" /></allbutlast>
+ <resources refid="testrc" />
+ </difference>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testallbutlast6">
+ <au:assertTrue>
+ <resourcecount count="0">
+ <allbutlast count="6"><resources refid="testrc" /></allbutlast>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testallbutlast-1">
+ <au:expectfailure expectedmessage="size-limited collection count should be set to an int &gt;= 0">
+ <resourcecount>
+ <allbutlast count="-1"><resources refid="testrc" /></allbutlast>
+ </resourcecount>
+ </au:expectfailure>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/resources/javaresource-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/resources/javaresource-test.xml
new file mode 100644
index 00000000..a83184d0
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/resources/javaresource-test.xml
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="antunit" xmlns:au="antlib:org.apache.ant.antunit">
+
+ <import file="../../antunit-base.xml"/>
+
+ <target name="setUp">
+ <mkdir dir="${output}"/>
+ </target>
+
+ <target name="testUsesSystemClasspath" depends="setUp">
+ <copy todir="${output}">
+ <javaresource name="org/apache/tools/ant/antlib.xml"/>
+ </copy>
+ <au:assertFileExists file="${output}/org/apache/tools/ant/antlib.xml"/>
+ </target>
+
+ <target name="-setUpAntlibXmlInInput" depends="setUp">
+ <mkdir dir="${input}/org/apache/tools/ant"/>
+ <echo file="${input}/org/apache/tools/ant/antlib.xml">Hello, world!</echo>
+ </target>
+
+ <target name="testParentFirstIsDefault" depends="-setUpAntlibXmlInInput">
+ <copy todir="${output}">
+ <javaresource name="org/apache/tools/ant/antlib.xml">
+ <classpath location="${input}"/>
+ </javaresource>
+ </copy>
+ <au:assertFileExists file="${output}/org/apache/tools/ant/antlib.xml"/>
+ <au:assertFilesDiffer
+ expected="${input}/org/apache/tools/ant/antlib.xml"
+ actual="${output}/org/apache/tools/ant/antlib.xml"/>
+ </target>
+
+ <target name="testParentFirstFalse" depends="-setUpAntlibXmlInInput" unless="build.sysclasspath.only">
+ <copy todir="${output}">
+ <javaresource name="org/apache/tools/ant/antlib.xml"
+ parentFirst="false">
+ <classpath location="${input}"/>
+ </javaresource>
+ </copy>
+ <au:assertFileExists file="${output}/org/apache/tools/ant/antlib.xml"/>
+ <au:assertFilesMatch
+ expected="${input}/org/apache/tools/ant/antlib.xml"
+ actual="${output}/org/apache/tools/ant/antlib.xml"/>
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/resources/latepath-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/resources/latepath-test.xml
new file mode 100644
index 00000000..5cafffde
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/resources/latepath-test.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project xmlns:au="antlib:org.apache.ant.antunit">
+
+ <target name="testLatePath" depends="tearDown">
+ <path id="p">
+ <fileset file="testLatePath" />
+ </path>
+ <pathconvert refid="p" />
+ <touch file="testLatePath" />
+ <au:assertTrue>
+ <resourcecount when="eq" count="1" refid="p" />
+ </au:assertTrue>
+ </target>
+
+ <target name="tearDown">
+ <delete file="testLatePath" />
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/resources/multirootfileset-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/resources/multirootfileset-test.xml
new file mode 100644
index 00000000..27b6193e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/resources/multirootfileset-test.xml
@@ -0,0 +1,166 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project xmlns:au="antlib:org.apache.ant.antunit" default="antunit">
+
+ <import file="../../antunit-base.xml"/>
+
+ <target name="setUp">
+ <property name="a" location="${input}/a"/>
+ <property name="b" location="${input}/b"/>
+ <touch mkdirs="true" file="${a}/1/1.txt"/>
+ <touch mkdirs="true" file="${a}/1/2.txt"/>
+ <touch mkdirs="true" file="${a}/1/3.txt"/>
+ <touch mkdirs="true" file="${b}/2/3.txt"/>
+ <touch mkdirs="true" file="${b}/2/4.txt"/>
+ <mkdir dir="${output}"/>
+ </target>
+
+ <target name="test-count-in-simple-configuration" depends="setUp">
+ <resourcecount property="files">
+ <multirootfileset basedirs="${a},${b}"/>
+ </resourcecount>
+ <resourcecount property="dirs">
+ <multirootfileset basedirs="${a},${b}" type="dir"/>
+ </resourcecount>
+ <resourcecount property="files-and-dirs">
+ <multirootfileset basedirs="${a},${b}" type="both"/>
+ </resourcecount>
+ <au:assertPropertyEquals value="5" name="files"/>
+ <au:assertPropertyEquals value="4" name="dirs"/>
+ <au:assertPropertyEquals value="9" name="files-and-dirs"/>
+ </target>
+
+ <target name="test-count-nested-basedir-elements" depends="setUp">
+ <resourcecount property="files">
+ <multirootfileset>
+ <basedir file="${a}"/>
+ <basedir file="${b}"/>
+ </multirootfileset>
+ </resourcecount>
+ <resourcecount property="dirs">
+ <multirootfileset type="dir">
+ <basedir file="${a}"/>
+ <basedir file="${b}"/>
+ </multirootfileset>
+ </resourcecount>
+ <resourcecount property="files-and-dirs">
+ <multirootfileset type="both">
+ <basedir file="${a}"/>
+ <basedir file="${b}"/>
+ </multirootfileset>
+ </resourcecount>
+ <au:assertPropertyEquals value="5" name="files"/>
+ <au:assertPropertyEquals value="4" name="dirs"/>
+ <au:assertPropertyEquals value="9" name="files-and-dirs"/>
+ </target>
+
+ <target name="test-copying" depends="setUp">
+ <copy todir="${output}">
+ <multirootfileset basedirs="${a},${b}"/>
+ </copy>
+ <au:assertFileExists file="${output}/1/1.txt"/>
+ <au:assertFileExists file="${output}/1/2.txt"/>
+ <au:assertFileExists file="${output}/1/3.txt"/>
+ <au:assertFileExists file="${output}/2/3.txt"/>
+ <au:assertFileExists file="${output}/2/4.txt"/>
+ </target>
+
+ <target name="test-dirs" depends="setUp">
+ <pathconvert property="dirs" pathsep=":">
+ <multirootfileset basedirs="${a},${b}" type="dir"/>
+ </pathconvert>
+ <au:assertPropertyEquals value="${a}:${a}${file.separator}1:${b}:${b}${file.separator}2"
+ name="dirs"/>
+ </target>
+
+ <target name="test-include-pattern" depends="setUp">
+ <copy todir="${output}">
+ <multirootfileset basedirs="${a},${b}">
+ <include name="**/3.txt"/>
+ </multirootfileset>
+ </copy>
+ <au:assertFileDoesntExist file="${output}/1/1.txt"/>
+ <au:assertFileExists file="${output}/1/3.txt"/>
+ <au:assertFileExists file="${output}/2/3.txt"/>
+ <au:assertFileDoesntExist file="${output}/2/4.txt"/>
+ <pathconvert property="dirs" pathsep=":">
+ <multirootfileset basedirs="${a},${b}" type="dir">
+ <include name="1/"/>
+ </multirootfileset>
+ </pathconvert>
+ <au:assertPropertyEquals value="${a}${file.separator}1" name="dirs"/>
+ </target>
+
+ <target name="test-exclude-pattern" depends="setUp">
+ <copy todir="${output}">
+ <multirootfileset basedirs="${a},${b}">
+ <exclude name="**/3.txt"/>
+ </multirootfileset>
+ </copy>
+ <au:assertFileExists file="${output}/1/1.txt"/>
+ <au:assertFileDoesntExist file="${output}/1/3.txt"/>
+ <au:assertFileDoesntExist file="${output}/2/3.txt"/>
+ <au:assertFileExists file="${output}/2/4.txt"/>
+ <pathconvert property="dirs" pathsep=":">
+ <multirootfileset basedirs="${a},${b}" type="dir">
+ <exclude name="1/"/>
+ </multirootfileset>
+ </pathconvert>
+ <au:assertPropertyEquals value="${a}:${b}:${b}${file.separator}2"
+ name="dirs"/>
+ </target>
+
+ <target name="test-selectors" depends="setUp">
+ <copy todir="${output}">
+ <multirootfileset basedirs="${a},${b}">
+ <filename regex=".*3\.txt"/>
+ </multirootfileset>
+ </copy>
+ <au:assertFileDoesntExist file="${output}/1/1.txt"/>
+ <au:assertFileExists file="${output}/1/3.txt"/>
+ <au:assertFileExists file="${output}/2/3.txt"/>
+ <au:assertFileDoesntExist file="${output}/2/4.txt"/>
+ <pathconvert property="dirs" pathsep=":">
+ <multirootfileset basedirs="${a},${b}" type="dir">
+ <filename regex="1"/>
+ </multirootfileset>
+ </pathconvert>
+ <au:assertPropertyEquals value="${a}${file.separator}1" name="dirs"/>
+ </target>
+
+ <target name="test-cache-false" depends="setUp">
+ <copy todir="${output}">
+ <multirootfileset basedirs="${a},${b}" cache="false">
+ <filename regex=".*3\.txt"/>
+ </multirootfileset>
+ </copy>
+ <au:assertFileDoesntExist file="${output}/1/1.txt"/>
+ <au:assertFileExists file="${output}/1/3.txt"/>
+ <au:assertFileExists file="${output}/2/3.txt"/>
+ <au:assertFileDoesntExist file="${output}/2/4.txt"/>
+ <multirootfileset basedirs="${a},${b}" type="dir" cache="false"
+ id="the-one-dirs">
+ <filename regex="1"/>
+ </multirootfileset>
+ <pathconvert property="dirs" pathsep=":" refid="the-one-dirs"/>
+ <au:assertPropertyEquals value="${a}${file.separator}1" name="dirs"/>
+ <resourcecount property="dir-count" refid="the-one-dirs" />
+ <au:assertPropertyEquals value="1" name="dir-count"/>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/resources/resourcelist-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/resources/resourcelist-test.xml
new file mode 100644
index 00000000..33577476
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/resources/resourcelist-test.xml
@@ -0,0 +1,104 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<project name="test-concat" basedir="." default="antunit"
+ xmlns:au="antlib:org.apache.ant.antunit">
+
+ <import file="../../antunit-base.xml" />
+
+ <target name="setUp">
+ <mkdir dir="${input}"/>
+ <mkdir dir="${output}"/>
+ <touch file="${input}/b.txt"/>
+ </target>
+
+ <target name="testBasicOperation" depends="setUp">
+ <echo file="${input}/a.txt">${input}/b.txt
+${input}/c.txt</echo>
+ <property name="c" location="${input}/c.txt"/>
+ <au:expectfailure expectedmessage="Could not find resource file &quot;${c}&quot;">
+ <copy todir="${output}" flatten="true">
+ <resourcelist>
+ <file file="${input}/a.txt"/>
+ </resourcelist>
+ </copy>
+ </au:expectfailure>
+ <copy todir="${output}" flatten="true">
+ <restrict>
+ <resourcelist>
+ <file file="${input}/a.txt"/>
+ </resourcelist>
+ <exists/>
+ </restrict>
+ </copy>
+ <au:assertFileExists file="${output}/b.txt"/>
+ <au:assertFileDoesntExist file="${output}/c.txt"/>
+ </target>
+
+ <target name="testExpandsProperties" depends="setUp">
+ <echo file="${input}/a.txt">$${input}/b.txt</echo>
+ <copy todir="${output}" flatten="true">
+ <resourcelist>
+ <file file="${input}/a.txt"/>
+ </resourcelist>
+ </copy>
+ <au:assertFileExists file="${output}/b.txt"/>
+ </target>
+
+ <target name="testFilterChain" depends="setUp">
+ <echo file="${input}/a.txt">b.txt</echo>
+ <au:expectfailure expectedmessage="Could not find resource file">
+ <copy todir="${output}" flatten="true">
+ <resourcelist>
+ <file file="${input}/a.txt"/>
+ </resourcelist>
+ </copy>
+ </au:expectfailure>
+ <copy todir="${output}" flatten="true">
+ <resourcelist>
+ <file file="${input}/a.txt"/>
+ <filterchain>
+ <prefixlines prefix="${input}/"/>
+ </filterchain>
+ </resourcelist>
+ </copy>
+ <au:assertFileExists file="${output}/b.txt"/>
+ </target>
+
+ <target name="testPropertyExpandsToObject" depends="setUp">
+ <file file="${ant.file}" id="self"/>
+ <echo file="${input}/a.txt">$${ant.refid:self}</echo>
+ <copy todir="${output}" flatten="true">
+ <resourcelist>
+ <file file="${input}/a.txt"/>
+ </resourcelist>
+ </copy>
+ <au:assertFileExists file="${output}/resourcelist-test.xml"/>
+ </target>
+
+ <target name="testReadsURLs" depends="setUp">
+ <makeurl file="${ant.core.lib}" property="ant.jar"/>
+ <echo file="${input}/a.txt">jar:${ant.jar}!/org/apache/tools/ant/antlib.xml</echo>
+ <copy todir="${output}" flatten="true">
+ <resourcelist>
+ <file file="${input}/a.txt"/>
+ </resourcelist>
+ </copy>
+ <au:assertFileExists file="${output}/antlib.xml"/>
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/resources/resources-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/resources/resources-test.xml
new file mode 100644
index 00000000..19985c72
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/resources/resources-test.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="antunit" xmlns:au="antlib:org.apache.ant.antunit">
+
+ <import file="../../antunit-base.xml"/>
+
+ <target name="testToString"
+ description="https://issues.apache.org/bugzilla/show_bug.cgi?id=49588">
+ <resources id="A">
+ <string value="b"/>
+ </resources>
+ <union id="union"><resources refid="A"/></union>
+ <au:assertEquals expected="b" actual="${toString:A}"/>
+ <au:assertEquals expected="b" actual="${toString:union}"/>
+ <au:assertEquals expected="b" actual="${toString:A}"/>
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/resources/selectors/name-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/resources/selectors/name-test.xml
new file mode 100644
index 00000000..84cbedb4
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/resources/selectors/name-test.xml
@@ -0,0 +1,90 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project xmlns:au="antlib:org.apache.ant.antunit" default="antunit">
+
+ <import file="../../../antunit-base.xml" />
+
+ <property name="file" value="testfile"/>
+
+ <target name="createTestdir">
+ <mkdir dir="${output}"/>
+ <touch file="${output}/${file}"/>
+ </target>
+
+ <target name="testPattern" depends="createTestdir">
+ <au:assertTrue>
+ <resourcecount when="equal" count="1">
+ <restrict>
+ <fileset dir="${output}"/>
+ <name name="*"/>
+ </restrict>
+ </resourcecount>
+ </au:assertTrue>
+ <au:assertTrue>
+ <resourcecount when="equal" count="0">
+ <restrict>
+ <fileset dir="${output}"/>
+ <name name=".*"/>
+ </restrict>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testRegex" depends="createTestdir">
+ <au:assertTrue>
+ <resourcecount when="equal" count="1">
+ <restrict>
+ <fileset dir="${output}"/>
+ <name regex=".*"/>
+ </restrict>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testHandledirSep" depends="createTestdir">
+ <au:assertTrue>
+ <!-- only one should match the current platform -->
+ <resourcecount when="equal" count="1">
+ <resources>
+ <restrict>
+ <fileset dir="${output}"/>
+ <name name="**/${file}"/>
+ </restrict>
+ <restrict>
+ <fileset dir="${output}"/>
+ <name name="**\${file}"/>
+ </restrict>
+ </resources>
+ </resourcecount>
+ </au:assertTrue>
+ <au:assertTrue>
+ <resourcecount when="equal" count="2">
+ <resources>
+ <restrict>
+ <fileset dir="${output}"/>
+ <name name="**/${file}" handleDirSep="true"/>
+ </restrict>
+ <restrict>
+ <fileset dir="${output}"/>
+ <name name="**\${file}" handleDirSep="true"/>
+ </restrict>
+ </resources>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/resources/selectors/readwrite-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/resources/selectors/readwrite-test.xml
new file mode 100644
index 00000000..6a0301ba
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/resources/selectors/readwrite-test.xml
@@ -0,0 +1,106 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project xmlns:au="antlib:org.apache.ant.antunit" default="antunit"
+ xmlns:rsel="antlib:org.apache.tools.ant.types.resources.selectors">
+
+ <import file="../../../antunit-base.xml" />
+
+ <property name="dir" location="testdir"/>
+ <property name="file" value="testfile"/>
+
+ <condition property="unix">
+ <os family="unix"/>
+ </condition>
+
+ <target name="createTestdir">
+ <mkdir dir="${output}"/>
+ <touch file="${output}/${file}"/>
+ </target>
+
+ <target name="testReadable" depends="createTestdir">
+ <au:assertTrue>
+ <resourcecount when="equal" count="1">
+ <restrict>
+ <fileset dir="${output}"/>
+ <rsel:readable/>
+ </restrict>
+ </resourcecount>
+ </au:assertTrue>
+ <au:assertTrue>
+ <resourcecount when="equal" count="0">
+ <restrict>
+ <fileset dir="${output}" excludes="${file}"/>
+ <rsel:readable/>
+ </restrict>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testWritable" depends="createTestdir">
+ <au:assertTrue>
+ <resourcecount when="equal" count="1">
+ <restrict>
+ <fileset dir="${output}"/>
+ <rsel:writable/>
+ </restrict>
+ </resourcecount>
+ </au:assertTrue>
+ <au:assertTrue>
+ <resourcecount when="equal" count="0">
+ <restrict>
+ <fileset dir="${output}" excludes="${file}"/>
+ <rsel:writable/>
+ </restrict>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="makeFileUnwritable"
+ depends="createTestdir,makeFileUnwritable-Unix,makeFileUnwritable-Windows"/>
+ <target name="makeFileUnwritable-Unix" id="unix">
+ <chmod file="${output}/${file}" perm="444"/>
+ </target>
+ <target name="makeFileUnwritable-Windows" unless="unix">
+ <attrib file="${output}/${file}" readonly="true"/>
+ </target>
+
+ <target name="testUnwritable" depends="makeFileUnwritable">
+ <au:assertTrue>
+ <resourcecount when="equal" count="0">
+ <restrict>
+ <fileset dir="${output}"/>
+ <rsel:writable/>
+ </restrict>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testAsConditions" depends="makeFileUnwritable">
+ <au:assertTrue>
+ <isfileselected file="${output}/${file}">
+ <rsel:readable/>
+ </isfileselected>
+ </au:assertTrue>
+ <au:assertFalse>
+ <isfileselected file="${output}/${file}">
+ <rsel:writable/>
+ </isfileselected>
+ </au:assertFalse>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/resources/selectors/test-componentdef.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/resources/selectors/test-componentdef.xml
new file mode 100644
index 00000000..187412ec
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/resources/selectors/test-componentdef.xml
@@ -0,0 +1,458 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="all" xmlns:au="antlib:org.apache.ant.antunit">
+
+ <available property="jdk1.4+" classname="java.lang.CharSequence"/>
+ <condition property="some.regexp.support">
+ <or>
+ <isset property="jdk1.4+"/>
+ <isset property="apache.regexp.present"/>
+ <isset property="apache.oro.present"/>
+ </or>
+ </condition>
+
+ <target name="testname1">
+ <au:assertTrue>
+ <resourcecount when="equal" count="2">
+ <restrict>
+ <resources>
+ <resource name="foo" />
+ <resource name="bar" />
+ <resource name="baz" />
+ <resource name="boo" />
+ <resource name="bang" />
+ </resources>
+ <name name="ba?" />
+ </restrict>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testname2">
+ <au:assertTrue>
+ <resourcecount when="equal" count="3">
+ <restrict>
+ <resources>
+ <file file="foo" />
+ <resource name="foo" />
+ <file file="foo" basedir="${basedir}" />
+ </resources>
+ <name name="foo" />
+ </restrict>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="name" depends="testname1,testname2" />
+
+ <target name="testexists">
+ <au:assertTrue>
+ <resourcecount when="equal" count="1">
+ <restrict>
+ <resources>
+ <file file="idonotexist" />
+ <resource name="foo" />
+ <resource name="foo" exists="false" />
+ </resources>
+ <exists />
+ </restrict>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testinstanceoftype1">
+ <au:assertTrue>
+ <resourcecount when="equal" count="2">
+ <restrict>
+ <resources>
+ <file file="foo" />
+ <url url="http://ant.apache.org/index.html" />
+ <resource name="foo" />
+ <string value="foo" />
+ <file file="bar" />
+ </resources>
+ <instanceof type="file" />
+ </restrict>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testinstanceoftype2">
+ <typedef name="file" uri="test"
+ classname="org.apache.tools.ant.types.resources.FileResource" />
+ <au:assertTrue>
+ <resourcecount when="equal" count="1">
+ <restrict>
+ <resources>
+ <url file="foo" />
+ <file file="bar" xmlns="test" />
+ </resources>
+ <instanceof type="test:file" />
+ </restrict>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testinstanceoftype3">
+ <typedef name="file" uri="test"
+ classname="org.apache.tools.ant.types.resources.FileResource" />
+ <au:assertTrue>
+ <resourcecount when="equal" count="1">
+ <restrict>
+ <resources>
+ <url file="foo" />
+ <file file="bar" xmlns="test" />
+ </resources>
+ <instanceof type="file" uri="test" />
+ </restrict>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="instanceoftype"
+ depends="testinstanceoftype1,testinstanceoftype2,testinstanceoftype3" />
+
+ <target name="testinstanceofclass">
+ <au:assertTrue>
+ <resourcecount when="equal" count="7">
+ <restrict>
+ <resources>
+ <filelist dir="${basedir}" files="a,b,c,d,e,f,g" />
+ </resources>
+ <instanceof class="org.apache.tools.ant.types.Resource" />
+ </restrict>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="instanceof" depends="instanceoftype,testinstanceofclass" />
+
+ <target name="testtype">
+ <au:assertTrue>
+ <resourcecount when="equal" count="2">
+ <restrict>
+ <resources>
+ <file file="${basedir}" />
+ <file file="${ant.file}" />
+ <resource directory="true" />
+ <resource directory="false" />
+ </resources>
+ <type type="dir" />
+ </restrict>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testdate">
+ <au:assertTrue>
+ <resourcecount when="equal" count="3">
+ <restrict>
+ <resources>
+ <resource lastmodified="4" />
+ <resource lastmodified="5" />
+ <resource lastmodified="6" />
+ <resource lastmodified="7" />
+ <resource lastmodified="8" />
+ </resources>
+ <date when="after" millis="5" granularity="0" />
+ </restrict>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testsize">
+ <au:assertTrue>
+ <resourcecount when="equal" count="4">
+ <restrict>
+ <resources>
+ <resource size="4" />
+ <resource size="5" />
+ <resource size="6" />
+ <resource size="7" />
+ <resource size="8" />
+ </resources>
+ <size when="le" size="7" />
+ </restrict>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testand">
+ <au:assertTrue>
+ <resourcecount when="equal" count="1">
+ <restrict>
+ <resources>
+ <string value="fee" />
+ <resource name="fi" size="3" />
+ <resource name="fo" />
+ <resource name="fum" />
+ </resources>
+ <and xmlns="antlib:org.apache.tools.ant.types.resources.selectors">
+ <name name="f?" />
+ <size size="3" />
+ </and>
+ </restrict>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testor">
+ <au:assertTrue>
+ <resourcecount when="equal" count="3">
+ <restrict>
+ <resources>
+ <string value="fee" />
+ <resource name="fi" size="3" />
+ <resource name="fo" />
+ <resource name="fum" />
+ </resources>
+ <or xmlns="antlib:org.apache.tools.ant.types.resources.selectors">
+ <name name="f?" />
+ <size size="3" />
+ </or>
+ </restrict>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testnot">
+ <au:assertTrue>
+ <resourcecount when="equal" count="2">
+ <restrict>
+ <resources>
+ <string value="fee" />
+ <resource name="fi" size="3" />
+ <resource name="fo" />
+ <resource name="fum" />
+ </resources>
+ <not xmlns="antlib:org.apache.tools.ant.types.resources.selectors">
+ <size size="3" />
+ </not>
+ </restrict>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testnone">
+ <au:assertTrue>
+ <resourcecount when="equal" count="1">
+ <restrict>
+ <resources>
+ <string value="fee" />
+ <resource name="fi" size="3" />
+ <resource name="fo" />
+ <resource name="fum" />
+ </resources>
+ <none xmlns="antlib:org.apache.tools.ant.types.resources.selectors">
+ <name name="f?" />
+ <size size="3" />
+ </none>
+ </restrict>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testmajority1">
+ <au:assertTrue>
+ <resourcecount when="equal" count="2">
+ <restrict>
+ <resources>
+ <string value="fee" />
+ <resource name="fi" size="3" />
+ <resource name="fo" />
+ <resource name="fum" />
+ </resources>
+ <majority xmlns="antlib:org.apache.tools.ant.types.resources.selectors">
+ <name name="f?" />
+ <size size="3" />
+ <instanceof type="string" />
+ </majority>
+ </restrict>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testmajority2">
+ <au:assertTrue>
+ <resourcecount when="equal" count="3">
+ <restrict>
+ <resources>
+ <string value="fee" />
+ <resource name="fi" size="3" />
+ <resource name="fo" />
+ <resource name="fum" />
+ </resources>
+ <majority>
+ <name name="f?" />
+ <size size="3" />
+ <instanceof type="resource" />
+ </majority>
+ </restrict>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testmajority3">
+ <au:assertTrue>
+ <resourcecount when="equal" count="3">
+ <restrict>
+ <resources>
+ <string value="fee" />
+ <resource name="fi" size="3" />
+ <resource name="fo" />
+ <resource name="fum" />
+ </resources>
+ <majority allowtie="true">
+ <name name="f?" />
+ <size size="3" />
+ <instanceof type="string" />
+ <exists />
+ </majority>
+ </restrict>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testmajority4">
+ <au:assertTrue>
+ <resourcecount when="equal" count="2">
+ <restrict>
+ <resources>
+ <string value="fee" />
+ <resource name="fi" size="3" />
+ <resource name="fo" />
+ <resource name="fum" />
+ </resources>
+ <majority allowtie="false">
+ <name name="f?" />
+ <size size="3" />
+ <instanceof type="string" />
+ <exists />
+ </majority>
+ </restrict>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testcontains">
+ <au:assertTrue>
+ <resourcecount when="equal" count="2">
+ <restrict>
+ <resources>
+ <string value="foo" />
+ <string value="bar" />
+ <string value="baz" />
+ </resources>
+ <contains text="b"/>
+ </restrict>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testcontainsregexp" if="some.regexp.support">
+ <au:assertTrue>
+ <resourcecount when="equal" count="2">
+ <restrict>
+ <resources>
+ <string value="foo" />
+ <string value="bar" />
+ <string value="baz" />
+ </resources>
+ <containsregexp expression="^b..$"/>
+ </restrict>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testcompare">
+ <au:assertTrue>
+ <and>
+ <!-- basic test, natural ordering -->
+ <resourcecount count="3">
+ <restrict>
+ <compare when="greater" against="each">
+ <control><string value="b" /></control>
+ </compare>
+ <resources>
+ <string value="a" />
+ <string value="b" />
+ <string value="c" />
+ <string value="d" />
+ <string value="e" />
+ </resources>
+ </restrict>
+ </resourcecount>
+ <!-- one comparator, default when/against -->
+ <resourcecount count="5">
+ <restrict>
+ <compare>
+ <control><string value="." /></control>
+ <size />
+ </compare>
+ <resources>
+ <string value="a" />
+ <string value="b" />
+ <string value="c" />
+ <string value="d" />
+ <string value="e" />
+ </resources>
+ </restrict>
+ </resourcecount>
+ <!-- multiple controls, comparators -->
+ <resourcecount count="3">
+ <restrict>
+ <compare when="greater" against="each">
+ <control>
+ <string value="a" />
+ <string value="b" />
+ <string value="bb" />
+ <string value="c" />
+ <string value="ccc" />
+ </control>
+ <name />
+ <size />
+ </compare>
+ <resources>
+ <string value="a" />
+ <string value="bbbb" />
+ <string value="ccc" />
+ <string value="cccc" />
+ <string value="d" />
+ <string value="e" />
+ </resources>
+ </restrict>
+ </resourcecount>
+ </and>
+ </au:assertTrue>
+ </target>
+
+ <target name="majority"
+ depends="testmajority1,testmajority2,testmajority3,testmajority4" />
+
+ <target name="logical"
+ depends="testand,testor,testnone,testnot,majority" />
+
+ <target name="all"
+ depends="name,testexists,instanceof,testtype,testdate,testsize,testcontains,testcontainsregexp,logical,testcompare" />
+
+ <!--
+ The tests for oata.types.selectors.ModifiedSelectorTest as
+ ResourceSelector are in its test-buildfile src\etc\testcases\types\selectors.xml.
+ -->
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/resources/selectors/test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/resources/selectors/test.xml
new file mode 100644
index 00000000..24b804a3
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/resources/selectors/test.xml
@@ -0,0 +1,483 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="antunit" xmlns:au="antlib:org.apache.ant.antunit"
+ xmlns:rsel="antlib:org.apache.tools.ant.types.resources.selectors"
+ xmlns:rcmp="antlib:org.apache.tools.ant.types.resources.comparators">
+
+ <import file="../../../antunit-base.xml" />
+
+ <available property="jdk1.4+" classname="java.lang.CharSequence"/>
+ <condition property="some.regexp.support">
+ <or>
+ <isset property="jdk1.4+"/>
+ <isset property="apache.regexp.present"/>
+ <isset property="apache.oro.present"/>
+ </or>
+ </condition>
+
+ <target name="testname1">
+ <au:assertTrue>
+ <resourcecount when="equal" count="2">
+ <restrict>
+ <resources>
+ <resource name="foo" />
+ <resource name="bar" />
+ <resource name="baz" />
+ <resource name="boo" />
+ <resource name="bang" />
+ </resources>
+ <rsel:name name="ba?" />
+ </restrict>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testname2">
+ <au:assertTrue>
+ <resourcecount when="equal" count="3">
+ <restrict>
+ <resources>
+ <file file="foo" />
+ <resource name="foo" />
+ <file file="foo" basedir="${basedir}" />
+ </resources>
+ <rsel:name name="foo" />
+ </restrict>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="name" depends="testname1,testname2" />
+
+ <target name="testexists">
+ <au:assertTrue>
+ <resourcecount when="equal" count="1">
+ <restrict>
+ <resources>
+ <file file="idonotexist" />
+ <resource name="foo" />
+ <resource name="foo" exists="false" />
+ </resources>
+ <rsel:exists />
+ </restrict>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testinstanceoftype1">
+ <au:assertTrue>
+ <resourcecount when="equal" count="2">
+ <restrict>
+ <resources>
+ <file file="foo" />
+ <url url="http://ant.apache.org/index.html" />
+ <resource name="foo" />
+ <string value="foo" />
+ <file file="bar" />
+ </resources>
+ <rsel:instanceof type="file" />
+ </restrict>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testinstanceoftype2">
+ <typedef name="file" uri="test"
+ classname="org.apache.tools.ant.types.resources.FileResource" />
+ <au:assertTrue>
+ <resourcecount when="equal" count="1">
+ <restrict>
+ <resources>
+ <url file="foo" />
+ <file file="bar" xmlns="test" />
+ </resources>
+ <rsel:instanceof type="test:file" />
+ </restrict>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testinstanceoftype3">
+ <typedef name="file" uri="test"
+ classname="org.apache.tools.ant.types.resources.FileResource" />
+ <au:assertTrue>
+ <resourcecount when="equal" count="1">
+ <restrict>
+ <resources>
+ <url file="foo" />
+ <file file="bar" xmlns="test" />
+ </resources>
+ <rsel:instanceof type="file" uri="test" />
+ </restrict>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="instanceoftype"
+ depends="testinstanceoftype1,testinstanceoftype2,testinstanceoftype3" />
+
+ <target name="testinstanceofclass">
+ <au:assertTrue>
+ <resourcecount when="equal" count="7">
+ <restrict>
+ <resources>
+ <filelist dir="${basedir}" files="a,b,c,d,e,f,g" />
+ </resources>
+ <rsel:instanceof class="org.apache.tools.ant.types.Resource" />
+ </restrict>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="instanceof" depends="instanceoftype,testinstanceofclass" />
+
+ <target name="testtype">
+ <resources id="testtype">
+ <file file="${basedir}" />
+ <file file="${ant.file}" />
+ <resource directory="true" />
+ <resource directory="false" />
+ </resources>
+ <au:assertTrue>
+ <resourcecount when="equal" count="2">
+ <restrict>
+ <resources refid="testtype" />
+ <rsel:type type="dir" />
+ </restrict>
+ </resourcecount>
+ </au:assertTrue>
+ <au:assertTrue>
+ <resourcecount when="equal" count="2">
+ <restrict>
+ <resources refid="testtype" />
+ <rsel:type type="file" />
+ </restrict>
+ </resourcecount>
+ </au:assertTrue>
+ <au:assertTrue>
+ <resourcecount when="equal" count="4">
+ <restrict>
+ <resources refid="testtype" />
+ <rsel:type type="any" />
+ </restrict>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testdate">
+ <au:assertTrue>
+ <resourcecount when="equal" count="3">
+ <restrict>
+ <resources>
+ <resource lastmodified="4" />
+ <resource lastmodified="5" />
+ <resource lastmodified="6" />
+ <resource lastmodified="7" />
+ <resource lastmodified="8" />
+ </resources>
+ <rsel:date when="after" millis="5" granularity="0" />
+ </restrict>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testsize">
+ <au:assertTrue>
+ <resourcecount when="equal" count="4">
+ <restrict>
+ <resources>
+ <resource size="4" />
+ <resource size="5" />
+ <resource size="6" />
+ <resource size="7" />
+ <resource size="8" />
+ </resources>
+ <rsel:size when="le" size="7" />
+ </restrict>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testand">
+ <au:assertTrue>
+ <resourcecount when="equal" count="1">
+ <restrict>
+ <resources>
+ <string value="fee" />
+ <resource name="fi" size="3" />
+ <resource name="fo" />
+ <resource name="fum" />
+ </resources>
+ <and xmlns="antlib:org.apache.tools.ant.types.resources.selectors">
+ <name name="f?" />
+ <size size="3" />
+ </and>
+ </restrict>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testor">
+ <au:assertTrue>
+ <resourcecount when="equal" count="3">
+ <restrict>
+ <resources>
+ <string value="fee" />
+ <resource name="fi" size="3" />
+ <resource name="fo" />
+ <resource name="fum" />
+ </resources>
+ <or xmlns="antlib:org.apache.tools.ant.types.resources.selectors">
+ <name name="f?" />
+ <size size="3" />
+ </or>
+ </restrict>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testnot">
+ <au:assertTrue>
+ <resourcecount when="equal" count="2">
+ <restrict>
+ <resources>
+ <string value="fee" />
+ <resource name="fi" size="3" />
+ <resource name="fo" />
+ <resource name="fum" />
+ </resources>
+ <not xmlns="antlib:org.apache.tools.ant.types.resources.selectors">
+ <size size="3" />
+ </not>
+ </restrict>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testnone">
+ <au:assertTrue>
+ <resourcecount when="equal" count="1">
+ <restrict>
+ <resources>
+ <string value="fee" />
+ <resource name="fi" size="3" />
+ <resource name="fo" />
+ <resource name="fum" />
+ </resources>
+ <none xmlns="antlib:org.apache.tools.ant.types.resources.selectors">
+ <name name="f?" />
+ <size size="3" />
+ </none>
+ </restrict>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testmajority1">
+ <au:assertTrue>
+ <resourcecount when="equal" count="2">
+ <restrict>
+ <resources>
+ <string value="fee" />
+ <resource name="fi" size="3" />
+ <resource name="fo" />
+ <resource name="fum" />
+ </resources>
+ <majority xmlns="antlib:org.apache.tools.ant.types.resources.selectors">
+ <name name="f?" />
+ <size size="3" />
+ <instanceof type="string" />
+ </majority>
+ </restrict>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testmajority2">
+ <au:assertTrue>
+ <resourcecount when="equal" count="3">
+ <restrict>
+ <resources>
+ <string value="fee" />
+ <resource name="fi" size="3" />
+ <resource name="fo" />
+ <resource name="fum" />
+ </resources>
+ <majority xmlns="antlib:org.apache.tools.ant.types.resources.selectors">
+ <name name="f?" />
+ <size size="3" />
+ <instanceof type="resource" />
+ </majority>
+ </restrict>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testmajority3">
+ <au:assertTrue>
+ <resourcecount when="equal" count="3">
+ <restrict>
+ <resources>
+ <string value="fee" />
+ <resource name="fi" size="3" />
+ <resource name="fo" />
+ <resource name="fum" />
+ </resources>
+ <majority allowtie="true"
+ xmlns="antlib:org.apache.tools.ant.types.resources.selectors">
+ <name name="f?" />
+ <size size="3" />
+ <instanceof type="string" />
+ <exists />
+ </majority>
+ </restrict>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testmajority4">
+ <au:assertTrue>
+ <resourcecount when="equal" count="2">
+ <restrict>
+ <resources>
+ <string value="fee" />
+ <resource name="fi" size="3" />
+ <resource name="fo" />
+ <resource name="fum" />
+ </resources>
+ <majority allowtie="false"
+ xmlns="antlib:org.apache.tools.ant.types.resources.selectors">
+ <name name="f?" />
+ <size size="3" />
+ <instanceof type="string" />
+ <exists />
+ </majority>
+ </restrict>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testcontains">
+ <au:assertTrue>
+ <resourcecount when="equal" count="2">
+ <restrict>
+ <resources>
+ <string value="foo" />
+ <string value="bar" />
+ <string value="baz" />
+ </resources>
+ <contains text="b"
+ xmlns="antlib:org.apache.tools.ant.types.resources.selectors" />
+ </restrict>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testcontainsregexp" if="some.regexp.support">
+ <au:assertTrue>
+ <resourcecount when="equal" count="2">
+ <restrict>
+ <resources>
+ <string value="foo" />
+ <string value="bar" />
+ <string value="baz" />
+ </resources>
+ <containsregexp expression="^b..$"
+ xmlns="antlib:org.apache.tools.ant.types.resources.selectors" />
+ </restrict>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testcompare">
+ <au:assertTrue>
+ <and>
+ <!-- basic test, natural ordering -->
+ <resourcecount count="3">
+ <restrict>
+ <rsel:compare when="greater" against="each">
+ <control><string value="b" /></control>
+ </rsel:compare>
+ <resources>
+ <string value="a" />
+ <string value="b" />
+ <string value="c" />
+ <string value="d" />
+ <string value="e" />
+ </resources>
+ </restrict>
+ </resourcecount>
+ <!-- one comparator, default when/against -->
+ <resourcecount count="5">
+ <restrict>
+ <rsel:compare>
+ <control><string value="." /></control>
+ <rcmp:size />
+ </rsel:compare>
+ <resources>
+ <string value="a" />
+ <string value="b" />
+ <string value="c" />
+ <string value="d" />
+ <string value="e" />
+ </resources>
+ </restrict>
+ </resourcecount>
+ <!-- multiple controls, comparators -->
+ <resourcecount count="3">
+ <restrict>
+ <rsel:compare when="greater" against="each">
+ <control>
+ <string value="a" />
+ <string value="b" />
+ <string value="bb" />
+ <string value="c" />
+ <string value="ccc" />
+ </control>
+ <rcmp:name />
+ <rcmp:size />
+ </rsel:compare>
+ <resources>
+ <string value="a" />
+ <string value="bbbb" />
+ <string value="ccc" />
+ <string value="cccc" />
+ <string value="d" />
+ <string value="e" />
+ </resources>
+ </restrict>
+ </resourcecount>
+ </and>
+ </au:assertTrue>
+ </target>
+
+ <target name="majority"
+ depends="testmajority1,testmajority2,testmajority3,testmajority4" />
+
+ <target name="logical"
+ depends="testand,testor,testnone,testnot,majority" />
+
+ <target name="all"
+ depends="name,testexists,instanceof,testtype,testdate,testsize,testcontains,testcontainsregexp,logical,testcompare" />
+
+ <!--
+ The tests for oata.types.selectors.ModifiedSelectorTest as
+ ResourceSelector are in its test-buildfile src\etc\testcases\types\selectors.xml.
+ -->
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/resources/test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/resources/test.xml
new file mode 100644
index 00000000..5af37b9a
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/resources/test.xml
@@ -0,0 +1,460 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="antunit" xmlns:au="antlib:org.apache.ant.antunit">
+
+ <import file="../../antunit-base.xml" />
+
+ <property name="dirname" value="work" />
+ <property name="dir" location="${output}/${dirname}" />
+ <property name="zip" location="${output}/${dirname}.zip" />
+ <property name="jar" location="${antunit.tmpdir}/${dirname}.jar" />
+ <property name="file" location="${output}/${dirname}/file.txt" />
+
+ <condition property="offline">
+ <not>
+ <or>
+ <http url="http://www.apache.org"/>
+ <http url="http://www.google.com"/>
+ </or>
+ </not>
+ </condition>
+
+ <target name="setUp">
+
+ <touch mkdirs="true">
+ <filelist dir="${dir}/foo/a" files="x,y,z" />
+ </touch>
+
+ <copy todir="${dir}/foo" enablemultiplemappings="true">
+ <fileset dir="${dir}/foo" />
+ <mapper>
+ <globmapper handledirsep="true" from="a/*" to="b/*" />
+ <globmapper handledirsep="true" from="a/*" to="c/*" />
+ </mapper>
+ </copy>
+
+ <copy todir="${dir}/bar">
+ <fileset dir="${dir}/foo" />
+ </copy>
+
+ <property name="foo" location="${dir}/foo" />
+ <property name="foo.a" location="${dir}/foo/a" />
+ <property name="foo.b" location="${dir}/foo/b" />
+ <property name="foo.c" location="${dir}/foo/c" />
+
+ <property name="bar" location="${dir}/bar" />
+ <property name="bar.a" location="${dir}/bar/a" />
+ <property name="bar.b" location="${dir}/bar/b" />
+ <property name="bar.c" location="${dir}/bar/c" />
+ </target>
+
+ <target name="tearDown">
+ <delete dir="${dir}" />
+ <delete file="${zip}" />
+ <delete file="${jar}" deleteonexit="true" />
+ <delete file="${file}" />
+ </target>
+
+ <target name="testfiles1" depends="setUp">
+ <au:assertTrue>
+ <resourcecount count="26">
+ <files>
+ <include name="${dir}/foo/" />
+ <include name="${dir}/bar/" />
+ </files>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testfiles2" depends="setUp">
+ <au:assertTrue>
+ <resourcecount count="8">
+ <files>
+ <include name="${dir}/foo/" />
+ <include name="${dir}/bar/" />
+ <type type="dir" />
+ </files>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testfiles3" depends="setUp">
+ <au:assertTrue>
+ <resourcecount count="18">
+ <files>
+ <include name="${dir}/foo/" />
+ <include name="${dir}/bar/" />
+ <type type="file" />
+ </files>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testnestedresources" depends="setUp">
+ <au:assertTrue>
+ <resourcecount count="27"><!-- include duplicates! -->
+ <resources>
+ <files>
+ <include name="${dir}/foo/" />
+ <include name="${dir}/bar/" />
+ <type type="file" />
+ </files>
+ <files>
+ <include name="${dir}/foo/" />
+ <type type="file" />
+ </files>
+ </resources>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testresourcesref" depends="setUp">
+ <files id="files">
+ <include name="${dir}/foo/" />
+ <include name="${dir}/bar/" />
+ <type type="file" />
+ </files>
+ <au:assertTrue>
+ <resourcecount count="18">
+ <resources refid="files" />
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testfileset" depends="setUp">
+ <au:assertTrue>
+ <resourcecount count="9">
+ <fileset dir="${dir}/foo" />
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testdirset" depends="setUp">
+ <au:assertTrue>
+ <resourcecount count="4">
+ <dirset dir="${dir}/foo" />
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testfilelist">
+ <au:assertTrue>
+ <resourcecount count="5">
+ <filelist dir="${dir}/foo" files="1,2,3,4,5" />
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testpath" depends="setUp">
+ <au:assertTrue>
+ <resourcecount count="24">
+ <path>
+ <path id="p">
+ <fileset id="fs" dir="${foo.a}" /> <!-- 3 -->
+ <dirset id="ds" dir="${foo}" /> <!-- 4 -->
+ </path>
+ <pathelement id="pe" location="${dir}" /> <!-- 1 -->
+ <filelist id="fl" dir="${bar}" files="1,2,3,a,b,c" /> <!-- 6 -->
+ <files id="f"> <!-- 13; 3 overlap fl -->
+ <include name="${bar}/"/>
+ </files>
+ </path>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="createzip" depends="setUp">
+ <zip destfile="${zip}" basedir="${dir}" />
+ </target>
+
+ <target name="testzipfileset" depends="createzip">
+ <au:assertTrue>
+ <resourcecount count="9">
+ <zipfileset src="${zip}" includes="foo/" />
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testpropertyset">
+ <property name="testpropertyset.a" value="a" />
+ <property name="testpropertyset.aa" value="aa" />
+ <property name="testpropertyset.aaa" value="aaa" />
+ <propertyset id="testpropertyset">
+ <propertyref prefix="testpropertyset." />
+ </propertyset>
+ <au:assertTrue>
+ <and>
+ <resourcecount refid="testpropertyset" count="3" />
+ <length length="12">
+ <resources>
+ <resources refid="testpropertyset" />
+ <propertyset refid="testpropertyset" />
+ </resources>
+ </length>
+ </and>
+ </au:assertTrue>
+ </target>
+
+ <target name="testunion" depends="setUp">
+ <au:assertTrue>
+ <resourcecount count="4">
+ <union>
+ <files> <!-- 1 -->
+ <include name="${foo.a}/w"/>
+ <include name="${foo.a}/x"/>
+ </files>
+ <fileset dir="${foo.a}" includes="x,y" /> <!-- 2; net 1 -->
+ <filelist dir="${foo.a}" files="v" /> <!-- 1 -->
+ <files> <!-- 2; net 1 -->
+ <include name="${foo.a}/y"/>
+ <include name="${foo.a}/z"/>
+ </files>
+ </union>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testintersect">
+ <au:assertTrue>
+ <resourcecount count="3">
+ <intersect>
+ <filelist dir="${dir}" files="1,2,3,4,5" />
+ <filelist dir="${dir}" files="2,3,4,5,6" />
+ <filelist dir="${dir}" files="3,4,5,6,7" />
+ </intersect>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testdifference">
+ <au:assertTrue>
+ <resourcecount count="2">
+ <difference id="diff">
+ <filelist dir="${dir}" files="1,2,3,4,5" />
+ <filelist dir="${dir}" files="2,3,4,5,6" />
+ <filelist dir="${dir}" files="3,4,5,6,7" />
+ </difference>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testfileurl">
+ <au:assertTrue>
+ <length when="greater" length="0">
+ <url file="${ant.file}" />
+ </length>
+ </au:assertTrue>
+ </target>
+
+ <target name="testfileurlref">
+ <url id="fileurl" file="${ant.file}" />
+ <au:assertTrue>
+ <length when="greater" length="0">
+ <url refid="fileurl" />
+ </length>
+ </au:assertTrue>
+ </target>
+
+ <target name="testhttpurl1" unless="offline">
+ <au:assertTrue>
+ <length when="greater" length="0">
+ <url url="http://www.w3.org/MarkUp/" />
+ </length>
+ </au:assertTrue>
+ </target>
+
+ <target name="testhttpurl2" unless="offline">
+ <concat destfile="${file}" force="true" append="false">
+ <url id="httpurl" url="http://ant.apache.org/index.html" />
+ <url refid="httpurl" />
+ </concat>
+ <length property="httpurl.length">
+ <url refid="httpurl" />
+ </length>
+ <length property="file.length">
+ <file file="${file}"/>
+ </length>
+ <au:assertTrue message="length of url ${httpurl.length} length of file ${file.length} file should be twice as big">
+ <length file="${file}" when="greater" length="${httpurl.length}" />
+ </au:assertTrue>
+ </target>
+
+ <target name="createjar" depends="setUp">
+ <jar destfile="${jar}" basedir="${dir}" />
+ </target>
+
+ <target name="testjarurl" depends="createjar">
+ <pathconvert property="jarurl">
+ <url file="${jar}" />
+ </pathconvert>
+ <au:assertTrue>
+ <length when="greater" length="0">
+ <url url="jar:${jarurl}!/META-INF/MANIFEST.MF" />
+ </length>
+ </au:assertTrue>
+ </target>
+
+ <target name="testfile" depends="setUp">
+ <echo file="${file}">This is a test.</echo>
+ <au:assertTrue>
+ <length length="15">
+ <file file="${file}" />
+ </length>
+ </au:assertTrue>
+ </target>
+
+ <target name="testzipentry" depends="createjar">
+ <au:assertTrue>
+ <length when="greater" length="0">
+ <zipentry zipfile="${jar}" name="META-INF/MANIFEST.MF" />
+ </length>
+ </au:assertTrue>
+ </target>
+
+ <target name="teststring1">
+ <au:assertTrue>
+ <length length="15">
+ <string value="This is a test." />
+ </length>
+ </au:assertTrue>
+ </target>
+
+ <target name="teststring2">
+ <property name="test" value="foo" />
+ <au:assertTrue>
+ <length length="14">
+ <string value="This is a ${test}." />
+ </length>
+ </au:assertTrue>
+ </target>
+
+ <target name="testresource">
+ <au:assertTrue>
+ <length length="4096">
+ <resource size="4096" />
+ </length>
+ </au:assertTrue>
+ </target>
+
+ <target name="testproperty">
+ <property name="testproperty" value="abcdefghij" />
+ <au:assertTrue>
+ <length length="10">
+ <propertyresource name="testproperty" />
+ </length>
+ </au:assertTrue>
+ </target>
+
+ <target name="testPropertyResolvedAsResource">
+ <string id="s" value="abcdefghij" />
+ <au:assertTrue>
+ <resourcesmatch>
+ <resource refid="s" />
+ <propertyresource name="ant.refid:s" />
+ </resourcesmatch>
+ </au:assertTrue>
+ </target>
+
+ <target name="testfirst0">
+ <au:assertTrue>
+ <resourcecount count="0">
+ <first count="0">
+ <filelist dir="${dir}" files="1,2,3,4,5" />
+ </first>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testfirst1">
+ <au:assertTrue>
+ <resourcecount count="1">
+ <first>
+ <filelist dir="${dir}" files="1,2,3,4,5" />
+ </first>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testfirst2">
+ <au:assertTrue>
+ <resourcecount count="2">
+ <first count="2">
+ <filelist dir="${dir}" files="1,2,3,4,5" />
+ </first>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testJavaConstant">
+ <property name="test.tmp.dir" value="${antunit.tmpdir}/testJavaConstant"/>
+ <mkdir dir="${test.tmp.dir}"/>
+ <echo file="${test.tmp.dir}/SomeClass.java">
+ public class SomeClass {
+ public static final String CONSTANT = "constant";
+ public final String NOT_STATIC = "not-static";
+ private static final String PRIVATE = "private";
+ }
+ </echo>
+ <javac srcdir="${test.tmp.dir}" destdir="${test.tmp.dir}"/>
+ <path id="tmp.cp">
+ <pathelement location="${test.tmp.dir}"/>
+ </path>
+
+ <loadresource property="actual">
+ <javaconstant name="org.apache.tools.ant.Main.DEFAULT_BUILD_FILENAME"/>
+ </loadresource>
+ <au:assertEquals message="could not read java constant" expected="build.xml" actual="${actual}" />
+
+ <!--
+ We can't test for special error messages using built-in tasks
+ because they catch these messages
+ -->
+ <au:expectfailure>
+ <loadresource property="p">
+ <javaconstant/>
+ </loadresource>
+ </au:expectfailure>
+ <au:expectfailure>
+ <loadresource property="p">
+ <javaconstant name="org.apache.tools.ant.MissingClass"/>
+ </loadresource>
+ </au:expectfailure>
+ <au:expectfailure>
+ <loadresource property="p">
+ <javaconstant name="SomeClass.CONSTANT2" classpathref="tmp.cp"/>
+ </loadresource>
+ </au:expectfailure>
+ <au:expectfailure>
+ <loadresource property="p">
+ <javaconstant name="SomeClass.PRIVATE">
+ <classpath>
+ <pathelement location="${test.tmp.dir}"/>
+ </classpath>
+ </javaconstant>
+ </loadresource>
+ </au:expectfailure>
+ <au:expectfailure>
+ <loadresource property="p">
+ <javaconstant name="SomeClass.NOT_STATIC"/>
+ </loadresource>
+ </au:expectfailure>
+
+ <delete dir="${test.tmp.dir}"/>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/resources/tokens-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/resources/tokens-test.xml
new file mode 100644
index 00000000..c09d604c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/resources/tokens-test.xml
@@ -0,0 +1,128 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project name="test-tokens" default="antunit"
+ xmlns:au="antlib:org.apache.ant.antunit">
+
+ <property name="eol" value="${line.separator}" />
+
+ <target name="antunit">
+ <au:antunit>
+ <au:plainlistener />
+ <file file="${ant.file}" />
+ </au:antunit>
+ </target>
+
+ <target name="testLines">
+ <au:assertTrue>
+ <resourcecount count="0">
+ <difference>
+ <tokens>
+ <string value="foo${eol}bar${eol}baz" />
+ </tokens>
+ <resources>
+ <string value="foo" />
+ <string value="bar" />
+ <string value="baz" />
+ </resources>
+ </difference>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testExplicitLines">
+ <au:assertTrue>
+ <resourcecount count="0">
+ <difference>
+ <tokens>
+ <string value="foo${eol}bar${eol}baz" />
+ <linetokenizer />
+ </tokens>
+ <resources>
+ <string value="foo" />
+ <string value="bar" />
+ <string value="baz" />
+ </resources>
+ </difference>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testFileTokenizer">
+ <au:assertTrue>
+ <resourcecount count="1">
+ <tokens>
+ <resources>
+ <string value="foo${eol}bar${eol}baz" />
+ <file file="${ant.file}" />
+ </resources>
+ <filetokenizer />
+ </tokens>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testStringTokenizer">
+ <au:assertTrue>
+ <resourcecount count="0">
+ <difference>
+ <tokens>
+ <string value="foo bar baz " />
+ <stringtokenizer />
+ </tokens>
+ <resources>
+ <string value="foo" />
+ <string value="bar" />
+ <string value="baz" />
+ </resources>
+ </difference>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testEncoding">
+ <au:assertTrue>
+ <resourcecount count="0">
+ <difference>
+ <tokens encoding="utf-16">
+ <file file="utf-16.in" />
+ </tokens>
+ <resources>
+ <string value="foo" />
+ <string value="bar" />
+ <string value="baz" />
+ </resources>
+ </difference>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testSort">
+ <pathconvert property="sorted" pathsep="${eol}">
+ <sort>
+ <tokens>
+ <string value="foo bar etc baz" />
+ <stringtokenizer />
+ </tokens>
+ </sort>
+ </pathconvert>
+ <au:assertTrue>
+ <equals arg1="bar${eol}baz${eol}etc${eol}foo" arg2="${sorted}" />
+ </au:assertTrue>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/resources/utf-16.in b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/resources/utf-16.in
new file mode 100644
index 00000000..7c7c2a78
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/resources/utf-16.in
Binary files differ
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/selectors/depend-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/selectors/depend-test.xml
new file mode 100644
index 00000000..e868f6a6
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/selectors/depend-test.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project xmlns:au="antlib:org.apache.ant.antunit" default="antunit">
+
+ <import file="../../antunit-base.xml" />
+
+ <property name="output.dir" location="output" />
+ <property name="foo.file" location="${output.dir}/foo" />
+
+ <target name="setUp">
+ <touch file="${foo.file}" mkdirs="true" />
+ </target>
+
+ <target name="tearDown">
+ <delete dir="${output.dir}" />
+ </target>
+
+ <target name="testMapperByTypedef" depends="setUp">
+ <au:assertTrue>
+ <resourcecount count="1">
+ <fileset file="${foo.file}">
+ <depend targetdir="${basedir}"><!-- dummy targetdir -->
+ <mergemapper to="${ant.file}" />
+ </depend>
+ </fileset>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/selectors/different-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/selectors/different-test.xml
new file mode 100644
index 00000000..c2542d2f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/selectors/different-test.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project xmlns:au="antlib:org.apache.ant.antunit" default="antunit">
+
+ <import file="../../antunit-base.xml" />
+
+ <property name="output.dir" location="output" />
+ <property name="foo.file" location="${output.dir}/foo" />
+
+ <target name="setUp">
+ <mkdir dir="${output.dir}"/>
+ <echo file="${foo.file}">foo</echo>
+ </target>
+
+ <target name="tearDown">
+ <delete dir="${output.dir}" />
+ </target>
+
+ <target name="testMapperByTypedef" depends="setUp">
+ <au:assertTrue>
+ <resourcecount count="1">
+ <fileset file="${foo.file}">
+ <different targetdir="${basedir}"><!-- dummy targetdir -->
+ <mergemapper to="${ant.file}" />
+ </different>
+ </fileset>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/selectors/filename-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/selectors/filename-test.xml
new file mode 100644
index 00000000..3f28e11e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/selectors/filename-test.xml
@@ -0,0 +1,69 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project xmlns:au="antlib:org.apache.ant.antunit" default="antunit">
+
+ <import file="../../antunit-base.xml" />
+
+ <property name="file" value="testfile"/>
+
+ <target name="createTestdir">
+ <mkdir dir="${output}"/>
+ <touch file="${output}/${file}"/>
+ </target>
+
+ <target name="testPattern" depends="createTestdir">
+ <au:assertTrue>
+ <resourcecount when="equal" count="1">
+ <fileset dir="${output}">
+ <filename name="*"/>
+ </fileset>
+ </resourcecount>
+ </au:assertTrue>
+ <au:assertTrue>
+ <resourcecount when="equal" count="0">
+ <fileset dir="${output}">
+ <filename name="*" negate="true"/>
+ </fileset>
+ </resourcecount>
+ </au:assertTrue>
+ <au:assertTrue>
+ <resourcecount when="equal" count="0">
+ <fileset dir="${output}">
+ <filename name=".*"/>
+ </fileset>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testRegex" depends="createTestdir">
+ <au:assertTrue>
+ <resourcecount when="equal" count="1">
+ <fileset dir="${output}">
+ <filename regex=".*"/>
+ </fileset>
+ </resourcecount>
+ </au:assertTrue>
+ <au:assertTrue>
+ <resourcecount when="equal" count="0">
+ <fileset dir="${output}">
+ <filename regex=".*" negate="true"/>
+ </fileset>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/selectors/modified-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/selectors/modified-test.xml
new file mode 100644
index 00000000..a4c43e04
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/selectors/modified-test.xml
@@ -0,0 +1,76 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project xmlns:au="antlib:org.apache.ant.antunit" default="antunit">
+
+ <import file="../../antunit-base.xml" />
+
+ <target name="tearDown" depends="antunit-base.tearDown">
+ <delete file="cache.properties" quiet="true"/>
+ </target>
+
+ <target name="testUpdate"
+ description="https://issues.apache.org/bugzilla/show_bug.cgi?id=32597">
+ <mkdir dir="${input}"/>
+ <touch file="${input}/A"/>
+ <mkdir dir="${output}"/>
+ <pathconvert>
+ <fileset dir="${input}">
+ <modified/>
+ </fileset>
+ </pathconvert>
+ <au:assertFileExists file="cache.properties"/>
+ <copy todir="${output}" file="cache.properties"/>
+ <echo file="${input}/A">Hello</echo>
+ <pathconvert>
+ <fileset dir="${input}">
+ <modified update="false"/>
+ </fileset>
+ </pathconvert>
+ <au:assertFilesMatch
+ expected="${output}/cache.properties"
+ actual="cache.properties"/>
+ <pathconvert>
+ <fileset dir="${input}">
+ <modified>
+ <param name="update" value="false"/>
+ </modified>
+ </fileset>
+ </pathconvert>
+ <au:assertFilesMatch
+ expected="${output}/cache.properties"
+ actual="cache.properties"/>
+ <pathconvert>
+ <fileset dir="${input}">
+ <modified update="true"/>
+ </fileset>
+ </pathconvert>
+ <au:assertFilesDiffer
+ expected="${output}/cache.properties"
+ actual="cache.properties"/>
+ <copy todir="${output}" file="cache.properties"/>
+ <echo file="${input}/A">world</echo>
+ <pathconvert>
+ <fileset dir="${input}">
+ <modified update="true"/>
+ </fileset>
+ </pathconvert>
+ <au:assertFilesDiffer
+ expected="${output}/cache.properties"
+ actual="cache.properties"/>
+ </target>
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/selectors/present-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/selectors/present-test.xml
new file mode 100644
index 00000000..e31c722d
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/selectors/present-test.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project xmlns:au="antlib:org.apache.ant.antunit" default="antunit">
+
+ <import file="../../antunit-base.xml" />
+
+ <property name="output.dir" location="output" />
+ <property name="foo.file" location="${output.dir}/foo" />
+
+ <target name="setUp">
+ <touch file="${foo.file}" mkdirs="true" />
+ </target>
+
+ <target name="tearDown">
+ <delete dir="${output.dir}" />
+ </target>
+
+ <target name="testMapperByTypedef" depends="setUp">
+ <au:assertTrue>
+ <resourcecount count="1">
+ <fileset file="${foo.file}">
+ <present targetdir="${basedir}"><!-- dummy targetdir -->
+ <mergemapper to="${ant.file}" />
+ </present>
+ </fileset>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/selectors/readwrite-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/selectors/readwrite-test.xml
new file mode 100644
index 00000000..bd4ac8de
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/selectors/readwrite-test.xml
@@ -0,0 +1,99 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project xmlns:au="antlib:org.apache.ant.antunit" default="antunit">
+
+ <import file="../../antunit-base.xml" />
+
+ <property name="file" value="testfile"/>
+
+ <condition property="unix">
+ <os family="unix"/>
+ </condition>
+
+ <target name="createTestdir">
+ <mkdir dir="${output}"/>
+ <touch file="${output}/${file}"/>
+ </target>
+
+ <target name="testReadable" depends="createTestdir">
+ <au:assertTrue>
+ <resourcecount when="equal" count="1">
+ <fileset dir="${output}">
+ <readable/>
+ </fileset>
+ </resourcecount>
+ </au:assertTrue>
+ <au:assertTrue>
+ <resourcecount when="equal" count="0">
+ <fileset dir="${output}" excludes="${file}">
+ <readable/>
+ </fileset>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testWritable" depends="createTestdir">
+ <au:assertTrue>
+ <resourcecount when="equal" count="1">
+ <fileset dir="${output}">
+ <writable/>
+ </fileset>
+ </resourcecount>
+ </au:assertTrue>
+ <au:assertTrue>
+ <resourcecount when="equal" count="0">
+ <fileset dir="${output}" excludes="${file}">
+ <writable/>
+ </fileset>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="makeFileUnwritable"
+ depends="createTestdir,makeFileUnwritable-Unix,makeFileUnwritable-Windows"/>
+ <target name="makeFileUnwritable-Unix" id="unix">
+ <chmod file="${output}/${file}" perm="444"/>
+ </target>
+ <target name="makeFileUnwritable-Windows" unless="unix">
+ <attrib file="${output}/${file}" readonly="true"/>
+ </target>
+
+ <target name="testUnwritable" depends="makeFileUnwritable">
+ <au:assertTrue>
+ <resourcecount when="equal" count="0">
+ <fileset dir="${output}">
+ <writable/>
+ </fileset>
+ </resourcecount>
+ </au:assertTrue>
+ </target>
+
+ <target name="testAsConditions" depends="makeFileUnwritable">
+ <au:assertTrue>
+ <isfileselected file="${output}/${file}">
+ <readable/>
+ </isfileselected>
+ </au:assertTrue>
+ <au:assertFalse>
+ <isfileselected file="${output}/${file}">
+ <writable/>
+ </isfileselected>
+ </au:assertFalse>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/selectors/select-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/selectors/select-test.xml
new file mode 100644
index 00000000..f5f5b99e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/selectors/select-test.xml
@@ -0,0 +1,88 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project xmlns:au="antlib:org.apache.ant.antunit" default="antunit">
+
+ <import file="../../antunit-base.xml" />
+
+ <target name="setUp">
+ <mkdir dir="${input}"/>
+ <touch file="${input}/A"/>
+ <touch file="${input}/B"/>
+ <touch file="${input}/C"/>
+ <touch file="${input}/D"/>
+ <mkdir dir="${output}"/>
+ <macrodef name="cp">
+ <sequential>
+ <copy todir="${output}">
+ <fileset dir="${input}">
+ <or>
+ <selector if="${if}">
+ <filename name="A"/>
+ </selector>
+ <selector unless="${if}">
+ <filename name="B"/>
+ </selector>
+ <selector if="if">
+ <filename name="C"/>
+ </selector>
+ <selector unless="if">
+ <filename name="D"/>
+ </selector>
+ </or>
+ </fileset>
+ </copy>
+ </sequential>
+ </macrodef>
+ </target>
+
+ <target name="testIfNotSet" depends="setUp">
+ <cp/>
+ <au:assertFileDoesntExist file="${output}/C"/>
+ <au:assertFileExists file="${output}/D"/>
+ <au:assertFileDoesntExist file="${output}/A"/>
+ <au:assertFileExists file="${output}/B"/>
+ </target>
+
+ <target name="testIfSet" depends="setUp">
+ <property name="if" value="whatever"/>
+ <cp/>
+ <au:assertFileDoesntExist file="${output}/A"/>
+ <au:assertFileExists file="${output}/B"/>
+ <au:assertFileExists file="${output}/C"/>
+ <au:assertFileDoesntExist file="${output}/D"/>
+ </target>
+
+ <target name="testIfTrue" depends="setUp">
+ <property name="if" value="true"/>
+ <cp/>
+ <au:assertFileExists file="${output}/A"/>
+ <au:assertFileDoesntExist file="${output}/B"/>
+ <au:assertFileExists file="${output}/C"/>
+ <au:assertFileDoesntExist file="${output}/D"/>
+ </target>
+
+ <target name="testIfFalse" depends="setUp">
+ <property name="if" value="false"/>
+ <cp/>
+ <au:assertFileDoesntExist file="${output}/A"/>
+ <au:assertFileExists file="${output}/B"/>
+ <au:assertFileExists file="${output}/C"/>
+ <au:assertFileDoesntExist file="${output}/D"/>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/tarfileset-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/tarfileset-test.xml
new file mode 100644
index 00000000..3c4d3a98
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/tarfileset-test.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project xmlns:au="antlib:org.apache.ant.antunit" default="antunit">
+ <import file="../antunit-base.xml"/>
+
+ <target name="testMissingArchive">
+ <mkdir dir="${output}"/>
+ <au:expectfailure expectedMessage="The archive foo.tar doesn't exist">
+ <copy todir="${output}">
+ <tarfileset src="foo.tar"/>
+ </copy>
+ </au:expectfailure>
+ </target>
+
+ <target name="testMissingArchiveDoesntMatter">
+ <mkdir dir="${output}"/>
+ <copy todir="${output}">
+ <tarfileset src="foo.tar" errorOnMissingArchive="false"/>
+ </copy>
+ </target>
+
+ <target name="test-refid-check-encoding">
+ <tarfileset id="test-refid2"
+ encoding="utf-8"
+ dir="${basedir}"/>
+ <au:expectfailure>
+ <tarfileset id="ref4"
+ encoding="utf-8"
+ refid="test-refid2"/>
+ </au:expectfailure>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/zipfileset-test.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/zipfileset-test.xml
new file mode 100644
index 00000000..c8bb022b
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/antunit/types/zipfileset-test.xml
@@ -0,0 +1,83 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project xmlns:au="antlib:org.apache.ant.antunit" default="antunit">
+ <import file="../antunit-base.xml"/>
+
+ <target name="test-refid-modify">
+ <fileset id="modify-refid-1"
+ dir="${basedir}"
+ includes="*.xml"
+ />
+ <zipfileset id="modify-refid-2"
+ refid="modify-refid-1"
+ prefix="WEB-INF/lib/"/>
+ <delete quiet="yes" dir="${build.dir}"/>
+ <mkdir dir="${output}"/>
+ <jar jarfile="${output}/jar.jar">
+ <zipfileset refid="modify-refid-2"/>
+ </jar>
+ <unjar src="${output}/jar.jar"
+ dest="${output}"/>
+ <au:assertTrue>
+ <available file="${output}/WEB-INF/lib/zipfileset-test.xml"/>
+ </au:assertTrue>
+ </target>
+
+ <target name="test-refid-check-prefix">
+ <zipfileset id="test-refid"
+ dir="${basedir}"/>
+ <au:expectfailure>
+ <zipfileset id="ref2"
+ refid="test-refid"
+ prefix="WEB-INF/lib/"/>
+ </au:expectfailure>
+ <au:expectfailure>
+ <zipfileset id="ref3"
+ prefix="WEB-INF/lib/"
+ ReFiD="test-refid"/>
+ </au:expectfailure>
+ </target>
+
+ <target name="test-refid-check-encoding">
+ <zipfileset id="test-refid2"
+ encoding="utf-8"
+ dir="${basedir}"/>
+ <au:expectfailure>
+ <zipfileset id="ref4"
+ encoding="utf-8"
+ refid="test-refid2"/>
+ </au:expectfailure>
+ </target>
+
+ <target name="testMissingArchive">
+ <mkdir dir="${output}"/>
+ <au:expectfailure expectedMessage="The archive foo.zip doesn't exist">
+ <copy todir="${output}">
+ <zipfileset src="foo.zip"/>
+ </copy>
+ </au:expectfailure>
+ </target>
+
+ <target name="testMissingArchiveDoesntMatter">
+ <mkdir dir="${output}"/>
+ <copy todir="${output}">
+ <zipfileset src="foo.zip" errorOnMissingArchive="false"/>
+ </copy>
+ </target>
+
+</project>
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/AntAssert.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/AntAssert.java
new file mode 100644
index 00000000..7771924f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/AntAssert.java
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Provides common assert functions for use across multiple tests, similar to the <tt>Assert</tt>s
+ * within JUnit.
+ */
+public class AntAssert {
+
+ /**
+ * Assert that a string contains the given substring.
+ * @param message the message to fail with if the substring is not present in the target string.
+ * @param needle the string to search for.
+ * @param haystack the string to search in.
+ */
+ public static void assertContains(String message, String needle, String haystack) {
+ String formattedMessage = (message == null ? "" : message + " ");
+ assertTrue(formattedMessage + String.format("expected message containing: <%s> but got: <%s>", needle, haystack), haystack.contains(needle));
+ }
+
+ /**
+ * Assert that a string contains the given substring. A default failure message will be used if the target string
+ * is not found.
+ * @param needle the target string to search for.
+ * @param haystack the string to search in.
+ */
+ public static void assertContains(String needle, String haystack) {
+ assertContains("", needle, haystack);
+ }
+
+ /**
+ * Assert that a string does not contain the given substring.
+ * @param message the message to fail with if the substring is present in the target string.
+ * @param needle the string to search for.
+ * @param haystack the string to search in.
+ */
+ public static void assertNotContains(String message, String needle, String haystack) {
+ String formattedMessage = (message == null ? "" : message + " ");
+ assertFalse(formattedMessage + String.format("expected message not to contain: <%s> but got: <%s>", needle, haystack), haystack.contains(needle));
+ }
+
+ /**
+ * Assert that a string does not contain the given substring. A default failure message will be used if the target
+ * string is found.
+ * @param needle the target string to search for.
+ * @param haystack the string to search in.
+ */
+ public static void assertNotContains(String needle, String haystack) {
+ assertNotContains("", needle, haystack);
+ }
+
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/AntClassLoaderDelegationTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/AntClassLoaderDelegationTest.java
new file mode 100644
index 00000000..ae5ce627
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/AntClassLoaderDelegationTest.java
@@ -0,0 +1,124 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.List;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.util.FileUtils;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Test case for ant class loader
+ *
+ */
+public class AntClassLoaderDelegationTest {
+
+ /** Instance of a utility class to use for file operations. */
+ private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+
+ private Project p;
+
+ @Before
+ public void setUp() {
+ p = new Project();
+ p.init();
+ }
+
+ /** Sample resource present in build/testcases/ */
+ private static final String TEST_RESOURCE
+ = "apache/tools/ant/IncludeTest.class";
+
+ @Test
+ public void testFindResources() throws Exception {
+ // This path should contain the class files for these testcases:
+ String buildTestcases = System.getProperty("build.tests");
+ assertNotNull("defined ${build.tests}", buildTestcases);
+ assertTrue("have a dir " + buildTestcases,
+ new File(buildTestcases).isDirectory());
+ Path path = new Path(p, buildTestcases + "/org");
+ // A special parent loader which is not the system class loader:
+ ClassLoader parent = new ParentLoader();
+ // An AntClassLoader which is supposed to delegate to
+ // the parent and then to the disk path:
+ ClassLoader acl = new AntClassLoader(parent, p, path, true);
+ // The intended result URLs:
+ URL urlFromPath = new URL(
+ FILE_UTILS.toURI(buildTestcases) + "org/" + TEST_RESOURCE);
+ URL urlFromParent = new URL("http://ant.apache.org/" + TEST_RESOURCE);
+ assertEquals("correct resources (regular delegation order)",
+ Arrays.asList(new URL[] {urlFromParent, urlFromPath}),
+ enum2List(acl.getResources(TEST_RESOURCE)));
+ acl = new AntClassLoader(parent, p, path, false);
+ assertEquals("correct resources (reverse delegation order)",
+ Arrays.asList(new URL[] {urlFromPath, urlFromParent}),
+ enum2List(acl.getResources(TEST_RESOURCE)));
+ }
+
+ @Test
+ public void testFindIsolateResources() throws Exception {
+ String buildTestcases = System.getProperty("build.tests");
+ assertNotNull("defined ${build.tests}", buildTestcases);
+ assertTrue("have a dir " + buildTestcases,
+ new File(buildTestcases).isDirectory());
+ Path path = new Path(p, buildTestcases + "/org");
+ // A special parent loader which is not the system class loader:
+ ClassLoader parent = new ParentLoader();
+
+ URL urlFromPath = new URL(
+ FILE_UTILS.toURI(buildTestcases) + "org/" + TEST_RESOURCE);
+ AntClassLoader acl = new AntClassLoader(parent, p, path, false);
+ acl.setIsolated(true);
+ assertEquals("correct resources (reverse delegation order)",
+ Arrays.asList(new URL[] {urlFromPath}),
+ enum2List(acl.getResources(TEST_RESOURCE)));
+ }
+
+ private static List enum2List(Enumeration e) {
+ return Collections.list(e);
+ }
+
+ /** Special loader that just knows how to find TEST_RESOURCE. */
+ private static final class ParentLoader extends ClassLoader {
+
+ public ParentLoader() {}
+
+ protected Enumeration findResources(String name) throws IOException {
+ if (name.equals(TEST_RESOURCE)) {
+ return Collections.enumeration(
+ Collections.singleton(
+ new URL("http://ant.apache.org/" + name)));
+ } else {
+ return Collections.enumeration(Collections.EMPTY_SET);
+ }
+ }
+
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/AntClassLoaderPerformance.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/AntClassLoaderPerformance.java
new file mode 100644
index 00000000..2145cfa1
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/AntClassLoaderPerformance.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant;
+
+import java.io.File;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.util.FileUtils;
+import org.junit.Test;
+
+/**
+ * Used to verify the performance effect of classloader changes.
+ */
+public class AntClassLoaderPerformance {
+
+ @Test
+ public void testFindClass() throws Exception {
+ String testCaseURL = getClass()
+ .getClassLoader().getResource("junit/framework/TestCase.class")
+ .toExternalForm();
+ int pling = testCaseURL.indexOf('!');
+ String jarName = testCaseURL.substring(4, pling);
+ File f = new File(FileUtils.getFileUtils().fromURI(jarName));
+ Path p = new Path(null);
+ p.createPathElement().setLocation(f);
+ AntClassLoader al = null;
+ for (int i = 0; i < 1000; i++) {
+ try {
+ // not using factory method so the test can run on Ant
+ // 1.7.1 as well
+ al = new AntClassLoader(null, null, p, false);
+ al.findClass("junit.framework.TestCase");
+ } finally {
+ if (al != null) {
+ al.cleanup();
+ }
+ }
+ }
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/AntClassLoaderTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/AntClassLoaderTest.java
new file mode 100644
index 00000000..8419037e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/AntClassLoaderTest.java
@@ -0,0 +1,210 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.File;
+import java.io.PrintStream;
+import java.net.URL;
+
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.util.FileUtils;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+/**
+ * Test case for ant class loader
+ *
+ */
+public class AntClassLoaderTest {
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ private AntClassLoader loader;
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/core/antclassloader.xml");
+ buildRule.executeTarget("setUp");
+ }
+
+ @After
+ public void tearDown() {
+ if (loader != null) {
+ loader.cleanup();
+ }
+ }
+
+ //test inspired by bug report 37085
+ @Test
+ public void testJarWithManifestInDirWithSpace() {
+ String mainjarstring = buildRule.getProject().getProperty("main.jar");
+ String extjarstring = buildRule.getProject().getProperty("ext.jar");
+ Path myPath = new Path(buildRule.getProject());
+ myPath.setLocation(new File(mainjarstring));
+ buildRule.getProject().setUserProperty("build.sysclasspath","ignore");
+ loader = buildRule.getProject().createClassLoader(myPath);
+ String path = loader.getClasspath();
+ assertEquals(mainjarstring + File.pathSeparator + extjarstring, path);
+ }
+
+ @Test
+ public void testJarWithManifestInNonAsciiDir() {
+ String mainjarstring = buildRule.getProject().getProperty("main.jar.nonascii");
+ String extjarstring = buildRule.getProject().getProperty("ext.jar.nonascii");
+ Path myPath = new Path(buildRule.getProject());
+ myPath.setLocation(new File(mainjarstring));
+ buildRule.getProject().setUserProperty("build.sysclasspath","ignore");
+ loader = buildRule.getProject().createClassLoader(myPath);
+ String path = loader.getClasspath();
+ assertEquals(mainjarstring + File.pathSeparator + extjarstring, path);
+ }
+
+ @Test
+ public void testCleanup() throws BuildException {
+ Path path = new Path(buildRule.getProject(), ".");
+ loader = buildRule.getProject().createClassLoader(path);
+ try {
+ // we don't expect to find this
+ loader.findClass("fubar");
+ fail("Did not expect to find fubar class");
+ } catch (ClassNotFoundException e) {
+ // ignore expected
+ }
+
+ loader.cleanup();
+ try {
+ // we don't expect to find this
+ loader.findClass("fubar");
+ fail("Did not expect to find fubar class");
+ } catch (ClassNotFoundException e) {
+ // ignore expected
+ } catch (NullPointerException e) {
+ fail("loader should not fail even if cleaned up");
+ }
+
+ // tell the build it is finished
+ buildRule.getProject().fireBuildFinished(null);
+ try {
+ // we don't expect to find this
+ loader.findClass("fubar");
+ fail("Did not expect to find fubar class");
+ } catch (ClassNotFoundException e) {
+ // ignore expected
+ } catch (NullPointerException e) {
+ fail("loader should not fail even if project finished");
+ }
+ }
+
+ @Test
+ public void testGetPackage() throws Exception {
+ buildRule.executeTarget("prepareGetPackageTest");
+ Path myPath = new Path(buildRule.getProject());
+ myPath.setLocation(new File(buildRule.getProject().getProperty("test.jar")));
+ buildRule.getProject().setUserProperty("build.sysclasspath","ignore");
+ loader = buildRule.getProject().createClassLoader(myPath);
+ assertNotNull("should find class", loader.findClass("org.example.Foo"));
+ assertNotNull("should find package",
+ new GetPackageWrapper(loader).getPackage("org.example"));
+ }
+
+ @Test
+ public void testCodeSource() throws Exception {
+ buildRule.executeTarget("prepareGetPackageTest");
+ Path myPath = new Path(buildRule.getProject());
+ File testJar = new File(buildRule.getProject().getProperty("test.jar"));
+ myPath.setLocation(testJar);
+ buildRule.getProject().setUserProperty("build.sysclasspath","ignore");
+ loader = buildRule.getProject().createClassLoader(myPath);
+ Class<?> foo = loader.findClass("org.example.Foo");
+ URL codeSourceLocation =
+ foo.getProtectionDomain().getCodeSource().getLocation();
+ assertEquals(codeSourceLocation + " should point to test.jar",
+ FileUtils.getFileUtils().getFileURL(testJar), codeSourceLocation);
+ }
+
+ @Test
+ public void testSignedJar() throws Exception {
+ buildRule.executeTarget("signTestJar");
+ File jar = new File(buildRule.getProject().getProperty("test.jar"));
+
+ Path myPath = new Path(buildRule.getProject());
+ myPath.setLocation(jar);
+ buildRule.getProject().setUserProperty("build.sysclasspath","ignore");
+ loader = buildRule.getProject().createClassLoader(myPath);
+ Class<?> foo = loader.findClass("org.example.Foo");
+
+ assertNotNull("should find class", foo);
+ assertNotNull("should have certificates",
+ foo.getProtectionDomain().getCodeSource()
+ .getCertificates());
+ assertNotNull("should be signed", foo.getSigners());
+ }
+
+ /**
+ * @see <a href="https://issues.apache.org/bugzilla/show_bug.cgi?id=47593">
+ * bug 47593, request to log the name of corrupt zip files from which
+ * classes cannot be loaded</a>
+ */
+ @Test
+ public void testInvalidZipException() throws Exception {
+ buildRule.executeTarget("createNonJar");
+ File jar = new File(buildRule.getProject().getProperty("tmp.dir")
+ + "/foo.jar");
+
+ Path myPath = new Path(buildRule.getProject());
+ myPath.setLocation(jar);
+ buildRule.getProject().setUserProperty("build.sysclasspath","ignore");
+ loader = buildRule.getProject().createClassLoader(myPath);
+ PrintStream sysErr = System.err;
+ try {
+ StringBuffer errBuffer = new StringBuffer();
+ PrintStream err =
+ new PrintStream(new BuildFileRule.AntOutputStream(errBuffer));
+ System.setErr(err);
+ loader.getResource("foo.txt");
+ String log = buildRule.getLog();
+ int startMessage = log.indexOf("CLASSPATH element ");
+ assertTrue(startMessage >= 0);
+ assertTrue(log.indexOf("foo.jar is not a JAR", startMessage) > 0);
+ log = errBuffer.toString();
+ startMessage = log.indexOf("CLASSPATH element ");
+ assertTrue(startMessage >= 0);
+ assertTrue(log.indexOf("foo.jar is not a JAR", startMessage) > 0);
+ } finally {
+ System.setErr(sysErr);
+ }
+ }
+
+ private static class GetPackageWrapper extends ClassLoader {
+ GetPackageWrapper(ClassLoader parent) {
+ super(parent);
+ }
+ public Package getPackage(String s) {
+ return super.getPackage(s);
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/BuildFileRule.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/BuildFileRule.java
new file mode 100644
index 00000000..b4e00fdc
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/BuildFileRule.java
@@ -0,0 +1,318 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant;
+
+import java.io.File;
+import java.io.OutputStream;
+import java.io.PrintStream;
+
+import org.apache.tools.ant.util.ProcessUtil;
+import org.junit.rules.ExternalResource;
+
+/**
+ * Provides access for JUnit tests to execute Ant targets and access execution details (i.e logs).
+ *
+ * Example usage:
+ * <code>
+ * public class MyTest {
+ *
+ * \@Rule
+ * public BuildFileRule rule = new BuildFileRule();
+ *
+ * \@Before
+ * public void setUp() {
+ * rule.configureProject("my/and/file.xml");
+ * }
+ *
+ * \@Test
+ * public void testSuccess() {
+ * rule.executeTarget("passingTaget");
+ * assertEquals("Incorrect log message", "[taskName] Action Complete", rule.getLog());
+ * }
+ *
+ * \@Test
+ * public void testException() {
+ * try {
+ * rule.executeTarget("failingTarget");
+ * fail("Target should have thrown a BuildException");
+ * } catch (BuildException ex) {
+ * assertContains("Exception did not contain correct text", "Could not find compiler on classpath", ex.getMessage());
+ * }
+ * }
+ *
+ * }
+ * </code>
+ */
+public class BuildFileRule extends ExternalResource {
+
+ private Project project;
+
+ private StringBuffer logBuffer;
+ private StringBuffer fullLogBuffer;
+ private StringBuffer outputBuffer;
+ private StringBuffer errorBuffer;
+
+
+
+ /**
+ * Tidies up following a test execution. If the currently configured
+ * project has a <tt>tearDown</tt> target then this will automatically
+ * be called, otherwise this method will not perform any actions.
+ */
+ @Override
+ protected void after() {
+ if (project == null) {
+ // configureProject has not been called - nothing we can clean-up
+ return;
+ }
+ final String tearDown = "tearDown";
+ if (project.getTargets().containsKey(tearDown)) {
+ project.executeTarget(tearDown);
+ }
+ }
+
+ /**
+ * Gets the INFO, WARNING and ERROR message from the current execution,
+ * unless the logging level is set above any of these level in which case
+ * the message is excluded.
+ * This is only valid if configureProject() has been called.
+ *
+ * @return The INFO, WARN and ERROR messages in the log.
+ */
+ public String getLog() {
+ return logBuffer.toString();
+ }
+
+ /**
+ * Gets any messages that have been logged during the current execution, unless
+ * the logging level has been set above the log level defined in the message.
+ *
+ * Only valid if configureProject() has been called.
+ * @return the content of the log.
+ */
+ public String getFullLog() {
+ return fullLogBuffer.toString();
+ }
+
+ /**
+ * Provides all output sent to the System.out stream during the current execution.
+ * @return all output messages in a single string, normalised to have platform independent line breaks.
+ */
+ public String getOutput() {
+ return cleanBuffer(outputBuffer);
+ }
+
+ /**
+ * Provides all output sent to the System.err stream during the current execution.
+ * @return all error messages in a single string, normalised to have platform independent line breaks.
+ */
+ public String getError() {
+ return cleanBuffer(errorBuffer);
+ }
+
+ private String cleanBuffer(StringBuffer buffer) {
+ StringBuilder cleanedBuffer = new StringBuilder();
+ for (int i = 0; i < buffer.length(); i++) {
+ char ch = buffer.charAt(i);
+ if (ch != '\r') {
+ cleanedBuffer.append(ch);
+ }
+ }
+ return cleanedBuffer.toString();
+ }
+
+ /**
+ * Sets up to run the named project
+ *
+ * @param filename name of project file to run
+ */
+ public void configureProject(String filename) throws BuildException {
+ configureProject(filename, Project.MSG_DEBUG);
+ }
+
+ /**
+ * Sets up to run the named project
+ *
+ * @param filename name of project file to run
+ */
+ public void configureProject(String filename, int logLevel) throws BuildException {
+ logBuffer = new StringBuffer();
+ fullLogBuffer = new StringBuffer();
+ project = new Project();
+ project.init();
+ File antFile = new File(System.getProperty("root"), filename);
+ project.setProperty("ant.processid", ProcessUtil.getProcessId("<Process>"));
+ project.setProperty("ant.threadname", Thread.currentThread().getName());
+ project.setUserProperty("ant.file" , antFile.getAbsolutePath());
+ project.addBuildListener(new AntTestListener(logLevel));
+ ProjectHelper.configureProject(project, antFile);
+ }
+
+ /**
+ * Executes a target in the configured Ant build file. Requires #configureProject()
+ * to have been invoked before this call.
+ *
+ * @param targetName the target in the currently configured build file to run.
+ */
+ public void executeTarget(String targetName) {
+ outputBuffer = new StringBuffer();
+ PrintStream out = new PrintStream(new AntOutputStream(outputBuffer));
+ errorBuffer = new StringBuffer();
+ PrintStream err = new PrintStream(new AntOutputStream(errorBuffer));
+ logBuffer = new StringBuffer();
+ fullLogBuffer = new StringBuffer();
+
+ /* we synchronize to protect our custom output streams from being overridden
+ * by other tests executing targets concurrently. Ultimately this would only
+ * happen if we ran a multi-threaded test executing multiple targets at once, and
+ * this protection doesn't prevent a target from internally modifying the output
+ * stream during a test - but at least this scenario is fairly deterministic so
+ * easier to troubleshoot.
+ */
+ synchronized (System.out) {
+ PrintStream sysOut = System.out;
+ PrintStream sysErr = System.err;
+ sysOut.flush();
+ sysErr.flush();
+ try {
+ System.setOut(out);
+ System.setErr(err);
+ project.executeTarget(targetName);
+ } finally {
+ System.setOut(sysOut);
+ System.setErr(sysErr);
+ }
+ }
+ }
+
+ /**
+ * Get the project which has been configured for a test.
+ *
+ * @return the Project instance for this test.
+ */
+ public Project getProject() {
+ return project;
+ }
+
+
+ /**
+ * An output stream which saves contents to our buffer.
+ */
+ protected static class AntOutputStream extends OutputStream {
+ private StringBuffer buffer;
+
+ public AntOutputStream( StringBuffer buffer ) {
+ this.buffer = buffer;
+ }
+
+ public void write(int b) {
+ buffer.append((char)b);
+ }
+ }
+
+ /**
+ * Our own personal build listener.
+ */
+ private class AntTestListener implements BuildListener {
+ private int logLevel;
+
+ /**
+ * Constructs a test listener which will ignore log events
+ * above the given level.
+ */
+ public AntTestListener(int logLevel) {
+ this.logLevel = logLevel;
+ }
+
+ /**
+ * Fired before any targets are started.
+ */
+ public void buildStarted(BuildEvent event) {
+ }
+
+ /**
+ * Fired after the last target has finished. This event
+ * will still be thrown if an error occurred during the build.
+ *
+ * @see BuildEvent#getException()
+ */
+ public void buildFinished(BuildEvent event) {
+ }
+
+ /**
+ * Fired when a target is started.
+ *
+ * @see BuildEvent#getTarget()
+ */
+ public void targetStarted(BuildEvent event) {
+ }
+
+ /**
+ * Fired when a target has finished. This event will
+ * still be thrown if an error occurred during the build.
+ *
+ * @see BuildEvent#getException()
+ */
+ public void targetFinished(BuildEvent event) {
+ }
+
+ /**
+ * Fired when a task is started.
+ *
+ * @see BuildEvent#getTask()
+ */
+ public void taskStarted(BuildEvent event) {
+ }
+
+ /**
+ * Fired when a task has finished. This event will still
+ * be throw if an error occurred during the build.
+ *
+ * @see BuildEvent#getException()
+ */
+ public void taskFinished(BuildEvent event) {
+ }
+
+ /**
+ * Fired whenever a message is logged.
+ *
+ * @see BuildEvent#getMessage()
+ * @see BuildEvent#getPriority()
+ */
+ public void messageLogged(BuildEvent event) {
+ if (event.getPriority() > logLevel) {
+ // ignore event
+ return;
+ }
+
+ if (event.getPriority() == Project.MSG_INFO ||
+ event.getPriority() == Project.MSG_WARN ||
+ event.getPriority() == Project.MSG_ERR) {
+ logBuffer.append(event.getMessage());
+ }
+ fullLogBuffer.append(event.getMessage());
+ }
+ }
+
+ public File getOutputDir() {
+ return new File(getProject().getProperty("output"));
+ }
+
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/BuildFileTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/BuildFileTest.java
new file mode 100644
index 00000000..e18d71b8
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/BuildFileTest.java
@@ -0,0 +1,592 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant;
+
+import java.io.File;
+import java.io.PrintStream;
+import java.net.URL;
+
+import junit.framework.TestCase;
+import org.apache.tools.ant.util.ProcessUtil;
+
+/**
+ * A BuildFileTest is a TestCase which executes targets from an Ant buildfile
+ * for testing.
+ *
+ * This class provides a number of utility methods for particular build file
+ * tests which extend this class.
+ *
+ * @deprecated as of 1.9.4. Use BuildFileRule, Assert, AntAssert and JUnit4 annotations to drive tests instead
+ * @see org.apache.tools.ant.BuildFileRule
+ */
+@Deprecated
+public abstract class BuildFileTest extends TestCase {
+
+ protected Project project;
+
+ private StringBuffer logBuffer;
+ private StringBuffer fullLogBuffer;
+ private StringBuffer outBuffer;
+ private StringBuffer errBuffer;
+ private BuildException buildException;
+
+ /**
+ * Default constructor for the BuildFileTest object.
+ */
+ public BuildFileTest() {
+ super();
+ }
+
+ /**
+ * Constructor for the BuildFileTest object.
+ *
+ * @param name string to pass up to TestCase constructor
+ */
+ public BuildFileTest(String name) {
+ super(name);
+ }
+
+ /**
+ * Automatically calls the target called "tearDown"
+ * from the build file tested if it exits.
+ *
+ * This allows to use Ant tasks directly in the build file
+ * to clean up after each test. Note that no "setUp" target
+ * is automatically called, since it's trivial to have a
+ * test target depend on it.
+ */
+ protected void tearDown() throws Exception {
+ if (project == null) {
+ /*
+ * Maybe the BuildFileTest was subclassed and there is
+ * no initialized project. So we could avoid getting a
+ * NPE.
+ * If there is an initialized project getTargets() does
+ * not return null as it is initialized by an empty
+ * HashSet.
+ */
+ return;
+ }
+ final String tearDown = "tearDown";
+ if (project.getTargets().containsKey(tearDown)) {
+ project.executeTarget(tearDown);
+ }
+ }
+
+ /**
+ * run a target, expect for any build exception
+ *
+ * @param target target to run
+ * @param cause information string to reader of report
+ */
+ public void expectBuildException(String target, String cause) {
+ expectSpecificBuildException(target, cause, null);
+ }
+
+ /**
+ * Assert that only the given message has been logged with a
+ * priority &lt;= INFO when running the given target.
+ */
+ public void expectLog(String target, String log) {
+ executeTarget(target);
+ String realLog = getLog();
+ assertEquals(log, realLog);
+ }
+
+ /**
+ * Assert that the given substring is in the log messages.
+ */
+ public void assertLogContaining(String substring) {
+ String realLog = getLog();
+ assertTrue("expecting log to contain \"" + substring + "\" log was \""
+ + realLog + "\"",
+ realLog.indexOf(substring) >= 0);
+ }
+
+ /**
+ * Assert that the given substring is not in the log messages.
+ */
+ public void assertLogNotContaining(String substring) {
+ String realLog = getLog();
+ assertFalse("didn't expect log to contain \"" + substring + "\" log was \""
+ + realLog + "\"",
+ realLog.indexOf(substring) >= 0);
+ }
+
+ /**
+ * Assert that the given substring is in the output messages.
+ * @since Ant1.7
+ */
+ public void assertOutputContaining(String substring) {
+ assertOutputContaining(null, substring);
+ }
+
+ /**
+ * Assert that the given substring is in the output messages.
+ * @param message Print this message if the test fails. Defaults to
+ * a meaningful text if <tt>null</tt> is passed.
+ * @since Ant1.7
+ */
+ public void assertOutputContaining(String message, String substring) {
+ String realOutput = getOutput();
+ String realMessage = (message != null)
+ ? message
+ : "expecting output to contain \"" + substring + "\" output was \"" + realOutput + "\"";
+ assertTrue(realMessage, realOutput.indexOf(substring) >= 0);
+ }
+
+ /**
+ * Assert that the given substring is not in the output messages.
+ * @param message Print this message if the test fails. Defaults to
+ * a meaningful text if <tt>null</tt> is passed.
+ * @since Ant1.7
+ */
+ public void assertOutputNotContaining(String message, String substring) {
+ String realOutput = getOutput();
+ String realMessage = (message != null)
+ ? message
+ : "expecting output to not contain \"" + substring + "\" output was \"" + realOutput + "\"";
+ assertFalse(realMessage, realOutput.indexOf(substring) >= 0);
+ }
+
+ /**
+ * Assert that the given message has been logged with a priority &lt;= INFO when running the
+ * given target.
+ */
+ public void expectLogContaining(String target, String log) {
+ executeTarget(target);
+ assertLogContaining(log);
+ }
+
+ /**
+ * Assert that the given message has not been logged with a
+ * priority &lt;= INFO when running the given target.
+ */
+ public void expectLogNotContaining(String target, String log) {
+ executeTarget(target);
+ assertLogNotContaining(log);
+ }
+
+ /**
+ * Gets the log the BuildFileTest object.
+ * Only valid if configureProject() has been called.
+ *
+ * @pre logBuffer!=null
+ * @return The log value
+ */
+ public String getLog() {
+ return logBuffer.toString();
+ }
+
+ /**
+ * Assert that the given message has been logged with a priority
+ * &gt;= VERBOSE when running the given target.
+ */
+ public void expectDebuglog(String target, String log) {
+ executeTarget(target);
+ String realLog = getFullLog();
+ assertEquals(log, realLog);
+ }
+
+ /**
+ * Assert that the given substring is in the log messages.
+ */
+ public void assertDebuglogContaining(String substring) {
+ String realLog = getFullLog();
+ assertTrue("expecting debug log to contain \"" + substring
+ + "\" log was \""
+ + realLog + "\"",
+ realLog.indexOf(substring) >= 0);
+ }
+
+ /**
+ * Gets the log the BuildFileTest object.
+ *
+ * Only valid if configureProject() has been called.
+ *
+ * @pre fullLogBuffer!=null
+ * @return The log value
+ */
+ public String getFullLog() {
+ return fullLogBuffer.toString();
+ }
+
+ /**
+ * execute the target, verify output matches expectations
+ *
+ * @param target target to execute
+ * @param output output to look for
+ */
+ public void expectOutput(String target, String output) {
+ executeTarget(target);
+ String realOutput = getOutput();
+ assertEquals(output, realOutput.trim());
+ }
+
+ /**
+ * Executes the target, verify output matches expectations
+ * and that we got the named error at the end
+ *
+ * @param target target to execute
+ * @param output output to look for
+ * @param error Description of Parameter
+ */
+ public void expectOutputAndError(String target, String output, String error) {
+ executeTarget(target);
+ String realOutput = getOutput();
+ assertEquals(output, realOutput);
+ String realError = getError();
+ assertEquals(error, realError);
+ }
+
+ public String getOutput() {
+ return cleanBuffer(outBuffer);
+ }
+
+ public String getError() {
+ return cleanBuffer(errBuffer);
+ }
+
+ public BuildException getBuildException() {
+ return buildException;
+ }
+
+ private String cleanBuffer(StringBuffer buffer) {
+ StringBuffer cleanedBuffer = new StringBuffer();
+ for (int i = 0; i < buffer.length(); i++) {
+ char ch = buffer.charAt(i);
+ if (ch != '\r') {
+ cleanedBuffer.append(ch);
+ }
+ }
+ return cleanedBuffer.toString();
+ }
+
+ /**
+ * Sets up to run the named project
+ *
+ * @param filename name of project file to run
+ */
+ public void configureProject(String filename) throws BuildException {
+ configureProject(filename, Project.MSG_DEBUG);
+ }
+
+ /**
+ * Sets up to run the named project
+ *
+ * @param filename name of project file to run
+ */
+ public void configureProject(String filename, int logLevel)
+ throws BuildException {
+ logBuffer = new StringBuffer();
+ fullLogBuffer = new StringBuffer();
+ project = new Project();
+ project.init();
+ File antFile = new File(System.getProperty("root"), filename);
+ project.setUserProperty("ant.file" , antFile.getAbsolutePath());
+ // set two new properties to allow to build unique names when running multithreaded tests
+ project.setProperty("ant.processid", ProcessUtil.getProcessId("<Process>"));
+ project.setProperty("ant.threadname", Thread.currentThread().getName());
+ project.addBuildListener(new AntTestListener(logLevel));
+ ProjectHelper.configureProject(project, antFile);
+ }
+
+ /**
+ * Executes a target we have set up
+ *
+ * @pre configureProject has been called
+ * @param targetName target to run
+ */
+ public void executeTarget(String targetName) {
+ PrintStream sysOut = System.out;
+ PrintStream sysErr = System.err;
+ try {
+ sysOut.flush();
+ sysErr.flush();
+ outBuffer = new StringBuffer();
+ PrintStream out = new PrintStream(new AntOutputStream(outBuffer));
+ System.setOut(out);
+ errBuffer = new StringBuffer();
+ PrintStream err = new PrintStream(new AntOutputStream(errBuffer));
+ System.setErr(err);
+ logBuffer = new StringBuffer();
+ fullLogBuffer = new StringBuffer();
+ buildException = null;
+ project.executeTarget(targetName);
+ } finally {
+ System.setOut(sysOut);
+ System.setErr(sysErr);
+ }
+
+ }
+
+ /**
+ * Get the project which has been configured for a test.
+ *
+ * @return the Project instance for this test.
+ */
+ public Project getProject() {
+ return project;
+ }
+
+ /**
+ * Gets the directory of the project.
+ *
+ * @return the base dir of the project
+ */
+ public File getProjectDir() {
+ return project.getBaseDir();
+ }
+
+ /**
+ * get location of temporary directory pointed to by property "output"
+ * @return location of temporary directory pointed to by property "output"
+ * @since Ant 1.9.4
+ */
+ public File getOutputDir() {
+ return new File(project.getProperty("output"));
+ }
+
+ /**
+ * Runs a target, wait for a build exception.
+ *
+ * @param target target to run
+ * @param cause information string to reader of report
+ * @param msg the message value of the build exception we are waiting
+ * for set to null for any build exception to be valid
+ */
+ public void expectSpecificBuildException(String target, String cause, String msg) {
+ try {
+ executeTarget(target);
+ } catch (org.apache.tools.ant.BuildException ex) {
+ buildException = ex;
+ if ((null != msg) && (!ex.getMessage().equals(msg))) {
+ fail("Should throw BuildException because '" + cause
+ + "' with message '" + msg
+ + "' (actual message '" + ex.getMessage() + "' instead)");
+ }
+ return;
+ }
+ fail("Should throw BuildException because: " + cause);
+ }
+
+ /**
+ * run a target, expect an exception string
+ * containing the substring we look for (case sensitive match)
+ *
+ * @param target target to run
+ * @param cause information string to reader of report
+ * @param contains substring of the build exception to look for
+ */
+ public void expectBuildExceptionContaining(String target, String cause, String contains) {
+ try {
+ executeTarget(target);
+ } catch (org.apache.tools.ant.BuildException ex) {
+ buildException = ex;
+ if ((null != contains) && (ex.getMessage().indexOf(contains) == -1)) {
+ fail("Should throw BuildException because '" + cause + "' with message containing '" + contains + "' (actual message '" + ex.getMessage() + "' instead)");
+ }
+ return;
+ }
+ fail("Should throw BuildException because: " + cause);
+ }
+
+ /**
+ * call a target, verify property is as expected
+ *
+ * @param target build file target
+ * @param property property name
+ * @param value expected value
+ */
+ public void expectPropertySet(String target, String property, String value) {
+ executeTarget(target);
+ assertPropertyEquals(property, value);
+ }
+
+ /**
+ * assert that a property equals a value; comparison is case sensitive.
+ *
+ * @param property property name
+ * @param value expected value
+ */
+ public void assertPropertyEquals(String property, String value) {
+ String result = project.getProperty(property);
+ assertEquals("property " + property,value,result);
+ }
+
+ /**
+ * assert that a property equals "true".
+ *
+ * @param property property name
+ */
+ public void assertPropertySet(String property) {
+ assertPropertyEquals(property, "true");
+ }
+
+ /**
+ * assert that a property is null.
+ *
+ * @param property property name
+ */
+ public void assertPropertyUnset(String property) {
+ String result = project.getProperty(property);
+ if (result != null) {
+ fail("Expected property " + property
+ + " to be unset, but it is set to the value: " + result);
+ }
+ }
+
+ /**
+ * call a target, verify named property is "true".
+ *
+ * @param target build file target
+ * @param property property name
+ */
+ public void expectPropertySet(String target, String property) {
+ expectPropertySet(target, property, "true");
+ }
+
+ /**
+ * Call a target, verify property is null.
+ *
+ * @param target build file target
+ * @param property property name
+ */
+ public void expectPropertyUnset(String target, String property) {
+ expectPropertySet(target, property, null);
+ }
+
+ /**
+ * Retrieve a resource from the caller classloader to avoid
+ * assuming a vm working directory. The resource path must be
+ * relative to the package name or absolute from the root path.
+ *
+ * @param resource the resource to retrieve its url.
+ * @throws junit.framework.AssertionFailedError if the resource is not found.
+ */
+ public URL getResource(String resource){
+ URL url = getClass().getResource(resource);
+ assertNotNull("Could not find resource :" + resource, url);
+ return url;
+ }
+
+ /**
+ * an output stream which saves stuff to our buffer.
+ */
+ protected static class AntOutputStream extends java.io.OutputStream {
+ private StringBuffer buffer;
+
+ public AntOutputStream( StringBuffer buffer ) {
+ this.buffer = buffer;
+ }
+
+ public void write(int b) {
+ buffer.append((char)b);
+ }
+ }
+
+ /**
+ * Our own personal build listener.
+ */
+ private class AntTestListener implements BuildListener {
+ private int logLevel;
+
+ /**
+ * Constructs a test listener which will ignore log events
+ * above the given level.
+ */
+ public AntTestListener(int logLevel) {
+ this.logLevel = logLevel;
+ }
+
+ /**
+ * Fired before any targets are started.
+ */
+ public void buildStarted(BuildEvent event) {
+ }
+
+ /**
+ * Fired after the last target has finished. This event
+ * will still be thrown if an error occurred during the build.
+ *
+ * @see BuildEvent#getException()
+ */
+ public void buildFinished(BuildEvent event) {
+ }
+
+ /**
+ * Fired when a target is started.
+ *
+ * @see BuildEvent#getTarget()
+ */
+ public void targetStarted(BuildEvent event) {
+ //System.out.println("targetStarted " + event.getTarget().getName());
+ }
+
+ /**
+ * Fired when a target has finished. This event will
+ * still be thrown if an error occurred during the build.
+ *
+ * @see BuildEvent#getException()
+ */
+ public void targetFinished(BuildEvent event) {
+ //System.out.println("targetFinished " + event.getTarget().getName());
+ }
+
+ /**
+ * Fired when a task is started.
+ *
+ * @see BuildEvent#getTask()
+ */
+ public void taskStarted(BuildEvent event) {
+ //System.out.println("taskStarted " + event.getTask().getTaskName());
+ }
+
+ /**
+ * Fired when a task has finished. This event will still
+ * be throw if an error occurred during the build.
+ *
+ * @see BuildEvent#getException()
+ */
+ public void taskFinished(BuildEvent event) {
+ //System.out.println("taskFinished " + event.getTask().getTaskName());
+ }
+
+ /**
+ * Fired whenever a message is logged.
+ *
+ * @see BuildEvent#getMessage()
+ * @see BuildEvent#getPriority()
+ */
+ public void messageLogged(BuildEvent event) {
+ if (event.getPriority() > logLevel) {
+ // ignore event
+ return;
+ }
+
+ if (event.getPriority() == Project.MSG_INFO ||
+ event.getPriority() == Project.MSG_WARN ||
+ event.getPriority() == Project.MSG_ERR) {
+ logBuffer.append(event.getMessage());
+ }
+ fullLogBuffer.append(event.getMessage());
+ }
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/CaseTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/CaseTest.java
new file mode 100644
index 00000000..81cf385f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/CaseTest.java
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.apache.tools.ant.AntAssert.assertContains;
+import static org.junit.Assert.fail;
+
+/**
+ * Simple tests of build file processing
+ */
+public class CaseTest {
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/core/case.xml");
+ }
+
+ /**
+ * Test whether the build file treats nested elements without
+ * regard to case. This should not cause an exception.
+ */
+ @Test
+ public void testCaseSensitivity() {
+ buildRule.executeTarget("case-sensitivity");
+ }
+
+ /**
+ * Test whether the build file uses case when determining
+ * task names.
+ */
+ @Test
+ public void testTaskCase() {
+ try {
+ buildRule.executeTarget("taskcase");
+ fail("Build exception should have been thrown due to case sensitivity of name");
+ } catch(BuildException ex) {
+ assertContains("Task names should be case sensitive", "Problem: failed to create task or type ecHO", ex.getMessage());
+ }
+ }
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/DefaultLoggerTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/DefaultLoggerTest.java
new file mode 100644
index 00000000..00f4dfa1
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/DefaultLoggerTest.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant;
+
+import org.apache.tools.ant.util.StringUtils;
+import org.junit.Test;
+
+import java.io.PrintWriter;
+
+import static org.junit.Assert.assertEquals;
+
+public class DefaultLoggerTest {
+
+
+ private static String msg(Throwable error, boolean verbose) {
+ StringBuffer m = new StringBuffer();
+ DefaultLogger.throwableMessage(m, error, verbose);
+ return m.toString();
+ }
+
+ @Test
+ public void testThrowableMessage() throws Exception { // #43398
+ BuildException be = new BuildException("oops", new Location("build.xml", 1, 0));
+ assertEquals(
+ "build.xml:1: oops" + StringUtils.LINE_SEP,
+ msg(be, false));
+ be = ProjectHelper.addLocationToBuildException(be, new Location("build.xml", 2, 0));
+ assertEquals(
+ "build.xml:2: The following error occurred while executing this line:" + StringUtils.LINE_SEP +
+ "build.xml:1: oops" + StringUtils.LINE_SEP,
+ msg(be, false));
+ be = ProjectHelper.addLocationToBuildException(be, new Location("build.xml", 3, 0));
+ assertEquals(
+ "build.xml:3: The following error occurred while executing this line:" + StringUtils.LINE_SEP +
+ "build.xml:2: The following error occurred while executing this line:" + StringUtils.LINE_SEP +
+ "build.xml:1: oops" + StringUtils.LINE_SEP,
+ msg(be, false));
+ Exception x = new Exception("problem") {
+ public void printStackTrace(PrintWriter w) {
+ w.println("problem");
+ w.println(" at p.C.m");
+ }
+ };
+ assertEquals(
+ "problem" + StringUtils.LINE_SEP +
+ " at p.C.m" + StringUtils.LINE_SEP,
+ msg(x, false));
+ be = new BuildException(x, new Location("build.xml", 1, 0));
+ assertEquals(
+ "build.xml:1: problem" + StringUtils.LINE_SEP +
+ " at p.C.m" + StringUtils.LINE_SEP,
+ msg(be, false));
+ be = ProjectHelper.addLocationToBuildException(be, new Location("build.xml", 2, 0));
+ assertEquals(
+ "build.xml:2: The following error occurred while executing this line:" + StringUtils.LINE_SEP +
+ "build.xml:1: problem" + StringUtils.LINE_SEP +
+ " at p.C.m" + StringUtils.LINE_SEP,
+ msg(be, false));
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/DirectoryScannerTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/DirectoryScannerTest.java
new file mode 100644
index 00000000..c0c25fd7
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/DirectoryScannerTest.java
@@ -0,0 +1,588 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeTrue;
+import static org.junit.Assume.assumeFalse;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+
+import org.apache.tools.ant.taskdefs.condition.Os;
+import org.apache.tools.ant.types.selectors.TokenizedPath;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+/**
+ * JUnit testcases for org.apache.tools.ant.DirectoryScanner
+ *
+ */
+public class DirectoryScannerTest {
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ // keep track of what operating systems are supported here.
+ private boolean supportsSymlinks = Os.isFamily("unix");
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/core/directoryscanner.xml");
+ buildRule.getProject().executeTarget("setUp");
+ }
+
+ @Test
+ public void test1() {
+ DirectoryScanner ds = new DirectoryScanner();
+ ds.setBasedir(new File(buildRule.getProject().getProperty("output")));
+ ds.setIncludes(new String[] {"alpha"});
+ ds.scan();
+ compareFiles(ds, new String[] {} ,new String[] {"alpha"});
+ }
+
+ @Test
+ public void test2() {
+ DirectoryScanner ds = new DirectoryScanner();
+ ds.setBasedir(new File(buildRule.getProject().getProperty("output")));
+ ds.setIncludes(new String[] {"alpha/"});
+ ds.scan();
+ compareFiles(ds, new String[] {"alpha/beta/beta.xml",
+ "alpha/beta/gamma/gamma.xml"},
+ new String[] {"alpha", "alpha/beta", "alpha/beta/gamma"});
+ }
+
+ @Test
+ public void test3() {
+ DirectoryScanner ds = new DirectoryScanner();
+ ds.setBasedir(new File(buildRule.getProject().getProperty("output")));
+ ds.scan();
+ compareFiles(ds, new String[] {"alpha/beta/beta.xml",
+ "alpha/beta/gamma/gamma.xml"},
+ new String[] {"", "alpha", "alpha/beta",
+ "alpha/beta/gamma"});
+ }
+
+ @Test
+ public void testFullPathMatchesCaseSensitive() {
+ DirectoryScanner ds = new DirectoryScanner();
+ ds.setBasedir(new File(buildRule.getProject().getProperty("output")));
+ ds.setIncludes(new String[] {"alpha/beta/gamma/GAMMA.XML"});
+ ds.scan();
+ compareFiles(ds, new String[] {}, new String[] {});
+ }
+
+ @Test
+ public void testFullPathMatchesCaseInsensitive() {
+ DirectoryScanner ds = new DirectoryScanner();
+ ds.setCaseSensitive(false);
+ ds.setBasedir(new File(buildRule.getProject().getProperty("output")));
+ ds.setIncludes(new String[] {"alpha/beta/gamma/GAMMA.XML"});
+ ds.scan();
+ compareFiles(ds, new String[] {"alpha/beta/gamma/gamma.xml"},
+ new String[] {});
+ }
+
+ @Test
+ public void test2ButCaseInsensitive() {
+ DirectoryScanner ds = new DirectoryScanner();
+ ds.setBasedir(new File(buildRule.getProject().getProperty("output")));
+ ds.setIncludes(new String[] {"ALPHA/"});
+ ds.setCaseSensitive(false);
+ ds.scan();
+ compareFiles(ds, new String[] {"alpha/beta/beta.xml",
+ "alpha/beta/gamma/gamma.xml"},
+ new String[] {"alpha", "alpha/beta", "alpha/beta/gamma"});
+ }
+
+ @Test
+ public void testAllowSymlinks() {
+
+ assumeTrue("Current system does not support Symlinks", supportsSymlinks);
+
+ buildRule.getProject().executeTarget("symlink-setup");
+ DirectoryScanner ds = new DirectoryScanner();
+ ds.setBasedir(new File(buildRule.getProject().getProperty("output")));
+ ds.setIncludes(new String[] {"alpha/beta/gamma/"});
+ ds.scan();
+ compareFiles(ds, new String[] {"alpha/beta/gamma/gamma.xml"},
+ new String[] {"alpha/beta/gamma"});
+ }
+
+ @Test
+ public void testProhibitSymlinks() {
+ assumeTrue("Current system does not support Symlinks", supportsSymlinks);
+
+
+ buildRule.getProject().executeTarget("symlink-setup");
+ DirectoryScanner ds = new DirectoryScanner();
+ ds.setBasedir(new File(buildRule.getProject().getProperty("output")));
+ ds.setIncludes(new String[] {"alpha/beta/gamma/"});
+ ds.setFollowSymlinks(false);
+ ds.scan();
+ compareFiles(ds, new String[] {}, new String[] {});
+ }
+
+ // father and child pattern test
+ @Test
+ public void testOrderOfIncludePatternsIrrelevant() {
+ String [] expectedFiles = {"alpha/beta/beta.xml",
+ "alpha/beta/gamma/gamma.xml"};
+ String [] expectedDirectories = {"alpha/beta", "alpha/beta/gamma" };
+ DirectoryScanner ds = new DirectoryScanner();
+ ds.setBasedir(new File(buildRule.getProject().getProperty("output")));
+ ds.setIncludes(new String[] {"alpha/be?a/**", "alpha/beta/gamma/"});
+ ds.scan();
+ compareFiles(ds, expectedFiles, expectedDirectories);
+ // redo the test, but the 2 include patterns are inverted
+ ds = new DirectoryScanner();
+ ds.setBasedir(new File(buildRule.getProject().getProperty("output")));
+ ds.setIncludes(new String[] {"alpha/beta/gamma/", "alpha/be?a/**"});
+ ds.scan();
+ compareFiles(ds, expectedFiles, expectedDirectories);
+ }
+
+ @Test
+ public void testPatternsDifferInCaseScanningSensitive() {
+ DirectoryScanner ds = new DirectoryScanner();
+ ds.setBasedir(new File(buildRule.getProject().getProperty("output")));
+ ds.setIncludes(new String[] {"alpha/", "ALPHA/"});
+ ds.scan();
+ compareFiles(ds, new String[] {"alpha/beta/beta.xml",
+ "alpha/beta/gamma/gamma.xml"},
+ new String[] {"alpha", "alpha/beta", "alpha/beta/gamma"});
+ }
+
+ @Test
+ public void testPatternsDifferInCaseScanningInsensitive() {
+ DirectoryScanner ds = new DirectoryScanner();
+ ds.setBasedir(new File(buildRule.getProject().getProperty("output")));
+ ds.setIncludes(new String[] {"alpha/", "ALPHA/"});
+ ds.setCaseSensitive(false);
+ ds.scan();
+ compareFiles(ds, new String[] {"alpha/beta/beta.xml",
+ "alpha/beta/gamma/gamma.xml"},
+ new String[] {"alpha", "alpha/beta", "alpha/beta/gamma"});
+ }
+
+ @Test
+ public void testFullpathDiffersInCaseScanningSensitive() {
+ DirectoryScanner ds = new DirectoryScanner();
+ ds.setBasedir(new File(buildRule.getProject().getProperty("output")));
+ ds.setIncludes(new String[] {
+ "alpha/beta/gamma/gamma.xml",
+ "alpha/beta/gamma/GAMMA.XML"
+ });
+ ds.scan();
+ compareFiles(ds, new String[] {"alpha/beta/gamma/gamma.xml"},
+ new String[] {});
+ }
+
+ @Test
+ public void testFullpathDiffersInCaseScanningInsensitive() {
+ DirectoryScanner ds = new DirectoryScanner();
+ ds.setBasedir(new File(buildRule.getProject().getProperty("output")));
+ ds.setIncludes(new String[] {
+ "alpha/beta/gamma/gamma.xml",
+ "alpha/beta/gamma/GAMMA.XML"
+ });
+ ds.setCaseSensitive(false);
+ ds.scan();
+ compareFiles(ds, new String[] {"alpha/beta/gamma/gamma.xml"},
+ new String[] {});
+ }
+
+ @Test
+ public void testParentDiffersInCaseScanningSensitive() {
+ DirectoryScanner ds = new DirectoryScanner();
+ ds.setBasedir(new File(buildRule.getProject().getProperty("output")));
+ ds.setIncludes(new String[] {"alpha/", "ALPHA/beta/"});
+ ds.scan();
+ compareFiles(ds, new String[] {"alpha/beta/beta.xml",
+ "alpha/beta/gamma/gamma.xml"},
+ new String[] {"alpha", "alpha/beta", "alpha/beta/gamma"});
+ }
+
+ @Test
+ public void testParentDiffersInCaseScanningInsensitive() {
+ DirectoryScanner ds = new DirectoryScanner();
+ ds.setBasedir(new File(buildRule.getProject().getProperty("output")));
+ ds.setIncludes(new String[] {"alpha/", "ALPHA/beta/"});
+ ds.setCaseSensitive(false);
+ ds.scan();
+ compareFiles(ds, new String[] {"alpha/beta/beta.xml",
+ "alpha/beta/gamma/gamma.xml"},
+ new String[] {"alpha", "alpha/beta", "alpha/beta/gamma"});
+ }
+
+ /**
+ * Test case for setFollowLinks() and associated functionality.
+ * Only supports test on Linux at the moment because Java has
+ * no real notion of symlinks built in, so an os-specfic call
+ * to Runtime.exec() must be made to create a link to test against.
+ * @throws InterruptedException
+ */
+ @Test
+ public void testSetFollowLinks() throws IOException, InterruptedException {
+ if (supportsSymlinks) {
+ File linkFile = new File(System.getProperty("root"), "src/main/org/apache/tools/ThisIsALink");
+ System.err.println("link exists pre-test? " + linkFile.exists());
+
+ try {
+ // add conditions and more commands as soon as the need arises
+ String[] command = new String[] {
+ "ln", "-s", "ant", linkFile.getAbsolutePath()
+ };
+ Process process = Runtime.getRuntime().exec(command);
+ assertEquals("0 return code expected for external process", 0, process.waitFor());
+
+
+ File dir = new File(System.getProperty("root"), "src/main/org/apache/tools");
+
+ DirectoryScanner ds = new DirectoryScanner();
+
+ // followLinks should be true by default, but if this ever
+ // changes we will need this line.
+ ds.setFollowSymlinks(true);
+
+ ds.setBasedir(dir);
+ ds.setExcludes(new String[] {"ant/**"});
+ ds.scan();
+
+ boolean haveZipPackage = false;
+ boolean haveTaskdefsPackage = false;
+
+ String[] included = ds.getIncludedDirectories();
+ for (int i=0; i<included.length; i++) {
+ if (included[i].equals("zip")) {
+ haveZipPackage = true;
+ } else if (included[i].equals("ThisIsALink"
+ + File.separator
+ + "taskdefs")) {
+ haveTaskdefsPackage = true;
+ }
+ }
+
+ // if we followed the symlink we just made we should
+ // bypass the excludes.
+
+ assertTrue("(1) zip package included", haveZipPackage);
+ assertTrue("(1) taskdefs package included",
+ haveTaskdefsPackage);
+
+
+ ds = new DirectoryScanner();
+ ds.setFollowSymlinks(false);
+
+ ds.setBasedir(dir);
+ ds.setExcludes(new String[] {"ant/**"});
+ ds.scan();
+
+ haveZipPackage = false;
+ haveTaskdefsPackage = false;
+ included = ds.getIncludedDirectories();
+ for (int i=0; i<included.length; i++) {
+ if (included[i].equals("zip")) {
+ haveZipPackage = true;
+ } else if (included[i].equals("ThisIsALink"
+ + File.separator
+ + "taskdefs")) {
+ haveTaskdefsPackage = true;
+ }
+ }
+ assertTrue("(2) zip package included", haveZipPackage);
+ assertTrue("(2) taskdefs package not included",
+ !haveTaskdefsPackage);
+
+ } finally {
+ if (!linkFile.delete()) {
+ //TODO log this?
+ //throw new RuntimeException("Failed to delete " + linkFile);
+ }
+
+ }
+ }
+ }
+
+ @Test
+ public void testExcludeOneFile() {
+ DirectoryScanner ds = new DirectoryScanner();
+ ds.setBasedir(new File(buildRule.getProject().getProperty("output")));
+ ds.setIncludes(new String[] {
+ "**/*.xml"
+ });
+ ds.setExcludes(new String[] {
+ "alpha/beta/b*xml"
+ });
+ ds.scan();
+ compareFiles(ds, new String[] {"alpha/beta/gamma/gamma.xml"},
+ new String[] {});
+ }
+
+ @Test
+ public void testExcludeHasPrecedence() {
+ DirectoryScanner ds = new DirectoryScanner();
+ ds.setBasedir(new File(buildRule.getProject().getProperty("output")));
+ ds.setIncludes(new String[] {
+ "alpha/**"
+ });
+ ds.setExcludes(new String[] {
+ "alpha/**"
+ });
+ ds.scan();
+ compareFiles(ds, new String[] {},
+ new String[] {});
+
+ }
+
+ @Test
+ public void testAlternateIncludeExclude() {
+ DirectoryScanner ds = new DirectoryScanner();
+ ds.setBasedir(new File(buildRule.getProject().getProperty("output")));
+ ds.setIncludes(new String[] {
+ "alpha/**",
+ "alpha/beta/gamma/**"
+ });
+ ds.setExcludes(new String[] {
+ "alpha/beta/**"
+ });
+ ds.scan();
+ compareFiles(ds, new String[] {},
+ new String[] {"alpha"});
+
+ }
+
+ @Test
+ public void testAlternateExcludeInclude() {
+ DirectoryScanner ds = new DirectoryScanner();
+ ds.setBasedir(new File(buildRule.getProject().getProperty("output")));
+ ds.setExcludes(new String[] {
+ "alpha/**",
+ "alpha/beta/gamma/**"
+ });
+ ds.setIncludes(new String[] {
+ "alpha/beta/**"
+ });
+ ds.scan();
+ compareFiles(ds, new String[] {},
+ new String[] {});
+
+ }
+
+ /**
+ * Test inspired by Bug#1415.
+ */
+ @Test
+ public void testChildrenOfExcludedDirectory() {
+ buildRule.getProject().executeTarget("children-of-excluded-dir-setup");
+ DirectoryScanner ds = new DirectoryScanner();
+ ds.setBasedir(new File(buildRule.getProject().getProperty("output")));
+ ds.setExcludes(new String[] {"alpha/**"});
+ ds.setFollowSymlinks(false);
+ ds.scan();
+ compareFiles(ds, new String[] {"delta/delta.xml"},
+ new String[] {"", "delta"});
+
+ ds = new DirectoryScanner();
+ ds.setBasedir(new File(buildRule.getProject().getProperty("output")));
+ ds.setExcludes(new String[] {"alpha"});
+ ds.setFollowSymlinks(false);
+ ds.scan();
+ compareFiles(ds, new String[] {"alpha/beta/beta.xml",
+ "alpha/beta/gamma/gamma.xml",
+ "delta/delta.xml"},
+ new String[] {"", "alpha/beta", "alpha/beta/gamma", "delta"});
+
+ }
+
+ @Test
+ public void testIsExcludedDirectoryScanned() {
+ String shareclassloader = buildRule.getProject().getProperty("tests.and.ant.share.classloader");
+ // when the test is started by the build.xml of ant
+ // if the property tests.and.ant.share.classloader is not set in the build.xml
+ // a sysproperty with name tests.and.ant.share.classloader and value
+ // ${tests.and.ant.share.classloader} will be set
+ // we are trying to catch this here.
+ assumeFalse("cannot execute testIsExcludedDirectoryScanned when tests are forked, " +
+ "package private method called", shareclassloader == null
+ || (shareclassloader != null && shareclassloader.indexOf("${") == 0));
+ buildRule.getProject().executeTarget("children-of-excluded-dir-setup");
+ DirectoryScanner ds = new DirectoryScanner();
+ ds.setBasedir(new File(buildRule.getProject().getProperty("output")));
+
+ ds.setExcludes(new String[] {"**/gamma/**"});
+ ds.setFollowSymlinks(false);
+ ds.scan();
+ Set<String> set = ds.getScannedDirs();
+ assertFalse("empty set", set.isEmpty());
+ String s = "alpha/beta/gamma/".replace('/', File.separatorChar);
+ assertFalse("scanned " + s, set.contains(s));
+ }
+
+ @Test
+ public void testAbsolute1() {
+ buildRule.getProject().executeTarget("extended-setup");
+ DirectoryScanner ds = new DirectoryScanner();
+ String tmpdir = buildRule.getProject().getProperty("output").replace(
+ File.separatorChar, '/');
+ ds.setIncludes(new String[] {tmpdir + "/**/*"});
+ ds.scan();
+ compareFiles(ds, new String[] {tmpdir + "/alpha/beta/beta.xml",
+ tmpdir + "/alpha/beta/gamma/gamma.xml",
+ tmpdir + "/delta/delta.xml"},
+ new String[] {tmpdir + "/alpha",
+ tmpdir + "/alpha/beta",
+ tmpdir + "/alpha/beta/gamma",
+ tmpdir + "/delta"});
+ }
+
+ @Test
+ public void testAbsolute2() {
+ DirectoryScanner ds = new DirectoryScanner();
+ ds.setIncludes(new String[] {"alpha/**", "alpha/beta/gamma/**"});
+ ds.scan();
+ String[] mt = new String[0];
+ compareFiles(ds, mt, mt);
+ }
+
+ @Test
+ public void testAbsolute3() {
+ buildRule.getProject().executeTarget("extended-setup");
+ DirectoryScanner ds = new DirectoryScanner();
+ String tmpdir = buildRule.getProject().getProperty("output").replace(
+ File.separatorChar, '/');
+ ds.setIncludes(new String[] {tmpdir + "/**/*"});
+ ds.setExcludes(new String[] {"**/alpha",
+ "**/delta/*"});
+ ds.scan();
+ compareFiles(ds, new String[] {tmpdir + "/alpha/beta/beta.xml",
+ tmpdir + "/alpha/beta/gamma/gamma.xml"},
+ new String[] {tmpdir + "/alpha/beta",
+ tmpdir + "/alpha/beta/gamma",
+ tmpdir + "/delta"});
+ }
+
+ @Test
+ public void testAbsolute4() {
+ buildRule.getProject().executeTarget("extended-setup");
+ DirectoryScanner ds = new DirectoryScanner();
+ String tmpdir = buildRule.getProject().getProperty("output").replace(
+ File.separatorChar, '/') ;
+ ds.setIncludes(new String[] {tmpdir + "/alpha/beta/**/*",
+ tmpdir + "/delta/*"});
+ ds.setExcludes(new String[] {"**/beta.xml"});
+ ds.scan();
+ compareFiles(ds, new String[] {tmpdir + "/alpha/beta/gamma/gamma.xml",
+ tmpdir + "/delta/delta.xml"},
+ new String[] {tmpdir + "/alpha/beta/gamma"});
+ }
+
+ @Test
+ public void testAbsolute5() {
+ //testing drive letter search from root:
+ assumeTrue("Can't use drive letters on non DOS or Netware systems", (Os.isFamily("dos") || Os.isFamily("netware")));
+ DirectoryScanner ds = new DirectoryScanner();
+ String pattern = new File(File.separator).getAbsolutePath().toUpperCase() + "*";
+ ds.setIncludes(new String[] {pattern});
+ ds.scan();
+ //if this is our context we assume there must be something here:
+ assertTrue("should have at least one resident file",
+ ds.getIncludedFilesCount() + ds.getIncludedDirsCount() > 0);
+ }
+
+ private void compareFiles(DirectoryScanner ds, String[] expectedFiles,
+ String[] expectedDirectories) {
+ String includedFiles[] = ds.getIncludedFiles();
+ String includedDirectories[] = ds.getIncludedDirectories();
+ assertEquals("file present: ", expectedFiles.length,
+ includedFiles.length);
+ assertEquals("directories present: ", expectedDirectories.length,
+ includedDirectories.length);
+
+ TreeSet<String> files = new TreeSet<String>();
+ for (int counter = 0; counter < includedFiles.length; counter++) {
+ files.add(includedFiles[counter].replace(File.separatorChar, '/'));
+ }
+ TreeSet<String> directories = new TreeSet<String>();
+ for (int counter = 0; counter < includedDirectories.length; counter++) {
+ directories.add(includedDirectories[counter]
+ .replace(File.separatorChar, '/'));
+ }
+
+ String currentfile;
+ Iterator<String> i = files.iterator();
+ int counter = 0;
+ while (i.hasNext()) {
+ currentfile = (String) i.next();
+ assertEquals(expectedFiles[counter], currentfile);
+ counter++;
+ }
+ String currentdirectory;
+ Iterator<String> dirit = directories.iterator();
+ counter = 0;
+ while (dirit.hasNext()) {
+ currentdirectory = (String) dirit.next();
+ assertEquals(expectedDirectories[counter], currentdirectory);
+ counter++;
+ }
+ }
+
+ @Test
+ public void testRecursiveExcludes() throws Exception {
+ DirectoryScanner ds = new DirectoryScanner();
+ ds.setBasedir(new File(buildRule.getProject().getProperty("output")));
+ ds.setExcludes(new String[] {"**/beta/**"});
+ ds.scan();
+ List<String> dirs = Arrays.asList(ds.getExcludedDirectories());
+ assertEquals(2, dirs.size());
+ assertTrue("beta is excluded",
+ dirs.contains("alpha/beta".replace('/', File.separatorChar)));
+ assertTrue("gamma is excluded",
+ dirs.contains("alpha/beta/gamma".replace('/',
+ File.separatorChar)));
+ List<String> files = Arrays.asList(ds.getExcludedFiles());
+ assertEquals(2, files.size());
+ assertTrue("beta.xml is excluded",
+ files.contains("alpha/beta/beta.xml"
+ .replace('/', File.separatorChar)));
+ assertTrue("gamma.xml is excluded",
+ files.contains("alpha/beta/gamma/gamma.xml"
+ .replace('/', File.separatorChar)));
+ }
+
+ @Test
+ public void testContentsExcluded() {
+ DirectoryScanner ds = new DirectoryScanner();
+ ds.setBasedir(new File("."));
+ ds.setIncludes(new String[] {"**"});
+ ds.addDefaultExcludes();
+ ds.ensureNonPatternSetsReady();
+ File f = new File(".svn");
+ TokenizedPath p = new TokenizedPath(f.getAbsolutePath());
+ assertTrue(ds.contentsExcluded(p));
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/DispatchTaskTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/DispatchTaskTest.java
new file mode 100644
index 00000000..604a0a2e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/DispatchTaskTest.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant;
+
+import static org.junit.Assert.fail;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+public class DispatchTaskTest {
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/core/dispatch/dispatch.xml");
+ }
+
+ @Test
+ public void testDisp() {
+ try {
+ buildRule.executeTarget("disp");
+ fail("BuildException should have been thrown");
+ } catch(BuildException ex) {
+ //FIXME the previous method used here ignored the build exception - what are we trying to test
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/DummyTaskAbstract.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/DummyTaskAbstract.java
new file mode 100644
index 00000000..18fe09d2
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/DummyTaskAbstract.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant;
+
+import org.apache.tools.ant.Task;
+
+public abstract class DummyTaskAbstract extends Task {
+
+ public DummyTaskAbstract() {
+ }
+
+ public void execute() {
+ }
+
+ public abstract void abstractDummy();
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/DummyTaskInterface.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/DummyTaskInterface.java
new file mode 100644
index 00000000..8ae5f5b3
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/DummyTaskInterface.java
@@ -0,0 +1,25 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant;
+
+public interface DummyTaskInterface {
+
+ void execute();
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/DummyTaskOk.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/DummyTaskOk.java
new file mode 100644
index 00000000..ff8fdab3
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/DummyTaskOk.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant;
+
+import org.apache.tools.ant.Task;
+
+public class DummyTaskOk extends Task {
+
+ public DummyTaskOk() {
+ }
+
+ public void execute() {
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/DummyTaskOkNonTask.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/DummyTaskOkNonTask.java
new file mode 100644
index 00000000..234abd61
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/DummyTaskOkNonTask.java
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant;
+
+public class DummyTaskOkNonTask {
+
+ public DummyTaskOkNonTask() {
+ }
+
+ public void execute() {
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/DummyTaskWithNonPublicExecute.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/DummyTaskWithNonPublicExecute.java
new file mode 100644
index 00000000..766283d6
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/DummyTaskWithNonPublicExecute.java
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant;
+
+public class DummyTaskWithNonPublicExecute {
+
+ public DummyTaskWithNonPublicExecute() {
+ }
+
+ void execute() {
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/DummyTaskWithNonVoidExecute.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/DummyTaskWithNonVoidExecute.java
new file mode 100644
index 00000000..876b9b70
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/DummyTaskWithNonVoidExecute.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant;
+
+public class DummyTaskWithNonVoidExecute {
+
+ public DummyTaskWithNonVoidExecute() {
+ }
+
+ public int execute() {
+ return 0;
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/DummyTaskWithoutDefaultConstructor.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/DummyTaskWithoutDefaultConstructor.java
new file mode 100644
index 00000000..40661f5e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/DummyTaskWithoutDefaultConstructor.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant;
+
+import org.apache.tools.ant.Task;
+
+public class DummyTaskWithoutDefaultConstructor extends Task {
+
+ public DummyTaskWithoutDefaultConstructor(int dummy) {
+ }
+
+ public void execute() {
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/DummyTaskWithoutExecute.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/DummyTaskWithoutExecute.java
new file mode 100644
index 00000000..6d5ea006
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/DummyTaskWithoutExecute.java
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant;
+
+public class DummyTaskWithoutExecute {
+
+ public DummyTaskWithoutExecute() {
+ }
+
+ public void execute(String dummy) {
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/DummyTaskWithoutPublicConstructor.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/DummyTaskWithoutPublicConstructor.java
new file mode 100644
index 00000000..0ec4ff8e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/DummyTaskWithoutPublicConstructor.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant;
+
+import org.apache.tools.ant.Task;
+
+public class DummyTaskWithoutPublicConstructor extends Task {
+
+ DummyTaskWithoutPublicConstructor() {
+ }
+
+ public void execute() {
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/ExecutorTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/ExecutorTest.java
new file mode 100644
index 00000000..6a370935
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/ExecutorTest.java
@@ -0,0 +1,171 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import java.util.Vector;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+/**
+ * Executor tests
+ */
+public class ExecutorTest implements BuildListener {
+
+ private static final String SINGLE_CHECK
+ = "org.apache.tools.ant.helper.SingleCheckExecutor";
+ private static final String IGNORE_DEPS
+ = "org.apache.tools.ant.helper.IgnoreDependenciesExecutor";
+
+ private static final Vector<String> TARGET_NAMES;
+ static {
+ TARGET_NAMES = new Vector<String>();
+ TARGET_NAMES.add("a");
+ TARGET_NAMES.add("b");
+ }
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ private int targetCount;
+
+ /* BuildListener stuff */
+ public void targetStarted(BuildEvent event) {
+ targetCount++;
+ }
+ public void buildStarted(BuildEvent event) {}
+ public void buildFinished(BuildEvent event) {}
+ public void targetFinished(BuildEvent event) {}
+ public void taskStarted(BuildEvent event) {}
+ public void taskFinished(BuildEvent event) {}
+ public void messageLogged(BuildEvent event) {}
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/core/executor.xml");
+ targetCount = 0;
+ buildRule.getProject().addBuildListener(this);
+ }
+
+ private Project getProject(String e) {
+ return getProject(e, false);
+ }
+
+ private Project getProject(String e, boolean f) {
+ return getProject(e, f, false);
+ }
+
+ private Project getProject(String e, boolean f, boolean k) {
+ Project p = buildRule.getProject();
+ p.setNewProperty("ant.executor.class", e);
+ p.setKeepGoingMode(k);
+ if (f) {
+ p.setNewProperty("failfoo", "foo");
+ }
+ return p;
+ }
+
+ @Test
+ public void testDefaultExecutor() {
+ buildRule.getProject().executeTargets(TARGET_NAMES);
+ assertEquals(4, targetCount);
+ }
+
+ @Test
+ public void testSingleCheckExecutor() {
+ getProject(SINGLE_CHECK).executeTargets(TARGET_NAMES);
+ assertEquals(3, targetCount);
+ }
+
+ @Test
+ public void testIgnoreDependenciesExecutor() {
+ getProject(IGNORE_DEPS).executeTargets(TARGET_NAMES);
+ assertEquals(2, targetCount);
+ }
+
+ @Test
+ public void testDefaultFailure() {
+ try {
+ getProject(null, true).executeTargets(TARGET_NAMES);
+ fail("should fail");
+ } catch (BuildException e) {
+ assertEquals("failfoo", e.getMessage());
+ assertEquals(1, targetCount);
+ }
+ }
+
+ @Test
+ public void testSingleCheckFailure() {
+ try {
+ getProject(SINGLE_CHECK, true).executeTargets(TARGET_NAMES);
+ fail("should fail");
+ } catch (BuildException e) {
+ assertEquals("failfoo", e.getMessage());
+ assertEquals(1, targetCount);
+ }
+ }
+
+ @Test
+ public void testIgnoreDependenciesFailure() {
+ //no foo failure; foo is never executed as dependencies are ignored!
+ getProject(IGNORE_DEPS, true).executeTargets(TARGET_NAMES);
+ }
+
+ @Test
+ public void testKeepGoingDefault() {
+ try {
+ getProject(null, true, true).executeTargets(TARGET_NAMES);
+ fail("should fail");
+ } catch (BuildException e) {
+ assertEquals("failfoo", e.getMessage());
+ assertEquals(2, targetCount);
+ }
+ }
+
+ @Test
+ public void testKeepGoingSingleCheck() {
+ try {
+ getProject(SINGLE_CHECK, true, true).executeTargets(TARGET_NAMES);
+ fail("should fail");
+ } catch (BuildException e) {
+ assertEquals("failfoo", e.getMessage());
+ assertEquals(1, targetCount);
+ }
+ }
+
+ @Test
+ public void testKeepGoingIgnoreDependencies() {
+ try {
+ //explicitly add foo for failure
+ Vector<String> targetNames = new Vector<String>(TARGET_NAMES);
+ targetNames.add(0, "foo");
+ getProject(IGNORE_DEPS, true, true).executeTargets(targetNames);
+ fail("should fail");
+ } catch (BuildException e) {
+ assertEquals("failfoo", e.getMessage());
+ assertEquals(3, targetCount);
+ }
+ }
+
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/ExtendedTaskdefTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/ExtendedTaskdefTest.java
new file mode 100644
index 00000000..a1412414
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/ExtendedTaskdefTest.java
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant;
+
+import static org.junit.Assert.fail;
+
+import static org.apache.tools.ant.AntAssert.assertContains;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+/**
+ * created 16-Mar-2006 12:25:12
+ */
+
+public class ExtendedTaskdefTest {
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/core/extended-taskdef.xml");
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ buildRule.executeTarget("teardown");
+ }
+
+ @Test
+ public void testRun() throws Exception {
+ try {
+ buildRule.executeTarget("testRun");
+ fail("BuildException should have been thrown");
+ } catch(BuildException ex) {
+ assertContains("exception thrown by the subclass", "executing the Foo task", ex.getMessage());
+ }
+ }
+
+ @Test
+ public void testRun2() throws Exception {
+ try {
+ buildRule.executeTarget("testRun2");
+ fail("BuildException should have been thrown");
+ } catch(BuildException ex) {
+ assertContains("exception thrown by the subclass", "executing the Foo task", ex.getMessage());
+ }
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/FileUtilities.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/FileUtilities.java
new file mode 100644
index 00000000..a9de5cea
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/FileUtilities.java
@@ -0,0 +1,88 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant;
+
+
+import org.apache.tools.ant.util.FileUtils;
+
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+
+import static org.junit.Assume.assumeTrue;
+
+public class FileUtilities {
+
+ /**
+ * Reads the contents of a file into a String.
+ * @param project the project containing the base directory the file is in.
+ * @param fileName the path to the file from the base directory.
+ * @return the contents of the given file as a string.
+ * @throws IOException on error reading the file (not existing, not readable etc)
+ */
+ public static String getFileContents(Project project, String fileName) throws IOException {
+ return getFileContents(new File(project.getBaseDir(), fileName));
+ }
+
+ /**
+ * Reads the contents of a file into a String.
+ * @param file the file to read.
+ * @return the contents of the given file as a string.
+ * @throws IOException on error reading the file (not existing, not readable etc)
+ */
+ public static String getFileContents(File file) throws IOException {
+ FileReader rdr = null;
+ try {
+ rdr = new FileReader(file);
+ return FileUtils.readFully(rdr);
+ }
+ finally {
+ if (rdr != null) {
+ rdr.close();
+ }
+ }
+ }
+
+
+ /**
+ * Modified the timestamp on a file so it's <tt>seconds</tt> earlier than it was before. Where <tt>file</tt>
+ * is a directory, this function recurses into all child files (and directories) and reduces their modified
+ * timestamps by the same range, rather than set all timestamps to the same time.
+ * @param file the file to change, or the directory to change then recurse into
+ * @param seconds how many seconds to roll the timestamp back by
+ */
+ public static void rollbackTimetamps(File file, long seconds) {
+ if (null == file || !file.exists()) {
+ return;
+ }
+
+ assumeTrue(file.setLastModified(file.lastModified() - (seconds * 1000)));
+
+ if (file.isDirectory()) {
+ File[] children = file.listFiles();
+ // only possible if exception occurs, or abstract path was not valid
+ if (children == null) {
+ return;
+ }
+ for (File child : children) {
+ rollbackTimetamps(child, seconds);
+ }
+ }
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/ImmutableTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/ImmutableTest.java
new file mode 100644
index 00000000..cd65a5a6
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/ImmutableTest.java
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertEquals;
+
+/**
+ */
+public class ImmutableTest {
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/core/immutable.xml");
+ }
+
+ // override allowed on <available>
+ @Test
+ public void test1() {
+ buildRule.executeTarget("test1");
+ assertEquals("override",buildRule.getProject().getProperty("test"));
+ }
+
+ // ensure <tstamp>'s new prefix attribute is working
+ @Test
+ public void test2() {
+ buildRule.executeTarget("test2");
+ assertNotNull(buildRule.getProject().getProperty("DSTAMP"));
+ assertNotNull(buildRule.getProject().getProperty("start.DSTAMP"));
+ }
+
+ // ensure <tstamp> follows the immutability rule
+ @Test
+ public void test3() {
+ buildRule.executeTarget("test3");
+ assertEquals("original", buildRule.getProject().getProperty("DSTAMP"));
+ }
+
+ // ensure <condition> follows the immutability rule
+ @Test
+ public void test4() {
+ buildRule.executeTarget("test4");
+ assertEquals("original", buildRule.getProject().getProperty("test"));
+ }
+ // ensure <checksum> follows the immutability rule
+ @Test
+ public void test5() {
+ buildRule.executeTarget("test5");
+ assertEquals("original", buildRule.getProject().getProperty("test"));
+ }
+
+ // ensure <exec> follows the immutability rule
+ @Test
+ public void test6() {
+ buildRule.executeTarget("test6");
+ assertEquals("original", buildRule.getProject().getProperty("test1"));
+ assertEquals("original", buildRule.getProject().getProperty("test2"));
+ }
+
+ // ensure <pathconvert> follows the immutability rule
+ @Test
+ public void test7() {
+ buildRule.executeTarget("test7");
+ assertEquals("original", buildRule.getProject().getProperty("test"));
+ }
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/IncludeTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/IncludeTest.java
new file mode 100644
index 00000000..54e61a41
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/IncludeTest.java
@@ -0,0 +1,151 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant;
+
+import static org.apache.tools.ant.AntAssert.assertContains;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import org.junit.Rule;
+import org.junit.Test;
+
+/**
+ * Test the build file inclusion using XML entities.
+ *
+ */
+public class IncludeTest {
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ @Test
+ public void test1() {
+ buildRule.configureProject("src/etc/testcases/core/include/basic/include.xml");
+ buildRule.executeTarget("test1");
+ assertEquals("from included entity", buildRule.getLog());
+ }
+
+ @Test
+ public void test2() {
+ buildRule.configureProject("src/etc/testcases/core/include/frag#ment/include.xml");
+ buildRule.executeTarget("test1");
+ assertEquals("from included entity", buildRule.getLog());
+ }
+
+ @Test
+ public void test3() {
+ buildRule.configureProject("src/etc/testcases/core/include/frag#ment/simple.xml");
+ buildRule.executeTarget("test1");
+ assertEquals("from simple buildfile", buildRule.getLog());
+ }
+
+ @Test
+ public void test4() {
+ buildRule.configureProject("src/etc/testcases/core/include/basic/relative.xml");
+ buildRule.executeTarget("test1");
+ assertEquals("from included entity", buildRule.getLog());
+ }
+
+ @Test
+ public void test5() {
+ buildRule.configureProject("src/etc/testcases/core/include/frag#ment/relative.xml");
+ buildRule.executeTarget("test1");
+ assertEquals("from included entity", buildRule.getLog());
+ }
+
+ @Test
+ public void testParseErrorInIncluding() {
+ try {
+ buildRule.configureProject("src/etc/testcases/core/include/including_file_parse_error/build.xml");
+ fail("should have caused a parser exception");
+ } catch (BuildException e) {
+ assertContains(e.getLocation().toString()
+ + " should refer to build.xml",
+ "build.xml:", e.getLocation().toString());
+ }
+ }
+
+ @Test
+ public void testTaskErrorInIncluding() {
+ buildRule.configureProject("src/etc/testcases/core/include/including_file_task_error/build.xml");
+ try {
+ buildRule.executeTarget("test");
+ fail("should have cause a build failure");
+ } catch (BuildException e) {
+ assertTrue(e.getMessage()
+ + " should start with \'Warning: Could not find",
+ e.getMessage().startsWith("Warning: Could not find file "));
+ assertTrue(e.getLocation().toString()
+ + " should end with build.xml:14: ",
+ e.getLocation().toString().endsWith("build.xml:14: "));
+ }
+ }
+
+ @Test
+ public void testParseErrorInIncluded() {
+ try {
+ buildRule.configureProject("src/etc/testcases/core/include/included_file_parse_error/build.xml");
+ fail("should have caused a parser exception");
+ } catch (BuildException e) {
+ assertContains(e.getLocation().toString()
+ + " should refer to included_file.xml",
+ "included_file.xml:",
+ e.getLocation().toString());
+ }
+ }
+
+ @Test
+ public void testTaskErrorInIncluded() {
+ buildRule.configureProject("src/etc/testcases/core/include/included_file_task_error/build.xml");
+ try {
+ buildRule.executeTarget("test");
+ fail("should have cause a build failure");
+ } catch (BuildException e) {
+ assertTrue(e.getMessage()
+ + " should start with \'Warning: Could not find",
+ e.getMessage().startsWith("Warning: Could not find file "));
+ assertTrue(e.getLocation().toString()
+ + " should end with included_file.xml:2: ",
+ e.getLocation().toString().endsWith("included_file.xml:2: "));
+ }
+ }
+
+ @Test
+ public void testWithSpaceInclude() {
+ buildRule.configureProject("src/etc/testcases/core/include/with space/include.xml");
+ buildRule.executeTarget("test1");
+ assertEquals("from included entity in 'with space'", buildRule.getLog());
+ }
+
+ @Test
+ public void testWithSpaceSimple() {
+ buildRule.configureProject("src/etc/testcases/core/include/with space/simple.xml");
+ buildRule.executeTarget("test1");
+ assertEquals("from simple buildfile in 'with space'", buildRule.getLog());
+ }
+
+ @Test
+ public void testWithSpaceRelative() {
+ buildRule.configureProject("src/etc/testcases/core/include/with space/relative.xml");
+ buildRule.executeTarget("test1");
+ assertEquals("from included entity in 'with space'", buildRule.getLog());
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/IntrospectionHelperTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/IntrospectionHelperTest.java
new file mode 100644
index 00000000..ca4085d2
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/IntrospectionHelperTest.java
@@ -0,0 +1,726 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant;
+
+import java.io.File;
+import java.lang.reflect.Method;
+import java.lang.reflect.InvocationTargetException;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import org.apache.tools.ant.taskdefs.condition.Os;
+import org.junit.Before;
+import org.junit.ComparisonFailure;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+/**
+ * JUnit testcases for org.apache.tools.ant.IntrospectionHelper.
+ *
+ */
+
+public class IntrospectionHelperTest {
+
+ private Project p;
+ private IntrospectionHelper ih;
+ private static final String projectBasedir = File.separator;
+
+ @Before
+ public void setUp() {
+ p = new Project();
+ p.setBasedir(projectBasedir);
+ ih = IntrospectionHelper.getHelper(getClass());
+ }
+
+ @Test
+ public void testIsDynamic() {
+ assertFalse("Not dynamic", ih.isDynamic());
+ }
+
+ @Test
+ public void testIsContainer() {
+ assertFalse("Not a container", ih.isContainer());
+ }
+
+ @Test
+ public void testAddText() throws BuildException {
+ ih.addText(p, this, "test");
+ try {
+ ih.addText(p, this, "test2");
+ fail("test2 shouldn\'t be equal to test");
+ } catch (BuildException be) {
+ assertTrue(be.getCause() instanceof ComparisonFailure);
+ }
+
+ ih = IntrospectionHelper.getHelper(String.class);
+ try {
+ ih.addText(p, "", "test");
+ fail("String doesn\'t support addText");
+ } catch (BuildException be) {
+ //TODO the value should be asserted
+ }
+ }
+
+ @Test
+ @Ignore("This silently ignores a build exception")
+ public void testGetAddTextMethod() {
+ Method m = ih.getAddTextMethod();
+ assertMethod(m, "addText", String.class, "test", "bing!");
+
+ ih = IntrospectionHelper.getHelper(String.class);
+ try {
+ m = ih.getAddTextMethod();
+ } catch (BuildException e) {}
+ }
+
+ @Test
+ public void testSupportsCharacters() {
+ assertTrue("IntrospectionHelperTest supports addText",
+ ih.supportsCharacters());
+
+ ih = IntrospectionHelper.getHelper(String.class);
+ assertTrue("String doesn\'t support addText", !ih.supportsCharacters());
+ }
+
+ public void addText(String text) {
+ assertEquals("test", text);
+ }
+
+ @Test
+ public void testElementCreators() throws BuildException {
+ try {
+ ih.getElementType("one");
+ fail("don't have element type one");
+ } catch (BuildException be) {
+ //TODO we should be asserting a value in here
+ }
+ try {
+ ih.getElementType("two");
+ fail("createTwo takes arguments");
+ } catch (BuildException be) {
+ //TODO we should be asserting a value in here
+ }
+ try {
+ ih.getElementType("three");
+ fail("createThree returns void");
+ } catch (BuildException be) {
+ //TODO we should be asserting a value in here
+ }
+ try {
+ ih.getElementType("four");
+ fail("createFour returns array");
+ } catch (BuildException be) {
+ //TODO we should be asserting a value in here
+ }
+ try {
+ ih.getElementType("five");
+ fail("createFive returns primitive type");
+ } catch (BuildException be) {
+ //TODO we should be asserting a value in here
+ }
+ assertEquals(String.class, ih.getElementType("six"));
+ assertEquals("test", ih.createElement(p, this, "six"));
+
+ try {
+ ih.getElementType("seven");
+ fail("addSeven takes two arguments");
+ } catch (BuildException be) {
+ //TODO we should be asserting a value in here
+ }
+ try {
+ ih.getElementType("eight");
+ fail("addEight takes no arguments");
+ } catch (BuildException be) {
+ //TODO we should be asserting a value in here
+ }
+ try {
+ ih.getElementType("nine");
+ fail("nine return non void");
+ } catch (BuildException be) {
+ //TODO we should be asserting a value in here
+ }
+ try {
+ ih.getElementType("ten");
+ fail("addTen takes array argument");
+ } catch (BuildException be) {
+ //TODO we should be asserting a value in here
+ }
+ try {
+ ih.getElementType("eleven");
+ fail("addEleven takes primitive argument");
+ } catch (BuildException be) {
+ //TODO we should be asserting a value in here
+ }
+ try {
+ ih.getElementType("twelve");
+ fail("no primitive constructor for java.lang.Class");
+ } catch (BuildException be) {
+ //TODO we should be asserting a value in here
+ }
+ assertEquals(StringBuffer.class, ih.getElementType("thirteen"));
+ assertEquals("test", ih.createElement(p, this, "thirteen").toString());
+
+ try {
+ ih.createElement(p, this, "fourteen");
+ fail("fourteen throws NullPointerException");
+ } catch (BuildException be) {
+ assertTrue(be.getCause() instanceof NullPointerException);
+ }
+
+ try {
+ ih.createElement(p, this, "fourteen");
+ fail("fifteen throws NullPointerException");
+ } catch (BuildException be) {
+ assertTrue(be.getCause() instanceof NullPointerException);
+ }
+ }
+
+ private Map getExpectedNestedElements() {
+ Map elemMap = new Hashtable();
+ elemMap.put("six", String.class);
+ elemMap.put("thirteen", StringBuffer.class);
+ elemMap.put("fourteen", StringBuffer.class);
+ elemMap.put("fifteen", StringBuffer.class);
+ return elemMap;
+ }
+
+ @Test
+ public void testGetNestedElements() {
+ Map elemMap = getExpectedNestedElements();
+ Enumeration e = ih.getNestedElements();
+ while (e.hasMoreElements()) {
+ String name = (String) e.nextElement();
+ Class expect = (Class) elemMap.get(name);
+ assertNotNull("Support for "+name+" in IntrospectioNHelperTest?",
+ expect);
+ assertEquals("Return type of "+name, expect, ih.getElementType(name));
+ elemMap.remove(name);
+ }
+ assertTrue("Found all", elemMap.isEmpty());
+ }
+
+ @Test
+ public void testGetNestedElementMap() {
+ Map elemMap = getExpectedNestedElements();
+ Map actualMap = ih.getNestedElementMap();
+ for (Iterator i = actualMap.entrySet().iterator(); i.hasNext();) {
+ Map.Entry entry = (Map.Entry) i.next();
+ String elemName = (String) entry.getKey();
+ Class elemClass = (Class) elemMap.get(elemName);
+ assertNotNull("Support for " + elemName +
+ " in IntrospectionHelperTest?", elemClass);
+ assertEquals("Type of " + elemName, elemClass, entry.getValue());
+ elemMap.remove(elemName);
+ }
+ assertTrue("Found all", elemMap.isEmpty());
+
+ // Check it's a read-only map.
+ try {
+ actualMap.clear();
+ //TODO we should be asserting a value somewhere in here
+ } catch (UnsupportedOperationException e) {}
+ }
+
+ @Test
+ public void testGetElementMethod() {
+ assertElemMethod("six", "createSix", String.class, null);
+ assertElemMethod("thirteen", "addThirteen", null, StringBuffer.class);
+ assertElemMethod("fourteen", "addFourteen", null, StringBuffer.class);
+ assertElemMethod("fifteen", "createFifteen", StringBuffer.class, null);
+ }
+
+ private void assertElemMethod(String elemName, String methodName,
+ Class returnType, Class methodArg) {
+ Method m = ih.getElementMethod(elemName);
+ assertEquals("Method name", methodName, m.getName());
+ Class expectedReturnType = (returnType == null)? Void.TYPE: returnType;
+ assertEquals("Return type", expectedReturnType, m.getReturnType());
+ Class[] args = m.getParameterTypes();
+ if (methodArg != null) {
+ assertEquals("Arg Count", 1, args.length);
+ assertEquals("Arg Type", methodArg, args[0]);
+ } else {
+ assertEquals("Arg Count", 0, args.length);
+ }
+ }
+
+ public Object createTwo(String s) {
+ return null;
+ }
+
+ public void createThree() {}
+
+ public Object[] createFour() {
+ return null;
+ }
+
+ public int createFive() {
+ return 0;
+ }
+
+ public String createSix() {
+ return "test";
+ }
+
+ public StringBuffer createFifteen() {
+ throw new NullPointerException();
+ }
+
+ public void addSeven(String s, String s2) {}
+
+ public void addEight() {}
+
+ public String addNine(String s) {
+ return null;
+ }
+
+ public void addTen(String[] s) {}
+
+ public void addEleven(int i) {}
+
+ public void addTwelve(Class c) {}
+
+ public void addThirteen(StringBuffer sb) {
+ sb.append("test");
+ }
+
+ public void addFourteen(StringBuffer s) {
+ throw new NullPointerException();
+ }
+
+ @Test
+ public void testAttributeSetters() throws BuildException {
+ try {
+ ih.setAttribute(p, this, "one", "test");
+ fail("setOne doesn't exist");
+ } catch (BuildException be) {
+ //TODO we should be asserting a value in here
+ }
+ try {
+ ih.setAttribute(p, this, "two", "test");
+ fail("setTwo returns non void");
+ } catch (BuildException be) {
+ //TODO we should be asserting a value in here
+ }
+ try {
+ ih.setAttribute(p, this, "three", "test");
+ fail("setThree takes no args");
+ } catch (BuildException be) {
+ //TODO we should be asserting a value in here
+ }
+ try {
+ ih.setAttribute(p, this, "four", "test");
+ fail("setFour takes two args");
+ } catch (BuildException be) {
+ //TODO we should be asserting a value in here
+ }
+ try {
+ ih.setAttribute(p, this, "five", "test");
+ fail("setFive takes array arg");
+ } catch (BuildException be) {
+ //TODO we should be asserting a value in here
+ }
+ try {
+ ih.setAttribute(p, this, "six", "test");
+ fail("Project doesn't have a String constructor");
+ } catch (BuildException be) {
+ //TODO we should be asserting a value in here
+ }
+ ih.setAttribute(p, this, "seven", "2");
+ try {
+ ih.setAttribute(p, this, "seven", "3");
+ fail("2 shouldn't be equals to three");
+ } catch (BuildException be) {
+ assertTrue(be.getCause() instanceof ComparisonFailure);
+ }
+ ih.setAttribute(p, this, "eight", "2");
+ try {
+ ih.setAttribute(p, this, "eight", "3");
+ fail("2 shouldn't be equals to three - as int");
+ } catch (BuildException be) {
+ assertTrue("Cause of error: " + be.toString(), be.getCause() instanceof AssertionError);
+ }
+ ih.setAttribute(p, this, "nine", "2");
+ try {
+ ih.setAttribute(p, this, "nine", "3");
+ fail("2 shouldn't be equals to three - as Integer");
+ } catch (BuildException be) {
+ assertTrue(be.getCause() instanceof AssertionError);
+ }
+ ih.setAttribute(p, this, "ten", "2");
+ try {
+ ih.setAttribute(p, this, "ten", "3");
+ fail(projectBasedir+"2 shouldn't be equals to "+projectBasedir+"3");
+ } catch (BuildException be) {
+ assertTrue(be.getCause() instanceof AssertionError);
+ }
+ ih.setAttribute(p, this, "eleven", "2");
+ try {
+ ih.setAttribute(p, this, "eleven", "on");
+ fail("on shouldn't be false");
+ } catch (BuildException be) {
+ assertTrue(be.getCause() instanceof AssertionError);
+ }
+ ih.setAttribute(p, this, "twelve", "2");
+ try {
+ ih.setAttribute(p, this, "twelve", "on");
+ fail("on shouldn't be false");
+ } catch (BuildException be) {
+ assertTrue(be.getCause() instanceof AssertionError);
+ }
+ ih.setAttribute(p, this, "thirteen", "org.apache.tools.ant.Project");
+ try {
+ ih.setAttribute(p, this, "thirteen", "org.apache.tools.ant.ProjectHelper");
+ fail("org.apache.tools.ant.Project shouldn't be equal to org.apache.tools.ant.ProjectHelper");
+ } catch (BuildException be) {
+ assertTrue(be.getCause() instanceof AssertionError);
+ }
+ try {
+ ih.setAttribute(p, this, "thirteen", "org.apache.tools.ant.Project2");
+ fail("org.apache.tools.ant.Project2 doesn't exist");
+ } catch (BuildException be) {
+ assertTrue(be.getCause() instanceof ClassNotFoundException);
+ }
+ ih.setAttribute(p, this, "fourteen", "2");
+ try {
+ ih.setAttribute(p, this, "fourteen", "on");
+ fail("2 shouldn't be equals to three - as StringBuffer");
+ } catch (BuildException be) {
+ assertTrue(be.getCause() instanceof ComparisonFailure);
+ }
+ ih.setAttribute(p, this, "fifteen", "abcd");
+ try {
+ ih.setAttribute(p, this, "fifteen", "on");
+ fail("o shouldn't be equal to a");
+ } catch (BuildException be) {
+ assertTrue(be.getCause() instanceof AssertionError);
+ }
+ ih.setAttribute(p, this, "sixteen", "abcd");
+ try {
+ ih.setAttribute(p, this, "sixteen", "on");
+ fail("o shouldn't be equal to a");
+ } catch (BuildException be) {
+ assertTrue(be.getCause() instanceof AssertionError);
+ }
+ ih.setAttribute(p, this, "seventeen", "17");
+ try {
+ ih.setAttribute(p, this, "seventeen", "3");
+ fail("17 shouldn't be equals to three");
+ } catch (BuildException be) {
+ assertTrue(be.getCause() instanceof AssertionError);
+ }
+ ih.setAttribute(p, this, "eightteen", "18");
+ try {
+ ih.setAttribute(p, this, "eightteen", "3");
+ fail("18 shouldn't be equals to three");
+ } catch (BuildException be) {
+ assertTrue(be.getCause() instanceof AssertionError);
+ }
+ ih.setAttribute(p, this, "nineteen", "19");
+ try {
+ ih.setAttribute(p, this, "nineteen", "3");
+ fail("19 shouldn't be equals to three");
+ } catch (BuildException be) {
+ assertTrue(be.getCause() instanceof AssertionError);
+ }
+ }
+
+ private Map getExpectedAttributes() {
+ Map attrMap = new Hashtable();
+ attrMap.put("seven", String.class);
+ attrMap.put("eight", Integer.TYPE);
+ attrMap.put("nine", Integer.class);
+ attrMap.put("ten", File.class);
+ attrMap.put("eleven", Boolean.TYPE);
+ attrMap.put("twelve", Boolean.class);
+ attrMap.put("thirteen", Class.class);
+ attrMap.put("fourteen", StringBuffer.class);
+ attrMap.put("fifteen", Character.TYPE);
+ attrMap.put("sixteen", Character.class);
+ attrMap.put("seventeen", Byte.TYPE);
+ attrMap.put("eightteen", Short.TYPE);
+ attrMap.put("nineteen", Double.TYPE);
+
+ /*
+ * JUnit 3.7 adds a getName method to TestCase - so we now
+ * have a name attribute in IntrospectionHelperTest if we run
+ * under JUnit 3.7 but not in earlier versions.
+ *
+ * Simply add it here and remove it after the tests.
+ */
+ attrMap.put("name", String.class);
+
+ return attrMap;
+ }
+
+ @Test
+ public void testGetAttributes() {
+ Map attrMap = getExpectedAttributes();
+ Enumeration e = ih.getAttributes();
+ while (e.hasMoreElements()) {
+ String name = (String) e.nextElement();
+ Class expect = (Class) attrMap.get(name);
+ assertNotNull("Support for "+name+" in IntrospectionHelperTest?",
+ expect);
+ assertEquals("Type of "+name, expect, ih.getAttributeType(name));
+ attrMap.remove(name);
+ }
+ attrMap.remove("name");
+ assertTrue("Found all", attrMap.isEmpty());
+ }
+
+ @Test
+ public void testGetAttributeMap() {
+ Map attrMap = getExpectedAttributes();
+ Map actualMap = ih.getAttributeMap();
+ for (Iterator i = actualMap.entrySet().iterator(); i.hasNext();) {
+ Map.Entry entry = (Map.Entry) i.next();
+ String attrName = (String) entry.getKey();
+ Class attrClass = (Class) attrMap.get(attrName);
+ assertNotNull("Support for " + attrName +
+ " in IntrospectionHelperTest?", attrClass);
+ assertEquals("Type of " + attrName, attrClass, entry.getValue());
+ attrMap.remove(attrName);
+ }
+ attrMap.remove("name");
+ assertTrue("Found all", attrMap.isEmpty());
+
+ // Check it's a read-only map.
+ try {
+ actualMap.clear();
+ //TODO we should be asserting a value somewhere in here
+ } catch (UnsupportedOperationException e) {}
+ }
+
+ @Test
+ public void testGetAttributeMethod() {
+ assertAttrMethod("seven", "setSeven", String.class,
+ "2", "3");
+ assertAttrMethod("eight", "setEight", Integer.TYPE,
+ new Integer(2), new Integer(3));
+ assertAttrMethod("nine", "setNine", Integer.class,
+ new Integer(2), new Integer(3));
+ assertAttrMethod("ten", "setTen", File.class,
+ new File(projectBasedir + 2), new File("toto"));
+ assertAttrMethod("eleven", "setEleven", Boolean.TYPE,
+ Boolean.FALSE, Boolean.TRUE);
+ assertAttrMethod("twelve", "setTwelve", Boolean.class,
+ Boolean.FALSE, Boolean.TRUE);
+ assertAttrMethod("thirteen", "setThirteen", Class.class,
+ Project.class, Map.class);
+ assertAttrMethod("fourteen", "setFourteen", StringBuffer.class,
+ new StringBuffer("2"), new StringBuffer("3"));
+ assertAttrMethod("fifteen", "setFifteen", Character.TYPE,
+ new Character('a'), new Character('b'));
+ assertAttrMethod("sixteen", "setSixteen", Character.class,
+ new Character('a'), new Character('b'));
+ assertAttrMethod("seventeen", "setSeventeen", Byte.TYPE,
+ new Byte((byte)17), new Byte((byte)10));
+ assertAttrMethod("eightteen", "setEightteen", Short.TYPE,
+ new Short((short)18), new Short((short)10));
+ assertAttrMethod("nineteen", "setNineteen", Double.TYPE,
+ new Double(19), new Double((short)10));
+
+ try {
+ assertAttrMethod("onehundred", null, null, null, null);
+ fail("Should have raised a BuildException!");
+ } catch (BuildException e) {
+ //TODO we should be asserting a value in here
+ }
+ }
+
+ private void assertAttrMethod(String attrName, String methodName,
+ Class methodArg, Object arg, Object badArg) {
+ Method m = ih.getAttributeMethod(attrName);
+ assertMethod(m, methodName, methodArg, arg, badArg);
+ }
+
+ public int setTwo(String s) {
+ return 0;
+ }
+
+ public void setThree() {}
+
+ public void setFour(String s1, String s2) {}
+
+ public void setFive(String[] s) {}
+
+ public void setSix(Project p) {}
+
+ public void setSeven(String s) {
+ assertEquals("2", s);
+ }
+
+ public void setEight(int i) {
+ assertEquals(2, i);
+ }
+
+ public void setNine(Integer i) {
+ assertEquals(2, i.intValue());
+ }
+
+ public void setTen(File f) {
+ String path = f.getAbsolutePath();
+ if (Os.isFamily("unix") || Os.isFamily("openvms")) {
+ assertEquals(projectBasedir+"2", path);
+ } else if (Os.isFamily("netware")) {
+ assertEquals(projectBasedir+"2", path.toLowerCase(Locale.US));
+ } else {
+ assertEquals(":"+projectBasedir+"2",
+ path.toLowerCase(Locale.US).substring(1));
+ }
+ }
+
+ public void setEleven(boolean b) {
+ assertTrue(!b);
+ }
+
+ public void setTwelve(Boolean b) {
+ assertTrue(!b.booleanValue());
+ }
+
+ public void setThirteen(Class c) {
+ assertEquals(Project.class, c);
+ }
+
+ public void setFourteen(StringBuffer sb) {
+ assertEquals("2", sb.toString());
+ }
+
+ public void setFifteen(char c) {
+ assertEquals(c, 'a');
+ }
+
+ public void setSixteen(Character c) {
+ assertEquals(c.charValue(), 'a');
+ }
+
+ public void setSeventeen(byte b) {
+ assertEquals(17, b);
+ }
+
+ public void setEightteen(short s) {
+ assertEquals(18, s);
+ }
+
+ public void setNineteen(double d) {
+ double diff = d - 19;
+ assertTrue("Expected 19, received " + d, diff > -1e-6 && diff < 1e-6);
+ }
+
+ @Test
+ public void testGetExtensionPoints() {
+ List extensions = ih.getExtensionPoints();
+ final int adders = 2;
+ assertEquals("extension count", adders, extensions.size());
+
+ // this original test assumed something about the order of
+ // add(Number) and addConfigured(Map) returned by reflection.
+ // Unfortunately the assumption doesn't hold for all VMs
+ // (failed on MacOS X using JDK 1.4.2_05) and the possible
+ // combinatorics are too hard to check. We really only want
+ // to ensure that the more derived Hashtable can be found
+ // before Map.
+// assertExtMethod(extensions.get(0), "add", Number.class,
+// new Integer(2), new Integer(3));
+
+ // addConfigured(Hashtable) should come before addConfigured(Map)
+ assertExtMethod(extensions.get(adders - 2),
+ "addConfigured", Hashtable.class,
+ makeTable("key", "value"), makeTable("1", "2"));
+
+ assertExtMethod(extensions.get(adders - 1), "addConfigured", Map.class,
+ new HashMap(), makeTable("1", "2"));
+ }
+
+ private void assertExtMethod(Object mo, String methodName, Class methodArg,
+ Object arg, Object badArg) {
+ assertMethod((Method) mo, methodName, methodArg, arg, badArg);
+ }
+
+ private void assertMethod(Method m, String methodName, Class methodArg,
+ Object arg, Object badArg) {
+ assertEquals("Method name", methodName, m.getName());
+ assertEquals("Return type", Void.TYPE, m.getReturnType());
+ Class[] args = m.getParameterTypes();
+ assertEquals("Arg Count", 1, args.length);
+ assertEquals("Arg Type", methodArg, args[0]);
+
+ try {
+ m.invoke(this, new Object[] { arg });
+ } catch (IllegalAccessException e) {
+ throw new BuildException(e);
+ } catch (InvocationTargetException e) {
+ throw new BuildException(e);
+ }
+
+ try {
+ m.invoke(this, new Object[] { badArg });
+ fail("Should have raised an assertion exception");
+ } catch (IllegalAccessException e) {
+ throw new BuildException(e);
+ } catch (InvocationTargetException e) {
+ Throwable t = e.getTargetException();
+ assertTrue(t.toString(), t instanceof AssertionError);
+ }
+ }
+
+ public List add(List l) {
+ // INVALID extension point
+ return null;
+ }
+
+ // see comments in testGetExtensionPoints
+// public void add(Number n) {
+// // Valid extension point
+// assertEquals(2, n.intValue());
+// }
+
+ public void add(List l, int i) {
+ // INVALID extension point
+ }
+
+ public void addConfigured(Map m) {
+ // Valid extension point
+ assertTrue(m.size() == 0);
+ }
+
+ public void addConfigured(Hashtable h) {
+ // Valid extension point, more derived than Map above, but *after* it!
+ assertEquals(makeTable("key", "value"), h);
+ }
+
+ private Hashtable makeTable(Object key, Object value) {
+ Hashtable table = new Hashtable();
+ table.put(key, value);
+ return table;
+ }
+
+} // IntrospectionHelperTest
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/LoaderRefTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/LoaderRefTest.java
new file mode 100644
index 00000000..2fb7439b
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/LoaderRefTest.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant;
+
+import static org.apache.tools.ant.AntAssert.assertContains;
+import static org.junit.Assert.fail;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+/**
+ */
+public class LoaderRefTest {
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/core/loaderref/loaderref.xml");
+ buildRule.executeTarget("setUp");
+ }
+
+ // override allowed on <available>
+ @Test
+ public void testBadRef() {
+ try {
+ buildRule.executeTarget("testbadref");
+ fail("BuildRule should have thrown an exception due to a bad classloader being specified");
+ } catch (BuildException ex) {
+ assertContains("Should fail due to ref not being a class loader", "does not reference a class loader", ex.getMessage());
+ }
+ }
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/LocationTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/LocationTest.java
new file mode 100644
index 00000000..c8048a31
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/LocationTest.java
@@ -0,0 +1,93 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant;
+
+import org.apache.tools.ant.taskdefs.ConditionTask;
+import org.apache.tools.ant.taskdefs.Echo;
+import org.apache.tools.ant.types.FileSet;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+public class LocationTest {
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/core/location.xml");
+ }
+
+ @Test
+ public void testPlainTask() {
+ buildRule.executeTarget("testPlainTask");
+ Echo e = (Echo) buildRule.getProject().getReference("echo");
+ assertFalse(e.getLocation() == Location.UNKNOWN_LOCATION);
+ assertFalse(e.getLocation().getLineNumber() == 0);
+ }
+
+ @Test
+ public void testStandaloneType() {
+ buildRule.executeTarget("testStandaloneType");
+ Echo e = (Echo) buildRule.getProject().getReference("echo2");
+ FileSet f = (FileSet) buildRule.getProject().getReference("fs");
+ assertFalse(f.getLocation() == Location.UNKNOWN_LOCATION);
+ assertEquals(e.getLocation().getLineNumber() + 1,
+ f.getLocation().getLineNumber());
+ }
+
+ @Test
+ public void testConditionTask() {
+ buildRule.executeTarget("testConditionTask");
+ TaskAdapter ta = (TaskAdapter) buildRule.getProject().getReference("cond");
+ ConditionTask c = (ConditionTask) ta.getProxy();
+ assertFalse(c.getLocation() == Location.UNKNOWN_LOCATION);
+ assertFalse(c.getLocation().getLineNumber() == 0);
+ }
+
+ @Test
+ public void testMacrodefWrappedTask() {
+ buildRule.executeTarget("testMacrodefWrappedTask");
+ Echo e = (Echo) buildRule.getProject().getReference("echo3");
+ assertTrue(buildRule.getLog().indexOf("Line: "
+ + (e.getLocation().getLineNumber() + 1))
+ > -1);
+ }
+
+ @Test
+ public void testPresetdefWrappedTask() {
+ buildRule.executeTarget("testPresetdefWrappedTask");
+ Echo e = (Echo) buildRule.getProject().getReference("echo4");
+ assertTrue(buildRule.getLog().indexOf("Line: "
+ + (e.getLocation().getLineNumber() + 1))
+ > -1);
+ }
+
+ public static class EchoLocation extends Task {
+ public void execute() {
+ log("Line: " + getLocation().getLineNumber(), Project.MSG_INFO);
+ }
+ }
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/MockBuildListener.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/MockBuildListener.java
new file mode 100644
index 00000000..e3a96a85
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/MockBuildListener.java
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertEquals;
+
+import java.util.Vector;
+
+public class MockBuildListener implements BuildListener {
+
+ private final Vector<BuildEvent> buffer = new Vector<BuildEvent>();
+ private final Project project;
+
+ public MockBuildListener(final Project project) {
+ this.project = project;
+ }
+
+ public void buildStarted(BuildEvent event) {}
+ public void buildFinished(BuildEvent event) {}
+ public void targetStarted(BuildEvent event) {}
+ public void targetFinished(BuildEvent event) {}
+ public void taskStarted(BuildEvent event) {}
+ public void taskFinished(BuildEvent event) {}
+
+ public void messageLogged(final BuildEvent actual) {
+ if(actual.getPriority()==Project.MSG_DEBUG)
+ return;
+ assertTrue("unexpected messageLogged: "+actual.getMessage(), !buffer.isEmpty());
+ assertEquals("unexpected project ", project, actual.getProject());
+
+ BuildEvent expected = (BuildEvent) buffer.elementAt(0);
+ buffer.removeElementAt(0);
+ assertEquals("unexpected messageLogged ", expected.getMessage(), actual.getMessage());
+ assertEquals("unexpected priority ", expected.getPriority(), actual.getPriority());
+ }
+
+ public void assertEmpty() {
+ assertTrue("MockBuildListener is not empty", buffer.isEmpty());
+ }
+
+ public void addBuildEvent(final String message, final int priority) {
+ final BuildEvent be = new BuildEvent(project);
+ be.setMessage(message, priority);
+ buffer.addElement(be);
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/PickOneTask.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/PickOneTask.java
new file mode 100644
index 00000000..560194b0
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/PickOneTask.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant;
+
+import org.apache.tools.ant.dispatch.DispatchTask;
+
+public class PickOneTask extends DispatchTask {
+ public void list() {
+ throw new BuildException("list");
+ }
+
+ public void show() {
+ throw new BuildException("show");
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/ProjectComponentTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/ProjectComponentTest.java
new file mode 100644
index 00000000..44ea56fb
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/ProjectComponentTest.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertSame;
+
+public class ProjectComponentTest {
+
+ @Test
+ public void testClone() throws CloneNotSupportedException {
+ Project expectedProject = new Project();
+ Location expectedLocation = new Location("foo");
+ String expectedDescription = "bar";
+
+ // use an anonymous subclass since ProjectComponent is abstract
+ ProjectComponent pc = new ProjectComponent() {
+ };
+ pc.setProject(expectedProject);
+ pc.setLocation(expectedLocation);
+ pc.setDescription(expectedDescription);
+
+ ProjectComponent cloned = (ProjectComponent) pc.clone();
+ assertNotSame(pc, cloned);
+ assertSame(cloned.getProject(), expectedProject);
+ assertSame(cloned.getLocation(), expectedLocation);
+ assertSame(cloned.getDescription(), expectedDescription);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/ProjectHelperRepositoryTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/ProjectHelperRepositoryTest.java
new file mode 100644
index 00000000..550c342b
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/ProjectHelperRepositoryTest.java
@@ -0,0 +1,105 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant;
+
+import java.io.File;
+
+import org.apache.tools.ant.helper.ProjectHelper2;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.resources.FileResource;
+import org.apache.tools.ant.types.resources.StringResource;
+import org.junit.Test;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+/**
+ * Testing around the management of the project helpers
+ */
+public class ProjectHelperRepositoryTest {
+
+ public static class SomeHelper extends ProjectHelper {
+ public boolean canParseBuildFile(Resource buildFile) {
+ return buildFile instanceof FileResource
+ && buildFile.getName().endsWith(".myext");
+ }
+
+ public boolean canParseAntlibDescriptor(Resource r) {
+ return r instanceof FileResource && r.getName().endsWith(".myext");
+ }
+ }
+
+ @Test
+ public void testFind() throws Exception {
+ ProjectHelperRepository repo = ProjectHelperRepository.getInstance();
+ repo.registerProjectHelper(SomeHelper.class);
+
+ Resource r = new FileResource(new File("test.xml"));
+ ProjectHelper helper = repo.getProjectHelperForBuildFile(r);
+ assertTrue(helper instanceof ProjectHelper2);
+ helper = repo.getProjectHelperForAntlib(r);
+ assertTrue(helper instanceof ProjectHelper2);
+
+ r = new FileResource(new File("test.myext"));
+ helper = repo.getProjectHelperForBuildFile(r);
+ assertTrue(helper instanceof SomeHelper);
+ helper = repo.getProjectHelperForAntlib(r);
+ assertTrue(helper instanceof SomeHelper);
+
+ r = new StringResource("test.myext");
+ helper = repo.getProjectHelperForBuildFile(r);
+ assertTrue(helper instanceof ProjectHelper2);
+ helper = repo.getProjectHelperForAntlib(r);
+ assertTrue(helper instanceof ProjectHelper2);
+
+ r = new StringResource("test.other");
+ helper = repo.getProjectHelperForBuildFile(r);
+ assertTrue(helper instanceof ProjectHelper2);
+ helper = repo.getProjectHelperForAntlib(r);
+ assertTrue(helper instanceof ProjectHelper2);
+ }
+
+ @Test
+ public void testNoDefaultContructor() throws Exception {
+
+ class IncrrectHelper extends ProjectHelper {
+ // the default constructor is not visible to ant here
+ }
+
+ ProjectHelperRepository repo = ProjectHelperRepository.getInstance();
+ try {
+ repo.registerProjectHelper(IncrrectHelper.class);
+ fail("Registring an helper with no default constructor should fail");
+ } catch (BuildException e) {
+ // ok
+ //TODO we should be asserting a value in here
+ }
+ }
+
+ @Test
+ public void testUnkwnowHelper() throws Exception {
+ ProjectHelperRepository repo = ProjectHelperRepository.getInstance();
+ try {
+ repo.registerProjectHelper("xxx.yyy.zzz.UnknownHelper");
+ fail("Registring an unknwon helper should fail");
+ } catch (BuildException e) {
+ // ok
+ //TODO we should be asserting a value in here
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/ProjectTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/ProjectTest.java
new file mode 100644
index 00000000..17c15c22
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/ProjectTest.java
@@ -0,0 +1,327 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant;
+
+import org.apache.tools.ant.input.DefaultInputHandler;
+import org.apache.tools.ant.input.InputHandler;
+import org.apache.tools.ant.input.PropertyFileInputHandler;
+import org.apache.tools.ant.taskdefs.condition.Os;
+
+import java.io.File;
+
+import org.apache.tools.ant.types.FileSet;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.types.PatternSet;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.apache.tools.ant.AntAssert.assertContains;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+
+/**
+ * Very limited test class for Project. Waiting to be extended.
+ *
+ */
+public class ProjectTest {
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ private Project p;
+ private String root;
+ private MockBuildListener mbl;
+
+ @Before
+ public void setUp() {
+ p = new Project();
+ p.init();
+ root = new File(File.separator).getAbsolutePath().toUpperCase();
+ mbl = new MockBuildListener(p);
+ }
+
+ @Test
+ public void testDataTypes() throws BuildException {
+ assertNull("dummy is not a known data type",
+ p.createDataType("dummy"));
+ Object o = p.createDataType("fileset");
+ assertNotNull("fileset is a known type", o);
+ assertTrue("fileset creates FileSet", o instanceof FileSet);
+ assertTrue("PatternSet",
+ p.createDataType("patternset") instanceof PatternSet);
+ assertTrue("Path", p.createDataType("path") instanceof Path);
+ }
+
+ /**
+ * This test has been a starting point for moving the code to FileUtils.
+ */
+ @Test
+ public void testResolveFile() {
+ if (Os.isFamily("netware") || Os.isFamily("dos")) {
+ assertEqualsIgnoreDriveCase(localize(File.separator),
+ p.resolveFile("/", null).getPath());
+ assertEqualsIgnoreDriveCase(localize(File.separator),
+ p.resolveFile("\\", null).getPath());
+ /*
+ * throw in drive letters
+ */
+ String driveSpec = "C:";
+ String driveSpecLower = "c:";
+
+ assertEqualsIgnoreDriveCase(driveSpecLower + "\\",
+ p.resolveFile(driveSpec + "/", null).getPath());
+ assertEqualsIgnoreDriveCase(driveSpecLower + "\\",
+ p.resolveFile(driveSpec + "\\", null).getPath());
+ assertEqualsIgnoreDriveCase(driveSpecLower + "\\",
+ p.resolveFile(driveSpecLower + "/", null).getPath());
+ assertEqualsIgnoreDriveCase(driveSpecLower + "\\",
+ p.resolveFile(driveSpecLower + "\\", null).getPath());
+ /*
+ * promised to eliminate consecutive slashes after drive letter.
+ */
+ assertEqualsIgnoreDriveCase(driveSpec + "\\",
+ p.resolveFile(driveSpec + "/////", null).getPath());
+ assertEqualsIgnoreDriveCase(driveSpec + "\\",
+ p.resolveFile(driveSpec + "\\\\\\\\\\\\", null).getPath());
+ } else {
+ /*
+ * Start with simple absolute file names.
+ */
+ assertEquals(File.separator,
+ p.resolveFile("/", null).getPath());
+ assertEquals(File.separator,
+ p.resolveFile("\\", null).getPath());
+ /*
+ * drive letters are not used, just to be considered as normal
+ * part of a name
+ */
+ String driveSpec = "C:";
+ String udir = System.getProperty("user.dir") + File.separatorChar;
+ assertEquals(udir + driveSpec,
+ p.resolveFile(driveSpec + "/", null).getPath());
+ assertEquals(udir + driveSpec,
+ p.resolveFile(driveSpec + "\\", null).getPath());
+ String driveSpecLower = "c:";
+ assertEquals(udir + driveSpecLower,
+ p.resolveFile(driveSpecLower + "/", null).getPath());
+ assertEquals(udir + driveSpecLower,
+ p.resolveFile(driveSpecLower + "\\", null).getPath());
+ }
+ /*
+ * Now test some relative file name magic.
+ */
+ assertEquals(localize("/1/2/3/4"),
+ p.resolveFile("4", new File(localize("/1/2/3"))).getPath());
+ assertEquals(localize("/1/2/3/4"),
+ p.resolveFile("./4", new File(localize("/1/2/3"))).getPath());
+ assertEquals(localize("/1/2/3/4"),
+ p.resolveFile(".\\4", new File(localize("/1/2/3"))).getPath());
+ assertEquals(localize("/1/2/3/4"),
+ p.resolveFile("./.\\4", new File(localize("/1/2/3"))).getPath());
+ assertEquals(localize("/1/2/3/4"),
+ p.resolveFile("../3/4", new File(localize("/1/2/3"))).getPath());
+ assertEquals(localize("/1/2/3/4"),
+ p.resolveFile("..\\3\\4", new File(localize("/1/2/3"))).getPath());
+ assertEquals(localize("/1/2/3/4"),
+ p.resolveFile("../../5/.././2/./3/6/../4", new File(localize("/1/2/3"))).getPath());
+ assertEquals(localize("/1/2/3/4"),
+ p.resolveFile("..\\../5/..\\./2/./3/6\\../4", new File(localize("/1/2/3"))).getPath());
+
+ }
+
+ /**
+ * adapt file separators to local conventions
+ */
+ private String localize(String path) {
+ path = root + path.substring(1);
+ return path.replace('\\', File.separatorChar).replace('/', File.separatorChar);
+ }
+
+ /**
+ * convenience method
+ * the drive letter is in lower case under cygwin
+ * calling this method allows tests where FileUtils.normalize
+ * is called via resolveFile to pass under cygwin
+ */
+ private void assertEqualsIgnoreDriveCase(String s1, String s2) {
+ if ((Os.isFamily("dos") || Os.isFamily("netware"))
+ && s1.length() >= 1 && s2.length() >= 1) {
+ StringBuffer sb1 = new StringBuffer(s1);
+ StringBuffer sb2 = new StringBuffer(s2);
+ sb1.setCharAt(0, Character.toUpperCase(s1.charAt(0)));
+ sb2.setCharAt(0, Character.toUpperCase(s2.charAt(0)));
+ assertEquals(sb1.toString(), sb2.toString());
+ } else {
+ assertEquals(s1, s2);
+ }
+ }
+
+ private void assertTaskDefFails(final Class taskClass,
+ final String message) {
+ final String dummyName = "testTaskDefinitionDummy";
+ try {
+ mbl.addBuildEvent(message, Project.MSG_ERR);
+ p.addTaskDefinition(dummyName, taskClass);
+ fail("expected BuildException(\""+message+"\", Project.MSG_ERR) when adding task " + taskClass);
+ }
+ catch(BuildException e) {
+ assertEquals(message, e.getMessage());
+ mbl.assertEmpty();
+ assertTrue(!p.getTaskDefinitions().containsKey(dummyName));
+ }
+ }
+
+ @Test
+ public void testAddTaskDefinition() {
+ p.addBuildListener(mbl);
+
+ p.addTaskDefinition("Ok", DummyTaskOk.class);
+ assertEquals(DummyTaskOk.class, p.getTaskDefinitions().get("Ok"));
+ p.addTaskDefinition("OkNonTask", DummyTaskOkNonTask.class);
+ assertEquals(DummyTaskOkNonTask.class, p.getTaskDefinitions().get("OkNonTask"));
+ mbl.assertEmpty();
+
+ assertTaskDefFails(DummyTaskPrivate.class, DummyTaskPrivate.class + " is not public");
+
+ assertTaskDefFails(DummyTaskProtected.class,
+ DummyTaskProtected.class + " is not public");
+
+ assertTaskDefFails(DummyTaskPackage.class, DummyTaskPackage.class + " is not public");
+
+ assertTaskDefFails(DummyTaskAbstract.class, DummyTaskAbstract.class + " is abstract");
+ assertTaskDefFails(DummyTaskInterface.class, DummyTaskInterface.class + " is abstract");
+
+ assertTaskDefFails(DummyTaskWithoutDefaultConstructor.class, "No public no-arg constructor in " + DummyTaskWithoutDefaultConstructor.class);
+ assertTaskDefFails(DummyTaskWithoutPublicConstructor.class, "No public no-arg constructor in " + DummyTaskWithoutPublicConstructor.class);
+
+ assertTaskDefFails(DummyTaskWithoutExecute.class, "No public execute() in " + DummyTaskWithoutExecute.class);
+ assertTaskDefFails(DummyTaskWithNonPublicExecute.class, "No public execute() in " + DummyTaskWithNonPublicExecute.class);
+
+ mbl.addBuildEvent("return type of execute() should be void but was \"int\" in " + DummyTaskWithNonVoidExecute.class, Project.MSG_WARN);
+ p.addTaskDefinition("NonVoidExecute", DummyTaskWithNonVoidExecute.class);
+ mbl.assertEmpty();
+ assertEquals(DummyTaskWithNonVoidExecute.class, p.getTaskDefinitions().get("NonVoidExecute"));
+ }
+
+ @Test
+ public void testInputHandler() {
+ InputHandler ih = p.getInputHandler();
+ assertNotNull(ih);
+ assertTrue(ih instanceof DefaultInputHandler);
+ InputHandler pfih = new PropertyFileInputHandler();
+ p.setInputHandler(pfih);
+ assertSame(pfih, p.getInputHandler());
+ }
+
+ @Test
+ public void testTaskDefinitionContainsKey() {
+ assertTrue(p.getTaskDefinitions().containsKey("echo"));
+ }
+
+ @Test
+ public void testTaskDefinitionContains() {
+ assertTrue(p.getTaskDefinitions().contains(org.apache.tools.ant.taskdefs.Echo.class));
+ }
+
+ @Test
+ public void testDuplicateTargets() {
+ // fail, because buildfile contains two targets with the same name
+ try {
+ buildRule.configureProject("src/etc/testcases/core/duplicate-target.xml");
+ fail("Should throw BuildException about duplicate target");
+ } catch (BuildException ex) {
+ assertEquals("specific message",
+ "Duplicate target 'twice'",
+ ex.getMessage());
+ }
+ }
+
+ @Test
+ public void testDuplicateTargetsImport() {
+ // overriding target from imported buildfile is allowed
+ buildRule.configureProject("src/etc/testcases/core/duplicate-target2.xml");
+ buildRule.executeTarget("once");
+ assertContains("once from buildfile", buildRule.getLog());
+ }
+
+ @Test
+ public void testOutputDuringMessageLoggedIsSwallowed()
+ throws InterruptedException {
+ final String FOO = "foo", BAR = "bar";
+ p.addBuildListener(new BuildListener() {
+ public void buildStarted(BuildEvent event) {}
+ public void buildFinished(BuildEvent event) {}
+ public void targetStarted(BuildEvent event) {}
+ public void targetFinished(BuildEvent event) {}
+ public void taskStarted(BuildEvent event) {}
+ public void taskFinished(BuildEvent event) {}
+ public void messageLogged(final BuildEvent actual) {
+ assertEquals(FOO, actual.getMessage());
+ // each of the following lines would cause an
+ // infinite loop if the message wasn't swallowed
+ System.err.println(BAR);
+ System.out.println(BAR);
+ p.log(BAR, Project.MSG_INFO);
+ }
+ });
+ final boolean[] done = new boolean[] {false};
+ Thread t = new Thread() {
+ public void run() {
+ p.log(FOO, Project.MSG_INFO);
+ done[0] = true;
+ }
+ };
+ t.start();
+ t.join(2000);
+ assertTrue("Expected logging thread to finish successfully", done[0]);
+ }
+
+ /**
+ * @see <a href="https://issues.apache.org/bugzilla/show_bug.cgi?id=47623">
+ * https://issues.apache.org/bugzilla/show_bug.cgi?id=47623</a>
+ */
+ @Test
+ public void testNullThrowableMessageLog() {
+ p.log(new Task() {}, null, new Throwable(), Project.MSG_ERR);
+ // be content if no exception has been thrown
+ }
+
+ private class DummyTaskPrivate extends Task {
+ public DummyTaskPrivate() {}
+ public void execute() {}
+ }
+
+ protected class DummyTaskProtected extends Task {
+ public DummyTaskProtected() {}
+ public void execute() {}
+ }
+
+
+ class DummyTaskPackage extends Task {
+ public DummyTaskPackage() {}
+ public void execute() {}
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/PropertyExpansionTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/PropertyExpansionTest.java
new file mode 100644
index 00000000..4ac8c5f7
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/PropertyExpansionTest.java
@@ -0,0 +1,99 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+
+package org.apache.tools.ant;
+
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * class to look at how we expand properties
+ */
+public class PropertyExpansionTest {
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+ /**
+ * we bind to an existing test file because we are too lazy to write our
+ * own, and we don't really care what it is
+ */
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/core/immutable.xml");
+ }
+
+ /**
+ * run through the test cases of expansion
+ */
+ @Test
+ public void testPropertyExpansion() {
+ assertExpandsTo("","");
+ assertExpandsTo("$","$");
+ assertExpandsTo("$$-","$-");
+ assertExpandsTo("$$","$");
+ buildRule.getProject().setProperty("expanded","EXPANDED");
+ assertExpandsTo("a${expanded}b","aEXPANDEDb");
+ assertExpandsTo("${expanded}${expanded}","EXPANDEDEXPANDED");
+ assertExpandsTo("$$$","$$");
+ assertExpandsTo("$$$$-","$$-");
+ assertExpandsTo("","");
+ assertExpandsTo("Class$$subclass","Class$subclass");
+ }
+
+ /**
+ * new things we want
+ */
+ @Test
+ public void testDollarPassthru() {
+ assertExpandsTo("$-","$-");
+ assertExpandsTo("Class$subclass","Class$subclass");
+ assertExpandsTo("$$$-","$$-");
+ assertExpandsTo("$$$$$","$$$");
+ assertExpandsTo("${unassigned.property}","${unassigned.property}");
+ assertExpandsTo("a$b","a$b");
+ assertExpandsTo("$}}","$}}");
+ }
+
+
+ /**
+ * old things we dont want; not a test no more
+ */
+ @Test
+ @Ignore("Previously disabled through naming convention")
+ public void oldtestQuirkyLegacyBehavior() {
+ assertExpandsTo("Class$subclass","Classsubclass");
+ assertExpandsTo("$$$-","$-");
+ assertExpandsTo("a$b","ab");
+ assertExpandsTo("$}}","}}");
+ }
+
+ /**
+ * little helper method to validate stuff
+ */
+ private void assertExpandsTo(String source,String expected) {
+ String actual = buildRule.getProject().replaceProperties(source);
+ assertEquals(source,expected,actual);
+ }
+
+//end class
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/PropertyFileCLITest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/PropertyFileCLITest.java
new file mode 100644
index 00000000..37188829
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/PropertyFileCLITest.java
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant;
+
+import java.io.File;
+import java.io.FileReader;
+import java.io.FileWriter;
+import org.apache.tools.ant.util.FileUtils;
+import org.junit.Test;
+
+import static org.apache.tools.ant.AntAssert.assertContains;
+
+public class PropertyFileCLITest {
+
+ @Test
+ public void testPropertyResolution() throws Exception {
+ FileUtils fu = FileUtils.getFileUtils();
+ File props = fu.createTempFile("propertyfilecli", ".properties",
+ null, true, true);
+ File build = fu.createTempFile("propertyfilecli", ".xml", null, true,
+ true);
+ File log = fu.createTempFile("propertyfilecli", ".log", null, true,
+ true);
+ FileWriter fw = null;
+ FileReader fr = null;
+ try {
+ fw = new FileWriter(props);
+ fw.write("w=world\nmessage=Hello, ${w}\n");
+ fw.close();
+ fw = new FileWriter(build);
+ fw.write("<project><echo>${message}</echo></project>");
+ fw.close();
+ fw = null;
+ Main m = new NoExitMain();
+ m.startAnt(new String[] {
+ "-propertyfile", props.getAbsolutePath(),
+ "-f", build.getAbsolutePath(),
+ "-l", log.getAbsolutePath()
+ }, null, null);
+ String l = FileUtils.safeReadFully(fr = new FileReader(log));
+ assertContains("Hello, world", l);
+ } finally {
+ FileUtils.close(fw);
+ FileUtils.close(fr);
+ }
+ }
+
+ private static class NoExitMain extends Main {
+ protected void exit(int exitCode) {
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/TaskContainerTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/TaskContainerTest.java
new file mode 100644
index 00000000..700b7c11
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/TaskContainerTest.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.assertTrue;
+
+public class TaskContainerTest {
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/core/taskcontainer.xml");
+ }
+
+ @Test
+ public void testPropertyExpansion() {
+ buildRule.executeTarget("testPropertyExpansion");
+ assertTrue("attribute worked",
+ buildRule.getLog().indexOf("As attribute: it worked") > -1);
+ assertTrue("nested text worked",
+ buildRule.getLog().indexOf("As nested text: it worked") > -1);
+ }
+
+ @Test
+ public void testTaskdef() {
+ buildRule.executeTarget("testTaskdef");
+ assertTrue("attribute worked",
+ buildRule.getLog().indexOf("As attribute: it worked") > -1);
+ assertTrue("nested text worked",
+ buildRule.getLog().indexOf("As nested text: it worked") > -1);
+ assertTrue("nested text worked",
+ buildRule.getLog().indexOf("As nested task: it worked") > -1);
+ }
+
+ @Test
+ public void testCaseInsensitive() {
+ buildRule.executeTarget("testCaseInsensitive");
+ assertTrue("works outside of container",
+ buildRule.getLog().indexOf("hello ") > -1);
+ assertTrue("works inside of container",
+ buildRule.getLog().indexOf("world") > -1);
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/TopLevelTaskTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/TopLevelTaskTest.java
new file mode 100644
index 00000000..7d73dc0e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/TopLevelTaskTest.java
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant;
+
+// This test will fail with embed, or if top-level is moved out of
+// dependency - as 'echo' happens as part of configureProject stage.
+
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * Tests for builds with tasks at the top level
+ *
+ * @since Ant 1.6
+ */
+public class TopLevelTaskTest {
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ @Test
+ public void testNoTarget() {
+ buildRule.configureProject("src/etc/testcases/core/topleveltasks/notarget.xml");
+ buildRule.executeTarget("");
+ assertEquals("Called", buildRule.getLog());
+ }
+
+ @Test
+ public void testCalledFromTopLevelAnt() {
+ buildRule.configureProject("src/etc/testcases/core/topleveltasks/toplevelant.xml");
+ buildRule.executeTarget("");
+ assertEquals("Called", buildRule.getLog());
+ }
+
+ @Test
+ public void testCalledFromTargetLevelAnt() {
+ buildRule.configureProject("src/etc/testcases/core/topleveltasks/targetlevelant.xml");
+ buildRule.executeTarget("foo");
+ assertEquals("Called", buildRule.getLog());
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/UnknownElementTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/UnknownElementTest.java
new file mode 100644
index 00000000..be7e21b8
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/UnknownElementTest.java
@@ -0,0 +1,115 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant;
+
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Rule;
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertNotNull;
+
+public class UnknownElementTest {
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/core/unknownelement.xml");
+ }
+
+ @Test
+ public void testMaybeConfigure() {
+ // make sure we do not get a NPE
+ buildRule.executeTarget("testMaybeConfigure");
+ }
+
+ /**
+ * Not really a UnknownElement test but rather one of "what
+ * information is available in taskFinished".
+ * @see <a href="https://issues.apache.org/bugzilla/show_bug.cgi?id=26197">
+ * https://issues.apache.org/bugzilla/show_bug.cgi?id=26197</a>
+ */
+ @Test
+ @Ignore("Previously disabled through naming convention")
+ public void XtestTaskFinishedEvent() {
+ buildRule.getProject().addBuildListener(new BuildListener() {
+ public void buildStarted(BuildEvent event) {}
+ public void buildFinished(BuildEvent event) {}
+ public void targetStarted(BuildEvent event) {}
+ public void targetFinished(BuildEvent event) {}
+ public void taskStarted(BuildEvent event) {
+ assertTaskProperties(event.getTask());
+ }
+ public void taskFinished(BuildEvent event) {
+ assertTaskProperties(event.getTask());
+ }
+ public void messageLogged(BuildEvent event) {}
+ private void assertTaskProperties(Task ue) {
+ assertNotNull(ue);
+ assertTrue(ue instanceof UnknownElement);
+ Task t = ((UnknownElement) ue).getTask();
+ assertNotNull(t);
+ assertEquals("org.apache.tools.ant.taskdefs.Echo",
+ t.getClass().getName());
+ }
+ });
+ buildRule.executeTarget("echo");
+ }
+
+ public static class Child extends Task {
+ Parent parent;
+ public void injectParent(Parent parent) {
+ this.parent = parent;
+ }
+ public void execute() {
+ parent.fromChild();
+ }
+ }
+
+ public static class Parent extends Task implements TaskContainer {
+ List children = new ArrayList();
+ public void addTask(Task t) {
+ children.add(t);
+ }
+
+ public void fromChild() {
+ log("fromchild");
+ }
+
+ public void execute() {
+ for (Iterator i = children.iterator(); i.hasNext();) {
+ UnknownElement el = (UnknownElement) i.next();
+ el.maybeConfigure();
+ Child child = (Child) el.getRealThing();
+ child.injectParent(this);
+ child.perform();
+ }
+ }
+ }
+}
+
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/XmlLoggerTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/XmlLoggerTest.java
new file mode 100644
index 00000000..cfeb16b4
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/XmlLoggerTest.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant;
+
+import org.apache.tools.ant.taskdefs.Cvs;
+import org.junit.Test;
+
+public class XmlLoggerTest {
+
+ @Test
+ // see https://issues.apache.org/bugzilla/show_bug.cgi?id=56850
+ // "NPE in XmlLogger.buildFinished"
+ public void test() throws Throwable {
+ final XmlLogger logger = new XmlLogger();
+ final Cvs task = new Cvs();
+ final BuildEvent event = new BuildEvent(task);
+ logger.buildStarted(event);
+ logger.buildFinished(event);
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/filters/ConcatFilterTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/filters/ConcatFilterTest.java
new file mode 100644
index 00000000..38583540
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/filters/ConcatFilterTest.java
@@ -0,0 +1,143 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.filters;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.tools.ant.BuildFileRule;
+import org.apache.tools.ant.FileUtilities;
+import org.apache.tools.ant.util.StringUtils;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * JUnit Testcases for ConcatReader
+ */
+public class ConcatFilterTest {
+
+ private static final String lSep = StringUtils.LINE_SEP;
+
+ private static final String FILE_PREPEND_WITH =
+ "this-should-be-the-first-line" + lSep
+ + "Line 1" + lSep
+ + "Line 2" + lSep
+ + "Line 3" + lSep
+ + "Line 4" + lSep
+ ;
+
+ private static final String FILE_PREPEND =
+ "Line 1" + lSep
+ + "Line 2" + lSep
+ + "Line 3" + lSep
+ + "Line 4" + lSep
+ + "Line 5" + lSep
+ ;
+
+ private static final String FILE_APPEND_WITH =
+ "Line 57" + lSep
+ + "Line 58" + lSep
+ + "Line 59" + lSep
+ + "Line 60" + lSep
+ + "this-should-be-the-last-line" + lSep
+ ;
+
+ private static final String FILE_APPEND =
+ "Line 56" + lSep
+ + "Line 57" + lSep
+ + "Line 58" + lSep
+ + "Line 59" + lSep
+ + "Line 60" + lSep
+ ;
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/filters/concat.xml");
+ }
+
+ @Test
+ public void testFilterReaderNoArgs() throws IOException {
+ buildRule.executeTarget("testFilterReaderNoArgs");
+ File expected = new File(buildRule.getProject().getProperty("output"), "concatfilter.test");
+ File result = new File(buildRule.getProject().getProperty("output"), "concat.FilterReaderNoArgs.test");
+ assertEquals("testFilterReaderNoArgs: Result not like expected", FileUtilities.getFileContents(expected),
+ FileUtilities.getFileContents(result));
+ }
+
+ @Test
+ public void testFilterReaderBefore() throws IOException {
+ doTest("testFilterReaderPrepend", FILE_PREPEND_WITH, FILE_APPEND);
+ }
+
+ @Test
+ public void testFilterReaderAfter() throws IOException {
+ doTest("testFilterReaderAppend", FILE_PREPEND, FILE_APPEND_WITH);
+ }
+
+ @Test
+ public void testFilterReaderBeforeAfter() throws IOException {
+ doTest("testFilterReaderPrependAppend", FILE_PREPEND_WITH, FILE_APPEND_WITH);
+ }
+
+ @Test
+ public void testConcatFilter() throws IOException {
+ doTest("testConcatFilter", FILE_PREPEND, FILE_APPEND);
+ }
+
+ @Test
+ public void testConcatFilterBefore() throws IOException {
+ doTest("testConcatFilterPrepend", FILE_PREPEND_WITH, FILE_APPEND);
+ }
+
+ @Test
+ public void testConcatFilterAfter() throws IOException {
+ doTest("testConcatFilterAppend", FILE_PREPEND, FILE_APPEND_WITH);
+ }
+
+ @Test
+ public void testConcatFilterBeforeAfter() throws IOException {
+ doTest("testConcatFilterPrependAppend", FILE_PREPEND_WITH, FILE_APPEND_WITH);
+ }
+
+
+ /**
+ * Executes a target and checks the beginning and the ending of a file.
+ * The filename depends on the target name: target name <i>testHelloWorld</i>
+ * will search for a file <i>result/concat.HelloWorld.test</i>.
+ * @param target The target to invoke
+ * @param expectedStart The string which should be at the beginning of the file
+ * @param expectedEnd The string which should be at the end of the file
+ */
+ protected void doTest(String target, String expectedStart, String expectedEnd) throws IOException {
+ buildRule.executeTarget(target);
+ String resultContent = FileUtilities.getFileContents(
+ new File(buildRule.getProject().getProperty("output") + "/concat." + target.substring(4) + ".test"));
+ assertTrue("First 5 lines differs.", resultContent.startsWith(expectedStart));
+ assertTrue("Last 5 lines differs.", resultContent.endsWith(expectedEnd));
+ }
+
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/filters/DynamicFilterTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/filters/DynamicFilterTest.java
new file mode 100644
index 00000000..5de7f6bc
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/filters/DynamicFilterTest.java
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.filters;
+
+import java.io.File;
+import java.io.Reader;
+import java.io.IOException;
+
+import org.apache.tools.ant.BuildFileRule;
+import org.apache.tools.ant.FileUtilities;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.apache.tools.ant.AntAssert.assertContains;
+
+public class DynamicFilterTest {
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/filters/dynamicfilter.xml");
+ buildRule.executeTarget("setUp");
+ }
+
+ @Test
+ public void testCustomFilter() throws IOException {
+ buildRule.executeTarget("dynamicfilter");
+ String content = FileUtilities.getFileContents(
+ new File(buildRule.getProject().getProperty("output") + "/dynamicfilter"));
+ assertContains("hellO wOrld", content);
+ }
+
+
+
+ public static class CustomFilter implements ChainableReader {
+ char replace = 'x';
+ char with = 'y';
+
+ public void setReplace(char replace) {
+ this.replace = replace;
+ }
+
+ public void setWith(char with) {
+ this.with = with;
+ }
+
+ public Reader chain(final Reader rdr) {
+ return new BaseFilterReader(rdr) {
+ public int read()
+ throws IOException
+ {
+ int c = in.read();
+ if (c == replace)
+ return with;
+ else
+ return c;
+ }
+ };
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/filters/EscapeUnicodeTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/filters/EscapeUnicodeTest.java
new file mode 100644
index 00000000..7c5e3040
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/filters/EscapeUnicodeTest.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.filters;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.tools.ant.BuildFileRule;
+import org.apache.tools.ant.FileUtilities;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class EscapeUnicodeTest {
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/filters/build.xml");
+ }
+
+ @Test
+ public void testEscapeUnicode() throws IOException {
+ buildRule.executeTarget("testEscapeUnicode");
+ File expected = buildRule.getProject().resolveFile("expected/escapeunicode.test");
+ File result = new File(buildRule.getProject().getProperty("output"), "escapeunicode.test");
+ assertEquals(FileUtilities.getFileContents(expected), FileUtilities.getFileContents(result));
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/filters/HeadTailTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/filters/HeadTailTest.java
new file mode 100644
index 00000000..7c910d12
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/filters/HeadTailTest.java
@@ -0,0 +1,137 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.filters;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.tools.ant.BuildFileRule;
+import org.apache.tools.ant.FileUtilities;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+/** JUnit Testcases for TailFilter and HeadFilter
+ */
+/* I wrote the testcases in one java file because I want also to test the
+ * combined behaviour (see end of the class).
+*/
+public class HeadTailTest {
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/filters/head-tail.xml");
+ }
+
+ @Test
+ public void testHead() throws IOException {
+ buildRule.executeTarget("testHead");
+ File expected = buildRule.getProject().resolveFile("expected/head-tail.head.test");
+ File result = new File(buildRule.getProject().getProperty("output") + "/head-tail.head.test");
+ assertEquals("testHead: Result not like expected", FileUtilities.getFileContents(expected), FileUtilities.getFileContents(result));
+ }
+
+ @Test
+ public void testHeadLines() throws IOException {
+ buildRule.executeTarget("testHeadLines");
+ File expected = buildRule.getProject().resolveFile("expected/head-tail.headLines.test");
+ File result = new File(buildRule.getProject().getProperty("output") + "/head-tail.headLines.test");
+ assertEquals("testHeadLines: Result not like expected", FileUtilities.getFileContents(expected), FileUtilities.getFileContents(result));
+ }
+
+ @Test
+ public void testHeadSkip() throws IOException {
+ buildRule.executeTarget("testHeadSkip");
+ File expected = buildRule.getProject().resolveFile("expected/head-tail.headSkip.test");
+ File result = new File(buildRule.getProject().getProperty("output") + "/head-tail.headSkip.test");
+ assertEquals("testHeadSkip: Result not like expected", FileUtilities.getFileContents(expected), FileUtilities.getFileContents(result));
+ }
+
+ @Test
+ public void testHeadLinesSkip() throws IOException {
+ buildRule.executeTarget("testHeadLinesSkip");
+ File expected = buildRule.getProject().resolveFile("expected/head-tail.headLinesSkip.test");
+ File result = new File(buildRule.getProject().getProperty("output") + "/head-tail.headLinesSkip.test");
+ assertEquals("testHeadLinesSkip: Result not like expected", FileUtilities.getFileContents(expected), FileUtilities.getFileContents(result));
+ }
+
+ @Test
+ public void testFilterReaderHeadLinesSkip() throws IOException {
+ buildRule.executeTarget("testFilterReaderHeadLinesSkip");
+ File expected = buildRule.getProject().resolveFile("expected/head-tail.headLinesSkip.test");
+ File result = new File(buildRule.getProject().getProperty("output") + "/head-tail.filterReaderHeadLinesSkip.test");
+ assertEquals("testFilterReaderHeadLinesSkip: Result not like expected",
+ FileUtilities.getFileContents(expected), FileUtilities.getFileContents(result));
+ }
+
+ @Test
+ public void testTail() throws IOException {
+ buildRule.executeTarget("testTail");
+ File expected =buildRule.getProject().resolveFile("expected/head-tail.tail.test");
+ File result = new File(buildRule.getProject().getProperty("output") + "/head-tail.tail.test");
+ assertEquals("testTail: Result not like expected", FileUtilities.getFileContents(expected), FileUtilities.getFileContents(result));
+ }
+
+ @Test
+ public void testTailLines() throws IOException {
+ buildRule.executeTarget("testTailLines");
+ File expected = buildRule.getProject().resolveFile("expected/head-tail.tailLines.test");
+ File result = new File(buildRule.getProject().getProperty("output") + "/head-tail.tailLines.test");
+ assertEquals("testTailLines: Result not like expected", FileUtilities.getFileContents(expected), FileUtilities.getFileContents(result));
+ }
+
+ @Test
+ public void testTailSkip() throws IOException {
+ buildRule.executeTarget("testTailSkip");
+ File expected = buildRule.getProject().resolveFile("expected/head-tail.tailSkip.test");
+ File result = new File(buildRule.getProject().getProperty("output") + "/head-tail.tailSkip.test");
+ assertEquals("testTailSkip: Result not like expected", FileUtilities.getFileContents(expected), FileUtilities.getFileContents(result));
+ }
+
+ @Test
+ public void testTailLinesSkip() throws IOException {
+ buildRule.executeTarget("testTailLinesSkip");
+ File expected = buildRule.getProject().resolveFile("expected/head-tail.tailLinesSkip.test");
+ File result = new File(buildRule.getProject().getProperty("output") + "/head-tail.tailLinesSkip.test");
+ assertEquals("testTailLinesSkip: Result not like expected", FileUtilities.getFileContents(expected), FileUtilities.getFileContents(result));
+ }
+
+ @Test
+ public void testFilterReaderTailLinesSkip() throws IOException {
+ buildRule.executeTarget("testFilterReaderTailLinesSkip");
+ File expected = buildRule.getProject().resolveFile("expected/head-tail.tailLinesSkip.test");
+ File result = new File(buildRule.getProject().getProperty("output") + "/head-tail.filterReaderTailLinesSkip.test");
+ assertEquals("testFilterReaderTailLinesSkip: Result not like expected",
+ FileUtilities.getFileContents(expected), FileUtilities.getFileContents(result));
+ }
+
+ @Test
+ public void testHeadTail() throws IOException {
+ buildRule.executeTarget("testHeadTail");
+ File expected = buildRule.getProject().resolveFile("expected/head-tail.headtail.test");
+ File result = new File(buildRule.getProject().getProperty("output") + "/head-tail.headtail.test");
+ assertEquals("testHeadTail: Result not like expected", FileUtilities.getFileContents(expected), FileUtilities.getFileContents(result));
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/filters/LineContainsTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/filters/LineContainsTest.java
new file mode 100644
index 00000000..9dcb291b
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/filters/LineContainsTest.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.filters;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.tools.ant.BuildFileRule;
+import org.apache.tools.ant.FileUtilities;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+
+public class LineContainsTest {
+
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/filters/build.xml");
+ }
+
+ @Test
+ public void testLineContains() throws IOException {
+ buildRule.executeTarget("testLineContains");
+ File expected = buildRule.getProject().resolveFile("expected/linecontains.test");
+ File result = new File(buildRule.getProject().getProperty("output"),"linecontains.test");
+ assertEquals(FileUtilities.getFileContents(expected), FileUtilities.getFileContents(result));
+ }
+
+ @Test
+ public void testNegateLineContains() throws IOException {
+ buildRule.executeTarget("testNegateLineContains");
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/filters/NoNewLineTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/filters/NoNewLineTest.java
new file mode 100644
index 00000000..c12a1d3f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/filters/NoNewLineTest.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.filters;
+
+import java.io.IOException;
+
+import org.apache.tools.ant.BuildFileRule;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+/** JUnit Testcases for No new line when filterchain used
+ */
+
+
+public class NoNewLineTest {
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/filters/build.xml");
+ }
+
+
+ @Test
+ public void testNoAddNewLine() throws IOException {
+ buildRule.executeTarget("testNoAddNewLine");
+ }
+
+
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/filters/ReplaceTokensTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/filters/ReplaceTokensTest.java
new file mode 100644
index 00000000..4db8d7a0
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/filters/ReplaceTokensTest.java
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.filters;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.tools.ant.BuildFileRule;
+import org.apache.tools.ant.FileUtilities;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class ReplaceTokensTest {
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/filters/build.xml");
+ }
+
+ @Test
+ public void testReplaceTokens() throws IOException {
+ buildRule.executeTarget("testReplaceTokens");
+ File expected = buildRule.getProject().resolveFile("expected/replacetokens.test");
+ File result = new File(buildRule.getProject().getProperty("output"), "replacetokens.test");
+ assertEquals(FileUtilities.getFileContents(expected), FileUtilities.getFileContents(result));
+ }
+
+ @Test
+ public void testReplaceTokensPropertyFile() throws IOException {
+ buildRule.executeTarget("testReplaceTokensPropertyFile");
+ File expected = buildRule.getProject().resolveFile("expected/replacetokens.test");
+ File result = new File(buildRule.getProject().getProperty("output"), "replacetokensPropertyFile.test");
+ assertEquals(FileUtilities.getFileContents(expected), FileUtilities.getFileContents(result));
+ }
+
+ @Test
+ public void testReplaceTokensDoubleEncoded() throws IOException {
+ buildRule.executeTarget("testReplaceTokensDoubleEncoded");
+ File expected = buildRule.getProject().resolveFile("expected/replacetokens.double.test");
+ File result = new File(buildRule.getProject().getProperty("output"), "replacetokens.double.test");
+ assertEquals(FileUtilities.getFileContents(expected), FileUtilities.getFileContents(result));
+ }
+
+ @Test
+ public void testReplaceTokensDoubleEncodedToSimple() throws IOException {
+ buildRule.executeTarget("testReplaceTokensDoubleEncodedToSimple");
+ File expected = buildRule.getProject().resolveFile("expected/replacetokens.test");
+ File result = new File(buildRule.getProject().getProperty("output"), "replacetokens.double.test");
+ assertEquals(FileUtilities.getFileContents(expected), FileUtilities.getFileContents(result));
+ }
+
+ @Test
+ public void testReplaceTokensMustacheStyle() throws IOException {
+ buildRule.executeTarget("testReplaceTokensMustacheStyle");
+ File expected = buildRule.getProject().resolveFile("expected/replacetokens.test");
+ File result = new File(buildRule.getProject().getProperty("output"), "replacetokens.mustache.test");
+ assertEquals(FileUtilities.getFileContents(expected), FileUtilities.getFileContents(result));
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/filters/StripJavaCommentsTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/filters/StripJavaCommentsTest.java
new file mode 100644
index 00000000..7114d497
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/filters/StripJavaCommentsTest.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.filters;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.tools.ant.BuildFileRule;
+import org.apache.tools.ant.FileUtilities;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class StripJavaCommentsTest {
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/filters/build.xml");
+ }
+
+
+ @Test
+ public void testStripJavaComments() throws IOException {
+ buildRule.executeTarget("testStripJavaComments");
+ File expected = buildRule.getProject().resolveFile("expected/stripjavacomments.test");
+ File result = new File(buildRule.getProject().getProperty("output"), "stripjavacomments.test");
+ assertEquals(FileUtilities.getFileContents(expected), FileUtilities.getFileContents(result));
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/filters/TokenFilterTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/filters/TokenFilterTest.java
new file mode 100644
index 00000000..f0db15a0
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/filters/TokenFilterTest.java
@@ -0,0 +1,279 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.filters;
+
+import static org.apache.tools.ant.AntAssert.assertContains;
+import static org.apache.tools.ant.AntAssert.assertNotContains;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.Reader;
+
+import org.apache.tools.ant.BuildFileRule;
+import org.apache.tools.ant.util.FileUtils;
+import org.junit.Assume;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+/**
+ */
+public class TokenFilterTest {
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/filters/tokenfilter.xml");
+ buildRule.executeTarget("setUp");
+ }
+
+ /** make sure tokenfilter exists */
+ @Test
+ public void testTokenfilter() throws IOException {
+ buildRule.executeTarget("tokenfilter");
+ }
+
+ @Test
+ public void testTrimignore() throws IOException {
+ buildRule.executeTarget("trimignore");
+ assertContains("Hello-World", buildRule.getLog());
+ }
+
+ @Test
+ public void testStringTokenizer() throws IOException {
+ buildRule.executeTarget("stringtokenizer");
+ assertContains("#This#is#a#number#of#words#", buildRule.getLog());
+ }
+
+ @Test
+ public void testUnixLineOutput() throws IOException {
+ buildRule.executeTarget("unixlineoutput");
+ assertContains("\nThis\nis\na\nnumber\nof\nwords\n",
+ getFileString(buildRule.getProject().getProperty("output") + "/unixlineoutput"));
+ }
+
+ @Test
+ public void testDosLineOutput() throws IOException {
+
+ buildRule.executeTarget("doslineoutput");
+ assertContains("\r\nThis\r\nis\r\na\r\nnumber\r\nof\r\nwords\r\n",
+ getFileString(buildRule.getProject().getProperty("output") + "/doslineoutput"));
+ }
+
+ @Test
+ public void testFileTokenizer() throws IOException {
+ buildRule.executeTarget("filetokenizer");
+ String contents = getFileString(buildRule.getProject().getProperty("output") + "/filetokenizer");
+ assertContains(" of words", contents);
+ assertNotContains(" This is", contents);
+ }
+
+ @Test
+ public void testReplaceString() throws IOException {
+ buildRule.executeTarget("replacestring");
+ assertContains("this is the moon",
+ getFileString(buildRule.getProject().getProperty("output") + "/replacestring"));
+ }
+
+ @Test
+ public void testReplaceStrings() throws IOException {
+ buildRule.executeTarget("replacestrings");
+ assertContains("bar bar bar", buildRule.getLog());
+ }
+
+ @Test
+ public void testContainsString() throws IOException {
+ buildRule.executeTarget("containsstring");
+ String contents = getFileString(buildRule.getProject().getProperty("output") + "/containsstring");
+ assertContains("this is a line contains foo", contents);
+ assertNotContains("this line does not", contents);
+ }
+
+ @Test
+ public void testReplaceRegex() throws IOException {
+
+ buildRule.executeTarget("hasregex");
+ Assume.assumeTrue("Regex not present",
+ getFileString(buildRule.getProject().getProperty("output") + "/replaceregexp").contains("bye world"));
+
+ buildRule.executeTarget("replaceregex");
+ String contents = getFileString(buildRule.getProject().getProperty("output") + "/replaceregex");
+ assertContains("world world world world", contents);
+ assertContains("dog Cat dog", contents);
+ assertContains("moon Sun Sun", contents);
+ assertContains("found WhiteSpace", contents);
+ assertContains("Found digits [1234]", contents);
+ assertNotContains("This is a line with digits", contents);
+ }
+
+ @Test
+ public void testFilterReplaceRegex() throws IOException {
+ buildRule.executeTarget("hasregex");
+ Assume.assumeTrue("Regex not present",
+ getFileString(buildRule.getProject().getProperty("output") + "/replaceregexp").contains("bye world"));
+
+ buildRule.executeTarget("filterreplaceregex");
+ String contents = getFileString(buildRule.getProject().getProperty("output") + "/filterreplaceregex");
+ assertContains("world world world world", contents);
+
+ }
+
+ @Test
+ public void testHandleDollerMatch() throws IOException {
+ buildRule.executeTarget("hasregex");
+ Assume.assumeTrue("Regex not present", getFileString(buildRule.getProject().getProperty("output") + "/replaceregexp").contains("bye world"));
+
+ buildRule.executeTarget("dollermatch");
+ }
+
+ @Test
+ public void testTrimFile() throws IOException {
+ buildRule.executeTarget("trimfile");
+ String contents = getFileString(buildRule.getProject().getProperty("output") + "/trimfile");
+ assertTrue("no ws at start", contents.startsWith("This is th"));
+ assertTrue("no ws at end", contents.endsWith("second line."));
+ assertContains(" This is the second", contents);
+ }
+
+ @Test
+ public void testTrimFileByLine() throws IOException {
+ buildRule.executeTarget("trimfilebyline");
+ String contents = getFileString(buildRule.getProject().getProperty("output") + "/trimfilebyline");
+ assertFalse("no ws at start", contents.startsWith("This is th"));
+ assertFalse("no ws at end", contents.endsWith("second line."));
+ assertNotContains(" This is the second", contents);
+ assertContains("file.\nThis is the second", contents);
+ }
+
+ @Test
+ public void testFilterReplaceString() throws IOException {
+ buildRule.executeTarget("filterreplacestring");
+ String contents = getFileString(buildRule.getProject().getProperty("output") + "/filterreplacestring");
+ assertContains("This is the moon", contents);
+ }
+
+ @Test
+ public void testFilterReplaceStrings() throws IOException {
+ buildRule.executeTarget("filterreplacestrings");
+ assertContains("bar bar bar", buildRule.getLog());
+ }
+
+ @Test
+ public void testContainsRegex() throws IOException {
+ buildRule.executeTarget("hasregex");
+ Assume.assumeTrue("Regex not present", getFileString(buildRule.getProject().getProperty("output") + "/replaceregexp").contains("bye world"));
+
+ //expectFileContains(buildRule.getProject().getProperty("output") + "/replaceregexp", "bye world");
+
+ buildRule.executeTarget("containsregex");
+ String contents = getFileString(buildRule.getProject().getProperty("output") + "/containsregex");
+ assertContains("hello world", contents);
+ assertNotContains("this is the moon", contents);
+ assertContains("World here", contents);
+ }
+
+ @Test
+ public void testFilterContainsRegex() throws IOException {
+ buildRule.executeTarget("hasregex");
+ Assume.assumeTrue("Regex not present", getFileString(buildRule.getProject().getProperty("output") + "/replaceregexp").contains("bye world"));
+
+ buildRule.executeTarget("filtercontainsregex");
+ String contents = getFileString(buildRule.getProject().getProperty("output") + "/filtercontainsregex");
+ assertContains("hello world", contents);
+ assertNotContains("this is the moon", contents);
+ assertContains("World here", contents);
+ }
+
+ @Test
+ public void testContainsRegex2() throws IOException {
+ buildRule.executeTarget("hasregex");
+ Assume.assumeTrue("Regex not present", getFileString(buildRule.getProject().getProperty("output") + "/replaceregexp").contains("bye world"));
+
+ buildRule.executeTarget("containsregex2");
+ String contents = getFileString(buildRule.getProject().getProperty("output") + "/containsregex2");
+ assertContains("void register_bits();", contents);
+ }
+
+ @Test
+ public void testDeleteCharacters() throws IOException {
+ buildRule.executeTarget("deletecharacters");
+ String contents = getFileString(buildRule.getProject().getProperty("output") + "/deletechars");
+ assertNotContains("#", contents);
+ assertNotContains("*", contents);
+ assertContains("This is some ", contents);
+ }
+
+ @Test
+ public void testScriptFilter() throws IOException {
+ Assume.assumeTrue("Project does not have 'testScriptFilter' target",
+ buildRule.getProject().getTargets().contains("testScriptFilter"));
+ buildRule.executeTarget("scriptfilter");
+ assertContains("HELLO WORLD", getFileString(buildRule.getProject().getProperty("output") + "/scriptfilter"));
+
+ }
+
+ @Test
+ public void testScriptFilter2() throws IOException {
+ Assume.assumeTrue("Project does not have 'testScriptFilter' target", buildRule.getProject().getTargets().contains("testScriptFilter"));
+ buildRule.executeTarget("scriptfilter2");
+ assertContains("HELLO MOON", getFileString(buildRule.getProject().getProperty("output") + "/scriptfilter2"));
+ }
+
+ @Test
+ public void testCustomTokenFilter() throws IOException {
+ buildRule.executeTarget("customtokenfilter");
+ assertContains("Hello World", getFileString(buildRule.getProject().getProperty("output") + "/custom"));
+ }
+
+ // ------------------------------------------------------
+ // Helper methods
+ // -----------------------------------------------------
+
+ private String getFileString(String filename)
+ throws IOException
+ {
+ Reader r = null;
+ try {
+ r = new FileReader(FILE_UTILS.resolveFile(buildRule.getProject().getBaseDir(),filename));
+ return FileUtils.readFully(r);
+ }
+ finally {
+ FileUtils.close(r);
+ }
+ }
+
+
+ public static class Capitalize
+ implements TokenFilter.Filter
+ {
+ public String filter(String token) {
+ if (token.length() == 0)
+ return token;
+ return token.substring(0, 1).toUpperCase() +
+ token.substring(1);
+ }
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/launch/LocatorTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/launch/LocatorTest.java
new file mode 100644
index 00000000..0c3c24fd
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/launch/LocatorTest.java
@@ -0,0 +1,180 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.launch;
+
+import java.io.File;
+
+import org.apache.tools.ant.taskdefs.condition.Os;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import static junit.framework.Assert.assertEquals;
+import static org.apache.tools.ant.AntAssert.assertContains;
+import static org.junit.Assert.fail;
+
+/** Test the locator in the ant-launch JAR */
+public class LocatorTest {
+ private boolean windows;
+ private boolean unix;
+ private static final String LAUNCHER_JAR = "//morzine/slo/Java/Apache/ant/lib/ant-launcher.jar";
+ private static final String SHARED_JAR_URI = "jar:file:"+ LAUNCHER_JAR +"!/org/apache/tools/ant/launch/Launcher.class";
+
+
+ @Before
+ public void setUp() throws Exception {
+ windows = Os.isFamily(Os.FAMILY_DOS);
+ unix = Os.isFamily(Os.FAMILY_UNIX);
+ }
+
+ /**
+ * expect a uri to resolve to strings on different platforms
+ * @param uri uri to parse
+ * @param expectedUnix unix string (or null to skip that test)
+ * @param expectedDos DOS string (or null to skip that test)
+ * @return the resolved string
+ */
+ private String resolveTo(String uri, String expectedUnix, String expectedDos) {
+ String result = Locator.fromURI(uri);
+ assertResolved(uri, expectedUnix, result, unix);
+ assertResolved(uri, expectedDos, result, windows);
+ return result;
+ }
+
+ /**
+ * Assert something resolved
+ * @param uri original URI
+ * @param expectedResult what we expected
+ * @param result what we got
+ * @param enabled is the test enabled?
+ */
+ private void assertResolved(String uri, String expectedResult, String result, boolean enabled) {
+ if (enabled && expectedResult != null && expectedResult.length() > 0) {
+ assertEquals("Expected " + uri + " to resolve to \n" + expectedResult + "\n but got\n"
+ + result + "\n", expectedResult, result);
+ }
+ }
+
+ /**
+ * This asserts that we can round trip the path to a URI and back again
+ * @param path filename with no directory separators
+ * @return the trailing filename
+ */
+ private String assertResolves(String path) {
+ String asuri = new File(path).toURI().toASCIIString();
+ String fullpath = System.getProperty("user.dir") + File.separator + path;
+ String result = resolveTo(asuri, fullpath, fullpath);
+ return result.substring(result.lastIndexOf(File.separatorChar) + 1);
+ }
+
+
+ /**
+ * this isnt really a valid URI, except maybe in IE
+ * @throws Exception
+ */
+ public void testNetworkURI() throws Exception {
+ resolveTo("file:\\\\PC03\\jclasses\\lib\\ant-1.7.0.jar", ""
+ + "\\\\PC03\\jclasses\\lib\\ant-1.7.0.jar",
+ "\\\\PC03\\jclasses\\lib\\ant-1.7.0.jar");
+ }
+
+ @Ignore("We don't appear to generate paths like this in the launcher")
+ @Test
+ public void testTripleForwardSlashNetworkURI() throws Exception {
+ resolveTo("file:///PC03/jclasses/lib/ant-1.7.0.jar",
+ "///PC03/jclasses/lib/ant-1.7.0.jar",
+ "\\\\PC03\\jclasses\\lib\\ant-1.7.0.jar");
+ }
+
+ @Test
+ public void testUnixNetworkPath() throws Exception {
+ resolveTo("file://cluster/home/ant/lib",
+ "//cluster/home/ant/lib",
+ "\\\\cluster\\home\\ant\\lib");
+ }
+
+ @Test
+ public void testUnixPath() throws Exception {
+ resolveTo("file:/home/ant/lib", "/home/ant/lib", null);
+ }
+
+ @Test
+ public void testSpacedURI() throws Exception {
+ resolveTo("file:C:\\Program Files\\Ant\\lib",
+ "C:\\Program Files\\Ant\\lib",
+ "C:\\Program Files\\Ant\\lib");
+ }
+
+ /**
+ * Bug 42275; Ant failing to run off a remote share
+ * @throws Throwable if desired
+ */
+ @Test
+ public void testAntOnRemoteShare() throws Throwable {
+ String resolved=Locator.fromJarURI(SHARED_JAR_URI);
+ assertResolved(SHARED_JAR_URI, LAUNCHER_JAR, resolved, unix);
+ assertResolved(SHARED_JAR_URI, LAUNCHER_JAR.replace('/', '\\'),
+ resolved, windows);
+ }
+
+ /**
+ * Bug 42275; Ant failing to run off a remote share
+ *
+ * @throws Throwable if desired
+ */
+ @Test
+ public void testFileFromRemoteShare() throws Throwable {
+ String resolved = Locator.fromJarURI(SHARED_JAR_URI);
+ File f = new File(resolved);
+ String path = f.getAbsolutePath();
+ if (windows) {
+ assertEquals(0, path.indexOf("\\\\"));
+ }
+ }
+
+ @Test
+ public void testHttpURI() throws Exception {
+ String url = "http://ant.apache.org";
+ try {
+ Locator.fromURI(url);
+ fail("Exception should have been thrown");
+ } catch (IllegalArgumentException e) {
+ String message = e.getMessage();
+ assertContains(Locator.ERROR_NOT_FILE_URI, message);
+ assertContains(url, message);
+ }
+ }
+
+ @Test
+ public void testInternationalURI() throws Exception {
+ String result = assertResolves("L\u00f6wenbrau.aus.M\u00fcnchen");
+ char umlauted = result.charAt(1);
+ assertEquals("expected 0xf6 (\u00f6), but got " + Integer.toHexString(umlauted) + " '"
+ + umlauted + "'", 0xf6, umlauted);
+ assertEquals("file:/tmp/a%C3%A7a%C3%AD%20berry", Locator.encodeURI("file:/tmp/a\u00E7a\u00ED berry"));
+ assertEquals("file:/tmp/a\u00E7a\u00ED berry", Locator.decodeUri("file:/tmp/a%C3%A7a%C3%AD%20berry"));
+ assertEquals("file:/tmp/a\u00E7a\u00ED berry", Locator.decodeUri("file:/tmp/a\u00E7a\u00ED%20berry")); // #50543
+ assertEquals("file:/tmp/hezky \u010Desky", Locator.decodeUri("file:/tmp/hezky%20\u010Desky")); // non-ISO-8859-1 variant
+ }
+
+ @Test
+ public void testOddLowAsciiURI() throws Exception {
+ assertResolves("hash# and percent%");
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/loader/AntClassLoader5Test.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/loader/AntClassLoader5Test.java
new file mode 100644
index 00000000..469877a4
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/loader/AntClassLoader5Test.java
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.loader;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.Enumeration;
+import org.apache.tools.ant.AntClassLoader;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.util.CollectionUtils;
+import org.junit.Test;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+public class AntClassLoader5Test {
+
+ /**
+ * Asserts that getResources won't return resources that cannot be
+ * seen by AntClassLoader but by ClassLoader.this.parent.
+ *
+ * @see <a href="https://issues.apache.org/bugzilla/show_bug.cgi?id=46752">
+ * https://issues.apache.org/bugzilla/show_bug.cgi?id=46752</a>
+ */
+ @Test
+ public void testGetResources() throws IOException {
+ AntClassLoader acl = new AntClassLoader5(new EmptyLoader(), null,
+ new Path(null), true);
+ assertNull(acl.getResource("META-INF/MANIFEST.MF"));
+ assertFalse(acl.getResources("META-INF/MANIFEST.MF").hasMoreElements());
+
+ // double check using system classloader as parent
+ acl = new AntClassLoader5(null, null, new Path(null), true);
+ assertNotNull(acl.getResource("META-INF/MANIFEST.MF"));
+ assertTrue(acl.getResources("META-INF/MANIFEST.MF").hasMoreElements());
+ }
+
+ @Test
+ public void testGetResourcesUsingFactory() throws IOException {
+ AntClassLoader acl =
+ AntClassLoader.newAntClassLoader(new EmptyLoader(), null,
+ new Path(null), true);
+ assertNull(acl.getResource("META-INF/MANIFEST.MF"));
+ assertFalse(acl.getResources("META-INF/MANIFEST.MF").hasMoreElements());
+ }
+
+ private static class EmptyLoader extends ClassLoader {
+ public URL getResource(String n) {
+ return null;
+ }
+ public Enumeration getResources(String n) {
+ return new CollectionUtils.EmptyEnumeration();
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/AbstractCvsTaskTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/AbstractCvsTaskTest.java
new file mode 100644
index 00000000..227987fa
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/AbstractCvsTaskTest.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.AntAssert;
+import org.apache.tools.ant.BuildFileRule;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import java.io.File;
+
+import static org.junit.Assert.assertTrue;
+
+/**
+ */
+public class AbstractCvsTaskTest {
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/abstractcvstask.xml");
+ buildRule.executeTarget("setUp");
+ }
+
+ @After
+ public void tearDown() {
+ buildRule.executeTarget("cleanup");
+ }
+
+ @Test
+ public void testAbstractCvsTask() {
+ buildRule.executeTarget("all");
+ }
+
+ @Test
+ public void testPackageAttribute() {
+ File f = new File(buildRule.getProject().getProperty("output") + "/src/Makefile");
+ assertTrue("starting empty", !f.exists());
+ buildRule.executeTarget("package-attribute");
+ AntAssert.assertContains("U src/Makefile", buildRule.getLog());
+ assertTrue("now it is there", f.exists());
+ }
+
+ @Test
+ public void testTagAttribute() {
+ File f = new File(buildRule.getProject().getProperty("output") + "/src/Makefile");
+ assertTrue("starting empty", !f.exists());
+ buildRule.executeTarget("tag-attribute");
+ AntAssert.assertContains("OPENBSD_5_3", buildRule.getLog());
+ assertTrue("now it is there", f.exists());
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/AntLikeTasksAtTopLevelTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/AntLikeTasksAtTopLevelTest.java
new file mode 100644
index 00000000..298bf098
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/AntLikeTasksAtTopLevelTest.java
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.BuildFileRule;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+/**
+ * @since Ant 1.6
+ */
+public class AntLikeTasksAtTopLevelTest {
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ @Test
+ public void testAnt() {
+ try {
+ buildRule.configureProject("src/etc/testcases/taskdefs/toplevelant.xml");
+ fail("no exception thrown");
+ } catch (BuildException e) {
+ assertEquals("ant task at the top level must not invoke its own"
+ + " build file.", e.getMessage());
+ }
+ }
+
+ @Test
+ public void testSubant() {
+ try {
+ buildRule.configureProject("src/etc/testcases/taskdefs/toplevelsubant.xml");
+ fail("no exception thrown");
+ } catch (BuildException e) {
+ assertEquals("subant task at the top level must not invoke its own"
+ + " build file.", e.getMessage());
+ }
+ }
+
+ @Test
+ public void testAntcall() {
+ try {
+ buildRule.configureProject("src/etc/testcases/taskdefs/toplevelantcall.xml");
+ fail("no exception thrown");
+ } catch (BuildException e) {
+ assertEquals("antcall must not be used at the top level.",
+ e.getMessage());
+ }
+ }
+
+}// AntLikeTasksAtTopLevelTest
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/AntStructureTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/AntStructureTest.java
new file mode 100644
index 00000000..da51b5d9
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/AntStructureTest.java
@@ -0,0 +1,114 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.AntAssert;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.BuildFileRule;
+import org.apache.tools.ant.Project;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import java.io.PrintWriter;
+import java.util.Hashtable;
+
+import static org.junit.Assert.fail;
+
+/**
+ */
+public class AntStructureTest {
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/antstructure.xml");
+ }
+
+ @After
+ public void tearDown() {
+ buildRule.executeTarget("tearDown");
+ }
+
+ @Test
+ public void test1() {
+ try {
+ buildRule.executeTarget("test1");
+ fail("required argument not specified");
+ } catch (BuildException ex) {
+ //TODO assert exception message
+ }
+ }
+
+ @Test
+ public void testCustomPrinter() {
+ buildRule.executeTarget("testCustomPrinter");
+ // can't access the booleans in MyPrinter here (even if they
+ // were static) since the MyPrinter instance that was used in
+ // the test has likely been loaded via a different classloader
+ // than this class. Therefore we make the printer assert its
+ // state and only check for the tail invocation.
+ AntAssert.assertContains(MyPrinter.TAIL_CALLED, buildRule.getLog());
+ }
+
+ public static class MyPrinter implements AntStructure.StructurePrinter {
+ private static final String TAIL_CALLED = "tail has been called";
+ private boolean headCalled = false;
+ private boolean targetCalled = false;
+ private boolean tailCalled = false;
+ private int elementCalled = 0;
+ private Project p;
+
+ public void printHead(PrintWriter out, Project p, Hashtable tasks,
+ Hashtable types) {
+ Assert.assertTrue(!headCalled);
+ Assert.assertTrue(!targetCalled);
+ Assert.assertTrue(!tailCalled);
+ Assert.assertEquals(0, elementCalled);
+ headCalled = true;
+ }
+ public void printTargetDecl(PrintWriter out) {
+ Assert.assertTrue(headCalled);
+ Assert.assertTrue(!targetCalled);
+ Assert.assertTrue(!tailCalled);
+ Assert.assertEquals(0, elementCalled);
+ targetCalled = true;
+ }
+ public void printElementDecl(PrintWriter out, Project p, String name,
+ Class element) {
+ Assert.assertTrue(headCalled);
+ Assert.assertTrue(targetCalled);
+ Assert.assertTrue(!tailCalled);
+ elementCalled++;
+ this.p = p;
+ }
+ public void printTail(PrintWriter out) {
+ Assert.assertTrue(headCalled);
+ Assert.assertTrue(targetCalled);
+ Assert.assertTrue(!tailCalled);
+ Assert.assertTrue(elementCalled > 0);
+ tailCalled = true;
+ p.log(TAIL_CALLED);
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/AntTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/AntTest.java
new file mode 100644
index 00000000..0d6453c4
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/AntTest.java
@@ -0,0 +1,607 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.io.File;
+
+import junit.framework.AssertionFailedError;
+
+import org.apache.tools.ant.AntAssert;
+import org.apache.tools.ant.BuildEvent;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.BuildFileRule;
+import org.apache.tools.ant.BuildListener;
+import org.apache.tools.ant.input.InputHandler;
+import org.apache.tools.ant.input.PropertyFileInputHandler;
+import org.apache.tools.ant.types.Path;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+/**
+ */
+public class AntTest {
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/ant.xml");
+ }
+
+ @After
+ public void tearDown() {
+ buildRule.executeTarget("cleanup");
+ }
+
+ @Test
+ public void test1() {
+ try {
+ buildRule.executeTarget("test1");
+ fail("recursive call");
+ } catch(BuildException ex) {
+ //TODO assert exception message
+ }
+ }
+
+ // target must be specified
+ @Test
+ public void test2() {
+ try {
+ buildRule.executeTarget("test2");
+ fail("required argument not specified");
+ } catch(BuildException ex) {
+ //TODO assert exception message
+ }
+ }
+
+ // Should fail since a recursion will occur...
+ @Test
+ public void test3() {
+ try {
+ buildRule.executeTarget("test1");
+ fail("recursive call");
+ } catch(BuildException ex) {
+ //TODO assert exception message
+ }
+ }
+
+ @Test
+ public void test4() {
+ try {
+ buildRule.executeTarget("test4");
+ fail("target attribute must not be empty");
+ } catch (BuildException ex) {
+ //TODO assert exception message
+ }
+ }
+
+ @Test
+ public void test4b() {
+ try {
+ buildRule.executeTarget("test4b");
+ fail("target doesn't exist");
+ } catch(BuildException ex) {
+ //TODO assert exception message
+ }
+ }
+
+ @Test
+ public void test5() {
+ buildRule.executeTarget("test5");
+ }
+
+ @Test
+ public void test6() {
+ buildRule.executeTarget("test6");
+ }
+
+ @Test
+ public void testExplicitBasedir1() {
+ File dir1 = buildRule.getProject().getBaseDir();
+ File dir2 = buildRule.getProject().resolveFile("..");
+ testBaseDirs("explicitBasedir1",
+ new String[] {dir1.getAbsolutePath(),
+ dir2.getAbsolutePath()
+ });
+ }
+
+ @Test
+ public void testExplicitBasedir2() {
+ File dir1 = buildRule.getProject().getBaseDir();
+ File dir2 = buildRule.getProject().resolveFile("..");
+ testBaseDirs("explicitBasedir2",
+ new String[] {dir1.getAbsolutePath(),
+ dir2.getAbsolutePath()
+ });
+ }
+
+ @Test
+ public void testInheritBasedir() {
+ String basedir = buildRule.getProject().getBaseDir().getAbsolutePath();
+ testBaseDirs("inheritBasedir", new String[] {basedir, basedir});
+ }
+
+ @Test
+ public void testDoNotInheritBasedir() {
+ File dir1 = buildRule.getProject().getBaseDir();
+ File dir2 = buildRule.getProject().resolveFile("ant");
+ testBaseDirs("doNotInheritBasedir",
+ new String[] {dir1.getAbsolutePath(),
+ dir2.getAbsolutePath()
+ });
+ }
+
+ @Test
+ public void testBasedirTripleCall() {
+ File dir1 = buildRule.getProject().getBaseDir();
+ File dir2 = buildRule.getProject().resolveFile("ant");
+ testBaseDirs("tripleCall",
+ new String[] {dir1.getAbsolutePath(),
+ dir2.getAbsolutePath(),
+ dir1.getAbsolutePath()
+ });
+ }
+
+ protected void testBaseDirs(String target, String[] dirs) {
+ BasedirChecker bc = new BasedirChecker(dirs);
+ buildRule.getProject().addBuildListener(bc);
+ buildRule.executeTarget(target);
+ AssertionFailedError ae = bc.getError();
+ if (ae != null) {
+ throw ae;
+ }
+ buildRule.getProject().removeBuildListener(bc);
+ }
+
+ @Test
+ public void testReferenceInheritance() {
+ Path p = Path.systemClasspath;
+ p.setProject(buildRule.getProject());
+ buildRule.getProject().addReference("path", p);
+ buildRule.getProject().addReference("no-override", p);
+ testReference("testInherit", new String[] {"path", "path"},
+ new boolean[] {true, true}, p);
+ testReference("testInherit",
+ new String[] {"no-override", "no-override"},
+ new boolean[] {true, false}, p);
+ testReference("testInherit",
+ new String[] {"no-override", "no-override"},
+ new boolean[] {false, false}, null);
+ }
+
+ @Test
+ public void testReferenceNoInheritance() {
+ Path p = Path.systemClasspath;
+ p.setProject(buildRule.getProject());
+ buildRule.getProject().addReference("path", p);
+ buildRule.getProject().addReference("no-override", p);
+ testReference("testNoInherit", new String[] {"path", "path"},
+ new boolean[] {true, false}, p);
+ testReference("testNoInherit", new String[] {"path", "path"},
+ new boolean[] {false, true}, null);
+ testReference("testInherit",
+ new String[] {"no-override", "no-override"},
+ new boolean[] {true, false}, p);
+ testReference("testInherit",
+ new String[] {"no-override", "no-override"},
+ new boolean[] {false, false}, null);
+ }
+
+ @Test
+ public void testReferenceRename() {
+ Path p = Path.systemClasspath;
+ p.setProject(buildRule.getProject());
+ buildRule.getProject().addReference("path", p);
+ testReference("testRename", new String[] {"path", "path"},
+ new boolean[] {true, false}, p);
+ testReference("testRename", new String[] {"path", "path"},
+ new boolean[] {false, true}, null);
+ testReference("testRename", new String[] {"newpath", "newpath"},
+ new boolean[] {false, true}, p);
+ }
+
+ @Test
+ public void testInheritPath() {
+ buildRule.executeTarget("testInheritPath");
+ }
+
+ protected void testReference(String target, String[] keys,
+ boolean[] expect, Object value) {
+ ReferenceChecker rc = new ReferenceChecker(keys, expect, value);
+ buildRule.getProject().addBuildListener(rc);
+ buildRule.executeTarget(target);
+ AssertionFailedError ae = rc.getError();
+ if (ae != null) {
+ throw ae;
+ }
+ buildRule.getProject().removeBuildListener(rc);
+ }
+
+ @Test
+ public void testLogfilePlacement() {
+ File[] logFiles = new File[] {
+ buildRule.getProject().resolveFile("test1.log"),
+ buildRule.getProject().resolveFile("test2.log"),
+ buildRule.getProject().resolveFile("ant/test3.log"),
+ buildRule.getProject().resolveFile("ant/test4.log")
+ };
+ for (int i=0; i<logFiles.length; i++) {
+ assertTrue(logFiles[i].getName()+" doesn\'t exist",
+ !logFiles[i].exists());
+ }
+
+ buildRule.executeTarget("testLogfilePlacement");
+
+ for (int i=0; i<logFiles.length; i++) {
+ assertTrue(logFiles[i].getName()+" exists",
+ logFiles[i].exists());
+ }
+ }
+
+ @Test
+ public void testInputHandlerInheritance() {
+ InputHandler ih = new PropertyFileInputHandler();
+ buildRule.getProject().setInputHandler(ih);
+ InputHandlerChecker ic = new InputHandlerChecker(ih);
+ buildRule.getProject().addBuildListener(ic);
+ buildRule.executeTarget("tripleCall");
+ AssertionFailedError ae = ic.getError();
+ if (ae != null) {
+ throw ae;
+ }
+ buildRule.getProject().removeBuildListener(ic);
+ }
+
+ @Test
+ public void testRefId() {
+ Path testPath = new Path(buildRule.getProject());
+ testPath.createPath().setPath(System.getProperty("java.class.path"));
+ PropertyChecker pc =
+ new PropertyChecker("testprop",
+ new String[] {null,
+ testPath.toString()});
+ buildRule.getProject().addBuildListener(pc);
+ buildRule.executeTarget("testRefid");
+ AssertionFailedError ae = pc.getError();
+ if (ae != null) {
+ throw ae;
+ }
+ buildRule.getProject().removeBuildListener(pc);
+ }
+
+ @Test
+ public void testUserPropertyWinsInheritAll() {
+ buildRule.getProject().setUserProperty("test", "7");
+ buildRule.executeTarget("test-property-override-inheritall-start");
+
+ AntAssert.assertContains("The value of test is 7", buildRule.getLog());
+ }
+
+ @Test
+ public void testUserPropertyWinsNoInheritAll() {
+ buildRule.getProject().setUserProperty("test", "7");
+ buildRule.executeTarget("test-property-override-no-inheritall-start");
+
+ AntAssert.assertContains("The value of test is 7", buildRule.getLog());
+ }
+
+ @Test
+ public void testOverrideWinsInheritAll() {
+ buildRule.executeTarget("test-property-override-inheritall-start");
+
+ AntAssert.assertContains("The value of test is 4", buildRule.getLog());
+ }
+
+ @Test
+ public void testOverrideWinsNoInheritAll() {
+ buildRule.executeTarget("test-property-override-no-inheritall-start");
+ AntAssert.assertContains("The value of test is 4", buildRule.getLog());
+ }
+
+ @Test
+ public void testPropertySet() {
+ buildRule.executeTarget("test-propertyset");
+ assertTrue(buildRule.getLog().indexOf("test1 is ${test1}") > -1);
+ assertTrue(buildRule.getLog().indexOf("test2 is ${test2}") > -1);
+ assertTrue(buildRule.getLog().indexOf("test1.x is 1") > -1);
+ }
+
+ @Test
+ public void testInfiniteLoopViaDepends() {
+ try {
+ buildRule.executeTarget("infinite-loop-via-depends");
+ fail("recursive call");
+ } catch(BuildException ex) {
+ //TODO assert exception message
+ }
+ }
+
+ @Test
+ public void testMultiSameProperty() {
+ buildRule.executeTarget("multi-same-property");
+ assertEquals("prop is two", buildRule.getLog());
+ }
+
+ @Test
+ public void testTopLevelTarget() {
+ buildRule.executeTarget("topleveltarget");
+
+ assertEquals("Hello world", buildRule.getLog());
+ }
+
+ @Test
+ public void testMultiplePropertyFileChildren() {
+ PropertyChecker pcBar = new PropertyChecker("bar",
+ new String[] {null, "Bar"});
+ PropertyChecker pcFoo = new PropertyChecker("foo",
+ new String[] {null, "Foo"});
+ buildRule.getProject().addBuildListener(pcBar);
+ buildRule.getProject().addBuildListener(pcFoo);
+ buildRule.executeTarget("multiple-property-file-children");
+ AssertionFailedError aeBar = pcBar.getError();
+ if (aeBar != null) {
+ throw aeBar;
+ }
+ AssertionFailedError aeFoo = pcFoo.getError();
+ if (aeFoo != null) {
+ throw aeFoo;
+ }
+ buildRule.getProject().removeBuildListener(pcBar);
+ buildRule.getProject().removeBuildListener(pcFoo);
+ }
+
+ @Test
+ public void testBlankTarget() {
+ try {
+ buildRule.executeTarget("blank-target");
+ fail("target name must not be empty");
+ } catch(BuildException ex) {
+ //TODO assert exception message
+ }
+ }
+
+ @Test
+ public void testMultipleTargets() {
+ buildRule.executeTarget("multiple-targets");
+ assertEquals("tadadctbdbtc", buildRule.getLog());
+ }
+
+ @Test
+ public void testMultipleTargets2() {
+ buildRule.executeTarget("multiple-targets-2");
+ assertEquals("dadctb", buildRule.getLog());
+ }
+
+ @Test
+ public void testAntCoreLib() {
+ // Cf. #42263
+ buildRule.executeTarget("sub-show-ant.core.lib");
+ String realLog = buildRule.getLog();
+ assertTrue("found ant.core.lib in: " + realLog, realLog.matches(".*(ant[.]jar|build.classes).*"));
+ }
+
+ private class BasedirChecker implements BuildListener {
+ private String[] expectedBasedirs;
+ private int calls = 0;
+ private AssertionFailedError error;
+
+ BasedirChecker(String[] dirs) {
+ expectedBasedirs = dirs;
+ }
+
+ public void buildStarted(BuildEvent event) {}
+ public void buildFinished(BuildEvent event) {}
+ public void targetFinished(BuildEvent event){}
+ public void taskStarted(BuildEvent event) {}
+ public void taskFinished(BuildEvent event) {}
+ public void messageLogged(BuildEvent event) {}
+
+ public void targetStarted(BuildEvent event) {
+ if (event.getTarget().getName().equals("")) {
+ return;
+ }
+ if (error == null) {
+ try {
+ assertEquals(expectedBasedirs[calls++],
+ event.getProject().getBaseDir().getAbsolutePath());
+ } catch (AssertionFailedError e) {
+ error = e;
+ }
+ }
+ }
+
+ AssertionFailedError getError() {
+ return error;
+ }
+
+ }
+
+ private class ReferenceChecker implements BuildListener {
+ private String[] keys;
+ private boolean[] expectSame;
+ private Object value;
+ private int calls = 0;
+ private AssertionFailedError error;
+
+ ReferenceChecker(String[] keys, boolean[] expectSame, Object value) {
+ this.keys = keys;
+ this.expectSame = expectSame;
+ this.value = value;
+ }
+
+ public void buildStarted(BuildEvent event) {}
+ public void buildFinished(BuildEvent event) {}
+ public void targetFinished(BuildEvent event){}
+ public void taskStarted(BuildEvent event) {}
+ public void taskFinished(BuildEvent event) {}
+ public void messageLogged(BuildEvent event) {}
+
+ public void targetStarted(BuildEvent event) {
+ if (event.getTarget().getName().equals("")) {
+ return;
+ }
+ if (error == null) {
+ try {
+ String msg =
+ "Call " + calls + " refid=\'" + keys[calls] + "\'";
+ if (value == null) {
+ Object o = event.getProject().getReference(keys[calls]);
+ if (expectSame[calls++]) {
+ assertNull(msg, o);
+ } else {
+ assertNotNull(msg, o);
+ }
+ } else {
+ // a rather convoluted equals() test
+ Path expect = (Path) value;
+ Path received = (Path) event.getProject().getReference(keys[calls]);
+ boolean shouldBeEqual = expectSame[calls++];
+ if (received == null) {
+ assertTrue(msg, !shouldBeEqual);
+ } else {
+ String[] l1 = expect.list();
+ String[] l2 = received.list();
+ if (l1.length == l2.length) {
+ for (int i=0; i<l1.length; i++) {
+ if (!l1[i].equals(l2[i])) {
+ assertTrue(msg, !shouldBeEqual);
+ }
+ }
+ assertTrue(msg, shouldBeEqual);
+ } else {
+ assertTrue(msg, !shouldBeEqual);
+ }
+ }
+ }
+ } catch (AssertionFailedError e) {
+ error = e;
+ }
+ }
+ }
+
+ AssertionFailedError getError() {
+ return error;
+ }
+
+ }
+
+ private class InputHandlerChecker implements BuildListener {
+ private InputHandler ih;
+ private AssertionFailedError error;
+
+ InputHandlerChecker(InputHandler value) {
+ ih = value;
+ }
+
+ public void buildStarted(BuildEvent event) {
+ check(event);
+ }
+ public void buildFinished(BuildEvent event) {
+ check(event);
+ }
+ public void targetFinished(BuildEvent event) {
+ check(event);
+ }
+ public void taskStarted(BuildEvent event) {
+ check(event);
+ }
+ public void taskFinished(BuildEvent event) {
+ check(event);
+ }
+ public void messageLogged(BuildEvent event) {
+ check(event);
+ }
+
+ public void targetStarted(BuildEvent event) {
+ check(event);
+ }
+
+ private void check(BuildEvent event) {
+ if (error == null) {
+ try {
+ assertNotNull(event.getProject().getInputHandler());
+ assertSame(ih, event.getProject().getInputHandler());
+ } catch (AssertionFailedError e) {
+ error = e;
+ }
+ }
+ }
+
+ AssertionFailedError getError() {
+ return error;
+ }
+
+ }
+
+ private class PropertyChecker implements BuildListener {
+ private String[] expectedValues;
+ private String key;
+ private int calls = 0;
+ private AssertionFailedError error;
+
+ PropertyChecker(String key, String[] values) {
+ this.key = key;
+ this.expectedValues = values;
+ }
+
+ public void buildStarted(BuildEvent event) {}
+ public void buildFinished(BuildEvent event) {}
+ public void targetFinished(BuildEvent event){}
+ public void taskStarted(BuildEvent event) {}
+ public void taskFinished(BuildEvent event) {}
+ public void messageLogged(BuildEvent event) {}
+
+ public void targetStarted(BuildEvent event) {
+ if (event.getTarget().getName().equals("")) {
+ return;
+ }
+ if (calls >= expectedValues.length) {
+ error = new AssertionFailedError("Unexpected invocation of"
+ + " target "
+ + event.getTarget().getName());
+ }
+
+ if (error == null) {
+ try {
+ assertEquals(expectedValues[calls++],
+ event.getProject().getProperty(key));
+ } catch (AssertionFailedError e) {
+ error = e;
+ }
+ }
+ }
+
+ AssertionFailedError getError() {
+ return error;
+ }
+
+ }
+
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/AntlibTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/AntlibTest.java
new file mode 100644
index 00000000..c5c78ab3
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/AntlibTest.java
@@ -0,0 +1,106 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.BuildFileRule;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.Project;
+import org.junit.Assume;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ */
+public class AntlibTest {
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/antlib.xml");
+ }
+
+ /**
+ * only do the antlib tests if we are in the same JVM as ant.
+ * @return
+ */
+ private boolean isSharedJVM() {
+ String property = System.getProperty("tests.and.ant.share.classloader");
+ return property!=null && Project.toBoolean(property);
+ }
+
+ @Test
+ public void testAntlibFile() {
+ buildRule.executeTarget("antlib.file");
+ assertEquals("MyTask called", buildRule.getLog());
+ }
+
+ /**
+ * Confirms that all matching resources will be used, so that you
+ * can collect several antlibs in one Definer call.
+ * @see "http://issues.apache.org/bugzilla/show_bug.cgi?id=24024"
+ */
+ @Test
+ public void testAntlibResource() {
+ buildRule.executeTarget("antlib.resource");
+ assertEquals("MyTask called-and-then-MyTask2 called", buildRule.getLog());
+ }
+
+ @Test
+ public void testNsCurrent() {
+ buildRule.executeTarget("ns.current");
+ assertEquals("Echo2 inside a macroHello from x:p", buildRule.getLog());
+ }
+
+ @Test
+ public void testAntlib_uri() {
+ Assume.assumeTrue("Test requires shared JVM", isSharedJVM());
+ buildRule.executeTarget("antlib_uri");
+ }
+
+ @Test
+ public void testAntlib_uri_auto() {
+ Assume.assumeTrue("Test requires shared JVM", isSharedJVM());
+ buildRule.executeTarget("antlib_uri_auto");
+ }
+
+ @Test
+ public void testAntlib_uri_auto2() {
+ Assume.assumeTrue("Test requires shared JVM", isSharedJVM());
+ buildRule.executeTarget("antlib_uri_auto2");
+ }
+
+ public static class MyTask extends Task {
+ public void execute() {
+ log("MyTask called");
+ }
+ }
+
+ public static class MyTask2 extends Task {
+ public void execute() {
+ log("MyTask2 called");
+ }
+ }
+
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/AvailableTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/AvailableTest.java
new file mode 100644
index 00000000..ef97e375
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/AvailableTest.java
@@ -0,0 +1,272 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.BuildFileRule;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+/**
+ * JUnit test for the Available task/condition.
+ */
+public class AvailableTest {
+
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/available.xml");
+ buildRule.executeTarget("setUp");
+ }
+
+ // Nothing specified -> Fail
+ @Test
+ public void test1() {
+ try {
+ buildRule.executeTarget("test1");
+ fail("Required argument not specified");
+ } catch (BuildException ex) {
+ //TODO assert exception message
+ }
+ }
+
+ // Only property specified -> Fail
+ @Test
+ public void test2() {
+ try {
+ buildRule.executeTarget("test2");
+ fail("Required argument not specified");
+ } catch (BuildException ex) {
+ //TODO assert exception message
+ }
+ }
+
+ // Only file specified -> Fail
+ @Test
+ public void test3() {
+ try {
+ buildRule.executeTarget("test3");
+ fail("Required argument not specified");
+ } catch (BuildException ex) {
+ //TODO assert exception message
+ }
+ }
+
+ // file doesn't exist -> property 'test' == null
+ @Test
+ public void test4() {
+ buildRule.executeTarget("test4");
+ assertTrue(buildRule.getProject().getProperty("test") == null);
+ }
+
+ // file does exist -> property 'test' == 'true'
+ public void test5() {
+ buildRule.executeTarget("test5");
+ assertEquals("true", buildRule.getProject().getProperty("test"));
+ }
+
+ // resource doesn't exist -> property 'test' == null
+ @Test
+ public void test6() {
+ buildRule.executeTarget("test6");
+ assertTrue(buildRule.getProject().getProperty("test") == null);
+ }
+
+ // resource does exist -> property 'test' == 'true'
+ @Test
+ public void test7() {
+ buildRule.executeTarget("test7");
+ assertEquals("true", buildRule.getProject().getProperty("test"));
+ }
+
+ // class doesn't exist -> property 'test' == null
+ @Test
+ public void test8() {
+ buildRule.executeTarget("test8");
+ assertTrue(buildRule.getProject().getProperty("test") == null);
+ }
+
+ // class does exist -> property 'test' == 'true'
+ @Test
+ public void test9() {
+ buildRule.executeTarget("test9");
+ assertEquals("true", buildRule.getProject().getProperty("test"));
+ }
+
+ // All three specified and all three exist -> true
+ @Test
+ public void test10() {
+ buildRule.executeTarget("test10");
+ assertEquals("true", buildRule.getProject().getProperty("test"));
+ }
+
+ // All three specified but class missing -> null
+ @Test
+ public void test11() {
+ buildRule.executeTarget("test11");
+ assertNull(buildRule.getProject().getProperty("test"));
+ }
+
+ // Specified property-name is "" -> true
+ @Test
+ public void test12() {
+ buildRule.executeTarget("test12");
+ assertNull(buildRule.getProject().getProperty("test"));
+ assertEquals("true", buildRule.getProject().getProperty(""));
+ }
+
+ // Specified file is "" -> invalid files do not exist
+ @Test
+ public void test13() {
+ buildRule.executeTarget("test13");
+ assertNull(buildRule.getProject().getProperty("test"));
+ }
+
+ // Specified file is "" actually a directory, so it should pass
+ @Test
+ public void test13b() {
+ buildRule.executeTarget("test13b");
+ assertEquals("true", buildRule.getProject().getProperty("test"));
+ }
+
+ // Specified resource is "" -> can such a thing exist?
+ /*
+ * returns non null IBM JDK 1.3 Linux
+ */
+// public void test14() {
+// buildRule.executeTarget("test14");
+// assertEquals(buildRule.getProject().getProperty("test"), null);
+// }
+
+ // Specified class is "" -> can not exist
+ @Test
+ public void test15() {
+ buildRule.executeTarget("test15");
+ assertNull(buildRule.getProject().getProperty("test"));
+ }
+
+ // Specified dir is "" -> this is the current directory and should
+ // always exist
+ @Test
+ public void test16() {
+ buildRule.executeTarget("test16");
+ assertEquals("true", buildRule.getProject().getProperty("test"));
+ }
+
+ // Specified dir is "../taskdefs" -> should exist since it's the
+ // location of the buildfile used...
+ @Test
+ public void test17() {
+ buildRule.executeTarget("test17");
+ assertEquals("true", buildRule.getProject().getProperty("test"));
+ }
+
+ // Specified dir is "../this_dir_should_never_exist" -> null
+ @Test
+ public void test18() {
+ buildRule.executeTarget("test18");
+ assertNull(buildRule.getProject().getProperty("test"));
+ }
+
+ // Invalid type specified
+ @Test
+ public void test19() {
+ try {
+ buildRule.executeTarget("test19");
+ fail("Invalid value for type attribute");
+ } catch (BuildException ex) {
+ //TODO assert exception message
+ }
+ }
+
+ // Core class that exists in system classpath is ignored
+ @Test
+ public void test20() {
+ buildRule.executeTarget("test20");
+ assertNull(buildRule.getProject().getProperty("test"));
+ }
+
+ // Core class that exists in system classpath is ignored, but found in specified classpath
+ @Test
+ public void test21() {
+ buildRule.executeTarget("test21");
+ assertEquals("true", buildRule.getProject().getProperty("test"));
+ }
+
+ // Core class that exists in system classpath is not ignored with ignoresystemclass="false"
+ @Test
+ public void test22() {
+ buildRule.executeTarget("test22");
+ assertEquals("true", buildRule.getProject().getProperty("test"));
+ }
+
+ // Core class that exists in system classpath is not ignored with default ignoresystemclasses value
+ @Test
+ public void test23() {
+ buildRule.executeTarget("test23");
+ assertEquals("true", buildRule.getProject().getProperty("test"));
+ }
+
+ // Class is found in specified classpath
+ @Test
+ public void test24() {
+ buildRule.executeTarget("test24");
+ assertEquals("true", buildRule.getProject().getProperty("test"));
+ }
+
+ // File is not found in specified filepath
+ @Test
+ public void testSearchInPathNotThere() {
+ buildRule.executeTarget("searchInPathNotThere");
+ assertNull(buildRule.getProject().getProperty("test"));
+ }
+
+ // File is not found in specified filepath
+ @Test
+ public void testSearchInPathIsThere() {
+ buildRule.executeTarget("searchInPathIsThere");
+ assertEquals("true", buildRule.getProject().getProperty("test"));
+ }
+
+ // test when file begins with basedir twice
+ @Test
+ public void testDoubleBasedir() {
+ buildRule.executeTarget("testDoubleBasedir");
+ }
+
+ // test for searching parents
+ @Test
+ public void testSearchParents() {
+ buildRule.executeTarget("search-parents");
+ }
+ // test for not searching parents
+ @Test
+ public void testSearchParentsNot() {
+ buildRule.executeTarget("search-parents-not");
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/BUnzip2Test.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/BUnzip2Test.java
new file mode 100644
index 00000000..9ea9a4ff
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/BUnzip2Test.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.io.File;
+import org.apache.tools.ant.BuildFileRule;
+import org.apache.tools.ant.FileUtilities;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+
+public class BUnzip2Test {
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ private File outputDir;
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/bunzip2.xml");
+ outputDir = new File(buildRule.getProject().getProperty("output"));
+ buildRule.executeTarget("prepare");
+ }
+
+ @Test
+ public void testRealTest() throws java.io.IOException {
+ testRealTest("realTest");
+ }
+
+ @Test
+ public void testRealTestWithResource() throws java.io.IOException {
+ testRealTest("realTestWithResource");
+ }
+
+ private void testRealTest(String target) throws java.io.IOException {
+ buildRule.executeTarget(target);
+ assertEquals("File content mismatch after bunzip2",
+ FileUtilities.getFileContents(new File(outputDir, "asf-logo-huge-from-gzip.tar")),
+ FileUtilities.getFileContents(new File(outputDir, "asf-logo-huge.tar")));
+ }
+
+ @Test
+ public void testDocumentationClaimsOnCopy() throws java.io.IOException {
+ testRealTest("testDocumentationClaimsOnCopy");
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/BZip2Test.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/BZip2Test.java
new file mode 100644
index 00000000..bd881430
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/BZip2Test.java
@@ -0,0 +1,117 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.BuildFileRule;
+import org.apache.tools.bzip2.CBZip2InputStream;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+/**
+ */
+public class BZip2Test {
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ private File outputDir;
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/bzip2.xml");
+ outputDir = new File(buildRule.getProject().getProperty("output"));
+ buildRule.executeTarget("prepare");
+ }
+
+ @Test
+ public void testRealTest() throws IOException {
+ buildRule.executeTarget("realTest");
+
+ // doesn't work: Depending on the compression engine used,
+ // compressed bytes may differ. False errors would be
+ // reported.
+ // assertTrue("File content mismatch",
+ // FILE_UTILS.contentEquals(project.resolveFile("expected/asf-logo-huge.tar.bz2"),
+ // project.resolveFile("asf-logo-huge.tar.bz2")));
+
+ // We have to compare the decompressed content instead:
+
+ File originalFile =
+ buildRule.getProject().resolveFile("expected/asf-logo-huge.tar.bz2");
+ File actualFile = new File(outputDir, "asf-logo-huge.tar.bz2");
+
+ InputStream originalIn =
+ new BufferedInputStream(new FileInputStream(originalFile));
+ assertEquals((byte) 'B', originalIn.read());
+ assertEquals((byte) 'Z', originalIn.read());
+
+ InputStream actualIn =
+ new BufferedInputStream(new FileInputStream(actualFile));
+ assertEquals((byte) 'B', actualIn.read());
+ assertEquals((byte) 'Z', actualIn.read());
+
+ originalIn = new CBZip2InputStream(originalIn);
+ actualIn = new CBZip2InputStream(actualIn);
+
+ while (true) {
+ int expected = originalIn.read();
+ int actual = actualIn.read();
+ if (expected >= 0) {
+ if (expected != actual) {
+ fail("File content mismatch");
+ }
+ } else {
+ if (actual >= 0) {
+ fail("File content mismatch");
+ }
+ break;
+ }
+ }
+
+ originalIn.close();
+ actualIn.close();
+ }
+
+ @Test
+ public void testResource(){
+ buildRule.executeTarget("realTestWithResource");
+ }
+
+ @Test
+ public void testDateCheck(){
+ buildRule.executeTarget("testDateCheck");
+ String log = buildRule.getLog();
+ assertTrue(
+ "Expecting message ending with 'asf-logo.gif.bz2 is up to date.' but got '" + log + "'",
+ log.endsWith("asf-logo.gif.bz2 is up to date."));
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/BasenameTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/BasenameTest.java
new file mode 100644
index 00000000..3915d6b1
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/BasenameTest.java
@@ -0,0 +1,114 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.BuildFileRule;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+/**
+ */
+public class BasenameTest {
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/basename.xml");
+ }
+
+ @Test
+ public void test1() {
+ try {
+ buildRule.executeTarget("test1");
+ fail("Required attribute missing");
+ } catch (BuildException ex) {
+ //TODO assert exception message
+ }
+ }
+
+ @Test
+ public void test2() {
+ try {
+ buildRule.executeTarget("test2");
+ fail("Required attribute missing");
+ } catch (BuildException ex) {
+ //TODO assert exception message
+ }
+ }
+
+ @Test
+ public void test3() {
+ try {
+ buildRule.executeTarget("test3");
+ fail("Required attribute missing");
+ } catch (BuildException ex) {
+ //TODO assert exception message
+ }
+ }
+
+ @Test
+ public void test4() {
+ buildRule.executeTarget("test4");
+ String checkprop = buildRule.getProject().getProperty("file.w.suf");
+ assertEquals("foo.txt", checkprop);
+ }
+
+ @Test
+ public void test5() {
+ buildRule.executeTarget("test5");
+ String checkprop = buildRule.getProject().getProperty("file.wo.suf");
+ assertEquals("foo", checkprop);
+ }
+
+ @Test
+ public void testMultipleDots() {
+ buildRule.executeTarget("testMultipleDots");
+ String checkprop = buildRule.getProject().getProperty("file.wo.suf");
+ assertEquals("foo.bar", checkprop);
+ }
+
+ @Test
+ public void testNoDots() {
+ buildRule.executeTarget("testNoDots");
+ String checkprop = buildRule.getProject().getProperty("file.wo.suf");
+ assertEquals("foo.bar", checkprop);
+ }
+
+ @Test
+ public void testValueEqualsSuffixWithDot() {
+ buildRule.executeTarget("testValueEqualsSuffixWithDot");
+ String checkprop = buildRule.getProject().getProperty("file.wo.suf");
+ assertEquals("", checkprop);
+ }
+
+ @Test
+ public void testValueEqualsSuffixWithoutDot() {
+ buildRule.executeTarget("testValueEqualsSuffixWithoutDot");
+ String checkprop = buildRule.getProject().getProperty("file.wo.suf");
+ assertEquals("", checkprop);
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/CVSPassTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/CVSPassTest.java
new file mode 100644
index 00000000..9fe42b15
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/CVSPassTest.java
@@ -0,0 +1,119 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.io.*;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.BuildFileRule;
+import org.apache.tools.ant.FileUtilities;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+/**
+ * Tests CVSLogin task.
+ *
+ */
+public class CVSPassTest {
+ private final String EOL = System.getProperty("line.separator");
+ private static final String JAKARTA_URL =
+ ":pserver:anoncvs@jakarta.apache.org:/home/cvspublic Ay=0=h<Z";
+ private static final String XML_URL =
+ ":pserver:anoncvs@xml.apache.org:/home/cvspublic Ay=0=h<Z";
+ private static final String TIGRIS_URL =
+ ":pserver:guest@cvs.tigris.org:/cvs AIbdZ,";
+
+ @Rule
+ public final BuildFileRule buildRule = new BuildFileRule();
+
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/cvspass.xml");
+ }
+
+ @Test
+ public void testNoCVSRoot() {
+ try{
+ buildRule.executeTarget("test1");
+ fail("BuildException not thrown");
+ }catch(BuildException e){
+ assertEquals("cvsroot is required", e.getMessage());
+ }
+ }
+
+ @Test
+ public void testNoPassword() {
+ try{
+ buildRule.executeTarget("test2");
+ fail("BuildException not thrown");
+ }catch(BuildException e){
+ assertEquals("password is required", e.getMessage());
+ }
+ }
+
+ @After
+ public void tearDown() {
+ buildRule.executeTarget("cleanup");
+ }
+
+ @Test
+ public void testPassFile() throws Exception {
+ buildRule.executeTarget("test3");
+ File f = new File(buildRule.getProject().getBaseDir(), "testpassfile.tmp");
+
+ assertTrue( "Passfile "+f+" not created", f.exists());
+
+ assertEquals(JAKARTA_URL+EOL, FileUtilities.getFileContents(f));
+
+ }
+
+ @Test
+ public void testPassFileDuplicateEntry() throws Exception {
+ buildRule.executeTarget("test4");
+ File f = new File(buildRule.getProject().getBaseDir(), "testpassfile.tmp");
+
+ assertTrue( "Passfile "+f+" not created", f.exists());
+
+ assertEquals(
+ JAKARTA_URL+ EOL+
+ TIGRIS_URL+ EOL,
+ FileUtilities.getFileContents(f));
+ }
+
+ @Test
+ public void testPassFileMultipleEntry() throws Exception {
+ buildRule.executeTarget("test5");
+ File f = new File(buildRule.getProject().getBaseDir(), "testpassfile.tmp");
+
+ assertTrue( "Passfile "+f+" not created", f.exists());
+
+ assertEquals(
+ JAKARTA_URL+ EOL+
+ XML_URL+ EOL+
+ TIGRIS_URL+ EOL,
+ FileUtilities.getFileContents(f));
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/CallTargetTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/CallTargetTest.java
new file mode 100644
index 00000000..337c6a46
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/CallTargetTest.java
@@ -0,0 +1,92 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.AntAssert;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.BuildFileRule;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import java.util.Vector;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+/**
+ */
+public class CallTargetTest {
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/calltarget.xml");
+ buildRule.executeTarget("setUp");
+ }
+
+ // see bugrep 21724 (references not passing through with antcall)
+ @Test
+ public void testInheritRefFileSet() {
+ buildRule.executeTarget("testinheritreffileset");
+ AntAssert.assertContains("calltarget.xml", buildRule.getLog());
+ }
+
+ // see bugrep 21724 (references not passing through with antcall)
+ @Test
+ public void testInheritFilterset() {
+ buildRule.getProject().executeTarget("testinheritreffilterset");
+ }
+
+ // see bugrep 11418 (In repeated calls to the same target,
+ // params will not be passed in)
+ @Test
+ public void testMultiCall() {
+ Vector<String> v = new Vector<String>();
+ v.add("call-multi");
+ v.add("call-multi");
+ buildRule.getProject().executeTargets(v);
+ AntAssert.assertContains("multi is SETmulti is SET", buildRule.getLog());
+ }
+
+ @Test
+ public void testBlankTarget() {
+ try {
+ buildRule.executeTarget("blank-target");
+ fail("target name must not be empty");
+ } catch (BuildException ex) {
+ //TODO assert exception contents
+ }
+ }
+
+ @Test
+ public void testMultipleTargets() {
+ buildRule.executeTarget("multiple-targets");
+ assertEquals("tadadctbdbtc", buildRule.getLog());
+ }
+
+ @Test
+ public void testMultipleTargets2() {
+ buildRule.executeTarget("multiple-targets-2");
+ assertEquals("dadctb", buildRule.getLog());
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/ChecksumTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/ChecksumTest.java
new file mode 100644
index 00000000..bd4bdfcf
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/ChecksumTest.java
@@ -0,0 +1,109 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.BuildFileRule;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import java.io.IOException;
+
+public class ChecksumTest {
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/checksum.xml");
+ }
+
+ @After
+ public void tearDown() {
+ buildRule.executeTarget("cleanup");
+ }
+
+ @Test
+ public void testCreateMd5() throws IOException {
+ buildRule.executeTarget("createMd5");
+ }
+
+ @Test
+ public void testCreateMD5SUMformat() throws IOException {
+ buildRule.executeTarget("createMD5SUMformat");
+ }
+
+ @Test
+ public void testCreateSVFformat() throws IOException {
+ buildRule.executeTarget("createSVFformat");
+ }
+
+ @Test
+ public void testCreatePattern() throws IOException {
+ buildRule.executeTarget("createPattern");
+ }
+
+ @Test
+ public void testSetProperty() {
+ buildRule.executeTarget("setProperty");
+ }
+
+ @Test
+ public void testVerifyTotal() {
+ buildRule.executeTarget("verifyTotal");
+ }
+
+ @Test
+ public void testVerifyTotalRC() {
+ buildRule.executeTarget("verifyTotalRC");
+ }
+
+ @Test
+ public void testVerifyChecksumdir() {
+ buildRule.executeTarget("verifyChecksumdir");
+ }
+
+ @Test
+ public void testVerifyAsTask() {
+ buildRule.executeTarget("verifyAsTask");
+ }
+
+ @Test
+ public void testVerifyMD5SUMAsTask() {
+ buildRule.executeTarget("verifyMD5SUMAsTask");
+ }
+
+ @Test
+ public void testVerifyAsCondition() {
+ buildRule.executeTarget("verifyAsCondition");
+ }
+
+ @Test
+ public void testVerifyFromProperty() {
+ buildRule.executeTarget("verifyFromProperty");
+ }
+
+ @Test
+ public void testVerifyChecksumdirNoTotal() {
+ buildRule.executeTarget("verifyChecksumdirNoTotal");
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/ConcatTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/ConcatTest.java
new file mode 100644
index 00000000..b5441830
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/ConcatTest.java
@@ -0,0 +1,315 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.BuildFileRule;
+import org.apache.tools.ant.FileUtilities;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import java.io.File;
+import java.io.IOException;
+
+import static org.apache.tools.ant.AntAssert.assertContains;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+/**
+ * A test class for the 'concat' task, used to concatenate a series of
+ * files into a single stream.
+ *
+ */
+public class ConcatTest {
+
+ /**
+ * The name of the temporary file.
+ */
+ private static final String tempFile = "concat.tmp";
+
+ /**
+ * The name of the temporary file.
+ */
+ private static final String tempFile2 = "concat.tmp.2";
+
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+
+ /**
+ * Test set up, called by the unit test framework prior to each
+ * test.
+ */
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/concat.xml");
+ }
+
+ /**
+ * Test tear down, called by the unit test framework prior to each
+ * test.
+ */
+ @After
+ public void tearDown() {
+ buildRule.executeTarget("cleanup");
+ }
+
+ /**
+ * Expect an exception when insufficient information is provided.
+ */
+ @Test
+ public void test1() {
+ try {
+ buildRule.executeTarget("test1");
+ fail("BuildException should have been thrown - Insufficient information");
+ } catch (BuildException ex) {
+ //TODO assert value
+ }
+
+ }
+
+ /**
+ * Expect an exception when the destination file is invalid.
+ */
+ @Test
+ public void test2() {
+ try {
+ buildRule.executeTarget("test2");
+ fail("BuildException should have been thrown - Invalid destination file");
+ } catch(BuildException ex) {
+ //TODO assert value
+ }
+ }
+
+ /**
+ * Cats the string 'Hello, World!' to a temporary file.
+ */
+ @Test
+ public void test3() {
+
+ File file = new File(buildRule.getProject().getBaseDir(), tempFile);
+ if (file.exists()) {
+ file.delete();
+ }
+
+ buildRule.executeTarget("test3");
+
+ assertTrue(file.exists());
+ }
+
+ /**
+ * Cats the file created in test3 three times.
+ */
+ @Test
+ public void test4() {
+ test3();
+
+ File file = new File(buildRule.getProject().getBaseDir(), tempFile);
+ final long origSize = file.length();
+
+ buildRule.executeTarget("test4");
+
+ File file2 = new File(buildRule.getProject().getBaseDir(), tempFile2);
+ final long newSize = file2.length();
+
+ assertEquals(origSize * 3, newSize);
+ }
+
+ /**
+ * Cats the string 'Hello, World!' to the console.
+ */
+ @Test
+ public void test5() {
+ buildRule.executeTarget("test5");
+ assertEquals("Hello, World!", buildRule.getLog());
+ }
+
+ @Test
+ public void test6() {
+ String filename = "src/etc/testcases/taskdefs/thisfiledoesnotexist"
+ .replace('/', File.separatorChar);
+ buildRule.executeTarget("test6");
+ assertContains(filename + " does not exist", buildRule.getLog());
+ }
+
+ @Test
+ public void testConcatNoNewline() {
+ buildRule.executeTarget("testConcatNoNewline");
+ assertEquals("ab", buildRule.getLog());
+ }
+
+ @Test
+ public void testConcatNoNewlineEncoding() {
+ buildRule.executeTarget("testConcatNoNewlineEncoding");
+ assertEquals("ab", buildRule.getLog());
+ }
+
+ @Test
+ public void testPath() {
+ test3();
+
+ File file = new File(buildRule.getProject().getBaseDir(), tempFile);
+ final long origSize = file.length();
+
+ buildRule.executeTarget("testPath");
+
+ File file2 = new File(buildRule.getProject().getBaseDir(), tempFile2);
+ final long newSize = file2.length();
+
+ assertEquals(origSize, newSize);
+
+ }
+
+ @Test
+ public void testAppend() {
+ test3();
+
+ File file = new File(buildRule.getProject().getBaseDir(), tempFile);
+ final long origSize = file.length();
+
+ buildRule.executeTarget("testAppend");
+
+ File file2 = new File(buildRule.getProject().getBaseDir(), tempFile2);
+ final long newSize = file2.length();
+
+ assertEquals(origSize*2, newSize);
+
+ }
+
+ @Test
+ public void testFilter() {
+ buildRule.executeTarget("testfilter");
+ assertTrue(buildRule.getLog().indexOf("REPLACED") > -1);
+ }
+
+ @Test
+ public void testNoOverwrite() {
+ buildRule.executeTarget("testnooverwrite");
+ File file2 = new File(buildRule.getProject().getBaseDir(), tempFile2);
+ long size = file2.length();
+ assertEquals(size, 0);
+ }
+
+ @Test
+ public void testOverwrite() {
+ buildRule.executeTarget("testoverwrite");
+ File file2 = new File(buildRule.getProject().getBaseDir(), tempFile2);
+ long size = file2.length();
+ assertTrue(size > 0);
+ }
+
+ @Test
+ public void testheaderfooter() {
+ test3();
+ buildRule.executeTarget("testheaderfooter");
+ assertEquals("headerHello, World!footer", buildRule.getLog());
+ }
+
+ @Test
+ public void testfileheader() {
+ test3();
+ buildRule.executeTarget("testfileheader");
+ assertEquals("Hello, World!Hello, World!", buildRule.getLog());
+ }
+
+ /**
+ * Expect an exception when attempting to cat an file to itself
+ */
+ @Test
+ public void testsame() {
+ try {
+ buildRule.executeTarget("samefile");
+ fail("Build exception should have been thrown - output file same as input");
+ } catch(BuildException ex) {
+ //TODO assert value
+ }
+ }
+
+ /**
+ * Check if filter inline works
+ */
+ @Test
+ public void testfilterinline() {
+ buildRule.executeTarget("testfilterinline");
+ assertTrue(buildRule.getLog().indexOf("REPLACED") > -1);
+ }
+
+ /**
+ * Check if multireader works
+ */
+ @Test
+ public void testmultireader() {
+ buildRule.executeTarget("testmultireader");
+ assertTrue(buildRule.getLog().indexOf("Bye") > -1);
+ assertTrue(buildRule.getLog().indexOf("Hello") == -1);
+ }
+ /**
+ * Check if fixlastline works
+ */
+ @Test
+ public void testfixlastline()
+ throws IOException
+ {
+ buildRule.executeTarget("testfixlastline");
+ assertContains("end of line" + System.getProperty("line.separator") + "This has",
+ FileUtilities.getFileContents(buildRule.getProject(), "concat.line4"));
+ }
+
+ /**
+ * Check if fixlastline works with eol
+ */
+ @Test
+ public void testfixlastlineeol()
+ throws IOException
+ {
+ buildRule.executeTarget("testfixlastlineeol");
+ assertContains("end of line\rThis has", FileUtilities.getFileContents(buildRule.getProject(), "concat.linecr"));
+ }
+
+
+ @Test
+ public void testTranscoding() throws IOException {
+ buildRule.executeTarget("testTranscoding");
+ File f1 = buildRule.getProject().resolveFile("copy/expected/utf-8");
+ File f2 = buildRule.getProject().resolveFile("concat.utf8");
+ assertEquals(f1.toString() + " differs from " + f2.toString(),
+ FileUtilities.getFileContents(f1), FileUtilities.getFileContents(f2));
+ }
+
+ // ------------------------------------------------------
+ // Helper methods - should be in a utility class
+ // -----------------------------------------------------
+ private void expectFileContainsx(
+ String target, String filename, String contains)
+ throws IOException
+ {
+ buildRule.executeTarget(target);
+ String content = FileUtilities.getFileContents(buildRule.getProject(), filename);
+ assertTrue(
+ "expecting file " + filename + " to contain " +
+ contains +
+ " but got " + content, content.indexOf(contains) > -1);
+ }
+
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/ConditionTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/ConditionTest.java
new file mode 100644
index 00000000..1b6c1039
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/ConditionTest.java
@@ -0,0 +1,379 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.BuildFileRule;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.fail;
+
+public class ConditionTest {
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+
+ /**
+ * The JUnit setup method
+ */
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/condition.xml");
+ }
+
+
+ /**
+ * The teardown method for JUnit
+ */
+ @After
+ public void tearDown() {
+ buildRule.executeTarget("cleanup");
+ }
+
+ @Test
+ public void testBasic() {
+ buildRule.executeTarget("basic");
+ assertEquals("true", buildRule.getProject().getProperty("basic"));
+ }
+
+ @Test
+ public void testConditionIncomplete() {
+ try {
+ buildRule.executeTarget("condition-incomplete");
+ fail("BuildException should have been thrown - property attribute has been omitted");
+ } catch (BuildException ex) {
+ assertEquals("The property attribute is required.", ex.getMessage());
+ }
+ }
+
+ @Test
+ public void testConditionEmpty() {
+ try {
+ buildRule.executeTarget("condition-empty");
+ fail("BuildException should have been thrown - no conditions");
+ } catch(BuildException ex) {
+ assertEquals("You must nest a condition into <condition>", ex.getMessage());
+ }
+ }
+
+ @Test
+ public void testShortcut() {
+ buildRule.executeTarget("shortcut");
+ assertEquals("set", buildRule.getProject().getProperty("shortcut"));
+ }
+
+ @Test
+ public void testUnset() {
+ buildRule.executeTarget("dontset");
+ assertNull(buildRule.getProject().getProperty("dontset"));
+ }
+
+ @Test
+ public void testSetValue() {
+ buildRule.executeTarget("setvalue");
+ assertEquals("woowoo", buildRule.getProject().getProperty("setvalue"));
+ }
+
+ @Test
+ public void testNegation() {
+ buildRule.executeTarget("negation");
+ assertEquals("true", buildRule.getProject().getProperty("negation"));
+ }
+
+ @Test
+ public void testNegationFalse() {
+ buildRule.executeTarget("negationfalse");
+ assertNull(buildRule.getProject().getProperty("negationfalse"));
+ }
+
+ @Test
+ public void testNegationIncomplete() {
+ try {
+ buildRule.executeTarget("negationincomplete");
+ fail("BuildException should have been thrown - no conditions in <not>");
+ } catch (BuildException ex) {
+ assertEquals("You must nest a condition into <not>", ex.getMessage());
+ }
+ }
+
+ @Test
+ public void testAnd() {
+ buildRule.executeTarget("and");
+ assertEquals("true", buildRule.getProject().getProperty("and"));
+ }
+
+ @Test
+ public void testAndFails() {
+ buildRule.executeTarget("andfails");
+ assertNull(buildRule.getProject().getProperty("andfails"));
+ }
+
+ @Test
+ public void testAndIncomplete() {
+ buildRule.executeTarget("andincomplete");
+ assertNull(buildRule.getProject().getProperty("andincomplete"));
+ }
+
+ @Test
+ public void testAndempty() {
+ buildRule.executeTarget("andempty");
+ assertEquals("true", buildRule.getProject().getProperty("andempty"));
+ }
+
+ @Test
+ public void testOr() {
+ buildRule.executeTarget("or");
+ assertEquals("true", buildRule.getProject().getProperty("or"));
+ }
+
+ @Test
+ public void testOrincomplete() {
+ buildRule.executeTarget("or");
+ assertEquals("true", buildRule.getProject().getProperty("or"));
+ }
+
+ @Test
+ public void testOrFails() {
+ buildRule.executeTarget("orfails");
+ assertNull(buildRule.getProject().getProperty("orfails"));
+ }
+
+ @Test
+ public void testOrboth() {
+ buildRule.executeTarget("orboth");
+ assertEquals("true", buildRule.getProject().getProperty("orboth"));
+ }
+
+ @Test
+ public void testFilesmatchIdentical() {
+ buildRule.executeTarget("filesmatch-identical");
+ assertEquals("true", buildRule.getProject().getProperty("filesmatch-identical"));
+ }
+
+ @Test
+ public void testFilesmatchIncomplete() {
+ try {
+ buildRule.executeTarget("filesmatch-incomplete");
+ fail("Build exception should have been thrown - Missing file2 attirbute");
+ } catch (BuildException ex) {
+ assertEquals("both file1 and file2 are required in filesmatch", ex.getMessage());
+ }
+ }
+
+ @Test
+ public void testFilesmatchOddsizes() {
+ buildRule.executeTarget("filesmatch-oddsizes");
+ assertNull(buildRule.getProject().getProperty("filesmatch-oddsizes"));
+ }
+
+ @Test
+ public void testFilesmatchExistence() {
+ buildRule.executeTarget("filesmatch-existence");
+ assertNull(buildRule.getProject().getProperty("filesmatch-existence"));
+ }
+
+ @Test
+ public void testFilesmatchDifferent() {
+ buildRule.executeTarget("filesmatch-different");
+ assertNull(buildRule.getProject().getProperty("filesmatch-different"));
+ }
+
+ @Test
+ public void testFilesmatchMatch() {
+ buildRule.executeTarget("filesmatch-match");
+ assertEquals("true", buildRule.getProject().getProperty("filesmatch-match"));
+ }
+
+ @Test
+ public void testFilesmatchDifferentSizes() {
+ buildRule.executeTarget("filesmatch-different-sizes");
+ assertNull(buildRule.getProject().getProperty("filesmatch-different-sizes"));
+ }
+
+ @Test
+ public void testFilesmatchDifferentOnemissing() {
+ buildRule.executeTarget("filesmatch-different-onemissing");
+ assertNull(buildRule.getProject().getProperty("filesmatch-different-onemissing"));
+ }
+
+ @Test
+ public void testFilesmatchDifferentEol() {
+ buildRule.executeTarget("filesmatch-different-eol");
+ }
+
+ @Test
+ public void testFilesmatchSameEol() {
+ buildRule.executeTarget("filesmatch-same-eol");
+ }
+
+ @Test
+ public void testFilesmatchNeitherExist() {
+ buildRule.executeTarget("filesmatch-neitherexist");
+ }
+
+ @Test
+ public void testContains() {
+ buildRule.executeTarget("contains");
+ assertEquals("true", buildRule.getProject().getProperty("contains"));
+ }
+
+ @Test
+ public void testContainsDoesnt() {
+ buildRule.executeTarget("contains-doesnt");
+ assertNull(buildRule.getProject().getProperty("contains-doesnt"));
+ }
+
+ @Test
+ public void testContainsAnycase() {
+ buildRule.executeTarget("contains-anycase");
+ assertEquals("true", buildRule.getProject().getProperty("contains-anycase"));
+ }
+
+ @Test
+ public void testContainsIncomplete1() {
+ try {
+ buildRule.executeTarget("contains-incomplete1");
+ fail("BuildException should have been thrown - Missing contains attribute");
+ } catch(BuildException ex) {
+ assertEquals("both string and substring are required in contains", ex.getMessage());
+ }
+ }
+
+ @Test
+ public void testContainsIncomplete2() {
+ try {
+ buildRule.executeTarget("contains-incomplete2");
+ fail("BuildException should have been thrown - Missing contains attribute");
+ } catch(BuildException ex) {
+ assertEquals("both string and substring are required in contains", ex.getMessage());
+ }
+ }
+
+ @Test
+ public void testIstrue() {
+ buildRule.executeTarget("istrue");
+ assertEquals("true", buildRule.getProject().getProperty("istrue"));
+ }
+
+ @Test
+ public void testIstrueNot() {
+ buildRule.executeTarget("istrue-not");
+ assertNull(buildRule.getProject().getProperty("istrue-not"));
+ }
+
+ @Test
+ public void testIstrueFalse() {
+ buildRule.executeTarget("istrue-false");
+ assertNull(buildRule.getProject().getProperty("istrue-false"));
+ }
+
+ @Test
+ public void testIstrueIncomplete1() {
+ try {
+ buildRule.executeTarget("istrue-incomplete");
+ fail("BuildException should have been thrown - Missing attribute");
+ } catch(BuildException ex) {
+ assertEquals("Nothing to test for truth", ex.getMessage());
+ }
+ }
+
+ @Test
+ public void testIsfalseTrue() {
+ buildRule.executeTarget("isfalse-true");
+ assertNull(buildRule.getProject().getProperty("isfalse-true"));
+ }
+
+ @Test
+ public void testIsfalseNot() {
+ buildRule.executeTarget("isfalse-not");
+ assertEquals("true", buildRule.getProject().getProperty("isfalse-not"));
+ }
+
+ @Test
+ public void testIsfalseFalse() {
+
+ buildRule.executeTarget("isfalse-false");
+ assertEquals("true", buildRule.getProject().getProperty("isfalse-false"));
+ }
+
+ @Test
+ public void testIsfalseIncomplete1() {
+ try {
+ buildRule.executeTarget("isfalse-incomplete");
+ fail("BuildException should have been thrown - Missing attribute");
+ } catch(BuildException ex) {
+ assertEquals("Nothing to test for falsehood", ex.getMessage());
+ }
+ }
+
+ @Test
+ public void testElse() {
+ buildRule.executeTarget("testElse");
+ }
+
+ @Test
+ public void testResourcesmatchError() {
+ try {
+ buildRule.executeTarget("resourcematch-error");
+ fail("BuildException should have been thrown - no resources specified");
+ } catch (BuildException ex) {
+ //TODO assert value
+ }
+ }
+
+ @Test
+ public void testResourcesmatchEmpty() {
+ buildRule.executeTarget("resourcesmatch-match-empty");
+ }
+
+ @Test
+ public void testResourcesmatchOne() {
+ buildRule.executeTarget("resourcesmatch-match-one");
+ }
+
+ @Test
+ public void testResourcesmatchBinary() {
+ buildRule.executeTarget("resourcesmatch-match-binary");
+ }
+
+ @Test
+ public void testResourcesmatchMultipleBinary() {
+ buildRule.executeTarget("resourcesmatch-match-multiple-binary");
+ }
+
+ @Test
+ public void testResourcesmatchDiffer() {
+ buildRule.executeTarget("resourcesmatch-differ");
+ }
+
+ @Test
+ public void testResourcesmatchText() {
+ buildRule.executeTarget("resourcesmatch-match-text");
+ }
+
+ @Test
+ public void testResourcesmatchNoneExist() {
+ buildRule.executeTarget("resourcesmatch-noneexist");
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/CopyTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/CopyTest.java
new file mode 100644
index 00000000..a7a32a9a
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/CopyTest.java
@@ -0,0 +1,280 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.BuildFileRule;
+import org.apache.tools.ant.FileUtilities;
+import org.apache.tools.ant.util.FileUtils;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Rule;
+import org.junit.Test;
+
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+
+import static org.apache.tools.ant.AntAssert.assertContains;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+/**
+ * Tests FileSet using the Copy task.
+ *
+ */
+public class CopyTest {
+
+ @Rule
+ public final BuildFileRule buildRule = new BuildFileRule();
+
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/copy.xml");
+ buildRule.executeTarget("setUp");
+ }
+
+ @Test
+ public void test1() {
+ buildRule.executeTarget("test1");
+ File f = new File(buildRule.getProject().getProperty("output"), "copytest1.tmp");
+ if ( !f.exists()) {
+ fail("Copy failed");
+ }
+ }
+
+ @Test
+ public void test2() {
+ buildRule.executeTarget("test2");
+ File f = new File(buildRule.getProject().getProperty("output"), "copytest1dir/copy.xml");
+ if ( !f.exists()) {
+ fail("Copy failed");
+ }
+ }
+
+ @Test
+ public void test3() {
+ buildRule.executeTarget("test3");
+ File file3 = new File(buildRule.getProject().getProperty("output"), "copytest3.tmp");
+ //rollback file timestamp instead of delaying test
+ FileUtilities.rollbackTimetamps(file3, 3);
+ buildRule.executeTarget("test3Part2");
+ assertTrue(file3.exists());
+
+ File file3a = new File(buildRule.getProject().getProperty("output"), "copytest3a.tmp");
+ assertTrue(file3a.exists());
+ File file3b = new File(buildRule.getProject().getProperty("output"), "copytest3b.tmp");
+ assertTrue(file3b.exists());
+ File file3c = new File(buildRule.getProject().getProperty("output"), "copytest3c.tmp");
+ assertTrue(file3c.exists());
+
+ //file length checks rely on touch generating a zero byte file
+ if(file3.length()==0) {
+ fail("could not overwrite an existing, older file");
+ }
+ if(file3c.length()!=0) {
+ fail("could not force overwrite an existing, newer file");
+ }
+ if(file3b.length()==0) {
+ fail("unexpectedly overwrote an existing, newer file");
+ }
+
+ //file time checks for java1.2+
+ assertTrue(file3a.lastModified()==file3.lastModified());
+ assertTrue(file3c.lastModified()<file3a.lastModified());
+
+ }
+
+ @Test
+ public void testFilterTest() {
+ buildRule.executeTarget("filtertest");
+ assertTrue(buildRule.getLog().indexOf("loop in tokens") == -1);
+ }
+
+ @Test
+ public void testInfiniteFilter() {
+ buildRule.executeTarget("infinitetest");
+ assertContains("loop in tokens", buildRule.getOutput());
+ }
+
+ @Test
+ public void testFilterSet() throws IOException {
+ buildRule.executeTarget("testFilterSet");
+ File tmp = new File(buildRule.getProject().getProperty("output"), "copy.filterset.tmp");
+ File check = new File(buildRule.getProject().getBaseDir(), "expected/copy.filterset.filtered");
+ assertTrue(tmp.exists());
+ assertEquals(FileUtilities.getFileContents(tmp), FileUtilities.getFileContents(check));
+ }
+
+ @Test
+ public void testFilterChain() throws IOException {
+ buildRule.executeTarget("testFilterChain");
+ File tmp = new File(buildRule.getProject().getProperty("output"), "copy.filterchain.tmp");
+ File check = new File(buildRule.getProject().getBaseDir(), "expected/copy.filterset.filtered");
+ assertTrue(tmp.exists());
+ assertEquals(FileUtilities.getFileContents(tmp), FileUtilities.getFileContents(check));
+ }
+
+ @Test
+ public void testSingleFileFileset() {
+ buildRule.executeTarget("test_single_file_fileset");
+ File file = new File(buildRule.getProject().getProperty("output"),
+ "copytest_single_file_fileset.tmp");
+ assertTrue(file.exists());
+ }
+
+ @Test
+ public void testSingleFilePath() {
+ buildRule.executeTarget("test_single_file_path");
+ File file = new File(buildRule.getProject().getProperty("output"),
+ "copytest_single_file_path.tmp");
+ assertTrue(file.exists());
+ }
+
+ @Test
+ public void testTranscoding() throws IOException {
+ buildRule.executeTarget("testTranscoding");
+ File f1 = buildRule.getProject().resolveFile("copy/expected/utf-8");
+ File f2 = new File(buildRule.getProject().getProperty("output"), "copytest1.tmp");
+ assertEquals(FileUtilities.getFileContents(f1), FileUtilities.getFileContents(f2));
+ }
+
+ @Test
+ public void testMissingFileIgnore() {
+ buildRule.executeTarget("testMissingFileIgnore");
+ assertContains("Warning: Could not find file", buildRule.getLog());
+ }
+
+ @Test
+ public void testMissingFileBail() {
+ try {
+ buildRule.executeTarget("testMissingFileBail");
+ fail("not-there doesn't exist");
+ } catch (BuildException ex) {
+ assertTrue(ex.getMessage()
+ .startsWith("Warning: Could not find file "));
+ }
+ }
+
+ @Test
+ public void testMissingDirIgnore() {
+ buildRule.executeTarget("testMissingDirIgnore");
+ assertContains("Warning: ", buildRule.getLog());
+ }
+
+ @Test
+ public void testMissingDirBail() {
+ try {
+ buildRule.executeTarget("testMissingDirBail");
+ fail("not-there doesn't exist");
+ } catch (BuildException ex) {
+ assertTrue(ex.getMessage().endsWith(" does not exist."));
+ }
+ }
+
+ @Test
+ public void testFileResourcePlain() {
+ buildRule.executeTarget("testFileResourcePlain");
+ File file1 = new File(buildRule.getProject().getProperty("to.dir")+"/file1.txt");
+ File file2 = new File(buildRule.getProject().getProperty("to.dir")+"/file2.txt");
+ File file3 = new File(buildRule.getProject().getProperty("to.dir")+"/file3.txt");
+ assertTrue(file1.exists());
+ assertTrue(file2.exists());
+ assertTrue(file3.exists());
+ }
+
+ @Ignore("Previously ignored by naming convention")
+ @Test
+ public void testFileResourceWithMapper() {
+ buildRule.executeTarget("testFileResourceWithMapper");
+ File file1 = new File(buildRule.getProject().getProperty("to.dir")+"/file1.txt.bak");
+ File file2 = new File(buildRule.getProject().getProperty("to.dir")+"/file2.txt.bak");
+ File file3 = new File(buildRule.getProject().getProperty("to.dir")+"/file3.txt.bak");
+ assertTrue(file1.exists());
+ assertTrue(file2.exists());
+ assertTrue(file3.exists());
+ }
+
+ @Test
+ public void testFileResourceWithFilter() {
+ buildRule.executeTarget("testFileResourceWithFilter");
+ File file1 = new File(buildRule.getProject().getProperty("to.dir")+"/fileNR.txt");
+ assertTrue(file1.exists());
+ try {
+ String file1Content = FileUtils.readFully(new FileReader(file1));
+ assertEquals("This is file 42", file1Content);
+ } catch (IOException e) {
+ // no-op: not a real business error
+ }
+ }
+
+ @Test
+ public void testPathAsResource() {
+ buildRule.executeTarget("testPathAsResource");
+ File file1 = new File(buildRule.getProject().getProperty("to.dir")+"/file1.txt");
+ File file2 = new File(buildRule.getProject().getProperty("to.dir")+"/file2.txt");
+ File file3 = new File(buildRule.getProject().getProperty("to.dir")+"/file3.txt");
+ assertTrue(file1.exists());
+ assertTrue(file2.exists());
+ assertTrue(file3.exists());
+ }
+
+ @Test
+ public void testZipfileset() {
+ buildRule.executeTarget("testZipfileset");
+ File file1 = new File(buildRule.getProject().getProperty("to.dir")+"/file1.txt");
+ File file2 = new File(buildRule.getProject().getProperty("to.dir")+"/file2.txt");
+ File file3 = new File(buildRule.getProject().getProperty("to.dir")+"/file3.txt");
+ assertTrue(file1.exists());
+ assertTrue(file2.exists());
+ assertTrue(file3.exists());
+ }
+
+ @Test
+ public void testDirset() {
+ buildRule.executeTarget("testDirset");
+ }
+
+ @Ignore("Previously ignored due to naming convention")
+ @Test
+ public void testResourcePlain() {
+ buildRule.executeTarget("testResourcePlain");
+ }
+
+ @Ignore("Previously ignored due to naming convention")
+ @Test
+ public void testResourcePlainWithMapper() {
+ buildRule.executeTarget("testResourcePlainWithMapper");
+ }
+
+ @Ignore("Previously ignored due to naming convention")
+ @Test
+ public void testResourcePlainWithFilter() {
+ buildRule.executeTarget("testResourcePlainWithFilter");
+ }
+
+ @Ignore("Previously ignored due to naming convention")
+ @Test
+ public void testOnlineResources() {
+ buildRule.executeTarget("testOnlineResources");
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/CopydirTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/CopydirTest.java
new file mode 100644
index 00000000..a7fdd5cb
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/CopydirTest.java
@@ -0,0 +1,100 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.BuildFileRule;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.File;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+
+public class CopydirTest {
+
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/copydir.xml");
+ buildRule.executeTarget("setUp");
+ }
+
+ @Test
+ public void test1() {
+ try {
+ buildRule.executeTarget("test1");
+ fail("Required argument not specified");
+ } catch (BuildException ex) {
+ // TODO assert value
+ }
+ }
+
+ @Test
+ public void test2() {
+ try {
+ buildRule.executeTarget("test2");
+ fail("Required argument not specified");
+ } catch (BuildException ex) {
+ // TODO assert value
+ }
+ }
+
+ @Test
+ public void test3() {
+ try {
+ buildRule.executeTarget("test3");
+ fail("Required argument not specified");
+ } catch (BuildException ex) {
+ // TODO assert value
+ }
+ }
+
+ @Test
+ public void test4() {
+ buildRule.executeTarget("test4");
+ assertEquals("DEPRECATED - The copydir task is deprecated. Use copy instead.Warning: src == dest",
+ buildRule.getLog());
+ }
+
+ @Test
+ public void test5() {
+ buildRule.executeTarget("test5");
+ java.io.File f = new java.io.File(new File(buildRule.getProject().getProperty("output")), "taskdefs.tmp");
+
+ if (!f.exists() || !f.isDirectory()) {
+ fail("Copy failed");
+ }
+ // We keep this, so we have something to delete in later tests :-)
+ }
+
+ @Test
+ public void test6() {
+ try {
+ buildRule.executeTarget("test6");
+ fail("target is file");
+ } catch (BuildException ex) {
+ //TODO assert value
+ }
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/CopyfileTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/CopyfileTest.java
new file mode 100644
index 00000000..a3d84eeb
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/CopyfileTest.java
@@ -0,0 +1,100 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.BuildFileRule;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.File;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+/**
+ */
+public class CopyfileTest {
+
+ public final BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/copyfile.xml");
+ buildRule.executeTarget("setUp");
+ }
+
+ @Test
+ public void test1() {
+ try {
+ buildRule.executeTarget("test1");
+ fail("Required argument not specified");
+ } catch (BuildException ex) {
+ // TODO assert value
+ }
+ }
+
+ @Test
+ public void test2() {
+ try {
+ buildRule.executeTarget("test2");
+ fail("Required argument not specified");
+ } catch (BuildException ex) {
+ // TODO assert value
+ }
+ }
+
+ @Test
+ public void test3() {
+ try {
+ buildRule.executeTarget("test3");
+ fail("Required argument not specified");
+ } catch (BuildException ex) {
+ // TODO assert value
+ }
+ }
+
+ @Test
+ public void test4() {
+ buildRule.executeTarget("test4");
+ assertEquals("DEPRECATED - The copyfile task is deprecated. Use copy instead.Warning: src == dest",
+ buildRule.getLog());
+ }
+
+ @Test
+ public void test5() {
+ buildRule.executeTarget("test5");
+ File f = new File(new File(buildRule.getProject().getProperty("output")), "copyfile.tmp");
+ if (f.exists()) {
+ f.delete();
+ } else {
+ fail("Copy failed");
+ }
+ }
+
+ @Test
+ public void test6() {
+ try {
+ buildRule.executeTarget("test6");
+ fail("Required argument not specified");
+ } catch (BuildException ex) {
+ // TODO assert value
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/DefaultExcludesTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/DefaultExcludesTest.java
new file mode 100644
index 00000000..e093d4f7
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/DefaultExcludesTest.java
@@ -0,0 +1,170 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.BuildFileRule;
+import org.apache.tools.ant.DirectoryScanner;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+/**
+ */
+public class DefaultExcludesTest {
+
+ @Rule
+ public final BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/defaultexcludes.xml");
+ }
+
+ @After
+ public void tearDown() {
+ buildRule.executeTarget("cleanup");
+ }
+
+ // Output the default excludes
+ @Test
+ public void test1() {
+ String[] expected = {
+ "**/*~",
+ "**/#*#",
+ "**/.#*",
+ "**/%*%",
+ "**/._*",
+ "**/CVS",
+ "**/CVS/**",
+ "**/.cvsignore",
+ "**/SCCS",
+ "**/SCCS/**",
+ "**/vssver.scc",
+ "**/.svn",
+ "**/.svn/**",
+ "**/.git",
+ "**/.git/**",
+ "**/.gitattributes",
+ "**/.gitignore",
+ "**/.gitmodules",
+ "**/.hg",
+ "**/.hg/**",
+ "**/.hgignore",
+ "**/.hgsub",
+ "**/.hgsubstate",
+ "**/.hgtags",
+ "**/.bzr",
+ "**/.bzr/**",
+ "**/.bzrignore",
+ "**/.DS_Store"};
+ buildRule.getProject().executeTarget("test1");
+ assertArrayContentsEquals("current default excludes", expected, DirectoryScanner.getDefaultExcludes());
+ }
+
+ // adding something to the excludes'
+ @Test
+ public void test2() {
+ String[] expected = {
+ "**/*~",
+ "**/#*#",
+ "**/.#*",
+ "**/%*%",
+ "**/._*",
+ "**/CVS",
+ "**/CVS/**",
+ "**/.cvsignore",
+ "**/SCCS",
+ "**/SCCS/**",
+ "**/vssver.scc",
+ "**/.svn",
+ "**/.svn/**",
+ "**/.git",
+ "**/.git/**",
+ "**/.gitattributes",
+ "**/.gitignore",
+ "**/.gitmodules",
+ "**/.hg",
+ "**/.hg/**",
+ "**/.hgignore",
+ "**/.hgsub",
+ "**/.hgsubstate",
+ "**/.hgtags",
+ "**/.bzr",
+ "**/.bzr/**",
+ "**/.bzrignore",
+ "**/.DS_Store",
+ "foo"};
+ buildRule.executeTarget("test2");
+ assertArrayContentsEquals("current default excludes", expected, DirectoryScanner.getDefaultExcludes());
+ }
+
+ // removing something from the defaults
+ @Test
+ public void test3() {
+ String[] expected = {
+ "**/*~",
+ "**/#*#",
+ "**/.#*",
+ "**/%*%",
+ "**/._*",
+ //CVS missing
+ "**/CVS/**",
+ "**/.cvsignore",
+ "**/SCCS",
+ "**/SCCS/**",
+ "**/vssver.scc",
+ "**/.svn",
+ "**/.svn/**",
+ "**/.git",
+ "**/.git/**",
+ "**/.gitattributes",
+ "**/.gitignore",
+ "**/.gitmodules",
+ "**/.hg",
+ "**/.hg/**",
+ "**/.hgignore",
+ "**/.hgsub",
+ "**/.hgsubstate",
+ "**/.hgtags",
+ "**/.bzr",
+ "**/.bzr/**",
+ "**/.bzrignore",
+ "**/.DS_Store"};
+ buildRule.executeTarget("test3");
+ assertArrayContentsEquals("current default excludes", expected, DirectoryScanner.getDefaultExcludes());
+ }
+
+ private void assertArrayContentsEquals(String message, String[] expected, String[] actual) {
+ // check that both arrays have the same size
+ assertEquals(message + " : string array length match", expected.length, actual.length);
+ for (int counter=0; counter < expected.length; counter++) {
+ boolean found = false;
+ for (int i = 0; !found && i < actual.length; i++) {
+ found |= expected[counter].equals(actual[i]);
+ }
+ assertTrue(message + " : didn't find element "
+ + expected[counter] + " in array match", found);
+ }
+
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/DeleteTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/DeleteTest.java
new file mode 100644
index 00000000..fb244213
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/DeleteTest.java
@@ -0,0 +1,112 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.BuildFileRule;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.fail;
+
+/**
+ */
+public class DeleteTest {
+
+ @Rule
+ public final BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/delete.xml");
+ }
+
+ @Test
+ public void test1() {
+ try {
+ buildRule.executeTarget("test1");
+ fail("required argument not specified");
+ } catch (BuildException ex) {
+ //TODO assert value
+ }
+ }
+
+ @Test
+ public void test2() {
+ buildRule.executeTarget("test2");
+ }
+//where oh where has my test case 3 gone?
+ @Test
+ public void test4() {
+ buildRule.executeTarget("test4");
+ }
+ @Test
+ public void test5() {
+ buildRule.executeTarget("test5");
+ }
+ @Test
+ public void test6() {
+ buildRule.executeTarget("test6");
+ }
+ @Test
+ public void test7() {
+ buildRule.executeTarget("test7");
+ }
+ @Test
+ public void test8() {
+ buildRule.executeTarget("test8");
+ }
+ @Test
+ public void test9() {
+ buildRule.executeTarget("test9");
+ }
+ @Test
+ public void test10() {
+ buildRule.executeTarget("test10");
+ }
+ @Test
+ public void test11() {
+ buildRule.executeTarget("test11");
+ }
+ @Test
+ public void test12() {
+ buildRule.executeTarget("test12");
+ }
+ @Test
+ public void test13() {
+ buildRule.executeTarget("test13");
+ }
+ @Test
+ public void test14() {
+ buildRule.executeTarget("test14");
+ }
+ @Test
+ public void test15() {
+ buildRule.executeTarget("test15");
+ }
+ @Test
+ public void test16() {
+ buildRule.executeTarget("test16");
+ }
+ @Test
+ public void test17() {
+ buildRule.executeTarget("test17");
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/DeltreeTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/DeltreeTest.java
new file mode 100644
index 00000000..b2dcc69e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/DeltreeTest.java
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.BuildFileRule;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.fail;
+
+public class DeltreeTest {
+
+ @Rule
+ public final BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/deltree.xml");
+ }
+
+ @Test
+ public void test1() {
+ try {
+ buildRule.executeTarget("test1");
+ fail("required argument not specified");
+ } catch (BuildException ex) {
+ //TODO assert value
+ }
+ }
+
+ @Test
+ public void test2() {
+ // We try to delete the directory created in CopydirTest
+ buildRule.executeTarget("test2");
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/DemuxOutputTask.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/DemuxOutputTask.java
new file mode 100644
index 00000000..e5e3b2f9
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/DemuxOutputTask.java
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs;
+
+import java.util.Random;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Task;
+
+/**
+ * A simple task that prints to System.out and System.err and then catches
+ * the output which it then checks. If the output does not match, an
+ * exception is thrown
+ *
+ * @since 1.5
+ * @created 21 February 2002
+ */
+public class DemuxOutputTask extends Task {
+ private String randomOutValue;
+ private String randomErrValue;
+ private boolean outputReceived = false;
+ private boolean errorReceived = false;
+
+ public void execute() {
+ Random generator = new Random();
+ randomOutValue = "Output Value is " + generator.nextInt();
+ randomErrValue = "Error Value is " + generator.nextInt();
+
+ System.out.println(randomOutValue);
+ System.err.println(randomErrValue);
+ if (!outputReceived) {
+ throw new BuildException("Did not receive output");
+ }
+
+ if (!errorReceived) {
+ throw new BuildException("Did not receive error");
+ }
+ }
+
+ protected void handleOutput(String line) {
+ line = line.trim();
+ if (line.length() != 0 && !line.equals(randomOutValue)) {
+ String message = "Received = [" + line + "], expected = ["
+ + randomOutValue + "]";
+ throw new BuildException(message);
+ }
+ outputReceived = true;
+ }
+
+ protected void handleErrorOutput(String line) {
+ line = line.trim();
+ if (line.length() != 0 && !line.equals(randomErrValue)) {
+ String message = "Received = [" + line + "], expected = ["
+ + randomErrValue + "]";
+ throw new BuildException(message);
+ }
+ errorReceived = true;
+ }
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/DirnameTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/DirnameTest.java
new file mode 100644
index 00000000..96c6c4a1
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/DirnameTest.java
@@ -0,0 +1,92 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.BuildFileRule;
+import org.apache.tools.ant.taskdefs.condition.Os;
+import org.junit.Assume;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+/**
+ */
+public class DirnameTest {
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/dirname.xml");
+ }
+
+ @Test
+ public void test1() {
+ try {
+ buildRule.executeTarget("test1");
+ fail("Build exception should have been thrown as property attribute is required");
+ } catch(BuildException ex) {
+ assertEquals("property attribute required", ex.getMessage());
+ }
+ }
+
+ @Test
+ public void test2() {
+ try {
+ buildRule.executeTarget("test2");
+ fail("Build exception should have been thrown as file attribute is required");
+ } catch(BuildException ex) {
+ assertEquals("file attribute required", ex.getMessage());
+ }
+ }
+
+ @Test
+ public void test3() {
+ try {
+ buildRule.executeTarget("test3");
+ fail("Build exception should have been thrown as property attribute is required");
+ } catch(BuildException ex) {
+ assertEquals("property attribute required", ex.getMessage());
+ }
+ }
+
+ @Test
+ public void test4() {
+ Assume.assumeFalse("Test not possible on DOS or Netware family OS", Os.isFamily("netware") || Os.isFamily("dos"));
+ buildRule.executeTarget("test4");
+ String filesep = System.getProperty("file.separator");
+ String expected = filesep + "usr" + filesep + "local";
+ String checkprop = buildRule.getProject().getProperty("local.dir");
+ assertEquals("dirname failed", expected, checkprop);
+ }
+
+ @Test
+ public void test5() {
+ buildRule.executeTarget("test5");
+ String expected = buildRule.getProject().getProperty("basedir");
+ String checkprop = buildRule.getProject().getProperty("base.dir");
+ assertEquals("dirname failed", expected, checkprop);
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/DynamicTask.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/DynamicTask.java
new file mode 100644
index 00000000..0d4b6cda
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/DynamicTask.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.DynamicConfigurator;
+import org.apache.tools.ant.Task;
+
+public class DynamicTask extends Task implements DynamicConfigurator {
+
+ public void execute() {
+ }
+
+ public void setDynamicAttribute(String name, String value) {
+ getProject().setNewProperty(name, value);
+ }
+
+ public Object createDynamicElement(String name) {
+ return new Sub();
+ }
+
+ public class Sub implements DynamicConfigurator {
+ public void setDynamicAttribute(String name, String value) {
+ getProject().setNewProperty(name, value);
+ }
+
+ public Object createDynamicElement(String name) {
+ return null;
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/DynamicTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/DynamicTest.java
new file mode 100644
index 00000000..615dd903
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/DynamicTest.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.BuildFileRule;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class DynamicTest {
+
+ @Rule
+ public final BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/dynamictask.xml");
+ }
+
+ @Test
+ public void testSimple() {
+ buildRule.executeTarget("simple");
+ assertEquals("1", buildRule.getProject().getProperty("prop1"));
+ assertEquals("2", buildRule.getProject().getProperty("prop2"));
+ assertEquals("3", buildRule.getProject().getProperty("prop3"));
+ assertEquals("4", buildRule.getProject().getProperty("prop4"));
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/EchoTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/EchoTest.java
new file mode 100644
index 00000000..5c2ae28e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/EchoTest.java
@@ -0,0 +1,105 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.PrintStream;
+
+import org.apache.tools.ant.DefaultLogger;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.util.FileUtils;
+import org.junit.After;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * Test Java-dependent parts of the Echo task.
+ */
+public class EchoTest {
+
+ private File removeThis;
+
+ @Test
+ public void testLogBlankEcho() {
+ Project p = new Project();
+ p.init();
+ EchoTestLogger logger = new EchoTestLogger();
+ p.addBuildListener(logger);
+ Echo echo = new Echo();
+ echo.setProject(p);
+ echo.setTaskName("testLogBlankEcho");
+ echo.execute();
+ assertEquals("[testLogBlankEcho] ", logger.lastLoggedMessage );
+ }
+
+ @Test
+ public void testLogUTF8Echo() throws IOException {
+ Project p = new Project();
+ p.init();
+ EchoTestLogger logger = new EchoTestLogger();
+ p.addBuildListener(logger);
+ Echo echo = new Echo();
+ echo.setProject(p);
+ echo.setTaskName("testLogUTF8Echo");
+ echo.setMessage("\u00e4\u00a9");
+ removeThis = new File("abc.txt");
+ echo.setFile(removeThis);
+ echo.setEncoding("UTF-8");
+ echo.execute();
+ String x = FileUtils.readFully(new InputStreamReader(new FileInputStream(removeThis), "UTF-8" ));
+ assertEquals(x,"\u00e4\u00a9");
+ }
+
+ @After
+ public void tearDown() {
+ if (removeThis != null && removeThis.exists()) {
+ if (!removeThis.delete())
+ {
+ removeThis.deleteOnExit();
+ }
+ }
+ }
+
+ private class EchoTestLogger extends DefaultLogger {
+ String lastLoggedMessage;
+
+ /**
+ * Create a new EchoTestLogger.
+ */
+ public EchoTestLogger() {
+ super();
+ this.setMessageOutputLevel(Project.MSG_DEBUG);
+ this.setOutputPrintStream(new PrintStream(new ByteArrayOutputStream(256)));
+ this.setErrorPrintStream(new PrintStream(new ByteArrayOutputStream(256)));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected void log(String message) {
+ this.lastLoggedMessage = message;
+ }
+
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/EchoXMLTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/EchoXMLTest.java
new file mode 100644
index 00000000..cc9ec24e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/EchoXMLTest.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.BuildFileRule;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.apache.tools.ant.AntAssert.assertContains;
+import static org.junit.Assert.fail;
+
+public class EchoXMLTest {
+
+ @Rule
+ public final BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/echoxml.xml");
+ }
+
+ @After
+ public void tearDown() {
+ buildRule.executeTarget("tearDown");
+ }
+
+ @Test
+ public void testPass() {
+ buildRule.executeTarget("testPass");
+ }
+
+ @Test
+ public void testFail() {
+ try {
+ buildRule.executeTarget("testFail");
+ fail("BuildException expected: must fail");
+ } catch (BuildException ex) {
+ assertContains("${foo}=bar", ex.getMessage());
+ }
+ }
+
+ @Test
+ public void testEmpty() {
+ try {
+ buildRule.executeTarget("testEmpty");
+ fail("BuildException expected: must fail");
+ } catch (BuildException ex) {
+ assertContains("No nested XML specified", ex.getMessage());
+ }
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/ExecTaskTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/ExecTaskTest.java
new file mode 100644
index 00000000..b7427606
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/ExecTaskTest.java
@@ -0,0 +1,192 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.util.GregorianCalendar;
+
+import org.apache.tools.ant.BuildEvent;
+import org.apache.tools.ant.BuildFileRule;
+import org.apache.tools.ant.BuildListener;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.ProjectHelper;
+import org.apache.tools.ant.util.FileUtils;
+import org.junit.Assume;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Rule;
+import org.junit.Test;
+
+/**
+ * Unit test for the &lt;exec&gt; task.
+ */
+public class ExecTaskTest {
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ private static final String BUILD_PATH = "src/etc/testcases/taskdefs/exec/";
+ private static final String BUILD_FILE = BUILD_PATH + "exec.xml";
+ private static final int TIME_TO_WAIT = 1;
+ /** maximum time allowed for the build in milliseconds */
+ private static final int MAX_BUILD_TIME = 6000;
+ private static final int SECURITY_MARGIN = 4000; // wait 4 second extras
+ // the test failed with 100 ms of margin on cvs.apache.org on August 1st, 2003
+ // the test randomly failed with 3 s of margin on Windows Jenkins slaves on during July 2014
+
+ /** Utilities used for file operations */
+ private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+
+ private File logFile;
+ private MonitoredBuild myBuild = null;
+ volatile private boolean buildFinished = false;
+
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject(BUILD_FILE);
+ }
+
+ @Test
+ public void testspawn() throws InterruptedException {
+ buildRule.getProject().executeTarget("setUp");
+ Assume.assumeNotNull(buildRule.getProject().getProperty("test.can.run"));
+ myBuild = new MonitoredBuild(new File(System.getProperty("root"), BUILD_FILE), "spawn");
+ logFile = FILE_UTILS.createTempFile("spawn", "log", new File(buildRule.getProject().getProperty("output")),
+ false, false);
+ // this is guaranteed by FileUtils#createTempFile
+ assertTrue("log file not existing", !logFile.exists());
+ // make the spawned process run 1 seconds
+ myBuild.setTimeToWait(TIME_TO_WAIT);
+ myBuild.setLogFile(logFile.getAbsolutePath());
+ myBuild.addBuildListener(new MonitoredBuildListener());
+ myBuild.start();
+ GregorianCalendar startwait = new GregorianCalendar();
+ // this loop runs parallel to the build
+ while (!buildFinished) {
+ Thread.sleep(10);
+ GregorianCalendar now = new GregorianCalendar();
+ // security
+ if (now.getTime().getTime() - startwait.getTime().getTime() > MAX_BUILD_TIME) {
+ System.out.println("aborting wait, too long "
+ + (now.getTime().getTime() - startwait.getTime().getTime())
+ + "milliseconds");
+ break;
+ }
+ }
+ // now wait until the spawned process is finished
+ Thread.sleep((TIME_TO_WAIT) * 1000 + SECURITY_MARGIN);
+ // time of the build in milli seconds
+ long elapsed = myBuild.getTimeElapsed();
+ assertTrue("we waited more than the process lasted",
+ TIME_TO_WAIT * 1000 + SECURITY_MARGIN > elapsed);
+ logFile = new File(logFile.getAbsolutePath());
+ assertTrue("log file found after spawn", logFile.exists());
+ }
+
+ @Test
+ @Ignore("#50507 - fails at least on Linux")
+ /* TODO #50507 - fails at least on Linux */
+ public void testOutAndErr() {
+ buildRule.getProject().executeTarget("test-out-and-err");
+ }
+
+ private static class MonitoredBuild implements Runnable {
+ private Thread worker;
+ private File myBuildFile = null;
+ private String target = null;
+ private Project project = null;
+ private GregorianCalendar timeStarted = null;
+ private GregorianCalendar timeFinished = null;
+
+ public void setLogFile(String logFile) {
+ project.setProperty("logFile", logFile);
+ }
+
+ public void setTimeToWait(int timeToWait) {
+ project.setProperty("timeToWait", Long.toString(timeToWait));
+ }
+
+ public void addBuildListener(BuildListener bl) {
+ project.addBuildListener(bl);
+ }
+
+ public MonitoredBuild(File buildFile, String target) {
+ myBuildFile = buildFile;
+ this.target = target;
+ project = new Project();
+ project = new Project();
+ project.init();
+ project.setUserProperty("ant.file", myBuildFile.getAbsolutePath());
+ ProjectHelper.configureProject(project, myBuildFile);
+ }
+
+ /**
+ *
+ * @return time in millis of the build
+ */
+ public long getTimeElapsed() {
+ return timeFinished.getTime().getTime() - timeStarted.getTime().getTime();
+ }
+
+ public void start() {
+ worker = new Thread(this, myBuildFile.toString() + "/" + target);
+ worker.start();
+ }
+
+ public void run() {
+ startProject();
+ }
+
+ private void startProject() {
+ timeStarted = new GregorianCalendar();
+ project.executeTarget(target);
+ timeFinished = new GregorianCalendar();
+ }
+ }
+
+ private class MonitoredBuildListener implements BuildListener {
+ public void buildStarted(BuildEvent event) {
+ }
+
+ public void buildFinished(BuildEvent event) {
+ }
+
+ public void targetStarted(BuildEvent event) {
+ }
+
+ public void targetFinished(BuildEvent event) {
+ if (event.getTarget().getName().equals("spawn")) {
+ buildFinished = true;
+ }
+ }
+
+ public void taskStarted(BuildEvent event) {
+ }
+
+ public void taskFinished(BuildEvent event) {
+ }
+
+ public void messageLogged(BuildEvent event) {
+ }
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/ExecuteJavaTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/ExecuteJavaTest.java
new file mode 100644
index 00000000..069645b3
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/ExecuteJavaTest.java
@@ -0,0 +1,131 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.MagicNames;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.types.Commandline;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Simple testcase for the ExecuteJava class - mostly stolen from
+ * ExecuteWatchdogTest.
+ *
+ */
+public class ExecuteJavaTest {
+
+ private final static int TIME_OUT = 5000;
+
+ private final static int CLOCK_ERROR=200;
+ private final static int TIME_OUT_TEST=TIME_OUT-CLOCK_ERROR;
+
+ private ExecuteJava ej;
+ private Project project;
+ private Path cp;
+
+ @Before
+ public void setUp(){
+ ej = new ExecuteJava();
+ ej.setTimeout((long)TIME_OUT);
+ project = new Project();
+ project.setBasedir(".");
+ project.setProperty(MagicNames.ANT_HOME, System.getProperty(MagicNames.ANT_HOME));
+ cp = new Path(project, getTestClassPath());
+ ej.setClasspath(cp);
+ }
+
+ private Commandline getCommandline(int timetorun) throws Exception {
+ Commandline cmd = new Commandline();
+ cmd.setExecutable(TimeProcess.class.getName());
+ cmd.createArgument().setValue(String.valueOf(timetorun));
+ return cmd;
+ }
+
+ @Test
+ public void testNoTimeOut() throws Exception {
+ Commandline cmd = getCommandline(TIME_OUT/2);
+ ej.setJavaCommand(cmd);
+ ej.execute(project);
+ assertTrue("process should not have been killed", !ej.killedProcess());
+ }
+
+ // test that the watchdog ends the process
+ @Test
+ public void testTimeOut() throws Exception {
+ Commandline cmd = getCommandline(TIME_OUT*2);
+ ej.setJavaCommand(cmd);
+ long now = System.currentTimeMillis();
+ ej.execute(project);
+ long elapsed = System.currentTimeMillis() - now;
+ assertTrue("process should have been killed", ej.killedProcess());
+
+ assertTrue("elapse time of "+elapsed
+ +" ms is less than timeout value of "+TIME_OUT_TEST+" ms",
+ elapsed >= TIME_OUT_TEST);
+ assertTrue("elapse time of "+elapsed
+ +" ms is greater than run value of "+(TIME_OUT*2)+" ms",
+ elapsed < TIME_OUT*2);
+ }
+
+ @Test
+ public void testNoTimeOutForked() throws Exception {
+ Commandline cmd = getCommandline(TIME_OUT/2);
+ ej.setJavaCommand(cmd);
+ ej.fork(cp);
+ assertTrue("process should not have been killed", !ej.killedProcess());
+ }
+
+ // test that the watchdog ends the process
+ @Test
+ public void testTimeOutForked() throws Exception {
+ Commandline cmd = getCommandline(TIME_OUT*2);
+ ej.setJavaCommand(cmd);
+ long now = System.currentTimeMillis();
+ ej.fork(cp);
+ long elapsed = System.currentTimeMillis() - now;
+ assertTrue("process should have been killed", ej.killedProcess());
+
+ assertTrue("elapse time of "+elapsed
+ +" ms is less than timeout value of "+TIME_OUT_TEST+" ms",
+ elapsed >= TIME_OUT_TEST);
+ assertTrue("elapse time of "+elapsed
+ +" ms is greater than run value of "+(TIME_OUT*2)+" ms",
+ elapsed < TIME_OUT*2);
+ }
+
+ /**
+ * Dangerous method to obtain the classpath for the test. This is
+ * severely tighted to the build.xml properties.
+ */
+ private static String getTestClassPath(){
+ String classpath = System.getProperty("build.tests");
+ if (classpath == null) {
+ System.err.println("WARNING: 'build.tests' property is not available !");
+ classpath = System.getProperty("java.class.path");
+ }
+
+ return classpath;
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/ExecuteWatchdogTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/ExecuteWatchdogTest.java
new file mode 100644
index 00000000..1834d5e3
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/ExecuteWatchdogTest.java
@@ -0,0 +1,162 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+
+import org.apache.tools.ant.util.JavaEnvUtils;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.internal.AssumptionViolatedException;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Simple testcase for the ExecuteWatchdog class.
+ *
+ */
+public class ExecuteWatchdogTest {
+
+ private final static long TIME_OUT = 5000;
+
+ private final static String TEST_CLASSPATH = getTestClassPath();
+
+ private final static int CLOCK_ERROR=200;
+ private final static long TIME_OUT_TEST=TIME_OUT-CLOCK_ERROR;
+
+ private ExecuteWatchdog watchdog;
+
+ @Before
+ public void setUp(){
+ watchdog = new ExecuteWatchdog(TIME_OUT);
+ }
+
+ /**
+ * Dangerous method to obtain the classpath for the test. This is
+ * severely tied to the build.xml properties.
+ */
+ private static String getTestClassPath(){
+ String classpath = System.getProperty("build.tests");
+ if (classpath == null) {
+ System.err.println("WARNING: 'build.tests' property is not available !");
+ classpath = System.getProperty("java.class.path");
+ }
+
+ return classpath;
+ }
+
+ private Process getProcess(long timetorun) throws Exception {
+ String[] cmdArray = {
+ JavaEnvUtils.getJreExecutable("java"), "-classpath", TEST_CLASSPATH,
+ TimeProcess.class.getName(), String.valueOf(timetorun)
+ };
+ //System.out.println("Testing with classpath: " + System.getProperty("java.class.path"));
+ return Runtime.getRuntime().exec(cmdArray);
+ }
+
+ private String getErrorOutput(Process p) throws Exception {
+ BufferedReader err = new BufferedReader( new InputStreamReader(p.getErrorStream()) );
+ StringBuffer buf = new StringBuffer();
+ String line;
+ while ( (line = err.readLine()) != null){
+ buf.append(line);
+ }
+ return buf.toString();
+ }
+
+ private int waitForEnd(Process p) throws Exception {
+ int retcode = p.waitFor();
+ if (retcode != 0){
+ String err = getErrorOutput(p);
+ if (err.length() > 0){
+ System.err.println("ERROR:");
+ System.err.println(err);
+ }
+ }
+ return retcode;
+ }
+
+ @Test
+ public void testNoTimeOut() throws Exception {
+ Process process = getProcess(TIME_OUT/2);
+ watchdog.start(process);
+ int retCode = waitForEnd(process);
+ assertTrue("process should not have been killed", !watchdog.killedProcess());
+ assertFalse(Execute.isFailure(retCode));
+ }
+
+ // test that the watchdog ends the process
+ @Test
+ public void testTimeOut() throws Exception {
+ Process process = getProcess(TIME_OUT*2);
+ long now = System.currentTimeMillis();
+ watchdog.start(process);
+ int retCode = process.waitFor();
+ long elapsed = System.currentTimeMillis() - now;
+ assertTrue("process should have been killed", watchdog.killedProcess());
+ // assertTrue("return code is invalid: " + retCode, retCode!=0);
+ assertTrue("elapse time of "+elapsed+" ms is less than timeout value of "+TIME_OUT_TEST+" ms", elapsed >= TIME_OUT_TEST);
+ assertTrue("elapse time of "+elapsed+" ms is greater than run value of "+(TIME_OUT*2)+" ms", elapsed < TIME_OUT*2);
+ }
+
+ // test a process that runs and failed
+ @Test
+ public void testFailed() throws Exception {
+ Process process = getProcess(-1); // process should abort
+ watchdog.start(process);
+ int retCode = process.waitFor();
+ assertTrue("process should not have been killed", !watchdog.killedProcess());
+ assertTrue("return code is invalid: " + retCode, retCode!=0);
+ }
+
+ @Test
+ public void testManualStop() throws Exception {
+ final Process process = getProcess(TIME_OUT*2);
+ watchdog.start(process);
+
+ // I assume that starting this takes less than TIME_OUT/2 ms...
+ Thread thread = new Thread(){
+ public void run(){
+ try {
+ process.waitFor();
+ } catch(InterruptedException e){
+ // not very nice but will do the job
+ throw new AssumptionViolatedException("process interrupted in thread", e);
+ }
+ }
+ };
+ thread.start();
+
+ // wait for TIME_OUT/2, there should be about TIME_OUT/2 ms remaining before timeout
+ thread.join(TIME_OUT/2);
+
+ // now stop the watchdog.
+ watchdog.stop();
+
+ // wait for the thread to die, should be the end of the process
+ thread.join();
+
+ // process should be dead and well finished
+ assertEquals(0, process.exitValue());
+ assertTrue("process should not have been killed", !watchdog.killedProcess());
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/FailTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/FailTest.java
new file mode 100644
index 00000000..8883558d
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/FailTest.java
@@ -0,0 +1,210 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.BuildFileRule;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+/**
+ */
+public class FailTest {
+
+ @Rule
+ public final BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/fail.xml");
+ }
+
+ @Test
+ public void test1() {
+ try {
+ buildRule.executeTarget("test1");
+ fail("it is required to fail :-)") ;
+ } catch (BuildException ex) {
+ assertEquals("No message", ex.getMessage());
+ }
+ }
+
+ @Test
+ public void test2() {
+ try {
+ buildRule.executeTarget("test2");
+ fail("it is required to fail :-)") ;
+ } catch (BuildException ex) {
+ assertEquals("test2", ex.getMessage());
+ }
+ }
+
+ @Test
+ public void testText() {
+ try {
+ buildRule.executeTarget("testText");
+ fail("it is required to fail :-)") ;
+ } catch (BuildException ex) {
+ assertEquals("testText", ex.getMessage());
+ }
+ }
+
+ @Test
+ public void testIf() {
+ buildRule.executeTarget("testIf");
+ buildRule.getProject().setProperty("foo", "");
+ try {
+ buildRule.executeTarget("testIf");
+ fail("testIf must fail if foo has been set") ;
+ } catch (BuildException ex) {
+ //TODO assert result
+ }
+ }
+
+ @Test
+ public void testUnless() {
+ try {
+ buildRule.executeTarget("testUnless");
+ fail("testUnless must fail unless foo has been set") ;
+ } catch (BuildException ex) {
+ //TODO assert rules
+ }
+ buildRule.getProject().setProperty("foo", "");
+ buildRule.executeTarget("testUnless");
+
+ }
+
+ /**
+ * see that the different combinations work, and
+ * that the autogenerated text contains information
+ * about which condition was not met
+ */
+ @Test
+ public void testIfAndUnless() {
+ //neither
+ buildRule.executeTarget("testIfAndUnless");
+ buildRule.getProject().setProperty("if", "");
+ try {
+ buildRule.executeTarget("testIfAndUnless");
+ fail("expect fail on defined(if)") ;
+ } catch (BuildException ex) {
+ assertEquals("if=if and unless=unless", ex.getMessage());
+ }
+ buildRule.getProject().setProperty("unless", "");
+ //this call should succeed as unless overrides if
+ buildRule.executeTarget("testIfAndUnless");
+ }
+ /**
+ * see that the different combinations work, and
+ * that the autogenerated text contains information
+ * about which condition was not met
+ */
+ @Test
+ public void testIfAndUnless2() {
+ buildRule.getProject().setProperty("unless", "");
+ buildRule.executeTarget("testIfAndUnless");
+ }
+
+ @Test
+ public void testNested1() {
+ try {
+ buildRule.executeTarget("testNested1");
+ fail("it is required to fail :-)") ;
+ } catch (BuildException ex) {
+ assertEquals("condition satisfied", ex.getMessage());
+ }
+ }
+
+ @Test
+ public void testNested2() {
+ buildRule.executeTarget("testNested2");
+ }
+
+ @Test
+ public void testNested3() {
+ try {
+ buildRule.executeTarget("testNested3");
+ fail("it is required to fail :-)") ;
+ } catch (BuildException ex) {
+ assertEquals("testNested3", ex.getMessage());
+ }
+ }
+
+ @Test
+ public void testNested4() {
+ String specificMessage = "Nested conditions "
+ + "not permitted in conjunction with if/unless attributes";
+
+ char[] c = {'a', 'b', 'c'};
+ StringBuffer target = new StringBuffer("testNested4x");
+
+ for (int i = 0; i < c.length; i++) {
+ target.setCharAt(target.length() - 1, c[i]);
+ try {
+ buildRule.executeTarget(target.toString());
+ fail("it is required to fail :-)") ;
+ } catch (BuildException ex) {
+ assertEquals(specificMessage, ex.getMessage());
+ }
+ }
+ }
+
+ @Test
+ public void testNested5() {
+ try {
+ buildRule.executeTarget("testNested5");
+ fail("it is required to fail :-)") ;
+ } catch (BuildException ex) {
+ assertEquals("Only one nested condition is allowed.", ex.getMessage());
+ }
+ }
+
+ @Test
+ public void testNested6() {
+ try {
+ buildRule.executeTarget("testNested6");
+ fail("it is required to fail :-)") ;
+ } catch (BuildException ex) {
+ assertEquals("testNested6\ntestNested6\ntestNested6", ex.getMessage());
+ }
+ }
+
+ @Test
+ public void testNested7() {
+ String specificMessage = "A single nested condition is required.";
+
+ char[] c = {'a', 'b'};
+ StringBuffer target = new StringBuffer("testNested7x");
+
+ for (int i = 0; i < c.length; i++) {
+ target.setCharAt(target.length() - 1, c[i]);
+ try {
+ buildRule.executeTarget(target.toString());
+ fail("it is required to fail :-)") ;
+ } catch (BuildException ex) {
+ assertEquals(specificMessage, ex.getMessage());
+ }
+ }
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/FilterTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/FilterTest.java
new file mode 100644
index 00000000..fdbec6e8
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/FilterTest.java
@@ -0,0 +1,147 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.BuildFileRule;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+
+public class FilterTest {
+
+ @Rule
+ public final BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/filter.xml");
+ }
+
+ @After
+ public void tearDown() {
+ buildRule.executeTarget("cleanup");
+ }
+
+ @Test
+ public void test1() {
+ try {
+ buildRule.executeTarget("test1");
+ fail("required argument missing");
+ } catch (BuildException ex) {
+ //TODO assert value
+ }
+ }
+
+ @Test
+ public void test2() {
+ try {
+ buildRule.executeTarget("test2");
+ fail("required argument missing");
+ } catch (BuildException ex) {
+ //TODO assert value
+ }
+ }
+
+ @Test
+ public void test3() {
+ try {
+ buildRule.executeTarget("test3");
+ fail("required argument missing");
+ } catch (BuildException ex) {
+ //TODO assert value
+ }
+ }
+
+ @Test
+ public void test4() {
+ buildRule.executeTarget("test4");
+ }
+
+ @Test
+ public void test5() {
+ buildRule.executeTarget("test5");
+ assertEquals("2000",
+ getFilteredFile("5", "filtered.tmp"));
+ }
+
+
+ @Test
+ public void test6() {
+ buildRule.executeTarget("test6");
+ assertEquals("2000",
+ getFilteredFile("6", "taskdefs.tmp/filter1.txt"));
+ }
+
+ @Test
+ public void test7() {
+ buildRule.executeTarget("test7");
+ assertEquals("<%@ include file=\"root/some/include.jsp\"%>",
+ getFilteredFile("7", "filtered.tmp"));
+ }
+
+ @Test
+ public void test8() {
+ buildRule.executeTarget("test8");
+ assertEquals("<%@ include file=\"root/some/include.jsp\"%>",
+ getFilteredFile("8", "taskdefs.tmp/filter2.txt"));
+ }
+
+ @Test
+ public void test9() {
+ buildRule.executeTarget("test9");
+ assertEquals("included",
+ getFilteredFile("9", "taskdefs.tmp/filter3.txt"));
+ }
+
+ private String getFilteredFile(String testNumber, String filteredFile) {
+
+ String line = null;
+ File f = new File(buildRule.getProject().getBaseDir(), filteredFile);
+ if (!f.exists()) {
+ fail("filter test"+testNumber+" failed");
+ } else {
+ BufferedReader in = null;
+ try {
+ in = new BufferedReader(new FileReader(f));
+ } catch (FileNotFoundException fnfe) {
+ fail("filter test"+testNumber+" failed, filtered file: " + f.toString() + " not found");
+ }
+ try {
+ line = in.readLine();
+ in.close();
+ } catch (IOException ioe) {
+ fail("filter test"+testNumber+" failed. IOException while reading filtered file: " + ioe);
+ }
+ }
+ f.delete();
+ return line;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/FixCrLfTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/FixCrLfTest.java
new file mode 100644
index 00000000..06a18cc8
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/FixCrLfTest.java
@@ -0,0 +1,262 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import junit.framework.AssertionFailedError;
+
+import org.apache.tools.ant.AntAssert;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.BuildFileRule;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+/**
+ */
+public class FixCrLfTest {
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/fixcrlf/build.xml");
+ }
+
+ @Test
+ public void test1() throws IOException {
+ buildRule.executeTarget("test1");
+ }
+
+ @Test
+ public void test2() throws IOException {
+ buildRule.executeTarget("test2");
+ }
+
+ @Test
+ public void test3() throws IOException {
+ buildRule.executeTarget("test3");
+ }
+
+ @Test
+ public void test4() throws IOException {
+ buildRule.executeTarget("test4");
+ }
+
+ @Test
+ public void test5() throws IOException {
+ buildRule.executeTarget("test5");
+ }
+
+ @Test
+ public void test6() throws IOException {
+ buildRule.executeTarget("test6");
+ }
+
+ @Test
+ public void test7() throws IOException {
+ buildRule.executeTarget("test7");
+ }
+
+ @Test
+ public void test8() throws IOException {
+ buildRule.executeTarget("test8");
+ }
+
+ @Test
+ public void test9() throws IOException {
+ buildRule.executeTarget("test9");
+ }
+
+ @Test
+ public void testMacLines() throws IOException {
+ buildRule.executeTarget("testMacLines");
+ }
+
+ @Test
+ public void testNoOverwrite() throws IOException {
+ buildRule.executeTarget("testNoOverwrite");
+ }
+
+ @Test
+ public void testEncoding() throws IOException {
+ buildRule.executeTarget("testEncoding");
+ }
+
+ @Test
+ public void testOutputEncoding() throws IOException {
+ buildRule.executeTarget("testOutputEncoding");
+ }
+
+ @Test
+ public void testLongLines() throws IOException {
+ buildRule.executeTarget("testLongLines");
+ }
+
+ @Test
+ public void testCrCrLfSequenceUnix() throws IOException {
+ buildRule.executeTarget("testCrCrLfSequence-unix");
+ }
+
+ @Test
+ public void testCrCrLfSequenceDos() throws IOException {
+ buildRule.executeTarget("testCrCrLfSequence-dos");
+ }
+
+ @Test
+ public void testCrCrLfSequenceMac() throws IOException {
+ buildRule.executeTarget("testCrCrLfSequence-mac");
+ }
+
+ @Test
+ public void testFixlastDos() throws IOException {
+ buildRule.executeTarget("testFixlastDos");
+ }
+
+ @Test
+ public void testFixlastFalseMac() throws IOException {
+ buildRule.executeTarget("testFixlastFalseMac");
+ }
+
+ @Test
+ public void testFixFile() throws Exception {
+ buildRule.executeTarget("testFixFile");
+ }
+
+ @Test
+ public void testFixFileExclusive() throws Exception {
+ try {
+ buildRule.executeTarget("testFixFileExclusive");
+ fail(FixCRLF.ERROR_FILE_AND_SRCDIR);
+ } catch (BuildException ex) {
+ AntAssert.assertContains(FixCRLF.ERROR_FILE_AND_SRCDIR, ex.getMessage());
+ }
+ }
+
+ /**
+ * Bugzilla Report 20840
+ *
+ * Will fail with an exception if the parent directories do not
+ * get created.
+ */
+ @Test
+ public void testCreateParentDirs() {
+ buildRule.executeTarget("createParentDirs");
+ }
+
+ @Test
+ public void testPreserveLastModified() {
+ buildRule.executeTarget("testPreserveLastModified");
+ }
+
+ @Test
+ public void testFilter1() {
+ buildRule.executeTarget("testFilter1");
+ }
+
+ @Test
+ public void testFilter2() {
+ buildRule.executeTarget("testFilter2");
+ }
+
+ @Test
+ public void testFilter3() {
+ buildRule.executeTarget("testFilter3");
+ }
+
+ @Test
+ public void testFilter4() {
+ buildRule.executeTarget("testFilter4");
+ }
+
+ @Test
+ public void testFilter5() {
+ buildRule.executeTarget("testFilter5");
+ }
+
+ @Test
+ public void testFilter6() {
+ buildRule.executeTarget("testFilter6");
+ }
+
+ @Test
+ public void testFilter7() {
+ buildRule.executeTarget("testFilter7");
+ }
+
+ @Test
+ public void testFilter8() {
+ buildRule.executeTarget("testFilter8");
+ }
+
+ @Test
+ public void testFilter9() {
+ buildRule.executeTarget("testFilter9");
+ }
+
+ @Test
+ public void testCannotDoubleEof() {
+ buildRule.executeTarget("testCannotDoubleEof");
+ }
+
+ @Test
+ public void testTabInLiteralInComment() {
+ buildRule.executeTarget("testTabInLiteralInComment");
+ }
+
+ // not used, but public so theoretically must remain for BC?
+ @Deprecated
+ public void assertEqualContent(File expect, File result)
+ throws AssertionFailedError, IOException {
+ if (!result.exists()) {
+ fail("Expected file "+result+" doesn\'t exist");
+ }
+
+ InputStream inExpect = null;
+ InputStream inResult = null;
+ try {
+ inExpect = new BufferedInputStream(new FileInputStream(expect));
+ inResult = new BufferedInputStream(new FileInputStream(result));
+
+ int expectedByte = inExpect.read();
+ while (expectedByte != -1) {
+ assertEquals(expectedByte, inResult.read());
+ expectedByte = inExpect.read();
+ }
+ assertEquals("End of file", -1, inResult.read());
+ } finally {
+ if (inResult != null) {
+ inResult.close();
+ }
+ if (inExpect != null) {
+ inExpect.close();
+ }
+ }
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/GUnzipTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/GUnzipTest.java
new file mode 100644
index 00000000..fc731f75
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/GUnzipTest.java
@@ -0,0 +1,91 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.BuildFileRule;
+import org.apache.tools.ant.FileUtilities;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+public class GUnzipTest {
+
+ @Rule
+ public final BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/gunzip.xml");
+ }
+
+ @After
+ public void tearDown() {
+ buildRule.executeTarget("cleanup");
+ }
+
+ @Test
+ public void test1() {
+ try {
+ buildRule.executeTarget("test1");
+ fail("required argument missing");
+ } catch (BuildException ex) {
+ //TODO assert value
+ }
+ }
+
+ @Test
+ public void test2() {
+ try {
+ buildRule.executeTarget("test2");
+ fail("attribute src invalid");
+ } catch (BuildException ex) {
+ //TODO assert value
+ }
+ }
+
+ @Test
+ public void testRealTest() throws java.io.IOException {
+ testRealTest("realTest");
+ }
+
+ @Test
+ public void testRealTestWithResource() throws java.io.IOException {
+ testRealTest("realTestWithResource");
+ }
+
+ private void testRealTest(String target) throws java.io.IOException {
+ buildRule.executeTarget(target);
+ assertEquals(FileUtilities.getFileContents(buildRule.getProject().resolveFile("../asf-logo.gif")),
+ FileUtilities.getFileContents(buildRule.getProject().resolveFile("asf-logo.gif")));
+ }
+
+ @Test
+ public void testTestGzipTask() throws java.io.IOException {
+ testRealTest("testGzipTask");
+ }
+
+ @Test
+ public void testDocumentationClaimsOnCopy() throws java.io.IOException {
+ testRealTest("testDocumentationClaimsOnCopy");
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/GetTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/GetTest.java
new file mode 100644
index 00000000..3e1157d8
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/GetTest.java
@@ -0,0 +1,122 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.BuildFileRule;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.fail;
+
+/**
+ */
+public class GetTest {
+
+ @Rule
+ public final BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/get.xml");
+ }
+
+ @After
+ public void tearDown() {
+ buildRule.executeTarget("cleanup");
+ }
+
+ @Test
+ public void test1() {
+ try {
+ buildRule.executeTarget("test1");
+ fail("required argument missing");
+ } catch (BuildException ex) {
+ //TODO assert value
+ }
+ }
+
+ @Test
+ public void test2() {
+ try {
+ buildRule.executeTarget("test2");
+ fail("required argument missing");
+ } catch (BuildException ex) {
+ //TODO assert value
+ }
+ }
+
+ @Test
+ public void test3() {
+ try {
+ buildRule.executeTarget("test3");
+ fail("required argument missing");
+ } catch (BuildException ex) {
+ //TODO assert value
+ }
+ }
+
+ @Test
+ public void test4() {
+ try {
+ buildRule.executeTarget("test4");
+ fail("src invalid");
+ } catch (BuildException ex) {
+ //TODO assert value
+ }
+ }
+
+ @Test
+ public void test5() {
+ try {
+ buildRule.executeTarget("test5");
+ fail("dest invalid (or no http-server on local machine");
+ } catch (BuildException ex) {
+ //TODO assert value
+ }
+ }
+
+ @Test
+ public void test6() {
+ buildRule.executeTarget("test6");
+ }
+
+ @Test
+ public void test7() {
+ try {
+ buildRule.executeTarget("test7");
+ fail("userAgent may not be null or empty");
+ } catch (BuildException ex) {
+ //TODO assert value
+ }
+ }
+
+ @Test
+ public void testUseTimestamp() {
+ buildRule.executeTarget("testUseTimestamp");
+ }
+
+ @Test
+ public void testUseTomorrow() {
+ buildRule.executeTarget("testUseTomorrow");
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/GzipTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/GzipTest.java
new file mode 100644
index 00000000..00ea0638
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/GzipTest.java
@@ -0,0 +1,113 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.BuildFileRule;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+/**
+ */
+public class GzipTest {
+
+ @Rule
+ public final BuildFileRule buildRule = new BuildFileRule();
+
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/gzip.xml");
+ }
+
+ @Test
+ public void test1() {
+ try {
+ buildRule.executeTarget("test1");
+ fail("BuildException expected: required argument missing");
+ } catch (BuildException ex) {
+ //TODO assert value
+ }
+ }
+
+ @Test
+ public void test2() {
+ try {
+ buildRule.executeTarget("test2");
+ fail("BuildException expected: required argument missing");
+ } catch (BuildException ex) {
+ //TODO assert value
+ }
+ }
+
+ @Test
+ public void test3() {
+ try {
+ buildRule.executeTarget("test3");
+ fail("BuildException expected: required argument missing");
+ } catch (BuildException ex) {
+ //TODO assert value
+ }
+ }
+
+ @Test
+ public void test4() {
+ try {
+ buildRule.executeTarget("test4");
+ fail("BuildException expected: zipfile must not point to a directory");
+ } catch (BuildException ex) {
+ //TODO assert value
+ }
+ }
+
+ @Test
+ public void testGZip(){
+ buildRule.executeTarget("realTest");
+ String log = buildRule.getLog();
+ assertTrue("Expecting message starting with 'Building:' but got '"
+ + log + "'", log.startsWith("Building:"));
+ assertTrue("Expecting message ending with 'asf-logo.gif.gz' but got '"
+ + log + "'", log.endsWith("asf-logo.gif.gz"));
+ }
+
+ @Test
+ public void testResource(){
+ buildRule.executeTarget("realTestWithResource");
+ }
+
+ @Test
+ public void testDateCheck(){
+ buildRule.executeTarget("testDateCheck");
+ String log = buildRule.getLog();
+ assertTrue(
+ "Expecting message ending with 'asf-logo.gif.gz is up to date.' but got '" + log + "'",
+ log.endsWith("asf-logo.gif.gz is up to date."));
+ }
+
+ @After
+ public void tearDown(){
+ buildRule.executeTarget("cleanup");
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/ImportTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/ImportTest.java
new file mode 100644
index 00000000..e64d6f8c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/ImportTest.java
@@ -0,0 +1,174 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import static org.apache.tools.ant.AntAssert.assertContains;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.BuildFileRule;
+import org.apache.tools.ant.Location;
+import org.apache.tools.ant.Project;
+import org.junit.Assume;
+import org.junit.Ignore;
+import org.junit.Rule;
+import org.junit.Test;
+
+public class ImportTest {
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ @Test
+ public void testSimpleImport() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/import/import.xml");
+ assertContains("Before importIn imported topAfter import", buildRule.getLog());
+ }
+
+ @Test
+ public void testUnnamedNesting() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/import/unnamedImport.xml",
+ Project.MSG_WARN);
+ String log = buildRule.getLog();
+ assertTrue("Warnings logged when not expected: " + log,
+ log.length() == 0);
+ }
+
+ @Test
+ public void testSerial() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/import/subdir/serial.xml");
+ assertContains("Unnamed2.xmlUnnamed1.xml", buildRule.getLog());
+ assertContains("Expected string was not found in log",
+ "Skipped already imported file", buildRule.getFullLog());
+ }
+
+ // allow this as imported in targets are only tested when a target is run
+ @Test
+ public void testImportInTargetNoEffect() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/import/subdir/importintarget.xml");
+ buildRule.executeTarget("no-import");
+ assertNull(buildRule.getProject().getProperty("foo"));
+ assertNull(buildRule.getProject().getReference("baz"));
+ }
+
+ @Ignore("deactivate this test as imports within targets are not allowed")
+ @Test
+ public void notTestImportInTargetWithEffect() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/import/subdir/importintarget.xml");
+ buildRule.executeTarget("do-import");
+ assertEquals(buildRule.getProject().getProperty("foo"), "bar");
+ assertNotNull(buildRule.getProject().getReference("baz"));
+ }
+
+ @Test
+ public void testImportInTargetNotAllowed() {
+ buildRule.configureProject(
+ "src/etc/testcases/taskdefs/import/subdir/importintarget.xml");
+ try {
+ buildRule.executeTarget("do-import");
+ fail("Build exception should have been thrown as import only allowed in top level task");
+ } catch(BuildException ex) {
+ assertContains( "not a top level task", "import only allowed as a top-level task", ex.getMessage());
+ }
+ }
+
+ @Test
+ public void testImportInSequential() {
+ buildRule.configureProject(
+ "src/etc/testcases/taskdefs/import/subdir/importinsequential.xml");
+ buildRule.executeTarget("within-imported");
+ assertEquals(buildRule.getProject().getProperty("foo"), "bar");
+ assertNotNull(buildRule.getProject().getReference("baz"));
+ }
+
+ @Test
+ public void testImportSameTargets() {
+ try {
+ buildRule.configureProject(
+ "src/etc/testcases/taskdefs/import/same_target.xml");
+ fail("Expected build exception");
+ } catch (BuildException ex) {
+ assertContains("Message did not contain expected contents", "Duplicate target", ex.getMessage());
+ }
+ }
+
+ @Test
+ public void testImportError() {
+ try {
+ buildRule.configureProject(
+ "src/etc/testcases/taskdefs/import/import_bad_import.xml");
+ fail("Build exception should have been thrown");
+ } catch (BuildException ex) {
+ Location lo = ex.getLocation();
+ assertNotNull(
+ "expected location of build exception to be set", lo);
+ assertContains(
+ "expected location to contain calling file", "import_bad_import.xml", lo.getFileName());
+ assertContains(
+ "expected message of ex to contain called file", "bad.xml", ex.getMessage());
+ }
+ }
+
+ @Test
+ public void testSymlinkedImports() throws Exception {
+ String ln = "/usr/bin/ln";
+ if (!new File(ln).exists()) {
+ ln = "/bin/ln";
+ }
+ Assume.assumeTrue("Current system does not support Symlinks", new File(ln).exists());
+ String symlink = "src/etc/testcases/taskdefs/import/symlinks/d3b";
+ File symlinkFile = new File(System.getProperty("root"), symlink);
+ if (Runtime.getRuntime().exec(new String[] {ln, "-s", "d3a", symlinkFile.getAbsolutePath()}).waitFor() != 0) {
+ throw new IOException("'" + ln + " -s d3a " + symlink + "' failed");
+ }
+ try {
+ buildRule.configureProject(
+ "src/etc/testcases/taskdefs/import/symlinks/d1/p1.xml");
+ assertEquals(
+ buildRule.getProject().getProperty("ant.file.p2"),
+ new File(System.getProperty("root"), "src/etc/testcases/taskdefs/import/symlinks/d2/p2.xml")
+ .getAbsolutePath());
+ assertEquals(
+ buildRule.getProject().getProperty("ant.file.p3"),
+ new File(System.getProperty("root"), "src/etc/testcases/taskdefs/import/symlinks/d3b/p3.xml")
+ .getAbsolutePath());
+ } finally {
+ symlinkFile.delete();
+ }
+ }
+
+ @Test
+ public void testTargetFirst() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/import/importtargetfirst.xml");
+ assertContains("Importing targetfirstAfter target firstAfter importing", buildRule.getLog());
+ }
+
+ @Test
+ public void testTargetName() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/import/c.xml");
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/InitializeClassTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/InitializeClassTest.java
new file mode 100644
index 00000000..a44303f9
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/InitializeClassTest.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+
+import org.apache.tools.ant.BuildFileRule;
+import org.apache.tools.ant.FileUtilities;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * Test to see if static initializers are invoked the same way
+ * when <java> is invoked in forked and unforked modes.
+ *
+ */
+public class InitializeClassTest {
+
+ @Rule
+ public final BuildFileRule buildRule = new BuildFileRule();
+
+ private File f1 = new File(System.getProperty("root"), "src/etc/testcases/taskdefs/forkedout");
+ private File f2 = new File(System.getProperty("root"), "src/etc/testcases/taskdefs/unforkedout");
+
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/initializeclass.xml");
+ }
+
+ @Test
+ public void testAll() throws IOException {
+ buildRule.executeTarget("forked");
+ synchronized (System.out) {
+ PrintStream ps = System.out;
+ PrintStream newps = new PrintStream(new FileOutputStream(f2));
+ try {
+ System.setOut(newps);
+ buildRule.getProject().executeTarget("unforked");
+ } finally {
+ System.setOut(ps);
+
+ newps.close();
+ }
+ }
+ assertEquals(FileUtilities.getFileContents(f1), FileUtilities.getFileContents(f2));
+ }
+
+ @After
+ public void tearDown() {
+ f1.delete();
+ f2.delete();
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/InputTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/InputTest.java
new file mode 100644
index 00000000..4b6efaa1
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/InputTest.java
@@ -0,0 +1,126 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.BuildFileRule;
+import org.apache.tools.ant.input.PropertyFileInputHandler;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+
+public class InputTest {
+
+ @Rule
+ public final BuildFileRule buildRule = new BuildFileRule();
+
+ private InputStream originalStdIn;
+
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/input.xml");
+ System.getProperties()
+ .put(PropertyFileInputHandler.FILE_NAME_KEY,
+ buildRule.getProject().resolveFile("input.properties")
+ .getAbsolutePath());
+ buildRule.getProject().setInputHandler(new PropertyFileInputHandler());
+ originalStdIn = System.in;
+ }
+
+ @After
+ public void tearDown() {
+ System.setIn(originalStdIn);
+ }
+
+ @Test
+ public void test1() {
+ buildRule.executeTarget("test1");
+ }
+
+ @Test
+ public void test2() {
+ buildRule.executeTarget("test2");
+ }
+
+ @Test
+ public void test3() {
+ try {
+ buildRule.executeTarget("test3");
+ fail("BuildException expected: invalid input");
+ } catch (BuildException ex) {
+ assertEquals("Found invalid input test for 'All data is going to be deleted from DB continue?'",
+ ex.getMessage());
+ }
+ }
+
+ @Test
+ public void test5() {
+ buildRule.executeTarget("test5");
+ }
+
+ @Test
+ public void test6() {
+ buildRule.executeTarget("test6");
+ assertEquals("scott", buildRule.getProject().getProperty("db.user"));
+ }
+
+ @Test
+ public void testPropertyFileInlineHandler() {
+ buildRule.executeTarget("testPropertyFileInlineHandler");
+ }
+
+ @Test
+ public void testDefaultInlineHandler() throws IOException {
+ stdin();
+ buildRule.executeTarget("testDefaultInlineHandler");
+ }
+
+ @Test
+ public void testGreedyInlineHandler() throws IOException {
+ stdin();
+ buildRule.executeTarget("testGreedyInlineHandler");
+ }
+
+ @Test
+ public void testGreedyInlineHandlerClassname() throws IOException {
+ stdin();
+ buildRule.executeTarget("testGreedyInlineHandlerClassname");
+ }
+
+ @Test
+ public void testGreedyInlineHandlerRefid() throws IOException {
+ stdin();
+ buildRule.executeTarget("testGreedyInlineHandlerRefid");
+ }
+
+ private void stdin() throws IOException {
+ System.setIn(new FileInputStream(buildRule.getProject().resolveFile("input.stdin")));
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/JarTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/JarTest.java
new file mode 100644
index 00000000..9b8ff155
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/JarTest.java
@@ -0,0 +1,375 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.IOException;
+import java.io.Reader;
+import java.util.Enumeration;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.BuildFileRule;
+import org.apache.tools.ant.FileUtilities;
+import org.apache.tools.ant.util.FileUtils;
+import org.junit.After;
+import org.junit.Assume;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.apache.tools.ant.AntAssert.assertContains;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+/**
+ */
+public class JarTest {
+
+ @Rule
+ public final BuildFileRule buildRule = new BuildFileRule();
+
+ private static String tempJar = "tmp.jar";
+ private static String tempDir = "jartmp/";
+ private Reader r1, r2;
+
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/jar.xml");
+ buildRule.executeTarget("setUp");
+ }
+
+ @After
+ public void tearDown() {
+ if (r1 != null) {
+ try {
+ r1.close();
+ } catch (IOException e) {
+ }
+ }
+ if (r2 != null) {
+ try {
+ r2.close();
+ } catch (IOException e) {
+ }
+ }
+ }
+
+ @Test
+ public void test1() {
+ try {
+ buildRule.executeTarget("test1");
+ fail("BuildException expected: required argument not specified");
+ } catch (BuildException ex) {
+ //TODO assert value
+ }
+ }
+
+ @Test
+ public void test2() {
+ try {
+ buildRule.executeTarget("test2");
+ fail("BuildException expected: manifest file does not exist");
+ } catch (BuildException ex) {
+ //TODO assert value
+ }
+ }
+
+ @Test
+ public void test3() {
+ try {
+ buildRule.executeTarget("test3");
+ fail("BuildException expected: Unrecognized whenempty attribute: format C: /y");
+ } catch (BuildException ex) {
+ //TODO assert value
+ }
+ }
+
+ private File getOutputDir() {
+ return new File(buildRule.getProject().getProperty("output"));
+ }
+
+ @Test
+ public void test4() {
+ buildRule.executeTarget("test4");
+ File jarFile = new File(getOutputDir(), tempJar);
+
+ assertTrue(jarFile.exists());
+ }
+
+ @Test
+ public void testNoRecreateWithoutUpdate() {
+ testNoRecreate("test4");
+ }
+
+ @Test
+ public void testNoRecreateWithUpdate() {
+ testNoRecreate("testNoRecreateWithUpdate");
+ }
+
+ private void testNoRecreate(String secondTarget) {
+ buildRule.executeTarget("test4");
+ File jarFile = new File(getOutputDir(), tempJar);
+
+ // move the modified date back a couple of seconds rather than delay the test on each run
+ Assume.assumeTrue(jarFile.setLastModified(jarFile.lastModified()
+ - (FileUtils.getFileUtils().getFileTimestampGranularity() * 3)));
+ long jarModifiedDate = jarFile.lastModified();
+
+ buildRule.executeTarget(secondTarget);
+ assertEquals("jar has not been recreated in " + secondTarget,
+ jarModifiedDate, jarFile.lastModified());
+ }
+
+ @Test
+ public void testRecreateWithoutUpdateAdditionalFiles() {
+ testRecreate("test4", "testRecreateWithoutUpdateAdditionalFiles");
+ }
+
+ @Test
+ public void testRecreateWithUpdateAdditionalFiles() {
+ testRecreate("test4", "testRecreateWithUpdateAdditionalFiles");
+ }
+
+ @Test
+ public void testRecreateWithoutUpdateNewerFile() {
+ testRecreate("testRecreateNewerFileSetup",
+ "testRecreateWithoutUpdateNewerFile");
+ }
+
+ @Test
+ public void testRecreateWithUpdateNewerFile() {
+ testRecreate("testRecreateNewerFileSetup",
+ "testRecreateWithUpdateNewerFile");
+ }
+
+ private void testRecreate(String firstTarget, String secondTarget) {
+ //Move the modified date on all input back a couple of seconds rather then delay the test to achieve a similar effect
+ FileUtilities.rollbackTimetamps(buildRule.getProject().getBaseDir(), 5);
+
+ buildRule.executeTarget(firstTarget);
+ File jarFile = new File(getOutputDir(), tempJar);
+
+ //Move the modified date back a couple of seconds rather then delay the test to achieve a similar effect
+ FileUtilities.rollbackTimetamps(buildRule.getOutputDir(), 5);
+
+ long jarModifiedDate = jarFile.lastModified();
+ buildRule.executeTarget(secondTarget);
+ jarFile = new File(getOutputDir(), tempJar);
+ assertTrue("jar has been recreated in " + secondTarget,
+ jarModifiedDate < jarFile.lastModified());
+ }
+
+ @Test
+ public void testManifestStaysIntact()
+ throws IOException, ManifestException {
+ buildRule.executeTarget("testManifestStaysIntact");
+
+ r1 = new FileReader(new File(getOutputDir(),
+ tempDir + "manifest"));
+ r2 = new FileReader(new File(getOutputDir(),
+ tempDir + "META-INF/MANIFEST.MF"));
+
+ Manifest mf1 = new Manifest(r1);
+ Manifest mf2 = new Manifest(r2);
+ assertEquals(mf1, mf2);
+ }
+
+ @Test
+ public void testNoRecreateBasedirExcludesWithUpdate() {
+ testNoRecreate("testNoRecreateBasedirExcludesWithUpdate");
+ }
+
+ @Test
+ public void testNoRecreateBasedirExcludesWithoutUpdate() {
+ testNoRecreate("testNoRecreateBasedirExcludesWithoutUpdate");
+ }
+
+ @Test
+ public void testNoRecreateZipfilesetExcludesWithUpdate() {
+ testNoRecreate("testNoRecreateZipfilesetExcludesWithUpdate");
+ }
+
+ @Test
+ public void testNoRecreateZipfilesetExcludesWithoutUpdate() {
+ testNoRecreate("testNoRecreateZipfilesetExcludesWithoutUpdate");
+ }
+
+ @Test
+ public void testRecreateZipfilesetWithoutUpdateAdditionalFiles() {
+ testRecreate("test4",
+ "testRecreateZipfilesetWithoutUpdateAdditionalFiles");
+ }
+
+ @Test
+ public void testRecreateZipfilesetWithUpdateAdditionalFiles() {
+ testRecreate("test4",
+ "testRecreateZipfilesetWithUpdateAdditionalFiles");
+ }
+
+ @Test
+ public void testRecreateZipfilesetWithoutUpdateNewerFile() {
+ testRecreate("testRecreateNewerFileSetup",
+ "testRecreateZipfilesetWithoutUpdateNewerFile");
+ }
+
+ @Test
+ public void testRecreateZipfilesetWithUpdateNewerFile() {
+ testRecreate("testRecreateNewerFileSetup",
+ "testRecreateZipfilesetWithUpdateNewerFile");
+ }
+
+ @Test
+ public void testCreateWithEmptyFileset() {
+ buildRule.executeTarget("testCreateWithEmptyFilesetSetUp");
+ buildRule.executeTarget("testCreateWithEmptyFileset");
+ buildRule.executeTarget("testCreateWithEmptyFileset");
+ }
+
+ @Test
+ public void testUpdateIfOnlyManifestHasChanged() {
+ buildRule.executeTarget("testUpdateIfOnlyManifestHasChanged");
+ File jarXml = new File(getOutputDir(), tempDir + "jar.xml");
+ assertTrue(jarXml.exists());
+ }
+
+ // bugzilla report 10262
+ @Test
+ public void testNoDuplicateIndex() throws IOException {
+ ZipFile archive = null;
+ try {
+ buildRule.executeTarget("testIndexTests");
+ archive = new ZipFile(new File(getOutputDir(), tempJar));
+ Enumeration e = archive.entries();
+ int numberOfIndexLists = 0;
+ while (e.hasMoreElements()) {
+ ZipEntry ze = (ZipEntry) e.nextElement();
+ if (ze.getName().equals("META-INF/INDEX.LIST")) {
+ numberOfIndexLists++;
+ }
+ }
+ assertEquals(1, numberOfIndexLists);
+ } finally {
+ if (archive != null) {
+ archive.close();
+ }
+ }
+ }
+
+ // bugzilla report 16972
+ @Test
+ public void testRootFilesInIndex() throws IOException {
+ ZipFile archive = null;
+ try {
+ buildRule.executeTarget("testIndexTests");
+ archive = new ZipFile(new File(getOutputDir(), tempJar));
+ ZipEntry ze = archive.getEntry("META-INF/INDEX.LIST");
+ InputStream is = archive.getInputStream(ze);
+ BufferedReader r = new BufferedReader(new InputStreamReader(is,
+ "UTF8"));
+ boolean foundSub = false;
+ boolean foundSubFoo = false;
+ boolean foundFoo = false;
+
+ String line = r.readLine();
+ while (line != null) {
+ if (line.equals("foo")) {
+ foundFoo = true;
+ } else if (line.equals("sub")) {
+ foundSub = true;
+ } else if (line.equals("sub/foo")) {
+ foundSubFoo = true;
+ }
+ line = r.readLine();
+ }
+
+ assertTrue(foundSub);
+ assertTrue(!foundSubFoo);
+ assertTrue(foundFoo);
+ } finally {
+ if (archive != null) {
+ archive.close();
+ }
+ }
+ }
+ @Test
+ public void testManifestOnlyJar() {
+
+ buildRule.executeTarget("testManifestOnlyJar");
+ assertContains("Building MANIFEST-only jar: ", buildRule.getLog());
+ File manifestFile = new File(getOutputDir(), tempDir + "META-INF" + File.separator + "MANIFEST.MF");
+ assertTrue(manifestFile.exists());
+ }
+
+ @Test
+ public void testIndexJarsPlusJarMarker() {
+ buildRule.executeTarget("testIndexJarsPlusJarMarker");
+ }
+
+ @Test
+ public void testNoVersionInfoFail() {
+ try {
+ buildRule.executeTarget("testNoVersionInfoFail");
+ fail("BuildException expected: Manifest Implemention information missing.");
+ } catch (BuildException ex) {
+ assertContains("No Implementation-Title set.", ex.getMessage());
+ }
+ }
+
+ @Test
+ public void testNoVersionInfoIgnore() {
+ buildRule.executeTarget("testNoVersionInfoIgnore");
+ assertTrue(buildRule.getFullLog().indexOf("No Implementation-Title set.") > -1 );
+ assertTrue(buildRule.getFullLog().indexOf("No Implementation-Version set.") > -1 );
+ assertTrue(buildRule.getFullLog().indexOf("No Implementation-Vendor set.") > -1 );
+ }
+
+ @Test
+ public void testNoVersionInfoWarn() {
+ buildRule.executeTarget("testNoVersionInfoWarn");
+ assertTrue(buildRule.getLog().indexOf("No Implementation-Title set.") > -1 );
+ assertTrue(buildRule.getLog().indexOf("No Implementation-Version set.") > -1 );
+ assertTrue(buildRule.getLog().indexOf("No Implementation-Vendor set.") > -1 );
+ }
+
+ @Test
+ public void testNoVersionInfoNoStrict() {
+ buildRule.executeTarget("testNoVersionInfoNoStrict");
+ assertFalse(buildRule.getLog().indexOf("No Implementation-Title set.") > -1 );
+ assertFalse(buildRule.getLog().indexOf("No Implementation-Version set.") > -1 );
+ assertFalse(buildRule.getLog().indexOf("No Implementation-Vendor set.") > -1 );
+ }
+
+ @Test
+ public void testHasVersionInfo() {
+ buildRule.executeTarget("testHasVersionInfo");
+ assertFalse(buildRule.getLog().indexOf("No Implementation-Title set.") > -1 );
+ assertFalse(buildRule.getLog().indexOf("No Implementation-Version set.") > -1 );
+ assertFalse(buildRule.getLog().indexOf("No Implementation-Vendor set.") > -1 );
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/JavaTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/JavaTest.java
new file mode 100644
index 00000000..d54b8f28
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/JavaTest.java
@@ -0,0 +1,475 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.PipedInputStream;
+import java.io.PipedOutputStream;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.BuildFileRule;
+import org.apache.tools.ant.input.DefaultInputHandler;
+import org.apache.tools.ant.util.FileUtils;
+import org.apache.tools.ant.util.TeeOutputStream;
+import org.junit.Assume;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.internal.AssumptionViolatedException;
+
+import static org.apache.tools.ant.AntAssert.assertContains;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+/**
+ * stress out java task
+ * */
+public class JavaTest {
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ private static final int TIME_TO_WAIT = 1;
+ // wait 1 second extra to allow for java to start ...
+ // this time was OK on a Win NT machine and on nagoya
+ private static final int SECURITY_MARGIN = 2000;
+
+ /** Utilities used for file operations */
+ private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+
+ private boolean runFatalTests=false;
+
+
+ /**
+ * configure the project.
+ * if the property junit.run.fatal.tests is set we run
+ * the fatal tests
+ */
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/java.xml");
+ buildRule.executeTarget("setUp");
+
+ //final String propname="tests-classpath.value";
+ //String testClasspath=System.getProperty(propname);
+ //System.out.println("Test cp="+testClasspath);
+ String runFatal=System.getProperty("junit.run.fatal.tests");
+ if(runFatal!=null)
+ runFatalTests=true;
+ }
+
+ @Test
+ public void testNoJarNoClassname(){
+ try {
+ buildRule.executeTarget("testNoJarNoClassname");
+ fail("Build exception should have been thrown - parameter validation");
+ } catch (BuildException ex) {
+ assertContains("Classname must not be null.", ex.getMessage());
+ }
+ }
+
+ @Test
+ public void testJarNoFork() {
+ try {
+ buildRule.executeTarget("testJarNoFork");
+ fail("Build exception should have been thrown - parameter validation");
+ } catch (BuildException ex) {
+ assertContains("Cannot execute a jar in non-forked mode. Please set fork='true'. ", ex.getMessage());
+ }
+ }
+
+ @Test
+ public void testJarAndClassName() {
+ try {
+ buildRule.executeTarget("testJarAndClassName");
+ fail("Build exception should have been thrown - both classname and JAR are not allowed");
+ } catch (BuildException ex) {
+ assertEquals("Cannot use 'jar' and 'classname' attributes in same command", ex.getMessage());
+ }
+ }
+
+ @Test
+ public void testClassnameAndJar() {
+ try {
+ buildRule.executeTarget("testClassnameAndJar");
+ fail("Build exception should have been thrown - both classname and JAR are not allowed");
+ } catch (BuildException ex) {
+ assertEquals("Cannot use 'jar' and 'classname' attributes in same command.", ex.getMessage());
+ }
+ }
+
+ @Test
+ public void testRun() {
+ buildRule.executeTarget("testRun");
+ }
+
+
+
+ /** this test fails but we ignore the return value;
+ * we verify that failure only matters when failonerror is set
+ */
+ @Test
+ public void testRunFail() {
+ Assume.assumeTrue("Fatal tests have not been set to run", runFatalTests);
+ buildRule.executeTarget("testRunFail");
+ }
+
+ @Test
+ public void testRunFailFoe() {
+ Assume.assumeTrue("Fatal tests have not been set to run", runFatalTests);
+ try {
+ buildRule.executeTarget("testRunFailFoe");
+ fail("Build exception should have been thrown - " + "java failures being propagated");
+ } catch (BuildException ex) {
+ assertContains("Java returned:", ex.getMessage());
+ }
+ }
+
+ @Test
+ public void testRunFailFoeFork() {
+ try {
+ buildRule.executeTarget("testRunFailFoeFork");
+ fail("Build exception should have been thrown - " + "java failures being propagated");
+ } catch (BuildException ex) {
+ assertContains("Java returned:", ex.getMessage());
+ }
+ }
+
+ @Test
+ public void testExcepting() {
+ buildRule.executeTarget("testExcepting");
+ assertContains("Exception raised inside called program", buildRule.getLog());
+ }
+
+ @Test
+ public void testExceptingFork() {
+ buildRule.executeTarget("testExceptingFork");
+ assertContains("Java Result:", buildRule.getLog());
+ }
+
+ @Test
+ public void testExceptingFoe() {
+ try {
+ buildRule.executeTarget("testExceptingFoe");
+ fail("Build exception should have been thrown - " + "passes exception through");
+ } catch (BuildException ex) {
+ assertContains("Exception raised inside called program", ex.getMessage());
+ }
+ }
+
+ @Test
+ public void testExceptingFoeFork() {
+ try {
+ buildRule.executeTarget("testExceptingFoeFork");
+ fail("Build exception should have been thrown - " + "exceptions turned into error codes");
+ } catch (BuildException ex) {
+ assertContains("Java returned:", ex.getMessage());
+ }
+ }
+
+ @Test
+ public void testResultPropertyZero() {
+ buildRule.executeTarget("testResultPropertyZero");
+ assertEquals("0", buildRule.getProject().getProperty("exitcode"));
+ }
+
+ @Test
+ public void testResultPropertyNonZero() {
+ buildRule.executeTarget("testResultPropertyNonZero");
+ assertEquals("2", buildRule.getProject().getProperty("exitcode"));
+ }
+
+ @Test
+ public void testResultPropertyZeroNoFork() {
+ buildRule.executeTarget("testResultPropertyZeroNoFork");
+ assertEquals("0", buildRule.getProject().getProperty("exitcode"));
+ }
+
+ @Test
+ public void testResultPropertyNonZeroNoFork() {
+ buildRule.executeTarget("testResultPropertyNonZeroNoFork");
+ assertEquals("-1", buildRule.getProject().getProperty("exitcode"));
+ }
+
+ @Test
+ public void testRunFailWithFailOnError() {
+ try {
+ buildRule.executeTarget("testRunFailWithFailOnError");
+ fail("Build exception should have been thrown - " + "non zero return code");
+ } catch (BuildException ex) {
+ assertContains("Java returned:", ex.getMessage());
+ }
+ }
+
+ @Test
+ public void testRunSuccessWithFailOnError() {
+ buildRule.executeTarget("testRunSuccessWithFailOnError");
+ }
+
+ @Test
+ public void testSpawn() throws InterruptedException {
+ File logFile = FILE_UTILS.createTempFile("spawn", "log",
+ new File(buildRule.getProject().getProperty("output")), false, false);
+ // this is guaranteed by FileUtils#createTempFile
+ assertTrue("log file not existing", !logFile.exists());
+ buildRule.getProject().setProperty("logFile", logFile.getAbsolutePath());
+ buildRule.getProject().setProperty("timeToWait", Long.toString(TIME_TO_WAIT));
+ buildRule.getProject().executeTarget("testSpawn");
+
+ Thread.sleep(TIME_TO_WAIT * 1000 + SECURITY_MARGIN);
+
+
+ // let's be nice with the next generation of developers
+ if (!logFile.exists()) {
+ System.out.println("suggestion: increase the constant"
+ + " SECURITY_MARGIN to give more time for java to start.");
+ }
+ assertTrue("log file exists", logFile.exists());
+ }
+
+ @Test
+ public void testRedirect1() {
+ buildRule.executeTarget("redirect1");
+ }
+
+ @Test
+ public void testRedirect2() {
+ buildRule.executeTarget("redirect2");
+ }
+
+ @Test
+ public void testRedirect3() {
+ buildRule.executeTarget("redirect3");
+ }
+
+ @Test
+ public void testRedirector1() {
+ buildRule.executeTarget("redirector1");
+ }
+
+ @Test
+ public void testRedirector2() {
+ buildRule.executeTarget("redirector2");
+ }
+
+ @Test
+ public void testReleasedInput() throws Exception {
+ PipedOutputStream out = new PipedOutputStream();
+ final PipedInputStream in = new PipedInputStream(out);
+ buildRule.getProject().setInputHandler(new DefaultInputHandler() {
+ protected InputStream getInputStream() {
+ return in;
+ }
+ });
+ buildRule.getProject().setDefaultInputStream(in);
+
+ Java java = new Java();
+ java.setProject(buildRule.getProject());
+ java.setClassname("org.apache.tools.ant.Main");
+ java.setArgs("-version");
+ java.setFork(true);
+ // note: due to the missing classpath it will fail, but the input stream
+ // reader will be read
+ java.execute();
+
+ Thread inputThread = new Thread(new Runnable() {
+ public void run() {
+ Input input = new Input();
+ input.setProject(buildRule.getProject());
+ input.setAddproperty("input.value");
+ input.execute();
+ }
+ });
+ inputThread.start();
+
+ // wait a little bit for the task to wait for input
+ Thread.sleep(100);
+
+ // write some stuff in the input stream to be catched by the input task
+ out.write("foo\n".getBytes());
+ out.flush();
+ try {
+ out.write("bar\n".getBytes());
+ out.flush();
+ } catch (IOException x) {
+ // "Pipe closed" on XP; ignore?
+ }
+
+ inputThread.join(2000);
+
+ assertEquals("foo", buildRule.getProject().getProperty("input.value"));
+ }
+
+ @Test
+ public void testFlushedInput() throws Exception {
+ final PipedOutputStream out = new PipedOutputStream();
+ final PipedInputStream in = new PipedInputStream(out);
+ buildRule.getProject().setInputHandler(new DefaultInputHandler() {
+ protected InputStream getInputStream() {
+ return in;
+ }
+ });
+ buildRule.getProject().setDefaultInputStream(in);
+
+ final boolean[] timeout = new boolean[1];
+ timeout[0] = false;
+
+ Thread writingThread = new Thread(new Runnable() {
+ public void run() {
+ try {
+ // wait a little bit to have the target executed
+ Thread.sleep(500);
+ } catch (InterruptedException e) {
+ throw new AssumptionViolatedException("Thread interrupted", e);
+ }
+ try {
+ out.write("foo-FlushedInput\n".getBytes());
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ });
+ writingThread.setDaemon(true);
+
+ writingThread.start();
+ buildRule.executeTarget("flushedInput");
+ }
+
+ /**
+ * entry point class with no dependencies other
+ * than normal JRE runtime
+ */
+ public static class EntryPoint {
+
+ /**
+ * this entry point is used by the java.xml tests to
+ * generate failure strings to handle
+ * argv[0] = exit code (optional)
+ * argv[1] = string to print to System.out (optional)
+ * argv[1] = string to print to System.err (optional)
+ */
+ public static void main(String[] argv) {
+ int exitCode=0;
+ if(argv.length>0) {
+ try {
+ exitCode=Integer.parseInt(argv[0]);
+ } catch(NumberFormatException nfe) {
+ exitCode=-1;
+ }
+ }
+ if(argv.length>1) {
+ System.out.println(argv[1]);
+ }
+ if(argv.length>2) {
+ System.err.println(argv[2]);
+ }
+ if(exitCode!=0) {
+ System.exit(exitCode);
+ }
+ }
+ }
+
+ /**
+ * entry point class with no dependencies other
+ * than normal JRE runtime
+ */
+ public static class ExceptingEntryPoint {
+
+ /**
+ * throw a run time exception which does not need
+ * to be in the signature of the entry point
+ */
+ public static void main(String[] argv) {
+ throw new NullPointerException("Exception raised inside called program");
+ }
+ }
+ /**
+ * test class for spawn
+ */
+ public static class SpawnEntryPoint {
+ public static void main(String [] argv) throws InterruptedException {
+ int sleepTime = 10;
+ String logFile = "spawn.log";
+ if (argv.length >= 1) {
+ sleepTime = Integer.parseInt(argv[0]);
+ }
+ if (argv.length >= 2)
+ {
+ logFile = argv[1];
+ }
+ OutputStreamWriter out = null;
+ Thread.sleep(sleepTime * 1000);
+
+ try {
+ File dest = new File(logFile);
+ FileOutputStream fos = new FileOutputStream(dest);
+ out = new OutputStreamWriter(fos);
+ out.write("bye bye\n");
+ } catch (Exception ex) {}
+ finally {
+ try {out.close();} catch (IOException ioe) {}}
+
+ }
+ }
+
+ /**
+ * entry point class to pipe System.in to the specified stream:
+ * "out", "err", or "both". If none specified, swallow the input.
+ */
+ public static class PipeEntryPoint {
+
+ /**
+ * pipe input to specified output
+ */
+ public static void main(String[] args) throws InterruptedException {
+ OutputStream os = null;
+ if (args.length > 0) {
+ if ("out".equalsIgnoreCase(args[0])) {
+ os = System.out;
+ } else if ("err".equalsIgnoreCase(args[0])) {
+ os = System.err;
+ } else if ("both".equalsIgnoreCase(args[0])) {
+ os = new TeeOutputStream(System.out, System.err);
+ }
+ }
+ if (os != null) {
+ Thread t = new Thread(new StreamPumper(System.in, os, true));
+ t.setName("PipeEntryPoint " + args[0]);
+ t.start();
+ t.join();
+ }
+ }
+ }
+
+ public static class ReadPoint {
+ public static void main(String[] args) throws IOException {
+ String line = new BufferedReader(new InputStreamReader(System.in)).readLine();
+ System.out.println(line);
+ }
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/JavacTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/JavacTest.java
new file mode 100644
index 00000000..12ceea28
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/JavacTest.java
@@ -0,0 +1,247 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.compilers.CompilerAdapter;
+import org.apache.tools.ant.taskdefs.compilers.CompilerAdapterFactory;
+import org.apache.tools.ant.taskdefs.compilers.Javac13;
+import org.apache.tools.ant.taskdefs.compilers.JavacExternal;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.apache.tools.ant.AntAssert.assertContains;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Testcase for <javac>.
+ *
+ */
+public class JavacTest {
+
+ private Project project;
+ private Javac javac;
+
+ @Before
+ public void setUp() {
+ project = new Project();
+ project.init();
+ javac = new Javac();
+ javac.setProject(project);
+ }
+
+ /**
+ * Test setting the name of the javac executable.
+ */
+ @Test
+ public void testForkedExecutableName() {
+ assertNull("no fork means no executable", javac.getJavacExecutable());
+
+ project.setProperty("build.compiler", "modern");
+ assertNull("no fork means no executable", javac.getJavacExecutable());
+
+ javac.setFork(true);
+ assertNotNull("normal fork", javac.getJavacExecutable());
+ assertContains("name should contain \"javac\"", "javac",
+ javac.getJavacExecutable());
+
+ project.setProperty("build.compiler", "extJavac");
+ javac.setFork(false);
+ assertNotNull("fork via property", javac.getJavacExecutable());
+ assertContains("name should contain \"javac\"", "javac", javac.getJavacExecutable());
+
+ project.setProperty("build.compiler", "whatever");
+ assertNull("no fork and not extJavac means no executable",
+ javac.getJavacExecutable());
+
+ String myJavac = "Slartibartfast";
+ javac.setFork(true);
+ javac.setExecutable(myJavac);
+ assertEquals(myJavac, javac.getJavacExecutable());
+ }
+
+ /**
+ * Test nested compiler args.
+ */
+ @Test
+ public void testCompilerArg() {
+ String[] args = javac.getCurrentCompilerArgs();
+ assertNotNull(args);
+ assertEquals("no args", 0, args.length);
+
+ Javac.ImplementationSpecificArgument arg = javac.createCompilerArg();
+ String ford = "Ford";
+ String prefect = "Prefect";
+ String testArg = ford + " " + prefect;
+ arg.setValue(testArg);
+ args = javac.getCurrentCompilerArgs();
+ assertEquals("unconditional single arg", 1, args.length);
+ assertEquals(testArg, args[0]);
+
+ arg.setCompiler("jikes");
+ args = javac.getCurrentCompilerArgs();
+ assertNotNull(args);
+ assertEquals("implementation is jikes but build.compiler is null",
+ 0, args.length);
+
+ project.setProperty("build.compiler", "jvc");
+ args = javac.getCurrentCompilerArgs();
+ assertNotNull(args);
+ assertEquals("implementation is jikes but build.compiler is jvc",
+ 0, args.length);
+
+ project.setProperty("build.compiler", "jikes");
+ args = javac.getCurrentCompilerArgs();
+ assertEquals("both are jikes", 1, args.length);
+ assertEquals(testArg, args[0]);
+
+ arg.setLine(testArg);
+ args = javac.getCurrentCompilerArgs();
+ assertEquals("split at space", 2, args.length);
+ assertEquals(ford, args[0]);
+ assertEquals(prefect, args[1]);
+ }
+
+ /**
+ * Test nested compiler args in the fork="true" and
+ * implementation="extJavac" case.
+ */
+ @Test
+ public void testCompilerArgForForkAndExtJavac() {
+ Javac.ImplementationSpecificArgument arg = javac.createCompilerArg();
+ String ford = "Ford";
+ String prefect = "Prefect";
+ String testArg = ford + " " + prefect;
+ arg.setValue(testArg);
+ arg.setCompiler("extJavac");
+ javac.setFork(true);
+ String[] args = javac.getCurrentCompilerArgs();
+ assertEquals("both are forked javac", 1, args.length);
+ assertEquals(testArg, args[0]);
+ }
+
+ /**
+ * Test compiler attribute.
+ */
+ @Test
+ public void testCompilerAttribute() {
+ // check defaults
+ String compiler = javac.getCompiler();
+ assertNotNull(compiler);
+ if (System.getProperty("build.compiler") != null) {
+ assertEquals(System.getProperty("build.compiler"),
+ compiler);
+ } else {
+ assertTrue("default value",
+ "javac1.1".equals(compiler)
+ || "javac1.2".equals(compiler)
+ || "javac1.3".equals(compiler)
+ || "javac1.4".equals(compiler)
+ || "javac1.5".equals(compiler)
+ || "classic".equals(compiler));
+ }
+
+ javac.setFork(true);
+ assertNotNull(javac.getCompiler());
+ assertEquals("extJavac", javac.getCompiler());
+ assertEquals(compiler, javac.getCompilerVersion());
+
+ // check build.compiler provides defaults
+ javac = new Javac();
+ javac.setProject(project);
+ // setUserProperty to override system properties
+ project.setUserProperty("build.compiler", "jikes");
+ compiler = javac.getCompiler();
+ assertNotNull(compiler);
+ assertEquals("jikes", compiler);
+
+ javac.setFork(true);
+ compiler = javac.getCompiler();
+ assertNotNull(compiler);
+ assertEquals("jikes", compiler);
+
+ // check attribute overrides build.compiler
+ javac.setFork(false);
+ javac.setCompiler("jvc");
+ compiler = javac.getCompiler();
+ assertNotNull(compiler);
+ assertEquals("jvc", compiler);
+
+ javac.setFork(true);
+ compiler = javac.getCompiler();
+ assertNotNull(compiler);
+ assertEquals("jvc", compiler);
+ }
+
+ @Test
+ public void testCompilerAdapter() {
+ javac.setCompiler("javac1.4");
+
+ javac.setDepend(true);
+ CompilerAdapter adapter =
+ CompilerAdapterFactory.getCompiler(javac.getCompiler(), javac);
+
+ assertTrue(adapter instanceof Javac13);
+
+ javac.setFork(true);
+ adapter =
+ CompilerAdapterFactory.getCompiler(javac.getCompiler(), javac);
+ assertTrue(adapter instanceof JavacExternal);
+ }
+
+ @Test
+ public void testSourceNoDefault() {
+ assertNull(javac.getSource());
+ }
+
+ @Test
+ public void testSourceWithDefault() {
+ project.setNewProperty("ant.build.javac.source", "1.4");
+ assertEquals("1.4", javac.getSource());
+ }
+
+ @Test
+ public void testSourceOverridesDefault() {
+ project.setNewProperty("ant.build.javac.source", "1.4");
+ javac.setSource("1.5");
+ assertEquals("1.5", javac.getSource());
+ }
+
+ @Test
+ public void testTargetNoDefault() {
+ assertNull(javac.getTarget());
+ }
+
+ @Test
+ public void testTargetWithDefault() {
+ project.setNewProperty("ant.build.javac.target", "1.4");
+ assertEquals("1.4", javac.getTarget());
+ }
+
+ @Test
+ public void testTargetOverridesDefault() {
+ project.setNewProperty("ant.build.javac.target", "1.4");
+ javac.setTarget("1.5");
+ assertEquals("1.5", javac.getTarget());
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/JavadocTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/JavadocTest.java
new file mode 100644
index 00000000..f7a287d5
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/JavadocTest.java
@@ -0,0 +1,132 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.BuildFileRule;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+public class JavadocTest {
+
+ @Rule
+ public final BuildFileRule buildRule = new BuildFileRule();
+
+ private static final String BUILD_PATH = "src/etc/testcases/taskdefs/javadoc/";
+ private static final String BUILD_FILENAME = "javadoc.xml";
+ private static final String BUILD_FILE = BUILD_PATH + BUILD_FILENAME;
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject(BUILD_FILE);
+ }
+
+ // PR 38370
+ @Test
+ public void testDirsetPath() {
+ buildRule.executeTarget("dirsetPath");
+ }
+
+ // PR 38370
+ @Test
+ public void testDirsetPathWithoutPackagenames() {
+ buildRule.executeTarget("dirsetPathWithoutPackagenames");
+ }
+
+ // PR 38370
+ @Test
+ public void testNestedDirsetPath() {
+ buildRule.executeTarget("nestedDirsetPath");
+ }
+
+ // PR 38370
+ @Test
+ public void testFilesetPath() {
+ buildRule.executeTarget("filesetPath");
+ }
+
+ // PR 38370
+ @Test
+ public void testNestedFilesetPath() {
+ buildRule.executeTarget("nestedFilesetPath");
+ }
+
+ // PR 38370
+ @Test
+ public void testFilelistPath() {
+ buildRule.executeTarget("filelistPath");
+ }
+
+ // PR 38370
+ @Test
+ public void testNestedFilelistPath() {
+ buildRule.executeTarget("nestedFilelistPath");
+ }
+
+ // PR 38370
+ @Test
+ public void testPathelementPath() {
+ buildRule.executeTarget("pathelementPath");
+ }
+
+ // PR 38370
+ @Test
+ public void testPathelementLocationPath() {
+ buildRule.executeTarget("pathelementLocationPath");
+ }
+
+ // PR 38370
+ @Test
+ public void testNestedSource() {
+ buildRule.executeTarget("nestedSource");
+ }
+
+ // PR 38370
+ @Test
+ public void testNestedFilesetRef() {
+ buildRule.executeTarget("nestedFilesetRef");
+ }
+
+ // PR 38370
+ @Test
+ public void testNestedFilesetRefInPath() {
+ buildRule.executeTarget("nestedFilesetRefInPath");
+ }
+
+ @Test
+ public void testNestedFilesetNoPatterns() {
+ buildRule.executeTarget("nestedFilesetNoPatterns");
+ }
+
+ @Test
+ public void testDoublyNestedFileset() {
+ buildRule.executeTarget("doublyNestedFileset");
+ }
+
+ @Test
+ public void testDoublyNestedFilesetNoPatterns() {
+ buildRule.executeTarget("doublyNestedFilesetNoPatterns");
+ }
+
+ @Test
+ public void testNonJavaIncludes() { // #41264
+ buildRule.executeTarget("nonJavaIncludes");
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/LoadFileTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/LoadFileTest.java
new file mode 100644
index 00000000..fd8c3281
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/LoadFileTest.java
@@ -0,0 +1,170 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.BuildFileRule;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.apache.tools.ant.AntAssert.assertContains;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.fail;
+
+/**
+ * Test the load file task
+ */
+public class LoadFileTest {
+
+ @Rule
+ public final BuildFileRule buildRule = new BuildFileRule();
+
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/loadfile.xml");
+ }
+
+
+ @After
+ public void tearDown() {
+ buildRule.executeTarget("cleanup");
+ }
+
+
+ /**
+ * A unit test for JUnit
+ */
+ @Test
+ public void testNoSourcefileDefined() {
+ try {
+ buildRule.executeTarget("testNoSourcefileDefined");
+ fail("BuildException expected: source file not defined");
+ } catch (BuildException ex) {
+ //TODO assert value
+ }
+ }
+
+
+ /**
+ * A unit test for JUnit
+ */
+ @Test
+ public void testNoPropertyDefined() {
+ try {
+ buildRule.executeTarget("testNoPropertyDefined");
+ fail("BuildException expected: output property not defined");
+ } catch (BuildException ex) {
+ //TODO assert value
+ }
+ }
+
+
+ /**
+ * A unit test for JUnit
+ */
+ @Test
+ public void testNoSourcefilefound() {
+ try {
+ buildRule.executeTarget("testNoSourcefilefound");
+ fail("BuildException expected: File not found");
+ } catch (BuildException ex) {
+ assertContains(" doesn't exist", ex.getMessage());
+ }
+ }
+
+ /**
+ * A unit test for JUnit
+ */
+ @Test
+ public void testFailOnError()
+ throws BuildException {
+ buildRule.executeTarget("testFailOnError");
+ assertNull(buildRule.getProject().getProperty("testFailOnError"));
+ }
+
+
+ /**
+ * A unit test for JUnit
+ */
+ @Test
+ public void testLoadAFile()
+ throws BuildException {
+ buildRule.executeTarget("testLoadAFile");
+ if(buildRule.getProject().getProperty("testLoadAFile").indexOf("eh?")<0) {
+ fail("property is not all in the file");
+ }
+ }
+
+
+ /**
+ * A unit test for JUnit
+ */
+ @Test
+ public void testLoadAFileEnc()
+ throws BuildException {
+ buildRule.executeTarget("testLoadAFileEnc");
+ assertNotNull("file load files", buildRule.getProject().getProperty("testLoadAFileEnc"));
+ }
+
+ /**
+ * A unit test for JUnit
+ */
+ @Test
+ public void testEvalProps()
+ throws BuildException {
+ buildRule.executeTarget("testEvalProps");
+ if(buildRule.getProject().getProperty("testEvalProps").indexOf("rain")<0) {
+ fail("property eval broken");
+ }
+ }
+
+ /**
+ * Test FilterChain and FilterReaders
+ */
+ @Test
+ public void testFilterChain()
+ throws BuildException {
+ buildRule.executeTarget("testFilterChain");
+ if(buildRule.getProject().getProperty("testFilterChain").indexOf("World!")<0) {
+ fail("Filter Chain broken");
+ }
+ }
+
+ /**
+ * Test StripJavaComments filterreader functionality.
+ */
+ @Test
+ public final void testStripJavaComments()
+ throws BuildException {
+ buildRule.executeTarget("testStripJavaComments");
+ final String expected = buildRule.getProject().getProperty("expected");
+ final String generated = buildRule.getProject().getProperty("testStripJavaComments");
+ assertEquals(expected, generated);
+ }
+
+ @Test
+ public void testOneLine() {
+ buildRule.executeTarget("testOneLine");
+ assertEquals("1,2,3,4", buildRule.getProject().getProperty("testOneLine"));
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/MacroDefTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/MacroDefTest.java
new file mode 100644
index 00000000..18b9786b
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/MacroDefTest.java
@@ -0,0 +1,206 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.BuildFileRule;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.apache.tools.ant.AntAssert.assertContains;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+/**
+ */
+public class MacroDefTest {
+
+ @Rule
+ public final BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/macrodef.xml");
+ }
+
+ @Test
+ public void testSimple() {
+ buildRule.executeTarget("simple");
+ assertEquals("Hello World", buildRule.getLog());
+ }
+
+ @Test
+ public void testText() {
+ buildRule.executeTarget("text");
+ assertEquals("Inner Text", buildRule.getLog());
+ }
+
+ @Test
+ public void testDuplicateAttribute() {
+ try {
+ buildRule.executeTarget("duplicate.attribute");
+ fail("BuildException expected: the attribute text has already been specified");
+ } catch (BuildException ex) {
+ //TODO assert value
+ }
+ }
+
+ @Test
+ public void testDuplicateElement() {
+ try {
+ buildRule.executeTarget("duplicate.element");
+ fail("BuildException expected: the element text has already been specified");
+ } catch (BuildException ex) {
+ //TODO assert value
+ }
+ }
+
+ @Test
+ public void testUri() {
+ buildRule.executeTarget("uri");
+ assertEquals("Hello World", buildRule.getLog());
+ }
+
+ @Test
+ public void testNested() {
+ buildRule.executeTarget("nested");
+ assertEquals("A nested element", buildRule.getLog());
+ }
+
+ @Test
+ public void testDouble() {
+ buildRule.executeTarget("double");
+ assertEquals("@{prop} is 'property', value of ${property} is 'A property value'", buildRule.getLog());
+ }
+
+ @Test
+ public void testIgnoreCase() {
+ buildRule.executeTarget("ignorecase");
+ assertEquals("a is ab is b", buildRule.getLog());
+ }
+
+ @Test
+ public void testIgnoreElementCase() {
+ buildRule.executeTarget("ignore-element-case");
+ assertEquals("nested elementnested element", buildRule.getLog());
+ }
+
+ @Test
+ public void testTextElement() {
+ buildRule.executeTarget("textelement");
+ assertContains("Hello world", buildRule.getLog());
+ }
+
+ @Test
+ public void testTextTrim() {
+ buildRule.executeTarget("text.trim");
+ assertContains("[Hello world]", buildRule.getLog());
+ }
+
+ @Test
+ public void testDuplicateTextName() {
+ try {
+ buildRule.executeTarget("duplicatetextname");
+ fail("BuildException expected: the name \"text\" is already used as an attribute");
+ } catch (BuildException ex) {
+ //TODO assert value
+ }
+ }
+ @Test
+ public void testDuplicateTextName2() {
+ try {
+ buildRule.executeTarget("duplicatetextname2");
+ fail("BuildException expected: the attribute name \"text\" has already been used by the text element");
+ } catch (BuildException ex) {
+ //TODO assert value
+ }
+ }
+ @Test
+ public void testEscape() {
+ buildRule.executeTarget("escape");
+ assertEquals("a@b or a@b is avalue@bvalue", buildRule.getLog());
+ }
+ @Test
+ public void testAttributeDescription() {
+ buildRule.executeTarget("attribute.description");
+ assertEquals("description is hello world", buildRule.getLog());
+ }
+ @Test
+ public void testOverrideDefault() {
+ buildRule.executeTarget("override.default");
+ assertEquals("value is new", buildRule.getLog());
+ }
+ @Test
+ public void testImplicit() {
+ buildRule.executeTarget("implicit");
+ assertEquals("Before implicitIn implicitAfter implicit", buildRule.getLog());
+ }
+ @Test
+ public void testImplicitNotOptional() {
+ try {
+ buildRule.executeTarget("implicit.notoptional");
+ fail("BuildException expected: Missing nested elements for implicit element implicit");
+ } catch (BuildException ex) {
+ assertEquals("Missing nested elements for implicit element implicit", ex.getMessage());
+ }
+ }
+ @Test
+ public void testImplicitOptional() {
+ buildRule.executeTarget("implicit.optional");
+ assertEquals("Before implicitAfter implicit", buildRule.getLog());
+ }
+ @Test
+ public void testImplicitExplicit() {
+ try {
+ buildRule.executeTarget("implicit.explicit");
+ fail("BuildException expected: Only one element allowed when using implicit elements");
+ } catch (BuildException ex) {
+ assertEquals("Only one element allowed when using implicit elements", ex.getMessage());
+ }
+ }
+
+ @Test
+ public void testBackTraceOff() {
+ try {
+ buildRule.executeTarget("backtraceoff");
+ } catch (BuildException ex) {
+ if (ex.getMessage().indexOf("following error occurred") != -1) {
+ fail("error message contained backtrace - " + ex.getMessage());
+ }
+ }
+ }
+
+ @Test
+ public void testBackTrace() {
+ try {
+ buildRule.executeTarget("backtraceon");
+ fail("BuildException expected: Checking if a back trace is created");
+ } catch (BuildException ex) {
+ assertContains("following error occurred", ex.getMessage());
+ }
+ }
+
+ @Test
+ public void testTopLevelText() {
+ buildRule.executeTarget("top-level-text");
+ assertContains("Hello World", buildRule.getLog());
+ }
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/MakeUrlTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/MakeUrlTest.java
new file mode 100644
index 00000000..8c2762a7
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/MakeUrlTest.java
@@ -0,0 +1,176 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.BuildFileRule;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import java.io.InputStream;
+import java.io.IOException;
+import java.net.URL;
+
+import static org.apache.tools.ant.AntAssert.assertContains;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+
+public class MakeUrlTest {
+
+ @Rule
+ public final BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/makeurl.xml");
+ }
+
+ @Test
+ public void testEmpty() {
+ try {
+ buildRule.executeTarget("testEmpty");
+ fail("BuildException expected: missing property");
+ } catch (BuildException ex) {
+ assertContains("property", ex.getMessage());
+ }
+ }
+
+ @Test
+ public void testNoProperty() {
+ try {
+ buildRule.executeTarget("testNoProperty");
+ fail("BuildException expected: missing property");
+ } catch (BuildException ex) {
+ assertContains("property", ex.getMessage());
+ }
+ }
+
+ @Test
+ public void testNoFile() {
+ try {
+ buildRule.executeTarget("testNoFile");
+ fail("BuildException expected: missing file");
+ } catch (BuildException ex) {
+ assertContains("file", ex.getMessage());
+ }
+ }
+
+ @Test
+ public void testValidation() {
+ try {
+ buildRule.executeTarget("testValidation");
+ fail("BuildException expected: " + MakeUrl.ERROR_MISSING_FILE);
+ } catch (BuildException ex) {
+ assertContains("file", ex.getMessage());
+ }
+ }
+
+ @Test
+ public void testWorks() {
+ buildRule.executeTarget("testWorks");
+ assertPropertyContains("testWorks", "file:");
+ assertPropertyContains("testWorks", "/foo");
+ }
+
+ @Test
+ public void testIllegalChars() {
+ buildRule.executeTarget("testIllegalChars");
+ assertPropertyContains("testIllegalChars", "file:");
+ assertPropertyContains("testIllegalChars", "fo%20o%25");
+ }
+
+ /**
+ * test that we can round trip by opening a url that exists
+ *
+ * @throws IOException
+ */
+ @Test
+ public void testRoundTrip() throws IOException {
+ buildRule.executeTarget("testRoundTrip");
+ assertPropertyContains("testRoundTrip", "file:");
+ String property = getProperty("testRoundTrip");
+ URL url = new URL(property);
+ InputStream instream = url.openStream();
+ instream.close();
+ }
+
+ @Test
+ public void testIllegalCombinations() {
+ buildRule.executeTarget("testIllegalCombinations");
+ assertPropertyContains("testIllegalCombinations", "/foo");
+ assertPropertyContains("testIllegalCombinations", ".xml");
+ }
+
+ @Test
+ public void testFileset() {
+ buildRule.executeTarget("testFileset");
+ assertPropertyContains("testFileset", ".xml ");
+ assertPropertyEndsWith("testFileset", ".xml");
+ }
+
+ @Test
+ public void testFilesetSeparator() {
+ buildRule.executeTarget("testFilesetSeparator");
+ assertPropertyContains("testFilesetSeparator", ".xml\",\"");
+ assertPropertyEndsWith("testFilesetSeparator", ".xml");
+ }
+
+ @Test
+ public void testPath() {
+ buildRule.executeTarget("testPath");
+ assertPropertyContains("testPath", "makeurl.xml");
+ }
+
+ /**
+ * assert that a property ends with
+ *
+ * @param property
+ * @param ending
+ */
+ private void assertPropertyEndsWith(String property, String ending) {
+ String result = getProperty(property);
+ String substring = result.substring(result.length() - ending.length());
+ assertEquals(ending, substring);
+ }
+
+ /**
+ * assert that a property contains a string
+ *
+ * @param property name of property to look for
+ * @param contains what to search for in the string
+ */
+ protected void assertPropertyContains(String property, String contains) {
+ String result = getProperty(property);
+
+ assertTrue("expected " + contains + " in " + result,
+ result != null && result.indexOf(contains) >= 0);
+ }
+
+ /**
+ * get a property from the project
+ *
+ * @param property
+ * @return
+ */
+ protected String getProperty(String property) {
+ return buildRule.getProject().getProperty(property);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/ManifestClassPathTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/ManifestClassPathTest.java
new file mode 100644
index 00000000..95d4f3de
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/ManifestClassPathTest.java
@@ -0,0 +1,249 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs;
+
+
+import static org.apache.tools.ant.AntAssert.assertContains;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.fail;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.BuildFileRule;
+import org.apache.tools.ant.taskdefs.condition.Os;
+import org.apache.tools.ant.util.regexp.RegexpMatcherFactory;
+import org.junit.Assume;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+/**
+ * Tests &lt;bm:manifestclasspath&gt;.
+ */
+public class ManifestClassPathTest {
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/manifestclasspath.xml");
+ }
+
+ @Test
+ public void testBadDirectory() {
+ try {
+ buildRule.executeTarget("test-bad-directory");
+ fail("Build exception should have been thrown on bad directory");
+ } catch (BuildException ex) {
+ assertContains("Jar's directory not found:", ex.getMessage());
+ }
+ assertNull(buildRule.getProject().getProperty("jar.classpath"));
+ }
+
+ @Test
+ public void testBadNoProperty() {
+ try {
+ buildRule.executeTarget("test-bad-no-property");
+ fail("Build exception should have been thrown on no property");
+ } catch (BuildException ex) {
+ assertContains("Missing 'property' attribute!", ex.getMessage());
+ }
+ assertNull(buildRule.getProject().getProperty("jar.classpath"));
+ }
+
+ @Test
+ public void testBadPropertyExists() {
+ try {
+ buildRule.executeTarget("test-bad-property-exists");
+ fail("Build exception should have been thrown on bad property");
+ } catch (BuildException ex) {
+ assertContains("Property 'jar.classpath' already set!", ex.getMessage());
+ }
+ assertEquals(buildRule.getProject().getProperty("jar.classpath"), "exists");
+ }
+
+ @Test
+ public void testBadNoJarfile() {
+ try {
+ buildRule.executeTarget("test-bad-no-jarfile");
+ fail("Build exception should have been thrown on bad jar file");
+ } catch (BuildException ex) {
+ assertContains("Missing 'jarfile' attribute!", ex.getMessage());
+ }
+ assertNull(buildRule.getProject().getProperty("jar.classpath"));
+ }
+
+ @Test
+ public void testBadNoClassPath() {
+ try {
+ buildRule.executeTarget("test-bad-no-classpath");
+ fail("Build exception should have been thrown on no classpath");
+ } catch (BuildException ex) {
+ assertContains("Missing nested <classpath>!", ex.getMessage());
+ }
+ assertNull(buildRule.getProject().getProperty("jar.classpath"));
+ }
+
+ @Test
+ public void testParentLevel1() {
+ buildRule.executeTarget("test-parent-level1");
+
+ assertEquals(buildRule.getProject().getProperty("jar.classpath"), "dsp-core/ " +
+ "dsp-pres/ " +
+ "dsp-void/ " +
+ "../generated/dsp-core/ " +
+ "../generated/dsp-pres/ " +
+ "../generated/dsp-void/ " +
+ "../resources/dsp-core/ " +
+ "../resources/dsp-pres/ " +
+ "../resources/dsp-void/");
+ }
+
+ @Test
+ public void testParentLevel2() {
+ buildRule.executeTarget("test-parent-level2");
+
+ assertEquals(buildRule.getProject().getProperty("jar.classpath"), "../dsp-core/ " +
+ "../dsp-pres/ " +
+ "../dsp-void/ " +
+ "../../generated/dsp-core/ " +
+ "../../generated/dsp-pres/ " +
+ "../../generated/dsp-void/ " +
+ "../../resources/dsp-core/ " +
+ "../../resources/dsp-pres/ " +
+ "../../resources/dsp-void/");
+ }
+
+ @Test
+ public void testParentLevel2TooDeep() {
+ try {
+ buildRule.executeTarget("test-parent-level2-too-deep");
+ fail("Build exception should have been thrown on no suitable path");
+ } catch (BuildException ex) {
+ assertContains("No suitable relative path from ", ex.getMessage());
+ }
+ assertNull(buildRule.getProject().getProperty("jar.classpath"));
+ }
+
+ @Test
+ public void testPseudoTahoeRefid() {
+ Assume.assumeTrue("No regexp matcher is present", RegexpMatcherFactory.regexpMatcherPresent(buildRule.getProject()));
+
+ buildRule.executeTarget("test-pseudo-tahoe-refid");
+ assertEquals(buildRule.getProject().getProperty("jar.classpath"), "classes/dsp-core/ " +
+ "classes/dsp-pres/ " +
+ "classes/dsp-void/ " +
+ "generated/dsp-core/ " +
+ "resources/dsp-core/ " +
+ "resources/dsp-pres/");
+ }
+
+ @Test
+ public void testPseudoTahoeNested() {
+ Assume.assumeTrue("No regexp matcher is present", RegexpMatcherFactory.regexpMatcherPresent(buildRule.getProject()));
+
+ buildRule.executeTarget("test-pseudo-tahoe-nested");
+ assertEquals(buildRule.getProject().getProperty("jar.classpath"), "classes/dsp-core/ " +
+ "classes/dsp-pres/ " +
+ "classes/dsp-void/ " +
+ "generated/dsp-core/ " +
+ "resources/dsp-core/ " +
+ "resources/dsp-pres/");
+ }
+
+ @Test
+ public void testParentLevel2WithJars() {
+ buildRule.executeTarget("test-parent-level2-with-jars");
+
+ assertEquals(buildRule.getProject().getProperty("jar.classpath"), "../../lib/acme-core.jar " +
+ "../../lib/acme-pres.jar " +
+ "../dsp-core/ " +
+ "../dsp-pres/ " +
+ "../dsp-void/ " +
+ "../../generated/dsp-core/ " +
+ "../../generated/dsp-pres/ " +
+ "../../generated/dsp-void/ " +
+ "../../resources/dsp-core/ " +
+ "../../resources/dsp-pres/ " +
+ "../../resources/dsp-void/");
+ }
+
+ @Test
+ public void testInternationalGerman() {
+ buildRule.executeTarget("international-german");
+ buildRule.executeTarget("run-two-jars");
+ assertContains("beta alpha", buildRule.getLog());
+
+ }
+
+ @Test
+ public void testInternationalHebrew() {
+ Assume.assumeFalse("Test with hebrew path not attempted under Windows", Os.isFamily("windows"));
+ buildRule.executeTarget("international-hebrew");
+ buildRule.executeTarget("run-two-jars");
+ assertContains("beta alpha", buildRule.getLog());
+ }
+
+ @Test
+ public void testSameWindowsDrive() {
+ Assume.assumeTrue("Test with drive letters only run on windows", Os.isFamily("windows"));
+ buildRule.executeTarget("testSameDrive");
+ assertEquals(buildRule.getProject().getProperty("cp"), "../a/b/x.jar");
+ }
+
+ @Test
+ public void testDifferentWindowsDrive() {
+ Assume.assumeTrue("Test with drive letters only run on windows", Os.isFamily("windows"));
+ // the lines below try to find a drive name different than the one containing the temp dir
+ // if the temp dir is C will try to use D
+ // if the temp dir is on D or other will try to use C
+ File tmpdir = new File(System.getProperty("java.io.tmpdir"));
+ String driveLetter = "C";
+ try {
+ String tmpCanonicalPath = tmpdir.getCanonicalPath();
+ driveLetter = tmpCanonicalPath.substring(0, 1).toUpperCase();
+ } catch (IOException ioe) {
+ System.out.println("exception happened getting canonical path of java.io.tmpdir : " + ioe.getMessage());
+ }
+ String altDriveLetter = null;
+ try {
+ if ("C".equals(driveLetter)) {
+ altDriveLetter = "D";
+ } else {
+ altDriveLetter = "C";
+ }
+ new java.io.File(altDriveLetter + ":/foo.txt").getCanonicalPath();
+ } catch (java.io.IOException e) {
+ Assume.assumeNoException("Drive " + altDriveLetter + ": doesn't exist or is not ready", e);
+ }
+ buildRule.getProject().setProperty("altDriveLetter", altDriveLetter);
+
+ try {
+ buildRule.executeTarget("testDifferentDrive");
+ fail("Build exception should have been thrown on no alternative drive");
+ } catch (BuildException ex) {
+ assertContains("No suitable relative path from ", ex.getMessage());
+ }
+
+ assertNull(buildRule.getProject().getProperty("cp"));
+ }
+} // END class ManifestClassPathTest
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/ManifestTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/ManifestTest.java
new file mode 100644
index 00000000..6e794327
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/ManifestTest.java
@@ -0,0 +1,477 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.BuildFileRule;
+import org.apache.tools.ant.Project;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.apache.tools.ant.AntAssert.assertContains;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+/**
+ * Testcase for the Manifest class used in the jar task.
+ *
+ */
+public class ManifestTest {
+
+ @Rule
+ public final BuildFileRule buildRule = new BuildFileRule();
+
+ private File expandedManifest;
+ private File outDir;
+
+ public static final String LONG_LINE
+ = "AReallyLongLineToTestLineBreakingInManifests-ACapabilityWhich" +
+ "IsSureToLeadToHundredsOfQuestionsAboutWhyAntMungesManifests" +
+ "OfCourseTheAnswerIsThatIsWhatTheSpecRequiresAndIfAnythingHas" +
+ "AProblemWithThatItIsNotABugInAnt";
+
+ public static final String LONG_70_NAME
+ = "ThisNameIsJustSeventyCharactersWhichIsAllowedAccordingToTheSpecsFiller";
+ public static final String LONG_68_NAME
+ = "ThisNameIsJustSixtyEightCharactersWhichIsAllowedAccordingToTheSpecsX";
+ public static final String NOT_LONG_NAME
+ = "NameIsJustUnderSeventyCharactersWhichIsAllowedAccordingTheSpec";
+
+ public static final String VALUE = "NOT_LONG";
+
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/manifest.xml");
+ outDir = new File(buildRule.getProject().getProperty("output"));
+ expandedManifest = new File(outDir, "manifests/META-INF/MANIFEST.MF");
+ }
+
+ @After
+ public void tearDown() {
+ buildRule.executeTarget("tearDown");
+ }
+
+ /**
+ * Empty manifest - is OK
+ */
+ @Test
+ public void test1() throws ManifestException, IOException {
+ buildRule.executeTarget("test1");
+ Manifest manifest = getManifest(expandedManifest);
+ String version = manifest.getManifestVersion();
+ assertEquals("Manifest was not created with correct version - ", "1.0", version);
+ }
+
+ /**
+ * Simple Manifest with version 2.0
+ */
+ @Test
+ public void test2() throws ManifestException, IOException {
+ buildRule.executeTarget("test2");
+ Manifest manifest = getManifest(expandedManifest);
+ String version = manifest.getManifestVersion();
+ assertEquals("Manifest was not created with correct version - ", "2.0", version);
+ }
+
+ /**
+ * Malformed manifest - no : on the line
+ */
+ @Test
+ public void test3() {
+ try {
+ buildRule.executeTarget("test3");
+ fail("BuildException expected: Manifest is invalid - no colon on header line");
+ } catch (BuildException ex) {
+ assertContains("Invalid Manifest", ex.getMessage());
+ }
+ }
+
+ /**
+ * Malformed manifest - starts with continuation line
+ */
+ @Test
+ public void test4() {
+ try {
+ buildRule.executeTarget("test4");
+ fail("BuildException expected: Manifest is invalid - section starts with continuation line");
+ } catch (BuildException ex) {
+ assertContains("Invalid Manifest", ex.getMessage());
+ }
+ }
+
+ /**
+ * Malformed manifest - Name attribute in main section
+ */
+ @Test
+ public void test5() {
+ buildRule.executeTarget("test5");
+ String output = buildRule.getLog();
+ boolean hasWarning = output.indexOf("Manifest warning: \"Name\" attributes should not occur in the main section") != -1;
+ assertTrue("Expected warning about Name in main section", hasWarning);
+ }
+
+ /**
+ * New Section not starting with Name attribute.
+ */
+ @Test
+ public void test6() {
+ try {
+ buildRule.executeTarget("test6");
+ fail("BuildException expected: Manifest is invalid - section starts with incorrect attribute");
+ } catch (BuildException ex) {
+ assertContains("Invalid Manifest", ex.getMessage());
+ }
+ String output = buildRule.getLog();
+ boolean hasWarning = output.indexOf("Manifest sections should start with a \"Name\" attribute") != -1;
+ assertTrue("Expected warning about section not starting with Name: attribute", hasWarning);
+ }
+
+
+ /**
+ * From attribute is illegal
+ */
+ @Test
+ public void test7() {
+ buildRule.executeTarget("test7");
+
+ boolean hasWarning = buildRule.getLog().indexOf(Manifest.ERROR_FROM_FORBIDDEN) != -1;
+ assertTrue("Expected warning about From: attribute", hasWarning);
+ }
+
+ /**
+ * Inline manifest - OK
+ */
+ @Test
+ public void test8() throws IOException, ManifestException {
+ buildRule.executeTarget("test8");
+ Manifest manifest = getManifest(expandedManifest);
+ Manifest.Section mainSection = manifest.getMainSection();
+ String classpath = mainSection.getAttributeValue("class-path");
+ assertEquals("Class-Path attribute was not set correctly - ", "fubar", classpath);
+
+ Manifest.Section testSection = manifest.getSection("Test");
+ String testAttr = testSection.getAttributeValue("TestAttr");
+ assertEquals("TestAttr attribute was not set correctly - ", "Test", testAttr);
+ }
+
+ /**
+ * Inline manifest - Invalid since has a Name attribute in the section element
+ */
+ @Test
+ public void test9() {
+ try {
+ buildRule.executeTarget("test9");
+ fail("BuildException expected: Construction is invalid - Name attribute should not be used");
+ } catch (BuildException ex) {
+ assertContains("Specify the section name using the \"name\" attribute of the <section> element",
+ ex.getMessage());
+ }
+ }
+
+ /**
+ * Inline manifest - Invalid attribute without name
+ */
+ @Test
+ public void test10() {
+ try {
+ buildRule.executeTarget("test10");
+ fail("BuildException expected: Attribute has no name");
+ } catch (BuildException ex) {
+ assertContains("Attributes must have name and value", ex.getMessage());
+ }
+ }
+
+ /**
+ * Inline manifest - Invalid attribute without value
+ */
+ @Test
+ public void test11() {
+ try {
+ buildRule.executeTarget("test11");
+ fail("BuildException expected: Attribute has no value");
+ } catch (BuildException ex) {
+ assertContains("Attributes must have name and value", ex.getMessage());
+ }
+ }
+
+ /**
+ * Inline manifest - Invalid attribute without value
+ */
+ @Test
+ public void test12() {
+ try {
+ buildRule.executeTarget("test12");
+ fail("BuildException expected: Section with no name");
+ } catch (BuildException ex) {
+ assertContains("Sections must have a name", ex.getMessage());
+ }
+ }
+
+ /**
+ * Inline manifest - Duplicate attribute
+ */
+ @Test
+ public void test13() {
+ try {
+ buildRule.executeTarget("test13");
+ fail("BuildException expected: Duplicate Attribute");
+ } catch (BuildException ex) {
+ assertContains("The attribute \"Test\" may not occur more than once in the same section", ex.getMessage());
+ }
+ }
+
+ /**
+ * Inline manifest - OK since classpath entries can be duplicated.
+ */
+ @Test
+ public void test14() throws IOException, ManifestException {
+ buildRule.executeTarget("test14");
+ Manifest manifest = getManifest(expandedManifest);
+ Manifest.Section mainSection = manifest.getMainSection();
+ String classpath = mainSection.getAttributeValue("class-path");
+ assertEquals("Class-Path attribute was not set correctly - ",
+ "Test1 Test2 Test3 Test4", classpath);
+ }
+
+ /**
+ * Tets long line wrapping
+ */
+ @Test
+ public void testLongLine() throws IOException, ManifestException {
+ Project p = buildRule.getProject();
+ p.setUserProperty("test.longline", LONG_LINE);
+ p.setUserProperty("test.long68name" , LONG_68_NAME);
+ p.setUserProperty("test.long70name" , LONG_70_NAME);
+ p.setUserProperty("test.notlongname" , NOT_LONG_NAME);
+ p.setUserProperty("test.value", VALUE);
+ buildRule.executeTarget("testLongLine");
+
+ Manifest manifest = getManifest(expandedManifest);
+ Manifest.Section mainSection = manifest.getMainSection();
+ String classpath = mainSection.getAttributeValue("class-path");
+ assertEquals("Class-Path attribute was not set correctly - ",
+ LONG_LINE, classpath);
+
+ String value = mainSection.getAttributeValue(LONG_68_NAME);
+ assertEquals("LONG_68_NAME_VALUE_MISMATCH", VALUE, value);
+ value = mainSection.getAttributeValue(LONG_70_NAME);
+ assertEquals("LONG_70_NAME_VALUE_MISMATCH", VALUE, value);
+ value = mainSection.getAttributeValue(NOT_LONG_NAME);
+ assertEquals("NOT_LONG_NAME_VALUE_MISMATCH", VALUE, value);
+
+ Set set = new HashSet();
+ FileReader fin = new FileReader(expandedManifest);
+ try {
+ BufferedReader in = new BufferedReader(fin);
+
+ String read = in.readLine();
+ while (read != null) {
+ set.add(read);
+ read = in.readLine();
+ }
+ in.close();
+ } finally {
+ fin.close();
+ }
+
+ assertTrue("Manifest file should have contained string ", set
+ .remove(" NOT_LONG"));
+ assertTrue("Manifest file should have contained string ", set
+ .remove(" NG"));
+ assertTrue("Manifest file should have contained string ", set
+ .remove(LONG_70_NAME + ": "));
+ assertTrue("Manifest file should have contained string ", set
+ .remove(NOT_LONG_NAME + ": NOT_LO"));
+ }
+
+ /**
+ * Tests ordering of sections
+ */
+ @Test
+ public void testOrder1() throws IOException, ManifestException {
+ buildRule.executeTarget("testOrder1");
+
+ Manifest manifest = getManifest(expandedManifest);
+ Enumeration e = manifest.getSectionNames();
+ String section1 = (String)e.nextElement();
+ String section2 = (String)e.nextElement();
+ assertEquals("First section name unexpected", "Test1", section1);
+ assertEquals("Second section name unexpected", "Test2", section2);
+
+ Manifest.Section section = manifest.getSection("Test1");
+ e = section.getAttributeKeys();
+ String attr1Key = (String)e.nextElement();
+ String attr2Key = (String)e.nextElement();
+ String attr1 = section.getAttribute(attr1Key).getName();
+ String attr2 = section.getAttribute(attr2Key).getName();
+ assertEquals("First attribute name unexpected", "TestAttr1", attr1);
+ assertEquals("Second attribute name unexpected", "TestAttr2", attr2);
+ }
+
+ /**
+ * Tests ordering of sections
+ */
+ @Test
+ public void testOrder2() throws IOException, ManifestException {
+ buildRule.executeTarget("testOrder2");
+
+ Manifest manifest = getManifest(expandedManifest);
+ Enumeration e = manifest.getSectionNames();
+ String section1 = (String)e.nextElement();
+ String section2 = (String)e.nextElement();
+ assertEquals("First section name unexpected", "Test2", section1);
+ assertEquals("Second section name unexpected", "Test1", section2);
+
+ Manifest.Section section = manifest.getSection("Test1");
+ e = section.getAttributeKeys();
+ String attr1Key = (String)e.nextElement();
+ String attr2Key = (String)e.nextElement();
+ String attr1 = section.getAttribute(attr1Key).getName();
+ String attr2 = section.getAttribute(attr2Key).getName();
+ assertEquals("First attribute name unexpected", "TestAttr2", attr1);
+ assertEquals("Second attribute name unexpected", "TestAttr1", attr2);
+ }
+
+ /**
+ * file attribute for manifest task is required.
+ */
+ @Test
+ public void testNoFile() {
+ try {
+ buildRule.executeTarget("testNoFile");
+ fail("BuildException expected: file is required");
+ } catch (BuildException ex) {
+ //TODO assert value
+ }
+ }
+
+ /**
+ * replace changes Manifest-Version from 2.0 to 1.0
+ */
+ @Test
+ public void testReplace() throws IOException, ManifestException {
+ buildRule.executeTarget("testReplace");
+ Manifest mf = getManifest(new File(outDir, "mftest.mf"));
+ assertNotNull(mf);
+ assertEquals(Manifest.getDefaultManifest(), mf);
+ }
+
+ /**
+ * update keeps the Manifest-Version and adds a new attribute Foo
+ */
+ @Test
+ public void testUpdate() throws IOException, ManifestException {
+ buildRule.executeTarget("testUpdate");
+ Manifest mf = getManifest(new File(outDir, "mftest.mf"));
+ assertNotNull(mf);
+ assertTrue(!Manifest.getDefaultManifest().equals(mf));
+ String mfAsString = mf.toString();
+ assertNotNull(mfAsString);
+ assertTrue(mfAsString.startsWith("Manifest-Version: 2.0"));
+ assertTrue(mfAsString.indexOf("Foo: Bar") > -1);
+
+ mf = getManifest(new File(outDir, "mftest2.mf"));
+ assertNotNull(mf);
+ mfAsString = mf.toString();
+ assertNotNull(mfAsString);
+ assertEquals(-1, mfAsString.indexOf("Foo: Bar"));
+ assertTrue(mfAsString.indexOf("Foo: Baz") > -1);
+ }
+
+ @Test
+ public void testFrom() {
+ buildRule.executeTarget("testFrom");
+ assertContains(Manifest.ERROR_FROM_FORBIDDEN, buildRule.getLog());
+ }
+
+ @Test
+ public void testIllegalName() {
+ try {
+ buildRule.executeTarget("testIllegalName");
+ fail("BuildException expected: Manifest attribute names must not contain ' '");
+ } catch (BuildException ex) {
+ //TODO assert value
+ }
+ }
+
+ @Test
+ public void testIllegalNameInSection() {
+ try {
+ buildRule.executeTarget("testIllegalNameInSection");
+ fail("BuildException expected: Manifest attribute names must not contain ' '");
+ } catch (BuildException ex) {
+ //TODO assert value
+ }
+ }
+
+ @Test
+ public void testIllegalNameBegin() {
+ try {
+ buildRule.executeTarget("testIllegalNameInSection");
+ fail("BuildException expected: Manifest attribute names must not start with '-' at the begin.");
+ } catch (BuildException ex) {
+ //TODO assert value
+ }
+ }
+
+ @Test
+ public void testIllegalName2() {
+ try {
+ buildRule.executeTarget("testIllegalName");
+ fail("BuildException expected: Manifest attribute names must not contain '.'");
+ } catch (BuildException ex) {
+ //TODO assert value
+ }
+ }
+
+ @Test
+ public void testIllegalName3() {
+ try {
+ buildRule.executeTarget("testIllegalName");
+ fail("BuildException expected: Manifest attribute names must not contain '*'");
+ } catch (BuildException ex) {
+ //TODO assert value
+ }
+ }
+
+ /**
+ * Reads mftest.mf.
+ */
+ private Manifest getManifest(File file) throws IOException, ManifestException {
+ FileReader r = new FileReader(file);
+ try {
+ return new Manifest(r);
+ } finally {
+ r.close();
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/MkdirTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/MkdirTest.java
new file mode 100644
index 00000000..d8f1bfc5
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/MkdirTest.java
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.BuildFileRule;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.fail;
+
+/**
+ */
+public class MkdirTest {
+
+ @Rule
+ public final BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/mkdir.xml");
+ }
+
+ @Test
+ public void test1() {
+ try {
+ buildRule.executeTarget("test1");
+ fail("BuildException expected: required argument missing");
+ } catch (BuildException ex) {
+ //TODO assert value
+ }
+ }
+
+ @Test
+ public void test2() {
+ try {
+ buildRule.executeTarget("test2");
+ fail("BuildException expected: directory already exists as a file");
+ } catch (BuildException ex) {
+ //TODO assert value
+ }
+ }
+
+ @Test
+ public void test3() {
+ buildRule.executeTarget("test3");
+ java.io.File f = new java.io.File(buildRule.getProject().getProperty("output"), "testdir.tmp");
+ if (!f.exists() || !f.isDirectory()) {
+ fail("mkdir failed");
+ } else {
+ f.delete();
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/MoveTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/MoveTest.java
new file mode 100644
index 00000000..0537c0a0
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/MoveTest.java
@@ -0,0 +1,168 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.BuildFileRule;
+import org.apache.tools.ant.FileUtilities;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import java.io.File;
+import java.io.IOException;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Tests the Move task.
+ *
+ */
+public class MoveTest {
+
+ @Rule
+ public final BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/move.xml");
+ buildRule.executeTarget("setUp");
+ }
+
+ @Test
+ public void testFilterSet() throws IOException {
+ buildRule.executeTarget("testFilterSet");
+ File tmp = new File(buildRule.getProject().getProperty("output"), "move.filterset.tmp");
+ File check = new File(buildRule.getProject().getBaseDir(), "expected/copy.filterset.filtered");
+ assertTrue(tmp.exists());
+ assertEquals(FileUtilities.getFileContents(check), FileUtilities.getFileContents(tmp));
+ }
+
+ @Test
+ public void testFilterChain() throws IOException {
+ buildRule.executeTarget("testFilterChain");
+ File tmp = new File(buildRule.getProject().getProperty("output"), "move.filterchain.tmp");
+ File check = new File(buildRule.getProject().getBaseDir(), "expected/copy.filterset.filtered");
+ assertTrue(tmp.exists());
+ assertEquals(FileUtilities.getFileContents(check), FileUtilities.getFileContents(tmp));
+ }
+
+ /** Bugzilla Report 11732 */
+ @Test
+ public void testDirectoryRemoval() throws IOException {
+
+ buildRule.executeTarget("testDirectoryRemoval");
+ String output = buildRule.getProject().getProperty("output");
+ assertTrue(!new File(output,"E/B/1").exists());
+ assertTrue(new File(output, "E/C/2").exists());
+ assertTrue(new File(output,"E/D/3").exists());
+ assertTrue(new File(output,"A/B/1").exists());
+ assertTrue(!new File(output,"A/C/2").exists());
+ assertTrue(!new File(output,"A/D/3").exists());
+ assertTrue(!new File(output,"A/C").exists());
+ assertTrue(!new File(output,"A/D").exists());
+ }
+
+ /** Bugzilla Report 18886 */
+ @Test
+ public void testDirectoryRetaining() throws IOException {
+ buildRule.executeTarget("testDirectoryRetaining");
+ String output = buildRule.getProject().getProperty("output");
+ assertTrue(new File(output,"E").exists());
+ assertTrue(new File(output,"E/1").exists());
+ assertTrue(!new File(output,"A/1").exists());
+ assertTrue(new File(output,"A").exists());
+ }
+
+ @Test
+ public void testCompleteDirectoryMove() throws IOException {
+ testCompleteDirectoryMove("testCompleteDirectoryMove");
+ }
+
+ @Test
+ public void testCompleteDirectoryMove2() throws IOException {
+ testCompleteDirectoryMove("testCompleteDirectoryMove2");
+ }
+
+ private void testCompleteDirectoryMove(String target) throws IOException {
+ buildRule.executeTarget(target);
+ String output = buildRule.getProject().getProperty("output");
+ assertTrue(new File(output,"E").exists());
+ assertTrue(new File(output,"E/1").exists());
+ assertTrue(!new File(output,"A/1").exists());
+ // <path> swallows the basedir, it seems
+ //assertTrue(!new File(getOutputDir(),"A").exists());
+ }
+
+ @Test
+ public void testPathElementMove() throws IOException {
+ buildRule.executeTarget("testPathElementMove");
+ String output = buildRule.getProject().getProperty("output");
+ assertTrue(new File(output,"E").exists());
+ assertTrue(new File(output,"E/1").exists());
+ assertTrue(!new File(output,"A/1").exists());
+ assertTrue(new File(output,"A").exists());
+ }
+
+ @Test
+ public void testMoveFileAndFileset() {
+ buildRule.executeTarget("testMoveFileAndFileset");
+ }
+
+ @Test
+ public void testCompleteDirectoryMoveToExistingDir() {
+ buildRule.executeTarget("testCompleteDirectoryMoveToExistingDir");
+ }
+
+ @Test
+ public void testCompleteDirectoryMoveFileToFile() {
+ buildRule.executeTarget("testCompleteDirectoryMoveFileToFile");
+ }
+
+ @Test
+ public void testCompleteDirectoryMoveFileToDir() {
+ buildRule.executeTarget("testCompleteDirectoryMoveFileToDir");
+ }
+
+ @Test
+ public void testCompleteDirectoryMoveFileAndFileset() {
+ buildRule.executeTarget("testCompleteDirectoryMoveFileAndFileset");
+ }
+
+ @Test
+ public void testCompleteDirectoryMoveFileToExistingFile() {
+ buildRule.executeTarget("testCompleteDirectoryMoveFileToExistingFile");
+ }
+
+ @Test
+ public void testCompleteDirectoryMoveFileToExistingDir() {
+ buildRule.executeTarget("testCompleteDirectoryMoveFileToExistingDir");
+ }
+
+ @Test
+ public void testCompleteDirectoryMoveFileToDirWithExistingFile() {
+ buildRule.executeTarget("testCompleteDirectoryMoveFileToDirWithExistingFile");
+ }
+
+ @Test
+ public void testCompleteDirectoryMoveFileToDirWithExistingDir() {
+ buildRule.executeTarget("testCompleteDirectoryMoveFileToDirWithExistingDir");
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/MultiMapTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/MultiMapTest.java
new file mode 100644
index 00000000..95f9eafd
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/MultiMapTest.java
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.BuildFileRule;
+import org.apache.tools.ant.util.FileNameMapper;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+
+/**
+ */
+public class MultiMapTest {
+
+ @Rule
+ public final BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/multimap.xml");
+ }
+
+ @Test
+ public void testMultiCopy() {
+ buildRule.executeTarget("multicopy");
+ }
+
+ @Test
+ public void testMultiMove() {
+ buildRule.executeTarget("multimove");
+ }
+
+ @Test
+ public void testSingleCopy() {
+ buildRule.executeTarget("singlecopy");
+ }
+
+ @Test
+ public void testSingleMove() {
+ buildRule.executeTarget("singlemove");
+ }
+
+ @Test
+ public void testCopyWithEmpty() {
+ buildRule.executeTarget("copywithempty");
+ }
+
+ @Test
+ public void testMoveWithEmpty() {
+ buildRule.executeTarget("movewithempty");
+ }
+
+ public static class TestMapper implements FileNameMapper {
+ public TestMapper() {}
+ public void setFrom(String from) {}
+ public void setTo(String to) {}
+ public String[] mapFileName(final String source_file_name) {
+ return new String[] {
+ source_file_name, source_file_name+".copy2" };
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/NiceTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/NiceTest.java
new file mode 100644
index 00000000..98d9fa58
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/NiceTest.java
@@ -0,0 +1,83 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.BuildFileRule;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.apache.tools.ant.AntAssert.assertContains;
+import static org.junit.Assert.fail;
+
+/**
+ * test nice
+ */
+public class NiceTest {
+
+ @Rule
+ public final BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/nice.xml");
+ }
+
+ @Test
+ public void testNoop() {
+ buildRule.executeTarget("noop");
+ }
+
+ @Test
+ public void testCurrent() {
+ buildRule.executeTarget("current");
+ }
+
+ @Test
+ public void testFaster() {
+ buildRule.executeTarget("faster");
+ }
+
+ @Test
+ public void testSlower() {
+ buildRule.executeTarget("slower");
+ }
+
+ @Test
+ public void testTooSlow() {
+ try {
+ buildRule.executeTarget("too_slow");
+ fail("BuildException expected: out of range");
+ } catch (BuildException ex) {
+ assertContains("out of the range 1-10", ex.getMessage());
+ }
+ }
+
+ @Test
+ public void testTooFast() {
+ try {
+ buildRule.executeTarget("too_fast");
+ fail("BuildException expected: out of range");
+ } catch (BuildException ex) {
+ assertContains("out of the range 1-10", ex.getMessage());
+ }
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/ParallelTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/ParallelTest.java
new file mode 100644
index 00000000..3ca7cf78
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/ParallelTest.java
@@ -0,0 +1,195 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs;
+
+import java.io.PrintStream;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.BuildFileRule;
+import org.apache.tools.ant.DemuxOutputStream;
+import org.apache.tools.ant.ExitStatusException;
+import org.apache.tools.ant.Project;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+/**
+ * Test of the parallel TaskContainer
+ */
+public class ParallelTest {
+
+ @Rule
+ public final BuildFileRule buildRule = new BuildFileRule();
+
+ /** Standard property value for the basic test */
+ public final static String DIRECT_MESSAGE = "direct";
+ /** Standard property value for the basic and fail test */
+ public final static String DELAYED_MESSAGE = "delayed";
+ /** Standard property value for the fail test */
+ public final static String FAILURE_MESSAGE = "failure";
+
+ /** the build fiel associated with this test */
+ public final static String TEST_BUILD_FILE
+ = "src/etc/testcases/taskdefs/parallel.xml";
+
+
+ /** The JUnit setup method */
+ @Before
+ public void setUp() {
+ buildRule.configureProject(TEST_BUILD_FILE);
+ }
+
+ /** tests basic operation of the parallel task */
+ @Test
+ public void testBasic() {
+ // should get no output at all
+ Project p = buildRule.getProject();
+ p.setUserProperty("test.direct", DIRECT_MESSAGE);
+ p.setUserProperty("test.delayed", DELAYED_MESSAGE);
+ buildRule.executeTarget("testBasic");
+ assertEquals("", buildRule.getOutput());
+ assertEquals("", buildRule.getError());
+ String log = buildRule.getLog();
+ assertEquals("parallel tasks didn't output correct data", log,
+ DIRECT_MESSAGE + DELAYED_MESSAGE);
+
+ }
+
+ /** tests basic operation of the parallel task */
+ @Test
+ public void testThreadCount() {
+ // should get no output at all
+ Project p = buildRule.getProject();
+ p.setUserProperty("test.direct", DIRECT_MESSAGE);
+ p.setUserProperty("test.delayed", DELAYED_MESSAGE);
+ buildRule.executeTarget("testThreadCount");
+ assertEquals("", buildRule.getOutput());
+ assertEquals("", buildRule.getError());
+ String log = buildRule.getLog();
+ int pos = 0;
+ while (pos > -1) {
+ pos = countThreads(log, pos);
+ }
+ }
+
+ /**
+ * the test result string should match the regex
+ * <code>^(\|\d+\/(+-)*)+\|$</code> for someting like
+ * <code>|3/++--+-|5/+++++-----|</code>
+ *
+ *@return -1 no more tests
+ * # start pos of next test
+ */
+ static int countThreads(String s, int start) {
+ int firstPipe = s.indexOf('|', start);
+ int beginSlash = s.indexOf('/', firstPipe);
+ int lastPipe = s.indexOf('|', beginSlash);
+ if ((firstPipe == -1) || (beginSlash == -1) || (lastPipe == -1)) {
+ return -1;
+ }
+
+ int max = Integer.parseInt(s.substring(firstPipe + 1, beginSlash));
+ int current = 0;
+ int pos = beginSlash + 1;
+ while (pos < lastPipe) {
+ switch (s.charAt(pos++)) {
+ case '+':
+ current++;
+ break;
+ case '-':
+ current--;
+ break;
+ default:
+ fail("Only expect '+-' in result count, found "
+ + s.charAt(--pos) + " at position " + pos);
+ }
+ if (current > max) {
+ fail("Number of executing threads exceeded number allowed: "
+ + current + " > " + max);
+ }
+ }
+ return lastPipe;
+ }
+
+
+ /** tests the failure of a task within a parallel construction */
+ @Test
+ public void testFail() {
+ // should get no output at all
+ Project p = buildRule.getProject();
+ p.setUserProperty("test.failure", FAILURE_MESSAGE);
+ p.setUserProperty("test.delayed", DELAYED_MESSAGE);
+ try {
+ buildRule.executeTarget("testFail");
+ fail("fail task in one parallel branch");
+ } catch (BuildException ex) {
+ assertEquals(FAILURE_MESSAGE, ex.getMessage());
+ }
+ }
+
+ /** tests the demuxing of output streams in a multithreaded situation */
+ @Test
+ public void testDemux() {
+ Project p = buildRule.getProject();
+ p.addTaskDefinition("demuxtest", DemuxOutputTask.class);
+ synchronized (System.out) {
+ PrintStream out = System.out;
+ PrintStream err = System.err;
+ System.setOut(new PrintStream(new DemuxOutputStream(p, false)));
+ System.setErr(new PrintStream(new DemuxOutputStream(p, true)));
+
+ try {
+ p.executeTarget("testDemux");
+ } finally {
+ System.setOut(out);
+ System.setErr(err);
+ }
+ }
+ }
+
+ /**
+ * @see "https://issues.apache.org/bugzilla/show_bug.cgi?id=55539"
+ */
+ @Test
+ public void testSingleExit() {
+ try {
+ buildRule.executeTarget("testSingleExit");
+ fail("ExitStatusException should have been thrown");
+ } catch (ExitStatusException ex) {
+ assertEquals(42, ex.getStatus());
+ }
+ }
+
+ /**
+ * @see "https://issues.apache.org/bugzilla/show_bug.cgi?id=55539"
+ */
+ @Test
+ public void testExitAndOtherException() {
+ try {
+ buildRule.executeTarget("testExitAndOtherException");
+ fail("ExitStatusException should have been thrown");
+ } catch (ExitStatusException ex) {
+ assertEquals(42, ex.getStatus());
+ }
+ }
+
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/PathConvertTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/PathConvertTest.java
new file mode 100644
index 00000000..31a516e3
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/PathConvertTest.java
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.BuildFileRule;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * Unit test for the &lt;pathconvert&gt; task.
+ */
+public class PathConvertTest {
+
+ @Rule
+ public final BuildFileRule buildRule = new BuildFileRule();
+
+ private static final String BUILD_PATH = "src/etc/testcases/taskdefs/";
+ private static final String BUILD_FILENAME = "pathconvert.xml";
+ private static final String BUILD_FILE = BUILD_PATH + BUILD_FILENAME;
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject(BUILD_FILE);
+ }
+
+ @Test
+ public void testMap() {
+ test("testmap");
+ }
+
+ @Test
+ public void testMapper() {
+ test("testmapper");
+ }
+
+ @Test
+ public void testNoTargetOs() {
+ buildRule.executeTarget("testnotargetos");
+ }
+
+ private void test(String target) {
+ buildRule.executeTarget(target);
+ assertEquals("test#" + BUILD_FILENAME, buildRule.getProject().getProperty("result"));
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/PreSetDefTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/PreSetDefTest.java
new file mode 100644
index 00000000..8c7c1f3f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/PreSetDefTest.java
@@ -0,0 +1,154 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.BuildFileRule;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.types.FileSet;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.apache.tools.ant.AntAssert.assertContains;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+/**
+ */
+public class PreSetDefTest {
+
+ @Rule
+ public final BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/presetdef.xml");
+ }
+
+ @Test
+ public void testSimple() {
+ buildRule.executeTarget("simple");
+ assertEquals("Hello world", buildRule.getLog());
+ }
+
+ @Test
+ public void testText() {
+ buildRule.executeTarget("text");
+ assertEquals("Inner Text", buildRule.getLog());
+ }
+
+ @Test
+ public void testUri() {
+ buildRule.executeTarget("uri");
+ assertEquals("Hello world", buildRule.getLog());
+ }
+
+ @Test
+ public void testDefaultTest() {
+ buildRule.executeTarget("defaulttest");
+ assertEquals("attribute is false", buildRule.getLog());
+ }
+
+ @Test
+ public void testDoubleDefault() {
+ buildRule.executeTarget("doubledefault");
+ assertEquals("attribute is falseattribute is true", buildRule.getLog());
+ }
+
+ @Test
+ public void testTextOptional() {
+ buildRule.executeTarget("text.optional");
+ assertEquals("MyTextoverride text", buildRule.getLog());
+ }
+
+ @Test
+ public void testElementOrder() {
+ buildRule.executeTarget("element.order");
+ assertEquals("Line 1Line 2", buildRule.getLog());
+ }
+
+ @Test
+ public void testElementOrder2() {
+ buildRule.executeTarget("element.order2");
+ assertEquals("Line 1Line 2Line 3", buildRule.getLog());
+ }
+
+ @Test
+ public void testAntTypeTest() {
+ buildRule.executeTarget("antTypeTest");
+ assertEquals("", buildRule.getLog());
+ }
+
+ @Test
+ public void testCorrectTaskNameBadAttr() {
+ try {
+ buildRule.executeTarget("correct_taskname_badattr");
+ fail("BuildException expected: attribute message");
+ } catch (BuildException ex) {
+ assertContains("javac doesn't support the", ex.getMessage());
+ }
+ }
+
+ @Test
+ public void testCorrectTaskNameBadEl() {
+ try {
+ buildRule.executeTarget("correct_taskname_badel");
+ fail("BuildException expected: element message");
+ } catch (BuildException ex) {
+ assertContains("javac doesn't support the", ex.getMessage());
+ }
+ }
+
+ @Test
+ public void testPresetdefWithNestedElementTwice() { // #38056
+ buildRule.executeTarget("presetdef-with-nested-element-twice");
+ buildRule.executeTarget("presetdef-with-nested-element-twice");
+ }
+
+ /**
+ * A test class to check default properties
+ */
+ public static class DefaultTest extends Task {
+ boolean isSet = false;
+ boolean attribute = false;
+ public void setAttribute(boolean b) {
+ if (isSet) {
+ throw new BuildException("Attribute Already set");
+ }
+ attribute = b;
+ isSet = true;
+ }
+
+ public void execute() {
+ getProject().log("attribute is " + attribute);
+ }
+ }
+
+ /**
+ * A test class to check presetdef with add and addConfigured and ant-type
+ */
+ public static class AntTypeTest extends Task {
+ public void addFileSet(FileSet fileset) {
+ }
+ public void addConfiguredConfigured(FileSet fileset) {
+ }
+ }
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/ProcessDestroyerTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/ProcessDestroyerTest.java
new file mode 100644
index 00000000..eadac406
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/ProcessDestroyerTest.java
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+/*
+ * Created on Feb 19, 2003
+ */
+package org.apache.tools.ant.taskdefs;
+
+import java.io.IOException;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+/**
+ */
+//TODO this test seems really unsafe due to the infinite loop
+public class ProcessDestroyerTest {
+
+ @Test
+ public void testProcessDestroyer() throws IOException {
+ ProcessDestroyer processDestroyer = new ProcessDestroyer();
+ Process process =
+ Runtime.getRuntime().exec(
+ "java -cp "
+ + System.getProperty("java.class.path")
+ + " "
+ + getClass().getName());
+
+ assertFalse("Not registered as shutdown hook",
+ processDestroyer.isAddedAsShutdownHook());
+
+ processDestroyer.add(process);
+
+ assertTrue("Registered as shutdown hook",
+ processDestroyer.isAddedAsShutdownHook());
+ try {
+ process.destroy();
+ } finally {
+ processDestroyer.remove(process);
+ }
+
+ assertFalse("Not registered as shutdown hook",
+ processDestroyer.isAddedAsShutdownHook());
+
+ }
+
+ public static void main(String[] args) throws IOException, InterruptedException {
+ new ProcessDestroyerTest().testProcessDestroyer();
+ Thread.sleep(60000);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/PropertyTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/PropertyTest.java
new file mode 100644
index 00000000..52b762d0
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/PropertyTest.java
@@ -0,0 +1,141 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import static org.apache.tools.ant.AntAssert.assertContains;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.BuildFileRule;
+import org.apache.tools.ant.util.FileUtils;
+import org.junit.Assume;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+/**
+ */
+public class PropertyTest {
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ /** Utilities used for file operations */
+ private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/property.xml");
+ buildRule.executeTarget("setUp");
+ }
+
+ @Test
+ public void test1() {
+ // should get no output at all
+ buildRule.executeTarget("test1");
+ assertEquals("System output should have been empty", "", buildRule.getOutput());
+ assertEquals("System error should have been empty", "", buildRule.getError());
+ }
+
+ @Test
+ public void test2() {
+ buildRule.executeTarget("test2");
+ assertContains("testprop1=aa, testprop3=xxyy, testprop4=aazz", buildRule.getLog());
+ }
+
+ @Test
+ public void test3() {
+ try {
+ buildRule.executeTarget("test3");
+ fail("Did not throw exception on circular exception");
+ }
+ catch (BuildException e) {
+ assertTrue("Circular definition not detected - ",
+ e.getMessage().indexOf("was circularly defined") != -1);
+ }
+
+ }
+
+ @Test
+ public void test4() {
+ buildRule.executeTarget("test4");
+ assertContains("http.url is http://localhost:999", buildRule.getLog());
+ }
+
+ @Test
+ public void test5() {
+ String baseDir = buildRule.getProject().getProperty("basedir");
+ String uri = FILE_UTILS.toURI(baseDir + "/property3.properties");
+ buildRule.getProject().setNewProperty("test5.url", uri);
+
+ buildRule.executeTarget("test5");
+ assertContains("http.url is http://localhost:999", buildRule.getLog());
+ }
+
+ @Test
+ public void testPrefixSuccess() {
+ buildRule.executeTarget("prefix.success");
+ assertEquals("80", buildRule.getProject().getProperty("server1.http.port"));
+ }
+
+ @Test
+ public void testPrefixFailure() {
+ try {
+ buildRule.executeTarget("prefix.fail");
+ fail("Did not throw exception on invalid use of prefix");
+ }
+ catch (BuildException e) {
+ assertContains("Prefix allowed on non-resource/file load - ",
+ "Prefix is only valid", e.getMessage());
+ }
+ }
+
+ @Test
+ public void testCircularReference() {
+ try {
+ buildRule.executeTarget("testCircularReference");
+ fail("Did not throw exception on circular exception");
+ } catch (BuildException e) {
+ assertContains("Circular definition not detected - ",
+ "was circularly defined", e.getMessage());
+ }
+ }
+
+ @Test
+ public void testThisIsNotACircularReference() {
+ buildRule.executeTarget("thisIsNotACircularReference");
+ assertContains("b is A/A/A", buildRule.getLog());
+ }
+
+ @Test
+ public void testXmlProperty() {
+ try {
+ Class.forName("java.lang.Iterable");
+ } catch (ClassNotFoundException e) {
+ Assume.assumeNoException("XML Loading only on Java 5+", e);
+ }
+ buildRule.executeTarget("testXmlProperty");
+ assertEquals("ONE", buildRule.getProject().getProperty("xml.one"));
+ assertEquals("TWO", buildRule.getProject().getProperty("xml.two"));
+
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/ProtectedJarMethodsTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/ProtectedJarMethodsTest.java
new file mode 100644
index 00000000..27b3c8c8
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/ProtectedJarMethodsTest.java
@@ -0,0 +1,106 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+
+import org.apache.tools.ant.BuildFileRule;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+/**
+ */
+public class ProtectedJarMethodsTest {
+
+ @Rule
+ public final BuildFileRule buildRule = new BuildFileRule();
+ private static String tempJar = "tmp.jar";
+
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/jar.xml");
+ buildRule.executeTarget("setUp");
+ }
+
+ @Test
+ public void testGrabFilesAndDirs() throws IOException {
+ buildRule.executeTarget("testIndexTests");
+ String archive = buildRule.getProject().getProperty(tempJar);
+ ArrayList dirs = new ArrayList();
+ ArrayList files = new ArrayList();
+ String[] expectedDirs = new String[] {
+ "META-INF/",
+ "sub/",
+ };
+ String[] expectedFiles = new String[] {
+ "foo",
+ };
+ Jar.grabFilesAndDirs(archive, dirs, files);
+ assertEquals(expectedDirs.length, dirs.size());
+ for (int i = 0; i < expectedDirs.length; i++) {
+ assertTrue("Found " + expectedDirs[i],
+ dirs.contains(expectedDirs[i]));
+ }
+ assertEquals(expectedFiles.length, files.size());
+ for (int i = 0; i < expectedFiles.length; i++) {
+ assertTrue("Found " + expectedFiles[i],
+ files.contains(expectedFiles[i]));
+ }
+ }
+
+ @Test
+ public void testFindJarNameNoClasspath() {
+ assertEquals("foo", Jar.findJarName("foo", null));
+ assertEquals("foo", Jar.findJarName("lib" + File.separatorChar + "foo",
+ null));
+ }
+
+ @Test
+ public void testFindJarNameNoMatch() {
+ assertNull(Jar.findJarName("foo", new String[] {"bar"}));
+ }
+
+ @Test
+ public void testFindJarNameSimpleMatches() {
+ assertEquals("foo", Jar.findJarName("foo", new String[] {"foo"}));
+ assertEquals("lib/foo", Jar.findJarName("foo",
+ new String[] {"lib/foo"}));
+ assertEquals("foo", Jar.findJarName("bar" + File.separatorChar + "foo",
+ new String[] {"foo"}));
+ assertEquals("lib/foo",
+ Jar.findJarName("bar" + File.separatorChar + "foo",
+ new String[] {"lib/foo"}));
+ }
+
+ @Test
+ public void testFindJarNameLongestMatchWins() {
+ assertEquals("lib/foo",
+ Jar.findJarName("lib/foo",
+ new String[] {"foo", "lib/foo",
+ "lib/bar/foo"}));
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/RecorderTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/RecorderTest.java
new file mode 100644
index 00000000..c4806cd8
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/RecorderTest.java
@@ -0,0 +1,103 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.BuildFileRule;
+import org.apache.tools.ant.util.FileUtils;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import java.io.File;
+import java.io.IOException;
+
+import static org.junit.Assert.assertTrue;
+
+/**
+ */
+public class RecorderTest {
+
+ @Rule
+ public final BuildFileRule buildRule = new BuildFileRule();
+
+ private static final String REC_IN = "recorder/";
+
+ /** Utilities used for file operations */
+ private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/recorder.xml");
+ buildRule.executeTarget("setUp");
+ }
+
+ @Test
+ public void testNoAppend() throws IOException {
+ buildRule.executeTarget("noappend");
+ assertTrue(FILE_UTILS
+ .contentEquals(buildRule.getProject().resolveFile(REC_IN
+ + "rectest1.result"),
+ new File(buildRule.getOutputDir(),
+ "rectest1.log"), true));
+ }
+
+ @Test
+ public void testAppend() throws IOException {
+ buildRule.executeTarget("append");
+ assertTrue(FILE_UTILS
+ .contentEquals(buildRule.getProject().resolveFile(REC_IN
+ + "rectest2.result"),
+ new File(buildRule.getOutputDir(),
+ "rectest2.log"), true));
+ }
+
+ @Test
+ public void testRestart() throws IOException {
+ buildRule.executeTarget("restart");
+ assertTrue(FILE_UTILS
+ .contentEquals(buildRule.getProject().resolveFile(REC_IN
+ + "rectest3.result"),
+ new File(buildRule.getOutputDir(), "rectest3.log"), true));
+ }
+
+ @Test
+ public void testDeleteRestart() throws IOException {
+ buildRule.executeTarget("deleterestart");
+ assertTrue(FILE_UTILS
+ .contentEquals(buildRule.getProject().resolveFile(REC_IN
+ + "rectest4.result"),
+ new File(buildRule.getOutputDir(),
+ "rectest4.log"), true));
+ }
+
+ @Test
+ public void testSubBuild() throws IOException {
+ buildRule.executeTarget("subbuild");
+ assertTrue(FILE_UTILS
+ .contentEquals(buildRule.getProject().resolveFile(REC_IN
+ + "rectest5.result"),
+ new File(buildRule.getOutputDir(), "rectest5.log"), true));
+ assertTrue(FILE_UTILS
+ .contentEquals(buildRule.getProject().resolveFile(REC_IN
+ + "rectest6.result"),
+ new File(buildRule.getOutputDir(), "rectest6.log"), true));
+
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/RenameTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/RenameTest.java
new file mode 100644
index 00000000..0cb13441
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/RenameTest.java
@@ -0,0 +1,88 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.BuildFileRule;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.fail;
+
+public class RenameTest {
+
+ @Rule
+ public final BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/rename.xml");
+ }
+
+ @Test
+ public void test1() {
+ try {
+ buildRule.executeTarget("test1");
+ fail("BuildException should have been thrown: required argument missing");
+ } catch (BuildException ex) {
+ //TODO assert value
+ }
+ }
+ @Test
+ public void test2() {
+ try {
+ buildRule.executeTarget("test2");
+ fail("BuildException should have been thrown: required argument missing");
+ } catch (BuildException ex) {
+ //TODO assert value
+ }
+ }
+ @Test
+ public void test3() {
+ try {
+ buildRule.executeTarget("test3");
+ fail("BuildException should have been thrown: required argument missing");
+ } catch (BuildException ex) {
+ //TODO assert value
+ }
+ }
+
+ @Test
+ @Ignore("Previously commented out")
+ public void test4() {
+ try {
+ buildRule.executeTarget("test4");
+ fail("BuildException should have been thrown: source and destination the same");
+ } catch (BuildException ex) {
+ //TODO assert value
+ }
+ }
+
+ @Test
+ @Ignore("Previously commented out")
+ public void test5() {
+ buildRule.executeTarget("test5");
+ }
+ @Test
+ public void test6() {
+ buildRule.executeTarget("test6");
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/ReplaceTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/ReplaceTest.java
new file mode 100644
index 00000000..387c54dc
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/ReplaceTest.java
@@ -0,0 +1,180 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import junit.framework.AssertionFailedError;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.BuildFileRule;
+import org.apache.tools.ant.util.FileUtils;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeTrue;
+
+/**
+ */
+public class ReplaceTest {
+
+ @Rule
+ public final BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/replace.xml");
+ buildRule.executeTarget("setUp");
+ }
+
+ @Test
+ public void test1() {
+ try {
+ buildRule.executeTarget("test1");
+ fail("BuildException expected: required argument not specified");
+ } catch (BuildException ex) {
+ //TODO assert value
+ }
+ }
+
+ @Test
+ public void test2() {
+ try {
+ buildRule.executeTarget("test2");
+ fail("BuildException expected: required argument not specified");
+ } catch (BuildException ex) {
+ //TODO assert value
+ }
+ }
+
+ @Test
+ public void test3() {
+ try {
+ buildRule.executeTarget("test3");
+ fail("BuildException expected: required argument not specified");
+ } catch (BuildException ex) {
+ //TODO assert value
+ }
+ }
+
+ @Test
+ public void test4() {
+ try {
+ buildRule.executeTarget("test4");
+ fail("BuildException expected: empty token not allowed");
+ } catch (BuildException ex) {
+ //TODO assert value
+ }
+ }
+
+ @Test
+ public void test5() {
+ buildRule.executeTarget("test5");
+ }
+
+ @Test
+ public void test6() {
+ try {
+ buildRule.executeTarget("test6");
+ fail("BuildException expected: required argument not specified");
+ } catch (BuildException ex) {
+ //TODO assert value
+ }
+ }
+
+ @Test
+ public void test7() {
+ try {
+ buildRule.executeTarget("test7");
+ fail("BuildException expected: empty token not allowed");
+ } catch (BuildException ex) {
+ //TODO assert value
+ }
+ }
+
+ @Test
+ public void test8() {
+ buildRule.executeTarget("test8");
+ }
+
+ @Test
+ public void test9() throws IOException {
+
+ buildRule.executeTarget("test9");
+ assertEqualContent(new File(buildRule.getOutputDir(), "result.txt"),
+ new File(buildRule.getOutputDir(), "output.txt"));
+ }
+
+ @Test
+ public void testNoPreserveLastModified() throws Exception {
+ buildRule.executeTarget("lastModifiedSetup");
+ File testFile = new File(buildRule.getOutputDir(), "test.txt");
+ assumeTrue("Could not change file modification time",
+ testFile.setLastModified(testFile.lastModified() - (FileUtils.getFileUtils().getFileTimestampGranularity() * 5)));
+ long ts1 = testFile.lastModified();
+ buildRule.executeTarget("testNoPreserve");
+ assertTrue(ts1 < new File(buildRule.getOutputDir(), "test.txt").lastModified());
+ }
+
+ @Test
+ public void testPreserveLastModified() throws Exception {
+ buildRule.executeTarget("lastModifiedSetup");
+ File testFile = new File(buildRule.getOutputDir(), "test.txt");
+ assumeTrue("Could not change file modification time",
+ testFile.setLastModified(testFile.lastModified() - (FileUtils.getFileUtils().getFileTimestampGranularity() * 5)));
+ long ts1 = testFile.lastModified();buildRule.executeTarget("testPreserve");
+ assertTrue(ts1 == new File(buildRule.getOutputDir(), "test.txt").lastModified());
+ }
+
+ public void assertEqualContent(File expect, File result)
+ throws AssertionFailedError, IOException {
+ if (!result.exists()) {
+ fail("Expected file "+result+" doesn\'t exist");
+ }
+
+ InputStream inExpect = null;
+ InputStream inResult = null;
+ try {
+ inExpect = new BufferedInputStream(new FileInputStream(expect));
+ inResult = new BufferedInputStream(new FileInputStream(result));
+
+ int expectedByte = inExpect.read();
+ while (expectedByte != -1) {
+ assertEquals(expectedByte, inResult.read());
+ expectedByte = inExpect.read();
+ }
+ assertEquals("End of file", -1, inResult.read());
+ } finally {
+ if (inResult != null) {
+ inResult.close();
+ }
+ if (inExpect != null) {
+ inExpect.close();
+ }
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/RmicAdvancedTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/RmicAdvancedTest.java
new file mode 100644
index 00000000..c9d25146
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/RmicAdvancedTest.java
@@ -0,0 +1,467 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.AntAssert;
+import org.apache.tools.ant.BuildFileRule;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.taskdefs.rmic.RmicAdapterFactory;
+import org.apache.tools.ant.taskdefs.rmic.DefaultRmicAdapter;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.fail;
+
+/**
+ * Date: 04-Aug-2004
+ * Time: 22:15:46
+ */
+public class RmicAdvancedTest {
+
+ private final static String TASKDEFS_DIR = "src/etc/testcases/taskdefs/rmic/";
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ /**
+ * The JUnit setup method
+ */
+ @Before
+ public void setUp() throws Exception {
+ buildRule.configureProject(TASKDEFS_DIR + "rmic.xml");
+ }
+
+ /**
+ * verify that "default" binds us to the default compiler
+ */
+ @Test
+ public void testDefault() throws Exception {
+ buildRule.executeTarget("testDefault");
+ }
+
+ /**
+ * verify that "default" binds us to the default compiler
+ */
+ @Test
+ public void testDefaultDest() throws Exception {
+ buildRule.executeTarget("testDefaultDest");
+ }
+
+ /**
+ * verify that "" binds us to the default compiler
+ */
+ @Test
+ public void testEmpty() throws Exception {
+ buildRule.executeTarget("testEmpty");
+ }
+
+ /**
+ * verify that "" binds us to the default compiler
+ */
+ @Test
+ public void testEmptyDest() throws Exception {
+ buildRule.executeTarget("testEmptyDest");
+ }
+
+ /**
+ * test sun's rmic compiler
+ */
+ @Test
+ public void testRmic() throws Exception {
+ buildRule.executeTarget("testRmic");
+ }
+
+ /**
+ * test sun's rmic compiler
+ */
+ @Test
+ public void testRmicDest() throws Exception {
+ buildRule.executeTarget("testRmicDest");
+ }
+
+ /**
+ * test sun's rmic compiler strips
+ * out -J arguments when not forking
+ */
+ @Test
+ public void testRmicJArg() throws Exception {
+ buildRule.executeTarget("testRmicJArg");
+ }
+
+ /**
+ * test sun's rmic compiler strips
+ * out -J arguments when not forking
+ */
+ @Test
+ public void testRmicJArgDest() throws Exception {
+ buildRule.executeTarget("testRmicJArgDest");
+ }
+
+ /**
+ * A unit test for JUnit
+ */
+ @Test
+ public void testKaffe() throws Exception {
+ buildRule.executeTarget("testKaffe");
+ }
+
+ /**
+ * A unit test for JUnit
+ */
+ @Test
+ public void testKaffeDest() throws Exception {
+ buildRule.executeTarget("testKaffeDest");
+ }
+
+ // WLrmic tests don't work
+ /**
+ * test weblogic
+ */
+ @Test
+ @Ignore("WLRmin tests don't work")
+ public void XtestWlrmic() throws Exception {
+ buildRule.executeTarget("testWlrmic");
+ }
+
+ /**
+ * test weblogic's stripping of -J args
+ */
+ @Test
+ @Ignore("WLRmin tests don't work")
+ public void XtestWlrmicJArg() throws Exception {
+ buildRule.executeTarget("testWlrmicJArg");
+ }
+
+ /**
+ * test the forking compiler
+ */
+ @Test
+ @Ignore("WLRmin tests don't work")
+ public void NotestForking() throws Exception {
+ buildRule.executeTarget("testForking");
+ }
+
+ /**
+ * test the forking compiler
+ */
+ @Test
+ public void testForkingAntClasspath() throws Exception {
+ buildRule.executeTarget("testForkingAntClasspath");
+ }
+
+ /**
+ * test the forking compiler
+ */
+ @Test
+ public void testForkingAntClasspathDest() throws Exception {
+ buildRule.executeTarget("testForkingAntClasspathDest");
+ }
+
+ /**
+ * test the forking compiler
+ */
+ @Test
+ public void testAntClasspath() throws Exception {
+ buildRule.executeTarget("testAntClasspath");
+ }
+
+ /**
+ * test the forking compiler
+ */
+ @Test
+ public void testAntClasspathDest() throws Exception {
+ buildRule.executeTarget("testAntClasspathDest");
+ }
+
+ /**
+ * A unit test for JUnit
+ */
+ @Test
+ public void testBadName() throws Exception {
+ try {
+ buildRule.executeTarget("testBadName");
+ fail("Compile not known");
+ } catch (BuildException ex) {
+ AntAssert.assertContains(RmicAdapterFactory.ERROR_UNKNOWN_COMPILER, ex.getMessage());
+ }
+ }
+
+ /**
+ * load an adapter by name
+ */
+ @Test
+ public void testExplicitClass() throws Exception {
+ buildRule.executeTarget("testExplicitClass");
+ }
+
+ /**
+ * A unit test for JUnit
+ */
+ @Test
+ public void testWrongClass() throws Exception {
+ try {
+ buildRule.executeTarget("testWrongClass");
+ fail("Class not an RMIC adapter");
+ } catch (BuildException ex) {
+ AntAssert.assertContains(RmicAdapterFactory.ERROR_NOT_RMIC_ADAPTER, ex.getMessage());
+ }
+ }
+
+
+ /**
+ * A unit test for JUnit
+ */
+ @Test
+ public void testDefaultBadClass() throws Exception {
+ try {
+ buildRule.executeTarget("testDefaultBadClass");
+ fail("expected the class to fail");
+ } catch(BuildException ex) {
+ AntAssert.assertContains(Rmic.ERROR_RMIC_FAILED, ex.getMessage());
+ }
+ //dont look for much text here as it is vendor and version dependent
+ AntAssert.assertContains("unimplemented.class", buildRule.getLog());
+ }
+
+
+ /**
+ * A unit test for JUnit
+ */
+ @Test
+ public void testMagicProperty() throws Exception {
+ try {
+ buildRule.executeTarget("testMagicProperty");
+ fail("Magic property not working");
+ } catch (BuildException ex) {
+ AntAssert.assertContains(RmicAdapterFactory.ERROR_UNKNOWN_COMPILER, ex.getMessage());
+ }
+ }
+
+ /**
+ * A unit test for JUnit
+ */
+ @Test
+ public void testMagicPropertyOverridesEmptyString() throws Exception {
+ try {
+ buildRule.executeTarget("testMagicPropertyOverridesEmptyString");
+ fail("Magic property not working");
+ } catch (BuildException ex) {
+ AntAssert.assertContains(RmicAdapterFactory.ERROR_UNKNOWN_COMPILER, ex.getMessage());
+ }
+ }
+
+
+ @Test
+ public void testMagicPropertyIsEmptyString() throws Exception {
+ buildRule.executeTarget("testMagicPropertyIsEmptyString");
+ }
+
+
+ @Test
+ @Ignore("Previously named to prevent execution")
+ public void NotestFailingAdapter() throws Exception {
+ try {
+ buildRule.executeTarget("testFailingAdapter");
+ fail("Expected failures to propogate");
+ } catch (BuildException ex) {
+ AntAssert.assertContains(Rmic.ERROR_RMIC_FAILED, ex.getMessage());
+ }
+ }
+
+
+ /**
+ * test that version 1.1 stubs are good
+ * @throws Exception
+ */
+ @Test
+ public void testVersion11() throws Exception {
+ buildRule.executeTarget("testVersion11");
+ }
+
+ /**
+ * test that version 1.1 stubs are good
+ * @throws Exception
+ */
+ @Test
+ public void testVersion11Dest() throws Exception {
+ buildRule.executeTarget("testVersion11Dest");
+ }
+
+ /**
+ * test that version 1.2 stubs are good
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testVersion12() throws Exception {
+ buildRule.executeTarget("testVersion12");
+ }
+
+ /**
+ * test that version 1.2 stubs are good
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testVersion12Dest() throws Exception {
+ buildRule.executeTarget("testVersion12Dest");
+ }
+
+ /**
+ * test that version compat stubs are good
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testVersionCompat() throws Exception {
+ buildRule.executeTarget("testVersionCompat");
+ }
+
+ /**
+ * test that version compat stubs are good
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testVersionCompatDest() throws Exception {
+ buildRule.executeTarget("testVersionCompatDest");
+ }
+
+ /**
+ * test that passes -Xnew to sun's rmic.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testXnew() throws Exception {
+ buildRule.executeTarget("testXnew");
+ }
+
+ /**
+ * test that passes -Xnew to sun's rmic.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testXnewDest() throws Exception {
+ buildRule.executeTarget("testXnewDest");
+ }
+
+ /**
+ * test that passes -Xnew to sun's rmic running in a different VM.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testXnewForked() throws Exception {
+ buildRule.executeTarget("testXnewForked");
+ }
+
+ /**
+ * test that passes -Xnew to sun's rmic running in a different VM.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testXnewForkedDest() throws Exception {
+ buildRule.executeTarget("testXnewForkedDest");
+ }
+
+ /**
+ * test that runs the new xnew compiler adapter.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testXnewCompiler() throws Exception {
+ buildRule.executeTarget("testXnewCompiler");
+ }
+
+ /**
+ * test that runs the new xnew compiler adapter.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testXnewCompilerDest() throws Exception {
+ buildRule.executeTarget("testXnewCompilerDest");
+ }
+
+ /**
+ * test that verifies that IDL compiles.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testIDL() throws Exception {
+ buildRule.executeTarget("testIDL");
+ }
+
+ /**
+ * test that verifies that IDL compiles.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testIDLDest() throws Exception {
+ buildRule.executeTarget("testIDLDest");
+ }
+
+ /**
+ * test that verifies that IIOP compiles.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testIIOP() throws Exception {
+ buildRule.executeTarget("testIIOP");
+ }
+
+ /**
+ * test that verifies that IIOP compiles.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testIIOPDest() throws Exception {
+ buildRule.executeTarget("testIIOPDest");
+ }
+
+ /**
+ * this little bunny verifies that we can load stuff, and that
+ * a failure to execute is turned into a fault
+ */
+ public static class FailingRmicAdapter extends DefaultRmicAdapter {
+ public static final String LOG_MESSAGE = "hello from FailingRmicAdapter";
+
+ /**
+ * Executes the task.
+ *
+ * @return false -always
+ */
+ public boolean execute() throws BuildException {
+ getRmic().log(LOG_MESSAGE);
+ return false;
+ }
+ }
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/RmicTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/RmicTest.java
new file mode 100644
index 00000000..8d3200c3
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/RmicTest.java
@@ -0,0 +1,104 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.Project;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+
+/**
+ * Testcase for <rmic>.
+ *
+ * @since Ant 1.5
+ */
+public class RmicTest {
+
+ private Project project;
+ private Rmic rmic;
+
+ @Before
+ public void setUp() {
+ project = new Project();
+ project.init();
+ rmic = new Rmic();
+ rmic.setProject(project);
+ }
+
+ /**
+ * Test nested compiler args.
+ */
+ @Test
+ public void testCompilerArg() {
+ String[] args = rmic.getCurrentCompilerArgs();
+ assertNotNull(args);
+ assertEquals("no args", 0, args.length);
+
+ Rmic.ImplementationSpecificArgument arg = rmic.createCompilerArg();
+ String ford = "Ford";
+ String prefect = "Prefect";
+ String testArg = ford + " " + prefect;
+ arg.setValue(testArg);
+ args = rmic.getCurrentCompilerArgs();
+ assertEquals("unconditional single arg", 1, args.length);
+ assertEquals(testArg, args[0]);
+
+ arg.setCompiler("weblogic");
+ args = rmic.getCurrentCompilerArgs();
+ assertNotNull(args);
+ assertEquals("implementation is weblogic but build.rmic is null",
+ 0, args.length);
+
+ project.setProperty("build.rmic", "sun");
+ args = rmic.getCurrentCompilerArgs();
+ assertNotNull(args);
+ assertEquals("implementation is weblogic but build.rmic is sun",
+ 0, args.length);
+
+ project.setProperty("build.rmic", "weblogic");
+ args = rmic.getCurrentCompilerArgs();
+ assertEquals("both are weblogic", 1, args.length);
+ assertEquals(testArg, args[0]);
+ }
+
+ /**
+ * Test compiler attribute.
+ */
+ @Test
+ public void testCompilerAttribute() {
+ // check defaults
+ String compiler = rmic.getCompiler();
+ assertNotNull(compiler);
+ assertEquals("expected sun or kaffe, but found "+compiler,compiler,"default");
+
+ project.setNewProperty("build.rmic", "weblogic");
+ compiler = rmic.getCompiler();
+ assertNotNull(compiler);
+ assertEquals("weblogic", compiler);
+
+ // check attribute overrides build.compiler
+ rmic.setCompiler("kaffe");
+ compiler = rmic.getCompiler();
+ assertNotNull(compiler);
+ assertEquals("kaffe", compiler);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/SQLExecTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/SQLExecTest.java
new file mode 100644
index 00000000..fbce8a6d
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/SQLExecTest.java
@@ -0,0 +1,326 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs;
+
+import java.sql.Driver;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.sql.DriverPropertyInfo;
+import java.util.Properties;
+import java.io.File;
+import java.net.URL;
+import java.util.logging.Logger;
+
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.BuildException;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import static org.apache.tools.ant.AntAssert.assertContains;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+/**
+ * Simple testcase to test for driver caching.
+ * To test for your own database, you may need to tweak getProperties(int)
+ * and add a couple of keys. see testOracle and testMySQL for an example.
+ *
+ * It would be much better to extend this testcase by using HSQL
+ * as the test db, so that a db is really used.
+ *
+ */
+public class SQLExecTest {
+
+ // some database keys, see #getProperties(int)
+ public final static int NULL = 0;
+ public final static int ORACLE = 1;
+ public final static int MYSQL = 2;
+
+ // keys used in properties.
+ public final static String DRIVER = "driver";
+ public final static String USER = "user";
+ public final static String PASSWORD = "password";
+ public final static String URL = "url";
+ public final static String PATH = "path";
+ public final static String SQL = "sql";
+
+ @Before
+ public void setUp() throws Exception {
+ // make sure the cache is cleared.
+ JDBCTask.getLoaderMap().clear();
+ }
+
+ // simple test to ensure that the caching does work...
+ @Test
+ public void testDriverCaching(){
+ SQLExec sql = createTask(getProperties(NULL));
+ assertTrue(!SQLExec.getLoaderMap().containsKey(NULL_DRIVER));
+ try {
+ sql.execute();
+ fail("BuildException should have been thrown");
+ } catch (BuildException e){
+ assertContains("No suitable Driver", e.getMessage());
+ }
+ assertTrue(SQLExec.getLoaderMap().containsKey(NULL_DRIVER));
+ assertSame(sql.getLoader(), JDBCTask.getLoaderMap().get(NULL_DRIVER));
+ ClassLoader loader1 = sql.getLoader();
+
+ // 2nd run..
+ sql = createTask(getProperties(NULL));
+ // the driver must still be cached.
+ assertTrue(JDBCTask.getLoaderMap().containsKey(NULL_DRIVER));
+ try {
+ sql.execute();
+ } catch (BuildException e){
+ assertTrue(e.getCause().getMessage().indexOf("No suitable Driver") != -1);
+ }
+ assertTrue(JDBCTask.getLoaderMap().containsKey(NULL_DRIVER));
+ assertSame(sql.getLoader(), JDBCTask.getLoaderMap().get(NULL_DRIVER));
+ assertSame(loader1, sql.getLoader());
+ }
+
+ @Test
+ public void testNull() throws Exception {
+ doMultipleCalls(1000, NULL, true, true);
+ }
+
+ @Ignore
+ @Test
+ public void testOracle(){
+ doMultipleCalls(1000, ORACLE, true, false);
+ }
+
+ @Ignore
+ @Test
+ public void testMySQL(){
+ doMultipleCalls(1000, MYSQL, true, false);
+ }
+
+
+ /**
+ * run a sql tasks multiple times.
+ * @param calls number of times to execute the task
+ * @param database the database to execute on.
+ * @param caching should caching be enabled ?
+ * @param catchexception true to catch exception for each call, false if not.
+ */
+ protected void doMultipleCalls(int calls, int database, boolean caching, boolean catchexception){
+ Properties props = getProperties(database);
+ for (int i = 0; i < calls; i++){
+ SQLExec sql = createTask(props);
+ sql.setCaching(caching);
+ try {
+ sql.execute();
+ } catch (BuildException e){
+ if (!catchexception){
+ throw e;
+ }
+ }
+ }
+ }
+
+ /**
+ * Create a task from a set of properties
+ * @see #getProperties(int)
+ */
+ protected SQLExec createTask(Properties props){
+ SQLExec sql = new SQLExec();
+ sql.setProject( new Project() );
+ sql.setDriver( props.getProperty(DRIVER) );
+ sql.setUserid( props.getProperty(USER) );
+ sql.setPassword( props.getProperty(PASSWORD) );
+ sql.setUrl( props.getProperty(URL) );
+ sql.createClasspath().setLocation( new File(props.getProperty(PATH)) );
+ sql.addText( props.getProperty(SQL) );
+ return sql;
+ }
+
+ /**
+ * try to find the path from a resource (jar file or directory name)
+ * so that it can be used as a classpath to load the resource.
+ */
+ protected String findResourcePath(String resource){
+ resource = resource.replace('.', '/') + ".class";
+ URL url = getClass().getClassLoader().getResource(resource);
+ if (url == null) {
+ return null;
+ }
+ String u = url.toString();
+ if (u.startsWith("jar:file:")) {
+ int pling = u.indexOf("!");
+ return u.substring("jar:file:".length(), pling);
+ } else if (u.startsWith("file:")) {
+ int tail = u.indexOf(resource);
+ return u.substring("file:".length(), tail);
+ }
+ return null;
+ }
+
+ /**
+ * returns a configuration associated to a specific database.
+ * If you want to test on your specific base, you'd better
+ * tweak this to make it run or add your own database.
+ * The driver lib should be dropped into the system classloader.
+ */
+ protected Properties getProperties(int database){
+ Properties props = null;
+ switch (database){
+ case ORACLE:
+ props = getProperties("oracle.jdbc.driver.OracleDriver", "test", "test", "jdbc:oracle:thin:@127.0.0.1:1521:orcl");
+ break;
+ case MYSQL:
+ props = getProperties("org.gjt.mm.mysql.Driver", "test", "test", "jdbc:mysql://127.0.0.1:3306/test");
+ break;
+ case NULL:
+ default:
+ props = getProperties(NULL_DRIVER, "test", "test", "jdbc:database://hostname:port/name");
+ }
+ // look for the driver path...
+ String path = findResourcePath(props.getProperty(DRIVER));
+ props.put(PATH, path);
+ props.put(SQL, "create table OOME_TEST(X INTEGER NOT NULL);\ndrop table if exists OOME_TEST;");
+ return props;
+ }
+
+ /** helper method to build properties */
+ protected Properties getProperties(String driver, String user, String pwd, String url){
+ Properties props = new Properties();
+ props.put(DRIVER, driver);
+ props.put(USER, user);
+ props.put(PASSWORD, pwd);
+ props.put(URL, url);
+ return props;
+ }
+
+
+//--- NULL JDBC driver just for simple test since there are no db driver
+// available as a default in Ant :)
+
+ public final static String NULL_DRIVER = NullDriver.class.getName();
+
+ public static class NullDriver implements Driver {
+ public Connection connect(String url, Properties info)
+ throws SQLException {
+ return null;
+ }
+
+ public boolean acceptsURL(String url) throws SQLException {
+ return false;
+ }
+
+ public DriverPropertyInfo[] getPropertyInfo(String url, Properties info)
+ throws SQLException {
+ return new DriverPropertyInfo[0];
+ }
+
+ public int getMajorVersion() {
+ return 0;
+ }
+
+ public int getMinorVersion() {
+ return 0;
+ }
+
+ public boolean jdbcCompliant() {
+ return false;
+ }
+
+ public Logger getParentLogger() /*throws SQLFeatureNotSupportedException*/ {
+ return Logger.getAnonymousLogger();
+ }
+ }
+
+ @Test
+ public void testLastDelimiterPositionNormalModeStrict() {
+ SQLExec s = new SQLExec();
+ assertEquals(-1,
+ s.lastDelimiterPosition(new StringBuffer(), null));
+ assertEquals(-1,
+ s.lastDelimiterPosition(new StringBuffer("GO"), null));
+ assertEquals(-1,
+ s.lastDelimiterPosition(new StringBuffer("; "), null));
+ assertEquals(2,
+ s.lastDelimiterPosition(new StringBuffer("ab;"), null));
+ s.setDelimiter("GO");
+ assertEquals(-1,
+ s.lastDelimiterPosition(new StringBuffer("GO "), null));
+ assertEquals(-1,
+ s.lastDelimiterPosition(new StringBuffer("go"), null));
+ assertEquals(0,
+ s.lastDelimiterPosition(new StringBuffer("GO"), null));
+ }
+
+ @Test
+ public void testLastDelimiterPositionNormalModeNonStrict() {
+ SQLExec s = new SQLExec();
+ s.setStrictDelimiterMatching(false);
+ assertEquals(-1,
+ s.lastDelimiterPosition(new StringBuffer(), null));
+ assertEquals(-1,
+ s.lastDelimiterPosition(new StringBuffer("GO"), null));
+ assertEquals(0,
+ s.lastDelimiterPosition(new StringBuffer("; "), null));
+ assertEquals(2,
+ s.lastDelimiterPosition(new StringBuffer("ab;"), null));
+ s.setDelimiter("GO");
+ assertEquals(0,
+ s.lastDelimiterPosition(new StringBuffer("GO "), null));
+ assertEquals(0,
+ s.lastDelimiterPosition(new StringBuffer("go"), null));
+ assertEquals(0,
+ s.lastDelimiterPosition(new StringBuffer("GO"), null));
+ }
+
+ @Test
+ public void testLastDelimiterPositionRowModeStrict() {
+ SQLExec s = new SQLExec();
+ SQLExec.DelimiterType t = new SQLExec.DelimiterType();
+ t.setValue("row");
+ s.setDelimiterType(t);
+ assertEquals(-1, s.lastDelimiterPosition(null, ""));
+ assertEquals(-1, s.lastDelimiterPosition(null, "GO"));
+ assertEquals(-1, s.lastDelimiterPosition(null, "; "));
+ assertEquals(1, s.lastDelimiterPosition(new StringBuffer("ab"), ";"));
+ s.setDelimiter("GO");
+ assertEquals(-1, s.lastDelimiterPosition(null, "GO "));
+ assertEquals(-1, s.lastDelimiterPosition(null, "go"));
+ assertEquals(0, s.lastDelimiterPosition(new StringBuffer("ab"), "GO"));
+ }
+
+ @Test
+ public void testLastDelimiterPositionRowModeNonStrict() {
+ SQLExec s = new SQLExec();
+ SQLExec.DelimiterType t = new SQLExec.DelimiterType();
+ t.setValue("row");
+ s.setDelimiterType(t);
+ s.setStrictDelimiterMatching(false);
+ assertEquals(-1, s.lastDelimiterPosition(null, ""));
+ assertEquals(-1, s.lastDelimiterPosition(null, "GO"));
+ assertEquals(0, s.lastDelimiterPosition(new StringBuffer("; "), "; "));
+ assertEquals(1, s.lastDelimiterPosition(new StringBuffer("ab"), ";"));
+ s.setDelimiter("GO");
+ assertEquals(1,
+ s.lastDelimiterPosition(new StringBuffer("abcd"), "GO "));
+ assertEquals(0, s.lastDelimiterPosition(new StringBuffer("go"), "go"));
+ assertEquals(0, s.lastDelimiterPosition(new StringBuffer("ab"), "GO"));
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/SignJarTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/SignJarTest.java
new file mode 100644
index 00000000..95585fde
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/SignJarTest.java
@@ -0,0 +1,139 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.io.File;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.BuildFileRule;
+import org.apache.tools.ant.util.JavaEnvUtils;
+import org.junit.Assume;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+/**
+ * Testcase for the Signjar task
+ *
+ */
+public class SignJarTest {
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/signjar.xml");
+ }
+
+ /**
+ * check for being offline
+ * @return true if the system property "offline" is "true"
+ */
+ private boolean isOffline() {
+ return Boolean.getBoolean("offline");
+ }
+
+ @Test
+ public void testSigFile() {
+ buildRule.executeTarget("sigfile");
+ SignJarChild sj = new SignJarChild();
+ sj.setAlias("testonly");
+ sj.setKeystore("testkeystore");
+ sj.setStorepass("apacheant");
+ File jar = new File(buildRule.getProject().getProperty("test.jar"));
+ sj.setJar(jar);
+ assertFalse("mustn't find signature without sigfile attribute",
+ sj.isSigned());
+ sj.setSigfile("TEST");
+ assertTrue("must find signature with sigfile attribute",
+ sj.isSigned());
+ }
+
+ @Test
+ public void testInvalidChars() {
+ buildRule.executeTarget("invalidchars");
+ SignJarChild sj = new SignJarChild();
+ sj.setAlias("test@nly");
+ sj.setKeystore("testkeystore");
+ sj.setStorepass("apacheant");
+ File jar = new File(buildRule.getProject().getProperty("test.jar"));
+ sj.setJar(jar);
+ assertTrue(sj.isSigned());
+ }
+
+ /**
+ * subclass in order to get access to protected isSigned method if
+ * tests and task come from different classloaders.
+ */
+ private static class SignJarChild extends SignJar {
+ public boolean isSigned() {
+ return isSigned(jar);
+ }
+ }
+
+ @Test
+ public void testURLKeystoreFile() {
+ buildRule.executeTarget("urlKeystoreFile");
+ }
+
+ @Test
+ public void testURLKeystoreHTTP() {
+ Assume.assumeFalse("Test is set offline", isOffline());
+ buildRule.executeTarget("urlKeystoreHTTP");
+ }
+
+ @Test
+ public void testTsaLocalhost() {
+ Assume.assumeTrue("Only runs on Java 1.5+", JavaEnvUtils.getJavaVersionNumber()>=15);
+ try {
+ buildRule.executeTarget("testTsaLocalhost");
+ fail("Should have thrown exception - no TSA at localhost:0");
+ } catch(BuildException ex) {
+ assertEquals("jarsigner returned: 1", ex.getMessage());
+ }
+ }
+
+ /**
+ * @see <a href="https://issues.apache.org/bugzilla/show_bug.cgi?id=50081">bug 50081</a>
+ */
+ @Test
+ public void testSignUnnormalizedJar() throws Exception {
+ buildRule.executeTarget("jar");
+ File testJar = new File(buildRule.getProject().getProperty("test.jar"));
+ File testJarParent = testJar.getParentFile();
+ File f = new File(testJarParent,
+ "../" + testJarParent.getName() + "/"
+ + testJar.getName());
+ assertFalse(testJar.equals(f));
+ assertEquals(testJar.getCanonicalPath(), f.getCanonicalPath());
+ SignJar s = new SignJar();
+ s.setProject(buildRule.getProject());
+ s.setJar(f);
+ s.setAlias("testonly");
+ s.setStorepass("apacheant");
+ s.setKeystore("testkeystore");
+ s.execute();
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/SleepTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/SleepTest.java
new file mode 100644
index 00000000..d1487df9
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/SleepTest.java
@@ -0,0 +1,120 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.BuildFileRule;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+public class SleepTest {
+
+ @Rule
+ public final BuildFileRule buildRule = new BuildFileRule();
+
+ private final static String TASKDEFS_DIR = "src/etc/testcases/taskdefs/";
+ private final static int ERROR_RANGE=1000;
+
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject(TASKDEFS_DIR + "sleep.xml");
+ }
+
+ @Test
+ public void test1() {
+ Timer timer=new Timer();
+ buildRule.executeTarget("test1");
+ timer.stop();
+ assertTrue(timer.time()>=0);
+ }
+
+ @Test
+ public void test2() {
+ Timer timer=new Timer();
+ buildRule.executeTarget("test2");
+ timer.stop();
+ assertTrue(timer.time()>=0);
+ }
+
+ @Test
+ public void test3() {
+ Timer timer=new Timer();
+ buildRule.executeTarget("test3");
+ timer.stop();
+ assertTrue(timer.time()>=(2000-ERROR_RANGE));
+ }
+
+ @Test
+ public void test4() {
+ Timer timer=new Timer();
+ buildRule.executeTarget("test3");
+ timer.stop();
+ assertTrue(timer.time()>=(2000-ERROR_RANGE) && timer.time()<60000);
+ }
+
+ @Test
+ public void test5() {
+ try {
+ buildRule.executeTarget("test5");
+ fail("Negative sleep periods are not supported");
+ } catch (BuildException ex) {
+ //TODO assert value
+ }
+ }
+
+ @Test
+ public void test6() {
+ Timer timer=new Timer();
+ buildRule.executeTarget("test6");
+ timer.stop();
+ assertTrue(timer.time()<2000);
+ }
+
+
+ /**
+ * inner timer class
+ */
+ private static class Timer {
+ long start=0;
+ long stop=0;
+
+ public Timer() {
+ start();
+ }
+
+ public void start() {
+ start=System.currentTimeMillis();
+ }
+
+ public void stop() {
+ stop=System.currentTimeMillis();
+ }
+
+ public long time() {
+ return stop-start;
+ }
+ }
+
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/StyleTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/StyleTest.java
new file mode 100644
index 00000000..24c4e9de
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/StyleTest.java
@@ -0,0 +1,225 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs;
+
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.BuildFileRule;
+import org.apache.tools.ant.FileUtilities;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+
+/**
+ * TestCases for {@link XSLTProcess} task.
+ * TODO merge with {@link org.apache.tools.ant.taskdefs.optional.XsltTest}?
+ * @version 2003-08-05
+ */
+public class StyleTest {
+
+ @Rule
+ public final BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() throws Exception {
+ buildRule.configureProject("src/etc/testcases/taskdefs/style/build.xml");
+ }
+
+ @Test
+ public void testStyleIsSet() throws Exception {
+
+ try {
+ buildRule.executeTarget("testStyleIsSet");
+ fail("Must throws a BuildException: no stylesheet specified");
+ } catch (BuildException ex) {
+ assertEquals("specify the stylesheet either as a filename in style attribute or as a nested resource",
+ ex.getMessage());
+ }
+ }
+
+ @Test
+ public void testTransferParameterSet() throws Exception {
+ expectFileContains("testTransferParameterSet", // target
+ buildRule.getOutputDir().getAbsoluteFile() + "/out.xml", // file
+ "set='myvalue'"); // exptected string
+ }
+
+ @Test
+ public void testTransferParameterEmpty() throws Exception {
+ expectFileContains("testTransferParameterEmpty",
+ buildRule.getOutputDir().getAbsoluteFile() + "/out.xml",
+ "empty=''");
+ }
+
+ @Test
+ public void testTransferParameterUnset() throws Exception {
+ expectFileContains("testTransferParameterUnset",
+ buildRule.getOutputDir().getAbsoluteFile() + "/out.xml",
+ "undefined='${value}'");
+ }
+
+ @Test
+ public void testTransferParameterUnsetWithIf() throws Exception {
+ expectFileContains("testTransferParameterUnsetWithIf",
+ buildRule.getOutputDir().getAbsoluteFile() + "/out.xml",
+ "undefined='undefined default value'");
+ }
+
+ @Test
+ public void testNewerStylesheet() throws Exception {
+ expectFileContains("testNewerStylesheet",
+ buildRule.getOutputDir().getAbsoluteFile() + "/out.xml",
+ "new-value");
+ }
+
+ @Test
+ public void testDefaultMapper() throws Exception {
+ testDefaultMapper("testDefaultMapper");
+ }
+
+ @Test
+ public void testExplicitFileset() throws Exception {
+ testDefaultMapper("testExplicitFileset");
+ }
+
+ public void testDefaultMapper(String target) throws Exception {
+ assertTrue(!(
+ new File(buildRule.getOutputDir().getAbsoluteFile(), "data.html").exists()));
+ expectFileContains(target,
+ buildRule.getOutputDir().getAbsoluteFile() + "/data.html",
+ "set='myvalue'");
+ }
+
+ @Test
+ public void testCustomMapper() throws Exception {
+ assertTrue(!new File(buildRule.getOutputDir().getAbsoluteFile(), "out.xml").exists());
+ expectFileContains("testCustomMapper",
+ buildRule.getOutputDir().getAbsoluteFile() + "/out.xml",
+ "set='myvalue'");
+ }
+
+ @Test
+ public void testTypedMapper() throws Exception {
+ assertTrue(!new File(buildRule.getOutputDir().getAbsoluteFile(), "out.xml").exists());
+ expectFileContains("testTypedMapper",
+ buildRule.getOutputDir().getAbsoluteFile() + "/out.xml",
+ "set='myvalue'");
+ }
+
+ @Test
+ public void testDirectoryHierarchyWithDirMatching() throws Exception {
+ buildRule.executeTarget("testDirectoryHierarchyWithDirMatching");
+ assertTrue(new File(buildRule.getOutputDir().getAbsoluteFile(), "dest/level1/data.html")
+ .exists());
+ }
+
+ @Test
+ public void testDirsWithSpaces() throws Exception {
+ buildRule.executeTarget("testDirsWithSpaces");
+ assertTrue(new File(buildRule.getOutputDir().getAbsoluteFile(), "d est/data.html")
+ .exists());
+ }
+
+ @Test
+ public void testWithStyleAttrAndResource() {
+ try {
+ buildRule.executeTarget("testWithStyleAttrAndResource");
+ fail("Must throws a BuildException");
+ } catch (BuildException ex) {
+ assertEquals("specify the stylesheet either as a filename in style attribute or as a "
+ + "nested resource but not as both", ex.getMessage());
+ }
+ }
+
+ @Test
+ public void testWithFileResource() throws Exception {
+ expectFileContains("testWithFileResource", buildRule.getOutputDir().getAbsoluteFile() + "/out.xml", "set='value'");
+ }
+
+ @Test
+ public void testWithUrlResource() throws Exception {
+ expectFileContains("testWithUrlResource", buildRule.getOutputDir().getAbsoluteFile() + "/out.xml", "set='value'");
+ }
+
+ @Test
+ public void testFilenameAsParam() throws Exception {
+ buildRule.executeTarget("testFilenameAsParam");
+ assertFileContains(buildRule.getOutputDir().getAbsoluteFile() + "/one.txt", "filename='one.xml'");
+ assertFileContains(buildRule.getOutputDir().getAbsoluteFile() + "/two.txt", "filename='two.xml'");
+ assertFileContains(buildRule.getOutputDir().getAbsoluteFile() + "/three.txt", "filename='three.xml'");
+ assertFileContains(buildRule.getOutputDir().getAbsoluteFile() + "/dir/four.txt", "filename='four.xml'");
+ assertFileContains(buildRule.getOutputDir().getAbsoluteFile() + "/dir/four.txt", "filedir ='-not-set-'");
+ }
+
+ @Test
+ public void testFilenameAsParamNoSetting() throws Exception {
+ buildRule.executeTarget("testFilenameAsParamNoSetting");
+ assertFileContains(buildRule.getOutputDir().getAbsoluteFile() + "/one.txt", "filename='-not-set-'");
+ assertFileContains(buildRule.getOutputDir().getAbsoluteFile() + "/two.txt", "filename='-not-set-'");
+ assertFileContains(buildRule.getOutputDir().getAbsoluteFile() + "/three.txt", "filename='-not-set-'");
+ assertFileContains(buildRule.getOutputDir().getAbsoluteFile() + "/dir/four.txt", "filename='-not-set-'");
+ }
+
+ @Test
+ public void testFilenameAndFiledirAsParam() throws Exception {
+ buildRule.executeTarget("testFilenameAndFiledirAsParam");
+ assertFileContains(buildRule.getOutputDir().getAbsoluteFile() + "/one.txt", "filename='one.xml'");
+ assertFileContains(buildRule.getOutputDir().getAbsoluteFile() + "/one.txt", "filedir ='.'");
+ assertFileContains(buildRule.getOutputDir().getAbsoluteFile() + "/dir/four.txt", "filename='four.xml'");
+ assertFileContains(buildRule.getOutputDir().getAbsoluteFile() + "/dir/four.txt", "filedir ='dir'");
+ }
+
+
+ // ************* copied from ConcatTest *************
+
+ // ------------------------------------------------------
+ // Helper methods - should be in BuildFileTest
+ // -----------------------------------------------------
+
+ private String getFileString(String filename)
+ throws IOException
+ {
+ return FileUtilities.getFileContents(new File(filename));
+ }
+
+ private void expectFileContains(
+ String target, String filename, String contains)
+ throws IOException
+ {
+ buildRule.executeTarget(target);
+ assertFileContains(filename, contains);
+ }
+
+ private void assertFileContains(String filename, String contains) throws IOException {
+ String content = getFileString(filename);
+ assertTrue(
+ "expecting file " + filename
+ + " to contain " + contains
+ + " but got " + content,
+ content.indexOf(contains) > -1);
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/SubAntTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/SubAntTest.java
new file mode 100644
index 00000000..58ee4f3e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/SubAntTest.java
@@ -0,0 +1,161 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.io.File;
+
+import junit.framework.AssertionFailedError;
+
+import org.apache.tools.ant.BuildEvent;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.BuildFileRule;
+import org.apache.tools.ant.BuildListener;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.apache.tools.ant.AntAssert.assertContains;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+
+public class SubAntTest {
+
+ @Rule
+ public final BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/subant.xml");
+ }
+
+ @Test
+ public void testnodirs() {
+ buildRule.executeTarget("testnodirs");
+ assertEquals("No sub-builds to iterate on",buildRule.getLog());
+ }
+
+ // target must be specified
+ @Test
+ public void testgenericantfile() {
+ File dir1 = buildRule.getProject().resolveFile(".");
+ File dir2 = buildRule.getProject().resolveFile("subant/subant-test1");
+ File dir3 = buildRule.getProject().resolveFile("subant/subant-test2");
+
+ testBaseDirs("testgenericantfile",
+ new String[] { dir1.getAbsolutePath(),
+ dir2.getAbsolutePath(),
+ dir3.getAbsolutePath()
+
+ });
+ }
+
+ @Test
+ public void testantfile() {
+ File dir1 = buildRule.getProject().resolveFile(".");
+ // basedir of subant/subant-test1/subant.xml is ..
+ // therefore we expect here the subant/subant-test1 subdirectory
+ File dir2 = buildRule.getProject().resolveFile("subant/subant-test1");
+ // basedir of subant/subant-test2/subant.xml is ..
+ // therefore we expect here the subant subdirectory
+ File dir3 = buildRule.getProject().resolveFile("subant");
+
+ testBaseDirs("testantfile",
+ new String[] { dir1.getAbsolutePath(),
+ dir2.getAbsolutePath(),
+ dir3.getAbsolutePath()
+
+ });
+
+ }
+
+ @Test
+ public void testMultipleTargets() {
+ buildRule.executeTarget("multipleTargets");
+ assertContains("test1-one", buildRule.getLog());
+ assertContains("test1-two", buildRule.getLog());
+ assertContains("test2-one", buildRule.getLog());
+ assertContains("test2-two", buildRule.getLog());
+ }
+
+ @Test
+ public void testMultipleTargetsOneDoesntExist_FOEfalse() {
+ buildRule.executeTarget("multipleTargetsOneDoesntExist_FOEfalse");
+ assertContains("Target \"three\" does not exist in the project \"subant\"", buildRule.getLog());
+ }
+
+ @Test
+ public void testMultipleTargetsOneDoesntExist_FOEtrue() {
+ try {
+ buildRule.executeTarget("multipleTargetsOneDoesntExist_FOEtrue");
+ fail("BuildException expected: Calling not existent target");
+ } catch (BuildException ex) {
+ assertContains("Target \"three\" does not exist in the project \"subant\"", ex.getMessage());
+ }
+ }
+
+ protected void testBaseDirs(String target, String[] dirs) {
+ SubAntTest.BasedirChecker bc = new SubAntTest.BasedirChecker(dirs);
+ buildRule.getProject().addBuildListener(bc);
+ buildRule.executeTarget(target);
+ AssertionFailedError ae = bc.getError();
+ if (ae != null) {
+ throw ae;
+ }
+ buildRule.getProject().removeBuildListener(bc);
+ }
+
+ private class BasedirChecker implements BuildListener {
+ private String[] expectedBasedirs;
+ private int calls = 0;
+ private AssertionFailedError error;
+
+ BasedirChecker(String[] dirs) {
+ expectedBasedirs = dirs;
+ }
+
+ public void buildStarted(BuildEvent event) {}
+ public void buildFinished(BuildEvent event) {}
+ public void targetFinished(BuildEvent event){}
+ public void taskStarted(BuildEvent event) {}
+ public void taskFinished(BuildEvent event) {}
+ public void messageLogged(BuildEvent event) {}
+
+ public void targetStarted(BuildEvent event) {
+ if (event.getTarget().getName().equals("")) {
+ return;
+ }
+ if (error == null) {
+ try {
+ assertEquals(expectedBasedirs[calls++],
+ event.getProject().getBaseDir().getAbsolutePath());
+ } catch (AssertionFailedError e) {
+ error = e;
+ }
+ }
+ }
+
+ AssertionFailedError getError() {
+ return error;
+ }
+
+ }
+
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/SyncTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/SyncTest.java
new file mode 100644
index 00000000..93431dcb
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/SyncTest.java
@@ -0,0 +1,148 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.BuildFileRule;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.apache.tools.ant.AntAssert.assertContains;
+import static org.junit.Assert.assertTrue;
+
+public class SyncTest {
+
+ @Rule
+ public final BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/sync.xml");
+ }
+
+ @Test
+ public void testSimpleCopy() {
+ buildRule.executeTarget("simplecopy");
+ String d = buildRule.getProject().getProperty("dest") + "/a/b/c/d";
+ assertFileIsPresent(d);
+ assertTrue(buildRule.getFullLog().indexOf("dangling") == -1);
+ }
+
+ @Test
+ public void testEmptyCopy() {
+ buildRule.executeTarget("emptycopy");
+ String d = buildRule.getProject().getProperty("dest") + "/a/b/c/d";
+ assertFileIsNotPresent(d);
+ String c = buildRule.getProject().getProperty("dest") + "/a/b/c";
+ assertFileIsNotPresent(c);
+ assertTrue(buildRule.getFullLog().indexOf("dangling") == -1);
+ }
+
+ @Test
+ public void testEmptyDirCopy() {
+ buildRule.executeTarget("emptydircopy");
+ String d = buildRule.getProject().getProperty("dest") + "/a/b/c/d";
+ assertFileIsNotPresent(d);
+ String c = buildRule.getProject().getProperty("dest") + "/a/b/c";
+ assertFileIsPresent(c);
+ assertTrue(buildRule.getFullLog().indexOf("dangling") == -1);
+ }
+
+ @Test
+ public void testCopyAndRemove() {
+ testCopyAndRemove("copyandremove");
+ }
+
+ @Test
+ public void testCopyAndRemoveWithFileList() {
+ testCopyAndRemove("copyandremove-with-filelist");
+ }
+
+ @Test
+ public void testCopyAndRemoveWithZipfileset() {
+ testCopyAndRemove("copyandremove-with-zipfileset");
+ }
+
+ private void testCopyAndRemove(String target) {
+ buildRule.executeTarget(target);
+ String d = buildRule.getProject().getProperty("dest") + "/a/b/c/d";
+ assertFileIsPresent(d);
+ String f = buildRule.getProject().getProperty("dest") + "/e/f";
+ assertFileIsNotPresent(f);
+ assertTrue(buildRule.getFullLog().indexOf("Removing orphan file:") > -1);
+ assertContains("Removed 1 dangling file from", buildRule.getFullLog());
+ assertContains("Removed 1 dangling directory from", buildRule.getFullLog());
+ }
+
+ @Test
+ public void testCopyAndRemoveEmptyPreserve() {
+ buildRule.executeTarget("copyandremove-emptypreserve");
+ String d = buildRule.getProject().getProperty("dest") + "/a/b/c/d";
+ assertFileIsPresent(d);
+ String f = buildRule.getProject().getProperty("dest") + "/e/f";
+ assertFileIsNotPresent(f);
+ assertTrue(buildRule.getFullLog().indexOf("Removing orphan file:") > -1);
+ assertContains("Removed 1 dangling file from", buildRule.getFullLog());
+ assertContains("Removed 1 dangling directory from", buildRule.getFullLog());
+ }
+
+ @Test
+ public void testEmptyDirCopyAndRemove() {
+ buildRule.executeTarget("emptydircopyandremove");
+ String d = buildRule.getProject().getProperty("dest") + "/a/b/c/d";
+ assertFileIsNotPresent(d);
+ String c = buildRule.getProject().getProperty("dest") + "/a/b/c";
+ assertFileIsPresent(c);
+ String f = buildRule.getProject().getProperty("dest") + "/e/f";
+ assertFileIsNotPresent(f);
+ assertTrue(buildRule.getFullLog().indexOf("Removing orphan directory:") > -1);
+ assertContains("NO dangling file to remove from", buildRule.getFullLog());
+ assertContains("Removed 2 dangling directories from", buildRule.getFullLog());
+ }
+
+ @Test
+ public void testCopyNoRemove() {
+ buildRule.executeTarget("copynoremove");
+ String d = buildRule.getProject().getProperty("dest") + "/a/b/c/d";
+ assertFileIsPresent(d);
+ String f = buildRule.getProject().getProperty("dest") + "/e/f";
+ assertFileIsPresent(f);
+ assertTrue(buildRule.getFullLog().indexOf("Removing orphan file:") == -1);
+ }
+
+ @Test
+ public void testCopyNoRemoveSelectors() {
+ buildRule.executeTarget("copynoremove-selectors");
+ String d = buildRule.getProject().getProperty("dest") + "/a/b/c/d";
+ assertFileIsPresent(d);
+ String f = buildRule.getProject().getProperty("dest") + "/e/f";
+ assertFileIsPresent(f);
+ assertTrue(buildRule.getFullLog().indexOf("Removing orphan file:") == -1);
+ }
+
+ public void assertFileIsPresent(String f) {
+ assertTrue("Expected file " + f,
+ buildRule.getProject().resolveFile(f).exists());
+ }
+
+ public void assertFileIsNotPresent(String f) {
+ assertTrue("Didn't expect file " + f,
+ !buildRule.getProject().resolveFile(f).exists());
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/TStampTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/TStampTest.java
new file mode 100644
index 00000000..ed7403c7
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/TStampTest.java
@@ -0,0 +1,117 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs;
+
+import java.util.Calendar;
+import java.util.TimeZone;
+import java.util.Date;
+import java.text.SimpleDateFormat;
+
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Location;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+/**
+ *
+ */
+public class TStampTest {
+
+ protected Tstamp tstamp;
+ protected Project project;
+ protected Location location;
+
+ @Before
+ public void setUp() throws Exception {
+ location = new Location("test.xml");
+ project = new Project();
+ tstamp = new Tstamp();
+ tstamp.setLocation(location);
+ tstamp.setProject(project);
+ }
+
+ @Test
+ public void testTimeZone() throws Exception {
+ Tstamp.CustomFormat format = tstamp.createFormat();
+ format.setProperty("today");
+ format.setPattern("HH:mm:ss z");
+ format.setTimezone("GMT");
+ Date date = Calendar.getInstance().getTime();
+ format.execute(project, date, location);
+ String today = project.getProperty("today");
+
+ SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss z");
+ sdf.setTimeZone( TimeZone.getTimeZone("GMT") );
+ String expected = sdf.format(date);
+
+ assertEquals(expected, today);
+ }
+
+ /**
+ * verifies that custom props have priority over the
+ * originals
+ * @throws Exception
+ */
+ @Test
+ public void testWriteOrder() throws Exception {
+ Tstamp.CustomFormat format = tstamp.createFormat();
+ format.setProperty("TODAY");
+ format.setPattern("HH:mm:ss z");
+ format.setTimezone("GMT");
+ Date date = Calendar.getInstance().getTime();
+ format.execute(project, date, location);
+ String today = project.getProperty("TODAY");
+
+ SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss z");
+ sdf.setTimeZone( TimeZone.getTimeZone("GMT") );
+ String expected = sdf.format(date);
+
+ assertEquals(expected, today);
+
+ }
+
+ /**
+ * verifies that custom props have priority over the
+ * originals
+ * @throws Exception
+ */
+ @Test
+ public void testPrefix() throws Exception {
+ tstamp.setPrefix("prefix");
+ tstamp.execute();
+ String prop= project.getProperty("prefix.DSTAMP");
+ assertNotNull(prop);
+ }
+
+ @Test
+ public void testFormatPrefix() throws Exception {
+ Tstamp.CustomFormat format = tstamp.createFormat();
+ format.setProperty("format");
+ format.setPattern("HH:mm:ss z");
+ format.setTimezone("GMT");
+
+ tstamp.setPrefix("prefix");
+ tstamp.execute();
+ String prop= project.getProperty("prefix.format");
+ assertNotNull(prop);
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/TarTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/TarTest.java
new file mode 100644
index 00000000..c5ba1200
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/TarTest.java
@@ -0,0 +1,210 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.io.IOException;
+import java.io.File;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.BuildFileRule;
+import org.apache.tools.ant.FileUtilities;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+public class TarTest {
+
+ @Rule
+ public final BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/tar.xml");
+ buildRule.executeTarget("setUp");
+ }
+
+ @Test
+ public void test1() {
+ try {
+ buildRule.executeTarget("test1");
+ fail("BuildException expected: required argument not specified");
+ } catch (BuildException ex) {
+ //TODO assert value
+ }
+ }
+
+ @Test
+ public void test2() {
+ try {
+ buildRule.executeTarget("test2");
+ fail("BuildException expected: required argument not specified");
+ } catch (BuildException ex) {
+ //TODO assert value
+ }
+ }
+
+ @Test
+ public void test3() {
+ try {
+ buildRule.executeTarget("test3");
+ fail("BuildException expected: required argument not specified");
+ } catch (BuildException ex) {
+ //TODO assert value
+ }
+ }
+
+ @Test
+ public void test4() {
+ try {
+ buildRule.executeTarget("test4");
+ fail("BuildException expected: tar cannot include itself");
+ } catch (BuildException ex) {
+ //TODO assert value
+ }
+ }
+
+ @Test
+ public void test5() {
+ buildRule.executeTarget("test5");
+ File f
+ = new File(buildRule.getProject().getProperty("output"), "test5.tar");
+
+ if (!f.exists()) {
+ fail("Tarring a directory failed");
+ }
+ }
+
+ @Test
+ public void test6() {
+ try {
+ buildRule.executeTarget("test6");
+ fail("BuildException expected: Invalid value specified for longfile attribute.");
+ } catch (BuildException ex) {
+ //TODO assert value
+ }
+ }
+
+ @Test
+ public void test7() {
+ test7("test7");
+ }
+
+ @Test
+ public void test7UsingPlainFileSet() {
+ test7("test7UsingPlainFileSet");
+ }
+
+ @Test
+ public void test7UsingFileList() {
+ test7("test7UsingFileList");
+ }
+
+ private void test7(String target) {
+ buildRule.executeTarget(target);
+ File f1
+ = new File(buildRule.getProject().getProperty("output"), "untar/test7-prefix");
+
+ if (!(f1.exists() && f1.isDirectory())) {
+ fail("The prefix attribute is not working properly.");
+ }
+
+ File f2
+ = new File(buildRule.getProject().getProperty("output"), "untar/test7dir");
+
+ if (!(f2.exists() && f2.isDirectory())) {
+ fail("The prefix attribute is not working properly.");
+ }
+ }
+
+ @Test
+ public void test8() {
+ test8("test8");
+ }
+
+ @Test
+ public void test8UsingZipFileset() {
+ test8("test8UsingZipFileset");
+ }
+
+ @Test
+ public void test8UsingZipFilesetSrc() {
+ test8("test8UsingZipFilesetSrc");
+ }
+
+ @Test
+ public void test8UsingTarFilesetSrc() {
+ test8("test8UsingTarFilesetSrc");
+ }
+
+ @Test
+ public void test8UsingZipEntry() {
+ test8("test8UsingZipEntry");
+ }
+
+ private void test8(String target) {
+ buildRule.executeTarget(target);
+ File f1
+ = new File(buildRule.getProject().getProperty("output"), "untar/test8.xml");
+ if (! f1.exists()) {
+ fail("The fullpath attribute or the preserveLeadingSlashes attribute does not work propertly");
+ }
+ }
+
+ @Test
+ public void test9() {
+ try {
+ buildRule.executeTarget("test9");
+ fail("BuildException expected: Invalid value specified for compression attribute.");
+ } catch (BuildException ex) {
+ //TODO assert value
+ }
+ }
+
+ @Test
+ public void test10() {
+ buildRule.executeTarget("test10");
+ File f1
+ = new File(buildRule.getProject().getProperty("output"), "untar/test10.xml");
+ if (! f1.exists()) {
+ fail("The fullpath attribute or the preserveLeadingSlashes attribute does not work propertly");
+ }
+ }
+
+ @Test
+ public void test11() {
+ buildRule.executeTarget("test11");
+ File f1
+ = new File(buildRule.getProject().getProperty("output"), "untar/test11.xml");
+ if (! f1.exists()) {
+ fail("The fullpath attribute or the preserveLeadingSlashes attribute does not work propertly");
+ }
+ }
+
+ @Test
+ public void testGZipResource() throws IOException {
+ buildRule.executeTarget("testGZipResource");
+ assertEquals(FileUtilities.getFileContents(buildRule.getProject().resolveFile("../asf-logo.gif")),
+ FileUtilities.getFileContents(new File(buildRule.getProject().getProperty("output"), "untar/asf-logo.gif.gz")));
+ }
+
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/TaskdefTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/TaskdefTest.java
new file mode 100644
index 00000000..eaa8a667
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/TaskdefTest.java
@@ -0,0 +1,128 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.BuildFileRule;
+import org.apache.tools.ant.Project;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+/**
+ */
+public class TaskdefTest {
+
+ @Rule
+ public final BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/taskdef.xml");
+ }
+
+ @Test
+ public void test1() {
+ try {
+ buildRule.executeTarget("test1");
+ fail("BuildException expected: required argument not specified");
+ } catch (BuildException ex) {
+ //TODO assert value
+ }
+ }
+
+ @Test
+ public void test2() {
+ try {
+ buildRule.executeTarget("test2");
+ fail("BuildException expected: required argument not specified");
+ } catch (BuildException ex) {
+ //TODO assert value
+ }
+ }
+
+ @Test
+ public void test3() {
+ try {
+ buildRule.executeTarget("test3");
+ fail("BuildException expected: required argument not specified");
+ } catch (BuildException ex) {
+ //TODO assert value
+ }
+ }
+
+ @Test
+ public void test4() {
+ try {
+ buildRule.executeTarget("test4");
+ fail("BuildException expected: classname specified doesn't exist");
+ } catch (BuildException ex) {
+ //TODO assert value
+ }
+ }
+
+ @Test
+ public void test5() {
+ try {
+ buildRule.executeTarget("test5");
+ fail("BuildException expected: No public execute() in " + Project.class);
+ } catch (BuildException ex) {
+ //TODO assert value
+ }
+ }
+
+ @Test
+ public void test5a() {
+ buildRule.executeTarget("test5a");
+ }
+
+ @Test
+ public void test6() {
+ buildRule.executeTarget("test6");
+ assertEquals("simpletask: worked", buildRule.getLog());
+ }
+
+ @Test
+ public void test7() {
+ buildRule.executeTarget("test7");
+ assertEquals("worked", buildRule.getLog());
+ }
+
+ @Test
+ public void testGlobal() {
+ buildRule.executeTarget("testGlobal");
+ assertEquals("worked", buildRule.getLog());
+ }
+
+ @Test
+ public void testOverride() {
+ buildRule.executeTarget("testOverride");
+ String log = buildRule.getLog();
+ assertTrue("override warning sent",
+ log.indexOf("Trying to override old definition of task copy") > -1);
+ assertTrue("task inside target worked",
+ log.indexOf("In target") > -1);
+ assertTrue("task inside target worked",
+ log.indexOf("In TaskContainer") > -1);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/TaskdefsTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/TaskdefsTest.java
new file mode 100644
index 00000000..9316059c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/TaskdefsTest.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.BuildFileTest;
+
+/**
+ * @deprecated use {@link org.apache.tools.ant.BuildFileRule} instead.
+ */
+public abstract class TaskdefsTest extends BuildFileTest {
+
+ public TaskdefsTest(String name) {
+ super(name);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/TestProcess.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/TestProcess.java
new file mode 100644
index 00000000..062003fa
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/TestProcess.java
@@ -0,0 +1,96 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import org.junit.internal.AssumptionViolatedException;
+
+/**
+ * Interactive Testcase for Processdestroyer.
+ *
+ */
+public class TestProcess
+ implements Runnable
+{
+ private boolean run = true;
+ private boolean done = false;
+
+ public void shutdown()
+ {
+ if (!done)
+ {
+ System.out.println("shutting down TestProcess");
+ run = false;
+
+ synchronized(this)
+ {
+ while (!done)
+ {
+ try {
+ wait();
+ } catch (InterruptedException ie) {
+ throw new AssumptionViolatedException("Thread interrupted", ie);
+ }
+ }
+ }
+
+ System.out.println("TestProcess shut down");
+ }
+ }
+
+ public void run()
+ {
+ for (int i = 0; i < 5 && run; i++)
+ {
+ System.out.println(Thread.currentThread().getName());
+
+ try {
+ Thread.sleep(2000);
+ } catch (InterruptedException ie) {
+ throw new AssumptionViolatedException("Thread interrupted", ie);
+ }
+ }
+
+ synchronized(this)
+ {
+ done = true;
+ notifyAll();
+ }
+ }
+
+ public Thread getShutdownHook()
+ {
+ return new TestProcessShutdownHook();
+ }
+
+ private class TestProcessShutdownHook
+ extends Thread
+ {
+ public void run()
+ {
+ shutdown();
+ }
+ }
+
+ public static void main(String[] args)
+ {
+ TestProcess tp = new TestProcess();
+ new Thread(tp, "TestProcess thread").start();
+ Runtime.getRuntime().addShutdownHook(tp.getShutdownHook());
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/TimeProcess.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/TimeProcess.java
new file mode 100644
index 00000000..eee15d12
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/TimeProcess.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs;
+
+/**
+ * Helper class for ExecuteWatchdogTest and ExecuteJavaTest.
+ *
+ * <p>Used to be an inner class of ExecuteWatchdogTest.
+ *
+ */
+public class TimeProcess {
+ public static void main(String[] args) throws Exception {
+ int time = Integer.parseInt(args[0]);
+ if (time < 1) {
+ throw new IllegalArgumentException("Invalid time: " + time);
+ }
+ Thread.sleep(time);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/TouchTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/TouchTest.java
new file mode 100644
index 00000000..0a968b25
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/TouchTest.java
@@ -0,0 +1,211 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.BuildFileRule;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.util.FileUtils;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import java.io.File;
+
+import static org.apache.tools.ant.AntAssert.assertContains;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+public class TouchTest {
+
+ @Rule
+ public final BuildFileRule buildRule = new BuildFileRule();
+
+ private static String TOUCH_FILE = "src/etc/testcases/taskdefs/touchtest";
+
+ /** Utilities used for file operations */
+ private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/touch.xml");
+ }
+
+ @After
+ public void tearDown() {
+ buildRule.executeTarget("cleanup");
+ }
+
+ public long getTargetTime() {
+
+ File file = new File(System.getProperty("root"), TOUCH_FILE);
+ if(!file.exists()) {
+ throw new BuildException("failed to touch file " + file);
+ }
+ return file.lastModified();
+ }
+
+ /**
+ * No real test, simply checks whether the dateformat without
+ * seconds is accepted - by erroring out otherwise.
+ */
+ @Test
+ public void testNoSeconds() {
+ buildRule.executeTarget("noSeconds");
+ getTargetTime();
+ }
+
+ /**
+ * No real test, simply checks whether the dateformat with
+ * seconds is accepted - by erroring out otherwise.
+ */
+ @Test
+ public void testSeconds() {
+ buildRule.executeTarget("seconds");
+ getTargetTime();
+ }
+ /**
+ * verify that the millis test sets things up
+ */
+ @Test
+ public void testMillis() {
+ touchFile("testMillis", 662256000000L);
+ }
+
+ /**
+ * verify that the default value defaults to now
+ */
+ @Test
+ public void testNow() {
+ long now=System.currentTimeMillis();
+ buildRule.executeTarget("testNow");
+ long time = getTargetTime();
+ assertTimesNearlyMatch(time,now,5000);
+ }
+ /**
+ * verify that the millis test sets things up
+ */
+ @Test
+ public void test2000() {
+ touchFile("test2000", 946080000000L);
+ }
+
+ /**
+ * test the file list
+ */
+ @Test
+ public void testFilelist() {
+ touchFile("testFilelist", 662256000000L);
+ }
+
+ /**
+ * test the file set
+ */
+ @Test
+ public void testFileset() {
+ touchFile("testFileset", 946080000000L);
+ }
+
+ /**
+ * test the resource collection
+ */
+ @Test
+ public void testResourceCollection() {
+ touchFile("testResourceCollection", 1662256000000L);
+ }
+
+ /**
+ * test the mapped file set
+ */
+ @Test
+ public void testMappedFileset() {
+ buildRule.executeTarget("testMappedFileset");
+ }
+
+ /**
+ * test the explicit mapped file set
+ */
+ @Test
+ public void testExplicitMappedFileset() {
+ buildRule.executeTarget("testExplicitMappedFileset");
+ }
+
+ /**
+ * test the mapped file list
+ */
+ @Test
+ public void testMappedFilelist() {
+ buildRule.executeTarget("testMappedFilelist");
+ }
+
+ /**
+ * test the pattern attribute
+ */
+ @Test
+ public void testGoodPattern() {
+ buildRule.executeTarget("testGoodPattern");
+ }
+
+ /**
+ * test the pattern attribute again
+ */
+ @Test
+ public void testBadPattern() {
+ try {
+ buildRule.executeTarget("testBadPattern");
+ fail("No parsing exception thrown");
+ } catch (BuildException ex) {
+ assertContains("Unparseable", ex.getMessage());
+ }
+
+ }
+
+ /**
+ * run a target to touch the test file; verify the timestamp is as expected
+ * @param targetName
+ * @param timestamp
+ */
+ private void touchFile(String targetName, long timestamp) {
+ buildRule.executeTarget(targetName);
+ long time = getTargetTime();
+ assertTimesNearlyMatch(timestamp, time);
+ }
+
+ /**
+ * assert that two times are within the current FS granularity;
+ * @param timestamp
+ * @param time
+ */
+ public void assertTimesNearlyMatch(long timestamp,long time) {
+ long granularity= FILE_UTILS.getFileTimestampGranularity();
+ assertTimesNearlyMatch(timestamp, time, granularity);
+ }
+
+ /**
+ * assert that two times are within a specified range
+ * @param timestamp
+ * @param time
+ * @param range
+ */
+ private void assertTimesNearlyMatch(long timestamp, long time, long range) {
+ assertTrue("Time " + timestamp + " is not within " + range + " ms of "
+ + time, (Math.abs(time - timestamp) <= range));
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/TypeAdapterTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/TypeAdapterTest.java
new file mode 100644
index 00000000..3488f399
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/TypeAdapterTest.java
@@ -0,0 +1,176 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.lang.reflect.Method;
+
+import org.apache.tools.ant.BuildFileRule;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.TypeAdapter;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.apache.tools.ant.AntAssert.assertContains;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+
+/**
+ */
+public class TypeAdapterTest {
+
+ @Rule
+ public final BuildFileRule buildRule = new BuildFileRule();
+
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/typeadapter.xml");
+ }
+
+ @Test
+ public void testTaskAdapter() {
+ buildRule.executeTarget("taskadapter");
+ assertContains("MyExec called", buildRule.getLog());
+ }
+
+ @Test
+ public void testRunAdapter() {
+ buildRule.executeTarget("runadapter");
+ assertContains("MyRunnable called", buildRule.getLog());
+ }
+
+ @Test
+ public void testRunAdapterError() {
+ try {
+ buildRule.executeTarget("runadaptererror");
+ fail("BuildException expected: no public run method");
+ } catch (BuildException ex) {
+ assertContains("No public run() method in", ex.getMessage());
+ }
+ }
+
+ @Test
+ public void testDelay() {
+ buildRule.executeTarget("delay");
+ assertContains("MyTask called", buildRule.getLog());
+ }
+
+ @Test
+ public void testOnErrorReport() {
+ buildRule.executeTarget("onerror.report");
+ assertContains("MyTaskNotPresent cannot be found", buildRule.getLog());
+ }
+
+ @Test
+ public void testOnErrorIgnore() {
+ buildRule.executeTarget("onerror.ignore");
+ assertEquals("", buildRule.getLog());
+ }
+
+ public static class MyTask extends Task {
+ public void execute() {
+ log("MyTask called");
+ }
+ }
+
+ public static class MyExec {
+ private Project project;
+ public void setProject(Project project) {
+ this.project = project;
+ }
+
+ public void execute() {
+ project.log("MyExec called");
+ }
+ }
+
+ public static class MyRunnable {
+ private Project project;
+ public void setProject(Project project) {
+ this.project = project;
+ }
+
+ public void run() {
+ project.log("MyRunnable called");
+ }
+ }
+
+ public static class RunnableAdapter
+ extends Task implements TypeAdapter
+ {
+ private String execMethodName = "run";
+ private Object proxy;
+
+ public Method getExecuteMethod(Class proxyClass) {
+ try {
+ Method execMethod = proxyClass.getMethod(execMethodName);
+ if (!Void.TYPE.equals(execMethod.getReturnType())) {
+ String message =
+ "return type of " + execMethodName + "() should be "
+ + "void but was \"" + execMethod.getReturnType() +
+ "\" in "
+ + proxyClass;
+ log(message, Project.MSG_WARN);
+ }
+ return execMethod;
+ } catch (NoSuchMethodException e) {
+ String message = "No public "+ execMethodName +
+ "() method in "
+ + proxyClass;
+ log(message, Project.MSG_ERR);
+ throw new BuildException(message);
+ }
+ }
+ public void checkProxyClass(Class proxyClass) {
+ getExecuteMethod(proxyClass);
+ }
+
+ public void setProxy(Object o) {
+ getExecuteMethod(o.getClass());
+ this.proxy = o;
+ }
+
+ public Object getProxy() {
+ return proxy;
+ }
+
+ public void execute() {
+ getProject().setProjectReference(proxy);
+ Method executeMethod = getExecuteMethod(proxy.getClass());
+ try {
+ executeMethod.invoke(proxy);
+ } catch (java.lang.reflect.InvocationTargetException ie) {
+ log("Error in " + proxy.getClass(), Project.MSG_ERR);
+ Throwable t = ie.getTargetException();
+ if (t instanceof BuildException) {
+ throw ((BuildException) t);
+ } else {
+ throw new BuildException(t);
+ }
+ } catch (Exception ex) {
+ log("Error in " + proxy.getClass(), Project.MSG_ERR);
+ throw new BuildException(ex);
+ }
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/TypedefTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/TypedefTest.java
new file mode 100644
index 00000000..bfc11dd4
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/TypedefTest.java
@@ -0,0 +1,136 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.BuildFileRule;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.apache.tools.ant.AntAssert.assertContains;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+
+/**
+ */
+public class TypedefTest {
+
+ @Rule
+ public final BuildFileRule buildRule = new BuildFileRule();
+
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/typedef.xml");
+ }
+
+ @Test
+ public void testEmpty() {
+ try {
+ buildRule.executeTarget("empty");
+ fail("BuildException expected: required argument not specified");
+ } catch (BuildException ex) {
+ //TODO assert value
+ }
+ }
+
+ @Test
+ public void testNoName() {
+ try {
+ buildRule.executeTarget("noName");
+ fail("BuildException expected: required argument not specified");
+ } catch (BuildException ex) {
+ //TODO assert value
+ }
+ }
+
+ @Test
+ public void testNoClassname() {
+ try {
+ buildRule.executeTarget("noClassname");
+ fail("BuildException expected: required argument not specified");
+ } catch (BuildException ex) {
+ //TODO assert value
+ }
+ }
+
+ @Test
+ public void testClassNotFound() {
+ try {
+ buildRule.executeTarget("classNotFound");
+ fail("BuildException expected: classname specified doesn't exist");
+ } catch (BuildException ex) {
+ //TODO assert value
+ }
+ }
+
+ @Test
+ public void testGlobal() {
+ buildRule.executeTarget("testGlobal");
+ assertEquals("", buildRule.getLog());
+ Object ref = buildRule.getProject().getReferences().get("global");
+ assertNotNull("ref is not null", ref);
+ assertEquals("org.example.types.TypedefTestType",
+ ref.getClass().getName());
+ }
+
+ @Test
+ public void testLocal() {
+ buildRule.executeTarget("testLocal");
+ assertEquals("", buildRule.getLog());
+ Object ref = buildRule.getProject().getReferences().get("local");
+ assertNotNull("ref is not null", ref);
+ assertEquals("org.example.types.TypedefTestType",
+ ref.getClass().getName());
+ }
+
+ /**
+ * test to make sure that one can define a not present
+ * optional type twice and then have a valid definition.
+ */
+ @Test
+ public void testDoubleNotPresent() {
+ buildRule.executeTarget("double-notpresent");
+ assertContains("hi", buildRule.getLog());
+ }
+
+ @Test
+ public void testNoResourceOnErrorFailAll(){
+ try {
+ buildRule.executeTarget("noresourcefailall");
+ fail("BuildException expected: the requested resource does not exist");
+ } catch (BuildException ex) {
+ assertContains("Could not load definitions from resource ", ex.getMessage());
+ }
+ }
+
+ @Test
+ public void testNoResourceOnErrorFail(){
+ buildRule.executeTarget("noresourcefail");
+ assertContains("Could not load definitions from resource ", buildRule.getLog());
+ }
+
+ @Test
+ public void testNoResourceOnErrorNotFail(){
+ buildRule.executeTarget("noresourcenotfail");
+ assertContains("Could not load definitions from resource ", buildRule.getLog());
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/UntarTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/UntarTest.java
new file mode 100644
index 00000000..e0f7eb2a
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/UntarTest.java
@@ -0,0 +1,111 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.BuildFileRule;
+import org.apache.tools.ant.FileUtilities;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import java.io.File;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+
+public class UntarTest {
+
+ @Rule
+ public final BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/untar.xml");
+ }
+
+ @Test
+ public void testRealTest() throws java.io.IOException {
+ testLogoExtraction("realTest");
+ }
+
+ @Test
+ public void testRealGzipTest() throws java.io.IOException {
+ testLogoExtraction("realGzipTest");
+ }
+
+ @Test
+ public void testRealBzip2Test() throws java.io.IOException {
+ testLogoExtraction("realBzip2Test");
+ }
+
+ @Test
+ public void testTestTarTask() throws java.io.IOException {
+ testLogoExtraction("testTarTask");
+ }
+
+ @Test
+ public void testTestGzipTarTask() throws java.io.IOException {
+ testLogoExtraction("testGzipTarTask");
+ }
+
+ @Test
+ public void testTestBzip2TarTask() throws java.io.IOException {
+ testLogoExtraction("testBzip2TarTask");
+ }
+
+ @Test
+ public void testSrcDirTest() {
+ try {
+ buildRule.executeTarget("srcDirTest");
+ fail("Src cannot be a directory.");
+ } catch (BuildException ex) {
+ //TODO assert value
+ }
+ }
+
+ @Test
+ public void testEncoding() {
+ buildRule.executeTarget("encodingTest");
+ String filename = buildRule.getProject().getProperty("output") + "/untartestout/foo";
+ assertTrue("foo has been properly named",
+ buildRule.getProject().resolveFile(filename).exists());
+ }
+
+ @Test
+ public void testResourceCollection() throws java.io.IOException {
+ testLogoExtraction("resourceCollection");
+ }
+
+ private void testLogoExtraction(String target) throws java.io.IOException {
+ buildRule.executeTarget(target);
+ assertEquals(FileUtilities.getFileContents(buildRule.getProject().resolveFile("../asf-logo.gif")),
+ FileUtilities.getFileContents(new File(buildRule.getProject().getProperty("output"), "untar/asf-logo.gif")));
+
+ }
+
+ @Test
+ public void testDocumentationClaimsOnCopy() {
+ buildRule.executeTarget("testDocumentationClaimsOnCopy");
+ assertFalse(new File(buildRule.getProject().getProperty("output"), "untar/1/foo").exists());
+ assertTrue(new File(buildRule.getProject().getProperty("output"), "untar/2/bar").exists());
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/UnzipTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/UnzipTest.java
new file mode 100644
index 00000000..ad99620e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/UnzipTest.java
@@ -0,0 +1,250 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.BuildFileRule;
+import org.apache.tools.ant.FileUtilities;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Rule;
+import org.junit.Test;
+
+import java.io.File;
+import java.io.IOException;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+public class UnzipTest {
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/unzip.xml");
+ }
+
+ @Test
+ public void test1() {
+ try {
+ buildRule.executeTarget("test1");
+ fail("BuildException expected: required argument not specified");
+ } catch (BuildException ex) {
+ //TODO assert value
+ }
+ }
+
+ @Test
+ public void test2() {
+ try {
+ buildRule.executeTarget("test2");
+ fail("BuildException expected: required argument not specified");
+ } catch (BuildException ex) {
+ //TODO assert value
+ }
+ }
+
+ @Test
+ public void test3() {
+ try {
+ buildRule.executeTarget("test3");
+ fail("BuildException expected: required argument not specified");
+ } catch (BuildException ex) {
+ //TODO assert value
+ }
+ }
+
+
+ @Test
+ public void testRealTest() throws java.io.IOException {
+ buildRule.executeTarget("realTest");
+ assertLogoUncorrupted();
+ }
+
+ /**
+ * test that the logo gif file has not been corrupted
+ * @throws IOException
+ */
+ private void assertLogoUncorrupted() throws IOException {
+ assertEquals(FileUtilities.getFileContents(buildRule.getProject().resolveFile("../asf-logo.gif")),
+ FileUtilities.getFileContents(new File(buildRule.getProject().getProperty("output"), "asf-logo.gif")));
+
+ }
+
+ @Test
+ public void testTestZipTask() throws java.io.IOException {
+ buildRule.executeTarget("testZipTask");
+ assertLogoUncorrupted();
+ }
+
+ @Test
+ public void testTestUncompressedZipTask() throws java.io.IOException {
+ buildRule.executeTarget("testUncompressedZipTask");
+ assertLogoUncorrupted();
+ }
+
+ /*
+ * PR 11100
+ */
+ @Test
+ public void testPatternSetExcludeOnly() {
+ buildRule.executeTarget("testPatternSetExcludeOnly");
+ assertFileMissing("1/foo is excluded", buildRule.getProject().getProperty("output") + "/unziptestout/1/foo");
+ assertFileExists("2/bar is not excluded", buildRule.getProject().getProperty("output") + "/unziptestout/2/bar");
+ }
+
+ /*
+ * PR 11100
+ */
+ @Test
+ public void testPatternSetIncludeOnly() {
+ buildRule.executeTarget("testPatternSetIncludeOnly");
+ assertFileMissing("1/foo is not included", buildRule.getProject().getProperty("output") + "/unziptestout/1/foo");
+ assertFileExists("2/bar is included", buildRule.getProject().getProperty("output") + "/unziptestout/2/bar");
+ }
+
+ /*
+ * PR 11100
+ */
+ @Test
+ public void testPatternSetIncludeAndExclude() {
+ buildRule.executeTarget("testPatternSetIncludeAndExclude");
+ assertFileMissing("1/foo is not included", buildRule.getProject().getProperty("output") + "/unziptestout/1/foo");
+ assertFileMissing("2/bar is excluded", buildRule.getProject().getProperty("output") + "/unziptestout/2/bar");
+ }
+
+ /*
+ * PR 38973
+ */
+ @Test
+ public void testTwoPatternSets() {
+ buildRule.executeTarget("testTwoPatternSets");
+ assertFileMissing("1/foo is not included", buildRule.getProject().getProperty("output") + "/unziptestout/1/foo");
+ assertFileExists("2/bar is included", buildRule.getProject().getProperty("output") + "/unziptestout/2/bar");
+ }
+
+ /*
+ * PR 38973
+ */
+ @Test
+ public void testTwoPatternSetsWithExcludes() {
+ buildRule.executeTarget("testTwoPatternSetsWithExcludes");
+ assertFileMissing("1/foo is not included", buildRule.getProject().getProperty("output") + "/unziptestout/1/foo");
+ assertFileMissing("2/bar is excluded", buildRule.getProject().getProperty("output") + "/unziptestout/2/bar");
+ }
+
+ /*
+ * PR 16213
+ */
+ @Test
+ @Ignore("we lack a self extracting archive that we are allowed to distribute - see PR 49080")
+ public void testSelfExtractingArchive() {
+ // disabled because we lack a self extracting archive that we
+ // are allowed to distribute - see PR 49080
+ buildRule.executeTarget("selfExtractingArchive");
+ }
+
+
+ /*
+ * PR 20969
+ */
+ @Test
+ public void testPatternSetSlashOnly() {
+ buildRule.executeTarget("testPatternSetSlashOnly");
+ assertFileMissing("1/foo is not included", buildRule.getProject().getProperty("output") + "/unziptestout/1/foo");
+ assertFileExists("\"2/bar is included", buildRule.getProject().getProperty("output") + "/unziptestout/2/bar");
+ }
+
+
+ /*
+ * PR 10504
+ */
+ @Test
+ public void testEncoding() {
+ buildRule.executeTarget("encodingTest");
+ assertFileExists("foo has been properly named", buildRule.getProject().getProperty("output") + "/unziptestout/foo");
+ }
+
+ /*
+ * PR 21996
+ */
+ @Test
+ public void testFlattenMapper() {
+ buildRule.executeTarget("testFlattenMapper");
+ assertFileMissing("1/foo is not flattened", buildRule.getProject().getProperty("output") + "/unziptestout/1/foo");
+ assertFileExists("foo is flattened", buildRule.getProject().getProperty("output") + "/unziptestout/foo");
+ }
+
+ /**
+ * assert that a file exists, relative to the project
+ * @param message message if there is no mpatch
+ * @param filename filename to resolve against the project
+ */
+ private void assertFileExists(String message, String filename) {
+ assertTrue(message,
+ buildRule.getProject().resolveFile(filename).exists());
+ }
+
+ /**
+ * assert that a file doesnt exist, relative to the project
+ *
+ * @param message message if there is no mpatch
+ * @param filename filename to resolve against the project
+ */
+ private void assertFileMissing(String message, String filename) {
+ assertTrue(message,
+ !buildRule.getProject().resolveFile(filename).exists());
+ }
+
+ /**
+ * PR 21996
+ */
+ @Test
+ public void testGlobMapper() {
+ buildRule.executeTarget("testGlobMapper");
+ assertFileMissing("1/foo is not mapped", buildRule.getProject().getProperty("output") + "/unziptestout/1/foo");
+ assertFileExists("1/foo is mapped", buildRule.getProject().getProperty("output") + "/unziptestout/1/foo.txt");
+ }
+
+ @Test
+ public void testTwoMappers() {
+ try {
+ buildRule.executeTarget("testTwoMappers");
+ fail("BuildException expected: " + Expand.ERROR_MULTIPLE_MAPPERS);
+ } catch (BuildException ex) {
+ //TODO assert value
+ }
+ }
+
+ @Test
+ public void testResourceCollections() {
+ buildRule.executeTarget("testResourceCollection");
+ assertFileExists("junit.jar has been extracted",
+ buildRule.getProject().getProperty("output") + "/unziptestout/junit/framework/Assert.class");
+ }
+
+ @Test
+ public void testDocumentationClaimsOnCopy() {
+ buildRule.executeTarget("testDocumentationClaimsOnCopy");
+ assertFileMissing("1/foo is excluded", buildRule.getProject().getProperty("output") + "/unziptestout/1/foo");
+ assertFileExists("2/bar is not excluded", buildRule.getProject().getProperty("output") + "/unziptestout/2/bar");
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/UpToDateTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/UpToDateTest.java
new file mode 100644
index 00000000..b9677c4b
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/UpToDateTest.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.BuildFileRule;
+import org.apache.tools.ant.util.FileUtils;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import java.io.File;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assume.assumeTrue;
+
+public class UpToDateTest {
+
+ @Rule
+ public final BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/uptodate.xml");
+ buildRule.executeTarget("setUp");
+ File srcDir = buildRule.getProject().resolveFile("source");
+ assumeTrue("Could not change modification timestamp of source directory",
+ srcDir.setLastModified(srcDir.lastModified()
+ - (3 * FileUtils.getFileUtils().getFileTimestampGranularity())));
+ }
+
+ @After
+ public void tearDown() {
+ buildRule.executeTarget("tearDown");
+ }
+
+ @Test
+ public void testFilesetUpToDate() {
+ buildRule.executeTarget("testFilesetUpToDate");
+ assertEquals("true", buildRule.getProject().getProperty("foo"));
+ }
+
+ @Test
+ public void testFilesetOutOfDate() {
+ buildRule.executeTarget("testFilesetOutOfDate");
+ assertNull(buildRule.getProject().getProperty("foo"));
+ }
+
+ @Test
+ public void testRCUpToDate() {
+ buildRule.executeTarget("testRCUpToDate");
+ assertEquals("true", buildRule.getProject().getProperty("foo"));
+ }
+
+ @Test
+ public void testRCOutOfDate() {
+ buildRule.executeTarget("testRCOutOfDate");
+ assertNull(buildRule.getProject().getProperty("foo"));
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/WarTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/WarTest.java
new file mode 100644
index 00000000..1513ac75
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/WarTest.java
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.io.File;
+
+import org.apache.tools.ant.BuildFileRule;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Testcase for the war task
+ *
+ */
+public class WarTest {
+ public static final String TEST_BUILD_FILE
+ = "src/etc/testcases/taskdefs/war.xml";
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject(TEST_BUILD_FILE);
+ }
+
+ /**
+ * Test direct dependency removal
+ */
+ @Test
+ public void testLibRefs() {
+ buildRule.executeTarget("testlibrefs");
+ File f = new File(buildRule.getOutputDir(), "WEB-INF/lib/war.xml");
+ assertTrue("File has been put into lib", f.exists());
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/WhichResourceTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/WhichResourceTest.java
new file mode 100644
index 00000000..8e282b3a
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/WhichResourceTest.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.BuildFileRule;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.assertNotNull;
+
+public class WhichResourceTest {
+ public static final String TEST_BUILD_FILE
+ = "src/etc/testcases/taskdefs/whichresource.xml";
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject(TEST_BUILD_FILE);
+ }
+
+ @Test
+ public void testClassname() {
+ buildRule.executeTarget("testClassname");
+ assertNotNull(buildRule.getProject().getProperty("antmain"));
+ }
+
+ @Test
+ public void testResourcename() {
+ buildRule.executeTarget("testResourcename");
+ assertNotNull(buildRule.getProject().getProperty("defaults"));
+ }
+
+ @Test
+ public void testResourcenameWithLeadingSlash() {
+ buildRule.executeTarget("testResourcenameWithLeadingSlash");
+ assertNotNull(buildRule.getProject().getProperty("defaults"));
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/XmlPropertyTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/XmlPropertyTest.java
new file mode 100644
index 00000000..89069173
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/XmlPropertyTest.java
@@ -0,0 +1,376 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.io.File;
+import java.io.FileFilter;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Properties;
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildFileRule;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.util.FileUtils;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+/**
+ */
+public class XmlPropertyTest {
+ private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/xmlproperty.xml");
+ }
+
+ @Test
+ public void testFile() {
+ testProperties("test");
+ }
+
+ @Test
+ public void testResource() {
+ testProperties("testResource");
+ }
+
+ private void testProperties(String target) {
+ buildRule.executeTarget(target);
+ assertEquals("true", buildRule.getProject().getProperty("root-tag(myattr)"));
+ assertEquals("Text", buildRule.getProject().getProperty("root-tag.inner-tag"));
+ assertEquals("val",
+ buildRule.getProject().getProperty("root-tag.inner-tag(someattr)"));
+ assertEquals("false", buildRule.getProject().getProperty("root-tag.a2.a3.a4"));
+ assertEquals("CDATA failed",
+ "<test>", buildRule.getProject().getProperty("root-tag.cdatatag"));
+ }
+
+ @Test
+ public void testDTD() {
+ buildRule.executeTarget("testdtd");
+ assertEquals("Text", buildRule.getProject().getProperty("root-tag.inner-tag"));
+ }
+
+ @Test
+ public void testNone () throws IOException {
+ doTest("testNone", false, false, false, false, false);
+ }
+
+ @Test
+ public void testKeeproot() throws IOException {
+ doTest("testKeeproot", true, false, false, false, false);
+ }
+
+ @Test
+ public void testCollapse () throws IOException {
+ doTest("testCollapse", false, true, false, false, false);
+ }
+
+ @Test
+ public void testSemantic () throws IOException {
+ doTest("testSemantic", false, false, true, false, false);
+ }
+
+ @Test
+ public void testKeeprootCollapse () throws IOException {
+ doTest("testKeeprootCollapse", true, true, false, false, false);
+ }
+
+ @Test
+ public void testKeeprootSemantic () throws IOException {
+ doTest("testKeeprootSemantic", true, false, true, false, false);
+ }
+
+ @Test
+ public void testCollapseSemantic () throws IOException {
+ doTest("testCollapseSemantic", false, true, true, false, false);
+ }
+
+ @Test
+ public void testKeeprootCollapseSemantic () throws IOException {
+ doTest("testKeeprootCollapseSemantic", true, true, true, false, false);
+ }
+
+ @Test
+ public void testInclude () throws IOException {
+ doTest("testInclude", false, false, false, true, false);
+ }
+
+ @Test
+ public void testSemanticInclude () throws IOException {
+ doTest("testSemanticInclude", false, false, true, true, false);
+ }
+
+ @Test
+ public void testSemanticLocal () throws IOException {
+ doTest("testSemanticInclude", false, false, true, false, true);
+ }
+
+ @Test
+ public void testNeedsCatalog() {
+ buildRule.executeTarget("testneedscat");
+ assertEquals("true", buildRule.getProject().getProperty("skinconfig.foo"));
+ }
+
+ /**
+ * Actually run a test, finding all input files (and corresponding
+ * goldfile)
+ */
+ private void doTest(String msg, boolean keepRoot, boolean collapse,
+ boolean semantic, boolean include, boolean localRoot) throws IOException {
+ Enumeration iter =
+ getFiles(new File(System.getProperty("root"), "src/etc/testcases/taskdefs/xmlproperty/inputs"));
+ while (iter.hasMoreElements()) {
+ File inputFile = (File) iter.nextElement();
+ // What's the working directory? If local, then its the
+ // folder of the input file. Otherwise, its the "current" dir..
+ File workingDir;
+ if ( localRoot ) {
+ workingDir = inputFile.getParentFile();
+ } else {
+ workingDir = FILE_UTILS.resolveFile(new File("."), ".");
+ }
+
+
+ File propertyFile = getGoldfile(inputFile, keepRoot, collapse,
+ semantic, include, localRoot);
+ if (!propertyFile.exists()) {
+// System.out.println("Skipping as "
+// + propertyFile.getAbsolutePath()
+// + ") doesn't exist.");
+ continue;
+ }
+
+ // System.out.println(msg + " (" + propertyFile.getName() + ") in (" + workingDir + ")");
+
+ Project p = new Project();
+
+ XmlProperty xmlproperty = new XmlProperty();
+ xmlproperty.setProject(p);
+ xmlproperty.setFile(inputFile);
+
+ xmlproperty.setKeeproot(keepRoot);
+ xmlproperty.setCollapseAttributes(collapse);
+ xmlproperty.setSemanticAttributes(semantic);
+ xmlproperty.setIncludeSemanticAttribute(include);
+ xmlproperty.setRootDirectory(workingDir);
+
+ // Set a property on the project to make sure that loading
+ // a property with the same name from an xml file will
+ // *not* change it.
+ p.setNewProperty("override.property.test", "foo");
+
+ xmlproperty.execute();
+
+ Properties props = new Properties();
+ props.load(new FileInputStream(propertyFile));
+
+ //printProperties(p.getProperties());
+
+ ensureProperties(msg, inputFile, workingDir, p, props);
+ ensureReferences(msg, inputFile, p.getReferences());
+
+ }
+ }
+
+ /**
+ * Make sure every property loaded from the goldfile was also
+ * read from the XmlProperty. We could try and test the other way,
+ * but some other properties may get set in the XmlProperty due
+ * to generic Project/Task configuration.
+ */
+ private static void ensureProperties (String msg, File inputFile,
+ File workingDir, Project p,
+ Properties properties) {
+ Hashtable xmlproperties = p.getProperties();
+ // Every key identified by the Properties must have been loaded.
+ Enumeration propertyKeyEnum = properties.propertyNames();
+ while(propertyKeyEnum.hasMoreElements()){
+ String currentKey = propertyKeyEnum.nextElement().toString();
+ String assertMsg = msg + "-" + inputFile.getName()
+ + " Key=" + currentKey;
+
+ String propertyValue = properties.getProperty(currentKey);
+
+ String xmlValue = (String)xmlproperties.get(currentKey);
+
+ if (propertyValue.startsWith("ID.")) {
+ // The property is an id's thing -- either a property
+ // or a path. We need to make sure
+ // that the object was created with the given id.
+ // We don't have an adequate way of testing the actual
+ // *value* of the Path object, though...
+ String id = currentKey;
+ Object obj = p.getReferences().get(id);
+
+ if ( obj == null ) {
+ fail(assertMsg + " Object ID does not exist.");
+ }
+
+ // What is the property supposed to be?
+ propertyValue =
+ propertyValue.substring(3, propertyValue.length());
+ if (propertyValue.equals("path")) {
+ if (!(obj instanceof Path)) {
+ fail(assertMsg + " Path ID is a "
+ + obj.getClass().getName());
+ }
+ } else {
+ assertEquals(assertMsg, propertyValue, obj.toString());
+ }
+
+ } else {
+
+ if (propertyValue.startsWith("FILE.")) {
+ // The property is the name of a file. We are testing
+ // a location attribute, so we need to resolve the given
+ // file name in the provided folder.
+ String fileName =
+ propertyValue.substring(5, propertyValue.length());
+ File f = new File(workingDir, fileName);
+ propertyValue = f.getAbsolutePath();
+ }
+
+ assertEquals(assertMsg, propertyValue, xmlValue);
+ }
+
+ }
+ }
+
+ /**
+ * Debugging method to print the properties in the given hashtable
+ */
+ private static void printProperties(Hashtable xmlproperties) {
+ Enumeration keyEnum = xmlproperties.keys();
+ while (keyEnum.hasMoreElements()) {
+ String currentKey = keyEnum.nextElement().toString();
+ System.out.println(currentKey + " = "
+ + xmlproperties.get(currentKey));
+ }
+ }
+
+ /**
+ * Ensure all references loaded by the project are valid.
+ */
+ private static void ensureReferences (String msg, File inputFile,
+ Hashtable references) {
+ Enumeration referenceKeyEnum = references.keys();
+ while(referenceKeyEnum.hasMoreElements()){
+ String currentKey = referenceKeyEnum.nextElement().toString();
+ Object currentValue = references.get(currentKey);
+
+ if (currentValue instanceof Path) {
+ } else if (currentValue instanceof String) {
+ } else {
+ if( ! currentKey.startsWith("ant.") ) {
+ fail(msg + "-" + inputFile.getName() + " Key="
+ + currentKey + " is not a recognized type.");
+ }
+ }
+ }
+ }
+
+ /**
+ * Munge the name of the input file to find an appropriate goldfile,
+ * based on hardwired naming conventions.
+ */
+ private static File getGoldfile (File input, boolean keepRoot,
+ boolean collapse, boolean semantic,
+ boolean include, boolean localRoot) {
+ // Substitute .xml with .properties
+ String baseName = input.getName().toLowerCase();
+ if (baseName.endsWith(".xml")) {
+ baseName = baseName.substring(0, baseName.length() - 4)
+ + ".properties";
+ }
+
+ File dir = input.getParentFile().getParentFile();
+
+ String goldFileFolder = "goldfiles/";
+
+ if (keepRoot) {
+ goldFileFolder += "keeproot-";
+ } else {
+ goldFileFolder += "nokeeproot-";
+ }
+
+ if (semantic) {
+ goldFileFolder += "semantic-";
+ if (include) {
+ goldFileFolder += "include-";
+ }
+ } else {
+ if (collapse) {
+ goldFileFolder += "collapse-";
+ } else {
+ goldFileFolder += "nocollapse-";
+ }
+ }
+
+ return new File(dir, goldFileFolder + baseName);
+ }
+
+ /**
+ * Retrieve a list of xml files in the specified folder
+ * and below.
+ */
+ private static Enumeration getFiles (final File startingDir) {
+ Vector result = new Vector();
+ getFiles(startingDir, result);
+ return result.elements();
+ }
+
+ /**
+ * Collect a list of xml files in the specified folder
+ * and below.
+ */
+ private static void getFiles (final File startingDir, Vector collect) {
+ FileFilter filter = new FileFilter() {
+ public boolean accept (File file) {
+ if (file.isDirectory()) {
+ return true;
+ } else {
+ return (file.getPath().indexOf("taskdefs") > 0 &&
+ file.getPath().toLowerCase().endsWith(".xml") );
+ }
+ }
+ };
+
+ File[] files = startingDir.listFiles(filter);
+ for (int i=0;i<files.length;i++) {
+ File f = files[i];
+ if (!f.isDirectory()) {
+ collect.addElement(f);
+ } else {
+ getFiles(f, collect);
+ }
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/XmlnsTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/XmlnsTest.java
new file mode 100644
index 00000000..590a4db9
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/XmlnsTest.java
@@ -0,0 +1,89 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.BuildFileRule;
+import org.apache.tools.ant.Task;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+
+public class XmlnsTest {
+
+ @Rule
+ public final BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/xmlns.xml");
+ }
+
+ @Test
+ public void testXmlns() {
+ buildRule.executeTarget("xmlns");
+ assertEquals("MyTask called", buildRule.getLog());
+ }
+
+ @Test
+ public void testXmlnsFile() {
+ buildRule.executeTarget("xmlns.file");
+ assertEquals("MyTask called", buildRule.getLog());
+ }
+
+ @Test
+ public void testCore() {
+ buildRule.executeTarget("core");
+ assertEquals("MyTask called", buildRule.getLog());
+ }
+
+ @Test
+ public void testExcluded() {
+ try {
+ buildRule.executeTarget("excluded");
+ fail("BuildException expected: excluded uri");
+ } catch (BuildException ex) {
+ assertEquals("Attempt to use a reserved URI ant:notallowed", ex.getMessage());
+ }
+ }
+
+ @Test
+ public void testOther() {
+ buildRule.executeTarget("other");
+ assertEquals("a message", buildRule.getLog());
+ }
+
+ @Test
+ public void testNsAttributes() {
+ buildRule.executeTarget("ns.attributes");
+ assertEquals("hello world", buildRule.getLog());
+ }
+
+ public static class MyTask extends Task {
+ public void execute() {
+ log("MyTask called");
+ }
+ }
+
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/ZipExtraFieldTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/ZipExtraFieldTest.java
new file mode 100644
index 00000000..c5a42162
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/ZipExtraFieldTest.java
@@ -0,0 +1,109 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.InputStream;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.Iterator;
+
+import org.apache.tools.ant.types.Resource;
+
+import org.apache.tools.ant.types.ResourceCollection;
+import org.apache.tools.ant.types.resources.ZipResource;
+import org.apache.tools.zip.JarMarker;
+import org.apache.tools.zip.Zip64ExtendedInformationExtraField;
+import org.apache.tools.zip.ZipEntry;
+import org.apache.tools.zip.ZipExtraField;
+import org.apache.tools.zip.ZipFile;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+public class ZipExtraFieldTest {
+
+ @Test
+ public void testPreservesExtraFields() throws IOException {
+ testExtraField(new Zip(), true);
+ }
+
+ public void testDoesntCreateZip64ExtraFieldForJar() throws IOException {
+ testExtraField(new Jar(), false);
+ }
+
+ private void testExtraField(Zip testInstance, boolean expectZip64)
+ throws IOException {
+
+ File f = File.createTempFile("ziptest", ".zip");
+ f.delete();
+ ZipFile zf = null;
+ try {
+ testInstance.setDestFile(f);
+ final ZipResource r = new ZipResource() {
+ public String getName() {
+ return "x";
+ }
+ public boolean isExists() {
+ return true;
+ }
+ public boolean isDirectory() {
+ return false;
+ }
+ public long getLastModified() {
+ return 1;
+ }
+ public InputStream getInputStream() {
+ return new ByteArrayInputStream(new byte[0]);
+ }
+ public ZipExtraField[] getExtraFields() {
+ return new ZipExtraField[] {
+ new JarMarker()
+ };
+ }
+ };
+ testInstance.add(new ResourceCollection() {
+ public boolean isFilesystemOnly() { return false; }
+ public int size() { return 1; }
+ public Iterator<Resource> iterator() {
+ return Collections.<Resource>singleton(r).iterator();
+ }
+ });
+ testInstance.execute();
+
+ zf = new ZipFile(f);
+ ZipEntry ze = zf.getEntry("x");
+ assertNotNull(ze);
+ assertEquals(expectZip64 ? 2 : 1, ze.getExtraFields().length);
+ assertTrue(ze.getExtraFields()[0] instanceof JarMarker);
+ if (expectZip64) {
+ assertTrue(ze.getExtraFields()[1]
+ instanceof Zip64ExtendedInformationExtraField);
+ }
+ } finally {
+ ZipFile.closeQuietly(zf);
+ if (f.exists()) {
+ f.delete();
+ }
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/ZipTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/ZipTest.java
new file mode 100644
index 00000000..5a7a3590
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/ZipTest.java
@@ -0,0 +1,300 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipException;
+import java.util.zip.ZipFile;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.BuildFileRule;
+import org.apache.tools.ant.util.FileUtils;
+import org.apache.tools.zip.UnixStat;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.apache.tools.ant.AntAssert.assertContains;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeTrue;
+
+
+public class ZipTest {
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ //instance variable to allow cleanup
+ ZipFile zfPrefixAddsDir = null;
+
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/zip.xml");
+ buildRule.executeTarget("setUp");
+ }
+
+ @Test
+ public void test1() {
+ try {
+ buildRule.executeTarget("test1");
+ fail("BuildException expected: required argument not specified");
+ } catch (BuildException ex) {
+ //TODO assert value
+ }
+ }
+
+ @Test
+ public void test2() {
+ try {
+ buildRule.executeTarget("test2");
+ fail("BuildException expected: required argument not specified");
+ } catch (BuildException ex) {
+ //TODO assert value
+ }
+ }
+
+ @Test
+ public void test3() {
+ try {
+ buildRule.executeTarget("test3");
+ fail("BuildException expected: zip cannot include itself");
+ } catch (BuildException ex) {
+ //TODO assert value
+ }
+ }
+
+ @Test
+ @Ignore("Previously commented out")
+ public void test4() {
+ try {
+ buildRule.executeTarget("test4");
+ fail("BuildException expected: zip cannot include itself");
+ } catch (BuildException ex) {
+ //TODO assert value
+ }
+ }
+
+ @After
+ public void tearDown() {
+ try {
+ if ( zfPrefixAddsDir != null) {
+ zfPrefixAddsDir.close();
+ }
+
+ } catch (IOException e) {
+ //ignored
+ }
+ }
+
+ @Test
+ public void test5() {
+ buildRule.executeTarget("test5");
+ }
+
+
+ @Test
+ public void test6() {
+ buildRule.executeTarget("test6");
+ }
+
+
+ @Test
+ public void test7() {
+ buildRule.executeTarget("test7");
+ }
+
+ @Test
+ public void test8() {
+ buildRule.executeTarget("test8");
+ }
+
+ @Test
+ public void testZipgroupfileset() throws IOException {
+ buildRule.executeTarget("testZipgroupfileset");
+
+ ZipFile zipFile = new ZipFile(new File(buildRule.getProject().getProperty("output"), "zipgroupfileset.zip"));
+
+ assertTrue(zipFile.getEntry("ant.xml") != null);
+ assertTrue(zipFile.getEntry("optional/jspc.xml") != null);
+ assertTrue(zipFile.getEntry("zip/zipgroupfileset3.zip") != null);
+
+ assertTrue(zipFile.getEntry("test6.mf") == null);
+ assertTrue(zipFile.getEntry("test7.mf") == null);
+
+ zipFile.close();
+ }
+
+ @Test
+ public void testUpdateNotNecessary() {
+ buildRule.executeTarget("testUpdateNotNecessary");
+ assertEquals(-1, buildRule.getLog().indexOf("Updating"));
+ }
+
+ @Test
+ public void testUpdateIsNecessary() {
+ buildRule.executeTarget("testUpdateIsNecessary");
+ assertContains("Updating", buildRule.getLog());
+ }
+
+ // Bugzilla Report 18403
+ @Test
+ public void testPrefixAddsDir() throws IOException {
+ buildRule.executeTarget("testPrefixAddsDir");
+ File archive = new File(buildRule.getProject().getProperty("output"), "test3.zip");
+ zfPrefixAddsDir = new ZipFile(archive);
+ ZipEntry ze = zfPrefixAddsDir.getEntry("test/");
+ assertNotNull("test/ has been added", ze);
+
+ }
+
+ // Bugzilla Report 19449
+ @Test
+ public void testFilesOnlyDoesntCauseRecreate() {
+ buildRule.executeTarget("testFilesOnlyDoesntCauseRecreateSetup");
+ File testFile = new File(buildRule.getOutputDir(), "test3.zip");
+ assumeTrue("Could not change file modification time",
+ testFile.setLastModified(testFile.lastModified() - (FileUtils.getFileUtils().getFileTimestampGranularity() * 5)));
+ long l = testFile.lastModified();
+
+ buildRule.executeTarget("testFilesOnlyDoesntCauseRecreate");
+ assertEquals(l, testFile.lastModified());
+ }
+
+ // Bugzilla Report 22865
+ @Test
+ public void testEmptySkip() {
+ buildRule.executeTarget("testEmptySkip");
+ }
+ // Bugzilla Report 30365
+ @Test
+ public void testZipEmptyDir() {
+ buildRule.executeTarget("zipEmptyDir");
+ }
+ // Bugzilla Report 40258
+ @Test
+ public void testZipEmptyDirFilesOnly() {
+ buildRule.executeTarget("zipEmptyDirFilesOnly");
+ }
+ @Test
+ public void testZipEmptyCreate() {
+ buildRule.executeTarget("zipEmptyCreate");
+ assertContains("Note: creating empty", buildRule.getLog());
+ }
+ // Bugzilla Report 25513
+ @Test
+ public void testCompressionLevel() {
+ buildRule.executeTarget("testCompressionLevel");
+ }
+
+ // Bugzilla Report 33412
+ @Test
+ public void testDefaultExcludesAndUpdate()
+ throws ZipException, IOException {
+ buildRule.executeTarget("testDefaultExcludesAndUpdate");
+ ZipFile f = null;
+ try {
+ f = new ZipFile(new File(buildRule.getProject().getProperty("output"), "test3.zip"));
+ assertNotNull("ziptest~ should be included",
+ f.getEntry("ziptest~"));
+ } finally {
+ if (f != null) {
+ f.close();
+ }
+ }
+ }
+
+ @Test
+ public void testFileResource() {
+ buildRule.executeTarget("testFileResource");
+ }
+
+ @Test
+ public void testNonFileResource() {
+ buildRule.executeTarget("testNonFileResource");
+ }
+
+ @Test
+ public void testTarFileSet() throws IOException {
+ buildRule.executeTarget("testTarFileSet");
+ org.apache.tools.zip.ZipFile zf = null;
+ try {
+ zf = new org.apache.tools.zip.ZipFile(new File(buildRule.getProject().getProperty("output"), "test3.zip"));
+ org.apache.tools.zip.ZipEntry ze = zf.getEntry("asf-logo.gif");
+ assertEquals(UnixStat.FILE_FLAG | 0446, ze.getUnixMode());
+ } finally {
+ if (zf != null) {
+ zf.close();
+ }
+ }
+ }
+
+ @Test
+ public void testRewriteZeroPermissions() throws IOException {
+ buildRule.executeTarget("rewriteZeroPermissions");
+ org.apache.tools.zip.ZipFile zf = null;
+ try {
+ zf = new org.apache.tools.zip.ZipFile(new File(buildRule.getProject().getProperty("output"), "test3.zip"));
+ org.apache.tools.zip.ZipEntry ze = zf.getEntry("testdir/test.txt");
+ assertEquals(UnixStat.FILE_FLAG | 0644, ze.getUnixMode());
+ } finally {
+ if (zf != null) {
+ zf.close();
+ }
+ }
+ }
+
+ @Test
+ public void testAcceptZeroPermissions() throws IOException {
+ buildRule.executeTarget("acceptZeroPermissions");
+ org.apache.tools.zip.ZipFile zf = null;
+ try {
+ zf = new org.apache.tools.zip.ZipFile(new File(buildRule.getProject().getProperty("output"), "test3.zip"));
+ org.apache.tools.zip.ZipEntry ze = zf.getEntry("testdir/test.txt");
+ assertEquals(0000, ze.getUnixMode());
+ } finally {
+ if (zf != null) {
+ zf.close();
+ }
+ }
+ }
+
+ @Test
+ public void testForBugzilla34764() throws IOException {
+ buildRule.executeTarget("testForBugzilla34764");
+ org.apache.tools.zip.ZipFile zf = null;
+ try {
+ zf = new org.apache.tools.zip.ZipFile(new File(buildRule.getProject().getProperty("output"), "test3.zip"));
+ org.apache.tools.zip.ZipEntry ze = zf.getEntry("file1");
+ assertEquals(UnixStat.FILE_FLAG | 0644, ze.getUnixMode());
+ } finally {
+ if (zf != null) {
+ zf.close();
+ }
+ }
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/compilers/DefaultCompilerAdapterTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/compilers/DefaultCompilerAdapterTest.java
new file mode 100644
index 00000000..750098f9
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/compilers/DefaultCompilerAdapterTest.java
@@ -0,0 +1,223 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.compilers;
+
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.Javac;
+import org.apache.tools.ant.types.Commandline;
+import org.junit.Test;
+
+import static org.apache.tools.ant.AntAssert.assertContains;
+import static org.junit.Assert.assertEquals;
+
+public class DefaultCompilerAdapterTest {
+
+ private static class LogCapturingJavac extends Javac {
+ private StringBuffer sb = new StringBuffer();
+ public void log(String msg, int msgLevel) {
+ sb.append(msg);
+ }
+ String getLog() {
+ return sb.toString();
+ }
+ }
+
+ private static class SourceTargetHelper extends DefaultCompilerAdapter {
+ /**
+ * Overridden to have no effect.
+ */
+ protected Commandline setupJavacCommandlineSwitches(Commandline cmd,
+ boolean debug) {
+ return cmd;
+ }
+
+ public boolean execute() { return false; }
+
+ /**
+ * public to avoid classloader issues.
+ */
+ public Commandline setupModernJavacCommandlineSwitches(Commandline cmd) {
+ return super.setupModernJavacCommandlineSwitches(cmd);
+ }
+ }
+
+ @Test
+ public void testSourceIsIgnoredForJavac13() {
+ testSource(null, "javac1.3", "", null, "1.1");
+ testSource(null, "javac1.3", "", null, "1.2");
+ testSource(null, "javac1.3", "", null, "1.3");
+ testSource(null, "javac1.3", "", null, "1.4");
+ }
+
+ @Test
+ public void testSource11IsUpgradedTo13() {
+ testSource("1.3", "javac1.4", "", null, "1.1");
+ testSource("1.3", "javac1.5", "", null, "1.1");
+ testSource("1.3", "javac1.6", "", null, "1.1");
+ testSource("1.3", "javac1.7", "", null, "1.1");
+ testSource("1.3", "javac1.8", "", null, "1.1");
+ }
+
+ @Test
+ public void testSource12IsUpgradedTo13() {
+ testSource("1.3", "javac1.4", "", null, "1.2");
+ testSource("1.3", "javac1.5", "", null, "1.2");
+ testSource("1.3", "javac1.6", "", null, "1.2");
+ testSource("1.3", "javac1.7", "", null, "1.2");
+ testSource("1.3", "javac1.8", "", null, "1.2");
+ }
+
+ @Test
+ public void testImplicitSourceForJava15() {
+ commonSourceDowngrades("javac1.5");
+ testSource(null, "javac1.5", "", "1.5");
+ testSource(null, "javac1.5", "", "5");
+ }
+
+ @Test
+ public void testImplicitSourceForJava16() {
+ commonSourceDowngrades("javac1.6");
+ testSource(null, "javac1.6", "", "1.5");
+ testSource(null, "javac1.6", "", "5");
+ testSource(null, "javac1.6", "", "1.6");
+ testSource(null, "javac1.6", "", "6");
+ }
+
+ @Test
+ public void testImplicitSourceForJava17() {
+ commonSourceDowngrades("javac1.7");
+ testSource("1.5", "javac1.7",
+ "If you specify -target 1.5 you now must also specify"
+ + " -source 1.5", "1.5");
+ testSource("1.6", "javac1.7",
+ "If you specify -target 1.6 you now must also specify"
+ + " -source 1.6", "1.6");
+ testSource("5", "javac1.7",
+ "If you specify -target 5 you now must also specify"
+ + " -source 5", "5");
+ testSource("6", "javac1.7",
+ "If you specify -target 6 you now must also specify"
+ + " -source 6", "6");
+ testSource(null, "javac1.7", "", "1.7");
+ testSource(null, "javac1.7", "", "7");
+ }
+
+ @Test
+ public void testImplicitSourceForJava18() {
+ commonSourceDowngrades("javac1.8");
+ testSource("1.5", "javac1.8",
+ "If you specify -target 1.5 you now must also specify"
+ + " -source 1.5", "1.5");
+ testSource("1.6", "javac1.8",
+ "If you specify -target 1.6 you now must also specify"
+ + " -source 1.6", "1.6");
+ testSource("1.7", "javac1.8",
+ "If you specify -target 1.7 you now must also specify"
+ + " -source 1.7", "1.7");
+ testSource("5", "javac1.8",
+ "If you specify -target 5 you now must also specify"
+ + " -source 5", "5");
+ testSource("6", "javac1.8",
+ "If you specify -target 6 you now must also specify"
+ + " -source 6", "6");
+ testSource("7", "javac1.8",
+ "If you specify -target 7 you now must also specify"
+ + " -source 7", "7");
+ testSource(null, "javac1.8", "", "1.8");
+ testSource(null, "javac1.8", "", "8");
+ }
+
+ @Test
+ public void testImplicitSourceForJava19() {
+ commonSourceDowngrades("javac1.9");
+ testSource("1.5", "javac1.9",
+ "If you specify -target 1.5 you now must also specify"
+ + " -source 1.5", "1.5");
+ testSource("1.6", "javac1.9",
+ "If you specify -target 1.6 you now must also specify"
+ + " -source 1.6", "1.6");
+ testSource("1.7", "javac1.9",
+ "If you specify -target 1.7 you now must also specify"
+ + " -source 1.7", "1.7");
+ testSource("1.8", "javac1.9",
+ "If you specify -target 1.8 you now must also specify"
+ + " -source 1.8", "1.8");
+ testSource("5", "javac1.9",
+ "If you specify -target 5 you now must also specify"
+ + " -source 5", "5");
+ testSource("6", "javac1.9",
+ "If you specify -target 6 you now must also specify"
+ + " -source 6", "6");
+ testSource("7", "javac1.9",
+ "If you specify -target 7 you now must also specify"
+ + " -source 7", "7");
+ testSource("8", "javac1.9",
+ "If you specify -target 8 you now must also specify"
+ + " -source 8", "8");
+ testSource(null, "javac1.9", "", "1.9");
+ testSource(null, "javac1.9", "", "9");
+ }
+
+ private void commonSourceDowngrades(String javaVersion) {
+ testSource("1.3", javaVersion,
+ "If you specify -target 1.1 you now must also specify"
+ + " -source 1.3", "1.1");
+ testSource("1.3", javaVersion,
+ "If you specify -target 1.2 you now must also specify"
+ + " -source 1.3", "1.2");
+ testSource("1.3", javaVersion,
+ "If you specify -target 1.3 you now must also specify"
+ + " -source 1.3", "1.3");
+ testSource("1.4", javaVersion,
+ "If you specify -target 1.4 you now must also specify"
+ + " -source 1.4", "1.4");
+ }
+
+ private void testSource(String expectedSource, String javaVersion,
+ String expectedLog, String configuredTarget) {
+ testSource(expectedSource, javaVersion, expectedLog, configuredTarget,
+ null);
+ }
+
+ private void testSource(String expectedSource, String javaVersion,
+ String expectedLog, String configuredTarget,
+ String configuredSource) {
+ LogCapturingJavac javac = new LogCapturingJavac();
+ javac.setProject(new Project());
+ javac.setCompiler(javaVersion);
+ javac.setSource(configuredSource);
+ javac.setTarget(configuredTarget);
+ SourceTargetHelper sth = new SourceTargetHelper();
+ sth.setJavac(javac);
+ Commandline cmd = new Commandline();
+ sth.setupModernJavacCommandlineSwitches(cmd);
+ if ("".equals(expectedLog)) {
+ assertEquals("", javac.getLog());
+ } else {
+ String l = javac.getLog();
+ assertContains(expectedLog, l);
+ }
+ String[] args = cmd.getCommandline();
+ assertEquals(expectedSource == null ? 0 : 2, args.length);
+ if (expectedSource != null) {
+ assertEquals("-source", args[0]);
+ assertEquals(expectedSource, args[1]);
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/condition/AntVersionTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/condition/AntVersionTest.java
new file mode 100644
index 00000000..b70a1381
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/condition/AntVersionTest.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.condition;
+
+import org.apache.tools.ant.BuildFileRule;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+/**
+ * Testcases for the &lt;antversion&gt; condition.
+ *
+ */
+public class AntVersionTest {
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() throws Exception {
+ buildRule.configureProject("src/etc/testcases/taskdefs/conditions/antversion.xml");
+ }
+
+ @Test
+ public void testAtLeast() {
+ buildRule.executeTarget("testatleast");
+ }
+
+ @Test
+ public void testExactly() {
+ buildRule.executeTarget("testexactly");
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/condition/ContainsTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/condition/ContainsTest.java
new file mode 100644
index 00000000..a45b511a
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/condition/ContainsTest.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.condition;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Testcase for the &lt;contains&gt; condition.
+ *
+ */
+public class ContainsTest {
+
+ @Test
+ public void testCaseSensitive() {
+ Contains con = new Contains();
+ con.setString("abc");
+ con.setSubstring("A");
+ assertTrue(!con.eval());
+
+ con.setCasesensitive(false);
+ assertTrue(con.eval());
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/condition/EqualsTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/condition/EqualsTest.java
new file mode 100644
index 00000000..5f9b996a
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/condition/EqualsTest.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.condition;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Testcase for the &lt;equals&gt; condition.
+ *
+ */
+public class EqualsTest {
+
+ @Test
+ public void testTrim() {
+ Equals eq = new Equals();
+ eq.setArg1("a");
+ eq.setArg2(" a");
+ assertTrue(!eq.eval());
+
+ eq.setTrim(true);
+ assertTrue(eq.eval());
+
+ eq.setArg2("a\t");
+ assertTrue(eq.eval());
+ }
+
+ @Test
+ public void testCaseSensitive() {
+ Equals eq = new Equals();
+ eq.setArg1("a");
+ eq.setArg2("A");
+ assertTrue(!eq.eval());
+
+ eq.setCasesensitive(false);
+ assertTrue(eq.eval());
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/condition/HttpTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/condition/HttpTest.java
new file mode 100644
index 00000000..15a9d2d3
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/condition/HttpTest.java
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.condition;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.BuildFileRule;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.fail;
+
+/**
+ * Testcases for the &lt;http&gt; condition. All these tests require
+ * us to be online as they attempt to get the status of various pages
+ * on the Ant Apache web site.
+ */
+public class HttpTest {
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/conditions/http.xml");
+ }
+
+ @Test
+ public void testNoMethod() {
+ buildRule.executeTarget("basic-no-method");
+ assertEquals("true", buildRule.getProject().getProperty("basic-no-method"));
+ assertNull(buildRule.getProject().getProperty("basic-no-method-bad-url"));
+ }
+
+ @Test
+ public void testHeadRequest() {
+ buildRule.executeTarget("test-head-request");
+ assertEquals("true", buildRule.getProject().getProperty("test-head-request"));
+ assertNull(buildRule.getProject().getProperty("test-head-request-bad-url"));
+ }
+
+ @Test
+ public void testGetRequest() {
+ buildRule.executeTarget("test-get-request");
+ assertEquals("true", buildRule.getProject().getProperty("test-get-request"));
+ assertNull(buildRule.getProject().getProperty("test-get-request-bad-url"));
+ }
+
+ @Test
+ public void testBadRequestMethod() {
+ try {
+ buildRule.executeTarget("bad-request-method");
+ fail("Exception should have been thrown as invalid HTTP request method specified");
+ } catch (BuildException ex) {
+ //TODO we should assert the correct build exception was thrown
+ }
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/condition/IsFailureTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/condition/IsFailureTest.java
new file mode 100644
index 00000000..86594765
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/condition/IsFailureTest.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.condition;
+
+import org.apache.tools.ant.BuildFileRule;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+/**
+ * Testcases for the &lt;isfailure&gt; condition.
+ *
+ */
+public class IsFailureTest {
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/conditions/isfailure.xml");
+ }
+
+ @Test
+ public void testIsFailure() {
+ buildRule.executeTarget("testisfailure");
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/condition/IsFileSelectedTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/condition/IsFileSelectedTest.java
new file mode 100644
index 00000000..84d88a55
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/condition/IsFileSelectedTest.java
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.condition;
+
+import org.apache.tools.ant.AntAssert;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.BuildFileRule;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.fail;
+
+/**
+ * Testcase for the &lt;isfileselected&gt; condition.
+ *
+ */
+public class IsFileSelectedTest {
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/conditions/isfileselected.xml");
+ }
+
+ @Test
+ public void testSimple() {
+ buildRule.executeTarget("simple");
+ }
+
+ @Test
+ public void testName() {
+ buildRule.executeTarget("name");
+ }
+
+ @Test
+ public void testBaseDir() {
+ buildRule.executeTarget("basedir");
+ }
+
+ @Test
+ public void testType() {
+ buildRule.executeTarget("type");
+ }
+
+ @Test
+ public void testNotSelector() {
+ try {
+ buildRule.executeTarget("not.selector");
+ fail("Exception should have been thrown: checking for use as a selector (not allowed)");
+ } catch(BuildException ex) {
+ AntAssert.assertContains("fileset doesn't support the nested \"isfile",
+ ex.getMessage());
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/condition/IsReachableTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/condition/IsReachableTest.java
new file mode 100644
index 00000000..d036834c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/condition/IsReachableTest.java
@@ -0,0 +1,116 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.condition;
+
+import org.apache.tools.ant.AntAssert;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.BuildFileRule;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+/**
+ * test for reachable things
+ */
+public class IsReachableTest {
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject(
+ "src/etc/testcases/taskdefs/conditions/isreachable.xml");
+ }
+
+
+ @Test
+ public void testLocalhost() throws Exception {
+ buildRule.executeTarget("testLocalhost");
+ }
+
+ @Test
+ public void testLocalhostURL() throws Exception {
+ buildRule.executeTarget("testLocalhostURL");
+ }
+
+ @Test
+ public void testIpv4localhost() throws Exception {
+ buildRule.executeTarget("testIpv4localhost");
+ }
+
+ @Test
+ public void testFTPURL() throws Exception {
+ buildRule.executeTarget("testFTPURL");
+ }
+
+ @Test
+ public void testBoth() throws Exception {
+ try {
+ buildRule.executeTarget("testBoth");
+ fail("Build exception expected: error on two targets");
+ } catch(BuildException ex) {
+ assertEquals(IsReachable.ERROR_BOTH_TARGETS, ex.getMessage());
+ }
+ }
+
+ @Test
+ public void testNoTargets() throws Exception {
+ try {
+ buildRule.executeTarget("testNoTargets");
+ fail("Build exception expected: no params");
+ } catch(BuildException ex) {
+ assertEquals(IsReachable.ERROR_NO_HOSTNAME, ex.getMessage());
+ }
+ }
+
+ @Test
+ public void testBadTimeout() throws Exception {
+ try {
+ buildRule.executeTarget("testBadTimeout");
+ fail("Build exception expected: error on -ve timeout");
+ } catch(BuildException ex) {
+ assertEquals(IsReachable.ERROR_BAD_TIMEOUT, ex.getMessage());
+ }
+ }
+
+ @Test
+ @Ignore("Previously named in a way to prevent execution")
+ public void NotestFile() throws Exception {
+ try {
+ buildRule.executeTarget("testFile");
+ fail("Build exception expected: error on file URL");
+ } catch(BuildException ex) {
+ assertEquals(IsReachable.ERROR_NO_HOST_IN_URL, ex.getMessage());
+ }
+ }
+
+ @Test
+ public void testBadURL() throws Exception {
+ try {
+ buildRule.executeTarget("testBadURL");
+ fail("Build exception expected: error in URL");
+ } catch(BuildException ex) {
+ AntAssert.assertContains(IsReachable.ERROR_BAD_URL, ex.getMessage());
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/condition/IsReferenceTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/condition/IsReferenceTest.java
new file mode 100644
index 00000000..01b6b47c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/condition/IsReferenceTest.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.condition;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.BuildFileRule;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+import static org.junit.Assert.assertNull;
+
+/**
+ * Testcases for the &lt;isreference&gt; condition.
+ *
+ */
+public class IsReferenceTest {
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/conditions/isreference.xml");
+ }
+
+ @Test
+ public void testBasic() {
+ buildRule.executeTarget("basic");
+ assertEquals("true", buildRule.getProject().getProperty("global-path"));
+ assertEquals("true", buildRule.getProject().getProperty("target-path"));
+ assertNull(buildRule.getProject().getProperty("undefined"));
+ }
+
+ @Test
+ public void testNotEnoughArgs() {
+ try {
+ buildRule.executeTarget("isreference-incomplete");
+ fail("Build exception expected: refid attirbute has been omitted");
+ } catch(BuildException ex) {
+ assertEquals("No reference specified for isreference condition", ex.getMessage());
+ }
+ }
+
+ @Test
+ public void testType() {
+ buildRule.executeTarget("type");
+ assertEquals("true", buildRule.getProject().getProperty("global-path"));
+ assertNull(buildRule.getProject().getProperty("global-path-as-fileset"));
+ assertNull(buildRule.getProject().getProperty("global-path-as-foo"));
+ assertEquals("true", buildRule.getProject().getProperty("global-echo"));
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/condition/IsSignedTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/condition/IsSignedTest.java
new file mode 100644
index 00000000..0f4001c3
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/condition/IsSignedTest.java
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.condition;
+
+import org.apache.tools.ant.BuildFileRule;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+/**
+ * Testcase for the &lt;issigned&gt; condition.
+ *
+ */
+public class IsSignedTest {
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/conditions/issigned.xml");
+ }
+
+ @Test
+ public void testPass() {
+ buildRule.executeTarget("pass");
+ }
+
+ @Test
+ public void testPassword() {
+ buildRule.executeTarget("password");
+ }
+
+ @Test
+ public void testAPassword() {
+ buildRule.executeTarget("apassword");
+ }
+
+ @Test
+ public void testAllSigned() {
+ buildRule.executeTarget("allsigned");
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/condition/ParserSupportsTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/condition/ParserSupportsTest.java
new file mode 100644
index 00000000..2a2354ff
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/condition/ParserSupportsTest.java
@@ -0,0 +1,95 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.condition;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.BuildFileRule;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+/**
+
+ */
+public class ParserSupportsTest {
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/conditions/parsersupports.xml");
+ }
+
+ @Test
+ public void testEmpty() {
+ try {
+ buildRule.executeTarget("testEmpty");
+ fail("Build exception expected: " + ParserSupports.ERROR_NO_ATTRIBUTES);
+ } catch(BuildException ex) {
+ assertEquals(ParserSupports.ERROR_NO_ATTRIBUTES, ex.getMessage());
+ }
+ }
+
+ @Test
+ public void testBoth() {
+ try {
+ buildRule.executeTarget("testBoth");
+ fail("Build exception expected: " + ParserSupports.ERROR_BOTH_ATTRIBUTES);
+ } catch(BuildException ex) {
+ assertEquals(ParserSupports.ERROR_BOTH_ATTRIBUTES, ex.getMessage());
+ }
+ }
+
+ @Test
+ public void testNamespaces() {
+ buildRule.executeTarget("testNamespaces");
+ }
+
+ @Test
+ public void testPropertyNoValue() {
+ try {
+ buildRule.executeTarget("testPropertyNoValue");
+ fail("Build exception expected: " + ParserSupports.ERROR_NO_VALUE);
+ } catch(BuildException ex) {
+ assertEquals(ParserSupports.ERROR_NO_VALUE, ex.getMessage());
+ }
+ }
+
+ @Test
+ public void testUnknownProperty() {
+ buildRule.executeTarget("testUnknownProperty");
+ }
+
+ @Test
+ @Ignore("Previously named in a manner to prevent execution")
+ public void NotestPropertyInvalid() {
+ buildRule.executeTarget("testPropertyInvalid");
+ }
+
+ @Test
+ @Ignore("Previously named in a manner to prevent execution")
+ public void NotestXercesProperty() {
+ buildRule.executeTarget("testXercesProperty");
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/condition/TypeFoundTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/condition/TypeFoundTest.java
new file mode 100644
index 00000000..ab284943
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/condition/TypeFoundTest.java
@@ -0,0 +1,91 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.condition;
+
+import org.apache.tools.ant.AntAssert;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.BuildFileRule;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+import static org.junit.Assert.assertNull;
+
+/**
+ * test the typeexists condition
+ */
+public class TypeFoundTest {
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/conditions/typefound.xml");
+ }
+
+ @Test
+ public void testTask() {
+ buildRule.executeTarget("testTask");
+ assertEquals("true", buildRule.getProject().getProperty("testTask"));
+ }
+
+ @Test
+ public void testUndefined() {
+ try {
+ buildRule.executeTarget("testUndefined");
+ fail("Build exception expected: left out the name attribute");
+ } catch(BuildException ex) {
+ AntAssert.assertContains("No type specified", ex.getMessage());
+ }
+ }
+
+ @Test
+ public void testTaskThatIsntDefined() {
+ buildRule.executeTarget("testTaskThatIsntDefined");
+ assertNull(buildRule.getProject().getProperty("testTaskThatIsntDefined"));
+ }
+
+ @Test
+ public void testTaskThatDoesntReallyExist() {
+ buildRule.executeTarget("testTaskThatDoesntReallyExist");
+ assertNull(buildRule.getProject().getProperty("testTaskThatDoesntReallyExist"));
+ }
+
+ @Test
+ public void testType() {
+ buildRule.executeTarget("testType");
+ assertEquals("true", buildRule.getProject().getProperty("testType"));
+ }
+
+ @Test
+ public void testPreset() {
+ buildRule.executeTarget("testPreset");
+ assertEquals("true", buildRule.getProject().getProperty("testPreset"));
+ }
+
+ @Test
+ public void testMacro() {
+ buildRule.executeTarget("testMacro");
+ assertEquals("true", buildRule.getProject().getProperty("testMacro"));
+ }
+
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/condition/XorTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/condition/XorTest.java
new file mode 100644
index 00000000..4f04c357
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/condition/XorTest.java
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.condition;
+
+import org.apache.tools.ant.BuildFileRule;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+/**
+ * Test that Xor follows the conventional boolean logic semantics
+ * (a ^ b) === (a||b)&!(a&&b)
+ */
+public class XorTest {
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/conditions/xor.xml");
+ }
+
+ @Test
+ public void testEmpty() {
+ buildRule.executeTarget("testEmpty");
+ }
+
+ @Test
+ public void test0() {
+ buildRule.executeTarget("test0");
+ }
+
+ @Test
+ public void test1() {
+ buildRule.executeTarget("test1");
+ }
+
+ @Test
+ public void test00() {
+ buildRule.executeTarget("test00");
+ }
+
+ @Test
+ public void test10() {
+ buildRule.executeTarget("test10");
+ }
+
+ @Test
+ public void test01() {
+ buildRule.executeTarget("test01");
+ }
+
+ @Test
+ public void test11() {
+ buildRule.executeTarget("test11");
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/cvslib/ChangeLogParserTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/cvslib/ChangeLogParserTest.java
new file mode 100644
index 00000000..3dfaf8dd
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/cvslib/ChangeLogParserTest.java
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.cvslib;
+
+import org.junit.Test;
+
+import java.util.Calendar;
+import java.util.Locale;
+import java.util.TimeZone;
+import java.util.Date;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * Minimal test of the parser implementation
+ */
+public class ChangeLogParserTest {
+
+ protected ChangeLogParser parser = new ChangeLogParser();
+
+ @Test
+ public void testOldCvsFormat() throws Exception {
+ parser.stdout("Working file: build.xml");
+ parser.stdout("revision 1.475");
+ parser.stdout("date: 2004/06/05 16:10:32; author: somebody; state: Exp; lines: +2 -2");
+ parser.stdout("I have done something. I swear.");
+ parser.stdout("=============================================================================");
+ CVSEntry[] entries = parser.getEntrySetAsArray();
+ assertEquals("somebody", entries[0].getAuthor());
+ Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"), Locale.US);
+ cal.set(Calendar.MILLISECOND, 0);
+ cal.set(2004, Calendar.JUNE, 5, 16, 10, 32);
+ Date date = cal.getTime();
+ assertEquals(date, entries[0].getDate());
+ }
+
+ @Test
+ public void testCvs112Format() throws Exception {
+ parser.stdout("Working file: build.xml");
+ parser.stdout("revision 1.475");
+ parser.stdout("date: 2004-06-05 16:10:32 +0000; author: somebody; state: Exp; lines: +2 -2");
+ parser.stdout("I have done something. I swear.");
+ parser.stdout("=============================================================================");
+ CVSEntry[] entries = parser.getEntrySetAsArray();
+ assertEquals("somebody", entries[0].getAuthor());
+ Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"), Locale.US);
+ cal.set(Calendar.MILLISECOND, 0);
+ cal.set(2004, Calendar.JUNE, 5, 16, 10, 32);
+ Date date = cal.getTime();
+ assertEquals(date, entries[0].getDate());
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/cvslib/ChangeLogWriterTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/cvslib/ChangeLogWriterTest.java
new file mode 100644
index 00000000..a2531d8e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/cvslib/ChangeLogWriterTest.java
@@ -0,0 +1,96 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.cvslib;
+
+import java.util.Date;
+import java.io.PrintWriter;
+import java.io.OutputStreamWriter;
+import java.io.ByteArrayOutputStream;
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+
+import org.apache.tools.ant.util.JAXPUtils;
+import org.junit.Test;
+import org.xml.sax.XMLReader;
+import org.xml.sax.InputSource;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
+import org.xml.sax.Locator;
+import org.xml.sax.Attributes;
+
+/**
+ * Test for the cvslib ChangeLogWriter
+ */
+public class ChangeLogWriterTest {
+
+ private ChangeLogWriter writer = new ChangeLogWriter();
+
+ @Test
+ public void testNonUTF8Characters() throws Exception {
+ CVSEntry entry = new CVSEntry(new Date(), "Se\u00f1orita", "2003 < 2004 && 3 > 5");
+ entry.addFile("Medicare & review.doc", "1.1");
+ entry.addFile("El\u00e8ments de style", "1.2");
+ CVSEntry[] entries = { entry };
+
+ ByteArrayOutputStream output = new ByteArrayOutputStream();
+ PrintWriter pwriter = new PrintWriter(new OutputStreamWriter(output, "UTF-8"));
+ writer.printChangeLog(pwriter, entries);
+
+ // make sure that the parsing does not break
+ XMLReader xmlReader = JAXPUtils.getXMLReader();
+ InputStream input = new ByteArrayInputStream(output.toByteArray());
+ xmlReader.setContentHandler(new NullContentHandler());
+ xmlReader.parse(new InputSource(input));
+ }
+
+ public static class NullContentHandler implements ContentHandler {
+ public void endDocument() throws SAXException {
+ }
+
+ public void startDocument() throws SAXException {
+ }
+
+ public void characters(char ch[], int start, int length) throws SAXException {
+ String debug = new String(ch, start, length);
+ }
+
+ public void ignorableWhitespace(char ch[], int start, int length) throws SAXException {
+ }
+
+ public void endPrefixMapping(String prefix) throws SAXException {
+ }
+
+ public void skippedEntity(String name) throws SAXException {
+ }
+
+ public void setDocumentLocator(Locator locator) {
+ }
+
+ public void processingInstruction(String target, String data) throws SAXException {
+ }
+
+ public void startPrefixMapping(String prefix, String uri) throws SAXException {
+ }
+
+ public void endElement(String namespaceURI, String localName, String qName) throws SAXException {
+ }
+
+ public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException {
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/dir1/B.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/dir1/B.java
new file mode 100644
index 00000000..9057fa0c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/dir1/B.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.dir1;
+
+public class B extends org.apache.tools.ant.taskdefs.dir2.A {
+ static {
+ System.out.println("B CLASS INITIALIZATION");
+ setA(new B());
+ }
+
+ public String toString() {
+ return "I am a B.";
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/dir2/A.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/dir2/A.java
new file mode 100644
index 00000000..5186ac4c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/dir2/A.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.dir2;
+
+public class A {
+ public static void main(String [] args) {
+ System.out.println("MAIN");
+ System.out.println(a);
+ }
+
+ static A a=new A();
+
+ static {
+ System.out.println("A CLASS INITIALIZATION");
+ }
+
+ protected static void setA(A oa) {
+ a=oa;
+ }
+
+ public String toString() {
+ return "I am a A.";
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/email/EmailAddressTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/email/EmailAddressTest.java
new file mode 100644
index 00000000..31ecafba
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/email/EmailAddressTest.java
@@ -0,0 +1,112 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.email;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+/**
+ * @since Ant 1.6
+ */
+public class EmailAddressTest {
+
+ @Test
+ public void test1() {
+ expectNameAddress( new EmailAddress("address (name)") );
+ }
+
+ @Test
+ public void test2() {
+ expectNameAddress( new EmailAddress("(name) address") );
+ }
+
+ @Test
+ public void test3() {
+ expectNameAddress( new EmailAddress("name <address>") );
+ }
+
+ @Test
+ public void test4() {
+ expectNameAddress( new EmailAddress("<address> name") );
+ }
+
+ @Test
+ public void test5() {
+ expectNameAddress( new EmailAddress("<address> (name)") );
+ }
+
+ @Test
+ public void test6() {
+ expectNameAddress( new EmailAddress("(name) <address>") );
+ }
+
+ @Test
+ public void test7() {
+ expectNameAddress2( new EmailAddress("address (<name>)") );
+ }
+
+ @Test
+ public void test8() {
+ expectNameAddress2( new EmailAddress("(<name>) address") );
+ }
+
+ @Test
+ public void test9() {
+ expectNameAddress3( new EmailAddress("address") );
+ }
+
+ @Test
+ public void testA() {
+ expectNameAddress3( new EmailAddress("<address>") );
+ }
+
+ @Test
+ public void testB() {
+ expectNameAddress3( new EmailAddress(" <address> ") );
+ }
+
+ @Test
+ public void testC() {
+ expectNameAddress3( new EmailAddress("< address >") );
+ }
+
+ @Test
+ public void testD() {
+ expectNameAddress3( new EmailAddress(" < address > ") );
+ }
+
+ private void expectNameAddress(EmailAddress e) {
+ assertEquals( "name", e.getName() );
+ assertEquals( "address", e.getAddress() );
+ }
+
+ // where the name contains <>
+ private void expectNameAddress2(EmailAddress e) {
+ assertEquals( "<name>", e.getName() );
+ assertEquals( "address", e.getAddress() );
+ }
+
+ // where only an address is supplied
+ private void expectNameAddress3(EmailAddress e) {
+ assertNull("Expected null, found <" + e.getName() + ">", e.getName());
+ assertEquals( "address", e.getAddress() );
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/email/EmailTaskTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/email/EmailTaskTest.java
new file mode 100644
index 00000000..6363f90d
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/email/EmailTaskTest.java
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.email;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.BuildFileRule;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.fail;
+
+/**
+ * TODO : develop these testcases - the email task needs to have attributes allowing
+ * to simulate sending mail and to catch the output in text files or streams
+ */
+public class EmailTaskTest {
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/email/mail.xml");
+ }
+
+ @Test
+ public void test1() {
+ try {
+ buildRule.executeTarget("test1");
+ fail("Build exception expected: SMTP auth only possibly with MIME mail");
+ } catch(BuildException ex) {
+ //TODO assert exception message
+ }
+ }
+
+ @Test
+ public void test2() {
+ try {
+ buildRule.executeTarget("test2");
+ fail("Build exception expected: SSL only possibly with MIME mail");
+ } catch(BuildException ex) {
+ //TODO assert exception message
+ }
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/email/MessageTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/email/MessageTest.java
new file mode 100644
index 00000000..df75067f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/email/MessageTest.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.email;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.util.FileUtils;
+import org.junit.After;
+import org.junit.Test;
+
+public class MessageTest {
+ private static final File f = new File(System.getProperty("java.io.tmpdir"),
+ "message.txt");
+ /**
+ * test for bugzilla 48932
+ */
+ @Test
+ public void testPrintStreamDoesNotGetClosed() throws IOException {
+ Message ms = new Message();
+ Project p = new Project();
+ ms.setProject(p);
+ ms.addText("hi, this is an email");
+ FileOutputStream fis = null;
+ try {
+ fis = new FileOutputStream(f);
+ ms.print(new PrintStream(fis));
+ fis.write(120);
+ } finally {
+ FileUtils.close(fis);
+ }
+
+ }
+
+ @After
+ public void tearDown() {
+ if (f.exists()) {
+ FileUtils fu = FileUtils.getFileUtils();
+ fu.tryHardToDelete(f);
+ }
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/ANTLRTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/ANTLRTest.java
new file mode 100644
index 00000000..92584483
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/ANTLRTest.java
@@ -0,0 +1,216 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.BuildFileRule;
+import org.apache.tools.ant.FileUtilities;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import java.io.File;
+import java.io.FilenameFilter;
+
+import static org.apache.tools.ant.AntAssert.assertContains;
+import static org.apache.tools.ant.AntAssert.assertNotContains;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+/**
+ * If you want to run tests, it is highly recommended
+ * to download ANTLR (www.antlr.org), build the 'antlrall.jar' jar
+ * with <code>make antlr-all.jar</code> and drop the jar (about 300KB) into
+ * Ant lib.
+ * - Running w/ the default antlr.jar (70KB) does not work (missing class)
+ *
+ * Unless of course you specify the ANTLR classpath in your
+ * system classpath. (see ANTLR install.html)
+ *
+ */
+public class ANTLRTest {
+
+ private final static String TASKDEFS_DIR = "src/etc/testcases/taskdefs/optional/antlr/";
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject(TASKDEFS_DIR + "antlr.xml");
+ }
+
+ @Test
+ public void test1() {
+ try {
+ buildRule.executeTarget("test1");
+ fail("required argument, target, missing");
+ } catch (BuildException ex) {
+ //TODO should check exception message
+ }
+ }
+
+ @Test
+ public void test2() {
+ try {
+ buildRule.executeTarget("test2");
+ fail("Invalid output directory");
+ } catch (BuildException ex) {
+ //TODO should check exception message
+ }
+ }
+
+ @Test
+ public void test3() {
+ buildRule.executeTarget("test3");
+ }
+
+ @Test
+ public void test4() {
+ buildRule.executeTarget("test4");
+ }
+
+ @Test
+ public void test5() {
+ // should print "panic: Cannot find importVocab file 'JavaTokenTypes.txt'"
+ // since it needs to run java.g first before java.tree.g
+ try {
+ buildRule.executeTarget("test5");
+ fail("ANTLR returned: 1");
+ } catch (BuildException ex) {
+ //TODO should check exception message
+ }
+ }
+
+ @Test
+ public void test6() {
+ buildRule.executeTarget("test6");
+ }
+
+ @Test
+ public void test7() {
+ try {
+ buildRule.executeTarget("test7");
+ fail("Unable to determine generated class");
+ } catch (BuildException ex) {
+ //TODO should check exception message
+ }
+ }
+
+ /**
+ * This is a negative test for the super grammar (glib) option.
+ */
+ @Test
+ public void test8() {
+ try {
+ buildRule.executeTarget("test8");
+ fail("Invalid super grammar file");
+ } catch (BuildException ex) {
+ //TODO should check exception message
+ }
+ }
+
+ /**
+ * This is a positive test for the super grammar (glib) option. ANTLR
+ * will throw an error if everything is not correct.
+ */
+ @Test
+ public void test9() {
+ buildRule.executeTarget("test9");
+ }
+
+ /**
+ * This test creates an html-ized version of the calculator grammar.
+ * The sanity check is simply whether or not an html file was generated.
+ */
+ @Test
+ public void test10() {
+ buildRule.executeTarget("test10");
+ File outputDirectory = new File(buildRule.getProject().getProperty("output"));
+ String[] calcFiles = outputDirectory.list(new HTMLFilter());
+ assertTrue(calcFiles.length > 0);
+ }
+
+ /**
+ * This is just a quick sanity check to run the diagnostic option and
+ * make sure that it doesn't throw any funny exceptions.
+ */
+ @Test
+ public void test11() {
+ buildRule.executeTarget("test11");
+ }
+
+ /**
+ * This is just a quick sanity check to run the trace option and
+ * make sure that it doesn't throw any funny exceptions.
+ */
+ @Test
+ public void test12() {
+ buildRule.executeTarget("test12");
+ }
+
+ /**
+ * This is just a quick sanity check to run all the rest of the
+ * trace options (traceLexer, traceParser, and traceTreeWalker) to
+ * make sure that they don't throw any funny exceptions.
+ */
+ @Test
+ public void test13() {
+ buildRule.executeTarget("test13");
+ }
+
+ @Test
+ public void testNoRecompile() {
+ buildRule.executeTarget("test9");
+ assertNotContains("Skipped grammar file.", buildRule.getFullLog());
+ buildRule.executeTarget("noRecompile");
+ assertContains("Skipped grammar file.", buildRule.getFullLog());
+ }
+
+ @Test
+ public void testNormalRecompile() {
+ buildRule.executeTarget("test9");
+ assertNotContains("Skipped grammar file.", buildRule.getFullLog());
+
+ FileUtilities.rollbackTimetamps(buildRule.getOutputDir(), 5);
+
+ buildRule.executeTarget("normalRecompile");
+ assertNotContains("Skipped grammar file.", buildRule.getFullLog());
+ }
+
+ @Test
+ // Bugzilla Report 12961
+ public void testSupergrammarChangeRecompile() {
+ buildRule.executeTarget("test9");
+ assertNotContains("Skipped grammar file.", buildRule.getFullLog());
+
+ FileUtilities.rollbackTimetamps(buildRule.getOutputDir(), 5);
+
+ buildRule.executeTarget("supergrammarChangeRecompile");
+ assertNotContains("Skipped grammar file.", buildRule.getFullLog());
+
+ }
+
+}
+
+class HTMLFilter implements FilenameFilter {
+ public boolean accept(File dir, String name) {
+ return name.endsWith("html");
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/AbstractXSLTLiaisonTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/AbstractXSLTLiaisonTest.java
new file mode 100644
index 00000000..434e81f5
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/AbstractXSLTLiaisonTest.java
@@ -0,0 +1,104 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.net.URL;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import org.apache.tools.ant.taskdefs.XSLTLiaison;
+import org.apache.tools.ant.util.FileUtils;
+import org.junit.Before;
+import org.junit.Test;
+import org.w3c.dom.Document;
+
+/**
+ * Abtract testcase for XSLTLiaison.
+ * Override createLiaison for each XSLTLiaison.
+ *
+ * <a href="sbailliez@apache.org">Stephane Bailliez</a>
+ */
+public abstract class AbstractXSLTLiaisonTest {
+
+ private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+
+ protected XSLTLiaison liaison;
+
+ @Before
+ public void setUp() throws Exception {
+ liaison = createLiaison();
+ }
+
+ // to override
+ protected abstract XSLTLiaison createLiaison() throws Exception ;
+
+ /** load the file from the caller classloader that loaded this class */
+ protected File getFile(String name) throws FileNotFoundException {
+ URL url = getClass().getResource(name);
+ if (url == null){
+ throw new FileNotFoundException("Unable to load '" + name + "' from classpath");
+ }
+ return new File(FILE_UTILS.fromURI(url.toExternalForm()));
+ }
+
+ /** keep it simple stupid */
+ @Test
+ public void testTransform() throws Exception {
+ File xsl = getFile("/taskdefs/optional/xsltliaison-in.xsl");
+ liaison.setStylesheet(xsl);
+ liaison.addParam("param", "value");
+ File in = getFile("/taskdefs/optional/xsltliaison-in.xml");
+ File out = new File("xsltliaison.tmp");
+ out.deleteOnExit(); // just to be sure
+ try {
+ liaison.transform(in, out);
+ } finally {
+ out.delete();
+ }
+ }
+
+ @Test
+ public void testEncoding() throws Exception {
+ File xsl = getFile("/taskdefs/optional/xsltliaison-encoding-in.xsl");
+ liaison.setStylesheet(xsl);
+ File in = getFile("/taskdefs/optional/xsltliaison-encoding-in.xml");
+ File out = new File("xsltliaison-encoding.tmp");
+ out.deleteOnExit(); // just to be sure
+ try {
+ liaison.transform(in, out);
+ Document doc = parseXML(out);
+ assertEquals("root",doc.getDocumentElement().getNodeName());
+ assertEquals("message",doc.getDocumentElement().getFirstChild().getNodeName());
+ assertEquals("\u00E9\u00E0\u00E8\u00EF\u00F9",doc.getDocumentElement().getFirstChild().getFirstChild().getNodeValue());
+ } finally {
+ out.delete();
+ }
+ }
+
+ public Document parseXML(File file) throws Exception {
+ DocumentBuilderFactory dbfactory = DocumentBuilderFactory.newInstance();
+ DocumentBuilder dbuilder = dbfactory.newDocumentBuilder();
+ return dbuilder.parse(file);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/BeanShellScriptTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/BeanShellScriptTest.java
new file mode 100644
index 00000000..88020229
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/BeanShellScriptTest.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional;
+
+import org.apache.tools.ant.BuildFileRule;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * Tests the examples of the &lt;script&gt; task docs.
+ *
+ * @since Ant 1.5.2
+ */
+public class BeanShellScriptTest {
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/optional/script.xml");
+ }
+
+ @Test
+ public void testCanLoad() {
+ buildRule.executeTarget("useBeanshell");
+ assertEquals("I'm here", buildRule.getLog());
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/EchoPropertiesTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/EchoPropertiesTest.java
new file mode 100644
index 00000000..925777c5
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/EchoPropertiesTest.java
@@ -0,0 +1,266 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional;
+
+import static org.apache.tools.ant.AntAssert.assertContains;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeTrue;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Properties;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.BuildFileRule;
+import org.apache.tools.ant.util.regexp.RegexpMatcherFactory;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+/**
+ * Tests the EchoProperties task.
+ *
+ * @created 17-Jan-2002
+ * @since Ant 1.5
+ */
+public class EchoPropertiesTest {
+
+ private final static String TASKDEFS_DIR = "src/etc/testcases/taskdefs/optional/";
+ private static final String GOOD_OUTFILE = "test.properties";
+ private static final String GOOD_OUTFILE_XML = "test.xml";
+ private static final String PREFIX_OUTFILE = "test-prefix.properties";
+ private static final String TEST_VALUE = "isSet";
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject(TASKDEFS_DIR + "echoproperties.xml");
+ buildRule.getProject().setProperty("test.property", TEST_VALUE);
+ }
+
+
+ @After
+ public void tearDown() {
+ buildRule.executeTarget("cleanup");
+ }
+
+
+ @Test
+ public void testEchoToLog() {
+ buildRule.executeTarget("testEchoToLog");
+ assertContains("test.property=" + TEST_VALUE, buildRule.getLog());
+ }
+
+ @Test
+ public void testEchoWithEmptyPrefixToLog() {
+ buildRule.executeTarget("testEchoWithEmptyPrefixToLog");
+ assertContains("test.property="+TEST_VALUE, buildRule.getLog());
+ }
+
+
+ @Test
+ public void testReadBadFile() {
+ try {
+ buildRule.executeTarget("testReadBadFile");
+ fail("BuildException should have been thrown on bad file");
+ }
+ catch(BuildException ex) {
+ assertContains("srcfile is a directory","srcfile is a directory!", ex.getMessage());
+ }
+ }
+
+ @Test
+ public void testReadBadFileNoFail() {
+ buildRule.executeTarget("testReadBadFileNoFail");
+ assertContains("srcfile is a directory!", buildRule.getLog());
+ }
+
+
+ @Test
+ public void testEchoToBadFile() {
+ try {
+ buildRule.executeTarget("testEchoToBadFile");
+ fail("BuildException should have been thrown on destination file being a directory");
+ } catch(BuildException ex) {
+ assertContains("destfile is a directory", "destfile is a directory!", ex.getMessage());
+ }
+ }
+
+
+ @Test
+ public void testEchoToBadFileNoFail() {
+ buildRule.executeTarget("testEchoToBadFileNoFail");
+ assertContains("destfile is a directory!", buildRule.getLog());
+ }
+
+
+ @Test
+ public void testEchoToGoodFile() throws Exception {
+ buildRule.executeTarget("testEchoToGoodFile");
+ assertGoodFile();
+ }
+
+
+ @Test
+ public void testEchoToGoodFileXml() throws Exception {
+ buildRule.executeTarget("testEchoToGoodFileXml");
+
+ // read in the file
+ File f = createRelativeFile(GOOD_OUTFILE_XML);
+ FileReader fr = new FileReader(f);
+ BufferedReader br = new BufferedReader(fr);
+ try {
+ String read = null;
+ while ((read = br.readLine()) != null) {
+ if (read.indexOf("<property name=\"test.property\" value=\""+TEST_VALUE+"\" />") >= 0) {
+ // found the property we set - it's good.
+ return;
+ }
+ }
+ fail("did not encounter set property in generated file.");
+ } finally {
+ try {
+ fr.close();
+ } catch(IOException e) {}
+ try {
+ br.close();
+ } catch(IOException e) {}
+ }
+ }
+
+
+ @Test
+ public void testEchoToGoodFileFail() throws Exception {
+ buildRule.executeTarget("testEchoToGoodFileFail");
+ assertGoodFile();
+ }
+
+
+ @Test
+ public void testEchoToGoodFileNoFail() throws Exception {
+ buildRule.executeTarget("testEchoToGoodFileNoFail");
+ assertGoodFile();
+ }
+
+ @Test
+ public void testEchoPrefix() throws Exception {
+ testEchoPrefixVarious("testEchoPrefix");
+ }
+
+ @Test
+ public void testEchoPrefixAsPropertyset() throws Exception {
+ testEchoPrefixVarious("testEchoPrefixAsPropertyset");
+ }
+
+ @Test
+ public void testEchoPrefixAsNegatedPropertyset() throws Exception {
+ testEchoPrefixVarious("testEchoPrefixAsNegatedPropertyset");
+ }
+
+ @Test
+ public void testEchoPrefixAsDoublyNegatedPropertyset() throws Exception {
+ testEchoPrefixVarious("testEchoPrefixAsDoublyNegatedPropertyset");
+ }
+
+ @Test
+ public void testWithPrefixAndRegex() throws Exception {
+ try {
+ buildRule.executeTarget("testWithPrefixAndRegex");
+ fail("BuildException should have been thrown on Prefix and RegEx beng set");
+ } catch (BuildException ex) {
+ assertEquals("The target must fail with prefix and regex attributes set", "Please specify either prefix or regex, but not both", ex.getMessage());
+ }
+ }
+
+ @Test
+ public void testWithEmptyPrefixAndRegex() throws Exception {
+ buildRule.executeTarget("testEchoWithEmptyPrefixToLog");
+ assertContains("test.property="+TEST_VALUE, buildRule.getLog());
+ }
+
+ @Test
+ public void testWithRegex() throws Exception {
+ assumeTrue("Test skipped because no regexp matcher is present.", RegexpMatcherFactory.regexpMatcherPresent(buildRule.getProject()));
+ buildRule.executeTarget("testWithRegex");
+ // the following line has been changed from checking ant.home to ant.version so the test will still work when run outside of an ant script
+ assertContains("ant.version=", buildRule.getFullLog());
+ }
+
+ private void testEchoPrefixVarious(String target) throws Exception {
+ buildRule.executeTarget(target);
+ Properties props = loadPropFile(PREFIX_OUTFILE);
+ assertEquals("prefix didn't include 'a.set' property",
+ "true", props.getProperty("a.set"));
+ assertNull("prefix failed to filter out property 'b.set'",
+ props.getProperty("b.set"));
+ }
+
+ protected Properties loadPropFile(String relativeFilename)
+ throws IOException {
+ File f = createRelativeFile(relativeFilename);
+ Properties props=new Properties();
+ InputStream in=null;
+ try {
+ in=new BufferedInputStream(new FileInputStream(f));
+ props.load(in);
+ } finally {
+ if(in!=null) {
+ try { in.close(); } catch(IOException e) {}
+ }
+ }
+ return props;
+ }
+
+ protected void assertGoodFile() throws Exception {
+ File f = createRelativeFile(GOOD_OUTFILE);
+ assertTrue("Did not create "+f.getAbsolutePath(),
+ f.exists());
+ Properties props=loadPropFile(GOOD_OUTFILE);
+ props.list(System.out);
+ assertEquals("test property not found ",
+ TEST_VALUE, props.getProperty("test.property"));
+ }
+
+
+ protected String toAbsolute(String filename) {
+ return createRelativeFile(filename).getAbsolutePath();
+ }
+
+
+ protected File createRelativeFile(String filename) {
+ if (filename.equals(".")) {
+ return buildRule.getProject().getBaseDir();
+ }
+ // else
+ return new File(buildRule.getProject().getBaseDir(), filename);
+ }
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/JavahTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/JavahTest.java
new file mode 100644
index 00000000..8b02fff5
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/JavahTest.java
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional;
+
+import org.apache.tools.ant.BuildFileRule;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import java.io.File;
+
+import static org.junit.Assert.assertTrue;
+
+public class JavahTest {
+
+ private final static String BUILD_XML =
+ "src/etc/testcases/taskdefs/optional/javah/build.xml";
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject(BUILD_XML);
+ }
+
+ @After
+ public void tearDown() {
+ buildRule.executeTarget("tearDown");
+ }
+
+ @Test
+ public void testSimpleCompile() {
+ buildRule.executeTarget("simple-compile");
+ assertTrue(new File(buildRule.getProject().getProperty("output"), "org_example_Foo.h")
+ .exists());
+ }
+
+ @Test
+ public void testCompileFileset() {
+ buildRule.executeTarget("test-fileset");
+ assertTrue(new File(buildRule.getProject().getProperty("output"), "org_example_Foo.h").exists());
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/JspcTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/JspcTest.java
new file mode 100644
index 00000000..57475cc1
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/JspcTest.java
@@ -0,0 +1,200 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional;
+
+import java.io.File;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.BuildFileRule;
+import org.apache.tools.ant.taskdefs.optional.jsp.Jasper41Mangler;
+import org.apache.tools.ant.taskdefs.optional.jsp.JspMangler;
+import org.apache.tools.ant.taskdefs.optional.jsp.JspNameMangler;
+import org.apache.tools.ant.taskdefs.optional.jsp.compilers.JspCompilerAdapter;
+import org.apache.tools.ant.taskdefs.optional.jsp.compilers.JspCompilerAdapterFactory;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+/**
+ * Tests the Jspc task.
+ *
+ * created 07 March 2002
+ * @since Ant 1.5
+ */
+public class JspcTest {
+
+ private final static String TASKDEFS_DIR = "src/etc/testcases/taskdefs/optional/";
+
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject(TASKDEFS_DIR + "jspc.xml");
+ }
+
+
+
+ @Test
+ public void testSimple() {
+ executeJspCompile("testSimple", "simple_jsp.java");
+ }
+
+
+ @Test
+ public void testUriroot() throws Exception {
+ executeJspCompile("testUriroot", "uriroot_jsp.java");
+ }
+
+
+ @Test
+ public void testXml() throws Exception {
+ executeJspCompile("testXml", "xml_jsp.java");
+ }
+
+
+ /**
+ * try a keyword in a file
+ */
+ @Test
+ public void testKeyword() throws Exception {
+ executeJspCompile("testKeyword", "default_jsp.java");
+ }
+
+
+ /**
+ * what happens to 1nvalid-classname
+ */
+ @Test
+ public void testInvalidClassname() throws Exception {
+ executeJspCompile("testInvalidClassname",
+ "_1nvalid_0002dclassname_jsp.java");
+ }
+
+
+ @Test
+ public void testNoTld() throws Exception {
+ try {
+ buildRule.executeTarget("testNoTld");
+ fail("Not found");
+ } catch (BuildException ex) {
+ assertEquals("Java returned: 9", ex.getMessage());
+ }
+ }
+
+
+ @Test
+ public void testNotAJspFile() throws Exception {
+ buildRule.executeTarget("testNotAJspFile");
+ }
+
+ /**
+ * webapp test is currently broken, because it picks up
+ * on the missing_tld file, and bails.
+ */
+ @Ignore("picks up on the missing_tld file, and incorrectly bails")
+ @Test
+ public void testWebapp() throws Exception {
+ buildRule.executeTarget("testWebapp");
+ }
+
+ /**
+ * run a target then verify the named file gets created
+ *
+ * @param target Description of Parameter
+ * @param javafile Description of Parameter
+ */
+ protected void executeJspCompile(String target, String javafile) {
+ buildRule.executeTarget(target);
+ assertJavaFileCreated(javafile);
+ }
+
+
+ /**
+ * verify that a named file was created
+ *
+ * @param filename Description of Parameter
+ */
+ protected void assertJavaFileCreated(String filename) {
+ File file = getOutputFile(filename);
+ assertTrue("file " + filename + " not found", file.exists());
+ assertTrue("file " + filename + " is empty", file.length() > 0);
+ }
+
+ /**
+ * Gets the OutputFile attribute of the JspcTest object
+ *
+ * @param subpath Description of Parameter
+ * @return The OutputFile value
+ */
+ protected File getOutputFile(String subpath) {
+ return new File(buildRule.getProject().getProperty("output"), subpath);
+ }
+
+ /**
+ * verify that we select the appropriate mangler
+ */
+ @Test
+ public void testJasperNameManglerSelection() {
+ JspCompilerAdapter adapter=
+ JspCompilerAdapterFactory.getCompiler("jasper", null,null);
+ JspMangler mangler=adapter.createMangler();
+ assertTrue(mangler instanceof JspNameMangler);
+ adapter= JspCompilerAdapterFactory.getCompiler("jasper41", null, null);
+ mangler = adapter.createMangler();
+ assertTrue(mangler instanceof Jasper41Mangler);
+ }
+
+ @Test
+ public void testJasper41() {
+ JspMangler mangler = new Jasper41Mangler();
+ //java keywords are not special
+ assertMapped(mangler, "for.jsp", "for_jsp");
+ //underscores go in front of invalid start chars
+ assertMapped(mangler, "0.jsp", "_0_jsp");
+ //underscores at the front get an underscore too
+ assertMapped(mangler, "_.jsp", "___jsp");
+ //non java char at start => underscore then the the _hex value
+ assertMapped(mangler, "-.jsp", "__0002d_jsp");
+ //and paths are stripped
+ char s = File.separatorChar;
+ assertMapped(mangler, "" + s + s + "somewhere" + s + "file" + s + "index.jsp", "index_jsp");
+ }
+
+ /**
+ * assert our mapping rules
+ * @param mangler
+ * @param filename
+ * @param classname
+ */
+ protected void assertMapped(JspMangler mangler, String filename, String classname) {
+ String mappedname = mangler.mapJspToJavaName(new File(filename));
+ assertTrue(filename+" should have mapped to "+classname
+ +" but instead mapped to "+mappedname,
+ classname.equals(mappedname));
+ }
+
+
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/Native2AsciiTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/Native2AsciiTest.java
new file mode 100644
index 00000000..53da2af4
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/Native2AsciiTest.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional;
+
+import java.io.File;
+
+import org.apache.tools.ant.BuildFileRule;
+import org.apache.tools.ant.util.FileUtils;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.assertTrue;
+
+public class Native2AsciiTest {
+
+ private final static String BUILD_XML =
+ "src/etc/testcases/taskdefs/optional/native2ascii/build.xml";
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject(BUILD_XML);
+ }
+
+ @After
+ public void tearDown() {
+ buildRule.executeTarget("tearDown");
+ }
+
+ @Test
+ public void testIso8859_1() throws java.io.IOException {
+ buildRule.executeTarget("testIso8859-1");
+ File in = buildRule.getProject().resolveFile("expected/iso8859-1.test");
+ File out = new File(buildRule.getProject().getProperty("output"), "iso8859-1.test");
+ assertTrue(FileUtils.getFileUtils().contentEquals(in, out, true));
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/PropertyFileTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/PropertyFileTest.java
new file mode 100644
index 00000000..7056ca90
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/PropertyFileTest.java
@@ -0,0 +1,235 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.Properties;
+
+import org.apache.tools.ant.BuildFileRule;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * JUnit testcase that exercises the optional PropertyFile task in ant.
+ * (this is really more of a functional test so far.., but it's enough to let
+ * me start refactoring...)
+ *
+ *created October 2, 2001
+ */
+
+public class PropertyFileTest {
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() throws Exception {
+ buildRule.configureProject(projectFilePath);
+ buildRule.executeTarget("setUp");
+ initTestPropFile();
+ initBuildPropFile();
+ buildRule.configureProject(projectFilePath);
+ buildRule.getProject().setProperty(valueDoesNotGetOverwrittenPropertyFileKey,
+ valueDoesNotGetOverwrittenPropertyFile);
+ }
+
+
+ @Test
+ public void testNonExistingFile() {
+ PropertyFile props = new PropertyFile();
+ props.setProject( buildRule.getProject() );
+ File file = new File("this-file-does-not-exist.properties");
+ props.setFile(file);
+ assertFalse("Properties file exists before test.", file.exists());
+ props.execute();
+ assertTrue("Properties file does not exist after test.", file.exists());
+ file.delete();
+ }
+
+ /**
+ * A unit test for JUnit- Exercises the propertyfile tasks ability to
+ * update properties that are already defined-
+ */
+ @Test
+ public void testUpdatesExistingProperties() throws Exception {
+ Properties beforeUpdate = getTestProperties();
+ assertEquals(FNAME, beforeUpdate.getProperty(FNAME_KEY));
+ assertEquals(LNAME, beforeUpdate.getProperty(LNAME_KEY));
+ assertEquals(EMAIL, beforeUpdate.getProperty(EMAIL_KEY));
+ assertEquals(null, beforeUpdate.getProperty(PHONE_KEY));
+ assertEquals(null, beforeUpdate.getProperty(AGE_KEY));
+ assertEquals(null, beforeUpdate.getProperty(DATE_KEY));
+
+ // ask ant to update the properties...
+ buildRule.executeTarget("update-existing-properties");
+
+ Properties afterUpdate = getTestProperties();
+ assertEquals(NEW_FNAME, afterUpdate.getProperty(FNAME_KEY));
+ assertEquals(NEW_LNAME, afterUpdate.getProperty(LNAME_KEY));
+ assertEquals(NEW_EMAIL, afterUpdate.getProperty(EMAIL_KEY));
+ assertEquals(NEW_PHONE, afterUpdate.getProperty(PHONE_KEY));
+ assertEquals(NEW_AGE, afterUpdate.getProperty(AGE_KEY));
+ assertEquals(NEW_DATE, afterUpdate.getProperty(DATE_KEY));
+ }
+
+ @Test
+ public void testDeleteProperties() throws Exception {
+ Properties beforeUpdate = getTestProperties();
+ assertEquals("Property '" + FNAME_KEY + "' should exist before deleting",
+ FNAME, beforeUpdate.getProperty(FNAME_KEY));
+ assertEquals("Property '" + LNAME_KEY + "' should exist before deleting",
+ LNAME, beforeUpdate.getProperty(LNAME_KEY));
+
+ buildRule.executeTarget("delete-properties");
+ Properties afterUpdate = getTestProperties();
+
+ assertEquals("Property '" + LNAME_KEY + "' should exist after deleting",
+ LNAME, afterUpdate.getProperty(LNAME_KEY));
+ assertNull("Property '" + FNAME_KEY + "' should be deleted",
+ afterUpdate.getProperty(FNAME_KEY));
+ }
+
+ @Test
+ public void testExerciseDefaultAndIncrement() throws Exception {
+ buildRule.executeTarget("exercise");
+ assertEquals("3",buildRule.getProject().getProperty("int.with.default"));
+ assertEquals("1",buildRule.getProject().getProperty("int.without.default"));
+ assertEquals("-->",buildRule.getProject().getProperty("string.with.default"));
+ assertEquals(".",buildRule.getProject().getProperty("string.without.default"));
+ assertEquals("2002/01/21 12:18", buildRule.getProject().getProperty("ethans.birth"));
+ assertEquals("2003/01/21", buildRule.getProject().getProperty("first.birthday"));
+ assertEquals("0124", buildRule.getProject().getProperty("olderThanAWeek"));
+ assertEquals("37", buildRule.getProject().getProperty("existing.prop"));
+ assertEquals("6",buildRule.getProject().getProperty("int.without.value"));
+ }
+
+ @Test
+ public void testValueDoesNotGetOverwritten() {
+ // this test shows that the bug report 21505 is fixed
+ buildRule.executeTarget("bugDemo1");
+ buildRule.executeTarget("bugDemo2");
+ assertEquals("5", buildRule.getProject().getProperty("foo"));
+ }
+
+
+ @Test
+ @Ignore("Previously commented out")
+ public void testDirect() throws Exception {
+ PropertyFile pf = new PropertyFile();
+ pf.setProject(buildRule.getProject());
+ pf.setFile(new File(System.getProperty("root"), testPropsFilePath));
+ PropertyFile.Entry entry = pf.createEntry();
+
+ entry.setKey("date");
+ entry.setValue("123");
+ PropertyFile.Entry.Type type = new PropertyFile.Entry.Type();
+ type.setValue("date");
+ entry.setType(type);
+
+ entry.setPattern("yyyy/MM/dd");
+
+ PropertyFile.Entry.Operation operation = new PropertyFile.Entry.Operation();
+ operation.setValue("+");
+ pf.execute();
+
+ Properties props = getTestProperties();
+ assertEquals("yeehaw", props.getProperty("date"));
+ }
+
+
+ private Properties getTestProperties() throws Exception {
+ Properties testProps = new Properties();
+ FileInputStream propsFile = new FileInputStream(new File(buildRule.getOutputDir(), testPropsFilePath));
+ testProps.load(propsFile);
+ propsFile.close();
+ return testProps;
+ }
+
+
+ private void initTestPropFile() throws IOException {
+ Properties testProps = new Properties();
+ testProps.put(FNAME_KEY, FNAME);
+ testProps.put(LNAME_KEY, LNAME);
+ testProps.put(EMAIL_KEY, EMAIL);
+ testProps.put("existing.prop", "37");
+
+ FileOutputStream fos = new FileOutputStream(new File(buildRule.getOutputDir(), testPropsFilePath));
+ testProps.store(fos, "defaults");
+ fos.close();
+ }
+
+
+ private void initBuildPropFile() throws IOException {
+ Properties buildProps = new Properties();
+ buildProps.put(testPropertyFileKey, testPropertyFile);
+ buildProps.put(FNAME_KEY, NEW_FNAME);
+ buildProps.put(LNAME_KEY, NEW_LNAME);
+ buildProps.put(EMAIL_KEY, NEW_EMAIL);
+ buildProps.put(PHONE_KEY, NEW_PHONE);
+ buildProps.put(AGE_KEY, NEW_AGE);
+ buildProps.put(DATE_KEY, NEW_DATE);
+
+ FileOutputStream fos = new FileOutputStream(new File(buildRule.getOutputDir(), buildPropsFilePath));
+ buildProps.store(fos, null);
+ fos.close();
+ }
+
+ private static final String
+ projectFilePath = "src/etc/testcases/taskdefs/optional/propertyfile.xml",
+
+ testPropertyFile = "propertyfile.test.properties",
+ testPropertyFileKey = "test.propertyfile",
+ testPropsFilePath = testPropertyFile,
+
+ valueDoesNotGetOverwrittenPropertyFile = "overwrite.test.properties",
+ valueDoesNotGetOverwrittenPropertyFileKey = "overwrite.test.propertyfile",
+ valueDoesNotGetOverwrittenPropsFilePath = valueDoesNotGetOverwrittenPropertyFile,
+
+ buildPropsFilePath = "propertyfile.build.properties",
+
+ FNAME = "Bruce",
+ NEW_FNAME = "Clark",
+ FNAME_KEY = "firstname",
+
+ LNAME = "Banner",
+ NEW_LNAME = "Kent",
+ LNAME_KEY = "lastname",
+
+ EMAIL = "incredible@hulk.com",
+ NEW_EMAIL = "kc@superman.com",
+ EMAIL_KEY = "email",
+
+ NEW_PHONE = "(520) 555-1212",
+ PHONE_KEY = "phone",
+
+ NEW_AGE = "30",
+ AGE_KEY = "age",
+
+ NEW_DATE = "2001/01/01 12:45",
+ DATE_KEY = "date";
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/PvcsTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/PvcsTest.java
new file mode 100644
index 00000000..cd7a4316
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/PvcsTest.java
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.BuildFileRule;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.fail;
+
+public class PvcsTest {
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/optional/pvcs.xml");
+ }
+
+ @Test
+ public void test1() {
+ try {
+ buildRule.executeTarget("test1");
+ fail("Required argument repository not specified");
+ } catch (BuildException ex) {
+ //TODO check exception message
+ }
+ }
+
+ @Test
+ public void test2() {
+ buildRule.executeTarget("test2");
+ }
+
+ @Test
+ public void test3() {
+ buildRule.executeTarget("test3");
+ }
+
+ @Test
+ public void test4() {
+ buildRule.executeTarget("test4");
+ }
+
+ @Test
+ public void test5() {
+ buildRule.executeTarget("test5");
+ }
+
+ @Test
+ public void test6() {
+ try {
+ buildRule.executeTarget("test6");
+ fail("Failed executing: /never/heard/of/a/directory/structure/like/this/pcli lvf -z " +
+ "-aw -pr//ct4serv2/pvcs/monitor /. Exception: /never/heard/of/a/directory/structure/like/this/pcli: not found");
+ } catch(BuildException ex) {
+ //TODO assert exception message
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/ReplaceRegExpTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/ReplaceRegExpTest.java
new file mode 100644
index 00000000..b6c09a5c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/ReplaceRegExpTest.java
@@ -0,0 +1,132 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional;
+
+import org.apache.tools.ant.BuildFileRule;
+import org.apache.tools.ant.FileUtilities;
+import org.apache.tools.ant.util.FileUtils;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import java.util.Properties;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assume.assumeTrue;
+
+/**
+ * JUnit Testcase for the optional replaceregexp task.
+ *
+ */
+public class ReplaceRegExpTest {
+ private static final String PROJECT_PATH = "src/etc/testcases/taskdefs/optional";
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject(PROJECT_PATH + "/replaceregexp.xml");
+ }
+
+ @Test
+ public void testReplace() throws IOException {
+ Properties original = new Properties();
+ FileInputStream propsFile = null;
+ try {
+ propsFile = new FileInputStream(new File(buildRule.getProject().getBaseDir() + "/replaceregexp.properties"));
+ original.load(propsFile);
+ } finally {
+ if (propsFile != null) {
+ propsFile.close();
+ propsFile = null;
+ }
+ }
+
+ assertEquals("Def", original.get("OldAbc"));
+
+ buildRule.executeTarget("testReplace");
+
+ Properties after = new Properties();
+ try {
+ propsFile = new FileInputStream(new File(buildRule.getOutputDir(), "test.properties"));
+ after.load(propsFile);
+ } finally {
+ if (propsFile != null) {
+ propsFile.close();
+ }
+ }
+
+ assertNull(after.get("OldAbc"));
+ assertEquals("AbcDef", after.get("NewProp"));
+ }
+
+ // inspired by bug 22541
+ @Test
+ public void testDirectoryDateDoesNotChange() {
+ buildRule.executeTarget("touchDirectory");
+ File myFile = buildRule.getOutputDir();
+ long timeStampBefore = myFile.lastModified();
+ buildRule.executeTarget("testDirectoryDateDoesNotChange");
+ long timeStampAfter = myFile.lastModified();
+ assertEquals("directory date should not change",
+ timeStampBefore, timeStampAfter);
+ }
+
+ @Test
+ public void testDontAddNewline1() throws IOException {
+ buildRule.executeTarget("testDontAddNewline1");
+ assertEquals(FileUtilities.getFileContents(new File(buildRule.getOutputDir(), "test.properties")),
+ FileUtilities.getFileContents(new File(buildRule.getProject().getBaseDir(), "replaceregexp2.result.properties")));
+ }
+
+ @Test
+ public void testDontAddNewline2() throws IOException {
+ buildRule.executeTarget("testDontAddNewline2");
+ assertEquals(FileUtilities.getFileContents(new File(buildRule.getOutputDir(), "test.properties")),
+ FileUtilities.getFileContents(new File(buildRule.getProject().getBaseDir(), "replaceregexp2.result.properties")));
+ }
+
+ @Test
+ public void testNoPreserveLastModified() throws Exception {
+ buildRule.executeTarget("lastModifiedSetup");
+ File testFile = new File(buildRule.getOutputDir(), "test.txt");
+ assumeTrue(testFile.setLastModified(testFile.lastModified()
+ - (FileUtils.getFileUtils().getFileTimestampGranularity() * 3)));
+ long ts1 = testFile.lastModified();
+ buildRule.executeTarget("testNoPreserve");
+ assertTrue(ts1 < testFile.lastModified());
+ }
+
+ @Test
+ public void testPreserveLastModified() throws Exception {
+ buildRule.executeTarget("lastModifiedSetup");
+ File testFile = new File(buildRule.getOutputDir(), "test.txt");
+ assumeTrue(testFile.setLastModified(testFile.lastModified()
+ - (FileUtils.getFileUtils().getFileTimestampGranularity() * 3)));
+ long ts1 = testFile.lastModified();
+ buildRule.executeTarget("testPreserve");
+ assertEquals(ts1 , testFile.lastModified());
+ }
+
+}// ReplaceRegExpTest
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/RhinoReferenceTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/RhinoReferenceTest.java
new file mode 100644
index 00000000..41803de6
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/RhinoReferenceTest.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional;
+
+import org.apache.tools.ant.BuildFileRule;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+/**
+ * Tests using an undefined reference.
+ *
+ * @since Ant 1.6
+ */
+public class RhinoReferenceTest {
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject(
+ "src/etc/testcases/taskdefs/optional/script_reference.xml");
+ }
+
+ @Test
+ public void testScript() {
+ buildRule.executeTarget("script");
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/RhinoScriptTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/RhinoScriptTest.java
new file mode 100644
index 00000000..35576dcb
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/RhinoScriptTest.java
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional;
+
+import org.apache.tools.ant.BuildFileRule;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Tests the examples of the &lt;script&gt; task docs.
+ *
+ * @since Ant 1.5.2
+ */
+public class RhinoScriptTest {
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/optional/script.xml");
+ }
+
+ @Test
+ public void testExample1() {
+ buildRule.executeTarget("example1");
+ int index = buildRule.getLog().indexOf("1");
+ assertTrue(index > -1);
+ index = buildRule.getLog().indexOf("4", index);
+ assertTrue(index > -1);
+ index = buildRule.getLog().indexOf("9", index);
+ assertTrue(index > -1);
+ index = buildRule.getLog().indexOf("16", index);
+ assertTrue(index > -1);
+ index = buildRule.getLog().indexOf("25", index);
+ assertTrue(index > -1);
+ index = buildRule.getLog().indexOf("36", index);
+ assertTrue(index > -1);
+ index = buildRule.getLog().indexOf("49", index);
+ assertTrue(index > -1);
+ index = buildRule.getLog().indexOf("64", index);
+ assertTrue(index > -1);
+ index = buildRule.getLog().indexOf("81", index);
+ assertTrue(index > -1);
+ index = buildRule.getLog().indexOf("100", index);
+ assertTrue(index > -1);
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/RpmTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/RpmTest.java
new file mode 100644
index 00000000..ac4462d5
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/RpmTest.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.taskdefs.Execute;
+import org.apache.tools.ant.taskdefs.ExecuteStreamHandler;
+import org.apache.tools.ant.types.Commandline;
+
+import org.junit.Test;
+
+import static org.junit.Assert.fail;
+import static org.apache.tools.ant.AntAssert.assertContains;
+
+public class RpmTest {
+
+ @Test
+ public void testShouldThrowExceptionWhenRpmFails() throws Exception {
+ Rpm rpm = new MyRpm();
+ rpm.setProject(new org.apache.tools.ant.Project());
+ rpm.setFailOnError(true);
+ // execute
+ try {
+ rpm.execute();
+ fail("should have thrown a build exception");
+ } catch (BuildException ex) {
+ assertContains("' failed with exit code 2", ex.getMessage());
+ }
+ }
+
+ @Test
+ public void testShouldNotThrowExceptionWhenRpmFails() throws Exception {
+ Rpm rpm = new MyRpm();
+ rpm.execute();
+ }
+
+ // override some of the code so we can test the handling of the
+ // return code only.
+ public static class MyRpm extends Rpm {
+ protected Execute getExecute(Commandline toExecute,
+ ExecuteStreamHandler streamhandler) {
+ return new Execute() {
+ public int execute() {
+ // 2 is != 0 and even, so it is considered
+ // failure on any platform currently supported
+ // by Execute#isFailure.
+ return 2;
+ }
+ };
+ }
+
+ public void log(String msg, int msgLevel) {
+ }
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/SchemaValidateTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/SchemaValidateTest.java
new file mode 100644
index 00000000..667c8904
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/SchemaValidateTest.java
@@ -0,0 +1,128 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional;
+
+import org.apache.tools.ant.AntAssert;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.BuildFileRule;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.fail;
+
+/**
+ * Test schema validation
+ */
+
+public class SchemaValidateTest {
+
+ /**
+ * where tasks run
+ */
+ private final static String TASKDEFS_DIR =
+ "src/etc/testcases/taskdefs/optional/";
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject(TASKDEFS_DIR + "schemavalidate.xml");
+ }
+
+ /**
+ * test with no namespace
+ */
+ @Test
+ public void testNoNamespace() throws Exception {
+ buildRule.executeTarget("testNoNamespace");
+ }
+
+ /**
+ * add namespace awareness.
+ */
+ @Test
+ public void testNSMapping() throws Exception {
+ buildRule.executeTarget("testNSMapping");
+ }
+
+ @Test
+ public void testNoEmptySchemaNamespace() throws Exception {
+ try {
+ buildRule.executeTarget("testNoEmptySchemaNamespace");
+ fail("Empty namespace URI");
+ } catch (BuildException ex) {
+ AntAssert.assertContains(SchemaValidate.SchemaLocation.ERROR_NO_URI, ex.getMessage());
+ }
+ }
+
+ @Test
+ public void testNoEmptySchemaLocation() throws Exception {
+ try {
+ buildRule.executeTarget("testNoEmptySchemaLocation");
+ fail("Empty schema location");
+ } catch (BuildException ex) {
+ AntAssert.assertContains(SchemaValidate.SchemaLocation.ERROR_NO_LOCATION,
+ ex.getMessage());
+ }
+ }
+
+ @Test
+ public void testNoFile() throws Exception {
+ try {
+ buildRule.executeTarget("testNoFile");
+ fail("No file at file attribute");
+ } catch (BuildException ex) {
+ AntAssert.assertContains(SchemaValidate.SchemaLocation.ERROR_NO_FILE,
+ ex.getMessage());
+ }
+ }
+
+ @Test
+ public void testNoDoubleSchemaLocation() throws Exception {
+ try {
+ buildRule.executeTarget("testNoDoubleSchemaLocation");
+ fail("Two locations for schemas");
+ } catch (BuildException ex) {
+ AntAssert.assertContains(SchemaValidate.SchemaLocation.ERROR_TWO_LOCATIONS,
+ ex.getMessage());
+ }
+ }
+
+ @Test
+ public void testNoDuplicateSchema() throws Exception {
+ try {
+ buildRule.executeTarget("testNoDuplicateSchema");
+ fail("duplicate schemas with different values");
+ } catch (BuildException ex) {
+ AntAssert.assertContains(SchemaValidate.ERROR_DUPLICATE_SCHEMA,
+ ex.getMessage());
+ }
+ }
+
+ @Test
+ public void testEqualsSchemasOK() throws Exception {
+ buildRule.executeTarget("testEqualsSchemasOK");
+ }
+
+ @Test
+ public void testFileset() throws Exception {
+ buildRule.executeTarget("testFileset");
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/TraXLiaisonTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/TraXLiaisonTest.java
new file mode 100644
index 00000000..02281eb6
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/TraXLiaisonTest.java
@@ -0,0 +1,129 @@
+package org.apache.tools.ant.taskdefs.optional;
+
+import static org.junit.Assert.assertTrue;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.InputStream;
+import java.security.Permission;
+
+import junit.framework.AssertionFailedError;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.taskdefs.XSLTLiaison;
+import org.apache.tools.ant.taskdefs.XSLTLogger;
+import org.apache.tools.ant.util.JAXPUtils;
+import org.junit.After;
+import org.junit.Assume;
+import org.junit.Test;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+/**
+ * TraX XSLTLiaison testcase
+ */
+public class TraXLiaisonTest extends AbstractXSLTLiaisonTest
+ implements XSLTLogger {
+
+
+ @After
+ public void tearDown() {
+ File f = new File("xalan2-redirect-out.tmp");
+ if (f.exists()) {
+ f.delete();
+ }
+ }
+
+ public XSLTLiaison createLiaison() throws Exception {
+ TraXLiaison l = new TraXLiaison();
+ l.setLogger(this);
+ return l;
+ }
+
+ @Test
+ public void testXalan2Redirect() throws Exception {
+ try {
+ getClass().getClassLoader().loadClass("org.apache.xalan.lib.Redirect");
+ } catch (Exception exc) {
+ Assume.assumeNoException("xalan redirect is not on the classpath", exc);
+ }
+ File xsl = getFile("/taskdefs/optional/xalan-redirect-in.xsl");
+ liaison.setStylesheet(xsl);
+ File out = new File("xalan2-redirect-out-dummy.tmp");
+ File in = getFile("/taskdefs/optional/xsltliaison-in.xsl");
+ ClassLoader orig = Thread.currentThread().getContextClassLoader();
+ try {
+ liaison.addParam("xalan-version", "2");
+ // Use the JRE's Xerces, not lib/optional/xerces.jar:
+ Thread.currentThread().setContextClassLoader(new ClassLoader(ClassLoader.getSystemClassLoader().getParent()) {
+ public InputStream getResourceAsStream(String name) {
+ if (name.startsWith("META-INF/services/")) {
+ // work around JAXP #6723276 in JDK 6
+ return new ByteArrayInputStream(new byte[0]);
+ }
+ return super.getResourceAsStream(name);
+ }
+ });
+ // Tickle #52382:
+ System.setSecurityManager(new SecurityManager() {public void checkPermission(Permission perm) {}});
+ liaison.transform(in, out);
+ } finally {
+ out.delete();
+ Thread.currentThread().setContextClassLoader(orig);
+ System.setSecurityManager(null);
+ }
+ }
+
+ @Test
+ public void testMultipleTransform() throws Exception {
+ File xsl = getFile("/taskdefs/optional/xsltliaison-in.xsl");
+ liaison.setStylesheet(xsl);
+ liaison.addParam("param", "value");
+ File in = getFile("/taskdefs/optional/xsltliaison-in.xml");
+ // test for 10 consecutives transform
+ for (int i = 0; i < 50; i++){
+ File out = new File("xsltliaison" + i + ".tmp");
+ try {
+ liaison.transform(in, out);
+ } catch (Exception e){
+ throw new BuildException("failed in transform " + i, e);
+ } finally {
+ out.delete();
+ }
+ }
+ }
+
+ @Test
+ public void testSystemId(){
+ File file = null;
+ if ( File.separatorChar == '\\' ){
+ file = new File("d:\\jdk");
+ } else {
+ file = new File("/user/local/bin");
+ }
+ String systemid = JAXPUtils.getSystemId(file);
+ assertTrue("SystemIDs should start by file:/", systemid.startsWith("file:/"));
+ assertTrue("SystemIDs should not start with file:////", !systemid.startsWith("file:////"));
+ }
+
+ public void log(String message) {
+ throw new AssertionFailedError("Liaison sent message: "+message);
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/XmlValidateCatalogTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/XmlValidateCatalogTest.java
new file mode 100644
index 00000000..c9948bb9
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/XmlValidateCatalogTest.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional;
+
+import org.apache.tools.ant.BuildFileRule;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+/**
+ * Tests the XMLValidate optional task with nested external catalogs.
+ *
+ * @see XmlValidateTest
+ * @since Ant 1.6
+ */
+public class XmlValidateCatalogTest {
+
+ /**
+ * where tasks run
+ */
+ private final static String TASKDEFS_DIR = "src/etc/testcases/taskdefs/optional/";
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject(TASKDEFS_DIR + "xmlvalidate.xml");
+ }
+
+
+ /**
+ * catalogfiles fileset should be ignored
+ * if resolver.jar is not present, but will
+ * be used if it is. either way, test should
+ * work b/c we have a nested dtd with the same
+ * entity
+ */
+ @Test
+ public void testXmlCatalogFiles() {
+ buildRule.executeTarget("xmlcatalogfiles");
+ }
+
+ /**
+ * Test nested catalogpath.
+ * It should be ignored if resolver.jar is not
+ * present, but will be used if it is. either
+ * way, test should work b/c we have a nested
+ * dtd with the same entity
+ */
+ @Test
+ public void testXmlCatalogPath() {
+ buildRule.executeTarget("xmlcatalogpath");
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/XmlValidateTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/XmlValidateTest.java
new file mode 100644
index 00000000..58f7a4b1
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/XmlValidateTest.java
@@ -0,0 +1,193 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.BuildFileRule;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.internal.AssumptionViolatedException;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+/**
+ * Tests the XMLValidate optional task, by running targets in the test script
+ * <code>src/etc/testcases/taskdefs/optional/xmlvalidate.xml</code>
+ * <p>
+ *
+ * @see XmlValidateCatalogTest
+ * @since Ant 1.5
+ */
+public class XmlValidateTest {
+
+ /**
+ * where tasks run
+ */
+ private final static String TASKDEFS_DIR =
+ "src/etc/testcases/taskdefs/optional/";
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject(TASKDEFS_DIR + "xmlvalidate.xml");
+ }
+
+ /**
+ * Basic inline 'dtd' element test.
+ */
+ @Test
+ public void testValidate() throws Exception {
+ buildRule.executeTarget("testValidate");
+ }
+
+ /**
+ * Test indirect validation.
+ */
+ @Test
+ public void testDeepValidate() throws Exception {
+ buildRule.executeTarget("testDeepValidate");
+ }
+
+ @Test
+ public void testXmlCatalog() {
+ buildRule.executeTarget("xmlcatalog");
+ }
+
+ @Test
+ public void testXmlCatalogViaRefid() {
+ buildRule.executeTarget("xmlcatalogViaRefid");
+ }
+
+ /**
+ * Test that the nested dtd element is used when resolver.jar is not
+ * present. This test should pass either way.
+ */
+ @Test
+ public void testXmlCatalogFiles() {
+ buildRule.executeTarget("xmlcatalogfiles-override");
+ }
+
+ /**
+ * Test nested catalogpath.
+ * Test that the nested dtd element is used when resolver.jar is not
+ * present. This test should pass either way.
+ */
+ @Test
+ public void testXmlCatalogPath() {
+ buildRule.executeTarget("xmlcatalogpath-override");
+ }
+
+ /**
+ * Test nested xmlcatalog definitions
+ */
+ @Test
+ public void testXmlCatalogNested() {
+ buildRule.executeTarget("xmlcatalognested");
+ }
+
+ /**
+ * Test xml schema validation
+ */
+ @Test
+ public void testXmlSchemaGood() throws BuildException {
+ try {
+ buildRule.executeTarget("testSchemaGood");
+ } catch (BuildException e) {
+ if (e
+ .getMessage()
+ .endsWith(" doesn't recognize feature http://apache.org/xml/features/validation/schema")
+ || e.getMessage().endsWith(
+ " doesn't support feature http://apache.org/xml/features/validation/schema")) {
+ throw new AssumptionViolatedException("parser doesn't support schema");
+ } else {
+ throw e;
+ }
+ }
+ }
+ /**
+ * Test xml schema validation
+ */
+ @Test
+ public void testXmlSchemaBad() {
+ try {
+ buildRule.executeTarget("testSchemaBad");
+ fail("Should throw BuildException because 'Bad Schema Validation'");
+
+ } catch (BuildException e) {
+ if (e
+ .getMessage()
+ .endsWith(" doesn't recognize feature http://apache.org/xml/features/validation/schema")
+ || e.getMessage().endsWith(
+ " doesn't support feature http://apache.org/xml/features/validation/schema")) {
+ throw new AssumptionViolatedException("parser doesn't support schema");
+ } else {
+ assertTrue(
+ e.getMessage().indexOf("not a valid XML document") > -1);
+ }
+ }
+ }
+
+ /**
+ * iso-2022-jp.xml is valid but wouldn't get recognized on systems
+ * with a different native encoding.
+ *
+ * Bug 11279
+ */
+ @Test
+ public void testIso2022Jp() {
+ buildRule.executeTarget("testIso2022Jp");
+ }
+
+ /**
+ * utf-8.xml is invalid as it contains non-UTF-8 characters, but
+ * would pass on systems with a native iso-8859-1 (or similar)
+ * encoding.
+ *
+ * Bug 11279
+ */
+ @Test
+ public void testUtf8() {
+ try {
+ buildRule.executeTarget("testUtf8");
+ fail("Invalid characters in file");
+ } catch(BuildException ex) {
+ //TODO assert exception message
+ }
+ }
+
+ // Tests property element, using XML schema properties as an example.
+ @Test
+ public void testPropertySchemaForValidXML() {
+ buildRule.executeTarget("testProperty.validXML");
+ }
+
+ @Test
+ public void testPropertySchemaForInvalidXML() {
+ try {
+ buildRule.executeTarget("testProperty.invalidXML");
+ fail("XML file does not satisfy schema");
+ } catch(BuildException ex) {
+ //TODO assert exception message
+ }
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/XsltTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/XsltTest.java
new file mode 100644
index 00000000..a5b71def
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/XsltTest.java
@@ -0,0 +1,86 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.BuildFileRule;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.fail;
+
+/**
+ * Tests the {@link org.apache.tools.ant.taskdefs.XSLTProcess} task.
+ * TODO merge with {@link org.apache.tools.ant.taskdefs.StyleTest}?
+ * @since Ant 1.5
+ */
+public class XsltTest {
+
+ /**
+ * where tasks run
+ */
+ private final static String TASKDEFS_DIR = "src/etc/testcases/taskdefs/optional/";
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject(TASKDEFS_DIR + "xslt.xml");
+ }
+
+
+ @Test
+ public void testCatchNoDtd() {
+ try {
+ buildRule.executeTarget("testCatchNoDtd");
+ fail("Expected failure");
+ } catch(BuildException ex) {
+ //TODO assert exception message
+ }
+ }
+
+ @Test
+ public void testCatalog() throws Exception {
+ buildRule.executeTarget("testCatalog");
+ }
+
+ @Test
+ public void testOutputProperty() throws Exception {
+ buildRule.executeTarget("testOutputProperty");
+ }
+
+ @Test
+ public void testXMLWithEntitiesInNonAsciiPath() throws Exception {
+ buildRule.executeTarget("testXMLWithEntitiesInNonAsciiPath");
+ }
+
+ /**
+ * check that the system id gets set properly on stylesheets.
+ * @throws Exception if something goes wrong.
+ */
+ @Test
+ public void testStyleSheetWithInclude() throws Exception {
+ buildRule.executeTarget("testStyleSheetWithInclude");
+ if (buildRule.getLog().indexOf("java.io.FileNotFoundException") != -1) {
+ fail("xsl:include was not found");
+ }
+ }
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/depend/DependTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/depend/DependTest.java
new file mode 100644
index 00000000..95c1eb0b
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/depend/DependTest.java
@@ -0,0 +1,213 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.depend;
+
+import java.io.File;
+import java.util.Hashtable;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.BuildFileRule;
+import org.apache.tools.ant.DirectoryScanner;
+import org.apache.tools.ant.FileUtilities;
+import org.apache.tools.ant.types.FileSet;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.apache.tools.ant.AntAssert.assertContains;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+/**
+ * Testcase for the Depend optional task.
+ *
+ */
+public class DependTest {
+ public static final String RESULT_FILESET = "result";
+
+ public static final String TEST_BUILD_FILE
+ = "src/etc/testcases/taskdefs/optional/depend/depend.xml";
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject(TEST_BUILD_FILE);
+ }
+
+ /**
+ * Test direct dependency removal
+ */
+ @Test
+ public void testDirect() {
+ buildRule.executeTarget("src1setup");
+ buildRule.executeTarget("compile");
+
+ FileUtilities.rollbackTimetamps(new File(buildRule.getProject().getProperty("tempsrc.dir")), 5);
+ FileUtilities.rollbackTimetamps(new File(buildRule.getProject().getProperty("classes.dir")), 5);
+
+ buildRule.executeTarget("testdirect");
+ Hashtable files = getResultFiles();
+ assertEquals("Depend did not leave correct number of files", 3,
+ files.size());
+ assertTrue("Result did not contain A.class",
+ files.containsKey("A.class"));
+ assertTrue("Result did not contain D.class",
+ files.containsKey("D.class"));
+ }
+
+ /**
+ * Test dependency traversal (closure)
+ */
+ @Test
+ public void testClosure() {
+ buildRule.executeTarget("src1setup");
+ buildRule.executeTarget("compile");
+
+ FileUtilities.rollbackTimetamps(new File(buildRule.getProject().getProperty("tempsrc.dir")), 5);
+ FileUtilities.rollbackTimetamps(new File(buildRule.getProject().getProperty("classes.dir")), 5);
+
+ buildRule.executeTarget("testclosure");
+ Hashtable files = getResultFiles();
+ assertTrue("Depend did not leave correct number of files",
+ files.size() <= 2);
+ assertTrue("Result did not contain D.class",
+ files.containsKey("D.class"));
+ }
+
+ /**
+ * Test that inner class dependencies trigger deletion of the outer class
+ */
+ @Test
+ public void testInner() {
+ buildRule.executeTarget("src2setup");
+ buildRule.executeTarget("compile");
+
+ FileUtilities.rollbackTimetamps(new File(buildRule.getProject().getProperty("tempsrc.dir")), 5);
+ FileUtilities.rollbackTimetamps(new File(buildRule.getProject().getProperty("classes.dir")), 5);
+
+
+ buildRule.executeTarget("testinner");
+ assertEquals("Depend did not leave correct number of files", 0,
+ getResultFiles().size());
+ }
+
+ /**
+ * Test that multi-leve inner class dependencies trigger deletion of
+ * the outer class
+ */
+ @Test
+ public void testInnerInner() {
+ buildRule.executeTarget("src3setup");
+ buildRule.executeTarget("compile");
+
+ FileUtilities.rollbackTimetamps(new File(buildRule.getProject().getProperty("tempsrc.dir")), 5);
+ FileUtilities.rollbackTimetamps(new File(buildRule.getProject().getProperty("classes.dir")), 5);
+
+ buildRule.executeTarget("testinnerinner");
+ assertEquals("Depend did not leave correct number of files", 0,
+ getResultFiles().size());
+ }
+
+ /**
+ * Test that an exception is thrown when there is no source
+ */
+ @Test
+ public void testNoSource() {
+ try {
+ buildRule.executeTarget("testnosource");
+ fail("Build exception expected: No source specified");
+ } catch(BuildException ex) {
+ assertContains("srcdir attribute must be set", ex.getMessage());
+ }
+ }
+
+ /**
+ * Test that an exception is thrown when the source attribute is empty
+ */
+ @Test
+ public void testEmptySource() {
+ try {
+ buildRule.executeTarget("testemptysource");
+ fail("Build exception expected: No source specified");
+ } catch(BuildException ex) {
+ assertContains("srcdir attribute must be non-empty", ex.getMessage());
+ }
+ }
+
+ /**
+ * Read the result fileset into a Hashtable
+ *
+ * @return a Hashtable containing the names of the files in the result
+ * fileset
+ */
+ private Hashtable getResultFiles() {
+ FileSet resultFileSet = (FileSet) buildRule.getProject().getReference(RESULT_FILESET);
+ DirectoryScanner scanner = resultFileSet.getDirectoryScanner(buildRule.getProject());
+ String[] scannedFiles = scanner.getIncludedFiles();
+ Hashtable files = new Hashtable();
+ for (int i = 0; i < scannedFiles.length; ++i) {
+ files.put(scannedFiles[i], scannedFiles[i]);
+ }
+ return files;
+ }
+
+
+ /**
+ * Test mutual dependency between inner and outer do not cause both to be
+ * deleted
+ */
+ @Test
+ public void testInnerClosure() {
+ buildRule.executeTarget("testinnerclosure");
+ assertEquals("Depend did not leave correct number of files", 4,
+ getResultFiles().size());
+ }
+
+ /**
+ * Test the operation of the cache
+ */
+ @Test
+ public void testCache() {
+ buildRule.executeTarget("testcache");
+ }
+
+ /**
+ * Test the detection and warning of non public classes
+ */
+ @Test
+ public void testNonPublic() {
+ buildRule.executeTarget("src5setup");
+ buildRule.executeTarget("compile");
+
+ FileUtilities.rollbackTimetamps(new File(buildRule.getProject().getProperty("tempsrc.dir")), 5);
+ FileUtilities.rollbackTimetamps(new File(buildRule.getProject().getProperty("classes.dir")), 5);
+
+ buildRule.executeTarget("testnonpublic");
+ String log = buildRule.getLog();
+ assertContains("Expected warning about APrivate",
+ "The class APrivate in file", log);
+ assertContains("but has not been deleted because its source file "
+ + "could not be determined",
+ "The class APrivate in file", log);
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/i18n/TranslateTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/i18n/TranslateTest.java
new file mode 100644
index 00000000..6abc4f2d
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/i18n/TranslateTest.java
@@ -0,0 +1,87 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.i18n;
+
+import org.apache.tools.ant.BuildFileRule;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Tests the Translate task.
+ *
+ * @since Ant 1.6
+ */
+public class TranslateTest {
+
+ @Rule
+ public final BuildFileRule buildRule = new BuildFileRule();
+
+ static private final int BUF_SIZE = 32768;
+
+ private final static String TASKDEFS_DIR = "src/etc/testcases/taskdefs/optional/i18n/translate";
+
+
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject(TASKDEFS_DIR + "/translate.xml");
+ }
+
+ @Test
+ public void test1() throws IOException {
+ buildRule.executeTarget("test1");
+ assertTrue("translation of "+ TASKDEFS_DIR + "/input/template.txt",compareFiles(new File(buildRule.getProject().getBaseDir(), "expected/de/template.txt"),
+ new File(buildRule.getOutputDir(), "de/template.txt")));
+ }
+ private boolean compareFiles(File file1, File file2) throws IOException {
+ if (!file1.exists() || !file2.exists()) {
+ return false;
+ }
+
+ if (file1.length() != file2.length()) {
+ return false;
+ }
+
+ // byte - byte compare
+ byte[] buffer1 = new byte[BUF_SIZE];
+ byte[] buffer2 = new byte[BUF_SIZE];
+
+ FileInputStream fis1 = new FileInputStream(file1);
+ FileInputStream fis2 = new FileInputStream(file2);
+ int index = 0;
+ int read = 0;
+ while ((read = fis1.read(buffer1)) != -1) {
+ fis2.read(buffer2);
+ for (int i = 0; i < read; ++i, ++index) {
+ if (buffer1[i] != buffer2[i]) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/image/ImageTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/image/ImageTest.java
new file mode 100644
index 00000000..be79262d
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/image/ImageTest.java
@@ -0,0 +1,133 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.image;
+
+import org.apache.tools.ant.AntAssert;
+import org.apache.tools.ant.BuildFileRule;
+import org.apache.tools.ant.util.FileUtils;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Rule;
+import org.junit.Test;
+
+import java.io.File;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeTrue;
+
+
+/**
+ * Tests the Image task.
+ *
+ * @since Ant 1.5
+ */
+public class ImageTest {
+
+ private final static String TASKDEFS_DIR =
+ "src/etc/testcases/taskdefs/optional/image/";
+ private final static String LARGEIMAGE = "largeimage.jpg";
+
+ private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject(TASKDEFS_DIR + "image.xml");
+ }
+
+
+ @Test
+ public void testEchoToLog() {
+ buildRule.executeTarget("testEchoToLog");
+ AntAssert.assertContains("Processing File", buildRule.getLog());
+ }
+
+ @Test
+ public void testSimpleScale(){
+ buildRule.executeTarget("testSimpleScale");
+ AntAssert.assertContains("Processing File", buildRule.getLog());
+
+ File f = new File(buildRule.getOutputDir(), LARGEIMAGE);
+ assertTrue(
+ "Did not create "+f.getAbsolutePath(),
+ f.exists());
+
+ }
+
+ @Test
+ public void testOverwriteTrue() throws InterruptedException {
+ buildRule.executeTarget("testSimpleScale");
+ AntAssert.assertContains("Processing File", buildRule.getLog());
+ File f = new File(buildRule.getOutputDir(), LARGEIMAGE);
+ assumeTrue("Could not change file modificaiton date",
+ f.setLastModified(f.lastModified() - (FILE_UTILS.getFileTimestampGranularity() * 2)));
+ long lastModified = f.lastModified();
+ buildRule.executeTarget("testOverwriteTrue");
+ AntAssert.assertContains("Processing File", buildRule.getLog());
+ f = new File(buildRule.getOutputDir(), LARGEIMAGE);
+ long overwrittenLastModified = f.lastModified();
+ assertTrue("File was not overwritten.",
+ lastModified < overwrittenLastModified);
+ }
+
+ @Test
+ public void testOverwriteFalse() {
+ buildRule.executeTarget("testSimpleScale");
+ AntAssert.assertContains("Processing File", buildRule.getLog());
+ File f = new File(buildRule.getOutputDir(), LARGEIMAGE);
+ long lastModified = f.lastModified();
+ buildRule.executeTarget("testOverwriteFalse");
+ AntAssert.assertContains("Processing File", buildRule.getLog());
+ f = new File(buildRule.getOutputDir(), LARGEIMAGE);
+ long overwrittenLastModified = f.lastModified();
+ assertTrue("File was overwritten.",
+ lastModified == overwrittenLastModified);
+ }
+
+ @Test
+ public void testSimpleScaleWithMapper() {
+ buildRule.executeTarget("testSimpleScaleWithMapper");
+ AntAssert.assertContains("Processing File", buildRule.getLog());
+ File f = new File(buildRule.getOutputDir(), "scaled-" + LARGEIMAGE);
+ assertTrue(
+ "Did not create "+f.getAbsolutePath(),
+ f.exists());
+
+ }
+
+ @Test
+ @Ignore("Previously named in a manner to prevent execution")
+ public void testFailOnError() {
+ try {
+ buildRule.executeTarget("testFailOnError");
+ AntAssert.assertContains("Unable to process image stream", buildRule.getLog());
+ }
+ catch (RuntimeException re){
+ assertTrue("Run time exception should say "
+ + "'Unable to process image stream'. :"
+ + re.toString(),
+ re.toString()
+ .indexOf("Unable to process image stream") > -1);
+ }
+ }
+
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/jdepend/JDependTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/jdepend/JDependTest.java
new file mode 100644
index 00000000..545b7cbc
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/jdepend/JDependTest.java
@@ -0,0 +1,99 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.jdepend;
+
+import org.apache.tools.ant.AntAssert;
+import org.apache.tools.ant.BuildFileRule;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+/**
+ * Testcase for the JDepend optional task.
+ *
+ */
+public class JDependTest {
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject(
+ "src/etc/testcases/taskdefs/optional/jdepend/jdepend.xml");
+ }
+
+ /**
+ * Test simple
+ */
+ @Test
+ public void testSimple() {
+ buildRule.executeTarget("simple");
+ AntAssert.assertContains("Package: org.apache.tools.ant.util.facade",
+ buildRule.getOutput());
+ }
+
+ /**
+ * Test xml
+ */
+ @Test
+ public void testXml() {
+ buildRule.executeTarget("xml");
+ AntAssert.assertContains("<DependsUpon>", buildRule.getOutput());
+ }
+
+ /**
+ * Test fork
+ * - forked output goes to log
+ */
+ @Test
+ public void testFork() {
+ buildRule.executeTarget("fork");
+ AntAssert.assertContains("Package: org.apache.tools.ant.util.facade", buildRule.getLog());
+ }
+
+ /**
+ * Test fork xml
+ */
+ @Test
+ public void testForkXml() {
+ buildRule.executeTarget("fork-xml");
+ AntAssert.assertContains("<DependsUpon>", buildRule.getLog());
+ }
+
+ /**
+ * Test timeout
+ */
+ @Test
+ public void testTimeout() {
+ buildRule.executeTarget("fork-xml");
+ AntAssert.assertContains( "JDepend FAILED - Timed out", buildRule.getLog());
+ }
+
+
+ /**
+ * Test timeout without timing out
+ */
+ @Test
+ public void testTimeoutNot() {
+ buildRule.executeTarget("fork-timeout-not");
+ AntAssert.assertContains("Package: org.apache.tools.ant.util.facade", buildRule.getLog());
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/BatchTestTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/BatchTestTest.java
new file mode 100644
index 00000000..52a12ecc
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/BatchTestTest.java
@@ -0,0 +1,121 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.junit;
+
+
+import static org.junit.Assert.fail;
+import static org.junit.Assert.assertArrayEquals;
+
+import org.junit.Test;
+
+/**
+ *
+ * @author Marian Petras
+ */
+public class BatchTestTest {
+
+ @Test
+ public void testParseTestMethodNamesList() {
+ try {
+ JUnitTest.parseTestMethodNamesList(null);
+ fail("IllegalArgumentException expected when the param is <null>");
+ } catch (IllegalArgumentException ex) {
+ //this is an expected exception
+ }
+
+ assertArrayEquals(new String[0], JUnitTest.parseTestMethodNamesList(""));
+ assertArrayEquals(new String[0], JUnitTest.parseTestMethodNamesList(" "));
+ assertArrayEquals(new String[0], JUnitTest.parseTestMethodNamesList(" "));
+
+ checkParseCausesIAE(",");
+ checkParseCausesIAE(" ,");
+ checkParseCausesIAE(", ");
+ checkParseCausesIAE(" , ");
+ checkParseCausesIAE(",a");
+ checkParseCausesIAE(" ,a");
+ checkParseCausesIAE(" ,a");
+ checkParseCausesIAE(" , a");
+ checkParseCausesIAE(" ,a ");
+ checkParseCausesIAE(" ,a ,");
+ checkParseCausesIAE("ab,,cd");
+ checkParseCausesIAE("ab, ,cd");
+ checkParseCausesIAE("ab, ,cd");
+ checkParseCausesIAE("ab, ,cd,");
+ checkParseCausesIAE(",ab, ,cd,");
+
+ assertArrayEquals(new String[] {"abc"}, JUnitTest.parseTestMethodNamesList("abc"));
+ assertArrayEquals(new String[] {"abc"}, JUnitTest.parseTestMethodNamesList("abc "));
+ assertArrayEquals(new String[] {"abc"}, JUnitTest.parseTestMethodNamesList(" abc"));
+ assertArrayEquals(new String[] {"abc"}, JUnitTest.parseTestMethodNamesList(" abc "));
+ assertArrayEquals(new String[] {"abc"}, JUnitTest.parseTestMethodNamesList("abc "));
+ assertArrayEquals(new String[] {"abc"}, JUnitTest.parseTestMethodNamesList("abc,"));
+ assertArrayEquals(new String[] {"abc"}, JUnitTest.parseTestMethodNamesList("abc, "));
+ assertArrayEquals(new String[] {"abc"}, JUnitTest.parseTestMethodNamesList("abc ,"));
+ assertArrayEquals(new String[] {"abc"}, JUnitTest.parseTestMethodNamesList("abc , "));
+ assertArrayEquals(new String[] {"abc"}, JUnitTest.parseTestMethodNamesList(" abc ,"));
+
+ /* legal Java identifiers: */
+ assertArrayEquals(new String[] {"a"}, JUnitTest.parseTestMethodNamesList("a"));
+ assertArrayEquals(new String[] {"a1"}, JUnitTest.parseTestMethodNamesList("a1"));
+ assertArrayEquals(new String[] {"a$"}, JUnitTest.parseTestMethodNamesList("a$"));
+ assertArrayEquals(new String[] {"a$1"}, JUnitTest.parseTestMethodNamesList("a$1"));
+ assertArrayEquals(new String[] {"_bc"}, JUnitTest.parseTestMethodNamesList("_bc"));
+ assertArrayEquals(new String[] {"___"}, JUnitTest.parseTestMethodNamesList("___"));
+
+ /* illegal Java identifiers: */
+ checkParseCausesIAE("1");
+ checkParseCausesIAE("1a");
+ checkParseCausesIAE("1ab");
+ checkParseCausesIAE("1abc");
+ checkParseCausesIAE("1abc d");
+ checkParseCausesIAE("1abc de");
+ checkParseCausesIAE("1abc def");
+ checkParseCausesIAE("1abc def,");
+ checkParseCausesIAE(",1abc def");
+
+ assertArrayEquals(new String[] {"abc", "def"}, JUnitTest.parseTestMethodNamesList("abc,def"));
+ assertArrayEquals(new String[] {"abc", "def"}, JUnitTest.parseTestMethodNamesList("abc,def,"));
+ assertArrayEquals(new String[] {"abc", "def"}, JUnitTest.parseTestMethodNamesList("abc,def "));
+ assertArrayEquals(new String[] {"abc", "def"}, JUnitTest.parseTestMethodNamesList("abc, def"));
+ assertArrayEquals(new String[] {"abc", "def"}, JUnitTest.parseTestMethodNamesList("abc, def "));
+ assertArrayEquals(new String[] {"abc", "def"}, JUnitTest.parseTestMethodNamesList("abc ,def"));
+ assertArrayEquals(new String[] {"abc", "def"}, JUnitTest.parseTestMethodNamesList("abc ,def "));
+ assertArrayEquals(new String[] {"abc", "def"}, JUnitTest.parseTestMethodNamesList("abc , def"));
+ assertArrayEquals(new String[] {"abc", "def"}, JUnitTest.parseTestMethodNamesList("abc , def "));
+ assertArrayEquals(new String[] {"abc", "def"}, JUnitTest.parseTestMethodNamesList(" abc,def"));
+ assertArrayEquals(new String[] {"abc", "def"}, JUnitTest.parseTestMethodNamesList(" abc,def "));
+ assertArrayEquals(new String[] {"abc", "def"}, JUnitTest.parseTestMethodNamesList(" abc, def"));
+ assertArrayEquals(new String[] {"abc", "def"}, JUnitTest.parseTestMethodNamesList(" abc, def "));
+ assertArrayEquals(new String[] {"abc", "def"}, JUnitTest.parseTestMethodNamesList(" abc ,def"));
+ assertArrayEquals(new String[] {"abc", "def"}, JUnitTest.parseTestMethodNamesList(" abc ,def "));
+ assertArrayEquals(new String[] {"abc", "def"}, JUnitTest.parseTestMethodNamesList(" abc , def"));
+ assertArrayEquals(new String[] {"abc", "def"}, JUnitTest.parseTestMethodNamesList(" abc , def "));
+ assertArrayEquals(new String[] {"abc", "def"}, JUnitTest.parseTestMethodNamesList(" abc , def ,"));
+ }
+
+ private static void checkParseCausesIAE(String param) {
+ try {
+ JUnitTest.parseTestMethodNamesList(param);
+ fail("IllegalArgumentException expected when the param is \"" + param + '"');
+ } catch (IllegalArgumentException ex) {
+ //this is an expected exception
+ }
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/DOMUtilTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/DOMUtilTest.java
new file mode 100644
index 00000000..b72f69cc
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/DOMUtilTest.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.junit;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.xml.parsers.DocumentBuilder;
+
+import org.apache.tools.ant.util.JAXPUtils;
+import org.junit.Test;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.SAXException;
+
+public class DOMUtilTest {
+
+ @Test
+ public void testListChildNodes() throws SAXException, IOException {
+ DocumentBuilder db = JAXPUtils.getDocumentBuilder();
+ InputStream is = this.getClass().getClassLoader().getResourceAsStream("taskdefs/optional/junit/matches.xml");
+ Document doc = db.parse(is);
+ NodeList nl = DOMUtil.listChildNodes(doc.getDocumentElement(), new FooNodeFilter(), true);
+ assertEquals("expecting 3", 3, nl.getLength());
+ }
+
+ public class FooNodeFilter implements DOMUtil.NodeFilter {
+ public boolean accept(Node node) {
+ if (node.getNodeName().equals("foo")) {
+ return true;
+ }
+ return false;
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/JUnitClassLoaderTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/JUnitClassLoaderTest.java
new file mode 100644
index 00000000..4baf7418
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/JUnitClassLoaderTest.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.junit;
+
+import static org.junit.Assert.assertSame;
+
+import org.junit.Test;
+
+/**
+ * Test to ensure that the classloader loading JUnit testcase
+ * is also the context classloader.
+ *
+ */
+public class JUnitClassLoaderTest {
+
+ @Test
+ public void testContextClassLoader(){
+ ClassLoader context = Thread.currentThread().getContextClassLoader();
+ ClassLoader caller = getClass().getClassLoader();
+ assertSame(context, caller);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/JUnitReportTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/JUnitReportTest.java
new file mode 100644
index 00000000..c5b6feb9
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/JUnitReportTest.java
@@ -0,0 +1,211 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.junit;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.apache.tools.ant.AntAssert.assertContains;
+import static org.junit.Assert.fail;
+
+import java.io.File;
+import java.io.FileReader;
+import java.io.InputStream;
+import java.net.URL;
+
+import org.apache.tools.ant.BuildFileRule;
+import org.apache.tools.ant.util.FileUtils;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+/**
+ * Small testcase for the junitreporttask.
+ * First test added to reproduce an fault, still a lot to improve
+ *
+ */
+public class JUnitReportTest {
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/optional/junitreport.xml");
+ }
+
+ /**
+ * Verifies that no empty junit-noframes.html is generated when frames
+ * output is selected via the default.
+ * Needs reports1 task from junitreport.xml.
+ */
+ @Test
+ public void testNoFileJUnitNoFrames() {
+ buildRule.executeTarget("reports1");
+ assertFalse("No file junit-noframes.html expected", (new File(System.getProperty("root"), "src/etc/testcases/taskdefs/optional/junitreport/test/html/junit-noframes.html").exists()));
+
+ }
+
+ public void assertIndexCreated() {
+ if (!new File(buildRule.getProject().getProperty("output"), "html/index.html").exists()) {
+ fail("No file index file found");
+ }
+
+ }
+
+
+ @Test
+ public void testEmptyFile() throws Exception {
+ buildRule.executeTarget("testEmptyFile");
+ assertIndexCreated();
+ assertContains("Required text not found in log", XMLResultAggregator.WARNING_EMPTY_FILE, buildRule.getLog());
+ }
+
+ @Test
+ public void testIncompleteFile() throws Exception {
+ buildRule.executeTarget("testIncompleteFile");
+ assertIndexCreated();
+ assertContains("Required text not found in log", XMLResultAggregator.WARNING_IS_POSSIBLY_CORRUPTED, buildRule.getLog());
+ }
+
+ @Test
+ public void testWrongElement() throws Exception {
+ buildRule.executeTarget("testWrongElement");
+ assertIndexCreated();
+ assertContains("Required text not found in log", XMLResultAggregator.WARNING_INVALID_ROOT_ELEMENT, buildRule.getLog());
+ }
+
+ // Bugzilla Report 34963
+ @Test
+ public void testStackTraceLineBreaks() throws Exception {
+ buildRule.executeTarget("testStackTraceLineBreaks");
+ assertIndexCreated();
+ FileReader r = null;
+ try {
+ r = new FileReader(new File(buildRule.getOutputDir(), "html/sampleproject/coins/0_CoinTest.html"));
+ String report = FileUtils.readFully(r);
+ assertContains("output must contain <br>:\n" + report, "junit.framework.AssertionFailedError: DOEG<br>", report);
+ assertContains("#51049: output must translate line breaks:\n" + report, "cur['line.separator'] = '\\r\\n';", report);
+ } finally {
+ FileUtils.close(r);
+ }
+ }
+
+
+ // Bugzilla Report 38477
+ @Test
+ public void testSpecialSignsInSrcPath() throws Exception {
+ buildRule.executeTarget("testSpecialSignsInSrcPath");
+ File reportFile = new File(buildRule.getOutputDir(), "html/index.html");
+ // tests one the file object
+ assertTrue("No index.html present. Not generated?", reportFile.exists() );
+ assertTrue("Cant read the report file.", reportFile.canRead() );
+ assertTrue("File shouldn't be empty.", reportFile.length() > 0 );
+ // conversion to URL via FileUtils like in XMLResultAggregator, not as suggested in the bug report
+ URL reportUrl = new URL( FileUtils.getFileUtils().toURI(reportFile.getAbsolutePath()) );
+ InputStream reportStream = reportUrl.openStream();
+ assertTrue("This shouldn't be an empty stream.", reportStream.available() > 0);
+ }
+
+ @Test
+ public void testSpecialSignsInHtmlPath() throws Exception {
+ buildRule.executeTarget("testSpecialSignsInHtmlPath");
+ File reportFile = new File(buildRule.getOutputDir(), "html# $%\u00A7&-!report/index.html");
+ // tests one the file object
+ assertTrue("No index.html present. Not generated?", reportFile.exists() );
+ assertTrue("Cant read the report file.", reportFile.canRead() );
+ assertTrue("File shouldn't be empty.", reportFile.length() > 0 );
+ // conversion to URL via FileUtils like in XMLResultAggregator, not as suggested in the bug report
+ URL reportUrl = new URL( FileUtils.getFileUtils().toURI(reportFile.getAbsolutePath()) );
+ InputStream reportStream = reportUrl.openStream();
+ assertTrue("This shouldn't be an empty stream.", reportStream.available() > 0);
+ }
+
+ //Bugzilla Report 39708
+ @Test
+ public void testWithStyleFromDir() throws Exception {
+ buildRule.executeTarget("testWithStyleFromDir");
+ File reportFile = new File(buildRule.getOutputDir(), "html/index.html");
+ // tests one the file object
+ assertTrue("No index.html present. Not generated?", reportFile.exists() );
+ assertTrue("Cant read the report file.", reportFile.canRead() );
+ assertTrue("File shouldn't be empty.", reportFile.length() > 0 );
+ // conversion to URL via FileUtils like in XMLResultAggregator, not as suggested in the bug report
+ URL reportUrl = new URL( FileUtils.getFileUtils().toURI(reportFile.getAbsolutePath()) );
+ InputStream reportStream = reportUrl.openStream();
+ assertTrue("This shouldn't be an empty stream.", reportStream.available() > 0);
+ }
+
+ //Bugzilla Report 40021
+ @Test
+ public void testNoFrames() throws Exception {
+ buildRule.executeTarget("testNoFrames");
+ File reportFile = new File(buildRule.getOutputDir(), "html/junit-noframes.html");
+ // tests one the file object
+ assertTrue("No junit-noframes.html present. Not generated?", reportFile.exists() );
+ assertTrue("Cant read the report file.", reportFile.canRead() );
+ assertTrue("File shouldn't be empty.", reportFile.length() > 0 );
+ // conversion to URL via FileUtils like in XMLResultAggregator, not as suggested in the bug report
+ URL reportUrl = new URL( FileUtils.getFileUtils().toURI(reportFile.getAbsolutePath()) );
+ InputStream reportStream = reportUrl.openStream();
+ assertTrue("This shouldn't be an empty stream.", reportStream.available() > 0);
+ }
+ //Bugzilla Report 39708
+ @Test
+ public void testWithStyleFromDirAndXslImport() throws Exception {
+ buildRule.executeTarget("testWithStyleFromDirAndXslImport");
+ File reportFile = new File(buildRule.getOutputDir(), "html/index.html");
+ // tests one the file object
+ assertTrue("No index.html present. Not generated?", reportFile.exists() );
+ assertTrue("Cant read the report file.", reportFile.canRead() );
+ assertTrue("File shouldn't be empty.", reportFile.length() > 0 );
+ // conversion to URL via FileUtils like in XMLResultAggregator, not as suggested in the bug report
+ URL reportUrl = new URL( FileUtils.getFileUtils().toURI(reportFile.getAbsolutePath()) );
+ InputStream reportStream = reportUrl.openStream();
+ assertTrue("This shouldn't be an empty stream.", reportStream.available() > 0);
+ }
+
+ @Test
+ public void testWithStyleFromClasspath() throws Exception {
+ buildRule.executeTarget("testWithStyleFromClasspath");
+ File reportFile = new File(buildRule.getOutputDir(), "html/index.html");
+ // tests one the file object
+ assertTrue("No index.html present. Not generated?", reportFile.exists() );
+ assertTrue("Cant read the report file.", reportFile.canRead() );
+ assertTrue("File shouldn't be empty.", reportFile.length() > 0 );
+ // conversion to URL via FileUtils like in XMLResultAggregator, not as suggested in the bug report
+ URL reportUrl = new URL( FileUtils.getFileUtils().toURI(reportFile.getAbsolutePath()) );
+ InputStream reportStream = reportUrl.openStream();
+ assertTrue("This shouldn't be an empty stream.", reportStream.available() > 0);
+ }
+
+ @Test
+ public void testWithParams() throws Exception {
+ buildRule.executeTarget("testWithParams");
+ assertContains("key1=value1,key2=value2", buildRule.getLog());
+ File reportFile = new File(buildRule.getOutputDir(), "html/index.html");
+ // tests one the file object
+ assertTrue("No index.html present. Not generated?", reportFile.exists() );
+ assertTrue("Cant read the report file.", reportFile.canRead() );
+ assertTrue("File shouldn't be empty.", reportFile.length() > 0 );
+ // conversion to URL via FileUtils like in XMLResultAggregator, not as suggested in the bug report
+ URL reportUrl = new URL( FileUtils.getFileUtils().toURI(reportFile.getAbsolutePath()) );
+ InputStream reportStream = reportUrl.openStream();
+ assertTrue("This shouldn't be an empty stream.", reportStream.available() > 0);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/JUnitTaskTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/JUnitTaskTest.java
new file mode 100644
index 00000000..61504ad1
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/JUnitTaskTest.java
@@ -0,0 +1,398 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.junit;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import static org.apache.tools.ant.AntAssert.assertNotContains;
+import static org.apache.tools.ant.AntAssert.assertContains;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathFactory;
+
+import org.apache.tools.ant.BuildFileRule;
+import org.apache.tools.ant.util.JavaEnvUtils;
+import org.junit.Assume;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+
+public class JUnitTaskTest {
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ /**
+ * The JUnit setup method.
+ */
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/optional/junit.xml");
+ }
+
+ @Test
+ public void testCrash() {
+ buildRule.executeTarget("crash");
+ assertEquals("true", buildRule.getProject().getProperty("crashed"));
+ }
+
+ @Test
+ public void testNoCrash() {
+ buildRule.executeTarget("nocrash");
+ assertNull(buildRule.getProject().getProperty("crashed"));
+ }
+
+ @Test
+ public void testTimeout() {
+ buildRule.executeTarget("timeout");
+ assertEquals("true", buildRule.getProject().getProperty("timeout"));
+ }
+
+ @Test
+ public void testNoTimeout() {
+ buildRule.executeTarget("notimeout");
+ assertNull(buildRule.getProject().getProperty("timeout"));
+ }
+
+ @Test
+ public void testNonForkedCapture() throws IOException {
+ buildRule.executeTarget("capture");
+ assertNoPrint(buildRule.getLog(), "log");
+ assertNoPrint(buildRule.getFullLog(), "debug log");
+ }
+
+ @Test
+ public void testForkedCapture() throws IOException {
+ buildRule.getProject().setProperty("fork", "true");
+ testNonForkedCapture();
+ // those would fail because of the way BuildFileRule captures output
+ assertNoPrint(buildRule.getOutput(), "output");
+ assertNoPrint(buildRule.getError(), "error output");
+ assertOutput();
+ }
+
+ @Test
+ public void testBatchTestForkOnceToDir() {
+ assertResultFilesExist("testBatchTestForkOnceToDir", ".xml");
+ }
+
+ /** Bugzilla Report 32973 */
+ @Test
+ public void testBatchTestForkOnceExtension() {
+ assertResultFilesExist("testBatchTestForkOnceExtension", ".foo");
+ }
+
+
+ /* Bugzilla Report 42984 */
+ //TODO This scenario works from command line, but not from JUnit ...
+ // Running these steps from the junit.xml-directory work
+ // $ ant -f junit.xml failureRecorder.prepare
+ // $ ant -f junit.xml failureRecorder.runtest
+ // $ ant -f junit.xml failureRecorder.runtest
+ // $ ant -f junit.xml failureRecorder.fixing
+ // $ ant -f junit.xml failureRecorder.runtest
+ // $ ant -f junit.xml failureRecorder.runtest
+ // But running the JUnit testcase fails in 4th run.
+ @Test
+ public void testFailureRecorder() {
+ if (JavaEnvUtils.isAtLeastJavaVersion(JavaEnvUtils.JAVA_1_5)) {
+ try {
+ Class<?> clazz =Class.forName("junit.framework.JUnit4TestAdapter");
+ Assume.assumeFalse("Skipping test since it fails with JUnit 4", clazz != null);
+ } catch (ClassNotFoundException e) {
+ // OK, this is JUnit3, can run test
+ }
+ }
+
+ File testDir = new File(buildRule.getOutputDir(), "out");
+ File collectorFile = new File(buildRule.getOutputDir(),
+ "out/FailedTests.java");
+
+ // ensure that there is a clean test environment
+ assertFalse("Test directory '" + testDir.getAbsolutePath()
+ + "' must not exist before the test preparation.",
+ testDir.exists());
+ assertFalse("The collector file '"
+ + collectorFile.getAbsolutePath()
+ + "'must not exist before the test preparation.",
+ collectorFile.exists());
+
+
+ // prepare the test environment
+ buildRule.executeTarget("failureRecorder.prepare");
+ assertTrue("Test directory '" + testDir.getAbsolutePath()
+ + "' was not created.", testDir.exists());
+ assertTrue("There should be one class.",
+ (new File(testDir, "A.class")).exists());
+ assertFalse("The collector file '"
+ + collectorFile.getAbsolutePath()
+ + "' should not exist before the 1st run.",
+ collectorFile.exists());
+
+
+ // 1st junit run: should do all tests - failing and not failing tests
+ buildRule.executeTarget("failureRecorder.runtest");
+ assertTrue("The collector file '" + collectorFile.getAbsolutePath()
+ + "' should exist after the 1st run.",
+ collectorFile.exists());
+ // the passing test cases
+ buildRule.executeTarget("A.test01");
+ assertContains("1st run: should run A.test01", buildRule.getOutput());
+ buildRule.executeTarget("B.test05");
+ assertContains("1st run: should run B.test05", buildRule.getOutput());
+ buildRule.executeTarget("B.test06");
+ assertContains("1st run: should run B.test06", buildRule.getOutput());
+ buildRule.executeTarget("C.test07");
+ assertContains("1st run: should run C.test07", buildRule.getOutput());
+ buildRule.executeTarget("C.test08");
+ assertContains("1st run: should run C.test08", buildRule.getOutput());
+ buildRule.executeTarget("C.test09");
+ assertContains("1st run: should run C.test09", buildRule.getOutput());
+ // the failing test cases
+ buildRule.executeTarget("A.test02");
+ assertContains("1st run: should run A.test02", buildRule.getOutput());
+ buildRule.executeTarget("A.test03");
+ assertContains("1st run: should run A.test03", buildRule.getOutput());
+ buildRule.executeTarget("B.test04");
+ assertContains("1st run: should run B.test04", buildRule.getOutput());
+ buildRule.executeTarget("D.test10");
+ assertContains("1st run: should run D.test10", buildRule.getOutput());
+
+
+ // 2nd junit run: should do only failing tests
+ buildRule.executeTarget("failureRecorder.runtest");
+ assertTrue("The collector file '" + collectorFile.getAbsolutePath()
+ + "' should exist after the 2nd run.",
+ collectorFile.exists());
+ // the passing test cases
+ buildRule.executeTarget("A.test01");
+ assertNotContains("2nd run: should not run A.test01", buildRule.getOutput());
+ buildRule.executeTarget("B.test05");
+ assertNotContains("2nd run: should not run A.test05", buildRule.getOutput());
+ buildRule.executeTarget("B.test06");
+ assertNotContains("2nd run: should not run B.test06", buildRule.getOutput());
+ buildRule.executeTarget("C.test07");
+ assertNotContains("2nd run: should not run C.test07", buildRule.getOutput());
+ buildRule.executeTarget("C.test08");
+ assertNotContains("2nd run: should not run C.test08", buildRule.getOutput());
+ buildRule.executeTarget("C.test09");
+ assertNotContains("2nd run: should not run C.test09", buildRule.getOutput());
+ // the failing test cases
+ buildRule.executeTarget("A.test02");
+ assertContains("2nd run: should run A.test02", buildRule.getOutput());
+ buildRule.executeTarget("A.test03");
+ assertContains("2nd run: should run A.test03", buildRule.getOutput());
+ buildRule.executeTarget("B.test04");
+ assertContains("2nd run: should run B.test04", buildRule.getOutput());
+ buildRule.executeTarget("D.test10");
+ assertContains("2nd run: should run D.test10", buildRule.getOutput());
+
+
+ // "fix" errors in class A
+ buildRule.executeTarget("failureRecorder.fixing");
+
+ // 3rd run: four running tests with two errors
+ buildRule.executeTarget("failureRecorder.runtest");
+ assertTrue("The collector file '" + collectorFile.getAbsolutePath()
+ + "' should exist after the 3rd run.",
+ collectorFile.exists());
+ buildRule.executeTarget("A.test02");
+ assertContains("3rd run: should run A.test02", buildRule.getOutput());
+ buildRule.executeTarget("A.test03");
+ assertContains("3rd run: should run A.test03", buildRule.getOutput());
+ buildRule.executeTarget("B.test04");
+ assertContains("3rd run: should run B.test04", buildRule.getOutput());
+ buildRule.executeTarget("D.test10");
+ assertContains("3rd run: should run D.test10", buildRule.getOutput());
+
+
+ // 4rd run: two running tests with errors
+ buildRule.executeTarget("failureRecorder.runtest");
+ assertTrue("The collector file '" + collectorFile.getAbsolutePath()
+ + "' should exist after the 4th run.",
+ collectorFile.exists());
+ //TODO: these two statements fail
+ //buildRule.executeTarget("A.test02");assertNotContains("4th run: should not run A.test02", buildRule.getOutput());
+ //buildRule.executeTarget("A.test03");assertNotContains("4th run: should not run A.test03", buildRule.getOutput());
+ buildRule.executeTarget("B.test04");
+ assertContains("4th run: should run B.test04", buildRule.getOutput());
+ buildRule.executeTarget("D.test10");
+ assertContains("4th run: should run D.test10", buildRule.getOutput());
+
+ }
+
+ @Test
+ public void testBatchTestForkOnceCustomFormatter() {
+ assertResultFilesExist("testBatchTestForkOnceCustomFormatter", "foo");
+ }
+
+ // Bugzilla Issue 45411
+ @Test
+ public void testMultilineAssertsNoFork() {
+ buildRule.executeTarget("testMultilineAssertsNoFork");
+ assertNotContains("messaged up", buildRule.getLog());
+ assertNotContains("crashed)", buildRule.getLog());
+ }
+
+ // Bugzilla Issue 45411
+ @Test
+ public void testMultilineAssertsFork() {
+ buildRule.executeTarget("testMultilineAssertsFork");
+ assertNotContains("messaged up", buildRule.getLog());
+ assertNotContains("crashed)", buildRule.getLog());
+ }
+
+ private void assertResultFilesExist(String target, String extension) {
+ buildRule.executeTarget(target);
+ assertResultFileExists("JUnitClassLoader", extension);
+ assertResultFileExists("JUnitTestRunner", extension);
+ assertResultFileExists("JUnitVersionHelper", extension);
+ }
+
+ private void assertResultFileExists(String classNameFragment, String ext) {
+ assertTrue("result for " + classNameFragment + "Test" + ext + " exists",
+
+ new File(buildRule.getOutputDir(), "TEST-org.apache.tools.ant."
+ + "taskdefs.optional.junit."
+ + classNameFragment + "Test" + ext)
+ .exists());
+ }
+
+ private void assertNoPrint(String result, String where) {
+ assertNotContains(where + " '" + result + "' must not contain print statement",
+ "print to System.", result);
+ }
+
+ private void assertOutput() throws IOException {
+ FileReader inner = new FileReader(new File(buildRule.getOutputDir(),
+ "testlog.txt"));
+ BufferedReader reader = new BufferedReader(inner);
+ try {
+ String line = reader.readLine();
+ assertEquals("Testsuite: org.apache.tools.ant.taskdefs.optional.junit.Printer",
+ line);
+ line = reader.readLine();
+ assertNotNull(line);
+ assertTrue(line.startsWith("Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed:"));
+ line = reader.readLine();
+ assertEquals("------------- Standard Output ---------------",
+ line);
+ assertPrint(reader.readLine(), "static", "out");
+ assertPrint(reader.readLine(), "constructor", "out");
+ assertPrint(reader.readLine(), "method", "out");
+ line = reader.readLine();
+ assertEquals("------------- ---------------- ---------------",
+ line);
+ line = reader.readLine();
+ assertEquals("------------- Standard Error -----------------",
+ line);
+ assertPrint(reader.readLine(), "static", "err");
+ assertPrint(reader.readLine(), "constructor", "err");
+ assertPrint(reader.readLine(), "method", "err");
+ line = reader.readLine();
+ assertEquals("------------- ---------------- ---------------",
+ line);
+ line = reader.readLine();
+ assertEquals("", line);
+ line = reader.readLine();
+ assertNotNull(line);
+ assertTrue(line.startsWith("Testcase: testNoCrash took "));
+ } finally {
+ inner.close();
+ }
+ }
+
+ private void assertPrint(String line, String from, String to) {
+ String search = from + " print to System." + to;
+ assertEquals(search, line);
+ }
+
+ @Test
+ public void testJUnit4Skip() throws Exception {
+ buildRule.executeTarget("testSkippableTests");
+
+ DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
+ DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
+ Document doc = dBuilder.parse(new File(buildRule.getOutputDir(), "TEST-org.example.junit.JUnit4Skippable.xml"));
+
+ assertEquals("Incorrect number of nodes created", 8, doc.getElementsByTagName("testcase").getLength());
+
+ XPathFactory factory = XPathFactory.newInstance();
+ XPath xpath = factory.newXPath();
+
+ assertEquals("Incorrect number of skipped tests in header", 4, Integer.parseInt(xpath.compile("//testsuite/@skipped").evaluate(doc)));
+ assertEquals("Incorrect number of error tests in header", 1, Integer.parseInt(xpath.compile("//testsuite/@errors").evaluate(doc)));
+ assertEquals("Incorrect number of failure tests in header", 2, Integer.parseInt(xpath.compile("//testsuite/@failures").evaluate(doc)));
+ assertEquals("Incorrect number of tests in header", 8, Integer.parseInt(xpath.compile("//testsuite/@tests").evaluate(doc)));
+
+
+ assertEquals("Incorrect ignore message on explicit ignored test", "Please don't ignore me!", xpath.compile("//testsuite/testcase[@name='explicitIgnoreTest']/skipped/@message").evaluate(doc));
+ assertEquals("No message should be set on Ignored tests with no Ignore annotation text", 0, ((Node)xpath.compile("//testsuite/testcase[@name='explicitlyIgnoreTestNoMessage']/skipped").evaluate(doc, XPathConstants.NODE)).getAttributes().getLength());
+ assertEquals("Incorrect ignore message on implicit ignored test", "This test will be ignored", xpath.compile("//testsuite/testcase[@name='implicitlyIgnoreTest']/skipped/@message").evaluate(doc));
+ assertNotNull("Implicit ignore test should have an ignore element", xpath.compile("//testsuite/testcase[@name='implicitlyIgnoreTestNoMessage']/skipped").evaluate(doc, XPathConstants.NODE));
+
+ }
+
+ @Test
+ public void testTestMethods() throws Exception {
+ buildRule.executeTarget("testTestMethods");
+ }
+
+ @Test
+ public void testNonTestsSkipped() throws Exception {
+
+ buildRule.executeTarget("testNonTests");
+ assertFalse("Test result should not exist as test was skipped - TEST-org.example.junit.NonTestMissed.xml", new File(buildRule.getOutputDir(), "TEST-org.example.junit.NonTestMissed.xml").exists());
+ assertFalse("Test result should not exist as test was skipped - TEST-org.example.junit.JUnit3NonTestMissed.xml", new File(buildRule.getOutputDir(), "TEST-org.example.junit.JUnit3TestMissed.xml").exists());
+ assertFalse("Test result should not exist as test was skipped - TEST-org.example.junit.AbstractTestMissed.xml", new File(buildRule.getOutputDir(), "TEST-org.example.junit.AbstractTestMissed.xml").exists());
+ assertFalse("Test result should not exist as test was skipped - TEST-org.example.junit.AbstractJUnit3TestMissed.xml", new File(buildRule.getOutputDir(), "TEST-org.example.junit.AbstractJUnit3TestMissed.xml").exists());
+ assertTrue("Test result should exist as test was not skipped - TEST-org.example.junit.AbstractTestNotMissed.xml", new File(buildRule.getOutputDir(), "TEST-org.example.junit.AbstractTestNotMissed.xml").exists());
+ assertTrue("Test result should exist as test was not skipped - TEST-org.example.junit.AbstractJUnit3TestNotMissed.xml", new File(buildRule.getOutputDir(), "TEST-org.example.junit.AbstractJUnit3TestNotMissed.xml").exists());
+ assertTrue("Test result should exist as test was not skipped - TEST-org.example.junit.TestNotMissed.xml", new File(buildRule.getOutputDir(), "TEST-org.example.junit.TestNotMissed.xml").exists());
+ assertTrue("Test result should exist as test was not skipped - TEST-org.example.junit.JUnit3TestNotMissed.xml", new File(buildRule.getOutputDir(), "TEST-org.example.junit.JUnit3TestNotMissed.xml").exists());
+ assertTrue("Test result should exist as test was not skipped - TEST-org.example.junit.TestWithSuiteNotMissed.xml", new File(buildRule.getOutputDir(), "TEST-org.example.junit.TestWithSuiteNotMissed.xml").exists());
+
+ buildRule.executeTarget("testNonTestsRun");
+ assertTrue("Test result should exist as test was not skipped - TEST-org.example.junit.NonTestMissed.xml", new File(buildRule.getOutputDir(), "TEST-org.example.junit.NonTestMissed.xml").exists());
+ assertTrue("Test result should exist as test was not skipped - TEST-org.example.junit.JUnit3NonTestMissed.xml", new File(buildRule.getOutputDir(), "TEST-org.example.junit.JUnit3NonTestMissed.xml").exists());
+ assertTrue("Test result should exist as test was not skipped - TEST-org.example.junit.TestNotMissed.xml", new File(buildRule.getOutputDir(), "TEST-org.example.junit.TestNotMissed.xml").exists());
+ assertTrue("Test result should exist as test was not skipped - TEST-org.example.junit.JUnit3TestNotMissed.xml", new File(buildRule.getOutputDir(), "TEST-org.example.junit.JUnit3TestNotMissed.xml").exists());
+ assertTrue("Test result should exist as test was not skipped - TEST-org.example.junit.AbstractTestMissed.xml", new File(buildRule.getOutputDir(), "TEST-org.example.junit.AbstractTestMissed.xml").exists());
+ assertTrue("Test result should exist as test was not skipped - TEST-org.example.junit.AbstractTestNotMissed.xml", new File(buildRule.getOutputDir(), "TEST-org.example.junit.AbstractTestNotMissed.xml").exists());
+ assertTrue("Test result should exist as test was not skipped - TEST-org.example.junit.AbstractJUnit3TestMissed.xml", new File(buildRule.getOutputDir(), "TEST-org.example.junit.AbstractJUnit3TestMissed.xml").exists());
+ assertTrue("Test result should exist as test was not skipped - TEST-org.example.junit.JUnit3NonTestMissed.xml", new File(buildRule.getOutputDir(), "TEST-org.example.junit.JUnit3NonTestMissed.xml").exists());
+ assertTrue("Test result should exist as test was not skipped - TEST-org.example.junit.TestWithSuiteNotMissed.xml", new File(buildRule.getOutputDir(), "TEST-org.example.junit.TestWithSuiteNotMissed.xml").exists());
+
+
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/JUnitTestListenerTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/JUnitTestListenerTest.java
new file mode 100644
index 00000000..38eaa142
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/JUnitTestListenerTest.java
@@ -0,0 +1,111 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.junit;
+
+import static org.apache.tools.ant.AntAssert.assertContains;
+import static org.apache.tools.ant.AntAssert.assertNotContains;
+
+import org.apache.tools.ant.BuildFileRule;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+public class JUnitTestListenerTest{
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ // The captureToSummary test writes to stdout and stderr, good for
+ // verifying that the TestListener support doesn't break anything.
+ private static final String PASS_TEST_TARGET = "captureToSummary";
+
+ // testNoCrash is the test invoked by the captureToSummary's junit task
+ private static final String PASS_TEST = "testNoCrash";
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/optional/junit.xml");
+ }
+
+
+ @Test
+ public void testFullLogOutput() {
+ buildRule.getProject().setProperty("enableEvents", "true");
+ buildRule.executeTarget(PASS_TEST_TARGET);
+ assertContains("expecting full log to have BuildListener events",
+ JUnitTask.TESTLISTENER_PREFIX, buildRule.getFullLog());
+ }
+
+ @Test
+ public void testNoLogOutput() {
+ buildRule.getProject().setProperty("enableEvents", "true");
+ buildRule.executeTarget(PASS_TEST_TARGET);
+ assertNotContains("expecting log to not have BuildListener events",
+ JUnitTask.TESTLISTENER_PREFIX, buildRule.getLog());
+ }
+
+ @Test
+ public void testTestCountFired() {
+ buildRule.getProject().setProperty("enableEvents", "true");
+ buildRule.executeTarget(PASS_TEST_TARGET);
+ assertContains("expecting test count message", JUnitTask.TESTLISTENER_PREFIX +
+ "tests to run: ", buildRule.getFullLog());
+ }
+
+ @Test
+ public void testStartTestFired() {
+ buildRule.getProject().setProperty("enableEvents", "true");
+ buildRule.executeTarget(PASS_TEST_TARGET);
+ assertContains("expecting test started message", JUnitTask.TESTLISTENER_PREFIX +
+ "startTest(" + PASS_TEST + ")", buildRule.getFullLog());
+ }
+
+ @Test
+ public void testEndTestFired() {
+ buildRule.getProject().setProperty("enableEvents", "true");
+ buildRule.executeTarget(PASS_TEST_TARGET);
+ assertContains("expecting test ended message", JUnitTask.TESTLISTENER_PREFIX +
+ "endTest(" + PASS_TEST + ")", buildRule.getFullLog());
+ }
+
+ @Test
+ public void testNoFullLogOutputByDefault() {
+ buildRule.executeTarget(PASS_TEST_TARGET);
+ assertNotContains("expecting full log to not have BuildListener events",
+ JUnitTask.TESTLISTENER_PREFIX, buildRule.getFullLog());
+ }
+
+ @Test
+ public void testFullLogOutputMagicProperty() {
+ buildRule.getProject().setProperty(JUnitTask.ENABLE_TESTLISTENER_EVENTS, "true");
+ buildRule.executeTarget(PASS_TEST_TARGET);
+ assertContains("expecting full log to have BuildListener events",
+ JUnitTask.TESTLISTENER_PREFIX, buildRule.getFullLog());
+ }
+
+ @Test
+ public void testNoFullLogOutputMagicPropertyWins() {
+ buildRule.getProject().setProperty(JUnitTask.ENABLE_TESTLISTENER_EVENTS, "false");
+ buildRule.getProject().setProperty("enableEvents", "true");
+ buildRule.executeTarget(PASS_TEST_TARGET);
+ assertNotContains("expecting full log to not have BuildListener events",
+ JUnitTask.TESTLISTENER_PREFIX, buildRule.getFullLog());
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/JUnitTestRunnerTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/JUnitTestRunnerTest.java
new file mode 100644
index 00000000..a75c5cbe
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/JUnitTestRunnerTest.java
@@ -0,0 +1,217 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.junit;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+import junit.framework.AssertionFailedError;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+import org.apache.tools.ant.BuildException;
+import org.junit.Test;
+
+/**
+ * Small testcase for the runner, tests are very very very basics.
+ * They must be enhanced with time.
+ *
+ */
+public class JUnitTestRunnerTest{
+
+
+
+ // check that a valid method name generates no errors
+ @Test
+ public void testValidMethod(){
+ TestRunner runner = createRunnerForTestMethod(ValidMethodTestCase.class,"testA");
+ runner.run();
+ assertEquals(runner.getFormatter().getError(), JUnitTestRunner.SUCCESS, runner.getRetCode());
+ }
+
+ // check that having an invalid method name generates an error
+ @Test
+ public void testInvalidMethod(){
+ TestRunner runner = createRunnerForTestMethod(InvalidMethodTestCase.class,"testInvalid");
+ runner.run();
+ String error = runner.getFormatter().getError();
+ // might be FAILURES or ERRORS depending on JUnit version?
+ assertTrue(error, runner.getRetCode() != JUnitTestRunner.SUCCESS);
+ }
+
+ // check that having no suite generates no errors
+ @Test
+ public void testNoSuite(){
+ TestRunner runner = createRunner(NoSuiteTestCase.class);
+ runner.run();
+ assertEquals(runner.getFormatter().getError(), JUnitTestRunner.SUCCESS, runner.getRetCode());
+ }
+
+ // check that a suite generates no errors
+ @Test
+ public void testSuite(){
+ TestRunner runner = createRunner(SuiteTestCase.class);
+ runner.run();
+ assertEquals(runner.getFormatter().getError(), JUnitTestRunner.SUCCESS, runner.getRetCode());
+ }
+
+ // check that an invalid suite generates an error.
+ @Test
+ public void testInvalidSuite(){
+ TestRunner runner = createRunner(InvalidSuiteTestCase.class);
+ runner.run();
+ String error = runner.getFormatter().getError();
+ assertEquals(error, JUnitTestRunner.ERRORS, runner.getRetCode());
+ assertTrue(error, error.indexOf("thrown on purpose") != -1);
+ }
+
+ // check that something which is not a testcase generates no errors
+ // at first even though this is incorrect.
+ @Test
+ public void testNoTestCase(){
+ TestRunner runner = createRunner(NoTestCase.class);
+ runner.run();
+ // On junit3 this is a FAILURE, on junit4 this is an ERROR
+ int ret = runner.getRetCode();
+
+ if (ret != JUnitTestRunner.FAILURES && ret != JUnitTestRunner.ERRORS) {
+ fail("Unexpected result " + ret + " from junit runner");
+ }
+ // JUnit3 test
+ //assertEquals(runner.getFormatter().getError(), JUnitTestRunner.FAILURES, runner.getRetCode());
+ }
+
+ // check that an exception in the constructor is noticed
+ @Test
+ public void testInvalidTestCase(){
+ TestRunner runner = createRunner(InvalidTestCase.class);
+ runner.run();
+ // On junit3 this is a FAILURE, on junit4 this is an ERROR
+ int ret = runner.getRetCode();
+ if (ret != JUnitTestRunner.FAILURES && ret != JUnitTestRunner.ERRORS) {
+ fail("Unexpected result " + ret + " from junit runner");
+ }
+ // JUNIT3 test
+ //assertEquals(error, JUnitTestRunner.FAILURES, runner.getRetCode());
+ //@fixme as of now does not report the original stacktrace.
+ //assertTrue(error, error.indexOf("thrown on purpose") != -1);
+ }
+
+ protected TestRunner createRunner(Class<?> clazz){
+ return new TestRunner(new JUnitTest(clazz.getName()), null,
+ true, true, true);
+ }
+
+ protected TestRunner createRunnerForTestMethod(Class<?> clazz, String method){
+ return new TestRunner(new JUnitTest(clazz.getName()), new String[] {method},
+ true, true, true);
+ }
+
+ // the test runner that wrap the dummy formatter that interests us
+ private final static class TestRunner extends JUnitTestRunner {
+ private ResultFormatter formatter = new ResultFormatter();
+ TestRunner(JUnitTest test, String[] methods, boolean haltonerror,
+ boolean filtertrace, boolean haltonfailure){
+ super(test, methods, haltonerror, filtertrace, haltonfailure,
+ false, false, TestRunner.class.getClassLoader());
+ // use the classloader that loaded this class otherwise
+ // it will not be able to run inner classes if this test
+ // is ran in non-forked mode.
+ addFormatter(formatter);
+ }
+ ResultFormatter getFormatter(){
+ return formatter;
+ }
+ }
+
+ // dummy formatter just to catch the error
+ private final static class ResultFormatter implements JUnitResultFormatter {
+ private Throwable error;
+ public void setSystemOutput(String output){}
+ public void setSystemError(String output){}
+ public void startTestSuite(JUnitTest suite) throws BuildException{}
+ public void endTestSuite(JUnitTest suite) throws BuildException{}
+ public void setOutput(java.io.OutputStream out){}
+ public void startTest(junit.framework.Test t) {}
+ public void endTest(junit.framework.Test test) {}
+ public void addFailure(junit.framework.Test test, AssertionFailedError t) { }
+ public void addError(junit.framework.Test test, Throwable t) {
+ error = t;
+ }
+ String getError(){
+ if (error == null){
+ return "";
+ }
+ StringWriter sw = new StringWriter();
+ error.printStackTrace(new PrintWriter(sw));
+ return sw.toString();
+ }
+ }
+
+ public static class NoTestCase {
+ }
+
+ public static class InvalidMethodTestCase extends TestCase {
+ public InvalidMethodTestCase(String name){ super(name); }
+ public void testA(){
+ throw new NullPointerException("thrown on purpose");
+ }
+ }
+
+ public static class ValidMethodTestCase extends TestCase {
+ public ValidMethodTestCase(String name){ super(name); }
+ public void testA(){
+ // expected to be executed
+ }
+ public void testB(){
+ // should not be executed
+ throw new NullPointerException("thrown on purpose");
+ }
+ }
+
+ public static class InvalidTestCase extends TestCase {
+ public InvalidTestCase(String name){
+ super(name);
+ throw new NullPointerException("thrown on purpose");
+ }
+ }
+
+ public static class NoSuiteTestCase extends TestCase {
+ public NoSuiteTestCase(String name){ super(name); }
+ public void testA(){}
+ }
+
+ public static class SuiteTestCase extends NoSuiteTestCase {
+ public SuiteTestCase(String name){ super(name); }
+ public static junit.framework.Test suite(){
+ return new TestSuite(SuiteTestCase.class);
+ }
+ }
+
+ public static class InvalidSuiteTestCase extends NoSuiteTestCase {
+ public InvalidSuiteTestCase(String name){ super(name); }
+ public static junit.framework.Test suite(){
+ throw new NullPointerException("thrown on purpose");
+ }
+ }
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/JUnitVersionHelperTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/JUnitVersionHelperTest.java
new file mode 100644
index 00000000..8af3d23c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/JUnitVersionHelperTest.java
@@ -0,0 +1,102 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.junit;
+
+import static org.junit.Assert.assertEquals;
+import junit.framework.JUnit4TestAdapterCache;
+import junit.framework.TestCase;
+import junit.framework.TestResult;
+
+import org.junit.Test;
+import org.junit.runner.Description;
+
+/**
+ */
+public class JUnitVersionHelperTest {
+
+ @Test
+ public void testMyOwnName() {
+ assertEquals("testMyOwnName",
+ JUnitVersionHelper.getTestCaseName(
+ JUnit4TestAdapterCache.getDefault().asTest(
+ Description.createTestDescription(JUnitVersionHelperTest.class, "testMyOwnName")
+ )
+ )
+ );
+ }
+
+ @Test
+ public void testNonTestCaseName() {
+ assertEquals("I'm a foo",
+ JUnitVersionHelper.getTestCaseName(new Foo1()));
+ }
+
+ @Test
+ public void testNoStringReturn() {
+ assertEquals("unknown",
+ JUnitVersionHelper.getTestCaseName(new Foo2()));
+ }
+
+ @Test
+ public void testNoGetName() {
+ assertEquals("unknown",
+ JUnitVersionHelper.getTestCaseName(new Foo3()));
+ }
+
+ @Test
+ public void testNameNotGetName() {
+ assertEquals("I'm a foo, too",
+ JUnitVersionHelper.getTestCaseName(new Foo4()));
+ }
+
+ @Test
+ public void testNull() {
+ assertEquals("unknown", JUnitVersionHelper.getTestCaseName(null));
+ }
+
+ @Test
+ public void testTestCaseSubClass() {
+ assertEquals("overridden getName",
+ JUnitVersionHelper.getTestCaseName(new Foo5()));
+ }
+
+ public static class Foo implements junit.framework.Test {
+ public int countTestCases() {return 0;}
+ public void run(TestResult result) {}
+ }
+
+ public static class Foo1 extends Foo {
+ public String getName() {return "I'm a foo";}
+ }
+
+ public static class Foo2 extends Foo {
+ public int getName() {return 1;}
+ }
+
+ public static class Foo3 extends Foo {
+ }
+
+ public static class Foo4 extends Foo {
+ public String name() {return "I'm a foo, too";}
+ }
+
+ public static class Foo5 extends TestCase {
+ public String getName() {return "overridden getName";}
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/NoVmCrash.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/NoVmCrash.java
new file mode 100644
index 00000000..392a92ee
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/NoVmCrash.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.junit;
+
+import org.junit.Test;
+
+/**
+ */
+public class NoVmCrash {
+
+ @Test
+ public void testNoCrash() {
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/Printer.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/Printer.java
new file mode 100644
index 00000000..0200648d
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/Printer.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.junit;
+
+import org.junit.Test;
+
+/**
+ */
+public class Printer {
+
+ public Printer() {
+ System.err.println("constructor print to System.err");
+ System.out.println("constructor print to System.out");
+ }
+
+ static {
+ System.err.println("static print to System.err");
+ System.out.println("static print to System.out");
+ }
+
+ @Test
+ public void testNoCrash() {
+ System.err.println("method print to System.err");
+ System.out.println("method print to System.out");
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/Sleeper.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/Sleeper.java
new file mode 100644
index 00000000..15098948
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/Sleeper.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.junit;
+
+
+import org.junit.Test;
+
+public class Sleeper {
+
+ @Test
+ public void testSleep() throws InterruptedException {
+ Thread.sleep(5 * 1000);
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/SuiteMethodTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/SuiteMethodTest.java
new file mode 100644
index 00000000..14a09661
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/SuiteMethodTest.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.junit;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+
+/**
+ * validates that the suite() method works in classes that don't
+ * implement Test.
+ */
+public class SuiteMethodTest {
+
+ public static Test suite() {
+ return new Nested("testMethod");
+ }
+
+ public static class Nested extends TestCase {
+ public Nested(String name) {
+ super(name);
+ }
+
+ public void testMethod() {
+ assertTrue(true);
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/TearDownOnVmCrashTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/TearDownOnVmCrashTest.java
new file mode 100644
index 00000000..9908eeea
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/TearDownOnVmCrashTest.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.junit;
+
+import static org.apache.tools.ant.AntAssert.assertContains;
+import static org.apache.tools.ant.AntAssert.assertNotContains;
+import static org.junit.Assert.assertEquals;
+
+import org.apache.tools.ant.BuildFileRule;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+public class TearDownOnVmCrashTest {
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/optional/junit/teardownlistener.xml");
+ }
+
+ @Test
+ public void testNoTeardown() {
+ buildRule.executeTarget("testNoTeardown");
+ assertEquals("true", buildRule.getProject().getProperty("error"));
+ assertNotContains("tearDown called on Timeout", buildRule.getOutput());
+ }
+
+ @Test
+ public void testTeardown() {
+ buildRule.executeTarget("testTeardown");
+ assertEquals("true", buildRule.getProject().getProperty("error"));
+ assertContains("tearDown called on Timeout", buildRule.getOutput());
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/TestFormatter.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/TestFormatter.java
new file mode 100644
index 00000000..27420d6f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/TestFormatter.java
@@ -0,0 +1,112 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.junit;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import junit.framework.AssertionFailedError;
+import junit.framework.Test;
+
+import org.apache.tools.ant.BuildException;
+
+public class TestFormatter implements JUnitResultFormatter {
+
+ private static final byte[] grafitto = new byte[] {
+ (byte) 'T', (byte) 'e', (byte) 's', (byte) 't', (byte) 'F', (byte) 'o',
+ (byte) 'r', (byte) 'm', (byte) 'a', (byte) 't', (byte) 't', (byte) 'e',
+ (byte) 'r', (byte) ' ', (byte) 'w', (byte) 'a', (byte) 's', (byte) ' ',
+ (byte) 'h', (byte) 'e', (byte) 'r', (byte) 'e', 10
+ };
+
+ /**
+ * Where to write the log to.
+ */
+ private OutputStream out;
+
+ /**
+ * Empty
+ */
+ public TestFormatter() {
+ }
+
+ /**
+ * Empty
+ */
+ public void startTestSuite(JUnitTest suite) {
+ }
+ /**
+ * Empty
+ */
+ public void startTest(Test t) {
+ }
+ /**
+ * Empty
+ */
+ public void endTest(Test test) {
+ }
+ /**
+ * Empty
+ */
+ public void addFailure(Test test, Throwable t) {
+ }
+ /**
+ * Empty
+ */
+ public void addFailure(Test test, AssertionFailedError t) {
+ }
+ /**
+ * Empty
+ */
+ public void addError(Test test, Throwable t) {
+ }
+ /**
+ * Empty
+ */
+ public void setSystemOutput(String out) {
+ }
+ /**
+ * Empty
+ */
+ public void setSystemError(String err) {
+ }
+
+ public void setOutput(OutputStream out) {
+ this.out = out;
+ }
+
+ public void endTestSuite(JUnitTest suite) throws BuildException {
+ if (out != null) {
+ try {
+ out.write(grafitto);
+ out.flush();
+ } catch (IOException ioex) {
+ throw new BuildException("Unable to write output", ioex);
+ } finally {
+ if (out != System.out && out != System.err) {
+ try {
+ out.close();
+ } catch (IOException e) {
+ // ignore
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/VmCrash.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/VmCrash.java
new file mode 100644
index 00000000..92d21b68
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/VmCrash.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.junit;
+
+import org.junit.Test;
+
+/**
+ */
+public class VmCrash {
+
+ @Test
+ public void testCrash() {
+ System.exit(0);
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/XMLFormatterWithCDATAOnSystemOut.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/XMLFormatterWithCDATAOnSystemOut.java
new file mode 100644
index 00000000..3f464d87
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/XMLFormatterWithCDATAOnSystemOut.java
@@ -0,0 +1,83 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.junit;
+
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+
+import org.apache.tools.ant.BuildFileRule;
+import org.apache.tools.ant.util.FileUtils;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.assertTrue;
+
+public class XMLFormatterWithCDATAOnSystemOut {
+
+ private static final String DIR = "src/etc/testcases/taskdefs/optional/junit";
+ private static final String REPORT =
+ "TEST-" + XMLFormatterWithCDATAOnSystemOut.class.getName() + ".xml";
+
+ private static final String TESTDATA =
+ "<ERROR>" +
+ "<![CDATA[<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
+ " <RESPONSE>" +
+ " <GDS/>" +
+ " <ERROR>" +
+ " <ID/>" +
+ " <MESSAGE/>" +
+ " <REQUEST_TYPE/>" +
+ " <RESEND/>" +
+ " <RAW_RESPONSE/>" +
+ " </ERROR>" +
+ " </RESPONSE>" +
+ "]]>" +
+ "</ERROR>";
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ @Test
+ public void testOutput() {
+ System.out.println(TESTDATA);
+ }
+
+ @Test
+ public void testBuildfile() throws IOException {
+ buildRule.configureProject(DIR + "/cdataoutput.xml");
+ if (buildRule.getProject().getProperty("cdata.inner") == null) {
+ // avoid endless loop
+ buildRule.executeTarget("run-junit");
+ File f = buildRule.getProject().resolveFile(REPORT);
+ FileReader reader = null;
+ try {
+ reader = new FileReader(f);
+ String content = FileUtils.readFully(reader);
+ assertTrue(content.indexOf("</RESPONSE>&#x5d;&#x5d;&gt;"
+ + "</ERROR>") > 0);
+ } finally {
+ if (reader != null) {
+ reader.close();
+ }
+ f.delete();
+ }
+ }
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/XMLResultAggregatorTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/XMLResultAggregatorTest.java
new file mode 100644
index 00000000..da67fec8
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/XMLResultAggregatorTest.java
@@ -0,0 +1,93 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.junit;
+
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.PrintWriter;
+import java.security.Permission;
+
+import org.apache.tools.ant.DefaultLogger;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.Delete;
+import org.apache.tools.ant.types.FileSet;
+import org.junit.Assume;
+import org.junit.Test;
+
+public class XMLResultAggregatorTest {
+
+ @Test
+ public void testFrames() throws Exception {
+ // For now, skip this test on JDK 6 (and below); see below for why:
+ try {
+ Class.forName("java.nio.file.Files");
+ } catch (ClassNotFoundException x) {
+ Assume.assumeNoException("Skip test on JDK 6 and below", x);
+ }
+ final File d = new File(System.getProperty("java.io.tmpdir"), "XMLResultAggregatorTest");
+ if (d.exists()) {
+ new Delete() {{removeDir(d);}}; // is there no utility method for this?
+ }
+ assertTrue(d.getAbsolutePath(), d.mkdir());
+ File xml = new File(d, "x.xml");
+ PrintWriter pw = new PrintWriter(new FileOutputStream(xml));
+ try {
+ pw.println("<testsuite errors='0' failures='0' name='my.UnitTest' tests='1'>");
+ pw.println(" <testcase classname='my.UnitTest' name='testSomething'/>");
+ pw.println("</testsuite>");
+ pw.flush();
+ } finally {
+ pw.close();
+ }
+ XMLResultAggregator task = new XMLResultAggregator();
+ task.setTodir(d);
+ Project project = new Project();
+ DefaultLogger logger = new DefaultLogger();
+ logger.setOutputPrintStream(System.out);
+ logger.setErrorPrintStream(System.err);
+ logger.setMessageOutputLevel(Project.MSG_INFO);
+ project.addBuildListener(logger);
+ project.init();
+ task.setProject(project);
+ AggregateTransformer report = task.createReport();
+ report.setTodir(d);
+ FileSet fs = new FileSet();
+ fs.setFile(xml);
+ task.addFileSet(fs);
+ /* getResourceAsStream override unnecessary on JDK 7. Ought to work around JAXP #6723276 in JDK 6, but causes a TypeCheckError in FunctionCall for reasons TBD:
+ Thread.currentThread().setContextClassLoader(new ClassLoader(ClassLoader.getSystemClassLoader().getParent()) {
+ public InputStream getResourceAsStream(String name) {
+ if (name.startsWith("META-INF/services/")) {
+ return new ByteArrayInputStream(new byte[0]);
+ }
+ return super.getResourceAsStream(name);
+ }
+ });
+ */
+ // Use the JRE's Xerces, not lib/optional/xerces.jar:
+ Thread.currentThread().setContextClassLoader(ClassLoader.getSystemClassLoader().getParent());
+ // Tickle #51668:
+ System.setSecurityManager(new SecurityManager() {public void checkPermission(Permission perm) {}});
+ task.execute();
+ assertTrue(new File(d, "index.html").isFile());
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/net/FTPTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/net/FTPTest.java
new file mode 100644
index 00000000..1a22115e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/net/FTPTest.java
@@ -0,0 +1,879 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.net;
+
+import static org.apache.tools.ant.AntAssert.assertContains;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Random;
+import java.util.Vector;
+
+import org.apache.commons.net.ftp.FTPClient;
+import org.apache.tools.ant.BuildEvent;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.BuildFileRule;
+import org.apache.tools.ant.DefaultLogger;
+import org.apache.tools.ant.DirectoryScanner;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.condition.Os;
+import org.apache.tools.ant.types.FileSet;
+import org.apache.tools.ant.util.RetryHandler;
+import org.apache.tools.ant.util.Retryable;
+import org.apache.tools.ant.util.regexp.RegexpMatcher;
+import org.apache.tools.ant.util.regexp.RegexpMatcherFactory;
+import org.junit.After;
+import org.junit.Assume;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+//FIXME these tests are more integration than unit tests and report errors badly
+public class FTPTest {
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ // keep track of what operating systems are supported here.
+ private boolean supportsSymlinks = Os.isFamily("unix");
+
+ private FTPClient ftp;
+
+ private boolean loginSuceeded = false;
+
+ private String loginFailureMessage;
+
+ private String tmpDir = null;
+ private String remoteTmpDir = null;
+ private String ftpFileSep = null;
+ private myFTP myFTPTask = new myFTP();
+
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/optional/net/ftp.xml");
+ Project project = buildRule.getProject();
+ project.executeTarget("setup");
+ tmpDir = project.getProperty("tmp.dir");
+ ftp = new FTPClient();
+ ftpFileSep = project.getProperty("ftp.filesep");
+ myFTPTask.setSeparator(ftpFileSep);
+ myFTPTask.setProject(project);
+ remoteTmpDir = myFTPTask.resolveFile(tmpDir);
+ String remoteHost = project.getProperty("ftp.host");
+ int port = Integer.parseInt(project.getProperty("ftp.port"));
+ String remoteUser = project.getProperty("ftp.user");
+ String password = project.getProperty("ftp.password");
+ boolean connectionSucceeded = false;
+ try {
+ ftp.connect(remoteHost, port);
+ connectionSucceeded = true;
+ } catch (Exception ex) {
+ loginFailureMessage = "could not connect to host " + remoteHost + " on port " + port;
+ }
+ if (connectionSucceeded) {
+ try {
+ ftp.login(remoteUser, password);
+ loginSuceeded = true;
+ } catch (IOException ioe) {
+ loginFailureMessage = "could not log on to " + remoteHost + " as user " + remoteUser;
+ }
+ }
+ }
+
+ @After
+ public void tearDown() {
+ try {
+ if (ftp!= null) {
+ ftp.disconnect();
+ }
+ } catch (IOException ioe) {
+ // do nothing
+ }
+ buildRule.getProject().executeTarget("cleanup");
+ }
+
+ private boolean changeRemoteDir(String remoteDir) {
+ boolean result = true;
+ try {
+ ftp.cwd(remoteDir);
+ }
+ catch (Exception ex) {
+ System.out.println("could not change directory to " + remoteTmpDir);
+ result = false;
+ }
+ return result;
+ }
+
+ @Test
+ public void test1() {
+ Assume.assumeTrue(loginFailureMessage, loginSuceeded);
+ Assume.assumeTrue("Could not change remote directory", changeRemoteDir(remoteTmpDir));
+
+ FTP.FTPDirectoryScanner ds = myFTPTask.newScanner(ftp);
+ ds.setBasedir(new File(buildRule.getProject().getBaseDir(), "tmp"));
+ ds.setIncludes(new String[] {"alpha"});
+ ds.scan();
+ compareFiles(ds, new String[] {} ,new String[] {"alpha"});
+ }
+
+ @Test
+ public void test2() {
+ Assume.assumeTrue(loginFailureMessage, loginSuceeded);
+ Assume.assumeTrue("Could not change remote directory", changeRemoteDir(remoteTmpDir));
+ FTP.FTPDirectoryScanner ds = myFTPTask.newScanner(ftp);
+ ds.setBasedir(new File(buildRule.getProject().getBaseDir(), "tmp"));
+ ds.setIncludes(new String[] {"alpha/"});
+ ds.scan();
+ compareFiles(ds, new String[] {"alpha/beta/beta.xml",
+ "alpha/beta/gamma/gamma.xml"},
+ new String[] {"alpha", "alpha/beta", "alpha/beta/gamma"});
+ }
+
+ @Test
+ public void test3() {
+ Assume.assumeTrue(loginFailureMessage, loginSuceeded);
+ Assume.assumeTrue("Could not change remote directory", changeRemoteDir(remoteTmpDir));
+ FTP.FTPDirectoryScanner ds = myFTPTask.newScanner(ftp);
+ ds.setBasedir(new File(buildRule.getProject().getBaseDir(), "tmp"));
+ ds.scan();
+ compareFiles(ds, new String[] {"alpha/beta/beta.xml",
+ "alpha/beta/gamma/gamma.xml"},
+ new String[] {"alpha", "alpha/beta",
+ "alpha/beta/gamma"});
+ }
+
+ @Test
+ public void testFullPathMatchesCaseSensitive() {
+ Assume.assumeTrue(loginFailureMessage, loginSuceeded);
+ Assume.assumeTrue("Could not change remote directory", changeRemoteDir(remoteTmpDir));
+ FTP.FTPDirectoryScanner ds = myFTPTask.newScanner(ftp);
+ ds.setBasedir(new File(buildRule.getProject().getBaseDir(), "tmp"));
+ ds.setIncludes(new String[] {"alpha/beta/gamma/GAMMA.XML"});
+ ds.scan();
+ compareFiles(ds, new String[] {}, new String[] {});
+ }
+
+ @Test
+ public void testFullPathMatchesCaseInsensitive() {
+ Assume.assumeTrue(loginFailureMessage, loginSuceeded);
+ Assume.assumeTrue("Could not change remote directory", changeRemoteDir(remoteTmpDir));
+ FTP.FTPDirectoryScanner ds = myFTPTask.newScanner(ftp);
+ ds.setCaseSensitive(false);
+ ds.setBasedir(new File(buildRule.getProject().getBaseDir(), "tmp"));
+ ds.setIncludes(new String[] {"alpha/beta/gamma/GAMMA.XML"});
+ ds.scan();
+ compareFiles(ds, new String[] {"alpha/beta/gamma/gamma.xml"},
+ new String[] {});
+ }
+
+ @Test
+ public void test2ButCaseInsensitive() {
+ Assume.assumeTrue(loginFailureMessage, loginSuceeded);
+ Assume.assumeTrue("Could not change remote directory", changeRemoteDir(remoteTmpDir));
+ FTP.FTPDirectoryScanner ds = myFTPTask.newScanner(ftp);
+ ds.setBasedir(new File(buildRule.getProject().getBaseDir(), "tmp"));
+ ds.setIncludes(new String[] {"ALPHA/"});
+ ds.setCaseSensitive(false);
+ ds.scan();
+ compareFiles(ds, new String[] {"alpha/beta/beta.xml",
+ "alpha/beta/gamma/gamma.xml"},
+ new String[] {"alpha", "alpha/beta", "alpha/beta/gamma"});
+ }
+
+ @Test
+ public void test2bisButCaseInsensitive() {
+ Assume.assumeTrue(loginFailureMessage, loginSuceeded);
+ Assume.assumeTrue("Could not change remote directory", changeRemoteDir(remoteTmpDir));
+ FTP.FTPDirectoryScanner ds = myFTPTask.newScanner(ftp);
+ ds.setBasedir(new File(buildRule.getProject().getBaseDir(), "tmp"));
+ ds.setIncludes(new String[] {"alpha/BETA/gamma/"});
+ ds.setCaseSensitive(false);
+ ds.scan();
+ compareFiles(ds, new String[] {"alpha/beta/gamma/gamma.xml"},
+ new String[] {"alpha/beta/gamma"});
+ }
+
+ @Test
+ public void testGetWithSelector() {
+ buildRule.executeTarget("ftp-get-with-selector");
+ assertContains("selectors are not supported in remote filesets", buildRule.getLog());
+ FileSet fsDestination = (FileSet) buildRule.getProject().getReference("fileset-destination-without-selector");
+ DirectoryScanner dsDestination = fsDestination.getDirectoryScanner(buildRule.getProject());
+ dsDestination.scan();
+ String [] sortedDestinationDirectories = dsDestination.getIncludedDirectories();
+ String [] sortedDestinationFiles = dsDestination.getIncludedFiles();
+ for (int counter = 0; counter < sortedDestinationDirectories.length; counter++) {
+ sortedDestinationDirectories[counter] =
+ sortedDestinationDirectories[counter].replace(File.separatorChar, '/');
+ }
+ for (int counter = 0; counter < sortedDestinationFiles.length; counter++) {
+ sortedDestinationFiles[counter] =
+ sortedDestinationFiles[counter].replace(File.separatorChar, '/');
+ }
+ FileSet fsSource = (FileSet) buildRule.getProject().getReference("fileset-source-without-selector");
+ DirectoryScanner dsSource = fsSource.getDirectoryScanner(buildRule.getProject());
+ dsSource.scan();
+ compareFiles(dsSource, sortedDestinationFiles, sortedDestinationDirectories);
+ }
+
+ @Test
+ public void testGetFollowSymlinksTrue() {
+ Assume.assumeTrue("System does not support Symlinks", supportsSymlinks);
+ Assume.assumeTrue(loginFailureMessage, loginSuceeded);
+ Assume.assumeTrue("Could not change remote directory", changeRemoteDir(remoteTmpDir));
+ buildRule.getProject().executeTarget("ftp-get-directory-symbolic-link");
+ FileSet fsDestination = (FileSet) buildRule.getProject().getReference("fileset-destination-without-selector");
+ DirectoryScanner dsDestination = fsDestination.getDirectoryScanner(buildRule.getProject());
+ dsDestination.scan();
+ compareFiles(dsDestination, new String[] {"alpha/beta/gamma/gamma.xml"},
+ new String[] {"alpha", "alpha/beta", "alpha/beta/gamma"});
+ }
+
+ @Test
+ public void testGetFollowSymlinksFalse() {
+ Assume.assumeTrue("System does not support Symlinks", supportsSymlinks);
+ Assume.assumeTrue(loginFailureMessage, loginSuceeded);
+ Assume.assumeTrue("Could not change remote directory", changeRemoteDir(remoteTmpDir));
+ buildRule.getProject().executeTarget("ftp-get-directory-no-symbolic-link");
+ FileSet fsDestination = (FileSet) buildRule.getProject().getReference("fileset-destination-without-selector");
+ DirectoryScanner dsDestination = fsDestination.getDirectoryScanner(buildRule.getProject());
+ dsDestination.scan();
+ compareFiles(dsDestination, new String[] {},
+ new String[] {});
+ }
+
+ @Test
+ public void testAllowSymlinks() {
+ Assume.assumeTrue("System does not support Symlinks", supportsSymlinks);
+ Assume.assumeTrue(loginFailureMessage, loginSuceeded);
+ Assume.assumeTrue("Could not change remote directory", changeRemoteDir(remoteTmpDir));
+ buildRule.getProject().executeTarget("symlink-setup");
+ FTP.FTPDirectoryScanner ds = myFTPTask.newScanner(ftp);
+ ds.setBasedir(new File(buildRule.getProject().getBaseDir(), "tmp"));
+ ds.setIncludes(new String[] {"alpha/beta/gamma/"});
+ ds.setFollowSymlinks(true);
+ ds.scan();
+ compareFiles(ds, new String[] {"alpha/beta/gamma/gamma.xml"},
+ new String[] {"alpha/beta/gamma"});
+ }
+
+ @Test
+ public void testProhibitSymlinks() {
+ Assume.assumeTrue("System does not support Symlinks", supportsSymlinks);
+ Assume.assumeTrue(loginFailureMessage, loginSuceeded);
+ Assume.assumeTrue("Could not change remote directory", changeRemoteDir(remoteTmpDir));
+ buildRule.getProject().executeTarget("symlink-setup");
+ FTP.FTPDirectoryScanner ds = myFTPTask.newScanner(ftp);
+ ds.setBasedir(new File(buildRule.getProject().getBaseDir(), "tmp"));
+ ds.setIncludes(new String[] {"alpha/beta/gamma/"});
+ ds.setFollowSymlinks(false);
+ ds.scan();
+ compareFiles(ds, new String[] {}, new String[] {});
+ }
+
+ @Test
+ public void testFileSymlink() {
+ Assume.assumeTrue("System does not support Symlinks", supportsSymlinks);
+ Assume.assumeTrue(loginFailureMessage, loginSuceeded);
+ Assume.assumeTrue("Could not change remote directory", changeRemoteDir(remoteTmpDir));
+ buildRule.getProject().executeTarget("symlink-file-setup");
+ FTP.FTPDirectoryScanner ds = myFTPTask.newScanner(ftp);
+ ds.setBasedir(new File(buildRule.getProject().getBaseDir(), "tmp"));
+ ds.setIncludes(new String[] {"alpha/beta/gamma/"});
+ ds.setFollowSymlinks(true);
+ ds.scan();
+ compareFiles(ds, new String[] {"alpha/beta/gamma/gamma.xml"},
+ new String[] {"alpha/beta/gamma"});
+ }
+
+ // father and child pattern test
+ @Test
+ public void testOrderOfIncludePatternsIrrelevant() {
+ Assume.assumeTrue(loginFailureMessage, loginSuceeded);
+ Assume.assumeTrue("Could not change remote directory", changeRemoteDir(remoteTmpDir));
+ String [] expectedFiles = {"alpha/beta/beta.xml",
+ "alpha/beta/gamma/gamma.xml"};
+ String [] expectedDirectories = {"alpha/beta", "alpha/beta/gamma" };
+ FTP.FTPDirectoryScanner ds = myFTPTask.newScanner(ftp);
+ ds.setBasedir(new File(buildRule.getProject().getBaseDir(), "tmp"));
+ ds.setIncludes(new String[] {"alpha/be?a/**", "alpha/beta/gamma/"});
+ ds.scan();
+ compareFiles(ds, expectedFiles, expectedDirectories);
+ // redo the test, but the 2 include patterns are inverted
+ ds = myFTPTask.newScanner(ftp);
+ ds.setBasedir(new File(buildRule.getProject().getBaseDir(), "tmp"));
+ ds.setIncludes(new String[] {"alpha/beta/gamma/", "alpha/be?a/**"});
+ ds.scan();
+ compareFiles(ds, expectedFiles, expectedDirectories);
+ }
+
+ @Test
+ public void testPatternsDifferInCaseScanningSensitive() {
+ Assume.assumeTrue(loginFailureMessage, loginSuceeded);
+ Assume.assumeTrue("Could not change remote directory", changeRemoteDir(remoteTmpDir));
+ FTP.FTPDirectoryScanner ds = myFTPTask.newScanner(ftp);
+ ds.setBasedir(new File(buildRule.getProject().getBaseDir(), "tmp"));
+ ds.setIncludes(new String[] {"alpha/", "ALPHA/"});
+ ds.scan();
+ compareFiles(ds, new String[] {"alpha/beta/beta.xml",
+ "alpha/beta/gamma/gamma.xml"},
+ new String[] {"alpha", "alpha/beta", "alpha/beta/gamma"});
+ }
+
+ @Test
+ public void testPatternsDifferInCaseScanningInsensitive() {
+ Assume.assumeTrue(loginFailureMessage, loginSuceeded);
+ Assume.assumeTrue("Could not change remote directory", changeRemoteDir(remoteTmpDir));
+ FTP.FTPDirectoryScanner ds = myFTPTask.newScanner(ftp);
+ ds.setBasedir(new File(buildRule.getProject().getBaseDir(), "tmp"));
+ ds.setIncludes(new String[] {"alpha/", "ALPHA/"});
+ ds.setCaseSensitive(false);
+ ds.scan();
+ compareFiles(ds, new String[] {"alpha/beta/beta.xml",
+ "alpha/beta/gamma/gamma.xml"},
+ new String[] {"alpha", "alpha/beta", "alpha/beta/gamma"});
+ }
+
+ @Test
+ public void testFullpathDiffersInCaseScanningSensitive() {
+ Assume.assumeTrue(loginFailureMessage, loginSuceeded);
+ Assume.assumeTrue("Could not change remote directory", changeRemoteDir(remoteTmpDir));
+ FTP.FTPDirectoryScanner ds = myFTPTask.newScanner(ftp);
+ ds.setBasedir(new File(buildRule.getProject().getBaseDir(), "tmp"));
+ ds.setIncludes(new String[] {
+ "alpha/beta/gamma/gamma.xml",
+ "alpha/beta/gamma/GAMMA.XML"
+ });
+ ds.scan();
+ compareFiles(ds, new String[] {"alpha/beta/gamma/gamma.xml"},
+ new String[] {});
+ }
+
+ @Test
+ public void testFullpathDiffersInCaseScanningInsensitive() {
+ Assume.assumeTrue(loginFailureMessage, loginSuceeded);
+ Assume.assumeTrue("Could not change remote directory", changeRemoteDir(remoteTmpDir));
+ FTP.FTPDirectoryScanner ds = myFTPTask.newScanner(ftp);
+ ds.setBasedir(new File(buildRule.getProject().getBaseDir(), "tmp"));
+ ds.setIncludes(new String[] {
+ "alpha/beta/gamma/gamma.xml",
+ "alpha/beta/gamma/GAMMA.XML"
+ });
+ ds.setCaseSensitive(false);
+ ds.scan();
+ compareFiles(ds, new String[] {"alpha/beta/gamma/gamma.xml"},
+ new String[] {});
+ }
+
+ @Test
+ public void testParentDiffersInCaseScanningSensitive() {
+ Assume.assumeTrue(loginFailureMessage, loginSuceeded);
+ Assume.assumeTrue("Could not change remote directory", changeRemoteDir(remoteTmpDir));
+ FTP.FTPDirectoryScanner ds = myFTPTask.newScanner(ftp);
+ ds.setBasedir(new File(buildRule.getProject().getBaseDir(), "tmp"));
+ ds.setIncludes(new String[] {"alpha/", "ALPHA/beta/"});
+ ds.scan();
+ compareFiles(ds, new String[] {"alpha/beta/beta.xml",
+ "alpha/beta/gamma/gamma.xml"},
+ new String[] {"alpha", "alpha/beta", "alpha/beta/gamma"});
+ }
+
+ @Test
+ public void testParentDiffersInCaseScanningInsensitive() {
+ Assume.assumeTrue(loginFailureMessage, loginSuceeded);
+ Assume.assumeTrue("Could not change remote directory", changeRemoteDir(remoteTmpDir));
+ FTP.FTPDirectoryScanner ds = myFTPTask.newScanner(ftp);
+ ds.setBasedir(new File(buildRule.getProject().getBaseDir(), "tmp"));
+ ds.setIncludes(new String[] {"alpha/", "ALPHA/beta/"});
+ ds.setCaseSensitive(false);
+ ds.scan();
+ compareFiles(ds, new String[] {"alpha/beta/beta.xml",
+ "alpha/beta/gamma/gamma.xml"},
+ new String[] {"alpha", "alpha/beta", "alpha/beta/gamma"});
+ }
+
+ @Test
+ public void testExcludeOneFile() {
+ Assume.assumeTrue(loginFailureMessage, loginSuceeded);
+ Assume.assumeTrue("Could not change remote directory", changeRemoteDir(remoteTmpDir));
+ FTP.FTPDirectoryScanner ds = myFTPTask.newScanner(ftp);
+ ds.setBasedir(new File(buildRule.getProject().getBaseDir(), "tmp"));
+ ds.setIncludes(new String[] {
+ "**/*.xml"
+ });
+ ds.setExcludes(new String[] {
+ "alpha/beta/b*xml"
+ });
+ ds.scan();
+ compareFiles(ds, new String[] {"alpha/beta/gamma/gamma.xml"},
+ new String[] {});
+ }
+
+ @Test
+ public void testExcludeHasPrecedence() {
+ Assume.assumeTrue(loginFailureMessage, loginSuceeded);
+ Assume.assumeTrue("Could not change remote directory", changeRemoteDir(remoteTmpDir));
+ FTP.FTPDirectoryScanner ds = myFTPTask.newScanner(ftp);
+ ds.setBasedir(new File(buildRule.getProject().getBaseDir(), "tmp"));
+ ds.setIncludes(new String[] {
+ "alpha/**"
+ });
+ ds.setExcludes(new String[] {
+ "alpha/**"
+ });
+ ds.scan();
+ compareFiles(ds, new String[] {},
+ new String[] {});
+
+ }
+
+ @Test
+ public void testAlternateIncludeExclude() {
+ Assume.assumeTrue(loginFailureMessage, loginSuceeded);
+ Assume.assumeTrue("Could not change remote directory", changeRemoteDir(remoteTmpDir));
+ FTP.FTPDirectoryScanner ds = myFTPTask.newScanner(ftp);
+ ds.setBasedir(new File(buildRule.getProject().getBaseDir(), "tmp"));
+ ds.setIncludes(new String[] {
+ "alpha/**",
+ "alpha/beta/gamma/**"
+ });
+ ds.setExcludes(new String[] {
+ "alpha/beta/**"
+ });
+ ds.scan();
+ compareFiles(ds, new String[] {},
+ new String[] {"alpha"});
+
+ }
+
+ @Test
+ public void testAlternateExcludeInclude() {
+ Assume.assumeTrue(loginFailureMessage, loginSuceeded);
+ Assume.assumeTrue("Could not change remote directory", changeRemoteDir(remoteTmpDir));
+ FTP.FTPDirectoryScanner ds = myFTPTask.newScanner(ftp);
+ ds.setBasedir(new File(buildRule.getProject().getBaseDir(), "tmp"));
+ ds.setExcludes(new String[] {
+ "alpha/**",
+ "alpha/beta/gamma/**"
+ });
+ ds.setIncludes(new String[] {
+ "alpha/beta/**"
+ });
+ ds.scan();
+ compareFiles(ds, new String[] {},
+ new String[] {});
+
+ }
+
+ /**
+ * Test inspired by Bug#1415.
+ */
+ @Test
+ public void testChildrenOfExcludedDirectory() {
+ Assume.assumeTrue(loginFailureMessage, loginSuceeded);
+ Assume.assumeTrue("Could not change remote directory", changeRemoteDir(remoteTmpDir));
+ buildRule.getProject().executeTarget("children-of-excluded-dir-setup");
+ FTP.FTPDirectoryScanner ds = myFTPTask.newScanner(ftp);
+ ds.setBasedir(new File(buildRule.getProject().getBaseDir(), "tmp"));
+ ds.setExcludes(new String[] {"alpha/**"});
+ ds.scan();
+ compareFiles(ds, new String[] {"delta/delta.xml"},
+ new String[] {"delta"});
+
+ ds = myFTPTask.newScanner(ftp);
+ Assume.assumeTrue("Could not change remote directory", changeRemoteDir(remoteTmpDir));
+ ds.setBasedir(new File(buildRule.getProject().getBaseDir(), "tmp"));
+ ds.setExcludes(new String[] {"alpha"});
+ ds.scan();
+ compareFiles(ds, new String[] {"alpha/beta/beta.xml",
+ "alpha/beta/gamma/gamma.xml",
+ "delta/delta.xml"},
+ new String[] {"alpha/beta", "alpha/beta/gamma", "delta"});
+
+ }
+
+ /**
+ * This class enables the use of the log messages as a way of testing
+ * the number of files actually transferred.
+ * It uses the ant regular expression mechanism to get a regex parser
+ * to parse the log output.
+ */
+ private class CountLogListener extends DefaultLogger {
+ private Vector lastMatchGroups = null;
+ private RegexpMatcher matcher = new RegexpMatcherFactory().newRegexpMatcher();
+
+ /**
+ * The only constructor for a CountLogListener
+ * @param pattern a regular expression pattern. It should have
+ * one parenthesized group and that group should contain the
+ * number desired.
+ */
+ public CountLogListener(String pattern) {
+ super();
+ this.matcher.setPattern(pattern);
+ }
+
+
+ /*
+ * @param event the build event that is being logged.
+ */
+ public void messageLogged(BuildEvent event) {
+ String message = event.getMessage();
+ if (this.matcher.matches(message)) {
+ lastMatchGroups = this.matcher.getGroups(message);
+ }
+ super.messageLogged(event);
+ }
+
+ /**
+ * returns the desired number that results from parsing the log
+ * message
+ * @return the number of files indicated in the desired message or -1
+ * if a matching log message was never found.
+ */
+ public int getCount() {
+ if (this.lastMatchGroups == null) {
+ return -1;
+ }
+ return Integer.parseInt((String) this.lastMatchGroups.get(1));
+ }
+ }
+
+ /**
+ * This class enables the use of the log to count the number
+ * of times a message has been emitted.
+ */
+ private class LogCounter extends DefaultLogger {
+ private Map searchMap = new HashMap();
+ private int matchCount;
+
+ public void addLogMessageToSearch(String message) {
+ searchMap.put(message, new Integer(0));
+ }
+
+ /*
+ * @param event the build event that is being logged.
+ */
+ public void messageLogged(BuildEvent event) {
+ String message = event.getMessage();
+ Integer mcnt = (Integer) searchMap.get(message);
+ if (null != mcnt) {
+ searchMap.put(message, new Integer(mcnt.intValue() + 1));
+ }
+ super.messageLogged(event);
+ }
+
+ /**
+ * @return the number of times that the looked for message was sent
+ * to the log
+ */
+ public int getMatchCount(String message) {
+ Integer mcnt = (Integer) searchMap.get(message);
+ if (null != mcnt) {
+ return mcnt.intValue();
+ }
+ return 0;
+ }
+ }
+ /**
+ * Tests the combination of the newer parameter and the
+ * serverTimezoneConfig parameter in the PUT action. The default
+ * configuration is an ftp server on localhost which formats
+ * timestamps as GMT.
+ */
+ @Test
+ public void testTimezonePut() {
+ CountLogListener log = new CountLogListener("(\\d+) files? sent");
+ buildRule.getProject().executeTarget("timed.test.setup");
+ buildRule.getProject().addBuildListener(log);
+ buildRule.getProject().executeTarget("timed.test.put.older");
+ assertEquals(1, log.getCount());
+ }
+
+ /**
+ * Tests the combination of the newer parameter and the
+ * serverTimezoneConfig parameter in the GET action. The default
+ * configuration is an ftp server on localhost which formats
+ * timestamps as GMT.
+ */
+ @Test
+ public void testTimezoneGet() {
+ CountLogListener log = new CountLogListener("(\\d+) files? retrieved");
+ buildRule.getProject().executeTarget("timed.test.setup");
+ buildRule.getProject().addBuildListener(log);
+ buildRule.getProject().executeTarget("timed.test.get.older");
+ assertEquals(3, log.getCount());
+ }
+
+
+ /**
+ * Tests that the presence of one of the server config params forces
+ * the system type to Unix if not specified.
+ */
+ @Test
+ public void testConfiguration1() {
+ int[] expectedCounts = {
+ 1,1,0,1,0,0,0
+ };
+ performConfigTest("configuration.1", expectedCounts);
+
+ }
+
+ /**
+ * Tests the systemTypeKey attribute.
+ */
+ @Test
+ public void testConfiguration2() {
+ int[] expectedCounts = {
+ 1,0,0,1,1,0,0
+ };
+ performConfigTest("configuration.2", expectedCounts);
+
+ }
+
+ /**
+ * Tests the systemTypeKey attribute with UNIX specified.
+ */
+ @Test
+ public void testConfiguration3() {
+ int[] expectedCounts = {
+ 1,0,1,0,0,1,0
+ };
+ performConfigTest("configuration.3", expectedCounts);
+
+ }
+
+ @Test
+ public void testConfigurationLang() {
+ int[] expectedCounts = {
+ 1,1,0,0,0,0,1
+ };
+ performConfigTest("configuration.lang.good", expectedCounts);
+
+ try {
+ performConfigTest("configuration.lang.bad", expectedCounts);
+ fail("BuildException Expected");
+ } catch (Exception bx) {
+ assertTrue(bx instanceof BuildException);
+ }
+ }
+ /**
+ * Tests the systemTypeKey attribute.
+ */
+ @Test
+ public void testConfigurationNone() {
+ int[] expectedCounts = {
+ 0,0,0,0,0,0,0
+ };
+ performConfigTest("configuration.none", expectedCounts);
+
+ }
+
+ private void performConfigTest(String target, int[] expectedCounts) {
+ String[] messages = new String[]{
+ "custom configuration",
+ "custom config: system key = default (UNIX)",
+ "custom config: system key = UNIX",
+ "custom config: server time zone ID = " + buildRule.getProject().getProperty("ftp.server.timezone"),
+ "custom config: system key = WINDOWS",
+ "custom config: default date format = yyyy/MM/dd HH:mm",
+ "custom config: server language code = de"
+
+ };
+ LogCounter counter = new LogCounter();
+ for (int i=0; i < messages.length; i++) {
+ counter.addLogMessageToSearch(messages[i]);
+ }
+
+ buildRule.getProject().addBuildListener(counter);
+ buildRule.getProject().executeTarget(target);
+ for (int i=0; i < messages.length; i++) {
+ assertEquals("target "+target+":message "+ i, expectedCounts[i], counter.getMatchCount(messages[i]));
+ }
+
+ }
+
+
+ /**
+ * this test is inspired by a user reporting that deletions of directories with the ftp task do not work
+ */
+ @Test
+ public void testFTPDelete() {
+ buildRule.getProject().executeTarget("ftp-delete");
+ }
+
+ private void compareFiles(DirectoryScanner ds, String[] expectedFiles,
+ String[] expectedDirectories) {
+ String includedFiles[] = ds.getIncludedFiles();
+ String includedDirectories[] = ds.getIncludedDirectories();
+ assertEquals("file present: ", expectedFiles.length,
+ includedFiles.length);
+ assertEquals("directories present: ", expectedDirectories.length,
+ includedDirectories.length);
+
+ for (int counter=0; counter < includedFiles.length; counter++) {
+ includedFiles[counter] = includedFiles[counter].replace(File.separatorChar, '/');
+ }
+ Arrays.sort(includedFiles);
+ for (int counter=0; counter < includedDirectories.length; counter++) {
+ includedDirectories[counter] = includedDirectories[counter]
+ .replace(File.separatorChar, '/');
+ }
+ Arrays.sort(includedDirectories);
+ for (int counter=0; counter < includedFiles.length; counter++) {
+ assertEquals(expectedFiles[counter], includedFiles[counter]);
+ }
+ for (int counter=0; counter < includedDirectories.length; counter++) {
+ assertEquals(expectedDirectories[counter], includedDirectories[counter]);
+ counter++;
+ }
+ }
+ private static class myFTP extends FTP {
+ public FTP.FTPDirectoryScanner newScanner(FTPClient client) {
+ return new FTP.FTPDirectoryScanner(client);
+ }
+ // provide public visibility
+ public String resolveFile(String file) {
+ return super.resolveFile(file);
+ }
+ }
+
+
+ public abstract static class myRetryableFTP extends FTP {
+ private final int numberOfFailuresToSimulate;
+ private int simulatedFailuresLeft;
+
+ protected myRetryableFTP(int numberOfFailuresToSimulate) {
+ this.numberOfFailuresToSimulate = numberOfFailuresToSimulate;
+ this.simulatedFailuresLeft = numberOfFailuresToSimulate;
+ }
+
+ protected void getFile(FTPClient ftp, String dir, String filename)
+ throws IOException, BuildException
+ {
+ if (this.simulatedFailuresLeft > 0) {
+ this.simulatedFailuresLeft--;
+ throw new IOException("Simulated failure for testing");
+ }
+ super.getFile(ftp, dir, filename);
+ }
+ protected void executeRetryable(RetryHandler h, Retryable r,
+ String filename) throws IOException
+ {
+ this.simulatedFailuresLeft = this.numberOfFailuresToSimulate;
+ super.executeRetryable(h, r, filename);
+ }
+ }
+ public static class oneFailureFTP extends myRetryableFTP {
+ public oneFailureFTP() {
+ super(1);
+ }
+ }
+ public static class twoFailureFTP extends myRetryableFTP {
+ public twoFailureFTP() {
+ super(2);
+ }
+ }
+ public static class threeFailureFTP extends myRetryableFTP {
+ public threeFailureFTP() {
+ super(3);
+ }
+ }
+
+ public static class randomFailureFTP extends myRetryableFTP {
+ public randomFailureFTP() {
+ super(new Random().nextInt(Short.MAX_VALUE));
+ }
+ }
+ public void testGetWithSelectorRetryable1() {
+ buildRule.getProject().addTaskDefinition("ftp", oneFailureFTP.class);
+ try {
+ buildRule.getProject().executeTarget("ftp-get-with-selector-retryable");
+ } catch (BuildException bx) {
+ fail("Two retries expected, failed after one.");
+ }
+ }
+
+ @Test
+ public void testGetWithSelectorRetryable2() {
+ buildRule.getProject().addTaskDefinition("ftp", twoFailureFTP.class);
+ try {
+ buildRule.getProject().executeTarget("ftp-get-with-selector-retryable");
+ } catch (BuildException bx) {
+ fail("Two retries expected, failed after two.");
+ }
+ }
+
+ @Test
+ public void testGetWithSelectorRetryable3() {
+ buildRule.getProject().addTaskDefinition("ftp", threeFailureFTP.class);
+ try {
+ buildRule.getProject().executeTarget("ftp-get-with-selector-retryable");
+ fail("Two retries expected, continued after two.");
+ } catch (BuildException bx) {
+ }
+ }
+
+ @Test
+ public void testGetWithSelectorRetryableRandom() {
+ buildRule.getProject().addTaskDefinition("ftp", randomFailureFTP.class);
+ try {
+ buildRule.getProject().setProperty("ftp.retries", "forever");
+ buildRule.getProject().executeTarget("ftp-get-with-selector-retryable");
+ } catch (BuildException bx) {
+ fail("Retry forever specified, but failed.");
+ }
+ }
+
+ @Test
+ public void testInitialCommand() {
+ performCommandTest("test-initial-command", new int[] { 1,0 });
+ }
+
+ @Test
+ public void testSiteAction() {
+ performCommandTest("test-site-action", new int[] { 1,0 });
+ }
+
+ private void performCommandTest(String target, int[] expectedCounts) {
+ String[] messages = new String[]{
+ "Doing Site Command: umask 222",
+ "Failed to issue Site Command: umask 222",
+
+ };
+ LogCounter counter = new LogCounter();
+ for (int i=0; i < messages.length; i++) {
+ counter.addLogMessageToSearch(messages[i]);
+ }
+
+ buildRule.getProject().addBuildListener(counter);
+ buildRule.getProject().executeTarget(target);
+ for (int i=0; i < messages.length; i++) {
+ assertEquals("target "+target+":message "+ i, expectedCounts[i], counter.getMatchCount(messages[i]));
+ }
+
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/script/ScriptDefTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/script/ScriptDefTest.java
new file mode 100644
index 00000000..5d4d4cf6
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/script/ScriptDefTest.java
@@ -0,0 +1,146 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.script;
+
+import org.apache.tools.ant.AntAssert;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.BuildFileRule;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.FileSet;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import java.io.File;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+/**
+ * Tests the examples of the &lt;scriptdef&gt; task.
+ *
+ * @since Ant 1.6
+ */
+public class ScriptDefTest {
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/optional/script/scriptdef.xml");
+ }
+
+ @Test
+ public void testSimple() {
+ buildRule.executeTarget("simple");
+ // get the fileset and its basedir
+ Project p = buildRule.getProject();
+ FileSet fileset = (FileSet) p.getReference("testfileset");
+ File baseDir = fileset.getDir(p);
+ String log = buildRule.getLog();
+ assertTrue("Expecting attribute value printed",
+ log.indexOf("Attribute attr1 = test") != -1);
+
+ assertTrue("Expecting nested element value printed",
+ log.indexOf("Fileset basedir = " + baseDir.getAbsolutePath()) != -1);
+ }
+
+ @Test
+ public void testNoLang() {
+ try {
+ buildRule.executeTarget("nolang");
+ fail("Absence of language attribute not detected");
+ } catch(BuildException ex) {
+ AntAssert.assertContains("requires a language attribute", ex.getMessage());
+ }
+ }
+
+ @Test
+ public void testNoName() {
+ try {
+ buildRule.executeTarget("noname");
+ fail("Absence of name attribute not detected");
+ } catch(BuildException ex) {
+ AntAssert.assertContains("scriptdef requires a name attribute", ex.getMessage());
+ }
+ }
+
+ @Test
+ public void testNestedByClassName() {
+ buildRule.executeTarget("nestedbyclassname");
+ // get the fileset and its basedir
+ Project p = buildRule.getProject();
+ FileSet fileset = (FileSet) p.getReference("testfileset");
+ File baseDir = fileset.getDir(p);
+ String log = buildRule.getLog();
+ assertTrue("Expecting attribute value to be printed",
+ log.indexOf("Attribute attr1 = test") != -1);
+
+ assertTrue("Expecting nested element value to be printed",
+ log.indexOf("Fileset basedir = " + baseDir.getAbsolutePath()) != -1);
+ }
+
+ @Test
+ public void testNoElement() {
+ buildRule.executeTarget("noelement");
+ assertEquals("Attribute attr1 = test", buildRule.getOutput().trim());
+ }
+
+ @Test
+ public void testException() {
+ try {
+ buildRule.executeTarget("exception");
+ fail("Should have thrown an exception in the script");
+ } catch(BuildException ex) {
+ AntAssert.assertContains("TypeError", ex.getMessage());
+ }
+ }
+
+ @Test
+ public void testDoubleDef() {
+ buildRule.executeTarget("doubledef");
+ String log = buildRule.getLog();
+ assertTrue("Task1 did not execute",
+ log.indexOf("Task1") != -1);
+ assertTrue("Task2 did not execute",
+ log.indexOf("Task2") != -1);
+ }
+
+ @Test
+ public void testDoubleAttribute() {
+ try {
+ buildRule.executeTarget("doubleAttributeDef");
+ fail("Should have detected duplicate attirbute definition");
+ } catch(BuildException ex) {
+ AntAssert.assertContains("attr1 attribute more than once", ex.getMessage());
+ }
+ }
+
+ @Test
+ public void testProperty() {
+ buildRule.executeTarget("property");
+ // get the fileset and its basedir
+ String log = buildRule.getLog();
+ assertTrue("Expecting property in attribute value replaced",
+ log.indexOf("Attribute value = test") != -1);
+ }
+
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/sos/SOSTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/sos/SOSTest.java
new file mode 100644
index 00000000..c45ec17e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/sos/SOSTest.java
@@ -0,0 +1,351 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.sos;
+
+import java.io.File;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.BuildFileRule;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.Commandline;
+import org.apache.tools.ant.types.Path;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+/**
+ * Testcase to ensure that command line generation and required attributes are
+ * correct.
+ *
+ */
+public class SOSTest {
+
+ private Commandline commandline;
+
+ private static final String VSS_SERVER_PATH = "\\\\server\\vss\\srcsafe.ini";
+ private static final String VSS_PROJECT_PATH = "/SourceRoot/Project";
+ private static final String DS_VSS_PROJECT_PATH = "$/SourceRoot/Project";
+ private static final String SOS_SERVER_PATH = "192.168.0.1:8888";
+ private static final String SOS_USERNAME = "ant";
+ private static final String SOS_PASSWORD = "rocks";
+ private static final String LOCAL_PATH = "testdir";
+ private static final String SRC_FILE = "Class1.java";
+ private static final String SRC_LABEL = "label1";
+ private static final String SRC_COMMENT = "I fixed a bug";
+ private static final String SOS_HOME = "/home/user/.sos";
+ private static final String VERSION = "007";
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+ private Project project;
+
+ @Before
+ public void setUp() {
+ project = new Project();
+ project.init();
+ project.setBasedir(".");
+ }
+
+ @After
+ public void tearDown() {
+ File file = new File(project.getBaseDir(), LOCAL_PATH);
+ if (file.exists()) {
+ file.delete();
+ }
+ }
+
+ /** Test SOSGetFile flags & commandline generation */
+ @Test
+ public void testGetFileFlags() {
+ String[] sTestCmdLine = {"soscmd", "-command", "GetFile", "-file",
+ SRC_FILE, "-revision", "007", "-server", SOS_SERVER_PATH, "-name",
+ SOS_USERNAME, "-password", SOS_PASSWORD, "-database", VSS_SERVER_PATH,
+ "-project", DS_VSS_PROJECT_PATH, "-verbose", "-nocompress",
+ "-nocache", "-workdir", project.getBaseDir().getAbsolutePath()
+ + File.separator + LOCAL_PATH};
+
+ // Set up a SOSGet task
+ SOSGet sosGet = new SOSGet();
+ sosGet.setProject(project);
+ sosGet.setVssServerPath(VSS_SERVER_PATH);
+ sosGet.setSosServerPath(SOS_SERVER_PATH);
+ sosGet.setProjectPath(VSS_PROJECT_PATH);
+ sosGet.setFile(SRC_FILE);
+ sosGet.setUsername(SOS_USERNAME);
+ sosGet.setPassword(SOS_PASSWORD);
+ sosGet.setVersion(VERSION);
+ sosGet.setLocalPath(new Path(project, LOCAL_PATH));
+ sosGet.setNoCache(true);
+ sosGet.setNoCompress(true);
+ sosGet.setVerbose(true);
+ sosGet.setRecursive(true);
+
+ commandline = sosGet.buildCmdLine();
+
+ checkCommandLines(sTestCmdLine, commandline.getCommandline());
+ }
+
+ /** Test SOSGetProject flags & commandline generation */
+ @Test
+ public void testGetProjectFlags() {
+ String[] sTestCmdLine = {"soscmd", "-command", "GetProject", "-recursive",
+ "-label", SRC_LABEL, "-server", SOS_SERVER_PATH, "-name", SOS_USERNAME,
+ "-password", "", "-database", VSS_SERVER_PATH, "-project",
+ DS_VSS_PROJECT_PATH, "", "", "-soshome", SOS_HOME, "-workdir",
+ project.getBaseDir().getAbsolutePath()};
+
+ // Set up a SOSGet task
+ SOSGet sosGet = new SOSGet();
+ sosGet.setProject(project);
+ sosGet.setVssServerPath(VSS_SERVER_PATH);
+ sosGet.setSosServerPath(SOS_SERVER_PATH);
+ sosGet.setProjectPath(DS_VSS_PROJECT_PATH);
+ sosGet.setLabel(SRC_LABEL);
+ sosGet.setUsername(SOS_USERNAME);
+ sosGet.setSosHome(SOS_HOME);
+ sosGet.setNoCache(true);
+ sosGet.setNoCompress(false);
+ sosGet.setVerbose(false);
+ sosGet.setRecursive(true);
+
+ commandline = sosGet.buildCmdLine();
+
+ checkCommandLines(sTestCmdLine, commandline.getCommandline());
+ }
+
+ /** Tests SOSGet required attributes. */
+ @Test
+ public void testGetExceptions() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/optional/sos/sos.xml");
+ expectSpecificBuildException("sosget.1", "some cause", "sosserverpath attribute must be set!");
+ expectSpecificBuildException("sosget.2", "some cause", "username attribute must be set!");
+ expectSpecificBuildException("sosget.3", "some cause", "vssserverpath attribute must be set!");
+ expectSpecificBuildException("sosget.4", "some cause", "projectpath attribute must be set!");
+ }
+
+ /** Test CheckInFile option flags */
+ @Test
+ public void testCheckinFileFlags() {
+ String[] sTestCmdLine = {"soscmd", "-command", "CheckInFile", "-file",
+ SRC_FILE, "-server", SOS_SERVER_PATH, "-name", SOS_USERNAME,
+ "-password", SOS_PASSWORD, "-database", VSS_SERVER_PATH, "-project",
+ DS_VSS_PROJECT_PATH, "-verbose", "-nocompress", "-nocache",
+ "-workdir", project.getBaseDir().getAbsolutePath() + File.separator
+ + LOCAL_PATH, "-log", SRC_COMMENT};
+
+ // Set up a SOSCheckin task
+ SOSCheckin sosCheckin = new SOSCheckin();
+ sosCheckin.setProject(project);
+ sosCheckin.setVssServerPath(VSS_SERVER_PATH);
+ sosCheckin.setSosServerPath(SOS_SERVER_PATH);
+ sosCheckin.setProjectPath(VSS_PROJECT_PATH);
+ sosCheckin.setFile(SRC_FILE);
+ sosCheckin.setComment(SRC_COMMENT);
+ sosCheckin.setUsername(SOS_USERNAME);
+ sosCheckin.setPassword(SOS_PASSWORD);
+ sosCheckin.setLocalPath(new Path(project, LOCAL_PATH));
+ sosCheckin.setNoCache(true);
+ sosCheckin.setNoCompress(true);
+ sosCheckin.setVerbose(true);
+ sosCheckin.setRecursive(true);
+
+ commandline = sosCheckin.buildCmdLine();
+
+ checkCommandLines(sTestCmdLine, commandline.getCommandline());
+ }
+
+ /** Test CheckInProject option flags */
+ @Test
+ public void testCheckinProjectFlags() {
+ String[] sTestCmdLine = {"soscmd", "-command", "CheckInProject",
+ "-recursive", "-server", SOS_SERVER_PATH, "-name", SOS_USERNAME,
+ "-password", "", "-database", VSS_SERVER_PATH, "-project",
+ DS_VSS_PROJECT_PATH, "", "", "-soshome", SOS_HOME, "-workdir",
+ project.getBaseDir().getAbsolutePath(), "-log", SRC_COMMENT,};
+
+ // Set up a SOSCheckin task
+ SOSCheckin sosCheckin = new SOSCheckin();
+ sosCheckin.setProject(project);
+ sosCheckin.setVssServerPath(VSS_SERVER_PATH);
+ sosCheckin.setSosServerPath(SOS_SERVER_PATH);
+ sosCheckin.setProjectPath(DS_VSS_PROJECT_PATH);
+ sosCheckin.setComment(SRC_COMMENT);
+ sosCheckin.setUsername(SOS_USERNAME);
+ sosCheckin.setSosHome(SOS_HOME);
+ sosCheckin.setNoCache(true);
+ sosCheckin.setNoCompress(false);
+ sosCheckin.setVerbose(false);
+ sosCheckin.setRecursive(true);
+
+ commandline = sosCheckin.buildCmdLine();
+
+ checkCommandLines(sTestCmdLine, commandline.getCommandline());
+ }
+
+ /** Test SOSCheckIn required attributes. */
+ @Test
+ public void testCheckinExceptions() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/optional/sos/sos.xml");
+ expectSpecificBuildException("soscheckin.1", "some cause", "sosserverpath attribute must be set!");
+ expectSpecificBuildException("soscheckin.2", "some cause", "username attribute must be set!");
+ expectSpecificBuildException("soscheckin.3", "some cause", "vssserverpath attribute must be set!");
+ expectSpecificBuildException("soscheckin.4", "some cause", "projectpath attribute must be set!");
+ }
+
+ /** Test CheckOutFile option flags */
+ @Test
+ public void testCheckoutFileFlags() {
+ String[] sTestCmdLine = {"soscmd", "-command", "CheckOutFile", "-file",
+ SRC_FILE, "-server", SOS_SERVER_PATH, "-name", SOS_USERNAME,
+ "-password", SOS_PASSWORD, "-database", VSS_SERVER_PATH, "-project",
+ DS_VSS_PROJECT_PATH, "-verbose", "-nocompress", "-nocache",
+ "-workdir", project.getBaseDir().getAbsolutePath()
+ + File.separator + LOCAL_PATH};
+
+ // Set up a SOSCheckout task
+ SOSCheckout sosCheckout = new SOSCheckout();
+ sosCheckout.setProject(project);
+ sosCheckout.setVssServerPath(VSS_SERVER_PATH);
+ sosCheckout.setSosServerPath(SOS_SERVER_PATH);
+ sosCheckout.setProjectPath(DS_VSS_PROJECT_PATH);
+ sosCheckout.setFile(SRC_FILE);
+ sosCheckout.setUsername(SOS_USERNAME);
+ sosCheckout.setPassword(SOS_PASSWORD);
+ sosCheckout.setLocalPath(new Path(project, LOCAL_PATH));
+ sosCheckout.setNoCache(true);
+ sosCheckout.setNoCompress(true);
+ sosCheckout.setVerbose(true);
+ sosCheckout.setRecursive(true);
+
+ commandline = sosCheckout.buildCmdLine();
+
+ checkCommandLines(sTestCmdLine, commandline.getCommandline());
+ }
+
+ /** Test CheckOutProject option flags */
+ @Test
+ public void testCheckoutProjectFlags() {
+ String[] sTestCmdLine = {"soscmd", "-command", "CheckOutProject",
+ "-recursive", "-server", SOS_SERVER_PATH, "-name", SOS_USERNAME,
+ "-password", "", "-database", VSS_SERVER_PATH, "-project",
+ DS_VSS_PROJECT_PATH, "", "", "-soshome", SOS_HOME, "-workdir",
+ project.getBaseDir().getAbsolutePath()};
+
+ // Set up a sosCheckout task
+ SOSCheckout sosCheckout = new SOSCheckout();
+ sosCheckout.setProject(project);
+ sosCheckout.setVssServerPath(VSS_SERVER_PATH);
+ sosCheckout.setSosServerPath(SOS_SERVER_PATH);
+ sosCheckout.setProjectPath(VSS_PROJECT_PATH);
+ sosCheckout.setUsername(SOS_USERNAME);
+ sosCheckout.setSosHome(SOS_HOME);
+ sosCheckout.setNoCache(true);
+ sosCheckout.setNoCompress(false);
+ sosCheckout.setVerbose(false);
+ sosCheckout.setRecursive(true);
+
+ commandline = sosCheckout.buildCmdLine();
+
+ checkCommandLines(sTestCmdLine, commandline.getCommandline());
+ }
+
+ /** Test SOSCheckout required attributes. */
+ @Test
+ public void testCheckoutExceptions() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/optional/sos/sos.xml");
+ expectSpecificBuildException("soscheckout.1", "some cause", "sosserverpath attribute must be set!");
+ expectSpecificBuildException("soscheckout.2", "some cause", "username attribute must be set!");
+ expectSpecificBuildException("soscheckout.3", "some cause", "vssserverpath attribute must be set!");
+ expectSpecificBuildException("soscheckout.4", "some cause", "projectpath attribute must be set!");
+ }
+
+ /** Test Label option flags */
+ @Test
+ public void testLabelFlags() {
+ String[] sTestCmdLine = {"soscmd", "-command", "AddLabel", "-server",
+ SOS_SERVER_PATH, "-name", SOS_USERNAME, "-password", "", "-database",
+ VSS_SERVER_PATH, "-project", DS_VSS_PROJECT_PATH, "-label",
+ SRC_LABEL, "-verbose", "-log", SRC_COMMENT};
+
+ // Set up a sosCheckout task
+ SOSLabel sosLabel = new SOSLabel();
+ sosLabel.setVssServerPath(VSS_SERVER_PATH);
+ sosLabel.setSosServerPath(SOS_SERVER_PATH);
+ sosLabel.setProjectPath(DS_VSS_PROJECT_PATH);
+ sosLabel.setUsername(SOS_USERNAME);
+ sosLabel.setSosHome(SOS_HOME);
+ sosLabel.setComment(SRC_COMMENT);
+ sosLabel.setLabel(SRC_LABEL);
+ sosLabel.setNoCache(true);
+ sosLabel.setNoCompress(false);
+ sosLabel.setVerbose(true);
+
+ commandline = sosLabel.buildCmdLine();
+
+ checkCommandLines(sTestCmdLine, commandline.getCommandline());
+ }
+
+ /** Test SOSLabel required attributes. */
+ @Test
+ public void testLabelExceptions() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/optional/sos/sos.xml");
+ expectSpecificBuildException("soslabel.1", "some cause", "sosserverpath attribute must be set!");
+ expectSpecificBuildException("soslabel.2", "some cause", "username attribute must be set!");
+ expectSpecificBuildException("soslabel.3", "some cause", "vssserverpath attribute must be set!");
+ expectSpecificBuildException("soslabel.4", "some cause", "projectpath attribute must be set!");
+ expectSpecificBuildException("soslabel.5", "some cause", "label attribute must be set!");
+ }
+
+ private void expectSpecificBuildException(String target, String errorMessage,
+ String exceptionMessage) {
+ try {
+ buildRule.executeTarget(target);
+ fail(errorMessage);
+ } catch(BuildException ex) {
+ assertEquals(exceptionMessage, ex.getMessage());
+ }
+ }
+
+ /**
+ * Iterate through the generated command line comparing it to reference
+ * one.
+ *
+ * @param sTestCmdLine The reference command line;
+ * @param sGeneratedCmdLine The generated command line;
+ */
+ private void checkCommandLines(String[] sTestCmdLine, String[] sGeneratedCmdLine) {
+ int length = sTestCmdLine.length;
+ for (int i = 0; i < length; i++) {
+ try {
+ assertEquals("arg # " + String.valueOf(i),
+ sTestCmdLine[i],
+ sGeneratedCmdLine[i]);
+ } catch (ArrayIndexOutOfBoundsException aioob) {
+ fail("missing arg " + sTestCmdLine[i]);
+ }
+ }
+ if (sGeneratedCmdLine.length > sTestCmdLine.length) {
+ // We have extra elements
+ fail("extra args");
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/splash/SplashScreenTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/splash/SplashScreenTest.java
new file mode 100644
index 00000000..fb0b3eaf
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/splash/SplashScreenTest.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.splash;
+
+import org.apache.tools.ant.Project;
+
+/**
+ * This is an "interactive" test, it passes if the splash screen
+ * disappears after the "finished" but before the "exiting" message.
+ *
+ * This even isn't a JUnit test case.
+ *
+ * @since Ant 1.5.2
+ */
+public class SplashScreenTest {
+
+ public static void main(String[] args) throws InterruptedException {
+ Project p = new Project();
+ SplashTask t = new SplashTask();
+ t.setProject(p);
+ t.execute();
+
+ // give it some time to display
+ Thread.sleep(2000);
+
+ p.fireBuildFinished(null);
+ System.err.println("finished");
+
+ Thread.sleep(2000);
+ System.err.println("exiting");
+ System.exit(0);
+ }
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/ssh/ScpTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/ssh/ScpTest.java
new file mode 100644
index 00000000..dff5b25a
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/ssh/ScpTest.java
@@ -0,0 +1,206 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.ssh;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.condition.FilesMatch;
+import org.apache.tools.ant.types.FileSet;
+import org.apache.tools.ant.types.selectors.FilenameSelector;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+/**
+ * This is a unit test for the Scp task in Ant. It must be
+ * configured with command line options in order for it to work.
+ * Here are the options:
+ *
+ * scp.tmp This is a local path to a temporary
+ * directory for this task to use.
+ * scp.host This is the remote location of the form:
+ * "user:password@host:/path/to/directory"
+ * scp.port The port of the listening SSH service.
+ * Defaults to 22. (optional)
+ * scp.known.hosts The file containing the public keys of known
+ * hosts. Must be a SSH2 version file, but
+ * supports RSA and DSA keys. If it is not present
+ * this task setTrust() to true. (optional)
+ */
+public class ScpTest {
+
+ private File tempDir;
+ private String sshHostUri = System.getProperty("scp.host");
+ private int port = Integer.parseInt( System.getProperty( "scp.port", "22" ) );
+ private String knownHosts = System.getProperty("scp.known.hosts");
+
+ private List cleanUpList = new ArrayList();
+
+ public ScpTest() {
+ if (System.getProperty("scp.tmp") != null) {
+ tempDir = new File(System.getProperty("scp.tmp"));
+ }
+ }
+
+ @Before
+ public void setUp() {
+ cleanUpList.clear();
+ }
+
+ @After
+ public void tearDown() {
+ for( Iterator i = cleanUpList.iterator(); i.hasNext(); ) {
+ File file = (File) i.next();
+ file.delete();
+ }
+ }
+
+ @Test
+ public void testSingleFileUploadAndDownload() throws IOException {
+ assertNotNull("system property scp.tmp must be set", tempDir);
+ File uploadFile = createTemporaryFile();
+
+ // upload
+ Scp scpTask = createTask();
+ scpTask.setFile( uploadFile.getPath() );
+ scpTask.setTodir( sshHostUri );
+ scpTask.execute();
+
+ File testFile = new File( tempDir.getPath() + File.separator +
+ "download-testSingleFileUploadAndDownload.test" );
+ addCleanup(testFile );
+ assertFalse("Assert that the testFile does not exist.", testFile.exists());
+
+ // download
+ scpTask = createTask();
+ scpTask.setFile( sshHostUri + "/" + uploadFile.getName() );
+ scpTask.setTodir( testFile.getPath() );
+ scpTask.execute();
+
+ assertTrue( "Assert that the testFile exists.", testFile.exists() );
+ compareFiles( uploadFile, testFile );
+ }
+
+ @Test
+ public void testMultiUploadAndDownload() throws IOException {
+ assertNotNull("system property scp.tmp must be set", tempDir);
+ List uploadList = new ArrayList();
+ for( int i = 0; i < 5; i++ ) {
+ uploadList.add( createTemporaryFile() );
+ }
+
+ Scp scp = createTask();
+ FilenameSelector selector = new FilenameSelector();
+ selector.setName( "scp*" );
+ FileSet fileset = new FileSet();
+ fileset.setDir( tempDir );
+ fileset.addFilename( selector );
+ scp.addFileset( fileset );
+ scp.setTodir( sshHostUri );
+ scp.execute();
+
+ File multi = new File( tempDir, "multi" );
+ multi.mkdir();
+ addCleanup( multi );
+
+ Scp scp2 = createTask();
+ scp2.setFile( sshHostUri + "/scp*" );
+ scp2.setTodir( multi.getPath() );
+ scp2.execute();
+
+ FilesMatch match = new FilesMatch();
+ for( Iterator i = uploadList.iterator(); i.hasNext(); ) {
+ File f = (File)i.next();
+ match.setFile1( f );
+ File f2 = new File( multi, f.getName() );
+ match.setFile2( f2 );
+ assertTrue("Assert file '" + f.getPath() + "' and file '" +
+ f2.getPath() + "'", match.eval() );
+ }
+ }
+
+ @Test
+ public void testRemoteToDir() throws IOException {
+ Scp scpTask = createTask();
+
+ // first try an invalid URI
+ try {
+ scpTask.setRemoteTodir( "host:/a/path/without/an/at" );
+ fail("Expected a BuildException to be thrown due to invalid"
+ + " remoteToDir");
+ }
+ catch (BuildException e)
+ {
+ // expected
+ //TODO we should be asserting a value in here
+ }
+
+ // And this one should work
+ scpTask.setRemoteTodir( "user:password@host:/a/path/with/an/at" );
+ // no exception
+ }
+
+ public void addCleanup( File file ) {
+ cleanUpList.add( file );
+ }
+
+ private void compareFiles(File src, File dest) {
+ FilesMatch match = new FilesMatch();
+ match.setFile1( src );
+ match.setFile2( dest );
+
+ assertTrue( "Assert files are equal.", match.eval() );
+ }
+
+ private File createTemporaryFile() throws IOException {
+ File uploadFile;
+ uploadFile = File.createTempFile( "scp", "test", tempDir );
+ FileWriter writer = new FileWriter( uploadFile );
+ writer.write("Can you hear me now?\n");
+ writer.close();
+ addCleanup( uploadFile );
+ return uploadFile;
+ }
+
+ private Scp createTask() {
+ Scp scp = new Scp();
+ Project p = new Project();
+ p.init();
+ scp.setProject( p );
+ if( knownHosts != null ) {
+ scp.setKnownhosts( knownHosts );
+ } else {
+ scp.setTrust( true );
+ }
+ scp.setPort( port );
+ return scp;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/unix/SymlinkTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/unix/SymlinkTest.java
new file mode 100644
index 00000000..e36d6838
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/unix/SymlinkTest.java
@@ -0,0 +1,297 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+/*
+ * Since the initial version of this file was deveolped on the clock on
+ * an NSF grant I should say the following boilerplate:
+ *
+ * This material is based upon work supported by the National Science
+ * Foundaton under Grant No. EIA-0196404. Any opinions, findings, and
+ * conclusions or recommendations expressed in this material are those
+ * of the author and do not necessarily reflect the views of the
+ * National Science Foundation.
+ */
+
+package org.apache.tools.ant.taskdefs.optional.unix;
+
+import org.apache.tools.ant.BuildFileRule;
+import org.apache.tools.ant.taskdefs.condition.Os;
+
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.util.SymbolicLinkUtils;
+import org.junit.After;
+import org.junit.Assume;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.File;
+
+/**
+ * Test cases for the Symlink task. Link creation, link deletion, recording
+ * of links in multiple directories, and restoration of links recorded are
+ * all tested. A separate test for the utility method Symlink.deleteSymlink
+ * is not included because action="delete" only prints a message and calls
+ * Symlink.deleteSymlink, making a separate test redundant.
+ *
+ */
+
+public class SymlinkTest {
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ private boolean supportsSymlinks = Os.isFamily("unix");
+
+ @Before
+ public void setUp() {
+ Assume.assumeTrue("Symlinks not supported on current operating system", supportsSymlinks);
+ buildRule.configureProject("src/etc/testcases/taskdefs/optional/unix/symlink.xml");
+ buildRule.executeTarget("setUp");
+ }
+
+ @Test
+ public void testSingle() {
+ buildRule.executeTarget("test-single");
+ Project p = buildRule.getProject();
+ assertNotNull("Failed to create file",
+ p.getProperty("test.single.file.created"));
+ assertNotNull("Failed to create link",
+ p.getProperty("test.single.link.created"));
+ }
+
+ @Test
+ public void testDelete() {
+ buildRule.executeTarget("test-delete");
+ Project p = buildRule.getProject();
+ String linkDeleted = p.getProperty("test.delete.link.still.there");
+ assertNotNull("Actual file deleted by symlink",
+ p.getProperty("test.delete.file.still.there"));
+ if (linkDeleted != null) {
+ fail(linkDeleted);
+ }
+ }
+
+ @Test
+ public void testRecord() {
+ buildRule.executeTarget("test-record");
+ Project p = buildRule.getProject();
+
+ assertNotNull("Failed to create dir1",
+ p.getProperty("test.record.dir1.created"));
+
+ assertNotNull("Failed to create dir2",
+ p.getProperty("test.record.dir2.created"));
+
+ assertNotNull("Failed to create file1",
+ p.getProperty("test.record.file1.created"));
+
+ assertNotNull("Failed to create file2",
+ p.getProperty("test.record.file2.created"));
+
+ assertNotNull("Failed to create fileA",
+ p.getProperty("test.record.fileA.created"));
+
+ assertNotNull("Failed to create fileB",
+ p.getProperty("test.record.fileB.created"));
+
+ assertNotNull("Failed to create fileC",
+ p.getProperty("test.record.fileC.created"));
+
+ assertNotNull("Failed to create link1",
+ p.getProperty("test.record.link1.created"));
+
+ assertNotNull("Failed to create link2",
+ p.getProperty("test.record.link2.created"));
+
+ assertNotNull("Failed to create link3",
+ p.getProperty("test.record.link3.created"));
+
+ assertNotNull("Failed to create dirlink",
+ p.getProperty("test.record.dirlink.created"));
+
+ assertNotNull("Failed to create dirlink2",
+ p.getProperty("test.record.dirlink2.created"));
+
+ assertNotNull("Couldn't record links in dir1",
+ p.getProperty("test.record.dir1.recorded"));
+
+ assertNotNull("Couldn't record links in dir2",
+ p.getProperty("test.record.dir2.recorded"));
+
+ String dir3rec = p.getProperty("test.record.dir3.recorded");
+
+ if (dir3rec != null) {
+ fail(dir3rec);
+ }
+
+ }
+
+ @Test
+ public void testRecreate() {
+ buildRule.executeTarget("test-recreate");
+ Project p = buildRule.getProject();
+ String link1Rem = p.getProperty("test.recreate.link1.not.removed");
+ String link2Rem = p.getProperty("test.recreate.link2.not.removed");
+ String link3Rem = p.getProperty("test.recreate.link3.not.removed");
+ String dirlinkRem = p.getProperty("test.recreate.dirlink.not.removed");
+ if (link1Rem != null) {
+ fail(link1Rem);
+ }
+ if (link2Rem != null) {
+ fail(link2Rem);
+ }
+ if (link3Rem != null) {
+ fail(link3Rem);
+ }
+ if (dirlinkRem != null) {
+ fail(dirlinkRem);
+ }
+ assertNotNull("Failed to recreate link1",
+ p.getProperty("test.recreate.link1.recreated"));
+ assertNotNull("Failed to recreate link2",
+ p.getProperty("test.recreate.link2.recreated"));
+ assertNotNull("Failed to recreate link3",
+ p.getProperty("test.recreate.link3.recreated"));
+ assertNotNull("Failed to recreate dirlink",
+ p.getProperty("test.recreate.dirlink.recreated"));
+
+ String doubleRecreate = p.getProperty("test.recreate.dirlink2.recreated.twice");
+
+ if (doubleRecreate != null) {
+ fail(doubleRecreate);
+ }
+
+ assertNotNull("Failed to alter dirlink3",
+ p.getProperty("test.recreate.dirlink3.was.altered"));
+ }
+
+ @Test
+ public void testSymbolicLinkUtilsMethods() throws Exception {
+
+ buildRule.executeTarget("test-fileutils");
+ SymbolicLinkUtils su = SymbolicLinkUtils.getSymbolicLinkUtils();
+
+ java.io.File f = new File(buildRule.getOutputDir(), "file1");
+ assertTrue(f.exists());
+ assertFalse(f.isDirectory());
+ assertTrue(f.isFile());
+ assertFalse(su.isSymbolicLink(f.getAbsolutePath()));
+ assertFalse(su.isSymbolicLink(f.getParentFile(),
+ f.getName()));
+ assertFalse(su.isDanglingSymbolicLink(f.getAbsolutePath()));
+ assertFalse(su.isDanglingSymbolicLink(f.getParentFile(),
+ f.getName()));
+
+ f = new File(buildRule.getOutputDir(), "dir1");
+ assertTrue(f.exists());
+ assertTrue(f.isDirectory());
+ assertFalse(f.isFile());
+ assertFalse(su.isSymbolicLink(f.getAbsolutePath()));
+ assertFalse(su.isSymbolicLink(f.getParentFile(),
+ f.getName()));
+ assertFalse(su.isDanglingSymbolicLink(f.getAbsolutePath()));
+ assertFalse(su.isDanglingSymbolicLink(f.getParentFile(),
+ f.getName()));
+
+ f = new File(buildRule.getOutputDir(), "file2");
+ assertFalse(f.exists());
+ assertFalse(f.isDirectory());
+ assertFalse(f.isFile());
+ assertFalse(su.isSymbolicLink(f.getAbsolutePath()));
+ assertFalse(su.isSymbolicLink(f.getParentFile(),
+ f.getName()));
+ assertFalse(su.isDanglingSymbolicLink(f.getAbsolutePath()));
+ assertFalse(su.isDanglingSymbolicLink(f.getParentFile(),
+ f.getName()));
+
+ f = new File(buildRule.getOutputDir(), "dir2");
+ assertFalse(f.exists());
+ assertFalse(f.isDirectory());
+ assertFalse(f.isFile());
+ assertFalse(su.isSymbolicLink(f.getAbsolutePath()));
+ assertFalse(su.isSymbolicLink(f.getParentFile(),
+ f.getName()));
+ assertFalse(su.isDanglingSymbolicLink(f.getAbsolutePath()));
+ assertFalse(su.isDanglingSymbolicLink(f.getParentFile(),
+ f.getName()));
+
+
+ f = new File(buildRule.getOutputDir(), "file.there");
+ assertTrue(f.exists());
+ assertFalse(f.isDirectory());
+ assertTrue(f.isFile());
+ assertTrue(su.isSymbolicLink(f.getAbsolutePath()));
+ assertTrue(su.isSymbolicLink(f.getParentFile(),
+ f.getName()));
+ assertFalse(su.isDanglingSymbolicLink(f.getAbsolutePath()));
+ assertFalse(su.isDanglingSymbolicLink(f.getParentFile(),
+ f.getName()));
+
+ f = new File(buildRule.getOutputDir(), "dir.there");
+ assertTrue(f.exists());
+ assertTrue(f.isDirectory());
+ assertFalse(f.isFile());
+ assertTrue(su.isSymbolicLink(f.getAbsolutePath()));
+ assertTrue(su.isSymbolicLink(f.getParentFile(),
+ f.getName()));
+ assertFalse(su.isDanglingSymbolicLink(f.getAbsolutePath()));
+ assertFalse(su.isDanglingSymbolicLink(f.getParentFile(),
+ f.getName()));
+
+ // it is not possible to find out that symbolic links pointing
+ // to inexistent files or directories are symbolic links
+ // it used to be possible to detect this on Mac
+ // this is not true under Snow Leopard and JDK 1.5
+ // Removing special handling of MacOS until someone shouts
+ // Antoine
+ f = new File(buildRule.getOutputDir(), "file.notthere");
+ assertFalse(f.exists());
+ assertFalse(f.isDirectory());
+ assertFalse(f.isFile());
+ assertTrue(su.isSymbolicLink(f.getAbsolutePath()) == false);
+ assertTrue(su.isSymbolicLink(f.getParentFile(), f.getName()) == false);
+ assertTrue(su.isDanglingSymbolicLink(f.getAbsolutePath()));
+ assertTrue(su.isDanglingSymbolicLink(f.getParentFile(),
+ f.getName()));
+
+ f = new File(buildRule.getOutputDir(), "dir.notthere");
+ assertFalse(f.exists());
+ assertFalse(f.isDirectory());
+ assertFalse(f.isFile());
+ assertTrue(su.isSymbolicLink(f.getAbsolutePath()) == false);
+ assertTrue(su.isSymbolicLink(f.getParentFile(), f.getName()) == false);
+ assertTrue(su.isDanglingSymbolicLink(f.getAbsolutePath()));
+ assertTrue(su.isDanglingSymbolicLink(f.getParentFile(),
+ f.getName()));
+
+ }
+
+ @After
+ public void tearDown() {
+ if (buildRule.getProject() != null) {
+ buildRule.executeTarget("tearDown");
+ }
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/vss/MSVSSTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/vss/MSVSSTest.java
new file mode 100644
index 00000000..aa96d8d5
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/taskdefs/optional/vss/MSVSSTest.java
@@ -0,0 +1,475 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.vss;
+
+import java.io.File;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.TimeZone;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.BuildFileRule;
+import org.apache.tools.ant.Location;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.Tstamp;
+import org.apache.tools.ant.types.Commandline;
+import org.apache.tools.ant.types.Path;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+/**
+ * Testcase to ensure that command line generation and required attributes are correct.
+ *
+ */
+public class MSVSSTest implements MSVSSConstants {
+
+ private Commandline commandline;
+
+ private static final String VSS_PROJECT_PATH = "/SourceRoot/Project";
+ private static final String DS_VSS_PROJECT_PATH = "$/SourceRoot/Project";
+ private static final String VSS_USERNAME = "ant";
+ private static final String VSS_PASSWORD = "rocks";
+ private static final String LOCAL_PATH = "testdir";
+ private static final String SRC_LABEL = "label1";
+ private static final String LONG_LABEL = "123456789012345678901234567890";
+ private static final String SRC_COMMENT = "I fixed a bug";
+ private static final String VERSION = "007";
+ private static final String DATE = "00-00-00";
+ private static final String DATE2 = "01-01-01";
+ private static final String OUTPUT = "output.log";
+ private static final String SS_DIR = "c:/winnt".replace('/', File.separatorChar);
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+ private Project project;
+
+ @Before
+ public void setUp(){
+ project = new Project();
+ project.setBasedir(".");
+ project.init();
+ }
+
+ @After
+ public void tearDown() {
+ File file = new File(project.getBaseDir(), LOCAL_PATH);
+ if (file.exists()) {
+ file.delete();
+ }
+ }
+
+ @Test
+ public void testGetCommandLine() {
+ String[] sTestCmdLine = {MSVSS.SS_EXE, MSVSS.COMMAND_GET, DS_VSS_PROJECT_PATH,
+ MSVSS.FLAG_OVERRIDE_WORKING_DIR + project.getBaseDir()
+ .getAbsolutePath()
+ + File.separator + LOCAL_PATH, MSVSS.FLAG_AUTORESPONSE_DEF,
+ MSVSS.FLAG_RECURSION, MSVSS.FLAG_VERSION + VERSION, MSVSS.FLAG_LOGIN
+ + VSS_USERNAME + "," + VSS_PASSWORD, FLAG_FILETIME_UPDATED, FLAG_SKIP_WRITABLE};
+
+ // Set up a VSSGet task
+ MSVSSGET vssGet = new MSVSSGET();
+ vssGet.setProject(project);
+ vssGet.setRecursive(true);
+ vssGet.setLocalpath(new Path(project, LOCAL_PATH));
+ vssGet.setLogin(VSS_USERNAME + "," + VSS_PASSWORD);
+ vssGet.setVersion(VERSION);
+ vssGet.setQuiet(false);
+ vssGet.setDate(DATE);
+ vssGet.setLabel(SRC_LABEL);
+ vssGet.setVsspath(VSS_PROJECT_PATH);
+ MSVSS.CurrentModUpdated cmu = new MSVSS.CurrentModUpdated();
+ cmu.setValue(TIME_UPDATED);
+ vssGet.setFileTimeStamp(cmu);
+ MSVSS.WritableFiles wf = new MSVSS.WritableFiles();
+ wf.setValue(WRITABLE_SKIP);
+ vssGet.setWritableFiles(wf);
+
+ commandline = vssGet.buildCmdLine();
+
+ checkCommandLines(sTestCmdLine, commandline.getCommandline());
+ }
+
+ /** Tests VSSGet required attributes. */
+ @Test
+ public void testGetExceptions() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/optional/vss/vss.xml");
+ expectSpecificBuildException("vssget.1", "some cause", "vsspath attribute must be set!");
+ }
+
+ /** Tests Label commandline generation. */
+ @Test
+ public void testLabelCommandLine1() {
+ String[] sTestCmdLine = {MSVSS.SS_EXE, MSVSS.COMMAND_LABEL, DS_VSS_PROJECT_PATH,
+ MSVSS.FLAG_COMMENT + SRC_COMMENT, MSVSS.FLAG_AUTORESPONSE_YES,
+ MSVSS.FLAG_LABEL + SRC_LABEL, MSVSS.FLAG_VERSION + VERSION, MSVSS.FLAG_LOGIN
+ + VSS_USERNAME + "," + VSS_PASSWORD};
+
+ // Set up a VSSLabel task
+ MSVSSLABEL vssLabel = new MSVSSLABEL();
+ vssLabel.setProject(project);
+ vssLabel.setComment(SRC_COMMENT);
+ vssLabel.setLogin(VSS_USERNAME + "," + VSS_PASSWORD);
+ vssLabel.setVersion(VERSION);
+ vssLabel.setAutoresponse("Y");
+ vssLabel.setLabel(SRC_LABEL);
+ vssLabel.setVsspath(VSS_PROJECT_PATH);
+
+ commandline = vssLabel.buildCmdLine();
+
+ checkCommandLines(sTestCmdLine, commandline.getCommandline());
+ }
+
+ /** Tests Label commandline generation with a label of more than 31 chars. */
+ @Test
+ public void testLabelCommandLine2() {
+ String[] sTestCmdLine = {MSVSS.SS_EXE, MSVSS.COMMAND_LABEL, DS_VSS_PROJECT_PATH,
+ MSVSS.FLAG_COMMENT + SRC_COMMENT, MSVSS.FLAG_AUTORESPONSE_DEF,
+ MSVSS.FLAG_LABEL + LONG_LABEL,
+ MSVSS.FLAG_LOGIN + VSS_USERNAME + "," + VSS_PASSWORD};
+
+ // Set up a VSSLabel task
+ MSVSSLABEL vssLabel = new MSVSSLABEL();
+ vssLabel.setProject(project);
+ vssLabel.setComment(SRC_COMMENT);
+ vssLabel.setLogin(VSS_USERNAME + "," + VSS_PASSWORD);
+ vssLabel.setLabel(LONG_LABEL + "blahblah");
+ vssLabel.setVsspath(VSS_PROJECT_PATH);
+
+ commandline = vssLabel.buildCmdLine();
+
+ checkCommandLines(sTestCmdLine, commandline.getCommandline());
+ }
+
+ /**
+ * Test VSSLabel required attributes.
+ */
+ @Test
+ public void testLabelExceptions() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/optional/vss/vss.xml");
+ expectSpecificBuildException("vsslabel.1", "some cause", "vsspath attribute must be set!");
+ expectSpecificBuildException("vsslabel.2", "some cause", "label attribute must be set!");
+ }
+
+ /** Tests VSSHistory commandline generation with from label. */
+ @Test
+ public void testHistoryCommandLine1() {
+ String[] sTestCmdLine = {MSVSS.SS_EXE, MSVSS.COMMAND_HISTORY, DS_VSS_PROJECT_PATH,
+ MSVSS.FLAG_AUTORESPONSE_DEF, MSVSS.FLAG_VERSION_LABEL + LONG_LABEL
+ + MSVSS.VALUE_FROMLABEL + SRC_LABEL, MSVSS.FLAG_LOGIN + VSS_USERNAME
+ + "," + VSS_PASSWORD, MSVSS.FLAG_OUTPUT + project.getBaseDir()
+ .getAbsolutePath()
+ + File.separator + OUTPUT};
+
+ // Set up a VSSHistory task
+ MSVSSHISTORY vssHistory = new MSVSSHISTORY();
+ vssHistory.setProject(project);
+
+ vssHistory.setLogin(VSS_USERNAME + "," + VSS_PASSWORD);
+
+ vssHistory.setFromLabel(SRC_LABEL);
+ vssHistory.setToLabel(LONG_LABEL + "blahblah");
+ vssHistory.setVsspath(VSS_PROJECT_PATH);
+ vssHistory.setRecursive(false);
+ vssHistory.setOutput(new File(project.getBaseDir().getAbsolutePath(), OUTPUT));
+
+ commandline = vssHistory.buildCmdLine();
+
+ checkCommandLines(sTestCmdLine, commandline.getCommandline());
+ }
+
+ /** Tests VSSHistory commandline generation with from date. */
+ @Test
+ public void testHistoryCommandLine2() {
+ String[] sTestCmdLine = {MSVSS.SS_EXE, MSVSS.COMMAND_HISTORY, DS_VSS_PROJECT_PATH,
+ MSVSS.FLAG_AUTORESPONSE_DEF, MSVSS.FLAG_VERSION_DATE + DATE + MSVSS.VALUE_FROMDATE
+ + DATE2, MSVSS.FLAG_RECURSION, MSVSS.FLAG_LOGIN + VSS_USERNAME + "," + VSS_PASSWORD};
+
+ // Set up a VSSHistory task
+ MSVSSHISTORY vssHistory = new MSVSSHISTORY();
+ vssHistory.setProject(project);
+ vssHistory.setLogin(VSS_USERNAME + "," + VSS_PASSWORD);
+ vssHistory.setFromDate(DATE2);
+ vssHistory.setToDate(DATE);
+ vssHistory.setVsspath(VSS_PROJECT_PATH);
+ vssHistory.setRecursive(true);
+
+ commandline = vssHistory.buildCmdLine();
+
+ checkCommandLines(sTestCmdLine, commandline.getCommandline());
+ }
+
+ /** Tests VSSHistory commandline generation with date calculation. */
+ @Test
+ public void testHistoryCommandLine3() {
+ // Set up a Timestamp
+ Tstamp tstamp = new Tstamp();
+ Location location = new Location("src/etc/testcases/taskdefs/optional/vss/vss.xml");
+ tstamp.setLocation(location);
+ tstamp.setProject(project);
+ Tstamp.CustomFormat format = tstamp.createFormat();
+ format.setProperty("today");
+ format.setPattern("HH:mm:ss z");
+ format.setTimezone("GMT");
+ Date date = Calendar.getInstance().getTime();
+ format.execute(project, date, location);
+ String today = project.getProperty("today");
+
+ // Get today's date
+ SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss z");
+ sdf.setTimeZone( TimeZone.getTimeZone("GMT") );
+ String expected = sdf.format(date);
+
+ // Set up a VSSHistory task
+ MSVSSHISTORY vssHistory = new MSVSSHISTORY();
+ vssHistory.setProject(project);
+ vssHistory.setLogin(VSS_USERNAME);
+ vssHistory.setToDate(today);
+ vssHistory.setVsspath(VSS_PROJECT_PATH);
+
+ String[] sTestCmdLine = {MSVSS.SS_EXE, MSVSS.COMMAND_HISTORY, DS_VSS_PROJECT_PATH,
+ MSVSS.FLAG_AUTORESPONSE_DEF, MSVSS.FLAG_VERSION_DATE + expected, MSVSS.FLAG_LOGIN + VSS_USERNAME};
+
+ commandline = vssHistory.buildCmdLine();
+
+ checkCommandLines(sTestCmdLine, commandline.getCommandline());
+ }
+
+ /**
+ * Tests VSSHistory required attributes.
+ */
+ @Test
+ public void testHistoryExceptions() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/optional/vss/vss.xml");
+ expectSpecificBuildException("vsshistory.1", "some cause", "vsspath attribute must be set!");
+ }
+
+ private void expectSpecificBuildException(String target, String failMessage,
+ String exceptionMessage) {
+ try {
+ buildRule.executeTarget(target);
+ fail(failMessage);
+ } catch(BuildException ex) {
+ assertEquals(exceptionMessage, ex.getMessage());
+ }
+ }
+
+ /** Tests CheckIn commandline generation. */
+ @Test
+ public void testCheckinCommandLine() {
+ String[] sTestCmdLine = {MSVSS.SS_EXE, MSVSS.COMMAND_CHECKIN, DS_VSS_PROJECT_PATH,
+ MSVSS.FLAG_AUTORESPONSE_NO, MSVSS.FLAG_WRITABLE, MSVSS.FLAG_LOGIN + VSS_USERNAME,
+ MSVSS.FLAG_COMMENT + SRC_COMMENT};
+
+ // Set up a VSSCheckIn task
+ MSVSSCHECKIN vssCheckin = new MSVSSCHECKIN();
+ vssCheckin.setProject(project);
+ vssCheckin.setComment(SRC_COMMENT);
+ vssCheckin.setLogin(VSS_USERNAME);
+ vssCheckin.setAutoresponse("N");
+ vssCheckin.setVsspath(VSS_PROJECT_PATH);
+ vssCheckin.setWritable(true);
+
+ commandline = vssCheckin.buildCmdLine();
+
+ checkCommandLines(sTestCmdLine, commandline.getCommandline());
+ }
+
+ /**
+ * Test VSSCheckIn required attributes.
+ */
+ @Test
+ public void testCheckinExceptions() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/optional/vss/vss.xml");
+ expectSpecificBuildException("vsscheckin.1", "some cause", "vsspath attribute must be set!");
+ }
+
+ /** Tests CheckOut commandline generation. */
+ @Test
+ public void testCheckoutCommandLine() {
+ String[] sTestCmdLine = {SS_DIR + File.separator + MSVSS.SS_EXE, MSVSS.COMMAND_CHECKOUT,
+ DS_VSS_PROJECT_PATH, MSVSS.FLAG_AUTORESPONSE_DEF, MSVSS.FLAG_RECURSION,
+ MSVSS.FLAG_VERSION_DATE + DATE, MSVSS.FLAG_LOGIN + VSS_USERNAME,
+ FLAG_FILETIME_MODIFIED, FLAG_NO_GET};
+
+ // Set up a VSSCheckOut task
+ MSVSSCHECKOUT vssCheckout = new MSVSSCHECKOUT();
+ vssCheckout.setProject(project);
+ vssCheckout.setLogin(VSS_USERNAME);
+ vssCheckout.setVsspath(DS_VSS_PROJECT_PATH);
+ vssCheckout.setRecursive(true);
+ vssCheckout.setDate(DATE);
+ vssCheckout.setLabel(SRC_LABEL);
+ vssCheckout.setSsdir(SS_DIR);
+ MSVSS.CurrentModUpdated cmu = new MSVSS.CurrentModUpdated();
+ cmu.setValue(TIME_MODIFIED);
+ vssCheckout.setFileTimeStamp(cmu);
+ vssCheckout.setGetLocalCopy(false);
+
+ commandline = vssCheckout.buildCmdLine();
+
+ checkCommandLines(sTestCmdLine, commandline.getCommandline());
+ }
+
+ /**
+ * Test VSSCheckout required attributes.
+ */
+ @Test
+ public void testCheckoutExceptions() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/optional/vss/vss.xml");
+ expectSpecificBuildException("vsscheckout.1", "some cause", "vsspath attribute must be set!");
+ expectSpecificBuildException("vsscheckout.2", "some cause", "blah is not a legal value for this attribute");
+ }
+
+ /** Tests Add commandline generation. */
+ @Test
+ public void testAddCommandLine() {
+ String[] sTestCmdLine = {SS_DIR + File.separator + MSVSS.SS_EXE, MSVSS.COMMAND_ADD,
+ project.getBaseDir().getAbsolutePath() + File.separator + LOCAL_PATH,
+ MSVSS.FLAG_AUTORESPONSE_DEF, MSVSS.FLAG_RECURSION,
+ MSVSS.FLAG_LOGIN + VSS_USERNAME + "," + VSS_PASSWORD, MSVSS.FLAG_COMMENT + "-"};
+
+ // Set up a VSSAdd task
+ MSVSSADD vssAdd = new MSVSSADD();
+ vssAdd.setProject(project);
+ vssAdd.setLogin(VSS_USERNAME + "," + VSS_PASSWORD);
+ vssAdd.setVsspath(DS_VSS_PROJECT_PATH);
+ vssAdd.setRecursive(true);
+ vssAdd.setSsdir(SS_DIR);
+ vssAdd.setWritable(false);
+ vssAdd.setLocalpath(new Path(project, LOCAL_PATH));
+
+ commandline = vssAdd.buildCmdLine();
+
+ checkCommandLines(sTestCmdLine, commandline.getCommandline());
+ }
+
+ /**
+ * Test VSSAdd required attributes.
+ */
+ @Test
+ public void testAddExceptions() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/optional/vss/vss.xml");
+ expectSpecificBuildException("vssadd.1", "some cause", "localPath attribute must be set!");
+ }
+
+ /** Tests CP commandline generation. */
+ @Test
+ public void testCpCommandLine() {
+ String[] sTestCmdLine = {MSVSS.SS_EXE, MSVSS.COMMAND_CP,
+ DS_VSS_PROJECT_PATH, MSVSS.FLAG_AUTORESPONSE_DEF, MSVSS.FLAG_LOGIN +
+ VSS_USERNAME};
+
+ // Set up a VSSCp task
+ MSVSSCP vssCp = new MSVSSCP();
+ vssCp.setProject(project);
+ vssCp.setLogin(VSS_USERNAME);
+ vssCp.setVsspath(DS_VSS_PROJECT_PATH);
+
+ commandline = vssCp.buildCmdLine();
+
+ checkCommandLines(sTestCmdLine, commandline.getCommandline());
+ }
+
+ /**
+ * Test VSSCP required attributes.
+ */
+ @Test
+ public void testCpExceptions() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/optional/vss/vss.xml");
+ expectSpecificBuildException("vsscp.1", "some cause", "vsspath attribute must be set!");
+ }
+
+ /** Tests Create commandline generation. */
+ @Test
+ public void testCreateCommandLine() {
+ String[] sTestCmdLine = { MSVSS.SS_EXE, MSVSS.COMMAND_CREATE,
+ DS_VSS_PROJECT_PATH, MSVSS.FLAG_COMMENT + SRC_COMMENT, MSVSS.FLAG_AUTORESPONSE_NO,
+ MSVSS.FLAG_QUIET, MSVSS.FLAG_LOGIN + VSS_USERNAME};
+
+ // Set up a VSSCreate task
+ MSVSSCREATE vssCreate = new MSVSSCREATE();
+ vssCreate.setProject(project);
+ vssCreate.setComment(SRC_COMMENT);
+ vssCreate.setLogin(VSS_USERNAME);
+ vssCreate.setVsspath(DS_VSS_PROJECT_PATH);
+ vssCreate.setFailOnError(true);
+ vssCreate.setAutoresponse("N");
+ vssCreate.setQuiet(true);
+
+ commandline = vssCreate.buildCmdLine();
+
+ checkCommandLines(sTestCmdLine, commandline.getCommandline());
+ }
+
+ /**
+ * Test VSSCreate required attributes.
+ */
+ @Test
+ public void testCreateExceptions() {
+ buildRule.configureProject("src/etc/testcases/taskdefs/optional/vss/vss.xml");
+ expectSpecificBuildException("vsscreate.1", "some cause", "vsspath attribute must be set!");
+ }
+
+ /**
+ * Iterate through the generated command line comparing it to reference one.
+ * @param sTestCmdLine The reference command line;
+ * @param sGeneratedCmdLine The generated command line;
+ */
+ private void checkCommandLines(String[] sTestCmdLine, String[] sGeneratedCmdLine) {
+ int testLength = sTestCmdLine.length;
+ int genLength = sGeneratedCmdLine.length;
+
+ int genIndex = 0;
+ int testIndex = 0;
+
+ while (testIndex < testLength) {
+ try {
+ if (sGeneratedCmdLine[genIndex].equals("")) {
+ genIndex++;
+ continue;
+ }
+ assertEquals("arg # " + testIndex,
+ sTestCmdLine[testIndex],
+ sGeneratedCmdLine[genIndex]);
+ testIndex++;
+ genIndex++;
+ } catch (ArrayIndexOutOfBoundsException aioob) {
+ fail("missing arg " + sTestCmdLine[testIndex]);
+ }
+ }
+
+ // Count the number of empty strings
+ int cnt = 0;
+ for (int i = 0; i < genLength; i++) {
+ if (sGeneratedCmdLine[i].equals("")) {
+ cnt++;
+ }
+ }
+ if (genLength - cnt > sTestCmdLine.length) {
+ // We have extra elements
+ fail("extra args");
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/AbstractFileSetTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/AbstractFileSetTest.java
new file mode 100644
index 00000000..aa4fd39c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/AbstractFileSetTest.java
@@ -0,0 +1,248 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types;
+
+import java.io.File;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+/**
+ * Base class for FileSetTest and DirSetTest.
+ *
+ * <p>This doesn't actually test much, mainly reference handling.
+ *
+ */
+
+public abstract class AbstractFileSetTest {
+
+ private Project project;
+
+
+ @Before
+ public void setUp() {
+ project = new Project();
+ project.setBasedir(".");
+ }
+
+ protected abstract AbstractFileSet getInstance();
+
+ protected final Project getProject() {
+ return project;
+ }
+
+ @Test
+ public final void testEmptyElementIfIsReference() {
+ AbstractFileSet f = getInstance();
+ f.setIncludes("**/*.java");
+ try {
+ f.setRefid(new Reference(getProject(), "dummyref"));
+ fail("Can add reference to "
+ + f.getDataTypeName()
+ + " with elements from setIncludes");
+ } catch (BuildException be) {
+ assertEquals("You must not specify more than one attribute "
+ + "when using refid", be.getMessage());
+ }
+
+ f = getInstance();
+ f.createPatternSet();
+ try {
+ f.setRefid(new Reference(getProject(), "dummyref"));
+ fail("Can add reference to "
+ + f.getDataTypeName()
+ + " with nested patternset element.");
+ } catch (BuildException be) {
+ assertEquals("You must not specify nested elements when "
+ + "using refid", be.getMessage());
+ }
+
+ f = getInstance();
+ f.createInclude();
+ try {
+ f.setRefid(new Reference(getProject(), "dummyref"));
+ fail("Can add reference to "
+ + f.getDataTypeName()
+ + " with nested include element.");
+ } catch (BuildException be) {
+ assertEquals("You must not specify more than one attribute "
+ + "when using refid", be.getMessage());
+ }
+
+ f = getInstance();
+ f.setRefid(new Reference(getProject(), "dummyref"));
+ try {
+ f.setIncludes("**/*.java");
+ fail("Can set includes in "
+ + f.getDataTypeName()
+ + " that is a reference.");
+ } catch (BuildException be) {
+ assertEquals("You must not specify more than one attribute "
+ + "when using refid", be.getMessage());
+ }
+ try {
+ f.setIncludesfile(new File("/a"));
+ fail("Can set includesfile in "
+ + f.getDataTypeName()
+ + " that is a reference.");
+ } catch (BuildException be) {
+ assertEquals("You must not specify more than one attribute "
+ + "when using refid", be.getMessage());
+ }
+ try {
+ f.setExcludes("**/*.java");
+ fail("Can set excludes in "
+ + f.getDataTypeName()
+ + " that is a reference.");
+ } catch (BuildException be) {
+ assertEquals("You must not specify more than one attribute "
+ + "when using refid", be.getMessage());
+ }
+ try {
+ f.setExcludesfile(new File("/a"));
+ fail("Can set excludesfile in "
+ + f.getDataTypeName()
+ + " that is a reference.");
+ } catch (BuildException be) {
+ assertEquals("You must not specify more than one attribute "
+ + "when using refid", be.getMessage());
+ }
+ try {
+ f.setDir(project.resolveFile("."));
+ fail("Can set dir in "
+ + f.getDataTypeName()
+ + " that is a reference.");
+ } catch (BuildException be) {
+ assertEquals("You must not specify more than one attribute "
+ + "when using refid", be.getMessage());
+ }
+ try {
+ f.createInclude();
+ fail("Can add nested include in "
+ + f.getDataTypeName()
+ + " that is a reference.");
+ } catch (BuildException be) {
+ assertEquals("You must not specify nested elements when using "
+ + "refid", be.getMessage());
+ }
+ try {
+ f.createExclude();
+ fail("Can add nested exclude in "
+ + f.getDataTypeName()
+ + " that is a reference.");
+ } catch (BuildException be) {
+ assertEquals("You must not specify nested elements when using "
+ + "refid", be.getMessage());
+ }
+ try {
+ f.createIncludesFile();
+ fail("Can add nested includesfile in "
+ + f.getDataTypeName()
+ + " that is a reference.");
+ } catch (BuildException be) {
+ assertEquals("You must not specify nested elements when using "
+ + "refid", be.getMessage());
+ }
+ try {
+ f.createExcludesFile();
+ fail("Can add nested excludesfile in "
+ + f.getDataTypeName()
+ + " that is a reference.");
+ } catch (BuildException be) {
+ assertEquals("You must not specify nested elements when using "
+ + "refid", be.getMessage());
+ }
+ try {
+ f.createPatternSet();
+ fail("Can add nested patternset in "
+ + f.getDataTypeName()
+ + " that is a reference.");
+ } catch (BuildException be) {
+ assertEquals("You must not specify nested elements when using "
+ + "refid", be.getMessage());
+ }
+ }
+
+ @Test
+ public void testCircularReferenceCheck() {
+ AbstractFileSet f = getInstance();
+ project.addReference("dummy", f);
+ f.setRefid(new Reference(getProject(), "dummy"));
+ try {
+ f.getDir(project);
+ fail("Can make " + f.getDataTypeName()
+ + " a Reference to itself.");
+ } catch (BuildException be) {
+ assertEquals("This data type contains a circular reference.",
+ be.getMessage());
+ }
+ try {
+ f.getDirectoryScanner(project);
+ fail("Can make " + f.getDataTypeName()
+ + " a Reference to itself.");
+ } catch (BuildException be) {
+ assertEquals("This data type contains a circular reference.",
+ be.getMessage());
+ }
+
+ // dummy1 --> dummy2 --> dummy3 --> dummy1
+ AbstractFileSet f1 = getInstance();
+ project.addReference("dummy1", f1);
+ f1.setRefid(new Reference(getProject(), "dummy2"));
+ AbstractFileSet f2 = getInstance();
+ project.addReference("dummy2", f2);
+ f2.setRefid(new Reference(getProject(), "dummy3"));
+ AbstractFileSet f3 = getInstance();
+ project.addReference("dummy3", f3);
+ f3.setRefid(new Reference(getProject(), "dummy1"));
+ try {
+ f1.getDir(project);
+ fail("Can make circular reference.");
+ } catch (BuildException be) {
+ assertEquals("This data type contains a circular reference.",
+ be.getMessage());
+ }
+ try {
+ f1.getDirectoryScanner(project);
+ fail("Can make circular reference.");
+ } catch (BuildException be) {
+ assertEquals("This data type contains a circular reference.",
+ be.getMessage());
+ }
+
+ // dummy1 --> dummy2 --> dummy3
+ // (which has the Project's basedir as root).
+ f1 = getInstance();
+ project.addReference("dummy1", f1);
+ f1.setRefid(new Reference(getProject(), "dummy2"));
+ f2 = getInstance();
+ project.addReference("dummy2", f2);
+ f2.setRefid(new Reference(getProject(), "dummy3"));
+ f3 = getInstance();
+ project.addReference("dummy3", f3);
+ f3.setDir(project.resolveFile("."));
+ File dir = f1.getDir(project);
+ assertEquals("Dir is basedir", dir, project.getBaseDir());
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/AddTypeTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/AddTypeTest.java
new file mode 100644
index 00000000..6c91a9af
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/AddTypeTest.java
@@ -0,0 +1,223 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types;
+
+import org.apache.tools.ant.AntAssert;
+import org.apache.tools.ant.BuildFileRule;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.taskdefs.condition.Condition;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.fail;
+
+public class AddTypeTest {
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/types/addtype.xml");
+ }
+
+ @Test
+ public void testAddPath() {
+ buildRule.executeTarget("addpath");
+ }
+
+ @Test
+ public void testAddCondition() {
+ buildRule.executeTarget("addcondition");
+ }
+
+ @Test
+ public void testAddFilter() {
+ buildRule.executeTarget("addfilter");
+ }
+
+ @Test
+ public void testAddSelector() {
+ buildRule.executeTarget("addselector");
+ }
+
+ @Test
+ public void testNestedA() {
+ buildRule.executeTarget("nested.a");
+ AntAssert.assertContains("add A called", buildRule.getLog());
+ }
+
+ @Test
+ public void testNestedB() {
+ buildRule.executeTarget("nested.b");
+ AntAssert.assertContains( "add B called", buildRule.getLog());
+ }
+
+ @Test
+ public void testNestedC() {
+ buildRule.executeTarget("nested.c");
+ AntAssert.assertContains( "add C called", buildRule.getLog());
+ }
+
+ @Test
+ public void testNestedAB() {
+ try {
+ buildRule.executeTarget("nested.ab");
+ fail("Build exception expected: Should have got ambiguous");
+ } catch (BuildException ex) {
+ AntAssert.assertContains("ambiguous", ex.getMessage());
+ }
+ }
+
+ @Test
+ public void testConditionType() {
+ buildRule.executeTarget("condition.type");
+ AntAssert.assertContains( "beforeafter", buildRule.getLog());
+ }
+
+ @Test
+ public void testConditionTask() {
+ buildRule.executeTarget("condition.task");
+ AntAssert.assertContains( "My Condition execution", buildRule.getLog());
+ }
+
+ @Test
+ public void testConditionConditionType() {
+ buildRule.executeTarget("condition.condition.type");
+ AntAssert.assertContains( "My Condition eval", buildRule.getLog());
+ }
+
+ @Test
+ public void testConditionConditionTask() {
+ try {
+ buildRule.executeTarget("condition.condition.task");
+ fail("Build exception expected: Task masking condition");
+ } catch (BuildException ex) {
+ AntAssert.assertContains("doesn't support the nested", ex.getMessage());
+ }
+ }
+
+ @Test
+ public void testAddConfigured() {
+ buildRule.executeTarget("myaddconfigured");
+ AntAssert.assertContains("value is Value Setexecute: value is Value Set",
+ buildRule.getLog());
+ }
+
+ @Test
+ public void testAddConfiguredValue() {
+ buildRule.executeTarget("myaddconfiguredvalue");
+ AntAssert.assertContains("value is Value Setexecute: value is Value Set",
+ buildRule.getLog());
+ }
+
+ @Test
+ public void testNamespace() {
+ buildRule.executeTarget("namespacetest");
+ }
+
+ // The following will be used as types and tasks
+
+ public static interface A {}
+ public static interface B {}
+ public static interface C extends A {}
+ public static interface AB extends A, B {}
+
+ public static class AImpl implements A{}
+ public static class BImpl implements B{}
+ public static class CImpl implements C{}
+ public static class ABImpl implements AB{}
+
+ public static class NestedContainer
+ extends Task
+ {
+ public void add(A el) {
+ log("add A called");
+ }
+ public void add(B el) {
+ log("add B called");
+ }
+ public void add(C el) {
+ log("add C called");
+ }
+ }
+
+ public static class MyCondition
+ implements Condition
+ {
+ Project project;
+ public void setProject(Project project) {
+ this.project = project;
+ }
+ public boolean eval() {
+ project.log("My Condition eval");
+ return true;
+ }
+ public void execute() {
+ project.log("My Condition execution");
+ }
+ }
+
+ public static class MyValue
+ {
+ private String text = "NOT SET YET";
+ public void addText(String text) {
+ this.text = text;
+ }
+ public String toString() {
+ return text;
+ }
+ }
+
+ public static class MyAddConfigured
+ extends Task
+ {
+ MyValue value;
+ public void addConfigured(MyValue value) {
+ log("value is " + value);
+ this.value = value;
+ }
+ public void add(MyValue value) {
+ throw new BuildException("Should not be called");
+ }
+ public void execute() {
+ log("execute: value is " + value);
+ }
+ }
+
+ public static class MyAddConfiguredValue
+ extends Task
+ {
+ MyValue value;
+ public void addConfiguredValue(MyValue value) {
+ log("value is " + value);
+ this.value = value;
+ }
+ public void addValue(MyValue value) {
+ throw new BuildException("Should not be called");
+ }
+ public void execute() {
+ log("execute: value is " + value);
+ }
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/AssertionsTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/AssertionsTest.java
new file mode 100644
index 00000000..4210fc1a
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/AssertionsTest.java
@@ -0,0 +1,125 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.BuildFileRule;
+import org.junit.Assume;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.apache.tools.ant.AntAssert.assertContains;
+import static org.junit.Assert.fail;
+
+/**
+ * test assertion handling
+ */
+public class AssertionsTest {
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/types/assertions.xml");
+ }
+
+
+ /**
+ * runs a test and expects an assertion thrown in forked code
+ * @param target
+ */
+ private void expectAssertion(String target) {
+ try {
+ buildRule.executeTarget(target);
+ fail("BuildException should have been thrown by assertion fail in task");
+ } catch (BuildException ex) {
+ assertContains("assertion not thrown in "+target, "Java returned: 1", ex.getMessage());
+ }
+ }
+
+ @Test
+ public void testClassname() {
+ expectAssertion("test-classname");
+ }
+
+ @Test
+ public void testPackage() {
+ expectAssertion("test-package");
+ }
+
+ @Test
+ public void testEmptyAssertions() {
+ buildRule.executeTarget("test-empty-assertions");
+ }
+
+ @Test
+ public void testDisable() {
+ buildRule.executeTarget("test-disable");
+ }
+
+ @Test
+ public void testOverride() {
+ expectAssertion("test-override");
+ }
+
+ @Test
+ public void testOverride2() {
+ buildRule.executeTarget("test-override2");
+ }
+
+ @Test
+ public void testReferences() {
+ expectAssertion("test-references");
+ }
+
+ @Test
+ public void testMultipleAssertions() {
+ try {
+ buildRule.executeTarget("test-multiple-assertions");
+ fail("BuildException should have been thrown by assertion fail in task");
+ } catch (BuildException ex) {
+ assertContains("multiple assertions rejected", "Only one assertion declaration is allowed", ex.getMessage());
+ }
+ }
+
+ @Test
+ public void testReferenceAbuse() {
+ try {
+ buildRule.executeTarget("test-reference-abuse");
+ fail("BuildException should have been thrown by reference abuse");
+ } catch (BuildException ex) {
+ assertContains("reference abuse rejected", "You must not specify", ex.getMessage());
+ }
+ }
+
+ @Test
+ public void testNofork() {
+ Assume.assumeFalse("ran Ant tests with -ea and this would fail spuriously", AssertionsTest.class.desiredAssertionStatus());
+ buildRule.executeTarget("test-nofork");
+ assertContains("Assertion statements are currently ignored in non-forked mode", buildRule.getLog());
+ }
+
+ @Test
+ public void testJUnit() {
+ buildRule.executeTarget("test-junit");
+ }
+}
+
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/CommandlineJavaTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/CommandlineJavaTest.java
new file mode 100644
index 00000000..c18ff5ee
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/CommandlineJavaTest.java
@@ -0,0 +1,191 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types;
+
+
+import org.apache.tools.ant.MagicNames;
+import org.apache.tools.ant.Project;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+/**
+ * JUnit testcases for org.apache.tools.ant.CommandlineJava
+ *
+ */
+public class CommandlineJavaTest {
+
+ private String cloneVm;
+
+
+ private Project project;
+
+ @Before
+ public void setUp() {
+ project = new Project();
+ project.setBasedir(System.getProperty("root"));
+ project.setProperty("build.sysclasspath", "ignore");
+ cloneVm = System.getProperty("ant.build.clonevm");
+ if (cloneVm != null) {
+ System.setProperty("ant.build.clonevm", "false");
+ }
+ }
+
+ @After
+ public void tearDown() {
+ if (cloneVm != null) {
+ System.setProperty("ant.build.clonevm", cloneVm);
+ }
+ }
+
+ @Test
+ public void testGetCommandline() throws Exception {
+ CommandlineJava c = new CommandlineJava();
+ c.createArgument().setValue("org.apache.tools.ant.CommandlineJavaTest");
+ c.setClassname("junit.textui.TestRunner");
+ c.createVmArgument().setValue("-Djava.compiler=NONE");
+ String[] s = c.getCommandline();
+ assertEquals("no classpath", 4, s.length);
+ /*
+ * After changing CommandlineJava to search for the java
+ * executable, I don't know, how to tests the value returned
+ * here without using the same logic as applied in the class
+ * itself.
+ *
+ * assertTrue("no classpath", "java", s[0]);
+ */
+ assertEquals("no classpath", "-Djava.compiler=NONE", s[1]);
+ assertEquals("no classpath", "junit.textui.TestRunner", s[2]);
+ assertEquals("no classpath",
+ "org.apache.tools.ant.CommandlineJavaTest", s[3]);
+ try {
+ c.clone();
+ } catch (NullPointerException ex) {
+ fail("cloning should work without classpath specified");
+ }
+
+ c.createClasspath(project).setLocation(project.resolveFile("build.xml"));
+ c.createClasspath(project).setLocation(project.resolveFile(
+ System.getProperty(MagicNames.ANT_HOME)+"/lib/ant.jar"));
+ s = c.getCommandline();
+ assertEquals("with classpath", 6, s.length);
+ // assertEquals("with classpath", "java", s[0]);
+ assertEquals("with classpath", "-Djava.compiler=NONE", s[1]);
+ assertEquals("with classpath", "-classpath", s[2]);
+ assertTrue("build.xml contained",
+ s[3].indexOf("build.xml"+java.io.File.pathSeparator) >= 0);
+ assertTrue("ant.jar contained", s[3].endsWith("ant.jar"));
+ assertEquals("with classpath", "junit.textui.TestRunner", s[4]);
+ assertEquals("with classpath",
+ "org.apache.tools.ant.CommandlineJavaTest", s[5]);
+ }
+
+ @Test
+ public void testJarOption() throws Exception {
+ CommandlineJava c = new CommandlineJava();
+ c.createArgument().setValue("arg1");
+ c.setJar("myfile.jar");
+ c.createVmArgument().setValue("-classic");
+ c.createVmArgument().setValue("-Dx=y");
+ String[] s = c.getCommandline();
+ assertEquals("-classic", s[1]);
+ assertEquals("-Dx=y", s[2]);
+ assertEquals("-jar", s[3]);
+ assertEquals("myfile.jar", s[4]);
+ assertEquals("arg1", s[5]);
+ }
+
+ @Test
+ public void testSysproperties() {
+ String currentClasspath = System.getProperty("java.class.path");
+ assertNotNull(currentClasspath);
+ assertNull(System.getProperty("key"));
+ CommandlineJava c = new CommandlineJava();
+ Environment.Variable v = new Environment.Variable();
+ v.setKey("key");
+ v.setValue("value");
+ c.addSysproperty(v);
+
+ project.setProperty("key2", "value2");
+ PropertySet ps = new PropertySet();
+ ps.setProject(project);
+ ps.appendName("key2");
+ c.addSyspropertyset(ps);
+
+ try {
+ c.setSystemProperties();
+ String newClasspath = System.getProperty("java.class.path");
+ assertNotNull(newClasspath);
+ assertEquals(currentClasspath, newClasspath);
+ assertNotNull(System.getProperty("key"));
+ assertEquals("value", System.getProperty("key"));
+ assertTrue(System.getProperties().containsKey("java.class.path"));
+ assertNotNull(System.getProperty("key2"));
+ assertEquals("value2", System.getProperty("key2"));
+ } finally {
+ c.restoreSystemProperties();
+ }
+ assertNull(System.getProperty("key"));
+ assertNull(System.getProperty("key2"));
+ }
+
+ @Test
+ public void testAssertions() throws Exception {
+ CommandlineJava c = new CommandlineJava();
+ c.createArgument().setValue("org.apache.tools.ant.CommandlineJavaTest");
+ c.setClassname("junit.textui.TestRunner");
+ c.createVmArgument().setValue("-Djava.compiler=NONE");
+ Assertions a = new Assertions();
+ a.setProject(project);
+ Assertions.EnabledAssertion ea = new Assertions.EnabledAssertion();
+ ea.setClass("junit.textui.TestRunner");
+ a.addEnable(ea);
+ c.setAssertions(a);
+
+ String[] expected = new String[] {
+ null,
+ "-Djava.compiler=NONE",
+ "-ea:junit.textui.TestRunner",
+ "junit.textui.TestRunner",
+ "org.apache.tools.ant.CommandlineJavaTest",
+ };
+
+ // only the second iteration would pass because of PR 27218
+ for (int i = 0; i < 3; i++) {
+ String[] s = c.getCommandline();
+ assertEquals(expected.length, s.length);
+ for (int j = 1; j < expected.length; j++) {
+ assertEquals(expected[j], s[j]);
+ }
+ }
+ CommandlineJava c2 = (CommandlineJava) c.clone();
+ String[] s = c2.getCommandline();
+ assertEquals(expected.length, s.length);
+ for (int j = 1; j < expected.length; j++) {
+ assertEquals(expected[j], s[j]);
+ }
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/CommandlineTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/CommandlineTest.java
new file mode 100644
index 00000000..e8e44429
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/CommandlineTest.java
@@ -0,0 +1,180 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types;
+
+import org.apache.tools.ant.BuildException;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+import static org.junit.Assert.assertNotNull;
+
+/**
+ * JUnit 3 testcases for org.apache.tools.ant.CommandLine
+ *
+ */
+public class CommandlineTest {
+
+ @Test
+ public void testTokenizer() {
+ String[] s = Commandline.translateCommandline("1 2 3");
+ assertEquals("Simple case", 3, s.length);
+ for (int i=0; i<3; i++) {
+ assertEquals(""+(i+1), s[i]);
+ }
+
+ s = Commandline.translateCommandline("");
+ assertEquals("empty string", 0, s.length);
+
+ s = Commandline.translateCommandline(null);
+ assertEquals("null", 0, s.length);
+
+ s = Commandline.translateCommandline("1 \'2\' 3");
+ assertEquals("Simple case with single quotes", 3, s.length);
+ assertEquals("Single quotes have been stripped", "2", s[1]);
+
+ s = Commandline.translateCommandline("1 \"2\" 3");
+ assertEquals("Simple case with double quotes", 3, s.length);
+ assertEquals("Double quotes have been stripped", "2", s[1]);
+
+ s = Commandline.translateCommandline("1 \"2 3\" 4");
+ assertEquals("Case with double quotes and whitespace", 3, s.length);
+ assertEquals("Double quotes stripped, space included", "2 3", s[1]);
+
+ s = Commandline.translateCommandline("1 \"2\'3\" 4");
+ assertEquals("Case with double quotes around single quote", 3, s.length);
+ assertEquals("Double quotes stripped, single quote included", "2\'3",
+ s[1]);
+
+ s = Commandline.translateCommandline("1 \'2 3\' 4");
+ assertEquals("Case with single quotes and whitespace", 3, s.length);
+ assertEquals("Single quotes stripped, space included", "2 3", s[1]);
+
+ s = Commandline.translateCommandline("1 \'2\"3\' 4");
+ assertEquals("Case with single quotes around double quote", 3, s.length);
+ assertEquals("Single quotes stripped, double quote included", "2\"3",
+ s[1]);
+
+ // \ doesn't have a special meaning anymore - this is different from
+ // what the Unix sh does but causes a lot of problems on DOS
+ // based platforms otherwise
+ s = Commandline.translateCommandline("1 2\\ 3 4");
+ assertEquals("case with quoted whitespace", 4, s.length);
+ assertEquals("backslash included", "2\\", s[1]);
+
+ // "" should become a single empty argument, same for ''
+ // PR 5906
+ s = Commandline.translateCommandline("\"\" a");
+ assertEquals("Doublequoted null arg prepend", 2, s.length);
+ assertEquals("Doublequoted null arg prepend", "", s[0]);
+ assertEquals("Doublequoted null arg prepend", "a", s[1]);
+ s = Commandline.translateCommandline("a \"\"");
+ assertEquals("Doublequoted null arg append", 2, s.length);
+ assertEquals("Doublequoted null arg append", "a", s[0]);
+ assertEquals("Doublequoted null arg append", "", s[1]);
+ s = Commandline.translateCommandline("\"\"");
+ assertEquals("Doublequoted null arg", 1, s.length);
+ assertEquals("Doublequoted null arg", "", s[0]);
+
+ s = Commandline.translateCommandline("\'\' a");
+ assertEquals("Singlequoted null arg prepend", 2, s.length);
+ assertEquals("Singlequoted null arg prepend", "", s[0]);
+ assertEquals("Singlequoted null arg prepend", "a", s[1]);
+ s = Commandline.translateCommandline("a \'\'");
+ assertEquals("Singlequoted null arg append", 2, s.length);
+ assertEquals("Singlequoted null arg append", "a", s[0]);
+ assertEquals("Singlequoted null arg append", "", s[1]);
+ s = Commandline.translateCommandline("\'\'");
+ assertEquals("Singlequoted null arg", 1, s.length);
+ assertEquals("Singlequoted null arg", "", s[0]);
+
+ // now to the expected failures
+
+ try {
+ Commandline.translateCommandline("a \'b c");
+ fail("unbalanced single quotes undetected");
+ } catch (BuildException be) {
+ assertEquals("unbalanced quotes in a \'b c", be.getMessage());
+ }
+
+ try {
+ Commandline.translateCommandline("a \"b c");
+ fail("unbalanced double quotes undetected");
+ } catch (BuildException be) {
+ assertEquals("unbalanced quotes in a \"b c", be.getMessage());
+ }
+ }
+
+ @Test
+ public void testToString() {
+ assertEquals("", Commandline.toString(new String[0]));
+ assertEquals("", Commandline.toString(null));
+ assertEquals("1 2 3", Commandline.toString(new String[] {"1", "2", "3"}));
+ assertEquals("1 \"2 3\"", Commandline.toString(new String[] {"1", "2 3"}));
+ assertEquals("1 \"2\'3\"", Commandline.toString(new String[] {"1", "2\'3"}));
+ assertEquals("1 \'2\"3\'", Commandline.toString(new String[] {"1", "2\"3"}));
+ }
+
+ @Test
+ public void testAwkCommand() {
+ Commandline c = new Commandline();
+ c.setExecutable("awk");
+ c.createArgument().setValue("'NR == 2 { print $NF }'");
+ String[] s = c.getCommandline();
+ assertNotNull(s);
+ assertEquals(2, s.length);
+ assertEquals("awk", s[0]);
+ assertEquals("'NR == 2 { print $NF }'", s[1]);
+ }
+
+ @Test
+ public void testPrefix() {
+ Commandline c = new Commandline();
+ Commandline.Argument a = c.createArgument();
+ a.setValue("foo");
+ a.setPrefix("-f=");
+ String[] s = c.getCommandline();
+ assertEquals(1, s.length);
+ assertEquals("-f=foo", s[0]);
+ }
+
+ @Test
+ public void testSuffix() {
+ Commandline c = new Commandline();
+ Commandline.Argument a = c.createArgument();
+ a.setValue("foo");
+ a.setSuffix(",1");
+ String[] s = c.getCommandline();
+ assertEquals(1, s.length);
+ assertEquals("foo,1", s[0]);
+ }
+
+ @Test
+ public void testPrefixSuffixLine() {
+ Commandline c = new Commandline();
+ Commandline.Argument a = c.createArgument();
+ a.setLine("one two");
+ a.setPrefix("number ");
+ a.setSuffix(".");
+ String[] s = c.getCommandline();
+ assertEquals(2, s.length);
+ assertEquals("number one.", s[0]);
+ assertEquals("number two.", s[1]);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/DescriptionTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/DescriptionTest.java
new file mode 100644
index 00000000..90dbce7f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/DescriptionTest.java
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types;
+
+import org.apache.tools.ant.BuildFileRule;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * FilterSet testing
+ *
+ */
+public class DescriptionTest {
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ @Test
+ public void test1() {
+ buildRule.configureProject("src/etc/testcases/types/description1.xml");
+ assertEquals("Single description failed", "Test Project Description", buildRule.getProject().getDescription());
+ }
+
+ @Test
+ public void test2() {
+ buildRule.configureProject("src/etc/testcases/types/description2.xml");
+ assertEquals("Multi line description failed", "Multi Line\nProject Description", buildRule.getProject().getDescription());
+ }
+
+ @Test
+ public void test3() {
+ buildRule.configureProject("src/etc/testcases/types/description3.xml");
+ assertEquals("Multi instance description failed", "Multi Instance Project Description", buildRule.getProject().getDescription());
+ }
+
+ @Test
+ public void test4() {
+ buildRule.configureProject("src/etc/testcases/types/description4.xml");
+ assertEquals("Multi instance nested description failed", "Multi Instance Nested Project Description", buildRule.getProject().getDescription());
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/DirSetTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/DirSetTest.java
new file mode 100644
index 00000000..8c659ba7
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/DirSetTest.java
@@ -0,0 +1,94 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import org.apache.tools.ant.BuildException;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+/**
+ * JUnit 3 testcases for org.apache.tools.ant.types.DirSet.
+ *
+ */
+public class DirSetTest extends AbstractFileSetTest {
+
+ protected AbstractFileSet getInstance() {
+ return new DirSet();
+ }
+
+ @Test
+ public void testFileSetIsNoDirSet() {
+ DirSet ds = (DirSet) getInstance();
+ ds.setProject(getProject());
+ FileSet fs = new FileSet();
+ fs.setProject(getProject());
+ getProject().addReference("dummy", fs);
+ ds.setRefid(new Reference(getProject(), "dummy"));
+ try {
+ ds.getDir(getProject());
+ fail("DirSet created from FileSet reference");
+ } catch (BuildException e) {
+ assertEquals("dummy doesn\'t denote a DirSet", e.getMessage());
+ }
+
+ ds = (DirSet) getInstance();
+ ds.setProject(getProject());
+ getProject().addReference("dummy2", ds);
+ fs.setRefid(new Reference(getProject(), "dummy2"));
+ try {
+ fs.getDir(getProject());
+ fail("FileSet created from DirSet reference");
+ } catch (BuildException e) {
+ assertEquals("dummy2 doesn\'t denote a FileSet", e.getMessage());
+ }
+ }
+
+ public void testToString() throws Exception {
+ File tmp = File.createTempFile("DirSetTest", "");
+ try {
+ tmp.delete();
+ File a = new File(tmp, "a");
+ a.mkdirs();
+ File b = new File(tmp, "b");
+ File bc = new File(b, "c");
+ bc.mkdirs();
+ new FileOutputStream(new File(a, "x")).close();
+ new FileOutputStream(new File(b, "x")).close();
+ new FileOutputStream(new File(bc, "x")).close();
+ DirSet ds = new DirSet();
+ ds.setProject(getProject());
+ ds.setDir(tmp);
+ ds.setIncludes("b/");
+ assertEquals("b;b" + File.separator + "c", ds.toString());
+ } finally {
+ new File(tmp, "a/x").delete();
+ new File(tmp, "a").delete();
+ new File(tmp, "b/c/x").delete();
+ new File(tmp, "b/c").delete();
+ new File(tmp, "b/x").delete();
+ new File(tmp, "b").delete();
+ tmp.delete();
+ }
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/EnumeratedAttributeTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/EnumeratedAttributeTest.java
new file mode 100644
index 00000000..0e2e241e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/EnumeratedAttributeTest.java
@@ -0,0 +1,106 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types;
+
+
+import org.apache.tools.ant.BuildException;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+/**
+ * JUnit testcases for org.apache.tools.ant.EnumeratedAttribute.
+ */
+public class EnumeratedAttributeTest {
+
+ private static String[] expected = {"a", "b", "c"};
+
+ @Test
+ public void testContains() {
+ EnumeratedAttribute t1 = new TestNormal();
+ for (int i=0; i<expected.length; i++) {
+ assertTrue(expected[i]+" is in TestNormal",
+ t1.containsValue(expected[i]));
+ assertTrue(expected[i].toUpperCase()+" is in TestNormal",
+ !t1.containsValue(expected[i].toUpperCase()));
+ }
+ assertTrue("TestNormal doesn\'t have \"d\" attribute",
+ !t1.containsValue("d"));
+ assertTrue("TestNull doesn\'t have \"d\" attribute and doesn\'t die",
+ !(new TestNull()).containsValue("d"));
+ }
+
+ @Test
+ public void testFactory() {
+ Factory ea = (Factory)EnumeratedAttribute.getInstance(Factory.class, "one");
+ assertEquals("Factory did not set the right value.", ea.getValue(), "one");
+ try {
+ EnumeratedAttribute.getInstance(Factory.class, "illegal");
+ fail("Factory should fail when trying to set an illegal value.");
+ } catch (BuildException be) {
+ // was expected
+ //TODO assert exception message
+ }
+ }
+
+ @Test
+ public void testExceptions() {
+ EnumeratedAttribute t1 = new TestNormal();
+ for (int i=0; i<expected.length; i++) {
+ try {
+ t1.setValue(expected[i]);
+ } catch (BuildException be) {
+ fail("unexpected exception for value "+expected[i]);
+ }
+ }
+ try {
+ t1.setValue("d");
+ fail("expected exception for value \"d\"");
+ } catch (BuildException be) {
+ //TODO assert build exception
+ }
+ try {
+ (new TestNull()).setValue("d");
+ fail("expected exception for value \"d\" in TestNull");
+ } catch (BuildException be) {
+ //TODO assert exception message
+ }
+ }
+
+ public static class TestNormal extends EnumeratedAttribute {
+ public String[] getValues() {
+ return expected;
+ }
+ }
+
+ public static class TestNull extends EnumeratedAttribute {
+ public String[] getValues() {
+ return null;
+ }
+ }
+
+ public static class Factory extends EnumeratedAttribute {
+ public String[] getValues() {
+ return new String[] { "one", "two", "three" };
+ }
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/FileListTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/FileListTest.java
new file mode 100644
index 00000000..463ba782
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/FileListTest.java
@@ -0,0 +1,163 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.BuildFileRule;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import java.io.File;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+/**
+ * Some tests for filelist.
+ */
+
+public class FileListTest {
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/types/filelist.xml");
+ }
+
+ @Test
+ public void testEmptyElementIfIsReference() {
+ FileList f = new FileList();
+ f.setDir(buildRule.getProject().resolveFile("."));
+ try {
+ f.setRefid(new Reference(buildRule.getProject(), "dummyref"));
+ fail("Can add reference to FileList with directory attribute set.");
+ } catch (BuildException be) {
+ assertEquals("You must not specify more than one attribute when using refid",
+ be.getMessage());
+ }
+
+ f = new FileList();
+ f.setFiles("foo.xml,c/d/bar.xml");
+ try {
+ f.setRefid(new Reference(buildRule.getProject(), "dummyref"));
+ fail("Can add reference to FileList with file attribute set.");
+ } catch (BuildException be) {
+ assertEquals("You must not specify more than one attribute when using refid",
+ be.getMessage());
+ }
+
+ f = new FileList();
+ f.setRefid(new Reference(buildRule.getProject(), "dummyref"));
+ try {
+ f.setFiles("a/b/foo.java");
+ fail("Can set files in FileList that is a reference.");
+ } catch (BuildException be) {
+ assertEquals("You must not specify more than one attribute when using refid",
+ be.getMessage());
+ }
+ try {
+ f.setDir(buildRule.getProject().resolveFile("."));
+ fail("Can set dir in FileList that is a reference.");
+ } catch (BuildException be) {
+ assertEquals("You must not specify more than one attribute when using refid",
+ be.getMessage());
+ }
+ }
+
+ @Test
+ public void testCircularReferenceCheck() {
+ FileList f = new FileList();
+ buildRule.getProject().addReference("dummy", f);
+ f.setRefid(new Reference(buildRule.getProject(), "dummy"));
+ try {
+ f.getDir(buildRule.getProject());
+ fail("Can make FileList a Reference to itself.");
+ } catch (BuildException be) {
+ assertEquals("This data type contains a circular reference.",
+ be.getMessage());
+ }
+ try {
+ f.getFiles(buildRule.getProject());
+ fail("Can make FileList a Reference to itself.");
+ } catch (BuildException be) {
+ assertEquals("This data type contains a circular reference.",
+ be.getMessage());
+ }
+
+ // dummy1 --> dummy2 --> dummy3 --> dummy1
+ FileList f1 = new FileList();
+ buildRule.getProject().addReference("dummy1", f1);
+ f1.setRefid(new Reference(buildRule.getProject(), "dummy2"));
+ FileList f2 = new FileList();
+ buildRule.getProject().addReference("dummy2", f2);
+ f2.setRefid(new Reference(buildRule.getProject(), "dummy3"));
+ FileList f3 = new FileList();
+ buildRule.getProject().addReference("dummy3", f3);
+ f3.setRefid(new Reference(buildRule.getProject(), "dummy1"));
+ try {
+ f1.getDir(buildRule.getProject());
+ fail("Can make circular reference.");
+ } catch (BuildException be) {
+ assertEquals("This data type contains a circular reference.",
+ be.getMessage());
+ }
+ try {
+ f1.getFiles(buildRule.getProject());
+ fail("Can make circular reference.");
+ } catch (BuildException be) {
+ assertEquals("This data type contains a circular reference.",
+ be.getMessage());
+ }
+
+ // dummy1 --> dummy2 --> dummy3
+ // (which has the Project's basedir as root).
+ f1 = new FileList();
+ buildRule.getProject().addReference("dummy1", f1);
+ f1.setRefid(new Reference(buildRule.getProject(), "dummy2"));
+ f2 = new FileList();
+ buildRule.getProject().addReference("dummy2", f2);
+ f2.setRefid(new Reference(buildRule.getProject(), "dummy3"));
+ f3 = new FileList();
+ buildRule.getProject().addReference("dummy3", f3);
+ f3.setDir(buildRule.getProject().resolveFile("."));
+ File dir = f1.getDir(buildRule.getProject());
+ assertEquals("Dir is basedir", dir, buildRule.getProject().getBaseDir());
+ }
+
+ @Test
+ public void testSimple() {
+ buildRule.executeTarget("simple");
+ assertEquals("/abc/a", buildRule.getLog());
+ }
+
+ @Test
+ public void testDouble() {
+ buildRule.executeTarget("double");
+ assertEquals("/abc/a:/abc/b", buildRule.getLog());
+ }
+
+ @Test
+ public void testNested() {
+ buildRule.executeTarget("nested");
+ assertEquals("/abc/a:/abc/b", buildRule.getLog());
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/FileSetTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/FileSetTest.java
new file mode 100644
index 00000000..8a1c35ac
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/FileSetTest.java
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types;
+
+
+/**
+ * JUnit 3 testcases for org.apache.tools.ant.types.FileSet.
+ *
+ * <p>This doesn't actually test much, mainly reference handling.
+ *
+ */
+
+public class FileSetTest extends AbstractFileSetTest {
+
+
+ protected AbstractFileSet getInstance() {
+ return new FileSet();
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/FilterSetTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/FilterSetTest.java
new file mode 100644
index 00000000..f4df4a38
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/FilterSetTest.java
@@ -0,0 +1,239 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.BuildFileRule;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.Hashtable;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+/**
+ * FilterSet testing
+ *
+ */
+public class FilterSetTest {
+
+ static private final int BUF_SIZE = 32768;
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/types/filterset.xml");
+ }
+
+ @After
+ public void tearDown() {
+ buildRule.executeTarget("cleanup");
+ }
+
+ @Test
+ public void test1() throws IOException {
+ buildRule.executeTarget("test1");
+ assertTrue("Filterset 1 failed", compareFiles("src/etc/testcases/types/gold/filterset1.txt",
+ "src/etc/testcases/types/dest1.txt"));
+ }
+
+ @Test
+ public void test2() throws IOException {
+ buildRule.executeTarget("test2");
+ assertTrue("Filterset 2 failed", compareFiles("src/etc/testcases/types/gold/filterset2.txt",
+ "src/etc/testcases/types/dest2.txt"));
+ }
+
+ @Test
+ public void test3() throws IOException {
+ buildRule.executeTarget("test3");
+ assertTrue("Filterset 3 failed", compareFiles("src/etc/testcases/types/gold/filterset3.txt",
+ "src/etc/testcases/types/dest3.txt"));
+ }
+
+ /**
+ * This will test the recursive FilterSet. Which means that if
+ * the filter value @test@ contains another filter value, it will
+ * actually resolve.
+ */
+ @Test
+ public void testRecursive() {
+ String result = "it works line";
+ String line="@test@ line";
+ FilterSet fs = new FilterSet();
+ fs.addFilter("test", "@test1@");
+ fs.addFilter("test1","@test2@");
+ fs.addFilter("test2", "it works");
+ fs.setBeginToken("@");
+ fs.setEndToken("@");
+ assertEquals(result, fs.replaceTokens(line));
+ }
+
+ /**
+ * Test to see what happens when the resolving occurs in an
+ * infinite loop.
+ */
+ @Test
+ public void testInfinite() {
+ String result = "@test@ line testvalue";
+ String line = "@test@ line @test3@";
+ FilterSet fs = new FilterSet();
+ fs.addFilter("test", "@test1@");
+ fs.addFilter("test1","@test2@");
+ fs.addFilter("test2", "@test@");
+ fs.addFilter("test3", "testvalue");
+ fs.setBeginToken("@");
+ fs.setEndToken("@");
+ assertEquals(result, fs.replaceTokens(line));
+ }
+
+ /**
+ * Test to see what happens when the resolving occurs in
+ * what would be an infinite loop, but with recursion disabled.
+ */
+ @Test
+ public void testRecursionDisabled() {
+ String result = "@test1@ line testvalue";
+ String line = "@test@ line @test2@";
+ FilterSet fs = new FilterSet();
+ fs.addFilter("test", "@test1@");
+ fs.addFilter("test1","@test@");
+ fs.addFilter("test2", "testvalue");
+ fs.setBeginToken("@");
+ fs.setEndToken("@");
+ fs.setRecurse(false);
+ assertEquals(result, fs.replaceTokens(line));
+ }
+
+ @Test
+ public void testNonInfiniteRecursiveMultipleOnSingleLine() {
+ FilterSet filters = new FilterSet();
+
+ filters.setBeginToken("<");
+ filters.setEndToken(">");
+
+ filters.addFilter("ul", "<itemizedlist>");
+ filters.addFilter("/ul", "</itemizedList>");
+ filters.addFilter("li", "<listitem>");
+ filters.addFilter("/li", "</listitem>");
+
+ String result = "<itemizedlist><listitem>Item 1</listitem> <listitem>Item 2</listitem></itemizedList>";
+ String line = "<ul><li>Item 1</li> <li>Item 2</li></ul>";
+
+ assertEquals(result, filters.replaceTokens(line));
+ }
+
+ @Test
+ public void testNestedFilterSets() {
+ buildRule.executeTarget("test-nested-filtersets");
+
+ FilterSet fs = (FilterSet) buildRule.getProject().getReference("1");
+ Hashtable filters = fs.getFilterHash();
+ assertEquals(1, filters.size());
+ assertEquals("value1", filters.get("token1"));
+
+ fs = (FilterSet) buildRule.getProject().getReference("2");
+ filters = fs.getFilterHash();
+ assertEquals(2, filters.size());
+ assertEquals("1111", filters.get("aaaa"));
+ assertEquals("2222", filters.get("bbbb"));
+
+ fs = (FilterSet) buildRule.getProject().getReference("3");
+ filters = fs.getFilterHash();
+ assertEquals(1, filters.size());
+ assertEquals("value4", filters.get("token4"));
+
+ fs = (FilterSet) buildRule.getProject().getReference("5");
+ filters = fs.getFilterHash();
+ assertEquals(1, filters.size());
+ assertEquals("value1", filters.get("token1"));
+ }
+
+ @Test
+ public void testFiltersFileElement() {
+ buildRule.executeTarget("testFiltersFileElement");
+ }
+
+ @Test
+ public void testFiltersFileAttribute() {
+ buildRule.executeTarget("testFiltersFileAttribute");
+ }
+
+ @Test
+ public void testMultipleFiltersFiles() {
+ buildRule.executeTarget("testMultipleFiltersFiles");
+ }
+
+ @Test
+ public void testMissingFiltersFile() {
+ try {
+ buildRule.executeTarget("testMissingFiltersFile");
+ fail("should fail due to missing filtersfile");
+ } catch (BuildException ex) {
+ //TODO assert exception text
+ }
+ }
+
+ @Test
+ public void testAllowMissingFiltersFile() {
+ buildRule.executeTarget("testAllowMissingFiltersFile");
+ }
+
+ private boolean compareFiles(String name1, String name2) throws IOException {
+ File file1 = new File(System.getProperty("root"), name1);
+ File file2 = new File(System.getProperty("root"), name2);
+
+
+ if (!file1.exists() || !file2.exists()) {
+ return false;
+ }
+
+ if (file1.length() != file2.length()) {
+ return false;
+ }
+
+ // byte - byte compare
+ byte[] buffer1 = new byte[BUF_SIZE];
+ byte[] buffer2 = new byte[BUF_SIZE];
+
+ FileInputStream fis1 = new FileInputStream(file1);
+ FileInputStream fis2 = new FileInputStream(file2);
+ int index = 0;
+ int read = 0;
+ while ((read = fis1.read(buffer1)) != -1) {
+ fis2.read(buffer2);
+ for (int i = 0; i < read; ++i, ++index) {
+ if (buffer1[i] != buffer2[i]) {
+ return false;
+ }
+ }
+ }
+ return true;
+
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/FlexIntegerTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/FlexIntegerTest.java
new file mode 100644
index 00000000..3e08b2cb
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/FlexIntegerTest.java
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types;
+
+import org.apache.tools.ant.BuildFileRule;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.BuildException;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class FlexIntegerTest {
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/types/flexinteger.xml");
+ }
+
+ @Test
+ public void testFlexInteger() {
+ buildRule.executeTarget("test");
+ assertEquals(buildRule.getProject().getProperty("flexint.value1"), "10");
+ assertEquals(buildRule.getProject().getProperty("flexint.value2"), "8");
+ }
+
+ // This class acts as a custom Ant task also
+ // and uses these variables/methods in that mode
+ private Project taskProject;
+ String propName;
+ private FlexInteger value;
+
+
+
+ public void setPropName(String propName) {
+ this.propName = propName;
+ }
+
+ public void setValue(FlexInteger value) {
+ this.value = value;
+ }
+
+ public void setProject(Project project) {
+ taskProject = project;
+ }
+
+ public void execute() {
+ if (propName == null || value == null) {
+ throw new BuildException("name and value required");
+ }
+
+ taskProject.setNewProperty(propName, value.toString());
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/MapperTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/MapperTest.java
new file mode 100644
index 00000000..980f5cc2
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/MapperTest.java
@@ -0,0 +1,235 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.BuildFileRule;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.util.ChainedMapper;
+import org.apache.tools.ant.util.FileNameMapper;
+import org.apache.tools.ant.util.FlatFileNameMapper;
+import org.apache.tools.ant.util.GlobPatternMapper;
+import org.apache.tools.ant.util.MergingMapper;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+/**
+ * JUnit testcases for org.apache.tools.ant.types.Mapper.
+ *
+ */
+
+public class MapperTest {
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ private Project project;
+
+ @Before
+ public void setUp() {
+ project = new Project();
+ project.setBasedir(".");
+ }
+
+ @Test
+ public void testEmptyElementIfIsReference() {
+ Mapper m = new Mapper(project);
+ m.setFrom("*.java");
+ try {
+ m.setRefid(new Reference(project, "dummyref"));
+ fail("Can add reference to Mapper with from attribute set");
+ } catch (BuildException be) {
+ assertEquals("You must not specify more than one attribute when using refid",
+ be.getMessage());
+ }
+
+ m = new Mapper(project);
+ m.setRefid(new Reference(project, "dummyref"));
+ try {
+ m.setFrom("*.java");
+ fail("Can set from in Mapper that is a reference.");
+ } catch (BuildException be) {
+ assertEquals("You must not specify more than one attribute when using refid",
+ be.getMessage());
+ }
+
+ m = new Mapper(project);
+ m.setRefid(new Reference(project, "dummyref"));
+ try {
+ m.setTo("*.java");
+ fail("Can set to in Mapper that is a reference.");
+ } catch (BuildException be) {
+ assertEquals("You must not specify more than one attribute when using refid",
+ be.getMessage());
+ }
+ try {
+ Mapper.MapperType mt = new Mapper.MapperType();
+ mt.setValue("glob");
+ m.setType(mt);
+ fail("Can set type in Mapper that is a reference.");
+ } catch (BuildException be) {
+ assertEquals("You must not specify more than one attribute when using refid",
+ be.getMessage());
+ }
+ }
+
+ @Test
+ public void testCircularReferenceCheck() {
+ Mapper m = new Mapper(project);
+ project.addReference("dummy", m);
+ m.setRefid(new Reference(project, "dummy"));
+ try {
+ m.getImplementation();
+ fail("Can make Mapper a Reference to itself.");
+ } catch (BuildException be) {
+ assertEquals("This data type contains a circular reference.",
+ be.getMessage());
+ }
+
+ // dummy1 --> dummy2 --> dummy3 --> dummy1
+ Mapper m1 = new Mapper(project);
+ project.addReference("dummy1", m1);
+ m1.setRefid(new Reference(project, "dummy2"));
+ Mapper m2 = new Mapper(project);
+ project.addReference("dummy2", m2);
+ m2.setRefid(new Reference(project, "dummy3"));
+ Mapper m3 = new Mapper(project);
+ project.addReference("dummy3", m3);
+ m3.setRefid(new Reference(project, "dummy1"));
+ try {
+ m1.getImplementation();
+ fail("Can make circular reference.");
+ } catch (BuildException be) {
+ assertEquals("This data type contains a circular reference.",
+ be.getMessage());
+ }
+
+ // dummy1 --> dummy2 --> dummy3
+ // (which holds a glob mapper from "*.java" to "*.class"
+ m1 = new Mapper(project);
+ project.addReference("dummy1", m1);
+ m1.setRefid(new Reference(project, "dummy2"));
+ m2 = new Mapper(project);
+ project.addReference("dummy2", m2);
+ m2.setRefid(new Reference(project, "dummy3"));
+ m3 = new Mapper(project);
+ project.addReference("dummy3", m3);
+ Mapper.MapperType mt = new Mapper.MapperType();
+ mt.setValue("glob");
+ m3.setType(mt);
+ m3.setFrom("*.java");
+ m3.setTo("*.class");
+ FileNameMapper fmm = m1.getImplementation();
+ assertTrue("should be glob", fmm instanceof GlobPatternMapper);
+ String[] result = fmm.mapFileName("a.java");
+ assertEquals("a.java should match", 1, result.length);
+ assertEquals("a.class", result[0]);
+ }
+
+ @Test
+ public void testNested() {
+ Mapper mapper1 = new Mapper(project);
+ Mapper.MapperType mt = new Mapper.MapperType();
+ mt.setValue("glob");
+ mapper1.setType(mt);
+ mapper1.setFrom("from*");
+ mapper1.setTo("to*");
+
+ //mix element types
+ FileNameMapper mapper2 = new FlatFileNameMapper();
+ FileNameMapper mapper3 = new MergingMapper();
+ mapper3.setTo("mergefile");
+
+ Mapper container = new Mapper(project);
+ container.addConfiguredMapper(mapper1);
+ container.add(mapper2);
+ container.add(mapper3);
+
+ FileNameMapper fileNameMapper = container.getImplementation();
+ String[] targets = fileNameMapper.mapFileName("fromfilename");
+ assertNotNull("no filenames mapped", targets);
+ assertEquals("wrong number of filenames mapped", 3, targets.length);
+ List list = Arrays.asList(targets);
+ assertTrue("cannot find expected target \"tofilename\"",
+ list.contains("tofilename"));
+ assertTrue("cannot find expected target \"fromfilename\"",
+ list.contains("fromfilename"));
+ assertTrue("cannot find expected target \"mergefile\"",
+ list.contains("mergefile"));
+ }
+
+ @Test
+ public void testChained() {
+
+ // a --> b --> c --- def
+ // \-- ghi
+
+ FileNameMapper mapperAB = new GlobPatternMapper();
+ mapperAB.setFrom("a");
+ mapperAB.setTo("b");
+
+ FileNameMapper mapperBC = new GlobPatternMapper();
+ mapperBC.setFrom("b");
+ mapperBC.setTo("c");
+
+ //implicit composite
+ Mapper mapperCX = new Mapper(project);
+
+ FileNameMapper mapperDEF = new GlobPatternMapper();
+ mapperDEF.setFrom("c");
+ mapperDEF.setTo("def");
+
+ FileNameMapper mapperGHI = new GlobPatternMapper();
+ mapperGHI.setFrom("c");
+ mapperGHI.setTo("ghi");
+
+ mapperCX.add(mapperDEF);
+ mapperCX.add(mapperGHI);
+
+ Mapper chained = new Mapper(project);
+ chained.setClassname(ChainedMapper.class.getName());
+ chained.add(mapperAB);
+ chained.add(mapperBC);
+ chained.addConfiguredMapper(mapperCX);
+
+ FileNameMapper fileNameMapper = chained.getImplementation();
+ String[] targets = fileNameMapper.mapFileName("a");
+ assertNotNull("no filenames mapped", targets);
+ assertEquals("wrong number of filenames mapped", 2, targets.length);
+ List list = Arrays.asList(targets);
+ assertTrue("cannot find expected target \"def\"", list.contains("def"));
+ assertTrue("cannot find expected target \"ghi\"", list.contains("ghi"));
+ }
+
+ @Test
+ public void testCopyTaskWithTwoFilesets() {
+ buildRule.configureProject("src/etc/testcases/types/mapper.xml");
+ buildRule.executeTarget("test1");
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/PathTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/PathTest.java
new file mode 100644
index 00000000..2ad1819c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/PathTest.java
@@ -0,0 +1,579 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types;
+
+import java.io.File;
+import java.util.Locale;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.condition.Os;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+/**
+ * JUnit testcases for org.apache.tools.ant.types.Path
+ *
+ */
+
+public class PathTest {
+
+ public static boolean isUnixStyle = File.pathSeparatorChar == ':';
+ public static boolean isNetWare = Os.isFamily("netware");
+
+ private Project project;
+
+ @Before
+ public void setUp() {
+ project = new Project();
+ project.setBasedir(System.getProperty("root"));
+ }
+
+ // actually tests constructor as well as setPath
+ @Test
+ public void testConstructorUnixStyle() {
+ Path p = new Path(project, "/a:/b");
+ String[] l = p.list();
+ assertEquals("two items, Unix style", 2, l.length);
+ if (isUnixStyle) {
+ assertEquals("/a", l[0]);
+ assertEquals("/b", l[1]);
+ } else if (isNetWare) {
+ assertEquals("\\a", l[0]);
+ assertEquals("\\b", l[1]);
+ } else {
+ String base = new File(File.separator).getAbsolutePath();
+ assertEquals(base + "a", l[0]);
+ assertEquals(base + "b", l[1]);
+ }
+ }
+
+ @Test
+ public void testRelativePathUnixStyle() {
+ project.setBasedir(new File(System.getProperty("root"), "src/etc").getAbsolutePath());
+ Path p = new Path(project, "..:testcases");
+ String[] l = p.list();
+ assertEquals("two items, Unix style", 2, l.length);
+ if (isUnixStyle) {
+ assertTrue("test resolved relative to src/etc",
+ l[0].endsWith("/src"));
+ assertTrue("test resolved relative to src/etc",
+ l[1].endsWith("/src/etc/testcases"));
+ } else if (isNetWare) {
+ assertTrue("test resolved relative to src/etc",
+ l[0].endsWith("\\src"));
+ assertTrue("test resolved relative to src/etc",
+ l[1].endsWith("\\src\\etc\\testcases"));
+ } else {
+ assertTrue("test resolved relative to src/etc",
+ l[0].endsWith("\\src"));
+ assertTrue("test resolved relative to src/etc",
+ l[1].endsWith("\\src\\etc\\testcases"));
+ }
+ }
+
+ @Test
+ public void testConstructorWindowsStyle() {
+ Path p = new Path(project, "\\a;\\b");
+ String[] l = p.list();
+ assertEquals("two items, DOS style", 2, l.length);
+ if (isUnixStyle) {
+ assertEquals("/a", l[0]);
+ assertEquals("/b", l[1]);
+ } else if (isNetWare) {
+ assertEquals("\\a", l[0]);
+ assertEquals("\\b", l[1]);
+ } else {
+ String base = new File(File.separator).getAbsolutePath();
+ assertEquals(base + "a", l[0]);
+ assertEquals(base + "b", l[1]);
+ }
+
+ p = new Path(project, "c:\\test");
+ l = p.list();
+ if (isUnixStyle) {
+ assertEquals("no drives on Unix", 2, l.length);
+ assertTrue("c resolved relative to project\'s basedir",
+ l[0].endsWith("/c"));
+ assertEquals("/test", l[1]);
+ } else if (isNetWare) {
+ assertEquals("volumes on NetWare", 1, l.length);
+ assertEquals("c:\\test", l[0].toLowerCase(Locale.US));
+ } else {
+ assertEquals("drives on DOS", 1, l.length);
+ assertEquals("c:\\test", l[0].toLowerCase(Locale.US));
+ }
+
+ p = new Path(project, "c:\\test;d:\\programs");
+ l = p.list();
+ if (isUnixStyle) {
+ assertEquals("no drives on Unix", 4, l.length);
+ assertTrue("c resolved relative to project\'s basedir",
+ l[0].endsWith("/c"));
+ assertEquals("/test", l[1]);
+ assertTrue("d resolved relative to project\'s basedir",
+ l[2].endsWith("/d"));
+ assertEquals("/programs", l[3]);
+ } else if (isNetWare) {
+ assertEquals("volumes on NetWare", 2, l.length);
+ assertEquals("c:\\test", l[0].toLowerCase(Locale.US));
+ assertEquals("d:\\programs", l[1].toLowerCase(Locale.US));
+ } else {
+ assertEquals("drives on DOS", 2, l.length);
+ assertEquals("c:\\test", l[0].toLowerCase(Locale.US));
+ assertEquals("d:\\programs", l[1].toLowerCase(Locale.US));
+ }
+
+ p = new Path(project, "c:/test");
+ l = p.list();
+ if (isUnixStyle) {
+ assertEquals("no drives on Unix", 2, l.length);
+ assertTrue("c resolved relative to project\'s basedir",
+ l[0].endsWith("/c"));
+ assertEquals("/test", l[1]);
+ } else if (isNetWare) {
+ assertEquals("volumes on NetWare", 1, l.length);
+ assertEquals("c:\\test", l[0].toLowerCase(Locale.US));
+ } else {
+ assertEquals("drives on DOS", 1, l.length);
+ assertEquals("c:\\test", l[0].toLowerCase(Locale.US));
+ }
+
+ p = new Path(project, "c:/test;d:/programs");
+ l = p.list();
+ if (isUnixStyle) {
+ assertEquals("no drives on Unix", 4, l.length);
+ assertTrue("c resolved relative to project\'s basedir",
+ l[0].endsWith("/c"));
+ assertEquals("/test", l[1]);
+ assertTrue("d resolved relative to project\'s basedir",
+ l[2].endsWith("/d"));
+ assertEquals("/programs", l[3]);
+ } else if (isNetWare) {
+ assertEquals("volumes on NetWare", 2, l.length);
+ assertEquals("c:\\test", l[0].toLowerCase(Locale.US));
+ assertEquals("d:\\programs", l[1].toLowerCase(Locale.US));
+ } else {
+ assertEquals("drives on DOS", 2, l.length);
+ assertEquals("c:\\test", l[0].toLowerCase(Locale.US));
+ assertEquals("d:\\programs", l[1].toLowerCase(Locale.US));
+ }
+ }
+
+ @Test
+ public void testConstructorNetWareStyle() {
+ // try a netware-volume length path, see how it is handled
+ Path p = new Path(project, "sys:\\test");
+ String[] l = p.list();
+ if (isUnixStyle) {
+ assertEquals("no drives on Unix", 2, l.length);
+ assertTrue("sys resolved relative to project\'s basedir",
+ l[0].endsWith("/sys"));
+ assertEquals("/test", l[1]);
+ } else if (isNetWare) {
+ assertEquals("sys:\\test", l[0].toLowerCase(Locale.US));
+ assertEquals("volumes on NetWare", 1, l.length);
+ } else {
+ assertEquals("no multiple character-length volumes on Windows", 2, l.length);
+ assertTrue("sys resolved relative to project\'s basedir",
+ l[0].endsWith("\\sys"));
+ assertTrue("test resolved relative to project\'s basedir",
+ l[1].endsWith("\\test"));
+ }
+
+ // try a multi-part netware-volume length path, see how it is handled
+ p = new Path(project, "sys:\\test;dev:\\temp");
+ l = p.list();
+ if (isUnixStyle) {
+ assertEquals("no drives on Unix", 4, l.length);
+ assertTrue("sys resolved relative to project\'s basedir",
+ l[0].endsWith("/sys"));
+ assertEquals("/test", l[1]);
+ assertTrue("dev resolved relative to project\'s basedir",
+ l[2].endsWith("/dev"));
+ assertEquals("/temp", l[3]);
+ } else if (isNetWare) {
+ assertEquals("volumes on NetWare", 2, l.length);
+ assertEquals("sys:\\test", l[0].toLowerCase(Locale.US));
+ assertEquals("dev:\\temp", l[1].toLowerCase(Locale.US));
+ } else {
+ assertEquals("no multiple character-length volumes on Windows", 4, l.length);
+ assertTrue("sys resolved relative to project\'s basedir",
+ l[0].endsWith("\\sys"));
+ assertTrue("test resolved relative to project\'s basedir",
+ l[1].endsWith("\\test"));
+ assertTrue("dev resolved relative to project\'s basedir",
+ l[2].endsWith("\\dev"));
+ assertTrue("temp resolved relative to project\'s basedir",
+ l[3].endsWith("\\temp"));
+ }
+
+ // try a netware-volume length path w/forward slash, see how it is handled
+ p = new Path(project, "sys:/test");
+ l = p.list();
+ if (isUnixStyle) {
+ assertEquals("no drives on Unix", 2, l.length);
+ assertTrue("sys resolved relative to project\'s basedir",
+ l[0].endsWith("/sys"));
+ assertEquals("/test", l[1]);
+ } else if (isNetWare) {
+ assertEquals("volumes on NetWare", 1, l.length);
+ assertEquals("sys:\\test", l[0].toLowerCase(Locale.US));
+ } else {
+ assertEquals("no multiple character-length volumes on Windows", 2, l.length);
+ assertTrue("sys resolved relative to project\'s basedir",
+ l[0].endsWith("\\sys"));
+ assertTrue("test resolved relative to project\'s basedir",
+ l[1].endsWith("\\test"));
+ }
+
+ // try a multi-part netware-volume length path w/forward slash, see how it is handled
+ p = new Path(project, "sys:/test;dev:/temp");
+ l = p.list();
+ if (isUnixStyle) {
+ assertEquals("no drives on Unix", 4, l.length);
+ assertTrue("sys resolved relative to project\'s basedir",
+ l[0].endsWith("/sys"));
+ assertEquals("/test", l[1]);
+ assertTrue("dev resolved relative to project\'s basedir",
+ l[2].endsWith("/dev"));
+ assertEquals("/temp", l[3]);
+ } else if (isNetWare) {
+ assertEquals("volumes on NetWare", 2, l.length);
+ assertEquals("sys:\\test", l[0].toLowerCase(Locale.US));
+ assertEquals("dev:\\temp", l[1].toLowerCase(Locale.US));
+ } else {
+ assertEquals("no multiple character-length volumes on Windows", 4, l.length);
+ assertTrue("sys resolved relative to project\'s basedir",
+ l[0].endsWith("\\sys"));
+ assertTrue("test resolved relative to project\'s basedir",
+ l[1].endsWith("\\test"));
+ assertTrue("dev resolved relative to project\'s basedir",
+ l[2].endsWith("\\dev"));
+ assertTrue("temp resolved relative to project\'s basedir",
+ l[3].endsWith("\\temp"));
+ }
+
+ // try a multi-part netware-volume length path with UNIX
+ // separator (this testcase if from an actual bug that was
+ // found, in AvailableTest, which uses PathTokenizer)
+ p = new Path(project,
+ "SYS:\\JAVA/lib/rt.jar:SYS:\\JAVA/lib/classes.zip");
+ l = p.list();
+ if (isUnixStyle) {
+ assertEquals("no drives on Unix", 3, l.length);
+ assertTrue("sys resolved relative to project\'s basedir",
+ l[0].endsWith("/SYS"));
+ assertEquals("/JAVA/lib/rt.jar", l[1]);
+ assertEquals("/JAVA/lib/classes.zip", l[2]);
+ } else if (isNetWare) {
+ assertEquals("volumes on NetWare", 2, l.length);
+ assertEquals("sys:\\java\\lib\\rt.jar", l[0].toLowerCase(Locale.US));
+ assertEquals("sys:\\java\\lib\\classes.zip", l[1].toLowerCase(Locale.US));
+ } else {
+ assertEquals("no multiple character-length volumes on Windows", 3, l.length);
+ assertTrue("sys resolved relative to project\'s basedir",
+ l[0].endsWith("\\SYS"));
+ assertTrue("java/lib/rt.jar resolved relative to project\'s basedir",
+ l[1].endsWith("\\JAVA\\lib\\rt.jar"));
+ assertTrue("java/lib/classes.zip resolved relative to project\'s basedir",
+ l[2].endsWith("\\JAVA\\lib\\classes.zip"));
+ }
+ }
+
+ @Test
+ public void testConstructorMixedStyle() {
+ Path p = new Path(project, "\\a;\\b:/c");
+ String[] l = p.list();
+ assertEquals("three items, mixed style", 3, l.length);
+ if (isUnixStyle) {
+ assertEquals("/a", l[0]);
+ assertEquals("/b", l[1]);
+ assertEquals("/c", l[2]);
+ } else if (isNetWare) {
+ assertEquals("\\a", l[0]);
+ assertEquals("\\b", l[1]);
+ assertEquals("\\c", l[2]);
+ } else {
+ String base = new File(File.separator).getAbsolutePath();
+ assertEquals(base + "a", l[0]);
+ assertEquals(base + "b", l[1]);
+ assertEquals(base + "c", l[2]);
+ }
+ }
+
+ @Test
+ public void testSetLocation() {
+ Path p = new Path(project);
+ p.setLocation(new File(File.separatorChar+"a"));
+ String[] l = p.list();
+ if (isUnixStyle) {
+ assertEquals(1, l.length);
+ assertEquals("/a", l[0]);
+ } else if (isNetWare) {
+ assertEquals(1, l.length);
+ assertEquals("\\a", l[0]);
+ } else {
+ assertEquals(1, l.length);
+ assertEquals(":\\a", l[0].substring(1));
+ }
+ }
+
+ @Test
+ public void testAppending() {
+ Path p = new Path(project, "/a:/b");
+ String[] l = p.list();
+ assertEquals("2 after construction", 2, l.length);
+ p.setLocation(new File("/c"));
+ l = p.list();
+ assertEquals("3 after setLocation", 3, l.length);
+ p.setPath("\\d;\\e");
+ l = p.list();
+ assertEquals("5 after setPath", 5, l.length);
+ p.append(new Path(project, "\\f"));
+ l = p.list();
+ assertEquals("6 after append", 6, l.length);
+ p.createPath().setLocation(new File("/g"));
+ l = p.list();
+ assertEquals("7 after append", 7, l.length);
+ }
+
+ @Test
+ public void testEmpyPath() {
+ Path p = new Path(project, "");
+ String[] l = p.list();
+ assertEquals("0 after construction", 0, l.length);
+ p.setPath("");
+ l = p.list();
+ assertEquals("0 after setPath", 0, l.length);
+ p.append(new Path(project));
+ l = p.list();
+ assertEquals("0 after append", 0, l.length);
+ p.createPath();
+ l = p.list();
+ assertEquals("0 after append", 0, l.length);
+ }
+
+ @Test
+ public void testUnique() {
+ Path p = new Path(project, "/a:/a");
+ String[] l = p.list();
+ assertEquals("1 after construction", 1, l.length);
+ String base = new File(File.separator).getAbsolutePath();
+ p.setLocation(new File(base, "a"));
+ l = p.list();
+ assertEquals("1 after setLocation", 1, l.length);
+ p.setPath("\\a;/a");
+ l = p.list();
+ assertEquals("1 after setPath", 1, l.length);
+ p.append(new Path(project, "/a;\\a:\\a"));
+ l = p.list();
+ assertEquals("1 after append", 1, l.length);
+ p.createPath().setPath("\\a:/a");
+ l = p.list();
+ assertEquals("1 after append", 1, l.length);
+ }
+
+ @Test
+ public void testEmptyElementIfIsReference() {
+ Path p = new Path(project, "/a:/a");
+ try {
+ p.setRefid(new Reference(project, "dummyref"));
+ fail("Can add reference to Path with elements from constructor");
+ } catch (BuildException be) {
+ assertEquals("You must not specify more than one attribute when using refid",
+ be.getMessage());
+ }
+
+ p = new Path(project);
+ p.setLocation(new File("/a"));
+ try {
+ p.setRefid(new Reference(project, "dummyref"));
+ fail("Can add reference to Path with elements from setLocation");
+ } catch (BuildException be) {
+ assertEquals("You must not specify more than one attribute when using refid",
+ be.getMessage());
+ }
+
+ Path another = new Path(project, "/a:/a");
+ project.addReference("dummyref", another);
+ p = new Path(project);
+ p.setRefid(new Reference(project, "dummyref"));
+ try {
+ p.setLocation(new File("/a"));
+ fail("Can set location in Path that is a reference.");
+ } catch (BuildException be) {
+ assertEquals("You must not specify more than one attribute when using refid",
+ be.getMessage());
+ }
+
+ try {
+ p.setPath("/a;\\a");
+ fail("Can set path in Path that is a reference.");
+ } catch (BuildException be) {
+ assertEquals("You must not specify more than one attribute when using refid",
+ be.getMessage());
+ }
+
+ try {
+ p.createPath();
+ fail("Can create nested Path in Path that is a reference.");
+ } catch (BuildException be) {
+ assertEquals("You must not specify nested elements when using refid",
+ be.getMessage());
+ }
+
+ try {
+ p.createPathElement();
+ fail("Can create nested PathElement in Path that is a reference.");
+ } catch (BuildException be) {
+ assertEquals("You must not specify nested elements when using refid",
+ be.getMessage());
+ }
+
+ try {
+ p.addFileset(new FileSet());
+ fail("Can add nested FileSet in Path that is a reference.");
+ } catch (BuildException be) {
+ assertEquals("You must not specify nested elements when using refid",
+ be.getMessage());
+ }
+
+ try {
+ p.addFilelist(new FileList());
+ fail("Can add nested FileList in Path that is a reference.");
+ } catch (BuildException be) {
+ assertEquals("You must not specify nested elements when using refid",
+ be.getMessage());
+ }
+
+ try {
+ p.addDirset(new DirSet());
+ fail("Can add nested Dirset in Path that is a reference.");
+ } catch (BuildException be) {
+ assertEquals("You must not specify nested elements when using refid",
+ be.getMessage());
+ }
+ }
+
+ @Test
+ public void testCircularReferenceCheck() {
+ Path p = new Path(project);
+ project.addReference("dummy", p);
+ p.setRefid(new Reference(project, "dummy"));
+ try {
+ p.list();
+ fail("Can make Path a Reference to itself.");
+ } catch (BuildException be) {
+ assertEquals("This data type contains a circular reference.",
+ be.getMessage());
+ }
+
+ // dummy1 --> dummy2 --> dummy3 --> dummy1
+ Path p1 = new Path(project);
+ project.addReference("dummy1", p1);
+ Path p2 = p1.createPath();
+ project.addReference("dummy2", p2);
+ Path p3 = p2.createPath();
+ project.addReference("dummy3", p3);
+ p3.setRefid(new Reference(project, "dummy1"));
+ try {
+ p1.list();
+ fail("Can make circular reference.");
+ } catch (BuildException be) {
+ assertEquals("This data type contains a circular reference.",
+ be.getMessage());
+ }
+
+ // dummy1 --> dummy2 --> dummy3 (with Path "/a")
+ p1 = new Path(project);
+ project.addReference("dummy1", p1);
+ p2 = p1.createPath();
+ project.addReference("dummy2", p2);
+ p3 = p2.createPath();
+ project.addReference("dummy3", p3);
+ p3.setLocation(new File("/a"));
+ String[] l = p1.list();
+ assertEquals("One element buried deep inside a nested path structure",
+ 1, l.length);
+ if (isUnixStyle) {
+ assertEquals("/a", l[0]);
+ } else if (isNetWare) {
+ assertEquals("\\a", l[0]);
+ } else {
+ assertEquals(":\\a", l[0].substring(1));
+ }
+ }
+
+ @Test
+ public void testFileList() {
+ Path p = new Path(project);
+ FileList f = new FileList();
+ f.setProject(project);
+ f.setDir(project.resolveFile("."));
+ f.setFiles("build.xml");
+ p.addFilelist(f);
+ String[] l = p.list();
+ assertEquals(1, l.length);
+ assertEquals(project.resolveFile("build.xml").getAbsolutePath(), l[0]);
+ }
+
+ @Test
+ public void testFileSet() {
+ Path p = new Path(project);
+ FileSet f = new FileSet();
+ f.setProject(project);
+ f.setDir(project.resolveFile("."));
+ f.setIncludes("build.xml");
+ p.addFileset(f);
+ String[] l = p.list();
+ assertEquals(1, l.length);
+ assertEquals(project.resolveFile("build.xml").getAbsolutePath(), l[0]);
+ }
+
+ @Test
+ public void testDirSet() {
+ Path p = new Path(project);
+ DirSet d = new DirSet();
+ d.setProject(project);
+ d.setDir(project.resolveFile("."));
+ d.setIncludes("build");
+ p.addDirset(d);
+ String[] l = p.list();
+ assertEquals(1, l.length);
+ assertEquals(project.resolveFile("build").getAbsolutePath(), l[0]);
+ }
+
+ @Test
+ public void testRecursion() {
+ Path p = new Path(project);
+ try {
+ p.append(p);
+ assertEquals(0, p.list().length);
+ } catch (BuildException x) {
+ String m = x.toString();
+ assertTrue(m, m.indexOf("circular") != -1);
+ }
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/PatternSetTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/PatternSetTest.java
new file mode 100644
index 00000000..065d757d
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/PatternSetTest.java
@@ -0,0 +1,206 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.File;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+/**
+ * JUnit 3 testcases for org.apache.tools.ant.types.PatternSet.
+ *
+ * <p>This doesn't actually test much, mainly reference handling.</p>
+ *
+ */
+
+public class PatternSetTest {
+
+ private Project project;
+
+ @Before
+ public void setUp() {
+ project = new Project();
+ project.setBasedir(".");
+ }
+
+ @Test
+ public void testEmptyElementIfIsReference() {
+ PatternSet p = new PatternSet();
+ p.setIncludes("**/*.java");
+ try {
+ p.setRefid(new Reference(project, "dummyref"));
+ fail("Can add reference to PatternSet with elements from setIncludes");
+ } catch (BuildException be) {
+ assertEquals("You must not specify more than one attribute when using refid",
+ be.getMessage());
+ }
+
+ p = new PatternSet();
+ p.setRefid(new Reference(project, "dummyref"));
+ try {
+ p.setIncludes("**/*.java");
+ fail("Can set includes in PatternSet that is a reference.");
+ } catch (BuildException be) {
+ assertEquals("You must not specify more than one attribute when using refid",
+ be.getMessage());
+ }
+
+ p = new PatternSet();
+ p.setRefid(new Reference(project, "dummyref"));
+ try {
+ p.setIncludesfile(new File("/a"));
+ fail("Can set includesfile in PatternSet that is a reference.");
+ } catch (BuildException be) {
+ assertEquals("You must not specify more than one attribute when using refid",
+ be.getMessage());
+ }
+ try {
+ p.setExcludes("**/*.java");
+ fail("Can set excludes in PatternSet that is a reference.");
+ } catch (BuildException be) {
+ assertEquals("You must not specify more than one attribute when using refid",
+ be.getMessage());
+ }
+ try {
+ p.setExcludesfile(new File("/a"));
+ fail("Can set excludesfile in PatternSet that is a reference.");
+ } catch (BuildException be) {
+ assertEquals("You must not specify more than one attribute when using refid",
+ be.getMessage());
+ }
+ try {
+ p.createInclude();
+ fail("Can add nested include in PatternSet that is a reference.");
+ } catch (BuildException be) {
+ assertEquals("You must not specify nested elements when using refid",
+ be.getMessage());
+ }
+ try {
+ p.createExclude();
+ fail("Can add nested exclude in PatternSet that is a reference.");
+ } catch (BuildException be) {
+ assertEquals("You must not specify nested elements when using refid",
+ be.getMessage());
+ }
+ try {
+ p.createIncludesFile();
+ fail("Can add nested includesfile in PatternSet that is a reference.");
+ } catch (BuildException be) {
+ assertEquals("You must not specify nested elements when using refid",
+ be.getMessage());
+ }
+ try {
+ p.createExcludesFile();
+ fail("Can add nested excludesfile in PatternSet that is a reference.");
+ } catch (BuildException be) {
+ assertEquals("You must not specify nested elements when using refid",
+ be.getMessage());
+ }
+ }
+
+ @Test
+ public void testCircularReferenceCheck() {
+ PatternSet p = new PatternSet();
+ project.addReference("dummy", p);
+ p.setRefid(new Reference(project, "dummy"));
+ try {
+ p.getIncludePatterns(project);
+ fail("Can make PatternSet a Reference to itself.");
+ } catch (BuildException be) {
+ assertEquals("This data type contains a circular reference.",
+ be.getMessage());
+ }
+ try {
+ p.getExcludePatterns(project);
+ fail("Can make PatternSet a Reference to itself.");
+ } catch (BuildException be) {
+ assertEquals("This data type contains a circular reference.",
+ be.getMessage());
+ }
+
+ // dummy1 --> dummy2 --> dummy3 --> dummy1
+ PatternSet p1 = new PatternSet();
+ project.addReference("dummy1", p1);
+ p1.setRefid(new Reference(project, "dummy2"));
+ PatternSet p2 = new PatternSet();
+ project.addReference("dummy2", p2);
+ p2.setRefid(new Reference(project, "dummy3"));
+ PatternSet p3 = new PatternSet();
+ project.addReference("dummy3", p3);
+ p3.setRefid(new Reference(project, "dummy1"));
+ try {
+ p1.getIncludePatterns(project);
+ fail("Can make circular reference.");
+ } catch (BuildException be) {
+ assertEquals("This data type contains a circular reference.",
+ be.getMessage());
+ }
+ try {
+ p1.getExcludePatterns(project);
+ fail("Can make circular reference.");
+ } catch (BuildException be) {
+ assertEquals("This data type contains a circular reference.",
+ be.getMessage());
+ }
+
+ // dummy1 --> dummy2 --> dummy3
+ // (which holds patterns "include" and "exclude")
+ p1 = new PatternSet();
+ project.addReference("dummy1", p1);
+ p1.setRefid(new Reference(project, "dummy2"));
+ p2 = new PatternSet();
+ project.addReference("dummy2", p2);
+ p2.setRefid(new Reference(project, "dummy3"));
+ p3 = new PatternSet();
+ project.addReference("dummy3", p3);
+ p3.setIncludes("include");
+ p3.createExclude().setName("exclude");
+ String[] i = p1.getIncludePatterns(project);
+ assertEquals("One include pattern buried deep inside a nested patternset structure",
+ 1, i.length);
+ assertEquals("include", i[0]);
+ i = p3.getExcludePatterns(project);
+ assertEquals("One exclude pattern buried deep inside a nested patternset structure",
+ 1, i.length);
+ assertEquals("exclude", i[0]);
+ }
+
+ @Test
+ public void testNestedPatternset() {
+ PatternSet p = new PatternSet();
+ p.setIncludes("**/*.java");
+
+ PatternSet nested = new PatternSet();
+ nested.setExcludes("**/*.class");
+
+ p.addConfiguredPatternset(nested);
+
+ String[] excludes = p.getExcludePatterns(project);
+ String[] includes = p.getIncludePatterns(project);
+
+ assertEquals("Includes","**/*.java", includes[0]);
+ assertEquals("Excludes","**/*.class", excludes[0]);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/PermissionsTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/PermissionsTest.java
new file mode 100644
index 00000000..1e43fe1a
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/PermissionsTest.java
@@ -0,0 +1,158 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types;
+
+import org.apache.tools.ant.ExitException;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.fail;
+
+/**
+ * JUnit 3 testcases for org.apache.tools.ant.types.Permissions.
+ *
+ */
+public class PermissionsTest {
+
+ Permissions perms;
+
+ @Before
+ public void setUp() {
+ perms = new Permissions();
+ Permissions.Permission perm = new Permissions.Permission();
+ // Grant extra permissions to read and write the user.* properties and read to the
+ // java.home property
+ perm.setActions("read, write");
+ perm.setName("user.*");
+ perm.setClass("java.util.PropertyPermission");
+ perms.addConfiguredGrant(perm);
+
+ perm = new Permissions.Permission();
+ perm.setActions("read");
+ perm.setName("java.home");
+ perm.setClass("java.util.PropertyPermission");
+ perms.addConfiguredGrant(perm);
+
+ perm = new Permissions.Permission();
+ perm.setActions("read");
+ perm.setName("file.encoding");
+ perm.setClass("java.util.PropertyPermission");
+ perms.addConfiguredGrant(perm);
+
+ // Revoke permission to write user.home (granted above via user.*), still able to read though.
+ // and the default granted permission to read os.name.
+ perm = new Permissions.Permission();
+ perm.setActions("write");
+ perm.setName("user.home");
+ perm.setClass("java.util.PropertyPermission");
+ perms.addConfiguredRevoke(perm);
+
+ perm = new Permissions.Permission();
+ perm.setActions("read");
+ perm.setName("os.*");
+ perm.setClass("java.util.PropertyPermission");
+ perms.addConfiguredRevoke(perm);
+ }
+
+ /** Tests a permission that is granted per default. */
+ @Test
+ public void testDefaultGranted() {
+ perms.setSecurityManager();
+ try {
+ System.getProperty("line.separator");
+ } finally {
+ perms.restoreSecurityManager();
+ }
+ }
+
+ /** Tests a permission that has been granted later via wildcard. */
+ @Test
+ public void testGranted() {
+ perms.setSecurityManager();
+ try {
+ String s = System.getProperty("user.name");
+ System.setProperty("user.name", s);
+ } finally {
+ perms.restoreSecurityManager();
+ }
+ }
+
+ /** Tests a permission that has been granted and revoked later. */
+ @Test
+ public void testGrantedAndRevoked() {
+ perms.setSecurityManager();
+ try {
+ String s = System.getProperty("user.home");
+ System.setProperty("user.home", s);
+ fail("Could perform an action that should have been forbidden.");
+ } catch (SecurityException e){
+ // Was expected, test passes
+ } finally {
+ perms.restoreSecurityManager();
+ }
+ }
+
+ /** Tests a permission that is granted as per default but revoked later via wildcard. */
+ @Test
+ public void testDefaultRevoked() {
+ perms.setSecurityManager();
+ try {
+ System.getProperty("os.name");
+ fail("Could perform an action that should have been forbidden.");
+ } catch (SecurityException e){
+ // Was expected, test passes
+ } finally {
+ perms.restoreSecurityManager();
+ }
+ }
+ /** Tests a permission that has not been granted or revoked. */
+ @Test
+ public void testOther() {
+ String ls = System.getProperty("line.separator");
+ perms.setSecurityManager();
+ try {
+ System.setProperty("line.separator",ls);
+ fail("Could perform an action that should have been forbidden.");
+ } catch (SecurityException e){
+ //TODO assert exception message
+ // Was expected, test passes
+ } finally {
+ perms.restoreSecurityManager();
+ }
+ }
+
+ /** Tests an exit condition. */
+ @Test
+ public void testExit() {
+ perms.setSecurityManager();
+ try {
+ System.out.println("If this is the last line on standard out the testExit f.a.i.l.e.d");
+ System.exit(3);
+ fail("Totaly impossible that this fail is ever executed. Please let me know if it is!");
+ } catch (ExitException e) {
+ if (e.getStatus() != 3) {
+ fail("Received wrong exit status in Exit Exception.");
+ }
+ System.out.println("testExit successful.");
+ } finally {
+ perms.restoreSecurityManager();
+ }
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/PolyTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/PolyTest.java
new file mode 100644
index 00000000..0d5e2ceb
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/PolyTest.java
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types;
+
+import org.apache.tools.ant.AntAssert;
+import org.apache.tools.ant.BuildFileRule;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+public class PolyTest {
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/types/poly.xml");
+ }
+
+ @Test
+ public void testFileSet() {
+ buildRule.executeTarget("fileset");
+ AntAssert.assertContains( "types.FileSet", buildRule.getLog());
+ }
+
+ @Test
+ public void testFileSetAntType() {
+ buildRule.executeTarget("fileset-ant-type");
+ AntAssert.assertContains("types.PolyTest$MyFileSet", buildRule.getLog());
+ }
+
+ @Test
+ public void testPath() {
+ buildRule.executeTarget("path");
+ AntAssert.assertContains( "types.Path", buildRule.getLog());
+ }
+
+ @Test
+ public void testPathAntType() {
+ buildRule.executeTarget("path-ant-type");
+ AntAssert.assertContains( "types.PolyTest$MyPath", buildRule.getLog());
+ }
+
+ public static class MyFileSet extends FileSet {}
+
+ public static class MyPath extends Path {
+ public MyPath(Project project) {
+ super(project);
+ }
+ }
+
+ public static class MyTask extends Task {
+ public void addPath(Path path) {
+ log("class of path is " + path.getClass());
+ }
+ public void addFileset(FileSet fileset) {
+ log("class of fileset is " + fileset.getClass());
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/RedirectorElementTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/RedirectorElementTest.java
new file mode 100644
index 00000000..f4c2abe0
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/RedirectorElementTest.java
@@ -0,0 +1,86 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types;
+
+import org.apache.tools.ant.AntAssert;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.BuildFileRule;
+import org.apache.tools.ant.Project;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+public class RedirectorElementTest {
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/types/redirector.xml", Project.MSG_VERBOSE);
+ }
+
+ @Test
+ public void test1() {
+ buildRule.executeTarget("test1");
+ assertTrue((buildRule.getProject().<Object> getReference("test1")
+ instanceof RedirectorElement));
+ }
+
+ @Test
+ public void test2() {
+ try {
+ buildRule.executeTarget("test2");
+ fail("You must not specify more than one attribute when using refid");
+ } catch (BuildException ex) {
+ //TODO assert exception message
+ }
+ }
+
+ @Test
+ public void test3() {
+ try {
+ buildRule.executeTarget("test3");
+ fail("You must not specify nested elements when using refid");
+ } catch (BuildException ex) {
+ //TODO assert exception message
+ }
+ }
+
+ @Test
+ public void test4() {
+ buildRule.executeTarget("test4");
+ }
+
+ @Test
+ public void testLogInputString() {
+ buildRule.executeTarget("testLogInputString");
+ if (buildRule.getLog().indexOf("testLogInputString can-cat") >=0 ) {
+ AntAssert.assertContains("Using input string", buildRule.getFullLog());
+ }
+ }
+
+ @Test
+ public void testRefid() {
+ buildRule.executeTarget("testRefid");
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/ResourceOutputTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/ResourceOutputTest.java
new file mode 100644
index 00000000..b66335a3
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/ResourceOutputTest.java
@@ -0,0 +1,160 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.UnknownServiceException;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.Zip;
+import org.apache.tools.ant.types.resources.ImmutableResourceException;
+import org.apache.tools.ant.types.resources.PropertyResource;
+import org.apache.tools.ant.types.resources.StringResource;
+import org.apache.tools.ant.types.resources.URLResource;
+import org.apache.tools.ant.types.resources.ZipResource;
+import org.apache.tools.ant.util.FileUtils;
+import org.apache.tools.ant.util.ResourceUtils;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+public class ResourceOutputTest {
+
+ private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+ private static final File basedir = new File(System.getProperty("root"),
+ "src/etc/testcases/types/resources");
+
+ private Project project;
+
+ @Before
+ public void setUp() {
+ project = new Project();
+ project.init();
+ project.setUserProperty("basedir" , basedir.getAbsolutePath());
+ }
+
+ @Test
+ public void testresourceoutput() {
+ try {
+ testoutputbe(new Resource("foo"));
+ fail("should have caught UnsupportedOperationException");
+ } catch (UnsupportedOperationException e) {
+ //TODO assert exception message
+ }
+ }
+
+ @Test
+ public void teststringoutput1() {
+ StringResource r = new StringResource();
+ testoutputbe(r);
+ assertEquals("foo", r.getValue());
+ }
+
+ @Test
+ public void teststringoutput2() throws IOException {
+ StringResource r = new StringResource("bar");
+ try {
+ testoutput(r);
+ fail("should have caught ImmutableResourceException");
+ } catch (ImmutableResourceException e) {
+ //TODO assert exception message
+ }
+ assertEquals("bar", r.getValue());
+ }
+
+ @Test
+ public void testpropertyoutput1() {
+ PropertyResource r = new PropertyResource(project, "bar");
+ testoutputbe(r);
+ assertEquals("foo", project.getProperty("bar"));
+ }
+
+ @Test
+ public void testpropertyoutput2() throws IOException {
+ project.setNewProperty("bar", "bar");
+ PropertyResource r = new PropertyResource(project, "bar");
+ try {
+ testoutput(r);
+ fail("should have caught ImmutableResourceException");
+ } catch (ImmutableResourceException e) {
+ //TODO assert exception message
+ }
+ assertEquals("bar", project.getProperty("bar"));
+ }
+
+ @Test
+ public void testurloutput() throws IOException {
+ File f = project.resolveFile("testurloutput");
+ try {
+ FILE_UTILS.createNewFile(f);
+ testoutput(new URLResource(f));
+ fail("should have caught UnknownServiceException");
+ } catch (UnknownServiceException e) {
+ //TODO assert exception message
+ } finally {
+ if (!f.delete()) {
+ f.deleteOnExit();
+ }
+ }
+ }
+
+ @Test
+ public void testzipentryoutput() {
+ Zip z = new Zip();
+ z.setProject(project);
+ Zip.WhenEmpty create = new Zip.WhenEmpty();
+ create.setValue("create");
+ z.setWhenempty(create);
+ z.setBasedir(basedir);
+ z.setExcludes("**/*");
+ File f = project.resolveFile("foo");
+ z.setDestFile(f);
+ z.execute();
+ ZipResource r = new ZipResource();
+ r.setZipfile(f);
+ r.setName("foo");
+ try {
+ testoutputbe(r);
+ fail("should have caught UnsupportedOperationException");
+ } catch (UnsupportedOperationException e) {
+ //TODO assert exception message
+ } finally {
+ if (!f.delete()) {
+ f.deleteOnExit();
+ }
+ }
+ }
+
+ private void testoutputbe(Resource dest) {
+ try {
+ testoutput(dest);
+ } catch (IOException e) {
+ throw new BuildException(e);
+ }
+ }
+
+ private void testoutput(Resource dest) throws IOException {
+ ResourceUtils.copyResource(new StringResource("foo"), dest, null);
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/TarFileSetTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/TarFileSetTest.java
new file mode 100644
index 00000000..b30168aa
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/TarFileSetTest.java
@@ -0,0 +1,119 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types;
+
+import java.io.File;
+
+import org.apache.tools.ant.BuildException;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+/**
+ * JUnit 3 testcases for org.apache.tools.ant.types.TarFileSet.
+ *
+ * <p>This doesn't actually test much, mainly reference handling.
+ *
+ */
+
+public class TarFileSetTest extends AbstractFileSetTest {
+
+
+ protected AbstractFileSet getInstance() {
+ return new TarFileSet();
+ }
+
+ @Test
+ public final void testAttributes() {
+ TarFileSet f = (TarFileSet)getInstance();
+ //check that dir and src are incompatible
+ f.setSrc(new File("example.tar"));
+ try {
+ f.setDir(new File("examples"));
+ fail("can add dir to "
+ + f.getDataTypeName()
+ + " when a src is already present");
+ } catch (BuildException be) {
+ assertEquals("Cannot set both dir and src attributes",be.getMessage());
+ }
+ f = (TarFileSet)getInstance();
+ //check that dir and src are incompatible
+ f.setDir(new File("examples"));
+ try {
+ f.setSrc(new File("example.tar"));
+ fail("can add src to "
+ + f.getDataTypeName()
+ + " when a dir is already present");
+ } catch (BuildException be) {
+ assertEquals("Cannot set both dir and src attributes",be.getMessage());
+ }
+ //check that fullpath and prefix are incompatible
+ f = (TarFileSet)getInstance();
+ f.setSrc(new File("example.tar"));
+ f.setPrefix("/examples");
+ try {
+ f.setFullpath("/doc/manual/index.html");
+ fail("Can add fullpath to "
+ + f.getDataTypeName()
+ + " when a prefix is already present");
+ } catch (BuildException be) {
+ assertEquals("Cannot set both fullpath and prefix attributes", be.getMessage());
+ }
+ f = (TarFileSet)getInstance();
+ f.setSrc(new File("example.tar"));
+ f.setFullpath("/doc/manual/index.html");
+ try {
+ f.setPrefix("/examples");
+ fail("Can add prefix to "
+ + f.getDataTypeName()
+ + " when a fullpath is already present");
+ } catch (BuildException be) {
+ assertEquals("Cannot set both fullpath and prefix attributes", be.getMessage());
+ }
+ // check that reference tarfilesets cannot have specific attributes
+ f = (TarFileSet)getInstance();
+ f.setRefid(new Reference(getProject(), "test"));
+ try {
+ f.setSrc(new File("example.tar"));
+ fail("Can add src to "
+ + f.getDataTypeName()
+ + " when a refid is already present");
+ } catch (BuildException be) {
+ assertEquals("You must not specify more than one "
+ + "attribute when using refid", be.getMessage());
+ }
+ // check that a reference tarfileset gets the same attributes as the original
+ f = (TarFileSet)getInstance();
+ f.setSrc(new File("example.tar"));
+ f.setPrefix("/examples");
+ f.setFileMode("600");
+ f.setDirMode("530");
+ getProject().addReference("test",f);
+ TarFileSet zid=(TarFileSet)getInstance();
+ zid.setRefid(new Reference(getProject(), "test"));
+ assertTrue("src attribute copied by copy constructor",zid.getSrc(getProject()).equals(f.getSrc(getProject())));
+ assertTrue("prefix attribute copied by copy constructor",f.getPrefix(getProject()).equals(zid.getPrefix(getProject())));
+ assertTrue("file mode attribute copied by copy constructor",f.getFileMode(getProject())==zid.getFileMode(getProject()));
+ assertTrue("dir mode attribute copied by copy constructor",f.getDirMode(getProject())==zid.getDirMode(getProject()));
+ }
+
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/XMLCatalogBuildFileTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/XMLCatalogBuildFileTest.java
new file mode 100644
index 00000000..96c0c5d2
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/XMLCatalogBuildFileTest.java
@@ -0,0 +1,98 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types;
+
+import org.apache.tools.ant.BuildFileRule;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * testcases for org.apache.tools.ant.types.XMLCatalog
+ *
+ * @see org.apache.tools.ant.types.XMLCatalogTest
+ *
+ */
+public class XMLCatalogBuildFileTest {
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+
+
+ //
+ // Ensure that an external entity resolves as expected with NO
+ // XMLCatalog involvement:
+ //
+ // Transform an XML file that refers to the entity into a text
+ // file, stuff result into property: val1
+ //
+ @Test
+ public void testEntityNoCatalog() {
+ buildRule.configureProject("src/etc/testcases/types/xmlcatalog.xml");
+ buildRule.executeTarget("testentitynocatalog");
+ assertEquals("A stitch in time saves nine", buildRule.getProject().getProperty("val1"));
+ }
+
+ //
+ // Ensure that an external entity resolves as expected Using an
+ // XMLCatalog:
+ //
+ // Transform an XML file that refers to the entity into a text
+ // file, entity is listed in the XMLCatalog pointing to a
+ // different file. Stuff result into property: val2
+ //
+ @Test
+ public void testEntityWithCatalog() {
+ buildRule.configureProject("src/etc/testcases/types/xmlcatalog.xml");
+ buildRule.executeTarget("testentitywithcatalog");
+ assertEquals("No news is good news", buildRule.getProject().getProperty("val2"));
+ }
+
+ //
+ // Ensure that an external entity resolves as expected with NO
+ // XMLCatalog involvement:
+ //
+ // Transform an XML file that contains a reference to a _second_ XML file
+ // via the document() function. The _second_ XML file refers to an entity.
+ // Stuff result into the property: val3
+ //
+ @Test
+ public void testDocumentNoCatalog() {
+ buildRule.configureProject("src/etc/testcases/types/xmlcatalog.xml");
+ buildRule.executeTarget("testdocumentnocatalog");
+ assertEquals("A stitch in time saves nine", buildRule.getProject().getProperty("val3"));
+ }
+
+ //
+ // Ensure that an external entity resolves as expected Using an
+ // XMLCatalog:
+ //
+ // Transform an XML file that contains a reference to a _second_ XML file
+ // via the document() function. The _second_ XML file refers to an entity.
+ // The entity is listed in the XMLCatalog pointing to a different file.
+ // Stuff result into the property: val4
+ @Test
+ public void testDocumentWithCatalog() {
+ buildRule.configureProject("src/etc/testcases/types/xmlcatalog.xml");
+ buildRule.executeTarget("testdocumentwithcatalog");
+ assertEquals("No news is good news", buildRule.getProject().getProperty("val4"));
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/XMLCatalogTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/XMLCatalogTest.java
new file mode 100644
index 00000000..c1adc30d
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/XMLCatalogTest.java
@@ -0,0 +1,392 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import javax.xml.transform.Source;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.sax.SAXSource;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.util.JAXPUtils;
+import org.junit.Before;
+import org.junit.Test;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.junit.Assert.assertNotNull;
+
+/**
+ * JUnit testcases for org.apache.tools.ant.types.XMLCatalog
+ *
+ */
+public class XMLCatalogTest {
+
+ private Project project;
+ private XMLCatalog catalog;
+
+ private XMLCatalog newCatalog() {
+ XMLCatalog cat = new XMLCatalog();
+ cat.setProject(project);
+ return cat;
+ }
+
+ private static String toURLString(File file) throws MalformedURLException {
+ return JAXPUtils.getSystemId(file);
+ }
+
+ @Before
+ public void setUp() {
+ project = new Project();
+ project.setBasedir(System.getProperty("root"));
+
+ // This causes XMLCatalog to print out detailed logging
+ // messages for debugging
+ //
+ // DefaultLogger logger = new DefaultLogger();
+ // logger.setMessageOutputLevel(Project.MSG_DEBUG);
+ // logger.setOutputPrintStream(System.out);
+ // logger.setErrorPrintStream(System.err);
+ // project.addBuildListener(logger);
+
+ catalog = newCatalog();
+ }
+
+ @Test
+ public void testEmptyCatalog() {
+ try {
+ InputSource result = catalog.resolveEntity("PUBLIC ID ONE",
+ "i/dont/exist.dtd");
+ assertNull("Empty catalog should return null", result);
+ } catch (Exception e) {
+ fail("resolveEntity() failed!" + e.toString());
+ }
+
+ try {
+ Source result = catalog.resolve("i/dont/exist.dtd", null);
+ String expected = toURLString(new File(project.getBaseDir() +
+ "/i/dont/exist.dtd"));
+ String resultStr =
+ fileURLPartWithoutLeadingSlashes((SAXSource)result);
+ assertTrue("Empty catalog should return input with a system ID like "
+ + expected + " but was " + resultStr,
+ expected.endsWith(resultStr));
+ } catch (Exception e) {
+ fail("resolve() failed!" + e.toString());
+ }
+ }
+
+ private static String fileURLPartWithoutLeadingSlashes(SAXSource result)
+ throws MalformedURLException {
+ //
+ // These shenanigans are necessary b/c Norm Walsh's resolver
+ // has a different idea of how file URLs are created on windoze
+ // ie file://c:/foo instead of file:///c:/foo
+ //
+ String resultStr =
+ new URL(result.getInputSource().getSystemId()).getFile();
+ // on Sun's Java6 this returns an unexpected number of four
+ // leading slashes, at least on Linux - strip all of them
+ while (resultStr.startsWith("/")) {
+ resultStr = resultStr.substring(1);
+ }
+ return resultStr;
+ }
+
+ @Test
+ public void testNonExistentEntry() throws IOException, SAXException, TransformerException {
+
+ ResourceLocation dtd = new ResourceLocation();
+ dtd.setPublicId("PUBLIC ID ONE");
+ dtd.setLocation("i/dont/exist.dtd");
+
+ InputSource isResult = catalog.resolveEntity("PUBLIC ID ONE",
+ "i/dont/exist.dtd");
+ assertNull("Nonexistent Catalog entry should not be returned", isResult);
+
+ Source result = catalog.resolve("i/dont/exist.dtd", null);
+ String expected = toURLString(new File(project.getBaseDir().toURL() +
+ "/i/dont/exist.dtd"));
+ String resultStr =
+ fileURLPartWithoutLeadingSlashes((SAXSource)result);
+ assertTrue("Nonexistent Catalog entry return input with a system ID like "
+ + expected + " but was " + resultStr,
+ expected.endsWith(resultStr));
+ }
+
+ @Test
+ public void testEmptyElementIfIsReference() {
+ ResourceLocation dtd = new ResourceLocation();
+ dtd.setPublicId("PUBLIC ID ONE");
+ dtd.setLocation("i/dont/exist.dtd");
+ catalog.addDTD(dtd);
+ project.addReference("catalog", catalog);
+
+ try {
+ catalog.setRefid(new Reference(project, "dummyref"));
+ fail("Can add reference to nonexistent XMLCatalog");
+ } catch (BuildException be) {
+ assertEquals("You must not specify more than one "
+ + "attribute when using refid", be.getMessage());
+ }
+
+ XMLCatalog catalog2 = newCatalog();
+ catalog2.setRefid(new Reference(project, "catalog"));
+
+ try {
+ catalog2.addConfiguredXMLCatalog(catalog);
+ fail("Can add nested XMLCatalog to XMLCatalog that is a reference");
+ } catch (BuildException be) {
+ assertEquals("You must not specify nested elements when using refid",
+ be.getMessage());
+ }
+ }
+
+ @Test
+ public void testCircularReferenceCheck() throws IOException, SAXException {
+
+ // catalog <--> catalog
+ project.addReference("catalog", catalog);
+ catalog.setRefid(new Reference(project, "catalog"));
+
+ try {
+ InputSource result = catalog.resolveEntity("PUBLIC ID ONE",
+ "i/dont/exist.dtd");
+ fail("Can make XMLCatalog a Reference to itself.");
+ } catch (BuildException be) {
+ assertEquals("This data type contains a circular reference.",
+ be.getMessage());
+ } catch (Exception e) {
+ fail("resolveEntity() failed!" + e.toString());
+ }
+
+ // catalog1 --> catalog2 --> catalog3 --> catalog1
+ XMLCatalog catalog1 = newCatalog();
+ project.addReference("catalog1", catalog1);
+ XMLCatalog catalog2 = newCatalog();
+ project.addReference("catalog2", catalog2);
+ XMLCatalog catalog3 = newCatalog();
+ project.addReference("catalog3", catalog3);
+
+ catalog3.setRefid(new Reference(project, "catalog1"));
+ catalog2.setRefid(new Reference(project, "catalog3"));
+ catalog1.setRefid(new Reference(project, "catalog2"));
+
+ try {
+ catalog1.resolveEntity("PUBLIC ID ONE",
+ "i/dont/exist.dtd");
+ fail("Can make circular reference");
+ } catch (BuildException be) {
+ assertEquals("This data type contains a circular reference.",
+ be.getMessage());
+ }
+ }
+ // inspired by Bugzilla Report 23913
+ // a problem used to happen under Windows when the location of the DTD was given as an absolute path
+ // possibly with a mixture of file separators
+ @Test
+ public void testAbsolutePath() throws IOException, SAXException {
+ ResourceLocation dtd = new ResourceLocation();
+ dtd.setPublicId("-//stevo//DTD doc 1.0//EN");
+
+ String sysid = System.getProperty("root") + File.separator + "src/etc/testcases/taskdefs/optional/xml/doc.dtd";
+ dtd.setLocation(sysid);
+ catalog.addDTD(dtd);
+ File dtdFile = project.resolveFile(sysid);
+
+ InputSource result = catalog.resolveEntity("-//stevo//DTD doc 1.0//EN",
+ "nap:chemical+brothers");
+ assertNotNull(result);
+ assertEquals(toURLString(dtdFile),
+ result.getSystemId());
+
+
+ }
+
+ @Test
+ public void testSimpleEntry() throws IOException, SAXException {
+
+ ResourceLocation dtd = new ResourceLocation();
+ dtd.setPublicId("-//stevo//DTD doc 1.0//EN");
+ String sysid = "src/etc/testcases/taskdefs/optional/xml/doc.dtd";
+ dtd.setLocation(sysid);
+ catalog.addDTD(dtd);
+ File dtdFile = project.resolveFile(sysid);
+
+ InputSource result = catalog.resolveEntity("-//stevo//DTD doc 1.0//EN",
+ "nap:chemical+brothers");
+ assertNotNull(result);
+ assertEquals(toURLString(dtdFile),
+ result.getSystemId());
+
+ }
+
+ @Test
+ public void testEntryReference() throws IOException, SAXException, TransformerException {
+
+ String publicId = "-//stevo//DTD doc 1.0//EN";
+ String sysid = "src/etc/testcases/taskdefs/optional/xml/doc.dtd";
+
+ // catalog2 --> catalog1 --> catalog
+ ResourceLocation dtd = new ResourceLocation();
+ dtd.setPublicId(publicId);
+ dtd.setLocation(sysid);
+ catalog.addDTD(dtd);
+ File dtdFile = project.resolveFile(sysid);
+
+ String uri = "http://foo.com/bar/blah.xml";
+ String uriLoc = "src/etc/testcases/taskdefs/optional/xml/about.xml";
+
+ ResourceLocation entity = new ResourceLocation();
+ entity.setPublicId(uri);
+ entity.setLocation(uriLoc);
+ catalog.addEntity(entity);
+ File xmlFile = project.resolveFile(uriLoc);
+
+ project.addReference("catalog", catalog);
+
+ XMLCatalog catalog1 = newCatalog();
+ project.addReference("catalog1", catalog1);
+ XMLCatalog catalog2 = newCatalog();
+ project.addReference("catalog2", catalog1);
+
+ catalog1.setRefid(new Reference(project, "catalog"));
+ catalog2.setRefid(new Reference(project, "catalog1"));
+
+ InputSource isResult = catalog2.resolveEntity(publicId,
+ "nap:chemical+brothers");
+
+ assertNotNull(isResult);
+ assertEquals(toURLString(dtdFile),
+ isResult.getSystemId());
+
+
+ Source result = catalog.resolve(uri, null);
+ assertNotNull(result);
+ assertEquals(toURLString(xmlFile),
+ result.getSystemId());
+ }
+
+ @Test
+ public void testNestedCatalog() throws IOException, SAXException, TransformerException {
+
+ String publicId = "-//stevo//DTD doc 1.0//EN";
+ String dtdLoc = "src/etc/testcases/taskdefs/optional/xml/doc.dtd";
+
+ ResourceLocation dtd = new ResourceLocation();
+ dtd.setPublicId(publicId);
+ dtd.setLocation(dtdLoc);
+ catalog.addDTD(dtd);
+ File dtdFile = project.resolveFile(dtdLoc);
+
+ String uri = "http://foo.com/bar/blah.xml";
+ String uriLoc = "src/etc/testcases/taskdefs/optional/xml/about.xml";
+
+ ResourceLocation entity = new ResourceLocation();
+ entity.setPublicId(uri);
+ entity.setLocation(uriLoc);
+ catalog.addEntity(entity);
+ File xmlFile = project.resolveFile(uriLoc);
+
+ XMLCatalog catalog1 = newCatalog();
+ catalog1.addConfiguredXMLCatalog(catalog);
+
+ InputSource isResult = catalog1.resolveEntity(publicId,
+ "nap:chemical+brothers");
+ assertNotNull(isResult);
+ assertEquals(toURLString(dtdFile),
+ isResult.getSystemId());
+
+ Source result = catalog.resolve(uri, null);
+ assertNotNull(result);
+ assertEquals(toURLString(xmlFile),
+ result.getSystemId());
+
+ }
+
+ @Test
+ public void testResolverBase() throws MalformedURLException, TransformerException {
+
+ String uri = "http://foo.com/bar/blah.xml";
+ String uriLoc = "etc/testcases/taskdefs/optional/xml/about.xml";
+ String base = toURLString(project.getBaseDir()) + "/src/";
+
+ ResourceLocation entity = new ResourceLocation();
+ entity.setPublicId(uri);
+ entity.setLocation(uriLoc);
+ catalog.addEntity(entity);
+ File xmlFile = project.resolveFile("src/" + uriLoc);
+
+ Source result = catalog.resolve(uri, base);
+ assertNotNull(result);
+ assertEquals(toURLString(xmlFile),
+ result.getSystemId());
+
+ }
+
+ @Test
+ public void testClasspath() throws IOException, TransformerException, SAXException {
+
+
+ String publicId = "-//stevo//DTD doc 1.0//EN";
+ String dtdLoc = "testcases/taskdefs/optional/xml/doc.dtd";
+ String path1 = project.getBaseDir().toString() + "/src/etc";
+
+ ResourceLocation dtd = new ResourceLocation();
+ dtd.setPublicId(publicId);
+ dtd.setLocation(dtdLoc);
+ catalog.addDTD(dtd);
+ File dtdFile = project.resolveFile("src/etc/" + dtdLoc);
+
+ String uri = "http://foo.com/bar/blah.xml";
+ String uriLoc = "etc/testcases/taskdefs/optional/xml/about.xml";
+ String path2 = project.getBaseDir().toString() + "/src";
+
+ ResourceLocation entity = new ResourceLocation();
+ entity.setPublicId(uri);
+ entity.setLocation(uriLoc);
+ catalog.addEntity(entity);
+ File xmlFile = project.resolveFile("src/" + uriLoc);
+
+ Path aPath = new Path(project, path1);
+ aPath.append(new Path(project, path2));
+ catalog.setClasspath(aPath);
+
+ InputSource isResult = catalog.resolveEntity(publicId,
+ "nap:chemical+brothers");
+ assertNotNull(isResult);
+ String resultStr1 = new URL(isResult.getSystemId()).getFile();
+ assertTrue(toURLString(dtdFile).endsWith(resultStr1));
+
+ Source result = catalog.resolve(uri, null);
+ assertNotNull(result);
+ String resultStr = new URL(result.getSystemId()).getFile();
+ assertTrue(toURLString(xmlFile).endsWith(resultStr));
+
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/ZipFileSetTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/ZipFileSetTest.java
new file mode 100644
index 00000000..e7b14c19
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/ZipFileSetTest.java
@@ -0,0 +1,118 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types;
+
+import java.io.File;
+
+import org.apache.tools.ant.BuildException;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+/**
+ * JUnit 3 testcases for org.apache.tools.ant.types.ZipFileSet.
+ *
+ * <p>This doesn't actually test much, mainly reference handling.
+ *
+ */
+
+public class ZipFileSetTest extends AbstractFileSetTest {
+
+ protected AbstractFileSet getInstance() {
+ return new ZipFileSet();
+ }
+
+ @Test
+ public final void testAttributes() {
+ ZipFileSet f = (ZipFileSet)getInstance();
+ //check that dir and src are incompatible
+ f.setSrc(new File("example.zip"));
+ try {
+ f.setDir(new File("examples"));
+ fail("can add dir to "
+ + f.getDataTypeName()
+ + " when a src is already present");
+ } catch (BuildException be) {
+ assertEquals("Cannot set both dir and src attributes",be.getMessage());
+ }
+ f = (ZipFileSet)getInstance();
+ //check that dir and src are incompatible
+ f.setDir(new File("examples"));
+ try {
+ f.setSrc(new File("example.zip"));
+ fail("can add src to "
+ + f.getDataTypeName()
+ + " when a dir is already present");
+ } catch (BuildException be) {
+ assertEquals("Cannot set both dir and src attributes",be.getMessage());
+ }
+ //check that fullpath and prefix are incompatible
+ f = (ZipFileSet)getInstance();
+ f.setSrc(new File("example.zip"));
+ f.setPrefix("/examples");
+ try {
+ f.setFullpath("/doc/manual/index.html");
+ fail("Can add fullpath to "
+ + f.getDataTypeName()
+ + " when a prefix is already present");
+ } catch (BuildException be) {
+ assertEquals("Cannot set both fullpath and prefix attributes", be.getMessage());
+ }
+ f = (ZipFileSet)getInstance();
+ f.setSrc(new File("example.zip"));
+ f.setFullpath("/doc/manual/index.html");
+ try {
+ f.setPrefix("/examples");
+ fail("Can add prefix to "
+ + f.getDataTypeName()
+ + " when a fullpath is already present");
+ } catch (BuildException be) {
+ assertEquals("Cannot set both fullpath and prefix attributes", be.getMessage());
+ }
+ // check that reference zipfilesets cannot have specific attributes
+ f = (ZipFileSet)getInstance();
+ f.setRefid(new Reference(getProject(), "test"));
+ try {
+ f.setSrc(new File("example.zip"));
+ fail("Can add src to "
+ + f.getDataTypeName()
+ + " when a refid is already present");
+ } catch (BuildException be) {
+ assertEquals("You must not specify more than one "
+ + "attribute when using refid", be.getMessage());
+ }
+ // check that a reference zipfileset gets the same attributes as the original
+ f = (ZipFileSet)getInstance();
+ f.setSrc(new File("example.zip"));
+ f.setPrefix("/examples");
+ f.setFileMode("600");
+ f.setDirMode("530");
+ getProject().addReference("test",f);
+ ZipFileSet zid=(ZipFileSet)getInstance();
+ zid.setRefid(new Reference(getProject(), "test"));
+ assertTrue("src attribute copied by copy constructor",zid.getSrc(getProject()).equals(f.getSrc(getProject())));
+ assertTrue("prefix attribute copied by copy constructor",f.getPrefix(getProject()).equals(zid.getPrefix(getProject())));
+ assertTrue("file mode attribute copied by copy constructor",f.getFileMode(getProject())==zid.getFileMode(getProject()));
+ assertTrue("dir mode attribute copied by copy constructor",f.getDirMode(getProject())==zid.getDirMode(getProject()));
+ }
+
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/mappers/GlobMapperTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/mappers/GlobMapperTest.java
new file mode 100644
index 00000000..310fb5e5
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/mappers/GlobMapperTest.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types.mappers;
+
+import org.apache.tools.ant.BuildFileRule;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+/**
+ * Testcase for the &lt;globmapper&gt; mapper.
+ *
+ */
+public class GlobMapperTest {
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/types/mappers/globmapper.xml");
+ }
+
+ @Test
+ public void testIgnoreCase() {
+ buildRule.executeTarget("ignore.case");
+ }
+ public void testHandleDirSep() {
+ buildRule.executeTarget("handle.dirsep");
+ }
+}
+
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/mappers/MapperResult.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/mappers/MapperResult.java
new file mode 100644
index 00000000..43a7b296
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/mappers/MapperResult.java
@@ -0,0 +1,103 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types.mappers;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.types.Mapper;
+import org.apache.tools.ant.util.FileNameMapper;
+
+/**
+ * This is a test task to show the result of a mapper
+ * on a specific input.
+ * (Test is not in the name of the class, to make sure that
+ * it is not treated as a unit test.
+ */
+
+public class MapperResult extends Task {
+
+ private String failMessage = "";
+ private String input;
+ private String output;
+ private FileNameMapper fileNameMapper;
+
+ /**
+ * The output on an empty string array
+ */
+ private static final String NULL_MAPPER_RESULT = "<NULL>";
+
+ public void setFailMessage(String failMessage) {
+ this.failMessage = failMessage;
+ }
+
+ public void setInput(String input) {
+ this.input = input;
+ }
+
+ public void setOutput(String output) {
+ this.output = output;
+ }
+
+ public void addConfiguredMapper(Mapper mapper) {
+ add(mapper.getImplementation());
+ }
+
+ public void add(FileNameMapper fileNameMapper) {
+ if (this.fileNameMapper != null) {
+ throw new BuildException("Only one mapper type nested element allowed");
+ }
+ this.fileNameMapper = fileNameMapper;
+ }
+
+ public void execute() {
+ if (input == null) {
+ throw new BuildException("Missing attribute 'input'");
+ }
+ if (output == null) {
+ throw new BuildException("Missing attribute 'output'");
+ }
+ if (fileNameMapper == null) {
+ throw new BuildException("Missing a nested file name mapper type element");
+ }
+ String[] result = fileNameMapper.mapFileName(input);
+ String flattened;
+ if (result == null) {
+ flattened = NULL_MAPPER_RESULT;
+ } else {
+ StringBuffer b = new StringBuffer();
+ for (int i = 0; i < result.length; ++i) {
+ if (i != 0) {
+ b.append("|");
+ }
+ b.append(result[i]);
+ }
+ flattened = b.toString();
+ }
+ if (!flattened.equals(output)) {
+ throw new BuildException(
+ failMessage
+ + " "
+ + "got "
+ + flattened
+ + " "
+ + "expected "
+ + output);
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/mappers/RegexpPatternMapperTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/mappers/RegexpPatternMapperTest.java
new file mode 100644
index 00000000..d01593b4
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/mappers/RegexpPatternMapperTest.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types.mappers;
+
+import org.apache.tools.ant.BuildFileRule;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+/**
+ * Testcase for the &lt;regexpmapper&gt; mapper.
+ *
+ */
+public class RegexpPatternMapperTest {
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/types/mappers/regexpmapper.xml");
+ }
+
+ @Test
+ public void testIgnoreCase() {
+ buildRule.executeTarget("ignore.case");
+ }
+
+ @Test
+ public void testHandleDirSep() {
+ buildRule.executeTarget("handle.dirsep");
+ }
+}
+
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/optional/ScriptMapperTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/optional/ScriptMapperTest.java
new file mode 100644
index 00000000..bf727db9
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/optional/ScriptMapperTest.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types.optional;
+
+import org.apache.tools.ant.BuildFileRule;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+/**
+ * Test our script mapping
+ */
+public class ScriptMapperTest {
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/types/mappers/scriptmapper.xml");
+ }
+
+ @Test
+ public void testClear() {
+ buildRule.executeTarget("testClear");
+ }
+
+ @Test
+ public void testSetMultiple() {
+ buildRule.executeTarget("testSetMultiple");
+ }
+
+ @Test
+ public void testPassthrough() {
+ buildRule.executeTarget("testPassthrough");
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/optional/ScriptSelectorTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/optional/ScriptSelectorTest.java
new file mode 100644
index 00000000..304d6d09
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/optional/ScriptSelectorTest.java
@@ -0,0 +1,83 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.optional;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.BuildFileRule;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.apache.tools.ant.AntAssert.assertContains;
+import static org.junit.Assert.fail;
+
+/**
+ * Test that scripting selection works. Needs scripting support to work
+ */
+public class ScriptSelectorTest {
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/types/selectors/scriptselector.xml");
+ }
+
+ @Test
+ public void testNolanguage() {
+ try {
+ buildRule.executeTarget("testNolanguage");
+ fail("Absence of language attribute not detected");
+ } catch(BuildException ex) {
+ assertContains("script language must be specified", ex.getMessage());
+
+ }
+ }
+
+ @Test
+ public void testSelectionSetByDefault() {
+ buildRule.executeTarget("testSelectionSetByDefault");
+ }
+
+ @Test
+ public void testSelectionSetWorks() {
+ buildRule.executeTarget("testSelectionSetWorks");
+ }
+
+ @Test
+ public void testSelectionClearWorks() {
+ buildRule.executeTarget("testSelectionClearWorks");
+ }
+
+ @Test
+ public void testFilenameAttribute() {
+ buildRule.executeTarget("testFilenameAttribute");
+ }
+
+ @Test
+ public void testFileAttribute() {
+ buildRule.executeTarget("testFileAttribute");
+ }
+
+ @Test
+ public void testBasedirAttribute() {
+ buildRule.executeTarget("testBasedirAttribute");
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/optional/depend/ClassFileSetTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/optional/depend/ClassFileSetTest.java
new file mode 100644
index 00000000..392667cb
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/optional/depend/ClassFileSetTest.java
@@ -0,0 +1,186 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types.optional.depend;
+
+import java.io.File;
+import java.util.Hashtable;
+
+import org.apache.tools.ant.BuildFileRule;
+import org.apache.tools.ant.DirectoryScanner;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.FileSet;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Testcase for the Classfileset optional type.
+ *
+ */
+public class ClassFileSetTest {
+ public static final String RESULT_FILESET = "result";
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ // share the setup for testing the depend task
+ buildRule.configureProject("src/etc/testcases/taskdefs/optional/depend/depend.xml");
+ }
+
+ /**
+ * Test basic classfileset
+ */
+ @Test
+ public void testBasicSet() {
+ Project p = buildRule.getProject();
+ buildRule.executeTarget("testbasicset");
+ FileSet resultFileSet = (FileSet)p.getReference(RESULT_FILESET);
+ DirectoryScanner scanner = resultFileSet.getDirectoryScanner(p);
+ String[] scannedFiles = scanner.getIncludedFiles();
+ Hashtable files = new Hashtable();
+ for (int i = 0; i < scannedFiles.length; ++i) {
+ files.put(scannedFiles[i], scannedFiles[i]);
+ }
+ assertEquals("Classfileset did not pick up expected number of "
+ + "class files", 4, files.size());
+ assertTrue("Result did not contain A.class",
+ files.containsKey("A.class"));
+ assertTrue("Result did not contain B.class",
+ files.containsKey("B.class"));
+ assertTrue("Result did not contain C.class",
+ files.containsKey("C.class"));
+ assertTrue("Result did not contain D.class",
+ files.containsKey("D.class"));
+ }
+
+ /**
+ * Test small classfileset
+ */
+ @Test
+ public void testSmallSet() {
+ Project p = buildRule.getProject();
+ buildRule.executeTarget("testsmallset");
+ FileSet resultFileSet = (FileSet)p.getReference(RESULT_FILESET);
+ DirectoryScanner scanner = resultFileSet.getDirectoryScanner(p);
+ String[] scannedFiles = scanner.getIncludedFiles();
+ Hashtable files = new Hashtable();
+ for (int i = 0; i < scannedFiles.length; ++i) {
+ files.put(scannedFiles[i], scannedFiles[i]);
+ }
+ assertEquals("Classfileset did not pick up expected number of "
+ + "class files", 2, files.size());
+ assertTrue("Result did not contain B.class",
+ files.containsKey("B.class"));
+ assertTrue("Result did not contain C.class",
+ files.containsKey("C.class"));
+ }
+
+ /**
+ * Test combo classfileset
+ */
+ @Test
+ public void testComboSet() {
+ Project p = buildRule.getProject();
+ buildRule.executeTarget("testcomboset");
+ FileSet resultFileSet = (FileSet)p.getReference(RESULT_FILESET);
+ DirectoryScanner scanner = resultFileSet.getDirectoryScanner(p);
+ String[] scannedFiles = scanner.getIncludedFiles();
+ Hashtable files = new Hashtable();
+ for (int i = 0; i < scannedFiles.length; ++i) {
+ files.put(scannedFiles[i], scannedFiles[i]);
+ }
+ assertEquals("Classfileset did not pick up expected number of "
+ + "class files", 1, files.size());
+ assertTrue("Result did not contain C.class",
+ files.containsKey("C.class"));
+ }
+
+ /**
+ * Test that you can pass a classfileset by reference to a fileset.
+ */
+ @Test
+ public void testByReference() {
+ buildRule.executeTarget("testbyreference");
+ }
+
+ /**
+ * Test that classes included in a method "System.out.println(MyClass.class)" are included.
+ */
+ @Test
+ public void testMethodParam() {
+ Project p = buildRule.getProject();
+ buildRule.executeTarget("testmethodparam");
+ FileSet resultFileSet = (FileSet)p.getReference(RESULT_FILESET);
+ DirectoryScanner scanner = resultFileSet.getDirectoryScanner(p);
+ String[] scannedFiles = scanner.getIncludedFiles();
+ Hashtable files = new Hashtable();
+ for (int i = 0; i < scannedFiles.length; ++i) {
+ files.put(scannedFiles[i], scannedFiles[i]);
+ }
+ assertEquals("Classfileset did not pick up expected number of "
+ + "class files", 5, files.size());
+ assertTrue("Result did not contain A.class",
+ files.containsKey("A.class"));
+ assertTrue("Result did not contain B.class",
+ files.containsKey("B.class"));
+ assertTrue("Result did not contain C.class",
+ files.containsKey("C.class"));
+ assertTrue("Result did not contain D.class",
+ files.containsKey("D.class"));
+ assertTrue("Result did not contain E.class",
+ files.containsKey("E.class"));
+ }
+
+ /**
+ * Test that classes included in a method "System.out.println(Outer.Inner.class)" are included.
+ */
+ @Test
+ public void testMethodParamInner() {
+ Project p = buildRule.getProject();
+ buildRule.executeTarget("testmethodparaminner");
+ FileSet resultFileSet = (FileSet)p.getReference(RESULT_FILESET);
+ DirectoryScanner scanner = resultFileSet.getDirectoryScanner(p);
+ String[] scannedFiles = scanner.getIncludedFiles();
+ Hashtable files = new Hashtable();
+ for (int i = 0; i < scannedFiles.length; ++i) {
+ files.put(scannedFiles[i], scannedFiles[i]);
+ }
+ assertEquals("Classfileset did not pick up expected number of "
+ + "class files", 4, files.size());
+ assertTrue("Result did not contain test" + File.separator + "Outer$Inner.class",
+ files.containsKey("test" + File.separator + "Outer$Inner.class"));
+ assertTrue("Result did not contain test" + File.separator + "Outer.class",
+ files.containsKey("test" + File.separator + "Outer.class"));
+ assertTrue("Result did not contain test" + File.separator + "ContainsOnlyInner.class",
+ files.containsKey("test" + File.separator + "ContainsOnlyInner.class"));
+ assertTrue("Result did not contain test" + File.separator + "ContainsOnlyInner.class",
+ files.containsKey("test" + File.separator + "MethodParam.class"));
+ }
+
+ @Test
+ public void testResourceCollection() {
+ buildRule.executeTarget("testresourcecollection");
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/resources/FileResourceTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/resources/FileResourceTest.java
new file mode 100644
index 00000000..71efc656
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/resources/FileResourceTest.java
@@ -0,0 +1,122 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.resources;
+
+import java.io.File;
+
+import org.apache.tools.ant.Project;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * Test Java API of {@link FileResource}.
+ */
+public class FileResourceTest {
+
+ private File root;
+
+ @Before
+ public void setUp() {
+ root = new File(System.getProperty("root"));
+ }
+
+ @Test
+ public void testAttributes() {
+ FileResource f = new FileResource();
+ f.setBaseDir(root);
+ f.setName("foo");
+ assertEquals(new File(root, "foo"), f.getFile());
+ assertEquals(root, f.getBaseDir());
+ assertEquals("foo", f.getName());
+ }
+
+ @Test
+ public void testNonImmediateBasedir() {
+ FileResource f = new FileResource();
+ f.setBaseDir(root);
+ f.setName("foo/bar");
+ assertEquals(new File(root, "foo/bar"), f.getFile());
+ assertEquals(root, f.getBaseDir());
+ assertEquals("foo/bar", f.getName().replace(File.separatorChar, '/'));
+ }
+
+ @Test
+ public void testFile() {
+ FileResource f = new FileResource(new File(root, "foo"));
+ assertEquals(new File(root, "foo"), f.getFile());
+ assertEquals(root, f.getBaseDir());
+ assertEquals("foo", f.getName());
+ }
+
+ @Test
+ public void testBasedirAndName() {
+ FileResource f = new FileResource(root, "foo");
+ assertEquals(new File(root, "foo"), f.getFile());
+ assertEquals(root, f.getBaseDir());
+ assertEquals("foo", f.getName());
+ }
+
+ @Test
+ public void testNonImmediateBasedirAndName() {
+ FileResource f = new FileResource(root, "foo/bar");
+ assertEquals(new File(root, "foo/bar"), f.getFile());
+ assertEquals(root, f.getBaseDir());
+ assertEquals("foo/bar", f.getName().replace(File.separatorChar, '/'));
+ }
+
+ @Test
+ public void testProjectAndFilename() {
+ Project p = new Project();
+ p.setBaseDir(root);
+ FileResource f = new FileResource(p, "foo");
+ assertEquals(new File(root, "foo"), f.getFile());
+ assertEquals(root, f.getBaseDir());
+ assertEquals("foo", f.getName());
+ }
+
+ @Test
+ public void testRelativeFactoryResource() {
+ FileResource f = new FileResource(root, "foo");
+ FileResource relative = f.getResource("bar").as(FileResource.class);
+ assertEquals(new File(root, "foo/bar"), relative.getFile());
+ assertEquals("foo/bar", relative.getName().replace(File.separatorChar, '/'));
+ assertEquals(root, relative.getBaseDir());
+ }
+
+ @Test
+ public void testAbsoluteFactoryResource() {
+ FileResource f = new FileResource(new File(root, "foo/a"));
+ assertEquals(new File(root, "foo"), f.getBaseDir());
+ File bar = new File(root, "bar");
+ FileResource fromFactory = f.getResource(bar.getAbsolutePath()).as(FileResource.class);
+ assertEquals(bar, fromFactory.getFile());
+ assertEquals(root, fromFactory.getBaseDir());
+ }
+
+ @Test
+ public void testParentSiblingFactoryResource() {
+ FileResource f = new FileResource(new File(root, "foo/a"));
+ assertEquals(new File(root, "foo"), f.getBaseDir());
+ FileResource parentSibling = f.getResource("../../bar").as(FileResource.class);
+ assertEquals(root, parentSibling.getBaseDir());
+ assertEquals("bar", parentSibling.getName());
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/resources/JavaResourceTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/resources/JavaResourceTest.java
new file mode 100644
index 00000000..a67db39b
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/resources/JavaResourceTest.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.resources;
+
+import org.apache.tools.ant.BuildFileRule;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+
+public class JavaResourceTest {
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/types/resources/javaresource.xml");
+ }
+
+ @Test
+ public void testLoadManifest() {
+ buildRule.executeTarget("loadManifest");
+ assertNotNull(buildRule.getProject().getProperty("manifest"));
+
+ // this actually relies on the first manifest being found on
+ // the classpath (probably rt.jar's) being valid
+ assertTrue(buildRule.getProject().getProperty("manifest")
+ .startsWith("Manifest-Version:"));
+ }
+
+ @Test
+ public void testIsURLProvider() {
+ JavaResource r = new JavaResource();
+ assertSame(r, r.as(URLProvider.class));
+ }
+
+ @Test
+ public void testGetURLOfManifest() {
+ JavaResource r = new JavaResource();
+ r.setName("META-INF/MANIFEST.MF");
+ assertNotNull(r.getURL());
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/resources/LazyResourceCollectionTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/resources/LazyResourceCollectionTest.java
new file mode 100644
index 00000000..f91077a6
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/resources/LazyResourceCollectionTest.java
@@ -0,0 +1,186 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.resources;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+
+
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.ResourceCollection;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+public class LazyResourceCollectionTest {
+
+ private class StringResourceCollection implements ResourceCollection {
+ List resources = Arrays.<Resource>asList();
+
+ List createdIterators = new ArrayList();
+
+ public int size() {
+ return resources.size();
+ }
+
+ public Iterator<Resource> iterator() {
+ StringResourceIterator it = new StringResourceIterator();
+ createdIterators.add(it);
+ return it;
+ }
+
+ public boolean isFilesystemOnly() {
+ return false;
+ }
+ }
+
+ private class StringResourceIterator implements Iterator {
+ int cursor = 0;
+
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+
+ public Object next() {
+ if (cursor < 3) {
+ cursor++;
+ return new StringResource("r" + cursor);
+ }
+ return null;
+ }
+
+ public boolean hasNext() {
+ return cursor < 3;
+ }
+ }
+
+ @Test
+ public void testLazyLoading() throws Exception {
+ StringResourceCollection collectionTest = new StringResourceCollection();
+ LazyResourceCollectionWrapper lazyCollection = new LazyResourceCollectionWrapper();
+ lazyCollection.add(collectionTest);
+
+ Iterator<Resource> it = lazyCollection.iterator();
+ assertOneCreatedIterator(collectionTest);
+ StringResourceIterator stringResourceIterator = (StringResourceIterator) collectionTest.createdIterators
+ .get(0);
+ assertEquals("A resource was loaded without iterating", 1,
+ stringResourceIterator.cursor);
+
+ StringResource r = (StringResource) it.next();
+ assertOneCreatedIterator(collectionTest);
+ assertEquals("r1", r.getValue());
+ assertEquals("Iterating once load more than 1 resource", 2,
+ stringResourceIterator.cursor);
+
+ r = (StringResource) it.next();
+ assertOneCreatedIterator(collectionTest);
+ assertEquals("r2", r.getValue());
+ assertEquals("Iterating twice load more than 2 resources", 3,
+ stringResourceIterator.cursor);
+
+ r = (StringResource) it.next();
+ assertOneCreatedIterator(collectionTest);
+ assertEquals("r3", r.getValue());
+ assertEquals("Iterating 3 times load more than 3 resources", 3,
+ stringResourceIterator.cursor);
+
+ try {
+ it.next();
+ fail("NoSuchElementException should have been raised");
+ } catch (NoSuchElementException e) {
+ // ok
+ }
+ }
+
+ private void assertOneCreatedIterator(
+ StringResourceCollection testCollection) {
+ assertEquals("More than one iterator has been created", 1,
+ testCollection.createdIterators.size());
+ }
+
+ @Test
+ public void testCaching() throws Exception {
+ StringResourceCollection collectionTest = new StringResourceCollection();
+ LazyResourceCollectionWrapper lazyCollection = new LazyResourceCollectionWrapper();
+ lazyCollection.add(collectionTest);
+
+ assertTrue(lazyCollection.isCache());
+ Iterator<Resource> it1 = lazyCollection.iterator();
+ assertOneCreatedIterator(collectionTest);
+ Iterator<Resource> it2 = lazyCollection.iterator();
+ assertOneCreatedIterator(collectionTest);
+
+ StringResourceIterator stringResourceIterator = (StringResourceIterator) collectionTest.createdIterators
+ .get(0);
+ assertEquals("A resource was loaded without iterating", 1,
+ stringResourceIterator.cursor);
+
+ StringResource r = (StringResource) it1.next();
+ assertEquals("r1", r.getValue());
+ assertEquals("Iterating once load more than 1 resource", 2,
+ stringResourceIterator.cursor);
+
+ r = (StringResource) it2.next();
+ assertEquals("r1", r.getValue());
+ assertEquals(
+ "The second iterator did not lookup in the cache for a resource",
+ 2, stringResourceIterator.cursor);
+
+ r = (StringResource) it2.next();
+ assertEquals("r2", r.getValue());
+ assertEquals("Iterating twice load more than 2 resources", 3,
+ stringResourceIterator.cursor);
+
+ r = (StringResource) it1.next();
+ assertEquals("r2", r.getValue());
+ assertEquals(
+ "The first iterator did not lookup in the cache for a resource",
+ 3, stringResourceIterator.cursor);
+
+ r = (StringResource) it2.next();
+ assertEquals("r3", r.getValue());
+ assertEquals("Iterating 3 times load more than 3 resources", 3,
+ stringResourceIterator.cursor);
+
+ r = (StringResource) it1.next();
+ assertEquals("r3", r.getValue());
+ assertEquals(
+ "The first iterator did not lookup in the cache for a resource",
+ 3, stringResourceIterator.cursor);
+
+ try {
+ it1.next();
+ fail("NoSuchElementException should have been raised");
+ } catch (NoSuchElementException e) {
+ // ok
+ }
+
+ try {
+ it2.next();
+ fail("NoSuchElementException should have been raised");
+ } catch (NoSuchElementException e) {
+ // ok
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/resources/MultiRootFileSetTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/resources/MultiRootFileSetTest.java
new file mode 100644
index 00000000..6c05963b
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/resources/MultiRootFileSetTest.java
@@ -0,0 +1,131 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types.resources;
+
+import java.io.File;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.AbstractFileSet;
+import org.apache.tools.ant.types.AbstractFileSetTest;
+import org.apache.tools.ant.types.Reference;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+/**
+ * This doesn't actually test much, mainly reference handling.
+ */
+public class MultiRootFileSetTest extends AbstractFileSetTest {
+
+
+ protected AbstractFileSet getInstance() {
+ return new MultiRootFileSet() {
+ // overriding so set/getDir works as expected by the base test class
+ private File dir;
+ public void setDir(File dir) {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ this.dir = dir;
+ }
+
+ public synchronized File getDir(Project p) {
+ if (isReference()) {
+ return getRef(p).getDir(p);
+ }
+ dieOnCircularReference();
+ return dir;
+ }
+ };
+ }
+
+ @Test
+ public void testEmptyElementIfIsReferenceAdditionalAttributes() {
+ MultiRootFileSet f = new MultiRootFileSet();
+ f.setProject(getProject());
+ f.setBaseDirs("a");
+ try {
+ f.setRefid(new Reference(getProject(), "dummyref"));
+ fail("Can add reference to multirootfileset "
+ + " with elements from setBasedirs");
+ } catch (BuildException be) {
+ assertEquals("You must not specify more than one attribute "
+ + "when using refid", be.getMessage());
+ }
+ f = new MultiRootFileSet();
+ f.addConfiguredBaseDir(new FileResource(new File(".")));
+ try {
+ f.setRefid(new Reference(getProject(), "dummyref"));
+ fail("Can add reference to multirootfileset"
+ + " with elements from addConfiguredBaseDir");
+ } catch (BuildException be) {
+ assertEquals("You must not specify more than one attribute "
+ + "when using refid", be.getMessage());
+ }
+
+ f = new MultiRootFileSet();
+ f.setRefid(new Reference(getProject(), "dummyref"));
+ try {
+ f.setBaseDirs("a");
+ fail("Can set basedirs in multirootfileset"
+ + " that is a reference.");
+ } catch (BuildException be) {
+ assertEquals("You must not specify more than one attribute "
+ + "when using refid", be.getMessage());
+ }
+ try {
+ f.setCache(true);
+ fail("Can set cache in multirootfileset"
+ + " that is a reference.");
+ } catch (BuildException be) {
+ assertEquals("You must not specify more than one attribute "
+ + "when using refid", be.getMessage());
+ }
+ try {
+ f.setType(MultiRootFileSet.SetType.file);
+ fail("Can set type in multirootfileset"
+ + " that is a reference.");
+ } catch (BuildException be) {
+ assertEquals("You must not specify more than one attribute "
+ + "when using refid", be.getMessage());
+ }
+ try {
+ f.addConfiguredBaseDir(new FileResource(new File(".")));
+ fail("Can add nested basedir in multirootfileset "
+ + " that is a reference.");
+ } catch (BuildException be) {
+ assertEquals("You must not specify nested elements when using "
+ + "refid", be.getMessage());
+ }
+ }
+
+ @Test
+ public void testDirCannotBeSet() {
+ try {
+ new MultiRootFileSet().setDir(new File("."));
+ fail("Can set dir in a multirootfileset");
+ } catch (BuildException e) {
+ assertTrue(e.getMessage()
+ .endsWith(" doesn't support the dir attribute"));
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/resources/ResourceListTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/resources/ResourceListTest.java
new file mode 100644
index 00000000..f0201789
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/resources/ResourceListTest.java
@@ -0,0 +1,134 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.resources;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.BuildFileRule;
+import org.apache.tools.ant.types.FilterChain;
+import org.apache.tools.ant.types.Reference;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+public class ResourceListTest {
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() throws Exception {
+ buildRule.configureProject("src/etc/testcases/types/resources/resourcelist.xml");
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ buildRule.executeTarget("tearDown");
+ }
+
+ @Test
+ public void testEmptyElementWithReference() {
+ ResourceList rl = new ResourceList();
+ rl.setEncoding("foo");
+ try {
+ rl.setRefid(new Reference(buildRule.getProject(), "dummyref"));
+ fail("Can add reference to ResourceList with encoding attribute set.");
+ } catch (BuildException be) {
+ assertEquals("You must not specify more than one attribute when using refid",
+ be.getMessage());
+ }
+
+ rl = new ResourceList();
+ rl.setRefid(new Reference(buildRule.getProject(), "dummyref"));
+ try {
+ rl.setEncoding("foo");
+ fail("Can set encoding in ResourceList that is a reference");
+ } catch (BuildException be) {
+ assertEquals("You must not specify more than one attribute when using refid",
+ be.getMessage());
+ }
+
+ rl = new ResourceList();
+ rl.add(new FileResource(buildRule.getProject(), "."));
+ try {
+ rl.setRefid(new Reference(buildRule.getProject(), "dummyref"));
+ fail("Can add reference to ResourceList with nested resource collection.");
+ } catch (BuildException be) {
+ assertEquals("You must not specify nested elements when using refid",
+ be.getMessage());
+ }
+
+ rl = new ResourceList();
+ rl.setRefid(new Reference(buildRule.getProject(), "dummyref"));
+ try {
+ rl.add(new FileResource(buildRule.getProject(), "."));
+ fail("Can add reference to ResourceList with nested resource collection.");
+ } catch (BuildException be) {
+ assertEquals("You must not specify nested elements when using refid",
+ be.getMessage());
+ }
+
+ rl = new ResourceList();
+ rl.addFilterChain(new FilterChain());
+ try {
+ rl.setRefid(new Reference(buildRule.getProject(), "dummyref"));
+ fail("Can add reference to ResourceList with nested filter chain.");
+ } catch (BuildException be) {
+ assertEquals("You must not specify nested elements when using refid",
+ be.getMessage());
+ }
+
+ rl = new ResourceList();
+ rl.setRefid(new Reference(buildRule.getProject(), "dummyref"));
+ try {
+ rl.addFilterChain(new FilterChain());
+ fail("Can add reference to ResourceList with nested filter chain.");
+ } catch (BuildException be) {
+ assertEquals("You must not specify nested elements when using refid",
+ be.getMessage());
+ }
+ }
+
+ @Test
+ public void testCircularReference() throws Exception {
+ ResourceList rl1 = new ResourceList();
+ rl1.setProject(buildRule.getProject());
+ rl1.setRefid(new Reference(buildRule.getProject(), "foo"));
+
+ ResourceList rl2 = new ResourceList();
+ rl2.setProject(buildRule.getProject());
+ buildRule.getProject().addReference("foo", rl2);
+
+ Union u = new Union();
+ u.add(rl1);
+ u.setProject(buildRule.getProject());
+
+ rl2.add(u);
+
+ try {
+ rl2.size();
+ fail("Can make ResourceList a Reference to itself.");
+ } catch (BuildException be) {
+ assertEquals("This data type contains a circular reference.",
+ be.getMessage());
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/resources/TarResourceTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/resources/TarResourceTest.java
new file mode 100644
index 00000000..a9593f09
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/resources/TarResourceTest.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.types.resources;
+
+import org.apache.tools.ant.BuildFileRule;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import java.io.File;
+
+import static org.apache.tools.ant.FileUtilities.getFileContents;
+import static org.junit.Assert.assertEquals;
+
+
+public class TarResourceTest {
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() throws Exception {
+ buildRule.configureProject("src/etc/testcases/types/resources/tarentry.xml");
+ }
+
+
+ @After
+ public void tearDown() throws Exception {
+ buildRule.executeTarget("tearDown");
+ }
+
+ @Test
+ public void testUncompressSource() throws java.io.IOException {
+ buildRule.executeTarget("uncompressSource");
+ assertEquals(getFileContents(buildRule.getProject().resolveFile("../../asf-logo.gif")),
+ getFileContents(new File(buildRule.getProject().getProperty("output"), "asf-logo.gif")));
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/selectors/BaseSelectorRule.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/selectors/BaseSelectorRule.java
new file mode 100644
index 00000000..d5613b26
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/selectors/BaseSelectorRule.java
@@ -0,0 +1,125 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types.selectors;
+
+import java.io.File;
+
+
+import org.apache.tools.ant.BuildFileRule;
+
+
+/**
+ * Base test case for Selectors. Provides a shared test as well as
+ * a test bed for selecting on, and a helper method for determining
+ * whether selections are correct.
+ *
+ */
+public class BaseSelectorRule extends BuildFileRule {
+
+ private File beddir;
+ private File mirrordir;
+ private final String[] filenames = {".","asf-logo.gif.md5","asf-logo.gif.bz2",
+ "asf-logo.gif.gz","copy.filterset.filtered","zip/asf-logo.gif.zip",
+ "tar/asf-logo.gif.tar","tar/asf-logo-huge.tar.gz",
+ "tar/gz/asf-logo.gif.tar.gz","tar/bz2/asf-logo.gif.tar.bz2",
+ "tar/bz2/asf-logo-huge.tar.bz2","tar/bz2"};
+ private File[] files = new File[filenames.length];
+ private File[] mirrorfiles = new File[filenames.length];
+
+ @Override
+ public void before() throws Throwable {
+ super.before();
+ configureProject("src/etc/testcases/types/selectors.xml");
+ executeTarget("setUp");
+
+ executeTarget("setupfiles");
+ executeTarget("mirrorfiles");
+
+ beddir = new File(super.getProject().getProperty("test.dir"));
+ mirrordir = new File(super.getProject().getProperty("mirror.dir"));
+
+ for (int x = 0; x < files.length; x++) {
+ files[x] = new File(beddir,filenames[x]);
+ mirrorfiles[x] = new File(mirrordir,filenames[x]);
+ }
+ }
+
+ @Override
+ public void after() {
+ super.after();
+ executeTarget("tearDown");
+ }
+
+ public File getBeddir() {
+ return beddir;
+ }
+
+ public File[] getMirrorFiles() {
+ return mirrorfiles;
+ }
+
+ public File[] getFiles() {
+ return files;
+ }
+
+ public String[] getFilenames() {
+ return filenames;
+ }
+
+
+ /**
+ * This is a helper method that takes a selector and calls its
+ * isSelected() method on each file in the testbed. It returns
+ * a string of "T"s amd "F"s
+ */
+ public String selectionString(FileSelector selector) {
+ return selectionString(beddir,files,selector);
+ }
+
+ /**
+ * This is a helper method that takes a selector and calls its
+ * isSelected() method on each file in the mirror testbed. This
+ * variation is used for dependency checks and to get around the
+ * limitations in the touch task when running JDK 1.1. It returns
+ * a string of "T"s amd "F"s.
+ */
+ public String mirrorSelectionString(FileSelector selector) {
+ return selectionString(mirrordir,mirrorfiles,selector);
+ }
+
+ /**
+ * Worker method for the two convenience methods above. Applies a
+ * selector on a set of files passed in and returns a string of
+ * "T"s amd "F"s from applying the selector to each file.
+ */
+ public String selectionString(File basedir, File[] files, FileSelector selector) {
+ StringBuilder buf = new StringBuilder();
+ for (int x = 0; x < files.length; x++) {
+ if (selector.isSelected(basedir,filenames[x],files[x])) {
+ buf.append('T');
+ }
+ else {
+ buf.append('F');
+ }
+ }
+ return buf.toString();
+ }
+
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/selectors/BaseSelectorTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/selectors/BaseSelectorTest.java
new file mode 100644
index 00000000..2332778e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/selectors/BaseSelectorTest.java
@@ -0,0 +1,295 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types.selectors;
+
+import java.io.File;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.BuildFileTest;
+import org.apache.tools.ant.Project;
+
+/**
+ * Base test case for Selectors. Provides a shared test as well as
+ * a test bed for selecting on, and a helper method for determining
+ * whether selections are correct.
+ *
+ * @deprecated as of 1.9.4. Use {@link org.apache.tools.ant.types.selectors.BaseSelectorRule} instead.
+ */
+@Deprecated
+public abstract class BaseSelectorTest extends BuildFileTest {
+
+ private Project project;
+ private TaskdefForMakingBed tbed = null;
+ protected File basedir;
+ protected File beddir;
+ protected File mirrordir;
+ protected String[] filenames = {".","asf-logo.gif.md5","asf-logo.gif.bz2",
+ "asf-logo.gif.gz","copy.filterset.filtered","zip/asf-logo.gif.zip",
+ "tar/asf-logo.gif.tar","tar/asf-logo-huge.tar.gz",
+ "tar/gz/asf-logo.gif.tar.gz","tar/bz2/asf-logo.gif.tar.bz2",
+ "tar/bz2/asf-logo-huge.tar.bz2","tar/bz2"};
+ protected File[] files = new File[filenames.length];
+ protected File[] mirrorfiles = new File[filenames.length];
+
+ public BaseSelectorTest(String name) {
+ super(name);
+ }
+
+ public void setUp() {
+ configureProject("src/etc/testcases/types/selectors.xml");
+ executeTarget("setUp");
+ beddir = new File(super.getProject().getProperty("test.dir"));
+ mirrordir = new File(super.getProject().getProperty("mirror.dir"));
+ basedir = getProjectDir();
+ project = new Project();
+ project.init();
+ project.setBaseDir(basedir);
+ for (int x = 0; x < files.length; x++) {
+ files[x] = new File(beddir,filenames[x]);
+ mirrorfiles[x] = new File(mirrordir,filenames[x]);
+ }
+ }
+
+ /**
+ * Override this in child classes to return a specific Selector
+ */
+ public abstract BaseSelector getInstance();
+
+
+ /**
+ * Return a preconfigured selector (with a set reference to
+ * project instance).
+ * @return the selector
+ */
+ public BaseSelector getSelector() {
+ BaseSelector selector = getInstance();
+ selector.setProject( getProject() );
+ return selector;
+ }
+
+
+ public Project getProject() {
+ return project;
+ }
+
+ /**
+ * This is a test that all Selectors derived from BaseSelector can
+ * use. It calls the setError() method and checks to ensure that a
+ * BuildException is thrown as a result.
+ */
+ public void testRespondsToError() {
+ BaseSelector s = getInstance();
+ if (s == null) {
+ return;
+ }
+ s.setError("test error");
+ try {
+ s.isSelected(beddir,filenames[0],files[0]);
+ fail("Cannot cause BuildException when setError() is called");
+ } catch (BuildException be) {
+ assertEquals("test error",
+ be.getMessage());
+ }
+ }
+
+
+ /**
+ * This is a helper method that takes a selector and calls its
+ * isSelected() method on each file in the testbed. It returns
+ * a string of "T"s amd "F"s
+ */
+ public String selectionString(FileSelector selector) {
+ return selectionString(beddir,files,selector);
+ }
+
+ /**
+ * This is a helper method that takes a selector and calls its
+ * isSelected() method on each file in the mirror testbed. This
+ * variation is used for dependency checks and to get around the
+ * limitations in the touch task when running JDK 1.1. It returns
+ * a string of "T"s amd "F"s.
+ */
+ public String mirrorSelectionString(FileSelector selector) {
+ return selectionString(mirrordir,mirrorfiles,selector);
+ }
+
+ /**
+ * Worker method for the two convenience methods above. Applies a
+ * selector on a set of files passed in and returns a string of
+ * "T"s amd "F"s from applying the selector to each file.
+ */
+ public String selectionString(File basedir, File[] files, FileSelector selector) {
+ StringBuffer buf = new StringBuffer();
+ for (int x = 0; x < files.length; x++) {
+ if (selector.isSelected(basedir,filenames[x],files[x])) {
+ buf.append('T');
+ }
+ else {
+ buf.append('F');
+ }
+ }
+ return buf.toString();
+ }
+
+ /**
+ * Does the selection test for a given selector and prints the
+ * filenames of the differing files (selected but shouldn't,
+ * not selected but should).
+ * @param selector The selector to test
+ * @param expected The expected result
+ */
+ public void performTests(FileSelector selector, String expected) {
+ String result = selectionString(selector);
+ String diff = diff(expected, result);
+ String resolved = resolve(diff);
+ assertEquals("Differing files: " + resolved, result, expected);
+ }
+
+ /**
+ * Checks which files are selected and shouldn't be or which
+ * are not selected but should.
+ * @param expected String containing 'F's and 'T's
+ * @param result String containing 'F's and 'T's
+ * @return Difference as String containing '-' (equal) and
+ * 'X' (difference).
+ */
+ public String diff(String expected, String result) {
+ int length1 = expected.length();
+ int length2 = result.length();
+ int min = (length1 > length2) ? length2 : length1;
+ StringBuffer sb = new StringBuffer();
+ for (int i=0; i<min; i++) {
+ sb.append(
+ (expected.charAt(i) == result.charAt(i))
+ ? "-"
+ : "X"
+ );
+ }
+ return sb.toString();
+ }
+
+
+ /**
+ * Resolves a diff-String (@see diff()) against the (inherited) filenames-
+ * and files arrays.
+ * @param filelist Diff-String
+ * @return String containing the filenames for all differing files,
+ * separated with semicolons ';'
+ */
+ public String resolve(String filelist) {
+ StringBuffer sb = new StringBuffer();
+ int min = (filenames.length > filelist.length())
+ ? filelist.length()
+ : filenames.length;
+ for (int i=0; i<min; i++) {
+ if ('X'==filelist.charAt(i)) {
+ sb.append(filenames[i]);
+ sb.append(";");
+ }
+ }
+ return sb.toString();
+ }
+
+
+ /**
+ * <p>Creates a testbed. We avoid the dreaded "test" word so that we
+ * don't falsely identify this as a test to be run. The actual
+ * setting up of the testbed is done in the
+ * <code>src/etc/testcases/types/selectors.xml</code> build file.</p>
+ *
+ * <p>Note that the right way to call this is within a try block,
+ * with a finally clause that calls cleanupBed(). You place tests of
+ * the isSelected() method within the try block.</p>
+ */
+ protected void makeBed() {
+ tbed = new TaskdefForMakingBed("setupfiles");
+ tbed.setUp();
+ tbed.makeTestbed();
+ }
+
+ /**
+ * Cleans up the testbed by calling a target in the
+ * <code>src/etc/testcases/types/selectors.xml</code> file.
+ */
+ protected void cleanupBed() {
+ if (tbed != null) {
+ tbed.tearDown();
+ tbed = null;
+ }
+ }
+
+
+ /**
+ * <p>Creates a mirror of the testbed for use in dependency checks.</p>
+ *
+ * <p>Note that the right way to call this is within a try block,
+ * with a finally clause that calls cleanupMirror(). You place tests of
+ * the isSelected() method within the try block.</p>
+ */
+ protected void makeMirror() {
+ tbed = new TaskdefForMakingBed("mirrorfiles");
+ tbed.setUp();
+ tbed.makeMirror();
+ }
+
+ /**
+ * Cleans up the mirror testbed by calling a target in the
+ * <code>src/etc/testcases/types/selectors.xml</code> file.
+ */
+ protected void cleanupMirror() {
+ if (tbed != null) {
+ tbed.deleteMirror();
+ tbed = null;
+ }
+ }
+
+ private class TaskdefForMakingBed extends BuildFileTest {
+
+ TaskdefForMakingBed(String name) {
+ super(name);
+ }
+
+ public void setUp() {
+ configureProject("src/etc/testcases/types/selectors.xml");
+ }
+
+ public void tearDown() {
+ try {
+ super.tearDown();
+ } catch (Exception exc) {
+ // ignore
+ }
+ }
+
+ public void makeTestbed() {
+ executeTarget("setupfiles");
+ }
+
+ public void makeMirror() {
+ executeTarget("mirrorfiles");
+ }
+
+ public void deleteMirror() {
+ executeTarget("tearDown");
+ }
+ }
+
+
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/selectors/ContainsRegexpTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/selectors/ContainsRegexpTest.java
new file mode 100644
index 00000000..41e9c830
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/selectors/ContainsRegexpTest.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types.selectors;
+
+import java.io.File;
+
+import org.apache.tools.ant.BuildFileRule;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+
+public class ContainsRegexpTest {
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/types/selectors.xml");
+ }
+
+ @Test
+ public void testContainsRegexp() {
+ buildRule.executeTarget("containsregexp");
+ File dir = new File(buildRule.getOutputDir(), "regexpseltestdest");
+ File[] files = dir.listFiles();
+ int filecount = files.length;
+
+ if (filecount != 1) {
+ assertEquals("ContainsRegexp test should have copied 1 file",
+ 1, files.length);
+
+ }
+ }
+
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/selectors/ContainsSelectorTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/selectors/ContainsSelectorTest.java
new file mode 100644
index 00000000..9a5a83fe
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/selectors/ContainsSelectorTest.java
@@ -0,0 +1,114 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types.selectors;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.types.Parameter;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+/**
+ * Tests Contains Selectors.
+ *
+ */
+public class ContainsSelectorTest {
+
+ @Rule
+ public final BaseSelectorRule selectorRule = new BaseSelectorRule();
+
+
+ /**
+ * Test the code that validates the selector.
+ */
+ @Test
+ public void testValidate() {
+ ContainsSelector s = new ContainsSelector();
+ try {
+ s.isSelected(selectorRule.getProject().getBaseDir(),selectorRule.getFilenames()[0],selectorRule.getFiles()[0]);
+ fail("ContainsSelector did not check for required field 'text'");
+ } catch (BuildException be1) {
+ assertEquals("The text attribute is required", be1.getMessage());
+ }
+
+ s = new ContainsSelector();
+ Parameter param = new Parameter();
+ param.setName("garbage in");
+ param.setValue("garbage out");
+ Parameter[] params = {param};
+ s.setParameters(params);
+ try {
+ s.isSelected(selectorRule.getProject().getBaseDir(),selectorRule.getFilenames()[0],selectorRule.getFiles()[0]);
+ fail("ContainsSelector did not check for valid parameter element");
+ } catch (BuildException be2) {
+ assertEquals("Invalid parameter garbage in", be2.getMessage());
+ }
+
+ }
+
+ /**
+ * Tests to make sure that the selector is selecting files correctly.
+ */
+ @Test
+ public void testSelectionBehaviour() {
+ ContainsSelector s;
+ String results;
+
+
+ s = new ContainsSelector();
+ s.setText("no such string in test files");
+ results = selectorRule.selectionString(s);
+ assertEquals("TFFFFFFFFFFT", results);
+
+ s = new ContainsSelector();
+ s.setText("Apache Ant");
+ results = selectorRule.selectionString(s);
+ assertEquals("TFFFTFFFFFFT", results);
+
+ s = new ContainsSelector();
+ s.setText("apache ant");
+ s.setCasesensitive(true);
+ results = selectorRule.selectionString(s);
+ assertEquals("TFFFFFFFFFFT", results);
+
+ s = new ContainsSelector();
+ s.setText("apache ant");
+ s.setCasesensitive(false);
+ results = selectorRule.selectionString(s);
+ assertEquals("TFFFTFFFFFFT", results);
+
+ s = new ContainsSelector();
+ s.setText("ApacheAnt");
+ s.setIgnorewhitespace(true);
+ results = selectorRule.selectionString(s);
+ assertEquals("TFFFTFFFFFFT", results);
+
+ s = new ContainsSelector();
+ s.setText("A p a c h e A n t");
+ s.setIgnorewhitespace(true);
+ results = selectorRule.selectionString(s);
+ assertEquals("TFFFTFFFFFFT", results);
+
+
+
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/selectors/DateSelectorTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/selectors/DateSelectorTest.java
new file mode 100644
index 00000000..6e461bab
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/selectors/DateSelectorTest.java
@@ -0,0 +1,229 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types.selectors;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.types.Parameter;
+import org.junit.Assume;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+
+/**
+ * Tests Date Selectors.
+ *
+ */
+public class DateSelectorTest {
+
+ @Rule
+ public final BaseSelectorRule selectorRule = new BaseSelectorRule();
+
+
+ /**
+ * Test the code that validates the selector.
+ */
+ @Test
+ public void testValidate() {
+ DateSelector s = new DateSelector();
+ try {
+ s.isSelected(selectorRule.getProject().getBaseDir(),selectorRule.getFilenames()[0],selectorRule.getFiles()[0]);
+ fail("DateSelector did not check for required fields");
+ } catch (BuildException be1) {
+ assertEquals("You must provide a datetime or the number of "
+ + "milliseconds.", be1.getMessage());
+ }
+
+ s = new DateSelector();
+ s.setDatetime("01/01/1969 01:01 AM");
+ try {
+ s.isSelected(selectorRule.getProject().getBaseDir(),selectorRule.getFilenames()[0],selectorRule.getFiles()[0]);
+ fail("DateSelector did not check for Datetime being in the "
+ + "allowable range");
+ } catch (BuildException be2) {
+ assertEquals("Date of 01/01/1969 01:01 AM results in negative "
+ + "milliseconds value relative to epoch (January 1, "
+ + "1970, 00:00:00 GMT).", be2.getMessage());
+ }
+
+ s = new DateSelector();
+ s.setDatetime("this is not a date");
+ try {
+ s.isSelected(selectorRule.getProject().getBaseDir(),selectorRule.getFilenames()[0],selectorRule.getFiles()[0]);
+ fail("DateSelector did not check for Datetime being in a "
+ + "valid format");
+ } catch (BuildException be3) {
+ assertEquals("Date of this is not a date"
+ + " Cannot be parsed correctly. It should be in"
+ + " MM/DD/YYYY HH:MM AM_PM format.", be3.getMessage());
+ }
+
+ s = new DateSelector();
+ Parameter param = new Parameter();
+ param.setName("garbage in");
+ param.setValue("garbage out");
+ Parameter[] params = new Parameter[1];
+ params[0] = param;
+ s.setParameters(params);
+ try {
+ s.isSelected(selectorRule.getProject().getBaseDir(),selectorRule.getFilenames()[0],selectorRule.getFiles()[0]);
+ fail("DateSelector did not check for valid parameter element");
+ } catch (BuildException be4) {
+ assertEquals("Invalid parameter garbage in", be4.getMessage());
+ }
+
+ s = new DateSelector();
+ param = new Parameter();
+ param.setName("millis");
+ param.setValue("garbage out");
+ params[0] = param;
+ s.setParameters(params);
+ try {
+ s.isSelected(selectorRule.getProject().getBaseDir(),selectorRule.getFilenames()[0],selectorRule.getFiles()[0]);
+ fail("DateSelector did not check for valid millis parameter");
+ } catch (BuildException be5) {
+ assertEquals("Invalid millisecond setting garbage out",
+ be5.getMessage());
+ }
+
+ s = new DateSelector();
+ param = new Parameter();
+ param.setName("granularity");
+ param.setValue("garbage out");
+ params[0] = param;
+ s.setParameters(params);
+ try {
+ s.isSelected(selectorRule.getProject().getBaseDir(),selectorRule.getFilenames()[0],selectorRule.getFiles()[0]);
+ fail("DateSelector did not check for valid granularity parameter");
+ } catch (BuildException be6) {
+ assertEquals("Invalid granularity setting garbage out",
+ be6.getMessage());
+ }
+
+ }
+
+ /**
+ * Tests to make sure that the selector is selecting files correctly.
+ */
+ @Test
+ public void testSelectionBehaviour() {
+ DateSelector s;
+ String results;
+
+ DateSelector.TimeComparisons before = new
+ DateSelector.TimeComparisons();
+ before.setValue("before");
+ DateSelector.TimeComparisons equal = new
+ DateSelector.TimeComparisons();
+ equal.setValue("equal");
+ DateSelector.TimeComparisons after = new
+ DateSelector.TimeComparisons();
+ after.setValue("after");
+
+
+ s = new DateSelector();
+ s.setDatetime("10/10/1999 1:45 PM");
+ s.setWhen(before);
+ results = selectorRule.selectionString(s);
+ assertEquals("TFFFFFFFFFFT", results);
+
+ s = new DateSelector();
+ s.setDatetime("10/10/1999 1:45 PM");
+ s.setWhen(before);
+ s.setCheckdirs(true);
+ results = selectorRule.selectionString(s);
+ assertEquals("FFFFFFFFFFFF", results);
+
+ s = new DateSelector();
+ s.setDatetime("10/10/1999 1:45 PM");
+ s.setWhen(after);
+ results = selectorRule.selectionString(s);
+ assertEquals("TTTTTTTTTTTT", results);
+
+ s = new DateSelector();
+ s.setDatetime("11/21/2001 4:54 AM");
+ s.setWhen(before);
+ results = selectorRule.selectionString(s);
+ assertEquals("TFTFFFFFFFFT", results);
+
+ s = new DateSelector();
+ s.setDatetime("11/21/2001 4:55 AM");
+
+ long milliseconds = s.getMillis();
+ s.setWhen(equal);
+ results = selectorRule.selectionString(s);
+ assertEquals("TTFFTFFFTTTT", results);
+
+ s = new DateSelector();
+ s.setMillis(milliseconds);
+ s.setWhen(equal);
+ results = selectorRule.selectionString(s);
+ assertEquals("TTFFTFFFTTTT", results);
+
+ s = new DateSelector();
+ s.setDatetime("11/21/2001 4:56 AM");
+ s.setWhen(after);
+ results = selectorRule.selectionString(s);
+ assertEquals("TFFTFTTTFFFT", results);
+
+ s = new DateSelector();
+ Parameter param1 = new Parameter();
+ Parameter param2 = new Parameter();
+ param1.setName("datetime");
+ param1.setValue("11/21/2001 4:56 AM");
+ param2.setName("when");
+ param2.setValue("after");
+ Parameter[] params = {param1,param2};
+ s.setParameters(params);
+ results = selectorRule.selectionString(s);
+ assertEquals("TFFTFTTTFFFT", results);
+
+ s = new DateSelector();
+ long testtime = selectorRule.getMirrorFiles()[5].lastModified();
+ s.setMillis(testtime);
+ s.setWhen(after);
+ s.setGranularity(2);
+
+ // setup the modified timestamp to match what the test needs, although be aware that the 3rd and 4th
+ // files don't exist so can't be changed, so don't try and loop over them
+ for (int i = 1; i <=2; i++) {
+ Assume.assumeTrue("Cannot setup file times for test", selectorRule.getMirrorFiles()[i].setLastModified(testtime - (3*60*60*100)));
+ }
+
+
+ results = selectorRule.mirrorSelectionString(s);
+ assertEquals("TFFFFTTTTTTT", results);
+
+ s = new DateSelector();
+ testtime = selectorRule.getMirrorFiles()[6].lastModified();
+ s.setMillis(testtime);
+ s.setWhen(before);
+ s.setGranularity(2);
+ for (int i = 7; i <= 10; i++) {
+ Assume.assumeTrue("Cannot setup file times for test", selectorRule.getMirrorFiles()[i].setLastModified(testtime + (3*60*60*100)));
+ }
+
+ results = selectorRule.mirrorSelectionString(s);
+ assertEquals("TTTTTTTFFFFT", results);
+
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/selectors/DependSelectorTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/selectors/DependSelectorTest.java
new file mode 100644
index 00000000..ec95878a
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/selectors/DependSelectorTest.java
@@ -0,0 +1,185 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types.selectors;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.types.Mapper;
+import org.junit.Rule;
+import org.junit.Test;
+
+import java.io.File;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+
+/**
+ * Tests Depend Selectors
+ *
+ */
+public class DependSelectorTest {
+
+ @Rule
+ public final BaseSelectorRule selectorRule = new BaseSelectorRule();
+
+ @Test
+ public void testValidateSingleMapper() {
+ try {
+ DependSelector s = new DependSelector();
+ s.createMapper();
+ s.createMapper();
+ fail("DependSelector allowed more than one nested mapper.");
+ } catch (BuildException be1) {
+ assertEquals("Cannot define more than one mapper",
+ be1.getMessage());
+ }
+ }
+
+
+ @Test
+ public void testValidateRequiredFields() {
+ try {
+ DependSelector s = new DependSelector();
+ s.isSelected(selectorRule.getProject().getBaseDir(), selectorRule.getFilenames()[0], selectorRule.getFiles()[0]);
+ fail("DependSelector did not check for required fields");
+ } catch (BuildException be2) {
+ assertEquals("The targetdir attribute is required.",
+ be2.getMessage());
+ }
+
+ }
+
+ @Test
+ public void testNoMapper() {
+ DependSelector s = new DependSelector();
+ s.setTargetdir(selectorRule.getBeddir());
+
+ String results = selectorRule.selectionString(s);
+ assertEquals("FFFFFFFFFFFF", results);
+ }
+
+ @Test
+ public void testIdentityMapper() {
+ DependSelector s = new DependSelector();
+ s.setTargetdir(selectorRule.getBeddir());
+
+ Mapper.MapperType identity = new Mapper.MapperType();
+ identity.setValue("identity");
+
+ Mapper m = s.createMapper();
+ m.setType(identity);
+
+ String results = selectorRule.selectionString(s);
+ assertEquals("FFFFFFFFFFFF", results);
+ }
+
+ @Test
+ public void testMergeMapper() {
+ DependSelector s = new DependSelector();
+ s.setTargetdir(selectorRule.getBeddir());
+
+ Mapper.MapperType merge = new Mapper.MapperType();
+ merge.setValue("merge");
+
+ Mapper m = s.createMapper();
+ m.setType(merge);
+ m.setTo("asf-logo.gif.gz");
+
+ String results = selectorRule.selectionString(s);
+ assertEquals("TFFFFTTTFFF", results.substring(0,11));
+ }
+
+ @Test
+ public void testMergeMapper2() {
+ DependSelector s = new DependSelector();
+ s.setTargetdir(selectorRule.getBeddir());
+
+ Mapper.MapperType merge = new Mapper.MapperType();
+ merge.setValue("merge");
+
+ Mapper m = s.createMapper();
+ m.setType(merge);
+ m.setTo("asf-logo.gif.bz2");
+ String results = selectorRule.selectionString(s);
+ assertEquals("TTFTTTTTTTTT", results);
+ }
+
+ @Test
+ public void testGlobMapperRelativePath() {
+ DependSelector s = new DependSelector();
+ File subdir = new File("selectortest/tar/bz2");
+ s.setTargetdir(subdir);
+
+ Mapper.MapperType glob = new Mapper.MapperType();
+ glob.setValue("glob");
+
+ Mapper m = s.createMapper();
+ m.setType(glob);
+ m.setFrom("*.bz2");
+ m.setTo("*.tar.bz2");
+
+ String results = selectorRule.selectionString(s);
+ assertEquals("FFTFFFFFFTTF", results);
+ }
+
+ @Test
+ public void testRestrictedGlobMapper() {
+ DependSelector s = new DependSelector();
+ File subdir = new File(selectorRule.getBeddir(), "tar/bz2");
+ s.setTargetdir(subdir);
+
+ Mapper.MapperType glob = new Mapper.MapperType();
+ glob.setValue("glob");
+
+ Mapper m = s.createMapper();
+ m.setType(glob);
+ m.setFrom("*.bz2");
+ m.setTo("*.tar.bz2");
+ String results = selectorRule.selectionString(s);
+ assertEquals("FFFFFFFFFTTF", results);
+ }
+
+ @Test
+ public void testSelectionNoMapper() {
+ DependSelector s = new DependSelector();
+ s.setTargetdir(new File(selectorRule.getOutputDir(), "selectortest2"));
+ String results = selectorRule.selectionString(s);
+ assertEquals("FFFTTFFFFFFF", results);
+ }
+
+
+ @Test
+ public void testMirroredSelection() {
+ DependSelector s = new DependSelector();
+ s.setTargetdir(new File(selectorRule.getOutputDir(), "selectortest2/tar/bz2"));
+
+ Mapper.MapperType glob = new Mapper.MapperType();
+ glob.setValue("glob");
+
+ Mapper m = s.createMapper();
+ m.setType(glob);
+ m.setFrom("*.bz2");
+ m.setTo("*.tar.bz2");
+ String results = selectorRule.mirrorSelectionString(s);
+ assertEquals("FFFFFFFFFTTF", results);
+ results = selectorRule.selectionString(s);
+ assertEquals("FFFFFFFFFTTF", results);
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/selectors/DepthSelectorTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/selectors/DepthSelectorTest.java
new file mode 100644
index 00000000..391fb27d
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/selectors/DepthSelectorTest.java
@@ -0,0 +1,147 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types.selectors;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.types.Parameter;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+/**
+ * Tests Depth Selectors
+ *
+ */
+public class DepthSelectorTest {
+
+ @Rule
+ public final BaseSelectorRule selectorRule = new BaseSelectorRule();
+
+
+ /**
+ * Test the code that validates the selector.
+ */
+ @Test
+ public void testValidate() {
+ DepthSelector s = new DepthSelector();
+ try {
+ s.isSelected(selectorRule.getProject().getBaseDir(),selectorRule.getFilenames()[0],selectorRule.getFiles()[0]);
+ fail("DepthSelector did not check for required fields");
+ } catch (BuildException be1) {
+ assertEquals("You must set at least one of the min or the " +
+ "max levels.", be1.getMessage());
+ }
+
+ s = new DepthSelector();
+ s.setMin(5);
+ s.setMax(2);
+ try {
+ s.isSelected(selectorRule.getProject().getBaseDir(),selectorRule.getFilenames()[0],selectorRule.getFiles()[0]);
+ fail("DepthSelector did not check for maximum being higher "
+ + "than minimum");
+ } catch (BuildException be2) {
+ assertEquals("The maximum depth is lower than the minimum.",
+ be2.getMessage());
+ }
+
+ s = new DepthSelector();
+ Parameter param = new Parameter();
+ param.setName("garbage in");
+ param.setValue("garbage out");
+ Parameter[] params = new Parameter[1];
+ params[0] = param;
+ s.setParameters(params);
+ try {
+ s.isSelected(selectorRule.getProject().getBaseDir(),selectorRule.getFilenames()[0],selectorRule.getFiles()[0]);
+ fail("DepthSelector did not check for valid parameter element");
+ } catch (BuildException be3) {
+ assertEquals("Invalid parameter garbage in", be3.getMessage());
+ }
+
+ s = new DepthSelector();
+ param = new Parameter();
+ param.setName("min");
+ param.setValue("garbage out");
+ params[0] = param;
+ s.setParameters(params);
+ try {
+ s.isSelected(selectorRule.getProject().getBaseDir(),selectorRule.getFilenames()[0],selectorRule.getFiles()[0]);
+ fail("DepthSelector accepted bad minimum as parameter");
+ } catch (BuildException be4) {
+ assertEquals("Invalid minimum value garbage out",
+ be4.getMessage());
+ }
+
+ s = new DepthSelector();
+ param = new Parameter();
+ param.setName("max");
+ param.setValue("garbage out");
+ params[0] = param;
+ s.setParameters(params);
+ try {
+ s.isSelected(selectorRule.getProject().getBaseDir(),selectorRule.getFilenames()[0],selectorRule.getFiles()[0]);
+ fail("DepthSelector accepted bad maximum as parameter");
+ } catch (BuildException be5) {
+ assertEquals("Invalid maximum value garbage out",
+ be5.getMessage());
+ }
+
+ }
+
+ /**
+ * Tests to make sure that the selector is selecting files correctly.
+ */
+ @Test
+ public void testSelectionBehaviour() {
+ DepthSelector s;
+ String results;
+
+ s = new DepthSelector();
+ s.setMin(20);
+ s.setMax(25);
+ results = selectorRule.selectionString(s);
+ assertEquals("FFFFFFFFFFFF", results);
+
+ s = new DepthSelector();
+ s.setMin(0);
+ results = selectorRule.selectionString(s);
+ assertEquals("TTTTTTTTTTTT", results);
+
+ s = new DepthSelector();
+ s.setMin(1);
+ results = selectorRule.selectionString(s);
+ assertEquals("FFFFFTTTTTTT", results);
+
+ s = new DepthSelector();
+ s.setMax(0);
+ results = selectorRule.selectionString(s);
+ assertEquals("TTTTTFFFFFFF", results);
+
+ s = new DepthSelector();
+ s.setMin(1);
+ s.setMax(1);
+ results = selectorRule.selectionString(s);
+ assertEquals("FFFFFTTTFFFT", results);
+
+
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/selectors/FilenameSelectorTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/selectors/FilenameSelectorTest.java
new file mode 100644
index 00000000..ce7729a8
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/selectors/FilenameSelectorTest.java
@@ -0,0 +1,115 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types.selectors;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.types.Parameter;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+/**
+ * Tests Filename Selectors
+ *
+ */
+public class FilenameSelectorTest {
+
+ @Rule
+ public final BaseSelectorRule selectorRule = new BaseSelectorRule();
+
+ /**
+ * Test the code that validates the selector.
+ */
+ @Test
+ public void testValidate() {
+ FilenameSelector s = new FilenameSelector();
+ try {
+ s.isSelected(selectorRule.getProject().getBaseDir(),selectorRule.getFilenames()[0],selectorRule.getFiles()[0]);
+ fail("FilenameSelector did not check for required fields");
+ } catch (BuildException be1) {
+ assertEquals("The name or regex attribute is required", be1.getMessage());
+ }
+
+ s = new FilenameSelector();
+ Parameter param = new Parameter();
+ param.setName("garbage in");
+ param.setValue("garbage out");
+ Parameter[] params = {param};
+ s.setParameters(params);
+ try {
+ s.isSelected(selectorRule.getProject().getBaseDir(),selectorRule.getFilenames()[0],selectorRule.getFiles()[0]);
+ fail("FilenameSelector did not check for valid parameter element");
+ } catch (BuildException be2) {
+ assertEquals("Invalid parameter garbage in", be2.getMessage());
+ }
+
+ }
+
+ /**
+ * Tests to make sure that the selector is selecting files correctly.
+ */
+ @Test
+ public void testSelectionBehaviour() {
+ FilenameSelector s;
+ String results;
+
+
+ s = new FilenameSelector();
+ s.setName("no match possible");
+ results = selectorRule.selectionString(s);
+ assertEquals("FFFFFFFFFFFF", results);
+
+ s = new FilenameSelector();
+ s.setName("*.gz");
+ results = selectorRule.selectionString(s);
+ // This is turned off temporarily. There appears to be a bug
+ // in SelectorUtils.matchPattern() where it is recursive on
+ // Windows even if no ** is in pattern.
+ //assertEquals("FFFTFFFFFFFF", results); // Unix
+ // vs
+ //assertEquals("FFFTFFFFTFFF", results); // Windows
+
+ s = new FilenameSelector();
+ s.setName("**/*.gz");
+ s.setNegate(true);
+ results = selectorRule.selectionString(s);
+ assertEquals("TTTFTTTFFTTT", results);
+
+ s = new FilenameSelector();
+ s.setName("**/*.GZ");
+ s.setCasesensitive(false);
+ results = selectorRule.selectionString(s);
+ assertEquals("FFFTFFFTTFFF", results);
+
+ s = new FilenameSelector();
+ Parameter param1 = new Parameter();
+ param1.setName("name");
+ param1.setValue("**/*.bz2");
+ Parameter[] params = {param1};
+ s.setParameters(params);
+ results = selectorRule.selectionString(s);
+ assertEquals("FFTFFFFFFTTF", results);
+
+
+
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/selectors/MockAlgorithm.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/selectors/MockAlgorithm.java
new file mode 100644
index 00000000..458c83fe
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/selectors/MockAlgorithm.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types.selectors;
+
+
+import java.io.File;
+import org.apache.tools.ant.types.selectors.modifiedselector.Algorithm;
+
+public class MockAlgorithm implements Algorithm {
+ public boolean isValid() {
+ return true;
+ }
+
+ public String getValue(File file) {
+ return "TEST";
+ }
+
+ public String toString() {
+ return "MockAlgorithm@" + hashCode();
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/selectors/MockCache.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/selectors/MockCache.java
new file mode 100644
index 00000000..e501a6b8
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/selectors/MockCache.java
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types.selectors;
+
+
+import java.util.Iterator;
+import org.apache.tools.ant.types.selectors.modifiedselector.Cache;
+
+public class MockCache implements Cache {
+
+ public boolean debug = false;
+ public boolean saved = false;
+
+
+ public MockCache() {
+ log("()");
+ }
+
+ public boolean isValid() {
+ log(".isValid()");
+ return true;
+ }
+ public void delete() {
+ log(".delete()");
+ }
+ public void load() {
+ log(".load()");
+ }
+ public void save() {
+ log(".save()");
+ saved = true;
+ }
+ public Object get(Object key) {
+ log(".get("+key+")");
+ return key;
+ }
+ public void put(Object key, Object value) {
+ log(".put("+key+", "+value+")");
+ saved = false;
+ }
+ public Iterator<String> iterator() {
+ log("iterator()");
+ return null;
+ }
+ public String toString() {
+ return "MockCache@" + hashCode();
+ }
+
+ private void log(String msg) {
+ if (debug) System.out.println(this+msg);
+ }
+}//class-MockCache
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/selectors/MockComparator.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/selectors/MockComparator.java
new file mode 100644
index 00000000..a7c15539
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/selectors/MockComparator.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types.selectors;
+
+import java.util.Comparator;
+
+public class MockComparator implements Comparator {
+
+ public int compare(Object o1, Object o2) {
+ return 0;
+ }
+
+ public String toString() {
+ return "MockComparator";
+ }
+}//class-MockCache
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/selectors/ModifiedSelectorTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/selectors/ModifiedSelectorTest.java
new file mode 100644
index 00000000..80dd6dfa
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/selectors/ModifiedSelectorTest.java
@@ -0,0 +1,1062 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types.selectors;
+
+
+// Java
+import java.io.File;
+import java.text.RuleBasedCollator;
+import java.util.Comparator;
+import java.util.Iterator;
+
+import org.apache.tools.ant.AntAssert;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.BuildFileRule;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Target;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.types.Parameter;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.types.selectors.modifiedselector.Algorithm;
+import org.apache.tools.ant.types.selectors.modifiedselector.Cache;
+import org.apache.tools.ant.types.selectors.modifiedselector.ChecksumAlgorithm;
+import org.apache.tools.ant.types.selectors.modifiedselector.DigestAlgorithm;
+import org.apache.tools.ant.types.selectors.modifiedselector.EqualComparator;
+import org.apache.tools.ant.types.selectors.modifiedselector.HashvalueAlgorithm;
+import org.apache.tools.ant.types.selectors.modifiedselector.ModifiedSelector;
+import org.apache.tools.ant.types.selectors.modifiedselector.PropertiesfileCache;
+import org.apache.tools.ant.util.FileUtils;
+import org.junit.Assume;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+
+/**
+ * Unit tests for ModifiedSelector.
+ *
+ * @since Ant 1.6
+ */
+public class ModifiedSelectorTest {
+
+ @Rule
+ public final BaseSelectorRule selectorRule = new BaseSelectorRule();
+
+ /** Utilities used for file operations */
+ private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+
+ // ===================== attributes =====================
+
+
+ /** Path where the testclasses are. */
+ private Path testclasses = null;
+
+
+
+
+ // ===================== JUnit stuff =====================
+
+
+ @Before
+ public void setUp() {
+ // init the testclasses path object
+ Project prj = selectorRule.getProject();
+ testclasses = new Path(prj, prj.getProperty("build.tests.value"));
+ }
+
+
+ // ======= testcases for the attributes and nested elements of the selector =====
+
+
+ /** Test right use of cache names. */
+ @Test
+ public void testValidateWrongCache() {
+ String name = "this-is-not-a-valid-cache-name";
+ try {
+ ModifiedSelector.CacheName cacheName = new ModifiedSelector.CacheName();
+ cacheName.setValue(name);
+ fail("CacheSelector.CacheName accepted invalid value.");
+ } catch (BuildException be) {
+ assertEquals(name + " is not a legal value for this attribute",
+ be.getMessage());
+ }
+ }
+
+
+ /** Test right use of cache names. */
+ @Test
+ public void testValidateWrongAlgorithm() {
+ String name = "this-is-not-a-valid-algorithm-name";
+ try {
+ ModifiedSelector.AlgorithmName algoName
+ = new ModifiedSelector.AlgorithmName();
+ algoName.setValue(name);
+ fail("CacheSelector.AlgorithmName accepted invalid value.");
+ } catch (BuildException be) {
+ assertEquals(name + " is not a legal value for this attribute",
+ be.getMessage());
+ }
+ }
+
+
+ /** Test right use of comparator names. */
+ @Test
+ public void testValidateWrongComparator() {
+ String name = "this-is-not-a-valid-comparator-name";
+ try {
+ ModifiedSelector.ComparatorName compName
+ = new ModifiedSelector.ComparatorName();
+ compName.setValue(name);
+ fail("ModifiedSelector.ComparatorName accepted invalid value.");
+ } catch (BuildException be) {
+ assertEquals(name + " is not a legal value for this attribute",
+ be.getMessage());
+ }
+ }
+
+
+ @Test
+ public void testIllegalCustomAlgorithm() {
+ try {
+ getAlgoName("java.lang.Object");
+ fail("Illegal classname used.");
+ } catch (BuildException e) {
+ assertEquals("Wrong exception message.",
+ "Specified class (java.lang.Object) is not an Algorithm.",
+ e.getMessage());
+
+ }
+ }
+
+
+ @Test
+ public void testNonExistentCustomAlgorithm() {
+ try {
+ getAlgoName("non.existent.custom.Algorithm");
+ fail("does 'non.existent.custom.Algorithm' really exist?");
+ } catch (BuildException e) {
+ assertEquals("Wrong exception message.",
+ "Specified class (non.existent.custom.Algorithm) not found.",
+ e.getMessage());
+
+ }
+ }
+
+ @Test
+ public void testCustomAlgorithm() {
+ String algo = getAlgoName("org.apache.tools.ant.types.selectors.modifiedselector.HashvalueAlgorithm");
+ assertTrue("Wrong algorithm used: "+algo, algo.startsWith("HashvalueAlgorithm"));
+ }
+
+ @Test
+ public void testCustomAlgorithm2() {
+ String algo = getAlgoName("org.apache.tools.ant.types.selectors.MockAlgorithm");
+ assertTrue("Wrong algorithm used: "+algo, algo.startsWith("MockAlgorithm"));
+ }
+
+
+ @Test
+ public void testCustomClasses() {
+ Assume.assumeNotNull("Ant home not set", selectorRule.getProject().getProperty("ant.home") );
+ BFT bft = new BFT();
+ bft.setUp();
+ try {
+ // do the actions
+ bft.doTarget("modifiedselectortest-customClasses");
+ // do the checks - the buildfile stores the fileset as property
+ String fsFullValue = bft.getProperty("fs.full.value");
+ String fsModValue = bft.getProperty("fs.mod.value");
+
+ assertNotNull("'fs.full.value' must be set.", fsFullValue);
+ assertTrue("'fs.full.value' must not be null.", !"".equals(fsFullValue));
+ assertTrue("'fs.full.value' must contain ant.bat.", fsFullValue.indexOf("ant.bat")>-1);
+
+ assertNotNull("'fs.mod.value' must be set.", fsModValue);
+ // must be empty according to the Mock* implementations
+ assertTrue("'fs.mod.value' must be empty.", "".equals(fsModValue));
+ // don't catch the JUnit exceptions
+ } finally {
+ bft.doTarget("modifiedselectortest-scenario-clean");
+ bft.deletePropertiesfile();
+ bft.tearDown();
+ }
+ }
+
+
+ @Test
+ public void testDelayUpdateTaskFinished() {
+ doDelayUpdateTest(1);
+ }
+
+
+ @Test
+ public void testDelayUpdateTargetFinished() {
+ doDelayUpdateTest(2);
+ }
+
+
+ @Test
+ public void testDelayUpdateBuildFinished() {
+ doDelayUpdateTest(3);
+ }
+
+
+ public void doDelayUpdateTest(int kind) {
+ // no check for 1<=kind<=3 - only internal use therefore check it
+ // while development
+
+ // readable form of parameter kind
+ String[] kinds = {"task", "target", "build"};
+
+ // setup the "Ant project"
+ MockProject project = new MockProject();
+ File base = new File("base");
+ File file1 = new File("file1");
+ File file2 = new File("file2");
+
+ // setup the selector
+ ModifiedSelector sel = new ModifiedSelector();
+ sel.setProject(project);
+ sel.setUpdate(true);
+ sel.setDelayUpdate(true);
+ // sorry - otherwise we will get a ClassCastException because the MockCache
+ // is loaded by two different classloader ...
+ sel.setClassLoader(this.getClass().getClassLoader());
+ sel.addClasspath(testclasses);
+
+ sel.setAlgorithmClass("org.apache.tools.ant.types.selectors.MockAlgorithm");
+ sel.setCacheClass("org.apache.tools.ant.types.selectors.MockCache");
+ sel.configure();
+
+ // get the cache, so we can check our things
+ MockCache cache = (MockCache)sel.getCache();
+
+ // the test
+ assertFalse("Cache must not be saved before 1st selection.", cache.saved);
+ sel.isSelected(base, "file1", file1);
+ assertFalse("Cache must not be saved after 1st selection.", cache.saved);
+ sel.isSelected(base, "file2", file2);
+ assertFalse("Cache must not be saved after 2nd selection.", cache.saved);
+ switch (kind) {
+ case 1 : project.fireTaskFinished(); break;
+ case 2 : project.fireTargetFinished(); break;
+ case 3 : project.fireBuildFinished(); break;
+ }
+ assertTrue("Cache must be saved after " + kinds[kind-1] + "Finished-Event.", cache.saved);
+
+ // MockCache doesnt create a file - therefore no cleanup needed
+ }
+
+
+ /**
+ * Extracts the real used algorithm name from the ModifiedSelector using
+ * its toString() method.
+ * @param classname the classname from the algorithm to use
+ * @return the algorithm part from the toString() (without brackets)
+ */
+ private String getAlgoName(String classname) {
+ ModifiedSelector sel = new ModifiedSelector();
+ sel.setProject(selectorRule.getProject());
+ // add the test classes to its classpath
+ sel.addClasspath(testclasses);
+ sel.setAlgorithmClass(classname);
+ // let the selector do its checks
+ sel.validate();
+ // extract the algorithm name (and config) from the selectors output
+ String s1 = sel.toString();
+ int posStart = s1.indexOf("algorithm=") + 10;
+ int posEnd = s1.indexOf(" comparator=");
+ String algo = s1.substring(posStart, posEnd);
+ // '<' and '>' are only used if the algorithm has properties
+ if (algo.startsWith("<")) algo = algo.substring(1);
+ if (algo.endsWith(">")) algo = algo.substring(0, algo.length()-1);
+ // return the clean value
+ return algo;
+ }
+
+
+ // ================ testcases for the cache implementations ================
+
+
+ /**
+ * Propertycache must have a set 'cachefile' attribute.
+ * The default in ModifiedSelector "cache.properties" is set by the selector.
+ */
+ @Test
+ public void testPropcacheInvalid() {
+ Cache cache = new PropertiesfileCache();
+ if (cache.isValid())
+ fail("PropertyfilesCache does not check its configuration.");
+ }
+
+
+ @Test
+ public void testPropertyfileCache() {
+ PropertiesfileCache cache = new PropertiesfileCache();
+ File cachefile = new File("cache.properties");
+ cache.setCachefile(cachefile);
+ doTest(cache);
+ assertFalse("Cache file not deleted.", cachefile.exists());
+ }
+
+
+ /** Checks whether a cache file is created. */
+ @Test
+ public void testCreatePropertiesCacheDirect() {
+ File cachefile = new File(selectorRule.getProject().getBaseDir(), "cachefile.properties");
+
+ PropertiesfileCache cache = new PropertiesfileCache();
+ cache.setCachefile(cachefile);
+
+ cache.put("key", "value");
+ cache.save();
+
+ assertTrue("Cachefile not created.", cachefile.exists());
+
+ cache.delete();
+ assertFalse("Cachefile not deleted.", cachefile.exists());
+ }
+
+
+ /** Checks whether a cache file is created. */
+ @Test
+ public void testCreatePropertiesCacheViaModifiedSelector() {
+ File cachefile = new File(selectorRule.getProject().getBaseDir(), "cachefile.properties");
+
+ // Configure the selector
+ ModifiedSelector s = new ModifiedSelector();
+ s.setDelayUpdate(false);
+ s.addParam("cache.cachefile", cachefile);
+
+ ModifiedSelector.CacheName cacheName = new ModifiedSelector.CacheName();
+ cacheName.setValue("propertyfile");
+ s.setCache(cacheName);
+
+ s.setUpdate(true);
+
+ selectorRule.selectionString(s);
+
+ // evaluate correctness
+ assertTrue("Cache file is not created.", cachefile.exists());
+ cachefile.delete();
+
+ }
+
+
+ /**
+ * In earlier implementations there were problems with the <i>order</i>
+ * of the <param>s. The scenario was <pre>
+ * <custom class="ModifiedSelector">
+ * <param name="cache.cachefile" value="mycache.properties" />
+ * <param name="cache" value="propertyfiles" />
+ * </custom>
+ * </pre> It was important first to set the cache and then to set
+ * the cache's configuration parameters. That results in the reorganized
+ * configure() method of ModifiedSelector. This testcase tests that.
+ */
+ @Test
+ public void testCreatePropertiesCacheViaCustomSelector() {
+ File cachefile = FILE_UTILS.createTempFile("tmp-cache-", ".properties", null, false, false);
+
+ // Configure the selector
+
+ ExtendSelector s = new ExtendSelector();
+ s.setClassname("org.apache.tools.ant.types.selectors.modifiedselector.ModifiedSelector");
+ s.addParam(createParam("update", "true"));
+ s.addParam(createParam("cache.cachefile", cachefile.getAbsolutePath()));
+ s.addParam(createParam("cache", "propertyfile"));
+
+ selectorRule.selectionString(s);
+
+ // evaluate correctness
+ assertTrue("Cache file is not created.", cachefile.exists());
+ cachefile.delete();
+
+ }
+
+
+ @Test
+ @Ignore("same logic as on algorithm, no testcases created")
+ public void testCustomCache() {
+ // same logic as on algorithm, no testcases created
+ }
+
+
+ /**
+ * Test the interface semantic of Caches.
+ * This method does some common test for cache implementations.
+ * A cache must return a stored value and a valid iterator.
+ * After calling the delete() the cache must be empty.
+ *
+ * @param cache configured test object
+ */
+ protected void doTest(Cache cache) {
+ assertTrue("Cache not proper configured.", cache.isValid());
+
+ String key1 = "key1";
+ String value1 = "value1";
+ String key2 = "key2";
+ String value2 = "value2";
+
+ // given cache must be empty
+ Iterator it1 = cache.iterator();
+ assertFalse("Cache is not empty", it1.hasNext());
+
+ // cache must return a stored value
+ cache.put(key1, value1);
+ cache.put(key2, value2);
+ assertEquals("cache returned wrong value", value1, cache.get(key1));
+ assertEquals("cache returned wrong value", value2, cache.get(key2));
+
+ // test the iterator
+ Iterator it2 = cache.iterator();
+ Object returned = it2.next();
+ boolean ok = (key1.equals(returned) || key2.equals(returned));
+ String msg = "Iterator returned unexpected value."
+ + " key1.equals(returned)="+key1.equals(returned)
+ + " key2.equals(returned)="+key2.equals(returned)
+ + " returned="+returned
+ + " ok="+ok;
+ assertTrue(msg, ok);
+
+ // clear the cache
+ cache.delete();
+ Iterator it3 = cache.iterator();
+ assertFalse("Cache is not empty", it3.hasNext());
+ }
+
+
+ // ============== testcases for the algorithm implementations ==============
+
+
+ @Test
+ public void testHashvalueAlgorithm() {
+ HashvalueAlgorithm algo = new HashvalueAlgorithm();
+ doTest(algo);
+ }
+
+
+ @Test
+ public void testDigestAlgorithmMD5() {
+ DigestAlgorithm algo = new DigestAlgorithm();
+ algo.setAlgorithm("MD5");
+ doTest(algo);
+ }
+
+
+ @Test
+ public void testDigestAlgorithmSHA() {
+ DigestAlgorithm algo = new DigestAlgorithm();
+ algo.setAlgorithm("SHA");
+ doTest(algo);
+ }
+
+
+ @Test
+ public void testChecksumAlgorithm() {
+ ChecksumAlgorithm algo = new ChecksumAlgorithm();
+ doTest(algo);
+ }
+
+
+ @Test
+ public void testChecksumAlgorithmCRC() {
+ ChecksumAlgorithm algo = new ChecksumAlgorithm();
+ algo.setAlgorithm("CRC");
+ doTest(algo);
+ }
+
+
+ @Test
+ public void testChecksumAlgorithmAdler() {
+ ChecksumAlgorithm algo = new ChecksumAlgorithm();
+ algo.setAlgorithm("Adler");
+ doTest(algo);
+ }
+
+
+ /**
+ * Test the interface semantic of Algorithms.
+ * This method does some common test for algorithm implementations.
+ * An algorithm must return always the same value for the same file and
+ * it must not return <i>null</i>.
+ *
+ * @param algo configured test object
+ */
+ protected void doTest(Algorithm algo) {
+ assertTrue("Algorithm not proper configured.", algo.isValid());
+ for (int i=0; i<selectorRule.getFiles().length; i++) {
+ File file = selectorRule.getFiles()[i]; // must not be a directory
+ if (file.isFile()) {
+ // get the Hashvalues
+ String hash1 = algo.getValue(file);
+ String hash2 = algo.getValue(file);
+ String hash3 = algo.getValue(file);
+ String hash4 = algo.getValue(file);
+ String hash5 = algo.getValue(new File(file.getAbsolutePath()));
+
+ // Assert !=null and equality
+ assertNotNull("Hashvalue was null for "+file.getAbsolutePath(), hash1);
+ assertNotNull("Hashvalue was null for "+file.getAbsolutePath(), hash2);
+ assertNotNull("Hashvalue was null for "+file.getAbsolutePath(), hash3);
+ assertNotNull("Hashvalue was null for "+file.getAbsolutePath(), hash4);
+ assertNotNull("Hashvalue was null for "+file.getAbsolutePath(), hash5);
+ assertEquals("getHashvalue() returned different value for "+file.getAbsolutePath(), hash1, hash2);
+ assertEquals("getHashvalue() returned different value for "+file.getAbsolutePath(), hash1, hash3);
+ assertEquals("getHashvalue() returned different value for "+file.getAbsolutePath(), hash1, hash4);
+ assertEquals("getHashvalue() returned different value for "+file.getAbsolutePath(), hash1, hash5);
+ }//if-isFile
+ }//for
+
+ }
+
+
+
+ // ============== testcases for the comparator implementations ==============
+
+
+ @Test
+ public void testEqualComparator() {
+ EqualComparator comp = new EqualComparator();
+ doTest(comp);
+ }
+
+
+ @Test
+ public void testRuleComparator() {
+ RuleBasedCollator comp = (RuleBasedCollator)RuleBasedCollator.getInstance();
+ doTest(comp);
+ }
+
+
+ @Test
+ public void testEqualComparatorViaSelector() {
+ ModifiedSelector s = new ModifiedSelector();
+ ModifiedSelector.ComparatorName compName = new ModifiedSelector.ComparatorName();
+ compName.setValue("equal");
+ s.setComparator(compName);
+ try {
+ performTests(s, "TTTTTTTTTTTT");
+ } finally {
+ s.getCache().delete();
+ }
+ }
+
+
+ @Test
+ @Ignore("not yet supported see note in selector")
+ public void testRuleComparatorViaSelector() {
+ ModifiedSelector s = new ModifiedSelector();
+ ModifiedSelector.ComparatorName compName = new ModifiedSelector.ComparatorName();
+ compName.setValue("rule");
+ s.setComparator(compName);
+ try {
+ performTests(s, "TTTTTTTTTTTT");
+ } finally {
+ s.getCache().delete();
+ }
+ }
+
+
+ @Test
+ @Ignore("same logic as on algorithm, no testcases created")
+ public void testCustomComparator() {
+ // same logic as on algorithm, no testcases created
+ }
+
+
+ @Test
+ public void testResourceSelectorSimple() {
+ BFT bft = new BFT();
+ bft.doTarget("modifiedselectortest-ResourceSimple");
+ bft.deleteCachefile();
+ //new File("src/etc/testcases/types/resources/selectors/cache.properties").delete();
+ }
+
+ @Test
+ public void testResourceSelectorSelresTrue() {
+ BFT bft = new BFT();
+ bft.doTarget("modifiedselectortest-ResourceSelresTrue");
+ AntAssert.assertContains("does not provide an InputStream", bft.getLog());
+ bft.deleteCachefile();
+ }
+
+ @Test
+ public void testResourceSelectorSelresFalse() {
+ BFT bft = new BFT();
+ bft.doTarget("modifiedselectortest-ResourceSelresFalse");
+ bft.deleteCachefile();
+ }
+
+ @Test
+ public void testResourceSelectorScenarioSimple() {
+
+ Assume.assumeNotNull("Ant home not set", selectorRule.getProject().getProperty("ant.home"));
+ BFT bft = new BFT();
+ bft.doTarget("modifiedselectortest-scenario-resourceSimple");
+ bft.doTarget("modifiedselectortest-scenario-clean");
+ bft.deleteCachefile();
+ }
+
+ /**
+ * Test the interface semantic of Comparators.
+ * This method does some common test for comparator implementations.
+ *
+ * @param comp configured test object
+ */
+ protected void doTest(Comparator comp) {
+ Object o1 = new String("string1");
+ Object o2 = new String("string2");
+ Object o3 = new String("string2"); // really "2"
+
+ assertTrue("Comparator gave wrong value.", comp.compare(o1, o2) != 0);
+ assertTrue("Comparator gave wrong value.", comp.compare(o1, o3) != 0);
+ assertTrue("Comparator gave wrong value.", comp.compare(o2, o3) == 0);
+ }
+
+
+ // ===================== scenario tests =====================
+
+
+ /**
+ * Tests whether the seldirs attribute is used.
+ */
+ @Test
+ public void testSeldirs() {
+ ModifiedSelector s = new ModifiedSelector();
+ StringBuffer sbTrue = new StringBuffer();
+ StringBuffer sbFalse = new StringBuffer();
+ for (int i=0; i<selectorRule.getFiles().length; i++) {
+ if (selectorRule.getFiles()[i].isDirectory()) {
+ sbTrue.append("T");
+ sbFalse.append("F");
+ } else {
+ sbTrue.append("T");
+ sbFalse.append("T");
+ }
+ }
+
+ s.setSeldirs(true);
+ performTests(s, sbTrue.toString());
+ s.getCache().delete();
+
+ s.setSeldirs(false);
+ performTests(s, sbFalse.toString());
+ s.getCache().delete();
+
+ s.getCache().delete();
+ }
+
+
+ /**
+ * Complex test scenario using default values (DigestAlgorithm with MD5,
+ * PropertiesfileCache with file=cache.properties, EqualComparator
+ * and update=true). <ol>
+ * <li> try fist time --> should select all </li>
+ * <li> try second time --> should select no files (only directories) </li>
+ * <li> modify timestamp of one file and content of a nother one </li>
+ * <li> try third time --> should select only the file with modified
+ * content </li>
+ */
+ @Test
+ public void testScenario1() {
+ BFT bft = null;
+ ModifiedSelector s = null;
+ try {
+
+ String results;
+
+ // Configure the selector - only defaults are used
+ s = new ModifiedSelector();
+
+ //
+ // ***** First Run *****
+ // the first call should get all files, because nothing is in
+ // the cache
+ //
+ performTests(s, "TTTTTTTTTTTT");
+
+ //
+ // ***** Second Run *****
+ // the second call should get no files, because no content
+ // has changed
+ //
+ performTests(s, "TFFFFFFFFFFT");
+
+ //
+ // ***** make some files dirty *****
+ //
+
+ // these files are made dirty --> 3+4 with different content
+ String f2name = "tar/bz2/asf-logo-huge.tar.bz2";
+ String f3name = "asf-logo.gif.md5";
+ String f4name = "copy.filterset.filtered";
+
+ // AccessObject to the test-Ant-environment
+ bft = new BFT();
+ // give some values (via property file) to that environment
+ bft.writeProperties("f2name="+f2name);
+ bft.writeProperties("f3name="+f3name);
+ bft.writeProperties("f4name="+f4name);
+ // call the target for making the files dirty
+ bft.doTarget("modifiedselectortest-makeDirty");
+
+ //
+ // ***** Third Run *****
+ // third call should get only those files, which CONTENT changed
+ // (no timestamp changes required!)
+ results = selectorRule.selectionString(s);
+
+ //
+ // ***** Check the result *****
+ //
+
+ // Mark all files which should be selected as (T)rue and all others
+ // as (F)alse. Directories are always selected so they always are
+ // (T)rue.
+ StringBuffer expected = new StringBuffer();
+ for (int i=0; i<selectorRule.getFiles().length; i++) {
+ String ch = "F";
+ if (selectorRule.getFiles()[i].isDirectory()) ch = "T";
+ // f2name shouldn't be selected: only timestamp has changed!
+ if (selectorRule.getFilenames()[i].equalsIgnoreCase(f3name)) ch = "T";
+ if (selectorRule.getFilenames()[i].equalsIgnoreCase(f4name)) ch = "T";
+ expected.append(ch);
+ }
+
+ assertEquals(
+ "Wrong files selected. Differing files: " // info text
+ + resolve(diff(expected.toString(), results)), // list of files
+ expected.toString(), // expected result
+ results // result
+ );
+
+ } finally {
+ // cleanup the environment
+ if (s!=null) s.getCache().delete();
+ if (bft!=null) bft.deletePropertiesfile();
+ }
+ }
+
+
+ /**
+ * This scenario is based on scenario 1, but does not use any
+ * default value and its based on <custom> selector. Used values are:<ul>
+ * <li><b>Cache: </b> Propertyfile,
+ * cachefile={java.io.tmpdir}/mycache.txt </li>
+ * <li><b>Algorithm: </b> Digest
+ * algorithm=SHA, Provider=null </li>
+ * <li><b>Comparator: </b> java.text.RuleBasedCollator
+ * <li><b>Update: </b> true </li>
+ */
+ @Test
+ @Ignore("RuleBasedCollator not yet supported - see Selector:375 note")
+ public void testScenario2() {
+ ExtendSelector s = new ExtendSelector();
+ BFT bft = new BFT();
+ String cachefile = System.getProperty("java.io.tmpdir")+"/mycache.txt";
+ try {
+
+ s.setClassname("org.apache.tools.ant.types.selectors.modifiedselector.ModifiedSelector");
+
+ s.addParam(createParam("cache.cachefile", cachefile));
+ //s.addParam(createParam("algorithm.provider","---")); // i don't know any valid
+ s.addParam(createParam("cache","propertyfile"));
+ s.addParam(createParam("update","true"));
+ s.addParam(createParam("comparator","rule"));
+ s.addParam(createParam("algorithm.name","sha"));
+ s.addParam(createParam("algorithm","digest"));
+
+ // first and second run
+ performTests(s, "TTTTTTTTTTTT");
+ performTests(s, "TFFFFFFFFFFT");
+ // make dirty
+ String f2name = "tar/bz2/asf-logo-huge.tar.bz2";
+ String f3name = "asf-logo.gif.md5";
+ String f4name = "copy.filterset.filtered";
+ bft.writeProperties("f2name="+f2name);
+ bft.writeProperties("f3name="+f3name);
+ bft.writeProperties("f4name="+f4name);
+ bft.doTarget("modifiedselectortest-makeDirty");
+ // third run
+ String results = selectorRule.selectionString(s);
+ StringBuffer expected = new StringBuffer();
+ for (int i=0; i<selectorRule.getFilenames().length; i++) {
+ String ch = "F";
+ if (selectorRule.getFiles()[i].isDirectory()) ch = "T";
+ if (selectorRule.getFilenames()[i].equalsIgnoreCase(f3name)) ch = "T";
+ if (selectorRule.getFilenames()[i].equalsIgnoreCase(f4name)) ch = "T";
+ expected.append(ch);
+ }
+ assertEquals(
+ "Wrong files selected. Differing files: " // info text
+ + resolve(diff(expected.toString(), results)), // list of files
+ expected.toString(), // expected result
+ results // result
+ );
+ } finally {
+ // cleanup the environment
+ (new java.io.File(cachefile)).delete();
+ bft.deletePropertiesfile();
+ }
+ }
+
+
+ @Test
+ public void testScenarioCoreSelectorDefaults() {
+ Assume.assumeNotNull("Ant home not set", selectorRule.getProject().getProperty("ant.home") );
+ doScenarioTest("modifiedselectortest-scenario-coreselector-defaults", "cache.properties");
+ }
+
+
+ @Test
+ public void testScenarioCoreSelectorSettings() {
+ Assume.assumeNotNull("Ant home not set", selectorRule.getProject().getProperty("ant.home") );
+ doScenarioTest("modifiedselectortest-scenario-coreselector-settings", "core.cache.properties");
+ }
+
+
+ @Test
+ public void testScenarioCustomSelectorSettings() {
+ Assume.assumeNotNull("Ant home not set", selectorRule.getProject().getProperty("ant.home") );
+ doScenarioTest("modifiedselectortest-scenario-customselector-settings", "core.cache.properties");
+ }
+
+
+ public void doScenarioTest(String target, String cachefilename) {
+ BFT bft = new BFT();
+ bft.setUp();
+ File cachefile = new File(selectorRule.getProject().getBaseDir(), cachefilename);
+ try {
+ // do the actions
+ bft.doTarget("modifiedselectortest-scenario-clean");
+ bft.doTarget(target);
+
+ // the directories to check
+ File to1 = new File(selectorRule.getOutputDir(), "selectortest/to-1");
+ File to2 = new File(selectorRule.getOutputDir(), "selectortest/to-2");
+ File to3 = new File(selectorRule.getOutputDir(), "selectortest/to-3");
+
+ // do the checks
+ assertTrue("Cache file not created.", cachefile.exists());
+ assertTrue("Not enough files copied on first time.", to1.list().length>5);
+ assertTrue("Too much files copied on second time.", to2.list().length==0);
+ assertTrue("Too much files copied on third time.", to3.list().length==2);
+ // don't catch the JUnit exceptions
+ } finally {
+ bft.doTarget("modifiedselectortest-scenario-clean");
+ bft.deletePropertiesfile();
+ bft.tearDown();
+ cachefile.delete();
+ }
+ }
+
+
+ // ===================== helper methods and classes ====================
+
+
+ /**
+ * Creates a configured parameter object.
+ * @param name name of the parameter
+ * @param value value of the parameter
+ * @return the parameter object
+ */
+ private Parameter createParam(String name, String value) {
+ Parameter p = new Parameter();
+ p.setName(name);
+ p.setValue(value);
+ return p;
+ }
+
+
+ /**
+ * The BFT class wrapps the selector test-builfile inside an
+ * ant project. It supports target execution
+ * and property transfer to that project.
+ */
+ private class BFT extends BuildFileRule {
+ String buildfile = "src/etc/testcases/types/selectors.xml";
+
+ String propfile = "ModifiedSelectorTest.properties";
+
+ boolean isConfigured = false;
+
+
+ public void setUp() {
+ super.configureProject(buildfile);
+ isConfigured = true;
+ }
+
+
+ /**
+ * This stub teardown is here because the outer class needs to call the
+ * tearDown method, and in the superclass it is protected.
+ */
+ public void tearDown() {
+ super.after();
+
+ }
+
+ public void doTarget(String target) {
+ if (!isConfigured) setUp();
+ executeTarget(target);
+ }
+
+ public String getProperty(String property) {
+ return super.getProject().getProperty(property);
+ }
+
+ public void writeProperties(String line) {
+ if (!isConfigured) setUp();
+ File dir = getProject().getBaseDir();
+ File file = new File(dir, propfile);
+ try {
+ java.io.FileWriter out =
+ new java.io.FileWriter(file.getAbsolutePath(), true);
+ out.write(line);
+ out.write(System.getProperty("line.separator"));
+ out.flush();
+ out.close();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ public void deletePropertiesfile() {
+ if (!isConfigured) setUp();
+ new File(getProject().getBaseDir(), propfile).delete();
+ }
+
+ public void deleteCachefile() {
+ File basedir = new File(buildfile).getParentFile();
+ File cacheFile = new File(basedir, "cache.properties");
+ cacheFile.delete();
+ }
+
+ }//class-BFT
+
+
+ /**
+ * MockProject wrappes a very small ant project (one target, one task)
+ * but provides public methods to fire the build events.
+ */
+ private class MockProject extends Project {
+ private Task task;
+ private Target target;
+
+ public MockProject() {
+ task = new Task(){
+ public void execute() {
+ }
+ };
+ task.setTaskName("testTask");
+ target = new Target();
+ target.setName("testTarget");
+ target.setProject(this);
+ target.addTask(task);
+ task.setOwningTarget(target);
+ }
+
+ public void fireBuildFinished() {
+ super.fireBuildFinished(null);
+ }
+ public void fireSubBuildFinished() {
+ super.fireSubBuildFinished(null);
+ }
+ public void fireTargetStarted() {
+ super.fireTargetStarted(target);
+ }
+ public void fireTargetFinished() {
+ super.fireTargetFinished(target, null);
+ }
+ public void fireTaskStarted() {
+ super.fireTaskStarted(task);
+ }
+ public void fireTaskFinished() {
+ super.fireTaskFinished(task, null);
+ }
+ }//class-MockProject
+
+
+ /**
+ * Does the selection test for a given selector and prints the
+ * filenames of the differing files (selected but shouldn't,
+ * not selected but should).
+ * @param selector The selector to test
+ * @param expected The expected result
+ */
+ private void performTests(FileSelector selector, String expected) {
+ String result = selectorRule.selectionString(selector);
+ String diff = diff(expected, result);
+ String resolved = resolve(diff);
+ assertEquals("Differing files: " + resolved, result, expected);
+ }
+ /**
+ * Checks which files are selected and shouldn't be or which
+ * are not selected but should.
+ * @param expected String containing 'F's and 'T's
+ * @param result String containing 'F's and 'T's
+ * @return Difference as String containing '-' (equal) and
+ * 'X' (difference).
+ */
+ private String diff(String expected, String result) {
+ int length1 = expected.length();
+ int length2 = result.length();
+ int min = (length1 > length2) ? length2 : length1;
+ StringBuffer sb = new StringBuffer();
+ for (int i=0; i<min; i++) {
+ sb.append(
+ (expected.charAt(i) == result.charAt(i))
+ ? "-"
+ : "X"
+ );
+ }
+ return sb.toString();
+ }
+
+ /**
+ * Resolves a diff-String (@see diff()) against the (inherited) filenames-
+ * and files arrays.
+ * @param filelist Diff-String
+ * @return String containing the filenames for all differing files,
+ * separated with semicolons ';'
+ */
+ private String resolve(String filelist) {
+ StringBuffer sb = new StringBuffer();
+ int min = (selectorRule.getFilenames().length > filelist.length())
+ ? filelist.length()
+ : selectorRule.getFilenames().length;
+ for (int i=0; i<min; i++) {
+ if ('X'==filelist.charAt(i)) {
+ sb.append(selectorRule.getFilenames()[i]);
+ sb.append(";");
+ }
+ }
+ return sb.toString();
+ }
+
+
+}//class-ModifiedSelectorTest
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/selectors/PresentSelectorTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/selectors/PresentSelectorTest.java
new file mode 100644
index 00000000..e96a6758
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/selectors/PresentSelectorTest.java
@@ -0,0 +1,137 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types.selectors;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.types.Mapper;
+import org.junit.Rule;
+import org.junit.Test;
+
+import java.io.File;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+
+/**
+ * Tests Present Selectors
+ *
+ */
+public class PresentSelectorTest {
+
+
+ @Rule
+ public final BaseSelectorRule selectorRule = new BaseSelectorRule();
+
+ /**
+ * Test the code that validates the selector.
+ */
+ @Test
+ public void testValidate() {
+ PresentSelector s = new PresentSelector();
+ try {
+ s.createMapper();
+ s.createMapper();
+ fail("PresentSelector allowed more than one nested mapper.");
+ } catch (BuildException be1) {
+ assertEquals("Cannot define more than one mapper",
+ be1.getMessage());
+ }
+
+ s = new PresentSelector();
+ try {
+ s.isSelected(selectorRule.getProject().getBaseDir(),selectorRule.getFilenames()[0],selectorRule.getFiles()[0]);
+ fail("PresentSelector did not check for required fields");
+ } catch (BuildException be2) {
+ assertEquals("The targetdir attribute is required.",
+ be2.getMessage());
+ }
+
+ }
+
+ /**
+ * Tests to make sure that the selector is selecting files correctly.
+ */
+ @Test
+ public void testSelectionBehaviour() {
+ PresentSelector s;
+ String results;
+ Mapper m;
+ Mapper.MapperType identity = new Mapper.MapperType();
+ identity.setValue("identity");
+ Mapper.MapperType glob = new Mapper.MapperType();
+ glob.setValue("glob");
+ Mapper.MapperType merge = new Mapper.MapperType();
+ merge.setValue("merge");
+ Mapper.MapperType flatten = new Mapper.MapperType();
+ flatten.setValue("flatten");
+
+ File beddir = selectorRule.getBeddir();
+
+ s = new PresentSelector();
+ s.setTargetdir(beddir);
+ results = selectorRule.selectionString(s);
+ assertEquals("TTTTTTTTTTTT", results);
+
+ s = new PresentSelector();
+ s.setTargetdir(beddir);
+ m = s.createMapper();
+ m.setType(identity);
+ results = selectorRule.selectionString(s);
+ assertEquals("TTTTTTTTTTTT", results);
+
+ s = new PresentSelector();
+ File subdir = new File(System.getProperty("root"), "src/etc/testcases/taskdefs/expected");
+ s.setTargetdir(subdir);
+ m = s.createMapper();
+ m.setType(flatten);
+ results = selectorRule.selectionString(s);
+ assertEquals("TTTTTTTTTTTF", results);
+
+ s = new PresentSelector();
+ s.setTargetdir(beddir);
+ m = s.createMapper();
+ m.setType(merge);
+ m.setTo("asf-logo.gif.gz");
+ results = selectorRule.selectionString(s);
+ assertEquals("TTTTTTTTTTTT", results);
+
+ s = new PresentSelector();
+ subdir = new File(beddir, "tar/bz2");
+ s.setTargetdir(subdir);
+ m = s.createMapper();
+ m.setType(glob);
+ m.setFrom("*.bz2");
+ m.setTo("*.tar.bz2");
+ results = selectorRule.selectionString(s);
+ assertEquals("FFTFFFFFFFFF", results);
+
+
+ s = new PresentSelector();
+ subdir = new File(selectorRule.getOutputDir(), "selectortest2");
+ s.setTargetdir(subdir);
+ results = selectorRule.selectionString(s);
+ assertEquals("TTTFFTTTTTTT", results);
+ results = selectorRule.selectionString(s);
+ assertEquals("TTTFFTTTTTTT", results);
+
+
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/selectors/README b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/selectors/README
new file mode 100644
index 00000000..eb48f6bb
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/selectors/README
@@ -0,0 +1,96 @@
+A DESCRIPTION OF THE SELECTOR TEST FRAMEWORK
+
+When writing tests for selectors, I found that I wanted to have some
+standard way of working with a set of files and testing whether one or
+another of them was selected. To that end, I created a base class called
+BaseSelectorTest that does most of the heavy lifting. Of course, you can
+test your selectors any way you want, but if you want to reuse this code,
+read on.
+
+What BaseSelectorTest does is use an ant build file
+"src/etc/testcases/types/selector.xml" to copy a tree of files out of
+"src/etc/testcases/taskdefs/expected" into a "selectortest" directories.
+Then it takes a list of 12 of the files and directories in this tree, and
+applies whatever selector you pass in to each one. It passes back to your
+test a 12 character long string indicating which of the 12 files and
+directories was selected, using 'T' for selected and 'F' for not selected.
+In the Test class for your selector, you override the getInstance() method
+to create your own type of selector, and set the elements of your selector
+a variety of ways to ensure that the string of T's and F's returned when
+the selector is applied to those 12 files is correct.
+
+So, for example, DepthSelectorTest.java extends BaseSelectorTest and has
+the following code:
+
+
+ public BaseSelector getInstance() {
+ return new DepthSelector();
+ }
+
+
+ public void testSelectionBehaviour() {
+ DepthSelector s;
+ String results;
+
+
+ try {
+ makeBed();
+
+
+ s = (DepthSelector)getInstance();
+ s.setMin(20);
+ s.setMax(25);
+ results = selectionString(s);
+ assertEquals("FFFFFFFFFFFF", results);
+
+
+ s = (DepthSelector)getInstance();
+ s.setMin(0);
+ results = selectionString(s);
+ assertEquals("TTTTTTTTTTTT", results);
+
+
+ s = (DepthSelector)getInstance();
+ s.setMin(1);
+ results = selectionString(s);
+ assertEquals("FFFFFTTTTTTT", results);
+
+
+The first test says that none of the 12 files or directories will match if
+the depth range for the selector is between 20 and 25 (that would be one
+deep directory tree!). The second says that all files and directories
+match if the minimum depth is set to 0 and the maximum isn't specified. The
+third test says that if the minumum depth is 1, the first 5 entries in the
+list of 12 will not be selected and the rest will.
+
+
+You can find the 12 files and directories that are tested for selection in
+the BaseSelectorTest class. I used a fixed list so that if someone added
+new files to the src/etc/testcases/types directory it wouldn't break my
+tests:
+
+
+ protected String[] filenames = {".","asf-logo.gif.md5","asf-
+ logo.gif.bz2",
+ "asf-logo.gif.gz","copy.filterset.filtered","zip/asf-
+ logo.gif.zip",
+ "tar/asf-logo.gif.tar","tar/asf-logo-huge.tar.gz",
+ "tar/gz/asf-logo.gif.tar.gz","tar/bz2/asf-logo.gif.tar.bz2",
+ "tar/bz2/asf-logo-huge.tar.bz2","tar/bz2"};
+
+
+If you wish to use this set of files and directories to test your selector,
+you can reuse the BaseSelectorTest with no change to it.
+
+You may find you need to alter the build file so that you get some
+variation in the files that your selector can work with. Most of the core
+selectors have required that kind of modification. If you do that, make
+sure that it doesn't alter the output strings on the other selector test,
+or if it does that you update their expected return results.
+
+You may also want to alter the set of files you look at in a particular
+selector test. Since the filelist in BaseSelectorTest is protected, you
+should be able to override it as you need to. Or you can alter the fileset
+in BaseSelectorTest itself, provided you update the test strings in all the
+other unit tests.
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/selectors/SignedSelectorTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/selectors/SignedSelectorTest.java
new file mode 100644
index 00000000..1eb40dc4
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/selectors/SignedSelectorTest.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types.selectors;
+
+import org.apache.tools.ant.BuildFileRule;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+/**
+ * Testcase for the &lt;signedselector&gt; selector.
+ *
+ */
+public class SignedSelectorTest {
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/types/selectors/signedselector.xml");
+ }
+
+ @Test
+ public void testSelectSigned() {
+ buildRule.executeTarget("selectsigned");
+ }
+
+ @Test
+ public void testNotSelected() {
+ buildRule.executeTarget("notselected");
+ }
+
+ @Test
+ public void testName() {
+ buildRule.executeTarget("name");
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/selectors/SizeSelectorTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/selectors/SizeSelectorTest.java
new file mode 100644
index 00000000..0e543f1c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/selectors/SizeSelectorTest.java
@@ -0,0 +1,237 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types.selectors;
+
+import java.util.Locale;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.types.Parameter;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+/**
+ * Tests Size Selectors
+ *
+ */
+public class SizeSelectorTest {
+
+ @Rule
+ public final BaseSelectorRule selectorRule = new BaseSelectorRule();
+
+ /**
+ * Test the code that validates the selector.
+ */
+ @Test
+ public void testValidate() {
+ SizeSelector s = new SizeSelector();
+ try {
+ s.isSelected(selectorRule.getProject().getBaseDir(), selectorRule.getFilenames()[0],selectorRule.getFiles()[0]);
+ fail("SizeSelector did not check for required fields");
+ } catch (BuildException be1) {
+ assertEquals("The value attribute is required, and must "
+ + "be positive", be1.getMessage());
+ }
+
+ s = new SizeSelector();
+ s.setValue(-10);
+ try {
+ s.isSelected(selectorRule.getProject().getBaseDir(), selectorRule.getFilenames()[0],selectorRule.getFiles()[0]);
+ fail("SizeSelector did not check for value being in the "
+ + "allowable range");
+ } catch (BuildException be2) {
+ assertEquals("The value attribute is required, and must "
+ + "be positive", be2.getMessage());
+ }
+
+ s = new SizeSelector();
+ Parameter param = new Parameter();
+ param.setName("garbage in");
+ param.setValue("garbage out");
+ Parameter[] params = {param};
+ s.setParameters(params);
+ try {
+ s.isSelected(selectorRule.getProject().getBaseDir(), selectorRule.getFilenames()[0],selectorRule.getFiles()[0]);
+ fail("SizeSelector did not check for valid parameter element");
+ } catch (BuildException be3) {
+ assertEquals("Invalid parameter garbage in", be3.getMessage());
+ }
+
+ s = new SizeSelector();
+ param = new Parameter();
+ param.setName("value");
+ param.setValue("garbage out");
+ params[0] = param;
+ s.setParameters(params);
+ try {
+ s.isSelected(selectorRule.getProject().getBaseDir(), selectorRule.getFilenames()[0],selectorRule.getFiles()[0]);
+ fail("SizeSelector accepted bad value as parameter");
+ } catch (BuildException be4) {
+ assertEquals("Invalid size setting garbage out",
+ be4.getMessage());
+ }
+
+ s = new SizeSelector();
+ Parameter param1 = new Parameter();
+ Parameter param2 = new Parameter();
+ param1.setName("value");
+ param1.setValue("5");
+ param2.setName("units");
+ param2.setValue("garbage out");
+ params = new Parameter[2];
+ params[0] = param1;
+ params[1] = param2;
+ try {
+ s.setParameters(params);
+ s.isSelected(selectorRule.getProject().getBaseDir(), selectorRule.getFilenames()[0],selectorRule.getFiles()[0]);
+ fail("SizeSelector accepted bad units as parameter");
+ } catch (BuildException be5) {
+ assertEquals("garbage out is not a legal value for this attribute",
+ be5.getMessage());
+ }
+
+ }
+
+ /**
+ * Tests to make sure that the selector is selecting files correctly.
+ */
+ @Test
+ public void testSelectionBehaviour() {
+ SizeSelector s;
+ String results;
+
+ SizeSelector.ByteUnits kilo = new SizeSelector.ByteUnits();
+ kilo.setValue("K");
+ SizeSelector.ByteUnits kibi = new SizeSelector.ByteUnits();
+ kibi.setValue("Ki");
+ SizeSelector.ByteUnits tibi = new SizeSelector.ByteUnits();
+ tibi.setValue("Ti");
+ SizeSelector.SizeComparisons less = new SizeSelector.SizeComparisons();
+ less.setValue("less");
+ SizeSelector.SizeComparisons equal = new SizeSelector.SizeComparisons();
+ equal.setValue("equal");
+ SizeSelector.SizeComparisons more = new SizeSelector.SizeComparisons();
+ more.setValue("more");
+
+
+
+ s = new SizeSelector();
+ s.setValue(10);
+ s.setWhen(less);
+ results = selectorRule.selectionString(s);
+ assertEquals("TFFFFFFFFFFT", results);
+
+ s = new SizeSelector();
+ s.setValue(10);
+ s.setWhen(more);
+ results = selectorRule.selectionString(s);
+ assertEquals("TTTTTTTTTTTT", results);
+
+ s = new SizeSelector();
+ s.setValue(32);
+ s.setWhen(equal);
+ results = selectorRule.selectionString(s);
+ assertEquals("TFFFTFFFFFFT", results);
+
+ s = new SizeSelector();
+ s.setValue(7);
+ s.setWhen(more);
+ s.setUnits(kilo);
+ results = selectorRule.selectionString(s);
+ assertEquals("TFTFFTTTTTTT", results);
+
+ s = new SizeSelector();
+ s.setValue(7);
+ s.setWhen(more);
+ s.setUnits(kibi);
+ results = selectorRule.selectionString(s);
+ assertEquals("TFTFFFTTFTTT", results);
+
+ s = new SizeSelector();
+ s.setValue(99999);
+ s.setWhen(more);
+ s.setUnits(tibi);
+ results = selectorRule.selectionString(s);
+ assertEquals("TFFFFFFFFFFT", results);
+
+ s = new SizeSelector();
+ Parameter param1 = new Parameter();
+ Parameter param2 = new Parameter();
+ Parameter param3 = new Parameter();
+ param1.setName("value");
+ param1.setValue("20");
+ param2.setName("units");
+ param2.setValue("Ki");
+ param3.setName("when");
+ param3.setValue("more");
+ Parameter[] params = {param1,param2,param3};
+ s.setParameters(params);
+ results = selectorRule.selectionString(s);
+ assertEquals("TFFFFFFTFFTT", results);
+
+
+ }
+
+ @Test
+ public void testParameterParsingLowerCase() {
+ testCaseInsensitiveParameterParsing("units");
+ }
+
+ @Test
+ public void testParameterParsingUpperCase() {
+ testCaseInsensitiveParameterParsing("UNITS");
+ }
+
+ @Test
+ public void testParameterParsingLowerCaseTurkish() {
+ Locale l = Locale.getDefault();
+ try {
+ Locale.setDefault(new Locale("tr"));
+ testCaseInsensitiveParameterParsing("units");
+ } finally {
+ Locale.setDefault(l);
+ }
+ }
+
+ @Test
+ public void testParameterParsingUpperCaseTurkish() {
+ Locale l = Locale.getDefault();
+ try {
+ Locale.setDefault(new Locale("tr"));
+ testCaseInsensitiveParameterParsing("UNITS");
+ } finally {
+ Locale.setDefault(l);
+ }
+ }
+
+ private void testCaseInsensitiveParameterParsing(String name) {
+ SizeSelector s = new SizeSelector();
+ Parameter p = new Parameter();
+ p.setName(name);
+ p.setValue("foo");
+ try {
+ s.setParameters(new Parameter[] {p});
+ fail("should have caused an exception");
+ } catch (BuildException be) {
+ assertEquals("foo is not a legal value for this attribute",
+ be.getMessage());
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/selectors/TokenizedPatternTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/selectors/TokenizedPatternTest.java
new file mode 100644
index 00000000..06e86bd9
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/selectors/TokenizedPatternTest.java
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types.selectors;
+
+import java.io.File;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class TokenizedPatternTest {
+ private static final String DOT_SVN_PATTERN =
+ SelectorUtils.DEEP_TREE_MATCH + File.separator + ".svn"
+ + File.separator + SelectorUtils.DEEP_TREE_MATCH;
+
+ @Test
+ public void testTokenization() {
+ TokenizedPattern pat = new TokenizedPattern(DOT_SVN_PATTERN);
+ assertEquals(3, pat.depth());
+ assertEquals(DOT_SVN_PATTERN, pat.getPattern());
+ assertTrue(pat.containsPattern(SelectorUtils.DEEP_TREE_MATCH));
+ assertTrue(pat.containsPattern(".svn"));
+ }
+
+ @Test
+ public void testEndsWith() {
+ assertTrue(new TokenizedPattern(DOT_SVN_PATTERN)
+ .endsWith(SelectorUtils.DEEP_TREE_MATCH));
+ }
+
+ @Test
+ public void testWithoutLastToken() {
+ assertEquals(SelectorUtils.DEEP_TREE_MATCH + File.separatorChar
+ + ".svn" + File.separator,
+ new TokenizedPattern(DOT_SVN_PATTERN)
+ .withoutLastToken().getPattern());
+ }
+
+ @Test
+ public void testMatchPath() {
+ File f = new File(".svn");
+ TokenizedPath p = new TokenizedPath(f.getAbsolutePath());
+ assertTrue(new TokenizedPattern(DOT_SVN_PATTERN).matchPath(p, true));
+ assertTrue(new TokenizedPattern(DOT_SVN_PATTERN)
+ .withoutLastToken().matchPath(p, true));
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/selectors/TypeSelectorTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/selectors/TypeSelectorTest.java
new file mode 100644
index 00000000..2973d2b4
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/types/selectors/TypeSelectorTest.java
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.types.selectors;
+
+import org.apache.tools.ant.BuildException;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+/**
+ * Tests Type Selectors.
+ *
+ */
+public class TypeSelectorTest {
+
+ @Rule
+ public BaseSelectorRule selectorRule = new BaseSelectorRule();
+
+
+ /**
+ * Test the code that validates the selector.
+ */
+ @Test
+ public void testValidate() {
+ TypeSelector s = new TypeSelector();
+ try {
+ s.isSelected(selectorRule.getProject().getBaseDir(), selectorRule.getFilenames()[0] ,selectorRule.getFiles()[0]);
+ fail("TypeSelector did not check for required fields");
+ } catch (BuildException be1) {
+ assertEquals("The type attribute is required"
+ , be1.getMessage());
+ }
+ }
+
+ /**
+ * Tests to make sure that the selector is selecting files correctly.
+ */
+ @Test
+ public void testSelectionBehaviour() {
+ TypeSelector s;
+ String results;
+
+ TypeSelector.FileType directory = new TypeSelector.FileType();
+ directory.setValue("dir");
+ TypeSelector.FileType file = new TypeSelector.FileType();
+ file.setValue("file");
+
+
+
+ s = new TypeSelector();
+ s.setType(directory);
+ results = selectorRule.selectionString(s);
+ assertEquals("TFFFFFFFFFFT", results);
+
+ s = new TypeSelector();
+ s.setType(file);
+ results = selectorRule.selectionString(s);
+ assertEquals("FTTTTTTTTTTF", results);
+
+
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/Base64ConverterTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/Base64ConverterTest.java
new file mode 100644
index 00000000..48a4cbd7
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/Base64ConverterTest.java
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.util;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * TestCase for Base64Converter.
+ *
+ */
+public class Base64ConverterTest {
+
+ @Test
+ public void testOneValue() {
+ byte[] mybytes = {0, 0, (byte)0xFF};
+ Base64Converter base64Converter = new Base64Converter();
+ assertEquals("AAD/",base64Converter.encode(mybytes));
+ }
+
+ @Test
+ public void testHelloWorld() {
+ byte[] mybytes = "Hello World".getBytes();
+ Base64Converter base64Converter = new Base64Converter();
+ assertEquals("SGVsbG8gV29ybGQ=", base64Converter.encode(mybytes));
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/ClasspathUtilsTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/ClasspathUtilsTest.java
new file mode 100644
index 00000000..3cffa100
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/ClasspathUtilsTest.java
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.util;
+
+import java.io.IOException;
+import java.util.Enumeration;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.Path;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertTrue;
+
+
+/**
+ * Test case for ClasspathUtils
+ *
+ */
+public class ClasspathUtilsTest {
+
+ private Project p;
+
+ @Before
+ public void setUp() {
+ p = new Project();
+ p.init();
+ }
+
+
+ @Test
+ public void testOnlyOneInstance() {
+ Enumeration enumeration;
+ String list = "";
+ ClassLoader c = ClasspathUtils.getUniqueClassLoaderForPath(p, (Path) null, false);
+ try {
+ enumeration = c.getResources(
+ "org/apache/tools/ant/taskdefs/defaults.properties");
+ } catch (IOException e) {
+ throw new BuildException(
+ "Could not get the defaults.properties resource", e);
+ }
+ int count = 0;
+ while (enumeration.hasMoreElements()) {
+ list = list + " " + enumeration.nextElement();
+ count++;
+ }
+ assertTrue("Should be only one and not " + count + " " + list, count == 1);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/CollectionUtilsTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/CollectionUtilsTest.java
new file mode 100644
index 00000000..425dc471
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/CollectionUtilsTest.java
@@ -0,0 +1,102 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.util;
+
+import java.util.Hashtable;
+import java.util.Properties;
+import java.util.Stack;
+import java.util.Vector;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Tests for org.apache.tools.ant.util.CollectionUtils.
+ *
+ */
+public class CollectionUtilsTest {
+
+
+ @Test
+ public void testVectorEquals() {
+ assertTrue(!CollectionUtils.equals(null, new Vector()));
+ assertTrue(!CollectionUtils.equals(new Vector(), null));
+ assertTrue(CollectionUtils.equals(new Vector(), new Vector()));
+ Vector v1 = new Vector();
+ Stack s2 = new Stack();
+ v1.addElement("foo");
+ s2.push("foo");
+ assertTrue(CollectionUtils.equals(v1, s2));
+ assertTrue(CollectionUtils.equals(s2, v1));
+ v1.addElement("bar");
+ assertTrue(!CollectionUtils.equals(v1, s2));
+ assertTrue(!CollectionUtils.equals(s2, v1));
+ s2.push("bar");
+ assertTrue(CollectionUtils.equals(v1, s2));
+ assertTrue(CollectionUtils.equals(s2, v1));
+ s2.push("baz");
+ assertTrue(!CollectionUtils.equals(v1, s2));
+ assertTrue(!CollectionUtils.equals(s2, v1));
+ v1.addElement("baz");
+ assertTrue(CollectionUtils.equals(v1, s2));
+ assertTrue(CollectionUtils.equals(s2, v1));
+ v1.addElement("zyzzy");
+ s2.push("zyzzy2");
+ assertTrue(!CollectionUtils.equals(v1, s2));
+ assertTrue(!CollectionUtils.equals(s2, v1));
+ }
+
+ @Test
+ public void testDictionaryEquals() {
+ assertTrue(!CollectionUtils.equals(null, new Hashtable()));
+ assertTrue(!CollectionUtils.equals(new Hashtable(), null));
+ assertTrue(CollectionUtils.equals(new Hashtable(), new Properties()));
+ Hashtable h1 = new Hashtable();
+ Properties p2 = new Properties();
+ h1.put("foo", "");
+ p2.put("foo", "");
+ assertTrue(CollectionUtils.equals(h1, p2));
+ assertTrue(CollectionUtils.equals(p2, h1));
+ h1.put("bar", "");
+ assertTrue(!CollectionUtils.equals(h1, p2));
+ assertTrue(!CollectionUtils.equals(p2, h1));
+ p2.put("bar", "");
+ assertTrue(CollectionUtils.equals(h1, p2));
+ assertTrue(CollectionUtils.equals(p2, h1));
+ p2.put("baz", "");
+ assertTrue(!CollectionUtils.equals(h1, p2));
+ assertTrue(!CollectionUtils.equals(p2, h1));
+ h1.put("baz", "");
+ assertTrue(CollectionUtils.equals(h1, p2));
+ assertTrue(CollectionUtils.equals(p2, h1));
+ h1.put("zyzzy", "");
+ p2.put("zyzzy2", "");
+ assertTrue(!CollectionUtils.equals(h1, p2));
+ assertTrue(!CollectionUtils.equals(p2, h1));
+ p2.put("zyzzy", "");
+ h1.put("zyzzy2", "");
+ assertTrue(CollectionUtils.equals(h1, p2));
+ assertTrue(CollectionUtils.equals(p2, h1));
+ h1.put("dada", "1");
+ p2.put("dada", "2");
+ assertTrue(!CollectionUtils.equals(h1, p2));
+ assertTrue(!CollectionUtils.equals(p2, h1));
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/DOMElementWriterTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/DOMElementWriterTest.java
new file mode 100644
index 00000000..fe09ce93
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/DOMElementWriterTest.java
@@ -0,0 +1,305 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.util;
+
+import org.junit.Test;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import java.io.IOException;
+import java.io.StringWriter;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Tests for org.apache.tools.ant.util.DOMElementWriter.
+ *
+ */
+public class DOMElementWriterTest {
+
+ private DOMElementWriter w = new DOMElementWriter();
+
+ @Test
+ public void testIsReference() {
+ assertTrue("&#20;", w.isReference("&#20;"));
+ assertTrue("&#x20;", w.isReference("&#x20;"));
+ assertTrue("&#xA0;", w.isReference("&#xA0;"));
+ assertTrue("&#A0;", !w.isReference("&#A0;"));
+ assertTrue("20;", !w.isReference("20;"));
+ assertTrue("&#20", !w.isReference("&#20"));
+ assertTrue("&quot;", w.isReference("&quot;"));
+ assertTrue("&apos;", w.isReference("&apos;"));
+ assertTrue("&gt;", w.isReference("&gt;"));
+ assertTrue("&lt;", w.isReference("&lt;"));
+ assertTrue("&amp;", w.isReference("&amp;"));
+ }
+
+ @Test
+ public void testEncode() {
+ assertEquals("&amp;#20;", w.encode("&#20;"));
+ assertEquals("&amp;#x20;", w.encode("&#x20;"));
+ assertEquals("&amp;#xA0;", w.encode("&#xA0;"));
+ assertEquals("&amp;#A0;", w.encode("&#A0;"));
+ assertEquals("20;", w.encode("20;"));
+ assertEquals("&amp;#20", w.encode("&#20"));
+ assertEquals("&amp;quot;", w.encode("&quot;"));
+ assertEquals("&amp;apos;", w.encode("&apos;"));
+ assertEquals("&amp;gt;", w.encode("&gt;"));
+ assertEquals("&amp;lt;", w.encode("&lt;"));
+ assertEquals("&amp;amp;", w.encode("&amp;"));
+ assertEquals("&quot;", w.encode("\""));
+ assertEquals("&lt;", w.encode("<"));
+ assertEquals("&amp;", w.encode("&"));
+ assertEquals("", w.encode("\u0017"));
+ assertEquals("\r\n\t", w.encode("\r\n\t"));
+ }
+
+ @Test
+ public void testEncodeAttributeValue() {
+ assertEquals("&amp;#20;", w.encodeAttributeValue("&#20;"));
+ assertEquals("&amp;#x20;", w.encodeAttributeValue("&#x20;"));
+ assertEquals("&amp;#xA0;", w.encodeAttributeValue("&#xA0;"));
+ assertEquals("&amp;#A0;", w.encodeAttributeValue("&#A0;"));
+ assertEquals("20;", w.encodeAttributeValue("20;"));
+ assertEquals("&amp;#20", w.encodeAttributeValue("&#20"));
+ assertEquals("&amp;quot;", w.encodeAttributeValue("&quot;"));
+ assertEquals("&amp;apos;", w.encodeAttributeValue("&apos;"));
+ assertEquals("&amp;gt;", w.encodeAttributeValue("&gt;"));
+ assertEquals("&amp;lt;", w.encodeAttributeValue("&lt;"));
+ assertEquals("&amp;amp;", w.encodeAttributeValue("&amp;"));
+ assertEquals("&quot;", w.encodeAttributeValue("\""));
+ assertEquals("&lt;", w.encodeAttributeValue("<"));
+ assertEquals("&amp;", w.encodeAttributeValue("&"));
+ assertEquals("", w.encodeAttributeValue("\u0017"));
+ assertEquals("&#xd;&#xa;&#x9;", w.encodeAttributeValue("\r\n\t"));
+ }
+
+ @Test
+ public void testAttributeWithWhitespace() throws IOException {
+ Document d = DOMUtils.newDocument();
+ Element root = d.createElement("root");
+ root.setAttribute("foo", "bar\nbaz");
+ StringWriter sw = new StringWriter();
+ DOMElementWriter w = new DOMElementWriter();
+ w.write(root, sw, 0, " ");
+ assertEquals("<root foo=\"bar&#xa;baz\" />" + StringUtils.LINE_SEP,
+ sw.toString());
+ }
+
+ @Test
+ public void testEncodeData() {
+ assertEquals("&#20;\"20;&", w.encodedata("&#20;\"20;&"));
+ assertEquals("", w.encodedata("\u0017"));
+ }
+
+ @Test
+ public void testIsLegalCharacter() {
+ assertTrue("0x00", !w.isLegalCharacter('\u0000'));
+ assertTrue("0x09", w.isLegalCharacter('\t'));
+ assertTrue("0x0A", w.isLegalCharacter('\n'));
+ assertTrue("0x0C", w.isLegalCharacter('\r'));
+ assertTrue("0x1F", !w.isLegalCharacter('\u001F'));
+ assertTrue("0x20", w.isLegalCharacter('\u0020'));
+ assertTrue("0xD7FF", w.isLegalCharacter('\uD7FF'));
+ assertTrue("0xD800", !w.isLegalCharacter('\uD800'));
+ assertTrue("0xDFFF", !w.isLegalCharacter('\uDFFF'));
+ assertTrue("0xE000", w.isLegalCharacter('\uE000'));
+ assertTrue("0xFFFD", w.isLegalCharacter('\uFFFD'));
+ assertTrue("0xFFFE", !w.isLegalCharacter('\uFFFE'));
+ }
+
+ @Test
+ public void testCDATAEndEncoding() {
+ assertEquals("]>", w.encodedata("]>"));
+ assertEquals("]]", w.encodedata("]]"));
+ assertEquals("]]]]><![CDATA[>", w.encodedata("]]>"));
+ assertEquals("]]]]><![CDATA[>A", w.encodedata("]]>A"));
+ assertEquals("A]]]]><![CDATA[>", w.encodedata("A]]>"));
+ assertEquals("A]]]]><![CDATA[>A", w.encodedata("A]]>A"));
+ assertEquals("A]]]]><![CDATA[>B]]]]><![CDATA[>C",
+ w.encodedata("A]]>B]]>C"));
+ }
+
+ @Test
+ public void testNoAdditionalWhiteSpaceForText() throws IOException {
+ Document d = DOMUtils.newDocument();
+ Element root = d.createElement("root");
+ DOMUtils.appendTextElement(root, "textElement", "content");
+
+ StringWriter sw = new StringWriter();
+ DOMElementWriter w = new DOMElementWriter();
+ w.write(root, sw, 0, " ");
+ assertEquals("<root>" + StringUtils.LINE_SEP
+ + " <textElement>content</textElement>"
+ + StringUtils.LINE_SEP
+ + "</root>" + StringUtils.LINE_SEP,
+ sw.toString());
+ }
+
+ @Test
+ public void testNoAdditionalWhiteSpaceForCDATA() throws IOException {
+ Document d = DOMUtils.newDocument();
+ Element root = d.createElement("root");
+ DOMUtils.appendCDATAElement(root, "cdataElement", "content");
+
+ StringWriter sw = new StringWriter();
+ DOMElementWriter w = new DOMElementWriter();
+ w.write(root, sw, 0, " ");
+ assertEquals("<root>" + StringUtils.LINE_SEP
+ + " <cdataElement><![CDATA[content]]></cdataElement>"
+ + StringUtils.LINE_SEP
+ + "</root>" + StringUtils.LINE_SEP,
+ sw.toString());
+ }
+
+ @Test
+ public void testNoAdditionalWhiteSpaceForEmptyElement() throws IOException {
+ Document d = DOMUtils.newDocument();
+ Element root = d.createElement("root");
+ DOMUtils.createChildElement(root, "emptyElement");
+
+ StringWriter sw = new StringWriter();
+ DOMElementWriter w = new DOMElementWriter();
+ w.write(root, sw, 0, " ");
+ assertEquals("<root>" + StringUtils.LINE_SEP
+ // + " <emptyElement></emptyElement>"
+ + " <emptyElement />"
+ + StringUtils.LINE_SEP
+ + "</root>" + StringUtils.LINE_SEP,
+ sw.toString());
+ }
+
+ @Test
+ public void testNoNSPrefixByDefault() throws IOException {
+ Document d = DOMUtils.newDocument();
+ Element root = d.createElementNS("urn:foo", "root");
+ root.setAttributeNS("urn:foo2", "bar", "baz");
+
+ StringWriter sw = new StringWriter();
+ DOMElementWriter w = new DOMElementWriter();
+ w.write(root, sw, 0, " ");
+ assertEquals("<root bar=\"baz\" />"
+ + StringUtils.LINE_SEP, sw.toString());
+ }
+
+ @Test
+ public void testNSOnElement() throws IOException {
+ Document d = DOMUtils.newDocument();
+ Element root = d.createElementNS("urn:foo", "root");
+ root.setAttributeNS("urn:foo2", "bar", "baz");
+
+ StringWriter sw = new StringWriter();
+ DOMElementWriter w =
+ new DOMElementWriter(false,
+ DOMElementWriter.XmlNamespacePolicy
+ .ONLY_QUALIFY_ELEMENTS);
+ w.write(root, sw, 0, " ");
+ assertEquals("<root bar=\"baz\" xmlns=\"urn:foo\" />"
+ + StringUtils.LINE_SEP, sw.toString());
+ }
+
+ @Test
+ public void testNSPrefixOnAttribute() throws IOException {
+ Document d = DOMUtils.newDocument();
+ Element root = d.createElementNS("urn:foo", "root");
+ root.setAttributeNS("urn:foo2", "bar", "baz");
+
+ StringWriter sw = new StringWriter();
+ DOMElementWriter w =
+ new DOMElementWriter(false,
+ DOMElementWriter.XmlNamespacePolicy
+ .QUALIFY_ALL);
+ w.write(root, sw, 0, " ");
+ assertEquals("<root ns0:bar=\"baz\" xmlns=\"urn:foo\""
+ + " xmlns:ns0=\"urn:foo2\" />"
+ + StringUtils.LINE_SEP, sw.toString());
+ }
+
+ @Test
+ public void testNSPrefixOnAttributeEvenWithoutElement() throws IOException {
+ Document d = DOMUtils.newDocument();
+ Element root = d.createElementNS("urn:foo", "root");
+ root.setAttributeNS("urn:foo2", "bar", "baz");
+
+ StringWriter sw = new StringWriter();
+ DOMElementWriter w =
+ new DOMElementWriter(false,
+ new DOMElementWriter.XmlNamespacePolicy(false,
+ true)
+ );
+ w.write(root, sw, 0, " ");
+ assertEquals("<root ns0:bar=\"baz\" xmlns:ns0=\"urn:foo2\" />"
+ + StringUtils.LINE_SEP, sw.toString());
+ }
+
+ @Test
+ public void testNSGetsReused() throws IOException {
+ Document d = DOMUtils.newDocument();
+ Element root = d.createElementNS("urn:foo", "root");
+ Element child = d.createElementNS("urn:foo", "child");
+ root.appendChild(child);
+ StringWriter sw = new StringWriter();
+ DOMElementWriter w =
+ new DOMElementWriter(false,
+ DOMElementWriter.XmlNamespacePolicy
+ .ONLY_QUALIFY_ELEMENTS);
+ w.write(root, sw, 0, " ");
+ assertEquals("<root xmlns=\"urn:foo\">"
+ + StringUtils.LINE_SEP
+ + " <child />"
+ + StringUtils.LINE_SEP
+ + "</root>"
+ + StringUtils.LINE_SEP, sw.toString());
+ }
+
+ @Test
+ public void testNSGoesOutOfScope() throws IOException {
+ Document d = DOMUtils.newDocument();
+ Element root = d.createElementNS("urn:foo", "root");
+ Element child = d.createElementNS("urn:foo2", "child");
+ root.appendChild(child);
+ Element child2 = d.createElementNS("urn:foo2", "child");
+ root.appendChild(child2);
+ Element grandChild = d.createElementNS("urn:foo2", "grandchild");
+ child2.appendChild(grandChild);
+ Element child3 = d.createElementNS("urn:foo2", "child");
+ root.appendChild(child3);
+ StringWriter sw = new StringWriter();
+ DOMElementWriter w =
+ new DOMElementWriter(false,
+ DOMElementWriter.XmlNamespacePolicy
+ .ONLY_QUALIFY_ELEMENTS);
+ w.write(root, sw, 0, " ");
+ assertEquals("<root xmlns=\"urn:foo\">"
+ + StringUtils.LINE_SEP
+ + " <ns0:child xmlns:ns0=\"urn:foo2\" />"
+ + StringUtils.LINE_SEP
+ + " <ns1:child xmlns:ns1=\"urn:foo2\">"
+ + StringUtils.LINE_SEP
+ + " <ns1:grandchild />"
+ + StringUtils.LINE_SEP
+ + " </ns1:child>"
+ + StringUtils.LINE_SEP
+ + " <ns2:child xmlns:ns2=\"urn:foo2\" />"
+ + StringUtils.LINE_SEP
+ + "</root>"
+ + StringUtils.LINE_SEP, sw.toString());
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/DateUtilsTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/DateUtilsTest.java
new file mode 100644
index 00000000..4f5aa844
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/DateUtilsTest.java
@@ -0,0 +1,106 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.util;
+
+import java.util.Calendar;
+import java.util.TimeZone;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * TestCase for DateUtils.
+ *
+ */
+public class DateUtilsTest {
+
+
+ @Test
+ public void testElapsedTime(){
+ String text = DateUtils.formatElapsedTime(50*1000);
+ assertEquals("50 seconds", text);
+ text = DateUtils.formatElapsedTime(65*1000);
+ assertEquals("1 minute 5 seconds", text);
+ text = DateUtils.formatElapsedTime(120*1000);
+ assertEquals("2 minutes 0 seconds", text);
+ text = DateUtils.formatElapsedTime(121*1000);
+ assertEquals("2 minutes 1 second", text);
+ }
+
+ // https://issues.apache.org/bugzilla/show_bug.cgi?id=44659
+ @Test
+ public void testLongElapsedTime(){
+ assertEquals("2926 minutes 13 seconds",
+ DateUtils.formatElapsedTime(1000 * 175573));
+ assertEquals("153722867280912 minutes 55 seconds",
+ DateUtils.formatElapsedTime(Long.MAX_VALUE));
+ }
+
+ @Test
+ public void testDateTimeISO(){
+ TimeZone timeZone = TimeZone.getTimeZone("GMT+1");
+ Calendar cal = Calendar.getInstance(timeZone);
+ cal.set(2002,1,23,10,11,12);
+ String text = DateUtils.format(cal.getTime(),
+ DateUtils.ISO8601_DATETIME_PATTERN);
+ assertEquals("2002-02-23T09:11:12", text);
+ }
+
+ @Test
+ public void testDateISO(){
+ TimeZone timeZone = TimeZone.getTimeZone("GMT");
+ Calendar cal = Calendar.getInstance(timeZone);
+ cal.set(2002,1,23);
+ String text = DateUtils.format(cal.getTime(),
+ DateUtils.ISO8601_DATE_PATTERN);
+ assertEquals("2002-02-23", text);
+ }
+
+ @Test
+ public void testTimeISODate(){
+ // make sure that elapsed time in set via date works
+ TimeZone timeZone = TimeZone.getTimeZone("GMT+1");
+ Calendar cal = Calendar.getInstance(timeZone);
+ cal.set(2002,1,23, 21, 11, 12);
+ String text = DateUtils.format(cal.getTime(),
+ DateUtils.ISO8601_TIME_PATTERN);
+ assertEquals("20:11:12", text);
+ }
+
+ @Test
+ public void testTimeISO(){
+ // make sure that elapsed time in ms works
+ long ms = (20*3600 + 11*60 + 12)*1000;
+ String text = DateUtils.format(ms,
+ DateUtils.ISO8601_TIME_PATTERN);
+ assertEquals("20:11:12", text);
+ }
+
+ @Test
+ public void testPhaseOfMoon() {
+ TimeZone timeZone = TimeZone.getTimeZone("GMT");
+ Calendar cal = Calendar.getInstance(timeZone);
+ // should be full moon
+ cal.set(2002, 2, 27);
+ assertEquals(4, DateUtils.getPhaseOfMoon(cal));
+ // should be new moon
+ cal.set(2002, 2, 12);
+ assertEquals(0, DateUtils.getPhaseOfMoon(cal));
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/DeweyDecimalTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/DeweyDecimalTest.java
new file mode 100644
index 00000000..bcda609b
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/DeweyDecimalTest.java
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.util;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import org.junit.Test;
+
+@SuppressWarnings("ResultOfObjectAllocationIgnored")
+public class DeweyDecimalTest {
+
+ @Test public void parse() {
+ assertEquals("1.2.3", new DeweyDecimal("1.2.3").toString());
+ }
+
+ @Test(expected=NumberFormatException.class) public void misparseEmpty() {
+ new DeweyDecimal("1..2");
+ }
+
+ @Test(expected=NumberFormatException.class) public void misparseNonNumeric() {
+ new DeweyDecimal("1.2.3-beta-5");
+ }
+
+ @Test(expected=NumberFormatException.class) public void misparseFinalDot() {
+ new DeweyDecimal("1.2.");
+ }
+
+ // TODO initial dots, empty string, null, negative numbers, ...
+
+ @Test public void testHashCode() {
+ assertEquals(new DeweyDecimal("1.2.3").hashCode(), new DeweyDecimal("1.2.3").hashCode());
+ }
+
+ @Test public void testEquals() {
+ assertTrue(new DeweyDecimal("1.2.3").equals(new DeweyDecimal("1.2.3")));
+ assertFalse(new DeweyDecimal("1.2.3").equals(new DeweyDecimal("1.2.4")));
+ assertTrue(new DeweyDecimal("1.2.0").equals(new DeweyDecimal("1.2")));
+ assertTrue(new DeweyDecimal("1.2").equals(new DeweyDecimal("1.2.0")));
+ }
+
+ @Test public void compareTo() {
+ assertTrue(new DeweyDecimal("1.2.3").compareTo(new DeweyDecimal("1.2")) > 0);
+ assertTrue(new DeweyDecimal("1.2").compareTo(new DeweyDecimal("1.2.3")) < 0);
+ assertTrue(new DeweyDecimal("1.2.3").compareTo(new DeweyDecimal("1.2.3")) == 0);
+ assertTrue(new DeweyDecimal("1.2.3").compareTo(new DeweyDecimal("1.1.4")) > 0);
+ assertTrue(new DeweyDecimal("1.2.3").compareTo(new DeweyDecimal("1.2.2.9")) > 0);
+ assertTrue(new DeweyDecimal("1.2.0").compareTo(new DeweyDecimal("1.2")) == 0);
+ assertTrue(new DeweyDecimal("1.2").compareTo(new DeweyDecimal("1.2.0")) == 0);
+ }
+
+ // TODO isGreaterThan, ...
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/FileUtilsTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/FileUtilsTest.java
new file mode 100644
index 00000000..d0361cc5
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/FileUtilsTest.java
@@ -0,0 +1,625 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.util;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.taskdefs.condition.Os;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeTrue;
+
+/**
+ * Tests for org.apache.tools.ant.util.FileUtils.
+ *
+ */
+public class FileUtilsTest {
+
+ private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+ private File removeThis;
+ private String root;
+
+
+ @Before
+ public void setUp() {
+ // Windows adds the drive letter in uppercase, unless you run Cygwin
+ root = new File(File.separator).getAbsolutePath().toUpperCase();
+ }
+
+ @After
+ public void tearDown() {
+ if (removeThis != null && removeThis.exists()) {
+ if (!removeThis.delete())
+ {
+ removeThis.deleteOnExit();
+ }
+ }
+ }
+
+ /**
+ * test modification.
+ * Since Ant1.7, the method being tested no longer uses
+ * reflection to provide backwards support to Java1.1, so this
+ * test is not so critical. But it does explore file system
+ * behaviour and will help catch any regression in Java itself,
+ * so is worth retaining.
+ * @see FileUtils#setFileLastModified(java.io.File, long)
+ * @throws IOException
+ */
+ @Test
+ public void testSetLastModified() throws IOException {
+ removeThis = new File("dummy");
+ FileOutputStream fos = new FileOutputStream(removeThis);
+ fos.write(new byte[0]);
+ fos.close();
+ assumeTrue("Could not change file modified time", removeThis.setLastModified(removeThis.lastModified() - 2000));
+ long modTime = removeThis.lastModified();
+ assertTrue(modTime != 0);
+
+
+ FILE_UTILS.setFileLastModified(removeThis, -1);
+ long secondModTime = removeThis.lastModified();
+ assertTrue(secondModTime > modTime);
+
+ // number of milliseconds in a day
+ final int millisperday=24 * 3600 * 1000;
+ // in a previous version, the date of the file was set to 123456
+ // milliseconds since 01.01.1970
+ // it did not work on a computer running JDK 1.4.1_02 + Windows 2000
+ FILE_UTILS.setFileLastModified(removeThis, secondModTime + millisperday);
+ long thirdModTime = removeThis.lastModified();
+ /*
+ * I would love to compare this with 123456, but depending on
+ * the filesystems granularity it can take an arbitrary value.
+ *
+ * Just assert the time has changed.
+ */
+ assertTrue(thirdModTime != secondModTime);
+ }
+
+ @Test
+ public void testResolveFile() {
+ if (!(Os.isFamily("dos") || Os.isFamily("netware"))) {
+ /*
+ * Start with simple absolute file names.
+ */
+ assertEquals(File.separator,
+ FILE_UTILS.resolveFile(null, "/").getPath());
+ assertEquals(File.separator,
+ FILE_UTILS.resolveFile(null, "\\").getPath());
+ } else {
+ assertEqualsIgnoreDriveCase(localize(File.separator),
+ FILE_UTILS.resolveFile(null, "/").getPath());
+ assertEqualsIgnoreDriveCase(localize(File.separator),
+ FILE_UTILS.resolveFile(null, "\\").getPath());
+ /*
+ * throw in drive letters
+ */
+ String driveSpec = "C:";
+ assertEquals(driveSpec + "\\",
+ FILE_UTILS.resolveFile(null, driveSpec + "/").getPath());
+ assertEquals(driveSpec + "\\",
+ FILE_UTILS.resolveFile(null, driveSpec + "\\").getPath());
+ String driveSpecLower = "c:";
+ assertEquals(driveSpecLower + "\\",
+ FILE_UTILS.resolveFile(null, driveSpecLower + "/").getPath());
+ assertEquals(driveSpecLower + "\\",
+ FILE_UTILS.resolveFile(null, driveSpecLower + "\\").getPath());
+ /*
+ * promised to eliminate consecutive slashes after drive letter.
+ */
+ assertEquals(driveSpec + "\\",
+ FILE_UTILS.resolveFile(null, driveSpec + "/////").getPath());
+ assertEquals(driveSpec + "\\",
+ FILE_UTILS.resolveFile(null, driveSpec + "\\\\\\\\\\\\").getPath());
+ }
+ if (Os.isFamily("netware")) {
+ /*
+ * throw in NetWare volume names
+ */
+ String driveSpec = "SYS:";
+ assertEquals(driveSpec,
+ FILE_UTILS.resolveFile(null, driveSpec + "/").getPath());
+ assertEquals(driveSpec,
+ FILE_UTILS.resolveFile(null, driveSpec + "\\").getPath());
+ String driveSpecLower = "sys:";
+ assertEquals(driveSpec,
+ FILE_UTILS.resolveFile(null, driveSpecLower + "/").getPath());
+ assertEquals(driveSpec,
+ FILE_UTILS.resolveFile(null, driveSpecLower + "\\").getPath());
+ /*
+ * promised to eliminate consecutive slashes after drive letter.
+ */
+ assertEquals(driveSpec,
+ FILE_UTILS.resolveFile(null, driveSpec + "/////").getPath());
+ assertEquals(driveSpec,
+ FILE_UTILS.resolveFile(null, driveSpec + "\\\\\\\\\\\\").getPath());
+ } else if (!(Os.isFamily("dos"))) {
+ /*
+ * drive letters must be considered just normal filenames.
+ */
+ String driveSpec = "C:";
+ String udir = System.getProperty("user.dir");
+ assertEquals(udir + File.separator + driveSpec,
+ FILE_UTILS.resolveFile(null, driveSpec + "/").getPath());
+ assertEquals(udir + File.separator + driveSpec,
+ FILE_UTILS.resolveFile(null, driveSpec + "\\").getPath());
+ String driveSpecLower = "c:";
+ assertEquals(udir + File.separator + driveSpecLower,
+ FILE_UTILS.resolveFile(null, driveSpecLower + "/").getPath());
+ assertEquals(udir + File.separator + driveSpecLower,
+ FILE_UTILS.resolveFile(null, driveSpecLower + "\\").getPath());
+ }
+
+ /*
+ * Now test some relative file name magic.
+ */
+ assertEquals(localize("/1/2/3/4"),
+ FILE_UTILS.resolveFile(new File(localize("/1/2/3")), "4").getPath());
+ assertEquals(localize("/1/2/3/4"),
+ FILE_UTILS.resolveFile(new File(localize("/1/2/3")), "./4").getPath());
+ assertEquals(localize("/1/2/3/4"),
+ FILE_UTILS.resolveFile(new File(localize("/1/2/3")), ".\\4").getPath());
+ assertEquals(localize("/1/2/3/4"),
+ FILE_UTILS.resolveFile(new File(localize("/1/2/3")), "./.\\4").getPath());
+ assertEquals(localize("/1/2/3/4"),
+ FILE_UTILS.resolveFile(new File(localize("/1/2/3")), "../3/4").getPath());
+ assertEquals(localize("/1/2/3/4"),
+ FILE_UTILS.resolveFile(new File(localize("/1/2/3")), "..\\3\\4").getPath());
+ assertEquals(localize("/1/2/3/4"),
+ FILE_UTILS.resolveFile(new File(localize("/1/2/3")), "../../5/.././2/./3/6/../4").getPath());
+ assertEquals(localize("/1/2/3/4"),
+ FILE_UTILS.resolveFile(new File(localize("/1/2/3")), "..\\../5/..\\./2/./3/6\\../4").getPath());
+
+ assertEquals("meaningless result but no exception",
+ new File(localize("/1/../../b")),
+ FILE_UTILS.resolveFile(new File(localize("/1")), "../../b"));
+
+ }
+
+ @Test
+ public void testNormalize() {
+ if (!(Os.isFamily("dos") || Os.isFamily("netware"))) {
+ /*
+ * Start with simple absolute file names.
+ */
+ assertEquals(File.separator,
+ FILE_UTILS.normalize("/").getPath());
+ assertEquals(File.separator,
+ FILE_UTILS.normalize("\\").getPath());
+ } else {
+ try {
+ FILE_UTILS.normalize("/").getPath();
+ fail("normalized \"/\" on dos or netware");
+ } catch (Exception e) {
+ }
+ try {
+ FILE_UTILS.normalize("\\").getPath();
+ fail("normalized \"\\\" on dos or netware");
+ } catch (Exception e) {
+ }
+ }
+
+ if (Os.isFamily("dos")) {
+ /*
+ * throw in drive letters
+ */
+ String driveSpec = "C:";
+ try {
+ FILE_UTILS.normalize(driveSpec).getPath();
+ fail(driveSpec + " is not an absolute path");
+ } catch (Exception e) {
+ }
+ assertEquals(driveSpec + "\\",
+ FILE_UTILS.normalize(driveSpec + "/").getPath());
+ assertEquals(driveSpec + "\\",
+ FILE_UTILS.normalize(driveSpec + "\\").getPath());
+ String driveSpecLower = "c:";
+ assertEquals(driveSpecLower + "\\",
+ FILE_UTILS.normalize(driveSpecLower + "/").getPath());
+ assertEquals(driveSpecLower + "\\",
+ FILE_UTILS.normalize(driveSpecLower + "\\").getPath());
+ /*
+ * promised to eliminate consecutive slashes after drive letter.
+ */
+ assertEquals(driveSpec + "\\",
+ FILE_UTILS.normalize(driveSpec + "/////").getPath());
+ assertEquals(driveSpec + "\\",
+ FILE_UTILS.normalize(driveSpec + "\\\\\\\\\\\\").getPath());
+ } else if (Os.isFamily("netware")) {
+ /*
+ * throw in NetWare volume names
+ */
+ String driveSpec = "SYS:";
+ assertEquals(driveSpec,
+ FILE_UTILS.normalize(driveSpec).getPath());
+ assertEquals(driveSpec,
+ FILE_UTILS.normalize(driveSpec + "/").getPath());
+ assertEquals(driveSpec,
+ FILE_UTILS.normalize(driveSpec + "\\").getPath());
+ String driveSpecLower = "sys:";
+ assertEquals(driveSpec,
+ FILE_UTILS.normalize(driveSpecLower).getPath());
+ assertEquals(driveSpec,
+ FILE_UTILS.normalize(driveSpecLower + "/").getPath());
+ assertEquals(driveSpec,
+ FILE_UTILS.normalize(driveSpecLower + "\\").getPath());
+ assertEquals(driveSpec + "\\junk",
+ FILE_UTILS.normalize(driveSpecLower + "\\junk").getPath());
+ /*
+ * promised to eliminate consecutive slashes after drive letter.
+ */
+ assertEquals(driveSpec,
+ FILE_UTILS.normalize(driveSpec + "/////").getPath());
+ assertEquals(driveSpec,
+ FILE_UTILS.normalize(driveSpec + "\\\\\\\\\\\\").getPath());
+ } else {
+ try {
+ String driveSpec = "C:";
+ assertEquals(driveSpec,
+ FILE_UTILS.normalize(driveSpec).getPath());
+ fail("Expected failure, C: isn't an absolute path on other os's");
+ } catch (BuildException e) {
+ // Passed test
+ }
+ }
+
+ /*
+ * Now test some relative file name magic.
+ */
+ assertEquals(localize("/1/2/3/4"),
+ FILE_UTILS.normalize(localize("/1/2/3/4")).getPath());
+ assertEquals(localize("/1/2/3/4"),
+ FILE_UTILS.normalize(localize("/1/2/3/./4")).getPath());
+ assertEquals(localize("/1/2/3/4"),
+ FILE_UTILS.normalize(localize("/1/2/3/.\\4")).getPath());
+ assertEquals(localize("/1/2/3/4"),
+ FILE_UTILS.normalize(localize("/1/2/3/./.\\4")).getPath());
+ assertEquals(localize("/1/2/3/4"),
+ FILE_UTILS.normalize(localize("/1/2/3/../3/4")).getPath());
+ assertEquals(localize("/1/2/3/4"),
+ FILE_UTILS.normalize(localize("/1/2/3/..\\3\\4")).getPath());
+ assertEquals(localize("/1/2/3/4"),
+ FILE_UTILS.normalize(localize("/1/2/3/../../5/.././2/./3/6/../4")).getPath());
+ assertEquals(localize("/1/2/3/4"),
+ FILE_UTILS.normalize(localize("/1/2/3/..\\../5/..\\./2/./3/6\\../4")).getPath());
+
+ try {
+ FILE_UTILS.normalize("foo");
+ fail("foo is not an absolute path");
+ } catch (BuildException e) {
+ // Expected exception caught
+ }
+
+ assertEquals("will not go outside FS root (but will not throw an exception either)",
+ new File(localize("/1/../../b")),
+ FILE_UTILS.normalize(localize("/1/../../b")));
+ }
+
+ /**
+ * Test handling of null arguments.
+ */
+ @Test
+ public void testNullArgs() {
+ try {
+ FILE_UTILS.normalize(null);
+ fail("successfully normalized a null-file");
+ } catch (NullPointerException npe) {
+ // Expected exception caught
+ }
+
+ File f = FILE_UTILS.resolveFile(null, "a");
+ assertEquals(f, new File("a").getAbsoluteFile());
+ }
+
+
+ /**
+ * Test createTempFile
+ */
+ @Test
+ public void testCreateTempFile()
+ {
+ // null parent dir
+ File tmp1 = FILE_UTILS.createTempFile("pre", ".suf", null, false, true);
+ String tmploc = System.getProperty("java.io.tmpdir");
+ String name = tmp1.getName();
+ assertTrue("starts with pre", name.startsWith("pre"));
+ assertTrue("ends with .suf", name.endsWith(".suf"));
+ assertTrue("File was created", tmp1.exists());
+ assertEquals((new File(tmploc, tmp1.getName())).getAbsolutePath(), tmp1
+ .getAbsolutePath());
+ tmp1.delete();
+
+ File dir2 = new File(tmploc + "/ant-test");
+ dir2.mkdir();
+ removeThis = dir2;
+
+ File tmp2 = FILE_UTILS.createTempFile("pre", ".suf", dir2, true, true);
+ String name2 = tmp2.getName();
+ assertTrue("starts with pre", name2.startsWith("pre"));
+ assertTrue("ends with .suf", name2.endsWith(".suf"));
+ assertTrue("File was created", tmp2.exists());
+ assertEquals((new File(dir2, tmp2.getName())).getAbsolutePath(), tmp2
+ .getAbsolutePath());
+ tmp2.delete();
+ dir2.delete();
+
+ File parent = new File((new File("/tmp")).getAbsolutePath());
+ tmp1 = FILE_UTILS.createTempFile("pre", ".suf", parent, false);
+ assertTrue("new file", !tmp1.exists());
+
+ name = tmp1.getName();
+ assertTrue("starts with pre", name.startsWith("pre"));
+ assertTrue("ends with .suf", name.endsWith(".suf"));
+ assertEquals("is inside parent dir", parent.getAbsolutePath(), tmp1
+ .getParent());
+
+ tmp2 = FILE_UTILS.createTempFile("pre", ".suf", parent, false);
+ assertTrue("files are different", !tmp1.getAbsolutePath().equals(
+ tmp2.getAbsolutePath()));
+
+ // null parent dir
+ File tmp3 = FILE_UTILS.createTempFile("pre", ".suf", null, false);
+ tmploc = System.getProperty("java.io.tmpdir");
+ assertEquals((new File(tmploc, tmp3.getName())).getAbsolutePath(), tmp3
+ .getAbsolutePath());
+ }
+
+ /**
+ * Test contentEquals
+ */
+ @Test
+ public void testContentEquals() throws IOException {
+ assertTrue("Non existing files", FILE_UTILS.contentEquals(new File(System.getProperty("root"), "foo"),
+ new File(System.getProperty("root"), "bar")));
+ assertTrue("One exists, the other one doesn\'t",
+ !FILE_UTILS.contentEquals(new File(System.getProperty("root"), "foo"), new File(System.getProperty("root"), "build.xml")));
+ assertTrue("Don\'t compare directories",
+ !FILE_UTILS.contentEquals(new File(System.getProperty("root"), "src"), new File(System.getProperty("root"), "src")));
+ assertTrue("File equals itself",
+ FILE_UTILS.contentEquals(new File(System.getProperty("root"), "build.xml"),
+ new File(System.getProperty("root"), "build.xml")));
+ assertTrue("Files are different",
+ !FILE_UTILS.contentEquals(new File(System.getProperty("root"), "build.xml"),
+ new File(System.getProperty("root"), "docs.xml")));
+ }
+
+ /**
+ * Test createNewFile
+ */
+ @Test
+ public void testCreateNewFile() throws IOException {
+ removeThis = new File("dummy");
+ assertTrue(!removeThis.exists());
+ FILE_UTILS.createNewFile(removeThis);
+ assertTrue(removeThis.exists());
+ }
+
+ /**
+ * Test removeLeadingPath.
+ */
+ @Test
+ public void testRemoveLeadingPath() {
+ assertEquals("bar", FILE_UTILS.removeLeadingPath(new File("/foo"),
+ new File("/foo/bar")));
+ assertEquals("bar", FILE_UTILS.removeLeadingPath(new File("/foo/"),
+ new File("/foo/bar")));
+ assertEquals("bar", FILE_UTILS.removeLeadingPath(new File("\\foo"),
+ new File("\\foo\\bar")));
+ assertEquals("bar", FILE_UTILS.removeLeadingPath(new File("\\foo\\"),
+ new File("\\foo\\bar")));
+ assertEquals("bar", FILE_UTILS.removeLeadingPath(new File("c:/foo"),
+ new File("c:/foo/bar")));
+ assertEquals("bar", FILE_UTILS.removeLeadingPath(new File("c:/foo/"),
+ new File("c:/foo/bar")));
+ assertEquals("bar", FILE_UTILS.removeLeadingPath(new File("c:\\foo"),
+ new File("c:\\foo\\bar")));
+ assertEquals("bar", FILE_UTILS.removeLeadingPath(new File("c:\\foo\\"),
+ new File("c:\\foo\\bar")));
+ if (!(Os.isFamily("dos") || Os.isFamily("netware"))) {
+ assertEquals(FILE_UTILS.normalize("/bar").getAbsolutePath(),
+ FILE_UTILS.removeLeadingPath(new File("/foo"), new File("/bar")));
+ assertEquals(FILE_UTILS.normalize("/foobar").getAbsolutePath(),
+ FILE_UTILS.removeLeadingPath(new File("/foo"), new File("/foobar")));
+ }
+ // bugzilla report 19979
+ assertEquals("", FILE_UTILS.removeLeadingPath(new File("/foo/bar"),
+ new File("/foo/bar")));
+ assertEquals("", FILE_UTILS.removeLeadingPath(new File("/foo/bar"),
+ new File("/foo/bar/")));
+ assertEquals("", FILE_UTILS.removeLeadingPath(new File("/foo/bar/"),
+ new File("/foo/bar/")));
+ assertEquals("", FILE_UTILS.removeLeadingPath(new File("/foo/bar/"),
+ new File("/foo/bar")));
+
+ String expected = "foo/bar".replace('\\', File.separatorChar)
+ .replace('/', File.separatorChar);
+ assertEquals(expected, FILE_UTILS.removeLeadingPath(new File("/"),
+ new File("/foo/bar")));
+ assertEquals(expected, FILE_UTILS.removeLeadingPath(new File("c:/"),
+ new File("c:/foo/bar")));
+ assertEquals(expected, FILE_UTILS.removeLeadingPath(new File("c:\\"),
+ new File("c:\\foo\\bar")));
+ }
+
+ /**
+ * test toUri
+ */
+ @Test
+ public void testToURI() {
+ String dosRoot;
+ if (Os.isFamily("dos") || Os.isFamily("netware")) {
+ dosRoot = System.getProperty("user.dir")
+ .substring(0, 3).replace(File.separatorChar, '/');
+ }
+ else
+ {
+ dosRoot = "";
+ }
+ if (Os.isFamily("dos")) {
+ assertEquals("file:/c:/foo", removeExtraneousAuthority(FILE_UTILS.toURI("c:\\foo")));
+ }
+ if (Os.isFamily("netware")) {
+ assertEquals("file:/SYS:/foo", removeExtraneousAuthority(FILE_UTILS.toURI("sys:\\foo")));
+ }
+ if (File.pathSeparatorChar == '/') {
+ assertEquals("file:/foo", removeExtraneousAuthority(FILE_UTILS.toURI("/foo")));
+ assertTrue("file: URIs must name absolute paths", FILE_UTILS.toURI("./foo").startsWith("file:/"));
+ assertTrue(FILE_UTILS.toURI("./foo").endsWith("/foo"));
+ assertEquals("file:/" + dosRoot + "foo%20bar", removeExtraneousAuthority(FILE_UTILS.toURI("/foo bar")));
+ assertEquals("file:/" + dosRoot + "foo%23bar", removeExtraneousAuthority(FILE_UTILS.toURI("/foo#bar")));
+ } else if (File.pathSeparatorChar == '\\') {
+ assertEquals("file:/" + dosRoot + "foo", removeExtraneousAuthority(FILE_UTILS.toURI("\\foo")));
+ assertTrue("file: URIs must name absolute paths", FILE_UTILS.toURI(".\\foo").startsWith("file:/"));
+ assertTrue(FILE_UTILS.toURI(".\\foo").endsWith("/foo"));
+ assertEquals("file:/" + dosRoot + "foo%20bar", removeExtraneousAuthority(FILE_UTILS.toURI("\\foo bar")));
+ assertEquals("file:/" + dosRoot + "foo%23bar", removeExtraneousAuthority(FILE_UTILS.toURI("\\foo#bar")));
+ }
+ // a test with ant for germans
+ // the escaped character used for the test is the "a umlaut"
+ // this is the fix for the bug 37348
+ assertEquals("file:/" + dosRoot + "%C3%A4nt", removeExtraneousAuthority(FILE_UTILS.toURI("/\u00E4nt")));
+ }
+
+ /**
+ * Authority field is unnecessary, but harmless, in file: URIs.
+ * Java 1.4 does not produce it when using File.toURI.
+ */
+ private static String removeExtraneousAuthority(String uri) {
+ String prefix = "file:///";
+ if (uri.startsWith(prefix)) {
+ return "file:/" + uri.substring(prefix.length());
+ } else {
+ return uri;
+ }
+ }
+
+ @Test
+ public void testIsContextRelativePath() {
+ assumeTrue("Test only runs on DOS", Os.isFamily("dos"));
+ assertTrue(FileUtils.isContextRelativePath("/\u00E4nt"));
+ assertTrue(FileUtils.isContextRelativePath("\\foo"));
+ }
+
+ /**
+ * test fromUri
+ */
+ @Test
+ public void testFromURI() {
+ String dosRoot;
+ if (Os.isFamily("dos") || Os.isFamily("netware")) {
+ dosRoot = System.getProperty("user.dir").substring(0, 2);
+ } else {
+ dosRoot = "";
+ }
+ if (Os.isFamily("netware")) {
+ assertEqualsIgnoreDriveCase("SYS:\\foo", FILE_UTILS.fromURI("file:///sys:/foo"));
+ }
+ if (Os.isFamily("dos")) {
+ assertEqualsIgnoreDriveCase("C:\\foo", FILE_UTILS.fromURI("file:///c:/foo"));
+ }
+ assertEqualsIgnoreDriveCase(dosRoot + File.separator + "foo", FILE_UTILS.fromURI("file:///foo"));
+ assertEquals("." + File.separator + "foo",
+ FILE_UTILS.fromURI("file:./foo"));
+ assertEquals(dosRoot + File.separator + "foo bar", FILE_UTILS.fromURI("file:///foo%20bar"));
+ assertEquals(dosRoot + File.separator + "foo#bar", FILE_UTILS.fromURI("file:///foo%23bar"));
+ }
+
+ @Test
+ public void testModificationTests() {
+
+ //get a time
+ long firstTime=System.currentTimeMillis();
+ //add some time. We assume no OS has a granularity this bad
+ long secondTime=firstTime+60000;
+/*
+ assertTrue("same timestamp is up to date",
+ fu.isUpToDate(firstTime, firstTime));
+ */
+
+ //check that older is up to date with a newer dest
+ assertTrue("older source files are up to date",
+ FILE_UTILS.isUpToDate(firstTime,secondTime));
+ //check that older is up to date with a newer dest
+ assertFalse("newer source files are no up to date",
+ FILE_UTILS.isUpToDate(secondTime, firstTime));
+
+ assertTrue("-1 dest timestamp implies nonexistence",
+ !FILE_UTILS.isUpToDate(firstTime,-1L));
+ }
+
+ @Test
+ public void testHasErrorInCase() {
+ File tempFolder = new File(System.getProperty("java.io.tmpdir"));
+ File wellcased = FILE_UTILS.createTempFile("alpha", "beta", tempFolder,
+ true, true);
+ String s = wellcased.getName().toUpperCase();
+ File wrongcased = new File(tempFolder, s);
+ if (Os.isFamily("mac") && Os.isFamily("unix")) {
+ //no guarantees on filesystem case-sensitivity
+ } else if (Os.isFamily("dos")) {
+ assertTrue(FILE_UTILS.hasErrorInCase(wrongcased));
+ assertFalse(FILE_UTILS.hasErrorInCase(wellcased));
+ } else {
+ assertFalse(FILE_UTILS.hasErrorInCase(wrongcased));
+ assertFalse(FILE_UTILS.hasErrorInCase(wellcased));
+ }
+
+ }
+ public void testGetDefaultEncoding() {
+ // This just tests that the function does not blow up
+ FILE_UTILS.getDefaultEncoding();
+ }
+
+ /**
+ * adapt file separators to local conventions
+ */
+ private String localize(String path) {
+ path = root + path.substring(1);
+ return path.replace('\\', File.separatorChar).replace('/', File.separatorChar);
+ }
+
+ /**
+ * convenience method
+ * normalize brings the drive in uppercase
+ * the drive letter is in lower case under cygwin
+ * calling this method allows tests where normalize is called to pass under cygwin
+ */
+ private void assertEqualsIgnoreDriveCase(String s1, String s2) {
+ if ((Os.isFamily("dos") || Os.isFamily("netware"))
+ && s1.length() > 0 && s2.length() > 0) {
+ StringBuilder sb1 = new StringBuilder(s1);
+ StringBuilder sb2 = new StringBuilder(s2);
+ sb1.setCharAt(0, Character.toUpperCase(s1.charAt(0)));
+ sb2.setCharAt(0, Character.toUpperCase(s2.charAt(0)));
+ assertEquals(sb1.toString(), sb2.toString());
+ } else {
+ assertEquals(s1, s2);
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/GlobPatternMapperTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/GlobPatternMapperTest.java
new file mode 100644
index 00000000..5bd7db60
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/GlobPatternMapperTest.java
@@ -0,0 +1,102 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.util;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+/**
+ * Tests for org.apache.tools.ant.util;GlobPatternMapper.
+ *
+ */
+public class GlobPatternMapperTest {
+
+ @Test
+ public void testNoPatternAtAll() {
+ GlobPatternMapper m = new GlobPatternMapper();
+ m.setFrom("foobar");
+ m.setTo("baz");
+ assertNull("Shouldn\'t match foobar", m.mapFileName("plonk"));
+ String[] result = m.mapFileName("foobar");
+ assertNotNull("Should match foobar", result);
+ assertEquals("only one result for foobar", 1, result.length);
+ assertEquals("baz", result[0]);
+ }
+
+ @Test
+ public void testPostfixOnly() {
+ GlobPatternMapper m = new GlobPatternMapper();
+ m.setFrom("*foo");
+ m.setTo("*plonk");
+ assertNull("Shouldn\'t match *foo", m.mapFileName("bar.baz"));
+ String[] result = m.mapFileName("bar.foo");
+ assertNotNull("Should match *.foo", result);
+ assertEquals("only one result for bar.foo", 1, result.length);
+ assertEquals("bar.plonk", result[0]);
+
+ // Try a silly case
+ m.setTo("foo*");
+ result = m.mapFileName("bar.foo");
+ assertEquals("foobar.", result[0]);
+ }
+
+ @Test
+ public void testPrefixOnly() {
+ GlobPatternMapper m = new GlobPatternMapper();
+ m.setFrom("foo*");
+ m.setTo("plonk*");
+ assertNull("Shouldn\'t match foo*", m.mapFileName("bar.baz"));
+ String[] result = m.mapFileName("foo.bar");
+ assertNotNull("Should match foo*", result);
+ assertEquals("only one result for foo.bar", 1, result.length);
+ assertEquals("plonk.bar", result[0]);
+
+ // Try a silly case
+ m.setTo("*foo");
+ result = m.mapFileName("foo.bar");
+ assertEquals(".barfoo", result[0]);
+ }
+
+ @Test
+ public void testPreAndPostfix() {
+ GlobPatternMapper m = new GlobPatternMapper();
+ m.setFrom("foo*bar");
+ m.setTo("plonk*pling");
+ assertNull("Shouldn\'t match foo*bar", m.mapFileName("bar.baz"));
+ String[] result = m.mapFileName("foo.bar");
+ assertNotNull("Should match foo*bar", result);
+ assertEquals("only one result for foo.bar", 1, result.length);
+ assertEquals("plonk.pling", result[0]);
+
+ // and a little longer
+ result = m.mapFileName("foo.baz.bar");
+ assertNotNull("Should match foo*bar", result);
+ assertEquals("only one result for foo.baz.bar", 1, result.length);
+ assertEquals("plonk.baz.pling", result[0]);
+
+ // and a little shorter
+ result = m.mapFileName("foobar");
+ assertNotNull("Should match foo*bar", result);
+ assertEquals("only one result for foobar", 1, result.length);
+ assertEquals("plonkpling", result[0]);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/JAXPUtilsTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/JAXPUtilsTest.java
new file mode 100644
index 00000000..105c33d1
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/JAXPUtilsTest.java
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.util;
+
+import org.junit.Test;
+
+import java.io.File;
+
+import static org.junit.Assert.assertTrue;
+
+/**
+ * JAXPUtils test case
+ */
+public class JAXPUtilsTest {
+
+ @Test
+ public void testGetSystemId(){
+ File file = null;
+ if ( File.separatorChar == '\\' ){
+ file = new File("d:\\jdk");
+ } else {
+ file = new File("/user/local/bin");
+ }
+ String systemid = JAXPUtils.getSystemId(file);
+ assertTrue("SystemIDs should start by file:/", systemid.startsWith("file:/"));
+ assertTrue("SystemIDs should not start with file:////", !systemid.startsWith("file:////"));
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/JavaEnvUtilsTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/JavaEnvUtilsTest.java
new file mode 100644
index 00000000..8bcb1f2c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/JavaEnvUtilsTest.java
@@ -0,0 +1,144 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.util;
+
+import java.io.File;
+
+import junit.framework.AssertionFailedError;
+
+import org.apache.tools.ant.taskdefs.condition.Os;
+import org.junit.Assume;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * TestCase for JavaEnvUtils.
+ *
+ */
+public class JavaEnvUtilsTest {
+
+ private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
+
+
+ @Test
+ public void testGetExecutableNetware() {
+ Assume.assumeTrue("Test only runs on netware", Os.isName("netware"));
+ assertEquals("java", JavaEnvUtils.getJreExecutable("java"));
+ assertEquals("javac", JavaEnvUtils.getJdkExecutable("javac"));
+ assertEquals("foo", JavaEnvUtils.getJreExecutable("foo"));
+ assertEquals("foo", JavaEnvUtils.getJdkExecutable("foo"));
+ }
+
+ @Test
+ public void testGetExecutableWindows() {
+ Assume.assumeTrue("Test only runs on windows", Os.isFamily("windows"));
+ String javaHome =
+ FILE_UTILS.normalize(System.getProperty("java.home"))
+ .getAbsolutePath();
+
+ String j = JavaEnvUtils.getJreExecutable("java");
+ assertTrue(j.endsWith(".exe"));
+ assertTrue(j+" is absolute", (new File(j)).isAbsolute());
+ try {
+ assertTrue(j+" is normalized and in the JRE dir",
+ j.startsWith(javaHome));
+ } catch (AssertionFailedError e) {
+ // java.home is bogus
+ assertEquals("java.exe", j);
+ }
+
+ j = JavaEnvUtils.getJdkExecutable("javac");
+ assertTrue(j.endsWith(".exe"));
+ try {
+ assertTrue(j+" is absolute", (new File(j)).isAbsolute());
+ String javaHomeParent =
+ FILE_UTILS.normalize(javaHome+"/..").getAbsolutePath();
+ assertTrue(j+" is normalized and in the JDK dir",
+ j.startsWith(javaHomeParent));
+ assertTrue(j+" is normalized and not in the JRE dir",
+ !j.startsWith(javaHome));
+
+ } catch (AssertionFailedError e) {
+ // java.home is bogus
+ assertEquals("javac.exe", j);
+ }
+
+ assertEquals("foo.exe", JavaEnvUtils.getJreExecutable("foo"));
+ assertEquals("foo.exe", JavaEnvUtils.getJdkExecutable("foo"));
+ }
+
+ @Test
+ public void testGetExecutableMostPlatforms() {
+ Assume.assumeTrue("Test only runs on non Netware and non Windows systems",
+ !Os.isName("netware") && !Os.isFamily("windows"));
+ String javaHome =
+ FILE_UTILS.normalize(System.getProperty("java.home"))
+ .getAbsolutePath();
+
+ // could still be OS/2
+ String extension = Os.isFamily("dos") ? ".exe" : "";
+
+ String j = JavaEnvUtils.getJreExecutable("java");
+ if (!extension.equals("")) {
+ assertTrue(j.endsWith(extension));
+ }
+ assertTrue(j+" is absolute", (new File(j)).isAbsolute());
+ assertTrue(j+" is normalized and in the JRE dir",
+ j.startsWith(javaHome));
+
+ j = JavaEnvUtils.getJdkExecutable("javac");
+ if (!extension.equals("")) {
+ assertTrue(j.endsWith(extension));
+ }
+ assertTrue(j+" is absolute", (new File(j)).isAbsolute());
+
+ String javaHomeParent =
+ FILE_UTILS.normalize(javaHome+"/..").getAbsolutePath();
+ assertTrue(j+" is normalized and in the JDK dir",
+ j.startsWith(javaHomeParent));
+
+ if ((Os.isFamily("mac") && JavaEnvUtils.getJavaVersionNumber() <= JavaEnvUtils.VERSION_1_6)
+ || JavaEnvUtils.isAtLeastJavaVersion(JavaEnvUtils.JAVA_1_9)) {
+ assertTrue(j+" is normalized and in the JRE dir",
+ j.startsWith(javaHome));
+ } else {
+ assertTrue(j+" is normalized and not in the JRE dir",
+ !j.startsWith(javaHome));
+ }
+
+ assertEquals("foo"+extension,
+ JavaEnvUtils.getJreExecutable("foo"));
+ assertEquals("foo"+extension,
+ JavaEnvUtils.getJdkExecutable("foo"));
+ }
+
+ @Test
+ public void testIsAtLeastJavaVersion()
+ {
+ assertTrue(
+ "Current java version is not at least the current java version...",
+ JavaEnvUtils.isAtLeastJavaVersion(JavaEnvUtils.getJavaVersion()));
+ assertFalse(
+ "In case the current java version is higher than 9.0 definitely a new algorithem will be needed",
+ JavaEnvUtils.isAtLeastJavaVersion("9.0"));
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/LayoutPreservingPropertiesTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/LayoutPreservingPropertiesTest.java
new file mode 100644
index 00000000..89cd3daa
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/LayoutPreservingPropertiesTest.java
@@ -0,0 +1,316 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.util;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.InputStreamReader;
+import java.io.IOException;
+import java.util.Properties;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class LayoutPreservingPropertiesTest {
+
+ /**
+ * Tests that a properties file read by the
+ * LayoutPreservingPropertiesFile and then saves the properties in
+ * it.
+ */
+ @Test
+ public void testPreserve() throws Exception {
+ File simple = new File(System.getProperty("root"),
+ "src/etc/testcases/util/simple.properties");
+ FileInputStream fis = new FileInputStream(simple);
+ LayoutPreservingProperties lpf = new LayoutPreservingProperties();
+ lpf.load(fis);
+
+ File tmp = File.createTempFile("tmp", "props");
+ tmp.deleteOnExit();
+ lpf.saveAs(tmp);
+
+ // now compare original and tmp for property equivalence
+ Properties originalProps = new Properties();
+ originalProps.load(new FileInputStream(simple));
+
+ Properties tmpProps = new Properties();
+ tmpProps.load(new FileInputStream(tmp));
+
+ assertEquals("properties corrupted", originalProps, tmpProps);
+
+ // and now make sure that the comments made it into the new file
+ String s = readFile(tmp);
+ assertTrue("missing comment", s.indexOf("# a comment") > -1);
+ assertTrue("missing comment", s.indexOf("! more comment") > -1);
+ }
+
+ /**
+ * Tests that names and value are properly escaped when being
+ * written out.
+ */
+ @Test
+ public void testEscaping() throws Exception {
+ LayoutPreservingProperties lpf = new LayoutPreservingProperties();
+
+ lpf.setProperty(" prop one ", " leading and trailing spaces ");
+ lpf.setProperty("prop\ttwo", "contains\ttab");
+ lpf.setProperty("prop\nthree", "contains\nnewline");
+ lpf.setProperty("prop\rfour", "contains\rcarraige return");
+ lpf.setProperty("prop\ffive", "contains\fform feed");
+ lpf.setProperty("prop\\six", "contains\\backslash");
+ lpf.setProperty("prop:seven", "contains:colon");
+ lpf.setProperty("prop=eight", "contains=equals");
+ lpf.setProperty("prop#nine", "contains#hash");
+ lpf.setProperty("prop!ten", "contains!exclamation");
+
+ File tmp = File.createTempFile("tmp", "props");
+ tmp.deleteOnExit();
+ lpf.saveAs(tmp);
+
+ // and check that the resulting file looks okay
+ String s = readFile(tmp);
+
+ assertTrue(s.indexOf("\\ prop\\ one\\ =\\ \\ leading and trailing"
+ + " spaces ") > -1);
+ assertTrue(s.indexOf("prop\\ttwo=contains\\ttab") > -1);
+ assertTrue(s.indexOf("prop\\nthree=contains\\nnewline") > -1);
+ assertTrue(s.indexOf("prop\\rfour=contains\\rcarraige return") > -1);
+ assertTrue(s.indexOf("prop\\\\six=contains\\\\backslash") > -1);
+ assertTrue(s.indexOf("prop\\:seven=contains\\:colon") > -1);
+ assertTrue(s.indexOf("prop\\=eight=contains\\=equals") > -1);
+ assertTrue(s.indexOf("prop\\#nine=contains\\#hash") > -1);
+ assertTrue(s.indexOf("prop\\!ten=contains\\!exclamation") > -1);
+ }
+
+ /**
+ * Tests that properties are correctly indexed, so that when we set
+ * an existing property, it updates the logical line, and it doesn't
+ * append a new one.
+ */
+ @Test
+ public void testOverwrite() throws Exception {
+ File unusual = new File(System.getProperty("root"),
+ "src/etc/testcases/util/unusual.properties");
+ FileInputStream fis = new FileInputStream(unusual);
+ LayoutPreservingProperties lpf = new LayoutPreservingProperties();
+ lpf.load(fis);
+
+ lpf.setProperty(" prop one ", "new one");
+ lpf.setProperty("prop\ttwo", "new two");
+ lpf.setProperty("prop\nthree", "new three");
+
+ File tmp = File.createTempFile("tmp", "props");
+ tmp.deleteOnExit();
+ lpf.saveAs(tmp);
+
+ // and check that the resulting file looks okay
+ String s = readFile(tmp);
+
+ assertTrue(s.indexOf("\\ prop\\ one\\ =\\ \\ leading and"
+ + " trailing spaces ") == -1);
+ assertTrue(s.indexOf("\\ prop\\ one\\ =new one") > -1);
+ assertTrue(s.indexOf("prop\\ttwo=contains\\ttab") == -1);
+ assertTrue(s.indexOf("prop\\ttwo=new two") > -1);
+ assertTrue(s.indexOf("prop\\nthree=contains\\nnewline") == -1);
+ assertTrue(s.indexOf("prop\\nthree=new three") > -1);
+ }
+
+ @Test
+ public void testStoreWithHeader() throws Exception {
+ File simple = new File(System.getProperty("root"),
+ "src/etc/testcases/util/simple.properties");
+ FileInputStream fis = new FileInputStream(simple);
+ LayoutPreservingProperties lpf = new LayoutPreservingProperties();
+ lpf.load(fis);
+
+ File tmp = File.createTempFile("tmp", "props");
+ tmp.deleteOnExit();
+ FileOutputStream fos = new FileOutputStream(tmp);
+ lpf.store(fos, "file-header");
+ fos.close();
+
+ // and check that the resulting file looks okay
+ String s = readFile(tmp);
+
+ assertTrue("should have had header ", s.startsWith("#file-header"));
+ }
+
+ @Test
+ public void testClear() throws Exception {
+ File simple = new File(System.getProperty("root"),
+ "src/etc/testcases/util/simple.properties");
+ FileInputStream fis = new FileInputStream(simple);
+ LayoutPreservingProperties lpf = new LayoutPreservingProperties();
+ lpf.load(fis);
+
+ lpf.clear();
+
+ File tmp = File.createTempFile("tmp", "props");
+ tmp.deleteOnExit();
+ lpf.saveAs(tmp);
+
+ // and check that the resulting file looks okay
+ String s = readFile(tmp);
+
+ assertTrue("should have had no properties ",
+ s.indexOf("prop.alpha") == -1);
+ assertTrue("should have had no properties ",
+ s.indexOf("prop.beta") == -1);
+ assertTrue("should have had no properties ",
+ s.indexOf("prop.gamma") == -1);
+
+ assertTrue("should have had no comments",
+ s.indexOf("# a comment") == -1);
+ assertTrue("should have had no comments",
+ s.indexOf("! more comment") == -1);
+ assertTrue("should have had no comments",
+ s.indexOf("# now a line wrapping one") == -1);
+ }
+
+ @Test
+ public void testRemove() throws Exception {
+ File simple = new File(System.getProperty("root"),
+ "src/etc/testcases/util/simple.properties");
+ FileInputStream fis = new FileInputStream(simple);
+ LayoutPreservingProperties lpf = new LayoutPreservingProperties();
+ lpf.load(fis);
+
+ lpf.remove("prop.beta");
+
+ File tmp = File.createTempFile("tmp", "props");
+ tmp.deleteOnExit();
+ lpf.saveAs(tmp);
+
+ // and check that the resulting file looks okay
+ String s = readFile(tmp);
+
+ assertTrue("should not have had prop.beta",
+ s.indexOf("prop.beta") == -1);
+ assertTrue("should have had prop.beta's comment",
+ s.indexOf("! more comment") > -1);
+ }
+
+ @Test
+ public void testRemoveWithComment() throws Exception {
+ File simple = new File(System.getProperty("root"),
+ "src/etc/testcases/util/simple.properties");
+ FileInputStream fis = new FileInputStream(simple);
+ LayoutPreservingProperties lpf = new LayoutPreservingProperties();
+ lpf.load(fis);
+
+ lpf.setRemoveComments(true);
+
+ lpf.remove("prop.beta");
+
+ File tmp = File.createTempFile("tmp", "props");
+ tmp.deleteOnExit();
+ lpf.saveAs(tmp);
+
+ // and check that the resulting file looks okay
+ String s = readFile(tmp);
+
+ assertTrue("should not have had prop.beta",
+ s.indexOf("prop.beta") == -1);
+ assertTrue("should not have had prop.beta's comment",
+ s.indexOf("! more comment") == -1);
+ }
+
+ @Test
+ public void testClone() throws Exception {
+ File simple = new File(System.getProperty("root"),
+ "src/etc/testcases/util/simple.properties");
+ FileInputStream fis = new FileInputStream(simple);
+ LayoutPreservingProperties lpf1 = new LayoutPreservingProperties();
+ lpf1.load(fis);
+
+ LayoutPreservingProperties lpf2 =
+ (LayoutPreservingProperties) lpf1.clone();
+
+ lpf2.setProperty("prop.new", "a new property");
+ lpf2.setProperty("prop.beta", "a new value for beta");
+
+ assertEquals("size of original is wrong", 3, lpf1.size());
+ assertEquals("size of clone is wrong", 4, lpf2.size());
+
+ File tmp1 = File.createTempFile("tmp", "props");
+ tmp1.deleteOnExit();
+ lpf1.saveAs(tmp1);
+ String s1 = readFile(tmp1);
+
+ File tmp2 = File.createTempFile("tmp", "props");
+ tmp2.deleteOnExit();
+ lpf2.saveAs(tmp2);
+ String s2 = readFile(tmp2);
+
+ // check original is untouched
+ assertTrue("should have had 'simple'", s1.indexOf("simple") > -1);
+ assertTrue("should not have had prop.new", s1.indexOf("prop.new") == -1);
+
+ // check clone has the changes
+ assertTrue("should have had 'a new value for beta'",
+ s2.indexOf("a new value for beta") > -1);
+ assertTrue("should have had prop.new", s2.indexOf("prop.new") > -1);
+ }
+
+ @Test
+ public void testPreserveEscapeName() throws Exception {
+ LayoutPreservingProperties lpf = new LayoutPreservingProperties();
+ File unusual = new File(System.getProperty("root"),
+ "src/etc/testcases/util/unusual.properties");
+ FileInputStream fis = new FileInputStream(unusual);
+ lpf.load(fis);
+
+ lpf.setProperty("prop:seven", "new value for seven");
+ lpf.setProperty("prop=eight", "new value for eight");
+ lpf.setProperty("prop eleven", "new value for eleven");
+
+ lpf.setProperty("alpha", "new value for alpha");
+ lpf.setProperty("beta", "new value for beta");
+
+ File tmp = File.createTempFile("tmp", "props");
+ tmp.deleteOnExit();
+ lpf.saveAs(tmp);
+
+ // and check that the resulting file looks okay
+ String s = readFile(tmp);
+
+ assertTrue(s.indexOf("prop\\:seven=new value for seven") > -1);
+ assertTrue(s.indexOf("prop\\=eight=new value for eight") > -1);
+ assertTrue(s.indexOf("prop\\ eleven=new value for eleven") > -1);
+ assertTrue(s.indexOf("alpha=new value for alpha") > -1);
+ assertTrue(s.indexOf("beta=new value for beta") > -1);
+
+ assertTrue(s.indexOf("prop\\:seven=contains\\:colon") == -1);
+ assertTrue(s.indexOf("prop\\=eight=contains\\=equals") == -1);
+ assertTrue(s.indexOf("alpha:set with a colon") == -1);
+ assertTrue(s.indexOf("beta set with a space") == -1);
+ }
+
+ private static String readFile(File f) throws IOException {
+ FileInputStream fis = new FileInputStream(f);
+ InputStreamReader isr = new InputStreamReader(fis);
+ String s = FileUtils.readFully(isr);
+ isr.close();
+ fis.close();
+ return s;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/LazyFileOutputStreamTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/LazyFileOutputStreamTest.java
new file mode 100644
index 00000000..82c36340
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/LazyFileOutputStreamTest.java
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.util;
+
+import java.io.File;
+import java.io.IOException;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertTrue;
+
+/**
+ * @since Ant 1.6
+ */
+public class LazyFileOutputStreamTest {
+ private LazyFileOutputStream los;
+ private final static File f = new File("test.txt");
+
+ @Before
+ public void setUp() {
+ los = new LazyFileOutputStream(f);
+ }
+
+ @After
+ public void tearDown() throws IOException {
+ try {
+ los.close();
+ } finally {
+ f.delete();
+ }
+ }
+
+ @Test
+ public void testNoFileWithoutWrite() throws IOException {
+ los.close();
+ assertTrue(f + " has not been written.", !f.exists());
+ }
+
+ @Test
+ public void testOpen() throws IOException {
+ los.open();
+ los.close();
+ assertTrue(f + " has been written.", f.exists());
+ }
+
+ @Test
+ public void testSingleByte() throws IOException {
+ los.write(0);
+ los.close();
+ assertTrue(f + " has been written.", f.exists());
+ }
+
+ @Test
+ public void testByteArray() throws IOException {
+ los.write(new byte[] {0});
+ los.close();
+ assertTrue(f + " has been written.", f.exists());
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/LineOrientedOutputStreamTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/LineOrientedOutputStreamTest.java
new file mode 100644
index 00000000..1fa23e84
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/LineOrientedOutputStreamTest.java
@@ -0,0 +1,153 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.util;
+
+import java.io.IOException;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+
+public class LineOrientedOutputStreamTest {
+
+ private static String LINE = "This is a line";
+ private DummyStream stream;
+
+
+ @Before
+ public void setUp() {
+ stream = new DummyStream();
+ }
+
+ @After
+ public void tearDown() throws IOException {
+ if (stream != null) {
+ stream.close();
+ }
+ }
+
+ @Test
+ public void testLineWithLinefeedArray() throws IOException {
+ writeByteArray();
+ writeAsArray('\n');
+ stream.assertInvoked();
+ }
+
+ @Test
+ public void testLineWithLinefeedSingleBytes() throws IOException {
+ writeSingleBytes();
+ stream.write('\n');
+ stream.assertInvoked();
+ }
+
+ @Test
+ public void testLineWithCariagereturnArray() throws IOException {
+ writeByteArray();
+ writeAsArray('\r');
+ stream.assertInvoked();
+ }
+
+ @Test
+ public void testLineWithCariagereturnSingleBytes() throws IOException {
+ writeSingleBytes();
+ stream.write('\r');
+ stream.assertInvoked();
+ }
+
+ @Test
+ public void testLineWithCariagereturnLinefeedArray() throws IOException {
+ writeByteArray();
+ writeAsArray('\r');
+ writeAsArray('\n');
+ stream.assertInvoked();
+ }
+
+ @Test
+ public void testLineWithCariagereturnLinefeedSingleBytes() throws IOException {
+ writeSingleBytes();
+ stream.write('\r');
+ stream.write('\n');
+ stream.assertInvoked();
+ }
+
+ @Test
+ public void testFlushArray() throws IOException {
+ writeByteArray();
+ stream.flush();
+ stream.assertNotInvoked();
+ }
+
+ @Test
+ public void testFlushSingleBytes() throws IOException {
+ writeSingleBytes();
+ stream.flush();
+ stream.assertNotInvoked();
+ }
+
+ @Test
+ public void testCloseArray() throws IOException {
+ writeByteArray();
+ stream.close();
+ stream.assertInvoked();
+ stream = null;
+ }
+
+ @Test
+ public void testCloseSingleBytes() throws IOException {
+ writeSingleBytes();
+ stream.close();
+ stream.assertInvoked();
+ stream = null;
+ }
+
+ private void writeByteArray() throws IOException {
+ stream.write(LINE.getBytes(), 0, LINE.length());
+ }
+
+ private void writeSingleBytes() throws IOException {
+ byte[] b = LINE.getBytes();
+ for (int i = 0; i < b.length; i++) {
+ stream.write(b[i]);
+ }
+ }
+
+ private void writeAsArray(char c) throws IOException {
+ stream.write(new byte[] {(byte) c}, 0, 1);
+ }
+
+ private class DummyStream extends LineOrientedOutputStream {
+ private boolean invoked;
+ protected void processLine(String line) {
+ assertFalse("Only one line", invoked);
+ assertEquals(LINE, line);
+ invoked = true;
+ }
+
+ private void assertInvoked() {
+ assertTrue("At least one line", invoked);
+ }
+ private void assertNotInvoked() {
+ assertTrue("No output", !invoked);
+ }
+ }
+}// LineOrientedOutputStreamTest
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/LinkedHashtableTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/LinkedHashtableTest.java
new file mode 100644
index 00000000..bfd2cda7
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/LinkedHashtableTest.java
@@ -0,0 +1,165 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.util;
+
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertEquals;
+
+public class LinkedHashtableTest {
+
+ private static final Object K1 = new Object();
+ private static final Object K2 = new Object();
+ private static final Object V1 = new Object();
+ private static final Object V2 = new Object();
+ private Hashtable h = new LinkedHashtable();
+
+ public void testClear() {
+ h.put(K1, V1);
+ h.clear();
+ assertTrue(h.isEmpty());
+ }
+
+ public void testClone() {
+ h.put(K1, V1);
+ Hashtable h2 = (Hashtable) h.clone();
+ assertTrue(h2 instanceof LinkedHashtable);
+ assertTrue(h2.containsKey(K1));
+ }
+
+ @Test
+ public void testContainsAndPut() {
+ h.put(K1, V1);
+ assertTrue(h.contains(K1));
+ assertTrue(h.containsKey(K1));
+ assertTrue(h.containsValue(V1));
+ assertFalse(h.containsKey(K2));
+ }
+
+ @Test
+ public void testGet() {
+ assertNull(h.get(K1));
+ h.put(K1, V1);
+ assertSame(V1, h.get(K1));
+ }
+
+ @Test
+ public void testIsEmpty() {
+ assertTrue(h.isEmpty());
+ h.put(K1, V1);
+ assertFalse(h.isEmpty());
+ }
+
+ @Test
+ public void testPutReturnValue() {
+ assertNull(h.put(K1, V1));
+ assertSame(V1, h.put(K1, V2));
+ }
+
+ @Test
+ public void testPutAll() {
+ LinkedHashtable h2 = new LinkedHashtable();
+ h.put(K1, V1);
+ h2.putAll(h);
+ assertTrue(h2.containsKey(K1));
+ }
+
+ @Test
+ public void testRemove() {
+ h.put(K1, V1);
+ assertSame(V1, h.remove(K1));
+ assertTrue(h.isEmpty());
+ assertNull(h.remove(K1));
+ }
+
+ @Test
+ public void testSize() {
+ assertEquals(0, h.size());
+ h.put(K1, V1);
+ assertEquals(1, h.size());
+ }
+
+ @Test
+ public void testKeys() {
+ multiSetup();
+ assertKeys(CollectionUtils.asIterator(h.keys()));
+ }
+
+ @Test
+ public void testKeySet() {
+ multiSetup();
+ assertKeys(h.keySet().iterator());
+ }
+
+ @Test
+ public void testElements() {
+ multiSetup();
+ assertValues(CollectionUtils.asIterator(h.elements()));
+ }
+
+ @Test
+ public void testValues() {
+ multiSetup();
+ assertValues(h.values().iterator());
+ }
+
+ @Test
+ public void testEntrySet() {
+ multiSetup();
+ Iterator i = h.entrySet().iterator();
+ assertTrue(i.hasNext());
+ Map.Entry e = (Map.Entry) i.next();
+ assertSame(K1, e.getKey());
+ assertSame(V1, e.getValue());
+ assertTrue(i.hasNext());
+ e = (Map.Entry) i.next();
+ assertSame(K2, e.getKey());
+ assertSame(V2, e.getValue());
+ assertFalse(i.hasNext());
+ }
+
+ private void multiSetup() {
+ h.put(K1, V1);
+ h.put(K2, V2);
+ }
+
+ private static void assertKeys(Iterator i) {
+ assertTrue(i.hasNext());
+ assertSame(K1, i.next());
+ assertTrue(i.hasNext());
+ assertSame(K2, i.next());
+ assertFalse(i.hasNext());
+ }
+
+ private static void assertValues(Iterator i) {
+ assertTrue(i.hasNext());
+ assertSame(V1, i.next());
+ assertTrue(i.hasNext());
+ assertSame(V2, i.next());
+ assertFalse(i.hasNext());
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/LoaderUtilsTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/LoaderUtilsTest.java
new file mode 100644
index 00000000..9935edd6
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/LoaderUtilsTest.java
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.util;
+
+import java.io.File;
+import org.junit.Test;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertEquals;
+
+/**
+ * @since Ant 1.6
+ */
+public class LoaderUtilsTest {
+
+ @Test
+ public void testGetXyzSource() {
+ File f1 = LoaderUtils.getClassSource(LoaderUtils.class);
+ assertNotNull(f1);
+
+ File f2 = LoaderUtils.getResourceSource(null,
+ "org/apache/tools/ant/taskdefs/defaults.properties");
+ assertNotNull(f2);
+
+ assertEquals(f1.getAbsolutePath(), f2.getAbsolutePath());
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/PackageNameMapperTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/PackageNameMapperTest.java
new file mode 100644
index 00000000..fdf73931
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/PackageNameMapperTest.java
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+ package org.apache.tools.ant.util;
+
+import org.junit.Test;
+
+import java.io.File;
+
+import static org.junit.Assert.assertEquals;
+
+public class PackageNameMapperTest {
+
+ @Test
+ public void testMapping() {
+ PackageNameMapper mapper = new PackageNameMapper();
+ mapper.setFrom("*.java");
+ mapper.setTo("TEST-*.xml");
+ String file = fixupPath("org/apache/tools/ant/util/PackageNameMapperTest.java");
+ String result = mapper.mapFileName(file)[0];
+
+ assertEquals("TEST-org.apache.tools.ant.util.PackageNameMapperTest.xml",
+ result);
+ }
+
+ private String fixupPath(String file) {
+ return file.replace('/', File.separatorChar);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/ReaderInputStreamTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/ReaderInputStreamTest.java
new file mode 100644
index 00000000..bd07251e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/ReaderInputStreamTest.java
@@ -0,0 +1,142 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.util;
+
+import org.junit.Test;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStreamReader;
+import java.io.StringReader;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+/**
+ * Test for ReaderInputStream
+ */
+public class ReaderInputStreamTest {
+
+ @Test
+ public void testSimple() throws Exception {
+ compareBytes("abc", "utf-8");
+ }
+
+ @Test
+ public void testSimple16() throws Exception {
+ compareBytes("a", "utf-16");
+ }
+
+ @Test
+ public void testSimpleAbc16() throws Exception {
+ // THIS WILL FAIL.
+ //compareBytes("abc", "utf-16");
+ byte[] bytes = new byte[40];
+ int pos = 0;
+ ReaderInputStream r = new ReaderInputStream(
+ new StringReader("abc"), "utf-16");
+ for (int i = 0; true; ++i) {
+ int res = r.read();
+ if (res == -1) {
+ break;
+ }
+ bytes[pos++] = (byte) res;
+ }
+ bytes = "abc".getBytes("utf-16");
+ // String n = new String(bytes, 0, pos, "utf-16");
+ new String(bytes, 0, bytes.length, "utf-16");
+ }
+
+ @Test
+ public void testReadZero() throws Exception {
+ ReaderInputStream r = new ReaderInputStream(
+ new StringReader("abc"));
+ byte[] bytes = new byte[30];
+ // First read in zero bytes
+ r.read(bytes, 0, 0);
+ // Now read in the string
+ int readin = r.read(bytes, 0, 10);
+ // Make sure that the counts are the same
+ assertEquals("abc".getBytes().length, readin);
+ }
+
+ @Test
+ public void testPreample() throws Exception {
+ byte[] bytes = "".getBytes("utf-16");
+ System.out.println("Preample len is " + bytes.length);
+ }
+
+ @Test
+ public void testIso88591ToUtf8() throws Exception {
+ InputStreamReader fin = null;
+ ReaderInputStream r = null;
+ FileInputStream utf8 = null;
+ try {
+ fin = new InputStreamReader(new FileInputStream(new File(System.getProperty("root"), "src/tests/antunit/taskdefs/exec/input/iso8859-1")),
+ "ISO8859_1");
+ r = new ReaderInputStream(fin, "UTF8");
+
+ ByteArrayOutputStream actualOS = new ByteArrayOutputStream();
+ int b = r.read();
+ while (b > -1) {
+ actualOS.write((byte) b);
+ b = r.read();
+ }
+
+ utf8 = new FileInputStream(new File(System.getProperty("root"), "src/tests/antunit/taskdefs/exec/expected/utf-8"));
+ ByteArrayOutputStream expectedOS = new ByteArrayOutputStream();
+ b = utf8.read();
+ while (b > -1) {
+ expectedOS.write((byte) b);
+ b = utf8.read();
+ }
+
+ byte[] expected = expectedOS.toByteArray();
+ byte[] actual = actualOS.toByteArray();
+ assertEquals("length", expected.length, actual.length);
+ for (int i = 0; i < actual.length; i++) {
+ assertEquals("byte " + i, expected[i], actual[i]);
+ }
+ } finally {
+ FileUtils.close(fin);
+ FileUtils.close(r);
+ FileUtils.close(utf8);
+ }
+ }
+
+ private void compareBytes(String s, String encoding) throws Exception {
+ byte[] expected = s.getBytes(encoding);
+
+ ReaderInputStream r = new ReaderInputStream(
+ new StringReader(s), encoding);
+ for (int i = 0; i < expected.length; ++i) {
+ int expect = expected[i] & 0xFF;
+ int read = r.read();
+ if (expect != read) {
+ fail("Mismatch in ReaderInputStream at index " + i
+ + " expecting " + expect + " got " + read + " for string "
+ + s + " with encoding " + encoding);
+ }
+ }
+ if (r.read() != -1) {
+ fail("Mismatch in ReaderInputStream - EOF not seen for string "
+ + s + " with encoding " + encoding);
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/ResourceUtilsTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/ResourceUtilsTest.java
new file mode 100644
index 00000000..96cc9cbf
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/ResourceUtilsTest.java
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.util;
+
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.Echo;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.ResourceFactory;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * Tests for org.apache.tools.ant.util.ResourceUtils.
+ */
+public class ResourceUtilsTest implements ResourceFactory, FileNameMapper {
+
+ private Echo taskINeedForLogging = new Echo();
+
+ @Before
+ public void setUp() {
+ taskINeedForLogging.setProject(new Project());
+ }
+
+ @Test
+ public void testNoDuplicates() {
+ Resource r = new Resource("samual vimes", true, 1, false);
+ Resource[] toNew =
+ ResourceUtils.selectOutOfDateSources(taskINeedForLogging,
+ new Resource[] {r},
+ this, this);
+ assertEquals(1, toNew.length);
+ }
+
+ /* ============ ResourceFactory interface ====================== */
+ public Resource getResource(String name) {
+ return new Resource(name); // implies lastModified == 0
+ }
+
+ /* ============ FileNameMapper interface ======================= */
+ public void setFrom(String s) {}
+ public void setTo(String s) {}
+ public String[] mapFileName(String s) {
+ return new String[] {"fred colon", "carrot ironfoundersson"};
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/StringUtilsTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/StringUtilsTest.java
new file mode 100644
index 00000000..53ef1b29
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/StringUtilsTest.java
@@ -0,0 +1,170 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.util;
+
+import java.util.Vector;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Test for StringUtils
+ */
+public class StringUtilsTest {
+
+ @Test
+ public void testSplit(){
+ final String data = "a,b,,";
+ Vector res = StringUtils.split(data, ',');
+ assertEquals(4, res.size());
+ assertEquals("a", res.elementAt(0));
+ assertEquals("b", res.elementAt(1));
+ assertEquals("", res.elementAt(2));
+ assertEquals("", res.elementAt(3));
+ }
+
+ @Test
+ public void testSplitLines(){
+ final String data = "a\r\nb\nc\nd\ne";
+ Vector res = StringUtils.lineSplit(data);
+ assertEquals(5, res.size());
+ assertEquals("a\r", res.elementAt(0));
+ assertEquals("b", res.elementAt(1));
+ assertEquals("c", res.elementAt(2));
+ assertEquals("d", res.elementAt(3));
+ assertEquals("e", res.elementAt(4));
+ }
+
+ @Test
+ public void testReplace() {
+ final String data = "abcabcabca";
+ String res = StringUtils.replace(data, "a", "");
+ assertEquals("bcbcbc", res);
+ }
+
+ @Test
+ public void testEndsWithBothEmpty() {
+ assertTrue( StringUtils.endsWith( new StringBuffer(), "") );
+ }
+
+ @Test
+ public void testEndsWithEmptyString() {
+ assertTrue( StringUtils.endsWith( new StringBuffer("12234545"), "") );
+ }
+
+ @Test
+ public void testEndsWithShorterString() {
+ assertTrue( StringUtils.endsWith( new StringBuffer("12345678"), "78"));
+ }
+
+ @Test
+ public void testEndsWithSameString() {
+ assertTrue( StringUtils.endsWith( new StringBuffer("123"), "123"));
+ }
+
+ @Test
+ public void testEndsWithLongerString() {
+ assertFalse( StringUtils.endsWith( new StringBuffer("12"), "1245"));
+ }
+
+ @Test
+ public void testEndsWithNoMatch() {
+ assertFalse( StringUtils.endsWith( new StringBuffer("12345678"), "789"));
+ }
+
+ @Test
+ public void testEndsWithEmptyBuffer() {
+ assertFalse( StringUtils.endsWith( new StringBuffer(""), "12345667") );
+ }
+
+ @Test
+ public void testEndsWithJDKPerf() {
+ StringBuffer buf = getFilledBuffer(1024*300, 'a');
+ for (int i = 0; i < 1000; i++) {
+ assertTrue(buf.toString().endsWith("aa"));
+ }
+ }
+
+ @Test
+ public void testEndsWithPerf() {
+ StringBuffer buf = getFilledBuffer(1024*300, 'a');
+ for (int i = 0; i < 1000; i++) {
+ assertTrue(StringUtils.endsWith(buf, "aa"));
+ }
+ }
+
+ private StringBuffer getFilledBuffer(int size, char ch) {
+ StringBuffer buf = new StringBuffer(size);
+ for (int i = 0; i < size; i++) { buf.append(ch); };
+ return buf;
+ }
+
+ @Test
+ public void testParseHumanSizes() throws Exception {
+ final long KILOBYTE = 1024;
+ final long MEGABYTE = KILOBYTE * 1024;
+ final long GIGABYTE = MEGABYTE * 1024;
+ final long TERABYTE = GIGABYTE * 1024;
+ final long PETABYTE = TERABYTE * 1024;
+ assertEquals(StringUtils.parseHumanSizes("1K"), KILOBYTE);
+ assertEquals(StringUtils.parseHumanSizes("1M"), MEGABYTE);
+ assertEquals(StringUtils.parseHumanSizes("1G"), GIGABYTE);
+ assertEquals(StringUtils.parseHumanSizes("1T"), TERABYTE);
+ assertEquals(StringUtils.parseHumanSizes("1P"), PETABYTE);
+ assertEquals(StringUtils.parseHumanSizes("1"), 1L);
+ }
+
+ @Test
+ public void testRemoveSuffix() {
+ String prefix = "Prefix";
+ String name = "Name";
+ String suffix = "Suffix";
+ String input = prefix + name + suffix;
+ assertEquals(
+ "Does not remove the suffix right.",
+ prefix + name,
+ StringUtils.removeSuffix(input, suffix)
+ );
+ assertEquals(
+ "Should leave the string unattended.",
+ prefix + name + suffix,
+ StringUtils.removeSuffix(input, "bla")
+ );
+ }
+
+ @Test
+ public void testRemovePrefix() {
+ String prefix = "Prefix";
+ String name = "Name";
+ String suffix = "Suffix";
+ String input = prefix + name + suffix;
+ assertEquals(
+ "Does not remove the prefix right.",
+ name + suffix,
+ StringUtils.removePrefix(input, prefix)
+ );
+ assertEquals(
+ "Should leave the string unattended.",
+ prefix + name + suffix,
+ StringUtils.removePrefix(input, "bla")
+ );
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/SymlinkUtilsTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/SymlinkUtilsTest.java
new file mode 100644
index 00000000..d1de1b1a
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/SymlinkUtilsTest.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.util;
+
+import static org.junit.Assert.assertFalse;
+
+import java.io.IOException;
+
+import org.apache.tools.ant.taskdefs.condition.Os;
+import org.junit.Assume;
+import org.junit.Test;
+
+public class SymlinkUtilsTest {
+
+ private static final SymbolicLinkUtils SYMLINK_UTILS =
+ SymbolicLinkUtils.getSymbolicLinkUtils();
+
+ @Test
+ public void testRootIsNoSymlink() throws IOException {
+ Assume.assumeFalse("Symlink doesn't work on Windows", Os.isFamily("windows"));
+ assertFalse(SYMLINK_UTILS.isSymbolicLink("/"));
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/UnPackageNameMapperTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/UnPackageNameMapperTest.java
new file mode 100644
index 00000000..7586950d
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/UnPackageNameMapperTest.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.util;
+
+import java.io.File;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class UnPackageNameMapperTest {
+
+ @Test
+ public void testMapping() {
+ UnPackageNameMapper mapper = new UnPackageNameMapper();
+ mapper.setFrom("TEST-*.xml");
+ mapper.setTo("*.java");
+ String file ="TEST-org.apache.tools.ant.util.UnPackageNameMapperTest.xml";
+ String result = mapper.mapFileName(file)[0];
+ String expected = fixupPath("org/apache/tools/ant/util/UnPackageNameMapperTest.java");
+
+ assertEquals(expected, result);
+ }
+
+ private String fixupPath(String file) {
+ return file.replace('/', File.separatorChar);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/UnicodeUtilTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/UnicodeUtilTest.java
new file mode 100644
index 00000000..090da569
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/UnicodeUtilTest.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.util;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class UnicodeUtilTest {
+
+ @Test
+ public void testChineseWord() {
+ String word = "\u81ea\u7531";
+ assertEquals("u81ea", UnicodeUtil.EscapeUnicode(word.charAt(0)).toString());
+ assertEquals("u7531", UnicodeUtil.EscapeUnicode(word.charAt(1)).toString());
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/VectorSetTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/VectorSetTest.java
new file mode 100644
index 00000000..11491e3a
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/VectorSetTest.java
@@ -0,0 +1,295 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.util;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+public class VectorSetTest {
+
+ private static final Object O = new Object();
+ private VectorSet v = new VectorSet();
+
+ @Test
+ public void testAdd() {
+ assertTrue(v.add(O));
+ assertFalse(v.add(O));
+ assertEquals(1, v.size());
+ }
+
+ @Test
+ public void testAdd2() {
+ v.add(0, O);
+ v.add(1, O);
+ assertEquals(1, v.size());
+ }
+
+ @Test
+ public void testAddElement() {
+ v.addElement(O);
+ v.addElement(O);
+ assertEquals(1, v.size());
+ }
+
+ @Test
+ public void testAddAll() {
+ assertTrue(v.addAll(Arrays.asList(new Object[] {O, O})));
+ assertEquals(1, v.size());
+ }
+
+ @Test
+ public void testAddAll2() {
+ assertTrue(v.addAll(0, Arrays.asList(new Object[] {O, O})));
+ assertEquals(1, v.size());
+ }
+
+ @Test
+ public void testClear() {
+ v.add(O);
+ v.clear();
+ assertEquals(0, v.size());
+ }
+
+ @Test
+ public void testClone() {
+ v.add(O);
+ Object o = v.clone();
+ assertTrue(o instanceof VectorSet);
+ VectorSet vs = (VectorSet) o;
+ assertEquals(1, vs.size());
+ assertTrue(vs.contains(O));
+ }
+
+ @Test
+ public void testContains() {
+ assertFalse(v.contains(O));
+ v.add(O);
+ assertTrue(v.contains(O));
+ assertFalse(v.contains(null));
+ }
+
+ @Test
+ public void testContainsAll() {
+ assertFalse(v.containsAll(Arrays.asList(new Object[] {O, O})));
+ v.add(O);
+ assertTrue(v.containsAll(Arrays.asList(new Object[] {O, O})));
+ assertFalse(v.containsAll(Arrays.asList(new Object[] {O, null})));
+ }
+
+ @Test
+ public void testInsertElementAt() {
+ v.insertElementAt(O, 0);
+ v.insertElementAt(O, 1);
+ assertEquals(1, v.size());
+ }
+
+ @Test
+ public void testRemoveIndex() {
+ v.add(O);
+ assertSame(O, v.remove(0));
+ assertEquals(0, v.size());
+ try {
+ v.remove(0);
+ fail("expected an AIOBE");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ //TODO assert exception values
+ // expected
+ }
+ }
+
+ @Test
+ public void testRemoveObject() {
+ v.add(O);
+ assertTrue(v.remove(O));
+ assertEquals(0, v.size());
+ assertFalse(v.remove(O));
+ }
+
+ @Test
+ public void testRemoveAtEndWhenSizeEqualsCapacity() {
+ v = new VectorSet(3, 1);
+ Object a = new Object();
+ v.add(a);
+ Object b = new Object();
+ v.add(b);
+ v.add(O);
+ assertEquals(3, v.size());
+ assertEquals(3, v.capacity());
+ assertTrue(v.remove(O));
+ assertEquals(2, v.size());
+ assertFalse(v.remove(O));
+ assertSame(a, v.elementAt(0));
+ assertSame(b, v.elementAt(1));
+ }
+
+ @Test
+ public void testRemoveAtFrontWhenSizeEqualsCapacity() {
+ v = new VectorSet(3, 1);
+ v.add(O);
+ Object a = new Object();
+ v.add(a);
+ Object b = new Object();
+ v.add(b);
+ assertEquals(3, v.size());
+ assertEquals(3, v.capacity());
+ assertTrue(v.remove(O));
+ assertEquals(2, v.size());
+ assertFalse(v.remove(O));
+ assertSame(a, v.elementAt(0));
+ assertSame(b, v.elementAt(1));
+ }
+
+ @Test
+ public void testRemoveInMiddleWhenSizeEqualsCapacity() {
+ v = new VectorSet(3, 1);
+ Object a = new Object();
+ v.add(a);
+ v.add(O);
+ Object b = new Object();
+ v.add(b);
+ assertEquals(3, v.size());
+ assertEquals(3, v.capacity());
+ assertTrue(v.remove(O));
+ assertEquals(2, v.size());
+ assertFalse(v.remove(O));
+ assertSame(a, v.elementAt(0));
+ assertSame(b, v.elementAt(1));
+ }
+
+ @Test
+ public void testRemoveAll() {
+ v.add(O);
+ assertTrue(v.removeAll(Arrays.asList(new Object[] {O, O})));
+ assertEquals(0, v.size());
+ assertFalse(v.removeAll(Arrays.asList(new Object[] {O, O})));
+ }
+
+ @Test
+ public void testRemoveAllElements() {
+ v.add(O);
+ v.removeAllElements();
+ assertEquals(0, v.size());
+ }
+
+ @Test
+ public void testRemoveElement() {
+ v.add(O);
+ assertTrue(v.removeElement(O));
+ assertEquals(0, v.size());
+ assertFalse(v.removeElement(O));
+ }
+
+ @Test
+ public void testRemoveElementAt() {
+ v.add(O);
+ v.removeElementAt(0);
+ assertEquals(0, v.size());
+ try {
+ v.removeElementAt(0);
+ fail("expected an AIOBE");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ //TODO assert exception values
+ // expected
+ }
+ }
+
+ @Test
+ public void testRemoveRange() {
+ Object a = new Object();
+ Object b = new Object();
+ Object c = new Object();
+ v.addAll(Arrays.asList(new Object[] {O, a, b, c}));
+ v.removeRange(1, 3);
+ assertEquals(2, v.size());
+ assertTrue(v.contains(O));
+ assertTrue(v.contains(c));
+ }
+
+ @Test
+ public void testRetainAll() {
+ Object a = new Object();
+ Object b = new Object();
+ Object c = new Object();
+ v.addAll(Arrays.asList(new Object[] {O, a, b, c}));
+ assertEquals(0, v.indexOf(O));
+ assertTrue(v.retainAll(Arrays.asList(new Object[] {c, O})));
+ assertEquals(2, v.size());
+ assertTrue(v.contains(O));
+ assertTrue(v.contains(c));
+ assertEquals(0, v.indexOf(O));
+ }
+
+ @Test
+ public void testRetainAllReturnValueAndEmptiness() {
+ v.add(1);
+ v.add(2);
+ v.add(3);
+ assertTrue(v.retainAll(Arrays.asList(1, 2)));
+ assertEquals(2, v.size());
+ assertFalse(v.retainAll(Arrays.asList(1, 2)));
+ assertEquals(2, v.size());
+ assertTrue(v.retainAll(Arrays.asList(4, 5)));
+ assertEquals(0, v.size());
+ assertFalse(v.retainAll(Arrays.asList(4, 5)));
+ }
+
+ @Test
+ public void testSet() {
+ v.add(O);
+ Object a = new Object();
+ assertSame(O, v.set(0, a));
+ assertSame(a, v.get(0));
+ assertEquals(1, v.size());
+ }
+
+ @Test
+ public void testSetElementAt() {
+ v.add(O);
+ Object a = new Object();
+ v.setElementAt(a, 0);
+ assertSame(a, v.get(0));
+ assertEquals(1, v.size());
+ }
+
+ @Test
+ public void testRetainAllSpeed() {
+ int size = 50000;
+ for (int i = 0; i < size; i++) {
+ v.add(i);
+ v.add(i);
+ }
+ assertEquals(size, v.size());
+ ArrayList<Integer> list = new ArrayList<Integer>();
+ for (int i = size - 4; i < 2 * size; i++) {
+ list.add(i);
+ v.add(i);
+ }
+ assertTrue(v.retainAll(list));
+ assertEquals(v.toString(), size + 4, v.size());
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/XMLFragmentTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/XMLFragmentTest.java
new file mode 100644
index 00000000..0ac938f0
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/XMLFragmentTest.java
@@ -0,0 +1,91 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.util;
+
+import org.apache.tools.ant.BuildFileRule;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+public class XMLFragmentTest {
+
+ @Rule
+ public BuildFileRule buildRule = new BuildFileRule();
+
+ @Before
+ public void setUp() {
+ buildRule.configureProject("src/etc/testcases/types/xmlfragment.xml");
+ }
+
+ @Test
+ public void testNestedText() {
+ XMLFragment x = (XMLFragment) buildRule.getProject().getReference("nested-text");
+ assertNotNull(x);
+ Node n = x.getFragment();
+ assertTrue("No attributes", !n.hasAttributes());
+ NodeList nl = n.getChildNodes();
+ assertEquals(1, nl.getLength());
+ assertEquals(Node.TEXT_NODE, nl.item(0).getNodeType());
+ assertEquals("foo", nl.item(0).getNodeValue());
+ }
+
+ @Test
+ public void testNestedChildren() {
+ XMLFragment x =
+ (XMLFragment) buildRule.getProject().getReference("with-children");
+ assertNotNull(x);
+ Node n = x.getFragment();
+ assertTrue("No attributes", !n.hasAttributes());
+ NodeList nl = n.getChildNodes();
+ assertEquals(3, nl.getLength());
+
+ assertEquals(Node.ELEMENT_NODE, nl.item(0).getNodeType());
+ Element child1 = (Element) nl.item(0);
+ assertEquals("child1", child1.getTagName());
+ assertTrue(!child1.hasAttributes());
+ NodeList nl2 = child1.getChildNodes();
+ assertEquals(1, nl2.getLength());
+ assertEquals(Node.TEXT_NODE, nl2.item(0).getNodeType());
+ assertEquals("foo", nl2.item(0).getNodeValue());
+
+ assertEquals(Node.ELEMENT_NODE, nl.item(1).getNodeType());
+ Element child2 = (Element) nl.item(1);
+ assertEquals("child2", child2.getTagName());
+ assertTrue(child2.hasAttributes());
+ nl2 = child2.getChildNodes();
+ assertEquals(0, nl2.getLength());
+ assertEquals("bar", child2.getAttribute("foo"));
+
+ assertEquals(Node.ELEMENT_NODE, nl.item(2).getNodeType());
+ Element child3 = (Element) nl.item(2);
+ assertEquals("child3", child3.getTagName());
+ assertTrue(!child3.hasAttributes());
+ nl2 = child3.getChildNodes();
+ assertEquals(1, nl2.getLength());
+ assertEquals(Node.ELEMENT_NODE, nl2.item(0).getNodeType());
+ assertEquals("child4", ((Element) nl2.item(0)).getTagName());
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/facade/FacadeTaskHelperTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/facade/FacadeTaskHelperTest.java
new file mode 100644
index 00000000..df2d43b3
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/facade/FacadeTaskHelperTest.java
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.util.facade;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * @since Ant 1.5
+ */
+public class FacadeTaskHelperTest {
+
+ @Test
+ public void testPrecedenceRules() {
+ FacadeTaskHelper fth = new FacadeTaskHelper("foo");
+ assertEquals("foo", fth.getImplementation());
+
+ fth.setMagicValue("bar");
+ assertEquals("bar", fth.getImplementation());
+
+ fth = new FacadeTaskHelper("foo", "bar");
+ assertEquals("bar", fth.getImplementation());
+
+ fth = new FacadeTaskHelper("foo", null);
+ assertEquals("foo", fth.getImplementation());
+
+ fth = new FacadeTaskHelper("foo");
+ fth.setMagicValue("bar");
+ fth.setImplementation("baz");
+ assertEquals("baz", fth.getImplementation());
+ }
+
+ @Test
+ public void testHasBeenSet() {
+ FacadeTaskHelper fth = new FacadeTaskHelper("foo");
+ assertTrue("nothing set", !fth.hasBeenSet());
+ fth.setMagicValue(null);
+ assertTrue("magic has not been set", !fth.hasBeenSet());
+ fth.setMagicValue("foo");
+ assertTrue("magic has been set", fth.hasBeenSet());
+ fth.setMagicValue(null);
+ assertTrue(!fth.hasBeenSet());
+ fth.setImplementation("baz");
+ assertTrue("set explicitly", fth.hasBeenSet());
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/facade/ImplementationSpecificArgumentTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/facade/ImplementationSpecificArgumentTest.java
new file mode 100644
index 00000000..a1b97d1d
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/facade/ImplementationSpecificArgumentTest.java
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.util.facade;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+/**
+ * @since Ant 1.5
+ */
+public class ImplementationSpecificArgumentTest {
+
+ @Test
+ public void testDependsOnImplementation() {
+ ImplementationSpecificArgument ia =
+ new ImplementationSpecificArgument();
+ ia.setLine("A B");
+ String[] parts = ia.getParts();
+ assertNotNull(parts);
+ assertEquals(2, parts.length);
+ assertEquals("A", parts[0]);
+ assertEquals("B", parts[1]);
+
+ parts = ia.getParts(null);
+ assertNotNull(parts);
+ assertEquals(2, parts.length);
+ assertEquals("A", parts[0]);
+ assertEquals("B", parts[1]);
+
+ ia.setImplementation("foo");
+ parts = ia.getParts(null);
+ assertNotNull(parts);
+ assertEquals(0, parts.length);
+
+ parts = ia.getParts("foo");
+ assertNotNull(parts);
+ assertEquals(2, parts.length);
+ assertEquals("A", parts[0]);
+ assertEquals("B", parts[1]);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/regexp/JakartaOroMatcherTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/regexp/JakartaOroMatcherTest.java
new file mode 100644
index 00000000..d1405f4a
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/regexp/JakartaOroMatcherTest.java
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.util.regexp;
+
+/**
+ * Tests for the jakarta-oro implementation of the RegexpMatcher interface.
+ *
+ */
+public class JakartaOroMatcherTest extends RegexpMatcherTest {
+
+ public RegexpMatcher getImplementation() {
+ return new JakartaOroMatcher();
+ }
+
+ public JakartaOroMatcherTest(String name) {
+ super(name);
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/regexp/JakartaOroRegexpTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/regexp/JakartaOroRegexpTest.java
new file mode 100644
index 00000000..e869c62e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/regexp/JakartaOroRegexpTest.java
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.util.regexp;
+
+/**
+ * Tests for the jakarta-oro implementation of the Regexp interface.
+ *
+ */
+public class JakartaOroRegexpTest extends RegexpTest {
+
+ public Regexp getRegexpImplementation() {
+ return new JakartaOroRegexp();
+ }
+
+ public JakartaOroRegexpTest(String name) {
+ super(name);
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/regexp/JakartaRegexpMatcherTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/regexp/JakartaRegexpMatcherTest.java
new file mode 100644
index 00000000..3340b59c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/regexp/JakartaRegexpMatcherTest.java
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.util.regexp;
+
+import java.io.IOException;
+
+import junit.framework.AssertionFailedError;
+
+/**
+ * Tests for the jakarta-regexp implementation of the RegexpMatcher interface.
+ *
+ */
+public class JakartaRegexpMatcherTest extends RegexpMatcherTest {
+
+ public RegexpMatcher getImplementation() {
+ return new JakartaRegexpMatcher();
+ }
+
+ public JakartaRegexpMatcherTest(String name) {
+ super(name);
+ }
+
+ public void testWindowsLineSeparator2() throws IOException {
+ try {
+ super.testWindowsLineSeparator2();
+ fail("Should trigger when this bug is fixed. {@since 1.2}");
+ } catch (AssertionFailedError e) {
+ }
+ }
+
+ /**
+ * Fails for the same reason as "default" mode in doEndTest2.
+ */
+ public void testUnixLineSeparator() throws IOException {
+ try {
+ super.testUnixLineSeparator();
+ fail("Should trigger once this bug is fixed. {@since 1.2}");
+ } catch (AssertionFailedError e) {
+ }
+ }
+
+
+ /**
+ * Fails for "default" mode.
+ */
+ protected void doEndTest2(String text) {}
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/regexp/JakartaRegexpRegexpTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/regexp/JakartaRegexpRegexpTest.java
new file mode 100644
index 00000000..078fbb1b
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/regexp/JakartaRegexpRegexpTest.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.util.regexp;
+
+import java.io.IOException;
+
+import junit.framework.AssertionFailedError;
+
+/**
+ * Tests for the jakarta-regexp implementation of the Regexp interface.
+ *
+ */
+public class JakartaRegexpRegexpTest extends RegexpTest {
+
+ public Regexp getRegexpImplementation() {
+ return new JakartaRegexpRegexp();
+ }
+
+ public JakartaRegexpRegexpTest(String name) {
+ super(name);
+ }
+
+ public void testWindowsLineSeparator2() throws IOException {
+ try {
+ super.testWindowsLineSeparator2();
+ fail("Should trigger when this bug is fixed. {@since 1.2}");
+ } catch (AssertionFailedError e){
+ }
+ }
+
+ /**
+ * Fails for the same reason as "default" mode in doEndTest2.
+ */
+ public void testUnixLineSeparator() throws IOException {
+ try {
+ super.testUnixLineSeparator();
+ fail("Should trigger once this bug is fixed. {@since 1.2}");
+ } catch (AssertionFailedError e){
+ }
+ }
+
+ /**
+ * Fails for "default" mode.
+ */
+ protected void doEndTest2(String text) {}
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/regexp/Jdk14RegexpMatcherTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/regexp/Jdk14RegexpMatcherTest.java
new file mode 100644
index 00000000..c042e715
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/regexp/Jdk14RegexpMatcherTest.java
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.util.regexp;
+
+import java.io.IOException;
+
+import junit.framework.AssertionFailedError;
+
+/**
+ * Tests for the JDK 1.4 implementation of the RegexpMatcher interface.
+ *
+ */
+public class Jdk14RegexpMatcherTest extends RegexpMatcherTest {
+
+ public RegexpMatcher getImplementation() {
+ return new Jdk14RegexpMatcher();
+ }
+
+ public Jdk14RegexpMatcherTest(String name) {
+ super(name);
+ }
+
+ public void testParagraphCharacter() throws IOException {
+ try {
+ super.testParagraphCharacter();
+ fail("Should trigger once fixed. {@since JDK 1.4RC1}");
+ } catch (AssertionFailedError e){
+ }
+ }
+
+ public void testLineSeparatorCharacter() throws IOException {
+ try {
+ super.testLineSeparatorCharacter();
+ fail("Should trigger once fixed. {@since JDK 1.4RC1}");
+ } catch (AssertionFailedError e){
+ }
+ }
+
+ public void testStandaloneCR() throws IOException {
+ try {
+ super.testStandaloneCR();
+ fail("Should trigger once fixed. {@since JDK 1.4RC1}");
+ } catch (AssertionFailedError e){
+ }
+ }
+
+ public void testWindowsLineSeparator() throws IOException {
+ try {
+ super.testWindowsLineSeparator();
+ fail("Should trigger once fixed. {@since JDK 1.4RC1}");
+ } catch (AssertionFailedError e){
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/regexp/Jdk14RegexpRegexpTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/regexp/Jdk14RegexpRegexpTest.java
new file mode 100644
index 00000000..2b60406a
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/regexp/Jdk14RegexpRegexpTest.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.util.regexp;
+
+import java.io.IOException;
+
+import junit.framework.AssertionFailedError;
+
+/**
+ * Tests for the JDK 1.4 implementation of the Regexp interface.
+ *
+ */
+public class Jdk14RegexpRegexpTest extends RegexpTest {
+
+ public Regexp getRegexpImplementation() {
+ return new Jdk14RegexpRegexp();
+ }
+
+ public Jdk14RegexpRegexpTest(String name) {
+ super(name);
+ }
+
+ public void testParagraphCharacter() throws IOException {
+ try {
+ super.testParagraphCharacter();
+ fail("Should trigger once fixed. {@since JDK 1.4RC1}");
+ } catch (AssertionFailedError e){
+ }
+ }
+
+ public void testLineSeparatorCharacter() throws IOException {
+ try {
+ super.testLineSeparatorCharacter();
+ fail("Should trigger once fixed. {@since JDK 1.4RC1}");
+ } catch (AssertionFailedError e){
+ }
+ }
+
+ public void testStandaloneCR() throws IOException {
+ try {
+ super.testStandaloneCR();
+ fail("Should trigger once fixed. {@since JDK 1.4RC1}");
+ } catch (AssertionFailedError e){
+ }
+ }
+
+ public void testWindowsLineSeparator() throws IOException {
+ try {
+ super.testWindowsLineSeparator();
+ fail("Should trigger once fixed. {@since JDK 1.4RC1}");
+ } catch (AssertionFailedError e){
+ }
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/regexp/RegexpMatcherTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/regexp/RegexpMatcherTest.java
new file mode 100644
index 00000000..09508274
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/regexp/RegexpMatcherTest.java
@@ -0,0 +1,204 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.util.regexp;
+
+import java.io.IOException;
+import java.util.Vector;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests for all implementations of the RegexpMatcher interface.
+ *
+ */
+public abstract class RegexpMatcherTest extends TestCase {
+
+ public final static String UNIX_LINE = "\n";
+
+ private RegexpMatcher reg;
+
+ public abstract RegexpMatcher getImplementation();
+
+ protected final RegexpMatcher getReg() {return reg;}
+
+ public RegexpMatcherTest(String name) {
+ super(name);
+ }
+
+ public void setUp() {
+ reg = getImplementation();
+ }
+
+ public void testMatches() {
+ reg.setPattern("aaaa");
+ assertTrue("aaaa should match itself", reg.matches("aaaa"));
+ assertTrue("aaaa should match xaaaa", reg.matches("xaaaa"));
+ assertTrue("aaaa shouldn\'t match xaaa", !reg.matches("xaaa"));
+ reg.setPattern("^aaaa");
+ assertTrue("^aaaa shouldn\'t match xaaaa", !reg.matches("xaaaa"));
+ assertTrue("^aaaa should match aaaax", reg.matches("aaaax"));
+ reg.setPattern("aaaa$");
+ assertTrue("aaaa$ shouldn\'t match aaaax", !reg.matches("aaaax"));
+ assertTrue("aaaa$ should match xaaaa", reg.matches("xaaaa"));
+ reg.setPattern("[0-9]+");
+ assertTrue("[0-9]+ should match 123", reg.matches("123"));
+ assertTrue("[0-9]+ should match 1", reg.matches("1"));
+ assertTrue("[0-9]+ shouldn\'t match \'\'", !reg.matches(""));
+ assertTrue("[0-9]+ shouldn\'t match a", !reg.matches("a"));
+ reg.setPattern("[0-9]*");
+ assertTrue("[0-9]* should match 123", reg.matches("123"));
+ assertTrue("[0-9]* should match 1", reg.matches("1"));
+ assertTrue("[0-9]* should match \'\'", reg.matches(""));
+ assertTrue("[0-9]* should match a", reg.matches("a"));
+ reg.setPattern("([0-9]+)=\\1");
+ assertTrue("([0-9]+)=\\1 should match 1=1", reg.matches("1=1"));
+ assertTrue("([0-9]+)=\\1 shouldn\'t match 1=2", !reg.matches("1=2"));
+ }
+
+ public void testGroups() {
+ reg.setPattern("aaaa");
+ Vector v = reg.getGroups("xaaaa");
+ assertEquals("No parens -> no extra groups", 1, v.size());
+ assertEquals("Trivial match with no parens", "aaaa",
+ (String) v.elementAt(0));
+
+ reg.setPattern("(aaaa)");
+ v = reg.getGroups("xaaaa");
+ assertEquals("Trivial match with single paren", 2, v.size());
+ assertEquals("Trivial match with single paren, full match", "aaaa",
+ (String) v.elementAt(0));
+ assertEquals("Trivial match with single paren, matched paren", "aaaa",
+ (String) v.elementAt(0));
+
+ reg.setPattern("(a+)b(b+)");
+ v = reg.getGroups("xaabb");
+ assertEquals(3, v.size());
+ assertEquals("aabb", (String) v.elementAt(0));
+ assertEquals("aa", (String) v.elementAt(1));
+ assertEquals("b", (String) v.elementAt(2));
+ }
+
+ public void testBugzillaReport14619() {
+ reg.setPattern("^(.*)/src/((.*/)*)([a-zA-Z0-9_\\.]+)\\.java$");
+ Vector v = reg.getGroups("de/tom/src/Google.java");
+ assertEquals(5, v.size());
+ assertEquals("de/tom", v.elementAt(1));
+ assertEquals("", v.elementAt(2));
+ assertEquals("", v.elementAt(3));
+ assertEquals("Google", v.elementAt(4));
+ }
+
+ public void testCaseInsensitiveMatch() {
+ reg.setPattern("aaaa");
+ assertTrue("aaaa doesn't match AAaa", !reg.matches("AAaa"));
+ assertTrue("aaaa matches AAaa ignoring case",
+ reg.matches("AAaa", RegexpMatcher.MATCH_CASE_INSENSITIVE));
+ }
+
+
+// make sure there are no issues concerning line separator interpretation
+// a line separator for regex (perl) is always a unix line (ie \n)
+
+ public void testParagraphCharacter() throws IOException {
+ reg.setPattern("end of text$");
+ assertTrue("paragraph character", !reg.matches("end of text\u2029"));
+ }
+
+ public void testLineSeparatorCharacter() throws IOException {
+ reg.setPattern("end of text$");
+ assertTrue("line-separator character", !reg.matches("end of text\u2028"));
+ }
+
+ public void testNextLineCharacter() throws IOException {
+ reg.setPattern("end of text$");
+ assertTrue("next-line character", !reg.matches("end of text\u0085"));
+ }
+
+ public void testStandaloneCR() throws IOException {
+ reg.setPattern("end of text$");
+ assertTrue("standalone CR", !reg.matches("end of text\r"));
+ }
+
+ public void testWindowsLineSeparator() throws IOException {
+ reg.setPattern("end of text$");
+ assertTrue("Windows line separator", !reg.matches("end of text\r\n"));
+ }
+
+ public void testWindowsLineSeparator2() throws IOException {
+ reg.setPattern("end of text\r$");
+ assertTrue("Windows line separator", reg.matches("end of text\r\n"));
+ }
+
+ public void testUnixLineSeparator() throws IOException {
+ reg.setPattern("end of text$");
+ assertTrue("Unix line separator", reg.matches("end of text\n"));
+ }
+
+
+ public void testMultiVersusSingleLine() throws IOException {
+ StringBuffer buf = new StringBuffer();
+ buf.append("Line1").append(UNIX_LINE);
+ buf.append("starttest Line2").append(UNIX_LINE);
+ buf.append("Line3 endtest").append(UNIX_LINE);
+ buf.append("Line4").append(UNIX_LINE);
+ String text = buf.toString();
+
+ doStartTest1(text);
+ doStartTest2(text);
+ doEndTest1(text);
+ doEndTest2(text);
+ }
+
+ protected void doStartTest1(String text) {
+ reg.setPattern("^starttest");
+ assertTrue("^starttest in default mode", !reg.matches(text));
+ assertTrue("^starttest in single line mode",
+ !reg.matches(text, RegexpMatcher.MATCH_SINGLELINE));
+ assertTrue("^starttest in multi line mode",
+ reg.matches(text, RegexpMatcher.MATCH_MULTILINE));
+ }
+
+ protected void doStartTest2(String text) {
+ reg.setPattern("^Line1");
+ assertTrue("^Line1 in default mode", reg.matches(text));
+ assertTrue("^Line1 in single line mode",
+ reg.matches(text, RegexpMatcher.MATCH_SINGLELINE));
+ assertTrue("^Line1 in multi line mode",
+ reg.matches(text, RegexpMatcher.MATCH_MULTILINE));
+ }
+
+ protected void doEndTest1(String text) {
+ reg.setPattern("endtest$");
+ assertTrue("endtest$ in default mode", !reg.matches(text));
+ assertTrue("endtest$ in single line mode",
+ !reg.matches(text, RegexpMatcher.MATCH_SINGLELINE));
+ assertTrue("endtest$ in multi line mode",
+ reg.matches(text, RegexpMatcher.MATCH_MULTILINE));
+ }
+
+ protected void doEndTest2(String text) {
+ reg.setPattern("Line4$");
+ assertTrue("Line4$ in default mode", reg.matches(text));
+ assertTrue("Line4$ in single line mode",
+ reg.matches(text, RegexpMatcher.MATCH_SINGLELINE));
+ assertTrue("Line4$ in multi line mode",
+ reg.matches(text, RegexpMatcher.MATCH_MULTILINE));
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/regexp/RegexpTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/regexp/RegexpTest.java
new file mode 100644
index 00000000..5cfe8c97
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/ant/util/regexp/RegexpTest.java
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.util.regexp;
+
+/**
+ * Tests for all implementations of the Regexp interface.
+ *
+ */
+public abstract class RegexpTest extends RegexpMatcherTest {
+
+ private static final String test = "abcdefg-abcdefg";
+ private static final String pattern = "ab([^d]*)d([^f]*)f";
+
+ public RegexpTest(String name) {
+ super(name);
+ }
+
+ public final RegexpMatcher getImplementation() {
+ return getRegexpImplementation();
+ }
+
+ public abstract Regexp getRegexpImplementation();
+
+ public void testSubstitution() {
+ Regexp reg = (Regexp) getReg();
+ reg.setPattern(pattern);
+ assertTrue(reg.matches(test));
+ assertEquals("abedcfg-abcdefg", reg.substitute(test, "ab\\2d\\1f",
+ Regexp.MATCH_DEFAULT));
+ }
+
+ public void testReplaceFirstSubstitution() {
+ Regexp reg = (Regexp) getReg();
+ reg.setPattern(pattern);
+ assertTrue(reg.matches(test));
+ assertEquals("abedcfg-abcdefg", reg.substitute(test, "ab\\2d\\1f",
+ Regexp.REPLACE_FIRST));
+ }
+
+ public void testReplaceAllSubstitution() {
+ Regexp reg = (Regexp) getReg();
+ reg.setPattern(pattern);
+ assertTrue(reg.matches(test));
+ assertEquals("abedcfg-abedcfg", reg.substitute(test, "ab\\2d\\1f",
+ Regexp.REPLACE_ALL));
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/bzip2/BlockSortTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/bzip2/BlockSortTest.java
new file mode 100644
index 00000000..12b871ed
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/bzip2/BlockSortTest.java
@@ -0,0 +1,171 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tools.bzip2;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+
+public class BlockSortTest {
+
+ private static final byte[] FIXTURE = { 0, 1, (byte) 252, (byte) 253, (byte) 255,
+ (byte) 254, 3, 2, (byte) 128 };
+
+ /*
+ Burrows-Wheeler transform of fixture the manual way:
+
+ * build the matrix
+
+ 0, 1, 252, 253, 255, 254, 3, 2, 128
+ 1, 252, 253, 255, 254, 3, 2, 128, 0
+ 252, 253, 255, 254, 3, 2, 128, 0, 1
+ 253, 255, 254, 3, 2, 128, 0, 1, 252
+ 255, 254, 3, 2, 128, 0, 1, 252, 253
+ 254, 3, 2, 128, 0, 1, 252, 253, 255
+ 3, 2, 128, 0, 1, 252, 253, 255, 254
+ 2, 128, 0, 1, 252, 253, 255, 254, 3
+ 128, 0, 1, 252, 253, 255, 254, 3, 2
+
+ * sort it
+
+ 0, 1, 252, 253, 255, 254, 3, 2, 128
+ 1, 252, 253, 255, 254, 3, 2, 128, 0
+ 2, 128, 0, 1, 252, 253, 255, 254, 3
+ 3, 2, 128, 0, 1, 252, 253, 255, 254
+ 128, 0, 1, 252, 253, 255, 254, 3, 2
+ 252, 253, 255, 254, 3, 2, 128, 0, 1
+ 253, 255, 254, 3, 2, 128, 0, 1, 252
+ 254, 3, 2, 128, 0, 1, 252, 253, 255
+ 255, 254, 3, 2, 128, 0, 1, 252, 253
+
+ * grab last column
+
+ 128, 0, 3, 254, 2, 1, 252, 255, 253
+
+ and the original line has been 0
+ */
+
+ private static final byte[] FIXTURE_BWT = { (byte) 128, 0, 3, (byte) 254, 2, 1,
+ (byte) 252, (byte) 255, (byte) 253 };
+
+ private static final int[] FIXTURE_SORTED = {
+ 0, 1, 7, 6, 8, 2, 3, 5, 4
+ };
+
+ private static final byte[] FIXTURE2 = {
+ 'C', 'o', 'm', 'm', 'o', 'n', 's', ' ', 'C', 'o', 'm', 'p', 'r', 'e', 's', 's',
+ };
+
+ private static final byte[] FIXTURE2_BWT = {
+ 's', 's', ' ', 'r', 'o', 'm', 'o', 'o', 'C', 'C', 'm', 'm', 'p', 'n', 's', 'e',
+ };
+
+ @Test
+ public void testSortFixture() {
+ DS ds = setUpFixture();
+ ds.s.blockSort(ds.data, FIXTURE.length - 1);
+ assertFixtureSorted(ds.data);
+ assertEquals(0, ds.data.origPtr);
+ }
+
+ @Test
+ public void testSortFixtureMainSort() {
+ DS ds = setUpFixture();
+ ds.s.mainSort(ds.data, FIXTURE.length - 1);
+ assertFixtureSorted(ds.data);
+ }
+
+ @Test
+ public void testSortFixtureFallbackSort() {
+ DS ds = setUpFixture();
+ ds.s.fallbackSort(ds.data, FIXTURE.length - 1);
+ assertFixtureSorted(ds.data);
+ }
+
+ @Test
+ public void testSortFixture2() {
+ DS ds = setUpFixture2();
+ ds.s.blockSort(ds.data, FIXTURE2.length - 1);
+ assertFixture2Sorted(ds.data);
+ assertEquals(1, ds.data.origPtr);
+ }
+
+ @Test
+ public void testSortFixture2MainSort() {
+ DS ds = setUpFixture2();
+ ds.s.mainSort(ds.data, FIXTURE2.length - 1);
+ assertFixture2Sorted(ds.data);
+ }
+
+ @Test
+ public void testSortFixture2FallbackSort() {
+ DS ds = setUpFixture2();
+ ds.s.fallbackSort(ds.data, FIXTURE2.length - 1);
+ assertFixture2Sorted(ds.data);
+ }
+
+ @Test
+ public void testFallbackSort() {
+ CBZip2OutputStream.Data data = new CBZip2OutputStream.Data(1);
+ BlockSort s = new BlockSort(data);
+ int[] fmap = new int[FIXTURE.length];
+ s.fallbackSort(fmap, FIXTURE, FIXTURE.length);
+ assertArrayEquals(FIXTURE_SORTED, fmap);
+ }
+
+ private DS setUpFixture() {
+ return setUpFixture(FIXTURE);
+ }
+
+ private void assertFixtureSorted(CBZip2OutputStream.Data data) {
+ assertFixtureSorted(data, FIXTURE, FIXTURE_BWT);
+ }
+
+ private DS setUpFixture2() {
+ return setUpFixture(FIXTURE2);
+ }
+
+ private void assertFixture2Sorted(CBZip2OutputStream.Data data) {
+ assertFixtureSorted(data, FIXTURE2, FIXTURE2_BWT);
+ }
+
+ private DS setUpFixture(byte[] fixture) {
+ CBZip2OutputStream.Data data = new CBZip2OutputStream.Data(1);
+ System.arraycopy(fixture, 0, data.block, 1, fixture.length);
+ return new DS(data, new BlockSort(data));
+ }
+
+ private void assertFixtureSorted(CBZip2OutputStream.Data data,
+ byte[] fixture, byte[] fixtureBwt) {
+ assertEquals(fixture[fixture.length - 1], data.block[0]);
+ for (int i = 0; i < fixture.length; i++) {
+ assertEquals(fixtureBwt[i], data.block[data.fmap[i]]);
+ }
+ }
+
+ private static class DS {
+ private final CBZip2OutputStream.Data data;
+ private final BlockSort s;
+ DS(CBZip2OutputStream.Data data, BlockSort s) {
+ this.data = data;
+ this.s = s;
+ }
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/bzip2/CBZip2StreamTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/bzip2/CBZip2StreamTest.java
new file mode 100644
index 00000000..50e0e576
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/bzip2/CBZip2StreamTest.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.bzip2;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+import org.junit.Test;
+
+import static org.junit.Assert.fail;
+
+public class CBZip2StreamTest {
+
+ @Test
+ public void testNullPointer() throws IOException {
+ try {
+ new CBZip2InputStream(new ByteArrayInputStream(new byte[0]));
+ fail("expected an exception");
+ } catch (IOException e) {
+ // expected
+ //TODO assert exception values
+ }
+ }
+
+ @Test
+ public void testDivisionByZero() throws IOException {
+ CBZip2OutputStream cb = new CBZip2OutputStream(new ByteArrayOutputStream());
+ cb.close();
+ // expected no exception
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/mail/MailMessageTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/mail/MailMessageTest.java
new file mode 100644
index 00000000..87e2f754
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/mail/MailMessageTest.java
@@ -0,0 +1,707 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.mail;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.io.PrintStream;
+import java.net.InetAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildException;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.internal.AssumptionViolatedException;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+
+/**
+ * JUnit testcases for org.apache.tools.mail.MailMessage.
+ *
+ * @since Ant 1.6
+ */
+public class MailMessageTest {
+
+ // 27224 = magic (a random port which is unlikely to be in use)
+ private static int TEST_PORT = 27224;
+
+ private String local = null;
+
+ @Before
+ public void setUp() {
+ try {
+ local = InetAddress.getLocalHost().getHostName();
+ } catch (java.net.UnknownHostException uhe) {
+ // ignore
+ }
+ }
+
+ /**
+ * Test an example that is similar to the one given in the API
+ * If this testcase takes >90s to complete, it is very likely that
+ * the two threads are blocked waiting for each other and Thread.join()
+ * timed out.
+ * @throws InterruptedException
+ */
+ @Test
+ public void testAPIExample() throws InterruptedException {
+
+ ServerThread testMailServer = new ServerThread();
+ Thread server = new Thread(testMailServer);
+ server.start();
+
+ ClientThread testMailClient = new ClientThread();
+
+ testMailClient.from("Mail Message <EmailTaskTest@ant.apache.org>");
+ testMailClient.to("to@you.com");
+ testMailClient.cc("cc1@you.com");
+ testMailClient.cc("cc2@you.com");
+ testMailClient.bcc("bcc@you.com");
+ testMailClient.setSubject("Test subject");
+ testMailClient.setMessage( "test line 1\n" +
+ "test line 2" );
+
+ Thread client = new Thread(testMailClient);
+ client.start();
+
+ server.join(60 * 1000); // 60s
+ client.join(30 * 1000); // a further 30s
+
+ String result = testMailServer.getResult();
+ String expectedResult = "220 test SMTP EmailTaskTest\r\n" +
+ "HELO " + local + "\r\n" +
+ "250 " + local + " Hello " + local + " [127.0.0.1], pleased to meet you\r\n" +
+ "MAIL FROM: <EmailTaskTest@ant.apache.org>\r\n" +
+ "250\r\n" +
+ "RCPT TO: <to@you.com>\r\n" +
+ "250\r\n" +
+ "RCPT TO: <cc1@you.com>\r\n" +
+ "250\r\n" +
+ "RCPT TO: <cc2@you.com>\r\n" +
+ "250\r\n" +
+ "RCPT TO: <bcc@you.com>\r\n" +
+ "250\r\n" +
+ "DATA\r\n" +
+ "354\r\n" +
+ "Subject: Test subject\r\n" +
+ "From: Mail Message <EmailTaskTest@ant.apache.org>\r\n" +
+ "To: to@you.com\r\n" +
+ "Cc: cc1@you.com, cc2@you.com\r\n" +
+ "X-Mailer: org.apache.tools.mail.MailMessage (ant.apache.org)\r\n" +
+ "\r\n" +
+ "test line 1\r\n" +
+ "test line 2\r\n" +
+ "\r\n" +
+ ".\r\n" +
+ "250\r\n" +
+ "QUIT\r\n" +
+ "221\r\n";
+ /*for (int icounter = 0; icounter<expectedResult.length(); icounter++) {
+ if (icounter < result.length()) {
+ if (expectedResult.charAt(icounter) != result.charAt(icounter)) {
+ System.out.println("posit " + icounter + " expected "
+ + expectedResult.charAt(icounter)
+ + " result " + result.charAt(icounter));
+ }
+ }
+ }
+ if (expectedResult.length()>result.length()) {
+ System.out.println("excedent of expected result "
+ + expectedResult.substring(result.length()));
+ }
+ if (expectedResult.length()<result.length()) {
+ System.out.println("excedent of result "
+ + result.substring(expectedResult.length()));
+ }*/
+ assertEquals(expectedResult.length(), result.length());
+ assertEquals(expectedResult, result); // order of headers cannot be guaranteed
+ assertFalse(testMailClient.getFailMessage(), testMailClient.isFailed());
+ }
+
+ /**
+ * Test a MailMessage with no cc or bcc lines
+ * @throws InterruptedException
+ */
+ @Test
+ public void testToOnly() throws InterruptedException {
+ ServerThread testMailServer = new ServerThread();
+ Thread server = new Thread(testMailServer);
+ server.start();
+
+ ClientThread testMailClient = new ClientThread();
+
+ testMailClient.from("Mail Message <EmailTaskTest@ant.apache.org>");
+ testMailClient.to("to@you.com");
+ testMailClient.setSubject("Test subject");
+ testMailClient.setMessage( "test line 1\n" +
+ "test line 2" );
+
+ Thread client = new Thread(testMailClient);
+ client.start();
+
+ server.join(60 * 1000); // 60s
+ client.join(30 * 1000); // a further 30s
+
+ String result = testMailServer.getResult();
+ String expectedResult = "220 test SMTP EmailTaskTest\r\n" +
+ "HELO " + local + "\r\n" +
+ "250 " + local + " Hello " + local + " [127.0.0.1], pleased to meet you\r\n" +
+ "MAIL FROM: <EmailTaskTest@ant.apache.org>\r\n" +
+ "250\r\n" +
+ "RCPT TO: <to@you.com>\r\n" +
+ "250\r\n" +
+ "DATA\r\n" +
+ "354\r\n" +
+ "Subject: Test subject\r\n" +
+ "From: Mail Message <EmailTaskTest@ant.apache.org>\r\n" +
+ "To: to@you.com\r\n" +
+ "X-Mailer: org.apache.tools.mail.MailMessage (ant.apache.org)\r\n" +
+ "\r\n" +
+ "test line 1\r\n" +
+ "test line 2\r\n" +
+ "\r\n" +
+ ".\r\n" +
+ "250\r\n" +
+ "QUIT\r\n" +
+ "221\r\n";
+ assertEquals(expectedResult.length(), result.length());
+ assertEquals(expectedResult, result); // order of headers cannot be guaranteed
+ assertFalse(testMailClient.getFailMessage(), testMailClient.isFailed());
+ }
+
+
+ /**
+ * Test a MailMessage with no to or bcc lines
+ * @throws InterruptedException
+ */
+ @Test
+ public void testCcOnly() throws InterruptedException {
+ ServerThread testMailServer = new ServerThread();
+ Thread server = new Thread(testMailServer);
+ server.start();
+
+ ClientThread testMailClient = new ClientThread();
+
+ testMailClient.from("Mail Message <EmailTaskTest@ant.apache.org>");
+ testMailClient.cc("cc@you.com");
+ testMailClient.setSubject("Test subject");
+ testMailClient.setMessage( "test line 1\n" +
+ "test line 2" );
+
+ Thread client = new Thread(testMailClient);
+ client.start();
+
+ server.join(60 * 1000); // 60s
+ client.join(30 * 1000); // a further 30s
+
+ String result = testMailServer.getResult();
+ String expectedResult = "220 test SMTP EmailTaskTest\r\n" +
+ "HELO " + local + "\r\n" +
+ "250 " + local + " Hello " + local + " [127.0.0.1], pleased to meet you\r\n" +
+ "MAIL FROM: <EmailTaskTest@ant.apache.org>\r\n" +
+ "250\r\n" +
+ "RCPT TO: <cc@you.com>\r\n" +
+ "250\r\n" +
+ "DATA\r\n" +
+ "354\r\n" +
+ "Subject: Test subject\r\n" +
+ "From: Mail Message <EmailTaskTest@ant.apache.org>\r\n" +
+ "Cc: cc@you.com\r\n" +
+ "X-Mailer: org.apache.tools.mail.MailMessage (ant.apache.org)\r\n" +
+ "\r\n" +
+ "test line 1\r\n" +
+ "test line 2\r\n" +
+ "\r\n" +
+ ".\r\n" +
+ "250\r\n" +
+ "QUIT\r\n" +
+ "221\r\n";
+ assertEquals(expectedResult.length(), result.length());
+ assertEquals(expectedResult, result);
+ assertFalse(testMailClient.getFailMessage(), testMailClient.isFailed());
+ }
+
+
+ /**
+ * Test a MailMessage with no to or cc lines
+ * @throws InterruptedException
+ */
+ @Test
+ public void testBccOnly() throws InterruptedException {
+ ServerThread testMailServer = new ServerThread();
+ Thread server = new Thread(testMailServer);
+ server.start();
+
+ ClientThread testMailClient = new ClientThread();
+
+ testMailClient.from("Mail Message <EmailTaskTest@ant.apache.org>");
+ testMailClient.bcc("bcc@you.com");
+ testMailClient.setSubject("Test subject");
+ testMailClient.setMessage( "test line 1\n" +
+ "test line 2" );
+
+ Thread client = new Thread(testMailClient);
+ client.start();
+
+ server.join(60 * 1000); // 60s
+ client.join(30 * 1000); // a further 30s
+
+ String result = testMailServer.getResult();
+ String expectedResult = "220 test SMTP EmailTaskTest\r\n" +
+ "HELO " + local + "\r\n" +
+ "250 " + local + " Hello " + local + " [127.0.0.1], pleased to meet you\r\n" +
+ "MAIL FROM: <EmailTaskTest@ant.apache.org>\r\n" +
+ "250\r\n" +
+ "RCPT TO: <bcc@you.com>\r\n" +
+ "250\r\n" +
+ "DATA\r\n" +
+ "354\r\n" +
+ "Subject: Test subject\r\n" +
+ "From: Mail Message <EmailTaskTest@ant.apache.org>\r\n" +
+ "X-Mailer: org.apache.tools.mail.MailMessage (ant.apache.org)\r\n" +
+ "\r\n" +
+ "test line 1\r\n" +
+ "test line 2\r\n" +
+ "\r\n" +
+ ".\r\n" +
+ "250\r\n" +
+ "QUIT\r\n" +
+ "221\r\n";
+ assertEquals( expectedResult.length(), result.length() );
+ assertEquals( expectedResult, result );
+ assertFalse(testMailClient.getFailMessage(), testMailClient.isFailed());
+ }
+
+
+ /**
+ * Test a MailMessage with no subject line
+ * Subject is an optional field (RFC 822 s4.1)
+ * @throws InterruptedException
+ */
+ @Test
+ public void testNoSubject() throws InterruptedException {
+ ServerThread testMailServer = new ServerThread();
+ Thread server = new Thread(testMailServer);
+ server.start();
+
+ ClientThread testMailClient = new ClientThread();
+
+ testMailClient.from("Mail Message <EmailTaskTest@ant.apache.org>");
+ testMailClient.to("to@you.com");
+ testMailClient.setMessage( "test line 1\n" +
+ "test line 2" );
+
+ Thread client = new Thread(testMailClient);
+ client.start();
+
+ server.join(60 * 1000); // 60s
+ client.join(30 * 1000); // a further 30s
+
+ String result = testMailServer.getResult();
+ String expectedResult = "220 test SMTP EmailTaskTest\r\n" +
+ "HELO " + local + "\r\n" +
+ "250 " + local + " Hello " + local + " [127.0.0.1], pleased to meet you\r\n" +
+ "MAIL FROM: <EmailTaskTest@ant.apache.org>\r\n" +
+ "250\r\n" +
+ "RCPT TO: <to@you.com>\r\n" +
+ "250\r\n" +
+ "DATA\r\n" +
+ "354\r\n" +
+ "From: Mail Message <EmailTaskTest@ant.apache.org>\r\n" +
+ "To: to@you.com\r\n" +
+ "X-Mailer: org.apache.tools.mail.MailMessage (ant.apache.org)\r\n" +
+ "\r\n" +
+ "test line 1\r\n" +
+ "test line 2\r\n" +
+ "\r\n" +
+ ".\r\n" +
+ "250\r\n" +
+ "QUIT\r\n" +
+ "221\r\n";
+ assertEquals( expectedResult.length(), result.length() );
+ assertEquals( expectedResult, result );
+ assertFalse(testMailClient.getFailMessage(), testMailClient.isFailed());
+ }
+
+
+ /**
+ * Test a MailMessage with empty body message
+ * @throws InterruptedException
+ */
+ @Test
+ public void testEmptyBody() throws InterruptedException {
+ ServerThread testMailServer = new ServerThread();
+ Thread server = new Thread(testMailServer);
+ server.start();
+
+ ClientThread testMailClient = new ClientThread();
+
+ testMailClient.from("Mail Message <EmailTaskTest@ant.apache.org>");
+ testMailClient.to("to@you.com");
+ testMailClient.setSubject("Test subject");
+ testMailClient.setMessage("");
+
+ Thread client = new Thread(testMailClient);
+ client.start();
+
+ server.join(60 * 1000); // 60s
+ client.join(30 * 1000); // a further 30s
+
+ String result = testMailServer.getResult();
+ String expectedResult = "220 test SMTP EmailTaskTest\r\n" +
+ "HELO " + local + "\r\n" +
+ "250 " + local + " Hello " + local + " [127.0.0.1], pleased to meet you\r\n" +
+ "MAIL FROM: <EmailTaskTest@ant.apache.org>\r\n" +
+ "250\r\n" +
+ "RCPT TO: <to@you.com>\r\n" +
+ "250\r\n" +
+ "DATA\r\n" +
+ "354\r\n" +
+ "Subject: Test subject\r\n" +
+ "From: Mail Message <EmailTaskTest@ant.apache.org>\r\n" +
+ "To: to@you.com\r\n" +
+ "X-Mailer: org.apache.tools.mail.MailMessage (ant.apache.org)\r\n" +
+ "\r\n" +
+ "\r\n" +
+ "\r\n" +
+ ".\r\n" +
+ "250\r\n" +
+ "QUIT\r\n" +
+ "221\r\n";
+ assertEquals(expectedResult.length(), result.length());
+ assertEquals(expectedResult, result);
+ assertFalse(testMailClient.getFailMessage(), testMailClient.isFailed());
+ }
+
+
+ /**
+ * Test a MailMessage with US-ASCII character set
+ * The next four testcase can be kinda hard to debug as Ant will often
+ * print the junit failure in US-ASCII.
+ * @throws InterruptedException
+ */
+ @Test
+ public void testAsciiCharset() throws InterruptedException {
+
+ ServerThread testMailServer = new ServerThread();
+ Thread server = new Thread(testMailServer);
+ server.start();
+
+ ClientThread testMailClient = new ClientThread();
+
+ testMailClient.from("Mail Message <EmailTaskTest@ant.apache.org>");
+ testMailClient.to("Ceki G\u00fclc\u00fc <abuse@mail-abuse.org>");
+ testMailClient.setSubject("Test subject");
+ testMailClient.setMessage("");
+
+ Thread client = new Thread(testMailClient);
+ client.start();
+
+ server.join(60 * 1000); // 60s
+ client.join(30 * 1000); // a further 30s
+
+ String result = testMailServer.getResult();
+ String expectedResult = "220 test SMTP EmailTaskTest\r\n" +
+ "HELO " + local + "\r\n" +
+ "250 " + local + " Hello " + local + " [127.0.0.1], pleased to meet you\r\n" +
+ "MAIL FROM: <EmailTaskTest@ant.apache.org>\r\n" +
+ "250\r\n" +
+ "RCPT TO: <abuse@mail-abuse.org>\r\n" +
+ "250\r\n" +
+ "DATA\r\n" +
+ "354\r\n" +
+ "Subject: Test subject\r\n" +
+ "From: Mail Message <EmailTaskTest@ant.apache.org>\r\n" +
+ "To: Ceki G\u00fclc\u00fc <abuse@mail-abuse.org>\r\n" +
+ "X-Mailer: org.apache.tools.mail.MailMessage (ant.apache.org)\r\n" +
+ "\r\n" +
+ "\r\n" +
+ "\r\n" +
+ ".\r\n" +
+ "250\r\n" +
+ "QUIT\r\n" +
+ "221\r\n";
+ ByteArrayOutputStream baos1 = new ByteArrayOutputStream();
+ ByteArrayOutputStream baos2 = new ByteArrayOutputStream();
+ PrintStream bos1 = new PrintStream(baos1, true);
+ PrintStream bos2 = new PrintStream(baos2, true);
+
+ bos1.print(expectedResult);
+ bos2.print(result);
+
+ assertEquals( "expected message length != actual message length "
+ + "in testAsciiCharset()", expectedResult.length(), result.length() );
+ assertEquals( "baos1 and baos2 should be the same in testAsciiCharset()",
+ baos1.toString(), baos2.toString() ); // order of headers cannot be guaranteed
+ assertFalse(testMailClient.getFailMessage(), testMailClient.isFailed());
+ }
+
+
+
+
+ /**
+ * A private test class that pretends to be a mail transfer agent
+ */
+ private class ServerThread implements Runnable {
+
+ private StringBuffer sb = null;
+ private boolean loop = false;
+ ServerSocket ssock = null;
+ Socket sock = null;
+ BufferedWriter out = null;
+ BufferedReader in = null;
+ private boolean data = false; // state engine: false=envelope, true=message
+
+ public void run() {
+
+ try {
+ ssock = new ServerSocket(TEST_PORT);
+ sock = ssock.accept(); // wait for connection
+ in = new BufferedReader( new InputStreamReader(
+ sock.getInputStream()) );
+ out = new BufferedWriter( new OutputStreamWriter(
+ sock.getOutputStream() ) );
+ sb = new StringBuffer();
+ send( "220 test SMTP EmailTaskTest\r\n" );
+ loop = true;
+ while ( loop ) {
+ String response = in.readLine();
+ if ( response == null ) {
+ loop = false;
+ break;
+ }
+ sb.append( response + "\r\n" );
+
+ if ( !data && response.startsWith( "HELO" ) ) {
+ send( "250 " + local + " Hello " + local + " " +
+ "[127.0.0.1], pleased to meet you\r\n" );
+ } else if ( !data && response.startsWith("MAIL") ) {
+ send( "250\r\n" );
+ } else if ( !data && response.startsWith("RCPT")) {
+ send( "250\r\n" );
+ } else if (!data && response.startsWith("DATA")) {
+ send( "354\r\n" );
+ data = true;
+ } else if (data && response.equals(".") ) {
+ send( "250\r\n" );
+ data = false;
+ } else if (!data && response.startsWith("QUIT")) {
+ send( "221\r\n" );
+ loop = false;
+ } else if (!data) {
+ //throw new IllegalStateException("Command unrecognized: "
+ // + response);
+ send( "500 5.5.1 Command unrecognized: \"" +
+ response + "\"\r\n" );
+ loop = false;
+ } else {
+ // sb.append( response + "\r\n" );
+ }
+
+ } // while
+ } catch (IOException ioe) {
+ throw new BuildException(ioe);
+ } finally {
+ disconnect();
+ }
+ }
+
+ private void send(String retmsg) throws IOException {
+ out.write( retmsg );
+ out.flush();
+ sb.append( retmsg );
+ }
+
+ private void disconnect() {
+ if (out != null) {
+ try {
+ out.flush();
+ out.close();
+ out = null;
+ } catch (IOException e) {
+ // ignore
+ }
+ }
+ if (in != null) {
+ try {
+ in.close();
+ in = null;
+ } catch (IOException e) {
+ // ignore
+ }
+ }
+ if (sock != null) {
+ try {
+ sock.close();
+ sock = null;
+ } catch (IOException e) {
+ // ignore
+ }
+ }
+ if (ssock != null) {
+ try {
+ ssock.close();
+ ssock = null;
+ } catch (IOException e) {
+ // ignore
+ }
+ }
+ }
+
+ public synchronized String getResult() {
+ loop = false;
+ return sb.toString();
+ }
+
+ }
+
+ /**
+ * A private test class that wraps MailMessage
+ */
+ private class ClientThread implements Runnable {
+
+ private MailMessage msg;
+ private boolean fail = false;
+ private String failMessage = null;
+
+ protected String from = null;
+ protected String subject = null;
+ protected String message = null;
+
+ protected Vector replyToList = new Vector();
+ protected Vector toList = new Vector();
+ protected Vector ccList = new Vector();
+ protected Vector bccList = new Vector();
+
+
+ public void run() {
+ for (int i = 9; i > 0; i--) {
+ try {
+ msg = new MailMessage("localhost", TEST_PORT);
+ } catch (java.net.ConnectException ce) {
+ try {
+ Thread.sleep(10 * 1000);
+ } catch (InterruptedException ie) {
+ throw new AssumptionViolatedException("Thread interrupted", ie);
+ }
+ } catch (IOException ioe) {
+ fail = true;
+ failMessage = "IOException: " + ioe;
+ return;
+ }
+ if (msg != null) {
+ break;
+ }
+ }
+
+ if (msg == null) {
+ fail = true;
+ failMessage = "java.net.ConnectException: Connection refused";
+ return;
+ }
+
+ try {
+ msg.from(from);
+
+ Enumeration e;
+
+ e = replyToList.elements();
+ while (e.hasMoreElements()) {
+ msg.replyto(e.nextElement().toString());
+ }
+
+ e = toList.elements();
+ while (e.hasMoreElements()) {
+ msg.to(e.nextElement().toString());
+ }
+
+ e = ccList.elements();
+ while (e.hasMoreElements()) {
+ msg.cc(e.nextElement().toString());
+ }
+
+ e = bccList.elements();
+ while (e.hasMoreElements()) {
+ msg.bcc(e.nextElement().toString());
+ }
+
+ if (subject != null) {
+ msg.setSubject(subject);
+ }
+
+ if (message != null ) {
+ PrintStream out = msg.getPrintStream();
+ out.println( message );
+ }
+
+ msg.sendAndClose();
+ } catch (IOException ioe) {
+ fail = true;
+ failMessage = "IOException: " + ioe;
+ return;
+ }
+ }
+
+ public boolean isFailed() {
+ return fail;
+ }
+
+ public String getFailMessage() {
+ return failMessage;
+ }
+
+ public void replyTo(String replyTo) {
+ replyToList.add(replyTo);
+ }
+
+ public void to(String to) {
+ toList.add(to);
+ }
+
+ public void cc(String cc) {
+ ccList.add(cc);
+ }
+
+ public void bcc(String bcc) {
+ bccList.add(bcc);
+ }
+
+ public void setSubject(String subject) {
+ this.subject = subject;
+ }
+
+ public void from(String from) {
+ this.from = from;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/tar/TarEntryTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/tar/TarEntryTest.java
new file mode 100644
index 00000000..e942cdb3
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/tar/TarEntryTest.java
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.tar;
+
+import org.junit.Test;
+
+/**
+ * @since Ant 1.6
+ */
+public class TarEntryTest {
+
+ /**
+ * demonstrates bug 18105 on OSes with os.name shorter than 7.
+ */
+ @Test
+ public void testFileConstructor() {
+ new TarEntry(new java.io.File("/foo"));
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/tar/TarOutputStreamTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/tar/TarOutputStreamTest.java
new file mode 100644
index 00000000..cb65e2df
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/tar/TarOutputStreamTest.java
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.tar;
+
+import org.junit.Test;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+public class TarOutputStreamTest {
+
+ @Test
+ public void testClose() throws IOException {
+ ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
+ TarOutputStream stream = new TarOutputStream(byteStream);
+ stream.close();
+ stream.close();
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/tar/TarRoundTripTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/tar/TarRoundTripTest.java
new file mode 100644
index 00000000..98e6378d
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/tar/TarRoundTripTest.java
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.tar;
+
+import org.junit.Test;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+public class TarRoundTripTest {
+
+ private static final String LONG_NAME
+ = "this/path/name/contains/more/than/one/hundred/characters/in/order/"
+ + "to/test/the/GNU/long/file/name/capability/round/tripped";
+
+ /**
+ * test round-tripping long (GNU) entries
+ */
+ @Test
+ public void testLongRoundTrippingGNU() throws IOException {
+ testLongRoundTripping(TarOutputStream.LONGFILE_GNU);
+ }
+
+ /**
+ * test round-tripping long (POSIX) entries
+ */
+ @Test
+ public void testLongRoundTrippingPOSIX() throws IOException {
+ testLongRoundTripping(TarOutputStream.LONGFILE_POSIX);
+ }
+
+ private void testLongRoundTripping(int mode) throws IOException {
+ TarEntry original = new TarEntry(LONG_NAME);
+ assertTrue("over 100 chars", LONG_NAME.length() > 100);
+ assertEquals("original name", LONG_NAME, original.getName());
+
+
+ ByteArrayOutputStream buff = new ByteArrayOutputStream();
+ TarOutputStream tos = new TarOutputStream(buff);
+ tos.setLongFileMode(mode);
+ tos.putNextEntry(original);
+ tos.closeEntry();
+ tos.close();
+
+ TarInputStream tis
+ = new TarInputStream(new ByteArrayInputStream(buff.toByteArray()));
+ TarEntry tripped = tis.getNextEntry();
+ assertEquals("round-tripped name", LONG_NAME, tripped.getName());
+ assertNull("no more entries", tis.getNextEntry());
+ tis.close();
+ }
+}
+
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/zip/AsiExtraFieldTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/zip/AsiExtraFieldTest.java
new file mode 100644
index 00000000..873b3f50
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/zip/AsiExtraFieldTest.java
@@ -0,0 +1,163 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.zip;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+/**
+ * JUnit testcases for org.apache.tools.zip.AsiExtraField.
+ *
+ */
+public class AsiExtraFieldTest implements UnixStat {
+
+ /**
+ * Test file mode magic.
+ */
+ @Test
+ public void testModes() {
+ AsiExtraField a = new AsiExtraField();
+ a.setMode(0123);
+ assertEquals("plain file", 0100123, a.getMode());
+ a.setDirectory(true);
+ assertEquals("directory", 040123, a.getMode());
+ a.setLinkedFile("test");
+ assertEquals("symbolic link", 0120123, a.getMode());
+ }
+
+ /**
+ * Test content.
+ */
+ @Test
+ public void testContent() {
+ AsiExtraField a = new AsiExtraField();
+ a.setMode(0123);
+ a.setUserId(5);
+ a.setGroupId(6);
+ byte[] b = a.getLocalFileDataData();
+
+ // CRC manually calculated, sorry
+ byte[] expect = {(byte)0xC6, 0x02, 0x78, (byte)0xB6, // CRC
+ 0123, (byte)0x80, // mode
+ 0, 0, 0, 0, // link length
+ 5, 0, 6, 0}; // uid, gid
+ assertEquals("no link", expect.length, b.length);
+ for (int i=0; i<expect.length; i++) {
+ assertEquals("no link, byte "+i, expect[i], b[i]);
+ }
+
+ a.setLinkedFile("test");
+ expect = new byte[] {0x75, (byte)0x8E, 0x41, (byte)0xFD, // CRC
+ 0123, (byte)0xA0, // mode
+ 4, 0, 0, 0, // link length
+ 5, 0, 6, 0, // uid, gid
+ (byte)'t', (byte)'e', (byte)'s', (byte)'t'};
+ b = a.getLocalFileDataData();
+ assertEquals("no link", expect.length, b.length);
+ for (int i=0; i<expect.length; i++) {
+ assertEquals("no link, byte "+i, expect[i], b[i]);
+ }
+
+ }
+
+ /**
+ * Test reparse
+ */
+ @Test
+ public void testReparse() throws Exception {
+ // CRC manually calculated, sorry
+ byte[] data = {(byte)0xC6, 0x02, 0x78, (byte)0xB6, // CRC
+ 0123, (byte)0x80, // mode
+ 0, 0, 0, 0, // link length
+ 5, 0, 6, 0}; // uid, gid
+ AsiExtraField a = new AsiExtraField();
+ a.parseFromLocalFileData(data, 0, data.length);
+ assertEquals("length plain file", data.length,
+ a.getLocalFileDataLength().getValue());
+ assertTrue("plain file, no link", !a.isLink());
+ assertTrue("plain file, no dir", !a.isDirectory());
+ assertEquals("mode plain file", FILE_FLAG | 0123, a.getMode());
+ assertEquals("uid plain file", 5, a.getUserId());
+ assertEquals("gid plain file", 6, a.getGroupId());
+
+ data = new byte[] {0x75, (byte)0x8E, 0x41, (byte)0xFD, // CRC
+ 0123, (byte)0xA0, // mode
+ 4, 0, 0, 0, // link length
+ 5, 0, 6, 0, // uid, gid
+ (byte)'t', (byte)'e', (byte)'s', (byte)'t'};
+ a = new AsiExtraField();
+ a.parseFromLocalFileData(data, 0, data.length);
+ assertEquals("length link", data.length,
+ a.getLocalFileDataLength().getValue());
+ assertTrue("link, is link", a.isLink());
+ assertTrue("link, no dir", !a.isDirectory());
+ assertEquals("mode link", LINK_FLAG | 0123, a.getMode());
+ assertEquals("uid link", 5, a.getUserId());
+ assertEquals("gid link", 6, a.getGroupId());
+ assertEquals("test", a.getLinkedFile());
+
+ data = new byte[] {(byte)0x8E, 0x01, (byte)0xBF, (byte)0x0E, // CRC
+ 0123, (byte)0x40, // mode
+ 0, 0, 0, 0, // link
+ 5, 0, 6, 0}; // uid, gid
+ a = new AsiExtraField();
+ a.parseFromLocalFileData(data, 0, data.length);
+ assertEquals("length dir", data.length,
+ a.getLocalFileDataLength().getValue());
+ assertTrue("dir, no link", !a.isLink());
+ assertTrue("dir, is dir", a.isDirectory());
+ assertEquals("mode dir", DIR_FLAG | 0123, a.getMode());
+ assertEquals("uid dir", 5, a.getUserId());
+ assertEquals("gid dir", 6, a.getGroupId());
+
+ data = new byte[] {0, 0, 0, 0, // bad CRC
+ 0123, (byte)0x40, // mode
+ 0, 0, 0, 0, // link
+ 5, 0, 6, 0}; // uid, gid
+ a = new AsiExtraField();
+ try {
+ a.parseFromLocalFileData(data, 0, data.length);
+ fail("should raise bad CRC exception");
+ } catch (Exception e) {
+ assertEquals("bad CRC checksum 0 instead of ebf018e",
+ e.getMessage());
+ }
+ }
+
+ @Test
+ public void testClone() {
+ AsiExtraField s1 = new AsiExtraField();
+ s1.setUserId(42);
+ s1.setGroupId(12);
+ s1.setLinkedFile("foo");
+ s1.setMode(0644);
+ s1.setDirectory(true);
+ AsiExtraField s2 = (AsiExtraField) s1.clone();
+ assertNotSame(s1, s2);
+ assertEquals(s1.getUserId(), s2.getUserId());
+ assertEquals(s1.getGroupId(), s2.getGroupId());
+ assertEquals(s1.getLinkedFile(), s2.getLinkedFile());
+ assertEquals(s1.getMode(), s2.getMode());
+ assertEquals(s1.isDirectory(), s2.isDirectory());
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/zip/ExtraFieldUtilsTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/zip/ExtraFieldUtilsTest.java
new file mode 100644
index 00000000..95a6779e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/zip/ExtraFieldUtilsTest.java
@@ -0,0 +1,210 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.zip;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+/**
+ * JUnit 3 testcases for org.apache.tools.zip.ExtraFieldUtils.
+ *
+ */
+public class ExtraFieldUtilsTest implements UnixStat {
+
+ /**
+ * Header-ID of a ZipExtraField not supported by Ant.
+ *
+ * <p>Used to be ZipShort(1) but this is the ID of the Zip64 extra
+ * field.</p>
+ */
+ static final ZipShort UNRECOGNIZED_HEADER = new ZipShort(0x5555);
+
+ private AsiExtraField a;
+ private UnrecognizedExtraField dummy;
+ private byte[] data;
+ private byte[] aLocal;
+
+ @Before
+ public void setUp() {
+ a = new AsiExtraField();
+ a.setMode(0755);
+ a.setDirectory(true);
+ dummy = new UnrecognizedExtraField();
+ dummy.setHeaderId(UNRECOGNIZED_HEADER);
+ dummy.setLocalFileDataData(new byte[] {0});
+ dummy.setCentralDirectoryData(new byte[] {0});
+
+ aLocal = a.getLocalFileDataData();
+ byte[] dummyLocal = dummy.getLocalFileDataData();
+ data = new byte[4 + aLocal.length + 4 + dummyLocal.length];
+ System.arraycopy(a.getHeaderId().getBytes(), 0, data, 0, 2);
+ System.arraycopy(a.getLocalFileDataLength().getBytes(), 0, data, 2, 2);
+ System.arraycopy(aLocal, 0, data, 4, aLocal.length);
+ System.arraycopy(dummy.getHeaderId().getBytes(), 0, data,
+ 4+aLocal.length, 2);
+ System.arraycopy(dummy.getLocalFileDataLength().getBytes(), 0, data,
+ 4+aLocal.length+2, 2);
+ System.arraycopy(dummyLocal, 0, data,
+ 4+aLocal.length+4, dummyLocal.length);
+
+ }
+
+ /**
+ * test parser.
+ */
+ @Test
+ public void testParse() throws Exception {
+ ZipExtraField[] ze = ExtraFieldUtils.parse(data);
+ assertEquals("number of fields", 2, ze.length);
+ assertTrue("type field 1", ze[0] instanceof AsiExtraField);
+ assertEquals("mode field 1", 040755,
+ ((AsiExtraField) ze[0]).getMode());
+ assertTrue("type field 2", ze[1] instanceof UnrecognizedExtraField);
+ assertEquals("data length field 2", 1,
+ ze[1].getLocalFileDataLength().getValue());
+
+ byte[] data2 = new byte[data.length-1];
+ System.arraycopy(data, 0, data2, 0, data2.length);
+ try {
+ ExtraFieldUtils.parse(data2);
+ fail("data should be invalid");
+ } catch (Exception e) {
+ assertEquals("message",
+ "bad extra field starting at "+(4 + aLocal.length)
+ + ". Block length of 1 bytes exceeds remaining data of 0 bytes.",
+ e.getMessage());
+ }
+ }
+
+ @Test
+ public void testParseWithRead() throws Exception {
+ ZipExtraField[] ze =
+ ExtraFieldUtils.parse(data, true,
+ ExtraFieldUtils.UnparseableExtraField.READ);
+ assertEquals("number of fields", 2, ze.length);
+ assertTrue("type field 1", ze[0] instanceof AsiExtraField);
+ assertEquals("mode field 1", 040755,
+ ((AsiExtraField) ze[0]).getMode());
+ assertTrue("type field 2", ze[1] instanceof UnrecognizedExtraField);
+ assertEquals("data length field 2", 1,
+ ze[1].getLocalFileDataLength().getValue());
+
+ byte[] data2 = new byte[data.length-1];
+ System.arraycopy(data, 0, data2, 0, data2.length);
+ ze = ExtraFieldUtils.parse(data2, true,
+ ExtraFieldUtils.UnparseableExtraField.READ);
+ assertEquals("number of fields", 2, ze.length);
+ assertTrue("type field 1", ze[0] instanceof AsiExtraField);
+ assertEquals("mode field 1", 040755,
+ ((AsiExtraField) ze[0]).getMode());
+ assertTrue("type field 2", ze[1] instanceof UnparseableExtraFieldData);
+ assertEquals("data length field 2", 4,
+ ze[1].getLocalFileDataLength().getValue());
+ for (int i = 0; i < 4; i++) {
+ assertEquals("byte number " + i,
+ data2[data.length - 5 + i],
+ ze[1].getLocalFileDataData()[i]);
+ }
+ }
+
+ @Test
+ public void testParseWithSkip() throws Exception {
+ ZipExtraField[] ze =
+ ExtraFieldUtils.parse(data, true,
+ ExtraFieldUtils.UnparseableExtraField.SKIP);
+ assertEquals("number of fields", 2, ze.length);
+ assertTrue("type field 1", ze[0] instanceof AsiExtraField);
+ assertEquals("mode field 1", 040755,
+ ((AsiExtraField) ze[0]).getMode());
+ assertTrue("type field 2", ze[1] instanceof UnrecognizedExtraField);
+ assertEquals("data length field 2", 1,
+ ze[1].getLocalFileDataLength().getValue());
+
+ byte[] data2 = new byte[data.length-1];
+ System.arraycopy(data, 0, data2, 0, data2.length);
+ ze = ExtraFieldUtils.parse(data2, true,
+ ExtraFieldUtils.UnparseableExtraField.SKIP);
+ assertEquals("number of fields", 1, ze.length);
+ assertTrue("type field 1", ze[0] instanceof AsiExtraField);
+ assertEquals("mode field 1", 040755,
+ ((AsiExtraField) ze[0]).getMode());
+ }
+
+ /**
+ * Test merge methods
+ */
+ @Test
+ public void testMerge() {
+ byte[] local =
+ ExtraFieldUtils.mergeLocalFileDataData(new ZipExtraField[] {a, dummy});
+ assertEquals("local length", data.length, local.length);
+ for (int i=0; i<local.length; i++) {
+ assertEquals("local byte "+i, data[i], local[i]);
+ }
+
+ byte[] dummyCentral = dummy.getCentralDirectoryData();
+ byte[] data2 = new byte[4 + aLocal.length + 4 + dummyCentral.length];
+ System.arraycopy(data, 0, data2, 0, 4 + aLocal.length + 2);
+ System.arraycopy(dummy.getCentralDirectoryLength().getBytes(), 0,
+ data2, 4+aLocal.length+2, 2);
+ System.arraycopy(dummyCentral, 0, data2,
+ 4+aLocal.length+4, dummyCentral.length);
+
+
+ byte[] central =
+ ExtraFieldUtils.mergeCentralDirectoryData(new ZipExtraField[] {a, dummy});
+ assertEquals("central length", data2.length, central.length);
+ for (int i=0; i<central.length; i++) {
+ assertEquals("central byte "+i, data2[i], central[i]);
+ }
+
+ }
+
+ @Test
+ public void testMergeWithUnparseableData() throws Exception {
+ ZipExtraField d = new UnparseableExtraFieldData();
+ byte[] b = UNRECOGNIZED_HEADER.getBytes();
+ d.parseFromLocalFileData(new byte[] {b[0], b[1], 1, 0}, 0, 4);
+ byte[] local =
+ ExtraFieldUtils.mergeLocalFileDataData(new ZipExtraField[] {a, d});
+ assertEquals("local length", data.length - 1, local.length);
+ for (int i = 0; i < local.length; i++) {
+ assertEquals("local byte " + i, data[i], local[i]);
+ }
+
+ byte[] dCentral = d.getCentralDirectoryData();
+ byte[] data2 = new byte[4 + aLocal.length + dCentral.length];
+ System.arraycopy(data, 0, data2, 0, 4 + aLocal.length + 2);
+ System.arraycopy(dCentral, 0, data2,
+ 4 + aLocal.length, dCentral.length);
+
+
+ byte[] central =
+ ExtraFieldUtils.mergeCentralDirectoryData(new ZipExtraField[] {a, d});
+ assertEquals("central length", data2.length, central.length);
+ for (int i = 0; i < central.length; i++) {
+ assertEquals("central byte " + i, data2[i], central[i]);
+ }
+
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/zip/UTF8ZipFilesTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/zip/UTF8ZipFilesTest.java
new file mode 100644
index 00000000..38b2df58
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/zip/UTF8ZipFilesTest.java
@@ -0,0 +1,260 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.zip;
+
+import java.io.File;
+import java.io.InputStream;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.Enumeration;
+import java.util.zip.CRC32;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+public class UTF8ZipFilesTest {
+
+ private static final String UTF_8 = "utf-8";
+ private static final String CP437 = "cp437";
+ private static final String US_ASCII = "US-ASCII";
+ private static final String ASCII_TXT = "ascii.txt";
+ private static final String EURO_FOR_DOLLAR_TXT = "\u20AC_for_Dollar.txt";
+ private static final String OIL_BARREL_TXT = "\u00D6lf\u00E4sser.txt";
+
+ @Test
+ public void testUtf8FileRoundtripExplicitUnicodeExtra()
+ throws IOException {
+ testFileRoundtrip(UTF_8, true, true);
+ }
+
+ @Test
+ public void testUtf8FileRoundtripNoEFSExplicitUnicodeExtra()
+ throws IOException {
+ testFileRoundtrip(UTF_8, false, true);
+ }
+
+ @Test
+ public void testCP437FileRoundtripExplicitUnicodeExtra()
+ throws IOException {
+ testFileRoundtrip(CP437, false, true);
+ }
+
+ @Test
+ public void testASCIIFileRoundtripExplicitUnicodeExtra()
+ throws IOException {
+ testFileRoundtrip(US_ASCII, false, true);
+ }
+
+ @Test
+ public void testUtf8FileRoundtripImplicitUnicodeExtra()
+ throws IOException {
+ testFileRoundtrip(UTF_8, true, false);
+ }
+
+ @Test
+ public void testUtf8FileRoundtripNoEFSImplicitUnicodeExtra()
+ throws IOException {
+ testFileRoundtrip(UTF_8, false, false);
+ }
+
+ @Test
+ public void testCP437FileRoundtripImplicitUnicodeExtra()
+ throws IOException {
+ testFileRoundtrip(CP437, false, false);
+ }
+
+ @Test
+ public void testASCIIFileRoundtripImplicitUnicodeExtra()
+ throws IOException {
+ testFileRoundtrip(US_ASCII, false, false);
+ }
+
+ @Test
+ public void testZipFileReadsUnicodeFields() throws IOException {
+ File file = File.createTempFile("unicode-test", ".zip");
+ ZipFile zf = null;
+ try {
+ createTestFile(file, US_ASCII, false, true);
+ zf = new ZipFile(file, US_ASCII, true);
+ assertCanRead(zf, ASCII_TXT);
+ assertCanRead(zf, EURO_FOR_DOLLAR_TXT);
+ assertCanRead(zf, OIL_BARREL_TXT);
+ } finally {
+ ZipFile.closeQuietly(zf);
+ if (file.exists()) {
+ file.delete();
+ }
+ }
+ }
+
+ private static void testFileRoundtrip(String encoding, boolean withEFS,
+ boolean withExplicitUnicodeExtra)
+ throws IOException {
+
+ File file = File.createTempFile(encoding + "-test", ".zip");
+ try {
+ createTestFile(file, encoding, withEFS, withExplicitUnicodeExtra);
+ testFile(file, encoding);
+ } finally {
+ if (file.exists()) {
+ file.delete();
+ }
+ }
+ }
+
+ private static void createTestFile(File file, String encoding,
+ boolean withEFS,
+ boolean withExplicitUnicodeExtra)
+ throws IOException {
+
+ ZipEncoding zipEncoding = ZipEncodingHelper.getZipEncoding(encoding);
+
+ ZipOutputStream zos = null;
+ try {
+ zos = new ZipOutputStream(file);
+ zos.setEncoding(encoding);
+ zos.setUseLanguageEncodingFlag(withEFS);
+ zos.setCreateUnicodeExtraFields(withExplicitUnicodeExtra ?
+ ZipOutputStream
+ .UnicodeExtraFieldPolicy.NEVER
+ : ZipOutputStream
+ .UnicodeExtraFieldPolicy.ALWAYS);
+
+ ZipEntry ze = new ZipEntry(OIL_BARREL_TXT);
+ if (withExplicitUnicodeExtra
+ && !zipEncoding.canEncode(ze.getName())) {
+
+ ByteBuffer en = zipEncoding.encode(ze.getName());
+
+ ze.addExtraField(new UnicodePathExtraField(ze.getName(),
+ en.array(),
+ en.arrayOffset(),
+ en.limit()));
+ }
+
+ zos.putNextEntry(ze);
+ zos.write("Hello, world!".getBytes("US-ASCII"));
+ zos.closeEntry();
+
+ ze = new ZipEntry(EURO_FOR_DOLLAR_TXT);
+ if (withExplicitUnicodeExtra
+ && !zipEncoding.canEncode(ze.getName())) {
+
+ ByteBuffer en = zipEncoding.encode(ze.getName());
+
+ ze.addExtraField(new UnicodePathExtraField(ze.getName(),
+ en.array(),
+ en.arrayOffset(),
+ en.limit()));
+ }
+
+ zos.putNextEntry(ze);
+ zos.write("Give me your money!".getBytes("US-ASCII"));
+ zos.closeEntry();
+
+ ze = new ZipEntry(ASCII_TXT);
+
+ if (withExplicitUnicodeExtra
+ && !zipEncoding.canEncode(ze.getName())) {
+
+ ByteBuffer en = zipEncoding.encode(ze.getName());
+
+ ze.addExtraField(new UnicodePathExtraField(ze.getName(),
+ en.array(),
+ en.arrayOffset(),
+ en.limit()));
+ }
+
+ zos.putNextEntry(ze);
+ zos.write("ascii".getBytes("US-ASCII"));
+ zos.closeEntry();
+ } finally {
+ if (zos != null) {
+ try {
+ zos.close();
+ } catch (IOException e) { /* swallow */ }
+ }
+ }
+ }
+
+ private static void testFile(File file, String encoding)
+ throws IOException {
+ ZipFile zf = null;
+ try {
+ zf = new ZipFile(file, encoding, false);
+
+ Enumeration e = zf.getEntries();
+ while (e.hasMoreElements()) {
+ ZipEntry ze = (ZipEntry) e.nextElement();
+
+ if (ze.getName().endsWith("sser.txt")) {
+ assertUnicodeName(ze, OIL_BARREL_TXT, encoding);
+
+ } else if (ze.getName().endsWith("_for_Dollar.txt")) {
+ assertUnicodeName(ze, EURO_FOR_DOLLAR_TXT, encoding);
+ } else if (!ze.getName().equals(ASCII_TXT)) {
+ throw new AssertionError("Urecognized ZIP entry with name ["
+ + ze.getName() + "] found.");
+ }
+ }
+ } finally {
+ ZipFile.closeQuietly(zf);
+ }
+ }
+
+ private static UnicodePathExtraField findUniCodePath(ZipEntry ze) {
+ return (UnicodePathExtraField)
+ ze.getExtraField(UnicodePathExtraField.UPATH_ID);
+ }
+
+ private static void assertUnicodeName(ZipEntry ze,
+ String expectedName,
+ String encoding)
+ throws IOException {
+ if (!expectedName.equals(ze.getName())) {
+ UnicodePathExtraField ucpf = findUniCodePath(ze);
+ assertNotNull(ucpf);
+
+ ZipEncoding enc = ZipEncodingHelper.getZipEncoding(encoding);
+ ByteBuffer ne = enc.encode(ze.getName());
+
+ CRC32 crc = new CRC32();
+ crc.update(ne.array(),ne.arrayOffset(),ne.limit());
+
+ assertEquals(crc.getValue(), ucpf.getNameCRC32());
+ assertEquals(expectedName, new String(ucpf.getUnicodeName(),
+ UTF_8));
+ }
+ }
+
+ private static void assertCanRead(ZipFile zf, String fileName) throws IOException {
+ ZipEntry entry = zf.getEntry(fileName);
+ assertNotNull("Entry " + fileName + " doesn't exist", entry);
+ InputStream is = zf.getInputStream(entry);
+ assertNotNull("InputStream is null", is);
+ try {
+ is.read();
+ } finally {
+ is.close();
+ }
+ }
+
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/zip/ZipEncodingTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/zip/ZipEncodingTest.java
new file mode 100644
index 00000000..826e410a
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/zip/ZipEncodingTest.java
@@ -0,0 +1,152 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tools.zip;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * Test zip encodings.
+ */
+public class ZipEncodingTest {
+ private static final String UNENC_STRING = "\u2016";
+
+ // stress test for internal grow method.
+ private static final String BAD_STRING =
+ "\u2016\u2015\u2016\u2015\u2016\u2015\u2016\u2015\u2016\u2015\u2016";
+
+ private static final String BAD_STRING_ENC =
+ "%U2016%U2015%U2016%U2015%U2016%U2015%U2016%U2015%U2016%U2015%U2016";
+
+ @Test
+ public void testSimpleCp437Encoding() throws IOException {
+
+ doSimpleEncodingTest("Cp437", null);
+ }
+
+ @Test
+ public void testSimpleCp850Encoding() throws IOException {
+
+ doSimpleEncodingTest("Cp850", null);
+ }
+
+ @Test
+ public void testNioCp1252Encoding() throws IOException {
+ // CP1252 has some undefined code points, these are
+ // the defined ones
+ // retrieved by
+ // awk '/^0x/ && NF>2 {print $1;}' CP1252.TXT
+ byte[] b =
+ new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+ 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
+ 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
+ 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
+ 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
+ 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
+ 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
+ 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
+ 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
+ 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
+ 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
+ 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
+ (byte) 0x80, (byte) 0x82, (byte) 0x83, (byte) 0x84,
+ (byte) 0x85, (byte) 0x86, (byte) 0x87, (byte) 0x88,
+ (byte) 0x89, (byte) 0x8A, (byte) 0x8B, (byte) 0x8C,
+ (byte) 0x8E, (byte) 0x91, (byte) 0x92, (byte) 0x93,
+ (byte) 0x94, (byte) 0x95, (byte) 0x96, (byte) 0x97,
+ (byte) 0x98, (byte) 0x99, (byte) 0x9A, (byte) 0x9B,
+ (byte) 0x9C, (byte) 0x9E, (byte) 0x9F, (byte) 0xA0,
+ (byte) 0xA1, (byte) 0xA2, (byte) 0xA3, (byte) 0xA4,
+ (byte) 0xA5, (byte) 0xA6, (byte) 0xA7, (byte) 0xA8,
+ (byte) 0xA9, (byte) 0xAA, (byte) 0xAB, (byte) 0xAC,
+ (byte) 0xAD, (byte) 0xAE, (byte) 0xAF, (byte) 0xB0,
+ (byte) 0xB1, (byte) 0xB2, (byte) 0xB3, (byte) 0xB4,
+ (byte) 0xB5, (byte) 0xB6, (byte) 0xB7, (byte) 0xB8,
+ (byte) 0xB9, (byte) 0xBA, (byte) 0xBB, (byte) 0xBC,
+ (byte) 0xBD, (byte) 0xBE, (byte) 0xBF, (byte) 0xC0,
+ (byte) 0xC1, (byte) 0xC2, (byte) 0xC3, (byte) 0xC4,
+ (byte) 0xC5, (byte) 0xC6, (byte) 0xC7, (byte) 0xC8,
+ (byte) 0xC9, (byte) 0xCA, (byte) 0xCB, (byte) 0xCC,
+ (byte) 0xCD, (byte) 0xCE, (byte) 0xCF, (byte) 0xD0,
+ (byte) 0xD1, (byte) 0xD2, (byte) 0xD3, (byte) 0xD4,
+ (byte) 0xD5, (byte) 0xD6, (byte) 0xD7, (byte) 0xD8,
+ (byte) 0xD9, (byte) 0xDA, (byte) 0xDB, (byte) 0xDC,
+ (byte) 0xDD, (byte) 0xDE, (byte) 0xDF, (byte) 0xE0,
+ (byte) 0xE1, (byte) 0xE2, (byte) 0xE3, (byte) 0xE4,
+ (byte) 0xE5, (byte) 0xE6, (byte) 0xE7, (byte) 0xE8,
+ (byte) 0xE9, (byte) 0xEA, (byte) 0xEB, (byte) 0xEC,
+ (byte) 0xED, (byte) 0xEE, (byte) 0xEF, (byte) 0xF0,
+ (byte) 0xF1, (byte) 0xF2, (byte) 0xF3, (byte) 0xF4,
+ (byte) 0xF5, (byte) 0xF6, (byte) 0xF7, (byte) 0xF8,
+ (byte) 0xF9, (byte) 0xFA, (byte) 0xFB, (byte) 0xFC,
+ (byte) 0xFD, (byte) 0xFE, (byte) 0xFF };
+
+ doSimpleEncodingTest("Cp1252",b);
+ }
+
+ private static void assertByteEquals(byte[] expected, ByteBuffer actual) {
+
+ assertEquals(expected.length, actual.limit());
+
+ for (int i = 0; i < expected.length; ++i) {
+
+ byte a = actual.get();
+ assertEquals(expected[i], a);
+ }
+
+ }
+
+ private void doSimpleEncodingTest(String name, byte[] testBytes)
+ throws IOException {
+
+ ZipEncoding enc = ZipEncodingHelper.getZipEncoding(name);
+
+ if (testBytes == null) {
+
+ testBytes = new byte[256];
+ for (int i = 0; i < 256; ++i) {
+ testBytes[i] = (byte) i;
+ }
+ }
+
+ String decoded = enc.decode(testBytes);
+
+ assertEquals(true, enc.canEncode(decoded));
+
+ ByteBuffer encoded = enc.encode(decoded);
+
+ assertByteEquals(testBytes, encoded);
+
+ assertEquals(false, enc.canEncode(UNENC_STRING));
+ assertByteEquals("%U2016".getBytes("US-ASCII"), enc.encode(UNENC_STRING));
+ assertEquals(false, enc.canEncode(BAD_STRING));
+ assertByteEquals(BAD_STRING_ENC.getBytes("US-ASCII"),
+ enc.encode(BAD_STRING));
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/zip/ZipEntryTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/zip/ZipEntryTest.java
new file mode 100644
index 00000000..3c21f6f3
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/zip/ZipEntryTest.java
@@ -0,0 +1,228 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.zip;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.fail;
+
+/**
+ * JUnit 3 testcases for org.apache.tools.zip.ZipEntry.
+ *
+ */
+public class ZipEntryTest {
+
+
+ /**
+ * test handling of extra fields
+ */
+ @Test
+ public void testExtraFields() {
+ AsiExtraField a = new AsiExtraField();
+ a.setDirectory(true);
+ a.setMode(0755);
+ UnrecognizedExtraField u = new UnrecognizedExtraField();
+ u.setHeaderId(ExtraFieldUtilsTest.UNRECOGNIZED_HEADER);
+ u.setLocalFileDataData(new byte[0]);
+
+ ZipEntry ze = new ZipEntry("test/");
+ ze.setExtraFields(new ZipExtraField[] {a, u});
+ byte[] data1 = ze.getExtra();
+ ZipExtraField[] result = ze.getExtraFields();
+ assertEquals("first pass", 2, result.length);
+ assertSame(a, result[0]);
+ assertSame(u, result[1]);
+
+ UnrecognizedExtraField u2 = new UnrecognizedExtraField();
+ u2.setHeaderId(ExtraFieldUtilsTest.UNRECOGNIZED_HEADER);
+ u2.setLocalFileDataData(new byte[] {1});
+
+ ze.addExtraField(u2);
+ byte[] data2 = ze.getExtra();
+ result = ze.getExtraFields();
+ assertEquals("second pass", 2, result.length);
+ assertSame(a, result[0]);
+ assertSame(u2, result[1]);
+ assertEquals("length second pass", data1.length+1, data2.length);
+
+ UnrecognizedExtraField u3 = new UnrecognizedExtraField();
+ u3.setHeaderId(new ZipShort(2));
+ u3.setLocalFileDataData(new byte[] {1});
+ ze.addExtraField(u3);
+ result = ze.getExtraFields();
+ assertEquals("third pass", 3, result.length);
+
+ ze.removeExtraField(ExtraFieldUtilsTest.UNRECOGNIZED_HEADER);
+ byte[] data3 = ze.getExtra();
+ result = ze.getExtraFields();
+ assertEquals("fourth pass", 2, result.length);
+ assertSame(a, result[0]);
+ assertSame(u3, result[1]);
+ assertEquals("length fourth pass", data2.length, data3.length);
+
+ try {
+ ze.removeExtraField(ExtraFieldUtilsTest.UNRECOGNIZED_HEADER);
+ fail("should be no such element");
+ } catch (java.util.NoSuchElementException nse) {
+ //TODO assert exception values
+ }
+ }
+
+ /**
+ * test handling of extra fields via central directory
+ */
+ @Test
+ public void testExtraFieldMerging() {
+ AsiExtraField a = new AsiExtraField();
+ a.setDirectory(true);
+ a.setMode(0755);
+ UnrecognizedExtraField u = new UnrecognizedExtraField();
+ u.setHeaderId(ExtraFieldUtilsTest.UNRECOGNIZED_HEADER);
+ u.setLocalFileDataData(new byte[0]);
+
+ ZipEntry ze = new ZipEntry("test/");
+ ze.setExtraFields(new ZipExtraField[] {a, u});
+
+ // merge
+ // Header-ID 1 + length 1 + one byte of data
+ byte[] b = ExtraFieldUtilsTest.UNRECOGNIZED_HEADER.getBytes();
+ ze.setCentralDirectoryExtra(new byte[] {b[0], b[1], 1, 0, 127});
+
+ ZipExtraField[] result = ze.getExtraFields();
+ assertEquals("first pass", 2, result.length);
+ assertSame(a, result[0]);
+ assertEquals(ExtraFieldUtilsTest.UNRECOGNIZED_HEADER,
+ result[1].getHeaderId());
+ assertEquals(new ZipShort(0), result[1].getLocalFileDataLength());
+ assertEquals(new ZipShort(1), result[1].getCentralDirectoryLength());
+
+ // add new
+ // Header-ID 2 + length 0
+ ze.setCentralDirectoryExtra(new byte[] {2, 0, 0, 0});
+
+ result = ze.getExtraFields();
+ assertEquals("second pass", 3, result.length);
+
+ // merge
+ // Header-ID 2 + length 1 + one byte of data
+ ze.setExtra(new byte[] {2, 0, 1, 0, 127});
+
+ result = ze.getExtraFields();
+ assertEquals("third pass", 3, result.length);
+ assertSame(a, result[0]);
+ assertEquals(new ZipShort(2), result[2].getHeaderId());
+ assertEquals(new ZipShort(1), result[2].getLocalFileDataLength());
+ assertEquals(new ZipShort(0), result[2].getCentralDirectoryLength());
+ }
+
+ /**
+ * test handling of extra fields
+ */
+ @Test
+ public void testAddAsFirstExtraField() {
+ AsiExtraField a = new AsiExtraField();
+ a.setDirectory(true);
+ a.setMode(0755);
+ UnrecognizedExtraField u = new UnrecognizedExtraField();
+ u.setHeaderId(ExtraFieldUtilsTest.UNRECOGNIZED_HEADER);
+ u.setLocalFileDataData(new byte[0]);
+
+ ZipEntry ze = new ZipEntry("test/");
+ ze.setExtraFields(new ZipExtraField[] {a, u});
+ byte[] data1 = ze.getExtra();
+
+ UnrecognizedExtraField u2 = new UnrecognizedExtraField();
+ u2.setHeaderId(ExtraFieldUtilsTest.UNRECOGNIZED_HEADER);
+ u2.setLocalFileDataData(new byte[] {1});
+
+ ze.addAsFirstExtraField(u2);
+ byte[] data2 = ze.getExtra();
+ ZipExtraField[] result = ze.getExtraFields();
+ assertEquals("second pass", 2, result.length);
+ assertSame(u2, result[0]);
+ assertSame(a, result[1]);
+ assertEquals("length second pass", data1.length + 1, data2.length);
+
+ UnrecognizedExtraField u3 = new UnrecognizedExtraField();
+ u3.setHeaderId(new ZipShort(2));
+ u3.setLocalFileDataData(new byte[] {1});
+ ze.addAsFirstExtraField(u3);
+ result = ze.getExtraFields();
+ assertEquals("third pass", 3, result.length);
+ assertSame(u3, result[0]);
+ assertSame(u2, result[1]);
+ assertSame(a, result[2]);
+ }
+
+ @Test
+ public void testUnixMode() {
+ ZipEntry ze = new ZipEntry("foo");
+ assertEquals(0, ze.getPlatform());
+ ze.setUnixMode(0755);
+ assertEquals(3, ze.getPlatform());
+ assertEquals(0755,
+ (ze.getExternalAttributes() >> 16) & 0xFFFF);
+ assertEquals(0, ze.getExternalAttributes() & 0xFFFF);
+
+ ze.setUnixMode(0444);
+ assertEquals(3, ze.getPlatform());
+ assertEquals(0444,
+ (ze.getExternalAttributes() >> 16) & 0xFFFF);
+ assertEquals(1, ze.getExternalAttributes() & 0xFFFF);
+
+ ze = new ZipEntry("foo/");
+ assertEquals(0, ze.getPlatform());
+ ze.setUnixMode(0777);
+ assertEquals(3, ze.getPlatform());
+ assertEquals(0777,
+ (ze.getExternalAttributes() >> 16) & 0xFFFF);
+ assertEquals(0x10, ze.getExternalAttributes() & 0xFFFF);
+
+ ze.setUnixMode(0577);
+ assertEquals(3, ze.getPlatform());
+ assertEquals(0577,
+ (ze.getExternalAttributes() >> 16) & 0xFFFF);
+ assertEquals(0x11, ze.getExternalAttributes() & 0xFFFF);
+ }
+
+ /**
+ * Test case for
+ * <a href="https://issues.apache.org/jira/browse/COMPRESS-94"
+ * >COMPRESS-94</a>.
+ */
+ @Test
+ public void testNotEquals() {
+ ZipEntry entry1 = new ZipEntry("foo");
+ ZipEntry entry2 = new ZipEntry("bar");
+ assertFalse(entry1.equals(entry2));
+ }
+
+ @Test
+ public void testCopyConstructor() throws Exception {
+ ZipEntry archiveEntry = new ZipEntry("fred");
+ archiveEntry.setUnixMode(0664);
+ archiveEntry.setMethod(ZipEntry.DEFLATED);
+ archiveEntry.getGeneralPurposeBit().useStrongEncryption(true);
+ ZipEntry copy = new ZipEntry(archiveEntry);
+ assertEquals(archiveEntry, copy);
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/zip/ZipLongTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/zip/ZipLongTest.java
new file mode 100644
index 00000000..a7ece044
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/zip/ZipLongTest.java
@@ -0,0 +1,94 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.zip;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * JUnit testcases for org.apache.tools.zip.ZipLong.
+ *
+ */
+public class ZipLongTest {
+
+ /**
+ * Test conversion to bytes.
+ */
+ @Test
+ public void testToBytes() {
+ ZipLong zl = new ZipLong(0x12345678);
+ byte[] result = zl.getBytes();
+ assertEquals("length getBytes", 4, result.length);
+ assertEquals("first byte getBytes", 0x78, result[0]);
+ assertEquals("second byte getBytes", 0x56, result[1]);
+ assertEquals("third byte getBytes", 0x34, result[2]);
+ assertEquals("fourth byte getBytes", 0x12, result[3]);
+ }
+
+ /**
+ * Test conversion from bytes.
+ */
+ @Test
+ public void testFromBytes() {
+ byte[] val = new byte[] {0x78, 0x56, 0x34, 0x12};
+ ZipLong zl = new ZipLong(val);
+ assertEquals("value from bytes", 0x12345678, zl.getValue());
+ }
+
+ /**
+ * Test the contract of the equals method.
+ */
+ @Test
+ public void testEquals() {
+ ZipLong zl = new ZipLong(0x12345678);
+ ZipLong zl2 = new ZipLong(0x12345678);
+ ZipLong zl3 = new ZipLong(0x87654321);
+
+ assertTrue("reflexive", zl.equals(zl));
+
+ assertTrue("works", zl.equals(zl2));
+ assertTrue("works, part two", !zl.equals(zl3));
+
+ assertTrue("symmetric", zl2.equals(zl));
+
+ assertTrue("null handling", !zl.equals(null));
+ assertTrue("non ZipLong handling", !zl.equals(new Integer(0x1234)));
+ }
+
+ /**
+ * Test sign handling.
+ */
+ @Test
+ public void testSign() {
+ ZipLong zl = new ZipLong(new byte[] {(byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF});
+ assertEquals(0x00000000FFFFFFFFl, zl.getValue());
+ }
+
+ @Test
+ public void testClone() {
+ ZipLong s1 = new ZipLong(42);
+ ZipLong s2 = (ZipLong) s1.clone();
+ assertNotSame(s1, s2);
+ assertEquals(s1, s2);
+ assertEquals(s1.getValue(), s2.getValue());
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/zip/ZipOutputStreamTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/zip/ZipOutputStreamTest.java
new file mode 100644
index 00000000..a69db6c1
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/zip/ZipOutputStreamTest.java
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.zip;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.Calendar;
+import java.util.Date;
+
+import static org.junit.Assert.assertEquals;
+
+public class ZipOutputStreamTest {
+
+ private Date time;
+ private ZipLong zl;
+
+ @Before
+ public void setUp() throws Exception {
+ time = new Date();
+ Calendar cal = Calendar.getInstance();
+ cal.setTime(time);
+ int year = cal.get(Calendar.YEAR);
+ int month = cal.get(Calendar.MONTH) + 1;
+ long value = ((year - 1980) << 25)
+ | (month << 21)
+ | (cal.get(Calendar.DAY_OF_MONTH) << 16)
+ | (cal.get(Calendar.HOUR_OF_DAY) << 11)
+ | (cal.get(Calendar.MINUTE) << 5)
+ | (cal.get(Calendar.SECOND) >> 1);
+
+ byte[] result = new byte[4];
+ result[0] = (byte) ((value & 0xFF));
+ result[1] = (byte) ((value & 0xFF00) >> 8);
+ result[2] = (byte) ((value & 0xFF0000) >> 16);
+ result[3] = (byte) ((value & 0xFF000000L) >> 24);
+ zl = new ZipLong(result);
+ }
+
+
+ @Test
+ public void testZipLong() throws Exception {
+ ZipLong test = ZipOutputStream.toDosTime(time);
+ assertEquals(test.getValue(), zl.getValue());
+ }
+
+ @Test
+ public void testAdjustToLong() {
+ assertEquals((long) Integer.MAX_VALUE,
+ ZipOutputStream.adjustToLong(Integer.MAX_VALUE));
+ assertEquals(((long) Integer.MAX_VALUE) + 1,
+ ZipOutputStream.adjustToLong(Integer.MAX_VALUE + 1));
+ assertEquals(2 * ((long) Integer.MAX_VALUE),
+ ZipOutputStream.adjustToLong(2 * Integer.MAX_VALUE));
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/zip/ZipShortTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/zip/ZipShortTest.java
new file mode 100644
index 00000000..a6aa3e78
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/apache/tools/zip/ZipShortTest.java
@@ -0,0 +1,92 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.zip;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * JUnit 3 testcases for org.apache.tools.zip.ZipShort.
+ *
+ */
+public class ZipShortTest {
+
+ /**
+ * Test conversion to bytes.
+ */
+ @Test
+ public void testToBytes() {
+ ZipShort zs = new ZipShort(0x1234);
+ byte[] result = zs.getBytes();
+ assertEquals("length getBytes", 2, result.length);
+ assertEquals("first byte getBytes", 0x34, result[0]);
+ assertEquals("second byte getBytes", 0x12, result[1]);
+ }
+
+ /**
+ * Test conversion from bytes.
+ */
+ @Test
+ public void testFromBytes() {
+ byte[] val = new byte[] {0x34, 0x12};
+ ZipShort zs = new ZipShort(val);
+ assertEquals("value from bytes", 0x1234, zs.getValue());
+ }
+
+ /**
+ * Test the contract of the equals method.
+ */
+ @Test
+ public void testEquals() {
+ ZipShort zs = new ZipShort(0x1234);
+ ZipShort zs2 = new ZipShort(0x1234);
+ ZipShort zs3 = new ZipShort(0x5678);
+
+ assertTrue("reflexive", zs.equals(zs));
+
+ assertTrue("works", zs.equals(zs2));
+ assertTrue("works, part two", !zs.equals(zs3));
+
+ assertTrue("symmetric", zs2.equals(zs));
+
+ assertTrue("null handling", !zs.equals(null));
+ assertTrue("non ZipShort handling", !zs.equals(new Integer(0x1234)));
+ }
+
+ /**
+ * Test sign handling.
+ */
+ @Test
+ public void testSign() {
+ ZipShort zs = new ZipShort(new byte[] {(byte)0xFF, (byte)0xFF});
+ assertEquals(0x0000FFFF, zs.getValue());
+ }
+
+ @Test
+ public void testClone() {
+ ZipShort s1 = new ZipShort(42);
+ ZipShort s2 = (ZipShort) s1.clone();
+ assertNotSame(s1, s2);
+ assertEquals(s1, s2);
+ assertEquals(s1.getValue(), s2.getValue());
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/example/junit/AbstractJUnit3TestMissed.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/example/junit/AbstractJUnit3TestMissed.java
new file mode 100644
index 00000000..fd261f5d
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/example/junit/AbstractJUnit3TestMissed.java
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.example.junit;
+
+import junit.framework.TestCase;
+
+public abstract class AbstractJUnit3TestMissed extends TestCase {
+
+ public void testNothing() {
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/example/junit/AbstractJUnit3TestNotMissed.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/example/junit/AbstractJUnit3TestNotMissed.java
new file mode 100644
index 00000000..e1d1c0b9
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/example/junit/AbstractJUnit3TestNotMissed.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.example.junit;
+
+import junit.framework.TestCase;
+
+public abstract class AbstractJUnit3TestNotMissed extends TestCase {
+
+ public void testNothing() {
+ }
+
+ public static class InnerAbstractTestNotMissed extends AbstractJUnit3TestNotMissed {
+
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/example/junit/AbstractTestMissed.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/example/junit/AbstractTestMissed.java
new file mode 100644
index 00000000..6724d5b8
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/example/junit/AbstractTestMissed.java
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.example.junit;
+
+import org.junit.Test;
+
+
+public abstract class AbstractTestMissed {
+
+ @Test
+ public void testNothing() {
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/example/junit/AbstractTestNotMissed.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/example/junit/AbstractTestNotMissed.java
new file mode 100644
index 00000000..9a77d1b7
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/example/junit/AbstractTestNotMissed.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.example.junit;
+
+import org.junit.Test;
+
+public abstract class AbstractTestNotMissed {
+
+ @Test
+ public void testNothing() {
+ }
+
+ public static class InnerAbstractTestNotMissed extends AbstractTestNotMissed {
+
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/example/junit/JUnit3NonTestMissed.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/example/junit/JUnit3NonTestMissed.java
new file mode 100644
index 00000000..76cead6c
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/example/junit/JUnit3NonTestMissed.java
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.example.junit;
+
+import junit.framework.TestCase;
+
+public class JUnit3NonTestMissed extends TestCase {
+
+ public void notATest() {
+ //this isn't a test but shouldn't case an error
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/example/junit/JUnit3TestNotMissed.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/example/junit/JUnit3TestNotMissed.java
new file mode 100644
index 00000000..1e5ac2de
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/example/junit/JUnit3TestNotMissed.java
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.example.junit;
+
+import junit.framework.TestCase;
+
+public class JUnit3TestNotMissed extends TestCase {
+
+ public void testNothing() {
+ // don't fail
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/example/junit/JUnit4Skippable.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/example/junit/JUnit4Skippable.java
new file mode 100644
index 00000000..aa89ab7d
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/example/junit/JUnit4Skippable.java
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.example.junit;
+
+import org.junit.Assume;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+public class JUnit4Skippable {
+
+ @Test
+ public void passingTest() {
+ assertTrue("This test passed", true);
+ }
+
+ @Ignore("Please don't ignore me!")
+ @Test
+ public void explicitIgnoreTest() {
+ fail("This test should be skipped");
+ }
+
+ @Test
+ public void implicitlyIgnoreTest() {
+ Assume.assumeFalse("This test will be ignored", true);
+ fail("I told you, this test should have been ignored!");
+ }
+
+ @Test
+ @Ignore
+ public void explicitlyIgnoreTestNoMessage() {
+ fail("This test should be skipped");
+ }
+
+ @Test
+ public void implicitlyIgnoreTestNoMessage() {
+ Assume.assumeFalse(true);
+ fail("I told you, this test should have been ignored!");
+ }
+
+ @Test
+ public void failingTest() {
+ fail("I told you this test was going to fail");
+ }
+
+ @Test
+ public void failingTestNoMessage() {
+ fail();
+ }
+
+ @Test
+ public void errorTest() {
+ throw new RuntimeException("Whoops, this test went wrong");
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/example/junit/MultilineAsserts.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/example/junit/MultilineAsserts.java
new file mode 100644
index 00000000..06e10390
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/example/junit/MultilineAsserts.java
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.example.junit;
+
+import junit.framework.TestCase;
+
+public class MultilineAsserts extends TestCase {
+ public void testFoo() { assertTrue("testFoo \nmessed up", false); }
+ public void testBar() { assertTrue("testBar \ndidn't work", true); }
+ public void testFee() { assertTrue("testFee \ncrashed", false); }
+ public void testFie() { assertTrue("testFie \nbroke", true); }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/example/junit/NonTestMissed.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/example/junit/NonTestMissed.java
new file mode 100644
index 00000000..0a020ec9
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/example/junit/NonTestMissed.java
@@ -0,0 +1,25 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.example.junit;
+
+public class NonTestMissed {
+
+ public void notATest() {
+ //this isn't a test but shouldn't case an error
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/example/junit/Output.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/example/junit/Output.java
new file mode 100644
index 00000000..a7135f7b
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/example/junit/Output.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.example.junit;
+
+import junit.framework.TestCase;
+
+/**
+ * Not really a test of Ant but a test that is run by the test of the
+ * junit task. Confused?
+ *
+ * @since Ant 1.5
+ */
+public class Output extends TestCase {
+
+ public Output(String s) {
+ super(s);
+ }
+
+ public void testOutput() {
+ System.out.println("foo");
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/example/junit/TestNotMissed.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/example/junit/TestNotMissed.java
new file mode 100644
index 00000000..6d3babeb
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/example/junit/TestNotMissed.java
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.example.junit;
+
+
+import org.junit.Test;
+
+public class TestNotMissed {
+
+ @Test
+ public void testNothing() {
+ // don't fail
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/example/junit/TestWithSuiteNotMissed.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/example/junit/TestWithSuiteNotMissed.java
new file mode 100644
index 00000000..80b722c2
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/example/junit/TestWithSuiteNotMissed.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.example.junit;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class TestWithSuiteNotMissed {
+
+ public static Test suite() {
+ TestSuite test = new TestSuite("meh");
+ JUnit3TestNotMissed testCase = new JUnit3TestNotMissed();
+ testCase.setName("testNothing");
+ test.addTest(testCase);
+ return test;
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/example/junit/ThreadedOutput.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/example/junit/ThreadedOutput.java
new file mode 100644
index 00000000..91f462a2
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/example/junit/ThreadedOutput.java
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.example.junit;
+
+import junit.framework.TestCase;
+
+/**
+ * Not really a test of Ant but a test that is run by the test of the
+ * junit task. Confused?
+ *
+ * @since Ant 1.5
+ */
+public class ThreadedOutput extends TestCase {
+
+ public ThreadedOutput(String s) {
+ super(s);
+ }
+
+ public void testOutput() throws InterruptedException {
+ Thread t = new Thread(new Runnable() {
+ public void run() {
+ System.out.println("foo");
+ }
+ });
+ t.start();
+ t.join();
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/example/junit/Timeout.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/example/junit/Timeout.java
new file mode 100644
index 00000000..6a42ee75
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/example/junit/Timeout.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.example.junit;
+
+import org.junit.After;
+import org.junit.Test;
+
+public class Timeout {
+ @Test
+ public void testTimeout() throws InterruptedException {
+ Thread.sleep(5000);
+ }
+ @After
+ public void tearDown() {
+ System.out.println("tearDown called on Timeout");
+ }
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/example/junit/XmlParserTest.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/example/junit/XmlParserTest.java
new file mode 100644
index 00000000..e5fae55f
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/example/junit/XmlParserTest.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.example.junit;
+
+import org.junit.Test;
+import org.xml.sax.SAXException;
+import org.xml.sax.XMLReader;
+import org.xml.sax.helpers.XMLReaderFactory;
+
+import static org.junit.Assert.assertNotNull;
+
+/**
+ * created Aug 12, 2004 1:39:59 PM
+ */
+
+public class XmlParserTest {
+
+
+ @Test
+ public void testXercesIsPresent() throws SAXException {
+ XMLReader xerces;
+ xerces = XMLReaderFactory.createXMLReader(
+ "org.apache.xerces.parsers.SAXParser");
+ assertNotNull(xerces);
+ }
+
+ @Test
+ public void testXercesHandlesSchema() throws SAXException {
+ XMLReader xerces;
+ xerces = XMLReaderFactory.createXMLReader("org.apache.xerces.parsers.SAXParser");
+ xerces.setFeature("http://apache.org/xml/features/validation/schema",
+ true);
+ }
+
+ @Test
+ public void testParserHandlesSchema() throws SAXException {
+ XMLReader xerces;
+ xerces = XMLReaderFactory.createXMLReader();
+ xerces.setFeature("http://apache.org/xml/features/validation/schema",
+ true);
+ }
+
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/example/tasks/TaskdefTestContainerTask.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/example/tasks/TaskdefTestContainerTask.java
new file mode 100644
index 00000000..a566d5c1
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/example/tasks/TaskdefTestContainerTask.java
@@ -0,0 +1,25 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.example.tasks;
+
+import org.apache.tools.ant.taskdefs.Sequential;
+
+public class TaskdefTestContainerTask extends Sequential {
+ public TaskdefTestContainerTask() {}
+}
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/example/tasks/TaskdefTestSimpleTask.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/example/tasks/TaskdefTestSimpleTask.java
new file mode 100644
index 00000000..bce8cd50
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/example/tasks/TaskdefTestSimpleTask.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.example.tasks;
+
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+
+public class TaskdefTestSimpleTask extends Task {
+
+ public class Echo {
+ Echo() {}
+ private String message = null;
+ public void setMessage(String s) {message = s;}
+ }
+
+ public TaskdefTestSimpleTask() {}
+
+ private Echo echo;
+ public Echo createEcho() {
+ echo = new Echo();
+ return echo;
+ }
+
+ public void execute() {
+ log("simpletask: "+echo.message, Project.MSG_INFO);
+ }
+
+}
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/example/tasks/antlib.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/example/tasks/antlib.xml
new file mode 100644
index 00000000..b920da7e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/example/tasks/antlib.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<antlib>
+<macrodef name="simple">
+ <element name="some-tasks" optional="yes" implicit="yes"/>
+ <sequential>
+ <some-tasks/>
+ </sequential>
+</macrodef>
+</antlib>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/example/tasks/antlib2.xml b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/example/tasks/antlib2.xml
new file mode 100644
index 00000000..b920da7e
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/example/tasks/antlib2.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<antlib>
+<macrodef name="simple">
+ <element name="some-tasks" optional="yes" implicit="yes"/>
+ <sequential>
+ <some-tasks/>
+ </sequential>
+</macrodef>
+</antlib>
+
diff --git a/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/example/types/TypedefTestType.java b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/example/types/TypedefTestType.java
new file mode 100644
index 00000000..235b76f6
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/tests/junit/org/example/types/TypedefTestType.java
@@ -0,0 +1,25 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.example.types;
+
+import org.apache.tools.ant.ProjectComponent;
+
+public class TypedefTestType extends ProjectComponent {
+}
+
diff --git a/framework/src/maven/apache-maven-3.3.3/DEPENDENCIES b/framework/src/maven/apache-maven-3.3.3/DEPENDENCIES
new file mode 100644
index 00000000..434a38eb
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/DEPENDENCIES
@@ -0,0 +1,111 @@
+// ------------------------------------------------------------------
+// Transitive dependencies of this project determined from the
+// maven pom organized by organization.
+// ------------------------------------------------------------------
+
+Apache Maven Distribution
+
+
+From: 'an unknown organization'
+ - AOP alliance (http://aopalliance.sourceforge.net) aopalliance:aopalliance:jar:1.0
+ License: Public Domain
+ - Guava: Google Core Libraries for Java (http://code.google.com/p/guava-libraries/guava) com.google.guava:guava:bundle:18.0
+ License: The Apache Software License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0.txt)
+ - JSR-250 Common Annotations for the JavaTM Platform (http://jcp.org/aboutJava/communityprocess/final/jsr250/index.html) javax.annotation:jsr250-api:jar:1.0
+ License: COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 (https://glassfish.dev.java.net/public/CDDLv1.0.html)
+ - javax.inject (http://code.google.com/p/atinject/) javax.inject:javax.inject:jar:1
+ License: The Apache Software License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0.txt)
+ - Plexus Cipher: encryption/decryption Component (http://spice.sonatype.org/plexus-cipher) org.sonatype.plexus:plexus-cipher:jar:1.7
+ License: Apache Public License 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
+ - Plexus Security Dispatcher Component (http://spice.sonatype.org/plexus-sec-dispatcher) org.sonatype.plexus:plexus-sec-dispatcher:jar:1.3
+ License: Apache Public License 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
+
+From: 'Codehaus' (http://www.codehaus.org/)
+ - Plexus Classworlds (http://plexus.codehaus.org/plexus-classworlds/) org.codehaus.plexus:plexus-classworlds:bundle:2.5.2
+ License: The Apache Software License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0.txt)
+ - Plexus :: Component Annotations (http://plexus.codehaus.org/plexus-containers/plexus-component-annotations/) org.codehaus.plexus:plexus-component-annotations:jar:1.5.5
+ License: The Apache Software License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0.txt)
+ - Plexus Interpolation API (http://plexus.codehaus.org/plexus-components/plexus-interpolation) org.codehaus.plexus:plexus-interpolation:jar:1.21
+ License: The Apache Software License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0.txt)
+ - Plexus Common Utilities (http://plexus.codehaus.org/plexus-utils) org.codehaus.plexus:plexus-utils:jar:3.0.20
+ License: The Apache Software License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0.txt)
+
+From: 'Google, Inc.' (http://www.google.com)
+ - Sisu Guice - Core Library (https://github.com/google/guice/sisu-guice) org.sonatype.sisu:sisu-guice:jar:3.2.5
+ License: The Apache Software License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0.txt)
+
+From: 'Jonathan Hedley' (http://jonathanhedley.com/)
+ - jsoup (http://jsoup.org/) org.jsoup:jsoup:jar:1.7.2
+ License: The MIT License (http://jsoup.com/license)
+
+From: 'QOS.ch' (http://www.qos.ch)
+ - SLF4J API Module (http://www.slf4j.org) org.slf4j:slf4j-api:jar:1.7.5
+ License: MIT License (http://www.opensource.org/licenses/mit-license.php)
+ - SLF4J Simple Binding (http://www.slf4j.org) org.slf4j:slf4j-simple:jar:1.7.5
+ License: MIT License (http://www.opensource.org/licenses/mit-license.php)
+
+From: 'Seam Framework' (http://seamframework.org)
+ - CDI APIs (http://www.seamframework.org/Weld/cdi-api) javax.enterprise:cdi-api:jar:1.0
+ License: Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
+
+From: 'The Apache Software Foundation' (http://www.apache.org/)
+ - Commons CLI (http://commons.apache.org/cli/) commons-cli:commons-cli:jar:1.2
+ License: The Apache Software License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0.txt)
+ - Commons IO (http://commons.apache.org/io/) commons-io:commons-io:jar:2.2
+ License: The Apache Software License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0.txt)
+ - Commons Lang (http://commons.apache.org/lang/) commons-lang:commons-lang:jar:2.6
+ License: The Apache Software License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0.txt)
+ - Maven Aether Provider (http://maven.apache.org/ref/3.3.3/maven-aether-provider) org.apache.maven:maven-aether-provider:jar:3.3.3
+ License: Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0.txt)
+ - Maven Artifact (http://maven.apache.org/ref/3.3.3/maven-artifact) org.apache.maven:maven-artifact:jar:3.3.3
+ License: Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0.txt)
+ - Maven Builder Support (http://maven.apache.org/ref/3.3.3/maven-builder-support) org.apache.maven:maven-builder-support:jar:3.3.3
+ License: Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0.txt)
+ - Maven Compat (http://maven.apache.org/ref/3.3.3/maven-compat) org.apache.maven:maven-compat:jar:3.3.3
+ License: Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0.txt)
+ - Maven Core (http://maven.apache.org/ref/3.3.3/maven-core) org.apache.maven:maven-core:jar:3.3.3
+ License: Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0.txt)
+ - Maven Embedder (http://maven.apache.org/ref/3.3.3/maven-embedder) org.apache.maven:maven-embedder:jar:3.3.3
+ License: Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0.txt)
+ - Maven Model (http://maven.apache.org/ref/3.3.3/maven-model) org.apache.maven:maven-model:jar:3.3.3
+ License: Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0.txt)
+ - Maven Model Builder (http://maven.apache.org/ref/3.3.3/maven-model-builder) org.apache.maven:maven-model-builder:jar:3.3.3
+ License: Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0.txt)
+ - Maven Plugin API (http://maven.apache.org/ref/3.3.3/maven-plugin-api) org.apache.maven:maven-plugin-api:jar:3.3.3
+ License: Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0.txt)
+ - Maven Repository Metadata Model (http://maven.apache.org/ref/3.3.3/maven-repository-metadata) org.apache.maven:maven-repository-metadata:jar:3.3.3
+ License: Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0.txt)
+ - Maven Settings (http://maven.apache.org/ref/3.3.3/maven-settings) org.apache.maven:maven-settings:jar:3.3.3
+ License: Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0.txt)
+ - Maven Settings Builder (http://maven.apache.org/ref/3.3.3/maven-settings-builder) org.apache.maven:maven-settings-builder:jar:3.3.3
+ License: Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0.txt)
+ - Apache Maven Wagon :: Providers :: File Provider (http://maven.apache.org/wagon/wagon-providers/wagon-file) org.apache.maven.wagon:wagon-file:jar:2.9
+ License: Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0.txt)
+ - Apache Maven Wagon :: Providers :: HTTP Provider (http://maven.apache.org/wagon/wagon-providers/wagon-http) org.apache.maven.wagon:wagon-http:jar:2.9
+ License: Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0.txt)
+ - Apache Maven Wagon :: Providers :: HTTP Shared Library (http://maven.apache.org/wagon/wagon-providers/wagon-http-shared) org.apache.maven.wagon:wagon-http-shared:jar:2.9
+ License: Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0.txt)
+ - Apache Maven Wagon :: API (http://maven.apache.org/wagon/wagon-provider-api) org.apache.maven.wagon:wagon-provider-api:jar:2.9
+ License: Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0.txt)
+
+From: 'The Eclipse Foundation' (http://www.eclipse.org/)
+ - Aether API (http://www.eclipse.org/aether/aether-api/) org.eclipse.aether:aether-api:jar:1.0.2.v20150114
+ License: Eclipse Public License, Version 1.0 (http://www.eclipse.org/legal/epl-v10.html)
+ - Aether Connector Basic (http://www.eclipse.org/aether/aether-connector-basic/) org.eclipse.aether:aether-connector-basic:jar:1.0.2.v20150114
+ License: Eclipse Public License, Version 1.0 (http://www.eclipse.org/legal/epl-v10.html)
+ - Aether Implementation (http://www.eclipse.org/aether/aether-impl/) org.eclipse.aether:aether-impl:jar:1.0.2.v20150114
+ License: Eclipse Public License, Version 1.0 (http://www.eclipse.org/legal/epl-v10.html)
+ - Aether SPI (http://www.eclipse.org/aether/aether-spi/) org.eclipse.aether:aether-spi:jar:1.0.2.v20150114
+ License: Eclipse Public License, Version 1.0 (http://www.eclipse.org/legal/epl-v10.html)
+ - Aether Transport Wagon (http://www.eclipse.org/aether/aether-transport-wagon/) org.eclipse.aether:aether-transport-wagon:jar:1.0.2.v20150114
+ License: Eclipse Public License, Version 1.0 (http://www.eclipse.org/legal/epl-v10.html)
+ - Aether Utilities (http://www.eclipse.org/aether/aether-util/) org.eclipse.aether:aether-util:jar:1.0.2.v20150114
+ License: Eclipse Public License, Version 1.0 (http://www.eclipse.org/legal/epl-v10.html)
+ - org.eclipse.sisu.inject (http://www.eclipse.org/sisu/org.eclipse.sisu.inject/) org.eclipse.sisu:org.eclipse.sisu.inject:eclipse-plugin:0.3.0
+ License: Eclipse Public License, Version 1.0 (http://www.eclipse.org/legal/epl-v10.html)
+ - org.eclipse.sisu.plexus (http://www.eclipse.org/sisu/org.eclipse.sisu.plexus/) org.eclipse.sisu:org.eclipse.sisu.plexus:eclipse-plugin:0.3.0
+ License: Eclipse Public License, Version 1.0 (http://www.eclipse.org/legal/epl-v10.html)
+
+
+
+
diff --git a/framework/src/maven/apache-maven-3.3.3/LICENSE b/framework/src/maven/apache-maven-3.3.3/LICENSE
new file mode 100644
index 00000000..d6456956
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/LICENSE
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/framework/src/maven/apache-maven-3.3.3/NOTICE b/framework/src/maven/apache-maven-3.3.3/NOTICE
new file mode 100644
index 00000000..9485054b
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/NOTICE
@@ -0,0 +1,5 @@
+Apache Maven
+Copyright 2001-2015 The Apache Software Foundation
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
diff --git a/framework/src/maven/apache-maven-3.3.3/README.md b/framework/src/maven/apache-maven-3.3.3/README.md
new file mode 100644
index 00000000..b030c448
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/README.md
@@ -0,0 +1,23 @@
+# Maven
+
+Maven is available under the [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.txt)
+
+- [Maven Issue Tracker](http://jira.codehaus.org/browse/MNG)
+- [Maven Wiki](https://cwiki.apache.org/confluence/display/MAVEN/Index)
+- [Building Maven](http://maven.apache.org/guides/development/guide-building-m2.html)
+- [Running Core ITs](http://maven.apache.org/core-its/core-it-suite/)
+
+## Bootstrapping Basics
+
+If you want to bootstrap Maven, you'll need:
+
+- Java 1.7+
+- Ant 1.8 or later
+
+Run Ant, specifying a location into which the completed Maven distro should be installed:
+
+```
+ant -Dmaven.home="$HOME/apps/maven/apache-maven-3.3.x-SNAPSHOT"
+```
+
+Once the build completes, you should have a new Maven distro ready to roll in that directory!
diff --git a/framework/src/maven/apache-maven-3.3.3/apache-maven/README.txt b/framework/src/maven/apache-maven-3.3.3/apache-maven/README.txt
new file mode 100644
index 00000000..b05080d6
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/apache-maven/README.txt
@@ -0,0 +1,79 @@
+
+ Apache Maven
+
+ What is it?
+ -----------
+
+ Maven is a software project management and comprehension tool. Based on
+ the concept of a Project Object Model (POM), Maven can manage a project's
+ build, reporting and documentation from a central piece of information.
+
+ Documentation
+ -------------
+
+ The most up-to-date documentation can be found at http://maven.apache.org/.
+
+ Release Notes
+ -------------
+
+ The full list of changes can be found at http://maven.apache.org/release-notes.html.
+
+ System Requirements
+ -------------------
+
+ JDK:
+ 1.7 or above (this is to execute Maven - it still allows you to build against 1.3
+ and prior JDK's).
+ Memory:
+ No minimum requirement.
+ Disk:
+ Approximately 10MB is required for the Maven installation itself. In addition to
+ that, additional disk space will be used for your local Maven repository. The size
+ of your local repository will vary depending on usage but expect at least 500MB.
+ Operating System:
+ Windows:
+ Windows 2000 or above.
+ Unix based systems (Linux, Solaris and Mac OS X) and others:
+ No minimum requirement.
+
+ Installing Maven
+ ----------------
+
+ 1) Unpack the archive where you would like to store the binaries, eg:
+
+ Unix-based operating systems (Linux, Solaris and Mac OS X)
+ tar zxvf apache-maven-3.x.y.tar.gz
+ Windows
+ unzip apache-maven-3.x.y.zip
+
+ 2) A directory called "apache-maven-3.x.y" will be created.
+
+ 3) Add the bin directory to your PATH, eg:
+
+ Unix-based operating systems (Linux, Solaris and Mac OS X)
+ export PATH=/usr/local/apache-maven-3.x.y/bin:$PATH
+ Windows
+ set PATH="c:\program files\apache-maven-3.x.y\bin";%PATH%
+
+ 4) Make sure JAVA_HOME is set to the location of your JDK
+
+ 5) Run "mvn --version" to verify that it is correctly installed.
+
+ For complete documentation, see http://maven.apache.org/download.html#Installation
+
+ Licensing
+ ---------
+
+ Please see the file called LICENSE.
+
+ Maven URLS
+ ----------
+
+ Home Page: http://maven.apache.org/
+ Downloads: http://maven.apache.org/download.html
+ Release Notes: http://maven.apache.org/release-notes.html
+ Mailing Lists: http://maven.apache.org/mail-lists.html
+ Source Code: https://git-wip-us.apache.org/repos/asf/maven.git/apache-maven
+ Issue Tracking: http://jira.codehaus.org/browse/MNG
+ Wiki: https://cwiki.apache.org/confluence/display/MAVEN/
+ Available Plugins: http://maven.apache.org/plugins/index.html
diff --git a/framework/src/maven/apache-maven-3.3.3/apache-maven/pom.xml b/framework/src/maven/apache-maven-3.3.3/apache-maven/pom.xml
new file mode 100644
index 00000000..89a41833
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/apache-maven/pom.xml
@@ -0,0 +1,216 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+ <!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to you under the Apache License, Version
+ 2.0 (the "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0 Unless required by
+ applicable law or agreed to in writing, software distributed under
+ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
+ OR CONDITIONS OF ANY KIND, either express or implied. See the
+ License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven</artifactId>
+ <version>3.3.3</version>
+ </parent>
+
+ <artifactId>apache-maven</artifactId>
+ <packaging>pom</packaging>
+
+ <name>Apache Maven Distribution</name>
+ <description>The Apache Maven distribution, source and binary, in zip and tar.gz formats.</description>
+
+ <properties>
+ <distributionFileName>${distributionId}-${project.version}</distributionFileName>
+ </properties>
+
+ <scm><!-- remove when git scm url format can accept artifact-id at the end, as automatically inherited -->
+ <connection>scm:git:https://git-wip-us.apache.org/repos/asf/maven.git</connection>
+ <developerConnection>scm:git:https://git-wip-us.apache.org/repos/asf/maven.git</developerConnection>
+ <tag>maven-3.3.3</tag>
+ </scm>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-embedder</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-compat</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.sisu</groupId>
+ <artifactId>org.eclipse.sisu.plexus</artifactId>
+ </dependency>
+ <!-- CLI -->
+ <dependency>
+ <groupId>commons-cli</groupId>
+ <artifactId>commons-cli</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.wagon</groupId>
+ <artifactId>wagon-http</artifactId>
+ <classifier>shaded</classifier>
+ <exclusions>
+ <exclusion>
+ <groupId>org.apache.maven.wagon</groupId>
+ <artifactId>wagon-http-shared4</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.apache.httpcomponents</groupId>
+ <artifactId>httpclient</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.apache.httpcomponents</groupId>
+ <artifactId>httpcore</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.wagon</groupId>
+ <artifactId>wagon-file</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.aether</groupId>
+ <artifactId>aether-connector-basic</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.aether</groupId>
+ <artifactId>aether-transport-wagon</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-simple</artifactId>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <finalName>${distributionFileName}</finalName>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-remote-resources-plugin</artifactId>
+ <version>1.5</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.rat</groupId>
+ <artifactId>apache-rat-plugin</artifactId>
+ <configuration>
+ <excludes combine.children="append">
+ <exclude>src/bin/m2.conf</exclude>
+ </excludes>
+ </configuration>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>test-compile</id>
+ <goals>
+ <goal>testCompile</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <systemProperties>
+ <property>
+ <name>basedir</name>
+ <value>${basedir}</value>
+ </property>
+ </systemProperties>
+ </configuration>
+ <executions>
+ <execution>
+ <id>test</id>
+ <goals>
+ <goal>test</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>create-distro</id>
+ <phase>package</phase>
+ <goals>
+ <goal>single</goal>
+ </goals>
+ <configuration>
+ <descriptors>
+ <descriptor>src/main/assembly/bin.xml</descriptor>
+ </descriptors>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+ <pluginRepositories>
+ <pluginRepository>
+ <id>apache.snapshots</id>
+ <url>http://repository.apache.org/snapshots/</url>
+ <snapshots>
+ <enabled>true</enabled>
+ </snapshots>
+ <releases>
+ <enabled>false</enabled>
+ </releases>
+ </pluginRepository>
+ </pluginRepositories>
+
+ <profiles>
+ <profile>
+ <id>apache-release</id>
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>make-src-assembly</id>
+ <phase>package</phase>
+ <goals>
+ <goal>single</goal>
+ </goals>
+ <configuration>
+ <descriptors>
+ <descriptor>src/main/assembly/src.xml</descriptor>
+ </descriptors>
+ <tarLongFileMode>gnu</tarLongFileMode>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/apache-maven/src/bin/m2.conf b/framework/src/maven/apache-maven-3.3.3/apache-maven/src/bin/m2.conf
new file mode 100644
index 00000000..2991e0b3
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/apache-maven/src/bin/m2.conf
@@ -0,0 +1,8 @@
+main is org.apache.maven.cli.MavenCli from plexus.core
+
+set maven.home default ${user.home}/m2
+
+[plexus.core]
+optionally ${maven.home}/lib/ext/*.jar
+load ${maven.home}/lib/*.jar
+load ${maven.home}/conf/logging
diff --git a/framework/src/maven/apache-maven-3.3.3/apache-maven/src/bin/mvn b/framework/src/maven/apache-maven-3.3.3/apache-maven/src/bin/mvn
new file mode 100755
index 00000000..902de4af
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/apache-maven/src/bin/mvn
@@ -0,0 +1,232 @@
+#!/bin/sh
+# ----------------------------------------------------------------------------
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+# ----------------------------------------------------------------------------
+
+# ----------------------------------------------------------------------------
+# Maven2 Start Up Batch script
+#
+# Required ENV vars:
+# ------------------
+# JAVA_HOME - location of a JDK home dir
+#
+# Optional ENV vars
+# -----------------
+# M2_HOME - location of maven2's installed home dir
+# MAVEN_OPTS - parameters passed to the Java VM when running Maven
+# e.g. to debug Maven itself, use
+# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
+# MAVEN_SKIP_RC - flag to disable loading of mavenrc files
+# ----------------------------------------------------------------------------
+
+if [ -z "$MAVEN_SKIP_RC" ] ; then
+
+ if [ -f /etc/mavenrc ] ; then
+ . /etc/mavenrc
+ fi
+
+ if [ -f "$HOME/.mavenrc" ] ; then
+ . "$HOME/.mavenrc"
+ fi
+
+fi
+
+# OS specific support. $var _must_ be set to either true or false.
+cygwin=false;
+darwin=false;
+mingw=false
+case "`uname`" in
+ CYGWIN*) cygwin=true ;;
+ MINGW*) mingw=true;;
+ Darwin*) darwin=true
+ #
+ # Look for the Apple JDKs first to preserve the existing behaviour, and then look
+ # for the new JDKs provided by Oracle.
+ #
+ if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK ] ; then
+ #
+ # Apple JDKs
+ #
+ export JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home
+ fi
+
+ if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Java/JavaVirtualMachines/CurrentJDK ] ; then
+ #
+ # Apple JDKs
+ #
+ export JAVA_HOME=/System/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home
+ fi
+
+ if [ -z "$JAVA_HOME" ] && [ -L "/Library/Java/JavaVirtualMachines/CurrentJDK" ] ; then
+ #
+ # Oracle JDKs
+ #
+ export JAVA_HOME=/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home
+ fi
+
+ if [ -z "$JAVA_HOME" ] && [ -x "/usr/libexec/java_home" ]; then
+ #
+ # Apple JDKs
+ #
+ export JAVA_HOME=`/usr/libexec/java_home`
+ fi
+ ;;
+esac
+
+if [ -z "$JAVA_HOME" ] ; then
+ if [ -r /etc/gentoo-release ] ; then
+ JAVA_HOME=`java-config --jre-home`
+ fi
+fi
+
+if [ -z "$M2_HOME" ] ; then
+ ## resolve links - $0 may be a link to maven's home
+ PRG="$0"
+
+ # need this for relative symlinks
+ while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG="`dirname "$PRG"`/$link"
+ fi
+ done
+
+ saveddir=`pwd`
+
+ M2_HOME=`dirname "$PRG"`/..
+
+ # make it fully qualified
+ M2_HOME=`cd "$M2_HOME" && pwd`
+
+ cd "$saveddir"
+ # echo Using m2 at $M2_HOME
+fi
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched
+if $cygwin ; then
+ [ -n "$M2_HOME" ] &&
+ M2_HOME=`cygpath --unix "$M2_HOME"`
+ [ -n "$JAVA_HOME" ] &&
+ JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+ [ -n "$CLASSPATH" ] &&
+ CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
+fi
+
+# For Migwn, ensure paths are in UNIX format before anything is touched
+if $mingw ; then
+ [ -n "$M2_HOME" ] &&
+ M2_HOME="`(cd "$M2_HOME"; pwd)`"
+ [ -n "$JAVA_HOME" ] &&
+ JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
+ # TODO classpath?
+fi
+
+if [ -z "$JAVA_HOME" ]; then
+ javaExecutable="`which javac`"
+ if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
+ # readlink(1) is not available as standard on Solaris 10.
+ readLink=`which readlink`
+ if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
+ if $darwin ; then
+ javaHome="`dirname \"$javaExecutable\"`"
+ javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
+ else
+ javaExecutable="`readlink -f \"$javaExecutable\"`"
+ fi
+ javaHome="`dirname \"$javaExecutable\"`"
+ javaHome=`expr "$javaHome" : '\(.*\)/bin'`
+ JAVA_HOME="$javaHome"
+ export JAVA_HOME
+ fi
+ fi
+fi
+
+if [ -z "$JAVACMD" ] ; then
+ if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ else
+ JAVACMD="`which java`"
+ fi
+fi
+
+if [ ! -x "$JAVACMD" ] ; then
+ echo "Error: JAVA_HOME is not defined correctly." >&2
+ echo " We cannot execute $JAVACMD" >&2
+ exit 1
+fi
+
+if [ -z "$JAVA_HOME" ] ; then
+ echo "Warning: JAVA_HOME environment variable is not set."
+fi
+
+CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin; then
+ [ -n "$M2_HOME" ] &&
+ M2_HOME=`cygpath --path --windows "$M2_HOME"`
+ [ -n "$JAVA_HOME" ] &&
+ JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
+ [ -n "$CLASSPATH" ] &&
+ CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
+fi
+
+# traverses directory structure from process work directory to filesystem root
+# first directory with .mvn subdirectory is considered project base directory
+find_maven_basedir() {
+ local basedir=$(pwd)
+ local wdir=$(pwd)
+ while [ "$wdir" != '/' ] ; do
+ wdir=$(cd "$wdir/.."; pwd)
+ if [ -d "$wdir"/.mvn ] ; then
+ basedir=$wdir
+ break
+ fi
+ done
+ echo "${basedir}"
+}
+
+# concatenates all lines of a file
+concat_lines() {
+ if [ -f "$1" ]; then
+ echo "$(tr -s '\n' ' ' < "$1")"
+ fi
+}
+
+export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-$(find_maven_basedir)}
+MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
+
+# Provide a "standardized" way to retrieve the CLI args that will
+# work with both Windows and non-Windows executions.
+MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@"
+export MAVEN_CMD_LINE_ARGS
+
+exec "$JAVACMD" \
+ $MAVEN_OPTS \
+ -classpath "${M2_HOME}"/boot/plexus-classworlds-*.jar \
+ "-Dclassworlds.conf=${M2_HOME}/bin/m2.conf" \
+ "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
+ ${CLASSWORLDS_LAUNCHER} "$@"
diff --git a/framework/src/maven/apache-maven-3.3.3/apache-maven/src/bin/mvn.cmd b/framework/src/maven/apache-maven-3.3.3/apache-maven/src/bin/mvn.cmd
new file mode 100644
index 00000000..4fad0939
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/apache-maven/src/bin/mvn.cmd
@@ -0,0 +1,176 @@
+@REM ----------------------------------------------------------------------------
+@REM Licensed to the Apache Software Foundation (ASF) under one
+@REM or more contributor license agreements. See the NOTICE file
+@REM distributed with this work for additional information
+@REM regarding copyright ownership. The ASF licenses this file
+@REM to you under the Apache License, Version 2.0 (the
+@REM "License"); you may not use this file except in compliance
+@REM with the License. You may obtain a copy of the License at
+@REM
+@REM http://www.apache.org/licenses/LICENSE-2.0
+@REM
+@REM Unless required by applicable law or agreed to in writing,
+@REM software distributed under the License is distributed on an
+@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+@REM KIND, either express or implied. See the License for the
+@REM specific language governing permissions and limitations
+@REM under the License.
+@REM ----------------------------------------------------------------------------
+
+@REM ----------------------------------------------------------------------------
+@REM Maven2 Start Up Batch script
+@REM
+@REM Required ENV vars:
+@REM JAVA_HOME - location of a JDK home dir
+@REM
+@REM Optional ENV vars
+@REM M2_HOME - location of maven2's installed home dir
+@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
+@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending
+@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
+@REM e.g. to debug Maven itself, use
+@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
+@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
+@REM ----------------------------------------------------------------------------
+
+@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
+@echo off
+@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on'
+@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
+
+@REM set %HOME% to equivalent of $HOME
+if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
+
+@REM Execute a user defined script before this one
+if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
+@REM check for pre script, once with legacy .bat ending and once with .cmd ending
+if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
+if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
+:skipRcPre
+
+@setlocal
+
+set ERROR_CODE=0
+
+@REM To isolate internal variables from possible post scripts, we use another setlocal
+@setlocal
+
+@REM ==== START VALIDATION ====
+if not "%JAVA_HOME%" == "" goto OkJHome
+
+echo.
+echo Error: JAVA_HOME not found in your environment. >&2
+echo Please set the JAVA_HOME variable in your environment to match the >&2
+echo location of your Java installation. >&2
+echo.
+goto error
+
+:OkJHome
+if exist "%JAVA_HOME%\bin\java.exe" goto chkMHome
+
+echo.
+echo Error: JAVA_HOME is set to an invalid directory. >&2
+echo JAVA_HOME = "%JAVA_HOME%" >&2
+echo Please set the JAVA_HOME variable in your environment to match the >&2
+echo location of your Java installation. >&2
+echo.
+goto error
+
+:chkMHome
+if not "%M2_HOME%"=="" goto valMHome
+
+SET "M2_HOME=%~dp0.."
+if not "%M2_HOME%"=="" goto valMHome
+
+echo.
+echo Error: M2_HOME not found in your environment. >&2
+echo Please set the M2_HOME variable in your environment to match the >&2
+echo location of the Maven installation. >&2
+echo.
+goto error
+
+:valMHome
+
+:stripMHome
+if not "_%M2_HOME:~-1%"=="_\" goto checkMCmd
+set "M2_HOME=%M2_HOME:~0,-1%"
+goto stripMHome
+
+:checkMCmd
+if exist "%M2_HOME%\bin\mvn.cmd" goto init
+
+echo.
+echo Error: M2_HOME is set to an invalid directory. >&2
+echo M2_HOME = "%M2_HOME%" >&2
+echo Please set the M2_HOME variable in your environment to match the >&2
+echo location of the Maven installation >&2
+echo.
+goto error
+@REM ==== END VALIDATION ====
+
+:init
+
+set MAVEN_CMD_LINE_ARGS=%*
+
+@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
+@REM Fallback to current working directory if not found.
+
+set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
+IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
+
+set EXEC_DIR=%CD%
+set WDIR=%EXEC_DIR%
+:findBaseDir
+IF EXIST "%WDIR%"\.mvn goto baseDirFound
+cd ..
+IF "%WDIR%"=="%CD%" goto baseDirNotFound
+set WDIR=%CD%
+goto findBaseDir
+
+:baseDirFound
+set MAVEN_PROJECTBASEDIR=%WDIR%
+cd "%EXEC_DIR%"
+goto endDetectBaseDir
+
+:baseDirNotFound
+set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
+cd "%EXEC_DIR%"
+
+:endDetectBaseDir
+
+IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
+
+@setlocal EnableExtensions EnableDelayedExpansion
+for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
+@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
+
+:endReadAdditionalConfig
+
+SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
+
+for %%i in ("%M2_HOME%"\boot\plexus-classworlds-*) do set CLASSWORLDS_JAR="%%i"
+
+set CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
+
+%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %CLASSWORLDS_JAR% "-Dclassworlds.conf=%M2_HOME%\bin\m2.conf" "-Dmaven.home=%M2_HOME%" "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %CLASSWORLDS_LAUNCHER% %MAVEN_CMD_LINE_ARGS%
+if ERRORLEVEL 1 goto error
+goto end
+
+:error
+set ERROR_CODE=1
+
+:end
+@endlocal & set ERROR_CODE=%ERROR_CODE%
+
+if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
+@REM check for post script, once with legacy .bat ending and once with .cmd ending
+if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
+if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
+:skipRcPost
+
+@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
+if "%MAVEN_BATCH_PAUSE%" == "on" pause
+
+if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
+
+exit /B %ERROR_CODE%
diff --git a/framework/src/maven/apache-maven-3.3.3/apache-maven/src/bin/mvnDebug b/framework/src/maven/apache-maven-3.3.3/apache-maven/src/bin/mvnDebug
new file mode 100755
index 00000000..73905fdf
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/apache-maven/src/bin/mvnDebug
@@ -0,0 +1,41 @@
+#!/bin/sh
+# ----------------------------------------------------------------------------
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+# ----------------------------------------------------------------------------
+
+# ----------------------------------------------------------------------------
+# Maven2 Start Up Batch script
+#
+# Required ENV vars:
+# ------------------
+# JAVA_HOME - location of a JDK home dir
+#
+# Optional ENV vars
+# -----------------
+# M2_HOME - location of maven2's installed home dir
+# MAVEN_OPTS - parameters passed to the Java VM when running Maven
+# e.g. to debug Maven itself, use
+# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
+# MAVEN_SKIP_RC - flag to disable loading of mavenrc files
+# ----------------------------------------------------------------------------
+
+MAVEN_DEBUG_OPTS="-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000"
+
+echo Preparing to Execute Maven in Debug Mode
+
+env MAVEN_OPTS="$MAVEN_OPTS $MAVEN_DEBUG_OPTS" $(dirname $0)/mvn "$@"
diff --git a/framework/src/maven/apache-maven-3.3.3/apache-maven/src/bin/mvnDebug.cmd b/framework/src/maven/apache-maven-3.3.3/apache-maven/src/bin/mvnDebug.cmd
new file mode 100644
index 00000000..1f0d3bfb
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/apache-maven/src/bin/mvnDebug.cmd
@@ -0,0 +1,31 @@
+@REM ----------------------------------------------------------------------------
+@REM Licensed to the Apache Software Foundation (ASF) under one
+@REM or more contributor license agreements. See the NOTICE file
+@REM distributed with this work for additional information
+@REM regarding copyright ownership. The ASF licenses this file
+@REM to you under the Apache License, Version 2.0 (the
+@REM "License"); you may not use this file except in compliance
+@REM with the License. You may obtain a copy of the License at
+@REM
+@REM http://www.apache.org/licenses/LICENSE-2.0
+@REM
+@REM Unless required by applicable law or agreed to in writing,
+@REM software distributed under the License is distributed on an
+@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+@REM KIND, either express or implied. See the License for the
+@REM specific language governing permissions and limitations
+@REM under the License.
+@REM ----------------------------------------------------------------------------
+
+@REM ----------------------------------------------------------------------------
+@REM Maven2 Start Up Batch script to run mvn.cmd with the following additional
+@REM Java VM settings:
+@REM
+@REM -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
+@REM
+@REM ----------------------------------------------------------------------------
+
+@setlocal
+@set MAVEN_DEBUG_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
+
+@call "%~dp0"mvn.cmd %*
diff --git a/framework/src/maven/apache-maven-3.3.3/apache-maven/src/bin/mvnyjp b/framework/src/maven/apache-maven-3.3.3/apache-maven/src/bin/mvnyjp
new file mode 100755
index 00000000..ef4f8e1d
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/apache-maven/src/bin/mvnyjp
@@ -0,0 +1,42 @@
+#!/bin/sh
+# ----------------------------------------------------------------------------
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+# ----------------------------------------------------------------------------
+
+# ----------------------------------------------------------------------------
+# Maven2 Start Up Batch script
+#
+# Required ENV vars:
+# ------------------
+# JAVA_HOME - location of a JDK home dir
+#
+# Optional ENV vars
+# -----------------
+# M2_HOME - location of maven2's installed home dir
+# MAVEN_OPTS - parameters passed to the Java VM when running Maven
+# e.g. to debug Maven itself, use
+# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
+# MAVEN_SKIP_RC - flag to disable loading of mavenrc files
+# ----------------------------------------------------------------------------
+
+if [ ! -f "$YJPLIB" ]; then
+ echo "Error: Unable to autodetect the YJP library location. Please set YJPLIB variable" >&2
+ exit 1
+fi
+
+env MAVEN_OPTS="-agentpath:$YJPLIB=onexit=snapshot,onexit=memory,tracing,onlylocal $MAVEN_OPTS" $(dirname $0)/mvn "$@"
diff --git a/framework/src/maven/apache-maven-3.3.3/apache-maven/src/conf/logging/simplelogger.properties b/framework/src/maven/apache-maven-3.3.3/apache-maven/src/conf/logging/simplelogger.properties
new file mode 100644
index 00000000..859ff725
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/apache-maven/src/conf/logging/simplelogger.properties
@@ -0,0 +1,25 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+org.slf4j.simpleLogger.defaultLogLevel=info
+org.slf4j.simpleLogger.showDateTime=false
+org.slf4j.simpleLogger.showThreadName=false
+org.slf4j.simpleLogger.showLogName=false
+org.slf4j.simpleLogger.logFile=System.out
+org.slf4j.simpleLogger.levelInBrackets=true
+org.slf4j.simpleLogger.log.Sisu=info
+org.slf4j.simpleLogger.warnLevelString=WARNING \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/apache-maven/src/conf/settings.xml b/framework/src/maven/apache-maven-3.3.3/apache-maven/src/conf/settings.xml
new file mode 100644
index 00000000..19d7a977
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/apache-maven/src/conf/settings.xml
@@ -0,0 +1,257 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<!--
+ | This is the configuration file for Maven. It can be specified at two levels:
+ |
+ | 1. User Level. This settings.xml file provides configuration for a single user,
+ | and is normally provided in ${user.home}/.m2/settings.xml.
+ |
+ | NOTE: This location can be overridden with the CLI option:
+ |
+ | -s /path/to/user/settings.xml
+ |
+ | 2. Global Level. This settings.xml file provides configuration for all Maven
+ | users on a machine (assuming they're all using the same Maven
+ | installation). It's normally provided in
+ | ${maven.home}/conf/settings.xml.
+ |
+ | NOTE: This location can be overridden with the CLI option:
+ |
+ | -gs /path/to/global/settings.xml
+ |
+ | The sections in this sample file are intended to give you a running start at
+ | getting the most out of your Maven installation. Where appropriate, the default
+ | values (values used when the setting is not specified) are provided.
+ |
+ |-->
+<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
+ <!-- localRepository
+ | The path to the local repository maven will use to store artifacts.
+ |
+ | Default: ${user.home}/.m2/repository
+ <localRepository>/path/to/local/repo</localRepository>
+ -->
+
+ <!-- interactiveMode
+ | This will determine whether maven prompts you when it needs input. If set to false,
+ | maven will use a sensible default value, perhaps based on some other setting, for
+ | the parameter in question.
+ |
+ | Default: true
+ <interactiveMode>true</interactiveMode>
+ -->
+
+ <!-- offline
+ | Determines whether maven should attempt to connect to the network when executing a build.
+ | This will have an effect on artifact downloads, artifact deployment, and others.
+ |
+ | Default: false
+ <offline>false</offline>
+ -->
+
+ <!-- pluginGroups
+ | This is a list of additional group identifiers that will be searched when resolving plugins by their prefix, i.e.
+ | when invoking a command line like "mvn prefix:goal". Maven will automatically add the group identifiers
+ | "org.apache.maven.plugins" and "org.codehaus.mojo" if these are not already contained in the list.
+ |-->
+ <pluginGroups>
+ <!-- pluginGroup
+ | Specifies a further group identifier to use for plugin lookup.
+ <pluginGroup>com.your.plugins</pluginGroup>
+ -->
+ </pluginGroups>
+
+ <!-- proxies
+ | This is a list of proxies which can be used on this machine to connect to the network.
+ | Unless otherwise specified (by system property or command-line switch), the first proxy
+ | specification in this list marked as active will be used.
+ |-->
+ <proxies>
+ <!-- proxy
+ | Specification for one proxy, to be used in connecting to the network.
+ |
+ <proxy>
+ <id>optional</id>
+ <active>true</active>
+ <protocol>http</protocol>
+ <username>proxyuser</username>
+ <password>proxypass</password>
+ <host>proxy.host.net</host>
+ <port>80</port>
+ <nonProxyHosts>local.net|some.host.com</nonProxyHosts>
+ </proxy>
+ -->
+ </proxies>
+
+ <!-- servers
+ | This is a list of authentication profiles, keyed by the server-id used within the system.
+ | Authentication profiles can be used whenever maven must make a connection to a remote server.
+ |-->
+ <servers>
+ <!-- server
+ | Specifies the authentication information to use when connecting to a particular server, identified by
+ | a unique name within the system (referred to by the 'id' attribute below).
+ |
+ | NOTE: You should either specify username/password OR privateKey/passphrase, since these pairings are
+ | used together.
+ |
+ <server>
+ <id>deploymentRepo</id>
+ <username>repouser</username>
+ <password>repopwd</password>
+ </server>
+ -->
+
+ <!-- Another sample, using keys to authenticate.
+ <server>
+ <id>siteServer</id>
+ <privateKey>/path/to/private/key</privateKey>
+ <passphrase>optional; leave empty if not used.</passphrase>
+ </server>
+ -->
+ </servers>
+
+ <!-- mirrors
+ | This is a list of mirrors to be used in downloading artifacts from remote repositories.
+ |
+ | It works like this: a POM may declare a repository to use in resolving certain artifacts.
+ | However, this repository may have problems with heavy traffic at times, so people have mirrored
+ | it to several places.
+ |
+ | That repository definition will have a unique id, so we can create a mirror reference for that
+ | repository, to be used as an alternate download site. The mirror site will be the preferred
+ | server for that repository.
+ |-->
+ <mirrors>
+ <!-- mirror
+ | Specifies a repository mirror site to use instead of a given repository. The repository that
+ | this mirror serves has an ID that matches the mirrorOf element of this mirror. IDs are used
+ | for inheritance and direct lookup purposes, and must be unique across the set of mirrors.
+ |
+ <mirror>
+ <id>mirrorId</id>
+ <mirrorOf>repositoryId</mirrorOf>
+ <name>Human Readable Name for this Mirror.</name>
+ <url>http://my.repository.com/repo/path</url>
+ </mirror>
+ -->
+ </mirrors>
+
+ <!-- profiles
+ | This is a list of profiles which can be activated in a variety of ways, and which can modify
+ | the build process. Profiles provided in the settings.xml are intended to provide local machine-
+ | specific paths and repository locations which allow the build to work in the local environment.
+ |
+ | For example, if you have an integration testing plugin - like cactus - that needs to know where
+ | your Tomcat instance is installed, you can provide a variable here such that the variable is
+ | dereferenced during the build process to configure the cactus plugin.
+ |
+ | As noted above, profiles can be activated in a variety of ways. One way - the activeProfiles
+ | section of this document (settings.xml) - will be discussed later. Another way essentially
+ | relies on the detection of a system property, either matching a particular value for the property,
+ | or merely testing its existence. Profiles can also be activated by JDK version prefix, where a
+ | value of '1.4' might activate a profile when the build is executed on a JDK version of '1.4.2_07'.
+ | Finally, the list of active profiles can be specified directly from the command line.
+ |
+ | NOTE: For profiles defined in the settings.xml, you are restricted to specifying only artifact
+ | repositories, plugin repositories, and free-form properties to be used as configuration
+ | variables for plugins in the POM.
+ |
+ |-->
+ <profiles>
+ <!-- profile
+ | Specifies a set of introductions to the build process, to be activated using one or more of the
+ | mechanisms described above. For inheritance purposes, and to activate profiles via <activatedProfiles/>
+ | or the command line, profiles have to have an ID that is unique.
+ |
+ | An encouraged best practice for profile identification is to use a consistent naming convention
+ | for profiles, such as 'env-dev', 'env-test', 'env-production', 'user-jdcasey', 'user-brett', etc.
+ | This will make it more intuitive to understand what the set of introduced profiles is attempting
+ | to accomplish, particularly when you only have a list of profile id's for debug.
+ |
+ | This profile example uses the JDK version to trigger activation, and provides a JDK-specific repo.
+ <profile>
+ <id>jdk-1.4</id>
+
+ <activation>
+ <jdk>1.4</jdk>
+ </activation>
+
+ <repositories>
+ <repository>
+ <id>jdk14</id>
+ <name>Repository for JDK 1.4 builds</name>
+ <url>http://www.myhost.com/maven/jdk14</url>
+ <layout>default</layout>
+ <snapshotPolicy>always</snapshotPolicy>
+ </repository>
+ </repositories>
+ </profile>
+ -->
+
+ <!--
+ | Here is another profile, activated by the system property 'target-env' with a value of 'dev',
+ | which provides a specific path to the Tomcat instance. To use this, your plugin configuration
+ | might hypothetically look like:
+ |
+ | ...
+ | <plugin>
+ | <groupId>org.myco.myplugins</groupId>
+ | <artifactId>myplugin</artifactId>
+ |
+ | <configuration>
+ | <tomcatLocation>${tomcatPath}</tomcatLocation>
+ | </configuration>
+ | </plugin>
+ | ...
+ |
+ | NOTE: If you just wanted to inject this configuration whenever someone set 'target-env' to
+ | anything, you could just leave off the <value/> inside the activation-property.
+ |
+ <profile>
+ <id>env-dev</id>
+
+ <activation>
+ <property>
+ <name>target-env</name>
+ <value>dev</value>
+ </property>
+ </activation>
+
+ <properties>
+ <tomcatPath>/path/to/tomcat/instance</tomcatPath>
+ </properties>
+ </profile>
+ -->
+ </profiles>
+
+ <!-- activeProfiles
+ | List of profiles that are active for all builds.
+ |
+ <activeProfiles>
+ <activeProfile>alwaysActiveProfile</activeProfile>
+ <activeProfile>anotherAlwaysActiveProfile</activeProfile>
+ </activeProfiles>
+ -->
+</settings>
diff --git a/framework/src/maven/apache-maven-3.3.3/apache-maven/src/conf/toolchains.xml b/framework/src/maven/apache-maven-3.3.3/apache-maven/src/conf/toolchains.xml
new file mode 100644
index 00000000..aefddd8a
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/apache-maven/src/conf/toolchains.xml
@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<!--
+ | This is the toolchains file for Maven. It can be specified at two levels:
+ |
+ | 1. User Level. This toolchains.xml file provides configuration for a single user,
+ | and is normally provided in ${user.home}/.m2/toolchains.xml.
+ |
+ | NOTE: This location can be overridden with the CLI option:
+ |
+ | -t /path/to/user/toolchains.xml
+ |
+ | 2. Global Level. This toolchains.xml file provides configuration for all Maven
+ | users on a machine (assuming they're all using the same Maven
+ | installation). It's normally provided in
+ | ${maven.home}/conf/toolchains.xml.
+ |
+ | NOTE: This location can be overridden with the CLI option:
+ |
+ | -gt /path/to/global/toolchains.xml
+ |
+ | The sections in this sample file are intended to give you a running start at
+ | getting the most out of your Maven installation.
+ |-->
+<toolchains xmlns="http://maven.apache.org/TOOLCHAINS/1.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/TOOLCHAINS/1.1.0 http://maven.apache.org/xsd/toolchains-1.1.0.xsd">
+
+ <!--
+ | With toolchains you can refer to installations on your system. This
+ | way you don't have to hardcode paths in your pom.xml.
+ |
+ | Every toolchain consist of 3 elements:
+ | * type: the type of tool. An often used value is 'jdk'. Toolchains-aware
+ | plugins should document which type you must use.
+ |
+ | * provides: A list of key/value-pairs.
+ | Based on the toolchain-configuration in the pom.xml Maven will search for
+ | matching <provides/> configuration. You can decide for yourself which key-value
+ | pairs to use. Often used keys are 'version', 'vendor' and 'arch'. By default
+ | the version has a special meaning. If you configured in the pom.xml '1.5'
+ | Maven will search for 1.5 and above.
+ |
+ | * configuration: Additional configuration for this tool.
+ | Look for documentation of the toolchains-aware plugin which configuration elements
+ | can be used.
+ |
+ | See also http://maven.apache.org/guides/mini/guide-using-toolchains.html
+ |
+ | General example
+
+ <toolchain>
+ <type/>
+ <provides>
+ <version>1.0</version>
+ </provides>
+ <configuration/>
+ </toolchain>
+
+ | JDK examples
+
+ <toolchain>
+ <type>jdk</type>
+ <provides>
+ <version>1.5</version>
+ <vendor>sun</vendor>
+ </provides>
+ <configuration>
+ <jdkHome>/path/to/jdk/1.5</jdkHome>
+ </configuration>
+ </toolchain>
+ <toolchain>
+ <type>jdk</type>
+ <provides>
+ <version>1.6</version>
+ <vendor>sun</vendor>
+ </provides>
+ <configuration>
+ <jdkHome>/path/to/jdk/1.6</jdkHome>
+ </configuration>
+ </toolchain>
+
+ -->
+
+</toolchains> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/apache-maven/src/lib/ext/README.txt b/framework/src/maven/apache-maven-3.3.3/apache-maven/src/lib/ext/README.txt
new file mode 100644
index 00000000..5ebe59eb
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/apache-maven/src/lib/ext/README.txt
@@ -0,0 +1,2 @@
+Use this directory to contribute 3rd-party extensions to the Maven core. These extensions can either extend or override
+Maven's default implementation.
diff --git a/framework/src/maven/apache-maven-3.3.3/apache-maven/src/main/appended-resources/META-INF/LICENSE.vm b/framework/src/maven/apache-maven-3.3.3/apache-maven/src/main/appended-resources/META-INF/LICENSE.vm
new file mode 100644
index 00000000..1a462252
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/apache-maven/src/main/appended-resources/META-INF/LICENSE.vm
@@ -0,0 +1,49 @@
+##
+## Licensed to the Apache Software Foundation (ASF) under one
+## or more contributor license agreements. See the NOTICE file
+## distributed with this work for additional information
+## regarding copyright ownership. The ASF licenses this file
+## to you under the Apache License, Version 2.0 (the
+## "License"); you may not use this file except in compliance
+## with the License. You may obtain a copy of the License at
+##
+## http://www.apache.org/licenses/LICENSE-2.0
+##
+## Unless required by applicable law or agreed to in writing,
+## software distributed under the License is distributed on an
+## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+## KIND, either express or implied. See the License for the
+## specific language governing permissions and limitations
+## under the License.
+##
+## $Date: 2008-03-09 23:17:06 -0700 (Sun, 09 Mar 2008) $ $Rev: 635446 $
+##
+
+Apache Maven includes a number of components and libraries with separate
+copyright notices and license terms. Your use of those components are
+subject to the terms and conditions of the following licenses.
+
+#set ( $apacheTxt = "The Apache Software License, Version 2.0" )
+
+#foreach ( $project in $projects )
+#foreach ( $license in $project.licenses)
+#if ( ! ($apacheTxt == $license.name) )
+#set ( $artId = $project.artifact.artifactId)
+#set ( $lf = $locator )
+#set ( $url = $license.url )
+## glass fish URL is now invalid, use a fixed one
+#if ($url == "https://glassfish.dev.java.net/public/CDDLv1.0.html")
+#set ( $url = 'https://glassfish.java.net/public/CDDLv1.0.html' )
+#end
+#if ($url)
+#set ( $licFile = 'lib/' + $artId + '.license' )
+#set ( $downloaded = $lf.getResourceAsFile($url, "licenses/${licFile}") )
+#end
+
+$project.name #if ($project.url)($project.url)#end $project.artifact
+ License: $license.name #if ($url) $url ($licFile)#end
+
+#end
+#end
+#end
+
diff --git a/framework/src/maven/apache-maven-3.3.3/apache-maven/src/main/assembly/bin.xml b/framework/src/maven/apache-maven-3.3.3/apache-maven/src/main/assembly/bin.xml
new file mode 100644
index 00000000..ea14a9d8
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/apache-maven/src/main/assembly/bin.xml
@@ -0,0 +1,94 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<assembly>
+ <id>bin</id>
+ <formats>
+ <format>zip</format>
+ <format>tar.gz</format>
+ </formats>
+ <dependencySets>
+ <dependencySet>
+ <useProjectArtifact>false</useProjectArtifact>
+ <outputDirectory>boot</outputDirectory>
+ <includes>
+ <include>org.codehaus.plexus:plexus-classworlds</include>
+ </includes>
+ </dependencySet>
+ <dependencySet>
+ <useProjectArtifact>false</useProjectArtifact>
+ <outputDirectory>lib</outputDirectory>
+ <excludes>
+ <exclude>org.codehaus.plexus:plexus-classworlds</exclude>
+ </excludes>
+ </dependencySet>
+ </dependencySets>
+ <fileSets>
+ <fileSet>
+ <includes>
+ <include>README*</include>
+ </includes>
+ </fileSet>
+ <fileSet>
+ <directory>target/maven-shared-archive-resources/META-INF</directory>
+ <outputDirectory>/</outputDirectory>
+ <includes>
+ <include>LICENSE</include>
+ <include>NOTICE</include>
+ </includes>
+ </fileSet>
+ <fileSet>
+ <directory>target/licenses/lib</directory>
+ <outputDirectory>lib</outputDirectory>
+ <includes>
+ <include>**</include>
+ </includes>
+ </fileSet>
+ <fileSet>
+ <directory>src/bin</directory>
+ <outputDirectory>bin</outputDirectory>
+ <includes>
+ <include>*.cmd</include>
+ <include>*.conf</include>
+ </includes>
+ <lineEnding>dos</lineEnding>
+ </fileSet>
+ <fileSet>
+ <directory>src/bin</directory>
+ <outputDirectory>bin</outputDirectory>
+ <includes>
+ <include>m2</include>
+ <include>mvn</include>
+ <include>mvnDebug</include>
+ <!-- This is so that CI systems can periodically run the profiler -->
+ <include>mvnyjp</include>
+ </includes>
+ <lineEnding>unix</lineEnding>
+ <fileMode>0755</fileMode>
+ </fileSet>
+ <fileSet>
+ <directory>src/conf</directory>
+ <outputDirectory>conf</outputDirectory>
+ </fileSet>
+ <fileSet>
+ <directory>src/lib</directory>
+ <outputDirectory>lib</outputDirectory>
+ </fileSet>
+ </fileSets>
+</assembly>
diff --git a/framework/src/maven/apache-maven-3.3.3/apache-maven/src/main/assembly/src.xml b/framework/src/maven/apache-maven-3.3.3/apache-maven/src/main/assembly/src.xml
new file mode 100644
index 00000000..3bf10e05
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/apache-maven/src/main/assembly/src.xml
@@ -0,0 +1,49 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<assembly>
+ <id>src</id>
+ <formats>
+ <format>zip</format>
+ <format>tar.gz</format>
+ </formats>
+ <fileSets>
+ <fileSet>
+ <directory>${project.basedir}/..</directory>
+ <outputDirectory>/</outputDirectory>
+ <excludes>
+ <exclude>%regex[(?!((?!target/)[^/]+/)*src/).*target.*]</exclude>
+ <exclude>**/*.log</exclude>
+ <exclude>**/.gitignore</exclude>
+ <exclude>**/.gitattributes</exclude>
+ <exclude>init-git-svn.sh</exclude>
+ <exclude>**/.repository/**</exclude>
+ </excludes>
+ </fileSet>
+ <fileSet>
+ <directory>${project.build.directory}/maven-shared-archive-resources/META-INF</directory>
+ <outputDirectory>/</outputDirectory>
+ <includes>
+ <include>DEPENDENCIES</include>
+ <!-- exclude the license and notice as they are not as accurate as the ones from above -->
+ </includes>
+ </fileSet>
+ </fileSets>
+</assembly>
+
diff --git a/framework/src/maven/apache-maven-3.3.3/apache-maven/src/site/site.xml b/framework/src/maven/apache-maven-3.3.3/apache-maven/src/site/site.xml
new file mode 100644
index 00000000..cd5a7454
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/apache-maven/src/site/site.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project xmlns="http://maven.apache.org/DECORATION/1.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/DECORATION/1.0.0 http://maven.apache.org/xsd/decoration-1.0.0.xsd">
+ <body>
+ <menu ref="parent"/>
+ <menu ref="reports"/>
+ </body>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/apache-maven/src/test/java/org/apache/maven/settings/GlobalSettingsTest.java b/framework/src/maven/apache-maven-3.3.3/apache-maven/src/test/java/org/apache/maven/settings/GlobalSettingsTest.java
new file mode 100644
index 00000000..b728be38
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/apache-maven/src/test/java/org/apache/maven/settings/GlobalSettingsTest.java
@@ -0,0 +1,59 @@
+package org.apache.maven.settings;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+
+import junit.framework.TestCase;
+
+import org.apache.maven.settings.io.xpp3.SettingsXpp3Reader;
+
+/**
+ * Tests that the global settings.xml shipped with the distribution is in good state.
+ *
+ * @author Benjamin Bentmann
+ */
+public class GlobalSettingsTest
+ extends TestCase
+{
+
+ public void testValidGlobalSettings()
+ throws Exception
+ {
+ String basedir = System.getProperty( "basedir", System.getProperty( "user.dir" ) );
+
+ File globalSettingsFile = new File( basedir, "src/conf/settings.xml" );
+ assertTrue( globalSettingsFile.getAbsolutePath(), globalSettingsFile.isFile() );
+
+ Reader reader = new InputStreamReader( new FileInputStream( globalSettingsFile ), "UTF-8" );
+ try
+ {
+ new SettingsXpp3Reader().read( reader );
+ }
+ finally
+ {
+ reader.close();
+ }
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/build.xml b/framework/src/maven/apache-maven-3.3.3/build.xml
new file mode 100644
index 00000000..0442a125
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/build.xml
@@ -0,0 +1,307 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<!-- START SNIPPET: ant-bootstrap
+
+By default the bootstrap will use ~/.m2/repository as the integration repository but you can define the integration
+repository by specifying a property on the command line:
+
+ant -Dmaven.repo.local=/my/integration/repository
+
+Those familiar with Maven will note this is the same way the local repository can be set from the command-line.
+This facilitates having a set of builds converge on the same repository for integration purposes.
+
+END SNIPPET: ant-bootstrap -->
+
+<project default="all" basedir="." xmlns:artifact="urn:maven-artifact-ant">
+
+ <property name="distributionDirectory" value="apache-maven"/>
+ <property name="distributionId" value="apache-maven"/>
+ <property name="distributionShortName" value="Maven"/>
+ <property name="distributionName" value="Apache Maven"/>
+ <property name="it.workdir.version" value="3.0.x" />
+ <property name="maven-compile.jvmargs" value="-Xmx512m -Xms512m"/>
+ <property name="maven-compile.fork" value="true"/>
+ <property name="maven-compile.maxmemory" value="512m"/>
+
+ <target name="initTaskDefs">
+ <echo>Building ${distributionName} ...</echo>
+ <xmlproperty file="pom.xml" prefix="xmlPom" />
+ <path id="maven-ant-tasks.classpath" path="maven-ant-tasks-2.1.1.jar" />
+ <typedef resource="org/apache/maven/artifact/ant/antlib.xml" uri="urn:maven-artifact-ant" classpathref="maven-ant-tasks.classpath" />
+ </target>
+
+ <target name="isMavenHomeSet" depends="initTaskDefs">
+ <property environment="env" />
+ <condition property="maven.home" value="${env.M2_HOME}">
+ <isset property="env.M2_HOME" />
+ </condition>
+ <fail message="You must set the M2_HOME environment variable or specify a maven.home property to this Ant script">
+ <condition>
+ <or>
+ <not>
+ <isset property="maven.home" />
+ </not>
+ <equals arg1="${maven.home}" arg2="" trim="true" />
+ </or>
+ </condition>
+ </fail>
+ <available property="maven.home.exists" file="${maven.home}" />
+ </target>
+
+ <target name="prompt-maven-home-exists" depends="isMavenHomeSet" if="maven.home.exists">
+ <input addproperty="maven.home.exists.continue" validargs="yes,no" defaultvalue="no">WARNING:
+The specified target directory
+ ${maven.home}
+already exists. It will be deleted and overwritten by the build.
+Do you want to continue?</input>
+ <fail message="Build was aborted by user">
+ <condition>
+ <equals arg1="${maven.home.exists.continue}" arg2="no" trim="true" casesensitive="false" />
+ </condition>
+ </fail>
+ </target>
+
+ <target name="init" depends="isMavenHomeSet">
+ <!-- Initialize properties -->
+ <property name="maven.home.basename.expected" value="${distributionId}-${xmlPom.project.version}" />
+ <property name="maven.assembly" location="${distributionDirectory}/target/${maven.home.basename.expected}-bin.zip" />
+ <property name="maven.repo.local" value="${user.home}/.m2/repository" />
+ <property name="maven.debug" value="-e" />
+ <property name="maven.test.skip" value="false" />
+ <property name="skipTests" value="false" />
+ <property name="surefire.useFile" value="true" />
+ <property name="maven.test.redirectTestOutputToFile" value="${surefire.useFile}" />
+ <property name="maven.goal" value="install" />
+ <echo>maven.home = ${maven.home}</echo>
+ <echo>maven.repo.local = ${maven.repo.local}</echo>
+ <echo>distributionId = ${distributionId}</echo>
+ <echo>distributionName = ${distributionName}</echo>
+ <echo>distributionDirectory = ${distributionDirectory}</echo>
+ </target>
+
+ <target name="clean-bootstrap" description="cleans up generated bootstrap classes">
+ <delete dir="bootstrap" />
+ </target>
+
+ <target name="pull" depends="init" unless="skip.pull">
+ <!-- Pull the dependencies that Maven needs to build -->
+ <copy file="pom.xml" tofile="dependencies.xml" />
+ <replace file="${basedir}/dependencies.xml" token="&lt;!--bootstrap-start-comment--&gt;" value="&lt;!--" />
+ <replace file="${basedir}/dependencies.xml" token="&lt;!--bootstrap-end-comment--&gt;" value="--&gt;" />
+ <artifact:pom file="${basedir}/dependencies.xml" id="pom">
+ <localRepository path="${maven.repo.local}" />
+ </artifact:pom>
+ <artifact:dependencies pathId="pom.pathid" filesetId="pom.fileset" useScope="compile">
+ <localRepository path="${maven.repo.local}" />
+ <pom refid="pom" />
+ </artifact:dependencies>
+ <delete file="${basedir}/dependencies.xml" />
+
+ <!-- Pull the dependencies for Modello -->
+ <artifact:dependencies pathId="modello.pathid" filesetId="modello.fileset">
+ <localRepository path="${maven.repo.local}" />
+ <dependency groupId="org.codehaus.modello" artifactId="modello-maven-plugin" version="${pom.properties.modelloVersion}" />
+ </artifact:dependencies>
+
+ <!-- Pull the dependencies for the MetadataGenerator CLI -->
+ <artifact:dependencies pathId="pmdg.pathid" filesetId="pmdg.fileset">
+ <localRepository path="${maven.repo.local}" />
+ <dependency groupId="org.codehaus.plexus" artifactId="plexus-component-metadata" version="${pom.properties.plexusVersion}" />
+ </artifact:dependencies>
+
+ </target>
+
+ <target name="process-classes" depends="pull" description="generates plexus component metadata.">
+ <mkdir dir="${basedir}/bootstrap/target" />
+ <mkdir dir="${basedir}/bootstrap/target/classes" />
+
+ <path id="pmdg.classpath">
+ <path refid="maven.classpath" />
+ <path refid="pmdg.pathid" />
+ </path>
+
+ <echo>Using plexus version ${pom.properties.plexusVersion}</echo>
+ <java fork="true" classname="org.codehaus.plexus.metadata.PlexusMetadataGeneratorCli" failonerror="true">
+ <classpath refid="pmdg.classpath" />
+ <!-- We need to generate component descriptors from the maven-artifact sources which use javadoc annotations. -->
+ <arg value="--source" />
+ <arg value="${basedir}/maven-compat/src/main/java" />
+ <!-- We have separated the artifact handlers and lifecycle mappings into a separate file. -->
+ <arg value="--descriptors" />
+ <arg value="${basedir}/maven-core/src/main/resources/META-INF/plexus" />
+ <!-- Search the classes for annotations that we've compiled. -->
+ <arg value="--classes" />
+ <arg value="${basedir}/bootstrap/target/classes" />
+ <!-- We'll make one big fat components descriptor. -->
+ <arg value="--output" />
+ <arg value="${basedir}/bootstrap/target/classes/META-INF/plexus/components.xml" />
+ </java>
+ </target>
+
+ <target name="generate-sources" depends="pull" description="generates Java sources from Modello mdo model files">
+ <mkdir dir="bootstrap/target" />
+ <mkdir dir="bootstrap/target/generated-sources" />
+
+ <macrodef name="modello-single-mode">
+ <attribute name="file" />
+ <attribute name="mode" />
+ <attribute name="version" />
+ <sequential>
+ <java fork="true" classname="org.codehaus.modello.ModelloCli" failonerror="true">
+ <classpath refid="modello.pathid" />
+ <arg file="@{file}" />
+ <!-- model file -->
+ <arg value="@{mode}" />
+ <!-- output type -->
+ <arg file="bootstrap/target/generated-sources" />
+ <!-- output directory -->
+ <arg value="@{version}" />
+ <!-- model version -->
+ <arg value="false" />
+ <!-- package with version -->
+ <arg value="true" />
+ <!-- use Java 5 -->
+ <arg value="UTF-8" />
+ <!-- encoding -->
+ </java>
+ </sequential>
+ </macrodef>
+
+ <macrodef name="modello">
+ <attribute name="file" />
+ <attribute name="version" default="1.0.0" />
+ <sequential>
+ <echo taskname="modello" message="Generating sources for @{file}" />
+ <modello-single-mode file="@{file}" version="@{version}" mode="java" />
+ <modello-single-mode file="@{file}" version="@{version}" mode="xpp3-reader" />
+ <modello-single-mode file="@{file}" version="@{version}" mode="xpp3-writer" />
+ </sequential>
+ </macrodef>
+
+ <macrodef name="modello-ex">
+ <attribute name="file" />
+ <attribute name="version" default="1.0.0" />
+ <sequential>
+ <modello file="@{file}" version="@{version}" />
+ <modello-single-mode file="@{file}" version="@{version}" mode="xpp3-extended-reader" />
+ </sequential>
+ </macrodef>
+
+ <modello-ex file="maven-model/src/main/mdo/maven.mdo" version="4.0.0" />
+ <modello file="maven-plugin-api/src/main/mdo/lifecycle.mdo" />
+ <modello file="maven-model-builder/src/main/mdo/profiles.mdo" />
+ <modello file="maven-settings/src/main/mdo/settings.mdo" version="1.1.0" />
+ <modello file="maven-core/src/main/mdo/toolchains.mdo" version="1.1.0" />
+ <modello file="maven-repository-metadata/src/main/mdo/metadata.mdo" version="1.1.0" />
+ <modello file="maven-compat/src/main/mdo/profiles.mdo" />
+ <modello file="maven-compat/src/main/mdo/paramdoc.mdo" />
+ <modello file="maven-embedder/src/main/mdo/core-extensions.mdo" />
+ </target>
+
+ <target name="compile-boot" depends="generate-sources" description="compiles the bootstrap sources">
+ <path id="sources">
+ <dirset dir=".">
+ <include name="bootstrap/target/generated-sources" />
+ <include name="*/src/main/java" />
+ </dirset>
+ </path>
+
+ <mkdir dir="bootstrap/target/classes" />
+ <javac destdir="bootstrap/target/classes" encoding="UTF-8" source="1.6" target="1.6" debug="true" includeAntRuntime="false">
+ <src refid="sources" />
+ <classpath refid="pom.pathid" />
+ </javac>
+
+ <copy todir="bootstrap/target/classes" encoding="ISO-8859-1">
+ <fileset dir="maven-core/src/main/resources">
+ <include name="**/build.properties" />
+ </fileset>
+ <filterset begintoken="${" endtoken="}">
+ <filter token="project.version" value="${xmlPom.project.version}"/>
+ </filterset>
+ </copy>
+ <echo file="bootstrap/target/classes/META-INF/maven/org.apache.maven/maven-core/pom.properties" encoding="ISO-8859-1">
+ version = ${xmlPom.project.version}
+ </echo>
+
+ <path id="maven.classpath">
+ <pathelement location="bootstrap/target/classes" />
+ <dirset dir=".">
+ <include name="*/src/main/resources" />
+ </dirset>
+ <path refid="pom.pathid" />
+ </path>
+ </target>
+
+ <target name="maven-compile" depends="compile-boot,process-classes" description="compiles Maven using the bootstrap Maven, skipping automated tests">
+ <java fork="${maven-compile.fork}" classname="org.apache.maven.cli.MavenCli" failonerror="true" timeout="600000" maxmemory="${maven-compile.maxmemory}">
+ <!--jvmarg line="-Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000"/-->
+ <!--jvmarg value="${maven-compile.jvmargs}"/-->
+ <classpath refid="maven.classpath" />
+ <arg value="${maven.debug}" />
+ <arg value="-B" />
+ <arg value="-V" />
+ <arg value="clean" />
+ <arg value="${maven.goal}" />
+ <arg value="-Dmaven.test.skip=${maven.test.skip}" />
+ <arg value="-DskipTests=${skipTests}" />
+ <arg value="-Dmaven.repo.local=${maven.repo.local}" />
+ <arg value="-Dsurefire.useFile=${surefire.useFile}" />
+ <arg value="-Dmaven.test.redirectTestOutputToFile=${maven.test.redirectTestOutputToFile}" />
+ <arg value="-DdistributionId=${distributionId}" />
+ <arg value="-DdistributionShortName=${distributionShortName}" />
+ <arg value="-DdistributionName=${distributionName}" />
+ <jvmarg value="-Dmaven.multiModuleProjectDirectory=${basedir}" />
+ </java>
+ </target>
+
+ <target name="maven-assembly" depends="maven-compile" description="generates the Maven installation assembly using the bootstrap Maven">
+ <echo>
+The new Maven distribution was created as part of the MAVEN-COMPILE step, above.
+This goal just validates the presence of that distribution.
+</echo>
+ <condition property="build.failed">
+ <not>
+ <available file="${maven.assembly}" />
+ </not>
+ </condition>
+ <fail if="build.failed" message="Assembly task seemed to succeed, but couldn't find assembly file: ${maven.assembly}" />
+ </target>
+
+ <target name="extract-assembly" depends="init,prompt-maven-home-exists,maven-assembly" description="extracts the maven assembly into maven.home">
+ <echo>Extracting assembly to ${maven.home} ...</echo>
+ <!-- If we are starting from scratch make sure the directory is created -->
+ <delete dir="${maven.home}" />
+ <mkdir dir="${maven.home}" />
+ <unzip src="${maven.assembly}" dest="${maven.home}">
+ <mapper type="regexp" from="^[^\\/]+[\\/](.*)$$" to="\1" />
+ </unzip>
+ <chmod perm="+x">
+ <fileset dir="${maven.home}/bin">
+ <include name="mvn" />
+ <include name="mvnDebug" />
+ <include name="mvnyjp" />
+ </fileset>
+ </chmod>
+ </target>
+
+ <target name="all" depends="clean-bootstrap,init,extract-assembly" />
+
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/deploySite.sh b/framework/src/maven/apache-maven-3.3.3/deploySite.sh
new file mode 100644
index 00000000..f6c265d7
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/deploySite.sh
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+mvn -Preporting site site:stage $@
+mvn scm-publish:publish-scm $@
diff --git a/framework/src/maven/apache-maven-3.3.3/doap_Maven.rdf b/framework/src/maven/apache-maven-3.3.3/doap_Maven.rdf
new file mode 100644
index 00000000..e574e863
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/doap_Maven.rdf
@@ -0,0 +1,178 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+<rdf:RDF xml:lang="en" xmlns="http://usefulinc.com/ns/doap#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:asfext="http://projects.apache.org/ns/asfext#" xmlns:foaf="http://xmlns.com/foaf/0.1/">
+ <Project rdf:about="http://Maven.rdf.apache.org/">
+ <created>2001</created>
+ <license rdf:resource="http://www.apache.org/licenses/LICENSE-2.0.txt"/>
+ <name>Apache Maven</name>
+ <homepage rdf:resource="http://maven.apache.org/"/>
+ <asfext:pmc rdf:resource="http://maven.apache.org/"/>
+ <shortdesc>Maven is a project development management and comprehension tool.</shortdesc>
+ <description>Maven is a project development management and comprehension tool. Based on the concept of a project object model: builds, dependency management, documentation creation, site publication, and distribution publication are all controlled from the declarative file. Maven can be extended by plugins to utilise a number of other development tools for reporting or the build process.</description>
+ <bug-database rdf:resource="http://jira.codehaus.org/browse/MNG"/>
+ <mailing-list rdf:resource="http://maven.apache.org/mail-lists.html"/>
+ <download-page rdf:resource="http://maven.apache.org/download.html"/>
+ <programming-language>Java</programming-language>
+ <category rdf:resource="http://projects.apache.org/category/build-management"/>
+ <release>
+ <Version>
+ <name>Latest stable release</name>
+ <created>2014-12-20</created>
+ <revision>3.2.5</revision>
+ <file-release>http://archive.apache.org/dist/maven/maven-3/3.2.5/binaries/apache-maven-3.2.5-bin.zip</file-release>
+ <file-release>http://archive.apache.org/dist/maven/maven-3/3.2.5/binaries/apache-maven-3.2.5-bin.tar.gz</file-release>
+ <file-release>http://archive.apache.org/dist/maven/maven-3/3.2.5/source/apache-maven-3.2.5-src.zip</file-release>
+ <file-release>http://archive.apache.org/dist/maven/maven-3/3.2.5/source/apache-maven-3.2.5-src.tar.gz</file-release>
+ </Version>
+ </release>
+ <release>
+ <Version>
+ <name>Apache Maven 3.2.3</name>
+ <created>2014-08-17</created>
+ <revision>3.2.3</revision>
+ <file-release>http://archive.apache.org/dist/maven/maven-3/3.2.3/binaries/apache-maven-3.2.3-bin.zip</file-release>
+ <file-release>http://archive.apache.org/dist/maven/maven-3/3.2.3/binaries/apache-maven-3.2.3-bin.tar.gz</file-release>
+ <file-release>http://archive.apache.org/dist/maven/maven-3/3.2.3/source/apache-maven-3.2.3-src.zip</file-release>
+ <file-release>http://archive.apache.org/dist/maven/maven-3/3.2.3/source/apache-maven-3.2.3-src.tar.gz</file-release>
+ </Version>
+ </release>
+ <release>
+ <Version>
+ <name>Apache Maven 3.2.2</name>
+ <created>2014-06-25</created>
+ <revision>3.2.2</revision>
+ <file-release>http://archive.apache.org/dist/maven/maven-3/3.2.2/binaries/apache-maven-3.2.2-bin.zip</file-release>
+ <file-release>http://archive.apache.org/dist/maven/maven-3/3.2.2/binaries/apache-maven-3.2.2-bin.tar.gz</file-release>
+ <file-release>http://archive.apache.org/dist/maven/maven-3/3.2.2/source/apache-maven-3.2.2-src.zip</file-release>
+ <file-release>http://archive.apache.org/dist/maven/maven-3/3.2.2/source/apache-maven-3.2.2-src.tar.gz</file-release>
+ </Version>
+ </release>
+ <release>
+ <Version>
+ <name>Apache Maven 3.2.1</name>
+ <created>2014-02-21</created>
+ <revision>3.2.1</revision>
+ <file-release>http://archive.apache.org/dist/maven/maven-3/3.2.1/binaries/apache-maven-3.2.1-bin.zip</file-release>
+ <file-release>http://archive.apache.org/dist/maven/maven-3/3.2.1/binaries/apache-maven-3.2.1-bin.tar.gz</file-release>
+ <file-release>http://archive.apache.org/dist/maven/maven-3/3.2.1/source/apache-maven-3.2.1-src.zip</file-release>
+ <file-release>http://archive.apache.org/dist/maven/maven-3/3.2.1/source/apache-maven-3.2.1-src.tar.gz</file-release>
+ </Version>
+ </release>
+ <release>
+ <Version>
+ <name>Apache Maven 3.1.1</name>
+ <created>2013-10-04</created>
+ <revision>3.1.1</revision>
+ <file-release>http://archive.apache.org/dist/maven/maven-3/3.1.1/binaries/apache-maven-3.1.1-bin.zip</file-release>
+ <file-release>http://archive.apache.org/dist/maven/maven-3/3.1.1/binaries/apache-maven-3.1.1-bin.tar.gz</file-release>
+ <file-release>http://archive.apache.org/dist/maven/maven-3/3.1.1/source/apache-maven-3.1.1-src.zip</file-release>
+ <file-release>http://archive.apache.org/dist/maven/maven-3/3.1.1/source/apache-maven-3.1.1-src.tar.gz</file-release>
+ </Version>
+ </release>
+ <release>
+ <Version>
+ <name>Apache Maven 3.1.0</name>
+ <created>2013-07-15</created>
+ <revision>3.1.0</revision>
+ <file-release>http://archive.apache.org/dist/maven/maven-3/3.1.0/binaries/apache-maven-3.1.0-bin.zip</file-release>
+ <file-release>http://archive.apache.org/dist/maven/maven-3/3.1.0/binaries/apache-maven-3.1.0-bin.tar.gz</file-release>
+ <file-release>http://archive.apache.org/dist/maven/maven-3/3.1.0/source/apache-maven-3.1.0-src.zip</file-release>
+ <file-release>http://archive.apache.org/dist/maven/maven-3/3.1.0/source/apache-maven-3.1.0-src.tar.gz</file-release>
+ </Version>
+ </release>
+ <release>
+ <Version>
+ <name>Apache Maven 3.0.5</name>
+ <created>2013-02-23</created>
+ <revision>3.0.5</revision>
+ <file-release>http://archive.apache.org/dist/maven/maven-3/3.0.5/binaries/apache-maven-3.0.5-bin.zip</file-release>
+ <file-release>http://archive.apache.org/dist/maven/maven-3/3.0.5/binaries/apache-maven-3.0.5-bin.tar.gz</file-release>
+ <file-release>http://archive.apache.org/dist/maven/maven-3/3.0.5/source/apache-maven-3.0.5-src.zip</file-release>
+ <file-release>http://archive.apache.org/dist/maven/maven-3/3.0.5/source/apache-maven-3.0.5-src.tar.gz</file-release>
+ </Version>
+ </release>
+ <release>
+ <Version>
+ <name>Apache Maven 3.0.4</name>
+ <created>2012-01-20</created>
+ <revision>3.0.4</revision>
+ <file-release>http://archive.apache.org/dist/maven/binaries/apache-maven-3.0.4-bin.zip</file-release>
+ <file-release>http://archive.apache.org/dist/maven/binaries/apache-maven-3.0.4-bin.tar.gz</file-release>
+ <file-release>http://archive.apache.org/dist/maven/source/apache-maven-3.0.4-src.zip</file-release>
+ <file-release>http://archive.apache.org/dist/maven/source/apache-maven-3.0.4-src.tar.gz</file-release>
+ </Version>
+ </release>
+ <release>
+ <Version>
+ <name>Apache Maven 3.0.3</name>
+ <created>2011-03-03</created>
+ <revision>3.0.3</revision>
+ <file-release>http://archive.apache.org/dist/maven/binaries/apache-maven-3.0.3-bin.zip</file-release>
+ <file-release>http://archive.apache.org/dist/maven/binaries/apache-maven-3.0.3-bin.tar.gz</file-release>
+ <file-release>http://archive.apache.org/dist/maven/source/apache-maven-3.0.3-src.zip</file-release>
+ <file-release>http://archive.apache.org/dist/maven/source/apache-maven-3.0.3-src.tar.gz</file-release>
+ </Version>
+ </release>
+ <release>
+ <Version>
+ <name>Apache Maven 3.0.2</name>
+ <created>2011-01-12</created>
+ <revision>3.0.2</revision>
+ <file-release>http://archive.apache.org/dist/maven/binaries/apache-maven-3.0.2-bin.zip</file-release>
+ <file-release>http://archive.apache.org/dist/maven/binaries/apache-maven-3.0.2-bin.tar.gz</file-release>
+ <file-release>http://archive.apache.org/dist/maven/source/apache-maven-3.0.2-src.zip</file-release>
+ <file-release>http://archive.apache.org/dist/maven/source/apache-maven-3.0.2-src.tar.gz</file-release>
+ </Version>
+ </release>
+ <release>
+ <Version>
+ <name>Apache Maven 3.0.1</name>
+ <created>2010-11-23</created>
+ <revision>3.0.1</revision>
+ <file-release>http://archive.apache.org/dist/maven/binaries/apache-maven-3.0.1-bin.zip</file-release>
+ <file-release>http://archive.apache.org/dist/maven/binaries/apache-maven-3.0.1-bin.tar.gz</file-release>
+ <file-release>http://archive.apache.org/dist/maven/source/apache-maven-3.0.1-src.zip</file-release>
+ <file-release>http://archive.apache.org/dist/maven/source/apache-maven-3.0.1-src.tar.gz</file-release>
+ </Version>
+ </release>
+ <release>
+ <Version>
+ <name>Apache Maven 3.0</name>
+ <created>2010-10-04</created>
+ <revision>3.0</revision>
+ <file-release>http://archive.apache.org/dist/maven/binaries/apache-maven-3.0-bin.zip</file-release>
+ <file-release>http://archive.apache.org/dist/maven/binaries/apache-maven-3.0-bin.tar.gz</file-release>
+ <file-release>http://archive.apache.org/dist/maven/source/apache-maven-3.0-src.zip</file-release>
+ <file-release>http://archive.apache.org/dist/maven/source/apache-maven-3.0-src.tar.gz</file-release>
+ </Version>
+ </release>
+ <repository>
+ <GitRepository>
+ <location rdf:resource="https://git-wip-us.apache.org/repos/asf/maven.git"/>
+ <browse rdf:resource="https://git-wip-us.apache.org/repos/asf/maven.git"/>
+ </GitRepository>
+ </repository>
+ <maintainer>
+ <foaf:Person>
+ <foaf:name>Apache Maven PMC</foaf:name>
+ <foaf:mbox rdf:resource="mailto:dev@maven.apache.org"/>
+ </foaf:Person>
+ </maintainer>
+ </Project>
+</rdf:RDF>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/pom.xml
new file mode 100644
index 00000000..4906647c
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/pom.xml
@@ -0,0 +1,130 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven</artifactId>
+ <version>3.3.3</version>
+ </parent>
+
+ <artifactId>maven-aether-provider</artifactId>
+
+ <name>Maven Aether Provider</name>
+ <description>Extensions to Aether for utilizing Maven POM and repository metadata.</description>
+
+ <scm><!-- remove when git scm url format can accept artifact-id at the end, as automatically inherited -->
+ <connection>scm:git:https://git-wip-us.apache.org/repos/asf/maven.git</connection>
+ <developerConnection>scm:git:https://git-wip-us.apache.org/repos/asf/maven.git</developerConnection>
+ <tag>maven-3.3.3</tag>
+ </scm>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-model</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-model-builder</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-repository-metadata</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.aether</groupId>
+ <artifactId>aether-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.aether</groupId>
+ <artifactId>aether-spi</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.aether</groupId>
+ <artifactId>aether-util</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.aether</groupId>
+ <artifactId>aether-impl</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-component-annotations</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-utils</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.sonatype.sisu</groupId>
+ <artifactId>sisu-guice</artifactId>
+ <classifier>no_aop</classifier>
+ <optional>true</optional>
+ <exclusions>
+ <exclusion>
+ <groupId>aopalliance</groupId>
+ <artifactId>aopalliance</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <!-- Testing -->
+ <dependency>
+ <groupId>org.eclipse.aether</groupId>
+ <artifactId>aether-connector-basic</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.aether</groupId>
+ <artifactId>aether-transport-wagon</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.wagon</groupId>
+ <artifactId>wagon-file</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.sisu</groupId>
+ <artifactId>org.eclipse.sisu.plexus</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-core</artifactId>
+ <version>1.9.5</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-component-metadata</artifactId>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
+
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/ArtifactDescriptorReaderDelegate.java b/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/ArtifactDescriptorReaderDelegate.java
new file mode 100644
index 00000000..29749ad0
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/ArtifactDescriptorReaderDelegate.java
@@ -0,0 +1,153 @@
+package org.apache.maven.repository.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.maven.model.DependencyManagement;
+import org.apache.maven.model.DistributionManagement;
+import org.apache.maven.model.License;
+import org.apache.maven.model.Model;
+import org.apache.maven.model.Prerequisites;
+import org.apache.maven.model.Repository;
+import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.artifact.Artifact;
+import org.eclipse.aether.artifact.ArtifactProperties;
+import org.eclipse.aether.artifact.ArtifactType;
+import org.eclipse.aether.artifact.ArtifactTypeRegistry;
+import org.eclipse.aether.artifact.DefaultArtifact;
+import org.eclipse.aether.artifact.DefaultArtifactType;
+import org.eclipse.aether.graph.Dependency;
+import org.eclipse.aether.graph.Exclusion;
+import org.eclipse.aether.resolution.ArtifactDescriptorResult;
+
+/**
+ * Populates Aether {@link ArtifactDescriptorResult} from Maven project {@link Model}.
+ *
+ * @since 3.2.4
+ * @provisional This class is part of work in progress and can be changed or removed without notice.
+ */
+public class ArtifactDescriptorReaderDelegate
+{
+ public void populateResult( RepositorySystemSession session, ArtifactDescriptorResult result, Model model )
+ {
+ ArtifactTypeRegistry stereotypes = session.getArtifactTypeRegistry();
+
+ for ( Repository r : model.getRepositories() )
+ {
+ result.addRepository( ArtifactDescriptorUtils.toRemoteRepository( r ) );
+ }
+
+ for ( org.apache.maven.model.Dependency dependency : model.getDependencies() )
+ {
+ result.addDependency( convert( dependency, stereotypes ) );
+ }
+
+ DependencyManagement mngt = model.getDependencyManagement();
+ if ( mngt != null )
+ {
+ for ( org.apache.maven.model.Dependency dependency : mngt.getDependencies() )
+ {
+ result.addManagedDependency( convert( dependency, stereotypes ) );
+ }
+ }
+
+ Map<String, Object> properties = new LinkedHashMap<String, Object>();
+
+ Prerequisites prerequisites = model.getPrerequisites();
+ if ( prerequisites != null )
+ {
+ properties.put( "prerequisites.maven", prerequisites.getMaven() );
+ }
+
+ List<License> licenses = model.getLicenses();
+ properties.put( "license.count", licenses.size() );
+ for ( int i = 0; i < licenses.size(); i++ )
+ {
+ License license = licenses.get( i );
+ properties.put( "license." + i + ".name", license.getName() );
+ properties.put( "license." + i + ".url", license.getUrl() );
+ properties.put( "license." + i + ".comments", license.getComments() );
+ properties.put( "license." + i + ".distribution", license.getDistribution() );
+ }
+
+ result.setProperties( properties );
+
+ setArtifactProperties( result, model );
+ }
+
+ private Dependency convert( org.apache.maven.model.Dependency dependency, ArtifactTypeRegistry stereotypes )
+ {
+ ArtifactType stereotype = stereotypes.get( dependency.getType() );
+ if ( stereotype == null )
+ {
+ stereotype = new DefaultArtifactType( dependency.getType() );
+ }
+
+ boolean system = dependency.getSystemPath() != null && dependency.getSystemPath().length() > 0;
+
+ Map<String, String> props = null;
+ if ( system )
+ {
+ props = Collections.singletonMap( ArtifactProperties.LOCAL_PATH, dependency.getSystemPath() );
+ }
+
+ Artifact artifact =
+ new DefaultArtifact( dependency.getGroupId(), dependency.getArtifactId(), dependency.getClassifier(), null,
+ dependency.getVersion(), props, stereotype );
+
+ List<Exclusion> exclusions = new ArrayList<Exclusion>( dependency.getExclusions().size() );
+ for ( org.apache.maven.model.Exclusion exclusion : dependency.getExclusions() )
+ {
+ exclusions.add( convert( exclusion ) );
+ }
+
+ Dependency result = new Dependency( artifact, dependency.getScope(), dependency.isOptional(), exclusions );
+
+ return result;
+ }
+
+ private Exclusion convert( org.apache.maven.model.Exclusion exclusion )
+ {
+ return new Exclusion( exclusion.getGroupId(), exclusion.getArtifactId(), "*", "*" );
+ }
+
+ private void setArtifactProperties( ArtifactDescriptorResult result, Model model )
+ {
+ String downloadUrl = null;
+ DistributionManagement distMngt = model.getDistributionManagement();
+ if ( distMngt != null )
+ {
+ downloadUrl = distMngt.getDownloadUrl();
+ }
+ if ( downloadUrl != null && downloadUrl.length() > 0 )
+ {
+ Artifact artifact = result.getArtifact();
+ Map<String, String> props = new HashMap<String, String>( artifact.getProperties() );
+ props.put( ArtifactProperties.DOWNLOAD_URL, downloadUrl );
+ result.setArtifact( artifact.setProperties( props ) );
+ }
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/ArtifactDescriptorUtils.java b/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/ArtifactDescriptorUtils.java
new file mode 100644
index 00000000..7d4ede87
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/ArtifactDescriptorUtils.java
@@ -0,0 +1,81 @@
+package org.apache.maven.repository.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.model.Repository;
+import org.eclipse.aether.artifact.Artifact;
+import org.eclipse.aether.artifact.DefaultArtifact;
+import org.eclipse.aether.repository.RemoteRepository;
+import org.eclipse.aether.repository.RepositoryPolicy;
+
+/**
+ * <strong>Warning:</strong> This is an internal utility class that is only public for technical reasons, it is not part
+ * of the public API. In particular, this class can be changed or deleted without prior notice.
+ *
+ * @author Benjamin Bentmann
+ */
+public class ArtifactDescriptorUtils
+{
+
+ public static Artifact toPomArtifact( Artifact artifact )
+ {
+ Artifact pomArtifact = artifact;
+
+ if ( pomArtifact.getClassifier().length() > 0 || !"pom".equals( pomArtifact.getExtension() ) )
+ {
+ pomArtifact =
+ new DefaultArtifact( artifact.getGroupId(), artifact.getArtifactId(), "pom", artifact.getVersion() );
+ }
+
+ return pomArtifact;
+ }
+
+ public static RemoteRepository toRemoteRepository( Repository repository )
+ {
+ RemoteRepository.Builder builder =
+ new RemoteRepository.Builder( repository.getId(), repository.getLayout(), repository.getUrl() );
+ builder.setSnapshotPolicy( toRepositoryPolicy( repository.getSnapshots() ) );
+ builder.setReleasePolicy( toRepositoryPolicy( repository.getReleases() ) );
+ return builder.build();
+ }
+
+ public static RepositoryPolicy toRepositoryPolicy( org.apache.maven.model.RepositoryPolicy policy )
+ {
+ boolean enabled = true;
+ String checksums = RepositoryPolicy.CHECKSUM_POLICY_WARN;
+ String updates = RepositoryPolicy.UPDATE_POLICY_DAILY;
+
+ if ( policy != null )
+ {
+ enabled = policy.isEnabled();
+ if ( policy.getUpdatePolicy() != null )
+ {
+ updates = policy.getUpdatePolicy();
+ }
+ if ( policy.getChecksumPolicy() != null )
+ {
+ checksums = policy.getChecksumPolicy();
+ }
+ }
+
+ return new RepositoryPolicy( enabled, updates, checksums );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/DefaultArtifactDescriptorReader.java b/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/DefaultArtifactDescriptorReader.java
new file mode 100644
index 00000000..a768de56
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/DefaultArtifactDescriptorReader.java
@@ -0,0 +1,435 @@
+package org.apache.maven.repository.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import org.apache.maven.model.DistributionManagement;
+import org.apache.maven.model.Model;
+import org.apache.maven.model.Relocation;
+import org.apache.maven.model.building.DefaultModelBuilderFactory;
+import org.apache.maven.model.building.DefaultModelBuildingRequest;
+import org.apache.maven.model.building.FileModelSource;
+import org.apache.maven.model.building.ModelBuilder;
+import org.apache.maven.model.building.ModelBuildingException;
+import org.apache.maven.model.building.ModelBuildingRequest;
+import org.apache.maven.model.building.ModelProblem;
+import org.apache.maven.model.resolution.UnresolvableModelException;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+import org.eclipse.aether.RepositoryEvent;
+import org.eclipse.aether.RepositoryEvent.EventType;
+import org.eclipse.aether.RepositoryException;
+import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.RequestTrace;
+import org.eclipse.aether.artifact.Artifact;
+import org.eclipse.aether.impl.ArtifactDescriptorReader;
+import org.eclipse.aether.impl.ArtifactResolver;
+import org.eclipse.aether.impl.RemoteRepositoryManager;
+import org.eclipse.aether.impl.RepositoryEventDispatcher;
+import org.eclipse.aether.impl.VersionRangeResolver;
+import org.eclipse.aether.impl.VersionResolver;
+import org.eclipse.aether.repository.WorkspaceReader;
+import org.eclipse.aether.repository.WorkspaceRepository;
+import org.eclipse.aether.resolution.ArtifactDescriptorException;
+import org.eclipse.aether.resolution.ArtifactDescriptorPolicy;
+import org.eclipse.aether.resolution.ArtifactDescriptorPolicyRequest;
+import org.eclipse.aether.resolution.ArtifactDescriptorRequest;
+import org.eclipse.aether.resolution.ArtifactDescriptorResult;
+import org.eclipse.aether.resolution.ArtifactRequest;
+import org.eclipse.aether.resolution.ArtifactResolutionException;
+import org.eclipse.aether.resolution.ArtifactResult;
+import org.eclipse.aether.resolution.VersionRequest;
+import org.eclipse.aether.resolution.VersionResolutionException;
+import org.eclipse.aether.resolution.VersionResult;
+import org.eclipse.aether.spi.locator.Service;
+import org.eclipse.aether.spi.locator.ServiceLocator;
+import org.eclipse.aether.spi.log.Logger;
+import org.eclipse.aether.spi.log.LoggerFactory;
+import org.eclipse.aether.spi.log.NullLoggerFactory;
+import org.eclipse.aether.transfer.ArtifactNotFoundException;
+
+/**
+ * @author Benjamin Bentmann
+ */
+@Named
+@Component( role = ArtifactDescriptorReader.class )
+public class DefaultArtifactDescriptorReader
+ implements ArtifactDescriptorReader, Service
+{
+
+ @SuppressWarnings( "unused" )
+ @Requirement( role = LoggerFactory.class )
+ private Logger logger = NullLoggerFactory.LOGGER;
+
+ @Requirement
+ private RemoteRepositoryManager remoteRepositoryManager;
+
+ @Requirement
+ private VersionResolver versionResolver;
+
+ @Requirement
+ private VersionRangeResolver versionRangeResolver;
+
+ @Requirement
+ private ArtifactResolver artifactResolver;
+
+ @Requirement
+ private RepositoryEventDispatcher repositoryEventDispatcher;
+
+ @Requirement
+ private ModelBuilder modelBuilder;
+
+ public DefaultArtifactDescriptorReader()
+ {
+ // enable no-arg constructor
+ }
+
+ @Inject
+ DefaultArtifactDescriptorReader( RemoteRepositoryManager remoteRepositoryManager, VersionResolver versionResolver,
+ ArtifactResolver artifactResolver, ModelBuilder modelBuilder,
+ RepositoryEventDispatcher repositoryEventDispatcher, LoggerFactory loggerFactory )
+ {
+ setRemoteRepositoryManager( remoteRepositoryManager );
+ setVersionResolver( versionResolver );
+ setArtifactResolver( artifactResolver );
+ setModelBuilder( modelBuilder );
+ setLoggerFactory( loggerFactory );
+ setRepositoryEventDispatcher( repositoryEventDispatcher );
+ }
+
+ public void initService( ServiceLocator locator )
+ {
+ setLoggerFactory( locator.getService( LoggerFactory.class ) );
+ setRemoteRepositoryManager( locator.getService( RemoteRepositoryManager.class ) );
+ setVersionResolver( locator.getService( VersionResolver.class ) );
+ setVersionRangeResolver( locator.getService( VersionRangeResolver.class ) );
+ setArtifactResolver( locator.getService( ArtifactResolver.class ) );
+ setRepositoryEventDispatcher( locator.getService( RepositoryEventDispatcher.class ) );
+ modelBuilder = locator.getService( ModelBuilder.class );
+ if ( modelBuilder == null )
+ {
+ setModelBuilder( new DefaultModelBuilderFactory().newInstance() );
+ }
+ }
+
+ public DefaultArtifactDescriptorReader setLoggerFactory( LoggerFactory loggerFactory )
+ {
+ this.logger = NullLoggerFactory.getSafeLogger( loggerFactory, getClass() );
+ return this;
+ }
+
+ void setLogger( LoggerFactory loggerFactory )
+ {
+ // plexus support
+ setLoggerFactory( loggerFactory );
+ }
+
+ public DefaultArtifactDescriptorReader setRemoteRepositoryManager( RemoteRepositoryManager remoteRepositoryManager )
+ {
+ if ( remoteRepositoryManager == null )
+ {
+ throw new IllegalArgumentException( "remote repository manager has not been specified" );
+ }
+ this.remoteRepositoryManager = remoteRepositoryManager;
+ return this;
+ }
+
+ public DefaultArtifactDescriptorReader setVersionResolver( VersionResolver versionResolver )
+ {
+ if ( versionResolver == null )
+ {
+ throw new IllegalArgumentException( "version resolver has not been specified" );
+ }
+ this.versionResolver = versionResolver;
+ return this;
+ }
+
+ /** @since 3.2.2 */
+ public DefaultArtifactDescriptorReader setVersionRangeResolver( VersionRangeResolver versionRangeResolver )
+ {
+ if ( versionRangeResolver == null )
+ {
+ throw new IllegalArgumentException( "version range resolver has not been specified" );
+ }
+ this.versionRangeResolver = versionRangeResolver;
+ return this;
+ }
+
+ public DefaultArtifactDescriptorReader setArtifactResolver( ArtifactResolver artifactResolver )
+ {
+ if ( artifactResolver == null )
+ {
+ throw new IllegalArgumentException( "artifact resolver has not been specified" );
+ }
+ this.artifactResolver = artifactResolver;
+ return this;
+ }
+
+ public DefaultArtifactDescriptorReader setRepositoryEventDispatcher( RepositoryEventDispatcher red )
+ {
+ if ( red == null )
+ {
+ throw new IllegalArgumentException( "repository event dispatcher has not been specified" );
+ }
+ this.repositoryEventDispatcher = red;
+ return this;
+ }
+
+ public DefaultArtifactDescriptorReader setModelBuilder( ModelBuilder modelBuilder )
+ {
+ if ( modelBuilder == null )
+ {
+ throw new IllegalArgumentException( "model builder has not been specified" );
+ }
+ this.modelBuilder = modelBuilder;
+ return this;
+ }
+
+ public ArtifactDescriptorResult readArtifactDescriptor( RepositorySystemSession session,
+ ArtifactDescriptorRequest request )
+ throws ArtifactDescriptorException
+ {
+ ArtifactDescriptorResult result = new ArtifactDescriptorResult( request );
+
+ Model model = loadPom( session, request, result );
+ if ( model != null )
+ {
+ Map<String, Object> config = session.getConfigProperties();
+ ArtifactDescriptorReaderDelegate delegate =
+ (ArtifactDescriptorReaderDelegate) config.get( ArtifactDescriptorReaderDelegate.class.getName() );
+
+ if ( delegate == null )
+ {
+ delegate = new ArtifactDescriptorReaderDelegate();
+ }
+
+ delegate.populateResult( session, result, model );
+ }
+
+ return result;
+ }
+
+ private Model loadPom( RepositorySystemSession session, ArtifactDescriptorRequest request,
+ ArtifactDescriptorResult result )
+ throws ArtifactDescriptorException
+ {
+ RequestTrace trace = RequestTrace.newChild( request.getTrace(), request );
+
+ Set<String> visited = new LinkedHashSet<String>();
+ for ( Artifact a = request.getArtifact();; )
+ {
+ Artifact pomArtifact = ArtifactDescriptorUtils.toPomArtifact( a );
+ try
+ {
+ VersionRequest versionRequest =
+ new VersionRequest( a, request.getRepositories(), request.getRequestContext() );
+ versionRequest.setTrace( trace );
+ VersionResult versionResult = versionResolver.resolveVersion( session, versionRequest );
+
+ a = a.setVersion( versionResult.getVersion() );
+
+ versionRequest =
+ new VersionRequest( pomArtifact, request.getRepositories(), request.getRequestContext() );
+ versionRequest.setTrace( trace );
+ versionResult = versionResolver.resolveVersion( session, versionRequest );
+
+ pomArtifact = pomArtifact.setVersion( versionResult.getVersion() );
+ }
+ catch ( VersionResolutionException e )
+ {
+ result.addException( e );
+ throw new ArtifactDescriptorException( result );
+ }
+
+ if ( !visited.add( a.getGroupId() + ':' + a.getArtifactId() + ':' + a.getBaseVersion() ) )
+ {
+ RepositoryException exception =
+ new RepositoryException( "Artifact relocations form a cycle: " + visited );
+ invalidDescriptor( session, trace, a, exception );
+ if ( ( getPolicy( session, a, request ) & ArtifactDescriptorPolicy.IGNORE_INVALID ) != 0 )
+ {
+ return null;
+ }
+ result.addException( exception );
+ throw new ArtifactDescriptorException( result );
+ }
+
+ ArtifactResult resolveResult;
+ try
+ {
+ ArtifactRequest resolveRequest =
+ new ArtifactRequest( pomArtifact, request.getRepositories(), request.getRequestContext() );
+ resolveRequest.setTrace( trace );
+ resolveResult = artifactResolver.resolveArtifact( session, resolveRequest );
+ pomArtifact = resolveResult.getArtifact();
+ result.setRepository( resolveResult.getRepository() );
+ }
+ catch ( ArtifactResolutionException e )
+ {
+ if ( e.getCause() instanceof ArtifactNotFoundException )
+ {
+ missingDescriptor( session, trace, a, (Exception) e.getCause() );
+ if ( ( getPolicy( session, a, request ) & ArtifactDescriptorPolicy.IGNORE_MISSING ) != 0 )
+ {
+ return null;
+ }
+ }
+ result.addException( e );
+ throw new ArtifactDescriptorException( result );
+ }
+
+ Model model;
+
+ // hack: don't rebuild model if it was already loaded during reactor resolution
+ final WorkspaceReader workspace = session.getWorkspaceReader();
+ if ( workspace instanceof MavenWorkspaceReader )
+ {
+ model = ( (MavenWorkspaceReader) workspace ).findModel( pomArtifact );
+ if ( model != null )
+ {
+ return model;
+ }
+ }
+
+ try
+ {
+ ModelBuildingRequest modelRequest = new DefaultModelBuildingRequest();
+ modelRequest.setValidationLevel( ModelBuildingRequest.VALIDATION_LEVEL_MINIMAL );
+ modelRequest.setProcessPlugins( false );
+ modelRequest.setTwoPhaseBuilding( false );
+ modelRequest.setSystemProperties( toProperties( session.getUserProperties(),
+ session.getSystemProperties() ) );
+ modelRequest.setModelCache( DefaultModelCache.newInstance( session ) );
+ modelRequest.setModelResolver( new DefaultModelResolver( session, trace.newChild( modelRequest ),
+ request.getRequestContext(), artifactResolver,
+ versionRangeResolver, remoteRepositoryManager,
+ request.getRepositories() ) );
+ if ( resolveResult.getRepository() instanceof WorkspaceRepository )
+ {
+ modelRequest.setPomFile( pomArtifact.getFile() );
+ }
+ else
+ {
+ modelRequest.setModelSource( new FileModelSource( pomArtifact.getFile() ) );
+ }
+
+ model = modelBuilder.build( modelRequest ).getEffectiveModel();
+ }
+ catch ( ModelBuildingException e )
+ {
+ for ( ModelProblem problem : e.getProblems() )
+ {
+ if ( problem.getException() instanceof UnresolvableModelException )
+ {
+ result.addException( problem.getException() );
+ throw new ArtifactDescriptorException( result );
+ }
+ }
+ invalidDescriptor( session, trace, a, e );
+ if ( ( getPolicy( session, a, request ) & ArtifactDescriptorPolicy.IGNORE_INVALID ) != 0 )
+ {
+ return null;
+ }
+ result.addException( e );
+ throw new ArtifactDescriptorException( result );
+ }
+
+ Relocation relocation = getRelocation( model );
+
+ if ( relocation != null )
+ {
+ result.addRelocation( a );
+ a =
+ new RelocatedArtifact( a, relocation.getGroupId(), relocation.getArtifactId(),
+ relocation.getVersion() );
+ result.setArtifact( a );
+ }
+ else
+ {
+ return model;
+ }
+ }
+ }
+
+ private Properties toProperties( Map<String, String> dominant, Map<String, String> recessive )
+ {
+ Properties props = new Properties();
+ if ( recessive != null )
+ {
+ props.putAll( recessive );
+ }
+ if ( dominant != null )
+ {
+ props.putAll( dominant );
+ }
+ return props;
+ }
+
+ private Relocation getRelocation( Model model )
+ {
+ Relocation relocation = null;
+ DistributionManagement distMngt = model.getDistributionManagement();
+ if ( distMngt != null )
+ {
+ relocation = distMngt.getRelocation();
+ }
+ return relocation;
+ }
+
+ private void missingDescriptor( RepositorySystemSession session, RequestTrace trace, Artifact artifact,
+ Exception exception )
+ {
+ RepositoryEvent.Builder event = new RepositoryEvent.Builder( session, EventType.ARTIFACT_DESCRIPTOR_MISSING );
+ event.setTrace( trace );
+ event.setArtifact( artifact );
+ event.setException( exception );
+
+ repositoryEventDispatcher.dispatch( event.build() );
+ }
+
+ private void invalidDescriptor( RepositorySystemSession session, RequestTrace trace, Artifact artifact,
+ Exception exception )
+ {
+ RepositoryEvent.Builder event = new RepositoryEvent.Builder( session, EventType.ARTIFACT_DESCRIPTOR_INVALID );
+ event.setTrace( trace );
+ event.setArtifact( artifact );
+ event.setException( exception );
+
+ repositoryEventDispatcher.dispatch( event.build() );
+ }
+
+ private int getPolicy( RepositorySystemSession session, Artifact a, ArtifactDescriptorRequest request )
+ {
+ ArtifactDescriptorPolicy policy = session.getArtifactDescriptorPolicy();
+ if ( policy == null )
+ {
+ return ArtifactDescriptorPolicy.STRICT;
+ }
+ return policy.getPolicy( session, new ArtifactDescriptorPolicyRequest( a, request.getRequestContext() ) );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/DefaultModelCache.java b/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/DefaultModelCache.java
new file mode 100644
index 00000000..f13495df
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/DefaultModelCache.java
@@ -0,0 +1,119 @@
+package org.apache.maven.repository.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.model.building.ModelCache;
+import org.eclipse.aether.RepositoryCache;
+import org.eclipse.aether.RepositorySystemSession;
+
+/**
+ * A model builder cache backed by the repository system cache.
+ *
+ * @author Benjamin Bentmann
+ */
+class DefaultModelCache
+ implements ModelCache
+{
+
+ private final RepositorySystemSession session;
+
+ private final RepositoryCache cache;
+
+ public static ModelCache newInstance( RepositorySystemSession session )
+ {
+ if ( session.getCache() == null )
+ {
+ return null;
+ }
+ else
+ {
+ return new DefaultModelCache( session );
+ }
+ }
+
+ private DefaultModelCache( RepositorySystemSession session )
+ {
+ this.session = session;
+ this.cache = session.getCache();
+ }
+
+ public Object get( String groupId, String artifactId, String version, String tag )
+ {
+ return cache.get( session, new Key( groupId, artifactId, version, tag ) );
+ }
+
+ public void put( String groupId, String artifactId, String version, String tag, Object data )
+ {
+ cache.put( session, new Key( groupId, artifactId, version, tag ), data );
+ }
+
+ static class Key
+ {
+
+ private final String groupId;
+
+ private final String artifactId;
+
+ private final String version;
+
+ private final String tag;
+
+ private final int hash;
+
+ public Key( String groupId, String artifactId, String version, String tag )
+ {
+ this.groupId = groupId;
+ this.artifactId = artifactId;
+ this.version = version;
+ this.tag = tag;
+
+ int h = 17;
+ h = h * 31 + this.groupId.hashCode();
+ h = h * 31 + this.artifactId.hashCode();
+ h = h * 31 + this.version.hashCode();
+ h = h * 31 + this.tag.hashCode();
+ hash = h;
+ }
+
+ @Override
+ public boolean equals( Object obj )
+ {
+ if ( this == obj )
+ {
+ return true;
+ }
+ if ( null == obj || !getClass().equals( obj.getClass() ) )
+ {
+ return false;
+ }
+
+ Key that = (Key) obj;
+ return artifactId.equals( that.artifactId ) && groupId.equals( that.groupId )
+ && version.equals( that.version ) && tag.equals( that.tag );
+ }
+
+ @Override
+ public int hashCode()
+ {
+ return hash;
+ }
+
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/DefaultModelResolver.java b/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/DefaultModelResolver.java
new file mode 100644
index 00000000..7cd47475
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/DefaultModelResolver.java
@@ -0,0 +1,229 @@
+package org.apache.maven.repository.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import com.google.common.base.Predicate;
+import com.google.common.collect.Iterables;
+import org.apache.maven.model.Parent;
+import org.apache.maven.model.Repository;
+import org.apache.maven.model.building.FileModelSource;
+import org.apache.maven.model.building.ModelSource;
+import org.apache.maven.model.resolution.InvalidRepositoryException;
+import org.apache.maven.model.resolution.ModelResolver;
+import org.apache.maven.model.resolution.UnresolvableModelException;
+import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.RequestTrace;
+import org.eclipse.aether.artifact.Artifact;
+import org.eclipse.aether.artifact.DefaultArtifact;
+import org.eclipse.aether.impl.ArtifactResolver;
+import org.eclipse.aether.impl.RemoteRepositoryManager;
+import org.eclipse.aether.impl.VersionRangeResolver;
+import org.eclipse.aether.repository.RemoteRepository;
+import org.eclipse.aether.resolution.ArtifactRequest;
+import org.eclipse.aether.resolution.ArtifactResolutionException;
+import org.eclipse.aether.resolution.VersionRangeRequest;
+import org.eclipse.aether.resolution.VersionRangeResolutionException;
+import org.eclipse.aether.resolution.VersionRangeResult;
+
+/**
+ * A model resolver to assist building of dependency POMs. This resolver gives priority to those repositories that have
+ * been initially specified and repositories discovered in dependency POMs are recessively merged into the search chain.
+ *
+ * @author Benjamin Bentmann
+ * @see DefaultArtifactDescriptorReader
+ */
+class DefaultModelResolver
+ implements ModelResolver
+{
+
+ private final RepositorySystemSession session;
+
+ private final RequestTrace trace;
+
+ private final String context;
+
+ private List<RemoteRepository> repositories;
+
+ private final List<RemoteRepository> externalRepositories;
+
+ private final ArtifactResolver resolver;
+
+ private final VersionRangeResolver versionRangeResolver;
+
+ private final RemoteRepositoryManager remoteRepositoryManager;
+
+ private final Set<String> repositoryIds;
+
+ public DefaultModelResolver( RepositorySystemSession session, RequestTrace trace, String context,
+ ArtifactResolver resolver, VersionRangeResolver versionRangeResolver,
+ RemoteRepositoryManager remoteRepositoryManager, List<RemoteRepository> repositories )
+ {
+ this.session = session;
+ this.trace = trace;
+ this.context = context;
+ this.resolver = resolver;
+ this.versionRangeResolver = versionRangeResolver;
+ this.remoteRepositoryManager = remoteRepositoryManager;
+ this.repositories = repositories;
+ List<RemoteRepository> externalRepositories = new ArrayList<RemoteRepository>();
+ externalRepositories.addAll( repositories );
+ this.externalRepositories = Collections.unmodifiableList( externalRepositories );
+
+ this.repositoryIds = new HashSet<String>();
+ }
+
+ private DefaultModelResolver( DefaultModelResolver original )
+ {
+ this.session = original.session;
+ this.trace = original.trace;
+ this.context = original.context;
+ this.resolver = original.resolver;
+ this.versionRangeResolver = original.versionRangeResolver;
+ this.remoteRepositoryManager = original.remoteRepositoryManager;
+ this.repositories = new ArrayList<RemoteRepository>( original.repositories );
+ this.externalRepositories = original.externalRepositories;
+ this.repositoryIds = new HashSet<String>( original.repositoryIds );
+ }
+
+ @Override
+ public void addRepository( Repository repository )
+ throws InvalidRepositoryException
+ {
+ addRepository( repository, false );
+ }
+
+ @Override
+ public void addRepository( final Repository repository, boolean replace )
+ throws InvalidRepositoryException
+ {
+ if ( session.isIgnoreArtifactDescriptorRepositories() )
+ {
+ return;
+ }
+
+ if ( !repositoryIds.add( repository.getId() ) )
+ {
+ if ( !replace )
+ {
+ return;
+ }
+
+ removeMatchingRepository( repositories, repository.getId() );
+ }
+
+ List<RemoteRepository> newRepositories =
+ Collections.singletonList( ArtifactDescriptorUtils.toRemoteRepository( repository ) );
+
+ this.repositories =
+ remoteRepositoryManager.aggregateRepositories( session, repositories, newRepositories, true );
+ }
+
+ private static void removeMatchingRepository( Iterable<RemoteRepository> repositories, final String id )
+ {
+ Iterables.removeIf( repositories, new Predicate<RemoteRepository>()
+ {
+ @Override
+ public boolean apply( RemoteRepository remoteRepository )
+ {
+ return remoteRepository.getId().equals( id );
+ }
+ } );
+ }
+
+ @Override
+ public ModelResolver newCopy()
+ {
+ return new DefaultModelResolver( this );
+ }
+
+ @Override
+ public ModelSource resolveModel( String groupId, String artifactId, String version )
+ throws UnresolvableModelException
+ {
+ Artifact pomArtifact = new DefaultArtifact( groupId, artifactId, "", "pom", version );
+
+ try
+ {
+ ArtifactRequest request = new ArtifactRequest( pomArtifact, repositories, context );
+ request.setTrace( trace );
+ pomArtifact = resolver.resolveArtifact( session, request ).getArtifact();
+ }
+ catch ( ArtifactResolutionException e )
+ {
+ throw new UnresolvableModelException( e.getMessage(), groupId, artifactId, version, e );
+ }
+
+ File pomFile = pomArtifact.getFile();
+
+ return new FileModelSource( pomFile );
+ }
+
+ public ModelSource resolveModel( Parent parent )
+ throws UnresolvableModelException
+ {
+ Artifact artifact = new DefaultArtifact( parent.getGroupId(), parent.getArtifactId(), "", "pom",
+ parent.getVersion() );
+
+ VersionRangeRequest versionRangeRequest = new VersionRangeRequest( artifact, repositories, context );
+ versionRangeRequest.setTrace( trace );
+
+ try
+ {
+ VersionRangeResult versionRangeResult =
+ versionRangeResolver.resolveVersionRange( session, versionRangeRequest );
+
+ if ( versionRangeResult.getHighestVersion() == null )
+ {
+ throw new UnresolvableModelException( "No versions matched the requested range '" + parent.getVersion()
+ + "'", parent.getGroupId(), parent.getArtifactId(),
+ parent.getVersion() );
+
+ }
+
+ if ( versionRangeResult.getVersionConstraint() != null
+ && versionRangeResult.getVersionConstraint().getRange() != null
+ && versionRangeResult.getVersionConstraint().getRange().getUpperBound() == null )
+ {
+ throw new UnresolvableModelException( "The requested version range '" + parent.getVersion()
+ + "' does not specify an upper bound", parent.getGroupId(),
+ parent.getArtifactId(), parent.getVersion() );
+
+ }
+
+ parent.setVersion( versionRangeResult.getHighestVersion().toString() );
+ }
+ catch ( VersionRangeResolutionException e )
+ {
+ throw new UnresolvableModelException( e.getMessage(), parent.getGroupId(), parent.getArtifactId(),
+ parent.getVersion(), e );
+
+ }
+
+ return resolveModel( parent.getGroupId(), parent.getArtifactId(), parent.getVersion() );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/DefaultVersionRangeResolver.java b/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/DefaultVersionRangeResolver.java
new file mode 100644
index 00000000..e8ba06b9
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/DefaultVersionRangeResolver.java
@@ -0,0 +1,322 @@
+package org.apache.maven.repository.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.FileInputStream;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import org.apache.maven.artifact.repository.metadata.Versioning;
+import org.apache.maven.artifact.repository.metadata.io.xpp3.MetadataXpp3Reader;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+import org.codehaus.plexus.util.IOUtil;
+import org.eclipse.aether.RepositoryEvent.EventType;
+import org.eclipse.aether.RepositoryEvent;
+import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.RequestTrace;
+import org.eclipse.aether.SyncContext;
+import org.eclipse.aether.impl.MetadataResolver;
+import org.eclipse.aether.impl.RepositoryEventDispatcher;
+import org.eclipse.aether.impl.SyncContextFactory;
+import org.eclipse.aether.impl.VersionRangeResolver;
+import org.eclipse.aether.metadata.DefaultMetadata;
+import org.eclipse.aether.metadata.Metadata;
+import org.eclipse.aether.repository.ArtifactRepository;
+import org.eclipse.aether.repository.RemoteRepository;
+import org.eclipse.aether.repository.WorkspaceReader;
+import org.eclipse.aether.resolution.MetadataRequest;
+import org.eclipse.aether.resolution.MetadataResult;
+import org.eclipse.aether.resolution.VersionRangeRequest;
+import org.eclipse.aether.resolution.VersionRangeResolutionException;
+import org.eclipse.aether.resolution.VersionRangeResult;
+import org.eclipse.aether.spi.locator.Service;
+import org.eclipse.aether.spi.locator.ServiceLocator;
+import org.eclipse.aether.spi.log.Logger;
+import org.eclipse.aether.spi.log.LoggerFactory;
+import org.eclipse.aether.spi.log.NullLoggerFactory;
+import org.eclipse.aether.util.version.GenericVersionScheme;
+import org.eclipse.aether.version.InvalidVersionSpecificationException;
+import org.eclipse.aether.version.Version;
+import org.eclipse.aether.version.VersionConstraint;
+import org.eclipse.aether.version.VersionScheme;
+
+/**
+ * @author Benjamin Bentmann
+ */
+@Named
+@Component( role = VersionRangeResolver.class )
+public class DefaultVersionRangeResolver
+ implements VersionRangeResolver, Service
+{
+
+ private static final String MAVEN_METADATA_XML = "maven-metadata.xml";
+
+ @SuppressWarnings( "unused" )
+ @Requirement( role = LoggerFactory.class )
+ private Logger logger = NullLoggerFactory.LOGGER;
+
+ @Requirement
+ private MetadataResolver metadataResolver;
+
+ @Requirement
+ private SyncContextFactory syncContextFactory;
+
+ @Requirement
+ private RepositoryEventDispatcher repositoryEventDispatcher;
+
+ public DefaultVersionRangeResolver()
+ {
+ // enable default constructor
+ }
+
+ @Inject
+ DefaultVersionRangeResolver( MetadataResolver metadataResolver, SyncContextFactory syncContextFactory,
+ RepositoryEventDispatcher repositoryEventDispatcher, LoggerFactory loggerFactory )
+ {
+ setMetadataResolver( metadataResolver );
+ setSyncContextFactory( syncContextFactory );
+ setLoggerFactory( loggerFactory );
+ setRepositoryEventDispatcher( repositoryEventDispatcher );
+ }
+
+ public void initService( ServiceLocator locator )
+ {
+ setLoggerFactory( locator.getService( LoggerFactory.class ) );
+ setMetadataResolver( locator.getService( MetadataResolver.class ) );
+ setSyncContextFactory( locator.getService( SyncContextFactory.class ) );
+ setRepositoryEventDispatcher( locator.getService( RepositoryEventDispatcher.class ) );
+ }
+
+ public DefaultVersionRangeResolver setLoggerFactory( LoggerFactory loggerFactory )
+ {
+ this.logger = NullLoggerFactory.getSafeLogger( loggerFactory, getClass() );
+ return this;
+ }
+
+ void setLogger( LoggerFactory loggerFactory )
+ {
+ // plexus support
+ setLoggerFactory( loggerFactory );
+ }
+
+ public DefaultVersionRangeResolver setMetadataResolver( MetadataResolver metadataResolver )
+ {
+ if ( metadataResolver == null )
+ {
+ throw new IllegalArgumentException( "metadata resolver has not been specified" );
+ }
+ this.metadataResolver = metadataResolver;
+ return this;
+ }
+
+ public DefaultVersionRangeResolver setSyncContextFactory( SyncContextFactory syncContextFactory )
+ {
+ if ( syncContextFactory == null )
+ {
+ throw new IllegalArgumentException( "sync context factory has not been specified" );
+ }
+ this.syncContextFactory = syncContextFactory;
+ return this;
+ }
+
+ public DefaultVersionRangeResolver setRepositoryEventDispatcher( RepositoryEventDispatcher red )
+ {
+ if ( red == null )
+ {
+ throw new IllegalArgumentException( "repository event dispatcher has not been specified" );
+ }
+ this.repositoryEventDispatcher = red;
+ return this;
+ }
+
+ public VersionRangeResult resolveVersionRange( RepositorySystemSession session, VersionRangeRequest request )
+ throws VersionRangeResolutionException
+ {
+ VersionRangeResult result = new VersionRangeResult( request );
+
+ VersionScheme versionScheme = new GenericVersionScheme();
+
+ VersionConstraint versionConstraint;
+ try
+ {
+ versionConstraint = versionScheme.parseVersionConstraint( request.getArtifact().getVersion() );
+ }
+ catch ( InvalidVersionSpecificationException e )
+ {
+ result.addException( e );
+ throw new VersionRangeResolutionException( result );
+ }
+
+ result.setVersionConstraint( versionConstraint );
+
+ if ( versionConstraint.getRange() == null )
+ {
+ result.addVersion( versionConstraint.getVersion() );
+ }
+ else
+ {
+ Map<String, ArtifactRepository> versionIndex = getVersions( session, result, request );
+
+ List<Version> versions = new ArrayList<Version>();
+ for ( Map.Entry<String, ArtifactRepository> v : versionIndex.entrySet() )
+ {
+ try
+ {
+ Version ver = versionScheme.parseVersion( v.getKey() );
+ if ( versionConstraint.containsVersion( ver ) )
+ {
+ versions.add( ver );
+ result.setRepository( ver, v.getValue() );
+ }
+ }
+ catch ( InvalidVersionSpecificationException e )
+ {
+ result.addException( e );
+ }
+ }
+
+ Collections.sort( versions );
+ result.setVersions( versions );
+ }
+
+ return result;
+ }
+
+ private Map<String, ArtifactRepository> getVersions( RepositorySystemSession session, VersionRangeResult result,
+ VersionRangeRequest request )
+ {
+ RequestTrace trace = RequestTrace.newChild( request.getTrace(), request );
+
+ Map<String, ArtifactRepository> versionIndex = new HashMap<String, ArtifactRepository>();
+
+ Metadata metadata =
+ new DefaultMetadata( request.getArtifact().getGroupId(), request.getArtifact().getArtifactId(),
+ MAVEN_METADATA_XML, Metadata.Nature.RELEASE_OR_SNAPSHOT );
+
+ List<MetadataRequest> metadataRequests = new ArrayList<MetadataRequest>( request.getRepositories().size() );
+
+ metadataRequests.add( new MetadataRequest( metadata, null, request.getRequestContext() ) );
+
+ for ( RemoteRepository repository : request.getRepositories() )
+ {
+ MetadataRequest metadataRequest = new MetadataRequest( metadata, repository, request.getRequestContext() );
+ metadataRequest.setDeleteLocalCopyIfMissing( true );
+ metadataRequest.setTrace( trace );
+ metadataRequests.add( metadataRequest );
+ }
+
+ List<MetadataResult> metadataResults = metadataResolver.resolveMetadata( session, metadataRequests );
+
+ WorkspaceReader workspace = session.getWorkspaceReader();
+ if ( workspace != null )
+ {
+ List<String> versions = workspace.findVersions( request.getArtifact() );
+ for ( String version : versions )
+ {
+ versionIndex.put( version, workspace.getRepository() );
+ }
+ }
+
+ for ( MetadataResult metadataResult : metadataResults )
+ {
+ result.addException( metadataResult.getException() );
+
+ ArtifactRepository repository = metadataResult.getRequest().getRepository();
+ if ( repository == null )
+ {
+ repository = session.getLocalRepository();
+ }
+
+ Versioning versioning = readVersions( session, trace, metadataResult.getMetadata(), repository, result );
+ for ( String version : versioning.getVersions() )
+ {
+ if ( !versionIndex.containsKey( version ) )
+ {
+ versionIndex.put( version, repository );
+ }
+ }
+ }
+
+ return versionIndex;
+ }
+
+ private Versioning readVersions( RepositorySystemSession session, RequestTrace trace, Metadata metadata,
+ ArtifactRepository repository, VersionRangeResult result )
+ {
+ Versioning versioning = null;
+
+ FileInputStream fis = null;
+ try
+ {
+ if ( metadata != null )
+ {
+ SyncContext syncContext = syncContextFactory.newInstance( session, true );
+
+ try
+ {
+ syncContext.acquire( null, Collections.singleton( metadata ) );
+
+ if ( metadata.getFile() != null && metadata.getFile().exists() )
+ {
+ fis = new FileInputStream( metadata.getFile() );
+ org.apache.maven.artifact.repository.metadata.Metadata m =
+ new MetadataXpp3Reader().read( fis, false );
+ versioning = m.getVersioning();
+ }
+ }
+ finally
+ {
+ syncContext.close();
+ }
+ }
+ }
+ catch ( Exception e )
+ {
+ invalidMetadata( session, trace, metadata, repository, e );
+ result.addException( e );
+ }
+ finally
+ {
+ IOUtil.close( fis );
+ }
+
+ return ( versioning != null ) ? versioning : new Versioning();
+ }
+
+ private void invalidMetadata( RepositorySystemSession session, RequestTrace trace, Metadata metadata,
+ ArtifactRepository repository, Exception exception )
+ {
+ RepositoryEvent.Builder event = new RepositoryEvent.Builder( session, EventType.METADATA_INVALID );
+ event.setTrace( trace );
+ event.setMetadata( metadata );
+ event.setException( exception );
+ event.setRepository( repository );
+
+ repositoryEventDispatcher.dispatch( event.build() );
+ }
+
+} \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/DefaultVersionResolver.java b/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/DefaultVersionResolver.java
new file mode 100644
index 00000000..d722644e
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/DefaultVersionResolver.java
@@ -0,0 +1,636 @@
+package org.apache.maven.repository.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import org.apache.maven.artifact.repository.metadata.Snapshot;
+import org.apache.maven.artifact.repository.metadata.SnapshotVersion;
+import org.apache.maven.artifact.repository.metadata.Versioning;
+import org.apache.maven.artifact.repository.metadata.io.xpp3.MetadataXpp3Reader;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+import org.codehaus.plexus.util.IOUtil;
+import org.codehaus.plexus.util.StringUtils;
+import org.eclipse.aether.RepositoryCache;
+import org.eclipse.aether.RepositoryEvent.EventType;
+import org.eclipse.aether.RepositoryEvent;
+import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.RequestTrace;
+import org.eclipse.aether.SyncContext;
+import org.eclipse.aether.artifact.Artifact;
+import org.eclipse.aether.impl.MetadataResolver;
+import org.eclipse.aether.impl.RepositoryEventDispatcher;
+import org.eclipse.aether.impl.SyncContextFactory;
+import org.eclipse.aether.impl.VersionResolver;
+import org.eclipse.aether.internal.impl.CacheUtils;
+import org.eclipse.aether.metadata.DefaultMetadata;
+import org.eclipse.aether.metadata.Metadata;
+import org.eclipse.aether.repository.ArtifactRepository;
+import org.eclipse.aether.repository.LocalRepository;
+import org.eclipse.aether.repository.RemoteRepository;
+import org.eclipse.aether.repository.WorkspaceReader;
+import org.eclipse.aether.repository.WorkspaceRepository;
+import org.eclipse.aether.resolution.MetadataRequest;
+import org.eclipse.aether.resolution.MetadataResult;
+import org.eclipse.aether.resolution.VersionRequest;
+import org.eclipse.aether.resolution.VersionResolutionException;
+import org.eclipse.aether.resolution.VersionResult;
+import org.eclipse.aether.spi.locator.Service;
+import org.eclipse.aether.spi.locator.ServiceLocator;
+import org.eclipse.aether.spi.log.Logger;
+import org.eclipse.aether.spi.log.LoggerFactory;
+import org.eclipse.aether.spi.log.NullLoggerFactory;
+import org.eclipse.aether.util.ConfigUtils;
+
+/**
+ * @author Benjamin Bentmann
+ */
+@Named
+@Component( role = VersionResolver.class )
+public class DefaultVersionResolver
+ implements VersionResolver, Service
+{
+
+ private static final String MAVEN_METADATA_XML = "maven-metadata.xml";
+
+ private static final String RELEASE = "RELEASE";
+
+ private static final String LATEST = "LATEST";
+
+ private static final String SNAPSHOT = "SNAPSHOT";
+
+ @SuppressWarnings( "unused" )
+ @Requirement( role = LoggerFactory.class )
+ private Logger logger = NullLoggerFactory.LOGGER;
+
+ @Requirement
+ private MetadataResolver metadataResolver;
+
+ @Requirement
+ private SyncContextFactory syncContextFactory;
+
+ @Requirement
+ private RepositoryEventDispatcher repositoryEventDispatcher;
+
+ public DefaultVersionResolver()
+ {
+ // enable no-arg constructor
+ }
+
+ @Inject
+ DefaultVersionResolver( MetadataResolver metadataResolver, SyncContextFactory syncContextFactory,
+ RepositoryEventDispatcher repositoryEventDispatcher, LoggerFactory loggerFactory )
+ {
+ setMetadataResolver( metadataResolver );
+ setSyncContextFactory( syncContextFactory );
+ setLoggerFactory( loggerFactory );
+ setRepositoryEventDispatcher( repositoryEventDispatcher );
+ }
+
+ public void initService( ServiceLocator locator )
+ {
+ setLoggerFactory( locator.getService( LoggerFactory.class ) );
+ setMetadataResolver( locator.getService( MetadataResolver.class ) );
+ setSyncContextFactory( locator.getService( SyncContextFactory.class ) );
+ setRepositoryEventDispatcher( locator.getService( RepositoryEventDispatcher.class ) );
+ }
+
+ public DefaultVersionResolver setLoggerFactory( LoggerFactory loggerFactory )
+ {
+ this.logger = NullLoggerFactory.getSafeLogger( loggerFactory, getClass() );
+ return this;
+ }
+
+ void setLogger( LoggerFactory loggerFactory )
+ {
+ // plexus support
+ setLoggerFactory( loggerFactory );
+ }
+
+ public DefaultVersionResolver setMetadataResolver( MetadataResolver metadataResolver )
+ {
+ if ( metadataResolver == null )
+ {
+ throw new IllegalArgumentException( "metadata resolver has not been specified" );
+ }
+ this.metadataResolver = metadataResolver;
+ return this;
+ }
+
+ public DefaultVersionResolver setSyncContextFactory( SyncContextFactory syncContextFactory )
+ {
+ if ( syncContextFactory == null )
+ {
+ throw new IllegalArgumentException( "sync context factory has not been specified" );
+ }
+ this.syncContextFactory = syncContextFactory;
+ return this;
+ }
+
+ public DefaultVersionResolver setRepositoryEventDispatcher( RepositoryEventDispatcher repositoryEventDispatcher )
+ {
+ if ( repositoryEventDispatcher == null )
+ {
+ throw new IllegalArgumentException( "repository event dispatcher has not been specified" );
+ }
+ this.repositoryEventDispatcher = repositoryEventDispatcher;
+ return this;
+ }
+
+ public VersionResult resolveVersion( RepositorySystemSession session, VersionRequest request )
+ throws VersionResolutionException
+ {
+ RequestTrace trace = RequestTrace.newChild( request.getTrace(), request );
+
+ Artifact artifact = request.getArtifact();
+
+ String version = artifact.getVersion();
+
+ VersionResult result = new VersionResult( request );
+
+ Key cacheKey = null;
+ RepositoryCache cache = session.getCache();
+ if ( cache != null && !ConfigUtils.getBoolean( session, false, "aether.versionResolver.noCache" ) )
+ {
+ cacheKey = new Key( session, request );
+
+ Object obj = cache.get( session, cacheKey );
+ if ( obj instanceof Record )
+ {
+ Record record = (Record) obj;
+ result.setVersion( record.version );
+ result.setRepository( CacheUtils.getRepository( session, request.getRepositories(), record.repoClass,
+ record.repoId ) );
+ return result;
+ }
+ }
+
+ Metadata metadata;
+
+ if ( RELEASE.equals( version ) )
+ {
+ metadata =
+ new DefaultMetadata( artifact.getGroupId(), artifact.getArtifactId(), MAVEN_METADATA_XML,
+ Metadata.Nature.RELEASE );
+ }
+ else if ( LATEST.equals( version ) )
+ {
+ metadata =
+ new DefaultMetadata( artifact.getGroupId(), artifact.getArtifactId(), MAVEN_METADATA_XML,
+ Metadata.Nature.RELEASE_OR_SNAPSHOT );
+ }
+ else if ( version.endsWith( SNAPSHOT ) )
+ {
+ WorkspaceReader workspace = session.getWorkspaceReader();
+ if ( workspace != null && workspace.findVersions( artifact ).contains( version ) )
+ {
+ metadata = null;
+ result.setRepository( workspace.getRepository() );
+ }
+ else
+ {
+ metadata =
+ new DefaultMetadata( artifact.getGroupId(), artifact.getArtifactId(), version, MAVEN_METADATA_XML,
+ Metadata.Nature.SNAPSHOT );
+ }
+ }
+ else
+ {
+ metadata = null;
+ }
+
+ if ( metadata == null )
+ {
+ result.setVersion( version );
+ }
+ else
+ {
+ List<MetadataRequest> metadataReqs = new ArrayList<MetadataRequest>( request.getRepositories().size() );
+
+ metadataReqs.add( new MetadataRequest( metadata, null, request.getRequestContext() ) );
+
+ for ( RemoteRepository repository : request.getRepositories() )
+ {
+ MetadataRequest metadataRequest =
+ new MetadataRequest( metadata, repository, request.getRequestContext() );
+ metadataRequest.setDeleteLocalCopyIfMissing( true );
+ metadataRequest.setFavorLocalRepository( true );
+ metadataRequest.setTrace( trace );
+ metadataReqs.add( metadataRequest );
+ }
+
+ List<MetadataResult> metadataResults = metadataResolver.resolveMetadata( session, metadataReqs );
+
+ Map<String, VersionInfo> infos = new HashMap<String, VersionInfo>();
+
+ for ( MetadataResult metadataResult : metadataResults )
+ {
+ result.addException( metadataResult.getException() );
+
+ ArtifactRepository repository = metadataResult.getRequest().getRepository();
+ if ( repository == null )
+ {
+ repository = session.getLocalRepository();
+ }
+
+ Versioning v = readVersions( session, trace, metadataResult.getMetadata(), repository, result );
+ merge( artifact, infos, v, repository );
+ }
+
+ if ( RELEASE.equals( version ) )
+ {
+ resolve( result, infos, RELEASE );
+ }
+ else if ( LATEST.equals( version ) )
+ {
+ if ( !resolve( result, infos, LATEST ) )
+ {
+ resolve( result, infos, RELEASE );
+ }
+
+ if ( result.getVersion() != null && result.getVersion().endsWith( SNAPSHOT ) )
+ {
+ VersionRequest subRequest = new VersionRequest();
+ subRequest.setArtifact( artifact.setVersion( result.getVersion() ) );
+ if ( result.getRepository() instanceof RemoteRepository )
+ {
+ RemoteRepository r = (RemoteRepository) result.getRepository();
+ subRequest.setRepositories( Collections.singletonList( r ) );
+ }
+ else
+ {
+ subRequest.setRepositories( request.getRepositories() );
+ }
+ VersionResult subResult = resolveVersion( session, subRequest );
+ result.setVersion( subResult.getVersion() );
+ result.setRepository( subResult.getRepository() );
+ for ( Exception exception : subResult.getExceptions() )
+ {
+ result.addException( exception );
+ }
+ }
+ }
+ else
+ {
+ String key = SNAPSHOT + getKey( artifact.getClassifier(), artifact.getExtension() );
+ merge( infos, SNAPSHOT, key );
+ if ( !resolve( result, infos, key ) )
+ {
+ result.setVersion( version );
+ }
+ }
+
+ if ( StringUtils.isEmpty( result.getVersion() ) )
+ {
+ throw new VersionResolutionException( result );
+ }
+ }
+
+ if ( cacheKey != null && metadata != null && isSafelyCacheable( session, artifact ) )
+ {
+ cache.put( session, cacheKey, new Record( result.getVersion(), result.getRepository() ) );
+ }
+
+ return result;
+ }
+
+ private boolean resolve( VersionResult result, Map<String, VersionInfo> infos, String key )
+ {
+ VersionInfo info = infos.get( key );
+ if ( info != null )
+ {
+ result.setVersion( info.version );
+ result.setRepository( info.repository );
+ }
+ return info != null;
+ }
+
+ private Versioning readVersions( RepositorySystemSession session, RequestTrace trace, Metadata metadata,
+ ArtifactRepository repository, VersionResult result )
+ {
+ Versioning versioning = null;
+
+ FileInputStream fis = null;
+ try
+ {
+ if ( metadata != null )
+ {
+ SyncContext syncContext = syncContextFactory.newInstance( session, true );
+
+ try
+ {
+ syncContext.acquire( null, Collections.singleton( metadata ) );
+
+ if ( metadata.getFile() != null && metadata.getFile().exists() )
+ {
+ fis = new FileInputStream( metadata.getFile() );
+ org.apache.maven.artifact.repository.metadata.Metadata m =
+ new MetadataXpp3Reader().read( fis, false );
+ versioning = m.getVersioning();
+
+ /*
+ * NOTE: Users occasionally misuse the id "local" for remote repos which screws up the metadata
+ * of the local repository. This is especially troublesome during snapshot resolution so we try
+ * to handle that gracefully.
+ */
+ if ( versioning != null && repository instanceof LocalRepository )
+ {
+ if ( versioning.getSnapshot() != null && versioning.getSnapshot().getBuildNumber() > 0 )
+ {
+ Versioning repaired = new Versioning();
+ repaired.setLastUpdated( versioning.getLastUpdated() );
+ Snapshot snapshot = new Snapshot();
+ snapshot.setLocalCopy( true );
+ repaired.setSnapshot( snapshot );
+ versioning = repaired;
+
+ throw new IOException( "Snapshot information corrupted with remote repository data"
+ + ", please verify that no remote repository uses the id '" + repository.getId()
+ + "'" );
+ }
+ }
+ }
+ }
+ finally
+ {
+ syncContext.close();
+ }
+ }
+ }
+ catch ( Exception e )
+ {
+ invalidMetadata( session, trace, metadata, repository, e );
+ result.addException( e );
+ }
+ finally
+ {
+ IOUtil.close( fis );
+ }
+
+ return ( versioning != null ) ? versioning : new Versioning();
+ }
+
+ private void invalidMetadata( RepositorySystemSession session, RequestTrace trace, Metadata metadata,
+ ArtifactRepository repository, Exception exception )
+ {
+ RepositoryEvent.Builder event = new RepositoryEvent.Builder( session, EventType.METADATA_INVALID );
+ event.setTrace( trace );
+ event.setMetadata( metadata );
+ event.setException( exception );
+ event.setRepository( repository );
+
+ repositoryEventDispatcher.dispatch( event.build() );
+ }
+
+ private void merge( Artifact artifact, Map<String, VersionInfo> infos, Versioning versioning,
+ ArtifactRepository repository )
+ {
+ if ( StringUtils.isNotEmpty( versioning.getRelease() ) )
+ {
+ merge( RELEASE, infos, versioning.getLastUpdated(), versioning.getRelease(), repository );
+ }
+
+ if ( StringUtils.isNotEmpty( versioning.getLatest() ) )
+ {
+ merge( LATEST, infos, versioning.getLastUpdated(), versioning.getLatest(), repository );
+ }
+
+ for ( SnapshotVersion sv : versioning.getSnapshotVersions() )
+ {
+ if ( StringUtils.isNotEmpty( sv.getVersion() ) )
+ {
+ String key = getKey( sv.getClassifier(), sv.getExtension() );
+ merge( SNAPSHOT + key, infos, sv.getUpdated(), sv.getVersion(), repository );
+ }
+ }
+
+ Snapshot snapshot = versioning.getSnapshot();
+ if ( snapshot != null && versioning.getSnapshotVersions().isEmpty() )
+ {
+ String version = artifact.getVersion();
+ if ( snapshot.getTimestamp() != null && snapshot.getBuildNumber() > 0 )
+ {
+ String qualifier = snapshot.getTimestamp() + '-' + snapshot.getBuildNumber();
+ version = version.substring( 0, version.length() - SNAPSHOT.length() ) + qualifier;
+ }
+ merge( SNAPSHOT, infos, versioning.getLastUpdated(), version, repository );
+ }
+ }
+
+ private void merge( String key, Map<String, VersionInfo> infos, String timestamp, String version,
+ ArtifactRepository repository )
+ {
+ VersionInfo info = infos.get( key );
+ if ( info == null )
+ {
+ info = new VersionInfo( timestamp, version, repository );
+ infos.put( key, info );
+ }
+ else if ( info.isOutdated( timestamp ) )
+ {
+ info.version = version;
+ info.repository = repository;
+ info.timestamp = timestamp;
+ }
+ }
+
+ private void merge( Map<String, VersionInfo> infos, String srcKey, String dstKey )
+ {
+ VersionInfo srcInfo = infos.get( srcKey );
+ VersionInfo dstInfo = infos.get( dstKey );
+
+ if ( dstInfo == null
+ || ( srcInfo != null && dstInfo.isOutdated( srcInfo.timestamp )
+ && srcInfo.repository != dstInfo.repository ) )
+ {
+ infos.put( dstKey, srcInfo );
+ }
+ }
+
+ private String getKey( String classifier, String extension )
+ {
+ return StringUtils.clean( classifier ) + ':' + StringUtils.clean( extension );
+ }
+
+ private boolean isSafelyCacheable( RepositorySystemSession session, Artifact artifact )
+ {
+ /*
+ * The workspace/reactor is in flux so we better not assume definitive information for any of its
+ * artifacts/projects.
+ */
+
+ WorkspaceReader workspace = session.getWorkspaceReader();
+ if ( workspace == null )
+ {
+ return true;
+ }
+
+ Artifact pomArtifact = ArtifactDescriptorUtils.toPomArtifact( artifact );
+
+ return workspace.findArtifact( pomArtifact ) == null;
+ }
+
+ private static class VersionInfo
+ {
+
+ String timestamp;
+
+ String version;
+
+ ArtifactRepository repository;
+
+ public VersionInfo( String timestamp, String version, ArtifactRepository repository )
+ {
+ this.timestamp = ( timestamp != null ) ? timestamp : "";
+ this.version = version;
+ this.repository = repository;
+ }
+
+ public boolean isOutdated( String timestamp )
+ {
+ return timestamp != null && timestamp.compareTo( this.timestamp ) > 0;
+ }
+
+ }
+
+ private static class Key
+ {
+
+ private final String groupId;
+
+ private final String artifactId;
+
+ private final String classifier;
+
+ private final String extension;
+
+ private final String version;
+
+ private final String context;
+
+ private final File localRepo;
+
+ private final WorkspaceRepository workspace;
+
+ private final List<RemoteRepository> repositories;
+
+ private final int hashCode;
+
+ public Key( RepositorySystemSession session, VersionRequest request )
+ {
+ Artifact artifact = request.getArtifact();
+ groupId = artifact.getGroupId();
+ artifactId = artifact.getArtifactId();
+ classifier = artifact.getClassifier();
+ extension = artifact.getExtension();
+ version = artifact.getVersion();
+ localRepo = session.getLocalRepository().getBasedir();
+ workspace = CacheUtils.getWorkspace( session );
+ repositories = new ArrayList<RemoteRepository>( request.getRepositories().size() );
+ boolean repoMan = false;
+ for ( RemoteRepository repository : request.getRepositories() )
+ {
+ if ( repository.isRepositoryManager() )
+ {
+ repoMan = true;
+ repositories.addAll( repository.getMirroredRepositories() );
+ }
+ else
+ {
+ repositories.add( repository );
+ }
+ }
+ context = repoMan ? request.getRequestContext() : "";
+
+ int hash = 17;
+ hash = hash * 31 + groupId.hashCode();
+ hash = hash * 31 + artifactId.hashCode();
+ hash = hash * 31 + classifier.hashCode();
+ hash = hash * 31 + extension.hashCode();
+ hash = hash * 31 + version.hashCode();
+ hash = hash * 31 + localRepo.hashCode();
+ hash = hash * 31 + CacheUtils.repositoriesHashCode( repositories );
+ hashCode = hash;
+ }
+
+ @Override
+ public boolean equals( Object obj )
+ {
+ if ( obj == this )
+ {
+ return true;
+ }
+ else if ( obj == null || !getClass().equals( obj.getClass() ) )
+ {
+ return false;
+ }
+
+ Key that = (Key) obj;
+ return artifactId.equals( that.artifactId ) && groupId.equals( that.groupId )
+ && classifier.equals( that.classifier ) && extension.equals( that.extension )
+ && version.equals( that.version ) && context.equals( that.context )
+ && localRepo.equals( that.localRepo ) && CacheUtils.eq( workspace, that.workspace )
+ && CacheUtils.repositoriesEquals( repositories, that.repositories );
+ }
+
+ @Override
+ public int hashCode()
+ {
+ return hashCode;
+ }
+
+ }
+
+ private static class Record
+ {
+ final String version;
+
+ final String repoId;
+
+ final Class<?> repoClass;
+
+ public Record( String version, ArtifactRepository repository )
+ {
+ this.version = version;
+ if ( repository != null )
+ {
+ repoId = repository.getId();
+ repoClass = repository.getClass();
+ }
+ else
+ {
+ repoId = null;
+ repoClass = null;
+ }
+ }
+ }
+
+} \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/LocalSnapshotMetadata.java b/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/LocalSnapshotMetadata.java
new file mode 100644
index 00000000..a22d07d2
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/LocalSnapshotMetadata.java
@@ -0,0 +1,163 @@
+package org.apache.maven.repository.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import org.apache.maven.artifact.repository.metadata.Metadata;
+import org.apache.maven.artifact.repository.metadata.Snapshot;
+import org.apache.maven.artifact.repository.metadata.SnapshotVersion;
+import org.apache.maven.artifact.repository.metadata.Versioning;
+import org.eclipse.aether.artifact.Artifact;
+
+/**
+ * @author Benjamin Bentmann
+ */
+final class LocalSnapshotMetadata
+ extends MavenMetadata
+{
+
+ private final Collection<Artifact> artifacts = new ArrayList<Artifact>();
+
+ private final boolean legacyFormat;
+
+ public LocalSnapshotMetadata( Artifact artifact, boolean legacyFormat )
+ {
+ super( createMetadata( artifact, legacyFormat ), null );
+ this.legacyFormat = legacyFormat;
+ }
+
+ public LocalSnapshotMetadata( Metadata metadata, File file, boolean legacyFormat )
+ {
+ super( metadata, file );
+ this.legacyFormat = legacyFormat;
+ }
+
+ private static Metadata createMetadata( Artifact artifact, boolean legacyFormat )
+ {
+ Snapshot snapshot = new Snapshot();
+ snapshot.setLocalCopy( true );
+ Versioning versioning = new Versioning();
+ versioning.setSnapshot( snapshot );
+
+ Metadata metadata = new Metadata();
+ metadata.setVersioning( versioning );
+ metadata.setGroupId( artifact.getGroupId() );
+ metadata.setArtifactId( artifact.getArtifactId() );
+ metadata.setVersion( artifact.getBaseVersion() );
+
+ if ( !legacyFormat )
+ {
+ metadata.setModelVersion( "1.1.0" );
+ }
+
+ return metadata;
+ }
+
+ public void bind( Artifact artifact )
+ {
+ artifacts.add( artifact );
+ }
+
+ public MavenMetadata setFile( File file )
+ {
+ return new LocalSnapshotMetadata( metadata, file, legacyFormat );
+ }
+
+ public Object getKey()
+ {
+ return getGroupId() + ':' + getArtifactId() + ':' + getVersion();
+ }
+
+ public static Object getKey( Artifact artifact )
+ {
+ return artifact.getGroupId() + ':' + artifact.getArtifactId() + ':' + artifact.getBaseVersion();
+ }
+
+ @Override
+ protected void merge( Metadata recessive )
+ {
+ metadata.getVersioning().updateTimestamp();
+
+ if ( !legacyFormat )
+ {
+ String lastUpdated = metadata.getVersioning().getLastUpdated();
+
+ Map<String, SnapshotVersion> versions = new LinkedHashMap<String, SnapshotVersion>();
+
+ for ( Artifact artifact : artifacts )
+ {
+ SnapshotVersion sv = new SnapshotVersion();
+ sv.setClassifier( artifact.getClassifier() );
+ sv.setExtension( artifact.getExtension() );
+ sv.setVersion( getVersion() );
+ sv.setUpdated( lastUpdated );
+ versions.put( getKey( sv.getClassifier(), sv.getExtension() ), sv );
+ }
+
+ Versioning versioning = recessive.getVersioning();
+ if ( versioning != null )
+ {
+ for ( SnapshotVersion sv : versioning.getSnapshotVersions() )
+ {
+ String key = getKey( sv.getClassifier(), sv.getExtension() );
+ if ( !versions.containsKey( key ) )
+ {
+ versions.put( key, sv );
+ }
+ }
+ }
+
+ metadata.getVersioning().setSnapshotVersions( new ArrayList<SnapshotVersion>( versions.values() ) );
+ }
+
+ artifacts.clear();
+ }
+
+ private String getKey( String classifier, String extension )
+ {
+ return classifier + ':' + extension;
+ }
+
+ public String getGroupId()
+ {
+ return metadata.getGroupId();
+ }
+
+ public String getArtifactId()
+ {
+ return metadata.getArtifactId();
+ }
+
+ public String getVersion()
+ {
+ return metadata.getVersion();
+ }
+
+ public Nature getNature()
+ {
+ return Nature.SNAPSHOT;
+ }
+
+} \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/LocalSnapshotMetadataGenerator.java b/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/LocalSnapshotMetadataGenerator.java
new file mode 100644
index 00000000..ee7c10b0
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/LocalSnapshotMetadataGenerator.java
@@ -0,0 +1,82 @@
+package org.apache.maven.repository.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.artifact.Artifact;
+import org.eclipse.aether.impl.MetadataGenerator;
+import org.eclipse.aether.installation.InstallRequest;
+import org.eclipse.aether.metadata.Metadata;
+import org.eclipse.aether.util.ConfigUtils;
+
+/**
+ * @author Benjamin Bentmann
+ */
+class LocalSnapshotMetadataGenerator
+ implements MetadataGenerator
+{
+
+ private Map<Object, LocalSnapshotMetadata> snapshots;
+
+ private final boolean legacyFormat;
+
+ public LocalSnapshotMetadataGenerator( RepositorySystemSession session, InstallRequest request )
+ {
+ legacyFormat = ConfigUtils.getBoolean( session.getConfigProperties(), false, "maven.metadata.legacy" );
+
+ snapshots = new LinkedHashMap<Object, LocalSnapshotMetadata>();
+ }
+
+ public Collection<? extends Metadata> prepare( Collection<? extends Artifact> artifacts )
+ {
+ for ( Artifact artifact : artifacts )
+ {
+ if ( artifact.isSnapshot() )
+ {
+ Object key = LocalSnapshotMetadata.getKey( artifact );
+ LocalSnapshotMetadata snapshotMetadata = snapshots.get( key );
+ if ( snapshotMetadata == null )
+ {
+ snapshotMetadata = new LocalSnapshotMetadata( artifact, legacyFormat );
+ snapshots.put( key, snapshotMetadata );
+ }
+ snapshotMetadata.bind( artifact );
+ }
+ }
+
+ return Collections.emptyList();
+ }
+
+ public Artifact transformArtifact( Artifact artifact )
+ {
+ return artifact;
+ }
+
+ public Collection<? extends Metadata> finish( Collection<? extends Artifact> artifacts )
+ {
+ return snapshots.values();
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/MavenAetherModule.java b/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/MavenAetherModule.java
new file mode 100644
index 00000000..fa81f611
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/MavenAetherModule.java
@@ -0,0 +1,76 @@
+package org.apache.maven.repository.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import org.apache.maven.model.building.DefaultModelBuilderFactory;
+import org.apache.maven.model.building.ModelBuilder;
+import org.eclipse.aether.impl.AetherModule;
+import org.eclipse.aether.impl.ArtifactDescriptorReader;
+import org.eclipse.aether.impl.MetadataGeneratorFactory;
+import org.eclipse.aether.impl.VersionRangeResolver;
+import org.eclipse.aether.impl.VersionResolver;
+
+import com.google.inject.AbstractModule;
+import com.google.inject.Provides;
+import com.google.inject.name.Names;
+
+public final class MavenAetherModule
+ extends AbstractModule
+{
+
+ @Override
+ protected void configure()
+ {
+ install( new AetherModule() );
+ bind( ArtifactDescriptorReader.class ) //
+ .to( DefaultArtifactDescriptorReader.class ).in( Singleton.class );
+ bind( VersionResolver.class ) //
+ .to( DefaultVersionResolver.class ).in( Singleton.class );
+ bind( VersionRangeResolver.class ) //
+ .to( DefaultVersionRangeResolver.class ).in( Singleton.class );
+ bind( MetadataGeneratorFactory.class ).annotatedWith( Names.named( "snapshot" ) ) //
+ .to( SnapshotMetadataGeneratorFactory.class ).in( Singleton.class );
+ bind( MetadataGeneratorFactory.class ).annotatedWith( Names.named( "versions" ) ) //
+ .to( VersionsMetadataGeneratorFactory.class ).in( Singleton.class );
+ bind( ModelBuilder.class ) //
+ .toInstance( new DefaultModelBuilderFactory().newInstance() );
+ }
+
+ @Provides
+ @Singleton
+ Set<MetadataGeneratorFactory> provideMetadataGeneratorFactories( @Named( "snapshot" )
+ MetadataGeneratorFactory snapshot,
+ @Named( "versions" )
+ MetadataGeneratorFactory versions )
+ {
+ Set<MetadataGeneratorFactory> factories = new HashSet<MetadataGeneratorFactory>();
+ factories.add( snapshot );
+ factories.add( versions );
+ return Collections.unmodifiableSet( factories );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/MavenMetadata.java b/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/MavenMetadata.java
new file mode 100644
index 00000000..bdf28783
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/MavenMetadata.java
@@ -0,0 +1,150 @@
+package org.apache.maven.repository.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.io.Reader;
+import java.io.Writer;
+import java.util.Collections;
+import java.util.Map;
+
+import org.apache.maven.artifact.repository.metadata.Metadata;
+import org.apache.maven.artifact.repository.metadata.io.xpp3.MetadataXpp3Reader;
+import org.apache.maven.artifact.repository.metadata.io.xpp3.MetadataXpp3Writer;
+import org.codehaus.plexus.util.IOUtil;
+import org.codehaus.plexus.util.ReaderFactory;
+import org.codehaus.plexus.util.WriterFactory;
+import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
+import org.eclipse.aether.RepositoryException;
+import org.eclipse.aether.metadata.AbstractMetadata;
+import org.eclipse.aether.metadata.MergeableMetadata;
+
+/**
+ * @author Benjamin Bentmann
+ */
+abstract class MavenMetadata
+ extends AbstractMetadata
+ implements MergeableMetadata
+{
+
+ static final String MAVEN_METADATA_XML = "maven-metadata.xml";
+
+ private final File file;
+
+ protected Metadata metadata;
+
+ private boolean merged;
+
+ protected MavenMetadata( Metadata metadata, File file )
+ {
+ this.metadata = metadata;
+ this.file = file;
+ }
+
+ public String getType()
+ {
+ return MAVEN_METADATA_XML;
+ }
+
+ public File getFile()
+ {
+ return file;
+ }
+
+ public void merge( File existing, File result )
+ throws RepositoryException
+ {
+ Metadata recessive = read( existing );
+
+ merge( recessive );
+
+ write( result, metadata );
+
+ merged = true;
+ }
+
+ public boolean isMerged()
+ {
+ return merged;
+ }
+
+ protected abstract void merge( Metadata recessive );
+
+ static Metadata read( File metadataFile )
+ throws RepositoryException
+ {
+ if ( metadataFile.length() <= 0 )
+ {
+ return new Metadata();
+ }
+
+ Reader reader = null;
+ try
+ {
+ reader = ReaderFactory.newXmlReader( metadataFile );
+ return new MetadataXpp3Reader().read( reader, false );
+ }
+ catch ( IOException e )
+ {
+ throw new RepositoryException( "Could not read metadata " + metadataFile + ": " + e.getMessage(), e );
+ }
+ catch ( XmlPullParserException e )
+ {
+ throw new RepositoryException( "Could not parse metadata " + metadataFile + ": " + e.getMessage(), e );
+ }
+ finally
+ {
+ IOUtil.close( reader );
+ }
+ }
+
+ private void write( File metadataFile, Metadata metadata )
+ throws RepositoryException
+ {
+ Writer writer = null;
+ try
+ {
+ metadataFile.getParentFile().mkdirs();
+ writer = WriterFactory.newXmlWriter( metadataFile );
+ new MetadataXpp3Writer().write( writer, metadata );
+ }
+ catch ( IOException e )
+ {
+ throw new RepositoryException( "Could not write metadata " + metadataFile + ": " + e.getMessage(), e );
+ }
+ finally
+ {
+ IOUtil.close( writer );
+ }
+ }
+
+ public Map<String, String> getProperties()
+ {
+ return Collections.emptyMap();
+ }
+
+ @Override
+ public org.eclipse.aether.metadata.Metadata setProperties( Map<String, String> properties )
+ {
+ return this;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/MavenRepositorySystemUtils.java b/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/MavenRepositorySystemUtils.java
new file mode 100644
index 00000000..5b240efe
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/MavenRepositorySystemUtils.java
@@ -0,0 +1,141 @@
+package org.apache.maven.repository.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Properties;
+
+import org.eclipse.aether.DefaultRepositorySystemSession;
+import org.eclipse.aether.artifact.DefaultArtifactType;
+import org.eclipse.aether.collection.DependencyGraphTransformer;
+import org.eclipse.aether.collection.DependencyManager;
+import org.eclipse.aether.collection.DependencySelector;
+import org.eclipse.aether.collection.DependencyTraverser;
+import org.eclipse.aether.impl.ArtifactDescriptorReader;
+import org.eclipse.aether.impl.DefaultServiceLocator;
+import org.eclipse.aether.impl.MetadataGeneratorFactory;
+import org.eclipse.aether.impl.VersionRangeResolver;
+import org.eclipse.aether.impl.VersionResolver;
+import org.eclipse.aether.util.artifact.DefaultArtifactTypeRegistry;
+import org.eclipse.aether.util.graph.manager.ClassicDependencyManager;
+import org.eclipse.aether.util.graph.selector.AndDependencySelector;
+import org.eclipse.aether.util.graph.selector.ExclusionDependencySelector;
+import org.eclipse.aether.util.graph.selector.OptionalDependencySelector;
+import org.eclipse.aether.util.graph.selector.ScopeDependencySelector;
+import org.eclipse.aether.util.graph.transformer.ChainedDependencyGraphTransformer;
+import org.eclipse.aether.util.graph.transformer.ConflictResolver;
+import org.eclipse.aether.util.graph.transformer.JavaDependencyContextRefiner;
+import org.eclipse.aether.util.graph.transformer.JavaScopeDeriver;
+import org.eclipse.aether.util.graph.transformer.JavaScopeSelector;
+import org.eclipse.aether.util.graph.transformer.NearestVersionSelector;
+import org.eclipse.aether.util.graph.transformer.SimpleOptionalitySelector;
+import org.eclipse.aether.util.graph.traverser.FatArtifactTraverser;
+import org.eclipse.aether.util.repository.SimpleArtifactDescriptorPolicy;
+
+/**
+ * A utility class to assist in setting up a Maven-like repository system. <em>Note:</em> This component is meant to
+ * assist those clients that employ the repository system outside of an IoC container, Maven plugins should instead
+ * always use regular dependency injection to acquire the repository system.
+ *
+ * @author Benjamin Bentmann
+ */
+public final class MavenRepositorySystemUtils
+{
+
+ private MavenRepositorySystemUtils()
+ {
+ // hide constructor
+ }
+
+ /**
+ * Creates a new service locator that already knows about all service implementations included in this library. To
+ * acquire a complete repository system, clients need to add some repository connectors for remote transfers.
+ *
+ * @return The new service locator, never {@code null}.
+ */
+ public static DefaultServiceLocator newServiceLocator()
+ {
+ DefaultServiceLocator locator = new DefaultServiceLocator();
+ locator.addService( ArtifactDescriptorReader.class, DefaultArtifactDescriptorReader.class );
+ locator.addService( VersionResolver.class, DefaultVersionResolver.class );
+ locator.addService( VersionRangeResolver.class, DefaultVersionRangeResolver.class );
+ locator.addService( MetadataGeneratorFactory.class, SnapshotMetadataGeneratorFactory.class );
+ locator.addService( MetadataGeneratorFactory.class, VersionsMetadataGeneratorFactory.class );
+ return locator;
+ }
+
+ /**
+ * Creates a new Maven-like repository system session by initializing the session with values typical for
+ * Maven-based resolution. In more detail, this method configures settings relevant for the processing of dependency
+ * graphs, most other settings remain at their generic default value. Use the various setters to further configure
+ * the session with authentication, mirror, proxy and other information required for your environment.
+ *
+ * @return The new repository system session, never {@code null}.
+ */
+ public static DefaultRepositorySystemSession newSession()
+ {
+ DefaultRepositorySystemSession session = new DefaultRepositorySystemSession();
+
+ DependencyTraverser depTraverser = new FatArtifactTraverser();
+ session.setDependencyTraverser( depTraverser );
+
+ DependencyManager depManager = new ClassicDependencyManager();
+ session.setDependencyManager( depManager );
+
+ DependencySelector depFilter =
+ new AndDependencySelector( new ScopeDependencySelector( "test", "provided" ),
+ new OptionalDependencySelector(), new ExclusionDependencySelector() );
+ session.setDependencySelector( depFilter );
+
+ DependencyGraphTransformer transformer =
+ new ConflictResolver( new NearestVersionSelector(), new JavaScopeSelector(),
+ new SimpleOptionalitySelector(), new JavaScopeDeriver() );
+ new ChainedDependencyGraphTransformer( transformer, new JavaDependencyContextRefiner() );
+ session.setDependencyGraphTransformer( transformer );
+
+ DefaultArtifactTypeRegistry stereotypes = new DefaultArtifactTypeRegistry();
+ stereotypes.add( new DefaultArtifactType( "pom" ) );
+ stereotypes.add( new DefaultArtifactType( "maven-plugin", "jar", "", "java" ) );
+ stereotypes.add( new DefaultArtifactType( "jar", "jar", "", "java" ) );
+ stereotypes.add( new DefaultArtifactType( "ejb", "jar", "", "java" ) );
+ stereotypes.add( new DefaultArtifactType( "ejb-client", "jar", "client", "java" ) );
+ stereotypes.add( new DefaultArtifactType( "test-jar", "jar", "tests", "java" ) );
+ stereotypes.add( new DefaultArtifactType( "javadoc", "jar", "javadoc", "java" ) );
+ stereotypes.add( new DefaultArtifactType( "java-source", "jar", "sources", "java", false, false ) );
+ stereotypes.add( new DefaultArtifactType( "war", "war", "", "java", false, true ) );
+ stereotypes.add( new DefaultArtifactType( "ear", "ear", "", "java", false, true ) );
+ stereotypes.add( new DefaultArtifactType( "rar", "rar", "", "java", false, true ) );
+ stereotypes.add( new DefaultArtifactType( "par", "par", "", "java", false, true ) );
+ session.setArtifactTypeRegistry( stereotypes );
+
+ session.setArtifactDescriptorPolicy( new SimpleArtifactDescriptorPolicy( true, true ) );
+
+ // MNG-5670 guard against ConcurrentModificationException
+ Properties sysProps = new Properties();
+ for ( String key : System.getProperties().stringPropertyNames() )
+ {
+ sysProps.put( key, System.getProperty( key ) );
+ }
+ session.setSystemProperties( sysProps );
+ session.setConfigProperties( sysProps );
+
+ return session;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/MavenSnapshotMetadata.java b/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/MavenSnapshotMetadata.java
new file mode 100644
index 00000000..1e6f9097
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/MavenSnapshotMetadata.java
@@ -0,0 +1,100 @@
+package org.apache.maven.repository.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collection;
+
+import org.apache.maven.artifact.repository.metadata.Metadata;
+import org.eclipse.aether.artifact.Artifact;
+
+/**
+ * @author Hervé Boutemy
+ */
+abstract class MavenSnapshotMetadata
+ extends MavenMetadata
+{
+ static final String SNAPSHOT = "SNAPSHOT";
+
+ protected final Collection<Artifact> artifacts = new ArrayList<Artifact>();
+
+ protected final boolean legacyFormat;
+
+ protected MavenSnapshotMetadata( Metadata metadata, File file, boolean legacyFormat )
+ {
+ super( metadata, file );
+ this.legacyFormat = legacyFormat;
+ }
+
+ protected static Metadata createRepositoryMetadata( Artifact artifact, boolean legacyFormat )
+ {
+ Metadata metadata = new Metadata();
+ if ( !legacyFormat )
+ {
+ metadata.setModelVersion( "1.1.0" );
+ }
+ metadata.setGroupId( artifact.getGroupId() );
+ metadata.setArtifactId( artifact.getArtifactId() );
+ metadata.setVersion( artifact.getBaseVersion() );
+
+ return metadata;
+ }
+
+ public void bind( Artifact artifact )
+ {
+ artifacts.add( artifact );
+ }
+
+ public Object getKey()
+ {
+ return getGroupId() + ':' + getArtifactId() + ':' + getVersion();
+ }
+
+ public static Object getKey( Artifact artifact )
+ {
+ return artifact.getGroupId() + ':' + artifact.getArtifactId() + ':' + artifact.getBaseVersion();
+ }
+
+ protected String getKey( String classifier, String extension )
+ {
+ return classifier + ':' + extension;
+ }
+
+ public String getGroupId()
+ {
+ return metadata.getGroupId();
+ }
+
+ public String getArtifactId()
+ {
+ return metadata.getArtifactId();
+ }
+
+ public String getVersion()
+ {
+ return metadata.getVersion();
+ }
+
+ public Nature getNature()
+ {
+ return Nature.SNAPSHOT;
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/MavenWorkspaceReader.java b/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/MavenWorkspaceReader.java
new file mode 100644
index 00000000..270cf588
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/MavenWorkspaceReader.java
@@ -0,0 +1,32 @@
+package org.apache.maven.repository.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.model.Model;
+import org.eclipse.aether.artifact.Artifact;
+import org.eclipse.aether.repository.WorkspaceReader;
+
+public interface MavenWorkspaceReader
+ extends WorkspaceReader
+{
+
+ Model findModel( Artifact artifact );
+
+} \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/RelocatedArtifact.java b/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/RelocatedArtifact.java
new file mode 100644
index 00000000..958eb388
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/RelocatedArtifact.java
@@ -0,0 +1,116 @@
+package org.apache.maven.repository.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.util.Map;
+
+import org.eclipse.aether.artifact.AbstractArtifact;
+import org.eclipse.aether.artifact.Artifact;
+
+/**
+ * @author Benjamin Bentmann
+ */
+final class RelocatedArtifact
+ extends AbstractArtifact
+{
+
+ private final Artifact artifact;
+
+ private final String groupId;
+
+ private final String artifactId;
+
+ private final String version;
+
+ public RelocatedArtifact( Artifact artifact, String groupId, String artifactId, String version )
+ {
+ if ( artifact == null )
+ {
+ throw new IllegalArgumentException( "no artifact specified" );
+ }
+ this.artifact = artifact;
+ this.groupId = ( groupId != null && groupId.length() > 0 ) ? groupId : null;
+ this.artifactId = ( artifactId != null && artifactId.length() > 0 ) ? artifactId : null;
+ this.version = ( version != null && version.length() > 0 ) ? version : null;
+ }
+
+ public String getGroupId()
+ {
+ if ( groupId != null )
+ {
+ return groupId;
+ }
+ else
+ {
+ return artifact.getGroupId();
+ }
+ }
+
+ public String getArtifactId()
+ {
+ if ( artifactId != null )
+ {
+ return artifactId;
+ }
+ else
+ {
+ return artifact.getArtifactId();
+ }
+ }
+
+ public String getVersion()
+ {
+ if ( version != null )
+ {
+ return version;
+ }
+ else
+ {
+ return artifact.getVersion();
+ }
+ }
+
+ public String getClassifier()
+ {
+ return artifact.getClassifier();
+ }
+
+ public String getExtension()
+ {
+ return artifact.getExtension();
+ }
+
+ public File getFile()
+ {
+ return artifact.getFile();
+ }
+
+ public String getProperty( String key, String defaultValue )
+ {
+ return artifact.getProperty( key, defaultValue );
+ }
+
+ public Map<String, String> getProperties()
+ {
+ return artifact.getProperties();
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/RemoteSnapshotMetadata.java b/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/RemoteSnapshotMetadata.java
new file mode 100644
index 00000000..4494cae6
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/RemoteSnapshotMetadata.java
@@ -0,0 +1,152 @@
+package org.apache.maven.repository.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.TimeZone;
+
+import org.apache.maven.artifact.repository.metadata.Metadata;
+import org.apache.maven.artifact.repository.metadata.Snapshot;
+import org.apache.maven.artifact.repository.metadata.SnapshotVersion;
+import org.apache.maven.artifact.repository.metadata.Versioning;
+import org.eclipse.aether.artifact.Artifact;
+
+/**
+ * @author Benjamin Bentmann
+ */
+final class RemoteSnapshotMetadata
+ extends MavenSnapshotMetadata
+{
+
+ private final Map<String, SnapshotVersion> versions = new LinkedHashMap<String, SnapshotVersion>();
+
+ public RemoteSnapshotMetadata( Artifact artifact, boolean legacyFormat )
+ {
+ super( createRepositoryMetadata( artifact, legacyFormat ), null, legacyFormat );
+ }
+
+ private RemoteSnapshotMetadata( Metadata metadata, File file, boolean legacyFormat )
+ {
+ super( metadata, file, legacyFormat );
+ }
+
+ public MavenMetadata setFile( File file )
+ {
+ return new RemoteSnapshotMetadata( metadata, file, legacyFormat );
+ }
+
+ public String getExpandedVersion( Artifact artifact )
+ {
+ String key = getKey( artifact.getClassifier(), artifact.getExtension() );
+ return versions.get( key ).getVersion();
+ }
+
+ @Override
+ protected void merge( Metadata recessive )
+ {
+ Snapshot snapshot;
+ String lastUpdated;
+
+ if ( metadata.getVersioning() == null )
+ {
+ DateFormat utcDateFormatter = new SimpleDateFormat( "yyyyMMdd.HHmmss" );
+ utcDateFormatter.setTimeZone( TimeZone.getTimeZone( "UTC" ) );
+
+ snapshot = new Snapshot();
+ snapshot.setBuildNumber( getBuildNumber( recessive ) + 1 );
+ snapshot.setTimestamp( utcDateFormatter.format( new Date() ) );
+
+ Versioning versioning = new Versioning();
+ versioning.setSnapshot( snapshot );
+ versioning.setLastUpdated( snapshot.getTimestamp().replace( ".", "" ) );
+ lastUpdated = versioning.getLastUpdated();
+
+ metadata.setVersioning( versioning );
+ }
+ else
+ {
+ snapshot = metadata.getVersioning().getSnapshot();
+ lastUpdated = metadata.getVersioning().getLastUpdated();
+ }
+
+ for ( Artifact artifact : artifacts )
+ {
+ String version = artifact.getVersion();
+
+ if ( version.endsWith( SNAPSHOT ) )
+ {
+ String qualifier = snapshot.getTimestamp() + '-' + snapshot.getBuildNumber();
+ version = version.substring( 0, version.length() - SNAPSHOT.length() ) + qualifier;
+ }
+
+ SnapshotVersion sv = new SnapshotVersion();
+ sv.setClassifier( artifact.getClassifier() );
+ sv.setExtension( artifact.getExtension() );
+ sv.setVersion( version );
+ sv.setUpdated( lastUpdated );
+
+ versions.put( getKey( sv.getClassifier(), sv.getExtension() ), sv );
+ }
+
+ artifacts.clear();
+
+ Versioning versioning = recessive.getVersioning();
+ if ( versioning != null )
+ {
+ for ( SnapshotVersion sv : versioning.getSnapshotVersions() )
+ {
+ String key = getKey( sv.getClassifier(), sv.getExtension() );
+ if ( !versions.containsKey( key ) )
+ {
+ versions.put( key, sv );
+ }
+ }
+ }
+
+ if ( !legacyFormat )
+ {
+ metadata.getVersioning().setSnapshotVersions( new ArrayList<SnapshotVersion>( versions.values() ) );
+ }
+ }
+
+ private static int getBuildNumber( Metadata metadata )
+ {
+ int number = 0;
+
+ Versioning versioning = metadata.getVersioning();
+ if ( versioning != null )
+ {
+ Snapshot snapshot = versioning.getSnapshot();
+ if ( snapshot != null && snapshot.getBuildNumber() > 0 )
+ {
+ number = snapshot.getBuildNumber();
+ }
+ }
+
+ return number;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/RemoteSnapshotMetadataGenerator.java b/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/RemoteSnapshotMetadataGenerator.java
new file mode 100644
index 00000000..6cbeec55
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/RemoteSnapshotMetadataGenerator.java
@@ -0,0 +1,107 @@
+package org.apache.maven.repository.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.artifact.Artifact;
+import org.eclipse.aether.deployment.DeployRequest;
+import org.eclipse.aether.impl.MetadataGenerator;
+import org.eclipse.aether.metadata.Metadata;
+import org.eclipse.aether.util.ConfigUtils;
+
+/**
+ * @author Benjamin Bentmann
+ */
+class RemoteSnapshotMetadataGenerator
+ implements MetadataGenerator
+{
+
+ private final Map<Object, RemoteSnapshotMetadata> snapshots;
+
+ private final boolean legacyFormat;
+
+ public RemoteSnapshotMetadataGenerator( RepositorySystemSession session, DeployRequest request )
+ {
+ legacyFormat = ConfigUtils.getBoolean( session.getConfigProperties(), false, "maven.metadata.legacy" );
+
+ snapshots = new LinkedHashMap<Object, RemoteSnapshotMetadata>();
+
+ /*
+ * NOTE: This should be considered a quirk to support interop with Maven's legacy ArtifactDeployer which
+ * processes one artifact at a time and hence cannot associate the artifacts from the same project to use the
+ * same timestamp+buildno for the snapshot versions. Allowing the caller to pass in metadata from a previous
+ * deployment allows to re-establish the association between the artifacts of the same project.
+ */
+ for ( Metadata metadata : request.getMetadata() )
+ {
+ if ( metadata instanceof RemoteSnapshotMetadata )
+ {
+ RemoteSnapshotMetadata snapshotMetadata = (RemoteSnapshotMetadata) metadata;
+ snapshots.put( snapshotMetadata.getKey(), snapshotMetadata );
+ }
+ }
+ }
+
+ public Collection<? extends Metadata> prepare( Collection<? extends Artifact> artifacts )
+ {
+ for ( Artifact artifact : artifacts )
+ {
+ if ( artifact.isSnapshot() )
+ {
+ Object key = RemoteSnapshotMetadata.getKey( artifact );
+ RemoteSnapshotMetadata snapshotMetadata = snapshots.get( key );
+ if ( snapshotMetadata == null )
+ {
+ snapshotMetadata = new RemoteSnapshotMetadata( artifact, legacyFormat );
+ snapshots.put( key, snapshotMetadata );
+ }
+ snapshotMetadata.bind( artifact );
+ }
+ }
+
+ return snapshots.values();
+ }
+
+ public Artifact transformArtifact( Artifact artifact )
+ {
+ if ( artifact.isSnapshot() && artifact.getVersion().equals( artifact.getBaseVersion() ) )
+ {
+ Object key = RemoteSnapshotMetadata.getKey( artifact );
+ RemoteSnapshotMetadata snapshotMetadata = snapshots.get( key );
+ if ( snapshotMetadata != null )
+ {
+ artifact = artifact.setVersion( snapshotMetadata.getExpandedVersion( artifact ) );
+ }
+ }
+
+ return artifact;
+ }
+
+ public Collection<? extends Metadata> finish( Collection<? extends Artifact> artifacts )
+ {
+ return Collections.emptyList();
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/SnapshotMetadataGeneratorFactory.java b/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/SnapshotMetadataGeneratorFactory.java
new file mode 100644
index 00000000..79ffaade
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/SnapshotMetadataGeneratorFactory.java
@@ -0,0 +1,52 @@
+package org.apache.maven.repository.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.codehaus.plexus.component.annotations.Component;
+import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.deployment.DeployRequest;
+import org.eclipse.aether.impl.MetadataGenerator;
+import org.eclipse.aether.impl.MetadataGeneratorFactory;
+import org.eclipse.aether.installation.InstallRequest;
+
+/**
+ * @author Benjamin Bentmann
+ */
+@Component( role = MetadataGeneratorFactory.class, hint = "snapshot" )
+public class SnapshotMetadataGeneratorFactory
+ implements MetadataGeneratorFactory
+{
+
+ public MetadataGenerator newInstance( RepositorySystemSession session, InstallRequest request )
+ {
+ return new LocalSnapshotMetadataGenerator( session, request );
+ }
+
+ public MetadataGenerator newInstance( RepositorySystemSession session, DeployRequest request )
+ {
+ return new RemoteSnapshotMetadataGenerator( session, request );
+ }
+
+ public float getPriority()
+ {
+ return 10;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/VersionsMetadata.java b/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/VersionsMetadata.java
new file mode 100644
index 00000000..adaca9db
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/VersionsMetadata.java
@@ -0,0 +1,133 @@
+package org.apache.maven.repository.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.LinkedHashSet;
+
+import org.apache.maven.artifact.repository.metadata.Metadata;
+import org.apache.maven.artifact.repository.metadata.Versioning;
+import org.eclipse.aether.artifact.Artifact;
+import org.eclipse.aether.artifact.ArtifactProperties;
+
+/**
+ * @author Benjamin Bentmann
+ */
+final class VersionsMetadata
+ extends MavenMetadata
+{
+
+ private final Artifact artifact;
+
+ public VersionsMetadata( Artifact artifact )
+ {
+ super( createRepositoryMetadata( artifact ), null );
+ this.artifact = artifact;
+ }
+
+ public VersionsMetadata( Artifact artifact, File file )
+ {
+ super( createRepositoryMetadata( artifact ), file );
+ this.artifact = artifact;
+ }
+
+ private static Metadata createRepositoryMetadata( Artifact artifact )
+ {
+ Metadata metadata = new Metadata();
+ metadata.setGroupId( artifact.getGroupId() );
+ metadata.setArtifactId( artifact.getArtifactId() );
+
+ Versioning versioning = new Versioning();
+ versioning.addVersion( artifact.getBaseVersion() );
+ if ( !artifact.isSnapshot() )
+ {
+ versioning.setRelease( artifact.getBaseVersion() );
+ }
+ if ( "maven-plugin".equals( artifact.getProperty( ArtifactProperties.TYPE, "" ) ) )
+ {
+ versioning.setLatest( artifact.getBaseVersion() );
+ }
+
+ metadata.setVersioning( versioning );
+
+ return metadata;
+ }
+
+ @Override
+ protected void merge( Metadata recessive )
+ {
+ Versioning versioning = metadata.getVersioning();
+ versioning.updateTimestamp();
+
+ if ( recessive.getVersioning() != null )
+ {
+ if ( versioning.getLatest() == null )
+ {
+ versioning.setLatest( recessive.getVersioning().getLatest() );
+ }
+ if ( versioning.getRelease() == null )
+ {
+ versioning.setRelease( recessive.getVersioning().getRelease() );
+ }
+
+ Collection<String> versions = new LinkedHashSet<String>( recessive.getVersioning().getVersions() );
+ versions.addAll( versioning.getVersions() );
+ versioning.setVersions( new ArrayList<String>( versions ) );
+ }
+ }
+
+ public Object getKey()
+ {
+ return getGroupId() + ':' + getArtifactId();
+ }
+
+ public static Object getKey( Artifact artifact )
+ {
+ return artifact.getGroupId() + ':' + artifact.getArtifactId();
+ }
+
+ public MavenMetadata setFile( File file )
+ {
+ return new VersionsMetadata( artifact, file );
+ }
+
+ public String getGroupId()
+ {
+ return artifact.getGroupId();
+ }
+
+ public String getArtifactId()
+ {
+ return artifact.getArtifactId();
+ }
+
+ public String getVersion()
+ {
+ return "";
+ }
+
+ public Nature getNature()
+ {
+ return artifact.isSnapshot() ? Nature.RELEASE_OR_SNAPSHOT : Nature.RELEASE;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/VersionsMetadataGenerator.java b/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/VersionsMetadataGenerator.java
new file mode 100644
index 00000000..e2f5e82d
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/VersionsMetadataGenerator.java
@@ -0,0 +1,108 @@
+package org.apache.maven.repository.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.artifact.Artifact;
+import org.eclipse.aether.deployment.DeployRequest;
+import org.eclipse.aether.impl.MetadataGenerator;
+import org.eclipse.aether.installation.InstallRequest;
+import org.eclipse.aether.metadata.Metadata;
+
+/**
+ * @author Benjamin Bentmann
+ */
+class VersionsMetadataGenerator
+ implements MetadataGenerator
+{
+
+ private Map<Object, VersionsMetadata> versions;
+
+ private Map<Object, VersionsMetadata> processedVersions;
+
+ public VersionsMetadataGenerator( RepositorySystemSession session, InstallRequest request )
+ {
+ this( session, request.getMetadata() );
+ }
+
+ public VersionsMetadataGenerator( RepositorySystemSession session, DeployRequest request )
+ {
+ this( session, request.getMetadata() );
+ }
+
+ private VersionsMetadataGenerator( RepositorySystemSession session, Collection<? extends Metadata> metadatas )
+ {
+ versions = new LinkedHashMap<Object, VersionsMetadata>();
+ processedVersions = new LinkedHashMap<Object, VersionsMetadata>();
+
+ /*
+ * NOTE: This should be considered a quirk to support interop with Maven's legacy ArtifactDeployer which
+ * processes one artifact at a time and hence cannot associate the artifacts from the same project to use the
+ * same version index. Allowing the caller to pass in metadata from a previous deployment allows to re-establish
+ * the association between the artifacts of the same project.
+ */
+ for ( Iterator<? extends Metadata> it = metadatas.iterator(); it.hasNext(); )
+ {
+ Metadata metadata = it.next();
+ if ( metadata instanceof VersionsMetadata )
+ {
+ it.remove();
+ VersionsMetadata versionsMetadata = (VersionsMetadata) metadata;
+ processedVersions.put( versionsMetadata.getKey(), versionsMetadata );
+ }
+ }
+ }
+
+ public Collection<? extends Metadata> prepare( Collection<? extends Artifact> artifacts )
+ {
+ return Collections.emptyList();
+ }
+
+ public Artifact transformArtifact( Artifact artifact )
+ {
+ return artifact;
+ }
+
+ public Collection<? extends Metadata> finish( Collection<? extends Artifact> artifacts )
+ {
+ for ( Artifact artifact : artifacts )
+ {
+ Object key = VersionsMetadata.getKey( artifact );
+ if ( processedVersions.get( key ) == null )
+ {
+ VersionsMetadata versionsMetadata = versions.get( key );
+ if ( versionsMetadata == null )
+ {
+ versionsMetadata = new VersionsMetadata( artifact );
+ versions.put( key, versionsMetadata );
+ }
+ }
+ }
+
+ return versions.values();
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/VersionsMetadataGeneratorFactory.java b/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/VersionsMetadataGeneratorFactory.java
new file mode 100644
index 00000000..47ef3601
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/VersionsMetadataGeneratorFactory.java
@@ -0,0 +1,52 @@
+package org.apache.maven.repository.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.codehaus.plexus.component.annotations.Component;
+import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.deployment.DeployRequest;
+import org.eclipse.aether.impl.MetadataGenerator;
+import org.eclipse.aether.impl.MetadataGeneratorFactory;
+import org.eclipse.aether.installation.InstallRequest;
+
+/**
+ * @author Benjamin Bentmann
+ */
+@Component( role = MetadataGeneratorFactory.class, hint = "versions" )
+public class VersionsMetadataGeneratorFactory
+ implements MetadataGeneratorFactory
+{
+
+ public MetadataGenerator newInstance( RepositorySystemSession session, InstallRequest request )
+ {
+ return new VersionsMetadataGenerator( session, request );
+ }
+
+ public MetadataGenerator newInstance( RepositorySystemSession session, DeployRequest request )
+ {
+ return new VersionsMetadataGenerator( session, request );
+ }
+
+ public float getPriority()
+ {
+ return 5;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/package-info.java b/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/package-info.java
new file mode 100644
index 00000000..5582cf75
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/package-info.java
@@ -0,0 +1,25 @@
+// CHECKSTYLE_OFF: RegexpHeader
+/**
+ * <a href="http://www.eclipse.org/aether/">Aether</a> extensions for utilizing the Maven POM and Maven repository
+ * metadata.
+ */
+package org.apache.maven.repository.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */ \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/site/apt/index.apt b/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/site/apt/index.apt
new file mode 100644
index 00000000..600ec417
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/site/apt/index.apt
@@ -0,0 +1,33 @@
+~~ Licensed to the Apache Software Foundation (ASF) under one
+~~ or more contributor license agreements. See the NOTICE file
+~~ distributed with this work for additional information
+~~ regarding copyright ownership. The ASF licenses this file
+~~ to you under the Apache License, Version 2.0 (the
+~~ "License"); you may not use this file except in compliance
+~~ with the License. You may obtain a copy of the License at
+~~
+~~ http://www.apache.org/licenses/LICENSE-2.0
+~~
+~~ Unless required by applicable law or agreed to in writing,
+~~ software distributed under the License is distributed on an
+~~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+~~ KIND, either express or implied. See the License for the
+~~ specific language governing permissions and limitations
+~~ under the License.
+
+ -----
+ Introduction
+ -----
+ Hervé Boutemy
+ -----
+ 2012-09-29
+ -----
+
+Maven Aether Provider
+
+ Maven Aether Provider is an {{{http://www.eclipse.org/aether/}Aether}} extension to support
+ Maven POMs and local+remote repositories.
+
+ Main component is <<<MavenRepositorySystemUtils>>>
+ ({{{./apidocs/org/apache/maven/repository/internal/MavenRepositorySystemUtils.html}javadoc}},
+ {{{./xref/org/apache/maven/repository/internal/MavenRepositorySystemUtils.html}source}}).
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/site/site.xml b/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/site/site.xml
new file mode 100644
index 00000000..3a16bf98
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/site/site.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project xmlns="http://maven.apache.org/DECORATION/1.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/DECORATION/1.0.0 http://maven.apache.org/xsd/decoration-1.0.0.xsd">
+ <body>
+ <menu name="Overview">
+ <item name="Introduction" href="index.html"/>
+ <item name="JavaDocs" href="apidocs/index.html"/>
+ <item name="Source Xref" href="xref/index.html"/>
+ <!--item name="FAQ" href="faq.html"/-->
+ </menu>
+
+ <menu ref="parent"/>
+ <menu ref="reports"/>
+ </body>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/test/java/org/apache/maven/repository/internal/AbstractRepositoryTestCase.java b/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/test/java/org/apache/maven/repository/internal/AbstractRepositoryTestCase.java
new file mode 100644
index 00000000..b81450ce
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/test/java/org/apache/maven/repository/internal/AbstractRepositoryTestCase.java
@@ -0,0 +1,87 @@
+package org.apache.maven.repository.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.net.MalformedURLException;
+
+import org.apache.maven.repository.internal.util.ConsoleRepositoryListener;
+import org.apache.maven.repository.internal.util.ConsoleTransferListener;
+import org.codehaus.plexus.ContainerConfiguration;
+import org.codehaus.plexus.PlexusConstants;
+import org.codehaus.plexus.PlexusTestCase;
+import org.eclipse.aether.DefaultRepositorySystemSession;
+import org.eclipse.aether.RepositorySystem;
+import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.repository.LocalRepository;
+import org.eclipse.aether.repository.RemoteRepository;
+
+public abstract class AbstractRepositoryTestCase
+ extends PlexusTestCase
+{
+ protected RepositorySystem system;
+
+ protected RepositorySystemSession session;
+
+ @Override
+ protected void customizeContainerConfiguration( ContainerConfiguration containerConfiguration )
+ {
+ super.customizeContainerConfiguration( containerConfiguration );
+ containerConfiguration.setAutoWiring( true );
+ containerConfiguration.setClassPathScanning( PlexusConstants.SCANNING_INDEX );
+ }
+
+ @Override
+ protected void setUp()
+ throws Exception
+ {
+ super.setUp();
+ system = lookup( RepositorySystem.class );
+ session = newMavenRepositorySystemSession( system );
+ }
+
+ @Override
+ protected void tearDown()
+ throws Exception
+ {
+ session = null;
+ system = null;
+ super.tearDown();
+ }
+
+ public static RepositorySystemSession newMavenRepositorySystemSession( RepositorySystem system )
+ {
+ DefaultRepositorySystemSession session = MavenRepositorySystemUtils.newSession();
+
+ LocalRepository localRepo = new LocalRepository( "target/local-repo" );
+ session.setLocalRepositoryManager( system.newLocalRepositoryManager( session, localRepo ) );
+
+ session.setTransferListener( new ConsoleTransferListener() );
+ session.setRepositoryListener( new ConsoleRepositoryListener() );
+
+ return session;
+ }
+
+ public static RemoteRepository newTestRepository()
+ throws MalformedURLException
+ {
+ return new RemoteRepository.Builder( "repo", "default",
+ getTestFile( "target/test-classes/repo" ).toURI().toURL().toString() ).build();
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/test/java/org/apache/maven/repository/internal/DefaultArtifactDescriptorReaderTest.java b/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/test/java/org/apache/maven/repository/internal/DefaultArtifactDescriptorReaderTest.java
new file mode 100644
index 00000000..e8731380
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/test/java/org/apache/maven/repository/internal/DefaultArtifactDescriptorReaderTest.java
@@ -0,0 +1,77 @@
+package org.apache.maven.repository.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+import org.eclipse.aether.RepositoryEvent;
+import org.eclipse.aether.RepositoryEvent.EventType;
+import org.eclipse.aether.artifact.DefaultArtifact;
+import org.eclipse.aether.impl.ArtifactDescriptorReader;
+import org.eclipse.aether.impl.RepositoryEventDispatcher;
+import org.eclipse.aether.resolution.ArtifactDescriptorRequest;
+import org.mockito.ArgumentCaptor;
+
+public class DefaultArtifactDescriptorReaderTest
+ extends AbstractRepositoryTestCase
+{
+
+ public void testMng5459()
+ throws Exception
+ {
+ // prepare
+ DefaultArtifactDescriptorReader reader = (DefaultArtifactDescriptorReader) lookup( ArtifactDescriptorReader.class );
+
+ RepositoryEventDispatcher eventDispatcher = mock( RepositoryEventDispatcher.class );
+
+ ArgumentCaptor<RepositoryEvent> event = ArgumentCaptor.forClass( RepositoryEvent.class );
+
+ reader.setRepositoryEventDispatcher( eventDispatcher );
+
+ ArtifactDescriptorRequest request = new ArtifactDescriptorRequest();
+
+ request.addRepository( newTestRepository() );
+
+ request.setArtifact( new DefaultArtifact( "org.apache.maven.its", "dep-mng5459", "jar", "0.4.0-SNAPSHOT" ) );
+
+ // execute
+ reader.readArtifactDescriptor( session, request );
+
+ // verify
+ verify( eventDispatcher ).dispatch( event.capture() );
+
+ boolean missingArtifactDescriptor = false;
+
+ for( RepositoryEvent evt : event.getAllValues() )
+ {
+ if ( EventType.ARTIFACT_DESCRIPTOR_MISSING.equals( evt.getType() ) )
+ {
+ assertEquals( "Could not find artifact org.apache.maven.its:dep-mng5459:pom:0.4.0-20130404.090532-2 in repo (" + newTestRepository().getUrl() + ")", evt.getException().getMessage() );
+ missingArtifactDescriptor = true;
+ }
+ }
+
+ if( !missingArtifactDescriptor )
+ {
+ fail( "Expected missing artifact descriptor for org.apache.maven.its:dep-mng5459:pom:0.4.0-20130404.090532-2" );
+ }
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/test/java/org/apache/maven/repository/internal/DefaultVersionResolverTest.java b/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/test/java/org/apache/maven/repository/internal/DefaultVersionResolverTest.java
new file mode 100644
index 00000000..90dd6a4c
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/test/java/org/apache/maven/repository/internal/DefaultVersionResolverTest.java
@@ -0,0 +1,96 @@
+package org.apache.maven.repository.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.eclipse.aether.artifact.Artifact;
+import org.eclipse.aether.impl.VersionResolver;
+import org.eclipse.aether.resolution.VersionRequest;
+import org.eclipse.aether.resolution.VersionResult;
+import org.eclipse.aether.artifact.DefaultArtifact;
+
+public class DefaultVersionResolverTest
+ extends AbstractRepositoryTestCase
+{
+ private DefaultVersionResolver versionResolver;
+
+ @Override
+ protected void setUp()
+ throws Exception
+ {
+ super.setUp();
+ // be sure we're testing the right class, i.e. DefaultVersionResolver.class
+ versionResolver = (DefaultVersionResolver) lookup( VersionResolver.class, "default" );
+ }
+
+ @Override
+ protected void tearDown()
+ throws Exception
+ {
+ versionResolver = null;
+ super.tearDown();
+ }
+
+ public void testResolveSeparateInstalledClassifiedNonUniqueVersionedArtifacts()
+ throws Exception
+ {
+ VersionRequest requestB = new VersionRequest();
+ requestB.addRepository( newTestRepository() );
+ Artifact artifactB =
+ new DefaultArtifact( "org.apache.maven.its", "dep-mng5324", "classifierB", "jar", "07.20.3-SNAPSHOT" );
+ requestB.setArtifact( artifactB );
+
+ VersionResult resultB = versionResolver.resolveVersion( session, requestB );
+ assertEquals( "07.20.3-20120809.112920-97", resultB.getVersion() );
+
+ VersionRequest requestA = new VersionRequest();
+ requestA.addRepository( newTestRepository() );
+
+ Artifact artifactA =
+ new DefaultArtifact( "org.apache.maven.its", "dep-mng5324", "classifierA", "jar", "07.20.3-SNAPSHOT" );
+ requestA.setArtifact( artifactA );
+
+ VersionResult resultA = versionResolver.resolveVersion( session, requestA );
+ assertEquals( "07.20.3-20120809.112124-88", resultA.getVersion() );
+ }
+
+ public void testResolveSeparateInstalledClassifiedNonVersionedArtifacts()
+ throws Exception
+ {
+ VersionRequest requestA = new VersionRequest();
+ requestA.addRepository( newTestRepository() );
+ String versionA = "07.20.3-20120809.112124-88";
+ Artifact artifactA =
+ new DefaultArtifact( "org.apache.maven.its", "dep-mng5324", "classifierA", "jar", versionA );
+ requestA.setArtifact( artifactA );
+
+ VersionResult resultA = versionResolver.resolveVersion( session, requestA );
+ assertEquals( versionA, resultA.getVersion() );
+
+ VersionRequest requestB = new VersionRequest();
+ requestB.addRepository( newTestRepository() );
+ String versionB = "07.20.3-20120809.112920-97";
+ Artifact artifactB =
+ new DefaultArtifact( "org.apache.maven.its", "dep-mng5324", "classifierB", "jar", versionB );
+ requestB.setArtifact( artifactB );
+
+ VersionResult resultB = versionResolver.resolveVersion( session, requestB );
+ assertEquals( versionB, resultB.getVersion() );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/test/java/org/apache/maven/repository/internal/MavenRepositorySystemUtilsTest.java b/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/test/java/org/apache/maven/repository/internal/MavenRepositorySystemUtilsTest.java
new file mode 100644
index 00000000..768835a5
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/test/java/org/apache/maven/repository/internal/MavenRepositorySystemUtilsTest.java
@@ -0,0 +1,45 @@
+package org.apache.maven.repository.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.eclipse.aether.RepositorySystem;
+import org.eclipse.aether.impl.MetadataGeneratorFactory;
+import org.eclipse.aether.spi.locator.ServiceLocator;
+
+import junit.framework.TestCase;
+
+public class MavenRepositorySystemUtilsTest
+ extends TestCase
+{
+
+ public void testGetRepositorySystem()
+ {
+ ServiceLocator locator = MavenRepositorySystemUtils.newServiceLocator();
+ RepositorySystem repoSys = locator.getService( RepositorySystem.class );
+ assertNotNull( repoSys );
+ }
+
+ public void testGetMetadataGeneratorFactories()
+ {
+ ServiceLocator locator = MavenRepositorySystemUtils.newServiceLocator();
+ assertEquals( 2, locator.getServices( MetadataGeneratorFactory.class ).size() );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/test/java/org/apache/maven/repository/internal/RepositorySystemTest.java b/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/test/java/org/apache/maven/repository/internal/RepositorySystemTest.java
new file mode 100644
index 00000000..db77a441
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/test/java/org/apache/maven/repository/internal/RepositorySystemTest.java
@@ -0,0 +1,220 @@
+package org.apache.maven.repository.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.eclipse.aether.artifact.Artifact;
+import org.eclipse.aether.collection.CollectRequest;
+import org.eclipse.aether.collection.CollectResult;
+import org.eclipse.aether.graph.Dependency;
+import org.eclipse.aether.graph.DependencyNode;
+import org.eclipse.aether.resolution.ArtifactDescriptorRequest;
+import org.eclipse.aether.resolution.ArtifactDescriptorResult;
+import org.eclipse.aether.resolution.ArtifactRequest;
+import org.eclipse.aether.resolution.ArtifactResult;
+import org.eclipse.aether.artifact.DefaultArtifact;
+
+public class RepositorySystemTest
+ extends AbstractRepositoryTestCase
+{
+ public void testResolveVersionRange()
+ throws Exception
+ {
+ //VersionRangeResult resolveVersionRange( RepositorySystemSession session, VersionRangeRequest request )
+ // throws VersionRangeResolutionException;
+
+ }
+
+ public void testResolveVersion()
+ throws Exception
+ {
+ //VersionResult resolveVersion( RepositorySystemSession session, VersionRequest request )
+ // throws VersionResolutionException;
+ }
+
+ public void testReadArtifactDescriptor()
+ throws Exception
+ {
+ Artifact artifact = new DefaultArtifact( "ut.simple:artifact:extension:classifier:1.0" );
+
+ ArtifactDescriptorRequest request = new ArtifactDescriptorRequest();
+ request.setArtifact( artifact );
+ request.addRepository( newTestRepository() );
+
+ ArtifactDescriptorResult result = system.readArtifactDescriptor( session, request );
+
+ List<Dependency> deps = result.getDependencies();
+ assertEquals( 2, deps.size() );
+ checkUtSimpleArtifactDependencies( deps.get( 0 ), deps.get( 1 ) );
+ }
+
+ /**
+ * check ut.simple:artifact:1.0 dependencies
+ */
+ private void checkUtSimpleArtifactDependencies( Dependency dep1, Dependency dep2 )
+ {
+ assertEquals( "compile", dep1.getScope() );
+ assertFalse( dep1.isOptional() );
+ assertEquals( 0, dep1.getExclusions().size() );
+ Artifact depArtifact = dep1.getArtifact();
+ assertEquals( "ut.simple", depArtifact.getGroupId() );
+ assertEquals( "dependency", depArtifact.getArtifactId() );
+ assertEquals( "1.0", depArtifact.getVersion() );
+ assertEquals( "1.0", depArtifact.getBaseVersion() );
+ assertNull( depArtifact.getFile() );
+ assertFalse( depArtifact.isSnapshot() );
+ assertEquals( "", depArtifact.getClassifier() );
+ assertEquals( "jar", depArtifact.getExtension() );
+ assertEquals( "java", depArtifact.getProperty( "language", null ) );
+ assertEquals( "jar", depArtifact.getProperty( "type", null ) );
+ assertEquals( "true", depArtifact.getProperty( "constitutesBuildPath", null ) );
+ assertEquals( "false", depArtifact.getProperty( "includesDependencies", null ) );
+ assertEquals( 4, depArtifact.getProperties().size() );
+
+ assertEquals( "compile", dep2.getScope() );
+ assertFalse( dep2.isOptional() );
+ assertEquals( 0, dep2.getExclusions().size() );
+ depArtifact = dep2.getArtifact();
+ assertEquals( "ut.simple", depArtifact.getGroupId() );
+ assertEquals( "dependency", depArtifact.getArtifactId() );
+ assertEquals( "1.0", depArtifact.getVersion() );
+ assertEquals( "1.0", depArtifact.getBaseVersion() );
+ assertNull( depArtifact.getFile() );
+ assertFalse( depArtifact.isSnapshot() );
+ assertEquals( "sources", depArtifact.getClassifier() );
+ assertEquals( "jar", depArtifact.getExtension() );
+ assertEquals( "java", depArtifact.getProperty( "language", null ) );
+ assertEquals( "jar", depArtifact.getProperty( "type", null ) ); // shouldn't it be java-sources given the classifier?
+ assertEquals( "true", depArtifact.getProperty( "constitutesBuildPath", null ) ); // shouldn't it be false given the classifier?
+ assertEquals( "false", depArtifact.getProperty( "includesDependencies", null ) );
+ assertEquals( 4, depArtifact.getProperties().size() );
+ }
+
+ public void testCollectDependencies()
+ throws Exception
+ {
+ Artifact artifact = new DefaultArtifact( "ut.simple:artifact:extension:classifier:1.0" );
+ // notice: extension and classifier not really used in this test...
+
+ CollectRequest collectRequest = new CollectRequest();
+ collectRequest.setRoot( new Dependency( artifact, null ) );
+ collectRequest.addRepository( newTestRepository() );
+
+ CollectResult collectResult = system.collectDependencies( session, collectRequest );
+
+ List<DependencyNode> nodes = collectResult.getRoot().getChildren();
+ assertEquals( 2, nodes.size() );
+ checkUtSimpleArtifactDependencies( nodes.get( 0 ).getDependency(), nodes.get( 1 ).getDependency() );
+ }
+
+ public void testResolveArtifact()
+ throws Exception
+ {
+ Artifact artifact = new DefaultArtifact( "ut.simple:artifact:1.0" );
+
+ ArtifactRequest artifactRequest = new ArtifactRequest();
+ artifactRequest.setArtifact( artifact );
+ artifactRequest.addRepository( newTestRepository() );
+
+ ArtifactResult artifactResult = system.resolveArtifact( session, artifactRequest );
+ checkArtifactResult( artifactResult, "artifact-1.0.jar" );
+
+ artifact = new DefaultArtifact( "ut.simple:artifact:zip:1.0" );
+ artifactRequest.setArtifact( artifact );
+ artifactResult = system.resolveArtifact( session, artifactRequest );
+ checkArtifactResult( artifactResult, "artifact-1.0.zip" );
+
+ artifact = new DefaultArtifact( "ut.simple:artifact:zip:classifier:1.0" );
+ artifactRequest.setArtifact( artifact );
+ artifactResult = system.resolveArtifact( session, artifactRequest );
+ checkArtifactResult( artifactResult, "artifact-1.0-classifier.zip" );
+ }
+
+ private void checkArtifactResult( ArtifactResult result, String filename )
+ {
+ assertFalse( result.isMissing() );
+ assertTrue( result.isResolved() );
+ Artifact artifact = result.getArtifact();
+ assertNotNull( artifact.getFile() );
+ assertEquals( filename, artifact.getFile().getName() );
+ }
+
+ public void testResolveArtifacts()
+ throws Exception
+ {
+ ArtifactRequest req1 = new ArtifactRequest();
+ req1.setArtifact( new DefaultArtifact( "ut.simple:artifact:1.0" ) );
+ req1.addRepository( newTestRepository() );
+
+ ArtifactRequest req2 = new ArtifactRequest();
+ req2.setArtifact( new DefaultArtifact( "ut.simple:artifact:zip:1.0" ) );
+ req2.addRepository( newTestRepository() );
+
+ ArtifactRequest req3 = new ArtifactRequest();
+ req3.setArtifact( new DefaultArtifact( "ut.simple:artifact:zip:classifier:1.0" ) );
+ req3.addRepository( newTestRepository() );
+
+ List<ArtifactRequest> requests = Arrays.asList( req1, req2, req3 );
+
+ List<ArtifactResult> results = system.resolveArtifacts( session, requests );
+
+ assertEquals( 3, results.size() );
+ checkArtifactResult( results.get( 0 ), "artifact-1.0.jar" );
+ checkArtifactResult( results.get( 1 ), "artifact-1.0.zip" );
+ checkArtifactResult( results.get( 2 ), "artifact-1.0-classifier.zip" );
+ }
+
+ public void testResolveMetadata()
+ throws Exception
+ {
+ //List<MetadataResult> resolveMetadata( RepositorySystemSession session,
+ // Collection<? extends MetadataRequest> requests );
+ }
+
+ public void testInstall()
+ throws Exception
+ {
+ //InstallResult install( RepositorySystemSession session, InstallRequest request )
+ // throws InstallationException;
+ // release, snapshot unique ou non unique, attachement
+ }
+
+ public void testDeploy()
+ throws Exception
+ {
+ //DeployResult deploy( RepositorySystemSession session, DeployRequest request )
+ // throws DeploymentException;
+ }
+
+ public void testNewLocalRepositoryManager()
+ throws Exception
+ {
+ //LocalRepositoryManager newLocalRepositoryManager( LocalRepository localRepository );
+ }
+
+ public void testNewSyncContext()
+ throws Exception
+ {
+ //SyncContext newSyncContext( RepositorySystemSession session, boolean shared );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/test/java/org/apache/maven/repository/internal/util/ConsoleRepositoryListener.java b/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/test/java/org/apache/maven/repository/internal/util/ConsoleRepositoryListener.java
new file mode 100644
index 00000000..2879a9fe
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/test/java/org/apache/maven/repository/internal/util/ConsoleRepositoryListener.java
@@ -0,0 +1,132 @@
+package org.apache.maven.repository.internal.util;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.PrintStream;
+
+import org.eclipse.aether.AbstractRepositoryListener;
+import org.eclipse.aether.RepositoryEvent;
+
+public class ConsoleRepositoryListener
+ extends AbstractRepositoryListener
+{
+
+ private PrintStream out;
+
+ public ConsoleRepositoryListener()
+ {
+ this( null );
+ }
+
+ public ConsoleRepositoryListener( PrintStream out )
+ {
+ this.out = ( out != null ) ? out : System.out;
+ }
+
+ public void artifactDeployed( RepositoryEvent event )
+ {
+ println( "artifactDeployed", event.getArtifact() + " to " + event.getRepository() );
+ }
+
+ public void artifactDeploying( RepositoryEvent event )
+ {
+ println( "artifactDeploying", event.getArtifact() + " to " + event.getRepository() );
+ }
+
+ public void artifactDescriptorInvalid( RepositoryEvent event )
+ {
+ println( "artifactDescriptorInvalid", "for " + event.getArtifact() + ": " + event.getException().getMessage() );
+ }
+
+ public void artifactDescriptorMissing( RepositoryEvent event )
+ {
+ println( "artifactDescriptorMissing", "for " + event.getArtifact() );
+ }
+
+ public void artifactInstalled( RepositoryEvent event )
+ {
+ println( "artifactInstalled", event.getArtifact() + " to " + event.getFile() );
+ }
+
+ public void artifactInstalling( RepositoryEvent event )
+ {
+ println( "artifactInstalling", event.getArtifact() + " to " + event.getFile() );
+ }
+
+ public void artifactResolved( RepositoryEvent event )
+ {
+ println( "artifactResolved", event.getArtifact() + " from " + event.getRepository() );
+ }
+
+ public void artifactDownloading( RepositoryEvent event )
+ {
+ println( "artifactDownloading", event.getArtifact() + " from " + event.getRepository() );
+ }
+
+ public void artifactDownloaded( RepositoryEvent event )
+ {
+ println( "artifactDownloaded", event.getArtifact() + " from " + event.getRepository() );
+ }
+
+ public void artifactResolving( RepositoryEvent event )
+ {
+ println( "artifactResolving", event.getArtifact().toString() );
+ }
+
+ public void metadataDeployed( RepositoryEvent event )
+ {
+ println( "metadataDeployed", event.getMetadata() + " to " + event.getRepository() );
+ }
+
+ public void metadataDeploying( RepositoryEvent event )
+ {
+ println( "metadataDeploying", event.getMetadata() + " to " + event.getRepository() );
+ }
+
+ public void metadataInstalled( RepositoryEvent event )
+ {
+ println( "metadataInstalled", event.getMetadata() + " to " + event.getFile() );
+ }
+
+ public void metadataInstalling( RepositoryEvent event )
+ {
+ println( "metadataInstalling", event.getMetadata() + " to " + event.getFile() );
+ }
+
+ public void metadataInvalid( RepositoryEvent event )
+ {
+ println( "metadataInvalid", event.getMetadata().toString() );
+ }
+
+ public void metadataResolved( RepositoryEvent event )
+ {
+ println( "metadataResolved", event.getMetadata() + " from " + event.getRepository() );
+ }
+
+ public void metadataResolving( RepositoryEvent event )
+ {
+ println( "metadataResolving", event.getMetadata() + " from " + event.getRepository() );
+ }
+
+ private void println( String event, String message )
+ {
+ out.println( "Aether Repository - " + event + ": " + message );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/test/java/org/apache/maven/repository/internal/util/ConsoleTransferListener.java b/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/test/java/org/apache/maven/repository/internal/util/ConsoleTransferListener.java
new file mode 100644
index 00000000..fb442834
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/test/java/org/apache/maven/repository/internal/util/ConsoleTransferListener.java
@@ -0,0 +1,186 @@
+package org.apache.maven.repository.internal.util;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.PrintStream;
+import java.text.DecimalFormat;
+import java.text.DecimalFormatSymbols;
+import java.util.Locale;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.eclipse.aether.transfer.AbstractTransferListener;
+import org.eclipse.aether.transfer.TransferEvent;
+import org.eclipse.aether.transfer.TransferResource;
+
+public class ConsoleTransferListener
+ extends AbstractTransferListener
+{
+
+ private PrintStream out;
+
+ private Map<TransferResource, Long> downloads = new ConcurrentHashMap<TransferResource, Long>();
+
+ private int lastLength;
+
+ public ConsoleTransferListener()
+ {
+ this( null );
+ }
+
+ public ConsoleTransferListener( PrintStream out )
+ {
+ this.out = ( out != null ) ? out : System.out;
+ }
+
+ @Override
+ public void transferInitiated( TransferEvent event )
+ {
+ String message = event.getRequestType() == TransferEvent.RequestType.PUT ? "Uploading" : "Downloading";
+
+ println( "transferInitiated", message + ": " + event.getResource().getRepositoryUrl() + event.getResource().getResourceName() );
+ }
+
+ @Override
+ public void transferProgressed( TransferEvent event )
+ {
+ TransferResource resource = event.getResource();
+ downloads.put( resource, event.getTransferredBytes() );
+
+ StringBuilder buffer = new StringBuilder( 64 );
+
+ for ( Map.Entry<TransferResource, Long> entry : downloads.entrySet() )
+ {
+ long total = entry.getKey().getContentLength();
+ long complete = entry.getValue();
+
+ buffer.append( getStatus( complete, total ) ).append( " " );
+ }
+
+ int pad = lastLength - buffer.length();
+ lastLength = buffer.length();
+ pad( buffer, pad );
+ buffer.append( '\r' );
+
+ print( "transferProgressed", buffer.toString() );
+ }
+
+ private String getStatus( long complete, long total )
+ {
+ if ( total >= 1024 )
+ {
+ return toKB( complete ) + "/" + toKB( total ) + " KB ";
+ }
+ else if ( total >= 0 )
+ {
+ return complete + "/" + total + " B ";
+ }
+ else if ( complete >= 1024 )
+ {
+ return toKB( complete ) + " KB ";
+ }
+ else
+ {
+ return complete + " B ";
+ }
+ }
+
+ private void pad( StringBuilder buffer, int spaces )
+ {
+ String block = " ";
+ while ( spaces > 0 )
+ {
+ int n = Math.min( spaces, block.length() );
+ buffer.append( block, 0, n );
+ spaces -= n;
+ }
+ }
+
+ @Override
+ public void transferSucceeded( TransferEvent event )
+ {
+ transferCompleted( event );
+
+ TransferResource resource = event.getResource();
+ long contentLength = event.getTransferredBytes();
+ if ( contentLength >= 0 )
+ {
+ String type = ( event.getRequestType() == TransferEvent.RequestType.PUT ? "Uploaded" : "Downloaded" );
+ String len = contentLength >= 1024 ? toKB( contentLength ) + " KB" : contentLength + " B";
+
+ String throughput = "";
+ long duration = System.currentTimeMillis() - resource.getTransferStartTime();
+ if ( duration > 0 )
+ {
+ DecimalFormat format = new DecimalFormat( "0.0", new DecimalFormatSymbols( Locale.ENGLISH ) );
+ double kbPerSec = ( contentLength / 1024.0 ) / ( duration / 1000.0 );
+ throughput = " at " + format.format( kbPerSec ) + " KB/sec";
+ }
+
+ println( "transferSucceeded", type + ": " + resource.getRepositoryUrl() + resource.getResourceName() + " ("
+ + len + throughput + ")" );
+ }
+ }
+
+ @Override
+ public void transferFailed( TransferEvent event )
+ {
+ transferCompleted( event );
+
+ println( "transferFailed", event.getException().getClass() + ": " + event.getException().getMessage() );
+ }
+
+ private void transferCompleted( TransferEvent event )
+ {
+ downloads.remove( event.getResource() );
+
+ StringBuilder buffer = new StringBuilder( 64 );
+ pad( buffer, lastLength );
+ buffer.append( '\r' );
+ out.println( buffer );
+ }
+
+ @Override
+ public void transferCorrupted( TransferEvent event )
+ {
+ println( "transferCorrupted", event.getException().getClass() + ": " + event.getException().getMessage() );
+ }
+
+ protected long toKB( long bytes )
+ {
+ return ( bytes + 1023 ) / 1024;
+ }
+
+ private void println( String event, String message )
+ {
+ print( event, message );
+ out.println();
+ }
+
+ private void print( String event, String message )
+ {
+ out.print( "Aether Transfer - " + event );
+ if ( message != null )
+ {
+ out.print( ": " );
+ out.print( message );
+ }
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/test/resources/repo/org/apache/maven/its/dep-mng5324/07.20.3-SNAPSHOT/maven-metadata.xml b/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/test/resources/repo/org/apache/maven/its/dep-mng5324/07.20.3-SNAPSHOT/maven-metadata.xml
new file mode 100644
index 00000000..9f0a7fed
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/test/resources/repo/org/apache/maven/its/dep-mng5324/07.20.3-SNAPSHOT/maven-metadata.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you under the Apache License, Version 2.0 (the
+ ~ "License"); you may not use this file except in compliance
+ ~ with the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing,
+ ~ software distributed under the License is distributed on an
+ ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ ~ KIND, either express or implied. See the License for the
+ ~ specific language governing permissions and limitations
+ ~ under the License.
+-->
+
+<metadata xmlns="http://maven.apache.org/METADATA/1.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/METADATA/1.1.0 http://maven.apache.org/xsd/metadata-1.1.0.xsd"
+ modelVersion="1.1.0">
+ <groupId>org.apache.maven.its</groupId>
+ <artifactId>dep-mng5324</artifactId>
+ <version>07.20.3-SNAPSHOT</version><!-- metadata for artifact snapshot -->
+ <versioning>
+ <snapshot>
+ <timestamp>20120809.112920</timestamp>
+ <buildNumber>97</buildNumber>
+ </snapshot>
+ <lastUpdated>20120809112920</lastUpdated>
+ <snapshotVersions>
+ <snapshotVersion>
+ <classifier>classifierA</classifier>
+ <extension>jar</extension>
+ <value>07.20.3-20120809.112124-88</value>
+ <updated>20120809112124</updated>
+ </snapshotVersion>
+ <snapshotVersion>
+ <classifier>classifierB</classifier>
+ <extension>jar</extension>
+ <value>07.20.3-20120809.112920-97</value>
+ <updated>20120809112920</updated>
+ </snapshotVersion>
+ </snapshotVersions>
+ </versioning>
+</metadata> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/test/resources/repo/org/apache/maven/its/dep-mng5459/0.4.0-SNAPSHOT/maven-metadata.xml b/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/test/resources/repo/org/apache/maven/its/dep-mng5459/0.4.0-SNAPSHOT/maven-metadata.xml
new file mode 100644
index 00000000..923f26fe
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/test/resources/repo/org/apache/maven/its/dep-mng5459/0.4.0-SNAPSHOT/maven-metadata.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you under the Apache License, Version 2.0 (the
+ ~ "License"); you may not use this file except in compliance
+ ~ with the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing,
+ ~ software distributed under the License is distributed on an
+ ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ ~ KIND, either express or implied. See the License for the
+ ~ specific language governing permissions and limitations
+ ~ under the License.
+-->
+
+<metadata xmlns="http://maven.apache.org/METADATA/1.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/METADATA/1.1.0 http://maven.apache.org/xsd/metadata-1.1.0.xsd"
+ modelVersion="1.1.0">
+ <groupId>org.apache.maven.its</groupId>
+ <artifactId>dep-mng5459</artifactId>
+ <version>0.4.0-SNAPSHOT</version>
+ <versioning>
+ <snapshot>
+ <timestamp>20130404.090532</timestamp>
+ <buildNumber>2</buildNumber>
+ </snapshot>
+ <lastUpdated>20130404093657</lastUpdated>
+ <snapshotVersions>
+ <snapshotVersion>
+ <extension>pom</extension>
+ <value>0.4.0-20130404.090532-2</value>
+ <updated>20130404090532</updated>
+ </snapshotVersion>
+ <snapshotVersion>
+ <extension>jar</extension>
+ <value>0.4.0-20130404.093655-3</value>
+ <updated>20130404093655</updated>
+ </snapshotVersion>
+ </snapshotVersions>
+ </versioning>
+</metadata> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/test/resources/repo/ut/simple/artifact/1.0/artifact-1.0-classifier.zip b/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/test/resources/repo/ut/simple/artifact/1.0/artifact-1.0-classifier.zip
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/test/resources/repo/ut/simple/artifact/1.0/artifact-1.0-classifier.zip
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/test/resources/repo/ut/simple/artifact/1.0/artifact-1.0.jar b/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/test/resources/repo/ut/simple/artifact/1.0/artifact-1.0.jar
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/test/resources/repo/ut/simple/artifact/1.0/artifact-1.0.jar
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/test/resources/repo/ut/simple/artifact/1.0/artifact-1.0.pom b/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/test/resources/repo/ut/simple/artifact/1.0/artifact-1.0.pom
new file mode 100644
index 00000000..f8b72af5
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/test/resources/repo/ut/simple/artifact/1.0/artifact-1.0.pom
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you under the Apache License, Version 2.0 (the
+ ~ "License"); you may not use this file except in compliance
+ ~ with the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing,
+ ~ software distributed under the License is distributed on an
+ ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ ~ KIND, either express or implied. See the License for the
+ ~ specific language governing permissions and limitations
+ ~ under the License.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>ut.simple</groupId>
+ <artifactId>parent</artifactId>
+ <version>1.0</version>
+ </parent>
+
+ <artifactId>artifact</artifactId>
+
+ <name>Simple Unit Test Artifact</name>
+
+ <dependencies>
+ <dependency>
+ <groupId>ut.simple</groupId>
+ <artifactId>dependency</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>ut.simple</groupId>
+ <artifactId>dependency</artifactId>
+ <version>1.0</version>
+ <classifier>sources</classifier>
+ </dependency>
+ </dependencies>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/test/resources/repo/ut/simple/artifact/1.0/artifact-1.0.zip b/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/test/resources/repo/ut/simple/artifact/1.0/artifact-1.0.zip
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/test/resources/repo/ut/simple/artifact/1.0/artifact-1.0.zip
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/test/resources/repo/ut/simple/artifact/maven-metadata.xml b/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/test/resources/repo/ut/simple/artifact/maven-metadata.xml
new file mode 100644
index 00000000..2de7eccf
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/test/resources/repo/ut/simple/artifact/maven-metadata.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you under the Apache License, Version 2.0 (the
+ ~ "License"); you may not use this file except in compliance
+ ~ with the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing,
+ ~ software distributed under the License is distributed on an
+ ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ ~ KIND, either express or implied. See the License for the
+ ~ specific language governing permissions and limitations
+ ~ under the License.
+-->
+
+<metadata xmlns="http://maven.apache.org/METADATA/1.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/METADATA/1.1.0 http://maven.apache.org/xsd/metadata-1.1.0.xsd">
+ <groupId>ut.simple</groupId>
+ <artifactId>artifact</artifactId>
+ <versioning>
+ <latest>1.0</latest>
+ <release>1.0</release>
+ <versions>
+ <version>1.0</version>
+ </versions>
+ <lastUpdated>20111123122038</lastUpdated>
+ </versioning>
+</metadata> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/test/resources/repo/ut/simple/dependency/1.0/dependency-1.0-sources.jar b/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/test/resources/repo/ut/simple/dependency/1.0/dependency-1.0-sources.jar
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/test/resources/repo/ut/simple/dependency/1.0/dependency-1.0-sources.jar
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/test/resources/repo/ut/simple/dependency/1.0/dependency-1.0.jar b/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/test/resources/repo/ut/simple/dependency/1.0/dependency-1.0.jar
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/test/resources/repo/ut/simple/dependency/1.0/dependency-1.0.jar
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/test/resources/repo/ut/simple/dependency/1.0/dependency-1.0.pom b/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/test/resources/repo/ut/simple/dependency/1.0/dependency-1.0.pom
new file mode 100644
index 00000000..c021dfac
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/test/resources/repo/ut/simple/dependency/1.0/dependency-1.0.pom
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you under the Apache License, Version 2.0 (the
+ ~ "License"); you may not use this file except in compliance
+ ~ with the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing,
+ ~ software distributed under the License is distributed on an
+ ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ ~ KIND, either express or implied. See the License for the
+ ~ specific language governing permissions and limitations
+ ~ under the License.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>ut.simple</groupId>
+ <artifactId>dependency</artifactId>
+ <version>1.0</version>
+
+ <name>Simple Unit Test Dependency</name>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/test/resources/repo/ut/simple/dependency/maven-metadata.xml b/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/test/resources/repo/ut/simple/dependency/maven-metadata.xml
new file mode 100644
index 00000000..8a97c341
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/test/resources/repo/ut/simple/dependency/maven-metadata.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you under the Apache License, Version 2.0 (the
+ ~ "License"); you may not use this file except in compliance
+ ~ with the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing,
+ ~ software distributed under the License is distributed on an
+ ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ ~ KIND, either express or implied. See the License for the
+ ~ specific language governing permissions and limitations
+ ~ under the License.
+-->
+
+<metadata xmlns="http://maven.apache.org/METADATA/1.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/METADATA/1.1.0 http://maven.apache.org/xsd/metadata-1.1.0.xsd">
+ <groupId>ut.simple</groupId>
+ <artifactId>dependency</artifactId>
+ <versioning>
+ <latest>1.0</latest>
+ <release>1.0</release>
+ <versions>
+ <version>1.0</version>
+ </versions>
+ <lastUpdated>20111123122038</lastUpdated>
+ </versioning>
+</metadata> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/test/resources/repo/ut/simple/parent/1.0/parent-1.0.pom b/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/test/resources/repo/ut/simple/parent/1.0/parent-1.0.pom
new file mode 100644
index 00000000..ed64c9e6
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/test/resources/repo/ut/simple/parent/1.0/parent-1.0.pom
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you under the Apache License, Version 2.0 (the
+ ~ "License"); you may not use this file except in compliance
+ ~ with the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing,
+ ~ software distributed under the License is distributed on an
+ ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ ~ KIND, either express or implied. See the License for the
+ ~ specific language governing permissions and limitations
+ ~ under the License.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>ut.simple</groupId>
+ <artifactId>parent</artifactId>
+ <version>1.0</version>
+ <packaging>pom</packaging>
+
+ <name>Simple Unit Test Parent</name>
+
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>ut.simple</groupId>
+ <artifactId>dependency</artifactId>
+ <version>1.0</version>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/test/resources/repo/ut/simple/parent/maven-metadata.xml b/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/test/resources/repo/ut/simple/parent/maven-metadata.xml
new file mode 100644
index 00000000..7199d52a
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-aether-provider/src/test/resources/repo/ut/simple/parent/maven-metadata.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you under the Apache License, Version 2.0 (the
+ ~ "License"); you may not use this file except in compliance
+ ~ with the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing,
+ ~ software distributed under the License is distributed on an
+ ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ ~ KIND, either express or implied. See the License for the
+ ~ specific language governing permissions and limitations
+ ~ under the License.
+-->
+
+<metadata xmlns="http://maven.apache.org/METADATA/1.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/METADATA/1.1.0 http://maven.apache.org/xsd/metadata-1.1.0.xsd">
+ <groupId>ut.simple</groupId>
+ <artifactId>parent</artifactId>
+ <versioning>
+ <latest>1.0</latest>
+ <release>1.0</release>
+ <versions>
+ <version>1.0</version>
+ </versions>
+ <lastUpdated>20111123122038</lastUpdated>
+ </versioning>
+</metadata> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-ant-tasks-2.1.1.jar b/framework/src/maven/apache-maven-3.3.3/maven-ant-tasks-2.1.1.jar
new file mode 100644
index 00000000..7810a541
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-ant-tasks-2.1.1.jar
Binary files differ
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-artifact/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-artifact/pom.xml
new file mode 100644
index 00000000..206d72b8
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-artifact/pom.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+ <!--
+ Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE
+ file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by
+ applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language
+ governing permissions and limitations under the License.
+ -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven</artifactId>
+ <version>3.3.3</version>
+ </parent>
+
+ <artifactId>maven-artifact</artifactId>
+
+ <name>Maven Artifact</name>
+
+ <scm><!-- remove when git scm url format can accept artifact-id at the end, as automatically inherited -->
+ <connection>scm:git:https://git-wip-us.apache.org/repos/asf/maven.git</connection>
+ <developerConnection>scm:git:https://git-wip-us.apache.org/repos/asf/maven.git</developerConnection>
+ <tag>maven-3.3.3</tag>
+ </scm>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-utils</artifactId>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-component-metadata</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <configuration>
+ <archive>
+ <manifestEntries>
+ <Main-Class>org.apache.maven.artifact.versioning.ComparableVersion</Main-Class>
+ </manifestEntries>
+ </archive>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/Artifact.java b/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/Artifact.java
new file mode 100644
index 00000000..6cc00226
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/Artifact.java
@@ -0,0 +1,161 @@
+package org.apache.maven.artifact;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.util.Collection;
+import java.util.List;
+import java.util.regex.Pattern;
+
+import org.apache.maven.artifact.handler.ArtifactHandler;
+import org.apache.maven.artifact.metadata.ArtifactMetadata;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
+import org.apache.maven.artifact.versioning.ArtifactVersion;
+import org.apache.maven.artifact.versioning.OverConstrainedVersionException;
+import org.apache.maven.artifact.versioning.VersionRange;
+
+/**
+ * Maven Artifact interface. Notice that it mixes artifact definition concepts (groupId, artifactId, version)
+ * with dependency information (version range, scope).
+ */
+public interface Artifact
+ extends Comparable<Artifact>
+{
+
+ String RELEASE_VERSION = "RELEASE";
+
+ String LATEST_VERSION = "LATEST";
+
+ String SNAPSHOT_VERSION = "SNAPSHOT";
+
+ Pattern VERSION_FILE_PATTERN = Pattern.compile( "^(.*)-([0-9]{8}.[0-9]{6})-([0-9]+)$" );
+
+ // TODO: into artifactScope handler
+
+ String SCOPE_COMPILE = "compile";
+
+ String SCOPE_COMPILE_PLUS_RUNTIME = "compile+runtime";
+
+ String SCOPE_TEST = "test";
+
+ String SCOPE_RUNTIME = "runtime";
+
+ String SCOPE_RUNTIME_PLUS_SYSTEM = "runtime+system";
+
+ String SCOPE_PROVIDED = "provided";
+
+ String SCOPE_SYSTEM = "system";
+
+ String SCOPE_IMPORT = "import"; // Used to import dependencyManagement dependencies
+
+ String getGroupId();
+
+ String getArtifactId();
+
+ String getVersion();
+
+ void setVersion( String version );
+
+ String getScope();
+
+ String getType();
+
+ String getClassifier();
+
+ boolean hasClassifier();
+
+ File getFile();
+
+ void setFile( File destination );
+
+ String getBaseVersion();
+
+ void setBaseVersion( String baseVersion );
+
+ String getId();
+
+ String getDependencyConflictId();
+
+ void addMetadata( ArtifactMetadata metadata );
+
+ Collection<ArtifactMetadata> getMetadataList();
+
+ void setRepository( ArtifactRepository remoteRepository );
+
+ ArtifactRepository getRepository();
+
+ void updateVersion( String version, ArtifactRepository localRepository );
+
+ String getDownloadUrl();
+
+ void setDownloadUrl( String downloadUrl );
+
+ ArtifactFilter getDependencyFilter();
+
+ void setDependencyFilter( ArtifactFilter artifactFilter );
+
+ ArtifactHandler getArtifactHandler();
+
+ List<String> getDependencyTrail();
+
+ void setDependencyTrail( List<String> dependencyTrail );
+
+ void setScope( String scope );
+
+ VersionRange getVersionRange();
+
+ void setVersionRange( VersionRange newRange );
+
+ void selectVersion( String version );
+
+ void setGroupId( String groupId );
+
+ void setArtifactId( String artifactId );
+
+ boolean isSnapshot();
+
+ void setResolved( boolean resolved );
+
+ boolean isResolved();
+
+ void setResolvedVersion( String version );
+
+ void setArtifactHandler( ArtifactHandler handler );
+
+ boolean isRelease();
+
+ void setRelease( boolean release );
+
+ List<ArtifactVersion> getAvailableVersions();
+
+ void setAvailableVersions( List<ArtifactVersion> versions );
+
+ boolean isOptional();
+
+ void setOptional( boolean optional );
+
+ ArtifactVersion getSelectedVersion()
+ throws OverConstrainedVersionException;
+
+ boolean isSelectedVersionKnown()
+ throws OverConstrainedVersionException;
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/ArtifactUtils.java b/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/ArtifactUtils.java
new file mode 100644
index 00000000..8efc45cd
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/ArtifactUtils.java
@@ -0,0 +1,215 @@
+package org.apache.maven.artifact;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Matcher;
+
+import org.apache.maven.artifact.versioning.VersionRange;
+
+public final class ArtifactUtils
+{
+
+ public static boolean isSnapshot( String version )
+ {
+ if ( version != null )
+ {
+ if ( version.regionMatches( true, version.length() - Artifact.SNAPSHOT_VERSION.length(),
+ Artifact.SNAPSHOT_VERSION, 0, Artifact.SNAPSHOT_VERSION.length() ) )
+ {
+ return true;
+ }
+ else if ( Artifact.VERSION_FILE_PATTERN.matcher( version ).matches() )
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static String toSnapshotVersion( String version )
+ {
+ if ( version == null )
+ {
+ throw new IllegalArgumentException( "version: null" );
+ }
+
+ Matcher m = Artifact.VERSION_FILE_PATTERN.matcher( version );
+ if ( m.matches() )
+ {
+ return m.group( 1 ) + "-" + Artifact.SNAPSHOT_VERSION;
+ }
+ else
+ {
+ return version;
+ }
+ }
+
+ public static String versionlessKey( Artifact artifact )
+ {
+ return versionlessKey( artifact.getGroupId(), artifact.getArtifactId() );
+ }
+
+ public static String versionlessKey( String groupId, String artifactId )
+ {
+ if ( groupId == null )
+ {
+ throw new NullPointerException( "groupId is null" );
+ }
+ if ( artifactId == null )
+ {
+ throw new NullPointerException( "artifactId is null" );
+ }
+ return groupId + ":" + artifactId;
+ }
+
+ public static String key( Artifact artifact )
+ {
+ return key( artifact.getGroupId(), artifact.getArtifactId(), artifact.getVersion() );
+ }
+
+ public static String key( String groupId, String artifactId, String version )
+ {
+ if ( groupId == null )
+ {
+ throw new NullPointerException( "groupId is null" );
+ }
+ if ( artifactId == null )
+ {
+ throw new NullPointerException( "artifactId is null" );
+ }
+ if ( version == null )
+ {
+ throw new NullPointerException( "version is null" );
+ }
+
+ return groupId + ":" + artifactId + ":" + version;
+ }
+
+ public static Map<String, Artifact> artifactMapByVersionlessId( Collection<Artifact> artifacts )
+ {
+ Map<String, Artifact> artifactMap = new LinkedHashMap<String, Artifact>();
+
+ if ( artifacts != null )
+ {
+ for ( Artifact artifact : artifacts )
+ {
+ artifactMap.put( versionlessKey( artifact ), artifact );
+ }
+ }
+
+ return artifactMap;
+ }
+
+ public static Artifact copyArtifactSafe( Artifact artifact )
+ {
+ return ( artifact != null ) ? copyArtifact( artifact ) : null;
+ }
+
+ public static Artifact copyArtifact( Artifact artifact )
+ {
+ VersionRange range = artifact.getVersionRange();
+
+ // For some reason with the introduction of MNG-1577 we have the case in Yoko where a depMan section has
+ // something like the following:
+ //
+ // <dependencyManagement>
+ // <dependencies>
+ // <!-- Yoko modules -->
+ // <dependency>
+ // <groupId>org.apache.yoko</groupId>
+ // <artifactId>yoko-core</artifactId>
+ // <version>${version}</version>
+ // </dependency>
+ // ...
+ //
+ // And the range is not set so we'll check here and set it. jvz.
+
+ if ( range == null )
+ {
+ range = VersionRange.createFromVersion( artifact.getVersion() );
+ }
+
+ DefaultArtifact clone = new DefaultArtifact( artifact.getGroupId(), artifact.getArtifactId(), range.cloneOf(),
+ artifact.getScope(), artifact.getType(), artifact.getClassifier(),
+ artifact.getArtifactHandler(), artifact.isOptional() );
+ clone.setRelease( artifact.isRelease() );
+ clone.setResolvedVersion( artifact.getVersion() );
+ clone.setResolved( artifact.isResolved() );
+ clone.setFile( artifact.getFile() );
+
+ clone.setAvailableVersions( copyList( artifact.getAvailableVersions() ) );
+ if ( artifact.getVersion() != null )
+ {
+ clone.setBaseVersion( artifact.getBaseVersion() );
+ }
+ clone.setDependencyFilter( artifact.getDependencyFilter() );
+ clone.setDependencyTrail( copyList( artifact.getDependencyTrail() ) );
+ clone.setDownloadUrl( artifact.getDownloadUrl() );
+ clone.setRepository( artifact.getRepository() );
+
+ return clone;
+ }
+
+ /** Returns <code>to</code> collection */
+ public static <T extends Collection<Artifact>> T copyArtifacts( Collection<Artifact> from, T to )
+ {
+ for ( Artifact artifact : from )
+ {
+ to.add( ArtifactUtils.copyArtifact( artifact ) );
+ }
+ return to;
+ }
+
+ public static <K, T extends Map<K, Artifact>> T copyArtifacts( Map<K, ? extends Artifact> from, T to )
+ {
+ if ( from != null )
+ {
+ for ( Map.Entry<K, ? extends Artifact> entry : from.entrySet() )
+ {
+ to.put( entry.getKey(), ArtifactUtils.copyArtifact( entry.getValue() ) );
+ }
+ }
+
+ return to;
+ }
+
+ private static <T> List<T> copyList( List<T> original )
+ {
+ List<T> copy = null;
+
+ if ( original != null )
+ {
+ copy = new ArrayList<T>();
+
+ if ( !original.isEmpty() )
+ {
+ copy.addAll( original );
+ }
+ }
+
+ return copy;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/DefaultArtifact.java b/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/DefaultArtifact.java
new file mode 100644
index 00000000..e3e42c0a
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/DefaultArtifact.java
@@ -0,0 +1,597 @@
+package org.apache.maven.artifact;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Matcher;
+
+import org.apache.maven.artifact.handler.ArtifactHandler;
+import org.apache.maven.artifact.metadata.ArtifactMetadata;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
+import org.apache.maven.artifact.versioning.ArtifactVersion;
+import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
+import org.apache.maven.artifact.versioning.OverConstrainedVersionException;
+import org.apache.maven.artifact.versioning.VersionRange;
+import org.codehaus.plexus.util.StringUtils;
+
+/**
+ * @author Jason van Zyl
+ */
+public class DefaultArtifact
+ implements Artifact
+{
+ private String groupId;
+
+ private String artifactId;
+
+ private String baseVersion;
+
+ private final String type;
+
+ private final String classifier;
+
+ private volatile String scope;
+
+ private volatile File file;
+
+ private ArtifactRepository repository;
+
+ private String downloadUrl;
+
+ private ArtifactFilter dependencyFilter;
+
+ private ArtifactHandler artifactHandler;
+
+ private List<String> dependencyTrail;
+
+ private volatile String version;
+
+ private VersionRange versionRange;
+
+ private volatile boolean resolved;
+
+ private boolean release;
+
+ private List<ArtifactVersion> availableVersions;
+
+ private Map<Object, ArtifactMetadata> metadataMap;
+
+ private boolean optional;
+
+ public DefaultArtifact( String groupId, String artifactId, String version, String scope, String type,
+ String classifier, ArtifactHandler artifactHandler )
+ {
+ this( groupId, artifactId, VersionRange.createFromVersion( version ), scope, type, classifier, artifactHandler,
+ false );
+ }
+
+ public DefaultArtifact( String groupId, String artifactId, VersionRange versionRange, String scope, String type,
+ String classifier, ArtifactHandler artifactHandler )
+ {
+ this( groupId, artifactId, versionRange, scope, type, classifier, artifactHandler, false );
+ }
+
+ public DefaultArtifact( String groupId, String artifactId, VersionRange versionRange, String scope, String type,
+ String classifier, ArtifactHandler artifactHandler, boolean optional )
+ {
+ this.groupId = groupId;
+
+ this.artifactId = artifactId;
+
+ this.versionRange = versionRange;
+
+ selectVersionFromNewRangeIfAvailable();
+
+ this.artifactHandler = artifactHandler;
+
+ this.scope = scope;
+
+ this.type = type;
+
+ if ( classifier == null )
+ {
+ classifier = artifactHandler.getClassifier();
+ }
+
+ this.classifier = classifier;
+
+ this.optional = optional;
+
+ validateIdentity();
+ }
+
+ private void validateIdentity()
+ {
+ if ( empty( groupId ) )
+ {
+ throw new InvalidArtifactRTException( groupId, artifactId, getVersion(), type,
+ "The groupId cannot be empty." );
+ }
+
+ if ( artifactId == null )
+ {
+ throw new InvalidArtifactRTException( groupId, artifactId, getVersion(), type,
+ "The artifactId cannot be empty." );
+ }
+
+ if ( type == null )
+ {
+ throw new InvalidArtifactRTException( groupId, artifactId, getVersion(), type,
+ "The type cannot be empty." );
+ }
+
+ if ( ( version == null ) && ( versionRange == null ) )
+ {
+ throw new InvalidArtifactRTException( groupId, artifactId, getVersion(), type,
+ "The version cannot be empty." );
+ }
+ }
+
+ private boolean empty( String value )
+ {
+ return ( value == null ) || ( value.trim().length() < 1 );
+ }
+
+ public String getClassifier()
+ {
+ return classifier;
+ }
+
+ public boolean hasClassifier()
+ {
+ return StringUtils.isNotEmpty( classifier );
+ }
+
+ public String getScope()
+ {
+ return scope;
+ }
+
+ public String getGroupId()
+ {
+ return groupId;
+ }
+
+ public String getArtifactId()
+ {
+ return artifactId;
+ }
+
+ public String getVersion()
+ {
+ return version;
+ }
+
+ public void setVersion( String version )
+ {
+ this.version = version;
+ setBaseVersionInternal( version );
+ versionRange = null;
+ }
+
+ public String getType()
+ {
+ return type;
+ }
+
+ public void setFile( File file )
+ {
+ this.file = file;
+ }
+
+ public File getFile()
+ {
+ return file;
+ }
+
+ public ArtifactRepository getRepository()
+ {
+ return repository;
+ }
+
+ public void setRepository( ArtifactRepository repository )
+ {
+ this.repository = repository;
+ }
+
+ // ----------------------------------------------------------------------
+ //
+ // ----------------------------------------------------------------------
+
+ public String getId()
+ {
+ return getDependencyConflictId() + ":" + getBaseVersion();
+ }
+
+ public String getDependencyConflictId()
+ {
+ StringBuilder sb = new StringBuilder( 128 );
+ sb.append( getGroupId() );
+ sb.append( ":" );
+ appendArtifactTypeClassifierString( sb );
+ return sb.toString();
+ }
+
+ private void appendArtifactTypeClassifierString( StringBuilder sb )
+ {
+ sb.append( getArtifactId() );
+ sb.append( ":" );
+ sb.append( getType() );
+ if ( hasClassifier() )
+ {
+ sb.append( ":" );
+ sb.append( getClassifier() );
+ }
+ }
+
+ public void addMetadata( ArtifactMetadata metadata )
+ {
+ if ( metadataMap == null )
+ {
+ metadataMap = new HashMap<Object, ArtifactMetadata>();
+ }
+
+ ArtifactMetadata m = metadataMap.get( metadata.getKey() );
+ if ( m != null )
+ {
+ m.merge( metadata );
+ }
+ else
+ {
+ metadataMap.put( metadata.getKey(), metadata );
+ }
+ }
+
+ public Collection<ArtifactMetadata> getMetadataList()
+ {
+ if ( metadataMap == null )
+ {
+ return Collections.emptyList();
+ }
+
+ return metadataMap.values();
+ }
+
+ // ----------------------------------------------------------------------
+ // Object overrides
+ // ----------------------------------------------------------------------
+
+ public String toString()
+ {
+ StringBuilder sb = new StringBuilder();
+ if ( getGroupId() != null )
+ {
+ sb.append( getGroupId() );
+ sb.append( ":" );
+ }
+ appendArtifactTypeClassifierString( sb );
+ sb.append( ":" );
+ if ( getBaseVersionInternal() != null )
+ {
+ sb.append( getBaseVersionInternal() );
+ }
+ else
+ {
+ sb.append( versionRange.toString() );
+ }
+ if ( scope != null )
+ {
+ sb.append( ":" );
+ sb.append( scope );
+ }
+ return sb.toString();
+ }
+
+ public int hashCode()
+ {
+ int result = 17;
+ result = 37 * result + groupId.hashCode();
+ result = 37 * result + artifactId.hashCode();
+ result = 37 * result + type.hashCode();
+ if ( version != null )
+ {
+ result = 37 * result + version.hashCode();
+ }
+ result = 37 * result + ( classifier != null ? classifier.hashCode() : 0 );
+ return result;
+ }
+
+ public boolean equals( Object o )
+ {
+ if ( o == this )
+ {
+ return true;
+ }
+
+ if ( !( o instanceof Artifact ) )
+ {
+ return false;
+ }
+
+ Artifact a = (Artifact) o;
+
+ if ( !a.getGroupId().equals( groupId ) )
+ {
+ return false;
+ }
+ else if ( !a.getArtifactId().equals( artifactId ) )
+ {
+ return false;
+ }
+ else if ( !a.getVersion().equals( version ) )
+ {
+ return false;
+ }
+ else if ( !a.getType().equals( type ) )
+ {
+ return false;
+ }
+ else if ( a.getClassifier() == null ? classifier != null : !a.getClassifier().equals( classifier ) )
+ {
+ return false;
+ }
+
+ // We don't consider the version range in the comparison, just the resolved version
+
+ return true;
+ }
+
+ public String getBaseVersion()
+ {
+ if ( baseVersion == null && version != null )
+ {
+ setBaseVersionInternal( version );
+ }
+
+ return baseVersion;
+ }
+
+ protected String getBaseVersionInternal()
+ {
+ if ( ( baseVersion == null ) && ( version != null ) )
+ {
+ setBaseVersionInternal( version );
+ }
+
+ return baseVersion;
+ }
+
+ public void setBaseVersion( String baseVersion )
+ {
+ setBaseVersionInternal( baseVersion );
+ }
+
+ protected void setBaseVersionInternal( String baseVersion )
+ {
+ Matcher m = VERSION_FILE_PATTERN.matcher( baseVersion );
+
+ if ( m.matches() )
+ {
+ this.baseVersion = m.group( 1 ) + "-" + SNAPSHOT_VERSION;
+ }
+ else
+ {
+ this.baseVersion = baseVersion;
+ }
+ }
+
+ public int compareTo( Artifact a )
+ {
+ int result = groupId.compareTo( a.getGroupId() );
+ if ( result == 0 )
+ {
+ result = artifactId.compareTo( a.getArtifactId() );
+ if ( result == 0 )
+ {
+ result = type.compareTo( a.getType() );
+ if ( result == 0 )
+ {
+ if ( classifier == null )
+ {
+ if ( a.getClassifier() != null )
+ {
+ result = 1;
+ }
+ }
+ else
+ {
+ if ( a.getClassifier() != null )
+ {
+ result = classifier.compareTo( a.getClassifier() );
+ }
+ else
+ {
+ result = -1;
+ }
+ }
+ if ( result == 0 )
+ {
+ // We don't consider the version range in the comparison, just the resolved version
+ result = new DefaultArtifactVersion( version ).compareTo(
+ new DefaultArtifactVersion( a.getVersion() ) );
+ }
+ }
+ }
+ }
+ return result;
+ }
+
+ public void updateVersion( String version, ArtifactRepository localRepository )
+ {
+ setResolvedVersion( version );
+ setFile( new File( localRepository.getBasedir(), localRepository.pathOf( this ) ) );
+ }
+
+ public String getDownloadUrl()
+ {
+ return downloadUrl;
+ }
+
+ public void setDownloadUrl( String downloadUrl )
+ {
+ this.downloadUrl = downloadUrl;
+ }
+
+ public ArtifactFilter getDependencyFilter()
+ {
+ return dependencyFilter;
+ }
+
+ public void setDependencyFilter( ArtifactFilter artifactFilter )
+ {
+ dependencyFilter = artifactFilter;
+ }
+
+ public ArtifactHandler getArtifactHandler()
+ {
+ return artifactHandler;
+ }
+
+ public List<String> getDependencyTrail()
+ {
+ return dependencyTrail;
+ }
+
+ public void setDependencyTrail( List<String> dependencyTrail )
+ {
+ this.dependencyTrail = dependencyTrail;
+ }
+
+ public void setScope( String scope )
+ {
+ this.scope = scope;
+ }
+
+ public VersionRange getVersionRange()
+ {
+ return versionRange;
+ }
+
+ public void setVersionRange( VersionRange versionRange )
+ {
+ this.versionRange = versionRange;
+ selectVersionFromNewRangeIfAvailable();
+ }
+
+ private void selectVersionFromNewRangeIfAvailable()
+ {
+ if ( ( versionRange != null ) && ( versionRange.getRecommendedVersion() != null ) )
+ {
+ selectVersion( versionRange.getRecommendedVersion().toString() );
+ }
+ else
+ {
+ version = null;
+ baseVersion = null;
+ }
+ }
+
+ public void selectVersion( String version )
+ {
+ this.version = version;
+ setBaseVersionInternal( version );
+ }
+
+ public void setGroupId( String groupId )
+ {
+ this.groupId = groupId;
+ }
+
+ public void setArtifactId( String artifactId )
+ {
+ this.artifactId = artifactId;
+ }
+
+ public boolean isSnapshot()
+ {
+ return getBaseVersion() != null
+ && ( getBaseVersion().endsWith( SNAPSHOT_VERSION ) || getBaseVersion().equals( LATEST_VERSION ) );
+ }
+
+ public void setResolved( boolean resolved )
+ {
+ this.resolved = resolved;
+ }
+
+ public boolean isResolved()
+ {
+ return resolved;
+ }
+
+ public void setResolvedVersion( String version )
+ {
+ this.version = version;
+ // retain baseVersion
+ }
+
+ public void setArtifactHandler( ArtifactHandler artifactHandler )
+ {
+ this.artifactHandler = artifactHandler;
+ }
+
+ public void setRelease( boolean release )
+ {
+ this.release = release;
+ }
+
+ public boolean isRelease()
+ {
+ return release;
+ }
+
+ public List<ArtifactVersion> getAvailableVersions()
+ {
+ return availableVersions;
+ }
+
+ public void setAvailableVersions( List<ArtifactVersion> availableVersions )
+ {
+ this.availableVersions = availableVersions;
+ }
+
+ public boolean isOptional()
+ {
+ return optional;
+ }
+
+ public ArtifactVersion getSelectedVersion()
+ throws OverConstrainedVersionException
+ {
+ return versionRange.getSelectedVersion( this );
+ }
+
+ public boolean isSelectedVersionKnown()
+ throws OverConstrainedVersionException
+ {
+ return versionRange.isSelectedVersionKnown( this );
+ }
+
+ public void setOptional( boolean optional )
+ {
+ this.optional = optional;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/InvalidArtifactRTException.java b/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/InvalidArtifactRTException.java
new file mode 100644
index 00000000..adf656d1
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/InvalidArtifactRTException.java
@@ -0,0 +1,100 @@
+package org.apache.maven.artifact;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Exception thrown when the identity of an artifact can not be established,
+ * eg. one of groupId, artifactId, version or type is null.
+ */
+public class InvalidArtifactRTException
+ extends RuntimeException
+{
+
+ private final String groupId;
+ private final String artifactId;
+ private final String version;
+ private final String type;
+ private final String baseMessage;
+
+ public InvalidArtifactRTException( String groupId,
+ String artifactId,
+ String version,
+ String type,
+ String message )
+ {
+ this.groupId = groupId;
+ this.artifactId = artifactId;
+ this.version = version;
+ this.type = type;
+ this.baseMessage = message;
+ }
+
+ public InvalidArtifactRTException( String groupId,
+ String artifactId,
+ String version,
+ String type,
+ String message,
+ Throwable cause )
+ {
+ super( cause );
+
+ this.groupId = groupId;
+ this.artifactId = artifactId;
+ this.version = version;
+ this.type = type;
+ this.baseMessage = message;
+ }
+
+ public String getMessage()
+ {
+ return "For artifact {" + getArtifactKey() + "}: " + getBaseMessage();
+ }
+
+ public String getBaseMessage()
+ {
+ return baseMessage;
+ }
+
+ public String getArtifactId()
+ {
+ return artifactId;
+ }
+
+ public String getGroupId()
+ {
+ return groupId;
+ }
+
+ public String getType()
+ {
+ return type;
+ }
+
+ public String getVersion()
+ {
+ return version;
+ }
+
+ public String getArtifactKey()
+ {
+ return groupId + ":" + artifactId + ":" + version + ":" + type;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/handler/ArtifactHandler.java b/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/handler/ArtifactHandler.java
new file mode 100644
index 00000000..a9d60f2e
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/handler/ArtifactHandler.java
@@ -0,0 +1,42 @@
+package org.apache.maven.artifact.handler;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * @author <a href="mailto:jason@maven.org">Jason van Zyl</a>
+ */
+public interface ArtifactHandler
+{
+ String ROLE = ArtifactHandler.class.getName();
+
+ String getExtension();
+
+ String getDirectory();
+
+ String getClassifier();
+
+ String getPackaging();
+
+ boolean isIncludesDependencies();
+
+ String getLanguage();
+
+ boolean isAddedToClasspath();
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/metadata/ArtifactMetadata.java b/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/metadata/ArtifactMetadata.java
new file mode 100644
index 00000000..452c9f4a
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/metadata/ArtifactMetadata.java
@@ -0,0 +1,27 @@
+package org.apache.maven.artifact.metadata;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+@Deprecated
+public interface ArtifactMetadata
+ extends org.apache.maven.repository.legacy.metadata.ArtifactMetadata
+{
+ void merge( ArtifactMetadata metadata );
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/repository/ArtifactRepository.java b/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/repository/ArtifactRepository.java
new file mode 100644
index 00000000..9ef30387
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/repository/ArtifactRepository.java
@@ -0,0 +1,135 @@
+package org.apache.maven.artifact.repository;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.List;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.metadata.ArtifactMetadata;
+import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout;
+import org.apache.maven.repository.Proxy;
+
+/**
+ * Abstraction of an artifact repository. Artifact repositories can be remote, local, or even build reactor or
+ * IDE workspace.
+ */
+public interface ArtifactRepository
+{
+ String pathOf( Artifact artifact );
+
+ String pathOfRemoteRepositoryMetadata( ArtifactMetadata artifactMetadata );
+
+ String pathOfLocalRepositoryMetadata( ArtifactMetadata metadata, ArtifactRepository repository );
+
+ String getUrl();
+
+ void setUrl( String url );
+
+ String getBasedir();
+
+ String getProtocol();
+
+ String getId();
+
+ void setId( String id );
+
+ ArtifactRepositoryPolicy getSnapshots();
+
+ void setSnapshotUpdatePolicy( ArtifactRepositoryPolicy policy );
+
+ ArtifactRepositoryPolicy getReleases();
+
+ void setReleaseUpdatePolicy( ArtifactRepositoryPolicy policy );
+
+ ArtifactRepositoryLayout getLayout();
+
+ void setLayout( ArtifactRepositoryLayout layout );
+
+ String getKey();
+
+ @Deprecated
+ boolean isUniqueVersion();
+
+ @Deprecated
+ boolean isBlacklisted();
+
+ @Deprecated
+ void setBlacklisted( boolean blackListed );
+
+ //
+ // New interface methods for the repository system.
+ //
+ /**
+ *
+ * @param artifact
+ * @return
+ * @since 3.0-alpha-3
+ */
+ Artifact find( Artifact artifact );
+
+ /**
+ * Finds the versions of the specified artifact that are available in this repository.
+ *
+ * @param artifact The artifact whose available versions should be determined, must not be {@code null}.
+ * @return The available versions of the artifact or an empty list if none, never {@code null}.
+ * @since 3.0-alpha-3
+ */
+ List<String> findVersions( Artifact artifact );
+
+ /**
+ * Indicates whether this repository is backed by actual projects. For instance, the build reactor or IDE workspace
+ * are examples of such repositories.
+ *
+ * @return {@code true} if the repository is backed by actual projects, {@code false} otherwise.
+ * @since 3.0-beta-1
+ */
+ boolean isProjectAware();
+
+ /**
+ * @since 3.0-alpha-3
+ */
+ void setAuthentication( Authentication authentication );
+ /**
+ * @since 3.0-alpha-3
+ */
+ Authentication getAuthentication();
+
+ /**
+ * @since 3.0-alpha-3
+ */
+ void setProxy( Proxy proxy );
+ /**
+ * @since 3.0-alpha-3
+ */
+ Proxy getProxy();
+
+ /**
+ * @since 3.0.3
+ * @return the repositories mirrored by the actual one
+ */
+ List<ArtifactRepository> getMirroredRepositories();
+
+ /**
+ * @since 3.0.3
+ * @param mirroredRepositories the repositories that the actual one mirrors
+ */
+ void setMirroredRepositories( List<ArtifactRepository> mirroredRepositories );
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/repository/ArtifactRepositoryPolicy.java b/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/repository/ArtifactRepositoryPolicy.java
new file mode 100644
index 00000000..b6cd8f39
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/repository/ArtifactRepositoryPolicy.java
@@ -0,0 +1,222 @@
+package org.apache.maven.artifact.repository;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Calendar;
+import java.util.Date;
+
+/**
+ * Describes a set of policies for a repository to use under certain conditions.
+ *
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ */
+public class ArtifactRepositoryPolicy
+{
+ public static final String UPDATE_POLICY_NEVER = "never";
+
+ public static final String UPDATE_POLICY_ALWAYS = "always";
+
+ public static final String UPDATE_POLICY_DAILY = "daily";
+
+ public static final String UPDATE_POLICY_INTERVAL = "interval";
+
+ public static final String CHECKSUM_POLICY_FAIL = "fail";
+
+ public static final String CHECKSUM_POLICY_WARN = "warn";
+
+ public static final String CHECKSUM_POLICY_IGNORE = "ignore";
+
+ private boolean enabled;
+
+ private String updatePolicy;
+
+ private String checksumPolicy;
+
+ public ArtifactRepositoryPolicy()
+ {
+ this( true, null, null );
+ }
+
+ public ArtifactRepositoryPolicy( ArtifactRepositoryPolicy policy )
+ {
+ this( policy.isEnabled(), policy.getUpdatePolicy(), policy.getChecksumPolicy() );
+ }
+
+ public ArtifactRepositoryPolicy( boolean enabled, String updatePolicy, String checksumPolicy )
+ {
+ this.enabled = enabled;
+
+ if ( updatePolicy == null )
+ {
+ updatePolicy = UPDATE_POLICY_DAILY;
+ }
+ this.updatePolicy = updatePolicy;
+
+ if ( checksumPolicy == null )
+ {
+ checksumPolicy = CHECKSUM_POLICY_WARN;
+ }
+ this.checksumPolicy = checksumPolicy;
+ }
+
+ public void setEnabled( boolean enabled )
+ {
+ this.enabled = enabled;
+ }
+
+ public void setUpdatePolicy( String updatePolicy )
+ {
+ if ( updatePolicy != null )
+ {
+ this.updatePolicy = updatePolicy;
+ }
+ }
+
+ public void setChecksumPolicy( String checksumPolicy )
+ {
+ if ( checksumPolicy != null )
+ {
+ this.checksumPolicy = checksumPolicy;
+ }
+ }
+
+ public boolean isEnabled()
+ {
+ return enabled;
+ }
+
+ public String getUpdatePolicy()
+ {
+ return updatePolicy;
+ }
+
+ public String getChecksumPolicy()
+ {
+ return checksumPolicy;
+ }
+
+ public boolean checkOutOfDate( Date lastModified )
+ {
+ boolean checkForUpdates = false;
+
+ if ( UPDATE_POLICY_ALWAYS.equals( updatePolicy ) )
+ {
+ checkForUpdates = true;
+ }
+ else if ( UPDATE_POLICY_DAILY.equals( updatePolicy ) )
+ {
+ // Get local midnight boundary
+ Calendar cal = Calendar.getInstance();
+
+ cal.set( Calendar.HOUR_OF_DAY, 0 );
+ cal.set( Calendar.MINUTE, 0 );
+ cal.set( Calendar.SECOND, 0 );
+ cal.set( Calendar.MILLISECOND, 0 );
+
+ if ( cal.getTime().after( lastModified ) )
+ {
+ checkForUpdates = true;
+ }
+ }
+ else if ( updatePolicy.startsWith( UPDATE_POLICY_INTERVAL ) )
+ {
+ String s = updatePolicy.substring( UPDATE_POLICY_INTERVAL.length() + 1 );
+ int minutes = Integer.valueOf( s );
+ Calendar cal = Calendar.getInstance();
+ cal.add( Calendar.MINUTE, -minutes );
+ if ( cal.getTime().after( lastModified ) )
+ {
+ checkForUpdates = true;
+ }
+ }
+ // else assume "never"
+ return checkForUpdates;
+ }
+
+ @Override
+ public String toString()
+ {
+ StringBuilder buffer = new StringBuilder( 64 );
+ buffer.append( "{enabled=" );
+ buffer.append( enabled );
+ buffer.append( ", checksums=" );
+ buffer.append( checksumPolicy );
+ buffer.append( ", updates=" );
+ buffer.append( updatePolicy );
+ buffer.append( "}" );
+ return buffer.toString();
+ }
+
+ public void merge( ArtifactRepositoryPolicy policy )
+ {
+ if ( policy != null && policy.isEnabled() )
+ {
+ setEnabled( true );
+
+ if ( ordinalOfCksumPolicy( policy.getChecksumPolicy() ) < ordinalOfCksumPolicy( getChecksumPolicy() ) )
+ {
+ setChecksumPolicy( policy.getChecksumPolicy() );
+ }
+
+ if ( ordinalOfUpdatePolicy( policy.getUpdatePolicy() ) < ordinalOfUpdatePolicy( getUpdatePolicy() ) )
+ {
+ setUpdatePolicy( policy.getUpdatePolicy() );
+ }
+ }
+ }
+
+ private int ordinalOfCksumPolicy( String policy )
+ {
+ if ( ArtifactRepositoryPolicy.CHECKSUM_POLICY_FAIL.equals( policy ) )
+ {
+ return 2;
+ }
+ else if ( ArtifactRepositoryPolicy.CHECKSUM_POLICY_IGNORE.equals( policy ) )
+ {
+ return 0;
+ }
+ else
+ {
+ return 1;
+ }
+ }
+
+ private int ordinalOfUpdatePolicy( String policy )
+ {
+ if ( ArtifactRepositoryPolicy.UPDATE_POLICY_DAILY.equals( policy ) )
+ {
+ return 1440;
+ }
+ else if ( ArtifactRepositoryPolicy.UPDATE_POLICY_ALWAYS.equals( policy ) )
+ {
+ return 0;
+ }
+ else if ( policy != null && policy.startsWith( ArtifactRepositoryPolicy.UPDATE_POLICY_INTERVAL ) )
+ {
+ String s = policy.substring( UPDATE_POLICY_INTERVAL.length() + 1 );
+ return Integer.valueOf( s );
+ }
+ else
+ {
+ return Integer.MAX_VALUE;
+ }
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/repository/Authentication.java b/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/repository/Authentication.java
new file mode 100644
index 00000000..323fb25b
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/repository/Authentication.java
@@ -0,0 +1,126 @@
+package org.apache.maven.artifact.repository;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+public class Authentication
+{
+
+ private String privateKey;
+
+ private String passphrase;
+
+ public Authentication( String userName, String password )
+ {
+ this.username = userName;
+ this.password = password;
+ }
+
+ /**
+ * Username used to login to the host
+ */
+ private String username;
+
+ /**
+ * Password associated with the login
+ */
+ private String password;
+
+ /**
+ * Get the user's password which is used when connecting to the repository.
+ *
+ * @return password of user
+ */
+ public String getPassword()
+ {
+ return password;
+ }
+
+ /**
+ * Set the user's password which is used when connecting to the repository.
+ *
+ * @param password password of the user
+ */
+ public void setPassword( String password )
+ {
+ this.password = password;
+ }
+
+ /**
+ * Get the username used to access the repository.
+ *
+ * @return username at repository
+ */
+ public String getUsername()
+ {
+ return username;
+ }
+
+ /**
+ * Set username used to access the repository.
+ *
+ * @param userName the username used to access repository
+ */
+ public void setUsername( final String userName )
+ {
+ this.username = userName;
+ }
+
+ /**
+ * Get the passphrase of the private key file. The passphrase is used only when host/protocol supports
+ * authentication via exchange of private/public keys and private key was used for authentication.
+ *
+ * @return passphrase of the private key file
+ */
+ public String getPassphrase()
+ {
+ return passphrase;
+ }
+
+ /**
+ * Set the passphrase of the private key file.
+ *
+ * @param passphrase passphrase of the private key file
+ */
+ public void setPassphrase( final String passphrase )
+ {
+ this.passphrase = passphrase;
+ }
+
+ /**
+ * Get the absolute path to the private key file.
+ *
+ * @return absolute path to private key
+ */
+ public String getPrivateKey()
+ {
+ return privateKey;
+ }
+
+ /**
+ * Set the absolute path to private key file.
+ *
+ * @param privateKey path to private key in local file system
+ */
+ public void setPrivateKey( final String privateKey )
+ {
+ this.privateKey = privateKey;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/repository/layout/ArtifactRepositoryLayout.java b/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/repository/layout/ArtifactRepositoryLayout.java
new file mode 100644
index 00000000..2a18c863
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/repository/layout/ArtifactRepositoryLayout.java
@@ -0,0 +1,38 @@
+package org.apache.maven.artifact.repository.layout;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.metadata.ArtifactMetadata;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+
+/** @author jdcasey */
+public interface ArtifactRepositoryLayout
+{
+ String ROLE = ArtifactRepositoryLayout.class.getName();
+
+ String getId();
+
+ String pathOf( Artifact artifact );
+
+ String pathOfLocalRepositoryMetadata( ArtifactMetadata metadata, ArtifactRepository repository );
+
+ String pathOfRemoteRepositoryMetadata( ArtifactMetadata metadata );
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/repository/layout/ArtifactRepositoryLayout2.java b/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/repository/layout/ArtifactRepositoryLayout2.java
new file mode 100644
index 00000000..c0544e5c
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/repository/layout/ArtifactRepositoryLayout2.java
@@ -0,0 +1,31 @@
+package org.apache.maven.artifact.repository.layout;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy;
+
+public interface ArtifactRepositoryLayout2
+ extends ArtifactRepositoryLayout
+{
+
+ ArtifactRepository newMavenArtifactRepository( String id, String url, ArtifactRepositoryPolicy snapshots,
+ ArtifactRepositoryPolicy releases );
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/repository/metadata/RepositoryMetadataStoreException.java b/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/repository/metadata/RepositoryMetadataStoreException.java
new file mode 100644
index 00000000..38488522
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/repository/metadata/RepositoryMetadataStoreException.java
@@ -0,0 +1,40 @@
+package org.apache.maven.artifact.repository.metadata;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Problem storing the repository metadata in the local repository.
+ *
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ */
+public class RepositoryMetadataStoreException
+ extends Exception
+{
+ public RepositoryMetadataStoreException( String message )
+ {
+ super( message );
+ }
+
+ public RepositoryMetadataStoreException( String message,
+ Exception e )
+ {
+ super( message, e );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/resolver/AbstractArtifactResolutionException.java b/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/resolver/AbstractArtifactResolutionException.java
new file mode 100644
index 00000000..66e147c2
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/resolver/AbstractArtifactResolutionException.java
@@ -0,0 +1,347 @@
+package org.apache.maven.artifact.resolver;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy;
+
+/**
+ * Base class for artifact resolution exceptions.
+ *
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ */
+public class AbstractArtifactResolutionException
+ extends Exception
+{
+ private String groupId;
+
+ private String artifactId;
+
+ private String version;
+
+ private String type;
+
+ private String classifier;
+
+ private Artifact artifact;
+
+ private List<ArtifactRepository> remoteRepositories;
+
+ private final String originalMessage;
+
+ private final String path;
+
+ static final String LS = System.getProperty( "line.separator" );
+
+ @SuppressWarnings( "checkstyle:parameternumber" )
+ protected AbstractArtifactResolutionException( String message,
+ String groupId,
+ String artifactId,
+ String version,
+ String type,
+ String classifier,
+ List<ArtifactRepository> remoteRepositories,
+ List<String> path )
+ {
+ this( message, groupId, artifactId, version, type, classifier, remoteRepositories, path, null );
+ }
+
+ @SuppressWarnings( "checkstyle:parameternumber" )
+ protected AbstractArtifactResolutionException( String message,
+ String groupId,
+ String artifactId,
+ String version,
+ String type,
+ String classifier,
+ List<ArtifactRepository> remoteRepositories,
+ List<String> path,
+ Throwable t )
+ {
+ super( constructMessageBase( message, groupId, artifactId, version, type, remoteRepositories, path ), t );
+
+ this.originalMessage = message;
+ this.groupId = groupId;
+ this.artifactId = artifactId;
+ this.type = type;
+ this.classifier = classifier;
+ this.version = version;
+ this.remoteRepositories = remoteRepositories;
+ this.path = constructArtifactPath( path, "" );
+ }
+
+ protected AbstractArtifactResolutionException( String message,
+ Artifact artifact )
+ {
+ this( message, artifact, null );
+ }
+
+ protected AbstractArtifactResolutionException( String message,
+ Artifact artifact,
+ List<ArtifactRepository> remoteRepositories )
+ {
+ this( message, artifact, remoteRepositories, null );
+ }
+
+ protected AbstractArtifactResolutionException( String message,
+ Artifact artifact,
+ List<ArtifactRepository> remoteRepositories,
+ Throwable t )
+ {
+ this( message, artifact.getGroupId(), artifact.getArtifactId(), artifact.getVersion(), artifact.getType(),
+ artifact.getClassifier(), remoteRepositories, artifact.getDependencyTrail(), t );
+ this.artifact = artifact;
+ }
+
+ public Artifact getArtifact()
+ {
+ return artifact;
+ }
+
+ public String getGroupId()
+ {
+ return groupId;
+ }
+
+ public String getArtifactId()
+ {
+ return artifactId;
+ }
+
+ public String getVersion()
+ {
+ return version;
+ }
+
+ public String getType()
+ {
+ return type;
+ }
+
+ /** @return the classifier */
+ public String getClassifier()
+ {
+ return this.classifier;
+ }
+
+ /** @return the path */
+ public String getPath()
+ {
+ return this.path;
+ }
+
+ public List<ArtifactRepository> getRemoteRepositories()
+ {
+ return remoteRepositories;
+ }
+
+ public String getOriginalMessage()
+ {
+ return originalMessage;
+ }
+
+ protected static String constructArtifactPath( List<String> path,
+ String indentation )
+ {
+ StringBuilder sb = new StringBuilder();
+
+ if ( path != null )
+ {
+ sb.append( LS );
+ sb.append( indentation );
+ sb.append( "Path to dependency: " );
+ sb.append( LS );
+ int num = 1;
+ for ( Iterator<String> i = path.iterator(); i.hasNext(); num++ )
+ {
+ sb.append( indentation );
+ sb.append( "\t" );
+ sb.append( num );
+ sb.append( ") " );
+ sb.append( i.next() );
+ sb.append( LS );
+ }
+ }
+
+ return sb.toString();
+ }
+
+ private static String constructMessageBase( String message,
+ String groupId,
+ String artifactId,
+ String version,
+ String type,
+ List<ArtifactRepository> remoteRepositories,
+ List<String> path )
+ {
+ StringBuilder sb = new StringBuilder();
+
+ sb.append( message );
+
+ if ( message == null || !message.contains( "from the specified remote repositories:" ) )
+ {
+ sb.append( LS );
+ sb.append( " " ).append( groupId ).append( ":" ).append( artifactId ).append( ":" ).append( type ).append(
+ ":" ).append( version );
+ sb.append( LS );
+ if ( remoteRepositories != null )
+ {
+ sb.append( LS );
+ sb.append( "from the specified remote repositories:" );
+ sb.append( LS ).append( " " );
+
+ if ( remoteRepositories.isEmpty() )
+ {
+ sb.append( "(none)" );
+ }
+
+ for ( Iterator<ArtifactRepository> i = remoteRepositories.iterator(); i.hasNext(); )
+ {
+ ArtifactRepository remoteRepository = i.next();
+
+ sb.append( remoteRepository.getId() );
+ sb.append( " (" );
+ sb.append( remoteRepository.getUrl() );
+
+ ArtifactRepositoryPolicy releases = remoteRepository.getReleases();
+ if ( releases != null )
+ {
+ sb.append( ", releases=" ).append( releases.isEnabled() );
+ }
+
+ ArtifactRepositoryPolicy snapshots = remoteRepository.getSnapshots();
+ if ( snapshots != null )
+ {
+ sb.append( ", snapshots=" ).append( snapshots.isEnabled() );
+ }
+
+ sb.append( ")" );
+ if ( i.hasNext() )
+ {
+ sb.append( "," ).append( LS ).append( " " );
+ }
+ }
+ }
+
+ sb.append( constructArtifactPath( path, "" ) );
+ sb.append( LS );
+ }
+
+ return sb.toString();
+ }
+
+ @SuppressWarnings( "checkstyle:parameternumber" )
+ protected static String constructMissingArtifactMessage( String message,
+ String indentation,
+ String groupId,
+ String artifactId,
+ String version,
+ String type,
+ String classifier,
+ String downloadUrl,
+ List<String> path )
+ {
+ StringBuilder sb = new StringBuilder( message );
+
+ if ( !"pom".equals( type ) )
+ {
+ if ( downloadUrl != null )
+ {
+ sb.append( LS );
+ sb.append( LS );
+ sb.append( indentation );
+ sb.append( "Try downloading the file manually from: " );
+ sb.append( LS );
+ sb.append( indentation );
+ sb.append( " " );
+ sb.append( downloadUrl );
+ }
+ else
+ {
+ sb.append( LS );
+ sb.append( LS );
+ sb.append( indentation );
+ sb.append( "Try downloading the file manually from the project website." );
+ }
+
+ sb.append( LS );
+ sb.append( LS );
+ sb.append( indentation );
+ sb.append( "Then, install it using the command: " );
+ sb.append( LS );
+ sb.append( indentation );
+ sb.append( " mvn install:install-file -DgroupId=" );
+ sb.append( groupId );
+ sb.append( " -DartifactId=" );
+ sb.append( artifactId );
+ sb.append( " -Dversion=" );
+ sb.append( version );
+
+ //insert classifier only if it was used in the artifact
+ if ( classifier != null && !classifier.equals( "" ) )
+ {
+ sb.append( " -Dclassifier=" );
+ sb.append( classifier );
+ }
+ sb.append( " -Dpackaging=" );
+ sb.append( type );
+ sb.append( " -Dfile=/path/to/file" );
+ sb.append( LS );
+
+ // If people want to deploy it
+ sb.append( LS );
+ sb.append( indentation );
+ sb.append( "Alternatively, if you host your own repository you can deploy the file there: " );
+ sb.append( LS );
+ sb.append( indentation );
+ sb.append( " mvn deploy:deploy-file -DgroupId=" );
+ sb.append( groupId );
+ sb.append( " -DartifactId=" );
+ sb.append( artifactId );
+ sb.append( " -Dversion=" );
+ sb.append( version );
+
+ //insert classifier only if it was used in the artifact
+ if ( classifier != null && !classifier.equals( "" ) )
+ {
+ sb.append( " -Dclassifier=" );
+ sb.append( classifier );
+ }
+ sb.append( " -Dpackaging=" );
+ sb.append( type );
+ sb.append( " -Dfile=/path/to/file" );
+ sb.append( " -Durl=[url] -DrepositoryId=[id]" );
+ sb.append( LS );
+ }
+
+ sb.append( constructArtifactPath( path, indentation ) );
+ sb.append( LS );
+
+ return sb.toString();
+ }
+
+ public String getArtifactPath()
+ {
+ return path;
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/resolver/ArtifactNotFoundException.java b/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/resolver/ArtifactNotFoundException.java
new file mode 100644
index 00000000..76f7b584
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/resolver/ArtifactNotFoundException.java
@@ -0,0 +1,85 @@
+package org.apache.maven.artifact.resolver;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+
+import java.util.List;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+
+/**
+ * @author Jason van Zyl
+ */
+public class ArtifactNotFoundException
+ extends AbstractArtifactResolutionException
+{
+ private String downloadUrl;
+
+ protected ArtifactNotFoundException( String message, Artifact artifact,
+ List<ArtifactRepository> remoteRepositories )
+ {
+ super( message, artifact, remoteRepositories );
+ }
+
+ public ArtifactNotFoundException( String message, Artifact artifact )
+ {
+ this( message, artifact.getGroupId(), artifact.getArtifactId(), artifact.getVersion(), artifact.getType(),
+ artifact.getClassifier(), null, artifact.getDownloadUrl(), artifact.getDependencyTrail() );
+ }
+
+ protected ArtifactNotFoundException( String message, Artifact artifact,
+ List<ArtifactRepository> remoteRepositories, Throwable cause )
+ {
+ this( message, artifact.getGroupId(), artifact.getArtifactId(), artifact.getVersion(), artifact.getType(),
+ artifact.getClassifier(), remoteRepositories, artifact.getDownloadUrl(), artifact.getDependencyTrail(),
+ cause );
+ }
+
+ @SuppressWarnings( "checkstyle:parameternumber" )
+ public ArtifactNotFoundException( String message, String groupId, String artifactId, String version, String type,
+ String classifier, List<ArtifactRepository> remoteRepositories,
+ String downloadUrl, List<String> path, Throwable cause )
+ {
+ super( constructMissingArtifactMessage( message, "", groupId, artifactId, version, type, classifier,
+ downloadUrl, path ), groupId, artifactId, version, type, classifier,
+ remoteRepositories, null, cause );
+
+ this.downloadUrl = downloadUrl;
+ }
+
+ @SuppressWarnings( "checkstyle:parameternumber" )
+ private ArtifactNotFoundException( String message, String groupId, String artifactId, String version, String type,
+ String classifier, List<ArtifactRepository> remoteRepositories,
+ String downloadUrl, List<String> path )
+ {
+ super( constructMissingArtifactMessage( message, "", groupId, artifactId, version, type, classifier,
+ downloadUrl, path ), groupId, artifactId, version, type, classifier,
+ remoteRepositories, null );
+
+ this.downloadUrl = downloadUrl;
+ }
+
+ public String getDownloadUrl()
+ {
+ return downloadUrl;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/resolver/ArtifactResolutionException.java b/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/resolver/ArtifactResolutionException.java
new file mode 100644
index 00000000..074d812c
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/resolver/ArtifactResolutionException.java
@@ -0,0 +1,68 @@
+package org.apache.maven.artifact.resolver;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.List;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+
+/**
+ * @author Jason van Zyl
+ */
+public class ArtifactResolutionException
+ extends AbstractArtifactResolutionException
+{
+ @SuppressWarnings( "checkstyle:parameternumber" )
+ public ArtifactResolutionException( String message, String groupId, String artifactId, String version, String type,
+ String classifier, List<ArtifactRepository> remoteRepositories,
+ List<String> path, Throwable t )
+ {
+ super( message, groupId, artifactId, version, type, classifier, remoteRepositories, path, t );
+ }
+
+ public ArtifactResolutionException( String message, String groupId, String artifactId, String version, String type,
+ String classifier, Throwable t )
+ {
+ super( message, groupId, artifactId, version, type, classifier, null, null, t );
+ }
+
+ public ArtifactResolutionException( String message, Artifact artifact )
+ {
+ super( message, artifact );
+ }
+
+ public ArtifactResolutionException( String message, Artifact artifact, List<ArtifactRepository> remoteRepositories )
+ {
+ super( message, artifact, remoteRepositories );
+ }
+
+ public ArtifactResolutionException( String message, Artifact artifact, Throwable cause )
+ {
+ super( message, artifact, null, cause );
+ }
+
+ public ArtifactResolutionException( String message, Artifact artifact, List<ArtifactRepository> remoteRepositories,
+ Throwable cause )
+ {
+ super( message, artifact, remoteRepositories, cause );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/resolver/CyclicDependencyException.java b/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/resolver/CyclicDependencyException.java
new file mode 100644
index 00000000..d3706179
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/resolver/CyclicDependencyException.java
@@ -0,0 +1,45 @@
+package org.apache.maven.artifact.resolver;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.artifact.Artifact;
+
+/**
+ * Indiciates a cycle in the dependency graph.
+ *
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ */
+public class CyclicDependencyException
+ extends ArtifactResolutionException
+{
+ private Artifact artifact;
+
+ public CyclicDependencyException( String message,
+ Artifact artifact )
+ {
+ super( message, artifact );
+ this.artifact = artifact;
+ }
+
+ public Artifact getArtifact()
+ {
+ return artifact;
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/resolver/MultipleArtifactsNotFoundException.java b/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/resolver/MultipleArtifactsNotFoundException.java
new file mode 100644
index 00000000..0f13db15
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/resolver/MultipleArtifactsNotFoundException.java
@@ -0,0 +1,122 @@
+package org.apache.maven.artifact.resolver;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+
+/**
+ * Exception caused when one or more artifacts can not be resolved because they are not found in the
+ * local or remote repositories.
+ */
+public class MultipleArtifactsNotFoundException
+ extends ArtifactResolutionException
+{
+ private final List<Artifact> resolvedArtifacts;
+ private final List<Artifact> missingArtifacts;
+
+ /** @deprecated use {@link #MultipleArtifactsNotFoundException(Artifact, List, List, List)} */
+ @Deprecated
+ public MultipleArtifactsNotFoundException( Artifact originatingArtifact,
+ List<Artifact> missingArtifacts,
+ List<ArtifactRepository> remoteRepositories )
+ {
+ this( originatingArtifact, new ArrayList<Artifact>(), missingArtifacts, remoteRepositories );
+ }
+
+ /**
+ * Create an instance of the exception with allrequired information.
+ *
+ * @param originatingArtifact the artifact that was being resolved
+ * @param resolvedArtifacts artifacts that could be resolved
+ * @param missingArtifacts artifacts that could not be resolved
+ * @param remoteRepositories remote repositories where the missing artifacts were not found
+ */
+ public MultipleArtifactsNotFoundException( Artifact originatingArtifact,
+ List<Artifact> resolvedArtifacts,
+ List<Artifact> missingArtifacts,
+ List<ArtifactRepository> remoteRepositories )
+ {
+ super( constructMessage( missingArtifacts ), originatingArtifact, remoteRepositories );
+ this.resolvedArtifacts = resolvedArtifacts;
+ this.missingArtifacts = missingArtifacts;
+ }
+
+ /**
+ * artifacts that could be resolved
+ *
+ * @return {@link List} of {@link Artifact}
+ */
+ public List<Artifact> getResolvedArtifacts()
+ {
+ return resolvedArtifacts;
+ }
+
+ /**
+ * artifacts that could NOT be resolved
+ *
+ * @return {@link List} of {@link Artifact}
+ */
+ public List<Artifact> getMissingArtifacts()
+ {
+ return missingArtifacts;
+ }
+
+ private static String constructMessage( List<Artifact> artifacts )
+ {
+ StringBuilder buffer = new StringBuilder( "Missing:\n" );
+
+ buffer.append( "----------\n" );
+
+ int counter = 0;
+
+ for ( Artifact artifact : artifacts )
+ {
+ String message = ( ++counter ) + ") " + artifact.getId();
+
+ buffer.append( constructMissingArtifactMessage( message, " ", artifact.getGroupId(),
+ artifact.getArtifactId(), artifact.getVersion(), artifact.getType(), artifact.getClassifier(),
+ artifact.getDownloadUrl(), artifact.getDependencyTrail() ) );
+ }
+
+ buffer.append( "----------\n" );
+
+ int size = artifacts.size();
+
+ buffer.append( size ).append( " required artifact" );
+
+ if ( size > 1 )
+ {
+ buffer.append( "s are" );
+ }
+ else
+ {
+ buffer.append( " is" );
+ }
+
+ buffer.append( " missing.\n\nfor artifact: " );
+
+ return buffer.toString();
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/resolver/filter/ArtifactFilter.java b/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/resolver/filter/ArtifactFilter.java
new file mode 100644
index 00000000..27b08a88
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/resolver/filter/ArtifactFilter.java
@@ -0,0 +1,30 @@
+package org.apache.maven.artifact.resolver.filter;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.artifact.Artifact;
+
+/**
+ * @author <a href="mailto:jason@maven.org">Jason van Zyl</a>
+ */
+public interface ArtifactFilter
+{
+ boolean include( Artifact artifact );
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/versioning/ArtifactVersion.java b/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/versioning/ArtifactVersion.java
new file mode 100644
index 00000000..5b516a91
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/versioning/ArtifactVersion.java
@@ -0,0 +1,42 @@
+package org.apache.maven.artifact.versioning;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Describes an artifact version in terms of its components, converts it to/from a string and
+ * compares two versions.
+ *
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ */
+public interface ArtifactVersion
+ extends Comparable<ArtifactVersion>
+{
+ int getMajorVersion();
+
+ int getMinorVersion();
+
+ int getIncrementalVersion();
+
+ int getBuildNumber();
+
+ String getQualifier();
+
+ void parseVersion( String version );
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/versioning/ComparableVersion.java b/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/versioning/ComparableVersion.java
new file mode 100644
index 00000000..67a46960
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/versioning/ComparableVersion.java
@@ -0,0 +1,503 @@
+package org.apache.maven.artifact.versioning;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+import java.util.Properties;
+import java.util.Stack;
+
+/**
+ * Generic implementation of version comparison.
+ *
+ * <p>Features:
+ * <ul>
+ * <li>mixing of '<code>-</code>' (dash) and '<code>.</code>' (dot) separators,</li>
+ * <li>transition between characters and digits also constitutes a separator:
+ * <code>1.0alpha1 =&gt; [1, 0, alpha, 1]</code></li>
+ * <li>unlimited number of version components,</li>
+ * <li>version components in the text can be digits or strings,</li>
+ * <li>strings are checked for well-known qualifiers and the qualifier ordering is used for version ordering.
+ * Well-known qualifiers (case insensitive) are:<ul>
+ * <li><code>alpha</code> or <code>a</code></li>
+ * <li><code>beta</code> or <code>b</code></li>
+ * <li><code>milestone</code> or <code>m</code></li>
+ * <li><code>rc</code> or <code>cr</code></li>
+ * <li><code>snapshot</code></li>
+ * <li><code>(the empty string)</code> or <code>ga</code> or <code>final</code></li>
+ * <li><code>sp</code></li>
+ * </ul>
+ * Unknown qualifiers are considered after known qualifiers, with lexical order (always case insensitive),
+ * </li>
+ * <li>a dash usually precedes a qualifier, and is always less important than something preceded with a dot.</li>
+ * </ul></p>
+ *
+ * @see <a href="https://cwiki.apache.org/confluence/display/MAVENOLD/Versioning">"Versioning" on Maven Wiki</a>
+ * @author <a href="mailto:kenney@apache.org">Kenney Westerhof</a>
+ * @author <a href="mailto:hboutemy@apache.org">Hervé Boutemy</a>
+ */
+public class ComparableVersion
+ implements Comparable<ComparableVersion>
+{
+ private String value;
+
+ private String canonical;
+
+ private ListItem items;
+
+ private interface Item
+ {
+ int INTEGER_ITEM = 0;
+ int STRING_ITEM = 1;
+ int LIST_ITEM = 2;
+
+ int compareTo( Item item );
+
+ int getType();
+
+ boolean isNull();
+ }
+
+ /**
+ * Represents a numeric item in the version item list.
+ */
+ private static class IntegerItem
+ implements Item
+ {
+ private static final BigInteger BIG_INTEGER_ZERO = new BigInteger( "0" );
+
+ private final BigInteger value;
+
+ public static final IntegerItem ZERO = new IntegerItem();
+
+ private IntegerItem()
+ {
+ this.value = BIG_INTEGER_ZERO;
+ }
+
+ public IntegerItem( String str )
+ {
+ this.value = new BigInteger( str );
+ }
+
+ public int getType()
+ {
+ return INTEGER_ITEM;
+ }
+
+ public boolean isNull()
+ {
+ return BIG_INTEGER_ZERO.equals( value );
+ }
+
+ public int compareTo( Item item )
+ {
+ if ( item == null )
+ {
+ return BIG_INTEGER_ZERO.equals( value ) ? 0 : 1; // 1.0 == 1, 1.1 > 1
+ }
+
+ switch ( item.getType() )
+ {
+ case INTEGER_ITEM:
+ return value.compareTo( ( (IntegerItem) item ).value );
+
+ case STRING_ITEM:
+ return 1; // 1.1 > 1-sp
+
+ case LIST_ITEM:
+ return 1; // 1.1 > 1-1
+
+ default:
+ throw new RuntimeException( "invalid item: " + item.getClass() );
+ }
+ }
+
+ public String toString()
+ {
+ return value.toString();
+ }
+ }
+
+ /**
+ * Represents a string in the version item list, usually a qualifier.
+ */
+ private static class StringItem
+ implements Item
+ {
+ private static final String[] QUALIFIERS = { "alpha", "beta", "milestone", "rc", "snapshot", "", "sp" };
+
+ @SuppressWarnings( "checkstyle:constantname" )
+ private static final List<String> _QUALIFIERS = Arrays.asList( QUALIFIERS );
+
+ private static final Properties ALIASES = new Properties();
+ static
+ {
+ ALIASES.put( "ga", "" );
+ ALIASES.put( "final", "" );
+ ALIASES.put( "cr", "rc" );
+ }
+
+ /**
+ * A comparable value for the empty-string qualifier. This one is used to determine if a given qualifier makes
+ * the version older than one without a qualifier, or more recent.
+ */
+ private static final String RELEASE_VERSION_INDEX = String.valueOf( _QUALIFIERS.indexOf( "" ) );
+
+ private String value;
+
+ public StringItem( String value, boolean followedByDigit )
+ {
+ if ( followedByDigit && value.length() == 1 )
+ {
+ // a1 = alpha-1, b1 = beta-1, m1 = milestone-1
+ switch ( value.charAt( 0 ) )
+ {
+ case 'a':
+ value = "alpha";
+ break;
+ case 'b':
+ value = "beta";
+ break;
+ case 'm':
+ value = "milestone";
+ break;
+ default:
+ }
+ }
+ this.value = ALIASES.getProperty( value , value );
+ }
+
+ public int getType()
+ {
+ return STRING_ITEM;
+ }
+
+ public boolean isNull()
+ {
+ return ( comparableQualifier( value ).compareTo( RELEASE_VERSION_INDEX ) == 0 );
+ }
+
+ /**
+ * Returns a comparable value for a qualifier.
+ *
+ * This method takes into account the ordering of known qualifiers then unknown qualifiers with lexical
+ * ordering.
+ *
+ * just returning an Integer with the index here is faster, but requires a lot of if/then/else to check for -1
+ * or QUALIFIERS.size and then resort to lexical ordering. Most comparisons are decided by the first character,
+ * so this is still fast. If more characters are needed then it requires a lexical sort anyway.
+ *
+ * @param qualifier
+ * @return an equivalent value that can be used with lexical comparison
+ */
+ public static String comparableQualifier( String qualifier )
+ {
+ int i = _QUALIFIERS.indexOf( qualifier );
+
+ return i == -1 ? ( _QUALIFIERS.size() + "-" + qualifier ) : String.valueOf( i );
+ }
+
+ public int compareTo( Item item )
+ {
+ if ( item == null )
+ {
+ // 1-rc < 1, 1-ga > 1
+ return comparableQualifier( value ).compareTo( RELEASE_VERSION_INDEX );
+ }
+ switch ( item.getType() )
+ {
+ case INTEGER_ITEM:
+ return -1; // 1.any < 1.1 ?
+
+ case STRING_ITEM:
+ return comparableQualifier( value ).compareTo( comparableQualifier( ( (StringItem) item ).value ) );
+
+ case LIST_ITEM:
+ return -1; // 1.any < 1-1
+
+ default:
+ throw new RuntimeException( "invalid item: " + item.getClass() );
+ }
+ }
+
+ public String toString()
+ {
+ return value;
+ }
+ }
+
+ /**
+ * Represents a version list item. This class is used both for the global item list and for sub-lists (which start
+ * with '-(number)' in the version specification).
+ */
+ private static class ListItem
+ extends ArrayList<Item>
+ implements Item
+ {
+ public int getType()
+ {
+ return LIST_ITEM;
+ }
+
+ public boolean isNull()
+ {
+ return ( size() == 0 );
+ }
+
+ void normalize()
+ {
+ for ( int i = size() - 1; i >= 0; i-- )
+ {
+ Item lastItem = get( i );
+
+ if ( lastItem.isNull() )
+ {
+ // remove null trailing items: 0, "", empty list
+ remove( i );
+ }
+ else if ( !( lastItem instanceof ListItem ) )
+ {
+ break;
+ }
+ }
+ }
+
+ public int compareTo( Item item )
+ {
+ if ( item == null )
+ {
+ if ( size() == 0 )
+ {
+ return 0; // 1-0 = 1- (normalize) = 1
+ }
+ Item first = get( 0 );
+ return first.compareTo( null );
+ }
+ switch ( item.getType() )
+ {
+ case INTEGER_ITEM:
+ return -1; // 1-1 < 1.0.x
+
+ case STRING_ITEM:
+ return 1; // 1-1 > 1-sp
+
+ case LIST_ITEM:
+ Iterator<Item> left = iterator();
+ Iterator<Item> right = ( (ListItem) item ).iterator();
+
+ while ( left.hasNext() || right.hasNext() )
+ {
+ Item l = left.hasNext() ? left.next() : null;
+ Item r = right.hasNext() ? right.next() : null;
+
+ // if this is shorter, then invert the compare and mul with -1
+ int result = l == null ? ( r == null ? 0 : -1 * r.compareTo( l ) ) : l.compareTo( r );
+
+ if ( result != 0 )
+ {
+ return result;
+ }
+ }
+
+ return 0;
+
+ default:
+ throw new RuntimeException( "invalid item: " + item.getClass() );
+ }
+ }
+
+ public String toString()
+ {
+ StringBuilder buffer = new StringBuilder();
+ for ( Iterator<Item> iter = iterator(); iter.hasNext(); )
+ {
+ Item item = iter.next();
+ if ( buffer.length() > 0 )
+ {
+ buffer.append( ( item instanceof ListItem ) ? '-' : '.' );
+ }
+ buffer.append( item );
+ }
+ return buffer.toString();
+ }
+ }
+
+ public ComparableVersion( String version )
+ {
+ parseVersion( version );
+ }
+
+ public final void parseVersion( String version )
+ {
+ this.value = version;
+
+ items = new ListItem();
+
+ version = version.toLowerCase( Locale.ENGLISH );
+
+ ListItem list = items;
+
+ Stack<Item> stack = new Stack<Item>();
+ stack.push( list );
+
+ boolean isDigit = false;
+
+ int startIndex = 0;
+
+ for ( int i = 0; i < version.length(); i++ )
+ {
+ char c = version.charAt( i );
+
+ if ( c == '.' )
+ {
+ if ( i == startIndex )
+ {
+ list.add( IntegerItem.ZERO );
+ }
+ else
+ {
+ list.add( parseItem( isDigit, version.substring( startIndex, i ) ) );
+ }
+ startIndex = i + 1;
+ }
+ else if ( c == '-' )
+ {
+ if ( i == startIndex )
+ {
+ list.add( IntegerItem.ZERO );
+ }
+ else
+ {
+ list.add( parseItem( isDigit, version.substring( startIndex, i ) ) );
+ }
+ startIndex = i + 1;
+
+ list.add( list = new ListItem() );
+ stack.push( list );
+ }
+ else if ( Character.isDigit( c ) )
+ {
+ if ( !isDigit && i > startIndex )
+ {
+ list.add( new StringItem( version.substring( startIndex, i ), true ) );
+ startIndex = i;
+
+ list.add( list = new ListItem() );
+ stack.push( list );
+ }
+
+ isDigit = true;
+ }
+ else
+ {
+ if ( isDigit && i > startIndex )
+ {
+ list.add( parseItem( true, version.substring( startIndex, i ) ) );
+ startIndex = i;
+
+ list.add( list = new ListItem() );
+ stack.push( list );
+ }
+
+ isDigit = false;
+ }
+ }
+
+ if ( version.length() > startIndex )
+ {
+ list.add( parseItem( isDigit, version.substring( startIndex ) ) );
+ }
+
+ while ( !stack.isEmpty() )
+ {
+ list = (ListItem) stack.pop();
+ list.normalize();
+ }
+
+ canonical = items.toString();
+ }
+
+ private static Item parseItem( boolean isDigit, String buf )
+ {
+ return isDigit ? new IntegerItem( buf ) : new StringItem( buf, false );
+ }
+
+ public int compareTo( ComparableVersion o )
+ {
+ return items.compareTo( o.items );
+ }
+
+ public String toString()
+ {
+ return value;
+ }
+
+ public String getCanonical()
+ {
+ return canonical;
+ }
+
+ public boolean equals( Object o )
+ {
+ return ( o instanceof ComparableVersion ) && canonical.equals( ( (ComparableVersion) o ).canonical );
+ }
+
+ public int hashCode()
+ {
+ return canonical.hashCode();
+ }
+
+ /**
+ * Main to test version parsing and comparison.
+ *
+ * @param args the version strings to parse and compare
+ */
+ public static void main( String... args )
+ {
+ System.out.println( "Display parameters as parsed by Maven (in canonical form) and comparison result:" );
+ if ( args.length == 0 )
+ {
+ return;
+ }
+
+ ComparableVersion prev = null;
+ int i = 1;
+ for ( String version : args )
+ {
+ ComparableVersion c = new ComparableVersion( version );
+
+ if ( prev != null )
+ {
+ int compare = prev.compareTo( c );
+ System.out.println( " " + prev.toString() + ' '
+ + ( ( compare == 0 ) ? "==" : ( ( compare < 0 ) ? "<" : ">" ) ) + ' ' + version );
+ }
+
+ System.out.println( String.valueOf( i++ ) + ". " + version + " == " + c.getCanonical() );
+
+ prev = c;
+ }
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/versioning/DefaultArtifactVersion.java b/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/versioning/DefaultArtifactVersion.java
new file mode 100644
index 00000000..99b2b85b
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/versioning/DefaultArtifactVersion.java
@@ -0,0 +1,228 @@
+package org.apache.maven.artifact.versioning;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.StringTokenizer;
+import java.util.regex.Pattern;
+import java.util.NoSuchElementException;
+
+/**
+ * Default implementation of artifact versioning.
+ *
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ */
+public class DefaultArtifactVersion
+ implements ArtifactVersion
+{
+ private Integer majorVersion;
+
+ private Integer minorVersion;
+
+ private Integer incrementalVersion;
+
+ private Integer buildNumber;
+
+ private String qualifier;
+
+ private ComparableVersion comparable;
+
+ public DefaultArtifactVersion( String version )
+ {
+ parseVersion( version );
+ }
+
+ @Override
+ public int hashCode()
+ {
+ return 11 + comparable.hashCode();
+ }
+
+ @Override
+ public boolean equals( Object other )
+ {
+ if ( this == other )
+ {
+ return true;
+ }
+
+ if ( !( other instanceof ArtifactVersion ) )
+ {
+ return false;
+ }
+
+ return compareTo( (ArtifactVersion) other ) == 0;
+ }
+
+ public int compareTo( ArtifactVersion otherVersion )
+ {
+ if ( otherVersion instanceof DefaultArtifactVersion )
+ {
+ return this.comparable.compareTo( ( (DefaultArtifactVersion) otherVersion ).comparable );
+ }
+ else
+ {
+ return compareTo( new DefaultArtifactVersion( otherVersion.toString() ) );
+ }
+ }
+
+ public int getMajorVersion()
+ {
+ return majorVersion != null ? majorVersion : 0;
+ }
+
+ public int getMinorVersion()
+ {
+ return minorVersion != null ? minorVersion : 0;
+ }
+
+ public int getIncrementalVersion()
+ {
+ return incrementalVersion != null ? incrementalVersion : 0;
+ }
+
+ public int getBuildNumber()
+ {
+ return buildNumber != null ? buildNumber : 0;
+ }
+
+ public String getQualifier()
+ {
+ return qualifier;
+ }
+
+ public final void parseVersion( String version )
+ {
+ comparable = new ComparableVersion( version );
+
+ int index = version.indexOf( "-" );
+
+ String part1;
+ String part2 = null;
+
+ if ( index < 0 )
+ {
+ part1 = version;
+ }
+ else
+ {
+ part1 = version.substring( 0, index );
+ part2 = version.substring( index + 1 );
+ }
+
+ if ( part2 != null )
+ {
+ try
+ {
+ if ( ( part2.length() == 1 ) || !part2.startsWith( "0" ) )
+ {
+ buildNumber = Integer.valueOf( part2 );
+ }
+ else
+ {
+ qualifier = part2;
+ }
+ }
+ catch ( NumberFormatException e )
+ {
+ qualifier = part2;
+ }
+ }
+
+ if ( ( !part1.contains( "." ) ) && !part1.startsWith( "0" ) )
+ {
+ try
+ {
+ majorVersion = Integer.valueOf( part1 );
+ }
+ catch ( NumberFormatException e )
+ {
+ // qualifier is the whole version, including "-"
+ qualifier = version;
+ buildNumber = null;
+ }
+ }
+ else
+ {
+ boolean fallback = false;
+
+ StringTokenizer tok = new StringTokenizer( part1, "." );
+ try
+ {
+ majorVersion = getNextIntegerToken( tok );
+ if ( tok.hasMoreTokens() )
+ {
+ minorVersion = getNextIntegerToken( tok );
+ }
+ if ( tok.hasMoreTokens() )
+ {
+ incrementalVersion = getNextIntegerToken( tok );
+ }
+ if ( tok.hasMoreTokens() )
+ {
+ qualifier = tok.nextToken();
+ fallback = Pattern.compile( "\\d+" ).matcher( qualifier ).matches();
+ }
+
+ // string tokenzier won't detect these and ignores them
+ if ( part1.contains( ".." ) || part1.startsWith( "." ) || part1.endsWith( "." ) )
+ {
+ fallback = true;
+ }
+ }
+ catch ( NumberFormatException e )
+ {
+ fallback = true;
+ }
+
+ if ( fallback )
+ {
+ // qualifier is the whole version, including "-"
+ qualifier = version;
+ majorVersion = null;
+ minorVersion = null;
+ incrementalVersion = null;
+ buildNumber = null;
+ }
+ }
+ }
+
+ private static Integer getNextIntegerToken( StringTokenizer tok )
+ {
+ try
+ {
+ String s = tok.nextToken();
+ if ( ( s.length() > 1 ) && s.startsWith( "0" ) )
+ {
+ throw new NumberFormatException( "Number part has a leading 0: '" + s + "'" );
+ }
+ return Integer.valueOf( s );
+ }
+ catch ( NoSuchElementException e )
+ {
+ throw new NumberFormatException( "Number is invalid" );
+ }
+ }
+
+ @Override
+ public String toString()
+ {
+ return comparable.toString();
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/versioning/InvalidVersionSpecificationException.java b/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/versioning/InvalidVersionSpecificationException.java
new file mode 100644
index 00000000..adc48b93
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/versioning/InvalidVersionSpecificationException.java
@@ -0,0 +1,34 @@
+package org.apache.maven.artifact.versioning;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Occurs when a version is invalid.
+ *
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ */
+public class InvalidVersionSpecificationException
+ extends Exception
+{
+ public InvalidVersionSpecificationException( String message )
+ {
+ super( message );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/versioning/OverConstrainedVersionException.java b/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/versioning/OverConstrainedVersionException.java
new file mode 100644
index 00000000..bd8f3830
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/versioning/OverConstrainedVersionException.java
@@ -0,0 +1,49 @@
+package org.apache.maven.artifact.versioning;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.List;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.resolver.ArtifactResolutionException;
+
+/**
+ * Occurs when ranges exclude each other and no valid value remains.
+ *
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ */
+public class OverConstrainedVersionException
+ extends ArtifactResolutionException
+{
+ public OverConstrainedVersionException( String msg,
+ Artifact artifact )
+ {
+ super( msg, artifact );
+ }
+
+ public OverConstrainedVersionException( String msg,
+ Artifact artifact,
+ List<ArtifactRepository> remoteRepositories )
+ {
+ super( msg, artifact, remoteRepositories );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/versioning/Restriction.java b/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/versioning/Restriction.java
new file mode 100644
index 00000000..d73d7ea5
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/versioning/Restriction.java
@@ -0,0 +1,195 @@
+package org.apache.maven.artifact.versioning;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Describes a restriction in versioning.
+ *
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ */
+public class Restriction
+{
+ private final ArtifactVersion lowerBound;
+
+ private final boolean lowerBoundInclusive;
+
+ private final ArtifactVersion upperBound;
+
+ private final boolean upperBoundInclusive;
+
+ public static final Restriction EVERYTHING = new Restriction( null, false, null, false );
+
+ public Restriction( ArtifactVersion lowerBound, boolean lowerBoundInclusive, ArtifactVersion upperBound,
+ boolean upperBoundInclusive )
+ {
+ this.lowerBound = lowerBound;
+ this.lowerBoundInclusive = lowerBoundInclusive;
+ this.upperBound = upperBound;
+ this.upperBoundInclusive = upperBoundInclusive;
+ }
+
+ public ArtifactVersion getLowerBound()
+ {
+ return lowerBound;
+ }
+
+ public boolean isLowerBoundInclusive()
+ {
+ return lowerBoundInclusive;
+ }
+
+ public ArtifactVersion getUpperBound()
+ {
+ return upperBound;
+ }
+
+ public boolean isUpperBoundInclusive()
+ {
+ return upperBoundInclusive;
+ }
+
+ public boolean containsVersion( ArtifactVersion version )
+ {
+ if ( lowerBound != null )
+ {
+ int comparison = lowerBound.compareTo( version );
+
+ if ( ( comparison == 0 ) && !lowerBoundInclusive )
+ {
+ return false;
+ }
+ if ( comparison > 0 )
+ {
+ return false;
+ }
+ }
+ if ( upperBound != null )
+ {
+ int comparison = upperBound.compareTo( version );
+
+ if ( ( comparison == 0 ) && !upperBoundInclusive )
+ {
+ return false;
+ }
+ if ( comparison < 0 )
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ @Override
+ public int hashCode()
+ {
+ int result = 13;
+
+ if ( lowerBound == null )
+ {
+ result += 1;
+ }
+ else
+ {
+ result += lowerBound.hashCode();
+ }
+
+ result *= lowerBoundInclusive ? 1 : 2;
+
+ if ( upperBound == null )
+ {
+ result -= 3;
+ }
+ else
+ {
+ result -= upperBound.hashCode();
+ }
+
+ result *= upperBoundInclusive ? 2 : 3;
+
+ return result;
+ }
+
+ @Override
+ public boolean equals( Object other )
+ {
+ if ( this == other )
+ {
+ return true;
+ }
+
+ if ( !( other instanceof Restriction ) )
+ {
+ return false;
+ }
+
+ Restriction restriction = (Restriction) other;
+ if ( lowerBound != null )
+ {
+ if ( !lowerBound.equals( restriction.lowerBound ) )
+ {
+ return false;
+ }
+ }
+ else if ( restriction.lowerBound != null )
+ {
+ return false;
+ }
+
+ if ( lowerBoundInclusive != restriction.lowerBoundInclusive )
+ {
+ return false;
+ }
+
+ if ( upperBound != null )
+ {
+ if ( !upperBound.equals( restriction.upperBound ) )
+ {
+ return false;
+ }
+ }
+ else if ( restriction.upperBound != null )
+ {
+ return false;
+ }
+
+ return upperBoundInclusive == restriction.upperBoundInclusive;
+
+ }
+
+ public String toString()
+ {
+ StringBuilder buf = new StringBuilder();
+
+ buf.append( isLowerBoundInclusive() ? "[" : "(" );
+ if ( getLowerBound() != null )
+ {
+ buf.append( getLowerBound().toString() );
+ }
+ buf.append( "," );
+ if ( getUpperBound() != null )
+ {
+ buf.append( getUpperBound().toString() );
+ }
+ buf.append( isUpperBoundInclusive() ? "]" : ")" );
+
+ return buf.toString();
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/versioning/VersionRange.java b/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/versioning/VersionRange.java
new file mode 100644
index 00000000..dd8e028c
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/artifact/versioning/VersionRange.java
@@ -0,0 +1,583 @@
+package org.apache.maven.artifact.versioning;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.maven.artifact.Artifact;
+
+/**
+ * Construct a version range from a specification.
+ *
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ */
+public class VersionRange
+{
+ private final ArtifactVersion recommendedVersion;
+
+ private final List<Restriction> restrictions;
+
+ private VersionRange( ArtifactVersion recommendedVersion,
+ List<Restriction> restrictions )
+ {
+ this.recommendedVersion = recommendedVersion;
+ this.restrictions = restrictions;
+ }
+
+ public ArtifactVersion getRecommendedVersion()
+ {
+ return recommendedVersion;
+ }
+
+ public List<Restriction> getRestrictions()
+ {
+ return restrictions;
+ }
+
+ public VersionRange cloneOf()
+ {
+ List<Restriction> copiedRestrictions = null;
+
+ if ( restrictions != null )
+ {
+ copiedRestrictions = new ArrayList<Restriction>();
+
+ if ( !restrictions.isEmpty() )
+ {
+ copiedRestrictions.addAll( restrictions );
+ }
+ }
+
+ return new VersionRange( recommendedVersion, copiedRestrictions );
+ }
+
+ /**
+ * Create a version range from a string representation
+ * <p/>
+ * Some spec examples are
+ * <ul>
+ * <li><code>1.0</code> Version 1.0</li>
+ * <li><code>[1.0,2.0)</code> Versions 1.0 (included) to 2.0 (not included)</li>
+ * <li><code>[1.0,2.0]</code> Versions 1.0 to 2.0 (both included)</li>
+ * <li><code>[1.5,)</code> Versions 1.5 and higher</li>
+ * <li><code>(,1.0],[1.2,)</code> Versions up to 1.0 (included) and 1.2 or higher</li>
+ * </ul>
+ *
+ * @param spec string representation of a version or version range
+ * @return a new {@link VersionRange} object that represents the spec
+ * @throws InvalidVersionSpecificationException
+ *
+ */
+ public static VersionRange createFromVersionSpec( String spec )
+ throws InvalidVersionSpecificationException
+ {
+ if ( spec == null )
+ {
+ return null;
+ }
+
+ List<Restriction> restrictions = new ArrayList<Restriction>();
+ String process = spec;
+ ArtifactVersion version = null;
+ ArtifactVersion upperBound = null;
+ ArtifactVersion lowerBound = null;
+
+ while ( process.startsWith( "[" ) || process.startsWith( "(" ) )
+ {
+ int index1 = process.indexOf( ")" );
+ int index2 = process.indexOf( "]" );
+
+ int index = index2;
+ if ( index2 < 0 || index1 < index2 )
+ {
+ if ( index1 >= 0 )
+ {
+ index = index1;
+ }
+ }
+
+ if ( index < 0 )
+ {
+ throw new InvalidVersionSpecificationException( "Unbounded range: " + spec );
+ }
+
+ Restriction restriction = parseRestriction( process.substring( 0, index + 1 ) );
+ if ( lowerBound == null )
+ {
+ lowerBound = restriction.getLowerBound();
+ }
+ if ( upperBound != null )
+ {
+ if ( restriction.getLowerBound() == null || restriction.getLowerBound().compareTo( upperBound ) < 0 )
+ {
+ throw new InvalidVersionSpecificationException( "Ranges overlap: " + spec );
+ }
+ }
+ restrictions.add( restriction );
+ upperBound = restriction.getUpperBound();
+
+ process = process.substring( index + 1 ).trim();
+
+ if ( process.length() > 0 && process.startsWith( "," ) )
+ {
+ process = process.substring( 1 ).trim();
+ }
+ }
+
+ if ( process.length() > 0 )
+ {
+ if ( restrictions.size() > 0 )
+ {
+ throw new InvalidVersionSpecificationException(
+ "Only fully-qualified sets allowed in multiple set scenario: " + spec );
+ }
+ else
+ {
+ version = new DefaultArtifactVersion( process );
+ restrictions.add( Restriction.EVERYTHING );
+ }
+ }
+
+ return new VersionRange( version, restrictions );
+ }
+
+ private static Restriction parseRestriction( String spec )
+ throws InvalidVersionSpecificationException
+ {
+ boolean lowerBoundInclusive = spec.startsWith( "[" );
+ boolean upperBoundInclusive = spec.endsWith( "]" );
+
+ String process = spec.substring( 1, spec.length() - 1 ).trim();
+
+ Restriction restriction;
+
+ int index = process.indexOf( "," );
+
+ if ( index < 0 )
+ {
+ if ( !lowerBoundInclusive || !upperBoundInclusive )
+ {
+ throw new InvalidVersionSpecificationException( "Single version must be surrounded by []: " + spec );
+ }
+
+ ArtifactVersion version = new DefaultArtifactVersion( process );
+
+ restriction = new Restriction( version, lowerBoundInclusive, version, upperBoundInclusive );
+ }
+ else
+ {
+ String lowerBound = process.substring( 0, index ).trim();
+ String upperBound = process.substring( index + 1 ).trim();
+ if ( lowerBound.equals( upperBound ) )
+ {
+ throw new InvalidVersionSpecificationException( "Range cannot have identical boundaries: " + spec );
+ }
+
+ ArtifactVersion lowerVersion = null;
+ if ( lowerBound.length() > 0 )
+ {
+ lowerVersion = new DefaultArtifactVersion( lowerBound );
+ }
+ ArtifactVersion upperVersion = null;
+ if ( upperBound.length() > 0 )
+ {
+ upperVersion = new DefaultArtifactVersion( upperBound );
+ }
+
+ if ( upperVersion != null && lowerVersion != null && upperVersion.compareTo( lowerVersion ) < 0 )
+ {
+ throw new InvalidVersionSpecificationException( "Range defies version ordering: " + spec );
+ }
+
+ restriction = new Restriction( lowerVersion, lowerBoundInclusive, upperVersion, upperBoundInclusive );
+ }
+
+ return restriction;
+ }
+
+ public static VersionRange createFromVersion( String version )
+ {
+ List<Restriction> restrictions = Collections.emptyList();
+ return new VersionRange( new DefaultArtifactVersion( version ), restrictions );
+ }
+
+ /**
+ * Creates and returns a new <code>VersionRange</code> that is a restriction of this
+ * version range and the specified version range.
+ * <p>
+ * Note: Precedence is given to the recommended version from this version range over the
+ * recommended version from the specified version range.
+ * </p>
+ *
+ * @param restriction the <code>VersionRange</code> that will be used to restrict this version
+ * range.
+ * @return the <code>VersionRange</code> that is a restriction of this version range and the
+ * specified version range.
+ * <p>
+ * The restrictions of the returned version range will be an intersection of the restrictions
+ * of this version range and the specified version range if both version ranges have
+ * restrictions. Otherwise, the restrictions on the returned range will be empty.
+ * </p>
+ * <p>
+ * The recommended version of the returned version range will be the recommended version of
+ * this version range, provided that ranges falls within the intersected restrictions. If
+ * the restrictions are empty, this version range's recommended version is used if it is not
+ * <code>null</code>. If it is <code>null</code>, the specified version range's recommended
+ * version is used (provided it is non-<code>null</code>). If no recommended version can be
+ * obtained, the returned version range's recommended version is set to <code>null</code>.
+ * </p>
+ * @throws NullPointerException if the specified <code>VersionRange</code> is
+ * <code>null</code>.
+ */
+ public VersionRange restrict( VersionRange restriction )
+ {
+ List<Restriction> r1 = this.restrictions;
+ List<Restriction> r2 = restriction.restrictions;
+ List<Restriction> restrictions;
+
+ if ( r1.isEmpty() || r2.isEmpty() )
+ {
+ restrictions = Collections.emptyList();
+ }
+ else
+ {
+ restrictions = intersection( r1, r2 );
+ }
+
+ ArtifactVersion version = null;
+ if ( restrictions.size() > 0 )
+ {
+ for ( Restriction r : restrictions )
+ {
+ if ( recommendedVersion != null && r.containsVersion( recommendedVersion ) )
+ {
+ // if we find the original, use that
+ version = recommendedVersion;
+ break;
+ }
+ else if ( version == null && restriction.getRecommendedVersion() != null
+ && r.containsVersion( restriction.getRecommendedVersion() ) )
+ {
+ // use this if we can, but prefer the original if possible
+ version = restriction.getRecommendedVersion();
+ }
+ }
+ }
+ // Either the original or the specified version ranges have no restrictions
+ else if ( recommendedVersion != null )
+ {
+ // Use the original recommended version since it exists
+ version = recommendedVersion;
+ }
+ else if ( restriction.recommendedVersion != null )
+ {
+ // Use the recommended version from the specified VersionRange since there is no
+ // original recommended version
+ version = restriction.recommendedVersion;
+ }
+/* TODO: should throw this immediately, but need artifact
+ else
+ {
+ throw new OverConstrainedVersionException( "Restricting incompatible version ranges" );
+ }
+*/
+
+ return new VersionRange( version, restrictions );
+ }
+
+ private List<Restriction> intersection( List<Restriction> r1, List<Restriction> r2 )
+ {
+ List<Restriction> restrictions = new ArrayList<Restriction>( r1.size() + r2.size() );
+ Iterator<Restriction> i1 = r1.iterator();
+ Iterator<Restriction> i2 = r2.iterator();
+ Restriction res1 = i1.next();
+ Restriction res2 = i2.next();
+
+ boolean done = false;
+ while ( !done )
+ {
+ if ( res1.getLowerBound() == null || res2.getUpperBound() == null
+ || res1.getLowerBound().compareTo( res2.getUpperBound() ) <= 0 )
+ {
+ if ( res1.getUpperBound() == null || res2.getLowerBound() == null
+ || res1.getUpperBound().compareTo( res2.getLowerBound() ) >= 0 )
+ {
+ ArtifactVersion lower;
+ ArtifactVersion upper;
+ boolean lowerInclusive;
+ boolean upperInclusive;
+
+ // overlaps
+ if ( res1.getLowerBound() == null )
+ {
+ lower = res2.getLowerBound();
+ lowerInclusive = res2.isLowerBoundInclusive();
+ }
+ else if ( res2.getLowerBound() == null )
+ {
+ lower = res1.getLowerBound();
+ lowerInclusive = res1.isLowerBoundInclusive();
+ }
+ else
+ {
+ int comparison = res1.getLowerBound().compareTo( res2.getLowerBound() );
+ if ( comparison < 0 )
+ {
+ lower = res2.getLowerBound();
+ lowerInclusive = res2.isLowerBoundInclusive();
+ }
+ else if ( comparison == 0 )
+ {
+ lower = res1.getLowerBound();
+ lowerInclusive = res1.isLowerBoundInclusive() && res2.isLowerBoundInclusive();
+ }
+ else
+ {
+ lower = res1.getLowerBound();
+ lowerInclusive = res1.isLowerBoundInclusive();
+ }
+ }
+
+ if ( res1.getUpperBound() == null )
+ {
+ upper = res2.getUpperBound();
+ upperInclusive = res2.isUpperBoundInclusive();
+ }
+ else if ( res2.getUpperBound() == null )
+ {
+ upper = res1.getUpperBound();
+ upperInclusive = res1.isUpperBoundInclusive();
+ }
+ else
+ {
+ int comparison = res1.getUpperBound().compareTo( res2.getUpperBound() );
+ if ( comparison < 0 )
+ {
+ upper = res1.getUpperBound();
+ upperInclusive = res1.isUpperBoundInclusive();
+ }
+ else if ( comparison == 0 )
+ {
+ upper = res1.getUpperBound();
+ upperInclusive = res1.isUpperBoundInclusive() && res2.isUpperBoundInclusive();
+ }
+ else
+ {
+ upper = res2.getUpperBound();
+ upperInclusive = res2.isUpperBoundInclusive();
+ }
+ }
+
+ // don't add if they are equal and one is not inclusive
+ if ( lower == null || upper == null || lower.compareTo( upper ) != 0 )
+ {
+ restrictions.add( new Restriction( lower, lowerInclusive, upper, upperInclusive ) );
+ }
+ else if ( lowerInclusive && upperInclusive )
+ {
+ restrictions.add( new Restriction( lower, lowerInclusive, upper, upperInclusive ) );
+ }
+
+ //noinspection ObjectEquality
+ if ( upper == res2.getUpperBound() )
+ {
+ // advance res2
+ if ( i2.hasNext() )
+ {
+ res2 = i2.next();
+ }
+ else
+ {
+ done = true;
+ }
+ }
+ else
+ {
+ // advance res1
+ if ( i1.hasNext() )
+ {
+ res1 = i1.next();
+ }
+ else
+ {
+ done = true;
+ }
+ }
+ }
+ else
+ {
+ // move on to next in r1
+ if ( i1.hasNext() )
+ {
+ res1 = i1.next();
+ }
+ else
+ {
+ done = true;
+ }
+ }
+ }
+ else
+ {
+ // move on to next in r2
+ if ( i2.hasNext() )
+ {
+ res2 = i2.next();
+ }
+ else
+ {
+ done = true;
+ }
+ }
+ }
+
+ return restrictions;
+ }
+
+ public ArtifactVersion getSelectedVersion( Artifact artifact )
+ throws OverConstrainedVersionException
+ {
+ ArtifactVersion version;
+ if ( recommendedVersion != null )
+ {
+ version = recommendedVersion;
+ }
+ else
+ {
+ if ( restrictions.size() == 0 )
+ {
+ throw new OverConstrainedVersionException( "The artifact has no valid ranges", artifact );
+ }
+
+ version = null;
+ }
+ return version;
+ }
+
+ public boolean isSelectedVersionKnown( Artifact artifact )
+ throws OverConstrainedVersionException
+ {
+ boolean value = false;
+ if ( recommendedVersion != null )
+ {
+ value = true;
+ }
+ else
+ {
+ if ( restrictions.size() == 0 )
+ {
+ throw new OverConstrainedVersionException( "The artifact has no valid ranges", artifact );
+ }
+ }
+ return value;
+ }
+
+ public String toString()
+ {
+ if ( recommendedVersion != null )
+ {
+ return recommendedVersion.toString();
+ }
+ else
+ {
+ StringBuilder buf = new StringBuilder();
+ for ( Iterator<Restriction> i = restrictions.iterator(); i.hasNext(); )
+ {
+ Restriction r = i.next();
+
+ buf.append( r.toString() );
+
+ if ( i.hasNext() )
+ {
+ buf.append( ',' );
+ }
+ }
+ return buf.toString();
+ }
+ }
+
+ public ArtifactVersion matchVersion( List<ArtifactVersion> versions )
+ {
+ // TODO: could be more efficient by sorting the list and then moving along the restrictions in order?
+
+ ArtifactVersion matched = null;
+ for ( ArtifactVersion version : versions )
+ {
+ if ( containsVersion( version ) )
+ {
+ // valid - check if it is greater than the currently matched version
+ if ( matched == null || version.compareTo( matched ) > 0 )
+ {
+ matched = version;
+ }
+ }
+ }
+ return matched;
+ }
+
+ public boolean containsVersion( ArtifactVersion version )
+ {
+ for ( Restriction restriction : restrictions )
+ {
+ if ( restriction.containsVersion( version ) )
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public boolean hasRestrictions()
+ {
+ return !restrictions.isEmpty() && recommendedVersion == null;
+ }
+
+ public boolean equals( Object obj )
+ {
+ if ( this == obj )
+ {
+ return true;
+ }
+ if ( !( obj instanceof VersionRange ) )
+ {
+ return false;
+ }
+ VersionRange other = (VersionRange) obj;
+
+ boolean equals =
+ recommendedVersion == other.recommendedVersion
+ || ( ( recommendedVersion != null ) && recommendedVersion.equals( other.recommendedVersion ) );
+ equals &=
+ restrictions == other.restrictions
+ || ( ( restrictions != null ) && restrictions.equals( other.restrictions ) );
+ return equals;
+ }
+
+ public int hashCode()
+ {
+ int hash = 7;
+ hash = 31 * hash + ( recommendedVersion == null ? 0 : recommendedVersion.hashCode() );
+ hash = 31 * hash + ( restrictions == null ? 0 : restrictions.hashCode() );
+ return hash;
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/repository/Proxy.java b/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/repository/Proxy.java
new file mode 100644
index 00000000..ea2c0238
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/repository/Proxy.java
@@ -0,0 +1,197 @@
+package org.apache.maven.repository;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+public class Proxy
+{
+ public static final String PROXY_SOCKS5 = "SOCKS_5";
+
+ public static final String PROXY_SOCKS4 = "SOCKS4";
+
+ public static final String PROXY_HTTP = "HTTP";
+
+ /**
+ * Proxy server host
+ */
+ private String host;
+
+ /**
+ * Username used to access the proxy server
+ */
+ private String userName;
+
+ /**
+ * Password associated with the proxy server
+ */
+ private String password;
+
+ /**
+ * Proxy server port
+ */
+ private int port;
+
+ /**
+ * Type of the proxy
+ */
+ private String protocol;
+
+ /**
+ * The non-proxy hosts. Follows Java system property format: <code>*.foo.com|localhost</code>.
+ */
+ private String nonProxyHosts;
+
+ /**
+ * For NTLM proxies, specifies the NTLM host.
+ */
+ private String ntlmHost;
+
+ /**
+ * For NTLM proxies, specifies the NTLM domain.
+ */
+ private String ntlmDomain;
+
+ /**
+ * Return proxy server host name.
+ *
+ * @return proxy server host name
+ */
+ public String getHost()
+ {
+ return host;
+ }
+
+ /**
+ * Set proxy host name.
+ *
+ * @param host proxy server host name
+ */
+ public void setHost( String host )
+ {
+ this.host = host;
+ }
+
+ /**
+ * Get user's password used to login to proxy server.
+ *
+ * @return user's password at proxy host
+ */
+ public String getPassword()
+ {
+ return password;
+ }
+
+ /**
+ * Set the user's password for the proxy server.
+ *
+ * @param password password to use to login to a proxy server
+ */
+ public void setPassword( String password )
+ {
+ this.password = password;
+ }
+
+ /**
+ * Get the proxy port.
+ *
+ * @return proxy server port
+ */
+ public int getPort()
+ {
+ return port;
+ }
+
+ /**
+ * Set the proxy port.
+ *
+ * @param port proxy server port
+ */
+ public void setPort( int port )
+ {
+ this.port = port;
+ }
+
+ /**
+ * Get the proxy username.
+ *
+ * @return username for the proxy server
+ */
+ public String getUserName()
+ {
+ return userName;
+ }
+
+ /**
+ * Set the proxy username.
+ *
+ * @param userName username for the proxy server
+ */
+ public void setUserName( String userName )
+ {
+ this.userName = userName;
+ }
+
+ /**
+ * Get the type of the proxy server.
+ *
+ * @return the type of the proxy server
+ */
+ public String getProtocol()
+ {
+ return protocol;
+ }
+
+ /**
+ * @param type the type of the proxy server like <i>SOCKSv4</i>
+ */
+ public void setProtocol( String protocol )
+ {
+ this.protocol = protocol;
+ }
+
+ public String getNonProxyHosts()
+ {
+ return nonProxyHosts;
+ }
+
+ public void setNonProxyHosts( String nonProxyHosts )
+ {
+ this.nonProxyHosts = nonProxyHosts;
+ }
+
+ public String getNtlmHost()
+ {
+ return ntlmHost;
+ }
+
+ public void setNtlmHost( String ntlmHost )
+ {
+ this.ntlmHost = ntlmHost;
+ }
+
+ public void setNtlmDomain( String ntlmDomain )
+ {
+ this.ntlmDomain = ntlmDomain;
+ }
+
+ public String getNtlmDomain()
+ {
+ return ntlmDomain;
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/repository/legacy/metadata/ArtifactMetadata.java b/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/repository/legacy/metadata/ArtifactMetadata.java
new file mode 100644
index 00000000..e66a84a9
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/main/java/org/apache/maven/repository/legacy/metadata/ArtifactMetadata.java
@@ -0,0 +1,83 @@
+package org.apache.maven.repository.legacy.metadata;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.repository.metadata.RepositoryMetadataStoreException;
+
+/**
+ * Contains metadata about an artifact, and methods to retrieve/store it from an artifact repository.
+ *
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ * @todo merge with artifactmetadatasource
+ * @todo retrieval exception not appropriate for store
+ */
+public interface ArtifactMetadata
+{
+ /** Whether this metadata should be stored alongside the artifact. */
+ boolean storedInArtifactVersionDirectory();
+
+ /** Whether this metadata should be stored alongside the group. */
+ boolean storedInGroupDirectory();
+
+ String getGroupId();
+
+ String getArtifactId();
+
+ String getBaseVersion();
+
+ Object getKey();
+
+ /**
+ * Get the filename of this metadata on the local repository.
+ *
+ * @param repository the remote repository it came from
+ * @return the filename
+ */
+ String getLocalFilename( ArtifactRepository repository );
+
+ /**
+ * Get the filename of this metadata on the remote repository.
+ *
+ * @return the filename
+ */
+ String getRemoteFilename();
+
+ /**
+ * Merge a new metadata set into this piece of metadata.
+ *
+ * @param metadata the new metadata
+ * @todo this should only be needed on the repository metadata
+ */
+ void merge( ArtifactMetadata metadata );
+
+ /**
+ * Store the metadata in the local repository.
+ *
+ * @param localRepository the local repository
+ * @param remoteRepository the remote repository it came from
+ * @todo this should only be needed on the repository metadata
+ */
+ void storeInLocalRepository( ArtifactRepository localRepository,
+ ArtifactRepository remoteRepository )
+ throws RepositoryMetadataStoreException;
+
+ String extendedToString();
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/site/apt/index.apt b/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/site/apt/index.apt
new file mode 100644
index 00000000..f796c118
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/site/apt/index.apt
@@ -0,0 +1,47 @@
+~~ Licensed to the Apache Software Foundation (ASF) under one
+~~ or more contributor license agreements. See the NOTICE file
+~~ distributed with this work for additional information
+~~ regarding copyright ownership. The ASF licenses this file
+~~ to you under the Apache License, Version 2.0 (the
+~~ "License"); you may not use this file except in compliance
+~~ with the License. You may obtain a copy of the License at
+~~
+~~ http://www.apache.org/licenses/LICENSE-2.0
+~~
+~~ Unless required by applicable law or agreed to in writing,
+~~ software distributed under the License is distributed on an
+~~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+~~ KIND, either express or implied. See the License for the
+~~ specific language governing permissions and limitations
+~~ under the License.
+
+ -----
+ Introduction
+ -----
+ Hervé Boutemy
+ -----
+ 2014-11-30
+ -----
+
+Maven Artifact
+
+ Maven Artifact classes, providing <<<Artifact>>> interface ({{{./apidocs/org/apache/maven/artifact/Artifact.html}javadoc}}),
+ with its <<<DefaultArtifact>>> implementation ({{{./xref/org/apache/maven/artifact/DefaultArtifact.html}source}}).
+
+ The jar file is executable and provides a little tool to display how Maven parses and compares versions:
+
++----+
+$ java -jar maven-artifact-*.jar 3.2.4-alpha-1 3.2.4-SNAPSHOT 3.2.4.0
+Display parameters as parsed by Maven (in canonical form) and comparison result:
+1. 3.2.4-alpha-1 == 3.2.4.alpha.1
+ 3.2.4-alpha-1 < 3.2.4-SNAPSHOT
+2. 3.2.4-SNAPSHOT == 3.2.4.snapshot
+ 3.2.4-SNAPSHOT < 3.2.4.0
+3. 3.2.4.0 == 3.2.4
++----+
+
+* Useful entry points
+
+ * artifact version comparison {{{./apidocs/org/apache/maven/artifact/versioning/ComparableVersion.html}javadoc}},
+
+ * {{{./apidocs/org/apache/maven/artifact/versioning/VersionRange.html}version range}}.
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/site/site.xml b/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/site/site.xml
new file mode 100644
index 00000000..3a16bf98
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/site/site.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project xmlns="http://maven.apache.org/DECORATION/1.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/DECORATION/1.0.0 http://maven.apache.org/xsd/decoration-1.0.0.xsd">
+ <body>
+ <menu name="Overview">
+ <item name="Introduction" href="index.html"/>
+ <item name="JavaDocs" href="apidocs/index.html"/>
+ <item name="Source Xref" href="xref/index.html"/>
+ <!--item name="FAQ" href="faq.html"/-->
+ </menu>
+
+ <menu ref="parent"/>
+ <menu ref="reports"/>
+ </body>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/test/java/org/apache/maven/artifact/versioning/ComparableVersionTest.java b/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/test/java/org/apache/maven/artifact/versioning/ComparableVersionTest.java
new file mode 100644
index 00000000..6cf372f7
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/test/java/org/apache/maven/artifact/versioning/ComparableVersionTest.java
@@ -0,0 +1,231 @@
+package org.apache.maven.artifact.versioning;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Locale;
+
+import junit.framework.TestCase;
+
+/**
+ * Test ComparableVersion.
+ *
+ * @author <a href="mailto:hboutemy@apache.org">Hervé Boutemy</a>
+ */
+@SuppressWarnings( "unchecked" )
+public class ComparableVersionTest
+ extends TestCase
+{
+ private Comparable newComparable( String version )
+ {
+ ComparableVersion ret = new ComparableVersion( version );
+ String canonical = ret.getCanonical();
+ String parsedCanonical = new ComparableVersion( canonical ).getCanonical();
+
+ System.out.println( "canonical( " + version + " ) = " + canonical );
+ assertEquals( "canonical( " + version + " ) = " + canonical + " -> canonical: " + parsedCanonical, canonical,
+ parsedCanonical );
+
+ return ret;
+ }
+
+ private static final String[] VERSIONS_QUALIFIER =
+ { "1-alpha2snapshot", "1-alpha2", "1-alpha-123", "1-beta-2", "1-beta123", "1-m2", "1-m11", "1-rc", "1-cr2",
+ "1-rc123", "1-SNAPSHOT", "1", "1-sp", "1-sp2", "1-sp123", "1-abc", "1-def", "1-pom-1", "1-1-snapshot",
+ "1-1", "1-2", "1-123" };
+
+ private static final String[] VERSIONS_NUMBER =
+ { "2.0", "2-1", "2.0.a", "2.0.0.a", "2.0.2", "2.0.123", "2.1.0", "2.1-a", "2.1b", "2.1-c", "2.1-1", "2.1.0.1",
+ "2.2", "2.123", "11.a2", "11.a11", "11.b2", "11.b11", "11.m2", "11.m11", "11", "11.a", "11b", "11c", "11m" };
+
+ private void checkVersionsOrder( String[] versions )
+ {
+ Comparable[] c = new Comparable[versions.length];
+ for ( int i = 0; i < versions.length; i++ )
+ {
+ c[i] = newComparable( versions[i] );
+ }
+
+ for ( int i = 1; i < versions.length; i++ )
+ {
+ Comparable low = c[i - 1];
+ for ( int j = i; j < versions.length; j++ )
+ {
+ Comparable high = c[j];
+ assertTrue( "expected " + low + " < " + high, low.compareTo( high ) < 0 );
+ assertTrue( "expected " + high + " > " + low, high.compareTo( low ) > 0 );
+ }
+ }
+ }
+
+ private void checkVersionsEqual( String v1, String v2 )
+ {
+ Comparable c1 = newComparable( v1 );
+ Comparable c2 = newComparable( v2 );
+ assertTrue( "expected " + v1 + " == " + v2, c1.compareTo( c2 ) == 0 );
+ assertTrue( "expected " + v2 + " == " + v1, c2.compareTo( c1 ) == 0 );
+ assertTrue( "expected same hashcode for " + v1 + " and " + v2, c1.hashCode() == c2.hashCode() );
+ assertTrue( "expected " + v1 + ".equals( " + v2 + " )", c1.equals( c2 ) );
+ assertTrue( "expected " + v2 + ".equals( " + v1 + " )", c2.equals( c1 ) );
+ }
+
+ private void checkVersionsOrder( String v1, String v2 )
+ {
+ Comparable c1 = newComparable( v1 );
+ Comparable c2 = newComparable( v2 );
+ assertTrue( "expected " + v1 + " < " + v2, c1.compareTo( c2 ) < 0 );
+ assertTrue( "expected " + v2 + " > " + v1, c2.compareTo( c1 ) > 0 );
+ }
+
+ public void testVersionsQualifier()
+ {
+ checkVersionsOrder( VERSIONS_QUALIFIER );
+ }
+
+ public void testVersionsNumber()
+ {
+ checkVersionsOrder( VERSIONS_NUMBER );
+ }
+
+ public void testVersionsEqual()
+ {
+ newComparable( "1.0-alpha" );
+ checkVersionsEqual( "1", "1" );
+ checkVersionsEqual( "1", "1.0" );
+ checkVersionsEqual( "1", "1.0.0" );
+ checkVersionsEqual( "1.0", "1.0.0" );
+ checkVersionsEqual( "1", "1-0" );
+ checkVersionsEqual( "1", "1.0-0" );
+ checkVersionsEqual( "1.0", "1.0-0" );
+ // no separator between number and character
+ checkVersionsEqual( "1a", "1-a" );
+ checkVersionsEqual( "1a", "1.0-a" );
+ checkVersionsEqual( "1a", "1.0.0-a" );
+ checkVersionsEqual( "1.0a", "1-a" );
+ checkVersionsEqual( "1.0.0a", "1-a" );
+ checkVersionsEqual( "1x", "1-x" );
+ checkVersionsEqual( "1x", "1.0-x" );
+ checkVersionsEqual( "1x", "1.0.0-x" );
+ checkVersionsEqual( "1.0x", "1-x" );
+ checkVersionsEqual( "1.0.0x", "1-x" );
+
+ // aliases
+ checkVersionsEqual( "1ga", "1" );
+ checkVersionsEqual( "1final", "1" );
+ checkVersionsEqual( "1cr", "1rc" );
+
+ // special "aliases" a, b and m for alpha, beta and milestone
+ checkVersionsEqual( "1a1", "1-alpha-1" );
+ checkVersionsEqual( "1b2", "1-beta-2" );
+ checkVersionsEqual( "1m3", "1-milestone-3" );
+
+ // case insensitive
+ checkVersionsEqual( "1X", "1x" );
+ checkVersionsEqual( "1A", "1a" );
+ checkVersionsEqual( "1B", "1b" );
+ checkVersionsEqual( "1M", "1m" );
+ checkVersionsEqual( "1Ga", "1" );
+ checkVersionsEqual( "1GA", "1" );
+ checkVersionsEqual( "1Final", "1" );
+ checkVersionsEqual( "1FinaL", "1" );
+ checkVersionsEqual( "1FINAL", "1" );
+ checkVersionsEqual( "1Cr", "1Rc" );
+ checkVersionsEqual( "1cR", "1rC" );
+ checkVersionsEqual( "1m3", "1Milestone3" );
+ checkVersionsEqual( "1m3", "1MileStone3" );
+ checkVersionsEqual( "1m3", "1MILESTONE3" );
+ }
+
+ public void testVersionComparing()
+ {
+ checkVersionsOrder( "1", "2" );
+ checkVersionsOrder( "1.5", "2" );
+ checkVersionsOrder( "1", "2.5" );
+ checkVersionsOrder( "1.0", "1.1" );
+ checkVersionsOrder( "1.1", "1.2" );
+ checkVersionsOrder( "1.0.0", "1.1" );
+ checkVersionsOrder( "1.0.1", "1.1" );
+ checkVersionsOrder( "1.1", "1.2.0" );
+
+ checkVersionsOrder( "1.0-alpha-1", "1.0" );
+ checkVersionsOrder( "1.0-alpha-1", "1.0-alpha-2" );
+ checkVersionsOrder( "1.0-alpha-1", "1.0-beta-1" );
+
+ checkVersionsOrder( "1.0-beta-1", "1.0-SNAPSHOT" );
+ checkVersionsOrder( "1.0-SNAPSHOT", "1.0" );
+ checkVersionsOrder( "1.0-alpha-1-SNAPSHOT", "1.0-alpha-1" );
+
+ checkVersionsOrder( "1.0", "1.0-1" );
+ checkVersionsOrder( "1.0-1", "1.0-2" );
+ checkVersionsOrder( "1.0.0", "1.0-1" );
+
+ checkVersionsOrder( "2.0-1", "2.0.1" );
+ checkVersionsOrder( "2.0.1-klm", "2.0.1-lmn" );
+ checkVersionsOrder( "2.0.1", "2.0.1-xyz" );
+
+ checkVersionsOrder( "2.0.1", "2.0.1-123" );
+ checkVersionsOrder( "2.0.1-xyz", "2.0.1-123" );
+ }
+
+ /**
+ * Test <a href="https://jira.codehaus.org/browse/MNG-5568">MNG-5568</a> edge case
+ * which was showing transitive inconsistency: since A > B and B > C then we should have A > C
+ * otherwise sorting a list of ComparableVersions() will in some cases throw runtime exception;
+ * see Netbeans issues <a href="https://netbeans.org/bugzilla/show_bug.cgi?id=240845">240845</a> and
+ * <a href="https://netbeans.org/bugzilla/show_bug.cgi?id=226100">226100</a>
+ */
+ public void testMng5568()
+ {
+ String a = "6.1.0";
+ String b = "6.1.0rc3";
+ String c = "6.1H.5-beta"; // this is the unusual version string, with 'H' in the middle
+
+ checkVersionsOrder( b, a ); // classical
+ checkVersionsOrder( b, c ); // now b < c, but before MNG-5568, we had b > c
+ checkVersionsOrder( a, c );
+ }
+
+ public void testLocaleIndependent()
+ {
+ Locale orig = Locale.getDefault();
+ Locale[] locales = { Locale.ENGLISH, new Locale( "tr" ), Locale.getDefault() };
+ try
+ {
+ for ( Locale locale : locales )
+ {
+ Locale.setDefault( locale );
+ checkVersionsEqual( "1-abcdefghijklmnopqrstuvwxyz", "1-ABCDEFGHIJKLMNOPQRSTUVWXYZ" );
+ }
+ }
+ finally
+ {
+ Locale.setDefault( orig );
+ }
+ }
+
+ public void testReuse()
+ {
+ ComparableVersion c1 = new ComparableVersion( "1" );
+ c1.parseVersion( "2" );
+
+ Comparable c2 = newComparable( "2" );
+
+ assertEquals( "reused instance should be equivalent to new instance", c1, c2 );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/test/java/org/apache/maven/artifact/versioning/DefaultArtifactVersionTest.java b/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/test/java/org/apache/maven/artifact/versioning/DefaultArtifactVersionTest.java
new file mode 100644
index 00000000..fc5a2742
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/test/java/org/apache/maven/artifact/versioning/DefaultArtifactVersionTest.java
@@ -0,0 +1,223 @@
+package org.apache.maven.artifact.versioning;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import junit.framework.TestCase;
+
+/**
+ * Test DefaultArtifactVersion.
+ *
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ */
+public class DefaultArtifactVersionTest
+ extends TestCase
+{
+ private ArtifactVersion newArtifactVersion( String version )
+ {
+ return new DefaultArtifactVersion( version );
+ }
+
+ private void checkVersionParsing( String version, int major, int minor, int incremental, int buildnumber,
+ String qualifier )
+ {
+ ArtifactVersion artifactVersion = newArtifactVersion( version );
+ String parsed =
+ "'" + version + "' parsed as ('" + artifactVersion.getMajorVersion() + "', '"
+ + artifactVersion.getMinorVersion() + "', '" + artifactVersion.getIncrementalVersion() + "', '"
+ + artifactVersion.getBuildNumber() + "', '" + artifactVersion.getQualifier() + "'), ";
+ assertEquals( parsed + "check major version", major, artifactVersion.getMajorVersion() );
+ assertEquals( parsed + "check minor version", minor, artifactVersion.getMinorVersion() );
+ assertEquals( parsed + "check incremental version", incremental, artifactVersion.getIncrementalVersion() );
+ assertEquals( parsed + "check build number", buildnumber, artifactVersion.getBuildNumber() );
+ assertEquals( parsed + "check qualifier", qualifier, artifactVersion.getQualifier() );
+ assertEquals( "check " + version + " string value", version, artifactVersion.toString() );
+ }
+
+ public void testVersionParsing()
+ {
+ checkVersionParsing( "1", 1, 0, 0, 0, null );
+ checkVersionParsing( "1.2", 1, 2, 0, 0, null );
+ checkVersionParsing( "1.2.3", 1, 2, 3, 0, null );
+ checkVersionParsing( "1.2.3-1", 1, 2, 3, 1, null );
+ checkVersionParsing( "1.2.3-alpha-1", 1, 2, 3, 0, "alpha-1" );
+ checkVersionParsing( "1.2-alpha-1", 1, 2, 0, 0, "alpha-1" );
+ checkVersionParsing( "1.2-alpha-1-20050205.060708-1", 1, 2, 0, 0, "alpha-1-20050205.060708-1" );
+ checkVersionParsing( "RELEASE", 0, 0, 0, 0, "RELEASE" );
+ checkVersionParsing( "2.0-1", 2, 0, 0, 1, null );
+
+ // 0 at the beginning of a number has a special handling
+ checkVersionParsing( "02", 0, 0, 0, 0, "02" );
+ checkVersionParsing( "0.09", 0, 0, 0, 0, "0.09" );
+ checkVersionParsing( "0.2.09", 0, 0, 0, 0, "0.2.09" );
+ checkVersionParsing( "2.0-01", 2, 0, 0, 0, "01" );
+
+ // version schemes not really supported: fully transformed as qualifier
+ checkVersionParsing( "1.0.1b", 0, 0, 0, 0, "1.0.1b" );
+ checkVersionParsing( "1.0M2", 0, 0, 0, 0, "1.0M2" );
+ checkVersionParsing( "1.0RC2", 0, 0, 0, 0, "1.0RC2" );
+ checkVersionParsing( "1.1.2.beta1", 1, 1, 2, 0, "beta1" );
+ checkVersionParsing( "1.7.3.beta1", 1, 7, 3, 0, "beta1" );
+ checkVersionParsing( "1.7.3.0", 0, 0, 0, 0, "1.7.3.0" );
+ checkVersionParsing( "1.7.3.0-1", 0, 0, 0, 0, "1.7.3.0-1" );
+ checkVersionParsing( "PATCH-1193602", 0, 0, 0, 0, "PATCH-1193602" );
+ checkVersionParsing( "5.0.0alpha-2006020117", 0, 0, 0, 0, "5.0.0alpha-2006020117" );
+ checkVersionParsing( "1.0.0.-SNAPSHOT", 0, 0, 0, 0, "1.0.0.-SNAPSHOT" );
+ checkVersionParsing( "1..0-SNAPSHOT", 0, 0, 0, 0, "1..0-SNAPSHOT" );
+ checkVersionParsing( "1.0.-SNAPSHOT", 0, 0, 0, 0, "1.0.-SNAPSHOT" );
+ checkVersionParsing( ".1.0-SNAPSHOT", 0, 0, 0, 0, ".1.0-SNAPSHOT" );
+
+ checkVersionParsing( "1.2.3.200705301630", 0, 0, 0, 0, "1.2.3.200705301630" );
+ checkVersionParsing( "1.2.3-200705301630", 1, 2, 3, 0, "200705301630" );
+ }
+
+ public void testVersionComparing()
+ {
+ assertVersionEqual( "1", "1" );
+ assertVersionOlder( "1", "2" );
+ assertVersionOlder( "1.5", "2" );
+ assertVersionOlder( "1", "2.5" );
+ assertVersionEqual( "1", "1.0" );
+ assertVersionEqual( "1", "1.0.0" );
+ assertVersionOlder( "1.0", "1.1" );
+ assertVersionOlder( "1.1", "1.2" );
+ assertVersionOlder( "1.0.0", "1.1" );
+ assertVersionOlder( "1.1", "1.2.0" );
+
+ assertVersionOlder( "1.1.2.alpha1", "1.1.2" );
+ assertVersionOlder( "1.1.2.alpha1", "1.1.2.beta1" );
+ assertVersionOlder( "1.1.2.beta1", "1.2" );
+
+ assertVersionOlder( "1.0-alpha-1", "1.0" );
+ assertVersionOlder( "1.0-alpha-1", "1.0-alpha-2" );
+ assertVersionOlder( "1.0-alpha-2", "1.0-alpha-15" );
+ assertVersionOlder( "1.0-alpha-1", "1.0-beta-1" );
+
+ assertVersionOlder( "1.0-beta-1", "1.0-SNAPSHOT" );
+ assertVersionOlder( "1.0-SNAPSHOT", "1.0" );
+ assertVersionOlder( "1.0-alpha-1-SNAPSHOT", "1.0-alpha-1" );
+
+ assertVersionOlder( "1.0", "1.0-1" );
+ assertVersionOlder( "1.0-1", "1.0-2" );
+ assertVersionEqual( "2.0-0", "2.0" );
+ assertVersionOlder( "2.0", "2.0-1" );
+ assertVersionOlder( "2.0.0", "2.0-1" );
+ assertVersionOlder( "2.0-1", "2.0.1" );
+
+ assertVersionOlder( "2.0.1-klm", "2.0.1-lmn" );
+ assertVersionOlder( "2.0.1", "2.0.1-xyz" );
+ assertVersionOlder( "2.0.1-xyz-1", "2.0.1-1-xyz" );
+
+ assertVersionOlder( "2.0.1", "2.0.1-123" );
+ assertVersionOlder( "2.0.1-xyz", "2.0.1-123" );
+
+ assertVersionOlder( "1.2.3-10000000000", "1.2.3-10000000001" );
+ assertVersionOlder( "1.2.3-1", "1.2.3-10000000001" );
+ assertVersionOlder( "2.3.0-v200706262000", "2.3.0-v200706262130" ); // org.eclipse:emf:2.3.0-v200706262000
+ // org.eclipse.wst.common_core.feature_2.0.0.v200706041905-7C78EK9E_EkMNfNOd2d8qq
+ assertVersionOlder( "2.0.0.v200706041905-7C78EK9E_EkMNfNOd2d8qq", "2.0.0.v200706041906-7C78EK9E_EkMNfNOd2d8qq" );
+ }
+
+ public void testVersionSnapshotComparing()
+ {
+ assertVersionEqual( "1-SNAPSHOT", "1-SNAPSHOT" );
+ assertVersionOlder( "1-SNAPSHOT", "2-SNAPSHOT" );
+ assertVersionOlder( "1.5-SNAPSHOT", "2-SNAPSHOT" );
+ assertVersionOlder( "1-SNAPSHOT", "2.5-SNAPSHOT" );
+ assertVersionEqual( "1-SNAPSHOT", "1.0-SNAPSHOT" );
+ assertVersionEqual( "1-SNAPSHOT", "1.0.0-SNAPSHOT" );
+ assertVersionOlder( "1.0-SNAPSHOT", "1.1-SNAPSHOT" );
+ assertVersionOlder( "1.1-SNAPSHOT", "1.2-SNAPSHOT" );
+ assertVersionOlder( "1.0.0-SNAPSHOT", "1.1-SNAPSHOT" );
+ assertVersionOlder( "1.1-SNAPSHOT", "1.2.0-SNAPSHOT" );
+
+ // assertVersionOlder( "1.0-alpha-1-SNAPSHOT", "1.0-SNAPSHOT" );
+ assertVersionOlder( "1.0-alpha-1-SNAPSHOT", "1.0-alpha-2-SNAPSHOT" );
+ assertVersionOlder( "1.0-alpha-1-SNAPSHOT", "1.0-beta-1-SNAPSHOT" );
+
+ assertVersionOlder( "1.0-beta-1-SNAPSHOT", "1.0-SNAPSHOT-SNAPSHOT" );
+ assertVersionOlder( "1.0-SNAPSHOT-SNAPSHOT", "1.0-SNAPSHOT" );
+ assertVersionOlder( "1.0-alpha-1-SNAPSHOT-SNAPSHOT", "1.0-alpha-1-SNAPSHOT" );
+
+ assertVersionOlder( "1.0-SNAPSHOT", "1.0-1-SNAPSHOT" );
+ assertVersionOlder( "1.0-1-SNAPSHOT", "1.0-2-SNAPSHOT" );
+ // assertVersionEqual( "2.0-0-SNAPSHOT", "2.0-SNAPSHOT" );
+ assertVersionOlder( "2.0-SNAPSHOT", "2.0-1-SNAPSHOT" );
+ assertVersionOlder( "2.0.0-SNAPSHOT", "2.0-1-SNAPSHOT" );
+ assertVersionOlder( "2.0-1-SNAPSHOT", "2.0.1-SNAPSHOT" );
+
+ assertVersionOlder( "2.0.1-klm-SNAPSHOT", "2.0.1-lmn-SNAPSHOT" );
+ // assertVersionOlder( "2.0.1-xyz-SNAPSHOT", "2.0.1-SNAPSHOT" );
+ assertVersionOlder( "2.0.1-SNAPSHOT", "2.0.1-123-SNAPSHOT" );
+ assertVersionOlder( "2.0.1-xyz-SNAPSHOT", "2.0.1-123-SNAPSHOT" );
+ }
+
+ public void testSnapshotVsReleases()
+ {
+ assertVersionOlder( "1.0-RC1", "1.0-SNAPSHOT" );
+ assertVersionOlder( "1.0-rc1", "1.0-SNAPSHOT" );
+ assertVersionOlder( "1.0-rc-1", "1.0-SNAPSHOT" );
+ }
+
+ public void testHashCode()
+ {
+ ArtifactVersion v1 = newArtifactVersion( "1" );
+ ArtifactVersion v2 = newArtifactVersion( "1.0" );
+ assertEquals( true, v1.equals( v2 ) );
+ assertEquals( v1.hashCode(), v2.hashCode() );
+ }
+
+ public void testEqualsNullSafe()
+ {
+ assertFalse( newArtifactVersion( "1" ).equals( null ) );
+ }
+
+ public void testEqualsTypeSafe()
+ {
+ assertFalse( newArtifactVersion( "1" ).equals( "non-an-artifact-version-instance" ) );
+ }
+
+ public void testNonNumericVersionRepresentationReturnsANumberFormatException()
+ {
+ try
+ {
+ new DefaultArtifactVersion( "..." );
+ }
+ catch ( Exception e )
+ {
+ assertTrue( "We expect a NumberFormatException to be thrown.", e instanceof NumberFormatException );
+ }
+ }
+
+ private void assertVersionOlder( String left, String right )
+ {
+ assertTrue( left + " should be older than " + right,
+ newArtifactVersion( left ).compareTo( newArtifactVersion( right ) ) < 0 );
+ assertTrue( right + " should be newer than " + left,
+ newArtifactVersion( right ).compareTo( newArtifactVersion( left ) ) > 0 );
+ }
+
+ private void assertVersionEqual( String left, String right )
+ {
+ assertTrue( left + " should be equal to " + right,
+ newArtifactVersion( left ).compareTo( newArtifactVersion( right ) ) == 0 );
+ assertTrue( right + " should be equal to " + left,
+ newArtifactVersion( right ).compareTo( newArtifactVersion( left ) ) == 0 );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/test/java/org/apache/maven/artifact/versioning/VersionRangeTest.java b/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/test/java/org/apache/maven/artifact/versioning/VersionRangeTest.java
new file mode 100644
index 00000000..14b16cba
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-artifact/src/test/java/org/apache/maven/artifact/versioning/VersionRangeTest.java
@@ -0,0 +1,730 @@
+package org.apache.maven.artifact.versioning;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.List;
+
+import junit.framework.TestCase;
+
+import org.apache.maven.artifact.Artifact;
+
+/**
+ * Tests version range construction.
+ *
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ */
+public class VersionRangeTest
+ extends TestCase
+{
+ private static final String CHECK_NUM_RESTRICTIONS = "check number of restrictions";
+
+ private static final String CHECK_UPPER_BOUND = "check upper bound";
+
+ private static final String CHECK_UPPER_BOUND_INCLUSIVE = "check upper bound is inclusive";
+
+ private static final String CHECK_LOWER_BOUND = "check lower bound";
+
+ private static final String CHECK_LOWER_BOUND_INCLUSIVE = "check lower bound is inclusive";
+
+ private static final String CHECK_VERSION_RECOMMENDATION = "check version recommended";
+
+ private static final String CHECK_SELECTED_VERSION_KNOWN = "check selected version known";
+
+ private static final String CHECK_SELECTED_VERSION = "check selected version";
+
+ public void testRange()
+ throws InvalidVersionSpecificationException, OverConstrainedVersionException
+ {
+ Artifact artifact = null;
+
+ VersionRange range = VersionRange.createFromVersionSpec( "(,1.0]" );
+ List<Restriction> restrictions = range.getRestrictions();
+ assertEquals( CHECK_NUM_RESTRICTIONS, 1, restrictions.size() );
+ Restriction restriction = restrictions.get( 0 );
+ assertNull( CHECK_LOWER_BOUND, restriction.getLowerBound() );
+ assertFalse( CHECK_LOWER_BOUND_INCLUSIVE, restriction.isLowerBoundInclusive() );
+ assertEquals( CHECK_UPPER_BOUND, "1.0", restriction.getUpperBound().toString() );
+ assertTrue( CHECK_UPPER_BOUND_INCLUSIVE, restriction.isUpperBoundInclusive() );
+ assertNull( CHECK_VERSION_RECOMMENDATION, range.getRecommendedVersion() );
+ assertFalse( CHECK_SELECTED_VERSION_KNOWN, range.isSelectedVersionKnown( artifact ) );
+ assertNull( CHECK_SELECTED_VERSION, range.getSelectedVersion( artifact ) );
+
+ range = VersionRange.createFromVersionSpec( "1.0" );
+ assertEquals( CHECK_VERSION_RECOMMENDATION, "1.0", range.getRecommendedVersion().toString() );
+ restrictions = range.getRestrictions();
+ assertEquals( CHECK_NUM_RESTRICTIONS, 1, restrictions.size() );
+ restriction = restrictions.get( 0 );
+ assertNull( CHECK_LOWER_BOUND, restriction.getLowerBound() );
+ assertFalse( CHECK_LOWER_BOUND_INCLUSIVE, restriction.isLowerBoundInclusive() );
+ assertNull( CHECK_UPPER_BOUND, restriction.getUpperBound() );
+ assertFalse( CHECK_UPPER_BOUND_INCLUSIVE, restriction.isUpperBoundInclusive() );
+ assertTrue( CHECK_SELECTED_VERSION_KNOWN, range.isSelectedVersionKnown( artifact ) );
+ assertEquals( CHECK_SELECTED_VERSION, "1.0", range.getSelectedVersion( artifact ).toString() );
+
+ range = VersionRange.createFromVersionSpec( "[1.0]" );
+ restrictions = range.getRestrictions();
+ assertEquals( CHECK_NUM_RESTRICTIONS, 1, restrictions.size() );
+ restriction = restrictions.get( 0 );
+ assertEquals( CHECK_LOWER_BOUND, "1.0", restriction.getLowerBound().toString() );
+ assertTrue( CHECK_LOWER_BOUND_INCLUSIVE, restriction.isLowerBoundInclusive() );
+ assertEquals( CHECK_UPPER_BOUND, "1.0", restriction.getUpperBound().toString() );
+ assertTrue( CHECK_UPPER_BOUND_INCLUSIVE, restriction.isUpperBoundInclusive() );
+ assertNull( CHECK_VERSION_RECOMMENDATION, range.getRecommendedVersion() );
+ assertFalse( CHECK_SELECTED_VERSION_KNOWN, range.isSelectedVersionKnown( artifact ) );
+ assertNull( CHECK_SELECTED_VERSION, range.getSelectedVersion( artifact ) );
+
+ range = VersionRange.createFromVersionSpec( "[1.2,1.3]" );
+ restrictions = range.getRestrictions();
+ assertEquals( CHECK_NUM_RESTRICTIONS, 1, restrictions.size() );
+ restriction = restrictions.get( 0 );
+ assertEquals( CHECK_LOWER_BOUND, "1.2", restriction.getLowerBound().toString() );
+ assertTrue( CHECK_LOWER_BOUND_INCLUSIVE, restriction.isLowerBoundInclusive() );
+ assertEquals( CHECK_UPPER_BOUND, "1.3", restriction.getUpperBound().toString() );
+ assertTrue( CHECK_UPPER_BOUND_INCLUSIVE, restriction.isUpperBoundInclusive() );
+ assertNull( CHECK_VERSION_RECOMMENDATION, range.getRecommendedVersion() );
+ assertFalse( CHECK_SELECTED_VERSION_KNOWN, range.isSelectedVersionKnown( artifact ) );
+ assertNull( CHECK_SELECTED_VERSION, range.getSelectedVersion( artifact ) );
+
+ range = VersionRange.createFromVersionSpec( "[1.0,2.0)" );
+ restrictions = range.getRestrictions();
+ assertEquals( CHECK_NUM_RESTRICTIONS, 1, restrictions.size() );
+ restriction = restrictions.get( 0 );
+ assertEquals( CHECK_LOWER_BOUND, "1.0", restriction.getLowerBound().toString() );
+ assertTrue( CHECK_LOWER_BOUND_INCLUSIVE, restriction.isLowerBoundInclusive() );
+ assertEquals( CHECK_UPPER_BOUND, "2.0", restriction.getUpperBound().toString() );
+ assertFalse( CHECK_UPPER_BOUND_INCLUSIVE, restriction.isUpperBoundInclusive() );
+ assertNull( CHECK_VERSION_RECOMMENDATION, range.getRecommendedVersion() );
+ assertFalse( CHECK_SELECTED_VERSION_KNOWN, range.isSelectedVersionKnown( artifact ) );
+ assertNull( CHECK_SELECTED_VERSION, range.getSelectedVersion( artifact ) );
+
+ range = VersionRange.createFromVersionSpec( "[1.5,)" );
+ restrictions = range.getRestrictions();
+ assertEquals( CHECK_NUM_RESTRICTIONS, 1, restrictions.size() );
+ restriction = restrictions.get( 0 );
+ assertEquals( CHECK_LOWER_BOUND, "1.5", restriction.getLowerBound().toString() );
+ assertTrue( CHECK_LOWER_BOUND_INCLUSIVE, restriction.isLowerBoundInclusive() );
+ assertNull( CHECK_UPPER_BOUND, restriction.getUpperBound() );
+ assertFalse( CHECK_UPPER_BOUND_INCLUSIVE, restriction.isUpperBoundInclusive() );
+ assertNull( CHECK_VERSION_RECOMMENDATION, range.getRecommendedVersion() );
+ assertFalse( CHECK_SELECTED_VERSION_KNOWN, range.isSelectedVersionKnown( artifact ) );
+ assertNull( CHECK_SELECTED_VERSION, range.getSelectedVersion( artifact ) );
+
+ range = VersionRange.createFromVersionSpec( "(,1.0],[1.2,)" );
+ restrictions = range.getRestrictions();
+ assertEquals( CHECK_NUM_RESTRICTIONS, 2, restrictions.size() );
+ restriction = restrictions.get( 0 );
+ assertNull( CHECK_LOWER_BOUND, restriction.getLowerBound() );
+ assertFalse( CHECK_LOWER_BOUND_INCLUSIVE, restriction.isLowerBoundInclusive() );
+ assertEquals( CHECK_UPPER_BOUND, "1.0", restriction.getUpperBound().toString() );
+ assertTrue( CHECK_UPPER_BOUND_INCLUSIVE, restriction.isUpperBoundInclusive() );
+ assertNull( CHECK_VERSION_RECOMMENDATION, range.getRecommendedVersion() );
+ restriction = restrictions.get( 1 );
+ assertEquals( CHECK_LOWER_BOUND, "1.2", restriction.getLowerBound().toString() );
+ assertTrue( CHECK_LOWER_BOUND_INCLUSIVE, restriction.isLowerBoundInclusive() );
+ assertNull( CHECK_UPPER_BOUND, restriction.getUpperBound() );
+ assertFalse( CHECK_UPPER_BOUND_INCLUSIVE, restriction.isUpperBoundInclusive() );
+ assertNull( CHECK_VERSION_RECOMMENDATION, range.getRecommendedVersion() );
+ assertFalse( CHECK_SELECTED_VERSION_KNOWN, range.isSelectedVersionKnown( artifact ) );
+ assertNull( CHECK_SELECTED_VERSION, range.getSelectedVersion( artifact ) );
+
+ range = VersionRange.createFromVersionSpec( "[1.0,)" );
+ assertFalse( range.containsVersion( new DefaultArtifactVersion( "1.0-SNAPSHOT" ) ) );
+
+ range = VersionRange.createFromVersionSpec( "[1.0,1.1-SNAPSHOT]" );
+ assertTrue( range.containsVersion( new DefaultArtifactVersion( "1.1-SNAPSHOT" ) ) );
+
+ range = VersionRange.createFromVersionSpec( "[5.0.9.0,5.0.10.0)" );
+ assertTrue( range.containsVersion( new DefaultArtifactVersion( "5.0.9.0" ) ) );
+ }
+
+ public void testInvalidRanges()
+ {
+ checkInvalidRange( "(1.0)" );
+ checkInvalidRange( "[1.0)" );
+ checkInvalidRange( "(1.0]" );
+ checkInvalidRange( "(1.0,1.0]" );
+ checkInvalidRange( "[1.0,1.0)" );
+ checkInvalidRange( "(1.0,1.0)" );
+ checkInvalidRange( "[1.1,1.0]" );
+ checkInvalidRange( "[1.0,1.2),1.3" );
+ // overlap
+ checkInvalidRange( "[1.0,1.2),(1.1,1.3]" );
+ // overlap
+ checkInvalidRange( "[1.1,1.3),(1.0,1.2]" );
+ // ordering
+ checkInvalidRange( "(1.1,1.2],[1.0,1.1)" );
+ }
+
+ public void testIntersections()
+ throws InvalidVersionSpecificationException
+ {
+ VersionRange range1 = VersionRange.createFromVersionSpec( "1.0" );
+ VersionRange range2 = VersionRange.createFromVersionSpec( "1.1" );
+ VersionRange mergedRange = range1.restrict( range2 );
+ // TODO: current policy is to retain the original version - is this correct, do we need strategies or is that handled elsewhere?
+// assertEquals( CHECK_VERSION_RECOMMENDATION, "1.1", mergedRange.getRecommendedVersion().toString() );
+ assertEquals( CHECK_VERSION_RECOMMENDATION, "1.0", mergedRange.getRecommendedVersion().toString() );
+ List<Restriction> restrictions = mergedRange.getRestrictions();
+ assertEquals( CHECK_NUM_RESTRICTIONS, 1, restrictions.size() );
+ Restriction restriction = restrictions.get( 0 );
+ assertNull( CHECK_LOWER_BOUND, restriction.getLowerBound() );
+ assertFalse( CHECK_LOWER_BOUND_INCLUSIVE, restriction.isLowerBoundInclusive() );
+ assertNull( CHECK_UPPER_BOUND, restriction.getUpperBound() );
+ assertFalse( CHECK_UPPER_BOUND_INCLUSIVE, restriction.isUpperBoundInclusive() );
+
+ mergedRange = range2.restrict( range1 );
+ assertEquals( CHECK_VERSION_RECOMMENDATION, "1.1", mergedRange.getRecommendedVersion().toString() );
+ restrictions = mergedRange.getRestrictions();
+ assertEquals( CHECK_NUM_RESTRICTIONS, 1, restrictions.size() );
+ restriction = restrictions.get( 0 );
+ assertNull( CHECK_LOWER_BOUND, restriction.getLowerBound() );
+ assertFalse( CHECK_LOWER_BOUND_INCLUSIVE, restriction.isLowerBoundInclusive() );
+ assertNull( CHECK_UPPER_BOUND, restriction.getUpperBound() );
+ assertFalse( CHECK_UPPER_BOUND_INCLUSIVE, restriction.isUpperBoundInclusive() );
+
+ // TODO: test reversed restrictions on all below
+ range1 = VersionRange.createFromVersionSpec( "[1.0,)" );
+ range2 = VersionRange.createFromVersionSpec( "1.1" );
+ mergedRange = range1.restrict( range2 );
+ assertEquals( CHECK_VERSION_RECOMMENDATION, "1.1", mergedRange.getRecommendedVersion().toString() );
+ restrictions = mergedRange.getRestrictions();
+ assertEquals( CHECK_NUM_RESTRICTIONS, 1, restrictions.size() );
+ restriction = restrictions.get( 0 );
+ assertEquals( CHECK_LOWER_BOUND, "1.0", restriction.getLowerBound().toString() );
+ assertTrue( CHECK_LOWER_BOUND_INCLUSIVE, restriction.isLowerBoundInclusive() );
+ assertNull( CHECK_UPPER_BOUND, restriction.getUpperBound() );
+ assertFalse( CHECK_UPPER_BOUND_INCLUSIVE, restriction.isUpperBoundInclusive() );
+
+ range1 = VersionRange.createFromVersionSpec( "[1.1,)" );
+ range2 = VersionRange.createFromVersionSpec( "1.1" );
+ mergedRange = range1.restrict( range2 );
+ assertEquals( CHECK_VERSION_RECOMMENDATION, "1.1", mergedRange.getRecommendedVersion().toString() );
+ restrictions = mergedRange.getRestrictions();
+ assertEquals( CHECK_NUM_RESTRICTIONS, 1, restrictions.size() );
+ restriction = restrictions.get( 0 );
+ assertEquals( CHECK_LOWER_BOUND, "1.1", restriction.getLowerBound().toString() );
+ assertTrue( CHECK_LOWER_BOUND_INCLUSIVE, restriction.isLowerBoundInclusive() );
+ assertNull( CHECK_UPPER_BOUND, restriction.getUpperBound() );
+ assertFalse( CHECK_UPPER_BOUND_INCLUSIVE, restriction.isUpperBoundInclusive() );
+
+ range1 = VersionRange.createFromVersionSpec( "[1.1]" );
+ range2 = VersionRange.createFromVersionSpec( "1.1" );
+ mergedRange = range1.restrict( range2 );
+ assertEquals( CHECK_VERSION_RECOMMENDATION, "1.1", mergedRange.getRecommendedVersion().toString() );
+ restrictions = mergedRange.getRestrictions();
+ assertEquals( CHECK_NUM_RESTRICTIONS, 1, restrictions.size() );
+ restriction = restrictions.get( 0 );
+ assertEquals( CHECK_LOWER_BOUND, "1.1", restriction.getLowerBound().toString() );
+ assertTrue( CHECK_LOWER_BOUND_INCLUSIVE, restriction.isLowerBoundInclusive() );
+ assertEquals( CHECK_UPPER_BOUND, "1.1", restriction.getLowerBound().toString() );
+ assertTrue( CHECK_UPPER_BOUND_INCLUSIVE, restriction.isUpperBoundInclusive() );
+
+ range1 = VersionRange.createFromVersionSpec( "(1.1,)" );
+ range2 = VersionRange.createFromVersionSpec( "1.1" );
+ mergedRange = range1.restrict( range2 );
+ assertNull( CHECK_VERSION_RECOMMENDATION, mergedRange.getRecommendedVersion() );
+ restrictions = mergedRange.getRestrictions();
+ assertEquals( CHECK_NUM_RESTRICTIONS, 1, restrictions.size() );
+ restriction = restrictions.get( 0 );
+ assertEquals( CHECK_LOWER_BOUND, "1.1", restriction.getLowerBound().toString() );
+ assertFalse( CHECK_LOWER_BOUND_INCLUSIVE, restriction.isLowerBoundInclusive() );
+ assertNull( CHECK_UPPER_BOUND, restriction.getUpperBound() );
+ assertFalse( CHECK_UPPER_BOUND_INCLUSIVE, restriction.isUpperBoundInclusive() );
+
+ range1 = VersionRange.createFromVersionSpec( "[1.2,)" );
+ range2 = VersionRange.createFromVersionSpec( "1.1" );
+ mergedRange = range1.restrict( range2 );
+ assertNull( CHECK_VERSION_RECOMMENDATION, mergedRange.getRecommendedVersion() );
+ restrictions = mergedRange.getRestrictions();
+ assertEquals( CHECK_NUM_RESTRICTIONS, 1, restrictions.size() );
+ restriction = restrictions.get( 0 );
+ assertEquals( CHECK_LOWER_BOUND, "1.2", restriction.getLowerBound().toString() );
+ assertTrue( CHECK_LOWER_BOUND_INCLUSIVE, restriction.isLowerBoundInclusive() );
+ assertNull( CHECK_UPPER_BOUND, restriction.getUpperBound() );
+ assertFalse( CHECK_UPPER_BOUND_INCLUSIVE, restriction.isUpperBoundInclusive() );
+
+ range1 = VersionRange.createFromVersionSpec( "(,1.2]" );
+ range2 = VersionRange.createFromVersionSpec( "1.1" );
+ mergedRange = range1.restrict( range2 );
+ assertEquals( CHECK_VERSION_RECOMMENDATION, "1.1", mergedRange.getRecommendedVersion().toString() );
+ restrictions = mergedRange.getRestrictions();
+ assertEquals( CHECK_NUM_RESTRICTIONS, 1, restrictions.size() );
+ restriction = restrictions.get( 0 );
+ assertNull( CHECK_LOWER_BOUND, restriction.getLowerBound() );
+ assertFalse( CHECK_LOWER_BOUND_INCLUSIVE, restriction.isLowerBoundInclusive() );
+ assertEquals( CHECK_UPPER_BOUND, "1.2", restriction.getUpperBound().toString() );
+ assertTrue( CHECK_UPPER_BOUND_INCLUSIVE, restriction.isUpperBoundInclusive() );
+
+ range1 = VersionRange.createFromVersionSpec( "(,1.1]" );
+ range2 = VersionRange.createFromVersionSpec( "1.1" );
+ mergedRange = range1.restrict( range2 );
+ assertEquals( CHECK_VERSION_RECOMMENDATION, "1.1", mergedRange.getRecommendedVersion().toString() );
+ restrictions = mergedRange.getRestrictions();
+ assertEquals( CHECK_NUM_RESTRICTIONS, 1, restrictions.size() );
+ restriction = restrictions.get( 0 );
+ assertNull( CHECK_LOWER_BOUND, restriction.getLowerBound() );
+ assertFalse( CHECK_LOWER_BOUND_INCLUSIVE, restriction.isLowerBoundInclusive() );
+ assertEquals( CHECK_UPPER_BOUND, "1.1", restriction.getUpperBound().toString() );
+ assertTrue( CHECK_UPPER_BOUND_INCLUSIVE, restriction.isUpperBoundInclusive() );
+
+ range1 = VersionRange.createFromVersionSpec( "(,1.1)" );
+ range2 = VersionRange.createFromVersionSpec( "1.1" );
+ mergedRange = range1.restrict( range2 );
+ assertNull( CHECK_VERSION_RECOMMENDATION, mergedRange.getRecommendedVersion() );
+ restrictions = mergedRange.getRestrictions();
+ assertEquals( CHECK_NUM_RESTRICTIONS, 1, restrictions.size() );
+ restriction = restrictions.get( 0 );
+ assertNull( CHECK_LOWER_BOUND, restriction.getLowerBound() );
+ assertFalse( CHECK_LOWER_BOUND_INCLUSIVE, restriction.isLowerBoundInclusive() );
+ assertEquals( CHECK_UPPER_BOUND, "1.1", restriction.getUpperBound().toString() );
+ assertFalse( CHECK_UPPER_BOUND_INCLUSIVE, restriction.isUpperBoundInclusive() );
+
+ range1 = VersionRange.createFromVersionSpec( "(,1.0]" );
+ range2 = VersionRange.createFromVersionSpec( "1.1" );
+ mergedRange = range1.restrict( range2 );
+ assertNull( CHECK_VERSION_RECOMMENDATION, mergedRange.getRecommendedVersion() );
+ restrictions = mergedRange.getRestrictions();
+ assertEquals( CHECK_NUM_RESTRICTIONS, 1, restrictions.size() );
+ restriction = restrictions.get( 0 );
+ assertNull( CHECK_LOWER_BOUND, restriction.getLowerBound() );
+ assertFalse( CHECK_LOWER_BOUND_INCLUSIVE, restriction.isLowerBoundInclusive() );
+ assertEquals( CHECK_UPPER_BOUND, "1.0", restriction.getUpperBound().toString() );
+ assertTrue( CHECK_UPPER_BOUND_INCLUSIVE, restriction.isUpperBoundInclusive() );
+
+ range1 = VersionRange.createFromVersionSpec( "(,1.0], [1.1,)" );
+ range2 = VersionRange.createFromVersionSpec( "1.2" );
+ mergedRange = range1.restrict( range2 );
+ assertEquals( CHECK_VERSION_RECOMMENDATION, "1.2", mergedRange.getRecommendedVersion().toString() );
+ restrictions = mergedRange.getRestrictions();
+ assertEquals( CHECK_NUM_RESTRICTIONS, 2, restrictions.size() );
+ restriction = restrictions.get( 0 );
+ assertNull( CHECK_LOWER_BOUND, restriction.getLowerBound() );
+ assertFalse( CHECK_LOWER_BOUND_INCLUSIVE, restriction.isLowerBoundInclusive() );
+ assertEquals( CHECK_UPPER_BOUND, "1.0", restriction.getUpperBound().toString() );
+ assertTrue( CHECK_UPPER_BOUND_INCLUSIVE, restriction.isUpperBoundInclusive() );
+ restriction = restrictions.get( 1 );
+ assertEquals( CHECK_LOWER_BOUND, "1.1", restriction.getLowerBound().toString() );
+ assertTrue( CHECK_LOWER_BOUND_INCLUSIVE, restriction.isLowerBoundInclusive() );
+ assertNull( CHECK_UPPER_BOUND, restriction.getUpperBound() );
+ assertFalse( CHECK_UPPER_BOUND_INCLUSIVE, restriction.isUpperBoundInclusive() );
+
+ range1 = VersionRange.createFromVersionSpec( "(,1.0], [1.1,)" );
+ range2 = VersionRange.createFromVersionSpec( "1.0.5" );
+ mergedRange = range1.restrict( range2 );
+ assertNull( CHECK_VERSION_RECOMMENDATION, mergedRange.getRecommendedVersion() );
+ restrictions = mergedRange.getRestrictions();
+ assertEquals( CHECK_NUM_RESTRICTIONS, 2, restrictions.size() );
+ restriction = restrictions.get( 0 );
+ assertNull( CHECK_LOWER_BOUND, restriction.getLowerBound() );
+ assertFalse( CHECK_LOWER_BOUND_INCLUSIVE, restriction.isLowerBoundInclusive() );
+ assertEquals( CHECK_UPPER_BOUND, "1.0", restriction.getUpperBound().toString() );
+ assertTrue( CHECK_UPPER_BOUND_INCLUSIVE, restriction.isUpperBoundInclusive() );
+ restriction = restrictions.get( 1 );
+ assertEquals( CHECK_LOWER_BOUND, "1.1", restriction.getLowerBound().toString() );
+ assertTrue( CHECK_LOWER_BOUND_INCLUSIVE, restriction.isLowerBoundInclusive() );
+ assertNull( CHECK_UPPER_BOUND, restriction.getUpperBound() );
+ assertFalse( CHECK_UPPER_BOUND_INCLUSIVE, restriction.isUpperBoundInclusive() );
+
+ range1 = VersionRange.createFromVersionSpec( "(,1.1), (1.1,)" );
+ range2 = VersionRange.createFromVersionSpec( "1.1" );
+ mergedRange = range1.restrict( range2 );
+ assertNull( CHECK_VERSION_RECOMMENDATION, mergedRange.getRecommendedVersion() );
+ restrictions = mergedRange.getRestrictions();
+ assertEquals( CHECK_NUM_RESTRICTIONS, 2, restrictions.size() );
+ restriction = restrictions.get( 0 );
+ assertNull( CHECK_LOWER_BOUND, restriction.getLowerBound() );
+ assertFalse( CHECK_LOWER_BOUND_INCLUSIVE, restriction.isLowerBoundInclusive() );
+ assertEquals( CHECK_UPPER_BOUND, "1.1", restriction.getUpperBound().toString() );
+ assertFalse( CHECK_UPPER_BOUND_INCLUSIVE, restriction.isUpperBoundInclusive() );
+ restriction = restrictions.get( 1 );
+ assertEquals( CHECK_LOWER_BOUND, "1.1", restriction.getLowerBound().toString() );
+ assertFalse( CHECK_LOWER_BOUND_INCLUSIVE, restriction.isLowerBoundInclusive() );
+ assertNull( CHECK_UPPER_BOUND, restriction.getUpperBound() );
+ assertFalse( CHECK_UPPER_BOUND_INCLUSIVE, restriction.isUpperBoundInclusive() );
+
+ range1 = VersionRange.createFromVersionSpec( "[1.1,1.3]" );
+ range2 = VersionRange.createFromVersionSpec( "(1.1,)" );
+ mergedRange = range1.restrict( range2 );
+ assertNull( CHECK_VERSION_RECOMMENDATION, mergedRange.getRecommendedVersion() );
+ restrictions = mergedRange.getRestrictions();
+ assertEquals( CHECK_NUM_RESTRICTIONS, 1, restrictions.size() );
+ restriction = restrictions.get( 0 );
+ assertEquals( CHECK_LOWER_BOUND, "1.1", restriction.getLowerBound().toString() );
+ assertFalse( CHECK_LOWER_BOUND_INCLUSIVE, restriction.isLowerBoundInclusive() );
+ assertEquals( CHECK_UPPER_BOUND, "1.3", restriction.getUpperBound().toString() );
+ assertTrue( CHECK_UPPER_BOUND_INCLUSIVE, restriction.isUpperBoundInclusive() );
+
+ range1 = VersionRange.createFromVersionSpec( "(,1.3)" );
+ range2 = VersionRange.createFromVersionSpec( "[1.2,1.3]" );
+ mergedRange = range1.restrict( range2 );
+ assertNull( CHECK_VERSION_RECOMMENDATION, mergedRange.getRecommendedVersion() );
+ restrictions = mergedRange.getRestrictions();
+ assertEquals( CHECK_NUM_RESTRICTIONS, 1, restrictions.size() );
+ restriction = restrictions.get( 0 );
+ assertEquals( CHECK_LOWER_BOUND, "1.2", restriction.getLowerBound().toString() );
+ assertTrue( CHECK_LOWER_BOUND_INCLUSIVE, restriction.isLowerBoundInclusive() );
+ assertEquals( CHECK_UPPER_BOUND, "1.3", restriction.getUpperBound().toString() );
+ assertFalse( CHECK_UPPER_BOUND_INCLUSIVE, restriction.isUpperBoundInclusive() );
+
+ range1 = VersionRange.createFromVersionSpec( "[1.1,1.3]" );
+ range2 = VersionRange.createFromVersionSpec( "[1.2,)" );
+ mergedRange = range1.restrict( range2 );
+ assertNull( CHECK_VERSION_RECOMMENDATION, mergedRange.getRecommendedVersion() );
+ restrictions = mergedRange.getRestrictions();
+ assertEquals( CHECK_NUM_RESTRICTIONS, 1, restrictions.size() );
+ restriction = restrictions.get( 0 );
+ assertEquals( CHECK_LOWER_BOUND, "1.2", restriction.getLowerBound().toString() );
+ assertTrue( CHECK_LOWER_BOUND_INCLUSIVE, restriction.isLowerBoundInclusive() );
+ assertEquals( CHECK_UPPER_BOUND, "1.3", restriction.getUpperBound().toString() );
+ assertTrue( CHECK_UPPER_BOUND_INCLUSIVE, restriction.isUpperBoundInclusive() );
+
+ range1 = VersionRange.createFromVersionSpec( "(,1.3]" );
+ range2 = VersionRange.createFromVersionSpec( "[1.2,1.4]" );
+ mergedRange = range1.restrict( range2 );
+ assertNull( CHECK_VERSION_RECOMMENDATION, mergedRange.getRecommendedVersion() );
+ restrictions = mergedRange.getRestrictions();
+ assertEquals( CHECK_NUM_RESTRICTIONS, 1, restrictions.size() );
+ restriction = restrictions.get( 0 );
+ assertEquals( CHECK_LOWER_BOUND, "1.2", restriction.getLowerBound().toString() );
+ assertTrue( CHECK_LOWER_BOUND_INCLUSIVE, restriction.isLowerBoundInclusive() );
+ assertEquals( CHECK_UPPER_BOUND, "1.3", restriction.getUpperBound().toString() );
+ assertTrue( CHECK_UPPER_BOUND_INCLUSIVE, restriction.isUpperBoundInclusive() );
+
+ range1 = VersionRange.createFromVersionSpec( "(1.2,1.3]" );
+ range2 = VersionRange.createFromVersionSpec( "[1.1,1.4]" );
+ mergedRange = range1.restrict( range2 );
+ assertNull( CHECK_VERSION_RECOMMENDATION, mergedRange.getRecommendedVersion() );
+ restrictions = mergedRange.getRestrictions();
+ assertEquals( CHECK_NUM_RESTRICTIONS, 1, restrictions.size() );
+ restriction = restrictions.get( 0 );
+ assertEquals( CHECK_LOWER_BOUND, "1.2", restriction.getLowerBound().toString() );
+ assertFalse( CHECK_LOWER_BOUND_INCLUSIVE, restriction.isLowerBoundInclusive() );
+ assertEquals( CHECK_UPPER_BOUND, "1.3", restriction.getUpperBound().toString() );
+ assertTrue( CHECK_UPPER_BOUND_INCLUSIVE, restriction.isUpperBoundInclusive() );
+
+ range1 = VersionRange.createFromVersionSpec( "(1.2,1.3)" );
+ range2 = VersionRange.createFromVersionSpec( "[1.1,1.4]" );
+ mergedRange = range1.restrict( range2 );
+ assertNull( CHECK_VERSION_RECOMMENDATION, mergedRange.getRecommendedVersion() );
+ restrictions = mergedRange.getRestrictions();
+ assertEquals( CHECK_NUM_RESTRICTIONS, 1, restrictions.size() );
+ restriction = restrictions.get( 0 );
+ assertEquals( CHECK_LOWER_BOUND, "1.2", restriction.getLowerBound().toString() );
+ assertFalse( CHECK_LOWER_BOUND_INCLUSIVE, restriction.isLowerBoundInclusive() );
+ assertEquals( CHECK_UPPER_BOUND, "1.3", restriction.getUpperBound().toString() );
+ assertFalse( CHECK_UPPER_BOUND_INCLUSIVE, restriction.isUpperBoundInclusive() );
+
+ range1 = VersionRange.createFromVersionSpec( "[1.2,1.3)" );
+ range2 = VersionRange.createFromVersionSpec( "[1.1,1.4]" );
+ mergedRange = range1.restrict( range2 );
+ assertNull( CHECK_VERSION_RECOMMENDATION, mergedRange.getRecommendedVersion() );
+ restrictions = mergedRange.getRestrictions();
+ assertEquals( CHECK_NUM_RESTRICTIONS, 1, restrictions.size() );
+ restriction = restrictions.get( 0 );
+ assertEquals( CHECK_LOWER_BOUND, "1.2", restriction.getLowerBound().toString() );
+ assertTrue( CHECK_LOWER_BOUND_INCLUSIVE, restriction.isLowerBoundInclusive() );
+ assertEquals( CHECK_UPPER_BOUND, "1.3", restriction.getUpperBound().toString() );
+ assertFalse( CHECK_UPPER_BOUND_INCLUSIVE, restriction.isUpperBoundInclusive() );
+
+ range1 = VersionRange.createFromVersionSpec( "[1.0,1.1]" );
+ range2 = VersionRange.createFromVersionSpec( "[1.1,1.4]" );
+ mergedRange = range1.restrict( range2 );
+ assertNull( CHECK_VERSION_RECOMMENDATION, mergedRange.getRecommendedVersion() );
+ restrictions = mergedRange.getRestrictions();
+ assertEquals( CHECK_NUM_RESTRICTIONS, 1, restrictions.size() );
+ restriction = restrictions.get( 0 );
+ assertEquals( CHECK_LOWER_BOUND, "1.1", restriction.getLowerBound().toString() );
+ assertTrue( CHECK_LOWER_BOUND_INCLUSIVE, restriction.isLowerBoundInclusive() );
+ assertEquals( CHECK_UPPER_BOUND, "1.1", restriction.getUpperBound().toString() );
+ assertTrue( CHECK_UPPER_BOUND_INCLUSIVE, restriction.isUpperBoundInclusive() );
+
+ range1 = VersionRange.createFromVersionSpec( "[1.0,1.1)" );
+ range2 = VersionRange.createFromVersionSpec( "[1.1,1.4]" );
+ mergedRange = range1.restrict( range2 );
+ assertNull( CHECK_VERSION_RECOMMENDATION, mergedRange.getRecommendedVersion() );
+ restrictions = mergedRange.getRestrictions();
+ assertEquals( CHECK_NUM_RESTRICTIONS, 0, restrictions.size() );
+
+ range1 = VersionRange.createFromVersionSpec( "[1.0,1.2],[1.3,1.5]" );
+ range2 = VersionRange.createFromVersionSpec( "[1.1]" );
+ mergedRange = range1.restrict( range2 );
+ assertNull( CHECK_VERSION_RECOMMENDATION, mergedRange.getRecommendedVersion() );
+ restrictions = mergedRange.getRestrictions();
+ assertEquals( CHECK_NUM_RESTRICTIONS, 1, restrictions.size() );
+ restriction = restrictions.get( 0 );
+ assertEquals( CHECK_LOWER_BOUND, "1.1", restriction.getLowerBound().toString() );
+ assertTrue( CHECK_LOWER_BOUND_INCLUSIVE, restriction.isLowerBoundInclusive() );
+ assertEquals( CHECK_UPPER_BOUND, "1.1", restriction.getUpperBound().toString() );
+ assertTrue( CHECK_UPPER_BOUND_INCLUSIVE, restriction.isUpperBoundInclusive() );
+
+ range1 = VersionRange.createFromVersionSpec( "[1.0,1.2],[1.3,1.5]" );
+ range2 = VersionRange.createFromVersionSpec( "[1.4]" );
+ mergedRange = range1.restrict( range2 );
+ assertNull( CHECK_VERSION_RECOMMENDATION, mergedRange.getRecommendedVersion() );
+ restrictions = mergedRange.getRestrictions();
+ assertEquals( CHECK_NUM_RESTRICTIONS, 1, restrictions.size() );
+ restriction = restrictions.get( 0 );
+ assertEquals( CHECK_LOWER_BOUND, "1.4", restriction.getLowerBound().toString() );
+ assertTrue( CHECK_LOWER_BOUND_INCLUSIVE, restriction.isLowerBoundInclusive() );
+ assertEquals( CHECK_UPPER_BOUND, "1.4", restriction.getUpperBound().toString() );
+ assertTrue( CHECK_UPPER_BOUND_INCLUSIVE, restriction.isUpperBoundInclusive() );
+
+ range1 = VersionRange.createFromVersionSpec( "[1.0,1.2],[1.3,1.5]" );
+ range2 = VersionRange.createFromVersionSpec( "[1.1,1.4]" );
+ mergedRange = range1.restrict( range2 );
+ assertNull( CHECK_VERSION_RECOMMENDATION, mergedRange.getRecommendedVersion() );
+ restrictions = mergedRange.getRestrictions();
+ assertEquals( CHECK_NUM_RESTRICTIONS, 2, restrictions.size() );
+ restriction = restrictions.get( 0 );
+ assertEquals( CHECK_LOWER_BOUND, "1.1", restriction.getLowerBound().toString() );
+ assertTrue( CHECK_LOWER_BOUND_INCLUSIVE, restriction.isLowerBoundInclusive() );
+ assertEquals( CHECK_UPPER_BOUND, "1.2", restriction.getUpperBound().toString() );
+ assertTrue( CHECK_UPPER_BOUND_INCLUSIVE, restriction.isUpperBoundInclusive() );
+ restriction = restrictions.get( 1 );
+ assertEquals( CHECK_LOWER_BOUND, "1.3", restriction.getLowerBound().toString() );
+ assertTrue( CHECK_LOWER_BOUND_INCLUSIVE, restriction.isLowerBoundInclusive() );
+ assertEquals( CHECK_UPPER_BOUND, "1.4", restriction.getUpperBound().toString() );
+ assertTrue( CHECK_UPPER_BOUND_INCLUSIVE, restriction.isUpperBoundInclusive() );
+
+ range1 = VersionRange.createFromVersionSpec( "[1.0,1.2),(1.3,1.5]" );
+ range2 = VersionRange.createFromVersionSpec( "[1.1,1.4]" );
+ mergedRange = range1.restrict( range2 );
+ assertNull( CHECK_VERSION_RECOMMENDATION, mergedRange.getRecommendedVersion() );
+ restrictions = mergedRange.getRestrictions();
+ assertEquals( CHECK_NUM_RESTRICTIONS, 2, restrictions.size() );
+ restriction = restrictions.get( 0 );
+ assertEquals( CHECK_LOWER_BOUND, "1.1", restriction.getLowerBound().toString() );
+ assertTrue( CHECK_LOWER_BOUND_INCLUSIVE, restriction.isLowerBoundInclusive() );
+ assertEquals( CHECK_UPPER_BOUND, "1.2", restriction.getUpperBound().toString() );
+ assertFalse( CHECK_UPPER_BOUND_INCLUSIVE, restriction.isUpperBoundInclusive() );
+ restriction = restrictions.get( 1 );
+ assertEquals( CHECK_LOWER_BOUND, "1.3", restriction.getLowerBound().toString() );
+ assertFalse( CHECK_LOWER_BOUND_INCLUSIVE, restriction.isLowerBoundInclusive() );
+ assertEquals( CHECK_UPPER_BOUND, "1.4", restriction.getUpperBound().toString() );
+ assertTrue( CHECK_UPPER_BOUND_INCLUSIVE, restriction.isUpperBoundInclusive() );
+
+ range1 = VersionRange.createFromVersionSpec( "[1.0,1.2],[1.3,1.5]" );
+ range2 = VersionRange.createFromVersionSpec( "(1.1,1.4)" );
+ mergedRange = range1.restrict( range2 );
+ assertNull( CHECK_VERSION_RECOMMENDATION, mergedRange.getRecommendedVersion() );
+ restrictions = mergedRange.getRestrictions();
+ assertEquals( CHECK_NUM_RESTRICTIONS, 2, restrictions.size() );
+ restriction = restrictions.get( 0 );
+ assertEquals( CHECK_LOWER_BOUND, "1.1", restriction.getLowerBound().toString() );
+ assertFalse( CHECK_LOWER_BOUND_INCLUSIVE, restriction.isLowerBoundInclusive() );
+ assertEquals( CHECK_UPPER_BOUND, "1.2", restriction.getUpperBound().toString() );
+ assertTrue( CHECK_UPPER_BOUND_INCLUSIVE, restriction.isUpperBoundInclusive() );
+ restriction = restrictions.get( 1 );
+ assertEquals( CHECK_LOWER_BOUND, "1.3", restriction.getLowerBound().toString() );
+ assertTrue( CHECK_LOWER_BOUND_INCLUSIVE, restriction.isLowerBoundInclusive() );
+ assertEquals( CHECK_UPPER_BOUND, "1.4", restriction.getUpperBound().toString() );
+ assertFalse( CHECK_UPPER_BOUND_INCLUSIVE, restriction.isUpperBoundInclusive() );
+
+ range1 = VersionRange.createFromVersionSpec( "[1.0,1.2),(1.3,1.5]" );
+ range2 = VersionRange.createFromVersionSpec( "(1.1,1.4)" );
+ mergedRange = range1.restrict( range2 );
+ assertNull( CHECK_VERSION_RECOMMENDATION, mergedRange.getRecommendedVersion() );
+ restrictions = mergedRange.getRestrictions();
+ assertEquals( CHECK_NUM_RESTRICTIONS, 2, restrictions.size() );
+ restriction = restrictions.get( 0 );
+ assertEquals( CHECK_LOWER_BOUND, "1.1", restriction.getLowerBound().toString() );
+ assertFalse( CHECK_LOWER_BOUND_INCLUSIVE, restriction.isLowerBoundInclusive() );
+ assertEquals( CHECK_UPPER_BOUND, "1.2", restriction.getUpperBound().toString() );
+ assertFalse( CHECK_UPPER_BOUND_INCLUSIVE, restriction.isUpperBoundInclusive() );
+ restriction = restrictions.get( 1 );
+ assertEquals( CHECK_LOWER_BOUND, "1.3", restriction.getLowerBound().toString() );
+ assertFalse( CHECK_LOWER_BOUND_INCLUSIVE, restriction.isLowerBoundInclusive() );
+ assertEquals( CHECK_UPPER_BOUND, "1.4", restriction.getUpperBound().toString() );
+ assertFalse( CHECK_UPPER_BOUND_INCLUSIVE, restriction.isUpperBoundInclusive() );
+
+ range1 = VersionRange.createFromVersionSpec( "(,1.1),(1.4,)" );
+ range2 = VersionRange.createFromVersionSpec( "[1.1,1.4]" );
+ mergedRange = range1.restrict( range2 );
+ assertNull( CHECK_VERSION_RECOMMENDATION, mergedRange.getRecommendedVersion() );
+ restrictions = mergedRange.getRestrictions();
+ assertEquals( CHECK_NUM_RESTRICTIONS, 0, restrictions.size() );
+
+ range1 = VersionRange.createFromVersionSpec( "(,1.1],[1.4,)" );
+ range2 = VersionRange.createFromVersionSpec( "(1.1,1.4)" );
+ mergedRange = range1.restrict( range2 );
+ assertNull( CHECK_VERSION_RECOMMENDATION, mergedRange.getRecommendedVersion() );
+ restrictions = mergedRange.getRestrictions();
+ assertEquals( CHECK_NUM_RESTRICTIONS, 0, restrictions.size() );
+
+ range1 = VersionRange.createFromVersionSpec( "[,1.1],[1.4,]" );
+ range2 = VersionRange.createFromVersionSpec( "[1.2,1.3]" );
+ mergedRange = range1.restrict( range2 );
+ assertNull( CHECK_VERSION_RECOMMENDATION, mergedRange.getRecommendedVersion() );
+ restrictions = mergedRange.getRestrictions();
+ assertEquals( CHECK_NUM_RESTRICTIONS, 0, restrictions.size() );
+
+ range1 = VersionRange.createFromVersionSpec( "[1.0,1.2],[1.3,1.5]" );
+ range2 = VersionRange.createFromVersionSpec( "[1.1,1.4],[1.6,]" );
+ mergedRange = range1.restrict( range2 );
+ assertNull( CHECK_VERSION_RECOMMENDATION, mergedRange.getRecommendedVersion() );
+ restrictions = mergedRange.getRestrictions();
+ assertEquals( CHECK_NUM_RESTRICTIONS, 2, restrictions.size() );
+ restriction = restrictions.get( 0 );
+ assertEquals( CHECK_LOWER_BOUND, "1.1", restriction.getLowerBound().toString() );
+ assertTrue( CHECK_LOWER_BOUND_INCLUSIVE, restriction.isLowerBoundInclusive() );
+ assertEquals( CHECK_UPPER_BOUND, "1.2", restriction.getUpperBound().toString() );
+ assertTrue( CHECK_UPPER_BOUND_INCLUSIVE, restriction.isUpperBoundInclusive() );
+ restriction = restrictions.get( 1 );
+ assertEquals( CHECK_LOWER_BOUND, "1.3", restriction.getLowerBound().toString() );
+ assertTrue( CHECK_LOWER_BOUND_INCLUSIVE, restriction.isLowerBoundInclusive() );
+ assertEquals( CHECK_UPPER_BOUND, "1.4", restriction.getUpperBound().toString() );
+ assertTrue( CHECK_UPPER_BOUND_INCLUSIVE, restriction.isUpperBoundInclusive() );
+
+ range1 = VersionRange.createFromVersionSpec( "[1.0,1.2],[1.3,1.5]" );
+ range2 = VersionRange.createFromVersionSpec( "[1.1,1.4],[1.5,]" );
+ mergedRange = range1.restrict( range2 );
+ assertNull( CHECK_VERSION_RECOMMENDATION, mergedRange.getRecommendedVersion() );
+ restrictions = mergedRange.getRestrictions();
+ assertEquals( CHECK_NUM_RESTRICTIONS, 3, restrictions.size() );
+ restriction = restrictions.get( 0 );
+ assertEquals( CHECK_LOWER_BOUND, "1.1", restriction.getLowerBound().toString() );
+ assertTrue( CHECK_LOWER_BOUND_INCLUSIVE, restriction.isLowerBoundInclusive() );
+ assertEquals( CHECK_UPPER_BOUND, "1.2", restriction.getUpperBound().toString() );
+ assertTrue( CHECK_UPPER_BOUND_INCLUSIVE, restriction.isUpperBoundInclusive() );
+ restriction = restrictions.get( 1 );
+ assertEquals( CHECK_LOWER_BOUND, "1.3", restriction.getLowerBound().toString() );
+ assertTrue( CHECK_LOWER_BOUND_INCLUSIVE, restriction.isLowerBoundInclusive() );
+ assertEquals( CHECK_UPPER_BOUND, "1.4", restriction.getUpperBound().toString() );
+ assertTrue( CHECK_UPPER_BOUND_INCLUSIVE, restriction.isUpperBoundInclusive() );
+ restriction = restrictions.get( 2 );
+ assertEquals( CHECK_LOWER_BOUND, "1.5", restriction.getLowerBound().toString() );
+ assertTrue( CHECK_LOWER_BOUND_INCLUSIVE, restriction.isLowerBoundInclusive() );
+ assertEquals( CHECK_UPPER_BOUND, "1.5", restriction.getUpperBound().toString() );
+ assertTrue( CHECK_UPPER_BOUND_INCLUSIVE, restriction.isUpperBoundInclusive() );
+
+ range1 = VersionRange.createFromVersionSpec( "[1.0,1.2],[1.3,1.7]" );
+ range2 = VersionRange.createFromVersionSpec( "[1.1,1.4],[1.5,1.6]" );
+ mergedRange = range1.restrict( range2 );
+ assertNull( CHECK_VERSION_RECOMMENDATION, mergedRange.getRecommendedVersion() );
+ restrictions = mergedRange.getRestrictions();
+ assertEquals( CHECK_NUM_RESTRICTIONS, 3, restrictions.size() );
+ restriction = restrictions.get( 0 );
+ assertEquals( CHECK_LOWER_BOUND, "1.1", restriction.getLowerBound().toString() );
+ assertTrue( CHECK_LOWER_BOUND_INCLUSIVE, restriction.isLowerBoundInclusive() );
+ assertEquals( CHECK_UPPER_BOUND, "1.2", restriction.getUpperBound().toString() );
+ assertTrue( CHECK_UPPER_BOUND_INCLUSIVE, restriction.isUpperBoundInclusive() );
+ restriction = restrictions.get( 1 );
+ assertEquals( CHECK_LOWER_BOUND, "1.3", restriction.getLowerBound().toString() );
+ assertTrue( CHECK_LOWER_BOUND_INCLUSIVE, restriction.isLowerBoundInclusive() );
+ assertEquals( CHECK_UPPER_BOUND, "1.4", restriction.getUpperBound().toString() );
+ assertTrue( CHECK_UPPER_BOUND_INCLUSIVE, restriction.isUpperBoundInclusive() );
+ restriction = restrictions.get( 2 );
+ assertEquals( CHECK_LOWER_BOUND, "1.5", restriction.getLowerBound().toString() );
+ assertTrue( CHECK_LOWER_BOUND_INCLUSIVE, restriction.isLowerBoundInclusive() );
+ assertEquals( CHECK_UPPER_BOUND, "1.6", restriction.getUpperBound().toString() );
+ assertTrue( CHECK_UPPER_BOUND_INCLUSIVE, restriction.isUpperBoundInclusive() );
+
+ // test restricting empty sets
+ range1 = VersionRange.createFromVersionSpec( "[,1.1],[1.4,]" );
+ range2 = VersionRange.createFromVersionSpec( "[1.2,1.3]" );
+ range1 = range1.restrict( range2 );
+ mergedRange = range1.restrict( range2 );
+ assertNull( CHECK_VERSION_RECOMMENDATION, mergedRange.getRecommendedVersion() );
+ restrictions = mergedRange.getRestrictions();
+ assertEquals( CHECK_NUM_RESTRICTIONS, 0, restrictions.size() );
+
+ range1 = VersionRange.createFromVersionSpec( "[,1.1],[1.4,]" );
+ range2 = VersionRange.createFromVersionSpec( "[1.2,1.3]" );
+ range2 = range1.restrict( range2 );
+ mergedRange = range1.restrict( range2 );
+ assertNull( CHECK_VERSION_RECOMMENDATION, mergedRange.getRecommendedVersion() );
+ restrictions = mergedRange.getRestrictions();
+ assertEquals( CHECK_NUM_RESTRICTIONS, 0, restrictions.size() );
+ }
+
+ public void testReleaseRangeBoundsContainsSnapshots()
+ throws InvalidVersionSpecificationException
+ {
+ VersionRange range = VersionRange.createFromVersionSpec( "[1.0,1.2]" );
+
+ assertTrue( range.containsVersion( new DefaultArtifactVersion( "1.1-SNAPSHOT" ) ) );
+ assertTrue( range.containsVersion( new DefaultArtifactVersion( "1.2-SNAPSHOT" ) ) );
+ assertFalse( range.containsVersion( new DefaultArtifactVersion( "1.0-SNAPSHOT" ) ) );
+ }
+
+ public void testSnapshotRangeBoundsCanContainSnapshots()
+ throws InvalidVersionSpecificationException
+ {
+ VersionRange range = VersionRange.createFromVersionSpec( "[1.0,1.2-SNAPSHOT]" );
+
+ assertTrue( range.containsVersion( new DefaultArtifactVersion( "1.1-SNAPSHOT" ) ) );
+ assertTrue( range.containsVersion( new DefaultArtifactVersion( "1.2-SNAPSHOT" ) ) );
+
+ range = VersionRange.createFromVersionSpec( "[1.0-SNAPSHOT,1.2]" );
+
+ assertTrue( range.containsVersion( new DefaultArtifactVersion( "1.0-SNAPSHOT" ) ) );
+ assertTrue( range.containsVersion( new DefaultArtifactVersion( "1.1-SNAPSHOT" ) ) );
+ }
+
+ public void testSnapshotSoftVersionCanContainSnapshot()
+ throws InvalidVersionSpecificationException
+ {
+ VersionRange range = VersionRange.createFromVersionSpec( "1.0-SNAPSHOT" );
+
+ assertTrue( range.containsVersion( new DefaultArtifactVersion( "1.0-SNAPSHOT" ) ) );
+ }
+
+ private void checkInvalidRange( String version )
+ {
+ try
+ {
+ VersionRange.createFromVersionSpec( version );
+ fail( "Version " + version + " should have failed to construct" );
+ }
+ catch ( InvalidVersionSpecificationException expected )
+ {
+ // expected
+ }
+ }
+
+ public void testContains() throws InvalidVersionSpecificationException
+ {
+ ArtifactVersion actualVersion = new DefaultArtifactVersion( "2.0.5" );
+ assertTrue( enforceVersion( "2.0.5", actualVersion ) );
+ assertTrue( enforceVersion( "2.0.4", actualVersion ) );
+ assertTrue( enforceVersion( "[2.0.5]", actualVersion ) );
+ assertFalse( enforceVersion( "[2.0.6,)", actualVersion ) );
+ assertFalse( enforceVersion( "[2.0.6]", actualVersion ) );
+ assertTrue( enforceVersion( "[2.0,2.1]", actualVersion ) );
+ assertFalse( enforceVersion( "[2.0,2.0.3]", actualVersion ) );
+ assertTrue( enforceVersion( "[2.0,2.0.5]", actualVersion ) );
+ assertFalse( enforceVersion( "[2.0,2.0.5)", actualVersion ) );
+ }
+
+ public boolean enforceVersion( String requiredVersionRange, ArtifactVersion actualVersion )
+ throws InvalidVersionSpecificationException
+ {
+ VersionRange vr = null;
+
+ vr = VersionRange.createFromVersionSpec( requiredVersionRange );
+
+ return vr.containsVersion( actualVersion );
+ }
+
+ public void testOrder0()
+ {
+ // assertTrue( new DefaultArtifactVersion( "1.0-alpha10" ).compareTo( new DefaultArtifactVersion( "1.0-alpha1" ) ) > 0 );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-builder-support/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-builder-support/pom.xml
new file mode 100644
index 00000000..791b5e4e
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-builder-support/pom.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven</artifactId>
+ <version>3.3.3</version>
+ </parent>
+
+ <artifactId>maven-builder-support</artifactId>
+
+ <name>Maven Builder Support</name>
+ <description>Support for descriptor builders (model, setting, toolchains)</description>
+
+ <scm><!-- remove when git scm url format can accept artifact-id at the end, as automatically inherited -->
+ <connection>scm:git:https://git-wip-us.apache.org/repos/asf/maven.git</connection>
+ <developerConnection>scm:git:https://git-wip-us.apache.org/repos/asf/maven.git</developerConnection>
+ <tag>maven-3.3.3</tag>
+ </scm>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-utils</artifactId>
+ </dependency>
+ </dependencies>
+
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-builder-support/src/main/java/org/apache/maven/building/DefaultProblem.java b/framework/src/maven/apache-maven-3.3.3/maven-builder-support/src/main/java/org/apache/maven/building/DefaultProblem.java
new file mode 100644
index 00000000..ad1fc40f
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-builder-support/src/main/java/org/apache/maven/building/DefaultProblem.java
@@ -0,0 +1,161 @@
+package org.apache.maven.building;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Describes a problem that was encountered during settings building. A problem can either be an exception that was
+ * thrown or a simple string message. In addition, a problem carries a hint about its source, e.g. the settings file
+ * that exhibits the problem.
+ *
+ * @author Benjamin Bentmann
+ * @author Robert Scholte
+ */
+class DefaultProblem
+ implements Problem
+{
+
+ private final String source;
+
+ private final int lineNumber;
+
+ private final int columnNumber;
+
+ private final String message;
+
+ private final Exception exception;
+
+ private final Severity severity;
+
+ /**
+ * Creates a new problem with the specified message and exception.
+ * Either {@code message} or {@code exception} is required
+ *
+ * @param message The message describing the problem, may be {@code null}.
+ * @param severity The severity level of the problem, may be {@code null} to default to
+ * {@link SettingsProblem.Severity#ERROR}.
+ * @param source A hint about the source of the problem like a file path, may be {@code null}.
+ * @param lineNumber The one-based index of the line containing the problem or {@code -1} if unknown.
+ * @param columnNumber The one-based index of the column containing the problem or {@code -1} if unknown.
+ * @param exception The exception that caused this problem, may be {@code null}.
+ */
+ public DefaultProblem( String message, Severity severity, String source, int lineNumber, int columnNumber,
+ Exception exception )
+ {
+ this.message = message;
+ this.severity = ( severity != null ) ? severity : Severity.ERROR;
+ this.source = ( source != null ) ? source : "";
+ this.lineNumber = lineNumber;
+ this.columnNumber = columnNumber;
+ this.exception = exception;
+ }
+
+ public String getSource()
+ {
+ return source;
+ }
+
+ public int getLineNumber()
+ {
+ return lineNumber;
+ }
+
+ public int getColumnNumber()
+ {
+ return columnNumber;
+ }
+
+ public String getLocation()
+ {
+ StringBuilder buffer = new StringBuilder( 256 );
+
+ if ( getSource().length() > 0 )
+ {
+ if ( buffer.length() > 0 )
+ {
+ buffer.append( ", " );
+ }
+ buffer.append( getSource() );
+ }
+
+ if ( getLineNumber() > 0 )
+ {
+ if ( buffer.length() > 0 )
+ {
+ buffer.append( ", " );
+ }
+ buffer.append( "line " ).append( getLineNumber() );
+ }
+
+ if ( getColumnNumber() > 0 )
+ {
+ if ( buffer.length() > 0 )
+ {
+ buffer.append( ", " );
+ }
+ buffer.append( "column " ).append( getColumnNumber() );
+ }
+
+ return buffer.toString();
+ }
+
+ public Exception getException()
+ {
+ return exception;
+ }
+
+ public String getMessage()
+ {
+ String msg;
+
+ if ( message != null && message.length() > 0 )
+ {
+ msg = message;
+ }
+ else
+ {
+ msg = exception.getMessage();
+
+ if ( msg == null )
+ {
+ msg = "";
+ }
+ }
+
+ return msg;
+ }
+
+ public Severity getSeverity()
+ {
+ return severity;
+ }
+
+ @Override
+ public String toString()
+ {
+ StringBuilder buffer = new StringBuilder( 128 );
+
+ buffer.append( "[" ).append( getSeverity() ).append( "] " );
+ buffer.append( getMessage() );
+ buffer.append( " @ " ).append( getLocation() );
+
+ return buffer.toString();
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-builder-support/src/main/java/org/apache/maven/building/DefaultProblemCollector.java b/framework/src/maven/apache-maven-3.3.3/maven-builder-support/src/main/java/org/apache/maven/building/DefaultProblemCollector.java
new file mode 100644
index 00000000..567f620e
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-builder-support/src/main/java/org/apache/maven/building/DefaultProblemCollector.java
@@ -0,0 +1,64 @@
+package org.apache.maven.building;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Collects problems that are encountered during settings building.
+ *
+ * @author Benjamin Bentmann
+ * @author Robert Scholte
+ */
+class DefaultProblemCollector
+ implements ProblemCollector
+{
+
+ private List<Problem> problems;
+
+ private String source;
+
+ public DefaultProblemCollector( List<Problem> problems )
+ {
+ this.problems = ( problems != null ) ? problems : new ArrayList<Problem>();
+ }
+
+ @Override
+ public List<Problem> getProblems()
+ {
+ return problems;
+ }
+
+ @Override
+ public void setSource( String source )
+ {
+ this.source = source;
+ }
+
+ @Override
+ public void add( Problem.Severity severity, String message, int line, int column, Exception cause )
+ {
+ Problem problem = new DefaultProblem( message, severity, source, line, column, cause );
+
+ problems.add( problem );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-builder-support/src/main/java/org/apache/maven/building/FileSource.java b/framework/src/maven/apache-maven-3.3.3/maven-builder-support/src/main/java/org/apache/maven/building/FileSource.java
new file mode 100644
index 00000000..1a6fc2f4
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-builder-support/src/main/java/org/apache/maven/building/FileSource.java
@@ -0,0 +1,79 @@
+package org.apache.maven.building;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Wraps an ordinary {@link File} as a source.
+ *
+ * @author Benjamin Bentmann
+ */
+public class FileSource
+ implements Source
+{
+ private final File file;
+
+ /**
+ * Creates a new source backed by the specified file.
+ *
+ * @param file The file, must not be {@code null}.
+ */
+ public FileSource( File file )
+ {
+ if ( file == null )
+ {
+ throw new IllegalArgumentException( "no file specified" );
+ }
+ this.file = file.getAbsoluteFile();
+ }
+
+ @Override
+ public InputStream getInputStream()
+ throws IOException
+ {
+ return new FileInputStream( file );
+ }
+
+ @Override
+ public String getLocation()
+ {
+ return file.getPath();
+ }
+
+ /**
+ * Gets the file of this source.
+ *
+ * @return The underlying file, never {@code null}.
+ */
+ public File getFile()
+ {
+ return file;
+ }
+
+ @Override
+ public String toString()
+ {
+ return getLocation();
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-builder-support/src/main/java/org/apache/maven/building/Problem.java b/framework/src/maven/apache-maven-3.3.3/maven-builder-support/src/main/java/org/apache/maven/building/Problem.java
new file mode 100644
index 00000000..9ab9b3a8
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-builder-support/src/main/java/org/apache/maven/building/Problem.java
@@ -0,0 +1,101 @@
+package org.apache.maven.building;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Describes a problem that was encountered during settings building. A problem can either be an exception that was
+ * thrown or a simple string message. In addition, a problem carries a hint about its source, e.g. the settings file
+ * that exhibits the problem.
+ *
+ * @author Benjamin Bentmann
+ * @author Robert Scholte
+ */
+public interface Problem
+{
+
+ /**
+ * The different severity levels for a problem, in decreasing order.
+ */
+ enum Severity
+ {
+
+ FATAL, //
+ ERROR, //
+ WARNING //
+
+ }
+
+ /**
+ * Gets the hint about the source of the problem. While the syntax of this hint is unspecified and depends on the
+ * creator of the problem, the general expectation is that the hint provides sufficient information to the user to
+ * track the problem back to its origin. A concrete example for such a source hint can be the file path or URL from
+ * which the settings were read.
+ *
+ * @return The hint about the source of the problem or an empty string if unknown, never {@code null}.
+ */
+ String getSource();
+
+ /**
+ * Gets the one-based index of the line containing the problem. The line number should refer to some text file that
+ * is given by {@link #getSource()}.
+ *
+ * @return The one-based index of the line containing the problem or a non-positive value if unknown.
+ */
+ int getLineNumber();
+
+ /**
+ * Gets the one-based index of the column containing the problem. The column number should refer to some text file
+ * that is given by {@link #getSource()}.
+ *
+ * @return The one-based index of the column containing the problem or non-positive value if unknown.
+ */
+ int getColumnNumber();
+
+ /**
+ * Gets the location of the problem. The location is a user-friendly combination of the values from
+ * {@link #getSource()}, {@link #getLineNumber()} and {@link #getColumnNumber()}. The exact syntax of the returned
+ * value is undefined.
+ *
+ * @return The location of the problem, never {@code null}.
+ */
+ String getLocation();
+
+ /**
+ * Gets the exception that caused this problem (if any).
+ *
+ * @return The exception that caused this problem or {@code null} if not applicable.
+ */
+ Exception getException();
+
+ /**
+ * Gets the message that describes this problem.
+ *
+ * @return The message describing this problem, never {@code null}.
+ */
+ String getMessage();
+
+ /**
+ * Gets the severity level of this problem.
+ *
+ * @return The severity level of this problem, never {@code null}.
+ */
+ Severity getSeverity();
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-builder-support/src/main/java/org/apache/maven/building/ProblemCollector.java b/framework/src/maven/apache-maven-3.3.3/maven-builder-support/src/main/java/org/apache/maven/building/ProblemCollector.java
new file mode 100644
index 00000000..e7015676
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-builder-support/src/main/java/org/apache/maven/building/ProblemCollector.java
@@ -0,0 +1,59 @@
+package org.apache.maven.building;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.List;
+
+/**
+ * Collects problems that are encountered during settings building.
+ *
+ * @author Benjamin Bentmann
+ * @author Robert Scholte
+ */
+public interface ProblemCollector
+{
+
+ /**
+ * Adds the specified problem.
+ * Either message or exception is required
+ *
+ * @param severity The severity of the problem, must not be {@code null}.
+ * @param message The detail message of the problem, may be {@code null}.
+ * @param line The one-based index of the line containing the problem or {@code -1} if unknown.
+ * @param column The one-based index of the column containing the problem or {@code -1} if unknown.
+ * @param cause The cause of the problem, may be {@code null}.
+ */
+ void add( Problem.Severity severity, String message, int line, int column, Exception cause );
+
+ /**
+ * The next messages will be bound to this source. When calling this method again, previous messages keep
+ * their source, but the next messages will use the new source.
+ *
+ * @param source
+ */
+ void setSource( String source );
+
+ /**
+ *
+ * @return the collected Problems, never {@code null}
+ */
+ List<Problem> getProblems();
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-builder-support/src/main/java/org/apache/maven/building/ProblemCollectorFactory.java b/framework/src/maven/apache-maven-3.3.3/maven-builder-support/src/main/java/org/apache/maven/building/ProblemCollectorFactory.java
new file mode 100644
index 00000000..c1c23737
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-builder-support/src/main/java/org/apache/maven/building/ProblemCollectorFactory.java
@@ -0,0 +1,43 @@
+package org.apache.maven.building;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.List;
+
+/**
+ *
+ * @author Robert Scholte
+ * @since 3.3.0
+ */
+public class ProblemCollectorFactory
+{
+
+ /**
+ * The default implementation is not visible, create it with this factory
+ *
+ * @param problems starting set of problems, may be {@code null}
+ * @return a new instance of a ProblemCollector
+ */
+ public static ProblemCollector newInstance( List<Problem> problems )
+ {
+ return new DefaultProblemCollector( problems );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-builder-support/src/main/java/org/apache/maven/building/Source.java b/framework/src/maven/apache-maven-3.3.3/maven-builder-support/src/main/java/org/apache/maven/building/Source.java
new file mode 100644
index 00000000..1f7510ba
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-builder-support/src/main/java/org/apache/maven/building/Source.java
@@ -0,0 +1,49 @@
+package org.apache.maven.building;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Provides access to the contents of a source independently of the backing store (e.g. file system, database, memory).
+ *
+ * @author Benjamin Bentmann
+ */
+public interface Source
+{
+
+ /**
+ * Gets a byte stream to the source contents. Closing the returned stream is the responsibility of the caller.
+ *
+ * @return A byte stream to the source contents, never {@code null}.
+ */
+ InputStream getInputStream()
+ throws IOException;
+
+ /**
+ * Provides a user-friendly hint about the location of the source. This could be a local file path, a URI or just an
+ * empty string. The intention is to assist users during error reporting.
+ *
+ * @return A user-friendly hint about the location of the source, never {@code null}.
+ */
+ String getLocation();
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-builder-support/src/main/java/org/apache/maven/building/StringSource.java b/framework/src/maven/apache-maven-3.3.3/maven-builder-support/src/main/java/org/apache/maven/building/StringSource.java
new file mode 100644
index 00000000..f9d87c0b
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-builder-support/src/main/java/org/apache/maven/building/StringSource.java
@@ -0,0 +1,90 @@
+package org.apache.maven.building;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Wraps an ordinary {@link CharSequence} as a source.
+ *
+ * @author Benjamin Bentmann
+ */
+public class StringSource
+ implements Source
+{
+
+ private String content;
+
+ private String location;
+
+ /**
+ * Creates a new source backed by the specified string.
+ *
+ * @param content The String representation, may be empty or {@code null}.
+ */
+ public StringSource( CharSequence content )
+ {
+ this( content, null );
+ }
+
+ /**
+ * Creates a new source backed by the specified string.
+ *
+ * @param content The String representation, may be empty or {@code null}.
+ * @param location The location to report for this use, may be {@code null}.
+ */
+ public StringSource( CharSequence content, String location )
+ {
+ this.content = ( content != null ) ? content.toString() : "";
+ this.location = ( location != null ) ? location : "(memory)";
+ }
+
+ @Override
+ public InputStream getInputStream()
+ throws IOException
+ {
+ return new ByteArrayInputStream( content.getBytes( "UTF-8" ) );
+ }
+
+ @Override
+ public String getLocation()
+ {
+ return location;
+ }
+
+ /**
+ * Gets the content of this source.
+ *
+ * @return The underlying character stream, never {@code null}.
+ */
+ public String getContent()
+ {
+ return content;
+ }
+
+ @Override
+ public String toString()
+ {
+ return getLocation();
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-builder-support/src/main/java/org/apache/maven/building/UrlSource.java b/framework/src/maven/apache-maven-3.3.3/maven-builder-support/src/main/java/org/apache/maven/building/UrlSource.java
new file mode 100644
index 00000000..7bd3e3c3
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-builder-support/src/main/java/org/apache/maven/building/UrlSource.java
@@ -0,0 +1,80 @@
+package org.apache.maven.building;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+
+/**
+ * Wraps an ordinary {@link URL} as a source.
+ *
+ * @author Benjamin Bentmann
+ */
+public class UrlSource
+ implements Source
+{
+
+ private URL url;
+
+ /**
+ * Creates a new source backed by the specified URL.
+ *
+ * @param url The file, must not be {@code null}.
+ */
+ public UrlSource( URL url )
+ {
+ if ( url == null )
+ {
+ throw new IllegalArgumentException( "no url specified" );
+ }
+ this.url = url;
+ }
+
+ @Override
+ public InputStream getInputStream()
+ throws IOException
+ {
+ return url.openStream();
+ }
+
+ @Override
+ public String getLocation()
+ {
+ return url.toString();
+ }
+
+ /**
+ * Gets the URL of this source.
+ *
+ * @return The underlying URL, never {@code null}.
+ */
+ public URL getUrl()
+ {
+ return url;
+ }
+
+ @Override
+ public String toString()
+ {
+ return getLocation();
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-builder-support/src/site/site.xml b/framework/src/maven/apache-maven-3.3.3/maven-builder-support/src/site/site.xml
new file mode 100644
index 00000000..3a16bf98
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-builder-support/src/site/site.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project xmlns="http://maven.apache.org/DECORATION/1.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/DECORATION/1.0.0 http://maven.apache.org/xsd/decoration-1.0.0.xsd">
+ <body>
+ <menu name="Overview">
+ <item name="Introduction" href="index.html"/>
+ <item name="JavaDocs" href="apidocs/index.html"/>
+ <item name="Source Xref" href="xref/index.html"/>
+ <!--item name="FAQ" href="faq.html"/-->
+ </menu>
+
+ <menu ref="parent"/>
+ <menu ref="reports"/>
+ </body>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-builder-support/src/test/java/org/apache/maven/building/DefaultProblemCollectorTest.java b/framework/src/maven/apache-maven-3.3.3/maven-builder-support/src/test/java/org/apache/maven/building/DefaultProblemCollectorTest.java
new file mode 100644
index 00000000..bf0f8477
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-builder-support/src/test/java/org/apache/maven/building/DefaultProblemCollectorTest.java
@@ -0,0 +1,76 @@
+package org.apache.maven.building;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import static org.junit.Assert.*;
+
+import org.apache.maven.building.Problem.Severity;
+import org.junit.Test;
+
+public class DefaultProblemCollectorTest
+{
+
+ @Test
+ public void testGetProblems()
+ {
+ DefaultProblemCollector collector = new DefaultProblemCollector( null );
+ assertNotNull( collector.getProblems() );
+ assertEquals( 0, collector.getProblems().size() );
+
+ collector.add( null, "MESSAGE1", -1, -1, null );
+
+ Exception e2 = new Exception();
+ collector.add( Severity.WARNING, null, 42, 127, e2 );
+
+ assertEquals( 2, collector.getProblems().size() );
+
+ Problem p1 = collector.getProblems().get(0);
+ assertEquals( Severity.ERROR, p1.getSeverity() );
+ assertEquals( "MESSAGE1",p1.getMessage() );
+ assertEquals( -1, p1.getLineNumber() );
+ assertEquals( -1, p1.getColumnNumber() );
+ assertEquals( null, p1.getException() );
+
+ Problem p2 = collector.getProblems().get(1);
+ assertEquals( Severity.WARNING, p2.getSeverity() );
+ assertEquals( "",p2.getMessage() );
+ assertEquals( 42, p2.getLineNumber() );
+ assertEquals( 127, p2.getColumnNumber() );
+ assertEquals( e2, p2.getException() );
+ }
+
+ @Test
+ public void testSetSource()
+ {
+ DefaultProblemCollector collector = new DefaultProblemCollector( null );
+
+ collector.add( null, "PROBLEM1", -1, -1, null );
+
+ collector.setSource( "SOURCE_PROBLEM2" );
+ collector.add( null, "PROBLEM2", -1, -1, null );
+
+ collector.setSource( "SOURCE_PROBLEM3" );
+ collector.add( null, "PROBLEM3", -1, -1, null );
+
+ assertEquals( "", collector.getProblems().get( 0 ).getSource() );
+ assertEquals( "SOURCE_PROBLEM2", collector.getProblems().get( 1 ).getSource() );
+ assertEquals( "SOURCE_PROBLEM3", collector.getProblems().get( 2 ).getSource() );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-builder-support/src/test/java/org/apache/maven/building/DefaultProblemTest.java b/framework/src/maven/apache-maven-3.3.3/maven-builder-support/src/test/java/org/apache/maven/building/DefaultProblemTest.java
new file mode 100644
index 00000000..80a20da9
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-builder-support/src/test/java/org/apache/maven/building/DefaultProblemTest.java
@@ -0,0 +1,136 @@
+package org.apache.maven.building;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertSame;
+
+import org.apache.maven.building.Problem.Severity;
+import org.junit.Test;
+
+public class DefaultProblemTest
+{
+
+ @Test
+ public void testGetSeverity()
+ {
+ DefaultProblem problem = new DefaultProblem( null, null, null, -1, -1, null );
+ assertEquals( Severity.ERROR, problem.getSeverity() );
+
+ problem = new DefaultProblem( null, Severity.FATAL, null, -1, -1, null );
+ assertEquals( Severity.FATAL, problem.getSeverity() );
+
+ problem = new DefaultProblem( null, Severity.ERROR, null, -1, -1, null );
+ assertEquals( Severity.ERROR, problem.getSeverity() );
+
+ problem = new DefaultProblem( null, Severity.WARNING, null, -1, -1, null );
+ assertEquals( Severity.WARNING, problem.getSeverity() );
+ }
+
+ @Test
+ public void testGetLineNumber()
+ {
+ DefaultProblem problem = new DefaultProblem( null, null, null, -1, -1, null );
+ assertEquals( -1, problem.getLineNumber() );
+
+ problem = new DefaultProblem( null, null, null, 42, -1, null );
+ assertEquals( 42, problem.getLineNumber() );
+
+ problem = new DefaultProblem( null, null, null, Integer.MAX_VALUE, -1, null );
+ assertEquals( Integer.MAX_VALUE, problem.getLineNumber() );
+
+ // this case is not specified, might also return -1
+ problem = new DefaultProblem( null, null, null, Integer.MIN_VALUE, -1, null );
+ assertEquals( Integer.MIN_VALUE, problem.getLineNumber() );
+ }
+
+ @Test
+ public void testGetColumnNumber()
+ {
+ DefaultProblem problem = new DefaultProblem( null, null, null, -1, -1, null );
+ assertEquals( -1, problem.getColumnNumber() );
+
+ problem = new DefaultProblem( null, null, null, -1, 42, null );
+ assertEquals( 42, problem.getColumnNumber() );
+
+ problem = new DefaultProblem( null, null, null, -1, Integer.MAX_VALUE, null );
+ assertEquals( Integer.MAX_VALUE, problem.getColumnNumber() );
+
+ // this case is not specified, might also return -1
+ problem = new DefaultProblem( null, null, null, -1, Integer.MIN_VALUE, null );
+ assertEquals( Integer.MIN_VALUE, problem.getColumnNumber() );
+ }
+
+ @Test
+ public void testGetException()
+ {
+ DefaultProblem problem = new DefaultProblem( null, null, null, -1, -1, null );
+ assertEquals( null, problem.getException() );
+
+ Exception e = new Exception();
+ problem = new DefaultProblem( null, null, null, -1, -1, e );
+ assertSame( e, problem.getException() );
+ }
+
+ @Test
+ public void testGetSource()
+ {
+ DefaultProblem problem = new DefaultProblem( null, null, null, -1, -1, null );
+ assertEquals( "", problem.getSource() );
+
+ problem = new DefaultProblem( null, null, "", -1, -1, null );
+ assertEquals( "", problem.getSource() );
+
+ problem = new DefaultProblem( null, null, "SOURCE", -1, -1, null );
+ assertEquals( "SOURCE", problem.getSource() );
+ }
+
+ @Test
+ public void testGetLocation()
+ {
+ DefaultProblem problem = new DefaultProblem( null, null, null, -1, -1, null );
+ assertEquals( "", problem.getLocation() );
+
+ problem = new DefaultProblem( null, null, "SOURCE", -1, -1, null );
+ assertEquals( "SOURCE", problem.getLocation() );
+
+ problem = new DefaultProblem( null, null, null, 42, -1, null );
+ assertEquals( "line 42", problem.getLocation() );
+
+ problem = new DefaultProblem( null, null, null, -1, 127, null );
+ assertEquals( "column 127", problem.getLocation() );
+
+ problem = new DefaultProblem( null, null, "SOURCE", 42, 127, null );
+ assertEquals( "SOURCE, line 42, column 127", problem.getLocation() );
+ }
+
+ @Test
+ public void testGetMessage()
+ {
+ DefaultProblem problem = new DefaultProblem( "MESSAGE", null, null, -1, -1, null );
+ assertEquals( "MESSAGE", problem.getMessage() );
+
+ problem = new DefaultProblem( null, null, null, -1, -1, new Exception() );
+ assertEquals( "", problem.getMessage() );
+
+ problem = new DefaultProblem( null, null, null, -1, -1, new Exception( "EXCEPTION MESSAGE" ) );
+ assertEquals( "EXCEPTION MESSAGE", problem.getMessage() );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-builder-support/src/test/java/org/apache/maven/building/FileSourceTest.java b/framework/src/maven/apache-maven-3.3.3/maven-builder-support/src/test/java/org/apache/maven/building/FileSourceTest.java
new file mode 100644
index 00000000..086adda8
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-builder-support/src/test/java/org/apache/maven/building/FileSourceTest.java
@@ -0,0 +1,93 @@
+package org.apache.maven.building;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import java.io.File;
+import java.io.InputStream;
+import java.util.Scanner;
+
+import org.junit.Test;
+
+public class FileSourceTest
+{
+
+ @Test
+ public void testFileSource()
+ {
+ try
+ {
+ new FileSource( null );
+ fail( "Should fail, since you must specify a file" );
+ }
+ catch ( IllegalArgumentException e )
+ {
+ assertEquals( "no file specified", e.getMessage() );
+ }
+ }
+
+ @Test
+ public void testGetInputStream()
+ throws Exception
+ {
+ File txtFile = new File( "target/test-classes/source.txt" );
+ FileSource source = new FileSource( txtFile );
+
+ Scanner scanner = null;
+ InputStream is = null;
+ try
+ {
+ is = source.getInputStream();
+
+ scanner = new Scanner( is );
+ assertEquals( "Hello World!", scanner.nextLine() );
+ }
+ finally
+ {
+ if ( scanner != null )
+ {
+ scanner.close();
+ }
+ if ( is != null )
+ {
+ is.close();
+ }
+ }
+ }
+
+ @Test
+ public void testGetLocation()
+ {
+ File txtFile = new File( "target/test-classes/source.txt" );
+ FileSource source = new FileSource( txtFile );
+ assertEquals( txtFile.getAbsolutePath(), source.getLocation() );
+ }
+
+ @Test
+ public void testGetFile()
+ {
+ File txtFile = new File( "target/test-classes/source.txt" );
+ FileSource source = new FileSource( txtFile );
+ assertEquals( txtFile.getAbsoluteFile(), source.getFile() );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-builder-support/src/test/java/org/apache/maven/building/ProblemCollectorFactoryTest.java b/framework/src/maven/apache-maven-3.3.3/maven-builder-support/src/test/java/org/apache/maven/building/ProblemCollectorFactoryTest.java
new file mode 100644
index 00000000..44c7906c
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-builder-support/src/test/java/org/apache/maven/building/ProblemCollectorFactoryTest.java
@@ -0,0 +1,45 @@
+package org.apache.maven.building;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotSame;
+
+import java.util.Collections;
+
+import org.junit.Test;
+
+public class ProblemCollectorFactoryTest
+{
+
+ @Test
+ public void testNewInstance()
+ {
+ ProblemCollector collector1 = ProblemCollectorFactory.newInstance( null );
+
+ Problem problem = new DefaultProblem( "MESSAGE1", null, null, -1, -1, null );
+ ProblemCollector collector2 = ProblemCollectorFactory.newInstance( Collections.singletonList( problem ) );
+
+ assertNotSame( collector1, collector2 );
+ assertEquals( 0, collector1.getProblems().size() );
+ assertEquals( 1, collector2.getProblems().size() );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-builder-support/src/test/java/org/apache/maven/building/StringSourceTest.java b/framework/src/maven/apache-maven-3.3.3/maven-builder-support/src/test/java/org/apache/maven/building/StringSourceTest.java
new file mode 100644
index 00000000..013b8a4d
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-builder-support/src/test/java/org/apache/maven/building/StringSourceTest.java
@@ -0,0 +1,79 @@
+package org.apache.maven.building;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.InputStream;
+import java.util.Scanner;
+
+import org.junit.Test;
+
+public class StringSourceTest
+{
+ @Test
+ public void testGetInputStream()
+ throws Exception
+ {
+ StringSource source = new StringSource( "Hello World!" );
+
+ Scanner scanner = null;
+ InputStream is = null;
+ try
+ {
+ is = source.getInputStream();
+
+ scanner = new Scanner( is );
+ assertEquals( "Hello World!", scanner.nextLine() );
+ }
+ finally
+ {
+ if ( scanner != null )
+ {
+ scanner.close();
+ }
+ if ( is != null )
+ {
+ is.close();
+ }
+ }
+ }
+
+ @Test
+ public void testGetLocation()
+ {
+ StringSource source = new StringSource( "Hello World!" );
+ assertEquals( "(memory)", source.getLocation() );
+
+ source = new StringSource( "Hello World!", "LOCATION" );
+ assertEquals( "LOCATION", source.getLocation() );
+ }
+
+ @Test
+ public void testGetContent()
+ {
+ StringSource source = new StringSource( null );
+ assertEquals( "", source.getContent() );
+
+ source = new StringSource( "Hello World!", "LOCATION" );
+ assertEquals( "Hello World!", source.getContent() );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-builder-support/src/test/java/org/apache/maven/building/UrlSourceTest.java b/framework/src/maven/apache-maven-3.3.3/maven-builder-support/src/test/java/org/apache/maven/building/UrlSourceTest.java
new file mode 100644
index 00000000..5524c9b3
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-builder-support/src/test/java/org/apache/maven/building/UrlSourceTest.java
@@ -0,0 +1,87 @@
+package org.apache.maven.building;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import java.io.File;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.Scanner;
+
+import org.junit.Test;
+
+public class UrlSourceTest
+{
+
+ @Test
+ public void testUrlSource()
+ {
+ try
+ {
+ new UrlSource( null );
+ fail( "Should fail, since you must specify a url" );
+ }
+ catch ( IllegalArgumentException e )
+ {
+ assertEquals( "no url specified", e.getMessage() );
+ }
+ }
+
+ @Test
+ public void testGetInputStream()
+ throws Exception
+ {
+ URL txtFile = new File( "target/test-classes/source.txt" ).toURI().toURL();
+ UrlSource source = new UrlSource( txtFile );
+
+ Scanner scanner = null;
+ InputStream is = null;
+ try
+ {
+ is = source.getInputStream();
+
+ scanner = new Scanner( is );
+ assertEquals( "Hello World!", scanner.nextLine() );
+ }
+ finally
+ {
+ if ( scanner != null )
+ {
+ scanner.close();
+ }
+ if ( is != null )
+ {
+ is.close();
+ }
+ }
+ }
+
+ @Test
+ public void testGetLocation()
+ throws Exception
+ {
+ URL txtFile = new File( "target/test-classes/source.txt" ).toURI().toURL();
+ UrlSource source = new UrlSource( txtFile );
+ assertEquals( txtFile.toExternalForm(), source.getLocation() );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-builder-support/src/test/resources/source.txt b/framework/src/maven/apache-maven-3.3.3/maven-builder-support/src/test/resources/source.txt
new file mode 100644
index 00000000..c57eff55
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-builder-support/src/test/resources/source.txt
@@ -0,0 +1 @@
+Hello World! \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-compat/pom.xml
new file mode 100644
index 00000000..1b4c6c1a
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/pom.xml
@@ -0,0 +1,115 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+ <!--
+ Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE
+ file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by
+ applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language
+ governing permissions and limitations under the License.
+ -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven</artifactId>
+ <version>3.3.3</version>
+ </parent>
+
+ <artifactId>maven-compat</artifactId>
+
+ <name>Maven Compat</name>
+ <description>Maven2 classes maintained as compatibility layer.</description>
+
+ <scm><!-- remove when git scm url format can accept artifact-id at the end, as automatically inherited -->
+ <connection>scm:git:https://git-wip-us.apache.org/repos/asf/maven.git</connection>
+ <developerConnection>scm:git:https://git-wip-us.apache.org/repos/asf/maven.git</developerConnection>
+ <tag>maven-3.3.3</tag>
+ </scm>
+
+ <properties>
+ <checkstyle.failOnViolation>false</checkstyle.failOnViolation><!-- lazyness for code that will disappear in future... -->
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-model</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-model-builder</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-settings</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-artifact</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-utils</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-interpolation</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.sisu</groupId>
+ <artifactId>org.eclipse.sisu.plexus</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-component-annotations</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.wagon</groupId>
+ <artifactId>wagon-provider-api</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.maven.wagon</groupId>
+ <artifactId>wagon-file</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.aether</groupId>
+ <artifactId>aether-connector-basic</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.aether</groupId>
+ <artifactId>aether-transport-wagon</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-component-metadata</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.modello</groupId>
+ <artifactId>modello-maven-plugin</artifactId>
+ <configuration>
+ <version>1.0.0</version>
+ <models>
+ <model>src/main/mdo/profiles.mdo</model>
+ <model>src/main/mdo/paramdoc.mdo</model>
+ </models>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/ArtifactScopeEnum.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/ArtifactScopeEnum.java
new file mode 100644
index 00000000..7051e3bf
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/ArtifactScopeEnum.java
@@ -0,0 +1,133 @@
+package org.apache.maven.artifact;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Type safe reincarnation of Artifact scope. Also supplies the <code>DEFAULT_SCOPE<code> as well
+ * as convenience method to deal with scope relationships.
+ *
+ * @author <a href="oleg@codehaus.org">Oleg Gusakov</a>
+ *
+ */
+
+public enum ArtifactScopeEnum
+{
+ compile( 1 ), test( 2 ), runtime( 3 ), provided( 4 ), system( 5 ), runtime_plus_system( 6 );
+
+ public static final ArtifactScopeEnum DEFAULT_SCOPE = compile;
+
+ private int id;
+
+ // Constructor
+ ArtifactScopeEnum( int id )
+ {
+ this.id = id;
+ }
+
+ int getId()
+ {
+ return id;
+ }
+
+
+ /**
+ * Helper method to simplify null processing
+ *
+ * @return
+ */
+ public static final ArtifactScopeEnum checkScope( ArtifactScopeEnum scope )
+ {
+ return scope == null ? DEFAULT_SCOPE : scope;
+ }
+
+ /**
+ *
+ * @return unsafe String representation of this scope.
+ */
+ public String getScope()
+ {
+ if ( id == 1 )
+ {
+ return Artifact.SCOPE_COMPILE;
+ }
+ else if ( id == 2 )
+ {
+ return Artifact.SCOPE_TEST;
+
+ }
+ else if ( id == 3 )
+ {
+ return Artifact.SCOPE_RUNTIME;
+
+ }
+ else if ( id == 4 )
+ {
+ return Artifact.SCOPE_PROVIDED;
+ }
+ else if ( id == 5 )
+ {
+ return Artifact.SCOPE_SYSTEM;
+ }
+ else
+ {
+ return Artifact.SCOPE_RUNTIME_PLUS_SYSTEM;
+ }
+ }
+
+ private static final ArtifactScopeEnum [][][] COMPLIANCY_SETS = {
+ { { compile }, { compile, provided, system } }
+ , { { test }, { compile, test, provided, system } }
+ , { { runtime }, { compile, runtime, system } }
+ , { { provided }, { compile, test, provided } }
+ };
+
+ /**
+ * scope relationship function. Used by the graph conflict resolution policies
+ *
+ * @param scope
+ * @return true is supplied scope is an inclusive sub-scope of current one.
+ */
+ public boolean encloses( ArtifactScopeEnum scope )
+ {
+ final ArtifactScopeEnum s = checkScope( scope );
+
+ // system scope is historic only - and simple
+ if ( id == system.id )
+ {
+ return scope.id == system.id;
+ }
+
+ for ( ArtifactScopeEnum[][] set : COMPLIANCY_SETS )
+ {
+ if ( id == set[0][0].id )
+ {
+ for ( ArtifactScopeEnum ase : set[1] )
+ {
+ if ( s.id == ase.id )
+ {
+ return true;
+ }
+ }
+ break;
+ }
+ }
+ return false;
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/ArtifactStatus.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/ArtifactStatus.java
new file mode 100644
index 00000000..3bd1e341
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/ArtifactStatus.java
@@ -0,0 +1,124 @@
+package org.apache.maven.artifact;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Type safe enumeration for the artifact status field.
+ *
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ */
+public final class ArtifactStatus
+ implements Comparable<ArtifactStatus>
+{
+ /**
+ * No trust - no information about status.
+ */
+ public static final ArtifactStatus NONE = new ArtifactStatus( "none", 0 );
+
+ /**
+ * No trust - information was generated with defaults.
+ */
+ public static final ArtifactStatus GENERATED = new ArtifactStatus( "generated", 1 );
+
+ /**
+ * Low trust - was converted from the Maven 1.x repository.
+ */
+ public static final ArtifactStatus CONVERTED = new ArtifactStatus( "converted", 2 );
+
+ /**
+ * Moderate trust - it was deployed directly from a partner.
+ */
+ public static final ArtifactStatus PARTNER = new ArtifactStatus( "partner", 3 );
+
+ /**
+ * Moderate trust - it was deployed directly by a user.
+ */
+ public static final ArtifactStatus DEPLOYED = new ArtifactStatus( "deployed", 4 );
+
+ /**
+ * Trusted, as it has had its data verified by hand.
+ */
+ public static final ArtifactStatus VERIFIED = new ArtifactStatus( "verified", 5 );
+
+ private final int rank;
+
+ private final String key;
+
+ private static Map<String, ArtifactStatus> map;
+
+ private ArtifactStatus( String key, int rank )
+ {
+ this.rank = rank;
+ this.key = key;
+
+ if ( map == null )
+ {
+ map = new HashMap<String, ArtifactStatus>();
+ }
+ map.put( key, this );
+ }
+
+ public static ArtifactStatus valueOf( String status )
+ {
+ ArtifactStatus retVal = null;
+
+ if ( status != null )
+ {
+ retVal = map.get( status );
+ }
+
+ return retVal != null ? retVal : NONE;
+ }
+
+ public boolean equals( Object o )
+ {
+ if ( this == o )
+ {
+ return true;
+ }
+ if ( o == null || getClass() != o.getClass() )
+ {
+ return false;
+ }
+
+ final ArtifactStatus that = (ArtifactStatus) o;
+
+ return rank == that.rank;
+
+ }
+
+ public int hashCode()
+ {
+ return rank;
+ }
+
+ public String toString()
+ {
+ return key;
+ }
+
+ public int compareTo( ArtifactStatus s )
+ {
+ return rank - s.rank;
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/UnknownRepositoryLayoutException.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/UnknownRepositoryLayoutException.java
new file mode 100644
index 00000000..5abe1105
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/UnknownRepositoryLayoutException.java
@@ -0,0 +1,54 @@
+package org.apache.maven.artifact;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
+
+/**
+ * Exception which is meant to occur when a layout specified for a particular
+ * repository doesn't have a corresponding {@link ArtifactRepositoryLayout}
+ * component in the current container.
+ *
+ * @author jdcasey
+ */
+public class UnknownRepositoryLayoutException
+ extends InvalidRepositoryException
+{
+
+ private final String layoutId;
+
+ public UnknownRepositoryLayoutException( String repositoryId, String layoutId )
+ {
+ super( "Cannot find ArtifactRepositoryLayout instance for: " + layoutId, repositoryId );
+ this.layoutId = layoutId;
+ }
+
+ public UnknownRepositoryLayoutException( String repositoryId, String layoutId, ComponentLookupException e )
+ {
+ super( "Cannot find ArtifactRepositoryLayout instance for: " + layoutId, repositoryId, e );
+ this.layoutId = layoutId;
+ }
+
+ public String getLayoutId()
+ {
+ return layoutId;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/deployer/ArtifactDeployer.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/deployer/ArtifactDeployer.java
new file mode 100644
index 00000000..072552cc
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/deployer/ArtifactDeployer.java
@@ -0,0 +1,61 @@
+package org.apache.maven.artifact.deployer;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+
+public interface ArtifactDeployer
+{
+ String ROLE = ArtifactDeployer.class.getName();
+
+ /**
+ * Deploy an artifact from a particular directory. The artifact handler is used to determine the
+ * filename of the source file.
+ *
+ * @param basedir the directory where the artifact is stored
+ * @param finalName the name of the artifact without extension
+ * @param artifact the artifact definition
+ * @param deploymentRepository the repository to deploy to
+ * @param localRepository the local repository to install into
+ * @throws ArtifactDeploymentException if an error occurred deploying the artifact
+ * @deprecated to be removed before 2.0 after the install/deploy plugins use the alternate
+ * method
+ */
+ @Deprecated
+ void deploy( String basedir, String finalName, Artifact artifact, ArtifactRepository deploymentRepository,
+ ArtifactRepository localRepository )
+ throws ArtifactDeploymentException;
+
+ /**
+ * Deploy an artifact from a particular file.
+ *
+ * @param source the file to deploy
+ * @param artifact the artifact definition
+ * @param deploymentRepository the repository to deploy to
+ * @param localRepository the local repository to install into
+ * @throws ArtifactDeploymentException if an error occurred deploying the artifact
+ */
+ void deploy( File source, Artifact artifact, ArtifactRepository deploymentRepository,
+ ArtifactRepository localRepository )
+ throws ArtifactDeploymentException;
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/deployer/ArtifactDeploymentException.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/deployer/ArtifactDeploymentException.java
new file mode 100644
index 00000000..6e44ed3c
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/deployer/ArtifactDeploymentException.java
@@ -0,0 +1,43 @@
+package org.apache.maven.artifact.deployer;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * @author Jason van Zyl
+ */
+public class ArtifactDeploymentException
+ extends Exception
+{
+ public ArtifactDeploymentException( String message )
+ {
+ super( message );
+ }
+
+ public ArtifactDeploymentException( Throwable cause )
+ {
+ super( cause );
+ }
+
+ public ArtifactDeploymentException( String message,
+ Throwable cause )
+ {
+ super( message, cause );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/deployer/DefaultArtifactDeployer.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/deployer/DefaultArtifactDeployer.java
new file mode 100644
index 00000000..abbab821
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/deployer/DefaultArtifactDeployer.java
@@ -0,0 +1,161 @@
+package org.apache.maven.artifact.deployer;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.maven.RepositoryUtils;
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.metadata.ArtifactMetadata;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.repository.DefaultArtifactRepository;
+import org.apache.maven.artifact.repository.LegacyLocalRepositoryManager;
+import org.apache.maven.artifact.repository.metadata.ArtifactRepositoryMetadata;
+import org.apache.maven.artifact.repository.metadata.MetadataBridge;
+import org.apache.maven.artifact.repository.metadata.SnapshotArtifactRepositoryMetadata;
+import org.apache.maven.plugin.LegacySupport;
+import org.apache.maven.project.artifact.ProjectArtifactMetadata;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+import org.codehaus.plexus.logging.AbstractLogEnabled;
+import org.eclipse.aether.RepositorySystem;
+import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.RequestTrace;
+import org.eclipse.aether.deployment.DeployRequest;
+import org.eclipse.aether.deployment.DeployResult;
+import org.eclipse.aether.deployment.DeploymentException;
+import org.eclipse.aether.metadata.MergeableMetadata;
+import org.eclipse.aether.repository.RemoteRepository;
+import org.eclipse.aether.util.artifact.SubArtifact;
+
+@Component( role = ArtifactDeployer.class, instantiationStrategy = "per-lookup" )
+public class DefaultArtifactDeployer
+ extends AbstractLogEnabled
+ implements ArtifactDeployer
+{
+
+ @Requirement
+ private RepositorySystem repoSystem;
+
+ @Requirement
+ private LegacySupport legacySupport;
+
+ private Map<Object, MergeableMetadata> relatedMetadata = new ConcurrentHashMap<Object, MergeableMetadata>();
+
+ /**
+ * @deprecated we want to use the artifact method only, and ensure artifact.file is set
+ * correctly.
+ */
+ @Deprecated
+ public void deploy( String basedir, String finalName, Artifact artifact, ArtifactRepository deploymentRepository,
+ ArtifactRepository localRepository )
+ throws ArtifactDeploymentException
+ {
+ String extension = artifact.getArtifactHandler().getExtension();
+ File source = new File( basedir, finalName + "." + extension );
+ deploy( source, artifact, deploymentRepository, localRepository );
+ }
+
+ public void deploy( File source, Artifact artifact, ArtifactRepository deploymentRepository,
+ ArtifactRepository localRepository )
+ throws ArtifactDeploymentException
+ {
+ RepositorySystemSession session =
+ LegacyLocalRepositoryManager.overlay( localRepository, legacySupport.getRepositorySession(), repoSystem );
+
+ DeployRequest request = new DeployRequest();
+
+ request.setTrace( RequestTrace.newChild( null, legacySupport.getSession().getCurrentProject() ) );
+
+ org.eclipse.aether.artifact.Artifact mainArtifact = RepositoryUtils.toArtifact( artifact );
+ mainArtifact = mainArtifact.setFile( source );
+ request.addArtifact( mainArtifact );
+
+ String versionKey = artifact.getGroupId() + ':' + artifact.getArtifactId();
+ String snapshotKey = null;
+ if ( artifact.isSnapshot() )
+ {
+ snapshotKey = versionKey + ':' + artifact.getBaseVersion();
+ request.addMetadata( relatedMetadata.get( snapshotKey ) );
+ }
+ request.addMetadata( relatedMetadata.get( versionKey ) );
+
+ for ( ArtifactMetadata metadata : artifact.getMetadataList() )
+ {
+ if ( metadata instanceof ProjectArtifactMetadata )
+ {
+ org.eclipse.aether.artifact.Artifact pomArtifact = new SubArtifact( mainArtifact, "", "pom" );
+ pomArtifact = pomArtifact.setFile( ( (ProjectArtifactMetadata) metadata ).getFile() );
+ request.addArtifact( pomArtifact );
+ }
+ else if ( metadata instanceof SnapshotArtifactRepositoryMetadata
+ || metadata instanceof ArtifactRepositoryMetadata )
+ {
+ // eaten, handled by repo system
+ }
+ else
+ {
+ request.addMetadata( new MetadataBridge( metadata ) );
+ }
+ }
+
+ RemoteRepository remoteRepo = RepositoryUtils.toRepo( deploymentRepository );
+ /*
+ * NOTE: This provides backward-compat with maven-deploy-plugin:2.4 which bypasses the repository factory when
+ * using an alternative deployment location.
+ */
+ if ( deploymentRepository instanceof DefaultArtifactRepository
+ && deploymentRepository.getAuthentication() == null )
+ {
+ RemoteRepository.Builder builder = new RemoteRepository.Builder( remoteRepo );
+ builder.setAuthentication( session.getAuthenticationSelector().getAuthentication( remoteRepo ) );
+ builder.setProxy( session.getProxySelector().getProxy( remoteRepo ) );
+ remoteRepo = builder.build();
+ }
+ request.setRepository( remoteRepo );
+
+ DeployResult result;
+ try
+ {
+ result = repoSystem.deploy( session, request );
+ }
+ catch ( DeploymentException e )
+ {
+ throw new ArtifactDeploymentException( e.getMessage(), e );
+ }
+
+ for ( Object metadata : result.getMetadata() )
+ {
+ if ( metadata.getClass().getName().endsWith( ".internal.VersionsMetadata" ) )
+ {
+ relatedMetadata.put( versionKey, (MergeableMetadata) metadata );
+ }
+ if ( snapshotKey != null && metadata.getClass().getName().endsWith( ".internal.RemoteSnapshotMetadata" ) )
+ {
+ relatedMetadata.put( snapshotKey, (MergeableMetadata) metadata );
+ }
+ }
+
+ artifact.setResolvedVersion( result.getArtifacts().iterator().next().getVersion() );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/installer/ArtifactInstallationException.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/installer/ArtifactInstallationException.java
new file mode 100644
index 00000000..9f1e45b9
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/installer/ArtifactInstallationException.java
@@ -0,0 +1,43 @@
+package org.apache.maven.artifact.installer;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * @author <a href="mailto:jason@maven.org">Jason van Zyl</a>
+ */
+public class ArtifactInstallationException
+ extends Exception
+{
+ public ArtifactInstallationException( String message )
+ {
+ super( message );
+ }
+
+ public ArtifactInstallationException( Throwable cause )
+ {
+ super( cause );
+ }
+
+ public ArtifactInstallationException( String message,
+ Throwable cause )
+ {
+ super( message, cause );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/installer/ArtifactInstaller.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/installer/ArtifactInstaller.java
new file mode 100644
index 00000000..376eba20
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/installer/ArtifactInstaller.java
@@ -0,0 +1,60 @@
+package org.apache.maven.artifact.installer;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+
+/**
+ * @author <a href="michal@codehaus.org">Michal Maczka</a>
+ */
+public interface ArtifactInstaller
+{
+ String ROLE = ArtifactInstaller.class.getName();
+
+ /**
+ * Install an artifact from a particular directory. The artifact handler is used to determine
+ * the filename of the source file.
+ *
+ * @param basedir the directory where the artifact is stored
+ * @param finalName the name of the artifact sans extension
+ * @param artifact the artifact definition
+ * @param localRepository the local repository to install into
+ * @throws ArtifactInstallationException if an error occurred installing the artifact
+ * @deprecated to be removed before 2.0 after the instlal/deploy plugins use the alternate
+ * method
+ */
+ @Deprecated
+ void install( String basedir, String finalName, Artifact artifact, ArtifactRepository localRepository )
+ throws ArtifactInstallationException;
+
+ /**
+ * Install an artifact from a particular file.
+ *
+ * @param source the file to install
+ * @param artifact the artifact definition
+ * @param localRepository the local repository to install into
+ * @throws ArtifactInstallationException if an error occurred installing the artifact
+ */
+ void install( File source, Artifact artifact, ArtifactRepository localRepository )
+ throws ArtifactInstallationException;
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/installer/DefaultArtifactInstaller.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/installer/DefaultArtifactInstaller.java
new file mode 100644
index 00000000..a2529757
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/installer/DefaultArtifactInstaller.java
@@ -0,0 +1,135 @@
+package org.apache.maven.artifact.installer;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+
+import org.apache.maven.RepositoryUtils;
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.metadata.ArtifactMetadata;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.repository.LegacyLocalRepositoryManager;
+import org.apache.maven.artifact.repository.metadata.ArtifactRepositoryMetadata;
+import org.apache.maven.artifact.repository.metadata.MetadataBridge;
+import org.apache.maven.artifact.repository.metadata.Snapshot;
+import org.apache.maven.artifact.repository.metadata.SnapshotArtifactRepositoryMetadata;
+import org.apache.maven.artifact.repository.metadata.Versioning;
+import org.apache.maven.plugin.LegacySupport;
+import org.apache.maven.project.artifact.ProjectArtifactMetadata;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+import org.codehaus.plexus.logging.AbstractLogEnabled;
+import org.eclipse.aether.RepositorySystem;
+import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.RequestTrace;
+import org.eclipse.aether.installation.InstallRequest;
+import org.eclipse.aether.installation.InstallationException;
+import org.eclipse.aether.util.artifact.SubArtifact;
+
+/**
+ * @author Jason van Zyl
+ */
+@Component( role = ArtifactInstaller.class )
+public class DefaultArtifactInstaller
+ extends AbstractLogEnabled
+ implements ArtifactInstaller
+{
+
+ @Requirement
+ private RepositorySystem repoSystem;
+
+ @Requirement
+ private LegacySupport legacySupport;
+
+ /** @deprecated we want to use the artifact method only, and ensure artifact.file is set correctly. */
+ @Deprecated
+ public void install( String basedir, String finalName, Artifact artifact, ArtifactRepository localRepository )
+ throws ArtifactInstallationException
+ {
+ String extension = artifact.getArtifactHandler().getExtension();
+ File source = new File( basedir, finalName + "." + extension );
+
+ install( source, artifact, localRepository );
+ }
+
+ public void install( File source, Artifact artifact, ArtifactRepository localRepository )
+ throws ArtifactInstallationException
+ {
+ RepositorySystemSession session =
+ LegacyLocalRepositoryManager.overlay( localRepository, legacySupport.getRepositorySession(), repoSystem );
+
+ InstallRequest request = new InstallRequest();
+
+ request.setTrace( RequestTrace.newChild( null, legacySupport.getSession().getCurrentProject() ) );
+
+ org.eclipse.aether.artifact.Artifact mainArtifact = RepositoryUtils.toArtifact( artifact );
+ mainArtifact = mainArtifact.setFile( source );
+ request.addArtifact( mainArtifact );
+
+ for ( ArtifactMetadata metadata : artifact.getMetadataList() )
+ {
+ if ( metadata instanceof ProjectArtifactMetadata )
+ {
+ org.eclipse.aether.artifact.Artifact pomArtifact = new SubArtifact( mainArtifact, "", "pom" );
+ pomArtifact = pomArtifact.setFile( ( (ProjectArtifactMetadata) metadata ).getFile() );
+ request.addArtifact( pomArtifact );
+ }
+ else if ( metadata instanceof SnapshotArtifactRepositoryMetadata
+ || metadata instanceof ArtifactRepositoryMetadata )
+ {
+ // eaten, handled by repo system
+ }
+ else
+ {
+ request.addMetadata( new MetadataBridge( metadata ) );
+ }
+ }
+
+ try
+ {
+ repoSystem.install( session, request );
+ }
+ catch ( InstallationException e )
+ {
+ throw new ArtifactInstallationException( e.getMessage(), e );
+ }
+
+ /*
+ * NOTE: Not used by Maven core, only here to provide backward-compat with plugins like the Install Plugin.
+ */
+
+ if ( artifact.isSnapshot() )
+ {
+ Snapshot snapshot = new Snapshot();
+ snapshot.setLocalCopy( true );
+ artifact.addMetadata( new SnapshotArtifactRepositoryMetadata( artifact, snapshot ) );
+ }
+
+ Versioning versioning = new Versioning();
+ versioning.updateTimestamp();
+ versioning.addVersion( artifact.getBaseVersion() );
+ if ( artifact.isRelease() )
+ {
+ versioning.setRelease( artifact.getBaseVersion() );
+ }
+ artifact.addMetadata( new ArtifactRepositoryMetadata( artifact, versioning ) );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/manager/DefaultWagonManager.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/manager/DefaultWagonManager.java
new file mode 100644
index 00000000..29876e24
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/manager/DefaultWagonManager.java
@@ -0,0 +1,182 @@
+package org.apache.maven.artifact.manager;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.List;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.repository.ArtifactRepositoryFactory;
+import org.apache.maven.execution.MavenExecutionRequest;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.plugin.LegacySupport;
+import org.apache.maven.repository.MirrorSelector;
+import org.apache.maven.settings.Mirror;
+import org.apache.maven.settings.Proxy;
+import org.apache.maven.settings.Server;
+import org.apache.maven.settings.crypto.DefaultSettingsDecryptionRequest;
+import org.apache.maven.settings.crypto.SettingsDecrypter;
+import org.apache.maven.settings.crypto.SettingsDecryptionResult;
+import org.apache.maven.wagon.ResourceDoesNotExistException;
+import org.apache.maven.wagon.TransferFailedException;
+import org.apache.maven.wagon.authentication.AuthenticationInfo;
+import org.apache.maven.wagon.proxy.ProxyInfo;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+import org.codehaus.plexus.logging.Logger;
+
+@Component( role = WagonManager.class )
+public class DefaultWagonManager
+ extends org.apache.maven.repository.legacy.DefaultWagonManager
+ implements WagonManager
+{
+
+ // NOTE: This must use a different field name than in the super class or IoC has no chance to inject the loggers
+ @Requirement
+ private Logger log;
+
+ @Requirement
+ private LegacySupport legacySupport;
+
+ @Requirement
+ private SettingsDecrypter settingsDecrypter;
+
+ @Requirement
+ private MirrorSelector mirrorSelector;
+
+ @Requirement
+ private ArtifactRepositoryFactory artifactRepositoryFactory;
+
+ public AuthenticationInfo getAuthenticationInfo( String id )
+ {
+ MavenSession session = legacySupport.getSession();
+
+ if ( session != null && id != null )
+ {
+ MavenExecutionRequest request = session.getRequest();
+
+ if ( request != null )
+ {
+ List<Server> servers = request.getServers();
+
+ if ( servers != null )
+ {
+ for ( Server server : servers )
+ {
+ if ( id.equalsIgnoreCase( server.getId() ) )
+ {
+ SettingsDecryptionResult result =
+ settingsDecrypter.decrypt( new DefaultSettingsDecryptionRequest( server ) );
+ server = result.getServer();
+
+ AuthenticationInfo authInfo = new AuthenticationInfo();
+ authInfo.setUserName( server.getUsername() );
+ authInfo.setPassword( server.getPassword() );
+ authInfo.setPrivateKey( server.getPrivateKey() );
+ authInfo.setPassphrase( server.getPassphrase() );
+
+ return authInfo;
+ }
+ }
+ }
+ }
+ }
+
+ // empty one to prevent NPE
+ return new AuthenticationInfo();
+ }
+
+ public ProxyInfo getProxy( String protocol )
+ {
+ MavenSession session = legacySupport.getSession();
+
+ if ( session != null && protocol != null )
+ {
+ MavenExecutionRequest request = session.getRequest();
+
+ if ( request != null )
+ {
+ List<Proxy> proxies = request.getProxies();
+
+ if ( proxies != null )
+ {
+ for ( Proxy proxy : proxies )
+ {
+ if ( proxy.isActive() && protocol.equalsIgnoreCase( proxy.getProtocol() ) )
+ {
+ SettingsDecryptionResult result =
+ settingsDecrypter.decrypt( new DefaultSettingsDecryptionRequest( proxy ) );
+ proxy = result.getProxy();
+
+ ProxyInfo proxyInfo = new ProxyInfo();
+ proxyInfo.setHost( proxy.getHost() );
+ proxyInfo.setType( proxy.getProtocol() );
+ proxyInfo.setPort( proxy.getPort() );
+ proxyInfo.setNonProxyHosts( proxy.getNonProxyHosts() );
+ proxyInfo.setUserName( proxy.getUsername() );
+ proxyInfo.setPassword( proxy.getPassword() );
+
+ return proxyInfo;
+ }
+ }
+ }
+ }
+ }
+
+ return null;
+ }
+
+ public void getArtifact( Artifact artifact, ArtifactRepository repository )
+ throws TransferFailedException, ResourceDoesNotExistException
+ {
+ getArtifact( artifact, repository, null, false );
+ }
+
+ public void getArtifact( Artifact artifact, List<ArtifactRepository> remoteRepositories )
+ throws TransferFailedException, ResourceDoesNotExistException
+ {
+ getArtifact( artifact, remoteRepositories, null, false );
+ }
+
+ @Deprecated
+ public ArtifactRepository getMirrorRepository( ArtifactRepository repository )
+ {
+
+ Mirror mirror = mirrorSelector.getMirror( repository, legacySupport.getSession().getSettings().getMirrors() );
+
+ if ( mirror != null )
+ {
+ String id = mirror.getId();
+ if ( id == null )
+ {
+ // TODO: this should be illegal in settings.xml
+ id = repository.getId();
+ }
+
+ log.debug( "Using mirror: " + mirror.getUrl() + " (id: " + id + ")" );
+
+ repository = artifactRepositoryFactory.createArtifactRepository( id, mirror.getUrl(),
+ repository.getLayout(), repository.getSnapshots(),
+ repository.getReleases() );
+ }
+ return repository;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/manager/WagonConfigurationException.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/manager/WagonConfigurationException.java
new file mode 100644
index 00000000..8065116f
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/manager/WagonConfigurationException.java
@@ -0,0 +1,38 @@
+package org.apache.maven.artifact.manager;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * @author Olivier Lamy
+ */
+@Deprecated
+public class WagonConfigurationException
+ extends org.apache.maven.repository.legacy.WagonConfigurationException
+{
+ public WagonConfigurationException( String repositoryId, String message, Throwable cause )
+ {
+ super( repositoryId, message, cause );
+ }
+
+ public WagonConfigurationException( String repositoryId, String message )
+ {
+ super( repositoryId, message );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/manager/WagonManager.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/manager/WagonManager.java
new file mode 100644
index 00000000..fb7ca8b6
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/manager/WagonManager.java
@@ -0,0 +1,56 @@
+package org.apache.maven.artifact.manager;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.List;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.wagon.ResourceDoesNotExistException;
+import org.apache.maven.wagon.TransferFailedException;
+import org.apache.maven.wagon.authentication.AuthenticationInfo;
+import org.apache.maven.wagon.proxy.ProxyInfo;
+
+/**
+ * Manages <a href="http://maven.apache.org/wagon">Wagon</a> related operations in Maven.
+ *
+ * @author <a href="michal.maczka@dimatics.com">Michal Maczka </a>
+ */
+@Deprecated
+public interface WagonManager
+ extends org.apache.maven.repository.legacy.WagonManager
+{
+ /**
+ * this method is only here for backward compat (project-info-reports:dependencies)
+ * the default implementation will return an empty AuthenticationInfo
+ */
+ AuthenticationInfo getAuthenticationInfo( String id );
+
+ ProxyInfo getProxy( String protocol );
+
+ void getArtifact( Artifact artifact, ArtifactRepository repository )
+ throws TransferFailedException, ResourceDoesNotExistException;
+
+ void getArtifact( Artifact artifact, List<ArtifactRepository> remoteRepositories )
+ throws TransferFailedException, ResourceDoesNotExistException;
+
+ ArtifactRepository getMirrorRepository( ArtifactRepository repository );
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/repository/ArtifactRepositoryFactory.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/repository/ArtifactRepositoryFactory.java
new file mode 100644
index 00000000..ac18b3ad
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/repository/ArtifactRepositoryFactory.java
@@ -0,0 +1,55 @@
+package org.apache.maven.artifact.repository;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.artifact.UnknownRepositoryLayoutException;
+import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout;
+
+/** @author jdcasey */
+public interface ArtifactRepositoryFactory
+{
+ String ROLE = ArtifactRepositoryFactory.class.getName();
+
+ String DEFAULT_LAYOUT_ID = "default";
+
+ String LOCAL_REPOSITORY_ID = "local";
+
+ @Deprecated
+ ArtifactRepositoryLayout getLayout( String layoutId )
+ throws UnknownRepositoryLayoutException;
+
+ @Deprecated
+ ArtifactRepository createDeploymentArtifactRepository( String id, String url, String layoutId, boolean uniqueVersion )
+ throws UnknownRepositoryLayoutException;
+
+ ArtifactRepository createDeploymentArtifactRepository( String id, String url, ArtifactRepositoryLayout layout,
+ boolean uniqueVersion );
+
+ ArtifactRepository createArtifactRepository( String id, String url, String layoutId,
+ ArtifactRepositoryPolicy snapshots, ArtifactRepositoryPolicy releases )
+ throws UnknownRepositoryLayoutException;
+
+ ArtifactRepository createArtifactRepository( String id, String url, ArtifactRepositoryLayout repositoryLayout,
+ ArtifactRepositoryPolicy snapshots, ArtifactRepositoryPolicy releases );
+
+ void setGlobalUpdatePolicy( String snapshotPolicy );
+
+ void setGlobalChecksumPolicy( String checksumPolicy );
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/repository/DefaultArtifactRepository.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/repository/DefaultArtifactRepository.java
new file mode 100644
index 00000000..e0a55879
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/repository/DefaultArtifactRepository.java
@@ -0,0 +1,267 @@
+package org.apache.maven.artifact.repository;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.metadata.ArtifactMetadata;
+import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout;
+import org.apache.maven.repository.Proxy;
+import org.apache.maven.wagon.repository.Repository;
+
+/**
+ * This class is an abstraction of the location from/to resources can be
+ * transfered.
+ *
+ * @author <a href="michal.maczka@dimatics.com">Michal Maczka </a>
+ */
+@Deprecated
+public class DefaultArtifactRepository
+ extends Repository
+ implements ArtifactRepository
+{
+ private ArtifactRepositoryLayout layout;
+
+ private ArtifactRepositoryPolicy snapshots;
+
+ private ArtifactRepositoryPolicy releases;
+
+ private boolean blacklisted;
+
+ private Authentication authentication;
+
+ private Proxy proxy;
+
+ private List<ArtifactRepository> mirroredRepositories = Collections.emptyList();
+
+ /**
+ * Create a local repository or a test repository.
+ *
+ * @param id the unique identifier of the repository
+ * @param url the URL of the repository
+ * @param layout the layout of the repository
+ */
+ public DefaultArtifactRepository( String id, String url, ArtifactRepositoryLayout layout )
+ {
+ this( id, url, layout, null, null );
+ }
+
+ /**
+ * Create a remote deployment repository.
+ *
+ * @param id the unique identifier of the repository
+ * @param url the URL of the repository
+ * @param layout the layout of the repository
+ * @param uniqueVersion whether to assign each snapshot a unique version
+ */
+ public DefaultArtifactRepository( String id, String url, ArtifactRepositoryLayout layout, boolean uniqueVersion )
+ {
+ super( id, url );
+ this.layout = layout;
+ }
+
+ /**
+ * Create a remote download repository.
+ *
+ * @param id the unique identifier of the repository
+ * @param url the URL of the repository
+ * @param layout the layout of the repository
+ * @param snapshots the policies to use for snapshots
+ * @param releases the policies to use for releases
+ */
+ public DefaultArtifactRepository( String id, String url, ArtifactRepositoryLayout layout,
+ ArtifactRepositoryPolicy snapshots, ArtifactRepositoryPolicy releases )
+ {
+ super( id, url );
+
+ this.layout = layout;
+
+ if ( snapshots == null )
+ {
+ snapshots = new ArtifactRepositoryPolicy( true, ArtifactRepositoryPolicy.UPDATE_POLICY_ALWAYS,
+ ArtifactRepositoryPolicy.CHECKSUM_POLICY_IGNORE );
+ }
+
+ this.snapshots = snapshots;
+
+ if ( releases == null )
+ {
+ releases = new ArtifactRepositoryPolicy( true, ArtifactRepositoryPolicy.UPDATE_POLICY_ALWAYS,
+ ArtifactRepositoryPolicy.CHECKSUM_POLICY_IGNORE );
+ }
+
+ this.releases = releases;
+ }
+
+ public String pathOf( Artifact artifact )
+ {
+ return layout.pathOf( artifact );
+ }
+
+ public String pathOfRemoteRepositoryMetadata( ArtifactMetadata artifactMetadata )
+ {
+ return layout.pathOfRemoteRepositoryMetadata( artifactMetadata );
+ }
+
+ public String pathOfLocalRepositoryMetadata( ArtifactMetadata metadata, ArtifactRepository repository )
+ {
+ return layout.pathOfLocalRepositoryMetadata( metadata, repository );
+ }
+
+ public void setLayout( ArtifactRepositoryLayout layout )
+ {
+ this.layout = layout;
+ }
+
+ public ArtifactRepositoryLayout getLayout()
+ {
+ return layout;
+ }
+
+ public void setSnapshotUpdatePolicy( ArtifactRepositoryPolicy snapshots )
+ {
+ this.snapshots = snapshots;
+ }
+
+ public ArtifactRepositoryPolicy getSnapshots()
+ {
+ return snapshots;
+ }
+
+ public void setReleaseUpdatePolicy( ArtifactRepositoryPolicy releases )
+ {
+ this.releases = releases;
+ }
+
+ public ArtifactRepositoryPolicy getReleases()
+ {
+ return releases;
+ }
+
+ public String getKey()
+ {
+ return getId();
+ }
+
+ public boolean isBlacklisted()
+ {
+ return blacklisted;
+ }
+
+ public void setBlacklisted( boolean blacklisted )
+ {
+ this.blacklisted = blacklisted;
+ }
+
+ public String toString()
+ {
+ StringBuilder sb = new StringBuilder();
+
+ sb.append( " id: " ).append( getId() ).append( "\n" );
+ sb.append( " url: " ).append( getUrl() ).append( "\n" );
+ sb.append( " layout: " ).append( layout != null ? layout : "none" ).append( "\n" );
+
+ if ( snapshots != null )
+ {
+ sb.append( "snapshots: [enabled => " ).append( snapshots.isEnabled() );
+ sb.append( ", update => " ).append( snapshots.getUpdatePolicy() ).append( "]\n" );
+ }
+
+ if ( releases != null )
+ {
+ sb.append( " releases: [enabled => " ).append( releases.isEnabled() );
+ sb.append( ", update => " ).append( releases.getUpdatePolicy() ).append( "]\n" );
+ }
+
+ return sb.toString();
+ }
+
+ public Artifact find( Artifact artifact )
+ {
+ File artifactFile = new File( getBasedir(), pathOf( artifact ) );
+
+ // We need to set the file here or the resolver will fail with an NPE, not fully equipped to deal
+ // with multiple local repository implementations yet.
+ artifact.setFile( artifactFile );
+
+ if ( artifactFile.exists() )
+ {
+ artifact.setResolved( true );
+ }
+
+ return artifact;
+ }
+
+ public List<String> findVersions( Artifact artifact )
+ {
+ return Collections.emptyList();
+ }
+
+ public boolean isProjectAware()
+ {
+ return false;
+ }
+
+ public Authentication getAuthentication()
+ {
+ return authentication;
+ }
+
+ public void setAuthentication( Authentication authentication )
+ {
+ this.authentication = authentication;
+ }
+
+ public Proxy getProxy()
+ {
+ return proxy;
+ }
+
+ public void setProxy( Proxy proxy )
+ {
+ this.proxy = proxy;
+ }
+
+ public boolean isUniqueVersion()
+ {
+ return true;
+ }
+
+ public List<ArtifactRepository> getMirroredRepositories()
+ {
+ return mirroredRepositories;
+ }
+
+ public void setMirroredRepositories( List<ArtifactRepository> mirroredRepositories )
+ {
+ if ( mirroredRepositories != null )
+ {
+ this.mirroredRepositories = mirroredRepositories;
+ }
+ else
+ {
+ this.mirroredRepositories = Collections.emptyList();
+ }
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/repository/DefaultArtifactRepositoryFactory.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/repository/DefaultArtifactRepositoryFactory.java
new file mode 100644
index 00000000..658dbdac
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/repository/DefaultArtifactRepositoryFactory.java
@@ -0,0 +1,124 @@
+package org.apache.maven.artifact.repository;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.maven.artifact.UnknownRepositoryLayoutException;
+import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout;
+import org.apache.maven.plugin.LegacySupport;
+import org.apache.maven.repository.RepositorySystem;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+import org.eclipse.aether.RepositorySystemSession;
+
+/**
+ * @author jdcasey
+ */
+@Component( role = ArtifactRepositoryFactory.class )
+public class DefaultArtifactRepositoryFactory
+ implements ArtifactRepositoryFactory
+{
+
+ @Requirement
+ private org.apache.maven.repository.legacy.repository.ArtifactRepositoryFactory factory;
+
+ @Requirement
+ private LegacySupport legacySupport;
+
+ @Requirement
+ private RepositorySystem repositorySystem;
+
+ public ArtifactRepositoryLayout getLayout( String layoutId )
+ throws UnknownRepositoryLayoutException
+ {
+ return factory.getLayout( layoutId );
+ }
+
+ public ArtifactRepository createDeploymentArtifactRepository( String id, String url, String layoutId,
+ boolean uniqueVersion )
+ throws UnknownRepositoryLayoutException
+ {
+ return injectSession( factory.createDeploymentArtifactRepository( id, url, layoutId, uniqueVersion ), false );
+ }
+
+ public ArtifactRepository createDeploymentArtifactRepository( String id, String url,
+ ArtifactRepositoryLayout repositoryLayout,
+ boolean uniqueVersion )
+ {
+ return injectSession( factory.createDeploymentArtifactRepository( id, url, repositoryLayout, uniqueVersion ),
+ false );
+ }
+
+ public ArtifactRepository createArtifactRepository( String id, String url, String layoutId,
+ ArtifactRepositoryPolicy snapshots,
+ ArtifactRepositoryPolicy releases )
+ throws UnknownRepositoryLayoutException
+ {
+ return injectSession( factory.createArtifactRepository( id, url, layoutId, snapshots, releases ), true );
+ }
+
+ public ArtifactRepository createArtifactRepository( String id, String url,
+ ArtifactRepositoryLayout repositoryLayout,
+ ArtifactRepositoryPolicy snapshots,
+ ArtifactRepositoryPolicy releases )
+ {
+ return injectSession( factory.createArtifactRepository( id, url, repositoryLayout, snapshots, releases ), true );
+ }
+
+ public void setGlobalUpdatePolicy( String updatePolicy )
+ {
+ factory.setGlobalUpdatePolicy( updatePolicy );
+ }
+
+ public void setGlobalChecksumPolicy( String checksumPolicy )
+ {
+ factory.setGlobalChecksumPolicy( checksumPolicy );
+ }
+
+ private ArtifactRepository injectSession( ArtifactRepository repository, boolean mirrors )
+ {
+ RepositorySystemSession session = legacySupport.getRepositorySession();
+
+ if ( session != null && repository != null && !isLocalRepository( repository ) )
+ {
+ List<ArtifactRepository> repositories = Arrays.asList( repository );
+
+ if ( mirrors )
+ {
+ repositorySystem.injectMirror( session, repositories );
+ }
+
+ repositorySystem.injectProxy( session, repositories );
+
+ repositorySystem.injectAuthentication( session, repositories );
+ }
+
+ return repository;
+ }
+
+ private boolean isLocalRepository( ArtifactRepository repository )
+ {
+ // unfortunately, the API doesn't allow to tell a remote repo and the local repo apart...
+ return "local".equals( repository.getId() );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/repository/layout/FlatRepositoryLayout.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/repository/layout/FlatRepositoryLayout.java
new file mode 100644
index 00000000..8553a312
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/repository/layout/FlatRepositoryLayout.java
@@ -0,0 +1,92 @@
+package org.apache.maven.artifact.repository.layout;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.handler.ArtifactHandler;
+import org.apache.maven.artifact.metadata.ArtifactMetadata;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.codehaus.plexus.component.annotations.Component;
+
+/**
+ * The code in this class is taken from DefaultRepositorylayout, located at:
+ * http://svn.apache.org/viewvc/maven/components/trunk/maven-artifact/src/main/java/org/apache/maven/artifact/repository/layout/DefaultRepositoryLayout.java
+ *
+ */
+@Component( role = ArtifactRepositoryLayout.class, hint = "flat" )
+public class FlatRepositoryLayout
+ implements ArtifactRepositoryLayout
+{
+ private static final char ARTIFACT_SEPARATOR = '-';
+
+ private static final char GROUP_SEPARATOR = '.';
+
+ public String getId()
+ {
+ return "flat";
+ }
+
+ public String pathOf( Artifact artifact )
+ {
+ ArtifactHandler artifactHandler = artifact.getArtifactHandler();
+
+ StringBuilder path = new StringBuilder( 128 );
+
+ path.append( artifact.getArtifactId() ).append( ARTIFACT_SEPARATOR ).append( artifact.getVersion() );
+
+ if ( artifact.hasClassifier() )
+ {
+ path.append( ARTIFACT_SEPARATOR ).append( artifact.getClassifier() );
+ }
+
+ if ( artifactHandler.getExtension() != null && artifactHandler.getExtension().length() > 0 )
+ {
+ path.append( GROUP_SEPARATOR ).append( artifactHandler.getExtension() );
+ }
+
+ return path.toString();
+ }
+
+ public String pathOfLocalRepositoryMetadata( ArtifactMetadata metadata, ArtifactRepository repository )
+ {
+ return pathOfRepositoryMetadata( metadata.getLocalFilename( repository ) );
+ }
+
+ private String pathOfRepositoryMetadata( String filename )
+ {
+ StringBuilder path = new StringBuilder( 128 );
+
+ path.append( filename );
+
+ return path.toString();
+ }
+
+ public String pathOfRemoteRepositoryMetadata( ArtifactMetadata metadata )
+ {
+ return pathOfRepositoryMetadata( metadata.getRemoteFilename() );
+ }
+
+ @Override
+ public String toString()
+ {
+ return getId();
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/repository/metadata/DefaultRepositoryMetadataManager.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/repository/metadata/DefaultRepositoryMetadataManager.java
new file mode 100644
index 00000000..e7937134
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/repository/metadata/DefaultRepositoryMetadataManager.java
@@ -0,0 +1,558 @@
+package org.apache.maven.artifact.repository.metadata;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.Reader;
+import java.io.Writer;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.maven.artifact.metadata.ArtifactMetadata;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy;
+import org.apache.maven.artifact.repository.DefaultRepositoryRequest;
+import org.apache.maven.artifact.repository.RepositoryRequest;
+import org.apache.maven.artifact.repository.metadata.io.xpp3.MetadataXpp3Reader;
+import org.apache.maven.artifact.repository.metadata.io.xpp3.MetadataXpp3Writer;
+import org.apache.maven.repository.legacy.UpdateCheckManager;
+import org.apache.maven.repository.legacy.WagonManager;
+import org.apache.maven.wagon.ResourceDoesNotExistException;
+import org.apache.maven.wagon.TransferFailedException;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+import org.codehaus.plexus.logging.AbstractLogEnabled;
+import org.codehaus.plexus.util.IOUtil;
+import org.codehaus.plexus.util.ReaderFactory;
+import org.codehaus.plexus.util.WriterFactory;
+import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
+
+/**
+ * @author Jason van Zyl
+ */
+@Component( role = RepositoryMetadataManager.class )
+public class DefaultRepositoryMetadataManager
+ extends AbstractLogEnabled
+ implements RepositoryMetadataManager
+{
+ @Requirement
+ private WagonManager wagonManager;
+
+ @Requirement
+ private UpdateCheckManager updateCheckManager;
+
+ public void resolve( RepositoryMetadata metadata, List<ArtifactRepository> remoteRepositories,
+ ArtifactRepository localRepository )
+ throws RepositoryMetadataResolutionException
+ {
+ RepositoryRequest request = new DefaultRepositoryRequest();
+ request.setLocalRepository( localRepository );
+ request.setRemoteRepositories( remoteRepositories );
+ resolve( metadata, request );
+ }
+
+ public void resolve( RepositoryMetadata metadata, RepositoryRequest request )
+ throws RepositoryMetadataResolutionException
+ {
+ ArtifactRepository localRepo = request.getLocalRepository();
+ List<ArtifactRepository> remoteRepositories = request.getRemoteRepositories();
+
+ if ( !request.isOffline() )
+ {
+ Date localCopyLastModified = null;
+ if ( metadata.getBaseVersion() != null )
+ {
+ localCopyLastModified = getLocalCopyLastModified( localRepo, metadata );
+ }
+
+ for ( ArtifactRepository repository : remoteRepositories )
+ {
+ ArtifactRepositoryPolicy policy = metadata.getPolicy( repository );
+
+ File file =
+ new File( localRepo.getBasedir(), localRepo.pathOfLocalRepositoryMetadata( metadata, repository ) );
+ boolean update;
+
+ if ( !policy.isEnabled() )
+ {
+ update = false;
+
+ if ( getLogger().isDebugEnabled() )
+ {
+ getLogger().debug(
+ "Skipping update check for " + metadata.getKey() + " (" + file
+ + ") from disabled repository " + repository.getId() + " ("
+ + repository.getUrl() + ")" );
+ }
+ }
+ else if ( request.isForceUpdate() )
+ {
+ update = true;
+ }
+ else if ( localCopyLastModified != null && !policy.checkOutOfDate( localCopyLastModified ) )
+ {
+ update = false;
+
+ if ( getLogger().isDebugEnabled() )
+ {
+ getLogger().debug(
+ "Skipping update check for " + metadata.getKey() + " (" + file
+ + ") from repository " + repository.getId() + " (" + repository.getUrl()
+ + ") in favor of local copy" );
+ }
+ }
+ else
+ {
+ update = updateCheckManager.isUpdateRequired( metadata, repository, file );
+ }
+
+ if ( update )
+ {
+ getLogger().info( metadata.getKey() + ": checking for updates from " + repository.getId() );
+ try
+ {
+ wagonManager.getArtifactMetadata( metadata, repository, file, policy.getChecksumPolicy() );
+ }
+ catch ( ResourceDoesNotExistException e )
+ {
+ getLogger().debug( metadata + " could not be found on repository: " + repository.getId() );
+
+ // delete the local copy so the old details aren't used.
+ if ( file.exists() )
+ {
+ if ( !file.delete() )
+ {
+ // sleep for 10ms just in case this is windows holding a file lock
+ try
+ {
+ Thread.sleep( 10 );
+ }
+ catch ( InterruptedException ie )
+ {
+ // ignore
+ }
+ file.delete(); // if this fails, forget about it
+ }
+ }
+ }
+ catch ( TransferFailedException e )
+ {
+ getLogger().warn( metadata + " could not be retrieved from repository: " + repository.getId()
+ + " due to an error: " + e.getMessage() );
+ getLogger().debug( "Exception", e );
+ }
+ finally
+ {
+ updateCheckManager.touch( metadata, repository, file );
+ }
+ }
+
+ // TODO: should this be inside the above check?
+ // touch file so that this is not checked again until interval has passed
+ if ( file.exists() )
+ {
+ file.setLastModified( System.currentTimeMillis() );
+ }
+ }
+ }
+
+ try
+ {
+ mergeMetadata( metadata, remoteRepositories, localRepo );
+ }
+ catch ( RepositoryMetadataStoreException e )
+ {
+ throw new RepositoryMetadataResolutionException( "Unable to store local copy of metadata: "
+ + e.getMessage(), e );
+ }
+ }
+
+ private Date getLocalCopyLastModified( ArtifactRepository localRepository, RepositoryMetadata metadata )
+ {
+ String metadataPath = localRepository.pathOfLocalRepositoryMetadata( metadata, localRepository );
+ File metadataFile = new File( localRepository.getBasedir(), metadataPath );
+ return metadataFile.isFile() ? new Date( metadataFile.lastModified() ) : null;
+ }
+
+ private void mergeMetadata( RepositoryMetadata metadata, List<ArtifactRepository> remoteRepositories,
+ ArtifactRepository localRepository )
+ throws RepositoryMetadataStoreException
+ {
+ // TODO: currently this is first wins, but really we should take the latest by comparing either the
+ // snapshot timestamp, or some other timestamp later encoded into the metadata.
+ // TODO: this needs to be repeated here so the merging doesn't interfere with the written metadata
+ // - we'd be much better having a pristine input, and an ongoing metadata for merging instead
+
+ Map<ArtifactRepository, Metadata> previousMetadata = new HashMap<ArtifactRepository, Metadata>();
+ ArtifactRepository selected = null;
+ for ( ArtifactRepository repository : remoteRepositories )
+ {
+ ArtifactRepositoryPolicy policy = metadata.getPolicy( repository );
+
+ if ( policy.isEnabled() && loadMetadata( metadata, repository, localRepository, previousMetadata ) )
+ {
+ metadata.setRepository( repository );
+ selected = repository;
+ }
+ }
+ if ( loadMetadata( metadata, localRepository, localRepository, previousMetadata ) )
+ {
+ metadata.setRepository( null );
+ selected = localRepository;
+ }
+
+ updateSnapshotMetadata( metadata, previousMetadata, selected, localRepository );
+ }
+
+ private void updateSnapshotMetadata( RepositoryMetadata metadata,
+ Map<ArtifactRepository, Metadata> previousMetadata,
+ ArtifactRepository selected, ArtifactRepository localRepository )
+ throws RepositoryMetadataStoreException
+ {
+ // TODO: this could be a lot nicer... should really be in the snapshot transformation?
+ if ( metadata.isSnapshot() )
+ {
+ Metadata prevMetadata = metadata.getMetadata();
+
+ for ( ArtifactRepository repository : previousMetadata.keySet() )
+ {
+ Metadata m = previousMetadata.get( repository );
+ if ( repository.equals( selected ) )
+ {
+ if ( m.getVersioning() == null )
+ {
+ m.setVersioning( new Versioning() );
+ }
+
+ if ( m.getVersioning().getSnapshot() == null )
+ {
+ m.getVersioning().setSnapshot( new Snapshot() );
+ }
+ }
+ else
+ {
+ if ( ( m.getVersioning() != null ) && ( m.getVersioning().getSnapshot() != null )
+ && m.getVersioning().getSnapshot().isLocalCopy() )
+ {
+ m.getVersioning().getSnapshot().setLocalCopy( false );
+ metadata.setMetadata( m );
+ metadata.storeInLocalRepository( localRepository, repository );
+ }
+ }
+ }
+
+ metadata.setMetadata( prevMetadata );
+ }
+ }
+
+ private boolean loadMetadata( RepositoryMetadata repoMetadata, ArtifactRepository remoteRepository,
+ ArtifactRepository localRepository, Map<ArtifactRepository,
+ Metadata> previousMetadata )
+ {
+ boolean setRepository = false;
+
+ File metadataFile =
+ new File( localRepository.getBasedir(), localRepository.pathOfLocalRepositoryMetadata( repoMetadata,
+ remoteRepository ) );
+
+ if ( metadataFile.exists() )
+ {
+ Metadata metadata;
+
+ try
+ {
+ metadata = readMetadata( metadataFile );
+ }
+ catch ( RepositoryMetadataReadException e )
+ {
+ if ( getLogger().isDebugEnabled() )
+ {
+ getLogger().warn( e.getMessage(), e );
+ }
+ else
+ {
+ getLogger().warn( e.getMessage() );
+ }
+ return setRepository;
+ }
+
+ if ( repoMetadata.isSnapshot() && ( previousMetadata != null ) )
+ {
+ previousMetadata.put( remoteRepository, metadata );
+ }
+
+ if ( repoMetadata.getMetadata() != null )
+ {
+ setRepository = repoMetadata.getMetadata().merge( metadata );
+ }
+ else
+ {
+ repoMetadata.setMetadata( metadata );
+ setRepository = true;
+ }
+ }
+ return setRepository;
+ }
+
+ /** @todo share with DefaultPluginMappingManager. */
+ protected Metadata readMetadata( File mappingFile )
+ throws RepositoryMetadataReadException
+ {
+ Metadata result;
+
+ Reader reader = null;
+ try
+ {
+ reader = ReaderFactory.newXmlReader( mappingFile );
+
+ MetadataXpp3Reader mappingReader = new MetadataXpp3Reader();
+
+ result = mappingReader.read( reader, false );
+ }
+ catch ( FileNotFoundException e )
+ {
+ throw new RepositoryMetadataReadException( "Cannot read metadata from '" + mappingFile + "'", e );
+ }
+ catch ( IOException e )
+ {
+ throw new RepositoryMetadataReadException( "Cannot read metadata from '" + mappingFile + "': "
+ + e.getMessage(), e );
+ }
+ catch ( XmlPullParserException e )
+ {
+ throw new RepositoryMetadataReadException( "Cannot read metadata from '" + mappingFile + "': "
+ + e.getMessage(), e );
+ }
+ finally
+ {
+ IOUtil.close( reader );
+ }
+
+ return result;
+ }
+
+ /**
+ * Ensures the last updated timestamp of the specified metadata does not refer to the future and fixes the local
+ * metadata if necessary to allow proper merging/updating of metadata during deployment.
+ */
+ private void fixTimestamp( File metadataFile, Metadata metadata, Metadata reference )
+ {
+ boolean changed = false;
+
+ if ( metadata != null && reference != null )
+ {
+ Versioning versioning = metadata.getVersioning();
+ Versioning versioningRef = reference.getVersioning();
+ if ( versioning != null && versioningRef != null )
+ {
+ String lastUpdated = versioning.getLastUpdated();
+ String now = versioningRef.getLastUpdated();
+ if ( lastUpdated != null && now != null && now.compareTo( lastUpdated ) < 0 )
+ {
+ getLogger().warn(
+ "The last updated timestamp in " + metadataFile + " refers to the future (now = "
+ + now + ", lastUpdated = " + lastUpdated
+ + "). Please verify that the clocks of all"
+ + " deploying machines are reasonably synchronized." );
+ versioning.setLastUpdated( now );
+ changed = true;
+ }
+ }
+ }
+
+ if ( changed )
+ {
+ getLogger().debug( "Repairing metadata in " + metadataFile );
+
+ Writer writer = null;
+ try
+ {
+ writer = WriterFactory.newXmlWriter( metadataFile );
+ new MetadataXpp3Writer().write( writer, metadata );
+ }
+ catch ( IOException e )
+ {
+ String msg = "Could not write fixed metadata to " + metadataFile + ": " + e.getMessage();
+ if ( getLogger().isDebugEnabled() )
+ {
+ getLogger().warn( msg, e );
+ }
+ else
+ {
+ getLogger().warn( msg );
+ }
+ }
+ finally
+ {
+ IOUtil.close( writer );
+ }
+ }
+ }
+
+ public void resolveAlways( RepositoryMetadata metadata, ArtifactRepository localRepository,
+ ArtifactRepository remoteRepository )
+ throws RepositoryMetadataResolutionException
+ {
+ File file;
+ try
+ {
+ file = getArtifactMetadataFromDeploymentRepository( metadata, localRepository, remoteRepository );
+ }
+ catch ( TransferFailedException e )
+ {
+ throw new RepositoryMetadataResolutionException( metadata + " could not be retrieved from repository: "
+ + remoteRepository.getId() + " due to an error: " + e.getMessage(), e );
+ }
+
+ try
+ {
+ if ( file.exists() )
+ {
+ Metadata prevMetadata = readMetadata( file );
+ metadata.setMetadata( prevMetadata );
+ }
+ }
+ catch ( RepositoryMetadataReadException e )
+ {
+ throw new RepositoryMetadataResolutionException( e.getMessage(), e );
+ }
+ }
+
+ private File getArtifactMetadataFromDeploymentRepository( ArtifactMetadata metadata,
+ ArtifactRepository localRepo,
+ ArtifactRepository remoteRepository )
+ throws TransferFailedException
+ {
+ File file =
+ new File( localRepo.getBasedir(), localRepo.pathOfLocalRepositoryMetadata( metadata, remoteRepository ) );
+
+ try
+ {
+ wagonManager.getArtifactMetadataFromDeploymentRepository( metadata, remoteRepository, file,
+ ArtifactRepositoryPolicy.CHECKSUM_POLICY_WARN );
+ }
+ catch ( ResourceDoesNotExistException e )
+ {
+ getLogger().info( metadata + " could not be found on repository: " + remoteRepository.getId()
+ + ", so will be created" );
+
+ // delete the local copy so the old details aren't used.
+ if ( file.exists() )
+ {
+ if ( !file.delete() )
+ {
+ // sleep for 10ms just in case this is windows holding a file lock
+ try
+ {
+ Thread.sleep( 10 );
+ }
+ catch ( InterruptedException ie )
+ {
+ // ignore
+ }
+ file.delete(); // if this fails, forget about it
+ }
+ }
+ }
+ finally
+ {
+ if ( metadata instanceof RepositoryMetadata )
+ {
+ updateCheckManager.touch( (RepositoryMetadata) metadata, remoteRepository, file );
+ }
+ }
+ return file;
+ }
+
+ public void deploy( ArtifactMetadata metadata, ArtifactRepository localRepository,
+ ArtifactRepository deploymentRepository )
+ throws RepositoryMetadataDeploymentException
+ {
+ File file;
+ if ( metadata instanceof RepositoryMetadata )
+ {
+ getLogger().info( "Retrieving previous metadata from " + deploymentRepository.getId() );
+ try
+ {
+ file = getArtifactMetadataFromDeploymentRepository( metadata, localRepository, deploymentRepository );
+ }
+ catch ( TransferFailedException e )
+ {
+ throw new RepositoryMetadataDeploymentException( metadata + " could not be retrieved from repository: "
+ + deploymentRepository.getId() + " due to an error: " + e.getMessage(), e );
+ }
+
+ if ( file.isFile() )
+ {
+ try
+ {
+ fixTimestamp( file, readMetadata( file ), ( (RepositoryMetadata) metadata ).getMetadata() );
+ }
+ catch ( RepositoryMetadataReadException e )
+ {
+ // will be reported via storeInlocalRepository
+ }
+ }
+ }
+ else
+ {
+ // It's a POM - we don't need to retrieve it first
+ file =
+ new File( localRepository.getBasedir(),
+ localRepository.pathOfLocalRepositoryMetadata( metadata, deploymentRepository ) );
+ }
+
+ try
+ {
+ metadata.storeInLocalRepository( localRepository, deploymentRepository );
+ }
+ catch ( RepositoryMetadataStoreException e )
+ {
+ throw new RepositoryMetadataDeploymentException( "Error installing metadata: " + e.getMessage(), e );
+ }
+
+ try
+ {
+ wagonManager.putArtifactMetadata( file, metadata, deploymentRepository );
+ }
+ catch ( TransferFailedException e )
+ {
+ throw new RepositoryMetadataDeploymentException( "Error while deploying metadata: " + e.getMessage(), e );
+ }
+ }
+
+ public void install( ArtifactMetadata metadata, ArtifactRepository localRepository )
+ throws RepositoryMetadataInstallationException
+ {
+ try
+ {
+ metadata.storeInLocalRepository( localRepository, localRepository );
+ }
+ catch ( RepositoryMetadataStoreException e )
+ {
+ throw new RepositoryMetadataInstallationException( "Error installing metadata: " + e.getMessage(), e );
+ }
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/repository/metadata/GroupRepositoryMetadata.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/repository/metadata/GroupRepositoryMetadata.java
new file mode 100644
index 00000000..490b47f3
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/repository/metadata/GroupRepositoryMetadata.java
@@ -0,0 +1,119 @@
+package org.apache.maven.artifact.repository.metadata;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.artifact.repository.ArtifactRepository;
+
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Metadata for the group directory of the repository.
+ *
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ */
+public class GroupRepositoryMetadata
+ extends AbstractRepositoryMetadata
+{
+ private final String groupId;
+
+ public GroupRepositoryMetadata( String groupId )
+ {
+ super( new Metadata() );
+ this.groupId = groupId;
+ }
+
+ public boolean storedInGroupDirectory()
+ {
+ return true;
+ }
+
+ public boolean storedInArtifactVersionDirectory()
+ {
+ return false;
+ }
+
+ public String getGroupId()
+ {
+ return groupId;
+ }
+
+ public String getArtifactId()
+ {
+ return null;
+ }
+
+ public String getBaseVersion()
+ {
+ return null;
+ }
+
+ public void addPluginMapping( String goalPrefix,
+ String artifactId )
+ {
+ addPluginMapping( goalPrefix, artifactId, artifactId );
+ }
+
+ public void addPluginMapping( String goalPrefix,
+ String artifactId,
+ String name )
+ {
+ List plugins = getMetadata().getPlugins();
+ boolean found = false;
+ for ( Iterator i = plugins.iterator(); i.hasNext() && !found; )
+ {
+ Plugin plugin = (Plugin) i.next();
+ if ( plugin.getPrefix().equals( goalPrefix ) )
+ {
+ found = true;
+ }
+ }
+ if ( !found )
+ {
+ Plugin plugin = new Plugin();
+ plugin.setPrefix( goalPrefix );
+ plugin.setArtifactId( artifactId );
+ plugin.setName( name );
+
+
+ getMetadata().addPlugin( plugin );
+ }
+ }
+
+ public Object getKey()
+ {
+ return groupId;
+ }
+
+ public boolean isSnapshot()
+ {
+ return false;
+ }
+
+ public ArtifactRepository getRepository()
+ {
+ return null;
+ }
+
+ public void setRepository( ArtifactRepository remoteRepository )
+ {
+ // intentionally blank
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/repository/metadata/MetadataBridge.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/repository/metadata/MetadataBridge.java
new file mode 100644
index 00000000..bf199218
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/repository/metadata/MetadataBridge.java
@@ -0,0 +1,172 @@
+package org.apache.maven.artifact.repository.metadata;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.util.Collections;
+import java.util.Map;
+
+import org.apache.maven.artifact.metadata.ArtifactMetadata;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.repository.DefaultArtifactRepository;
+import org.codehaus.plexus.util.FileUtils;
+import org.eclipse.aether.RepositoryException;
+import org.eclipse.aether.metadata.AbstractMetadata;
+import org.eclipse.aether.metadata.MergeableMetadata;
+import org.eclipse.aether.metadata.Metadata;
+
+/**
+ * <strong>Warning:</strong> This is an internal utility class that is only public for technical reasons, it is not part
+ * of the public API. In particular, this class can be changed or deleted without prior notice.
+ *
+ * @author Benjamin Bentmann
+ */
+public final class MetadataBridge
+ extends AbstractMetadata
+ implements MergeableMetadata
+{
+
+ private ArtifactMetadata metadata;
+
+ private boolean merged;
+
+ public MetadataBridge( ArtifactMetadata metadata )
+ {
+ this.metadata = metadata;
+ }
+
+ public void merge( File current, File result )
+ throws RepositoryException
+ {
+ try
+ {
+ if ( current.exists() )
+ {
+ FileUtils.copyFile( current, result );
+ }
+ ArtifactRepository localRepo = new MetadataRepository( result );
+ metadata.storeInLocalRepository( localRepo, localRepo );
+ merged = true;
+ }
+ catch ( Exception e )
+ {
+ throw new RepositoryException( e.getMessage(), e );
+ }
+ }
+
+ public boolean isMerged()
+ {
+ return merged;
+ }
+
+ public String getGroupId()
+ {
+ return emptify( metadata.getGroupId() );
+ }
+
+ public String getArtifactId()
+ {
+ return metadata.storedInGroupDirectory() ? "" : emptify( metadata.getArtifactId() );
+ }
+
+ public String getVersion()
+ {
+ return metadata.storedInArtifactVersionDirectory() ? emptify( metadata.getBaseVersion() ) : "";
+ }
+
+ public String getType()
+ {
+ return metadata.getRemoteFilename();
+ }
+
+ private String emptify( String string )
+ {
+ return ( string != null ) ? string : "";
+ }
+
+ public File getFile()
+ {
+ return null;
+ }
+
+ public MetadataBridge setFile( File file )
+ {
+ return this;
+ }
+
+ public Nature getNature()
+ {
+ if ( metadata instanceof RepositoryMetadata )
+ {
+ switch ( ( (RepositoryMetadata) metadata ).getNature() )
+ {
+ case RepositoryMetadata.RELEASE_OR_SNAPSHOT:
+ return Nature.RELEASE_OR_SNAPSHOT;
+ case RepositoryMetadata.SNAPSHOT:
+ return Nature.SNAPSHOT;
+ default:
+ return Nature.RELEASE;
+ }
+ }
+ else
+ {
+ return Nature.RELEASE;
+ }
+ }
+
+ public Map<String, String> getProperties()
+ {
+ return Collections.emptyMap();
+ }
+
+ @Override
+ public Metadata setProperties( Map<String, String> properties )
+ {
+ return this;
+ }
+
+ @SuppressWarnings( "deprecation" )
+ static class MetadataRepository
+ extends DefaultArtifactRepository
+ {
+
+ private File metadataFile;
+
+ public MetadataRepository( File metadataFile )
+ {
+ super( "local", "", null );
+ this.metadataFile = metadataFile;
+ }
+
+ @Override
+ public String getBasedir()
+ {
+ return metadataFile.getParent();
+ }
+
+ @Override
+ public String pathOfLocalRepositoryMetadata( ArtifactMetadata metadata, ArtifactRepository repository )
+ {
+ return metadataFile.getName();
+ }
+
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/repository/metadata/MetadataUtils.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/repository/metadata/MetadataUtils.java
new file mode 100644
index 00000000..bdc4a795
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/repository/metadata/MetadataUtils.java
@@ -0,0 +1,39 @@
+package org.apache.maven.artifact.repository.metadata;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Assists in handling repository metadata.
+ *
+ * @author Benjamin Bentmann
+ */
+class MetadataUtils
+{
+
+ public static Metadata cloneMetadata( Metadata src )
+ {
+ if ( src == null )
+ {
+ return null;
+ }
+ return src.clone();
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/repository/metadata/RepositoryMetadataReadException.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/repository/metadata/RepositoryMetadataReadException.java
new file mode 100644
index 00000000..23e59841
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/repository/metadata/RepositoryMetadataReadException.java
@@ -0,0 +1,40 @@
+package org.apache.maven.artifact.repository.metadata;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Problem storing the repository metadata in the local repository.
+ *
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ */
+public class RepositoryMetadataReadException
+ extends Exception
+{
+ public RepositoryMetadataReadException( String message )
+ {
+ super( message );
+ }
+
+ public RepositoryMetadataReadException( String message,
+ Exception e )
+ {
+ super( message, e );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/repository/metadata/SnapshotArtifactRepositoryMetadata.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/repository/metadata/SnapshotArtifactRepositoryMetadata.java
new file mode 100644
index 00000000..359ab2ce
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/repository/metadata/SnapshotArtifactRepositoryMetadata.java
@@ -0,0 +1,98 @@
+package org.apache.maven.artifact.repository.metadata;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+
+/**
+ * Metadata for the artifact version directory of the repository.
+ *
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ * @todo split instantiation (versioning, plugin mappings) from definition
+ */
+public class SnapshotArtifactRepositoryMetadata
+ extends AbstractRepositoryMetadata
+{
+ private Artifact artifact;
+
+ public SnapshotArtifactRepositoryMetadata( Artifact artifact )
+ {
+ super( createMetadata( artifact, null ) );
+ this.artifact = artifact;
+ }
+
+ public SnapshotArtifactRepositoryMetadata( Artifact artifact,
+ Snapshot snapshot )
+ {
+ super( createMetadata( artifact, createVersioning( snapshot ) ) );
+ this.artifact = artifact;
+ }
+
+ public boolean storedInGroupDirectory()
+ {
+ return false;
+ }
+
+ public boolean storedInArtifactVersionDirectory()
+ {
+ return true;
+ }
+
+ public String getGroupId()
+ {
+ return artifact.getGroupId();
+ }
+
+ public String getArtifactId()
+ {
+ return artifact.getArtifactId();
+ }
+
+ public String getBaseVersion()
+ {
+ return artifact.getBaseVersion();
+ }
+
+ public Object getKey()
+ {
+ return "snapshot " + artifact.getGroupId() + ":" + artifact.getArtifactId() + ":" + artifact.getBaseVersion();
+ }
+
+ public boolean isSnapshot()
+ {
+ return artifact.isSnapshot();
+ }
+
+ public int getNature()
+ {
+ return isSnapshot() ? SNAPSHOT : RELEASE;
+ }
+
+ public ArtifactRepository getRepository()
+ {
+ return artifact.getRepository();
+ }
+
+ public void setRepository( ArtifactRepository remoteRepository )
+ {
+ artifact.setRepository( remoteRepository );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/resolver/ArtifactCollector.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/resolver/ArtifactCollector.java
new file mode 100644
index 00000000..5ef86022
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/resolver/ArtifactCollector.java
@@ -0,0 +1,42 @@
+package org.apache.maven.artifact.resolver;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.List;
+import java.util.Set;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
+
+@Deprecated
+public interface ArtifactCollector
+ extends org.apache.maven.repository.legacy.resolver.LegacyArtifactCollector
+{
+
+ @Deprecated
+ ArtifactResolutionResult collect( Set<Artifact> artifacts, Artifact originatingArtifact,
+ ArtifactRepository localRepository, List<ArtifactRepository> remoteRepositories,
+ ArtifactMetadataSource source, ArtifactFilter filter,
+ List<ResolutionListener> listeners )
+ throws ArtifactResolutionException;
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/resolver/ArtifactResolver.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/resolver/ArtifactResolver.java
new file mode 100644
index 00000000..0ca940a1
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/resolver/ArtifactResolver.java
@@ -0,0 +1,108 @@
+package org.apache.maven.artifact.resolver;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
+import org.apache.maven.wagon.events.TransferListener;
+
+/**
+ * @author Jason van Zyl
+ */
+// Just hide the one method we want behind the RepositorySystem interface.
+public interface ArtifactResolver
+{
+
+ ArtifactResolutionResult resolve( ArtifactResolutionRequest request );
+
+ // The rest is deprecated
+
+ // USED BY MAVEN ASSEMBLY PLUGIN 2.2-beta-2
+ @Deprecated
+ String ROLE = ArtifactResolver.class.getName();
+
+ // USED BY SUREFIRE, DEPENDENCY PLUGIN
+ @Deprecated
+ ArtifactResolutionResult resolveTransitively( Set<Artifact> artifacts, Artifact originatingArtifact,
+ ArtifactRepository localRepository,
+ List<ArtifactRepository> remoteRepositories,
+ ArtifactMetadataSource source, ArtifactFilter filter )
+ throws ArtifactResolutionException, ArtifactNotFoundException;
+
+ // USED BY MAVEN ASSEMBLY PLUGIN
+ @Deprecated
+ ArtifactResolutionResult resolveTransitively( Set<Artifact> artifacts, Artifact originatingArtifact,
+ Map managedVersions, ArtifactRepository localRepository,
+ List<ArtifactRepository> remoteRepositories,
+ ArtifactMetadataSource source )
+ throws ArtifactResolutionException, ArtifactNotFoundException;
+
+ // USED BY MAVEN ASSEMBLY PLUGIN
+ @Deprecated
+ ArtifactResolutionResult resolveTransitively( Set<Artifact> artifacts, Artifact originatingArtifact,
+ Map managedVersions, ArtifactRepository localRepository,
+ List<ArtifactRepository> remoteRepositories,
+ ArtifactMetadataSource source, ArtifactFilter filter )
+ throws ArtifactResolutionException, ArtifactNotFoundException;
+
+ @Deprecated
+ ArtifactResolutionResult resolveTransitively( Set<Artifact> artifacts, Artifact originatingArtifact,
+ List<ArtifactRepository> remoteRepositories,
+ ArtifactRepository localRepository, ArtifactMetadataSource source )
+ throws ArtifactResolutionException, ArtifactNotFoundException;
+
+ @Deprecated
+ ArtifactResolutionResult resolveTransitively( Set<Artifact> artifacts, Artifact originatingArtifact,
+ Map managedVersions, ArtifactRepository localRepository,
+ List<ArtifactRepository> remoteRepositories,
+ ArtifactMetadataSource source, ArtifactFilter filter,
+ List<ResolutionListener> listeners )
+ throws ArtifactResolutionException, ArtifactNotFoundException;
+
+ @Deprecated
+ ArtifactResolutionResult resolveTransitively( Set<Artifact> artifacts, Artifact originatingArtifact,
+ List<ArtifactRepository> remoteRepositories,
+ ArtifactRepository localRepository, ArtifactMetadataSource source,
+ List<ResolutionListener> listeners )
+ throws ArtifactResolutionException, ArtifactNotFoundException;
+
+ // USED BY REMOTE RESOURCES PLUGIN, DEPENDENCY PLUGIN
+ @Deprecated
+ void resolve( Artifact artifact, List<ArtifactRepository> remoteRepositories, ArtifactRepository localRepository )
+ throws ArtifactResolutionException, ArtifactNotFoundException;
+
+ // USED BY REMOTE RESOURCES PLUGIN
+ @Deprecated
+ void resolve( Artifact artifact, List<ArtifactRepository> remoteRepositories, ArtifactRepository localRepository,
+ TransferListener downloadMonitor )
+ throws ArtifactResolutionException, ArtifactNotFoundException;
+
+ // USED BY DEPENDENCY PLUGIN, ARCHETYPE DOWNLOADER
+ @Deprecated
+ void resolveAlways( Artifact artifact, List<ArtifactRepository> remoteRepositories,
+ ArtifactRepository localRepository )
+ throws ArtifactResolutionException, ArtifactNotFoundException;
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/resolver/DebugResolutionListener.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/resolver/DebugResolutionListener.java
new file mode 100644
index 00000000..b066e4c0
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/resolver/DebugResolutionListener.java
@@ -0,0 +1,167 @@
+package org.apache.maven.artifact.resolver;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.versioning.VersionRange;
+import org.codehaus.plexus.logging.Logger;
+
+/**
+ * Send resolution events to the debug log.
+ *
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ */
+public class DebugResolutionListener
+ implements ResolutionListener, ResolutionListenerForDepMgmt
+{
+ private Logger logger;
+
+ private String indent = "";
+
+ private static Set<Artifact> ignoredArtifacts = new HashSet<Artifact>();
+
+ public DebugResolutionListener( Logger logger )
+ {
+ this.logger = logger;
+ }
+
+ public void testArtifact( Artifact node )
+ {
+ }
+
+ public void startProcessChildren( Artifact artifact )
+ {
+ indent += " ";
+ }
+
+ public void endProcessChildren( Artifact artifact )
+ {
+ indent = indent.substring( 2 );
+ }
+
+ public void includeArtifact( Artifact artifact )
+ {
+ logger.debug( indent + artifact + " (selected for " + artifact.getScope() + ")" );
+ }
+
+ public void omitForNearer( Artifact omitted, Artifact kept )
+ {
+ String omittedVersion = omitted.getVersion();
+ String keptVersion = kept.getVersion();
+
+ if ( omittedVersion != null ? !omittedVersion.equals( keptVersion ) : keptVersion != null )
+ {
+ logger.debug( indent + omitted + " (removed - nearer found: " + kept.getVersion() + ")" );
+ }
+ }
+
+ public void omitForCycle( Artifact omitted )
+ {
+ logger.debug( indent + omitted + " (removed - causes a cycle in the graph)" );
+ }
+
+ public void updateScopeCurrentPom( Artifact artifact, String ignoredScope )
+ {
+ logger.debug( indent + artifact + " (not setting artifactScope to: " + ignoredScope + "; local artifactScope "
+ + artifact.getScope() + " wins)" );
+
+ // TODO: better way than static? this might hide messages in a reactor
+ if ( !ignoredArtifacts.contains( artifact ) )
+ {
+ logger.warn( "\n\tArtifact " + artifact + " retains local artifactScope '" + artifact.getScope()
+ + "' overriding broader artifactScope '" + ignoredScope + "'\n"
+ + "\tgiven by a dependency. If this is not intended, modify or remove the local artifactScope.\n" );
+ ignoredArtifacts.add( artifact );
+ }
+ }
+
+ public void updateScope( Artifact artifact, String scope )
+ {
+ logger.debug( indent + artifact + " (setting artifactScope to: " + scope + ")" );
+ }
+
+ public void selectVersionFromRange( Artifact artifact )
+ {
+ logger.debug( indent + artifact + " (setting version to: " + artifact.getVersion() + " from range: "
+ + artifact.getVersionRange() + ")" );
+ }
+
+ public void restrictRange( Artifact artifact, Artifact replacement, VersionRange newRange )
+ {
+ logger.debug( indent + artifact + " (range restricted from: " + artifact.getVersionRange() + " and: "
+ + replacement.getVersionRange() + " to: " + newRange + " )" );
+ }
+
+ /**
+ * The logic used here used to be a copy of the logic used in the DefaultArtifactCollector, and this method was
+ * called right before the actual version/artifactScope changes were done. However, a different set of conditionals (and
+ * more information) is needed to be able to determine when and if the version and/or artifactScope changes. See the two
+ * added methods, manageArtifactVersion and manageArtifactScope.
+ */
+ public void manageArtifact( Artifact artifact, Artifact replacement )
+ {
+ String msg = indent + artifact;
+ msg += " (";
+ if ( replacement.getVersion() != null )
+ {
+ msg += "applying version: " + replacement.getVersion() + ";";
+ }
+ if ( replacement.getScope() != null )
+ {
+ msg += "applying artifactScope: " + replacement.getScope();
+ }
+ msg += ")";
+ logger.debug( msg );
+ }
+
+ public void manageArtifactVersion( Artifact artifact, Artifact replacement )
+ {
+ // only show msg if a change is actually taking place
+ if ( !replacement.getVersion().equals( artifact.getVersion() ) )
+ {
+ String msg = indent + artifact + " (applying version: " + replacement.getVersion() + ")";
+ logger.debug( msg );
+ }
+ }
+
+ public void manageArtifactScope( Artifact artifact, Artifact replacement )
+ {
+ // only show msg if a change is actually taking place
+ if ( !replacement.getScope().equals( artifact.getScope() ) )
+ {
+ String msg = indent + artifact + " (applying artifactScope: " + replacement.getScope() + ")";
+ logger.debug( msg );
+ }
+ }
+
+ public void manageArtifactSystemPath( Artifact artifact, Artifact replacement )
+ {
+ // only show msg if a change is actually taking place
+ if ( !replacement.getScope().equals( artifact.getScope() ) )
+ {
+ String msg = indent + artifact + " (applying system path: " + replacement.getFile() + ")";
+ logger.debug( msg );
+ }
+ }
+
+} \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/resolver/DefaultArtifactCollector.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/resolver/DefaultArtifactCollector.java
new file mode 100644
index 00000000..cefb9e28
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/resolver/DefaultArtifactCollector.java
@@ -0,0 +1,30 @@
+package org.apache.maven.artifact.resolver;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.codehaus.plexus.component.annotations.Component;
+
+@Deprecated
+@Component( role = ArtifactCollector.class )
+public class DefaultArtifactCollector
+ extends org.apache.maven.repository.legacy.resolver.DefaultLegacyArtifactCollector
+ implements ArtifactCollector
+{
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/resolver/DefaultArtifactResolver.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/resolver/DefaultArtifactResolver.java
new file mode 100644
index 00000000..1631a013
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/resolver/DefaultArtifactResolver.java
@@ -0,0 +1,643 @@
+package org.apache.maven.artifact.resolver;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Executor;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.regex.Matcher;
+
+import org.apache.maven.RepositoryUtils;
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.factory.ArtifactFactory;
+import org.apache.maven.artifact.metadata.ArtifactMetadataRetrievalException;
+import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
+import org.apache.maven.artifact.metadata.ResolutionGroup;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.repository.LegacyLocalRepositoryManager;
+import org.apache.maven.artifact.repository.RepositoryRequest;
+import org.apache.maven.artifact.repository.metadata.Snapshot;
+import org.apache.maven.artifact.repository.metadata.SnapshotArtifactRepositoryMetadata;
+import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.plugin.LegacySupport;
+import org.apache.maven.repository.legacy.metadata.DefaultMetadataResolutionRequest;
+import org.apache.maven.repository.legacy.metadata.MetadataResolutionRequest;
+import org.apache.maven.repository.legacy.resolver.conflict.ConflictResolver;
+import org.apache.maven.wagon.events.TransferListener;
+import org.codehaus.plexus.PlexusContainer;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
+import org.codehaus.plexus.logging.Logger;
+import org.codehaus.plexus.personality.plexus.lifecycle.phase.Disposable;
+import org.eclipse.aether.RepositorySystem;
+import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.repository.LocalRepositoryManager;
+import org.eclipse.aether.resolution.ArtifactRequest;
+import org.eclipse.aether.resolution.ArtifactResult;
+
+/**
+ * @author Jason van Zyl
+ */
+@Component( role = ArtifactResolver.class )
+public class DefaultArtifactResolver
+ implements ArtifactResolver, Disposable
+{
+ @Requirement
+ private Logger logger;
+
+ @Requirement
+ protected ArtifactFactory artifactFactory;
+
+ @Requirement
+ private ArtifactCollector artifactCollector;
+
+ @Requirement
+ private ResolutionErrorHandler resolutionErrorHandler;
+
+ @Requirement
+ private ArtifactMetadataSource source;
+
+ @Requirement
+ private PlexusContainer container;
+
+ @Requirement
+ private LegacySupport legacySupport;
+
+ @Requirement
+ private RepositorySystem repoSystem;
+
+ private final Executor executor;
+
+ public DefaultArtifactResolver()
+ {
+ int threads = Integer.getInteger( "maven.artifact.threads", 5 );
+ if ( threads <= 1 )
+ {
+ executor = new Executor()
+ {
+ public void execute( Runnable command )
+ {
+ command.run();
+ }
+ };
+ }
+ else
+ {
+ executor =
+ new ThreadPoolExecutor( threads, threads, 3, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(),
+ new DaemonThreadCreator() );
+ }
+ }
+
+ private RepositorySystemSession getSession( ArtifactRepository localRepository )
+ {
+ return LegacyLocalRepositoryManager.overlay( localRepository, legacySupport.getRepositorySession(), repoSystem );
+ }
+
+ private void injectSession1( RepositoryRequest request, MavenSession session )
+ {
+ if ( session != null )
+ {
+ request.setOffline( session.isOffline() );
+ request.setForceUpdate( session.getRequest().isUpdateSnapshots() );
+ }
+ }
+
+ private void injectSession2( ArtifactResolutionRequest request, MavenSession session )
+ {
+ injectSession1( request, session );
+
+ if ( session != null )
+ {
+ request.setServers( session.getRequest().getServers() );
+ request.setMirrors( session.getRequest().getMirrors() );
+ request.setProxies( session.getRequest().getProxies() );
+ }
+ }
+
+ public void resolve( Artifact artifact, List<ArtifactRepository> remoteRepositories,
+ ArtifactRepository localRepository, TransferListener resolutionListener )
+ throws ArtifactResolutionException, ArtifactNotFoundException
+ {
+ resolve( artifact, remoteRepositories, getSession( localRepository ) );
+ }
+
+ public void resolveAlways( Artifact artifact, List<ArtifactRepository> remoteRepositories,
+ ArtifactRepository localRepository )
+ throws ArtifactResolutionException, ArtifactNotFoundException
+ {
+ resolve( artifact, remoteRepositories, getSession( localRepository ) );
+ }
+
+ private void resolve( Artifact artifact, List<ArtifactRepository> remoteRepositories,
+ RepositorySystemSession session )
+ throws ArtifactResolutionException, ArtifactNotFoundException
+ {
+ if ( artifact == null )
+ {
+ return;
+ }
+
+ if ( Artifact.SCOPE_SYSTEM.equals( artifact.getScope() ) )
+ {
+ File systemFile = artifact.getFile();
+
+ if ( systemFile == null )
+ {
+ throw new ArtifactNotFoundException( "System artifact: " + artifact + " has no file attached", artifact );
+ }
+
+ if ( !systemFile.exists() )
+ {
+ throw new ArtifactNotFoundException( "System artifact: " + artifact + " not found in path: " + systemFile, artifact );
+ }
+
+ if ( !systemFile.isFile() )
+ {
+ throw new ArtifactNotFoundException( "System artifact: " + artifact + " is not a file: " + systemFile, artifact );
+ }
+
+ artifact.setResolved( true );
+
+ return;
+ }
+
+ if ( !artifact.isResolved() )
+ {
+ ArtifactResult result;
+
+ try
+ {
+ ArtifactRequest artifactRequest = new ArtifactRequest();
+ artifactRequest.setArtifact( RepositoryUtils.toArtifact( artifact ) );
+ artifactRequest.setRepositories( RepositoryUtils.toRepos( remoteRepositories ) );
+
+ // Maven 2.x quirk: an artifact always points at the local repo, regardless whether resolved or not
+ LocalRepositoryManager lrm = session.getLocalRepositoryManager();
+ String path = lrm.getPathForLocalArtifact( artifactRequest.getArtifact() );
+ artifact.setFile( new File( lrm.getRepository().getBasedir(), path ) );
+
+ result = repoSystem.resolveArtifact( session, artifactRequest );
+ }
+ catch ( org.eclipse.aether.resolution.ArtifactResolutionException e )
+ {
+ if ( e.getCause() instanceof org.eclipse.aether.transfer.ArtifactNotFoundException )
+ {
+ throw new ArtifactNotFoundException( e.getMessage(), artifact, remoteRepositories, e );
+ }
+ else
+ {
+ throw new ArtifactResolutionException( e.getMessage(), artifact, remoteRepositories, e );
+ }
+ }
+
+ artifact.selectVersion( result.getArtifact().getVersion() );
+ artifact.setFile( result.getArtifact().getFile() );
+ artifact.setResolved( true );
+
+ if ( artifact.isSnapshot() )
+ {
+ Matcher matcher = Artifact.VERSION_FILE_PATTERN.matcher( artifact.getVersion() );
+ if ( matcher.matches() )
+ {
+ Snapshot snapshot = new Snapshot();
+ snapshot.setTimestamp( matcher.group( 2 ) );
+ try
+ {
+ snapshot.setBuildNumber( Integer.parseInt( matcher.group( 3 ) ) );
+ artifact.addMetadata( new SnapshotArtifactRepositoryMetadata( artifact, snapshot ) );
+ }
+ catch ( NumberFormatException e )
+ {
+ logger.warn( "Invalid artifact version " + artifact.getVersion() + ": " + e.getMessage() );
+ }
+ }
+ }
+ }
+ }
+
+ public ArtifactResolutionResult resolveTransitively( Set<Artifact> artifacts, Artifact originatingArtifact,
+ ArtifactRepository localRepository,
+ List<ArtifactRepository> remoteRepositories,
+ ArtifactMetadataSource source, ArtifactFilter filter )
+ throws ArtifactResolutionException, ArtifactNotFoundException
+ {
+ return resolveTransitively( artifacts, originatingArtifact, Collections.EMPTY_MAP, localRepository,
+ remoteRepositories, source, filter );
+
+ }
+
+ public ArtifactResolutionResult resolveTransitively( Set<Artifact> artifacts, Artifact originatingArtifact,
+ Map managedVersions, ArtifactRepository localRepository,
+ List<ArtifactRepository> remoteRepositories,
+ ArtifactMetadataSource source )
+ throws ArtifactResolutionException, ArtifactNotFoundException
+ {
+ return resolveTransitively( artifacts, originatingArtifact, managedVersions, localRepository,
+ remoteRepositories, source, null );
+ }
+
+ public ArtifactResolutionResult resolveTransitively( Set<Artifact> artifacts, Artifact originatingArtifact,
+ Map managedVersions, ArtifactRepository localRepository,
+ List<ArtifactRepository> remoteRepositories,
+ ArtifactMetadataSource source, ArtifactFilter filter )
+ throws ArtifactResolutionException, ArtifactNotFoundException
+ {
+ return resolveTransitively( artifacts, originatingArtifact, managedVersions, localRepository,
+ remoteRepositories, source, filter, null );
+ }
+
+ public ArtifactResolutionResult resolveTransitively( Set<Artifact> artifacts, Artifact originatingArtifact,
+ List<ArtifactRepository> remoteRepositories,
+ ArtifactRepository localRepository,
+ ArtifactMetadataSource source )
+ throws ArtifactResolutionException, ArtifactNotFoundException
+ {
+ return resolveTransitively( artifacts, originatingArtifact, localRepository, remoteRepositories, source, null );
+ }
+
+ public ArtifactResolutionResult resolveTransitively( Set<Artifact> artifacts, Artifact originatingArtifact,
+ List<ArtifactRepository> remoteRepositories,
+ ArtifactRepository localRepository,
+ ArtifactMetadataSource source,
+ List<ResolutionListener> listeners )
+ throws ArtifactResolutionException, ArtifactNotFoundException
+ {
+ return resolveTransitively( artifacts, originatingArtifact, Collections.EMPTY_MAP, localRepository,
+ remoteRepositories, source, null, listeners );
+ }
+
+ public ArtifactResolutionResult resolveTransitively( Set<Artifact> artifacts, Artifact originatingArtifact,
+ Map managedVersions, ArtifactRepository localRepository,
+ List<ArtifactRepository> remoteRepositories,
+ ArtifactMetadataSource source, ArtifactFilter filter,
+ List<ResolutionListener> listeners )
+ throws ArtifactResolutionException, ArtifactNotFoundException
+ {
+ return resolveTransitively( artifacts, originatingArtifact, managedVersions, localRepository,
+ remoteRepositories, source, filter, listeners, null );
+ }
+
+ public ArtifactResolutionResult resolveTransitively( Set<Artifact> artifacts, Artifact originatingArtifact,
+ Map managedVersions, ArtifactRepository localRepository,
+ List<ArtifactRepository> remoteRepositories,
+ ArtifactMetadataSource source, ArtifactFilter filter,
+ List<ResolutionListener> listeners,
+ List<ConflictResolver> conflictResolvers )
+ throws ArtifactResolutionException, ArtifactNotFoundException
+ {
+ ArtifactResolutionRequest request = new ArtifactResolutionRequest()
+ .setArtifact( originatingArtifact )
+ .setResolveRoot( false )
+ // This is required by the surefire plugin
+ .setArtifactDependencies( artifacts )
+ .setManagedVersionMap( managedVersions )
+ .setLocalRepository( localRepository )
+ .setRemoteRepositories( remoteRepositories )
+ .setCollectionFilter( filter )
+ .setListeners( listeners );
+
+ injectSession2( request, legacySupport.getSession() );
+
+ return resolveWithExceptions( request );
+ }
+
+ public ArtifactResolutionResult resolveWithExceptions( ArtifactResolutionRequest request )
+ throws ArtifactResolutionException, ArtifactNotFoundException
+ {
+ ArtifactResolutionResult result = resolve( request );
+
+ // We have collected all the problems so let's mimic the way the old code worked and just blow up right here.
+ // That's right lets just let it rip right here and send a big incomprehensible blob of text at unsuspecting
+ // users. Bad dog!
+
+ resolutionErrorHandler.throwErrors( request, result );
+
+ return result;
+ }
+
+ // ------------------------------------------------------------------------
+ //
+ // ------------------------------------------------------------------------
+
+ public ArtifactResolutionResult resolve( ArtifactResolutionRequest request )
+ {
+ Artifact rootArtifact = request.getArtifact();
+ Set<Artifact> artifacts = request.getArtifactDependencies();
+ Map<String, Artifact> managedVersions = request.getManagedVersionMap();
+ List<ResolutionListener> listeners = request.getListeners();
+ ArtifactFilter collectionFilter = request.getCollectionFilter();
+ ArtifactFilter resolutionFilter = request.getResolutionFilter();
+ RepositorySystemSession session = getSession( request.getLocalRepository() );
+
+ //TODO: hack because metadata isn't generated in m2e correctly and i want to run the maven i have in the workspace
+ if ( source == null )
+ {
+ try
+ {
+ source = container.lookup( ArtifactMetadataSource.class );
+ }
+ catch ( ComponentLookupException e )
+ {
+ // won't happen
+ }
+ }
+
+ if ( listeners == null )
+ {
+ listeners = new ArrayList<ResolutionListener>();
+
+ if ( logger.isDebugEnabled() )
+ {
+ listeners.add( new DebugResolutionListener( logger ) );
+ }
+
+ listeners.add( new WarningResolutionListener( logger ) );
+ }
+
+ ArtifactResolutionResult result = new ArtifactResolutionResult();
+
+ // The root artifact may, or may not be resolved so we need to check before we attempt to resolve.
+ // This is often an artifact like a POM that is taken from disk and we already have hold of the
+ // file reference. But this may be a Maven Plugin that we need to resolve from a remote repository
+ // as well as its dependencies.
+
+ if ( request.isResolveRoot() /* && rootArtifact.getFile() == null */ )
+ {
+ try
+ {
+ resolve( rootArtifact, request.getRemoteRepositories(), session );
+ }
+ catch ( ArtifactResolutionException e )
+ {
+ result.addErrorArtifactException( e );
+ return result;
+ }
+ catch ( ArtifactNotFoundException e )
+ {
+ result.addMissingArtifact( request.getArtifact() );
+ return result;
+ }
+ }
+
+ ArtifactResolutionRequest collectionRequest = request;
+
+ if ( request.isResolveTransitively() )
+ {
+ MetadataResolutionRequest metadataRequest = new DefaultMetadataResolutionRequest( request );
+
+ metadataRequest.setArtifact( rootArtifact );
+ metadataRequest.setResolveManagedVersions( managedVersions == null );
+
+ try
+ {
+ ResolutionGroup resolutionGroup = source.retrieve( metadataRequest );
+
+ if ( managedVersions == null )
+ {
+ managedVersions = resolutionGroup.getManagedVersions();
+ }
+
+ Set<Artifact> directArtifacts = resolutionGroup.getArtifacts();
+
+ if ( artifacts == null || artifacts.isEmpty() )
+ {
+ artifacts = directArtifacts;
+ }
+ else
+ {
+ List<Artifact> allArtifacts = new ArrayList<Artifact>();
+ allArtifacts.addAll( artifacts );
+ allArtifacts.addAll( directArtifacts );
+
+ Map<String, Artifact> mergedArtifacts = new LinkedHashMap<String, Artifact>();
+ for ( Artifact artifact : allArtifacts )
+ {
+ String conflictId = artifact.getDependencyConflictId();
+ if ( !mergedArtifacts.containsKey( conflictId ) )
+ {
+ mergedArtifacts.put( conflictId, artifact );
+ }
+ }
+
+ artifacts = new LinkedHashSet<Artifact>( mergedArtifacts.values() );
+ }
+
+ collectionRequest = new ArtifactResolutionRequest( request );
+ collectionRequest.setServers( request.getServers() );
+ collectionRequest.setMirrors( request.getMirrors() );
+ collectionRequest.setProxies( request.getProxies() );
+ collectionRequest.setRemoteRepositories( resolutionGroup.getResolutionRepositories() );
+ }
+ catch ( ArtifactMetadataRetrievalException e )
+ {
+ ArtifactResolutionException are =
+ new ArtifactResolutionException( "Unable to get dependency information for " + rootArtifact.getId()
+ + ": " + e.getMessage(), rootArtifact, metadataRequest.getRemoteRepositories(), e );
+ result.addMetadataResolutionException( are );
+ return result;
+ }
+ }
+
+ if ( artifacts == null || artifacts.isEmpty() )
+ {
+ if ( request.isResolveRoot() )
+ {
+ result.addArtifact( rootArtifact );
+ }
+ return result;
+ }
+
+ // After the collection we will have the artifact object in the result but they will not be resolved yet.
+ result =
+ artifactCollector.collect( artifacts, rootArtifact, managedVersions, collectionRequest, source,
+ collectionFilter, listeners, null );
+
+ // We have metadata retrieval problems, or there are cycles that have been detected
+ // so we give this back to the calling code and let them deal with this information
+ // appropriately.
+
+ if ( result.hasMetadataResolutionExceptions() || result.hasVersionRangeViolations() || result.hasCircularDependencyExceptions() )
+ {
+ return result;
+ }
+
+ if ( result.getArtifactResolutionNodes() != null )
+ {
+ ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
+
+ CountDownLatch latch = new CountDownLatch( result.getArtifactResolutionNodes().size() );
+
+ for ( ResolutionNode node : result.getArtifactResolutionNodes() )
+ {
+ Artifact artifact = node.getArtifact();
+
+ if ( resolutionFilter == null || resolutionFilter.include( artifact ) )
+ {
+ executor.execute( new ResolveTask( classLoader, latch, artifact, session,
+ node.getRemoteRepositories(), result ) );
+ }
+ else
+ {
+ latch.countDown();
+ }
+ }
+ try
+ {
+ latch.await();
+ }
+ catch ( InterruptedException e )
+ {
+ result.addErrorArtifactException( new ArtifactResolutionException( "Resolution interrupted",
+ rootArtifact, e ) );
+ }
+ }
+
+ // We want to send the root artifact back in the result but we need to do this after the other dependencies
+ // have been resolved.
+ if ( request.isResolveRoot() )
+ {
+ // Add the root artifact (as the first artifact to retain logical order of class path!)
+ Set<Artifact> allArtifacts = new LinkedHashSet<Artifact>();
+ allArtifacts.add( rootArtifact );
+ allArtifacts.addAll( result.getArtifacts() );
+ result.setArtifacts( allArtifacts );
+ }
+
+ return result;
+ }
+
+ public void resolve( Artifact artifact, List<ArtifactRepository> remoteRepositories, ArtifactRepository localRepository )
+ throws ArtifactResolutionException, ArtifactNotFoundException
+ {
+ resolve( artifact, remoteRepositories, localRepository, null );
+ }
+
+ /**
+ * ThreadCreator for creating daemon threads with fixed ThreadGroup-name.
+ */
+ static final class DaemonThreadCreator
+ implements ThreadFactory
+ {
+ static final String THREADGROUP_NAME = "org.apache.maven.artifact.resolver.DefaultArtifactResolver";
+
+ static final ThreadGroup GROUP = new ThreadGroup( THREADGROUP_NAME );
+
+ static final AtomicInteger THREAD_NUMBER = new AtomicInteger( 1 );
+
+ public Thread newThread( Runnable r )
+ {
+ Thread newThread = new Thread( GROUP, r, "resolver-" + THREAD_NUMBER.getAndIncrement() );
+ newThread.setDaemon( true );
+ newThread.setContextClassLoader( null );
+ return newThread;
+ }
+ }
+
+ private class ResolveTask
+ implements Runnable
+ {
+
+ private final ClassLoader classLoader;
+
+ private final CountDownLatch latch;
+
+ private final Artifact artifact;
+
+ private final RepositorySystemSession session;
+
+ private final List<ArtifactRepository> remoteRepositories;
+
+ private final ArtifactResolutionResult result;
+
+ public ResolveTask( ClassLoader classLoader, CountDownLatch latch, Artifact artifact, RepositorySystemSession session,
+ List<ArtifactRepository> remoteRepositories, ArtifactResolutionResult result )
+ {
+ this.classLoader = classLoader;
+ this.latch = latch;
+ this.artifact = artifact;
+ this.session = session;
+ this.remoteRepositories = remoteRepositories;
+ this.result = result;
+ }
+
+ public void run()
+ {
+ ClassLoader old = Thread.currentThread().getContextClassLoader();
+ try
+ {
+ Thread.currentThread().setContextClassLoader( classLoader );
+ resolve( artifact, remoteRepositories, session );
+ }
+ catch ( ArtifactNotFoundException anfe )
+ {
+ // These are cases where the artifact just isn't present in any of the remote repositories
+ // because it wasn't deployed, or it was deployed in the wrong place.
+
+ synchronized ( result )
+ {
+ result.addMissingArtifact( artifact );
+ }
+ }
+ catch ( ArtifactResolutionException e )
+ {
+ // This is really a wagon TransferFailedException so something went wrong after we successfully
+ // retrieved the metadata.
+
+ synchronized ( result )
+ {
+ result.addErrorArtifactException( e );
+ }
+ }
+ finally
+ {
+ latch.countDown();
+ Thread.currentThread().setContextClassLoader( old );
+
+ }
+ }
+
+ }
+
+ @Override
+ public void dispose()
+ {
+ if ( executor instanceof ExecutorService )
+ {
+ ( (ExecutorService) executor ).shutdownNow();
+ }
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/resolver/ResolutionListenerForDepMgmt.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/resolver/ResolutionListenerForDepMgmt.java
new file mode 100644
index 00000000..06da7e3e
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/resolver/ResolutionListenerForDepMgmt.java
@@ -0,0 +1,43 @@
+package org.apache.maven.artifact.resolver;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.artifact.Artifact;
+
+/**
+ * Do not use!
+ * <p/>
+ * Should only be implmemented by DebugResolutionListener. Remove this
+ * when the ResolutionListener interface deprecation of the manageArtifact
+ * method (and the [yet to be done] addition of these methods to that
+ * interface) has had a chance to propagate to all interested plugins.
+ */
+@Deprecated
+public interface ResolutionListenerForDepMgmt
+{
+ void manageArtifactVersion( Artifact artifact,
+ Artifact replacement );
+
+ void manageArtifactScope( Artifact artifact,
+ Artifact replacement );
+
+ void manageArtifactSystemPath( Artifact artifact,
+ Artifact replacement );
+} \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/resolver/UnresolvedArtifacts.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/resolver/UnresolvedArtifacts.java
new file mode 100644
index 00000000..b9ccf706
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/resolver/UnresolvedArtifacts.java
@@ -0,0 +1,66 @@
+package org.apache.maven.artifact.resolver;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.List;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+
+/**
+ * A simple recording of the Artifacts that could not be resolved for a given resolution request, along with
+ * the remote repositories where attempts were made to resolve the artifacts.
+ *
+ * @author Jason van Zyl
+ */
+public class UnresolvedArtifacts
+{
+ private Artifact originatingArtifact;
+
+ private List<Artifact> artifacts;
+
+ private List<ArtifactRepository> remoteRepositories;
+
+ public UnresolvedArtifacts( Artifact originatingArtifact,
+ List<Artifact> artifacts,
+ List<ArtifactRepository> remoteRepositories )
+ {
+ this.originatingArtifact = originatingArtifact;
+
+ this.artifacts = artifacts;
+
+ this.remoteRepositories = remoteRepositories;
+ }
+
+ public Artifact getOriginatingArtifact()
+ {
+ return originatingArtifact;
+ }
+
+ public List<Artifact> getArtifacts()
+ {
+ return artifacts;
+ }
+
+ public List<ArtifactRepository> getRemoteRepositories()
+ {
+ return remoteRepositories;
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/resolver/WarningResolutionListener.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/resolver/WarningResolutionListener.java
new file mode 100644
index 00000000..825d595a
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/resolver/WarningResolutionListener.java
@@ -0,0 +1,90 @@
+package org.apache.maven.artifact.resolver;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.versioning.VersionRange;
+import org.codehaus.plexus.logging.Logger;
+
+/**
+ * Send resolution warning events to the warning log.
+ *
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ */
+public class WarningResolutionListener
+ implements ResolutionListener
+{
+ private Logger logger;
+
+ public WarningResolutionListener( Logger logger )
+ {
+ this.logger = logger;
+ }
+
+ public void testArtifact( Artifact node )
+ {
+ }
+
+ public void startProcessChildren( Artifact artifact )
+ {
+ }
+
+ public void endProcessChildren( Artifact artifact )
+ {
+ }
+
+ public void includeArtifact( Artifact artifact )
+ {
+ }
+
+ public void omitForNearer( Artifact omitted,
+ Artifact kept )
+ {
+ }
+
+ public void omitForCycle( Artifact omitted )
+ {
+ }
+
+ public void updateScopeCurrentPom( Artifact artifact,
+ String scope )
+ {
+ }
+
+ public void updateScope( Artifact artifact,
+ String scope )
+ {
+ }
+
+ public void manageArtifact( Artifact artifact,
+ Artifact replacement )
+ {
+ }
+
+ public void selectVersionFromRange( Artifact artifact )
+ {
+ }
+
+ public void restrictRange( Artifact artifact,
+ Artifact replacement,
+ VersionRange newRange )
+ {
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/resolver/filter/InversionArtifactFilter.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/resolver/filter/InversionArtifactFilter.java
new file mode 100644
index 00000000..0499db51
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/resolver/filter/InversionArtifactFilter.java
@@ -0,0 +1,65 @@
+package org.apache.maven.artifact.resolver.filter;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.artifact.Artifact;
+
+public class InversionArtifactFilter
+ implements ArtifactFilter
+{
+ private final ArtifactFilter toInvert;
+
+ public InversionArtifactFilter( ArtifactFilter toInvert )
+ {
+ this.toInvert = toInvert;
+ }
+
+ public boolean include( Artifact artifact )
+ {
+ return !toInvert.include( artifact );
+ }
+
+ @Override
+ public int hashCode()
+ {
+ int hash = 17;
+ hash = hash * 31 + toInvert.hashCode();
+ return hash;
+ }
+
+ @Override
+ public boolean equals( Object obj )
+ {
+ if ( this == obj )
+ {
+ return true;
+ }
+
+ if ( !( obj instanceof InversionArtifactFilter ) )
+ {
+ return false;
+ }
+
+ InversionArtifactFilter other = (InversionArtifactFilter) obj;
+
+ return toInvert.equals( other.toInvert );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/resolver/filter/OrArtifactFilter.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/resolver/filter/OrArtifactFilter.java
new file mode 100644
index 00000000..8cd02ccf
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/resolver/filter/OrArtifactFilter.java
@@ -0,0 +1,93 @@
+package org.apache.maven.artifact.resolver.filter;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Collection;
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+import org.apache.maven.artifact.Artifact;
+
+/**
+ * Apply multiple filters, accepting an artifact if at least one of the filters accepts it.
+ *
+ * @author Benjamin Bentmann
+ */
+public class OrArtifactFilter
+ implements ArtifactFilter
+{
+
+ private Set<ArtifactFilter> filters;
+
+ public OrArtifactFilter()
+ {
+ this.filters = new LinkedHashSet<ArtifactFilter>();
+ }
+
+ public OrArtifactFilter( Collection<ArtifactFilter> filters )
+ {
+ this.filters = new LinkedHashSet<ArtifactFilter>( filters );
+ }
+
+ public boolean include( Artifact artifact )
+ {
+ for ( ArtifactFilter filter : filters )
+ {
+ if ( filter.include( artifact ) )
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ public void add( ArtifactFilter artifactFilter )
+ {
+ filters.add( artifactFilter );
+ }
+
+ @Override
+ public int hashCode()
+ {
+ int hash = 17;
+ hash = hash * 31 + filters.hashCode();
+ return hash;
+ }
+
+ @Override
+ public boolean equals( Object obj )
+ {
+ if ( this == obj )
+ {
+ return true;
+ }
+
+ if ( !( obj instanceof OrArtifactFilter ) )
+ {
+ return false;
+ }
+
+ OrArtifactFilter other = (OrArtifactFilter) obj;
+
+ return filters.equals( other.filters );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/resolver/filter/TypeArtifactFilter.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/resolver/filter/TypeArtifactFilter.java
new file mode 100644
index 00000000..76c39ec3
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/resolver/filter/TypeArtifactFilter.java
@@ -0,0 +1,66 @@
+package org.apache.maven.artifact.resolver.filter;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.artifact.Artifact;
+
+/** Artifact Filter which filters on artifact type */
+public class TypeArtifactFilter
+ implements ArtifactFilter
+{
+ private String type = "jar";
+
+ public TypeArtifactFilter( String type )
+ {
+ this.type = type;
+ }
+
+ public boolean include( Artifact artifact )
+ {
+ return type.equals( artifact.getType() );
+ }
+
+ @Override
+ public int hashCode()
+ {
+ int hash = 17;
+ hash = hash * 31 + type.hashCode();
+ return hash;
+ }
+
+ @Override
+ public boolean equals( Object obj )
+ {
+ if ( this == obj )
+ {
+ return true;
+ }
+
+ if ( !( obj instanceof TypeArtifactFilter ) )
+ {
+ return false;
+ }
+
+ TypeArtifactFilter other = (TypeArtifactFilter) obj;
+
+ return type.equals( other.type );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/versioning/ManagedVersionMap.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/versioning/ManagedVersionMap.java
new file mode 100644
index 00000000..86b49499
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/artifact/versioning/ManagedVersionMap.java
@@ -0,0 +1,56 @@
+package org.apache.maven.artifact.versioning;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.apache.maven.artifact.Artifact;
+
+@Deprecated
+public class ManagedVersionMap
+ extends HashMap<String, Artifact>
+{
+ public ManagedVersionMap( Map<String, Artifact> map )
+ {
+ super();
+ if ( map != null )
+ {
+ putAll( map );
+ }
+ }
+
+ public String toString()
+ {
+ StringBuilder buffer = new StringBuilder( "ManagedVersionMap (" + size() + " entries)\n" );
+ Iterator<String> iter = keySet().iterator();
+ while ( iter.hasNext() )
+ {
+ String key = iter.next();
+ buffer.append( key ).append( "=" ).append( get( key ) );
+ if ( iter.hasNext() )
+ {
+ buffer.append( "\n" );
+ }
+ }
+ return buffer.toString();
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/execution/DefaultRuntimeInformation.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/execution/DefaultRuntimeInformation.java
new file mode 100644
index 00000000..7767aff1
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/execution/DefaultRuntimeInformation.java
@@ -0,0 +1,64 @@
+package org.apache.maven.execution;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.artifact.versioning.ArtifactVersion;
+import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable;
+import org.codehaus.plexus.personality.plexus.lifecycle.phase.InitializationException;
+import org.codehaus.plexus.util.StringUtils;
+
+/**
+ * Describes runtime information about the application.
+ *
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ */
+@Deprecated
+@Component( role = RuntimeInformation.class )
+public class DefaultRuntimeInformation
+ implements RuntimeInformation, Initializable
+{
+
+ @Requirement
+ private org.apache.maven.rtinfo.RuntimeInformation rtInfo;
+
+ private ArtifactVersion applicationVersion;
+
+ public ArtifactVersion getApplicationVersion()
+ {
+ return applicationVersion;
+ }
+
+ public void initialize()
+ throws InitializationException
+ {
+ String mavenVersion = rtInfo.getMavenVersion();
+
+ if ( StringUtils.isEmpty( mavenVersion ) )
+ {
+ throw new InitializationException( "Unable to read Maven version from maven-core" );
+ }
+
+ applicationVersion = new DefaultArtifactVersion( mavenVersion );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/execution/RuntimeInformation.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/execution/RuntimeInformation.java
new file mode 100644
index 00000000..22e522d2
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/execution/RuntimeInformation.java
@@ -0,0 +1,34 @@
+package org.apache.maven.execution;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.artifact.versioning.ArtifactVersion;
+
+/**
+ * Describes runtime information about the application.
+ *
+ * @deprecated Use {@link org.apache.maven.rtinfo.RuntimeInformation} instead.
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ */
+@Deprecated
+public interface RuntimeInformation
+{
+ ArtifactVersion getApplicationVersion();
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/profiles/DefaultMavenProfilesBuilder.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/profiles/DefaultMavenProfilesBuilder.java
new file mode 100644
index 00000000..4745749b
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/profiles/DefaultMavenProfilesBuilder.java
@@ -0,0 +1,93 @@
+package org.apache.maven.profiles;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.profiles.io.xpp3.ProfilesXpp3Reader;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.interpolation.EnvarBasedValueSource;
+import org.codehaus.plexus.interpolation.RegexBasedInterpolator;
+import org.codehaus.plexus.logging.AbstractLogEnabled;
+import org.codehaus.plexus.util.IOUtil;
+import org.codehaus.plexus.util.ReaderFactory;
+import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.Reader;
+import java.io.StringReader;
+import java.io.StringWriter;
+
+@Deprecated
+@Component( role = MavenProfilesBuilder.class )
+public class DefaultMavenProfilesBuilder
+ extends AbstractLogEnabled
+ implements MavenProfilesBuilder
+{
+ private static final String PROFILES_XML_FILE = "profiles.xml";
+
+ public ProfilesRoot buildProfiles( File basedir )
+ throws IOException, XmlPullParserException
+ {
+ File profilesXml = new File( basedir, PROFILES_XML_FILE );
+
+ ProfilesRoot profilesRoot = null;
+
+ if ( profilesXml.exists() )
+ {
+ ProfilesXpp3Reader reader = new ProfilesXpp3Reader();
+ Reader profileReader = null;
+ try
+ {
+ profileReader = ReaderFactory.newXmlReader( profilesXml );
+
+ StringWriter sWriter = new StringWriter();
+
+ IOUtil.copy( profileReader, sWriter );
+
+ String rawInput = sWriter.toString();
+
+ try
+ {
+ RegexBasedInterpolator interpolator = new RegexBasedInterpolator();
+ interpolator.addValueSource( new EnvarBasedValueSource() );
+
+ rawInput = interpolator.interpolate( rawInput, "settings" );
+ }
+ catch ( Exception e )
+ {
+ getLogger().warn( "Failed to initialize environment variable resolver. Skipping environment "
+ + "substitution in " + PROFILES_XML_FILE + "." );
+ getLogger().debug( "Failed to initialize envar resolver. Skipping resolution.", e );
+ }
+
+ StringReader sReader = new StringReader( rawInput );
+
+ profilesRoot = reader.read( sReader );
+ }
+ finally
+ {
+ IOUtil.close( profileReader );
+ }
+ }
+
+ return profilesRoot;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/profiles/DefaultProfileManager.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/profiles/DefaultProfileManager.java
new file mode 100644
index 00000000..3b99e9e2
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/profiles/DefaultProfileManager.java
@@ -0,0 +1,248 @@
+package org.apache.maven.profiles;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.model.Activation;
+import org.apache.maven.model.Profile;
+import org.apache.maven.model.building.ModelProblem;
+import org.apache.maven.model.building.ModelProblemCollector;
+import org.apache.maven.model.profile.DefaultProfileActivationContext;
+import org.apache.maven.model.profile.ProfileSelector;
+import org.apache.maven.profiles.activation.ProfileActivationException;
+import org.codehaus.plexus.MutablePlexusContainer;
+import org.codehaus.plexus.PlexusContainer;
+import org.codehaus.plexus.component.annotations.Requirement;
+import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
+import org.codehaus.plexus.logging.Logger;
+
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import org.apache.maven.model.building.ModelProblemCollectorRequest;
+
+@Deprecated
+public class DefaultProfileManager
+ implements ProfileManager
+{
+
+ @Requirement
+ private Logger logger;
+
+ @Requirement
+ private ProfileSelector profileSelector;
+
+ private List activatedIds = new ArrayList();
+
+ private List deactivatedIds = new ArrayList();
+
+ private List defaultIds = new ArrayList();
+
+ private Map profilesById = new LinkedHashMap();
+
+ private Properties requestProperties;
+
+ /**
+ * @deprecated without passing in the system properties, the SystemPropertiesProfileActivator will not work
+ * correctly in embedded envirnments.
+ */
+ public DefaultProfileManager( PlexusContainer container )
+ {
+ this( container, null );
+ }
+
+ /**
+ * the properties passed to the profile manager are the props that
+ * are passed to maven, possibly containing profile activator properties
+ *
+ */
+ public DefaultProfileManager( PlexusContainer container, Properties props )
+ {
+ try
+ {
+ this.profileSelector = container.lookup( ProfileSelector.class );
+ this.logger = ( (MutablePlexusContainer) container ).getLogger();
+ }
+ catch ( ComponentLookupException e )
+ {
+ throw new IllegalStateException( e );
+ }
+ this.requestProperties = props;
+ }
+
+ public Properties getRequestProperties()
+ {
+ return requestProperties;
+ }
+
+ public Map getProfilesById()
+ {
+ return profilesById;
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.maven.profiles.ProfileManager#addProfile(org.apache.maven.model.Profile)
+ */
+ public void addProfile( Profile profile )
+ {
+ String profileId = profile.getId();
+
+ Profile existing = (Profile) profilesById.get( profileId );
+ if ( existing != null )
+ {
+ logger.warn( "Overriding profile: \'" + profileId + "\' (source: " + existing.getSource()
+ + ") with new instance from source: " + profile.getSource() );
+ }
+
+ profilesById.put( profile.getId(), profile );
+
+ Activation activation = profile.getActivation();
+
+ if ( activation != null && activation.isActiveByDefault() )
+ {
+ activateAsDefault( profileId );
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.maven.profiles.ProfileManager#explicitlyActivate(java.lang.String)
+ */
+ public void explicitlyActivate( String profileId )
+ {
+ if ( !activatedIds.contains( profileId ) )
+ {
+ logger.debug( "Profile with id: \'" + profileId + "\' has been explicitly activated." );
+
+ activatedIds.add( profileId );
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.maven.profiles.ProfileManager#explicitlyActivate(java.util.List)
+ */
+ public void explicitlyActivate( List profileIds )
+ {
+ for ( Object profileId1 : profileIds )
+ {
+ String profileId = (String) profileId1;
+
+ explicitlyActivate( profileId );
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.maven.profiles.ProfileManager#explicitlyDeactivate(java.lang.String)
+ */
+ public void explicitlyDeactivate( String profileId )
+ {
+ if ( !deactivatedIds.contains( profileId ) )
+ {
+ logger.debug( "Profile with id: \'" + profileId + "\' has been explicitly deactivated." );
+
+ deactivatedIds.add( profileId );
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.maven.profiles.ProfileManager#explicitlyDeactivate(java.util.List)
+ */
+ public void explicitlyDeactivate( List profileIds )
+ {
+ for ( Object profileId1 : profileIds )
+ {
+ String profileId = (String) profileId1;
+
+ explicitlyDeactivate( profileId );
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.maven.profiles.ProfileManager#getActiveProfiles()
+ */
+ public List getActiveProfiles()
+ throws ProfileActivationException
+ {
+ DefaultProfileActivationContext context = new DefaultProfileActivationContext();
+ context.setActiveProfileIds( activatedIds );
+ context.setInactiveProfileIds( deactivatedIds );
+ context.setSystemProperties( System.getProperties() );
+ context.setUserProperties( requestProperties );
+
+ final List<ProfileActivationException> errors = new ArrayList<ProfileActivationException>();
+
+ List<Profile> profiles =
+ profileSelector.getActiveProfiles( profilesById.values(), context, new ModelProblemCollector()
+ {
+
+ public void add( ModelProblemCollectorRequest req )
+ {
+ if ( !ModelProblem.Severity.WARNING.equals( req.getSeverity() ) )
+ {
+ errors.add( new ProfileActivationException( req.getMessage(), req.getException() ) );
+ }
+ }
+ } );
+
+ if ( !errors.isEmpty() )
+ {
+ throw errors.get( 0 );
+ }
+
+ return profiles;
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.maven.profiles.ProfileManager#addProfiles(java.util.List)
+ */
+ public void addProfiles( List profiles )
+ {
+ for ( Object profile1 : profiles )
+ {
+ Profile profile = (Profile) profile1;
+
+ addProfile( profile );
+ }
+ }
+
+ public void activateAsDefault( String profileId )
+ {
+ if ( !defaultIds.contains( profileId ) )
+ {
+ defaultIds.add( profileId );
+ }
+ }
+
+ public List getExplicitlyActivatedIds()
+ {
+ return activatedIds;
+ }
+
+ public List getExplicitlyDeactivatedIds()
+ {
+ return deactivatedIds;
+ }
+
+ public List getIdsActivatedByDefault()
+ {
+ return defaultIds;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/profiles/MavenProfilesBuilder.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/profiles/MavenProfilesBuilder.java
new file mode 100644
index 00000000..32fb6aaa
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/profiles/MavenProfilesBuilder.java
@@ -0,0 +1,37 @@
+package org.apache.maven.profiles;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
+
+import java.io.File;
+import java.io.IOException;
+
+/**
+ * @author jdcasey
+ */
+@Deprecated
+public interface MavenProfilesBuilder
+{
+ String ROLE = MavenProfilesBuilder.class.getName();
+
+ ProfilesRoot buildProfiles( File basedir )
+ throws IOException, XmlPullParserException;
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/profiles/ProfileManager.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/profiles/ProfileManager.java
new file mode 100644
index 00000000..ddda3d7f
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/profiles/ProfileManager.java
@@ -0,0 +1,58 @@
+package org.apache.maven.profiles;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.model.Profile;
+import org.apache.maven.profiles.activation.ProfileActivationException;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+@Deprecated
+public interface ProfileManager
+{
+
+ void addProfile( Profile profile );
+
+ void explicitlyActivate( String profileId );
+
+ void explicitlyActivate( List profileIds );
+
+ void explicitlyDeactivate( String profileId );
+
+ void explicitlyDeactivate( List profileIds );
+
+ List getActiveProfiles()
+ throws ProfileActivationException;
+
+ void addProfiles( List profiles );
+
+ Map getProfilesById();
+
+ List getExplicitlyActivatedIds();
+
+ List getExplicitlyDeactivatedIds();
+
+ List getIdsActivatedByDefault();
+
+ Properties getRequestProperties();
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/profiles/ProfilesConversionUtils.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/profiles/ProfilesConversionUtils.java
new file mode 100644
index 00000000..72527b09
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/profiles/ProfilesConversionUtils.java
@@ -0,0 +1,151 @@
+package org.apache.maven.profiles;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.model.Activation;
+import org.apache.maven.model.ActivationFile;
+import org.apache.maven.model.ActivationProperty;
+import org.apache.maven.model.Profile;
+import org.apache.maven.model.Repository;
+
+import java.util.List;
+
+@Deprecated
+public class ProfilesConversionUtils
+{
+ private ProfilesConversionUtils()
+ {
+ }
+
+ public static Profile convertFromProfileXmlProfile( org.apache.maven.profiles.Profile profileXmlProfile )
+ {
+ Profile profile = new Profile();
+
+ profile.setId( profileXmlProfile.getId() );
+
+ profile.setSource( "profiles.xml" );
+
+ org.apache.maven.profiles.Activation profileActivation = profileXmlProfile.getActivation();
+
+ if ( profileActivation != null )
+ {
+ Activation activation = new Activation();
+
+ activation.setActiveByDefault( profileActivation.isActiveByDefault() );
+
+ activation.setJdk( profileActivation.getJdk() );
+
+ org.apache.maven.profiles.ActivationProperty profileProp = profileActivation.getProperty();
+
+ if ( profileProp != null )
+ {
+ ActivationProperty prop = new ActivationProperty();
+
+ prop.setName( profileProp.getName() );
+ prop.setValue( profileProp.getValue() );
+
+ activation.setProperty( prop );
+ }
+
+
+ ActivationOS profileOs = profileActivation.getOs();
+
+ if ( profileOs != null )
+ {
+ org.apache.maven.model.ActivationOS os = new org.apache.maven.model.ActivationOS();
+
+ os.setArch( profileOs.getArch() );
+ os.setFamily( profileOs.getFamily() );
+ os.setName( profileOs.getName() );
+ os.setVersion( profileOs.getVersion() );
+
+ activation.setOs( os );
+ }
+
+ org.apache.maven.profiles.ActivationFile profileFile = profileActivation.getFile();
+
+ if ( profileFile != null )
+ {
+ ActivationFile file = new ActivationFile();
+
+ file.setExists( profileFile.getExists() );
+ file.setMissing( profileFile.getMissing() );
+
+ activation.setFile( file );
+ }
+
+ profile.setActivation( activation );
+ }
+
+ profile.setProperties( profileXmlProfile.getProperties() );
+
+ List repos = profileXmlProfile.getRepositories();
+ if ( repos != null )
+ {
+ for ( Object repo : repos )
+ {
+ profile.addRepository( convertFromProfileXmlRepository( (org.apache.maven.profiles.Repository) repo ) );
+ }
+ }
+
+ List pluginRepos = profileXmlProfile.getPluginRepositories();
+ if ( pluginRepos != null )
+ {
+ for ( Object pluginRepo : pluginRepos )
+ {
+ profile.addPluginRepository(
+ convertFromProfileXmlRepository( (org.apache.maven.profiles.Repository) pluginRepo ) );
+ }
+ }
+
+ return profile;
+ }
+
+ private static Repository convertFromProfileXmlRepository( org.apache.maven.profiles.Repository profileXmlRepo )
+ {
+ Repository repo = new Repository();
+
+ repo.setId( profileXmlRepo.getId() );
+ repo.setLayout( profileXmlRepo.getLayout() );
+ repo.setName( profileXmlRepo.getName() );
+ repo.setUrl( profileXmlRepo.getUrl() );
+
+ if ( profileXmlRepo.getSnapshots() != null )
+ {
+ repo.setSnapshots( convertRepositoryPolicy( profileXmlRepo.getSnapshots() ) );
+ }
+ if ( profileXmlRepo.getReleases() != null )
+ {
+ repo.setReleases( convertRepositoryPolicy( profileXmlRepo.getReleases() ) );
+ }
+
+ return repo;
+ }
+
+ private static org.apache.maven.model.RepositoryPolicy convertRepositoryPolicy( RepositoryPolicy profileXmlRepo )
+ {
+ org.apache.maven.model.RepositoryPolicy policy = new org.apache.maven.model.RepositoryPolicy();
+ policy.setEnabled( profileXmlRepo.isEnabled() );
+ policy.setUpdatePolicy( profileXmlRepo.getUpdatePolicy() );
+ policy.setChecksumPolicy( profileXmlRepo.getChecksumPolicy() );
+ return policy;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/profiles/activation/DetectedProfileActivator.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/profiles/activation/DetectedProfileActivator.java
new file mode 100644
index 00000000..5d6a8bf6
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/profiles/activation/DetectedProfileActivator.java
@@ -0,0 +1,35 @@
+package org.apache.maven.profiles.activation;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.model.Profile;
+
+@Deprecated
+public abstract class DetectedProfileActivator
+ implements ProfileActivator
+{
+ public boolean canDetermineActivation( Profile profile )
+ {
+ return canDetectActivation( profile );
+ }
+
+ protected abstract boolean canDetectActivation( Profile profile );
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/profiles/activation/FileProfileActivator.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/profiles/activation/FileProfileActivator.java
new file mode 100644
index 00000000..de4ba2ed
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/profiles/activation/FileProfileActivator.java
@@ -0,0 +1,109 @@
+package org.apache.maven.profiles.activation;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.IOException;
+
+import org.apache.maven.model.Activation;
+import org.apache.maven.model.ActivationFile;
+import org.apache.maven.model.Profile;
+import org.codehaus.plexus.interpolation.EnvarBasedValueSource;
+import org.codehaus.plexus.interpolation.InterpolationException;
+import org.codehaus.plexus.interpolation.MapBasedValueSource;
+import org.codehaus.plexus.interpolation.RegexBasedInterpolator;
+import org.codehaus.plexus.logging.LogEnabled;
+import org.codehaus.plexus.logging.Logger;
+import org.codehaus.plexus.util.FileUtils;
+import org.codehaus.plexus.util.StringUtils;
+
+@Deprecated
+public class FileProfileActivator
+ extends DetectedProfileActivator
+ implements LogEnabled
+{
+ private Logger logger;
+
+ protected boolean canDetectActivation( Profile profile )
+ {
+ return profile.getActivation() != null && profile.getActivation().getFile() != null;
+ }
+
+ public boolean isActive( Profile profile )
+ {
+ Activation activation = profile.getActivation();
+
+ ActivationFile actFile = activation.getFile();
+
+ if ( actFile != null )
+ {
+ // check if the file exists, if it does then the profile will be active
+ String fileString = actFile.getExists();
+
+ RegexBasedInterpolator interpolator = new RegexBasedInterpolator();
+ try
+ {
+ interpolator.addValueSource( new EnvarBasedValueSource() );
+ }
+ catch ( IOException e )
+ {
+ // ignored
+ }
+ interpolator.addValueSource( new MapBasedValueSource( System.getProperties() ) );
+
+ try
+ {
+ if ( StringUtils.isNotEmpty( fileString ) )
+ {
+ fileString = StringUtils.replace( interpolator.interpolate( fileString, "" ), "\\", "/" );
+ return FileUtils.fileExists( fileString );
+ }
+
+ // check if the file is missing, if it is then the profile will be active
+ fileString = actFile.getMissing();
+
+ if ( StringUtils.isNotEmpty( fileString ) )
+ {
+ fileString = StringUtils.replace( interpolator.interpolate( fileString, "" ), "\\", "/" );
+ return !FileUtils.fileExists( fileString );
+ }
+ }
+ catch ( InterpolationException e )
+ {
+ if ( logger.isDebugEnabled() )
+ {
+ logger.debug( "Failed to interpolate missing file location for profile activator: " + fileString,
+ e );
+ }
+ else
+ {
+ logger.warn( "Failed to interpolate missing file location for profile activator: " + fileString
+ + ". Run in debug mode (-X) for more information." );
+ }
+ }
+ }
+
+ return false;
+ }
+
+ public void enableLogging( Logger logger )
+ {
+ this.logger = logger;
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/profiles/activation/JdkPrefixProfileActivator.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/profiles/activation/JdkPrefixProfileActivator.java
new file mode 100644
index 00000000..dfae95f6
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/profiles/activation/JdkPrefixProfileActivator.java
@@ -0,0 +1,97 @@
+package org.apache.maven.profiles.activation;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
+import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
+import org.apache.maven.artifact.versioning.VersionRange;
+import org.apache.maven.model.Activation;
+import org.apache.maven.model.Profile;
+import org.codehaus.plexus.util.StringUtils;
+
+@Deprecated
+public class JdkPrefixProfileActivator
+ extends DetectedProfileActivator
+{
+ private static final String JDK_VERSION = System.getProperty( "java.version" );
+
+ public boolean isActive( Profile profile )
+ throws ProfileActivationException
+ {
+ Activation activation = profile.getActivation();
+
+ String jdk = activation.getJdk();
+
+ // null case is covered by canDetermineActivation(), so we can do a straight startsWith() here.
+ if ( jdk.startsWith( "[" ) || jdk.startsWith( "(" ) )
+ {
+ try
+ {
+ return matchJdkVersionRange( jdk );
+ }
+ catch ( InvalidVersionSpecificationException e )
+ {
+ throw new ProfileActivationException( "Invalid JDK version in profile '" + profile.getId() + "': "
+ + e.getMessage() );
+ }
+ }
+
+ boolean reverse = false;
+
+ if ( jdk.startsWith( "!" ) )
+ {
+ reverse = true;
+ jdk = jdk.substring( 1 );
+ }
+
+ if ( getJdkVersion().startsWith( jdk ) )
+ {
+ return !reverse;
+ }
+ else
+ {
+ return reverse;
+ }
+ }
+
+ private boolean matchJdkVersionRange( String jdk )
+ throws InvalidVersionSpecificationException
+ {
+ VersionRange jdkVersionRange = VersionRange.createFromVersionSpec( convertJdkToMavenVersion( jdk ) );
+ DefaultArtifactVersion jdkVersion = new DefaultArtifactVersion( convertJdkToMavenVersion( getJdkVersion() ) );
+ return jdkVersionRange.containsVersion( jdkVersion );
+ }
+
+ private String convertJdkToMavenVersion( String jdk )
+ {
+ return jdk.replaceAll( "_", "-" );
+ }
+
+ protected String getJdkVersion()
+ {
+ return JDK_VERSION;
+ }
+
+ protected boolean canDetectActivation( Profile profile )
+ {
+ return profile.getActivation() != null && StringUtils.isNotEmpty( profile.getActivation().getJdk() );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/profiles/activation/OperatingSystemProfileActivator.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/profiles/activation/OperatingSystemProfileActivator.java
new file mode 100644
index 00000000..7464a303
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/profiles/activation/OperatingSystemProfileActivator.java
@@ -0,0 +1,161 @@
+package org.apache.maven.profiles.activation;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.model.Activation;
+import org.apache.maven.model.ActivationOS;
+import org.apache.maven.model.Profile;
+import org.codehaus.plexus.util.Os;
+
+@Deprecated
+public class OperatingSystemProfileActivator
+ implements ProfileActivator
+{
+
+ public boolean canDetermineActivation( Profile profile )
+ {
+ Activation activation = profile.getActivation();
+ return activation != null && activation.getOs() != null;
+ }
+
+ public boolean isActive( Profile profile )
+ {
+ Activation activation = profile.getActivation();
+ ActivationOS os = activation.getOs();
+
+ boolean result = ensureAtLeastOneNonNull( os );
+
+ if ( result && os.getFamily() != null )
+ {
+ result = determineFamilyMatch( os.getFamily() );
+ }
+ if ( result && os.getName() != null )
+ {
+ result = determineNameMatch( os.getName() );
+ }
+ if ( result && os.getArch() != null )
+ {
+ result = determineArchMatch( os.getArch() );
+ }
+ if ( result && os.getVersion() != null )
+ {
+ result = determineVersionMatch( os.getVersion() );
+ }
+ return result;
+ }
+
+ private boolean ensureAtLeastOneNonNull( ActivationOS os )
+ {
+ return os.getArch() != null || os.getFamily() != null || os.getName() != null || os.getVersion() != null;
+ }
+
+ private boolean determineVersionMatch( String version )
+ {
+ String test = version;
+ boolean reverse = false;
+
+ if ( test.startsWith( "!" ) )
+ {
+ reverse = true;
+ test = test.substring( 1 );
+ }
+
+ boolean result = Os.isVersion( test );
+
+ if ( reverse )
+ {
+ return !result;
+ }
+ else
+ {
+ return result;
+ }
+ }
+
+ private boolean determineArchMatch( String arch )
+ {
+ String test = arch;
+ boolean reverse = false;
+
+ if ( test.startsWith( "!" ) )
+ {
+ reverse = true;
+ test = test.substring( 1 );
+ }
+
+ boolean result = Os.isArch( test );
+
+ if ( reverse )
+ {
+ return !result;
+ }
+ else
+ {
+ return result;
+ }
+ }
+
+ private boolean determineNameMatch( String name )
+ {
+ String test = name;
+ boolean reverse = false;
+
+ if ( test.startsWith( "!" ) )
+ {
+ reverse = true;
+ test = test.substring( 1 );
+ }
+
+ boolean result = Os.isName( test );
+
+ if ( reverse )
+ {
+ return !result;
+ }
+ else
+ {
+ return result;
+ }
+ }
+
+ private boolean determineFamilyMatch( String family )
+ {
+ String test = family;
+ boolean reverse = false;
+
+ if ( test.startsWith( "!" ) )
+ {
+ reverse = true;
+ test = test.substring( 1 );
+ }
+
+ boolean result = Os.isFamily( test );
+
+ if ( reverse )
+ {
+ return !result;
+ }
+ else
+ {
+ return result;
+ }
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/profiles/activation/ProfileActivationException.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/profiles/activation/ProfileActivationException.java
new file mode 100644
index 00000000..7fc372cb
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/profiles/activation/ProfileActivationException.java
@@ -0,0 +1,39 @@
+package org.apache.maven.profiles.activation;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+@Deprecated
+public class ProfileActivationException
+ extends Exception
+{
+
+ private static final long serialVersionUID = -90820222109103638L;
+
+ public ProfileActivationException( String message, Throwable cause )
+ {
+ super( message, cause );
+ }
+
+ public ProfileActivationException( String message )
+ {
+ super( message );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/profiles/activation/ProfileActivator.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/profiles/activation/ProfileActivator.java
new file mode 100644
index 00000000..d0a9ecb5
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/profiles/activation/ProfileActivator.java
@@ -0,0 +1,33 @@
+package org.apache.maven.profiles.activation;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.model.Profile;
+
+@Deprecated
+public interface ProfileActivator
+{
+ final String ROLE = ProfileActivator.class.getName();
+
+ boolean canDetermineActivation( Profile profile );
+
+ boolean isActive( Profile profile )
+ throws ProfileActivationException;
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/profiles/activation/SystemPropertyProfileActivator.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/profiles/activation/SystemPropertyProfileActivator.java
new file mode 100644
index 00000000..a03267dc
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/profiles/activation/SystemPropertyProfileActivator.java
@@ -0,0 +1,114 @@
+package org.apache.maven.profiles.activation;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Properties;
+import org.apache.maven.model.Activation;
+import org.apache.maven.model.ActivationProperty;
+import org.apache.maven.model.Profile;
+import org.codehaus.plexus.context.Context;
+import org.codehaus.plexus.context.ContextException;
+import org.codehaus.plexus.personality.plexus.lifecycle.phase.Contextualizable;
+import org.codehaus.plexus.util.StringUtils;
+
+@Deprecated
+public class SystemPropertyProfileActivator
+ extends DetectedProfileActivator implements Contextualizable
+{
+ private Properties properties;
+
+ public void contextualize( Context context )
+ throws ContextException
+ {
+ properties = (Properties) context.get( "SystemProperties" );
+ }
+
+ protected boolean canDetectActivation( Profile profile )
+ {
+ return profile.getActivation() != null && profile.getActivation().getProperty() != null;
+ }
+
+ public boolean isActive( Profile profile )
+ throws ProfileActivationException
+ {
+ Activation activation = profile.getActivation();
+
+ ActivationProperty property = activation.getProperty();
+
+ if ( property != null )
+ {
+ String name = property.getName();
+ boolean reverseName = false;
+
+ if ( name == null )
+ {
+ throw new ProfileActivationException( "The property name is required to activate the profile '"
+ + profile.getId() + "'" );
+ }
+
+ if ( name.startsWith( "!" ) )
+ {
+ reverseName = true;
+ name = name.substring( 1 );
+ }
+
+ String sysValue = properties.getProperty( name );
+
+ String propValue = property.getValue();
+ if ( StringUtils.isNotEmpty( propValue ) )
+ {
+ boolean reverseValue = false;
+ if ( propValue.startsWith( "!" ) )
+ {
+ reverseValue = true;
+ propValue = propValue.substring( 1 );
+ }
+
+ // we have a value, so it has to match the system value...
+ boolean result = propValue.equals( sysValue );
+
+ if ( reverseValue )
+ {
+ return !result;
+ }
+ else
+ {
+ return result;
+ }
+ }
+ else
+ {
+ boolean result = StringUtils.isNotEmpty( sysValue );
+
+ if ( reverseName )
+ {
+ return !result;
+ }
+ else
+ {
+ return result;
+ }
+ }
+ }
+
+ return false;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/project/DefaultMavenProjectBuilder.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/project/DefaultMavenProjectBuilder.java
new file mode 100644
index 00000000..fff2de10
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/project/DefaultMavenProjectBuilder.java
@@ -0,0 +1,324 @@
+package org.apache.maven.project;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Properties;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.InvalidRepositoryException;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
+import org.apache.maven.artifact.resolver.ArtifactResolutionException;
+import org.apache.maven.execution.MavenExecutionRequest;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.model.Repository;
+import org.apache.maven.model.building.ModelBuildingException;
+import org.apache.maven.model.building.ModelBuildingRequest;
+import org.apache.maven.model.building.ModelSource;
+import org.apache.maven.model.building.UrlModelSource;
+import org.apache.maven.plugin.LegacySupport;
+import org.apache.maven.profiles.ProfileManager;
+import org.apache.maven.properties.internal.EnvironmentUtils;
+import org.apache.maven.repository.RepositorySystem;
+import org.apache.maven.wagon.events.TransferListener;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+
+/**
+ */
+@Component( role = MavenProjectBuilder.class )
+@Deprecated
+public class DefaultMavenProjectBuilder
+ implements MavenProjectBuilder
+{
+
+ @Requirement
+ private ProjectBuilder projectBuilder;
+
+ @Requirement
+ private RepositorySystem repositorySystem;
+
+ @Requirement
+ private LegacySupport legacySupport;
+
+ // ----------------------------------------------------------------------
+ // MavenProjectBuilder Implementation
+ // ----------------------------------------------------------------------
+
+ private ProjectBuildingRequest toRequest( ProjectBuilderConfiguration configuration )
+ {
+ DefaultProjectBuildingRequest request = new DefaultProjectBuildingRequest();
+
+ request.setValidationLevel( ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_2_0 );
+ request.setResolveDependencies( false );
+
+ request.setLocalRepository( configuration.getLocalRepository() );
+ request.setBuildStartTime( configuration.getBuildStartTime() );
+ request.setUserProperties( configuration.getUserProperties() );
+ request.setSystemProperties( configuration.getExecutionProperties() );
+
+ ProfileManager profileManager = configuration.getGlobalProfileManager();
+ if ( profileManager != null )
+ {
+ request.setActiveProfileIds( profileManager.getExplicitlyActivatedIds() );
+ request.setInactiveProfileIds( profileManager.getExplicitlyDeactivatedIds() );
+ }
+ else
+ {
+ /*
+ * MNG-4900: Hack to workaround deficiency of legacy API which makes it impossible for plugins to access the
+ * global profile manager which is required to build a POM like a CLI invocation does. Failure to consider
+ * the activated profiles can cause repo declarations to be lost which in turn will result in artifact
+ * resolution failures, in particular when using the enhanced local repo which guards access to local files
+ * based on the configured remote repos.
+ */
+ MavenSession session = legacySupport.getSession();
+ if ( session != null )
+ {
+ MavenExecutionRequest req = session.getRequest();
+ if ( req != null )
+ {
+ request.setActiveProfileIds( req.getActiveProfiles() );
+ request.setInactiveProfileIds( req.getInactiveProfiles() );
+ }
+ }
+ }
+
+ return request;
+ }
+
+ private ProjectBuildingRequest injectSession( ProjectBuildingRequest request )
+ {
+ MavenSession session = legacySupport.getSession();
+ if ( session != null )
+ {
+ request.setRepositorySession( session.getRepositorySession() );
+ request.setSystemProperties( session.getSystemProperties() );
+ if ( request.getUserProperties().isEmpty() )
+ {
+ request.setUserProperties( session.getUserProperties() );
+ }
+
+ MavenExecutionRequest req = session.getRequest();
+ if ( req != null )
+ {
+ request.setRemoteRepositories( req.getRemoteRepositories() );
+ }
+ }
+ else
+ {
+ Properties props = new Properties();
+ EnvironmentUtils.addEnvVars( props );
+ props.putAll( System.getProperties() );
+ request.setSystemProperties( props );
+ }
+
+ return request;
+ }
+
+ @SuppressWarnings( "unchecked" )
+ private List<ArtifactRepository> normalizeToArtifactRepositories( List<?> repositories,
+ ProjectBuildingRequest request )
+ throws ProjectBuildingException
+ {
+ /*
+ * This provides backward-compat with 2.x that allowed plugins like the maven-remote-resources-plugin:1.0 to
+ * populate the builder configuration with model repositories instead of artifact repositories.
+ */
+
+ if ( repositories != null )
+ {
+ boolean normalized = false;
+
+ List<ArtifactRepository> repos = new ArrayList<ArtifactRepository>( repositories.size() );
+
+ for ( Object repository : repositories )
+ {
+ if ( repository instanceof Repository )
+ {
+ try
+ {
+ ArtifactRepository repo = repositorySystem.buildArtifactRepository( (Repository) repository );
+ repositorySystem.injectMirror( request.getRepositorySession(), Arrays.asList( repo ) );
+ repositorySystem.injectProxy( request.getRepositorySession(), Arrays.asList( repo ) );
+ repositorySystem.injectAuthentication( request.getRepositorySession(), Arrays.asList( repo ) );
+ repos.add( repo );
+ }
+ catch ( InvalidRepositoryException e )
+ {
+ throw new ProjectBuildingException( "", "Invalid remote repository " + repository, e );
+ }
+ normalized = true;
+ }
+ else
+ {
+ repos.add( (ArtifactRepository) repository );
+ }
+ }
+
+ if ( normalized )
+ {
+ return repos;
+ }
+ }
+
+ return (List<ArtifactRepository>) repositories;
+ }
+
+ private ProjectBuildingException transformError( ProjectBuildingException e )
+ {
+ if ( e.getCause() instanceof ModelBuildingException )
+ {
+ return new InvalidProjectModelException( e.getProjectId(), e.getMessage(), e.getPomFile() );
+ }
+
+ return e;
+ }
+
+ public MavenProject build( File pom, ProjectBuilderConfiguration configuration )
+ throws ProjectBuildingException
+ {
+ ProjectBuildingRequest request = injectSession( toRequest( configuration ) );
+
+ try
+ {
+ return projectBuilder.build( pom, request ).getProject();
+ }
+ catch ( ProjectBuildingException e )
+ {
+ throw transformError( e );
+ }
+ }
+
+ // This is used by the SITE plugin.
+ public MavenProject build( File pom, ArtifactRepository localRepository, ProfileManager profileManager )
+ throws ProjectBuildingException
+ {
+ ProjectBuilderConfiguration configuration = new DefaultProjectBuilderConfiguration();
+ configuration.setLocalRepository( localRepository );
+ configuration.setGlobalProfileManager( profileManager );
+
+ return build( pom, configuration );
+ }
+
+ public MavenProject buildFromRepository( Artifact artifact, List<ArtifactRepository> remoteRepositories,
+ ProjectBuilderConfiguration configuration, boolean allowStubModel )
+ throws ProjectBuildingException
+ {
+ ProjectBuildingRequest request = injectSession( toRequest( configuration ) );
+ request.setRemoteRepositories( normalizeToArtifactRepositories( remoteRepositories, request ) );
+ request.setProcessPlugins( false );
+ request.setValidationLevel( ModelBuildingRequest.VALIDATION_LEVEL_MINIMAL );
+
+ try
+ {
+ return projectBuilder.build( artifact, allowStubModel, request ).getProject();
+ }
+ catch ( ProjectBuildingException e )
+ {
+ throw transformError( e );
+ }
+ }
+
+ public MavenProject buildFromRepository( Artifact artifact, List<ArtifactRepository> remoteRepositories,
+ ArtifactRepository localRepository, boolean allowStubModel )
+ throws ProjectBuildingException
+ {
+ ProjectBuilderConfiguration configuration = new DefaultProjectBuilderConfiguration();
+ configuration.setLocalRepository( localRepository );
+
+ return buildFromRepository( artifact, remoteRepositories, configuration, allowStubModel );
+ }
+
+ public MavenProject buildFromRepository( Artifact artifact, List<ArtifactRepository> remoteRepositories,
+ ArtifactRepository localRepository )
+ throws ProjectBuildingException
+ {
+ return buildFromRepository( artifact, remoteRepositories, localRepository, true );
+ }
+
+ /**
+ * This is used for pom-less execution like running archetype:generate. I am taking out the profile handling and the
+ * interpolation of the base directory until we spec this out properly.
+ */
+ public MavenProject buildStandaloneSuperProject( ProjectBuilderConfiguration configuration )
+ throws ProjectBuildingException
+ {
+ ProjectBuildingRequest request = injectSession( toRequest( configuration ) );
+ request.setProcessPlugins( false );
+ request.setValidationLevel( ModelBuildingRequest.VALIDATION_LEVEL_MINIMAL );
+
+ ModelSource modelSource = new UrlModelSource( getClass().getResource( "standalone.xml" ) );
+
+ MavenProject project = projectBuilder.build( modelSource, request ).getProject();
+ project.setExecutionRoot( true );
+ return project;
+ }
+
+ public MavenProject buildStandaloneSuperProject( ArtifactRepository localRepository )
+ throws ProjectBuildingException
+ {
+ return buildStandaloneSuperProject( localRepository, null );
+ }
+
+ public MavenProject buildStandaloneSuperProject( ArtifactRepository localRepository, ProfileManager profileManager )
+ throws ProjectBuildingException
+ {
+ ProjectBuilderConfiguration configuration = new DefaultProjectBuilderConfiguration();
+ configuration.setLocalRepository( localRepository );
+ configuration.setGlobalProfileManager( profileManager );
+
+ return buildStandaloneSuperProject( configuration );
+ }
+
+ public MavenProject buildWithDependencies( File pom, ArtifactRepository localRepository,
+ ProfileManager profileManager, TransferListener transferListener )
+ throws ProjectBuildingException, ArtifactResolutionException, ArtifactNotFoundException
+ {
+ ProjectBuilderConfiguration configuration = new DefaultProjectBuilderConfiguration();
+ configuration.setLocalRepository( localRepository );
+ configuration.setGlobalProfileManager( profileManager );
+
+ ProjectBuildingRequest request = injectSession( toRequest( configuration ) );
+
+ request.setResolveDependencies( true );
+
+ try
+ {
+ return projectBuilder.build( pom, request ).getProject();
+ }
+ catch ( ProjectBuildingException e )
+ {
+ throw transformError( e );
+ }
+ }
+
+ public MavenProject buildWithDependencies( File pom, ArtifactRepository localRepository,
+ ProfileManager profileManager )
+ throws ProjectBuildingException, ArtifactResolutionException, ArtifactNotFoundException
+ {
+ return buildWithDependencies( pom, localRepository, profileManager, null );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/project/DefaultProjectBuilderConfiguration.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/project/DefaultProjectBuilderConfiguration.java
new file mode 100644
index 00000000..d08f18e0
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/project/DefaultProjectBuilderConfiguration.java
@@ -0,0 +1,107 @@
+package org.apache.maven.project;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Date;
+import java.util.Properties;
+
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.profiles.ProfileManager;
+
+@Deprecated
+public class DefaultProjectBuilderConfiguration
+ implements ProjectBuilderConfiguration
+{
+
+ private ProfileManager globalProfileManager;
+
+ private ArtifactRepository localRepository;
+
+ private Properties userProperties;
+
+ private Properties executionProperties = System.getProperties();
+
+ private Date buildStartTime;
+
+ public DefaultProjectBuilderConfiguration()
+ {
+ }
+
+ public ProjectBuilderConfiguration setGlobalProfileManager( ProfileManager globalProfileManager )
+ {
+ this.globalProfileManager = globalProfileManager;
+ return this;
+ }
+
+ public ProfileManager getGlobalProfileManager()
+ {
+ return globalProfileManager;
+ }
+
+ public ProjectBuilderConfiguration setLocalRepository( ArtifactRepository localRepository )
+ {
+ this.localRepository = localRepository;
+ return this;
+ }
+
+ public ArtifactRepository getLocalRepository()
+ {
+ return localRepository;
+ }
+
+ public ProjectBuilderConfiguration setUserProperties( Properties userProperties )
+ {
+ this.userProperties = userProperties;
+ return this;
+ }
+
+ public Properties getUserProperties()
+ {
+ if ( userProperties == null )
+ {
+ userProperties = new Properties();
+ }
+
+ return userProperties;
+ }
+
+ public Properties getExecutionProperties()
+ {
+ return executionProperties;
+ }
+
+ public ProjectBuilderConfiguration setExecutionProperties( Properties executionProperties )
+ {
+ this.executionProperties = executionProperties;
+ return this;
+ }
+
+ public Date getBuildStartTime()
+ {
+ return buildStartTime;
+ }
+
+ public ProjectBuilderConfiguration setBuildStartTime( Date buildStartTime )
+ {
+ this.buildStartTime = buildStartTime;
+ return this;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/project/InvalidProjectModelException.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/project/InvalidProjectModelException.java
new file mode 100644
index 00000000..cf85aa9e
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/project/InvalidProjectModelException.java
@@ -0,0 +1,74 @@
+package org.apache.maven.project;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+
+import org.apache.maven.project.validation.ModelValidationResult;
+
+@Deprecated
+public class InvalidProjectModelException
+ extends ProjectBuildingException
+{
+ private ModelValidationResult validationResult;
+
+ public InvalidProjectModelException( String projectId, String message, File pomLocation )
+ {
+ super( projectId, message, pomLocation );
+ }
+
+ /**
+ * @param projectId
+ * @param pomLocation absolute path of the pom file
+ * @param message
+ * @param validationResult
+ * @deprecated use {@link File} constructor for pomLocation
+ */
+ public InvalidProjectModelException( String projectId, String pomLocation, String message,
+ ModelValidationResult validationResult )
+ {
+ this( projectId, message, new File( pomLocation ), validationResult );
+ }
+
+ public InvalidProjectModelException( String projectId, String message, File pomFile,
+ ModelValidationResult validationResult )
+ {
+ super( projectId, message, pomFile );
+
+ this.validationResult = validationResult;
+ }
+
+ /**
+ * @param projectId
+ * @param pomLocation absolute path of the pom file
+ * @param message
+ * @deprecated use {@link File} constructor for pomLocation
+ */
+ public InvalidProjectModelException( String projectId, String pomLocation, String message )
+ {
+ this( projectId, message, new File( pomLocation ) );
+ }
+
+ public final ModelValidationResult getValidationResult()
+ {
+ return validationResult;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/project/MavenProjectBuilder.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/project/MavenProjectBuilder.java
new file mode 100644
index 00000000..c44d8dbc
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/project/MavenProjectBuilder.java
@@ -0,0 +1,76 @@
+package org.apache.maven.project;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.util.List;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
+import org.apache.maven.artifact.resolver.ArtifactResolutionException;
+import org.apache.maven.profiles.ProfileManager;
+import org.apache.maven.wagon.events.TransferListener;
+
+/**
+ * @deprecated use {@link ProjectBuilder} instead
+ */
+@Deprecated
+public interface MavenProjectBuilder
+{
+
+ MavenProject build( File pom, ProjectBuilderConfiguration configuration )
+ throws ProjectBuildingException;
+
+ //TODO maven-site-plugin -- Vincent, Dennis and Lukas are checking but this doesn't appear to be required anymore.
+ MavenProject build( File pom, ArtifactRepository localRepository, ProfileManager profileManager )
+ throws ProjectBuildingException;
+
+ //TODO remote-resources-plugin
+ MavenProject buildFromRepository( Artifact artifact, List<ArtifactRepository> remoteRepositories,
+ ArtifactRepository localRepository )
+ throws ProjectBuildingException;
+
+ //TODO remote-resources-plugin
+ MavenProject buildFromRepository( Artifact artifact, List<ArtifactRepository> remoteRepositories,
+ ArtifactRepository localRepository, boolean allowStubModel )
+ throws ProjectBuildingException;
+
+ // TODO: this is only to provide a project for plugins that don't need a project to execute but need some
+ // of the values from a MavenProject. Ideally this should be something internal and nothing outside Maven
+ // would ever need this so it should not be exposed in a public API
+ MavenProject buildStandaloneSuperProject( ProjectBuilderConfiguration configuration )
+ throws ProjectBuildingException;
+
+ MavenProject buildStandaloneSuperProject( ArtifactRepository localRepository )
+ throws ProjectBuildingException;
+
+ MavenProject buildStandaloneSuperProject( ArtifactRepository localRepository, ProfileManager profileManager )
+ throws ProjectBuildingException;
+
+ MavenProject buildWithDependencies( File pom, ArtifactRepository localRepository,
+ ProfileManager globalProfileManager, TransferListener transferListener )
+ throws ProjectBuildingException, ArtifactResolutionException, ArtifactNotFoundException;
+
+ MavenProject buildWithDependencies( File pom, ArtifactRepository localRepository,
+ ProfileManager globalProfileManager )
+ throws ProjectBuildingException, ArtifactResolutionException, ArtifactNotFoundException;
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/project/MissingRepositoryElementException.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/project/MissingRepositoryElementException.java
new file mode 100644
index 00000000..17c267e3
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/project/MissingRepositoryElementException.java
@@ -0,0 +1,38 @@
+package org.apache.maven.project;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.artifact.InvalidRepositoryException;
+
+public class MissingRepositoryElementException
+ extends InvalidRepositoryException
+{
+
+ public MissingRepositoryElementException( String message, String repositoryId )
+ {
+ super( message, repositoryId );
+ }
+
+ public MissingRepositoryElementException( String message )
+ {
+ super( message, "-unknown-" );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/project/ModelUtils.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/project/ModelUtils.java
new file mode 100644
index 00000000..1af061d3
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/project/ModelUtils.java
@@ -0,0 +1,367 @@
+package org.apache.maven.project;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
+import org.apache.maven.model.Dependency;
+import org.apache.maven.model.Plugin;
+import org.apache.maven.model.PluginContainer;
+import org.apache.maven.model.PluginExecution;
+import org.apache.maven.model.Repository;
+import org.codehaus.plexus.util.xml.Xpp3Dom;
+
+/** @deprecated */
+@Deprecated
+public final class ModelUtils
+{
+
+ /**
+ * This should be the resulting ordering of plugins after merging:
+ * <p/>
+ * Given:
+ * <p/>
+ * parent: X -> A -> B -> D -> E
+ * child: Y -> A -> C -> D -> F
+ * <p/>
+ * Result:
+ * <p/>
+ * X -> Y -> A -> B -> C -> D -> E -> F
+ */
+ public static void mergePluginLists( PluginContainer childContainer, PluginContainer parentContainer,
+ boolean handleAsInheritance )
+ {
+ if ( ( childContainer == null ) || ( parentContainer == null ) )
+ {
+ // nothing to do.
+ return;
+ }
+
+ List<Plugin> parentPlugins = parentContainer.getPlugins();
+
+ if ( ( parentPlugins != null ) && !parentPlugins.isEmpty() )
+ {
+ parentPlugins = new ArrayList<Plugin>( parentPlugins );
+
+ // If we're processing this merge as an inheritance, we have to build up a list of
+ // plugins that were considered for inheritance.
+ if ( handleAsInheritance )
+ {
+ for ( Iterator<Plugin> it = parentPlugins.iterator(); it.hasNext(); )
+ {
+ Plugin plugin = it.next();
+
+ String inherited = plugin.getInherited();
+
+ if ( ( inherited != null ) && !Boolean.valueOf( inherited ) )
+ {
+ it.remove();
+ }
+ }
+ }
+
+ List<Plugin> assembledPlugins = new ArrayList<Plugin>();
+
+ Map<String, Plugin> childPlugins = childContainer.getPluginsAsMap();
+
+ for ( Plugin parentPlugin : parentPlugins )
+ {
+ String parentInherited = parentPlugin.getInherited();
+
+ // only merge plugin definition from the parent if at least one
+ // of these is true:
+ // 1. we're not processing the plugins in an inheritance-based merge
+ // 2. the parent's <inherited/> flag is not set
+ // 3. the parent's <inherited/> flag is set to true
+ if ( !handleAsInheritance || ( parentInherited == null )
+ || Boolean.valueOf( parentInherited ) )
+ {
+ Plugin childPlugin = childPlugins.get( parentPlugin.getKey() );
+
+ if ( ( childPlugin != null ) && !assembledPlugins.contains( childPlugin ) )
+ {
+ Plugin assembledPlugin = childPlugin;
+
+ mergePluginDefinitions( childPlugin, parentPlugin, handleAsInheritance );
+
+ // fix for MNG-2221 (assembly cache was not being populated for later reference):
+ assembledPlugins.add( assembledPlugin );
+ }
+
+ // if we're processing this as an inheritance-based merge, and
+ // the parent's <inherited/> flag is not set, then we need to
+ // clear the inherited flag in the merge result.
+ if ( handleAsInheritance && ( parentInherited == null ) )
+ {
+ parentPlugin.unsetInheritanceApplied();
+ }
+ }
+
+ // very important to use the parentPlugins List, rather than parentContainer.getPlugins()
+ // since this list is a local one, and may have been modified during processing.
+ List<Plugin> results =
+ ModelUtils.orderAfterMerge( assembledPlugins, parentPlugins, childContainer.getPlugins() );
+
+ childContainer.setPlugins( results );
+
+ childContainer.flushPluginMap();
+ }
+ }
+ }
+
+ public static List<Plugin> orderAfterMerge( List<Plugin> merged, List<Plugin> highPrioritySource,
+ List<Plugin> lowPrioritySource )
+ {
+ List<Plugin> results = new ArrayList<Plugin>();
+
+ if ( !merged.isEmpty() )
+ {
+ results.addAll( merged );
+ }
+
+ List<Plugin> missingFromResults = new ArrayList<Plugin>();
+
+ List<List<Plugin>> sources = new ArrayList<List<Plugin>>();
+
+ sources.add( highPrioritySource );
+ sources.add( lowPrioritySource );
+
+ for ( List<Plugin> source : sources )
+ {
+ for ( Plugin item : source )
+ {
+ if ( results.contains( item ) )
+ {
+ if ( !missingFromResults.isEmpty() )
+ {
+ int idx = results.indexOf( item );
+
+ if ( idx < 0 )
+ {
+ idx = 0;
+ }
+
+ results.addAll( idx, missingFromResults );
+
+ missingFromResults.clear();
+ }
+ }
+ else
+ {
+ missingFromResults.add( item );
+ }
+ }
+
+ if ( !missingFromResults.isEmpty() )
+ {
+ results.addAll( missingFromResults );
+
+ missingFromResults.clear();
+ }
+ }
+
+ return results;
+ }
+
+
+ public static void mergePluginDefinitions( Plugin child, Plugin parent, boolean handleAsInheritance )
+ {
+ if ( ( child == null ) || ( parent == null ) )
+ {
+ // nothing to do.
+ return;
+ }
+
+ if ( parent.isExtensions() )
+ {
+ child.setExtensions( true );
+ }
+
+ if ( ( child.getVersion() == null ) && ( parent.getVersion() != null ) )
+ {
+ child.setVersion( parent.getVersion() );
+ }
+
+ Xpp3Dom childConfiguration = (Xpp3Dom) child.getConfiguration();
+ Xpp3Dom parentConfiguration = (Xpp3Dom) parent.getConfiguration();
+
+ childConfiguration = Xpp3Dom.mergeXpp3Dom( childConfiguration, parentConfiguration );
+
+ child.setConfiguration( childConfiguration );
+
+ child.setDependencies( mergeDependencyList( child.getDependencies(), parent.getDependencies() ) );
+
+ // from here to the end of the method is dealing with merging of the <executions/> section.
+ String parentInherited = parent.getInherited();
+
+ boolean parentIsInherited = ( parentInherited == null ) || Boolean.valueOf( parentInherited );
+
+ List<PluginExecution> parentExecutions = parent.getExecutions();
+
+ if ( ( parentExecutions != null ) && !parentExecutions.isEmpty() )
+ {
+ List<PluginExecution> mergedExecutions = new ArrayList<PluginExecution>();
+
+ Map<String, PluginExecution> assembledExecutions = new TreeMap<String, PluginExecution>();
+
+ Map<String, PluginExecution> childExecutions = child.getExecutionsAsMap();
+
+ for ( PluginExecution parentExecution : parentExecutions )
+ {
+ String inherited = parentExecution.getInherited();
+
+ boolean parentExecInherited =
+ parentIsInherited && ( ( inherited == null ) || Boolean.valueOf( inherited ) );
+
+ if ( !handleAsInheritance || parentExecInherited )
+ {
+ PluginExecution assembled = parentExecution;
+
+ PluginExecution childExecution = childExecutions.get( parentExecution.getId() );
+
+ if ( childExecution != null )
+ {
+ mergePluginExecutionDefinitions( childExecution, parentExecution );
+
+ assembled = childExecution;
+ }
+ else if ( handleAsInheritance && ( parentInherited == null ) )
+ {
+ parentExecution.unsetInheritanceApplied();
+ }
+
+ assembledExecutions.put( assembled.getId(), assembled );
+ mergedExecutions.add( assembled );
+ }
+ }
+
+ for ( PluginExecution childExecution : child.getExecutions() )
+ {
+ if ( !assembledExecutions.containsKey( childExecution.getId() ) )
+ {
+ mergedExecutions.add( childExecution );
+ }
+ }
+
+ child.setExecutions( mergedExecutions );
+
+ child.flushExecutionMap();
+ }
+
+ }
+
+ private static void mergePluginExecutionDefinitions( PluginExecution child, PluginExecution parent )
+ {
+ if ( child.getPhase() == null )
+ {
+ child.setPhase( parent.getPhase() );
+ }
+
+ List<String> parentGoals = parent.getGoals();
+ List<String> childGoals = child.getGoals();
+
+ List<String> goals = new ArrayList<String>();
+
+ if ( ( childGoals != null ) && !childGoals.isEmpty() )
+ {
+ goals.addAll( childGoals );
+ }
+
+ if ( parentGoals != null )
+ {
+ for ( String goal : parentGoals )
+ {
+ if ( !goals.contains( goal ) )
+ {
+ goals.add( goal );
+ }
+ }
+ }
+
+ child.setGoals( goals );
+
+ Xpp3Dom childConfiguration = (Xpp3Dom) child.getConfiguration();
+ Xpp3Dom parentConfiguration = (Xpp3Dom) parent.getConfiguration();
+
+ childConfiguration = Xpp3Dom.mergeXpp3Dom( childConfiguration, parentConfiguration );
+
+ child.setConfiguration( childConfiguration );
+ }
+
+ public static List<Repository> mergeRepositoryLists( List<Repository> dominant, List<Repository> recessive )
+ {
+ List<Repository> repositories = new ArrayList<Repository>();
+
+ for ( Repository repository : dominant )
+ {
+ repositories.add( repository );
+ }
+
+ for ( Repository repository : recessive )
+ {
+ if ( !repositories.contains( repository ) )
+ {
+ repositories.add( repository );
+ }
+ }
+
+ return repositories;
+ }
+
+ public static void mergeFilterLists( List<String> childFilters, List<String> parentFilters )
+ {
+ for ( String f : parentFilters )
+ {
+ if ( !childFilters.contains( f ) )
+ {
+ childFilters.add( f );
+ }
+ }
+ }
+
+ private static List<Dependency> mergeDependencyList( List<Dependency> child, List<Dependency> parent )
+ {
+ Map<String, Dependency> depsMap = new LinkedHashMap<String, Dependency>();
+
+ if ( parent != null )
+ {
+ for ( Dependency dependency : parent )
+ {
+ depsMap.put( dependency.getManagementKey(), dependency );
+ }
+ }
+
+ if ( child != null )
+ {
+ for ( Dependency dependency : child )
+ {
+ depsMap.put( dependency.getManagementKey(), dependency );
+ }
+ }
+
+ return new ArrayList<Dependency>( depsMap.values() );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/project/ProjectBuilderConfiguration.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/project/ProjectBuilderConfiguration.java
new file mode 100644
index 00000000..ddfad3cb
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/project/ProjectBuilderConfiguration.java
@@ -0,0 +1,55 @@
+package org.apache.maven.project;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Date;
+import java.util.Properties;
+
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.profiles.ProfileManager;
+
+/**
+ * @deprecated use {@link ProjectBuildingRequest} instead
+ */
+@Deprecated
+public interface ProjectBuilderConfiguration
+{
+
+ ArtifactRepository getLocalRepository();
+
+ ProfileManager getGlobalProfileManager();
+
+ Properties getUserProperties();
+
+ Properties getExecutionProperties();
+
+ ProjectBuilderConfiguration setGlobalProfileManager( ProfileManager globalProfileManager );
+
+ ProjectBuilderConfiguration setLocalRepository( ArtifactRepository localRepository );
+
+ ProjectBuilderConfiguration setUserProperties( Properties userProperties );
+
+ ProjectBuilderConfiguration setExecutionProperties( Properties executionProperties );
+
+ Date getBuildStartTime();
+
+ ProjectBuilderConfiguration setBuildStartTime( Date buildStartTime );
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/project/ProjectUtils.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/project/ProjectUtils.java
new file mode 100644
index 00000000..b70d3cff
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/project/ProjectUtils.java
@@ -0,0 +1,118 @@
+package org.apache.maven.project;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.maven.artifact.InvalidRepositoryException;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.repository.ArtifactRepositoryFactory;
+import org.apache.maven.model.DeploymentRepository;
+import org.apache.maven.model.Repository;
+import org.apache.maven.plugin.LegacySupport;
+import org.apache.maven.repository.RepositorySystem;
+import org.codehaus.plexus.PlexusContainer;
+import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
+import org.eclipse.aether.RepositorySystemSession;
+
+// This class needs to stick around because it was exposed the the remote resources plugin started using it instead of
+// getting the repositories from the project.
+
+@Deprecated
+public final class ProjectUtils
+{
+
+ private ProjectUtils()
+ {
+ }
+
+ public static List<ArtifactRepository> buildArtifactRepositories( List<Repository> repositories,
+ ArtifactRepositoryFactory artifactRepositoryFactory,
+ PlexusContainer c )
+ throws InvalidRepositoryException
+ {
+
+ List<ArtifactRepository> remoteRepositories = new ArrayList<ArtifactRepository>();
+
+ for ( Repository r : repositories )
+ {
+ remoteRepositories.add( buildArtifactRepository( r, artifactRepositoryFactory, c ) );
+ }
+
+ return remoteRepositories;
+ }
+
+ public static ArtifactRepository buildDeploymentArtifactRepository( DeploymentRepository repo,
+ ArtifactRepositoryFactory artifactRepositoryFactory,
+ PlexusContainer c )
+ throws InvalidRepositoryException
+ {
+ return buildArtifactRepository( repo, artifactRepositoryFactory, c );
+ }
+
+ public static ArtifactRepository buildArtifactRepository( Repository repo,
+ ArtifactRepositoryFactory artifactRepositoryFactory,
+ PlexusContainer c )
+ throws InvalidRepositoryException
+ {
+ RepositorySystem repositorySystem = rs( c );
+ RepositorySystemSession session = rss( c );
+
+ ArtifactRepository repository = repositorySystem.buildArtifactRepository( repo );
+
+ if ( session != null )
+ {
+ repositorySystem.injectMirror( session, Arrays.asList( repository ) );
+ repositorySystem.injectProxy( session, Arrays.asList( repository ) );
+ repositorySystem.injectAuthentication( session, Arrays.asList( repository ) );
+ }
+
+ return repository;
+ }
+
+ private static RepositorySystem rs( PlexusContainer c )
+ {
+ try
+ {
+ return c.lookup( RepositorySystem.class );
+ }
+ catch ( ComponentLookupException e )
+ {
+ throw new IllegalStateException( e );
+ }
+ }
+
+ private static RepositorySystemSession rss( PlexusContainer c )
+ {
+ try
+ {
+ LegacySupport legacySupport = c.lookup( LegacySupport.class );
+
+ return legacySupport.getRepositorySession();
+ }
+ catch ( ComponentLookupException e )
+ {
+ throw new IllegalStateException( e );
+ }
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/project/inheritance/DefaultModelInheritanceAssembler.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/project/inheritance/DefaultModelInheritanceAssembler.java
new file mode 100644
index 00000000..4b08eb96
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/project/inheritance/DefaultModelInheritanceAssembler.java
@@ -0,0 +1,752 @@
+package org.apache.maven.project.inheritance;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.StringTokenizer;
+import java.util.TreeMap;
+
+import org.apache.maven.model.Build;
+import org.apache.maven.model.Dependency;
+import org.apache.maven.model.DependencyManagement;
+import org.apache.maven.model.DeploymentRepository;
+import org.apache.maven.model.DistributionManagement;
+import org.apache.maven.model.Extension;
+import org.apache.maven.model.Model;
+import org.apache.maven.model.PluginManagement;
+import org.apache.maven.model.ReportPlugin;
+import org.apache.maven.model.ReportSet;
+import org.apache.maven.model.Reporting;
+import org.apache.maven.model.Resource;
+import org.apache.maven.model.Scm;
+import org.apache.maven.model.Site;
+import org.apache.maven.project.ModelUtils;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.util.StringUtils;
+import org.codehaus.plexus.util.xml.Xpp3Dom;
+
+@Component( role = ModelInheritanceAssembler.class )
+public class DefaultModelInheritanceAssembler
+ implements ModelInheritanceAssembler
+{
+ // TODO: Remove this!
+ @SuppressWarnings( "unchecked" )
+ public void assembleBuildInheritance( Build childBuild, Build parentBuild, boolean handleAsInheritance )
+ {
+ // The build has been set but we want to step in here and fill in
+ // values that have not been set by the child.
+
+ if ( childBuild.getSourceDirectory() == null )
+ {
+ childBuild.setSourceDirectory( parentBuild.getSourceDirectory() );
+ }
+
+ if ( childBuild.getScriptSourceDirectory() == null )
+ {
+ childBuild.setScriptSourceDirectory( parentBuild.getScriptSourceDirectory() );
+ }
+
+ if ( childBuild.getTestSourceDirectory() == null )
+ {
+ childBuild.setTestSourceDirectory( parentBuild.getTestSourceDirectory() );
+ }
+
+ if ( childBuild.getOutputDirectory() == null )
+ {
+ childBuild.setOutputDirectory( parentBuild.getOutputDirectory() );
+ }
+
+ if ( childBuild.getTestOutputDirectory() == null )
+ {
+ childBuild.setTestOutputDirectory( parentBuild.getTestOutputDirectory() );
+ }
+
+ // Extensions are accumulated
+ mergeExtensionLists( childBuild, parentBuild );
+
+ if ( childBuild.getDirectory() == null )
+ {
+ childBuild.setDirectory( parentBuild.getDirectory() );
+ }
+
+ if ( childBuild.getDefaultGoal() == null )
+ {
+ childBuild.setDefaultGoal( parentBuild.getDefaultGoal() );
+ }
+
+ if ( childBuild.getFinalName() == null )
+ {
+ childBuild.setFinalName( parentBuild.getFinalName() );
+ }
+
+ ModelUtils.mergeFilterLists( childBuild.getFilters(), parentBuild.getFilters() );
+
+ List<Resource> resources = childBuild.getResources();
+ if ( ( resources == null ) || resources.isEmpty() )
+ {
+ childBuild.setResources( parentBuild.getResources() );
+ }
+
+ resources = childBuild.getTestResources();
+ if ( ( resources == null ) || resources.isEmpty() )
+ {
+ childBuild.setTestResources( parentBuild.getTestResources() );
+ }
+
+ // Plugins are aggregated if Plugin.inherit != false
+ ModelUtils.mergePluginLists( childBuild, parentBuild, handleAsInheritance );
+
+ // Plugin management :: aggregate
+ PluginManagement dominantPM = childBuild.getPluginManagement();
+ PluginManagement recessivePM = parentBuild.getPluginManagement();
+
+ if ( ( dominantPM == null ) && ( recessivePM != null ) )
+ {
+ // FIXME: Filter out the inherited == false stuff!
+ childBuild.setPluginManagement( recessivePM );
+ }
+ else
+ {
+ ModelUtils.mergePluginLists( childBuild.getPluginManagement(), parentBuild.getPluginManagement(), false );
+ }
+ }
+
+ private void assembleScmInheritance( Model child, Model parent, String childPathAdjustment, boolean appendPaths )
+ {
+ if ( parent.getScm() != null )
+ {
+ Scm parentScm = parent.getScm();
+
+ Scm childScm = child.getScm();
+
+ if ( childScm == null )
+ {
+ childScm = new Scm();
+
+ child.setScm( childScm );
+ }
+
+ if ( StringUtils.isEmpty( childScm.getConnection() ) && !StringUtils.isEmpty( parentScm.getConnection() ) )
+ {
+ childScm.setConnection(
+ appendPath( parentScm.getConnection(), child.getArtifactId(), childPathAdjustment, appendPaths ) );
+ }
+
+ if ( StringUtils.isEmpty( childScm.getDeveloperConnection() )
+ && !StringUtils.isEmpty( parentScm.getDeveloperConnection() ) )
+ {
+ childScm
+ .setDeveloperConnection( appendPath( parentScm.getDeveloperConnection(), child.getArtifactId(),
+ childPathAdjustment, appendPaths ) );
+ }
+
+ if ( StringUtils.isEmpty( childScm.getUrl() ) && !StringUtils.isEmpty( parentScm.getUrl() ) )
+ {
+ childScm.setUrl(
+ appendPath( parentScm.getUrl(), child.getArtifactId(), childPathAdjustment, appendPaths ) );
+ }
+ }
+ }
+
+ public void copyModel( Model dest, Model source )
+ {
+ assembleModelInheritance( dest, source, null, false );
+ }
+
+ public void assembleModelInheritance( Model child, Model parent, String childPathAdjustment )
+ {
+ assembleModelInheritance( child, parent, childPathAdjustment, true );
+ }
+
+ public void assembleModelInheritance( Model child, Model parent )
+ {
+ assembleModelInheritance( child, parent, null, true );
+ }
+
+ private void assembleModelInheritance( Model child, Model parent, String childPathAdjustment, boolean appendPaths )
+ {
+ // cannot inherit from null parent.
+ if ( parent == null )
+ {
+ return;
+ }
+
+ // Group id
+ if ( child.getGroupId() == null )
+ {
+ child.setGroupId( parent.getGroupId() );
+ }
+
+ // version
+ if ( child.getVersion() == null )
+ {
+ // The parent version may have resolved to something different, so we take what we asked for...
+ // instead of - child.setVersion( parent.getVersion() );
+
+ if ( child.getParent() != null )
+ {
+ child.setVersion( child.getParent().getVersion() );
+ }
+ }
+
+ // inceptionYear
+ if ( child.getInceptionYear() == null )
+ {
+ child.setInceptionYear( parent.getInceptionYear() );
+ }
+
+ // url
+ if ( child.getUrl() == null )
+ {
+ if ( parent.getUrl() != null )
+ {
+ child.setUrl( appendPath( parent.getUrl(), child.getArtifactId(), childPathAdjustment, appendPaths ) );
+ }
+ else
+ {
+ child.setUrl( parent.getUrl() );
+ }
+ }
+
+ assembleDistributionInheritence( child, parent, childPathAdjustment, appendPaths );
+
+ // issueManagement
+ if ( child.getIssueManagement() == null )
+ {
+ child.setIssueManagement( parent.getIssueManagement() );
+ }
+
+ // description
+ if ( child.getDescription() == null )
+ {
+ child.setDescription( parent.getDescription() );
+ }
+
+ // Organization
+ if ( child.getOrganization() == null )
+ {
+ child.setOrganization( parent.getOrganization() );
+ }
+
+ // Scm
+ assembleScmInheritance( child, parent, childPathAdjustment, appendPaths );
+
+ // ciManagement
+ if ( child.getCiManagement() == null )
+ {
+ child.setCiManagement( parent.getCiManagement() );
+ }
+
+ // developers
+ if ( child.getDevelopers().size() == 0 )
+ {
+ child.setDevelopers( parent.getDevelopers() );
+ }
+
+ // licenses
+ if ( child.getLicenses().size() == 0 )
+ {
+ child.setLicenses( parent.getLicenses() );
+ }
+
+ // developers
+ if ( child.getContributors().size() == 0 )
+ {
+ child.setContributors( parent.getContributors() );
+ }
+
+ // mailingLists
+ if ( child.getMailingLists().size() == 0 )
+ {
+ child.setMailingLists( parent.getMailingLists() );
+ }
+
+ // Build
+ assembleBuildInheritance( child, parent );
+
+ assembleDependencyInheritance( child, parent );
+
+ child.setRepositories( ModelUtils.mergeRepositoryLists( child.getRepositories(), parent.getRepositories() ) );
+// child.setPluginRepositories(
+// ModelUtils.mergeRepositoryLists( child.getPluginRepositories(), parent.getPluginRepositories() ) );
+
+ assembleReportingInheritance( child, parent );
+
+ assembleDependencyManagementInheritance( child, parent );
+
+ Properties props = new Properties();
+ props.putAll( parent.getProperties() );
+ props.putAll( child.getProperties() );
+
+ child.setProperties( props );
+ }
+
+ // TODO: Remove this!
+ @SuppressWarnings( "unchecked" )
+ private void assembleDependencyManagementInheritance( Model child, Model parent )
+ {
+ DependencyManagement parentDepMgmt = parent.getDependencyManagement();
+
+ DependencyManagement childDepMgmt = child.getDependencyManagement();
+
+ if ( parentDepMgmt != null )
+ {
+ if ( childDepMgmt == null )
+ {
+ child.setDependencyManagement( parentDepMgmt );
+ }
+ else
+ {
+ List<Dependency> childDeps = childDepMgmt.getDependencies();
+
+ Map<String, Dependency> mappedChildDeps = new TreeMap<String, Dependency>();
+ for ( Dependency dep : childDeps )
+ {
+ mappedChildDeps.put( dep.getManagementKey(), dep );
+ }
+
+ for ( Dependency dep : parentDepMgmt.getDependencies() )
+ {
+ if ( !mappedChildDeps.containsKey( dep.getManagementKey() ) )
+ {
+ childDepMgmt.addDependency( dep );
+ }
+ }
+ }
+ }
+ }
+
+ private void assembleReportingInheritance( Model child, Model parent )
+ {
+ // Reports :: aggregate
+ Reporting childReporting = child.getReporting();
+ Reporting parentReporting = parent.getReporting();
+
+ if ( parentReporting != null )
+ {
+ if ( childReporting == null )
+ {
+ childReporting = new Reporting();
+ child.setReporting( childReporting );
+ }
+
+ childReporting.setExcludeDefaults( parentReporting.isExcludeDefaults() );
+
+ if ( StringUtils.isEmpty( childReporting.getOutputDirectory() ) )
+ {
+ childReporting.setOutputDirectory( parentReporting.getOutputDirectory() );
+ }
+
+ mergeReportPluginLists( childReporting, parentReporting, true );
+ }
+ }
+
+ private static void mergeReportPluginLists( Reporting child, Reporting parent, boolean handleAsInheritance )
+ {
+ if ( ( child == null ) || ( parent == null ) )
+ {
+ // nothing to do.
+ return;
+ }
+
+ List<ReportPlugin> parentPlugins = parent.getPlugins();
+
+ if ( ( parentPlugins != null ) && !parentPlugins.isEmpty() )
+ {
+ Map<String, ReportPlugin> assembledPlugins = new TreeMap<String, ReportPlugin>();
+
+ Map<String, ReportPlugin> childPlugins = child.getReportPluginsAsMap();
+
+ for ( ReportPlugin parentPlugin : parentPlugins )
+ {
+ String parentInherited = parentPlugin.getInherited();
+
+ if ( !handleAsInheritance || ( parentInherited == null ) || Boolean.valueOf( parentInherited ) )
+ {
+
+ ReportPlugin assembledPlugin = parentPlugin;
+
+ ReportPlugin childPlugin = childPlugins.get( parentPlugin.getKey() );
+
+ if ( childPlugin != null )
+ {
+ assembledPlugin = childPlugin;
+
+ mergeReportPluginDefinitions( childPlugin, parentPlugin, handleAsInheritance );
+ }
+
+ if ( handleAsInheritance && ( parentInherited == null ) )
+ {
+ assembledPlugin.unsetInheritanceApplied();
+ }
+
+ assembledPlugins.put( assembledPlugin.getKey(), assembledPlugin );
+ }
+ }
+
+ for ( ReportPlugin childPlugin : childPlugins.values() )
+ {
+ if ( !assembledPlugins.containsKey( childPlugin.getKey() ) )
+ {
+ assembledPlugins.put( childPlugin.getKey(), childPlugin );
+ }
+ }
+
+ child.setPlugins( new ArrayList<ReportPlugin>( assembledPlugins.values() ) );
+
+ child.flushReportPluginMap();
+ }
+ }
+
+ private static void mergeReportSetDefinitions( ReportSet child, ReportSet parent )
+ {
+ List<String> parentReports = parent.getReports();
+ List<String> childReports = child.getReports();
+
+ List<String> reports = new ArrayList<String>();
+
+ if ( ( childReports != null ) && !childReports.isEmpty() )
+ {
+ reports.addAll( childReports );
+ }
+
+ if ( parentReports != null )
+ {
+ for ( String report : parentReports )
+ {
+ if ( !reports.contains( report ) )
+ {
+ reports.add( report );
+ }
+ }
+ }
+
+ child.setReports( reports );
+
+ Xpp3Dom childConfiguration = (Xpp3Dom) child.getConfiguration();
+ Xpp3Dom parentConfiguration = (Xpp3Dom) parent.getConfiguration();
+
+ childConfiguration = Xpp3Dom.mergeXpp3Dom( childConfiguration, parentConfiguration );
+
+ child.setConfiguration( childConfiguration );
+ }
+
+
+ public static void mergeReportPluginDefinitions( ReportPlugin child, ReportPlugin parent,
+ boolean handleAsInheritance )
+ {
+ if ( ( child == null ) || ( parent == null ) )
+ {
+ // nothing to do.
+ return;
+ }
+
+ if ( ( child.getVersion() == null ) && ( parent.getVersion() != null ) )
+ {
+ child.setVersion( parent.getVersion() );
+ }
+
+ // from here to the end of the method is dealing with merging of the <executions/> section.
+ String parentInherited = parent.getInherited();
+
+ boolean parentIsInherited = ( parentInherited == null ) || Boolean.valueOf( parentInherited );
+
+ List<ReportSet> parentReportSets = parent.getReportSets();
+
+ if ( ( parentReportSets != null ) && !parentReportSets.isEmpty() )
+ {
+ Map<String, ReportSet> assembledReportSets = new TreeMap<String, ReportSet>();
+
+ Map<String, ReportSet> childReportSets = child.getReportSetsAsMap();
+
+ for ( Object parentReportSet1 : parentReportSets )
+ {
+ ReportSet parentReportSet = (ReportSet) parentReportSet1;
+
+ if ( !handleAsInheritance || parentIsInherited )
+ {
+ ReportSet assembledReportSet = parentReportSet;
+
+ ReportSet childReportSet = childReportSets.get( parentReportSet.getId() );
+
+ if ( childReportSet != null )
+ {
+ mergeReportSetDefinitions( childReportSet, parentReportSet );
+
+ assembledReportSet = childReportSet;
+ }
+ else if ( handleAsInheritance && ( parentInherited == null ) )
+ {
+ parentReportSet.unsetInheritanceApplied();
+ }
+
+ assembledReportSets.put( assembledReportSet.getId(), assembledReportSet );
+ }
+ }
+
+ for ( Map.Entry<String, ReportSet> entry : childReportSets.entrySet() )
+ {
+ String id = entry.getKey();
+
+ if ( !assembledReportSets.containsKey( id ) )
+ {
+ assembledReportSets.put( id, entry.getValue() );
+ }
+ }
+
+ child.setReportSets( new ArrayList<ReportSet>( assembledReportSets.values() ) );
+
+ child.flushReportSetMap();
+ }
+
+ }
+
+ // TODO: Remove this!
+ @SuppressWarnings( "unchecked" )
+ private void assembleDependencyInheritance( Model child, Model parent )
+ {
+ Map<String, Dependency> depsMap = new LinkedHashMap<String, Dependency>();
+
+ List<Dependency> deps = parent.getDependencies();
+
+ if ( deps != null )
+ {
+ for ( Dependency dependency : deps )
+ {
+ depsMap.put( dependency.getManagementKey(), dependency );
+ }
+ }
+
+ deps = child.getDependencies();
+
+ if ( deps != null )
+ {
+ for ( Dependency dependency : deps )
+ {
+ depsMap.put( dependency.getManagementKey(), dependency );
+ }
+ }
+
+ child.setDependencies( new ArrayList<Dependency>( depsMap.values() ) );
+ }
+
+ private void assembleBuildInheritance( Model child, Model parent )
+ {
+ Build childBuild = child.getBuild();
+ Build parentBuild = parent.getBuild();
+
+ if ( parentBuild != null )
+ {
+ if ( childBuild == null )
+ {
+ childBuild = new Build();
+ child.setBuild( childBuild );
+ }
+
+ assembleBuildInheritance( childBuild, parentBuild, true );
+ }
+ }
+
+ private void assembleDistributionInheritence( Model child, Model parent, String childPathAdjustment,
+ boolean appendPaths )
+ {
+ if ( parent.getDistributionManagement() != null )
+ {
+ DistributionManagement parentDistMgmt = parent.getDistributionManagement();
+
+ DistributionManagement childDistMgmt = child.getDistributionManagement();
+
+ if ( childDistMgmt == null )
+ {
+ childDistMgmt = new DistributionManagement();
+
+ child.setDistributionManagement( childDistMgmt );
+ }
+
+ if ( childDistMgmt.getSite() == null )
+ {
+ if ( parentDistMgmt.getSite() != null )
+ {
+ Site site = new Site();
+
+ childDistMgmt.setSite( site );
+
+ site.setId( parentDistMgmt.getSite().getId() );
+
+ site.setName( parentDistMgmt.getSite().getName() );
+
+ site.setUrl( parentDistMgmt.getSite().getUrl() );
+
+ if ( site.getUrl() != null )
+ {
+ site.setUrl(
+ appendPath( site.getUrl(), child.getArtifactId(), childPathAdjustment, appendPaths ) );
+ }
+ }
+ }
+
+ if ( childDistMgmt.getRepository() == null )
+ {
+ if ( parentDistMgmt.getRepository() != null )
+ {
+ DeploymentRepository repository = copyDistributionRepository( parentDistMgmt.getRepository() );
+ childDistMgmt.setRepository( repository );
+ }
+ }
+
+ if ( childDistMgmt.getSnapshotRepository() == null )
+ {
+ if ( parentDistMgmt.getSnapshotRepository() != null )
+ {
+ DeploymentRepository repository =
+ copyDistributionRepository( parentDistMgmt.getSnapshotRepository() );
+ childDistMgmt.setSnapshotRepository( repository );
+ }
+ }
+
+ if ( StringUtils.isEmpty( childDistMgmt.getDownloadUrl() ) )
+ {
+ childDistMgmt.setDownloadUrl( parentDistMgmt.getDownloadUrl() );
+ }
+
+ // NOTE: We SHOULD NOT be inheriting status, since this is an assessment of the POM quality.
+ // NOTE: We SHOULD NOT be inheriting relocation, since this relates to a single POM
+ }
+ }
+
+ private static DeploymentRepository copyDistributionRepository( DeploymentRepository parentRepository )
+ {
+ DeploymentRepository repository = new DeploymentRepository();
+
+ repository.setId( parentRepository.getId() );
+
+ repository.setName( parentRepository.getName() );
+
+ repository.setUrl( parentRepository.getUrl() );
+
+ repository.setLayout( parentRepository.getLayout() );
+
+ repository.setUniqueVersion( parentRepository.isUniqueVersion() );
+
+ return repository;
+ }
+
+ // TODO: This should eventually be migrated to DefaultPathTranslator.
+ protected String appendPath( String parentPath, String childPath, String pathAdjustment, boolean appendPaths )
+ {
+ String uncleanPath = parentPath;
+
+ if ( appendPaths )
+ {
+ if ( pathAdjustment != null )
+ {
+ uncleanPath += "/" + pathAdjustment;
+ }
+
+ if ( childPath != null )
+ {
+ uncleanPath += "/" + childPath;
+ }
+ }
+
+ String cleanedPath = "";
+
+ int protocolIdx = uncleanPath.indexOf( "://" );
+
+ if ( protocolIdx > -1 )
+ {
+ cleanedPath = uncleanPath.substring( 0, protocolIdx + 3 );
+ uncleanPath = uncleanPath.substring( protocolIdx + 3 );
+ }
+
+ if ( uncleanPath.startsWith( "/" ) )
+ {
+ cleanedPath += "/";
+ }
+
+ return cleanedPath + resolvePath( uncleanPath );
+ }
+
+ // TODO: Move this to plexus-utils' PathTool.
+ private static String resolvePath( String uncleanPath )
+ {
+ LinkedList<String> pathElements = new LinkedList<String>();
+
+ StringTokenizer tokenizer = new StringTokenizer( uncleanPath, "/" );
+
+ while ( tokenizer.hasMoreTokens() )
+ {
+ String token = tokenizer.nextToken();
+
+ if ( token.equals( "" ) )
+ {
+ // Empty path entry ("...//.."), remove.
+ }
+ else if ( token.equals( ".." ) )
+ {
+ if ( pathElements.isEmpty() )
+ {
+ // FIXME: somehow report to the user
+ // that there are too many '..' elements.
+ // For now, ignore the extra '..'.
+ }
+ else
+ {
+ pathElements.removeLast();
+ }
+ }
+ else
+ {
+ pathElements.addLast( token );
+ }
+ }
+
+ StringBuilder cleanedPath = new StringBuilder();
+
+ while ( !pathElements.isEmpty() )
+ {
+ cleanedPath.append( pathElements.removeFirst() );
+ if ( !pathElements.isEmpty() )
+ {
+ cleanedPath.append( '/' );
+ }
+ }
+
+ return cleanedPath.toString();
+ }
+
+ private static void mergeExtensionLists( Build childBuild, Build parentBuild )
+ {
+ for ( Extension e : parentBuild.getExtensions() )
+ {
+ if ( !childBuild.getExtensions().contains( e ) )
+ {
+ childBuild.addExtension( e );
+ }
+ }
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/project/inheritance/ModelInheritanceAssembler.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/project/inheritance/ModelInheritanceAssembler.java
new file mode 100644
index 00000000..ef4edca5
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/project/inheritance/ModelInheritanceAssembler.java
@@ -0,0 +1,41 @@
+package org.apache.maven.project.inheritance;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.model.Build;
+import org.apache.maven.model.Model;
+
+/**
+ * @author Jason van Zyl
+ * @deprecated
+ */
+@Deprecated
+public interface ModelInheritanceAssembler
+{
+ String ROLE = ModelInheritanceAssembler.class.getName();
+
+ void assembleModelInheritance( Model child, Model parent, String childPathAdjustment );
+
+ void assembleModelInheritance( Model child, Model parent );
+
+ void assembleBuildInheritance( Build childBuild, Build parentBuild, boolean handleAsInheriance );
+
+ void copyModel( Model dest, Model source );
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/project/interpolation/AbstractStringBasedModelInterpolator.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/project/interpolation/AbstractStringBasedModelInterpolator.java
new file mode 100644
index 00000000..dfc3deec
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/project/interpolation/AbstractStringBasedModelInterpolator.java
@@ -0,0 +1,407 @@
+package org.apache.maven.project.interpolation;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.model.Model;
+import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
+import org.apache.maven.model.io.xpp3.MavenXpp3Writer;
+import org.apache.maven.project.DefaultProjectBuilderConfiguration;
+import org.apache.maven.project.ProjectBuilderConfiguration;
+import org.apache.maven.project.path.PathTranslator;
+import org.codehaus.plexus.component.annotations.Requirement;
+import org.codehaus.plexus.interpolation.AbstractValueSource;
+import org.codehaus.plexus.interpolation.InterpolationException;
+import org.codehaus.plexus.interpolation.InterpolationPostProcessor;
+import org.codehaus.plexus.interpolation.Interpolator;
+import org.codehaus.plexus.interpolation.MapBasedValueSource;
+import org.codehaus.plexus.interpolation.ObjectBasedValueSource;
+import org.codehaus.plexus.interpolation.PrefixAwareRecursionInterceptor;
+import org.codehaus.plexus.interpolation.PrefixedObjectValueSource;
+import org.codehaus.plexus.interpolation.PrefixedValueSourceWrapper;
+import org.codehaus.plexus.interpolation.RecursionInterceptor;
+import org.codehaus.plexus.interpolation.ValueSource;
+import org.codehaus.plexus.logging.AbstractLogEnabled;
+import org.codehaus.plexus.logging.Logger;
+import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable;
+import org.codehaus.plexus.personality.plexus.lifecycle.phase.InitializationException;
+import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+/**
+ * Use a regular expression search to find and resolve expressions within the POM.
+ *
+ * @author jdcasey Created on Feb 3, 2005
+ * @todo Consolidate this logic with the PluginParameterExpressionEvaluator, minus deprecations/bans.
+ */
+@Deprecated
+public abstract class AbstractStringBasedModelInterpolator
+ extends AbstractLogEnabled
+ implements ModelInterpolator, Initializable
+{
+ private static final List<String> PROJECT_PREFIXES = Arrays.asList( "pom.", "project." );
+
+ private static final List<String> TRANSLATED_PATH_EXPRESSIONS;
+
+ static
+ {
+ List<String> translatedPrefixes = new ArrayList<String>();
+
+ // MNG-1927, MNG-2124, MNG-3355:
+ // If the build section is present and the project directory is non-null, we should make
+ // sure interpolation of the directories below uses translated paths.
+ // Afterward, we'll double back and translate any paths that weren't covered during interpolation via the
+ // code below...
+ translatedPrefixes.add( "build.directory" );
+ translatedPrefixes.add( "build.outputDirectory" );
+ translatedPrefixes.add( "build.testOutputDirectory" );
+ translatedPrefixes.add( "build.sourceDirectory" );
+ translatedPrefixes.add( "build.testSourceDirectory" );
+ translatedPrefixes.add( "build.scriptSourceDirectory" );
+ translatedPrefixes.add( "reporting.outputDirectory" );
+
+ TRANSLATED_PATH_EXPRESSIONS = translatedPrefixes;
+ }
+
+ @Requirement
+ private PathTranslator pathTranslator;
+
+ private Interpolator interpolator;
+
+ private RecursionInterceptor recursionInterceptor;
+
+ // for testing.
+ protected AbstractStringBasedModelInterpolator( PathTranslator pathTranslator )
+ {
+ this.pathTranslator = pathTranslator;
+ }
+
+ /**
+ * @todo: Remove the throws clause.
+ * @throws IOException This exception is not thrown any more, and needs to be removed.
+ */
+ protected AbstractStringBasedModelInterpolator()
+ {
+ }
+
+ public Model interpolate( Model model, Map<String, ?> context )
+ throws ModelInterpolationException
+ {
+ return interpolate( model, context, true );
+ }
+
+ /**
+ * Serialize the inbound Model instance to a StringWriter, perform the regex replacement to resolve
+ * POM expressions, then re-parse into the resolved Model instance.
+ * <br/>
+ * <b>NOTE:</b> This will result in a different instance of Model being returned!!!
+ *
+ * @param model The inbound Model instance, to serialize and reference for expression resolution
+ * @param context The other context map to be used during resolution
+ * @return The resolved instance of the inbound Model. This is a different instance!
+ *
+ * @deprecated Use {@link ModelInterpolator#interpolate(Model, File, ProjectBuilderConfiguration, boolean)} instead.
+ */
+ public Model interpolate( Model model, Map<String, ?> context, boolean strict )
+ throws ModelInterpolationException
+ {
+ Properties props = new Properties();
+ props.putAll( context );
+
+ return interpolate( model,
+ null,
+ new DefaultProjectBuilderConfiguration().setExecutionProperties( props ),
+ true );
+ }
+
+ public Model interpolate( Model model,
+ File projectDir,
+ ProjectBuilderConfiguration config,
+ boolean debugEnabled )
+ throws ModelInterpolationException
+ {
+ StringWriter sWriter = new StringWriter( 1024 );
+
+ MavenXpp3Writer writer = new MavenXpp3Writer();
+ try
+ {
+ writer.write( sWriter, model );
+ }
+ catch ( IOException e )
+ {
+ throw new ModelInterpolationException( "Cannot serialize project model for interpolation.", e );
+ }
+
+ String serializedModel = sWriter.toString();
+ serializedModel = interpolate( serializedModel, model, projectDir, config, debugEnabled );
+
+ StringReader sReader = new StringReader( serializedModel );
+
+ MavenXpp3Reader modelReader = new MavenXpp3Reader();
+ try
+ {
+ model = modelReader.read( sReader );
+ }
+ catch ( IOException e )
+ {
+ throw new ModelInterpolationException(
+ "Cannot read project model from interpolating filter of serialized version.", e );
+ }
+ catch ( XmlPullParserException e )
+ {
+ throw new ModelInterpolationException(
+ "Cannot read project model from interpolating filter of serialized version.", e );
+ }
+
+ return model;
+ }
+
+ /**
+ * Interpolates all expressions in the src parameter.
+ * <p>
+ * The algorithm used for each expression is:
+ * <ul>
+ * <li>If it starts with either "pom." or "project.", the expression is evaluated against the model.</li>
+ * <li>If the value is null, get the value from the context.</li>
+ * <li>If the value is null, but the context contains the expression, don't replace the expression string
+ * with the value, and continue to find other expressions.</li>
+ * <li>If the value is null, get it from the model properties.</li>
+ * <li>
+ * @param overrideContext
+ * @param outputDebugMessages
+ */
+ public String interpolate( String src,
+ Model model,
+ final File projectDir,
+ ProjectBuilderConfiguration config,
+ boolean debug )
+ throws ModelInterpolationException
+ {
+ try
+ {
+ List<ValueSource> valueSources = createValueSources( model, projectDir, config );
+ List<InterpolationPostProcessor> postProcessors = createPostProcessors( model, projectDir, config );
+
+ return interpolateInternal( src, valueSources, postProcessors, debug );
+ }
+ finally
+ {
+ interpolator.clearAnswers();
+ }
+ }
+
+ protected List<ValueSource> createValueSources( final Model model, final File projectDir,
+ final ProjectBuilderConfiguration config )
+ {
+ String timestampFormat = DEFAULT_BUILD_TIMESTAMP_FORMAT;
+
+ Properties modelProperties = model.getProperties();
+ if ( modelProperties != null )
+ {
+ timestampFormat = modelProperties.getProperty( BUILD_TIMESTAMP_FORMAT_PROPERTY, timestampFormat );
+ }
+
+ ValueSource modelValueSource1 = new PrefixedObjectValueSource( PROJECT_PREFIXES, model, false );
+ ValueSource modelValueSource2 = new ObjectBasedValueSource( model );
+
+ ValueSource basedirValueSource = new PrefixedValueSourceWrapper( new AbstractValueSource( false )
+ {
+ public Object getValue( String expression )
+ {
+ if ( projectDir != null && "basedir".equals( expression ) )
+ {
+ return projectDir.getAbsolutePath();
+ }
+ return null;
+ }
+ }, PROJECT_PREFIXES, true );
+ ValueSource baseUriValueSource = new PrefixedValueSourceWrapper( new AbstractValueSource( false )
+ {
+ public Object getValue( String expression )
+ {
+ if ( projectDir != null && "baseUri".equals( expression ) )
+ {
+ return projectDir.getAbsoluteFile().toURI().toString();
+ }
+ return null;
+ }
+ }, PROJECT_PREFIXES, false );
+
+ List<ValueSource> valueSources = new ArrayList<ValueSource>( 9 );
+
+ // NOTE: Order counts here!
+ valueSources.add( basedirValueSource );
+ valueSources.add( baseUriValueSource );
+ valueSources.add( new BuildTimestampValueSource( config.getBuildStartTime(), timestampFormat ) );
+ valueSources.add( modelValueSource1 );
+ valueSources.add( new MapBasedValueSource( config.getUserProperties() ) );
+ valueSources.add( new MapBasedValueSource( modelProperties ) );
+ valueSources.add( new MapBasedValueSource( config.getExecutionProperties() ) );
+ valueSources.add( new AbstractValueSource( false )
+ {
+ public Object getValue( String expression )
+ {
+ return config.getExecutionProperties().getProperty( "env." + expression );
+ }
+ } );
+ valueSources.add( modelValueSource2 );
+
+ return valueSources;
+ }
+
+ protected List<InterpolationPostProcessor> createPostProcessors( final Model model, final File projectDir,
+ final ProjectBuilderConfiguration config )
+ {
+ return Collections.singletonList( (InterpolationPostProcessor) new PathTranslatingPostProcessor(
+ PROJECT_PREFIXES,
+ TRANSLATED_PATH_EXPRESSIONS,
+ projectDir,
+ pathTranslator ) );
+ }
+
+ @SuppressWarnings( "unchecked" )
+ protected String interpolateInternal( String src, List<ValueSource> valueSources,
+ List<InterpolationPostProcessor> postProcessors, boolean debug )
+ throws ModelInterpolationException
+ {
+ if ( !src.contains( "${" ) )
+ {
+ return src;
+ }
+
+ Logger logger = getLogger();
+
+ String result = src;
+ synchronized ( this )
+ {
+
+ for ( ValueSource vs : valueSources )
+ {
+ interpolator.addValueSource( vs );
+ }
+
+ for ( InterpolationPostProcessor postProcessor : postProcessors )
+ {
+ interpolator.addPostProcessor( postProcessor );
+ }
+
+ try
+ {
+ try
+ {
+ result = interpolator.interpolate( result, recursionInterceptor );
+ }
+ catch ( InterpolationException e )
+ {
+ throw new ModelInterpolationException( e.getMessage(), e );
+ }
+
+ if ( debug )
+ {
+ List<Object> feedback = interpolator.getFeedback();
+ if ( feedback != null && !feedback.isEmpty() )
+ {
+ logger.debug( "Maven encountered the following problems during initial POM interpolation:" );
+
+ Object last = null;
+ for ( Object next : feedback )
+ {
+ if ( next instanceof Throwable )
+ {
+ if ( last == null )
+ {
+ logger.debug( "", ( (Throwable) next ) );
+ }
+ else
+ {
+ logger.debug( String.valueOf( last ), ( (Throwable) next ) );
+ }
+ }
+ else
+ {
+ if ( last != null )
+ {
+ logger.debug( String.valueOf( last ) );
+ }
+
+ last = next;
+ }
+ }
+
+ if ( last != null )
+ {
+ logger.debug( String.valueOf( last ) );
+ }
+ }
+ }
+
+ interpolator.clearFeedback();
+ }
+ finally
+ {
+ for ( ValueSource vs : valueSources )
+ {
+ interpolator.removeValuesSource( vs );
+ }
+
+ for ( InterpolationPostProcessor postProcessor : postProcessors )
+ {
+ interpolator.removePostProcessor( postProcessor );
+ }
+ }
+ }
+
+ return result;
+ }
+
+ protected RecursionInterceptor getRecursionInterceptor()
+ {
+ return recursionInterceptor;
+ }
+
+ protected void setRecursionInterceptor( RecursionInterceptor recursionInterceptor )
+ {
+ this.recursionInterceptor = recursionInterceptor;
+ }
+
+ protected abstract Interpolator createInterpolator();
+
+ public void initialize()
+ throws InitializationException
+ {
+ interpolator = createInterpolator();
+ recursionInterceptor = new PrefixAwareRecursionInterceptor( PROJECT_PREFIXES );
+ }
+
+ protected final Interpolator getInterpolator()
+ {
+ return interpolator;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/project/interpolation/BuildTimestampValueSource.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/project/interpolation/BuildTimestampValueSource.java
new file mode 100644
index 00000000..f6319fa6
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/project/interpolation/BuildTimestampValueSource.java
@@ -0,0 +1,63 @@
+package org.apache.maven.project.interpolation;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import org.codehaus.plexus.interpolation.AbstractValueSource;
+
+/**
+ *
+ */
+@Deprecated
+public class BuildTimestampValueSource
+ extends AbstractValueSource
+{
+
+ private final Date startTime;
+
+ private final String format;
+
+ private String formattedDate;
+
+ public BuildTimestampValueSource( Date startTime, String format )
+ {
+ super( false );
+ this.startTime = startTime;
+ this.format = format;
+ }
+
+ public Object getValue( String expression )
+ {
+ if ( "build.timestamp".equals( expression ) || "maven.build.timestamp".equals( expression ) )
+ {
+ if ( formattedDate == null && startTime != null )
+ {
+ formattedDate = new SimpleDateFormat( format ).format( startTime );
+ }
+
+ return formattedDate;
+ }
+
+ return null;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/project/interpolation/ModelInterpolationException.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/project/interpolation/ModelInterpolationException.java
new file mode 100644
index 00000000..5b02880b
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/project/interpolation/ModelInterpolationException.java
@@ -0,0 +1,72 @@
+package org.apache.maven.project.interpolation;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * @author jdcasey
+ * <p/>
+ * Created on Feb 2, 2005
+ */
+@SuppressWarnings( "serial" )
+@Deprecated
+public class ModelInterpolationException
+ extends Exception
+{
+ private String expression;
+
+ private String originalMessage;
+
+ public ModelInterpolationException( String message )
+ {
+ super( message );
+ }
+
+ public ModelInterpolationException( String message, Throwable cause )
+ {
+ super( message, cause );
+ }
+
+ public ModelInterpolationException( String expression, String message, Throwable cause )
+ {
+ super( "The POM expression: " + expression + " could not be evaluated. Reason: " + message, cause );
+
+ this.expression = expression;
+ this.originalMessage = message;
+ }
+
+ public ModelInterpolationException( String expression, String message )
+ {
+ super( "The POM expression: " + expression + " could not be evaluated. Reason: " + message );
+
+ this.expression = expression;
+ this.originalMessage = message;
+ }
+
+ public String getExpression()
+ {
+ return expression;
+ }
+
+ public String getOriginalMessage()
+ {
+ return originalMessage;
+ }
+
+} \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/project/interpolation/ModelInterpolator.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/project/interpolation/ModelInterpolator.java
new file mode 100644
index 00000000..e1556eaf
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/project/interpolation/ModelInterpolator.java
@@ -0,0 +1,66 @@
+package org.apache.maven.project.interpolation;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.model.Model;
+import org.apache.maven.project.ProjectBuilderConfiguration;
+
+import java.io.File;
+import java.util.Map;
+
+/**
+ * @author jdcasey
+ * <p/>
+ * Created on Feb 2, 2005
+ */
+@Deprecated
+public interface ModelInterpolator
+{
+ String DEFAULT_BUILD_TIMESTAMP_FORMAT = "yyyyMMdd-HHmm";
+
+ String BUILD_TIMESTAMP_FORMAT_PROPERTY = "maven.build.timestamp.format";
+
+ String ROLE = ModelInterpolator.class.getName();
+
+ /**
+ * @deprecated Use {@link ModelInterpolator#interpolate(Model, File, ProjectBuilderConfiguration, boolean)} instead.
+ */
+ Model interpolate( Model project, Map<String, ?> context )
+ throws ModelInterpolationException;
+
+ /**
+ * @deprecated Use {@link ModelInterpolator#interpolate(Model, File, ProjectBuilderConfiguration, boolean)} instead.
+ */
+ Model interpolate( Model model, Map<String, ?> context, boolean strict )
+ throws ModelInterpolationException;
+
+ Model interpolate( Model model,
+ File projectDir,
+ ProjectBuilderConfiguration config,
+ boolean debugEnabled )
+ throws ModelInterpolationException;
+
+ String interpolate( String src,
+ Model model,
+ File projectDir,
+ ProjectBuilderConfiguration config,
+ boolean debugEnabled )
+ throws ModelInterpolationException;
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/project/interpolation/PathTranslatingPostProcessor.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/project/interpolation/PathTranslatingPostProcessor.java
new file mode 100644
index 00000000..da2ba056
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/project/interpolation/PathTranslatingPostProcessor.java
@@ -0,0 +1,64 @@
+package org.apache.maven.project.interpolation;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.project.path.PathTranslator;
+import org.codehaus.plexus.interpolation.InterpolationPostProcessor;
+import org.codehaus.plexus.interpolation.util.ValueSourceUtils;
+
+import java.io.File;
+import java.util.List;
+
+/**
+ *
+ */
+@Deprecated
+public class PathTranslatingPostProcessor
+ implements InterpolationPostProcessor
+{
+
+ private final List<String> unprefixedPathKeys;
+ private final File projectDir;
+ private final PathTranslator pathTranslator;
+ private final List<String> expressionPrefixes;
+
+ public PathTranslatingPostProcessor( List<String> expressionPrefixes, List<String> unprefixedPathKeys,
+ File projectDir, PathTranslator pathTranslator )
+ {
+ this.expressionPrefixes = expressionPrefixes;
+ this.unprefixedPathKeys = unprefixedPathKeys;
+ this.projectDir = projectDir;
+ this.pathTranslator = pathTranslator;
+ }
+
+ public Object execute( String expression,
+ Object value )
+ {
+ expression = ValueSourceUtils.trimPrefix( expression, expressionPrefixes, true );
+
+ if ( projectDir != null && value != null && unprefixedPathKeys.contains( expression ) )
+ {
+ return pathTranslator.alignToBaseDirectory( String.valueOf( value ), projectDir );
+ }
+
+ return value;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/project/interpolation/RegexBasedModelInterpolator.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/project/interpolation/RegexBasedModelInterpolator.java
new file mode 100644
index 00000000..4e251aee
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/project/interpolation/RegexBasedModelInterpolator.java
@@ -0,0 +1,58 @@
+package org.apache.maven.project.interpolation;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.IOException;
+import java.util.Properties;
+
+import org.apache.maven.project.path.PathTranslator;
+import org.codehaus.plexus.interpolation.Interpolator;
+import org.codehaus.plexus.interpolation.RegexBasedInterpolator;
+
+/**
+ * Use a regular expression search to find and resolve expressions within the POM.
+ *
+ * @author jdcasey Created on Feb 3, 2005
+ * @todo Consolidate this logic with the PluginParameterExpressionEvaluator, minus deprecations/bans.
+ */
+@Deprecated
+public class RegexBasedModelInterpolator
+ extends AbstractStringBasedModelInterpolator
+{
+
+ public RegexBasedModelInterpolator()
+ throws IOException
+ {
+ }
+
+ public RegexBasedModelInterpolator( PathTranslator pathTranslator )
+ {
+ super( pathTranslator );
+ }
+
+ public RegexBasedModelInterpolator( Properties envars )
+ {
+ }
+
+ protected Interpolator createInterpolator()
+ {
+ return new RegexBasedInterpolator( true );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/project/interpolation/StringSearchModelInterpolator.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/project/interpolation/StringSearchModelInterpolator.java
new file mode 100644
index 00000000..864f57f0
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/project/interpolation/StringSearchModelInterpolator.java
@@ -0,0 +1,410 @@
+package org.apache.maven.project.interpolation;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.model.Model;
+import org.apache.maven.project.ProjectBuilderConfiguration;
+import org.apache.maven.project.path.PathTranslator;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.interpolation.InterpolationPostProcessor;
+import org.codehaus.plexus.interpolation.Interpolator;
+import org.codehaus.plexus.interpolation.StringSearchInterpolator;
+import org.codehaus.plexus.interpolation.ValueSource;
+import org.codehaus.plexus.logging.Logger;
+
+import java.io.File;
+import java.lang.reflect.Array;
+import java.lang.reflect.Field;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.WeakHashMap;
+
+@Deprecated
+@Component( role = ModelInterpolator.class )
+public class StringSearchModelInterpolator
+ extends AbstractStringBasedModelInterpolator
+{
+
+ private static final Map<Class<?>, Field[]> fieldsByClass = new WeakHashMap<Class<?>, Field[]>();
+ private static final Map<Class<?>, Boolean> fieldIsPrimitiveByClass = new WeakHashMap<Class<?>, Boolean>();
+
+ public StringSearchModelInterpolator()
+ {
+ }
+
+ public StringSearchModelInterpolator( PathTranslator pathTranslator )
+ {
+ super( pathTranslator );
+ }
+
+ public Model interpolate( Model model, File projectDir, ProjectBuilderConfiguration config, boolean debugEnabled )
+ throws ModelInterpolationException
+ {
+ interpolateObject( model, model, projectDir, config, debugEnabled );
+
+ return model;
+ }
+
+ protected void interpolateObject( Object obj, Model model, File projectDir, ProjectBuilderConfiguration config,
+ boolean debugEnabled )
+ throws ModelInterpolationException
+ {
+ try
+ {
+ List<ValueSource> valueSources = createValueSources( model, projectDir, config );
+ List<InterpolationPostProcessor> postProcessors = createPostProcessors( model, projectDir, config );
+
+ InterpolateObjectAction action =
+ new InterpolateObjectAction( obj, valueSources, postProcessors, debugEnabled,
+ this, getLogger() );
+
+ ModelInterpolationException error = AccessController.doPrivileged( action );
+
+ if ( error != null )
+ {
+ throw error;
+ }
+ }
+ finally
+ {
+ getInterpolator().clearAnswers();
+ }
+ }
+
+ protected Interpolator createInterpolator()
+ {
+ StringSearchInterpolator interpolator = new StringSearchInterpolator();
+ interpolator.setCacheAnswers( true );
+
+ return interpolator;
+ }
+
+ private static final class InterpolateObjectAction implements PrivilegedAction<ModelInterpolationException>
+ {
+
+ private final boolean debugEnabled;
+ private final LinkedList<Object> interpolationTargets;
+ private final StringSearchModelInterpolator modelInterpolator;
+ private final Logger logger;
+ private final List<ValueSource> valueSources;
+ private final List<InterpolationPostProcessor> postProcessors;
+
+ public InterpolateObjectAction( Object target, List<ValueSource> valueSources,
+ List<InterpolationPostProcessor> postProcessors, boolean debugEnabled,
+ StringSearchModelInterpolator modelInterpolator, Logger logger )
+ {
+ this.valueSources = valueSources;
+ this.postProcessors = postProcessors;
+ this.debugEnabled = debugEnabled;
+
+ this.interpolationTargets = new LinkedList<Object>();
+ interpolationTargets.add( target );
+
+ this.modelInterpolator = modelInterpolator;
+ this.logger = logger;
+ }
+
+ public ModelInterpolationException run()
+ {
+ while ( !interpolationTargets.isEmpty() )
+ {
+ Object obj = interpolationTargets.removeFirst();
+
+ try
+ {
+ traverseObjectWithParents( obj.getClass(), obj );
+ }
+ catch ( ModelInterpolationException e )
+ {
+ return e;
+ }
+ }
+
+ return null;
+ }
+
+ @SuppressWarnings( "unchecked" )
+ private void traverseObjectWithParents( Class<?> cls, Object target )
+ throws ModelInterpolationException
+ {
+ if ( cls == null )
+ {
+ return;
+ }
+
+
+ if ( cls.isArray() )
+ {
+ evaluateArray( target );
+ }
+ else if ( isQualifiedForInterpolation( cls ) )
+ {
+ Field[] fields = fieldsByClass.get( cls );
+ if ( fields == null )
+ {
+ fields = cls.getDeclaredFields();
+ fieldsByClass.put( cls, fields );
+ }
+
+ for ( Field field : fields )
+ {
+ Class<?> type = field.getType();
+ if ( isQualifiedForInterpolation( field, type ) )
+ {
+ boolean isAccessible = field.isAccessible();
+ field.setAccessible( true );
+ try
+ {
+ try
+ {
+ if ( String.class == type )
+ {
+ String value = (String) field.get( target );
+ if ( value != null )
+ {
+ String interpolated =
+ modelInterpolator.interpolateInternal( value, valueSources, postProcessors,
+ debugEnabled );
+
+ if ( !interpolated.equals( value ) )
+ {
+ field.set( target, interpolated );
+ }
+ }
+ }
+ else if ( Collection.class.isAssignableFrom( type ) )
+ {
+ Collection<Object> c = (Collection<Object>) field.get( target );
+ if ( c != null && !c.isEmpty() )
+ {
+ List<Object> originalValues = new ArrayList<Object>( c );
+ try
+ {
+ c.clear();
+ }
+ catch ( UnsupportedOperationException e )
+ {
+ if ( debugEnabled && logger != null )
+ {
+ logger.debug( "Skipping interpolation of field: " + field + " in: "
+ + cls.getName()
+ + "; it is an unmodifiable collection." );
+ }
+ continue;
+ }
+
+ for ( Object value : originalValues )
+ {
+ if ( value != null )
+ {
+ if ( String.class == value.getClass() )
+ {
+ String interpolated =
+ modelInterpolator.interpolateInternal( (String) value,
+ valueSources,
+ postProcessors,
+ debugEnabled );
+
+ if ( !interpolated.equals( value ) )
+ {
+ c.add( interpolated );
+ }
+ else
+ {
+ c.add( value );
+ }
+ }
+ else
+ {
+ c.add( value );
+ if ( value.getClass().isArray() )
+ {
+ evaluateArray( value );
+ }
+ else
+ {
+ interpolationTargets.add( value );
+ }
+ }
+ }
+ else
+ {
+ // add the null back in...not sure what else to do...
+ c.add( value );
+ }
+ }
+ }
+ }
+ else if ( Map.class.isAssignableFrom( type ) )
+ {
+ Map<Object, Object> m = (Map<Object, Object>) field.get( target );
+ if ( m != null && !m.isEmpty() )
+ {
+ for ( Map.Entry<Object, Object> entry : m.entrySet() )
+ {
+ Object value = entry.getValue();
+
+ if ( value != null )
+ {
+ if ( String.class == value.getClass() )
+ {
+ String interpolated =
+ modelInterpolator.interpolateInternal( (String) value,
+ valueSources,
+ postProcessors,
+ debugEnabled );
+
+ if ( !interpolated.equals( value ) )
+ {
+ try
+ {
+ entry.setValue( interpolated );
+ }
+ catch ( UnsupportedOperationException e )
+ {
+ if ( debugEnabled && logger != null )
+ {
+ logger.debug(
+ "Skipping interpolation of field: " + field
+ + " (key: " + entry.getKey() + ") in: "
+ + cls.getName()
+ + "; it is an unmodifiable collection." );
+ }
+ }
+ }
+ }
+ else
+ {
+ if ( value.getClass().isArray() )
+ {
+ evaluateArray( value );
+ }
+ else
+ {
+ interpolationTargets.add( value );
+ }
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ Object value = field.get( target );
+ if ( value != null )
+ {
+ if ( field.getType().isArray() )
+ {
+ evaluateArray( value );
+ }
+ else
+ {
+ interpolationTargets.add( value );
+ }
+ }
+ }
+ }
+ catch ( IllegalArgumentException e )
+ {
+ throw new ModelInterpolationException(
+ "Failed to interpolate field: " + field + " on class: " + cls.getName(), e );
+ }
+ catch ( IllegalAccessException e )
+ {
+ throw new ModelInterpolationException(
+ "Failed to interpolate field: " + field + " on class: " + cls.getName(), e );
+ }
+ }
+ finally
+ {
+ field.setAccessible( isAccessible );
+ }
+ }
+ }
+
+ traverseObjectWithParents( cls.getSuperclass(), target );
+ }
+ }
+
+ private boolean isQualifiedForInterpolation( Class<?> cls )
+ {
+ return !cls.getPackage().getName().startsWith( "java" );
+ }
+
+ private boolean isQualifiedForInterpolation( Field field, Class<?> fieldType )
+ {
+ if ( !fieldIsPrimitiveByClass.containsKey( fieldType ) )
+ {
+ fieldIsPrimitiveByClass.put( fieldType, fieldType.isPrimitive() );
+ }
+
+ if ( fieldIsPrimitiveByClass.get( fieldType ) )
+ {
+ return false;
+ }
+
+// if ( fieldType.isPrimitive() )
+// {
+// return false;
+// }
+
+ if ( "parent".equals( field.getName() ) )
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ private void evaluateArray( Object target )
+ throws ModelInterpolationException
+ {
+ int len = Array.getLength( target );
+ for ( int i = 0; i < len; i++ )
+ {
+ Object value = Array.get( target, i );
+ if ( value != null )
+ {
+ if ( String.class == value.getClass() )
+ {
+ String interpolated =
+ modelInterpolator.interpolateInternal( (String) value, valueSources, postProcessors,
+ debugEnabled );
+
+ if ( !interpolated.equals( value ) )
+ {
+ Array.set( target, i, interpolated );
+ }
+ }
+ else
+ {
+ interpolationTargets.add( value );
+ }
+ }
+ }
+ }
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/project/path/DefaultPathTranslator.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/project/path/DefaultPathTranslator.java
new file mode 100644
index 00000000..ece7c397
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/project/path/DefaultPathTranslator.java
@@ -0,0 +1,261 @@
+package org.apache.maven.project.path;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.maven.model.Build;
+import org.apache.maven.model.Model;
+import org.apache.maven.model.Reporting;
+import org.apache.maven.model.Resource;
+import org.codehaus.plexus.component.annotations.Component;
+
+@Deprecated
+@Component( role = PathTranslator.class )
+public class DefaultPathTranslator
+ implements PathTranslator
+{
+ private static final String[] BASEDIR_EXPRESSIONS = {"${basedir}", "${pom.basedir}", "${project.basedir}"};
+
+ public void alignToBaseDirectory( Model model, File basedir )
+ {
+ if ( basedir == null )
+ {
+ return;
+ }
+
+ Build build = model.getBuild();
+
+ if ( build != null )
+ {
+ build.setDirectory( alignToBaseDirectory( build.getDirectory(), basedir ) );
+
+ build.setSourceDirectory( alignToBaseDirectory( build.getSourceDirectory(), basedir ) );
+
+ build.setTestSourceDirectory( alignToBaseDirectory( build.getTestSourceDirectory(), basedir ) );
+
+ for ( Resource resource : build.getResources() )
+ {
+ resource.setDirectory( alignToBaseDirectory( resource.getDirectory(), basedir ) );
+ }
+
+ for ( Resource resource : build.getTestResources() )
+ {
+ resource.setDirectory( alignToBaseDirectory( resource.getDirectory(), basedir ) );
+ }
+
+ if ( build.getFilters() != null )
+ {
+ List<String> filters = new ArrayList<String>();
+ for ( String filter : build.getFilters() )
+ {
+ filters.add( alignToBaseDirectory( filter, basedir ) );
+ }
+ build.setFilters( filters );
+ }
+
+ build.setOutputDirectory( alignToBaseDirectory( build.getOutputDirectory(), basedir ) );
+
+ build.setTestOutputDirectory( alignToBaseDirectory( build.getTestOutputDirectory(), basedir ) );
+ }
+
+ Reporting reporting = model.getReporting();
+
+ if ( reporting != null )
+ {
+ reporting.setOutputDirectory( alignToBaseDirectory( reporting.getOutputDirectory(), basedir ) );
+ }
+ }
+
+ public String alignToBaseDirectory( String path, File basedir )
+ {
+ if ( basedir == null )
+ {
+ return path;
+ }
+
+ if ( path == null )
+ {
+ return null;
+ }
+
+ String s = stripBasedirToken( path );
+
+ File file = new File( s );
+ if ( file.isAbsolute() )
+ {
+ // path was already absolute, just normalize file separator and we're done
+ s = file.getPath();
+ }
+ else if ( file.getPath().startsWith( File.separator ) )
+ {
+ // drive-relative Windows path, don't align with project directory but with drive root
+ s = file.getAbsolutePath();
+ }
+ else
+ {
+ // an ordinary relative path, align with project directory
+ s = new File( new File( basedir, s ).toURI().normalize() ).getAbsolutePath();
+ }
+
+ return s;
+ }
+
+ private String stripBasedirToken( String s )
+ {
+ if ( s != null )
+ {
+ String basedirExpr = null;
+ for ( String BASEDIR_EXPRESSION : BASEDIR_EXPRESSIONS )
+ {
+ basedirExpr = BASEDIR_EXPRESSION;
+ if ( s.startsWith( basedirExpr ) )
+ {
+ break;
+ }
+ else
+ {
+ basedirExpr = null;
+ }
+ }
+
+ if ( basedirExpr != null )
+ {
+ if ( s.length() > basedirExpr.length() )
+ {
+ // Take out basedir expression and the leading slash
+ s = chopLeadingFileSeparator( s.substring( basedirExpr.length() ) );
+ }
+ else
+ {
+ s = ".";
+ }
+ }
+ }
+
+ return s;
+ }
+
+ /**
+ * Removes the leading directory separator from the specified filesystem path (if any). For platform-independent
+ * behavior, this method accepts both the forward slash and the backward slash as separator.
+ *
+ * @param path The filesystem path, may be <code>null</code>.
+ * @return The altered filesystem path or <code>null</code> if the input path was <code>null</code>.
+ */
+ private String chopLeadingFileSeparator( String path )
+ {
+ if ( path != null )
+ {
+ if ( path.startsWith( "/" ) || path.startsWith( "\\" ) )
+ {
+ path = path.substring( 1 );
+ }
+ }
+ return path;
+ }
+
+ public void unalignFromBaseDirectory( Model model, File basedir )
+ {
+ if ( basedir == null )
+ {
+ return;
+ }
+
+ Build build = model.getBuild();
+
+ if ( build != null )
+ {
+ build.setDirectory( unalignFromBaseDirectory( build.getDirectory(), basedir ) );
+
+ build.setSourceDirectory( unalignFromBaseDirectory( build.getSourceDirectory(), basedir ) );
+
+ build.setTestSourceDirectory( unalignFromBaseDirectory( build.getTestSourceDirectory(), basedir ) );
+
+ for ( Resource resource : build.getResources() )
+ {
+ resource.setDirectory( unalignFromBaseDirectory( resource.getDirectory(), basedir ) );
+ }
+
+ for ( Resource resource : build.getTestResources() )
+ {
+ resource.setDirectory( unalignFromBaseDirectory( resource.getDirectory(), basedir ) );
+ }
+
+ if ( build.getFilters() != null )
+ {
+ List<String> filters = new ArrayList<String>();
+ for ( String filter : build.getFilters() )
+ {
+ filters.add( unalignFromBaseDirectory( filter, basedir ) );
+ }
+ build.setFilters( filters );
+ }
+
+ build.setOutputDirectory( unalignFromBaseDirectory( build.getOutputDirectory(), basedir ) );
+
+ build.setTestOutputDirectory( unalignFromBaseDirectory( build.getTestOutputDirectory(), basedir ) );
+ }
+
+ Reporting reporting = model.getReporting();
+
+ if ( reporting != null )
+ {
+ reporting.setOutputDirectory( unalignFromBaseDirectory( reporting.getOutputDirectory(), basedir ) );
+ }
+ }
+
+ public String unalignFromBaseDirectory( String path, File basedir )
+ {
+ if ( basedir == null )
+ {
+ return path;
+ }
+
+ if ( path == null )
+ {
+ return null;
+ }
+
+ path = path.trim();
+
+ String base = basedir.getAbsolutePath();
+ if ( path.startsWith( base ) )
+ {
+ path = chopLeadingFileSeparator( path.substring( base.length() ) );
+ }
+
+ if ( path.length() <= 0 )
+ {
+ path = ".";
+ }
+
+ if ( !new File( path ).isAbsolute() )
+ {
+ path = path.replace( '\\', '/' );
+ }
+
+ return path;
+ }
+
+}
+
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/project/validation/DefaultModelValidator.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/project/validation/DefaultModelValidator.java
new file mode 100644
index 00000000..0095f803
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/project/validation/DefaultModelValidator.java
@@ -0,0 +1,76 @@
+package org.apache.maven.project.validation;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.model.Model;
+import org.apache.maven.model.building.DefaultModelBuildingRequest;
+import org.apache.maven.model.building.ModelBuildingRequest;
+import org.apache.maven.model.building.ModelProblem;
+import org.apache.maven.model.building.ModelProblemCollector;
+import org.apache.maven.model.building.ModelProblemCollectorRequest;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+
+/**
+ * @author <a href="mailto:trygvis@inamo.no">Trygve Laugst&oslash;l</a>
+ */
+@Component( role = ModelValidator.class )
+@Deprecated
+public class DefaultModelValidator
+ implements ModelValidator
+{
+
+ @Requirement
+ private org.apache.maven.model.validation.ModelValidator modelValidator;
+
+ public ModelValidationResult validate( Model model )
+ {
+ ModelValidationResult result = new ModelValidationResult();
+
+ ModelBuildingRequest request =
+ new DefaultModelBuildingRequest().setValidationLevel( ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_2_0 );
+
+ SimpleModelProblemCollector problems = new SimpleModelProblemCollector( result );
+
+ modelValidator.validateEffectiveModel( model, request, problems );
+
+ return result;
+ }
+
+ private static class SimpleModelProblemCollector
+ implements ModelProblemCollector
+ {
+
+ ModelValidationResult result;
+
+ public SimpleModelProblemCollector( ModelValidationResult result )
+ {
+ this.result = result;
+ }
+
+ public void add( ModelProblemCollectorRequest req )
+ {
+ if ( !ModelProblem.Severity.WARNING.equals( req.getSeverity() ) )
+ {
+ result.addMessage( req.getMessage() );
+ }
+ }
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/project/validation/ModelValidationResult.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/project/validation/ModelValidationResult.java
new file mode 100644
index 00000000..cb8c6012
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/project/validation/ModelValidationResult.java
@@ -0,0 +1,95 @@
+package org.apache.maven.project.validation;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * @author <a href="mailto:trygvis@inamo.no">Trygve Laugst&oslash;l</a>
+ */
+public class ModelValidationResult
+{
+
+ /** */
+ private static final String NEWLINE = System.getProperty( "line.separator" );
+
+ /** */
+ private List<String> messages;
+
+ public ModelValidationResult()
+ {
+ messages = new ArrayList<String>();
+ }
+
+ public int getMessageCount()
+ {
+ return messages.size();
+ }
+
+ public String getMessage( int i )
+ {
+ return messages.get( i );
+ }
+
+ public List<String> getMessages()
+ {
+ return Collections.unmodifiableList( messages );
+ }
+
+ public void addMessage( String message )
+ {
+ messages.add( message );
+ }
+
+ public String toString()
+ {
+ return render( "" );
+ }
+
+ public String render( String indentation )
+ {
+ if ( messages.size() == 0 )
+ {
+ return indentation + "There were no validation errors.";
+ }
+
+ StringBuilder message = new StringBuilder();
+
+// if ( messages.size() == 1 )
+// {
+// message.append( "There was 1 validation error: " );
+// }
+// else
+// {
+// message.append( "There was " + messages.size() + " validation errors: " + NEWLINE );
+// }
+//
+ for ( int i = 0; i < messages.size(); i++ )
+ {
+ message.append( indentation ).append( "[" ).append( i ).append( "] " ).append( messages.get( i ) ).append(
+ NEWLINE );
+ }
+
+ return message.toString();
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/project/validation/ModelValidator.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/project/validation/ModelValidator.java
new file mode 100644
index 00000000..54fd04ca
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/project/validation/ModelValidator.java
@@ -0,0 +1,37 @@
+package org.apache.maven.project.validation;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.model.Model;
+
+/**
+ * Checks the model for missing or invalid values.
+ *
+ * @author <a href="mailto:trygvis@inamo.no">Trygve Laugst&oslash;l</a>
+ */
+@Deprecated
+public interface ModelValidator
+{
+
+ String ROLE = ModelValidator.class.getName();
+
+ ModelValidationResult validate( Model model );
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/reporting/MavenReportException.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/reporting/MavenReportException.java
new file mode 100644
index 00000000..af27a840
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/reporting/MavenReportException.java
@@ -0,0 +1,39 @@
+package org.apache.maven.reporting;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * An exception occurring during the execution of a Maven report.
+ *
+ * @author Brett Porter
+ * @author <a href="evenisse@apache.org">Emmanuel Venisse</a>
+ */
+public class MavenReportException extends Exception
+{
+ public MavenReportException( String msg )
+ {
+ super( msg );
+ }
+
+ public MavenReportException( String msg, Exception e )
+ {
+ super( msg, e );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/DefaultMirrorSelector.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/DefaultMirrorSelector.java
new file mode 100644
index 00000000..53e7bd4a
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/DefaultMirrorSelector.java
@@ -0,0 +1,205 @@
+package org.apache.maven.repository;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.List;
+
+import org.apache.maven.RepositoryUtils;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.settings.Mirror;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.util.StringUtils;
+
+@Component( role = MirrorSelector.class )
+public class DefaultMirrorSelector
+ implements MirrorSelector
+{
+
+ private static final String WILDCARD = "*";
+
+ private static final String EXTERNAL_WILDCARD = "external:*";
+
+ public Mirror getMirror( ArtifactRepository repository, List<Mirror> mirrors )
+ {
+ String repoId = repository.getId();
+
+ if ( repoId != null && mirrors != null )
+ {
+ for ( Mirror mirror : mirrors )
+ {
+ if ( repoId.equals( mirror.getMirrorOf() ) && matchesLayout( repository, mirror ) )
+ {
+ return mirror;
+ }
+ }
+
+ for ( Mirror mirror : mirrors )
+ {
+ if ( matchPattern( repository, mirror.getMirrorOf() ) && matchesLayout( repository, mirror ) )
+ {
+ return mirror;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * This method checks if the pattern matches the originalRepository. Valid patterns: * =
+ * everything external:* = everything not on the localhost and not file based. repo,repo1 = repo
+ * or repo1 *,!repo1 = everything except repo1
+ *
+ * @param originalRepository to compare for a match.
+ * @param pattern used for match. Currently only '*' is supported.
+ * @return true if the repository is a match to this pattern.
+ */
+ static boolean matchPattern( ArtifactRepository originalRepository, String pattern )
+ {
+ boolean result = false;
+ String originalId = originalRepository.getId();
+
+ // simple checks first to short circuit processing below.
+ if ( WILDCARD.equals( pattern ) || pattern.equals( originalId ) )
+ {
+ result = true;
+ }
+ else
+ {
+ // process the list
+ String[] repos = pattern.split( "," );
+ for ( String repo : repos )
+ {
+ repo = repo.trim();
+ // see if this is a negative match
+ if ( repo.length() > 1 && repo.startsWith( "!" ) )
+ {
+ if ( repo.substring( 1 ).equals( originalId ) )
+ {
+ // explicitly exclude. Set result and stop processing.
+ result = false;
+ break;
+ }
+ }
+ // check for exact match
+ else if ( repo.equals( originalId ) )
+ {
+ result = true;
+ break;
+ }
+ // check for external:*
+ else if ( EXTERNAL_WILDCARD.equals( repo ) && isExternalRepo( originalRepository ) )
+ {
+ result = true;
+ // don't stop processing in case a future segment explicitly excludes this repo
+ }
+ else if ( WILDCARD.equals( repo ) )
+ {
+ result = true;
+ // don't stop processing in case a future segment explicitly excludes this repo
+ }
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Checks the URL to see if this repository refers to an external repository
+ *
+ * @param originalRepository
+ * @return true if external.
+ */
+ static boolean isExternalRepo( ArtifactRepository originalRepository )
+ {
+ try
+ {
+ URL url = new URL( originalRepository.getUrl() );
+ return !( url.getHost().equals( "localhost" ) || url.getHost().equals( "127.0.0.1" )
+ || url.getProtocol().equals( "file" ) );
+ }
+ catch ( MalformedURLException e )
+ {
+ // bad url just skip it here. It should have been validated already, but the wagon lookup will deal with it
+ return false;
+ }
+ }
+
+ static boolean matchesLayout( ArtifactRepository repository, Mirror mirror )
+ {
+ return matchesLayout( RepositoryUtils.getLayout( repository ), mirror.getMirrorOfLayouts() );
+ }
+
+ /**
+ * Checks whether the layouts configured for a mirror match with the layout of the repository.
+ *
+ * @param repoLayout The layout of the repository, may be {@code null}.
+ * @param mirrorLayout The layouts supported by the mirror, may be {@code null}.
+ * @return {@code true} if the layouts associated with the mirror match the layout of the original repository,
+ * {@code false} otherwise.
+ */
+ static boolean matchesLayout( String repoLayout, String mirrorLayout )
+ {
+ boolean result = false;
+
+ // simple checks first to short circuit processing below.
+ if ( StringUtils.isEmpty( mirrorLayout ) || WILDCARD.equals( mirrorLayout ) )
+ {
+ result = true;
+ }
+ else if ( mirrorLayout.equals( repoLayout ) )
+ {
+ result = true;
+ }
+ else
+ {
+ // process the list
+ String[] layouts = mirrorLayout.split( "," );
+ for ( String layout : layouts )
+ {
+ // see if this is a negative match
+ if ( layout.length() > 1 && layout.startsWith( "!" ) )
+ {
+ if ( layout.substring( 1 ).equals( repoLayout ) )
+ {
+ // explicitly exclude. Set result and stop processing.
+ result = false;
+ break;
+ }
+ }
+ // check for exact match
+ else if ( layout.equals( repoLayout ) )
+ {
+ result = true;
+ break;
+ }
+ else if ( WILDCARD.equals( layout ) )
+ {
+ result = true;
+ // don't stop processing in case a future segment explicitly excludes this repo
+ }
+ }
+ }
+
+ return result;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/MavenArtifactMetadata.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/MavenArtifactMetadata.java
new file mode 100644
index 00000000..c507bf70
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/MavenArtifactMetadata.java
@@ -0,0 +1,119 @@
+package org.apache.maven.repository;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ *
+ *
+ * @author Oleg Gusakov
+ *
+ */
+public class MavenArtifactMetadata
+{
+ public static final String DEFAULT_TYPE = "jar";
+
+ String groupId;
+ String artifactId;
+ String version;
+ String classifier;
+ String type;
+ String scope;
+
+ transient Object datum;
+
+ public String getGroupId()
+ {
+ return groupId;
+ }
+
+ public void setGroupId( String groupId )
+ {
+ this.groupId = groupId;
+ }
+
+ public String getArtifactId()
+ {
+ return artifactId;
+ }
+
+ public void setArtifactId( String artifactId )
+ {
+ this.artifactId = artifactId;
+ }
+
+ public String getVersion()
+ {
+ return version;
+ }
+
+ public void setVersion( String version )
+ {
+ this.version = version;
+ }
+
+ public String getClassifier()
+ {
+ return classifier;
+ }
+
+ public void setClassifier( String classifier )
+ {
+ this.classifier = classifier;
+ }
+
+ public String getType()
+ {
+ return type;
+ }
+
+ public void setType( String type )
+ {
+ this.type = type;
+ }
+
+ public Object getDatum()
+ {
+ return datum;
+ }
+
+ public void setDatum( Object datum )
+ {
+ this.datum = datum;
+ }
+
+ public String getScope()
+ {
+ return scope;
+ }
+
+ public void setScope( String scope )
+ {
+ this.scope = scope;
+ }
+
+ @Override
+ public String toString()
+ {
+ return getGroupId() + ":" + getArtifactId() + ":" + getVersion() + ":"
+ + ( getClassifier() == null ? "" : getClassifier() ) + ":"
+ + ( getType() == null ? DEFAULT_TYPE : getType() );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/MetadataGraph.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/MetadataGraph.java
new file mode 100644
index 00000000..fcaddd2c
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/MetadataGraph.java
@@ -0,0 +1,96 @@
+package org.apache.maven.repository;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+/**
+ * This is the main graph data structure used by the RepositorySystem to present tree and graph objects.
+ *
+ * @author Oleg Gusakov
+ *
+ */
+public class MetadataGraph
+{
+ /** all graph nodes */
+ Collection<MetadataGraphNode> nodes;
+
+ /** entry point for tree-like structures */
+ MetadataGraphNode entry;
+
+ public MetadataGraph( MetadataGraphNode entry )
+ {
+ this();
+
+ this.entry = entry;
+ }
+
+ public MetadataGraph()
+ {
+ nodes = new ArrayList<MetadataGraphNode>( 64 );
+ }
+
+ public void addNode( MetadataGraphNode node )
+ {
+ nodes.add( node );
+ }
+
+ /**
+ * find a node by the GAV (metadata)
+ *
+ * @param md
+ * @return
+ */
+ public MetadataGraphNode findNode( MavenArtifactMetadata md )
+ {
+ for ( MetadataGraphNode mgn : nodes )
+ {
+ if ( mgn.metadata.equals( md ) )
+ {
+ return mgn;
+ }
+ }
+
+ MetadataGraphNode node = new MetadataGraphNode( md );
+ addNode( node );
+ return node;
+ }
+
+ /**
+ * getter
+ *
+ * @return
+ */
+ public MetadataGraphNode getEntry()
+ {
+ return entry;
+ }
+
+ /**
+ * getter
+ *
+ * @return
+ */
+ public Collection<MetadataGraphNode> getNodes()
+ {
+ return nodes;
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/MetadataGraphNode.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/MetadataGraphNode.java
new file mode 100644
index 00000000..c8b9ab4e
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/MetadataGraphNode.java
@@ -0,0 +1,101 @@
+package org.apache.maven.repository;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * MetadataGraph node - as it's a directed graph - holds adjacency lists for incident and exident nodes
+ *
+ * @author Oleg Gusakov
+ *
+ */
+public class MetadataGraphNode
+{
+ /** node payload */
+ MavenArtifactMetadata metadata;
+
+ /** nodes, incident to this (depend on me) */
+ List<MetadataGraphNode> inNodes;
+
+ /** nodes, exident to this (I depend on) */
+ List<MetadataGraphNode> exNodes;
+
+ public MetadataGraphNode()
+ {
+ inNodes = new ArrayList<MetadataGraphNode>( 4 );
+ exNodes = new ArrayList<MetadataGraphNode>( 8 );
+ }
+
+ public MetadataGraphNode( MavenArtifactMetadata metadata )
+ {
+ this();
+ this.metadata = metadata;
+ }
+
+ public MetadataGraphNode addIncident( MetadataGraphNode node )
+ {
+ inNodes.add( node );
+ return this;
+ }
+
+ public MetadataGraphNode addExident( MetadataGraphNode node )
+ {
+ exNodes.add( node );
+ return this;
+ }
+
+ @Override
+ public boolean equals( Object obj )
+ {
+ if ( obj == null )
+ {
+ return false;
+ }
+
+ if ( MetadataGraphNode.class.isAssignableFrom( obj.getClass() ) )
+ {
+ MetadataGraphNode node2 = (MetadataGraphNode) obj;
+
+ if ( node2.metadata == null )
+ {
+ return metadata == null;
+ }
+
+ return metadata != null && metadata.toString().equals( node2.metadata.toString() );
+ }
+ else
+ {
+ return super.equals( obj );
+ }
+ }
+
+ @Override
+ public int hashCode()
+ {
+ if ( metadata == null )
+ {
+ return super.hashCode();
+ }
+
+ return metadata.toString().hashCode();
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/MetadataResolutionRequest.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/MetadataResolutionRequest.java
new file mode 100644
index 00000000..c98dd053
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/MetadataResolutionRequest.java
@@ -0,0 +1,202 @@
+package org.apache.maven.repository;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+
+/**
+ *
+ *
+ * @author Oleg Gusakov
+ *
+ */
+public class MetadataResolutionRequest
+{
+ private MavenArtifactMetadata mad;
+
+ private String scope;
+
+ // Needs to go away
+ private Set<Artifact> artifactDependencies;
+
+ private ArtifactRepository localRepository;
+
+ private List<ArtifactRepository> remoteRepositories;
+
+ // This is like a filter but overrides all transitive versions
+ private Map managedVersionMap;
+
+ /** result type - flat list; the default */
+ private boolean asList = true;
+
+ /** result type - dirty tree */
+ private boolean asDirtyTree = false;
+
+ /** result type - resolved tree */
+ private boolean asResolvedTree = false;
+
+ /** result type - graph */
+ private boolean asGraph = false;
+
+ public MetadataResolutionRequest()
+ {
+ }
+
+ public MetadataResolutionRequest( MavenArtifactMetadata md, ArtifactRepository localRepository,
+ List<ArtifactRepository> remoteRepositories )
+ {
+ this.mad = md;
+ this.localRepository = localRepository;
+ this.remoteRepositories = remoteRepositories;
+ }
+
+ public MavenArtifactMetadata getArtifactMetadata()
+ {
+ return mad;
+ }
+
+ public MetadataResolutionRequest setArtifactMetadata( MavenArtifactMetadata md )
+ {
+ this.mad = md;
+
+ return this;
+ }
+
+ public MetadataResolutionRequest setArtifactDependencies( Set<Artifact> artifactDependencies )
+ {
+ this.artifactDependencies = artifactDependencies;
+
+ return this;
+ }
+
+ public Set<Artifact> getArtifactDependencies()
+ {
+ return artifactDependencies;
+ }
+
+ public ArtifactRepository getLocalRepository()
+ {
+ return localRepository;
+ }
+
+ public MetadataResolutionRequest setLocalRepository( ArtifactRepository localRepository )
+ {
+ this.localRepository = localRepository;
+
+ return this;
+ }
+
+ public List<ArtifactRepository> getRemoteRepostories()
+ {
+ return remoteRepositories;
+ }
+
+ public MetadataResolutionRequest setRemoteRepostories( List<ArtifactRepository> remoteRepostories )
+ {
+ this.remoteRepositories = remoteRepostories;
+
+ return this;
+ }
+
+ public Map getManagedVersionMap()
+ {
+ return managedVersionMap;
+ }
+
+ public MetadataResolutionRequest setManagedVersionMap( Map managedVersionMap )
+ {
+ this.managedVersionMap = managedVersionMap;
+
+ return this;
+ }
+
+ public String toString()
+ {
+ StringBuilder sb = new StringBuilder()
+ .append( "REQUEST: " ).append( "\n" )
+ .append( "artifact: " ).append( mad ).append( "\n" )
+ .append( artifactDependencies ).append( "\n" )
+ .append( "localRepository: " ).append( localRepository ).append( "\n" )
+ .append( "remoteRepositories: " ).append( remoteRepositories ).append( "\n" )
+ ;
+
+ return sb.toString();
+ }
+
+ public boolean isAsList()
+ {
+ return asList;
+ }
+
+ public MetadataResolutionRequest setAsList( boolean asList )
+ {
+ this.asList = asList;
+ return this;
+ }
+
+ public boolean isAsDirtyTree()
+ {
+ return asDirtyTree;
+ }
+
+ public MetadataResolutionRequest setAsDirtyTree( boolean asDirtyTree )
+ {
+ this.asDirtyTree = asDirtyTree;
+ return this;
+ }
+
+ public boolean isAsResolvedTree()
+ {
+ return asResolvedTree;
+ }
+
+ public MetadataResolutionRequest setAsResolvedTree( boolean asResolvedTree )
+ {
+ this.asResolvedTree = asResolvedTree;
+ return this;
+ }
+
+ public boolean isAsGraph()
+ {
+ return asGraph;
+ }
+
+ public MetadataResolutionRequest setAsGraph( boolean asGraph )
+ {
+ this.asGraph = asGraph;
+ return this;
+ }
+
+ public MetadataResolutionRequest setScope( String scope )
+ {
+ this.scope = scope;
+ return this;
+ }
+
+ public String getScope()
+ {
+ return scope;
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/MetadataResolutionResult.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/MetadataResolutionResult.java
new file mode 100644
index 00000000..209c36fa
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/MetadataResolutionResult.java
@@ -0,0 +1,356 @@
+package org.apache.maven.repository;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.resolver.ArtifactResolutionException;
+import org.apache.maven.artifact.resolver.CyclicDependencyException;
+import org.apache.maven.artifact.versioning.OverConstrainedVersionException;
+
+/**
+ *
+ *
+ * @author Oleg Gusakov
+ *
+ */
+public class MetadataResolutionResult
+{
+ private Artifact originatingArtifact;
+
+ private List<Artifact> missingArtifacts;
+
+ // Exceptions
+
+ private List<Exception> exceptions;
+
+ private List<Exception> versionRangeViolations;
+
+ private List<ArtifactResolutionException> metadataResolutionExceptions;
+
+ private List<CyclicDependencyException> circularDependencyExceptions;
+
+ private List<ArtifactResolutionException> errorArtifactExceptions;
+
+ // file system errors
+
+ private List<ArtifactRepository> repositories;
+
+ private Set<Artifact> requestedArtifacts;
+
+ private Set<Artifact> artifacts;
+
+ private MetadataGraph dirtyTree;
+
+ private MetadataGraph resolvedTree;
+
+ private MetadataGraph resolvedGraph;
+
+ public Artifact getOriginatingArtifact()
+ {
+ return originatingArtifact;
+ }
+
+ public MetadataResolutionResult ListOriginatingArtifact( final Artifact originatingArtifact )
+ {
+ this.originatingArtifact = originatingArtifact;
+
+ return this;
+ }
+
+ public void addArtifact( Artifact artifact )
+ {
+ if ( artifacts == null )
+ {
+ artifacts = new LinkedHashSet<Artifact>();
+ }
+
+ artifacts.add( artifact );
+ }
+
+ public Set<Artifact> getArtifacts()
+ {
+ return artifacts;
+ }
+
+ public void addRequestedArtifact( Artifact artifact )
+ {
+ if ( requestedArtifacts == null )
+ {
+ requestedArtifacts = new LinkedHashSet<Artifact>();
+ }
+
+ requestedArtifacts.add( artifact );
+ }
+
+ public Set<Artifact> getRequestedArtifacts()
+ {
+ return requestedArtifacts;
+ }
+
+ public boolean hasMissingArtifacts()
+ {
+ return missingArtifacts != null && !missingArtifacts.isEmpty();
+ }
+
+ public List<Artifact> getMissingArtifacts()
+ {
+ return missingArtifacts == null ? Collections.<Artifact> emptyList() : missingArtifacts;
+ }
+
+ public MetadataResolutionResult addMissingArtifact( Artifact artifact )
+ {
+ missingArtifacts = initList( missingArtifacts );
+
+ missingArtifacts.add( artifact );
+
+ return this;
+ }
+
+ public MetadataResolutionResult setUnresolvedArtifacts( final List<Artifact> unresolvedArtifacts )
+ {
+ this.missingArtifacts = unresolvedArtifacts;
+
+ return this;
+ }
+
+ // ------------------------------------------------------------------------
+ // Exceptions
+ // ------------------------------------------------------------------------
+
+ public boolean hasExceptions()
+ {
+ return exceptions != null && !exceptions.isEmpty();
+ }
+
+ public List<Exception> getExceptions()
+ {
+ return exceptions == null ? Collections.<Exception> emptyList() : exceptions;
+ }
+
+ // ------------------------------------------------------------------------
+ // Version Range Violations
+ // ------------------------------------------------------------------------
+
+ public boolean hasVersionRangeViolations()
+ {
+ return versionRangeViolations != null;
+ }
+
+ /**
+ * @TODO this needs to accept a {@link OverConstrainedVersionException} as returned by
+ * {@link #getVersionRangeViolation(int)} but it's not used like that in
+ * {@link DefaultLegacyArtifactCollector}
+ */
+ public MetadataResolutionResult addVersionRangeViolation( Exception e )
+ {
+ versionRangeViolations = initList( versionRangeViolations );
+
+ versionRangeViolations.add( e );
+
+ exceptions = initList( exceptions );
+
+ exceptions.add( e );
+
+ return this;
+ }
+
+ public OverConstrainedVersionException getVersionRangeViolation( int i )
+ {
+ return (OverConstrainedVersionException) versionRangeViolations.get( i );
+ }
+
+ public List<Exception> getVersionRangeViolations()
+ {
+ return versionRangeViolations == null ? Collections.<Exception> emptyList() : versionRangeViolations;
+ }
+
+ // ------------------------------------------------------------------------
+ // Metadata Resolution Exceptions: ArtifactResolutionExceptions
+ // ------------------------------------------------------------------------
+
+ public boolean hasMetadataResolutionExceptions()
+ {
+ return metadataResolutionExceptions != null;
+ }
+
+ public MetadataResolutionResult addMetadataResolutionException( ArtifactResolutionException e )
+ {
+ metadataResolutionExceptions = initList( metadataResolutionExceptions );
+
+ metadataResolutionExceptions.add( e );
+
+ exceptions = initList( exceptions );
+
+ exceptions.add( e );
+
+ return this;
+ }
+
+ public ArtifactResolutionException getMetadataResolutionException( int i )
+ {
+ return metadataResolutionExceptions.get( i );
+ }
+
+ public List<ArtifactResolutionException> getMetadataResolutionExceptions()
+ {
+ return metadataResolutionExceptions == null ? Collections.<ArtifactResolutionException> emptyList()
+ : metadataResolutionExceptions;
+ }
+
+ // ------------------------------------------------------------------------
+ // ErrorArtifactExceptions: ArtifactResolutionExceptions
+ // ------------------------------------------------------------------------
+
+ public boolean hasErrorArtifactExceptions()
+ {
+ return errorArtifactExceptions != null;
+ }
+
+ public MetadataResolutionResult addError( Exception e )
+ {
+ if ( exceptions == null )
+ {
+ initList( exceptions );
+ }
+
+ exceptions.add( e );
+
+ return this;
+ }
+
+ public List<ArtifactResolutionException> getErrorArtifactExceptions()
+ {
+ if ( errorArtifactExceptions == null )
+ {
+ return Collections.emptyList();
+ }
+
+ return errorArtifactExceptions;
+ }
+
+ // ------------------------------------------------------------------------
+ // Circular Dependency Exceptions
+ // ------------------------------------------------------------------------
+
+ public boolean hasCircularDependencyExceptions()
+ {
+ return circularDependencyExceptions != null;
+ }
+
+ public MetadataResolutionResult addCircularDependencyException( CyclicDependencyException e )
+ {
+ circularDependencyExceptions = initList( circularDependencyExceptions );
+
+ circularDependencyExceptions.add( e );
+
+ exceptions = initList( exceptions );
+
+ exceptions.add( e );
+
+ return this;
+ }
+
+ public CyclicDependencyException getCircularDependencyException( int i )
+ {
+ return circularDependencyExceptions.get( i );
+ }
+
+ public List<CyclicDependencyException> getCircularDependencyExceptions()
+ {
+ if ( circularDependencyExceptions == null )
+ {
+ return Collections.emptyList();
+ }
+
+ return circularDependencyExceptions;
+ }
+
+ // ------------------------------------------------------------------------
+ // Repositories
+ // ------------------------------------------------------------------------
+
+ public List<ArtifactRepository> getRepositories()
+ {
+ if ( repositories == null )
+ {
+ return Collections.emptyList();
+ }
+
+ return repositories;
+ }
+
+ public MetadataResolutionResult setRepositories( final List<ArtifactRepository> repositories )
+ {
+ this.repositories = repositories;
+
+ return this;
+ }
+
+ //
+ // Internal
+ //
+
+ private <T> List<T> initList( final List<T> l )
+ {
+ if ( l == null )
+ {
+ return new ArrayList<T>();
+ }
+ return l;
+ }
+
+ public String toString()
+ {
+ StringBuilder sb = new StringBuilder();
+
+ if ( artifacts != null )
+ {
+ int i = 1;
+ sb.append( "---------" ).append( "\n" );
+ sb.append( artifacts.size() ).append( "\n" );
+ for ( Artifact a : artifacts )
+ {
+ sb.append( i ).append( " " ).append( a ).append( "\n" );
+ i++;
+ }
+ sb.append( "---------" ).append( "\n" );
+ }
+
+ return sb.toString();
+ }
+
+ public MetadataGraph getResolvedTree()
+ {
+ return resolvedTree;
+ }
+
+ public void setResolvedTree( MetadataGraph resolvedTree )
+ {
+ this.resolvedTree = resolvedTree;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/MirrorSelector.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/MirrorSelector.java
new file mode 100644
index 00000000..c15899ed
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/MirrorSelector.java
@@ -0,0 +1,44 @@
+package org.apache.maven.repository;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.List;
+
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.settings.Mirror;
+
+/**
+ * Handles the selection of mirrors for repositories.
+ *
+ * @author Benjamin Bentmann
+ */
+public interface MirrorSelector
+{
+
+ /**
+ * Determines the mirror for the specified repository.
+ *
+ * @param repository The repository to determine the mirror for, must not be {@code null}.
+ * @param mirrors The available mirrors, may be {@code null}.
+ * @return The mirror specification for the repository or {@code null} if no mirror matched.
+ */
+ Mirror getMirror( ArtifactRepository repository, List<Mirror> mirrors );
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/UserLocalArtifactRepository.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/UserLocalArtifactRepository.java
new file mode 100644
index 00000000..70d3e0a0
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/UserLocalArtifactRepository.java
@@ -0,0 +1,74 @@
+package org.apache.maven.repository;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.metadata.ArtifactMetadata;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+
+public class UserLocalArtifactRepository
+ extends LocalArtifactRepository
+{
+ private ArtifactRepository localRepository;
+
+ public UserLocalArtifactRepository( ArtifactRepository localRepository )
+ {
+ this.localRepository = localRepository;
+ setLayout( localRepository.getLayout() );
+ }
+
+ @Override
+ public Artifact find( Artifact artifact )
+ {
+ File artifactFile = new File( localRepository.getBasedir(), pathOf( artifact ) );
+
+ // We need to set the file here or the resolver will fail with an NPE, not fully equipped to deal
+ // with multiple local repository implementations yet.
+ artifact.setFile( artifactFile );
+
+ return artifact;
+ }
+
+ @Override
+ public String getId()
+ {
+ return localRepository.getId();
+ }
+
+ @Override
+ public String pathOfLocalRepositoryMetadata( ArtifactMetadata metadata, ArtifactRepository repository )
+ {
+ return localRepository.pathOfLocalRepositoryMetadata( metadata, repository );
+ }
+
+ @Override
+ public String pathOf( Artifact artifact )
+ {
+ return localRepository.pathOf( artifact );
+ }
+
+ @Override
+ public boolean hasLocalMetadata()
+ {
+ return true;
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/VersionNotFoundException.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/VersionNotFoundException.java
new file mode 100644
index 00000000..77b1af12
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/VersionNotFoundException.java
@@ -0,0 +1,83 @@
+package org.apache.maven.repository;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+
+import org.apache.maven.artifact.ArtifactUtils;
+import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
+import org.apache.maven.model.Dependency;
+
+/**
+ * Thrown if a dependency has an invalid version.
+ *
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ */
+public class VersionNotFoundException
+ extends Exception
+{
+ private Dependency dependency;
+
+ private String projectId;
+ private File pomFile;
+ private InvalidVersionSpecificationException cause;
+
+ public VersionNotFoundException( String projectId, Dependency dependency, File pomFile,
+ InvalidVersionSpecificationException cause )
+ {
+ super( projectId + ", " + formatLocationInPom( dependency ) + " " + dependency.getVersion() + ", pom file "
+ + pomFile, cause );
+
+ this.projectId = projectId;
+
+ this.pomFile = pomFile;
+
+ this.cause = cause;
+
+ this.dependency = dependency;
+ }
+
+ private static String formatLocationInPom( Dependency dependency )
+ {
+ return "Dependency: " + ArtifactUtils.versionlessKey( dependency.getGroupId(), dependency.getArtifactId() );
+ }
+
+ public Dependency getDependency()
+ {
+ return dependency;
+ }
+
+ public String getProjectId()
+ {
+ return projectId;
+ }
+
+ public File getPomFile()
+ {
+ return pomFile;
+ }
+
+ public InvalidVersionSpecificationException getCauseException()
+ {
+ return cause;
+ }
+
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/ChecksumFailedException.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/ChecksumFailedException.java
new file mode 100644
index 00000000..4e0c4a6b
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/ChecksumFailedException.java
@@ -0,0 +1,42 @@
+package org.apache.maven.repository.legacy;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.wagon.TransferFailedException;
+
+/**
+ * Occurs when a download checksum fails.
+ *
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ */
+public class ChecksumFailedException
+ extends TransferFailedException
+{
+ public ChecksumFailedException( String s )
+ {
+ super( s );
+ }
+
+ public ChecksumFailedException( String message,
+ Throwable cause )
+ {
+ super( message, cause );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/DefaultUpdateCheckManager.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/DefaultUpdateCheckManager.java
new file mode 100644
index 00000000..57b307ef
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/DefaultUpdateCheckManager.java
@@ -0,0 +1,438 @@
+package org.apache.maven.repository.legacy;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.nio.ByteBuffer;
+import java.nio.channels.FileChannel;
+import java.nio.channels.FileLock;
+import java.util.Date;
+import java.util.Properties;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy;
+import org.apache.maven.artifact.repository.Authentication;
+import org.apache.maven.artifact.repository.metadata.RepositoryMetadata;
+import org.apache.maven.repository.Proxy;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.logging.AbstractLogEnabled;
+import org.codehaus.plexus.logging.Logger;
+import org.codehaus.plexus.util.IOUtil;
+
+@Component( role = UpdateCheckManager.class )
+public class DefaultUpdateCheckManager
+ extends AbstractLogEnabled
+ implements UpdateCheckManager
+{
+
+ private static final String ERROR_KEY_SUFFIX = ".error";
+
+ public DefaultUpdateCheckManager()
+ {
+
+ }
+
+ public DefaultUpdateCheckManager( Logger logger )
+ {
+ enableLogging( logger );
+ }
+
+ public static final String LAST_UPDATE_TAG = ".lastUpdated";
+
+ private static final String TOUCHFILE_NAME = "resolver-status.properties";
+
+ public boolean isUpdateRequired( Artifact artifact, ArtifactRepository repository )
+ {
+ File file = artifact.getFile();
+
+ ArtifactRepositoryPolicy policy = artifact.isSnapshot() ? repository.getSnapshots() : repository.getReleases();
+
+ if ( !policy.isEnabled() )
+ {
+ if ( getLogger().isDebugEnabled() )
+ {
+ getLogger().debug(
+ "Skipping update check for " + artifact + " (" + file + ") from "
+ + repository.getId() + " (" + repository.getUrl() + ")" );
+ }
+
+ return false;
+ }
+
+ if ( getLogger().isDebugEnabled() )
+ {
+ getLogger().debug(
+ "Determining update check for " + artifact + " (" + file + ") from "
+ + repository.getId() + " (" + repository.getUrl() + ")" );
+ }
+
+ if ( file == null )
+ {
+ // TODO throw something instead?
+ return true;
+ }
+
+ Date lastCheckDate;
+
+ if ( file.exists() )
+ {
+ lastCheckDate = new Date ( file.lastModified() );
+ }
+ else
+ {
+ File touchfile = getTouchfile( artifact );
+ lastCheckDate = readLastUpdated( touchfile, getRepositoryKey( repository ) );
+ }
+
+ return ( lastCheckDate == null ) || policy.checkOutOfDate( lastCheckDate );
+ }
+
+ public boolean isUpdateRequired( RepositoryMetadata metadata, ArtifactRepository repository, File file )
+ {
+ // Here, we need to determine which policy to use. Release updateInterval will be used when
+ // the metadata refers to a release artifact or meta-version, and snapshot updateInterval will be used when
+ // it refers to a snapshot artifact or meta-version.
+ // NOTE: Release metadata includes version information about artifacts that have been released, to allow
+ // meta-versions like RELEASE and LATEST to resolve, and also to allow retrieval of the range of valid, released
+ // artifacts available.
+ ArtifactRepositoryPolicy policy = metadata.getPolicy( repository );
+
+ if ( !policy.isEnabled() )
+ {
+ if ( getLogger().isDebugEnabled() )
+ {
+ getLogger().debug(
+ "Skipping update check for " + metadata.getKey() + " (" + file + ") from "
+ + repository.getId() + " (" + repository.getUrl() + ")" );
+ }
+
+ return false;
+ }
+
+ if ( getLogger().isDebugEnabled() )
+ {
+ getLogger().debug(
+ "Determining update check for " + metadata.getKey() + " (" + file + ") from "
+ + repository.getId() + " (" + repository.getUrl() + ")" );
+ }
+
+ if ( file == null )
+ {
+ // TODO throw something instead?
+ return true;
+ }
+
+ Date lastCheckDate = readLastUpdated( metadata, repository, file );
+
+ return ( lastCheckDate == null ) || policy.checkOutOfDate( lastCheckDate );
+ }
+
+ private Date readLastUpdated( RepositoryMetadata metadata, ArtifactRepository repository, File file )
+ {
+ File touchfile = getTouchfile( metadata, file );
+
+ String key = getMetadataKey( repository, file );
+
+ return readLastUpdated( touchfile, key );
+ }
+
+ public String getError( Artifact artifact, ArtifactRepository repository )
+ {
+ File touchFile = getTouchfile( artifact );
+ return getError( touchFile, getRepositoryKey( repository ) );
+ }
+
+ public void touch( Artifact artifact, ArtifactRepository repository, String error )
+ {
+ File file = artifact.getFile();
+
+ File touchfile = getTouchfile( artifact );
+
+ if ( file.exists() )
+ {
+ touchfile.delete();
+ }
+ else
+ {
+ writeLastUpdated( touchfile, getRepositoryKey( repository ), error );
+ }
+ }
+
+ public void touch( RepositoryMetadata metadata, ArtifactRepository repository, File file )
+ {
+ File touchfile = getTouchfile( metadata, file );
+
+ String key = getMetadataKey( repository, file );
+
+ writeLastUpdated( touchfile, key, null );
+ }
+
+ String getMetadataKey( ArtifactRepository repository, File file )
+ {
+ return repository.getId() + '.' + file.getName() + LAST_UPDATE_TAG;
+ }
+
+ String getRepositoryKey( ArtifactRepository repository )
+ {
+ StringBuilder buffer = new StringBuilder( 256 );
+
+ Proxy proxy = repository.getProxy();
+ if ( proxy != null )
+ {
+ if ( proxy.getUserName() != null )
+ {
+ int hash = ( proxy.getUserName() + proxy.getPassword() ).hashCode();
+ buffer.append( hash ).append( '@' );
+ }
+ buffer.append( proxy.getHost() ).append( ':' ).append( proxy.getPort() ).append( '>' );
+ }
+
+ // consider the username&password because a repo manager might block artifacts depending on authorization
+ Authentication auth = repository.getAuthentication();
+ if ( auth != null )
+ {
+ int hash = ( auth.getUsername() + auth.getPassword() ).hashCode();
+ buffer.append( hash ).append( '@' );
+ }
+
+ // consider the URL (instead of the id) as this most closely relates to the contents in the repo
+ buffer.append( repository.getUrl() );
+
+ return buffer.toString();
+ }
+
+ private void writeLastUpdated( File touchfile, String key, String error )
+ {
+ synchronized ( touchfile.getAbsolutePath().intern() )
+ {
+ if ( !touchfile.getParentFile().exists() && !touchfile.getParentFile().mkdirs() )
+ {
+ getLogger().debug( "Failed to create directory: " + touchfile.getParent()
+ + " for tracking artifact metadata resolution." );
+ return;
+ }
+
+ FileChannel channel = null;
+ FileLock lock = null;
+ try
+ {
+ Properties props = new Properties();
+
+ channel = new RandomAccessFile( touchfile, "rw" ).getChannel();
+ lock = channel.lock( 0, channel.size(), false );
+
+ if ( touchfile.canRead() )
+ {
+ getLogger().debug( "Reading resolution-state from: " + touchfile );
+ ByteBuffer buffer = ByteBuffer.allocate( (int) channel.size() );
+
+ channel.read( buffer );
+ buffer.flip();
+
+ ByteArrayInputStream stream = new ByteArrayInputStream( buffer.array() );
+ props.load( stream );
+ }
+
+ props.setProperty( key, Long.toString( System.currentTimeMillis() ) );
+
+ if ( error != null )
+ {
+ props.setProperty( key + ERROR_KEY_SUFFIX, error );
+ }
+ else
+ {
+ props.remove( key + ERROR_KEY_SUFFIX );
+ }
+
+ ByteArrayOutputStream stream = new ByteArrayOutputStream();
+
+ getLogger().debug( "Writing resolution-state to: " + touchfile );
+ props.store( stream, "Last modified on: " + new Date() );
+
+ byte[] data = stream.toByteArray();
+ ByteBuffer buffer = ByteBuffer.allocate( data.length );
+ buffer.put( data );
+ buffer.flip();
+
+ channel.position( 0 );
+ channel.write( buffer );
+ }
+ catch ( IOException e )
+ {
+ getLogger().debug( "Failed to record lastUpdated information for resolution.\nFile: "
+ + touchfile.toString() + "; key: " + key, e );
+ }
+ finally
+ {
+ if ( lock != null )
+ {
+ try
+ {
+ lock.release();
+ }
+ catch ( IOException e )
+ {
+ getLogger().debug( "Error releasing exclusive lock for resolution tracking file: "
+ + touchfile, e );
+ }
+ }
+
+ if ( channel != null )
+ {
+ try
+ {
+ channel.close();
+ }
+ catch ( IOException e )
+ {
+ getLogger().debug( "Error closing FileChannel for resolution tracking file: "
+ + touchfile, e );
+ }
+ }
+ }
+ }
+ }
+
+ Date readLastUpdated( File touchfile, String key )
+ {
+ getLogger().debug( "Searching for " + key + " in resolution tracking file." );
+
+ Properties props = read( touchfile );
+ if ( props != null )
+ {
+ String rawVal = props.getProperty( key );
+ if ( rawVal != null )
+ {
+ try
+ {
+ return new Date( Long.parseLong( rawVal ) );
+ }
+ catch ( NumberFormatException e )
+ {
+ getLogger().debug( "Cannot parse lastUpdated date: \'" + rawVal + "\'. Ignoring.", e );
+ }
+ }
+ }
+ return null;
+ }
+
+ private String getError( File touchFile, String key )
+ {
+ Properties props = read( touchFile );
+ if ( props != null )
+ {
+ return props.getProperty( key + ERROR_KEY_SUFFIX );
+ }
+ return null;
+ }
+
+ private Properties read( File touchfile )
+ {
+ if ( !touchfile.canRead() )
+ {
+ getLogger().debug( "Skipped unreadable resolution tracking file " + touchfile );
+ return null;
+ }
+
+ synchronized ( touchfile.getAbsolutePath().intern() )
+ {
+ FileLock lock = null;
+ FileChannel channel = null;
+ try
+ {
+ Properties props = new Properties();
+
+ FileInputStream stream = new FileInputStream( touchfile );
+ try
+ {
+ channel = stream.getChannel();
+ lock = channel.lock( 0, channel.size(), true );
+
+ getLogger().debug( "Reading resolution-state from: " + touchfile );
+ props.load( stream );
+
+ return props;
+ }
+ finally
+ {
+ IOUtil.close( stream );
+ }
+ }
+ catch ( IOException e )
+ {
+ getLogger().debug( "Failed to read resolution tracking file " + touchfile, e );
+
+ return null;
+ }
+ finally
+ {
+ if ( lock != null )
+ {
+ try
+ {
+ lock.release();
+ }
+ catch ( IOException e )
+ {
+ getLogger().debug( "Error releasing shared lock for resolution tracking file: " + touchfile,
+ e );
+ }
+ }
+
+ if ( channel != null )
+ {
+ try
+ {
+ channel.close();
+ }
+ catch ( IOException e )
+ {
+ getLogger().debug( "Error closing FileChannel for resolution tracking file: " + touchfile, e );
+ }
+ }
+ }
+ }
+ }
+
+ File getTouchfile( Artifact artifact )
+ {
+ StringBuilder sb = new StringBuilder( 128 );
+ sb.append( artifact.getArtifactId() );
+ sb.append( '-' ).append( artifact.getBaseVersion() );
+ if ( artifact.getClassifier() != null )
+ {
+ sb.append( '-' ).append( artifact.getClassifier() );
+ }
+ sb.append( '.' ).append( artifact.getType() ).append( LAST_UPDATE_TAG );
+ return new File( artifact.getFile().getParentFile(), sb.toString() );
+ }
+
+ File getTouchfile( RepositoryMetadata metadata, File file )
+ {
+ return new File( file.getParent(), TOUCHFILE_NAME );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/DefaultWagonManager.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/DefaultWagonManager.java
new file mode 100644
index 00000000..2c4a60ec
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/DefaultWagonManager.java
@@ -0,0 +1,823 @@
+package org.apache.maven.repository.legacy;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.Method;
+import java.security.NoSuchAlgorithmException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.metadata.ArtifactMetadata;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy;
+import org.apache.maven.plugin.LegacySupport;
+import org.apache.maven.wagon.ConnectionException;
+import org.apache.maven.wagon.ResourceDoesNotExistException;
+import org.apache.maven.wagon.TransferFailedException;
+import org.apache.maven.wagon.UnsupportedProtocolException;
+import org.apache.maven.wagon.Wagon;
+import org.apache.maven.wagon.authentication.AuthenticationException;
+import org.apache.maven.wagon.authentication.AuthenticationInfo;
+import org.apache.maven.wagon.authorization.AuthorizationException;
+import org.apache.maven.wagon.events.TransferListener;
+import org.apache.maven.wagon.observers.ChecksumObserver;
+import org.apache.maven.wagon.proxy.ProxyInfo;
+import org.apache.maven.wagon.repository.Repository;
+import org.codehaus.plexus.PlexusContainer;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+import org.codehaus.plexus.component.repository.exception.ComponentLifecycleException;
+import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
+import org.codehaus.plexus.logging.Logger;
+import org.codehaus.plexus.util.FileUtils;
+import org.eclipse.aether.ConfigurationProperties;
+import org.eclipse.aether.util.ConfigUtils;
+
+//TODO: remove the update check manager
+//TODO: separate into retriever and publisher
+//TODO: remove hardcoding of checksum logic
+@Component( role = WagonManager.class )
+public class DefaultWagonManager
+ implements WagonManager
+{
+ private static final String[] CHECKSUM_IDS = { "md5", "sha1" };
+
+ /** have to match the CHECKSUM_IDS */
+ private static final String[] CHECKSUM_ALGORITHMS = { "MD5", "SHA-1" };
+
+ @Requirement
+ private Logger logger;
+
+ @Requirement
+ private PlexusContainer container;
+
+ @Requirement
+ private UpdateCheckManager updateCheckManager;
+
+ @Requirement
+ private LegacySupport legacySupport;
+
+
+ //
+ // Retriever
+ //
+ @Override
+ public void getArtifact( Artifact artifact, ArtifactRepository repository, TransferListener downloadMonitor,
+ boolean force )
+ throws TransferFailedException, ResourceDoesNotExistException
+ {
+ String remotePath = repository.pathOf( artifact );
+
+ ArtifactRepositoryPolicy policy = artifact.isSnapshot() ? repository.getSnapshots() : repository.getReleases();
+
+ if ( !policy.isEnabled() )
+ {
+ logger.debug( "Skipping disabled repository " + repository.getId() + " for resolution of "
+ + artifact.getId() );
+ }
+ else if ( artifact.isSnapshot() || !artifact.getFile().exists() )
+ {
+ if ( force || updateCheckManager.isUpdateRequired( artifact, repository ) )
+ {
+ logger.debug( "Trying repository " + repository.getId() + " for resolution of " + artifact.getId()
+ + " from " + remotePath );
+
+ try
+ {
+ getRemoteFile( repository, artifact.getFile(), remotePath, downloadMonitor,
+ policy.getChecksumPolicy(), false );
+
+ updateCheckManager.touch( artifact, repository, null );
+ }
+ catch ( ResourceDoesNotExistException e )
+ {
+ updateCheckManager.touch( artifact, repository, null );
+ throw e;
+ }
+ catch ( TransferFailedException e )
+ {
+ String error = ( e.getMessage() != null ) ? e.getMessage() : e.getClass().getSimpleName();
+ updateCheckManager.touch( artifact, repository, error );
+ throw e;
+ }
+
+ logger.debug( " Artifact " + artifact.getId() + " resolved to " + artifact.getFile() );
+
+ artifact.setResolved( true );
+ }
+ else if ( !artifact.getFile().exists() )
+ {
+ String error = updateCheckManager.getError( artifact, repository );
+ if ( error != null )
+ {
+ throw new TransferFailedException( "Failure to resolve " + remotePath + " from "
+ + repository.getUrl() + " was cached in the local repository. "
+ + "Resolution will not be reattempted until the update interval of " + repository.getId()
+ + " has elapsed or updates are forced. Original error: " + error );
+ }
+ else
+ {
+ throw new ResourceDoesNotExistException( "Failure to resolve " + remotePath + " from "
+ + repository.getUrl() + " was cached in the local repository. "
+ + "Resolution will not be reattempted until the update interval of " + repository.getId()
+ + " has elapsed or updates are forced." );
+ }
+ }
+ }
+ }
+
+ @Override
+ public void getArtifact( Artifact artifact, List<ArtifactRepository> remoteRepositories,
+ TransferListener downloadMonitor, boolean force )
+ throws TransferFailedException, ResourceDoesNotExistException
+ {
+ TransferFailedException tfe = null;
+
+ for ( ArtifactRepository repository : remoteRepositories )
+ {
+ try
+ {
+ getArtifact( artifact, repository, downloadMonitor, force );
+
+ if ( artifact.isResolved() )
+ {
+ artifact.setRepository( repository );
+ break;
+ }
+ }
+ catch ( ResourceDoesNotExistException e )
+ {
+ // This one we will eat when looking through remote repositories
+ // because we want to cycle through them all before squawking.
+
+ logger.debug( "Unable to find artifact " + artifact.getId() + " in repository " + repository.getId()
+ + " (" + repository.getUrl() + ")", e );
+ }
+ catch ( TransferFailedException e )
+ {
+ tfe = e;
+
+ String msg =
+ "Unable to get artifact " + artifact.getId() + " from repository " + repository.getId() + " ("
+ + repository.getUrl() + "): " + e.getMessage();
+ if ( logger.isDebugEnabled() )
+ {
+ logger.warn( msg, e );
+ }
+ else
+ {
+ logger.warn( msg );
+ }
+ }
+ }
+
+ // if it already exists locally we were just trying to force it - ignore the update
+ if ( !artifact.getFile().exists() )
+ {
+ if ( tfe != null )
+ {
+ throw tfe;
+ }
+ else
+ {
+ throw new ResourceDoesNotExistException( "Unable to download the artifact from any repository" );
+ }
+ }
+ }
+
+ @Override
+ public void getArtifactMetadata( ArtifactMetadata metadata, ArtifactRepository repository, File destination,
+ String checksumPolicy )
+ throws TransferFailedException, ResourceDoesNotExistException
+ {
+ String remotePath = repository.pathOfRemoteRepositoryMetadata( metadata );
+
+ getRemoteFile( repository, destination, remotePath, null, checksumPolicy, true );
+ }
+
+ @Override
+ public void getArtifactMetadataFromDeploymentRepository( ArtifactMetadata metadata, ArtifactRepository repository,
+ File destination, String checksumPolicy )
+ throws TransferFailedException, ResourceDoesNotExistException
+ {
+ String remotePath = repository.pathOfRemoteRepositoryMetadata( metadata );
+
+ getRemoteFile( repository, destination, remotePath, null, checksumPolicy, true );
+ }
+
+ /**
+ * Deal with connecting to a wagon repository taking into account authentication and proxies.
+ *
+ * @param wagon
+ * @param repository
+ * @throws ConnectionException
+ * @throws AuthenticationException
+ */
+ private void connectWagon( Wagon wagon, ArtifactRepository repository )
+ throws ConnectionException, AuthenticationException
+ {
+ // MNG-5509
+ // See org.eclipse.aether.connector.wagon.WagonRepositoryConnector.connectWagon(Wagon)
+ if( legacySupport.getRepositorySession() != null )
+ {
+ String userAgent = ConfigUtils.getString( legacySupport.getRepositorySession(), null, ConfigurationProperties.USER_AGENT );
+ if( userAgent == null)
+ {
+ Properties headers = new Properties();
+
+ headers.put( "User-Agent", ConfigUtils.getString( legacySupport.getRepositorySession(), "Maven",
+ ConfigurationProperties.USER_AGENT ) );
+ try
+ {
+ Method setHttpHeaders = wagon.getClass().getMethod( "setHttpHeaders", Properties.class );
+ setHttpHeaders.invoke( wagon, headers );
+ }
+ catch ( NoSuchMethodException e )
+ {
+ // normal for non-http wagons
+ }
+ catch ( Exception e )
+ {
+ logger.debug( "Could not set user agent for wagon " + wagon.getClass().getName() + ": " + e );
+ }
+ }
+ }
+
+ if ( repository.getProxy() != null && logger.isDebugEnabled() )
+ {
+ logger.debug( "Using proxy " + repository.getProxy().getHost() + ":" + repository.getProxy().getPort()
+ + " for " + repository.getUrl() );
+ }
+
+ if ( repository.getAuthentication() != null && repository.getProxy() != null )
+ {
+ wagon.connect( new Repository( repository.getId(), repository.getUrl() ), authenticationInfo( repository ),
+ proxyInfo( repository ) );
+ }
+ else if ( repository.getAuthentication() != null )
+ {
+ wagon.connect( new Repository( repository.getId(), repository.getUrl() ),
+ authenticationInfo( repository ) );
+ }
+ else if ( repository.getProxy() != null )
+ {
+ wagon.connect( new Repository( repository.getId(), repository.getUrl() ), proxyInfo( repository ) );
+ }
+ else
+ {
+ wagon.connect( new Repository( repository.getId(), repository.getUrl() ) );
+ }
+ }
+
+ private AuthenticationInfo authenticationInfo( ArtifactRepository repository )
+ {
+ AuthenticationInfo ai = new AuthenticationInfo();
+ ai.setUserName( repository.getAuthentication().getUsername() );
+ ai.setPassword( repository.getAuthentication().getPassword() );
+ return ai;
+ }
+
+ private ProxyInfo proxyInfo( ArtifactRepository repository )
+ {
+ ProxyInfo proxyInfo = new ProxyInfo();
+ proxyInfo.setHost( repository.getProxy().getHost() );
+ proxyInfo.setType( repository.getProxy().getProtocol() );
+ proxyInfo.setPort( repository.getProxy().getPort() );
+ proxyInfo.setNonProxyHosts( repository.getProxy().getNonProxyHosts() );
+ proxyInfo.setUserName( repository.getProxy().getUserName() );
+ proxyInfo.setPassword( repository.getProxy().getPassword() );
+ return proxyInfo;
+ }
+
+ @Override
+ public void getRemoteFile( ArtifactRepository repository, File destination, String remotePath,
+ TransferListener downloadMonitor, String checksumPolicy, boolean force )
+ throws TransferFailedException, ResourceDoesNotExistException
+ {
+ String protocol = repository.getProtocol();
+
+ Wagon wagon;
+
+ try
+ {
+ wagon = getWagon( protocol );
+ }
+ catch ( UnsupportedProtocolException e )
+ {
+ throw new TransferFailedException( "Unsupported Protocol: '" + protocol + "': " + e.getMessage(), e );
+ }
+
+ if ( downloadMonitor != null )
+ {
+ wagon.addTransferListener( downloadMonitor );
+ }
+
+ File temp = new File( destination + ".tmp" );
+
+ temp.deleteOnExit();
+
+ boolean downloaded = false;
+
+ try
+ {
+ connectWagon( wagon, repository );
+
+ boolean firstRun = true;
+ boolean retry = true;
+
+ // this will run at most twice. The first time, the firstRun flag is turned off, and if the retry flag
+ // is set on the first run, it will be turned off and not re-set on the second try. This is because the
+ // only way the retry flag can be set is if ( firstRun == true ).
+ while ( firstRun || retry )
+ {
+ ChecksumObserver md5ChecksumObserver = null;
+ ChecksumObserver sha1ChecksumObserver = null;
+ try
+ {
+ // TODO: configure on repository
+ int i = 0;
+
+ md5ChecksumObserver = addChecksumObserver( wagon, CHECKSUM_ALGORITHMS[i++] );
+ sha1ChecksumObserver = addChecksumObserver( wagon, CHECKSUM_ALGORITHMS[i++] );
+
+ // reset the retry flag.
+ retry = false;
+
+ // This should take care of creating destination directory now on
+ if ( destination.exists() && !force )
+ {
+ try
+ {
+ downloaded = wagon.getIfNewer( remotePath, temp, destination.lastModified() );
+
+ if ( !downloaded )
+ {
+ // prevent additional checks of this artifact until it expires again
+ destination.setLastModified( System.currentTimeMillis() );
+ }
+ }
+ catch ( UnsupportedOperationException e )
+ {
+ // older wagons throw this. Just get() instead
+ wagon.get( remotePath, temp );
+
+ downloaded = true;
+ }
+ }
+ else
+ {
+ wagon.get( remotePath, temp );
+ downloaded = true;
+ }
+ }
+ finally
+ {
+ wagon.removeTransferListener( md5ChecksumObserver );
+ wagon.removeTransferListener( sha1ChecksumObserver );
+ }
+
+ if ( downloaded )
+ {
+ // keep the checksum files from showing up on the download monitor...
+ if ( downloadMonitor != null )
+ {
+ wagon.removeTransferListener( downloadMonitor );
+ }
+
+ // try to verify the SHA-1 checksum for this file.
+ try
+ {
+ verifyChecksum( sha1ChecksumObserver, destination, temp, remotePath, ".sha1", wagon );
+ }
+ catch ( ChecksumFailedException e )
+ {
+ // if we catch a ChecksumFailedException, it means the transfer/read succeeded, but the checksum
+ // doesn't match. This could be a problem with the server (ibiblio HTTP-200 error page), so we'll
+ // try this up to two times. On the second try, we'll handle it as a bona-fide error, based on the
+ // repository's checksum checking policy.
+ if ( firstRun )
+ {
+ logger.warn( "*** CHECKSUM FAILED - " + e.getMessage() + " - RETRYING" );
+ retry = true;
+ }
+ else
+ {
+ handleChecksumFailure( checksumPolicy, e.getMessage(), e.getCause() );
+ }
+ }
+ catch ( ResourceDoesNotExistException sha1TryException )
+ {
+ logger.debug( "SHA1 not found, trying MD5: " + sha1TryException.getMessage() );
+
+ // if this IS NOT a ChecksumFailedException, it was a problem with transfer/read of the checksum
+ // file...we'll try again with the MD5 checksum.
+ try
+ {
+ verifyChecksum( md5ChecksumObserver, destination, temp, remotePath, ".md5", wagon );
+ }
+ catch ( ChecksumFailedException e )
+ {
+ // if we also fail to verify based on the MD5 checksum, and the checksum transfer/read
+ // succeeded, then we need to determine whether to retry or handle it as a failure.
+ if ( firstRun )
+ {
+ retry = true;
+ }
+ else
+ {
+ handleChecksumFailure( checksumPolicy, e.getMessage(), e.getCause() );
+ }
+ }
+ catch ( ResourceDoesNotExistException md5TryException )
+ {
+ // this was a failed transfer, and we don't want to retry.
+ handleChecksumFailure( checksumPolicy, "Error retrieving checksum file for " + remotePath,
+ md5TryException );
+ }
+ }
+
+ // reinstate the download monitor...
+ if ( downloadMonitor != null )
+ {
+ wagon.addTransferListener( downloadMonitor );
+ }
+ }
+
+ // unset the firstRun flag, so we don't get caught in an infinite loop...
+ firstRun = false;
+ }
+ }
+ catch ( ConnectionException e )
+ {
+ throw new TransferFailedException( "Connection failed: " + e.getMessage(), e );
+ }
+ catch ( AuthenticationException e )
+ {
+ throw new TransferFailedException( "Authentication failed: " + e.getMessage(), e );
+ }
+ catch ( AuthorizationException e )
+ {
+ throw new TransferFailedException( "Authorization failed: " + e.getMessage(), e );
+ }
+ finally
+ {
+ // Remove remaining TransferListener instances (checksum handlers removed in above finally clause)
+ if ( downloadMonitor != null )
+ {
+ wagon.removeTransferListener( downloadMonitor );
+ }
+
+ disconnectWagon( wagon );
+
+ releaseWagon( protocol, wagon );
+ }
+
+ if ( downloaded )
+ {
+ if ( !temp.exists() )
+ {
+ throw new ResourceDoesNotExistException( "Downloaded file does not exist: " + temp );
+ }
+
+ // The temporary file is named destination + ".tmp" and is done this way to ensure
+ // that the temporary file is in the same file system as the destination because the
+ // File.renameTo operation doesn't really work across file systems.
+ // So we will attempt to do a File.renameTo for efficiency and atomicity, if this fails
+ // then we will use a brute force copy and delete the temporary file.
+
+ if ( !temp.renameTo( destination ) )
+ {
+ try
+ {
+ FileUtils.copyFile( temp, destination );
+
+ if ( !temp.delete() )
+ {
+ temp.deleteOnExit();
+ }
+ }
+ catch ( IOException e )
+ {
+ throw new TransferFailedException( "Error copying temporary file to the final destination: "
+ + e.getMessage(), e );
+ }
+ }
+ }
+ }
+
+ //
+ // Publisher
+ //
+ @Override
+ public void putArtifact( File source, Artifact artifact, ArtifactRepository deploymentRepository,
+ TransferListener downloadMonitor )
+ throws TransferFailedException
+ {
+ putRemoteFile( deploymentRepository, source, deploymentRepository.pathOf( artifact ), downloadMonitor );
+ }
+
+ @Override
+ public void putArtifactMetadata( File source, ArtifactMetadata artifactMetadata, ArtifactRepository repository )
+ throws TransferFailedException
+ {
+ logger.info( "Uploading " + artifactMetadata );
+ putRemoteFile( repository, source, repository.pathOfRemoteRepositoryMetadata( artifactMetadata ), null );
+ }
+
+ @Override
+ public void putRemoteFile( ArtifactRepository repository, File source, String remotePath,
+ TransferListener downloadMonitor )
+ throws TransferFailedException
+ {
+ String protocol = repository.getProtocol();
+
+ Wagon wagon;
+ try
+ {
+ wagon = getWagon( protocol );
+ }
+ catch ( UnsupportedProtocolException e )
+ {
+ throw new TransferFailedException( "Unsupported Protocol: '" + protocol + "': " + e.getMessage(), e );
+ }
+
+ if ( downloadMonitor != null )
+ {
+ wagon.addTransferListener( downloadMonitor );
+ }
+
+ Map<String, ChecksumObserver> checksums = new HashMap<String, ChecksumObserver>( 2 );
+
+ Map<String, String> sums = new HashMap<String, String>( 2 );
+
+ // TODO: configure these on the repository
+ for ( int i = 0; i < CHECKSUM_IDS.length; i++ )
+ {
+ checksums.put( CHECKSUM_IDS[i], addChecksumObserver( wagon, CHECKSUM_ALGORITHMS[i] ) );
+ }
+
+ List<File> temporaryFiles = new ArrayList<File>();
+
+ try
+ {
+ try
+ {
+ connectWagon( wagon, repository );
+
+ wagon.put( source, remotePath );
+ }
+ finally
+ {
+ if ( downloadMonitor != null )
+ {
+ wagon.removeTransferListener( downloadMonitor );
+ }
+ }
+
+ // Pre-store the checksums as any future puts will overwrite them
+ for ( String extension : checksums.keySet() )
+ {
+ ChecksumObserver observer = checksums.get( extension );
+ sums.put( extension, observer.getActualChecksum() );
+ }
+
+ // We do this in here so we can checksum the artifact metadata too, otherwise it could be metadata itself
+ for ( String extension : checksums.keySet() )
+ {
+ // TODO: shouldn't need a file intermediatary - improve wagon to take a stream
+ File temp = File.createTempFile( "maven-artifact", null );
+ temp.deleteOnExit();
+ FileUtils.fileWrite( temp.getAbsolutePath(), "UTF-8", sums.get( extension ) );
+
+ temporaryFiles.add( temp );
+ wagon.put( temp, remotePath + "." + extension );
+ }
+ }
+ catch ( ConnectionException e )
+ {
+ throw new TransferFailedException( "Connection failed: " + e.getMessage(), e );
+ }
+ catch ( AuthenticationException e )
+ {
+ throw new TransferFailedException( "Authentication failed: " + e.getMessage(), e );
+ }
+ catch ( AuthorizationException e )
+ {
+ throw new TransferFailedException( "Authorization failed: " + e.getMessage(), e );
+ }
+ catch ( ResourceDoesNotExistException e )
+ {
+ throw new TransferFailedException( "Resource to deploy not found: " + e.getMessage(), e );
+ }
+ catch ( IOException e )
+ {
+ throw new TransferFailedException( "Error creating temporary file for deployment: " + e.getMessage(), e );
+ }
+ finally
+ {
+ // MNG-4543
+ cleanupTemporaryFiles( temporaryFiles );
+
+ // Remove every checksum listener
+ for ( String aCHECKSUM_IDS : CHECKSUM_IDS )
+ {
+ TransferListener checksumListener = checksums.get( aCHECKSUM_IDS );
+ if ( checksumListener != null )
+ {
+ wagon.removeTransferListener( checksumListener );
+ }
+ }
+
+ disconnectWagon( wagon );
+
+ releaseWagon( protocol, wagon );
+ }
+ }
+
+ private void cleanupTemporaryFiles( List<File> files )
+ {
+ for ( File file : files )
+ {
+ // really don't care if it failed here only log warning
+ if ( !file.delete() )
+ {
+ logger.warn( "skip failed to delete temporary file : " + file.getAbsolutePath() );
+ file.deleteOnExit();
+ }
+ }
+
+ }
+
+ private ChecksumObserver addChecksumObserver( Wagon wagon, String algorithm )
+ throws TransferFailedException
+ {
+ try
+ {
+ ChecksumObserver checksumObserver = new ChecksumObserver( algorithm );
+ wagon.addTransferListener( checksumObserver );
+ return checksumObserver;
+ }
+ catch ( NoSuchAlgorithmException e )
+ {
+ throw new TransferFailedException( "Unable to add checksum for unsupported algorithm " + algorithm, e );
+ }
+ }
+
+ private void handleChecksumFailure( String checksumPolicy, String message, Throwable cause )
+ throws ChecksumFailedException
+ {
+ if ( ArtifactRepositoryPolicy.CHECKSUM_POLICY_FAIL.equals( checksumPolicy ) )
+ {
+ throw new ChecksumFailedException( message, cause );
+ }
+ else if ( !ArtifactRepositoryPolicy.CHECKSUM_POLICY_IGNORE.equals( checksumPolicy ) )
+ {
+ // warn if it is set to anything other than ignore
+ logger.warn( "*** CHECKSUM FAILED - " + message + " - IGNORING" );
+ }
+ // otherwise it is ignore
+ }
+
+ private void verifyChecksum( ChecksumObserver checksumObserver, File destination, File tempDestination,
+ String remotePath, String checksumFileExtension, Wagon wagon )
+ throws ResourceDoesNotExistException, TransferFailedException, AuthorizationException
+ {
+ try
+ {
+ // grab it first, because it's about to change...
+ String actualChecksum = checksumObserver.getActualChecksum();
+
+ File tempChecksumFile = new File( tempDestination + checksumFileExtension + ".tmp" );
+ tempChecksumFile.deleteOnExit();
+ wagon.get( remotePath + checksumFileExtension, tempChecksumFile );
+
+ String expectedChecksum = FileUtils.fileRead( tempChecksumFile, "UTF-8" );
+
+ // remove whitespaces at the end
+ expectedChecksum = expectedChecksum.trim();
+
+ // check for 'ALGO (name) = CHECKSUM' like used by openssl
+ if ( expectedChecksum.regionMatches( true, 0, "MD", 0, 2 )
+ || expectedChecksum.regionMatches( true, 0, "SHA", 0, 3 ) )
+ {
+ int lastSpacePos = expectedChecksum.lastIndexOf( ' ' );
+ expectedChecksum = expectedChecksum.substring( lastSpacePos + 1 );
+ }
+ else
+ {
+ // remove everything after the first space (if available)
+ int spacePos = expectedChecksum.indexOf( ' ' );
+
+ if ( spacePos != -1 )
+ {
+ expectedChecksum = expectedChecksum.substring( 0, spacePos );
+ }
+ }
+ if ( expectedChecksum.equalsIgnoreCase( actualChecksum ) )
+ {
+ File checksumFile = new File( destination + checksumFileExtension );
+ if ( checksumFile.exists() )
+ {
+ checksumFile.delete(); // ignore if failed as we will overwrite
+ }
+ FileUtils.copyFile( tempChecksumFile, checksumFile );
+ if ( !tempChecksumFile.delete() )
+ {
+ tempChecksumFile.deleteOnExit();
+ }
+ }
+ else
+ {
+ throw new ChecksumFailedException( "Checksum failed on download: local = '" + actualChecksum
+ + "'; remote = '" + expectedChecksum + "'" );
+ }
+ }
+ catch ( IOException e )
+ {
+ throw new ChecksumFailedException( "Invalid checksum file", e );
+ }
+ }
+
+ private void disconnectWagon( Wagon wagon )
+ {
+ try
+ {
+ wagon.disconnect();
+ }
+ catch ( ConnectionException e )
+ {
+ logger.error( "Problem disconnecting from wagon - ignoring: " + e.getMessage() );
+ }
+ }
+
+ private void releaseWagon( String protocol, Wagon wagon )
+ {
+ try
+ {
+ container.release( wagon );
+ }
+ catch ( ComponentLifecycleException e )
+ {
+ logger.error( "Problem releasing wagon - ignoring: " + e.getMessage() );
+ logger.debug( "", e );
+ }
+ }
+
+ @Override
+ @Deprecated
+ public Wagon getWagon( Repository repository )
+ throws UnsupportedProtocolException
+ {
+ return getWagon( repository.getProtocol() );
+ }
+
+ @Override
+ @Deprecated
+ public Wagon getWagon( String protocol )
+ throws UnsupportedProtocolException
+ {
+ if ( protocol == null )
+ {
+ throw new UnsupportedProtocolException( "Unspecified protocol" );
+ }
+
+ String hint = protocol.toLowerCase( java.util.Locale.ENGLISH );
+
+ Wagon wagon;
+ try
+ {
+ wagon = container.lookup( Wagon.class, hint );
+ }
+ catch ( ComponentLookupException e )
+ {
+ throw new UnsupportedProtocolException( "Cannot find wagon which supports the requested protocol: "
+ + protocol, e );
+ }
+
+ return wagon;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/LegacyRepositorySystem.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/LegacyRepositorySystem.java
new file mode 100644
index 00000000..6dd84dbc
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/LegacyRepositorySystem.java
@@ -0,0 +1,906 @@
+package org.apache.maven.repository.legacy;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.maven.RepositoryUtils;
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.InvalidRepositoryException;
+import org.apache.maven.artifact.factory.ArtifactFactory;
+import org.apache.maven.artifact.metadata.ArtifactMetadata;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.repository.legacy.repository.ArtifactRepositoryFactory;
+import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy;
+import org.apache.maven.artifact.repository.Authentication;
+import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout;
+import org.apache.maven.artifact.resolver.ArtifactResolutionRequest;
+import org.apache.maven.artifact.resolver.ArtifactResolutionResult;
+import org.apache.maven.artifact.resolver.ArtifactResolver;
+import org.apache.maven.artifact.resolver.filter.ExcludesArtifactFilter;
+import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
+import org.apache.maven.artifact.versioning.VersionRange;
+import org.apache.maven.model.Dependency;
+import org.apache.maven.model.Exclusion;
+import org.apache.maven.model.Plugin;
+import org.apache.maven.model.Repository;
+import org.apache.maven.model.RepositoryPolicy;
+import org.apache.maven.repository.DelegatingLocalArtifactRepository;
+import org.apache.maven.repository.LocalArtifactRepository;
+import org.apache.maven.repository.ArtifactTransferListener;
+import org.apache.maven.repository.MirrorSelector;
+import org.apache.maven.repository.Proxy;
+import org.apache.maven.repository.RepositorySystem;
+import org.apache.maven.repository.ArtifactDoesNotExistException;
+import org.apache.maven.repository.ArtifactTransferFailedException;
+import org.apache.maven.settings.Mirror;
+import org.apache.maven.settings.Server;
+import org.apache.maven.settings.building.SettingsProblem;
+import org.apache.maven.settings.crypto.DefaultSettingsDecryptionRequest;
+import org.apache.maven.settings.crypto.SettingsDecrypter;
+import org.apache.maven.settings.crypto.SettingsDecryptionRequest;
+import org.apache.maven.settings.crypto.SettingsDecryptionResult;
+import org.apache.maven.wagon.proxy.ProxyInfo;
+import org.apache.maven.wagon.proxy.ProxyUtils;
+import org.codehaus.plexus.PlexusContainer;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
+import org.codehaus.plexus.logging.Logger;
+import org.codehaus.plexus.util.StringUtils;
+import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.repository.AuthenticationContext;
+import org.eclipse.aether.repository.AuthenticationSelector;
+import org.eclipse.aether.repository.ProxySelector;
+import org.eclipse.aether.repository.RemoteRepository;
+
+/**
+ * @author Jason van Zyl
+ */
+@Component( role = RepositorySystem.class, hint = "default" )
+public class LegacyRepositorySystem
+ implements RepositorySystem
+{
+
+ @Requirement
+ private Logger logger;
+
+ @Requirement
+ private ArtifactFactory artifactFactory;
+
+ @Requirement
+ private ArtifactResolver artifactResolver;
+
+ @Requirement
+ private ArtifactRepositoryFactory artifactRepositoryFactory;
+
+ @Requirement( role = ArtifactRepositoryLayout.class )
+ private Map<String, ArtifactRepositoryLayout> layouts;
+
+ @Requirement
+ private WagonManager wagonManager;
+
+ @Requirement
+ private PlexusContainer plexus;
+
+ @Requirement
+ private MirrorSelector mirrorSelector;
+
+ @Requirement
+ private SettingsDecrypter settingsDecrypter;
+
+ public Artifact createArtifact( String groupId, String artifactId, String version, String scope, String type )
+ {
+ return artifactFactory.createArtifact( groupId, artifactId, version, scope, type );
+ }
+
+ public Artifact createArtifact( String groupId, String artifactId, String version, String packaging )
+ {
+ return artifactFactory.createBuildArtifact( groupId, artifactId, version, packaging );
+ }
+
+ public Artifact createArtifactWithClassifier( String groupId, String artifactId, String version, String type,
+ String classifier )
+ {
+ return artifactFactory.createArtifactWithClassifier( groupId, artifactId, version, type, classifier );
+ }
+
+ public Artifact createProjectArtifact( String groupId, String artifactId, String metaVersionId )
+ {
+ return artifactFactory.createProjectArtifact( groupId, artifactId, metaVersionId );
+ }
+
+ public Artifact createDependencyArtifact( Dependency d )
+ {
+ VersionRange versionRange;
+ try
+ {
+ versionRange = VersionRange.createFromVersionSpec( d.getVersion() );
+ }
+ catch ( InvalidVersionSpecificationException e )
+ {
+ return null;
+ }
+
+ Artifact artifact =
+ artifactFactory.createDependencyArtifact( d.getGroupId(), d.getArtifactId(), versionRange, d.getType(),
+ d.getClassifier(), d.getScope(), d.isOptional() );
+
+ if ( Artifact.SCOPE_SYSTEM.equals( d.getScope() ) && d.getSystemPath() != null )
+ {
+ artifact.setFile( new File( d.getSystemPath() ) );
+ }
+
+ if ( !d.getExclusions().isEmpty() )
+ {
+ List<String> exclusions = new ArrayList<String>();
+
+ for ( Exclusion exclusion : d.getExclusions() )
+ {
+ exclusions.add( exclusion.getGroupId() + ':' + exclusion.getArtifactId() );
+ }
+
+ artifact.setDependencyFilter( new ExcludesArtifactFilter( exclusions ) );
+ }
+
+ return artifact;
+ }
+
+ public Artifact createExtensionArtifact( String groupId, String artifactId, String version )
+ {
+ VersionRange versionRange;
+ try
+ {
+ versionRange = VersionRange.createFromVersionSpec( version );
+ }
+ catch ( InvalidVersionSpecificationException e )
+ {
+ return null;
+ }
+
+ return artifactFactory.createExtensionArtifact( groupId, artifactId, versionRange );
+ }
+
+ public Artifact createParentArtifact( String groupId, String artifactId, String version )
+ {
+ return artifactFactory.createParentArtifact( groupId, artifactId, version );
+ }
+
+ public Artifact createPluginArtifact( Plugin plugin )
+ {
+ VersionRange versionRange;
+ try
+ {
+ String version = plugin.getVersion();
+ if ( StringUtils.isEmpty( version ) )
+ {
+ version = "RELEASE";
+ }
+ versionRange = VersionRange.createFromVersionSpec( version );
+ }
+ catch ( InvalidVersionSpecificationException e )
+ {
+ return null;
+ }
+
+ return artifactFactory.createPluginArtifact( plugin.getGroupId(), plugin.getArtifactId(), versionRange );
+ }
+
+ public ArtifactRepositoryPolicy buildArtifactRepositoryPolicy( RepositoryPolicy policy )
+ {
+ boolean enabled = true;
+
+ String updatePolicy = null;
+
+ String checksumPolicy = null;
+
+ if ( policy != null )
+ {
+ enabled = policy.isEnabled();
+
+ if ( policy.getUpdatePolicy() != null )
+ {
+ updatePolicy = policy.getUpdatePolicy();
+ }
+ if ( policy.getChecksumPolicy() != null )
+ {
+ checksumPolicy = policy.getChecksumPolicy();
+ }
+ }
+
+ return new ArtifactRepositoryPolicy( enabled, updatePolicy, checksumPolicy );
+ }
+
+ public ArtifactRepository createDefaultLocalRepository()
+ throws InvalidRepositoryException
+ {
+ return createLocalRepository( RepositorySystem.defaultUserLocalRepository );
+ }
+
+ public ArtifactRepository createLocalRepository( File localRepository )
+ throws InvalidRepositoryException
+ {
+ return createRepository( "file://" + localRepository.toURI().getRawPath(),
+ RepositorySystem.DEFAULT_LOCAL_REPO_ID, true,
+ ArtifactRepositoryPolicy.UPDATE_POLICY_ALWAYS, true,
+ ArtifactRepositoryPolicy.UPDATE_POLICY_ALWAYS,
+ ArtifactRepositoryPolicy.CHECKSUM_POLICY_IGNORE );
+ }
+
+ public ArtifactRepository createDefaultRemoteRepository()
+ throws InvalidRepositoryException
+ {
+ return createRepository( RepositorySystem.DEFAULT_REMOTE_REPO_URL, RepositorySystem.DEFAULT_REMOTE_REPO_ID,
+ true, ArtifactRepositoryPolicy.UPDATE_POLICY_DAILY, false,
+ ArtifactRepositoryPolicy.UPDATE_POLICY_DAILY,
+ ArtifactRepositoryPolicy.CHECKSUM_POLICY_WARN );
+ }
+
+ public ArtifactRepository createLocalRepository( String url, String repositoryId )
+ throws IOException
+ {
+ return createRepository( canonicalFileUrl( url ), repositoryId, true,
+ ArtifactRepositoryPolicy.UPDATE_POLICY_ALWAYS, true,
+ ArtifactRepositoryPolicy.UPDATE_POLICY_ALWAYS,
+ ArtifactRepositoryPolicy.CHECKSUM_POLICY_IGNORE );
+ }
+
+ private String canonicalFileUrl( String url )
+ throws IOException
+ {
+ if ( !url.startsWith( "file:" ) )
+ {
+ url = "file://" + url;
+ }
+ else if ( url.startsWith( "file:" ) && !url.startsWith( "file://" ) )
+ {
+ url = "file://" + url.substring( "file:".length() );
+ }
+
+ // So now we have an url of the form file://<path>
+
+ // We want to eliminate any relative path nonsense and lock down the path so we
+ // need to fully resolve it before any sub-modules use the path. This can happen
+ // when you are using a custom settings.xml that contains a relative path entry
+ // for the local repository setting.
+
+ File localRepository = new File( url.substring( "file://".length() ) );
+
+ if ( !localRepository.isAbsolute() )
+ {
+ url = "file://" + localRepository.getCanonicalPath();
+ }
+
+ return url;
+ }
+
+ public ArtifactResolutionResult resolve( ArtifactResolutionRequest request )
+ {
+ /*
+ * Probably is not worth it, but here I make sure I restore request
+ * to its original state.
+ */
+ try
+ {
+ LocalArtifactRepository ideWorkspace =
+ plexus.lookup( LocalArtifactRepository.class, LocalArtifactRepository.IDE_WORKSPACE );
+
+ if ( request.getLocalRepository() instanceof DelegatingLocalArtifactRepository )
+ {
+ DelegatingLocalArtifactRepository delegatingLocalRepository =
+ (DelegatingLocalArtifactRepository) request.getLocalRepository();
+
+ LocalArtifactRepository orig = delegatingLocalRepository.getIdeWorspace();
+
+ delegatingLocalRepository.setIdeWorkspace( ideWorkspace );
+
+ try
+ {
+ return artifactResolver.resolve( request );
+ }
+ finally
+ {
+ delegatingLocalRepository.setIdeWorkspace( orig );
+ }
+ }
+ else
+ {
+ ArtifactRepository localRepository = request.getLocalRepository();
+ DelegatingLocalArtifactRepository delegatingLocalRepository =
+ new DelegatingLocalArtifactRepository( localRepository );
+ delegatingLocalRepository.setIdeWorkspace( ideWorkspace );
+ request.setLocalRepository( delegatingLocalRepository );
+ try
+ {
+ return artifactResolver.resolve( request );
+ }
+ finally
+ {
+ request.setLocalRepository( localRepository );
+ }
+ }
+ }
+ catch ( ComponentLookupException e )
+ {
+ // no ide workspace artifact resolution
+ }
+
+ return artifactResolver.resolve( request );
+ }
+
+ /*
+ public void addProxy( String protocol, String host, int port, String username, String password, String nonProxyHosts )
+ {
+ ProxyInfo proxyInfo = new ProxyInfo();
+ proxyInfo.setHost( host );
+ proxyInfo.setType( protocol );
+ proxyInfo.setPort( port );
+ proxyInfo.setNonProxyHosts( nonProxyHosts );
+ proxyInfo.setUserName( username );
+ proxyInfo.setPassword( password );
+
+ proxies.put( protocol, proxyInfo );
+
+ wagonManager.addProxy( protocol, host, port, username, password, nonProxyHosts );
+ }
+ */
+
+ public List<ArtifactRepository> getEffectiveRepositories( List<ArtifactRepository> repositories )
+ {
+ if ( repositories == null )
+ {
+ return null;
+ }
+
+ Map<String, List<ArtifactRepository>> reposByKey = new LinkedHashMap<String, List<ArtifactRepository>>();
+
+ for ( ArtifactRepository repository : repositories )
+ {
+ String key = repository.getId();
+
+ List<ArtifactRepository> aliasedRepos = reposByKey.get( key );
+
+ if ( aliasedRepos == null )
+ {
+ aliasedRepos = new ArrayList<ArtifactRepository>();
+ reposByKey.put( key, aliasedRepos );
+ }
+
+ aliasedRepos.add( repository );
+ }
+
+ List<ArtifactRepository> effectiveRepositories = new ArrayList<ArtifactRepository>();
+
+ for ( List<ArtifactRepository> aliasedRepos : reposByKey.values() )
+ {
+ List<ArtifactRepository> mirroredRepos = new ArrayList<ArtifactRepository>();
+
+ List<ArtifactRepositoryPolicy> releasePolicies =
+ new ArrayList<ArtifactRepositoryPolicy>( aliasedRepos.size() );
+
+ for ( ArtifactRepository aliasedRepo : aliasedRepos )
+ {
+ releasePolicies.add( aliasedRepo.getReleases() );
+ mirroredRepos.addAll( aliasedRepo.getMirroredRepositories() );
+ }
+
+ ArtifactRepositoryPolicy releasePolicy = getEffectivePolicy( releasePolicies );
+
+ List<ArtifactRepositoryPolicy> snapshotPolicies =
+ new ArrayList<ArtifactRepositoryPolicy>( aliasedRepos.size() );
+
+ for ( ArtifactRepository aliasedRepo : aliasedRepos )
+ {
+ snapshotPolicies.add( aliasedRepo.getSnapshots() );
+ }
+
+ ArtifactRepositoryPolicy snapshotPolicy = getEffectivePolicy( snapshotPolicies );
+
+ ArtifactRepository aliasedRepo = aliasedRepos.get( 0 );
+
+ ArtifactRepository effectiveRepository =
+ createArtifactRepository( aliasedRepo.getId(), aliasedRepo.getUrl(), aliasedRepo.getLayout(),
+ snapshotPolicy, releasePolicy );
+
+ effectiveRepository.setAuthentication( aliasedRepo.getAuthentication() );
+
+ effectiveRepository.setProxy( aliasedRepo.getProxy() );
+
+ effectiveRepository.setMirroredRepositories( mirroredRepos );
+
+ effectiveRepositories.add( effectiveRepository );
+ }
+
+ return effectiveRepositories;
+ }
+
+ private ArtifactRepositoryPolicy getEffectivePolicy( Collection<ArtifactRepositoryPolicy> policies )
+ {
+ ArtifactRepositoryPolicy effectivePolicy = null;
+
+ for ( ArtifactRepositoryPolicy policy : policies )
+ {
+ if ( effectivePolicy == null )
+ {
+ effectivePolicy = new ArtifactRepositoryPolicy( policy );
+ }
+ else
+ {
+ effectivePolicy.merge( policy );
+ }
+ }
+
+ return effectivePolicy;
+ }
+
+ public Mirror getMirror( ArtifactRepository repository, List<Mirror> mirrors )
+ {
+ return mirrorSelector.getMirror( repository, mirrors );
+ }
+
+ public void injectMirror( List<ArtifactRepository> repositories, List<Mirror> mirrors )
+ {
+ if ( repositories != null && mirrors != null )
+ {
+ for ( ArtifactRepository repository : repositories )
+ {
+ Mirror mirror = getMirror( repository, mirrors );
+ injectMirror( repository, mirror );
+ }
+ }
+ }
+
+ private Mirror getMirror( RepositorySystemSession session, ArtifactRepository repository )
+ {
+ if ( session != null )
+ {
+ org.eclipse.aether.repository.MirrorSelector selector = session.getMirrorSelector();
+ if ( selector != null )
+ {
+ RemoteRepository repo = selector.getMirror( RepositoryUtils.toRepo( repository ) );
+ if ( repo != null )
+ {
+ Mirror mirror = new Mirror();
+ mirror.setId( repo.getId() );
+ mirror.setUrl( repo.getUrl() );
+ mirror.setLayout( repo.getContentType() );
+ return mirror;
+ }
+ }
+ }
+ return null;
+ }
+
+ public void injectMirror( RepositorySystemSession session, List<ArtifactRepository> repositories )
+ {
+ if ( repositories != null && session != null )
+ {
+ for ( ArtifactRepository repository : repositories )
+ {
+ Mirror mirror = getMirror( session, repository );
+ injectMirror( repository, mirror );
+ }
+ }
+ }
+
+ private void injectMirror( ArtifactRepository repository, Mirror mirror )
+ {
+ if ( mirror != null )
+ {
+ ArtifactRepository original =
+ createArtifactRepository( repository.getId(), repository.getUrl(), repository.getLayout(),
+ repository.getSnapshots(), repository.getReleases() );
+
+ repository.setMirroredRepositories( Collections.singletonList( original ) );
+
+ repository.setId( mirror.getId() );
+ repository.setUrl( mirror.getUrl() );
+
+ if ( StringUtils.isNotEmpty( mirror.getLayout() ) )
+ {
+ repository.setLayout( getLayout( mirror.getLayout() ) );
+ }
+ }
+ }
+
+ public void injectAuthentication( List<ArtifactRepository> repositories, List<Server> servers )
+ {
+ if ( repositories != null )
+ {
+ Map<String, Server> serversById = new HashMap<String, Server>();
+
+ if ( servers != null )
+ {
+ for ( Server server : servers )
+ {
+ if ( !serversById.containsKey( server.getId() ) )
+ {
+ serversById.put( server.getId(), server );
+ }
+ }
+ }
+
+ for ( ArtifactRepository repository : repositories )
+ {
+ Server server = serversById.get( repository.getId() );
+
+ if ( server != null )
+ {
+ SettingsDecryptionRequest request = new DefaultSettingsDecryptionRequest( server );
+ SettingsDecryptionResult result = settingsDecrypter.decrypt( request );
+ server = result.getServer();
+
+ if ( logger.isDebugEnabled() )
+ {
+ for ( SettingsProblem problem : result.getProblems() )
+ {
+ logger.debug( problem.getMessage(), problem.getException() );
+ }
+ }
+
+ Authentication authentication = new Authentication( server.getUsername(), server.getPassword() );
+ authentication.setPrivateKey( server.getPrivateKey() );
+ authentication.setPassphrase( server.getPassphrase() );
+
+ repository.setAuthentication( authentication );
+ }
+ else
+ {
+ repository.setAuthentication( null );
+ }
+ }
+ }
+ }
+
+ private Authentication getAuthentication( RepositorySystemSession session, ArtifactRepository repository )
+ {
+ if ( session != null )
+ {
+ AuthenticationSelector selector = session.getAuthenticationSelector();
+ if ( selector != null )
+ {
+ RemoteRepository repo = RepositoryUtils.toRepo( repository );
+ org.eclipse.aether.repository.Authentication auth = selector.getAuthentication( repo );
+ if ( auth != null )
+ {
+ repo = new RemoteRepository.Builder( repo ).setAuthentication( auth ).build();
+ AuthenticationContext authCtx = AuthenticationContext.forRepository( session, repo );
+ Authentication result =
+ new Authentication( authCtx.get( AuthenticationContext.USERNAME ),
+ authCtx.get( AuthenticationContext.PASSWORD ) );
+ result.setPrivateKey( authCtx.get( AuthenticationContext.PRIVATE_KEY_PATH ) );
+ result.setPassphrase( authCtx.get( AuthenticationContext.PRIVATE_KEY_PASSPHRASE ) );
+ authCtx.close();
+ return result;
+ }
+ }
+ }
+ return null;
+ }
+
+ public void injectAuthentication( RepositorySystemSession session, List<ArtifactRepository> repositories )
+ {
+ if ( repositories != null && session != null )
+ {
+ for ( ArtifactRepository repository : repositories )
+ {
+ repository.setAuthentication( getAuthentication( session, repository ) );
+ }
+ }
+ }
+
+ private org.apache.maven.settings.Proxy getProxy( ArtifactRepository repository,
+ List<org.apache.maven.settings.Proxy> proxies )
+ {
+ if ( proxies != null && repository.getProtocol() != null )
+ {
+ for ( org.apache.maven.settings.Proxy proxy : proxies )
+ {
+ if ( proxy.isActive() && repository.getProtocol().equalsIgnoreCase( proxy.getProtocol() ) )
+ {
+ if ( StringUtils.isNotEmpty( proxy.getNonProxyHosts() ) )
+ {
+ ProxyInfo pi = new ProxyInfo();
+ pi.setNonProxyHosts( proxy.getNonProxyHosts() );
+
+ org.apache.maven.wagon.repository.Repository repo =
+ new org.apache.maven.wagon.repository.Repository( repository.getId(), repository.getUrl() );
+
+ if ( !ProxyUtils.validateNonProxyHosts( pi, repo.getHost() ) )
+ {
+ return proxy;
+ }
+ }
+ else
+ {
+ return proxy;
+ }
+ }
+ }
+ }
+
+ return null;
+ }
+
+ public void injectProxy( List<ArtifactRepository> repositories, List<org.apache.maven.settings.Proxy> proxies )
+ {
+ if ( repositories != null )
+ {
+ for ( ArtifactRepository repository : repositories )
+ {
+ org.apache.maven.settings.Proxy proxy = getProxy( repository, proxies );
+
+ if ( proxy != null )
+ {
+ SettingsDecryptionRequest request = new DefaultSettingsDecryptionRequest( proxy );
+ SettingsDecryptionResult result = settingsDecrypter.decrypt( request );
+ proxy = result.getProxy();
+
+ if ( logger.isDebugEnabled() )
+ {
+ for ( SettingsProblem problem : result.getProblems() )
+ {
+ logger.debug( problem.getMessage(), problem.getException() );
+ }
+ }
+
+ Proxy p = new Proxy();
+ p.setHost( proxy.getHost() );
+ p.setProtocol( proxy.getProtocol() );
+ p.setPort( proxy.getPort() );
+ p.setNonProxyHosts( proxy.getNonProxyHosts() );
+ p.setUserName( proxy.getUsername() );
+ p.setPassword( proxy.getPassword() );
+
+ repository.setProxy( p );
+ }
+ else
+ {
+ repository.setProxy( null );
+ }
+ }
+ }
+ }
+
+ private Proxy getProxy( RepositorySystemSession session, ArtifactRepository repository )
+ {
+ if ( session != null )
+ {
+ ProxySelector selector = session.getProxySelector();
+ if ( selector != null )
+ {
+ RemoteRepository repo = RepositoryUtils.toRepo( repository );
+ org.eclipse.aether.repository.Proxy proxy = selector.getProxy( repo );
+ if ( proxy != null )
+ {
+ Proxy p = new Proxy();
+ p.setHost( proxy.getHost() );
+ p.setProtocol( proxy.getType() );
+ p.setPort( proxy.getPort() );
+ if ( proxy.getAuthentication() != null )
+ {
+ repo = new RemoteRepository.Builder( repo ).setProxy( proxy ).build();
+ AuthenticationContext authCtx = AuthenticationContext.forProxy( session, repo );
+ p.setUserName( authCtx.get( AuthenticationContext.USERNAME ) );
+ p.setPassword( authCtx.get( AuthenticationContext.PASSWORD ) );
+ p.setNtlmDomain( authCtx.get( AuthenticationContext.NTLM_DOMAIN ) );
+ p.setNtlmHost( authCtx.get( AuthenticationContext.NTLM_WORKSTATION ) );
+ authCtx.close();
+ }
+ return p;
+ }
+ }
+ }
+ return null;
+ }
+
+ public void injectProxy( RepositorySystemSession session, List<ArtifactRepository> repositories )
+ {
+ if ( repositories != null && session != null )
+ {
+ for ( ArtifactRepository repository : repositories )
+ {
+ repository.setProxy( getProxy( session, repository ) );
+ }
+ }
+ }
+
+ public void retrieve( ArtifactRepository repository, File destination, String remotePath,
+ ArtifactTransferListener transferListener )
+ throws ArtifactTransferFailedException, ArtifactDoesNotExistException
+ {
+ try
+ {
+ wagonManager.getRemoteFile( repository, destination, remotePath,
+ TransferListenerAdapter.newAdapter( transferListener ),
+ ArtifactRepositoryPolicy.CHECKSUM_POLICY_WARN, true );
+ }
+ catch ( org.apache.maven.wagon.TransferFailedException e )
+ {
+ throw new ArtifactTransferFailedException( getMessage( e, "Error transferring artifact." ), e );
+ }
+ catch ( org.apache.maven.wagon.ResourceDoesNotExistException e )
+ {
+ throw new ArtifactDoesNotExistException( getMessage( e, "Requested artifact does not exist." ), e );
+ }
+ }
+
+ public void publish( ArtifactRepository repository, File source, String remotePath,
+ ArtifactTransferListener transferListener )
+ throws ArtifactTransferFailedException
+ {
+ try
+ {
+ wagonManager.putRemoteFile( repository, source, remotePath,
+ TransferListenerAdapter.newAdapter( transferListener ) );
+ }
+ catch ( org.apache.maven.wagon.TransferFailedException e )
+ {
+ throw new ArtifactTransferFailedException( getMessage( e, "Error transferring artifact." ), e );
+ }
+ }
+
+ //
+ // Artifact Repository Creation
+ //
+ public ArtifactRepository buildArtifactRepository( Repository repo )
+ throws InvalidRepositoryException
+ {
+ if ( repo != null )
+ {
+ String id = repo.getId();
+
+ if ( StringUtils.isEmpty( id ) )
+ {
+ throw new InvalidRepositoryException( "Repository identifier missing", "" );
+ }
+
+ String url = repo.getUrl();
+
+ if ( StringUtils.isEmpty( url ) )
+ {
+ throw new InvalidRepositoryException( "URL missing for repository " + id, id );
+ }
+
+ ArtifactRepositoryPolicy snapshots = buildArtifactRepositoryPolicy( repo.getSnapshots() );
+
+ ArtifactRepositoryPolicy releases = buildArtifactRepositoryPolicy( repo.getReleases() );
+
+ return createArtifactRepository( id, url, getLayout( repo.getLayout() ), snapshots, releases );
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ private ArtifactRepository createRepository( String url, String repositoryId, boolean releases,
+ String releaseUpdates, boolean snapshots, String snapshotUpdates,
+ String checksumPolicy )
+ {
+ ArtifactRepositoryPolicy snapshotsPolicy =
+ new ArtifactRepositoryPolicy( snapshots, snapshotUpdates, checksumPolicy );
+
+ ArtifactRepositoryPolicy releasesPolicy =
+ new ArtifactRepositoryPolicy( releases, releaseUpdates, checksumPolicy );
+
+ return createArtifactRepository( repositoryId, url, null, snapshotsPolicy, releasesPolicy );
+ }
+
+ public ArtifactRepository createArtifactRepository( String repositoryId, String url,
+ ArtifactRepositoryLayout repositoryLayout,
+ ArtifactRepositoryPolicy snapshots,
+ ArtifactRepositoryPolicy releases )
+ {
+ if ( repositoryLayout == null )
+ {
+ repositoryLayout = layouts.get( "default" );
+ }
+
+ ArtifactRepository artifactRepository =
+ artifactRepositoryFactory.createArtifactRepository( repositoryId, url, repositoryLayout, snapshots,
+ releases );
+
+ return artifactRepository;
+ }
+
+ private static String getMessage( Throwable error, String def )
+ {
+ if ( error == null )
+ {
+ return def;
+ }
+ String msg = error.getMessage();
+ if ( StringUtils.isNotEmpty( msg ) )
+ {
+ return msg;
+ }
+ return getMessage( error.getCause(), def );
+ }
+
+ private ArtifactRepositoryLayout getLayout( String id )
+ {
+ ArtifactRepositoryLayout layout = layouts.get( id );
+
+ if ( layout == null )
+ {
+ layout = new UnknownRepositoryLayout( id, layouts.get( "default" ) );
+ }
+
+ return layout;
+ }
+
+ /**
+ * In the future, the legacy system might encounter repository types for which no layout components exists because
+ * the actual communication with the repository happens via a repository connector. As a minimum, the legacy system
+ * needs to retain the id of this layout so that the content type of the remote repository can still be accurately
+ * described.
+ */
+ static class UnknownRepositoryLayout
+ implements ArtifactRepositoryLayout
+ {
+
+ private final String id;
+
+ private final ArtifactRepositoryLayout fallback;
+
+ public UnknownRepositoryLayout( String id, ArtifactRepositoryLayout fallback )
+ {
+ this.id = id;
+ this.fallback = fallback;
+ }
+
+ public String getId()
+ {
+ return id;
+ }
+
+ public String pathOf( Artifact artifact )
+ {
+ return fallback.pathOf( artifact );
+ }
+
+ public String pathOfLocalRepositoryMetadata( ArtifactMetadata metadata, ArtifactRepository repository )
+ {
+ return fallback.pathOfLocalRepositoryMetadata( metadata, repository );
+ }
+
+ public String pathOfRemoteRepositoryMetadata( ArtifactMetadata metadata )
+ {
+ return fallback.pathOfRemoteRepositoryMetadata( metadata );
+ }
+
+ @Override
+ public String toString()
+ {
+ return getId();
+ }
+
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/MavenArtifact.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/MavenArtifact.java
new file mode 100644
index 00000000..29b9b82d
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/MavenArtifact.java
@@ -0,0 +1,96 @@
+package org.apache.maven.repository.legacy;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.repository.ArtifactTransferResource;
+import org.apache.maven.wagon.resource.Resource;
+
+class MavenArtifact
+ implements ArtifactTransferResource
+{
+
+ private String repositoryUrl;
+
+ private Resource resource;
+
+ private long transferStartTime;
+
+ public MavenArtifact( String repositoryUrl, Resource resource )
+ {
+ if ( repositoryUrl == null )
+ {
+ this.repositoryUrl = "";
+ }
+ else if ( !repositoryUrl.endsWith( "/" ) && repositoryUrl.length() > 0 )
+ {
+ this.repositoryUrl = repositoryUrl + '/';
+ }
+ else
+ {
+ this.repositoryUrl = repositoryUrl;
+ }
+ this.resource = resource;
+
+ this.transferStartTime = System.currentTimeMillis();
+ }
+
+ public String getRepositoryUrl()
+ {
+ return repositoryUrl;
+ }
+
+ public String getName()
+ {
+ String name = resource.getName();
+
+ if ( name == null )
+ {
+ name = "";
+ }
+ else if ( name.startsWith( "/" ) )
+ {
+ name = name.substring( 1 );
+ }
+
+ return name;
+ }
+
+ public String getUrl()
+ {
+ return getRepositoryUrl() + getName();
+ }
+
+ public long getContentLength()
+ {
+ return resource.getContentLength();
+ }
+
+ public long getTransferStartTime()
+ {
+ return transferStartTime;
+ }
+
+ @Override
+ public String toString()
+ {
+ return getUrl();
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/TransferListenerAdapter.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/TransferListenerAdapter.java
new file mode 100644
index 00000000..b20bd72b
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/TransferListenerAdapter.java
@@ -0,0 +1,187 @@
+package org.apache.maven.repository.legacy;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.IdentityHashMap;
+import java.util.Map;
+
+import org.apache.maven.repository.ArtifactTransferEvent;
+import org.apache.maven.repository.ArtifactTransferListener;
+import org.apache.maven.repository.ArtifactTransferResource;
+import org.apache.maven.wagon.events.TransferEvent;
+import org.apache.maven.wagon.events.TransferListener;
+import org.apache.maven.wagon.repository.Repository;
+import org.apache.maven.wagon.resource.Resource;
+
+public class TransferListenerAdapter
+ implements TransferListener
+{
+
+ private final ArtifactTransferListener listener;
+
+ private final Map<Resource, ArtifactTransferResource> artifacts;
+
+ private final Map<Resource, Long> transfers;
+
+ public static TransferListener newAdapter( ArtifactTransferListener listener )
+ {
+ if ( listener == null )
+ {
+ return null;
+ }
+ else
+ {
+ return new TransferListenerAdapter( listener );
+ }
+ }
+
+ private TransferListenerAdapter( ArtifactTransferListener listener )
+ {
+ this.listener = listener;
+ this.artifacts = new IdentityHashMap<Resource, ArtifactTransferResource>();
+ this.transfers = new IdentityHashMap<Resource, Long>();
+ }
+
+ public void debug( String message )
+ {
+ }
+
+ public void transferCompleted( TransferEvent transferEvent )
+ {
+ ArtifactTransferEvent event = wrap( transferEvent );
+
+ Long transferred;
+ synchronized ( transfers )
+ {
+ transferred = transfers.remove( transferEvent.getResource() );
+ }
+ if ( transferred != null )
+ {
+ event.setTransferredBytes( transferred );
+ }
+
+ synchronized ( artifacts )
+ {
+ artifacts.remove( transferEvent.getResource() );
+ }
+
+ listener.transferCompleted( event );
+ }
+
+ public void transferError( TransferEvent transferEvent )
+ {
+ synchronized ( transfers )
+ {
+ transfers.remove( transferEvent.getResource() );
+ }
+ synchronized ( artifacts )
+ {
+ artifacts.remove( transferEvent.getResource() );
+ }
+ }
+
+ public void transferInitiated( TransferEvent transferEvent )
+ {
+ listener.transferInitiated( wrap( transferEvent ) );
+ }
+
+ public void transferProgress( TransferEvent transferEvent, byte[] buffer, int length )
+ {
+ Long transferred;
+ synchronized ( transfers )
+ {
+ transferred = transfers.get( transferEvent.getResource() );
+ if ( transferred == null )
+ {
+ transferred = (long) length;
+ }
+ else
+ {
+ transferred = transferred + length;
+ }
+ transfers.put( transferEvent.getResource(), transferred );
+ }
+
+ ArtifactTransferEvent event = wrap( transferEvent );
+ event.setDataBuffer( buffer );
+ event.setDataOffset( 0 );
+ event.setDataLength( length );
+ event.setTransferredBytes( transferred );
+
+ listener.transferProgress( event );
+ }
+
+ public void transferStarted( TransferEvent transferEvent )
+ {
+ listener.transferStarted( wrap( transferEvent ) );
+ }
+
+ private ArtifactTransferEvent wrap( TransferEvent event )
+ {
+ if ( event == null )
+ {
+ return null;
+ }
+ else
+ {
+ String wagon = event.getWagon().getClass().getName();
+
+ ArtifactTransferResource artifact = wrap( event.getWagon().getRepository(), event.getResource() );
+
+ ArtifactTransferEvent evt;
+ if ( event.getException() != null )
+ {
+ evt = new ArtifactTransferEvent( wagon, event.getException(), event.getRequestType(), artifact );
+ }
+ else
+ {
+ evt = new ArtifactTransferEvent( wagon, event.getEventType(), event.getRequestType(), artifact );
+ }
+
+ evt.setLocalFile( event.getLocalFile() );
+
+ return evt;
+ }
+ }
+
+ private ArtifactTransferResource wrap( Repository repository, Resource resource )
+ {
+ if ( resource == null )
+ {
+ return null;
+ }
+ else
+ {
+ synchronized ( artifacts )
+ {
+ ArtifactTransferResource artifact = artifacts.get( resource );
+
+ if ( artifact == null )
+ {
+ artifact = new MavenArtifact( repository.getUrl(), resource );
+ artifacts.put( resource, artifact );
+ }
+
+ return artifact;
+ }
+ }
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/UpdateCheckManager.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/UpdateCheckManager.java
new file mode 100644
index 00000000..f4e969b6
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/UpdateCheckManager.java
@@ -0,0 +1,41 @@
+package org.apache.maven.repository.legacy;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.repository.metadata.RepositoryMetadata;
+
+public interface UpdateCheckManager
+{
+
+ boolean isUpdateRequired( Artifact artifact, ArtifactRepository repository );
+
+ void touch( Artifact artifact, ArtifactRepository repository, String error );
+
+ String getError( Artifact artifact, ArtifactRepository repository );
+
+ boolean isUpdateRequired( RepositoryMetadata metadata, ArtifactRepository repository, File file );
+
+ void touch( RepositoryMetadata metadata, ArtifactRepository repository, File file );
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/WagonConfigurationException.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/WagonConfigurationException.java
new file mode 100644
index 00000000..078de00c
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/WagonConfigurationException.java
@@ -0,0 +1,63 @@
+package org.apache.maven.repository.legacy;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.wagon.TransferFailedException;
+
+
+public class WagonConfigurationException
+ extends TransferFailedException
+{
+
+ static final long serialVersionUID = 1;
+
+ private final String originalMessage;
+ private final String repositoryId;
+
+ public WagonConfigurationException( String repositoryId,
+ String message,
+ Throwable cause )
+ {
+ super( "While configuring wagon for \'" + repositoryId + "\': " + message, cause );
+
+ this.repositoryId = repositoryId;
+ this.originalMessage = message;
+ }
+
+ public WagonConfigurationException( String repositoryId,
+ String message )
+ {
+ super( "While configuring wagon for \'" + repositoryId + "\': " + message );
+
+ this.repositoryId = repositoryId;
+ this.originalMessage = message;
+ }
+
+ public final String getRepositoryId()
+ {
+ return repositoryId;
+ }
+
+ public final String getOriginalMessage()
+ {
+ return originalMessage;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/WagonManager.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/WagonManager.java
new file mode 100644
index 00000000..73ead269
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/WagonManager.java
@@ -0,0 +1,79 @@
+package org.apache.maven.repository.legacy;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.util.List;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.metadata.ArtifactMetadata;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.wagon.ResourceDoesNotExistException;
+import org.apache.maven.wagon.TransferFailedException;
+import org.apache.maven.wagon.UnsupportedProtocolException;
+import org.apache.maven.wagon.Wagon;
+import org.apache.maven.wagon.events.TransferListener;
+import org.apache.maven.wagon.repository.Repository;
+
+public interface WagonManager
+{
+ @Deprecated
+ Wagon getWagon( String protocol )
+ throws UnsupportedProtocolException;
+
+ @Deprecated
+ Wagon getWagon( Repository repository )
+ throws UnsupportedProtocolException, WagonConfigurationException;
+
+ //
+ // Retriever
+ //
+ void getArtifact( Artifact artifact, ArtifactRepository repository, TransferListener transferListener, boolean force )
+ throws TransferFailedException, ResourceDoesNotExistException;
+
+ void getArtifact( Artifact artifact, List<ArtifactRepository> remoteRepositories,
+ TransferListener transferListener, boolean force )
+ throws TransferFailedException, ResourceDoesNotExistException;
+
+ void getRemoteFile( ArtifactRepository repository, File destination, String remotePath,
+ TransferListener downloadMonitor, String checksumPolicy, boolean force )
+ throws TransferFailedException, ResourceDoesNotExistException;
+
+ void getArtifactMetadata( ArtifactMetadata metadata, ArtifactRepository remoteRepository, File destination,
+ String checksumPolicy )
+ throws TransferFailedException, ResourceDoesNotExistException;
+
+ void getArtifactMetadataFromDeploymentRepository( ArtifactMetadata metadata, ArtifactRepository remoteRepository,
+ File file, String checksumPolicyWarn )
+ throws TransferFailedException, ResourceDoesNotExistException;
+
+ //
+ // Deployer
+ //
+ void putArtifact( File source, Artifact artifact, ArtifactRepository deploymentRepository,
+ TransferListener downloadMonitor )
+ throws TransferFailedException;
+
+ void putRemoteFile( ArtifactRepository repository, File source, String remotePath, TransferListener downloadMonitor )
+ throws TransferFailedException;
+
+ void putArtifactMetadata( File source, ArtifactMetadata artifactMetadata, ArtifactRepository repository )
+ throws TransferFailedException;
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/repository/ArtifactRepositoryFactory.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/repository/ArtifactRepositoryFactory.java
new file mode 100644
index 00000000..b982f917
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/repository/ArtifactRepositoryFactory.java
@@ -0,0 +1,56 @@
+package org.apache.maven.repository.legacy.repository;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.artifact.UnknownRepositoryLayoutException;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy;
+import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout;
+
+/** @author jdcasey */
+public interface ArtifactRepositoryFactory
+{
+
+ String DEFAULT_LAYOUT_ID = "default";
+
+ String LOCAL_REPOSITORY_ID = "local";
+
+ @Deprecated
+ ArtifactRepositoryLayout getLayout( String layoutId )
+ throws UnknownRepositoryLayoutException;
+
+ @Deprecated
+ ArtifactRepository createDeploymentArtifactRepository( String id, String url, String layoutId, boolean uniqueVersion )
+ throws UnknownRepositoryLayoutException;
+
+ ArtifactRepository createDeploymentArtifactRepository( String id, String url, ArtifactRepositoryLayout layout,
+ boolean uniqueVersion );
+
+ ArtifactRepository createArtifactRepository( String id, String url, String layoutId,
+ ArtifactRepositoryPolicy snapshots, ArtifactRepositoryPolicy releases )
+ throws UnknownRepositoryLayoutException;
+
+ ArtifactRepository createArtifactRepository( String id, String url, ArtifactRepositoryLayout repositoryLayout,
+ ArtifactRepositoryPolicy snapshots, ArtifactRepositoryPolicy releases );
+
+ void setGlobalUpdatePolicy( String snapshotPolicy );
+
+ void setGlobalChecksumPolicy( String checksumPolicy );
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/repository/DefaultArtifactRepositoryFactory.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/repository/DefaultArtifactRepositoryFactory.java
new file mode 100644
index 00000000..4bc91167
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/repository/DefaultArtifactRepositoryFactory.java
@@ -0,0 +1,144 @@
+package org.apache.maven.repository.legacy.repository;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Map;
+
+import org.apache.maven.artifact.UnknownRepositoryLayoutException;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy;
+import org.apache.maven.artifact.repository.MavenArtifactRepository;
+import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout;
+import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout2;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+
+/**
+ * @author jdcasey
+ */
+@Component( role = ArtifactRepositoryFactory.class )
+public class DefaultArtifactRepositoryFactory
+ implements ArtifactRepositoryFactory
+{
+ // TODO: use settings?
+ private String globalUpdatePolicy;
+
+ private String globalChecksumPolicy;
+
+ @Requirement( role = ArtifactRepositoryLayout.class )
+ private Map<String, ArtifactRepositoryLayout> repositoryLayouts;
+
+ public ArtifactRepositoryLayout getLayout( String layoutId )
+ throws UnknownRepositoryLayoutException
+ {
+ return repositoryLayouts.get( layoutId );
+ }
+
+ public ArtifactRepository createDeploymentArtifactRepository( String id, String url, String layoutId,
+ boolean uniqueVersion )
+ throws UnknownRepositoryLayoutException
+ {
+ ArtifactRepositoryLayout layout = repositoryLayouts.get( layoutId );
+
+ checkLayout( id, layoutId, layout );
+
+ return createDeploymentArtifactRepository( id, url, layout, uniqueVersion );
+ }
+
+ private void checkLayout( String repositoryId, String layoutId, ArtifactRepositoryLayout layout )
+ throws UnknownRepositoryLayoutException
+ {
+ if ( layout == null )
+ {
+ throw new UnknownRepositoryLayoutException( repositoryId, layoutId );
+ }
+ }
+
+ public ArtifactRepository createDeploymentArtifactRepository( String id, String url,
+ ArtifactRepositoryLayout repositoryLayout,
+ boolean uniqueVersion )
+ {
+ return createArtifactRepository( id, url, repositoryLayout, null, null );
+ }
+
+ public ArtifactRepository createArtifactRepository( String id, String url, String layoutId,
+ ArtifactRepositoryPolicy snapshots,
+ ArtifactRepositoryPolicy releases )
+ throws UnknownRepositoryLayoutException
+ {
+ ArtifactRepositoryLayout layout = repositoryLayouts.get( layoutId );
+
+ checkLayout( id, layoutId, layout );
+
+ return createArtifactRepository( id, url, layout, snapshots, releases );
+ }
+
+ public ArtifactRepository createArtifactRepository( String id, String url,
+ ArtifactRepositoryLayout repositoryLayout,
+ ArtifactRepositoryPolicy snapshots,
+ ArtifactRepositoryPolicy releases )
+ {
+ if ( snapshots == null )
+ {
+ snapshots = new ArtifactRepositoryPolicy();
+ }
+
+ if ( releases == null )
+ {
+ releases = new ArtifactRepositoryPolicy();
+ }
+
+ if ( globalUpdatePolicy != null )
+ {
+ snapshots.setUpdatePolicy( globalUpdatePolicy );
+ releases.setUpdatePolicy( globalUpdatePolicy );
+ }
+
+ if ( globalChecksumPolicy != null )
+ {
+ snapshots.setChecksumPolicy( globalChecksumPolicy );
+ releases.setChecksumPolicy( globalChecksumPolicy );
+ }
+
+ ArtifactRepository repository;
+ if ( repositoryLayout instanceof ArtifactRepositoryLayout2 )
+ {
+ repository =
+ ( (ArtifactRepositoryLayout2) repositoryLayout ).newMavenArtifactRepository( id, url, snapshots,
+ releases );
+ }
+ else
+ {
+ repository = new MavenArtifactRepository( id, url, repositoryLayout, snapshots, releases );
+ }
+
+ return repository;
+ }
+
+ public void setGlobalUpdatePolicy( String updatePolicy )
+ {
+ globalUpdatePolicy = updatePolicy;
+ }
+
+ public void setGlobalChecksumPolicy( String checksumPolicy )
+ {
+ globalChecksumPolicy = checksumPolicy;
+ }
+ }
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/resolver/DefaultLegacyArtifactCollector.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/resolver/DefaultLegacyArtifactCollector.java
new file mode 100644
index 00000000..f734416b
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/resolver/DefaultLegacyArtifactCollector.java
@@ -0,0 +1,796 @@
+package org.apache.maven.repository.legacy.resolver;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
+import org.apache.maven.artifact.metadata.ResolutionGroup;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.resolver.ArtifactResolutionException;
+import org.apache.maven.artifact.resolver.ArtifactResolutionRequest;
+import org.apache.maven.artifact.resolver.ArtifactResolutionResult;
+import org.apache.maven.artifact.resolver.CyclicDependencyException;
+import org.apache.maven.artifact.resolver.ResolutionListener;
+import org.apache.maven.artifact.resolver.ResolutionListenerForDepMgmt;
+import org.apache.maven.artifact.resolver.ResolutionNode;
+import org.apache.maven.artifact.resolver.filter.AndArtifactFilter;
+import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
+import org.apache.maven.artifact.versioning.ArtifactVersion;
+import org.apache.maven.artifact.versioning.ManagedVersionMap;
+import org.apache.maven.artifact.versioning.OverConstrainedVersionException;
+import org.apache.maven.artifact.versioning.VersionRange;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.plugin.LegacySupport;
+import org.apache.maven.repository.legacy.metadata.ArtifactMetadataRetrievalException;
+import org.apache.maven.repository.legacy.metadata.DefaultMetadataResolutionRequest;
+import org.apache.maven.repository.legacy.metadata.MetadataResolutionRequest;
+import org.apache.maven.repository.legacy.resolver.conflict.ConflictResolver;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+import org.codehaus.plexus.logging.Logger;
+
+/**
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ * @author Jason van Zyl
+ */
+@Component( role = LegacyArtifactCollector.class )
+public class DefaultLegacyArtifactCollector
+ implements LegacyArtifactCollector
+{
+ @Requirement( hint = "nearest" )
+ private ConflictResolver defaultConflictResolver;
+
+ @Requirement
+ private Logger logger;
+
+ @Requirement
+ private LegacySupport legacySupport;
+
+ private void injectSession( ArtifactResolutionRequest request )
+ {
+ MavenSession session = legacySupport.getSession();
+
+ if ( session != null )
+ {
+ request.setOffline( session.isOffline() );
+ request.setForceUpdate( session.getRequest().isUpdateSnapshots() );
+ request.setServers( session.getRequest().getServers() );
+ request.setMirrors( session.getRequest().getMirrors() );
+ request.setProxies( session.getRequest().getProxies() );
+ }
+ }
+
+ public ArtifactResolutionResult collect( Set<Artifact> artifacts, Artifact originatingArtifact,
+ Map managedVersions, ArtifactRepository localRepository,
+ List<ArtifactRepository> remoteRepositories,
+ ArtifactMetadataSource source, ArtifactFilter filter,
+ List<ResolutionListener> listeners,
+ List<ConflictResolver> conflictResolvers )
+ {
+ ArtifactResolutionRequest request = new ArtifactResolutionRequest();
+ request.setLocalRepository( localRepository );
+ request.setRemoteRepositories( remoteRepositories );
+ injectSession( request );
+ return collect( artifacts, originatingArtifact, managedVersions, request, source, filter, listeners,
+ conflictResolvers );
+ }
+
+ public ArtifactResolutionResult collect( Set<Artifact> artifacts, Artifact originatingArtifact,
+ Map managedVersions, ArtifactResolutionRequest repositoryRequest,
+ ArtifactMetadataSource source, ArtifactFilter filter,
+ List<ResolutionListener> listeners,
+ List<ConflictResolver> conflictResolvers )
+ {
+ ArtifactResolutionResult result = new ArtifactResolutionResult();
+
+ result.setOriginatingArtifact( originatingArtifact );
+
+ if ( conflictResolvers == null )
+ {
+ conflictResolvers = Collections.singletonList( defaultConflictResolver );
+ }
+
+ Map<Object, List<ResolutionNode>> resolvedArtifacts = new LinkedHashMap<Object, List<ResolutionNode>>();
+
+ ResolutionNode root = new ResolutionNode( originatingArtifact, repositoryRequest.getRemoteRepositories() );
+
+ try
+ {
+ root.addDependencies( artifacts, repositoryRequest.getRemoteRepositories(), filter );
+ }
+ catch ( CyclicDependencyException e )
+ {
+ result.addCircularDependencyException( e );
+
+ return result;
+ }
+ catch ( OverConstrainedVersionException e )
+ {
+ result.addVersionRangeViolation( e );
+
+ return result;
+ }
+
+ ManagedVersionMap versionMap = getManagedVersionsMap( originatingArtifact, managedVersions );
+
+ try
+ {
+ recurse( result, root, resolvedArtifacts, versionMap, repositoryRequest, source, filter, listeners,
+ conflictResolvers );
+ }
+ catch ( CyclicDependencyException e )
+ {
+ logger.debug( "While recursing: " + e.getMessage(), e );
+ result.addCircularDependencyException( e );
+ }
+ catch ( OverConstrainedVersionException e )
+ {
+ logger.debug( "While recursing: " + e.getMessage(), e );
+ result.addVersionRangeViolation( e );
+ }
+ catch ( ArtifactResolutionException e )
+ {
+ logger.debug( "While recursing: " + e.getMessage(), e );
+ result.addErrorArtifactException( e );
+ }
+
+ Set<ResolutionNode> set = new LinkedHashSet<ResolutionNode>();
+
+ for ( List<ResolutionNode> nodes : resolvedArtifacts.values() )
+ {
+ for ( ResolutionNode node : nodes )
+ {
+ if ( !node.equals( root ) && node.isActive() )
+ {
+ Artifact artifact = node.getArtifact();
+
+ try
+ {
+ if ( node.filterTrail( filter ) )
+ {
+ // If it was optional and not a direct dependency,
+ // we don't add it or its children, just allow the update of the version and artifactScope
+ if ( node.isChildOfRootNode() || !artifact.isOptional() )
+ {
+ artifact.setDependencyTrail( node.getDependencyTrail() );
+
+ set.add( node );
+
+ // This is required right now.
+ result.addArtifact( artifact );
+ }
+ }
+ }
+ catch ( OverConstrainedVersionException e )
+ {
+ result.addVersionRangeViolation( e );
+ }
+ }
+ }
+ }
+
+ result.setArtifactResolutionNodes( set );
+
+ return result;
+ }
+
+ /**
+ * Get the map of managed versions, removing the originating artifact if it is also in managed versions
+ *
+ * @param originatingArtifact artifact we are processing
+ * @param managedVersions original managed versions
+ */
+ private ManagedVersionMap getManagedVersionsMap( Artifact originatingArtifact, Map managedVersions )
+ {
+ ManagedVersionMap versionMap;
+ if ( ( managedVersions != null ) && ( managedVersions instanceof ManagedVersionMap ) )
+ {
+ versionMap = (ManagedVersionMap) managedVersions;
+ }
+ else
+ {
+ versionMap = new ManagedVersionMap( managedVersions );
+ }
+
+ /* remove the originating artifact if it is also in managed versions to avoid being modified during resolution */
+ Artifact managedOriginatingArtifact = versionMap.get( originatingArtifact.getDependencyConflictId() );
+
+ if ( managedOriginatingArtifact != null )
+ {
+ // TODO we probably want to warn the user that he is building an artifact with
+ // different values than in dependencyManagement
+ if ( managedVersions instanceof ManagedVersionMap )
+ {
+ /* avoid modifying the managedVersions parameter creating a new map */
+ versionMap = new ManagedVersionMap( managedVersions );
+ }
+ versionMap.remove( originatingArtifact.getDependencyConflictId() );
+ }
+
+ return versionMap;
+ }
+
+ private void recurse( ArtifactResolutionResult result, ResolutionNode node,
+ Map<Object, List<ResolutionNode>> resolvedArtifacts, ManagedVersionMap managedVersions,
+ ArtifactResolutionRequest request, ArtifactMetadataSource source, ArtifactFilter filter,
+ List<ResolutionListener> listeners, List<ConflictResolver> conflictResolvers )
+ throws ArtifactResolutionException
+ {
+ fireEvent( ResolutionListener.TEST_ARTIFACT, listeners, node );
+
+ Object key = node.getKey();
+
+ // TODO: Does this check need to happen here? Had to add the same call
+ // below when we iterate on child nodes -- will that suffice?
+ if ( managedVersions.containsKey( key ) )
+ {
+ manageArtifact( node, managedVersions, listeners );
+ }
+
+ List<ResolutionNode> previousNodes = resolvedArtifacts.get( key );
+
+ if ( previousNodes != null )
+ {
+ for ( ResolutionNode previous : previousNodes )
+ {
+ try
+ {
+ if ( previous.isActive() )
+ {
+ // Version mediation
+ VersionRange previousRange = previous.getArtifact().getVersionRange();
+ VersionRange currentRange = node.getArtifact().getVersionRange();
+
+ if ( ( previousRange != null ) && ( currentRange != null ) )
+ {
+ // TODO: shouldn't need to double up on this work, only done for simplicity of handling
+ // recommended
+ // version but the restriction is identical
+ VersionRange newRange = previousRange.restrict( currentRange );
+ // TODO: ick. this forces the OCE that should have come from the previous call. It is still
+ // correct
+ if ( newRange.isSelectedVersionKnown( previous.getArtifact() ) )
+ {
+ fireEvent( ResolutionListener.RESTRICT_RANGE, listeners, node, previous.getArtifact(),
+ newRange );
+ }
+ previous.getArtifact().setVersionRange( newRange );
+ node.getArtifact().setVersionRange( currentRange.restrict( previousRange ) );
+
+ // Select an appropriate available version from the (now restricted) range
+ // Note this version was selected before to get the appropriate POM
+ // But it was reset by the call to setVersionRange on restricting the version
+ ResolutionNode[] resetNodes = { previous, node };
+ for ( int j = 0; j < 2; j++ )
+ {
+ Artifact resetArtifact = resetNodes[j].getArtifact();
+
+ // MNG-2123: if the previous node was not a range, then it wouldn't have any available
+ // versions. We just clobbered the selected version above. (why? i have no idea.)
+ // So since we are here and this is ranges we must go figure out the version (for a
+ // third time...)
+ if ( resetArtifact.getVersion() == null && resetArtifact.getVersionRange() != null )
+ {
+
+ // go find the version. This is a total hack. See previous comment.
+ List<ArtifactVersion> versions = resetArtifact.getAvailableVersions();
+ if ( versions == null )
+ {
+ try
+ {
+ MetadataResolutionRequest metadataRequest =
+ new DefaultMetadataResolutionRequest( request );
+ metadataRequest.setArtifact( resetArtifact );
+ versions = source.retrieveAvailableVersions( metadataRequest );
+ resetArtifact.setAvailableVersions( versions );
+ }
+ catch ( ArtifactMetadataRetrievalException e )
+ {
+ resetArtifact.setDependencyTrail( node.getDependencyTrail() );
+ throw new ArtifactResolutionException(
+ "Unable to get dependency information: "
+ + e.getMessage(), resetArtifact,
+ request.getRemoteRepositories(), e );
+ }
+ }
+ // end hack
+
+ // MNG-2861: match version can return null
+ ArtifactVersion selectedVersion =
+ resetArtifact.getVersionRange().matchVersion( resetArtifact.getAvailableVersions() );
+ if ( selectedVersion != null )
+ {
+ resetArtifact.selectVersion( selectedVersion.toString() );
+ }
+ else
+ {
+ throw new OverConstrainedVersionException( " Unable to find a version in "
+ + resetArtifact.getAvailableVersions() + " to match the range "
+ + resetArtifact.getVersionRange(), resetArtifact );
+ }
+
+ fireEvent( ResolutionListener.SELECT_VERSION_FROM_RANGE, listeners, resetNodes[j] );
+ }
+ }
+ }
+
+ // Conflict Resolution
+ ResolutionNode resolved = null;
+ for ( Iterator j = conflictResolvers.iterator(); ( resolved == null ) && j.hasNext(); )
+ {
+ ConflictResolver conflictResolver = (ConflictResolver) j.next();
+
+ resolved = conflictResolver.resolveConflict( previous, node );
+ }
+
+ if ( resolved == null )
+ {
+ // TODO: add better exception that can detail the two conflicting artifacts
+ ArtifactResolutionException are =
+ new ArtifactResolutionException( "Cannot resolve artifact version conflict between "
+ + previous.getArtifact().getVersion() + " and " + node.getArtifact().getVersion(),
+ previous.getArtifact() );
+ result.addVersionRangeViolation( are );
+ }
+
+ if ( ( resolved != previous ) && ( resolved != node ) )
+ {
+ // TODO: add better exception
+ result.addVersionRangeViolation( new ArtifactResolutionException(
+ "Conflict resolver returned unknown resolution node: ",
+ resolved.getArtifact() ) );
+ }
+
+ // TODO: should this be part of mediation?
+ // previous one is more dominant
+ ResolutionNode nearest;
+ ResolutionNode farthest;
+
+ if ( resolved == previous )
+ {
+ nearest = previous;
+ farthest = node;
+ }
+ else
+ {
+ nearest = node;
+ farthest = previous;
+ }
+
+ if ( checkScopeUpdate( farthest, nearest, listeners ) )
+ {
+ // if we need to update artifactScope of nearest to use farthest artifactScope, use the
+ // nearest version, but farthest artifactScope
+ nearest.disable();
+ farthest.getArtifact().setVersion( nearest.getArtifact().getVersion() );
+ fireEvent( ResolutionListener.OMIT_FOR_NEARER, listeners, nearest, farthest.getArtifact() );
+ }
+ else
+ {
+ farthest.disable();
+ fireEvent( ResolutionListener.OMIT_FOR_NEARER, listeners, farthest, nearest.getArtifact() );
+ }
+ }
+ }
+ catch ( OverConstrainedVersionException e )
+ {
+ result.addVersionRangeViolation( e );
+ }
+ }
+ }
+ else
+ {
+ previousNodes = new ArrayList<ResolutionNode>();
+
+ resolvedArtifacts.put( key, previousNodes );
+ }
+ previousNodes.add( node );
+
+ if ( node.isActive() )
+ {
+ fireEvent( ResolutionListener.INCLUDE_ARTIFACT, listeners, node );
+ }
+
+ // don't pull in the transitive deps of a system-scoped dependency.
+ if ( node.isActive() && !Artifact.SCOPE_SYSTEM.equals( node.getArtifact().getScope() ) )
+ {
+ fireEvent( ResolutionListener.PROCESS_CHILDREN, listeners, node );
+
+ Artifact parentArtifact = node.getArtifact();
+
+ for ( Iterator i = node.getChildrenIterator(); i.hasNext(); )
+ {
+ ResolutionNode child = (ResolutionNode) i.next();
+
+ try
+ {
+
+ // We leave in optional ones, but don't pick up its dependencies
+ if ( !child.isResolved() && ( !child.getArtifact().isOptional() || child.isChildOfRootNode() ) )
+ {
+ Artifact artifact = child.getArtifact();
+ artifact.setDependencyTrail( node.getDependencyTrail() );
+ List<ArtifactRepository> childRemoteRepositories = child.getRemoteRepositories();
+
+ MetadataResolutionRequest metadataRequest =
+ new DefaultMetadataResolutionRequest( request );
+ metadataRequest.setArtifact( artifact );
+ metadataRequest.setRemoteRepositories( childRemoteRepositories );
+
+ try
+ {
+ ResolutionGroup rGroup;
+
+ Object childKey;
+ do
+ {
+ childKey = child.getKey();
+
+ if ( managedVersions.containsKey( childKey ) )
+ {
+ // If this child node is a managed dependency, ensure
+ // we are using the dependency management version
+ // of this child if applicable b/c we want to use the
+ // managed version's POM, *not* any other version's POM.
+ // We retrieve the POM below in the retrieval step.
+ manageArtifact( child, managedVersions, listeners );
+
+ // Also, we need to ensure that any exclusions it presents are
+ // added to the artifact before we retrive the metadata
+ // for the artifact; otherwise we may end up with unwanted
+ // dependencies.
+ Artifact ma = managedVersions.get( childKey );
+ ArtifactFilter managedExclusionFilter = ma.getDependencyFilter();
+ if ( null != managedExclusionFilter )
+ {
+ if ( null != artifact.getDependencyFilter() )
+ {
+ AndArtifactFilter aaf = new AndArtifactFilter();
+ aaf.add( artifact.getDependencyFilter() );
+ aaf.add( managedExclusionFilter );
+ artifact.setDependencyFilter( aaf );
+ }
+ else
+ {
+ artifact.setDependencyFilter( managedExclusionFilter );
+ }
+ }
+ }
+
+ if ( artifact.getVersion() == null )
+ {
+ // set the recommended version
+ // TODO: maybe its better to just pass the range through to retrieval and use a
+ // transformation?
+ ArtifactVersion version;
+ if ( !artifact.isSelectedVersionKnown() )
+ {
+ List<ArtifactVersion> versions = artifact.getAvailableVersions();
+ if ( versions == null )
+ {
+ versions = source.retrieveAvailableVersions( metadataRequest );
+ artifact.setAvailableVersions( versions );
+ }
+
+ Collections.sort( versions );
+
+ VersionRange versionRange = artifact.getVersionRange();
+
+ version = versionRange.matchVersion( versions );
+
+ if ( version == null )
+ {
+ if ( versions.isEmpty() )
+ {
+ throw new OverConstrainedVersionException(
+ "No versions are present in the repository for the artifact with a range "
+ + versionRange,
+ artifact,
+ childRemoteRepositories );
+ }
+
+ throw new OverConstrainedVersionException( "Couldn't find a version in "
+ + versions + " to match range " + versionRange, artifact,
+ childRemoteRepositories );
+ }
+ }
+ else
+ {
+ version = artifact.getSelectedVersion();
+ }
+
+ artifact.selectVersion( version.toString() );
+ fireEvent( ResolutionListener.SELECT_VERSION_FROM_RANGE, listeners, child );
+ }
+
+ rGroup = source.retrieve( metadataRequest );
+
+ if ( rGroup == null )
+ {
+ break;
+ }
+ }
+ while( !childKey.equals( child.getKey() ) );
+
+ if ( parentArtifact != null && parentArtifact.getDependencyFilter() != null
+ && !parentArtifact.getDependencyFilter().include( artifact ) )
+ {
+ // MNG-3769: the [probably relocated] artifact is excluded.
+ // We could process exclusions on relocated artifact details in the
+ // MavenMetadataSource.createArtifacts(..) step, BUT that would
+ // require resolving the POM from the repository very early on in
+ // the build.
+ continue;
+ }
+
+ // TODO might be better to have source.retrieve() throw a specific exception for this
+ // situation
+ // and catch here rather than have it return null
+ if ( rGroup == null )
+ {
+ // relocated dependency artifact is declared excluded, no need to add and recurse
+ // further
+ continue;
+ }
+
+ child.addDependencies( rGroup.getArtifacts(), rGroup.getResolutionRepositories(), filter );
+
+ }
+ catch ( CyclicDependencyException e )
+ {
+ // would like to throw this, but we have crappy stuff in the repo
+
+ fireEvent( ResolutionListener.OMIT_FOR_CYCLE, listeners,
+ new ResolutionNode( e.getArtifact(), childRemoteRepositories, child ) );
+ }
+ catch ( ArtifactMetadataRetrievalException e )
+ {
+ artifact.setDependencyTrail( node.getDependencyTrail() );
+
+ throw new ArtifactResolutionException( "Unable to get dependency information for "
+ + artifact.getId() + ": " + e.getMessage(), artifact, childRemoteRepositories, e );
+ }
+
+ ArtifactResolutionRequest subRequest = new ArtifactResolutionRequest( metadataRequest );
+ subRequest.setServers( request.getServers() );
+ subRequest.setMirrors( request.getMirrors() );
+ subRequest.setProxies( request.getProxies() );
+ recurse( result, child, resolvedArtifacts, managedVersions, subRequest, source, filter,
+ listeners, conflictResolvers );
+ }
+ }
+ catch ( OverConstrainedVersionException e )
+ {
+ result.addVersionRangeViolation( e );
+ }
+ catch ( ArtifactResolutionException e )
+ {
+ result.addMetadataResolutionException( e );
+ }
+ }
+
+ fireEvent( ResolutionListener.FINISH_PROCESSING_CHILDREN, listeners, node );
+ }
+ }
+
+ private void manageArtifact( ResolutionNode node, ManagedVersionMap managedVersions,
+ List<ResolutionListener> listeners )
+ {
+ Artifact artifact = managedVersions.get( node.getKey() );
+
+ // Before we update the version of the artifact, we need to know
+ // whether we are working on a transitive dependency or not. This
+ // allows depMgmt to always override transitive dependencies, while
+ // explicit child override depMgmt (viz. depMgmt should only
+ // provide defaults to children, but should override transitives).
+ // We can do this by calling isChildOfRootNode on the current node.
+
+ if ( ( artifact.getVersion() != null )
+ && ( !node.isChildOfRootNode() || node.getArtifact().getVersion() == null ) )
+ {
+ fireEvent( ResolutionListener.MANAGE_ARTIFACT_VERSION, listeners, node, artifact );
+ node.getArtifact().setVersion( artifact.getVersion() );
+ }
+
+ if ( ( artifact.getScope() != null ) && ( !node.isChildOfRootNode() || node.getArtifact().getScope() == null ) )
+ {
+ fireEvent( ResolutionListener.MANAGE_ARTIFACT_SCOPE, listeners, node, artifact );
+ node.getArtifact().setScope( artifact.getScope() );
+ }
+
+ if ( Artifact.SCOPE_SYSTEM.equals( node.getArtifact().getScope() ) && ( node.getArtifact().getFile() == null )
+ && ( artifact.getFile() != null ) )
+ {
+ fireEvent( ResolutionListener.MANAGE_ARTIFACT_SYSTEM_PATH, listeners, node, artifact );
+ node.getArtifact().setFile( artifact.getFile() );
+ }
+ }
+
+ /**
+ * Check if the artifactScope needs to be updated. <a
+ * href="http://docs.codehaus.org/x/IGU#DependencyMediationandConflictResolution-Scoperesolution">More info</a>.
+ *
+ * @param farthest farthest resolution node
+ * @param nearest nearest resolution node
+ * @param listeners
+ */
+ boolean checkScopeUpdate( ResolutionNode farthest, ResolutionNode nearest, List<ResolutionListener> listeners )
+ {
+ boolean updateScope = false;
+ Artifact farthestArtifact = farthest.getArtifact();
+ Artifact nearestArtifact = nearest.getArtifact();
+
+ /* farthest is runtime and nearest has lower priority, change to runtime */
+ if ( Artifact.SCOPE_RUNTIME.equals( farthestArtifact.getScope() )
+ && ( Artifact.SCOPE_TEST.equals( nearestArtifact.getScope() )
+ || Artifact.SCOPE_PROVIDED.equals( nearestArtifact.getScope() ) ) )
+ {
+ updateScope = true;
+ }
+
+ /* farthest is compile and nearest is not (has lower priority), change to compile */
+ if ( Artifact.SCOPE_COMPILE.equals( farthestArtifact.getScope() )
+ && !Artifact.SCOPE_COMPILE.equals( nearestArtifact.getScope() ) )
+ {
+ updateScope = true;
+ }
+
+ /* current POM rules all, if nearest is in current pom, do not update its artifactScope */
+ if ( ( nearest.getDepth() < 2 ) && updateScope )
+ {
+ updateScope = false;
+
+ fireEvent( ResolutionListener.UPDATE_SCOPE_CURRENT_POM, listeners, nearest, farthestArtifact );
+ }
+
+ if ( updateScope )
+ {
+ fireEvent( ResolutionListener.UPDATE_SCOPE, listeners, nearest, farthestArtifact );
+
+ // previously we cloned the artifact, but it is more effecient to just update the artifactScope
+ // if problems are later discovered that the original object needs its original artifactScope value, cloning
+ // may
+ // again be appropriate
+ nearestArtifact.setScope( farthestArtifact.getScope() );
+ }
+
+ return updateScope;
+ }
+
+ private void fireEvent( int event, List<ResolutionListener> listeners, ResolutionNode node )
+ {
+ fireEvent( event, listeners, node, null );
+ }
+
+ private void fireEvent( int event, List<ResolutionListener> listeners, ResolutionNode node, Artifact replacement )
+ {
+ fireEvent( event, listeners, node, replacement, null );
+ }
+
+ private void fireEvent( int event, List<ResolutionListener> listeners, ResolutionNode node, Artifact replacement,
+ VersionRange newRange )
+ {
+ for ( ResolutionListener listener : listeners )
+ {
+ switch ( event )
+ {
+ case ResolutionListener.TEST_ARTIFACT:
+ listener.testArtifact( node.getArtifact() );
+ break;
+ case ResolutionListener.PROCESS_CHILDREN:
+ listener.startProcessChildren( node.getArtifact() );
+ break;
+ case ResolutionListener.FINISH_PROCESSING_CHILDREN:
+ listener.endProcessChildren( node.getArtifact() );
+ break;
+ case ResolutionListener.INCLUDE_ARTIFACT:
+ listener.includeArtifact( node.getArtifact() );
+ break;
+ case ResolutionListener.OMIT_FOR_NEARER:
+ listener.omitForNearer( node.getArtifact(), replacement );
+ break;
+ case ResolutionListener.OMIT_FOR_CYCLE:
+ listener.omitForCycle( node.getArtifact() );
+ break;
+ case ResolutionListener.UPDATE_SCOPE:
+ listener.updateScope( node.getArtifact(), replacement.getScope() );
+ break;
+ case ResolutionListener.UPDATE_SCOPE_CURRENT_POM:
+ listener.updateScopeCurrentPom( node.getArtifact(), replacement.getScope() );
+ break;
+ case ResolutionListener.MANAGE_ARTIFACT_VERSION:
+ if ( listener instanceof ResolutionListenerForDepMgmt )
+ {
+ ResolutionListenerForDepMgmt asImpl = (ResolutionListenerForDepMgmt) listener;
+ asImpl.manageArtifactVersion( node.getArtifact(), replacement );
+ }
+ else
+ {
+ listener.manageArtifact( node.getArtifact(), replacement );
+ }
+ break;
+ case ResolutionListener.MANAGE_ARTIFACT_SCOPE:
+ if ( listener instanceof ResolutionListenerForDepMgmt )
+ {
+ ResolutionListenerForDepMgmt asImpl = (ResolutionListenerForDepMgmt) listener;
+ asImpl.manageArtifactScope( node.getArtifact(), replacement );
+ }
+ else
+ {
+ listener.manageArtifact( node.getArtifact(), replacement );
+ }
+ break;
+ case ResolutionListener.MANAGE_ARTIFACT_SYSTEM_PATH:
+ if ( listener instanceof ResolutionListenerForDepMgmt )
+ {
+ ResolutionListenerForDepMgmt asImpl = (ResolutionListenerForDepMgmt) listener;
+ asImpl.manageArtifactSystemPath( node.getArtifact(), replacement );
+ }
+ else
+ {
+ listener.manageArtifact( node.getArtifact(), replacement );
+ }
+ break;
+ case ResolutionListener.SELECT_VERSION_FROM_RANGE:
+ listener.selectVersionFromRange( node.getArtifact() );
+ break;
+ case ResolutionListener.RESTRICT_RANGE:
+ if ( node.getArtifact().getVersionRange().hasRestrictions()
+ || replacement.getVersionRange().hasRestrictions() )
+ {
+ listener.restrictRange( node.getArtifact(), replacement, newRange );
+ }
+ break;
+ default:
+ throw new IllegalStateException( "Unknown event: " + event );
+ }
+ }
+ }
+
+ public ArtifactResolutionResult collect( Set<Artifact> artifacts, Artifact originatingArtifact,
+ Map managedVersions, ArtifactRepository localRepository,
+ List<ArtifactRepository> remoteRepositories,
+ ArtifactMetadataSource source, ArtifactFilter filter,
+ List<ResolutionListener> listeners )
+ {
+ return collect( artifacts, originatingArtifact, managedVersions, localRepository, remoteRepositories, source,
+ filter, listeners, null );
+ }
+
+ public ArtifactResolutionResult collect( Set<Artifact> artifacts, Artifact originatingArtifact,
+ ArtifactRepository localRepository,
+ List<ArtifactRepository> remoteRepositories,
+ ArtifactMetadataSource source, ArtifactFilter filter,
+ List<ResolutionListener> listeners )
+ {
+ return collect( artifacts, originatingArtifact, null, localRepository, remoteRepositories, source, filter,
+ listeners );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/resolver/LegacyArtifactCollector.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/resolver/LegacyArtifactCollector.java
new file mode 100644
index 00000000..fa7fb7a4
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/resolver/LegacyArtifactCollector.java
@@ -0,0 +1,62 @@
+package org.apache.maven.repository.legacy.resolver;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.resolver.ArtifactResolutionRequest;
+import org.apache.maven.artifact.resolver.ArtifactResolutionResult;
+import org.apache.maven.artifact.resolver.ResolutionListener;
+import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
+import org.apache.maven.repository.legacy.resolver.conflict.ConflictResolver;
+
+/**
+ * Artifact collector - takes a set of original artifacts and resolves all of the best versions to use
+ * along with their metadata. No artifacts are downloaded.
+ *
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ */
+@Deprecated
+public interface LegacyArtifactCollector
+{
+
+ ArtifactResolutionResult collect( Set<Artifact> artifacts, Artifact originatingArtifact, Map managedVersions,
+ ArtifactResolutionRequest repositoryRequest, ArtifactMetadataSource source,
+ ArtifactFilter filter, List<ResolutionListener> listeners,
+ List<ConflictResolver> conflictResolvers );
+
+ ArtifactResolutionResult collect( Set<Artifact> artifacts, Artifact originatingArtifact, Map managedVersions,
+ ArtifactRepository localRepository, List<ArtifactRepository> remoteRepositories,
+ ArtifactMetadataSource source, ArtifactFilter filter,
+ List<ResolutionListener> listeners, List<ConflictResolver> conflictResolvers );
+
+ // used by maven-dependency-tree and maven-dependency-plugin
+ @Deprecated
+ ArtifactResolutionResult collect( Set<Artifact> artifacts, Artifact originatingArtifact, Map managedVersions,
+ ArtifactRepository localRepository, List<ArtifactRepository> remoteRepositories,
+ ArtifactMetadataSource source, ArtifactFilter filter,
+ List<ResolutionListener> listeners );
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/resolver/conflict/ConflictResolver.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/resolver/conflict/ConflictResolver.java
new file mode 100644
index 00000000..4d129b7e
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/resolver/conflict/ConflictResolver.java
@@ -0,0 +1,44 @@
+package org.apache.maven.repository.legacy.resolver.conflict;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.artifact.resolver.ResolutionNode;
+
+/**
+ * Determines which version of an artifact to use when there are conflicting declarations.
+ *
+ * @author <a href="mailto:jason@maven.org">Jason van Zyl</a>
+ * @author <a href="mailto:markhobson@gmail.com">Mark Hobson</a>
+ */
+public interface ConflictResolver
+{
+ String ROLE = ConflictResolver.class.getName();
+
+ /**
+ * Determines which of the specified versions of an artifact to use when there are conflicting declarations.
+ *
+ * @param node1 the first artifact declaration
+ * @param node2 the second artifact declaration
+ * @return the artifact declaration to use: <code>node1</code>; <code>node2</code>; or <code>null</code>if
+ * this conflict cannot be resolved
+ * @since 3.0
+ */
+ ResolutionNode resolveConflict( ResolutionNode node1, ResolutionNode node2 );
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/resolver/conflict/ConflictResolverFactory.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/resolver/conflict/ConflictResolverFactory.java
new file mode 100644
index 00000000..8f3f9f43
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/resolver/conflict/ConflictResolverFactory.java
@@ -0,0 +1,48 @@
+package org.apache.maven.repository.legacy.resolver.conflict;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * A factory that produces conflict resolvers of various types.
+ *
+ * @author <a href="mailto:markhobson@gmail.com">Mark Hobson</a>
+ * @see ConflictResolver
+ * @since 3.0
+ */
+public interface ConflictResolverFactory
+{
+ // constants --------------------------------------------------------------
+
+ /** The plexus role for this component. */
+ String ROLE = ConflictResolverFactory.class.getName();
+
+ // methods ----------------------------------------------------------------
+
+ /**
+ * Gets a conflict resolver of the specified type.
+ *
+ * @param type the type of conflict resolver to obtain
+ * @return the conflict resolver
+ * @throws ConflictResolverNotFoundException
+ * if the specified type was not found
+ */
+ ConflictResolver getConflictResolver( String type )
+ throws ConflictResolverNotFoundException;
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/resolver/conflict/ConflictResolverNotFoundException.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/resolver/conflict/ConflictResolverNotFoundException.java
new file mode 100644
index 00000000..b5f61ed1
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/resolver/conflict/ConflictResolverNotFoundException.java
@@ -0,0 +1,47 @@
+package org.apache.maven.repository.legacy.resolver.conflict;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Indicates that a specified conflict resolver implementation could not be found.
+ *
+ * @author <a href="mailto:markhobson@gmail.com">Mark Hobson</a>
+ * @since 3.0
+ */
+public class ConflictResolverNotFoundException
+ extends Exception
+{
+ // constants --------------------------------------------------------------
+
+ /** The serial version ID. */
+ private static final long serialVersionUID = 3372412184339653914L;
+
+ // constructors -----------------------------------------------------------
+
+ /**
+ * Creates a new <code>ConflictResolverNotFoundException</code> with the specified message.
+ *
+ * @param message the message
+ */
+ public ConflictResolverNotFoundException( String message )
+ {
+ super( message );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/resolver/conflict/DefaultConflictResolver.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/resolver/conflict/DefaultConflictResolver.java
new file mode 100644
index 00000000..76f1929d
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/resolver/conflict/DefaultConflictResolver.java
@@ -0,0 +1,36 @@
+package org.apache.maven.repository.legacy.resolver.conflict;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.codehaus.plexus.component.annotations.Component;
+
+/**
+ * The default conflict resolver that delegates to the nearest strategy.
+ *
+ * @author <a href="mailto:jason@maven.org">Jason van Zyl</a>
+ * @see NearestConflictResolver
+ * @deprecated As of 3.0, use a specific implementation instead, e.g. {@link NearestConflictResolver}
+ */
+@Deprecated
+@Component( role = ConflictResolver.class )
+public class DefaultConflictResolver
+ extends NearestConflictResolver
+{
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/resolver/conflict/DefaultConflictResolverFactory.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/resolver/conflict/DefaultConflictResolverFactory.java
new file mode 100644
index 00000000..66716d1e
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/resolver/conflict/DefaultConflictResolverFactory.java
@@ -0,0 +1,80 @@
+package org.apache.maven.repository.legacy.resolver.conflict;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.codehaus.plexus.PlexusConstants;
+import org.codehaus.plexus.PlexusContainer;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
+import org.codehaus.plexus.context.Context;
+import org.codehaus.plexus.context.ContextException;
+import org.codehaus.plexus.personality.plexus.lifecycle.phase.Contextualizable;
+
+/**
+ * A conflict resolver factory that obtains instances from a plexus container.
+ *
+ * @author <a href="mailto:markhobson@gmail.com">Mark Hobson</a>
+ * @todo you don't need the container in here with the active maps (jvz).
+ * @since 3.0
+ */
+@Component( role = ConflictResolverFactory.class )
+public class DefaultConflictResolverFactory
+ implements ConflictResolverFactory, Contextualizable
+{
+ // fields -----------------------------------------------------------------
+
+ /**
+ * The plexus container used to obtain instances from.
+ */
+ @Requirement
+ private PlexusContainer container;
+
+ // ConflictResolverFactory methods ----------------------------------------
+
+ /*
+ * @see org.apache.maven.artifact.resolver.conflict.ConflictResolverFactory#getConflictResolver(java.lang.String)
+ */
+
+ public ConflictResolver getConflictResolver( String type )
+ throws ConflictResolverNotFoundException
+ {
+ try
+ {
+ return (ConflictResolver) container.lookup( ConflictResolver.ROLE, type );
+ }
+ catch ( ComponentLookupException exception )
+ {
+ throw new ConflictResolverNotFoundException( "Cannot find conflict resolver of type: " + type );
+ }
+ }
+
+ // Contextualizable methods -----------------------------------------------
+
+ /*
+ * @see org.codehaus.plexus.personality.plexus.lifecycle.phase.Contextualizable#contextualize(org.codehaus.plexus.context.Context)
+ */
+
+ public void contextualize( Context context )
+ throws ContextException
+ {
+ container = (PlexusContainer) context.get( PlexusConstants.PLEXUS_KEY );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/resolver/conflict/FarthestConflictResolver.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/resolver/conflict/FarthestConflictResolver.java
new file mode 100644
index 00000000..726e9a6d
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/resolver/conflict/FarthestConflictResolver.java
@@ -0,0 +1,47 @@
+package org.apache.maven.repository.legacy.resolver.conflict;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.artifact.resolver.ResolutionNode;
+import org.codehaus.plexus.component.annotations.Component;
+
+/**
+ * Resolves conflicting artifacts by always selecting the <em>farthest</em> declaration. Farthest is defined as the
+ * declaration that has the most transitive steps away from the project being built.
+ *
+ * @author <a href="mailto:markhobson@gmail.com">Mark Hobson</a>
+ * @since 3.0
+ */
+@Component( role = ConflictResolver.class, hint = "farthest" )
+public class FarthestConflictResolver
+ implements ConflictResolver
+{
+ // ConflictResolver methods -----------------------------------------------
+
+ /*
+ * @see org.apache.maven.artifact.resolver.conflict.ConflictResolver#resolveConflict(org.apache.maven.artifact.resolver.ResolutionNode,
+ * org.apache.maven.artifact.resolver.ResolutionNode)
+ */
+
+ public ResolutionNode resolveConflict( ResolutionNode node1, ResolutionNode node2 )
+ {
+ return node1.getDepth() >= node2.getDepth() ? node1 : node2;
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/resolver/conflict/NearestConflictResolver.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/resolver/conflict/NearestConflictResolver.java
new file mode 100644
index 00000000..338baed6
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/resolver/conflict/NearestConflictResolver.java
@@ -0,0 +1,48 @@
+package org.apache.maven.repository.legacy.resolver.conflict;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.artifact.resolver.ResolutionNode;
+import org.codehaus.plexus.component.annotations.Component;
+
+/**
+ * Resolves conflicting artifacts by always selecting the <em>nearest</em> declaration. Nearest is defined as the
+ * declaration that has the least transitive steps away from the project being built.
+ *
+ * @author <a href="mailto:jason@maven.org">Jason van Zyl</a>
+ * @author <a href="mailto:markhobson@gmail.com">Mark Hobson</a>
+ * @since 3.0
+ */
+@Component( role = ConflictResolver.class, hint = "nearest" )
+public class NearestConflictResolver
+ implements ConflictResolver
+{
+ // ConflictResolver methods -----------------------------------------------
+
+ /*
+ * @see org.apache.maven.artifact.resolver.conflict.ConflictResolver#resolveConflict(org.apache.maven.artifact.resolver.ResolutionNode,
+ * org.apache.maven.artifact.resolver.ResolutionNode)
+ */
+
+ public ResolutionNode resolveConflict( ResolutionNode node1, ResolutionNode node2 )
+ {
+ return node1.getDepth() <= node2.getDepth() ? node1 : node2;
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/resolver/conflict/NewestConflictResolver.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/resolver/conflict/NewestConflictResolver.java
new file mode 100644
index 00000000..1879a813
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/resolver/conflict/NewestConflictResolver.java
@@ -0,0 +1,62 @@
+package org.apache.maven.repository.legacy.resolver.conflict;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.artifact.resolver.ResolutionNode;
+import org.apache.maven.artifact.versioning.ArtifactVersion;
+import org.apache.maven.artifact.versioning.OverConstrainedVersionException;
+import org.codehaus.plexus.component.annotations.Component;
+
+/**
+ * Resolves conflicting artifacts by always selecting the <em>newest</em> declaration. Newest is defined as the
+ * declaration whose version is greater according to <code>ArtifactVersion.compareTo</code>.
+ *
+ * @author <a href="mailto:markhobson@gmail.com">Mark Hobson</a>
+ * @see ArtifactVersion#compareTo
+ * @since 3.0
+ */
+@Component( role = ConflictResolver.class, hint = "newest" )
+public class NewestConflictResolver
+ implements ConflictResolver
+{
+ // ConflictResolver methods -----------------------------------------------
+
+ /*
+ * @see org.apache.maven.artifact.resolver.conflict.ConflictResolver#resolveConflict(org.apache.maven.artifact.resolver.ResolutionNode,
+ * org.apache.maven.artifact.resolver.ResolutionNode)
+ */
+
+ public ResolutionNode resolveConflict( ResolutionNode node1, ResolutionNode node2 )
+ {
+ try
+ {
+ ArtifactVersion version1 = node1.getArtifact().getSelectedVersion();
+ ArtifactVersion version2 = node2.getArtifact().getSelectedVersion();
+
+ return version1.compareTo( version2 ) > 0 ? node1 : node2;
+ }
+ catch ( OverConstrainedVersionException exception )
+ {
+ // TODO: log message or throw exception?
+
+ return null;
+ }
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/resolver/conflict/OldestConflictResolver.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/resolver/conflict/OldestConflictResolver.java
new file mode 100644
index 00000000..5c5c12d6
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/resolver/conflict/OldestConflictResolver.java
@@ -0,0 +1,62 @@
+package org.apache.maven.repository.legacy.resolver.conflict;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.artifact.resolver.ResolutionNode;
+import org.apache.maven.artifact.versioning.ArtifactVersion;
+import org.apache.maven.artifact.versioning.OverConstrainedVersionException;
+import org.codehaus.plexus.component.annotations.Component;
+
+/**
+ * Resolves conflicting artifacts by always selecting the <em>oldest</em> declaration. Oldest is defined as the
+ * declaration whose version is less according to <code>ArtifactVersion.compareTo</code>.
+ *
+ * @author <a href="mailto:markhobson@gmail.com">Mark Hobson</a>
+ * @see ArtifactVersion#compareTo
+ * @since 3.0
+ */
+@Component( role = ConflictResolver.class, hint = "oldest" )
+public class OldestConflictResolver
+ implements ConflictResolver
+{
+ // ConflictResolver methods -----------------------------------------------
+
+ /*
+ * @see org.apache.maven.artifact.resolver.conflict.ConflictResolver#resolveConflict(org.apache.maven.artifact.resolver.ResolutionNode,
+ * org.apache.maven.artifact.resolver.ResolutionNode)
+ */
+
+ public ResolutionNode resolveConflict( ResolutionNode node1, ResolutionNode node2 )
+ {
+ try
+ {
+ ArtifactVersion version1 = node1.getArtifact().getSelectedVersion();
+ ArtifactVersion version2 = node2.getArtifact().getSelectedVersion();
+
+ return version1.compareTo( version2 ) <= 0 ? node1 : node2;
+ }
+ catch ( OverConstrainedVersionException exception )
+ {
+ // TODO: log message or throw exception?
+
+ return null;
+ }
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/resolver/transform/AbstractVersionTransformation.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/resolver/transform/AbstractVersionTransformation.java
new file mode 100644
index 00000000..3a5c7c6a
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/resolver/transform/AbstractVersionTransformation.java
@@ -0,0 +1,135 @@
+package org.apache.maven.repository.legacy.resolver.transform;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.List;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.repository.DefaultRepositoryRequest;
+import org.apache.maven.artifact.repository.RepositoryRequest;
+import org.apache.maven.artifact.repository.metadata.ArtifactRepositoryMetadata;
+import org.apache.maven.artifact.repository.metadata.Metadata;
+import org.apache.maven.artifact.repository.metadata.RepositoryMetadata;
+import org.apache.maven.artifact.repository.metadata.RepositoryMetadataManager;
+import org.apache.maven.artifact.repository.metadata.RepositoryMetadataResolutionException;
+import org.apache.maven.artifact.repository.metadata.SnapshotArtifactRepositoryMetadata;
+import org.apache.maven.artifact.repository.metadata.Versioning;
+import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
+import org.apache.maven.artifact.resolver.ArtifactResolutionException;
+import org.apache.maven.repository.legacy.WagonManager;
+import org.codehaus.plexus.component.annotations.Requirement;
+import org.codehaus.plexus.logging.AbstractLogEnabled;
+
+/**
+ * Describes a version transformation during artifact resolution.
+ *
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ * @todo try and refactor to remove abstract methods - not particular happy about current design
+ */
+public abstract class AbstractVersionTransformation
+ extends AbstractLogEnabled
+ implements ArtifactTransformation
+{
+ @Requirement
+ protected RepositoryMetadataManager repositoryMetadataManager;
+
+ @Requirement
+ protected WagonManager wagonManager;
+
+ public void transformForResolve( Artifact artifact, List<ArtifactRepository> remoteRepositories,
+ ArtifactRepository localRepository )
+ throws ArtifactResolutionException, ArtifactNotFoundException
+ {
+ RepositoryRequest request = new DefaultRepositoryRequest();
+ request.setLocalRepository( localRepository );
+ request.setRemoteRepositories( remoteRepositories );
+ transformForResolve( artifact, request );
+ }
+
+ protected String resolveVersion( Artifact artifact, ArtifactRepository localRepository,
+ List<ArtifactRepository> remoteRepositories )
+ throws RepositoryMetadataResolutionException
+ {
+ RepositoryRequest request = new DefaultRepositoryRequest();
+ request.setLocalRepository( localRepository );
+ request.setRemoteRepositories( remoteRepositories );
+ return resolveVersion( artifact, request );
+ }
+
+ protected String resolveVersion( Artifact artifact, RepositoryRequest request )
+ throws RepositoryMetadataResolutionException
+ {
+ RepositoryMetadata metadata;
+ // Don't use snapshot metadata for LATEST (which isSnapshot returns true for)
+ if ( !artifact.isSnapshot() || Artifact.LATEST_VERSION.equals( artifact.getBaseVersion() ) )
+ {
+ metadata = new ArtifactRepositoryMetadata( artifact );
+ }
+ else
+ {
+ metadata = new SnapshotArtifactRepositoryMetadata( artifact );
+ }
+
+ repositoryMetadataManager.resolve( metadata, request );
+
+ artifact.addMetadata( metadata );
+
+ Metadata repoMetadata = metadata.getMetadata();
+ String version = null;
+ if ( repoMetadata != null && repoMetadata.getVersioning() != null )
+ {
+ version = constructVersion( repoMetadata.getVersioning(), artifact.getBaseVersion() );
+ }
+
+ if ( version == null )
+ {
+ // use the local copy, or if it doesn't exist - go to the remote repo for it
+ version = artifact.getBaseVersion();
+ }
+
+ // TODO: also do this logging for other metadata?
+ // TODO: figure out way to avoid duplicated message
+ if ( getLogger().isDebugEnabled() )
+ {
+ if ( !version.equals( artifact.getBaseVersion() ) )
+ {
+ String message = artifact.getArtifactId() + ": resolved to version " + version;
+ if ( artifact.getRepository() != null )
+ {
+ message += " from repository " + artifact.getRepository().getId();
+ }
+ else
+ {
+ message += " from local repository";
+ }
+ getLogger().debug( message );
+ }
+ else
+ {
+ // Locally installed file is newer, don't use the resolved version
+ getLogger().debug( artifact.getArtifactId() + ": using locally installed snapshot" );
+ }
+ }
+ return version;
+ }
+
+ protected abstract String constructVersion( Versioning versioning, String baseVersion );
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/resolver/transform/ArtifactTransformation.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/resolver/transform/ArtifactTransformation.java
new file mode 100644
index 00000000..42604d75
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/resolver/transform/ArtifactTransformation.java
@@ -0,0 +1,86 @@
+package org.apache.maven.repository.legacy.resolver.transform;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.List;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.deployer.ArtifactDeploymentException;
+import org.apache.maven.artifact.installer.ArtifactInstallationException;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.repository.RepositoryRequest;
+import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
+import org.apache.maven.artifact.resolver.ArtifactResolutionException;
+
+/**
+ * @author <a href="mailto:jason@maven.org">Jason van Zyl </a>
+ */
+public interface ArtifactTransformation
+{
+ String ROLE = ArtifactTransformation.class.getName();
+
+ /**
+ * Take in a artifact and return the transformed artifact for locating in the remote repository. If no
+ * transformation has occurred the original artifact is returned.
+ *
+ * @param artifact Artifact to be transformed.
+ * @param request the repositories to check
+ */
+ void transformForResolve( Artifact artifact, RepositoryRequest request )
+ throws ArtifactResolutionException, ArtifactNotFoundException;
+
+ /**
+ * Take in a artifact and return the transformed artifact for locating in the remote repository. If no
+ * transformation has occurred the original artifact is returned.
+ *
+ * @param artifact Artifact to be transformed.
+ * @param remoteRepositories the repositories to check
+ * @param localRepository the local repository
+ */
+ void transformForResolve( Artifact artifact,
+ List<ArtifactRepository> remoteRepositories,
+ ArtifactRepository localRepository )
+ throws ArtifactResolutionException, ArtifactNotFoundException;
+
+ /**
+ * Take in a artifact and return the transformed artifact for locating in the local repository. If no
+ * transformation has occurred the original artifact is returned.
+ *
+ * @param artifact Artifact to be transformed.
+ * @param localRepository the local repository it will be stored in
+ */
+ void transformForInstall( Artifact artifact,
+ ArtifactRepository localRepository )
+ throws ArtifactInstallationException;
+
+ /**
+ * Take in a artifact and return the transformed artifact for distributing to remote repository. If no
+ * transformation has occurred the original artifact is returned.
+ *
+ * @param artifact Artifact to be transformed.
+ * @param remoteRepository the repository to deploy to
+ * @param localRepository the local repository
+ */
+ void transformForDeployment( Artifact artifact,
+ ArtifactRepository remoteRepository,
+ ArtifactRepository localRepository )
+ throws ArtifactDeploymentException;
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/resolver/transform/ArtifactTransformationManager.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/resolver/transform/ArtifactTransformationManager.java
new file mode 100644
index 00000000..f0ac9c89
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/resolver/transform/ArtifactTransformationManager.java
@@ -0,0 +1,82 @@
+package org.apache.maven.repository.legacy.resolver.transform;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.List;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.deployer.ArtifactDeploymentException;
+import org.apache.maven.artifact.installer.ArtifactInstallationException;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.repository.RepositoryRequest;
+import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
+import org.apache.maven.artifact.resolver.ArtifactResolutionException;
+
+/** Manages multiple ArtifactTransformation instances and applies them in succession. */
+public interface ArtifactTransformationManager
+{
+ String ROLE = ArtifactTransformationManager.class.getName();
+
+ /**
+ * Take in a artifact and return the transformed artifact for locating in the remote repository. If no
+ * transformation has occurred the original artifact is returned.
+ *
+ * @param artifact Artifact to be transformed.
+ * @param request the repositories to check
+ */
+ void transformForResolve( Artifact artifact, RepositoryRequest request )
+ throws ArtifactResolutionException, ArtifactNotFoundException;
+
+ /**
+ * Take in a artifact and return the transformed artifact for locating in the remote repository. If no
+ * transformation has occurred the original artifact is returned.
+ *
+ * @param artifact Artifact to be transformed.
+ * @param remoteRepositories the repositories to check
+ * @param localRepository the local repository
+ */
+ void transformForResolve( Artifact artifact, List<ArtifactRepository> remoteRepositories,
+ ArtifactRepository localRepository )
+ throws ArtifactResolutionException, ArtifactNotFoundException;
+
+ /**
+ * Take in a artifact and return the transformed artifact for locating in the local repository. If no
+ * transformation has occurred the original artifact is returned.
+ *
+ * @param artifact Artifact to be transformed.
+ * @param localRepository the local repository it will be stored in
+ */
+ void transformForInstall( Artifact artifact, ArtifactRepository localRepository )
+ throws ArtifactInstallationException;
+
+ /**
+ * Take in a artifact and return the transformed artifact for distributing to a remote repository. If no
+ * transformation has occurred the original artifact is returned.
+ *
+ * @param artifact Artifact to be transformed.
+ * @param remoteRepository the repository to deploy to
+ * @param localRepository the local repository the metadata is stored in
+ */
+ void transformForDeployment( Artifact artifact, ArtifactRepository remoteRepository,
+ ArtifactRepository localRepository )
+ throws ArtifactDeploymentException;
+
+ List getArtifactTransformations();
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/resolver/transform/DefaultArtifactTransformationManager.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/resolver/transform/DefaultArtifactTransformationManager.java
new file mode 100644
index 00000000..e9b1afbc
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/resolver/transform/DefaultArtifactTransformationManager.java
@@ -0,0 +1,86 @@
+package org.apache.maven.repository.legacy.resolver.transform;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.List;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.deployer.ArtifactDeploymentException;
+import org.apache.maven.artifact.installer.ArtifactInstallationException;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.repository.RepositoryRequest;
+import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
+import org.apache.maven.artifact.resolver.ArtifactResolutionException;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+
+/**
+ * @author Jason van Zyl
+ */
+@Component( role = ArtifactTransformationManager.class )
+public class DefaultArtifactTransformationManager
+ implements ArtifactTransformationManager
+{
+ @Requirement( role = ArtifactTransformation.class, hints = { "release", "latest", "snapshot" } )
+ private List<ArtifactTransformation> artifactTransformations;
+
+ public void transformForResolve( Artifact artifact, RepositoryRequest request )
+ throws ArtifactResolutionException, ArtifactNotFoundException
+ {
+ for ( ArtifactTransformation transform : artifactTransformations )
+ {
+ transform.transformForResolve( artifact, request );
+ }
+ }
+
+ public void transformForResolve( Artifact artifact, List<ArtifactRepository> remoteRepositories,
+ ArtifactRepository localRepository )
+ throws ArtifactResolutionException, ArtifactNotFoundException
+ {
+ for ( ArtifactTransformation transform : artifactTransformations )
+ {
+ transform.transformForResolve( artifact, remoteRepositories, localRepository );
+ }
+ }
+
+ public void transformForInstall( Artifact artifact, ArtifactRepository localRepository )
+ throws ArtifactInstallationException
+ {
+ for ( ArtifactTransformation transform : artifactTransformations )
+ {
+ transform.transformForInstall( artifact, localRepository );
+ }
+ }
+
+ public void transformForDeployment( Artifact artifact, ArtifactRepository remoteRepository,
+ ArtifactRepository localRepository )
+ throws ArtifactDeploymentException
+ {
+ for ( ArtifactTransformation transform : artifactTransformations )
+ {
+ transform.transformForDeployment( artifact, remoteRepository, localRepository );
+ }
+ }
+
+ public List getArtifactTransformations()
+ {
+ return artifactTransformations;
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/resolver/transform/LatestArtifactTransformation.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/resolver/transform/LatestArtifactTransformation.java
new file mode 100644
index 00000000..7b0e8513
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/resolver/transform/LatestArtifactTransformation.java
@@ -0,0 +1,74 @@
+package org.apache.maven.repository.legacy.resolver.transform;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.repository.RepositoryRequest;
+import org.apache.maven.artifact.repository.metadata.RepositoryMetadataResolutionException;
+import org.apache.maven.artifact.repository.metadata.Versioning;
+import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
+import org.apache.maven.artifact.resolver.ArtifactResolutionException;
+import org.codehaus.plexus.component.annotations.Component;
+
+@Component( role = ArtifactTransformation.class, hint = "latest" )
+public class LatestArtifactTransformation
+ extends AbstractVersionTransformation
+{
+
+ public void transformForResolve( Artifact artifact, RepositoryRequest request )
+ throws ArtifactResolutionException, ArtifactNotFoundException
+ {
+ if ( Artifact.LATEST_VERSION.equals( artifact.getVersion() ) )
+ {
+ try
+ {
+ String version = resolveVersion( artifact, request );
+ if ( Artifact.LATEST_VERSION.equals( version ) )
+ {
+ throw new ArtifactNotFoundException( "Unable to determine the latest version", artifact );
+ }
+
+ artifact.setBaseVersion( version );
+ artifact.updateVersion( version, request.getLocalRepository() );
+ }
+ catch ( RepositoryMetadataResolutionException e )
+ {
+ throw new ArtifactResolutionException( e.getMessage(), artifact, e );
+ }
+ }
+ }
+
+ public void transformForInstall( Artifact artifact, ArtifactRepository localRepository )
+ {
+ // metadata is added via addPluginArtifactMetadata
+ }
+
+ public void transformForDeployment( Artifact artifact, ArtifactRepository remoteRepository,
+ ArtifactRepository localRepository )
+ {
+ // metadata is added via addPluginArtifactMetadata
+ }
+
+ protected String constructVersion( Versioning versioning, String baseVersion )
+ {
+ return versioning.getLatest();
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/resolver/transform/ReleaseArtifactTransformation.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/resolver/transform/ReleaseArtifactTransformation.java
new file mode 100644
index 00000000..3714924c
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/resolver/transform/ReleaseArtifactTransformation.java
@@ -0,0 +1,100 @@
+package org.apache.maven.repository.legacy.resolver.transform;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.metadata.ArtifactMetadata;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.repository.RepositoryRequest;
+import org.apache.maven.artifact.repository.metadata.ArtifactRepositoryMetadata;
+import org.apache.maven.artifact.repository.metadata.RepositoryMetadataResolutionException;
+import org.apache.maven.artifact.repository.metadata.Versioning;
+import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
+import org.apache.maven.artifact.resolver.ArtifactResolutionException;
+import org.codehaus.plexus.component.annotations.Component;
+
+/**
+ * Change the version <code>RELEASE</code> to the appropriate release version from the remote repository.
+ *
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ */
+@Component( role = ArtifactTransformation.class, hint = "release" )
+public class ReleaseArtifactTransformation
+ extends AbstractVersionTransformation
+{
+
+ public void transformForResolve( Artifact artifact, RepositoryRequest request )
+ throws ArtifactResolutionException, ArtifactNotFoundException
+ {
+ if ( Artifact.RELEASE_VERSION.equals( artifact.getVersion() ) )
+ {
+ try
+ {
+ String version = resolveVersion( artifact, request );
+
+ if ( Artifact.RELEASE_VERSION.equals( version ) )
+ {
+ throw new ArtifactNotFoundException( "Unable to determine the release version", artifact );
+ }
+
+ artifact.setBaseVersion( version );
+ artifact.updateVersion( version, request.getLocalRepository() );
+ }
+ catch ( RepositoryMetadataResolutionException e )
+ {
+ throw new ArtifactResolutionException( e.getMessage(), artifact, e );
+ }
+ }
+ }
+
+ public void transformForInstall( Artifact artifact, ArtifactRepository localRepository )
+ {
+ ArtifactMetadata metadata = createMetadata( artifact );
+
+ artifact.addMetadata( metadata );
+ }
+
+ public void transformForDeployment( Artifact artifact, ArtifactRepository remoteRepository,
+ ArtifactRepository localRepository )
+ {
+ ArtifactMetadata metadata = createMetadata( artifact );
+
+ artifact.addMetadata( metadata );
+ }
+
+ private ArtifactMetadata createMetadata( Artifact artifact )
+ {
+ Versioning versioning = new Versioning();
+ versioning.updateTimestamp();
+ versioning.addVersion( artifact.getVersion() );
+
+ if ( artifact.isRelease() )
+ {
+ versioning.setRelease( artifact.getVersion() );
+ }
+
+ return new ArtifactRepositoryMetadata( artifact, versioning );
+ }
+
+ protected String constructVersion( Versioning versioning, String baseVersion )
+ {
+ return versioning.getRelease();
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/resolver/transform/SnapshotTransformation.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/resolver/transform/SnapshotTransformation.java
new file mode 100644
index 00000000..94f0ec0b
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/legacy/resolver/transform/SnapshotTransformation.java
@@ -0,0 +1,171 @@
+package org.apache.maven.repository.legacy.resolver.transform;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.TimeZone;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.deployer.ArtifactDeploymentException;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.repository.RepositoryRequest;
+import org.apache.maven.artifact.repository.metadata.Metadata;
+import org.apache.maven.artifact.repository.metadata.RepositoryMetadata;
+import org.apache.maven.artifact.repository.metadata.RepositoryMetadataResolutionException;
+import org.apache.maven.artifact.repository.metadata.Snapshot;
+import org.apache.maven.artifact.repository.metadata.SnapshotArtifactRepositoryMetadata;
+import org.apache.maven.artifact.repository.metadata.Versioning;
+import org.apache.maven.artifact.resolver.ArtifactResolutionException;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.util.StringUtils;
+
+/**
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ * @author <a href="mailto:mmaczka@interia.pl">Michal Maczka</a>
+ */
+@Component( role = ArtifactTransformation.class, hint = "snapshot" )
+public class SnapshotTransformation
+ extends AbstractVersionTransformation
+{
+ private String deploymentTimestamp;
+
+ private static final TimeZone UTC_TIME_ZONE = TimeZone.getTimeZone( "UTC" );
+
+ private static final String UTC_TIMESTAMP_PATTERN = "yyyyMMdd.HHmmss";
+
+ public void transformForResolve( Artifact artifact, RepositoryRequest request )
+ throws ArtifactResolutionException
+ {
+ // Only select snapshots that are unresolved (eg 1.0-SNAPSHOT, not 1.0-20050607.123456)
+ if ( artifact.isSnapshot() && artifact.getBaseVersion().equals( artifact.getVersion() ) )
+ {
+ try
+ {
+ String version = resolveVersion( artifact, request );
+ artifact.updateVersion( version, request.getLocalRepository() );
+ }
+ catch ( RepositoryMetadataResolutionException e )
+ {
+ throw new ArtifactResolutionException( e.getMessage(), artifact, e );
+ }
+ }
+ }
+
+ public void transformForInstall( Artifact artifact, ArtifactRepository localRepository )
+ {
+ if ( artifact.isSnapshot() )
+ {
+ Snapshot snapshot = new Snapshot();
+ snapshot.setLocalCopy( true );
+ RepositoryMetadata metadata = new SnapshotArtifactRepositoryMetadata( artifact, snapshot );
+
+ artifact.addMetadata( metadata );
+ }
+ }
+
+ public void transformForDeployment( Artifact artifact, ArtifactRepository remoteRepository,
+ ArtifactRepository localRepository )
+ throws ArtifactDeploymentException
+ {
+ if ( artifact.isSnapshot() )
+ {
+ Snapshot snapshot = new Snapshot();
+
+ snapshot.setTimestamp( getDeploymentTimestamp() );
+
+ // we update the build number anyway so that it doesn't get lost. It requires the timestamp to take effect
+ try
+ {
+ int buildNumber = resolveLatestSnapshotBuildNumber( artifact, localRepository, remoteRepository );
+
+ snapshot.setBuildNumber( buildNumber + 1 );
+ }
+ catch ( RepositoryMetadataResolutionException e )
+ {
+ throw new ArtifactDeploymentException( "Error retrieving previous build number for artifact '"
+ + artifact.getDependencyConflictId() + "': " + e.getMessage(), e );
+ }
+
+ RepositoryMetadata metadata = new SnapshotArtifactRepositoryMetadata( artifact, snapshot );
+
+ artifact.setResolvedVersion(
+ constructVersion( metadata.getMetadata().getVersioning(), artifact.getBaseVersion() ) );
+
+ artifact.addMetadata( metadata );
+ }
+ }
+
+ public String getDeploymentTimestamp()
+ {
+ if ( deploymentTimestamp == null )
+ {
+ deploymentTimestamp = getUtcDateFormatter().format( new Date() );
+ }
+ return deploymentTimestamp;
+ }
+
+ protected String constructVersion( Versioning versioning, String baseVersion )
+ {
+ String version = null;
+ Snapshot snapshot = versioning.getSnapshot();
+ if ( snapshot != null )
+ {
+ if ( snapshot.getTimestamp() != null && snapshot.getBuildNumber() > 0 )
+ {
+ String newVersion = snapshot.getTimestamp() + "-" + snapshot.getBuildNumber();
+ version = StringUtils.replace( baseVersion, Artifact.SNAPSHOT_VERSION, newVersion );
+ }
+ else
+ {
+ version = baseVersion;
+ }
+ }
+ return version;
+ }
+
+ private int resolveLatestSnapshotBuildNumber( Artifact artifact, ArtifactRepository localRepository,
+ ArtifactRepository remoteRepository )
+ throws RepositoryMetadataResolutionException
+ {
+ RepositoryMetadata metadata = new SnapshotArtifactRepositoryMetadata( artifact );
+
+ getLogger().info( "Retrieving previous build number from " + remoteRepository.getId() );
+ repositoryMetadataManager.resolveAlways( metadata, localRepository, remoteRepository );
+
+ int buildNumber = 0;
+ Metadata repoMetadata = metadata.getMetadata();
+ if ( ( repoMetadata != null )
+ && ( repoMetadata.getVersioning() != null && repoMetadata.getVersioning().getSnapshot() != null ) )
+ {
+ buildNumber = repoMetadata.getVersioning().getSnapshot().getBuildNumber();
+ }
+ return buildNumber;
+ }
+
+ public static DateFormat getUtcDateFormatter()
+ {
+ DateFormat utcDateFormatter = new SimpleDateFormat( UTC_TIMESTAMP_PATTERN );
+ utcDateFormatter.setTimeZone( UTC_TIME_ZONE );
+ return utcDateFormatter;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/metadata/ArtifactMetadata.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/metadata/ArtifactMetadata.java
new file mode 100644
index 00000000..2666eafb
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/metadata/ArtifactMetadata.java
@@ -0,0 +1,353 @@
+package org.apache.maven.repository.metadata;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Collection;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.ArtifactScopeEnum;
+
+/**
+ * Artifact Metadata that is resolved independent of Artifact itself.
+ *
+ * @author <a href="oleg@codehaus.org">Oleg Gusakov</a>
+ */
+public class ArtifactMetadata
+{
+ /**
+ * standard glorified artifact coordinates
+ */
+ protected String groupId;
+ protected String artifactId;
+ protected String version;
+ protected String type;
+ protected ArtifactScopeEnum artifactScope;
+ protected String classifier;
+
+ /**
+ * explanation: why this MD was chosen over it's siblings
+ * in the resulting structure (classpath for now)
+ */
+ protected String why;
+
+ /** dependencies of the artifact behind this metadata */
+ protected Collection<ArtifactMetadata> dependencies;
+
+ /** metadata URI */
+ protected String uri;
+
+ /** is metadata found anywhere */
+ protected boolean resolved = false;
+
+ /** does the actual artifact for this metadata exists */
+ protected boolean artifactExists = false;
+ /** artifact URI */
+ protected String artifactUri;
+
+ /** error message */
+ private String error;
+
+ //------------------------------------------------------------------
+ /**
+ *
+ */
+ public ArtifactMetadata( String name )
+ {
+ if ( name == null )
+ {
+ return;
+ }
+ int ind1 = name.indexOf( ':' );
+ int ind2 = name.lastIndexOf( ':' );
+
+ if ( ind1 == -1 || ind2 == -1 )
+ {
+ return;
+ }
+
+ this.groupId = name.substring( 0, ind1 );
+ if ( ind1 == ind2 )
+ {
+ this.artifactId = name.substring( ind1 + 1 );
+ }
+ else
+ {
+ this.artifactId = name.substring( ind1 + 1, ind2 );
+ this.version = name.substring( ind2 + 1 );
+ }
+ }
+
+ // ------------------------------------------------------------------
+ public ArtifactMetadata( String groupId, String name, String version )
+ {
+ this( groupId, name, version, null );
+ }
+ //------------------------------------------------------------------
+ public ArtifactMetadata( String groupId, String name, String version, String type )
+ {
+ this( groupId, name, version, type, null );
+ }
+
+ //------------------------------------------------------------------
+ public ArtifactMetadata( String groupId, String name, String version, String type, ArtifactScopeEnum artifactScope )
+ {
+ this( groupId, name, version, type, artifactScope, null );
+ }
+
+ //------------------------------------------------------------------
+ public ArtifactMetadata( String groupId, String name, String version, String type, ArtifactScopeEnum artifactScope,
+ String classifier )
+ {
+ this( groupId, name, version, type, artifactScope, classifier, null );
+ }
+ //------------------------------------------------------------------
+ public ArtifactMetadata( String groupId, String name, String version, String type, ArtifactScopeEnum artifactScope,
+ String classifier, String artifactUri )
+ {
+ this( groupId, name, version, type, artifactScope, classifier, artifactUri, null, true, null );
+ }
+ //------------------------------------------------------------------
+ public ArtifactMetadata( String groupId, String name, String version, String type, ArtifactScopeEnum artifactScope,
+ String classifier, String artifactUri, String why, boolean resolved, String error )
+ {
+ this.groupId = groupId;
+ this.artifactId = name;
+ this.version = version;
+ this.type = type;
+ this.artifactScope = artifactScope;
+ this.classifier = classifier;
+ this.artifactUri = artifactUri;
+ this.why = why;
+ this.resolved = resolved;
+ this.error = error;
+ }
+ //------------------------------------------------------------------
+ public ArtifactMetadata( String groupId, String name, String version, String type, String scopeString,
+ String classifier, String artifactUri, String why, boolean resolved, String error )
+ {
+ this( groupId, name, version, type,
+ scopeString == null ? ArtifactScopeEnum.DEFAULT_SCOPE : ArtifactScopeEnum.valueOf( scopeString ),
+ classifier, artifactUri, why, resolved, error );
+ }
+
+ //------------------------------------------------------------------
+ public ArtifactMetadata( Artifact af )
+ {
+ /*
+ if ( af != null )
+ {
+ init( af );
+ }
+ */
+ }
+ //------------------------------------------------------------------
+// public void init( ArtifactMetadata af )
+// {
+// setGroupId( af.getGroupId() );
+// setArtifactId( af.getArtifactId() );
+// setVersion( af.getVersion() );
+// setType( af.getType() );
+// setScope( af.getScope() );
+// setClassifier( af.getClassifier() );
+// //setUri( af.getDownloadUrl() );
+//
+// this.resolved = af.isResolved();
+// }
+
+ //------------------------------------------------------------------
+ @Override
+ public String toString()
+ {
+ return groupId + ":" + artifactId + ":" + version;
+ }
+
+ //------------------------------------------------------------------
+ public String toDomainString()
+ {
+ return groupId + ":" + artifactId;
+ }
+
+ //------------------------------------------------------------------
+ public String getGroupId()
+ {
+ return groupId;
+ }
+
+ public void setGroupId( String groupId )
+ {
+ this.groupId = groupId;
+ }
+
+ public String getArtifactId()
+ {
+ return artifactId;
+ }
+
+ public void setArtifactId( String name )
+ {
+ this.artifactId = name;
+ }
+
+ public String getVersion()
+ {
+ return version;
+ }
+
+ public void setVersion( String version )
+ {
+ this.version = version;
+ }
+
+ public String getType()
+ {
+ return type;
+ }
+
+ public String getCheckedType()
+ {
+ return type == null ? "jar" : type;
+ }
+
+ public void setType( String type )
+ {
+ this.type = type;
+ }
+
+ public ArtifactScopeEnum getArtifactScope()
+ {
+ return artifactScope == null ? ArtifactScopeEnum.DEFAULT_SCOPE : artifactScope;
+ }
+
+ public void setArtifactScope( ArtifactScopeEnum artifactScope )
+ {
+ this.artifactScope = artifactScope;
+ }
+
+ public void setScope( String scope )
+ {
+ this.artifactScope = scope == null ? ArtifactScopeEnum.DEFAULT_SCOPE : ArtifactScopeEnum.valueOf( scope );
+ }
+
+ public String getClassifier()
+ {
+ return classifier;
+ }
+
+ public void setClassifier( String classifier )
+ {
+ this.classifier = classifier;
+ }
+
+ public boolean isResolved()
+ {
+ return resolved;
+ }
+
+ public void setResolved( boolean resolved )
+ {
+ this.resolved = resolved;
+ }
+
+ public String getUri()
+ {
+ return uri;
+ }
+
+ public void setUri( String uri )
+ {
+ this.uri = uri;
+ }
+
+ public String getScope()
+ {
+ return getArtifactScope().getScope();
+ }
+
+ public ArtifactScopeEnum getScopeAsEnum()
+ {
+ return artifactScope == null ? ArtifactScopeEnum.DEFAULT_SCOPE : artifactScope;
+ }
+
+ public boolean isArtifactExists()
+ {
+ return artifactExists;
+ }
+
+ public void setArtifactExists( boolean artifactExists )
+ {
+ this.artifactExists = artifactExists;
+ }
+
+
+ public Collection<ArtifactMetadata> getDependencies()
+ {
+ return dependencies;
+ }
+
+ public void setDependencies( Collection<ArtifactMetadata> dependencies )
+ {
+ this.dependencies = dependencies;
+ }
+
+ public String getArtifactUri()
+ {
+ return artifactUri;
+ }
+
+ public void setArtifactUri( String artifactUri )
+ {
+ this.artifactUri = artifactUri;
+ }
+
+
+ public String getWhy()
+ {
+ return why;
+ }
+
+ public void setWhy( String why )
+ {
+ this.why = why;
+ }
+
+ //-------------------------------------------------------------------
+ public String getError()
+ {
+ return error;
+ }
+
+ public void setError( String error )
+ {
+ this.error = error;
+ }
+
+ public boolean isError()
+ {
+ return error == null;
+ }
+
+ //------------------------------------------------------------------
+ public String getDependencyConflictId()
+ {
+ return groupId + ":" + artifactId;
+ }
+ //------------------------------------------------------------------
+ //------------------------------------------------------------------
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/metadata/ClasspathContainer.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/metadata/ClasspathContainer.java
new file mode 100644
index 00000000..b0cb5b2f
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/metadata/ClasspathContainer.java
@@ -0,0 +1,144 @@
+package org.apache.maven.repository.metadata;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.maven.artifact.ArtifactScopeEnum;
+
+/**
+ * classpath container that is aware of the classpath scope
+ *
+ * @author <a href="oleg@codehaus.org">Oleg Gusakov</a>
+ *
+ */
+public class ClasspathContainer
+implements Iterable<ArtifactMetadata>
+{
+ private List<ArtifactMetadata> classpath;
+
+ private ArtifactScopeEnum scope;
+
+ // -------------------------------------------------------------------------------------------
+ public ClasspathContainer( ArtifactScopeEnum scope )
+ {
+ this.scope = ArtifactScopeEnum.checkScope( scope );
+ }
+
+ // -------------------------------------------------------------------------------------------
+ public ClasspathContainer( List<ArtifactMetadata> classpath, ArtifactScopeEnum scope )
+ {
+ this( scope );
+ this.classpath = classpath;
+ }
+
+ // -------------------------------------------------------------------------------------------
+ public Iterator<ArtifactMetadata> iterator()
+ {
+ return classpath == null ? null : classpath.iterator();
+ }
+
+ // -------------------------------------------------------------------------------------------
+ public ClasspathContainer add( ArtifactMetadata md )
+ {
+ if ( classpath == null )
+ {
+ classpath = new ArrayList<ArtifactMetadata>( 16 );
+ }
+
+ classpath.add( md );
+
+ return this;
+ }
+
+ // -------------------------------------------------------------------------------------------
+ public List<ArtifactMetadata> getClasspath()
+ {
+ return classpath;
+ }
+
+ // -------------------------------------------------------------------------------------------
+ public MetadataTreeNode getClasspathAsTree()
+ throws MetadataResolutionException
+ {
+ if ( classpath == null || classpath.size() < 1 )
+ {
+ return null;
+ }
+
+ MetadataTreeNode tree = null;
+ MetadataTreeNode parent = null;
+
+ for ( ArtifactMetadata md : classpath )
+ {
+ MetadataTreeNode node = new MetadataTreeNode( md, parent, md.isResolved(), md.getArtifactScope() );
+ if ( tree == null )
+ {
+ tree = node;
+ }
+
+ if ( parent != null )
+ {
+ parent.setNChildren( 1 );
+ parent.addChild( 0, node );
+ }
+
+ parent = node;
+
+ }
+ return tree;
+ }
+
+ public void setClasspath( List<ArtifactMetadata> classpath )
+ {
+ this.classpath = classpath;
+ }
+
+ public ArtifactScopeEnum getScope()
+ {
+ return scope;
+ }
+
+ public void setScope( ArtifactScopeEnum scope )
+ {
+ this.scope = scope;
+ }
+
+ // -------------------------------------------------------------------------------------------
+ @Override
+ public String toString()
+ {
+ StringBuilder sb = new StringBuilder( 256 );
+ sb.append( "[scope=" ).append( scope.getScope() );
+ if ( classpath != null )
+ {
+ for ( ArtifactMetadata md : classpath )
+ {
+ sb.append( ": " ).append( md.toString() ).append( '{' ).append( md.getArtifactUri() ).append( '}' );
+ }
+ }
+ sb.append( ']' );
+ return sb.toString();
+ }
+ // -------------------------------------------------------------------------------------------
+ // -------------------------------------------------------------------------------------------
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/metadata/ClasspathTransformation.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/metadata/ClasspathTransformation.java
new file mode 100644
index 00000000..eece4133
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/metadata/ClasspathTransformation.java
@@ -0,0 +1,46 @@
+package org.apache.maven.repository.metadata;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.artifact.ArtifactScopeEnum;
+
+/**
+ * Helper class to conver an Md Graph into some form of a classpath
+ *
+ * @author <a href="oleg@codehaus.org">Oleg Gusakov</a>
+ *
+ */
+public interface ClasspathTransformation
+{
+ String ROLE = ClasspathTransformation.class.getName();
+
+ /**
+ * Transform Graph into a Collection of metadata objects that
+ * could serve as a classpath for a particular scope
+ *
+ * @param dirtyGraph - dependency graph
+ * @param scope - which classpath to extract
+ * @param resolve - whether to resolve artifacts.
+ * @return Collection of metadata objects in the linked subgraph of the graph which
+ * contains the graph.getEntry() vertice
+ */
+ ClasspathContainer transform( MetadataGraph dirtyGraph, ArtifactScopeEnum scope, boolean resolve )
+ throws MetadataGraphTransformationException;
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/metadata/DefaultClasspathTransformation.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/metadata/DefaultClasspathTransformation.java
new file mode 100644
index 00000000..03984fbd
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/metadata/DefaultClasspathTransformation.java
@@ -0,0 +1,183 @@
+package org.apache.maven.repository.metadata;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.List;
+
+import org.apache.maven.artifact.ArtifactScopeEnum;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+
+/**
+ * default implementation of the metadata classpath transformer
+ *
+ * @author <a href="oleg@codehaus.org">Oleg Gusakov</a>
+ *
+ */
+@Component( role = ClasspathTransformation.class )
+public class DefaultClasspathTransformation
+ implements ClasspathTransformation
+{
+ @Requirement
+ GraphConflictResolver conflictResolver;
+
+ //----------------------------------------------------------------------------------------------------
+ public ClasspathContainer transform( MetadataGraph dirtyGraph, ArtifactScopeEnum scope, boolean resolve )
+ throws MetadataGraphTransformationException
+ {
+ try
+ {
+ if ( dirtyGraph == null || dirtyGraph.isEmpty() )
+ {
+ return null;
+ }
+
+ MetadataGraph cleanGraph = conflictResolver.resolveConflicts( dirtyGraph, scope );
+
+ if ( cleanGraph == null || cleanGraph.isEmpty() )
+ {
+ return null;
+ }
+
+ ClasspathContainer cpc = new ClasspathContainer( scope );
+ if ( cleanGraph.isEmptyEdges() )
+ {
+ // single entry in the classpath, populated from itself
+ ArtifactMetadata amd = cleanGraph.getEntry().getMd();
+ cpc.add( amd );
+ }
+ else
+ {
+ ClasspathGraphVisitor v = new ClasspathGraphVisitor( cleanGraph, cpc );
+ MetadataGraphVertex entry = cleanGraph.getEntry();
+ // entry point
+ v.visit( entry );
+ }
+
+ return cpc;
+ }
+ catch ( GraphConflictResolutionException e )
+ {
+ throw new MetadataGraphTransformationException( e );
+ }
+ }
+
+ //===================================================================================================
+ /**
+ * Helper class to traverse graph. Required to make the containing method thread-safe
+ * and yet use class level data to lessen stack usage in recursion
+ */
+ private class ClasspathGraphVisitor
+ {
+ MetadataGraph graph;
+
+ ClasspathContainer cpc;
+
+ List<MetadataGraphVertex> visited;
+
+ // -----------------------------------------------------------------------
+ protected ClasspathGraphVisitor( MetadataGraph cleanGraph, ClasspathContainer cpc )
+ {
+ this.cpc = cpc;
+ this.graph = cleanGraph;
+
+ visited = new ArrayList<MetadataGraphVertex>( cleanGraph.getVertices().size() );
+ }
+
+ // -----------------------------------------------------------------------
+ protected void visit( MetadataGraphVertex node ) // , String version, String artifactUri )
+ {
+ ArtifactMetadata md = node.getMd();
+ if ( visited.contains( node ) )
+ {
+ return;
+ }
+
+ cpc.add( md );
+//
+// TreeSet<MetadataGraphEdge> deps = new TreeSet<MetadataGraphEdge>(
+// new Comparator<MetadataGraphEdge>()
+// {
+// public int compare( MetadataGraphEdge e1
+// , MetadataGraphEdge e2
+// )
+// {
+// if( e1.getDepth() == e2.getDepth() )
+// {
+// if( e2.getPomOrder() == e1.getPomOrder() )
+// return e1.getTarget().toString().compareTo(e2.getTarget().toString() );
+//
+// return e2.getPomOrder() - e1.getPomOrder();
+// }
+//
+// return e2.getDepth() - e1.getDepth();
+// }
+// }
+// );
+
+ List<MetadataGraphEdge> exits = graph.getExcidentEdges( node );
+
+ if ( exits != null && exits.size() > 0 )
+ {
+ MetadataGraphEdge[] sortedExits = exits.toArray( new MetadataGraphEdge[exits.size()] );
+ Arrays.sort( sortedExits
+ ,
+ new Comparator<MetadataGraphEdge>()
+ {
+ public int compare( MetadataGraphEdge e1
+ , MetadataGraphEdge e2
+ )
+ {
+ if ( e1.getDepth() == e2.getDepth() )
+ {
+ if ( e2.getPomOrder() == e1.getPomOrder() )
+ {
+ return e1.getTarget().toString().compareTo( e2.getTarget().toString() );
+ }
+ return e2.getPomOrder() - e1.getPomOrder();
+ }
+
+ return e2.getDepth() - e1.getDepth();
+ }
+ }
+ );
+
+ for ( MetadataGraphEdge e : sortedExits )
+ {
+ MetadataGraphVertex targetNode = e.getTarget();
+ targetNode.getMd().setArtifactScope( e.getScope() );
+ targetNode.getMd().setWhy( e.getSource().getMd().toString() );
+ visit( targetNode );
+ }
+ }
+
+ }
+ //-----------------------------------------------------------------------
+ //-----------------------------------------------------------------------
+ }
+ //----------------------------------------------------------------------------------------------------
+ //----------------------------------------------------------------------------------------------------
+}
+
+
+
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/metadata/DefaultGraphConflictResolutionPolicy.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/metadata/DefaultGraphConflictResolutionPolicy.java
new file mode 100644
index 00000000..bb764227
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/metadata/DefaultGraphConflictResolutionPolicy.java
@@ -0,0 +1,73 @@
+package org.apache.maven.repository.metadata;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.artifact.versioning.ArtifactVersion;
+import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Configuration;
+
+/**
+ * @author <a href="mailto:oleg@codehaus.org">Oleg Gusakov</a>
+ *
+ */
+@Component( role = GraphConflictResolutionPolicy.class )
+public class DefaultGraphConflictResolutionPolicy
+ implements GraphConflictResolutionPolicy
+{
+ /**
+ * artifact, closer to the entry point, is selected
+ */
+ @Configuration( name = "closer-first", value = "true" )
+ private boolean closerFirst = true;
+
+ /**
+ * newer artifact is selected
+ */
+ @Configuration( name = "newer-first", value = "true" )
+ private boolean newerFirst = true;
+
+ public MetadataGraphEdge apply( MetadataGraphEdge e1, MetadataGraphEdge e2 )
+ {
+ int depth1 = e1.getDepth();
+ int depth2 = e2.getDepth();
+
+ if ( depth1 == depth2 )
+ {
+ ArtifactVersion v1 = new DefaultArtifactVersion( e1.getVersion() );
+ ArtifactVersion v2 = new DefaultArtifactVersion( e2.getVersion() );
+
+ if ( newerFirst )
+ {
+ return v1.compareTo( v2 ) > 0 ? e1 : e2;
+ }
+
+ return v1.compareTo( v2 ) > 0 ? e2 : e1;
+ }
+
+ if ( closerFirst )
+ {
+ return depth1 < depth2 ? e1 : e2;
+ }
+
+ return depth1 < depth2 ? e2 : e1;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/metadata/DefaultGraphConflictResolver.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/metadata/DefaultGraphConflictResolver.java
new file mode 100644
index 00000000..77060299
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/metadata/DefaultGraphConflictResolver.java
@@ -0,0 +1,249 @@
+package org.apache.maven.repository.metadata;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.TreeSet;
+
+import org.apache.maven.artifact.ArtifactScopeEnum;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+
+/**
+ * Default conflict resolver.Implements closer newer first policy by default, but could be configured via plexus
+ *
+ * @author <a href="mailto:oleg@codehaus.org">Oleg Gusakov</a>
+ */
+@Component( role = GraphConflictResolver.class )
+public class DefaultGraphConflictResolver
+ implements GraphConflictResolver
+{
+ /**
+ * artifact, closer to the entry point, is selected
+ */
+ @Requirement( role = GraphConflictResolutionPolicy.class )
+ protected GraphConflictResolutionPolicy policy;
+
+ // -------------------------------------------------------------------------------------
+ // -------------------------------------------------------------------------------------
+ public MetadataGraph resolveConflicts( MetadataGraph graph, ArtifactScopeEnum scope )
+ throws GraphConflictResolutionException
+ {
+ if ( policy == null )
+ {
+ throw new GraphConflictResolutionException( "no GraphConflictResolutionPolicy injected" );
+ }
+
+ if ( graph == null )
+ {
+ return null;
+ }
+
+ final MetadataGraphVertex entry = graph.getEntry();
+ if ( entry == null )
+ {
+ return null;
+ }
+
+ if ( graph.isEmpty() )
+ {
+ throw new GraphConflictResolutionException( "graph with an entry, but not vertices do not exist" );
+ }
+
+ if ( graph.isEmptyEdges() )
+ {
+ return null; // no edges - nothing to worry about
+ }
+
+ final TreeSet<MetadataGraphVertex> vertices = graph.getVertices();
+
+ try
+ {
+ // edge case - single vertex graph
+ if ( vertices.size() == 1 )
+ {
+ return new MetadataGraph( entry );
+ }
+
+ final ArtifactScopeEnum requestedScope = ArtifactScopeEnum.checkScope( scope );
+
+ MetadataGraph res = new MetadataGraph( vertices.size() );
+ res.setVersionedVertices( false );
+ res.setScopedVertices( false );
+
+ MetadataGraphVertex resEntry = res.addVertex( entry.getMd() );
+ res.setEntry( resEntry );
+
+ res.setScope( requestedScope );
+
+ for ( MetadataGraphVertex v : vertices )
+ {
+ final List<MetadataGraphEdge> ins = graph.getIncidentEdges( v );
+ final MetadataGraphEdge edge = cleanEdges( v, ins, requestedScope );
+
+ if ( edge == null )
+ { // no edges - don't need this vertex any more
+ if ( entry.equals( v ) )
+ { // unless it's an entry point.
+ // currently processing the entry point - it should not have any entry incident edges
+ res.getEntry().getMd().setWhy( "This is a graph entry point. No links." );
+ }
+ else
+ {
+ // System.out.println("--->"+v.getMd().toDomainString()
+ // +" has been terminated on this entry set\n-------------------\n"
+ // +ins
+ // +"\n-------------------\n"
+ // );
+ }
+ }
+ else
+ {
+ // System.out.println("+++>"+v.getMd().toDomainString()+" still has "+edge.toString() );
+ // fill in domain md with actual version data
+ ArtifactMetadata md = v.getMd();
+ ArtifactMetadata newMd =
+ new ArtifactMetadata( md.getGroupId(), md.getArtifactId(), edge.getVersion(), md.getType(),
+ md.getScopeAsEnum(), md.getClassifier(), edge.getArtifactUri(),
+ edge.getSource() == null ? "" : edge.getSource().getMd().toString(),
+ edge.isResolved(), edge.getTarget() == null ? null
+ : edge.getTarget().getMd().getError() );
+ MetadataGraphVertex newV = res.addVertex( newMd );
+ MetadataGraphVertex sourceV = res.addVertex( edge.getSource().getMd() );
+
+ res.addEdge( sourceV, newV, edge );
+ }
+ }
+ MetadataGraph linkedRes = findLinkedSubgraph( res );
+ // System.err.println("Original graph("+graph.getVertices().size()+"):\n"+graph.toString());
+ // System.err.println("Cleaned("+requestedScope+") graph("+res.getVertices().size()+"):\n"+res.toString());
+ // System.err.println("Linked("+requestedScope+")
+ // subgraph("+linkedRes.getVertices().size()+"):\n"+linkedRes.toString());
+ return linkedRes;
+ }
+ catch ( MetadataResolutionException e )
+ {
+ throw new GraphConflictResolutionException( e );
+ }
+ }
+
+ // -------------------------------------------------------------------------------------
+ private MetadataGraph findLinkedSubgraph( MetadataGraph g )
+ {
+ if ( g.getVertices().size() == 1 )
+ {
+ return g;
+ }
+
+ List<MetadataGraphVertex> visited = new ArrayList<MetadataGraphVertex>( g.getVertices().size() );
+ visit( g.getEntry(), visited, g );
+
+ List<MetadataGraphVertex> dropList = new ArrayList<MetadataGraphVertex>( g.getVertices().size() );
+
+ // collect drop list
+ for ( MetadataGraphVertex v : g.getVertices() )
+ {
+ if ( !visited.contains( v ) )
+ {
+ dropList.add( v );
+ }
+ }
+
+ if ( dropList.size() < 1 )
+ {
+ return g;
+ }
+
+ // now - drop vertices
+ TreeSet<MetadataGraphVertex> vertices = g.getVertices();
+ for ( MetadataGraphVertex v : dropList )
+ {
+ vertices.remove( v );
+ }
+
+ return g;
+ }
+
+ // -------------------------------------------------------------------------------------
+ private void visit( MetadataGraphVertex from, List<MetadataGraphVertex> visited, MetadataGraph graph )
+ {
+ if ( visited.contains( from ) )
+ {
+ return;
+ }
+
+ visited.add( from );
+
+ List<MetadataGraphEdge> exitList = graph.getExcidentEdges( from );
+ // String s = "|---> "+from.getMd().toString()+" - "+(exitList == null ? -1 : exitList.size()) + " exit links";
+ if ( exitList != null && exitList.size() > 0 )
+ {
+ for ( MetadataGraphEdge e : graph.getExcidentEdges( from ) )
+ {
+ visit( e.getTarget(), visited, graph );
+ }
+ }
+ }
+
+ // -------------------------------------------------------------------------------------
+ private MetadataGraphEdge cleanEdges( MetadataGraphVertex v, List<MetadataGraphEdge> edges,
+ ArtifactScopeEnum scope )
+ {
+ if ( edges == null || edges.isEmpty() )
+ {
+ return null;
+ }
+
+ if ( edges.size() == 1 )
+ {
+ MetadataGraphEdge e = edges.get( 0 );
+ if ( scope.encloses( e.getScope() ) )
+ {
+ return e;
+ }
+
+ return null;
+ }
+
+ MetadataGraphEdge res = null;
+
+ for ( MetadataGraphEdge e : edges )
+ {
+ if ( !scope.encloses( e.getScope() ) )
+ {
+ continue;
+ }
+
+ if ( res == null )
+ {
+ res = e;
+ }
+ else
+ {
+ res = policy.apply( e, res );
+ }
+ }
+
+ return res;
+ }
+ // -------------------------------------------------------------------------------------
+ // -------------------------------------------------------------------------------------
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/metadata/GraphConflictResolutionException.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/metadata/GraphConflictResolutionException.java
new file mode 100644
index 00000000..035904aa
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/metadata/GraphConflictResolutionException.java
@@ -0,0 +1,51 @@
+package org.apache.maven.repository.metadata;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ *
+ * @author <a href="mailto:oleg@codehaus.org">Oleg Gusakov</a>
+ *
+ */
+public class GraphConflictResolutionException
+ extends Exception
+{
+ private static final long serialVersionUID = 2677613140287940255L;
+
+ public GraphConflictResolutionException()
+ {
+ }
+
+ public GraphConflictResolutionException( String message )
+ {
+ super( message );
+ }
+
+ public GraphConflictResolutionException( Throwable cause )
+ {
+ super( cause );
+ }
+
+ public GraphConflictResolutionException( String message, Throwable cause )
+ {
+ super( message, cause );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/metadata/GraphConflictResolutionPolicy.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/metadata/GraphConflictResolutionPolicy.java
new file mode 100644
index 00000000..979d3831
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/metadata/GraphConflictResolutionPolicy.java
@@ -0,0 +1,35 @@
+package org.apache.maven.repository.metadata;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * MetadataGraph edge selection policy. Complements
+ * GraphConflictResolver by being injected into it
+ *
+ * @author <a href="mailto:oleg@codehaus.org">Oleg Gusakov</a>
+ *
+ */
+
+public interface GraphConflictResolutionPolicy
+{
+ String ROLE = GraphConflictResolutionPolicy.class.getName();
+
+ MetadataGraphEdge apply( MetadataGraphEdge e1, MetadataGraphEdge e2 );
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/metadata/GraphConflictResolver.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/metadata/GraphConflictResolver.java
new file mode 100644
index 00000000..ef70baa2
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/metadata/GraphConflictResolver.java
@@ -0,0 +1,48 @@
+package org.apache.maven.repository.metadata;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.artifact.ArtifactScopeEnum;
+
+/**
+ * Resolves conflicts in the supplied dependency graph.
+ * Different implementations will implement different conflict resolution policies.
+ *
+ * @author <a href="mailto:oleg@codehaus.org">Oleg Gusakov</a>
+ */
+public interface GraphConflictResolver
+{
+ String ROLE = GraphConflictResolver.class.getName();
+
+ /**
+ * Cleanses the supplied graph by leaving only one directed versioned edge\
+ * between any two nodes, if multiple exists. Uses scope relationships, defined
+ * in <code>ArtifactScopeEnum</code>
+ *
+ * @param graph the "dirty" graph to be simplified via conflict resolution
+ * @param scope scope for which the graph should be resolved
+ *
+ * @return resulting "clean" graph for the specified scope
+ *
+ * @since 3.0
+ */
+ MetadataGraph resolveConflicts( MetadataGraph graph, ArtifactScopeEnum scope )
+ throws GraphConflictResolutionException;
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/metadata/MetadataGraph.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/metadata/MetadataGraph.java
new file mode 100644
index 00000000..55b02504
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/metadata/MetadataGraph.java
@@ -0,0 +1,523 @@
+package org.apache.maven.repository.metadata;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeSet;
+
+import org.apache.maven.artifact.ArtifactScopeEnum;
+
+/**
+ * maven dependency metadata graph
+ *
+ * @author <a href="oleg@codehaus.org">Oleg Gusakov</a>
+ *
+ */
+public class MetadataGraph
+{
+ public static final int DEFAULT_VERTICES = 32;
+ public static final int DEFAULT_EDGES = 64;
+
+ // flags to indicate the granularity of vertices
+ private boolean versionedVertices = false;
+ private boolean scopedVertices = false;
+ /**
+ * the entry point we started building the graph from
+ */
+ MetadataGraphVertex entry;
+
+ // graph vertices
+ TreeSet<MetadataGraphVertex> vertices;
+
+ /**
+ * incident and excident edges per node
+ */
+ Map<MetadataGraphVertex, List<MetadataGraphEdge>> incidentEdges;
+ Map<MetadataGraphVertex, List<MetadataGraphEdge>> excidentEdges;
+
+ /**
+ * null in dirty graph, actual
+ * scope for conflict-resolved graph
+ */
+ ArtifactScopeEnum scope;
+
+ //------------------------------------------------------------------------
+ /**
+ * init graph
+ */
+ public MetadataGraph( int nVertices )
+ {
+ init( nVertices, 2 * nVertices );
+ }
+ public MetadataGraph( int nVertices, int nEdges )
+ {
+ init( nVertices, nEdges );
+ }
+ //------------------------------------------------------------------------
+ /**
+ * construct a single vertex
+ */
+ public MetadataGraph( MetadataGraphVertex entry )
+ throws MetadataResolutionException
+ {
+ checkVertex( entry );
+ checkVertices( 1 );
+
+ entry.setCompareVersion( versionedVertices );
+ entry.setCompareScope( scopedVertices );
+
+ vertices.add( entry );
+ this.entry = entry;
+ }
+ //------------------------------------------------------------------------
+ /**
+ * construct graph from a "dirty" tree
+ */
+ public MetadataGraph( MetadataTreeNode tree )
+ throws MetadataResolutionException
+ {
+ this( tree, false, false );
+ }
+ //------------------------------------------------------------------------
+ /**
+ * construct graph from a "dirty" tree
+ *
+ * @param tree "dirty" tree root
+ * @param versionedVertices true if graph nodes should be versioned (different versions -> different nodes)
+ * @param scopedVertices true if graph nodes should be versioned and scoped (different versions and/or scopes -> different nodes)
+ *
+ */
+ public MetadataGraph( MetadataTreeNode tree, boolean versionedVertices, boolean scopedVertices )
+ throws MetadataResolutionException
+ {
+ if ( tree == null )
+ {
+ throw new MetadataResolutionException( "tree is null" );
+ }
+
+ setVersionedVertices( versionedVertices );
+ setScopedVertices( scopedVertices );
+
+ this.versionedVertices = scopedVertices || versionedVertices;
+ this.scopedVertices = scopedVertices;
+
+ int count = countNodes( tree );
+
+ init( count, count + ( count / 2 ) );
+
+ processTreeNodes( null, tree, 0, 0 );
+ }
+ //------------------------------------------------------------------------
+ private void processTreeNodes( MetadataGraphVertex parentVertex, MetadataTreeNode node, int depth, int pomOrder )
+ throws MetadataResolutionException
+ {
+ if ( node == null )
+ {
+ return;
+ }
+
+ MetadataGraphVertex vertex = new MetadataGraphVertex( node.md, versionedVertices, scopedVertices );
+ if ( !vertices.contains( vertex ) )
+ {
+ vertices.add( vertex );
+ }
+
+ if ( parentVertex != null ) // then create the edge
+ {
+ ArtifactMetadata md = node.getMd();
+ MetadataGraphEdge e =
+ new MetadataGraphEdge( md.version, md.resolved, md.artifactScope, md.artifactUri, depth, pomOrder );
+ addEdge( parentVertex, vertex, e );
+ }
+ else
+ {
+ entry = vertex;
+ }
+
+ MetadataTreeNode[] kids = node.getChildren();
+ if ( kids == null || kids.length < 1 )
+ {
+ return;
+ }
+
+ for ( int i = 0; i < kids.length; i++ )
+ {
+ MetadataTreeNode n = kids[i];
+ processTreeNodes( vertex, n, depth + 1, i );
+ }
+ }
+ //------------------------------------------------------------------------
+ public MetadataGraphVertex findVertex( ArtifactMetadata md )
+ {
+ if ( md == null || vertices == null || vertices.size() < 1 )
+ {
+ return null;
+ }
+
+ MetadataGraphVertex v = new MetadataGraphVertex( md );
+ v.setCompareVersion( versionedVertices );
+ v.setCompareScope( scopedVertices );
+
+ for ( MetadataGraphVertex gv : vertices )
+ {
+ if ( gv.equals( v ) )
+ {
+ return gv;
+ }
+ }
+
+ return null;
+ }
+ //------------------------------------------------------------------------
+ public MetadataGraphVertex addVertex( ArtifactMetadata md )
+ {
+ if ( md == null )
+ {
+ return null;
+ }
+
+ checkVertices();
+
+ MetadataGraphVertex v = findVertex( md );
+ if ( v != null )
+ {
+ return v;
+ }
+
+ v = new MetadataGraphVertex( md );
+
+ v.setCompareVersion( versionedVertices );
+ v.setCompareScope( scopedVertices );
+
+ vertices.add( v );
+ return v;
+ }
+ //------------------------------------------------------------------------
+ /**
+ * init graph
+ */
+ private void init( int nVertices, int nEdges )
+ {
+ int nV = nVertices;
+ if ( nVertices < 1 )
+ {
+ nV = 1;
+ }
+
+ checkVertices( nV );
+
+ int nE = nVertices;
+ if ( nEdges <= nV )
+ {
+ nE = 2 * nE;
+ }
+
+ checkEdges( nE );
+ }
+
+ private void checkVertices()
+ {
+ checkVertices( DEFAULT_VERTICES );
+ }
+
+ private void checkVertices( int nVertices )
+ {
+ if ( vertices == null )
+ {
+ vertices = new TreeSet<MetadataGraphVertex>();
+ }
+ }
+ private void checkEdges()
+ {
+ int count = DEFAULT_EDGES;
+
+ if ( vertices != null )
+ {
+ count = vertices.size() + vertices.size() / 2;
+ }
+
+ checkEdges( count );
+ }
+ private void checkEdges( int nEdges )
+ {
+ if ( incidentEdges == null )
+ {
+ incidentEdges = new HashMap<MetadataGraphVertex, List<MetadataGraphEdge>>( nEdges );
+ }
+ if ( excidentEdges == null )
+ {
+ excidentEdges = new HashMap<MetadataGraphVertex, List<MetadataGraphEdge>>( nEdges );
+ }
+ }
+ //------------------------------------------------------------------------
+ private static void checkVertex( MetadataGraphVertex v )
+ throws MetadataResolutionException
+ {
+ if ( v == null )
+ {
+ throw new MetadataResolutionException( "null vertex" );
+ }
+ if ( v.getMd() == null )
+ {
+ throw new MetadataResolutionException( "vertex without metadata" );
+ }
+ }
+ //------------------------------------------------------------------------
+ private static void checkEdge( MetadataGraphEdge e )
+ throws MetadataResolutionException
+ {
+ if ( e == null )
+ {
+ throw new MetadataResolutionException( "badly formed edge" );
+ }
+ }
+ //------------------------------------------------------------------------
+ public List<MetadataGraphEdge> getEdgesBetween( MetadataGraphVertex vFrom, MetadataGraphVertex vTo )
+ {
+ List<MetadataGraphEdge> edges = getIncidentEdges( vTo );
+ if ( edges == null || edges.isEmpty() )
+ {
+ return null;
+ }
+
+ List<MetadataGraphEdge> res = new ArrayList<MetadataGraphEdge>( edges.size() );
+
+ for ( MetadataGraphEdge e : edges )
+ {
+ if ( e.getSource().equals( vFrom ) )
+ {
+ res.add( e );
+ }
+ }
+
+ return res;
+ }
+ //------------------------------------------------------------------------
+ public MetadataGraph addEdge( MetadataGraphVertex vFrom, MetadataGraphVertex vTo, MetadataGraphEdge e )
+ throws MetadataResolutionException
+ {
+ checkVertex( vFrom );
+ checkVertex( vTo );
+
+ checkVertices();
+
+ checkEdge( e );
+ checkEdges();
+
+ e.setSource( vFrom );
+ e.setTarget( vTo );
+
+ vFrom.setCompareVersion( versionedVertices );
+ vFrom.setCompareScope( scopedVertices );
+
+ List<MetadataGraphEdge> exList = excidentEdges.get( vFrom );
+ if ( exList == null )
+ {
+ exList = new ArrayList<MetadataGraphEdge>();
+ excidentEdges.put( vFrom, exList );
+ }
+
+ if ( !exList.contains( e ) )
+ {
+ exList.add( e );
+ }
+
+ List<MetadataGraphEdge> inList = incidentEdges.get( vTo );
+ if ( inList == null )
+ {
+ inList = new ArrayList<MetadataGraphEdge>();
+ incidentEdges.put( vTo, inList );
+ }
+
+ if ( !inList.contains( e ) )
+ {
+ inList.add( e );
+ }
+
+ return this;
+ }
+ //------------------------------------------------------------------------
+ public MetadataGraph removeVertex( MetadataGraphVertex v )
+ {
+ if ( vertices != null && v != null )
+ {
+ vertices.remove( v );
+ }
+
+ if ( incidentEdges != null )
+ {
+ incidentEdges.remove( v );
+ }
+
+ if ( excidentEdges != null )
+ {
+ excidentEdges.remove( v );
+ }
+
+ return this;
+
+ }
+ //------------------------------------------------------------------------
+ private static int countNodes( MetadataTreeNode tree )
+ {
+ if ( tree == null )
+ {
+ return 0;
+ }
+
+ int count = 1;
+ MetadataTreeNode[] kids = tree.getChildren();
+ if ( kids == null || kids.length < 1 )
+ {
+ return count;
+ }
+ for ( MetadataTreeNode n : kids )
+ {
+ count += countNodes( n );
+ }
+
+ return count;
+ }
+
+ //------------------------------------------------------------------------
+ public MetadataGraphVertex getEntry()
+ {
+ return entry;
+ }
+
+ public void setEntry( MetadataGraphVertex entry )
+ {
+ this.entry = entry;
+ }
+
+ public TreeSet<MetadataGraphVertex> getVertices()
+ {
+ return vertices;
+ }
+
+ public List<MetadataGraphEdge> getIncidentEdges( MetadataGraphVertex vertex )
+ {
+ checkEdges();
+ return incidentEdges.get( vertex );
+ }
+
+ public List<MetadataGraphEdge> getExcidentEdges( MetadataGraphVertex vertex )
+ {
+ checkEdges();
+ return excidentEdges.get( vertex );
+ }
+
+ public boolean isVersionedVertices()
+ {
+ return versionedVertices;
+ }
+
+ public void setVersionedVertices( boolean versionedVertices )
+ {
+ this.versionedVertices = versionedVertices;
+ }
+
+ public boolean isScopedVertices()
+ {
+ return scopedVertices;
+ }
+
+ public void setScopedVertices( boolean scopedVertices )
+ {
+ this.scopedVertices = scopedVertices;
+
+ // scoped graph is versioned by definition
+ if ( scopedVertices )
+ {
+ versionedVertices = true;
+ }
+ }
+
+ public ArtifactScopeEnum getScope()
+ {
+ return scope;
+ }
+
+ public void setScope( ArtifactScopeEnum scope )
+ {
+ this.scope = scope;
+ }
+
+ // ------------------------------------------------------------------------
+ public boolean isEmpty()
+ {
+ return entry == null || vertices == null || vertices.isEmpty();
+ }
+
+ //------------------------------------------------------------------------
+ public boolean isEmptyEdges()
+ {
+ return isEmpty() || incidentEdges == null || incidentEdges.isEmpty();
+ }
+ //------------------------------------------------------------------------
+ @Override
+ public String toString()
+ {
+ StringBuilder sb = new StringBuilder( 512 );
+ if ( isEmpty() )
+ {
+ return "empty";
+ }
+ for ( MetadataGraphVertex v : vertices )
+ {
+ sb.append( "Vertex: " ).append( v.getMd().toString() ).append( "\n" );
+ List<MetadataGraphEdge> ins = getIncidentEdges( v );
+ if ( ins != null )
+ {
+ for ( MetadataGraphEdge e : ins )
+ {
+ sb.append( " from : " ).append( e.toString() ).append( "\n" );
+ }
+ }
+ else
+ {
+ sb.append( " no entries\n" );
+ }
+
+ List<MetadataGraphEdge> outs = getExcidentEdges( v );
+ if ( outs != null )
+ {
+ for ( MetadataGraphEdge e : outs )
+ {
+ sb.append( " to : " ).append( e.toString() ).append( "\n" );
+ }
+ }
+ else
+ {
+ sb.append( " no exit\n" );
+ }
+
+ sb.append( "-------------------------------------------------\n" );
+ }
+ sb.append( "=============================================================\n" );
+ return sb.toString();
+ }
+
+ //------------------------------------------------------------------------
+ //------------------------------------------------------------------------
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/metadata/MetadataGraphEdge.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/metadata/MetadataGraphEdge.java
new file mode 100644
index 00000000..5f16df06
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/metadata/MetadataGraphEdge.java
@@ -0,0 +1,189 @@
+package org.apache.maven.repository.metadata;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.artifact.ArtifactScopeEnum;
+
+/**
+ * metadata graph edge - combination of version, scope and depth define
+ * an edge in the graph
+ *
+ * @author <a href="oleg@codehaus.org">Oleg Gusakov</a>
+ *
+ */
+
+public class MetadataGraphEdge
+{
+ String version;
+ ArtifactScopeEnum scope;
+ int depth = -1;
+ int pomOrder = -1;
+ boolean resolved = true;
+ String artifactUri;
+
+ /**
+ * capturing where this link came from
+ * and where it is linked to.
+ *
+ * In the first implementation only source used for explanatory function
+ */
+ MetadataGraphVertex source;
+ MetadataGraphVertex target;
+
+ //----------------------------------------------------------------------------
+ public MetadataGraphEdge( String version, boolean resolved, ArtifactScopeEnum scope, String artifactUri, int depth,
+ int pomOrder )
+ {
+ super();
+ this.version = version;
+ this.scope = scope;
+ this.artifactUri = artifactUri;
+ this.depth = depth;
+ this.resolved = resolved;
+ this.pomOrder = pomOrder;
+ }
+ //----------------------------------------------------------------------------
+ /**
+ * helper for equals
+ */
+ private static boolean objectsEqual( Object o1, Object o2 )
+ {
+ if ( o1 == null && o2 == null )
+ {
+ return true;
+ }
+ if ( o1 == null || o2 == null )
+ {
+ return false; // as they are not both null
+ }
+ return o1.equals( o2 );
+ }
+
+ //----------------------------------------------------------------------------
+ /**
+ * used to eliminate exact duplicates in the edge list
+ */
+ @Override
+ public boolean equals( Object o )
+ {
+ if ( o instanceof MetadataGraphEdge )
+ {
+ MetadataGraphEdge e = (MetadataGraphEdge) o;
+
+ return objectsEqual( version, e.version )
+ && ArtifactScopeEnum.checkScope( scope ).getScope().equals( ArtifactScopeEnum.checkScope( e.scope ).getScope() )
+ && depth == e.depth;
+ }
+ return false;
+ }
+
+ //----------------------------------------------------------------------------
+ public String getVersion()
+ {
+ return version;
+ }
+
+ public void setVersion( String version )
+ {
+ this.version = version;
+ }
+
+ public ArtifactScopeEnum getScope()
+ {
+ return scope;
+ }
+
+ public void setScope( ArtifactScopeEnum scope )
+ {
+ this.scope = scope;
+ }
+
+ public int getDepth()
+ {
+ return depth;
+ }
+
+ public void setDepth( int depth )
+ {
+ this.depth = depth;
+ }
+
+ public boolean isResolved()
+ {
+ return resolved;
+ }
+
+ public void setResolved( boolean resolved )
+ {
+ this.resolved = resolved;
+ }
+
+ public int getPomOrder()
+ {
+ return pomOrder;
+ }
+
+ public void setPomOrder( int pomOrder )
+ {
+ this.pomOrder = pomOrder;
+ }
+
+ public String getArtifactUri()
+ {
+ return artifactUri;
+ }
+
+ public void setArtifactUri( String artifactUri )
+ {
+ this.artifactUri = artifactUri;
+ }
+
+ public MetadataGraphVertex getSource()
+ {
+ return source;
+ }
+
+ public void setSource( MetadataGraphVertex source )
+ {
+ this.source = source;
+ }
+
+ public MetadataGraphVertex getTarget()
+ {
+ return target;
+ }
+
+ public void setTarget( MetadataGraphVertex target )
+ {
+ this.target = target;
+ }
+
+ @Override
+ public String toString()
+ {
+ return "[ " + "FROM:("
+ + ( source == null ? "no source" : ( source.md == null ? "no source MD" : source.md.toString() ) ) + ") "
+ + "TO:(" + ( target == null ? "no target" : ( target.md == null ? "no target MD" : target.md.toString() ) )
+ + ") " + "version=" + version + ", scope=" + ( scope == null ? "null" : scope.getScope() ) + ", depth="
+ + depth + "]";
+ }
+ //----------------------------------------------------------------------------
+ //----------------------------------------------------------------------------
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/metadata/MetadataGraphTransformationException.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/metadata/MetadataGraphTransformationException.java
new file mode 100644
index 00000000..16a34a8c
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/metadata/MetadataGraphTransformationException.java
@@ -0,0 +1,50 @@
+package org.apache.maven.repository.metadata;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * @author <a href="oleg@codehaus.org">Oleg Gusakov</a>
+ *
+ */
+public class MetadataGraphTransformationException
+ extends Exception
+{
+ private static final long serialVersionUID = -4029897098314019152L;
+
+ public MetadataGraphTransformationException()
+ {
+ }
+
+ public MetadataGraphTransformationException( String message )
+ {
+ super( message );
+ }
+
+ public MetadataGraphTransformationException( Throwable cause )
+ {
+ super( cause );
+ }
+
+ public MetadataGraphTransformationException( String message, Throwable cause )
+ {
+ super( message, cause );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/metadata/MetadataGraphVertex.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/metadata/MetadataGraphVertex.java
new file mode 100644
index 00000000..bdccf6a5
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/metadata/MetadataGraphVertex.java
@@ -0,0 +1,216 @@
+package org.apache.maven.repository.metadata;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.artifact.ArtifactScopeEnum;
+
+/**
+ * metadata graph vertice - just a wrapper around artifact's metadata
+ *
+ * @author <a href="oleg@codehaus.org">Oleg Gusakov</a>
+ */
+public class MetadataGraphVertex
+ implements Comparable<MetadataGraphVertex>
+{
+ ArtifactMetadata md;
+
+ // indications to use these in comparrison
+ private boolean compareVersion = false;
+ private boolean compareScope = false;
+
+ public MetadataGraphVertex( ArtifactMetadata md )
+ {
+ super();
+ this.md = md;
+ }
+
+ public MetadataGraphVertex( ArtifactMetadata md, boolean compareVersion, boolean compareScope )
+ {
+ this( md );
+ this.compareVersion = compareVersion;
+ this.compareScope = compareScope;
+ }
+
+ public ArtifactMetadata getMd()
+ {
+ return md;
+ }
+
+ public void setMd( ArtifactMetadata md )
+ {
+ this.md = md;
+ }
+
+ // ---------------------------------------------------------------------
+ public boolean isCompareVersion()
+ {
+ return compareVersion;
+ }
+
+ public void setCompareVersion( boolean compareVersion )
+ {
+ this.compareVersion = compareVersion;
+ }
+
+ public boolean isCompareScope()
+ {
+ return compareScope;
+ }
+
+ public void setCompareScope( boolean compareScope )
+ {
+ this.compareScope = compareScope;
+ }
+
+ // ---------------------------------------------------------------------
+ @Override
+ public String toString()
+ {
+ return "[" + ( md == null ? "no metadata" : md.toString() ) + "]";
+ }
+
+ // ---------------------------------------------------------------------
+ private static int compareStrings( String s1, String s2 )
+ {
+ if ( s1 == null && s2 == null )
+ {
+ return 0;
+ }
+
+ if ( s1 == null /* && s2 != null */ )
+ {
+ return -1;
+ }
+
+ if ( /* s1 != null && */ s2 == null )
+ {
+ return 1;
+ }
+
+ return s1.compareTo( s2 );
+ }
+
+ // ---------------------------------------------------------------------
+ public int compareTo( MetadataGraphVertex vertex )
+ {
+ if ( vertex == null || vertex.getMd() == null )
+ {
+ return 1;
+ }
+
+ ArtifactMetadata vmd = vertex.getMd();
+
+ if ( vmd == null )
+ {
+ if ( md == null )
+ {
+ return 0;
+ }
+ else
+ {
+ return 1;
+ }
+ }
+
+ int g = compareStrings( md.groupId, vmd.groupId );
+
+ if ( g == 0 )
+ {
+ int a = compareStrings( md.artifactId, vmd.artifactId );
+ if ( a == 0 )
+ {
+ if ( compareVersion )
+ {
+ int v = compareStrings( md.version, vmd.version );
+ if ( v == 0 )
+ {
+ if ( compareScope )
+ {
+ String s1 = ArtifactScopeEnum.checkScope( md.artifactScope ).getScope();
+ String s2 = ArtifactScopeEnum.checkScope( vmd.artifactScope ).getScope();
+ return s1.compareTo( s2 );
+ }
+ else
+ {
+ return 0;
+ }
+ }
+ else
+ {
+ return v;
+ }
+ }
+ else
+ {
+ return 0;
+ }
+ }
+ else
+ {
+ return a;
+ }
+ }
+
+ return g;
+ }
+
+ // ---------------------------------------------------------------------
+ @Override
+ public boolean equals( Object vo )
+ {
+ if ( vo == null || !( vo instanceof MetadataGraphVertex ) )
+ {
+ return false;
+ }
+ return compareTo( (MetadataGraphVertex) vo ) == 0;
+ }
+
+ // ---------------------------------------------------------------------
+
+ @Override
+ public int hashCode()
+ {
+ if ( md == null )
+ {
+ return super.hashCode();
+ }
+ StringBuilder hashString = new StringBuilder( 128 );
+ hashString.append( md.groupId ).append( "|" );
+ hashString.append( md.artifactId ).append( "|" );
+
+ if ( compareVersion )
+ {
+ hashString.append( md.version ).append( "|" );
+ }
+
+ if ( compareScope )
+ {
+ hashString.append( md.getArtifactScope() ).append( "|" );
+ }
+
+ return hashString.toString().hashCode();
+
+ // BASE64Encoder b64 = new BASE64Encoder();
+ // return b64.encode( hashString.toString().getBytes() ).hashCode();
+ }
+
+ // ---------------------------------------------------------------------
+ // ---------------------------------------------------------------------
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/metadata/MetadataResolution.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/metadata/MetadataResolution.java
new file mode 100644
index 00000000..9a9130b2
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/metadata/MetadataResolution.java
@@ -0,0 +1,71 @@
+package org.apache.maven.repository.metadata;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Collection;
+
+import org.apache.maven.artifact.repository.ArtifactRepository;
+
+/**
+ *
+ * @author Jason van Zyl
+ *
+ */
+public class MetadataResolution
+{
+ /** resolved MD */
+ private ArtifactMetadata artifactMetadata;
+
+ /** repositories, added by this POM */
+ private Collection<ArtifactRepository> metadataRepositories;
+ //-------------------------------------------------------------------
+ public MetadataResolution( ArtifactMetadata artifactMetadata )
+ {
+ this.artifactMetadata = artifactMetadata;
+ }
+ //-------------------------------------------------------------------
+ public MetadataResolution( ArtifactMetadata artifactMetadata, Collection<ArtifactRepository> metadataRepositories )
+ {
+ this( artifactMetadata );
+ this.metadataRepositories = metadataRepositories;
+ }
+ //-------------------------------------------------------------------
+ public Collection<ArtifactRepository> getMetadataRepositories()
+ {
+ return metadataRepositories;
+ }
+
+ public void setMetadataRepositories( Collection<ArtifactRepository> metadataRepositories )
+ {
+ this.metadataRepositories = metadataRepositories;
+ }
+ //-------------------------------------------------------------------
+ public ArtifactMetadata getArtifactMetadata()
+ {
+ return artifactMetadata;
+ }
+
+ public void setArtifactMetadata( ArtifactMetadata artifactMetadata )
+ {
+ this.artifactMetadata = artifactMetadata;
+ }
+ //-------------------------------------------------------------------
+ //-------------------------------------------------------------------
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/metadata/MetadataResolutionException.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/metadata/MetadataResolutionException.java
new file mode 100644
index 00000000..24f832ef
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/metadata/MetadataResolutionException.java
@@ -0,0 +1,49 @@
+package org.apache.maven.repository.metadata;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+public class MetadataResolutionException
+ extends Exception
+{
+
+ public MetadataResolutionException()
+ {
+ // TODO Auto-generated constructor stub
+ }
+
+ public MetadataResolutionException( String message )
+ {
+ super( message );
+ // TODO Auto-generated constructor stub
+ }
+
+ public MetadataResolutionException( Throwable cause )
+ {
+ super( cause );
+ // TODO Auto-generated constructor stub
+ }
+
+ public MetadataResolutionException( String message, Throwable cause )
+ {
+ super( message, cause );
+ // TODO Auto-generated constructor stub
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/metadata/MetadataResolutionRequest.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/metadata/MetadataResolutionRequest.java
new file mode 100644
index 00000000..e1f6fe1e
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/metadata/MetadataResolutionRequest.java
@@ -0,0 +1,79 @@
+package org.apache.maven.repository.metadata;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.List;
+
+import org.apache.maven.artifact.repository.ArtifactRepository;
+
+/** @author Oleg Gusakov */
+public class MetadataResolutionRequest
+{
+ protected ArtifactMetadata query;
+ protected ArtifactRepository localRepository;
+ protected List<ArtifactRepository> remoteRepositories;
+
+ //--------------------------------------------------------------------
+ public MetadataResolutionRequest()
+ {
+ }
+
+ //--------------------------------------------------------------------
+ public MetadataResolutionRequest( ArtifactMetadata query, ArtifactRepository localRepository,
+ List<ArtifactRepository> remoteRepositories )
+ {
+ this.query = query;
+ this.localRepository = localRepository;
+ this.remoteRepositories = remoteRepositories;
+ }
+
+ //--------------------------------------------------------------------
+ public ArtifactMetadata getQuery()
+ {
+ return query;
+ }
+
+ public void setQuery( ArtifactMetadata query )
+ {
+ this.query = query;
+ }
+
+ public ArtifactRepository getLocalRepository()
+ {
+ return localRepository;
+ }
+
+ public void setLocalRepository( ArtifactRepository localRepository )
+ {
+ this.localRepository = localRepository;
+ }
+
+ public List<ArtifactRepository> getRemoteRepositories()
+ {
+ return remoteRepositories;
+ }
+
+ public void setRemoteRepositories( List<ArtifactRepository> remoteRepositories )
+ {
+ this.remoteRepositories = remoteRepositories;
+ }
+ //--------------------------------------------------------------------
+ //--------------------------------------------------------------------
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/metadata/MetadataResolutionRequestTypeEnum.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/metadata/MetadataResolutionRequestTypeEnum.java
new file mode 100644
index 00000000..f305497a
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/metadata/MetadataResolutionRequestTypeEnum.java
@@ -0,0 +1,45 @@
+package org.apache.maven.repository.metadata;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+public enum MetadataResolutionRequestTypeEnum
+{
+ tree( 1 )
+ , graph( 2 )
+ , classpathCompile( 3 )
+ , classpathTest( 4 )
+ , classpathRuntime( 5 )
+ , versionedGraph( 6 )
+ , scopedGraph( 7 )
+ ;
+
+ private int id;
+
+ // Constructor
+ MetadataResolutionRequestTypeEnum( int id )
+ {
+ this.id = id;
+ }
+
+ int getId()
+ {
+ return id;
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/metadata/MetadataResolutionResult.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/metadata/MetadataResolutionResult.java
new file mode 100644
index 00000000..1d9e9c46
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/metadata/MetadataResolutionResult.java
@@ -0,0 +1,172 @@
+package org.apache.maven.repository.metadata;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.artifact.ArtifactScopeEnum;
+import org.codehaus.plexus.PlexusContainer;
+import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
+
+/**
+ * This object is tinted with ClasspathTransformation and GraphConflictResolver.
+ * Get rid of them after debugging
+ *
+ * @author <a href="oleg@codehaus.org">Oleg Gusakov</a>
+ */
+public class MetadataResolutionResult
+{
+ MetadataTreeNode treeRoot;
+
+ /**
+ * these components are are initialized on demand by
+ * explicit call of the initTreeProcessing()
+ */
+ ClasspathTransformation classpathTransformation;
+ GraphConflictResolver conflictResolver;
+
+ //----------------------------------------------------------------------------
+ public MetadataResolutionResult( )
+ {
+ }
+ //----------------------------------------------------------------------------
+ public MetadataResolutionResult( MetadataTreeNode root )
+ {
+ this.treeRoot = root;
+ }
+ //----------------------------------------------------------------------------
+ public MetadataTreeNode getTree()
+ {
+ return treeRoot;
+ }
+ //----------------------------------------------------------------------------
+ public void setTree( MetadataTreeNode root )
+ {
+ this.treeRoot = root;
+ }
+
+ public void initTreeProcessing( PlexusContainer plexus )
+ throws ComponentLookupException
+ {
+ classpathTransformation = plexus.lookup( ClasspathTransformation.class );
+ conflictResolver = plexus.lookup( GraphConflictResolver.class );
+ }
+ //----------------------------------------------------------------------------
+ public MetadataGraph getGraph()
+ throws MetadataResolutionException
+ {
+ return treeRoot == null ? null : new MetadataGraph( treeRoot );
+ }
+ //----------------------------------------------------------------------------
+ public MetadataGraph getGraph( ArtifactScopeEnum scope )
+ throws MetadataResolutionException, GraphConflictResolutionException
+ {
+ if ( treeRoot == null )
+ {
+ return null;
+ }
+
+ if ( conflictResolver == null )
+ {
+ return null;
+ }
+
+ return conflictResolver.resolveConflicts( getGraph(), scope );
+ }
+ //----------------------------------------------------------------------------
+ public MetadataGraph getGraph( MetadataResolutionRequestTypeEnum requestType )
+ throws MetadataResolutionException, GraphConflictResolutionException
+ {
+ if ( requestType == null )
+ {
+ return null;
+ }
+
+ if ( treeRoot == null )
+ {
+ return null;
+ }
+
+ if ( conflictResolver == null )
+ {
+ return null;
+ }
+
+ if ( requestType.equals( MetadataResolutionRequestTypeEnum.classpathCompile ) )
+ {
+ return conflictResolver.resolveConflicts( getGraph(), ArtifactScopeEnum.compile );
+ }
+ else if ( requestType.equals( MetadataResolutionRequestTypeEnum.classpathRuntime ) )
+ {
+ return conflictResolver.resolveConflicts( getGraph(), ArtifactScopeEnum.runtime );
+ }
+ else if ( requestType.equals( MetadataResolutionRequestTypeEnum.classpathRuntime ) )
+ {
+ return conflictResolver.resolveConflicts( getGraph(), ArtifactScopeEnum.test );
+ }
+ else if ( requestType.equals( MetadataResolutionRequestTypeEnum.classpathRuntime ) )
+ {
+ return conflictResolver.resolveConflicts( getGraph(), ArtifactScopeEnum.test );
+ }
+ else if ( requestType.equals( MetadataResolutionRequestTypeEnum.graph ) )
+ {
+ return getGraph();
+ }
+ else if ( requestType.equals( MetadataResolutionRequestTypeEnum.versionedGraph ) )
+ {
+ return new MetadataGraph( getTree(), true, false );
+ }
+ else if ( requestType.equals( MetadataResolutionRequestTypeEnum.scopedGraph ) )
+ {
+ return new MetadataGraph( getTree(), true, true );
+ }
+ return null;
+ }
+ //----------------------------------------------------------------------------
+ public ClasspathContainer getClasspath( ArtifactScopeEnum scope )
+ throws MetadataGraphTransformationException, MetadataResolutionException
+ {
+ if ( classpathTransformation == null )
+ {
+ return null;
+ }
+
+ MetadataGraph dirtyGraph = getGraph();
+ if ( dirtyGraph == null )
+ {
+ return null;
+ }
+
+ return classpathTransformation.transform( dirtyGraph, scope, false );
+ }
+
+ //----------------------------------------------------------------------------
+ public MetadataTreeNode getClasspathTree( ArtifactScopeEnum scope )
+ throws MetadataGraphTransformationException, MetadataResolutionException
+ {
+ ClasspathContainer cpc = getClasspath( scope );
+ if ( cpc == null )
+ {
+ return null;
+ }
+
+ return cpc.getClasspathAsTree();
+ }
+ //----------------------------------------------------------------------------
+ //----------------------------------------------------------------------------
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/metadata/MetadataRetrievalException.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/metadata/MetadataRetrievalException.java
new file mode 100644
index 00000000..f5461d71
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/metadata/MetadataRetrievalException.java
@@ -0,0 +1,59 @@
+package org.apache.maven.repository.metadata;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Error while retrieving repository metadata from the repository.
+ *
+ * @author Jason van Zyl
+ */
+public class MetadataRetrievalException
+ extends Exception
+{
+
+ private ArtifactMetadata artifact;
+
+ public MetadataRetrievalException( String message )
+ {
+ this( message, null, null );
+ }
+
+ public MetadataRetrievalException( Throwable cause )
+ {
+ this( null, cause, null );
+ }
+
+ public MetadataRetrievalException( String message, Throwable cause )
+ {
+ this( message, cause, null );
+ }
+
+ public MetadataRetrievalException( String message, Throwable cause, ArtifactMetadata artifact )
+ {
+ super( message, cause );
+
+ this.artifact = artifact;
+ }
+
+ public ArtifactMetadata getArtifactMetadata()
+ {
+ return artifact;
+ }
+} \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/metadata/MetadataSource.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/metadata/MetadataSource.java
new file mode 100644
index 00000000..3ca6ce84
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/metadata/MetadataSource.java
@@ -0,0 +1,39 @@
+package org.apache.maven.repository.metadata;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.List;
+
+import org.apache.maven.artifact.repository.ArtifactRepository;
+
+/**
+ * Provides some metadata operations, like querying the remote repository for a list of versions available for an
+ * artifact.
+ *
+ * @author Jason van Zyl
+ */
+public interface MetadataSource
+{
+ String ROLE = MetadataSource.class.getName();
+
+ MetadataResolution retrieve( ArtifactMetadata artifact, ArtifactRepository localRepository,
+ List<ArtifactRepository> remoteRepositories )
+ throws MetadataRetrievalException;
+} \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/metadata/MetadataTreeNode.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/metadata/MetadataTreeNode.java
new file mode 100644
index 00000000..dd720d38
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/repository/metadata/MetadataTreeNode.java
@@ -0,0 +1,148 @@
+package org.apache.maven.repository.metadata;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.ArtifactScopeEnum;
+
+/**
+ * metadata [dirty] Tree
+ *
+ * @author <a href="oleg@codehaus.org">Oleg Gusakov</a>
+ *
+ */
+public class MetadataTreeNode
+{
+ ArtifactMetadata md; // this node
+
+ MetadataTreeNode parent; // papa
+
+ /** default # of children. Used for tree creation optimization only */
+ int nChildren = 8;
+
+ MetadataTreeNode[] children; // of cause
+
+ public int getNChildren()
+ {
+ return nChildren;
+ }
+
+ public void setNChildren( int children )
+ {
+ nChildren = children;
+ }
+
+ //------------------------------------------------------------------------
+ public MetadataTreeNode()
+ {
+ }
+ //------------------------------------------------------------------------
+ public MetadataTreeNode( ArtifactMetadata md, MetadataTreeNode parent, boolean resolved, ArtifactScopeEnum scope )
+ {
+ if ( md != null )
+ {
+ md.setArtifactScope( ArtifactScopeEnum.checkScope( scope ) );
+ md.setResolved( resolved );
+ }
+
+ this.md = md;
+ this.parent = parent;
+ }
+ //------------------------------------------------------------------------
+ public MetadataTreeNode( Artifact af, MetadataTreeNode parent, boolean resolved, ArtifactScopeEnum scope )
+ {
+ this( new ArtifactMetadata( af ), parent, resolved, scope );
+ }
+
+ // ------------------------------------------------------------------------
+ public void addChild( int index, MetadataTreeNode kid )
+ {
+ if ( kid == null )
+ {
+ return;
+ }
+
+ if ( children == null )
+ {
+ children = new MetadataTreeNode[nChildren];
+ }
+
+ children[index % nChildren] = kid;
+ }
+
+ //------------------------------------------------------------------
+ @Override
+ public String toString()
+ {
+ return md == null ? "no metadata" : md.toString();
+ }
+
+ //------------------------------------------------------------------
+ public String graphHash()
+ throws MetadataResolutionException
+ {
+ if ( md == null )
+ {
+ throw new MetadataResolutionException( "treenode without metadata, parent: "
+ + ( parent == null ? "null" : parent.toString() ) );
+ }
+
+ return md.groupId + ":" + md.artifactId;
+ }
+
+ //------------------------------------------------------------------------
+ public boolean hasChildren()
+ {
+ return children != null;
+ }
+ //------------------------------------------------------------------------
+ public ArtifactMetadata getMd()
+ {
+ return md;
+ }
+
+ public void setMd( ArtifactMetadata md )
+ {
+ this.md = md;
+ }
+
+ public MetadataTreeNode getParent()
+ {
+ return parent;
+ }
+
+ public void setParent( MetadataTreeNode parent )
+ {
+ this.parent = parent;
+ }
+
+ public MetadataTreeNode[] getChildren()
+ {
+ return children;
+ }
+
+ public void setChildren( MetadataTreeNode[] children )
+ {
+ this.children = children;
+ }
+ //------------------------------------------------------------------------
+ //------------------------------------------------------------------------
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/usability/plugin/ExpressionDocumentationException.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/usability/plugin/ExpressionDocumentationException.java
new file mode 100644
index 00000000..050d135c
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/usability/plugin/ExpressionDocumentationException.java
@@ -0,0 +1,37 @@
+package org.apache.maven.usability.plugin;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+public class ExpressionDocumentationException
+ extends Exception
+{
+ static final long serialVersionUID = 1;
+
+ public ExpressionDocumentationException( String message, Throwable cause )
+ {
+ super( message, cause );
+ }
+
+ public ExpressionDocumentationException( String message )
+ {
+ super( message );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/usability/plugin/ExpressionDocumenter.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/usability/plugin/ExpressionDocumenter.java
new file mode 100644
index 00000000..0e98b0cb
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/java/org/apache/maven/usability/plugin/ExpressionDocumenter.java
@@ -0,0 +1,175 @@
+package org.apache.maven.usability.plugin;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.usability.plugin.io.xpp3.ParamdocXpp3Reader;
+import org.codehaus.plexus.util.IOUtil;
+import org.codehaus.plexus.util.ReaderFactory;
+import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class ExpressionDocumenter
+{
+
+ private static final String[] EXPRESSION_ROOTS = { "project", "settings", "session", "plugin", "rootless" };
+
+ private static final String EXPRESSION_DOCO_ROOTPATH = "META-INF/maven/plugin-expressions/";
+
+ private static Map expressionDocumentation;
+
+ public static Map load()
+ throws ExpressionDocumentationException
+ {
+ if ( expressionDocumentation == null )
+ {
+ expressionDocumentation = new HashMap();
+
+ ClassLoader docLoader = initializeDocLoader();
+
+ for ( String EXPRESSION_ROOT : EXPRESSION_ROOTS )
+ {
+ InputStream docStream = null;
+ try
+ {
+ docStream =
+ docLoader.getResourceAsStream( EXPRESSION_DOCO_ROOTPATH + EXPRESSION_ROOT + ".paramdoc.xml" );
+
+ if ( docStream != null )
+ {
+ Map doco = parseExpressionDocumentation( docStream );
+
+ expressionDocumentation.putAll( doco );
+ }
+ }
+ catch ( IOException e )
+ {
+ throw new ExpressionDocumentationException(
+ "Failed to read documentation for expression root: " + EXPRESSION_ROOT, e );
+ }
+ catch ( XmlPullParserException e )
+ {
+ throw new ExpressionDocumentationException(
+ "Failed to parse documentation for expression root: " + EXPRESSION_ROOT, e );
+ }
+ finally
+ {
+ IOUtil.close( docStream );
+ }
+ }
+ }
+
+ return expressionDocumentation;
+ }
+
+ /**
+ * <expressions>
+ * <expression>
+ * <syntax>project.distributionManagementArtifactRepository</syntax>
+ * <origin><![CDATA[
+ * <distributionManagement>
+ * <repository>
+ * <id>some-repo</id>
+ * <url>scp://host/path</url>
+ * </repository>
+ * <snapshotRepository>
+ * <id>some-snap-repo</id>
+ * <url>scp://host/snapshot-path</url>
+ * </snapshotRepository>
+ * </distributionManagement>
+ * ]]></origin>
+ * <usage><![CDATA[
+ * The repositories onto which artifacts should be deployed.
+ * One is for releases, the other for snapshots.
+ * ]]></usage>
+ * </expression>
+ * <expressions>
+ * @throws IOException
+ * @throws XmlPullParserException
+ */
+ private static Map parseExpressionDocumentation( InputStream docStream )
+ throws IOException, XmlPullParserException
+ {
+ Reader reader = new BufferedReader( ReaderFactory.newXmlReader( docStream ) );
+
+ ParamdocXpp3Reader paramdocReader = new ParamdocXpp3Reader();
+
+ ExpressionDocumentation documentation = paramdocReader.read( reader, true );
+
+ List expressions = documentation.getExpressions();
+
+ Map bySyntax = new HashMap();
+
+ if ( expressions != null && !expressions.isEmpty() )
+ {
+ for ( Object expression : expressions )
+ {
+ Expression expr = (Expression) expression;
+
+ bySyntax.put( expr.getSyntax(), expr );
+ }
+ }
+
+ return bySyntax;
+ }
+
+ private static ClassLoader initializeDocLoader()
+ throws ExpressionDocumentationException
+ {
+ String myResourcePath = ExpressionDocumenter.class.getName().replace( '.', '/' ) + ".class";
+
+ URL myResource = ExpressionDocumenter.class.getClassLoader().getResource( myResourcePath );
+
+ assert myResource != null : "The resource is this class itself loaded by its own classloader and must exist";
+
+ String myClasspathEntry = myResource.getPath();
+
+ myClasspathEntry = myClasspathEntry.substring( 0, myClasspathEntry.length() - ( myResourcePath.length() + 2 ) );
+
+ if ( myClasspathEntry.startsWith( "file:" ) )
+ {
+ myClasspathEntry = myClasspathEntry.substring( "file:".length() );
+ }
+
+ URL docResource;
+ try
+ {
+ docResource = new File( myClasspathEntry ).toURL();
+ }
+ catch ( MalformedURLException e )
+ {
+ throw new ExpressionDocumentationException( "Cannot construct expression documentation classpath"
+ + " resource base.", e );
+ }
+
+ return new URLClassLoader( new URL[] { docResource } );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/mdo/paramdoc.mdo b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/mdo/paramdoc.mdo
new file mode 100644
index 00000000..ab253316
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/mdo/paramdoc.mdo
@@ -0,0 +1,154 @@
+<?xml version="1.0"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<model xmlns="http://modello.codehaus.org/MODELLO/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://modello.codehaus.org/MODELLO/1.0.0 http://modello.codehaus.org/xsd/modello-1.0.0.xsd"
+ xml.namespace="http://maven.apache.org/PARAMDOC/${version}"
+ xml.schemaLocation="http://maven.apache.org/xsd/paramdoc-${version}.xsd">
+ <id>paramdoc</id>
+ <name>Paramdoc</name>
+ <description><![CDATA[Documentation on parameter expressions supported by Maven for use in plugins.]]></description>
+ <defaults>
+ <default>
+ <key>package</key>
+ <value>org.apache.maven.usability.plugin</value>
+ </default>
+ </defaults>
+ <classes>
+ <class rootElement="true" xml.tagName="paramdoc">
+ <version>1.0.0</version>
+ <name>ExpressionDocumentation</name>
+ <description>The root of a parameter plugin expression document.</description>
+ <fields>
+ <field>
+ <version>1.0.0</version>
+ <name>expressions</name>
+ <description>The list of plugin parameter expressions described by this
+ document.</description>
+ <association>
+ <type>Expression</type>
+ <multiplicity>*</multiplicity>
+ </association>
+ </field>
+ </fields>
+ <codeSegments>
+ <codeSegment>
+ <version>1.0.0</version>
+ <code><![CDATA[ private java.util.Map expressionsBySyntax;
+
+ public java.util.Map getExpressionsBySyntax()
+ {
+ if ( expressionsBySyntax == null )
+ {
+ expressionsBySyntax = new java.util.HashMap();
+
+ java.util.List expressions = getExpressions();
+
+ if ( expressions != null && !expressions.isEmpty() )
+ {
+ for ( java.util.Iterator it = expressions.iterator(); it.hasNext(); )
+ {
+ Expression expr = (Expression) it.next();
+
+ expressionsBySyntax.put( expr.getSyntax(), expr );
+ }
+ }
+ }
+
+ return expressionsBySyntax;
+ }
+
+ public void flushExpressionsBySyntax()
+ {
+ expressionsBySyntax = null;
+ }
+]]></code>
+ </codeSegment>
+ </codeSegments>
+ </class>
+ <class>
+ <version>1.0.0</version>
+ <name>Expression</name>
+ <description>A plugin parameter expression supported by Maven</description>
+ <fields>
+ <field>
+ <version>1.0.0</version>
+ <name>syntax</name>
+ <description>The syntax of the expression</description>
+ <type>String</type>
+ <required>true</required>
+ </field>
+ <field>
+ <version>1.0.0</version>
+ <name>description</name>
+ <description>The description of what this expression references, and what it's generally used for.</description>
+ <type>String</type>
+ <required>true</required>
+ </field>
+ <field>
+ <version>1.0.0</version>
+ <name>configuration</name>
+ <description>The place and syntax used to change the value of this expression.</description>
+ <type>String</type>
+ </field>
+ <field>
+ <version>1.0.0</version>
+ <name>cliOptions</name>
+ <description>The command-line switches used to change the value of this expression.</description>
+ <type>Properties</type>
+ <association xml.mapStyle="explode">
+ <type>String</type>
+ <multiplicity>*</multiplicity>
+ </association>
+ </field>
+ <field>
+ <version>1.0.0</version>
+ <name>apiMethods</name>
+ <description>The programmatic methods used to change the value of this expression.</description>
+ <type>Properties</type>
+ <association xml.mapStyle="explode">
+ <type>String</type>
+ <multiplicity>*</multiplicity>
+ </association>
+ </field>
+ <field>
+ <version>1.0.0</version>
+ <name>deprecation</name>
+ <description>A preferred alternative to this expression, in the case where it's deprecated.</description>
+ <type>String</type>
+ </field>
+ <field>
+ <version>1.0.0</version>
+ <name>ban</name>
+ <description>A preferred alternative to this expression, in the case where it's banned from use.</description>
+ <type>String</type>
+ </field>
+ <field>
+ <version>1.0.0</version>
+ <name>editable</name>
+ <description>Whether the value of this expression can be changed.</description>
+ <type>boolean</type>
+ <defaultValue>true</defaultValue>
+ </field>
+ </fields>
+ </class>
+ </classes>
+</model>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/mdo/profiles.mdo b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/mdo/profiles.mdo
new file mode 100644
index 00000000..3dcc9962
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/mdo/profiles.mdo
@@ -0,0 +1,398 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<model xmlns="http://modello.codehaus.org/MODELLO/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://modello.codehaus.org/MODELLO/1.0.0 http://modello.codehaus.org/xsd/modello-1.0.0.xsd"
+ xml.namespace="http://maven.apache.org/PROFILES/${version}"
+ xml.schemaLocation="http://maven.apache.org/xsd/profiles-${version}.xsd">
+ <id>profiles</id>
+ <name>Profiles</name>
+ <description><![CDATA[
+ Project-local overrides to the build process based on detected or user-provided environmental parameters.
+ This is the model specification for ${basedir}/profiles.xml.
+ ]]></description>
+ <defaults>
+ <default>
+ <key>package</key>
+ <value>org.apache.maven.profiles</value>
+ </default>
+ </defaults>
+ <classes>
+ <class rootElement="true" xml.tagName="profilesXml">
+ <name>ProfilesRoot</name>
+ <version>1.0.0</version>
+ <description>Root element of the profiles.xml file.</description>
+ <fields>
+ <field>
+ <name>profiles</name>
+ <version>1.0.0</version>
+ <description><![CDATA[
+ Configuration of build profiles for adjusting the build
+ according to environmental parameters
+ ]]></description>
+ <association>
+ <type>Profile</type>
+ <multiplicity>*</multiplicity>
+ </association>
+ </field>
+ <field>
+ <name>activeProfiles</name>
+ <version>1.0.0</version>
+ <description><![CDATA[
+ List of manually-activated build profiles, specified in the order in which
+ they should be applied.
+ ]]></description>
+ <association>
+ <type>String</type>
+ <multiplicity>*</multiplicity>
+ </association>
+ </field>
+ </fields>
+ </class>
+ <class>
+ <name>Profile</name>
+ <version>1.0.0</version>
+ <description><![CDATA[
+ Modifications to the build process which is keyed on some
+ sort of environmental parameter.
+ ]]></description>
+ <fields>
+ <field>
+ <name>id</name>
+ <required>true</required>
+ <version>1.0.0</version>
+ <type>String</type>
+ <description>The ID of this build profile, for activation
+ purposes.</description>
+ </field>
+ <field>
+ <name>activation</name>
+ <version>1.0.0</version>
+ <description><![CDATA[The conditional logic which will automatically
+ trigger the inclusion of this profile.]]></description>
+ <association>
+ <type>Activation</type>
+ </association>
+ </field>
+ <field>
+ <name>properties</name>
+ <description>Extended configuration specific to this profile goes
+ here.</description>
+ <type>Properties</type>
+ <association xml.mapStyle="inline">
+ <type>String</type>
+ <multiplicity>*</multiplicity>
+ </association>
+ </field>
+ <field>
+ <name>repositories</name>
+ <version>1.0.0</version>
+ <description><![CDATA[The lists of the remote repositories]]>
+ </description>
+ <association>
+ <type>Repository</type>
+ <multiplicity>*</multiplicity>
+ </association>
+ </field>
+ <field>
+ <name>pluginRepositories</name>
+ <version>1.0.0</version>
+ <description><![CDATA[
+ The lists of the remote repositories for discovering plugins
+ ]]></description>
+ <association>
+ <type>Repository</type>
+ <multiplicity>*</multiplicity>
+ </association>
+ <comment><![CDATA[ This may be removed or relocated in the near
+ future. It is undecided whether plugins really need a remote
+ repository set of their own. ]]></comment>
+ </field>
+ </fields>
+ </class>
+ <class>
+ <name>Activation</name>
+ <version>1.0.0</version>
+ <description><![CDATA[
+ The conditions within the build runtime environment which will trigger
+ the automatic inclusion of the parent build profile.
+ ]]></description>
+ <fields>
+ <field>
+ <name>activeByDefault</name>
+ <version>1.0.0</version>
+ <type>boolean</type>
+ <description>Flag specifying whether this profile is active as a default.</description>
+ </field>
+ <field>
+ <name>jdk</name>
+ <version>1.0.0</version>
+ <type>String</type>
+ <description><![CDATA[
+ Specifies that this profile will be activated when a matching JDK is detected.
+ ]]></description>
+ </field>
+ <field>
+ <name>os</name>
+ <version>1.0.0</version>
+ <description><![CDATA[
+ Specifies that this profile will be activated when matching OS attributes are detected.
+ ]]></description>
+ <association>
+ <type>ActivationOS</type>
+ </association>
+ </field>
+ <field>
+ <name>property</name>
+ <version>1.0.0</version>
+ <description><![CDATA[
+ Specifies that this profile will be activated when this System property is specified.
+ ]]></description>
+ <association>
+ <type>ActivationProperty</type>
+ </association>
+ </field>
+ <field>
+ <name>file</name>
+ <version>1.0.0</version>
+ <description><![CDATA[
+ Specifies that this profile will be activated based on existence of a file.
+ ]]></description>
+ <association>
+ <type>ActivationFile</type>
+ </association>
+ </field>
+ </fields>
+ </class>
+
+ <!-- TODO: reproduced from maven-model/maven.mdo, instead should inherit code and link to external docs -->
+ <class>
+ <name>RepositoryBase</name>
+ <version>1.0.0</version>
+ <description><![CDATA[
+ Repository contains the information needed
+ for establishing connections with remote repoistory
+ ]]></description>
+ <fields>
+ <field>
+ <name>id</name>
+ <version>1.0.0</version>
+ <description><![CDATA[
+ A unique identifier for a repository.
+ ]]></description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>name</name>
+ <version>1.0.0</version>
+ <description><![CDATA[
+ Human readable name of the repository
+ ]]></description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>url</name>
+ <version>1.0.0</version>
+ <description><![CDATA[
+ The url of the repository
+ ]]></description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>layout</name>
+ <version>1.0.0</version>
+ <description>The type of layout this repository uses for locating and storing artifacts - can be "legacy" or
+ "default".</description>
+ <type>String</type>
+ <defaultValue>default</defaultValue>
+ </field>
+ </fields>
+ <codeSegments>
+ <codeSegment>
+ <version>1.0.0</version>
+ <code><![CDATA[
+ public boolean equals( Object obj )
+ {
+ RepositoryBase other = (RepositoryBase) obj;
+
+ boolean retValue = false;
+
+ if ( id != null )
+ {
+ retValue = id.equals( other.id );
+ }
+
+ return retValue;
+ }
+ ]]></code>
+ </codeSegment>
+ </codeSegments>
+ </class>
+ <class>
+ <name>Repository</name>
+ <superClass>RepositoryBase</superClass>
+ <version>1.0.0</version>
+ <description>
+ Repository contains the information needed for establishing connections with remote repoistory
+ </description>
+ <fields>
+ <field>
+ <name>releases</name>
+ <version>1.0.0</version>
+ <description>How to handle downloading of releases from this repository</description>
+ <association>
+ <type>RepositoryPolicy</type>
+ </association>
+ </field>
+ <field>
+ <name>snapshots</name>
+ <version>1.0.0</version>
+ <description>How to handle downloading of snapshots from this repository</description>
+ <association>
+ <type>RepositoryPolicy</type>
+ </association>
+ </field>
+ </fields>
+ <!-- prevent modello generation of an incorrect equals method. Could be avoided by using <identity/> tags to mark ID as the only identity field -->
+ <codeSegments>
+ <codeSegment>
+ <version>1.0.0</version>
+ <code><![CDATA[
+ public boolean equals( Object obj )
+ {
+ return super.equals( obj );
+ }
+ ]]></code>
+ </codeSegment>
+ </codeSegments>
+ </class>
+
+ <class>
+ <name>RepositoryPolicy</name>
+ <version>1.0.0</version>
+ <description>Download policy</description>
+ <fields>
+ <field>
+ <name>enabled</name>
+ <version>1.0.0</version>
+ <description>Whether to use this repository for downloading this type of artifact</description>
+ <type>boolean</type>
+ <defaultValue>true</defaultValue>
+ </field>
+ <field>
+ <name>updatePolicy</name>
+ <version>1.0.0</version>
+ <description>
+ The frequency for downloading updates - can be "always", "daily" (default), "interval:XXX" (in minutes) or
+ "never" (only if it doesn't exist locally).
+ </description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>checksumPolicy</name>
+ <version>1.0.0</version>
+ <description>What to do when verification of an artifact checksum fails - warn, fail, etc. Valid values are
+ "fail" or "warn"</description>
+ <type>String</type>
+ </field>
+ </fields>
+ </class>
+ <class>
+ <name>ActivationProperty</name>
+ <version>1.0.0</version>
+ <description><![CDATA[
+ This is the property specification used to activate a profile. If the value field is empty,
+ then the existence of the named property will activate the profile, otherwise it does a case-sensitive
+ match against the property value as well.
+ ]]></description>
+ <fields>
+ <field>
+ <name>name</name>
+ <version>1.0.0</version>
+ <type>String</type>
+ <required>true</required>
+ <description>The name of the property to be used to activate a profile</description>
+ </field>
+ <field>
+ <name>value</name>
+ <version>1.0.0</version>
+ <type>String</type>
+ <description>The value of the property to be used to activate a profile</description>
+ </field>
+ </fields>
+ </class>
+ <class>
+ <name>ActivationFile</name>
+ <version>1.0.0</version>
+ <description><![CDATA[
+ This is the file specification used to activate a profile. The missing value will be a the location
+ of a file that needs to exist, and if it doesn't the profile must run. On the other hand exists will test
+ for the existence of the file and if it is there will run the profile.
+ ]]></description>
+ <fields>
+ <field>
+ <name>missing</name>
+ <version>1.0.0</version>
+ <type>String</type>
+ <description>The name of the file that should be missing to activate a profile</description>
+ </field>
+ <field>
+ <name>exists</name>
+ <version>1.0.0</version>
+ <type>String</type>
+ <description>The name of the file that should exist to activate a profile</description>
+ </field>
+ </fields>
+ </class>
+ <class>
+ <name>ActivationOS</name>
+ <version>1.0.0</version>
+ <description><![CDATA[
+ This is an activator which will detect an operating system's attributes in order to activate
+ its profile.
+ ]]></description>
+ <fields>
+ <field>
+ <name>name</name>
+ <version>1.0.0</version>
+ <type>String</type>
+ <description>The name of the OS to be used to activate a profile</description>
+ </field>
+ <field>
+ <name>family</name>
+ <version>1.0.0</version>
+ <type>String</type>
+ <description>The general family of the OS to be used to activate a profile (e.g. 'windows')</description>
+ </field>
+ <field>
+ <name>arch</name>
+ <version>1.0.0</version>
+ <type>String</type>
+ <description>The architecture of the OS to be used to activate a profile</description>
+ </field>
+ <field>
+ <name>version</name>
+ <version>1.0.0</version>
+ <type>String</type>
+ <description>The version of the OS to be used to activate a profile</description>
+ </field>
+ </fields>
+ </class>
+ </classes>
+</model>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/resources/META-INF/maven/plugin-expressions/project.paramdoc.xml b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/resources/META-INF/maven/plugin-expressions/project.paramdoc.xml
new file mode 100644
index 00000000..9acebefc
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/resources/META-INF/maven/plugin-expressions/project.paramdoc.xml
@@ -0,0 +1,172 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<paramdoc xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 ../../../../../../../maven-plugin-parameter-documenter/target/generated-site/xsd/paramdoc-1.0.0.xsd ">
+<expressions>
+ <expression>
+ <syntax>project.distributionManagementArtifactRepository</syntax>
+ <configuration>
+ <![CDATA[
+<distributionManagement>
+ <!-- use the following if you're not using a snapshot version. -->
+ <repository>
+ <id>repo</id>
+ <name>Repository Name</name>
+ <url>scp://host/path/to/repo</url>
+ </repository>
+ <!-- use the following if you ARE using a snapshot version. -->
+ <snapshotRepository>
+ <id>repo</id>
+ <name>Repository Name</name>
+ <url>scp://host/path/to/repo</url>
+ </snapshotRepository>
+</distributionManagement>
+ ]]></configuration>
+ <description> This is the ArtifactRepository used to deploy artifacts built by this
+ Maven.
+ </description>
+ </expression>
+ <expression>
+ <syntax>project.artifact</syntax>
+ <configuration>
+ <![CDATA[
+<groupId>project.group</groupId>
+<artifactId>project-artifact</artifactId>
+<version>0.0.0.0</version>
+<packaging>type</packaging>
+ ]]></configuration>
+ <description> This is the Artifact instance created from the essential project
+ attributes: groupId, artifactId, version, and packaging (with a default packaging of
+ 'jar').
+ </description>
+ </expression>
+ <expression>
+ <syntax>project.parent</syntax>
+ <configuration>
+ <![CDATA[
+<parent>
+ <groupId>project.group</groupId>
+ <artifactId>project-artifact</artifactId>
+ <version>0.0.0.0</version>
+</parent>
+ ]]></configuration>
+ <description> This is the MavenProject instance for the parent of the current POM.
+ </description>
+ </expression>
+ <expression>
+ <syntax>project.file</syntax>
+ <description> This is the File instance that refers to the location of the current POM on
+ disk.
+ </description>
+ </expression>
+ <expression>
+ <syntax>project.artifacts</syntax>
+ <configuration>
+ <![CDATA[
+<dependencies>
+ ...
+</dependencies>
+ ]]></configuration>
+ <description>
+ <![CDATA[
+ This is a set of Artifact instances resolved from the set of dependencies for
+ the current project.
+
+ NOTE: This will likely contain much more than the direct dependencies of the
+ current POM, since Maven uses transitive, or chained, dependency resolution.
+ ]]></description>
+ </expression>
+ <expression>
+ <syntax>project.parentArtifact</syntax>
+ <configuration>
+ <![CDATA[
+ <parent>
+ <groupId>project.group</groupId>
+ <artifactId>project-artifact</artifactId>
+ <version>0.0.0.0</version>
+ </parent>
+ ]]></configuration>
+ <description> This is the Artifact instance for the parent of the current POM.
+ </description>
+ </expression>
+ <expression>
+ <syntax>project.pluginArtifacts</syntax>
+ <configuration>
+ <![CDATA[
+<build>
+ <plugins>
+ ...
+ </plugins>
+</build>
+ ]]></configuration>
+ <description>
+ <![CDATA[
+ This is the list of Artifact instances for plugins used in the current build
+ for this project.
+
+ NOTE: This list may contain plugin Artifacts which are implied by the current POM's
+ packaging and the lifecycle phase being built.
+ ]]></description>
+ </expression>
+ <expression>
+ <syntax>project.remoteArtifactRepositories</syntax>
+ <configuration>
+ <![CDATA[
+<repositories>
+ ...
+</repositories>
+ ]]></configuration>
+ <description>
+ <![CDATA[
+ This is a list of ArtifactRepository instances used to resolve the Artifacts associated
+ with the current POM.
+
+ NOTE: This list will contain entries for repositories specified by ancestor POMs, including
+ the default built-in super-POM, which is the parent of all POMs.
+ ]]></description>
+ </expression>
+ <expression>
+ <syntax>project.pluginArtifactRepositories</syntax>
+ <configuration>
+ <![CDATA[
+<pluginRepositories>
+ ...
+</pluginRepositories>
+ ]]></configuration>
+ <description>
+ <![CDATA[
+ This is a list of ArtifactRepository instances used to resolve the Artifacts associated
+ with plugins used in building the current POM.
+
+ NOTE: This list will contain entries for repositories specified by ancestor POMs, including
+ the default built-in super-POM, which is the parent of all POMs.
+ ]]></description>
+ </expression>
+ <expression>
+ <syntax>project.attachedArtifacts</syntax>
+ <description>
+ <![CDATA[
+ This is a list of attachments to the main artifact produced by building the current POM.
+ Attachments are derived works, based on the main build process, such as an ejb-client jar,
+ project sources jar, etc.
+ ]]></description>
+ </expression>
+</expressions>
+</paramdoc> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/resources/META-INF/maven/plugin-expressions/rootless.paramdoc.xml b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/resources/META-INF/maven/plugin-expressions/rootless.paramdoc.xml
new file mode 100644
index 00000000..27f03435
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/resources/META-INF/maven/plugin-expressions/rootless.paramdoc.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<paramdoc xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 ../../../../../../../maven-plugin-parameter-documenter/target/generated-site/xsd/paramdoc-1.0.0.xsd ">
+ <expressions>
+ <expression>
+ <syntax>localRepository</syntax>
+ <configuration>
+ <![CDATA[
+ Inside ~/.m2/settings.xml:
+
+ <localRepository>/path/to/local/repository</localRepository>
+ ]]></configuration>
+ <description>The ArtifactRepository instance referencing the local artifact
+ repository.</description>
+ <cliOptions>
+ <cliOption>
+ <key>-Dmaven.repo.local=/path/to/local/repo</key>
+ <value>Override the local repository location on a per-build basis.</value>
+ </cliOption>
+ </cliOptions>
+ </expression>
+ <expression>
+ <syntax>reactorProjects</syntax>
+ <description>This is the current list of projects being built by
+ Maven.</description>
+ </expression>
+ </expressions>
+</paramdoc>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/resources/META-INF/maven/plugin-expressions/settings.paramdoc.xml b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/resources/META-INF/maven/plugin-expressions/settings.paramdoc.xml
new file mode 100644
index 00000000..e058218a
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/resources/META-INF/maven/plugin-expressions/settings.paramdoc.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<paramdoc xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 ../../../../../../../maven-plugin-parameter-documenter/target/generated-site/xsd/paramdoc-1.0.0.xsd ">
+ <expressions>
+ <expression>
+ <syntax>settings.offline</syntax>
+ <configuration>
+ <![CDATA[
+ <offline>true</offline>
+ ]]></configuration>
+ <description>
+ <![CDATA[
+ Flags the system as offline, to prevent accessing the network to resolve artifacts or execute plugins.
+
+ NOTE: It's also possible to switch to offline mode on a per-build basis, using the '-o' command-line option.
+ ]]></description>
+ </expression>
+ <expression>
+ <syntax>settings.interactiveMode</syntax>
+ <configuration>
+ <![CDATA[
+ <interactiveMode>true</interactiveMode>
+ ]]></configuration>
+ <description>
+ <![CDATA[
+ If false, flags the system to skip prompting the user for any information, or holding up the build
+ waiting for any input.
+
+ NOTE: It's also possible to switch to batch (ie. non-interactive) mode using the '-B' command-line option.
+ ]]></description>
+ </expression>
+ </expressions>
+</paramdoc> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/resources/META-INF/maven/plugin.xml b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/resources/META-INF/maven/plugin.xml
new file mode 100644
index 00000000..da5a62c0
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/main/resources/META-INF/maven/plugin.xml
@@ -0,0 +1,218 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<plugin>
+ <description>Maven Internal State-Management Plugins</description>
+ <groupId>org.apache.maven.plugins.internal</groupId>
+ <artifactId>maven-state-management</artifactId>
+ <version>2.1</version>
+ <goalPrefix>statemgmt</goalPrefix>
+ <isolatedRealm>false</isolatedRealm>
+ <inheritedByDefault>true</inheritedByDefault>
+ <mojos>
+ <mojo>
+ <goal>start-fork</goal>
+ <description>Setup the appropriate build state to initiate a forked execution.</description>
+ <requiresDirectInvocation>false</requiresDirectInvocation>
+ <requiresProject>false</requiresProject>
+ <requiresReports>false</requiresReports>
+ <aggregator>false</aggregator>
+ <requiresOnline>false</requiresOnline>
+ <inheritedByDefault>true</inheritedByDefault>
+ <implementation>org.apache.maven.lifecycle.statemgmt.StartForkedExecutionMojo</implementation>
+ <language>java</language>
+ <instantiationStrategy>per-lookup</instantiationStrategy>
+ <executionStrategy>once-per-session</executionStrategy>
+ <parameters>
+ <parameter>
+ <name>project</name>
+ <type>org.apache.maven.project.MavenProject</type>
+ <required>true</required>
+ <editable>false</editable>
+ <description>The current MavenProject instance, which will have a new executionProject set after execution.</description>
+ </parameter>
+ <parameter>
+ <name>session</name>
+ <type>org.apache.maven.execution.MavenSession</type>
+ <required>true</required>
+ <editable>false</editable>
+ <description>The current MavenSession instance, which will handle the fork context.</description>
+ </parameter>
+ <parameter>
+ <name>forkId</name>
+ <type>int</type>
+ <required>true</required>
+ <editable>true</editable>
+ <description>The current fork identifier.</description>
+ </parameter>
+ </parameters>
+ <configuration>
+ <project implementation="org.apache.maven.project.MavenProject" default-value="${project}"/>
+ <session implementation="org.apache.maven.execution.MavenSession" default-value="${session}"/>
+ <forkId implementation="int" default-value="-1">${forkId}</forkId>
+ </configuration>
+ </mojo>
+ <mojo>
+ <goal>end-fork</goal>
+ <description>Restore the non-fork currentProject instance, for use in the forking mojo.</description>
+ <requiresDirectInvocation>false</requiresDirectInvocation>
+ <requiresProject>false</requiresProject>
+ <requiresReports>false</requiresReports>
+ <aggregator>false</aggregator>
+ <requiresOnline>false</requiresOnline>
+ <inheritedByDefault>true</inheritedByDefault>
+ <implementation>org.apache.maven.lifecycle.statemgmt.EndForkedExecutionMojo</implementation>
+ <language>java</language>
+ <instantiationStrategy>per-lookup</instantiationStrategy>
+ <executionStrategy>once-per-session</executionStrategy>
+ <parameters>
+ <parameter>
+ <name>session</name>
+ <type>org.apache.maven.execution.MavenSession</type>
+ <required>true</required>
+ <editable>false</editable>
+ <description>The current MavenSession instance, which will handle the fork context.</description>
+ </parameter>
+ <parameter>
+ <name>forkId</name>
+ <type>int</type>
+ <required>true</required>
+ <editable>true</editable>
+ <description>The current fork identifier.</description>
+ </parameter>
+ </parameters>
+ <configuration>
+ <session implementation="org.apache.maven.execution.MavenSession" default-value="${session}"/>
+ <forkId implementation="int" default-value="-1">${forkId}</forkId>
+ </configuration>
+ </mojo>
+ <mojo>
+ <goal>clear-fork-context</goal>
+ <description>Tear down any build state used during the previous forked execution.</description>
+ <requiresDirectInvocation>false</requiresDirectInvocation>
+ <requiresProject>false</requiresProject>
+ <requiresReports>false</requiresReports>
+ <aggregator>false</aggregator>
+ <requiresOnline>false</requiresOnline>
+ <inheritedByDefault>true</inheritedByDefault>
+ <implementation>org.apache.maven.lifecycle.statemgmt.ClearForkedContextMojo</implementation>
+ <language>java</language>
+ <instantiationStrategy>per-lookup</instantiationStrategy>
+ <executionStrategy>once-per-session</executionStrategy>
+ <parameters>
+ <parameter>
+ <name>project</name>
+ <type>org.apache.maven.project.MavenProject</type>
+ <required>true</required>
+ <editable>false</editable>
+ <description>The current MavenProject instance, which will have the current executionProject cleared after execution.</description>
+ </parameter>
+ <parameter>
+ <name>forkId</name>
+ <type>int</type>
+ <required>true</required>
+ <editable>true</editable>
+ <description>The current fork identifier.</description>
+ </parameter>
+ </parameters>
+ <configuration>
+ <project implementation="org.apache.maven.project.MavenProject" default-value="${project}"/>
+ <forkId implementation="int" default-value="-1">${forkId}</forkId>
+ </configuration>
+ </mojo>
+ <mojo>
+ <goal>resolve-late-bound-plugin</goal>
+ <description>Resolve a late-bound plugin during a build, right before it is to be used.</description>
+ <requiresDirectInvocation>false</requiresDirectInvocation>
+ <requiresProject>false</requiresProject>
+ <requiresReports>false</requiresReports>
+ <aggregator>false</aggregator>
+ <requiresOnline>false</requiresOnline>
+ <inheritedByDefault>true</inheritedByDefault>
+ <implementation>org.apache.maven.lifecycle.statemgmt.ResolveLateBoundPluginMojo</implementation>
+ <language>java</language>
+ <instantiationStrategy>per-lookup</instantiationStrategy>
+ <executionStrategy>once-per-session</executionStrategy>
+ <parameters>
+ <parameter>
+ <name>project</name>
+ <type>org.apache.maven.project.MavenProject</type>
+ <required>true</required>
+ <editable>false</editable>
+ <description>The current MavenProject instance, for building a new MojoBinding instance.</description>
+ </parameter>
+ <parameter>
+ <name>session</name>
+ <type>org.apache.maven.execution.MavenSession</type>
+ <required>true</required>
+ <editable>false</editable>
+ <description>The current MavenSession instance, which will handle the fork context.</description>
+ </parameter>
+ <parameter>
+ <name>groupId</name>
+ <type>java.lang.String</type>
+ <required>true</required>
+ <editable>true</editable>
+ <description>The plugin's groupId.</description>
+ </parameter>
+ <parameter>
+ <name>artifactId</name>
+ <type>java.lang.String</type>
+ <required>true</required>
+ <editable>true</editable>
+ <description>The plugin's artifactId.</description>
+ </parameter>
+ <parameter>
+ <name>version</name>
+ <type>java.lang.String</type>
+ <required>false</required>
+ <editable>true</editable>
+ <description>The plugin's version.</description>
+ </parameter>
+ <parameter>
+ <name>goal</name>
+ <type>java.lang.String</type>
+ <required>true</required>
+ <editable>true</editable>
+ <description>The mojo's goal that we're looking for, as an extra validation step.</description>
+ </parameter>
+ </parameters>
+ <configuration>
+ <project implementation="org.apache.maven.project.MavenProject" default-value="${project}"/>
+ <session implementation="org.apache.maven.execution.MavenSession" default-value="${session}"/>
+ <groupId implementation="java.lang.String">${groupId}</groupId>
+ <artifactId implementation="java.lang.String">${artifactId}</artifactId>
+ <version implementation="java.lang.String">${version}</version>
+ <goal implementation="java.lang.String">${goal}</goal>
+ </configuration>
+ <requirements>
+ <requirement>
+ <role>org.apache.maven.plugin.loader.PluginLoader</role>
+ <field-name>pluginLoader</field-name>
+ </requirement>
+ <requirement>
+ <role>org.apache.maven.lifecycle.binding.MojoBindingFactory</role>
+ <field-name>bindingFactory</field-name>
+ </requirement>
+ </requirements>
+ </mojo>
+ </mojos>
+</plugin> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/site/site.xml b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/site/site.xml
new file mode 100644
index 00000000..3a16bf98
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/site/site.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project xmlns="http://maven.apache.org/DECORATION/1.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/DECORATION/1.0.0 http://maven.apache.org/xsd/decoration-1.0.0.xsd">
+ <body>
+ <menu name="Overview">
+ <item name="Introduction" href="index.html"/>
+ <item name="JavaDocs" href="apidocs/index.html"/>
+ <item name="Source Xref" href="xref/index.html"/>
+ <!--item name="FAQ" href="faq.html"/-->
+ </menu>
+
+ <menu ref="parent"/>
+ <menu ref="reports"/>
+ </body>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/artifact/AbstractArtifactComponentTestCase.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/artifact/AbstractArtifactComponentTestCase.java
new file mode 100644
index 00000000..010c566b
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/artifact/AbstractArtifactComponentTestCase.java
@@ -0,0 +1,371 @@
+package org.apache.maven.artifact;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.maven.artifact.factory.ArtifactFactory;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.plugin.LegacySupport;
+import org.apache.maven.repository.legacy.repository.ArtifactRepositoryFactory;
+import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy;
+import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout;
+import org.apache.maven.execution.DefaultMavenExecutionRequest;
+import org.apache.maven.execution.DefaultMavenExecutionResult;
+import org.apache.maven.execution.MavenSession;
+import org.codehaus.plexus.ContainerConfiguration;
+import org.codehaus.plexus.PlexusConstants;
+import org.codehaus.plexus.PlexusTestCase;
+import org.eclipse.aether.DefaultRepositorySystemSession;
+import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.collection.DependencyGraphTransformer;
+import org.eclipse.aether.collection.DependencyManager;
+import org.eclipse.aether.collection.DependencySelector;
+import org.eclipse.aether.collection.DependencyTraverser;
+import org.eclipse.aether.internal.impl.SimpleLocalRepositoryManagerFactory;
+import org.eclipse.aether.repository.LocalRepository;
+import org.eclipse.aether.util.graph.manager.ClassicDependencyManager;
+import org.eclipse.aether.util.graph.selector.AndDependencySelector;
+import org.eclipse.aether.util.graph.selector.ExclusionDependencySelector;
+import org.eclipse.aether.util.graph.selector.OptionalDependencySelector;
+import org.eclipse.aether.util.graph.selector.ScopeDependencySelector;
+import org.eclipse.aether.util.graph.transformer.ChainedDependencyGraphTransformer;
+import org.eclipse.aether.util.graph.transformer.ConflictResolver;
+import org.eclipse.aether.util.graph.transformer.JavaScopeDeriver;
+import org.eclipse.aether.util.graph.transformer.JavaScopeSelector;
+import org.eclipse.aether.util.graph.transformer.JavaDependencyContextRefiner;
+import org.eclipse.aether.util.graph.transformer.NearestVersionSelector;
+import org.eclipse.aether.util.graph.transformer.SimpleOptionalitySelector;
+import org.eclipse.aether.util.graph.traverser.FatArtifactTraverser;
+import org.eclipse.aether.util.repository.SimpleArtifactDescriptorPolicy;
+
+/**
+ * @author <a href="mailto:jason@maven.org">Jason van Zyl </a>
+ */
+public abstract class AbstractArtifactComponentTestCase
+ extends PlexusTestCase
+{
+ protected ArtifactFactory artifactFactory;
+
+ protected ArtifactRepositoryFactory artifactRepositoryFactory;
+
+ @Override
+ protected void customizeContainerConfiguration( ContainerConfiguration containerConfiguration )
+ {
+ super.customizeContainerConfiguration( containerConfiguration );
+ containerConfiguration.setAutoWiring( true );
+ containerConfiguration.setClassPathScanning( PlexusConstants.SCANNING_INDEX );
+ }
+
+ @Override
+ protected void setUp()
+ throws Exception
+ {
+ super.setUp();
+ artifactFactory = lookup( ArtifactFactory.class);
+ artifactRepositoryFactory = lookup( ArtifactRepositoryFactory.class );
+
+ RepositorySystemSession repoSession = initRepoSession();
+ MavenSession session =
+ new MavenSession( getContainer(), repoSession, new DefaultMavenExecutionRequest(),
+ new DefaultMavenExecutionResult() );
+
+ LegacySupport legacySupport = lookup(LegacySupport.class);
+ legacySupport.setSession( session );
+ }
+
+ @Override
+ protected void tearDown()
+ throws Exception
+ {
+ release( artifactFactory );
+
+ super.tearDown();
+ }
+
+ protected abstract String component();
+
+ /**
+ * Return an existing file, not a directory - causes creation to fail.
+ *
+ * @throws Exception
+ */
+ protected ArtifactRepository badLocalRepository()
+ throws Exception
+ {
+ String path = "target/test-repositories/" + component() + "/bad-local-repository";
+
+ File f = new File( getBasedir(), path );
+
+ f.createNewFile();
+
+ ArtifactRepositoryLayout repoLayout =
+ (ArtifactRepositoryLayout) lookup( ArtifactRepositoryLayout.ROLE, "default" );
+
+ return artifactRepositoryFactory.createArtifactRepository( "test", "file://" + f.getPath(), repoLayout, null, null );
+ }
+
+ protected String getRepositoryLayout()
+ {
+ return "default";
+ }
+
+ protected ArtifactRepository localRepository()
+ throws Exception
+ {
+ String path = "target/test-repositories/" + component() + "/local-repository";
+
+ File f = new File( getBasedir(), path );
+
+ ArtifactRepositoryLayout repoLayout =
+ (ArtifactRepositoryLayout) lookup( ArtifactRepositoryLayout.ROLE, "default" );
+
+ return artifactRepositoryFactory.createArtifactRepository( "local", "file://" + f.getPath(), repoLayout, null, null );
+ }
+
+ protected ArtifactRepository remoteRepository()
+ throws Exception
+ {
+ String path = "target/test-repositories/" + component() + "/remote-repository";
+
+ File f = new File( getBasedir(), path );
+
+ ArtifactRepositoryLayout repoLayout =
+ (ArtifactRepositoryLayout) lookup( ArtifactRepositoryLayout.ROLE, "default" );
+
+ return artifactRepositoryFactory.createArtifactRepository( "test", "file://" + f.getPath(), repoLayout,
+ new ArtifactRepositoryPolicy(), new ArtifactRepositoryPolicy() );
+ }
+
+ protected ArtifactRepository badRemoteRepository()
+ throws Exception
+ {
+ ArtifactRepositoryLayout repoLayout =
+ (ArtifactRepositoryLayout) lookup( ArtifactRepositoryLayout.ROLE, "default" );
+
+ return artifactRepositoryFactory.createArtifactRepository( "test", "http://foo.bar/repository", repoLayout, null, null );
+ }
+
+ protected void assertRemoteArtifactPresent( Artifact artifact )
+ throws Exception
+ {
+ ArtifactRepository remoteRepo = remoteRepository();
+
+ String path = remoteRepo.pathOf( artifact );
+
+ File file = new File( remoteRepo.getBasedir(), path );
+
+ if ( !file.exists() )
+ {
+ fail( "Remote artifact " + file + " should be present." );
+ }
+ }
+
+ protected void assertLocalArtifactPresent( Artifact artifact )
+ throws Exception
+ {
+ ArtifactRepository localRepo = localRepository();
+
+ String path = localRepo.pathOf( artifact );
+
+ File file = new File( localRepo.getBasedir(), path );
+
+ if ( !file.exists() )
+ {
+ fail( "Local artifact " + file + " should be present." );
+ }
+ }
+
+ protected void assertRemoteArtifactNotPresent( Artifact artifact )
+ throws Exception
+ {
+ ArtifactRepository remoteRepo = remoteRepository();
+
+ String path = remoteRepo.pathOf( artifact );
+
+ File file = new File( remoteRepo.getBasedir(), path );
+
+ if ( file.exists() )
+ {
+ fail( "Remote artifact " + file + " should not be present." );
+ }
+ }
+
+ protected void assertLocalArtifactNotPresent( Artifact artifact )
+ throws Exception
+ {
+ ArtifactRepository localRepo = localRepository();
+
+ String path = localRepo.pathOf( artifact );
+
+ File file = new File( localRepo.getBasedir(), path );
+
+ if ( file.exists() )
+ {
+ fail( "Local artifact " + file + " should not be present." );
+ }
+ }
+
+ // ----------------------------------------------------------------------
+ //
+ // ----------------------------------------------------------------------
+
+ protected List<ArtifactRepository> remoteRepositories()
+ throws Exception
+ {
+ List<ArtifactRepository> remoteRepositories = new ArrayList<ArtifactRepository>();
+
+ remoteRepositories.add( remoteRepository() );
+
+ return remoteRepositories;
+ }
+
+ // ----------------------------------------------------------------------
+ // Test artifact generation for unit tests
+ // ----------------------------------------------------------------------
+
+ protected Artifact createLocalArtifact( String artifactId, String version )
+ throws Exception
+ {
+ Artifact artifact = createArtifact( artifactId, version );
+
+ createArtifact( artifact, localRepository() );
+
+ return artifact;
+ }
+
+ protected Artifact createRemoteArtifact( String artifactId, String version )
+ throws Exception
+ {
+ Artifact artifact = createArtifact( artifactId, version );
+
+ createArtifact( artifact, remoteRepository() );
+
+ return artifact;
+ }
+
+ protected void createLocalArtifact( Artifact artifact )
+ throws Exception
+ {
+ createArtifact( artifact, localRepository() );
+ }
+
+ protected void createRemoteArtifact( Artifact artifact )
+ throws Exception
+ {
+ createArtifact( artifact, remoteRepository() );
+ }
+
+ protected void createArtifact( Artifact artifact, ArtifactRepository repository )
+ throws Exception
+ {
+ String path = repository.pathOf( artifact );
+
+ File artifactFile = new File( repository.getBasedir(), path );
+
+ if ( !artifactFile.getParentFile().exists() )
+ {
+ artifactFile.getParentFile().mkdirs();
+ }
+
+ Writer writer = new OutputStreamWriter( new FileOutputStream( artifactFile ), "ISO-8859-1" );
+
+ writer.write( artifact.getId() );
+
+ writer.close();
+ }
+
+ protected Artifact createArtifact( String artifactId, String version )
+ throws Exception
+ {
+ return createArtifact( artifactId, version, "jar" );
+ }
+
+ protected Artifact createArtifact( String artifactId, String version, String type )
+ throws Exception
+ {
+ return createArtifact( "org.apache.maven", artifactId, version, type );
+ }
+
+ protected Artifact createArtifact( String groupId, String artifactId, String version, String type )
+ throws Exception
+ {
+ Artifact a = artifactFactory.createBuildArtifact( groupId, artifactId, version, type );
+
+ return a;
+ }
+
+ protected void deleteLocalArtifact( Artifact artifact )
+ throws Exception
+ {
+ deleteArtifact( artifact, localRepository() );
+ }
+
+ protected void deleteArtifact( Artifact artifact, ArtifactRepository repository )
+ throws Exception
+ {
+ String path = repository.pathOf( artifact );
+
+ File artifactFile = new File( repository.getBasedir(), path );
+
+ if ( artifactFile.exists() )
+ {
+ if ( !artifactFile.delete() )
+ {
+ throw new IOException( "Failure while attempting to delete artifact " + artifactFile );
+ }
+ }
+ }
+
+ protected RepositorySystemSession initRepoSession()
+ throws Exception
+ {
+ DefaultRepositorySystemSession session = new DefaultRepositorySystemSession();
+ session.setArtifactDescriptorPolicy( new SimpleArtifactDescriptorPolicy( true, true ) );
+ DependencyTraverser depTraverser = new FatArtifactTraverser();
+ session.setDependencyTraverser( depTraverser );
+
+ DependencyManager depManager = new ClassicDependencyManager();
+ session.setDependencyManager( depManager );
+
+ DependencySelector depFilter =
+ new AndDependencySelector( new ScopeDependencySelector( "test", "provided" ),
+ new OptionalDependencySelector(), new ExclusionDependencySelector() );
+ session.setDependencySelector( depFilter );
+
+ DependencyGraphTransformer transformer =
+ new ConflictResolver( new NearestVersionSelector(), new JavaScopeSelector(),
+ new SimpleOptionalitySelector(), new JavaScopeDeriver() );
+ new ChainedDependencyGraphTransformer( transformer, new JavaDependencyContextRefiner() );
+ session.setDependencyGraphTransformer( transformer );
+
+ LocalRepository localRepo = new LocalRepository( localRepository().getBasedir() );
+ session.setLocalRepositoryManager( new SimpleLocalRepositoryManagerFactory().newInstance( session, localRepo ) );
+
+ return session;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/artifact/ArtifactUtilsTest.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/artifact/ArtifactUtilsTest.java
new file mode 100644
index 00000000..7b20eb5d
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/artifact/ArtifactUtilsTest.java
@@ -0,0 +1,79 @@
+package org.apache.maven.artifact;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.maven.artifact.versioning.VersionRange;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests {@link ArtifactUtils}.
+ *
+ * @author Benjamin Bentmann
+ */
+public class ArtifactUtilsTest
+ extends TestCase
+{
+
+ private Artifact newArtifact( String aid )
+ {
+ return new DefaultArtifact( "group", aid, VersionRange.createFromVersion( "1.0" ), "test", "jar", "tests", null );
+ }
+
+ public void testIsSnapshot()
+ {
+ assertEquals( false, ArtifactUtils.isSnapshot( null ) );
+ assertEquals( false, ArtifactUtils.isSnapshot( "" ) );
+ assertEquals( false, ArtifactUtils.isSnapshot( "1.2.3" ) );
+ assertEquals( true, ArtifactUtils.isSnapshot( "1.2.3-SNAPSHOT" ) );
+ assertEquals( true, ArtifactUtils.isSnapshot( "1.2.3-snapshot" ) );
+ assertEquals( true, ArtifactUtils.isSnapshot( "1.2.3-20090413.094722-2" ) );
+ }
+
+ public void testToSnapshotVersion()
+ {
+ assertEquals( "1.2.3", ArtifactUtils.toSnapshotVersion( "1.2.3" ) );
+ assertEquals( "1.2.3-SNAPSHOT", ArtifactUtils.toSnapshotVersion( "1.2.3-SNAPSHOT" ) );
+ assertEquals( "1.2.3-SNAPSHOT", ArtifactUtils.toSnapshotVersion( "1.2.3-20090413.094722-2" ) );
+ }
+
+ /**
+ * Tests that the ordering of the map resembles the ordering of the input collection of artifacts.
+ */
+ public void testArtifactMapByVersionlessIdOrdering()
+ throws Exception
+ {
+ List<Artifact> list = new ArrayList<Artifact>();
+ list.add( newArtifact( "b" ) );
+ list.add( newArtifact( "a" ) );
+ list.add( newArtifact( "c" ) );
+ list.add( newArtifact( "e" ) );
+ list.add( newArtifact( "d" ) );
+
+ Map<String, Artifact> map = ArtifactUtils.artifactMapByVersionlessId( list );
+ assertNotNull( map );
+ assertEquals( list, new ArrayList<Artifact>( map.values() ) );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/artifact/DefaultArtifactTest.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/artifact/DefaultArtifactTest.java
new file mode 100644
index 00000000..fbd01191
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/artifact/DefaultArtifactTest.java
@@ -0,0 +1,140 @@
+package org.apache.maven.artifact;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import junit.framework.TestCase;
+
+import org.apache.maven.artifact.handler.ArtifactHandlerMock;
+import org.apache.maven.artifact.versioning.VersionRange;
+
+public class DefaultArtifactTest
+ extends TestCase
+{
+
+ private DefaultArtifact artifact;
+
+ private DefaultArtifact snapshotArtifact;
+
+ private String groupId = "groupid", artifactId = "artifactId", version = "1.0", scope = "artifactScope", type = "type",
+ classifier = "classifier";
+
+ private String snapshotSpecVersion = "1.0-SNAPSHOT";
+ private String snapshotResolvedVersion = "1.0-20070606.010101-1";
+
+ private VersionRange versionRange;
+ private VersionRange snapshotVersionRange;
+
+ private ArtifactHandlerMock artifactHandler;
+
+ protected void setUp()
+ throws Exception
+ {
+ super.setUp();
+ artifactHandler = new ArtifactHandlerMock();
+ versionRange = VersionRange.createFromVersion( version );
+ artifact = new DefaultArtifact( groupId, artifactId, versionRange, scope, type, classifier, artifactHandler );
+
+ snapshotVersionRange = VersionRange.createFromVersion( snapshotResolvedVersion );
+ snapshotArtifact = new DefaultArtifact( groupId, artifactId, snapshotVersionRange, scope, type, classifier, artifactHandler );
+ }
+
+ public void testGetVersionReturnsResolvedVersionOnSnapshot()
+ {
+ assertEquals( snapshotResolvedVersion, snapshotArtifact.getVersion() );
+
+ // this is FOUL!
+// snapshotArtifact.isSnapshot();
+
+ assertEquals( snapshotSpecVersion, snapshotArtifact.getBaseVersion() );
+ }
+
+ public void testGetDependencyConflictId()
+ {
+ assertEquals( groupId + ":" + artifactId + ":" + type + ":" + classifier, artifact.getDependencyConflictId() );
+ }
+
+ public void testGetDependencyConflictIdNullGroupId()
+ {
+ artifact.setGroupId( null );
+ assertEquals( null + ":" + artifactId + ":" + type + ":" + classifier, artifact.getDependencyConflictId() );
+ }
+
+ public void testGetDependencyConflictIdNullClassifier()
+ {
+ artifact = new DefaultArtifact( groupId, artifactId, versionRange, scope, type, null, artifactHandler );
+ assertEquals( groupId + ":" + artifactId + ":" + type, artifact.getDependencyConflictId() );
+ }
+
+ public void testGetDependencyConflictIdNullScope()
+ {
+ artifact.setScope( null );
+ assertEquals( groupId + ":" + artifactId + ":" + type + ":" + classifier, artifact.getDependencyConflictId() );
+ }
+
+ public void testToString()
+ {
+ assertEquals( groupId + ":" + artifactId + ":" + type + ":" + classifier + ":" + version + ":" + scope,
+ artifact.toString() );
+ }
+
+ public void testToStringNullGroupId()
+ {
+ artifact.setGroupId( null );
+ assertEquals( artifactId + ":" + type + ":" + classifier + ":" + version + ":" + scope, artifact.toString() );
+ }
+
+ public void testToStringNullClassifier()
+ {
+ artifact = new DefaultArtifact( groupId, artifactId, versionRange, scope, type, null, artifactHandler );
+ assertEquals( groupId + ":" + artifactId + ":" + type + ":" + version + ":" + scope, artifact.toString() );
+ }
+
+ public void testToStringNullScope()
+ {
+ artifact.setScope( null );
+ assertEquals( groupId + ":" + artifactId + ":" + type + ":" + classifier + ":" + version, artifact.toString() );
+ }
+
+ public void testComparisonByVersion()
+ {
+ Artifact artifact1 = new DefaultArtifact( groupId, artifactId, VersionRange.createFromVersion( "5.0" ), scope,
+ type, classifier, artifactHandler );
+ Artifact artifact2 = new DefaultArtifact( groupId, artifactId, VersionRange.createFromVersion( "12.0" ), scope,
+ type, classifier, artifactHandler );
+
+ assertTrue( artifact1.compareTo( artifact2 ) < 0 );
+ assertTrue( artifact2.compareTo( artifact1 ) > 0 );
+
+ Artifact artifact = new DefaultArtifact( groupId, artifactId, VersionRange.createFromVersion( "5.0" ), scope,
+ type, classifier, artifactHandler );
+ assertTrue( artifact.compareTo( artifact1 ) == 0 );
+ assertTrue( artifact1.compareTo( artifact ) == 0 );
+ }
+
+ public void testNonResolvedVersionRangeConsistentlyYieldsNullVersions()
+ throws Exception
+ {
+ VersionRange vr = VersionRange.createFromVersionSpec( "[1.0,2.0)" );
+ artifact = new DefaultArtifact( groupId, artifactId, vr, scope, type, null, artifactHandler );
+ assertEquals( null, artifact.getVersion() );
+ assertEquals( null, artifact.getBaseVersion() );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/artifact/deployer/ArtifactDeployerTest.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/artifact/deployer/ArtifactDeployerTest.java
new file mode 100644
index 00000000..f929f480
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/artifact/deployer/ArtifactDeployerTest.java
@@ -0,0 +1,67 @@
+package org.apache.maven.artifact.deployer;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+
+import org.apache.maven.artifact.AbstractArtifactComponentTestCase;
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.codehaus.plexus.util.FileUtils;
+
+/**
+ * @author <a href="mailto:jason@maven.org">Jason van Zyl</a>
+ */
+public class ArtifactDeployerTest
+ extends AbstractArtifactComponentTestCase
+{
+ private ArtifactDeployer artifactDeployer;
+
+ protected void setUp()
+ throws Exception
+ {
+ super.setUp();
+
+ artifactDeployer = (ArtifactDeployer) lookup( ArtifactDeployer.ROLE );
+ }
+
+ protected String component()
+ {
+ return "deployer";
+ }
+
+ public void testArtifactInstallation()
+ throws Exception
+ {
+ String artifactBasedir = new File( getBasedir(), "src/test/resources/artifact-install" ).getAbsolutePath();
+
+ Artifact artifact = createArtifact( "artifact", "1.0" );
+
+ File file = new File( artifactBasedir, "artifact-1.0.jar" );
+ assertEquals( "dummy", FileUtils.fileRead( file, "UTF-8" ).trim() );
+
+ artifactDeployer.deploy( file, artifact, remoteRepository(), localRepository() );
+
+ ArtifactRepository remoteRepository = remoteRepository();
+ File deployedFile = new File( remoteRepository.getBasedir(), remoteRepository.pathOf( artifact ) );
+ assertTrue( deployedFile.exists() );
+ assertEquals( "dummy", FileUtils.fileRead( deployedFile, "UTF-8" ).trim() );
+ }
+} \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/artifact/deployer/SimpleArtifactMetadataSource.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/artifact/deployer/SimpleArtifactMetadataSource.java
new file mode 100644
index 00000000..f6bebcba
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/artifact/deployer/SimpleArtifactMetadataSource.java
@@ -0,0 +1,66 @@
+package org.apache.maven.artifact.deployer;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.versioning.ArtifactVersion;
+import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
+import org.apache.maven.repository.legacy.metadata.ArtifactMetadataRetrievalException;
+import org.apache.maven.repository.legacy.metadata.ArtifactMetadataSource;
+import org.apache.maven.repository.legacy.metadata.MetadataResolutionRequest;
+import org.apache.maven.repository.legacy.metadata.ResolutionGroup;
+
+/** @author Jason van Zyl */
+public class SimpleArtifactMetadataSource
+ implements ArtifactMetadataSource
+{
+ public ResolutionGroup retrieve( Artifact artifact, ArtifactRepository localRepository,
+ List<ArtifactRepository> remoteRepositories )
+ throws ArtifactMetadataRetrievalException
+ {
+ throw new UnsupportedOperationException( "Cannot retrieve metadata in this test case" );
+ }
+
+ public List<ArtifactVersion> retrieveAvailableVersions( Artifact artifact, ArtifactRepository localRepository,
+ List<ArtifactRepository> remoteRepositories )
+ throws ArtifactMetadataRetrievalException
+ {
+ return Collections.<ArtifactVersion>singletonList( new DefaultArtifactVersion( "10.1.3" ) );
+ }
+
+ public List<ArtifactVersion> retrieveAvailableVersionsFromDeploymentRepository( Artifact artifact,
+ ArtifactRepository localRepository,
+ ArtifactRepository remoteRepository )
+ throws ArtifactMetadataRetrievalException
+ {
+ return Collections.<ArtifactVersion>singletonList( new DefaultArtifactVersion( "10.1.3" ) );
+ }
+
+ public ResolutionGroup retrieve( MetadataResolutionRequest request )
+ throws ArtifactMetadataRetrievalException
+ {
+ return retrieve( request.getArtifact(), request.getLocalRepository(), request.getRemoteRepositories() );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/artifact/factory/DefaultArtifactFactoryTest.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/artifact/factory/DefaultArtifactFactoryTest.java
new file mode 100644
index 00000000..0d109acb
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/artifact/factory/DefaultArtifactFactoryTest.java
@@ -0,0 +1,49 @@
+package org.apache.maven.artifact.factory;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.versioning.VersionRange;
+import org.codehaus.plexus.PlexusTestCase;
+
+public class DefaultArtifactFactoryTest
+ extends PlexusTestCase
+{
+
+ public void testPropagationOfSystemScopeRegardlessOfInheritedScope() throws Exception
+ {
+ ArtifactFactory factory = (ArtifactFactory) lookup( ArtifactFactory.ROLE );
+
+ Artifact artifact = factory.createDependencyArtifact( "test-grp", "test-artifact", VersionRange.createFromVersion("1.0"), "type", null, "system", "provided" );
+ Artifact artifact2 = factory.createDependencyArtifact( "test-grp", "test-artifact-2", VersionRange.createFromVersion("1.0"), "type", null, "system", "test" );
+ Artifact artifact3 = factory.createDependencyArtifact( "test-grp", "test-artifact-3", VersionRange.createFromVersion("1.0"), "type", null, "system", "runtime" );
+ Artifact artifact4 = factory.createDependencyArtifact( "test-grp", "test-artifact-4", VersionRange.createFromVersion("1.0"), "type", null, "system", "compile" );
+
+ // this one should never happen in practice...
+ Artifact artifact5 = factory.createDependencyArtifact( "test-grp", "test-artifact-5", VersionRange.createFromVersion("1.0"), "type", null, "system", "system" );
+
+ assertEquals( "system", artifact.getScope() );
+ assertEquals( "system", artifact2.getScope() );
+ assertEquals( "system", artifact3.getScope() );
+ assertEquals( "system", artifact4.getScope() );
+ assertEquals( "system", artifact5.getScope() );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/artifact/handler/ArtifactHandlerMock.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/artifact/handler/ArtifactHandlerMock.java
new file mode 100644
index 00000000..a9f335e6
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/artifact/handler/ArtifactHandlerMock.java
@@ -0,0 +1,100 @@
+package org.apache.maven.artifact.handler;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+public class ArtifactHandlerMock
+ implements ArtifactHandler
+{
+
+ private String extension, directory, classifier, packaging, language;
+
+ private boolean includesDependencies, addedToClasspath;
+
+ public void setExtension( String extension )
+ {
+ this.extension = extension;
+ }
+
+ public String getExtension()
+ {
+ return extension;
+ }
+
+ public void setDirectory( String directory )
+ {
+ this.directory = directory;
+ }
+
+ public String getDirectory()
+ {
+ return directory;
+ }
+
+ public void setClassifier( String classifier )
+ {
+ this.classifier = classifier;
+ }
+
+ public String getClassifier()
+ {
+ return classifier;
+ }
+
+ public void setPackaging( String packaging )
+ {
+ this.packaging = packaging;
+ }
+
+ public String getPackaging()
+ {
+ return packaging;
+ }
+
+ public void setIncludesDependencies( boolean includesDependencies )
+ {
+ this.includesDependencies = includesDependencies;
+ }
+
+ public boolean isIncludesDependencies()
+ {
+ return includesDependencies;
+ }
+
+ public void setLanguage( String language )
+ {
+ this.language = language;
+ }
+
+ public String getLanguage()
+ {
+ return language;
+ }
+
+ public void setAddedToClasspath( boolean addedToClasspath )
+ {
+ this.addedToClasspath = addedToClasspath;
+ }
+
+ public boolean isAddedToClasspath()
+ {
+ return addedToClasspath;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/artifact/installer/ArtifactInstallerTest.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/artifact/installer/ArtifactInstallerTest.java
new file mode 100644
index 00000000..21bfb2b7
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/artifact/installer/ArtifactInstallerTest.java
@@ -0,0 +1,61 @@
+package org.apache.maven.artifact.installer;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+
+import org.apache.maven.artifact.AbstractArtifactComponentTestCase;
+import org.apache.maven.artifact.Artifact;
+
+/**
+ * @author <a href="mailto:jason@maven.org">Jason van Zyl</a>
+ */
+public class ArtifactInstallerTest
+ extends AbstractArtifactComponentTestCase
+{
+ private ArtifactInstaller artifactInstaller;
+
+ protected void setUp()
+ throws Exception
+ {
+ super.setUp();
+
+ artifactInstaller = (ArtifactInstaller) lookup( ArtifactInstaller.ROLE );
+ }
+
+ protected String component()
+ {
+ return "installer";
+ }
+
+ public void testArtifactInstallation()
+ throws Exception
+ {
+ String artifactBasedir = new File( getBasedir(), "src/test/resources/artifact-install" ).getAbsolutePath();
+
+ Artifact artifact = createArtifact( "artifact", "1.0" );
+
+ File source = new File( artifactBasedir, "artifact-1.0.jar" );
+
+ artifactInstaller.install( source, artifact, localRepository() );
+
+ assertLocalArtifactPresent( artifact );
+ }
+} \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/artifact/metadata/TestMetadataSource.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/artifact/metadata/TestMetadataSource.java
new file mode 100644
index 00000000..f8bb1677
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/artifact/metadata/TestMetadataSource.java
@@ -0,0 +1,102 @@
+package org.apache.maven.artifact.metadata;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.factory.ArtifactFactory;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.versioning.ArtifactVersion;
+import org.apache.maven.repository.legacy.metadata.MetadataResolutionRequest;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+
+@Component(role = ArtifactMetadataSource.class, hint="test")
+public class TestMetadataSource
+ implements ArtifactMetadataSource
+{
+ @Requirement
+ private ArtifactFactory factory;
+
+ public ResolutionGroup retrieve( Artifact artifact, ArtifactRepository localRepository, List<ArtifactRepository> remoteRepositories )
+ throws ArtifactMetadataRetrievalException
+ {
+ Set dependencies = new HashSet();
+
+ if ( "g".equals( artifact.getArtifactId() ) )
+ {
+ Artifact a = null;
+ try
+ {
+ a = factory.createBuildArtifact( "org.apache.maven", "h", "1.0", "jar" );
+ dependencies.add( a );
+ }
+ catch ( Exception e )
+ {
+ throw new ArtifactMetadataRetrievalException( "Error retrieving metadata", e, a );
+ }
+ }
+
+ if ( "i".equals( artifact.getArtifactId() ) )
+ {
+ Artifact a = null;
+ try
+ {
+ a = factory.createBuildArtifact( "org.apache.maven", "j", "1.0-SNAPSHOT", "jar" );
+ dependencies.add( a );
+ }
+ catch ( Exception e )
+ {
+ throw new ArtifactMetadataRetrievalException( "Error retrieving metadata", e, a );
+ }
+ }
+
+
+ return new ResolutionGroup( artifact, dependencies, remoteRepositories );
+ }
+
+ public List<ArtifactVersion> retrieveAvailableVersions( Artifact artifact, ArtifactRepository localRepository, List<ArtifactRepository> remoteRepositories )
+ throws ArtifactMetadataRetrievalException
+ {
+ throw new UnsupportedOperationException( "Cannot get available versions in this test case" );
+ }
+
+ public List<ArtifactVersion> retrieveAvailableVersionsFromDeploymentRepository( Artifact artifact, ArtifactRepository localRepository, ArtifactRepository remoteRepository )
+ throws ArtifactMetadataRetrievalException
+ {
+ throw new UnsupportedOperationException( "Cannot get available versions in this test case" );
+ }
+
+ public ResolutionGroup retrieve( MetadataResolutionRequest request )
+ throws ArtifactMetadataRetrievalException
+ {
+ return retrieve( request.getArtifact(), request.getLocalRepository(), request.getRemoteRepositories() );
+ }
+
+ public List<ArtifactVersion> retrieveAvailableVersions( MetadataResolutionRequest request )
+ throws ArtifactMetadataRetrievalException
+ {
+ return retrieveAvailableVersions( request.getArtifact(), request.getLocalRepository(), request.getRemoteRepositories() );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/artifact/repository/MavenArtifactRepositoryTest.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/artifact/repository/MavenArtifactRepositoryTest.java
new file mode 100644
index 00000000..533f3042
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/artifact/repository/MavenArtifactRepositoryTest.java
@@ -0,0 +1,59 @@
+package org.apache.maven.artifact.repository;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+
+import junit.framework.TestCase;
+
+public class MavenArtifactRepositoryTest
+ extends TestCase
+{
+ private static class MavenArtifactRepositorySubclass extends MavenArtifactRepository
+ {
+ String id;
+
+ public MavenArtifactRepositorySubclass(String id)
+ {
+ this.id = id;
+ }
+
+ @Override
+ public String getId()
+ {
+ return id;
+ }
+ }
+
+ public void testHashCodeEquals()
+ {
+ MavenArtifactRepositorySubclass r1 = new MavenArtifactRepositorySubclass( "foo" );
+ MavenArtifactRepositorySubclass r2 = new MavenArtifactRepositorySubclass( "foo" );
+ MavenArtifactRepositorySubclass r3 = new MavenArtifactRepositorySubclass( "bar" );
+
+ assertTrue( r1.hashCode() == r2.hashCode() );
+ assertFalse( r1.hashCode() == r3.hashCode() );
+
+ assertTrue( r1.equals( r2 ) );
+ assertTrue( r2.equals( r1 ) );
+
+ assertFalse( r1.equals( r3 ) );
+ assertFalse( r3.equals( r1 ) );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/artifact/resolver/ArtifactResolutionExceptionTest.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/artifact/resolver/ArtifactResolutionExceptionTest.java
new file mode 100644
index 00000000..aeacfb81
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/artifact/resolver/ArtifactResolutionExceptionTest.java
@@ -0,0 +1,64 @@
+package org.apache.maven.artifact.resolver;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Arrays;
+import java.util.List;
+
+import junit.framework.TestCase;
+
+/**
+ * Test the artifact resolution exception message
+ *
+ * @author Mauro Talevi
+ */
+public class ArtifactResolutionExceptionTest
+ extends TestCase
+{
+ private static final String LS = System.getProperty( "line.separator" );
+
+ public void testMissingArtifactMessageFormat()
+ {
+ String message = "Missing artifact";
+ String indentation = " ";
+ String groupId = "aGroupId";
+ String artifactId = "anArtifactId";
+ String version = "aVersion";
+ String type = "jar";
+ String classifier = "aClassifier";
+ String downloadUrl = "http://somewhere.com/download";
+ List path = Arrays.asList( "dependency1", "dependency2" );
+ String expected =
+ "Missing artifact" + LS + LS + " Try downloading the file manually from: " + LS
+ + " http://somewhere.com/download" + LS + LS + " Then, install it using the command: " + LS
+ + " mvn install:install-file -DgroupId=aGroupId -DartifactId=anArtifactId -Dversion=aVersion "
+ + "-Dclassifier=aClassifier -Dpackaging=jar -Dfile=/path/to/file" + LS + LS
+ + " Alternatively, if you host your own repository you can deploy the file there: " + LS
+ + " mvn deploy:deploy-file -DgroupId=aGroupId -DartifactId=anArtifactId"
+ + " -Dversion=aVersion -Dclassifier=aClassifier -Dpackaging=jar -Dfile=/path/to/file"
+ + " -Durl=[url] -DrepositoryId=[id]" + LS + LS + " Path to dependency: " + LS + " \t1) dependency1"
+ + LS + " \t2) dependency2" + LS + LS;
+ String actual =
+ AbstractArtifactResolutionException.constructMissingArtifactMessage( message, indentation, groupId,
+ artifactId, version, type, classifier,
+ downloadUrl, path );
+ assertEquals( expected, actual );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/artifact/resolver/ArtifactResolverTest.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/artifact/resolver/ArtifactResolverTest.java
new file mode 100644
index 00000000..117c0e22
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/artifact/resolver/ArtifactResolverTest.java
@@ -0,0 +1,283 @@
+package org.apache.maven.artifact.resolver;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.maven.artifact.AbstractArtifactComponentTestCase;
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.metadata.ArtifactMetadataRetrievalException;
+import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
+import org.apache.maven.artifact.metadata.ResolutionGroup;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.versioning.ArtifactVersion;
+import org.apache.maven.repository.legacy.metadata.MetadataResolutionRequest;
+import org.codehaus.plexus.component.repository.ComponentDescriptor;
+
+// It would be cool if there was a hook that i could use to setup a test environment.
+// I want to setup a local/remote repositories for testing but i don't want to have
+// to change them when i change the layout of the repositories. So i want to generate
+// the structure i want to test by using the artifact handler manager which dictates
+// the layout used for a particular artifact type.
+
+/**
+ * @author Jason van Zyl
+ */
+public class ArtifactResolverTest
+ extends AbstractArtifactComponentTestCase
+{
+ private DefaultArtifactResolver artifactResolver;
+
+ private Artifact projectArtifact;
+
+ @Override
+ protected void setUp()
+ throws Exception
+ {
+ super.setUp();
+
+ artifactResolver = (DefaultArtifactResolver) lookup( ArtifactResolver.class );
+
+ projectArtifact = createLocalArtifact( "project", "3.0" );
+ }
+
+ @Override
+ protected void tearDown()
+ throws Exception
+ {
+ artifactFactory = null;
+ projectArtifact = null;
+ super.tearDown();
+ }
+
+ @Override
+ protected String component()
+ {
+ return "resolver";
+ }
+
+ public void testResolutionOfASingleArtifactWhereTheArtifactIsPresentInTheLocalRepository()
+ throws Exception
+ {
+ Artifact a = createLocalArtifact( "a", "1.0" );
+
+ artifactResolver.resolve( a, remoteRepositories(), localRepository() );
+
+ assertLocalArtifactPresent( a );
+ }
+
+ public void testResolutionOfASingleArtifactWhereTheArtifactIsNotPresentLocallyAndMustBeRetrievedFromTheRemoteRepository()
+ throws Exception
+ {
+ Artifact b = createRemoteArtifact( "b", "1.0-SNAPSHOT" );
+ deleteLocalArtifact( b );
+ artifactResolver.resolve( b, remoteRepositories(), localRepository() );
+ assertLocalArtifactPresent( b );
+ }
+
+ @Override
+ protected Artifact createArtifact( String groupId, String artifactId, String version, String type )
+ throws Exception
+ {
+ // for the anonymous classes
+ return super.createArtifact( groupId, artifactId, version, type );
+ }
+
+ public void testTransitiveResolutionWhereAllArtifactsArePresentInTheLocalRepository()
+ throws Exception
+ {
+ Artifact g = createLocalArtifact( "g", "1.0" );
+
+ Artifact h = createLocalArtifact( "h", "1.0" );
+
+ ArtifactResolutionResult result = artifactResolver.resolveTransitively( Collections.singleton( g ), projectArtifact, remoteRepositories(), localRepository(), null );
+
+ printErrors( result );
+
+ assertEquals( 2, result.getArtifacts().size() );
+
+ assertTrue( result.getArtifacts().contains( g ) );
+
+ assertTrue( result.getArtifacts().contains( h ) );
+
+ assertLocalArtifactPresent( g );
+
+ assertLocalArtifactPresent( h );
+ }
+
+ public void testTransitiveResolutionWhereAllArtifactsAreNotPresentInTheLocalRepositoryAndMustBeRetrievedFromTheRemoteRepository()
+ throws Exception
+ {
+ Artifact i = createRemoteArtifact( "i", "1.0-SNAPSHOT" );
+ deleteLocalArtifact( i );
+
+ Artifact j = createRemoteArtifact( "j", "1.0-SNAPSHOT" );
+ deleteLocalArtifact( j );
+
+ ArtifactResolutionResult result = artifactResolver.resolveTransitively( Collections.singleton( i ), projectArtifact, remoteRepositories(), localRepository(), null );
+
+ printErrors( result );
+
+ assertEquals( 2, result.getArtifacts().size() );
+
+ assertTrue( result.getArtifacts().contains( i ) );
+
+ assertTrue( result.getArtifacts().contains( j ) );
+
+ assertLocalArtifactPresent( i );
+
+ assertLocalArtifactPresent( j );
+ }
+
+ public void testResolutionFailureWhenArtifactNotPresentInRemoteRepository()
+ throws Exception
+ {
+ Artifact k = createArtifact( "k", "1.0" );
+
+ try
+ {
+ artifactResolver.resolve( k, remoteRepositories(), localRepository() );
+ fail( "Resolution succeeded when it should have failed" );
+ }
+ catch ( ArtifactNotFoundException expected )
+ {
+ assertTrue( true );
+ }
+ }
+
+ public void testResolutionOfAnArtifactWhereOneRemoteRepositoryIsBadButOneIsGood()
+ throws Exception
+ {
+ Artifact l = createRemoteArtifact( "l", "1.0-SNAPSHOT" );
+ deleteLocalArtifact( l );
+
+ List<ArtifactRepository> repositories = new ArrayList<ArtifactRepository>();
+ repositories.add( remoteRepository() );
+ repositories.add( badRemoteRepository() );
+
+ artifactResolver.resolve( l, repositories, localRepository() );
+
+ assertLocalArtifactPresent( l );
+ }
+
+ public void testTransitiveResolutionOrder()
+ throws Exception
+ {
+ Artifact m = createLocalArtifact( "m", "1.0" );
+
+ Artifact n = createLocalArtifact( "n", "1.0" );
+
+ ArtifactMetadataSource mds = new ArtifactMetadataSource()
+ {
+ public ResolutionGroup retrieve( Artifact artifact, ArtifactRepository localRepository,
+ List<ArtifactRepository> remoteRepositories )
+ throws ArtifactMetadataRetrievalException
+ {
+ Set dependencies = new HashSet();
+
+ return new ResolutionGroup( artifact, dependencies, remoteRepositories );
+ }
+
+ public List<ArtifactVersion> retrieveAvailableVersions( Artifact artifact,
+ ArtifactRepository localRepository,
+ List<ArtifactRepository> remoteRepositories )
+ throws ArtifactMetadataRetrievalException
+ {
+ throw new UnsupportedOperationException( "Cannot get available versions in this test case" );
+ }
+
+ public List<ArtifactVersion> retrieveAvailableVersionsFromDeploymentRepository(
+ Artifact artifact,
+ ArtifactRepository localRepository,
+ ArtifactRepository remoteRepository )
+ throws ArtifactMetadataRetrievalException
+ {
+ throw new UnsupportedOperationException( "Cannot get available versions in this test case" );
+ }
+
+ public ResolutionGroup retrieve( MetadataResolutionRequest request )
+ throws ArtifactMetadataRetrievalException
+ {
+ return retrieve( request.getArtifact(), request.getLocalRepository(), request.getRemoteRepositories() );
+ }
+
+ public List<ArtifactVersion> retrieveAvailableVersions( MetadataResolutionRequest request )
+ throws ArtifactMetadataRetrievalException
+ {
+ return retrieveAvailableVersions( request.getArtifact(), request.getLocalRepository(), request.getRemoteRepositories() );
+ }
+ };
+
+ ArtifactResolutionResult result = null;
+
+ Set set = new LinkedHashSet();
+ set.add( n );
+ set.add( m );
+
+ result =
+ artifactResolver.resolveTransitively( set, projectArtifact, remoteRepositories(), localRepository(), mds );
+
+ printErrors( result );
+
+ Iterator i = result.getArtifacts().iterator();
+ assertEquals( "n should be first", n, i.next() );
+ assertEquals( "m should be second", m, i.next() );
+
+ // inverse order
+ set = new LinkedHashSet();
+ set.add( m );
+ set.add( n );
+
+ result =
+ artifactResolver.resolveTransitively( set, projectArtifact, remoteRepositories(), localRepository(), mds );
+
+ printErrors( result );
+
+ i = result.getArtifacts().iterator();
+ assertEquals( "m should be first", m, i.next() );
+ assertEquals( "n should be second", n, i.next() );
+ }
+
+ private void printErrors( ArtifactResolutionResult result )
+ {
+ if ( result.hasMissingArtifacts() )
+ {
+ for ( Artifact artifact : result.getMissingArtifacts() )
+ {
+ System.err.println( "Missing: " + artifact );
+ }
+ }
+
+ if ( result.hasExceptions() )
+ {
+ for ( Exception e : result.getExceptions() )
+ {
+ e.printStackTrace();
+ }
+ }
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/artifact/resolver/DefaultArtifactResolverTest.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/artifact/resolver/DefaultArtifactResolverTest.java
new file mode 100644
index 00000000..914d9d1c
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/artifact/resolver/DefaultArtifactResolverTest.java
@@ -0,0 +1,111 @@
+package org.apache.maven.artifact.resolver;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Collections;
+
+import org.apache.maven.artifact.AbstractArtifactComponentTestCase;
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.resolver.DefaultArtifactResolver.DaemonThreadCreator;
+
+public class DefaultArtifactResolverTest
+ extends AbstractArtifactComponentTestCase
+{
+ private DefaultArtifactResolver artifactResolver;
+
+ private Artifact projectArtifact;
+
+ @Override
+ protected void setUp()
+ throws Exception
+ {
+ super.setUp();
+
+ artifactResolver = (DefaultArtifactResolver) lookup( ArtifactResolver.class );
+
+ projectArtifact = createLocalArtifact( "project", "3.0" );
+ }
+
+ @Override
+ protected void tearDown()
+ throws Exception
+ {
+ artifactFactory = null;
+ projectArtifact = null;
+ super.tearDown();
+ }
+
+ @Override
+ protected String component()
+ {
+ return "resolver";
+ }
+
+ public void testMNG4738()
+ throws Exception
+ {
+ Artifact g = createLocalArtifact( "g", "1.0" );
+ createLocalArtifact( "h", "1.0" );
+ artifactResolver.resolveTransitively( Collections.singleton( g ), projectArtifact, remoteRepositories(),
+ localRepository(), null );
+
+ // we want to see all top-level thread groups
+ ThreadGroup tg = Thread.currentThread().getThreadGroup();
+ while ( tg.getParent() == null )
+ {
+ tg = tg.getParent();
+ }
+
+ ThreadGroup[] tgList = new ThreadGroup[tg.activeGroupCount()];
+ tg.enumerate( tgList );
+
+ boolean seen = false;
+
+ for ( ThreadGroup aTgList : tgList )
+ {
+ if ( !aTgList.getName().equals( DaemonThreadCreator.THREADGROUP_NAME ) )
+ {
+ continue;
+ }
+
+ seen = true;
+
+ tg = aTgList;
+ Thread[] ts = new Thread[tg.activeCount()];
+ tg.enumerate( ts );
+
+ for ( Thread active : ts )
+ {
+ String name = active.getName();
+ boolean daemon = active.isDaemon();
+ assertTrue( name + " is no daemon Thread.", daemon );
+ }
+
+ }
+
+ assertTrue( "Could not find ThreadGroup: " + DaemonThreadCreator.THREADGROUP_NAME, seen );
+ }
+
+ public void testLookup()
+ throws Exception
+ {
+ ArtifactResolver resolver = lookup( ArtifactResolver.class, "default" );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/artifact/resolver/TestFileWagon.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/artifact/resolver/TestFileWagon.java
new file mode 100644
index 00000000..c78c1901
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/artifact/resolver/TestFileWagon.java
@@ -0,0 +1,94 @@
+package org.apache.maven.artifact.resolver;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.io.InputStream;
+
+import org.apache.maven.wagon.ResourceDoesNotExistException;
+import org.apache.maven.wagon.TransferFailedException;
+import org.apache.maven.wagon.authorization.AuthorizationException;
+import org.apache.maven.wagon.events.TransferListener;
+import org.apache.maven.wagon.providers.file.FileWagon;
+import org.apache.maven.wagon.resource.Resource;
+
+/**
+ * Wagon used for test cases that annotates some methods. Note that this is not a thread-safe implementation.
+ */
+public class TestFileWagon
+ extends FileWagon
+{
+ private TestTransferListener testTransferListener;
+ private boolean insideGet;
+
+ protected void getTransfer( Resource resource,
+ File destination,
+ InputStream input,
+ boolean closeInput,
+ int maxSize )
+ throws TransferFailedException
+ {
+ addTransfer( "getTransfer " + resource.getName() );
+ super.getTransfer( resource, destination, input, closeInput, maxSize );
+ }
+
+ public void get( String resourceName, File destination )
+ throws TransferFailedException,
+ ResourceDoesNotExistException,
+ AuthorizationException
+ {
+ addTransfer( "get " + resourceName );
+
+ insideGet = true;
+
+ super.get( resourceName, destination );
+
+ insideGet = false;
+ }
+
+ private void addTransfer( String resourceName )
+ {
+ if ( testTransferListener != null )
+ {
+ testTransferListener.addTransfer( resourceName );
+ }
+ }
+
+ public boolean getIfNewer( String resourceName, File destination, long timestamp )
+ throws TransferFailedException,
+ ResourceDoesNotExistException,
+ AuthorizationException
+ {
+ if ( !insideGet )
+ {
+ addTransfer( "getIfNewer " + resourceName );
+ }
+ return super.getIfNewer( resourceName, destination, timestamp );
+ }
+
+ public void addTransferListener( TransferListener listener )
+ {
+ if ( listener instanceof TestTransferListener )
+ {
+ testTransferListener = (TestTransferListener) listener;
+ }
+ super.addTransferListener( listener );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/artifact/resolver/TestTransferListener.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/artifact/resolver/TestTransferListener.java
new file mode 100644
index 00000000..afec3ef5
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/artifact/resolver/TestTransferListener.java
@@ -0,0 +1,43 @@
+package org.apache.maven.artifact.resolver;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.maven.wagon.observers.AbstractTransferListener;
+
+public class TestTransferListener
+ extends AbstractTransferListener
+{
+
+ private final List<String> transfers = new ArrayList<String>();
+
+ public List<String> getTransfers()
+ {
+ return transfers;
+ }
+
+ public void addTransfer( String name )
+ {
+ transfers.add( name );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/artifact/resolver/filter/AndArtifactFilterTest.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/artifact/resolver/filter/AndArtifactFilterTest.java
new file mode 100644
index 00000000..bca112b8
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/artifact/resolver/filter/AndArtifactFilterTest.java
@@ -0,0 +1,62 @@
+package org.apache.maven.artifact.resolver.filter;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Arrays;
+
+import org.apache.maven.artifact.Artifact;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests {@link AndArtifactFilter}.
+ *
+ * @author Benjamin Bentmann
+ */
+public class AndArtifactFilterTest
+ extends TestCase
+{
+
+ private ArtifactFilter newSubFilter()
+ {
+ return new ArtifactFilter()
+ {
+ public boolean include( Artifact artifact )
+ {
+ return false;
+ }
+ };
+ }
+
+ public void testEquals()
+ {
+ AndArtifactFilter filter1 = new AndArtifactFilter();
+
+ AndArtifactFilter filter2 = new AndArtifactFilter( Arrays.asList( newSubFilter() ) );
+
+ assertFalse( filter1.equals( null ) );
+ assertTrue( filter1.equals( filter1 ) );
+ assertEquals( filter1.hashCode(), filter1.hashCode() );
+
+ assertFalse( filter1.equals( filter2 ) );
+ assertFalse( filter2.equals( filter1 ) );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/artifact/resolver/filter/FilterHashEqualsTest.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/artifact/resolver/filter/FilterHashEqualsTest.java
new file mode 100644
index 00000000..fb465663
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/artifact/resolver/filter/FilterHashEqualsTest.java
@@ -0,0 +1,50 @@
+package org.apache.maven.artifact.resolver.filter;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Arrays;
+import java.util.List;
+
+import junit.framework.TestCase;
+
+/**
+ * @author Igor Fedorenko
+ */
+public class FilterHashEqualsTest
+ extends TestCase
+{
+
+ public void testIncludesExcludesArtifactFilter()
+ {
+ List<String> patterns = Arrays.asList( "c", "d", "e" );
+
+ IncludesArtifactFilter f1 = new IncludesArtifactFilter( patterns );
+
+ IncludesArtifactFilter f2 = new IncludesArtifactFilter( patterns );
+
+ assertTrue( f1.equals(f2) );
+ assertTrue( f2.equals(f1) );
+ assertTrue( f1.hashCode() == f2.hashCode() );
+
+ IncludesArtifactFilter f3 = new IncludesArtifactFilter( Arrays.asList( "d", "c", "e" ) );
+ assertTrue( f1.equals( f3 ) );
+ assertTrue( f1.hashCode() == f3.hashCode() );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/artifact/resolver/filter/OrArtifactFilterTest.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/artifact/resolver/filter/OrArtifactFilterTest.java
new file mode 100644
index 00000000..e161437f
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/artifact/resolver/filter/OrArtifactFilterTest.java
@@ -0,0 +1,62 @@
+package org.apache.maven.artifact.resolver.filter;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Arrays;
+
+import org.apache.maven.artifact.Artifact;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests {@link OrArtifactFilter}.
+ *
+ * @author Benjamin Bentmann
+ */
+public class OrArtifactFilterTest
+ extends TestCase
+{
+
+ private ArtifactFilter newSubFilter()
+ {
+ return new ArtifactFilter()
+ {
+ public boolean include( Artifact artifact )
+ {
+ return false;
+ }
+ };
+ }
+
+ public void testEquals()
+ {
+ OrArtifactFilter filter1 = new OrArtifactFilter();
+
+ OrArtifactFilter filter2 = new OrArtifactFilter( Arrays.asList( newSubFilter() ) );
+
+ assertFalse( filter1.equals( null ) );
+ assertTrue( filter1.equals( filter1 ) );
+ assertEquals( filter1.hashCode(), filter1.hashCode() );
+
+ assertFalse( filter1.equals( filter2 ) );
+ assertFalse( filter2.equals( filter1 ) );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/artifact/resolver/filter/ScopeArtifactFilterTest.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/artifact/resolver/filter/ScopeArtifactFilterTest.java
new file mode 100644
index 00000000..1a65eca0
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/artifact/resolver/filter/ScopeArtifactFilterTest.java
@@ -0,0 +1,96 @@
+package org.apache.maven.artifact.resolver.filter;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.DefaultArtifact;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests {@link ScopeArtifactFilter}.
+ *
+ * @author Benjamin Bentmann
+ */
+public class ScopeArtifactFilterTest
+ extends TestCase
+{
+
+ private Artifact newArtifact( String scope )
+ {
+ return new DefaultArtifact( "g", "a", "1.0", scope, "jar", "", null );
+ }
+
+ public void testInclude_Compile()
+ {
+ ScopeArtifactFilter filter = new ScopeArtifactFilter( Artifact.SCOPE_COMPILE );
+
+ assertTrue( filter.include( newArtifact( Artifact.SCOPE_COMPILE ) ) );
+ assertTrue( filter.include( newArtifact( Artifact.SCOPE_SYSTEM ) ) );
+ assertTrue( filter.include( newArtifact( Artifact.SCOPE_PROVIDED ) ) );
+ assertFalse( filter.include( newArtifact( Artifact.SCOPE_RUNTIME ) ) );
+ assertFalse( filter.include( newArtifact( Artifact.SCOPE_TEST ) ) );
+ }
+
+ public void testInclude_CompilePlusRuntime()
+ {
+ ScopeArtifactFilter filter = new ScopeArtifactFilter( Artifact.SCOPE_COMPILE_PLUS_RUNTIME );
+
+ assertTrue( filter.include( newArtifact( Artifact.SCOPE_COMPILE ) ) );
+ assertTrue( filter.include( newArtifact( Artifact.SCOPE_SYSTEM ) ) );
+ assertTrue( filter.include( newArtifact( Artifact.SCOPE_PROVIDED ) ) );
+ assertTrue( filter.include( newArtifact( Artifact.SCOPE_RUNTIME ) ) );
+ assertFalse( filter.include( newArtifact( Artifact.SCOPE_TEST ) ) );
+ }
+
+ public void testInclude_Runtime()
+ {
+ ScopeArtifactFilter filter = new ScopeArtifactFilter( Artifact.SCOPE_RUNTIME );
+
+ assertTrue( filter.include( newArtifact( Artifact.SCOPE_COMPILE ) ) );
+ assertFalse( filter.include( newArtifact( Artifact.SCOPE_SYSTEM ) ) );
+ assertFalse( filter.include( newArtifact( Artifact.SCOPE_PROVIDED ) ) );
+ assertTrue( filter.include( newArtifact( Artifact.SCOPE_RUNTIME ) ) );
+ assertFalse( filter.include( newArtifact( Artifact.SCOPE_TEST ) ) );
+ }
+
+ public void testInclude_RuntimePlusSystem()
+ {
+ ScopeArtifactFilter filter = new ScopeArtifactFilter( Artifact.SCOPE_RUNTIME_PLUS_SYSTEM );
+
+ assertTrue( filter.include( newArtifact( Artifact.SCOPE_COMPILE ) ) );
+ assertTrue( filter.include( newArtifact( Artifact.SCOPE_SYSTEM ) ) );
+ assertFalse( filter.include( newArtifact( Artifact.SCOPE_PROVIDED ) ) );
+ assertTrue( filter.include( newArtifact( Artifact.SCOPE_RUNTIME ) ) );
+ assertFalse( filter.include( newArtifact( Artifact.SCOPE_TEST ) ) );
+ }
+
+ public void testInclude_Test()
+ {
+ ScopeArtifactFilter filter = new ScopeArtifactFilter( Artifact.SCOPE_TEST );
+
+ assertTrue( filter.include( newArtifact( Artifact.SCOPE_COMPILE ) ) );
+ assertTrue( filter.include( newArtifact( Artifact.SCOPE_SYSTEM ) ) );
+ assertTrue( filter.include( newArtifact( Artifact.SCOPE_PROVIDED ) ) );
+ assertTrue( filter.include( newArtifact( Artifact.SCOPE_RUNTIME ) ) );
+ assertTrue( filter.include( newArtifact( Artifact.SCOPE_TEST ) ) );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/artifact/testutils/TestFileManager.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/artifact/testutils/TestFileManager.java
new file mode 100644
index 00000000..a9f1ab7d
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/artifact/testutils/TestFileManager.java
@@ -0,0 +1,224 @@
+package org.apache.maven.artifact.testutils;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import junit.framework.Assert;
+
+import org.codehaus.plexus.util.FileUtils;
+
+public class TestFileManager
+{
+
+ public static final String TEMP_DIR_PATH = System.getProperty( "java.io.tmpdir" );
+
+ private List<File> filesToDelete = new ArrayList<File>();
+
+ private final String baseFilename;
+
+ private final String fileSuffix;
+
+ private StackTraceElement callerInfo;
+
+ private Thread cleanupWarning;
+
+ private boolean warnAboutCleanup = false;
+
+ public TestFileManager( String baseFilename, String fileSuffix )
+ {
+ this.baseFilename = baseFilename;
+ this.fileSuffix = fileSuffix;
+
+ initializeCleanupMonitoring();
+ }
+
+ private void initializeCleanupMonitoring()
+ {
+ callerInfo = new NullPointerException().getStackTrace()[2];
+
+ Runnable warning = new Runnable()
+ {
+
+ public void run()
+ {
+ maybeWarnAboutCleanUp();
+ }
+
+ };
+
+ cleanupWarning = new Thread( warning );
+
+ Runtime.getRuntime().addShutdownHook( cleanupWarning );
+ }
+
+ private void maybeWarnAboutCleanUp()
+ {
+ if ( warnAboutCleanup )
+ {
+ System.out.println( "[WARNING] TestFileManager from: " + callerInfo.getClassName() + " not cleaned up!" );
+ }
+ }
+
+ public void markForDeletion( File toDelete )
+ {
+ filesToDelete.add( toDelete );
+ warnAboutCleanup = true;
+ }
+
+ public synchronized File createTempDir()
+ {
+ try
+ {
+ Thread.sleep( 20 );
+ }
+ catch ( InterruptedException e )
+ {
+ // ignore
+ }
+
+ File dir = new File( TEMP_DIR_PATH, baseFilename + System.currentTimeMillis() );
+
+ dir.mkdirs();
+ markForDeletion( dir );
+
+ return dir;
+ }
+
+ public synchronized File createTempFile()
+ throws IOException
+ {
+ File tempFile = File.createTempFile( baseFilename, fileSuffix );
+ tempFile.deleteOnExit();
+ markForDeletion( tempFile );
+
+ return tempFile;
+ }
+
+ public void cleanUp()
+ throws IOException
+ {
+ for ( Iterator it = filesToDelete.iterator(); it.hasNext(); )
+ {
+ File file = (File) it.next();
+
+ if ( file.exists() )
+ {
+ if ( file.isDirectory() )
+ {
+ FileUtils.deleteDirectory( file );
+ }
+ else
+ {
+ file.delete();
+ }
+ }
+
+ it.remove();
+ }
+
+ warnAboutCleanup = false;
+ }
+
+ public void assertFileExistence( File dir, String filename, boolean shouldExist )
+ {
+ File file = new File( dir, filename );
+
+ if ( shouldExist )
+ {
+ Assert.assertTrue( file.exists() );
+ }
+ else
+ {
+ Assert.assertFalse( file.exists() );
+ }
+ }
+
+ public void assertFileContents( File dir, String filename, String contentsTest, String encoding )
+ throws IOException
+ {
+ assertFileExistence( dir, filename, true );
+
+ File file = new File( dir, filename );
+
+ String contents = FileUtils.fileRead( file, encoding );
+
+ Assert.assertEquals( contentsTest, contents );
+ }
+
+ public File createFile( File dir, String filename, String contents, String encoding )
+ throws IOException
+ {
+ File file = new File( dir, filename );
+
+ file.getParentFile().mkdirs();
+
+ FileUtils.fileWrite( file.getPath(), encoding, contents );
+
+ markForDeletion( file );
+
+ return file;
+ }
+
+ public String getFileContents( File file, String encoding )
+ throws IOException
+ {
+ return FileUtils.fileRead( file, encoding );
+ }
+
+ protected void finalize()
+ throws Throwable
+ {
+ maybeWarnAboutCleanUp();
+
+ super.finalize();
+ }
+
+ public File createFile( String filename, String content, String encoding )
+ throws IOException
+ {
+ File dir = createTempDir();
+ return createFile( dir, filename, content, encoding );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/artifact/transform/TransformationManagerTest.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/artifact/transform/TransformationManagerTest.java
new file mode 100644
index 00000000..38450929
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/artifact/transform/TransformationManagerTest.java
@@ -0,0 +1,46 @@
+package org.apache.maven.artifact.transform;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+import java.util.List;
+
+import org.apache.maven.repository.legacy.resolver.transform.ArtifactTransformationManager;
+import org.apache.maven.repository.legacy.resolver.transform.LatestArtifactTransformation;
+import org.apache.maven.repository.legacy.resolver.transform.ReleaseArtifactTransformation;
+import org.apache.maven.repository.legacy.resolver.transform.SnapshotTransformation;
+import org.codehaus.plexus.PlexusTestCase;
+
+/** @author Jason van Zyl */
+public class TransformationManagerTest
+ extends PlexusTestCase
+{
+ public void testTransformationManager()
+ throws Exception
+ {
+ ArtifactTransformationManager tm = lookup( ArtifactTransformationManager.class );
+
+ List tms = tm.getArtifactTransformations();
+
+ assertEquals( 3, tms.size() );
+
+ assertTrue( "We expected the release transformation and got " + tms.get(0), tms.get(0) instanceof ReleaseArtifactTransformation );
+
+ assertTrue( "We expected the latest transformation and got " + tms.get(1), tms.get(1) instanceof LatestArtifactTransformation );
+
+ assertTrue( "We expected the snapshot transformation and got " + tms.get(2), tms.get(2) instanceof SnapshotTransformation );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/profiles/manager/DefaultProfileManagerTest.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/profiles/manager/DefaultProfileManagerTest.java
new file mode 100644
index 00000000..8e3b86a6
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/profiles/manager/DefaultProfileManagerTest.java
@@ -0,0 +1,232 @@
+package org.apache.maven.profiles.manager;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.List;
+import java.util.Properties;
+
+import org.apache.maven.model.Activation;
+import org.apache.maven.model.ActivationProperty;
+import org.apache.maven.model.Profile;
+import org.apache.maven.profiles.DefaultProfileManager;
+import org.apache.maven.profiles.ProfileManager;
+import org.codehaus.plexus.PlexusTestCase;
+
+public class DefaultProfileManagerTest
+ extends PlexusTestCase
+{
+
+ public void setUp()
+ throws Exception
+ {
+ super.setUp();
+ }
+
+ public void testShouldActivateDefaultProfile()
+ throws Exception
+ {
+ Profile notActivated = new Profile();
+ notActivated.setId( "notActivated" );
+
+ Activation nonActivation = new Activation();
+
+ nonActivation.setJdk( "19.2" );
+
+ notActivated.setActivation( nonActivation );
+
+ Profile defaultActivated = new Profile();
+ defaultActivated.setId( "defaultActivated" );
+
+ Activation defaultActivation = new Activation();
+
+ defaultActivation.setActiveByDefault( true );
+
+ defaultActivated.setActivation( defaultActivation );
+
+ Properties props = System.getProperties();
+
+ ProfileManager profileManager = new DefaultProfileManager( getContainer(), props );
+
+ profileManager.addProfile( notActivated );
+ profileManager.addProfile( defaultActivated );
+
+ List active = profileManager.getActiveProfiles();
+
+ assertNotNull( active );
+ assertEquals( 1, active.size() );
+ assertEquals( "defaultActivated", ( (Profile) active.get( 0 ) ).getId() );
+ }
+
+ public void testShouldNotActivateDefaultProfile()
+ throws Exception
+ {
+ Profile syspropActivated = new Profile();
+ syspropActivated.setId( "syspropActivated" );
+
+ Activation syspropActivation = new Activation();
+
+ ActivationProperty syspropProperty = new ActivationProperty();
+ syspropProperty.setName( "java.version" );
+
+ syspropActivation.setProperty( syspropProperty );
+
+ syspropActivated.setActivation( syspropActivation );
+
+ Profile defaultActivated = new Profile();
+ defaultActivated.setId( "defaultActivated" );
+
+ Activation defaultActivation = new Activation();
+
+ defaultActivation.setActiveByDefault( true );
+
+ defaultActivated.setActivation( defaultActivation );
+
+ Properties props = System.getProperties();
+
+ ProfileManager profileManager = new DefaultProfileManager( getContainer(), props );
+
+ profileManager.addProfile( syspropActivated );
+ profileManager.addProfile( defaultActivated );
+
+ List active = profileManager.getActiveProfiles();
+
+ assertNotNull( active );
+ assertEquals( 1, active.size() );
+ assertEquals( "syspropActivated", ( (Profile) active.get( 0 ) ).getId() );
+ }
+
+
+ public void testShouldNotActivateReversalOfPresentSystemProperty()
+ throws Exception
+ {
+ Profile syspropActivated = new Profile();
+ syspropActivated.setId( "syspropActivated" );
+
+ Activation syspropActivation = new Activation();
+
+ ActivationProperty syspropProperty = new ActivationProperty();
+ syspropProperty.setName( "!java.version" );
+
+ syspropActivation.setProperty( syspropProperty );
+
+ syspropActivated.setActivation( syspropActivation );
+
+ Properties props = System.getProperties();
+
+ ProfileManager profileManager = new DefaultProfileManager( getContainer(), props );
+
+ profileManager.addProfile( syspropActivated );
+
+ List active = profileManager.getActiveProfiles();
+
+ assertNotNull( active );
+ assertEquals( 0, active.size() );
+ }
+
+ public void testShouldOverrideAndActivateInactiveProfile()
+ throws Exception
+ {
+ Profile syspropActivated = new Profile();
+ syspropActivated.setId( "syspropActivated" );
+
+ Activation syspropActivation = new Activation();
+
+ ActivationProperty syspropProperty = new ActivationProperty();
+ syspropProperty.setName( "!java.version" );
+
+ syspropActivation.setProperty( syspropProperty );
+
+ syspropActivated.setActivation( syspropActivation );
+
+ Properties props = System.getProperties();
+
+ ProfileManager profileManager = new DefaultProfileManager( getContainer(), props );
+
+ profileManager.addProfile( syspropActivated );
+
+ profileManager.explicitlyActivate( "syspropActivated" );
+
+ List active = profileManager.getActiveProfiles();
+
+ assertNotNull( active );
+ assertEquals( 1, active.size() );
+ assertEquals( "syspropActivated", ( (Profile) active.get( 0 ) ).getId() );
+ }
+
+ public void testShouldOverrideAndDeactivateActiveProfile()
+ throws Exception
+ {
+ Profile syspropActivated = new Profile();
+ syspropActivated.setId( "syspropActivated" );
+
+ Activation syspropActivation = new Activation();
+
+ ActivationProperty syspropProperty = new ActivationProperty();
+ syspropProperty.setName( "java.version" );
+
+ syspropActivation.setProperty( syspropProperty );
+
+ syspropActivated.setActivation( syspropActivation );
+
+ Properties props = System.getProperties();
+
+ ProfileManager profileManager = new DefaultProfileManager( getContainer(), props );
+
+ profileManager.addProfile( syspropActivated );
+
+ profileManager.explicitlyDeactivate( "syspropActivated" );
+
+ List active = profileManager.getActiveProfiles();
+
+ assertNotNull( active );
+ assertEquals( 0, active.size() );
+ }
+/*
+ public void testOsActivationProfile()
+ throws Exception
+ {
+ Profile osActivated = new Profile();
+ osActivated.setId( "os-profile" );
+
+ Activation osActivation = new Activation();
+
+ ActivationOS activationOS = new ActivationOS();
+
+ activationOS.setName( "!dddd" );
+
+ osActivation.setOs( activationOS );
+
+ osActivated.setActivation( osActivation );
+
+ Properties props = System.getProperties();
+ ProfileActivationContext ctx = new ProfileActivationContext( props, false );
+
+ ProfileManager profileManager = new DefaultProfileManager( getContainer(), props );
+
+ profileManager.addProfile( osActivated );
+
+ List active = profileManager.getActiveProfiles( null );
+
+ assertNotNull( active );
+ assertEquals( 1, active.size() );
+ }
+ */
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/AbstractMavenProjectTestCase.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/AbstractMavenProjectTestCase.java
new file mode 100644
index 00000000..7e3f7e6b
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/AbstractMavenProjectTestCase.java
@@ -0,0 +1,185 @@
+package org.apache.maven.project;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.Arrays;
+
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout;
+import org.apache.maven.model.building.ModelBuildingException;
+import org.apache.maven.model.building.ModelProblem;
+import org.apache.maven.repository.RepositorySystem;
+import org.apache.maven.repository.internal.MavenRepositorySystemUtils;
+import org.codehaus.plexus.ContainerConfiguration;
+import org.codehaus.plexus.PlexusConstants;
+import org.codehaus.plexus.PlexusTestCase;
+import org.eclipse.aether.DefaultRepositorySystemSession;
+
+/**
+ * @author Jason van Zyl
+ */
+public abstract class AbstractMavenProjectTestCase
+ extends PlexusTestCase
+{
+ protected ProjectBuilder projectBuilder;
+
+ protected RepositorySystem repositorySystem;
+
+ @Override
+ protected void customizeContainerConfiguration( ContainerConfiguration containerConfiguration )
+ {
+ super.customizeContainerConfiguration( containerConfiguration );
+ containerConfiguration.setAutoWiring( true );
+ containerConfiguration.setClassPathScanning( PlexusConstants.SCANNING_INDEX );
+ }
+
+ protected void setUp()
+ throws Exception
+ {
+ super.setUp();
+
+ if ( getContainer().hasComponent( ProjectBuilder.class, "test" ) )
+ {
+ projectBuilder = lookup( ProjectBuilder.class, "test" );
+ }
+ else
+ {
+ // default over to the main project builder...
+ projectBuilder = lookup( ProjectBuilder.class );
+ }
+
+ repositorySystem = lookup( RepositorySystem.class );
+ }
+
+ @Override
+ protected void tearDown()
+ throws Exception
+ {
+ projectBuilder = null;
+
+ super.tearDown();
+ }
+
+ protected ProjectBuilder getProjectBuilder()
+ {
+ return projectBuilder;
+ }
+
+ @Override
+ protected String getCustomConfigurationName()
+ {
+ String name = AbstractMavenProjectTestCase.class.getName().replace( '.', '/' ) + ".xml";
+ System.out.println( name );
+ return name;
+ }
+
+ // ----------------------------------------------------------------------
+ // Local repository
+ // ----------------------------------------------------------------------
+
+ protected File getLocalRepositoryPath()
+ throws FileNotFoundException, URISyntaxException
+ {
+ File markerFile = getFileForClasspathResource( "local-repo/marker.txt" );
+
+ return markerFile.getAbsoluteFile().getParentFile();
+ }
+
+ protected static File getFileForClasspathResource( String resource )
+ throws FileNotFoundException
+ {
+ ClassLoader cloader = Thread.currentThread().getContextClassLoader();
+
+ URL resourceUrl = cloader.getResource( resource );
+
+ if ( resourceUrl == null )
+ {
+ throw new FileNotFoundException( "Unable to find: " + resource );
+ }
+
+ return new File( URI.create( resourceUrl.toString().replaceAll( " ", "%20" ) ) );
+ }
+
+ protected ArtifactRepository getLocalRepository()
+ throws Exception
+ {
+ ArtifactRepositoryLayout repoLayout = lookup( ArtifactRepositoryLayout.class, "legacy" );
+
+ ArtifactRepository r = repositorySystem.createArtifactRepository( "local", "file://" + getLocalRepositoryPath().getAbsolutePath(), repoLayout, null, null );
+
+ return r;
+ }
+
+ // ----------------------------------------------------------------------
+ // Project building
+ // ----------------------------------------------------------------------
+
+ protected MavenProject getProjectWithDependencies( File pom )
+ throws Exception
+ {
+ ProjectBuildingRequest configuration = new DefaultProjectBuildingRequest();
+ configuration.setLocalRepository( getLocalRepository() );
+ configuration.setRemoteRepositories( Arrays.asList( new ArtifactRepository[] {} ) );
+ configuration.setProcessPlugins( false );
+ configuration.setResolveDependencies( true );
+ initRepoSession( configuration );
+
+ try
+ {
+ return projectBuilder.build( pom, configuration ).getProject();
+ }
+ catch ( Exception e )
+ {
+ Throwable cause = e.getCause();
+ if ( cause instanceof ModelBuildingException )
+ {
+ String message = "In: " + pom + "\n\n";
+ for ( ModelProblem problem : ( (ModelBuildingException) cause ).getProblems() )
+ {
+ message += problem + "\n";
+ }
+ System.out.println( message );
+ fail( message );
+ }
+
+ throw e;
+ }
+ }
+
+ protected MavenProject getProject( File pom )
+ throws Exception
+ {
+ ProjectBuildingRequest configuration = new DefaultProjectBuildingRequest();
+ configuration.setLocalRepository( getLocalRepository() );
+ initRepoSession( configuration );
+
+ return projectBuilder.build( pom, configuration ).getProject();
+ }
+
+ protected void initRepoSession( ProjectBuildingRequest request )
+ {
+ File localRepo = new File( request.getLocalRepository().getBasedir() );
+ DefaultRepositorySystemSession session = MavenRepositorySystemUtils.newSession();
+ session.setLocalRepositoryManager( new LegacyLocalRepositoryManager( localRepo ) );
+ request.setRepositorySession( session );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/ClasspathArtifactResolver.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/ClasspathArtifactResolver.java
new file mode 100644
index 00000000..36eaee8f
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/ClasspathArtifactResolver.java
@@ -0,0 +1,89 @@
+package org.apache.maven.project;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.FileNotFoundException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import org.codehaus.plexus.component.annotations.Component;
+import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.artifact.Artifact;
+import org.eclipse.aether.impl.ArtifactResolver;
+import org.eclipse.aether.resolution.ArtifactRequest;
+import org.eclipse.aether.resolution.ArtifactResolutionException;
+import org.eclipse.aether.resolution.ArtifactResult;
+import org.eclipse.aether.transfer.ArtifactNotFoundException;
+
+/**
+ * @author Benjamin Bentmann
+ */
+@Component( role = ArtifactResolver.class, hint = "classpath" )
+public class ClasspathArtifactResolver
+ implements ArtifactResolver
+{
+
+ public List<ArtifactResult> resolveArtifacts( RepositorySystemSession session,
+ Collection<? extends ArtifactRequest> requests )
+ throws ArtifactResolutionException
+ {
+ List<ArtifactResult> results = new ArrayList<ArtifactResult>();
+
+ for ( ArtifactRequest request : requests )
+ {
+ ArtifactResult result = new ArtifactResult( request );
+ results.add( result );
+
+ Artifact artifact = request.getArtifact();
+ if ( "maven-test".equals( artifact.getGroupId() ) )
+ {
+ String scope = artifact.getArtifactId().substring( "scope-".length() );
+
+ try
+ {
+ artifact =
+ artifact.setFile( ProjectClasspathTest.getFileForClasspathResource( ProjectClasspathTest.dir
+ + "transitive-" + scope + "-dep.xml" ) );
+ result.setArtifact( artifact );
+ }
+ catch ( FileNotFoundException e )
+ {
+ throw new IllegalStateException( "Missing test POM for " + artifact );
+ }
+ }
+ else
+ {
+ result.addException( new ArtifactNotFoundException( artifact, null ) );
+ throw new ArtifactResolutionException( results );
+ }
+ }
+
+ return results;
+ }
+
+ public ArtifactResult resolveArtifact( RepositorySystemSession session, ArtifactRequest request )
+ throws ArtifactResolutionException
+ {
+ return resolveArtifacts( session, Collections.singleton( request ) ).get( 0 );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/EmptyLifecycleExecutor.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/EmptyLifecycleExecutor.java
new file mode 100644
index 00000000..024917de
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/EmptyLifecycleExecutor.java
@@ -0,0 +1,110 @@
+package org.apache.maven.project;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Collections;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.lifecycle.DefaultLifecycles;
+import org.apache.maven.lifecycle.LifecycleExecutor;
+import org.apache.maven.lifecycle.MavenExecutionPlan;
+import org.apache.maven.model.Plugin;
+import org.apache.maven.model.PluginExecution;
+import org.apache.maven.plugin.MojoExecution;
+
+/**
+ * A stub implementation that assumes an empty lifecycle to bypass interaction with the plugin manager and to avoid
+ * plugin artifact resolution from repositories.
+ *
+ * @author Benjamin Bentmann
+ */
+public class EmptyLifecycleExecutor
+ implements LifecycleExecutor
+{
+
+ public MavenExecutionPlan calculateExecutionPlan( MavenSession session, String... tasks )
+ {
+ return new MavenExecutionPlan( null, new DefaultLifecycles() );
+ }
+
+ public MavenExecutionPlan calculateExecutionPlan( MavenSession session, boolean setup, String... tasks )
+ {
+ return new MavenExecutionPlan( null, new DefaultLifecycles() );
+ }
+
+ public void execute( MavenSession session )
+ {
+ }
+
+ public Set<Plugin> getPluginsBoundByDefaultToAllLifecycles( String packaging )
+ {
+ Set<Plugin> plugins;
+
+ // NOTE: The upper-case packaging name is intentional, that's a special hinting mode used for certain tests
+ if ( "JAR".equals( packaging ) )
+ {
+ plugins = new LinkedHashSet<Plugin>();
+
+ plugins.add( newPlugin( "maven-compiler-plugin", "compile", "testCompile" ) );
+ plugins.add( newPlugin( "maven-resources-plugin", "resources", "testResources" ) );
+ plugins.add( newPlugin( "maven-surefire-plugin", "test" ) );
+ plugins.add( newPlugin( "maven-jar-plugin", "jar" ) );
+ plugins.add( newPlugin( "maven-install-plugin", "install" ) );
+ plugins.add( newPlugin( "maven-deploy-plugin", "deploy" ) );
+ }
+ else
+ {
+ plugins = Collections.emptySet();
+ }
+
+ return plugins;
+ }
+
+ private Plugin newPlugin( String artifactId, String... goals )
+ {
+ Plugin plugin = new Plugin();
+
+ plugin.setGroupId( "org.apache.maven.plugins" );
+ plugin.setArtifactId( artifactId );
+
+ for ( String goal : goals )
+ {
+ PluginExecution pluginExecution = new PluginExecution();
+ pluginExecution.setId( "default-" + goal );
+ pluginExecution.addGoal( goal );
+ plugin.addExecution( pluginExecution );
+ }
+
+ return plugin;
+ }
+
+ public void calculateForkedExecutions( MojoExecution mojoExecution, MavenSession session )
+ {
+ }
+
+ public List<MavenProject> executeForkedExecutions( MojoExecution mojoExecution, MavenSession session )
+ {
+ return Collections.emptyList();
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/EmptyLifecyclePluginAnalyzer.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/EmptyLifecyclePluginAnalyzer.java
new file mode 100644
index 00000000..5a78a7e5
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/EmptyLifecyclePluginAnalyzer.java
@@ -0,0 +1,78 @@
+package org.apache.maven.project;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Collections;
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+import org.apache.maven.lifecycle.LifeCyclePluginAnalyzer;
+import org.apache.maven.model.Plugin;
+import org.apache.maven.model.PluginExecution;
+
+/**
+ * @author Benjamin Bentmann
+ */
+public class EmptyLifecyclePluginAnalyzer
+ implements LifeCyclePluginAnalyzer
+{
+ public Set<Plugin> getPluginsBoundByDefaultToAllLifecycles( String packaging )
+ {
+ Set<Plugin> plugins;
+
+ // NOTE: The upper-case packaging name is intentional, that's a special hinting mode used for certain tests
+ if ( "JAR".equals( packaging ) )
+ {
+ plugins = new LinkedHashSet<Plugin>();
+
+ plugins.add( newPlugin( "maven-compiler-plugin", "compile", "testCompile" ) );
+ plugins.add( newPlugin( "maven-resources-plugin", "resources", "testResources" ) );
+ plugins.add( newPlugin( "maven-surefire-plugin", "test" ) );
+ plugins.add( newPlugin( "maven-jar-plugin", "jar" ) );
+ plugins.add( newPlugin( "maven-install-plugin", "install" ) );
+ plugins.add( newPlugin( "maven-deploy-plugin", "deploy" ) );
+ }
+ else
+ {
+ plugins = Collections.emptySet();
+ }
+
+ return plugins;
+ }
+
+ private Plugin newPlugin( String artifactId, String... goals )
+ {
+ Plugin plugin = new Plugin();
+
+ plugin.setGroupId( "org.apache.maven.plugins" );
+ plugin.setArtifactId( artifactId );
+
+ for ( String goal : goals )
+ {
+ PluginExecution pluginExecution = new PluginExecution();
+ pluginExecution.setId( "default-" + goal );
+ pluginExecution.addGoal( goal );
+ plugin.addExecution( pluginExecution );
+ }
+
+ return plugin;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/LegacyLocalRepositoryManager.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/LegacyLocalRepositoryManager.java
new file mode 100644
index 00000000..52fdd804
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/LegacyLocalRepositoryManager.java
@@ -0,0 +1,192 @@
+package org.apache.maven.project;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+
+import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.artifact.Artifact;
+import org.eclipse.aether.metadata.Metadata;
+import org.eclipse.aether.repository.LocalArtifactRegistration;
+import org.eclipse.aether.repository.LocalArtifactRequest;
+import org.eclipse.aether.repository.LocalArtifactResult;
+import org.eclipse.aether.repository.LocalMetadataRegistration;
+import org.eclipse.aether.repository.LocalMetadataRequest;
+import org.eclipse.aether.repository.LocalMetadataResult;
+import org.eclipse.aether.repository.LocalRepository;
+import org.eclipse.aether.repository.LocalRepositoryManager;
+import org.eclipse.aether.repository.RemoteRepository;
+
+/**
+ * @author Benjamin Bentmann
+ */
+public class LegacyLocalRepositoryManager
+ implements LocalRepositoryManager
+{
+
+ private final LocalRepository repository;
+
+ public LegacyLocalRepositoryManager( File basedir )
+ {
+ this.repository = new LocalRepository( basedir.getAbsoluteFile(), "legacy" );
+ }
+
+ public LocalRepository getRepository()
+ {
+ return repository;
+ }
+
+ public String getPathForLocalArtifact( Artifact artifact )
+ {
+ StringBuilder path = new StringBuilder( 128 );
+
+ path.append( artifact.getGroupId() ).append( '/' );
+
+ path.append( artifact.getExtension() ).append( 's' ).append( '/' );
+
+ path.append( artifact.getArtifactId() ).append( '-' ).append( artifact.getVersion() );
+
+ if ( artifact.getClassifier().length() > 0 )
+ {
+ path.append( '-' ).append( artifact.getClassifier() );
+ }
+
+ path.append( '.' ).append( artifact.getExtension() );
+
+ return path.toString();
+ }
+
+ public String getPathForRemoteArtifact( Artifact artifact, RemoteRepository repository, String context )
+ {
+ return getPathForLocalArtifact( artifact );
+ }
+
+ public String getPathForLocalMetadata( Metadata metadata )
+ {
+ return getPath( metadata, "local" );
+ }
+
+ public String getPathForRemoteMetadata( Metadata metadata, RemoteRepository repository, String context )
+ {
+ return getPath( metadata, getRepositoryKey( repository, context ) );
+ }
+
+ String getRepositoryKey( RemoteRepository repository, String context )
+ {
+ return repository.getId();
+ }
+
+ private String getPath( Metadata metadata, String repositoryKey )
+ {
+ StringBuilder path = new StringBuilder( 128 );
+
+ if ( metadata.getGroupId().length() > 0 )
+ {
+ path.append( metadata.getGroupId().replace( '.', '/' ) ).append( '/' );
+
+ if ( metadata.getArtifactId().length() > 0 )
+ {
+ path.append( metadata.getArtifactId() ).append( '/' );
+
+ if ( metadata.getVersion().length() > 0 )
+ {
+ path.append( metadata.getVersion() ).append( '/' );
+ }
+ }
+ }
+
+ path.append( insertRepositoryKey( metadata.getType(), repositoryKey ) );
+
+ return path.toString();
+ }
+
+ private String insertRepositoryKey( String filename, String repositoryKey )
+ {
+ String result;
+ int idx = filename.indexOf( '.' );
+ if ( idx < 0 )
+ {
+ result = filename + '-' + repositoryKey;
+ }
+ else
+ {
+ result = filename.substring( 0, idx ) + '-' + repositoryKey + filename.substring( idx );
+ }
+ return result;
+ }
+
+ public LocalArtifactResult find( RepositorySystemSession session, LocalArtifactRequest request )
+ {
+ String path = getPathForLocalArtifact( request.getArtifact() );
+ File file = new File( getRepository().getBasedir(), path );
+
+ LocalArtifactResult result = new LocalArtifactResult( request );
+ if ( file.isFile() )
+ {
+ result.setFile( file );
+ result.setAvailable( true );
+ }
+
+ return result;
+ }
+
+ public void add( RepositorySystemSession session, LocalArtifactRegistration request )
+ {
+ // noop
+ }
+
+ public LocalMetadataResult find( RepositorySystemSession session, LocalMetadataRequest request )
+ {
+ LocalMetadataResult result = new LocalMetadataResult( request );
+
+ String path;
+
+ Metadata metadata = request.getMetadata();
+ String context = request.getContext();
+ RemoteRepository remote = request.getRepository();
+
+ if ( remote != null )
+ {
+ path = getPathForRemoteMetadata( metadata, remote, context );
+ }
+ else
+ {
+ path = getPathForLocalMetadata( metadata );
+ }
+
+ File file = new File( getRepository().getBasedir(), path );
+ if ( file.isFile() )
+ {
+ result.setFile( file );
+ }
+
+ return result;
+ }
+
+ public void add( RepositorySystemSession session, LocalMetadataRegistration request )
+ {
+ // noop
+ }
+
+ public String toString()
+ {
+ return String.valueOf( getRepository() );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/ModelUtilsTest.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/ModelUtilsTest.java
new file mode 100644
index 00000000..6c3df9a0
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/ModelUtilsTest.java
@@ -0,0 +1,616 @@
+package org.apache.maven.project;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import junit.framework.TestCase;
+
+import org.apache.maven.model.Build;
+import org.apache.maven.model.Dependency;
+import org.apache.maven.model.Plugin;
+import org.apache.maven.model.PluginContainer;
+import org.apache.maven.model.PluginExecution;
+import org.codehaus.plexus.util.xml.Xpp3Dom;
+import org.codehaus.plexus.util.xml.Xpp3DomBuilder;
+import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
+
+public class ModelUtilsTest
+ extends TestCase
+{
+
+ public void testShouldUseMainPluginDependencyVersionOverManagedDepVersion()
+ {
+ Plugin mgtPlugin = createPlugin( "group", "artifact", "1", Collections.EMPTY_MAP );
+ Dependency mgtDep = createDependency( "g", "a", "2" );
+ mgtPlugin.addDependency( mgtDep );
+
+ Plugin plugin = createPlugin( "group", "artifact", "1", Collections.EMPTY_MAP );
+ Dependency dep = createDependency( "g", "a", "1" );
+ plugin.addDependency( dep );
+
+ ModelUtils.mergePluginDefinitions( plugin, mgtPlugin, false );
+
+ assertEquals( dep.getVersion(), plugin.getDependencies().get( 0 ).getVersion() );
+ }
+
+ private Dependency createDependency( String gid,
+ String aid,
+ String ver )
+ {
+ Dependency dep = new Dependency();
+ dep.setGroupId( gid );
+ dep.setArtifactId( aid );
+ dep.setVersion( ver );
+
+ return dep;
+ }
+
+ public void testShouldNotInheritPluginWithInheritanceSetToFalse()
+ {
+ PluginContainer parent = new PluginContainer();
+
+ Plugin parentPlugin = createPlugin( "group", "artifact", "1.0", Collections.EMPTY_MAP );
+ parentPlugin.setInherited( "false" );
+
+ parent.addPlugin( parentPlugin );
+
+ PluginContainer child = new PluginContainer();
+
+ child.addPlugin( createPlugin( "group3", "artifact3", "1.0", Collections.EMPTY_MAP ) );
+
+ ModelUtils.mergePluginLists( child, parent, true );
+
+ List results = child.getPlugins();
+
+ assertEquals( 1, results.size() );
+
+ Plugin result1 = (Plugin) results.get( 0 );
+ assertEquals( "group3", result1.getGroupId() );
+ assertEquals( "artifact3", result1.getArtifactId() );
+ }
+
+ /**
+ * Test that this is the resulting ordering of plugins after merging:
+ *
+ * Given:
+ *
+ * parent: X -> A -> B -> D -> E
+ * child: Y -> A -> C -> D -> F
+ *
+ * Result:
+ *
+ * X -> Y -> A -> B -> C -> D -> E -> F
+ */
+ public void testShouldPreserveChildOrderingOfPluginsAfterParentMerge()
+ {
+ PluginContainer parent = new PluginContainer();
+
+ parent.addPlugin( createPlugin( "group", "artifact", "1.0", Collections.EMPTY_MAP ) );
+ parent.addPlugin( createPlugin( "group2", "artifact2", "1.0", Collections.singletonMap( "key", "value" ) ) );
+
+ PluginContainer child = new PluginContainer();
+
+ child.addPlugin( createPlugin( "group3", "artifact3", "1.0", Collections.EMPTY_MAP ) );
+ child.addPlugin( createPlugin( "group2", "artifact2", "1.0", Collections.singletonMap( "key2", "value2" ) ) );
+
+ ModelUtils.mergePluginLists( child, parent, true );
+
+ List results = child.getPlugins();
+
+ assertEquals( 3, results.size() );
+
+ Plugin result1 = (Plugin) results.get( 0 );
+
+ assertEquals( "group", result1.getGroupId() );
+ assertEquals( "artifact", result1.getArtifactId() );
+
+ Plugin result2 = (Plugin) results.get( 1 );
+
+ assertEquals( "group3", result2.getGroupId() );
+ assertEquals( "artifact3", result2.getArtifactId() );
+
+ Plugin result3 = (Plugin) results.get( 2 );
+
+ assertEquals( "group2", result3.getGroupId() );
+ assertEquals( "artifact2", result3.getArtifactId() );
+
+ Xpp3Dom result3Config = (Xpp3Dom) result3.getConfiguration();
+
+ assertNotNull( result3Config );
+
+ assertEquals( "value", result3Config.getChild( "key" ).getValue() );
+ assertEquals( "value2", result3Config.getChild( "key2" ).getValue() );
+ }
+
+ private Plugin createPlugin( String groupId, String artifactId, String version, Map configuration )
+ {
+ Plugin plugin = new Plugin();
+ plugin.setGroupId( groupId );
+ plugin.setArtifactId( artifactId );
+ plugin.setVersion( version );
+
+ Xpp3Dom config = new Xpp3Dom( "configuration" );
+
+ if( configuration != null )
+ {
+ for ( Object o : configuration.entrySet() )
+ {
+ Map.Entry entry = (Map.Entry) o;
+
+ Xpp3Dom param = new Xpp3Dom( String.valueOf( entry.getKey() ) );
+ param.setValue( String.valueOf( entry.getValue() ) );
+
+ config.addChild( param );
+ }
+ }
+
+ plugin.setConfiguration( config );
+
+ return plugin;
+ }
+
+ public void testShouldInheritOnePluginWithExecution()
+ {
+ Plugin parent = new Plugin();
+ parent.setArtifactId( "testArtifact" );
+ parent.setGroupId( "testGroup" );
+ parent.setVersion( "1.0" );
+
+ PluginExecution parentExecution = new PluginExecution();
+ parentExecution.setId( "testExecution" );
+
+ parent.addExecution( parentExecution );
+
+ Plugin child = new Plugin();
+ child.setArtifactId( "testArtifact" );
+ child.setGroupId( "testGroup" );
+ child.setVersion( "1.0" );
+
+ ModelUtils.mergePluginDefinitions( child, parent, false );
+
+ assertEquals( 1, child.getExecutions().size() );
+ }
+
+ public void testShouldMergeInheritedPluginHavingExecutionWithLocalPlugin()
+ {
+ Plugin parent = new Plugin();
+ parent.setArtifactId( "testArtifact" );
+ parent.setGroupId( "testGroup" );
+ parent.setVersion( "1.0" );
+
+ PluginExecution parentExecution = new PluginExecution();
+ parentExecution.setId( "testExecution" );
+
+ parent.addExecution( parentExecution );
+
+ Plugin child = new Plugin();
+ child.setArtifactId( "testArtifact" );
+ child.setGroupId( "testGroup" );
+ child.setVersion( "1.0" );
+
+ PluginExecution childExecution = new PluginExecution();
+ childExecution.setId( "testExecution2" );
+
+ child.addExecution( childExecution );
+
+ ModelUtils.mergePluginDefinitions( child, parent, false );
+
+ assertEquals( 2, child.getExecutions().size() );
+ }
+
+ public void testShouldMergeOnePluginWithInheritExecutionWithoutDuplicatingPluginInList()
+ {
+ Plugin parent = new Plugin();
+ parent.setArtifactId( "testArtifact" );
+ parent.setGroupId( "testGroup" );
+ parent.setVersion( "1.0" );
+
+ PluginExecution parentExecution = new PluginExecution();
+ parentExecution.setId( "testExecution" );
+
+ parent.addExecution( parentExecution );
+
+ Build parentContainer = new Build();
+ parentContainer.addPlugin( parent );
+
+ Plugin child = new Plugin();
+ child.setArtifactId( "testArtifact" );
+ child.setGroupId( "testGroup" );
+ child.setVersion( "1.0" );
+
+ Build childContainer = new Build();
+ childContainer.addPlugin( child );
+
+ ModelUtils.mergePluginLists( childContainer, parentContainer, true );
+
+ List plugins = childContainer.getPlugins();
+
+ assertEquals( 1, plugins.size() );
+
+ Plugin plugin = (Plugin) plugins.get( 0 );
+
+ assertEquals( 1, plugin.getExecutions().size() );
+ }
+
+ public void testShouldMergePluginWithDifferentExecutionFromParentWithoutDuplicatingPluginInList()
+ {
+ Plugin parent = new Plugin();
+ parent.setArtifactId( "testArtifact" );
+ parent.setGroupId( "testGroup" );
+ parent.setVersion( "1.0" );
+
+ PluginExecution parentExecution = new PluginExecution();
+ parentExecution.setId( "testExecution" );
+
+ parent.addExecution( parentExecution );
+
+ Build parentContainer = new Build();
+ parentContainer.addPlugin( parent );
+
+ Plugin child = new Plugin();
+ child.setArtifactId( "testArtifact" );
+ child.setGroupId( "testGroup" );
+ child.setVersion( "1.0" );
+
+ PluginExecution childExecution = new PluginExecution();
+ childExecution.setId( "testExecution2" );
+
+ child.addExecution( childExecution );
+
+
+ Build childContainer = new Build();
+ childContainer.addPlugin( child );
+
+ ModelUtils.mergePluginLists( childContainer, parentContainer, true );
+
+ List plugins = childContainer.getPlugins();
+
+ assertEquals( 1, plugins.size() );
+
+ Plugin plugin = (Plugin) plugins.get( 0 );
+
+ assertEquals( 2, plugin.getExecutions().size() );
+ }
+
+ public void testShouldNOTMergeInheritedPluginHavingInheritEqualFalse()
+ {
+ Plugin parent = new Plugin();
+ parent.setArtifactId( "testArtifact" );
+ parent.setGroupId( "testGroup" );
+ parent.setVersion( "1.0" );
+ parent.setInherited( "false" );
+
+ PluginExecution parentExecution = new PluginExecution();
+ parentExecution.setId( "testExecution" );
+
+ parent.addExecution( parentExecution );
+
+ Plugin child = new Plugin();
+ child.setArtifactId( "testArtifact" );
+ child.setGroupId( "testGroup" );
+ child.setVersion( "1.0" );
+
+ ModelUtils.mergePluginDefinitions( child, parent, true );
+
+ assertEquals( 0, child.getExecutions().size() );
+ }
+
+ /**
+ * Verifies MNG-1499: The order of the merged list should be the plugins specified by the parent followed by the
+ * child list.
+ */
+ public void testShouldKeepOriginalPluginOrdering()
+ {
+ Plugin parentPlugin1 = new Plugin();
+ parentPlugin1.setArtifactId( "testArtifact" );
+ parentPlugin1.setGroupId( "zzz" ); // This will put this plugin last in the sorted map
+ parentPlugin1.setVersion( "1.0" );
+
+ PluginExecution parentExecution1 = new PluginExecution();
+ parentExecution1.setId( "testExecution" );
+
+ parentPlugin1.addExecution( parentExecution1 );
+
+ Plugin parentPlugin2 = new Plugin();
+ parentPlugin2.setArtifactId( "testArtifact" );
+ parentPlugin2.setGroupId( "yyy" );
+ parentPlugin2.setVersion( "1.0" );
+
+ PluginExecution parentExecution2 = new PluginExecution();
+ parentExecution2.setId( "testExecution" );
+
+ parentPlugin2.addExecution( parentExecution2 );
+
+ PluginContainer parentContainer = new PluginContainer();
+ parentContainer.addPlugin(parentPlugin1);
+ parentContainer.addPlugin(parentPlugin2);
+
+
+ Plugin childPlugin1 = new Plugin();
+ childPlugin1.setArtifactId( "testArtifact" );
+ childPlugin1.setGroupId( "bbb" );
+ childPlugin1.setVersion( "1.0" );
+
+ PluginExecution childExecution1 = new PluginExecution();
+ childExecution1.setId( "testExecution" );
+
+ childPlugin1.addExecution( childExecution1 );
+
+ Plugin childPlugin2 = new Plugin();
+ childPlugin2.setArtifactId( "testArtifact" );
+ childPlugin2.setGroupId( "aaa" );
+ childPlugin2.setVersion( "1.0" );
+
+ PluginExecution childExecution2 = new PluginExecution();
+ childExecution2.setId( "testExecution" );
+
+ childPlugin2.addExecution( childExecution2 );
+
+ PluginContainer childContainer = new PluginContainer();
+ childContainer.addPlugin(childPlugin1);
+ childContainer.addPlugin(childPlugin2);
+
+
+ ModelUtils.mergePluginLists(childContainer, parentContainer, true);
+
+ assertEquals( 4, childContainer.getPlugins().size() );
+ assertSame(parentPlugin1, childContainer.getPlugins().get(0));
+ assertSame(parentPlugin2, childContainer.getPlugins().get(1));
+ assertSame(childPlugin1, childContainer.getPlugins().get(2));
+ assertSame(childPlugin2, childContainer.getPlugins().get(3));
+ }
+
+ /**
+ * Verifies MNG-1499: The ordering of plugin executions should also be in the specified order.
+ */
+ public void testShouldKeepOriginalPluginExecutionOrdering()
+ {
+ Plugin parent = new Plugin();
+ parent.setArtifactId( "testArtifact" );
+ parent.setGroupId( "testGroup" );
+ parent.setVersion( "1.0" );
+
+ PluginExecution parentExecution1 = new PluginExecution();
+ parentExecution1.setId( "zzz" ); // Will show up last in the sorted map
+ PluginExecution parentExecution2 = new PluginExecution();
+ parentExecution2.setId( "yyy" ); // Will show up last in the sorted map
+
+ parent.addExecution( parentExecution1 );
+ parent.addExecution( parentExecution2 );
+
+ // this block verifies MNG-1703
+ Dependency dep = new Dependency();
+ dep.setGroupId( "depGroupId" );
+ dep.setArtifactId( "depArtifactId" );
+ dep.setVersion( "depVersion" );
+ parent.setDependencies( Collections.singletonList( dep ) );
+
+ Plugin child = new Plugin();
+ child.setArtifactId( "testArtifact" );
+ child.setGroupId( "testGroup" );
+ child.setVersion( "1.0" );
+
+ PluginExecution childExecution1 = new PluginExecution();
+ childExecution1.setId( "bbb" );
+ PluginExecution childExecution2 = new PluginExecution();
+ childExecution2.setId( "aaa" );
+
+ child.addExecution( childExecution1 );
+ child.addExecution( childExecution2 );
+
+ ModelUtils.mergePluginDefinitions( child, parent, false );
+
+ assertEquals( 4, child.getExecutions().size() );
+ assertSame(parentExecution1, child.getExecutions().get(0));
+ assertSame(parentExecution2, child.getExecutions().get(1));
+ assertSame(childExecution1, child.getExecutions().get(2));
+ assertSame(childExecution2, child.getExecutions().get(3));
+
+ // this block prevents MNG-1703
+ assertEquals( 1, child.getDependencies().size() );
+ Dependency dep2 = child.getDependencies().get( 0 );
+ assertEquals( dep.getManagementKey(), dep2.getManagementKey() );
+ }
+
+ public void testShouldOverwritePluginConfigurationSubItemsByDefault()
+ throws XmlPullParserException, IOException
+ {
+ String parentConfigStr = "<configuration><items><item>one</item><item>two</item></items></configuration>";
+ Xpp3Dom parentConfig = Xpp3DomBuilder.build( new StringReader( parentConfigStr ) );
+
+ Plugin parentPlugin = createPlugin( "group", "artifact", "1", null );
+ parentPlugin.setConfiguration( parentConfig );
+
+ String childConfigStr = "<configuration><items><item>three</item></items></configuration>";
+ Xpp3Dom childConfig = Xpp3DomBuilder.build( new StringReader( childConfigStr ) );
+
+ Plugin childPlugin = createPlugin( "group", "artifact", "1", null );
+ childPlugin.setConfiguration( childConfig );
+
+ ModelUtils.mergePluginDefinitions( childPlugin, parentPlugin, true );
+
+ Xpp3Dom result = (Xpp3Dom) childPlugin.getConfiguration();
+ Xpp3Dom items = result.getChild( "items" );
+
+ assertEquals( 1, items.getChildCount() );
+
+ Xpp3Dom item = items.getChild( 0 );
+ assertEquals( "three", item.getValue() );
+ }
+
+ public void testShouldMergePluginConfigurationSubItemsWithMergeAttributeSet()
+ throws XmlPullParserException, IOException
+ {
+ String parentConfigStr = "<configuration><items><item>one</item><item>two</item></items></configuration>";
+ Xpp3Dom parentConfig = Xpp3DomBuilder.build( new StringReader( parentConfigStr ) );
+
+ Plugin parentPlugin = createPlugin( "group", "artifact", "1", null );
+ parentPlugin.setConfiguration( parentConfig );
+
+ String childConfigStr = "<configuration><items combine.children=\"append\"><item>three</item></items></configuration>";
+ Xpp3Dom childConfig = Xpp3DomBuilder.build( new StringReader( childConfigStr ) );
+
+ Plugin childPlugin = createPlugin( "group", "artifact", "1", null );
+ childPlugin.setConfiguration( childConfig );
+
+ ModelUtils.mergePluginDefinitions( childPlugin, parentPlugin, true );
+
+ Xpp3Dom result = (Xpp3Dom) childPlugin.getConfiguration();
+ Xpp3Dom items = result.getChild( "items" );
+
+ assertEquals( 3, items.getChildCount() );
+
+ Xpp3Dom[] item = items.getChildren();
+
+ List<String> actual = Arrays.asList( item[0].getValue(), item[1].getValue(), item[2].getValue() );
+ List<String> expected = Arrays.asList( "one", "two", "three" );
+ Collections.sort( actual );
+ Collections.sort( expected );
+ assertEquals( expected, actual );
+ }
+
+ public void testShouldNotMergePluginExecutionWhenExecInheritedIsFalseAndTreatAsInheritanceIsTrue()
+ {
+ String gid = "group";
+ String aid = "artifact";
+ String ver = "1";
+
+ PluginContainer parent = new PluginContainer();
+ Plugin pParent = createPlugin( gid, aid, ver, Collections.EMPTY_MAP );
+
+ pParent.setInherited( Boolean.toString( true ) );
+
+ PluginExecution eParent = new PluginExecution();
+
+ String testId = "test";
+
+ eParent.setId( testId );
+ eParent.addGoal( "run" );
+ eParent.setPhase( "initialize" );
+ eParent.setInherited( Boolean.toString( false ) );
+
+ pParent.addExecution( eParent );
+ parent.addPlugin( pParent );
+
+ PluginContainer child = new PluginContainer();
+ Plugin pChild = createPlugin( gid, aid, ver, Collections.EMPTY_MAP );
+ PluginExecution eChild = new PluginExecution();
+
+ eChild.setId( "child-specified" );
+ eChild.addGoal( "child" );
+ eChild.setPhase( "compile" );
+
+ pChild.addExecution( eChild );
+ child.addPlugin( pChild );
+
+ ModelUtils.mergePluginDefinitions( pChild, pParent, true );
+
+ Map executionMap = pChild.getExecutionsAsMap();
+ assertNull( "test execution should not be inherited from parent.", executionMap.get( testId ) );
+ }
+
+ public void testShouldNotMergePluginExecutionWhenPluginInheritedIsFalseAndTreatAsInheritanceIsTrue()
+ {
+ String gid = "group";
+ String aid = "artifact";
+ String ver = "1";
+
+ PluginContainer parent = new PluginContainer();
+ Plugin pParent = createPlugin( gid, aid, ver, Collections.EMPTY_MAP );
+
+ pParent.setInherited( Boolean.toString( false ) );
+
+ PluginExecution eParent = new PluginExecution();
+
+ String testId = "test";
+
+ eParent.setId( testId );
+ eParent.addGoal( "run" );
+ eParent.setPhase( "initialize" );
+ eParent.setInherited( Boolean.toString( true ) );
+
+ pParent.addExecution( eParent );
+ parent.addPlugin( pParent );
+
+ PluginContainer child = new PluginContainer();
+ Plugin pChild = createPlugin( gid, aid, ver, Collections.EMPTY_MAP );
+ PluginExecution eChild = new PluginExecution();
+
+ eChild.setId( "child-specified" );
+ eChild.addGoal( "child" );
+ eChild.setPhase( "compile" );
+
+ pChild.addExecution( eChild );
+ child.addPlugin( pChild );
+
+ ModelUtils.mergePluginDefinitions( pChild, pParent, true );
+
+ Map executionMap = pChild.getExecutionsAsMap();
+ assertNull( "test execution should not be inherited from parent.", executionMap.get( testId ) );
+ }
+
+ public void testShouldMergePluginExecutionWhenExecInheritedIsTrueAndTreatAsInheritanceIsTrue()
+ {
+ String gid = "group";
+ String aid = "artifact";
+ String ver = "1";
+
+ PluginContainer parent = new PluginContainer();
+ Plugin pParent = createPlugin( gid, aid, ver, Collections.EMPTY_MAP );
+
+ pParent.setInherited( Boolean.toString( true ) );
+
+ PluginExecution eParent = new PluginExecution();
+
+ String testId = "test";
+
+ eParent.setId( testId );
+ eParent.addGoal( "run" );
+ eParent.setPhase( "initialize" );
+ eParent.setInherited( Boolean.toString( true ) );
+
+ pParent.addExecution( eParent );
+ parent.addPlugin( pParent );
+
+ PluginContainer child = new PluginContainer();
+ Plugin pChild = createPlugin( gid, aid, ver, Collections.EMPTY_MAP );
+ PluginExecution eChild = new PluginExecution();
+
+ eChild.setId( "child-specified" );
+ eChild.addGoal( "child" );
+ eChild.setPhase( "compile" );
+
+ pChild.addExecution( eChild );
+ child.addPlugin( pChild );
+
+ ModelUtils.mergePluginDefinitions( pChild, pParent, true );
+
+ Map executionMap = pChild.getExecutionsAsMap();
+ assertNotNull( "test execution should be inherited from parent.", executionMap.get( testId ) );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/ProjectClasspathTest.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/ProjectClasspathTest.java
new file mode 100644
index 00000000..d9e7beb2
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/ProjectClasspathTest.java
@@ -0,0 +1,149 @@
+package org.apache.maven.project;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.util.Iterator;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.repository.RepositorySystem;
+import org.apache.maven.repository.internal.DefaultArtifactDescriptorReader;
+import org.eclipse.aether.impl.ArtifactDescriptorReader;
+import org.eclipse.aether.impl.ArtifactResolver;
+
+public class ProjectClasspathTest
+ extends AbstractMavenProjectTestCase
+{
+ static final String dir = "projects/scope/";
+
+ public void setUp()
+ throws Exception
+ {
+ ArtifactResolver resolver = lookup( ArtifactResolver.class, "classpath" );
+ DefaultArtifactDescriptorReader pomReader = (DefaultArtifactDescriptorReader)lookup(ArtifactDescriptorReader.class);
+ pomReader.setArtifactResolver( resolver );
+
+ projectBuilder = lookup( ProjectBuilder.class, "classpath" );
+
+ // the metadata source looks up the default impl, so we have to trick it
+ getContainer().addComponent( projectBuilder, ProjectBuilder.class, "default" );
+
+ repositorySystem = lookup( RepositorySystem.class );
+ }
+
+ @Override
+ protected String getCustomConfigurationName()
+ {
+ return null;
+ }
+
+ public void testProjectClasspath()
+ throws Exception
+ {
+ File f = getFileForClasspathResource( dir + "project-with-scoped-dependencies.xml" );
+
+ MavenProject project = getProjectWithDependencies( f );
+
+ Artifact artifact;
+
+ assertNotNull( "Test project can't be null!", project );
+
+ checkArtifactIdScope( project, "provided", "provided" );
+ checkArtifactIdScope( project, "test", "test" );
+ checkArtifactIdScope( project, "compile", "compile" );
+ checkArtifactIdScope( project, "runtime", "runtime" );
+ checkArtifactIdScope( project, "default", "compile" );
+
+ // check all transitive deps of a test dependency are test, except test and provided which is skipped
+ artifact = getArtifact( project, "maven-test-test", "scope-provided" );
+ assertNull( "Check no provided dependencies are transitive", artifact );
+ artifact = getArtifact( project, "maven-test-test", "scope-test" );
+ assertNull( "Check no test dependencies are transitive", artifact );
+
+ artifact = getArtifact( project, "maven-test-test", "scope-compile" );
+ assertNotNull( artifact );
+
+ System.out.println( "a = " + artifact );
+ System.out.println( "b = " + artifact.getScope() );
+ assertEquals( "Check scope", "test", artifact.getScope() );
+ artifact = getArtifact( project, "maven-test-test", "scope-default" );
+ assertEquals( "Check scope", "test", artifact.getScope() );
+ artifact = getArtifact( project, "maven-test-test", "scope-runtime" );
+ assertEquals( "Check scope", "test", artifact.getScope() );
+
+ // check all transitive deps of a provided dependency are provided scope, except for test
+ checkGroupIdScope( project, "provided", "maven-test-provided" );
+ artifact = getArtifact( project, "maven-test-provided", "scope-runtime" );
+ assertEquals( "Check scope", "provided", artifact.getScope() );
+
+ // check all transitive deps of a runtime dependency are runtime scope, except for test
+ checkGroupIdScope( project, "runtime", "maven-test-runtime" );
+ artifact = getArtifact( project, "maven-test-runtime", "scope-runtime" );
+ assertEquals( "Check scope", "runtime", artifact.getScope() );
+
+ // check all transitive deps of a compile dependency are compile scope, except for runtime and test
+ checkGroupIdScope( project, "compile", "maven-test-compile" );
+ artifact = getArtifact( project, "maven-test-compile", "scope-runtime" );
+ assertEquals( "Check scope", "runtime", artifact.getScope() );
+
+ // check all transitive deps of a default dependency are compile scope, except for runtime and test
+ checkGroupIdScope( project, "compile", "maven-test-default" );
+ artifact = getArtifact( project, "maven-test-default", "scope-runtime" );
+ assertEquals( "Check scope", "runtime", artifact.getScope() );
+ }
+
+ private void checkGroupIdScope( MavenProject project, String scopeValue, String groupId )
+ {
+ Artifact artifact;
+ artifact = getArtifact( project, groupId, "scope-compile" );
+ assertEquals( "Check scope", scopeValue, artifact.getScope() );
+ artifact = getArtifact( project, groupId, "scope-test" );
+ assertNull( "Check test dependency is not transitive", artifact );
+ artifact = getArtifact( project, groupId, "scope-provided" );
+ assertNull( "Check provided dependency is not transitive", artifact );
+ artifact = getArtifact( project, groupId, "scope-default" );
+ assertEquals( "Check scope", scopeValue, artifact.getScope() );
+ }
+
+ private void checkArtifactIdScope( MavenProject project, String scope, String scopeValue )
+ {
+ String artifactId = "scope-" + scope;
+ Artifact artifact = getArtifact( project, "maven-test", artifactId );
+ assertNotNull( artifact );
+ assertEquals( "Check scope", scopeValue, artifact.getScope() );
+ }
+
+ private Artifact getArtifact( MavenProject project, String groupId, String artifactId )
+ {
+ System.out.println( "[ Looking for " + groupId + ":" + artifactId + " ]" );
+ for ( Artifact a : project.getArtifacts() )
+ {
+ System.out.println( a.toString() );
+ if ( artifactId.equals( a.getArtifactId() ) && a.getGroupId().equals( groupId ) )
+ {
+ System.out.println( "RETURN" );
+ return a;
+ }
+ }
+ System.out.println( "Return null" );
+ return null;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/TestArtifactResolver.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/TestArtifactResolver.java
new file mode 100644
index 00000000..9f389d6d
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/TestArtifactResolver.java
@@ -0,0 +1,30 @@
+package org.apache.maven.project;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
+import org.apache.maven.artifact.resolver.ArtifactResolver;
+import org.apache.maven.artifact.resolver.DefaultArtifactResolver;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+
+@Component(role=ArtifactResolver.class,hint="classpath")
+public class TestArtifactResolver
+ extends DefaultArtifactResolver
+{
+ @Requirement(hint="classpath")
+ private ArtifactMetadataSource source;
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/TestMavenRepositorySystem.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/TestMavenRepositorySystem.java
new file mode 100644
index 00000000..2818df06
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/TestMavenRepositorySystem.java
@@ -0,0 +1,30 @@
+package org.apache.maven.project;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+import org.apache.maven.artifact.resolver.ArtifactResolver;
+import org.apache.maven.repository.RepositorySystem;
+import org.apache.maven.repository.legacy.LegacyRepositorySystem;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+
+@Component(role = RepositorySystem.class, hint = "classpath")
+public class TestMavenRepositorySystem
+ extends LegacyRepositorySystem
+{
+ @Requirement(hint="classpath")
+ private ArtifactResolver artifactResolver;
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/TestProjectBuilder.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/TestProjectBuilder.java
new file mode 100644
index 00000000..754487f4
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/TestProjectBuilder.java
@@ -0,0 +1,68 @@
+package org.apache.maven.project;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.util.Collections;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.codehaus.plexus.component.annotations.Component;
+
+@Component(role=ProjectBuilder.class,hint="classpath")
+public class TestProjectBuilder
+ extends DefaultProjectBuilder
+{
+
+ @Override
+ public ProjectBuildingResult build( Artifact artifact, ProjectBuildingRequest request )
+ throws ProjectBuildingException
+ {
+ if ( "maven-test".equals( artifact.getGroupId() ) )
+ {
+ String scope = artifact.getArtifactId().substring( "scope-".length() );
+
+ try
+ {
+ artifact.setFile( ProjectClasspathTest.getFileForClasspathResource( ProjectClasspathTest.dir + "transitive-" + scope + "-dep.xml" ) );
+ }
+ catch ( FileNotFoundException e )
+ {
+ throw new IllegalStateException( "Missing test POM for " + artifact );
+ }
+ }
+ if ( artifact.getFile() == null )
+ {
+ MavenProject project = new MavenProject();
+ project.setArtifact( artifact );
+ return new DefaultProjectBuildingResult( project, null, null );
+ }
+ return build( artifact.getFile(), request );
+ }
+
+ @Override
+ public ProjectBuildingResult build( File pomFile, ProjectBuildingRequest configuration )
+ throws ProjectBuildingException
+ {
+ ProjectBuildingResult result = super.build( pomFile, configuration );
+
+ result.getProject().setRemoteArtifactRepositories( Collections.<ArtifactRepository> emptyList() );
+
+ return result;
+ }
+
+} \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/inheritance/AbstractProjectInheritanceTestCase.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/inheritance/AbstractProjectInheritanceTestCase.java
new file mode 100644
index 00000000..413d6fea
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/inheritance/AbstractProjectInheritanceTestCase.java
@@ -0,0 +1,57 @@
+package org.apache.maven.project.inheritance;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+
+import org.apache.maven.project.AbstractMavenProjectTestCase;
+
+/**
+ * @author Jason van Zyl
+ */
+public abstract class AbstractProjectInheritanceTestCase
+ extends AbstractMavenProjectTestCase
+{
+ protected String getTestSeries()
+ {
+ String className = getClass().getPackage().getName();
+
+ return className.substring( className.lastIndexOf( "." ) + 1 );
+ }
+
+ protected File projectFile( String name )
+ {
+ return projectFile( "maven", name );
+ }
+
+ protected File projectFile( String groupId, String artifactId )
+ {
+ return new File( getLocalRepositoryPath(), "/" + groupId + "/poms/" + artifactId + "-1.0.pom" );
+ }
+
+ // ----------------------------------------------------------------------
+ // The local repository for this category of tests
+ // ----------------------------------------------------------------------
+
+ protected File getLocalRepositoryPath()
+ {
+ return getTestFile("src/test/resources/inheritance-repo/" + getTestSeries() );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/inheritance/t00/ProjectInheritanceTest.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/inheritance/t00/ProjectInheritanceTest.java
new file mode 100644
index 00000000..0ee79807
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/inheritance/t00/ProjectInheritanceTest.java
@@ -0,0 +1,93 @@
+package org.apache.maven.project.inheritance.t00;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.model.MailingList;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.project.inheritance.AbstractProjectInheritanceTestCase;
+
+/**
+ * A test which demonstrates maven's recursive inheritance where
+ * a distinct value is taken from each parent contributing to the
+ * the final model of the project being assembled. There is no
+ * overriding going on amongst the models being used in this test:
+ * each model in the lineage is providing a value that is not present
+ * anywhere else in the lineage. We are just making sure that values
+ * down in the lineage are bubbling up where they should.
+ *
+ * @author Jason van Zyl
+ */
+public class ProjectInheritanceTest
+ extends AbstractProjectInheritanceTestCase
+{
+ // ----------------------------------------------------------------------
+ //
+ // p4 inherits from p3
+ // p3 inherits from p2
+ // p2 inherits from p1
+ // p1 inherits from p0
+ // p0 inhertis from super model
+ //
+ // or we can show it graphically as:
+ //
+ // p4 ---> p3 ---> p2 ---> p1 ---> p0 --> super model
+ //
+ // ----------------------------------------------------------------------
+
+ public void testProjectInheritance()
+ throws Exception
+ {
+ MavenProject p4 = getProject( projectFile( "p4" ) );
+
+ assertEquals( "p4", p4.getName() );
+
+ // ----------------------------------------------------------------------
+ // Value inherited from p3
+ // ----------------------------------------------------------------------
+
+ assertEquals( "2000", p4.getInceptionYear() );
+
+ // ----------------------------------------------------------------------
+ // Value taken from p2
+ // ----------------------------------------------------------------------
+
+ assertEquals( "mailing-list", p4.getMailingLists().get( 0 ).getName() );
+
+ // ----------------------------------------------------------------------
+ // Value taken from p1
+ // ----------------------------------------------------------------------
+
+ assertEquals( "scm-url/p2/p3/p4", p4.getScm().getUrl() );
+
+ // ----------------------------------------------------------------------
+ // Value taken from p4
+ // ----------------------------------------------------------------------
+
+ assertEquals( "Codehaus", p4.getOrganization().getName() );
+
+ // ----------------------------------------------------------------------
+ // Value taken from super model
+ // ----------------------------------------------------------------------
+
+ assertEquals( "4.0.0", p4.getModelVersion() );
+
+ assertEquals( "4.0.0", p4.getModelVersion() );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/inheritance/t01/ProjectInheritanceTest.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/inheritance/t01/ProjectInheritanceTest.java
new file mode 100644
index 00000000..e6efcc4d
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/inheritance/t01/ProjectInheritanceTest.java
@@ -0,0 +1,92 @@
+package org.apache.maven.project.inheritance.t01;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.project.inheritance.AbstractProjectInheritanceTestCase;
+
+/**
+ * A test which demonstrates maven's recursive inheritance where
+ * we are testing to make sure that elements stated in a model are
+ * not clobbered by the same elements elsewhere in the lineage.
+ *
+ * @author Jason van Zyl
+ */
+public class ProjectInheritanceTest
+ extends AbstractProjectInheritanceTestCase
+{
+ // ----------------------------------------------------------------------
+ //
+ // p4 inherits from p3
+ // p3 inherits from p2
+ // p2 inherits from p1
+ // p1 inherits from p0
+ // p0 inhertis from super model
+ //
+ // or we can show it graphically as:
+ //
+ // p4 ---> p3 ---> p2 ---> p1 ---> p0 --> super model
+ //
+ // ----------------------------------------------------------------------
+
+ public void testProjectInheritance()
+ throws Exception
+ {
+ // ----------------------------------------------------------------------
+ // Check p0 value for org name
+ // ----------------------------------------------------------------------
+
+ MavenProject p0 = getProject( projectFile( "maven.t01", "p0" ) );
+
+ assertEquals( "p0-org", p0.getOrganization().getName() );
+
+ // ----------------------------------------------------------------------
+ // Check p1 value for org name
+ // ----------------------------------------------------------------------
+
+ MavenProject p1 = getProject( projectFile( "maven.t01", "p1" ) );
+
+ assertEquals( "p1-org", p1.getOrganization().getName() );
+
+ // ----------------------------------------------------------------------
+ // Check p2 value for org name
+ // ----------------------------------------------------------------------
+
+ MavenProject p2 = getProject( projectFile( "maven.t01", "p2" ) );
+
+ assertEquals( "p2-org", p2.getOrganization().getName() );
+
+ // ----------------------------------------------------------------------
+ // Check p2 value for org name
+ // ----------------------------------------------------------------------
+
+ MavenProject p3 = getProject( projectFile( "maven.t01", "p3" ) );
+
+ assertEquals( "p3-org", p3.getOrganization().getName() );
+
+ // ----------------------------------------------------------------------
+ // Check p4 value for org name
+ // ----------------------------------------------------------------------
+
+ MavenProject p4 = getProject( projectFile( "maven.t01", "p4" ) );
+
+ assertEquals( "p4-org", p4.getOrganization().getName() );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/inheritance/t02/ProjectInheritanceTest.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/inheritance/t02/ProjectInheritanceTest.java
new file mode 100644
index 00000000..339c81ff
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/inheritance/t02/ProjectInheritanceTest.java
@@ -0,0 +1,169 @@
+package org.apache.maven.project.inheritance.t02;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.maven.model.Build;
+import org.apache.maven.model.MailingList;
+import org.apache.maven.model.Plugin;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.project.inheritance.AbstractProjectInheritanceTestCase;
+
+/**
+ * A test which demonstrates maven's recursive inheritance where
+ * a distinct value is taken from each parent contributing to the
+ * the final model of the project being assembled. There is no
+ * overriding going on amongst the models being used in this test:
+ * each model in the lineage is providing a value that is not present
+ * anywhere else in the lineage. We are just making sure that values
+ * down in the lineage are bubbling up where they should.
+ *
+ * @author Jason van Zyl
+ */
+public class ProjectInheritanceTest
+ extends AbstractProjectInheritanceTestCase
+{
+ // ----------------------------------------------------------------------
+ //
+ // p4 inherits from p3
+ // p3 inherits from p2
+ // p2 inherits from p1
+ // p1 inherits from p0
+ // p0 inhertis from super model
+ //
+ // or we can show it graphically as:
+ //
+ // p4 ---> p3 ---> p2 ---> p1 ---> p0 --> super model
+ //
+ // ----------------------------------------------------------------------
+
+ public void testProjectInheritance()
+ throws Exception
+ {
+ File localRepo = getLocalRepositoryPath();
+
+ System.out.println( "Local repository is at: " + localRepo.getAbsolutePath() );
+
+ File pom0 = new File( localRepo, "p0/pom.xml" );
+ File pom1 = new File( pom0.getParentFile(), "p1/pom.xml" );
+ File pom2 = new File( pom1.getParentFile(), "p2/pom.xml" );
+ File pom3 = new File( pom2.getParentFile(), "p3/pom.xml" );
+ File pom4 = new File( pom3.getParentFile(), "p4/pom.xml" );
+ File pom5 = new File( pom4.getParentFile(), "p5/pom.xml" );
+
+ System.out.println( "Location of project-4's POM: " + pom4.getPath() );
+
+ // load everything...
+ MavenProject project0 = getProject( pom0 );
+ MavenProject project1 = getProject( pom1 );
+ MavenProject project2 = getProject( pom2 );
+ MavenProject project3 = getProject( pom3 );
+ MavenProject project4 = getProject( pom4 );
+ MavenProject project5 = getProject( pom5 );
+
+ assertEquals( "p4", project4.getName() );
+
+ // ----------------------------------------------------------------------
+ // Value inherited from p3
+ // ----------------------------------------------------------------------
+
+ assertEquals( "2000", project4.getInceptionYear() );
+
+ // ----------------------------------------------------------------------
+ // Value taken from p2
+ // ----------------------------------------------------------------------
+
+ assertEquals( "mailing-list", project4.getMailingLists().get( 0 ).getName() );
+
+ // ----------------------------------------------------------------------
+ // Value taken from p1
+ // ----------------------------------------------------------------------
+
+ assertEquals( "scm-url/p2/p3/p4", project4.getScm().getUrl() );
+
+ // ----------------------------------------------------------------------
+ // Value taken from p4
+ // ----------------------------------------------------------------------
+
+ assertEquals( "Codehaus", project4.getOrganization().getName() );
+
+ // ----------------------------------------------------------------------
+ // Value taken from super model
+ // ----------------------------------------------------------------------
+
+ assertEquals( "4.0.0", project4.getModelVersion() );
+
+ Build build = project4.getBuild();
+ List<Plugin> plugins = build.getPlugins();
+
+ Map validPluginCounts = new HashMap();
+
+ String testPluginArtifactId = "maven-compiler-plugin";
+
+ // this is the plugin we're looking for.
+ validPluginCounts.put( testPluginArtifactId, 0 );
+
+ // these are injected if -DperformRelease=true
+ validPluginCounts.put( "maven-deploy-plugin", 0 );
+ validPluginCounts.put( "maven-javadoc-plugin", 0 );
+ validPluginCounts.put( "maven-source-plugin", 0 );
+
+ Plugin testPlugin = null;
+
+ for ( Plugin plugin : plugins )
+ {
+ String pluginArtifactId = plugin.getArtifactId();
+
+ if ( !validPluginCounts.containsKey( pluginArtifactId ) )
+ {
+ fail( "Illegal plugin found: " + pluginArtifactId );
+ }
+ else
+ {
+ if ( pluginArtifactId.equals( testPluginArtifactId ) )
+ {
+ testPlugin = plugin;
+ }
+
+ Integer count = (Integer) validPluginCounts.get( pluginArtifactId );
+
+ if ( count > 0 )
+ {
+ fail( "Multiple copies of plugin: " + pluginArtifactId + " found in POM." );
+ }
+ else
+ {
+ count = count + 1;
+
+ validPluginCounts.put( pluginArtifactId, count );
+ }
+ }
+ }
+
+ List executions = testPlugin.getExecutions();
+
+ assertEquals( 1, executions.size() );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/inheritance/t03/ProjectInheritanceTest.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/inheritance/t03/ProjectInheritanceTest.java
new file mode 100644
index 00000000..73f518e4
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/inheritance/t03/ProjectInheritanceTest.java
@@ -0,0 +1,68 @@
+package org.apache.maven.project.inheritance.t03;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.project.inheritance.AbstractProjectInheritanceTestCase;
+
+/**
+ * A test which demonstrates maven's recursive inheritance where
+ * a distinct value is taken from each parent contributing to the
+ * the final model of the project being assembled. There is no
+ * overriding going on amongst the models being used in this test:
+ * each model in the lineage is providing a value that is not present
+ * anywhere else in the lineage. We are just making sure that values
+ * down in the lineage are bubbling up where they should.
+ *
+ * @author Jason van Zyl
+ */
+public class ProjectInheritanceTest
+ extends AbstractProjectInheritanceTestCase
+{
+ // ----------------------------------------------------------------------
+ //
+ // p1 inherits from p0
+ // p0 inhertis from super model
+ //
+ // or we can show it graphically as:
+ //
+ // p1 ---> p0 --> super model
+ //
+ // ----------------------------------------------------------------------
+
+ public void testProjectInheritance()
+ throws Exception
+ {
+ File localRepo = getLocalRepositoryPath();
+ File pom0 = new File( localRepo, "p0/pom.xml" );
+
+ File pom0Basedir = pom0.getParentFile();
+
+ File pom1 = new File( pom0Basedir, "p1/pom.xml" );
+
+ // load everything...
+ MavenProject project0 = getProject( pom0 );
+ MavenProject project1 = getProject( pom1 );
+
+ assertEquals( pom0Basedir, project1.getParent().getBasedir() );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/inheritance/t04/ProjectInheritanceTest.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/inheritance/t04/ProjectInheritanceTest.java
new file mode 100644
index 00000000..e24262f1
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/inheritance/t04/ProjectInheritanceTest.java
@@ -0,0 +1,86 @@
+package org.apache.maven.project.inheritance.t04;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.util.Iterator;
+import java.util.Set;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.project.inheritance.AbstractProjectInheritanceTestCase;
+
+/**
+ * Verifies the version of a dependency listed in a parent's
+ * dependencyManagement section is chosen over another version of the same
+ * dependency, listed transitively.
+ *
+ * @author <a href="mailto:pschneider@gmail.com">Patrick Schneider</a>
+ */
+public class ProjectInheritanceTest
+ extends AbstractProjectInheritanceTestCase
+{
+ // ----------------------------------------------------------------------
+ //
+ // p1 inherits from p0
+ // p0 inhertis from super model
+ //
+ // or we can show it graphically as:
+ //
+ // p1 ---> p0 --> super model
+ //
+ // p1 has a depMgmt section that specifies versions 1.0 of jars "a" & "b"
+ // jar "a" has a transitive dependency on 2.0 of jar "b", but maven should
+ // prefer to use version 1.0.
+ //
+ // ----------------------------------------------------------------------
+
+ public void testDependencyManagementOverridesTransitiveDependencyVersion()
+ throws Exception
+ {
+ File localRepo = getLocalRepositoryPath();
+ File pom0 = new File( localRepo, "p0/pom.xml" );
+ File pom0Basedir = pom0.getParentFile();
+ File pom1 = new File( pom0Basedir, "p1/pom.xml" );
+
+ // load the child project, which inherits from p0...
+ MavenProject project0 = getProjectWithDependencies( pom0 );
+ MavenProject project1 = getProjectWithDependencies( pom1 );
+
+ assertEquals( pom0Basedir, project1.getParent().getBasedir() );
+ Set set = project1.getArtifacts();
+ assertNotNull( "No artifacts", set );
+ assertTrue( "No Artifacts", set.size() > 0 );
+ assertTrue( "Set size should be 3, is " + set.size(), set.size() == 3 );
+
+ for ( Object aSet : set )
+ {
+ Artifact artifact = (Artifact) aSet;
+ System.out.println(
+ "Artifact: " + artifact.getDependencyConflictId() + " " + artifact.getVersion() + " Optional=" + (
+ artifact.isOptional()
+ ? "true"
+ : "false" ) );
+ assertTrue( "Incorrect version for " + artifact.getDependencyConflictId(),
+ artifact.getVersion().equals( "1.0" ) );
+ }
+
+ }
+} \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/inheritance/t05/ProjectInheritanceTest.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/inheritance/t05/ProjectInheritanceTest.java
new file mode 100644
index 00000000..1d2bd182
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/inheritance/t05/ProjectInheritanceTest.java
@@ -0,0 +1,79 @@
+package org.apache.maven.project.inheritance.t05;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.util.Iterator;
+import java.util.Set;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.project.inheritance.AbstractProjectInheritanceTestCase;
+
+/**
+ * A test which demonstrates maven's dependency management
+ *
+ * @author <a href="rgoers@apache.org">Ralph Goers</a>
+ */
+public class ProjectInheritanceTest
+ extends AbstractProjectInheritanceTestCase
+{
+ // ----------------------------------------------------------------------
+ //
+ // p1 inherits from p0
+ // p0 inhertis from super model
+ //
+ // or we can show it graphically as:
+ //
+ // p1 ---> p0 --> super model
+ //
+ // ----------------------------------------------------------------------
+
+ public void testDependencyManagement()
+ throws Exception
+ {
+ File localRepo = getLocalRepositoryPath();
+ File pom0 = new File( localRepo, "p0/pom.xml" );
+
+ File pom0Basedir = pom0.getParentFile();
+
+ File pom1 = new File( pom0Basedir, "p1/pom.xml" );
+
+ // load everything...
+ MavenProject project0 = getProjectWithDependencies( pom0 );
+ MavenProject project1 = getProjectWithDependencies( pom1 );
+
+ assertEquals( pom0Basedir, project1.getParent().getBasedir() );
+ Set set = project1.getArtifacts();
+ assertNotNull( "No artifacts", set );
+ assertTrue( "No Artifacts", set.size() > 0 );
+
+ for ( Object aSet : set )
+ {
+ Artifact artifact = (Artifact) aSet;
+ System.out.println(
+ "Artifact: " + artifact.getDependencyConflictId() + " " + artifact.getVersion() + " Scope: "
+ + artifact.getScope() );
+ assertTrue( "Incorrect version for " + artifact.getDependencyConflictId(),
+ artifact.getVersion().equals( "1.0" ) );
+ }
+
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/inheritance/t06/ProjectInheritanceTest.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/inheritance/t06/ProjectInheritanceTest.java
new file mode 100644
index 00000000..1b80dfeb
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/inheritance/t06/ProjectInheritanceTest.java
@@ -0,0 +1,80 @@
+package org.apache.maven.project.inheritance.t06;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.util.Iterator;
+import java.util.Set;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.project.inheritance.AbstractProjectInheritanceTestCase;
+
+/**
+ * A test which demonstrates maven's dependency management
+ *
+ * @author <a href="rgoers@apache.org">Ralph Goers</a>
+ */
+public class ProjectInheritanceTest
+ extends AbstractProjectInheritanceTestCase
+{
+ // ----------------------------------------------------------------------
+ //
+ // p1 inherits from p0
+ // p0 inhertis from super model
+ //
+ // or we can show it graphically as:
+ //
+ // p1 ---> p0 --> super model
+ //
+ // ----------------------------------------------------------------------
+
+ public void testDependencyManagement()
+ throws Exception
+ {
+ File localRepo = getLocalRepositoryPath();
+ File pom0 = new File( localRepo, "p0/pom.xml" );
+
+ File pom0Basedir = pom0.getParentFile();
+
+ File pom1 = new File( pom0Basedir, "p1/pom.xml" );
+
+ // load everything...
+ MavenProject project0 = getProjectWithDependencies( pom0 );
+ MavenProject project1 = getProjectWithDependencies( pom1 );
+
+ assertEquals( pom0Basedir, project1.getParent().getBasedir() );
+ Set set = project1.getArtifacts();
+ assertNotNull( "No artifacts", set );
+ assertTrue( "No Artifacts", set.size() > 0 );
+ Iterator iter = set.iterator();
+ assertTrue( "Set size should be 4, is " + set.size(), set.size() == 4 );
+
+ while ( iter.hasNext() )
+ {
+ Artifact artifact = (Artifact) iter.next();
+ System.out.println( "Artifact: " + artifact.getDependencyConflictId() + " " + artifact.getVersion()
+ + " Optional=" + ( artifact.isOptional() ? "true" : "false" ) );
+ assertTrue( "Incorrect version for " + artifact.getDependencyConflictId(),
+ artifact.getVersion().equals( "1.0" ) );
+ }
+
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/inheritance/t07/ProjectInheritanceTest.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/inheritance/t07/ProjectInheritanceTest.java
new file mode 100644
index 00000000..68586aaf
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/inheritance/t07/ProjectInheritanceTest.java
@@ -0,0 +1,82 @@
+package org.apache.maven.project.inheritance.t07;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.util.Iterator;
+import java.util.Set;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.project.inheritance.AbstractProjectInheritanceTestCase;
+
+/**
+ * A test which demonstrates maven's dependency management
+ *
+ * @author Jason van Zyl
+ */
+public class ProjectInheritanceTest
+ extends AbstractProjectInheritanceTestCase
+{
+ // ----------------------------------------------------------------------
+ //
+ // p1 inherits from p0
+ // p0 inhertis from super model
+ //
+ // or we can show it graphically as:
+ //
+ // p1 ---> p0 --> super model
+ //
+ // ----------------------------------------------------------------------
+
+ public void testDependencyManagement()
+ throws Exception
+ {
+ File localRepo = getLocalRepositoryPath();
+ File pom0 = new File( localRepo, "p0/pom.xml" );
+
+ File pom0Basedir = pom0.getParentFile();
+
+ File pom1 = new File( pom0Basedir, "p1/pom.xml" );
+
+ // load everything...
+ MavenProject project1 = getProjectWithDependencies( pom1 );
+
+ assertEquals( pom0Basedir, project1.getParent().getBasedir() );
+ System.out.println("Project " + project1.getId() + " " + project1);
+ Set set = project1.getArtifacts();
+ assertNotNull("No artifacts", set);
+ assertTrue("No Artifacts", set.size() > 0);
+ assertTrue("Set size should be 3, is " + set.size(), set.size() == 3 );
+
+ for ( Object aSet : set )
+ {
+ Artifact artifact = (Artifact) aSet;
+ assertFalse( "", artifact.getArtifactId().equals( "t07-d" ) );
+ System.out.println(
+ "Artifact: " + artifact.getDependencyConflictId() + " " + artifact.getVersion() + " Optional=" + (
+ artifact.isOptional()
+ ? "true"
+ : "false" ) );
+ assertTrue( "Incorrect version for " + artifact.getDependencyConflictId(),
+ artifact.getVersion().equals( "1.0" ) );
+ }
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/inheritance/t08/ProjectInheritanceTest.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/inheritance/t08/ProjectInheritanceTest.java
new file mode 100644
index 00000000..1afb8e8e
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/inheritance/t08/ProjectInheritanceTest.java
@@ -0,0 +1,81 @@
+package org.apache.maven.project.inheritance.t08;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.util.Iterator;
+import java.util.Set;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.project.inheritance.AbstractProjectInheritanceTestCase;
+
+/**
+ * A test which demonstrates maven's dependency management
+ *
+ * @author <a href="rgoers@apache.org">Ralph Goers</a>
+ */
+public class ProjectInheritanceTest
+ extends AbstractProjectInheritanceTestCase
+{
+ // ----------------------------------------------------------------------
+ //
+ // p1 inherits from p0
+ // p0 inhertis from super model
+ //
+ // or we can show it graphically as:
+ //
+ // p1 ---> p0 --> super model
+ //
+ // ----------------------------------------------------------------------
+
+ public void testDependencyManagement()
+ throws Exception
+ {
+ File localRepo = getLocalRepositoryPath();
+ File pom0 = new File( localRepo, "p0/pom.xml" );
+
+ File pom0Basedir = pom0.getParentFile();
+
+ File pom1 = new File( pom0Basedir, "p1/pom.xml" );
+
+ // load everything...
+ MavenProject project0 = getProjectWithDependencies( pom0 );
+ MavenProject project1 = getProjectWithDependencies( pom1 );
+
+ assertEquals( pom0Basedir, project1.getParent().getBasedir() );
+ System.out.println( "Project " + project1.getId() + " " + project1 );
+ Set set = project1.getArtifacts();
+ assertNotNull( "No artifacts", set );
+ assertTrue( "No Artifacts", set.size() > 0 );
+ Iterator iter = set.iterator();
+ assertTrue( "Set size should be 4, is " + set.size(), set.size() == 4 );
+
+ while ( iter.hasNext() )
+ {
+ Artifact artifact = (Artifact) iter.next();
+ System.out.println( "Artifact: " + artifact.getDependencyConflictId() + " " + artifact.getVersion()
+ + " Optional=" + ( artifact.isOptional() ? "true" : "false" ) );
+ assertTrue( "Incorrect version for " + artifact.getDependencyConflictId(),
+ artifact.getVersion().equals( "1.0" ) );
+ }
+
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/inheritance/t09/ProjectInheritanceTest.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/inheritance/t09/ProjectInheritanceTest.java
new file mode 100644
index 00000000..6a29b732
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/inheritance/t09/ProjectInheritanceTest.java
@@ -0,0 +1,119 @@
+package org.apache.maven.project.inheritance.t09;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import java.io.File;
+import java.util.Map;
+
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.project.inheritance.AbstractProjectInheritanceTestCase;
+
+/**
+ * Verifies exclusions listed in dependencyManagement are valid for
+ * transitive dependencies.
+ *
+ * @author <a href="mailto:pschneider@gmail.com">Patrick Schneider</a>
+ */
+public class ProjectInheritanceTest
+ extends AbstractProjectInheritanceTestCase
+{
+ // ----------------------------------------------------------------------
+ //
+ // p1 inherits from p0
+ // p0 inhertis from super model
+ //
+ // or we can show it graphically as:
+ //
+ // p1 ---> p0 --> super model
+ //
+ // ----------------------------------------------------------------------
+
+ /**
+ * How the test project is set up:
+ *
+ * 1. dependencyManagement lists dependencies on a & b,
+ * with an exclusion on c in b.
+ * 2. the child project lists a dependency on project a only
+ * 3. a depends on b (which is transitive to the child project),
+ * and b depends on c.
+ *
+ * We should see that the resulting size of collected artifacts is two:
+ * a & b only.
+ */
+ public void testDependencyManagementExclusionsExcludeTransitively()
+ throws Exception
+ {
+ File localRepo = getLocalRepositoryPath();
+
+ File pom0 = new File( localRepo, "p0/pom.xml" );
+ File pom0Basedir = pom0.getParentFile();
+ File pom1 = new File( pom0Basedir, "p1/pom.xml" );
+
+ // load the child project, which inherits from p0...
+ MavenProject project0 = getProjectWithDependencies( pom0 );
+ MavenProject project1 = getProjectWithDependencies( pom1 );
+
+ assertNotNull("Parent is null", project1.getParent());
+ assertEquals( pom0Basedir, project1.getParent().getBasedir() );
+ Map map = project1.getArtifactMap();
+
+ assertNotNull("No artifacts", map);
+ assertTrue("No Artifacts", map.size() > 0);
+ assertTrue("Set size should be 2, is " + map.size(), map.size() == 2);
+
+ assertTrue("maven-test:t09-a is not in the project", map.containsKey( "maven-test:t09-a" ));
+ assertTrue("maven-test:t09-b is not in the project", map.containsKey( "maven-test:t09-b" ));
+ assertFalse("maven-test:t09-c is in the project", map.containsKey( "maven-test:t09-c" ));
+ }
+
+ /**
+ * Setup exactly the same as the above test, except that the child project
+ * now depends upon d, which has a transitive dependency on c. Even though
+ * we did list an exclusion on c, it was only from within the context of
+ * project b. We will pick up project c in this case because no
+ * restrictions were placed on d. This demonstrates that a, b, c, & d will
+ * all be collected.
+ *
+ * @throws Exception
+ */
+ public void testDependencyManagementExclusionDoesNotOverrideGloballyForTransitives()
+ throws Exception
+ {
+ File localRepo = getLocalRepositoryPath();
+
+ File pom0 = new File( localRepo, "p0/pom.xml" );
+ File pom0Basedir = pom0.getParentFile();
+ File pom2 = new File( pom0Basedir, "p2/pom.xml" );
+
+ // load the child project, which inherits from p0...
+ MavenProject project0 = getProjectWithDependencies( pom0 );
+ MavenProject project2 = getProjectWithDependencies( pom2 );
+
+ assertEquals( pom0Basedir, project2.getParent().getBasedir() );
+ Map map = project2.getArtifactMap();
+ assertNotNull( "No artifacts", map );
+ assertTrue( "No Artifacts", map.size() > 0 );
+ assertTrue( "Set size should be 4, is " + map.size(), map.size() == 4 );
+
+ assertTrue( "maven-test:t09-a is not in the project", map.containsKey( "maven-test:t09-a" ) );
+ assertTrue( "maven-test:t09-b is not in the project", map.containsKey( "maven-test:t09-b" ) );
+ assertTrue( "maven-test:t09-c is not in the project", map.containsKey( "maven-test:t09-c" ) );
+ assertTrue( "maven-test:t09-d is not in the project", map.containsKey( "maven-test:t09-d" ) );
+ }
+} \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/inheritance/t10/ProjectInheritanceTest.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/inheritance/t10/ProjectInheritanceTest.java
new file mode 100644
index 00000000..9e5137f2
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/inheritance/t10/ProjectInheritanceTest.java
@@ -0,0 +1,94 @@
+package org.apache.maven.project.inheritance.t10;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.util.Map;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.project.inheritance.AbstractProjectInheritanceTestCase;
+
+/**
+ * Verifies scope inheritence of direct and transitive dependencies.
+ *
+ * Should show three behaviors:
+ *
+ * 1. dependencyManagement should override the scope of transitive dependencies.
+ * 2. Direct dependencies should override the scope of dependencyManagement.
+ * 3. Direct dependencies should inherit scope from dependencyManagement when
+ * they do not explicitly state a scope.
+ *
+ * @author <a href="mailto:pschneider@gmail.com">Patrick Schneider</a>
+ */
+public class ProjectInheritanceTest
+ extends AbstractProjectInheritanceTestCase
+{
+ // ----------------------------------------------------------------------
+ //
+ // p1 inherits from p0
+ // p0 inhertis from super model
+ //
+ // or we can show it graphically as:
+ //
+ // p1 ---> p0 --> super model
+ //
+ // ----------------------------------------------------------------------
+
+ public void testDependencyManagementOverridesTransitiveDependencyVersion()
+ throws Exception
+ {
+ File localRepo = getLocalRepositoryPath();
+
+ File pom0 = new File( localRepo, "p0/pom.xml" );
+ File pom0Basedir = pom0.getParentFile();
+ File pom1 = new File( pom0Basedir, "p1/pom.xml" );
+
+ // load the child project, which inherits from p0...
+ MavenProject project0 = getProjectWithDependencies( pom0 );
+ MavenProject project1 = getProjectWithDependencies( pom1 );
+
+ assertEquals( pom0Basedir, project1.getParent().getBasedir() );
+ System.out.println("Project " + project1.getId() + " " + project1);
+ Map map = project1.getArtifactMap();
+ assertNotNull("No artifacts", map);
+ assertTrue("No Artifacts", map.size() > 0);
+ assertTrue("Set size should be 3, is " + map.size(), map.size() == 3);
+
+ Artifact a = (Artifact) map.get("maven-test:t10-a");
+ Artifact b = (Artifact) map.get("maven-test:t10-b");
+ Artifact c = (Artifact) map.get("maven-test:t10-c");
+
+ assertNotNull( a );
+ assertNotNull( b );
+ assertNotNull( c );
+
+ // inherited from depMgmt
+ System.out.println(a.getScope());
+ assertTrue("Incorrect scope for " + a.getDependencyConflictId(), a.getScope().equals("test"));
+
+ // transitive dep, overridden b depMgmt
+ assertTrue("Incorrect scope for " + b.getDependencyConflictId(), b.getScope().equals("runtime"));
+
+ // direct dep, overrides depMgmt
+ assertTrue("Incorrect scope for " + c.getDependencyConflictId(), c.getScope().equals("runtime"));
+
+ }
+} \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/inheritance/t11/ProjectInheritanceTest.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/inheritance/t11/ProjectInheritanceTest.java
new file mode 100644
index 00000000..bbdecd7a
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/inheritance/t11/ProjectInheritanceTest.java
@@ -0,0 +1,64 @@
+package org.apache.maven.project.inheritance.t11;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.project.inheritance.AbstractProjectInheritanceTestCase;
+
+/**
+ * Verifies scope of root project is preserved regardless of parent depenedency management.
+ *
+ * @author <a href="mailto:pschneider@gmail.com">Patrick Schneider</a>
+ * @see <a href="http://jira.codehaus.org/browse/MNG-2919">MNG-2919</a>
+ */
+public class ProjectInheritanceTest
+ extends AbstractProjectInheritanceTestCase
+{
+ // ----------------------------------------------------------------------
+ //
+ // p1 inherits from p0
+ // p0 inhertis from super model
+ //
+ // or we can show it graphically as:
+ //
+ // p1 ---> p0 --> super model
+ //
+ // ----------------------------------------------------------------------
+
+ public void testDependencyManagementDoesNotOverrideScopeOfCurrentArtifact()
+ throws Exception
+ {
+ File localRepo = getLocalRepositoryPath();
+
+ File pom0 = new File( localRepo, "p0/pom.xml" );
+ File pom0Basedir = pom0.getParentFile();
+ File pom1 = new File( pom0Basedir, "p1/pom.xml" );
+
+ // load the child project, which inherits from p0...
+ MavenProject project0 = getProjectWithDependencies( pom0 );
+ MavenProject project1 = getProjectWithDependencies( pom1 );
+
+ assertEquals( pom0Basedir, project1.getParent().getBasedir() );
+ assertNull( "dependencyManagement has overwritten the scope of the currently building child project",
+ project1.getArtifact().getScope() );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/inheritance/t12/ProjectInheritanceTest.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/inheritance/t12/ProjectInheritanceTest.java
new file mode 100644
index 00000000..814e4871
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/inheritance/t12/ProjectInheritanceTest.java
@@ -0,0 +1,65 @@
+package org.apache.maven.project.inheritance.t12;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.util.Map;
+
+import org.apache.maven.model.Plugin;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.project.inheritance.AbstractProjectInheritanceTestCase;
+
+/**
+ * Verifies that plugin execution sections in the parent POM that have
+ * inherit == false are not inherited to the child POM.
+ */
+public class ProjectInheritanceTest extends AbstractProjectInheritanceTestCase
+{
+ // ----------------------------------------------------------------------
+ //
+ // p1 inherits from p0
+ // p0 inherits from super model
+ //
+ // or we can show it graphically as:
+ //
+ // p1 ---> p0 --> super model
+ //
+ // ----------------------------------------------------------------------
+
+ public void testFalsePluginExecutionInheritValue() throws Exception
+ {
+ File localRepo = getLocalRepositoryPath();
+
+ File pom0 = new File( localRepo, "p0/pom.xml" );
+ File pom0Basedir = pom0.getParentFile();
+ File pom1 = new File( pom0Basedir, "p1/pom.xml" );
+
+ getProjectWithDependencies( pom0 );
+ MavenProject project1 = getProjectWithDependencies( pom1 );
+
+ Map pluginMap = project1.getBuild().getPluginsAsMap();
+ Plugin compilerPlugin = (Plugin) pluginMap.get( "org.apache.maven.plugins:maven-compiler-plugin" );
+
+ assertNotNull( compilerPlugin );
+
+ Map executionMap = compilerPlugin.getExecutionsAsMap();
+ assertNull( "Plugin execution: \'test\' should NOT exist in the compiler plugin specification for the child project!", executionMap.get( "test" ) );
+ }
+} \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/inheritance/t12scm/ProjectInheritanceTest.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/inheritance/t12scm/ProjectInheritanceTest.java
new file mode 100644
index 00000000..3b086624
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/inheritance/t12scm/ProjectInheritanceTest.java
@@ -0,0 +1,125 @@
+package org.apache.maven.project.inheritance.t12scm;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.project.inheritance.AbstractProjectInheritanceTestCase;
+
+/**
+ * Verifies SCM inheritance uses modules statement from parent.
+ *
+ * @author jdcasey
+ */
+public class ProjectInheritanceTest
+ extends AbstractProjectInheritanceTestCase
+{
+ // ----------------------------------------------------------------------
+ //
+ // p1 inherits from p0
+ // p0 inhertis from super model
+ //
+ // or we can show it graphically as:
+ //
+ // p1 ---> p0 --> super model
+ //
+ // ----------------------------------------------------------------------
+
+ public void testScmInfoCalculatedCorrectlyOnParentAndChildRead()
+ throws Exception
+ {
+ File localRepo = getLocalRepositoryPath();
+
+ File pom0 = new File( localRepo, "p0/pom.xml" );
+ File pom0Basedir = pom0.getParentFile();
+ File pom1 = new File( pom0Basedir, "modules/p1/pom.xml" );
+
+ // load the child project, which inherits from p0...
+ MavenProject project0 = getProject( pom0 );
+ MavenProject project1 = getProject( pom1 );
+
+ System.out.println( "\n\n" );
+ System.out.println( "Parent SCM URL is: " + project0.getScm().getUrl() );
+ System.out.println( "Child SCM URL is: " + project1.getScm().getUrl() );
+ System.out.println();
+ System.out.println( "Parent SCM connection is: " + project0.getScm().getConnection() );
+ System.out.println( "Child SCM connection is: " + project1.getScm().getConnection() );
+ System.out.println();
+ System.out.println( "Parent SCM developer connection is: "
+ + project0.getScm().getDeveloperConnection() );
+ System.out.println( "Child SCM developer connection is: "
+ + project1.getScm().getDeveloperConnection() );
+
+ assertEquals( project1.getScm().getUrl(), project0.getScm().getUrl() + "/modules/p1" );
+ assertEquals( project1.getScm().getConnection(), project0.getScm().getConnection()
+ + "/modules/p1" );
+ assertEquals( project1.getScm().getDeveloperConnection(), project0.getScm()
+ .getDeveloperConnection()
+ + "/modules/p1" );
+ }
+
+ public void testScmInfoCalculatedCorrectlyOnChildOnlyRead()
+ throws Exception
+ {
+ File localRepo = getLocalRepositoryPath();
+
+ File pom1 = new File( localRepo, "p0/modules/p1/pom.xml" );
+
+ // load the child project, which inherits from p0...
+ MavenProject project1 = getProject( pom1 );
+
+ System.out.println( "\n\n" );
+ System.out.println( "Child SCM URL is: " + project1.getScm().getUrl() );
+ System.out.println( "Child SCM connection is: " + project1.getScm().getConnection() );
+ System.out.println( "Child SCM developer connection is: "
+ + project1.getScm().getDeveloperConnection() );
+
+ assertEquals( "http://host/viewer?path=/p0/modules/p1", project1.getScm().getUrl() );
+ assertEquals( "scm:svn:http://host/p0/modules/p1", project1.getScm().getConnection() );
+ assertEquals( "scm:svn:https://host/p0/modules/p1", project1.getScm().getDeveloperConnection() );
+ }
+
+// public void testScmInfoCalculatedCorrectlyOnChildReadFromLocalRepository()
+// throws Exception
+// {
+// File localRepo = getLocalRepositoryPath();
+//
+// ArtifactFactory factory = (ArtifactFactory) lookup( ArtifactFactory.class );
+// Artifact artifact = factory.createProjectArtifact( "maven", "p1", "1.0" );
+//
+// ArtifactRepositoryFactory repoFactory = (ArtifactRepositoryFactory) lookup( ArtifactRepositoryFactory.class );
+// ArtifactRepository localArtifactRepo = repoFactory.createLocalRepository( localRepo );
+//
+// MavenProject project1 = getProjectBuilder().buildFromRepository( artifact, Collections.EMPTY_LIST, localArtifactRepo );
+//
+// System.out.println( "\n\n" );
+// System.out.println( "Child SCM URL is: " + project1.getScm().getUrl() );
+// System.out.println( "Child SCM connection is: " + project1.getScm().getConnection() );
+// System.out.println( "Child SCM developer connection is: "
+// + project1.getScm().getDeveloperConnection() );
+//
+// assertEquals( project1.getScm().getUrl(), "http://host/viewer?path=/p0/modules/p1" );
+// assertEquals( project1.getScm().getConnection(), "scm:svn:http://host/p0/modules/p1" );
+// assertEquals( project1.getScm().getDeveloperConnection(),
+// "scm:svn:https://host/p0/modules/p1" );
+// }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/path/DefaultPathTranslatorTest.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/path/DefaultPathTranslatorTest.java
new file mode 100644
index 00000000..b19ef996
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/project/path/DefaultPathTranslatorTest.java
@@ -0,0 +1,58 @@
+package org.apache.maven.project.path;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+
+import junit.framework.TestCase;
+
+@SuppressWarnings( "deprecation" )
+public class DefaultPathTranslatorTest
+ extends TestCase
+{
+
+ public void testAlignToBasedirWhereBasedirExpressionIsTheCompleteValue()
+ {
+ File basedir = new File( System.getProperty( "java.io.tmpdir" ), "test" ).getAbsoluteFile();
+
+ String aligned = new DefaultPathTranslator().alignToBaseDirectory( "${basedir}", basedir );
+
+ assertEquals( basedir.getAbsolutePath(), aligned );
+ }
+
+ public void testAlignToBasedirWhereBasedirExpressionIsTheValuePrefix()
+ {
+ File basedir = new File( System.getProperty( "java.io.tmpdir" ), "test" ).getAbsoluteFile();
+
+ String aligned = new DefaultPathTranslator().alignToBaseDirectory( "${basedir}/dir", basedir );
+
+ assertEquals( new File( basedir, "dir" ).getAbsolutePath(), aligned );
+ }
+
+ public void testUnalignToBasedirWherePathEqualsBasedir()
+ {
+ File basedir = new File( System.getProperty( "java.io.tmpdir" ), "test" ).getAbsoluteFile();
+
+ String unaligned = new DefaultPathTranslator().unalignFromBaseDirectory( basedir.getAbsolutePath(), basedir );
+
+ assertEquals( ".", unaligned );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/DefaultMirrorSelectorTest.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/DefaultMirrorSelectorTest.java
new file mode 100644
index 00000000..fb32f0f2
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/DefaultMirrorSelectorTest.java
@@ -0,0 +1,38 @@
+package org.apache.maven.repository;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.repository.DefaultArtifactRepository;
+import org.codehaus.plexus.PlexusTestCase;
+
+public class DefaultMirrorSelectorTest
+ extends PlexusTestCase
+{
+
+ public void testMirrorWithMirroOfPatternContainingANegationIsNotSelected()
+ {
+ ArtifactRepository repository = new DefaultArtifactRepository( "snapshots.repo", "http://whatever", null );
+ String pattern = "external:*, !snapshots.repo";
+ boolean matches = DefaultMirrorSelector.matchPattern( repository, pattern );
+ System.out.println( matches );
+ assertFalse( matches );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/LegacyRepositoryLayout.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/LegacyRepositoryLayout.java
new file mode 100644
index 00000000..77a6baef
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/LegacyRepositoryLayout.java
@@ -0,0 +1,89 @@
+package org.apache.maven.repository;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.handler.ArtifactHandler;
+import org.apache.maven.artifact.metadata.ArtifactMetadata;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout;
+import org.codehaus.plexus.component.annotations.Component;
+
+/**
+ * @author jdcasey
+ */
+@Component(role=ArtifactRepositoryLayout.class, hint="legacy")
+public class LegacyRepositoryLayout
+ implements ArtifactRepositoryLayout
+{
+ private static final String PATH_SEPARATOR = "/";
+
+ public String getId()
+ {
+ return "legacy";
+ }
+
+ public String pathOf( Artifact artifact )
+ {
+ ArtifactHandler artifactHandler = artifact.getArtifactHandler();
+
+ StringBuilder path = new StringBuilder( 128 );
+
+ path.append( artifact.getGroupId() ).append( '/' );
+ path.append( artifactHandler.getDirectory() ).append( '/' );
+ path.append( artifact.getArtifactId() ).append( '-' ).append( artifact.getVersion() );
+
+ if ( artifact.hasClassifier() )
+ {
+ path.append( '-' ).append( artifact.getClassifier() );
+ }
+
+ if ( artifactHandler.getExtension() != null && artifactHandler.getExtension().length() > 0 )
+ {
+ path.append( '.' ).append( artifactHandler.getExtension() );
+ }
+
+ return path.toString();
+ }
+
+ public String pathOfLocalRepositoryMetadata( ArtifactMetadata metadata,
+ ArtifactRepository repository )
+ {
+ return pathOfRepositoryMetadata( metadata, metadata.getLocalFilename( repository ) );
+ }
+
+ private String pathOfRepositoryMetadata( ArtifactMetadata metadata,
+ String filename )
+ {
+ StringBuilder path = new StringBuilder( 128 );
+
+ path.append( metadata.getGroupId() ).append( PATH_SEPARATOR ).append( "poms" ).append( PATH_SEPARATOR );
+
+ path.append( filename );
+
+ return path.toString();
+ }
+
+ public String pathOfRemoteRepositoryMetadata( ArtifactMetadata metadata )
+ {
+ return pathOfRepositoryMetadata( metadata, metadata.getRemoteFilename() );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/LegacyRepositorySystemTest.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/LegacyRepositorySystemTest.java
new file mode 100644
index 00000000..96af590c
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/LegacyRepositorySystemTest.java
@@ -0,0 +1,206 @@
+package org.apache.maven.repository;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+import java.io.File;
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.resolver.ArtifactResolutionRequest;
+import org.apache.maven.artifact.resolver.ArtifactResolutionResult;
+import org.apache.maven.artifact.resolver.ResolutionErrorHandler;
+import org.apache.maven.execution.DefaultMavenExecutionRequest;
+import org.apache.maven.execution.DefaultMavenExecutionResult;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.model.Dependency;
+import org.apache.maven.model.Repository;
+import org.apache.maven.model.RepositoryPolicy;
+import org.apache.maven.plugin.LegacySupport;
+import org.apache.maven.repository.RepositorySystem;
+import org.codehaus.plexus.ContainerConfiguration;
+import org.codehaus.plexus.PlexusConstants;
+import org.codehaus.plexus.PlexusTestCase;
+import org.eclipse.aether.DefaultRepositorySystemSession;
+import org.eclipse.aether.internal.impl.SimpleLocalRepositoryManagerFactory;
+import org.eclipse.aether.repository.LocalRepository;
+
+/**
+ * Tests {@link LegacyRepositorySystem}.
+ *
+ * @author Benjamin Bentmann
+ */
+public class LegacyRepositorySystemTest
+ extends PlexusTestCase
+{
+ private RepositorySystem repositorySystem;
+
+ private ResolutionErrorHandler resolutionErrorHandler;
+
+ @Override
+ protected void customizeContainerConfiguration( ContainerConfiguration containerConfiguration )
+ {
+ super.customizeContainerConfiguration( containerConfiguration );
+ containerConfiguration.setAutoWiring( true );
+ containerConfiguration.setClassPathScanning( PlexusConstants.SCANNING_INDEX );
+ }
+
+ @Override
+ protected void setUp()
+ throws Exception
+ {
+ super.setUp();
+ repositorySystem = lookup( RepositorySystem.class, "default" );
+ resolutionErrorHandler = lookup( ResolutionErrorHandler.class );
+ }
+
+ @Override
+ protected void tearDown()
+ throws Exception
+ {
+ repositorySystem = null;
+ resolutionErrorHandler = null;
+ super.tearDown();
+ }
+
+ protected List<ArtifactRepository> getRemoteRepositories()
+ throws Exception
+ {
+ File repoDir = new File( getBasedir(), "src/test/remote-repo" ).getAbsoluteFile();
+
+ RepositoryPolicy policy = new RepositoryPolicy();
+ policy.setEnabled( true );
+ policy.setChecksumPolicy( "ignore" );
+ policy.setUpdatePolicy( "always" );
+
+ Repository repository = new Repository();
+ repository.setId( RepositorySystem.DEFAULT_REMOTE_REPO_ID );
+ repository.setUrl( "file://" + repoDir.toURI().getPath() );
+ repository.setReleases( policy );
+ repository.setSnapshots( policy );
+
+ return Arrays.asList( repositorySystem.buildArtifactRepository( repository ) );
+ }
+
+ protected ArtifactRepository getLocalRepository()
+ throws Exception
+ {
+ File repoDir = new File( getBasedir(), "target/local-repo" ).getAbsoluteFile();
+
+ return repositorySystem.createLocalRepository( repoDir );
+ }
+
+ public void testThatASystemScopedDependencyIsNotResolvedFromRepositories()
+ throws Exception
+ {
+ //
+ // We should get a whole slew of dependencies resolving this artifact transitively
+ //
+ Dependency d = new Dependency();
+ d.setGroupId( "org.apache.maven.its" );
+ d.setArtifactId( "b" );
+ d.setVersion( "0.1" );
+ d.setScope( Artifact.SCOPE_COMPILE );
+ Artifact artifact = repositorySystem.createDependencyArtifact( d );
+
+ ArtifactResolutionRequest request = new ArtifactResolutionRequest()
+ .setArtifact( artifact )
+ .setResolveRoot( true )
+ .setResolveTransitively( true )
+ .setRemoteRepositories( getRemoteRepositories() )
+ .setLocalRepository( getLocalRepository() );
+
+ DefaultRepositorySystemSession session = new DefaultRepositorySystemSession();
+ LocalRepository localRepo = new LocalRepository( request.getLocalRepository().getBasedir() );
+ session.setLocalRepositoryManager( new SimpleLocalRepositoryManagerFactory().newInstance( session, localRepo ) );
+ LegacySupport legacySupport = lookup( LegacySupport.class );
+ legacySupport.setSession( new MavenSession( getContainer(), session, new DefaultMavenExecutionRequest(),
+ new DefaultMavenExecutionResult() ) );
+
+ ArtifactResolutionResult result = repositorySystem.resolve( request );
+ resolutionErrorHandler.throwErrors( request, result );
+ assertEquals( 2, result.getArtifacts().size() );
+
+ //
+ // System scoped version which should
+ //
+ d.setScope( Artifact.SCOPE_SYSTEM );
+ File file = new File( getBasedir(), "src/test/repository-system/maven-core-2.1.0.jar" );
+ assertTrue( file.exists() );
+ d.setSystemPath( file.getCanonicalPath() );
+
+ artifact = repositorySystem.createDependencyArtifact( d );
+
+ //
+ // The request has not set any local or remote repositories as the system scoped dependency being resolved should only
+ // give us the dependency off the disk and nothing more.
+ //
+ request = new ArtifactResolutionRequest()
+ .setArtifact( artifact )
+ .setResolveRoot( true )
+ .setResolveTransitively( true );
+
+ result = repositorySystem.resolve( request );
+ resolutionErrorHandler.throwErrors( request, result );
+ assertEquals( 1, result.getArtifacts().size() );
+
+ //
+ // Put in a bogus file to make sure missing files cause the resolution to fail.
+ //
+ file = new File( getBasedir(), "src/test/repository-system/maven-monkey-2.1.0.jar" );
+ assertFalse( file.exists() );
+ d.setSystemPath( file.getCanonicalPath() );
+ artifact = repositorySystem.createDependencyArtifact( d );
+
+ //
+ // The request has not set any local or remote repositories as the system scoped dependency being resolved should only
+ // give us the dependency off the disk and nothing more.
+ //
+ request = new ArtifactResolutionRequest()
+ .setArtifact( artifact )
+ .setResolveRoot( true )
+ .setResolveTransitively( true );
+
+ try
+ {
+ result = repositorySystem.resolve( request );
+ resolutionErrorHandler.throwErrors( request, result );
+ }
+ catch( Exception e )
+ {
+ assertTrue( result.hasMissingArtifacts() );
+ }
+ }
+
+ public void testLocalRepositoryBasedir()
+ throws Exception
+ {
+ File localRepoDir = new File( "" ).getAbsoluteFile();
+
+ ArtifactRepository localRepo = repositorySystem.createLocalRepository( localRepoDir );
+
+ String basedir = localRepo.getBasedir();
+
+ assertFalse( basedir.endsWith( "/" ) );
+ assertFalse( basedir.endsWith( "\\" ) );
+
+ assertEquals( localRepoDir, new File( basedir ) );
+
+ assertEquals( localRepoDir.getPath(), basedir );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/MirrorProcessorTest.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/MirrorProcessorTest.java
new file mode 100644
index 00000000..57645750
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/MirrorProcessorTest.java
@@ -0,0 +1,259 @@
+package org.apache.maven.repository;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.repository.legacy.repository.ArtifactRepositoryFactory;
+import org.apache.maven.artifact.repository.layout.DefaultRepositoryLayout;
+import org.apache.maven.settings.Mirror;
+import org.codehaus.plexus.PlexusTestCase;
+
+public class MirrorProcessorTest
+ extends PlexusTestCase
+{
+ private DefaultMirrorSelector mirrorSelector;
+ private ArtifactRepositoryFactory repositorySystem;
+
+ protected void setUp()
+ throws Exception
+ {
+ mirrorSelector = (DefaultMirrorSelector) lookup( MirrorSelector.class );
+ repositorySystem = lookup( ArtifactRepositoryFactory.class );
+ }
+
+ @Override
+ protected void tearDown()
+ throws Exception
+ {
+ mirrorSelector = null;
+ repositorySystem = null;
+
+ super.tearDown();
+ }
+
+ public void testExternalURL()
+ {
+ assertTrue( DefaultMirrorSelector.isExternalRepo( getRepo( "foo", "http://somehost" ) ) );
+ assertTrue( DefaultMirrorSelector.isExternalRepo( getRepo( "foo", "http://somehost:9090/somepath" ) ) );
+ assertTrue( DefaultMirrorSelector.isExternalRepo( getRepo( "foo", "ftp://somehost" ) ) );
+ assertTrue( DefaultMirrorSelector.isExternalRepo( getRepo( "foo", "http://192.168.101.1" ) ) );
+ assertTrue( DefaultMirrorSelector.isExternalRepo( getRepo( "foo", "http://" ) ) );
+ // these are local
+ assertFalse( DefaultMirrorSelector.isExternalRepo( getRepo( "foo", "http://localhost:8080" ) ) );
+ assertFalse( DefaultMirrorSelector.isExternalRepo( getRepo( "foo", "http://127.0.0.1:9090" ) ) );
+ assertFalse( DefaultMirrorSelector.isExternalRepo( getRepo( "foo", "file://localhost/somepath" ) ) );
+ assertFalse( DefaultMirrorSelector.isExternalRepo( getRepo( "foo", "file://localhost/D:/somepath" ) ) );
+ assertFalse( DefaultMirrorSelector.isExternalRepo( getRepo( "foo", "http://localhost" ) ) );
+ assertFalse( DefaultMirrorSelector.isExternalRepo( getRepo( "foo", "http://127.0.0.1" ) ) );
+ assertFalse( DefaultMirrorSelector.isExternalRepo( getRepo( "foo", "file:///somepath" ) ) );
+ assertFalse( DefaultMirrorSelector.isExternalRepo( getRepo( "foo", "file://D:/somepath" ) ) );
+
+ // not a proper url so returns false;
+ assertFalse( DefaultMirrorSelector.isExternalRepo( getRepo( "foo", "192.168.101.1" ) ) );
+ assertFalse( DefaultMirrorSelector.isExternalRepo( getRepo( "foo", "" ) ) );
+ }
+
+ public void testMirrorLookup()
+ {
+ Mirror mirrorA = newMirror( "a", "a", "http://a" );
+ Mirror mirrorB = newMirror( "b", "b", "http://b" );
+
+ List<Mirror> mirrors = Arrays.asList( mirrorA, mirrorB );
+
+ assertSame( mirrorA, mirrorSelector.getMirror( getRepo( "a", "http://a.a" ), mirrors ) );
+
+ assertSame( mirrorB, mirrorSelector.getMirror( getRepo( "b", "http://a.a" ), mirrors ) );
+
+ assertNull( mirrorSelector.getMirror( getRepo( "c", "http://c.c" ), mirrors ) );
+ }
+
+ public void testMirrorWildcardLookup()
+ {
+ Mirror mirrorA = newMirror( "a", "a", "http://a" );
+ Mirror mirrorB = newMirror( "b", "b", "http://b" );
+ Mirror mirrorC = newMirror( "c", "*", "http://wildcard" );
+
+ List<Mirror> mirrors = Arrays.asList( mirrorA, mirrorB, mirrorC );
+
+ assertSame( mirrorA, mirrorSelector.getMirror( getRepo( "a", "http://a.a" ), mirrors ) );
+
+ assertSame( mirrorB, mirrorSelector.getMirror( getRepo( "b", "http://a.a" ), mirrors ) );
+
+ assertSame( mirrorC, mirrorSelector.getMirror( getRepo( "c", "http://c.c" ), mirrors ) );
+ }
+
+ public void testMirrorStopOnFirstMatch()
+ {
+ // exact matches win first
+ Mirror mirrorA2 = newMirror( "a2", "a,b", "http://a2" );
+ Mirror mirrorA = newMirror( "a", "a", "http://a" );
+ // make sure repeated entries are skipped
+ Mirror mirrorA3 = newMirror( "a", "a", "http://a3" );
+
+ Mirror mirrorB = newMirror( "b", "b", "http://b" );
+ Mirror mirrorC = newMirror( "c", "d,e", "http://de" );
+ Mirror mirrorC2 = newMirror( "c", "*", "http://wildcard" );
+ Mirror mirrorC3 = newMirror( "c", "e,f", "http://ef" );
+
+ List<Mirror> mirrors = Arrays.asList( mirrorA2, mirrorA, mirrorA3, mirrorB, mirrorC, mirrorC2, mirrorC3 );
+
+ assertSame( mirrorA, mirrorSelector.getMirror( getRepo( "a", "http://a.a" ), mirrors ) );
+
+ assertSame( mirrorB, mirrorSelector.getMirror( getRepo( "b", "http://a.a" ), mirrors ) );
+
+ assertSame( mirrorC2, mirrorSelector.getMirror( getRepo( "c", "http://c.c" ), mirrors ) );
+
+ assertSame( mirrorC, mirrorSelector.getMirror( getRepo( "d", "http://d" ), mirrors ) );
+
+ assertSame( mirrorC, mirrorSelector.getMirror( getRepo( "e", "http://e" ), mirrors ) );
+
+ assertSame( mirrorC2, mirrorSelector.getMirror( getRepo( "f", "http://f" ), mirrors ) );
+ }
+
+ public void testPatterns()
+ {
+ assertTrue( DefaultMirrorSelector.matchPattern( getRepo( "a" ), "*" ) );
+ assertTrue( DefaultMirrorSelector.matchPattern( getRepo( "a" ), "*," ) );
+ assertTrue( DefaultMirrorSelector.matchPattern( getRepo( "a" ), ",*," ) );
+ assertTrue( DefaultMirrorSelector.matchPattern( getRepo( "a" ), "*," ) );
+
+ assertTrue( DefaultMirrorSelector.matchPattern( getRepo( "a" ), "a" ) );
+ assertTrue( DefaultMirrorSelector.matchPattern( getRepo( "a" ), "a," ) );
+ assertTrue( DefaultMirrorSelector.matchPattern( getRepo( "a" ), ",a," ) );
+ assertTrue( DefaultMirrorSelector.matchPattern( getRepo( "a" ), "a," ) );
+
+ assertFalse( DefaultMirrorSelector.matchPattern( getRepo( "b" ), "a" ) );
+ assertFalse( DefaultMirrorSelector.matchPattern( getRepo( "b" ), "a," ) );
+ assertFalse( DefaultMirrorSelector.matchPattern( getRepo( "b" ), ",a" ) );
+ assertFalse( DefaultMirrorSelector.matchPattern( getRepo( "b" ), ",a," ) );
+
+ assertTrue( DefaultMirrorSelector.matchPattern( getRepo( "a" ), "a,b" ) );
+ assertTrue( DefaultMirrorSelector.matchPattern( getRepo( "b" ), "a,b" ) );
+
+ assertFalse( DefaultMirrorSelector.matchPattern( getRepo( "c" ), "a,b" ) );
+
+ assertTrue( DefaultMirrorSelector.matchPattern( getRepo( "a" ), "*" ) );
+ assertTrue( DefaultMirrorSelector.matchPattern( getRepo( "a" ), "*,b" ) );
+ assertTrue( DefaultMirrorSelector.matchPattern( getRepo( "a" ), "*,!b" ) );
+
+ assertFalse( DefaultMirrorSelector.matchPattern( getRepo( "a" ), "*,!a" ) );
+ assertFalse( DefaultMirrorSelector.matchPattern( getRepo( "a" ), "!a,*" ) );
+
+ assertTrue( DefaultMirrorSelector.matchPattern( getRepo( "c" ), "*,!a" ) );
+ assertTrue( DefaultMirrorSelector.matchPattern( getRepo( "c" ), "!a,*" ) );
+
+ assertFalse( DefaultMirrorSelector.matchPattern( getRepo( "c" ), "!a,!c" ) );
+ assertFalse( DefaultMirrorSelector.matchPattern( getRepo( "d" ), "!a,!c*" ) );
+ }
+
+ public void testPatternsWithExternal()
+ {
+ assertTrue( DefaultMirrorSelector.matchPattern( getRepo( "a", "http://localhost" ), "*" ) );
+ assertFalse( DefaultMirrorSelector.matchPattern( getRepo( "a", "http://localhost" ), "external:*" ) );
+
+ assertTrue( DefaultMirrorSelector.matchPattern( getRepo( "a", "http://localhost" ), "external:*,a" ) );
+ assertFalse( DefaultMirrorSelector.matchPattern( getRepo( "a", "http://localhost" ), "external:*,!a" ) );
+ assertTrue( DefaultMirrorSelector.matchPattern( getRepo( "a", "http://localhost" ), "a,external:*" ) );
+ assertFalse( DefaultMirrorSelector.matchPattern( getRepo( "a", "http://localhost" ), "!a,external:*" ) );
+
+ assertFalse( DefaultMirrorSelector.matchPattern( getRepo( "c", "http://localhost" ), "!a,external:*" ) );
+ assertTrue( DefaultMirrorSelector.matchPattern( getRepo( "c", "http://somehost" ), "!a,external:*" ) );
+ }
+
+ public void testLayoutPattern()
+ {
+ assertTrue( DefaultMirrorSelector.matchesLayout( "default", null ) );
+ assertTrue( DefaultMirrorSelector.matchesLayout( "default", "" ) );
+ assertTrue( DefaultMirrorSelector.matchesLayout( "default", "*" ) );
+
+ assertTrue( DefaultMirrorSelector.matchesLayout( "default", "default" ) );
+ assertFalse( DefaultMirrorSelector.matchesLayout( "default", "legacy" ) );
+
+ assertTrue( DefaultMirrorSelector.matchesLayout( "default", "legacy,default" ) );
+ assertTrue( DefaultMirrorSelector.matchesLayout( "default", "default,legacy" ) );
+
+ assertFalse( DefaultMirrorSelector.matchesLayout( "default", "legacy,!default" ) );
+ assertFalse( DefaultMirrorSelector.matchesLayout( "default", "!default,legacy" ) );
+
+ assertFalse( DefaultMirrorSelector.matchesLayout( "default", "*,!default" ) );
+ assertFalse( DefaultMirrorSelector.matchesLayout( "default", "!default,*" ) );
+ }
+
+ public void testMirrorLayoutConsideredForMatching()
+ {
+ ArtifactRepository repo = getRepo( "a" );
+
+ Mirror mirrorA = newMirror( "a", "a", null, "http://a" );
+ Mirror mirrorB = newMirror( "b", "a", "p2", "http://b" );
+
+ Mirror mirrorC = newMirror( "c", "*", null, "http://c" );
+ Mirror mirrorD = newMirror( "d", "*", "p2", "http://d" );
+
+ assertSame( mirrorA, mirrorSelector.getMirror( repo, Arrays.asList( mirrorA ) ) );
+ assertNull( mirrorSelector.getMirror( repo, Arrays.asList( mirrorB ) ) );
+
+ assertSame( mirrorC, mirrorSelector.getMirror( repo, Arrays.asList( mirrorC ) ) );
+ assertNull( mirrorSelector.getMirror( repo, Arrays.asList( mirrorD ) ) );
+ }
+
+ /**
+ * Build an ArtifactRepository object.
+ *
+ * @param id
+ * @param url
+ * @return
+ */
+ private ArtifactRepository getRepo( String id, String url )
+ {
+ return repositorySystem.createArtifactRepository( id, url, new DefaultRepositoryLayout(), null, null );
+ }
+
+ /**
+ * Build an ArtifactRepository object.
+ *
+ * @param id
+ * @return
+ */
+ private ArtifactRepository getRepo( String id )
+ {
+ return getRepo( id, "http://something" );
+ }
+
+ private Mirror newMirror( String id, String mirrorOf, String url )
+ {
+ return newMirror( id, mirrorOf, null, url );
+ }
+
+ private Mirror newMirror( String id, String mirrorOf, String layouts, String url )
+ {
+ Mirror mirror = new Mirror();
+
+ mirror.setId( id );
+ mirror.setMirrorOf( mirrorOf );
+ mirror.setMirrorOfLayouts( layouts );
+ mirror.setUrl( url );
+
+ return mirror;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/legacy/DefaultUpdateCheckManagerTest.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/legacy/DefaultUpdateCheckManagerTest.java
new file mode 100644
index 00000000..1c5f34c3
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/legacy/DefaultUpdateCheckManagerTest.java
@@ -0,0 +1,240 @@
+package org.apache.maven.repository.legacy;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+
+import org.apache.maven.artifact.AbstractArtifactComponentTestCase;
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.factory.ArtifactFactory;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.repository.metadata.ArtifactRepositoryMetadata;
+import org.apache.maven.artifact.repository.metadata.RepositoryMetadata;
+import org.apache.maven.repository.legacy.DefaultUpdateCheckManager;
+import org.codehaus.plexus.logging.Logger;
+import org.codehaus.plexus.logging.console.ConsoleLogger;
+
+public class DefaultUpdateCheckManagerTest
+ extends AbstractArtifactComponentTestCase
+{
+
+ DefaultUpdateCheckManager updateCheckManager;
+
+ @Override
+ protected String component()
+ {
+ return "updateCheckManager";
+ }
+
+ @Override
+ protected void setUp()
+ throws Exception
+ {
+ super.setUp();
+
+ updateCheckManager = new DefaultUpdateCheckManager( new ConsoleLogger( Logger.LEVEL_DEBUG, "test" ) );
+ }
+
+ public void testArtifact() throws Exception
+ {
+ ArtifactRepository remoteRepository = remoteRepository();
+
+ ArtifactRepository localRepository = localRepository();
+
+ Artifact a = createArtifact( "a", "0.0.1-SNAPSHOT" );
+ File file = new File( localRepository.getBasedir(),
+ localRepository.pathOf( a ) );
+ file.delete();
+ a.setFile( file );
+
+ File touchFile = updateCheckManager.getTouchfile( a );
+ touchFile.delete();
+
+ assertTrue( updateCheckManager.isUpdateRequired( a, remoteRepository ) );
+
+ file.getParentFile().mkdirs();
+ file.createNewFile();
+ updateCheckManager.touch( a, remoteRepository, null );
+
+ assertFalse( updateCheckManager.isUpdateRequired( a, remoteRepository ) );
+
+ assertNull( updateCheckManager.readLastUpdated( touchFile,
+ updateCheckManager.getRepositoryKey( remoteRepository ) ) );
+
+ assertFalse( updateCheckManager.getTouchfile( a ).exists() );
+ }
+
+ public void testMissingArtifact()
+ throws Exception
+ {
+ ArtifactRepository remoteRepository = remoteRepository();
+
+ ArtifactRepository localRepository = localRepository();
+
+ Artifact a = createArtifact( "a", "0.0.1-SNAPSHOT" );
+ File file = new File( localRepository.getBasedir(),
+ localRepository.pathOf( a ) );
+ file.delete();
+ a.setFile( file );
+
+ File touchFile = updateCheckManager.getTouchfile( a );
+ touchFile.delete();
+
+ assertTrue( updateCheckManager.isUpdateRequired( a, remoteRepository ) );
+
+ updateCheckManager.touch( a, remoteRepository, null );
+
+ assertFalse( updateCheckManager.isUpdateRequired( a, remoteRepository ) );
+
+ assertFalse( file.exists() );
+ assertNotNull( updateCheckManager.readLastUpdated( touchFile,
+ updateCheckManager.getRepositoryKey( remoteRepository ) ) );
+ }
+
+ public void testPom() throws Exception
+ {
+ ArtifactRepository remoteRepository = remoteRepository();
+
+ ArtifactRepository localRepository = localRepository();
+
+ Artifact a = createArtifact( "a", "0.0.1", "pom" );
+ File file = new File( localRepository.getBasedir(),
+ localRepository.pathOf( a ) );
+ file.delete();
+ a.setFile( file );
+
+ File touchFile = updateCheckManager.getTouchfile( a );
+ touchFile.delete();
+
+ assertTrue( updateCheckManager.isUpdateRequired( a, remoteRepository ) );
+
+ file.getParentFile().mkdirs();
+ file.createNewFile();
+ updateCheckManager.touch( a, remoteRepository, null );
+
+ assertFalse( updateCheckManager.isUpdateRequired( a, remoteRepository ) );
+
+ assertNull( updateCheckManager.readLastUpdated( touchFile,
+ updateCheckManager.getRepositoryKey( remoteRepository ) ) );
+
+ assertFalse( updateCheckManager.getTouchfile( a ).exists() );
+ }
+
+ public void testMissingPom()
+ throws Exception
+ {
+ ArtifactRepository remoteRepository = remoteRepository();
+
+ ArtifactRepository localRepository = localRepository();
+
+ Artifact a = createArtifact( "a", "0.0.1", "pom" );
+ File file = new File( localRepository.getBasedir(),
+ localRepository.pathOf( a ) );
+ file.delete();
+ a.setFile( file );
+
+ File touchFile = updateCheckManager.getTouchfile( a );
+ touchFile.delete();
+
+ assertTrue( updateCheckManager.isUpdateRequired( a, remoteRepository ) );
+
+ updateCheckManager.touch( a, remoteRepository, null );
+
+ assertFalse( updateCheckManager.isUpdateRequired( a, remoteRepository ) );
+
+ assertFalse( file.exists() );
+ assertNotNull( updateCheckManager.readLastUpdated( touchFile,
+ updateCheckManager.getRepositoryKey( remoteRepository ) ) );
+ }
+
+ public void testMetadata() throws Exception
+ {
+ ArtifactRepository remoteRepository = remoteRepository();
+
+ ArtifactRepository localRepository = localRepository();
+
+ Artifact a = createRemoteArtifact( "a", "0.0.1-SNAPSHOT" );
+ RepositoryMetadata metadata = new ArtifactRepositoryMetadata( a );
+
+ File file = new File( localRepository.getBasedir(),
+ localRepository.pathOfLocalRepositoryMetadata( metadata, localRepository ) );
+ file.delete();
+
+ File touchFile = updateCheckManager.getTouchfile( metadata, file );
+ touchFile.delete();
+
+ assertTrue( updateCheckManager.isUpdateRequired( metadata, remoteRepository, file ) );
+
+ file.getParentFile().mkdirs();
+ file.createNewFile();
+ updateCheckManager.touch( metadata, remoteRepository, file );
+
+ assertFalse( updateCheckManager.isUpdateRequired( metadata, remoteRepository, file ) );
+
+ assertNotNull( updateCheckManager.readLastUpdated( touchFile, updateCheckManager.getMetadataKey( remoteRepository, file ) ) );
+ }
+
+ public void testMissingMetadata() throws Exception
+ {
+ ArtifactRepository remoteRepository = remoteRepository();
+
+ ArtifactRepository localRepository = localRepository();
+
+ Artifact a = createRemoteArtifact( "a", "0.0.1-SNAPSHOT" );
+ RepositoryMetadata metadata = new ArtifactRepositoryMetadata( a );
+
+ File file = new File( localRepository.getBasedir(),
+ localRepository.pathOfLocalRepositoryMetadata( metadata, localRepository ) );
+ file.delete();
+
+ File touchFile = updateCheckManager.getTouchfile( metadata, file );
+ touchFile.delete();
+
+ assertTrue( updateCheckManager.isUpdateRequired( metadata, remoteRepository, file ) );
+
+ updateCheckManager.touch( metadata, remoteRepository, file );
+
+ assertFalse( updateCheckManager.isUpdateRequired( metadata, remoteRepository, file ) );
+
+ assertNotNull( updateCheckManager.readLastUpdated( touchFile, updateCheckManager.getMetadataKey( remoteRepository, file ) ) );
+ }
+
+ public void testArtifactTouchFileName() throws Exception
+ {
+ ArtifactFactory artifactFactory = (ArtifactFactory) lookup( ArtifactFactory.ROLE );
+
+ ArtifactRepository localRepository = localRepository();
+
+ Artifact a = artifactFactory.createArtifactWithClassifier( "groupdId", "a", "0.0.1-SNAPSHOT", "jar", null );
+ File file = new File( localRepository.getBasedir(),
+ localRepository.pathOf( a ) );
+ a.setFile( file );
+
+ assertEquals( "a-0.0.1-SNAPSHOT.jar.lastUpdated", updateCheckManager.getTouchfile( a ).getName() );
+
+ a = artifactFactory.createArtifactWithClassifier( "groupdId", "a", "0.0.1-SNAPSHOT", "jar", "classifier" );
+ file = new File( localRepository.getBasedir(),
+ localRepository.pathOf( a ) );
+ a.setFile( file );
+
+ assertEquals( "a-0.0.1-SNAPSHOT-classifier.jar.lastUpdated", updateCheckManager.getTouchfile( a ).getName() );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/legacy/DefaultWagonManagerTest.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/legacy/DefaultWagonManagerTest.java
new file mode 100644
index 00000000..068c0e0a
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/legacy/DefaultWagonManagerTest.java
@@ -0,0 +1,422 @@
+package org.apache.maven.repository.legacy;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.DefaultArtifact;
+import org.apache.maven.artifact.factory.ArtifactFactory;
+import org.apache.maven.artifact.metadata.ArtifactMetadata;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.repository.legacy.repository.ArtifactRepositoryFactory;
+import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy;
+import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout;
+import org.apache.maven.artifact.repository.layout.DefaultRepositoryLayout;
+import org.apache.maven.artifact.versioning.VersionRange;
+import org.apache.maven.wagon.ResourceDoesNotExistException;
+import org.apache.maven.wagon.TransferFailedException;
+import org.apache.maven.wagon.UnsupportedProtocolException;
+import org.apache.maven.wagon.Wagon;
+import org.apache.maven.wagon.authorization.AuthorizationException;
+import org.apache.maven.wagon.events.TransferEvent;
+import org.apache.maven.wagon.events.TransferListener;
+import org.apache.maven.wagon.observers.AbstractTransferListener;
+import org.apache.maven.wagon.observers.Debug;
+import org.codehaus.plexus.PlexusTestCase;
+import org.codehaus.plexus.util.FileUtils;
+
+/**
+ * @author <a href="michal.maczka@dimatics.com">Michal Maczka</a>
+ */
+public class DefaultWagonManagerTest
+ extends PlexusTestCase
+{
+ private DefaultWagonManager wagonManager;
+
+ private TransferListener transferListener = new Debug();
+
+ private ArtifactFactory artifactFactory;
+
+ private ArtifactRepositoryFactory artifactRepositoryFactory;
+
+ protected void setUp()
+ throws Exception
+ {
+ super.setUp();
+ wagonManager = (DefaultWagonManager) lookup( WagonManager.class );
+ artifactFactory = lookup( ArtifactFactory.class );
+ artifactRepositoryFactory = lookup( ArtifactRepositoryFactory.class );
+ }
+
+ @Override
+ protected void tearDown()
+ throws Exception
+ {
+ wagonManager = null;
+ artifactFactory = null;
+ super.tearDown();
+ }
+
+ public void testUnnecessaryRepositoryLookup()
+ throws Exception
+ {
+ Artifact artifact = createTestPomArtifact( "target/test-data/get-missing-pom" );
+
+ List<ArtifactRepository> repos = new ArrayList<ArtifactRepository>();
+ repos.add( artifactRepositoryFactory.createArtifactRepository( "repo1", "string://url1",
+ new ArtifactRepositoryLayoutStub(), null, null ) );
+ repos.add( artifactRepositoryFactory.createArtifactRepository( "repo2", "string://url2",
+ new ArtifactRepositoryLayoutStub(), null, null ) );
+
+ StringWagon wagon = (StringWagon) wagonManager.getWagon( "string" );
+ wagon.addExpectedContent( repos.get( 0 ).getLayout().pathOf( artifact ), "expected" );
+ wagon.addExpectedContent( repos.get( 1 ).getLayout().pathOf( artifact ), "expected" );
+
+ class TransferListener
+ extends AbstractTransferListener
+ {
+ public List<TransferEvent> events = new ArrayList<TransferEvent>();
+
+ @Override
+ public void transferInitiated( TransferEvent transferEvent )
+ {
+ events.add( transferEvent );
+ }
+ }
+
+ TransferListener listener = new TransferListener();
+ wagonManager.getArtifact( artifact, repos, listener, false );
+ assertEquals( 1, listener.events.size() );
+ }
+
+ public void testGetMissingJar() throws TransferFailedException, UnsupportedProtocolException, IOException
+ {
+ Artifact artifact = createTestArtifact( "target/test-data/get-missing-jar", "jar" );
+
+ ArtifactRepository repo = createStringRepo();
+
+ try
+ {
+ wagonManager.getArtifact( artifact, repo, null, false );
+
+ fail();
+ }
+ catch ( ResourceDoesNotExistException e )
+ {
+ assertTrue( true );
+ }
+
+ assertFalse( artifact.getFile().exists() );
+ }
+
+ public void testGetMissingJarForced() throws TransferFailedException, UnsupportedProtocolException, IOException
+ {
+ Artifact artifact = createTestArtifact( "target/test-data/get-missing-jar", "jar" );
+
+ ArtifactRepository repo = createStringRepo();
+
+ try
+ {
+ wagonManager.getArtifact( artifact, repo, null, false );
+
+ fail();
+ }
+ catch ( ResourceDoesNotExistException e )
+ {
+ assertTrue( true );
+ }
+
+ assertFalse( artifact.getFile().exists() );
+ }
+
+ public void testGetRemoteJar()
+ throws TransferFailedException, ResourceDoesNotExistException, UnsupportedProtocolException, IOException,
+ AuthorizationException
+ {
+ Artifact artifact = createTestArtifact( "target/test-data/get-remote-jar", "jar" );
+
+ ArtifactRepository repo = createStringRepo();
+
+ StringWagon wagon = (StringWagon) wagonManager.getWagon( "string" );
+ wagon.addExpectedContent( repo.getLayout().pathOf( artifact ), "expected" );
+
+ wagonManager.getArtifact( artifact, repo, null, false );
+
+ assertTrue( artifact.getFile().exists() );
+ assertEquals( "expected", FileUtils.fileRead( artifact.getFile(), "UTF-8" ) );
+ }
+
+ private Artifact createTestPomArtifact( String directory )
+ throws IOException
+ {
+ File testData = getTestFile( directory );
+ FileUtils.deleteDirectory( testData );
+ testData.mkdirs();
+
+ Artifact artifact = artifactFactory.createProjectArtifact( "test", "test", "1.0" );
+ artifact.setFile( new File( testData, "test-1.0.pom" ) );
+ assertFalse( artifact.getFile().exists() );
+ return artifact;
+ }
+
+ private Artifact createTestArtifact( String directory, String type )
+ throws IOException
+ {
+ return createTestArtifact( directory, "1.0", type );
+ }
+
+ private Artifact createTestArtifact( String directory, String version, String type )
+ throws IOException
+ {
+ File testData = getTestFile( directory );
+ FileUtils.deleteDirectory( testData );
+ testData.mkdirs();
+
+ Artifact artifact = artifactFactory.createBuildArtifact( "test", "test", version, type );
+ artifact.setFile( new File( testData, "test-" + version + "." + artifact.getArtifactHandler().getExtension() ) );
+ assertFalse( artifact.getFile().exists() );
+ return artifact;
+ }
+
+ private ArtifactRepository createStringRepo()
+ {
+ return artifactRepositoryFactory.createArtifactRepository( "id", "string://url", new ArtifactRepositoryLayoutStub(), null, null );
+ }
+
+ /**
+ * Build an ArtifactRepository object.
+ *
+ * @param id
+ * @param url
+ * @return
+ */
+ private ArtifactRepository getRepo( String id, String url )
+ {
+ return artifactRepositoryFactory.createArtifactRepository( id, url, new DefaultRepositoryLayout(), null, null );
+ }
+
+ /**
+ * Build an ArtifactRepository object.
+ *
+ * @param id
+ * @return
+ */
+ private ArtifactRepository getRepo( String id )
+ {
+ return getRepo( id, "http://something" );
+ }
+
+ public void testDefaultWagonManager()
+ throws Exception
+ {
+ assertWagon( "a" );
+
+ assertWagon( "b" );
+
+ assertWagon( "c" );
+
+ assertWagon( "string" );
+
+ try
+ {
+ assertWagon( "d" );
+
+ fail( "Expected :" + UnsupportedProtocolException.class.getName() );
+ }
+ catch ( UnsupportedProtocolException e )
+ {
+ // ok
+ assertTrue( true );
+ }
+ }
+
+ /**
+ * Check that transfer listeners are properly removed after getArtifact and putArtifact
+ */
+ public void testWagonTransferListenerRemovedAfterGetArtifactAndPutArtifact()
+ throws Exception
+ {
+ Artifact artifact = createTestArtifact( "target/test-data/transfer-listener", "jar" );
+ ArtifactRepository repo = createStringRepo();
+ StringWagon wagon = (StringWagon) wagonManager.getWagon( "string" );
+ wagon.addExpectedContent( repo.getLayout().pathOf( artifact ), "expected" );
+
+ /* getArtifact */
+ assertFalse( "Transfer listener is registered before test",
+ wagon.getTransferEventSupport().hasTransferListener( transferListener ) );
+ wagonManager.getArtifact( artifact, repo, transferListener, false );
+ assertFalse( "Transfer listener still registered after getArtifact",
+ wagon.getTransferEventSupport().hasTransferListener( transferListener ) );
+
+ /* putArtifact */
+ File sampleFile = getTestFile( "target/test-file" );
+ FileUtils.fileWrite( sampleFile.getAbsolutePath(), "sample file" );
+
+ assertFalse( "Transfer listener is registered before test", wagon.getTransferEventSupport().hasTransferListener( transferListener ) );
+ wagonManager.putArtifact( sampleFile, artifact, repo, transferListener );
+ assertFalse( "Transfer listener still registered after putArtifact", wagon.getTransferEventSupport().hasTransferListener( transferListener ) );
+ }
+
+ /**
+ * Checks the verification of checksums.
+ */
+ public void xtestChecksumVerification()
+ throws Exception
+ {
+ ArtifactRepositoryPolicy policy = new ArtifactRepositoryPolicy( true, ArtifactRepositoryPolicy.UPDATE_POLICY_ALWAYS, ArtifactRepositoryPolicy.CHECKSUM_POLICY_FAIL );
+
+ ArtifactRepository repo = artifactRepositoryFactory.createArtifactRepository( "id", "string://url", new ArtifactRepositoryLayoutStub(), policy, policy );
+
+ Artifact artifact =
+ new DefaultArtifact( "sample.group", "sample-art", VersionRange.createFromVersion( "1.0" ), "scope",
+ "jar", "classifier", null );
+ artifact.setFile( getTestFile( "target/sample-art" ) );
+
+ StringWagon wagon = (StringWagon) wagonManager.getWagon( "string" );
+
+ wagon.clearExpectedContent();
+ wagon.addExpectedContent( "path", "lower-case-checksum" );
+ wagon.addExpectedContent( "path.sha1", "2a25dc564a3b34f68237fc849066cbc7bb7a36a1" );
+
+ try
+ {
+ wagonManager.getArtifact( artifact, repo, null, false );
+ }
+ catch ( ChecksumFailedException e )
+ {
+ fail( "Checksum verification did not pass: " + e.getMessage() );
+ }
+
+ wagon.clearExpectedContent();
+ wagon.addExpectedContent( "path", "upper-case-checksum" );
+ wagon.addExpectedContent( "path.sha1", "B7BB97D7D0B9244398D9B47296907F73313663E6" );
+
+ try
+ {
+ wagonManager.getArtifact( artifact, repo, null, false );
+ }
+ catch ( ChecksumFailedException e )
+ {
+ fail( "Checksum verification did not pass: " + e.getMessage() );
+ }
+
+ wagon.clearExpectedContent();
+ wagon.addExpectedContent( "path", "expected-failure" );
+ wagon.addExpectedContent( "path.sha1", "b7bb97d7d0b9244398d9b47296907f73313663e6" );
+
+ try
+ {
+ wagonManager.getArtifact( artifact, repo, null, false );
+ fail( "Checksum verification did not fail" );
+ }
+ catch ( ChecksumFailedException e )
+ {
+ // expected
+ }
+
+ wagon.clearExpectedContent();
+ wagon.addExpectedContent( "path", "lower-case-checksum" );
+ wagon.addExpectedContent( "path.md5", "50b2cf50a103a965efac62b983035cac" );
+
+ try
+ {
+ wagonManager.getArtifact( artifact, repo, null, false );
+ }
+ catch ( ChecksumFailedException e )
+ {
+ fail( "Checksum verification did not pass: " + e.getMessage() );
+ }
+
+ wagon.clearExpectedContent();
+ wagon.addExpectedContent( "path", "upper-case-checksum" );
+ wagon.addExpectedContent( "path.md5", "842F568FCCFEB7E534DC72133D42FFDC" );
+
+ try
+ {
+ wagonManager.getArtifact( artifact, repo, null, false );
+ }
+ catch ( ChecksumFailedException e )
+ {
+ fail( "Checksum verification did not pass: " + e.getMessage() );
+ }
+
+ wagon.clearExpectedContent();
+ wagon.addExpectedContent( "path", "expected-failure" );
+ wagon.addExpectedContent( "path.md5", "b7bb97d7d0b9244398d9b47296907f73313663e6" );
+
+ try
+ {
+ wagonManager.getArtifact( artifact, repo, null, false );
+ fail( "Checksum verification did not fail" );
+ }
+ catch ( ChecksumFailedException e )
+ {
+ // expected
+ }
+ }
+
+ public void testPerLookupInstantiation()
+ throws Exception
+ {
+ String protocol = "perlookup";
+
+ Wagon one = wagonManager.getWagon( protocol );
+ Wagon two = wagonManager.getWagon( protocol );
+
+ assertNotSame( one, two );
+ }
+
+ private void assertWagon( String protocol )
+ throws Exception
+ {
+ Wagon wagon = wagonManager.getWagon( protocol );
+
+ assertNotNull( "Check wagon, protocol=" + protocol, wagon );
+ }
+
+ private final class ArtifactRepositoryLayoutStub
+ implements ArtifactRepositoryLayout
+ {
+ public String getId()
+ {
+ return "test";
+ }
+
+ public String pathOfRemoteRepositoryMetadata( ArtifactMetadata metadata )
+ {
+ return "path";
+ }
+
+ public String pathOfLocalRepositoryMetadata( ArtifactMetadata metadata, ArtifactRepository repository )
+ {
+ return "path";
+ }
+
+ public String pathOf( Artifact artifact )
+ {
+ return "path";
+ }
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/legacy/LegacyRepositorySystemTest.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/legacy/LegacyRepositorySystemTest.java
new file mode 100644
index 00000000..f34c05fb
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/legacy/LegacyRepositorySystemTest.java
@@ -0,0 +1,88 @@
+package org.apache.maven.repository.legacy;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+import java.io.File;
+import java.util.Arrays;
+
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.repository.Authentication;
+import org.apache.maven.repository.RepositorySystem;
+import org.apache.maven.settings.Server;
+import org.codehaus.plexus.ContainerConfiguration;
+import org.codehaus.plexus.PlexusConstants;
+import org.codehaus.plexus.PlexusTestCase;
+
+/**
+ * Tests {@link LegacyRepositorySystem}.
+ *
+ * @author Benjamin Bentmann
+ */
+public class LegacyRepositorySystemTest
+ extends PlexusTestCase
+{
+ private RepositorySystem repositorySystem;
+
+ @Override
+ protected void customizeContainerConfiguration( ContainerConfiguration containerConfiguration )
+ {
+ super.customizeContainerConfiguration( containerConfiguration );
+ containerConfiguration.setAutoWiring( true );
+ containerConfiguration.setClassPathScanning( PlexusConstants.SCANNING_INDEX );
+ }
+
+ @Override
+ protected void setUp()
+ throws Exception
+ {
+ super.setUp();
+ repositorySystem = lookup( RepositorySystem.class, "default" );
+ }
+
+ @Override
+ protected void tearDown()
+ throws Exception
+ {
+ repositorySystem = null;
+ super.tearDown();
+ }
+
+ public void testThatLocalRepositoryWithSpacesIsProperlyHandled()
+ throws Exception
+ {
+ File basedir = new File( "target/spacy path" ).getAbsoluteFile();
+ ArtifactRepository repo = repositorySystem.createLocalRepository( basedir );
+ assertEquals( basedir, new File( repo.getBasedir() ) );
+ }
+
+ public void testAuthenticationHandling()
+ throws Exception
+ {
+ Server server = new Server();
+ server.setId( "repository" );
+ server.setUsername( "jason" );
+ server.setPassword( "abc123" );
+
+ ArtifactRepository repository =
+ repositorySystem.createArtifactRepository( "repository", "http://foo", null, null, null );
+ repositorySystem.injectAuthentication( Arrays.asList( repository ), Arrays.asList( server ) );
+ Authentication authentication = repository.getAuthentication();
+ assertNotNull( authentication );
+ assertEquals( "jason", authentication.getUsername() );
+ assertEquals( "abc123", authentication.getPassword() );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/legacy/PerLookupWagon.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/legacy/PerLookupWagon.java
new file mode 100644
index 00000000..051f3e46
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/legacy/PerLookupWagon.java
@@ -0,0 +1,38 @@
+package org.apache.maven.repository.legacy;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.wagon.Wagon;
+import org.codehaus.plexus.component.annotations.Component;
+
+/**
+ * Wagon with per-lookup instantiation strategy.
+ */
+@Component( role = Wagon.class, hint = "perlookup", instantiationStrategy = "per-lookup" )
+public class PerLookupWagon
+ extends WagonMock
+{
+
+ public String[] getSupportedProtocols()
+ {
+ return new String[] { "perlookup" };
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/legacy/StringWagon.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/legacy/StringWagon.java
new file mode 100644
index 00000000..d0325db4
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/legacy/StringWagon.java
@@ -0,0 +1,107 @@
+package org.apache.maven.repository.legacy;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.UnsupportedEncodingException;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.maven.wagon.ConnectionException;
+import org.apache.maven.wagon.InputData;
+import org.apache.maven.wagon.OutputData;
+import org.apache.maven.wagon.ResourceDoesNotExistException;
+import org.apache.maven.wagon.StreamWagon;
+import org.apache.maven.wagon.TransferFailedException;
+import org.apache.maven.wagon.Wagon;
+import org.apache.maven.wagon.authentication.AuthenticationException;
+import org.apache.maven.wagon.authorization.AuthorizationException;
+import org.apache.maven.wagon.resource.Resource;
+import org.codehaus.plexus.component.annotations.Component;
+
+@Component(role=Wagon.class,hint="string")
+public class StringWagon
+ extends StreamWagon
+{
+ private Map<String, String> expectedContent = new HashMap<String, String>();
+
+ public void addExpectedContent( String resourceName, String expectedContent )
+ {
+ this.expectedContent.put( resourceName, expectedContent );
+ }
+
+ public String[] getSupportedProtocols()
+ {
+ return new String[] { "string" };
+ }
+
+ @Override
+ public void closeConnection()
+ throws ConnectionException
+ {
+ }
+
+ @Override
+ public void fillInputData( InputData inputData )
+ throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException
+ {
+ Resource resource = inputData.getResource();
+
+ String content = expectedContent.get( resource.getName() );
+
+ if ( content != null )
+ {
+ resource.setContentLength( content.length() );
+ resource.setLastModified( System.currentTimeMillis() );
+
+ try
+ {
+ inputData.setInputStream( new ByteArrayInputStream( content.getBytes( "UTF-8" ) ) );
+ }
+ catch ( UnsupportedEncodingException e )
+ {
+ throw new Error( "broken JVM", e );
+ }
+ }
+ else
+ {
+ throw new ResourceDoesNotExistException( "No content provided for " + resource.getName() );
+ }
+ }
+
+ @Override
+ public void fillOutputData( OutputData outputData )
+ throws TransferFailedException
+ {
+ outputData.setOutputStream( new ByteArrayOutputStream() );
+ }
+
+ @Override
+ protected void openConnectionInternal()
+ throws ConnectionException, AuthenticationException
+ {
+ }
+
+ public void clearExpectedContent()
+ {
+ expectedContent.clear();
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/legacy/WagonA.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/legacy/WagonA.java
new file mode 100644
index 00000000..601eefac
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/legacy/WagonA.java
@@ -0,0 +1,39 @@
+package org.apache.maven.repository.legacy;
+
+import org.apache.maven.wagon.Wagon;
+import org.codehaus.plexus.component.annotations.Component;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Wagon for testing, for protocol <code>a</code>
+ *
+ * @author <a href="mailto:carlos@apache.org">Carlos Sanchez</a>
+ * @author <a href="mailto:jason@maven.org">Jason van Zyl</a>
+ */
+@Component(role=Wagon.class,hint="a")
+public class WagonA
+ extends WagonMock
+{
+ public String[] getSupportedProtocols()
+ {
+ return new String[]{ "a" };
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/legacy/WagonB.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/legacy/WagonB.java
new file mode 100644
index 00000000..ecaef642
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/legacy/WagonB.java
@@ -0,0 +1,39 @@
+package org.apache.maven.repository.legacy;
+
+import org.apache.maven.wagon.Wagon;
+import org.codehaus.plexus.component.annotations.Component;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Wagon for testing, for protocols <code>b1</code> and <code>b2</code>
+ *
+ * @author <a href="mailto:carlos@apache.org">Carlos Sanchez</a>
+ * @author <a href="mailto:jason@maven.org">Jason van Zyl</a>
+ */
+@Component(role=Wagon.class,hint="b")
+public class WagonB
+ extends WagonMock
+{
+ public String[] getSupportedProtocols()
+ {
+ return new String[]{ "b1", "b2" };
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/legacy/WagonC.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/legacy/WagonC.java
new file mode 100644
index 00000000..29316ed5
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/legacy/WagonC.java
@@ -0,0 +1,39 @@
+package org.apache.maven.repository.legacy;
+
+import org.apache.maven.wagon.Wagon;
+import org.codehaus.plexus.component.annotations.Component;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Wagon for testing, for protocol <code>c</code>
+ *
+ * @author <a href="mailto:carlos@apache.org">Carlos Sanchez</a>
+ * @author <a href="mailto:jason@maven.org">Jason van Zyl</a>
+ */
+@Component(role=Wagon.class,hint="c")
+public class WagonC
+ extends WagonMock
+{
+ public String[] getSupportedProtocols()
+ {
+ return new String[]{ "c" };
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/legacy/WagonMock.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/legacy/WagonMock.java
new file mode 100644
index 00000000..c5163609
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/legacy/WagonMock.java
@@ -0,0 +1,50 @@
+package org.apache.maven.repository.legacy;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.wagon.providers.file.FileWagon;
+
+/**
+ * Mock of a Wagon for testing
+ *
+ * @author <a href="mailto:carlos@apache.org">Carlos Sanchez</a>
+ */
+public class WagonMock
+ extends FileWagon
+{
+
+ /**
+ * A field that can be configured in the Wagon
+ *
+ * @component.configuration default="configurableField"
+ */
+ private String configurableField = null;
+
+ public void setConfigurableField( String configurableField )
+ {
+ this.configurableField = configurableField;
+ }
+
+ public String getConfigurableField()
+ {
+ return configurableField;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/legacy/resolver/DefaultArtifactCollectorTest.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/legacy/resolver/DefaultArtifactCollectorTest.java
new file mode 100644
index 00000000..58dd3fa2
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/legacy/resolver/DefaultArtifactCollectorTest.java
@@ -0,0 +1,984 @@
+package org.apache.maven.repository.legacy.resolver;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.factory.ArtifactFactory;
+import org.apache.maven.artifact.metadata.ArtifactMetadataRetrievalException;
+import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
+import org.apache.maven.artifact.metadata.ResolutionGroup;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.resolver.ArtifactResolutionException;
+import org.apache.maven.artifact.resolver.ArtifactResolutionResult;
+import org.apache.maven.artifact.resolver.CyclicDependencyException;
+import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
+import org.apache.maven.artifact.resolver.filter.ExclusionSetFilter;
+import org.apache.maven.artifact.resolver.filter.ScopeArtifactFilter;
+import org.apache.maven.artifact.versioning.ArtifactVersion;
+import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
+import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
+import org.apache.maven.artifact.versioning.OverConstrainedVersionException;
+import org.apache.maven.artifact.versioning.VersionRange;
+import org.apache.maven.repository.legacy.metadata.MetadataResolutionRequest;
+import org.codehaus.plexus.PlexusTestCase;
+
+/**
+ * Test the default artifact collector.
+ *
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ */
+public class DefaultArtifactCollectorTest
+ extends PlexusTestCase
+{
+ private LegacyArtifactCollector artifactCollector;
+
+ private ArtifactFactory artifactFactory;
+
+ private ArtifactSpec projectArtifact;
+
+ private Source source;
+
+ private static final String GROUP_ID = "test";
+
+ @Override
+ protected void setUp()
+ throws Exception
+ {
+ super.setUp();
+
+ source = new Source();
+ artifactFactory = (ArtifactFactory) lookup( ArtifactFactory.ROLE );
+ artifactCollector = lookup( LegacyArtifactCollector.class );
+
+ projectArtifact = createArtifactSpec( "project", "1.0", null );
+ }
+
+ @Override
+ protected void tearDown()
+ throws Exception
+ {
+ artifactCollector = null;
+ artifactFactory = null;
+ super.tearDown();
+ }
+
+ // works, but we don't fail on cycles presently
+ public void disabledtestCircularDependencyNotIncludingCurrentProject()
+ throws ArtifactResolutionException, InvalidVersionSpecificationException
+ {
+ ArtifactSpec a = createArtifactSpec( "a", "1.0" );
+ ArtifactSpec b = a.addDependency( "b", "1.0" );
+ b.addDependency( "a", "1.0" );
+ try
+ {
+ collect( a );
+ fail( "Should have failed on cyclic dependency not involving project" );
+ }
+ catch ( CyclicDependencyException expected )
+ {
+ assertTrue( true );
+ }
+ }
+
+ // works, but we don't fail on cycles presently
+ public void disabledtestCircularDependencyIncludingCurrentProject()
+ throws ArtifactResolutionException, InvalidVersionSpecificationException
+ {
+ ArtifactSpec a = createArtifactSpec( "a", "1.0" );
+ ArtifactSpec b = a.addDependency( "b", "1.0" );
+ b.addDependency( "project", "1.0" );
+ try
+ {
+ collect( a );
+ fail( "Should have failed on cyclic dependency involving project" );
+ }
+ catch ( CyclicDependencyException expected )
+ {
+ assertTrue( true );
+ }
+ }
+
+ public void testResolveWithFilter()
+ throws ArtifactResolutionException, InvalidVersionSpecificationException
+ {
+ ArtifactSpec a = createArtifactSpec( "a", "1.0" );
+ ArtifactSpec b = a.addDependency( "b", "1.0" );
+ ArtifactSpec c = a.addDependency( "c", "3.0" );
+
+ b.addDependency( "c", "2.0" );
+ ArtifactSpec d = b.addDependency( "d", "4.0" );
+
+ ArtifactResolutionResult res = collect( a );
+ assertEquals( "Check artifact list",
+ createSet( new Object[] { a.artifact, b.artifact, c.artifact, d.artifact } ), res.getArtifacts() );
+
+ ArtifactFilter filter = new ExclusionSetFilter( new String[] { "b" } );
+ res = collect( a, filter );
+ assertEquals( "Check artifact list", createSet( new Object[] { a.artifact, c.artifact } ), res.getArtifacts() );
+ }
+
+ public void testResolveCorrectDependenciesWhenDifferentDependenciesOnNearest()
+ throws ArtifactResolutionException, InvalidVersionSpecificationException
+ {
+ ArtifactSpec a = createArtifactSpec( "a", "1.0" );
+ ArtifactSpec b = a.addDependency( "b", "1.0" );
+ ArtifactSpec c2 = b.addDependency( "c", "2.0" );
+ c2.addDependency( "d", "1.0" );
+
+ ArtifactSpec e = createArtifactSpec( "e", "1.0" );
+ ArtifactSpec c1 = e.addDependency( "c", "1.0" );
+ ArtifactSpec f = c1.addDependency( "f", "1.0" );
+
+ ArtifactResolutionResult res = collect( createSet( new Object[] { a.artifact, e.artifact } ) );
+ assertEquals( "Check artifact list", createSet( new Object[] { a.artifact, b.artifact, e.artifact, c1.artifact,
+ f.artifact } ), res.getArtifacts() );
+ assertEquals( "Check version", "1.0", getArtifact( "c", res.getArtifacts() ).getVersion() );
+ }
+
+ public void disabledtestResolveCorrectDependenciesWhenDifferentDependenciesOnNewest()
+ throws ArtifactResolutionException, InvalidVersionSpecificationException
+ {
+ // TODO: use newest conflict resolver
+ ArtifactSpec a = createArtifactSpec( "a", "1.0" );
+ ArtifactSpec b = a.addDependency( "b", "1.0" );
+ ArtifactSpec c2 = b.addDependency( "c", "2.0" );
+ ArtifactSpec d = c2.addDependency( "d", "1.0" );
+
+ ArtifactSpec e = createArtifactSpec( "e", "1.0" );
+ ArtifactSpec c1 = e.addDependency( "c", "1.0" );
+ c1.addDependency( "f", "1.0" );
+
+ ArtifactResolutionResult res = collect( createSet( new Object[] { a.artifact, e.artifact } ) );
+ assertEquals( "Check artifact list", createSet( new Object[] { a.artifact, b.artifact, e.artifact, c2.artifact,
+ d.artifact } ), res.getArtifacts() );
+ assertEquals( "Check version", "2.0", getArtifact( "c", res.getArtifacts() ).getVersion() );
+ }
+
+ public void disabledtestResolveCorrectDependenciesWhenDifferentDependenciesOnNewestVersionReplaced()
+ throws ArtifactResolutionException, InvalidVersionSpecificationException
+ {
+ // TODO: use newest conflict resolver
+ ArtifactSpec a = createArtifactSpec( "a", "1.0" );
+ ArtifactSpec b1 = a.addDependency( "b", "1.0" );
+ ArtifactSpec c = a.addDependency( "c", "1.0" );
+ ArtifactSpec d2 = b1.addDependency( "d", "2.0" );
+ d2.addDependency( "h", "1.0" );
+ ArtifactSpec d1 = c.addDependency( "d", "1.0" );
+ ArtifactSpec b2 = c.addDependency( "b", "2.0" );
+ ArtifactSpec e = b2.addDependency( "e", "1.0" );
+ ArtifactSpec g = d1.addDependency( "g", "1.0" );
+
+ ArtifactResolutionResult res = collect( createSet( new Object[] { a.artifact } ) );
+ Object[] artifacts = new Object[] { a.artifact, c.artifact, d1.artifact, b2.artifact, e.artifact, g.artifact };
+ assertEquals( "Check artifact list", createSet( artifacts ), res.getArtifacts() );
+ assertEquals( "Check version", "1.0", getArtifact( "d", res.getArtifacts() ).getVersion() );
+ assertEquals( "Check version", "2.0", getArtifact( "b", res.getArtifacts() ).getVersion() );
+ }
+
+ public void testResolveNearestNewestIsNearest()
+ throws ArtifactResolutionException, InvalidVersionSpecificationException
+ {
+ ArtifactSpec a = createArtifactSpec( "a", "1.0" );
+ ArtifactSpec b = a.addDependency( "b", "1.0" );
+ ArtifactSpec c = a.addDependency( "c", "3.0" );
+
+ b.addDependency( "c", "2.0" );
+
+ ArtifactResolutionResult res = collect( a );
+ assertEquals( "Check artifact list", createSet( new Object[] { a.artifact, b.artifact, c.artifact } ),
+ res.getArtifacts() );
+ assertEquals( "Check version", "3.0", getArtifact( "c", res.getArtifacts() ).getVersion() );
+ }
+
+ public void testResolveNearestOldestIsNearest()
+ throws ArtifactResolutionException, InvalidVersionSpecificationException
+ {
+ ArtifactSpec a = createArtifactSpec( "a", "1.0" );
+ ArtifactSpec b = a.addDependency( "b", "1.0" );
+ ArtifactSpec c = a.addDependency( "c", "2.0" );
+
+ b.addDependency( "c", "3.0" );
+
+ ArtifactResolutionResult res = collect( a );
+ assertEquals( "Check artifact list", createSet( new Object[] { a.artifact, b.artifact, c.artifact } ),
+ res.getArtifacts() );
+ assertEquals( "Check version", "2.0", getArtifact( "c", res.getArtifacts() ).getVersion() );
+ }
+
+ public void testResolveLocalNewestIsLocal()
+ throws ArtifactResolutionException, InvalidVersionSpecificationException
+ {
+ ArtifactSpec a = createArtifactSpec( "a", "1.0" );
+ a.addDependency( "b", "2.0" );
+ ArtifactSpec b = createArtifactSpec( "b", "3.0" );
+
+ ArtifactResolutionResult res = collect( createSet( new Object[] { a.artifact, b.artifact } ) );
+ assertEquals( "Check artifact list", createSet( new Object[] { a.artifact, b.artifact } ), res.getArtifacts() );
+ assertEquals( "Check version", "3.0", getArtifact( "b", res.getArtifacts() ).getVersion() );
+ }
+
+ public void testResolveLocalOldestIsLocal()
+ throws ArtifactResolutionException, InvalidVersionSpecificationException
+ {
+ ArtifactSpec a = createArtifactSpec( "a", "1.0" );
+ a.addDependency( "b", "3.0" );
+ ArtifactSpec b = createArtifactSpec( "b", "2.0" );
+
+ ArtifactResolutionResult res = collect( createSet( new Object[] { a.artifact, b.artifact } ) );
+ assertEquals( "Check artifact list", createSet( new Object[] { a.artifact, b.artifact } ), res.getArtifacts() );
+ assertEquals( "Check version", "2.0", getArtifact( "b", res.getArtifacts() ).getVersion() );
+ }
+
+ public void testResolveLocalWithNewerVersionButLesserScope()
+ throws ArtifactResolutionException, InvalidVersionSpecificationException
+ {
+ ArtifactSpec a = createArtifactSpec( "commons-logging", "1.0" );
+ a.addDependency( "junit", "3.7" );
+ ArtifactSpec b = createArtifactSpec( "junit", "3.8.1", Artifact.SCOPE_TEST );
+
+ ArtifactResolutionResult res = collect( createSet( new Object[] { a.artifact, b.artifact } ) );
+ assertEquals( "Check artifact list", createSet( new Object[] { a.artifact, b.artifact } ), res.getArtifacts() );
+ assertEquals( "Check version", "3.8.1", getArtifact( "junit", res.getArtifacts() ).getVersion() );
+ assertEquals( "Check artifactScope", Artifact.SCOPE_TEST, getArtifact( "junit", res.getArtifacts() ).getScope() );
+ }
+
+ public void testResolveLocalWithNewerVersionButLesserScopeResolvedFirst()
+ throws ArtifactResolutionException, InvalidVersionSpecificationException
+ {
+ ArtifactSpec b = createArtifactSpec( "junit", "3.8.1", Artifact.SCOPE_TEST );
+ ArtifactSpec a = createArtifactSpec( "commons-logging", "1.0" );
+ a.addDependency( "junit", "3.7" );
+
+ ArtifactResolutionResult res = collect( createSet( new Object[] { a.artifact, b.artifact } ) );
+ assertEquals( "Check artifact list", createSet( new Object[] { a.artifact, b.artifact } ), res.getArtifacts() );
+ assertEquals( "Check version", "3.8.1", getArtifact( "junit", res.getArtifacts() ).getVersion() );
+ assertEquals( "Check artifactScope", Artifact.SCOPE_TEST, getArtifact( "junit", res.getArtifacts() ).getScope() );
+ }
+
+ public void testResolveNearestWithRanges()
+ throws ArtifactResolutionException, InvalidVersionSpecificationException
+ {
+ ArtifactSpec a = createArtifactSpec( "a", "1.0" );
+ ArtifactSpec b = a.addDependency( "b", "1.0" );
+ ArtifactSpec c = a.addDependency( "c", "2.0" );
+
+ b.addDependency( "c", "[1.0,3.0]" );
+
+ ArtifactResolutionResult res = collect( a );
+ assertEquals( "Check artifact list", createSet( new Object[] { a.artifact, b.artifact, c.artifact } ),
+ res.getArtifacts() );
+ assertEquals( "Check version", "2.0", getArtifact( "c", res.getArtifacts() ).getVersion() );
+ }
+
+ public void testResolveRangeWithManagedVersion()
+ throws ArtifactResolutionException, InvalidVersionSpecificationException
+ {
+ ArtifactSpec a = createArtifactSpec( "a", "1.0" );
+ ArtifactSpec b = a.addDependency( "b", "[1.0,3.0]" );
+
+ ArtifactSpec managedB = createArtifactSpec( "b", "5.0" );
+
+ ArtifactResolutionResult res = collect( a, managedB.artifact );
+ assertEquals( "Check artifact list", createSet( new Object[] { a.artifact, managedB.artifact } ),
+ res.getArtifacts() );
+ assertEquals( "Check version", "5.0", getArtifact( "b", res.getArtifacts() ).getVersion() );
+ }
+
+ public void testCompatibleRanges()
+ throws ArtifactResolutionException, InvalidVersionSpecificationException
+ {
+ ArtifactSpec a = createArtifactSpec( "a", "1.0" );
+ ArtifactSpec b = a.addDependency( "b", "1.0" );
+ a.addDependency( "c", "[2.0,2.5]" );
+ b.addDependency( "c", "[1.0,3.0]" );
+ ArtifactSpec c = createArtifactSpec( "c", "2.5" );
+
+ ArtifactResolutionResult res = collect( a );
+
+ assertEquals( "Check artifact list", createSet( new Object[] { a.artifact, b.artifact, c.artifact } ),
+ res.getArtifacts() );
+ assertEquals( "Check version", "2.5", getArtifact( "c", res.getArtifacts() ).getVersion() );
+ }
+
+ public void testIncompatibleRanges()
+ throws ArtifactResolutionException, InvalidVersionSpecificationException
+ {
+ ArtifactSpec a = createArtifactSpec( "a", "1.0" );
+ ArtifactSpec b = a.addDependency( "b", "1.0" );
+ a.addDependency( "c", "[2.4,3.0]" );
+
+ b.addDependency( "c", "[1.0,2.0]" );
+
+ ArtifactResolutionResult res = collect( a );
+
+ assertTrue( res.hasVersionRangeViolations() );
+ }
+
+ public void testUnboundedRangeWhenVersionUnavailable()
+ throws ArtifactResolutionException, InvalidVersionSpecificationException
+ {
+ ArtifactSpec a = createArtifactSpec( "a", "1.0" );
+ ArtifactSpec b = a.addDependency( "b", "1.0" );
+ a.addDependency( "c", "[2.0,]" );
+ b.addDependency( "c", "[1.0,]" );
+
+ ArtifactResolutionResult res = collect( a );
+
+ assertTrue( res.hasVersionRangeViolations() );
+ }
+
+ public void testUnboundedRangeBelowLastRelease()
+ throws ArtifactResolutionException, InvalidVersionSpecificationException
+ {
+ ArtifactSpec a = createArtifactSpec( "a", "1.0" );
+ createArtifactSpec( "c", "1.5" );
+ ArtifactSpec c = createArtifactSpec( "c", "2.0" );
+ createArtifactSpec( "c", "1.1" );
+ a.addDependency( "c", "[1.0,)" );
+
+ ArtifactResolutionResult res = collect( a );
+
+ assertEquals( "Check artifact list", createSet( new Object[] { a.artifact, c.artifact } ), res.getArtifacts() );
+ assertEquals( "Check version", "2.0", getArtifact( "c", res.getArtifacts() ).getVersion() );
+ }
+
+ public void testUnboundedRangeAboveLastRelease()
+ throws ArtifactResolutionException, InvalidVersionSpecificationException
+ {
+ ArtifactSpec a = createArtifactSpec( "a", "1.0" );
+ createArtifactSpec( "c", "2.0" );
+ a.addDependency( "c", "[10.0,)" );
+
+ ArtifactResolutionResult res = collect( a );
+
+ assertTrue( res.hasVersionRangeViolations() );
+ }
+
+ public void testResolveManagedVersion()
+ throws ArtifactResolutionException, InvalidVersionSpecificationException
+ {
+ ArtifactSpec a = createArtifactSpec( "a", "1.0" );
+ a.addDependency( "b", "3.0", Artifact.SCOPE_RUNTIME );
+
+ Artifact managedVersion = createArtifactSpec( "b", "5.0" ).artifact;
+ Artifact modifiedB = createArtifactSpec( "b", "5.0", Artifact.SCOPE_RUNTIME ).artifact;
+
+ ArtifactResolutionResult res = collect( a, managedVersion );
+ assertEquals( "Check artifact list", createSet( new Object[] { a.artifact, modifiedB } ), res.getArtifacts() );
+ }
+
+ public void testCollectChangesVersionOfOriginatingArtifactIfInDependencyManagementHasDifferentVersion()
+ throws ArtifactResolutionException, InvalidVersionSpecificationException
+ {
+ ArtifactSpec a = createArtifactSpec( "a", "1.0" );
+
+ Artifact artifact = projectArtifact.artifact;
+ Artifact managedVersion = createArtifactSpec( artifact.getArtifactId(), "2.0" ).artifact;
+
+ ArtifactResolutionResult result = collect( a, managedVersion );
+
+ assertEquals( "collect has modified version in originating artifact", "1.0", artifact.getVersion() );
+
+ Artifact resolvedArtifact = result.getArtifacts().iterator().next();
+
+ assertEquals( "Resolved version don't match original artifact version", "1.0", resolvedArtifact.getVersion() );
+ }
+
+ public void testResolveCompileScopeOverTestScope()
+ throws ArtifactResolutionException, InvalidVersionSpecificationException
+ {
+ ArtifactSpec a = createArtifactSpec( "a", "1.0" );
+ ArtifactSpec c = createArtifactSpec( "c", "3.0", Artifact.SCOPE_TEST );
+
+ a.addDependency( "c", "2.0", Artifact.SCOPE_COMPILE );
+
+ Artifact modifiedC = createArtifactSpec( "c", "3.0", Artifact.SCOPE_COMPILE ).artifact;
+
+ ArtifactResolutionResult res = collect( createSet( new Object[] { a.artifact, c.artifact } ) );
+ assertEquals( "Check artifact list", createSet( new Object[] { a.artifact, modifiedC } ), res.getArtifacts() );
+ Artifact artifact = getArtifact( "c", res.getArtifacts() );
+ // local wins now, and irrelevant if not local as test/provided aren't transitive
+ // assertEquals( "Check artifactScope", Artifact.SCOPE_COMPILE, artifact.getArtifactScope() );
+ assertEquals( "Check artifactScope", Artifact.SCOPE_TEST, artifact.getScope() );
+ }
+
+ public void testResolveRuntimeScopeOverTestScope()
+ throws ArtifactResolutionException, InvalidVersionSpecificationException
+ {
+ ArtifactSpec a = createArtifactSpec( "a", "1.0" );
+ ArtifactSpec c = createArtifactSpec( "c", "3.0", Artifact.SCOPE_TEST );
+
+ a.addDependency( "c", "2.0", Artifact.SCOPE_RUNTIME );
+
+ Artifact modifiedC = createArtifactSpec( "c", "3.0", Artifact.SCOPE_RUNTIME ).artifact;
+
+ ArtifactResolutionResult res = collect( createSet( new Object[] { a.artifact, c.artifact } ) );
+ assertEquals( "Check artifact list", createSet( new Object[] { a.artifact, modifiedC } ), res.getArtifacts() );
+ Artifact artifact = getArtifact( "c", res.getArtifacts() );
+ // local wins now, and irrelevant if not local as test/provided aren't transitive
+ // assertEquals( "Check artifactScope", Artifact.SCOPE_RUNTIME, artifact.getArtifactScope() );
+ assertEquals( "Check artifactScope", Artifact.SCOPE_TEST, artifact.getScope() );
+ }
+
+ public void testResolveCompileScopeOverRuntimeScope()
+ throws ArtifactResolutionException, InvalidVersionSpecificationException
+ {
+ ArtifactSpec root = createArtifactSpec( "root", "1.0" );
+ ArtifactSpec a = root.addDependency( "a", "1.0" );
+ root.addDependency( "c", "3.0", Artifact.SCOPE_RUNTIME );
+
+ a.addDependency( "c", "2.0", Artifact.SCOPE_COMPILE );
+
+ Artifact modifiedC = createArtifactSpec( "c", "3.0", Artifact.SCOPE_COMPILE ).artifact;
+
+ ArtifactResolutionResult res = collect( createSet( new Object[] { root.artifact } ) );
+ assertEquals( "Check artifact list", createSet( new Object[] { a.artifact, root.artifact, modifiedC } ),
+ res.getArtifacts() );
+ Artifact artifact = getArtifact( "c", res.getArtifacts() );
+ assertEquals( "Check artifactScope", Artifact.SCOPE_COMPILE, artifact.getScope() );
+ }
+
+ public void testResolveCompileScopeOverProvidedScope()
+ throws ArtifactResolutionException, InvalidVersionSpecificationException
+ {
+ ArtifactSpec a = createArtifactSpec( "a", "1.0" );
+ ArtifactSpec c = createArtifactSpec( "c", "3.0", Artifact.SCOPE_PROVIDED );
+
+ a.addDependency( "c", "2.0", Artifact.SCOPE_COMPILE );
+
+ Artifact modifiedC = createArtifactSpec( "c", "3.0", Artifact.SCOPE_COMPILE ).artifact;
+
+ ArtifactResolutionResult res = collect( createSet( new Object[] { a.artifact, c.artifact } ) );
+ assertEquals( "Check artifact list", createSet( new Object[] { a.artifact, modifiedC } ), res.getArtifacts() );
+ Artifact artifact = getArtifact( "c", res.getArtifacts() );
+ // local wins now, and irrelevant if not local as test/provided aren't transitive
+ // assertEquals( "Check artifactScope", Artifact.SCOPE_COMPILE, artifact.getArtifactScope() );
+ assertEquals( "Check artifactScope", Artifact.SCOPE_PROVIDED, artifact.getScope() );
+ }
+
+ public void testResolveRuntimeScopeOverProvidedScope()
+ throws ArtifactResolutionException, InvalidVersionSpecificationException
+ {
+ ArtifactSpec a = createArtifactSpec( "a", "1.0" );
+ ArtifactSpec c = createArtifactSpec( "c", "3.0", Artifact.SCOPE_PROVIDED );
+
+ a.addDependency( "c", "2.0", Artifact.SCOPE_RUNTIME );
+
+ Artifact modifiedC = createArtifactSpec( "c", "3.0", Artifact.SCOPE_RUNTIME ).artifact;
+
+ ArtifactResolutionResult res = collect( createSet( new Object[] { a.artifact, c.artifact } ) );
+ assertEquals( "Check artifact list", createSet( new Object[] { a.artifact, modifiedC } ), res.getArtifacts() );
+ Artifact artifact = getArtifact( "c", res.getArtifacts() );
+ // local wins now, and irrelevant if not local as test/provided aren't transitive
+ // assertEquals( "Check artifactScope", Artifact.SCOPE_RUNTIME, artifact.getArtifactScope() );
+ assertEquals( "Check artifactScope", Artifact.SCOPE_PROVIDED, artifact.getScope() );
+ }
+
+ public void testProvidedScopeNotTransitive()
+ throws ArtifactResolutionException, InvalidVersionSpecificationException
+ {
+ ArtifactSpec a = createArtifactSpec( "a", "1.0", Artifact.SCOPE_PROVIDED );
+ ArtifactSpec b = createArtifactSpec( "b", "1.0" );
+ b.addDependency( "c", "3.0", Artifact.SCOPE_PROVIDED );
+
+ ArtifactResolutionResult res = collect( createSet( new Object[] { a.artifact, b.artifact } ) );
+ assertEquals( "Check artifact list", createSet( new Object[] { a.artifact, b.artifact } ), res.getArtifacts() );
+ }
+
+ public void testOptionalNotTransitive()
+ throws ArtifactResolutionException, InvalidVersionSpecificationException
+ {
+ ArtifactSpec a = createArtifactSpec( "a", "1.0" );
+ ArtifactSpec b = createArtifactSpec( "b", "1.0" );
+ b.addDependency( "c", "3.0", true );
+
+ ArtifactResolutionResult res = collect( createSet( new Object[] { a.artifact, b.artifact } ) );
+ assertEquals( "Check artifact list", createSet( new Object[] { a.artifact, b.artifact } ), res.getArtifacts() );
+ }
+
+ public void testOptionalIncludedAtRoot()
+ throws ArtifactResolutionException, InvalidVersionSpecificationException
+ {
+ ArtifactSpec a = createArtifactSpec( "a", "1.0" );
+
+ ArtifactSpec b = createArtifactSpec( "b", "1.0", true );
+
+ ArtifactResolutionResult res = collect( createSet( new Object[] { a.artifact, b.artifact } ) );
+ assertEquals( "Check artifact list", createSet( new Object[] { a.artifact, b.artifact } ), res.getArtifacts() );
+ }
+
+ public void testScopeUpdate()
+ throws InvalidVersionSpecificationException, ArtifactResolutionException
+ {
+ /* farthest = compile */
+ checkScopeUpdate( Artifact.SCOPE_COMPILE, Artifact.SCOPE_COMPILE, Artifact.SCOPE_COMPILE );
+ checkScopeUpdate( Artifact.SCOPE_COMPILE, Artifact.SCOPE_PROVIDED, Artifact.SCOPE_COMPILE );
+ checkScopeUpdate( Artifact.SCOPE_COMPILE, Artifact.SCOPE_RUNTIME, Artifact.SCOPE_COMPILE );
+ checkScopeUpdate( Artifact.SCOPE_COMPILE, Artifact.SCOPE_SYSTEM, Artifact.SCOPE_COMPILE );
+ checkScopeUpdate( Artifact.SCOPE_COMPILE, Artifact.SCOPE_TEST, Artifact.SCOPE_COMPILE );
+
+ /* farthest = provided */
+ checkScopeUpdate( Artifact.SCOPE_PROVIDED, Artifact.SCOPE_COMPILE, Artifact.SCOPE_COMPILE );
+ checkScopeUpdate( Artifact.SCOPE_PROVIDED, Artifact.SCOPE_PROVIDED, Artifact.SCOPE_PROVIDED );
+ checkScopeUpdate( Artifact.SCOPE_PROVIDED, Artifact.SCOPE_RUNTIME, Artifact.SCOPE_RUNTIME );
+ checkScopeUpdate( Artifact.SCOPE_PROVIDED, Artifact.SCOPE_SYSTEM, Artifact.SCOPE_SYSTEM );
+ checkScopeUpdate( Artifact.SCOPE_PROVIDED, Artifact.SCOPE_TEST, Artifact.SCOPE_TEST );
+
+ /* farthest = runtime */
+ checkScopeUpdate( Artifact.SCOPE_RUNTIME, Artifact.SCOPE_COMPILE, Artifact.SCOPE_COMPILE );
+ checkScopeUpdate( Artifact.SCOPE_RUNTIME, Artifact.SCOPE_PROVIDED, Artifact.SCOPE_RUNTIME );
+ checkScopeUpdate( Artifact.SCOPE_RUNTIME, Artifact.SCOPE_RUNTIME, Artifact.SCOPE_RUNTIME );
+ checkScopeUpdate( Artifact.SCOPE_RUNTIME, Artifact.SCOPE_SYSTEM, Artifact.SCOPE_SYSTEM );
+ checkScopeUpdate( Artifact.SCOPE_RUNTIME, Artifact.SCOPE_TEST, Artifact.SCOPE_RUNTIME );
+
+ /* farthest = system */
+ checkScopeUpdate( Artifact.SCOPE_SYSTEM, Artifact.SCOPE_COMPILE, Artifact.SCOPE_COMPILE );
+ checkScopeUpdate( Artifact.SCOPE_SYSTEM, Artifact.SCOPE_PROVIDED, Artifact.SCOPE_PROVIDED );
+ checkScopeUpdate( Artifact.SCOPE_SYSTEM, Artifact.SCOPE_RUNTIME, Artifact.SCOPE_RUNTIME );
+ checkScopeUpdate( Artifact.SCOPE_SYSTEM, Artifact.SCOPE_SYSTEM, Artifact.SCOPE_SYSTEM );
+ checkScopeUpdate( Artifact.SCOPE_SYSTEM, Artifact.SCOPE_TEST, Artifact.SCOPE_TEST );
+
+ /* farthest = test */
+ checkScopeUpdate( Artifact.SCOPE_TEST, Artifact.SCOPE_COMPILE, Artifact.SCOPE_COMPILE );
+ checkScopeUpdate( Artifact.SCOPE_TEST, Artifact.SCOPE_PROVIDED, Artifact.SCOPE_PROVIDED );
+ checkScopeUpdate( Artifact.SCOPE_TEST, Artifact.SCOPE_RUNTIME, Artifact.SCOPE_RUNTIME );
+ checkScopeUpdate( Artifact.SCOPE_TEST, Artifact.SCOPE_SYSTEM, Artifact.SCOPE_SYSTEM );
+ checkScopeUpdate( Artifact.SCOPE_TEST, Artifact.SCOPE_TEST, Artifact.SCOPE_TEST );
+ }
+
+ private void checkScopeUpdate( String farthestScope, String nearestScope, String expectedScope )
+ throws ArtifactResolutionException, InvalidVersionSpecificationException
+ {
+ checkScopeUpdateDirect( farthestScope, nearestScope, expectedScope );
+ checkScopeUpdateTransitively( farthestScope, nearestScope, expectedScope );
+ }
+
+ private void checkScopeUpdateTransitively( String farthestScope, String nearestScope, String expectedScope )
+ throws ArtifactResolutionException, InvalidVersionSpecificationException
+ {
+ ArtifactSpec a = createArtifactSpec( "a", "1.0" );
+ ArtifactSpec b = createArtifactSpec( "b", "1.0", nearestScope );
+ ArtifactSpec c = createArtifactSpec( "c", "1.0" );
+ a.addDependency( c );
+ ArtifactSpec dNearest = createArtifactSpec( "d", "2.0" );
+ b.addDependency( dNearest );
+ ArtifactSpec dFarthest = createArtifactSpec( "d", "3.0", farthestScope );
+ c.addDependency( dFarthest );
+
+ /* system and provided dependencies are not transitive */
+ if ( !Artifact.SCOPE_SYSTEM.equals( nearestScope ) && !Artifact.SCOPE_PROVIDED.equals( nearestScope ) )
+ {
+ checkScopeUpdate( a, b, expectedScope, "2.0" );
+ }
+ }
+
+ private void checkScopeUpdateDirect( String farthestScope, String nearestScope, String expectedScope )
+ throws ArtifactResolutionException, InvalidVersionSpecificationException
+ {
+ ArtifactSpec a = createArtifactSpec( "a", "1.0" );
+ ArtifactSpec b = createArtifactSpec( "b", "1.0" );
+ ArtifactSpec c = createArtifactSpec( "c", "1.0" );
+ a.addDependency( c );
+ ArtifactSpec dNearest = createArtifactSpec( "d", "2.0", nearestScope );
+ b.addDependency( dNearest );
+ ArtifactSpec dFarthest = createArtifactSpec( "d", "3.0", farthestScope );
+ c.addDependency( dFarthest );
+
+ checkScopeUpdate( a, b, expectedScope, "2.0" );
+ }
+
+ private void checkScopeUpdate( ArtifactSpec a, ArtifactSpec b, String expectedScope, String expectedVersion )
+ throws ArtifactResolutionException, InvalidVersionSpecificationException
+ {
+ ScopeArtifactFilter filter;
+ if ( Artifact.SCOPE_PROVIDED.equals( expectedScope ) )
+ {
+ filter = new ScopeArtifactFilter( Artifact.SCOPE_COMPILE );
+ }
+ else if ( Artifact.SCOPE_SYSTEM.equals( expectedScope ) )
+ {
+ filter = new ScopeArtifactFilter( Artifact.SCOPE_COMPILE );
+ }
+ else
+ {
+ filter = new ScopeArtifactFilter( expectedScope );
+ }
+
+ ArtifactResolutionResult res = collect( createSet( new Object[] { a.artifact, b.artifact } ), filter );
+ Artifact artifact = getArtifact( "d", res.getArtifacts() );
+ assertNotNull( "MNG-1895 Dependency was not added to resolution", artifact );
+ assertEquals( "Check artifactScope", expectedScope, artifact.getScope() );
+ assertEquals( "Check version", expectedVersion, artifact.getVersion() );
+
+ ArtifactSpec d = createArtifactSpec( "d", "1.0" );
+ res = collect( createSet( new Object[] { a.artifact, b.artifact, d.artifact } ), filter );
+ artifact = getArtifact( "d", res.getArtifacts() );
+ assertNotNull( "MNG-1895 Dependency was not added to resolution", artifact );
+ assertEquals( "Check artifactScope", d.artifact.getScope(), artifact.getScope() );
+ assertEquals( "Check version", "1.0", artifact.getVersion() );
+ }
+
+ public void disabledtestOptionalNotTransitiveButVersionIsInfluential()
+ throws ArtifactResolutionException, InvalidVersionSpecificationException
+ {
+ ArtifactSpec a = createArtifactSpec( "a", "1.0" );
+ ArtifactSpec b = createArtifactSpec( "b", "1.0" );
+ b.addDependency( "c", "3.0", true );
+ ArtifactSpec d = a.addDependency( "d", "1.0" );
+ ArtifactSpec e = d.addDependency( "e", "1.0" );
+ e.addDependency( "c", "2.0" );
+
+ ArtifactSpec c = createArtifactSpec( "c", "3.0" );
+
+ ArtifactResolutionResult res = collect( createSet( new Object[] { a.artifact, b.artifact } ) );
+ assertEquals( "Check artifact list", createSet( new Object[] { a.artifact, b.artifact, c.artifact, d.artifact,
+ e.artifact } ), res.getArtifacts() );
+ Artifact artifact = getArtifact( "c", res.getArtifacts() );
+ assertEquals( "Check version", "3.0", artifact.getVersion() );
+ }
+
+ public void testTestScopeNotTransitive()
+ throws ArtifactResolutionException, InvalidVersionSpecificationException
+ {
+ ArtifactSpec a = createArtifactSpec( "a", "1.0", Artifact.SCOPE_TEST );
+ ArtifactSpec b = createArtifactSpec( "b", "1.0" );
+ b.addDependency( "c", "3.0", Artifact.SCOPE_TEST );
+
+ ArtifactResolutionResult res = collect( createSet( new Object[] { a.artifact, b.artifact } ) );
+ assertEquals( "Check artifact list", createSet( new Object[] { a.artifact, b.artifact } ), res.getArtifacts() );
+ }
+
+ public void testSnapshotNotIncluded()
+ throws ArtifactResolutionException, InvalidVersionSpecificationException
+ {
+ ArtifactSpec a = createArtifactSpec( "a", "1.0" );
+ a.addDependency( "b", "[1.0,)" );
+ createArtifactSpec( "b", "1.0-SNAPSHOT" );
+
+ ArtifactResolutionResult res = collect( a );
+
+ assertTrue( res.hasVersionRangeViolations() );
+
+ /*
+ * try { ArtifactResolutionResult res = collect( a ); fail( "Expected b not to resolve: " + res ); } catch (
+ * OverConstrainedVersionException e ) { assertTrue( e.getMessage().indexOf( "[1.0-SNAPSHOT]" ) <
+ * e.getMessage().indexOf( "[1.0,)" ) ); }
+ */
+ }
+
+ public void testOverConstrainedVersionException()
+ throws ArtifactResolutionException, InvalidVersionSpecificationException
+ {
+ ArtifactSpec a = createArtifactSpec( "a", "1.0" );
+ a.addDependency( "b", "[1.0, 2.0)" );
+ a.addDependency( "c", "[3.3.0,4.0.0)" );
+
+ ArtifactSpec b = createArtifactSpec( "b", "1.0.0" );
+ b.addDependency( "c", "3.3.0-v3346" );
+
+ ArtifactSpec c = createArtifactSpec( "c", "3.2.1-v3235e" );
+
+ try
+ {
+ ArtifactResolutionResult res = collect( createSet( new Object[] { a.artifact } ) );
+ }
+ catch ( OverConstrainedVersionException e )
+ {
+ assertTrue( "Versions unordered", e.getMessage().contains( "[3.2.1-v3235e, 3.3.0-v3346]" ) );
+ assertTrue( "DependencyTrail unresolved", e.getMessage().contains( "Path to dependency:" ) );
+ }
+ }
+
+ private Artifact getArtifact( String id, Set artifacts )
+ {
+ for ( Object artifact : artifacts )
+ {
+ Artifact a = (Artifact) artifact;
+ if ( a.getArtifactId().equals( id ) && a.getGroupId().equals( GROUP_ID ) )
+ {
+ return a;
+ }
+ }
+ return null;
+ }
+
+ private ArtifactResolutionResult collect( Set artifacts )
+ throws ArtifactResolutionException
+ {
+ return collect( artifacts, null );
+ }
+
+ private ArtifactResolutionResult collect( Set artifacts, ArtifactFilter filter )
+ throws ArtifactResolutionException
+ {
+ return artifactCollector.collect( artifacts, projectArtifact.artifact, null, null, null, source, filter,
+ Collections.EMPTY_LIST, null );
+ }
+
+ private ArtifactResolutionResult collect( ArtifactSpec a )
+ throws ArtifactResolutionException
+ {
+ return artifactCollector.collect( Collections.singleton( a.artifact ), projectArtifact.artifact, null, null,
+ null, source, null, Collections.EMPTY_LIST, null );
+ }
+
+ private ArtifactResolutionResult collect( ArtifactSpec a, ArtifactFilter filter )
+ throws ArtifactResolutionException
+ {
+ return artifactCollector.collect( Collections.singleton( a.artifact ), projectArtifact.artifact, null, null,
+ null, source, filter, Collections.EMPTY_LIST, null );
+ }
+
+ private ArtifactResolutionResult collect( ArtifactSpec a, Artifact managedVersion )
+ throws ArtifactResolutionException
+ {
+ Map managedVersions = Collections.singletonMap( managedVersion.getDependencyConflictId(), managedVersion );
+ return artifactCollector.collect( Collections.singleton( a.artifact ), projectArtifact.artifact,
+ managedVersions, null, null, source, null, Collections.EMPTY_LIST, null );
+ }
+
+ private ArtifactSpec createArtifactSpec( String id, String version )
+ throws InvalidVersionSpecificationException
+ {
+ return createArtifactSpec( id, version, Artifact.SCOPE_COMPILE );
+ }
+
+ private ArtifactSpec createArtifactSpec( String id, String version, boolean optional )
+ throws InvalidVersionSpecificationException
+ {
+ return createArtifactSpec( id, version, Artifact.SCOPE_COMPILE, null, optional );
+ }
+
+ private ArtifactSpec createArtifactSpec( String id, String version, String scope )
+ throws InvalidVersionSpecificationException
+ {
+ return createArtifactSpec( id, version, scope, null, false );
+ }
+
+ private ArtifactSpec createArtifactSpec( String id, String version, String scope, String inheritedScope,
+ boolean optional )
+ throws InvalidVersionSpecificationException
+ {
+ VersionRange versionRange = VersionRange.createFromVersionSpec( version );
+ Artifact artifact =
+ artifactFactory.createDependencyArtifact( GROUP_ID, id, versionRange, "jar", null, scope, inheritedScope,
+ optional );
+ ArtifactSpec spec = null;
+ if ( artifact != null )
+ {
+ spec = new ArtifactSpec();
+ spec.artifact = artifact;
+ source.addArtifact( spec );
+ }
+ return spec;
+ }
+
+ private static Set createSet( Object[] x )
+ {
+ return new LinkedHashSet( Arrays.asList( x ) );
+ }
+
+ private class ArtifactSpec
+ {
+ private Artifact artifact;
+
+ private Set dependencies = new HashSet();
+
+ public ArtifactSpec addDependency( String id, String version )
+ throws InvalidVersionSpecificationException
+ {
+ return addDependency( id, version, Artifact.SCOPE_COMPILE );
+ }
+
+ public ArtifactSpec addDependency( String id, String version, String scope )
+ throws InvalidVersionSpecificationException
+ {
+ return addDependency( id, version, scope, false );
+ }
+
+ private ArtifactSpec addDependency( ArtifactSpec dep )
+ throws InvalidVersionSpecificationException
+ {
+ if ( dep != null )
+ {
+ dependencies.add( dep.artifact );
+ }
+ return dep;
+ }
+
+ private ArtifactSpec addDependency( String id, String version, String scope, boolean optional )
+ throws InvalidVersionSpecificationException
+ {
+ ArtifactSpec dep = createArtifactSpec( id, version, scope, artifact.getScope(), optional );
+ return addDependency( dep );
+ }
+
+ public ArtifactSpec addDependency( String id, String version, boolean optional )
+ throws InvalidVersionSpecificationException
+ {
+ return addDependency( id, version, Artifact.SCOPE_COMPILE, optional );
+ }
+ }
+
+ private class Source
+ implements ArtifactMetadataSource
+ {
+ private Map artifacts = new HashMap();
+
+ private Map versions = new HashMap();
+
+ public ResolutionGroup retrieve( Artifact artifact, ArtifactRepository localRepository,
+ List<ArtifactRepository> remoteRepositories )
+ throws ArtifactMetadataRetrievalException
+ {
+ String key = getKey( artifact );
+
+ ArtifactSpec a = (ArtifactSpec) artifacts.get( key );
+ try
+ {
+ return new ResolutionGroup( artifact, createArtifacts( artifactFactory, a.dependencies,
+ artifact.getScope(),
+ artifact.getDependencyFilter() ),
+ Collections.EMPTY_LIST );
+ }
+ catch ( InvalidVersionSpecificationException e )
+ {
+ throw new ArtifactMetadataRetrievalException( "Invalid version creating artifacts", e, artifact );
+ }
+ }
+
+ private String getKey( Artifact artifact )
+ {
+ return artifact.getDependencyConflictId();
+ }
+
+ private Set createArtifacts( ArtifactFactory artifactFactory, Set dependencies, String inheritedScope,
+ ArtifactFilter dependencyFilter )
+ throws InvalidVersionSpecificationException
+ {
+ Set projectArtifacts = new HashSet();
+
+ for ( Object dependency : dependencies )
+ {
+ Artifact d = (Artifact) dependency;
+
+ VersionRange versionRange;
+ if ( d.getVersionRange() != null )
+ {
+ versionRange = d.getVersionRange();
+ }
+ else
+ {
+ versionRange = VersionRange.createFromVersionSpec( d.getVersion() );
+ }
+ Artifact artifact;
+ if ( d.getScope().equals( Artifact.SCOPE_TEST ) || d.getScope().equals( Artifact.SCOPE_PROVIDED ) )
+ {
+ /* don't call createDependencyArtifact as it'll ignore test and provided scopes */
+ artifact =
+ artifactFactory.createArtifact( d.getGroupId(), d.getArtifactId(), d.getVersion(), d.getScope(),
+ d.getType() );
+ }
+ else
+ {
+ artifact =
+ artifactFactory.createDependencyArtifact( d.getGroupId(), d.getArtifactId(), versionRange,
+ d.getType(), d.getClassifier(), d.getScope(),
+ inheritedScope, d.isOptional() );
+ }
+
+ if ( artifact != null && ( dependencyFilter == null || dependencyFilter.include( artifact ) ) )
+ {
+ artifact.setDependencyFilter( dependencyFilter );
+
+ projectArtifacts.add( artifact );
+ }
+ }
+
+ return projectArtifacts;
+ }
+
+ public void addArtifact( ArtifactSpec spec )
+ {
+ artifacts.put( getKey( spec.artifact ), spec );
+
+ String key = spec.artifact.getDependencyConflictId();
+ List artifactVersions = (List) versions.get( key );
+ if ( artifactVersions == null )
+ {
+ artifactVersions = new ArrayList();
+ versions.put( key, artifactVersions );
+ }
+ if ( spec.artifact.getVersion() != null )
+ {
+ artifactVersions.add( new DefaultArtifactVersion( spec.artifact.getVersion() ) );
+ }
+ }
+
+ public List<ArtifactVersion> retrieveAvailableVersions( Artifact artifact, ArtifactRepository localRepository,
+ List<ArtifactRepository> remoteRepositories )
+ throws ArtifactMetadataRetrievalException
+ {
+ return retrieveAvailableVersions( artifact );
+ }
+
+ public List<ArtifactVersion> retrieveAvailableVersionsFromDeploymentRepository(
+ Artifact artifact,
+ ArtifactRepository localRepository,
+ ArtifactRepository remoteRepository )
+ throws ArtifactMetadataRetrievalException
+ {
+ return retrieveAvailableVersions( artifact );
+ }
+
+ private List<ArtifactVersion> retrieveAvailableVersions( Artifact artifact )
+ {
+ List artifactVersions = (List) versions.get( artifact.getDependencyConflictId() );
+ if ( artifactVersions == null )
+ {
+ artifactVersions = Collections.EMPTY_LIST;
+ }
+ return artifactVersions;
+ }
+
+ public ResolutionGroup retrieve( MetadataResolutionRequest request )
+ throws ArtifactMetadataRetrievalException
+ {
+ return retrieve( request.getArtifact(), request.getLocalRepository(), request.getRemoteRepositories() );
+ }
+
+ public List<ArtifactVersion> retrieveAvailableVersions( MetadataResolutionRequest request )
+ throws ArtifactMetadataRetrievalException
+ {
+ return retrieveAvailableVersions( request.getArtifact(), request.getLocalRepository(), request.getRemoteRepositories() );
+ }
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/legacy/resolver/conflict/AbstractConflictResolverTest.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/legacy/resolver/conflict/AbstractConflictResolverTest.java
new file mode 100644
index 00000000..bfab0d26
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/legacy/resolver/conflict/AbstractConflictResolverTest.java
@@ -0,0 +1,143 @@
+package org.apache.maven.repository.legacy.resolver.conflict;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.factory.ArtifactFactory;
+import org.apache.maven.artifact.resolver.ResolutionNode;
+import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
+import org.apache.maven.artifact.versioning.VersionRange;
+import org.apache.maven.repository.legacy.resolver.conflict.ConflictResolver;
+import org.codehaus.plexus.PlexusTestCase;
+
+/**
+ * Provides a basis for testing conflict resolvers.
+ *
+ * @author <a href="mailto:markhobson@gmail.com">Mark Hobson</a>
+ */
+public abstract class AbstractConflictResolverTest
+ extends PlexusTestCase
+{
+ // constants --------------------------------------------------------------
+
+ private static final String GROUP_ID = "test";
+
+ // fields -----------------------------------------------------------------
+
+ protected Artifact a1;
+
+ protected Artifact a2;
+
+ protected Artifact b1;
+
+ private final String roleHint;
+
+ private ArtifactFactory artifactFactory;
+
+ private ConflictResolver conflictResolver;
+
+ // constructors -----------------------------------------------------------
+
+ public AbstractConflictResolverTest( String roleHint )
+ throws Exception
+ {
+ this.roleHint = roleHint;
+ }
+
+ // TestCase methods -------------------------------------------------------
+
+ /*
+ * @see junit.framework.TestCase#setUp()
+ */
+ protected void setUp() throws Exception
+ {
+ super.setUp();
+
+ artifactFactory = (ArtifactFactory) lookup( ArtifactFactory.ROLE );
+ conflictResolver = (ConflictResolver) lookup( ConflictResolver.ROLE, roleHint );
+
+ a1 = createArtifact( "a", "1.0" );
+ a2 = createArtifact( "a", "2.0" );
+ b1 = createArtifact( "b", "1.0" );
+ }
+
+ /*
+ * @see org.codehaus.plexus.PlexusTestCase#tearDown()
+ */
+ protected void tearDown() throws Exception
+ {
+ a1 = null;
+ a2 = null;
+ b1 = null;
+
+ artifactFactory = null;
+ conflictResolver = null;
+
+ super.tearDown();
+ }
+
+ // protected methods ------------------------------------------------------
+
+ protected ConflictResolver getConflictResolver()
+ {
+ return conflictResolver;
+ }
+
+ protected void assertResolveConflict( ResolutionNode expectedNode, ResolutionNode actualNode1, ResolutionNode actualNode2 )
+ {
+ ResolutionNode resolvedNode = getConflictResolver().resolveConflict( actualNode1, actualNode2 );
+
+ assertNotNull( "Expected resolvable", resolvedNode );
+ assertEquals( "Resolution node", expectedNode, resolvedNode );
+ }
+
+ protected void assertUnresolvableConflict( ResolutionNode actualNode1, ResolutionNode actualNode2 )
+ {
+ ResolutionNode resolvedNode = getConflictResolver().resolveConflict( actualNode1, actualNode2 );
+
+ assertNull( "Expected unresolvable", resolvedNode );
+ }
+
+ protected Artifact createArtifact( String id, String version ) throws InvalidVersionSpecificationException
+ {
+ return createArtifact( id, version, Artifact.SCOPE_COMPILE );
+ }
+
+ protected Artifact createArtifact( String id, String version, boolean optional )
+ throws InvalidVersionSpecificationException
+ {
+ return createArtifact( id, version, Artifact.SCOPE_COMPILE, null, optional );
+ }
+
+ protected Artifact createArtifact( String id, String version, String scope )
+ throws InvalidVersionSpecificationException
+ {
+ return createArtifact( id, version, scope, null, false );
+ }
+
+ protected Artifact createArtifact( String id, String version, String scope, String inheritedScope, boolean optional )
+ throws InvalidVersionSpecificationException
+ {
+ VersionRange versionRange = VersionRange.createFromVersionSpec( version );
+
+ return artifactFactory.createDependencyArtifact( GROUP_ID, id, versionRange, "jar", null, scope,
+ inheritedScope, optional );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/legacy/resolver/conflict/FarthestConflictResolverTest.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/legacy/resolver/conflict/FarthestConflictResolverTest.java
new file mode 100644
index 00000000..96e283df
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/legacy/resolver/conflict/FarthestConflictResolverTest.java
@@ -0,0 +1,107 @@
+package org.apache.maven.repository.legacy.resolver.conflict;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Collections;
+
+import org.apache.maven.artifact.resolver.ResolutionNode;
+import org.apache.maven.repository.legacy.resolver.conflict.FarthestConflictResolver;
+
+/**
+ * Tests <code>FarthestConflictResolver</code>.
+ *
+ * @author <a href="mailto:markhobson@gmail.com">Mark Hobson</a>
+ * @see FarthestConflictResolver
+ */
+public class FarthestConflictResolverTest
+ extends AbstractConflictResolverTest
+{
+ // constructors -----------------------------------------------------------
+
+ public FarthestConflictResolverTest()
+ throws Exception
+ {
+ super("farthest");
+ }
+
+ // tests ------------------------------------------------------------------
+
+ /**
+ * Tests that <code>a:2.0</code> wins in the scenario:
+ * <pre>
+ * a:1.0
+ * b:1.0 -> a:2.0
+ * </pre>
+ */
+ public void testDepth()
+ {
+ ResolutionNode a1n = new ResolutionNode( a1, Collections.EMPTY_LIST );
+ ResolutionNode b1n = new ResolutionNode( b1, Collections.EMPTY_LIST );
+ ResolutionNode a2n = new ResolutionNode( a2, Collections.EMPTY_LIST, b1n );
+
+ assertResolveConflict( a2n, a1n, a2n );
+ }
+
+ /**
+ * Tests that <code>a:2.0</code> wins in the scenario:
+ * <pre>
+ * b:1.0 -> a:2.0
+ * a:1.0
+ * </pre>
+ */
+ public void testDepthReversed()
+ {
+ ResolutionNode b1n = new ResolutionNode( b1, Collections.EMPTY_LIST );
+ ResolutionNode a2n = new ResolutionNode( a2, Collections.EMPTY_LIST, b1n );
+ ResolutionNode a1n = new ResolutionNode( a1, Collections.EMPTY_LIST );
+
+ assertResolveConflict( a2n, a2n, a1n );
+ }
+
+ /**
+ * Tests that <code>a:1.0</code> wins in the scenario:
+ * <pre>
+ * a:1.0
+ * a:2.0
+ * </pre>
+ */
+ public void testEqual()
+ {
+ ResolutionNode a1n = new ResolutionNode( a1, Collections.EMPTY_LIST );
+ ResolutionNode a2n = new ResolutionNode( a2, Collections.EMPTY_LIST );
+
+ assertResolveConflict( a1n, a1n, a2n );
+ }
+
+ /**
+ * Tests that <code>a:2.0</code> wins in the scenario:
+ * <pre>
+ * a:2.0
+ * a:1.0
+ * </pre>
+ */
+ public void testEqualReversed()
+ {
+ ResolutionNode a2n = new ResolutionNode( a2, Collections.EMPTY_LIST );
+ ResolutionNode a1n = new ResolutionNode( a1, Collections.EMPTY_LIST );
+
+ assertResolveConflict( a2n, a2n, a1n );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/legacy/resolver/conflict/NearestConflictResolverTest.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/legacy/resolver/conflict/NearestConflictResolverTest.java
new file mode 100644
index 00000000..0c7b035f
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/legacy/resolver/conflict/NearestConflictResolverTest.java
@@ -0,0 +1,107 @@
+package org.apache.maven.repository.legacy.resolver.conflict;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Collections;
+
+import org.apache.maven.artifact.resolver.ResolutionNode;
+import org.apache.maven.repository.legacy.resolver.conflict.NearestConflictResolver;
+
+/**
+ * Tests <code>NearestConflictResolver</code>.
+ *
+ * @author <a href="mailto:markhobson@gmail.com">Mark Hobson</a>
+ * @see NearestConflictResolver
+ */
+public class NearestConflictResolverTest
+ extends AbstractConflictResolverTest
+{
+ // constructors -----------------------------------------------------------
+
+ public NearestConflictResolverTest()
+ throws Exception
+ {
+ super("nearest");
+ }
+
+ // tests ------------------------------------------------------------------
+
+ /**
+ * Tests that <code>a:1.0</code> wins in the scenario:
+ * <pre>
+ * a:1.0
+ * b:1.0 -> a:2.0
+ * </pre>
+ */
+ public void testDepth()
+ {
+ ResolutionNode a1n = new ResolutionNode( a1, Collections.EMPTY_LIST );
+ ResolutionNode b1n = new ResolutionNode( b1, Collections.EMPTY_LIST );
+ ResolutionNode a2n = new ResolutionNode( a2, Collections.EMPTY_LIST, b1n );
+
+ assertResolveConflict( a1n, a1n, a2n );
+ }
+
+ /**
+ * Tests that <code>a:1.0</code> wins in the scenario:
+ * <pre>
+ * b:1.0 -> a:2.0
+ * a:1.0
+ * </pre>
+ */
+ public void testDepthReversed()
+ {
+ ResolutionNode b1n = new ResolutionNode( b1, Collections.EMPTY_LIST );
+ ResolutionNode a2n = new ResolutionNode( a2, Collections.EMPTY_LIST, b1n );
+ ResolutionNode a1n = new ResolutionNode( a1, Collections.EMPTY_LIST );
+
+ assertResolveConflict( a1n, a2n, a1n );
+ }
+
+ /**
+ * Tests that <code>a:1.0</code> wins in the scenario:
+ * <pre>
+ * a:1.0
+ * a:2.0
+ * </pre>
+ */
+ public void testEqual()
+ {
+ ResolutionNode a1n = new ResolutionNode( a1, Collections.EMPTY_LIST );
+ ResolutionNode a2n = new ResolutionNode( a2, Collections.EMPTY_LIST );
+
+ assertResolveConflict( a1n, a1n, a2n );
+ }
+
+ /**
+ * Tests that <code>a:2.0</code> wins in the scenario:
+ * <pre>
+ * a:2.0
+ * a:1.0
+ * </pre>
+ */
+ public void testEqualReversed()
+ {
+ ResolutionNode a2n = new ResolutionNode( a2, Collections.EMPTY_LIST );
+ ResolutionNode a1n = new ResolutionNode( a1, Collections.EMPTY_LIST );
+
+ assertResolveConflict( a2n, a2n, a1n );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/legacy/resolver/conflict/NewestConflictResolverTest.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/legacy/resolver/conflict/NewestConflictResolverTest.java
new file mode 100644
index 00000000..68d19d6c
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/legacy/resolver/conflict/NewestConflictResolverTest.java
@@ -0,0 +1,107 @@
+package org.apache.maven.repository.legacy.resolver.conflict;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Collections;
+
+import org.apache.maven.artifact.resolver.ResolutionNode;
+import org.apache.maven.repository.legacy.resolver.conflict.NewestConflictResolver;
+
+/**
+ * Tests <code>NewestConflictResolver</code>.
+ *
+ * @author <a href="mailto:markhobson@gmail.com">Mark Hobson</a>
+ * @see NewestConflictResolver
+ */
+public class NewestConflictResolverTest
+ extends AbstractConflictResolverTest
+{
+ // constructors -----------------------------------------------------------
+
+ public NewestConflictResolverTest()
+ throws Exception
+ {
+ super("newest");
+ }
+
+ // tests ------------------------------------------------------------------
+
+ /**
+ * Tests that <code>a:2.0</code> wins in the scenario:
+ * <pre>
+ * a:1.0
+ * b:1.0 -> a:2.0
+ * </pre>
+ */
+ public void testDepth()
+ {
+ ResolutionNode a1n = new ResolutionNode( a1, Collections.EMPTY_LIST );
+ ResolutionNode b1n = new ResolutionNode( b1, Collections.EMPTY_LIST );
+ ResolutionNode a2n = new ResolutionNode( a2, Collections.EMPTY_LIST, b1n );
+
+ assertResolveConflict( a2n, a1n, a2n );
+ }
+
+ /**
+ * Tests that <code>a:2.0</code> wins in the scenario:
+ * <pre>
+ * b:1.0 -> a:2.0
+ * a:1.0
+ * </pre>
+ */
+ public void testDepthReversed()
+ {
+ ResolutionNode b1n = new ResolutionNode( b1, Collections.EMPTY_LIST );
+ ResolutionNode a2n = new ResolutionNode( a2, Collections.EMPTY_LIST, b1n );
+ ResolutionNode a1n = new ResolutionNode( a1, Collections.EMPTY_LIST );
+
+ assertResolveConflict( a2n, a2n, a1n );
+ }
+
+ /**
+ * Tests that <code>a:2.0</code> wins in the scenario:
+ * <pre>
+ * a:1.0
+ * a:2.0
+ * </pre>
+ */
+ public void testEqual()
+ {
+ ResolutionNode a1n = new ResolutionNode( a1, Collections.EMPTY_LIST );
+ ResolutionNode a2n = new ResolutionNode( a2, Collections.EMPTY_LIST );
+
+ assertResolveConflict( a2n, a1n, a2n );
+ }
+
+ /**
+ * Tests that <code>a:2.0</code> wins in the scenario:
+ * <pre>
+ * a:2.0
+ * a:1.0
+ * </pre>
+ */
+ public void testEqualReversed()
+ {
+ ResolutionNode a2n = new ResolutionNode( a2, Collections.EMPTY_LIST );
+ ResolutionNode a1n = new ResolutionNode( a1, Collections.EMPTY_LIST );
+
+ assertResolveConflict( a2n, a2n, a1n );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/legacy/resolver/conflict/OldestConflictResolverTest.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/legacy/resolver/conflict/OldestConflictResolverTest.java
new file mode 100644
index 00000000..6b06d34e
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/legacy/resolver/conflict/OldestConflictResolverTest.java
@@ -0,0 +1,107 @@
+package org.apache.maven.repository.legacy.resolver.conflict;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Collections;
+
+import org.apache.maven.artifact.resolver.ResolutionNode;
+import org.apache.maven.repository.legacy.resolver.conflict.OldestConflictResolver;
+
+/**
+ * Tests <code>OldestConflictResolver</code>.
+ *
+ * @author <a href="mailto:markhobson@gmail.com">Mark Hobson</a>
+ * @see OldestConflictResolver
+ */
+public class OldestConflictResolverTest
+ extends AbstractConflictResolverTest
+{
+ // constructors -----------------------------------------------------------
+
+ public OldestConflictResolverTest()
+ throws Exception
+ {
+ super("oldest");
+ }
+
+ // tests ------------------------------------------------------------------
+
+ /**
+ * Tests that <code>a:1.0</code> wins in the scenario:
+ * <pre>
+ * a:1.0
+ * b:1.0 -> a:2.0
+ * </pre>
+ */
+ public void testDepth()
+ {
+ ResolutionNode a1n = new ResolutionNode( a1, Collections.EMPTY_LIST );
+ ResolutionNode b1n = new ResolutionNode( b1, Collections.EMPTY_LIST );
+ ResolutionNode a2n = new ResolutionNode( a2, Collections.EMPTY_LIST, b1n );
+
+ assertResolveConflict( a1n, a1n, a2n );
+ }
+
+ /**
+ * Tests that <code>a:1.0</code> wins in the scenario:
+ * <pre>
+ * b:1.0 -> a:2.0
+ * a:1.0
+ * </pre>
+ */
+ public void testDepthReversed()
+ {
+ ResolutionNode b1n = new ResolutionNode( b1, Collections.EMPTY_LIST );
+ ResolutionNode a2n = new ResolutionNode( a2, Collections.EMPTY_LIST, b1n );
+ ResolutionNode a1n = new ResolutionNode( a1, Collections.EMPTY_LIST );
+
+ assertResolveConflict( a1n, a2n, a1n );
+ }
+
+ /**
+ * Tests that <code>a:1.0</code> wins in the scenario:
+ * <pre>
+ * a:1.0
+ * a:2.0
+ * </pre>
+ */
+ public void testEqual()
+ {
+ ResolutionNode a1n = new ResolutionNode( a1, Collections.EMPTY_LIST );
+ ResolutionNode a2n = new ResolutionNode( a2, Collections.EMPTY_LIST );
+
+ assertResolveConflict( a1n, a1n, a2n );
+ }
+
+ /**
+ * Tests that <code>a:1.0</code> wins in the scenario:
+ * <pre>
+ * a:2.0
+ * a:1.0
+ * </pre>
+ */
+ public void testEqualReversed()
+ {
+ ResolutionNode a2n = new ResolutionNode( a2, Collections.EMPTY_LIST );
+ ResolutionNode a1n = new ResolutionNode( a1, Collections.EMPTY_LIST );
+
+ assertResolveConflict( a1n, a2n, a1n );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/metadata/DefaultClasspathTransformationTest.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/metadata/DefaultClasspathTransformationTest.java
new file mode 100644
index 00000000..4f40516c
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/metadata/DefaultClasspathTransformationTest.java
@@ -0,0 +1,120 @@
+package org.apache.maven.repository.metadata;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+import org.apache.maven.artifact.ArtifactScopeEnum;
+import org.apache.maven.repository.metadata.ArtifactMetadata;
+import org.apache.maven.repository.metadata.ClasspathContainer;
+import org.apache.maven.repository.metadata.ClasspathTransformation;
+import org.apache.maven.repository.metadata.MetadataGraph;
+import org.apache.maven.repository.metadata.MetadataGraphEdge;
+import org.apache.maven.repository.metadata.MetadataGraphVertex;
+import org.codehaus.plexus.PlexusTestCase;
+
+/**
+ *
+ * @author <a href="mailto:oleg@codehaus.org">Oleg Gusakov</a>
+ *
+ */
+
+public class DefaultClasspathTransformationTest
+extends PlexusTestCase
+{
+ ClasspathTransformation transform;
+
+ MetadataGraph graph;
+
+ MetadataGraphVertex v1;
+ MetadataGraphVertex v2;
+ MetadataGraphVertex v3;
+ MetadataGraphVertex v4;
+ //------------------------------------------------------------------------------------------
+ @Override
+ protected void setUp() throws Exception
+ {
+ super.setUp();
+ transform = (ClasspathTransformation) lookup( ClasspathTransformation.ROLE, "default" );
+
+ graph = new MetadataGraph( 4, 3 );
+ /*
+ * v2
+ * v1<
+ * v3-v4
+ *
+ */
+ v1 = graph.addVertex(new ArtifactMetadata("g","a1","1.0"));
+ graph.setEntry(v1);
+ v2 = graph.addVertex(new ArtifactMetadata("g","a2","1.0"));
+ v3 = graph.addVertex(new ArtifactMetadata("g","a3","1.0"));
+ v4 = graph.addVertex(new ArtifactMetadata("g","a4","1.0"));
+
+ // v1-->v2
+ graph.addEdge(v1, v2, new MetadataGraphEdge( "1.1", true, null, null, 2, 1 ) );
+ graph.addEdge(v1, v2, new MetadataGraphEdge( "1.2", true, null, null, 2, 2 ) );
+
+ // v1-->v3
+ graph.addEdge(v1, v3, new MetadataGraphEdge( "1.1", true, null, null, 2, 1 ) );
+ graph.addEdge(v1, v3, new MetadataGraphEdge( "1.2", true, null, null, 4, 2 ) );
+
+ // v3-->v4
+ graph.addEdge(v3, v4, new MetadataGraphEdge( "1.1", true, ArtifactScopeEnum.runtime, null, 2, 2 ) );
+ graph.addEdge(v3, v4, new MetadataGraphEdge( "1.2", true, ArtifactScopeEnum.test, null, 2, 2 ) );
+ }
+ //------------------------------------------------------------------------------------------
+ public void testCompileClasspathTransform()
+ throws Exception
+ {
+ ClasspathContainer res;
+
+ res = transform.transform( graph, ArtifactScopeEnum.compile, false );
+
+ assertNotNull("null classpath container after compile transform", res );
+ assertNotNull("null classpath after compile transform", res.getClasspath() );
+ assertEquals("compile classpath should have 3 entries", 3, res.getClasspath().size() );
+ }
+ //------------------------------------------------------------------------------------------
+ public void testRuntimeClasspathTransform()
+ throws Exception
+ {
+ ClasspathContainer res;
+
+ res = transform.transform( graph, ArtifactScopeEnum.runtime, false );
+
+ assertNotNull("null classpath container after runtime transform", res );
+ assertNotNull("null classpath after runtime transform", res.getClasspath() );
+ assertEquals("runtime classpath should have 4 entries", 4, res.getClasspath().size() );
+
+ ArtifactMetadata md = res.getClasspath().get(3);
+ assertEquals("runtime artifact version should be 1.1", "1.1", md.getVersion() );
+ }
+ //------------------------------------------------------------------------------------------
+ public void testTestClasspathTransform()
+ throws Exception
+ {
+ ClasspathContainer res;
+
+ res = transform.transform( graph, ArtifactScopeEnum.test, false );
+
+ assertNotNull("null classpath container after runtime transform", res );
+ assertNotNull("null classpath after runtime transform", res.getClasspath() );
+ assertEquals("runtime classpath should have 4 entries", 4, res.getClasspath().size() );
+
+ ArtifactMetadata md = res.getClasspath().get(3);
+ assertEquals("test artifact version should be 1.2", "1.2", md.getVersion() );
+ }
+ //------------------------------------------------------------------------------------------
+ //------------------------------------------------------------------------------------------
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/metadata/DefaultGraphConflictResolutionPolicyTest.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/metadata/DefaultGraphConflictResolutionPolicyTest.java
new file mode 100644
index 00000000..31832c33
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/metadata/DefaultGraphConflictResolutionPolicyTest.java
@@ -0,0 +1,59 @@
+package org.apache.maven.repository.metadata;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+import org.apache.maven.repository.metadata.GraphConflictResolutionPolicy;
+import org.apache.maven.repository.metadata.MetadataGraphEdge;
+import org.codehaus.plexus.PlexusTestCase;
+
+/**
+ *
+ * @author <a href="mailto:oleg@codehaus.org">Oleg Gusakov</a>
+ *
+ */
+
+public class DefaultGraphConflictResolutionPolicyTest
+extends PlexusTestCase
+{
+ GraphConflictResolutionPolicy policy;
+ MetadataGraphEdge e1;
+ MetadataGraphEdge e2;
+ MetadataGraphEdge e3;
+ //------------------------------------------------------------------------------------------
+ @Override
+ protected void setUp() throws Exception
+ {
+ super.setUp();
+ policy = (GraphConflictResolutionPolicy) lookup( GraphConflictResolutionPolicy.ROLE, "default" );
+ e1 = new MetadataGraphEdge( "1.1", true, null, null, 2, 1 );
+ e2 = new MetadataGraphEdge( "1.2", true, null, null, 3, 2 );
+ e3 = new MetadataGraphEdge( "1.2", true, null, null, 2, 3 );
+ }
+ //------------------------------------------------------------------------------------------
+ public void testDefaultPolicy()
+ throws Exception
+ {
+ MetadataGraphEdge res;
+
+ res = policy.apply( e1, e2 );
+ assertEquals( "Wrong depth edge selected", "1.1", res.getVersion() );
+
+ res = policy.apply( e1, e3 );
+ assertEquals( "Wrong version edge selected", "1.2", res.getVersion() );
+ }
+ //------------------------------------------------------------------------------------------
+ //------------------------------------------------------------------------------------------
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/metadata/DefaultGraphConflictResolverTest.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/metadata/DefaultGraphConflictResolverTest.java
new file mode 100644
index 00000000..4fba8f54
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/metadata/DefaultGraphConflictResolverTest.java
@@ -0,0 +1,153 @@
+package org.apache.maven.repository.metadata;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+import org.apache.maven.artifact.ArtifactScopeEnum;
+import org.apache.maven.repository.metadata.ArtifactMetadata;
+import org.apache.maven.repository.metadata.GraphConflictResolver;
+import org.apache.maven.repository.metadata.MetadataGraph;
+import org.apache.maven.repository.metadata.MetadataGraphEdge;
+import org.apache.maven.repository.metadata.MetadataGraphVertex;
+import org.codehaus.plexus.PlexusTestCase;
+import org.codehaus.plexus.logging.Logger;
+
+/**
+ *
+ * @author <a href="mailto:oleg@codehaus.org">Oleg Gusakov</a>
+ *
+ */
+
+public class DefaultGraphConflictResolverTest
+extends PlexusTestCase
+{
+ Logger log;
+
+ GraphConflictResolver resolver;
+
+ MetadataGraph graph;
+
+ MetadataGraphVertex v1;
+ MetadataGraphVertex v2;
+ MetadataGraphVertex v3;
+ MetadataGraphVertex v4;
+ //------------------------------------------------------------------------------------------
+ @Override
+ protected void setUp() throws Exception
+ {
+ super.setUp();
+ resolver = (GraphConflictResolver) lookup( GraphConflictResolver.ROLE, "default" );
+
+ /*
+ * v2
+ * v1<
+ * v3-v4
+ *
+ */
+ graph = new MetadataGraph( 4, 3 );
+ v1 = graph.addVertex(new ArtifactMetadata("g","a1","1.0"));
+ graph.setEntry(v1);
+ v2 = graph.addVertex(new ArtifactMetadata("g","a2","1.0"));
+ v3 = graph.addVertex(new ArtifactMetadata("g","a3","1.0"));
+ v4 = graph.addVertex(new ArtifactMetadata("g","a4","1.0"));
+
+ // v1-->v2
+ graph.addEdge(v1, v2, new MetadataGraphEdge( "1.1", true, null, null, 2, 1 ) );
+ graph.addEdge(v1, v2, new MetadataGraphEdge( "1.2", true, null, null, 2, 2 ) );
+
+ // v1-->v3
+ graph.addEdge(v1, v3, new MetadataGraphEdge( "1.1", true, null, null, 2, 1 ) );
+ graph.addEdge(v1, v3, new MetadataGraphEdge( "1.2", true, null, null, 4, 2 ) );
+
+ // v3-->v4
+ graph.addEdge(v3, v4, new MetadataGraphEdge( "1.1", true, ArtifactScopeEnum.runtime, null, 2, 1 ) );
+ graph.addEdge(v3, v4, new MetadataGraphEdge( "1.2", true, ArtifactScopeEnum.provided, null, 2, 2 ) );
+ }
+ //------------------------------------------------------------------------------------------
+ public void testCompileResolution()
+ throws Exception
+ {
+ MetadataGraph res;
+
+ res = resolver.resolveConflicts( graph, ArtifactScopeEnum.compile );
+
+ assertNotNull("null graph after resolver", res );
+ assertNotNull("no vertices in the resulting graph after resolver", res.getVertices() );
+
+ assertNotNull("no edges in the resulting graph after resolver", res.getExcidentEdges(v1) );
+
+ assertEquals( "wrong # of vertices in the resulting graph after resolver", 4, res.getVertices().size() );
+ assertEquals( "wrong # of excident edges in the resulting graph entry after resolver", 2, res.getExcidentEdges(v1).size() );
+
+ assertEquals( "wrong # of v2 incident edges in the resulting graph after resolver", 1, res.getIncidentEdges(v2).size() );
+ assertEquals( "wrong edge v1-v2 in the resulting graph after resolver", "1.2", res.getIncidentEdges(v2).get(0).getVersion() );
+
+ assertEquals( "wrong # of edges v1-v3 in the resulting graph after resolver", 1, res.getIncidentEdges(v3).size() );
+ assertEquals( "wrong edge v1-v3 in the resulting graph after resolver", "1.1", res.getIncidentEdges(v3).get(0).getVersion() );
+
+ assertEquals( "wrong # of edges v3-v4 in the resulting graph after resolver", 1, res.getIncidentEdges(v4).size() );
+ assertEquals( "wrong edge v3-v4 in the resulting graph after resolver", "1.2", res.getIncidentEdges(v4).get(0).getVersion() );
+ }
+ //------------------------------------------------------------------------------------------
+ public void testRuntimeResolution()
+ throws Exception
+ {
+ MetadataGraph res;
+
+ res = resolver.resolveConflicts( graph, ArtifactScopeEnum.runtime );
+
+ assertNotNull("null graph after resolver", res );
+ assertNotNull("no vertices in the resulting graph after resolver", res.getVertices() );
+ assertNotNull("no edges in the resulting graph after resolver", res.getExcidentEdges(v1) );
+
+ assertEquals( "wrong # of vertices in the resulting graph after resolver", 4, res.getVertices().size() );
+ assertEquals( "wrong # of excident edges in the resulting graph entry after resolver", 2, res.getExcidentEdges(v1).size() );
+
+ assertEquals( "wrong # of v2 incident edges in the resulting graph after resolver", 1, res.getIncidentEdges(v2).size() );
+ assertEquals( "wrong edge v1-v2 in the resulting graph after resolver", "1.2", res.getIncidentEdges(v2).get(0).getVersion() );
+
+ assertEquals( "wrong # of edges v1-v3 in the resulting graph after resolver", 1, res.getIncidentEdges(v3).size() );
+ assertEquals( "wrong edge v1-v3 in the resulting graph after resolver", "1.1", res.getIncidentEdges(v3).get(0).getVersion() );
+
+ assertEquals( "wrong # of edges v3-v4 in the resulting graph after resolver", 1, res.getIncidentEdges(v4).size() );
+ assertEquals( "wrong edge v3-v4 in the resulting graph after resolver", "1.1", res.getIncidentEdges(v4).get(0).getVersion() );
+ }
+ //------------------------------------------------------------------------------------------
+ public void testTestResolution()
+ throws Exception
+ {
+ MetadataGraph res;
+
+ res = resolver.resolveConflicts( graph, ArtifactScopeEnum.test );
+
+ assertNotNull("null graph after resolver", res );
+ assertNotNull("no vertices in the resulting graph after resolver", res.getVertices() );
+ assertNotNull("no edges in the resulting graph after resolver", res.getExcidentEdges(v1) );
+
+ assertEquals( "wrong # of vertices in the resulting graph after resolver", 4, res.getVertices().size() );
+ assertEquals( "wrong # of excident edges in the resulting graph entry after resolver", 2, res.getExcidentEdges(v1).size() );
+
+ assertEquals( "wrong # of v2 incident edges in the resulting graph after resolver", 1, res.getIncidentEdges(v2).size() );
+ assertEquals( "wrong edge v1-v2 in the resulting graph after resolver", "1.2", res.getIncidentEdges(v2).get(0).getVersion() );
+
+ assertEquals( "wrong # of edges v1-v3 in the resulting graph after resolver", 1, res.getIncidentEdges(v3).size() );
+ assertEquals( "wrong edge v1-v3 in the resulting graph after resolver", "1.1", res.getIncidentEdges(v3).get(0).getVersion() );
+
+ assertEquals( "wrong # of edges v3-v4 in the resulting graph after resolver", 1, res.getIncidentEdges(v4).size() );
+ assertEquals( "wrong edge v3-v4 in the resulting graph after resolver", "1.2", res.getIncidentEdges(v4).get(0).getVersion() );
+ }
+ //------------------------------------------------------------------------------------------
+ //------------------------------------------------------------------------------------------
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/metadata/TestMetadataSource.java b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/metadata/TestMetadataSource.java
new file mode 100644
index 00000000..dd9a9001
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/java/org/apache/maven/repository/metadata/TestMetadataSource.java
@@ -0,0 +1,99 @@
+package org.apache.maven.repository.metadata;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.factory.ArtifactFactory;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.versioning.ArtifactVersion;
+import org.apache.maven.repository.legacy.metadata.ArtifactMetadataRetrievalException;
+import org.apache.maven.repository.legacy.metadata.ArtifactMetadataSource;
+import org.apache.maven.repository.legacy.metadata.MetadataResolutionRequest;
+import org.apache.maven.repository.legacy.metadata.ResolutionGroup;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+
+@Component(role = ArtifactMetadataSource.class)
+public class TestMetadataSource
+ implements ArtifactMetadataSource
+{
+ @Requirement
+ private ArtifactFactory factory;
+
+ public ResolutionGroup retrieve( Artifact artifact, ArtifactRepository localRepository, List<ArtifactRepository> remoteRepositories )
+ throws ArtifactMetadataRetrievalException
+ {
+ Set dependencies = new HashSet();
+
+ if ( "g".equals( artifact.getArtifactId() ) )
+ {
+ Artifact a = null;
+ try
+ {
+ a = factory.createBuildArtifact( "org.apache.maven", "h", "1.0", "jar" );
+ dependencies.add( a );
+ }
+ catch ( Exception e )
+ {
+ throw new ArtifactMetadataRetrievalException( "Error retrieving metadata", e, a );
+ }
+ }
+
+ if ( "i".equals( artifact.getArtifactId() ) )
+ {
+ Artifact a = null;
+ try
+ {
+ a = factory.createBuildArtifact( "org.apache.maven", "j", "1.0-SNAPSHOT", "jar" );
+ dependencies.add( a );
+ }
+ catch ( Exception e )
+ {
+ throw new ArtifactMetadataRetrievalException( "Error retrieving metadata", e, a );
+ }
+ }
+
+
+ return new ResolutionGroup( artifact, dependencies, remoteRepositories );
+ }
+
+ public List<ArtifactVersion> retrieveAvailableVersions( Artifact artifact, ArtifactRepository localRepository, List<ArtifactRepository> remoteRepositories )
+ throws ArtifactMetadataRetrievalException
+ {
+ throw new UnsupportedOperationException( "Cannot get available versions in this test case" );
+ }
+
+ public List<ArtifactVersion> retrieveAvailableVersionsFromDeploymentRepository( Artifact artifact, ArtifactRepository localRepository, ArtifactRepository remoteRepository )
+ throws ArtifactMetadataRetrievalException
+ {
+ throw new UnsupportedOperationException( "Cannot get available versions in this test case" );
+ }
+
+ public ResolutionGroup retrieve( MetadataResolutionRequest request )
+ throws ArtifactMetadataRetrievalException
+ {
+ return retrieve( request.getArtifact(), request.getLocalRepository(), request.getRemoteRepositories() );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/remote-repo/org/apache/maven/its/a/0.1/a-0.1.jar b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/remote-repo/org/apache/maven/its/a/0.1/a-0.1.jar
new file mode 100644
index 00000000..609ec21b
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/remote-repo/org/apache/maven/its/a/0.1/a-0.1.jar
Binary files differ
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/remote-repo/org/apache/maven/its/a/0.1/a-0.1.pom b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/remote-repo/org/apache/maven/its/a/0.1/a-0.1.pom
new file mode 100644
index 00000000..f4514188
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/remote-repo/org/apache/maven/its/a/0.1/a-0.1.pom
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its</groupId>
+ <artifactId>a</artifactId>
+ <version>0.1</version>
+ <packaging>jar</packaging>
+
+ <name>Maven Integration Test :: Dummy Artifact</name>
+ <description>
+
+ </description>
+
+ <distributionManagement>
+ <repository>
+ <id>maven-core-it</id>
+ <url>file:///${basedir}/repo</url>
+ </repository>
+ </distributionManagement>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/remote-repo/org/apache/maven/its/a/maven-metadata.xml b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/remote-repo/org/apache/maven/its/a/maven-metadata.xml
new file mode 100644
index 00000000..8099175e
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/remote-repo/org/apache/maven/its/a/maven-metadata.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<metadata>
+ <groupId>org.apache.maven.its</groupId>
+ <artifactId>a</artifactId>
+ <version>0.1</version>
+ <versioning>
+ <versions>
+ <version>0.1</version>
+ </versions>
+ <lastUpdated>20091023222756</lastUpdated>
+ </versioning>
+</metadata>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/remote-repo/org/apache/maven/its/b/0.1/b-0.1.jar b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/remote-repo/org/apache/maven/its/b/0.1/b-0.1.jar
new file mode 100644
index 00000000..19df0485
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/remote-repo/org/apache/maven/its/b/0.1/b-0.1.jar
Binary files differ
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/remote-repo/org/apache/maven/its/b/0.1/b-0.1.pom b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/remote-repo/org/apache/maven/its/b/0.1/b-0.1.pom
new file mode 100644
index 00000000..ca20cbf5
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/remote-repo/org/apache/maven/its/b/0.1/b-0.1.pom
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its</groupId>
+ <artifactId>b</artifactId>
+ <version>0.1</version>
+ <packaging>jar</packaging>
+
+ <name>Maven Integration Test :: Dummy Artifact</name>
+ <description>
+
+ </description>
+
+ <distributionManagement>
+ <repository>
+ <id>maven-core-it</id>
+ <url>file:///${basedir}/repo</url>
+ </repository>
+ </distributionManagement>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven.its</groupId>
+ <artifactId>a</artifactId>
+ <version>0.1</version>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/remote-repo/org/apache/maven/its/b/maven-metadata.xml b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/remote-repo/org/apache/maven/its/b/maven-metadata.xml
new file mode 100644
index 00000000..e77af628
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/remote-repo/org/apache/maven/its/b/maven-metadata.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<metadata>
+ <groupId>org.apache.maven.its</groupId>
+ <artifactId>b</artifactId>
+ <version>0.1</version>
+ <versioning>
+ <versions>
+ <version>0.1</version>
+ </versions>
+ <lastUpdated>20091023222817</lastUpdated>
+ </versioning>
+</metadata>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/repository-system/maven-core-2.1.0.jar b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/repository-system/maven-core-2.1.0.jar
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/repository-system/maven-core-2.1.0.jar
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/artifact-install/artifact-1.0.jar b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/artifact-install/artifact-1.0.jar
new file mode 100644
index 00000000..421376db
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/artifact-install/artifact-1.0.jar
@@ -0,0 +1 @@
+dummy
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t00/maven/poms/p0-1.0.pom b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t00/maven/poms/p0-1.0.pom
new file mode 100644
index 00000000..92c9f41d
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t00/maven/poms/p0-1.0.pom
@@ -0,0 +1,11 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven</groupId>
+ <artifactId>p0</artifactId>
+ <packaging>pom</packaging>
+ <name>p0</name>
+ <version>1.0</version>
+ <organization>
+ <name>Codehaus</name>
+ </organization>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t00/maven/poms/p1-1.0.pom b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t00/maven/poms/p1-1.0.pom
new file mode 100644
index 00000000..6038a806
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t00/maven/poms/p1-1.0.pom
@@ -0,0 +1,16 @@
+<project>
+ <parent>
+ <artifactId>p0</artifactId>
+ <groupId>maven</groupId>
+ <version>1.0</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven</groupId>
+ <artifactId>p1</artifactId>
+ <packaging>pom</packaging>
+ <name>p1</name>
+ <version>1.0</version>
+ <scm>
+ <url>scm-url</url>
+ </scm>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t00/maven/poms/p2-1.0.pom b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t00/maven/poms/p2-1.0.pom
new file mode 100644
index 00000000..9ac112ac
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t00/maven/poms/p2-1.0.pom
@@ -0,0 +1,18 @@
+<project>
+ <parent>
+ <artifactId>p1</artifactId>
+ <groupId>maven</groupId>
+ <version>1.0</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven</groupId>
+ <artifactId>p2</artifactId>
+ <packaging>pom</packaging>
+ <name>p2</name>
+ <version>1.0</version>
+ <mailingLists>
+ <mailingList>
+ <name>mailing-list</name>
+ </mailingList>
+ </mailingLists>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t00/maven/poms/p3-1.0.pom b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t00/maven/poms/p3-1.0.pom
new file mode 100644
index 00000000..d40684e9
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t00/maven/poms/p3-1.0.pom
@@ -0,0 +1,14 @@
+<project>
+ <parent>
+ <artifactId>p2</artifactId>
+ <groupId>maven</groupId>
+ <version>1.0</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven</groupId>
+ <artifactId>p3</artifactId>
+ <packaging>pom</packaging>
+ <name>p3</name>
+ <version>1.0</version>
+ <inceptionYear>2000</inceptionYear>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t00/maven/poms/p4-1.0.pom b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t00/maven/poms/p4-1.0.pom
new file mode 100644
index 00000000..dc9a2735
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t00/maven/poms/p4-1.0.pom
@@ -0,0 +1,13 @@
+<project>
+ <parent>
+ <artifactId>p3</artifactId>
+ <groupId>maven</groupId>
+ <version>1.0</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven</groupId>
+ <artifactId>p4</artifactId>
+ <packaging>jar</packaging>
+ <name>p4</name>
+ <version>1.0</version>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t01/maven.t01/poms/p0-1.0.pom b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t01/maven.t01/poms/p0-1.0.pom
new file mode 100644
index 00000000..9df2582d
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t01/maven.t01/poms/p0-1.0.pom
@@ -0,0 +1,11 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven.t01</groupId>
+ <artifactId>p0</artifactId>
+ <packaging>pom</packaging>
+ <name>p0</name>
+ <version>1.0</version>
+ <organization>
+ <name>p0-org</name>
+ </organization>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t01/maven.t01/poms/p1-1.0.pom b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t01/maven.t01/poms/p1-1.0.pom
new file mode 100644
index 00000000..4fc81d83
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t01/maven.t01/poms/p1-1.0.pom
@@ -0,0 +1,16 @@
+<project>
+ <parent>
+ <artifactId>p0</artifactId>
+ <groupId>maven.t01</groupId>
+ <version>1.0</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven.t01</groupId>
+ <artifactId>p1</artifactId>
+ <packaging>pom</packaging>
+ <name>p1</name>
+ <version>1.0</version>
+ <organization>
+ <name>p1-org</name>
+ </organization>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t01/maven.t01/poms/p2-1.0.pom b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t01/maven.t01/poms/p2-1.0.pom
new file mode 100644
index 00000000..8032cf2f
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t01/maven.t01/poms/p2-1.0.pom
@@ -0,0 +1,16 @@
+<project>
+ <parent>
+ <artifactId>p1</artifactId>
+ <groupId>maven.t01</groupId>
+ <version>1.0</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven.t01</groupId>
+ <artifactId>p2</artifactId>
+ <packaging>pom</packaging>
+ <name>p2</name>
+ <version>1.0</version>
+ <organization>
+ <name>p2-org</name>
+ </organization>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t01/maven.t01/poms/p3-1.0.pom b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t01/maven.t01/poms/p3-1.0.pom
new file mode 100644
index 00000000..6ed58569
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t01/maven.t01/poms/p3-1.0.pom
@@ -0,0 +1,16 @@
+<project>
+ <parent>
+ <artifactId>p2</artifactId>
+ <groupId>maven.t01</groupId>
+ <version>1.0</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven.t01</groupId>
+ <artifactId>p3</artifactId>
+ <packaging>pom</packaging>
+ <name>p3</name>
+ <version>1.0</version>
+ <organization>
+ <name>p3-org</name>
+ </organization>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t01/maven.t01/poms/p4-1.0.pom b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t01/maven.t01/poms/p4-1.0.pom
new file mode 100644
index 00000000..1739333a
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t01/maven.t01/poms/p4-1.0.pom
@@ -0,0 +1,16 @@
+<project>
+ <parent>
+ <artifactId>p3</artifactId>
+ <groupId>maven.t01</groupId>
+ <version>1.0</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven.t01</groupId>
+ <artifactId>p4</artifactId>
+ <packaging>jar</packaging>
+ <name>p4</name>
+ <version>1.0</version>
+ <organization>
+ <name>p4-org</name>
+ </organization>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t02/p0/p1/p2/p3/p4/p5/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t02/p0/p1/p2/p3/p4/p5/pom.xml
new file mode 100644
index 00000000..93d1d72f
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t02/p0/p1/p2/p3/p4/p5/pom.xml
@@ -0,0 +1,32 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <parent>
+ <artifactId>p4</artifactId>
+ <groupId>maven.t02</groupId>
+ <version>1.0</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven.t02</groupId>
+ <artifactId>p5</artifactId>
+ <packaging>jar</packaging>
+ <name>p5</name>
+ <version>1.0</version>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t02/p0/p1/p2/p3/p4/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t02/p0/p1/p2/p3/p4/pom.xml
new file mode 100644
index 00000000..77958f78
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t02/p0/p1/p2/p3/p4/pom.xml
@@ -0,0 +1,32 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <parent>
+ <artifactId>p3</artifactId>
+ <groupId>maven.t02</groupId>
+ <version>1.0</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven.t02</groupId>
+ <artifactId>p4</artifactId>
+ <packaging>pom</packaging>
+ <name>p4</name>
+ <version>1.0</version>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t02/p0/p1/p2/p3/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t02/p0/p1/p2/p3/pom.xml
new file mode 100644
index 00000000..d83de976
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t02/p0/p1/p2/p3/pom.xml
@@ -0,0 +1,33 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <parent>
+ <artifactId>p2</artifactId>
+ <groupId>maven.t02</groupId>
+ <version>1.0</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven.t02</groupId>
+ <artifactId>p3</artifactId>
+ <packaging>pom</packaging>
+ <name>p3</name>
+ <version>1.0</version>
+ <inceptionYear>2000</inceptionYear>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t02/p0/p1/p2/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t02/p0/p1/p2/pom.xml
new file mode 100644
index 00000000..c2b7d715
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t02/p0/p1/p2/pom.xml
@@ -0,0 +1,37 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <parent>
+ <artifactId>p1</artifactId>
+ <groupId>maven.t02</groupId>
+ <version>1.0</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven.t02</groupId>
+ <artifactId>p2</artifactId>
+ <packaging>pom</packaging>
+ <name>p2</name>
+ <version>1.0</version>
+ <mailingLists>
+ <mailingList>
+ <name>mailing-list</name>
+ </mailingList>
+ </mailingLists>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t02/p0/p1/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t02/p0/p1/pom.xml
new file mode 100644
index 00000000..af2d92ed
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t02/p0/p1/pom.xml
@@ -0,0 +1,51 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <parent>
+ <artifactId>p0</artifactId>
+ <groupId>maven.t02</groupId>
+ <version>1.0</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven.t02</groupId>
+ <artifactId>p1</artifactId>
+ <packaging>pom</packaging>
+ <name>p1</name>
+ <version>1.0</version>
+ <scm>
+ <url>scm-url</url>
+ </scm>
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>test</id>
+ <phase>package</phase>
+ <goals>
+ <goal>compile</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t02/p0/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t02/p0/pom.xml
new file mode 100644
index 00000000..3643fe49
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t02/p0/pom.xml
@@ -0,0 +1,30 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven.t02</groupId>
+ <artifactId>p0</artifactId>
+ <packaging>pom</packaging>
+ <name>p0</name>
+ <version>1.0</version>
+ <organization>
+ <name>Codehaus</name>
+ </organization>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t03/p0/p1/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t03/p0/p1/pom.xml
new file mode 100644
index 00000000..69fe6a1d
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t03/p0/p1/pom.xml
@@ -0,0 +1,45 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <parent>
+ <artifactId>p0</artifactId>
+ <groupId>maven.t03</groupId>
+ <version>1.0</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven.t03</groupId>
+ <artifactId>p1</artifactId>
+ <packaging>pom</packaging>
+ <name>p1</name>
+ <version>1.0</version>
+ <scm>
+ <url>scm-url</url>
+ </scm>
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-antrun-plugin</artifactId>
+ <configuration>
+ <tasks><echo>${project.parent.basedir}</echo></tasks>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t03/p0/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t03/p0/pom.xml
new file mode 100644
index 00000000..476ffdfb
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t03/p0/pom.xml
@@ -0,0 +1,30 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven.t03</groupId>
+ <artifactId>p0</artifactId>
+ <packaging>pom</packaging>
+ <name>p0</name>
+ <version>1.0</version>
+ <organization>
+ <name>Codehaus</name>
+ </organization>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t04/maven-test/jars/t04-a-1.0.jar b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t04/maven-test/jars/t04-a-1.0.jar
new file mode 100644
index 00000000..257cc564
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t04/maven-test/jars/t04-a-1.0.jar
@@ -0,0 +1 @@
+foo
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t04/maven-test/jars/t04-b-1.0.jar b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t04/maven-test/jars/t04-b-1.0.jar
new file mode 100644
index 00000000..257cc564
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t04/maven-test/jars/t04-b-1.0.jar
@@ -0,0 +1 @@
+foo
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t04/maven-test/jars/t04-b-2.0.jar b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t04/maven-test/jars/t04-b-2.0.jar
new file mode 100644
index 00000000..257cc564
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t04/maven-test/jars/t04-b-2.0.jar
@@ -0,0 +1 @@
+foo
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t04/maven-test/jars/t04-c-1.0.jar b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t04/maven-test/jars/t04-c-1.0.jar
new file mode 100644
index 00000000..257cc564
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t04/maven-test/jars/t04-c-1.0.jar
@@ -0,0 +1 @@
+foo
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t04/maven-test/jars/t04-c-2.0.jar b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t04/maven-test/jars/t04-c-2.0.jar
new file mode 100644
index 00000000..257cc564
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t04/maven-test/jars/t04-c-2.0.jar
@@ -0,0 +1 @@
+foo
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t04/maven-test/poms/t04-a-1.0.pom b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t04/maven-test/poms/t04-a-1.0.pom
new file mode 100644
index 00000000..5ca34c3a
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t04/maven-test/poms/t04-a-1.0.pom
@@ -0,0 +1,21 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven-test</groupId>
+ <artifactId>t04-a</artifactId>
+ <packaging>jar</packaging>
+ <version>1.0</version>
+ <repositories>
+ <repository>
+ <id>central</id>
+ <name>Fake Maven Central Repository</name>
+ <url>file://dummy</url>
+ </repository>
+ </repositories>
+ <dependencies>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>t04-b</artifactId>
+ <version>2.0</version>
+ </dependency>
+ </dependencies>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t04/maven-test/poms/t04-b-1.0.pom b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t04/maven-test/poms/t04-b-1.0.pom
new file mode 100644
index 00000000..4c311ab1
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t04/maven-test/poms/t04-b-1.0.pom
@@ -0,0 +1,7 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven-test</groupId>
+ <artifactId>t04-b</artifactId>
+ <packaging>jar</packaging>
+ <version>1.0</version>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t04/maven-test/poms/t04-b-2.0.pom b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t04/maven-test/poms/t04-b-2.0.pom
new file mode 100644
index 00000000..d24e3bc1
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t04/maven-test/poms/t04-b-2.0.pom
@@ -0,0 +1,7 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven-test</groupId>
+ <artifactId>t04-b</artifactId>
+ <packaging>jar</packaging>
+ <version>2.0</version>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t04/maven-test/poms/t04-c-1.0.pom b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t04/maven-test/poms/t04-c-1.0.pom
new file mode 100644
index 00000000..bef2488b
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t04/maven-test/poms/t04-c-1.0.pom
@@ -0,0 +1,7 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven-test</groupId>
+ <artifactId>t04-c</artifactId>
+ <packaging>jar</packaging>
+ <version>1.0</version>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t04/maven-test/poms/t04-c-2.0.pom b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t04/maven-test/poms/t04-c-2.0.pom
new file mode 100644
index 00000000..d24e3bc1
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t04/maven-test/poms/t04-c-2.0.pom
@@ -0,0 +1,7 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven-test</groupId>
+ <artifactId>t04-b</artifactId>
+ <packaging>jar</packaging>
+ <version>2.0</version>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t04/p0/p1/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t04/p0/p1/pom.xml
new file mode 100644
index 00000000..c25fc3e7
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t04/p0/p1/pom.xml
@@ -0,0 +1,41 @@
+<project>
+ <parent>
+ <artifactId>p0</artifactId>
+ <groupId>maven-t04</groupId>
+ <version>1.0</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven-t04</groupId>
+ <artifactId>p1</artifactId>
+ <packaging>pom</packaging>
+ <name>p1</name>
+ <version>1.0</version>
+ <scm>
+ <url>scm-url</url>
+ </scm>
+
+ <dependencies>
+
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>t04-a</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>t04-c</artifactId>
+ <version>1.0</version>
+ </dependency>
+
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-antrun-plugin</artifactId>
+ <configuration>
+ <tasks><echo>${project.parent.basedir}</echo></tasks>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t04/p0/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t04/p0/pom.xml
new file mode 100644
index 00000000..1b02dc2c
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t04/p0/pom.xml
@@ -0,0 +1,37 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven-t04</groupId>
+ <artifactId>p0</artifactId>
+ <packaging>pom</packaging>
+ <name>p0</name>
+ <version>1.0</version>
+ <organization>
+ <name>Codehaus</name>
+ </organization>
+
+ <dependencyManagement>
+
+ <dependencies>
+
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>t04-a</artifactId>
+ <version>1.0</version>
+ </dependency>
+
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>t04-b</artifactId>
+ <version>1.0</version>
+ </dependency>
+
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>t04-c</artifactId>
+ <version>2.0</version>
+ </dependency>
+
+ </dependencies>
+ </dependencyManagement>
+
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t05/maven-test/jars/t05-a-1.0.jar b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t05/maven-test/jars/t05-a-1.0.jar
new file mode 100644
index 00000000..257cc564
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t05/maven-test/jars/t05-a-1.0.jar
@@ -0,0 +1 @@
+foo
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t05/maven-test/jars/t05-a-2.0.jar b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t05/maven-test/jars/t05-a-2.0.jar
new file mode 100644
index 00000000..257cc564
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t05/maven-test/jars/t05-a-2.0.jar
@@ -0,0 +1 @@
+foo
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t05/maven-test/jars/t05-b-1.0.jar b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t05/maven-test/jars/t05-b-1.0.jar
new file mode 100644
index 00000000..257cc564
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t05/maven-test/jars/t05-b-1.0.jar
@@ -0,0 +1 @@
+foo
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t05/maven-test/jars/t05-b-1.1.jar b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t05/maven-test/jars/t05-b-1.1.jar
new file mode 100644
index 00000000..257cc564
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t05/maven-test/jars/t05-b-1.1.jar
@@ -0,0 +1 @@
+foo
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t05/maven-test/jars/t05-b-2.0.jar b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t05/maven-test/jars/t05-b-2.0.jar
new file mode 100644
index 00000000..257cc564
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t05/maven-test/jars/t05-b-2.0.jar
@@ -0,0 +1 @@
+foo
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t05/maven-test/jars/t05-c-1.0.jar b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t05/maven-test/jars/t05-c-1.0.jar
new file mode 100644
index 00000000..257cc564
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t05/maven-test/jars/t05-c-1.0.jar
@@ -0,0 +1 @@
+foo
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t05/maven-test/jars/t05-d-1.0.jar b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t05/maven-test/jars/t05-d-1.0.jar
new file mode 100644
index 00000000..257cc564
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t05/maven-test/jars/t05-d-1.0.jar
@@ -0,0 +1 @@
+foo
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t05/maven-test/jars/t05-d-1.1.jar b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t05/maven-test/jars/t05-d-1.1.jar
new file mode 100644
index 00000000..257cc564
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t05/maven-test/jars/t05-d-1.1.jar
@@ -0,0 +1 @@
+foo
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t05/maven-test/jars/t05-d-1.2.jar b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t05/maven-test/jars/t05-d-1.2.jar
new file mode 100644
index 00000000..257cc564
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t05/maven-test/jars/t05-d-1.2.jar
@@ -0,0 +1 @@
+foo
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t05/maven-test/poms/t05-a-1.0.pom b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t05/maven-test/poms/t05-a-1.0.pom
new file mode 100644
index 00000000..a1b8cb9b
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t05/maven-test/poms/t05-a-1.0.pom
@@ -0,0 +1,23 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven-test</groupId>
+ <artifactId>t05-a</artifactId>
+ <packaging>jar</packaging>
+ <version>1.0</version>
+ <repositories>
+ <repository>
+ <id>central</id>
+ <name>Fake Maven Central Repository</name>
+ <url>file://dummy</url>
+ </repository>
+ </repositories>
+ <dependencies>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>t05-b</artifactId>
+ <version>1.0</version>
+ <type>jar</type>
+ <scope>compile</scope>
+ </dependency>
+ </dependencies>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t05/maven-test/poms/t05-a-2.0.pom b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t05/maven-test/poms/t05-a-2.0.pom
new file mode 100644
index 00000000..097101e8
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t05/maven-test/poms/t05-a-2.0.pom
@@ -0,0 +1,23 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven-test</groupId>
+ <artifactId>t05-a</artifactId>
+ <packaging>jar</packaging>
+ <version>2.0</version>
+ <repositories>
+ <repository>
+ <id>central</id>
+ <name>Fake Maven Central Repository</name>
+ <url>file://dummy</url>
+ </repository>
+ </repositories>
+ <dependencies>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>t05-b</artifactId>
+ <version>1.0</version>
+ <type>jar</type>
+ <scope>compile</scope>
+ </dependency>
+ </dependencies>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t05/maven-test/poms/t05-b-1.0.pom b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t05/maven-test/poms/t05-b-1.0.pom
new file mode 100644
index 00000000..e0490ff7
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t05/maven-test/poms/t05-b-1.0.pom
@@ -0,0 +1,24 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven-test</groupId>
+ <artifactId>t05-b</artifactId>
+ <packaging>jar</packaging>
+ <version>1.0</version>
+ <dependencies>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>t05-c</artifactId>
+ <version>1.0</version>
+ <type>jar</type>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>t05-d</artifactId>
+ <version>1.1</version>
+ <type>jar</type>
+ <scope>compile</scope>
+ <optional>false</optional>
+ </dependency>
+ </dependencies>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t05/maven-test/poms/t05-b-1.1.pom b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t05/maven-test/poms/t05-b-1.1.pom
new file mode 100644
index 00000000..ff59f5d2
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t05/maven-test/poms/t05-b-1.1.pom
@@ -0,0 +1,24 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven-test</groupId>
+ <artifactId>t05-b</artifactId>
+ <packaging>jar</packaging>
+ <version>1.1</version>
+ <dependencies>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>t05-c</artifactId>
+ <version>1.0</version>
+ <type>jar</type>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>t05-d</artifactId>
+ <version>1.1</version>
+ <type>jar</type>
+ <scope>compile</scope>
+ <optional>false</optional>
+ </dependency>
+ </dependencies>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t05/maven-test/poms/t05-b-2.0.pom b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t05/maven-test/poms/t05-b-2.0.pom
new file mode 100644
index 00000000..79370ec4
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t05/maven-test/poms/t05-b-2.0.pom
@@ -0,0 +1,24 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven-test</groupId>
+ <artifactId>t05-b</artifactId>
+ <packaging>jar</packaging>
+ <version>2.0</version>
+ <dependencies>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>t05-c</artifactId>
+ <version>1.0</version>
+ <type>jar</type>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>t05-d</artifactId>
+ <version>1.1</version>
+ <type>jar</type>
+ <scope>compile</scope>
+ <optional>false</optional>
+ </dependency>
+ </dependencies>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t05/maven-test/poms/t05-c-1.0.pom b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t05/maven-test/poms/t05-c-1.0.pom
new file mode 100644
index 00000000..0edc3ddd
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t05/maven-test/poms/t05-c-1.0.pom
@@ -0,0 +1,17 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven-test</groupId>
+ <artifactId>t05-c</artifactId>
+ <packaging>jar</packaging>
+ <version>1.0</version>
+ <dependencies>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>t05-d</artifactId>
+ <version>1.1</version>
+ <type>jar</type>
+ <scope>compile</scope>
+ <optional>true</optional>
+ </dependency>
+ </dependencies>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t05/maven-test/poms/t05-d-1.0.pom b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t05/maven-test/poms/t05-d-1.0.pom
new file mode 100644
index 00000000..9290b033
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t05/maven-test/poms/t05-d-1.0.pom
@@ -0,0 +1,7 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven-test</groupId>
+ <artifactId>t05-d</artifactId>
+ <packaging>jar</packaging>
+ <version>1.0</version>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t05/maven-test/poms/t05-d-1.1.pom b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t05/maven-test/poms/t05-d-1.1.pom
new file mode 100644
index 00000000..b4af4b2c
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t05/maven-test/poms/t05-d-1.1.pom
@@ -0,0 +1,7 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven-test</groupId>
+ <artifactId>t05-d</artifactId>
+ <packaging>jar</packaging>
+ <version>1.1</version>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t05/maven-test/poms/t05-d-1.2.pom b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t05/maven-test/poms/t05-d-1.2.pom
new file mode 100644
index 00000000..09e1d947
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t05/maven-test/poms/t05-d-1.2.pom
@@ -0,0 +1,7 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven-test</groupId>
+ <artifactId>t05-d</artifactId>
+ <packaging>jar</packaging>
+ <version>1.2</version>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t05/p0/p1/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t05/p0/p1/pom.xml
new file mode 100644
index 00000000..d9c2d52b
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t05/p0/p1/pom.xml
@@ -0,0 +1,54 @@
+<project>
+ <parent>
+ <artifactId>p0</artifactId>
+ <groupId>maven-t05</groupId>
+ <version>1.0</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven-t05</groupId>
+ <artifactId>p1</artifactId>
+ <packaging>pom</packaging>
+ <name>p1</name>
+ <version>1.0</version>
+ <scm>
+ <url>scm-url</url>
+ </scm>
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>t05-b</artifactId>
+ <version>1.0</version>
+ </dependency>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>t05-d</artifactId>
+ <version>1.0</version>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>t05-a</artifactId>
+ <version>1.0</version>
+ <scope>runtime</scope>
+ </dependency>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>t05-c</artifactId>
+ <version>1.0</version>
+ <scope>runtime</scope>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-antrun-plugin</artifactId>
+ <configuration>
+ <tasks><echo>${project.parent.basedir}</echo></tasks>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t05/p0/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t05/p0/pom.xml
new file mode 100644
index 00000000..6c93838b
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t05/p0/pom.xml
@@ -0,0 +1,36 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven-t05</groupId>
+ <artifactId>p0</artifactId>
+ <packaging>pom</packaging>
+ <name>p0</name>
+ <version>1.0</version>
+ <organization>
+ <name>Codehaus</name>
+ </organization>
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>t05-a</artifactId>
+ <version>1.0</version>
+ </dependency>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>t05-b</artifactId>
+ <version>1.1</version>
+ </dependency>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>t05-c</artifactId>
+ <version>1.0</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>t05-d</artifactId>
+ <version>1.2</version>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t06/maven-test/jars/t06-a-1.0.jar b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t06/maven-test/jars/t06-a-1.0.jar
new file mode 100644
index 00000000..257cc564
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t06/maven-test/jars/t06-a-1.0.jar
@@ -0,0 +1 @@
+foo
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t06/maven-test/jars/t06-b-1.0.jar b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t06/maven-test/jars/t06-b-1.0.jar
new file mode 100644
index 00000000..257cc564
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t06/maven-test/jars/t06-b-1.0.jar
@@ -0,0 +1 @@
+foo
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t06/maven-test/jars/t06-b-1.1.jar b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t06/maven-test/jars/t06-b-1.1.jar
new file mode 100644
index 00000000..257cc564
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t06/maven-test/jars/t06-b-1.1.jar
@@ -0,0 +1 @@
+foo
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t06/maven-test/jars/t06-c-1.0.jar b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t06/maven-test/jars/t06-c-1.0.jar
new file mode 100644
index 00000000..257cc564
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t06/maven-test/jars/t06-c-1.0.jar
@@ -0,0 +1 @@
+foo
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t06/maven-test/jars/t06-d-1.0.jar b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t06/maven-test/jars/t06-d-1.0.jar
new file mode 100644
index 00000000..257cc564
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t06/maven-test/jars/t06-d-1.0.jar
@@ -0,0 +1 @@
+foo
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t06/maven-test/jars/t06-d-1.1.jar b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t06/maven-test/jars/t06-d-1.1.jar
new file mode 100644
index 00000000..257cc564
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t06/maven-test/jars/t06-d-1.1.jar
@@ -0,0 +1 @@
+foo
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t06/maven-test/jars/t06-d-1.2.jar b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t06/maven-test/jars/t06-d-1.2.jar
new file mode 100644
index 00000000..257cc564
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t06/maven-test/jars/t06-d-1.2.jar
@@ -0,0 +1 @@
+foo
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t06/maven-test/poms/t06-a-1.0.pom b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t06/maven-test/poms/t06-a-1.0.pom
new file mode 100644
index 00000000..21aa5f55
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t06/maven-test/poms/t06-a-1.0.pom
@@ -0,0 +1,23 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven-test</groupId>
+ <artifactId>t06-a</artifactId>
+ <packaging>jar</packaging>
+ <version>1.0</version>
+ <repositories>
+ <repository>
+ <id>central</id>
+ <name>Fake Maven Central Repository</name>
+ <url>file://dummy</url>
+ </repository>
+ </repositories>
+ <dependencies>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>t06-b</artifactId>
+ <version>1.0</version>
+ <type>jar</type>
+ <scope>compile</scope>
+ </dependency>
+ </dependencies>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t06/maven-test/poms/t06-b-1.0.pom b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t06/maven-test/poms/t06-b-1.0.pom
new file mode 100644
index 00000000..a9af131c
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t06/maven-test/poms/t06-b-1.0.pom
@@ -0,0 +1,24 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven-test</groupId>
+ <artifactId>t06-b</artifactId>
+ <packaging>jar</packaging>
+ <version>1.0</version>
+ <dependencies>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>t06-c</artifactId>
+ <version>1.0</version>
+ <type>jar</type>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>t06-d</artifactId>
+ <version>1.1</version>
+ <type>jar</type>
+ <scope>compile</scope>
+ <optional>false</optional>
+ </dependency>
+ </dependencies>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t06/maven-test/poms/t06-b-1.1.pom b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t06/maven-test/poms/t06-b-1.1.pom
new file mode 100644
index 00000000..a9af131c
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t06/maven-test/poms/t06-b-1.1.pom
@@ -0,0 +1,24 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven-test</groupId>
+ <artifactId>t06-b</artifactId>
+ <packaging>jar</packaging>
+ <version>1.0</version>
+ <dependencies>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>t06-c</artifactId>
+ <version>1.0</version>
+ <type>jar</type>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>t06-d</artifactId>
+ <version>1.1</version>
+ <type>jar</type>
+ <scope>compile</scope>
+ <optional>false</optional>
+ </dependency>
+ </dependencies>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t06/maven-test/poms/t06-c-1.0.pom b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t06/maven-test/poms/t06-c-1.0.pom
new file mode 100644
index 00000000..80272114
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t06/maven-test/poms/t06-c-1.0.pom
@@ -0,0 +1,17 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven-test</groupId>
+ <artifactId>t06-c</artifactId>
+ <packaging>jar</packaging>
+ <version>1.0</version>
+ <dependencies>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>t06-d</artifactId>
+ <version>1.1</version>
+ <type>jar</type>
+ <scope>compile</scope>
+ <optional>true</optional>
+ </dependency>
+ </dependencies>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t06/maven-test/poms/t06-d-1.0.pom b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t06/maven-test/poms/t06-d-1.0.pom
new file mode 100644
index 00000000..e4531ab4
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t06/maven-test/poms/t06-d-1.0.pom
@@ -0,0 +1,7 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven-test</groupId>
+ <artifactId>t06-d</artifactId>
+ <packaging>jar</packaging>
+ <version>1.0</version>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t06/maven-test/poms/t06-d-1.1.pom b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t06/maven-test/poms/t06-d-1.1.pom
new file mode 100644
index 00000000..c146cb89
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t06/maven-test/poms/t06-d-1.1.pom
@@ -0,0 +1,7 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven-test</groupId>
+ <artifactId>t06-d</artifactId>
+ <packaging>jar</packaging>
+ <version>1.1</version>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t06/maven-test/poms/t06-d-1.2.pom b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t06/maven-test/poms/t06-d-1.2.pom
new file mode 100644
index 00000000..ff91f975
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t06/maven-test/poms/t06-d-1.2.pom
@@ -0,0 +1,7 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven-test</groupId>
+ <artifactId>t06-d</artifactId>
+ <packaging>jar</packaging>
+ <version>1.2</version>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t06/p0/p1/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t06/p0/p1/pom.xml
new file mode 100644
index 00000000..46862190
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t06/p0/p1/pom.xml
@@ -0,0 +1,54 @@
+<project>
+ <parent>
+ <artifactId>p0</artifactId>
+ <groupId>maven-t06</groupId>
+ <version>1.0</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven-t06</groupId>
+ <artifactId>p1</artifactId>
+ <packaging>pom</packaging>
+ <name>p1</name>
+ <version>1.0</version>
+ <scm>
+ <url>scm-url</url>
+ </scm>
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>t06-b</artifactId>
+ <version>1.0</version>
+ </dependency>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>t06-d</artifactId>
+ <version>1.0</version>
+ <scope>test</scope>
+ <optional>false</optional>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>t06-a</artifactId>
+ <version>1.0</version>
+ </dependency>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>t06-c</artifactId>
+ <version>1.0</version>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-antrun-plugin</artifactId>
+ <configuration>
+ <tasks><echo>${project.parent.basedir}</echo></tasks>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t06/p0/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t06/p0/pom.xml
new file mode 100644
index 00000000..60c540ca
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t06/p0/pom.xml
@@ -0,0 +1,37 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven-t06</groupId>
+ <artifactId>p0</artifactId>
+ <packaging>pom</packaging>
+ <name>p0</name>
+ <version>1.0</version>
+ <organization>
+ <name>Codehaus</name>
+ </organization>
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>t06-a</artifactId>
+ <version>1.0</version>
+ </dependency>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>t06-b</artifactId>
+ <version>1.1</version>
+ </dependency>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>t06-c</artifactId>
+ <version>1.0</version>
+ </dependency>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>t06-d</artifactId>
+ <version>1.2</version>
+ <scope>test</scope>
+ <optional>false</optional>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t07/maven-test/jars/t07-a-1.0.jar b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t07/maven-test/jars/t07-a-1.0.jar
new file mode 100644
index 00000000..257cc564
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t07/maven-test/jars/t07-a-1.0.jar
@@ -0,0 +1 @@
+foo
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t07/maven-test/jars/t07-b-1.0.jar b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t07/maven-test/jars/t07-b-1.0.jar
new file mode 100644
index 00000000..257cc564
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t07/maven-test/jars/t07-b-1.0.jar
@@ -0,0 +1 @@
+foo
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t07/maven-test/jars/t07-b-1.1.jar b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t07/maven-test/jars/t07-b-1.1.jar
new file mode 100644
index 00000000..257cc564
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t07/maven-test/jars/t07-b-1.1.jar
@@ -0,0 +1 @@
+foo
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t07/maven-test/jars/t07-c-1.0.jar b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t07/maven-test/jars/t07-c-1.0.jar
new file mode 100644
index 00000000..257cc564
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t07/maven-test/jars/t07-c-1.0.jar
@@ -0,0 +1 @@
+foo
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t07/maven-test/jars/t07-d-1.0.jar b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t07/maven-test/jars/t07-d-1.0.jar
new file mode 100644
index 00000000..257cc564
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t07/maven-test/jars/t07-d-1.0.jar
@@ -0,0 +1 @@
+foo
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t07/maven-test/jars/t07-d-1.1.jar b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t07/maven-test/jars/t07-d-1.1.jar
new file mode 100644
index 00000000..257cc564
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t07/maven-test/jars/t07-d-1.1.jar
@@ -0,0 +1 @@
+foo
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t07/maven-test/jars/t07-d-1.2.jar b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t07/maven-test/jars/t07-d-1.2.jar
new file mode 100644
index 00000000..257cc564
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t07/maven-test/jars/t07-d-1.2.jar
@@ -0,0 +1 @@
+foo
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t07/maven-test/poms/t07-a-1.0.pom b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t07/maven-test/poms/t07-a-1.0.pom
new file mode 100644
index 00000000..05665a9c
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t07/maven-test/poms/t07-a-1.0.pom
@@ -0,0 +1,23 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven-test</groupId>
+ <artifactId>t07-a</artifactId>
+ <packaging>jar</packaging>
+ <version>1.0</version>
+ <repositories>
+ <repository>
+ <id>central</id>
+ <name>Fake Maven Central Repository</name>
+ <url>file://dummy</url>
+ </repository>
+ </repositories>
+ <dependencies>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>t07-b</artifactId>
+ <version>1.0</version>
+ <type>jar</type>
+ <scope>compile</scope>
+ </dependency>
+ </dependencies>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t07/maven-test/poms/t07-b-1.0.pom b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t07/maven-test/poms/t07-b-1.0.pom
new file mode 100644
index 00000000..8ce6751c
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t07/maven-test/poms/t07-b-1.0.pom
@@ -0,0 +1,24 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven-test</groupId>
+ <artifactId>t07-b</artifactId>
+ <packaging>jar</packaging>
+ <version>1.0</version>
+ <dependencies>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>t07-c</artifactId>
+ <version>1.0</version>
+ <type>jar</type>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>t07-d</artifactId>
+ <version>1.1</version>
+ <type>jar</type>
+ <scope>compile</scope>
+ <optional>true</optional>
+ </dependency>
+ </dependencies>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t07/maven-test/poms/t07-b-1.1.pom b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t07/maven-test/poms/t07-b-1.1.pom
new file mode 100644
index 00000000..689ad055
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t07/maven-test/poms/t07-b-1.1.pom
@@ -0,0 +1,24 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven-test</groupId>
+ <artifactId>t07-b</artifactId>
+ <packaging>jar</packaging>
+ <version>1.1</version>
+ <dependencies>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>t07-c</artifactId>
+ <version>1.0</version>
+ <type>jar</type>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>t07-d</artifactId>
+ <version>1.1</version>
+ <type>jar</type>
+ <scope>compile</scope>
+ <optional>true</optional>
+ </dependency>
+ </dependencies>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t07/maven-test/poms/t07-c-1.0.pom b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t07/maven-test/poms/t07-c-1.0.pom
new file mode 100644
index 00000000..494470c4
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t07/maven-test/poms/t07-c-1.0.pom
@@ -0,0 +1,17 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven-test</groupId>
+ <artifactId>t07-c</artifactId>
+ <packaging>jar</packaging>
+ <version>1.0</version>
+ <dependencies>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>t07-d</artifactId>
+ <version>1.1</version>
+ <type>jar</type>
+ <scope>compile</scope>
+ <optional>true</optional>
+ </dependency>
+ </dependencies>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t07/maven-test/poms/t07-d-1.0.pom b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t07/maven-test/poms/t07-d-1.0.pom
new file mode 100644
index 00000000..5761d515
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t07/maven-test/poms/t07-d-1.0.pom
@@ -0,0 +1,7 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven-test</groupId>
+ <artifactId>t07-d</artifactId>
+ <packaging>jar</packaging>
+ <version>1.0</version>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t07/maven-test/poms/t07-d-1.1.pom b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t07/maven-test/poms/t07-d-1.1.pom
new file mode 100644
index 00000000..08fc179c
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t07/maven-test/poms/t07-d-1.1.pom
@@ -0,0 +1,7 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven-test</groupId>
+ <artifactId>t07-d</artifactId>
+ <packaging>jar</packaging>
+ <version>1.1</version>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t07/maven-test/poms/t07-d-1.2.pom b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t07/maven-test/poms/t07-d-1.2.pom
new file mode 100644
index 00000000..544ccc59
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t07/maven-test/poms/t07-d-1.2.pom
@@ -0,0 +1,7 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven-test</groupId>
+ <artifactId>t07-d</artifactId>
+ <packaging>jar</packaging>
+ <version>1.2</version>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t07/p0/p1/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t07/p0/p1/pom.xml
new file mode 100644
index 00000000..6f700429
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t07/p0/p1/pom.xml
@@ -0,0 +1,54 @@
+<project>
+ <parent>
+ <artifactId>p0</artifactId>
+ <groupId>maven-t07</groupId>
+ <version>1.0</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven-t07</groupId>
+ <artifactId>p1</artifactId>
+ <packaging>pom</packaging>
+ <name>p1</name>
+ <version>1.0</version>
+ <scm>
+ <url>scm-url</url>
+ </scm>
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>t07-b</artifactId>
+ <version>1.0</version>
+ </dependency>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>t07-d</artifactId>
+ <version>1.0</version>
+ <scope>test</scope>
+ <optional>false</optional>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>t07-a</artifactId>
+ <version>1.0</version>
+ </dependency>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>t07-c</artifactId>
+ <version>1.0</version>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-antrun-plugin</artifactId>
+ <configuration>
+ <tasks><echo>${project.parent.basedir}</echo></tasks>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t07/p0/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t07/p0/pom.xml
new file mode 100644
index 00000000..b500ee0e
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t07/p0/pom.xml
@@ -0,0 +1,37 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven-t07</groupId>
+ <artifactId>p0</artifactId>
+ <packaging>pom</packaging>
+ <name>p0</name>
+ <version>1.0</version>
+ <organization>
+ <name>Codehaus</name>
+ </organization>
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>t07-a</artifactId>
+ <version>1.0</version>
+ </dependency>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>t07-b</artifactId>
+ <version>1.1</version>
+ </dependency>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>t07-c</artifactId>
+ <version>1.0</version>
+ </dependency>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>t07-d</artifactId>
+ <version>1.2</version>
+ <scope>test</scope>
+ <optional>false</optional>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t08/maven-test/jars/t08-a-1.0.jar b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t08/maven-test/jars/t08-a-1.0.jar
new file mode 100644
index 00000000..257cc564
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t08/maven-test/jars/t08-a-1.0.jar
@@ -0,0 +1 @@
+foo
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t08/maven-test/jars/t08-b-1.0.jar b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t08/maven-test/jars/t08-b-1.0.jar
new file mode 100644
index 00000000..257cc564
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t08/maven-test/jars/t08-b-1.0.jar
@@ -0,0 +1 @@
+foo
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t08/maven-test/jars/t08-b-1.1.jar b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t08/maven-test/jars/t08-b-1.1.jar
new file mode 100644
index 00000000..257cc564
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t08/maven-test/jars/t08-b-1.1.jar
@@ -0,0 +1 @@
+foo
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t08/maven-test/jars/t08-c-1.0.jar b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t08/maven-test/jars/t08-c-1.0.jar
new file mode 100644
index 00000000..257cc564
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t08/maven-test/jars/t08-c-1.0.jar
@@ -0,0 +1 @@
+foo
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t08/maven-test/jars/t08-d-1.0.jar b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t08/maven-test/jars/t08-d-1.0.jar
new file mode 100644
index 00000000..257cc564
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t08/maven-test/jars/t08-d-1.0.jar
@@ -0,0 +1 @@
+foo
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t08/maven-test/jars/t08-d-1.1.jar b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t08/maven-test/jars/t08-d-1.1.jar
new file mode 100644
index 00000000..257cc564
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t08/maven-test/jars/t08-d-1.1.jar
@@ -0,0 +1 @@
+foo
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t08/maven-test/jars/t08-d-1.2.jar b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t08/maven-test/jars/t08-d-1.2.jar
new file mode 100644
index 00000000..257cc564
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t08/maven-test/jars/t08-d-1.2.jar
@@ -0,0 +1 @@
+foo
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t08/maven-test/poms/t08-a-1.0.pom b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t08/maven-test/poms/t08-a-1.0.pom
new file mode 100644
index 00000000..186c2d89
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t08/maven-test/poms/t08-a-1.0.pom
@@ -0,0 +1,23 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven-test</groupId>
+ <artifactId>t08-a</artifactId>
+ <packaging>jar</packaging>
+ <version>1.0</version>
+ <repositories>
+ <repository>
+ <id>central</id>
+ <name>Fake Maven Central Repository</name>
+ <url>file://dummy</url>
+ </repository>
+ </repositories>
+ <dependencies>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>t08-b</artifactId>
+ <version>1.0</version>
+ <type>jar</type>
+ <scope>compile</scope>
+ </dependency>
+ </dependencies>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t08/maven-test/poms/t08-b-1.0.pom b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t08/maven-test/poms/t08-b-1.0.pom
new file mode 100644
index 00000000..d866ab35
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t08/maven-test/poms/t08-b-1.0.pom
@@ -0,0 +1,24 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven-test</groupId>
+ <artifactId>t08-b</artifactId>
+ <packaging>jar</packaging>
+ <version>1.0</version>
+ <dependencies>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>t08-c</artifactId>
+ <version>1.0</version>
+ <type>jar</type>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>t08-d</artifactId>
+ <version>1.1</version>
+ <type>jar</type>
+ <scope>compile</scope>
+ <optional>false</optional>
+ </dependency>
+ </dependencies>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t08/maven-test/poms/t08-b-1.1.pom b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t08/maven-test/poms/t08-b-1.1.pom
new file mode 100644
index 00000000..d402466e
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t08/maven-test/poms/t08-b-1.1.pom
@@ -0,0 +1,24 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven-test</groupId>
+ <artifactId>t08-b</artifactId>
+ <packaging>jar</packaging>
+ <version>1.1</version>
+ <dependencies>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>t08-c</artifactId>
+ <version>1.0</version>
+ <type>jar</type>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>t08-d</artifactId>
+ <version>1.1</version>
+ <type>jar</type>
+ <scope>compile</scope>
+ <optional>false</optional>
+ </dependency>
+ </dependencies>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t08/maven-test/poms/t08-c-1.0.pom b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t08/maven-test/poms/t08-c-1.0.pom
new file mode 100644
index 00000000..d8250528
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t08/maven-test/poms/t08-c-1.0.pom
@@ -0,0 +1,17 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven-test</groupId>
+ <artifactId>t08-c</artifactId>
+ <packaging>jar</packaging>
+ <version>1.0</version>
+ <dependencies>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>t08-d</artifactId>
+ <version>1.1</version>
+ <type>jar</type>
+ <scope>compile</scope>
+ <optional>true</optional>
+ </dependency>
+ </dependencies>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t08/maven-test/poms/t08-d-1.0.pom b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t08/maven-test/poms/t08-d-1.0.pom
new file mode 100644
index 00000000..f4530458
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t08/maven-test/poms/t08-d-1.0.pom
@@ -0,0 +1,7 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven-test</groupId>
+ <artifactId>t08-d</artifactId>
+ <packaging>jar</packaging>
+ <version>1.0</version>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t08/maven-test/poms/t08-d-1.1.pom b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t08/maven-test/poms/t08-d-1.1.pom
new file mode 100644
index 00000000..c7703b02
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t08/maven-test/poms/t08-d-1.1.pom
@@ -0,0 +1,7 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven-test</groupId>
+ <artifactId>t08-d</artifactId>
+ <packaging>jar</packaging>
+ <version>1.1</version>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t08/maven-test/poms/t08-d-1.2.pom b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t08/maven-test/poms/t08-d-1.2.pom
new file mode 100644
index 00000000..e341be53
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t08/maven-test/poms/t08-d-1.2.pom
@@ -0,0 +1,7 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven-test</groupId>
+ <artifactId>t08-d</artifactId>
+ <packaging>jar</packaging>
+ <version>1.2</version>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t08/p0/p1/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t08/p0/p1/pom.xml
new file mode 100644
index 00000000..331996d8
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t08/p0/p1/pom.xml
@@ -0,0 +1,59 @@
+<project>
+ <parent>
+ <artifactId>p0</artifactId>
+ <groupId>maven-t08</groupId>
+ <version>1.0</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven-t08</groupId>
+ <artifactId>p1</artifactId>
+ <packaging>pom</packaging>
+ <name>p1</name>
+ <version>1.0</version>
+ <scm>
+ <url>scm-url</url>
+ </scm>
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>t08-b</artifactId>
+ <version>1.0</version>
+ </dependency>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>t08-d</artifactId>
+ <version>1.0</version>
+ <scope>test</scope>
+ <optional>true</optional>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>t08-a</artifactId>
+ <version>1.0</version>
+ </dependency>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>t08-c</artifactId>
+ <version>1.0</version>
+ </dependency>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>t08-d</artifactId>
+ <version>1.0</version>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-antrun-plugin</artifactId>
+ <configuration>
+ <tasks><echo>${project.parent.basedir}</echo></tasks>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t08/p0/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t08/p0/pom.xml
new file mode 100644
index 00000000..a18ab853
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t08/p0/pom.xml
@@ -0,0 +1,37 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven-t08</groupId>
+ <artifactId>p0</artifactId>
+ <packaging>pom</packaging>
+ <name>p0</name>
+ <version>1.0</version>
+ <organization>
+ <name>Codehaus</name>
+ </organization>
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>t08-a</artifactId>
+ <version>1.0</version>
+ </dependency>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>t08-b</artifactId>
+ <version>1.1</version>
+ </dependency>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>t08-c</artifactId>
+ <version>1.0</version>
+ </dependency>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>t08-d</artifactId>
+ <version>1.2</version>
+ <scope>test</scope>
+ <optional>false</optional>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t09/maven-test/jars/t09-a-1.0.jar b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t09/maven-test/jars/t09-a-1.0.jar
new file mode 100644
index 00000000..257cc564
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t09/maven-test/jars/t09-a-1.0.jar
@@ -0,0 +1 @@
+foo
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t09/maven-test/jars/t09-b-1.0.jar b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t09/maven-test/jars/t09-b-1.0.jar
new file mode 100644
index 00000000..257cc564
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t09/maven-test/jars/t09-b-1.0.jar
@@ -0,0 +1 @@
+foo
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t09/maven-test/jars/t09-c-1.0.jar b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t09/maven-test/jars/t09-c-1.0.jar
new file mode 100644
index 00000000..257cc564
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t09/maven-test/jars/t09-c-1.0.jar
@@ -0,0 +1 @@
+foo
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t09/maven-test/jars/t09-d-1.0.jar b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t09/maven-test/jars/t09-d-1.0.jar
new file mode 100644
index 00000000..257cc564
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t09/maven-test/jars/t09-d-1.0.jar
@@ -0,0 +1 @@
+foo
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t09/maven-test/poms/t09-a-1.0.pom b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t09/maven-test/poms/t09-a-1.0.pom
new file mode 100644
index 00000000..54cf647b
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t09/maven-test/poms/t09-a-1.0.pom
@@ -0,0 +1,24 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven-test</groupId>
+ <artifactId>t09-a</artifactId>
+ <packaging>jar</packaging>
+ <version>1.0</version>
+ <repositories>
+ <repository>
+ <id>central</id>
+ <name>Fake Maven Central Repository</name>
+ <url>file://dummy</url>
+ </repository>
+ </repositories>
+
+ <dependencies>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>t09-b</artifactId>
+ <version>1.0</version>
+ <scope>compile</scope>
+ </dependency>
+ </dependencies>
+
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t09/maven-test/poms/t09-b-1.0.pom b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t09/maven-test/poms/t09-b-1.0.pom
new file mode 100644
index 00000000..ce001c2f
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t09/maven-test/poms/t09-b-1.0.pom
@@ -0,0 +1,17 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven-test</groupId>
+ <artifactId>t09-b</artifactId>
+ <packaging>jar</packaging>
+ <version>1.0</version>
+
+ <dependencies>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>t09-c</artifactId>
+ <version>1.0</version>
+ <scope>compile</scope>
+ </dependency>
+ </dependencies>
+
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t09/maven-test/poms/t09-c-1.0.pom b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t09/maven-test/poms/t09-c-1.0.pom
new file mode 100644
index 00000000..da7bc349
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t09/maven-test/poms/t09-c-1.0.pom
@@ -0,0 +1,7 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven-test</groupId>
+ <artifactId>t09-c</artifactId>
+ <packaging>jar</packaging>
+ <version>1.0</version>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t09/maven-test/poms/t09-d-1.0.pom b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t09/maven-test/poms/t09-d-1.0.pom
new file mode 100644
index 00000000..86227472
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t09/maven-test/poms/t09-d-1.0.pom
@@ -0,0 +1,17 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven-test</groupId>
+ <artifactId>t09-d</artifactId>
+ <packaging>jar</packaging>
+ <version>1.0</version>
+
+ <dependencies>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>t09-c</artifactId>
+ <version>1.0</version>
+ <scope>compile</scope>
+ </dependency>
+ </dependencies>
+
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t09/p0/p1/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t09/p0/p1/pom.xml
new file mode 100644
index 00000000..ae435843
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t09/p0/p1/pom.xml
@@ -0,0 +1,36 @@
+<project>
+ <parent>
+ <artifactId>p0</artifactId>
+ <groupId>maven-t09</groupId>
+ <version>1.0</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven-t09</groupId>
+ <artifactId>p1</artifactId>
+ <packaging>pom</packaging>
+ <name>p1</name>
+ <version>1.0</version>
+ <scm>
+ <url>scm-url</url>
+ </scm>
+
+ <dependencies>
+
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>t09-a</artifactId>
+ </dependency>
+
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-antrun-plugin</artifactId>
+ <configuration>
+ <tasks><echo>${project.parent.basedir}</echo></tasks>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t09/p0/p2/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t09/p0/p2/pom.xml
new file mode 100644
index 00000000..4681c2ef
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t09/p0/p2/pom.xml
@@ -0,0 +1,42 @@
+<project>
+ <parent>
+ <artifactId>p0</artifactId>
+ <groupId>maven-t09</groupId>
+ <version>1.0</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven-t09</groupId>
+ <artifactId>p2</artifactId>
+ <packaging>pom</packaging>
+ <name>p2</name>
+ <version>1.0</version>
+ <scm>
+ <url>scm-url</url>
+ </scm>
+
+ <dependencies>
+
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>t09-a</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>t09-d</artifactId>
+ <version>1.0</version>
+ </dependency>
+
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-antrun-plugin</artifactId>
+ <configuration>
+ <tasks><echo>${project.parent.basedir}</echo></tasks>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t09/p0/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t09/p0/pom.xml
new file mode 100644
index 00000000..a93746d2
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t09/p0/pom.xml
@@ -0,0 +1,38 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven-t09</groupId>
+ <artifactId>p0</artifactId>
+ <packaging>pom</packaging>
+ <name>p0</name>
+ <version>1.0</version>
+ <organization>
+ <name>Codehaus</name>
+ </organization>
+
+ <dependencyManagement>
+
+ <dependencies>
+
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>t09-a</artifactId>
+ <version>1.0</version>
+ </dependency>
+
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>t09-b</artifactId>
+ <version>1.0</version>
+ <exclusions>
+ <exclusion>
+ <groupId>maven-test</groupId>
+ <artifactId>t09-c</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
+ </dependencies>
+
+ </dependencyManagement>
+
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t10/maven-test/jars/t10-a-1.0.jar b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t10/maven-test/jars/t10-a-1.0.jar
new file mode 100644
index 00000000..257cc564
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t10/maven-test/jars/t10-a-1.0.jar
@@ -0,0 +1 @@
+foo
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t10/maven-test/jars/t10-b-1.0.jar b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t10/maven-test/jars/t10-b-1.0.jar
new file mode 100644
index 00000000..257cc564
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t10/maven-test/jars/t10-b-1.0.jar
@@ -0,0 +1 @@
+foo
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t10/maven-test/jars/t10-c-1.0.jar b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t10/maven-test/jars/t10-c-1.0.jar
new file mode 100644
index 00000000..257cc564
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t10/maven-test/jars/t10-c-1.0.jar
@@ -0,0 +1 @@
+foo
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t10/maven-test/poms/t10-a-1.0.pom b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t10/maven-test/poms/t10-a-1.0.pom
new file mode 100644
index 00000000..1fc2a221
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t10/maven-test/poms/t10-a-1.0.pom
@@ -0,0 +1,24 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven-test</groupId>
+ <artifactId>t10-a</artifactId>
+ <packaging>jar</packaging>
+ <version>1.0</version>
+ <repositories>
+ <repository>
+ <id>central</id>
+ <name>Fake Maven Central Repository</name>
+ <url>file://dummy</url>
+ </repository>
+ </repositories>
+
+ <dependencies>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>t10-b</artifactId>
+ <version>1.0</version>
+ <scope>compile</scope>
+ </dependency>
+ </dependencies>
+
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t10/maven-test/poms/t10-b-1.0.pom b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t10/maven-test/poms/t10-b-1.0.pom
new file mode 100644
index 00000000..64b5f97a
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t10/maven-test/poms/t10-b-1.0.pom
@@ -0,0 +1,7 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven-test</groupId>
+ <artifactId>t10-b</artifactId>
+ <packaging>jar</packaging>
+ <version>1.0</version>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t10/maven-test/poms/t10-c-1.0.pom b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t10/maven-test/poms/t10-c-1.0.pom
new file mode 100644
index 00000000..6548ab30
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t10/maven-test/poms/t10-c-1.0.pom
@@ -0,0 +1,7 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven-test</groupId>
+ <artifactId>t10-c</artifactId>
+ <packaging>jar</packaging>
+ <version>1.0</version>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t10/p0/p1/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t10/p0/p1/pom.xml
new file mode 100644
index 00000000..ed82ae13
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t10/p0/p1/pom.xml
@@ -0,0 +1,42 @@
+<project>
+ <parent>
+ <artifactId>p0</artifactId>
+ <groupId>maven-t10</groupId>
+ <version>1.0</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven-t10</groupId>
+ <artifactId>p1</artifactId>
+ <packaging>pom</packaging>
+ <name>p1</name>
+ <version>1.0</version>
+ <scm>
+ <url>scm-url</url>
+ </scm>
+
+ <dependencies>
+
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>t10-a</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>t10-c</artifactId>
+ <scope>runtime</scope>
+ </dependency>
+
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-antrun-plugin</artifactId>
+ <configuration>
+ <tasks><echo>${project.parent.basedir}</echo></tasks>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t10/p0/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t10/p0/pom.xml
new file mode 100644
index 00000000..853af40d
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t10/p0/pom.xml
@@ -0,0 +1,41 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven-t10</groupId>
+ <artifactId>p0</artifactId>
+ <packaging>pom</packaging>
+ <name>p0</name>
+ <version>1.0</version>
+ <organization>
+ <name>Codehaus</name>
+ </organization>
+
+ <dependencyManagement>
+
+ <dependencies>
+
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>t10-a</artifactId>
+ <version>1.0</version>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>t10-b</artifactId>
+ <version>1.0</version>
+ <scope>runtime</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>t10-c</artifactId>
+ <version>1.0</version>
+ <scope>test</scope>
+ </dependency>
+
+ </dependencies>
+
+ </dependencyManagement>
+
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t11/p0/p1/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t11/p0/p1/pom.xml
new file mode 100644
index 00000000..e4c79be4
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t11/p0/p1/pom.xml
@@ -0,0 +1,16 @@
+<project>
+ <parent>
+ <artifactId>p0</artifactId>
+ <groupId>maven</groupId>
+ <version>1.0</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven</groupId>
+ <artifactId>p1</artifactId>
+ <packaging>jar</packaging>
+ <name>p1</name>
+ <version>1.0</version>
+ <scm>
+ <url>scm-url</url>
+ </scm>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t11/p0/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t11/p0/pom.xml
new file mode 100644
index 00000000..23b07e2c
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t11/p0/pom.xml
@@ -0,0 +1,27 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven</groupId>
+ <artifactId>p0</artifactId>
+ <packaging>pom</packaging>
+ <name>p0</name>
+ <version>1.0</version>
+ <organization>
+ <name>Codehaus</name>
+ </organization>
+
+ <dependencyManagement>
+
+ <dependencies>
+
+ <dependency>
+ <groupId>maven</groupId>
+ <artifactId>p1</artifactId>
+ <version>1.0</version>
+ <scope>test</scope>
+ </dependency>
+
+ </dependencies>
+
+ </dependencyManagement>
+
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t12/p0/p1/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t12/p0/p1/pom.xml
new file mode 100644
index 00000000..15115cb8
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t12/p0/p1/pom.xml
@@ -0,0 +1,29 @@
+<project>
+ <parent>
+ <artifactId>p0</artifactId>
+ <groupId>maven</groupId>
+ <version>1.0</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>p1</artifactId>
+ <packaging>jar</packaging>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>normal</id>
+
+ <goals>
+ <goal>compile</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t12/p0/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t12/p0/pom.xml
new file mode 100644
index 00000000..4f2e6426
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t12/p0/pom.xml
@@ -0,0 +1,30 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven</groupId>
+ <artifactId>p0</artifactId>
+ <packaging>pom</packaging>
+ <version>1.0</version>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>test</id>
+
+ <!-- The key to this test... -->
+ <inherited>false</inherited>
+
+ <goals>
+ <goal>compile</goal>
+ </goals>
+ <phase>install</phase>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t12scm/maven/p0/1.0/p0-1.0.pom b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t12scm/maven/p0/1.0/p0-1.0.pom
new file mode 100644
index 00000000..97bf7ccc
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t12scm/maven/p0/1.0/p0-1.0.pom
@@ -0,0 +1,18 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven</groupId>
+ <artifactId>p0</artifactId>
+ <packaging>pom</packaging>
+ <version>1.0</version>
+
+ <scm>
+ <connection>scm:svn:http://host/p0</connection>
+ <developerConnection>scm:svn:https://host/p0</developerConnection>
+ <url>http://host/viewer?path=/p0</url>
+ </scm>
+
+ <modules>
+ <module>modules/p1</module>
+ </modules>
+
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t12scm/maven/p1/1.0/p1-1.0.pom b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t12scm/maven/p1/1.0/p1-1.0.pom
new file mode 100644
index 00000000..e9ddf0d7
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t12scm/maven/p1/1.0/p1-1.0.pom
@@ -0,0 +1,11 @@
+<project>
+ <parent>
+ <artifactId>p0</artifactId>
+ <groupId>maven</groupId>
+ <version>1.0</version>
+ <relativePath>../../pom.xml</relativePath>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>p1</artifactId>
+
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t12scm/p0/modules/p1/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t12scm/p0/modules/p1/pom.xml
new file mode 100644
index 00000000..736b5153
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t12scm/p0/modules/p1/pom.xml
@@ -0,0 +1,11 @@
+<project>
+ <parent>
+ <artifactId>p0</artifactId>
+ <groupId>maven</groupId>
+ <version>1.0</version>
+ <relativePath>../../pom.xml</relativePath>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>p1</artifactId>
+
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t12scm/p0/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t12scm/p0/pom.xml
new file mode 100644
index 00000000..a22df68e
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/inheritance-repo/t12scm/p0/pom.xml
@@ -0,0 +1,18 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven</groupId>
+ <artifactId>p0</artifactId>
+ <packaging>pom</packaging>
+ <version>1.0</version>
+
+ <scm>
+ <connection>scm:svn:http://host/p0</connection>
+ <developerConnection>scm:svn:https://host/p0</developerConnection>
+ <url>http://host/viewer?path=/p0</url>
+ </scm>
+
+ <modules>
+ <module>modules/p1</module>
+ </modules>
+
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/local-repo/marker.txt b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/local-repo/marker.txt
new file mode 100644
index 00000000..d9bab060
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/local-repo/marker.txt
@@ -0,0 +1 @@
+this is just a marker file. \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/local-repo/maven-test/jars/maven-test-a-1.0.jar b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/local-repo/maven-test/jars/maven-test-a-1.0.jar
new file mode 100644
index 00000000..257cc564
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/local-repo/maven-test/jars/maven-test-a-1.0.jar
@@ -0,0 +1 @@
+foo
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/local-repo/maven-test/jars/maven-test-b-1.0.jar b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/local-repo/maven-test/jars/maven-test-b-1.0.jar
new file mode 100644
index 00000000..257cc564
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/local-repo/maven-test/jars/maven-test-b-1.0.jar
@@ -0,0 +1 @@
+foo
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/local-repo/maven-test/jars/maven-test-c-1.0.jar b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/local-repo/maven-test/jars/maven-test-c-1.0.jar
new file mode 100644
index 00000000..257cc564
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/local-repo/maven-test/jars/maven-test-c-1.0.jar
@@ -0,0 +1 @@
+foo
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/local-repo/maven-test/jars/maven-test-d-1.0.jar b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/local-repo/maven-test/jars/maven-test-d-1.0.jar
new file mode 100644
index 00000000..257cc564
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/local-repo/maven-test/jars/maven-test-d-1.0.jar
@@ -0,0 +1 @@
+foo
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/local-repo/maven-test/poms/maven-test-a-1.0.pom b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/local-repo/maven-test/poms/maven-test-a-1.0.pom
new file mode 100644
index 00000000..6905f6c8
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/local-repo/maven-test/poms/maven-test-a-1.0.pom
@@ -0,0 +1,23 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven-test</groupId>
+ <artifactId>maven-test-a</artifactId>
+ <packaging>jar</packaging>
+ <version>1.0</version>
+ <repositories>
+ <repository>
+ <id>central</id>
+ <name>Fake Maven Central Repository</name>
+ <url>file://dummy</url>
+ </repository>
+ </repositories>
+ <dependencies>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>maven-test-b</artifactId>
+ <version>1.0</version>
+ <type>jar</type>
+ <scope>compile</scope>
+ </dependency>
+ </dependencies>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/local-repo/maven-test/poms/maven-test-b-1.0.pom b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/local-repo/maven-test/poms/maven-test-b-1.0.pom
new file mode 100644
index 00000000..e814951a
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/local-repo/maven-test/poms/maven-test-b-1.0.pom
@@ -0,0 +1,23 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven-test</groupId>
+ <artifactId>maven-test-b</artifactId>
+ <packaging>jar</packaging>
+ <version>1.0</version>
+ <dependencies>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>maven-test-c</artifactId>
+ <version>1.0</version>
+ <type>jar</type>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>maven-test-d</artifactId>
+ <version>1.1</version>
+ <type>jar</type>
+ <scope>compile</scope>
+ </dependency>
+ </dependencies>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/local-repo/maven-test/poms/maven-test-c-1.0.pom b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/local-repo/maven-test/poms/maven-test-c-1.0.pom
new file mode 100644
index 00000000..4631b88f
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/local-repo/maven-test/poms/maven-test-c-1.0.pom
@@ -0,0 +1,16 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven-test</groupId>
+ <artifactId>maven-test-c</artifactId>
+ <packaging>jar</packaging>
+ <version>1.0</version>
+ <dependencies>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>maven-test-d</artifactId>
+ <version>1.2</version>
+ <type>jar</type>
+ <scope>compile</scope>
+ </dependency>
+ </dependencies>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/local-repo/maven-test/poms/maven-test-d-1.1.pom b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/local-repo/maven-test/poms/maven-test-d-1.1.pom
new file mode 100644
index 00000000..6e22f608
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/local-repo/maven-test/poms/maven-test-d-1.1.pom
@@ -0,0 +1,7 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven-test</groupId>
+ <artifactId>maven-test-d</artifactId>
+ <packaging>jar</packaging>
+ <version>1.1</version>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/local-repo/maven-test/poms/maven-test-d-1.2.pom b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/local-repo/maven-test/poms/maven-test-d-1.2.pom
new file mode 100644
index 00000000..6e22f608
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/local-repo/maven-test/poms/maven-test-d-1.2.pom
@@ -0,0 +1,7 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven-test</groupId>
+ <artifactId>maven-test-d</artifactId>
+ <packaging>jar</packaging>
+ <version>1.1</version>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/local-repo/snapshot-test/jars/maven-snapshot-a-1.0-SNAPSHOT.jar b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/local-repo/snapshot-test/jars/maven-snapshot-a-1.0-SNAPSHOT.jar
new file mode 100644
index 00000000..c2c027fe
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/local-repo/snapshot-test/jars/maven-snapshot-a-1.0-SNAPSHOT.jar
@@ -0,0 +1 @@
+local \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/local-repo/snapshot-test/jars/maven-snapshot-a-1.0-SNAPSHOT.jar.snapshot-version b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/local-repo/snapshot-test/jars/maven-snapshot-a-1.0-SNAPSHOT.jar.snapshot-version
new file mode 100644
index 00000000..09f9180f
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/local-repo/snapshot-test/jars/maven-snapshot-a-1.0-SNAPSHOT.jar.snapshot-version
@@ -0,0 +1 @@
+20040101.101010 \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/local-repo/snapshot-test/jars/maven-snapshot-b-1.0-SNAPSHOT.jar b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/local-repo/snapshot-test/jars/maven-snapshot-b-1.0-SNAPSHOT.jar
new file mode 100644
index 00000000..c2c027fe
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/local-repo/snapshot-test/jars/maven-snapshot-b-1.0-SNAPSHOT.jar
@@ -0,0 +1 @@
+local \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/local-repo/snapshot-test/jars/maven-snapshot-b-1.0-SNAPSHOT.jar.snapshot-version b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/local-repo/snapshot-test/jars/maven-snapshot-b-1.0-SNAPSHOT.jar.snapshot-version
new file mode 100644
index 00000000..09f9180f
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/local-repo/snapshot-test/jars/maven-snapshot-b-1.0-SNAPSHOT.jar.snapshot-version
@@ -0,0 +1 @@
+20040101.101010 \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/local-repo/snapshot-test/jars/maven-snapshot-e-1.0-SNAPSHOT.jar b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/local-repo/snapshot-test/jars/maven-snapshot-e-1.0-SNAPSHOT.jar
new file mode 100644
index 00000000..c2c027fe
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/local-repo/snapshot-test/jars/maven-snapshot-e-1.0-SNAPSHOT.jar
@@ -0,0 +1 @@
+local \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/local-repo/snapshot-test/jars/maven-snapshot-e-1.0-SNAPSHOT.jar.snapshot-version b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/local-repo/snapshot-test/jars/maven-snapshot-e-1.0-SNAPSHOT.jar.snapshot-version
new file mode 100644
index 00000000..09f9180f
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/local-repo/snapshot-test/jars/maven-snapshot-e-1.0-SNAPSHOT.jar.snapshot-version
@@ -0,0 +1 @@
+20040101.101010 \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/local-repo/snapshot-test/poms/maven-test-snapshot-resolving-1.0.pom b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/local-repo/snapshot-test/poms/maven-test-snapshot-resolving-1.0.pom
new file mode 100644
index 00000000..64a075f4
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/local-repo/snapshot-test/poms/maven-test-snapshot-resolving-1.0.pom
@@ -0,0 +1,49 @@
+<project>
+ <groupId>snapshot-test</groupId>
+ <artifactId>maven-test-snapshot-resolving</artifactId>
+ <packaging>jar</packaging>
+ <repositories>
+ <repository>
+ <id>central</id>
+ <name>Fake Maven Central Repository</name>
+ <url>file://dummy</url>
+ </repository>
+ </repositories>
+ <dependencies>
+ <dependency>
+ <groupId>snapshot-test</groupId>
+ <artifactId>maven-snapshot-a</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <type>jar</type>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>snapshot-test</groupId>
+ <artifactId>maven-snapshot-b</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <type>jar</type>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>snapshot-test</groupId>
+ <artifactId>maven-snapshot-c</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <type>jar</type>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>snapshot-test</groupId>
+ <artifactId>maven-snapshot-d</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <type>jar</type>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>snapshot-test</groupId>
+ <artifactId>maven-snapshot-e</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <type>jar</type>
+ <scope>compile</scope>
+ </dependency>
+ </dependencies>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/org/apache/maven/artifact/deployer/ArtifactDeployerTest.xml b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/org/apache/maven/artifact/deployer/ArtifactDeployerTest.xml
new file mode 100644
index 00000000..f7c381fe
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/org/apache/maven/artifact/deployer/ArtifactDeployerTest.xml
@@ -0,0 +1,23 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<plexus>
+ <components>
+ </components>
+</plexus>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/org/apache/maven/artifact/installer/ArtifactInstallerTest.xml b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/org/apache/maven/artifact/installer/ArtifactInstallerTest.xml
new file mode 100644
index 00000000..f7c381fe
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/org/apache/maven/artifact/installer/ArtifactInstallerTest.xml
@@ -0,0 +1,23 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<plexus>
+ <components>
+ </components>
+</plexus>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/org/apache/maven/artifact/manager/DefaultWagonManagerTest.xml b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/org/apache/maven/artifact/manager/DefaultWagonManagerTest.xml
new file mode 100644
index 00000000..925022ef
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/org/apache/maven/artifact/manager/DefaultWagonManagerTest.xml
@@ -0,0 +1,48 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<plexus>
+ <components>
+ <component>
+ <role>org.apache.maven.wagon.Wagon</role>
+ <role-hint>a</role-hint>
+ <implementation>org.apache.maven.artifact.manager.WagonA</implementation>
+ </component>
+ <component>
+ <role>org.apache.maven.wagon.Wagon</role>
+ <role-hint>b1</role-hint>
+ <implementation>org.apache.maven.artifact.manager.WagonB</implementation>
+ </component>
+ <component>
+ <role>org.apache.maven.wagon.Wagon</role>
+ <role-hint>b2</role-hint>
+ <implementation>org.apache.maven.artifact.manager.WagonB</implementation>
+ </component>
+ <component>
+ <role>org.apache.maven.wagon.Wagon</role>
+ <role-hint>c</role-hint>
+ <implementation>org.apache.maven.artifact.manager.WagonC</implementation>
+ </component>
+ <component>
+ <role>org.apache.maven.wagon.Wagon</role>
+ <role-hint>string</role-hint>
+ <implementation>org.apache.maven.artifact.manager.StringWagon</implementation>
+ </component>
+ </components>
+</plexus>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/org/apache/maven/artifact/resolver/ArtifactResolverTest.xml b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/org/apache/maven/artifact/resolver/ArtifactResolverTest.xml
new file mode 100644
index 00000000..2b950859
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/org/apache/maven/artifact/resolver/ArtifactResolverTest.xml
@@ -0,0 +1,71 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<plexus>
+ <components>
+ <component>
+ <role>org.apache.maven.artifact.resolver.ArtifactResolver</role>
+ <role-hint>default</role-hint>
+ <implementation>org.apache.maven.artifact.resolver.DefaultArtifactResolver</implementation>
+ <isolated-realm>false</isolated-realm>
+ <requirements>
+ <requirement>
+ <role>org.codehaus.plexus.logging.Logger</role>
+ <role-hint>default</role-hint>
+ <field-name>logger</field-name>
+ </requirement>
+ <requirement>
+ <role>org.apache.maven.artifact.factory.ArtifactFactory</role>
+ <role-hint>default</role-hint>
+ <field-name>artifactFactory</field-name>
+ </requirement>
+ <requirement>
+ <role>org.apache.maven.artifact.resolver.ArtifactCollector</role>
+ <role-hint>default</role-hint>
+ <field-name>artifactCollector</field-name>
+ </requirement>
+ <requirement>
+ <role>org.apache.maven.artifact.resolver.ResolutionErrorHandler</role>
+ <role-hint>default</role-hint>
+ <field-name>resolutionErrorHandler</field-name>
+ </requirement>
+ <requirement>
+ <role>org.apache.maven.artifact.metadata.ArtifactMetadataSource</role>
+ <role-hint>test</role-hint>
+ <field-name>source</field-name>
+ </requirement>
+ <requirement>
+ <role>org.codehaus.plexus.PlexusContainer</role>
+ <role-hint>default</role-hint>
+ <field-name>container</field-name>
+ </requirement>
+ <requirement>
+ <role>org.apache.maven.plugin.LegacySupport</role>
+ <role-hint>default</role-hint>
+ <field-name>legacySupport</field-name>
+ </requirement>
+ <requirement>
+ <role>org.eclipse.aether.RepositorySystem</role>
+ <role-hint>default</role-hint>
+ <field-name>repoSystem</field-name>
+ </requirement>
+ </requirements>
+ </component>
+ </components>
+</plexus>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/org/apache/maven/artifact/resolver/ArtifactUpdatePolicyTest.xml b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/org/apache/maven/artifact/resolver/ArtifactUpdatePolicyTest.xml
new file mode 100644
index 00000000..b434d7b9
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/org/apache/maven/artifact/resolver/ArtifactUpdatePolicyTest.xml
@@ -0,0 +1,29 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<plexus>
+ <components>
+ <component>
+ <role>org.apache.maven.wagon.Wagon</role>
+ <role-hint>testfile</role-hint>
+ <implementation>org.apache.maven.artifact.resolver.TestFileWagon</implementation>
+ <instantiation-strategy>per-lookup</instantiation-strategy>
+ </component>
+ </components>
+</plexus> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/org/apache/maven/project/AbstractMavenProjectTestCase.xml b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/org/apache/maven/project/AbstractMavenProjectTestCase.xml
new file mode 100644
index 00000000..bcc291e1
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/org/apache/maven/project/AbstractMavenProjectTestCase.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<plexus>
+ <components>
+ <component>
+ <role>org.apache.maven.lifecycle.LifeCyclePluginAnalyzer</role>
+ <implementation>org.apache.maven.project.EmptyLifecyclePluginAnalyzer</implementation>
+ </component>
+ </components>
+</plexus>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/pom.xml
new file mode 100644
index 00000000..9443d87d
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/pom.xml
@@ -0,0 +1,155 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<model xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-core</artifactId>
+ <packaging>jar</packaging>
+ <name>Maven</name>
+ <version>2.0-SNAPSHOT</version>
+ <inceptionYear>2001</inceptionYear>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-model</artifactId>
+ <version>2.0-SNAPSHOT</version>
+ <type>jar</type>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-plugin</artifactId>
+ <version>2.0-SNAPSHOT</version>
+ <type>jar</type>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>commons-cli</groupId>
+ <artifactId>commons-cli</artifactId>
+ <version>1.0-beta-2</version>
+ <type>jar</type>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>plexus</groupId>
+ <artifactId>plexus-i18n</artifactId>
+ <version>1.0-beta-2-SNAPSHOT</version>
+ <type>jar</type>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>ognl</groupId>
+ <artifactId>ognl</artifactId>
+ <version>2.5.1</version>
+ <type>jar</type>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>marmalade</groupId>
+ <artifactId>marmalade-core</artifactId>
+ <version>0.1</version>
+ <type>jar</type>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>marmalade</groupId>
+ <artifactId>marmalade-el-ognl</artifactId>
+ <version>0.1</version>
+ <type>jar</type>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>plexus</groupId>
+ <artifactId>plexus-compiler-api</artifactId>
+ <version>1.0</version>
+ <type>jar</type>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>plexus</groupId>
+ <artifactId>plexus-compiler-javac</artifactId>
+ <version>1.0</version>
+ <type>jar</type>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>surefire</groupId>
+ <artifactId>surefire-booter</artifactId>
+ <version>1.1</version>
+ <type>jar</type>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>maven</groupId>
+ <artifactId>wagon-api</artifactId>
+ <version>0.9-SNAPSHOT</version>
+ <type>jar</type>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>wagon-http-lightweight</artifactId>
+ <version>0.9-SNAPSHOT</version>
+ <type>jar</type>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>maven</groupId>
+ <artifactId>wagon-ssh</artifactId>
+ <version>0.9-SNAPSHOT</version>
+ <type>jar</type>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>jsch</groupId>
+ <artifactId>jsch</artifactId>
+ <version>0.1.14</version>
+ <type>jar</type>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>qdox</groupId>
+ <artifactId>qdox</artifactId>
+ <version>1.2</version>
+ <type>jar</type>
+ <scope>compile</scope>
+ </dependency>
+ </dependencies>
+</model>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/projects/scope/project-with-scoped-dependencies.xml b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/projects/scope/project-with-scoped-dependencies.xml
new file mode 100644
index 00000000..c7062501
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/projects/scope/project-with-scoped-dependencies.xml
@@ -0,0 +1,99 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven</groupId>
+ <artifactId>maven-project-test</artifactId>
+ <name>Maven</name>
+ <version>1.0-beta-9</version>
+ <dependencies>
+
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>scope-default</artifactId>
+ <version>1.0</version>
+ </dependency>
+
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>scope-test</artifactId>
+ <version>1.0</version>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>scope-runtime</artifactId>
+ <version>1.0</version>
+ <scope>runtime</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>scope-compile</artifactId>
+ <version>1.0</version>
+ <scope>compile</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>scope-provided</artifactId>
+ <version>1.0</version>
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>maven-inherited</groupId>
+ <artifactId>scope-default</artifactId>
+ <version>1.0</version>
+ </dependency>
+
+ <dependency>
+ <groupId>maven-inherited</groupId>
+ <artifactId>scope-compile</artifactId>
+ <version>1.0</version>
+ <scope>compile</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>maven-inherited</groupId>
+ <artifactId>scope-runtime</artifactId>
+ <version>1.0</version>
+ <scope>runtime</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>maven-inherited</groupId>
+ <artifactId>scope-test</artifactId>
+ <version>1.0</version>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>maven-inherited</groupId>
+ <artifactId>scope-provided</artifactId>
+ <version>1.0</version>
+ <scope>provided</scope>
+ </dependency>
+ </dependencies>
+
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/projects/scope/transitive-compile-dep.xml b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/projects/scope/transitive-compile-dep.xml
new file mode 100644
index 00000000..1161c698
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/projects/scope/transitive-compile-dep.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven-test</groupId>
+ <artifactId>scope-compile</artifactId>
+ <version>1.0</version>
+ <dependencies>
+
+ <dependency>
+ <groupId>maven-test-compile</groupId>
+ <artifactId>scope-default</artifactId>
+ <version>1.0</version>
+ </dependency>
+
+ <dependency>
+ <groupId>maven-test-compile</groupId>
+ <artifactId>scope-test</artifactId>
+ <version>1.0</version>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>maven-test-compile</groupId>
+ <artifactId>scope-runtime</artifactId>
+ <version>1.0</version>
+ <scope>runtime</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>maven-test-compile</groupId>
+ <artifactId>scope-compile</artifactId>
+ <version>1.0</version>
+ <scope>compile</scope>
+ </dependency>
+ </dependencies>
+
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/projects/scope/transitive-default-dep.xml b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/projects/scope/transitive-default-dep.xml
new file mode 100644
index 00000000..c904be0e
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/projects/scope/transitive-default-dep.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven-test</groupId>
+ <artifactId>scope-default</artifactId>
+ <version>1.0</version>
+ <dependencies>
+
+ <dependency>
+ <groupId>maven-test-default</groupId>
+ <artifactId>scope-default</artifactId>
+ <version>1.0</version>
+ </dependency>
+
+ <dependency>
+ <groupId>maven-test-default</groupId>
+ <artifactId>scope-test</artifactId>
+ <version>1.0</version>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>maven-test-default</groupId>
+ <artifactId>scope-runtime</artifactId>
+ <version>1.0</version>
+ <scope>runtime</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>maven-test-default</groupId>
+ <artifactId>scope-compile</artifactId>
+ <version>1.0</version>
+ <scope>compile</scope>
+ </dependency>
+
+ </dependencies>
+
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/projects/scope/transitive-provided-dep.xml b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/projects/scope/transitive-provided-dep.xml
new file mode 100644
index 00000000..b85669ce
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/projects/scope/transitive-provided-dep.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven-test</groupId>
+ <artifactId>scope-provided</artifactId>
+ <version>1.0</version>
+ <dependencies>
+
+ <dependency>
+ <groupId>maven-test-provided</groupId>
+ <artifactId>scope-default</artifactId>
+ <version>1.0</version>
+ </dependency>
+
+ <dependency>
+ <groupId>maven-test-provided</groupId>
+ <artifactId>scope-test</artifactId>
+ <version>1.0</version>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>maven-test-provided</groupId>
+ <artifactId>scope-runtime</artifactId>
+ <version>1.0</version>
+ <scope>runtime</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>maven-test-provided</groupId>
+ <artifactId>scope-compile</artifactId>
+ <version>1.0</version>
+ <scope>compile</scope>
+ </dependency>
+ </dependencies>
+
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/projects/scope/transitive-runtime-dep.xml b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/projects/scope/transitive-runtime-dep.xml
new file mode 100644
index 00000000..921723c7
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/projects/scope/transitive-runtime-dep.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven-test</groupId>
+ <artifactId>scope-runtime</artifactId>
+ <version>1.0</version>
+ <dependencies>
+
+ <dependency>
+ <groupId>maven-test-runtime</groupId>
+ <artifactId>scope-default</artifactId>
+ <version>1.0</version>
+ </dependency>
+
+ <dependency>
+ <groupId>maven-test-runtime</groupId>
+ <artifactId>scope-test</artifactId>
+ <version>1.0</version>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>maven-test-runtime</groupId>
+ <artifactId>scope-runtime</artifactId>
+ <version>1.0</version>
+ <scope>runtime</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>maven-test-runtime</groupId>
+ <artifactId>scope-compile</artifactId>
+ <version>1.0</version>
+ <scope>compile</scope>
+ </dependency>
+
+ </dependencies>
+
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/projects/scope/transitive-test-dep.xml b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/projects/scope/transitive-test-dep.xml
new file mode 100644
index 00000000..ea2dde9f
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-compat/src/test/resources/projects/scope/transitive-test-dep.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven-test</groupId>
+ <artifactId>scope-test</artifactId>
+ <version>1.0</version>
+ <dependencies>
+
+ <dependency>
+ <groupId>maven-test-test</groupId>
+ <artifactId>scope-default</artifactId>
+ <version>1.0</version>
+ </dependency>
+
+ <dependency>
+ <groupId>maven-test-test</groupId>
+ <artifactId>scope-test</artifactId>
+ <version>1.0</version>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>maven-test-test</groupId>
+ <artifactId>scope-runtime</artifactId>
+ <version>1.0</version>
+ <scope>runtime</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>maven-test-test</groupId>
+ <artifactId>scope-compile</artifactId>
+ <version>1.0</version>
+ <scope>compile</scope>
+ </dependency>
+
+ </dependencies>
+
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/lifecycle-executor.txt b/framework/src/maven/apache-maven-3.3.3/maven-core/lifecycle-executor.txt
new file mode 100644
index 00000000..41e98bfd
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/lifecycle-executor.txt
@@ -0,0 +1,217 @@
+We have a lifecycle mapping for the packaging of *jar* below. You see that for this packaging we have a *default* lifecycle and a list of phases where each phase is a comma separated list of goals to run and they are in the form groupId:artifactId:version.
+
+<configuration>
+ <lifecycles>
+ <lifecycle>
+ <id>default</id>
+ <phases>
+ <process-resources>org.apache.maven.plugins:maven-resources-plugin:resources</process-resources>
+ <compile>org.apache.maven.plugins:maven-compiler-plugin:compile</compile>
+ <process-test-resources>org.apache.maven.plugins:maven-resources-plugin:testResources</process-test-resources>
+ <test-compile>org.apache.maven.plugins:maven-compiler-plugin:testCompile</test-compile>
+ <test>org.apache.maven.plugins:maven-surefire-plugin:test</test>
+ <package>org.apache.maven.plugins:maven-jar-plugin:jar</package>
+ <install>org.apache.maven.plugins:maven-install-plugin:install</install>
+ <deploy>org.apache.maven.plugins:maven-deploy-plugin:deploy</deploy>
+ </phases>
+ </lifecycle>
+ </lifecycles>
+</configuration>
+
+We need to turn this list of phases into a set of plugin objects that have an xml representation like the following:
+
+<plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-resources-plugin</artifactId>
+ <executions>
+ <execution>
+ <goals>
+ <goal>process</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ .
+ .
+ .
+</plugins>
+
+We need this form so that the model builder can make the first pass at merging. Full merging cannot be done because we don't know what the version of the plugin is yet that the user has requested. For plugins in the default lifecycle they are typically defined in the plugin management section of the parent POM. When the merging is complete we are going to have something that looks like the following:
+
+<plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-resources-plugin</artifactId>
+ <version>1.0</version</version>
+ <executions>
+ <execution>
+ <goals>
+ <goal>process</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ .
+ .
+ .
+</plugins>
+
+Once we have the version of the plugins the appropriate call to the plugin manager can be made to get the MojoDescriptor for the goal that needs to be run. In the MojoDescriptor we are interested in the <configuration/> element and <parameters/> element. From these elements we need to make a component configuration for the MojoExecution. The actual DOM like structure we create is of type PlexusConfiguration and is the type we use with the ComponentConfigurator to initialize fields in a Plexus component. Typically this is done within Plexus with the configuration supplied with component configuration, but in Maven we take configuration values from the POM. So we have to use the ComponentConfigurator outside of Plexus in order to configurure the Maven Mojo which is just a Plexus component. We can use the information from the MojoDescriptor along with the merged configuration information that is now present in the POM to create the complete PlexusConfiguration used to populate values in the Maven Mojo.
+
+foreach configuration element:
+ - if read only and being set squawk
+
+ - find the parameter
+ - get value from expression or default
+ - if required and null squawk
+
+ <configuration>
+ <attached implementation="boolean" default-value="true"/>
+ <localRepository implementation="org.apache.maven.artifact.repository.ArtifactRepository">${localRepository}</localRepository>
+ <resources implementation="java.util.List">${project.resources}</resources>
+ <repositories implementation="java.util.List">${project.repositories}</repositories>
+ <remoteArtifactRepositories implementation="java.util.List">${project.remoteArtifactRepositories}</remoteArtifactRepositories>
+ <appendedResourcesDirectory implementation="java.io.File">${basedir}/src/main/appended-resources</appendedResourcesDirectory>
+ <excludeScope implementation="java.lang.String" default-value="">${excludeScope}</excludeScope>
+ <includeScope implementation="java.lang.String" default-value="runtime">${includeScope}</includeScope>
+ <excludeGroupIds implementation="java.lang.String" default-value="">${excludeGroupIds}</excludeGroupIds>
+ <skip implementation="boolean" default-value="false">${remoteresources.skip}</skip>
+ <outputDirectory implementation="java.io.File">${project.build.directory}/maven-shared-archive-resources</outputDirectory>
+ <excludeArtifactIds implementation="java.lang.String" default-value="">${excludeArtifactIds}</excludeArtifactIds>
+ <excludeTransitive implementation="boolean" default-value="false">${excludeTransitive}</excludeTransitive>
+ <includeGroupIds implementation="java.lang.String" default-value="">${includeGroupIds}</includeGroupIds>
+ <mavenSession implementation="org.apache.maven.execution.MavenSession">${session}</mavenSession>
+ <project implementation="org.apache.maven.project.MavenProject">${project}</project>
+ <includeArtifactIds implementation="java.lang.String" default-value="">${includeArtifactIds}</includeArtifactIds>
+ </configuration>
+
+ <parameters>
+ <parameter>
+ <name>appendedResourcesDirectory</name>
+ <type>java.io.File</type>
+ <required>false</required>
+ <editable>true</editable>
+ </parameter>
+ <parameter>
+ <name>attached</name>
+ <type>boolean</type>
+ <required>false</required>
+ <editable>true</editable>
+ </parameter>
+ <parameter>
+ <name>excludeArtifactIds</name>
+ <type>java.lang.String</type>
+ <required>false</required>
+ <editable>true</editable>
+ </parameter>
+ <parameter>
+ <name>excludeGroupIds</name>
+ <type>java.lang.String</type>
+ <required>false</required>
+ <editable>true</editable>
+ </parameter>
+ <parameter>
+ <name>excludeScope</name>
+ <type>java.lang.String</type>
+ <required>false</required>
+ <editable>true</editable>
+ </parameter>
+ <parameter>
+ <name>excludeTransitive</name>
+ <type>boolean</type>
+ <required>false</required>
+ <editable>true</editable>
+ </parameter>
+ <parameter>
+ <name>includeArtifactIds</name>
+ <type>java.lang.String</type>
+ <required>false</required>
+ <editable>true</editable>
+ </parameter>
+ <parameter>
+ <name>includeGroupIds</name>
+ <type>java.lang.String</type>
+ <required>false</required>
+ <editable>true</editable>
+ </parameter>
+ <parameter>
+ <name>includeScope</name>
+ <type>java.lang.String</type>
+ <required>false</required>
+ <editable>true</editable>
+ </parameter>
+ <parameter>
+ <name>localRepository</name>
+ <type>org.apache.maven.artifact.repository.ArtifactRepository</type>
+ <required>true</required>
+ <editable>false</editable>
+ </parameter>
+ <parameter>
+ <name>mavenSession</name>
+ <type>org.apache.maven.execution.MavenSession</type>
+ <required>true</required>
+ <editable>false</editable>
+ <description>The Maven session.</description>
+ </parameter>
+ <parameter>
+ <name>outputDirectory</name>
+ <type>java.io.File</type>
+ <required>false</required>
+ <editable>true</editable>
+ </parameter>
+ <parameter>
+ <name>project</name>
+ <type>org.apache.maven.project.MavenProject</type>
+ <required>true</required>
+ <editable>false</editable>
+ </parameter>
+ <parameter>
+ <name>properties</name>
+ <type>java.util.Map</type>
+ <required>false</required>
+ <editable>true</editable>
+ </parameter>
+ <parameter>
+ <name>remoteArtifactRepositories</name>
+ <type>java.util.List</type>
+ <required>true</required>
+ <editable>false</editable>
+ </parameter>
+ <parameter>
+ <name>repositories</name>
+ <type>java.util.List</type>
+ <required>true</required>
+ <editable>false</editable>
+ </parameter>
+ <parameter>
+ <name>resourceBundles</name>
+ <type>java.util.List</type>
+ <required>true</required>
+ <editable>true</editable>
+ </parameter>
+ <parameter>
+ <name>resources</name>
+ <type>java.util.List</type>
+ <required>true</required>
+ <editable>false</editable>
+ </parameter>
+ <parameter>
+ <name>skip</name>
+ <type>boolean</type>
+ <required>false</required>
+ <editable>true</editable>
+ </parameter>
+ <parameter>
+ <name>supplementalModels</name>
+ <type>java.lang.String[]</type>
+ <required>false</required>
+ <editable>true</editable>
+ </parameter>
+ </parameters>
+
+- we need to know what came from the POM, and validate those
+- plugin in any default values
+- check to see if anything is missing
+
+In the case of something like Modello where it is common to specify the configuration for all the goals outside the execution block we need to account for creating the right configuration element which includes only those configuration elements for a particular goal that that particular goal understands. We need to walk through the parameters of the Mojo in question and only take the configuration options that apply.
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/plugin-manager.txt b/framework/src/maven/apache-maven-3.3.3/maven-core/plugin-manager.txt
new file mode 100644
index 00000000..f3fcf8e9
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/plugin-manager.txt
@@ -0,0 +1,184 @@
+h3. Plugins
+
+* Execution model
+* Metadata model
+* Metadata tooling
+ ** Metadata extractor
+ ** Metadata reader
+ ** Metadata writer
+ ** Metadata adapter (if required for the target system)
+* Maven packaging and lifecycle
+* Maven test harness for plugin execution model
+* Eclipse IDE tooling for plugin execution model and metadata model
+
+- we also seem to have information like the plugin lifecycle model that's burried inside the maven execution model
+- we also seem to have artifact information tangled inside the plugin model
+- we have to deal with scripting implementations (groovy, beanshell, ruby)
+- we need to deal with a shared context for plugins, like the guarded mojos
+- we need to deal with plugins as core application logic which can also interact with plugins
+
+* Along with this comes the testing strategies that make this work
+* The repository model where plugins can be stored and cataloged
+* Bridging this into an OSGi system: if this could be done then we can basically take over p2
+
+TODO
+
+- dealing with processing of input and adapting GAVs before searching i.e. plugin groups in Maven and default searching
+- how to deal with resolution from different places like local/remote/workspace
+- how to incorporate the metadata processor to start with
+- create a hook to programmatically configure the test
+- create a plugin processor
+- directory
+- jar
+- hooks for loading
+
+- i could make an annotation that marked another class as its plugin discoverer, i could just add it to the
+ the component descriptor and when it's loaded we can add the discoverer, that would be simpler. i could
+ also do this with the lister as well
+i'l
+// 1 the metadata -> model plugin/mojo descriptor
+// 2 tools for doing the mapping
+// 3 the component model -> interfaces for the plugin
+
+// The plugin manager should load up a directory structure of plugins.
+// - a plugin per directory where the plugin is present with its deps
+// - a plugin that has its dependencies packaged up with it
+// - implement filters and create a test where a plugin fails if the right classes are not filtered
+// - plugins with a dependency the same as the core but different versions, make it fail then fix it
+
+ /*
+ *
+ * h2. Concerns for the plugin manager
+ *
+ * h3. resolving the dependencies of a plugin - these could be resolved remotely at runtime or, -
+ * they could be resolved from a local repository - i think we need a simple dependency model here
+ * that is more mercury related and not Maven related i.e no POMs - workspace resolver - we need
+ * tools to pre-populate this repository
+ *
+ * h3. create an isolated classloader
+ *
+ * h3. lookup the plugin with a configuration
+ *
+ * h3. execute the plugin
+ *
+ * h3. plugins may have to deal with particular actions when a plugin is - installed - loaded -
+ * unloaded - update - uninstalled
+ *
+ * h3. plugins should be able to have specific metadata for a plugin model and that be translated -
+ * dependencies - resources - configuration - extension points of plugins
+ *
+ * For a particular application plugin there will be a declarative descriptor for that plugin type.
+ *
+ * - nexus - the plugin class - UI to contribute - what JS to hook into the UI - what resources to
+ * load into the UI - having packed or unpacked plugins, and positioning resources if necessary -
+ * maven can work out of the classloader, nexus plugins probably couldn't given the js and image
+ * resources
+ *
+ * We need to look at Maven, and Nexus as use cases and figure out what each of them needs to be
+ * able to do
+ *
+ * - now what is really the difference between this and loading a component in plexus - custom
+ * classloading capability - remote resolution of dependencies - do we want a model for sharing
+ * information among plugins, is this more like an extension point - do we need a sort of bus for
+ * application data - do we need a dictionary for our applications like Apple does. We could easily
+ * hook into this and this is the model we need to follow - how many of our REST services do not map
+ * directory to a method in the application interface?
+ *
+ * - research extension points versus plugins
+ *
+ * from igor: two plugins A and B, both depend on the same library but use different versions, say
+ * lib 1.0 and lib 2.0 when debugger hits a breakpoint inside a class from the library, IDE needs to
+ * know which version of library the class comes from
+ */
+
+This document outlines the concerns of a general plugin manager that would be used in conjunction with any Plexus-based application. The following outlined concerns are an attempt to describe what a plugin manager would need to do for Maven and for Nexus.
+
+h2. Concerns for the plugin manager
+
+h3. Resolving the dependencies of a plugin
+
+A plugin manager would need to know how to find the dependencies of a plugin whether that be from a workspace of an IDE, a local Maven repository, or a remote Maven repository. During development in an IDE we would need layered resolution approach that would allow resolution from the workspace, then the local Maven repository and then from any number of remote Maven repositories. During development from the command line we would need a layered resolution approach that would allow resolution from the local Maven repository and then from any number of remote Maven repositories. In production the resolution for the dependencies could also be layered but would depend on the preferred model for the given application. In the case of Maven no plugin dependencies are shipped with a Maven plugin, but in the case of Nexus we would probably want to include the dependencies for self-containment.
+
+h4. Working with POMs during development
+
+During the development of a plugin we would want to make it easy for a developer to create a plugin which means we would allow the direct use of a POM to state the dependencies of a given plugin and any tooling we created would be responsible for turning the dependency information in the POM into plugin metadata which described the dependencies of the plugin.
+
+We are looking at using Mercury for the resolution and retrieval of the plugin dependencies so during development we would translate the POMs into dependency information that Mercury can understand, and in production we would have the pre-digested format that Mercury could utilize to resolve and retrieve dependencies. We need to be careful that we are using Mercury during development and production so that we don’t get in the situation where Maven 2.x is resolving different then Mercury is. We can still leverage POMs during development but we need to make sure Mercury is doing the work.
+
+With respect to development inside an IDE the workspace from which we would like to resolve and retrieve dependencies is a read-only local repository to Mercury which is put at the front-end of the search order of any repository that Mercury will consult for artifacts.
+
+h4. Generation of plugin metadata and packaging
+
+To create the packaging for a plugin a special Maven packaging would be created with an accompanying life-cycle in order to create the plugin metadata required and create an archive of the plugin that can be consumed at runtime.
+
+h3. Creation of an isolated classloader
+
+The plugin artifact and its dependency artifacts will be loaded in an isolated ClassRealm which is simply an extension of the standard URLClassLoader. Mercury would be responsible for resolving and retrieving the dependencies which would then be used to populate a ClassRealm where there would be a connection to the host applications ClassRealm as the parent but the search order would be child first, and the parent ClassRealm can optionally choose to limit the searching to particular classes. The application ClassRealm, or parent ClassRealm, should only expose the API in the form of and application interface and model classes that may be required by plugins.
+
+For debugging purposes we also need to keep track of what versions of artifacts are being used so that when we are debugging in the IDE we can find the specific sources for a given version of a library so that the developer can debug the correct version of a library being used for a plugin.
+
+h3. Discovery all Plexus components
+
+Once the ClassRealm is populated with the plugin artifact and its dependency artifacts a discovery operation must be performed on the plugin ClassRealm in order to discover any Plexus components that may be present in any of the artifacts required for the plugins execution.
+
+h3. Looking up the plugin with a configuration
+
+Once the ClassRealm has been populated and all Plexus components have been discovered a lookup can be performed to retrieve the primary plugin component. Currently the component would need to be looked up and then the BasicComponentConfigurator would need to configure the component with a given Plexus configuration. We will discuss later how we would retrieve the Plexus configuration required for a given plugin.
+
+When a plugin has a complete and valid configuration, the plugin would be looked up in the Plexus container and be ready to perform any operations requested of it.
+
+h3. Execution of the plugin
+
+I still need to do some work here to figure out how a dispatching to a particular plugin would occur because everything needs to be mediated through the host application. For a given action that is possible for a user to perform in the UI we need to know the URI that is to be used with its given parameters. That URI in turn must map internally to a method in a given component which belongs to a plugin. This mapping should actually be more generalized and it shouldn’t matter internally whether this maps to the core application or extension of the application in the form of plugins.
+
+In the short term we are working with the model where the URI maps to a resource, and the resource itself is a Plexus component which can itself have a reference to the host application in order to perform its work. This may not occur in the first versions of the plugin API but a resource needs to simply become the mapping mechanism by which parameters are taken from the REST side of the application and mapped into a method call within a given Plexus component. Whether that be the core Nexus application or a component provided by a plugin.
+
+At the very least in the short term the resource needs to know how to lookup the component that is required to perform the work. This needs to be made simple, for the time being we can write and test plugins working in the same realm until we get complete isolation working.
+
+h3. Plugins need a specific metadata model
+
+Each application will have its own model for plugins. Much of this model will be common across applications but there will always be issues specific to a particular applications’s plugins. Some of the issues that need to be taken into consideration:
+
+* Plugin dependencies
+* Plugin resources like Javascript files or images
+* Configuration metadata and default configuration values
+* Extension points that plugins might expose
+
+h3. The plugin manager may have to deal with particular actions when a plugin is
+
+* installation
+* activation
+* update
+* deactivation
+* un-installation
+
+When a plugin is installed we may want to check the license and make users agree. We may also want to unpack the given plugin in a particular location.
+
+We might want to separate between installation and activation, it might be nice to allow a user to activate/deactivate a plugin instead of having to uninstall and reinstall a plugin in particular cases. This would prevent having to reconfigure the plugin again. For example it might be nice to turn off LDAP authentication without having to uninstall the plugin.
+
+These particular phases in a plugin’s lifecycle can probably be generalized to all plugins so could be something implemented in all plugins. Here we could have the descriptor either point to methods for each of these phases to execute or we could create a lifecycle in Plexus for these phases.
+
+For a particular application plugin there will be a declarative descriptor for that plugin type.
+
+h3. Some general notes on Nexus
+
+The plugin metadata:
+* the plugin class
+* UI to contribute
+* what JS to hook into the UI
+* what resources to load into the UI
+* having packed or unpacked plugins, and positioning resources if necessary
+* maven can work out of the classloader, nexus plugins probably couldn't given the js and image resources
+
+h3. Other issues
+
+We need to look at Maven, and Nexus as use cases and figure out what each of them needs to be able to do
+
+* now what is really the difference between this and loading a component in plexus
+* do we want a model for sharing information among plugins, is this more like an extension point
+* do we need a sort of bus for application data
+* do we need a dictionary for our applications like Apple does. We could easily hook into this and this is the model we need to follow. Following the model of apple applications the dictionary is what the REST URI should attach to. Not creating custom logic in the resource code.
+* how many of our REST services do not map directory to a method in the application interface?
+
+- an example of adding js
+- an example of adding a URI
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/pom.xml
new file mode 100644
index 00000000..c1d6c167
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/pom.xml
@@ -0,0 +1,238 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+ <!--
+ Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE
+ file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by
+ applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language
+ governing permissions and limitations under the License.
+ -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven</artifactId>
+ <version>3.3.3</version>
+ </parent>
+
+ <artifactId>maven-core</artifactId>
+
+ <name>Maven Core</name>
+ <description>Maven Core classes.</description>
+
+ <scm><!-- remove when git scm url format can accept artifact-id at the end, as automatically inherited -->
+ <connection>scm:git:https://git-wip-us.apache.org/repos/asf/maven.git</connection>
+ <developerConnection>scm:git:https://git-wip-us.apache.org/repos/asf/maven.git</developerConnection>
+ <tag>maven-3.3.3</tag>
+ </scm>
+
+ <properties>
+ <checkstyle.violation.ignore>RedundantThrows,NewlineAtEndOfFile,ParameterNumber,MethodLength,FileLength,JavadocType,MethodName,MagicNumber,ConstantName,VisibilityModifier,InnerAssignment</checkstyle.violation.ignore>
+ </properties>
+
+ <dependencies>
+ <!-- Maven -->
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-model</artifactId>
+ </dependency>
+ <!-- Remove the following two deps to see how to remove Settings from the core -->
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-settings</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-settings-builder</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-repository-metadata</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-artifact</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-plugin-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-model-builder</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-aether-provider</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.aether</groupId>
+ <artifactId>aether-impl</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.aether</groupId>
+ <artifactId>aether-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.aether</groupId>
+ <artifactId>aether-util</artifactId>
+ </dependency>
+ <!-- Plexus -->
+ <dependency>
+ <groupId>org.eclipse.sisu</groupId>
+ <artifactId>org.eclipse.sisu.plexus</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.sonatype.sisu</groupId>
+ <artifactId>sisu-guice</artifactId>
+ <classifier>no_aop</classifier>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-interpolation</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-utils</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-classworlds</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-component-annotations</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.sonatype.plexus</groupId>
+ <artifactId>plexus-sec-dispatcher</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>commons-jxpath</groupId>
+ <artifactId>commons-jxpath</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-core</artifactId>
+ <version>1.9.5</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <resources>
+ <resource>
+ <directory>src/main/resources</directory>
+ <filtering>true</filtering>
+ </resource>
+ </resources>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.rat</groupId>
+ <artifactId>apache-rat-plugin</artifactId>
+ <configuration>
+ <excludes combine.children="append">
+ <exclude>lifecycle-executor.txt</exclude>
+ <exclude>plugin-manager.txt</exclude>
+ <exclude>project-builder.txt</exclude>
+ <exclude>src/site/resources/design/**</exclude>
+ </excludes>
+ </configuration>
+ </plugin>
+ <!--This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build itself.-->
+ <plugin>
+ <groupId>org.eclipse.m2e</groupId>
+ <artifactId>lifecycle-mapping</artifactId>
+ <version>1.0.0</version>
+ <configuration>
+ <lifecycleMappingMetadata>
+ <pluginExecutions>
+ <pluginExecution>
+ <pluginExecutionFilter>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>buildnumber-maven-plugin</artifactId>
+ <versionRange>[1.2,)</versionRange>
+ <goals>
+ <goal>create-timestamp</goal>
+ </goals>
+ </pluginExecutionFilter>
+ <action>
+ <ignore />
+ </action>
+ </pluginExecution>
+ </pluginExecutions>
+ </lifecycleMappingMetadata>
+ </configuration>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-component-metadata</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.eclipse.sisu</groupId>
+ <artifactId>sisu-maven-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.modello</groupId>
+ <artifactId>modello-maven-plugin</artifactId>
+ <configuration>
+ <version>1.1.0</version>
+ <models>
+ <model>src/main/mdo/toolchains.mdo</model>
+ </models>
+ </configuration>
+ <executions>
+ <execution>
+ <id>plugin-site-doc</id>
+ <phase>pre-site</phase>
+ <goals>
+ <goal>xdoc</goal>
+ </goals>
+ <configuration>
+ <version>1.0.0</version>
+ <models>
+ <model>src/main/mdo/extension.mdo</model>
+ </models>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>buildnumber-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>create-noncanonicalrev</id>
+ <goals>
+ <goal>create-timestamp</goal>
+ </goals>
+ <configuration>
+ <timestampFormat>'NON-CANONICAL_'yyyy-MM-dd'T'HH:mm:ss_'${user.name}'</timestampFormat>
+ <timestampPropertyName>nonCanonicalRevision</timestampPropertyName>
+ </configuration>
+ </execution>
+ <execution>
+ <id>create-buildnumber</id>
+ <goals>
+ <goal>create</goal>
+ </goals>
+ <configuration>
+ <doCheck>false</doCheck>
+ <doUpdate>false</doUpdate>
+ <revisionOnScmFailure>${nonCanonicalRevision}</revisionOnScmFailure>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/project-builder.txt b/framework/src/maven/apache-maven-3.3.3/maven-core/project-builder.txt
new file mode 100644
index 00000000..a9aab65b
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/project-builder.txt
@@ -0,0 +1 @@
+Maven Project Builder and Maven Model Builder
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/AbstractMavenLifecycleParticipant.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/AbstractMavenLifecycleParticipant.java
new file mode 100644
index 00000000..20f6c802
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/AbstractMavenLifecycleParticipant.java
@@ -0,0 +1,77 @@
+package org.apache.maven;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.execution.MavenSession;
+
+/**
+ * Allows core extensions to participate in Maven build session lifecycle.
+ *
+ * All callback methods (will) follow beforeXXX/afterXXX naming pattern to
+ * indicate at what lifecycle point it is being called.
+ *
+ * @see <a href="http://maven.apache.org/examples/maven-3-lifecycle-extensions.html">example</a>
+ * @see <a href="http://jira.codehaus.org/browse/MNG-4224">MNG-4224</a>
+ * @since 3.0-alpha-3
+ */
+public abstract class AbstractMavenLifecycleParticipant
+{
+
+ /**
+ * Invoked after all MavenProject instances have been created.
+ *
+ * This callback is intended to allow extensions to manipulate MavenProjects
+ * before they are sorted and actual build execution starts.
+ */
+ public void afterProjectsRead( MavenSession session )
+ throws MavenExecutionException
+ {
+ // do nothing
+ }
+
+ /**
+ * Invoked after MavenSession instance has been created.
+ *
+ * This callback is intended to allow extensions to inject execution properties,
+ * activate profiles and perform similar tasks that affect MavenProject
+ * instance construction.
+ */
+ // TODO: This is too early for build extensions, so maybe just remove it?
+ public void afterSessionStart( MavenSession session )
+ throws MavenExecutionException
+ {
+ // do nothing
+ }
+
+ /**
+ * Invoked after all projects were built.
+ *
+ * This callback is intended to allow extensions to perform cleanup of any
+ * allocated external resources after the build. It is invoked on best-effort
+ * basis and may be missed due to an Error or RuntimeException in Maven core
+ * code.
+ * @since 3.2.1, MNG-5389
+ */
+ public void afterSessionEnd( MavenSession session )
+ throws MavenExecutionException
+ {
+ // do nothing
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/ArtifactFilterManager.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/ArtifactFilterManager.java
new file mode 100644
index 00000000..2cf9f996
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/ArtifactFilterManager.java
@@ -0,0 +1,51 @@
+package org.apache.maven;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Set;
+
+import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
+
+public interface ArtifactFilterManager
+{
+ /**
+ * Returns a filter for core + extension artifacts.
+ *
+ * @deprecated use {@code META-INF/maven/extension.xml} to define artifacts exported by Maven core and plugin
+ * extensions.
+ */
+ ArtifactFilter getArtifactFilter();
+
+ /**
+ * Returns a filter for only the core artifacts.
+ */
+ ArtifactFilter getCoreArtifactFilter();
+
+ /**
+ * Exclude an extension artifact (doesn't affect getArtifactFilter's result, only getExtensionArtifactFilter).
+ *
+ * @deprecated use {@code META-INF/maven/extension.xml} to define artifacts exported by Maven core and plugin
+ * extensions.
+ */
+ void excludeArtifact( String artifactId );
+
+ Set<String> getCoreArtifactExcludes();
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/ArtifactFilterManagerDelegate.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/ArtifactFilterManagerDelegate.java
new file mode 100644
index 00000000..13893254
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/ArtifactFilterManagerDelegate.java
@@ -0,0 +1,34 @@
+package org.apache.maven;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Set;
+
+/**
+ * @deprecated use {@code META-INF/maven/extension.xml} to define artifacts exported by Maven core extensions.
+ */
+public interface ArtifactFilterManagerDelegate
+{
+
+ void addExcludes( Set<String> excludes );
+
+ void addCoreExcludes( Set<String> excludes );
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/BuildAbort.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/BuildAbort.java
new file mode 100644
index 00000000..3255e32b
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/BuildAbort.java
@@ -0,0 +1,39 @@
+package org.apache.maven;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * A special throwable used to signal a graceful abort of the build.
+ */
+public class BuildAbort
+ extends Error
+{
+
+ public BuildAbort( String message )
+ {
+ super( message );
+ }
+
+ public BuildAbort( String message, Throwable cause )
+ {
+ super( message, cause );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/BuildFailureException.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/BuildFailureException.java
new file mode 100644
index 00000000..d35b0d2a
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/BuildFailureException.java
@@ -0,0 +1,39 @@
+package org.apache.maven;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * One or more builds failed.
+ *
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ */
+public class BuildFailureException
+ extends Exception
+{
+ public BuildFailureException( String message )
+ {
+ super( message );
+ }
+
+ public BuildFailureException( String message, Throwable cause )
+ {
+ super( message, cause );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/DefaultArtifactFilterManager.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/DefaultArtifactFilterManager.java
new file mode 100644
index 00000000..1962f917
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/DefaultArtifactFilterManager.java
@@ -0,0 +1,112 @@
+package org.apache.maven;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
+import org.apache.maven.artifact.resolver.filter.ExclusionSetFilter;
+import org.apache.maven.extension.internal.CoreExportsProvider;
+
+/**
+ * @author Jason van Zyl
+ */
+@Named
+@Singleton
+@SuppressWarnings( "deprecation" )
+public class DefaultArtifactFilterManager
+ implements ArtifactFilterManager
+{
+
+ // this is a live injected collection
+ protected final List<ArtifactFilterManagerDelegate> delegates;
+
+ protected Set<String> excludedArtifacts;
+
+ private final Set<String> coreArtifacts;
+
+ @Inject
+ public DefaultArtifactFilterManager( List<ArtifactFilterManagerDelegate> delegates,
+ CoreExportsProvider coreExports )
+ {
+ this.delegates = delegates;
+ this.coreArtifacts = coreExports.get().getExportedArtifacts();
+ }
+
+ private synchronized Set<String> getExcludedArtifacts()
+ {
+ if ( excludedArtifacts == null )
+ {
+ excludedArtifacts = new LinkedHashSet<String>( coreArtifacts );
+ }
+ return excludedArtifacts;
+ }
+
+ /**
+ * Returns the artifact filter for the core + extension artifacts.
+ *
+ * @see org.apache.maven.ArtifactFilterManager#getArtifactFilter()
+ */
+ public ArtifactFilter getArtifactFilter()
+ {
+ Set<String> excludes = new LinkedHashSet<String>( getExcludedArtifacts() );
+
+ for ( ArtifactFilterManagerDelegate delegate : delegates )
+ {
+ delegate.addExcludes( excludes );
+ }
+
+ return new ExclusionSetFilter( excludes );
+ }
+
+ /**
+ * Returns the artifact filter for the standard core artifacts.
+ *
+ * @see org.apache.maven.ArtifactFilterManager#getExtensionDependencyFilter()
+ */
+ public ArtifactFilter getCoreArtifactFilter()
+ {
+ return new ExclusionSetFilter( getCoreArtifactExcludes() );
+ }
+
+ public void excludeArtifact( String artifactId )
+ {
+ getExcludedArtifacts().add( artifactId );
+ }
+
+ public Set<String> getCoreArtifactExcludes()
+ {
+ Set<String> excludes = new LinkedHashSet<String>( coreArtifacts );
+
+ for ( ArtifactFilterManagerDelegate delegate : delegates )
+ {
+ delegate.addCoreExcludes( excludes );
+ }
+
+ return excludes;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/DefaultMaven.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/DefaultMaven.java
new file mode 100644
index 00000000..94e75e02
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/DefaultMaven.java
@@ -0,0 +1,521 @@
+package org.apache.maven;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.maven.artifact.ArtifactUtils;
+import org.apache.maven.execution.DefaultMavenExecutionResult;
+import org.apache.maven.execution.ExecutionEvent;
+import org.apache.maven.execution.MavenExecutionRequest;
+import org.apache.maven.execution.MavenExecutionResult;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.execution.ProjectDependencyGraph;
+import org.apache.maven.graph.GraphBuilder;
+import org.apache.maven.internal.aether.DefaultRepositorySystemSessionFactory;
+import org.apache.maven.lifecycle.internal.ExecutionEventCatapult;
+import org.apache.maven.lifecycle.internal.LifecycleStarter;
+import org.apache.maven.model.building.ModelProblem;
+import org.apache.maven.model.building.Result;
+import org.apache.maven.plugin.LegacySupport;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.project.ProjectBuilder;
+import org.apache.maven.repository.LocalRepositoryNotAccessibleException;
+import org.apache.maven.session.scope.internal.SessionScope;
+import org.codehaus.plexus.PlexusContainer;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
+import org.codehaus.plexus.logging.Logger;
+import org.eclipse.aether.DefaultRepositorySystemSession;
+import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.repository.WorkspaceReader;
+import org.eclipse.aether.util.repository.ChainedWorkspaceReader;
+
+import com.google.common.collect.Iterables;
+
+/**
+ * @author Jason van Zyl
+ */
+@Component( role = Maven.class )
+public class DefaultMaven
+ implements Maven
+{
+
+ @Requirement
+ private Logger logger;
+
+ @Requirement
+ protected ProjectBuilder projectBuilder;
+
+ @Requirement
+ private LifecycleStarter lifecycleStarter;
+
+ @Requirement
+ protected PlexusContainer container;
+
+ @Requirement
+ private ExecutionEventCatapult eventCatapult;
+
+ @Requirement
+ private LegacySupport legacySupport;
+
+ @Requirement
+ private SessionScope sessionScope;
+
+ @Requirement
+ private DefaultRepositorySystemSessionFactory repositorySessionFactory;
+
+ @Requirement( hint = GraphBuilder.HINT )
+ private GraphBuilder graphBuilder;
+
+ @Override
+ public MavenExecutionResult execute( MavenExecutionRequest request )
+ {
+ MavenExecutionResult result;
+
+ try
+ {
+ result = doExecute( request );
+ }
+ catch ( OutOfMemoryError e )
+ {
+ result = addExceptionToResult( new DefaultMavenExecutionResult(), e );
+ }
+ catch ( RuntimeException e )
+ {
+ //TODO Hack to make the cycle detection the same for the new graph builder
+ if ( e.getCause() instanceof ProjectCycleException )
+ {
+ result = addExceptionToResult( new DefaultMavenExecutionResult(), e.getCause() );
+ }
+ else
+ {
+ result = addExceptionToResult( new DefaultMavenExecutionResult(),
+ new InternalErrorException( "Internal error: " + e, e ) );
+ }
+ }
+ finally
+ {
+ legacySupport.setSession( null );
+ }
+
+ return result;
+ }
+
+ //
+ // 1) Setup initial properties.
+ //
+ // 2) Validate local repository directory is accessible.
+ //
+ // 3) Create RepositorySystemSession.
+ //
+ // 4) Create MavenSession.
+ //
+ // 5) Execute AbstractLifecycleParticipant.afterSessionStart(session)
+ //
+ // 6) Get reactor projects looking for general POM errors
+ //
+ // 7) Create ProjectDependencyGraph using trimming which takes into account --projects and reactor mode.
+ // This ensures that the projects passed into the ReactorReader are only those specified.
+ //
+ // 8) Create ReactorReader with the getProjectMap( projects ). NOTE that getProjectMap(projects) is the code that
+ // checks for duplicate projects definitions in the build. Ideally this type of duplicate checking should be
+ // part of getting the reactor projects in 6). The duplicate checking is conflated with getProjectMap(projects).
+ //
+ // 9) Execute AbstractLifecycleParticipant.afterProjectsRead(session)
+ //
+ // 10) Create ProjectDependencyGraph without trimming (as trimming was done in 7). A new topological sort is
+ // required after the execution of 9) as the AbstractLifecycleParticipants are free to mutate the MavenProject
+ // instances, which may change dependencies which can, in turn, affect the build order.
+ //
+ // 11) Execute LifecycleStarter.start()
+ //
+ @SuppressWarnings( "checkstyle:methodlength" )
+ private MavenExecutionResult doExecute( MavenExecutionRequest request )
+ {
+ request.setStartTime( new Date() );
+
+ MavenExecutionResult result = new DefaultMavenExecutionResult();
+
+ try
+ {
+ validateLocalRepository( request );
+ }
+ catch ( LocalRepositoryNotAccessibleException e )
+ {
+ return addExceptionToResult( result, e );
+ }
+
+ //
+ // We enter the session scope right after the MavenSession creation and before any of the
+ // AbstractLifecycleParticipant lookups
+ // so that @SessionScoped components can be @Injected into AbstractLifecycleParticipants.
+ //
+ sessionScope.enter();
+ try
+ {
+ DefaultRepositorySystemSession repoSession =
+ (DefaultRepositorySystemSession) newRepositorySession( request );
+ MavenSession session = new MavenSession( container, repoSession, request, result );
+
+ sessionScope.seed( MavenSession.class, session );
+
+ legacySupport.setSession( session );
+
+ return doExecute( request, session, result, repoSession );
+ }
+ finally
+ {
+ sessionScope.exit();
+ }
+ }
+
+ private MavenExecutionResult doExecute( MavenExecutionRequest request, MavenSession session,
+ MavenExecutionResult result, DefaultRepositorySystemSession repoSession )
+ {
+ try
+ {
+ for ( AbstractMavenLifecycleParticipant listener : getLifecycleParticipants( Collections
+ .<MavenProject>emptyList() ) )
+ {
+ listener.afterSessionStart( session );
+ }
+ }
+ catch ( MavenExecutionException e )
+ {
+ return addExceptionToResult( result, e );
+ }
+
+ eventCatapult.fire( ExecutionEvent.Type.ProjectDiscoveryStarted, session, null );
+
+ Result<? extends ProjectDependencyGraph> graphResult = buildGraph( session, result );
+
+ if ( graphResult.hasErrors() )
+ {
+ return addExceptionToResult( result,
+ Iterables.toArray( graphResult.getProblems(), ModelProblem.class )[0]
+ .getException() );
+ }
+
+ try
+ {
+ session.setProjectMap( getProjectMap( session.getProjects() ) );
+ }
+ catch ( DuplicateProjectException e )
+ {
+ return addExceptionToResult( result, e );
+ }
+
+ WorkspaceReader reactorWorkspace;
+ try
+ {
+ reactorWorkspace = container.lookup( WorkspaceReader.class, ReactorReader.HINT );
+ }
+ catch ( ComponentLookupException e )
+ {
+ return addExceptionToResult( result, e );
+ }
+
+ //
+ // Desired order of precedence for local artifact repositories
+ //
+ // Reactor
+ // Workspace
+ // User Local Repository
+ //
+ repoSession.setWorkspaceReader( ChainedWorkspaceReader.newInstance( reactorWorkspace,
+ repoSession.getWorkspaceReader() ) );
+
+ repoSession.setReadOnly();
+
+ ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader();
+ try
+ {
+ for ( AbstractMavenLifecycleParticipant listener : getLifecycleParticipants( session.getProjects() ) )
+ {
+ Thread.currentThread().setContextClassLoader( listener.getClass().getClassLoader() );
+
+ listener.afterProjectsRead( session );
+ }
+ }
+ catch ( MavenExecutionException e )
+ {
+ return addExceptionToResult( result, e );
+ }
+ finally
+ {
+ Thread.currentThread().setContextClassLoader( originalClassLoader );
+ }
+
+ //
+ // The projects need to be topologically after the participants have run their afterProjectsRead(session)
+ // because the participant is free to change the dependencies of a project which can potentially change the
+ // topological order of the projects, and therefore can potentially change the build order.
+ //
+ // Note that participants may affect the topological order of the projects but it is
+ // not expected that a participant will add or remove projects from the session.
+ //
+
+ graphResult = buildGraph( session, result );
+
+ if ( graphResult.hasErrors() )
+ {
+ return addExceptionToResult( result,
+ Iterables.toArray( graphResult.getProblems(), ModelProblem.class )[0]
+ .getException() );
+ }
+
+ try
+ {
+ if ( result.hasExceptions() )
+ {
+ return result;
+ }
+
+ result.setTopologicallySortedProjects( session.getProjects() );
+
+ result.setProject( session.getTopLevelProject() );
+
+ lifecycleStarter.execute( session );
+
+ validateActivatedProfiles( session.getProjects(), request.getActiveProfiles() );
+
+ if ( session.getResult().hasExceptions() )
+ {
+ return addExceptionToResult( result, session.getResult().getExceptions().get( 0 ) );
+ }
+ }
+ finally
+ {
+ try
+ {
+ afterSessionEnd( session.getProjects(), session );
+ }
+ catch ( MavenExecutionException e )
+ {
+ return addExceptionToResult( result, e );
+ }
+ }
+
+ return result;
+ }
+
+ private void afterSessionEnd( Collection<MavenProject> projects, MavenSession session )
+ throws MavenExecutionException
+ {
+ ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader();
+ try
+ {
+ for ( AbstractMavenLifecycleParticipant listener : getLifecycleParticipants( projects ) )
+ {
+ Thread.currentThread().setContextClassLoader( listener.getClass().getClassLoader() );
+
+ listener.afterSessionEnd( session );
+ }
+ }
+ finally
+ {
+ Thread.currentThread().setContextClassLoader( originalClassLoader );
+ }
+ }
+
+ public RepositorySystemSession newRepositorySession( MavenExecutionRequest request )
+ {
+ return repositorySessionFactory.newRepositorySession( request );
+ }
+
+ private void validateLocalRepository( MavenExecutionRequest request )
+ throws LocalRepositoryNotAccessibleException
+ {
+ File localRepoDir = request.getLocalRepositoryPath();
+
+ logger.debug( "Using local repository at " + localRepoDir );
+
+ localRepoDir.mkdirs();
+
+ if ( !localRepoDir.isDirectory() )
+ {
+ throw new LocalRepositoryNotAccessibleException( "Could not create local repository at " + localRepoDir );
+ }
+ }
+
+ private Collection<AbstractMavenLifecycleParticipant> getLifecycleParticipants( Collection<MavenProject> projects )
+ {
+ Collection<AbstractMavenLifecycleParticipant> lifecycleListeners =
+ new LinkedHashSet<AbstractMavenLifecycleParticipant>();
+
+ ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader();
+ try
+ {
+ try
+ {
+ lifecycleListeners.addAll( container.lookupList( AbstractMavenLifecycleParticipant.class ) );
+ }
+ catch ( ComponentLookupException e )
+ {
+ // this is just silly, lookupList should return an empty list!
+ logger.warn( "Failed to lookup lifecycle participants: " + e.getMessage() );
+ }
+
+ Collection<ClassLoader> scannedRealms = new HashSet<ClassLoader>();
+
+ for ( MavenProject project : projects )
+ {
+ ClassLoader projectRealm = project.getClassRealm();
+
+ if ( projectRealm != null && scannedRealms.add( projectRealm ) )
+ {
+ Thread.currentThread().setContextClassLoader( projectRealm );
+
+ try
+ {
+ lifecycleListeners.addAll( container.lookupList( AbstractMavenLifecycleParticipant.class ) );
+ }
+ catch ( ComponentLookupException e )
+ {
+ // this is just silly, lookupList should return an empty list!
+ logger.warn( "Failed to lookup lifecycle participants: " + e.getMessage() );
+ }
+ }
+ }
+ }
+ finally
+ {
+ Thread.currentThread().setContextClassLoader( originalClassLoader );
+ }
+
+ return lifecycleListeners;
+ }
+
+ private MavenExecutionResult addExceptionToResult( MavenExecutionResult result, Throwable e )
+ {
+ if ( !result.getExceptions().contains( e ) )
+ {
+ result.addException( e );
+ }
+
+ return result;
+ }
+
+ private void validateActivatedProfiles( List<MavenProject> projects, List<String> activeProfileIds )
+ {
+ Collection<String> notActivatedProfileIds = new LinkedHashSet<String>( activeProfileIds );
+
+ for ( MavenProject project : projects )
+ {
+ for ( List<String> profileIds : project.getInjectedProfileIds().values() )
+ {
+ notActivatedProfileIds.removeAll( profileIds );
+ }
+ }
+
+ for ( String notActivatedProfileId : notActivatedProfileIds )
+ {
+ logger.warn( "The requested profile \"" + notActivatedProfileId
+ + "\" could not be activated because it does not exist." );
+ }
+ }
+
+ private Map<String, MavenProject> getProjectMap( Collection<MavenProject> projects )
+ throws DuplicateProjectException
+ {
+ Map<String, MavenProject> index = new LinkedHashMap<String, MavenProject>();
+ Map<String, List<File>> collisions = new LinkedHashMap<String, List<File>>();
+
+ for ( MavenProject project : projects )
+ {
+ String projectId = ArtifactUtils.key( project.getGroupId(), project.getArtifactId(), project.getVersion() );
+
+ MavenProject collision = index.get( projectId );
+
+ if ( collision == null )
+ {
+ index.put( projectId, project );
+ }
+ else
+ {
+ List<File> pomFiles = collisions.get( projectId );
+
+ if ( pomFiles == null )
+ {
+ pomFiles = new ArrayList<File>( Arrays.asList( collision.getFile(), project.getFile() ) );
+ collisions.put( projectId, pomFiles );
+ }
+ else
+ {
+ pomFiles.add( project.getFile() );
+ }
+ }
+ }
+
+ if ( !collisions.isEmpty() )
+ {
+ throw new DuplicateProjectException( "Two or more projects in the reactor"
+ + " have the same identifier, please make sure that <groupId>:<artifactId>:<version>"
+ + " is unique for each project: " + collisions, collisions );
+ }
+
+ return index;
+ }
+
+ private Result<? extends ProjectDependencyGraph> buildGraph( MavenSession session, MavenExecutionResult result )
+ {
+ Result<? extends ProjectDependencyGraph> graphResult = graphBuilder.build( session );
+ for ( ModelProblem problem : graphResult.getProblems() )
+ {
+ if ( problem.getSeverity() == ModelProblem.Severity.WARNING )
+ {
+ logger.warn( problem.toString() );
+ }
+ else
+ {
+ logger.error( problem.toString() );
+ }
+ }
+
+ if ( !graphResult.hasErrors() )
+ {
+ ProjectDependencyGraph projectDependencyGraph = graphResult.get();
+ session.setProjects( projectDependencyGraph.getSortedProjects() );
+ session.setAllProjects( projectDependencyGraph.getSortedProjects() );
+ session.setProjectDependencyGraph( projectDependencyGraph );
+ }
+
+ return graphResult;
+ }
+
+ @Deprecated
+ // 5 January 2014
+ protected Logger getLogger()
+ {
+ return logger;
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/DefaultProjectDependenciesResolver.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/DefaultProjectDependenciesResolver.java
new file mode 100644
index 00000000..fa8be382
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/DefaultProjectDependenciesResolver.java
@@ -0,0 +1,217 @@
+package org.apache.maven;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.ArtifactUtils;
+import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
+import org.apache.maven.artifact.resolver.ArtifactResolutionException;
+import org.apache.maven.artifact.resolver.ArtifactResolutionRequest;
+import org.apache.maven.artifact.resolver.ArtifactResolutionResult;
+import org.apache.maven.artifact.resolver.MultipleArtifactsNotFoundException;
+import org.apache.maven.artifact.resolver.ResolutionErrorHandler;
+import org.apache.maven.artifact.resolver.filter.CumulativeScopeArtifactFilter;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.project.artifact.ProjectArtifact;
+import org.apache.maven.repository.RepositorySystem;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+
+@Deprecated
+@Component( role = ProjectDependenciesResolver.class )
+public class DefaultProjectDependenciesResolver
+ implements ProjectDependenciesResolver
+{
+
+ @Requirement
+ private RepositorySystem repositorySystem;
+
+ @Requirement
+ private ResolutionErrorHandler resolutionErrorHandler;
+
+ public Set<Artifact> resolve( MavenProject project, Collection<String> scopesToResolve, MavenSession session )
+ throws ArtifactResolutionException, ArtifactNotFoundException
+ {
+ return resolve( Collections.singleton( project ), scopesToResolve, session );
+ }
+
+ public Set<Artifact> resolve( MavenProject project, Collection<String> scopesToCollect,
+ Collection<String> scopesToResolve, MavenSession session )
+ throws ArtifactResolutionException, ArtifactNotFoundException
+ {
+ Set<MavenProject> mavenProjects = Collections.singleton( project );
+ return resolveImpl( mavenProjects, scopesToCollect, scopesToResolve, session,
+ getIgnorableArtifacts( mavenProjects ) );
+ }
+
+ public Set<Artifact> resolve( Collection<? extends MavenProject> projects, Collection<String> scopesToResolve,
+ MavenSession session )
+ throws ArtifactResolutionException, ArtifactNotFoundException
+ {
+ return resolveImpl( projects, null, scopesToResolve, session, getIgnorableArtifacts( projects ) );
+ }
+
+ public Set<Artifact> resolve( MavenProject project, Collection<String> scopesToCollect,
+ Collection<String> scopesToResolve, MavenSession session,
+ Set<Artifact> ignoreableArtifacts )
+ throws ArtifactResolutionException, ArtifactNotFoundException
+ {
+ return resolveImpl( Collections.singleton( project ), scopesToCollect, scopesToResolve, session,
+ getIgnorableArtifacts( ignoreableArtifacts ) );
+ }
+
+
+ private Set<Artifact> resolveImpl( Collection<? extends MavenProject> projects, Collection<String> scopesToCollect,
+ Collection<String> scopesToResolve, MavenSession session,
+ Set<String> projectIds )
+ throws ArtifactResolutionException, ArtifactNotFoundException
+ {
+ Set<Artifact> resolved = new LinkedHashSet<Artifact>();
+
+ if ( projects == null || projects.isEmpty() )
+ {
+ return resolved;
+ }
+
+ if ( ( scopesToCollect == null || scopesToCollect.isEmpty() )
+ && ( scopesToResolve == null || scopesToResolve.isEmpty() ) )
+ {
+ return resolved;
+ }
+
+ /*
+
+ Logic for transitive global exclusions
+
+ List<String> exclusions = new ArrayList<String>();
+
+ for ( Dependency d : project.getDependencies() )
+ {
+ if ( d.getExclusions() != null )
+ {
+ for ( Exclusion e : d.getExclusions() )
+ {
+ exclusions.add( e.getGroupId() + ":" + e.getArtifactId() );
+ }
+ }
+ }
+
+ ArtifactFilter scopeFilter = new ScopeArtifactFilter( scope );
+
+ ArtifactFilter filter;
+
+ if ( ! exclusions.isEmpty() )
+ {
+ filter = new AndArtifactFilter( Arrays.asList( new ArtifactFilter[]{
+ new ExcludesArtifactFilter( exclusions ), scopeFilter } ) );
+ }
+ else
+ {
+ filter = scopeFilter;
+ }
+ */
+
+ CumulativeScopeArtifactFilter resolutionScopeFilter = new CumulativeScopeArtifactFilter( scopesToResolve );
+
+ CumulativeScopeArtifactFilter collectionScopeFilter = new CumulativeScopeArtifactFilter( scopesToCollect );
+ collectionScopeFilter = new CumulativeScopeArtifactFilter( collectionScopeFilter, resolutionScopeFilter );
+
+ ArtifactResolutionRequest request =
+ new ArtifactResolutionRequest().setResolveRoot( false ).setResolveTransitively( true ).setCollectionFilter(
+ collectionScopeFilter ).setResolutionFilter( resolutionScopeFilter ).setLocalRepository(
+ session.getLocalRepository() ).setOffline( session.isOffline() ).setForceUpdate(
+ session.getRequest().isUpdateSnapshots() );
+ request.setServers( session.getRequest().getServers() );
+ request.setMirrors( session.getRequest().getMirrors() );
+ request.setProxies( session.getRequest().getProxies() );
+
+ for ( MavenProject project : projects )
+ {
+ request.setArtifact( new ProjectArtifact( project ) );
+ request.setArtifactDependencies( project.getDependencyArtifacts() );
+ request.setManagedVersionMap( project.getManagedVersionMap() );
+ request.setRemoteRepositories( project.getRemoteArtifactRepositories() );
+
+ ArtifactResolutionResult result = repositorySystem.resolve( request );
+
+ try
+ {
+ resolutionErrorHandler.throwErrors( request, result );
+ }
+ catch ( MultipleArtifactsNotFoundException e )
+ {
+
+ Collection<Artifact> missing = new HashSet<Artifact>( e.getMissingArtifacts() );
+
+ for ( Iterator<Artifact> it = missing.iterator(); it.hasNext(); )
+ {
+ String key = ArtifactUtils.key( it.next() );
+ if ( projectIds.contains( key ) )
+ {
+ it.remove();
+ }
+ }
+
+ if ( !missing.isEmpty() )
+ {
+ throw e;
+ }
+ }
+
+ resolved.addAll( result.getArtifacts() );
+ }
+
+ return resolved;
+ }
+
+
+ private Set<String> getIgnorableArtifacts( Collection<? extends MavenProject> projects )
+ {
+ Set<String> projectIds = new HashSet<String>( projects.size() * 2 );
+
+ for ( MavenProject p : projects )
+ {
+ String key = ArtifactUtils.key( p.getGroupId(), p.getArtifactId(), p.getVersion() );
+ projectIds.add( key );
+ }
+ return projectIds;
+ }
+
+ private Set<String> getIgnorableArtifacts( Iterable<Artifact> artifactIterable )
+ {
+ Set<String> projectIds = new HashSet<String>();
+
+ for ( Artifact artifact : artifactIterable )
+ {
+ String key = ArtifactUtils.key( artifact );
+ projectIds.add( key );
+ }
+ return projectIds;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/DuplicateProjectException.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/DuplicateProjectException.java
new file mode 100644
index 00000000..b1398729
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/DuplicateProjectException.java
@@ -0,0 +1,61 @@
+package org.apache.maven;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Signals a collision of two or more projects with the same g:a:v during a reactor build.
+ *
+ * @author Benjamin Bentmann
+ */
+public class DuplicateProjectException
+ extends MavenExecutionException
+{
+
+ private Map<String, List<File>> collisions;
+
+ /**
+ * Creates a new exception with specified details.
+ *
+ * @param message The message text, may be {@code null}.
+ * @param collisions The POM files of the projects that collided, indexed by their g:a:v, may be {@code null}.
+ */
+ public DuplicateProjectException( String message, Map<String, List<File>> collisions )
+ {
+ super( message, (File) null );
+
+ this.collisions = ( collisions != null ) ? collisions : new LinkedHashMap<String, List<File>>();
+ }
+
+ /**
+ * Gets the POM files of the projects that collided.
+ *
+ * @return The POM files of the projects that collided, indexed by their g:a:v, never {@code null}.
+ */
+ public Map<String, List<File>> getCollisions()
+ {
+ return collisions;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/InternalErrorException.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/InternalErrorException.java
new file mode 100644
index 00000000..afe92c1b
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/InternalErrorException.java
@@ -0,0 +1,36 @@
+package org.apache.maven;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Signals an internal error in Maven itself, e.g. a programming bug.
+ *
+ * @author Benjamin Bentmann
+ */
+public class InternalErrorException
+ extends MavenExecutionException
+{
+
+ public InternalErrorException( String message, Throwable cause )
+ {
+ super( message, cause );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/Maven.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/Maven.java
new file mode 100644
index 00000000..85638476
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/Maven.java
@@ -0,0 +1,34 @@
+package org.apache.maven;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.execution.MavenExecutionRequest;
+import org.apache.maven.execution.MavenExecutionResult;
+
+/**
+ * @author Jason van Zyl
+ */
+public interface Maven
+{
+ @Deprecated
+ String POMv4 = "pom.xml";
+
+ MavenExecutionResult execute( MavenExecutionRequest request );
+} \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/MavenExecutionException.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/MavenExecutionException.java
new file mode 100644
index 00000000..5708e525
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/MavenExecutionException.java
@@ -0,0 +1,55 @@
+package org.apache.maven;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+
+import org.apache.maven.project.ProjectBuildingException;
+
+/**
+ * @author Jason van Zyl
+ */
+public class MavenExecutionException
+ extends Exception
+{
+ private File pomFile;
+
+ public MavenExecutionException( String message, File pomFile )
+ {
+ super( message );
+ this.pomFile = pomFile;
+ }
+
+ public MavenExecutionException( String message, File pomFile, ProjectBuildingException cause )
+ {
+ super( message, cause );
+ this.pomFile = pomFile;
+ }
+
+ public MavenExecutionException( String message, Throwable cause )
+ {
+ super( message, cause );
+ }
+
+ public File getPomFile()
+ {
+ return pomFile;
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/MissingModuleException.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/MissingModuleException.java
new file mode 100644
index 00000000..c920a6ea
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/MissingModuleException.java
@@ -0,0 +1,48 @@
+package org.apache.maven;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+
+public class MissingModuleException
+ extends MavenExecutionException
+{
+
+ private File moduleFile;
+ private final String moduleName;
+
+ public MissingModuleException( String moduleName, File moduleFile, File pomFile )
+ {
+ super( "The module: " + moduleName + " cannot be found in file: " + moduleFile, pomFile );
+ this.moduleName = moduleName;
+ this.moduleFile = moduleFile;
+ }
+
+ public File getModuleFile()
+ {
+ return moduleFile;
+ }
+
+ public String getModuleName()
+ {
+ return moduleName;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/ProjectBuildFailureException.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/ProjectBuildFailureException.java
new file mode 100644
index 00000000..66ed3a08
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/ProjectBuildFailureException.java
@@ -0,0 +1,55 @@
+package org.apache.maven;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.plugin.MojoFailureException;
+
+/**
+ * Exception which occurs when a normal (i.e. non-aggregator) mojo fails to
+ * execute. In this case, the mojo failed while executing against a particular
+ * project instance, so we can wrap the {@link MojoFailureException} with context
+ * information including projectId that caused the failure.
+ *
+ * @author jdcasey
+ *
+ */
+public class ProjectBuildFailureException
+ extends BuildFailureException
+{
+
+ private final String projectId;
+
+ public ProjectBuildFailureException( String projectId, MojoFailureException cause )
+ {
+ super( "Build for project: " + projectId + " failed during execution of mojo.", cause );
+
+ this.projectId = projectId;
+ }
+
+ public MojoFailureException getMojoFailureException()
+ {
+ return (MojoFailureException) getCause();
+ }
+
+ public String getProjectId()
+ {
+ return projectId;
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/ProjectCycleException.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/ProjectCycleException.java
new file mode 100644
index 00000000..ecd8ecac
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/ProjectCycleException.java
@@ -0,0 +1,39 @@
+package org.apache.maven;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.codehaus.plexus.util.dag.CycleDetectedException;
+
+/**
+ * @author jdcasey
+ */
+public class ProjectCycleException
+ extends BuildFailureException
+{
+ public ProjectCycleException( String message )
+ {
+ super( message );
+ }
+
+ public ProjectCycleException( String message, CycleDetectedException cause )
+ {
+ super( message, cause );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/ProjectDependenciesResolver.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/ProjectDependenciesResolver.java
new file mode 100644
index 00000000..01e62278
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/ProjectDependenciesResolver.java
@@ -0,0 +1,95 @@
+package org.apache.maven;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Collection;
+import java.util.Set;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
+import org.apache.maven.artifact.resolver.ArtifactResolutionException;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.project.MavenProject;
+
+@Deprecated
+/**
+ * @deprecated As of 3.2.2, and there is no direct replacement. This is an internal class which was not marked as such,
+ * but should have been.
+ * @author jvanzyl
+ *
+ */
+public interface ProjectDependenciesResolver
+{
+
+ /**
+ * Resolves the transitive dependencies of the specified project.
+ *
+ * @param project The project whose dependencies should be resolved, must not be {@code null}.
+ * @param scopesToResolve The dependency scopes that should be resolved, may be {@code null}.
+ * @param session The current build session, must not be {@code null}.
+ * @return The transitive dependencies of the specified project that match the requested scopes, never {@code null}.
+ */
+ Set<Artifact> resolve( MavenProject project, Collection<String> scopesToResolve, MavenSession session )
+ throws ArtifactResolutionException, ArtifactNotFoundException;
+
+ /**
+ * Resolves the transitive dependencies of the specified project.
+ *
+ * @param project The project whose dependencies should be resolved, must not be {@code null}.
+ * @param scopesToCollect The dependency scopes that should be collected, may be {@code null}.
+ * @param scopesToResolve The dependency scopes that should be collected and also resolved, may be {@code null}.
+ * @param session The current build session, must not be {@code null}.
+ * @return The transitive dependencies of the specified project that match the requested scopes, never {@code null}.
+ */
+ Set<Artifact> resolve( MavenProject project, Collection<String> scopesToCollect,
+ Collection<String> scopesToResolve, MavenSession session )
+ throws ArtifactResolutionException, ArtifactNotFoundException;
+
+ /**
+ * Resolves the transitive dependencies of the specified project.
+ *
+ * @param project The project whose dependencies should be resolved, must not be {@code null}.
+ * @param scopesToCollect The dependency scopes that should be collected, may be {@code null}.
+ * @param scopesToResolve The dependency scopes that should be collected and also resolved, may be {@code null}.
+ * @param session The current build session, must not be {@code null}.
+ * @param ignoreableArtifacts Artifacts that need not be resolved
+ * @return The transitive dependencies of the specified project that match the requested scopes, never {@code null}.
+ */
+ Set<Artifact> resolve( MavenProject project, Collection<String> scopesToCollect,
+ Collection<String> scopesToResolve, MavenSession session, Set<Artifact> ignoreableArtifacts )
+ throws ArtifactResolutionException, ArtifactNotFoundException;
+
+ /**
+ * Resolves the transitive dependencies of the specified projects. Note that dependencies which can't be resolved
+ * from any repository but are present among the set of specified projects will not cause an exception. Instead,
+ * those unresolved artifacts will be returned in the result set, allowing the caller to take special care of
+ * artifacts that haven't been build yet.
+ *
+ * @param projects The projects whose dependencies should be resolved, may be {@code null}.
+ * @param scopes The dependency scopes that should be resolved, may be {@code null}.
+ * @param session The current build session, must not be {@code null}.
+ * @return The transitive dependencies of the specified projects that match the requested scopes, never
+ * {@code null}.
+ */
+ Set<Artifact> resolve( Collection<? extends MavenProject> projects, Collection<String> scopes,
+ MavenSession session )
+ throws ArtifactResolutionException, ArtifactNotFoundException;
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/ReactorReader.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/ReactorReader.java
new file mode 100644
index 00000000..252bdd09
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/ReactorReader.java
@@ -0,0 +1,255 @@
+package org.apache.maven;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import org.apache.maven.artifact.ArtifactUtils;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.model.Model;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.repository.internal.MavenWorkspaceReader;
+import org.eclipse.aether.artifact.Artifact;
+import org.eclipse.aether.repository.WorkspaceRepository;
+import org.eclipse.aether.util.artifact.ArtifactIdUtils;
+
+/**
+ * An implementation of a workspace reader that knows how to search the Maven reactor for artifacts, either
+ * as packaged jar if it has been built, or only compile output directory if packaging hasn't happened yet.
+ *
+ * @author Jason van Zyl
+ */
+@Named( ReactorReader.HINT )
+@SessionScoped
+class ReactorReader
+ implements MavenWorkspaceReader
+{
+ public static final String HINT = "reactor";
+
+ private static final Collection<String> COMPILE_PHASE_TYPES = Arrays.asList( "jar", "ejb-client" );
+
+ private Map<String, MavenProject> projectsByGAV;
+
+ private Map<String, List<MavenProject>> projectsByGA;
+
+ private WorkspaceRepository repository;
+
+ @Inject
+ public ReactorReader( MavenSession session )
+ {
+ projectsByGAV = session.getProjectMap();
+
+ projectsByGA = new HashMap<String, List<MavenProject>>( projectsByGAV.size() * 2 );
+ for ( MavenProject project : projectsByGAV.values() )
+ {
+ String key = ArtifactUtils.versionlessKey( project.getGroupId(), project.getArtifactId() );
+
+ List<MavenProject> projects = projectsByGA.get( key );
+
+ if ( projects == null )
+ {
+ projects = new ArrayList<MavenProject>( 1 );
+ projectsByGA.put( key, projects );
+ }
+
+ projects.add( project );
+ }
+
+ repository = new WorkspaceRepository( "reactor", new HashSet<String>( projectsByGAV.keySet() ) );
+ }
+
+ //
+ // Public API
+ //
+
+ public WorkspaceRepository getRepository()
+ {
+ return repository;
+ }
+
+ public File findArtifact( Artifact artifact )
+ {
+ String projectKey = ArtifactUtils.key( artifact.getGroupId(), artifact.getArtifactId(), artifact.getVersion() );
+
+ MavenProject project = projectsByGAV.get( projectKey );
+
+ if ( project != null )
+ {
+ File file = find( project, artifact );
+ if ( file == null && project != project.getExecutionProject() )
+ {
+ file = find( project.getExecutionProject(), artifact );
+ }
+ return file;
+ }
+
+ return null;
+ }
+
+ public List<String> findVersions( Artifact artifact )
+ {
+ String key = ArtifactUtils.versionlessKey( artifact.getGroupId(), artifact.getArtifactId() );
+
+ List<MavenProject> projects = projectsByGA.get( key );
+ if ( projects == null || projects.isEmpty() )
+ {
+ return Collections.emptyList();
+ }
+
+ List<String> versions = new ArrayList<String>();
+
+ for ( MavenProject project : projects )
+ {
+ if ( find( project, artifact ) != null )
+ {
+ versions.add( project.getVersion() );
+ }
+ }
+
+ return Collections.unmodifiableList( versions );
+ }
+
+ @Override
+ public Model findModel( Artifact artifact )
+ {
+ String projectKey = ArtifactUtils.key( artifact.getGroupId(), artifact.getArtifactId(), artifact.getVersion() );
+ MavenProject project = projectsByGAV.get( projectKey );
+ return project == null ? null : project.getModel();
+ }
+
+ //
+ // Implementation
+ //
+
+ private File find( MavenProject project, Artifact artifact )
+ {
+ if ( "pom".equals( artifact.getExtension() ) )
+ {
+ return project.getFile();
+ }
+
+ Artifact projectArtifact = findMatchingArtifact( project, artifact );
+
+ if ( hasArtifactFileFromPackagePhase( projectArtifact ) )
+ {
+ return projectArtifact.getFile();
+ }
+ else if ( !hasBeenPackaged( project ) )
+ {
+ // fallback to loose class files only if artifacts haven't been packaged yet
+ // and only for plain old jars. Not war files, not ear files, not anything else.
+
+ if ( isTestArtifact( artifact ) )
+ {
+ if ( project.hasLifecyclePhase( "test-compile" ) )
+ {
+ return new File( project.getBuild().getTestOutputDirectory() );
+ }
+ }
+ else
+ {
+ String type = artifact.getProperty( "type", "" );
+ if ( project.hasLifecyclePhase( "compile" ) && COMPILE_PHASE_TYPES.contains( type ) )
+ {
+ return new File( project.getBuild().getOutputDirectory() );
+ }
+ }
+ }
+
+ // The fall-through indicates that the artifact cannot be found;
+ // for instance if package produced nothing or classifier problems.
+ return null;
+ }
+
+ private boolean hasArtifactFileFromPackagePhase( Artifact projectArtifact )
+ {
+ return projectArtifact != null && projectArtifact.getFile() != null && projectArtifact.getFile().exists();
+ }
+
+ private boolean hasBeenPackaged( MavenProject project )
+ {
+ return project.hasLifecyclePhase( "package" ) || project.hasLifecyclePhase( "install" )
+ || project.hasLifecyclePhase( "deploy" );
+ }
+
+ /**
+ * Tries to resolve the specified artifact from the artifacts of the given project.
+ *
+ * @param project The project to try to resolve the artifact from, must not be <code>null</code>.
+ * @param requestedArtifact The artifact to resolve, must not be <code>null</code>.
+ * @return The matching artifact from the project or <code>null</code> if not found. Note that this
+ */
+ private Artifact findMatchingArtifact( MavenProject project, Artifact requestedArtifact )
+ {
+ String requestedRepositoryConflictId = ArtifactIdUtils.toVersionlessId( requestedArtifact );
+
+ Artifact mainArtifact = RepositoryUtils.toArtifact( project.getArtifact() );
+ if ( requestedRepositoryConflictId.equals( ArtifactIdUtils.toVersionlessId( mainArtifact ) ) )
+ {
+ return mainArtifact;
+ }
+
+ for ( Artifact attachedArtifact : RepositoryUtils.toArtifacts( project.getAttachedArtifacts() ) )
+ {
+ if ( attachedArtifactComparison( requestedArtifact, attachedArtifact ) )
+ {
+ return attachedArtifact;
+ }
+ }
+
+ return null;
+ }
+
+ private boolean attachedArtifactComparison( Artifact requested, Artifact attached )
+ {
+ //
+ // We are taking as much as we can from the DefaultArtifact.equals(). The requested artifact has no file so
+ // we want to remove that from the comparison.
+ //
+ return requested.getArtifactId().equals( attached.getArtifactId() )
+ && requested.getGroupId().equals( attached.getGroupId() )
+ && requested.getVersion().equals( attached.getVersion() )
+ && requested.getExtension().equals( attached.getExtension() )
+ && requested.getClassifier().equals( attached.getClassifier() );
+ }
+
+ /**
+ * Determines whether the specified artifact refers to test classes.
+ *
+ * @param artifact The artifact to check, must not be {@code null}.
+ * @return {@code true} if the artifact refers to test classes, {@code false} otherwise.
+ */
+ private static boolean isTestArtifact( Artifact artifact )
+ {
+ return ( "test-jar".equals( artifact.getProperty( "type", "" ) ) )
+ || ( "jar".equals( artifact.getExtension() ) && "tests".equals( artifact.getClassifier() ) );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/RepositoryUtils.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/RepositoryUtils.java
new file mode 100644
index 00000000..d7fd88e2
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/RepositoryUtils.java
@@ -0,0 +1,362 @@
+package org.apache.maven;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.maven.artifact.handler.ArtifactHandler;
+import org.apache.maven.artifact.handler.DefaultArtifactHandler;
+import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy;
+import org.eclipse.aether.artifact.Artifact;
+import org.eclipse.aether.artifact.ArtifactProperties;
+import org.eclipse.aether.artifact.ArtifactType;
+import org.eclipse.aether.artifact.ArtifactTypeRegistry;
+import org.eclipse.aether.artifact.DefaultArtifact;
+import org.eclipse.aether.artifact.DefaultArtifactType;
+import org.eclipse.aether.graph.Dependency;
+import org.eclipse.aether.graph.DependencyFilter;
+import org.eclipse.aether.graph.DependencyNode;
+import org.eclipse.aether.graph.Exclusion;
+import org.eclipse.aether.repository.Authentication;
+import org.eclipse.aether.repository.Proxy;
+import org.eclipse.aether.repository.RemoteRepository;
+import org.eclipse.aether.repository.RepositoryPolicy;
+import org.eclipse.aether.util.repository.AuthenticationBuilder;
+
+/**
+ * <strong>Warning:</strong> This is an internal utility class that is only public for technical reasons, it is not part
+ * of the public API. In particular, this class can be changed or deleted without prior notice.
+ *
+ * @author Benjamin Bentmann
+ */
+public class RepositoryUtils
+{
+
+ private static String nullify( String string )
+ {
+ return ( string == null || string.length() <= 0 ) ? null : string;
+ }
+
+ private static org.apache.maven.artifact.Artifact toArtifact( Dependency dependency )
+ {
+ if ( dependency == null )
+ {
+ return null;
+ }
+
+ org.apache.maven.artifact.Artifact result = toArtifact( dependency.getArtifact() );
+ result.setScope( dependency.getScope() );
+ result.setOptional( dependency.isOptional() );
+
+ return result;
+ }
+
+ public static org.apache.maven.artifact.Artifact toArtifact( Artifact artifact )
+ {
+ if ( artifact == null )
+ {
+ return null;
+ }
+
+ ArtifactHandler handler = newHandler( artifact );
+
+ /*
+ * NOTE: From Artifact.hasClassifier(), an empty string and a null both denote "no classifier". However, some
+ * plugins only check for null, so be sure to nullify an empty classifier.
+ */
+ org.apache.maven.artifact.Artifact result =
+ new org.apache.maven.artifact.DefaultArtifact( artifact.getGroupId(), artifact.getArtifactId(),
+ artifact.getVersion(), null,
+ artifact.getProperty( ArtifactProperties.TYPE,
+ artifact.getExtension() ),
+ nullify( artifact.getClassifier() ), handler );
+
+ result.setFile( artifact.getFile() );
+ result.setResolved( artifact.getFile() != null );
+
+ List<String> trail = new ArrayList<String>( 1 );
+ trail.add( result.getId() );
+ result.setDependencyTrail( trail );
+
+ return result;
+ }
+
+ public static void toArtifacts( Collection<org.apache.maven.artifact.Artifact> artifacts,
+ Collection<? extends DependencyNode> nodes, List<String> trail,
+ DependencyFilter filter )
+ {
+ for ( DependencyNode node : nodes )
+ {
+ org.apache.maven.artifact.Artifact artifact = toArtifact( node.getDependency() );
+
+ List<String> nodeTrail = new ArrayList<String>( trail.size() + 1 );
+ nodeTrail.addAll( trail );
+ nodeTrail.add( artifact.getId() );
+
+ if ( filter == null || filter.accept( node, Collections.<DependencyNode>emptyList() ) )
+ {
+ artifact.setDependencyTrail( nodeTrail );
+ artifacts.add( artifact );
+ }
+
+ toArtifacts( artifacts, node.getChildren(), nodeTrail, filter );
+ }
+ }
+
+ public static Artifact toArtifact( org.apache.maven.artifact.Artifact artifact )
+ {
+ if ( artifact == null )
+ {
+ return null;
+ }
+
+ String version = artifact.getVersion();
+ if ( version == null && artifact.getVersionRange() != null )
+ {
+ version = artifact.getVersionRange().toString();
+ }
+
+ Map<String, String> props = null;
+ if ( org.apache.maven.artifact.Artifact.SCOPE_SYSTEM.equals( artifact.getScope() ) )
+ {
+ String localPath = ( artifact.getFile() != null ) ? artifact.getFile().getPath() : "";
+ props = Collections.singletonMap( ArtifactProperties.LOCAL_PATH, localPath );
+ }
+
+ Artifact result =
+ new DefaultArtifact( artifact.getGroupId(), artifact.getArtifactId(), artifact.getClassifier(),
+ artifact.getArtifactHandler().getExtension(), version, props,
+ newArtifactType( artifact.getType(), artifact.getArtifactHandler() ) );
+ result = result.setFile( artifact.getFile() );
+
+ return result;
+ }
+
+ public static Dependency toDependency( org.apache.maven.artifact.Artifact artifact,
+ Collection<org.apache.maven.model.Exclusion> exclusions )
+ {
+ if ( artifact == null )
+ {
+ return null;
+ }
+
+ Artifact result = toArtifact( artifact );
+
+ List<Exclusion> excl = null;
+ if ( exclusions != null )
+ {
+ excl = new ArrayList<Exclusion>( exclusions.size() );
+ for ( org.apache.maven.model.Exclusion exclusion : exclusions )
+ {
+ excl.add( toExclusion( exclusion ) );
+ }
+ }
+
+ return new Dependency( result, artifact.getScope(), artifact.isOptional(), excl );
+ }
+
+ public static List<RemoteRepository> toRepos( List<ArtifactRepository> repos )
+ {
+ if ( repos == null )
+ {
+ return null;
+ }
+
+ List<RemoteRepository> results = new ArrayList<RemoteRepository>( repos.size() );
+ for ( ArtifactRepository repo : repos )
+ {
+ results.add( toRepo( repo ) );
+ }
+ return results;
+ }
+
+ public static RemoteRepository toRepo( ArtifactRepository repo )
+ {
+ RemoteRepository result = null;
+ if ( repo != null )
+ {
+ RemoteRepository.Builder builder =
+ new RemoteRepository.Builder( repo.getId(), getLayout( repo ), repo.getUrl() );
+ builder.setSnapshotPolicy( toPolicy( repo.getSnapshots() ) );
+ builder.setReleasePolicy( toPolicy( repo.getReleases() ) );
+ builder.setAuthentication( toAuthentication( repo.getAuthentication() ) );
+ builder.setProxy( toProxy( repo.getProxy() ) );
+ builder.setMirroredRepositories( toRepos( repo.getMirroredRepositories() ) );
+ result = builder.build();
+ }
+ return result;
+ }
+
+ public static String getLayout( ArtifactRepository repo )
+ {
+ try
+ {
+ return repo.getLayout().getId();
+ }
+ catch ( LinkageError e )
+ {
+ /*
+ * NOTE: getId() was added in 3.x and is as such not implemented by plugins compiled against 2.x APIs.
+ */
+ String className = repo.getLayout().getClass().getSimpleName();
+ if ( className.endsWith( "RepositoryLayout" ) )
+ {
+ String layout = className.substring( 0, className.length() - "RepositoryLayout".length() );
+ if ( layout.length() > 0 )
+ {
+ layout = Character.toLowerCase( layout.charAt( 0 ) ) + layout.substring( 1 );
+ return layout;
+ }
+ }
+ return "";
+ }
+ }
+
+ private static RepositoryPolicy toPolicy( ArtifactRepositoryPolicy policy )
+ {
+ RepositoryPolicy result = null;
+ if ( policy != null )
+ {
+ result = new RepositoryPolicy( policy.isEnabled(), policy.getUpdatePolicy(), policy.getChecksumPolicy() );
+ }
+ return result;
+ }
+
+ private static Authentication toAuthentication( org.apache.maven.artifact.repository.Authentication auth )
+ {
+ Authentication result = null;
+ if ( auth != null )
+ {
+ AuthenticationBuilder authBuilder = new AuthenticationBuilder();
+ authBuilder.addUsername( auth.getUsername() ).addPassword( auth.getPassword() );
+ authBuilder.addPrivateKey( auth.getPrivateKey(), auth.getPassphrase() );
+ result = authBuilder.build();
+ }
+ return result;
+ }
+
+ private static Proxy toProxy( org.apache.maven.repository.Proxy proxy )
+ {
+ Proxy result = null;
+ if ( proxy != null )
+ {
+ AuthenticationBuilder authBuilder = new AuthenticationBuilder();
+ authBuilder.addUsername( proxy.getUserName() ).addPassword( proxy.getPassword() );
+ result = new Proxy( proxy.getProtocol(), proxy.getHost(), proxy.getPort(), authBuilder.build() );
+ }
+ return result;
+ }
+
+ public static ArtifactHandler newHandler( Artifact artifact )
+ {
+ String type = artifact.getProperty( ArtifactProperties.TYPE, artifact.getExtension() );
+ DefaultArtifactHandler handler = new DefaultArtifactHandler( type );
+ handler.setExtension( artifact.getExtension() );
+ handler.setLanguage( artifact.getProperty( ArtifactProperties.LANGUAGE, null ) );
+ String addedToClasspath = artifact.getProperty( ArtifactProperties.CONSTITUTES_BUILD_PATH, "" );
+ handler.setAddedToClasspath( Boolean.parseBoolean( addedToClasspath ) );
+ String includesDependencies = artifact.getProperty( ArtifactProperties.INCLUDES_DEPENDENCIES, "" );
+ handler.setIncludesDependencies( Boolean.parseBoolean( includesDependencies ) );
+ return handler;
+ }
+
+ public static ArtifactType newArtifactType( String id, ArtifactHandler handler )
+ {
+ return new DefaultArtifactType( id, handler.getExtension(), handler.getClassifier(), handler.getLanguage(),
+ handler.isAddedToClasspath(), handler.isIncludesDependencies() );
+ }
+
+ public static Dependency toDependency( org.apache.maven.model.Dependency dependency,
+ ArtifactTypeRegistry stereotypes )
+ {
+ ArtifactType stereotype = stereotypes.get( dependency.getType() );
+ if ( stereotype == null )
+ {
+ stereotype = new DefaultArtifactType( dependency.getType() );
+ }
+
+ boolean system = dependency.getSystemPath() != null && dependency.getSystemPath().length() > 0;
+
+ Map<String, String> props = null;
+ if ( system )
+ {
+ props = Collections.singletonMap( ArtifactProperties.LOCAL_PATH, dependency.getSystemPath() );
+ }
+
+ Artifact artifact =
+ new DefaultArtifact( dependency.getGroupId(), dependency.getArtifactId(), dependency.getClassifier(), null,
+ dependency.getVersion(), props, stereotype );
+
+ List<Exclusion> exclusions = new ArrayList<Exclusion>( dependency.getExclusions().size() );
+ for ( org.apache.maven.model.Exclusion exclusion : dependency.getExclusions() )
+ {
+ exclusions.add( toExclusion( exclusion ) );
+ }
+
+ Dependency result = new Dependency( artifact, dependency.getScope(), dependency.isOptional(), exclusions );
+
+ return result;
+ }
+
+ private static Exclusion toExclusion( org.apache.maven.model.Exclusion exclusion )
+ {
+ return new Exclusion( exclusion.getGroupId(), exclusion.getArtifactId(), "*", "*" );
+ }
+
+ public static ArtifactTypeRegistry newArtifactTypeRegistry( ArtifactHandlerManager handlerManager )
+ {
+ return new MavenArtifactTypeRegistry( handlerManager );
+ }
+
+ static class MavenArtifactTypeRegistry
+ implements ArtifactTypeRegistry
+ {
+
+ private final ArtifactHandlerManager handlerManager;
+
+ public MavenArtifactTypeRegistry( ArtifactHandlerManager handlerManager )
+ {
+ this.handlerManager = handlerManager;
+ }
+
+ public ArtifactType get( String stereotypeId )
+ {
+ ArtifactHandler handler = handlerManager.getArtifactHandler( stereotypeId );
+ return newArtifactType( stereotypeId, handler );
+ }
+
+ }
+
+ public static Collection<Artifact> toArtifacts( Collection<org.apache.maven.artifact.Artifact> artifactsToConvert )
+ {
+ List<Artifact> artifacts = new ArrayList<Artifact>();
+ for ( org.apache.maven.artifact.Artifact a : artifactsToConvert )
+ {
+ artifacts.add( toArtifact( a ) );
+ }
+ return artifacts;
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/SessionScoped.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/SessionScoped.java
new file mode 100644
index 00000000..63b1eb77
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/SessionScoped.java
@@ -0,0 +1,42 @@
+package org.apache.maven;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import com.google.inject.ScopeAnnotation;
+
+/**
+ * Indicates that annotated component should be instantiated before session starts and discarded after session execution
+ * completes.
+ *
+ * @author Jason van Zyl
+ * @since 3.2.0
+ */
+@Target( { TYPE } )
+@Retention( RUNTIME )
+@ScopeAnnotation
+public @interface SessionScoped
+{
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/DependencyResolutionRequiredException.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/DependencyResolutionRequiredException.java
new file mode 100644
index 00000000..b54ba070
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/DependencyResolutionRequiredException.java
@@ -0,0 +1,35 @@
+package org.apache.maven.artifact;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Exception that occurs when an artifact file is used, but has not been resolved.
+ *
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ * @todo it may be better for artifact.getFile() to throw it - perhaps it is a runtime exception?
+ */
+public class DependencyResolutionRequiredException
+ extends Exception
+{
+ public DependencyResolutionRequiredException( Artifact artifact )
+ {
+ super( "Attempted to access the artifact " + artifact + "; which has not yet been resolved" );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/InvalidRepositoryException.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/InvalidRepositoryException.java
new file mode 100644
index 00000000..62991f11
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/InvalidRepositoryException.java
@@ -0,0 +1,65 @@
+package org.apache.maven.artifact;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.net.MalformedURLException;
+
+import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
+
+/**
+ * Error constructing an artifact repository.
+ *
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ */
+public class InvalidRepositoryException
+ extends Exception
+{
+ private final String repositoryId;
+
+ public InvalidRepositoryException( String message, String repositoryId, MalformedURLException cause )
+ {
+ super( message, cause );
+ this.repositoryId = repositoryId;
+ }
+
+ protected InvalidRepositoryException( String message, String repositoryId, ComponentLookupException cause )
+ {
+ super( message, cause );
+ this.repositoryId = repositoryId;
+ }
+
+ @Deprecated
+ public InvalidRepositoryException( String message, Throwable t )
+ {
+ super( message, t );
+ this.repositoryId = null;
+ }
+
+ public InvalidRepositoryException( String message, String repositoryId )
+ {
+ super( message );
+ this.repositoryId = repositoryId;
+ }
+
+ public String getRepositoryId()
+ {
+ return repositoryId;
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/factory/ArtifactFactory.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/factory/ArtifactFactory.java
new file mode 100644
index 00000000..a16f64f6
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/factory/ArtifactFactory.java
@@ -0,0 +1,59 @@
+package org.apache.maven.artifact.factory;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.versioning.VersionRange;
+
+@Deprecated
+public interface ArtifactFactory
+{
+ @Deprecated
+ String ROLE = ArtifactFactory.class.getName();
+
+ Artifact createArtifact( String groupId, String artifactId, String version, String scope, String type );
+
+ Artifact createArtifactWithClassifier( String groupId, String artifactId, String version, String type,
+ String classifier );
+
+ Artifact createDependencyArtifact( String groupId, String artifactId, VersionRange versionRange, String type,
+ String classifier, String scope );
+
+ Artifact createDependencyArtifact( String groupId, String artifactId, VersionRange versionRange, String type,
+ String classifier, String scope, boolean optional );
+
+ Artifact createDependencyArtifact( String groupId, String artifactId, VersionRange versionRange, String type,
+ String classifier, String scope, String inheritedScope );
+
+ Artifact createDependencyArtifact( String groupId, String artifactId, VersionRange versionRange, String type,
+ String classifier, String scope, String inheritedScope, boolean optional );
+
+ Artifact createBuildArtifact( String groupId, String artifactId, String version, String packaging );
+
+ Artifact createProjectArtifact( String groupId, String artifactId, String version );
+
+ Artifact createParentArtifact( String groupId, String artifactId, String version );
+
+ Artifact createPluginArtifact( String groupId, String artifactId, VersionRange versionRange );
+
+ Artifact createProjectArtifact( String groupId, String artifactId, String version, String scope );
+
+ Artifact createExtensionArtifact( String groupId, String artifactId, VersionRange versionRange );
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/factory/DefaultArtifactFactory.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/factory/DefaultArtifactFactory.java
new file mode 100644
index 00000000..dfcac019
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/factory/DefaultArtifactFactory.java
@@ -0,0 +1,160 @@
+package org.apache.maven.artifact.factory;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.DefaultArtifact;
+import org.apache.maven.artifact.handler.ArtifactHandler;
+import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager;
+import org.apache.maven.artifact.versioning.VersionRange;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+
+@Component( role = ArtifactFactory.class )
+public class DefaultArtifactFactory
+ implements ArtifactFactory
+{
+ @Requirement
+ private ArtifactHandlerManager artifactHandlerManager;
+
+ public Artifact createArtifact( String groupId, String artifactId, String version, String scope, String type )
+ {
+ return createArtifact( groupId, artifactId, version, scope, type, null, null );
+ }
+
+ public Artifact createArtifactWithClassifier( String groupId, String artifactId, String version, String type,
+ String classifier )
+ {
+ return createArtifact( groupId, artifactId, version, null, type, classifier, null );
+ }
+
+ public Artifact createDependencyArtifact( String groupId, String artifactId, VersionRange versionRange,
+ String type, String classifier, String scope )
+ {
+ return createArtifact( groupId, artifactId, versionRange, type, classifier, scope, null );
+ }
+
+ public Artifact createDependencyArtifact( String groupId, String artifactId, VersionRange versionRange,
+ String type, String classifier, String scope, boolean optional )
+ {
+ return createArtifact( groupId, artifactId, versionRange, type, classifier, scope, null, optional );
+ }
+
+ public Artifact createDependencyArtifact( String groupId, String artifactId, VersionRange versionRange,
+ String type, String classifier, String scope, String inheritedScope )
+ {
+ return createArtifact( groupId, artifactId, versionRange, type, classifier, scope, inheritedScope );
+ }
+
+ public Artifact createDependencyArtifact( String groupId, String artifactId, VersionRange versionRange,
+ String type, String classifier, String scope, String inheritedScope,
+ boolean optional )
+ {
+ return createArtifact( groupId, artifactId, versionRange, type, classifier, scope, inheritedScope, optional );
+ }
+
+ public Artifact createBuildArtifact( String groupId, String artifactId, String version, String packaging )
+ {
+ return createArtifact( groupId, artifactId, version, null, packaging, null, null );
+ }
+
+ public Artifact createProjectArtifact( String groupId, String artifactId, String version )
+ {
+ return createProjectArtifact( groupId, artifactId, version, null );
+ }
+
+ public Artifact createParentArtifact( String groupId, String artifactId, String version )
+ {
+ return createProjectArtifact( groupId, artifactId, version );
+ }
+
+ public Artifact createPluginArtifact( String groupId, String artifactId, VersionRange versionRange )
+ {
+ return createArtifact( groupId, artifactId, versionRange, "maven-plugin", null, Artifact.SCOPE_RUNTIME, null );
+ }
+
+ public Artifact createProjectArtifact( String groupId, String artifactId, String version, String scope )
+ {
+ return createArtifact( groupId, artifactId, version, scope, "pom" );
+ }
+
+ public Artifact createExtensionArtifact( String groupId, String artifactId, VersionRange versionRange )
+ {
+ return createArtifact( groupId, artifactId, versionRange, "jar", null, Artifact.SCOPE_RUNTIME, null );
+ }
+
+ private Artifact createArtifact( String groupId, String artifactId, String version, String scope, String type,
+ String classifier, String inheritedScope )
+ {
+ VersionRange versionRange = null;
+ if ( version != null )
+ {
+ versionRange = VersionRange.createFromVersion( version );
+ }
+ return createArtifact( groupId, artifactId, versionRange, type, classifier, scope, inheritedScope );
+ }
+
+ private Artifact createArtifact( String groupId, String artifactId, VersionRange versionRange, String type,
+ String classifier, String scope, String inheritedScope )
+ {
+ return createArtifact( groupId, artifactId, versionRange, type, classifier, scope, inheritedScope, false );
+ }
+
+ private Artifact createArtifact( String groupId, String artifactId, VersionRange versionRange, String type,
+ String classifier, String scope, String inheritedScope, boolean optional )
+ {
+ String desiredScope = Artifact.SCOPE_RUNTIME;
+
+ if ( inheritedScope == null )
+ {
+ desiredScope = scope;
+ }
+ else if ( Artifact.SCOPE_TEST.equals( scope ) || Artifact.SCOPE_PROVIDED.equals( scope ) )
+ {
+ return null;
+ }
+ else if ( Artifact.SCOPE_COMPILE.equals( scope ) && Artifact.SCOPE_COMPILE.equals( inheritedScope ) )
+ {
+ // added to retain compile artifactScope. Remove if you want compile inherited as runtime
+ desiredScope = Artifact.SCOPE_COMPILE;
+ }
+
+ if ( Artifact.SCOPE_TEST.equals( inheritedScope ) )
+ {
+ desiredScope = Artifact.SCOPE_TEST;
+ }
+
+ if ( Artifact.SCOPE_PROVIDED.equals( inheritedScope ) )
+ {
+ desiredScope = Artifact.SCOPE_PROVIDED;
+ }
+
+ if ( Artifact.SCOPE_SYSTEM.equals( scope ) )
+ {
+ // system scopes come through unchanged...
+ desiredScope = Artifact.SCOPE_SYSTEM;
+ }
+
+ ArtifactHandler handler = artifactHandlerManager.getArtifactHandler( type );
+
+ return new DefaultArtifact( groupId, artifactId, versionRange, desiredScope, type, classifier, handler,
+ optional );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/handler/DefaultArtifactHandler.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/handler/DefaultArtifactHandler.java
new file mode 100644
index 00000000..628f38bc
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/handler/DefaultArtifactHandler.java
@@ -0,0 +1,134 @@
+package org.apache.maven.artifact.handler;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.codehaus.plexus.component.annotations.Component;
+
+/**
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ * @author Jason van Zyl
+ */
+@Component( role = ArtifactHandler.class )
+public class DefaultArtifactHandler
+ implements ArtifactHandler
+{
+ private String extension;
+
+ private String type;
+
+ private String classifier;
+
+ private String directory;
+
+ private String packaging;
+
+ private boolean includesDependencies;
+
+ private String language;
+
+ private boolean addedToClasspath;
+
+ public DefaultArtifactHandler()
+ {
+ }
+
+ public DefaultArtifactHandler( String type )
+ {
+ this.type = type;
+ }
+
+ public String getExtension()
+ {
+ if ( extension == null )
+ {
+ extension = type;
+ }
+ return extension;
+ }
+
+ public void setExtension( String extension )
+ {
+ this.extension = extension;
+ }
+
+ public String getType()
+ {
+ return type;
+ }
+
+ public String getClassifier()
+ {
+ return classifier;
+ }
+
+ public String getDirectory()
+ {
+ if ( directory == null )
+ {
+ directory = getPackaging() + "s";
+ }
+ return directory;
+ }
+
+ public String getPackaging()
+ {
+ if ( packaging == null )
+ {
+ packaging = type;
+ }
+ return packaging;
+ }
+
+ public boolean isIncludesDependencies()
+ {
+ return includesDependencies;
+ }
+
+ public void setIncludesDependencies( boolean includesDependencies )
+ {
+ this.includesDependencies = includesDependencies;
+ }
+
+ public String getLanguage()
+ {
+ if ( language == null )
+ {
+ language = "none";
+ }
+
+ return language;
+ }
+
+ public void setLanguage( String language )
+ {
+ this.language = language;
+ }
+
+ public boolean isAddedToClasspath()
+ {
+ return addedToClasspath;
+ }
+
+ public void setAddedToClasspath( boolean addedToClasspath )
+ {
+ this.addedToClasspath = addedToClasspath;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/handler/manager/ArtifactHandlerManager.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/handler/manager/ArtifactHandlerManager.java
new file mode 100644
index 00000000..cada9e93
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/handler/manager/ArtifactHandlerManager.java
@@ -0,0 +1,37 @@
+package org.apache.maven.artifact.handler.manager;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Map;
+
+import org.apache.maven.artifact.handler.ArtifactHandler;
+
+/**
+ * @author Jason van Zyl
+ */
+public interface ArtifactHandlerManager
+{
+ String ROLE = ArtifactHandlerManager.class.getName();
+
+ ArtifactHandler getArtifactHandler( String type );
+
+ @Deprecated
+ void addHandlers( Map<String, ArtifactHandler> handlers );
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/handler/manager/DefaultArtifactHandlerManager.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/handler/manager/DefaultArtifactHandlerManager.java
new file mode 100644
index 00000000..6be636b0
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/handler/manager/DefaultArtifactHandlerManager.java
@@ -0,0 +1,73 @@
+package org.apache.maven.artifact.handler.manager;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.maven.artifact.handler.ArtifactHandler;
+import org.apache.maven.artifact.handler.DefaultArtifactHandler;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+
+/**
+ * @author Jason van Zyl
+ */
+@Component( role = ArtifactHandlerManager.class )
+public class DefaultArtifactHandlerManager
+ implements ArtifactHandlerManager
+{
+
+ @Requirement( role = ArtifactHandler.class )
+ private Map<String, ArtifactHandler> artifactHandlers;
+
+ private Map<String, ArtifactHandler> unmanagedHandlers = new ConcurrentHashMap<String, ArtifactHandler>();
+
+ public ArtifactHandler getArtifactHandler( String type )
+ {
+ ArtifactHandler handler = unmanagedHandlers.get( type );
+
+ if ( handler == null )
+ {
+ handler = artifactHandlers.get( type );
+
+ if ( handler == null )
+ {
+ handler = new DefaultArtifactHandler( type );
+ }
+ }
+
+ return handler;
+ }
+
+ public void addHandlers( Map<String, ArtifactHandler> handlers )
+ {
+ // legacy support for maven-gpg-plugin:1.0
+ unmanagedHandlers.putAll( handlers );
+ }
+
+ @Deprecated
+ public Set<String> getHandlerTypes()
+ {
+ return artifactHandlers.keySet();
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/metadata/AbstractArtifactMetadata.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/metadata/AbstractArtifactMetadata.java
new file mode 100644
index 00000000..5ef3a980
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/metadata/AbstractArtifactMetadata.java
@@ -0,0 +1,33 @@
+package org.apache.maven.artifact.metadata;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.artifact.Artifact;
+
+@Deprecated
+public abstract class AbstractArtifactMetadata
+ extends org.apache.maven.repository.legacy.metadata.AbstractArtifactMetadata
+ implements org.apache.maven.artifact.metadata.ArtifactMetadata
+{
+ protected AbstractArtifactMetadata( Artifact artifact )
+ {
+ super( artifact );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/metadata/ArtifactMetadataRetrievalException.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/metadata/ArtifactMetadataRetrievalException.java
new file mode 100644
index 00000000..e419ef9e
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/metadata/ArtifactMetadataRetrievalException.java
@@ -0,0 +1,55 @@
+package org.apache.maven.artifact.metadata;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.artifact.Artifact;
+
+@Deprecated
+public class ArtifactMetadataRetrievalException
+ extends org.apache.maven.repository.legacy.metadata.ArtifactMetadataRetrievalException
+{
+
+ /** @deprecated use {@link #ArtifactMetadataRetrievalException(String, Throwable, Artifact)} */
+ @Deprecated
+ public ArtifactMetadataRetrievalException( String message )
+ {
+ super( message, null, null );
+ }
+
+ /** @deprecated use {@link #ArtifactMetadataRetrievalException(String, Throwable, Artifact)} */
+ @Deprecated
+ public ArtifactMetadataRetrievalException( Throwable cause )
+ {
+ super( null, cause, null );
+ }
+
+ /** @deprecated use {@link #ArtifactMetadataRetrievalException(String, Throwable, Artifact)} */
+ @Deprecated
+ public ArtifactMetadataRetrievalException( String message,
+ Throwable cause )
+ {
+ super( message, cause, null );
+ }
+
+ public ArtifactMetadataRetrievalException( String message, Throwable cause, Artifact artifact )
+ {
+ super( message, cause, artifact );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/metadata/ArtifactMetadataSource.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/metadata/ArtifactMetadataSource.java
new file mode 100644
index 00000000..ccd58363
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/metadata/ArtifactMetadataSource.java
@@ -0,0 +1,52 @@
+package org.apache.maven.artifact.metadata;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.List;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.versioning.ArtifactVersion;
+import org.apache.maven.repository.legacy.metadata.MetadataResolutionRequest;
+
+@Deprecated
+public interface ArtifactMetadataSource
+ extends org.apache.maven.repository.legacy.metadata.ArtifactMetadataSource
+{
+
+ ResolutionGroup retrieve( MetadataResolutionRequest request )
+ throws ArtifactMetadataRetrievalException;
+
+ ResolutionGroup retrieve( Artifact artifact, ArtifactRepository localRepository,
+ List<ArtifactRepository> remoteRepositories )
+ throws ArtifactMetadataRetrievalException;
+
+ List<ArtifactVersion> retrieveAvailableVersions( MetadataResolutionRequest request )
+ throws ArtifactMetadataRetrievalException;
+
+ List<ArtifactVersion> retrieveAvailableVersions( Artifact artifact, ArtifactRepository localRepository,
+ List<ArtifactRepository> remoteRepositories )
+ throws ArtifactMetadataRetrievalException;
+
+ List<ArtifactVersion> retrieveAvailableVersionsFromDeploymentRepository( Artifact artifact,
+ ArtifactRepository localRepository,
+ ArtifactRepository remoteRepository )
+ throws ArtifactMetadataRetrievalException;
+} \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/metadata/ResolutionGroup.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/metadata/ResolutionGroup.java
new file mode 100644
index 00000000..c219b24e
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/metadata/ResolutionGroup.java
@@ -0,0 +1,46 @@
+package org.apache.maven.artifact.metadata;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+
+@Deprecated
+public class ResolutionGroup
+ extends org.apache.maven.repository.legacy.metadata.ResolutionGroup
+{
+
+ public ResolutionGroup( Artifact pomArtifact, Set<Artifact> artifacts,
+ List<ArtifactRepository> resolutionRepositories )
+ {
+ super( pomArtifact, artifacts, resolutionRepositories );
+ }
+
+ public ResolutionGroup( Artifact pomArtifact, Artifact relocatedArtifact, Set<Artifact> artifacts,
+ Map<String, Artifact> managedVersions, List<ArtifactRepository> resolutionRepositories )
+ {
+ super( pomArtifact, relocatedArtifact, artifacts, managedVersions, resolutionRepositories );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/repository/DefaultRepositoryRequest.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/repository/DefaultRepositoryRequest.java
new file mode 100644
index 00000000..6b18789d
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/repository/DefaultRepositoryRequest.java
@@ -0,0 +1,134 @@
+package org.apache.maven.artifact.repository;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.project.MavenProject;
+
+/**
+ * Collects basic settings to access the repository system.
+ *
+ * @author Benjamin Bentmann
+ */
+public class DefaultRepositoryRequest
+ implements RepositoryRequest
+{
+
+ private boolean offline;
+
+ private boolean forceUpdate;
+
+ private ArtifactRepository localRepository;
+
+ private List<ArtifactRepository> remoteRepositories;
+
+ /**
+ * Creates an empty repository request.
+ */
+ public DefaultRepositoryRequest()
+ {
+ // enables no-arg constructor
+ }
+
+ /**
+ * Creates a shallow copy of the specified repository request.
+ *
+ * @param repositoryRequest The repository request to copy from, must not be {@code null}.
+ */
+ public DefaultRepositoryRequest( RepositoryRequest repositoryRequest )
+ {
+ setLocalRepository( repositoryRequest.getLocalRepository() );
+ setRemoteRepositories( repositoryRequest.getRemoteRepositories() );
+ setOffline( repositoryRequest.isOffline() );
+ setForceUpdate( repositoryRequest.isForceUpdate() );
+ }
+
+ public static RepositoryRequest getRepositoryRequest( MavenSession session, MavenProject project )
+ {
+ RepositoryRequest request = new DefaultRepositoryRequest();
+
+ request.setLocalRepository( session.getLocalRepository() );
+ if ( project != null )
+ {
+ request.setRemoteRepositories( project.getPluginArtifactRepositories() );
+ }
+ request.setOffline( session.isOffline() );
+ request.setForceUpdate( session.getRequest().isUpdateSnapshots() );
+
+ return request;
+ }
+
+ public boolean isOffline()
+ {
+ return offline;
+ }
+
+ public DefaultRepositoryRequest setOffline( boolean offline )
+ {
+ this.offline = offline;
+
+ return this;
+ }
+
+ public boolean isForceUpdate()
+ {
+ return forceUpdate;
+ }
+
+ public DefaultRepositoryRequest setForceUpdate( boolean forceUpdate )
+ {
+ this.forceUpdate = forceUpdate;
+
+ return this;
+ }
+
+ public ArtifactRepository getLocalRepository()
+ {
+ return localRepository;
+ }
+
+ public DefaultRepositoryRequest setLocalRepository( ArtifactRepository localRepository )
+ {
+ this.localRepository = localRepository;
+
+ return this;
+ }
+
+ public List<ArtifactRepository> getRemoteRepositories()
+ {
+ if ( remoteRepositories == null )
+ {
+ remoteRepositories = new ArrayList<ArtifactRepository>();
+ }
+
+ return remoteRepositories;
+ }
+
+ public DefaultRepositoryRequest setRemoteRepositories( List<ArtifactRepository> remoteRepositories )
+ {
+ this.remoteRepositories = remoteRepositories;
+
+ return this;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/repository/LegacyLocalRepositoryManager.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/repository/LegacyLocalRepositoryManager.java
new file mode 100644
index 00000000..f56fb459
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/repository/LegacyLocalRepositoryManager.java
@@ -0,0 +1,435 @@
+package org.apache.maven.artifact.repository;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.maven.RepositoryUtils;
+import org.apache.maven.artifact.metadata.ArtifactMetadata;
+import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout;
+import org.apache.maven.artifact.repository.layout.DefaultRepositoryLayout;
+import org.apache.maven.artifact.repository.metadata.RepositoryMetadataStoreException;
+import org.apache.maven.repository.Proxy;
+import org.eclipse.aether.DefaultRepositorySystemSession;
+import org.eclipse.aether.RepositorySystem;
+import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.artifact.Artifact;
+import org.eclipse.aether.metadata.Metadata;
+import org.eclipse.aether.repository.LocalArtifactRegistration;
+import org.eclipse.aether.repository.LocalArtifactRequest;
+import org.eclipse.aether.repository.LocalArtifactResult;
+import org.eclipse.aether.repository.LocalMetadataRegistration;
+import org.eclipse.aether.repository.LocalMetadataRequest;
+import org.eclipse.aether.repository.LocalMetadataResult;
+import org.eclipse.aether.repository.LocalRepository;
+import org.eclipse.aether.repository.LocalRepositoryManager;
+import org.eclipse.aether.repository.RemoteRepository;
+
+/**
+ * <strong>Warning:</strong> This is an internal utility class that is only public for technical reasons, it is not part
+ * of the public API. In particular, this class can be changed or deleted without prior notice.
+ *
+ * @author Benjamin Bentmann
+ */
+public class LegacyLocalRepositoryManager
+ implements LocalRepositoryManager
+{
+
+ private final ArtifactRepository delegate;
+
+ private final LocalRepository repo;
+
+ private final boolean realLocalRepo;
+
+ public static RepositorySystemSession overlay( ArtifactRepository repository, RepositorySystemSession session,
+ RepositorySystem system )
+ {
+ if ( repository == null || repository.getBasedir() == null )
+ {
+ return session;
+ }
+
+ if ( session != null )
+ {
+ LocalRepositoryManager lrm = session.getLocalRepositoryManager();
+ if ( lrm != null && lrm.getRepository().getBasedir().equals( new File( repository.getBasedir() ) ) )
+ {
+ return session;
+ }
+ }
+ else
+ {
+ session = new DefaultRepositorySystemSession();
+ }
+
+ final LocalRepositoryManager llrm = new LegacyLocalRepositoryManager( repository );
+
+ return new DefaultRepositorySystemSession( session ).setLocalRepositoryManager( llrm );
+ }
+
+ private LegacyLocalRepositoryManager( ArtifactRepository delegate )
+ {
+ if ( delegate == null )
+ {
+ throw new IllegalArgumentException( "local repository delegate missing" );
+ }
+ this.delegate = delegate;
+
+ ArtifactRepositoryLayout layout = delegate.getLayout();
+ repo =
+ new LocalRepository( new File( delegate.getBasedir() ),
+ ( layout != null ) ? layout.getClass().getSimpleName() : "legacy" );
+
+ /*
+ * NOTE: "invoker:install" vs "appassembler:assemble": Both mojos use the artifact installer to put an artifact
+ * into a repository. In the first case, the result needs to be a proper local repository that one can use for
+ * local artifact resolution. In the second case, the result needs to precisely obey the path information of the
+ * repository's layout to allow pointing at artifacts within the repository. Unfortunately,
+ * DefaultRepositoryLayout does not correctly describe the layout of a local repository which unlike a remote
+ * repository never uses timestamps in the filename of a snapshot artifact. The discrepancy gets notable when a
+ * remotely resolved snapshot artifact gets passed into pathOf(). So producing a proper local artifact path
+ * using DefaultRepositoryLayout requires us to enforce usage of the artifact's base version. This
+ * transformation however contradicts the other use case of precisely obeying the repository's layout. The below
+ * flag tries to detect which use case applies to make both plugins happy.
+ */
+ realLocalRepo = ( layout instanceof DefaultRepositoryLayout ) && "local".equals( delegate.getId() );
+ }
+
+ public LocalRepository getRepository()
+ {
+ return repo;
+ }
+
+ public String getPathForLocalArtifact( Artifact artifact )
+ {
+ if ( realLocalRepo )
+ {
+ return delegate.pathOf( RepositoryUtils.toArtifact( artifact.setVersion( artifact.getBaseVersion() ) ) );
+ }
+ return delegate.pathOf( RepositoryUtils.toArtifact( artifact ) );
+ }
+
+ public String getPathForRemoteArtifact( Artifact artifact, RemoteRepository repository, String context )
+ {
+ return delegate.pathOf( RepositoryUtils.toArtifact( artifact ) );
+ }
+
+ public String getPathForLocalMetadata( Metadata metadata )
+ {
+ return delegate.pathOfLocalRepositoryMetadata( new ArtifactMetadataAdapter( metadata ), delegate );
+ }
+
+ public String getPathForRemoteMetadata( Metadata metadata, RemoteRepository repository, String context )
+ {
+ return delegate.pathOfLocalRepositoryMetadata( new ArtifactMetadataAdapter( metadata ),
+ new ArtifactRepositoryAdapter( repository ) );
+ }
+
+ public LocalArtifactResult find( RepositorySystemSession session, LocalArtifactRequest request )
+ {
+ String path = getPathForLocalArtifact( request.getArtifact() );
+ File file = new File( getRepository().getBasedir(), path );
+
+ LocalArtifactResult result = new LocalArtifactResult( request );
+ if ( file.isFile() )
+ {
+ result.setFile( file );
+ result.setAvailable( true );
+ }
+
+ return result;
+ }
+
+ public LocalMetadataResult find( RepositorySystemSession session, LocalMetadataRequest request )
+ {
+ Metadata metadata = request.getMetadata();
+
+ String path;
+ if ( request.getRepository() == null )
+ {
+ path = getPathForLocalMetadata( metadata );
+ }
+ else
+ {
+ path = getPathForRemoteMetadata( metadata, request.getRepository(), request.getContext() );
+ }
+
+ File file = new File( getRepository().getBasedir(), path );
+
+ LocalMetadataResult result = new LocalMetadataResult( request );
+ if ( file.isFile() )
+ {
+ result.setFile( file );
+ }
+
+ return result;
+ }
+
+ public void add( RepositorySystemSession session, LocalArtifactRegistration request )
+ {
+ // noop
+ }
+
+ public void add( RepositorySystemSession session, LocalMetadataRegistration request )
+ {
+ // noop
+ }
+
+ static class ArtifactMetadataAdapter
+ implements ArtifactMetadata
+ {
+
+ private final Metadata metadata;
+
+ public ArtifactMetadataAdapter( Metadata metadata )
+ {
+ this.metadata = metadata;
+ }
+
+ public boolean storedInArtifactVersionDirectory()
+ {
+ return metadata.getVersion().length() > 0;
+ }
+
+ public boolean storedInGroupDirectory()
+ {
+ return metadata.getArtifactId().length() <= 0;
+ }
+
+ public String getGroupId()
+ {
+ return nullify( metadata.getGroupId() );
+ }
+
+ public String getArtifactId()
+ {
+ return nullify( metadata.getArtifactId() );
+ }
+
+ public String getBaseVersion()
+ {
+ return nullify( metadata.getVersion() );
+ }
+
+ private String nullify( String str )
+ {
+ return ( str == null || str.length() <= 0 ) ? null : str;
+ }
+
+ public Object getKey()
+ {
+ return metadata.toString();
+ }
+
+ public String getRemoteFilename()
+ {
+ return metadata.getType();
+ }
+
+ public String getLocalFilename( ArtifactRepository repository )
+ {
+ return insertRepositoryKey( getRemoteFilename(), repository.getKey() );
+ }
+
+ private String insertRepositoryKey( String filename, String repositoryKey )
+ {
+ String result;
+ int idx = filename.indexOf( '.' );
+ if ( idx < 0 )
+ {
+ result = filename + '-' + repositoryKey;
+ }
+ else
+ {
+ result = filename.substring( 0, idx ) + '-' + repositoryKey + filename.substring( idx );
+ }
+ return result;
+ }
+
+ public void merge( org.apache.maven.repository.legacy.metadata.ArtifactMetadata metadata )
+ {
+ // not used
+ }
+
+ public void merge( ArtifactMetadata metadata )
+ {
+ // not used
+ }
+
+ public void storeInLocalRepository( ArtifactRepository localRepository, ArtifactRepository remoteRepository )
+ throws RepositoryMetadataStoreException
+ {
+ // not used
+ }
+
+ public String extendedToString()
+ {
+ return metadata.toString();
+ }
+
+ }
+
+ static class ArtifactRepositoryAdapter
+ implements ArtifactRepository
+ {
+
+ private final RemoteRepository repository;
+
+ public ArtifactRepositoryAdapter( RemoteRepository repository )
+ {
+ this.repository = repository;
+ }
+
+ public String pathOf( org.apache.maven.artifact.Artifact artifact )
+ {
+ return null;
+ }
+
+ public String pathOfRemoteRepositoryMetadata( ArtifactMetadata artifactMetadata )
+ {
+ return null;
+ }
+
+ public String pathOfLocalRepositoryMetadata( ArtifactMetadata metadata, ArtifactRepository repository )
+ {
+ return null;
+ }
+
+ public String getUrl()
+ {
+ return repository.getUrl();
+ }
+
+ public void setUrl( String url )
+ {
+ }
+
+ public String getBasedir()
+ {
+ return null;
+ }
+
+ public String getProtocol()
+ {
+ return repository.getProtocol();
+ }
+
+ public String getId()
+ {
+ return repository.getId();
+ }
+
+ public void setId( String id )
+ {
+ }
+
+ public ArtifactRepositoryPolicy getSnapshots()
+ {
+ return null;
+ }
+
+ public void setSnapshotUpdatePolicy( ArtifactRepositoryPolicy policy )
+ {
+ }
+
+ public ArtifactRepositoryPolicy getReleases()
+ {
+ return null;
+ }
+
+ public void setReleaseUpdatePolicy( ArtifactRepositoryPolicy policy )
+ {
+ }
+
+ public ArtifactRepositoryLayout getLayout()
+ {
+ return null;
+ }
+
+ public void setLayout( ArtifactRepositoryLayout layout )
+ {
+ }
+
+ public String getKey()
+ {
+ return getId();
+ }
+
+ public boolean isUniqueVersion()
+ {
+ return true;
+ }
+
+ public boolean isBlacklisted()
+ {
+ return false;
+ }
+
+ public void setBlacklisted( boolean blackListed )
+ {
+ }
+
+ public org.apache.maven.artifact.Artifact find( org.apache.maven.artifact.Artifact artifact )
+ {
+ return null;
+ }
+
+ public List<String> findVersions( org.apache.maven.artifact.Artifact artifact )
+ {
+ return Collections.emptyList();
+ }
+
+ public boolean isProjectAware()
+ {
+ return false;
+ }
+
+ public void setAuthentication( Authentication authentication )
+ {
+ }
+
+ public Authentication getAuthentication()
+ {
+ return null;
+ }
+
+ public void setProxy( Proxy proxy )
+ {
+ }
+
+ public Proxy getProxy()
+ {
+ return null;
+ }
+
+ public List<ArtifactRepository> getMirroredRepositories()
+ {
+ return Collections.emptyList();
+ }
+
+ public void setMirroredRepositories( List<ArtifactRepository> mirroredRepositories )
+ {
+ }
+
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/repository/MavenArtifactRepository.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/repository/MavenArtifactRepository.java
new file mode 100644
index 00000000..8e45b203
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/repository/MavenArtifactRepository.java
@@ -0,0 +1,412 @@
+package org.apache.maven.artifact.repository;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.metadata.ArtifactMetadata;
+import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout;
+import org.apache.maven.repository.Proxy;
+
+//TODO: completely separate local and remote artifact repositories
+public class MavenArtifactRepository
+ implements ArtifactRepository
+{
+ private String id;
+
+ private String url;
+
+ private String basedir;
+
+ private String protocol;
+
+ private ArtifactRepositoryLayout layout;
+
+ private ArtifactRepositoryPolicy snapshots;
+
+ private ArtifactRepositoryPolicy releases;
+
+ private Authentication authentication;
+
+ private Proxy proxy;
+
+ private List<ArtifactRepository> mirroredRepositories = Collections.emptyList();
+
+ public MavenArtifactRepository()
+ {
+ }
+
+ /**
+ * Create a remote download repository.
+ *
+ * @param id the unique identifier of the repository
+ * @param url the URL of the repository
+ * @param layout the layout of the repository
+ * @param snapshots the policies to use for snapshots
+ * @param releases the policies to use for releases
+ */
+ public MavenArtifactRepository( String id, String url, ArtifactRepositoryLayout layout,
+ ArtifactRepositoryPolicy snapshots, ArtifactRepositoryPolicy releases )
+ {
+ this.id = id;
+ this.url = url;
+ this.layout = layout;
+ this.snapshots = snapshots;
+ this.releases = releases;
+ //
+ // Derive these from the URL
+ //
+ this.protocol = protocol( url );
+ this.basedir = basedir( url );
+ }
+
+ public String pathOf( Artifact artifact )
+ {
+ return layout.pathOf( artifact );
+ }
+
+ public String pathOfRemoteRepositoryMetadata( ArtifactMetadata artifactMetadata )
+ {
+ return layout.pathOfRemoteRepositoryMetadata( artifactMetadata );
+ }
+
+ public String pathOfLocalRepositoryMetadata( ArtifactMetadata metadata, ArtifactRepository repository )
+ {
+ return layout.pathOfLocalRepositoryMetadata( metadata, repository );
+ }
+
+ public void setLayout( ArtifactRepositoryLayout layout )
+ {
+ this.layout = layout;
+ }
+
+ public ArtifactRepositoryLayout getLayout()
+ {
+ return layout;
+ }
+
+ public void setSnapshotUpdatePolicy( ArtifactRepositoryPolicy snapshots )
+ {
+ this.snapshots = snapshots;
+ }
+
+ public ArtifactRepositoryPolicy getSnapshots()
+ {
+ return snapshots;
+ }
+
+ public void setReleaseUpdatePolicy( ArtifactRepositoryPolicy releases )
+ {
+ this.releases = releases;
+ }
+
+ public ArtifactRepositoryPolicy getReleases()
+ {
+ return releases;
+ }
+
+ public String getKey()
+ {
+ return getId();
+ }
+
+ public String toString()
+ {
+ StringBuilder sb = new StringBuilder();
+
+ sb.append( " id: " ).append( getId() ).append( "\n" );
+ sb.append( " url: " ).append( getUrl() ).append( "\n" );
+ sb.append( " layout: " ).append( layout != null ? layout : "none" ).append( "\n" );
+
+ if ( proxy != null )
+ {
+ sb.append( " proxy: " ).append( proxy.getHost() ).append( ":" ).append( proxy.getPort() ).append( "\n" );
+ }
+
+ if ( snapshots != null )
+ {
+ sb.append( "snapshots: [enabled => " ).append( snapshots.isEnabled() );
+ sb.append( ", update => " ).append( snapshots.getUpdatePolicy() ).append( "]\n" );
+ }
+
+ if ( releases != null )
+ {
+ sb.append( " releases: [enabled => " ).append( releases.isEnabled() );
+ sb.append( ", update => " ).append( releases.getUpdatePolicy() ).append( "]\n" );
+ }
+
+ return sb.toString();
+ }
+
+ public Artifact find( Artifact artifact )
+ {
+ File artifactFile = new File( getBasedir(), pathOf( artifact ) );
+
+ // We need to set the file here or the resolver will fail with an NPE, not fully equipped to deal
+ // with multiple local repository implementations yet.
+ artifact.setFile( artifactFile );
+
+ return artifact;
+ }
+
+ public List<String> findVersions( Artifact artifact )
+ {
+ return Collections.emptyList();
+ }
+
+ public String getId()
+ {
+ return id;
+ }
+
+ public String getUrl()
+ {
+ return url;
+ }
+
+ public String getBasedir()
+ {
+ return basedir;
+ }
+
+ public String getProtocol()
+ {
+ return protocol;
+ }
+
+ public void setId( String id )
+ {
+ this.id = id;
+ }
+
+ public void setUrl( String url )
+ {
+ this.url = url;
+
+ this.protocol = protocol( url );
+ this.basedir = basedir( url );
+ }
+
+ // Path Utils
+
+ /**
+ * Return the protocol name.
+ * <br/>
+ * E.g: for input
+ * <code>http://www.codehause.org</code> this method will return <code>http</code>
+ *
+ * @param url the url
+ * @return the host name
+ */
+ private static String protocol( final String url )
+ {
+ final int pos = url.indexOf( ":" );
+
+ if ( pos == -1 )
+ {
+ return "";
+ }
+ return url.substring( 0, pos ).trim();
+ }
+
+ /**
+ * Derive the path portion of the given URL.
+ *
+ * @param url the repository URL
+ * @return the basedir of the repository
+ * @todo need to URL decode for spaces?
+ */
+ private String basedir( String url )
+ {
+ String retValue = null;
+
+ if ( protocol.equalsIgnoreCase( "file" ) )
+ {
+ retValue = url.substring( protocol.length() + 1 );
+ retValue = decode( retValue );
+ // special case: if omitted // on protocol, keep path as is
+ if ( retValue.startsWith( "//" ) )
+ {
+ retValue = retValue.substring( 2 );
+
+ if ( retValue.length() >= 2 && ( retValue.charAt( 1 ) == '|' || retValue.charAt( 1 ) == ':' ) )
+ {
+ // special case: if there is a windows drive letter, then keep the original return value
+ retValue = retValue.charAt( 0 ) + ":" + retValue.substring( 2 );
+ }
+ else
+ {
+ // Now we expect the host
+ int index = retValue.indexOf( "/" );
+ if ( index >= 0 )
+ {
+ retValue = retValue.substring( index + 1 );
+ }
+
+ // special case: if there is a windows drive letter, then keep the original return value
+ if ( retValue.length() >= 2 && ( retValue.charAt( 1 ) == '|' || retValue.charAt( 1 ) == ':' ) )
+ {
+ retValue = retValue.charAt( 0 ) + ":" + retValue.substring( 2 );
+ }
+ else if ( index >= 0 )
+ {
+ // leading / was previously stripped
+ retValue = "/" + retValue;
+ }
+ }
+ }
+
+ // special case: if there is a windows drive letter using |, switch to :
+ if ( retValue.length() >= 2 && retValue.charAt( 1 ) == '|' )
+ {
+ retValue = retValue.charAt( 0 ) + ":" + retValue.substring( 2 );
+ }
+
+ // normalize separators
+ retValue = new File( retValue ).getPath();
+ }
+
+ if ( retValue == null )
+ {
+ retValue = "/";
+ }
+ return retValue.trim();
+ }
+
+ /**
+ * Decodes the specified (portion of a) URL. <strong>Note:</strong> This decoder assumes that ISO-8859-1 is used to
+ * convert URL-encoded bytes to characters.
+ *
+ * @param url The URL to decode, may be <code>null</code>.
+ * @return The decoded URL or <code>null</code> if the input was <code>null</code>.
+ */
+ private static String decode( String url )
+ {
+ String decoded = url;
+ if ( url != null )
+ {
+ int pos = -1;
+ while ( ( pos = decoded.indexOf( '%', pos + 1 ) ) >= 0 )
+ {
+ if ( pos + 2 < decoded.length() )
+ {
+ String hexStr = decoded.substring( pos + 1, pos + 3 );
+ char ch = (char) Integer.parseInt( hexStr, 16 );
+ decoded = decoded.substring( 0, pos ) + ch + decoded.substring( pos + 3 );
+ }
+ }
+ }
+ return decoded;
+ }
+
+ public int hashCode()
+ {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ( ( getId() == null ) ? 0 : getId().hashCode() );
+ return result;
+ }
+
+ public boolean equals( Object obj )
+ {
+ if ( this == obj )
+ {
+ return true;
+ }
+ if ( obj == null )
+ {
+ return false;
+ }
+ if ( getClass() != obj.getClass() )
+ {
+ return false;
+ }
+
+ ArtifactRepository other = (ArtifactRepository) obj;
+
+ return eq( getId(), other.getId() );
+ }
+
+ protected static <T> boolean eq( T s1, T s2 )
+ {
+ return s1 != null ? s1.equals( s2 ) : s2 == null;
+ }
+
+ public Authentication getAuthentication()
+ {
+ return authentication;
+ }
+
+ public void setAuthentication( Authentication authentication )
+ {
+ this.authentication = authentication;
+ }
+
+ public Proxy getProxy()
+ {
+ return proxy;
+ }
+
+ public void setProxy( Proxy proxy )
+ {
+ this.proxy = proxy;
+ }
+
+ public boolean isBlacklisted()
+ {
+ return false;
+ }
+
+ public void setBlacklisted( boolean blackListed )
+ {
+ // no op
+ }
+
+ public boolean isUniqueVersion()
+ {
+ return true;
+ }
+
+ public boolean isProjectAware()
+ {
+ return false;
+ }
+
+ public List<ArtifactRepository> getMirroredRepositories()
+ {
+ return mirroredRepositories;
+ }
+
+ public void setMirroredRepositories( List<ArtifactRepository> mirroredRepositories )
+ {
+ if ( mirroredRepositories != null )
+ {
+ this.mirroredRepositories = mirroredRepositories;
+ }
+ else
+ {
+ this.mirroredRepositories = Collections.emptyList();
+ }
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/repository/RepositoryCache.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/repository/RepositoryCache.java
new file mode 100644
index 00000000..bf79d698
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/repository/RepositoryCache.java
@@ -0,0 +1,58 @@
+package org.apache.maven.artifact.repository;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Caches auxiliary data used during repository access like already processed metadata. The data in the cache is meant
+ * for exclusive consumption by the repository system and is opaque to the cache implementation.
+ *
+ * @author Benjamin Bentmann
+ */
+@Deprecated
+//
+// Used by Tycho and will break users and force them to upgrade to Maven 3.1 so we should really leave
+// this here, possibly indefinitely.
+//
+public interface RepositoryCache
+{
+
+ /**
+ * Puts the specified data into the cache. <strong>Warning:</strong> The cache will directly save the provided
+ * reference. If the cached data is mutable, i.e. could be modified after being put into the cache, the caller is
+ * responsible for creating a copy of the original data and store the copy in the cache.
+ *
+ * @param request The repository request from which this cache was retrieved, must not be {@code null}.
+ * @param key The key to use associate the data with, must not be {@code null}.
+ * @param data The data to store in the cache, may be {@code null}.
+ */
+ void put( RepositoryRequest request, Object key, Object data );
+
+ /**
+ * Gets the specified data from the cache. <strong>Warning:</strong> The cache will directly return the saved
+ * reference. If the cached data is to be modified after its retrieval, the caller is responsible to create a copy
+ * of the returned data and use this instead of the cache record.
+ *
+ * @param request The repository request from which this cache was retrieved, must not be {@code null}.
+ * @param key The key to use for lookup of the data, must not be {@code null}.
+ * @return The requested data or {@code null} if none was present in the cache.
+ */
+ Object get( RepositoryRequest request, Object key );
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/repository/RepositoryRequest.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/repository/RepositoryRequest.java
new file mode 100644
index 00000000..55f60686
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/repository/RepositoryRequest.java
@@ -0,0 +1,95 @@
+package org.apache.maven.artifact.repository;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.List;
+
+/**
+ * Collects basic settings to access the repository system.
+ *
+ * @author Benjamin Bentmann
+ */
+public interface RepositoryRequest
+{
+
+ /**
+ * Indicates whether network access to remote repositories has been disabled.
+ *
+ * @return {@code true} if remote access has been disabled, {@code false} otherwise.
+ */
+ boolean isOffline();
+
+ /**
+ * Enables/disables network access to remote repositories.
+ *
+ * @param offline {@code true} to disable remote access, {@code false} to allow network access.
+ * @return This request, never {@code null}.
+ */
+ RepositoryRequest setOffline( boolean offline );
+
+ /**
+ * Indicates whether remote repositories should be re-checked for updated artifacts/metadata regardless of their
+ * configured update policy.
+ *
+ * @return {@code true} if remote repositories should be re-checked for updated artifacts/metadata, {@code false}
+ * otherwise.
+ */
+ boolean isForceUpdate();
+
+ /**
+ * Enables/disabled forced checks for updated artifacts/metadata on remote repositories.
+ *
+ * @param forceUpdate {@code true} to forcibly check the remote repositories for updated artifacts/metadata, {@code
+ * false} to use the update policy configured on each repository.
+ * @return This request, never {@code null}.
+ */
+ RepositoryRequest setForceUpdate( boolean forceUpdate );
+
+ /**
+ * Gets the local repository to use.
+ *
+ * @return The local repository to use or {@code null} if not set.
+ */
+ ArtifactRepository getLocalRepository();
+
+ /**
+ * Sets the local repository to use.
+ *
+ * @param localRepository The local repository to use.
+ * @return This request, never {@code null}.
+ */
+ RepositoryRequest setLocalRepository( ArtifactRepository localRepository );
+
+ /**
+ * Gets the remote repositories to use.
+ *
+ * @return The remote repositories to use, never {@code null}.
+ */
+ List<ArtifactRepository> getRemoteRepositories();
+
+ /**
+ * Sets the remote repositories to use.
+ *
+ * @param remoteRepositories The remote repositories to use.
+ * @return This request, never {@code null}.
+ */
+ RepositoryRequest setRemoteRepositories( List<ArtifactRepository> remoteRepositories );
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/repository/layout/DefaultRepositoryLayout.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/repository/layout/DefaultRepositoryLayout.java
new file mode 100644
index 00000000..70c0b14c
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/repository/layout/DefaultRepositoryLayout.java
@@ -0,0 +1,112 @@
+package org.apache.maven.artifact.repository.layout;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.handler.ArtifactHandler;
+import org.apache.maven.artifact.metadata.ArtifactMetadata;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.codehaus.plexus.component.annotations.Component;
+
+/**
+ * @author jdcasey
+ */
+@Component( role = ArtifactRepositoryLayout.class, hint = "default" )
+public class DefaultRepositoryLayout
+ implements ArtifactRepositoryLayout
+{
+ private static final char PATH_SEPARATOR = '/';
+
+ private static final char GROUP_SEPARATOR = '.';
+
+ private static final char ARTIFACT_SEPARATOR = '-';
+
+ public String getId()
+ {
+ return "default";
+ }
+
+ public String pathOf( Artifact artifact )
+ {
+ ArtifactHandler artifactHandler = artifact.getArtifactHandler();
+
+ StringBuilder path = new StringBuilder( 128 );
+
+ path.append( formatAsDirectory( artifact.getGroupId() ) ).append( PATH_SEPARATOR );
+ path.append( artifact.getArtifactId() ).append( PATH_SEPARATOR );
+ path.append( artifact.getBaseVersion() ).append( PATH_SEPARATOR );
+ path.append( artifact.getArtifactId() ).append( ARTIFACT_SEPARATOR ).append( artifact.getVersion() );
+
+ if ( artifact.hasClassifier() )
+ {
+ path.append( ARTIFACT_SEPARATOR ).append( artifact.getClassifier() );
+ }
+
+ if ( artifactHandler.getExtension() != null && artifactHandler.getExtension().length() > 0 )
+ {
+ path.append( GROUP_SEPARATOR ).append( artifactHandler.getExtension() );
+ }
+
+ return path.toString();
+ }
+
+ public String pathOfLocalRepositoryMetadata( ArtifactMetadata metadata, ArtifactRepository repository )
+ {
+ return pathOfRepositoryMetadata( metadata, metadata.getLocalFilename( repository ) );
+ }
+
+ private String pathOfRepositoryMetadata( ArtifactMetadata metadata,
+ String filename )
+ {
+ StringBuilder path = new StringBuilder( 128 );
+
+ path.append( formatAsDirectory( metadata.getGroupId() ) ).append( PATH_SEPARATOR );
+ if ( !metadata.storedInGroupDirectory() )
+ {
+ path.append( metadata.getArtifactId() ).append( PATH_SEPARATOR );
+
+ if ( metadata.storedInArtifactVersionDirectory() )
+ {
+ path.append( metadata.getBaseVersion() ).append( PATH_SEPARATOR );
+ }
+ }
+
+ path.append( filename );
+
+ return path.toString();
+ }
+
+ public String pathOfRemoteRepositoryMetadata( ArtifactMetadata metadata )
+ {
+ return pathOfRepositoryMetadata( metadata, metadata.getRemoteFilename() );
+ }
+
+ private String formatAsDirectory( String directory )
+ {
+ return directory.replace( GROUP_SEPARATOR, PATH_SEPARATOR );
+ }
+
+ @Override
+ public String toString()
+ {
+ return getId();
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/repository/metadata/AbstractRepositoryMetadata.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/repository/metadata/AbstractRepositoryMetadata.java
new file mode 100644
index 00000000..e1e5fe3f
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/repository/metadata/AbstractRepositoryMetadata.java
@@ -0,0 +1,255 @@
+package org.apache.maven.artifact.repository.metadata;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.io.Reader;
+import java.io.Writer;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.metadata.ArtifactMetadata;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy;
+import org.apache.maven.artifact.repository.metadata.io.xpp3.MetadataXpp3Reader;
+import org.apache.maven.artifact.repository.metadata.io.xpp3.MetadataXpp3Writer;
+import org.codehaus.plexus.util.IOUtil;
+import org.codehaus.plexus.util.ReaderFactory;
+import org.codehaus.plexus.util.WriterFactory;
+import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
+
+/**
+ * Shared methods of the repository metadata handling.
+ *
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ */
+public abstract class AbstractRepositoryMetadata
+ implements RepositoryMetadata
+{
+ private Metadata metadata;
+
+ protected AbstractRepositoryMetadata( Metadata metadata )
+ {
+ this.metadata = metadata;
+ }
+
+ public String getRemoteFilename()
+ {
+ return "maven-metadata.xml";
+ }
+
+ public String getLocalFilename( ArtifactRepository repository )
+ {
+ return "maven-metadata-" + repository.getKey() + ".xml";
+ }
+
+ public void storeInLocalRepository( ArtifactRepository localRepository,
+ ArtifactRepository remoteRepository )
+ throws RepositoryMetadataStoreException
+ {
+ try
+ {
+ updateRepositoryMetadata( localRepository, remoteRepository );
+ }
+ catch ( IOException e )
+ {
+ throw new RepositoryMetadataStoreException( "Error updating group repository metadata", e );
+ }
+ catch ( XmlPullParserException e )
+ {
+ throw new RepositoryMetadataStoreException( "Error updating group repository metadata", e );
+ }
+ }
+
+ protected void updateRepositoryMetadata( ArtifactRepository localRepository,
+ ArtifactRepository remoteRepository )
+ throws IOException, XmlPullParserException
+ {
+ MetadataXpp3Reader mappingReader = new MetadataXpp3Reader();
+
+ Metadata metadata = null;
+
+ File metadataFile = new File( localRepository.getBasedir(),
+ localRepository.pathOfLocalRepositoryMetadata( this, remoteRepository ) );
+
+ if ( metadataFile.length() == 0 )
+ {
+ if ( !metadataFile.delete() )
+ {
+ // sleep for 10ms just in case this is windows holding a file lock
+ try
+ {
+ Thread.sleep( 10 );
+ }
+ catch ( InterruptedException e )
+ {
+ // ignore
+ }
+ metadataFile.delete(); // if this fails, forget about it, we'll try to overwrite it anyway so no need
+ // to delete on exit
+ }
+ }
+ else if ( metadataFile.exists() )
+ {
+ Reader reader = null;
+
+ try
+ {
+ reader = ReaderFactory.newXmlReader( metadataFile );
+
+ metadata = mappingReader.read( reader, false );
+ }
+ finally
+ {
+ IOUtil.close( reader );
+ }
+ }
+
+ boolean changed;
+
+ // If file could not be found or was not valid, start from scratch
+ if ( metadata == null )
+ {
+ metadata = this.metadata;
+
+ changed = true;
+ }
+ else
+ {
+ changed = metadata.merge( this.metadata );
+ }
+
+ // beware meta-versions!
+ String version = metadata.getVersion();
+ if ( version != null && ( Artifact.LATEST_VERSION.equals( version ) || Artifact.RELEASE_VERSION.equals(
+ version ) ) )
+ {
+ // meta-versions are not valid <version/> values...don't write them.
+ metadata.setVersion( null );
+ }
+
+ if ( changed || !metadataFile.exists() )
+ {
+ Writer writer = null;
+ try
+ {
+ metadataFile.getParentFile().mkdirs();
+ writer = WriterFactory.newXmlWriter( metadataFile );
+
+ MetadataXpp3Writer mappingWriter = new MetadataXpp3Writer();
+
+ mappingWriter.write( writer, metadata );
+ }
+ finally
+ {
+ IOUtil.close( writer );
+ }
+ }
+ else
+ {
+ metadataFile.setLastModified( System.currentTimeMillis() );
+ }
+ }
+
+ public String toString()
+ {
+ return "repository metadata for: \'" + getKey() + "\'";
+ }
+
+ protected static Metadata createMetadata( Artifact artifact,
+ Versioning versioning )
+ {
+ Metadata metadata = new Metadata();
+ metadata.setGroupId( artifact.getGroupId() );
+ metadata.setArtifactId( artifact.getArtifactId() );
+ metadata.setVersion( artifact.getVersion() );
+ metadata.setVersioning( versioning );
+ return metadata;
+ }
+
+ protected static Versioning createVersioning( Snapshot snapshot )
+ {
+ Versioning versioning = new Versioning();
+ versioning.setSnapshot( snapshot );
+ versioning.updateTimestamp();
+ return versioning;
+ }
+
+ public void setMetadata( Metadata metadata )
+ {
+ this.metadata = metadata;
+ }
+
+ public Metadata getMetadata()
+ {
+ return metadata;
+ }
+
+ public void merge( org.apache.maven.repository.legacy.metadata.ArtifactMetadata metadata )
+ {
+ // TODO: not sure that it should assume this, maybe the calls to addMetadata should pre-merge, then artifact replaces?
+ AbstractRepositoryMetadata repoMetadata = (AbstractRepositoryMetadata) metadata;
+ this.metadata.merge( repoMetadata.getMetadata() );
+ }
+
+ public void merge( ArtifactMetadata metadata )
+ {
+ // TODO: not sure that it should assume this, maybe the calls to addMetadata should pre-merge, then artifact replaces?
+ AbstractRepositoryMetadata repoMetadata = (AbstractRepositoryMetadata) metadata;
+ this.metadata.merge( repoMetadata.getMetadata() );
+ }
+
+ public String extendedToString()
+ {
+ StringBuilder buffer = new StringBuilder();
+
+ buffer.append( "\nRepository Metadata\n--------------------------" );
+ buffer.append( "\nGroupId: " ).append( getGroupId() );
+ buffer.append( "\nArtifactId: " ).append( getArtifactId() );
+ buffer.append( "\nMetadata Type: " ).append( getClass().getName() );
+
+ return buffer.toString();
+ }
+
+ public int getNature()
+ {
+ return RELEASE;
+ }
+
+ public ArtifactRepositoryPolicy getPolicy( ArtifactRepository repository )
+ {
+ int nature = getNature();
+ if ( ( nature & RepositoryMetadata.RELEASE_OR_SNAPSHOT ) == RepositoryMetadata.RELEASE_OR_SNAPSHOT )
+ {
+ ArtifactRepositoryPolicy policy = new ArtifactRepositoryPolicy( repository.getReleases() );
+ policy.merge( repository.getSnapshots() );
+ return policy;
+ }
+ else if ( ( nature & RepositoryMetadata.SNAPSHOT ) != 0 )
+ {
+ return repository.getSnapshots();
+ }
+ else
+ {
+ return repository.getReleases();
+ }
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/repository/metadata/ArtifactRepositoryMetadata.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/repository/metadata/ArtifactRepositoryMetadata.java
new file mode 100644
index 00000000..85fc6018
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/repository/metadata/ArtifactRepositoryMetadata.java
@@ -0,0 +1,129 @@
+package org.apache.maven.artifact.repository.metadata;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.ArtifactUtils;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.versioning.ArtifactVersion;
+import org.apache.maven.artifact.versioning.Restriction;
+import org.apache.maven.artifact.versioning.VersionRange;
+
+/**
+ * Metadata for the artifact directory of the repository.
+ *
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ */
+public class ArtifactRepositoryMetadata
+ extends AbstractRepositoryMetadata
+{
+ private Artifact artifact;
+
+ public ArtifactRepositoryMetadata( Artifact artifact )
+ {
+ this( artifact, null );
+ }
+
+ public ArtifactRepositoryMetadata( Artifact artifact,
+ Versioning versioning )
+ {
+ super( createMetadata( artifact, versioning ) );
+ this.artifact = artifact;
+ }
+
+ public boolean storedInGroupDirectory()
+ {
+ return false;
+ }
+
+ public boolean storedInArtifactVersionDirectory()
+ {
+ return false;
+ }
+
+ public String getGroupId()
+ {
+ return artifact.getGroupId();
+ }
+
+ public String getArtifactId()
+ {
+ return artifact.getArtifactId();
+ }
+
+ public String getBaseVersion()
+ {
+ // Don't want the artifact's version in here, as this is stored in the directory above that
+ return null;
+ }
+
+ public Object getKey()
+ {
+ return "artifact " + artifact.getGroupId() + ":" + artifact.getArtifactId();
+ }
+
+ public boolean isSnapshot()
+ {
+ // Don't consider the artifact's version in here, as this is stored in the directory above that
+ return false;
+ }
+
+ public int getNature()
+ {
+ if ( artifact.getVersion() != null )
+ {
+ return artifact.isSnapshot() ? SNAPSHOT : RELEASE;
+ }
+
+ VersionRange range = artifact.getVersionRange();
+ if ( range != null )
+ {
+ for ( Restriction restriction : range.getRestrictions() )
+ {
+ if ( isSnapshot( restriction.getLowerBound() ) || isSnapshot( restriction.getUpperBound() ) )
+ {
+ return RELEASE_OR_SNAPSHOT;
+ }
+ }
+ }
+
+ return RELEASE;
+ }
+
+ private boolean isSnapshot( ArtifactVersion version )
+ {
+ return version != null && ArtifactUtils.isSnapshot( version.getQualifier() );
+ }
+
+ public ArtifactRepository getRepository()
+ {
+ return null;
+ }
+
+ public void setRepository( ArtifactRepository remoteRepository )
+ {
+ /*
+ * NOTE: Metadata at the g:a level contains a collection of available versions. After merging, we can't tell
+ * which repository provides which version so the metadata manager must not restrict the artifact resolution to
+ * the repository with the most recent updates.
+ */
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/repository/metadata/RepositoryMetadata.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/repository/metadata/RepositoryMetadata.java
new file mode 100644
index 00000000..22e3ade8
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/repository/metadata/RepositoryMetadata.java
@@ -0,0 +1,92 @@
+package org.apache.maven.artifact.repository.metadata;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy;
+
+/**
+ * Describes repository directory metadata.
+ *
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ * @todo not happy about the store method - they use "this"
+ */
+public interface RepositoryMetadata
+ extends org.apache.maven.artifact.metadata.ArtifactMetadata
+{
+
+ int RELEASE = 1;
+
+ int SNAPSHOT = 2;
+
+ int RELEASE_OR_SNAPSHOT = RELEASE | SNAPSHOT;
+
+ /**
+ * Get the repository the metadata was located in.
+ *
+ * @return the repository
+ */
+ ArtifactRepository getRepository();
+
+ /**
+ * Set the repository the metadata was located in.
+ *
+ * @param remoteRepository the repository
+ */
+ void setRepository( ArtifactRepository remoteRepository );
+
+ /**
+ * Get the repository metadata associated with this marker.
+ *
+ * @return the metadata, or <code>null</code> if none loaded
+ */
+ Metadata getMetadata();
+
+ /**
+ * Set the metadata contents.
+ *
+ * @param metadata the metadata
+ */
+ void setMetadata( Metadata metadata );
+
+ /**
+ * Whether this represents a snapshot.
+ *
+ * @return if it is a snapshot
+ */
+ boolean isSnapshot();
+
+ /**
+ * Gets the artifact quality this metadata refers to. One of {@link #RELEASE}, {@link #SNAPSHOT} or
+ * {@link #RELEASE_OR_SNAPSHOT}.
+ *
+ * @return The artifact quality this metadata refers to.
+ */
+ int getNature();
+
+ /**
+ * Gets the policy that applies to this metadata regarding the specified repository.
+ *
+ * @param repository The repository for which to determine the policy, must not be {@code null}.
+ * @return The policy, never {@code null}.
+ */
+ ArtifactRepositoryPolicy getPolicy( ArtifactRepository repository );
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/repository/metadata/RepositoryMetadataDeploymentException.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/repository/metadata/RepositoryMetadataDeploymentException.java
new file mode 100644
index 00000000..94545650
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/repository/metadata/RepositoryMetadataDeploymentException.java
@@ -0,0 +1,40 @@
+package org.apache.maven.artifact.repository.metadata;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Error while deploying repository metadata.
+ *
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ */
+public class RepositoryMetadataDeploymentException
+ extends Throwable
+{
+ public RepositoryMetadataDeploymentException( String message )
+ {
+ super( message );
+ }
+
+ public RepositoryMetadataDeploymentException( String message,
+ Exception e )
+ {
+ super( message, e );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/repository/metadata/RepositoryMetadataInstallationException.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/repository/metadata/RepositoryMetadataInstallationException.java
new file mode 100644
index 00000000..55bb57ed
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/repository/metadata/RepositoryMetadataInstallationException.java
@@ -0,0 +1,40 @@
+package org.apache.maven.artifact.repository.metadata;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Error while installing repository metadata.
+ *
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ */
+public class RepositoryMetadataInstallationException
+ extends Throwable
+{
+ public RepositoryMetadataInstallationException( String message )
+ {
+ super( message );
+ }
+
+ public RepositoryMetadataInstallationException( String message,
+ Exception e )
+ {
+ super( message, e );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/repository/metadata/RepositoryMetadataManager.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/repository/metadata/RepositoryMetadataManager.java
new file mode 100644
index 00000000..35626e58
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/repository/metadata/RepositoryMetadataManager.java
@@ -0,0 +1,61 @@
+package org.apache.maven.artifact.repository.metadata;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.List;
+
+import org.apache.maven.artifact.metadata.ArtifactMetadata;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.repository.RepositoryRequest;
+
+public interface RepositoryMetadataManager
+{
+
+ void resolve( RepositoryMetadata repositoryMetadata, RepositoryRequest repositoryRequest )
+ throws RepositoryMetadataResolutionException;
+
+ void resolve( RepositoryMetadata repositoryMetadata, List<ArtifactRepository> repositories,
+ ArtifactRepository localRepository )
+ throws RepositoryMetadataResolutionException;
+
+ void resolveAlways( RepositoryMetadata metadata, ArtifactRepository localRepository,
+ ArtifactRepository remoteRepository )
+ throws RepositoryMetadataResolutionException;
+
+ /**
+ * Deploy metadata to the remote repository.
+ *
+ * @param metadata the metadata to deploy
+ * @param localRepository the local repository to install to first
+ * @param deploymentRepository the remote repository to deploy to
+ */
+ void deploy( ArtifactMetadata metadata, ArtifactRepository localRepository,
+ ArtifactRepository deploymentRepository )
+ throws RepositoryMetadataDeploymentException;
+
+ /**
+ * Install the metadata in the local repository.
+ *
+ * @param metadata the metadata
+ * @param localRepository the local repository
+ */
+ void install( ArtifactMetadata metadata, ArtifactRepository localRepository )
+ throws RepositoryMetadataInstallationException;
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/repository/metadata/RepositoryMetadataResolutionException.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/repository/metadata/RepositoryMetadataResolutionException.java
new file mode 100644
index 00000000..8a6f38d4
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/repository/metadata/RepositoryMetadataResolutionException.java
@@ -0,0 +1,40 @@
+package org.apache.maven.artifact.repository.metadata;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Error while retrieving repository metadata from the repository.
+ *
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ */
+public class RepositoryMetadataResolutionException
+ extends Exception
+{
+ public RepositoryMetadataResolutionException( String message )
+ {
+ super( message );
+ }
+
+ public RepositoryMetadataResolutionException( String message,
+ Exception e )
+ {
+ super( message, e );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/repository/metadata/io/DefaultMetadataReader.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/repository/metadata/io/DefaultMetadataReader.java
new file mode 100644
index 00000000..6a1578d8
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/repository/metadata/io/DefaultMetadataReader.java
@@ -0,0 +1,110 @@
+package org.apache.maven.artifact.repository.metadata.io;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.util.Map;
+
+import org.apache.maven.artifact.repository.metadata.Metadata;
+import org.apache.maven.artifact.repository.metadata.io.xpp3.MetadataXpp3Reader;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.util.IOUtil;
+import org.codehaus.plexus.util.ReaderFactory;
+import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
+
+/**
+ * Handles deserialization of metadata from some kind of textual format like XML.
+ *
+ * @author Benjamin Bentmann
+ */
+@Component( role = MetadataReader.class )
+public class DefaultMetadataReader
+ implements MetadataReader
+{
+
+ public Metadata read( File input, Map<String, ?> options )
+ throws IOException
+ {
+ if ( input == null )
+ {
+ throw new IllegalArgumentException( "input file missing" );
+ }
+
+ Metadata metadata = read( ReaderFactory.newXmlReader( input ), options );
+
+ return metadata;
+ }
+
+ public Metadata read( Reader input, Map<String, ?> options )
+ throws IOException
+ {
+ if ( input == null )
+ {
+ throw new IllegalArgumentException( "input reader missing" );
+ }
+
+ try
+ {
+ MetadataXpp3Reader r = new MetadataXpp3Reader();
+ return r.read( input, isStrict( options ) );
+ }
+ catch ( XmlPullParserException e )
+ {
+ throw new MetadataParseException( e.getMessage(), e.getLineNumber(), e.getColumnNumber(), e );
+ }
+ finally
+ {
+ IOUtil.close( input );
+ }
+ }
+
+ public Metadata read( InputStream input, Map<String, ?> options )
+ throws IOException
+ {
+ if ( input == null )
+ {
+ throw new IllegalArgumentException( "input stream missing" );
+ }
+
+ try
+ {
+ MetadataXpp3Reader r = new MetadataXpp3Reader();
+ return r.read( input, isStrict( options ) );
+ }
+ catch ( XmlPullParserException e )
+ {
+ throw new MetadataParseException( e.getMessage(), e.getLineNumber(), e.getColumnNumber(), e );
+ }
+ finally
+ {
+ IOUtil.close( input );
+ }
+ }
+
+ private boolean isStrict( Map<String, ?> options )
+ {
+ Object value = ( options != null ) ? options.get( IS_STRICT ) : null;
+ return value == null || Boolean.parseBoolean( value.toString() );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/repository/metadata/io/MetadataParseException.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/repository/metadata/io/MetadataParseException.java
new file mode 100644
index 00000000..e3e141b1
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/repository/metadata/io/MetadataParseException.java
@@ -0,0 +1,93 @@
+package org.apache.maven.artifact.repository.metadata.io;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.IOException;
+
+/**
+ * Signals a failure to parse the metadata due to invalid syntax (e.g. non-wellformed XML or unknown elements).
+ *
+ * @author Benjamin Bentmann
+ */
+public class MetadataParseException
+ extends IOException
+{
+
+ /**
+ * The one-based index of the line containing the error.
+ */
+ private final int lineNumber;
+
+ /**
+ * The one-based index of the column containing the error.
+ */
+ private final int columnNumber;
+
+ /**
+ * Creates a new parser exception with the specified details.
+ *
+ * @param message The error message, may be {@code null}.
+ * @param lineNumber The one-based index of the line containing the error or {@code -1} if unknown.
+ * @param columnNumber The one-based index of the column containing the error or {@code -1} if unknown.
+ */
+ public MetadataParseException( String message, int lineNumber, int columnNumber )
+ {
+ super( message );
+ this.lineNumber = lineNumber;
+ this.columnNumber = columnNumber;
+ }
+
+ /**
+ * Creates a new parser exception with the specified details.
+ *
+ * @param message The error message, may be {@code null}.
+ * @param lineNumber The one-based index of the line containing the error or {@code -1} if unknown.
+ * @param columnNumber The one-based index of the column containing the error or {@code -1} if unknown.
+ * @param cause The nested cause of this error, may be {@code null}.
+ */
+ public MetadataParseException( String message, int lineNumber, int columnNumber, Throwable cause )
+ {
+ super( message );
+ initCause( cause );
+ this.lineNumber = lineNumber;
+ this.columnNumber = columnNumber;
+ }
+
+ /**
+ * Gets the one-based index of the line containing the error.
+ *
+ * @return The one-based index of the line containing the error or a non-positive value if unknown.
+ */
+ public int getLineNumber()
+ {
+ return lineNumber;
+ }
+
+ /**
+ * Gets the one-based index of the column containing the error.
+ *
+ * @return The one-based index of the column containing the error or non-positive value if unknown.
+ */
+ public int getColumnNumber()
+ {
+ return columnNumber;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/repository/metadata/io/MetadataReader.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/repository/metadata/io/MetadataReader.java
new file mode 100644
index 00000000..232246fd
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/repository/metadata/io/MetadataReader.java
@@ -0,0 +1,82 @@
+package org.apache.maven.artifact.repository.metadata.io;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.util.Map;
+
+import org.apache.maven.artifact.repository.metadata.Metadata;
+
+/**
+ * Handles deserialization of metadata from some kind of textual format like XML.
+ *
+ * @author Benjamin Bentmann
+ */
+public interface MetadataReader
+{
+
+ /**
+ * The key for the option to enable strict parsing. This option is of type {@link Boolean} and defaults to {@code
+ * true}. If {@code false}, unknown elements will be ignored instead of causing a failure.
+ */
+ String IS_STRICT = "org.apache.maven.artifact.repository.metadata.io.isStrict";
+
+ /**
+ * Reads the metadata from the specified file.
+ *
+ * @param input The file to deserialize the metadata from, must not be {@code null}.
+ * @param options The options to use for deserialization, may be {@code null} to use the default values.
+ * @return The deserialized metadata, never {@code null}.
+ * @throws IOException If the metadata could not be deserialized.
+ * @throws MetadataParseException If the input format could not be parsed.
+ */
+ Metadata read( File input, Map<String, ?> options )
+ throws IOException, MetadataParseException;
+
+ /**
+ * Reads the metadata from the specified character reader. The reader will be automatically closed before the method
+ * returns.
+ *
+ * @param input The reader to deserialize the metadata from, must not be {@code null}.
+ * @param options The options to use for deserialization, may be {@code null} to use the default values.
+ * @return The deserialized metadata, never {@code null}.
+ * @throws IOException If the metadata could not be deserialized.
+ * @throws MetadataParseException If the input format could not be parsed.
+ */
+ Metadata read( Reader input, Map<String, ?> options )
+ throws IOException, MetadataParseException;
+
+ /**
+ * Reads the metadata from the specified byte stream. The stream will be automatically closed before the method
+ * returns.
+ *
+ * @param input The stream to deserialize the metadata from, must not be {@code null}.
+ * @param options The options to use for deserialization, may be {@code null} to use the default values.
+ * @return The deserialized metadata, never {@code null}.
+ * @throws IOException If the metadata could not be deserialized.
+ * @throws MetadataParseException If the input format could not be parsed.
+ */
+ Metadata read( InputStream input, Map<String, ?> options )
+ throws IOException, MetadataParseException;
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/resolver/ArtifactResolutionRequest.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/resolver/ArtifactResolutionRequest.java
new file mode 100644
index 00000000..050ec478
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/resolver/ArtifactResolutionRequest.java
@@ -0,0 +1,329 @@
+package org.apache.maven.artifact.resolver;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.repository.RepositoryCache;
+import org.apache.maven.artifact.repository.RepositoryRequest;
+import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
+import org.apache.maven.settings.Mirror;
+import org.apache.maven.settings.Proxy;
+import org.apache.maven.settings.Server;
+
+/**
+ * A resolution request allows you to either use an existing MavenProject, or a coordinate (gid:aid:version)
+ * to process a POMs dependencies.
+ *
+ * @author Jason van Zyl
+ */
+public class ArtifactResolutionRequest
+ implements RepositoryRequest
+{
+
+ private Artifact artifact;
+
+ // Needs to go away
+ // These are really overrides now, projects defining dependencies for a plugin that override what is
+ // specified in the plugin itself.
+ private Set<Artifact> artifactDependencies;
+
+ private ArtifactRepository localRepository;
+
+ private List<ArtifactRepository> remoteRepositories;
+
+ private ArtifactFilter collectionFilter;
+
+ private ArtifactFilter resolutionFilter;
+
+ // Needs to go away
+ private List<ResolutionListener> listeners = new ArrayList<ResolutionListener>();
+
+ // This is like a filter but overrides all transitive versions
+ private Map<String, Artifact> managedVersionMap;
+
+ private boolean resolveRoot = true;
+
+ private boolean resolveTransitively = false;
+
+ private boolean offline;
+
+ private boolean forceUpdate;
+
+ private List<Server> servers;
+
+ private List<Mirror> mirrors;
+
+ private List<Proxy> proxies;
+
+ public ArtifactResolutionRequest()
+ {
+ // nothing here
+ }
+
+ public ArtifactResolutionRequest( RepositoryRequest request )
+ {
+ setLocalRepository( request.getLocalRepository() );
+ setRemoteRepositories( request.getRemoteRepositories() );
+ setOffline( request.isOffline() );
+ setForceUpdate( request.isForceUpdate() );
+ }
+
+ public Artifact getArtifact()
+ {
+ return artifact;
+ }
+
+ public ArtifactResolutionRequest setArtifact( Artifact artifact )
+ {
+ this.artifact = artifact;
+
+ return this;
+ }
+
+ public ArtifactResolutionRequest setArtifactDependencies( Set<Artifact> artifactDependencies )
+ {
+ this.artifactDependencies = artifactDependencies;
+
+ return this;
+ }
+
+ public Set<Artifact> getArtifactDependencies()
+ {
+ return artifactDependencies;
+ }
+
+ public ArtifactRepository getLocalRepository()
+ {
+ return localRepository;
+ }
+
+ public ArtifactResolutionRequest setLocalRepository( ArtifactRepository localRepository )
+ {
+ this.localRepository = localRepository;
+
+ return this;
+ }
+
+ public List<ArtifactRepository> getRemoteRepositories()
+ {
+ return remoteRepositories;
+ }
+
+ public ArtifactResolutionRequest setRemoteRepositories( List<ArtifactRepository> remoteRepositories )
+ {
+ this.remoteRepositories = remoteRepositories;
+
+ return this;
+ }
+
+ /**
+ * Gets the artifact filter that controls traversal of the dependency graph.
+ *
+ * @return The filter used to determine which of the artifacts in the dependency graph should be traversed or
+ * {@code null} to collect all transitive dependencies.
+ */
+ public ArtifactFilter getCollectionFilter()
+ {
+ return collectionFilter;
+ }
+
+ public ArtifactResolutionRequest setCollectionFilter( ArtifactFilter filter )
+ {
+ this.collectionFilter = filter;
+
+ return this;
+ }
+
+ /**
+ * Gets the artifact filter that controls downloading of artifact files. This filter operates on those artifacts
+ * that have been included by the {@link #getCollectionFilter()}.
+ *
+ * @return The filter used to determine which of the artifacts should have their files resolved or {@code null} to
+ * resolve the files for all collected artifacts.
+ */
+ public ArtifactFilter getResolutionFilter()
+ {
+ return resolutionFilter;
+ }
+
+ public ArtifactResolutionRequest setResolutionFilter( ArtifactFilter filter )
+ {
+ this.resolutionFilter = filter;
+
+ return this;
+ }
+
+ public List<ResolutionListener> getListeners()
+ {
+ return listeners;
+ }
+
+ public ArtifactResolutionRequest setListeners( List<ResolutionListener> listeners )
+ {
+ this.listeners = listeners;
+
+ return this;
+ }
+
+ public ArtifactResolutionRequest addListener( ResolutionListener listener )
+ {
+ listeners.add( listener );
+
+ return this;
+ }
+
+ public Map<String, Artifact> getManagedVersionMap()
+ {
+ return managedVersionMap;
+ }
+
+ public ArtifactResolutionRequest setManagedVersionMap( Map<String, Artifact> managedVersionMap )
+ {
+ this.managedVersionMap = managedVersionMap;
+
+ return this;
+ }
+
+ public ArtifactResolutionRequest setResolveRoot( boolean resolveRoot )
+ {
+ this.resolveRoot = resolveRoot;
+
+ return this;
+ }
+
+ public boolean isResolveRoot()
+ {
+ return resolveRoot;
+ }
+
+ public ArtifactResolutionRequest setResolveTransitively( boolean resolveDependencies )
+ {
+ this.resolveTransitively = resolveDependencies;
+
+ return this;
+ }
+
+ public boolean isResolveTransitively()
+ {
+ return resolveTransitively;
+ }
+
+ public String toString()
+ {
+ StringBuilder sb = new StringBuilder()
+ .append( "REQUEST: " ).append( "\n" )
+ .append( "artifact: " ).append( artifact ).append( "\n" )
+ .append( artifactDependencies ).append( "\n" )
+ .append( "localRepository: " ).append( localRepository ).append( "\n" )
+ .append( "remoteRepositories: " ).append( remoteRepositories ).append( "\n" );
+
+ return sb.toString();
+ }
+
+ public boolean isOffline()
+ {
+ return offline;
+ }
+
+ public ArtifactResolutionRequest setOffline( boolean offline )
+ {
+ this.offline = offline;
+
+ return this;
+ }
+
+ public boolean isForceUpdate()
+ {
+ return forceUpdate;
+ }
+
+ public ArtifactResolutionRequest setForceUpdate( boolean forceUpdate )
+ {
+ this.forceUpdate = forceUpdate;
+
+ return this;
+ }
+
+ public ArtifactResolutionRequest setServers( List<Server> servers )
+ {
+ this.servers = servers;
+
+ return this;
+ }
+
+ public List<Server> getServers()
+ {
+ if ( servers == null )
+ {
+ servers = new ArrayList<Server>();
+ }
+
+ return servers;
+ }
+
+ public ArtifactResolutionRequest setMirrors( List<Mirror> mirrors )
+ {
+ this.mirrors = mirrors;
+
+ return this;
+ }
+
+ public List<Mirror> getMirrors()
+ {
+ if ( mirrors == null )
+ {
+ mirrors = new ArrayList<Mirror>();
+ }
+
+ return mirrors;
+ }
+
+ public ArtifactResolutionRequest setProxies( List<Proxy> proxies )
+ {
+ this.proxies = proxies;
+
+ return this;
+ }
+
+ public List<Proxy> getProxies()
+ {
+ if ( proxies == null )
+ {
+ proxies = new ArrayList<Proxy>();
+ }
+
+ return proxies;
+ }
+
+ //
+ // Used by Tycho and will break users and force them to upgrade to Maven 3.1 so we should really leave
+ // this here, possibly indefinitely.
+ //
+ public ArtifactResolutionRequest setCache( RepositoryCache cache )
+ {
+ return this;
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/resolver/ArtifactResolutionResult.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/resolver/ArtifactResolutionResult.java
new file mode 100644
index 00000000..86bfdb60
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/resolver/ArtifactResolutionResult.java
@@ -0,0 +1,358 @@
+package org.apache.maven.artifact.resolver;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.versioning.OverConstrainedVersionException;
+
+/**
+ * Specific problems during resolution that we want to account for:
+ * <p/>
+ * - missing metadata - version range violations - version circular dependencies - missing artifacts
+ * - network/transfer errors - file system errors: permissions
+ *
+ * @author Jason van Zyl
+ * @TODO carlos: all these possible has*Exceptions and get*Exceptions methods make the clients too
+ * complex requiring a long list of checks, need to create a parent/interfact/encapsulation
+ * for the types of exceptions
+ */
+public class ArtifactResolutionResult
+{
+ private Artifact originatingArtifact;
+
+ private List<Artifact> missingArtifacts;
+
+ // Exceptions
+
+ private List<Exception> exceptions;
+
+ private List<Exception> versionRangeViolations;
+
+ private List<ArtifactResolutionException> metadataResolutionExceptions;
+
+ private List<CyclicDependencyException> circularDependencyExceptions;
+
+ private List<ArtifactResolutionException> errorArtifactExceptions;
+
+ // file system errors
+
+ private List<ArtifactRepository> repositories;
+
+ private Set<Artifact> artifacts;
+
+ private Set<ResolutionNode> resolutionNodes;
+
+ public Artifact getOriginatingArtifact()
+ {
+ return originatingArtifact;
+ }
+
+ public ArtifactResolutionResult setOriginatingArtifact( final Artifact originatingArtifact )
+ {
+ this.originatingArtifact = originatingArtifact;
+
+ return this;
+ }
+
+ public void addArtifact( Artifact artifact )
+ {
+ if ( artifacts == null )
+ {
+ artifacts = new LinkedHashSet<Artifact>();
+ }
+
+ artifacts.add( artifact );
+ }
+
+ public Set<Artifact> getArtifacts()
+ {
+ if ( artifacts == null )
+ {
+ artifacts = new LinkedHashSet<Artifact>();
+ }
+
+ return artifacts;
+ }
+
+ public void setArtifacts( Set<Artifact> artifacts )
+ {
+ this.artifacts = artifacts;
+ }
+
+ public Set<ResolutionNode> getArtifactResolutionNodes()
+ {
+ if ( resolutionNodes == null )
+ {
+ resolutionNodes = new LinkedHashSet<ResolutionNode>();
+ }
+
+ return resolutionNodes;
+ }
+
+ public void setArtifactResolutionNodes( Set<ResolutionNode> resolutionNodes )
+ {
+ this.resolutionNodes = resolutionNodes;
+ }
+
+ public boolean hasMissingArtifacts()
+ {
+ return missingArtifacts != null && !missingArtifacts.isEmpty();
+ }
+
+ public List<Artifact> getMissingArtifacts()
+ {
+ return missingArtifacts == null ? Collections.<Artifact>emptyList() : missingArtifacts;
+ }
+
+ public ArtifactResolutionResult addMissingArtifact( Artifact artifact )
+ {
+ missingArtifacts = initList( missingArtifacts );
+
+ missingArtifacts.add( artifact );
+
+ return this;
+ }
+
+ public ArtifactResolutionResult setUnresolvedArtifacts( final List<Artifact> unresolvedArtifacts )
+ {
+ this.missingArtifacts = unresolvedArtifacts;
+
+ return this;
+ }
+
+ public boolean isSuccess()
+ {
+ return !( hasMissingArtifacts() || hasExceptions() );
+ }
+
+ // ------------------------------------------------------------------------
+ // Exceptions
+ // ------------------------------------------------------------------------
+
+ public boolean hasExceptions()
+ {
+ return exceptions != null && !exceptions.isEmpty();
+ }
+
+ public List<Exception> getExceptions()
+ {
+ return exceptions == null ? Collections.<Exception>emptyList() : exceptions;
+ }
+
+ // ------------------------------------------------------------------------
+ // Version Range Violations
+ // ------------------------------------------------------------------------
+
+ public boolean hasVersionRangeViolations()
+ {
+ return versionRangeViolations != null;
+ }
+
+ /**
+ * @TODO this needs to accept a {@link OverConstrainedVersionException} as returned by
+ * {@link #getVersionRangeViolation(int)} but it's not used like that in
+ * {@link DefaultLegacyArtifactCollector}
+ */
+ public ArtifactResolutionResult addVersionRangeViolation( Exception e )
+ {
+ versionRangeViolations = initList( versionRangeViolations );
+
+ versionRangeViolations.add( e );
+
+ exceptions = initList( exceptions );
+
+ exceptions.add( e );
+
+ return this;
+ }
+
+ public OverConstrainedVersionException getVersionRangeViolation( int i )
+ {
+ return (OverConstrainedVersionException) versionRangeViolations.get( i );
+ }
+
+ public List<Exception> getVersionRangeViolations()
+ {
+ return versionRangeViolations == null ? Collections.<Exception>emptyList() : versionRangeViolations;
+ }
+
+ // ------------------------------------------------------------------------
+ // Metadata Resolution Exceptions: ArtifactResolutionExceptions
+ // ------------------------------------------------------------------------
+
+ public boolean hasMetadataResolutionExceptions()
+ {
+ return metadataResolutionExceptions != null;
+ }
+
+ public ArtifactResolutionResult addMetadataResolutionException( ArtifactResolutionException e )
+ {
+ metadataResolutionExceptions = initList( metadataResolutionExceptions );
+
+ metadataResolutionExceptions.add( e );
+
+ exceptions = initList( exceptions );
+
+ exceptions.add( e );
+
+ return this;
+ }
+
+ public ArtifactResolutionException getMetadataResolutionException( int i )
+ {
+ return metadataResolutionExceptions.get( i );
+ }
+
+ public List<ArtifactResolutionException> getMetadataResolutionExceptions()
+ {
+ return metadataResolutionExceptions == null ? Collections.<ArtifactResolutionException>emptyList()
+ : metadataResolutionExceptions;
+ }
+
+ // ------------------------------------------------------------------------
+ // ErrorArtifactExceptions: ArtifactResolutionExceptions
+ // ------------------------------------------------------------------------
+
+ public boolean hasErrorArtifactExceptions()
+ {
+ return errorArtifactExceptions != null;
+ }
+
+ public ArtifactResolutionResult addErrorArtifactException( ArtifactResolutionException e )
+ {
+ errorArtifactExceptions = initList( errorArtifactExceptions );
+
+ errorArtifactExceptions.add( e );
+
+ exceptions = initList( exceptions );
+
+ exceptions.add( e );
+
+ return this;
+ }
+
+ public List<ArtifactResolutionException> getErrorArtifactExceptions()
+ {
+ if ( errorArtifactExceptions == null )
+ {
+ return Collections.emptyList();
+ }
+
+ return errorArtifactExceptions;
+ }
+
+ // ------------------------------------------------------------------------
+ // Circular Dependency Exceptions
+ // ------------------------------------------------------------------------
+
+ public boolean hasCircularDependencyExceptions()
+ {
+ return circularDependencyExceptions != null;
+ }
+
+ public ArtifactResolutionResult addCircularDependencyException( CyclicDependencyException e )
+ {
+ circularDependencyExceptions = initList( circularDependencyExceptions );
+
+ circularDependencyExceptions.add( e );
+
+ exceptions = initList( exceptions );
+
+ exceptions.add( e );
+
+ return this;
+ }
+
+ public CyclicDependencyException getCircularDependencyException( int i )
+ {
+ return circularDependencyExceptions.get( i );
+ }
+
+ public List<CyclicDependencyException> getCircularDependencyExceptions()
+ {
+ if ( circularDependencyExceptions == null )
+ {
+ return Collections.emptyList();
+ }
+
+ return circularDependencyExceptions;
+ }
+
+ // ------------------------------------------------------------------------
+ // Repositories
+ // ------------------------------------------------------------------------
+
+ public List<ArtifactRepository> getRepositories()
+ {
+ if ( repositories == null )
+ {
+ return Collections.emptyList();
+ }
+
+ return repositories;
+ }
+
+ public ArtifactResolutionResult setRepositories( final List<ArtifactRepository> repositories )
+ {
+ this.repositories = repositories;
+
+ return this;
+ }
+
+ //
+ // Internal
+ //
+
+ private <T> List<T> initList( final List<T> l )
+ {
+ if ( l == null )
+ {
+ return new ArrayList<T>();
+ }
+ return l;
+ }
+
+ public String toString()
+ {
+ StringBuilder sb = new StringBuilder();
+
+ if ( artifacts != null )
+ {
+ int i = 1;
+ sb.append( "---------" ).append( "\n" );
+ sb.append( artifacts.size() ).append( "\n" );
+ for ( Artifact a : artifacts )
+ {
+ sb.append( i ).append( " " ).append( a ).append( "\n" );
+ i++;
+ }
+ sb.append( "---------" ).append( "\n" );
+ }
+
+ return sb.toString();
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/resolver/DefaultResolutionErrorHandler.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/resolver/DefaultResolutionErrorHandler.java
new file mode 100644
index 00000000..a8caa79b
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/resolver/DefaultResolutionErrorHandler.java
@@ -0,0 +1,89 @@
+package org.apache.maven.artifact.resolver;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.codehaus.plexus.component.annotations.Component;
+
+/**
+ * @author Benjamin Bentmann
+ */
+@Component( role = ResolutionErrorHandler.class )
+public class DefaultResolutionErrorHandler
+ implements ResolutionErrorHandler
+{
+
+ public void throwErrors( ArtifactResolutionRequest request, ArtifactResolutionResult result )
+ throws ArtifactResolutionException
+ {
+ // Metadata cannot be found
+
+ if ( result.hasMetadataResolutionExceptions() )
+ {
+ throw result.getMetadataResolutionException( 0 );
+ }
+
+ // Metadata cannot be retrieved
+
+ // Cyclic Dependency Error
+
+ if ( result.hasCircularDependencyExceptions() )
+ {
+ throw result.getCircularDependencyException( 0 );
+ }
+
+ // Version Range Violation
+
+ if ( result.hasVersionRangeViolations() )
+ {
+ throw result.getVersionRangeViolation( 0 );
+ }
+
+ // Transfer Error
+
+ if ( result.hasErrorArtifactExceptions() )
+ {
+ throw result.getErrorArtifactExceptions().get( 0 );
+ }
+
+ if ( result.hasMissingArtifacts() )
+ {
+ throw new MultipleArtifactsNotFoundException( request.getArtifact(), toList( result.getArtifacts() ),
+ result.getMissingArtifacts(),
+ request.getRemoteRepositories() );
+ }
+
+ // this should never happen since we checked all possible error sources before but better be sure
+ if ( result.hasExceptions() )
+ {
+ throw new ArtifactResolutionException( "Unknown error during artifact resolution, " + request + ", "
+ + result.getExceptions(), request.getArtifact(), request.getRemoteRepositories() );
+ }
+ }
+
+ private static <T> List<T> toList( Collection<T> items )
+ {
+ return ( items != null ) ? new ArrayList<T>( items ) : null;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/resolver/ResolutionErrorHandler.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/resolver/ResolutionErrorHandler.java
new file mode 100644
index 00000000..c54e5b6c
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/resolver/ResolutionErrorHandler.java
@@ -0,0 +1,31 @@
+package org.apache.maven.artifact.resolver;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * @author Benjamin Bentmann
+ */
+public interface ResolutionErrorHandler
+{
+
+ void throwErrors( ArtifactResolutionRequest request, ArtifactResolutionResult result )
+ throws ArtifactResolutionException;
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/resolver/ResolutionListener.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/resolver/ResolutionListener.java
new file mode 100644
index 00000000..97687de2
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/resolver/ResolutionListener.java
@@ -0,0 +1,109 @@
+package org.apache.maven.artifact.resolver;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.versioning.VersionRange;
+
+/**
+ * Listens to the resolution process and handles events.
+ *
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ */
+public interface ResolutionListener
+{
+ String ROLE = ResolutionListener.class.getName();
+
+ int TEST_ARTIFACT = 1;
+
+ int PROCESS_CHILDREN = 2;
+
+ int FINISH_PROCESSING_CHILDREN = 3;
+
+ int INCLUDE_ARTIFACT = 4;
+
+ int OMIT_FOR_NEARER = 5;
+
+ int UPDATE_SCOPE = 6;
+
+ @Deprecated
+ int MANAGE_ARTIFACT = 7;
+
+ int OMIT_FOR_CYCLE = 8;
+
+ /**
+ * this event means that the artifactScope has NOT been updated to a farther node artifactScope because current
+ * node is in the first level pom
+ */
+ int UPDATE_SCOPE_CURRENT_POM = 9;
+
+ int SELECT_VERSION_FROM_RANGE = 10;
+
+ int RESTRICT_RANGE = 11;
+
+ int MANAGE_ARTIFACT_VERSION = 12;
+
+ int MANAGE_ARTIFACT_SCOPE = 13;
+
+ int MANAGE_ARTIFACT_SYSTEM_PATH = 14;
+
+ void testArtifact( Artifact node );
+
+ void startProcessChildren( Artifact artifact );
+
+ void endProcessChildren( Artifact artifact );
+
+ void includeArtifact( Artifact artifact );
+
+ void omitForNearer( Artifact omitted,
+ Artifact kept );
+
+ void updateScope( Artifact artifact,
+ String scope );
+
+ @Deprecated
+ void manageArtifact( Artifact artifact,
+ Artifact replacement );
+
+ // TODO Use the following two instead of manageArtifact
+ // TODO Remove ResolutionListenerDM interface
+
+ //void manageArtifactVersion( Artifact artifact, Artifact replacement );
+
+ //void manageArtifactScope( Artifact artifact, Artifact replacement );
+
+ void omitForCycle( Artifact artifact );
+
+ /**
+ * This event means that the artifactScope has NOT been updated to a farther node artifactScope because current
+ * node is in the first level pom
+ *
+ * @param artifact current node artifact, the one in the first level pom
+ * @param ignoredScope artifactScope that was ignored because artifact was in first level pom
+ */
+ void updateScopeCurrentPom( Artifact artifact,
+ String ignoredScope );
+
+ void selectVersionFromRange( Artifact artifact );
+
+ void restrictRange( Artifact artifact,
+ Artifact replacement,
+ VersionRange newRange );
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/resolver/ResolutionNode.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/resolver/ResolutionNode.java
new file mode 100644
index 00000000..ae6c9214
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/resolver/ResolutionNode.java
@@ -0,0 +1,251 @@
+package org.apache.maven.artifact.resolver;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
+import org.apache.maven.artifact.versioning.ArtifactVersion;
+import org.apache.maven.artifact.versioning.OverConstrainedVersionException;
+
+public class ResolutionNode
+{
+ private Artifact artifact;
+
+ private List<ResolutionNode> children;
+
+ private final List<Object> parents;
+
+ private final int depth;
+
+ private final ResolutionNode parent;
+
+ private final List<ArtifactRepository> remoteRepositories;
+
+ private boolean active = true;
+
+ private List<Artifact> trail;
+
+ public ResolutionNode( Artifact artifact, List<ArtifactRepository> remoteRepositories )
+ {
+ this.artifact = artifact;
+ this.remoteRepositories = remoteRepositories;
+ depth = 0;
+ parents = Collections.emptyList();
+ parent = null;
+ }
+
+ public ResolutionNode( Artifact artifact, List<ArtifactRepository> remoteRepositories, ResolutionNode parent )
+ {
+ this.artifact = artifact;
+ this.remoteRepositories = remoteRepositories;
+ depth = parent.depth + 1;
+ parents = new ArrayList<Object>();
+ parents.addAll( parent.parents );
+ parents.add( parent.getKey() );
+ this.parent = parent;
+ }
+
+ public Artifact getArtifact()
+ {
+ return artifact;
+ }
+
+ public Object getKey()
+ {
+ return artifact.getDependencyConflictId();
+ }
+
+ public void addDependencies( Set<Artifact> artifacts, List<ArtifactRepository> remoteRepositories,
+ ArtifactFilter filter )
+ throws CyclicDependencyException, OverConstrainedVersionException
+ {
+ if ( artifacts != null && !artifacts.isEmpty() )
+ {
+ children = new ArrayList<ResolutionNode>( artifacts.size() );
+
+ for ( Artifact a : artifacts )
+ {
+ if ( parents.contains( a.getDependencyConflictId() ) )
+ {
+ a.setDependencyTrail( getDependencyTrail() );
+
+ throw new CyclicDependencyException( "A dependency has introduced a cycle", a );
+ }
+
+ children.add( new ResolutionNode( a, remoteRepositories, this ) );
+ }
+ }
+ else
+ {
+ children = Collections.emptyList();
+ }
+ trail = null;
+ }
+
+ /**
+ * @return {@link List} &lt; {@link String} > with artifact ids
+ * @throws OverConstrainedVersionException
+ */
+ public List<String> getDependencyTrail()
+ throws OverConstrainedVersionException
+ {
+ List<Artifact> trial = getTrail();
+
+ List<String> ret = new ArrayList<String>( trial.size() );
+
+ for ( Artifact artifact : trial )
+ {
+ ret.add( artifact.getId() );
+ }
+
+ return ret;
+ }
+
+ private List<Artifact> getTrail()
+ throws OverConstrainedVersionException
+ {
+ if ( trail == null )
+ {
+ List<Artifact> ids = new LinkedList<Artifact>();
+ ResolutionNode node = this;
+ while ( node != null )
+ {
+ Artifact artifact = node.getArtifact();
+ if ( artifact.getVersion() == null )
+ {
+ // set the recommended version
+ ArtifactVersion selected = artifact.getSelectedVersion();
+ // MNG-2123: null is a valid response to getSelectedVersion, don't
+ // assume it won't ever be.
+ if ( selected != null )
+ {
+ artifact.selectVersion( selected.toString() );
+ }
+ else
+ {
+ throw new OverConstrainedVersionException( "Unable to get a selected Version for "
+ + artifact.getArtifactId(), artifact );
+ }
+ }
+
+ ids.add( 0, artifact );
+ node = node.parent;
+ }
+ trail = ids;
+ }
+ return trail;
+ }
+
+ public boolean isResolved()
+ {
+ return children != null;
+ }
+
+ /**
+ * Test whether the node is direct or transitive dependency.
+ */
+ public boolean isChildOfRootNode()
+ {
+ return parent != null && parent.parent == null;
+ }
+
+ public Iterator<ResolutionNode> getChildrenIterator()
+ {
+ return children.iterator();
+ }
+
+ public int getDepth()
+ {
+ return depth;
+ }
+
+ public List<ArtifactRepository> getRemoteRepositories()
+ {
+ return remoteRepositories;
+ }
+
+ public boolean isActive()
+ {
+ return active;
+ }
+
+ public void enable()
+ {
+ active = true;
+
+ // TODO: if it was null, we really need to go find them now... or is this taken care of by the ordering?
+ if ( children != null )
+ {
+ for ( ResolutionNode node : children )
+ {
+ node.enable();
+ }
+ }
+ }
+
+ public void disable()
+ {
+ active = false;
+ if ( children != null )
+ {
+ for ( ResolutionNode node : children )
+ {
+ node.disable();
+ }
+ }
+ }
+
+ public boolean filterTrail( ArtifactFilter filter )
+ throws OverConstrainedVersionException
+ {
+ boolean success = true;
+ if ( filter != null )
+ {
+ for ( Artifact artifact : getTrail() )
+ {
+ if ( !filter.include( artifact ) )
+ {
+ success = false;
+ }
+ }
+ }
+ return success;
+ }
+
+ @Override
+ public String toString()
+ {
+ return artifact.toString() + " (" + depth + "; " + ( active ? "enabled" : "disabled" ) + ")";
+ }
+
+ public void setArtifact( Artifact artifact )
+ {
+ this.artifact = artifact;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/resolver/filter/AbstractScopeArtifactFilter.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/resolver/filter/AbstractScopeArtifactFilter.java
new file mode 100644
index 00000000..95872dbb
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/resolver/filter/AbstractScopeArtifactFilter.java
@@ -0,0 +1,107 @@
+package org.apache.maven.artifact.resolver.filter;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.artifact.Artifact;
+
+/**
+ * Filter to only retain objects in the given artifactScope or better.
+ *
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ */
+abstract class AbstractScopeArtifactFilter
+ implements ArtifactFilter
+{
+
+ private boolean compileScope;
+
+ private boolean runtimeScope;
+
+ private boolean testScope;
+
+ private boolean providedScope;
+
+ private boolean systemScope;
+
+ void addScopeInternal( String scope )
+ {
+ if ( Artifact.SCOPE_COMPILE.equals( scope ) )
+ {
+ systemScope = true;
+ providedScope = true;
+ compileScope = true;
+ }
+ else if ( Artifact.SCOPE_RUNTIME.equals( scope ) )
+ {
+ compileScope = true;
+ runtimeScope = true;
+ }
+ else if ( Artifact.SCOPE_COMPILE_PLUS_RUNTIME.equals( scope ) )
+ {
+ systemScope = true;
+ providedScope = true;
+ compileScope = true;
+ runtimeScope = true;
+ }
+ else if ( Artifact.SCOPE_RUNTIME_PLUS_SYSTEM.equals( scope ) )
+ {
+ systemScope = true;
+ compileScope = true;
+ runtimeScope = true;
+ }
+ else if ( Artifact.SCOPE_TEST.equals( scope ) )
+ {
+ systemScope = true;
+ providedScope = true;
+ compileScope = true;
+ runtimeScope = true;
+ testScope = true;
+ }
+ }
+
+ public boolean include( Artifact artifact )
+ {
+ if ( Artifact.SCOPE_COMPILE.equals( artifact.getScope() ) )
+ {
+ return compileScope;
+ }
+ else if ( Artifact.SCOPE_RUNTIME.equals( artifact.getScope() ) )
+ {
+ return runtimeScope;
+ }
+ else if ( Artifact.SCOPE_TEST.equals( artifact.getScope() ) )
+ {
+ return testScope;
+ }
+ else if ( Artifact.SCOPE_PROVIDED.equals( artifact.getScope() ) )
+ {
+ return providedScope;
+ }
+ else if ( Artifact.SCOPE_SYSTEM.equals( artifact.getScope() ) )
+ {
+ return systemScope;
+ }
+ else
+ {
+ return true;
+ }
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/resolver/filter/AndArtifactFilter.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/resolver/filter/AndArtifactFilter.java
new file mode 100644
index 00000000..5c6689de
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/resolver/filter/AndArtifactFilter.java
@@ -0,0 +1,99 @@
+package org.apache.maven.artifact.resolver.filter;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.maven.artifact.Artifact;
+
+/**
+ * Apply multiple filters.
+ *
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ */
+public class AndArtifactFilter
+ implements ArtifactFilter
+{
+ private Set<ArtifactFilter> filters;
+
+ public AndArtifactFilter()
+ {
+ this.filters = new LinkedHashSet<ArtifactFilter>();
+ }
+
+ public AndArtifactFilter( List<ArtifactFilter> filters )
+ {
+ this.filters = new LinkedHashSet<ArtifactFilter>( filters );
+ }
+
+ public boolean include( Artifact artifact )
+ {
+ boolean include = true;
+ for ( Iterator<ArtifactFilter> i = filters.iterator(); i.hasNext() && include; )
+ {
+ ArtifactFilter filter = i.next();
+ if ( !filter.include( artifact ) )
+ {
+ include = false;
+ }
+ }
+ return include;
+ }
+
+ public void add( ArtifactFilter artifactFilter )
+ {
+ filters.add( artifactFilter );
+ }
+
+ public List<ArtifactFilter> getFilters()
+ {
+ return new ArrayList<ArtifactFilter>( filters );
+ }
+
+ @Override
+ public int hashCode()
+ {
+ int hash = 17;
+ hash = hash * 31 + filters.hashCode();
+ return hash;
+ }
+
+ @Override
+ public boolean equals( Object obj )
+ {
+ if ( this == obj )
+ {
+ return true;
+ }
+
+ if ( !( obj instanceof AndArtifactFilter ) )
+ {
+ return false;
+ }
+
+ AndArtifactFilter other = (AndArtifactFilter) obj;
+
+ return filters.equals( other.filters );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/resolver/filter/CumulativeScopeArtifactFilter.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/resolver/filter/CumulativeScopeArtifactFilter.java
new file mode 100644
index 00000000..fb0afcfb
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/resolver/filter/CumulativeScopeArtifactFilter.java
@@ -0,0 +1,122 @@
+package org.apache.maven.artifact.resolver.filter;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Filter to only retain objects in the given scope or better. This implementation allows the accumulation of multiple
+ * scopes and their associated implied scopes, so that the user can filter apply a series of implication rules in a
+ * single step. This should be a more efficient implementation of multiple standard {@link ScopeArtifactFilter}
+ * instances ORed together.
+ *
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ * @author jdcasey
+ */
+public class CumulativeScopeArtifactFilter
+ extends AbstractScopeArtifactFilter
+{
+
+ private Set<String> scopes;
+
+ /**
+ * Create a new filter with the specified scopes and their implied scopes enabled.
+ *
+ * @param scopes The scopes to enable, along with all implied scopes, may be {@code null}.
+ */
+ public CumulativeScopeArtifactFilter( Collection<String> scopes )
+ {
+ this.scopes = new HashSet<String>();
+
+ addScopes( scopes );
+ }
+
+ /**
+ * Creates a new filter that combines the specified filters.
+ *
+ * @param filters The filters to combine, may be {@code null}.
+ */
+ public CumulativeScopeArtifactFilter( CumulativeScopeArtifactFilter... filters )
+ {
+ this.scopes = new HashSet<String>();
+
+ if ( filters != null )
+ {
+ for ( CumulativeScopeArtifactFilter filter : filters )
+ {
+ addScopes( filter.getScopes() );
+ }
+ }
+ }
+
+ private void addScopes( Collection<String> scopes )
+ {
+ if ( scopes != null )
+ {
+ for ( String scope : scopes )
+ {
+ addScope( scope );
+ }
+ }
+ }
+
+ private void addScope( String scope )
+ {
+ this.scopes.add( scope );
+
+ addScopeInternal( scope );
+ }
+
+ public Set<String> getScopes()
+ {
+ return scopes;
+ }
+
+ @Override
+ public int hashCode()
+ {
+ int hash = 17;
+
+ hash = hash * 31 + scopes.hashCode();
+
+ return hash;
+ }
+
+ @Override
+ public boolean equals( Object obj )
+ {
+ if ( this == obj )
+ {
+ return true;
+ }
+
+ if ( !( obj instanceof CumulativeScopeArtifactFilter ) )
+ {
+ return false;
+ }
+
+ CumulativeScopeArtifactFilter that = (CumulativeScopeArtifactFilter) obj;
+
+ return scopes.equals( that.scopes );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/resolver/filter/ExcludesArtifactFilter.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/resolver/filter/ExcludesArtifactFilter.java
new file mode 100644
index 00000000..b6ef02e5
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/resolver/filter/ExcludesArtifactFilter.java
@@ -0,0 +1,44 @@
+package org.apache.maven.artifact.resolver.filter;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.List;
+
+import org.apache.maven.artifact.Artifact;
+
+/**
+ * Filter to exclude from a list of artifact patterns.
+ *
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ * @todo I think this is equiv. to exclusion set filter in maven-core
+ */
+public class ExcludesArtifactFilter
+ extends IncludesArtifactFilter
+{
+ public ExcludesArtifactFilter( List<String> patterns )
+ {
+ super( patterns );
+ }
+
+ public boolean include( Artifact artifact )
+ {
+ return !super.include( artifact );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/resolver/filter/ExclusionSetFilter.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/resolver/filter/ExclusionSetFilter.java
new file mode 100644
index 00000000..c3dc9812
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/resolver/filter/ExclusionSetFilter.java
@@ -0,0 +1,86 @@
+package org.apache.maven.artifact.resolver.filter;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Arrays;
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+import org.apache.maven.artifact.Artifact;
+
+/**
+ * @author <a href="mailto:jason@maven.org">Jason van Zyl</a>
+ */
+public class ExclusionSetFilter
+ implements ArtifactFilter
+{
+ private Set<String> excludes;
+
+ public ExclusionSetFilter( String[] excludes )
+ {
+ this.excludes = new LinkedHashSet<String>( Arrays.asList( excludes ) );
+ }
+
+ public ExclusionSetFilter( Set<String> excludes )
+ {
+ this.excludes = excludes;
+ }
+
+ public boolean include( Artifact artifact )
+ {
+ String id = artifact.getArtifactId();
+
+ if ( excludes.contains( id ) )
+ {
+ return false;
+ }
+
+ id = artifact.getGroupId() + ':' + id;
+
+ return !excludes.contains( id );
+
+ }
+
+ @Override
+ public int hashCode()
+ {
+ int hash = 17;
+ hash = hash * 31 + excludes.hashCode();
+ return hash;
+ }
+
+ @Override
+ public boolean equals( Object obj )
+ {
+ if ( this == obj )
+ {
+ return true;
+ }
+
+ if ( !( obj instanceof ExclusionSetFilter ) )
+ {
+ return false;
+ }
+
+ ExclusionSetFilter other = (ExclusionSetFilter) obj;
+
+ return excludes.equals( other.excludes );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/resolver/filter/IncludesArtifactFilter.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/resolver/filter/IncludesArtifactFilter.java
new file mode 100644
index 00000000..403e1251
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/resolver/filter/IncludesArtifactFilter.java
@@ -0,0 +1,93 @@
+package org.apache.maven.artifact.resolver.filter;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.maven.artifact.Artifact;
+
+/**
+ * Filter to include from a list of artifact patterns.
+ *
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ */
+public class IncludesArtifactFilter
+ implements ArtifactFilter
+{
+ private final Set<String> patterns;
+
+ public IncludesArtifactFilter( List<String> patterns )
+ {
+ this.patterns = new LinkedHashSet<String>( patterns );
+ }
+
+ public boolean include( Artifact artifact )
+ {
+ String id = artifact.getGroupId() + ":" + artifact.getArtifactId();
+
+ boolean matched = false;
+ for ( Iterator<String> i = patterns.iterator(); i.hasNext() & !matched; )
+ {
+ // TODO: what about wildcards? Just specifying groups? versions?
+ if ( id.equals( i.next() ) )
+ {
+ matched = true;
+ }
+ }
+ return matched;
+ }
+
+ public List<String> getPatterns()
+ {
+ return new ArrayList<String>( patterns );
+ }
+
+ @Override
+ public int hashCode()
+ {
+ int hash = 17;
+ hash = hash * 31 + patterns.hashCode();
+
+ return hash;
+ }
+
+ @Override
+ public boolean equals( Object obj )
+ {
+ if ( this == obj )
+ {
+ return true;
+ }
+
+ // make sure IncludesArtifactFilter is not equal ExcludesArtifactFilter!
+ if ( obj == null || getClass() != obj.getClass() )
+ {
+ return false;
+ }
+
+ IncludesArtifactFilter other = (IncludesArtifactFilter) obj;
+
+ return patterns.equals( other.patterns );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/resolver/filter/ScopeArtifactFilter.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/resolver/filter/ScopeArtifactFilter.java
new file mode 100644
index 00000000..1d131b71
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/artifact/resolver/filter/ScopeArtifactFilter.java
@@ -0,0 +1,78 @@
+package org.apache.maven.artifact.resolver.filter;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Filter to only retain objects in the given artifactScope or better.
+ *
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ */
+public class ScopeArtifactFilter
+ extends AbstractScopeArtifactFilter
+{
+
+ private final String scope;
+
+ public ScopeArtifactFilter( String scope )
+ {
+ this.scope = scope;
+
+ addScopeInternal( scope );
+ }
+
+ public String getScope()
+ {
+ return scope;
+ }
+
+ @Override
+ public int hashCode()
+ {
+ int hash = 17;
+
+ hash = hash * 31 + ( scope != null ? scope.hashCode() : 0 );
+
+ return hash;
+ }
+
+ @Override
+ public boolean equals( Object obj )
+ {
+ if ( this == obj )
+ {
+ return true;
+ }
+
+ if ( !( obj instanceof ScopeArtifactFilter ) )
+ {
+ return false;
+ }
+
+ ScopeArtifactFilter other = (ScopeArtifactFilter) obj;
+
+ return equals( scope, other.scope );
+ }
+
+ private static <T> boolean equals( T str1, T str2 )
+ {
+ return str1 != null ? str1.equals( str2 ) : str2 == null;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/bridge/MavenRepositorySystem.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/bridge/MavenRepositorySystem.java
new file mode 100644
index 00000000..f33bc328
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/bridge/MavenRepositorySystem.java
@@ -0,0 +1,785 @@
+package org.apache.maven.bridge;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.maven.RepositoryUtils;
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.DefaultArtifact;
+import org.apache.maven.artifact.InvalidRepositoryException;
+import org.apache.maven.artifact.handler.ArtifactHandler;
+import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy;
+import org.apache.maven.artifact.repository.Authentication;
+import org.apache.maven.artifact.repository.MavenArtifactRepository;
+import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout;
+import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout2;
+import org.apache.maven.artifact.repository.layout.DefaultRepositoryLayout;
+import org.apache.maven.artifact.resolver.filter.ExcludesArtifactFilter;
+import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
+import org.apache.maven.artifact.versioning.VersionRange;
+import org.apache.maven.execution.MavenExecutionRequest;
+import org.apache.maven.model.Dependency;
+import org.apache.maven.model.Exclusion;
+import org.apache.maven.model.Plugin;
+import org.apache.maven.repository.Proxy;
+import org.apache.maven.repository.RepositorySystem;
+import org.apache.maven.settings.Mirror;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+import org.codehaus.plexus.util.StringUtils;
+import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.repository.AuthenticationContext;
+import org.eclipse.aether.repository.AuthenticationSelector;
+import org.eclipse.aether.repository.ProxySelector;
+import org.eclipse.aether.repository.RemoteRepository;
+
+/**
+ * @author Jason van Zyl
+ */
+@Component( role = MavenRepositorySystem.class, hint = "default" )
+public class MavenRepositorySystem
+{
+ @Requirement
+ private ArtifactHandlerManager artifactHandlerManager;
+
+ @Requirement( role = ArtifactRepositoryLayout.class )
+ private Map<String, ArtifactRepositoryLayout> layouts;
+
+ // DefaultProjectBuilder
+ public Artifact createArtifact( String groupId, String artifactId, String version, String scope, String type )
+ {
+ return XcreateArtifact( groupId, artifactId, version, scope, type );
+ }
+
+ // DefaultProjectBuilder
+ public Artifact createProjectArtifact( String groupId, String artifactId, String metaVersionId )
+ {
+ return XcreateProjectArtifact( groupId, artifactId, metaVersionId );
+ }
+
+ // DefaultProjectBuilder
+ public Artifact createDependencyArtifact( Dependency d )
+ {
+ if ( d.getVersion() == null )
+ {
+ return null;
+ }
+
+ VersionRange versionRange;
+ try
+ {
+ versionRange = VersionRange.createFromVersionSpec( d.getVersion() );
+ }
+ catch ( InvalidVersionSpecificationException e )
+ {
+ return null;
+ }
+
+ Artifact artifact =
+ XcreateDependencyArtifact( d.getGroupId(), d.getArtifactId(), versionRange, d.getType(),
+ d.getClassifier(), d.getScope(), d.isOptional() );
+
+ if ( Artifact.SCOPE_SYSTEM.equals( d.getScope() ) && d.getSystemPath() != null )
+ {
+ artifact.setFile( new File( d.getSystemPath() ) );
+ }
+
+ if ( !d.getExclusions().isEmpty() )
+ {
+ List<String> exclusions = new ArrayList<String>();
+
+ for ( Exclusion exclusion : d.getExclusions() )
+ {
+ exclusions.add( exclusion.getGroupId() + ':' + exclusion.getArtifactId() );
+ }
+
+ artifact.setDependencyFilter( new ExcludesArtifactFilter( exclusions ) );
+ }
+
+ return artifact;
+ }
+
+ // DefaultProjectBuilder
+ public Artifact createExtensionArtifact( String groupId, String artifactId, String version )
+ {
+ VersionRange versionRange;
+ try
+ {
+ versionRange = VersionRange.createFromVersionSpec( version );
+ }
+ catch ( InvalidVersionSpecificationException e )
+ {
+ return null;
+ }
+
+ return XcreateExtensionArtifact( groupId, artifactId, versionRange );
+ }
+
+ // DefaultProjectBuilder
+ public Artifact createParentArtifact( String groupId, String artifactId, String version )
+ {
+ return XcreateParentArtifact( groupId, artifactId, version );
+ }
+
+ // DefaultProjectBuilder
+ public Artifact createPluginArtifact( Plugin plugin )
+ {
+ VersionRange versionRange;
+ try
+ {
+ String version = plugin.getVersion();
+ if ( StringUtils.isEmpty( version ) )
+ {
+ version = "RELEASE";
+ }
+ versionRange = VersionRange.createFromVersionSpec( version );
+ }
+ catch ( InvalidVersionSpecificationException e )
+ {
+ return null;
+ }
+
+ return XcreatePluginArtifact( plugin.getGroupId(), plugin.getArtifactId(), versionRange );
+ }
+
+ public void injectMirror( List<ArtifactRepository> repositories, List<Mirror> mirrors )
+ {
+ if ( repositories != null && mirrors != null )
+ {
+ for ( ArtifactRepository repository : repositories )
+ {
+ Mirror mirror = getMirror( repository, mirrors );
+ injectMirror( repository, mirror );
+ }
+ }
+ }
+
+ private Mirror getMirror( RepositorySystemSession session, ArtifactRepository repository )
+ {
+ if ( session != null )
+ {
+ org.eclipse.aether.repository.MirrorSelector selector = session.getMirrorSelector();
+ if ( selector != null )
+ {
+ RemoteRepository repo = selector.getMirror( RepositoryUtils.toRepo( repository ) );
+ if ( repo != null )
+ {
+ Mirror mirror = new Mirror();
+ mirror.setId( repo.getId() );
+ mirror.setUrl( repo.getUrl() );
+ mirror.setLayout( repo.getContentType() );
+ return mirror;
+ }
+ }
+ }
+ return null;
+ }
+
+ public void injectMirror( RepositorySystemSession session, List<ArtifactRepository> repositories )
+ {
+ if ( repositories != null && session != null )
+ {
+ for ( ArtifactRepository repository : repositories )
+ {
+ Mirror mirror = getMirror( session, repository );
+ injectMirror( repository, mirror );
+ }
+ }
+ }
+
+ private void injectMirror( ArtifactRepository repository, Mirror mirror )
+ {
+ if ( mirror != null )
+ {
+ ArtifactRepository original =
+ createArtifactRepository( repository.getId(), repository.getUrl(), repository.getLayout(),
+ repository.getSnapshots(), repository.getReleases() );
+
+ repository.setMirroredRepositories( Collections.singletonList( original ) );
+
+ repository.setId( mirror.getId() );
+ repository.setUrl( mirror.getUrl() );
+
+ if ( StringUtils.isNotEmpty( mirror.getLayout() ) )
+ {
+ repository.setLayout( getLayout( mirror.getLayout() ) );
+ }
+ }
+ }
+
+ private Authentication getAuthentication( RepositorySystemSession session, ArtifactRepository repository )
+ {
+ if ( session != null )
+ {
+ AuthenticationSelector selector = session.getAuthenticationSelector();
+ if ( selector != null )
+ {
+ RemoteRepository repo = RepositoryUtils.toRepo( repository );
+ org.eclipse.aether.repository.Authentication auth = selector.getAuthentication( repo );
+ if ( auth != null )
+ {
+ repo = new RemoteRepository.Builder( repo ).setAuthentication( auth ).build();
+ AuthenticationContext authCtx = AuthenticationContext.forRepository( session, repo );
+ Authentication result =
+ new Authentication( authCtx.get( AuthenticationContext.USERNAME ),
+ authCtx.get( AuthenticationContext.PASSWORD ) );
+ result.setPrivateKey( authCtx.get( AuthenticationContext.PRIVATE_KEY_PATH ) );
+ result.setPassphrase( authCtx.get( AuthenticationContext.PRIVATE_KEY_PASSPHRASE ) );
+ authCtx.close();
+ return result;
+ }
+ }
+ }
+ return null;
+ }
+
+ public void injectAuthentication( RepositorySystemSession session, List<ArtifactRepository> repositories )
+ {
+ if ( repositories != null && session != null )
+ {
+ for ( ArtifactRepository repository : repositories )
+ {
+ repository.setAuthentication( getAuthentication( session, repository ) );
+ }
+ }
+ }
+
+ private Proxy getProxy( RepositorySystemSession session, ArtifactRepository repository )
+ {
+ if ( session != null )
+ {
+ ProxySelector selector = session.getProxySelector();
+ if ( selector != null )
+ {
+ RemoteRepository repo = RepositoryUtils.toRepo( repository );
+ org.eclipse.aether.repository.Proxy proxy = selector.getProxy( repo );
+ if ( proxy != null )
+ {
+ Proxy p = new Proxy();
+ p.setHost( proxy.getHost() );
+ p.setProtocol( proxy.getType() );
+ p.setPort( proxy.getPort() );
+ if ( proxy.getAuthentication() != null )
+ {
+ repo = new RemoteRepository.Builder( repo ).setProxy( proxy ).build();
+ AuthenticationContext authCtx = AuthenticationContext.forProxy( session, repo );
+ p.setUserName( authCtx.get( AuthenticationContext.USERNAME ) );
+ p.setPassword( authCtx.get( AuthenticationContext.PASSWORD ) );
+ p.setNtlmDomain( authCtx.get( AuthenticationContext.NTLM_DOMAIN ) );
+ p.setNtlmHost( authCtx.get( AuthenticationContext.NTLM_WORKSTATION ) );
+ authCtx.close();
+ }
+ return p;
+ }
+ }
+ }
+ return null;
+ }
+
+ public void injectProxy( RepositorySystemSession session, List<ArtifactRepository> repositories )
+ {
+ if ( repositories != null && session != null )
+ {
+ for ( ArtifactRepository repository : repositories )
+ {
+ repository.setProxy( getProxy( session, repository ) );
+ }
+ }
+ }
+
+ private ArtifactRepositoryLayout getLayout( String id )
+ {
+ ArtifactRepositoryLayout layout = layouts.get( id );
+
+ return layout;
+ }
+
+
+ //
+ // Taken from LegacyRepositorySystem
+ //
+
+ public static org.apache.maven.model.Repository fromSettingsRepository( org.apache.maven.settings.Repository
+ settingsRepository )
+ {
+ org.apache.maven.model.Repository modelRepository = new org.apache.maven.model.Repository();
+ modelRepository.setId( settingsRepository.getId() );
+ modelRepository.setLayout( settingsRepository.getLayout() );
+ modelRepository.setName( settingsRepository.getName() );
+ modelRepository.setUrl( settingsRepository.getUrl() );
+ modelRepository.setReleases( fromSettingsRepositoryPolicy( settingsRepository.getReleases() ) );
+ modelRepository.setSnapshots( fromSettingsRepositoryPolicy( settingsRepository.getSnapshots() ) );
+ return modelRepository;
+ }
+
+ public static org.apache.maven.model.RepositoryPolicy fromSettingsRepositoryPolicy(
+ org.apache.maven.settings.RepositoryPolicy settingsRepositoryPolicy )
+ {
+ org.apache.maven.model.RepositoryPolicy modelRepositoryPolicy = new org.apache.maven.model.RepositoryPolicy();
+ if ( settingsRepositoryPolicy != null )
+ {
+ modelRepositoryPolicy.setEnabled( settingsRepositoryPolicy.isEnabled() );
+ modelRepositoryPolicy.setUpdatePolicy( settingsRepositoryPolicy.getUpdatePolicy() );
+ modelRepositoryPolicy.setChecksumPolicy( settingsRepositoryPolicy.getChecksumPolicy() );
+ }
+ return modelRepositoryPolicy;
+ }
+
+ public static ArtifactRepository buildArtifactRepository( org.apache.maven.settings.Repository repo )
+ throws InvalidRepositoryException
+ {
+ return buildArtifactRepository( fromSettingsRepository( repo ) );
+ }
+
+ public static ArtifactRepository buildArtifactRepository( org.apache.maven.model.Repository repo )
+ throws InvalidRepositoryException
+ {
+ if ( repo != null )
+ {
+ String id = repo.getId();
+
+ if ( StringUtils.isEmpty( id ) )
+ {
+ throw new InvalidRepositoryException( "Repository identifier missing", "" );
+ }
+
+ String url = repo.getUrl();
+
+ if ( StringUtils.isEmpty( url ) )
+ {
+ throw new InvalidRepositoryException( "URL missing for repository " + id, id );
+ }
+
+ ArtifactRepositoryPolicy snapshots = buildArtifactRepositoryPolicy( repo.getSnapshots() );
+
+ ArtifactRepositoryPolicy releases = buildArtifactRepositoryPolicy( repo.getReleases() );
+
+ ArtifactRepositoryLayout layout = new DefaultRepositoryLayout();
+
+ return createArtifactRepository( id, url, layout, snapshots, releases );
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ public static ArtifactRepositoryPolicy buildArtifactRepositoryPolicy( org.apache.maven.model.RepositoryPolicy
+ policy )
+ {
+ boolean enabled = true;
+
+ String updatePolicy = null;
+
+ String checksumPolicy = null;
+
+ if ( policy != null )
+ {
+ enabled = policy.isEnabled();
+
+ if ( policy.getUpdatePolicy() != null )
+ {
+ updatePolicy = policy.getUpdatePolicy();
+ }
+ if ( policy.getChecksumPolicy() != null )
+ {
+ checksumPolicy = policy.getChecksumPolicy();
+ }
+ }
+
+ return new ArtifactRepositoryPolicy( enabled, updatePolicy, checksumPolicy );
+ }
+
+ public ArtifactRepository createArtifactRepository( String id, String url, String layoutId,
+ ArtifactRepositoryPolicy snapshots,
+ ArtifactRepositoryPolicy releases )
+ throws Exception
+ {
+ ArtifactRepositoryLayout layout = layouts.get( layoutId );
+
+ checkLayout( id, layoutId, layout );
+
+ return createArtifactRepository( id, url, layout, snapshots, releases );
+ }
+
+ private void checkLayout( String repositoryId, String layoutId, ArtifactRepositoryLayout layout )
+ throws Exception
+ {
+ if ( layout == null )
+ {
+ throw new Exception( String.format( "Cannot find ArtifactRepositoryLayout instance for: %s %s", layoutId,
+ repositoryId ) );
+ }
+ }
+
+ public static ArtifactRepository createArtifactRepository( String id, String url,
+ ArtifactRepositoryLayout repositoryLayout,
+ ArtifactRepositoryPolicy snapshots,
+ ArtifactRepositoryPolicy releases )
+ {
+ if ( snapshots == null )
+ {
+ snapshots = new ArtifactRepositoryPolicy();
+ }
+
+ if ( releases == null )
+ {
+ releases = new ArtifactRepositoryPolicy();
+ }
+
+ ArtifactRepository repository;
+ if ( repositoryLayout instanceof ArtifactRepositoryLayout2 )
+ {
+ repository =
+ ( (ArtifactRepositoryLayout2) repositoryLayout ).newMavenArtifactRepository( id, url, snapshots,
+ releases );
+ }
+ else
+ {
+ repository = new MavenArtifactRepository( id, url, repositoryLayout, snapshots, releases );
+ }
+
+ return repository;
+ }
+
+ // ArtifactFactory
+ private Artifact XcreateArtifact( String groupId, String artifactId, String version, String scope, String type )
+ {
+ return XcreateArtifact( groupId, artifactId, version, scope, type, null, null );
+ }
+
+ private Artifact XcreateDependencyArtifact( String groupId, String artifactId, VersionRange versionRange,
+ String type, String classifier, String scope, boolean optional )
+ {
+ return XcreateArtifact( groupId, artifactId, versionRange, type, classifier, scope, null, optional );
+ }
+
+ private Artifact XcreateProjectArtifact( String groupId, String artifactId, String version )
+ {
+ return XcreateProjectArtifact( groupId, artifactId, version, null );
+ }
+
+ private Artifact XcreateParentArtifact( String groupId, String artifactId, String version )
+ {
+ return XcreateProjectArtifact( groupId, artifactId, version );
+ }
+
+ private Artifact XcreatePluginArtifact( String groupId, String artifactId, VersionRange versionRange )
+ {
+ return XcreateArtifact( groupId, artifactId, versionRange, "maven-plugin", null, Artifact.SCOPE_RUNTIME, null );
+ }
+
+ private Artifact XcreateProjectArtifact( String groupId, String artifactId, String version, String scope )
+ {
+ return XcreateArtifact( groupId, artifactId, version, scope, "pom" );
+ }
+
+ private Artifact XcreateExtensionArtifact( String groupId, String artifactId, VersionRange versionRange )
+ {
+ return XcreateArtifact( groupId, artifactId, versionRange, "jar", null, Artifact.SCOPE_RUNTIME, null );
+ }
+
+ private Artifact XcreateArtifact( String groupId, String artifactId, String version, String scope, String type,
+ String classifier, String inheritedScope )
+ {
+ VersionRange versionRange = null;
+ if ( version != null )
+ {
+ versionRange = VersionRange.createFromVersion( version );
+ }
+ return XcreateArtifact( groupId, artifactId, versionRange, type, classifier, scope, inheritedScope );
+ }
+
+ private Artifact XcreateArtifact( String groupId, String artifactId, VersionRange versionRange, String type,
+ String classifier, String scope, String inheritedScope )
+ {
+ return XcreateArtifact( groupId, artifactId, versionRange, type, classifier, scope, inheritedScope, false );
+ }
+
+ private Artifact XcreateArtifact( String groupId, String artifactId, VersionRange versionRange, String type,
+ String classifier, String scope, String inheritedScope, boolean optional )
+ {
+ String desiredScope = Artifact.SCOPE_RUNTIME;
+
+ if ( inheritedScope == null )
+ {
+ desiredScope = scope;
+ }
+ else if ( Artifact.SCOPE_TEST.equals( scope ) || Artifact.SCOPE_PROVIDED.equals( scope ) )
+ {
+ return null;
+ }
+ else if ( Artifact.SCOPE_COMPILE.equals( scope ) && Artifact.SCOPE_COMPILE.equals( inheritedScope ) )
+ {
+ // added to retain compile artifactScope. Remove if you want compile inherited as runtime
+ desiredScope = Artifact.SCOPE_COMPILE;
+ }
+
+ if ( Artifact.SCOPE_TEST.equals( inheritedScope ) )
+ {
+ desiredScope = Artifact.SCOPE_TEST;
+ }
+
+ if ( Artifact.SCOPE_PROVIDED.equals( inheritedScope ) )
+ {
+ desiredScope = Artifact.SCOPE_PROVIDED;
+ }
+
+ if ( Artifact.SCOPE_SYSTEM.equals( scope ) )
+ {
+ // system scopes come through unchanged...
+ desiredScope = Artifact.SCOPE_SYSTEM;
+ }
+
+ ArtifactHandler handler = artifactHandlerManager.getArtifactHandler( type );
+
+ return new DefaultArtifact( groupId, artifactId, versionRange, desiredScope, type, classifier, handler,
+ optional );
+ }
+
+ //
+ // Code taken from LegacyRepositorySystem
+ //
+
+ public ArtifactRepository createDefaultRemoteRepository( MavenExecutionRequest request )
+ throws Exception
+ {
+ return createRepository( RepositorySystem.DEFAULT_REMOTE_REPO_URL, RepositorySystem.DEFAULT_REMOTE_REPO_ID,
+ true, ArtifactRepositoryPolicy.UPDATE_POLICY_DAILY, false,
+ ArtifactRepositoryPolicy.UPDATE_POLICY_DAILY,
+ ArtifactRepositoryPolicy.CHECKSUM_POLICY_WARN );
+ }
+
+ public ArtifactRepository createRepository( String url, String repositoryId, boolean releases,
+ String releaseUpdates, boolean snapshots, String snapshotUpdates,
+ String checksumPolicy ) throws Exception
+ {
+ ArtifactRepositoryPolicy snapshotsPolicy =
+ new ArtifactRepositoryPolicy( snapshots, snapshotUpdates, checksumPolicy );
+
+ ArtifactRepositoryPolicy releasesPolicy =
+ new ArtifactRepositoryPolicy( releases, releaseUpdates, checksumPolicy );
+
+ return createArtifactRepository( repositoryId, url, "default", snapshotsPolicy, releasesPolicy );
+ }
+
+ public Set<String> getRepoIds( List<ArtifactRepository> repositories )
+ {
+ Set<String> repoIds = new HashSet<String>();
+
+ if ( repositories != null )
+ {
+ for ( ArtifactRepository repository : repositories )
+ {
+ repoIds.add( repository.getId() );
+ }
+ }
+
+ return repoIds;
+ }
+
+
+ public ArtifactRepository createLocalRepository( MavenExecutionRequest request, File localRepository )
+ throws Exception
+ {
+ return createRepository( "file://" + localRepository.toURI().getRawPath(),
+ RepositorySystem.DEFAULT_LOCAL_REPO_ID, true,
+ ArtifactRepositoryPolicy.UPDATE_POLICY_ALWAYS, true,
+ ArtifactRepositoryPolicy.UPDATE_POLICY_ALWAYS,
+ ArtifactRepositoryPolicy.CHECKSUM_POLICY_IGNORE );
+ }
+
+ private static final String WILDCARD = "*";
+
+ private static final String EXTERNAL_WILDCARD = "external:*";
+
+ public static Mirror getMirror( ArtifactRepository repository, List<Mirror> mirrors )
+ {
+ String repoId = repository.getId();
+
+ if ( repoId != null && mirrors != null )
+ {
+ for ( Mirror mirror : mirrors )
+ {
+ if ( repoId.equals( mirror.getMirrorOf() ) && matchesLayout( repository, mirror ) )
+ {
+ return mirror;
+ }
+ }
+
+ for ( Mirror mirror : mirrors )
+ {
+ if ( matchPattern( repository, mirror.getMirrorOf() ) && matchesLayout( repository, mirror ) )
+ {
+ return mirror;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * This method checks if the pattern matches the originalRepository. Valid patterns: * = everything external:* =
+ * everything not on the localhost and not file based. repo,repo1 = repo or repo1 *,!repo1 = everything except repo1
+ *
+ * @param originalRepository to compare for a match.
+ * @param pattern used for match. Currently only '*' is supported.
+ * @return true if the repository is a match to this pattern.
+ */
+ static boolean matchPattern( ArtifactRepository originalRepository, String pattern )
+ {
+ boolean result = false;
+ String originalId = originalRepository.getId();
+
+ // simple checks first to short circuit processing below.
+ if ( WILDCARD.equals( pattern ) || pattern.equals( originalId ) )
+ {
+ result = true;
+ }
+ else
+ {
+ // process the list
+ String[] repos = pattern.split( "," );
+ for ( String repo : repos )
+ {
+ // see if this is a negative match
+ if ( repo.length() > 1 && repo.startsWith( "!" ) )
+ {
+ if ( repo.substring( 1 ).equals( originalId ) )
+ {
+ // explicitly exclude. Set result and stop processing.
+ result = false;
+ break;
+ }
+ }
+ // check for exact match
+ else if ( repo.equals( originalId ) )
+ {
+ result = true;
+ break;
+ }
+ // check for external:*
+ else if ( EXTERNAL_WILDCARD.equals( repo ) && isExternalRepo( originalRepository ) )
+ {
+ result = true;
+ // don't stop processing in case a future segment explicitly excludes this repo
+ }
+ else if ( WILDCARD.equals( repo ) )
+ {
+ result = true;
+ // don't stop processing in case a future segment explicitly excludes this repo
+ }
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Checks the URL to see if this repository refers to an external repository
+ *
+ * @param originalRepository
+ * @return true if external.
+ */
+ static boolean isExternalRepo( ArtifactRepository originalRepository )
+ {
+ try
+ {
+ URL url = new URL( originalRepository.getUrl() );
+ return !( url.getHost().equals( "localhost" ) || url.getHost().equals( "127.0.0.1" )
+ || url.getProtocol().equals( "file" ) );
+ }
+ catch ( MalformedURLException e )
+ {
+ // bad url just skip it here. It should have been validated already, but the wagon lookup will deal with it
+ return false;
+ }
+ }
+
+ static boolean matchesLayout( ArtifactRepository repository, Mirror mirror )
+ {
+ return matchesLayout( RepositoryUtils.getLayout( repository ), mirror.getMirrorOfLayouts() );
+ }
+
+ /**
+ * Checks whether the layouts configured for a mirror match with the layout of the repository.
+ *
+ * @param repoLayout The layout of the repository, may be {@code null}.
+ * @param mirrorLayout The layouts supported by the mirror, may be {@code null}.
+ * @return {@code true} if the layouts associated with the mirror match the layout of the original repository,
+ * {@code false} otherwise.
+ */
+ static boolean matchesLayout( String repoLayout, String mirrorLayout )
+ {
+ boolean result = false;
+
+ // simple checks first to short circuit processing below.
+ if ( StringUtils.isEmpty( mirrorLayout ) || WILDCARD.equals( mirrorLayout ) )
+ {
+ result = true;
+ }
+ else if ( mirrorLayout.equals( repoLayout ) )
+ {
+ result = true;
+ }
+ else
+ {
+ // process the list
+ String[] layouts = mirrorLayout.split( "," );
+ for ( String layout : layouts )
+ {
+ // see if this is a negative match
+ if ( layout.length() > 1 && layout.startsWith( "!" ) )
+ {
+ if ( layout.substring( 1 ).equals( repoLayout ) )
+ {
+ // explicitly exclude. Set result and stop processing.
+ result = false;
+ break;
+ }
+ }
+ // check for exact match
+ else if ( layout.equals( repoLayout ) )
+ {
+ result = true;
+ break;
+ }
+ else if ( WILDCARD.equals( layout ) )
+ {
+ result = true;
+ // don't stop processing in case a future segment explicitly excludes this repo
+ }
+ }
+ }
+
+ return result;
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/classrealm/ArtifactClassRealmConstituent.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/classrealm/ArtifactClassRealmConstituent.java
new file mode 100644
index 00000000..562d6f47
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/classrealm/ArtifactClassRealmConstituent.java
@@ -0,0 +1,76 @@
+package org.apache.maven.classrealm;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+
+import org.eclipse.aether.artifact.Artifact;
+
+/**
+ * @author Benjamin Bentmann
+ */
+class ArtifactClassRealmConstituent
+ implements ClassRealmConstituent
+{
+
+ private final Artifact artifact;
+
+ public ArtifactClassRealmConstituent( Artifact artifact )
+ {
+ this.artifact = artifact;
+ }
+
+ public String getGroupId()
+ {
+ return artifact.getGroupId();
+ }
+
+ public String getArtifactId()
+ {
+ return artifact.getArtifactId();
+ }
+
+ public String getType()
+ {
+ return artifact.getExtension();
+ }
+
+ public String getClassifier()
+ {
+ return artifact.getClassifier();
+ }
+
+ public String getVersion()
+ {
+ return artifact.getBaseVersion();
+ }
+
+ public File getFile()
+ {
+ return artifact.getFile();
+ }
+
+ @Override
+ public String toString()
+ {
+ return artifact.toString();
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/classrealm/ClassRealmConstituent.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/classrealm/ClassRealmConstituent.java
new file mode 100644
index 00000000..f658eb43
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/classrealm/ClassRealmConstituent.java
@@ -0,0 +1,74 @@
+package org.apache.maven.classrealm;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+
+/**
+ * Describes a constituent of a class realm.
+ *
+ * @author Benjamin Bentmann
+ */
+public interface ClassRealmConstituent
+{
+
+ /**
+ * Gets the group id of the constituent's artifact.
+ *
+ * @return The group id, never {@code null}.
+ */
+ String getGroupId();
+
+ /**
+ * Gets the artifact id of the constituent's artifact.
+ *
+ * @return The artifact id, never {@code null}.
+ */
+ String getArtifactId();
+
+ /**
+ * Gets the type of the constituent's artifact.
+ *
+ * @return The type, never {@code null}.
+ */
+ String getType();
+
+ /**
+ * Gets the classifier of the constituent's artifact.
+ *
+ * @return The classifier or an empty string, never {@code null}.
+ */
+ String getClassifier();
+
+ /**
+ * Gets the version of the constituent's artifact.
+ *
+ * @return The version, never {@code null}.
+ */
+ String getVersion();
+
+ /**
+ * Gets the file of the constituent's artifact.
+ *
+ * @return The file, never {@code null}.
+ */
+ File getFile();
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/classrealm/ClassRealmManager.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/classrealm/ClassRealmManager.java
new file mode 100644
index 00000000..e5d15143
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/classrealm/ClassRealmManager.java
@@ -0,0 +1,88 @@
+package org.apache.maven.classrealm;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.List;
+import java.util.Map;
+
+import org.apache.maven.model.Model;
+import org.apache.maven.model.Plugin;
+import org.codehaus.plexus.classworlds.realm.ClassRealm;
+import org.eclipse.aether.artifact.Artifact;
+
+/**
+ * Manages the class realms used by Maven. <strong>Warning:</strong> This is an internal utility interface that is only
+ * public for technical reasons, it is not part of the public API. In particular, this interface can be changed or
+ * deleted without prior notice.
+ *
+ * @author Benjamin Bentmann
+ */
+public interface ClassRealmManager
+{
+
+ /**
+ * Gets the class realm hosting the Maven core.
+ *
+ * @return The class realm hosting the Maven core, never {@code null}.
+ */
+ ClassRealm getCoreRealm();
+
+ /**
+ * Gets the class realm exposing the Maven API. This is basically a restricted view on the Maven core realm.
+ *
+ * @return The class realm exposing the Maven API, never {@code null}.
+ */
+ ClassRealm getMavenApiRealm();
+
+ /**
+ * Creates a new class realm for the specified project and its build extensions.
+ *
+ * @param model The model of the project for which to create a realm, must not be {@code null}.
+ * @param artifacts The artifacts to add to the class realm, may be {@code null}. Unresolved artifacts (i.e. with a
+ * missing file) will automatically be excluded from the realm.
+ * @return The new project realm, never {@code null}.
+ */
+ ClassRealm createProjectRealm( Model model, List<Artifact> artifacts );
+
+ /**
+ * Creates a new class realm for the specified build extension.
+ *
+ * @param extension The extension plugin for which to create a realm, must not be {@code null}.
+ * @param artifacts The artifacts to add to the class realm, may be {@code null}. Unresolved artifacts (i.e. with a
+ * missing file) will automatically be excluded from the realm.
+ * @return The new extension realm, never {@code null}.
+ */
+ ClassRealm createExtensionRealm( Plugin extension, List<Artifact> artifacts );
+
+ /**
+ * Creates a new class realm for the specified plugin.
+ *
+ * @param plugin The plugin for which to create a realm, must not be {@code null}.
+ * @param parent The parent realm for the new realm, may be {@code null}.
+ * @param parentImports The packages/types to import from the parent realm, may be {@code null}.
+ * @param foreignImports The packages/types to import from foreign realms, may be {@code null}.
+ * @param artifacts The artifacts to add to the class realm, may be {@code null}. Unresolved artifacts (i.e. with a
+ * missing file) will automatically be excluded from the realm.
+ * @return The new plugin realm, never {@code null}.
+ */
+ ClassRealm createPluginRealm( Plugin plugin, ClassLoader parent, List<String> parentImports,
+ Map<String, ClassLoader> foreignImports, List<Artifact> artifacts );
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/classrealm/ClassRealmManagerDelegate.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/classrealm/ClassRealmManagerDelegate.java
new file mode 100644
index 00000000..b0229b97
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/classrealm/ClassRealmManagerDelegate.java
@@ -0,0 +1,36 @@
+package org.apache.maven.classrealm;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+
+import org.codehaus.plexus.classworlds.realm.ClassRealm;
+
+/**
+ * ClassRealmManagerDelegate is used to perform addition configuration of
+ * class realms created by ClassRealmManager.
+ *
+ * @author igor
+ */
+public interface ClassRealmManagerDelegate
+{
+
+ void setupRealm( ClassRealm classRealm, ClassRealmRequest request );
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/classrealm/ClassRealmRequest.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/classrealm/ClassRealmRequest.java
new file mode 100644
index 00000000..9b62108f
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/classrealm/ClassRealmRequest.java
@@ -0,0 +1,100 @@
+package org.apache.maven.classrealm;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Describes the requirements for a new class realm.
+ *
+ * @author Benjamin Bentmann
+ */
+public interface ClassRealmRequest
+{
+
+ /**
+ * The type of a class realm.
+ */
+ enum RealmType
+ {
+ /**
+ * The class realm for the public API of the Maven core.
+ */
+ Core,
+
+ /**
+ * A class realm for a project to aggregates its build extensions.
+ */
+ Project,
+
+ /**
+ * A class realm for a build extension.
+ */
+ Extension,
+
+ /**
+ * A class realm for a plugin.
+ */
+ Plugin,
+ }
+
+ /**
+ * Gets the type of the class realm.
+ *
+ * @return The type of the class realm, never {@code null}.
+ */
+ RealmType getType();
+
+ /**
+ * Gets the parent class realm (if any).
+ *
+ * @return The parent class realm or {@code null} if using the default parent.
+ */
+ ClassLoader getParent();
+
+ /**
+ * @deprecated Use {@link #getParentImports()} instead.
+ */
+ @Deprecated
+ List<String> getImports();
+
+ /**
+ * Gets the packages/types to import from the parent realm.
+ *
+ * @return The modifiable list of packages/types to import from the parent realm, never {@code null}.
+ */
+ List<String> getParentImports();
+
+ /**
+ * Gets the packages/types to import from foreign realms.
+ *
+ * @return The modifiable map of packages/types to import from foreign realms, never {@code null}.
+ */
+ Map<String, ClassLoader> getForeignImports();
+
+ /**
+ * Gets the constituents for the class realm.
+ *
+ * @return The modifiable list of constituents for the class realm, never {@code null}.
+ */
+ List<ClassRealmConstituent> getConstituents();
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/classrealm/DefaultClassRealmManager.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/classrealm/DefaultClassRealmManager.java
new file mode 100644
index 00000000..69ee04a9
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/classrealm/DefaultClassRealmManager.java
@@ -0,0 +1,416 @@
+package org.apache.maven.classrealm;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.net.MalformedURLException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+import java.util.Set;
+import java.util.TreeMap;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import org.apache.maven.artifact.ArtifactUtils;
+import org.apache.maven.classrealm.ClassRealmRequest.RealmType;
+import org.apache.maven.extension.internal.CoreExportsProvider;
+import org.apache.maven.model.Model;
+import org.apache.maven.model.Plugin;
+import org.codehaus.plexus.MutablePlexusContainer;
+import org.codehaus.plexus.PlexusContainer;
+import org.codehaus.plexus.classworlds.ClassWorld;
+import org.codehaus.plexus.classworlds.realm.ClassRealm;
+import org.codehaus.plexus.classworlds.realm.DuplicateRealmException;
+import org.codehaus.plexus.logging.Logger;
+import org.codehaus.plexus.util.StringUtils;
+import org.eclipse.aether.artifact.Artifact;
+
+/**
+ * Manages the class realms used by Maven. <strong>Warning:</strong> This is an internal utility class that is only
+ * public for technical reasons, it is not part of the public API. In particular, this class can be changed or deleted
+ * without prior notice.
+ *
+ * @author Benjamin Bentmann
+ */
+@Named
+@Singleton
+public class DefaultClassRealmManager
+ implements ClassRealmManager
+{
+ public static final String API_REALMID = "maven.api";
+
+ /**
+ * During normal command line build, ClassWorld is loaded by jvm system classloader, which only includes
+ * plexus-classworlds jar and possibly javaagent classes, see http://jira.codehaus.org/browse/MNG-4747.
+ * <p>
+ * Using ClassWorld to determine plugin/extensions realm parent classloaders gives m2e and integration test harness
+ * flexibility to load multiple version of maven into dedicated classloaders without assuming state of jvm system
+ * classloader.
+ */
+ private static final ClassLoader PARENT_CLASSLOADER = ClassWorld.class.getClassLoader();
+
+ private final Logger logger;
+
+ private final ClassWorld world;
+
+ private final ClassRealm containerRealm;
+
+ // this is a live injected collection
+ private final List<ClassRealmManagerDelegate> delegates;
+
+ private final ClassRealm mavenApiRealm;
+
+ /**
+ * Patterns of artifacts provided by maven core and exported via maven api realm. These artifacts are filtered from
+ * plugin and build extensions realms to avoid presence of duplicate and possibly conflicting classes on classpath.
+ */
+ private final Set<String> providedArtifacts;
+
+ @Inject
+ public DefaultClassRealmManager( Logger logger, PlexusContainer container,
+ List<ClassRealmManagerDelegate> delegates, CoreExportsProvider exports )
+ {
+ this.logger = logger;
+ this.world = ( (MutablePlexusContainer) container ).getClassWorld();
+ this.containerRealm = container.getContainerRealm();
+ this.delegates = delegates;
+
+ Map<String, ClassLoader> foreignImports = exports.get().getExportedPackages();
+
+ this.mavenApiRealm =
+ createRealm( API_REALMID, RealmType.Core, null /* parent */, null /* parentImports */,
+ foreignImports, null /* artifacts */ );
+
+ this.providedArtifacts = exports.get().getExportedArtifacts();
+ }
+
+ private ClassRealm newRealm( String id )
+ {
+ synchronized ( world )
+ {
+ String realmId = id;
+
+ Random random = new Random();
+
+ while ( true )
+ {
+ try
+ {
+ ClassRealm classRealm = world.newRealm( realmId, null );
+
+ if ( logger.isDebugEnabled() )
+ {
+ logger.debug( "Created new class realm " + realmId );
+ }
+
+ return classRealm;
+ }
+ catch ( DuplicateRealmException e )
+ {
+ realmId = id + '-' + random.nextInt();
+ }
+ }
+ }
+ }
+
+ public ClassRealm getMavenApiRealm()
+ {
+ return mavenApiRealm;
+ }
+
+ /**
+ * Creates a new class realm with the specified parent and imports.
+ *
+ * @param baseRealmId The base id to use for the new realm, must not be {@code null}.
+ * @param type The type of the class realm, must not be {@code null}.
+ * @param parent The parent realm for the new realm, may be {@code null}.
+ * @param parentImports The packages/types to import from the parent realm, may be {@code null}.
+ * @param foreignImports The packages/types to import from foreign realms, may be {@code null}.
+ * @param artifacts The artifacts to add to the realm, may be {@code null}. Unresolved artifacts (i.e. with a
+ * missing file) will automatically be excluded from the realm.
+ * @return The created class realm, never {@code null}.
+ */
+ private ClassRealm createRealm( String baseRealmId, RealmType type, ClassLoader parent, List<String> parentImports,
+ Map<String, ClassLoader> foreignImports, List<Artifact> artifacts )
+ {
+ Set<String> artifactIds = new LinkedHashSet<String>();
+
+ List<ClassRealmConstituent> constituents = new ArrayList<ClassRealmConstituent>();
+
+ if ( artifacts != null )
+ {
+ for ( Artifact artifact : artifacts )
+ {
+ if ( !isProvidedArtifact( artifact ) )
+ {
+ artifactIds.add( getId( artifact ) );
+ if ( artifact.getFile() != null )
+ {
+ constituents.add( new ArtifactClassRealmConstituent( artifact ) );
+ }
+ }
+ }
+ }
+
+ if ( parentImports != null )
+ {
+ parentImports = new ArrayList<String>( parentImports );
+ }
+ else
+ {
+ parentImports = new ArrayList<String>();
+ }
+
+ if ( foreignImports != null )
+ {
+ foreignImports = new TreeMap<String, ClassLoader>( foreignImports );
+ }
+ else
+ {
+ foreignImports = new TreeMap<String, ClassLoader>();
+ }
+
+ ClassRealm classRealm = newRealm( baseRealmId );
+
+ if ( parent != null )
+ {
+ classRealm.setParentClassLoader( parent );
+ }
+
+ callDelegates( classRealm, type, parent, parentImports, foreignImports, constituents );
+
+ wireRealm( classRealm, parentImports, foreignImports );
+
+ Set<String> includedIds = populateRealm( classRealm, constituents );
+
+ if ( logger.isDebugEnabled() )
+ {
+ artifactIds.removeAll( includedIds );
+
+ for ( String id : artifactIds )
+ {
+ logger.debug( " Excluded: " + id );
+ }
+ }
+
+ return classRealm;
+ }
+
+ public ClassRealm getCoreRealm()
+ {
+ return containerRealm;
+ }
+
+ public ClassRealm createProjectRealm( Model model, List<Artifact> artifacts )
+ {
+ if ( model == null )
+ {
+ throw new IllegalArgumentException( "model missing" );
+ }
+
+ ClassLoader parent = getMavenApiRealm();
+
+ return createRealm( getKey( model ), RealmType.Project, parent, null, null, artifacts );
+ }
+
+ private static String getKey( Model model )
+ {
+ return "project>" + model.getGroupId() + ":" + model.getArtifactId() + ":" + model.getVersion();
+ }
+
+ public ClassRealm createExtensionRealm( Plugin plugin, List<Artifact> artifacts )
+ {
+ if ( plugin == null )
+ {
+ throw new IllegalArgumentException( "extension plugin missing" );
+ }
+
+ ClassLoader parent = PARENT_CLASSLOADER;
+
+ Map<String, ClassLoader> foreignImports =
+ Collections.<String, ClassLoader>singletonMap( "", getMavenApiRealm() );
+
+ return createRealm( getKey( plugin, true ), RealmType.Extension, parent, null, foreignImports, artifacts );
+ }
+
+ private boolean isProvidedArtifact( Artifact artifact )
+ {
+ return providedArtifacts.contains( artifact.getGroupId() + ":" + artifact.getArtifactId() );
+ }
+
+ public ClassRealm createPluginRealm( Plugin plugin, ClassLoader parent, List<String> parentImports,
+ Map<String, ClassLoader> foreignImports, List<Artifact> artifacts )
+ {
+ if ( plugin == null )
+ {
+ throw new IllegalArgumentException( "plugin missing" );
+ }
+
+ if ( parent == null )
+ {
+ parent = PARENT_CLASSLOADER;
+ }
+
+ return createRealm( getKey( plugin, false ), RealmType.Plugin, parent, parentImports, foreignImports,
+ artifacts );
+ }
+
+ private static String getKey( Plugin plugin, boolean extension )
+ {
+ String version = ArtifactUtils.toSnapshotVersion( plugin.getVersion() );
+ return ( extension ? "extension>" : "plugin>" ) + plugin.getGroupId() + ":" + plugin.getArtifactId() + ":"
+ + version;
+ }
+
+ private static String getId( Artifact artifact )
+ {
+ return getId( artifact.getGroupId(), artifact.getArtifactId(), artifact.getExtension(),
+ artifact.getClassifier(), artifact.getBaseVersion() );
+ }
+
+ private static String getId( ClassRealmConstituent constituent )
+ {
+ return getId( constituent.getGroupId(), constituent.getArtifactId(), constituent.getType(),
+ constituent.getClassifier(), constituent.getVersion() );
+ }
+
+ private static String getId( String gid, String aid, String type, String cls, String ver )
+ {
+ return gid + ':' + aid + ':' + type + ( StringUtils.isNotEmpty( cls ) ? ':' + cls : "" ) + ':' + ver;
+ }
+
+ private void callDelegates( ClassRealm classRealm, RealmType type, ClassLoader parent, List<String> parentImports,
+ Map<String, ClassLoader> foreignImports, List<ClassRealmConstituent> constituents )
+ {
+ List<ClassRealmManagerDelegate> delegates = new ArrayList<ClassRealmManagerDelegate>( this.delegates );
+
+ if ( !delegates.isEmpty() )
+ {
+ ClassRealmRequest request =
+ new DefaultClassRealmRequest( type, parent, parentImports, foreignImports, constituents );
+
+ for ( ClassRealmManagerDelegate delegate : delegates )
+ {
+ try
+ {
+ delegate.setupRealm( classRealm, request );
+ }
+ catch ( Exception e )
+ {
+ logger.error( delegate.getClass().getName() + " failed to setup class realm " + classRealm + ": "
+ + e.getMessage(), e );
+ }
+ }
+ }
+ }
+
+ private Set<String> populateRealm( ClassRealm classRealm, List<ClassRealmConstituent> constituents )
+ {
+ Set<String> includedIds = new LinkedHashSet<String>();
+
+ if ( logger.isDebugEnabled() )
+ {
+ logger.debug( "Populating class realm " + classRealm.getId() );
+ }
+
+ for ( ClassRealmConstituent constituent : constituents )
+ {
+ File file = constituent.getFile();
+
+ String id = getId( constituent );
+ includedIds.add( id );
+
+ if ( logger.isDebugEnabled() )
+ {
+ logger.debug( " Included: " + id );
+ }
+
+ try
+ {
+ classRealm.addURL( file.toURI().toURL() );
+ }
+ catch ( MalformedURLException e )
+ {
+ // Not going to happen
+ logger.error( e.getMessage(), e );
+ }
+ }
+
+ return includedIds;
+ }
+
+ private void wireRealm( ClassRealm classRealm, List<String> parentImports, Map<String, ClassLoader> foreignImports )
+ {
+ if ( foreignImports != null && !foreignImports.isEmpty() )
+ {
+ if ( logger.isDebugEnabled() )
+ {
+ logger.debug( "Importing foreign packages into class realm " + classRealm.getId() );
+ }
+
+ for ( Map.Entry<String, ClassLoader> entry : foreignImports.entrySet() )
+ {
+ ClassLoader importedRealm = entry.getValue();
+ String imp = entry.getKey();
+
+ if ( logger.isDebugEnabled() )
+ {
+ logger.debug( " Imported: " + imp + " < " + getId( importedRealm ) );
+ }
+
+ classRealm.importFrom( importedRealm, imp );
+ }
+ }
+
+ if ( parentImports != null && !parentImports.isEmpty() )
+ {
+ if ( logger.isDebugEnabled() )
+ {
+ logger.debug( "Importing parent packages into class realm " + classRealm.getId() );
+ }
+
+ for ( String imp : parentImports )
+ {
+ if ( logger.isDebugEnabled() )
+ {
+ logger.debug( " Imported: " + imp + " < " + getId( classRealm.getParentClassLoader() ) );
+ }
+
+ classRealm.importFromParent( imp );
+ }
+ }
+ }
+
+ private String getId( ClassLoader classLoader )
+ {
+ if ( classLoader instanceof ClassRealm )
+ {
+ return ( (ClassRealm) classLoader ).getId();
+ }
+ return String.valueOf( classLoader );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/classrealm/DefaultClassRealmRequest.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/classrealm/DefaultClassRealmRequest.java
new file mode 100644
index 00000000..062b2cf3
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/classrealm/DefaultClassRealmRequest.java
@@ -0,0 +1,82 @@
+package org.apache.maven.classrealm;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author Benjamin Bentmann
+ */
+class DefaultClassRealmRequest
+ implements ClassRealmRequest
+{
+
+ private final RealmType type;
+
+ private final ClassLoader parent;
+
+ private final List<String> parentImports;
+
+ private final Map<String, ClassLoader> foreignImports;
+
+ private final List<ClassRealmConstituent> constituents;
+
+ public DefaultClassRealmRequest( RealmType type, ClassLoader parent, List<String> parentImports,
+ Map<String, ClassLoader> foreignImports, List<ClassRealmConstituent> constituents )
+ {
+ this.type = type;
+ this.parent = parent;
+ this.parentImports = parentImports;
+ this.foreignImports = foreignImports;
+ this.constituents = constituents;
+ }
+
+ public RealmType getType()
+ {
+ return type;
+ }
+
+ public ClassLoader getParent()
+ {
+ return parent;
+ }
+
+ public List<String> getImports()
+ {
+ return getParentImports();
+ }
+
+ public List<String> getParentImports()
+ {
+ return parentImports;
+ }
+
+ public Map<String, ClassLoader> getForeignImports()
+ {
+ return foreignImports;
+ }
+
+ public List<ClassRealmConstituent> getConstituents()
+ {
+ return constituents;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/configuration/BasedirBeanConfigurationPathTranslator.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/configuration/BasedirBeanConfigurationPathTranslator.java
new file mode 100644
index 00000000..9859f586
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/configuration/BasedirBeanConfigurationPathTranslator.java
@@ -0,0 +1,71 @@
+package org.apache.maven.configuration;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+
+/**
+ * A path translator that resolves relative paths against a specific base directory.
+ *
+ * @author Benjamin Bentmann
+ */
+public class BasedirBeanConfigurationPathTranslator
+ implements BeanConfigurationPathTranslator
+{
+
+ private final File basedir;
+
+ /**
+ * Creates a new path translator using the specified base directory.
+ *
+ * @param basedir The base directory to resolve relative paths against, may be {@code null} to disable path
+ * translation.
+ */
+ public BasedirBeanConfigurationPathTranslator( File basedir )
+ {
+ this.basedir = basedir;
+ }
+
+ public File translatePath( File path )
+ {
+ File result = path;
+
+ if ( path != null && basedir != null )
+ {
+ if ( path.isAbsolute() )
+ {
+ // path is already absolute, we're done
+ }
+ else if ( path.getPath().startsWith( File.separator ) )
+ {
+ // drive-relative Windows path, don't align with base dir but with drive root
+ result = path.getAbsoluteFile();
+ }
+ else
+ {
+ // an ordinary relative path, align with base dir
+ result = new File( new File( basedir, path.getPath() ).toURI().normalize() ).getAbsoluteFile();
+ }
+ }
+
+ return result;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/configuration/BeanConfigurationException.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/configuration/BeanConfigurationException.java
new file mode 100644
index 00000000..3d10ed4a
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/configuration/BeanConfigurationException.java
@@ -0,0 +1,41 @@
+package org.apache.maven.configuration;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Thrown when a bean couldn't be configured.
+ *
+ * @author Benjamin Bentmann
+ */
+public class BeanConfigurationException
+ extends Exception
+{
+
+ public BeanConfigurationException( String message )
+ {
+ super( message );
+ }
+
+ public BeanConfigurationException( String message, Throwable cause )
+ {
+ super( message, cause );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/configuration/BeanConfigurationPathTranslator.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/configuration/BeanConfigurationPathTranslator.java
new file mode 100644
index 00000000..39663391
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/configuration/BeanConfigurationPathTranslator.java
@@ -0,0 +1,41 @@
+package org.apache.maven.configuration;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+
+/**
+ * Postprocesses filesystem paths. For instance, a path translator might want to resolve relative paths given in the
+ * bean configuration against some base directory.
+ *
+ * @author Benjamin Bentmann
+ */
+public interface BeanConfigurationPathTranslator
+{
+
+ /**
+ * Translates the specified path.
+ *
+ * @param path The path to translate, may be {@code null}.
+ * @return The translated path or {@code null} if none.
+ */
+ File translatePath( File path );
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/configuration/BeanConfigurationRequest.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/configuration/BeanConfigurationRequest.java
new file mode 100644
index 00000000..d19aa204
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/configuration/BeanConfigurationRequest.java
@@ -0,0 +1,130 @@
+package org.apache.maven.configuration;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * A request to configure a bean from some configuration in the POM or similar.
+ *
+ * @author Benjamin Bentmann
+ */
+public interface BeanConfigurationRequest
+{
+
+ /**
+ * Gets the bean to configure. Eventually, a valid request must have a bean set.
+ *
+ * @return The bean to configure, or {@code null} if none.
+ */
+ Object getBean();
+
+ /**
+ * Sets the bean to configure. Eventually, a valid request must have a bean set.
+ *
+ * @param bean The bean to configure, may be {@code null}.
+ * @return This request for chaining, never {@code null}.
+ */
+ BeanConfigurationRequest setBean( Object bean );
+
+ /**
+ * Gets the configuration to unmarshal into the bean.
+ *
+ * @return The configuration to unmarshal into the bean or {@code null} if none.
+ */
+ Object getConfiguration();
+
+ /**
+ * Sets the configuration to unmarshal into the bean. The configuration should be taken from
+ * {@link org.apache.maven.model.ConfigurationContainer#getConfiguration()} or a similar source.
+ * Fully equivalent to {@code setConfiguration(configuration, null)}.
+ *
+ * @param configuration The configuration to unmarshal, may be {@code null}.
+ * @return This request for chaining, never {@code null}.
+ */
+ BeanConfigurationRequest setConfiguration( Object configuration );
+
+ /**
+ * Sets the configuration to unmarshal into the bean. The configuration should be taken from
+ * {@link org.apache.maven.model.ConfigurationContainer#getConfiguration()} or a similar source.
+ * If {@code element} is not {@code null}, child configuration element with the specified name will
+ * be unmarshaled.
+ *
+ * @param configuration The configuration to unmarshal, may be {@code null}.
+ * @param element Configuration element name to unmarshal or {@code null} to unmarshal entire configuration.
+ * @return This request for chaining, never {@code null}.
+ */
+ BeanConfigurationRequest setConfiguration( Object configuration, String element );
+
+ /**
+ * Returns configuration element name or {@code null}.
+ *
+ * @see #setConfiguration(Object, String)
+ *
+ * @return Configuration element name or {@code null}
+ */
+ String getConfigurationElement();
+
+ /**
+ * Gets the class loader from which to load any types referenced by the configuration. If unset, the class loader of
+ * the bean class will be used.
+ *
+ * @return The class loader to load referenced types from or {@code null} if unset.
+ */
+ ClassLoader getClassLoader();
+
+ /**
+ * Sets the class loader from which to load any types referenced by the configuration. If unset, the class loader of
+ * the bean class will be used.
+ *
+ * @param classLoader The class loader to load referenced types from, may be {@code null}.
+ * @return This request for chaining, never {@code null}.
+ */
+ BeanConfigurationRequest setClassLoader( ClassLoader classLoader );
+
+ /**
+ * Gets the optional preprocessor for configuration values.
+ *
+ * @return The preprocessor for configuration values or {@code null} if none.
+ */
+ BeanConfigurationValuePreprocessor getValuePreprocessor();
+
+ /**
+ * Sets the optional preprocessor for configuration values.
+ *
+ * @param valuePreprocessor The preprocessor for configuration values, may be {@code null} if unneeded.
+ * @return This request for chaining, never {@code null}.
+ */
+ BeanConfigurationRequest setValuePreprocessor( BeanConfigurationValuePreprocessor valuePreprocessor );
+
+ /**
+ * Gets the optional path translator for configuration values unmarshalled to files.
+ *
+ * @return The path translator for files or {@code null} if none.
+ */
+ BeanConfigurationPathTranslator getPathTranslator();
+
+ /**
+ * Sets the optional path translator for configuration values unmarshalled to files.
+ *
+ * @param pathTranslator The path translator for files, may be {@code null} if unneeded.
+ * @return This request for chaining, never {@code null}.
+ */
+ BeanConfigurationRequest setPathTranslator( BeanConfigurationPathTranslator pathTranslator );
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/configuration/BeanConfigurationValuePreprocessor.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/configuration/BeanConfigurationValuePreprocessor.java
new file mode 100644
index 00000000..63f85173
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/configuration/BeanConfigurationValuePreprocessor.java
@@ -0,0 +1,45 @@
+package org.apache.maven.configuration;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Preprocesses a value from a bean configuration before the bean configurator unmarshals it into a bean property. A
+ * common use case for such preprocessing is the evaluation of variables within the configuration value.
+ *
+ * @author Benjamin Bentmann
+ */
+public interface BeanConfigurationValuePreprocessor
+{
+
+ /**
+ * Preprocesses the specified bean configuration value. The optional type provided to this method is a hint (not a
+ * requirement) for the preprocessor to resolve the value to a compatible value or a (string) value than can be
+ * unmarshalled into that type. The preprocessor is not required to perform any type conversion but should rather
+ * filter out incompatible values from its result.
+ *
+ * @param value The configuration value to preprocess, must not be {@code null}.
+ * @param type The target type of the value, may be {@code null}.
+ * @return The processed configuration value or {@code null} if none.
+ * @throws BeanConfigurationException If an error occurred while preprocessing the value.
+ */
+ Object preprocessValue( String value, Class<?> type )
+ throws BeanConfigurationException;
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/configuration/BeanConfigurator.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/configuration/BeanConfigurator.java
new file mode 100644
index 00000000..36d23eca
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/configuration/BeanConfigurator.java
@@ -0,0 +1,44 @@
+package org.apache.maven.configuration;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Unmarshals some textual configuration from the POM or similar into the properties of a bean. This component works
+ * similar to the way Maven configures plugins from the POM, i.e. some configuration like {@code <param>value</param>}
+ * is mapped to an equally named property of the bean and converted. The properties of the bean are supposed to either
+ * have a public setter or be backed by an equally named field (of any visibility).
+ *
+ * @since 3.0
+ * @author Benjamin Bentmann
+ */
+public interface BeanConfigurator
+{
+
+ /**
+ * Performs the specified bean configuration.
+ *
+ * @param request The configuration request that specifies the bean and the configuration to process, must not be
+ * {@code null}.
+ * @throws BeanConfigurationException If the bean configuration could not be successfully processed.
+ */
+ void configureBean( BeanConfigurationRequest request )
+ throws BeanConfigurationException;
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/configuration/DefaultBeanConfigurationRequest.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/configuration/DefaultBeanConfigurationRequest.java
new file mode 100644
index 00000000..32def48f
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/configuration/DefaultBeanConfigurationRequest.java
@@ -0,0 +1,195 @@
+package org.apache.maven.configuration;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.model.Build;
+import org.apache.maven.model.Model;
+import org.apache.maven.model.Plugin;
+import org.apache.maven.model.PluginExecution;
+import org.apache.maven.model.PluginManagement;
+import org.codehaus.plexus.util.StringUtils;
+
+/**
+ * A basic bean configuration request.
+ *
+ * @author Benjamin Bentmann
+ */
+public class DefaultBeanConfigurationRequest
+ implements BeanConfigurationRequest
+{
+
+ private Object bean;
+
+ private Object configuration;
+
+ private String configurationElement;
+
+ private ClassLoader classLoader;
+
+ private BeanConfigurationValuePreprocessor valuePreprocessor;
+
+ private BeanConfigurationPathTranslator pathTranslator;
+
+ public Object getBean()
+ {
+ return bean;
+ }
+
+ public DefaultBeanConfigurationRequest setBean( Object bean )
+ {
+ this.bean = bean;
+ return this;
+ }
+
+ public Object getConfiguration()
+ {
+ return configuration;
+ }
+
+ public String getConfigurationElement()
+ {
+ return configurationElement;
+ }
+
+ public DefaultBeanConfigurationRequest setConfiguration( Object configuration )
+ {
+ return setConfiguration( configuration, null );
+ }
+
+ public DefaultBeanConfigurationRequest setConfiguration( Object configuration, String element )
+ {
+ this.configuration = configuration;
+ this.configurationElement = element;
+ return this;
+ }
+
+ /**
+ * Sets the configuration to the configuration taken from the specified build plugin in the POM. First, the build
+ * plugins will be searched for the specified plugin, if that fails, the plugin management section will be searched.
+ *
+ * @param model The POM to extract the plugin configuration from, may be {@code null}.
+ * @param pluginGroupId The group id of the plugin whose configuration should be used, must not be {@code null} or
+ * empty.
+ * @param pluginArtifactId The artifact id of the plugin whose configuration should be used, must not be
+ * {@code null} or empty.
+ * @param pluginExecutionId The id of a plugin execution whose configuration should be used, may be {@code null} or
+ * empty to use the general plugin configuration.
+ * @return This request for chaining, never {@code null}.
+ */
+ public DefaultBeanConfigurationRequest setConfiguration( Model model, String pluginGroupId,
+ String pluginArtifactId, String pluginExecutionId )
+ {
+ Plugin plugin = findPlugin( model, pluginGroupId, pluginArtifactId );
+ if ( plugin != null )
+ {
+ if ( StringUtils.isNotEmpty( pluginExecutionId ) )
+ {
+ for ( PluginExecution execution : plugin.getExecutions() )
+ {
+ if ( pluginExecutionId.equals( execution.getId() ) )
+ {
+ setConfiguration( execution.getConfiguration() );
+ break;
+ }
+ }
+ }
+ else
+ {
+ setConfiguration( plugin.getConfiguration() );
+ }
+ }
+ return this;
+ }
+
+ private Plugin findPlugin( Model model, String groupId, String artifactId )
+ {
+ if ( StringUtils.isEmpty( groupId ) )
+ {
+ throw new IllegalArgumentException( "group id for plugin has not been specified" );
+ }
+ if ( StringUtils.isEmpty( artifactId ) )
+ {
+ throw new IllegalArgumentException( "artifact id for plugin has not been specified" );
+ }
+
+ if ( model != null )
+ {
+ Build build = model.getBuild();
+ if ( build != null )
+ {
+ for ( Plugin plugin : build.getPlugins() )
+ {
+ if ( groupId.equals( plugin.getGroupId() ) && artifactId.equals( plugin.getArtifactId() ) )
+ {
+ return plugin;
+ }
+ }
+
+ PluginManagement mngt = build.getPluginManagement();
+ if ( mngt != null )
+ {
+ for ( Plugin plugin : mngt.getPlugins() )
+ {
+ if ( groupId.equals( plugin.getGroupId() ) && artifactId.equals( plugin.getArtifactId() ) )
+ {
+ return plugin;
+ }
+ }
+ }
+ }
+ }
+
+ return null;
+ }
+
+ public ClassLoader getClassLoader()
+ {
+ return classLoader;
+ }
+
+ public DefaultBeanConfigurationRequest setClassLoader( ClassLoader classLoader )
+ {
+ this.classLoader = classLoader;
+ return this;
+ }
+
+ public BeanConfigurationValuePreprocessor getValuePreprocessor()
+ {
+ return valuePreprocessor;
+ }
+
+ public DefaultBeanConfigurationRequest setValuePreprocessor( BeanConfigurationValuePreprocessor valuePreprocessor )
+ {
+ this.valuePreprocessor = valuePreprocessor;
+ return this;
+ }
+
+ public BeanConfigurationPathTranslator getPathTranslator()
+ {
+ return pathTranslator;
+ }
+
+ public DefaultBeanConfigurationRequest setPathTranslator( BeanConfigurationPathTranslator pathTranslator )
+ {
+ this.pathTranslator = pathTranslator;
+ return this;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/configuration/internal/DefaultBeanConfigurator.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/configuration/internal/DefaultBeanConfigurator.java
new file mode 100644
index 00000000..3d3def62
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/configuration/internal/DefaultBeanConfigurator.java
@@ -0,0 +1,160 @@
+package org.apache.maven.configuration.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+
+import org.apache.maven.configuration.BeanConfigurationException;
+import org.apache.maven.configuration.BeanConfigurationPathTranslator;
+import org.apache.maven.configuration.BeanConfigurationRequest;
+import org.apache.maven.configuration.BeanConfigurationValuePreprocessor;
+import org.apache.maven.configuration.BeanConfigurator;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.configurator.ComponentConfigurationException;
+import org.codehaus.plexus.component.configurator.converters.composite.ObjectWithFieldsConverter;
+import org.codehaus.plexus.component.configurator.converters.lookup.ConverterLookup;
+import org.codehaus.plexus.component.configurator.converters.lookup.DefaultConverterLookup;
+import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluationException;
+import org.codehaus.plexus.component.configurator.expression.TypeAwareExpressionEvaluator;
+import org.codehaus.plexus.configuration.PlexusConfiguration;
+import org.codehaus.plexus.configuration.xml.XmlPlexusConfiguration;
+import org.codehaus.plexus.util.xml.Xpp3Dom;
+
+/**
+ * <strong>Warning:</strong> This is an internal class that is only public for technical reasons, it is not part of the
+ * public API. In particular, this class can be changed or deleted without prior notice.
+ *
+ * @author Benjamin Bentmann
+ */
+@Component( role = BeanConfigurator.class )
+public class DefaultBeanConfigurator
+ implements BeanConfigurator
+{
+
+ private final ConverterLookup converterLookup = new DefaultConverterLookup();
+
+ public void configureBean( BeanConfigurationRequest request )
+ throws BeanConfigurationException
+ {
+ if ( request == null )
+ {
+ throw new IllegalArgumentException( "bean configuration request not specified" );
+ }
+
+ if ( request.getBean() == null )
+ {
+ throw new IllegalArgumentException( "bean to be configured not specified" );
+ }
+
+ Object configuration = request.getConfiguration();
+ if ( configuration == null )
+ {
+ return;
+ }
+
+ PlexusConfiguration plexusConfig;
+ if ( configuration instanceof PlexusConfiguration )
+ {
+ plexusConfig = (PlexusConfiguration) configuration;
+ }
+ else if ( configuration instanceof Xpp3Dom )
+ {
+ plexusConfig = new XmlPlexusConfiguration( (Xpp3Dom) configuration );
+ }
+ else
+ {
+ throw new BeanConfigurationException( "unsupported bean configuration source ("
+ + configuration.getClass().getName() + ")" );
+ }
+
+ if ( request.getConfigurationElement() != null )
+ {
+ plexusConfig = plexusConfig.getChild( request.getConfigurationElement() );
+ }
+
+ ClassLoader classLoader = request.getClassLoader();
+ if ( classLoader == null )
+ {
+ classLoader = request.getBean().getClass().getClassLoader();
+ }
+
+ BeanExpressionEvaluator evaluator = new BeanExpressionEvaluator( request );
+
+ ObjectWithFieldsConverter converter = new ObjectWithFieldsConverter();
+
+ try
+ {
+ converter.processConfiguration( converterLookup, request.getBean(), classLoader, plexusConfig, evaluator );
+ }
+ catch ( ComponentConfigurationException e )
+ {
+ throw new BeanConfigurationException( e.getMessage(), e );
+ }
+ }
+
+ static class BeanExpressionEvaluator
+ implements TypeAwareExpressionEvaluator
+ {
+
+ private final BeanConfigurationValuePreprocessor preprocessor;
+
+ private final BeanConfigurationPathTranslator translator;
+
+ public BeanExpressionEvaluator( BeanConfigurationRequest request )
+ {
+ preprocessor = request.getValuePreprocessor();
+ translator = request.getPathTranslator();
+ }
+
+ public Object evaluate( String expression, Class<?> type )
+ throws ExpressionEvaluationException
+ {
+ if ( preprocessor != null )
+ {
+ try
+ {
+ return preprocessor.preprocessValue( expression, type );
+ }
+ catch ( BeanConfigurationException e )
+ {
+ throw new ExpressionEvaluationException( e.getMessage(), e );
+ }
+ }
+ return expression;
+ }
+
+ public Object evaluate( String expression )
+ throws ExpressionEvaluationException
+ {
+ return evaluate( expression, null );
+ }
+
+ public File alignToBaseDirectory( File file )
+ {
+ if ( translator != null )
+ {
+ return translator.translatePath( file );
+ }
+ return file;
+ }
+
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/eventspy/AbstractEventSpy.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/eventspy/AbstractEventSpy.java
new file mode 100644
index 00000000..09132275
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/eventspy/AbstractEventSpy.java
@@ -0,0 +1,45 @@
+package org.apache.maven.eventspy;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * A skeleton eventspy that does nothing other than helping implementors.
+ * @since 3.0.2
+ */
+public abstract class AbstractEventSpy
+ implements EventSpy
+{
+
+ public void init( Context context )
+ throws Exception
+ {
+ }
+
+ public void onEvent( Object event )
+ throws Exception
+ {
+ }
+
+ public void close()
+ throws Exception
+ {
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/eventspy/EventSpy.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/eventspy/EventSpy.java
new file mode 100644
index 00000000..4284fce9
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/eventspy/EventSpy.java
@@ -0,0 +1,77 @@
+package org.apache.maven.eventspy;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Map;
+
+/**
+ * A core extension to monitor Maven's execution. Typically, such an extension gets loaded into Maven by specifying the
+ * system property {@code maven.ext.class.path} on the command line. As soon as dependency injection is setup, Maven
+ * looks up all implementators of this interface and calls their {@link #init(Context)} method. <em>Note:</em>
+ * Implementors are strongly advised to inherit from {@link AbstractEventSpy} instead of directly implementing this
+ * interface.
+ * @since 3.0.2
+ */
+public interface EventSpy
+{
+
+ interface Context
+ {
+
+ /**
+ * Gets key-value pairs providing information about the Maven runtime.
+ *
+ * @return The key-value pairs, never {@code null}.
+ */
+ Map<String, Object> getData();
+
+ }
+
+ /**
+ * Initializes the spy.
+ *
+ * @param context The event spy context, never {@code null}.
+ */
+ void init( Context context )
+ throws Exception;
+
+ /**
+ * Notifies the spy of some build event/operation.
+ *
+ * @param event The event, never {@code null}.
+ * @see org.apache.maven.settings.building.SettingsBuildingRequest
+ * @see org.apache.maven.settings.building.SettingsBuildingResult
+ * @see org.apache.maven.execution.MavenExecutionRequest
+ * @see org.apache.maven.execution.MavenExecutionResult
+ * @see org.apache.maven.project.DependencyResolutionRequest
+ * @see org.apache.maven.project.DependencyResolutionResult
+ * @see org.apache.maven.execution.ExecutionEvent
+ * @see org.eclipse.aether.RepositoryEvent
+ */
+ void onEvent( Object event )
+ throws Exception;
+
+ /**
+ * Notifies the spy of Maven's termination, allowing it to free any resources allocated by it.
+ */
+ void close()
+ throws Exception;
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/eventspy/internal/EventSpyDispatcher.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/eventspy/internal/EventSpyDispatcher.java
new file mode 100644
index 00000000..d44642d1
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/eventspy/internal/EventSpyDispatcher.java
@@ -0,0 +1,158 @@
+package org.apache.maven.eventspy.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.maven.eventspy.EventSpy;
+import org.apache.maven.execution.ExecutionListener;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+import org.codehaus.plexus.logging.Logger;
+import org.eclipse.aether.RepositoryListener;
+
+/**
+ * Dispatches callbacks to all registered eventspies.
+ * @since 3.0.2
+ */
+@Component( role = EventSpyDispatcher.class )
+public class EventSpyDispatcher
+{
+
+ @Requirement
+ private Logger logger;
+
+ @Requirement( role = EventSpy.class )
+ private List<EventSpy> eventSpies;
+
+ public void setEventSpies( List<EventSpy> eventSpies )
+ {
+ // make copy to get rid of needless overhead for dynamic lookups
+ this.eventSpies = new ArrayList<EventSpy>( eventSpies );
+ }
+
+ public List<EventSpy> getEventSpies()
+ {
+ return eventSpies;
+ }
+
+ public ExecutionListener chainListener( ExecutionListener listener )
+ {
+ if ( eventSpies.isEmpty() )
+ {
+ return listener;
+ }
+ return new EventSpyExecutionListener( this, listener );
+ }
+
+ public RepositoryListener chainListener( RepositoryListener listener )
+ {
+ if ( eventSpies.isEmpty() )
+ {
+ return listener;
+ }
+ return new EventSpyRepositoryListener( this, listener );
+ }
+
+ public void init( EventSpy.Context context )
+ {
+ if ( eventSpies.isEmpty() )
+ {
+ return;
+ }
+ for ( EventSpy eventSpy : eventSpies )
+ {
+ try
+ {
+ eventSpy.init( context );
+ }
+ catch ( Exception e )
+ {
+ logError( "initialize", e, eventSpy );
+ }
+ catch ( LinkageError e )
+ {
+ logError( "initialize", e, eventSpy );
+ }
+ }
+ }
+
+ public void onEvent( Object event )
+ {
+ if ( eventSpies.isEmpty() )
+ {
+ return;
+ }
+ for ( EventSpy eventSpy : eventSpies )
+ {
+ try
+ {
+ eventSpy.onEvent( event );
+ }
+ catch ( Exception e )
+ {
+ logError( "notify", e, eventSpy );
+ }
+ catch ( LinkageError e )
+ {
+ logError( "notify", e, eventSpy );
+ }
+ }
+ }
+
+ public void close()
+ {
+ if ( eventSpies.isEmpty() )
+ {
+ return;
+ }
+ for ( EventSpy eventSpy : eventSpies )
+ {
+ try
+ {
+ eventSpy.close();
+ }
+ catch ( Exception e )
+ {
+ logError( "close", e, eventSpy );
+ }
+ catch ( LinkageError e )
+ {
+ logError( "close", e, eventSpy );
+ }
+ }
+ }
+
+ private void logError( String action, Throwable e, EventSpy spy )
+ {
+ String msg = "Failed to " + action + " spy " + spy.getClass().getName() + ": " + e.getMessage();
+
+ if ( logger.isDebugEnabled() )
+ {
+ logger.warn( msg, e );
+ }
+ else
+ {
+ logger.warn( msg );
+ }
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/eventspy/internal/EventSpyExecutionListener.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/eventspy/internal/EventSpyExecutionListener.java
new file mode 100644
index 00000000..6b25da58
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/eventspy/internal/EventSpyExecutionListener.java
@@ -0,0 +1,163 @@
+package org.apache.maven.eventspy.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.execution.AbstractExecutionListener;
+import org.apache.maven.execution.ExecutionEvent;
+import org.apache.maven.execution.ExecutionListener;
+
+/**
+ * Forwards execution events to eventspies.
+ * @since 3.0.2
+ */
+class EventSpyExecutionListener
+ extends AbstractExecutionListener
+{
+
+ private final EventSpyDispatcher dispatcher;
+
+ private final ExecutionListener delegate;
+
+ public EventSpyExecutionListener( EventSpyDispatcher dispatcher, ExecutionListener delegate )
+ {
+ this.dispatcher = dispatcher;
+ this.delegate = delegate;
+ }
+
+ @Override
+ public void projectDiscoveryStarted( ExecutionEvent event )
+ {
+ dispatcher.onEvent( event );
+ delegate.projectDiscoveryStarted( event );
+ }
+
+ @Override
+ public void sessionStarted( ExecutionEvent event )
+ {
+ dispatcher.onEvent( event );
+ delegate.sessionStarted( event );
+ }
+
+ @Override
+ public void sessionEnded( ExecutionEvent event )
+ {
+ dispatcher.onEvent( event );
+ delegate.sessionEnded( event );
+ }
+
+ @Override
+ public void projectSkipped( ExecutionEvent event )
+ {
+ dispatcher.onEvent( event );
+ delegate.projectSkipped( event );
+ }
+
+ @Override
+ public void projectStarted( ExecutionEvent event )
+ {
+ dispatcher.onEvent( event );
+ delegate.projectStarted( event );
+ }
+
+ @Override
+ public void projectSucceeded( ExecutionEvent event )
+ {
+ dispatcher.onEvent( event );
+ delegate.projectSucceeded( event );
+ }
+
+ @Override
+ public void projectFailed( ExecutionEvent event )
+ {
+ dispatcher.onEvent( event );
+ delegate.projectFailed( event );
+ }
+
+ @Override
+ public void forkStarted( ExecutionEvent event )
+ {
+ dispatcher.onEvent( event );
+ delegate.forkStarted( event );
+ }
+
+ @Override
+ public void forkSucceeded( ExecutionEvent event )
+ {
+ dispatcher.onEvent( event );
+ delegate.forkSucceeded( event );
+ }
+
+ @Override
+ public void forkFailed( ExecutionEvent event )
+ {
+ dispatcher.onEvent( event );
+ delegate.forkFailed( event );
+ }
+
+ @Override
+ public void mojoSkipped( ExecutionEvent event )
+ {
+ dispatcher.onEvent( event );
+ delegate.mojoSkipped( event );
+ }
+
+ @Override
+ public void mojoStarted( ExecutionEvent event )
+ {
+ dispatcher.onEvent( event );
+ delegate.mojoStarted( event );
+ }
+
+ @Override
+ public void mojoSucceeded( ExecutionEvent event )
+ {
+ dispatcher.onEvent( event );
+ delegate.mojoSucceeded( event );
+ }
+
+ @Override
+ public void mojoFailed( ExecutionEvent event )
+ {
+ dispatcher.onEvent( event );
+ delegate.mojoFailed( event );
+ }
+
+ @Override
+ public void forkedProjectStarted( ExecutionEvent event )
+ {
+ dispatcher.onEvent( event );
+ delegate.forkedProjectStarted( event );
+ }
+
+ @Override
+ public void forkedProjectSucceeded( ExecutionEvent event )
+ {
+ dispatcher.onEvent( event );
+ delegate.forkedProjectSucceeded( event );
+ }
+
+ @Override
+ public void forkedProjectFailed( ExecutionEvent event )
+ {
+ dispatcher.onEvent( event );
+ delegate.forkedProjectFailed( event );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/eventspy/internal/EventSpyRepositoryListener.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/eventspy/internal/EventSpyRepositoryListener.java
new file mode 100644
index 00000000..60d4cd1c
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/eventspy/internal/EventSpyRepositoryListener.java
@@ -0,0 +1,176 @@
+package org.apache.maven.eventspy.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.eclipse.aether.AbstractRepositoryListener;
+import org.eclipse.aether.RepositoryEvent;
+import org.eclipse.aether.RepositoryListener;
+
+/**
+ * Forwards repository events to eventspies.
+ * @since 3.0.2
+ */
+class EventSpyRepositoryListener
+ extends AbstractRepositoryListener
+{
+ private final EventSpyDispatcher dispatcher;
+
+ private final RepositoryListener delegate;
+
+ public EventSpyRepositoryListener( EventSpyDispatcher dispatcher, RepositoryListener delegate )
+ {
+ this.dispatcher = dispatcher;
+ this.delegate = delegate;
+ }
+
+ @Override
+ public void artifactDeployed( RepositoryEvent event )
+ {
+ dispatcher.onEvent( event );
+ delegate.artifactDeployed( event );
+ }
+
+ @Override
+ public void artifactDeploying( RepositoryEvent event )
+ {
+ dispatcher.onEvent( event );
+ delegate.artifactDeploying( event );
+ }
+
+ @Override
+ public void artifactDescriptorInvalid( RepositoryEvent event )
+ {
+ dispatcher.onEvent( event );
+ delegate.artifactDescriptorInvalid( event );
+ }
+
+ @Override
+ public void artifactDescriptorMissing( RepositoryEvent event )
+ {
+ dispatcher.onEvent( event );
+ delegate.artifactDescriptorMissing( event );
+ }
+
+ @Override
+ public void artifactInstalled( RepositoryEvent event )
+ {
+ dispatcher.onEvent( event );
+ delegate.artifactInstalled( event );
+ }
+
+ @Override
+ public void artifactInstalling( RepositoryEvent event )
+ {
+ dispatcher.onEvent( event );
+ delegate.artifactInstalling( event );
+ }
+
+ @Override
+ public void artifactResolved( RepositoryEvent event )
+ {
+ dispatcher.onEvent( event );
+ delegate.artifactResolved( event );
+ }
+
+ @Override
+ public void artifactResolving( RepositoryEvent event )
+ {
+ dispatcher.onEvent( event );
+ delegate.artifactResolving( event );
+ }
+
+ @Override
+ public void metadataDeployed( RepositoryEvent event )
+ {
+ dispatcher.onEvent( event );
+ delegate.metadataDeployed( event );
+ }
+
+ @Override
+ public void metadataDeploying( RepositoryEvent event )
+ {
+ dispatcher.onEvent( event );
+ delegate.metadataDeploying( event );
+ }
+
+ @Override
+ public void metadataInstalled( RepositoryEvent event )
+ {
+ dispatcher.onEvent( event );
+ delegate.metadataInstalled( event );
+ }
+
+ @Override
+ public void metadataInstalling( RepositoryEvent event )
+ {
+ dispatcher.onEvent( event );
+ delegate.metadataInstalling( event );
+ }
+
+ @Override
+ public void metadataInvalid( RepositoryEvent event )
+ {
+ dispatcher.onEvent( event );
+ delegate.metadataInvalid( event );
+ }
+
+ @Override
+ public void metadataResolved( RepositoryEvent event )
+ {
+ dispatcher.onEvent( event );
+ delegate.metadataResolved( event );
+ }
+
+ @Override
+ public void metadataResolving( RepositoryEvent event )
+ {
+ dispatcher.onEvent( event );
+ delegate.metadataResolving( event );
+ }
+
+ @Override
+ public void artifactDownloaded( RepositoryEvent event )
+ {
+ dispatcher.onEvent( event );
+ delegate.artifactDownloaded( event );
+ }
+
+ @Override
+ public void artifactDownloading( RepositoryEvent event )
+ {
+ dispatcher.onEvent( event );
+ delegate.artifactDownloading( event );
+ }
+
+ @Override
+ public void metadataDownloaded( RepositoryEvent event )
+ {
+ dispatcher.onEvent( event );
+ delegate.metadataDownloaded( event );
+ }
+
+ @Override
+ public void metadataDownloading( RepositoryEvent event )
+ {
+ dispatcher.onEvent( event );
+ delegate.metadataDownloading( event );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/exception/DefaultExceptionHandler.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/exception/DefaultExceptionHandler.java
new file mode 100644
index 00000000..6df72c81
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/exception/DefaultExceptionHandler.java
@@ -0,0 +1,336 @@
+package org.apache.maven.exception;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.IOException;
+import java.net.ConnectException;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.maven.lifecycle.LifecycleExecutionException;
+import org.apache.maven.model.building.ModelProblem;
+import org.apache.maven.model.building.ModelProblemUtils;
+import org.apache.maven.plugin.AbstractMojoExecutionException;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugin.PluginContainerException;
+import org.apache.maven.plugin.PluginExecutionException;
+import org.apache.maven.project.ProjectBuildingException;
+import org.apache.maven.project.ProjectBuildingResult;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.util.StringUtils;
+
+/*
+
+- test projects for each of these
+- how to categorize the problems so that the id of the problem can be match to a page with descriptive help and the test
+ project
+- nice little sample projects that could be run in the core as well as integration tests
+
+All Possible Errors
+- invalid lifecycle phase (maybe same as bad CLI param, though you were talking about embedder too)
+- <module> specified is not found
+- malformed settings
+- malformed POM
+- local repository not writable
+- remote repositories not available
+- artifact metadata missing
+- extension metadata missing
+- extension artifact missing
+- artifact metadata retrieval problem
+- version range violation
+- circular dependency
+- artifact missing
+- artifact retrieval exception
+- md5 checksum doesn't match for local artifact, need to redownload this
+- POM doesn't exist for a goal that requires one
+- parent POM missing (in both the repository + relative path)
+- component not found
+
+Plugins:
+- plugin metadata missing
+- plugin metadata retrieval problem
+- plugin artifact missing
+- plugin artifact retrieval problem
+- plugin dependency metadata missing
+- plugin dependency metadata retrieval problem
+- plugin configuration problem
+- plugin execution failure due to something that is know to possibly go wrong (like compilation failure)
+- plugin execution error due to something that is not expected to go wrong (the compiler executable missing)
+- asking to use a plugin for which you do not have a version defined - tools to easily select versions
+- goal not found in a plugin (probably could list the ones that are)
+
+ */
+
+// PluginNotFoundException, PluginResolutionException, PluginDescriptorParsingException,
+// CycleDetectedInPluginGraphException;
+
+@Component( role = ExceptionHandler.class )
+public class DefaultExceptionHandler
+ implements ExceptionHandler
+{
+
+ public ExceptionSummary handleException( Throwable exception )
+ {
+ return handle( "", exception );
+ }
+
+ private ExceptionSummary handle( String message, Throwable exception )
+ {
+ String reference = getReference( exception );
+
+ List<ExceptionSummary> children = null;
+
+ if ( exception instanceof ProjectBuildingException )
+ {
+ List<ProjectBuildingResult> results = ( (ProjectBuildingException) exception ).getResults();
+
+ children = new ArrayList<ExceptionSummary>();
+
+ for ( ProjectBuildingResult result : results )
+ {
+ ExceptionSummary child = handle( result );
+ if ( child != null )
+ {
+ children.add( child );
+ }
+ }
+
+ message = "The build could not read " + children.size() + " project" + ( children.size() == 1 ? "" : "s" );
+ }
+ else
+ {
+ message = getMessage( message, exception );
+ }
+
+ return new ExceptionSummary( exception, message, reference, children );
+ }
+
+ private ExceptionSummary handle( ProjectBuildingResult result )
+ {
+ List<ExceptionSummary> children = new ArrayList<ExceptionSummary>();
+
+ for ( ModelProblem problem : result.getProblems() )
+ {
+ ExceptionSummary child = handle( problem, result.getProjectId() );
+ if ( child != null )
+ {
+ children.add( child );
+ }
+ }
+
+ if ( children.isEmpty() )
+ {
+ return null;
+ }
+
+ String message =
+ "\nThe project " + result.getProjectId() + " (" + result.getPomFile() + ") has "
+ + children.size() + " error" + ( children.size() == 1 ? "" : "s" );
+
+ return new ExceptionSummary( null, message, null, children );
+ }
+
+ private ExceptionSummary handle( ModelProblem problem, String projectId )
+ {
+ if ( ModelProblem.Severity.ERROR.compareTo( problem.getSeverity() ) >= 0 )
+ {
+ String message = problem.getMessage();
+
+ String location = ModelProblemUtils.formatLocation( problem, projectId );
+
+ if ( StringUtils.isNotEmpty( location ) )
+ {
+ message += " @ " + location;
+ }
+
+ return handle( message, problem.getException() );
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ private String getReference( Throwable exception )
+ {
+ String reference = "";
+
+ if ( exception != null )
+ {
+ if ( exception instanceof MojoExecutionException )
+ {
+ reference = MojoExecutionException.class.getSimpleName();
+
+ Throwable cause = exception.getCause();
+ if ( cause instanceof IOException )
+ {
+ cause = cause.getCause();
+ if ( cause instanceof ConnectException )
+ {
+ reference = ConnectException.class.getSimpleName();
+ }
+ }
+ }
+ else if ( exception instanceof MojoFailureException )
+ {
+ reference = MojoFailureException.class.getSimpleName();
+ }
+ else if ( exception instanceof LinkageError )
+ {
+ reference = LinkageError.class.getSimpleName();
+ }
+ else if ( exception instanceof PluginExecutionException )
+ {
+ Throwable cause = exception.getCause();
+
+ if ( cause instanceof PluginContainerException )
+ {
+ Throwable cause2 = cause.getCause();
+
+ if ( cause2 instanceof NoClassDefFoundError
+ && cause2.getMessage().contains( "org/sonatype/aether/" ) )
+ {
+ reference = "AetherClassNotFound";
+ }
+ }
+
+ if ( StringUtils.isEmpty( reference ) )
+ {
+ reference = getReference( cause );
+ }
+
+ if ( StringUtils.isEmpty( reference ) )
+ {
+ reference = exception.getClass().getSimpleName();
+ }
+ }
+ else if ( exception instanceof LifecycleExecutionException )
+ {
+ reference = getReference( exception.getCause() );
+ }
+ else if ( isNoteworthyException( exception ) )
+ {
+ reference = exception.getClass().getSimpleName();
+ }
+ }
+
+ if ( StringUtils.isNotEmpty( reference ) && !reference.startsWith( "http:" ) )
+ {
+ reference = "http://cwiki.apache.org/confluence/display/MAVEN/" + reference;
+ }
+
+ return reference;
+ }
+
+ private boolean isNoteworthyException( Throwable exception )
+ {
+ if ( exception == null )
+ {
+ return false;
+ }
+ else if ( exception instanceof Error )
+ {
+ return true;
+ }
+ else if ( exception instanceof RuntimeException )
+ {
+ return false;
+ }
+ else if ( exception.getClass().getName().startsWith( "java" ) )
+ {
+ return false;
+ }
+ return true;
+ }
+
+ private String getMessage( String message, Throwable exception )
+ {
+ String fullMessage = ( message != null ) ? message : "";
+
+ for ( Throwable t = exception; t != null; t = t.getCause() )
+ {
+ String exceptionMessage = t.getMessage();
+
+ if ( t instanceof AbstractMojoExecutionException )
+ {
+ String longMessage = ( (AbstractMojoExecutionException) t ).getLongMessage();
+ if ( StringUtils.isNotEmpty( longMessage ) )
+ {
+ if ( StringUtils.isEmpty( exceptionMessage ) || longMessage.contains( exceptionMessage ) )
+ {
+ exceptionMessage = longMessage;
+ }
+ else if ( !exceptionMessage.contains( longMessage ) )
+ {
+ exceptionMessage = join( exceptionMessage, '\n' + longMessage );
+ }
+ }
+ }
+
+ if ( StringUtils.isEmpty( exceptionMessage ) )
+ {
+ exceptionMessage = t.getClass().getSimpleName();
+ }
+
+ if ( t instanceof UnknownHostException && !fullMessage.contains( "host" ) )
+ {
+ fullMessage = join( fullMessage, "Unknown host " + exceptionMessage );
+ }
+ else if ( !fullMessage.contains( exceptionMessage ) )
+ {
+ fullMessage = join( fullMessage, exceptionMessage );
+ }
+ }
+
+ return fullMessage.trim();
+ }
+
+ private String join( String message1, String message2 )
+ {
+ String message = "";
+
+ if ( StringUtils.isNotEmpty( message1 ) )
+ {
+ message = message1.trim();
+ }
+
+ if ( StringUtils.isNotEmpty( message2 ) )
+ {
+ if ( StringUtils.isNotEmpty( message ) )
+ {
+ if ( message.endsWith( "." ) || message.endsWith( "!" ) || message.endsWith( ":" ) )
+ {
+ message += " ";
+ }
+ else
+ {
+ message += ": ";
+ }
+ }
+
+ message += message2;
+ }
+
+ return message;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/exception/ExceptionHandler.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/exception/ExceptionHandler.java
new file mode 100644
index 00000000..47865f67
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/exception/ExceptionHandler.java
@@ -0,0 +1,30 @@
+package org.apache.maven.exception;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Transform an exception into useful end-user message.
+ *
+ * @since 3.0-alpha-3
+ */
+public interface ExceptionHandler
+{
+ ExceptionSummary handleException( Throwable e );
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/exception/ExceptionSummary.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/exception/ExceptionSummary.java
new file mode 100644
index 00000000..dcc376a4
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/exception/ExceptionSummary.java
@@ -0,0 +1,79 @@
+package org.apache.maven.exception;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Provide a summary of the exception, containing:<ul>
+ * <li>the exception itself,</li>
+ * <li>useful end-user message,</li>
+ * <li>useful reference to a solution, or set of solutions: this is usually a wiki page url in
+ * <a href="http://cwiki.apache.org/confluence/display/MAVEN/">http://cwiki.apache.org/confluence/display/MAVEN/</a>,
+ * </li>
+ * <li>child exception summaries.</li>
+ * </ul>
+ */
+public class ExceptionSummary
+{
+
+ private Throwable exception;
+
+ private String message;
+
+ private String reference;
+
+ private List<ExceptionSummary> children;
+
+ public ExceptionSummary( Throwable exception, String message, String reference )
+ {
+ this( exception, message, reference, null );
+ }
+
+ public ExceptionSummary( Throwable exception, String message, String reference, List<ExceptionSummary> children )
+ {
+ this.exception = exception;
+ this.message = ( message != null ) ? message : "";
+ this.reference = ( reference != null ) ? reference : "";
+ this.children = ( children != null ) ? children : Collections.<ExceptionSummary>emptyList();
+ }
+
+ public Throwable getException()
+ {
+ return exception;
+ }
+
+ public String getMessage()
+ {
+ return message;
+ }
+
+ public String getReference()
+ {
+ return reference;
+ }
+
+ public List<ExceptionSummary> getChildren()
+ {
+ return children;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/AbstractExecutionListener.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/AbstractExecutionListener.java
new file mode 100644
index 00000000..89665007
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/AbstractExecutionListener.java
@@ -0,0 +1,116 @@
+package org.apache.maven.execution;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Provides a skeleton implementation for execution listeners. The methods of this class are empty.
+ *
+ * @author Benjamin Bentmann
+ */
+public class AbstractExecutionListener
+ implements ExecutionListener
+{
+
+ public void projectDiscoveryStarted( ExecutionEvent event )
+ {
+ // default does nothing
+ }
+
+ public void sessionStarted( ExecutionEvent event )
+ {
+ // default does nothing
+ }
+
+ public void sessionEnded( ExecutionEvent event )
+ {
+ // default does nothing
+ }
+
+ public void projectSkipped( ExecutionEvent event )
+ {
+ // default does nothing
+ }
+
+ public void projectStarted( ExecutionEvent event )
+ {
+ // default does nothing
+ }
+
+ public void projectSucceeded( ExecutionEvent event )
+ {
+ // default does nothing
+ }
+
+ public void projectFailed( ExecutionEvent event )
+ {
+ // default does nothing
+ }
+
+ public void forkStarted( ExecutionEvent event )
+ {
+ // default does nothing
+ }
+
+ public void forkSucceeded( ExecutionEvent event )
+ {
+ // default does nothing
+ }
+
+ public void forkFailed( ExecutionEvent event )
+ {
+ // default does nothing
+ }
+
+ public void mojoSkipped( ExecutionEvent event )
+ {
+ // default does nothing
+ }
+
+ public void mojoStarted( ExecutionEvent event )
+ {
+ // default does nothing
+ }
+
+ public void mojoSucceeded( ExecutionEvent event )
+ {
+ // default does nothing
+ }
+
+ public void mojoFailed( ExecutionEvent event )
+ {
+ // default does nothing
+ }
+
+ public void forkedProjectStarted( ExecutionEvent event )
+ {
+ // default does nothing
+ }
+
+ public void forkedProjectSucceeded( ExecutionEvent event )
+ {
+ // default does nothing
+ }
+
+ public void forkedProjectFailed( ExecutionEvent event )
+ {
+ // default does nothing
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/BuildFailure.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/BuildFailure.java
new file mode 100644
index 00000000..bf8f62ba
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/BuildFailure.java
@@ -0,0 +1,61 @@
+package org.apache.maven.execution;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.project.MavenProject;
+
+/**
+ * Summarizes the result of a failed project build in the reactor.
+ *
+ * @author Benjamin Bentmann
+ */
+public class BuildFailure
+ extends BuildSummary
+{
+
+ /**
+ * The cause of the build failure.
+ */
+ private final Throwable cause;
+
+ /**
+ * Creates a new build summary for the specified project.
+ *
+ * @param project The project being summarized, must not be {@code null}.
+ * @param time The build time of the project in milliseconds.
+ * @param cause The cause of the build failure, may be {@code null}.
+ */
+ public BuildFailure( MavenProject project, long time, Throwable cause )
+ {
+ super( project, time );
+ this.cause = cause;
+ }
+
+ /**
+ * Gets the cause of the build failure.
+ *
+ * @return The cause of the build failure or {@code null} if unknown.
+ */
+ public Throwable getCause()
+ {
+ return cause;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/BuildSuccess.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/BuildSuccess.java
new file mode 100644
index 00000000..3d0e8bd7
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/BuildSuccess.java
@@ -0,0 +1,44 @@
+package org.apache.maven.execution;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.project.MavenProject;
+
+/**
+ * Summarizes the result of a successful project build in the reactor.
+ *
+ * @author Benjamin Bentmann
+ */
+public class BuildSuccess
+ extends BuildSummary
+{
+
+ /**
+ * Creates a new build summary for the specified project.
+ *
+ * @param project The project being summarized, must not be {@code null}.
+ * @param time The build time of the project in milliseconds.
+ */
+ public BuildSuccess( MavenProject project, long time )
+ {
+ super( project, time );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/BuildSummary.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/BuildSummary.java
new file mode 100644
index 00000000..ec23f721
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/BuildSummary.java
@@ -0,0 +1,78 @@
+package org.apache.maven.execution;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.project.MavenProject;
+
+/**
+ * Summarizes the result of a project build in the reactor.
+ *
+ * @author Benjamin Bentmann
+ */
+public abstract class BuildSummary
+{
+
+ /**
+ * The project being summarized.
+ */
+ private final MavenProject project;
+
+ /**
+ * The build time of the project in milliseconds.
+ */
+ private final long time;
+
+ /**
+ * Creates a new build summary for the specified project.
+ *
+ * @param project The project being summarized, must not be {@code null}.
+ * @param time The build time of the project in milliseconds.
+ */
+ protected BuildSummary( MavenProject project, long time )
+ {
+ if ( project == null )
+ {
+ throw new IllegalArgumentException( "project missing" );
+ }
+ this.project = project;
+ this.time = time;
+ }
+
+ /**
+ * Gets the project being summarized.
+ *
+ * @return The project being summarized, never {@code null}.
+ */
+ public MavenProject getProject()
+ {
+ return project;
+ }
+
+ /**
+ * Gets the build time of the project in milliseconds.
+ *
+ * @return The build time of the project in milliseconds.
+ */
+ public long getTime()
+ {
+ return time;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/DefaultMavenExecutionRequest.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/DefaultMavenExecutionRequest.java
new file mode 100644
index 00000000..e5509dca
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/DefaultMavenExecutionRequest.java
@@ -0,0 +1,1299 @@
+package org.apache.maven.execution;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.eventspy.internal.EventSpyDispatcher;
+import org.apache.maven.model.Profile;
+import org.apache.maven.project.DefaultProjectBuildingRequest;
+import org.apache.maven.project.ProjectBuildingRequest;
+import org.apache.maven.settings.Mirror;
+import org.apache.maven.settings.Proxy;
+import org.apache.maven.settings.Server;
+import org.apache.maven.toolchain.model.ToolchainModel;
+import org.eclipse.aether.DefaultRepositoryCache;
+import org.eclipse.aether.RepositoryCache;
+import org.eclipse.aether.repository.WorkspaceReader;
+import org.eclipse.aether.transfer.TransferListener;
+
+import com.google.common.collect.Maps;
+
+/**
+ * @author Jason van Zyl
+ */
+public class DefaultMavenExecutionRequest
+ implements MavenExecutionRequest
+{
+
+ private RepositoryCache repositoryCache = new DefaultRepositoryCache();
+
+ private WorkspaceReader workspaceReader;
+
+ private ArtifactRepository localRepository;
+
+ private EventSpyDispatcher eventSpyDispatcher;
+
+ private File localRepositoryPath;
+
+ private boolean offline = false;
+
+ private boolean interactiveMode = true;
+
+ private boolean cacheTransferError;
+
+ private boolean cacheNotFound;
+
+ private List<Proxy> proxies;
+
+ private List<Server> servers;
+
+ private List<Mirror> mirrors;
+
+ private List<Profile> profiles;
+
+ private List<String> pluginGroups;
+
+ private boolean isProjectPresent = true;
+
+ // ----------------------------------------------------------------------------
+ // We need to allow per execution user and global settings as the embedder
+ // might be running in a mode where its executing many threads with totally
+ // different settings.
+ // ----------------------------------------------------------------------------
+
+ private File userSettingsFile;
+
+ private File globalSettingsFile;
+
+ private File userToolchainsFile;
+
+ private File globalToolchainsFile;
+
+ // ----------------------------------------------------------------------------
+ // Request
+ // ----------------------------------------------------------------------------
+
+ private File multiModuleProjectDirectory;
+
+ private File basedir;
+
+ private List<String> goals;
+
+ private boolean useReactor = false;
+
+ private boolean recursive = true;
+
+ private File pom;
+
+ private String reactorFailureBehavior = REACTOR_FAIL_FAST;
+
+ private List<String> selectedProjects;
+
+ private List<String> excludedProjects;
+
+ private String resumeFrom;
+
+ private String makeBehavior;
+
+ private Properties systemProperties;
+
+ private Properties userProperties;
+
+ private Date startTime;
+
+ private boolean showErrors = false;
+
+ private List<String> activeProfiles;
+
+ private List<String> inactiveProfiles;
+
+ private TransferListener transferListener;
+
+ private int loggingLevel = LOGGING_LEVEL_INFO;
+
+ private String globalChecksumPolicy;
+
+ private boolean updateSnapshots = false;
+
+ private List<ArtifactRepository> remoteRepositories;
+
+ private List<ArtifactRepository> pluginArtifactRepositories;
+
+ private ExecutionListener executionListener;
+
+ private int degreeOfConcurrency = 1;
+
+ private String builderId = "singlethreaded";
+
+ private Map<String, List<ToolchainModel>> toolchains;
+
+ /**
+ * Suppress SNAPSHOT updates.
+ *
+ * @issue MNG-2681
+ */
+ private boolean noSnapshotUpdates;
+
+ private boolean useLegacyLocalRepositoryManager = false;
+
+ private Map<String, Object> data;
+
+ public DefaultMavenExecutionRequest()
+ {
+ }
+
+ public static MavenExecutionRequest copy( MavenExecutionRequest original )
+ {
+ DefaultMavenExecutionRequest copy = new DefaultMavenExecutionRequest();
+ copy.setLocalRepository( original.getLocalRepository() );
+ copy.setLocalRepositoryPath( original.getLocalRepositoryPath() );
+ copy.setOffline( original.isOffline() );
+ copy.setInteractiveMode( original.isInteractiveMode() );
+ copy.setCacheNotFound( original.isCacheNotFound() );
+ copy.setCacheTransferError( original.isCacheTransferError() );
+ copy.setProxies( original.getProxies() );
+ copy.setServers( original.getServers() );
+ copy.setMirrors( original.getMirrors() );
+ copy.setProfiles( original.getProfiles() );
+ copy.setPluginGroups( original.getPluginGroups() );
+ copy.setProjectPresent( original.isProjectPresent() );
+ copy.setUserSettingsFile( original.getUserSettingsFile() );
+ copy.setGlobalSettingsFile( original.getGlobalSettingsFile() );
+ copy.setUserToolchainsFile( original.getUserToolchainsFile() );
+ copy.setGlobalToolchainsFile( original.getGlobalToolchainsFile() );
+ copy.setBaseDirectory( ( original.getBaseDirectory() != null ) ? new File( original.getBaseDirectory() )
+ : null );
+ copy.setGoals( original.getGoals() );
+ copy.setRecursive( original.isRecursive() );
+ copy.setPom( original.getPom() );
+ copy.setSystemProperties( original.getSystemProperties() );
+ copy.setUserProperties( original.getUserProperties() );
+ copy.setShowErrors( original.isShowErrors() );
+ copy.setActiveProfiles( original.getActiveProfiles() );
+ copy.setInactiveProfiles( original.getInactiveProfiles() );
+ copy.setTransferListener( original.getTransferListener() );
+ copy.setLoggingLevel( original.getLoggingLevel() );
+ copy.setGlobalChecksumPolicy( original.getGlobalChecksumPolicy() );
+ copy.setUpdateSnapshots( original.isUpdateSnapshots() );
+ copy.setRemoteRepositories( original.getRemoteRepositories() );
+ copy.setPluginArtifactRepositories( original.getPluginArtifactRepositories() );
+ copy.setRepositoryCache( original.getRepositoryCache() );
+ copy.setWorkspaceReader( original.getWorkspaceReader() );
+ copy.setNoSnapshotUpdates( original.isNoSnapshotUpdates() );
+ copy.setExecutionListener( original.getExecutionListener() );
+ copy.setUseLegacyLocalRepository( original.isUseLegacyLocalRepository() );
+ copy.setBuilderId( original.getBuilderId() );
+ return copy;
+ }
+
+ @Override
+ public String getBaseDirectory()
+ {
+ if ( basedir == null )
+ {
+ return null;
+ }
+
+ return basedir.getAbsolutePath();
+ }
+
+ @Override
+ public ArtifactRepository getLocalRepository()
+ {
+ return localRepository;
+ }
+
+ @Override
+ public File getLocalRepositoryPath()
+ {
+ return localRepositoryPath;
+ }
+
+ @Override
+ public List<String> getGoals()
+ {
+ if ( goals == null )
+ {
+ goals = new ArrayList<String>();
+ }
+ return goals;
+ }
+
+ @Override
+ public Properties getSystemProperties()
+ {
+ if ( systemProperties == null )
+ {
+ systemProperties = new Properties();
+ }
+
+ return systemProperties;
+ }
+
+ @Override
+ public Properties getUserProperties()
+ {
+ if ( userProperties == null )
+ {
+ userProperties = new Properties();
+ }
+
+ return userProperties;
+ }
+
+ @Override
+ public File getPom()
+ {
+ return pom;
+ }
+
+ @Override
+ public String getReactorFailureBehavior()
+ {
+ return reactorFailureBehavior;
+ }
+
+ @Override
+ public List<String> getSelectedProjects()
+ {
+ if ( selectedProjects == null )
+ {
+ selectedProjects = new ArrayList<String>();
+ }
+
+ return selectedProjects;
+ }
+
+ @Override
+ public List<String> getExcludedProjects()
+ {
+ if ( excludedProjects == null )
+ {
+ excludedProjects = new ArrayList<String>();
+ }
+
+ return excludedProjects;
+ }
+
+ @Override
+ public String getResumeFrom()
+ {
+ return resumeFrom;
+ }
+
+ @Override
+ public String getMakeBehavior()
+ {
+ return makeBehavior;
+ }
+
+ @Override
+ public Date getStartTime()
+ {
+ return startTime;
+ }
+
+ @Override
+ public boolean isShowErrors()
+ {
+ return showErrors;
+ }
+
+ @Override
+ public boolean isInteractiveMode()
+ {
+ return interactiveMode;
+ }
+
+ @Override
+ public MavenExecutionRequest setActiveProfiles( List<String> activeProfiles )
+ {
+ if ( activeProfiles != null )
+ {
+ this.activeProfiles = new ArrayList<String>( activeProfiles );
+ }
+ else
+ {
+ this.activeProfiles = null;
+ }
+
+ return this;
+ }
+
+ @Override
+ public MavenExecutionRequest setInactiveProfiles( List<String> inactiveProfiles )
+ {
+ if ( inactiveProfiles != null )
+ {
+ this.inactiveProfiles = new ArrayList<String>( inactiveProfiles );
+ }
+ else
+ {
+ this.inactiveProfiles = null;
+ }
+
+ return this;
+ }
+
+ @Override
+ public MavenExecutionRequest setRemoteRepositories( List<ArtifactRepository> remoteRepositories )
+ {
+ if ( remoteRepositories != null )
+ {
+ this.remoteRepositories = new ArrayList<ArtifactRepository>( remoteRepositories );
+ }
+ else
+ {
+ this.remoteRepositories = null;
+ }
+
+ return this;
+ }
+
+ @Override
+ public MavenExecutionRequest setPluginArtifactRepositories( List<ArtifactRepository> pluginArtifactRepositories )
+ {
+ if ( pluginArtifactRepositories != null )
+ {
+ this.pluginArtifactRepositories = new ArrayList<ArtifactRepository>( pluginArtifactRepositories );
+ }
+ else
+ {
+ this.pluginArtifactRepositories = null;
+ }
+
+ return this;
+ }
+
+ public void setProjectBuildingConfiguration( ProjectBuildingRequest projectBuildingConfiguration )
+ {
+ this.projectBuildingRequest = projectBuildingConfiguration;
+ }
+
+ @Override
+ public List<String> getActiveProfiles()
+ {
+ if ( activeProfiles == null )
+ {
+ activeProfiles = new ArrayList<String>();
+ }
+ return activeProfiles;
+ }
+
+ @Override
+ public List<String> getInactiveProfiles()
+ {
+ if ( inactiveProfiles == null )
+ {
+ inactiveProfiles = new ArrayList<String>();
+ }
+ return inactiveProfiles;
+ }
+
+ @Override
+ public TransferListener getTransferListener()
+ {
+ return transferListener;
+ }
+
+ @Override
+ public int getLoggingLevel()
+ {
+ return loggingLevel;
+ }
+
+ @Override
+ public boolean isOffline()
+ {
+ return offline;
+ }
+
+ @Override
+ public boolean isUpdateSnapshots()
+ {
+ return updateSnapshots;
+ }
+
+ @Override
+ public boolean isNoSnapshotUpdates()
+ {
+ return noSnapshotUpdates;
+ }
+
+ @Override
+ public String getGlobalChecksumPolicy()
+ {
+ return globalChecksumPolicy;
+ }
+
+ @Override
+ public boolean isRecursive()
+ {
+ return recursive;
+ }
+
+ // ----------------------------------------------------------------------
+ //
+ // ----------------------------------------------------------------------
+
+ @Override
+ public MavenExecutionRequest setBaseDirectory( File basedir )
+ {
+ this.basedir = basedir;
+
+ return this;
+ }
+
+ @Override
+ public MavenExecutionRequest setStartTime( Date startTime )
+ {
+ this.startTime = startTime;
+
+ return this;
+ }
+
+ @Override
+ public MavenExecutionRequest setShowErrors( boolean showErrors )
+ {
+ this.showErrors = showErrors;
+
+ return this;
+ }
+
+ @Override
+ public MavenExecutionRequest setGoals( List<String> goals )
+ {
+ if ( goals != null )
+ {
+ this.goals = new ArrayList<String>( goals );
+ }
+ else
+ {
+ this.goals = null;
+ }
+
+ return this;
+ }
+
+ @Override
+ public MavenExecutionRequest setLocalRepository( ArtifactRepository localRepository )
+ {
+ this.localRepository = localRepository;
+
+ if ( localRepository != null )
+ {
+ setLocalRepositoryPath( new File( localRepository.getBasedir() ).getAbsoluteFile() );
+ }
+
+ return this;
+ }
+
+ @Override
+ public MavenExecutionRequest setLocalRepositoryPath( File localRepository )
+ {
+ localRepositoryPath = localRepository;
+
+ return this;
+ }
+
+ @Override
+ public MavenExecutionRequest setLocalRepositoryPath( String localRepository )
+ {
+ localRepositoryPath = ( localRepository != null ) ? new File( localRepository ) : null;
+
+ return this;
+ }
+
+ @Override
+ public MavenExecutionRequest setSystemProperties( Properties properties )
+ {
+ if ( properties != null )
+ {
+ this.systemProperties = new Properties();
+ this.systemProperties.putAll( properties );
+ }
+ else
+ {
+ this.systemProperties = null;
+ }
+
+ return this;
+ }
+
+ @Override
+ public MavenExecutionRequest setUserProperties( Properties userProperties )
+ {
+ if ( userProperties != null )
+ {
+ this.userProperties = new Properties();
+ this.userProperties.putAll( userProperties );
+ }
+ else
+ {
+ this.userProperties = null;
+ }
+
+ return this;
+ }
+
+ @Override
+ public MavenExecutionRequest setReactorFailureBehavior( String failureBehavior )
+ {
+ reactorFailureBehavior = failureBehavior;
+
+ return this;
+ }
+
+ @Override
+ public MavenExecutionRequest setSelectedProjects( List<String> selectedProjects )
+ {
+ if ( selectedProjects != null )
+ {
+ this.selectedProjects = new ArrayList<String>( selectedProjects );
+ }
+ else
+ {
+ this.selectedProjects = null;
+ }
+
+ return this;
+ }
+
+ @Override
+ public MavenExecutionRequest setExcludedProjects( List<String> excludedProjects )
+ {
+ if ( excludedProjects != null )
+ {
+ this.excludedProjects = new ArrayList<String>( excludedProjects );
+ }
+ else
+ {
+ this.excludedProjects = null;
+ }
+
+ return this;
+ }
+
+ @Override
+ public MavenExecutionRequest setResumeFrom( String project )
+ {
+ this.resumeFrom = project;
+
+ return this;
+ }
+
+ @Override
+ public MavenExecutionRequest setMakeBehavior( String makeBehavior )
+ {
+ this.makeBehavior = makeBehavior;
+
+ return this;
+ }
+
+ @Override
+ public MavenExecutionRequest addActiveProfile( String profile )
+ {
+ if ( !getActiveProfiles().contains( profile ) )
+ {
+ getActiveProfiles().add( profile );
+ }
+
+ return this;
+ }
+
+ @Override
+ public MavenExecutionRequest addInactiveProfile( String profile )
+ {
+ if ( !getInactiveProfiles().contains( profile ) )
+ {
+ getInactiveProfiles().add( profile );
+ }
+
+ return this;
+ }
+
+ @Override
+ public MavenExecutionRequest addActiveProfiles( List<String> profiles )
+ {
+ for ( String profile : profiles )
+ {
+ addActiveProfile( profile );
+ }
+
+ return this;
+ }
+
+ @Override
+ public MavenExecutionRequest addInactiveProfiles( List<String> profiles )
+ {
+ for ( String profile : profiles )
+ {
+ addInactiveProfile( profile );
+ }
+
+ return this;
+ }
+
+ public MavenExecutionRequest setUseReactor( boolean reactorActive )
+ {
+ useReactor = reactorActive;
+
+ return this;
+ }
+
+ public boolean useReactor()
+ {
+ return useReactor;
+ }
+
+ /** @deprecated use {@link #setPom(File)} */
+ @Deprecated
+ public MavenExecutionRequest setPomFile( String pomFilename )
+ {
+ if ( pomFilename != null )
+ {
+ pom = new File( pomFilename );
+ }
+
+ return this;
+ }
+
+ @Override
+ public MavenExecutionRequest setPom( File pom )
+ {
+ this.pom = pom;
+
+ return this;
+ }
+
+ @Override
+ public MavenExecutionRequest setInteractiveMode( boolean interactive )
+ {
+ interactiveMode = interactive;
+
+ return this;
+ }
+
+ @Override
+ public MavenExecutionRequest setTransferListener( TransferListener transferListener )
+ {
+ this.transferListener = transferListener;
+
+ return this;
+ }
+
+ @Override
+ public MavenExecutionRequest setLoggingLevel( int loggingLevel )
+ {
+ this.loggingLevel = loggingLevel;
+
+ return this;
+ }
+
+ @Override
+ public MavenExecutionRequest setOffline( boolean offline )
+ {
+ this.offline = offline;
+
+ return this;
+ }
+
+ @Override
+ public MavenExecutionRequest setUpdateSnapshots( boolean updateSnapshots )
+ {
+ this.updateSnapshots = updateSnapshots;
+
+ return this;
+ }
+
+ @Override
+ public MavenExecutionRequest setNoSnapshotUpdates( boolean noSnapshotUpdates )
+ {
+ this.noSnapshotUpdates = noSnapshotUpdates;
+
+ return this;
+ }
+
+ @Override
+ public MavenExecutionRequest setGlobalChecksumPolicy( String globalChecksumPolicy )
+ {
+ this.globalChecksumPolicy = globalChecksumPolicy;
+
+ return this;
+ }
+
+ // ----------------------------------------------------------------------------
+ // Settings equivalents
+ // ----------------------------------------------------------------------------
+
+ @Override
+ public List<Proxy> getProxies()
+ {
+ if ( proxies == null )
+ {
+ proxies = new ArrayList<Proxy>();
+ }
+ return proxies;
+ }
+
+ @Override
+ public MavenExecutionRequest setProxies( List<Proxy> proxies )
+ {
+ if ( proxies != null )
+ {
+ this.proxies = new ArrayList<Proxy>( proxies );
+ }
+ else
+ {
+ this.proxies = null;
+ }
+
+ return this;
+ }
+
+ @Override
+ public MavenExecutionRequest addProxy( Proxy proxy )
+ {
+ if ( proxy == null )
+ {
+ throw new IllegalArgumentException( "proxy missing" );
+ }
+
+ for ( Proxy p : getProxies() )
+ {
+ if ( p.getId() != null && p.getId().equals( proxy.getId() ) )
+ {
+ return this;
+ }
+ }
+
+ getProxies().add( proxy );
+
+ return this;
+ }
+
+ @Override
+ public List<Server> getServers()
+ {
+ if ( servers == null )
+ {
+ servers = new ArrayList<Server>();
+ }
+ return servers;
+ }
+
+ @Override
+ public MavenExecutionRequest setServers( List<Server> servers )
+ {
+ if ( servers != null )
+ {
+ this.servers = new ArrayList<Server>( servers );
+ }
+ else
+ {
+ this.servers = null;
+ }
+
+ return this;
+ }
+
+ @Override
+ public MavenExecutionRequest addServer( Server server )
+ {
+ if ( server == null )
+ {
+ throw new IllegalArgumentException( "server missing" );
+ }
+
+ for ( Server p : getServers() )
+ {
+ if ( p.getId() != null && p.getId().equals( server.getId() ) )
+ {
+ return this;
+ }
+ }
+
+ getServers().add( server );
+
+ return this;
+ }
+
+ @Override
+ public List<Mirror> getMirrors()
+ {
+ if ( mirrors == null )
+ {
+ mirrors = new ArrayList<Mirror>();
+ }
+ return mirrors;
+ }
+
+ @Override
+ public MavenExecutionRequest setMirrors( List<Mirror> mirrors )
+ {
+ if ( mirrors != null )
+ {
+ this.mirrors = new ArrayList<Mirror>( mirrors );
+ }
+ else
+ {
+ this.mirrors = null;
+ }
+
+ return this;
+ }
+
+ @Override
+ public MavenExecutionRequest addMirror( Mirror mirror )
+ {
+ if ( mirror == null )
+ {
+ throw new IllegalArgumentException( "mirror missing" );
+ }
+
+ for ( Mirror p : getMirrors() )
+ {
+ if ( p.getId() != null && p.getId().equals( mirror.getId() ) )
+ {
+ return this;
+ }
+ }
+
+ getMirrors().add( mirror );
+
+ return this;
+ }
+
+ @Override
+ public List<Profile> getProfiles()
+ {
+ if ( profiles == null )
+ {
+ profiles = new ArrayList<Profile>();
+ }
+ return profiles;
+ }
+
+ @Override
+ public MavenExecutionRequest setProfiles( List<Profile> profiles )
+ {
+ if ( profiles != null )
+ {
+ this.profiles = new ArrayList<Profile>( profiles );
+ }
+ else
+ {
+ this.profiles = null;
+ }
+
+ return this;
+ }
+
+ @Override
+ public List<String> getPluginGroups()
+ {
+ if ( pluginGroups == null )
+ {
+ pluginGroups = new ArrayList<String>();
+ }
+
+ return pluginGroups;
+ }
+
+ @Override
+ public MavenExecutionRequest setPluginGroups( List<String> pluginGroups )
+ {
+ if ( pluginGroups != null )
+ {
+ this.pluginGroups = new ArrayList<String>( pluginGroups );
+ }
+ else
+ {
+ this.pluginGroups = null;
+ }
+
+ return this;
+ }
+
+ @Override
+ public MavenExecutionRequest addPluginGroup( String pluginGroup )
+ {
+ if ( !getPluginGroups().contains( pluginGroup ) )
+ {
+ getPluginGroups().add( pluginGroup );
+ }
+
+ return this;
+ }
+
+ @Override
+ public MavenExecutionRequest addPluginGroups( List<String> pluginGroups )
+ {
+ for ( String pluginGroup : pluginGroups )
+ {
+ addPluginGroup( pluginGroup );
+ }
+
+ return this;
+ }
+
+ @Override
+ public MavenExecutionRequest setRecursive( boolean recursive )
+ {
+ this.recursive = recursive;
+
+ return this;
+ }
+
+ // calculated from request attributes.
+ private ProjectBuildingRequest projectBuildingRequest;
+
+ @Override
+ public boolean isProjectPresent()
+ {
+ return isProjectPresent;
+ }
+
+ @Override
+ public MavenExecutionRequest setProjectPresent( boolean projectPresent )
+ {
+ isProjectPresent = projectPresent;
+
+ return this;
+ }
+
+ // Settings files
+
+ @Override
+ public File getUserSettingsFile()
+ {
+ return userSettingsFile;
+ }
+
+ @Override
+ public MavenExecutionRequest setUserSettingsFile( File userSettingsFile )
+ {
+ this.userSettingsFile = userSettingsFile;
+
+ return this;
+ }
+
+ @Override
+ public File getGlobalSettingsFile()
+ {
+ return globalSettingsFile;
+ }
+
+ @Override
+ public MavenExecutionRequest setGlobalSettingsFile( File globalSettingsFile )
+ {
+ this.globalSettingsFile = globalSettingsFile;
+
+ return this;
+ }
+
+ @Override
+ public File getUserToolchainsFile()
+ {
+ return userToolchainsFile;
+ }
+
+ @Override
+ public MavenExecutionRequest setUserToolchainsFile( File userToolchainsFile )
+ {
+ this.userToolchainsFile = userToolchainsFile;
+
+ return this;
+ }
+
+ @Override
+ public File getGlobalToolchainsFile()
+ {
+ return globalToolchainsFile;
+ }
+
+ @Override
+ public MavenExecutionRequest setGlobalToolchainsFile( File globalToolchainsFile )
+ {
+ this.globalToolchainsFile = globalToolchainsFile;
+ return this;
+ }
+
+ @Override
+ public MavenExecutionRequest addRemoteRepository( ArtifactRepository repository )
+ {
+ for ( ArtifactRepository repo : getRemoteRepositories() )
+ {
+ if ( repo.getId() != null && repo.getId().equals( repository.getId() ) )
+ {
+ return this;
+ }
+ }
+
+ getRemoteRepositories().add( repository );
+
+ return this;
+ }
+
+ @Override
+ public List<ArtifactRepository> getRemoteRepositories()
+ {
+ if ( remoteRepositories == null )
+ {
+ remoteRepositories = new ArrayList<ArtifactRepository>();
+ }
+ return remoteRepositories;
+ }
+
+ @Override
+ public MavenExecutionRequest addPluginArtifactRepository( ArtifactRepository repository )
+ {
+ for ( ArtifactRepository repo : getPluginArtifactRepositories() )
+ {
+ if ( repo.getId() != null && repo.getId().equals( repository.getId() ) )
+ {
+ return this;
+ }
+ }
+
+ getPluginArtifactRepositories().add( repository );
+
+ return this;
+ }
+
+ @Override
+ public List<ArtifactRepository> getPluginArtifactRepositories()
+ {
+ if ( pluginArtifactRepositories == null )
+ {
+ pluginArtifactRepositories = new ArrayList<ArtifactRepository>();
+ }
+ return pluginArtifactRepositories;
+ }
+
+ // TODO: this does not belong here.
+ @Override
+ public ProjectBuildingRequest getProjectBuildingRequest()
+ {
+ if ( projectBuildingRequest == null )
+ {
+ projectBuildingRequest = new DefaultProjectBuildingRequest();
+ projectBuildingRequest.setLocalRepository( getLocalRepository() );
+ projectBuildingRequest.setSystemProperties( getSystemProperties() );
+ projectBuildingRequest.setUserProperties( getUserProperties() );
+ projectBuildingRequest.setRemoteRepositories( getRemoteRepositories() );
+ projectBuildingRequest.setPluginArtifactRepositories( getPluginArtifactRepositories() );
+ projectBuildingRequest.setActiveProfileIds( getActiveProfiles() );
+ projectBuildingRequest.setInactiveProfileIds( getInactiveProfiles() );
+ projectBuildingRequest.setProfiles( getProfiles() );
+ projectBuildingRequest.setProcessPlugins( true );
+ projectBuildingRequest.setBuildStartTime( getStartTime() );
+ }
+
+ return projectBuildingRequest;
+ }
+
+ @Override
+ public MavenExecutionRequest addProfile( Profile profile )
+ {
+ if ( profile == null )
+ {
+ throw new IllegalArgumentException( "profile missing" );
+ }
+
+ for ( Profile p : getProfiles() )
+ {
+ if ( p.getId() != null && p.getId().equals( profile.getId() ) )
+ {
+ return this;
+ }
+ }
+
+ getProfiles().add( profile );
+
+ return this;
+ }
+
+ @Override
+ public RepositoryCache getRepositoryCache()
+ {
+ return repositoryCache;
+ }
+
+ @Override
+ public MavenExecutionRequest setRepositoryCache( RepositoryCache repositoryCache )
+ {
+ this.repositoryCache = repositoryCache;
+
+ return this;
+ }
+
+ @Override
+ public ExecutionListener getExecutionListener()
+ {
+ return executionListener;
+ }
+
+ @Override
+ public MavenExecutionRequest setExecutionListener( ExecutionListener executionListener )
+ {
+ this.executionListener = executionListener;
+
+ return this;
+ }
+
+ @Override
+ public void setDegreeOfConcurrency( final int degreeOfConcurrency )
+ {
+ this.degreeOfConcurrency = degreeOfConcurrency;
+ }
+
+ @Override
+ public int getDegreeOfConcurrency()
+ {
+ return degreeOfConcurrency;
+ }
+
+ @Override
+ public WorkspaceReader getWorkspaceReader()
+ {
+ return workspaceReader;
+ }
+
+ @Override
+ public MavenExecutionRequest setWorkspaceReader( WorkspaceReader workspaceReader )
+ {
+ this.workspaceReader = workspaceReader;
+ return this;
+ }
+
+ @Override
+ public boolean isCacheTransferError()
+ {
+ return cacheTransferError;
+ }
+
+ @Override
+ public MavenExecutionRequest setCacheTransferError( boolean cacheTransferError )
+ {
+ this.cacheTransferError = cacheTransferError;
+ return this;
+ }
+
+ @Override
+ public boolean isCacheNotFound()
+ {
+ return cacheNotFound;
+ }
+
+ @Override
+ public MavenExecutionRequest setCacheNotFound( boolean cacheNotFound )
+ {
+ this.cacheNotFound = cacheNotFound;
+ return this;
+ }
+
+ @Override
+ public boolean isUseLegacyLocalRepository()
+ {
+ return this.useLegacyLocalRepositoryManager;
+ }
+
+ @Override
+ public MavenExecutionRequest setUseLegacyLocalRepository( boolean useLegacyLocalRepositoryManager )
+ {
+ this.useLegacyLocalRepositoryManager = useLegacyLocalRepositoryManager;
+ return this;
+ }
+
+ @Override
+ public MavenExecutionRequest setBuilderId( String builderId )
+ {
+ this.builderId = builderId;
+ return this;
+ }
+
+ @Override
+ public String getBuilderId()
+ {
+ return builderId;
+ }
+
+ @Override
+ public Map<String, List<ToolchainModel>> getToolchains()
+ {
+ if ( toolchains == null )
+ {
+ toolchains = new HashMap<String, List<ToolchainModel>>();
+ }
+ return toolchains;
+ }
+
+ @Override
+ public MavenExecutionRequest setToolchains( Map<String, List<ToolchainModel>> toolchains )
+ {
+ this.toolchains = toolchains;
+ return this;
+ }
+
+ @Override
+ public void setMultiModuleProjectDirectory( File directory )
+ {
+ this.multiModuleProjectDirectory = directory;
+ }
+
+ @Override
+ public File getMultiModuleProjectDirectory()
+ {
+ return multiModuleProjectDirectory;
+ }
+
+ @Override
+ public MavenExecutionRequest setEventSpyDispatcher( EventSpyDispatcher eventSpyDispatcher )
+ {
+ this.eventSpyDispatcher = eventSpyDispatcher;
+ return this;
+ }
+
+ @Override
+ public EventSpyDispatcher getEventSpyDispatcher()
+ {
+ return eventSpyDispatcher;
+ }
+
+ @Override
+ public Map<String, Object> getData()
+ {
+ if ( data == null )
+ {
+ data = Maps.newHashMap();
+ }
+
+ return data;
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/DefaultMavenExecutionRequestPopulator.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/DefaultMavenExecutionRequestPopulator.java
new file mode 100644
index 00000000..7568fdee
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/DefaultMavenExecutionRequestPopulator.java
@@ -0,0 +1,318 @@
+package org.apache.maven.execution;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import org.apache.maven.artifact.InvalidRepositoryException;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.bridge.MavenRepositorySystem;
+import org.apache.maven.repository.RepositorySystem;
+//
+// All of this needs to go away and be couched in terms of the execution request
+//
+import org.apache.maven.settings.Mirror;
+import org.apache.maven.settings.Proxy;
+import org.apache.maven.settings.Repository;
+import org.apache.maven.settings.Server;
+import org.apache.maven.settings.Settings;
+import org.apache.maven.settings.SettingsUtils;
+//
+// Settings in core
+//
+import org.apache.maven.toolchain.model.PersistedToolchains;
+import org.apache.maven.toolchain.model.ToolchainModel;
+import org.codehaus.plexus.util.StringUtils;
+
+@Named
+public class DefaultMavenExecutionRequestPopulator
+ implements MavenExecutionRequestPopulator
+{
+
+ private final MavenRepositorySystem repositorySystem;
+
+ @Inject
+ public DefaultMavenExecutionRequestPopulator( MavenRepositorySystem repositorySystem )
+ {
+ this.repositorySystem = repositorySystem;
+ }
+
+
+ @Override
+ public MavenExecutionRequest populateFromToolchains( MavenExecutionRequest request, PersistedToolchains toolchains )
+ throws MavenExecutionRequestPopulationException
+ {
+ if ( toolchains != null )
+ {
+ Map<String, List<ToolchainModel>> groupedToolchains = new HashMap<String, List<ToolchainModel>>( 2 );
+
+ for ( ToolchainModel model : toolchains.getToolchains() )
+ {
+ if ( !groupedToolchains.containsKey( model.getType() ) )
+ {
+ groupedToolchains.put( model.getType(), new ArrayList<ToolchainModel>() );
+ }
+
+ groupedToolchains.get( model.getType() ).add( model );
+ }
+
+ request.setToolchains( groupedToolchains );
+ }
+ return request;
+ }
+
+ @Override
+ public MavenExecutionRequest populateDefaults( MavenExecutionRequest request )
+ throws MavenExecutionRequestPopulationException
+ {
+ baseDirectory( request );
+
+ localRepository( request );
+
+ populateDefaultPluginGroups( request );
+
+ injectDefaultRepositories( request );
+
+ injectDefaultPluginRepositories( request );
+
+ return request;
+ }
+
+ //
+ //
+ //
+
+ private void populateDefaultPluginGroups( MavenExecutionRequest request )
+ {
+ request.addPluginGroup( "org.apache.maven.plugins" );
+ request.addPluginGroup( "org.codehaus.mojo" );
+ }
+
+ private void injectDefaultRepositories( MavenExecutionRequest request )
+ throws MavenExecutionRequestPopulationException
+ {
+ Set<String> definedRepositories = repositorySystem.getRepoIds( request.getRemoteRepositories() );
+
+ if ( !definedRepositories.contains( RepositorySystem.DEFAULT_REMOTE_REPO_ID ) )
+ {
+ try
+ {
+ request.addRemoteRepository( repositorySystem.createDefaultRemoteRepository( request ) );
+ }
+ catch ( Exception e )
+ {
+ throw new MavenExecutionRequestPopulationException( "Cannot create default remote repository.", e );
+ }
+ }
+ }
+
+ private void injectDefaultPluginRepositories( MavenExecutionRequest request )
+ throws MavenExecutionRequestPopulationException
+ {
+ Set<String> definedRepositories = repositorySystem.getRepoIds( request.getPluginArtifactRepositories() );
+
+ if ( !definedRepositories.contains( RepositorySystem.DEFAULT_REMOTE_REPO_ID ) )
+ {
+ try
+ {
+ request.addPluginArtifactRepository( repositorySystem.createDefaultRemoteRepository( request ) );
+ }
+ catch ( Exception e )
+ {
+ throw new MavenExecutionRequestPopulationException( "Cannot create default remote repository.", e );
+ }
+ }
+ }
+
+ private void localRepository( MavenExecutionRequest request )
+ throws MavenExecutionRequestPopulationException
+ {
+ // ------------------------------------------------------------------------
+ // Local Repository
+ //
+ // 1. Use a value has been passed in via the configuration
+ // 2. Use value in the resultant settings
+ // 3. Use default value
+ // ------------------------------------------------------------------------
+
+ if ( request.getLocalRepository() == null )
+ {
+ request.setLocalRepository( createLocalRepository( request ) );
+ }
+
+ if ( request.getLocalRepositoryPath() == null )
+ {
+ request.setLocalRepositoryPath( new File( request.getLocalRepository().getBasedir() ).getAbsoluteFile() );
+ }
+ }
+
+ // ------------------------------------------------------------------------
+ // Artifact Transfer Mechanism
+ // ------------------------------------------------------------------------
+
+ private ArtifactRepository createLocalRepository( MavenExecutionRequest request )
+ throws MavenExecutionRequestPopulationException
+ {
+ String localRepositoryPath = null;
+
+ if ( request.getLocalRepositoryPath() != null )
+ {
+ localRepositoryPath = request.getLocalRepositoryPath().getAbsolutePath();
+ }
+
+ if ( StringUtils.isEmpty( localRepositoryPath ) )
+ {
+ localRepositoryPath = RepositorySystem.defaultUserLocalRepository.getAbsolutePath();
+ }
+
+ try
+ {
+ return repositorySystem.createLocalRepository( request, new File( localRepositoryPath ) );
+ }
+ catch ( Exception e )
+ {
+ throw new MavenExecutionRequestPopulationException( "Cannot create local repository.", e );
+ }
+ }
+
+ private void baseDirectory( MavenExecutionRequest request )
+ {
+ if ( request.getBaseDirectory() == null && request.getPom() != null )
+ {
+ request.setBaseDirectory( request.getPom().getAbsoluteFile().getParentFile() );
+ }
+ }
+
+ /*if_not[MAVEN4]*/
+
+ @Override
+ @Deprecated
+ public MavenExecutionRequest populateFromSettings( MavenExecutionRequest request, Settings settings )
+ throws MavenExecutionRequestPopulationException
+ {
+ if ( settings == null )
+ {
+ return request;
+ }
+
+ request.setOffline( settings.isOffline() );
+
+ request.setInteractiveMode( settings.isInteractiveMode() );
+
+ request.setPluginGroups( settings.getPluginGroups() );
+
+ request.setLocalRepositoryPath( settings.getLocalRepository() );
+
+ for ( Server server : settings.getServers() )
+ {
+ server = server.clone();
+
+ request.addServer( server );
+ }
+
+ // <proxies>
+ // <proxy>
+ // <active>true</active>
+ // <protocol>http</protocol>
+ // <host>proxy.somewhere.com</host>
+ // <port>8080</port>
+ // <username>proxyuser</username>
+ // <password>somepassword</password>
+ // <nonProxyHosts>www.google.com|*.somewhere.com</nonProxyHosts>
+ // </proxy>
+ // </proxies>
+
+ for ( Proxy proxy : settings.getProxies() )
+ {
+ if ( !proxy.isActive() )
+ {
+ continue;
+ }
+
+ proxy = proxy.clone();
+
+ request.addProxy( proxy );
+ }
+
+ // <mirrors>
+ // <mirror>
+ // <id>nexus</id>
+ // <mirrorOf>*</mirrorOf>
+ // <url>http://repository.sonatype.org/content/groups/public</url>
+ // </mirror>
+ // </mirrors>
+
+ for ( Mirror mirror : settings.getMirrors() )
+ {
+ mirror = mirror.clone();
+
+ request.addMirror( mirror );
+ }
+
+ request.setActiveProfiles( settings.getActiveProfiles() );
+
+ for ( org.apache.maven.settings.Profile rawProfile : settings.getProfiles() )
+ {
+ request.addProfile( SettingsUtils.convertFromSettingsProfile( rawProfile ) );
+
+ if ( settings.getActiveProfiles().contains( rawProfile.getId() ) )
+ {
+ List<Repository> remoteRepositories = rawProfile.getRepositories();
+ for ( Repository remoteRepository : remoteRepositories )
+ {
+ try
+ {
+ request.addRemoteRepository( repositorySystem.buildArtifactRepository( remoteRepository ) );
+ }
+ catch ( InvalidRepositoryException e )
+ {
+ // do nothing for now
+ }
+ }
+
+ List<Repository> pluginRepositories = rawProfile.getPluginRepositories();
+ for ( Repository pluginRepo : pluginRepositories )
+ {
+ try
+ {
+ request.addPluginArtifactRepository( repositorySystem.buildArtifactRepository( pluginRepo ) );
+ }
+ catch ( InvalidRepositoryException e )
+ {
+ // do nothing for now
+ }
+ }
+ }
+ }
+
+ return request;
+ }
+
+ /*end[MAVEN4]*/
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/DefaultMavenExecutionResult.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/DefaultMavenExecutionResult.java
new file mode 100644
index 00000000..a8967eda
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/DefaultMavenExecutionResult.java
@@ -0,0 +1,109 @@
+package org.apache.maven.execution;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Collections;
+import java.util.IdentityHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import org.apache.maven.project.DependencyResolutionResult;
+import org.apache.maven.project.MavenProject;
+
+/** @author Jason van Zyl */
+public class DefaultMavenExecutionResult
+ implements MavenExecutionResult
+{
+ private MavenProject project;
+
+ private List<MavenProject> topologicallySortedProjects = Collections.emptyList();
+
+ private DependencyResolutionResult dependencyResolutionResult;
+
+ private final List<Throwable> exceptions = new CopyOnWriteArrayList<Throwable>();
+
+ private final Map<MavenProject, BuildSummary> buildSummaries =
+ Collections.synchronizedMap( new IdentityHashMap<MavenProject, BuildSummary>() );
+
+ public MavenExecutionResult setProject( MavenProject project )
+ {
+ this.project = project;
+
+ return this;
+ }
+
+ public MavenProject getProject()
+ {
+ return project;
+ }
+
+ public MavenExecutionResult setTopologicallySortedProjects( List<MavenProject> topologicallySortedProjects )
+ {
+ this.topologicallySortedProjects = topologicallySortedProjects;
+
+ return this;
+ }
+
+ public List<MavenProject> getTopologicallySortedProjects()
+ {
+ return null == topologicallySortedProjects ? Collections.<MavenProject>emptyList()
+ : topologicallySortedProjects;
+ }
+
+ public DependencyResolutionResult getDependencyResolutionResult()
+ {
+ return dependencyResolutionResult;
+ }
+
+ public MavenExecutionResult setDependencyResolutionResult( DependencyResolutionResult dependencyResolutionResult )
+ {
+ this.dependencyResolutionResult = dependencyResolutionResult;
+
+ return this;
+ }
+
+ public List<Throwable> getExceptions()
+ {
+ return exceptions;
+ }
+
+ public MavenExecutionResult addException( Throwable t )
+ {
+ exceptions.add( t );
+
+ return this;
+ }
+
+ public boolean hasExceptions()
+ {
+ return !getExceptions().isEmpty();
+ }
+
+ public BuildSummary getBuildSummary( MavenProject project )
+ {
+ return buildSummaries.get( project );
+ }
+
+ public void addBuildSummary( BuildSummary summary )
+ {
+ buildSummaries.put( summary.getProject(), summary );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/ExecutionEvent.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/ExecutionEvent.java
new file mode 100644
index 00000000..0ee7f57a
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/ExecutionEvent.java
@@ -0,0 +1,92 @@
+package org.apache.maven.execution;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.plugin.MojoExecution;
+import org.apache.maven.project.MavenProject;
+
+/**
+ * Holds data relevant for an execution event.
+ *
+ * @author Benjamin Bentmann
+ */
+public interface ExecutionEvent
+{
+
+ /**
+ * The possible types of execution events.
+ */
+ enum Type
+ {
+ ProjectDiscoveryStarted,
+ SessionStarted,
+ SessionEnded,
+ ProjectSkipped,
+ ProjectStarted,
+ ProjectSucceeded,
+ ProjectFailed,
+ MojoSkipped,
+ MojoStarted,
+ MojoSucceeded,
+ MojoFailed,
+ ForkStarted,
+ ForkSucceeded,
+ ForkFailed,
+ ForkedProjectStarted,
+ ForkedProjectSucceeded,
+ ForkedProjectFailed,
+ }
+
+ /**
+ * Gets the type of the event.
+ *
+ * @return The type of the event, never {@code null}.
+ */
+ Type getType();
+
+ /**
+ * Gets the session from which this event originates.
+ *
+ * @return The current session, never {@code null}.
+ */
+ MavenSession getSession();
+
+ /**
+ * Gets the current project (if any).
+ *
+ * @return The current project or {@code null} if not applicable.
+ */
+ MavenProject getProject();
+
+ /**
+ * Gets the current mojo execution (if any).
+ *
+ * @return The current mojo execution or {@code null} if not applicable.
+ */
+ MojoExecution getMojoExecution();
+
+ /**
+ * Gets the exception that caused the event (if any).
+ *
+ * @return The exception or {@code null} if none.
+ */
+ Exception getException();
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/ExecutionListener.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/ExecutionListener.java
new file mode 100644
index 00000000..ad3f345a
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/ExecutionListener.java
@@ -0,0 +1,66 @@
+package org.apache.maven.execution;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Defines events that Maven fires during a build. <strong>Warning:</strong> This interface might be extended in future
+ * Maven versions to support further events. Hence it is strongly recommended to derive custom listeners from
+ * {@link AbstractExecutionListener} in order to avoid interoperability problems.
+ *
+ * @author Benjamin Bentmann
+ */
+public interface ExecutionListener
+{
+
+ void projectDiscoveryStarted( ExecutionEvent event );
+
+ void sessionStarted( ExecutionEvent event );
+
+ void sessionEnded( ExecutionEvent event );
+
+ void projectSkipped( ExecutionEvent event );
+
+ void projectStarted( ExecutionEvent event );
+
+ void projectSucceeded( ExecutionEvent event );
+
+ void projectFailed( ExecutionEvent event );
+
+ void mojoSkipped( ExecutionEvent event );
+
+ void mojoStarted( ExecutionEvent event );
+
+ void mojoSucceeded( ExecutionEvent event );
+
+ void mojoFailed( ExecutionEvent event );
+
+ void forkStarted( ExecutionEvent event );
+
+ void forkSucceeded( ExecutionEvent event );
+
+ void forkFailed( ExecutionEvent event );
+
+ void forkedProjectStarted( ExecutionEvent event );
+
+ void forkedProjectSucceeded( ExecutionEvent event );
+
+ void forkedProjectFailed( ExecutionEvent event );
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/MavenExecutionRequest.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/MavenExecutionRequest.java
new file mode 100644
index 00000000..53f84c50
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/MavenExecutionRequest.java
@@ -0,0 +1,443 @@
+package org.apache.maven.execution;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy;
+import org.apache.maven.eventspy.internal.EventSpyDispatcher;
+import org.apache.maven.model.Profile;
+import org.apache.maven.project.ProjectBuildingRequest;
+//
+// These settings values need to be removed and pushed down into a provider of configuration information
+//
+import org.apache.maven.settings.Mirror;
+import org.apache.maven.settings.Proxy;
+import org.apache.maven.settings.Server;
+//
+import org.apache.maven.toolchain.model.ToolchainModel;
+import org.codehaus.plexus.logging.Logger;
+import org.eclipse.aether.RepositoryCache;
+import org.eclipse.aether.repository.WorkspaceReader;
+import org.eclipse.aether.transfer.TransferListener;
+
+/**
+ * @author Jason van Zyl
+ */
+public interface MavenExecutionRequest
+{
+ // ----------------------------------------------------------------------
+ // Logging
+ // ----------------------------------------------------------------------
+
+ int LOGGING_LEVEL_DEBUG = Logger.LEVEL_DEBUG;
+
+ int LOGGING_LEVEL_INFO = Logger.LEVEL_INFO;
+
+ int LOGGING_LEVEL_WARN = Logger.LEVEL_WARN;
+
+ int LOGGING_LEVEL_ERROR = Logger.LEVEL_ERROR;
+
+ int LOGGING_LEVEL_FATAL = Logger.LEVEL_FATAL;
+
+ int LOGGING_LEVEL_DISABLED = Logger.LEVEL_DISABLED;
+
+ // ----------------------------------------------------------------------
+ // Reactor Failure Mode
+ // ----------------------------------------------------------------------
+
+ String REACTOR_FAIL_FAST = "FAIL_FAST";
+
+ String REACTOR_FAIL_AT_END = "FAIL_AT_END";
+
+ String REACTOR_FAIL_NEVER = "FAIL_NEVER";
+
+ // ----------------------------------------------------------------------
+ // Reactor Make Mode
+ // ----------------------------------------------------------------------
+
+ String REACTOR_MAKE_UPSTREAM = "make-upstream";
+
+ String REACTOR_MAKE_DOWNSTREAM = "make-downstream";
+
+ String REACTOR_MAKE_BOTH = "make-both";
+
+ // ----------------------------------------------------------------------
+ // Artifact repository policies
+ // ----------------------------------------------------------------------
+
+ String CHECKSUM_POLICY_FAIL = ArtifactRepositoryPolicy.CHECKSUM_POLICY_FAIL;
+
+ String CHECKSUM_POLICY_WARN = ArtifactRepositoryPolicy.CHECKSUM_POLICY_WARN;
+
+ // ----------------------------------------------------------------------
+ //
+ // ----------------------------------------------------------------------
+
+ // Base directory
+ MavenExecutionRequest setBaseDirectory( File basedir );
+
+ String getBaseDirectory();
+
+ // Timing (remove this)
+ MavenExecutionRequest setStartTime( Date start );
+
+ Date getStartTime();
+
+ // Goals
+ MavenExecutionRequest setGoals( List<String> goals );
+
+ List<String> getGoals();
+
+ // Properties
+
+ /**
+ * Sets the system properties to use for interpolation and profile activation. The system properties are collected
+ * from the runtime environment like {@link System#getProperties()} and environment variables.
+ *
+ * @param systemProperties The system properties, may be {@code null}.
+ * @return This request, never {@code null}.
+ */
+ MavenExecutionRequest setSystemProperties( Properties systemProperties );
+
+ /**
+ * Gets the system properties to use for interpolation and profile activation. The system properties are collected
+ * from the runtime environment like {@link System#getProperties()} and environment variables.
+ *
+ * @return The system properties, never {@code null}.
+ */
+ Properties getSystemProperties();
+
+ /**
+ * Sets the user properties to use for interpolation and profile activation. The user properties have been
+ * configured directly by the user on his discretion, e.g. via the {@code -Dkey=value} parameter on the command
+ * line.
+ *
+ * @param userProperties The user properties, may be {@code null}.
+ * @return This request, never {@code null}.
+ */
+ MavenExecutionRequest setUserProperties( Properties userProperties );
+
+ /**
+ * Gets the user properties to use for interpolation and profile activation. The user properties have been
+ * configured directly by the user on his discretion, e.g. via the {@code -Dkey=value} parameter on the command
+ * line.
+ *
+ * @return The user properties, never {@code null}.
+ */
+ Properties getUserProperties();
+
+ // Reactor
+ MavenExecutionRequest setReactorFailureBehavior( String failureBehavior );
+
+ String getReactorFailureBehavior();
+
+ MavenExecutionRequest setSelectedProjects( List<String> projects );
+
+ List<String> getSelectedProjects();
+
+ /**
+ * @param projects the projects to exclude
+ * @return this MavenExecutionRequest
+ * @since 3.2
+ */
+ MavenExecutionRequest setExcludedProjects( List<String> projects );
+
+ /**
+ * @return the excluded projects, never {@code null}
+ * @since 3.2
+ */
+ List<String> getExcludedProjects();
+
+ MavenExecutionRequest setResumeFrom( String project );
+
+ String getResumeFrom();
+
+ MavenExecutionRequest setMakeBehavior( String makeBehavior );
+
+ String getMakeBehavior();
+
+ /**
+ * Set's the parallel degree of concurrency used by the build.
+ *
+ * @param degreeOfConcurrency
+ */
+ void setDegreeOfConcurrency( int degreeOfConcurrency );
+
+ /**
+ * @return the degree of concurrency for the build.
+ */
+ int getDegreeOfConcurrency();
+
+ // Recursive (really to just process the top-level POM)
+ MavenExecutionRequest setRecursive( boolean recursive );
+
+ boolean isRecursive();
+
+ MavenExecutionRequest setPom( File pom );
+
+ File getPom();
+
+ // Errors
+ MavenExecutionRequest setShowErrors( boolean showErrors );
+
+ boolean isShowErrors();
+
+ // Transfer listeners
+ MavenExecutionRequest setTransferListener( TransferListener transferListener );
+
+ TransferListener getTransferListener();
+
+ // Logging
+ MavenExecutionRequest setLoggingLevel( int loggingLevel );
+
+ int getLoggingLevel();
+
+ // Update snapshots
+ MavenExecutionRequest setUpdateSnapshots( boolean updateSnapshots );
+
+ boolean isUpdateSnapshots();
+
+ MavenExecutionRequest setNoSnapshotUpdates( boolean noSnapshotUpdates );
+
+ boolean isNoSnapshotUpdates();
+
+ // Checksum policy
+ MavenExecutionRequest setGlobalChecksumPolicy( String globalChecksumPolicy );
+
+ String getGlobalChecksumPolicy();
+
+ // Local repository
+ MavenExecutionRequest setLocalRepositoryPath( String localRepository );
+
+ MavenExecutionRequest setLocalRepositoryPath( File localRepository );
+
+ File getLocalRepositoryPath();
+
+ MavenExecutionRequest setLocalRepository( ArtifactRepository repository );
+
+ ArtifactRepository getLocalRepository();
+
+ // Interactive
+ MavenExecutionRequest setInteractiveMode( boolean interactive );
+
+ boolean isInteractiveMode();
+
+ // Offline
+ MavenExecutionRequest setOffline( boolean offline );
+
+ boolean isOffline();
+
+ boolean isCacheTransferError();
+
+ MavenExecutionRequest setCacheTransferError( boolean cacheTransferError );
+
+ boolean isCacheNotFound();
+
+ MavenExecutionRequest setCacheNotFound( boolean cacheNotFound );
+
+ // Profiles
+ List<Profile> getProfiles();
+
+ MavenExecutionRequest addProfile( Profile profile );
+
+ MavenExecutionRequest setProfiles( List<Profile> profiles );
+
+ MavenExecutionRequest addActiveProfile( String profile );
+
+ MavenExecutionRequest addActiveProfiles( List<String> profiles );
+
+ MavenExecutionRequest setActiveProfiles( List<String> profiles );
+
+ List<String> getActiveProfiles();
+
+ MavenExecutionRequest addInactiveProfile( String profile );
+
+ MavenExecutionRequest addInactiveProfiles( List<String> profiles );
+
+ MavenExecutionRequest setInactiveProfiles( List<String> profiles );
+
+ List<String> getInactiveProfiles();
+
+ // Proxies
+ List<Proxy> getProxies();
+
+ MavenExecutionRequest setProxies( List<Proxy> proxies );
+
+ MavenExecutionRequest addProxy( Proxy proxy );
+
+ // Servers
+ List<Server> getServers();
+
+ MavenExecutionRequest setServers( List<Server> servers );
+
+ MavenExecutionRequest addServer( Server server );
+
+ // Mirrors
+ List<Mirror> getMirrors();
+
+ MavenExecutionRequest setMirrors( List<Mirror> mirrors );
+
+ MavenExecutionRequest addMirror( Mirror mirror );
+
+ // Plugin groups
+ List<String> getPluginGroups();
+
+ MavenExecutionRequest setPluginGroups( List<String> pluginGroups );
+
+ MavenExecutionRequest addPluginGroup( String pluginGroup );
+
+ MavenExecutionRequest addPluginGroups( List<String> pluginGroups );
+
+ boolean isProjectPresent();
+
+ MavenExecutionRequest setProjectPresent( boolean isProjectPresent );
+
+ File getUserSettingsFile();
+
+ MavenExecutionRequest setUserSettingsFile( File userSettingsFile );
+
+ File getGlobalSettingsFile();
+
+ MavenExecutionRequest setGlobalSettingsFile( File globalSettingsFile );
+
+ MavenExecutionRequest addRemoteRepository( ArtifactRepository repository );
+
+ MavenExecutionRequest addPluginArtifactRepository( ArtifactRepository repository );
+
+ /**
+ * Set a new list of remote repositories to use the execution request. This is necessary if you perform
+ * transformations on the remote repositories being used. For example if you replace existing repositories with
+ * mirrors then it's easier to just replace the whole list with a new list of transformed repositories.
+ *
+ * @param repositories
+ * @return This request, never {@code null}.
+ */
+ MavenExecutionRequest setRemoteRepositories( List<ArtifactRepository> repositories );
+
+ List<ArtifactRepository> getRemoteRepositories();
+
+ MavenExecutionRequest setPluginArtifactRepositories( List<ArtifactRepository> repositories );
+
+ List<ArtifactRepository> getPluginArtifactRepositories();
+
+ MavenExecutionRequest setRepositoryCache( RepositoryCache repositoryCache );
+
+ RepositoryCache getRepositoryCache();
+
+ WorkspaceReader getWorkspaceReader();
+
+ MavenExecutionRequest setWorkspaceReader( WorkspaceReader workspaceReader );
+
+ File getUserToolchainsFile();
+
+ MavenExecutionRequest setUserToolchainsFile( File userToolchainsFile );
+
+ /**
+ *
+ *
+ * @return the global toolchains file
+ * @since 3.3.0
+ */
+ File getGlobalToolchainsFile();
+
+ /**
+ *
+ * @param globalToolchainsFile the global toolchains file
+ * @return this request
+ * @since 3.3.0
+ */
+ MavenExecutionRequest setGlobalToolchainsFile( File globalToolchainsFile );
+
+ ExecutionListener getExecutionListener();
+
+ MavenExecutionRequest setExecutionListener( ExecutionListener executionListener );
+
+ ProjectBuildingRequest getProjectBuildingRequest();
+
+ /**
+ * @since 3.1
+ */
+ boolean isUseLegacyLocalRepository();
+
+ /**
+ * @since 3.1
+ */
+ MavenExecutionRequest setUseLegacyLocalRepository( boolean useLegacyLocalRepository );
+
+ /**
+ * Controls the {@link Builder} used by Maven by specification of the builder's id.
+ *
+ * @since 3.2.0
+ */
+ MavenExecutionRequest setBuilderId( String builderId );
+
+ /**
+ * Controls the {@link Builder} used by Maven by specification of the builders id.
+ *
+ * @since 3.2.0
+ */
+ String getBuilderId();
+
+ /**
+ *
+ * @param toolchains all toolchains grouped by type
+ * @return this request
+ * @since 3.3.0
+ */
+ MavenExecutionRequest setToolchains( Map<String, List<ToolchainModel>> toolchains );
+
+ /**
+ *
+ * @return all toolchains grouped by type, never {@code null}
+ * @since 3.3.0
+ */
+ Map<String, List<ToolchainModel>> getToolchains();
+
+ /**
+ * @since 3.3.0
+ */
+ void setMultiModuleProjectDirectory( File file );
+
+ /**
+ * @since 3.3.0
+ */
+ File getMultiModuleProjectDirectory();
+
+ /**
+ * @since 3.3.0
+ */
+ MavenExecutionRequest setEventSpyDispatcher( EventSpyDispatcher eventSpyDispatcher );
+
+ /**
+ * @since 3.3.0
+ */
+ EventSpyDispatcher getEventSpyDispatcher();
+
+ /**
+ * @since 3.3.0
+ */
+ Map<String, Object> getData();
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/MavenExecutionRequestPopulationException.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/MavenExecutionRequestPopulationException.java
new file mode 100644
index 00000000..ddd6ad22
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/MavenExecutionRequestPopulationException.java
@@ -0,0 +1,43 @@
+package org.apache.maven.execution;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * @author Jason van Zyl
+ */
+public class MavenExecutionRequestPopulationException
+ extends Exception
+{
+ public MavenExecutionRequestPopulationException( String message )
+ {
+ super( message );
+ }
+
+ public MavenExecutionRequestPopulationException( Throwable cause )
+ {
+ super( cause );
+ }
+
+ public MavenExecutionRequestPopulationException( String message,
+ Throwable cause )
+ {
+ super( message, cause );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/MavenExecutionRequestPopulator.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/MavenExecutionRequestPopulator.java
new file mode 100644
index 00000000..4f254f7a
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/MavenExecutionRequestPopulator.java
@@ -0,0 +1,74 @@
+package org.apache.maven.execution;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.settings.Settings;
+import org.apache.maven.toolchain.model.PersistedToolchains;
+
+/**
+ * Assists in populating an execution request for invocation of Maven.
+ *
+ * @author Benjamin Bentmann
+ */
+public interface MavenExecutionRequestPopulator
+{
+ /**
+ * Copies the values from the given toolchains into the specified execution request. This method will replace any
+ * existing values in the execution request that are controlled by the toolchains. Hence, it is expected that this
+ * method is called on a new/empty execution request before the caller mutates it to fit its needs.
+ *
+ * @param request The execution request to populate, must not be {@code null}.
+ * @param toolchains The toolchains to copy into the execution request, may be {@code null}.
+ * @return The populated execution request, never {@code null}.
+ * @throws MavenExecutionRequestPopulationException If the execution request could not be populated.
+ * @since 3.3.0
+ */
+ MavenExecutionRequest populateFromToolchains( MavenExecutionRequest request, PersistedToolchains toolchains )
+ throws MavenExecutionRequestPopulationException;
+
+ /**
+ * Injects default values like plugin groups or repositories into the specified execution request.
+ *
+ * @param request The execution request to populate, must not be {@code null}.
+ * @return The populated execution request, never {@code null}.
+ * @throws MavenExecutionRequestPopulationException If the execution request could not be populated.
+ */
+ MavenExecutionRequest populateDefaults( MavenExecutionRequest request )
+ throws MavenExecutionRequestPopulationException;
+
+ /*if_not[MAVEN4]*/
+
+ /**
+ * Copies the values from the given settings into the specified execution request. This method will replace any
+ * existing values in the execution request that are controlled by the settings. Hence, it is expected that this
+ * method is called on a new/empty execution request before the caller mutates it to fit its needs.
+ *
+ * @param request The execution request to populate, must not be {@code null}.
+ * @param settings The settings to copy into the execution request, may be {@code null}.
+ * @return The populated execution request, never {@code null}.
+ * @throws MavenExecutionRequestPopulationException If the execution request could not be populated.
+ */
+ @Deprecated
+ MavenExecutionRequest populateFromSettings( MavenExecutionRequest request, Settings settings )
+ throws MavenExecutionRequestPopulationException;
+
+ /*end[MAVEN4]*/
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/MavenExecutionResult.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/MavenExecutionResult.java
new file mode 100644
index 00000000..cb95fb1f
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/MavenExecutionResult.java
@@ -0,0 +1,70 @@
+package org.apache.maven.execution;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.List;
+
+import org.apache.maven.project.DependencyResolutionResult;
+import org.apache.maven.project.MavenProject;
+
+/**
+ * @author Jason van Zyl
+ */
+public interface MavenExecutionResult
+{
+ MavenExecutionResult setProject( MavenProject project );
+ MavenProject getProject();
+
+ MavenExecutionResult setTopologicallySortedProjects( List<MavenProject> projects );
+
+ /**
+ * @return the sorted list, or an empty list if there are no projects.
+ */
+ List<MavenProject> getTopologicallySortedProjects();
+
+ MavenExecutionResult setDependencyResolutionResult( DependencyResolutionResult result );
+ DependencyResolutionResult getDependencyResolutionResult();
+
+ // for each exception
+ // - knowing what artifacts are missing
+ // - project building exception
+ // - invalid project model exception: list of markers
+ // - xmlpull parser exception
+ List<Throwable> getExceptions();
+
+ MavenExecutionResult addException( Throwable e );
+
+ boolean hasExceptions();
+
+ /**
+ * Gets the build summary for the specified project.
+ *
+ * @param project The project to get the build summary for, must not be {@code null}.
+ * @return The build summary for the project or {@code null} if the project has not been built (yet).
+ */
+ BuildSummary getBuildSummary( MavenProject project );
+
+ /**
+ * Add the specified build summary.
+ *
+ * @param summary The build summary to add, must not be {@code null}.
+ */
+ void addBuildSummary( BuildSummary summary );
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/MavenSession.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/MavenSession.java
new file mode 100644
index 00000000..235691ac
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/MavenSession.java
@@ -0,0 +1,438 @@
+package org.apache.maven.execution;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.repository.RepositoryCache;
+import org.apache.maven.monitor.event.EventDispatcher;
+import org.apache.maven.plugin.descriptor.PluginDescriptor;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.project.ProjectBuildingRequest;
+import org.apache.maven.settings.Settings;
+import org.codehaus.plexus.PlexusContainer;
+import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
+import org.eclipse.aether.RepositorySystemSession;
+
+/**
+ * @author Jason van Zyl
+ */
+public class MavenSession
+ implements Cloneable
+{
+ private MavenExecutionRequest request;
+
+ private MavenExecutionResult result;
+
+ private RepositorySystemSession repositorySession;
+
+ private Properties executionProperties;
+
+ private MavenProject currentProject;
+
+ /**
+ * These projects have already been topologically sorted in the {@link org.apache.maven.Maven} component before
+ * being passed into the session. This is also the potentially constrained set of projects by using --projects
+ * on the command line.
+ */
+ private List<MavenProject> projects;
+
+ /**
+ * The full set of projects before any potential constraining by --projects. Useful in the case where you want to
+ * build a smaller set of projects but perform other operations in the context of your reactor.
+ */
+ private List<MavenProject> allProjects;
+
+ private MavenProject topLevelProject;
+
+ private ProjectDependencyGraph projectDependencyGraph;
+
+ private boolean parallel;
+
+ private final Map<String, Map<String, Map<String, Object>>> pluginContextsByProjectAndPluginKey =
+ new ConcurrentHashMap<String, Map<String, Map<String, Object>>>();
+
+
+ public void setProjects( List<MavenProject> projects )
+ {
+ if ( !projects.isEmpty() )
+ {
+ this.currentProject = projects.get( 0 );
+ this.topLevelProject = currentProject;
+ for ( MavenProject project : projects )
+ {
+ if ( project.isExecutionRoot() )
+ {
+ topLevelProject = project;
+ break;
+ }
+ }
+ }
+ else
+ {
+ this.currentProject = null;
+ this.topLevelProject = null;
+ }
+ this.projects = projects;
+ }
+
+ public ArtifactRepository getLocalRepository()
+ {
+ return request.getLocalRepository();
+ }
+
+ public List<String> getGoals()
+ {
+ return request.getGoals();
+ }
+
+ /**
+ * Gets the user properties to use for interpolation and profile activation. The user properties have been
+ * configured directly by the user on his discretion, e.g. via the {@code -Dkey=value} parameter on the command
+ * line.
+ *
+ * @return The user properties, never {@code null}.
+ */
+ public Properties getUserProperties()
+ {
+ return request.getUserProperties();
+ }
+
+ /**
+ * Gets the system properties to use for interpolation and profile activation. The system properties are collected
+ * from the runtime environment like {@link System#getProperties()} and environment variables.
+ *
+ * @return The system properties, never {@code null}.
+ */
+ public Properties getSystemProperties()
+ {
+ return request.getSystemProperties();
+ }
+
+ public Settings getSettings()
+ {
+ return settings;
+ }
+
+ public List<MavenProject> getProjects()
+ {
+ return projects;
+ }
+
+ public String getExecutionRootDirectory()
+ {
+ return request.getBaseDirectory();
+ }
+
+ public MavenExecutionRequest getRequest()
+ {
+ return request;
+ }
+
+ public void setCurrentProject( MavenProject currentProject )
+ {
+ this.currentProject = currentProject;
+ }
+
+ public MavenProject getCurrentProject()
+ {
+ return currentProject;
+ }
+
+ public ProjectBuildingRequest getProjectBuildingRequest()
+ {
+ return request.getProjectBuildingRequest().setRepositorySession( getRepositorySession() );
+ }
+
+ public List<String> getPluginGroups()
+ {
+ return request.getPluginGroups();
+ }
+
+ public boolean isOffline()
+ {
+ return request.isOffline();
+ }
+
+ public MavenProject getTopLevelProject()
+ {
+ return topLevelProject;
+ }
+
+ public MavenExecutionResult getResult()
+ {
+ return result;
+ }
+
+ // Backward compat
+
+ public Map<String, Object> getPluginContext( PluginDescriptor plugin, MavenProject project )
+ {
+ String projectKey = project.getId();
+
+ Map<String, Map<String, Object>> pluginContextsByKey = pluginContextsByProjectAndPluginKey.get( projectKey );
+
+ if ( pluginContextsByKey == null )
+ {
+ pluginContextsByKey = new ConcurrentHashMap<String, Map<String, Object>>();
+
+ pluginContextsByProjectAndPluginKey.put( projectKey, pluginContextsByKey );
+ }
+
+ String pluginKey = plugin.getPluginLookupKey();
+
+ Map<String, Object> pluginContext = pluginContextsByKey.get( pluginKey );
+
+ if ( pluginContext == null )
+ {
+ pluginContext = new ConcurrentHashMap<String, Object>();
+
+ pluginContextsByKey.put( pluginKey, pluginContext );
+ }
+
+ return pluginContext;
+ }
+
+ public ProjectDependencyGraph getProjectDependencyGraph()
+ {
+ return projectDependencyGraph;
+ }
+
+ public void setProjectDependencyGraph( ProjectDependencyGraph projectDependencyGraph )
+ {
+ this.projectDependencyGraph = projectDependencyGraph;
+ }
+
+ public String getReactorFailureBehavior()
+ {
+ return request.getReactorFailureBehavior();
+ }
+
+ @Override
+ public MavenSession clone()
+ {
+ try
+ {
+ return (MavenSession) super.clone();
+ }
+ catch ( CloneNotSupportedException e )
+ {
+ throw new RuntimeException( "Bug", e );
+ }
+ }
+
+ public Date getStartTime()
+ {
+ return request.getStartTime();
+ }
+
+ public boolean isParallel()
+ {
+ return parallel;
+ }
+
+ public void setParallel( boolean parallel )
+ {
+ this.parallel = parallel;
+ }
+
+ public RepositorySystemSession getRepositorySession()
+ {
+ return repositorySession;
+ }
+
+ private Map<String, MavenProject> projectMap;
+
+ public void setProjectMap( Map<String, MavenProject> projectMap )
+ {
+ this.projectMap = projectMap;
+ }
+
+ /** This is a provisional method and may be removed */
+ public List<MavenProject> getAllProjects()
+ {
+ return allProjects;
+ }
+
+ /** This is a provisional method and may be removed */
+ public void setAllProjects( List<MavenProject> allProjects )
+ {
+ this.allProjects = allProjects;
+ }
+
+ /*if_not[MAVEN4]*/
+
+ //
+ // Deprecated
+ //
+
+ private PlexusContainer container;
+
+ private final Settings settings;
+
+ @Deprecated
+ /** @deprecated This appears to only be used in the ReactorReader and we can do any processing required there */
+ public Map<String, MavenProject> getProjectMap()
+ {
+ return projectMap;
+ }
+
+ @Deprecated
+ public MavenSession( PlexusContainer container, RepositorySystemSession repositorySession,
+ MavenExecutionRequest request, MavenExecutionResult result )
+ {
+ this.container = container;
+ this.request = request;
+ this.result = result;
+ this.settings = new SettingsAdapter( request );
+ this.repositorySession = repositorySession;
+ }
+
+ @Deprecated
+ public MavenSession( PlexusContainer container, MavenExecutionRequest request, MavenExecutionResult result,
+ MavenProject project )
+ {
+ this( container, request, result, Arrays.asList( new MavenProject[]{project} ) );
+ }
+
+ @Deprecated
+ public MavenSession( PlexusContainer container, Settings settings, ArtifactRepository localRepository,
+ EventDispatcher eventDispatcher, ReactorManager unused, List<String> goals,
+ String executionRootDir, Properties executionProperties, Date startTime )
+ {
+ this( container, settings, localRepository, eventDispatcher, unused, goals, executionRootDir,
+ executionProperties, null, startTime );
+ }
+
+ @Deprecated
+ public MavenSession( PlexusContainer container, Settings settings, ArtifactRepository localRepository,
+ EventDispatcher eventDispatcher, ReactorManager unused, List<String> goals,
+ String executionRootDir, Properties executionProperties, Properties userProperties,
+ Date startTime )
+ {
+ this.container = container;
+ this.settings = settings;
+ this.executionProperties = executionProperties;
+ this.request = new DefaultMavenExecutionRequest();
+ this.request.setUserProperties( userProperties );
+ this.request.setLocalRepository( localRepository );
+ this.request.setGoals( goals );
+ this.request.setBaseDirectory( ( executionRootDir != null ) ? new File( executionRootDir ) : null );
+ this.request.setStartTime( startTime );
+ }
+
+ @Deprecated
+ public MavenSession( PlexusContainer container, MavenExecutionRequest request, MavenExecutionResult result,
+ List<MavenProject> projects )
+ {
+ this.container = container;
+ this.request = request;
+ this.result = result;
+ this.settings = new SettingsAdapter( request );
+ setProjects( projects );
+ }
+
+ @Deprecated
+ public List<MavenProject> getSortedProjects()
+ {
+ return getProjects();
+ }
+
+ @Deprecated
+ //
+ // Used by Tycho and will break users and force them to upgrade to Maven 3.1 so we should really leave
+ // this here, possibly indefinitely.
+ //
+ public RepositoryCache getRepositoryCache()
+ {
+ return null;
+ }
+
+ @Deprecated
+ public EventDispatcher getEventDispatcher()
+ {
+ return null;
+ }
+
+ @Deprecated
+ public boolean isUsingPOMsFromFilesystem()
+ {
+ return request.isProjectPresent();
+ }
+
+ /**
+ * @deprecated Use either {@link #getUserProperties()} or {@link #getSystemProperties()}.
+ */
+ @Deprecated
+ public Properties getExecutionProperties()
+ {
+ if ( executionProperties == null )
+ {
+ executionProperties = new Properties();
+ executionProperties.putAll( request.getSystemProperties() );
+ executionProperties.putAll( request.getUserProperties() );
+ }
+
+ return executionProperties;
+ }
+
+ @Deprecated
+ public PlexusContainer getContainer()
+ {
+ return container;
+ }
+
+ @Deprecated
+ public Object lookup( String role )
+ throws ComponentLookupException
+ {
+ return container.lookup( role );
+ }
+
+ @Deprecated
+ public Object lookup( String role, String roleHint )
+ throws ComponentLookupException
+ {
+ return container.lookup( role, roleHint );
+ }
+
+ @Deprecated
+ public List<Object> lookupList( String role )
+ throws ComponentLookupException
+ {
+ return container.lookupList( role );
+ }
+
+ @Deprecated
+ public Map<String, Object> lookupMap( String role )
+ throws ComponentLookupException
+ {
+ return container.lookupMap( role );
+ }
+
+ /*end[MAVEN4]*/
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/MojoExecutionEvent.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/MojoExecutionEvent.java
new file mode 100644
index 00000000..a8d293d1
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/MojoExecutionEvent.java
@@ -0,0 +1,86 @@
+package org.apache.maven.execution;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.plugin.Mojo;
+import org.apache.maven.plugin.MojoExecution;
+import org.apache.maven.project.MavenProject;
+
+/**
+ * Encapsulates parameters of MojoExecutionListener callback methods and is meant to provide API evolution path should
+ * it become necessary to introduce new parameters in the existing callbacks in the future.
+ *
+ * @see MojoExecutionListener
+ * @see org.apache.maven.execution.scope.WeakMojoExecutionListener
+ * @since 3.1.2
+ * @provisional This class is part of work in progress and can be changed or removed without notice.
+ */
+public class MojoExecutionEvent
+{
+ private final MavenSession session;
+
+ private final MavenProject project;
+
+ private final MojoExecution mojoExecution;
+
+ private final Mojo mojo;
+
+ private final Throwable cause;
+
+ public MojoExecutionEvent( MavenSession session, MavenProject project, MojoExecution mojoExecution, Mojo mojo )
+ {
+ this( session, project, mojoExecution, mojo, null );
+ }
+
+ public MojoExecutionEvent( MavenSession session, MavenProject project, MojoExecution mojoExecution, Mojo mojo,
+ Throwable cause )
+ {
+ this.session = session;
+ this.project = project;
+ this.mojoExecution = mojoExecution;
+ this.mojo = mojo;
+ this.cause = cause;
+ }
+
+ public MavenSession getSession()
+ {
+ return session;
+ }
+
+ public MavenProject getProject()
+ {
+ return project;
+ }
+
+ public MojoExecution getExecution()
+ {
+ return mojoExecution;
+ }
+
+ public Mojo getMojo()
+ {
+ return mojo;
+ }
+
+ public Throwable getCause()
+ {
+ return cause;
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/MojoExecutionListener.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/MojoExecutionListener.java
new file mode 100644
index 00000000..c2fb7a18
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/MojoExecutionListener.java
@@ -0,0 +1,40 @@
+package org.apache.maven.execution;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.plugin.MojoExecutionException;
+
+/**
+ * Extension point that allows build extensions observe and possibly veto mojo executions.
+ *
+ * @see org.apache.maven.execution.scope.WeakMojoExecutionListener
+ * @since 3.1.2
+ * @provisional This interface is part of work in progress and can be changed or removed without notice.
+ */
+public interface MojoExecutionListener
+{
+ void beforeMojoExecution( MojoExecutionEvent event )
+ throws MojoExecutionException;
+
+ void afterMojoExecutionSuccess( MojoExecutionEvent event )
+ throws MojoExecutionException;
+
+ void afterExecutionFailure( MojoExecutionEvent event );
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/ProjectDependencyGraph.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/ProjectDependencyGraph.java
new file mode 100644
index 00000000..1db277db
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/ProjectDependencyGraph.java
@@ -0,0 +1,64 @@
+package org.apache.maven.execution;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.List;
+
+import org.apache.maven.project.MavenProject;
+
+/**
+ * Describes the inter-dependencies between projects in the reactor.
+ *
+ * @author Benjamin Bentmann
+ */
+public interface ProjectDependencyGraph
+{
+
+ /**
+ * Gets all projects in their intended build order, i.e. after topologically sorting the projects according to their
+ * inter-dependencies.
+ *
+ * @return The projects in the build order, never {@code null}.
+ */
+ List<MavenProject> getSortedProjects();
+
+ /**
+ * Gets the downstream projects of the specified project. A downstream project is a project that directly or
+ * indirectly depends on the given project.
+ *
+ * @param project The project whose downstream projects should be retrieved, must not be {@code null}.
+ * @param transitive A flag whether to retrieve all direct and indirect downstream projects or just the immediate
+ * downstream projects.
+ * @return The downstream projects in the build order, never {@code null}.
+ */
+ List<MavenProject> getDownstreamProjects( MavenProject project, boolean transitive );
+
+ /**
+ * Gets the upstream projects of the specified project. An upstream project is a project that directly or indirectly
+ * is a prerequisite of the given project.
+ *
+ * @param project The project whose upstream projects should be retrieved, must not be {@code null}.
+ * @param transitive A flag whether to retrieve all direct and indirect upstream projects or just the immediate
+ * upstream projects.
+ * @return The upstream projects in the build order, never {@code null}.
+ */
+ List<MavenProject> getUpstreamProjects( MavenProject project, boolean transitive );
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/ProjectExecutionEvent.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/ProjectExecutionEvent.java
new file mode 100644
index 00000000..fb71078f
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/ProjectExecutionEvent.java
@@ -0,0 +1,90 @@
+package org.apache.maven.execution;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.List;
+
+import org.apache.maven.plugin.MojoExecution;
+import org.apache.maven.project.MavenProject;
+
+/**
+ * Encapsulates parameters of ProjectExecutionListener callback methods and is meant to provide API evolution path
+ * should it become necessary to introduce new parameters in the existing callbacks in the future.
+ *
+ * @see ProjectExecutionListener
+ * @since 3.1.2
+ * @provisional This class is part of work in progress and can be changed or removed without notice.
+ */
+public class ProjectExecutionEvent
+{
+
+ private final MavenSession session;
+
+ private final MavenProject project;
+
+ private final List<MojoExecution> executionPlan;
+
+ private final Throwable cause;
+
+ public ProjectExecutionEvent( MavenSession session, MavenProject project )
+ {
+ this( session, project, null, null );
+ }
+
+ public ProjectExecutionEvent( MavenSession session, MavenProject project, List<MojoExecution> executionPlan )
+ {
+ this( session, project, executionPlan, null );
+ }
+
+ public ProjectExecutionEvent( MavenSession session, MavenProject project, Throwable cause )
+ {
+ this( session, project, null, cause );
+ }
+
+ public ProjectExecutionEvent( MavenSession session, MavenProject project, List<MojoExecution> executionPlan,
+ Throwable cause )
+ {
+ this.session = session;
+ this.project = project;
+ this.executionPlan = executionPlan;
+ this.cause = cause;
+ }
+
+ public MavenSession getSession()
+ {
+ return session;
+ }
+
+ public MavenProject getProject()
+ {
+ return project;
+ }
+
+ public List<MojoExecution> getExecutionPlan()
+ {
+ return executionPlan;
+ }
+
+ public Throwable getCause()
+ {
+ return cause;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/ProjectExecutionListener.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/ProjectExecutionListener.java
new file mode 100644
index 00000000..d7e89183
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/ProjectExecutionListener.java
@@ -0,0 +1,44 @@
+package org.apache.maven.execution;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.lifecycle.LifecycleExecutionException;
+
+/**
+ * Extension point that allows build extensions observe and possibly veto project build execution.
+ *
+ * @see ExecutionListener
+ * @see MojoExecutionListener
+ * @since 3.1.2
+ * @provisional This interface is part of work in progress and can be changed or removed without notice.
+ */
+public interface ProjectExecutionListener
+{
+ void beforeProjectExecution( ProjectExecutionEvent event )
+ throws LifecycleExecutionException;
+
+ void beforeProjectLifecycleExecution( ProjectExecutionEvent event )
+ throws LifecycleExecutionException;
+
+ void afterProjectExecutionSuccess( ProjectExecutionEvent event )
+ throws LifecycleExecutionException;
+
+ void afterProjectExecutionFailure( ProjectExecutionEvent event );
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/ReactorManager.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/ReactorManager.java
new file mode 100644
index 00000000..1b99a3be
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/ReactorManager.java
@@ -0,0 +1,199 @@
+package org.apache.maven.execution;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.artifact.ArtifactUtils;
+import org.apache.maven.plugin.descriptor.PluginDescriptor;
+import org.apache.maven.project.DuplicateProjectException;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.project.ProjectSorter;
+import org.codehaus.plexus.util.dag.CycleDetectedException;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@Deprecated
+public class ReactorManager
+{
+ public static final String FAIL_FAST = "fail-fast";
+
+ public static final String FAIL_AT_END = "fail-at-end";
+
+ public static final String FAIL_NEVER = "fail-never";
+
+ public static final String MAKE_MODE = "make";
+
+ public static final String MAKE_DEPENDENTS_MODE = "make-dependents";
+
+ // make projects that depend on me, and projects that I depend on
+ public static final String MAKE_BOTH_MODE = "make-both";
+
+ private List<String> blackList = new ArrayList<String>();
+
+ private Map<String, BuildFailure> buildFailuresByProject = new HashMap<String, BuildFailure>();
+
+ private Map pluginContextsByProjectAndPluginKey = new HashMap();
+
+ private String failureBehavior = FAIL_FAST;
+
+ private final ProjectSorter sorter;
+
+ private Map<String, BuildSuccess> buildSuccessesByProject = new HashMap<String, BuildSuccess>();
+
+ public ReactorManager( List<MavenProject> projects )
+ throws CycleDetectedException, DuplicateProjectException
+ {
+ this.sorter = new ProjectSorter( projects );
+ }
+
+ public Map getPluginContext( PluginDescriptor plugin, MavenProject project )
+ {
+ Map pluginContextsByKey = (Map) pluginContextsByProjectAndPluginKey.get( project.getId() );
+
+ if ( pluginContextsByKey == null )
+ {
+ pluginContextsByKey = new HashMap();
+ pluginContextsByProjectAndPluginKey.put( project.getId(), pluginContextsByKey );
+ }
+
+ Map pluginContext = (Map) pluginContextsByKey.get( plugin.getPluginLookupKey() );
+
+ if ( pluginContext == null )
+ {
+ pluginContext = new HashMap();
+ pluginContextsByKey.put( plugin.getPluginLookupKey(), pluginContext );
+ }
+
+ return pluginContext;
+ }
+
+ public void setFailureBehavior( String failureBehavior )
+ {
+ if ( failureBehavior == null )
+ {
+ this.failureBehavior = FAIL_FAST; // default
+ return;
+ }
+ if ( FAIL_FAST.equals( failureBehavior ) || FAIL_AT_END.equals( failureBehavior )
+ || FAIL_NEVER.equals( failureBehavior ) )
+ {
+ this.failureBehavior = failureBehavior;
+ }
+ else
+ {
+ throw new IllegalArgumentException( "Invalid failure behavior (must be one of: \'" + FAIL_FAST + "\', \'"
+ + FAIL_AT_END + "\', \'" + FAIL_NEVER + "\')." );
+ }
+ }
+
+ public String getFailureBehavior()
+ {
+ return failureBehavior;
+ }
+
+ public void blackList( MavenProject project )
+ {
+ blackList( getProjectKey( project ) );
+ }
+
+ private void blackList( String id )
+ {
+ if ( !blackList.contains( id ) )
+ {
+ blackList.add( id );
+
+ List<String> dependents = sorter.getDependents( id );
+
+ if ( dependents != null && !dependents.isEmpty() )
+ {
+ for ( String dependentId : dependents )
+ {
+ if ( !buildSuccessesByProject.containsKey( dependentId )
+ && !buildFailuresByProject.containsKey( dependentId ) )
+ {
+ blackList( dependentId );
+ }
+ }
+ }
+ }
+ }
+
+ public boolean isBlackListed( MavenProject project )
+ {
+ return blackList.contains( getProjectKey( project ) );
+ }
+
+ private static String getProjectKey( MavenProject project )
+ {
+ return ArtifactUtils.versionlessKey( project.getGroupId(), project.getArtifactId() );
+ }
+
+ public void registerBuildFailure( MavenProject project, Exception error, String task, long time )
+ {
+ buildFailuresByProject.put( getProjectKey( project ), new BuildFailure( project, time, error ) );
+ }
+
+ public boolean hasBuildFailures()
+ {
+ return !buildFailuresByProject.isEmpty();
+ }
+
+ public boolean hasBuildFailure( MavenProject project )
+ {
+ return buildFailuresByProject.containsKey( getProjectKey( project ) );
+ }
+
+ public boolean hasMultipleProjects()
+ {
+ return sorter.hasMultipleProjects();
+ }
+
+ public List<MavenProject> getSortedProjects()
+ {
+ return sorter.getSortedProjects();
+ }
+
+ public boolean hasBuildSuccess( MavenProject project )
+ {
+ return buildSuccessesByProject.containsKey( getProjectKey( project ) );
+ }
+
+ public void registerBuildSuccess( MavenProject project, long time )
+ {
+ buildSuccessesByProject.put( getProjectKey( project ), new BuildSuccess( project, time ) );
+ }
+
+ public BuildFailure getBuildFailure( MavenProject project )
+ {
+ return (BuildFailure) buildFailuresByProject.get( getProjectKey( project ) );
+ }
+
+ public BuildSuccess getBuildSuccess( MavenProject project )
+ {
+ return (BuildSuccess) buildSuccessesByProject.get( getProjectKey( project ) );
+ }
+
+ public boolean executedMultipleProjects()
+ {
+ return buildFailuresByProject.size() + buildSuccessesByProject.size() > 1;
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/SettingsAdapter.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/SettingsAdapter.java
new file mode 100644
index 00000000..000607ff
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/SettingsAdapter.java
@@ -0,0 +1,126 @@
+package org.apache.maven.execution;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.maven.settings.Mirror;
+import org.apache.maven.settings.Profile;
+import org.apache.maven.settings.Proxy;
+import org.apache.maven.settings.RuntimeInfo;
+import org.apache.maven.settings.Server;
+import org.apache.maven.settings.Settings;
+import org.apache.maven.settings.SettingsUtils;
+
+/**
+ * Adapt a {@link MavenExecutionRequest} to a {@link Settings} object for use in the Maven core.
+ * We want to make sure that what is ask for in the execution request overrides what is in the settings.
+ * The CLI feeds into an execution request so if a particular value is present in the execution request
+ * then we will take that over the value coming from the user settings.
+ *
+ * @author Jason van Zyl
+ */
+class SettingsAdapter
+ extends Settings
+{
+
+ private MavenExecutionRequest request;
+
+ private RuntimeInfo runtimeInfo;
+
+ public SettingsAdapter( MavenExecutionRequest request )
+ {
+ this.request = request;
+
+ /*
+ * NOTE: Plugins like maven-release-plugin query the path to the settings.xml to pass it into a forked Maven and
+ * the CLI will fail when called with a non-existing settings, so be sure to only point at actual files. Having
+ * a null file should be harmless as this case matches general Maven 2.x behavior...
+ */
+ File userSettings = request.getUserSettingsFile();
+ this.runtimeInfo = new RuntimeInfo( ( userSettings != null && userSettings.isFile() ) ? userSettings : null );
+ }
+
+ @Override
+ public String getLocalRepository()
+ {
+ if ( request.getLocalRepositoryPath() != null )
+ {
+ return request.getLocalRepositoryPath().getAbsolutePath();
+ }
+
+ return null;
+ }
+
+ @Override
+ public boolean isInteractiveMode()
+ {
+ return request.isInteractiveMode();
+ }
+
+ @Override
+ public boolean isOffline()
+ {
+ return request.isOffline();
+ }
+
+ @Override
+ public List<Proxy> getProxies()
+ {
+ return request.getProxies();
+ }
+
+ @Override
+ public List<Server> getServers()
+ {
+ return request.getServers();
+ }
+
+ @Override
+ public List<Mirror> getMirrors()
+ {
+ return request.getMirrors();
+ }
+
+ @Override
+ public List<Profile> getProfiles()
+ {
+ List<Profile> result = new ArrayList<Profile>();
+ for ( org.apache.maven.model.Profile profile : request.getProfiles() )
+ {
+ result.add( SettingsUtils.convertToSettingsProfile( profile ) );
+ }
+ return result;
+ }
+
+ @Override
+ public List<String> getActiveProfiles()
+ {
+ return request.getActiveProfiles();
+ }
+
+ @Override
+ public List<String> getPluginGroups()
+ {
+ return request.getPluginGroups();
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/scope/MojoExecutionScoped.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/scope/MojoExecutionScoped.java
new file mode 100644
index 00000000..0dcbd16f
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/scope/MojoExecutionScoped.java
@@ -0,0 +1,42 @@
+package org.apache.maven.execution.scope;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import com.google.inject.ScopeAnnotation;
+
+/**
+ * Indicates that annotated component should be instantiated before mojo execution starts and discarded after mojo
+ * execution completes.
+ *
+ * @author igor
+ * @since 3.1.2
+ */
+@Target( { TYPE } )
+@Retention( RUNTIME )
+@ScopeAnnotation
+public @interface MojoExecutionScoped
+{
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/scope/WeakMojoExecutionListener.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/scope/WeakMojoExecutionListener.java
new file mode 100644
index 00000000..94e7c104
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/scope/WeakMojoExecutionListener.java
@@ -0,0 +1,44 @@
+package org.apache.maven.execution.scope;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.execution.MojoExecutionEvent;
+import org.apache.maven.plugin.MojoExecutionException;
+
+/**
+ * Extension point that allows build extensions observe and possibly veto mojo executions.
+ * <p>
+ * Unlike {@link MojoExecutionListener}, this extension point does not trigger instantiation of the component, hence
+ * "weak" class name prefix. Only applies to mojo execution scoped components.
+ *
+ * @see org.apache.maven.execution.MojoExecutionListener
+ * @since 3.1.2
+ * @provisional This interface is part of work in progress and can be changed or removed without notice.
+ */
+public interface WeakMojoExecutionListener
+{
+ void beforeMojoExecution( MojoExecutionEvent event )
+ throws MojoExecutionException;
+
+ void afterMojoExecutionSuccess( MojoExecutionEvent event )
+ throws MojoExecutionException;
+
+ void afterExecutionFailure( MojoExecutionEvent event );
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/scope/internal/MojoExecutionScope.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/scope/internal/MojoExecutionScope.java
new file mode 100644
index 00000000..8a98daf0
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/scope/internal/MojoExecutionScope.java
@@ -0,0 +1,190 @@
+package org.apache.maven.execution.scope.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Collection;
+import java.util.IdentityHashMap;
+import java.util.LinkedList;
+import java.util.Map;
+
+import org.apache.maven.execution.MojoExecutionEvent;
+import org.apache.maven.execution.MojoExecutionListener;
+import org.apache.maven.execution.scope.WeakMojoExecutionListener;
+import org.apache.maven.plugin.MojoExecutionException;
+
+import com.google.common.collect.Maps;
+import com.google.inject.Key;
+import com.google.inject.OutOfScopeException;
+import com.google.inject.Provider;
+import com.google.inject.Scope;
+import com.google.inject.util.Providers;
+
+public class MojoExecutionScope
+ implements Scope, MojoExecutionListener
+{
+ private static final Provider<Object> SEEDED_KEY_PROVIDER = new Provider<Object>()
+ {
+ public Object get()
+ {
+ throw new IllegalStateException();
+ }
+ };
+
+ private static final class ScopeState
+ {
+ public final Map<Key<?>, Provider<?>> seeded = Maps.newHashMap();
+
+ public final Map<Key<?>, Object> provided = Maps.newHashMap();
+ }
+
+ private final ThreadLocal<LinkedList<ScopeState>> values = new ThreadLocal<LinkedList<ScopeState>>();
+
+ public MojoExecutionScope()
+ {
+ }
+
+ public void enter()
+ {
+ LinkedList<ScopeState> stack = values.get();
+ if ( stack == null )
+ {
+ stack = new LinkedList<ScopeState>();
+ values.set( stack );
+ }
+ stack.addFirst( new ScopeState() );
+ }
+
+ private ScopeState getScopeState()
+ {
+ LinkedList<ScopeState> stack = values.get();
+ if ( stack == null || stack.isEmpty() )
+ {
+ throw new IllegalStateException();
+ }
+ return stack.getFirst();
+ }
+
+ public void exit()
+ throws MojoExecutionException
+ {
+ final LinkedList<ScopeState> stack = values.get();
+ if ( stack == null || stack.isEmpty() )
+ {
+ throw new IllegalStateException();
+ }
+ stack.removeFirst();
+ if ( stack.isEmpty() )
+ {
+ values.remove();
+ }
+ }
+
+ public <T> void seed( Class<T> clazz, Provider<T> value )
+ {
+ getScopeState().seeded.put( Key.get( clazz ), value );
+ }
+
+ public <T> void seed( Class<T> clazz, final T value )
+ {
+ getScopeState().seeded.put( Key.get( clazz ), Providers.of( value ) );
+ }
+
+ public <T> Provider<T> scope( final Key<T> key, final Provider<T> unscoped )
+ {
+ return new Provider<T>()
+ {
+ @SuppressWarnings( "unchecked" )
+ public T get()
+ {
+ LinkedList<ScopeState> stack = values.get();
+ if ( stack == null || stack.isEmpty() )
+ {
+ throw new OutOfScopeException( "Cannot access " + key + " outside of a scoping block" );
+ }
+
+ ScopeState state = stack.getFirst();
+
+ Provider<?> seeded = state.seeded.get( key );
+
+ if ( seeded != null )
+ {
+ return (T) seeded.get();
+ }
+
+ T provided = (T) state.provided.get( key );
+ if ( provided == null && unscoped != null )
+ {
+ provided = unscoped.get();
+ state.provided.put( key, provided );
+ }
+
+ return provided;
+ }
+ };
+ }
+
+ @SuppressWarnings( { "unchecked" } )
+ public static <T> Provider<T> seededKeyProvider()
+ {
+ return (Provider<T>) SEEDED_KEY_PROVIDER;
+ }
+
+ public void beforeMojoExecution( MojoExecutionEvent event )
+ throws MojoExecutionException
+ {
+ for ( WeakMojoExecutionListener provided : getProvidedListeners() )
+ {
+ provided.beforeMojoExecution( event );
+ }
+ }
+
+ public void afterMojoExecutionSuccess( MojoExecutionEvent event )
+ throws MojoExecutionException
+ {
+ for ( WeakMojoExecutionListener provided : getProvidedListeners() )
+ {
+ provided.afterMojoExecutionSuccess( event );
+ }
+ }
+
+ public void afterExecutionFailure( MojoExecutionEvent event )
+ {
+ for ( WeakMojoExecutionListener provided : getProvidedListeners() )
+ {
+ provided.afterExecutionFailure( event );
+ }
+ }
+
+ private Collection<WeakMojoExecutionListener> getProvidedListeners()
+ {
+ // the same instance can be provided multiple times under different Key's
+ // deduplicate instances to avoid redundant beforeXXX/afterXXX callbacks
+ IdentityHashMap<WeakMojoExecutionListener, Object> listeners =
+ new IdentityHashMap<WeakMojoExecutionListener, Object>();
+ for ( Object provided : getScopeState().provided.values() )
+ {
+ if ( provided instanceof WeakMojoExecutionListener )
+ {
+ listeners.put( (WeakMojoExecutionListener) provided, null );
+ }
+ }
+ return listeners.keySet();
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/scope/internal/MojoExecutionScopeCoreModule.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/scope/internal/MojoExecutionScopeCoreModule.java
new file mode 100644
index 00000000..8208c3c3
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/scope/internal/MojoExecutionScopeCoreModule.java
@@ -0,0 +1,45 @@
+package org.apache.maven.execution.scope.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import org.apache.maven.execution.MojoExecutionListener;
+
+@Named
+public class MojoExecutionScopeCoreModule
+ extends MojoExecutionScopeModule
+{
+
+ @Inject
+ public MojoExecutionScopeCoreModule()
+ {
+ super( new MojoExecutionScope() );
+ }
+
+ @Override
+ protected void configure()
+ {
+ super.configure();
+ bind( MojoExecutionListener.class ).toInstance( scope );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/scope/internal/MojoExecutionScopeModule.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/scope/internal/MojoExecutionScopeModule.java
new file mode 100644
index 00000000..229a3c56
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/execution/scope/internal/MojoExecutionScopeModule.java
@@ -0,0 +1,56 @@
+package org.apache.maven.execution.scope.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.execution.scope.MojoExecutionScoped;
+import org.apache.maven.plugin.MojoExecution;
+import org.apache.maven.project.MavenProject;
+import org.codehaus.plexus.PlexusContainer;
+import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
+
+import com.google.inject.AbstractModule;
+
+public class MojoExecutionScopeModule
+ extends AbstractModule
+{
+ protected final MojoExecutionScope scope;
+
+ public MojoExecutionScopeModule( PlexusContainer container )
+ throws ComponentLookupException
+ {
+ this( container.lookup( MojoExecutionScope.class ) );
+ }
+
+ protected MojoExecutionScopeModule( MojoExecutionScope scope )
+ {
+ this.scope = scope;
+ }
+
+ @Override
+ protected void configure()
+ {
+ bindScope( MojoExecutionScoped.class, scope );
+ bind( MojoExecutionScope.class ).toInstance( scope );
+
+ bind( MavenProject.class ).toProvider( MojoExecutionScope.<MavenProject>seededKeyProvider() ).in( scope );
+ bind( MojoExecution.class ).toProvider( MojoExecutionScope.<MojoExecution>seededKeyProvider() ).in( scope );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/extension/internal/CoreExports.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/extension/internal/CoreExports.java
new file mode 100644
index 00000000..c4265b31
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/extension/internal/CoreExports.java
@@ -0,0 +1,75 @@
+package org.apache.maven.extension.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Set;
+
+import org.codehaus.plexus.classworlds.realm.ClassRealm;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+
+/**
+ * Provides information about artifacts (identified by groupId:artifactId string key) and classpath elements exported by
+ * Maven core itself and loaded Maven core extensions.
+ *
+ * @since 3.3.0
+ */
+public class CoreExports
+{
+ private final Set<String> artifacts;
+
+ private final Map<String, ClassLoader> packages;
+
+ public CoreExports( CoreExtensionEntry entry )
+ {
+ this( entry.getClassRealm(), entry.getExportedArtifacts(), entry.getExportedPackages() );
+ }
+
+ public CoreExports( ClassRealm realm, Set<String> exportedArtifacts, Set<String> exportedPackages )
+ {
+ Map<String, ClassLoader> packages = new LinkedHashMap<String, ClassLoader>();
+ for ( String pkg : exportedPackages )
+ {
+ packages.put( pkg, realm );
+ }
+ this.artifacts = ImmutableSet.copyOf( exportedArtifacts );
+ this.packages = ImmutableMap.copyOf( packages );
+ }
+
+ /**
+ * Returns artifacts exported by Maven core and core extensions. Artifacts are identified by their
+ * groupId:artifactId string key.
+ */
+ public Set<String> getExportedArtifacts()
+ {
+ return artifacts;
+ }
+
+ /**
+ * Returns packages exported by Maven core and core extensions.
+ */
+ public Map<String, ClassLoader> getExportedPackages()
+ {
+ return packages;
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/extension/internal/CoreExportsProvider.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/extension/internal/CoreExportsProvider.java
new file mode 100644
index 00000000..e7e4534c
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/extension/internal/CoreExportsProvider.java
@@ -0,0 +1,53 @@
+package org.apache.maven.extension.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import org.codehaus.plexus.PlexusContainer;
+import org.eclipse.sisu.Nullable;
+
+@Named
+@Singleton
+public class CoreExportsProvider
+{
+
+ private final CoreExports exports;
+
+ @Inject
+ public CoreExportsProvider( PlexusContainer container, @Nullable CoreExports exports )
+ {
+ if ( exports == null )
+ {
+ this.exports = new CoreExports( CoreExtensionEntry.discoverFrom( container.getContainerRealm() ) );
+ }
+ else
+ {
+ this.exports = exports;
+ }
+ }
+
+ public CoreExports get()
+ {
+ return exports;
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/extension/internal/CoreExtensionEntry.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/extension/internal/CoreExtensionEntry.java
new file mode 100644
index 00000000..edadeb2d
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/extension/internal/CoreExtensionEntry.java
@@ -0,0 +1,141 @@
+package org.apache.maven.extension.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+import org.apache.maven.project.ExtensionDescriptor;
+import org.apache.maven.project.ExtensionDescriptorBuilder;
+import org.codehaus.plexus.classworlds.realm.ClassRealm;
+import org.codehaus.plexus.util.IOUtil;
+
+import com.google.common.collect.ImmutableSet;
+
+/**
+ * Provides information about artifacts (identified by groupId:artifactId string key) and classpath elements exported by
+ * Maven core itself or a Maven core extension.
+ *
+ * @since 3.3.0
+ */
+public class CoreExtensionEntry
+{
+ private final ClassRealm realm;
+
+ private final Set<String> artifacts;
+
+ private final Set<String> packages;
+
+ public CoreExtensionEntry( ClassRealm realm, Collection<String> artifacts, Collection<String> packages )
+ {
+ this.realm = realm;
+ this.artifacts = ImmutableSet.copyOf( artifacts );
+ this.packages = ImmutableSet.copyOf( packages );
+ }
+
+ /**
+ * Returns ClassLoader used to load extension classes.
+ */
+ public ClassRealm getClassRealm()
+ {
+ return realm;
+ }
+
+ /**
+ * Returns artifacts exported by the extension, identified by groupId:artifactId string key.
+ */
+ public Set<String> getExportedArtifacts()
+ {
+ return artifacts;
+ }
+
+ /**
+ * Returns classpath elements exported by the extension.
+ */
+ public Set<String> getExportedPackages()
+ {
+ return packages;
+ }
+
+ private static final ExtensionDescriptorBuilder builder = new ExtensionDescriptorBuilder();
+
+ public static CoreExtensionEntry discoverFrom( ClassRealm loader )
+ {
+ Set<String> artifacts = new LinkedHashSet<String>();
+ Set<String> packages = new LinkedHashSet<String>();
+
+ try
+ {
+ Enumeration<URL> urls = loader.getResources( builder.getExtensionDescriptorLocation() );
+ while ( urls.hasMoreElements() )
+ {
+ InputStream is = urls.nextElement().openStream();
+ try
+ {
+ ExtensionDescriptor descriptor = builder.build( is );
+ artifacts.addAll( descriptor.getExportedArtifacts() );
+ packages.addAll( descriptor.getExportedPackages() );
+ }
+ finally
+ {
+ IOUtil.close( is );
+ }
+ }
+ }
+ catch ( IOException ignored )
+ {
+ // exports descriptors are entirely optional
+ }
+
+ return new CoreExtensionEntry( loader, artifacts, packages );
+ }
+
+ public static CoreExtensionEntry discoverFrom( ClassRealm loader, Collection<File> classpath )
+ {
+ Set<String> artifacts = new LinkedHashSet<String>();
+ Set<String> packages = new LinkedHashSet<String>();
+
+ try
+ {
+ for ( File entry : classpath )
+ {
+ ExtensionDescriptor descriptor = builder.build( entry );
+ if ( descriptor != null )
+ {
+ artifacts.addAll( descriptor.getExportedArtifacts() );
+ packages.addAll( descriptor.getExportedPackages() );
+ }
+ }
+ }
+ catch ( IOException ignored )
+ {
+ // exports descriptors are entirely optional
+ }
+
+ return new CoreExtensionEntry( loader, artifacts, packages );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/graph/DefaultGraphBuilder.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/graph/DefaultGraphBuilder.java
new file mode 100644
index 00000000..c8367463
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/graph/DefaultGraphBuilder.java
@@ -0,0 +1,488 @@
+package org.apache.maven.graph;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.maven.DefaultMaven;
+import org.apache.maven.MavenExecutionException;
+import org.apache.maven.ProjectCycleException;
+import org.apache.maven.artifact.ArtifactUtils;
+import org.apache.maven.execution.MavenExecutionRequest;
+import org.apache.maven.execution.MavenExecutionResult;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.execution.ProjectDependencyGraph;
+import org.apache.maven.model.Plugin;
+import org.apache.maven.model.building.DefaultModelProblem;
+import org.apache.maven.model.building.ModelProblem;
+import org.apache.maven.model.building.ModelProblemUtils;
+import org.apache.maven.model.building.ModelSource;
+import org.apache.maven.model.building.Result;
+import org.apache.maven.model.building.UrlModelSource;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.project.ProjectBuilder;
+import org.apache.maven.project.ProjectBuildingException;
+import org.apache.maven.project.ProjectBuildingRequest;
+import org.apache.maven.project.ProjectBuildingResult;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+import org.codehaus.plexus.logging.Logger;
+import org.codehaus.plexus.util.StringUtils;
+import org.codehaus.plexus.util.dag.CycleDetectedException;
+
+import com.google.common.collect.Lists;
+
+@Component( role = GraphBuilder.class, hint = GraphBuilder.HINT )
+public class DefaultGraphBuilder
+ implements GraphBuilder
+{
+ @Requirement
+ private Logger logger;
+
+ @Requirement
+ protected ProjectBuilder projectBuilder;
+
+ @Override
+ public Result<ProjectDependencyGraph> build( MavenSession session )
+ {
+ if ( session.getProjectDependencyGraph() != null )
+ {
+ return dependencyGraph( session, session.getProjects(), false );
+ }
+
+ List<MavenProject> projects = session.getProjects();
+
+ if ( projects == null )
+ {
+ try
+ {
+ projects = getProjectsForMavenReactor( session );
+ }
+ catch ( ProjectBuildingException e )
+ {
+ return Result.error( Lists.newArrayList( new DefaultModelProblem( null, null, null, null, 0, 0, e ) ) );
+ }
+
+ validateProjects( projects );
+
+ return dependencyGraph( session, projects, true );
+ }
+ else
+ {
+ return dependencyGraph( session, projects, false );
+ }
+ }
+
+ private Result<ProjectDependencyGraph> dependencyGraph( MavenSession session, List<MavenProject> projects,
+ boolean applyMakeBehaviour )
+ {
+ MavenExecutionRequest request = session.getRequest();
+
+ ProjectDependencyGraph projectDependencyGraph = null;
+
+ try
+ {
+ projectDependencyGraph = new DefaultProjectDependencyGraph( projects );
+
+ if ( applyMakeBehaviour )
+ {
+ List<MavenProject> activeProjects = projectDependencyGraph.getSortedProjects();
+
+ activeProjects = trimSelectedProjects( activeProjects, projectDependencyGraph, request );
+ activeProjects = trimExcludedProjects( activeProjects, request );
+ activeProjects = trimResumedProjects( activeProjects, request );
+
+ if ( activeProjects.size() != projectDependencyGraph.getSortedProjects().size() )
+ {
+ projectDependencyGraph =
+ new FilteredProjectDependencyGraph( projectDependencyGraph, activeProjects );
+ }
+ }
+ }
+ catch ( CycleDetectedException e )
+ {
+ String message = "The projects in the reactor contain a cyclic reference: " + e.getMessage();
+ ProjectCycleException error = new ProjectCycleException( message, e );
+ return Result.error( Lists.newArrayList( new DefaultModelProblem( null, null, null, null, 0, 0, error ) ) );
+ }
+ catch ( org.apache.maven.project.DuplicateProjectException e )
+ {
+ return Result.error( Lists.newArrayList( new DefaultModelProblem( null, null, null, null, 0, 0, e ) ) );
+ }
+ catch ( MavenExecutionException e )
+ {
+ return Result.error( Lists.newArrayList( new DefaultModelProblem( null, null, null, null, 0, 0, e ) ) );
+ }
+
+ session.setProjects( projectDependencyGraph.getSortedProjects() );
+ session.setProjectDependencyGraph( projectDependencyGraph );
+
+ return Result.success( projectDependencyGraph );
+ }
+
+ private List<MavenProject> trimSelectedProjects( List<MavenProject> projects, ProjectDependencyGraph graph,
+ MavenExecutionRequest request )
+ throws MavenExecutionException
+ {
+ List<MavenProject> result = projects;
+
+ if ( !request.getSelectedProjects().isEmpty() )
+ {
+ File reactorDirectory = null;
+ if ( request.getBaseDirectory() != null )
+ {
+ reactorDirectory = new File( request.getBaseDirectory() );
+ }
+
+ Collection<MavenProject> selectedProjects = new LinkedHashSet<MavenProject>( projects.size() );
+
+ for ( String selector : request.getSelectedProjects() )
+ {
+ MavenProject selectedProject = null;
+
+ for ( MavenProject project : projects )
+ {
+ if ( isMatchingProject( project, selector, reactorDirectory ) )
+ {
+ selectedProject = project;
+ break;
+ }
+ }
+
+ if ( selectedProject != null )
+ {
+ selectedProjects.add( selectedProject );
+ }
+ else
+ {
+ throw new MavenExecutionException( "Could not find the selected project in the reactor: "
+ + selector, request.getPom() );
+ }
+ }
+
+ boolean makeUpstream = false;
+ boolean makeDownstream = false;
+
+ if ( MavenExecutionRequest.REACTOR_MAKE_UPSTREAM.equals( request.getMakeBehavior() ) )
+ {
+ makeUpstream = true;
+ }
+ else if ( MavenExecutionRequest.REACTOR_MAKE_DOWNSTREAM.equals( request.getMakeBehavior() ) )
+ {
+ makeDownstream = true;
+ }
+ else if ( MavenExecutionRequest.REACTOR_MAKE_BOTH.equals( request.getMakeBehavior() ) )
+ {
+ makeUpstream = true;
+ makeDownstream = true;
+ }
+ else if ( StringUtils.isNotEmpty( request.getMakeBehavior() ) )
+ {
+ throw new MavenExecutionException( "Invalid reactor make behavior: " + request.getMakeBehavior(),
+ request.getPom() );
+ }
+
+ if ( makeUpstream || makeDownstream )
+ {
+ for ( MavenProject selectedProject : new ArrayList<MavenProject>( selectedProjects ) )
+ {
+ if ( makeUpstream )
+ {
+ selectedProjects.addAll( graph.getUpstreamProjects( selectedProject, true ) );
+ }
+ if ( makeDownstream )
+ {
+ selectedProjects.addAll( graph.getDownstreamProjects( selectedProject, true ) );
+ }
+ }
+ }
+
+ result = new ArrayList<MavenProject>( selectedProjects.size() );
+
+ for ( MavenProject project : projects )
+ {
+ if ( selectedProjects.contains( project ) )
+ {
+ result.add( project );
+ }
+ }
+ }
+
+ return result;
+ }
+
+ private List<MavenProject> trimExcludedProjects( List<MavenProject> projects, MavenExecutionRequest request )
+ throws MavenExecutionException
+ {
+ List<MavenProject> result = projects;
+
+ if ( !request.getExcludedProjects().isEmpty() )
+ {
+ File reactorDirectory = null;
+
+ if ( request.getBaseDirectory() != null )
+ {
+ reactorDirectory = new File( request.getBaseDirectory() );
+ }
+
+ Collection<MavenProject> excludedProjects = new LinkedHashSet<MavenProject>( projects.size() );
+
+ for ( String selector : request.getExcludedProjects() )
+ {
+ MavenProject excludedProject = null;
+
+ for ( MavenProject project : projects )
+ {
+ if ( isMatchingProject( project, selector, reactorDirectory ) )
+ {
+ excludedProject = project;
+ break;
+ }
+ }
+
+ if ( excludedProject != null )
+ {
+ excludedProjects.add( excludedProject );
+ }
+ else
+ {
+ throw new MavenExecutionException( "Could not find the selected project in the reactor: "
+ + selector, request.getPom() );
+ }
+ }
+
+ result = new ArrayList<MavenProject>( projects.size() );
+ for ( MavenProject project : projects )
+ {
+ if ( !excludedProjects.contains( project ) )
+ {
+ result.add( project );
+ }
+ }
+ }
+
+ return result;
+ }
+
+ private List<MavenProject> trimResumedProjects( List<MavenProject> projects, MavenExecutionRequest request )
+ throws MavenExecutionException
+ {
+ List<MavenProject> result = projects;
+
+ if ( StringUtils.isNotEmpty( request.getResumeFrom() ) )
+ {
+ File reactorDirectory = null;
+ if ( request.getBaseDirectory() != null )
+ {
+ reactorDirectory = new File( request.getBaseDirectory() );
+ }
+
+ String selector = request.getResumeFrom();
+
+ result = new ArrayList<MavenProject>( projects.size() );
+
+ boolean resumed = false;
+
+ for ( MavenProject project : projects )
+ {
+ if ( !resumed && isMatchingProject( project, selector, reactorDirectory ) )
+ {
+ resumed = true;
+ }
+
+ if ( resumed )
+ {
+ result.add( project );
+ }
+ }
+
+ if ( !resumed )
+ {
+ throw new MavenExecutionException( "Could not find project to resume reactor build from: " + selector
+ + " vs " + projects, request.getPom() );
+ }
+ }
+
+ return result;
+ }
+
+ private boolean isMatchingProject( MavenProject project, String selector, File reactorDirectory )
+ {
+ // [groupId]:artifactId
+ if ( selector.indexOf( ':' ) >= 0 )
+ {
+ String id = ':' + project.getArtifactId();
+
+ if ( id.equals( selector ) )
+ {
+ return true;
+ }
+
+ id = project.getGroupId() + id;
+
+ if ( id.equals( selector ) )
+ {
+ return true;
+ }
+ }
+
+ // relative path, e.g. "sub", "../sub" or "."
+ else if ( reactorDirectory != null )
+ {
+ File selectedProject = new File( new File( reactorDirectory, selector ).toURI().normalize() );
+
+ if ( selectedProject.isFile() )
+ {
+ return selectedProject.equals( project.getFile() );
+ }
+ else if ( selectedProject.isDirectory() )
+ {
+ return selectedProject.equals( project.getBasedir() );
+ }
+ }
+
+ return false;
+ }
+
+ private MavenExecutionResult addExceptionToResult( MavenExecutionResult result, Throwable e )
+ {
+ if ( !result.getExceptions().contains( e ) )
+ {
+ result.addException( e );
+ }
+
+ return result;
+ }
+
+ // ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ //
+ // Project collection
+ //
+ // ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ private List<MavenProject> getProjectsForMavenReactor( MavenSession session )
+ throws ProjectBuildingException
+ {
+ MavenExecutionRequest request = session.getRequest();
+
+ request.getProjectBuildingRequest().setRepositorySession( session.getRepositorySession() );
+
+ List<MavenProject> projects = new ArrayList<MavenProject>();
+
+ // We have no POM file.
+ //
+ if ( request.getPom() == null )
+ {
+ ModelSource modelSource = new UrlModelSource( DefaultMaven.class.getResource( "project/standalone.xml" ) );
+ MavenProject project = projectBuilder.build( modelSource, request.getProjectBuildingRequest() )
+ .getProject();
+ project.setExecutionRoot( true );
+ projects.add( project );
+ request.setProjectPresent( false );
+ return projects;
+ }
+
+ List<File> files = Arrays.asList( request.getPom().getAbsoluteFile() );
+ collectProjects( projects, files, request );
+ return projects;
+ }
+
+ private void collectProjects( List<MavenProject> projects, List<File> files, MavenExecutionRequest request )
+ throws ProjectBuildingException
+ {
+ ProjectBuildingRequest projectBuildingRequest = request.getProjectBuildingRequest();
+
+ List<ProjectBuildingResult> results = projectBuilder.build( files, request.isRecursive(),
+ projectBuildingRequest );
+
+ boolean problems = false;
+
+ for ( ProjectBuildingResult result : results )
+ {
+ projects.add( result.getProject() );
+
+ if ( !result.getProblems().isEmpty() && logger.isWarnEnabled() )
+ {
+ logger.warn( "" );
+ logger.warn( "Some problems were encountered while building the effective model for "
+ + result.getProject().getId() );
+
+ for ( ModelProblem problem : result.getProblems() )
+ {
+ String loc = ModelProblemUtils.formatLocation( problem, result.getProjectId() );
+ logger.warn( problem.getMessage() + ( StringUtils.isNotEmpty( loc ) ? " @ " + loc : "" ) );
+ }
+
+ problems = true;
+ }
+ }
+
+ if ( problems )
+ {
+ logger.warn( "" );
+ logger.warn( "It is highly recommended to fix these problems"
+ + " because they threaten the stability of your build." );
+ logger.warn( "" );
+ logger.warn( "For this reason, future Maven versions might no"
+ + " longer support building such malformed projects." );
+ logger.warn( "" );
+ }
+ }
+
+ private void validateProjects( List<MavenProject> projects )
+ {
+ Map<String, MavenProject> projectsMap = new HashMap<String, MavenProject>();
+
+ for ( MavenProject p : projects )
+ {
+ String projectKey = ArtifactUtils.key( p.getGroupId(), p.getArtifactId(), p.getVersion() );
+
+ projectsMap.put( projectKey, p );
+ }
+
+ for ( MavenProject project : projects )
+ {
+ // MNG-1911 / MNG-5572: Building plugins with extensions cannot be part of reactor
+ for ( Plugin plugin : project.getBuildPlugins() )
+ {
+ if ( plugin.isExtensions() )
+ {
+ String pluginKey = ArtifactUtils.key( plugin.getGroupId(), plugin.getArtifactId(),
+ plugin.getVersion() );
+
+ if ( projectsMap.containsKey( pluginKey ) )
+ {
+ logger.warn( project.getName() + " uses " + plugin.getKey()
+ + " as extensions, which is not possible within the same reactor build. "
+ + "This plugin was pulled from the local repository!" );
+ }
+ }
+ }
+ }
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/graph/DefaultProjectDependencyGraph.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/graph/DefaultProjectDependencyGraph.java
new file mode 100644
index 00000000..01fec339
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/graph/DefaultProjectDependencyGraph.java
@@ -0,0 +1,134 @@
+package org.apache.maven.graph;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.maven.execution.ProjectDependencyGraph;
+import org.apache.maven.project.DuplicateProjectException;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.project.ProjectSorter;
+import org.codehaus.plexus.util.dag.CycleDetectedException;
+
+/**
+ * Describes the inter-dependencies between projects in the reactor.
+ *
+ * @author Benjamin Bentmann
+ */
+public class DefaultProjectDependencyGraph
+ implements ProjectDependencyGraph
+{
+
+ private ProjectSorter sorter;
+
+ /**
+ * Creates a new project dependency graph based on the specified projects.
+ *
+ * @param projects The projects to create the dependency graph with
+ * @throws DuplicateProjectException
+ * @throws CycleDetectedException
+ */
+ public DefaultProjectDependencyGraph( Collection<MavenProject> projects )
+ throws CycleDetectedException, DuplicateProjectException
+ {
+ this.sorter = new ProjectSorter( projects );
+ }
+
+ public List<MavenProject> getSortedProjects()
+ {
+ return new ArrayList<MavenProject>( sorter.getSortedProjects() );
+ }
+
+ public List<MavenProject> getDownstreamProjects( MavenProject project, boolean transitive )
+ {
+ if ( project == null )
+ {
+ throw new IllegalArgumentException( "project missing" );
+ }
+
+ Set<String> projectIds = new HashSet<String>();
+
+ getDownstreamProjects( ProjectSorter.getId( project ), projectIds, transitive );
+
+ return getSortedProjects( projectIds );
+ }
+
+ private void getDownstreamProjects( String projectId, Set<String> projectIds, boolean transitive )
+ {
+ for ( String id : sorter.getDependents( projectId ) )
+ {
+ if ( projectIds.add( id ) && transitive )
+ {
+ getDownstreamProjects( id, projectIds, transitive );
+ }
+ }
+ }
+
+ public List<MavenProject> getUpstreamProjects( MavenProject project, boolean transitive )
+ {
+ if ( project == null )
+ {
+ throw new IllegalArgumentException( "project missing" );
+ }
+
+ Set<String> projectIds = new HashSet<String>();
+
+ getUpstreamProjects( ProjectSorter.getId( project ), projectIds, transitive );
+
+ return getSortedProjects( projectIds );
+ }
+
+ private void getUpstreamProjects( String projectId, Collection<String> projectIds, boolean transitive )
+ {
+ for ( String id : sorter.getDependencies( projectId ) )
+ {
+ if ( projectIds.add( id ) && transitive )
+ {
+ getUpstreamProjects( id, projectIds, transitive );
+ }
+ }
+ }
+
+ private List<MavenProject> getSortedProjects( Set<String> projectIds )
+ {
+ List<MavenProject> result = new ArrayList<MavenProject>( projectIds.size() );
+
+ for ( MavenProject mavenProject : sorter.getSortedProjects() )
+ {
+ if ( projectIds.contains( ProjectSorter.getId( mavenProject ) ) )
+ {
+ result.add( mavenProject );
+ }
+ }
+
+ return result;
+ }
+
+ @Override
+ public String toString()
+ {
+ return sorter.getSortedProjects().toString();
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/graph/FilteredProjectDependencyGraph.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/graph/FilteredProjectDependencyGraph.java
new file mode 100644
index 00000000..662bda47
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/graph/FilteredProjectDependencyGraph.java
@@ -0,0 +1,111 @@
+package org.apache.maven.graph;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.IdentityHashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.maven.execution.ProjectDependencyGraph;
+import org.apache.maven.project.MavenProject;
+
+/**
+ * Provides a sub view of another dependency graph.
+ *
+ * @author Benjamin Bentmann
+ */
+class FilteredProjectDependencyGraph
+ implements ProjectDependencyGraph
+{
+
+ private ProjectDependencyGraph projectDependencyGraph;
+
+ private Map<MavenProject, ?> whiteList;
+
+ private List<MavenProject> sortedProjects;
+
+ /**
+ * Creates a new project dependency graph from the specified graph.
+ *
+ * @param projectDependencyGraph The project dependency graph to create a sub view from, must not be {@code null}.
+ * @param whiteList The projects on which the dependency view should focus, must not be {@code null}.
+ */
+ public FilteredProjectDependencyGraph( ProjectDependencyGraph projectDependencyGraph,
+ Collection<? extends MavenProject> whiteList )
+ {
+ if ( projectDependencyGraph == null )
+ {
+ throw new IllegalArgumentException( "project dependency graph missing" );
+ }
+
+ this.projectDependencyGraph = projectDependencyGraph;
+
+ this.whiteList = new IdentityHashMap<MavenProject, Object>();
+
+ for ( MavenProject project : whiteList )
+ {
+ this.whiteList.put( project, null );
+ }
+ }
+
+ public List<MavenProject> getSortedProjects()
+ {
+ if ( sortedProjects == null )
+ {
+ sortedProjects = applyFilter( projectDependencyGraph.getSortedProjects() );
+ }
+
+ return new ArrayList<MavenProject>( sortedProjects );
+ }
+
+ public List<MavenProject> getDownstreamProjects( MavenProject project, boolean transitive )
+ {
+ return applyFilter( projectDependencyGraph.getDownstreamProjects( project, transitive ) );
+ }
+
+ public List<MavenProject> getUpstreamProjects( MavenProject project, boolean transitive )
+ {
+ return applyFilter( projectDependencyGraph.getUpstreamProjects( project, transitive ) );
+ }
+
+ private List<MavenProject> applyFilter( Collection<? extends MavenProject> projects )
+ {
+ List<MavenProject> filtered = new ArrayList<MavenProject>( projects.size() );
+
+ for ( MavenProject project : projects )
+ {
+ if ( whiteList.containsKey( project ) )
+ {
+ filtered.add( project );
+ }
+ }
+
+ return filtered;
+ }
+
+ @Override
+ public String toString()
+ {
+ return getSortedProjects().toString();
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/graph/GraphBuilder.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/graph/GraphBuilder.java
new file mode 100644
index 00000000..fb7c4f2a
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/graph/GraphBuilder.java
@@ -0,0 +1,31 @@
+package org.apache.maven.graph;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.execution.ProjectDependencyGraph;
+import org.apache.maven.model.building.Result;
+
+public interface GraphBuilder
+{
+ String HINT = "graphBuilder";
+
+ Result<? extends ProjectDependencyGraph> build( MavenSession session );
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/internal/aether/DefaultRepositorySystemSessionFactory.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/internal/aether/DefaultRepositorySystemSessionFactory.java
new file mode 100644
index 00000000..26a8ddae
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/internal/aether/DefaultRepositorySystemSessionFactory.java
@@ -0,0 +1,271 @@
+package org.apache.maven.internal.aether;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Properties;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import org.apache.maven.RepositoryUtils;
+import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager;
+import org.apache.maven.bridge.MavenRepositorySystem;
+import org.apache.maven.eventspy.internal.EventSpyDispatcher;
+import org.apache.maven.execution.MavenExecutionRequest;
+import org.apache.maven.repository.internal.MavenRepositorySystemUtils;
+import org.apache.maven.settings.Mirror;
+import org.apache.maven.settings.Proxy;
+import org.apache.maven.settings.Server;
+import org.apache.maven.settings.building.SettingsProblem;
+import org.apache.maven.settings.crypto.DefaultSettingsDecryptionRequest;
+import org.apache.maven.settings.crypto.SettingsDecrypter;
+import org.apache.maven.settings.crypto.SettingsDecryptionResult;
+import org.codehaus.plexus.configuration.xml.XmlPlexusConfiguration;
+import org.codehaus.plexus.logging.Logger;
+import org.codehaus.plexus.util.IOUtil;
+import org.codehaus.plexus.util.xml.Xpp3Dom;
+import org.eclipse.aether.ConfigurationProperties;
+import org.eclipse.aether.DefaultRepositorySystemSession;
+import org.eclipse.aether.RepositorySystem;
+import org.eclipse.aether.repository.LocalRepository;
+import org.eclipse.aether.repository.NoLocalRepositoryManagerException;
+import org.eclipse.aether.repository.RepositoryPolicy;
+import org.eclipse.aether.repository.WorkspaceReader;
+import org.eclipse.aether.resolution.ResolutionErrorPolicy;
+import org.eclipse.aether.spi.localrepo.LocalRepositoryManagerFactory;
+import org.eclipse.aether.util.repository.AuthenticationBuilder;
+import org.eclipse.aether.util.repository.DefaultAuthenticationSelector;
+import org.eclipse.aether.util.repository.DefaultMirrorSelector;
+import org.eclipse.aether.util.repository.DefaultProxySelector;
+import org.eclipse.aether.util.repository.SimpleResolutionErrorPolicy;
+import org.eclipse.sisu.Nullable;
+
+/**
+ * @since 3.3.0
+ */
+@Named
+public class DefaultRepositorySystemSessionFactory
+{
+ @Inject
+ private Logger logger;
+
+ @Inject
+ private ArtifactHandlerManager artifactHandlerManager;
+
+ @Inject
+ private RepositorySystem repoSystem;
+
+ @Inject
+ @Nullable
+ @Named( "simple" )
+ private LocalRepositoryManagerFactory simpleLocalRepoMgrFactory;
+
+ @Inject
+ @Nullable
+ @Named( "ide" )
+ private WorkspaceReader workspaceRepository;
+
+ @Inject
+ private SettingsDecrypter settingsDecrypter;
+
+ @Inject
+ private EventSpyDispatcher eventSpyDispatcher;
+
+ @Inject
+ MavenRepositorySystem mavenRepositorySystem;
+
+ public DefaultRepositorySystemSession newRepositorySession( MavenExecutionRequest request )
+ {
+ DefaultRepositorySystemSession session = MavenRepositorySystemUtils.newSession();
+
+ session.setCache( request.getRepositoryCache() );
+
+ Map<Object, Object> configProps = new LinkedHashMap<Object, Object>();
+ configProps.put( ConfigurationProperties.USER_AGENT, getUserAgent() );
+ configProps.put( ConfigurationProperties.INTERACTIVE, request.isInteractiveMode() );
+ configProps.putAll( request.getSystemProperties() );
+ configProps.putAll( request.getUserProperties() );
+
+ session.setOffline( request.isOffline() );
+ session.setChecksumPolicy( request.getGlobalChecksumPolicy() );
+ if ( request.isNoSnapshotUpdates() )
+ {
+ session.setUpdatePolicy( RepositoryPolicy.UPDATE_POLICY_NEVER );
+ }
+ else if ( request.isUpdateSnapshots() )
+ {
+ session.setUpdatePolicy( RepositoryPolicy.UPDATE_POLICY_ALWAYS );
+ }
+ else
+ {
+ session.setUpdatePolicy( null );
+ }
+
+ int errorPolicy = 0;
+ errorPolicy |= request.isCacheNotFound() ? ResolutionErrorPolicy.CACHE_NOT_FOUND : 0;
+ errorPolicy |= request.isCacheTransferError() ? ResolutionErrorPolicy.CACHE_TRANSFER_ERROR : 0;
+ session.setResolutionErrorPolicy( new SimpleResolutionErrorPolicy( errorPolicy, errorPolicy
+ | ResolutionErrorPolicy.CACHE_NOT_FOUND ) );
+
+ session.setArtifactTypeRegistry( RepositoryUtils.newArtifactTypeRegistry( artifactHandlerManager ) );
+
+ LocalRepository localRepo = new LocalRepository( request.getLocalRepository().getBasedir() );
+
+ if ( request.isUseLegacyLocalRepository() )
+ {
+ logger.warn( "Disabling enhanced local repository: using legacy is strongly discouraged to ensure"
+ + " build reproducibility." );
+ try
+ {
+ session.setLocalRepositoryManager( simpleLocalRepoMgrFactory.newInstance( session, localRepo ) );
+ }
+ catch ( NoLocalRepositoryManagerException e )
+ {
+
+ logger.warn( "Failed to configure legacy local repository: back to default" );
+ session.setLocalRepositoryManager( repoSystem.newLocalRepositoryManager( session, localRepo ) );
+ }
+ }
+ else
+ {
+ session.setLocalRepositoryManager( repoSystem.newLocalRepositoryManager( session, localRepo ) );
+ }
+
+ if ( request.getWorkspaceReader() != null )
+ {
+ session.setWorkspaceReader( request.getWorkspaceReader() );
+ }
+ else
+ {
+ session.setWorkspaceReader( workspaceRepository );
+ }
+
+ DefaultSettingsDecryptionRequest decrypt = new DefaultSettingsDecryptionRequest();
+ decrypt.setProxies( request.getProxies() );
+ decrypt.setServers( request.getServers() );
+ SettingsDecryptionResult decrypted = settingsDecrypter.decrypt( decrypt );
+
+ if ( logger.isDebugEnabled() )
+ {
+ for ( SettingsProblem problem : decrypted.getProblems() )
+ {
+ logger.debug( problem.getMessage(), problem.getException() );
+ }
+ }
+
+ DefaultMirrorSelector mirrorSelector = new DefaultMirrorSelector();
+ for ( Mirror mirror : request.getMirrors() )
+ {
+ mirrorSelector.add( mirror.getId(), mirror.getUrl(), mirror.getLayout(), false, mirror.getMirrorOf(),
+ mirror.getMirrorOfLayouts() );
+ }
+ session.setMirrorSelector( mirrorSelector );
+
+ DefaultProxySelector proxySelector = new DefaultProxySelector();
+ for ( Proxy proxy : decrypted.getProxies() )
+ {
+ AuthenticationBuilder authBuilder = new AuthenticationBuilder();
+ authBuilder.addUsername( proxy.getUsername() ).addPassword( proxy.getPassword() );
+ proxySelector.add( new org.eclipse.aether.repository.Proxy( proxy.getProtocol(), proxy.getHost(),
+ proxy.getPort(), authBuilder.build() ),
+ proxy.getNonProxyHosts() );
+ }
+ session.setProxySelector( proxySelector );
+
+ DefaultAuthenticationSelector authSelector = new DefaultAuthenticationSelector();
+ for ( Server server : decrypted.getServers() )
+ {
+ AuthenticationBuilder authBuilder = new AuthenticationBuilder();
+ authBuilder.addUsername( server.getUsername() ).addPassword( server.getPassword() );
+ authBuilder.addPrivateKey( server.getPrivateKey(), server.getPassphrase() );
+ authSelector.add( server.getId(), authBuilder.build() );
+
+ if ( server.getConfiguration() != null )
+ {
+ Xpp3Dom dom = (Xpp3Dom) server.getConfiguration();
+ for ( int i = dom.getChildCount() - 1; i >= 0; i-- )
+ {
+ Xpp3Dom child = dom.getChild( i );
+ if ( "wagonProvider".equals( child.getName() ) )
+ {
+ dom.removeChild( i );
+ }
+ }
+
+ XmlPlexusConfiguration config = new XmlPlexusConfiguration( dom );
+ configProps.put( "aether.connector.wagon.config." + server.getId(), config );
+ }
+
+ configProps.put( "aether.connector.perms.fileMode." + server.getId(), server.getFilePermissions() );
+ configProps.put( "aether.connector.perms.dirMode." + server.getId(), server.getDirectoryPermissions() );
+ }
+ session.setAuthenticationSelector( authSelector );
+
+ session.setTransferListener( request.getTransferListener() );
+
+ session.setRepositoryListener( eventSpyDispatcher.chainListener( new LoggingRepositoryListener( logger ) ) );
+
+ session.setUserProperties( request.getUserProperties() );
+ session.setSystemProperties( request.getSystemProperties() );
+ session.setConfigProperties( configProps );
+
+ mavenRepositorySystem.injectMirror( request.getRemoteRepositories(), request.getMirrors() );
+ mavenRepositorySystem.injectProxy( session, request.getRemoteRepositories() );
+ mavenRepositorySystem.injectAuthentication( session, request.getRemoteRepositories() );
+
+ mavenRepositorySystem.injectMirror( request.getPluginArtifactRepositories(), request.getMirrors() );
+ mavenRepositorySystem.injectProxy( session, request.getPluginArtifactRepositories() );
+ mavenRepositorySystem.injectAuthentication( session, request.getPluginArtifactRepositories() );
+
+ return session;
+ }
+
+ private String getUserAgent()
+ {
+ return "Apache-Maven/" + getMavenVersion() + " (Java " + System.getProperty( "java.version" ) + "; "
+ + System.getProperty( "os.name" ) + " " + System.getProperty( "os.version" ) + ")";
+ }
+
+ private String getMavenVersion()
+ {
+ Properties props = new Properties();
+
+ InputStream is = getClass().getResourceAsStream( "/META-INF/maven/org.apache.maven/maven-core/pom.properties" );
+ if ( is != null )
+ {
+ try
+ {
+ props.load( is );
+ }
+ catch ( IOException e )
+ {
+ logger.debug( "Failed to read Maven version", e );
+ }
+ IOUtil.close( is );
+ }
+
+ return props.getProperty( "version", "unknown-version" );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/internal/aether/LoggingRepositoryListener.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/internal/aether/LoggingRepositoryListener.java
new file mode 100644
index 00000000..7b67c3bd
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/internal/aether/LoggingRepositoryListener.java
@@ -0,0 +1,141 @@
+package org.apache.maven.internal.aether;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.FileNotFoundException;
+
+import org.codehaus.plexus.logging.Logger;
+import org.eclipse.aether.AbstractRepositoryListener;
+import org.eclipse.aether.RepositoryEvent;
+import org.eclipse.aether.transfer.MetadataNotFoundException;
+
+/**
+ * @author Benjamin Bentmann
+ */
+class LoggingRepositoryListener
+ extends AbstractRepositoryListener
+{
+
+ private final Logger logger;
+
+ public LoggingRepositoryListener( Logger logger )
+ {
+ this.logger = logger;
+ }
+
+ @Override
+ public void artifactInstalling( RepositoryEvent event )
+ {
+ logger.info( "Installing " + event.getArtifact().getFile() + " to " + event.getFile() );
+ }
+
+ @Override
+ public void metadataInstalling( RepositoryEvent event )
+ {
+ logger.debug( "Installing " + event.getMetadata() + " to " + event.getFile() );
+ }
+
+ @Override
+ public void metadataResolved( RepositoryEvent event )
+ {
+ Exception e = event.getException();
+ if ( e != null )
+ {
+ if ( e instanceof MetadataNotFoundException )
+ {
+ logger.debug( e.getMessage() );
+ }
+ else if ( logger.isDebugEnabled() )
+ {
+ logger.warn( e.getMessage(), e );
+ }
+ else
+ {
+ logger.warn( e.getMessage() );
+ }
+ }
+ }
+
+ @Override
+ public void metadataInvalid( RepositoryEvent event )
+ {
+ Exception exception = event.getException();
+
+ StringBuilder buffer = new StringBuilder( 256 );
+ buffer.append( "The metadata " );
+ if ( event.getMetadata().getFile() != null )
+ {
+ buffer.append( event.getMetadata().getFile() );
+ }
+ else
+ {
+ buffer.append( event.getMetadata() );
+ }
+
+ if ( exception instanceof FileNotFoundException )
+ {
+ buffer.append( " is inaccessible" );
+ }
+ else
+ {
+ buffer.append( " is invalid" );
+ }
+
+ if ( exception != null )
+ {
+ buffer.append( ": " );
+ buffer.append( exception.getMessage() );
+ }
+
+ if ( logger.isDebugEnabled() )
+ {
+ logger.warn( buffer.toString(), exception );
+ }
+ else
+ {
+ logger.warn( buffer.toString() );
+ }
+ }
+
+ @Override
+ public void artifactDescriptorInvalid( RepositoryEvent event )
+ {
+ StringBuilder buffer = new StringBuilder( 256 );
+ buffer.append( "The POM for " );
+ buffer.append( event.getArtifact() );
+ buffer.append( " is invalid, transitive dependencies (if any) will not be available" );
+
+ if ( logger.isDebugEnabled() )
+ {
+ logger.warn( buffer + ": " + event.getException().getMessage() );
+ }
+ else
+ {
+ logger.warn( buffer + ", enable debug logging for more details" );
+ }
+ }
+
+ @Override
+ public void artifactDescriptorMissing( RepositoryEvent event )
+ {
+ logger.warn( "The POM for " + event.getArtifact() + " is missing, no dependency information available" );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/DefaultLifecycleExecutor.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/DefaultLifecycleExecutor.java
new file mode 100644
index 00000000..6f994b3d
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/DefaultLifecycleExecutor.java
@@ -0,0 +1,177 @@
+package org.apache.maven.lifecycle;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.lifecycle.internal.LifecycleExecutionPlanCalculator;
+import org.apache.maven.lifecycle.internal.LifecycleStarter;
+import org.apache.maven.lifecycle.internal.LifecycleTaskSegmentCalculator;
+import org.apache.maven.lifecycle.internal.MojoDescriptorCreator;
+import org.apache.maven.lifecycle.internal.MojoExecutor;
+import org.apache.maven.lifecycle.internal.ProjectIndex;
+import org.apache.maven.lifecycle.internal.TaskSegment;
+import org.apache.maven.model.Plugin;
+import org.apache.maven.plugin.InvalidPluginDescriptorException;
+import org.apache.maven.plugin.MojoExecution;
+import org.apache.maven.plugin.MojoNotFoundException;
+import org.apache.maven.plugin.PluginDescriptorParsingException;
+import org.apache.maven.plugin.PluginManagerException;
+import org.apache.maven.plugin.PluginNotFoundException;
+import org.apache.maven.plugin.PluginResolutionException;
+import org.apache.maven.plugin.descriptor.MojoDescriptor;
+import org.apache.maven.plugin.prefix.NoPluginFoundForPrefixException;
+import org.apache.maven.plugin.version.PluginVersionResolutionException;
+import org.apache.maven.project.MavenProject;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * A facade that provides lifecycle services to components outside maven core.
+ *
+ * Note that this component is not normally used from within core itself.
+ *
+ * @author Jason van Zyl
+ * @author Benjamin Bentmann
+ * @author Kristian Rosenvold
+ */
+@Component( role = LifecycleExecutor.class )
+public class DefaultLifecycleExecutor
+ implements LifecycleExecutor
+{
+
+ @Requirement
+ private LifeCyclePluginAnalyzer lifeCyclePluginAnalyzer;
+
+ @Requirement
+ private DefaultLifecycles defaultLifeCycles;
+
+ @Requirement
+ private LifecycleTaskSegmentCalculator lifecycleTaskSegmentCalculator;
+
+ @Requirement
+ private LifecycleExecutionPlanCalculator lifecycleExecutionPlanCalculator;
+
+ @Requirement
+ private MojoExecutor mojoExecutor;
+
+ @Requirement
+ private LifecycleStarter lifecycleStarter;
+
+
+ public void execute( MavenSession session )
+ {
+ lifecycleStarter.execute( session );
+ }
+
+ @Requirement
+ private MojoDescriptorCreator mojoDescriptorCreator;
+
+ // These methods deal with construction intact Plugin object that look like they come from a standard
+ // <plugin/> block in a Maven POM. We have to do some wiggling to pull the sources of information
+ // together and this really shows the problem of constructing a sensible default configuration but
+ // it's all encapsulated here so it appears normalized to the POM builder.
+
+ // We are going to take the project packaging and find all plugin in the default lifecycle and create
+ // fully populated Plugin objects, including executions with goals and default configuration taken
+ // from the plugin.xml inside a plugin.
+ //
+ // TODO: This whole method could probably removed by injecting lifeCyclePluginAnalyzer straight into client site.
+ // TODO: But for some reason the whole plexus appcontext refuses to start when I try this.
+
+ public Set<Plugin> getPluginsBoundByDefaultToAllLifecycles( String packaging )
+ {
+ return lifeCyclePluginAnalyzer.getPluginsBoundByDefaultToAllLifecycles( packaging );
+ }
+
+ // USED BY MAVEN HELP PLUGIN
+
+ @Deprecated
+ public Map<String, Lifecycle> getPhaseToLifecycleMap()
+ {
+ return defaultLifeCycles.getPhaseToLifecycleMap();
+ }
+
+ // NOTE: Backward-compat with maven-help-plugin:2.1
+
+ @SuppressWarnings( { "UnusedDeclaration" } )
+ MojoDescriptor getMojoDescriptor( String task, MavenSession session, MavenProject project, String invokedVia,
+ boolean canUsePrefix, boolean isOptionalMojo )
+ throws PluginNotFoundException, PluginResolutionException, PluginDescriptorParsingException,
+ MojoNotFoundException, NoPluginFoundForPrefixException, InvalidPluginDescriptorException,
+ PluginVersionResolutionException
+ {
+ return mojoDescriptorCreator.getMojoDescriptor( task, session, project );
+ }
+
+ // Used by m2eclipse
+
+ @SuppressWarnings( { "UnusedDeclaration" } )
+ public MavenExecutionPlan calculateExecutionPlan( MavenSession session, boolean setup, String... tasks )
+ throws PluginNotFoundException, PluginResolutionException, PluginDescriptorParsingException,
+ MojoNotFoundException, NoPluginFoundForPrefixException, InvalidPluginDescriptorException,
+ PluginManagerException, LifecyclePhaseNotFoundException, LifecycleNotFoundException,
+ PluginVersionResolutionException
+ {
+ List<TaskSegment> taskSegments =
+ lifecycleTaskSegmentCalculator.calculateTaskSegments( session, Arrays.asList( tasks ) );
+
+ TaskSegment mergedSegment = new TaskSegment( false );
+
+ for ( TaskSegment taskSegment : taskSegments )
+ {
+ mergedSegment.getTasks().addAll( taskSegment.getTasks() );
+ }
+
+ return lifecycleExecutionPlanCalculator.calculateExecutionPlan( session, session.getCurrentProject(),
+ mergedSegment.getTasks(), setup );
+ }
+
+ public MavenExecutionPlan calculateExecutionPlan( MavenSession session, String... tasks )
+ throws PluginNotFoundException, PluginResolutionException, PluginDescriptorParsingException,
+ MojoNotFoundException, NoPluginFoundForPrefixException, InvalidPluginDescriptorException,
+ PluginManagerException, LifecyclePhaseNotFoundException, LifecycleNotFoundException,
+ PluginVersionResolutionException
+ {
+ return calculateExecutionPlan( session, true, tasks );
+ }
+
+ // Site 3.x
+ public void calculateForkedExecutions( MojoExecution mojoExecution, MavenSession session )
+ throws MojoNotFoundException, PluginNotFoundException, PluginResolutionException,
+ PluginDescriptorParsingException, NoPluginFoundForPrefixException, InvalidPluginDescriptorException,
+ LifecyclePhaseNotFoundException, LifecycleNotFoundException, PluginVersionResolutionException
+ {
+ lifecycleExecutionPlanCalculator.calculateForkedExecutions( mojoExecution, session );
+ }
+
+ // Site 3.x
+ public List<MavenProject> executeForkedExecutions( MojoExecution mojoExecution, MavenSession session )
+ throws LifecycleExecutionException
+ {
+ return mojoExecutor.executeForkedExecutions( mojoExecution, session,
+ new ProjectIndex( session.getProjects() ) );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/DefaultLifecycles.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/DefaultLifecycles.java
new file mode 100644
index 00000000..64c9a7f9
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/DefaultLifecycles.java
@@ -0,0 +1,144 @@
+package org.apache.maven.lifecycle;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+import org.codehaus.plexus.logging.Logger;
+import org.codehaus.plexus.util.StringUtils;
+
+import com.google.common.base.Preconditions;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * @since 3.0
+ * @author Jason van Zyl
+ * @author Kristian Rosenvold
+ */
+// TODO: The configuration for the lifecycle needs to be externalized so that I can use the annotations properly for the
+// wiring and reference and external source for the lifecycle configuration.
+@Component( role = DefaultLifecycles.class )
+public class DefaultLifecycles
+{
+ public static final String[] STANDARD_LIFECYCLES = { "default", "clean", "site" };
+
+ // @Configuration(source="org/apache/maven/lifecycle/lifecycles.xml")
+
+ @Requirement( role = Lifecycle.class )
+ private Map<String, Lifecycle> lifecycles;
+
+ @Requirement
+ private Logger logger;
+
+ public DefaultLifecycles()
+ {
+ }
+
+ public DefaultLifecycles( Map<String, Lifecycle> lifecycles, Logger logger )
+ {
+ this.lifecycles = new LinkedHashMap<String, Lifecycle>();
+ this.logger = logger;
+ this.lifecycles = lifecycles;
+ }
+
+ public Lifecycle get( String key )
+ {
+ return getPhaseToLifecycleMap().get( key );
+ }
+
+ /**
+ * We use this to map all phases to the lifecycle that contains it. This is used so that a user can specify the
+ * phase they want to execute and we can easily determine what lifecycle we need to run.
+ *
+ * @return A map of lifecycles, indexed on id
+ */
+ public Map<String, Lifecycle> getPhaseToLifecycleMap()
+ {
+ // If people are going to make their own lifecycles then we need to tell people how to namespace them correctly
+ // so that they don't interfere with internally defined lifecycles.
+
+ HashMap<String, Lifecycle> phaseToLifecycleMap = new HashMap<String, Lifecycle>();
+
+ for ( Lifecycle lifecycle : getLifeCycles() )
+ {
+ if ( logger.isDebugEnabled() )
+ {
+ logger.debug( "Lifecycle " + lifecycle );
+ }
+
+ for ( String phase : lifecycle.getPhases() )
+ {
+ // The first definition wins.
+ if ( !phaseToLifecycleMap.containsKey( phase ) )
+ {
+ phaseToLifecycleMap.put( phase, lifecycle );
+ }
+ else
+ {
+ Lifecycle original = phaseToLifecycleMap.get( phase );
+ logger.warn( "Duplicated lifecycle phase " + phase + ". Defined in " + original.getId()
+ + " but also in " + lifecycle.getId() );
+ }
+ }
+ }
+
+ return phaseToLifecycleMap;
+ }
+
+ public List<Lifecycle> getLifeCycles()
+ {
+ // ensure canonical order of standard lifecycles
+ Map<String, Lifecycle> lifecycles = new LinkedHashMap<String, Lifecycle>( this.lifecycles );
+
+ LinkedHashSet<String> lifecycleNames = new LinkedHashSet<String>( Arrays.asList( STANDARD_LIFECYCLES ) );
+ lifecycleNames.addAll( lifecycles.keySet() );
+
+ ArrayList<Lifecycle> result = new ArrayList<Lifecycle>();
+ for ( String name : lifecycleNames )
+ {
+ Lifecycle lifecycle = lifecycles.get( name );
+ Preconditions.checkNotNull( "A lifecycle must have an id.", lifecycle.getId() );
+ result.add( lifecycle );
+ }
+
+ return result;
+ }
+
+ public String getLifecyclePhaseList()
+ {
+ Set<String> phases = new LinkedHashSet<String>();
+
+ for ( Lifecycle lifecycle : getLifeCycles() )
+ {
+ phases.addAll( lifecycle.getPhases() );
+ }
+
+ return StringUtils.join( phases.iterator(), ", " );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/LifeCyclePluginAnalyzer.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/LifeCyclePluginAnalyzer.java
new file mode 100644
index 00000000..ed07c1d5
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/LifeCyclePluginAnalyzer.java
@@ -0,0 +1,32 @@
+package org.apache.maven.lifecycle;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Set;
+import org.apache.maven.model.Plugin;
+
+/**
+ * @since 3.0
+ * @author Kristian Rosenvold
+ */
+public interface LifeCyclePluginAnalyzer
+{
+ Set<Plugin> getPluginsBoundByDefaultToAllLifecycles( String packaging );
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/Lifecycle.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/Lifecycle.java
new file mode 100644
index 00000000..fcfde951
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/Lifecycle.java
@@ -0,0 +1,80 @@
+package org.apache.maven.lifecycle;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Class Lifecycle.
+ */
+public class Lifecycle
+{
+ public Lifecycle()
+ {
+ }
+
+ public Lifecycle( String id, List<String> phases, Map<String, String> defaultPhases )
+ {
+ this.id = id;
+ this.phases = phases;
+ this.defaultPhases = defaultPhases;
+ }
+
+ // <lifecycle>
+ // <id>clean</id>
+ // <phases>
+ // <phase>pre-clean</phase>
+ // <phase>clean</phase>
+ // <phase>post-clean</phase>
+ // </phases>
+ // <default-phases>
+ // <clean>org.apache.maven.plugins:maven-clean-plugin:clean</clean>
+ // </default-phases>
+ // </lifecycle>
+
+ private String id;
+
+ private List<String> phases;
+
+ private Map<String, String> defaultPhases;
+
+ public String getId()
+ {
+ return this.id;
+ }
+
+ public List<String> getPhases()
+ {
+ return this.phases;
+ }
+
+ public Map<String, String> getDefaultPhases()
+ {
+ return defaultPhases;
+ }
+
+ @Override
+ public String toString()
+ {
+ return id + " -> " + phases;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/LifecycleExecutionException.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/LifecycleExecutionException.java
new file mode 100644
index 00000000..349576cd
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/LifecycleExecutionException.java
@@ -0,0 +1,111 @@
+package org.apache.maven.lifecycle;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.plugin.MojoExecution;
+import org.apache.maven.project.MavenProject;
+
+/**
+ * @author <a href="mailto:jason@maven.org">Jason van Zyl</a>
+ */
+public class LifecycleExecutionException
+ extends Exception
+{
+ private MavenProject project;
+
+ public LifecycleExecutionException( String message )
+ {
+ super( message );
+ }
+
+ public LifecycleExecutionException( Throwable cause )
+ {
+ super( cause );
+ }
+
+ public LifecycleExecutionException( String message, Throwable cause )
+ {
+ super( message, cause );
+ }
+
+ public LifecycleExecutionException( String message, MavenProject project )
+ {
+ super( message );
+ this.project = project;
+ }
+
+ public LifecycleExecutionException( String message, MojoExecution execution, MavenProject project )
+ {
+ super( message );
+ this.project = project;
+ }
+
+ public LifecycleExecutionException( String message, MojoExecution execution, MavenProject project, Throwable cause )
+ {
+ super( message, cause );
+ this.project = project;
+ }
+
+ public LifecycleExecutionException( MojoExecution execution, MavenProject project, Throwable cause )
+ {
+ this( createMessage( execution, project, cause ), execution, project, cause );
+ }
+
+ public MavenProject getProject()
+ {
+ return project;
+ }
+
+ private static String createMessage( MojoExecution execution, MavenProject project, Throwable cause )
+ {
+ StringBuilder buffer = new StringBuilder( 256 );
+
+ buffer.append( "Failed to execute goal" );
+
+ if ( execution != null )
+ {
+ buffer.append( ' ' );
+ buffer.append( execution.getGroupId() );
+ buffer.append( ':' );
+ buffer.append( execution.getArtifactId() );
+ buffer.append( ':' );
+ buffer.append( execution.getVersion() );
+ buffer.append( ':' );
+ buffer.append( execution.getGoal() );
+ buffer.append( " (" );
+ buffer.append( execution.getExecutionId() );
+ buffer.append( ")" );
+ }
+
+ if ( project != null )
+ {
+ buffer.append( " on project " );
+ buffer.append( project.getArtifactId() );
+ }
+
+ if ( cause != null )
+ {
+ buffer.append( ": " ).append( cause.getMessage() );
+ }
+
+ return buffer.toString();
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/LifecycleExecutor.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/LifecycleExecutor.java
new file mode 100644
index 00000000..04c602cf
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/LifecycleExecutor.java
@@ -0,0 +1,89 @@
+package org.apache.maven.lifecycle;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.model.Plugin;
+import org.apache.maven.plugin.InvalidPluginDescriptorException;
+import org.apache.maven.plugin.MojoExecution;
+import org.apache.maven.plugin.MojoNotFoundException;
+import org.apache.maven.plugin.PluginDescriptorParsingException;
+import org.apache.maven.plugin.PluginManagerException;
+import org.apache.maven.plugin.PluginNotFoundException;
+import org.apache.maven.plugin.PluginResolutionException;
+import org.apache.maven.plugin.prefix.NoPluginFoundForPrefixException;
+import org.apache.maven.plugin.version.PluginVersionResolutionException;
+import org.apache.maven.project.MavenProject;
+
+import java.util.List;
+import java.util.Set;
+
+/**
+ * A facade that provides lifecycle services to components outside Maven core.
+ *
+ * @author Jason van Zyl
+ */
+public interface LifecycleExecutor
+{
+
+ // USED BY MAVEN HELP PLUGIN
+ @Deprecated
+ String ROLE = LifecycleExecutor.class.getName();
+
+ // For a given project packaging find all the plugins that are bound to any registered
+ // lifecycles. The project builder needs to now what default plugin information needs to be
+ // merged into POM being built. Once the POM builder has this plugin information, versions can be assigned
+ // by the POM builder because they will have to be defined in plugin management. Once this is setComplete then it
+ // can be passed back so that the default configuration information can be populated.
+ //
+ // We need to know the specific version so that we can lookup the right version of the plugin descriptor
+ // which tells us what the default configuration is.
+ //
+
+ /**
+ * @return The plugins bound to the lifecycles of the specified packaging or {@code null} if the packaging is
+ * unknown.
+ */
+ Set<Plugin> getPluginsBoundByDefaultToAllLifecycles( String packaging );
+
+ MavenExecutionPlan calculateExecutionPlan( MavenSession session, String... tasks )
+ throws PluginNotFoundException, PluginResolutionException, PluginDescriptorParsingException,
+ MojoNotFoundException, NoPluginFoundForPrefixException, InvalidPluginDescriptorException,
+ PluginManagerException, LifecyclePhaseNotFoundException, LifecycleNotFoundException,
+ PluginVersionResolutionException;
+
+ MavenExecutionPlan calculateExecutionPlan( MavenSession session, boolean setup, String... tasks )
+ throws PluginNotFoundException, PluginResolutionException, PluginDescriptorParsingException,
+ MojoNotFoundException, NoPluginFoundForPrefixException, InvalidPluginDescriptorException,
+ PluginManagerException, LifecyclePhaseNotFoundException, LifecycleNotFoundException,
+ PluginVersionResolutionException;
+
+ void execute( MavenSession session );
+
+ // used by the site plugin 3.x
+ void calculateForkedExecutions( MojoExecution mojoExecution, MavenSession session )
+ throws MojoNotFoundException, PluginNotFoundException, PluginResolutionException,
+ PluginDescriptorParsingException, NoPluginFoundForPrefixException, InvalidPluginDescriptorException,
+ LifecyclePhaseNotFoundException, LifecycleNotFoundException, PluginVersionResolutionException;
+
+ // used by the site plugin 3.x
+ List<MavenProject> executeForkedExecutions( MojoExecution mojoExecution, MavenSession session )
+ throws LifecycleExecutionException;
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/LifecycleMappingDelegate.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/LifecycleMappingDelegate.java
new file mode 100644
index 00000000..f0701987
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/LifecycleMappingDelegate.java
@@ -0,0 +1,52 @@
+package org.apache.maven.lifecycle;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.List;
+import java.util.Map;
+
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.plugin.InvalidPluginDescriptorException;
+import org.apache.maven.plugin.MojoExecution;
+import org.apache.maven.plugin.MojoNotFoundException;
+import org.apache.maven.plugin.PluginDescriptorParsingException;
+import org.apache.maven.plugin.PluginNotFoundException;
+import org.apache.maven.plugin.PluginResolutionException;
+import org.apache.maven.project.MavenProject;
+
+/**
+ * Lifecycle mapping delegate component interface. Calculates project build execution plan given {@link Lifecycle} and
+ * lifecycle phase. Standard lifecycles use plugin execution {@code <phase>} or mojo default lifecycle phase to
+ * calculate the execution plan, but custom lifecycles can use alternative mapping strategies.
+ * <p>
+ * Implementations of this interface must be annotated with either {@code @Named("lifecycle-id")} or equivalent plexus
+ * {@code @Component} annotations.
+ *
+ * @since 3.2.0
+ * @see org.apache.maven.lifecycle.internal.DefaultLifecycleMappingDelegate
+ * @author ifedorenko
+ */
+public interface LifecycleMappingDelegate
+{
+ Map<String, List<MojoExecution>> calculateLifecycleMappings( MavenSession session, MavenProject project,
+ Lifecycle lifecycle, String lifecyclePhase )
+ throws PluginNotFoundException, PluginResolutionException, PluginDescriptorParsingException,
+ MojoNotFoundException, InvalidPluginDescriptorException;
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/LifecycleNotFoundException.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/LifecycleNotFoundException.java
new file mode 100644
index 00000000..e9ff0c20
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/LifecycleNotFoundException.java
@@ -0,0 +1,54 @@
+package org.apache.maven.lifecycle;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Signals a failure to locate a lifecycle.
+ *
+ * @author Benjamin Bentmann
+ */
+public class LifecycleNotFoundException
+ extends Exception
+{
+
+ private final String lifecycleId;
+
+ /**
+ * Creates a new exception to indicate that the specified lifecycle is unknown.
+ *
+ * @param lifecycleId The identifier of the lifecycle that could not be located, may be {@code null}.
+ */
+ public LifecycleNotFoundException( String lifecycleId )
+ {
+ super( "Unknown lifecycle " + lifecycleId );
+ this.lifecycleId = ( lifecycleId != null ) ? lifecycleId : "";
+ }
+
+ /**
+ * Gets the identifier of the lifecycle that was not found.
+ *
+ * @return The identifier of the lifecycle that was not found, never {@code null}.
+ */
+ public String getLifecycleId()
+ {
+ return lifecycleId;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/LifecyclePhaseNotFoundException.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/LifecyclePhaseNotFoundException.java
new file mode 100644
index 00000000..fab1d2f2
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/LifecyclePhaseNotFoundException.java
@@ -0,0 +1,55 @@
+package org.apache.maven.lifecycle;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Signals a failure to locate the lifecycle for some phase.
+ *
+ * @author Benjamin Bentmann
+ */
+public class LifecyclePhaseNotFoundException
+ extends Exception
+{
+
+ private final String lifecyclePhase;
+
+ /**
+ * Creates a new exception to indicate that the specified lifecycle phase is not defined by any known lifecycle.
+ *
+ * @param message The detail message, may be {@code null}.
+ * @param lifecyclePhase The name of the lifecycle phase that could not be located, may be {@code null}.
+ */
+ public LifecyclePhaseNotFoundException( String message, String lifecyclePhase )
+ {
+ super( message );
+ this.lifecyclePhase = ( lifecyclePhase != null ) ? lifecyclePhase : "";
+ }
+
+ /**
+ * Gets the lifecycle phase that was not found.
+ *
+ * @return The lifecycle phase that was not found, never {@code null}.
+ */
+ public String getLifecyclePhase()
+ {
+ return lifecyclePhase;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/MavenExecutionPlan.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/MavenExecutionPlan.java
new file mode 100644
index 00000000..7767ea25
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/MavenExecutionPlan.java
@@ -0,0 +1,202 @@
+package org.apache.maven.lifecycle;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.maven.lifecycle.internal.ExecutionPlanItem;
+import org.apache.maven.model.Plugin;
+import org.apache.maven.plugin.MojoExecution;
+import org.apache.maven.plugin.descriptor.MojoDescriptor;
+
+//TODO: lifecycles being executed
+//TODO: what runs in each phase
+//TODO: plugins that need downloading
+//TODO: project dependencies that need downloading
+//TODO: unfortunately the plugins need to be downloaded in order to get the plugin.xml file. need to externalize this
+// from the plugin archive.
+//TODO: this will be the class that people get in IDEs to modify
+
+public class MavenExecutionPlan
+ implements Iterable<ExecutionPlanItem>
+{
+
+ /*
+ At the moment, this class is totally immutable, and this is in line with thoughts about the
+ pre-calculated execution plan that stays the same during the execution.
+
+ If deciding to add mutable state to this class, it should be at least considered to
+ separate this into a separate mutable structure.
+
+ */
+
+ private final List<ExecutionPlanItem> planItem;
+
+ private final Map<String, ExecutionPlanItem> lastMojoExecutionForAllPhases;
+
+ final List<String> phasesInExecutionPlan;
+
+ public MavenExecutionPlan( List<ExecutionPlanItem> planItem, DefaultLifecycles defaultLifecycles )
+ {
+ this.planItem = planItem;
+
+ lastMojoExecutionForAllPhases = new LinkedHashMap<String, ExecutionPlanItem>();
+
+ LinkedHashSet<String> totalPhaseSet = new LinkedHashSet<String>();
+ if ( defaultLifecycles != null )
+ {
+ for ( String phase : getDistinctPhasesInOrderOfExecutionPlanAppearance( planItem ) )
+ {
+ final Lifecycle lifecycle = defaultLifecycles.get( phase );
+ if ( lifecycle != null )
+ {
+ totalPhaseSet.addAll( lifecycle.getPhases() );
+ }
+ }
+ }
+ this.phasesInExecutionPlan = new ArrayList<String>( totalPhaseSet );
+
+ Map<String, ExecutionPlanItem> lastInExistingPhases = new HashMap<String, ExecutionPlanItem>();
+ for ( ExecutionPlanItem executionPlanItem : getExecutionPlanItems() )
+ {
+ lastInExistingPhases.put( executionPlanItem.getLifecyclePhase(), executionPlanItem );
+ }
+
+ ExecutionPlanItem lastSeenExecutionPlanItem = null;
+
+ for ( String phase : totalPhaseSet )
+ {
+ ExecutionPlanItem forThisPhase = lastInExistingPhases.get( phase );
+ if ( forThisPhase != null )
+ {
+ lastSeenExecutionPlanItem = forThisPhase;
+ }
+
+ lastMojoExecutionForAllPhases.put( phase, lastSeenExecutionPlanItem );
+ }
+ }
+
+ public Iterator<ExecutionPlanItem> iterator()
+ {
+ return getExecutionPlanItems().iterator();
+ }
+
+ /**
+ * Returns the last ExecutionPlanItem in the supplied phase. If no items are in the specified phase,
+ * the closest executionPlanItem from an earlier phase item will be returned.
+ *
+ * @param requestedPhase the requested phase
+ * The execution plan item
+ * @return The ExecutionPlanItem or null if none can be found
+ */
+ public ExecutionPlanItem findLastInPhase( String requestedPhase )
+ {
+ return lastMojoExecutionForAllPhases.get( requestedPhase );
+ }
+
+ private List<ExecutionPlanItem> getExecutionPlanItems()
+ {
+ return planItem;
+ }
+
+ private static Iterable<String> getDistinctPhasesInOrderOfExecutionPlanAppearance(
+ List<ExecutionPlanItem> planItems )
+ {
+ LinkedHashSet<String> result = new LinkedHashSet<String>();
+ for ( ExecutionPlanItem executionPlanItem : planItems )
+ {
+ final String phase = executionPlanItem.getLifecyclePhase();
+ if ( !result.contains( phase ) )
+ {
+ result.add( phase );
+ }
+ }
+ return result;
+ }
+
+ public List<MojoExecution> getMojoExecutions()
+ {
+ List<MojoExecution> result = new ArrayList<MojoExecution>();
+ for ( ExecutionPlanItem executionPlanItem : planItem )
+ {
+ result.add( executionPlanItem.getMojoExecution() );
+ }
+ return result;
+ }
+
+ /**
+ * Get set of plugins having a goal/mojo used but not marked @threadSafe
+ *
+ * @return the set of plugins (without info on which goal is concerned)
+ */
+ public Set<Plugin> getNonThreadSafePlugins()
+ {
+ Set<Plugin> plugins = new HashSet<Plugin>();
+ for ( ExecutionPlanItem executionPlanItem : planItem )
+ {
+ final MojoExecution mojoExecution = executionPlanItem.getMojoExecution();
+ if ( !mojoExecution.getMojoDescriptor().isThreadSafe() )
+ {
+ plugins.add( mojoExecution.getPlugin() );
+ }
+ }
+ return plugins;
+ }
+
+ /**
+ * Get set of mojos used but not marked @threadSafe
+ *
+ * @return the set of mojo descriptors
+ */
+ public Set<MojoDescriptor> getNonThreadSafeMojos()
+ {
+ Set<MojoDescriptor> mojos = new HashSet<MojoDescriptor>();
+ for ( ExecutionPlanItem executionPlanItem : planItem )
+ {
+ final MojoExecution mojoExecution = executionPlanItem.getMojoExecution();
+ if ( !mojoExecution.getMojoDescriptor().isThreadSafe() )
+ {
+ mojos.add( mojoExecution.getMojoDescriptor() );
+ }
+ }
+ return mojos;
+ }
+
+ // Used by m2e but will be removed, really.
+ @Deprecated
+ public List<MojoExecution> getExecutions()
+ {
+ return getMojoExecutions();
+ }
+
+ public int size()
+ {
+ return planItem.size();
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/MissingProjectException.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/MissingProjectException.java
new file mode 100644
index 00000000..571e1d2b
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/MissingProjectException.java
@@ -0,0 +1,41 @@
+package org.apache.maven.lifecycle;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Signals a failure to execute a lifecycle phase or mojo because a project is required but not present.
+ *
+ * @author Benjamin Bentmann
+ */
+public class MissingProjectException
+ extends Exception
+{
+
+ /**
+ * Creates a new exception.
+ *
+ * @param message The detail message, may be {@code null}.
+ */
+ public MissingProjectException( String message )
+ {
+ super( message );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/MojoExecutionConfigurator.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/MojoExecutionConfigurator.java
new file mode 100644
index 00000000..b85bac77
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/MojoExecutionConfigurator.java
@@ -0,0 +1,44 @@
+package org.apache.maven.lifecycle;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.plugin.MojoExecution;
+import org.apache.maven.project.MavenProject;
+
+/**
+ * A MojoExecutionConfigurator is responsible for creating the configuration for Mojo based on configuration for a Mojo
+ * in the MavenProject and the default configuration for the Mojo from the containing plugin's plugin.xml descriptor.
+ *
+ * @provisional
+ * @author Jason van Zyl
+ * @since 3.3.1, MNG-5753
+ */
+public interface MojoExecutionConfigurator
+{
+ /**
+ * Create the MojoExecution configuration based on configuration for a Mojo in the MavenProject and the
+ * default configuration for the Mojo from the containing plugin's plugin.xml descriptor.
+ *
+ * @param project
+ * @param mojoExecution
+ * @param allowPluginLevelConfig
+ */
+ void configure( MavenProject project, MojoExecution mojoExecution, boolean allowPluginLevelConfig );
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/NoGoalSpecifiedException.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/NoGoalSpecifiedException.java
new file mode 100644
index 00000000..2ac9638a
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/NoGoalSpecifiedException.java
@@ -0,0 +1,41 @@
+package org.apache.maven.lifecycle;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Signals a failure to build because no goal was specified.
+ *
+ * @author Benjamin Bentmann
+ */
+public class NoGoalSpecifiedException
+ extends Exception
+{
+
+ /**
+ * Creates a new exception.
+ *
+ * @param message The detail message, may be {@code null}.
+ */
+ public NoGoalSpecifiedException( String message )
+ {
+ super( message );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/BuildListCalculator.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/BuildListCalculator.java
new file mode 100644
index 00000000..771385cc
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/BuildListCalculator.java
@@ -0,0 +1,67 @@
+package org.apache.maven.lifecycle.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.lifecycle.internal.builder.BuilderCommon;
+import org.apache.maven.project.MavenProject;
+import org.codehaus.plexus.component.annotations.Component;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * @since 3.0
+ * @author Kristian Rosenvold
+ * This class is not part of any public api and can be changed or deleted without prior notice.
+ */
+@Component( role = BuildListCalculator.class )
+public class BuildListCalculator
+{
+ public ProjectBuildList calculateProjectBuilds( MavenSession session, List<TaskSegment> taskSegments )
+ {
+ List<ProjectSegment> projectBuilds = new ArrayList<ProjectSegment>();
+
+ MavenProject rootProject = session.getTopLevelProject();
+
+ for ( TaskSegment taskSegment : taskSegments )
+ {
+ List<MavenProject> projects;
+
+ if ( taskSegment.isAggregating() )
+ {
+ projects = Collections.singletonList( rootProject );
+ }
+ else
+ {
+ projects = session.getProjects();
+ }
+ for ( MavenProject project : projects )
+ {
+ BuilderCommon.attachToThread( project ); // Not totally sure if this is needed for anything
+ MavenSession copiedSession = session.clone();
+ copiedSession.setCurrentProject( project );
+ projectBuilds.add( new ProjectSegment( project, taskSegment, copiedSession ) );
+ }
+ }
+ return new ProjectBuildList( projectBuilds );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/BuildThreadFactory.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/BuildThreadFactory.java
new file mode 100644
index 00000000..01545078
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/BuildThreadFactory.java
@@ -0,0 +1,39 @@
+package org.apache.maven.lifecycle.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * Simple {@link ThreadFactory} implementation that ensures the corresponding threads have a meaningful name.
+ */
+public class BuildThreadFactory
+ implements ThreadFactory
+{
+ private final AtomicInteger id = new AtomicInteger();
+
+ private static final String PREFIX = "BuilderThread";
+
+ public Thread newThread( Runnable r )
+ {
+ return new Thread( r, String.format( "%s %d", PREFIX, id.getAndIncrement() ) );
+ }
+} \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/CompoundProjectExecutionListener.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/CompoundProjectExecutionListener.java
new file mode 100644
index 00000000..f2a8291a
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/CompoundProjectExecutionListener.java
@@ -0,0 +1,72 @@
+package org.apache.maven.lifecycle.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Collection;
+
+import org.apache.maven.execution.ProjectExecutionEvent;
+import org.apache.maven.execution.ProjectExecutionListener;
+import org.apache.maven.lifecycle.LifecycleExecutionException;
+
+class CompoundProjectExecutionListener
+ implements ProjectExecutionListener
+{
+ private final Collection<ProjectExecutionListener> listeners;
+
+ public CompoundProjectExecutionListener( Collection<ProjectExecutionListener> listeners )
+ {
+ this.listeners = listeners; // NB this is live injected collection
+ }
+
+ public void beforeProjectExecution( ProjectExecutionEvent event )
+ throws LifecycleExecutionException
+ {
+ for ( ProjectExecutionListener listener : listeners )
+ {
+ listener.beforeProjectExecution( event );
+ }
+ }
+
+ public void beforeProjectLifecycleExecution( ProjectExecutionEvent event )
+ throws LifecycleExecutionException
+ {
+ for ( ProjectExecutionListener listener : listeners )
+ {
+ listener.beforeProjectLifecycleExecution( event );
+ }
+ }
+
+ public void afterProjectExecutionSuccess( ProjectExecutionEvent event )
+ throws LifecycleExecutionException
+ {
+ for ( ProjectExecutionListener listener : listeners )
+ {
+ listener.afterProjectExecutionSuccess( event );
+ }
+ }
+
+ public void afterProjectExecutionFailure( ProjectExecutionEvent event )
+ {
+ for ( ProjectExecutionListener listener : listeners )
+ {
+ listener.afterProjectExecutionFailure( event );
+ }
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DefaultExecutionEvent.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DefaultExecutionEvent.java
new file mode 100644
index 00000000..9434a659
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DefaultExecutionEvent.java
@@ -0,0 +1,77 @@
+package org.apache.maven.lifecycle.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.execution.ExecutionEvent;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.plugin.MojoExecution;
+import org.apache.maven.project.MavenProject;
+
+/**
+ * Holds data relevant for an execution event.
+ *
+ * @author Benjamin Bentmann
+ */
+class DefaultExecutionEvent
+ implements ExecutionEvent
+{
+
+ private final Type type;
+
+ private final MavenSession session;
+
+ private final MojoExecution mojoExecution;
+
+ private final Exception exception;
+
+ public DefaultExecutionEvent( Type type, MavenSession session, MojoExecution mojoExecution, Exception exception )
+ {
+ this.type = type;
+ this.session = session;
+ this.mojoExecution = mojoExecution;
+ this.exception = exception;
+ }
+
+ public Type getType()
+ {
+ return type;
+ }
+
+ public MavenSession getSession()
+ {
+ return session;
+ }
+
+ public MavenProject getProject()
+ {
+ return session.getCurrentProject();
+ }
+
+ public MojoExecution getMojoExecution()
+ {
+ return mojoExecution;
+ }
+
+ public Exception getException()
+ {
+ return exception;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DefaultExecutionEventCatapult.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DefaultExecutionEventCatapult.java
new file mode 100644
index 00000000..bfb98d43
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DefaultExecutionEventCatapult.java
@@ -0,0 +1,119 @@
+package org.apache.maven.lifecycle.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.execution.ExecutionEvent;
+import org.apache.maven.execution.ExecutionListener;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.plugin.MojoExecution;
+import org.codehaus.plexus.component.annotations.Component;
+
+/**
+ * Assists in firing execution events. <strong>Warning:</strong> This is an internal utility class that is only public
+ * for technical reasons, it is not part of the public API. In particular, this class can be changed or deleted without
+ * prior notice.
+ *
+ * @author Benjamin Bentmann
+ */
+@Component( role = ExecutionEventCatapult.class )
+public class DefaultExecutionEventCatapult
+ implements ExecutionEventCatapult
+{
+
+ public void fire( ExecutionEvent.Type eventType, MavenSession session, MojoExecution mojoExecution )
+ {
+ fire( eventType, session, mojoExecution, null );
+ }
+
+ public void fire( ExecutionEvent.Type eventType, MavenSession session, MojoExecution mojoExecution,
+ Exception exception )
+ {
+ ExecutionListener listener = session.getRequest().getExecutionListener();
+
+ if ( listener != null )
+ {
+ ExecutionEvent event = new DefaultExecutionEvent( eventType, session, mojoExecution, exception );
+
+ switch ( eventType )
+ {
+ case ProjectDiscoveryStarted:
+ listener.projectDiscoveryStarted( event );
+ break;
+
+ case SessionStarted:
+ listener.sessionStarted( event );
+ break;
+ case SessionEnded:
+ listener.sessionEnded( event );
+ break;
+
+ case ProjectSkipped:
+ listener.projectSkipped( event );
+ break;
+ case ProjectStarted:
+ listener.projectStarted( event );
+ break;
+ case ProjectSucceeded:
+ listener.projectSucceeded( event );
+ break;
+ case ProjectFailed:
+ listener.projectFailed( event );
+ break;
+
+ case MojoSkipped:
+ listener.mojoSkipped( event );
+ break;
+ case MojoStarted:
+ listener.mojoStarted( event );
+ break;
+ case MojoSucceeded:
+ listener.mojoSucceeded( event );
+ break;
+ case MojoFailed:
+ listener.mojoFailed( event );
+ break;
+
+ case ForkStarted:
+ listener.forkStarted( event );
+ break;
+ case ForkSucceeded:
+ listener.forkSucceeded( event );
+ break;
+ case ForkFailed:
+ listener.forkFailed( event );
+ break;
+
+ case ForkedProjectStarted:
+ listener.forkedProjectStarted( event );
+ break;
+ case ForkedProjectSucceeded:
+ listener.forkedProjectSucceeded( event );
+ break;
+ case ForkedProjectFailed:
+ listener.forkedProjectFailed( event );
+ break;
+
+ default:
+ throw new IllegalStateException( "Unknown execution event type " + eventType );
+ }
+ }
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DefaultLifecycleExecutionPlanCalculator.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DefaultLifecycleExecutionPlanCalculator.java
new file mode 100644
index 00000000..8cc47cc5
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DefaultLifecycleExecutionPlanCalculator.java
@@ -0,0 +1,591 @@
+package org.apache.maven.lifecycle.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.lifecycle.DefaultLifecycles;
+import org.apache.maven.lifecycle.Lifecycle;
+import org.apache.maven.lifecycle.LifecycleMappingDelegate;
+import org.apache.maven.lifecycle.LifecycleNotFoundException;
+import org.apache.maven.lifecycle.LifecyclePhaseNotFoundException;
+import org.apache.maven.lifecycle.MavenExecutionPlan;
+import org.apache.maven.lifecycle.MojoExecutionConfigurator;
+import org.apache.maven.lifecycle.internal.builder.BuilderCommon;
+import org.apache.maven.plugin.BuildPluginManager;
+import org.apache.maven.plugin.InvalidPluginDescriptorException;
+import org.apache.maven.plugin.MojoExecution;
+import org.apache.maven.plugin.MojoNotFoundException;
+import org.apache.maven.plugin.PluginDescriptorParsingException;
+import org.apache.maven.plugin.PluginNotFoundException;
+import org.apache.maven.plugin.PluginResolutionException;
+import org.apache.maven.plugin.descriptor.MojoDescriptor;
+import org.apache.maven.plugin.descriptor.Parameter;
+import org.apache.maven.plugin.descriptor.PluginDescriptor;
+import org.apache.maven.plugin.lifecycle.Execution;
+import org.apache.maven.plugin.lifecycle.Phase;
+import org.apache.maven.plugin.prefix.NoPluginFoundForPrefixException;
+import org.apache.maven.plugin.version.PluginVersionResolutionException;
+import org.apache.maven.plugin.version.PluginVersionResolver;
+import org.apache.maven.project.MavenProject;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+import org.codehaus.plexus.util.StringUtils;
+import org.codehaus.plexus.util.xml.Xpp3Dom;
+import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
+
+import com.google.common.collect.ImmutableMap;
+
+/**
+ * @since 3.0
+ * @author Benjamin Bentmann
+ * @author Kristian Rosenvold (Extract class)
+ * <p/>
+ * NOTE: This class is not part of any public api and can be changed or deleted without prior notice.
+ */
+@Component( role = LifecycleExecutionPlanCalculator.class )
+public class DefaultLifecycleExecutionPlanCalculator
+ implements LifecycleExecutionPlanCalculator
+{
+ @Requirement
+ private PluginVersionResolver pluginVersionResolver;
+
+ @Requirement
+ private BuildPluginManager pluginManager;
+
+ @Requirement
+ private DefaultLifecycles defaultLifeCycles;
+
+ @Requirement
+ private MojoDescriptorCreator mojoDescriptorCreator;
+
+ @Requirement
+ private LifecyclePluginResolver lifecyclePluginResolver;
+
+ @Requirement( hint = DefaultLifecycleMappingDelegate.HINT )
+ private LifecycleMappingDelegate standardDelegate;
+
+ @Requirement
+ private Map<String, LifecycleMappingDelegate> delegates;
+
+ @Requirement
+ private Map<String, MojoExecutionConfigurator> mojoExecutionConfigurators;
+
+ @SuppressWarnings( { "UnusedDeclaration" } )
+ public DefaultLifecycleExecutionPlanCalculator()
+ {
+ }
+
+ // Only used for testing
+ public DefaultLifecycleExecutionPlanCalculator( BuildPluginManager pluginManager,
+ DefaultLifecycles defaultLifeCycles,
+ MojoDescriptorCreator mojoDescriptorCreator,
+ LifecyclePluginResolver lifecyclePluginResolver )
+ {
+ this.pluginManager = pluginManager;
+ this.defaultLifeCycles = defaultLifeCycles;
+ this.mojoDescriptorCreator = mojoDescriptorCreator;
+ this.lifecyclePluginResolver = lifecyclePluginResolver;
+ this.mojoExecutionConfigurators =
+ ImmutableMap.of( "default", (MojoExecutionConfigurator) new DefaultMojoExecutionConfigurator() );
+ }
+
+ @Override
+ public MavenExecutionPlan calculateExecutionPlan( MavenSession session, MavenProject project, List<Object> tasks,
+ boolean setup )
+ throws PluginNotFoundException, PluginResolutionException, LifecyclePhaseNotFoundException,
+ PluginDescriptorParsingException, MojoNotFoundException, InvalidPluginDescriptorException,
+ NoPluginFoundForPrefixException, LifecycleNotFoundException, PluginVersionResolutionException
+ {
+ lifecyclePluginResolver.resolveMissingPluginVersions( project, session );
+
+ final List<MojoExecution> executions = calculateMojoExecutions( session, project, tasks );
+
+ if ( setup )
+ {
+ setupMojoExecutions( session, project, executions );
+ }
+
+ final List<ExecutionPlanItem> planItem = ExecutionPlanItem.createExecutionPlanItems( project, executions );
+
+ return new MavenExecutionPlan( planItem, defaultLifeCycles );
+ }
+
+ @Override
+ public MavenExecutionPlan calculateExecutionPlan( MavenSession session, MavenProject project, List<Object> tasks )
+ throws PluginNotFoundException, PluginResolutionException, LifecyclePhaseNotFoundException,
+ PluginDescriptorParsingException, MojoNotFoundException, InvalidPluginDescriptorException,
+ NoPluginFoundForPrefixException, LifecycleNotFoundException, PluginVersionResolutionException
+ {
+ return calculateExecutionPlan( session, project, tasks, true );
+ }
+
+ private void setupMojoExecutions( MavenSession session, MavenProject project, List<MojoExecution> mojoExecutions )
+ throws PluginNotFoundException, PluginResolutionException, PluginDescriptorParsingException,
+ MojoNotFoundException, InvalidPluginDescriptorException, NoPluginFoundForPrefixException,
+ LifecyclePhaseNotFoundException, LifecycleNotFoundException, PluginVersionResolutionException
+ {
+ for ( MojoExecution mojoExecution : mojoExecutions )
+ {
+ setupMojoExecution( session, project, mojoExecution );
+ }
+ }
+
+ @Override
+ public void setupMojoExecution( MavenSession session, MavenProject project, MojoExecution mojoExecution )
+ throws PluginNotFoundException, PluginResolutionException, PluginDescriptorParsingException,
+ MojoNotFoundException, InvalidPluginDescriptorException, NoPluginFoundForPrefixException,
+ LifecyclePhaseNotFoundException, LifecycleNotFoundException, PluginVersionResolutionException
+ {
+ MojoDescriptor mojoDescriptor = mojoExecution.getMojoDescriptor();
+
+ if ( mojoDescriptor == null )
+ {
+ mojoDescriptor =
+ pluginManager.getMojoDescriptor( mojoExecution.getPlugin(), mojoExecution.getGoal(),
+ project.getRemotePluginRepositories(),
+ session.getRepositorySession() );
+
+ mojoExecution.setMojoDescriptor( mojoDescriptor );
+ }
+
+ mojoExecutionConfigurator( mojoExecution ).configure( project,
+ mojoExecution,
+ MojoExecution.Source.CLI.equals( mojoExecution.getSource() ) );
+
+ finalizeMojoConfiguration( mojoExecution );
+
+ calculateForkedExecutions( mojoExecution, session, project, new HashSet<MojoDescriptor>() );
+ }
+
+ public List<MojoExecution> calculateMojoExecutions( MavenSession session, MavenProject project, List<Object> tasks )
+ throws PluginNotFoundException, PluginResolutionException, PluginDescriptorParsingException,
+ MojoNotFoundException, NoPluginFoundForPrefixException, InvalidPluginDescriptorException,
+ PluginVersionResolutionException, LifecyclePhaseNotFoundException
+ {
+ final List<MojoExecution> mojoExecutions = new ArrayList<MojoExecution>();
+
+ for ( Object task : tasks )
+ {
+ if ( task instanceof GoalTask )
+ {
+ String pluginGoal = ( (GoalTask) task ).pluginGoal;
+
+ String executionId = "default-cli";
+ int executionIdx = pluginGoal.indexOf( '@' );
+ if ( executionIdx > 0 )
+ {
+ executionId = pluginGoal.substring( executionIdx + 1 );
+ }
+
+ MojoDescriptor mojoDescriptor = mojoDescriptorCreator.getMojoDescriptor( pluginGoal, session, project );
+
+ MojoExecution mojoExecution = new MojoExecution( mojoDescriptor, executionId,
+ MojoExecution.Source.CLI );
+
+ mojoExecutions.add( mojoExecution );
+ }
+ else if ( task instanceof LifecycleTask )
+ {
+ String lifecyclePhase = ( (LifecycleTask) task ).getLifecyclePhase();
+
+ Map<String, List<MojoExecution>> phaseToMojoMapping =
+ calculateLifecycleMappings( session, project, lifecyclePhase );
+
+ for ( List<MojoExecution> mojoExecutionsFromLifecycle : phaseToMojoMapping.values() )
+ {
+ mojoExecutions.addAll( mojoExecutionsFromLifecycle );
+ }
+ }
+ else
+ {
+ throw new IllegalStateException( "unexpected task " + task );
+ }
+ }
+ return mojoExecutions;
+ }
+
+ private Map<String, List<MojoExecution>> calculateLifecycleMappings( MavenSession session, MavenProject project,
+ String lifecyclePhase )
+ throws LifecyclePhaseNotFoundException, PluginNotFoundException, PluginResolutionException,
+ PluginDescriptorParsingException, MojoNotFoundException, InvalidPluginDescriptorException
+ {
+ /*
+ * Determine the lifecycle that corresponds to the given phase.
+ */
+
+ Lifecycle lifecycle = defaultLifeCycles.get( lifecyclePhase );
+
+ if ( lifecycle == null )
+ {
+ throw new LifecyclePhaseNotFoundException( "Unknown lifecycle phase \"" + lifecyclePhase
+ + "\". You must specify a valid lifecycle phase" + " or a goal in the format <plugin-prefix>:<goal> or"
+ + " <plugin-group-id>:<plugin-artifact-id>[:<plugin-version>]:<goal>. Available lifecycle phases are: "
+ + defaultLifeCycles.getLifecyclePhaseList() + ".", lifecyclePhase );
+ }
+
+ LifecycleMappingDelegate delegate;
+ if ( Arrays.binarySearch( DefaultLifecycles.STANDARD_LIFECYCLES, lifecycle.getId() ) >= 0 )
+ {
+ delegate = standardDelegate;
+ }
+ else
+ {
+ delegate = delegates.get( lifecycle.getId() );
+ if ( delegate == null )
+ {
+ delegate = standardDelegate;
+ }
+ }
+
+ return delegate.calculateLifecycleMappings( session, project, lifecycle, lifecyclePhase );
+ }
+
+ /**
+ * Post-processes the effective configuration for the specified mojo execution. This step discards all parameters
+ * from the configuration that are not applicable to the mojo and injects the default values for any missing
+ * parameters.
+ *
+ * @param mojoExecution The mojo execution whose configuration should be finalized, must not be {@code null}.
+ */
+ private void finalizeMojoConfiguration( MojoExecution mojoExecution )
+ {
+ MojoDescriptor mojoDescriptor = mojoExecution.getMojoDescriptor();
+
+ Xpp3Dom executionConfiguration = mojoExecution.getConfiguration();
+ if ( executionConfiguration == null )
+ {
+ executionConfiguration = new Xpp3Dom( "configuration" );
+ }
+
+ Xpp3Dom defaultConfiguration = getMojoConfiguration( mojoDescriptor );
+
+ Xpp3Dom finalConfiguration = new Xpp3Dom( "configuration" );
+
+ if ( mojoDescriptor.getParameters() != null )
+ {
+ for ( Parameter parameter : mojoDescriptor.getParameters() )
+ {
+ Xpp3Dom parameterConfiguration = executionConfiguration.getChild( parameter.getName() );
+
+ if ( parameterConfiguration == null )
+ {
+ parameterConfiguration = executionConfiguration.getChild( parameter.getAlias() );
+ }
+
+ Xpp3Dom parameterDefaults = defaultConfiguration.getChild( parameter.getName() );
+
+ parameterConfiguration = Xpp3Dom.mergeXpp3Dom( parameterConfiguration, parameterDefaults,
+ Boolean.TRUE );
+
+ if ( parameterConfiguration != null )
+ {
+ parameterConfiguration = new Xpp3Dom( parameterConfiguration, parameter.getName() );
+
+ if ( StringUtils.isEmpty( parameterConfiguration.getAttribute( "implementation" ) )
+ && StringUtils.isNotEmpty( parameter.getImplementation() ) )
+ {
+ parameterConfiguration.setAttribute( "implementation", parameter.getImplementation() );
+ }
+
+ finalConfiguration.addChild( parameterConfiguration );
+ }
+ }
+ }
+
+ mojoExecution.setConfiguration( finalConfiguration );
+ }
+
+ private Xpp3Dom getMojoConfiguration( MojoDescriptor mojoDescriptor )
+ {
+ return MojoDescriptorCreator.convert( mojoDescriptor );
+ }
+
+ @Override
+ public void calculateForkedExecutions( MojoExecution mojoExecution, MavenSession session )
+ throws MojoNotFoundException, PluginNotFoundException, PluginResolutionException,
+ PluginDescriptorParsingException, NoPluginFoundForPrefixException, InvalidPluginDescriptorException,
+ LifecyclePhaseNotFoundException, LifecycleNotFoundException, PluginVersionResolutionException
+ {
+ calculateForkedExecutions( mojoExecution, session, session.getCurrentProject(), new HashSet<MojoDescriptor>() );
+ }
+
+ private void calculateForkedExecutions( MojoExecution mojoExecution, MavenSession session, MavenProject project,
+ Collection<MojoDescriptor> alreadyForkedExecutions )
+ throws MojoNotFoundException, PluginNotFoundException, PluginResolutionException,
+ PluginDescriptorParsingException, NoPluginFoundForPrefixException, InvalidPluginDescriptorException,
+ LifecyclePhaseNotFoundException, LifecycleNotFoundException, PluginVersionResolutionException
+ {
+ MojoDescriptor mojoDescriptor = mojoExecution.getMojoDescriptor();
+
+ if ( !mojoDescriptor.isForking() )
+ {
+ return;
+ }
+
+ if ( !alreadyForkedExecutions.add( mojoDescriptor ) )
+ {
+ return;
+ }
+
+ List<MavenProject> forkedProjects =
+ LifecycleDependencyResolver.getProjects( project, session, mojoDescriptor.isAggregator() );
+
+ for ( MavenProject forkedProject : forkedProjects )
+ {
+ if ( forkedProject != project )
+ {
+ lifecyclePluginResolver.resolveMissingPluginVersions( forkedProject, session );
+ }
+
+ List<MojoExecution> forkedExecutions;
+
+ if ( StringUtils.isNotEmpty( mojoDescriptor.getExecutePhase() ) )
+ {
+ forkedExecutions =
+ calculateForkedLifecycle( mojoExecution, session, forkedProject, alreadyForkedExecutions );
+ }
+ else
+ {
+ forkedExecutions = calculateForkedGoal( mojoExecution, session, forkedProject,
+ alreadyForkedExecutions );
+ }
+
+ mojoExecution.setForkedExecutions( BuilderCommon.getKey( forkedProject ), forkedExecutions );
+ }
+
+ alreadyForkedExecutions.remove( mojoDescriptor );
+ }
+
+ private List<MojoExecution> calculateForkedLifecycle( MojoExecution mojoExecution, MavenSession session,
+ MavenProject project,
+ Collection<MojoDescriptor> alreadyForkedExecutions )
+ throws MojoNotFoundException, PluginNotFoundException, PluginResolutionException,
+ PluginDescriptorParsingException, NoPluginFoundForPrefixException, InvalidPluginDescriptorException,
+ LifecyclePhaseNotFoundException, LifecycleNotFoundException, PluginVersionResolutionException
+ {
+ MojoDescriptor mojoDescriptor = mojoExecution.getMojoDescriptor();
+
+ String forkedPhase = mojoDescriptor.getExecutePhase();
+
+ Map<String, List<MojoExecution>> lifecycleMappings = calculateLifecycleMappings( session, project,
+ forkedPhase );
+
+ for ( List<MojoExecution> forkedExecutions : lifecycleMappings.values() )
+ {
+ for ( MojoExecution forkedExecution : forkedExecutions )
+ {
+ if ( forkedExecution.getMojoDescriptor() == null )
+ {
+ MojoDescriptor forkedMojoDescriptor =
+ pluginManager.getMojoDescriptor( forkedExecution.getPlugin(), forkedExecution.getGoal(),
+ project.getRemotePluginRepositories(),
+ session.getRepositorySession() );
+
+ forkedExecution.setMojoDescriptor( forkedMojoDescriptor );
+ }
+
+ mojoExecutionConfigurator( forkedExecution ).configure( project, forkedExecution, false );
+ }
+ }
+
+ injectLifecycleOverlay( lifecycleMappings, mojoExecution, session, project );
+
+ List<MojoExecution> mojoExecutions = new ArrayList<MojoExecution>();
+
+ for ( List<MojoExecution> forkedExecutions : lifecycleMappings.values() )
+ {
+ for ( MojoExecution forkedExecution : forkedExecutions )
+ {
+ if ( !alreadyForkedExecutions.contains( forkedExecution.getMojoDescriptor() ) )
+ {
+ finalizeMojoConfiguration( forkedExecution );
+
+ calculateForkedExecutions( forkedExecution, session, project, alreadyForkedExecutions );
+
+ mojoExecutions.add( forkedExecution );
+ }
+ }
+ }
+
+ return mojoExecutions;
+ }
+
+ private void injectLifecycleOverlay( Map<String, List<MojoExecution>> lifecycleMappings,
+ MojoExecution mojoExecution, MavenSession session, MavenProject project )
+ throws PluginDescriptorParsingException, LifecycleNotFoundException, MojoNotFoundException,
+ PluginNotFoundException, PluginResolutionException, NoPluginFoundForPrefixException,
+ InvalidPluginDescriptorException, PluginVersionResolutionException
+ {
+ MojoDescriptor mojoDescriptor = mojoExecution.getMojoDescriptor();
+
+ PluginDescriptor pluginDescriptor = mojoDescriptor.getPluginDescriptor();
+
+ String forkedLifecycle = mojoDescriptor.getExecuteLifecycle();
+
+ if ( StringUtils.isEmpty( forkedLifecycle ) )
+ {
+ return;
+ }
+
+ org.apache.maven.plugin.lifecycle.Lifecycle lifecycleOverlay;
+
+ try
+ {
+ lifecycleOverlay = pluginDescriptor.getLifecycleMapping( forkedLifecycle );
+ }
+ catch ( IOException e )
+ {
+ throw new PluginDescriptorParsingException( pluginDescriptor.getPlugin(), pluginDescriptor.getSource(), e );
+ }
+ catch ( XmlPullParserException e )
+ {
+ throw new PluginDescriptorParsingException( pluginDescriptor.getPlugin(), pluginDescriptor.getSource(), e );
+ }
+
+ if ( lifecycleOverlay == null )
+ {
+ throw new LifecycleNotFoundException( forkedLifecycle );
+ }
+
+ for ( Phase phase : lifecycleOverlay.getPhases() )
+ {
+ List<MojoExecution> forkedExecutions = lifecycleMappings.get( phase.getId() );
+
+ if ( forkedExecutions != null )
+ {
+ for ( Execution execution : phase.getExecutions() )
+ {
+ for ( String goal : execution.getGoals() )
+ {
+ MojoDescriptor forkedMojoDescriptor;
+
+ if ( goal.indexOf( ':' ) < 0 )
+ {
+ forkedMojoDescriptor = pluginDescriptor.getMojo( goal );
+ if ( forkedMojoDescriptor == null )
+ {
+ throw new MojoNotFoundException( goal, pluginDescriptor );
+ }
+ }
+ else
+ {
+ forkedMojoDescriptor = mojoDescriptorCreator.getMojoDescriptor( goal, session, project );
+ }
+
+ MojoExecution forkedExecution =
+ new MojoExecution( forkedMojoDescriptor, mojoExecution.getExecutionId() );
+
+ Xpp3Dom forkedConfiguration = (Xpp3Dom) execution.getConfiguration();
+
+ forkedExecution.setConfiguration( forkedConfiguration );
+
+ mojoExecutionConfigurator( forkedExecution ).configure( project, forkedExecution, true );
+
+ forkedExecutions.add( forkedExecution );
+ }
+ }
+
+ Xpp3Dom phaseConfiguration = (Xpp3Dom) phase.getConfiguration();
+
+ if ( phaseConfiguration != null )
+ {
+ for ( MojoExecution forkedExecution : forkedExecutions )
+ {
+ Xpp3Dom forkedConfiguration = forkedExecution.getConfiguration();
+
+ forkedConfiguration = Xpp3Dom.mergeXpp3Dom( phaseConfiguration, forkedConfiguration );
+
+ forkedExecution.setConfiguration( forkedConfiguration );
+ }
+ }
+ }
+ }
+ }
+
+ // org.apache.maven.plugins:maven-remote-resources-plugin:1.0:process
+ // TODO: take repo mans into account as one may be aggregating prefixes of many
+ // TODO: collect at the root of the repository, read the one at the root, and fetch remote if something is missing
+ // or the user forces the issue
+
+ private List<MojoExecution> calculateForkedGoal( MojoExecution mojoExecution, MavenSession session,
+ MavenProject project,
+ Collection<MojoDescriptor> alreadyForkedExecutions )
+ throws MojoNotFoundException, PluginNotFoundException, PluginResolutionException,
+ PluginDescriptorParsingException, NoPluginFoundForPrefixException, InvalidPluginDescriptorException,
+ LifecyclePhaseNotFoundException, LifecycleNotFoundException, PluginVersionResolutionException
+ {
+ MojoDescriptor mojoDescriptor = mojoExecution.getMojoDescriptor();
+
+ PluginDescriptor pluginDescriptor = mojoDescriptor.getPluginDescriptor();
+
+ String forkedGoal = mojoDescriptor.getExecuteGoal();
+
+ MojoDescriptor forkedMojoDescriptor = pluginDescriptor.getMojo( forkedGoal );
+ if ( forkedMojoDescriptor == null )
+ {
+ throw new MojoNotFoundException( forkedGoal, pluginDescriptor );
+ }
+
+ if ( alreadyForkedExecutions.contains( forkedMojoDescriptor ) )
+ {
+ return Collections.emptyList();
+ }
+
+ MojoExecution forkedExecution = new MojoExecution( forkedMojoDescriptor, forkedGoal );
+
+ mojoExecutionConfigurator( forkedExecution ).configure( project, forkedExecution, true );
+
+ finalizeMojoConfiguration( forkedExecution );
+
+ calculateForkedExecutions( forkedExecution, session, project, alreadyForkedExecutions );
+
+ return Collections.singletonList( forkedExecution );
+ }
+
+ private MojoExecutionConfigurator mojoExecutionConfigurator( MojoExecution mojoExecution )
+ {
+ String configuratorId = mojoExecution.getMojoDescriptor().getComponentConfigurator();
+ if ( configuratorId == null )
+ {
+ configuratorId = "default";
+ }
+
+ MojoExecutionConfigurator mojoExecutionConfigurator = mojoExecutionConfigurators.get( configuratorId );
+
+ if ( mojoExecutionConfigurator == null )
+ {
+ //
+ // The plugin has a custom component configurator but does not have a custom mojo execution configurator
+ // so fall back to the default mojo execution configurator.
+ //
+ mojoExecutionConfigurator = mojoExecutionConfigurators.get( "default" );
+ }
+ return mojoExecutionConfigurator;
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DefaultLifecycleMappingDelegate.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DefaultLifecycleMappingDelegate.java
new file mode 100644
index 00000000..3024fe45
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DefaultLifecycleMappingDelegate.java
@@ -0,0 +1,158 @@
+package org.apache.maven.lifecycle.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.lifecycle.Lifecycle;
+import org.apache.maven.lifecycle.LifecycleMappingDelegate;
+import org.apache.maven.model.Plugin;
+import org.apache.maven.model.PluginExecution;
+import org.apache.maven.plugin.BuildPluginManager;
+import org.apache.maven.plugin.InvalidPluginDescriptorException;
+import org.apache.maven.plugin.MojoExecution;
+import org.apache.maven.plugin.MojoNotFoundException;
+import org.apache.maven.plugin.PluginDescriptorParsingException;
+import org.apache.maven.plugin.PluginNotFoundException;
+import org.apache.maven.plugin.PluginResolutionException;
+import org.apache.maven.plugin.descriptor.MojoDescriptor;
+import org.apache.maven.project.MavenProject;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+
+@Component( role = LifecycleMappingDelegate.class, hint = DefaultLifecycleMappingDelegate.HINT )
+public class DefaultLifecycleMappingDelegate
+ implements LifecycleMappingDelegate
+{
+ public static final String HINT = "default";
+
+ @Requirement
+ private BuildPluginManager pluginManager;
+
+ public Map<String, List<MojoExecution>> calculateLifecycleMappings( MavenSession session, MavenProject project,
+ Lifecycle lifecycle, String lifecyclePhase )
+ throws PluginNotFoundException, PluginResolutionException, PluginDescriptorParsingException,
+ MojoNotFoundException, InvalidPluginDescriptorException
+ {
+ /*
+ * Initialize mapping from lifecycle phase to bound mojos. The key set of this map denotes the phases the caller
+ * is interested in, i.e. all phases up to and including the specified phase.
+ */
+
+ Map<String, Map<Integer, List<MojoExecution>>> mappings =
+ new LinkedHashMap<String, Map<Integer, List<MojoExecution>>>();
+
+ for ( String phase : lifecycle.getPhases() )
+ {
+ Map<Integer, List<MojoExecution>> phaseBindings = new TreeMap<Integer, List<MojoExecution>>();
+
+ mappings.put( phase, phaseBindings );
+
+ if ( phase.equals( lifecyclePhase ) )
+ {
+ break;
+ }
+ }
+
+ /*
+ * Grab plugin executions that are bound to the selected lifecycle phases from project. The effective model of
+ * the project already contains the plugin executions induced by the project's packaging type. Remember, all
+ * phases of interest and only those are in the lifecyle mapping, if a phase has no value in the map, we are not
+ * interested in any of the executions bound to it.
+ */
+
+ for ( Plugin plugin : project.getBuild().getPlugins() )
+ {
+ for ( PluginExecution execution : plugin.getExecutions() )
+ {
+ // if the phase is specified then I don't have to go fetch the plugin yet and pull it down
+ // to examine the phase it is associated to.
+ if ( execution.getPhase() != null )
+ {
+ Map<Integer, List<MojoExecution>> phaseBindings = mappings.get( execution.getPhase() );
+ if ( phaseBindings != null )
+ {
+ for ( String goal : execution.getGoals() )
+ {
+ MojoExecution mojoExecution = new MojoExecution( plugin, goal, execution.getId() );
+ mojoExecution.setLifecyclePhase( execution.getPhase() );
+ addMojoExecution( phaseBindings, mojoExecution, execution.getPriority() );
+ }
+ }
+ }
+ // if not then i need to grab the mojo descriptor and look at the phase that is specified
+ else
+ {
+ for ( String goal : execution.getGoals() )
+ {
+ MojoDescriptor mojoDescriptor =
+ pluginManager.getMojoDescriptor( plugin, goal, project.getRemotePluginRepositories(),
+ session.getRepositorySession() );
+
+ Map<Integer, List<MojoExecution>> phaseBindings = mappings.get( mojoDescriptor.getPhase() );
+ if ( phaseBindings != null )
+ {
+ MojoExecution mojoExecution = new MojoExecution( mojoDescriptor, execution.getId() );
+ mojoExecution.setLifecyclePhase( mojoDescriptor.getPhase() );
+ addMojoExecution( phaseBindings, mojoExecution, execution.getPriority() );
+ }
+ }
+ }
+ }
+ }
+
+ Map<String, List<MojoExecution>> lifecycleMappings = new LinkedHashMap<String, List<MojoExecution>>();
+
+ for ( Map.Entry<String, Map<Integer, List<MojoExecution>>> entry : mappings.entrySet() )
+ {
+ List<MojoExecution> mojoExecutions = new ArrayList<MojoExecution>();
+
+ for ( List<MojoExecution> executions : entry.getValue().values() )
+ {
+ mojoExecutions.addAll( executions );
+ }
+
+ lifecycleMappings.put( entry.getKey(), mojoExecutions );
+ }
+
+ return lifecycleMappings;
+
+ }
+
+ private void addMojoExecution( Map<Integer, List<MojoExecution>> phaseBindings, MojoExecution mojoExecution,
+ int priority )
+ {
+ List<MojoExecution> mojoExecutions = phaseBindings.get( priority );
+
+ if ( mojoExecutions == null )
+ {
+ mojoExecutions = new ArrayList<MojoExecution>();
+ phaseBindings.put( priority, mojoExecutions );
+ }
+
+ mojoExecutions.add( mojoExecution );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DefaultLifecyclePluginAnalyzer.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DefaultLifecyclePluginAnalyzer.java
new file mode 100644
index 00000000..a5e6a34c
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DefaultLifecyclePluginAnalyzer.java
@@ -0,0 +1,258 @@
+package org.apache.maven.lifecycle.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.lifecycle.DefaultLifecycles;
+import org.apache.maven.lifecycle.LifeCyclePluginAnalyzer;
+import org.apache.maven.lifecycle.Lifecycle;
+import org.apache.maven.lifecycle.mapping.LifecycleMapping;
+import org.apache.maven.model.Plugin;
+import org.apache.maven.model.PluginExecution;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+import org.codehaus.plexus.logging.Logger;
+import org.codehaus.plexus.util.StringUtils;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * @since 3.0
+ * @author Benjamin Bentmann
+ * @author Jason van Zyl
+ * @author jdcasey
+ * @author Kristian Rosenvold (extracted class only)
+ * <p/>
+ * NOTE: This class is not part of any public api and can be changed or deleted without prior notice.
+ */
+@Component( role = LifeCyclePluginAnalyzer.class )
+public class DefaultLifecyclePluginAnalyzer
+ implements LifeCyclePluginAnalyzer
+{
+
+ @Requirement( role = LifecycleMapping.class )
+ private Map<String, LifecycleMapping> lifecycleMappings;
+
+ @Requirement
+ private DefaultLifecycles defaultLifeCycles;
+
+ @Requirement
+ private Logger logger;
+
+ public DefaultLifecyclePluginAnalyzer()
+ {
+ }
+
+ // These methods deal with construction intact Plugin object that look like they come from a standard
+ // <plugin/> block in a Maven POM. We have to do some wiggling to pull the sources of information
+ // together and this really shows the problem of constructing a sensible default configuration but
+ // it's all encapsulated here so it appears normalized to the POM builder.
+
+ // We are going to take the project packaging and find all plugin in the default lifecycle and create
+ // fully populated Plugin objects, including executions with goals and default configuration taken
+ // from the plugin.xml inside a plugin.
+ //
+
+ public Set<Plugin> getPluginsBoundByDefaultToAllLifecycles( String packaging )
+ {
+ if ( logger.isDebugEnabled() )
+ {
+ logger.debug( "Looking up lifecyle mappings for packaging " + packaging + " from "
+ + Thread.currentThread().getContextClassLoader() );
+ }
+
+ LifecycleMapping lifecycleMappingForPackaging = lifecycleMappings.get( packaging );
+
+ if ( lifecycleMappingForPackaging == null )
+ {
+ return null;
+ }
+
+ Map<Plugin, Plugin> plugins = new LinkedHashMap<Plugin, Plugin>();
+
+ for ( Lifecycle lifecycle : getOrderedLifecycles() )
+ {
+ org.apache.maven.lifecycle.mapping.Lifecycle lifecycleConfiguration =
+ lifecycleMappingForPackaging.getLifecycles().get( lifecycle.getId() );
+
+ Map<String, String> phaseToGoalMapping = null;
+
+ if ( lifecycleConfiguration != null )
+ {
+ phaseToGoalMapping = lifecycleConfiguration.getPhases();
+ }
+ else if ( lifecycle.getDefaultPhases() != null )
+ {
+ phaseToGoalMapping = lifecycle.getDefaultPhases();
+ }
+
+ if ( phaseToGoalMapping != null )
+ {
+ // These are of the form:
+ //
+ // compile -> org.apache.maven.plugins:maven-compiler-plugin:compile[,gid:aid:goal,...]
+ //
+ for ( Map.Entry<String, String> goalsForLifecyclePhase : phaseToGoalMapping.entrySet() )
+ {
+ String phase = goalsForLifecyclePhase.getKey();
+ String goals = goalsForLifecyclePhase.getValue();
+ if ( goals != null )
+ {
+ parseLifecyclePhaseDefinitions( plugins, phase, goals );
+ }
+ }
+ }
+ }
+
+ return plugins.keySet();
+ }
+
+ private List<Lifecycle> getOrderedLifecycles()
+ {
+ // NOTE: The lifecycle order can affect implied execution ids so we better be deterministic.
+
+ List<Lifecycle> lifecycles = new ArrayList<Lifecycle>( defaultLifeCycles.getLifeCycles() );
+
+ Collections.sort( lifecycles, new Comparator<Lifecycle>()
+ {
+
+ public int compare( Lifecycle l1, Lifecycle l2 )
+ {
+ return l1.getId().compareTo( l2.getId() );
+ }
+
+ } );
+
+ return lifecycles;
+ }
+
+ private void parseLifecyclePhaseDefinitions( Map<Plugin, Plugin> plugins, String phase, String goals )
+ {
+ String[] mojos = StringUtils.split( goals, "," );
+
+ for ( int i = 0; i < mojos.length; i++ )
+ {
+ GoalSpec gs = parseGoalSpec( mojos[i].trim() );
+
+ if ( gs == null )
+ {
+ logger.warn( "Ignored invalid goal specification '" + mojos[i] + "' from lifecycle mapping for phase "
+ + phase );
+ continue;
+ }
+
+ Plugin plugin = new Plugin();
+ plugin.setGroupId( gs.groupId );
+ plugin.setArtifactId( gs.artifactId );
+ plugin.setVersion( gs.version );
+
+ Plugin existing = plugins.get( plugin );
+ if ( existing != null )
+ {
+ if ( existing.getVersion() == null )
+ {
+ existing.setVersion( plugin.getVersion() );
+ }
+ plugin = existing;
+ }
+ else
+ {
+ plugins.put( plugin, plugin );
+ }
+
+ PluginExecution execution = new PluginExecution();
+ execution.setId( getExecutionId( plugin, gs.goal ) );
+ execution.setPhase( phase );
+ execution.setPriority( i - mojos.length );
+ execution.getGoals().add( gs.goal );
+
+ plugin.getExecutions().add( execution );
+ }
+ }
+
+ private GoalSpec parseGoalSpec( String goalSpec )
+ {
+ GoalSpec gs = new GoalSpec();
+
+ String[] p = StringUtils.split( goalSpec.trim(), ":" );
+
+ if ( p.length == 3 )
+ {
+ // <groupId>:<artifactId>:<goal>
+ gs.groupId = p[0];
+ gs.artifactId = p[1];
+ gs.goal = p[2];
+ }
+ else if ( p.length == 4 )
+ {
+ // <groupId>:<artifactId>:<version>:<goal>
+ gs.groupId = p[0];
+ gs.artifactId = p[1];
+ gs.version = p[2];
+ gs.goal = p[3];
+ }
+ else
+ {
+ // invalid
+ gs = null;
+ }
+
+ return gs;
+ }
+
+ private String getExecutionId( Plugin plugin, String goal )
+ {
+ Set<String> existingIds = new HashSet<String>();
+ for ( PluginExecution execution : plugin.getExecutions() )
+ {
+ existingIds.add( execution.getId() );
+ }
+
+ String base = "default-" + goal;
+ String id = base;
+
+ for ( int index = 1; existingIds.contains( id ); index++ )
+ {
+ id = base + '-' + index;
+ }
+
+ return id;
+ }
+
+ static class GoalSpec
+ {
+
+ String groupId;
+
+ String artifactId;
+
+ String version;
+
+ String goal;
+
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DefaultLifecycleTaskSegmentCalculator.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DefaultLifecycleTaskSegmentCalculator.java
new file mode 100644
index 00000000..28377f1d
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DefaultLifecycleTaskSegmentCalculator.java
@@ -0,0 +1,155 @@
+package org.apache.maven.lifecycle.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.lifecycle.LifecycleNotFoundException;
+import org.apache.maven.lifecycle.LifecyclePhaseNotFoundException;
+import org.apache.maven.plugin.InvalidPluginDescriptorException;
+import org.apache.maven.plugin.MojoNotFoundException;
+import org.apache.maven.plugin.PluginDescriptorParsingException;
+import org.apache.maven.plugin.PluginNotFoundException;
+import org.apache.maven.plugin.PluginResolutionException;
+import org.apache.maven.plugin.descriptor.MojoDescriptor;
+import org.apache.maven.plugin.prefix.NoPluginFoundForPrefixException;
+import org.apache.maven.plugin.version.PluginVersionResolutionException;
+import org.apache.maven.project.MavenProject;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+import org.codehaus.plexus.util.StringUtils;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Calculates the task segments in the build
+ *
+ * @since 3.0
+ * @author Benjamin Bentmann
+ * @author Jason van Zyl
+ * @author jdcasey
+ * @author Kristian Rosenvold (extracted class)
+ * <p/>
+ * NOTE: This class is not part of any public api and can be changed or deleted without prior notice.
+ */
+
+@Component( role = LifecycleTaskSegmentCalculator.class )
+public class DefaultLifecycleTaskSegmentCalculator
+ implements LifecycleTaskSegmentCalculator
+{
+ @Requirement
+ private MojoDescriptorCreator mojoDescriptorCreator;
+
+ @Requirement
+ private LifecyclePluginResolver lifecyclePluginResolver;
+
+ public DefaultLifecycleTaskSegmentCalculator()
+ {
+ }
+
+ public List<TaskSegment> calculateTaskSegments( MavenSession session )
+ throws PluginNotFoundException, PluginResolutionException, PluginDescriptorParsingException,
+ MojoNotFoundException, NoPluginFoundForPrefixException, InvalidPluginDescriptorException,
+ PluginVersionResolutionException, LifecyclePhaseNotFoundException, LifecycleNotFoundException
+ {
+
+ MavenProject rootProject = session.getTopLevelProject();
+
+ List<String> tasks = session.getGoals();
+
+ if ( ( tasks == null || tasks.isEmpty() ) && !StringUtils.isEmpty( rootProject.getDefaultGoal() ) )
+ {
+ tasks = Arrays.asList( StringUtils.split( rootProject.getDefaultGoal() ) );
+ }
+
+ return calculateTaskSegments( session, tasks );
+ }
+
+ public List<TaskSegment> calculateTaskSegments( MavenSession session, List<String> tasks )
+ throws PluginNotFoundException, PluginResolutionException, PluginDescriptorParsingException,
+ MojoNotFoundException, NoPluginFoundForPrefixException, InvalidPluginDescriptorException,
+ PluginVersionResolutionException
+ {
+ List<TaskSegment> taskSegments = new ArrayList<TaskSegment>( tasks.size() );
+
+ TaskSegment currentSegment = null;
+
+ for ( String task : tasks )
+ {
+ if ( isGoalSpecification( task ) )
+ {
+ // "pluginPrefix:goal" or "groupId:artifactId[:version]:goal"
+
+ lifecyclePluginResolver.resolveMissingPluginVersions( session.getTopLevelProject(), session );
+
+ MojoDescriptor mojoDescriptor =
+ mojoDescriptorCreator.getMojoDescriptor( task, session, session.getTopLevelProject() );
+
+ boolean aggregating = mojoDescriptor.isAggregator() || !mojoDescriptor.isProjectRequired();
+
+ if ( currentSegment == null || currentSegment.isAggregating() != aggregating )
+ {
+ currentSegment = new TaskSegment( aggregating );
+ taskSegments.add( currentSegment );
+ }
+
+ currentSegment.getTasks().add( new GoalTask( task ) );
+ }
+ else
+ {
+ // lifecycle phase
+
+ if ( currentSegment == null || currentSegment.isAggregating() )
+ {
+ currentSegment = new TaskSegment( false );
+ taskSegments.add( currentSegment );
+ }
+
+ currentSegment.getTasks().add( new LifecycleTask( task ) );
+ }
+ }
+
+ return taskSegments;
+ }
+
+ public boolean requiresProject( MavenSession session )
+ {
+ List<String> goals = session.getGoals();
+ if ( goals != null )
+ {
+ for ( String goal : goals )
+ {
+ if ( !isGoalSpecification( goal ) )
+ {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+
+ private boolean isGoalSpecification( String task )
+ {
+ return task.indexOf( ':' ) >= 0;
+ }
+
+} \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DefaultMojoExecutionConfigurator.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DefaultMojoExecutionConfigurator.java
new file mode 100644
index 00000000..176ba320
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DefaultMojoExecutionConfigurator.java
@@ -0,0 +1,108 @@
+package org.apache.maven.lifecycle.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Collection;
+
+import org.apache.maven.lifecycle.MojoExecutionConfigurator;
+import org.apache.maven.model.Plugin;
+import org.apache.maven.model.PluginExecution;
+import org.apache.maven.plugin.MojoExecution;
+import org.apache.maven.project.MavenProject;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.util.StringUtils;
+import org.codehaus.plexus.util.xml.Xpp3Dom;
+
+/**
+ * @since 3.3.1, MNG-5753
+ */
+@Component( role = MojoExecutionConfigurator.class )
+public class DefaultMojoExecutionConfigurator
+ implements MojoExecutionConfigurator
+{
+
+ @Override
+ public void configure( MavenProject project, MojoExecution mojoExecution, boolean allowPluginLevelConfig )
+ {
+ String g = mojoExecution.getGroupId();
+
+ String a = mojoExecution.getArtifactId();
+
+ Plugin plugin = findPlugin( g, a, project.getBuildPlugins() );
+
+ if ( plugin == null && project.getPluginManagement() != null )
+ {
+ plugin = findPlugin( g, a, project.getPluginManagement().getPlugins() );
+ }
+
+ if ( plugin != null )
+ {
+ PluginExecution pluginExecution =
+ findPluginExecution( mojoExecution.getExecutionId(), plugin.getExecutions() );
+
+ Xpp3Dom pomConfiguration = null;
+
+ if ( pluginExecution != null )
+ {
+ pomConfiguration = (Xpp3Dom) pluginExecution.getConfiguration();
+ }
+ else if ( allowPluginLevelConfig )
+ {
+ pomConfiguration = (Xpp3Dom) plugin.getConfiguration();
+ }
+
+ Xpp3Dom mojoConfiguration = ( pomConfiguration != null ) ? new Xpp3Dom( pomConfiguration ) : null;
+
+ mojoConfiguration = Xpp3Dom.mergeXpp3Dom( mojoExecution.getConfiguration(), mojoConfiguration );
+
+ mojoExecution.setConfiguration( mojoConfiguration );
+ }
+ }
+
+ private Plugin findPlugin( String groupId, String artifactId, Collection<Plugin> plugins )
+ {
+ for ( Plugin plugin : plugins )
+ {
+ if ( artifactId.equals( plugin.getArtifactId() ) && groupId.equals( plugin.getGroupId() ) )
+ {
+ return plugin;
+ }
+ }
+
+ return null;
+ }
+
+ private PluginExecution findPluginExecution( String executionId, Collection<PluginExecution> executions )
+ {
+ if ( StringUtils.isNotEmpty( executionId ) )
+ {
+ for ( PluginExecution execution : executions )
+ {
+ if ( executionId.equals( execution.getId() ) )
+ {
+ return execution;
+ }
+ }
+ }
+
+ return null;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DefaultProjectArtifactFactory.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DefaultProjectArtifactFactory.java
new file mode 100644
index 00000000..762fc72b
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DefaultProjectArtifactFactory.java
@@ -0,0 +1,53 @@
+package org.apache.maven.lifecycle.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Set;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.factory.ArtifactFactory;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.project.artifact.InvalidDependencyVersionException;
+import org.apache.maven.project.artifact.MavenMetadataSource;
+
+@SuppressWarnings( "deprecation" )
+@Named
+public class DefaultProjectArtifactFactory
+ implements ProjectArtifactFactory
+{
+ private final ArtifactFactory artifactFactory;
+
+ @Inject
+ public DefaultProjectArtifactFactory( ArtifactFactory artifactFactory )
+ {
+ this.artifactFactory = artifactFactory;
+ }
+
+ @Override
+ public Set<Artifact> createArtifacts( MavenProject project )
+ throws InvalidDependencyVersionException
+ {
+ return MavenMetadataSource.createArtifacts( artifactFactory, project.getDependencies(), null, null, project );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DependencyContext.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DependencyContext.java
new file mode 100644
index 00000000..18fae7a9
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DependencyContext.java
@@ -0,0 +1,114 @@
+package org.apache.maven.lifecycle.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.project.MavenProject;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.TreeSet;
+
+/**
+ * Context of dependency artifacts for a particular project.
+ *
+ * @since 3.0
+ * @author Benjamin Bentmann
+ * @author Kristian Rosenvold (class extract only)
+ * <p/>
+ * NOTE: This class is not part of any public api and can be changed or deleted without prior notice.
+ */
+// TODO: From a concurrency perspective, this class is not good. The combination of mutable/immutable state is not nice
+public class DependencyContext
+{
+
+ private static final Collection<?> UNRESOLVED = Arrays.asList();
+
+ private final MavenProject project;
+
+ private final Collection<String> scopesToCollectForCurrentProject;
+
+ private final Collection<String> scopesToResolveForCurrentProject;
+
+ private final Collection<String> scopesToCollectForAggregatedProjects;
+
+ private final Collection<String> scopesToResolveForAggregatedProjects;
+
+ private volatile Collection<?> lastDependencyArtifacts = UNRESOLVED;
+
+ private volatile int lastDependencyArtifactCount = -1;
+
+ public DependencyContext( MavenProject project, Collection<String> scopesToCollect,
+ Collection<String> scopesToResolve )
+ {
+ this.project = project;
+ scopesToCollectForCurrentProject = scopesToCollect;
+ scopesToResolveForCurrentProject = scopesToResolve;
+ scopesToCollectForAggregatedProjects = Collections.synchronizedSet( new TreeSet<String>() );
+ scopesToResolveForAggregatedProjects = Collections.synchronizedSet( new TreeSet<String>() );
+ }
+
+ public MavenProject getProject()
+ {
+ return project;
+ }
+
+ public Collection<String> getScopesToCollectForCurrentProject()
+ {
+ return scopesToCollectForCurrentProject;
+ }
+
+ public Collection<String> getScopesToResolveForCurrentProject()
+ {
+ return scopesToResolveForCurrentProject;
+ }
+
+ public Collection<String> getScopesToCollectForAggregatedProjects()
+ {
+ return scopesToCollectForAggregatedProjects;
+ }
+
+ public Collection<String> getScopesToResolveForAggregatedProjects()
+ {
+ return scopesToResolveForAggregatedProjects;
+ }
+
+ public boolean isResolutionRequiredForCurrentProject()
+ {
+ return lastDependencyArtifacts != project.getDependencyArtifacts() || ( lastDependencyArtifacts != null
+ && lastDependencyArtifactCount != lastDependencyArtifacts.size() );
+ }
+
+ public boolean isResolutionRequiredForAggregatedProjects( Collection<String> scopesToCollect,
+ Collection<String> scopesToResolve )
+ {
+ boolean required =
+ scopesToCollectForAggregatedProjects.addAll( scopesToCollect )
+ || scopesToResolveForAggregatedProjects.addAll( scopesToResolve );
+ return required;
+ }
+
+ public void synchronizeWithProjectState()
+ {
+ lastDependencyArtifacts = project.getDependencyArtifacts();
+ lastDependencyArtifactCount = ( lastDependencyArtifacts != null ) ? lastDependencyArtifacts.size() : 0;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/ExecutionEventCatapult.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/ExecutionEventCatapult.java
new file mode 100644
index 00000000..acff5661
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/ExecutionEventCatapult.java
@@ -0,0 +1,40 @@
+package org.apache.maven.lifecycle.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.execution.ExecutionEvent;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.plugin.MojoExecution;
+
+/**
+ * Assists in firing execution events. <strong>Warning:</strong> This is an internal utility interface that is only
+ * public for technical reasons, it is not part of the public API. In particular, this interface can be changed or
+ * deleted without prior notice.
+ *
+ * @author Benjamin Bentmann
+ */
+public interface ExecutionEventCatapult
+{
+
+ void fire( ExecutionEvent.Type eventType, MavenSession session, MojoExecution mojoExecution );
+
+ void fire( ExecutionEvent.Type eventType, MavenSession session, MojoExecution mojoExecution, Exception exception );
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/ExecutionPlanItem.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/ExecutionPlanItem.java
new file mode 100644
index 00000000..cceffdf8
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/ExecutionPlanItem.java
@@ -0,0 +1,84 @@
+package org.apache.maven.lifecycle.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.lifecycle.internal.builder.BuilderCommon;
+import org.apache.maven.model.Plugin;
+import org.apache.maven.plugin.MojoExecution;
+import org.apache.maven.plugin.descriptor.MojoDescriptor;
+import org.apache.maven.project.MavenProject;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Wraps individual MojoExecutions, containing information about completion status and scheduling.
+ * <p/>
+ * NOTE: This class is not part of any public api and can be changed or deleted without prior notice.
+ *
+ * @since 3.0
+ * @author Kristian Rosenvold
+ */
+public class ExecutionPlanItem
+{
+ private final MojoExecution mojoExecution;
+
+ public ExecutionPlanItem( MojoExecution mojoExecution )
+ {
+ this.mojoExecution = mojoExecution;
+ }
+
+ public static List<ExecutionPlanItem> createExecutionPlanItems( MavenProject mavenProject,
+ List<MojoExecution> executions )
+ {
+ BuilderCommon.attachToThread( mavenProject );
+
+ List<ExecutionPlanItem> result = new ArrayList<ExecutionPlanItem>();
+ for ( MojoExecution mojoExecution : executions )
+ {
+ result.add( new ExecutionPlanItem( mojoExecution ) );
+ }
+ return result;
+ }
+
+ public MojoExecution getMojoExecution()
+ {
+ return mojoExecution;
+ }
+
+ public String getLifecyclePhase()
+ {
+ return mojoExecution.getLifecyclePhase();
+ }
+
+ public Plugin getPlugin()
+ {
+ final MojoDescriptor mojoDescriptor = getMojoExecution().getMojoDescriptor();
+ return mojoDescriptor.getPluginDescriptor().getPlugin();
+ }
+
+ @Override
+ public String toString()
+ {
+ return "ExecutionPlanItem{" + ", mojoExecution=" + mojoExecution + '}'
+ + super.toString();
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/GoalTask.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/GoalTask.java
new file mode 100644
index 00000000..5c43dbd4
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/GoalTask.java
@@ -0,0 +1,45 @@
+package org.apache.maven.lifecycle.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * A task that is a goal
+ * <p/>
+ * TODO: From a concurrecy perspective, this class is not good. The combination of mutable/immutable state is not nice
+ *
+ * @since 3.0
+ * @author Benjamin Bentmann
+ */
+public final class GoalTask
+{
+
+ final String pluginGoal;
+
+ public GoalTask( String pluginGoal )
+ {
+ this.pluginGoal = pluginGoal;
+ }
+
+ @Override
+ public String toString()
+ {
+ return pluginGoal;
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecycleDebugLogger.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecycleDebugLogger.java
new file mode 100644
index 00000000..2edbe754
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecycleDebugLogger.java
@@ -0,0 +1,182 @@
+package org.apache.maven.lifecycle.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.lifecycle.MavenExecutionPlan;
+import org.apache.maven.lifecycle.internal.builder.BuilderCommon;
+import org.apache.maven.plugin.MojoExecution;
+import org.apache.maven.plugin.descriptor.MojoDescriptor;
+import org.apache.maven.project.MavenProject;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+import org.codehaus.plexus.logging.Logger;
+import org.codehaus.plexus.util.StringUtils;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+
+/**
+ * Logs debug output from the various lifecycle phases.
+ *
+ * @since 3.0
+ * @author Benjamin Bentmann
+ * @author Jason van Zyl
+ * @author Kristian Rosenvold (extracted class only)
+ * <p/>
+ * NOTE: This class is not part of any public api and can be changed or deleted without prior notice.
+ */
+@Component( role = LifecycleDebugLogger.class )
+public class LifecycleDebugLogger
+{
+ @Requirement
+ private Logger logger;
+
+
+ public LifecycleDebugLogger()
+ {
+ }
+
+ public LifecycleDebugLogger( Logger logger )
+ {
+ this.logger = logger;
+ }
+
+
+ public void debug( String s )
+ {
+ logger.debug( s );
+ }
+
+ public void info( String s )
+ {
+ logger.info( s );
+ }
+
+ public void debugReactorPlan( ProjectBuildList projectBuilds )
+ {
+ if ( !logger.isDebugEnabled() )
+ {
+ return;
+ }
+
+ logger.debug( "=== REACTOR BUILD PLAN ================================================" );
+
+ for ( Iterator<ProjectSegment> it = projectBuilds.iterator(); it.hasNext(); )
+ {
+ ProjectSegment projectBuild = it.next();
+
+ logger.debug( "Project: " + projectBuild.getProject().getId() );
+ logger.debug( "Tasks: " + projectBuild.getTaskSegment().getTasks() );
+ logger.debug( "Style: " + ( projectBuild.getTaskSegment().isAggregating() ? "Aggregating" : "Regular" ) );
+
+ if ( it.hasNext() )
+ {
+ logger.debug( "-----------------------------------------------------------------------" );
+ }
+ }
+
+ logger.debug( "=======================================================================" );
+ }
+
+
+ public void debugProjectPlan( MavenProject currentProject, MavenExecutionPlan executionPlan )
+ {
+ if ( !logger.isDebugEnabled() )
+ {
+ return;
+ }
+
+ logger.debug( "=== PROJECT BUILD PLAN ================================================" );
+ logger.debug( "Project: " + BuilderCommon.getKey( currentProject ) );
+
+ debugDependencyRequirements( executionPlan.getMojoExecutions() );
+
+ logger.debug( "Repositories (dependencies): " + currentProject.getRemoteProjectRepositories() );
+ logger.debug( "Repositories (plugins) : " + currentProject.getRemotePluginRepositories() );
+
+ for ( ExecutionPlanItem mojoExecution : executionPlan )
+ {
+ debugMojoExecution( mojoExecution.getMojoExecution() );
+ }
+
+ logger.debug( "=======================================================================" );
+ }
+
+ private void debugMojoExecution( MojoExecution mojoExecution )
+ {
+ String mojoExecId =
+ mojoExecution.getGroupId() + ':' + mojoExecution.getArtifactId() + ':' + mojoExecution.getVersion() + ':'
+ + mojoExecution.getGoal() + " (" + mojoExecution.getExecutionId() + ')';
+
+ Map<String, List<MojoExecution>> forkedExecutions = mojoExecution.getForkedExecutions();
+ if ( !forkedExecutions.isEmpty() )
+ {
+ for ( Map.Entry<String, List<MojoExecution>> fork : forkedExecutions.entrySet() )
+ {
+ logger.debug( "--- init fork of " + fork.getKey() + " for " + mojoExecId + " ---" );
+
+ debugDependencyRequirements( fork.getValue() );
+
+ for ( MojoExecution forkedExecution : fork.getValue() )
+ {
+ debugMojoExecution( forkedExecution );
+ }
+
+ logger.debug( "--- exit fork of " + fork.getKey() + " for " + mojoExecId + " ---" );
+ }
+ }
+
+ logger.debug( "-----------------------------------------------------------------------" );
+ logger.debug( "Goal: " + mojoExecId );
+ logger.debug(
+ "Style: " + ( mojoExecution.getMojoDescriptor().isAggregator() ? "Aggregating" : "Regular" ) );
+ logger.debug( "Configuration: " + mojoExecution.getConfiguration() );
+ }
+
+ private void debugDependencyRequirements( List<MojoExecution> mojoExecutions )
+ {
+ Set<String> scopesToCollect = new TreeSet<String>();
+ Set<String> scopesToResolve = new TreeSet<String>();
+
+ for ( MojoExecution mojoExecution : mojoExecutions )
+ {
+ MojoDescriptor mojoDescriptor = mojoExecution.getMojoDescriptor();
+
+ String scopeToCollect = mojoDescriptor.getDependencyCollectionRequired();
+ if ( StringUtils.isNotEmpty( scopeToCollect ) )
+ {
+ scopesToCollect.add( scopeToCollect );
+ }
+
+ String scopeToResolve = mojoDescriptor.getDependencyResolutionRequired();
+ if ( StringUtils.isNotEmpty( scopeToResolve ) )
+ {
+ scopesToResolve.add( scopeToResolve );
+ }
+ }
+
+ logger.debug( "Dependencies (collect): " + scopesToCollect );
+ logger.debug( "Dependencies (resolve): " + scopesToResolve );
+ }
+
+} \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecycleDependencyResolver.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecycleDependencyResolver.java
new file mode 100644
index 00000000..4d73528c
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecycleDependencyResolver.java
@@ -0,0 +1,334 @@
+package org.apache.maven.lifecycle.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import org.apache.maven.RepositoryUtils;
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.ArtifactUtils;
+import org.apache.maven.eventspy.internal.EventSpyDispatcher;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.lifecycle.LifecycleExecutionException;
+import org.apache.maven.project.DefaultDependencyResolutionRequest;
+import org.apache.maven.project.DependencyResolutionException;
+import org.apache.maven.project.DependencyResolutionResult;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.project.ProjectDependenciesResolver;
+import org.apache.maven.project.artifact.InvalidDependencyVersionException;
+import org.codehaus.plexus.logging.Logger;
+import org.eclipse.aether.graph.Dependency;
+import org.eclipse.aether.graph.DependencyFilter;
+import org.eclipse.aether.graph.DependencyNode;
+import org.eclipse.aether.util.filter.AndDependencyFilter;
+import org.eclipse.aether.util.filter.ScopeDependencyFilter;
+
+/**
+ * Resolves dependencies for the artifacts in context of the lifecycle build
+ *
+ * @since 3.0
+ * @author Benjamin Bentmann
+ * @author Jason van Zyl
+ * @author Kristian Rosenvold (extracted class)
+ * <p/>
+ * NOTE: This class is not part of any public api and can be changed or deleted without prior notice.
+ */
+@Named
+public class LifecycleDependencyResolver
+{
+
+ @Inject
+ private ProjectDependenciesResolver dependenciesResolver;
+
+ @Inject
+ private Logger logger;
+
+ @Inject
+ private ProjectArtifactFactory artifactFactory;
+
+ @Inject
+ private EventSpyDispatcher eventSpyDispatcher;
+
+ public LifecycleDependencyResolver()
+ {
+ }
+
+ public LifecycleDependencyResolver( ProjectDependenciesResolver projectDependenciesResolver, Logger logger )
+ {
+ this.dependenciesResolver = projectDependenciesResolver;
+ this.logger = logger;
+ }
+
+ public static List<MavenProject> getProjects( MavenProject project, MavenSession session, boolean aggregator )
+ {
+ if ( aggregator )
+ {
+ return session.getProjects();
+ }
+ else
+ {
+ return Collections.singletonList( project );
+ }
+ }
+
+ public void resolveProjectDependencies( MavenProject project, Collection<String> scopesToCollect,
+ Collection<String> scopesToResolve, MavenSession session,
+ boolean aggregating, Set<Artifact> projectArtifacts )
+ throws LifecycleExecutionException
+ {
+ ClassLoader tccl = Thread.currentThread().getContextClassLoader();
+ try
+ {
+ ClassLoader projectRealm = project.getClassRealm();
+ if ( projectRealm != null && projectRealm != tccl )
+ {
+ Thread.currentThread().setContextClassLoader( projectRealm );
+ }
+
+ if ( project.getDependencyArtifacts() == null )
+ {
+ try
+ {
+ project.setDependencyArtifacts( artifactFactory.createArtifacts( project ) );
+ }
+ catch ( InvalidDependencyVersionException e )
+ {
+ throw new LifecycleExecutionException( e );
+ }
+ }
+
+ Set<Artifact> artifacts =
+ getDependencies( project, scopesToCollect, scopesToResolve, session, aggregating, projectArtifacts );
+
+ project.setResolvedArtifacts( artifacts );
+
+ Map<String, Artifact> map = new HashMap<String, Artifact>();
+ for ( Artifact artifact : artifacts )
+ {
+ map.put( artifact.getDependencyConflictId(), artifact );
+ }
+ for ( Artifact artifact : project.getDependencyArtifacts() )
+ {
+ if ( artifact.getFile() == null )
+ {
+ Artifact resolved = map.get( artifact.getDependencyConflictId() );
+ if ( resolved != null )
+ {
+ artifact.setFile( resolved.getFile() );
+ artifact.setDependencyTrail( resolved.getDependencyTrail() );
+ artifact.setResolvedVersion( resolved.getVersion() );
+ artifact.setResolved( true );
+ }
+ }
+ }
+ }
+ finally
+ {
+ Thread.currentThread().setContextClassLoader( tccl );
+ }
+ }
+
+ private Set<Artifact> getDependencies( MavenProject project, Collection<String> scopesToCollect,
+ Collection<String> scopesToResolve, MavenSession session,
+ boolean aggregating, Set<Artifact> projectArtifacts )
+ throws LifecycleExecutionException
+ {
+ if ( scopesToCollect == null )
+ {
+ scopesToCollect = Collections.emptySet();
+ }
+ if ( scopesToResolve == null )
+ {
+ scopesToResolve = Collections.emptySet();
+ }
+
+ if ( scopesToCollect.isEmpty() && scopesToResolve.isEmpty() )
+ {
+ return new LinkedHashSet<Artifact>();
+ }
+
+ scopesToCollect = new HashSet<String>( scopesToCollect );
+ scopesToCollect.addAll( scopesToResolve );
+
+ DependencyFilter collectionFilter = new ScopeDependencyFilter( null, negate( scopesToCollect ) );
+ DependencyFilter resolutionFilter = new ScopeDependencyFilter( null, negate( scopesToResolve ) );
+ resolutionFilter = AndDependencyFilter.newInstance( collectionFilter, resolutionFilter );
+ resolutionFilter =
+ AndDependencyFilter.newInstance( resolutionFilter, new ReactorDependencyFilter( projectArtifacts ) );
+
+ DependencyResolutionResult result;
+ try
+ {
+ DefaultDependencyResolutionRequest request =
+ new DefaultDependencyResolutionRequest( project, session.getRepositorySession() );
+ request.setResolutionFilter( resolutionFilter );
+
+ eventSpyDispatcher.onEvent( request );
+
+ result = dependenciesResolver.resolve( request );
+ }
+ catch ( DependencyResolutionException e )
+ {
+ result = e.getResult();
+
+ /*
+ * MNG-2277, the check below compensates for our bad plugin support where we ended up with aggregator
+ * plugins that require dependency resolution although they usually run in phases of the build where project
+ * artifacts haven't been assembled yet. The prime example of this is "mvn release:prepare".
+ */
+ if ( aggregating && areAllDependenciesInReactor( session.getProjects(),
+ result.getUnresolvedDependencies() ) )
+ {
+ logger.warn( "The following dependencies could not be resolved at this point of the build"
+ + " but seem to be part of the reactor:" );
+
+ for ( Dependency dependency : result.getUnresolvedDependencies() )
+ {
+ logger.warn( "o " + dependency );
+ }
+
+ logger.warn( "Try running the build up to the lifecycle phase \"package\"" );
+ }
+ else
+ {
+ throw new LifecycleExecutionException( null, project, e );
+ }
+ }
+
+ eventSpyDispatcher.onEvent( result );
+
+ Set<Artifact> artifacts = new LinkedHashSet<Artifact>();
+ if ( result.getDependencyGraph() != null && !result.getDependencyGraph().getChildren().isEmpty() )
+ {
+ RepositoryUtils.toArtifacts( artifacts, result.getDependencyGraph().getChildren(),
+ Collections.singletonList( project.getArtifact().getId() ), collectionFilter );
+ }
+ return artifacts;
+ }
+
+ private boolean areAllDependenciesInReactor( Collection<MavenProject> projects,
+ Collection<Dependency> dependencies )
+ {
+ Set<String> projectKeys = getReactorProjectKeys( projects );
+
+ for ( Dependency dependency : dependencies )
+ {
+ org.eclipse.aether.artifact.Artifact a = dependency.getArtifact();
+ String key = ArtifactUtils.key( a.getGroupId(), a.getArtifactId(), a.getVersion() );
+ if ( !projectKeys.contains( key ) )
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ private Set<String> getReactorProjectKeys( Collection<MavenProject> projects )
+ {
+ Set<String> projectKeys = new HashSet<String>( projects.size() * 2 );
+ for ( MavenProject project : projects )
+ {
+ String key = ArtifactUtils.key( project.getGroupId(), project.getArtifactId(), project.getVersion() );
+ projectKeys.add( key );
+ }
+ return projectKeys;
+ }
+
+ private Collection<String> negate( Collection<String> scopes )
+ {
+ Collection<String> result = new HashSet<String>();
+ Collections.addAll( result, "system", "compile", "provided", "runtime", "test" );
+
+ for ( String scope : scopes )
+ {
+ if ( "compile".equals( scope ) )
+ {
+ result.remove( "compile" );
+ result.remove( "system" );
+ result.remove( "provided" );
+ }
+ else if ( "runtime".equals( scope ) )
+ {
+ result.remove( "compile" );
+ result.remove( "runtime" );
+ }
+ else if ( "compile+runtime".equals( scope ) )
+ {
+ result.remove( "compile" );
+ result.remove( "system" );
+ result.remove( "provided" );
+ result.remove( "runtime" );
+ }
+ else if ( "runtime+system".equals( scope ) )
+ {
+ result.remove( "compile" );
+ result.remove( "system" );
+ result.remove( "runtime" );
+ }
+ else if ( "test".equals( scope ) )
+ {
+ result.clear();
+ }
+ }
+
+ return result;
+ }
+
+ private static class ReactorDependencyFilter
+ implements DependencyFilter
+ {
+
+ private Set<String> keys = new HashSet<String>();
+
+ public ReactorDependencyFilter( Collection<Artifact> artifacts )
+ {
+ for ( Artifact artifact : artifacts )
+ {
+ String key = ArtifactUtils.key( artifact );
+ keys.add( key );
+ }
+ }
+
+ public boolean accept( DependencyNode node, List<DependencyNode> parents )
+ {
+ Dependency dependency = node.getDependency();
+ if ( dependency != null )
+ {
+ org.eclipse.aether.artifact.Artifact a = dependency.getArtifact();
+ String key = ArtifactUtils.key( a.getGroupId(), a.getArtifactId(), a.getVersion() );
+ return !keys.contains( key );
+ }
+ return false;
+ }
+
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecycleExecutionPlanCalculator.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecycleExecutionPlanCalculator.java
new file mode 100644
index 00000000..7d35b102
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecycleExecutionPlanCalculator.java
@@ -0,0 +1,67 @@
+package org.apache.maven.lifecycle.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.lifecycle.LifecycleNotFoundException;
+import org.apache.maven.lifecycle.LifecyclePhaseNotFoundException;
+import org.apache.maven.lifecycle.MavenExecutionPlan;
+import org.apache.maven.plugin.InvalidPluginDescriptorException;
+import org.apache.maven.plugin.MojoExecution;
+import org.apache.maven.plugin.MojoNotFoundException;
+import org.apache.maven.plugin.PluginDescriptorParsingException;
+import org.apache.maven.plugin.PluginNotFoundException;
+import org.apache.maven.plugin.PluginResolutionException;
+import org.apache.maven.plugin.prefix.NoPluginFoundForPrefixException;
+import org.apache.maven.plugin.version.PluginVersionResolutionException;
+import org.apache.maven.project.MavenProject;
+
+import java.util.List;
+
+/**
+ * @since 3.0
+ * @author Benjamin Bentmann
+ * @author Kristian Rosenvold (extract interface only)
+ * <p/>
+ */
+public interface LifecycleExecutionPlanCalculator
+{
+ MavenExecutionPlan calculateExecutionPlan( MavenSession session, MavenProject project, List<Object> tasks )
+ throws PluginNotFoundException, PluginResolutionException, LifecyclePhaseNotFoundException,
+ PluginDescriptorParsingException, MojoNotFoundException, InvalidPluginDescriptorException,
+ NoPluginFoundForPrefixException, LifecycleNotFoundException, PluginVersionResolutionException;
+
+ MavenExecutionPlan calculateExecutionPlan( MavenSession session, MavenProject project, List<Object> tasks,
+ boolean setup )
+ throws PluginNotFoundException, PluginResolutionException, LifecyclePhaseNotFoundException,
+ PluginDescriptorParsingException, MojoNotFoundException, InvalidPluginDescriptorException,
+ NoPluginFoundForPrefixException, LifecycleNotFoundException, PluginVersionResolutionException;
+
+ void calculateForkedExecutions( MojoExecution mojoExecution, MavenSession session )
+ throws MojoNotFoundException, PluginNotFoundException, PluginResolutionException,
+ PluginDescriptorParsingException, NoPluginFoundForPrefixException, InvalidPluginDescriptorException,
+ LifecyclePhaseNotFoundException, LifecycleNotFoundException, PluginVersionResolutionException;
+
+ void setupMojoExecution( MavenSession session, MavenProject project, MojoExecution mojoExecution )
+ throws PluginNotFoundException, PluginResolutionException, PluginDescriptorParsingException,
+ MojoNotFoundException, InvalidPluginDescriptorException, NoPluginFoundForPrefixException,
+ LifecyclePhaseNotFoundException, LifecycleNotFoundException, PluginVersionResolutionException;
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecycleModuleBuilder.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecycleModuleBuilder.java
new file mode 100644
index 00000000..343fbf95
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecycleModuleBuilder.java
@@ -0,0 +1,154 @@
+package org.apache.maven.lifecycle.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.HashSet;
+import java.util.List;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.execution.BuildSuccess;
+import org.apache.maven.execution.ExecutionEvent;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.execution.ProjectExecutionEvent;
+import org.apache.maven.execution.ProjectExecutionListener;
+import org.apache.maven.lifecycle.MavenExecutionPlan;
+import org.apache.maven.lifecycle.internal.builder.BuilderCommon;
+import org.apache.maven.plugin.MojoExecution;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.session.scope.internal.SessionScope;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+
+/**
+ * Builds one or more lifecycles for a full module
+ *
+ * @since 3.0
+ * @author Benjamin Bentmann
+ * @author Jason van Zyl
+ * @author Kristian Rosenvold (extracted class)
+ * <p/>
+ * NOTE: This class is not part of any public api and can be changed or deleted without prior notice.
+ */
+@Component( role = LifecycleModuleBuilder.class )
+public class LifecycleModuleBuilder
+{
+
+ @Requirement
+ private MojoExecutor mojoExecutor;
+
+ @Requirement
+ private BuilderCommon builderCommon;
+
+ @Requirement
+ private ExecutionEventCatapult eventCatapult;
+
+ private ProjectExecutionListener projectExecutionListener;
+
+ // this tricks plexus-component-metadata generate required metadata
+ @Requirement
+ private List<ProjectExecutionListener> projectExecutionListeners;
+
+ @Requirement
+ private SessionScope sessionScope;
+
+ public void setProjectExecutionListeners( final List<ProjectExecutionListener> listeners )
+ {
+ this.projectExecutionListeners = listeners;
+ this.projectExecutionListener = new CompoundProjectExecutionListener( listeners );
+ }
+
+ public void buildProject( MavenSession session, ReactorContext reactorContext, MavenProject currentProject,
+ TaskSegment taskSegment )
+ {
+ buildProject( session, session, reactorContext, currentProject, taskSegment );
+ }
+
+ public void buildProject( MavenSession session, MavenSession rootSession, ReactorContext reactorContext,
+ MavenProject currentProject, TaskSegment taskSegment )
+ {
+ session.setCurrentProject( currentProject );
+
+ long buildStartTime = System.currentTimeMillis();
+
+ // session may be different from rootSession seeded in DefaultMaven
+ // explicitly seed the right session here to make sure it is used by Guice
+ sessionScope.enter( reactorContext.getSessionScopeMemento() );
+ sessionScope.seed( MavenSession.class, session );
+ try
+ {
+
+ if ( reactorContext.getReactorBuildStatus().isHaltedOrBlacklisted( currentProject ) )
+ {
+ eventCatapult.fire( ExecutionEvent.Type.ProjectSkipped, session, null );
+ return;
+ }
+
+ BuilderCommon.attachToThread( currentProject );
+
+ projectExecutionListener.beforeProjectExecution( new ProjectExecutionEvent( session, currentProject ) );
+
+ eventCatapult.fire( ExecutionEvent.Type.ProjectStarted, session, null );
+
+ MavenExecutionPlan executionPlan =
+ builderCommon.resolveBuildPlan( session, currentProject, taskSegment, new HashSet<Artifact>() );
+ List<MojoExecution> mojoExecutions = executionPlan.getMojoExecutions();
+
+ projectExecutionListener.beforeProjectLifecycleExecution( new ProjectExecutionEvent( session,
+ currentProject,
+ mojoExecutions ) );
+ mojoExecutor.execute( session, mojoExecutions, reactorContext.getProjectIndex() );
+
+ long buildEndTime = System.currentTimeMillis();
+
+ projectExecutionListener.afterProjectExecutionSuccess( new ProjectExecutionEvent( session, currentProject,
+ mojoExecutions ) );
+
+ reactorContext.getResult().addBuildSummary( new BuildSuccess( currentProject,
+ buildEndTime - buildStartTime ) );
+
+ eventCatapult.fire( ExecutionEvent.Type.ProjectSucceeded, session, null );
+ }
+ catch ( Throwable t )
+ {
+ builderCommon.handleBuildError( reactorContext, rootSession, session, currentProject, t, buildStartTime );
+
+ projectExecutionListener.afterProjectExecutionFailure( new ProjectExecutionEvent( session, currentProject,
+ t ) );
+
+ // rethrow original errors and runtime exceptions
+ if ( t instanceof RuntimeException )
+ {
+ throw (RuntimeException) t;
+ }
+ if ( t instanceof Error )
+ {
+ throw (Error) t;
+ }
+ }
+ finally
+ {
+ sessionScope.exit();
+
+ session.setCurrentProject( null );
+
+ Thread.currentThread().setContextClassLoader( reactorContext.getOriginalContextClassLoader() );
+ }
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecyclePluginResolver.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecyclePluginResolver.java
new file mode 100644
index 00000000..c615a6f6
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecyclePluginResolver.java
@@ -0,0 +1,95 @@
+package org.apache.maven.lifecycle.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.model.Plugin;
+import org.apache.maven.model.PluginManagement;
+import org.apache.maven.plugin.version.DefaultPluginVersionRequest;
+import org.apache.maven.plugin.version.PluginVersionRequest;
+import org.apache.maven.plugin.version.PluginVersionResolutionException;
+import org.apache.maven.plugin.version.PluginVersionResolver;
+import org.apache.maven.project.MavenProject;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @since 3.0
+ * @author Benjamin Bentmann
+ * @author Kristian Rosenvold (Extract class)
+ * <p/>
+ * NOTE: This class is not part of any public api and can be changed or deleted without prior notice.
+ */
+@Component( role = LifecyclePluginResolver.class )
+public class LifecyclePluginResolver
+{
+ @Requirement
+ private PluginVersionResolver pluginVersionResolver;
+
+
+ public LifecyclePluginResolver( PluginVersionResolver pluginVersionResolver )
+ {
+ this.pluginVersionResolver = pluginVersionResolver;
+ }
+
+ public LifecyclePluginResolver()
+ {
+ }
+
+ public void resolveMissingPluginVersions( MavenProject project, MavenSession session )
+ throws PluginVersionResolutionException
+ {
+ Map<String, String> versions = new HashMap<String, String>( 64 );
+
+ for ( Plugin plugin : project.getBuildPlugins() )
+ {
+ if ( plugin.getVersion() == null )
+ {
+ PluginVersionRequest request =
+ new DefaultPluginVersionRequest( plugin, session.getRepositorySession(),
+ project.getRemotePluginRepositories() );
+ plugin.setVersion( pluginVersionResolver.resolve( request ).getVersion() );
+ }
+ versions.put( plugin.getKey(), plugin.getVersion() );
+ }
+
+ PluginManagement pluginManagement = project.getPluginManagement();
+ if ( pluginManagement != null )
+ {
+ for ( Plugin plugin : pluginManagement.getPlugins() )
+ {
+ if ( plugin.getVersion() == null )
+ {
+ plugin.setVersion( versions.get( plugin.getKey() ) );
+ if ( plugin.getVersion() == null )
+ {
+ PluginVersionRequest request =
+ new DefaultPluginVersionRequest( plugin, session.getRepositorySession(),
+ project.getRemotePluginRepositories() );
+ plugin.setVersion( pluginVersionResolver.resolve( request ).getVersion() );
+ }
+ }
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecycleStarter.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecycleStarter.java
new file mode 100644
index 00000000..cee80739
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecycleStarter.java
@@ -0,0 +1,150 @@
+package org.apache.maven.lifecycle.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.List;
+import java.util.Map;
+
+import org.apache.maven.execution.ExecutionEvent;
+import org.apache.maven.execution.MavenExecutionResult;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.lifecycle.DefaultLifecycles;
+import org.apache.maven.lifecycle.MissingProjectException;
+import org.apache.maven.lifecycle.NoGoalSpecifiedException;
+import org.apache.maven.lifecycle.internal.builder.Builder;
+import org.apache.maven.lifecycle.internal.builder.BuilderNotFoundException;
+import org.apache.maven.session.scope.internal.SessionScope;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+import org.codehaus.plexus.logging.Logger;
+
+/**
+ * Starts the build life cycle
+ *
+ * @author Jason van Zyl
+ * @author Benjamin Bentmann
+ * @author Kristian Rosenvold
+ */
+@Component( role = LifecycleStarter.class )
+public class LifecycleStarter
+{
+ @Requirement
+ private ExecutionEventCatapult eventCatapult;
+
+ @Requirement
+ private DefaultLifecycles defaultLifeCycles;
+
+ @Requirement
+ private Logger logger;
+
+ @Requirement
+ private BuildListCalculator buildListCalculator;
+
+ @Requirement
+ private LifecycleDebugLogger lifecycleDebugLogger;
+
+ @Requirement
+ private LifecycleTaskSegmentCalculator lifecycleTaskSegmentCalculator;
+
+ @Requirement
+ private Map<String, Builder> builders;
+
+ @Requirement
+ private SessionScope sessionScope;
+
+ public void execute( MavenSession session )
+ {
+ eventCatapult.fire( ExecutionEvent.Type.SessionStarted, session, null );
+
+ ReactorContext reactorContext = null;
+ ProjectBuildList projectBuilds = null;
+ MavenExecutionResult result = session.getResult();
+
+ try
+ {
+ if ( buildExecutionRequiresProject( session ) && projectIsNotPresent( session ) )
+ {
+ throw new MissingProjectException( "The goal you specified requires a project to execute"
+ + " but there is no POM in this directory (" + session.getExecutionRootDirectory() + ")."
+ + " Please verify you invoked Maven from the correct directory." );
+ }
+
+ List<TaskSegment> taskSegments = lifecycleTaskSegmentCalculator.calculateTaskSegments( session );
+ projectBuilds = buildListCalculator.calculateProjectBuilds( session, taskSegments );
+
+ if ( projectBuilds.isEmpty() )
+ {
+ throw new NoGoalSpecifiedException( "No goals have been specified for this build."
+ + " You must specify a valid lifecycle phase or a goal in the format <plugin-prefix>:<goal> or"
+ + " <plugin-group-id>:<plugin-artifact-id>[:<plugin-version>]:<goal>."
+ + " Available lifecycle phases are: " + defaultLifeCycles.getLifecyclePhaseList() + "." );
+ }
+
+ ProjectIndex projectIndex = new ProjectIndex( session.getProjects() );
+
+ if ( logger.isDebugEnabled() )
+ {
+ lifecycleDebugLogger.debugReactorPlan( projectBuilds );
+ }
+
+ ClassLoader oldContextClassLoader = Thread.currentThread().getContextClassLoader();
+ ReactorBuildStatus reactorBuildStatus = new ReactorBuildStatus( session.getProjectDependencyGraph() );
+ reactorContext =
+ new ReactorContext( result, projectIndex, oldContextClassLoader, reactorBuildStatus,
+ sessionScope.memento() );
+
+ String builderId = session.getRequest().getBuilderId();
+ Builder builder = builders.get( builderId );
+ if ( builder == null )
+ {
+ throw new BuilderNotFoundException( String.format( "The builder requested using id = %s cannot be"
+ + " found", builderId ) );
+ }
+
+ int degreeOfConcurrency = session.getRequest().getDegreeOfConcurrency();
+ if ( degreeOfConcurrency >= 2 )
+ {
+ logger.info( "" );
+ logger.info( String.format( "Using the %s implementation with a thread count of %d",
+ builder.getClass().getSimpleName(), degreeOfConcurrency ) );
+ }
+ builder.build( session, reactorContext, projectBuilds, taskSegments, reactorBuildStatus );
+
+ }
+ catch ( Exception e )
+ {
+ result.addException( e );
+ }
+ finally
+ {
+ eventCatapult.fire( ExecutionEvent.Type.SessionEnded, session, null );
+ }
+ }
+
+ private boolean buildExecutionRequiresProject( MavenSession session )
+ {
+ return lifecycleTaskSegmentCalculator.requiresProject( session );
+ }
+
+ private boolean projectIsNotPresent( MavenSession session )
+ {
+ return !session.getRequest().isProjectPresent();
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecycleTask.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecycleTask.java
new file mode 100644
index 00000000..0b5fff34
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecycleTask.java
@@ -0,0 +1,50 @@
+package org.apache.maven.lifecycle.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * A task that is a lifecycle
+ * <p/>
+ * NOTE: This class is not part of any public api and can be changed or deleted without prior notice.
+ *
+ * @since 3.0
+ * @author Benjamin Bentmann
+ */
+public final class LifecycleTask
+{
+
+ private final String lifecyclePhase;
+
+ public LifecycleTask( String lifecyclePhase )
+ {
+ this.lifecyclePhase = lifecyclePhase;
+ }
+
+ @Override
+ public String toString()
+ {
+ return getLifecyclePhase();
+ }
+
+ public String getLifecyclePhase()
+ {
+ return lifecyclePhase;
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecycleTaskSegmentCalculator.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecycleTaskSegmentCalculator.java
new file mode 100644
index 00000000..a721355b
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/LifecycleTaskSegmentCalculator.java
@@ -0,0 +1,61 @@
+package org.apache.maven.lifecycle.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.lifecycle.LifecycleNotFoundException;
+import org.apache.maven.lifecycle.LifecyclePhaseNotFoundException;
+import org.apache.maven.plugin.InvalidPluginDescriptorException;
+import org.apache.maven.plugin.MojoNotFoundException;
+import org.apache.maven.plugin.PluginDescriptorParsingException;
+import org.apache.maven.plugin.PluginNotFoundException;
+import org.apache.maven.plugin.PluginResolutionException;
+import org.apache.maven.plugin.prefix.NoPluginFoundForPrefixException;
+import org.apache.maven.plugin.version.PluginVersionResolutionException;
+
+import java.util.List;
+
+/**
+ * Calculates the task segments in the build
+ *
+ * @since 3.0
+ * @author Benjamin Bentmann
+ * @author Jason van Zyl
+ * @author jdcasey
+ * @author Kristian Rosenvold (extracted interface)
+ * <p/>
+ * NOTE: This interface is not part of any public api and can be changed or deleted without prior notice.
+ */
+
+public interface LifecycleTaskSegmentCalculator
+{
+ List<TaskSegment> calculateTaskSegments( MavenSession session )
+ throws PluginNotFoundException, PluginResolutionException, PluginDescriptorParsingException,
+ MojoNotFoundException, NoPluginFoundForPrefixException, InvalidPluginDescriptorException,
+ PluginVersionResolutionException, LifecyclePhaseNotFoundException, LifecycleNotFoundException;
+
+ List<TaskSegment> calculateTaskSegments( MavenSession session, List<String> tasks )
+ throws PluginNotFoundException, PluginResolutionException, PluginDescriptorParsingException,
+ MojoNotFoundException, NoPluginFoundForPrefixException, InvalidPluginDescriptorException,
+ PluginVersionResolutionException;
+
+ boolean requiresProject( MavenSession session );
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/MojoDescriptorCreator.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/MojoDescriptorCreator.java
new file mode 100644
index 00000000..36c85fdd
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/MojoDescriptorCreator.java
@@ -0,0 +1,309 @@
+package org.apache.maven.lifecycle.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.model.Dependency;
+import org.apache.maven.model.Plugin;
+import org.apache.maven.plugin.BuildPluginManager;
+import org.apache.maven.plugin.InvalidPluginDescriptorException;
+import org.apache.maven.plugin.MojoNotFoundException;
+import org.apache.maven.plugin.PluginDescriptorParsingException;
+import org.apache.maven.plugin.PluginNotFoundException;
+import org.apache.maven.plugin.PluginResolutionException;
+import org.apache.maven.plugin.descriptor.MojoDescriptor;
+import org.apache.maven.plugin.prefix.DefaultPluginPrefixRequest;
+import org.apache.maven.plugin.prefix.NoPluginFoundForPrefixException;
+import org.apache.maven.plugin.prefix.PluginPrefixRequest;
+import org.apache.maven.plugin.prefix.PluginPrefixResolver;
+import org.apache.maven.plugin.prefix.PluginPrefixResult;
+import org.apache.maven.plugin.version.DefaultPluginVersionRequest;
+import org.apache.maven.plugin.version.PluginVersionRequest;
+import org.apache.maven.plugin.version.PluginVersionResolutionException;
+import org.apache.maven.plugin.version.PluginVersionResolver;
+import org.apache.maven.project.MavenProject;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+import org.codehaus.plexus.configuration.PlexusConfiguration;
+import org.codehaus.plexus.logging.Logger;
+import org.codehaus.plexus.util.xml.Xpp3Dom;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.StringTokenizer;
+
+/**
+ * Resolves dependencies for the artifacts in context of the lifecycle build
+ *
+ * @since 3.0
+ * @author Benjamin Bentmann
+ * @author Jason van Zyl
+ * @author jdcasey
+ * @author Kristian Rosenvold (extracted class only)
+ * <p/>
+ * NOTE: This class is not part of any public api and can be changed or deleted without prior notice.
+ */
+@Component( role = MojoDescriptorCreator.class )
+public class MojoDescriptorCreator
+{
+
+ @Requirement
+ private Logger logger;
+
+ @Requirement
+ private PluginVersionResolver pluginVersionResolver;
+
+ @Requirement
+ private BuildPluginManager pluginManager;
+
+ @Requirement
+ private PluginPrefixResolver pluginPrefixResolver;
+
+ @Requirement
+ private LifecyclePluginResolver lifecyclePluginResolver;
+
+ public MojoDescriptorCreator()
+ {
+ }
+
+ public MojoDescriptorCreator( PluginVersionResolver pluginVersionResolver, BuildPluginManager pluginManager,
+ PluginPrefixResolver pluginPrefixResolver,
+ LifecyclePluginResolver lifecyclePluginResolver )
+ {
+ this.pluginVersionResolver = pluginVersionResolver;
+ this.pluginManager = pluginManager;
+ this.pluginPrefixResolver = pluginPrefixResolver;
+ this.lifecyclePluginResolver = lifecyclePluginResolver;
+ }
+
+ private Plugin findPlugin( String groupId, String artifactId, Collection<Plugin> plugins )
+ {
+ for ( Plugin plugin : plugins )
+ {
+ if ( artifactId.equals( plugin.getArtifactId() ) && groupId.equals( plugin.getGroupId() ) )
+ {
+ return plugin;
+ }
+ }
+
+ return null;
+ }
+
+ public static Xpp3Dom convert( MojoDescriptor mojoDescriptor )
+ {
+ Xpp3Dom dom = new Xpp3Dom( "configuration" );
+
+ PlexusConfiguration c = mojoDescriptor.getMojoConfiguration();
+
+ PlexusConfiguration[] ces = c.getChildren();
+
+ if ( ces != null )
+ {
+ for ( PlexusConfiguration ce : ces )
+ {
+ String value = ce.getValue( null );
+ String defaultValue = ce.getAttribute( "default-value", null );
+ if ( value != null || defaultValue != null )
+ {
+ Xpp3Dom e = new Xpp3Dom( ce.getName() );
+ e.setValue( value );
+ if ( defaultValue != null )
+ {
+ e.setAttribute( "default-value", defaultValue );
+ }
+ dom.addChild( e );
+ }
+ }
+ }
+
+ return dom;
+ }
+
+ // org.apache.maven.plugins:maven-remote-resources-plugin:1.0:process@executionId
+
+ public MojoDescriptor getMojoDescriptor( String task, MavenSession session, MavenProject project )
+ throws PluginNotFoundException, PluginResolutionException, PluginDescriptorParsingException,
+ MojoNotFoundException, NoPluginFoundForPrefixException, InvalidPluginDescriptorException,
+ PluginVersionResolutionException
+ {
+ String goal = null;
+
+ Plugin plugin = null;
+
+ StringTokenizer tok = new StringTokenizer( task, ":" );
+
+ int numTokens = tok.countTokens();
+
+ if ( numTokens >= 4 )
+ {
+ // We have everything that we need
+ //
+ // org.apache.maven.plugins:maven-remote-resources-plugin:1.0:process
+ //
+ // groupId
+ // artifactId
+ // version
+ // goal
+ //
+ plugin = new Plugin();
+ plugin.setGroupId( tok.nextToken() );
+ plugin.setArtifactId( tok.nextToken() );
+ plugin.setVersion( tok.nextToken() );
+ goal = tok.nextToken();
+
+ // This won't be valid, but it constructs something easy to read in the error message
+ while ( tok.hasMoreTokens() )
+ {
+ goal += ":" + tok.nextToken();
+ }
+ }
+ else if ( numTokens == 3 )
+ {
+ // We have everything that we need except the version
+ //
+ // org.apache.maven.plugins:maven-remote-resources-plugin:???:process
+ //
+ // groupId
+ // artifactId
+ // ???
+ // goal
+ //
+ plugin = new Plugin();
+ plugin.setGroupId( tok.nextToken() );
+ plugin.setArtifactId( tok.nextToken() );
+ goal = tok.nextToken();
+ }
+ else if ( numTokens <= 2 )
+ {
+ // We have a prefix and goal
+ //
+ // idea:idea
+ //
+ String prefix = tok.nextToken();
+
+ if ( numTokens == 2 )
+ {
+ goal = tok.nextToken();
+ }
+ else
+ {
+ // goal was missing - pass through to MojoNotFoundException
+ goal = "";
+ }
+
+ // This is the case where someone has executed a single goal from the command line
+ // of the form:
+ //
+ // mvn remote-resources:process
+ //
+ // From the metadata stored on the server which has been created as part of a standard
+ // Maven plugin deployment we will find the right PluginDescriptor from the remote
+ // repository.
+
+ plugin = findPluginForPrefix( prefix, session );
+ }
+
+ int executionIdx = goal.indexOf( '@' );
+ if ( executionIdx > 0 )
+ {
+ goal = goal.substring( 0, executionIdx );
+ }
+
+ injectPluginDeclarationFromProject( plugin, project );
+
+ // If there is no version to be found then we need to look in the repository metadata for
+ // this plugin and see what's specified as the latest release.
+ //
+ if ( plugin.getVersion() == null )
+ {
+ resolvePluginVersion( plugin, session, project );
+ }
+
+ return pluginManager.getMojoDescriptor( plugin, goal, project.getRemotePluginRepositories(),
+ session.getRepositorySession() );
+ }
+
+ // TODO: take repo mans into account as one may be aggregating prefixes of many
+ // TODO: collect at the root of the repository, read the one at the root, and fetch remote if something is missing
+ // or the user forces the issue
+
+ public Plugin findPluginForPrefix( String prefix, MavenSession session )
+ throws NoPluginFoundForPrefixException
+ {
+ // [prefix]:[goal]
+
+ if ( session.getCurrentProject() != null )
+ {
+ try
+ {
+ lifecyclePluginResolver.resolveMissingPluginVersions( session.getCurrentProject(), session );
+ }
+ catch ( PluginVersionResolutionException e )
+ {
+ // not critical here
+ logger.debug( e.getMessage(), e );
+ }
+ }
+
+ PluginPrefixRequest prefixRequest = new DefaultPluginPrefixRequest( prefix, session );
+ PluginPrefixResult prefixResult = pluginPrefixResolver.resolve( prefixRequest );
+
+ Plugin plugin = new Plugin();
+ plugin.setGroupId( prefixResult.getGroupId() );
+ plugin.setArtifactId( prefixResult.getArtifactId() );
+
+ return plugin;
+ }
+
+ private void resolvePluginVersion( Plugin plugin, MavenSession session, MavenProject project )
+ throws PluginVersionResolutionException
+ {
+ PluginVersionRequest versionRequest =
+ new DefaultPluginVersionRequest( plugin, session.getRepositorySession(),
+ project.getRemotePluginRepositories() );
+ plugin.setVersion( pluginVersionResolver.resolve( versionRequest ).getVersion() );
+ }
+
+ private void injectPluginDeclarationFromProject( Plugin plugin, MavenProject project )
+ {
+ Plugin pluginInPom = findPlugin( plugin, project.getBuildPlugins() );
+
+ if ( pluginInPom == null && project.getPluginManagement() != null )
+ {
+ pluginInPom = findPlugin( plugin, project.getPluginManagement().getPlugins() );
+ }
+
+ if ( pluginInPom != null )
+ {
+ if ( plugin.getVersion() == null )
+ {
+ plugin.setVersion( pluginInPom.getVersion() );
+ }
+
+ plugin.setDependencies( new ArrayList<Dependency>( pluginInPom.getDependencies() ) );
+ }
+ }
+
+ private Plugin findPlugin( Plugin plugin, Collection<Plugin> plugins )
+ {
+ return findPlugin( plugin.getGroupId(), plugin.getArtifactId(), plugins );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/MojoExecutor.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/MojoExecutor.java
new file mode 100644
index 00000000..a6ba752c
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/MojoExecutor.java
@@ -0,0 +1,394 @@
+package org.apache.maven.lifecycle.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
+import org.apache.maven.artifact.resolver.filter.CumulativeScopeArtifactFilter;
+import org.apache.maven.execution.ExecutionEvent;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.lifecycle.LifecycleExecutionException;
+import org.apache.maven.lifecycle.MissingProjectException;
+import org.apache.maven.plugin.BuildPluginManager;
+import org.apache.maven.plugin.MavenPluginManager;
+import org.apache.maven.plugin.MojoExecution;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugin.PluginConfigurationException;
+import org.apache.maven.plugin.PluginIncompatibleException;
+import org.apache.maven.plugin.PluginManagerException;
+import org.apache.maven.plugin.descriptor.MojoDescriptor;
+import org.apache.maven.project.MavenProject;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+import org.codehaus.plexus.util.StringUtils;
+
+/**
+ * Executes an individual mojo
+ *
+ * @since 3.0
+ * @author Jason van Zyl
+ * @author Benjamin Bentmann
+ * @author Kristian Rosenvold
+ * <p/>
+ * NOTE: This class is not part of any public api and can be changed or deleted without prior notice.
+ */
+@Component( role = MojoExecutor.class )
+public class MojoExecutor
+{
+
+ @Requirement
+ private BuildPluginManager pluginManager;
+
+ @Requirement
+ private MavenPluginManager mavenPluginManager;
+
+ @Requirement
+ private LifecycleDependencyResolver lifeCycleDependencyResolver;
+
+ @Requirement
+ private ExecutionEventCatapult eventCatapult;
+
+ public MojoExecutor()
+ {
+ }
+
+ public DependencyContext newDependencyContext( MavenSession session, List<MojoExecution> mojoExecutions )
+ {
+ Set<String> scopesToCollect = new TreeSet<String>();
+ Set<String> scopesToResolve = new TreeSet<String>();
+
+ collectDependencyRequirements( scopesToResolve, scopesToCollect, mojoExecutions );
+
+ return new DependencyContext( session.getCurrentProject(), scopesToCollect, scopesToResolve );
+ }
+
+ private void collectDependencyRequirements( Set<String> scopesToResolve, Set<String> scopesToCollect,
+ Collection<MojoExecution> mojoExecutions )
+ {
+ for ( MojoExecution mojoExecution : mojoExecutions )
+ {
+ MojoDescriptor mojoDescriptor = mojoExecution.getMojoDescriptor();
+
+ scopesToResolve.addAll( toScopes( mojoDescriptor.getDependencyResolutionRequired() ) );
+
+ scopesToCollect.addAll( toScopes( mojoDescriptor.getDependencyCollectionRequired() ) );
+ }
+ }
+
+ private Collection<String> toScopes( String classpath )
+ {
+ if ( StringUtils.isNotEmpty( classpath ) )
+ {
+ if ( Artifact.SCOPE_COMPILE.equals( classpath ) )
+ {
+ return Arrays.asList( Artifact.SCOPE_COMPILE, Artifact.SCOPE_SYSTEM, Artifact.SCOPE_PROVIDED );
+ }
+ else if ( Artifact.SCOPE_RUNTIME.equals( classpath ) )
+ {
+ return Arrays.asList( Artifact.SCOPE_COMPILE, Artifact.SCOPE_RUNTIME );
+ }
+ else if ( Artifact.SCOPE_COMPILE_PLUS_RUNTIME.equals( classpath ) )
+ {
+ return Arrays.asList( Artifact.SCOPE_COMPILE, Artifact.SCOPE_SYSTEM, Artifact.SCOPE_PROVIDED,
+ Artifact.SCOPE_RUNTIME );
+ }
+ else if ( Artifact.SCOPE_RUNTIME_PLUS_SYSTEM.equals( classpath ) )
+ {
+ return Arrays.asList( Artifact.SCOPE_COMPILE, Artifact.SCOPE_SYSTEM, Artifact.SCOPE_RUNTIME );
+ }
+ else if ( Artifact.SCOPE_TEST.equals( classpath ) )
+ {
+ return Arrays.asList( Artifact.SCOPE_COMPILE, Artifact.SCOPE_SYSTEM, Artifact.SCOPE_PROVIDED,
+ Artifact.SCOPE_RUNTIME, Artifact.SCOPE_TEST );
+ }
+ }
+ return Collections.emptyList();
+ }
+
+ public void execute( MavenSession session, List<MojoExecution> mojoExecutions, ProjectIndex projectIndex )
+ throws LifecycleExecutionException
+
+ {
+ DependencyContext dependencyContext = newDependencyContext( session, mojoExecutions );
+
+ PhaseRecorder phaseRecorder = new PhaseRecorder( session.getCurrentProject() );
+
+ for ( MojoExecution mojoExecution : mojoExecutions )
+ {
+ execute( session, mojoExecution, projectIndex, dependencyContext, phaseRecorder );
+ }
+ }
+
+ public void execute( MavenSession session, MojoExecution mojoExecution, ProjectIndex projectIndex,
+ DependencyContext dependencyContext, PhaseRecorder phaseRecorder )
+ throws LifecycleExecutionException
+ {
+ execute( session, mojoExecution, projectIndex, dependencyContext );
+ phaseRecorder.observeExecution( mojoExecution );
+ }
+
+ private void execute( MavenSession session, MojoExecution mojoExecution, ProjectIndex projectIndex,
+ DependencyContext dependencyContext )
+ throws LifecycleExecutionException
+ {
+ MojoDescriptor mojoDescriptor = mojoExecution.getMojoDescriptor();
+
+ try
+ {
+ mavenPluginManager.checkRequiredMavenVersion( mojoDescriptor.getPluginDescriptor() );
+ }
+ catch ( PluginIncompatibleException e )
+ {
+ throw new LifecycleExecutionException( mojoExecution, session.getCurrentProject(), e );
+ }
+
+ if ( mojoDescriptor.isProjectRequired() && !session.getRequest().isProjectPresent() )
+ {
+ Throwable cause =
+ new MissingProjectException( "Goal requires a project to execute"
+ + " but there is no POM in this directory (" + session.getExecutionRootDirectory() + ")."
+ + " Please verify you invoked Maven from the correct directory." );
+ throw new LifecycleExecutionException( mojoExecution, null, cause );
+ }
+
+ if ( mojoDescriptor.isOnlineRequired() && session.isOffline() )
+ {
+ if ( MojoExecution.Source.CLI.equals( mojoExecution.getSource() ) )
+ {
+ Throwable cause =
+ new IllegalStateException( "Goal requires online mode for execution"
+ + " but Maven is currently offline." );
+ throw new LifecycleExecutionException( mojoExecution, session.getCurrentProject(), cause );
+ }
+ else
+ {
+ eventCatapult.fire( ExecutionEvent.Type.MojoSkipped, session, mojoExecution );
+
+ return;
+ }
+ }
+
+ List<MavenProject> forkedProjects = executeForkedExecutions( mojoExecution, session, projectIndex );
+
+ ensureDependenciesAreResolved( mojoDescriptor, session, dependencyContext );
+
+ eventCatapult.fire( ExecutionEvent.Type.MojoStarted, session, mojoExecution );
+
+ try
+ {
+ try
+ {
+ pluginManager.executeMojo( session, mojoExecution );
+ }
+ catch ( MojoFailureException e )
+ {
+ throw new LifecycleExecutionException( mojoExecution, session.getCurrentProject(), e );
+ }
+ catch ( MojoExecutionException e )
+ {
+ throw new LifecycleExecutionException( mojoExecution, session.getCurrentProject(), e );
+ }
+ catch ( PluginConfigurationException e )
+ {
+ throw new LifecycleExecutionException( mojoExecution, session.getCurrentProject(), e );
+ }
+ catch ( PluginManagerException e )
+ {
+ throw new LifecycleExecutionException( mojoExecution, session.getCurrentProject(), e );
+ }
+
+ eventCatapult.fire( ExecutionEvent.Type.MojoSucceeded, session, mojoExecution );
+ }
+ catch ( LifecycleExecutionException e )
+ {
+ eventCatapult.fire( ExecutionEvent.Type.MojoFailed, session, mojoExecution, e );
+
+ throw e;
+ }
+ finally
+ {
+ for ( MavenProject forkedProject : forkedProjects )
+ {
+ forkedProject.setExecutionProject( null );
+ }
+ }
+ }
+
+ public void ensureDependenciesAreResolved( MojoDescriptor mojoDescriptor, MavenSession session,
+ DependencyContext dependencyContext )
+ throws LifecycleExecutionException
+
+ {
+ MavenProject project = dependencyContext.getProject();
+ boolean aggregating = mojoDescriptor.isAggregator();
+
+ if ( dependencyContext.isResolutionRequiredForCurrentProject() )
+ {
+ Collection<String> scopesToCollect = dependencyContext.getScopesToCollectForCurrentProject();
+ Collection<String> scopesToResolve = dependencyContext.getScopesToResolveForCurrentProject();
+
+ lifeCycleDependencyResolver.resolveProjectDependencies( project, scopesToCollect, scopesToResolve, session,
+ aggregating, Collections.<Artifact>emptySet() );
+
+ dependencyContext.synchronizeWithProjectState();
+ }
+
+ if ( aggregating )
+ {
+ Collection<String> scopesToCollect = toScopes( mojoDescriptor.getDependencyCollectionRequired() );
+ Collection<String> scopesToResolve = toScopes( mojoDescriptor.getDependencyResolutionRequired() );
+
+ if ( dependencyContext.isResolutionRequiredForAggregatedProjects( scopesToCollect, scopesToResolve ) )
+ {
+ for ( MavenProject aggregatedProject : session.getProjects() )
+ {
+ if ( aggregatedProject != project )
+ {
+ lifeCycleDependencyResolver.resolveProjectDependencies( aggregatedProject, scopesToCollect,
+ scopesToResolve, session, aggregating,
+ Collections.<Artifact>emptySet() );
+ }
+ }
+ }
+ }
+
+ ArtifactFilter artifactFilter = getArtifactFilter( mojoDescriptor );
+ List<MavenProject> projectsToResolve =
+ LifecycleDependencyResolver.getProjects( session.getCurrentProject(), session,
+ mojoDescriptor.isAggregator() );
+ for ( MavenProject projectToResolve : projectsToResolve )
+ {
+ projectToResolve.setArtifactFilter( artifactFilter );
+ }
+ }
+
+ private ArtifactFilter getArtifactFilter( MojoDescriptor mojoDescriptor )
+ {
+ String scopeToResolve = mojoDescriptor.getDependencyResolutionRequired();
+ String scopeToCollect = mojoDescriptor.getDependencyCollectionRequired();
+
+ List<String> scopes = new ArrayList<String>( 2 );
+ if ( StringUtils.isNotEmpty( scopeToCollect ) )
+ {
+ scopes.add( scopeToCollect );
+ }
+ if ( StringUtils.isNotEmpty( scopeToResolve ) )
+ {
+ scopes.add( scopeToResolve );
+ }
+
+ if ( scopes.isEmpty() )
+ {
+ return null;
+ }
+ else
+ {
+ return new CumulativeScopeArtifactFilter( scopes );
+ }
+ }
+
+ public List<MavenProject> executeForkedExecutions( MojoExecution mojoExecution, MavenSession session,
+ ProjectIndex projectIndex )
+ throws LifecycleExecutionException
+ {
+ List<MavenProject> forkedProjects = Collections.emptyList();
+
+ Map<String, List<MojoExecution>> forkedExecutions = mojoExecution.getForkedExecutions();
+
+ if ( !forkedExecutions.isEmpty() )
+ {
+ eventCatapult.fire( ExecutionEvent.Type.ForkStarted, session, mojoExecution );
+
+ MavenProject project = session.getCurrentProject();
+
+ forkedProjects = new ArrayList<MavenProject>( forkedExecutions.size() );
+
+ try
+ {
+ for ( Map.Entry<String, List<MojoExecution>> fork : forkedExecutions.entrySet() )
+ {
+ String projectId = fork.getKey();
+
+ int index = projectIndex.getIndices().get( projectId );
+
+ MavenProject forkedProject = projectIndex.getProjects().get( projectId );
+
+ forkedProjects.add( forkedProject );
+
+ MavenProject executedProject = forkedProject.clone();
+
+ forkedProject.setExecutionProject( executedProject );
+
+ List<MojoExecution> mojoExecutions = fork.getValue();
+
+ if ( mojoExecutions.isEmpty() )
+ {
+ continue;
+ }
+
+ try
+ {
+ session.setCurrentProject( executedProject );
+ session.getProjects().set( index, executedProject );
+ projectIndex.getProjects().put( projectId, executedProject );
+
+ eventCatapult.fire( ExecutionEvent.Type.ForkedProjectStarted, session, mojoExecution );
+
+ execute( session, mojoExecutions, projectIndex );
+
+ eventCatapult.fire( ExecutionEvent.Type.ForkedProjectSucceeded, session, mojoExecution );
+ }
+ catch ( LifecycleExecutionException e )
+ {
+ eventCatapult.fire( ExecutionEvent.Type.ForkedProjectFailed, session, mojoExecution, e );
+
+ throw e;
+ }
+ finally
+ {
+ projectIndex.getProjects().put( projectId, forkedProject );
+ session.getProjects().set( index, forkedProject );
+ session.setCurrentProject( project );
+ }
+ }
+
+ eventCatapult.fire( ExecutionEvent.Type.ForkSucceeded, session, mojoExecution );
+ }
+ catch ( LifecycleExecutionException e )
+ {
+ eventCatapult.fire( ExecutionEvent.Type.ForkFailed, session, mojoExecution, e );
+
+ throw e;
+ }
+ }
+
+ return forkedProjects;
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/PhaseRecorder.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/PhaseRecorder.java
new file mode 100644
index 00000000..a09a3cb9
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/PhaseRecorder.java
@@ -0,0 +1,78 @@
+package org.apache.maven.lifecycle.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.plugin.MojoExecution;
+import org.apache.maven.project.MavenProject;
+
+/**
+ * @since 3.0
+ * @author Benjamin Bentmann
+ * @author Kristian Rosenvold
+ * <p/>
+ * NOTE: This class is not part of any public api and can be changed or deleted without prior notice.
+ */
+public class PhaseRecorder
+{
+ private String lastLifecyclePhase;
+
+ private final MavenProject project;
+
+ public PhaseRecorder( MavenProject project )
+ {
+ this.project = project;
+ }
+
+ public void observeExecution( MojoExecution mojoExecution )
+ {
+ String lifecyclePhase = mojoExecution.getLifecyclePhase();
+
+ if ( lifecyclePhase != null )
+ {
+ if ( lastLifecyclePhase == null )
+ {
+ lastLifecyclePhase = lifecyclePhase;
+ }
+ else if ( !lifecyclePhase.equals( lastLifecyclePhase ) )
+ {
+ project.addLifecyclePhase( lastLifecyclePhase );
+ lastLifecyclePhase = lifecyclePhase;
+ }
+ }
+
+ if ( lastLifecyclePhase != null )
+ {
+ project.addLifecyclePhase( lastLifecyclePhase );
+ }
+ }
+
+ public boolean isDifferentPhase( MojoExecution nextMojoExecution )
+ {
+ String lifecyclePhase = nextMojoExecution.getLifecyclePhase();
+ if ( lifecyclePhase == null )
+ {
+ return lastLifecyclePhase != null;
+ }
+ return !lifecyclePhase.equals( lastLifecyclePhase );
+
+ }
+
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/ProjectArtifactFactory.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/ProjectArtifactFactory.java
new file mode 100644
index 00000000..b4a81075
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/ProjectArtifactFactory.java
@@ -0,0 +1,38 @@
+package org.apache.maven.lifecycle.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Set;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.project.artifact.InvalidDependencyVersionException;
+
+/**
+ * Component interface responsible for creation of MavenProject#dependencyArtifacts instances.
+ *
+ * @since 3.2.4
+ * @provisional This interface is part of work in progress and can be changed or removed without notice.
+ */
+public interface ProjectArtifactFactory
+{
+ Set<Artifact> createArtifacts( MavenProject project )
+ throws InvalidDependencyVersionException;
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/ProjectBuildList.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/ProjectBuildList.java
new file mode 100644
index 00000000..6c8fd50a
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/ProjectBuildList.java
@@ -0,0 +1,158 @@
+package org.apache.maven.lifecycle.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.maven.artifact.ArtifactUtils;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.project.MavenProject;
+
+/**
+ * A list of project segments, ordered so that all ProjectSegments from first TaskSegment come before any
+ * subsequent TaskSegments.
+ *
+ * @since 3.0
+ * @author Kristian Rosenvold
+ * <p/>
+ * NOTE: This class is not part of any public api and can be changed or deleted without prior notice.
+ */
+public class ProjectBuildList
+ implements Iterable<ProjectSegment>
+{
+ private final List<ProjectSegment> items;
+
+ public ProjectBuildList( List<ProjectSegment> items )
+ {
+ this.items = Collections.unmodifiableList( items );
+ }
+
+ // TODO: Optimize; or maybe just rewrite the whole way aggregating mojos are being run.
+ /**
+ * Returns aProjectBuildList that contains only items for the specified taskSegment
+ * @param taskSegment the requested tasksegment
+ * @return a project build list for the supplied task segment
+ */
+ public ProjectBuildList getByTaskSegment( TaskSegment taskSegment )
+ {
+ List<ProjectSegment> currentSegment = new ArrayList<ProjectSegment>();
+ for ( ProjectSegment projectBuild : items )
+ {
+ if ( taskSegment == projectBuild.getTaskSegment() )
+ { // NOTE: There's no notion of taskSegment equality.
+ currentSegment.add( projectBuild );
+ }
+ }
+ return new ProjectBuildList( currentSegment );
+ }
+
+ public Map<MavenProject, ProjectSegment> selectSegment( TaskSegment taskSegment )
+ {
+ Map<MavenProject, ProjectSegment> result = new HashMap<MavenProject, ProjectSegment>();
+ for ( ProjectSegment projectBuild : items )
+ {
+ if ( taskSegment == projectBuild.getTaskSegment() )
+ { // NOTE: There's no notion of taskSegment equality.
+ result.put( projectBuild.getProject(), projectBuild );
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Finds the first ProjectSegment matching the supplied project
+ * @param mavenProject the requested project
+ * @return The projectSegment or null.
+ */
+ public ProjectSegment findByMavenProject( MavenProject mavenProject )
+ {
+ for ( ProjectSegment projectBuild : items )
+ {
+ if ( mavenProject.equals( projectBuild.getProject() ) )
+ {
+ return projectBuild;
+ }
+ }
+ return null;
+ }
+
+ public Iterator<ProjectSegment> iterator()
+ {
+ return items.iterator();
+ }
+
+ public void closeAll()
+ {
+ for ( ProjectSegment item : items )
+ {
+ MavenSession sessionForThisModule = item.getSession();
+ sessionForThisModule.setCurrentProject( null );
+ }
+ }
+
+ public int size()
+ {
+ return items.size();
+ }
+
+ public ProjectSegment get( int index )
+ {
+ return items.get( index );
+ }
+
+ public Set<String> getReactorProjectKeys()
+ {
+ Set<String> projectKeys = new HashSet<String>( items.size() * 2 );
+ for ( ProjectSegment projectBuild : items )
+ {
+ MavenProject project = projectBuild.getProject();
+ String key = ArtifactUtils.key( project.getGroupId(), project.getArtifactId(), project.getVersion() );
+ projectKeys.add( key );
+ }
+ return projectKeys;
+ }
+
+
+ public boolean isEmpty()
+ {
+ return items.isEmpty();
+ }
+
+ /**
+ * @return a set of all the projects managed by the build
+ */
+ public Set<MavenProject> getProjects()
+ {
+ Set<MavenProject> projects = new HashSet<MavenProject>();
+
+ for ( ProjectSegment s : items )
+ {
+ projects.add( s.getProject() );
+ }
+ return projects;
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/ProjectIndex.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/ProjectIndex.java
new file mode 100644
index 00000000..b1b1d186
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/ProjectIndex.java
@@ -0,0 +1,70 @@
+package org.apache.maven.lifecycle.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.lifecycle.internal.builder.BuilderCommon;
+import org.apache.maven.project.MavenProject;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Provides the positional index of the project
+ *
+ * @since 3.0
+ * @author Benjamin Bentmann
+ * @author Kristian Rosenvold (extracted class only)
+ * <p/>
+ * NOTE: This class is not part of any public api and can be changed or deleted without prior notice.
+ */
+// Todo: Kristian wonders if this class really is necessary and if it overlaps other concepts.
+public final class ProjectIndex
+{
+
+ private final Map<String, MavenProject> projects;
+
+ private final Map<String, Integer> indices;
+
+ public ProjectIndex( List<MavenProject> projects )
+ {
+ this.projects = new HashMap<String, MavenProject>( projects.size() * 2 );
+ this.indices = new HashMap<String, Integer>( projects.size() * 2 );
+
+ for ( int i = 0; i < projects.size(); i++ )
+ {
+ MavenProject project = projects.get( i );
+ String key = BuilderCommon.getKey( project );
+
+ this.getProjects().put( key, project );
+ this.getIndices().put( key, i );
+ }
+ }
+
+ public Map<String, MavenProject> getProjects()
+ {
+ return projects;
+ }
+
+ public Map<String, Integer> getIndices()
+ {
+ return indices;
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/ProjectSegment.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/ProjectSegment.java
new file mode 100644
index 00000000..5ef77454
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/ProjectSegment.java
@@ -0,0 +1,106 @@
+package org.apache.maven.lifecycle.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.execution.ProjectDependencyGraph;
+import org.apache.maven.project.MavenProject;
+
+import java.util.List;
+
+/**
+ * A build context that matches a mavenproject to a given tasksegment, and the session to be used.
+ * <p/>
+ * A note to the reader;
+ * <p/>
+ * There are several issues/discussions regarding how "aggregator" plugins should be handled.
+ * Read for instance http://docs.codehaus.org/display/MAVEN/Deterministic+Lifecycle+Planning
+ * <p/>
+ * In their current implementation they are "bolted" onto the lifecycle by separating them
+ * into TaskSegments. This class represents the execution context of one such task segment.
+ * <p/>
+ * Wise voices have suggested that maybe aggregators shouldn't be bound to the ordinary
+ * lifecycle at all, in which case we wouldn't be needing this class at all ( and
+ * ProjectBuildList.getByTaskSegments). Or maybe they should be introduced in the calculation
+ * of the execution plan instead, which seems much nicer.
+ * <p/>
+ * Additionally this class contains a clone of the MavenSession, which is *only* needed
+ * because it has as notion of a "current" project.
+ *
+ * @since 3.0
+ * @author Jason van Zyl
+ * @author Benjamin Bentmann
+ * @author Kristian Rosenvold
+ * <p/>
+ * NOTE: This class is not part of any public api and can be changed or deleted without prior notice.
+ */
+public final class ProjectSegment
+{
+ private final MavenProject project;
+
+ private final TaskSegment taskSegment;
+
+ private final MavenSession session;
+
+ private final List<MavenProject> nonTransitiveUpstreamProjects;
+
+ private final List<MavenProject> transitiveUpstreamProjects;
+
+ public ProjectSegment( MavenProject project, TaskSegment taskSegment, MavenSession copiedSession )
+ {
+ this.project = project;
+ this.taskSegment = taskSegment;
+ this.session = copiedSession;
+ final ProjectDependencyGraph dependencyGraph = getSession().getProjectDependencyGraph();
+ nonTransitiveUpstreamProjects = dependencyGraph.getUpstreamProjects( getProject(), false );
+ transitiveUpstreamProjects = dependencyGraph.getUpstreamProjects( getProject(), true );
+ }
+
+ public MavenSession getSession()
+ {
+ return session;
+ }
+
+ public MavenProject getProject()
+ {
+ return project;
+ }
+
+ public TaskSegment getTaskSegment()
+ {
+ return taskSegment;
+ }
+
+ public List<MavenProject> getImmediateUpstreamProjects()
+ {
+ return nonTransitiveUpstreamProjects;
+ }
+
+ public List<MavenProject> getTransitiveUpstreamProjects()
+ {
+ return transitiveUpstreamProjects;
+ }
+
+ @Override
+ public String toString()
+ {
+ return getProject().getId() + " -> " + getTaskSegment();
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/ReactorBuildStatus.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/ReactorBuildStatus.java
new file mode 100644
index 00000000..2e2c3fd4
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/ReactorBuildStatus.java
@@ -0,0 +1,80 @@
+package org.apache.maven.lifecycle.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.execution.ProjectDependencyGraph;
+import org.apache.maven.lifecycle.internal.builder.BuilderCommon;
+import org.apache.maven.project.MavenProject;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+
+/**
+ * Contains status information that is global to an entire reactor build.
+ *
+ * @since 3.0
+ * @author <a href="mailto:kristian.rosenvold@gmail.com">Kristian Rosenvold</a>
+ */
+public class ReactorBuildStatus
+{
+ private final ProjectDependencyGraph projectDependencyGraph;
+
+ private final Collection<String> blackListedProjects = Collections.synchronizedSet( new HashSet<String>() );
+
+ private volatile boolean halted = false;
+
+ public ReactorBuildStatus( ProjectDependencyGraph projectDependencyGraph )
+ {
+ this.projectDependencyGraph = projectDependencyGraph;
+ }
+
+ public boolean isBlackListed( MavenProject project )
+ {
+ return blackListedProjects.contains( BuilderCommon.getKey( project ) );
+ }
+
+ public void blackList( MavenProject project )
+ {
+ if ( blackListedProjects.add( BuilderCommon.getKey( project ) ) && projectDependencyGraph != null )
+ {
+ for ( MavenProject downstreamProject : projectDependencyGraph.getDownstreamProjects( project, true ) )
+ {
+ blackListedProjects.add( BuilderCommon.getKey( downstreamProject ) );
+ }
+ }
+ }
+
+ public void halt()
+ {
+ halted = true;
+ }
+
+ public boolean isHalted()
+ {
+ return halted;
+ }
+
+ public boolean isHaltedOrBlacklisted( MavenProject mavenProject )
+ {
+ return isBlackListed( mavenProject ) || isHalted();
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/ReactorContext.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/ReactorContext.java
new file mode 100644
index 00000000..7df53140
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/ReactorContext.java
@@ -0,0 +1,83 @@
+package org.apache.maven.lifecycle.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.execution.MavenExecutionResult;
+import org.apache.maven.session.scope.internal.SessionScope;
+
+/**
+ * Context that is fixed for the entire reactor build.
+ *
+ * @since 3.0
+ * @author Jason van Zyl
+ * @author Kristian Rosenvold
+ * NOTE: This class is not part of any public api and can be changed or deleted without prior notice.
+ */
+public class ReactorContext
+{
+ private final MavenExecutionResult result;
+
+ private final ProjectIndex projectIndex;
+
+ private final ClassLoader originalContextClassLoader;
+
+ private final ReactorBuildStatus reactorBuildStatus;
+
+ private final SessionScope.Memento sessionScope;
+
+ public ReactorContext( MavenExecutionResult result, ProjectIndex projectIndex,
+ ClassLoader originalContextClassLoader, ReactorBuildStatus reactorBuildStatus,
+ SessionScope.Memento sessionScope )
+ {
+ this.result = result;
+ this.projectIndex = projectIndex;
+ this.originalContextClassLoader = originalContextClassLoader;
+ this.reactorBuildStatus = reactorBuildStatus;
+ this.sessionScope = sessionScope;
+ }
+
+ public ReactorBuildStatus getReactorBuildStatus()
+ {
+ return reactorBuildStatus;
+ }
+
+ public MavenExecutionResult getResult()
+ {
+ return result;
+ }
+
+ public ProjectIndex getProjectIndex()
+ {
+ return projectIndex;
+ }
+
+ public ClassLoader getOriginalContextClassLoader()
+ {
+ return originalContextClassLoader;
+ }
+
+ /**
+ * @since 3.3.0
+ */
+ public SessionScope.Memento getSessionScopeMemento()
+ {
+ return sessionScope;
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/TaskSegment.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/TaskSegment.java
new file mode 100644
index 00000000..9551887c
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/TaskSegment.java
@@ -0,0 +1,73 @@
+package org.apache.maven.lifecycle.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Describes the required task segment as provided on the maven command line; i.e. "clean jetty:run install"
+ *
+ * @since 3.0
+ * @author Benjamin Bentmann
+ * @author Kristian Rosenvold (extracted class only)
+ * <p/>
+ * NOTE: This class is not part of any public api and can be changed or deleted without prior notice.
+ */
+public final class TaskSegment
+{
+
+ // Can be both "LifeCycleTask" (clean/install) and "GoalTask" (org.mortbay.jetty:maven-jetty-plugin:6.1.19:run)
+
+ private final List<Object> tasks;
+
+ private final boolean aggregating;
+
+ public TaskSegment( boolean aggregating )
+ {
+ this.aggregating = aggregating;
+ tasks = new ArrayList<Object>();
+ }
+
+ public TaskSegment( boolean aggregating, Object... tasks )
+ {
+ this.aggregating = aggregating;
+ this.tasks = new ArrayList<Object>( Arrays.asList( tasks ) );
+ }
+
+ @Override
+ public String toString()
+ {
+ return getTasks().toString();
+ }
+
+ public List<Object> getTasks()
+ {
+ return tasks;
+ }
+
+ public boolean isAggregating()
+ {
+ return aggregating;
+ }
+
+ // TODO: Consider throwing UnsupprtedSomething on hashCode/equals
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/builder/Builder.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/builder/Builder.java
new file mode 100644
index 00000000..155abf92
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/builder/Builder.java
@@ -0,0 +1,47 @@
+package org.apache.maven.lifecycle.internal.builder;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.List;
+import java.util.concurrent.ExecutionException;
+
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.lifecycle.internal.ProjectBuildList;
+import org.apache.maven.lifecycle.internal.ReactorBuildStatus;
+import org.apache.maven.lifecycle.internal.ReactorContext;
+import org.apache.maven.lifecycle.internal.TaskSegment;
+
+/**
+ * A {@link Builder} encapsulates a strategy for building a set of Maven projects. The default strategy in Maven builds
+ * the the projects serially, but a {@link Builder} can employ any type of concurrency model to build the projects.
+ *
+ * @author jvanzyl
+ * @provisional
+ */
+public interface Builder
+{
+ //
+ // Be nice to whittle this down to Session, maybe add task segments to the session. The session really is the
+ // the place to store reactor related information.
+ //
+ void build( MavenSession session, ReactorContext reactorContext, ProjectBuildList projectBuilds,
+ List<TaskSegment> taskSegments, ReactorBuildStatus reactorBuildStatus )
+ throws ExecutionException, InterruptedException;
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/builder/BuilderCommon.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/builder/BuilderCommon.java
new file mode 100644
index 00000000..34fb323e
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/builder/BuilderCommon.java
@@ -0,0 +1,199 @@
+package org.apache.maven.lifecycle.internal.builder;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.execution.BuildFailure;
+import org.apache.maven.execution.ExecutionEvent;
+import org.apache.maven.execution.MavenExecutionRequest;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.lifecycle.LifecycleExecutionException;
+import org.apache.maven.lifecycle.LifecycleNotFoundException;
+import org.apache.maven.lifecycle.LifecyclePhaseNotFoundException;
+import org.apache.maven.lifecycle.MavenExecutionPlan;
+import org.apache.maven.lifecycle.internal.ExecutionEventCatapult;
+import org.apache.maven.lifecycle.internal.LifecycleDebugLogger;
+import org.apache.maven.lifecycle.internal.LifecycleExecutionPlanCalculator;
+import org.apache.maven.lifecycle.internal.ReactorContext;
+import org.apache.maven.lifecycle.internal.TaskSegment;
+import org.apache.maven.model.Plugin;
+import org.apache.maven.plugin.InvalidPluginDescriptorException;
+import org.apache.maven.plugin.MojoNotFoundException;
+import org.apache.maven.plugin.PluginDescriptorParsingException;
+import org.apache.maven.plugin.PluginNotFoundException;
+import org.apache.maven.plugin.PluginResolutionException;
+import org.apache.maven.plugin.descriptor.MojoDescriptor;
+import org.apache.maven.plugin.prefix.NoPluginFoundForPrefixException;
+import org.apache.maven.plugin.version.PluginVersionResolutionException;
+import org.apache.maven.project.MavenProject;
+import org.codehaus.plexus.classworlds.realm.ClassRealm;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+import org.codehaus.plexus.logging.Logger;
+
+import java.util.Set;
+
+/**
+ * Common code that is shared by the LifecycleModuleBuilder and the LifeCycleWeaveBuilder
+ *
+ * @since 3.0
+ * @author Kristian Rosenvold
+ * Builds one or more lifecycles for a full module
+ * NOTE: This class is not part of any public api and can be changed or deleted without prior notice.
+ */
+@Component( role = BuilderCommon.class )
+public class BuilderCommon
+{
+ @Requirement
+ private LifecycleDebugLogger lifecycleDebugLogger;
+
+ @Requirement
+ private LifecycleExecutionPlanCalculator lifeCycleExecutionPlanCalculator;
+
+ @Requirement
+ private ExecutionEventCatapult eventCatapult;
+
+ @Requirement
+ private Logger logger;
+
+
+ public BuilderCommon()
+ {
+ }
+
+ public BuilderCommon( LifecycleDebugLogger lifecycleDebugLogger,
+ LifecycleExecutionPlanCalculator lifeCycleExecutionPlanCalculator, Logger logger )
+ {
+ this.lifecycleDebugLogger = lifecycleDebugLogger;
+ this.lifeCycleExecutionPlanCalculator = lifeCycleExecutionPlanCalculator;
+ this.logger = logger;
+ }
+
+ public MavenExecutionPlan resolveBuildPlan( MavenSession session, MavenProject project, TaskSegment taskSegment,
+ Set<Artifact> projectArtifacts )
+ throws PluginNotFoundException, PluginResolutionException, LifecyclePhaseNotFoundException,
+ PluginDescriptorParsingException, MojoNotFoundException, InvalidPluginDescriptorException,
+ NoPluginFoundForPrefixException, LifecycleNotFoundException, PluginVersionResolutionException,
+ LifecycleExecutionException
+ {
+ MavenExecutionPlan executionPlan =
+ lifeCycleExecutionPlanCalculator.calculateExecutionPlan( session, project, taskSegment.getTasks() );
+
+ lifecycleDebugLogger.debugProjectPlan( project, executionPlan );
+
+ if ( session.getRequest().getDegreeOfConcurrency() > 1 )
+ {
+ final Set<Plugin> unsafePlugins = executionPlan.getNonThreadSafePlugins();
+ if ( !unsafePlugins.isEmpty() && logger.isDebugEnabled() )
+ {
+ logger.warn( "*****************************************************************" );
+ logger.warn( "* Your build is requesting parallel execution, but project *" );
+ logger.warn( "* contains the following plugin(s) that have goals not marked *" );
+ logger.warn( "* as @threadSafe to support parallel building. *" );
+ logger.warn( "* While this /may/ work fine, please look for plugin updates *" );
+ logger.warn( "* and/or request plugins be made thread-safe. *" );
+ logger.warn( "* If reporting an issue, report it against the plugin in *" );
+ logger.warn( "* question, not against maven-core *" );
+ logger.warn( "*****************************************************************" );
+ if ( logger.isDebugEnabled() )
+ {
+ final Set<MojoDescriptor> unsafeGoals = executionPlan.getNonThreadSafeMojos();
+ logger.warn( "The following goals are not marked @threadSafe in " + project.getName() + ":" );
+ for ( MojoDescriptor unsafeGoal : unsafeGoals )
+ {
+ logger.warn( unsafeGoal.getId() );
+ }
+ }
+ else
+ {
+ logger.warn( "The following plugins are not marked @threadSafe in " + project.getName() + ":" );
+ for ( Plugin unsafePlugin : unsafePlugins )
+ {
+ logger.warn( unsafePlugin.getId() );
+ }
+ logger.warn( "Enable debug to see more precisely which goals are not marked @threadSafe." );
+ }
+ logger.warn( "*****************************************************************" );
+ }
+ }
+
+ return executionPlan;
+ }
+
+ public void handleBuildError( final ReactorContext buildContext, final MavenSession rootSession,
+ final MavenSession currentSession, final MavenProject mavenProject, Throwable t,
+ final long buildStartTime )
+ {
+ // record the error and mark the project as failed
+ long buildEndTime = System.currentTimeMillis();
+ buildContext.getResult().addException( t );
+ buildContext.getResult().addBuildSummary( new BuildFailure( mavenProject, buildEndTime - buildStartTime, t ) );
+
+ // notify listeners about "soft" project build failures only
+ if ( t instanceof Exception && !( t instanceof RuntimeException ) )
+ {
+ eventCatapult.fire( ExecutionEvent.Type.ProjectFailed, currentSession, null, (Exception) t );
+ }
+
+ // reactor failure modes
+ if ( t instanceof RuntimeException || !( t instanceof Exception ) )
+ {
+ // fail fast on RuntimeExceptions, Errors and "other" Throwables
+ // assume these are system errors and further build is meaningless
+ buildContext.getReactorBuildStatus().halt();
+ }
+ else if ( MavenExecutionRequest.REACTOR_FAIL_NEVER.equals( rootSession.getReactorFailureBehavior() ) )
+ {
+ // continue the build
+ }
+ else if ( MavenExecutionRequest.REACTOR_FAIL_AT_END.equals( rootSession.getReactorFailureBehavior() ) )
+ {
+ // continue the build but ban all projects that depend on the failed one
+ buildContext.getReactorBuildStatus().blackList( mavenProject );
+ }
+ else if ( MavenExecutionRequest.REACTOR_FAIL_FAST.equals( rootSession.getReactorFailureBehavior() ) )
+ {
+ buildContext.getReactorBuildStatus().halt();
+ }
+ else
+ {
+ logger.error( "invalid reactor failure behavior " + rootSession.getReactorFailureBehavior() );
+ buildContext.getReactorBuildStatus().halt();
+ }
+ }
+
+ public static void attachToThread( MavenProject currentProject )
+ {
+ ClassRealm projectRealm = currentProject.getClassRealm();
+ if ( projectRealm != null )
+ {
+ Thread.currentThread().setContextClassLoader( projectRealm );
+ }
+ }
+
+ // Todo: I'm really wondering where this method belongs; smells like it should be on MavenProject, but for some
+ // reason it isn't ? This localization is kind-of a code smell.
+
+ public static String getKey( MavenProject project )
+ {
+ return project.getGroupId() + ':' + project.getArtifactId() + ':' + project.getVersion();
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/builder/BuilderNotFoundException.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/builder/BuilderNotFoundException.java
new file mode 100644
index 00000000..52c668f1
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/builder/BuilderNotFoundException.java
@@ -0,0 +1,29 @@
+package org.apache.maven.lifecycle.internal.builder;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+public class BuilderNotFoundException
+ extends Exception
+{
+ public BuilderNotFoundException( String message )
+ {
+ super( message );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/builder/multithreaded/ConcurrencyDependencyGraph.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/builder/multithreaded/ConcurrencyDependencyGraph.java
new file mode 100644
index 00000000..de6a5a31
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/builder/multithreaded/ConcurrencyDependencyGraph.java
@@ -0,0 +1,153 @@
+package org.apache.maven.lifecycle.internal.builder.multithreaded;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.execution.ProjectDependencyGraph;
+import org.apache.maven.lifecycle.internal.ProjectBuildList;
+import org.apache.maven.lifecycle.internal.ProjectSegment;
+import org.apache.maven.project.MavenProject;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Presents a view of the Dependency Graph that is suited for concurrent building.
+ *
+ * @since 3.0
+ * @author Kristian Rosenvold
+ * <p/>
+ * NOTE: This class is not part of any public api and can be changed or deleted without prior notice.
+ */
+public class ConcurrencyDependencyGraph
+{
+
+ private final ProjectBuildList projectBuilds;
+
+ private final ProjectDependencyGraph projectDependencyGraph;
+
+ private final HashSet<MavenProject> finishedProjects = new HashSet<MavenProject>();
+
+ public ConcurrencyDependencyGraph( ProjectBuildList projectBuilds, ProjectDependencyGraph projectDependencyGraph )
+ {
+ this.projectDependencyGraph = projectDependencyGraph;
+ this.projectBuilds = projectBuilds;
+ }
+
+ public int getNumberOfBuilds()
+ {
+ return projectBuilds.size();
+ }
+
+ /**
+ * Gets all the builds that have no reactor-dependencies
+ *
+ * @return A list of all the initial builds
+ */
+
+ public List<MavenProject> getRootSchedulableBuilds()
+ {
+ List<MavenProject> result = new ArrayList<MavenProject>();
+ for ( ProjectSegment projectBuild : projectBuilds )
+ {
+ if ( projectDependencyGraph.getUpstreamProjects( projectBuild.getProject(), false ).size() == 0 )
+ {
+ result.add( projectBuild.getProject() );
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Marks the provided project as finished. Returns a list of
+ *
+ * @param mavenProject The project
+ * @return The list of builds that are eligible for starting now that the provided project is done
+ */
+ public List<MavenProject> markAsFinished( MavenProject mavenProject )
+ {
+ finishedProjects.add( mavenProject );
+ return getSchedulableNewProcesses( mavenProject );
+ }
+
+ private List<MavenProject> getSchedulableNewProcesses( MavenProject finishedProject )
+ {
+ List<MavenProject> result = new ArrayList<MavenProject>();
+ // schedule dependent projects, if all of their requirements are met
+ for ( MavenProject dependentProject : projectDependencyGraph.getDownstreamProjects( finishedProject, false ) )
+ {
+ final List<MavenProject> upstreamProjects =
+ projectDependencyGraph.getUpstreamProjects( dependentProject, false );
+ if ( finishedProjects.containsAll( upstreamProjects ) )
+ {
+ result.add( dependentProject );
+ }
+ }
+ return result;
+ }
+
+ /**
+ * @return set of projects that have yet to be processed successfully by the build.
+ */
+ public Set<MavenProject> getUnfinishedProjects()
+ {
+ Set<MavenProject> unfinished = new HashSet<MavenProject>( projectBuilds.getProjects() );
+ unfinished.remove( finishedProjects );
+ return unfinished;
+ }
+
+ /**
+ * @return set of projects that have been successfully processed by the build.
+ */
+ protected Set<MavenProject> getFinishedProjects()
+ {
+ return finishedProjects;
+ }
+
+ protected ProjectBuildList getProjectBuilds()
+ {
+ return projectBuilds;
+ }
+
+ /**
+ * For the given {@link MavenProject} {@code p}, return all of {@code p}'s dependencies.
+ *
+ * @param p
+ * @return List of prerequisite projects
+ */
+ protected List<MavenProject> getDependencies( MavenProject p )
+ {
+ return projectDependencyGraph.getUpstreamProjects( p, false );
+ }
+
+ /**
+ * For the given {@link MavenProject} {@code p} return {@code p}'s uncompleted dependencies.
+ *
+ * @param p
+ * @return List of uncompleted prerequisite projects
+ */
+ public List<MavenProject> getActiveDependencies( MavenProject p )
+ {
+ List<MavenProject> activeDependencies = projectDependencyGraph.getUpstreamProjects( p, false );
+ activeDependencies.removeAll( finishedProjects );
+ return activeDependencies;
+ }
+} \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/builder/multithreaded/MultiThreadedBuilder.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/builder/multithreaded/MultiThreadedBuilder.java
new file mode 100644
index 00000000..906e5e75
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/builder/multithreaded/MultiThreadedBuilder.java
@@ -0,0 +1,197 @@
+package org.apache.maven.lifecycle.internal.builder.multithreaded;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Callable;
+import java.util.concurrent.CompletionService;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorCompletionService;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.lifecycle.internal.BuildThreadFactory;
+import org.apache.maven.lifecycle.internal.LifecycleModuleBuilder;
+import org.apache.maven.lifecycle.internal.ProjectBuildList;
+import org.apache.maven.lifecycle.internal.ProjectSegment;
+import org.apache.maven.lifecycle.internal.ReactorBuildStatus;
+import org.apache.maven.lifecycle.internal.ReactorContext;
+import org.apache.maven.lifecycle.internal.TaskSegment;
+import org.apache.maven.lifecycle.internal.builder.Builder;
+import org.apache.maven.project.MavenProject;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+import org.codehaus.plexus.logging.Logger;
+
+/**
+ * Builds the full lifecycle in weave-mode (phase by phase as opposed to project-by-project)
+ *
+ * @since 3.0
+ * @author Kristian Rosenvold
+ * Builds one or more lifecycles for a full module
+ * <p/>
+ * NOTE: This class is not part of any public api and can be changed or deleted without prior notice.
+ */
+@Component( role = Builder.class, hint = "multithreaded" )
+public class MultiThreadedBuilder
+ implements Builder
+{
+
+ @Requirement
+ private Logger logger;
+
+ @Requirement
+ private LifecycleModuleBuilder lifecycleModuleBuilder;
+
+
+ public MultiThreadedBuilder()
+ {
+ }
+
+ @Override
+ public void build( MavenSession session, ReactorContext reactorContext, ProjectBuildList projectBuilds,
+ List<TaskSegment> taskSegments, ReactorBuildStatus reactorBuildStatus )
+ throws ExecutionException, InterruptedException
+ {
+ ExecutorService executor =
+ Executors.newFixedThreadPool( Math.min( session.getRequest().getDegreeOfConcurrency(),
+ session.getProjects().size() ), new BuildThreadFactory() );
+ CompletionService<ProjectSegment> service = new ExecutorCompletionService<ProjectSegment>( executor );
+ ConcurrencyDependencyGraph analyzer =
+ new ConcurrencyDependencyGraph( projectBuilds, session.getProjectDependencyGraph() );
+
+ // Currently disabled
+ ThreadOutputMuxer muxer = null; // new ThreadOutputMuxer( analyzer.getProjectBuilds(), System.out );
+
+ for ( TaskSegment taskSegment : taskSegments )
+ {
+ Map<MavenProject, ProjectSegment> projectBuildMap = projectBuilds.selectSegment( taskSegment );
+ try
+ {
+ multiThreadedProjectTaskSegmentBuild( analyzer, reactorContext, session, service, taskSegment,
+ projectBuildMap, muxer );
+ if ( reactorContext.getReactorBuildStatus().isHalted() )
+ {
+ break;
+ }
+ }
+ catch ( Exception e )
+ {
+ session.getResult().addException( e );
+ break;
+ }
+
+ }
+ }
+
+ private void multiThreadedProjectTaskSegmentBuild( ConcurrencyDependencyGraph analyzer,
+ ReactorContext reactorContext, MavenSession rootSession,
+ CompletionService<ProjectSegment> service,
+ TaskSegment taskSegment,
+ Map<MavenProject, ProjectSegment> projectBuildList,
+ ThreadOutputMuxer muxer )
+ {
+
+ // schedule independent projects
+ for ( MavenProject mavenProject : analyzer.getRootSchedulableBuilds() )
+ {
+ ProjectSegment projectSegment = projectBuildList.get( mavenProject );
+ logger.debug( "Scheduling: " + projectSegment.getProject() );
+ Callable<ProjectSegment> cb =
+ createBuildCallable( rootSession, projectSegment, reactorContext, taskSegment, muxer );
+ service.submit( cb );
+ }
+
+ // for each finished project
+ for ( int i = 0; i < analyzer.getNumberOfBuilds(); i++ )
+ {
+ try
+ {
+ ProjectSegment projectBuild = service.take().get();
+ if ( reactorContext.getReactorBuildStatus().isHalted() )
+ {
+ break;
+ }
+ final List<MavenProject> newItemsThatCanBeBuilt =
+ analyzer.markAsFinished( projectBuild.getProject() );
+ for ( MavenProject mavenProject : newItemsThatCanBeBuilt )
+ {
+ ProjectSegment scheduledDependent = projectBuildList.get( mavenProject );
+ logger.debug( "Scheduling: " + scheduledDependent );
+ Callable<ProjectSegment> cb =
+ createBuildCallable( rootSession, scheduledDependent, reactorContext, taskSegment, muxer );
+ service.submit( cb );
+ }
+ }
+ catch ( InterruptedException e )
+ {
+ rootSession.getResult().addException( e );
+ break;
+ }
+ catch ( ExecutionException e )
+ {
+ // TODO MNG-5766 changes likely made this redundant
+ rootSession.getResult().addException( e );
+ break;
+ }
+ }
+
+ // cancel outstanding builds (if any) - this can happen if an exception is thrown in above block
+
+ Future<ProjectSegment> unprocessed;
+ while ( ( unprocessed = service.poll() ) != null )
+ {
+ try
+ {
+ unprocessed.get();
+ }
+ catch ( InterruptedException e )
+ {
+ throw new RuntimeException( e );
+ }
+ catch ( ExecutionException e )
+ {
+ throw new RuntimeException( e );
+ }
+ }
+ }
+
+ private Callable<ProjectSegment> createBuildCallable( final MavenSession rootSession,
+ final ProjectSegment projectBuild,
+ final ReactorContext reactorContext,
+ final TaskSegment taskSegment, final ThreadOutputMuxer muxer )
+ {
+ return new Callable<ProjectSegment>()
+ {
+ public ProjectSegment call()
+ {
+ // muxer.associateThreadWithProjectSegment( projectBuild );
+ lifecycleModuleBuilder.buildProject( projectBuild.getSession(), rootSession, reactorContext,
+ projectBuild.getProject(), taskSegment );
+ // muxer.setThisModuleComplete( projectBuild );
+
+ return projectBuild;
+ }
+ };
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/builder/multithreaded/ThreadOutputMuxer.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/builder/multithreaded/ThreadOutputMuxer.java
new file mode 100644
index 00000000..8f1f4932
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/builder/multithreaded/ThreadOutputMuxer.java
@@ -0,0 +1,477 @@
+package org.apache.maven.lifecycle.internal.builder.multithreaded;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.maven.lifecycle.internal.ProjectBuildList;
+import org.apache.maven.lifecycle.internal.ProjectSegment;
+
+/**
+ * @since 3.0
+ * @author Kristian Rosenvold
+ * <p/>
+ * NOTE: This class is not part of any public api and can be changed or deleted without prior notice.
+ * This class in particular may spontaneusly self-combust and be replaced by a plexus-compliant thread aware
+ * logger implementation at any time.
+ */
+@SuppressWarnings( { "SynchronizationOnLocalVariableOrMethodParameter" } )
+public class ThreadOutputMuxer
+{
+ private final Iterator<ProjectSegment> projects;
+
+ private final ThreadLocal<ProjectSegment> projectBuildThreadLocal = new ThreadLocal<ProjectSegment>();
+
+ private final Map<ProjectSegment, ByteArrayOutputStream> streams =
+ new HashMap<ProjectSegment, ByteArrayOutputStream>();
+
+ private final Map<ProjectSegment, PrintStream> printStreams = new HashMap<ProjectSegment, PrintStream>();
+
+ private final ByteArrayOutputStream defaultOutputStreamForUnknownData = new ByteArrayOutputStream();
+
+ private final PrintStream defaultPringStream = new PrintStream( defaultOutputStreamForUnknownData );
+
+ private final Set<ProjectSegment> completedBuilds = Collections.synchronizedSet( new HashSet<ProjectSegment>() );
+
+ private volatile ProjectSegment currentBuild;
+
+ private final PrintStream originalSystemOUtStream;
+
+ private final ConsolePrinter printer;
+
+ /**
+ * A simple but safe solution for printing to the console.
+ */
+
+ class ConsolePrinter
+ implements Runnable
+ {
+ public volatile boolean running;
+
+ private final ProjectBuildList projectBuildList;
+
+ ConsolePrinter( ProjectBuildList projectBuildList )
+ {
+ this.projectBuildList = projectBuildList;
+ }
+
+ public void run()
+ {
+ running = true;
+ for ( ProjectSegment projectBuild : projectBuildList )
+ {
+ final PrintStream projectStream = printStreams.get( projectBuild );
+ ByteArrayOutputStream projectOs = streams.get( projectBuild );
+
+ do
+ {
+ synchronized ( projectStream )
+ {
+ try
+ {
+ projectStream.wait( 100 );
+ }
+ catch ( InterruptedException e )
+ {
+ throw new RuntimeException( e );
+ }
+ try
+ {
+ projectOs.writeTo( originalSystemOUtStream );
+ }
+ catch ( IOException e )
+ {
+ throw new RuntimeException( e );
+ }
+
+ projectOs.reset();
+ }
+ }
+ while ( !completedBuilds.contains( projectBuild ) );
+ }
+ running = false;
+ }
+
+ /*
+ Wait until we are sure the print-stream thread is running.
+ */
+
+ public void waitUntilRunning( boolean expect )
+ {
+ while ( !running == expect )
+ {
+ try
+ {
+ Thread.sleep( 10 );
+ }
+ catch ( InterruptedException e )
+ {
+ throw new RuntimeException( e );
+ }
+ }
+ }
+ }
+
+ public ThreadOutputMuxer( ProjectBuildList segmentChunks, PrintStream originalSystemOut )
+ {
+ projects = segmentChunks.iterator();
+ for ( ProjectSegment segmentChunk : segmentChunks )
+ {
+ final ByteArrayOutputStream value = new ByteArrayOutputStream();
+ streams.put( segmentChunk, value );
+ printStreams.put( segmentChunk, new PrintStream( value ) );
+ }
+ setNext();
+ this.originalSystemOUtStream = originalSystemOut;
+ System.setOut( new ThreadBoundPrintStream( this.originalSystemOUtStream ) );
+ printer = new ConsolePrinter( segmentChunks );
+ new Thread( printer ).start();
+ printer.waitUntilRunning( true );
+ }
+
+ public void close()
+ {
+ printer.waitUntilRunning( false );
+ System.setOut( this.originalSystemOUtStream );
+ }
+
+ private void setNext()
+ {
+ currentBuild = projects.hasNext() ? projects.next() : null;
+ }
+
+ private boolean ownsRealOutputStream( ProjectSegment projectBuild )
+ {
+ return projectBuild.equals( currentBuild );
+ }
+
+ private PrintStream getThreadBoundPrintStream()
+ {
+ ProjectSegment threadProject = projectBuildThreadLocal.get();
+ if ( threadProject == null )
+ {
+ return defaultPringStream;
+ }
+ if ( ownsRealOutputStream( threadProject ) )
+ {
+ return originalSystemOUtStream;
+ }
+ return printStreams.get( threadProject );
+ }
+
+ public void associateThreadWithProjectSegment( ProjectSegment projectBuild )
+ {
+ projectBuildThreadLocal.set( projectBuild );
+ }
+
+ public void setThisModuleComplete( ProjectSegment projectBuild )
+ {
+ completedBuilds.add( projectBuild );
+ PrintStream stream = printStreams.get( projectBuild );
+ synchronized ( stream )
+ {
+ stream.notifyAll();
+ }
+ disconnectThreadFromProject();
+ }
+
+ private void disconnectThreadFromProject()
+ {
+ projectBuildThreadLocal.remove();
+ }
+
+ private class ThreadBoundPrintStream
+ extends PrintStream
+ {
+
+ public ThreadBoundPrintStream( PrintStream systemOutStream )
+ {
+ super( systemOutStream );
+ }
+
+ private PrintStream getOutputStreamForCurrentThread()
+ {
+ return getThreadBoundPrintStream();
+ }
+
+ @Override
+ public void println()
+ {
+ final PrintStream currentStream = getOutputStreamForCurrentThread();
+ synchronized ( currentStream )
+ {
+ currentStream.println();
+ currentStream.notifyAll();
+ }
+ }
+
+ @Override
+ public void print( char c )
+ {
+ final PrintStream currentStream = getOutputStreamForCurrentThread();
+ synchronized ( currentStream )
+ {
+ currentStream.print( c );
+ currentStream.notifyAll();
+ }
+ }
+
+ @Override
+ public void println( char x )
+ {
+ final PrintStream currentStream = getOutputStreamForCurrentThread();
+ synchronized ( currentStream )
+ {
+ currentStream.println( x );
+ currentStream.notifyAll();
+ }
+ }
+
+ @Override
+ public void print( double d )
+ {
+ final PrintStream currentStream = getOutputStreamForCurrentThread();
+ synchronized ( currentStream )
+ {
+ currentStream.print( d );
+ currentStream.notifyAll();
+ }
+ }
+
+ @Override
+ public void println( double x )
+ {
+ final PrintStream currentStream = getOutputStreamForCurrentThread();
+ synchronized ( currentStream )
+ {
+ currentStream.println( x );
+ currentStream.notifyAll();
+ }
+ }
+
+ @Override
+ public void print( float f )
+ {
+ final PrintStream currentStream = getOutputStreamForCurrentThread();
+ synchronized ( currentStream )
+ {
+ currentStream.print( f );
+ currentStream.notifyAll();
+ }
+ }
+
+ @Override
+ public void println( float x )
+ {
+ final PrintStream currentStream = getOutputStreamForCurrentThread();
+ synchronized ( currentStream )
+ {
+ currentStream.println( x );
+ currentStream.notifyAll();
+ }
+ }
+
+ @Override
+ public void print( int i )
+ {
+ final PrintStream currentStream = getOutputStreamForCurrentThread();
+ synchronized ( currentStream )
+ {
+ currentStream.print( i );
+ currentStream.notifyAll();
+ }
+ }
+
+ @Override
+ public void println( int x )
+ {
+ final PrintStream currentStream = getOutputStreamForCurrentThread();
+ synchronized ( currentStream )
+ {
+ currentStream.println( x );
+ currentStream.notifyAll();
+ }
+ }
+
+ @Override
+ public void print( long l )
+ {
+ final PrintStream currentStream = getOutputStreamForCurrentThread();
+ synchronized ( currentStream )
+ {
+ currentStream.print( l );
+ currentStream.notifyAll();
+ }
+ }
+
+ @Override
+ public void println( long x )
+ {
+ final PrintStream currentStream = getOutputStreamForCurrentThread();
+ synchronized ( currentStream )
+ {
+ currentStream.print( x );
+ currentStream.notifyAll();
+ }
+ }
+
+ @Override
+ public void print( boolean b )
+ {
+ final PrintStream currentStream = getOutputStreamForCurrentThread();
+ synchronized ( currentStream )
+ {
+ currentStream.print( b );
+ currentStream.notifyAll();
+ }
+ }
+
+ @Override
+ public void println( boolean x )
+ {
+ final PrintStream currentStream = getOutputStreamForCurrentThread();
+ synchronized ( currentStream )
+ {
+ currentStream.print( x );
+ currentStream.notifyAll();
+ }
+ }
+
+ @Override
+ public void print( char s[] )
+ {
+ final PrintStream currentStream = getOutputStreamForCurrentThread();
+ synchronized ( currentStream )
+ {
+ currentStream.print( s );
+ currentStream.notifyAll();
+ }
+ }
+
+ @Override
+ public void println( char x[] )
+ {
+ final PrintStream currentStream = getOutputStreamForCurrentThread();
+ synchronized ( currentStream )
+ {
+ currentStream.print( x );
+ currentStream.notifyAll();
+ }
+ }
+
+ @Override
+ public void print( Object obj )
+ {
+ final PrintStream currentStream = getOutputStreamForCurrentThread();
+ synchronized ( currentStream )
+ {
+ currentStream.print( obj );
+ currentStream.notifyAll();
+ }
+ }
+
+ @Override
+ public void println( Object x )
+ {
+ final PrintStream currentStream = getOutputStreamForCurrentThread();
+ synchronized ( currentStream )
+ {
+ currentStream.println( x );
+ currentStream.notifyAll();
+ }
+ }
+
+ @Override
+ public void print( String s )
+ {
+ final PrintStream currentStream = getOutputStreamForCurrentThread();
+ synchronized ( currentStream )
+ {
+ currentStream.print( s );
+ currentStream.notifyAll();
+ }
+ }
+
+ @Override
+ public void println( String x )
+ {
+ final PrintStream currentStream = getOutputStreamForCurrentThread();
+ synchronized ( currentStream )
+ {
+ currentStream.println( x );
+ currentStream.notifyAll();
+ }
+ }
+
+ @Override
+ public void write( byte b[], int off, int len )
+ {
+ final PrintStream currentStream = getOutputStreamForCurrentThread();
+ synchronized ( currentStream )
+ {
+ currentStream.write( b, off, len );
+ currentStream.notifyAll();
+ }
+ }
+
+ @Override
+ public void close()
+ {
+ getOutputStreamForCurrentThread().close();
+ }
+
+ @Override
+ public void flush()
+ {
+ getOutputStreamForCurrentThread().flush();
+ }
+
+ @Override
+ public void write( int b )
+ {
+ final PrintStream currentStream = getOutputStreamForCurrentThread();
+ synchronized ( currentStream )
+ {
+ currentStream.write( b );
+ currentStream.notifyAll();
+ }
+ }
+
+ @Override
+ public void write( byte b[] )
+ throws IOException
+ {
+ final PrintStream currentStream = getOutputStreamForCurrentThread();
+ synchronized ( currentStream )
+ {
+ currentStream.write( b );
+ currentStream.notifyAll();
+ }
+ }
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/builder/singlethreaded/SingleThreadedBuilder.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/builder/singlethreaded/SingleThreadedBuilder.java
new file mode 100644
index 00000000..464944f1
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/internal/builder/singlethreaded/SingleThreadedBuilder.java
@@ -0,0 +1,65 @@
+package org.apache.maven.lifecycle.internal.builder.singlethreaded;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.List;
+
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.lifecycle.internal.LifecycleModuleBuilder;
+import org.apache.maven.lifecycle.internal.ProjectBuildList;
+import org.apache.maven.lifecycle.internal.ProjectSegment;
+import org.apache.maven.lifecycle.internal.ReactorBuildStatus;
+import org.apache.maven.lifecycle.internal.ReactorContext;
+import org.apache.maven.lifecycle.internal.TaskSegment;
+import org.apache.maven.lifecycle.internal.builder.Builder;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+
+@Component( role = Builder.class, hint = "singlethreaded" )
+public class SingleThreadedBuilder
+ implements Builder
+{
+ @Requirement
+ private LifecycleModuleBuilder lifecycleModuleBuilder;
+
+ public void build( MavenSession session, ReactorContext reactorContext, ProjectBuildList projectBuilds,
+ List<TaskSegment> taskSegments, ReactorBuildStatus reactorBuildStatus )
+ {
+ for ( TaskSegment taskSegment : taskSegments )
+ {
+ for ( ProjectSegment projectBuild : projectBuilds.getByTaskSegment( taskSegment ) )
+ {
+ try
+ {
+ lifecycleModuleBuilder.buildProject( session, reactorContext, projectBuild.getProject(),
+ taskSegment );
+ if ( reactorBuildStatus.isHalted() )
+ {
+ break;
+ }
+ }
+ catch ( Exception e )
+ {
+ break; // Why are we just ignoring this exception? Are exceptions are being used for flow control
+ }
+ }
+ }
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/mapping/DefaultLifecycleMapping.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/mapping/DefaultLifecycleMapping.java
new file mode 100644
index 00000000..9947e2fc
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/mapping/DefaultLifecycleMapping.java
@@ -0,0 +1,111 @@
+package org.apache.maven.lifecycle.mapping;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class DefaultLifecycleMapping
+ implements LifecycleMapping
+{
+
+ private List<Lifecycle> lifecycles;
+
+ private Map<String, Lifecycle> lifecycleMap;
+
+ /** @deprecated use lifecycles instead */
+ private Map<String, String> phases;
+
+ /**
+ * Populates the lifecycle map from the injected list of lifecycle mappings (if not already done).
+ */
+ private void initLifecycleMap()
+ {
+ if ( lifecycleMap == null )
+ {
+ lifecycleMap = new HashMap<String, Lifecycle>();
+
+ if ( lifecycles != null )
+ {
+ for ( Lifecycle lifecycle : lifecycles )
+ {
+ lifecycleMap.put( lifecycle.getId(), lifecycle );
+ }
+ }
+ else
+ {
+ /*
+ * NOTE: This is to provide a migration path for implementors of the legacy API which did not know about
+ * getLifecycles().
+ */
+
+ String[] lifecycleIds = { "default", "clean", "site" };
+
+ for ( String lifecycleId : lifecycleIds )
+ {
+ Map<String, String> phases = getPhases( lifecycleId );
+ if ( phases != null )
+ {
+ Lifecycle lifecycle = new Lifecycle();
+
+ lifecycle.setId( lifecycleId );
+ lifecycle.setPhases( phases );
+
+ lifecycleMap.put( lifecycleId, lifecycle );
+ }
+ }
+ }
+ }
+ }
+
+ public Map<String, Lifecycle> getLifecycles()
+ {
+ initLifecycleMap();
+
+ return lifecycleMap;
+ }
+
+ public List<String> getOptionalMojos( String lifecycle )
+ {
+ return null;
+ }
+
+ public Map<String, String> getPhases( String lifecycle )
+ {
+ initLifecycleMap();
+
+ Lifecycle lifecycleMapping = lifecycleMap.get( lifecycle );
+
+ if ( lifecycleMapping != null )
+ {
+ return lifecycleMapping.getPhases();
+ }
+ else if ( "default".equals( lifecycle ) )
+ {
+ return phases;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/mapping/Lifecycle.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/mapping/Lifecycle.java
new file mode 100644
index 00000000..6adf4f34
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/mapping/Lifecycle.java
@@ -0,0 +1,83 @@
+package org.apache.maven.lifecycle.mapping;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Class Lifecycle.
+ */
+public class Lifecycle
+{
+ /**
+ * Field id
+ */
+ private String id;
+
+ /**
+ * Field phases
+ */
+ private Map<String, String> phases;
+
+ /*
+ * NOTE: This exists merely for backward-compat with legacy-style lifecycle definitions and allows configuration
+ * injection to work instead of failing.
+ */
+ @SuppressWarnings( "unused" )
+ private List<String> optionalMojos;
+
+ /**
+ * Method getId
+ */
+ public String getId()
+ {
+ return this.id;
+ }
+
+ /**
+ * Method getPhases
+ */
+ public Map<String, String> getPhases()
+ {
+ return this.phases;
+ }
+
+ /**
+ * Method setId
+ *
+ * @param id
+ */
+ public void setId( String id )
+ {
+ this.id = id;
+ }
+
+ /**
+ * Method setPhases
+ *
+ * @param phases
+ */
+ public void setPhases( Map<String, String> phases )
+ {
+ this.phases = phases;
+ } //-- void setPhases(java.util.List)
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/mapping/LifecycleMapping.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/mapping/LifecycleMapping.java
new file mode 100644
index 00000000..e656cc9f
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/lifecycle/mapping/LifecycleMapping.java
@@ -0,0 +1,39 @@
+package org.apache.maven.lifecycle.mapping;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.List;
+import java.util.Map;
+
+public interface LifecycleMapping
+{
+
+ @Deprecated
+ String ROLE = LifecycleMapping.class.getName();
+
+ Map<String, Lifecycle> getLifecycles();
+
+ @Deprecated
+ List<String> getOptionalMojos( String lifecycle );
+
+ @Deprecated
+ Map<String, String> getPhases( String lifecycle );
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/model/plugin/DefaultLifecycleBindingsInjector.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/model/plugin/DefaultLifecycleBindingsInjector.java
new file mode 100644
index 00000000..1702aa1e
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/model/plugin/DefaultLifecycleBindingsInjector.java
@@ -0,0 +1,171 @@
+package org.apache.maven.model.plugin;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.maven.lifecycle.LifeCyclePluginAnalyzer;
+import org.apache.maven.model.Build;
+import org.apache.maven.model.Model;
+import org.apache.maven.model.Plugin;
+import org.apache.maven.model.PluginContainer;
+import org.apache.maven.model.PluginExecution;
+import org.apache.maven.model.PluginManagement;
+import org.apache.maven.model.building.ModelBuildingRequest;
+import org.apache.maven.model.building.ModelProblemCollector;
+import org.apache.maven.model.building.ModelProblem.Severity;
+import org.apache.maven.model.building.ModelProblem.Version;
+import org.apache.maven.model.building.ModelProblemCollectorRequest;
+import org.apache.maven.model.merge.MavenModelMerger;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+
+/**
+ * Handles injection of plugin executions induced by the lifecycle bindings for a packaging.
+ *
+ * @author Benjamin Bentmann
+ */
+@Component( role = LifecycleBindingsInjector.class )
+public class DefaultLifecycleBindingsInjector
+ implements LifecycleBindingsInjector
+{
+
+ private LifecycleBindingsMerger merger = new LifecycleBindingsMerger();
+
+ @Requirement
+ private LifeCyclePluginAnalyzer lifecycle;
+
+ public void injectLifecycleBindings( Model model, ModelBuildingRequest request, ModelProblemCollector problems )
+ {
+ String packaging = model.getPackaging();
+
+ Collection<Plugin> defaultPlugins = lifecycle.getPluginsBoundByDefaultToAllLifecycles( packaging );
+
+ if ( defaultPlugins == null )
+ {
+ problems.add( new ModelProblemCollectorRequest( Severity.ERROR, Version.BASE )
+ .setMessage( "Unknown packaging: " + packaging )
+ .setLocation( model.getLocation( "packaging" ) ) );
+ }
+ else if ( !defaultPlugins.isEmpty() )
+ {
+ Model lifecycleModel = new Model();
+ lifecycleModel.setBuild( new Build() );
+ lifecycleModel.getBuild().getPlugins().addAll( defaultPlugins );
+
+ merger.merge( model, lifecycleModel );
+ }
+ }
+
+ protected static class LifecycleBindingsMerger
+ extends MavenModelMerger
+ {
+
+ private static final String PLUGIN_MANAGEMENT = "plugin-management";
+
+ public void merge( Model target, Model source )
+ {
+ if ( target.getBuild() == null )
+ {
+ target.setBuild( new Build() );
+ }
+
+ Map<Object, Object> context =
+ Collections.<Object, Object>singletonMap( PLUGIN_MANAGEMENT, target.getBuild().getPluginManagement() );
+
+ mergePluginContainer_Plugins( target.getBuild(), source.getBuild(), false, context );
+ }
+
+ @Override
+ protected void mergePluginContainer_Plugins( PluginContainer target, PluginContainer source,
+ boolean sourceDominant, Map<Object, Object> context )
+ {
+ List<Plugin> src = source.getPlugins();
+ if ( !src.isEmpty() )
+ {
+ List<Plugin> tgt = target.getPlugins();
+
+ Map<Object, Plugin> merged = new LinkedHashMap<Object, Plugin>( ( src.size() + tgt.size() ) * 2 );
+
+ for ( Plugin element : tgt )
+ {
+ Object key = getPluginKey( element );
+ merged.put( key, element );
+ }
+
+ Map<Object, Plugin> unmanaged = new LinkedHashMap<Object, Plugin>();
+
+ for ( Plugin element : src )
+ {
+ Object key = getPluginKey( element );
+ Plugin existing = merged.get( key );
+ if ( existing != null )
+ {
+ mergePlugin( existing, element, sourceDominant, context );
+ }
+ else
+ {
+ merged.put( key, element );
+ unmanaged.put( key, element );
+ }
+ }
+
+ if ( !unmanaged.isEmpty() )
+ {
+ PluginManagement pluginMgmt = (PluginManagement) context.get( PLUGIN_MANAGEMENT );
+ if ( pluginMgmt != null )
+ {
+ for ( Plugin managedPlugin : pluginMgmt.getPlugins() )
+ {
+ Object key = getPluginKey( managedPlugin );
+ Plugin unmanagedPlugin = unmanaged.get( key );
+ if ( unmanagedPlugin != null )
+ {
+ Plugin plugin = managedPlugin.clone();
+ mergePlugin( plugin, unmanagedPlugin, sourceDominant, Collections.emptyMap() );
+ merged.put( key, plugin );
+ }
+ }
+ }
+ }
+
+ List<Plugin> result = new ArrayList<Plugin>( merged.values() );
+
+ target.setPlugins( result );
+ }
+ }
+
+ @Override
+ protected void mergePluginExecution( PluginExecution target, PluginExecution source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ super.mergePluginExecution( target, source, sourceDominant, context );
+
+ target.setPriority( Math.min( target.getPriority(), source.getPriority() ) );
+ }
+
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/monitor/event/EventDispatcher.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/monitor/event/EventDispatcher.java
new file mode 100644
index 00000000..492a2980
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/monitor/event/EventDispatcher.java
@@ -0,0 +1,37 @@
+package org.apache.maven.monitor.event;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * @author jdcasey
+ */
+@Deprecated
+public interface EventDispatcher
+{
+
+ void addEventMonitor( EventMonitor monitor );
+
+ void dispatchStart( String event, String target );
+
+ void dispatchEnd( String event, String target );
+
+ void dispatchError( String event, String target, Throwable cause );
+
+} \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/monitor/event/EventMonitor.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/monitor/event/EventMonitor.java
new file mode 100644
index 00000000..3e726746
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/monitor/event/EventMonitor.java
@@ -0,0 +1,35 @@
+package org.apache.maven.monitor.event;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * @author jdcasey
+ */
+@Deprecated
+public interface EventMonitor
+{
+
+ void startEvent( String eventName, String target, long timestamp );
+
+ void endEvent( String eventName, String target, long timestamp );
+
+ void errorEvent( String eventName, String target, long timestamp, Throwable cause );
+
+} \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/BuildPluginManager.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/BuildPluginManager.java
new file mode 100644
index 00000000..6c1b9cbf
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/BuildPluginManager.java
@@ -0,0 +1,54 @@
+package org.apache.maven.plugin;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.List;
+
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.model.Plugin;
+import org.apache.maven.plugin.descriptor.MojoDescriptor;
+import org.apache.maven.plugin.descriptor.PluginDescriptor;
+import org.codehaus.plexus.classworlds.realm.ClassRealm;
+import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.repository.RemoteRepository;
+
+/**
+ * @author Jason van Zyl
+ */
+public interface BuildPluginManager
+{
+ // igorf: Way too many declared exceptions!
+ PluginDescriptor loadPlugin( Plugin plugin, List<RemoteRepository> repositories, RepositorySystemSession session )
+ throws PluginNotFoundException, PluginResolutionException, PluginDescriptorParsingException,
+ InvalidPluginDescriptorException;
+
+ // igorf: Way too many declared exceptions!
+ MojoDescriptor getMojoDescriptor( Plugin plugin, String goal, List<RemoteRepository> repositories,
+ RepositorySystemSession session )
+ throws PluginNotFoundException, PluginResolutionException, PluginDescriptorParsingException,
+ MojoNotFoundException, InvalidPluginDescriptorException;
+
+ ClassRealm getPluginRealm( MavenSession session, PluginDescriptor pluginDescriptor )
+ throws PluginResolutionException, PluginManagerException;
+
+ void executeMojo( MavenSession session, MojoExecution execution )
+ throws MojoFailureException, MojoExecutionException, PluginConfigurationException, PluginManagerException;
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/CacheUtils.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/CacheUtils.java
new file mode 100644
index 00000000..a73e1efe
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/CacheUtils.java
@@ -0,0 +1,211 @@
+package org.apache.maven.plugin;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.maven.model.Dependency;
+import org.apache.maven.model.Exclusion;
+import org.apache.maven.model.Plugin;
+import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.repository.RemoteRepository;
+import org.eclipse.aether.repository.RepositoryPolicy;
+import org.eclipse.aether.repository.WorkspaceReader;
+import org.eclipse.aether.repository.WorkspaceRepository;
+
+/**
+ * @author Benjamin Bentmann
+ */
+class CacheUtils
+{
+
+ public static <T> boolean eq( T s1, T s2 )
+ {
+ return s1 != null ? s1.equals( s2 ) : s2 == null;
+ }
+
+ public static int hash( Object obj )
+ {
+ return obj != null ? obj.hashCode() : 0;
+ }
+
+ public static int repositoriesHashCode( List<RemoteRepository> repositories )
+ {
+ int result = 17;
+ for ( RemoteRepository repository : repositories )
+ {
+ result = 31 * result + repositoryHashCode( repository );
+ }
+ return result;
+ }
+
+ private static int repositoryHashCode( RemoteRepository repository )
+ {
+ int result = 17;
+ result = 31 * result + hash( repository.getUrl() );
+ return result;
+ }
+
+ private static boolean repositoryEquals( RemoteRepository r1, RemoteRepository r2 )
+ {
+ if ( r1 == r2 )
+ {
+ return true;
+ }
+
+ return eq( r1.getId(), r2.getId() ) && eq( r1.getUrl(), r2.getUrl() )
+ && policyEquals( r1.getPolicy( false ), r2.getPolicy( false ) )
+ && policyEquals( r1.getPolicy( true ), r2.getPolicy( true ) );
+ }
+
+ private static boolean policyEquals( RepositoryPolicy p1, RepositoryPolicy p2 )
+ {
+ if ( p1 == p2 )
+ {
+ return true;
+ }
+ // update policy doesn't affect contents
+ return p1.isEnabled() == p2.isEnabled() && eq( p1.getChecksumPolicy(), p2.getChecksumPolicy() );
+ }
+
+ public static boolean repositoriesEquals( List<RemoteRepository> r1, List<RemoteRepository> r2 )
+ {
+ if ( r1.size() != r2.size() )
+ {
+ return false;
+ }
+
+ for ( Iterator<RemoteRepository> it1 = r1.iterator(), it2 = r2.iterator(); it1.hasNext(); )
+ {
+ if ( !repositoryEquals( it1.next(), it2.next() ) )
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ public static int pluginHashCode( Plugin plugin )
+ {
+ int hash = 17;
+
+ hash = hash * 31 + hash( plugin.getGroupId() );
+ hash = hash * 31 + hash( plugin.getArtifactId() );
+ hash = hash * 31 + hash( plugin.getVersion() );
+
+ hash = hash * 31 + ( plugin.isExtensions() ? 1 : 0 );
+
+ for ( Dependency dependency : plugin.getDependencies() )
+ {
+ hash = hash * 31 + hash( dependency.getGroupId() );
+ hash = hash * 31 + hash( dependency.getArtifactId() );
+ hash = hash * 31 + hash( dependency.getVersion() );
+ hash = hash * 31 + hash( dependency.getType() );
+ hash = hash * 31 + hash( dependency.getClassifier() );
+ hash = hash * 31 + hash( dependency.getScope() );
+
+ for ( Exclusion exclusion : dependency.getExclusions() )
+ {
+ hash = hash * 31 + hash( exclusion.getGroupId() );
+ hash = hash * 31 + hash( exclusion.getArtifactId() );
+ }
+ }
+
+ return hash;
+ }
+
+ public static boolean pluginEquals( Plugin a, Plugin b )
+ {
+ return eq( a.getArtifactId(), b.getArtifactId() ) //
+ && eq( a.getGroupId(), b.getGroupId() ) //
+ && eq( a.getVersion(), b.getVersion() ) //
+ && a.isExtensions() == b.isExtensions() //
+ && dependenciesEquals( a.getDependencies(), b.getDependencies() );
+ }
+
+ private static boolean dependenciesEquals( List<Dependency> a, List<Dependency> b )
+ {
+ if ( a.size() != b.size() )
+ {
+ return false;
+ }
+
+ Iterator<Dependency> aI = a.iterator();
+ Iterator<Dependency> bI = b.iterator();
+
+ while ( aI.hasNext() )
+ {
+ Dependency aD = aI.next();
+ Dependency bD = bI.next();
+
+ boolean r = eq( aD.getGroupId(), bD.getGroupId() ) //
+ && eq( aD.getArtifactId(), bD.getArtifactId() ) //
+ && eq( aD.getVersion(), bD.getVersion() ) //
+ && eq( aD.getType(), bD.getType() ) //
+ && eq( aD.getClassifier(), bD.getClassifier() ) //
+ && eq( aD.getScope(), bD.getScope() );
+
+ r &= exclusionsEquals( aD.getExclusions(), bD.getExclusions() );
+
+ if ( !r )
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ private static boolean exclusionsEquals( List<Exclusion> a, List<Exclusion> b )
+ {
+ if ( a.size() != b.size() )
+ {
+ return false;
+ }
+
+ Iterator<Exclusion> aI = a.iterator();
+ Iterator<Exclusion> bI = b.iterator();
+
+ while ( aI.hasNext() )
+ {
+ Exclusion aD = aI.next();
+ Exclusion bD = bI.next();
+
+ boolean r = eq( aD.getGroupId(), bD.getGroupId() ) //
+ && eq( aD.getArtifactId(), bD.getArtifactId() );
+
+ if ( !r )
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ public static WorkspaceRepository getWorkspace( RepositorySystemSession session )
+ {
+ WorkspaceReader reader = session.getWorkspaceReader();
+ return ( reader != null ) ? reader.getRepository() : null;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/CompoundMojoExecutionListener.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/CompoundMojoExecutionListener.java
new file mode 100644
index 00000000..9fe52833
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/CompoundMojoExecutionListener.java
@@ -0,0 +1,64 @@
+package org.apache.maven.plugin;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Collection;
+
+import org.apache.maven.execution.MojoExecutionEvent;
+import org.apache.maven.execution.MojoExecutionListener;
+
+class CompoundMojoExecutionListener
+ implements MojoExecutionListener
+{
+
+ private final Collection<MojoExecutionListener> listeners;
+
+ public CompoundMojoExecutionListener( Collection<MojoExecutionListener> listeners )
+ {
+ this.listeners = listeners; // NB this is live injected collection
+ }
+
+ public void beforeMojoExecution( MojoExecutionEvent event )
+ throws MojoExecutionException
+ {
+ for ( MojoExecutionListener listener : listeners )
+ {
+ listener.beforeMojoExecution( event );
+ }
+ }
+
+ public void afterMojoExecutionSuccess( MojoExecutionEvent event )
+ throws MojoExecutionException
+ {
+ for ( MojoExecutionListener listener : listeners )
+ {
+ listener.afterMojoExecutionSuccess( event );
+ }
+ }
+
+ public void afterExecutionFailure( MojoExecutionEvent event )
+ {
+ for ( MojoExecutionListener listener : listeners )
+ {
+ listener.afterExecutionFailure( event );
+ }
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/CycleDetectedInPluginGraphException.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/CycleDetectedInPluginGraphException.java
new file mode 100644
index 00000000..f77461fe
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/CycleDetectedInPluginGraphException.java
@@ -0,0 +1,46 @@
+package org.apache.maven.plugin;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.model.Plugin;
+import org.codehaus.plexus.component.composition.CycleDetectedInComponentGraphException;
+
+/**
+ * Exception occurring trying to resolve a plugin.
+ *
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ */
+public class CycleDetectedInPluginGraphException
+ extends Exception
+{
+ private final Plugin plugin;
+
+ public CycleDetectedInPluginGraphException( Plugin plugin, CycleDetectedInComponentGraphException e )
+ {
+ super( "A cycle was detected in the component graph of the plugin: " + plugin.getArtifactId() );
+
+ this.plugin = plugin;
+ }
+
+ public Plugin getPlugin()
+ {
+ return plugin;
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/DebugConfigurationListener.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/DebugConfigurationListener.java
new file mode 100644
index 00000000..57084ceb
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/DebugConfigurationListener.java
@@ -0,0 +1,91 @@
+package org.apache.maven.plugin;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.lang.reflect.Array;
+
+import org.codehaus.plexus.component.configurator.ConfigurationListener;
+import org.codehaus.plexus.logging.Logger;
+
+/**
+ * Log at debug level the mojo configuration.
+ *
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ */
+@Deprecated
+public class DebugConfigurationListener
+ implements ConfigurationListener
+{
+ private Logger logger;
+
+ public DebugConfigurationListener( Logger logger )
+ {
+ this.logger = logger;
+ }
+
+ public void notifyFieldChangeUsingSetter( String fieldName, Object value, Object target )
+ {
+ if ( logger.isDebugEnabled() )
+ {
+ logger.debug( " (s) " + fieldName + " = " + toString( value ) );
+ }
+ }
+
+ public void notifyFieldChangeUsingReflection( String fieldName, Object value, Object target )
+ {
+ if ( logger.isDebugEnabled() )
+ {
+ logger.debug( " (f) " + fieldName + " = " + toString( value ) );
+ }
+ }
+
+ /**
+ * Creates a human-friendly string represenation of the specified object.
+ *
+ * @param obj The object to create a string representation for, may be <code>null</code>.
+ * @return The string representation, never <code>null</code>.
+ */
+ private String toString( Object obj )
+ {
+ String str;
+ if ( obj != null && obj.getClass().isArray() )
+ {
+ int n = Array.getLength( obj );
+ StringBuilder buf = new StringBuilder( 256 );
+ buf.append( '[' );
+ for ( int i = 0; i < n; i++ )
+ {
+ if ( i > 0 )
+ {
+ buf.append( ", " );
+ }
+ buf.append( String.valueOf( Array.get( obj, i ) ) );
+ }
+ buf.append( ']' );
+ str = buf.toString();
+ }
+ else
+ {
+ str = String.valueOf( obj );
+ }
+ return str;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/DefaultBuildPluginManager.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/DefaultBuildPluginManager.java
new file mode 100644
index 00000000..8145bd58
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/DefaultBuildPluginManager.java
@@ -0,0 +1,244 @@
+package org.apache.maven.plugin;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+import java.util.List;
+
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.execution.MojoExecutionEvent;
+import org.apache.maven.execution.MojoExecutionListener;
+import org.apache.maven.execution.scope.internal.MojoExecutionScope;
+import org.apache.maven.model.Plugin;
+import org.apache.maven.plugin.descriptor.MojoDescriptor;
+import org.apache.maven.plugin.descriptor.PluginDescriptor;
+import org.apache.maven.project.MavenProject;
+import org.codehaus.plexus.classworlds.realm.ClassRealm;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.repository.RemoteRepository;
+
+// TODO: the antrun plugin has its own configurator, the only plugin that does. might need to think about how that works
+// TODO: remove the coreArtifactFilterManager
+
+@Component( role = BuildPluginManager.class )
+public class DefaultBuildPluginManager
+ implements BuildPluginManager
+{
+
+ @Requirement
+ private MavenPluginManager mavenPluginManager;
+
+ @Requirement
+ private LegacySupport legacySupport;
+
+ @Requirement
+ private MojoExecutionScope scope;
+
+ private MojoExecutionListener mojoExecutionListener;
+
+ // this tricks plexus-component-metadata generate required metadata
+ @Requirement( role = MojoExecutionListener.class )
+ private List<MojoExecutionListener> mojoExecutionListeners;
+
+ public void setMojoExecutionListeners( final List<MojoExecutionListener> listeners )
+ {
+ this.mojoExecutionListeners = listeners;
+ this.mojoExecutionListener = new CompoundMojoExecutionListener( listeners );
+ }
+
+ /**
+ * @param plugin
+ * @param repositories
+ * @param session
+ * @return PluginDescriptor The component descriptor for the Maven plugin.
+ * @throws PluginNotFoundException The plugin could not be found in any repositories.
+ * @throws PluginResolutionException The plugin could be found but could not be resolved.
+ * @throws InvalidPluginDescriptorException
+ */
+ public PluginDescriptor loadPlugin( Plugin plugin, List<RemoteRepository> repositories,
+ RepositorySystemSession session )
+ throws PluginNotFoundException, PluginResolutionException, PluginDescriptorParsingException,
+ InvalidPluginDescriptorException
+ {
+ return mavenPluginManager.getPluginDescriptor( plugin, repositories, session );
+ }
+
+ // ----------------------------------------------------------------------
+ // Mojo execution
+ // ----------------------------------------------------------------------
+
+ public void executeMojo( MavenSession session, MojoExecution mojoExecution )
+ throws MojoFailureException, MojoExecutionException, PluginConfigurationException, PluginManagerException
+ {
+ MavenProject project = session.getCurrentProject();
+
+ MojoDescriptor mojoDescriptor = mojoExecution.getMojoDescriptor();
+
+ Mojo mojo = null;
+
+ ClassRealm pluginRealm;
+ try
+ {
+ pluginRealm = getPluginRealm( session, mojoDescriptor.getPluginDescriptor() );
+ }
+ catch ( PluginResolutionException e )
+ {
+ throw new PluginExecutionException( mojoExecution, project, e );
+ }
+
+ ClassLoader oldClassLoader = Thread.currentThread().getContextClassLoader();
+ Thread.currentThread().setContextClassLoader( pluginRealm );
+
+ MavenSession oldSession = legacySupport.getSession();
+
+ scope.enter();
+
+ try
+ {
+ scope.seed( MavenProject.class, project );
+ scope.seed( MojoExecution.class, mojoExecution );
+
+ mojo = mavenPluginManager.getConfiguredMojo( Mojo.class, session, mojoExecution );
+
+ legacySupport.setSession( session );
+
+ // NOTE: DuplicateArtifactAttachmentException is currently unchecked, so be careful removing this try/catch!
+ // This is necessary to avoid creating compatibility problems for existing plugins that use
+ // MavenProjectHelper.attachArtifact(..).
+ try
+ {
+ MojoExecutionEvent mojoExecutionEvent = new MojoExecutionEvent( session, project, mojoExecution, mojo );
+
+ mojoExecutionListener.beforeMojoExecution( mojoExecutionEvent );
+
+ mojo.execute();
+
+ mojoExecutionListener.afterMojoExecutionSuccess( mojoExecutionEvent );
+ }
+ catch ( ClassCastException e )
+ {
+ // to be processed in the outer catch block
+ throw e;
+ }
+ catch ( RuntimeException e )
+ {
+ throw new PluginExecutionException( mojoExecution, project, e );
+ }
+ }
+ catch ( PluginContainerException e )
+ {
+ mojoExecutionListener.afterExecutionFailure( new MojoExecutionEvent( session, project, mojoExecution, mojo,
+ e ) );
+
+ throw new PluginExecutionException( mojoExecution, project, e );
+ }
+ catch ( NoClassDefFoundError e )
+ {
+ mojoExecutionListener.afterExecutionFailure( new MojoExecutionEvent( session, project, mojoExecution, mojo,
+ e ) );
+
+ ByteArrayOutputStream os = new ByteArrayOutputStream( 1024 );
+ PrintStream ps = new PrintStream( os );
+ ps.println( "A required class was missing while executing " + mojoDescriptor.getId() + ": "
+ + e.getMessage() );
+ pluginRealm.display( ps );
+
+ Exception wrapper = new PluginContainerException( mojoDescriptor, pluginRealm, os.toString(), e );
+
+ throw new PluginExecutionException( mojoExecution, project, wrapper );
+ }
+ catch ( LinkageError e )
+ {
+ mojoExecutionListener.afterExecutionFailure( new MojoExecutionEvent( session, project, mojoExecution, mojo,
+ e ) );
+
+ ByteArrayOutputStream os = new ByteArrayOutputStream( 1024 );
+ PrintStream ps = new PrintStream( os );
+ ps.println( "An API incompatibility was encountered while executing " + mojoDescriptor.getId() + ": "
+ + e.getClass().getName() + ": " + e.getMessage() );
+ pluginRealm.display( ps );
+
+ Exception wrapper = new PluginContainerException( mojoDescriptor, pluginRealm, os.toString(), e );
+
+ throw new PluginExecutionException( mojoExecution, project, wrapper );
+ }
+ catch ( ClassCastException e )
+ {
+ mojoExecutionListener.afterExecutionFailure( new MojoExecutionEvent( session, project, mojoExecution, mojo,
+ e ) );
+
+ ByteArrayOutputStream os = new ByteArrayOutputStream( 1024 );
+ PrintStream ps = new PrintStream( os );
+ ps.println( "A type incompatibility occured while executing " + mojoDescriptor.getId() + ": "
+ + e.getMessage() );
+ pluginRealm.display( ps );
+
+ throw new PluginExecutionException( mojoExecution, project, os.toString(), e );
+ }
+ catch ( RuntimeException e )
+ {
+ mojoExecutionListener.afterExecutionFailure( new MojoExecutionEvent( session, project, mojoExecution, mojo,
+ e ) );
+
+ throw e;
+ }
+ finally
+ {
+ mavenPluginManager.releaseMojo( mojo, mojoExecution );
+
+ scope.exit();
+
+ Thread.currentThread().setContextClassLoader( oldClassLoader );
+
+ legacySupport.setSession( oldSession );
+ }
+ }
+
+ /**
+ * TODO pluginDescriptor classRealm and artifacts are set as a side effect of this
+ * call, which is not nice.
+ * @throws PluginResolutionException
+ */
+ public ClassRealm getPluginRealm( MavenSession session, PluginDescriptor pluginDescriptor )
+ throws PluginResolutionException, PluginManagerException
+ {
+ ClassRealm pluginRealm = pluginDescriptor.getClassRealm();
+ if ( pluginRealm != null )
+ {
+ return pluginRealm;
+ }
+
+ mavenPluginManager.setupPluginRealm( pluginDescriptor, session, null, null, null );
+
+ return pluginDescriptor.getClassRealm();
+ }
+
+ public MojoDescriptor getMojoDescriptor( Plugin plugin, String goal, List<RemoteRepository> repositories,
+ RepositorySystemSession session )
+ throws PluginNotFoundException, PluginResolutionException, PluginDescriptorParsingException,
+ MojoNotFoundException, InvalidPluginDescriptorException
+ {
+ return mavenPluginManager.getMojoDescriptor( plugin, goal, repositories, session );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/DefaultExtensionRealmCache.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/DefaultExtensionRealmCache.java
new file mode 100644
index 00000000..c9df92c6
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/DefaultExtensionRealmCache.java
@@ -0,0 +1,170 @@
+package org.apache.maven.plugin;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.project.ExtensionDescriptor;
+import org.apache.maven.project.MavenProject;
+import org.codehaus.plexus.classworlds.realm.ClassRealm;
+import org.codehaus.plexus.classworlds.realm.NoSuchRealmException;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.personality.plexus.lifecycle.phase.Disposable;
+
+/**
+ * Default extension realm cache implementation. Assumes cached data does not change.
+ */
+@Component( role = ExtensionRealmCache.class )
+public class DefaultExtensionRealmCache
+ implements ExtensionRealmCache, Disposable
+{
+
+ protected static class CacheKey
+ implements Key
+ {
+
+ private final List<File> files;
+
+ private final List<Long> timestamps;
+
+ private final List<Long> sizes;
+
+ private final List<String> ids;
+
+ private final int hashCode;
+
+ public CacheKey( List<Artifact> extensionArtifacts )
+ {
+ this.files = new ArrayList<File>( extensionArtifacts.size() );
+ this.timestamps = new ArrayList<Long>( extensionArtifacts.size() );
+ this.sizes = new ArrayList<Long>( extensionArtifacts.size() );
+ this.ids = new ArrayList<String>( extensionArtifacts.size() );
+
+ for ( Artifact artifact : extensionArtifacts )
+ {
+ File file = artifact.getFile();
+ files.add( file );
+ timestamps.add( ( file != null ) ? Long.valueOf( file.lastModified() ) : Long.valueOf( 0 ) );
+ sizes.add( ( file != null ) ? Long.valueOf( file.length() ) : Long.valueOf( 0 ) );
+ ids.add( artifact.getVersion() );
+ }
+
+ this.hashCode =
+ 31 * files.hashCode() + 31 * ids.hashCode() + 31 * timestamps.hashCode() + 31 * sizes.hashCode();
+ }
+
+ @Override
+ public int hashCode()
+ {
+ return hashCode;
+ }
+
+ @Override
+ public boolean equals( Object o )
+ {
+ if ( o == this )
+ {
+ return true;
+ }
+
+ if ( !( o instanceof CacheKey ) )
+ {
+ return false;
+ }
+
+ CacheKey other = (CacheKey) o;
+
+ return ids.equals( other.ids ) && files.equals( other.files ) && timestamps.equals( other.timestamps )
+ && sizes.equals( other.sizes );
+ }
+
+ @Override
+ public String toString()
+ {
+ return files.toString();
+ }
+ }
+
+ protected final Map<Key, CacheRecord> cache = new ConcurrentHashMap<Key, CacheRecord>();
+
+ @Override
+ public Key createKey( List<Artifact> extensionArtifacts )
+ {
+ return new CacheKey( extensionArtifacts );
+ }
+
+ public CacheRecord get( Key key )
+ {
+ return cache.get( key );
+ }
+
+ public CacheRecord put( Key key, ClassRealm extensionRealm, ExtensionDescriptor extensionDescriptor,
+ List<Artifact> artifacts )
+ {
+ if ( extensionRealm == null )
+ {
+ throw new NullPointerException();
+ }
+
+ if ( cache.containsKey( key ) )
+ {
+ throw new IllegalStateException( "Duplicate extension realm for extension " + key );
+ }
+
+ CacheRecord record = new CacheRecord( extensionRealm, extensionDescriptor, artifacts );
+
+ cache.put( key, record );
+
+ return record;
+ }
+
+ public void flush()
+ {
+ for ( CacheRecord record : cache.values() )
+ {
+ ClassRealm realm = record.realm;
+ try
+ {
+ realm.getWorld().disposeRealm( realm.getId() );
+ }
+ catch ( NoSuchRealmException e )
+ {
+ // ignore
+ }
+ }
+ cache.clear();
+ }
+
+ public void register( MavenProject project, Key key, CacheRecord record )
+ {
+ // default cache does not track extension usage
+ }
+
+ public void dispose()
+ {
+ flush();
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/DefaultPluginArtifactsCache.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/DefaultPluginArtifactsCache.java
new file mode 100644
index 00000000..23bda64d
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/DefaultPluginArtifactsCache.java
@@ -0,0 +1,218 @@
+package org.apache.maven.plugin;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.model.Plugin;
+import org.apache.maven.project.MavenProject;
+import org.codehaus.plexus.component.annotations.Component;
+import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.graph.DependencyFilter;
+import org.eclipse.aether.repository.LocalRepository;
+import org.eclipse.aether.repository.RemoteRepository;
+import org.eclipse.aether.repository.WorkspaceRepository;
+
+/**
+ * @author Igor Fedorenko
+ * @author Benjamin Bentmann
+ */
+@Component( role = PluginArtifactsCache.class )
+public class DefaultPluginArtifactsCache
+ implements PluginArtifactsCache
+{
+
+ protected static class CacheKey
+ implements Key
+ {
+
+ private final Plugin plugin;
+
+ private final WorkspaceRepository workspace;
+
+ private final LocalRepository localRepo;
+
+ private final List<RemoteRepository> repositories;
+
+ private final DependencyFilter filter;
+
+ private final int hashCode;
+
+ public CacheKey( Plugin plugin, DependencyFilter extensionFilter, List<RemoteRepository> repositories,
+ RepositorySystemSession session )
+ {
+ this.plugin = plugin.clone();
+ workspace = CacheUtils.getWorkspace( session );
+ this.localRepo = session.getLocalRepository();
+ this.repositories = new ArrayList<RemoteRepository>( repositories.size() );
+ for ( RemoteRepository repository : repositories )
+ {
+ if ( repository.isRepositoryManager() )
+ {
+ this.repositories.addAll( repository.getMirroredRepositories() );
+ }
+ else
+ {
+ this.repositories.add( repository );
+ }
+ }
+ this.filter = extensionFilter;
+
+ int hash = 17;
+ hash = hash * 31 + CacheUtils.pluginHashCode( plugin );
+ hash = hash * 31 + hash( workspace );
+ hash = hash * 31 + hash( localRepo );
+ hash = hash * 31 + CacheUtils.repositoriesHashCode( repositories );
+ hash = hash * 31 + hash( extensionFilter );
+ this.hashCode = hash;
+ }
+
+ @Override
+ public String toString()
+ {
+ return plugin.getId();
+ }
+
+ @Override
+ public int hashCode()
+ {
+ return hashCode;
+ }
+
+ private static int hash( Object obj )
+ {
+ return obj != null ? obj.hashCode() : 0;
+ }
+
+ @Override
+ public boolean equals( Object o )
+ {
+ if ( o == this )
+ {
+ return true;
+ }
+
+ if ( !( o instanceof CacheKey ) )
+ {
+ return false;
+ }
+
+ CacheKey that = (CacheKey) o;
+
+ return CacheUtils.pluginEquals( plugin, that.plugin ) && eq( workspace, that.workspace )
+ && eq( localRepo, that.localRepo ) && CacheUtils.repositoriesEquals( repositories, that.repositories )
+ && eq( filter, that.filter );
+ }
+
+ private static <T> boolean eq( T s1, T s2 )
+ {
+ return s1 != null ? s1.equals( s2 ) : s2 == null;
+ }
+
+ }
+
+ protected final Map<Key, CacheRecord> cache = new ConcurrentHashMap<Key, CacheRecord>();
+
+ public Key createKey( Plugin plugin, DependencyFilter extensionFilter, List<RemoteRepository> repositories,
+ RepositorySystemSession session )
+ {
+ return new CacheKey( plugin, extensionFilter, repositories, session );
+ }
+
+ public CacheRecord get( Key key )
+ throws PluginResolutionException
+ {
+ CacheRecord cacheRecord = cache.get( key );
+
+ if ( cacheRecord != null && cacheRecord.exception != null )
+ {
+ throw cacheRecord.exception;
+ }
+
+ return cacheRecord;
+ }
+
+ public CacheRecord put( Key key, List<Artifact> pluginArtifacts )
+ {
+ if ( pluginArtifacts == null )
+ {
+ throw new NullPointerException();
+ }
+
+ assertUniqueKey( key );
+
+ CacheRecord record =
+ new CacheRecord( Collections.unmodifiableList( new ArrayList<Artifact>( pluginArtifacts ) ) );
+
+ cache.put( key, record );
+
+ return record;
+ }
+
+ protected void assertUniqueKey( Key key )
+ {
+ if ( cache.containsKey( key ) )
+ {
+ throw new IllegalStateException( "Duplicate artifact resolution result for plugin " + key );
+ }
+ }
+
+ public CacheRecord put( Key key, PluginResolutionException exception )
+ {
+ if ( exception == null )
+ {
+ throw new NullPointerException();
+ }
+
+ assertUniqueKey( key );
+
+ CacheRecord record = new CacheRecord( exception );
+
+ cache.put( key, record );
+
+ return record;
+ }
+
+ public void flush()
+ {
+ cache.clear();
+ }
+
+ protected static int pluginHashCode( Plugin plugin )
+ {
+ return CacheUtils.pluginHashCode( plugin );
+ }
+
+ protected static boolean pluginEquals( Plugin a, Plugin b )
+ {
+ return CacheUtils.pluginEquals( a, b );
+ }
+
+ public void register( MavenProject project, Key cacheKey, CacheRecord record )
+ {
+ // default cache does not track record usage
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/DefaultPluginDescriptorCache.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/DefaultPluginDescriptorCache.java
new file mode 100644
index 00000000..4927726b
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/DefaultPluginDescriptorCache.java
@@ -0,0 +1,219 @@
+package org.apache.maven.plugin;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.maven.artifact.ArtifactUtils;
+import org.apache.maven.model.Plugin;
+import org.apache.maven.plugin.descriptor.MojoDescriptor;
+import org.apache.maven.plugin.descriptor.PluginDescriptor;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.repository.ComponentDescriptor;
+import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.repository.LocalRepository;
+import org.eclipse.aether.repository.RemoteRepository;
+import org.eclipse.aether.repository.WorkspaceRepository;
+
+/**
+ * Caches raw plugin descriptors. A raw plugin descriptor is a descriptor that has just been extracted from the plugin
+ * artifact and does not contain any runtime specific data. The cache must not be used for descriptors that hold runtime
+ * data like the plugin realm. <strong>Warning:</strong> This is an internal utility interface that is only public for
+ * technical reasons, it is not part of the public API. In particular, this interface can be changed or deleted without
+ * prior notice.
+ *
+ * @since 3.0
+ * @author Benjamin Bentmann
+ */
+@Component( role = PluginDescriptorCache.class )
+public class DefaultPluginDescriptorCache
+ implements PluginDescriptorCache
+{
+
+ private Map<Key, PluginDescriptor> descriptors = new HashMap<Key, PluginDescriptor>( 128 );
+
+ public void flush()
+ {
+ descriptors.clear();
+ }
+
+ public Key createKey( Plugin plugin, List<RemoteRepository> repositories, RepositorySystemSession session )
+ {
+ return new CacheKey( plugin, repositories, session );
+ }
+
+ public PluginDescriptor get( Key cacheKey )
+ {
+ return clone( descriptors.get( cacheKey ) );
+ }
+
+ public void put( Key cacheKey, PluginDescriptor pluginDescriptor )
+ {
+ descriptors.put( cacheKey, clone( pluginDescriptor ) );
+ }
+
+ protected static PluginDescriptor clone( PluginDescriptor original )
+ {
+ PluginDescriptor clone = null;
+
+ if ( original != null )
+ {
+ clone = new PluginDescriptor();
+
+ clone.setGroupId( original.getGroupId() );
+ clone.setArtifactId( original.getArtifactId() );
+ clone.setVersion( original.getVersion() );
+ clone.setGoalPrefix( original.getGoalPrefix() );
+ clone.setInheritedByDefault( original.isInheritedByDefault() );
+
+ clone.setName( original.getName() );
+ clone.setDescription( original.getDescription() );
+ clone.setRequiredMavenVersion( original.getRequiredMavenVersion() );
+
+ clone.setPluginArtifact( ArtifactUtils.copyArtifactSafe( original.getPluginArtifact() ) );
+
+ clone.setComponents( clone( original.getMojos(), clone ) );
+ clone.setId( original.getId() );
+ clone.setIsolatedRealm( original.isIsolatedRealm() );
+ clone.setSource( original.getSource() );
+
+ clone.setDependencies( original.getDependencies() );
+ }
+
+ return clone;
+ }
+
+ private static List<ComponentDescriptor<?>> clone( List<MojoDescriptor> mojos, PluginDescriptor pluginDescriptor )
+ {
+ List<ComponentDescriptor<?>> clones = null;
+
+ if ( mojos != null )
+ {
+ clones = new ArrayList<ComponentDescriptor<?>>( mojos.size() );
+
+ for ( MojoDescriptor mojo : mojos )
+ {
+ MojoDescriptor clone = mojo.clone();
+ clone.setPluginDescriptor( pluginDescriptor );
+ clones.add( clone );
+ }
+ }
+
+ return clones;
+ }
+
+ private static final class CacheKey
+ implements Key
+ {
+
+ private final String groupId;
+
+ private final String artifactId;
+
+ private final String version;
+
+ private final WorkspaceRepository workspace;
+
+ private final LocalRepository localRepo;
+
+ private final List<RemoteRepository> repositories;
+
+ private final int hashCode;
+
+ public CacheKey( Plugin plugin, List<RemoteRepository> repositories, RepositorySystemSession session )
+ {
+ groupId = plugin.getGroupId();
+ artifactId = plugin.getArtifactId();
+ version = plugin.getVersion();
+
+ workspace = CacheUtils.getWorkspace( session );
+ localRepo = session.getLocalRepository();
+ this.repositories = new ArrayList<RemoteRepository>( repositories.size() );
+ for ( RemoteRepository repository : repositories )
+ {
+ if ( repository.isRepositoryManager() )
+ {
+ this.repositories.addAll( repository.getMirroredRepositories() );
+ }
+ else
+ {
+ this.repositories.add( repository );
+ }
+ }
+
+ int hash = 17;
+ hash = hash * 31 + groupId.hashCode();
+ hash = hash * 31 + artifactId.hashCode();
+ hash = hash * 31 + version.hashCode();
+ hash = hash * 31 + hash( workspace );
+ hash = hash * 31 + localRepo.hashCode();
+ hash = hash * 31 + CacheUtils.repositoriesHashCode( repositories );
+ this.hashCode = hash;
+ }
+
+ @Override
+ public int hashCode()
+ {
+ return hashCode;
+ }
+
+ @Override
+ public boolean equals( Object obj )
+ {
+ if ( this == obj )
+ {
+ return true;
+ }
+
+ if ( !( obj instanceof CacheKey ) )
+ {
+ return false;
+ }
+
+ CacheKey that = (CacheKey) obj;
+
+ return eq( this.artifactId, that.artifactId ) && eq( this.groupId, that.groupId )
+ && eq( this.version, that.version ) && eq( this.localRepo, that.localRepo )
+ && eq( this.workspace, that.workspace )
+ && CacheUtils.repositoriesEquals( this.repositories, that.repositories );
+ }
+
+ @Override
+ public String toString()
+ {
+ return groupId + ':' + artifactId + ':' + version;
+ }
+
+ private static int hash( Object obj )
+ {
+ return obj != null ? obj.hashCode() : 0;
+ }
+
+ private static <T> boolean eq( T s1, T s2 )
+ {
+ return s1 != null ? s1.equals( s2 ) : s2 == null;
+ }
+
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/DefaultPluginRealmCache.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/DefaultPluginRealmCache.java
new file mode 100644
index 00000000..6c8288ee
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/DefaultPluginRealmCache.java
@@ -0,0 +1,219 @@
+package org.apache.maven.plugin;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.model.Plugin;
+import org.apache.maven.project.MavenProject;
+import org.codehaus.plexus.classworlds.realm.ClassRealm;
+import org.codehaus.plexus.classworlds.realm.NoSuchRealmException;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.personality.plexus.lifecycle.phase.Disposable;
+import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.graph.DependencyFilter;
+import org.eclipse.aether.repository.LocalRepository;
+import org.eclipse.aether.repository.RemoteRepository;
+import org.eclipse.aether.repository.WorkspaceRepository;
+
+/**
+ * Default PluginCache implementation. Assumes cached data does not change.
+ */
+@Component( role = PluginRealmCache.class )
+public class DefaultPluginRealmCache
+ implements PluginRealmCache, Disposable
+{
+
+ protected static class CacheKey
+ implements Key
+ {
+
+ private final Plugin plugin;
+
+ private final WorkspaceRepository workspace;
+
+ private final LocalRepository localRepo;
+
+ private final List<RemoteRepository> repositories;
+
+ private final ClassLoader parentRealm;
+
+ private final Map<String, ClassLoader> foreignImports;
+
+ private final DependencyFilter filter;
+
+ private final int hashCode;
+
+ public CacheKey( Plugin plugin, ClassLoader parentRealm, Map<String, ClassLoader> foreignImports,
+ DependencyFilter dependencyFilter, List<RemoteRepository> repositories,
+ RepositorySystemSession session )
+ {
+ this.plugin = plugin.clone();
+ this.workspace = CacheUtils.getWorkspace( session );
+ this.localRepo = session.getLocalRepository();
+ this.repositories = new ArrayList<RemoteRepository>( repositories.size() );
+ for ( RemoteRepository repository : repositories )
+ {
+ if ( repository.isRepositoryManager() )
+ {
+ this.repositories.addAll( repository.getMirroredRepositories() );
+ }
+ else
+ {
+ this.repositories.add( repository );
+ }
+ }
+ this.parentRealm = parentRealm;
+ this.foreignImports =
+ ( foreignImports != null ) ? foreignImports : Collections.<String, ClassLoader>emptyMap();
+ this.filter = dependencyFilter;
+
+ int hash = 17;
+ hash = hash * 31 + CacheUtils.pluginHashCode( plugin );
+ hash = hash * 31 + hash( workspace );
+ hash = hash * 31 + hash( localRepo );
+ hash = hash * 31 + CacheUtils.repositoriesHashCode( repositories );
+ hash = hash * 31 + hash( parentRealm );
+ hash = hash * 31 + this.foreignImports.hashCode();
+ hash = hash * 31 + hash( dependencyFilter );
+ this.hashCode = hash;
+ }
+
+ @Override
+ public String toString()
+ {
+ return plugin.getId();
+ }
+
+ @Override
+ public int hashCode()
+ {
+ return hashCode;
+ }
+
+ private static int hash( Object obj )
+ {
+ return obj != null ? obj.hashCode() : 0;
+ }
+
+ @Override
+ public boolean equals( Object o )
+ {
+ if ( o == this )
+ {
+ return true;
+ }
+
+ if ( !( o instanceof CacheKey ) )
+ {
+ return false;
+ }
+
+ CacheKey that = (CacheKey) o;
+
+ return parentRealm == that.parentRealm && CacheUtils.pluginEquals( plugin, that.plugin )
+ && eq( workspace, that.workspace ) && eq( localRepo, that.localRepo )
+ && CacheUtils.repositoriesEquals( this.repositories, that.repositories ) && eq( filter, that.filter )
+ && eq( foreignImports, that.foreignImports );
+ }
+
+ private static <T> boolean eq( T s1, T s2 )
+ {
+ return s1 != null ? s1.equals( s2 ) : s2 == null;
+ }
+
+ }
+
+ protected final Map<Key, CacheRecord> cache = new ConcurrentHashMap<Key, CacheRecord>();
+
+ public Key createKey( Plugin plugin, ClassLoader parentRealm, Map<String, ClassLoader> foreignImports,
+ DependencyFilter dependencyFilter, List<RemoteRepository> repositories,
+ RepositorySystemSession session )
+ {
+ return new CacheKey( plugin, parentRealm, foreignImports, dependencyFilter, repositories, session );
+ }
+
+ public CacheRecord get( Key key )
+ {
+ return cache.get( key );
+ }
+
+ public CacheRecord put( Key key, ClassRealm pluginRealm, List<Artifact> pluginArtifacts )
+ {
+ if ( pluginRealm == null || pluginArtifacts == null )
+ {
+ throw new IllegalArgumentException();
+ }
+
+ if ( cache.containsKey( key ) )
+ {
+ throw new IllegalStateException( "Duplicate plugin realm for plugin " + key );
+ }
+
+ CacheRecord record = new CacheRecord( pluginRealm, pluginArtifacts );
+
+ cache.put( key, record );
+
+ return record;
+ }
+
+ public void flush()
+ {
+ for ( CacheRecord record : cache.values() )
+ {
+ ClassRealm realm = record.realm;
+ try
+ {
+ realm.getWorld().disposeRealm( realm.getId() );
+ }
+ catch ( NoSuchRealmException e )
+ {
+ // ignore
+ }
+ }
+ cache.clear();
+ }
+
+ protected static int pluginHashCode( Plugin plugin )
+ {
+ return CacheUtils.pluginHashCode( plugin );
+ }
+
+ protected static boolean pluginEquals( Plugin a, Plugin b )
+ {
+ return CacheUtils.pluginEquals( a, b );
+ }
+
+ public void register( MavenProject project, Key key, CacheRecord record )
+ {
+ // default cache does not track plugin usage
+ }
+
+ public void dispose()
+ {
+ flush();
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/ExtensionRealmCache.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/ExtensionRealmCache.java
new file mode 100644
index 00000000..d50df0e9
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/ExtensionRealmCache.java
@@ -0,0 +1,84 @@
+package org.apache.maven.plugin;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.List;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.project.ExtensionDescriptor;
+import org.apache.maven.project.MavenProject;
+import org.codehaus.plexus.classworlds.realm.ClassRealm;
+
+/**
+ * Caches extension class realms. <strong>Warning:</strong> This is an internal utility interface that is only public
+ * for technical reasons, it is not part of the public API. In particular, this interface can be changed or deleted
+ * without prior notice.
+ *
+ * @author Igor Fedorenko
+ * @author Benjamin Bentmann
+ */
+public interface ExtensionRealmCache
+{
+ /**
+ * A cache key.
+ */
+ interface Key
+ {
+ // marker interface for cache keys
+ }
+
+ static class CacheRecord
+ {
+
+ public final ClassRealm realm;
+
+ public final ExtensionDescriptor desciptor;
+
+ public final List<Artifact> artifacts;
+
+ public CacheRecord( ClassRealm realm, ExtensionDescriptor descriptor, List<Artifact> artifacts )
+ {
+ this.realm = realm;
+ this.desciptor = descriptor;
+ this.artifacts = artifacts;
+ }
+
+ }
+
+ Key createKey( List<Artifact> extensionArtifacts );
+
+ CacheRecord get( Key key );
+
+ CacheRecord put( Key key, ClassRealm extensionRealm, ExtensionDescriptor extensionDescriptor,
+ List<Artifact> artifacts );
+
+ void flush();
+
+ /**
+ * Registers the specified cache record for usage with the given project. Integrators can use the information
+ * collected from this method in combination with a custom cache implementation to dispose unused records from the
+ * cache.
+ *
+ * @param project The project that employs the plugin realm, must not be {@code null}.
+ * @param record The cache record being used for the project, must not be {@code null}.
+ */
+ void register( MavenProject project, Key key, CacheRecord record );
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/InvalidPluginDescriptorException.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/InvalidPluginDescriptorException.java
new file mode 100644
index 00000000..223ccd81
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/InvalidPluginDescriptorException.java
@@ -0,0 +1,44 @@
+package org.apache.maven.plugin;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.List;
+
+public class InvalidPluginDescriptorException
+ extends Exception
+{
+
+ public InvalidPluginDescriptorException( String message, List<String> errors )
+ {
+ super( toMessage( message, errors ) );
+ }
+
+ private static String toMessage( String message, List<String> errors )
+ {
+ StringBuilder buffer = new StringBuilder( 256 );
+ buffer.append( message );
+ for ( String error : errors )
+ {
+ buffer.append( ", " ).append( error );
+ }
+ return buffer.toString();
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/InvalidPluginException.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/InvalidPluginException.java
new file mode 100644
index 00000000..b89fc869
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/InvalidPluginException.java
@@ -0,0 +1,48 @@
+package org.apache.maven.plugin;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.project.ProjectBuildingException;
+import org.apache.maven.project.artifact.InvalidDependencyVersionException;
+
+/**
+ * Thrown when a plugin is not internally consistent.
+ *
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ */
+public class InvalidPluginException
+ extends Exception
+{
+ public InvalidPluginException( String message, ProjectBuildingException e )
+ {
+ super( message, e );
+ }
+
+ public InvalidPluginException( String message, InvalidDependencyVersionException e )
+ {
+ super( message, e );
+ }
+
+ public InvalidPluginException( String message )
+ {
+ super( message );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/LegacySupport.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/LegacySupport.java
new file mode 100644
index 00000000..b246ed18
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/LegacySupport.java
@@ -0,0 +1,59 @@
+package org.apache.maven.plugin;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.execution.MavenSession;
+import org.eclipse.aether.RepositorySystemSession;
+
+/**
+ * Helps to provide backward-compatibility with plugins that use legacy components. <strong>Warning:</strong> This is an
+ * internal utility interface that is only public for technical reasons, it is not part of the public API. In
+ * particular, this interface can be changed or deleted without prior notice.
+ *
+ * @since 3.0
+ * @author Benjamin Bentmann
+ */
+public interface LegacySupport
+{
+
+ /**
+ * Sets the currently active session. Some legacy components are basically stateful and their API is missing
+ * parameters that would be required to delegate to a stateless component. Saving the session (in a thread-local
+ * variable) is our best effort to record any state that is required to enable proper delegation.
+ *
+ * @param session The currently active session, may be {@code null}.
+ */
+ void setSession( MavenSession session );
+
+ /**
+ * Gets the currently active session.
+ *
+ * @return The currently active session or {@code null} if none.
+ */
+ MavenSession getSession();
+
+ /**
+ * Gets the currently active repository session.
+ *
+ * @return The currently active repository session or {@code null} if none.
+ */
+ RepositorySystemSession getRepositorySession();
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/MavenPluginManager.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/MavenPluginManager.java
new file mode 100644
index 00000000..b228a1b4
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/MavenPluginManager.java
@@ -0,0 +1,128 @@
+package org.apache.maven.plugin;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.List;
+
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.model.Plugin;
+import org.apache.maven.plugin.descriptor.MojoDescriptor;
+import org.apache.maven.plugin.descriptor.PluginDescriptor;
+import org.apache.maven.project.MavenProject;
+import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.graph.DependencyFilter;
+import org.eclipse.aether.repository.RemoteRepository;
+
+/**
+ * Provides basic services to manage Maven plugins and their mojos. This component is kept general in its design such
+ * that the plugins/mojos can be used in arbitrary contexts. In particular, the mojos can be used for ordinary build
+ * plugins as well as special purpose plugins like reports.
+ *
+ * @since 3.0
+ * @author Benjamin Bentmann
+ */
+public interface MavenPluginManager
+{
+
+ /**
+ * Retrieves the descriptor for the specified plugin from its main artifact.
+ *
+ * @param plugin The plugin whose descriptor should be retrieved, must not be {@code null}.
+ * @param repositories The plugin repositories to use for resolving the plugin's main artifact, must not be {@code
+ * null}.
+ * @param session The repository session to use for resolving the plugin's main artifact, must not be {@code null}.
+ * @return The plugin descriptor, never {@code null}.
+ */
+ PluginDescriptor getPluginDescriptor( Plugin plugin, List<RemoteRepository> repositories,
+ RepositorySystemSession session )
+ throws PluginResolutionException, PluginDescriptorParsingException, InvalidPluginDescriptorException;
+
+ /**
+ * Retrieves the descriptor for the specified plugin goal from the plugin's main artifact.
+ *
+ * @param plugin The plugin whose mojo descriptor should be retrieved, must not be {@code null}.
+ * @param goal The simple name of the mojo whose descriptor should be retrieved, must not be {@code null}.
+ * @param repositories The plugin repositories to use for resolving the plugin's main artifact, must not be {@code
+ * null}.
+ * @param session The repository session to use for resolving the plugin's main artifact, must not be {@code null}.
+ * @return The mojo descriptor, never {@code null}.
+ */
+ MojoDescriptor getMojoDescriptor( Plugin plugin, String goal, List<RemoteRepository> repositories,
+ RepositorySystemSession session )
+ throws MojoNotFoundException, PluginResolutionException, PluginDescriptorParsingException,
+ InvalidPluginDescriptorException;
+
+ /**
+ * Verifies the specified plugin is compatible with the current Maven runtime.
+ *
+ * @param pluginDescriptor The descriptor of the plugin to check, must not be {@code null}.
+ */
+ void checkRequiredMavenVersion( PluginDescriptor pluginDescriptor )
+ throws PluginIncompatibleException;
+
+ /**
+ * Sets up the class realm for the specified plugin. Both the class realm and the plugin artifacts that constitute
+ * it will be stored in the plugin descriptor.
+ *
+ * @param pluginDescriptor The plugin descriptor in which to save the class realm and the plugin artifacts, must not
+ * be {@code null}.
+ * @param session The build session from which to pick the current project and repository settings, must not be
+ * {@code null}.
+ * @param parent The parent class realm for the plugin, may be {@code null} to use the Maven core realm.
+ * @param imports The packages/types to import from the parent realm, may be {@code null}.
+ * @param filter The filter used to exclude certain plugin dependencies, may be {@code null}.
+ */
+ void setupPluginRealm( PluginDescriptor pluginDescriptor, MavenSession session, ClassLoader parent,
+ List<String> imports, DependencyFilter filter )
+ throws PluginResolutionException, PluginContainerException;
+
+ /**
+ * Sets up class realm for the specified build extensions plugin.
+ *
+ * @since 3.3.0
+ */
+ ExtensionRealmCache.CacheRecord setupExtensionsRealm( MavenProject project, Plugin plugin,
+ RepositorySystemSession session )
+ throws PluginManagerException;
+
+ /**
+ * Looks up the mojo for the specified mojo execution and populates its parameters from the configuration given by
+ * the mojo execution. The mojo/plugin descriptor associated with the mojo execution provides the class realm to
+ * lookup the mojo from. <strong>Warning:</strong> The returned mojo instance must be released via
+ * {@link #releaseMojo(Object, MojoExecution)} when the mojo is no longer needed to free any resources allocated for
+ * it.
+ *
+ * @param mojoInterface The component role of the mojo, must not be {@code null}.
+ * @param session The build session in whose context the mojo will be used, must not be {@code null}.
+ * @param mojoExecution The mojo execution to retrieve the mojo for, must not be {@code null}.
+ * @return The ready-to-execute mojo, never {@code null}.
+ */
+ <T> T getConfiguredMojo( Class<T> mojoInterface, MavenSession session, MojoExecution mojoExecution )
+ throws PluginConfigurationException, PluginContainerException;
+
+ /**
+ * Releases the specified mojo back to the container.
+ *
+ * @param mojo The mojo to release, may be {@code null}.
+ * @param mojoExecution The mojo execution the mojo was originally retrieved for, must not be {@code null}.
+ */
+ void releaseMojo( Object mojo, MojoExecution mojoExecution );
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/MavenPluginValidator.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/MavenPluginValidator.java
new file mode 100644
index 00000000..2eb2738b
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/MavenPluginValidator.java
@@ -0,0 +1,78 @@
+package org.apache.maven.plugin;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.plugin.descriptor.PluginDescriptor;
+
+public class MavenPluginValidator
+{
+ private final Artifact pluginArtifact;
+
+ private List<String> errors = new ArrayList<String>();
+
+ private boolean firstDescriptor = true;
+
+ public MavenPluginValidator( Artifact pluginArtifact )
+ {
+ this.pluginArtifact = pluginArtifact;
+ }
+
+ public void validate( PluginDescriptor pluginDescriptor )
+ {
+ /*
+ * NOTE: For plugins that depend on other plugin artifacts the plugin realm contains more than one plugin
+ * descriptor. However, only the first descriptor is of interest.
+ */
+ if ( !firstDescriptor )
+ {
+ return;
+ }
+ firstDescriptor = false;
+
+ if ( !pluginArtifact.getGroupId().equals( pluginDescriptor.getGroupId() ) )
+ {
+ errors.add( "Plugin's descriptor contains the wrong group ID: " + pluginDescriptor.getGroupId() );
+ }
+
+ if ( !pluginArtifact.getArtifactId().equals( pluginDescriptor.getArtifactId() ) )
+ {
+ errors.add( "Plugin's descriptor contains the wrong artifact ID: " + pluginDescriptor.getArtifactId() );
+ }
+
+ if ( !pluginArtifact.getBaseVersion().equals( pluginDescriptor.getVersion() ) )
+ {
+ errors.add( "Plugin's descriptor contains the wrong version: " + pluginDescriptor.getVersion() );
+ }
+ }
+
+ public boolean hasErrors()
+ {
+ return !errors.isEmpty();
+ }
+
+ public List<String> getErrors()
+ {
+ return errors;
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/MojoExecution.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/MojoExecution.java
new file mode 100644
index 00000000..a417219e
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/MojoExecution.java
@@ -0,0 +1,237 @@
+package org.apache.maven.plugin;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.maven.model.Plugin;
+import org.apache.maven.plugin.descriptor.MojoDescriptor;
+import org.codehaus.plexus.util.xml.Xpp3Dom;
+
+public class MojoExecution
+{
+
+ private Plugin plugin;
+
+ private String goal;
+
+ private String executionId;
+
+ private MojoDescriptor mojoDescriptor;
+
+ private Xpp3Dom configuration;
+
+ /**
+ * Describes the source of an execution.
+ */
+ public enum Source
+ {
+
+ /**
+ * An execution that originates from the direct invocation of a goal from the CLI.
+ */
+ CLI,
+
+ /**
+ * An execution that originates from a goal bound to a lifecycle phase.
+ */
+ LIFECYCLE,
+ }
+
+ private Source source = Source.LIFECYCLE;
+
+ /**
+ * The phase may or may not have been bound to a phase but once the plan has been calculated we know what phase
+ * this mojo execution is going to run in.
+ */
+ private String lifecyclePhase;
+
+ /**
+ * The executions to fork before this execution, indexed by the groupId:artifactId:version of the project on which
+ * the forked execution are to be run and in reactor build order.
+ */
+ private Map<String, List<MojoExecution>> forkedExecutions = new LinkedHashMap<String, List<MojoExecution>>();
+
+ public MojoExecution( Plugin plugin, String goal, String executionId )
+ {
+ this.plugin = plugin;
+ this.goal = goal;
+ this.executionId = executionId;
+ }
+
+ public MojoExecution( MojoDescriptor mojoDescriptor )
+ {
+ this.mojoDescriptor = mojoDescriptor;
+ this.executionId = null;
+ this.configuration = null;
+ }
+
+ public MojoExecution( MojoDescriptor mojoDescriptor, String executionId, Source source )
+ {
+ this.mojoDescriptor = mojoDescriptor;
+ this.executionId = executionId;
+ this.configuration = null;
+ this.source = source;
+ }
+
+ public MojoExecution( MojoDescriptor mojoDescriptor, String executionId )
+ {
+ this.mojoDescriptor = mojoDescriptor;
+ this.executionId = executionId;
+ this.configuration = null;
+ }
+
+ public MojoExecution( MojoDescriptor mojoDescriptor, Xpp3Dom configuration )
+ {
+ this.mojoDescriptor = mojoDescriptor;
+ this.configuration = configuration;
+ this.executionId = null;
+ }
+
+ /**
+ * Gets the source of this execution.
+ *
+ * @return The source of this execution or {@code null} if unknown.
+ */
+ public Source getSource()
+ {
+ return source;
+ }
+
+ public String getExecutionId()
+ {
+ return executionId;
+ }
+
+ public Plugin getPlugin()
+ {
+ if ( mojoDescriptor != null )
+ {
+ return mojoDescriptor.getPluginDescriptor().getPlugin();
+ }
+
+ return plugin;
+ }
+
+ public MojoDescriptor getMojoDescriptor()
+ {
+ return mojoDescriptor;
+ }
+
+ public Xpp3Dom getConfiguration()
+ {
+ return configuration;
+ }
+
+ public void setConfiguration( Xpp3Dom configuration )
+ {
+ this.configuration = configuration;
+ }
+
+ public String identify()
+ {
+ StringBuilder sb = new StringBuilder( 256 );
+
+ sb.append( executionId );
+ sb.append( configuration.toString() );
+
+ return sb.toString();
+ }
+
+ public String getLifecyclePhase()
+ {
+ return lifecyclePhase;
+ }
+
+ public void setLifecyclePhase( String lifecyclePhase )
+ {
+ this.lifecyclePhase = lifecyclePhase;
+ }
+
+ @Override
+ public String toString()
+ {
+ StringBuilder buffer = new StringBuilder( 128 );
+ if ( mojoDescriptor != null )
+ {
+ buffer.append( mojoDescriptor.getId() );
+ }
+ buffer.append( " {execution: " ).append( executionId ).append( "}" );
+ return buffer.toString();
+ }
+
+ public String getGroupId()
+ {
+ if ( mojoDescriptor != null )
+ {
+ return mojoDescriptor.getPluginDescriptor().getGroupId();
+ }
+
+ return plugin.getGroupId();
+ }
+
+ public String getArtifactId()
+ {
+ if ( mojoDescriptor != null )
+ {
+ return mojoDescriptor.getPluginDescriptor().getArtifactId();
+ }
+
+ return plugin.getArtifactId();
+ }
+
+ public String getVersion()
+ {
+ if ( mojoDescriptor != null )
+ {
+ return mojoDescriptor.getPluginDescriptor().getVersion();
+ }
+
+ return plugin.getVersion();
+ }
+
+ public String getGoal()
+ {
+ if ( mojoDescriptor != null )
+ {
+ return mojoDescriptor.getGoal();
+ }
+
+ return goal;
+ }
+
+ public void setMojoDescriptor( MojoDescriptor mojoDescriptor )
+ {
+ this.mojoDescriptor = mojoDescriptor;
+ }
+
+ public Map<String, List<MojoExecution>> getForkedExecutions()
+ {
+ return forkedExecutions;
+ }
+
+ public void setForkedExecutions( String projectKey, List<MojoExecution> forkedExecutions )
+ {
+ this.forkedExecutions.put( projectKey, forkedExecutions );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/PluginArtifactsCache.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/PluginArtifactsCache.java
new file mode 100644
index 00000000..17537a29
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/PluginArtifactsCache.java
@@ -0,0 +1,91 @@
+package org.apache.maven.plugin;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.List;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.model.Plugin;
+import org.apache.maven.project.MavenProject;
+import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.graph.DependencyFilter;
+import org.eclipse.aether.repository.RemoteRepository;
+
+/**
+ * Caches plugin artifacts. <strong>Warning:</strong> This is an internal utility interface that is only public for
+ * technical reasons, it is not part of the public API. In particular, this interface can be changed or deleted without
+ * prior notice.
+ *
+ * @author Igor Fedorenko
+ * @author Benjamin Bentmann
+ */
+public interface PluginArtifactsCache
+{
+
+ /**
+ * A cache key.
+ */
+ interface Key
+ {
+ // marker interface for cache keys
+ }
+
+ static class CacheRecord
+ {
+
+ public final List<Artifact> artifacts;
+
+ public final PluginResolutionException exception;
+
+ public CacheRecord( List<Artifact> artifacts )
+ {
+ this.artifacts = artifacts;
+ this.exception = null;
+ }
+
+ public CacheRecord( PluginResolutionException exception )
+ {
+ this.artifacts = null;
+ this.exception = exception;
+ }
+ }
+
+ Key createKey( Plugin plugin, DependencyFilter extensionFilter, List<RemoteRepository> repositories,
+ RepositorySystemSession session );
+
+ CacheRecord get( Key key ) throws PluginResolutionException;
+
+ CacheRecord put( Key key, List<Artifact> pluginArtifacts );
+
+ CacheRecord put( Key key, PluginResolutionException e );
+
+ void flush();
+
+ /**
+ * Registers the specified cache record for usage with the given project. Integrators can use the information
+ * collected from this method in combination with a custom cache implementation to dispose unused records from the
+ * cache.
+ *
+ * @param project The project that employs the plugin realm, must not be {@code null}.
+ * @param record The cache record being used for the project, must not be {@code null}.
+ */
+ void register( MavenProject project, Key cacheKey, CacheRecord record );
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/PluginConfigurationException.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/PluginConfigurationException.java
new file mode 100644
index 00000000..f4dcffcd
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/PluginConfigurationException.java
@@ -0,0 +1,74 @@
+package org.apache.maven.plugin;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.plugin.descriptor.PluginDescriptor;
+import org.codehaus.plexus.component.configurator.ComponentConfigurationException;
+import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluationException;
+import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
+
+/**
+ * @author Jason van Zyl
+ */
+public class PluginConfigurationException
+ extends Exception
+{
+ private PluginDescriptor pluginDescriptor;
+
+ private String originalMessage;
+
+ public PluginConfigurationException( PluginDescriptor pluginDescriptor, String originalMessage )
+ {
+ super( originalMessage );
+ this.pluginDescriptor = pluginDescriptor;
+ this.originalMessage = originalMessage;
+ }
+
+ public PluginConfigurationException( PluginDescriptor pluginDescriptor, String originalMessage, Throwable cause )
+ {
+ super( originalMessage, cause );
+ this.pluginDescriptor = pluginDescriptor;
+ this.originalMessage = originalMessage;
+ }
+
+ public PluginConfigurationException( PluginDescriptor pluginDescriptor, String originalMessage,
+ ExpressionEvaluationException cause )
+ {
+ super( originalMessage, cause );
+ this.pluginDescriptor = pluginDescriptor;
+ this.originalMessage = originalMessage;
+ }
+
+ public PluginConfigurationException( PluginDescriptor pluginDescriptor, String originalMessage,
+ ComponentConfigurationException cause )
+ {
+ super( originalMessage, cause );
+ this.pluginDescriptor = pluginDescriptor;
+ this.originalMessage = originalMessage;
+ }
+
+ public PluginConfigurationException( PluginDescriptor pluginDescriptor, String originalMessage,
+ ComponentLookupException cause )
+ {
+ super( originalMessage, cause );
+ this.pluginDescriptor = pluginDescriptor;
+ this.originalMessage = originalMessage;
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/PluginContainerException.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/PluginContainerException.java
new file mode 100644
index 00000000..d35ac6c3
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/PluginContainerException.java
@@ -0,0 +1,88 @@
+package org.apache.maven.plugin;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.model.Plugin;
+import org.apache.maven.plugin.descriptor.MojoDescriptor;
+import org.codehaus.plexus.classworlds.realm.ClassRealm;
+import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
+import org.codehaus.plexus.component.repository.exception.ComponentRepositoryException;
+import org.codehaus.plexus.configuration.PlexusConfigurationException;
+
+/**
+ * Exception which occurs to indicate that the plugin cannot be initialized due
+ * to some deeper problem with Plexus. Context information includes the groupId,
+ * artifactId, and version for the plugin; at times, the goal name for which
+ * execution failed; a message detailing the problem; the ClassRealm used to
+ * lookup the plugin; and the Plexus exception that caused this error.
+ *
+ * @author jdcasey
+ *
+ */
+public class PluginContainerException
+ extends PluginManagerException
+{
+
+ private ClassRealm pluginRealm;
+
+ public PluginContainerException( MojoDescriptor mojoDescriptor, ClassRealm pluginRealm, String message,
+ Throwable e )
+ {
+ super( mojoDescriptor, message, e );
+
+ this.pluginRealm = pluginRealm;
+ }
+
+ public PluginContainerException( MojoDescriptor mojoDescriptor, ClassRealm pluginRealm, String message,
+ ComponentLookupException e )
+ {
+ super( mojoDescriptor, message, e );
+
+ this.pluginRealm = pluginRealm;
+ }
+
+ public PluginContainerException( Plugin plugin, ClassRealm pluginRealm, String message, Throwable e )
+ {
+ super( plugin, message, e );
+
+ this.pluginRealm = pluginRealm;
+ }
+
+ public PluginContainerException( Plugin plugin, ClassRealm pluginRealm, String message,
+ PlexusConfigurationException e )
+ {
+ super( plugin, message, e );
+
+ this.pluginRealm = pluginRealm;
+ }
+
+ public PluginContainerException( Plugin plugin, ClassRealm pluginRealm, String message,
+ ComponentRepositoryException e )
+ {
+ super( plugin, message, e );
+
+ this.pluginRealm = pluginRealm;
+ }
+
+ public ClassRealm getPluginRealm()
+ {
+ return pluginRealm;
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/PluginDescriptorCache.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/PluginDescriptorCache.java
new file mode 100644
index 00000000..08b4f1bc
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/PluginDescriptorCache.java
@@ -0,0 +1,58 @@
+package org.apache.maven.plugin;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.List;
+
+import org.apache.maven.model.Plugin;
+import org.apache.maven.plugin.descriptor.PluginDescriptor;
+import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.repository.RemoteRepository;
+
+/**
+ * Caches raw plugin descriptors. A raw plugin descriptor is a descriptor that has just been extracted from the plugin
+ * artifact and does not contain any runtime specific data. The cache must not be used for descriptors that hold runtime
+ * data like the plugin realm. <strong>Warning:</strong> This is an internal utility interface that is only public for
+ * technical reasons, it is not part of the public API. In particular, this interface can be changed or deleted without
+ * prior notice.
+ *
+ * @since 3.0
+ * @author Benjamin Bentmann
+ */
+public interface PluginDescriptorCache
+{
+
+ /**
+ * A cache key.
+ */
+ interface Key
+ {
+ // marker interface for cache keys
+ }
+
+ Key createKey( Plugin plugin, List<RemoteRepository> repositories, RepositorySystemSession session );
+
+ void put( Key key, PluginDescriptor pluginDescriptor );
+
+ PluginDescriptor get( Key key );
+
+ void flush();
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/PluginDescriptorParsingException.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/PluginDescriptorParsingException.java
new file mode 100644
index 00000000..7d57b363
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/PluginDescriptorParsingException.java
@@ -0,0 +1,58 @@
+package org.apache.maven.plugin;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.model.Plugin;
+
+/**
+ * @author Jason van Zyl
+ */
+public class PluginDescriptorParsingException
+ extends Exception
+{
+
+ public PluginDescriptorParsingException( Plugin plugin, String descriptorLocation, Throwable e )
+ {
+ super( createMessage( plugin, descriptorLocation, e ), e );
+ }
+
+ private static String createMessage( Plugin plugin, String descriptorLocation, Throwable e )
+ {
+ String message = "Failed to parse plugin descriptor";
+
+ if ( plugin != null )
+ {
+ message += " for " + plugin.getId();
+ }
+
+ if ( descriptorLocation != null )
+ {
+ message += " (" + descriptorLocation + ")";
+ }
+
+ if ( e != null )
+ {
+ message += ": " + e.getMessage();
+ }
+
+ return message;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/PluginExecutionException.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/PluginExecutionException.java
new file mode 100644
index 00000000..602d2cb4
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/PluginExecutionException.java
@@ -0,0 +1,90 @@
+package org.apache.maven.plugin;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.project.DuplicateArtifactAttachmentException;
+import org.apache.maven.project.MavenProject;
+import org.codehaus.plexus.util.StringUtils;
+
+public class PluginExecutionException
+ extends PluginManagerException
+{
+
+ private final MojoExecution mojoExecution;
+
+ public PluginExecutionException( MojoExecution mojoExecution, MavenProject project, String message )
+ {
+ super( mojoExecution.getMojoDescriptor(), project, message );
+ this.mojoExecution = mojoExecution;
+ }
+
+ public PluginExecutionException( MojoExecution mojoExecution, MavenProject project, String message,
+ Throwable cause )
+ {
+ super( mojoExecution.getMojoDescriptor(), project, message, cause );
+ this.mojoExecution = mojoExecution;
+ }
+
+ public PluginExecutionException( MojoExecution mojoExecution, MavenProject project, Exception cause )
+ {
+ super( mojoExecution.getMojoDescriptor(), project, constructMessage( mojoExecution, cause ), cause );
+ this.mojoExecution = mojoExecution;
+ }
+
+ public PluginExecutionException( MojoExecution mojoExecution, MavenProject project,
+ DuplicateArtifactAttachmentException cause )
+ {
+ super( mojoExecution.getMojoDescriptor(), project, constructMessage( mojoExecution, cause ), cause );
+ this.mojoExecution = mojoExecution;
+ }
+
+ public MojoExecution getMojoExecution()
+ {
+ return mojoExecution;
+ }
+
+ private static String constructMessage( MojoExecution mojoExecution, Throwable cause )
+ {
+ String message;
+
+ if ( mojoExecution != null )
+ {
+ message =
+ "Execution " + mojoExecution.getExecutionId() + " of goal " + mojoExecution.getMojoDescriptor().getId()
+ + " failed";
+ }
+ else
+ {
+ message = "Mojo execution failed";
+ }
+
+ if ( cause != null && StringUtils.isNotEmpty( cause.getMessage() ) )
+ {
+ message += ": " + cause.getMessage();
+ }
+ else
+ {
+ message += ".";
+ }
+
+ return message;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/PluginIncompatibleException.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/PluginIncompatibleException.java
new file mode 100644
index 00000000..f7b53ebd
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/PluginIncompatibleException.java
@@ -0,0 +1,36 @@
+package org.apache.maven.plugin;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.model.Plugin;
+
+/**
+ * Signals a plugin which is not compatible with the current Maven runtime.
+ */
+public class PluginIncompatibleException
+ extends PluginManagerException
+{
+
+ public PluginIncompatibleException( Plugin plugin, String message )
+ {
+ super( plugin, message, (Throwable) null );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/PluginLoaderException.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/PluginLoaderException.java
new file mode 100644
index 00000000..161e1c4e
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/PluginLoaderException.java
@@ -0,0 +1,124 @@
+package org.apache.maven.plugin;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
+import org.apache.maven.artifact.resolver.ArtifactResolutionException;
+import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
+import org.apache.maven.model.Plugin;
+import org.apache.maven.model.ReportPlugin;
+import org.apache.maven.plugin.version.PluginVersionNotFoundException;
+import org.apache.maven.plugin.version.PluginVersionResolutionException;
+
+/**
+ * Signifies a failure to load a plugin. This is used to abstract the specific errors which may be
+ * encountered at lower levels, and provide a dependable interface to the plugin-loading framework.
+ *
+ * @author jdcasey
+ *
+ */
+public class PluginLoaderException
+ extends Exception
+{
+
+ private String pluginKey;
+
+ public PluginLoaderException( Plugin plugin, String message, ArtifactResolutionException cause )
+ {
+ super( message, cause );
+ pluginKey = plugin.getKey();
+ }
+
+ public PluginLoaderException( Plugin plugin, String message, ArtifactNotFoundException cause )
+ {
+ super( message, cause );
+ pluginKey = plugin.getKey();
+ }
+
+ public PluginLoaderException( Plugin plugin, String message, PluginNotFoundException cause )
+ {
+ super( message, cause );
+ pluginKey = plugin.getKey();
+ }
+
+ public PluginLoaderException( Plugin plugin, String message, PluginVersionResolutionException cause )
+ {
+ super( message, cause );
+ pluginKey = plugin.getKey();
+ }
+
+ public PluginLoaderException( Plugin plugin, String message, InvalidVersionSpecificationException cause )
+ {
+ super( message, cause );
+ pluginKey = plugin.getKey();
+ }
+
+ public PluginLoaderException( Plugin plugin, String message, InvalidPluginException cause )
+ {
+ super( message, cause );
+ pluginKey = plugin.getKey();
+ }
+
+ public PluginLoaderException( Plugin plugin, String message, PluginManagerException cause )
+ {
+ super( message, cause );
+ pluginKey = plugin.getKey();
+ }
+
+ public PluginLoaderException( Plugin plugin, String message, PluginVersionNotFoundException cause )
+ {
+ super( message, cause );
+ pluginKey = plugin.getKey();
+ }
+
+ public PluginLoaderException( Plugin plugin, String message )
+ {
+ super( message );
+ pluginKey = plugin.getKey();
+ }
+
+ public PluginLoaderException( String message )
+ {
+ super( message );
+ }
+
+ public PluginLoaderException( String message, Throwable cause )
+ {
+ super( message, cause );
+ }
+
+ public PluginLoaderException( ReportPlugin plugin, String message, Throwable cause )
+ {
+ super( message, cause );
+ pluginKey = plugin.getKey();
+ }
+
+ public PluginLoaderException( ReportPlugin plugin, String message )
+ {
+ super( message );
+ pluginKey = plugin.getKey();
+ }
+
+ public String getPluginKey()
+ {
+ return pluginKey;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/PluginManager.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/PluginManager.java
new file mode 100644
index 00000000..1a3100e9
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/PluginManager.java
@@ -0,0 +1,82 @@
+package org.apache.maven.plugin;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
+import org.apache.maven.artifact.resolver.ArtifactResolutionException;
+import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.model.Plugin;
+import org.apache.maven.plugin.descriptor.PluginDescriptor;
+import org.apache.maven.plugin.version.PluginVersionNotFoundException;
+import org.apache.maven.plugin.version.PluginVersionResolutionException;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.project.artifact.InvalidDependencyVersionException;
+import org.apache.maven.settings.Settings;
+import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
+
+import java.util.Map;
+
+/**
+ * @author <a href="mailto:jason@maven.org">Jason van Zyl </a>
+ */
+@Deprecated
+public interface PluginManager
+{
+ String ROLE = PluginManager.class.getName();
+
+ void executeMojo( MavenProject project, MojoExecution execution, MavenSession session )
+ throws MojoExecutionException, ArtifactResolutionException, MojoFailureException, ArtifactNotFoundException,
+ InvalidDependencyVersionException, PluginManagerException, PluginConfigurationException;
+
+ PluginDescriptor getPluginDescriptorForPrefix( String prefix );
+
+ Plugin getPluginDefinitionForPrefix( String prefix, MavenSession session, MavenProject project );
+
+ PluginDescriptor verifyPlugin( Plugin plugin, MavenProject project, Settings settings,
+ ArtifactRepository localRepository )
+ throws ArtifactResolutionException, PluginVersionResolutionException, ArtifactNotFoundException,
+ InvalidVersionSpecificationException, InvalidPluginException, PluginManagerException, PluginNotFoundException,
+ PluginVersionNotFoundException;
+
+ Object getPluginComponent( Plugin plugin, String role, String roleHint )
+ throws PluginManagerException, ComponentLookupException;
+
+ Map getPluginComponents( Plugin plugin, String role )
+ throws ComponentLookupException, PluginManagerException;
+
+ /**
+ * @since 2.2.1
+ */
+ PluginDescriptor loadPluginDescriptor( Plugin plugin, MavenProject project, MavenSession session )
+ throws ArtifactResolutionException, PluginVersionResolutionException, ArtifactNotFoundException,
+ InvalidVersionSpecificationException, InvalidPluginException, PluginManagerException, PluginNotFoundException,
+ PluginVersionNotFoundException;
+
+ /**
+ * @since 2.2.1
+ */
+ PluginDescriptor loadPluginFully( Plugin plugin, MavenProject project, MavenSession session )
+ throws ArtifactResolutionException, PluginVersionResolutionException, ArtifactNotFoundException,
+ InvalidVersionSpecificationException, InvalidPluginException, PluginManagerException, PluginNotFoundException,
+ PluginVersionNotFoundException;
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/PluginManagerException.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/PluginManagerException.java
new file mode 100644
index 00000000..dc8f9a20
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/PluginManagerException.java
@@ -0,0 +1,197 @@
+package org.apache.maven.plugin;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
+import org.apache.maven.model.Plugin;
+import org.apache.maven.plugin.descriptor.MojoDescriptor;
+import org.apache.maven.plugin.descriptor.PluginDescriptor;
+import org.apache.maven.project.MavenProject;
+import org.codehaus.plexus.PlexusContainerException;
+import org.codehaus.plexus.classworlds.realm.NoSuchRealmException;
+import org.codehaus.plexus.component.repository.exception.ComponentRepositoryException;
+import org.codehaus.plexus.configuration.PlexusConfigurationException;
+
+/**
+ * Exception in the plugin manager.
+ *
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ */
+public class PluginManagerException
+ extends Exception
+{
+
+ private final String pluginGroupId;
+
+ private final String pluginArtifactId;
+
+ private final String pluginVersion;
+
+ private String goal;
+
+ private MavenProject project;
+
+ protected PluginManagerException( Plugin plugin, String message, MavenProject project, Throwable cause )
+ {
+ super( message, cause );
+
+ this.project = project;
+ pluginGroupId = plugin.getGroupId();
+ pluginArtifactId = plugin.getArtifactId();
+ pluginVersion = plugin.getVersion();
+ }
+
+ public PluginManagerException( Plugin plugin, String message, Throwable cause )
+ {
+ super( message, cause );
+
+ pluginGroupId = plugin.getGroupId();
+ pluginArtifactId = plugin.getArtifactId();
+ pluginVersion = plugin.getVersion();
+ }
+
+ protected PluginManagerException( MojoDescriptor mojoDescriptor, String message, Throwable cause )
+ {
+ super( message, cause );
+ pluginGroupId = mojoDescriptor.getPluginDescriptor().getGroupId();
+ pluginArtifactId = mojoDescriptor.getPluginDescriptor().getArtifactId();
+ pluginVersion = mojoDescriptor.getPluginDescriptor().getVersion();
+ goal = mojoDescriptor.getGoal();
+ }
+
+ protected PluginManagerException( MojoDescriptor mojoDescriptor, MavenProject project, String message )
+ {
+ super( message );
+ this.project = project;
+ pluginGroupId = mojoDescriptor.getPluginDescriptor().getGroupId();
+ pluginArtifactId = mojoDescriptor.getPluginDescriptor().getArtifactId();
+ pluginVersion = mojoDescriptor.getPluginDescriptor().getVersion();
+ goal = mojoDescriptor.getGoal();
+ }
+
+ protected PluginManagerException( MojoDescriptor mojoDescriptor, MavenProject project, String message,
+ Throwable cause )
+ {
+ super( message, cause );
+ this.project = project;
+ pluginGroupId = mojoDescriptor.getPluginDescriptor().getGroupId();
+ pluginArtifactId = mojoDescriptor.getPluginDescriptor().getArtifactId();
+ pluginVersion = mojoDescriptor.getPluginDescriptor().getVersion();
+ goal = mojoDescriptor.getGoal();
+ }
+
+ public PluginManagerException( Plugin plugin, InvalidVersionSpecificationException cause )
+ {
+ super( cause );
+
+ pluginGroupId = plugin.getGroupId();
+ pluginArtifactId = plugin.getArtifactId();
+ pluginVersion = plugin.getVersion();
+ }
+
+ public PluginManagerException( Plugin plugin, String message, PlexusConfigurationException cause )
+ {
+ super( message, cause );
+
+ pluginGroupId = plugin.getGroupId();
+ pluginArtifactId = plugin.getArtifactId();
+ pluginVersion = plugin.getVersion();
+ }
+
+ public PluginManagerException( Plugin plugin, String message, ComponentRepositoryException cause )
+ {
+ super( message, cause );
+
+ pluginGroupId = plugin.getGroupId();
+ pluginArtifactId = plugin.getArtifactId();
+ pluginVersion = plugin.getVersion();
+ }
+
+ public PluginManagerException( MojoDescriptor mojoDescriptor, MavenProject project, String message,
+ NoSuchRealmException cause )
+ {
+ super( message, cause );
+
+ this.project = project;
+ pluginGroupId = mojoDescriptor.getPluginDescriptor().getGroupId();
+ pluginArtifactId = mojoDescriptor.getPluginDescriptor().getArtifactId();
+ pluginVersion = mojoDescriptor.getPluginDescriptor().getVersion();
+ goal = mojoDescriptor.getGoal();
+ }
+
+ public PluginManagerException( MojoDescriptor mojoDescriptor, String message, MavenProject project,
+ PlexusContainerException cause )
+ {
+ super( message, cause );
+
+ this.project = project;
+
+ PluginDescriptor pd = mojoDescriptor.getPluginDescriptor();
+ pluginGroupId = pd.getGroupId();
+ pluginArtifactId = pd.getArtifactId();
+ pluginVersion = pd.getVersion();
+
+ goal = mojoDescriptor.getGoal();
+ }
+
+ public PluginManagerException( Plugin plugin, String message, PlexusContainerException cause )
+ {
+ super( message, cause );
+
+ pluginGroupId = plugin.getGroupId();
+ pluginArtifactId = plugin.getArtifactId();
+ pluginVersion = plugin.getVersion();
+ }
+
+ public PluginManagerException( Plugin plugin, String message, MavenProject project )
+ {
+ super( message );
+
+ pluginGroupId = plugin.getGroupId();
+ pluginArtifactId = plugin.getArtifactId();
+ pluginVersion = plugin.getVersion();
+ this.project = project;
+ }
+
+ public String getPluginGroupId()
+ {
+ return pluginGroupId;
+ }
+
+ public String getPluginArtifactId()
+ {
+ return pluginArtifactId;
+ }
+
+ public String getPluginVersion()
+ {
+ return pluginVersion;
+ }
+
+ public String getGoal()
+ {
+ return goal;
+ }
+
+ public MavenProject getProject()
+ {
+ return project;
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/PluginNotFoundException.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/PluginNotFoundException.java
new file mode 100644
index 00000000..ef54e2d7
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/PluginNotFoundException.java
@@ -0,0 +1,58 @@
+package org.apache.maven.plugin;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.List;
+
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.resolver.AbstractArtifactResolutionException;
+import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
+import org.apache.maven.model.Plugin;
+
+/**
+ * Exception occurring trying to resolve a plugin.
+ *
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ */
+public class PluginNotFoundException
+ extends AbstractArtifactResolutionException
+{
+ private Plugin plugin;
+
+ public PluginNotFoundException( Plugin plugin, ArtifactNotFoundException e )
+ {
+ super( "Plugin could not be found - check that the goal name is correct: " + e.getMessage(), e.getGroupId(),
+ e.getArtifactId(), e.getVersion(), "maven-plugin", null, e.getRemoteRepositories(), null, e.getCause() );
+ this.plugin = plugin;
+ }
+
+ public PluginNotFoundException( Plugin plugin, List<ArtifactRepository> remoteRepositories )
+ {
+ super( "Plugin could not be found, please check its coordinates for typos and ensure the required"
+ + " plugin repositories are defined in the POM", plugin.getGroupId(), plugin.getArtifactId(),
+ plugin.getVersion(), "maven-plugin", null, remoteRepositories, null );
+ this.plugin = plugin;
+ }
+
+ public Plugin getPlugin()
+ {
+ return plugin;
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/PluginParameterException.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/PluginParameterException.java
new file mode 100644
index 00000000..dcf459e7
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/PluginParameterException.java
@@ -0,0 +1,192 @@
+package org.apache.maven.plugin;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.maven.plugin.descriptor.MojoDescriptor;
+import org.apache.maven.plugin.descriptor.Parameter;
+import org.codehaus.plexus.util.StringUtils;
+
+public class PluginParameterException
+ extends PluginConfigurationException
+{
+
+ private final List<Parameter> parameters;
+
+ private final MojoDescriptor mojo;
+
+ public PluginParameterException( MojoDescriptor mojo, List<Parameter> parameters )
+ {
+ super( mojo.getPluginDescriptor(), "The parameters " + format( parameters ) + " for goal "
+ + mojo.getRoleHint() + " are missing or invalid" );
+
+ this.mojo = mojo;
+
+ this.parameters = parameters;
+ }
+
+ private static String format( List<Parameter> parameters )
+ {
+ StringBuilder buffer = new StringBuilder( 128 );
+ if ( parameters != null )
+ {
+ for ( Parameter parameter : parameters )
+ {
+ if ( buffer.length() > 0 )
+ {
+ buffer.append( ", " );
+ }
+ buffer.append( '\'' ).append( parameter.getName() ).append( '\'' );
+ }
+ }
+ return buffer.toString();
+ }
+
+ public MojoDescriptor getMojoDescriptor()
+ {
+ return mojo;
+ }
+
+ public List<Parameter> getParameters()
+ {
+ return parameters;
+ }
+
+ private static void decomposeParameterIntoUserInstructions( MojoDescriptor mojo, Parameter param,
+ StringBuilder messageBuffer )
+ {
+ String expression = param.getExpression();
+
+ if ( param.isEditable() )
+ {
+ boolean isArray = param.getType().endsWith( "[]" );
+ boolean isCollection = false;
+ boolean isMap = false;
+ boolean isProperties = false;
+ if ( !isArray )
+ {
+ try
+ {
+ //assuming Type is available in current ClassLoader
+ isCollection = Collection.class.isAssignableFrom( Class.forName( param.getType() ) );
+ isMap = Map.class.isAssignableFrom( Class.forName( param.getType() ) );
+ isProperties = Properties.class.isAssignableFrom( Class.forName( param.getType() ) );
+ }
+ catch ( ClassNotFoundException e )
+ {
+ // assume it is not assignable from Collection or Map
+ }
+ }
+
+ messageBuffer.append( "Inside the definition for plugin \'" );
+ messageBuffer.append( mojo.getPluginDescriptor().getArtifactId() );
+ messageBuffer.append( "\', specify the following:\n\n<configuration>\n ...\n" );
+ messageBuffer.append( " <" ).append( param.getName() ).append( '>' );
+ if ( isArray || isCollection )
+ {
+ messageBuffer.append( '\n' );
+ messageBuffer.append( " <item>" );
+ }
+ else if ( isProperties )
+ {
+ messageBuffer.append( '\n' );
+ messageBuffer.append( " <property>\n" );
+ messageBuffer.append( " <name>KEY</name>\n" );
+ messageBuffer.append( " <value>" );
+ }
+ else if ( isMap )
+ {
+ messageBuffer.append( '\n' );
+ messageBuffer.append( " <KEY>" );
+ }
+ messageBuffer.append( "VALUE" );
+ if ( isArray || isCollection )
+ {
+ messageBuffer.append( "</item>\n" );
+ messageBuffer.append( " " );
+ }
+ else if ( isProperties )
+ {
+ messageBuffer.append( "</value>\n" );
+ messageBuffer.append( " </property>\n" );
+ messageBuffer.append( " " );
+ }
+ else if ( isMap )
+ {
+ messageBuffer.append( "</KEY>\n" );
+ messageBuffer.append( " " );
+ }
+ messageBuffer.append( "</" ).append( param.getName() ).append( ">\n" );
+ messageBuffer.append( "</configuration>" );
+
+ String alias = param.getAlias();
+ if ( StringUtils.isNotEmpty( alias ) && !alias.equals( param.getName() ) )
+ {
+ messageBuffer.append( "\n\n-OR-\n\n<configuration>\n ...\n <" ).append( alias ).append(
+ ">VALUE</" ).append( alias ).append( ">\n</configuration>\n" );
+ }
+ }
+
+ if ( StringUtils.isEmpty( expression ) )
+ {
+ messageBuffer.append( "." );
+ }
+ else
+ {
+ if ( param.isEditable() )
+ {
+ messageBuffer.append( "\n\n-OR-\n\n" );
+ }
+
+ //addParameterUsageInfo( expression, messageBuffer );
+ }
+ }
+
+ public String buildDiagnosticMessage()
+ {
+ StringBuilder messageBuffer = new StringBuilder( 256 );
+
+ List<Parameter> params = getParameters();
+ MojoDescriptor mojo = getMojoDescriptor();
+
+ messageBuffer.append( "One or more required plugin parameters are invalid/missing for \'" )
+ .append( mojo.getPluginDescriptor().getGoalPrefix() ).append( ":" ).append( mojo.getGoal() )
+ .append( "\'\n" );
+
+ int idx = 0;
+ for ( Iterator<Parameter> it = params.iterator(); it.hasNext(); idx++ )
+ {
+ Parameter param = it.next();
+
+ messageBuffer.append( "\n[" ).append( idx ).append( "] " );
+
+ decomposeParameterIntoUserInstructions( mojo, param, messageBuffer );
+
+ messageBuffer.append( "\n" );
+ }
+
+ return messageBuffer.toString();
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/PluginParameterExpressionEvaluator.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/PluginParameterExpressionEvaluator.java
new file mode 100644
index 00000000..9199ba5a
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/PluginParameterExpressionEvaluator.java
@@ -0,0 +1,482 @@
+package org.apache.maven.plugin;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.util.Properties;
+
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.plugin.descriptor.MojoDescriptor;
+import org.apache.maven.plugin.descriptor.PluginDescriptor;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.project.path.PathTranslator;
+import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluationException;
+import org.codehaus.plexus.component.configurator.expression.TypeAwareExpressionEvaluator;
+import org.codehaus.plexus.logging.Logger;
+import org.codehaus.plexus.util.introspection.ReflectionValueExtractor;
+
+/**
+ * Evaluator for plugin parameters expressions. Content surrounded by <code>${</code> and <code>}</code> is evaluated.
+ * Recognized values are:<table border="1">
+ * <tr><th>expression</th> <th></th> <th>evaluation result</th></tr>
+ * <tr><td><code>session</code></td> <td></td> <td>the actual {@link MavenSession}</td></tr>
+ * <tr><td><code>session.*</code></td> <td>(since Maven 3)</td><td></td></tr>
+ * <tr><td><code>localRepository</code></td> <td></td>
+ * <td>{@link MavenSession#getLocalRepository()}</td></tr>
+ * <tr><td><code>reactorProjects</code></td> <td></td> <td>{@link MavenSession#getProjects()}</td></tr>
+ * <tr><td><code>repositorySystemSession</code></td><td> (since Maven 3)</td>
+ * <td>{@link MavenSession#getRepositorySession()}</td></tr>
+ * <tr><td><code>project</code></td> <td></td>
+ * <td>{@link MavenSession#getCurrentProject()}</td></tr>
+ * <tr><td><code>project.*</code></td> <td></td> <td></td></tr>
+ * <tr><td><code>pom.*</code></td> <td>(since Maven 3)</td><td>same as <code>project.*</code></td></tr>
+ * <tr><td><code>executedProject</code></td> <td></td>
+ * <td>{@link MavenProject#getExecutionProject()}</td></tr>
+ * <tr><td><code>settings</code></td> <td></td> <td>{@link MavenSession#getSettings()}</td></tr>
+ * <tr><td><code>settings.*</code></td> <td></td> <td></td></tr>
+ * <tr><td><code>basedir</code></td> <td></td>
+ * <td>{@link MavenSession#getExecutionRootDirectory()} or
+ * <code>System.getProperty( "user.dir" )</code> if null</td></tr>
+ * <tr><td><code>mojoExecution</code></td> <td></td> <td>the actual {@link MojoExecution}</td></tr>
+ * <tr><td><code>mojo</code></td> <td>(since Maven 3)</td><td>same as <code>mojoExecution</code></td></tr>
+ * <tr><td><code>mojo.*</code></td> <td>(since Maven 3)</td><td></td></tr>
+ * <tr><td><code>plugin</code></td> <td>(since Maven 3)</td>
+ * <td>{@link MojoExecution#getMojoDescriptor()}.{@link MojoDescriptor#getPluginDescriptor()
+ * getPluginDescriptor()}</td></tr>
+ * <tr><td><code>plugin.*</code></td> <td></td> <td></td></tr>
+ * <tr><td><code>*</code></td> <td></td> <td>system properties</td></tr>
+ * <tr><td><code>*</code></td> <td></td> <td>project properties</td></tr>
+ * </table>
+ * <i>Notice:</i> <code>reports</code> was supported in Maven 2.x but was removed in Maven 3
+ *
+ * @author Jason van Zyl
+ * @see MavenSession
+ * @see MojoExecution
+ */
+public class PluginParameterExpressionEvaluator
+ implements TypeAwareExpressionEvaluator
+{
+ private MavenSession session;
+
+ private MojoExecution mojoExecution;
+
+ private MavenProject project;
+
+ private String basedir;
+
+ private Properties properties;
+
+ @Deprecated //TODO: used by the Enforcer plugin
+ public PluginParameterExpressionEvaluator( MavenSession session, MojoExecution mojoExecution,
+ PathTranslator pathTranslator, Logger logger, MavenProject project,
+ Properties properties )
+ {
+ this( session, mojoExecution );
+ }
+
+ public PluginParameterExpressionEvaluator( MavenSession session )
+ {
+ this( session, null );
+ }
+
+ public PluginParameterExpressionEvaluator( MavenSession session, MojoExecution mojoExecution )
+ {
+ this.session = session;
+ this.mojoExecution = mojoExecution;
+ this.properties = new Properties();
+ this.project = session.getCurrentProject();
+
+ //
+ // Maven4: We may want to evaluate how this is used but we add these separate as the
+ // getExecutionProperties is deprecated in MavenSession.
+ //
+ this.properties.putAll( session.getUserProperties() );
+ this.properties.putAll( session.getSystemProperties() );
+
+ String basedir = null;
+
+ if ( project != null )
+ {
+ File projectFile = project.getBasedir();
+
+ // this should always be the case for non-super POM instances...
+ if ( projectFile != null )
+ {
+ basedir = projectFile.getAbsolutePath();
+ }
+ }
+
+ if ( basedir == null )
+ {
+ basedir = session.getExecutionRootDirectory();
+ }
+
+ if ( basedir == null )
+ {
+ basedir = System.getProperty( "user.dir" );
+ }
+
+ this.basedir = basedir;
+ }
+
+ @Override
+ public Object evaluate( String expr )
+ throws ExpressionEvaluationException
+ {
+ return evaluate( expr, null );
+ }
+
+ @Override
+ public Object evaluate( String expr, Class<?> type )
+ throws ExpressionEvaluationException
+ {
+ Object value = null;
+
+ if ( expr == null )
+ {
+ return null;
+ }
+
+ String expression = stripTokens( expr );
+ if ( expression.equals( expr ) )
+ {
+ int index = expr.indexOf( "${" );
+ if ( index >= 0 )
+ {
+ int lastIndex = expr.indexOf( "}", index );
+ if ( lastIndex >= 0 )
+ {
+ String retVal = expr.substring( 0, index );
+
+ if ( ( index > 0 ) && ( expr.charAt( index - 1 ) == '$' ) )
+ {
+ retVal += expr.substring( index + 1, lastIndex + 1 );
+ }
+ else
+ {
+ Object subResult = evaluate( expr.substring( index, lastIndex + 1 ) );
+
+ if ( subResult != null )
+ {
+ retVal += subResult;
+ }
+ else
+ {
+ retVal += "$" + expr.substring( index + 1, lastIndex + 1 );
+ }
+ }
+
+ retVal += evaluate( expr.substring( lastIndex + 1 ) );
+ return retVal;
+ }
+ }
+
+ // Was not an expression
+ if ( expression.contains( "$$" ) )
+ {
+ return expression.replaceAll( "\\$\\$", "\\$" );
+ }
+ else
+ {
+ return expression;
+ }
+ }
+
+ MojoDescriptor mojoDescriptor = mojoExecution.getMojoDescriptor();
+
+ if ( "localRepository".equals( expression ) )
+ {
+ value = session.getLocalRepository();
+ }
+ else if ( "session".equals( expression ) )
+ {
+ value = session;
+ }
+ else if ( expression.startsWith( "session" ) )
+ {
+ try
+ {
+ int pathSeparator = expression.indexOf( "/" );
+
+ if ( pathSeparator > 0 )
+ {
+ String pathExpression = expression.substring( 1, pathSeparator );
+ value = ReflectionValueExtractor.evaluate( pathExpression, session );
+ value = value + expression.substring( pathSeparator );
+ }
+ else
+ {
+ value = ReflectionValueExtractor.evaluate( expression.substring( 1 ), session );
+ }
+ }
+ catch ( Exception e )
+ {
+ // TODO: don't catch exception
+ throw new ExpressionEvaluationException( "Error evaluating plugin parameter expression: " + expression,
+ e );
+ }
+ }
+ else if ( "reactorProjects".equals( expression ) )
+ {
+ value = session.getProjects();
+ }
+ else if ( "mojoExecution".equals( expression ) )
+ {
+ value = mojoExecution;
+ }
+ else if ( "project".equals( expression ) )
+ {
+ value = project;
+ }
+ else if ( "executedProject".equals( expression ) )
+ {
+ value = project.getExecutionProject();
+ }
+ else if ( expression.startsWith( "project" ) || expression.startsWith( "pom" ) )
+ {
+ try
+ {
+ int pathSeparator = expression.indexOf( "/" );
+
+ if ( pathSeparator > 0 )
+ {
+ String pathExpression = expression.substring( 0, pathSeparator );
+ value = ReflectionValueExtractor.evaluate( pathExpression, project );
+ value = value + expression.substring( pathSeparator );
+ }
+ else
+ {
+ value = ReflectionValueExtractor.evaluate( expression.substring( 1 ), project );
+ }
+ }
+ catch ( Exception e )
+ {
+ // TODO: don't catch exception
+ throw new ExpressionEvaluationException( "Error evaluating plugin parameter expression: " + expression,
+ e );
+ }
+ }
+ else if ( expression.equals( "repositorySystemSession" ) )
+ {
+ value = session.getRepositorySession();
+ }
+ else if ( expression.equals( "mojo" ) )
+ {
+ value = mojoExecution;
+ }
+ else if ( expression.startsWith( "mojo" ) )
+ {
+ try
+ {
+ int pathSeparator = expression.indexOf( "/" );
+
+ if ( pathSeparator > 0 )
+ {
+ String pathExpression = expression.substring( 1, pathSeparator );
+ value = ReflectionValueExtractor.evaluate( pathExpression, mojoExecution );
+ value = value + expression.substring( pathSeparator );
+ }
+ else
+ {
+ value = ReflectionValueExtractor.evaluate( expression.substring( 1 ), mojoExecution );
+ }
+ }
+ catch ( Exception e )
+ {
+ // TODO: don't catch exception
+ throw new ExpressionEvaluationException( "Error evaluating plugin parameter expression: " + expression,
+ e );
+ }
+ }
+ else if ( expression.equals( "plugin" ) )
+ {
+ value = mojoDescriptor.getPluginDescriptor();
+ }
+ else if ( expression.startsWith( "plugin" ) )
+ {
+ try
+ {
+ int pathSeparator = expression.indexOf( "/" );
+
+ PluginDescriptor pluginDescriptor = mojoDescriptor.getPluginDescriptor();
+
+ if ( pathSeparator > 0 )
+ {
+ String pathExpression = expression.substring( 1, pathSeparator );
+ value = ReflectionValueExtractor.evaluate( pathExpression, pluginDescriptor );
+ value = value + expression.substring( pathSeparator );
+ }
+ else
+ {
+ value = ReflectionValueExtractor.evaluate( expression.substring( 1 ), pluginDescriptor );
+ }
+ }
+ catch ( Exception e )
+ {
+ throw new ExpressionEvaluationException( "Error evaluating plugin parameter expression: " + expression,
+ e );
+ }
+ }
+ else if ( "settings".equals( expression ) )
+ {
+ value = session.getSettings();
+ }
+ else if ( expression.startsWith( "settings" ) )
+ {
+ try
+ {
+ int pathSeparator = expression.indexOf( "/" );
+
+ if ( pathSeparator > 0 )
+ {
+ String pathExpression = expression.substring( 1, pathSeparator );
+ value = ReflectionValueExtractor.evaluate( pathExpression, session.getSettings() );
+ value = value + expression.substring( pathSeparator );
+ }
+ else
+ {
+ value = ReflectionValueExtractor.evaluate( expression.substring( 1 ), session.getSettings() );
+ }
+ }
+ catch ( Exception e )
+ {
+ // TODO: don't catch exception
+ throw new ExpressionEvaluationException( "Error evaluating plugin parameter expression: " + expression,
+ e );
+ }
+ }
+ else if ( "basedir".equals( expression ) )
+ {
+ value = basedir;
+ }
+ else if ( expression.startsWith( "basedir" ) )
+ {
+ int pathSeparator = expression.indexOf( "/" );
+
+ if ( pathSeparator > 0 )
+ {
+ value = basedir + expression.substring( pathSeparator );
+ }
+ }
+
+ /*
+ * MNG-4312: We neither have reserved all of the above magic expressions nor is their set fixed/well-known (it
+ * gets occasionally extended by newer Maven versions). This imposes the risk for existing plugins to
+ * unintentionally use such a magic expression for an ordinary system property. So here we check whether we
+ * ended up with a magic value that is not compatible with the type of the configured mojo parameter (a string
+ * could still be converted by the configurator so we leave those alone). If so, back off to evaluating the
+ * expression from properties only.
+ */
+ if ( value != null && type != null && !( value instanceof String ) && !isTypeCompatible( type, value ) )
+ {
+ value = null;
+ }
+
+ if ( value == null )
+ {
+ // The CLI should win for defining properties
+
+ if ( properties != null )
+ {
+ // We will attempt to get nab a system property as a way to specify a
+ // parameter to a plugins. My particular case here is allowing the surefire
+ // plugin to run a single test so I want to specify that class on the cli
+ // as a parameter.
+
+ value = properties.getProperty( expression );
+ }
+
+ if ( ( value == null ) && ( ( project != null ) && ( project.getProperties() != null ) ) )
+ {
+ value = project.getProperties().getProperty( expression );
+ }
+
+ }
+
+ if ( value instanceof String )
+ {
+ // TODO: without #, this could just be an evaluate call...
+
+ String val = (String) value;
+
+ int exprStartDelimiter = val.indexOf( "${" );
+
+ if ( exprStartDelimiter >= 0 )
+ {
+ if ( exprStartDelimiter > 0 )
+ {
+ value = val.substring( 0, exprStartDelimiter ) + evaluate( val.substring( exprStartDelimiter ) );
+ }
+ else
+ {
+ value = evaluate( val.substring( exprStartDelimiter ) );
+ }
+ }
+ }
+
+ return value;
+ }
+
+ private static boolean isTypeCompatible( Class<?> type, Object value )
+ {
+ if ( type.isInstance( value ) )
+ {
+ return true;
+ }
+ // likely Boolean -> boolean, Short -> int etc. conversions, it's not the problem case we try to avoid
+ return ( ( type.isPrimitive() || type.getName().startsWith( "java.lang." ) )
+ && value.getClass().getName().startsWith( "java.lang." ) );
+ }
+
+ private String stripTokens( String expr )
+ {
+ if ( expr.startsWith( "${" ) && ( expr.indexOf( "}" ) == expr.length() - 1 ) )
+ {
+ expr = expr.substring( 2, expr.length() - 1 );
+ }
+ return expr;
+ }
+
+ @Override
+ public File alignToBaseDirectory( File file )
+ {
+ // TODO: Copied from the DefaultInterpolator. We likely want to resurrect the PathTranslator or at least a
+ // similar component for re-usage
+ if ( file != null )
+ {
+ if ( file.isAbsolute() )
+ {
+ // path was already absolute, just normalize file separator and we're done
+ }
+ else if ( file.getPath().startsWith( File.separator ) )
+ {
+ // drive-relative Windows path, don't align with project directory but with drive root
+ file = file.getAbsoluteFile();
+ }
+ else
+ {
+ // an ordinary relative path, align with project directory
+ file = new File( new File( basedir, file.getPath() ).toURI().normalize() ).getAbsoluteFile();
+ }
+ }
+ return file;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/PluginRealmCache.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/PluginRealmCache.java
new file mode 100644
index 00000000..1ffa1575
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/PluginRealmCache.java
@@ -0,0 +1,85 @@
+package org.apache.maven.plugin;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.List;
+import java.util.Map;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.model.Plugin;
+import org.apache.maven.project.MavenProject;
+import org.codehaus.plexus.classworlds.realm.ClassRealm;
+import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.graph.DependencyFilter;
+import org.eclipse.aether.repository.RemoteRepository;
+
+/**
+ * Caches plugin class realms. <strong>Warning:</strong> This is an internal utility interface that is only public for
+ * technical reasons, it is not part of the public API. In particular, this interface can be changed or deleted without
+ * prior notice.
+ *
+ * @author Igor Fedorenko
+ * @author Benjamin Bentmann
+ */
+public interface PluginRealmCache
+{
+
+ static class CacheRecord
+ {
+ public final ClassRealm realm;
+
+ public final List<Artifact> artifacts;
+
+ public CacheRecord( ClassRealm realm, List<Artifact> artifacts )
+ {
+ this.realm = realm;
+ this.artifacts = artifacts;
+ }
+ }
+
+ /**
+ * A cache key.
+ */
+ interface Key
+ {
+ // marker interface for cache keys
+ }
+
+ Key createKey( Plugin plugin, ClassLoader parentRealm, Map<String, ClassLoader> foreignImports,
+ DependencyFilter dependencyFilter, List<RemoteRepository> repositories,
+ RepositorySystemSession session );
+
+ CacheRecord get( Key key );
+
+ CacheRecord put( Key key, ClassRealm pluginRealm, List<Artifact> pluginArtifacts );
+
+ void flush();
+
+ /**
+ * Registers the specified cache record for usage with the given project. Integrators can use the information
+ * collected from this method in combination with a custom cache implementation to dispose unused records from the
+ * cache.
+ *
+ * @param project The project that employs the plugin realm, must not be {@code null}.
+ * @param record The cache record being used for the project, must not be {@code null}.
+ */
+ void register( MavenProject project, Key key, CacheRecord record );
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/PluginResolutionException.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/PluginResolutionException.java
new file mode 100644
index 00000000..ab280643
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/PluginResolutionException.java
@@ -0,0 +1,47 @@
+package org.apache.maven.plugin;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.model.Plugin;
+
+/**
+ * Exception occurring trying to resolve a plugin.
+ *
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ */
+public class PluginResolutionException
+ extends Exception
+{
+
+ private final Plugin plugin;
+
+ public PluginResolutionException( Plugin plugin, Throwable cause )
+ {
+ super( "Plugin " + plugin.getId() + " or one of its dependencies could not be resolved: " + cause.getMessage(),
+ cause );
+ this.plugin = plugin;
+ }
+
+ public Plugin getPlugin()
+ {
+ return plugin;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultLegacySupport.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultLegacySupport.java
new file mode 100644
index 00000000..f397c1e8
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultLegacySupport.java
@@ -0,0 +1,74 @@
+package org.apache.maven.plugin.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.concurrent.atomic.AtomicReference;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.plugin.LegacySupport;
+import org.codehaus.plexus.component.annotations.Component;
+import org.eclipse.aether.RepositorySystemSession;
+
+/**
+ * Helps to provide backward-compatibility with plugins that use legacy components. <strong>Warning:</strong> This is an
+ * internal utility component that is only public for technical reasons, it is not part of the public API. In
+ * particular, this component can be changed or deleted without prior notice.
+ *
+ * @since 3.0
+ * @author Benjamin Bentmann
+ */
+@Component( role = LegacySupport.class )
+public class DefaultLegacySupport
+ implements LegacySupport
+{
+
+ private static final ThreadLocal<AtomicReference<MavenSession>> SESSION =
+ new InheritableThreadLocal<AtomicReference<MavenSession>>();
+
+ public void setSession( MavenSession session )
+ {
+ AtomicReference<MavenSession> reference = DefaultLegacySupport.SESSION.get();
+ if ( reference != null )
+ {
+ reference.set( null );
+ }
+
+ if ( session == null && reference != null )
+ {
+ DefaultLegacySupport.SESSION.remove();
+ }
+ else
+ {
+ DefaultLegacySupport.SESSION.set( new AtomicReference<MavenSession>( session ) );
+ }
+ }
+
+ public MavenSession getSession()
+ {
+ AtomicReference<MavenSession> currentSession = DefaultLegacySupport.SESSION.get();
+ return currentSession != null ? currentSession.get() : null;
+ }
+
+ public RepositorySystemSession getRepositorySession()
+ {
+ MavenSession session = getSession();
+ return ( session != null ) ? session.getRepositorySession() : null;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultMavenPluginManager.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultMavenPluginManager.java
new file mode 100644
index 00000000..d32e04c1
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultMavenPluginManager.java
@@ -0,0 +1,946 @@
+package org.apache.maven.plugin.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.BufferedInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintStream;
+import java.io.Reader;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.jar.JarFile;
+import java.util.zip.ZipEntry;
+
+import org.apache.maven.RepositoryUtils;
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.classrealm.ClassRealmManager;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.execution.scope.internal.MojoExecutionScopeModule;
+import org.apache.maven.model.Plugin;
+import org.apache.maven.monitor.logging.DefaultLog;
+import org.apache.maven.plugin.ContextEnabled;
+import org.apache.maven.plugin.DebugConfigurationListener;
+import org.apache.maven.plugin.ExtensionRealmCache;
+import org.apache.maven.plugin.InvalidPluginDescriptorException;
+import org.apache.maven.plugin.MavenPluginManager;
+import org.apache.maven.plugin.MavenPluginValidator;
+import org.apache.maven.plugin.Mojo;
+import org.apache.maven.plugin.MojoExecution;
+import org.apache.maven.plugin.MojoNotFoundException;
+import org.apache.maven.plugin.PluginArtifactsCache;
+import org.apache.maven.plugin.PluginConfigurationException;
+import org.apache.maven.plugin.PluginContainerException;
+import org.apache.maven.plugin.PluginDescriptorCache;
+import org.apache.maven.plugin.PluginDescriptorParsingException;
+import org.apache.maven.plugin.PluginIncompatibleException;
+import org.apache.maven.plugin.PluginManagerException;
+import org.apache.maven.plugin.PluginParameterException;
+import org.apache.maven.plugin.PluginParameterExpressionEvaluator;
+import org.apache.maven.plugin.PluginRealmCache;
+import org.apache.maven.plugin.PluginResolutionException;
+import org.apache.maven.plugin.descriptor.MojoDescriptor;
+import org.apache.maven.plugin.descriptor.Parameter;
+import org.apache.maven.plugin.descriptor.PluginDescriptor;
+import org.apache.maven.plugin.descriptor.PluginDescriptorBuilder;
+import org.apache.maven.plugin.version.DefaultPluginVersionRequest;
+import org.apache.maven.plugin.version.PluginVersionRequest;
+import org.apache.maven.plugin.version.PluginVersionResolutionException;
+import org.apache.maven.plugin.version.PluginVersionResolver;
+import org.apache.maven.project.ExtensionDescriptor;
+import org.apache.maven.project.ExtensionDescriptorBuilder;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.rtinfo.RuntimeInformation;
+import org.apache.maven.session.scope.internal.SessionScopeModule;
+import org.codehaus.plexus.DefaultPlexusContainer;
+import org.codehaus.plexus.PlexusContainer;
+import org.codehaus.plexus.classworlds.realm.ClassRealm;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+import org.codehaus.plexus.component.composition.CycleDetectedInComponentGraphException;
+import org.codehaus.plexus.component.configurator.ComponentConfigurationException;
+import org.codehaus.plexus.component.configurator.ComponentConfigurator;
+import org.codehaus.plexus.component.configurator.ConfigurationListener;
+import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluationException;
+import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluator;
+import org.codehaus.plexus.component.repository.ComponentDescriptor;
+import org.codehaus.plexus.component.repository.exception.ComponentLifecycleException;
+import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
+import org.codehaus.plexus.configuration.PlexusConfiguration;
+import org.codehaus.plexus.configuration.PlexusConfigurationException;
+import org.codehaus.plexus.configuration.xml.XmlPlexusConfiguration;
+import org.codehaus.plexus.logging.Logger;
+import org.codehaus.plexus.logging.LoggerManager;
+import org.codehaus.plexus.util.IOUtil;
+import org.codehaus.plexus.util.ReaderFactory;
+import org.codehaus.plexus.util.StringUtils;
+import org.codehaus.plexus.util.xml.Xpp3Dom;
+import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.graph.DependencyFilter;
+import org.eclipse.aether.graph.DependencyNode;
+import org.eclipse.aether.repository.RemoteRepository;
+import org.eclipse.aether.util.filter.AndDependencyFilter;
+import org.eclipse.aether.util.graph.visitor.PreorderNodeListGenerator;
+
+/**
+ * Provides basic services to manage Maven plugins and their mojos. This component is kept general in its design such
+ * that the plugins/mojos can be used in arbitrary contexts. In particular, the mojos can be used for ordinary build
+ * plugins as well as special purpose plugins like reports.
+ *
+ * @since 3.0
+ * @author Benjamin Bentmann
+ */
+@Component( role = MavenPluginManager.class )
+public class DefaultMavenPluginManager
+ implements MavenPluginManager
+{
+
+ /**
+ * PluginId=>ExtensionRealmCache.CacheRecord map MavenProject context value key. The map is used to ensure the same
+ * class realm is used to load build extensions and load mojos for extensions=true plugins.
+ *
+ * @noreference this is part of internal implementation and may be changed or removed without notice
+ * @since 3.3.0
+ */
+ public static final String KEY_EXTENSIONS_REALMS = DefaultMavenPluginManager.class.getName() + "/extensionsRealms";
+
+ @Requirement
+ private Logger logger;
+
+ @Requirement
+ private LoggerManager loggerManager;
+
+ @Requirement
+ private PlexusContainer container;
+
+ @Requirement
+ private ClassRealmManager classRealmManager;
+
+ @Requirement
+ private PluginDescriptorCache pluginDescriptorCache;
+
+ @Requirement
+ private PluginRealmCache pluginRealmCache;
+
+ @Requirement
+ private PluginDependenciesResolver pluginDependenciesResolver;
+
+ @Requirement
+ private RuntimeInformation runtimeInformation;
+
+ @Requirement
+ private ExtensionRealmCache extensionRealmCache;
+
+ @Requirement
+ private PluginVersionResolver pluginVersionResolver;
+
+ @Requirement
+ private PluginArtifactsCache pluginArtifactsCache;
+
+ private ExtensionDescriptorBuilder extensionDescriptorBuilder = new ExtensionDescriptorBuilder();
+
+ private PluginDescriptorBuilder builder = new PluginDescriptorBuilder();
+
+ public synchronized PluginDescriptor getPluginDescriptor( Plugin plugin, List<RemoteRepository> repositories,
+ RepositorySystemSession session )
+ throws PluginResolutionException, PluginDescriptorParsingException, InvalidPluginDescriptorException
+ {
+ PluginDescriptorCache.Key cacheKey = pluginDescriptorCache.createKey( plugin, repositories, session );
+
+ PluginDescriptor pluginDescriptor = pluginDescriptorCache.get( cacheKey );
+
+ if ( pluginDescriptor == null )
+ {
+ org.eclipse.aether.artifact.Artifact artifact =
+ pluginDependenciesResolver.resolve( plugin, repositories, session );
+
+ Artifact pluginArtifact = RepositoryUtils.toArtifact( artifact );
+
+ pluginDescriptor = extractPluginDescriptor( pluginArtifact, plugin );
+
+ pluginDescriptor.setRequiredMavenVersion( artifact.getProperty( "requiredMavenVersion", null ) );
+
+ pluginDescriptorCache.put( cacheKey, pluginDescriptor );
+ }
+
+ pluginDescriptor.setPlugin( plugin );
+
+ return pluginDescriptor;
+ }
+
+ private PluginDescriptor extractPluginDescriptor( Artifact pluginArtifact, Plugin plugin )
+ throws PluginDescriptorParsingException, InvalidPluginDescriptorException
+ {
+ PluginDescriptor pluginDescriptor = null;
+
+ File pluginFile = pluginArtifact.getFile();
+
+ try
+ {
+ if ( pluginFile.isFile() )
+ {
+ JarFile pluginJar = new JarFile( pluginFile, false );
+ try
+ {
+ ZipEntry pluginDescriptorEntry = pluginJar.getEntry( getPluginDescriptorLocation() );
+
+ if ( pluginDescriptorEntry != null )
+ {
+ InputStream is = pluginJar.getInputStream( pluginDescriptorEntry );
+
+ pluginDescriptor = parsePluginDescriptor( is, plugin, pluginFile.getAbsolutePath() );
+ }
+ }
+ finally
+ {
+ pluginJar.close();
+ }
+ }
+ else
+ {
+ File pluginXml = new File( pluginFile, getPluginDescriptorLocation() );
+
+ if ( pluginXml.isFile() )
+ {
+ InputStream is = new BufferedInputStream( new FileInputStream( pluginXml ) );
+ try
+ {
+ pluginDescriptor = parsePluginDescriptor( is, plugin, pluginXml.getAbsolutePath() );
+ }
+ finally
+ {
+ IOUtil.close( is );
+ }
+ }
+ }
+
+ if ( pluginDescriptor == null )
+ {
+ throw new IOException( "No plugin descriptor found at " + getPluginDescriptorLocation() );
+ }
+ }
+ catch ( IOException e )
+ {
+ throw new PluginDescriptorParsingException( plugin, pluginFile.getAbsolutePath(), e );
+ }
+
+ MavenPluginValidator validator = new MavenPluginValidator( pluginArtifact );
+
+ validator.validate( pluginDescriptor );
+
+ if ( validator.hasErrors() )
+ {
+ throw new InvalidPluginDescriptorException( "Invalid plugin descriptor for " + plugin.getId() + " ("
+ + pluginFile + ")", validator.getErrors() );
+ }
+
+ pluginDescriptor.setPluginArtifact( pluginArtifact );
+
+ return pluginDescriptor;
+ }
+
+ private String getPluginDescriptorLocation()
+ {
+ return "META-INF/maven/plugin.xml";
+ }
+
+ private PluginDescriptor parsePluginDescriptor( InputStream is, Plugin plugin, String descriptorLocation )
+ throws PluginDescriptorParsingException
+ {
+ try
+ {
+ Reader reader = ReaderFactory.newXmlReader( is );
+
+ PluginDescriptor pluginDescriptor = builder.build( reader, descriptorLocation );
+
+ return pluginDescriptor;
+ }
+ catch ( IOException e )
+ {
+ throw new PluginDescriptorParsingException( plugin, descriptorLocation, e );
+ }
+ catch ( PlexusConfigurationException e )
+ {
+ throw new PluginDescriptorParsingException( plugin, descriptorLocation, e );
+ }
+ }
+
+ public MojoDescriptor getMojoDescriptor( Plugin plugin, String goal, List<RemoteRepository> repositories,
+ RepositorySystemSession session )
+ throws MojoNotFoundException, PluginResolutionException, PluginDescriptorParsingException,
+ InvalidPluginDescriptorException
+ {
+ PluginDescriptor pluginDescriptor = getPluginDescriptor( plugin, repositories, session );
+
+ MojoDescriptor mojoDescriptor = pluginDescriptor.getMojo( goal );
+
+ if ( mojoDescriptor == null )
+ {
+ throw new MojoNotFoundException( goal, pluginDescriptor );
+ }
+
+ return mojoDescriptor;
+ }
+
+ public void checkRequiredMavenVersion( PluginDescriptor pluginDescriptor )
+ throws PluginIncompatibleException
+ {
+ String requiredMavenVersion = pluginDescriptor.getRequiredMavenVersion();
+ if ( StringUtils.isNotBlank( requiredMavenVersion ) )
+ {
+ try
+ {
+ if ( !runtimeInformation.isMavenVersion( requiredMavenVersion ) )
+ {
+ throw new PluginIncompatibleException( pluginDescriptor.getPlugin(), "The plugin "
+ + pluginDescriptor.getId() + " requires Maven version " + requiredMavenVersion );
+ }
+ }
+ catch ( RuntimeException e )
+ {
+ logger.warn( "Could not verify plugin's Maven prerequisite: " + e.getMessage() );
+ }
+ }
+ }
+
+ public synchronized void setupPluginRealm( PluginDescriptor pluginDescriptor, MavenSession session,
+ ClassLoader parent, List<String> imports, DependencyFilter filter )
+ throws PluginResolutionException, PluginContainerException
+ {
+ Plugin plugin = pluginDescriptor.getPlugin();
+ MavenProject project = session.getCurrentProject();
+
+ if ( plugin.isExtensions() )
+ {
+ ExtensionRealmCache.CacheRecord extensionRecord;
+ try
+ {
+ RepositorySystemSession repositorySession = session.getRepositorySession();
+ extensionRecord = setupExtensionsRealm( project, plugin, repositorySession );
+ }
+ catch ( PluginManagerException e )
+ {
+ // extensions realm is expected to be fully setup at this point
+ // any exception means a problem in maven code, not a user error
+ throw new IllegalStateException( e );
+ }
+
+ ClassRealm pluginRealm = extensionRecord.realm;
+ List<Artifact> pluginArtifacts = extensionRecord.artifacts;
+
+ for ( ComponentDescriptor<?> componentDescriptor : pluginDescriptor.getComponents() )
+ {
+ componentDescriptor.setRealm( pluginRealm );
+ }
+
+ pluginDescriptor.setClassRealm( pluginRealm );
+ pluginDescriptor.setArtifacts( pluginArtifacts );
+ }
+ else
+ {
+ Map<String, ClassLoader> foreignImports = calcImports( project, parent, imports );
+
+ PluginRealmCache.Key cacheKey =
+ pluginRealmCache.createKey( plugin, parent, foreignImports, filter,
+ project.getRemotePluginRepositories(), session.getRepositorySession() );
+
+ PluginRealmCache.CacheRecord cacheRecord = pluginRealmCache.get( cacheKey );
+
+ if ( cacheRecord != null )
+ {
+ pluginDescriptor.setClassRealm( cacheRecord.realm );
+ pluginDescriptor.setArtifacts( new ArrayList<Artifact>( cacheRecord.artifacts ) );
+ for ( ComponentDescriptor<?> componentDescriptor : pluginDescriptor.getComponents() )
+ {
+ componentDescriptor.setRealm( cacheRecord.realm );
+ }
+ }
+ else
+ {
+ createPluginRealm( pluginDescriptor, session, parent, foreignImports, filter );
+
+ cacheRecord =
+ pluginRealmCache.put( cacheKey, pluginDescriptor.getClassRealm(), pluginDescriptor.getArtifacts() );
+ }
+
+ pluginRealmCache.register( project, cacheKey, cacheRecord );
+ }
+ }
+
+ private void createPluginRealm( PluginDescriptor pluginDescriptor, MavenSession session, ClassLoader parent,
+ Map<String, ClassLoader> foreignImports, DependencyFilter filter )
+ throws PluginResolutionException, PluginContainerException
+ {
+ Plugin plugin = pluginDescriptor.getPlugin();
+
+ if ( plugin == null )
+ {
+ throw new IllegalArgumentException( "incomplete plugin descriptor, plugin missing" );
+ }
+
+ Artifact pluginArtifact = pluginDescriptor.getPluginArtifact();
+
+ if ( pluginArtifact == null )
+ {
+ throw new IllegalArgumentException( "incomplete plugin descriptor, plugin artifact missing" );
+ }
+
+ MavenProject project = session.getCurrentProject();
+
+ final ClassRealm pluginRealm;
+ final List<Artifact> pluginArtifacts;
+
+ RepositorySystemSession repositorySession = session.getRepositorySession();
+ DependencyFilter dependencyFilter = project.getExtensionDependencyFilter();
+ dependencyFilter = AndDependencyFilter.newInstance( dependencyFilter, filter );
+
+ DependencyNode root =
+ pluginDependenciesResolver.resolve( plugin, RepositoryUtils.toArtifact( pluginArtifact ),
+ dependencyFilter, project.getRemotePluginRepositories(),
+ repositorySession );
+
+ PreorderNodeListGenerator nlg = new PreorderNodeListGenerator();
+ root.accept( nlg );
+
+ pluginArtifacts = toMavenArtifacts( root, nlg );
+
+ pluginRealm =
+ classRealmManager.createPluginRealm( plugin, parent, null, foreignImports,
+ toAetherArtifacts( pluginArtifacts ) );
+
+ discoverPluginComponents( pluginRealm, plugin, pluginDescriptor );
+
+ pluginDescriptor.setClassRealm( pluginRealm );
+ pluginDescriptor.setArtifacts( pluginArtifacts );
+ }
+
+ private void discoverPluginComponents( final ClassRealm pluginRealm, Plugin plugin,
+ PluginDescriptor pluginDescriptor )
+ throws PluginContainerException
+ {
+ try
+ {
+ if ( pluginDescriptor != null )
+ {
+ for ( ComponentDescriptor<?> componentDescriptor : pluginDescriptor.getComponents() )
+ {
+ componentDescriptor.setRealm( pluginRealm );
+ container.addComponentDescriptor( componentDescriptor );
+ }
+ }
+
+ ( (DefaultPlexusContainer) container ).discoverComponents( pluginRealm,
+ new SessionScopeModule( container ),
+ new MojoExecutionScopeModule( container ) );
+ }
+ catch ( ComponentLookupException e )
+ {
+ throw new PluginContainerException( plugin, pluginRealm, "Error in component graph of plugin "
+ + plugin.getId() + ": " + e.getMessage(), e );
+ }
+ catch ( CycleDetectedInComponentGraphException e )
+ {
+ throw new PluginContainerException( plugin, pluginRealm, "Error in component graph of plugin "
+ + plugin.getId() + ": " + e.getMessage(), e );
+ }
+ }
+
+ private List<org.eclipse.aether.artifact.Artifact> toAetherArtifacts( final List<Artifact> pluginArtifacts )
+ {
+ return new ArrayList<org.eclipse.aether.artifact.Artifact>( RepositoryUtils.toArtifacts( pluginArtifacts ) );
+ }
+
+ private List<Artifact> toMavenArtifacts( DependencyNode root, PreorderNodeListGenerator nlg )
+ {
+ List<Artifact> artifacts = new ArrayList<Artifact>( nlg.getNodes().size() );
+ RepositoryUtils.toArtifacts( artifacts, Collections.singleton( root ), Collections.<String>emptyList(), null );
+ for ( Iterator<Artifact> it = artifacts.iterator(); it.hasNext(); )
+ {
+ Artifact artifact = it.next();
+ if ( artifact.getFile() == null )
+ {
+ it.remove();
+ }
+ }
+ return artifacts;
+ }
+
+ private Map<String, ClassLoader> calcImports( MavenProject project, ClassLoader parent, List<String> imports )
+ {
+ Map<String, ClassLoader> foreignImports = new HashMap<String, ClassLoader>();
+
+ ClassLoader projectRealm = project.getClassRealm();
+ if ( projectRealm != null )
+ {
+ foreignImports.put( "", projectRealm );
+ }
+ else
+ {
+ foreignImports.put( "", classRealmManager.getMavenApiRealm() );
+ }
+
+ if ( parent != null && imports != null )
+ {
+ for ( String parentImport : imports )
+ {
+ foreignImports.put( parentImport, parent );
+ }
+ }
+
+ return foreignImports;
+ }
+
+ public <T> T getConfiguredMojo( Class<T> mojoInterface, MavenSession session, MojoExecution mojoExecution )
+ throws PluginConfigurationException, PluginContainerException
+ {
+ MojoDescriptor mojoDescriptor = mojoExecution.getMojoDescriptor();
+
+ PluginDescriptor pluginDescriptor = mojoDescriptor.getPluginDescriptor();
+
+ ClassRealm pluginRealm = pluginDescriptor.getClassRealm();
+
+ if ( logger.isDebugEnabled() )
+ {
+ logger.debug( "Configuring mojo " + mojoDescriptor.getId() + " from plugin realm " + pluginRealm );
+ }
+
+ // We are forcing the use of the plugin realm for all lookups that might occur during
+ // the lifecycle that is part of the lookup. Here we are specifically trying to keep
+ // lookups that occur in contextualize calls in line with the right realm.
+ ClassRealm oldLookupRealm = container.setLookupRealm( pluginRealm );
+
+ ClassLoader oldClassLoader = Thread.currentThread().getContextClassLoader();
+ Thread.currentThread().setContextClassLoader( pluginRealm );
+
+ try
+ {
+ T mojo;
+
+ try
+ {
+ mojo = container.lookup( mojoInterface, mojoDescriptor.getRoleHint() );
+ }
+ catch ( ComponentLookupException e )
+ {
+ Throwable cause = e.getCause();
+ while ( cause != null && !( cause instanceof LinkageError )
+ && !( cause instanceof ClassNotFoundException ) )
+ {
+ cause = cause.getCause();
+ }
+
+ if ( ( cause instanceof NoClassDefFoundError ) || ( cause instanceof ClassNotFoundException ) )
+ {
+ ByteArrayOutputStream os = new ByteArrayOutputStream( 1024 );
+ PrintStream ps = new PrintStream( os );
+ ps.println( "Unable to load the mojo '" + mojoDescriptor.getGoal() + "' in the plugin '"
+ + pluginDescriptor.getId() + "'. A required class is missing: " + cause.getMessage() );
+ pluginRealm.display( ps );
+
+ throw new PluginContainerException( mojoDescriptor, pluginRealm, os.toString(), cause );
+ }
+ else if ( cause instanceof LinkageError )
+ {
+ ByteArrayOutputStream os = new ByteArrayOutputStream( 1024 );
+ PrintStream ps = new PrintStream( os );
+ ps.println( "Unable to load the mojo '" + mojoDescriptor.getGoal() + "' in the plugin '"
+ + pluginDescriptor.getId() + "' due to an API incompatibility: " + e.getClass().getName()
+ + ": " + cause.getMessage() );
+ pluginRealm.display( ps );
+
+ throw new PluginContainerException( mojoDescriptor, pluginRealm, os.toString(), cause );
+ }
+
+ throw new PluginContainerException( mojoDescriptor, pluginRealm, "Unable to load the mojo '"
+ + mojoDescriptor.getGoal() + "' (or one of its required components) from the plugin '"
+ + pluginDescriptor.getId() + "'", e );
+ }
+
+ if ( mojo instanceof ContextEnabled )
+ {
+ MavenProject project = session.getCurrentProject();
+
+ Map<String, Object> pluginContext = session.getPluginContext( pluginDescriptor, project );
+
+ if ( pluginContext != null )
+ {
+ pluginContext.put( "project", project );
+
+ pluginContext.put( "pluginDescriptor", pluginDescriptor );
+
+ ( (ContextEnabled) mojo ).setPluginContext( pluginContext );
+ }
+ }
+
+ if ( mojo instanceof Mojo )
+ {
+ Logger mojoLogger = loggerManager.getLoggerForComponent( mojoDescriptor.getImplementation() );
+ ( (Mojo) mojo ).setLog( new DefaultLog( mojoLogger ) );
+ }
+
+ Xpp3Dom dom = mojoExecution.getConfiguration();
+
+ PlexusConfiguration pomConfiguration;
+
+ if ( dom == null )
+ {
+ pomConfiguration = new XmlPlexusConfiguration( "configuration" );
+ }
+ else
+ {
+ pomConfiguration = new XmlPlexusConfiguration( dom );
+ }
+
+ ExpressionEvaluator expressionEvaluator = new PluginParameterExpressionEvaluator( session, mojoExecution );
+
+ populatePluginFields( mojo, mojoDescriptor, pluginRealm, pomConfiguration, expressionEvaluator );
+
+ return mojo;
+ }
+ finally
+ {
+ Thread.currentThread().setContextClassLoader( oldClassLoader );
+ container.setLookupRealm( oldLookupRealm );
+ }
+ }
+
+ private void populatePluginFields( Object mojo, MojoDescriptor mojoDescriptor, ClassRealm pluginRealm,
+ PlexusConfiguration configuration, ExpressionEvaluator expressionEvaluator )
+ throws PluginConfigurationException
+ {
+ ComponentConfigurator configurator = null;
+
+ String configuratorId = mojoDescriptor.getComponentConfigurator();
+
+ if ( StringUtils.isEmpty( configuratorId ) )
+ {
+ configuratorId = "basic";
+ }
+
+ try
+ {
+ // TODO: could the configuration be passed to lookup and the configurator known to plexus via the descriptor
+ // so that this method could entirely be handled by a plexus lookup?
+ configurator = container.lookup( ComponentConfigurator.class, configuratorId );
+
+ ConfigurationListener listener = new DebugConfigurationListener( logger );
+
+ ValidatingConfigurationListener validator =
+ new ValidatingConfigurationListener( mojo, mojoDescriptor, listener );
+
+ logger.debug( "Configuring mojo '" + mojoDescriptor.getId() + "' with " + configuratorId
+ + " configurator -->" );
+
+ configurator.configureComponent( mojo, configuration, expressionEvaluator, pluginRealm, validator );
+
+ logger.debug( "-- end configuration --" );
+
+ Collection<Parameter> missingParameters = validator.getMissingParameters();
+ if ( !missingParameters.isEmpty() )
+ {
+ if ( "basic".equals( configuratorId ) )
+ {
+ throw new PluginParameterException( mojoDescriptor, new ArrayList<Parameter>( missingParameters ) );
+ }
+ else
+ {
+ /*
+ * NOTE: Other configurators like the map-oriented one don't call into the listener, so do it the
+ * hard way.
+ */
+ validateParameters( mojoDescriptor, configuration, expressionEvaluator );
+ }
+ }
+ }
+ catch ( ComponentConfigurationException e )
+ {
+ String message = "Unable to parse configuration of mojo " + mojoDescriptor.getId();
+ if ( e.getFailedConfiguration() != null )
+ {
+ message += " for parameter " + e.getFailedConfiguration().getName();
+ }
+ message += ": " + e.getMessage();
+
+ throw new PluginConfigurationException( mojoDescriptor.getPluginDescriptor(), message, e );
+ }
+ catch ( ComponentLookupException e )
+ {
+ throw new PluginConfigurationException( mojoDescriptor.getPluginDescriptor(),
+ "Unable to retrieve component configurator " + configuratorId
+ + " for configuration of mojo " + mojoDescriptor.getId(), e );
+ }
+ catch ( NoClassDefFoundError e )
+ {
+ ByteArrayOutputStream os = new ByteArrayOutputStream( 1024 );
+ PrintStream ps = new PrintStream( os );
+ ps.println( "A required class was missing during configuration of mojo " + mojoDescriptor.getId() + ": "
+ + e.getMessage() );
+ pluginRealm.display( ps );
+
+ throw new PluginConfigurationException( mojoDescriptor.getPluginDescriptor(), os.toString(), e );
+ }
+ catch ( LinkageError e )
+ {
+ ByteArrayOutputStream os = new ByteArrayOutputStream( 1024 );
+ PrintStream ps = new PrintStream( os );
+ ps.println( "An API incompatibility was encountered during configuration of mojo " + mojoDescriptor.getId()
+ + ": " + e.getClass().getName() + ": " + e.getMessage() );
+ pluginRealm.display( ps );
+
+ throw new PluginConfigurationException( mojoDescriptor.getPluginDescriptor(), os.toString(), e );
+ }
+ finally
+ {
+ if ( configurator != null )
+ {
+ try
+ {
+ container.release( configurator );
+ }
+ catch ( ComponentLifecycleException e )
+ {
+ logger.debug( "Failed to release mojo configurator - ignoring." );
+ }
+ }
+ }
+ }
+
+ private void validateParameters( MojoDescriptor mojoDescriptor, PlexusConfiguration configuration,
+ ExpressionEvaluator expressionEvaluator )
+ throws ComponentConfigurationException, PluginParameterException
+ {
+ if ( mojoDescriptor.getParameters() == null )
+ {
+ return;
+ }
+
+ List<Parameter> invalidParameters = new ArrayList<Parameter>();
+
+ for ( Parameter parameter : mojoDescriptor.getParameters() )
+ {
+ if ( !parameter.isRequired() )
+ {
+ continue;
+ }
+
+ Object value = null;
+
+ PlexusConfiguration config = configuration.getChild( parameter.getName(), false );
+ if ( config != null )
+ {
+ String expression = config.getValue( null );
+
+ try
+ {
+ value = expressionEvaluator.evaluate( expression );
+
+ if ( value == null )
+ {
+ value = config.getAttribute( "default-value", null );
+ }
+ }
+ catch ( ExpressionEvaluationException e )
+ {
+ String msg =
+ "Error evaluating the expression '" + expression + "' for configuration value '"
+ + configuration.getName() + "'";
+ throw new ComponentConfigurationException( configuration, msg, e );
+ }
+ }
+
+ if ( value == null && ( config == null || config.getChildCount() <= 0 ) )
+ {
+ invalidParameters.add( parameter );
+ }
+ }
+
+ if ( !invalidParameters.isEmpty() )
+ {
+ throw new PluginParameterException( mojoDescriptor, invalidParameters );
+ }
+ }
+
+ public void releaseMojo( Object mojo, MojoExecution mojoExecution )
+ {
+ if ( mojo != null )
+ {
+ try
+ {
+ container.release( mojo );
+ }
+ catch ( ComponentLifecycleException e )
+ {
+ String goalExecId = mojoExecution.getGoal();
+
+ if ( mojoExecution.getExecutionId() != null )
+ {
+ goalExecId += " {execution: " + mojoExecution.getExecutionId() + "}";
+ }
+
+ logger.debug( "Error releasing mojo for " + goalExecId, e );
+ }
+ }
+ }
+
+ public ExtensionRealmCache.CacheRecord setupExtensionsRealm( MavenProject project, Plugin plugin,
+ RepositorySystemSession session )
+ throws PluginManagerException
+ {
+ @SuppressWarnings( "unchecked" )
+ Map<String, ExtensionRealmCache.CacheRecord> pluginRealms =
+ (Map<String, ExtensionRealmCache.CacheRecord>) project.getContextValue( KEY_EXTENSIONS_REALMS );
+ if ( pluginRealms == null )
+ {
+ pluginRealms = new HashMap<String, ExtensionRealmCache.CacheRecord>();
+ project.setContextValue( KEY_EXTENSIONS_REALMS, pluginRealms );
+ }
+
+ final String pluginKey = plugin.getId();
+
+ ExtensionRealmCache.CacheRecord extensionRecord = pluginRealms.get( pluginKey );
+ if ( extensionRecord != null )
+ {
+ return extensionRecord;
+ }
+
+ final List<RemoteRepository> repositories = project.getRemotePluginRepositories();
+
+ // resolve plugin version as necessary
+ if ( plugin.getVersion() == null )
+ {
+ PluginVersionRequest versionRequest = new DefaultPluginVersionRequest( plugin, session, repositories );
+ try
+ {
+ plugin.setVersion( pluginVersionResolver.resolve( versionRequest ).getVersion() );
+ }
+ catch ( PluginVersionResolutionException e )
+ {
+ throw new PluginManagerException( plugin, e.getMessage(), e );
+ }
+ }
+
+ // resolve plugin artifacts
+ List<Artifact> artifacts;
+ PluginArtifactsCache.Key cacheKey = pluginArtifactsCache.createKey( plugin, null, repositories, session );
+ PluginArtifactsCache.CacheRecord recordArtifacts;
+ try
+ {
+ recordArtifacts = pluginArtifactsCache.get( cacheKey );
+ }
+ catch ( PluginResolutionException e )
+ {
+ throw new PluginManagerException( plugin, e.getMessage(), e );
+ }
+ if ( recordArtifacts != null )
+ {
+ artifacts = recordArtifacts.artifacts;
+ }
+ else
+ {
+ try
+ {
+ artifacts = resolveExtensionArtifacts( plugin, repositories, session );
+ recordArtifacts = pluginArtifactsCache.put( cacheKey, artifacts );
+ }
+ catch ( PluginResolutionException e )
+ {
+ pluginArtifactsCache.put( cacheKey, e );
+ pluginArtifactsCache.register( project, cacheKey, recordArtifacts );
+ throw new PluginManagerException( plugin, e.getMessage(), e );
+ }
+ }
+ pluginArtifactsCache.register( project, cacheKey, recordArtifacts );
+
+ // create and cache extensions realms
+ final ExtensionRealmCache.Key extensionKey = extensionRealmCache.createKey( artifacts );
+ extensionRecord = extensionRealmCache.get( extensionKey );
+ if ( extensionRecord == null )
+ {
+ ClassRealm extensionRealm = classRealmManager.createExtensionRealm( plugin,
+ toAetherArtifacts( artifacts ) );
+
+ // TODO figure out how to use the same PluginDescriptor when running mojos
+
+ PluginDescriptor pluginDescriptor = null;
+ if ( plugin.isExtensions() && !artifacts.isEmpty() )
+ {
+ // ignore plugin descriptor parsing errors at this point
+ // these errors will reported during calculation of project build execution plan
+ try
+ {
+ pluginDescriptor = extractPluginDescriptor( artifacts.get( 0 ), plugin );
+ }
+ catch ( PluginDescriptorParsingException e )
+ {
+ // ignore, see above
+ }
+ catch ( InvalidPluginDescriptorException e )
+ {
+ // ignore, see above
+ }
+ }
+
+ discoverPluginComponents( extensionRealm, plugin, pluginDescriptor );
+
+ ExtensionDescriptor extensionDescriptor = null;
+ Artifact extensionArtifact = artifacts.get( 0 );
+ try
+ {
+ extensionDescriptor = extensionDescriptorBuilder.build( extensionArtifact.getFile() );
+ }
+ catch ( IOException e )
+ {
+ String message = "Invalid extension descriptor for " + plugin.getId() + ": " + e.getMessage();
+ if ( logger.isDebugEnabled() )
+ {
+ logger.error( message, e );
+ }
+ else
+ {
+ logger.error( message );
+ }
+ }
+ extensionRecord = extensionRealmCache.put( extensionKey, extensionRealm, extensionDescriptor, artifacts );
+ }
+ extensionRealmCache.register( project, extensionKey, extensionRecord );
+ pluginRealms.put( pluginKey, extensionRecord );
+
+ return extensionRecord;
+ }
+
+ private List<Artifact> resolveExtensionArtifacts( Plugin extensionPlugin, List<RemoteRepository> repositories,
+ RepositorySystemSession session )
+ throws PluginResolutionException
+ {
+ DependencyNode root = pluginDependenciesResolver.resolve( extensionPlugin, null, null, repositories, session );
+ PreorderNodeListGenerator nlg = new PreorderNodeListGenerator();
+ root.accept( nlg );
+ return toMavenArtifacts( root, nlg );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultPluginDependenciesResolver.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultPluginDependenciesResolver.java
new file mode 100644
index 00000000..5b0c2712
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultPluginDependenciesResolver.java
@@ -0,0 +1,256 @@
+package org.apache.maven.plugin.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.maven.RepositoryUtils;
+import org.apache.maven.model.Dependency;
+import org.apache.maven.model.Plugin;
+import org.apache.maven.plugin.PluginResolutionException;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+import org.codehaus.plexus.logging.Logger;
+import org.eclipse.aether.DefaultRepositorySystemSession;
+import org.eclipse.aether.RepositorySystem;
+import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.RequestTrace;
+import org.eclipse.aether.artifact.Artifact;
+import org.eclipse.aether.artifact.DefaultArtifact;
+import org.eclipse.aether.collection.CollectRequest;
+import org.eclipse.aether.collection.DependencyCollectionException;
+import org.eclipse.aether.collection.DependencyGraphTransformer;
+import org.eclipse.aether.collection.DependencySelector;
+import org.eclipse.aether.graph.DependencyFilter;
+import org.eclipse.aether.graph.DependencyNode;
+import org.eclipse.aether.graph.DependencyVisitor;
+import org.eclipse.aether.repository.RemoteRepository;
+import org.eclipse.aether.resolution.ArtifactDescriptorException;
+import org.eclipse.aether.resolution.ArtifactDescriptorRequest;
+import org.eclipse.aether.resolution.ArtifactDescriptorResult;
+import org.eclipse.aether.resolution.ArtifactRequest;
+import org.eclipse.aether.resolution.ArtifactResolutionException;
+import org.eclipse.aether.resolution.DependencyRequest;
+import org.eclipse.aether.resolution.DependencyResolutionException;
+import org.eclipse.aether.util.artifact.JavaScopes;
+import org.eclipse.aether.util.filter.AndDependencyFilter;
+import org.eclipse.aether.util.filter.ScopeDependencyFilter;
+import org.eclipse.aether.util.graph.selector.AndDependencySelector;
+import org.eclipse.aether.util.graph.transformer.ChainedDependencyGraphTransformer;
+import org.eclipse.aether.util.repository.SimpleArtifactDescriptorPolicy;
+
+/**
+ * Assists in resolving the dependencies of a plugin. <strong>Warning:</strong> This is an internal utility class that
+ * is only public for technical reasons, it is not part of the public API. In particular, this class can be changed or
+ * deleted without prior notice.
+ *
+ * @since 3.0
+ * @author Benjamin Bentmann
+ */
+@Component( role = PluginDependenciesResolver.class )
+public class DefaultPluginDependenciesResolver
+ implements PluginDependenciesResolver
+{
+
+ private static final String REPOSITORY_CONTEXT = "plugin";
+
+ @Requirement
+ private Logger logger;
+
+ @Requirement
+ private RepositorySystem repoSystem;
+
+ private Artifact toArtifact( Plugin plugin, RepositorySystemSession session )
+ {
+ return new DefaultArtifact( plugin.getGroupId(), plugin.getArtifactId(), null, "jar", plugin.getVersion(),
+ session.getArtifactTypeRegistry().get( "maven-plugin" ) );
+ }
+
+ public Artifact resolve( Plugin plugin, List<RemoteRepository> repositories, RepositorySystemSession session )
+ throws PluginResolutionException
+ {
+ RequestTrace trace = RequestTrace.newChild( null, plugin );
+
+ Artifact pluginArtifact = toArtifact( plugin, session );
+
+ try
+ {
+ DefaultRepositorySystemSession pluginSession = new DefaultRepositorySystemSession( session );
+ pluginSession.setArtifactDescriptorPolicy( new SimpleArtifactDescriptorPolicy( true, false ) );
+
+ ArtifactDescriptorRequest request =
+ new ArtifactDescriptorRequest( pluginArtifact, repositories, REPOSITORY_CONTEXT );
+ request.setTrace( trace );
+ ArtifactDescriptorResult result = repoSystem.readArtifactDescriptor( pluginSession, request );
+
+ pluginArtifact = result.getArtifact();
+
+ String requiredMavenVersion = (String) result.getProperties().get( "prerequisites.maven" );
+ if ( requiredMavenVersion != null )
+ {
+ Map<String, String> props = new LinkedHashMap<String, String>( pluginArtifact.getProperties() );
+ props.put( "requiredMavenVersion", requiredMavenVersion );
+ pluginArtifact = pluginArtifact.setProperties( props );
+ }
+ }
+ catch ( ArtifactDescriptorException e )
+ {
+ throw new PluginResolutionException( plugin, e );
+ }
+
+ try
+ {
+ ArtifactRequest request = new ArtifactRequest( pluginArtifact, repositories, REPOSITORY_CONTEXT );
+ request.setTrace( trace );
+ pluginArtifact = repoSystem.resolveArtifact( session, request ).getArtifact();
+ }
+ catch ( ArtifactResolutionException e )
+ {
+ throw new PluginResolutionException( plugin, e );
+ }
+
+ return pluginArtifact;
+ }
+
+ /**
+ * @since 3.3.0
+ */
+ public DependencyNode resolveCoreExtension( Plugin plugin, DependencyFilter dependencyFilter,
+ List<RemoteRepository> repositories, RepositorySystemSession session )
+ throws PluginResolutionException
+ {
+ return resolveInternal( plugin, null /* pluginArtifact */, dependencyFilter, null /* transformer */,
+ repositories, session );
+ }
+
+ public DependencyNode resolve( Plugin plugin, Artifact pluginArtifact, DependencyFilter dependencyFilter,
+ List<RemoteRepository> repositories, RepositorySystemSession session )
+ throws PluginResolutionException
+ {
+ return resolveInternal( plugin, pluginArtifact, dependencyFilter, new PlexusUtilsInjector(), repositories,
+ session );
+ }
+
+ private DependencyNode resolveInternal( Plugin plugin, Artifact pluginArtifact, DependencyFilter dependencyFilter,
+ DependencyGraphTransformer transformer,
+ List<RemoteRepository> repositories, RepositorySystemSession session )
+ throws PluginResolutionException
+ {
+ RequestTrace trace = RequestTrace.newChild( null, plugin );
+
+ if ( pluginArtifact == null )
+ {
+ pluginArtifact = toArtifact( plugin, session );
+ }
+
+ DependencyFilter collectionFilter = new ScopeDependencyFilter( "provided", "test" );
+ DependencyFilter resolutionFilter = AndDependencyFilter.newInstance( collectionFilter, dependencyFilter );
+
+ DependencyNode node;
+
+ try
+ {
+ DependencySelector selector =
+ AndDependencySelector.newInstance( session.getDependencySelector(), new WagonExcluder() );
+
+ transformer =
+ ChainedDependencyGraphTransformer.newInstance( session.getDependencyGraphTransformer(), transformer );
+
+ DefaultRepositorySystemSession pluginSession = new DefaultRepositorySystemSession( session );
+ pluginSession.setDependencySelector( selector );
+ pluginSession.setDependencyGraphTransformer( transformer );
+
+ CollectRequest request = new CollectRequest();
+ request.setRequestContext( REPOSITORY_CONTEXT );
+ request.setRepositories( repositories );
+ request.setRoot( new org.eclipse.aether.graph.Dependency( pluginArtifact, null ) );
+ for ( Dependency dependency : plugin.getDependencies() )
+ {
+ org.eclipse.aether.graph.Dependency pluginDep =
+ RepositoryUtils.toDependency( dependency, session.getArtifactTypeRegistry() );
+ if ( !JavaScopes.SYSTEM.equals( pluginDep.getScope() ) )
+ {
+ pluginDep = pluginDep.setScope( JavaScopes.RUNTIME );
+ }
+ request.addDependency( pluginDep );
+ }
+
+ DependencyRequest depRequest = new DependencyRequest( request, resolutionFilter );
+ depRequest.setTrace( trace );
+
+ request.setTrace( RequestTrace.newChild( trace, depRequest ) );
+
+ node = repoSystem.collectDependencies( pluginSession, request ).getRoot();
+
+ if ( logger.isDebugEnabled() )
+ {
+ node.accept( new GraphLogger() );
+ }
+
+ depRequest.setRoot( node );
+ repoSystem.resolveDependencies( session, depRequest );
+ }
+ catch ( DependencyCollectionException e )
+ {
+ throw new PluginResolutionException( plugin, e );
+ }
+ catch ( DependencyResolutionException e )
+ {
+ throw new PluginResolutionException( plugin, e.getCause() );
+ }
+
+ return node;
+ }
+
+ class GraphLogger
+ implements DependencyVisitor
+ {
+
+ private String indent = "";
+
+ public boolean visitEnter( DependencyNode node )
+ {
+ StringBuilder buffer = new StringBuilder( 128 );
+ buffer.append( indent );
+ org.eclipse.aether.graph.Dependency dep = node.getDependency();
+ if ( dep != null )
+ {
+ Artifact art = dep.getArtifact();
+
+ buffer.append( art );
+ buffer.append( ':' ).append( dep.getScope() );
+ }
+
+ logger.debug( buffer.toString() );
+ indent += " ";
+ return true;
+ }
+
+ public boolean visitLeave( DependencyNode node )
+ {
+ indent = indent.substring( 0, indent.length() - 3 );
+ return true;
+ }
+
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultPluginManager.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultPluginManager.java
new file mode 100644
index 00000000..015060f6
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultPluginManager.java
@@ -0,0 +1,261 @@
+package org.apache.maven.plugin.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Map;
+
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
+import org.apache.maven.artifact.resolver.ArtifactResolutionException;
+import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.model.Plugin;
+import org.apache.maven.plugin.InvalidPluginDescriptorException;
+import org.apache.maven.plugin.InvalidPluginException;
+import org.apache.maven.plugin.LegacySupport;
+import org.apache.maven.plugin.MavenPluginManager;
+import org.apache.maven.plugin.MojoExecution;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugin.PluginConfigurationException;
+import org.apache.maven.plugin.PluginDescriptorParsingException;
+import org.apache.maven.plugin.PluginManager;
+import org.apache.maven.plugin.PluginManagerException;
+import org.apache.maven.plugin.PluginNotFoundException;
+import org.apache.maven.plugin.PluginResolutionException;
+import org.apache.maven.plugin.descriptor.PluginDescriptor;
+import org.apache.maven.plugin.prefix.DefaultPluginPrefixRequest;
+import org.apache.maven.plugin.prefix.NoPluginFoundForPrefixException;
+import org.apache.maven.plugin.prefix.PluginPrefixRequest;
+import org.apache.maven.plugin.prefix.PluginPrefixResolver;
+import org.apache.maven.plugin.prefix.PluginPrefixResult;
+import org.apache.maven.plugin.version.DefaultPluginVersionRequest;
+import org.apache.maven.plugin.version.PluginVersionNotFoundException;
+import org.apache.maven.plugin.version.PluginVersionRequest;
+import org.apache.maven.plugin.version.PluginVersionResolutionException;
+import org.apache.maven.plugin.version.PluginVersionResolver;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.project.artifact.InvalidDependencyVersionException;
+import org.apache.maven.settings.Settings;
+import org.codehaus.plexus.PlexusContainer;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
+
+/**
+ * @author Benjamin Bentmann
+ */
+@Component( role = PluginManager.class )
+public class DefaultPluginManager
+ implements PluginManager
+{
+
+ @Requirement
+ private PlexusContainer container;
+
+ @Requirement
+ private MavenPluginManager pluginManager;
+
+ @Requirement
+ private PluginVersionResolver pluginVersionResolver;
+
+ @Requirement
+ private PluginPrefixResolver pluginPrefixResolver;
+
+ @Requirement
+ private LegacySupport legacySupport;
+
+ public void executeMojo( MavenProject project, MojoExecution execution, MavenSession session )
+ throws MojoExecutionException, ArtifactResolutionException, MojoFailureException, ArtifactNotFoundException,
+ InvalidDependencyVersionException, PluginManagerException, PluginConfigurationException
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public Object getPluginComponent( Plugin plugin, String role, String roleHint )
+ throws PluginManagerException, ComponentLookupException
+ {
+ MavenSession session = legacySupport.getSession();
+
+ PluginDescriptor pluginDescriptor;
+ try
+ {
+ pluginDescriptor =
+ pluginManager.getPluginDescriptor( plugin, session.getCurrentProject().getRemotePluginRepositories(),
+ session.getRepositorySession() );
+
+ pluginManager.setupPluginRealm( pluginDescriptor, session, null, null, null );
+ }
+ catch ( Exception e )
+ {
+ throw new PluginManagerException( plugin, e.getMessage(), e );
+ }
+
+ ClassLoader oldClassLoader = Thread.currentThread().getContextClassLoader();
+ try
+ {
+ Thread.currentThread().setContextClassLoader( pluginDescriptor.getClassRealm() );
+
+ return container.lookup( role, roleHint );
+ }
+ finally
+ {
+ Thread.currentThread().setContextClassLoader( oldClassLoader );
+ }
+ }
+
+ public Map getPluginComponents( Plugin plugin, String role )
+ throws ComponentLookupException, PluginManagerException
+ {
+ MavenSession session = legacySupport.getSession();
+
+ PluginDescriptor pluginDescriptor;
+ try
+ {
+ pluginDescriptor =
+ pluginManager.getPluginDescriptor( plugin, session.getCurrentProject().getRemotePluginRepositories(),
+ session.getRepositorySession() );
+
+ pluginManager.setupPluginRealm( pluginDescriptor, session, null, null, null );
+ }
+ catch ( Exception e )
+ {
+ throw new PluginManagerException( plugin, e.getMessage(), e );
+ }
+
+ ClassLoader oldClassLoader = Thread.currentThread().getContextClassLoader();
+ try
+ {
+ Thread.currentThread().setContextClassLoader( pluginDescriptor.getClassRealm() );
+
+ return container.lookupMap( role );
+ }
+ finally
+ {
+ Thread.currentThread().setContextClassLoader( oldClassLoader );
+ }
+ }
+
+ public Plugin getPluginDefinitionForPrefix( String prefix, MavenSession session, MavenProject project )
+ {
+ PluginPrefixRequest request = new DefaultPluginPrefixRequest( prefix, session );
+ request.setPom( project.getModel() );
+
+ try
+ {
+ PluginPrefixResult result = pluginPrefixResolver.resolve( request );
+
+ Plugin plugin = new Plugin();
+ plugin.setGroupId( result.getGroupId() );
+ plugin.setArtifactId( result.getArtifactId() );
+
+ return plugin;
+ }
+ catch ( NoPluginFoundForPrefixException e )
+ {
+ return null;
+ }
+ }
+
+ public PluginDescriptor getPluginDescriptorForPrefix( String prefix )
+ {
+ MavenSession session = legacySupport.getSession();
+
+ PluginPrefixRequest request = new DefaultPluginPrefixRequest( prefix, session );
+
+ try
+ {
+ PluginPrefixResult result = pluginPrefixResolver.resolve( request );
+
+ Plugin plugin = new Plugin();
+ plugin.setGroupId( result.getGroupId() );
+ plugin.setArtifactId( result.getArtifactId() );
+
+ return loadPluginDescriptor( plugin, session.getCurrentProject(), session );
+ }
+ catch ( Exception e )
+ {
+ return null;
+ }
+ }
+
+ public PluginDescriptor loadPluginDescriptor( Plugin plugin, MavenProject project, MavenSession session )
+ throws ArtifactResolutionException, PluginVersionResolutionException, ArtifactNotFoundException,
+ InvalidVersionSpecificationException, InvalidPluginException, PluginManagerException, PluginNotFoundException,
+ PluginVersionNotFoundException
+ {
+ return verifyPlugin( plugin, project, session.getSettings(), session.getLocalRepository() );
+ }
+
+ public PluginDescriptor loadPluginFully( Plugin plugin, MavenProject project, MavenSession session )
+ throws ArtifactResolutionException, PluginVersionResolutionException, ArtifactNotFoundException,
+ InvalidVersionSpecificationException, InvalidPluginException, PluginManagerException, PluginNotFoundException,
+ PluginVersionNotFoundException
+ {
+ PluginDescriptor pluginDescriptor = loadPluginDescriptor( plugin, project, session );
+
+ try
+ {
+ pluginManager.setupPluginRealm( pluginDescriptor, session, null, null, null );
+ }
+ catch ( PluginResolutionException e )
+ {
+ throw new PluginManagerException( plugin, e.getMessage(), e );
+ }
+
+ return pluginDescriptor;
+ }
+
+ public PluginDescriptor verifyPlugin( Plugin plugin, MavenProject project, Settings settings,
+ ArtifactRepository localRepository )
+ throws ArtifactResolutionException, PluginVersionResolutionException, ArtifactNotFoundException,
+ InvalidVersionSpecificationException, InvalidPluginException, PluginManagerException, PluginNotFoundException,
+ PluginVersionNotFoundException
+ {
+ MavenSession session = legacySupport.getSession();
+
+ if ( plugin.getVersion() == null )
+ {
+ PluginVersionRequest versionRequest =
+ new DefaultPluginVersionRequest( plugin, session.getRepositorySession(),
+ project.getRemotePluginRepositories() );
+ plugin.setVersion( pluginVersionResolver.resolve( versionRequest ).getVersion() );
+ }
+
+ try
+ {
+ return pluginManager.getPluginDescriptor( plugin, project.getRemotePluginRepositories(),
+ session.getRepositorySession() );
+ }
+ catch ( PluginResolutionException e )
+ {
+ throw new PluginNotFoundException( plugin, project.getPluginArtifactRepositories() );
+ }
+ catch ( PluginDescriptorParsingException e )
+ {
+ throw new PluginManagerException( plugin, e.getMessage(), e );
+ }
+ catch ( InvalidPluginDescriptorException e )
+ {
+ throw new PluginManagerException( plugin, e.getMessage(), e );
+ }
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/internal/PlexusUtilsInjector.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/internal/PlexusUtilsInjector.java
new file mode 100644
index 00000000..16a0b63c
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/internal/PlexusUtilsInjector.java
@@ -0,0 +1,87 @@
+package org.apache.maven.plugin.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.eclipse.aether.RepositoryException;
+import org.eclipse.aether.artifact.Artifact;
+import org.eclipse.aether.artifact.DefaultArtifact;
+import org.eclipse.aether.collection.DependencyGraphTransformationContext;
+import org.eclipse.aether.collection.DependencyGraphTransformer;
+import org.eclipse.aether.graph.DefaultDependencyNode;
+import org.eclipse.aether.graph.Dependency;
+import org.eclipse.aether.graph.DependencyNode;
+import org.eclipse.aether.util.artifact.JavaScopes;
+
+/**
+ * Injects plexus-utils:1.1 into a plugin's class path if it doesn't already declare a dependency on plexus-utils. This
+ * is another legacy bit to provide backward-compat with Maven 2.x.
+ *
+ * @author Benjamin Bentmann
+ */
+class PlexusUtilsInjector
+ implements DependencyGraphTransformer
+{
+
+ private static final String GID = "org.codehaus.plexus";
+
+ private static final String AID = "plexus-utils";
+
+ private static final String VER = "1.1";
+
+ private static final String EXT = "jar";
+
+ public DependencyNode transformGraph( DependencyNode node, DependencyGraphTransformationContext context )
+ throws RepositoryException
+ {
+ if ( findPlexusUtils( node ) == null )
+ {
+ Artifact pu = new DefaultArtifact( GID, AID, null, EXT, VER );
+ DefaultDependencyNode child = new DefaultDependencyNode( new Dependency( pu, JavaScopes.RUNTIME ) );
+ child.setRepositories( node.getRepositories() );
+ child.setRequestContext( node.getRequestContext() );
+ node.getChildren().add( child );
+ }
+
+ return node;
+ }
+
+ private DependencyNode findPlexusUtils( DependencyNode node )
+ {
+ Artifact artifact = node.getDependency().getArtifact();
+
+ if ( AID.equals( artifact.getArtifactId() ) && GID.equals( artifact.getGroupId() )
+ && EXT.equals( artifact.getExtension() ) && "".equals( artifact.getClassifier() ) )
+ {
+ return node;
+ }
+
+ for ( DependencyNode child : node.getChildren() )
+ {
+ DependencyNode result = findPlexusUtils( child );
+ if ( result != null )
+ {
+ return result;
+ }
+ }
+
+ return null;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/internal/PluginDependenciesResolver.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/internal/PluginDependenciesResolver.java
new file mode 100644
index 00000000..41942978
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/internal/PluginDependenciesResolver.java
@@ -0,0 +1,71 @@
+package org.apache.maven.plugin.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.List;
+
+import org.apache.maven.model.Plugin;
+import org.apache.maven.plugin.PluginResolutionException;
+import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.artifact.Artifact;
+import org.eclipse.aether.graph.DependencyFilter;
+import org.eclipse.aether.graph.DependencyNode;
+import org.eclipse.aether.repository.RemoteRepository;
+
+/**
+ * Assists in resolving the dependencies of a plugin. <strong>Warning:</strong> This is an internal utility interface
+ * that is only public for technical reasons, it is not part of the public API. In particular, this interface can be
+ * changed or deleted without prior notice.
+ *
+ * @since 3.0
+ * @author Benjamin Bentmann
+ */
+public interface PluginDependenciesResolver
+{
+
+ /**
+ * Resolves the main artifact of the specified plugin.
+ *
+ * @param plugin The plugin for which to resolve the main artifact, must not be {@code null}.
+ * @param repositories The plugin repositories to use for resolving the plugin's main artifact, must not be {@code
+ * null}.
+ * @param session The repository session to use for resolving the plugin's main artifact, must not be {@code null}.
+ * @return The resolved plugin artifact, never {@code null}.
+ * @throws PluginResolutionException If the plugin artifact could not be resolved.
+ */
+ Artifact resolve( Plugin plugin, List<RemoteRepository> repositories, RepositorySystemSession session )
+ throws PluginResolutionException;
+
+ /**
+ * Resolves the runtime dependencies of the specified plugin.
+ *
+ * @param plugin The plugin for which to resolve the dependencies, must not be {@code null}.
+ * @param pluginArtifact The plugin's main artifact, may be {@code null}.
+ * @param dependencyFilter A filter to exclude artifacts from resolution (but not collection), may be {@code null}.
+ * @param repositories The plugin repositories to use for resolving the plugin artifacts, must not be {@code null}.
+ * @param session The repository session to use for resolving the plugin artifacts, must not be {@code null}.
+ * @return The dependency tree denoting the resolved plugin class path, never {@code null}.
+ * @throws PluginResolutionException If any dependency could not be resolved.
+ */
+ DependencyNode resolve( Plugin plugin, Artifact pluginArtifact, DependencyFilter dependencyFilter,
+ List<RemoteRepository> repositories, RepositorySystemSession session )
+ throws PluginResolutionException;
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/internal/PluginDependencyResolutionListener.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/internal/PluginDependencyResolutionListener.java
new file mode 100644
index 00000000..533920a8
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/internal/PluginDependencyResolutionListener.java
@@ -0,0 +1,158 @@
+package org.apache.maven.plugin.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Collection;
+import java.util.IdentityHashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.Map;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.resolver.ResolutionListener;
+import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
+import org.apache.maven.artifact.versioning.VersionRange;
+
+/**
+ * Assists in detecting wagon providers brought into the plugin class path via legacy Maven core artifacts (e.g.
+ * maven-core:2.0.6) and excluding them. A plugin should be able to explicitly declare dependencies on specific wagons
+ * for its use. However, the (old) wagons pulled in transitively via legacy Maven core artifacts are usually not
+ * intended as dependencies and more importantly screw up artifact resolution because they would get preferred over the
+ * core wagon versions. This is a hack to provide backward-compat with Maven 2 (MNG-4528, MNG-4561).
+ *
+ * @since 3.0
+ * @author Benjamin Bentmann
+ */
+class PluginDependencyResolutionListener
+ implements ResolutionListener
+{
+
+ private ArtifactFilter coreFilter;
+
+ private LinkedList<Artifact> coreArtifacts = new LinkedList<Artifact>();
+
+ private Artifact wagonProvider;
+
+ private Map<Artifact, Object> bannedArtifacts = new IdentityHashMap<Artifact, Object>();
+
+ public PluginDependencyResolutionListener( ArtifactFilter coreFilter )
+ {
+ this.coreFilter = coreFilter;
+ }
+
+ public void removeBannedDependencies( Collection<Artifact> artifacts )
+ {
+ if ( !bannedArtifacts.isEmpty() && artifacts != null )
+ {
+ for ( Iterator<Artifact> it = artifacts.iterator(); it.hasNext(); )
+ {
+ Artifact artifact = it.next();
+ if ( bannedArtifacts.containsKey( artifact ) )
+ {
+ it.remove();
+ }
+ }
+ }
+ }
+
+ public void startProcessChildren( Artifact artifact )
+ {
+ if ( wagonProvider == null )
+ {
+ if ( isLegacyCoreArtifact( artifact ) )
+ {
+ coreArtifacts.addFirst( artifact );
+ }
+ else if ( !coreArtifacts.isEmpty() && isWagonProvider( artifact ) )
+ {
+ wagonProvider = artifact;
+ bannedArtifacts.put( artifact, null );
+ }
+ }
+ }
+
+ private boolean isLegacyCoreArtifact( Artifact artifact )
+ {
+ String version = artifact.getVersion();
+ return version != null && version.startsWith( "2." ) && !coreFilter.include( artifact );
+ }
+
+ public void endProcessChildren( Artifact artifact )
+ {
+ if ( wagonProvider == artifact )
+ {
+ wagonProvider = null;
+ }
+ else if ( coreArtifacts.peek() == artifact )
+ {
+ coreArtifacts.removeFirst();
+ }
+ }
+
+ public void includeArtifact( Artifact artifact )
+ {
+ if ( wagonProvider != null )
+ {
+ bannedArtifacts.put( artifact, null );
+ }
+ }
+
+ private boolean isWagonProvider( Artifact artifact )
+ {
+ if ( "org.apache.maven.wagon".equals( artifact.getGroupId() ) )
+ {
+ return artifact.getArtifactId().startsWith( "wagon-" );
+ }
+ return false;
+ }
+
+ public void manageArtifact( Artifact artifact, Artifact replacement )
+ {
+ }
+
+ public void omitForCycle( Artifact artifact )
+ {
+ }
+
+ public void omitForNearer( Artifact omitted, Artifact kept )
+ {
+ }
+
+ public void restrictRange( Artifact artifact, Artifact replacement, VersionRange newRange )
+ {
+ }
+
+ public void selectVersionFromRange( Artifact artifact )
+ {
+ }
+
+ public void testArtifact( Artifact node )
+ {
+ }
+
+ public void updateScope( Artifact artifact, String scope )
+ {
+ }
+
+ public void updateScopeCurrentPom( Artifact artifact, String ignoredScope )
+ {
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/internal/ValidatingConfigurationListener.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/internal/ValidatingConfigurationListener.java
new file mode 100644
index 00000000..706694b8
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/internal/ValidatingConfigurationListener.java
@@ -0,0 +1,97 @@
+package org.apache.maven.plugin.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.maven.plugin.descriptor.MojoDescriptor;
+import org.apache.maven.plugin.descriptor.Parameter;
+import org.codehaus.plexus.component.configurator.ConfigurationListener;
+
+/**
+ * A configuration listener to help validate the plugin configuration. For instance, check for required but missing
+ * parameters.
+ *
+ * @author Benjamin Bentmann
+ */
+class ValidatingConfigurationListener
+ implements ConfigurationListener
+{
+
+ private final Object mojo;
+
+ private final ConfigurationListener delegate;
+
+ private final Map<String, Parameter> missingParameters;
+
+ public ValidatingConfigurationListener( Object mojo, MojoDescriptor mojoDescriptor, ConfigurationListener delegate )
+ {
+ this.mojo = mojo;
+ this.delegate = delegate;
+ this.missingParameters = new HashMap<String, Parameter>();
+
+ if ( mojoDescriptor.getParameters() != null )
+ {
+ for ( Parameter param : mojoDescriptor.getParameters() )
+ {
+ if ( param.isRequired() )
+ {
+ missingParameters.put( param.getName(), param );
+ }
+ }
+ }
+ }
+
+ public Collection<Parameter> getMissingParameters()
+ {
+ return missingParameters.values();
+ }
+
+ public void notifyFieldChangeUsingSetter( String fieldName, Object value, Object target )
+ {
+ delegate.notifyFieldChangeUsingSetter( fieldName, value, target );
+
+ if ( mojo == target )
+ {
+ notify( fieldName, value );
+ }
+ }
+
+ public void notifyFieldChangeUsingReflection( String fieldName, Object value, Object target )
+ {
+ delegate.notifyFieldChangeUsingReflection( fieldName, value, target );
+
+ if ( mojo == target )
+ {
+ notify( fieldName, value );
+ }
+ }
+
+ private void notify( String fieldName, Object value )
+ {
+ if ( value != null )
+ {
+ missingParameters.remove( fieldName );
+ }
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/internal/WagonExcluder.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/internal/WagonExcluder.java
new file mode 100644
index 00000000..43e8cfc4
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/internal/WagonExcluder.java
@@ -0,0 +1,109 @@
+package org.apache.maven.plugin.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.eclipse.aether.artifact.Artifact;
+import org.eclipse.aether.collection.DependencyCollectionContext;
+import org.eclipse.aether.collection.DependencySelector;
+import org.eclipse.aether.graph.Dependency;
+
+/**
+ * Assists in detecting wagon providers brought into the plugin class path via legacy Maven core artifacts (e.g.
+ * maven-core:2.0.6) and excluding them. A plugin should be able to explicitly declare dependencies on specific wagons
+ * for its use. However, the (old) wagons pulled in transitively via legacy Maven core artifacts are usually not
+ * intended as dependencies and more importantly screw up artifact resolution because they would get preferred over the
+ * core wagon versions. This is a hack to provide backward-compat with Maven 2 (MNG-4528, MNG-4561).
+ *
+ * @author Benjamin Bentmann
+ */
+class WagonExcluder
+ implements DependencySelector
+{
+
+ private final boolean coreArtifact;
+
+ public WagonExcluder()
+ {
+ this( false );
+ }
+
+ private WagonExcluder( boolean coreArtifact )
+ {
+ this.coreArtifact = coreArtifact;
+ }
+
+ public boolean selectDependency( Dependency dependency )
+ {
+ return !coreArtifact || !isWagonProvider( dependency.getArtifact() );
+ }
+
+ public DependencySelector deriveChildSelector( DependencyCollectionContext context )
+ {
+ if ( coreArtifact || !isLegacyCoreArtifact( context.getDependency().getArtifact() ) )
+ {
+ return this;
+ }
+ else
+ {
+ return new WagonExcluder( true );
+ }
+ }
+
+ private boolean isLegacyCoreArtifact( Artifact artifact )
+ {
+ String version = artifact.getVersion();
+ return version != null && version.startsWith( "2." ) && artifact.getArtifactId().startsWith( "maven-" )
+ && artifact.getGroupId().equals( "org.apache.maven" );
+ }
+
+ private boolean isWagonProvider( Artifact artifact )
+ {
+ if ( "org.apache.maven.wagon".equals( artifact.getGroupId() ) )
+ {
+ return artifact.getArtifactId().startsWith( "wagon-" );
+ }
+ return false;
+ }
+
+ @Override
+ public boolean equals( Object obj )
+ {
+ if ( obj == this )
+ {
+ return true;
+ }
+ else if ( obj == null || !getClass().equals( obj.getClass() ) )
+ {
+ return false;
+ }
+
+ WagonExcluder that = (WagonExcluder) obj;
+ return coreArtifact == that.coreArtifact;
+ }
+
+ @Override
+ public int hashCode()
+ {
+ int hash = getClass().hashCode();
+ hash = hash * 31 + ( coreArtifact ? 1 : 0 );
+ return hash;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/prefix/DefaultPluginPrefixRequest.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/prefix/DefaultPluginPrefixRequest.java
new file mode 100644
index 00000000..7ab86cfd
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/prefix/DefaultPluginPrefixRequest.java
@@ -0,0 +1,156 @@
+package org.apache.maven.plugin.prefix;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.model.Model;
+import org.apache.maven.project.MavenProject;
+import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.repository.RemoteRepository;
+
+/**
+ * Collects settings required to resolve a plugin prefix.
+ *
+ * @since 3.0
+ * @author Benjamin Bentmann
+ */
+public class DefaultPluginPrefixRequest
+ implements PluginPrefixRequest
+{
+
+ private String prefix;
+
+ private List<String> pluginGroups = Collections.emptyList();
+
+ private Model pom;
+
+ private List<RemoteRepository> repositories = Collections.emptyList();
+
+ private RepositorySystemSession session;
+
+ /**
+ * Creates an empty request.
+ */
+ public DefaultPluginPrefixRequest()
+ {
+ }
+
+ /**
+ * Creates a request for the specified plugin prefix and build session. The provided build session will be used to
+ * configure repository settings. If the session has a current project, its plugin repositories and model will be
+ * used as well.
+ *
+ * @param prefix The plugin prefix to resolve, must not be {@code null}.
+ * @param session The build session from which to derive further settings, must not be {@code null}.
+ */
+ public DefaultPluginPrefixRequest( String prefix, MavenSession session )
+ {
+ setPrefix( prefix );
+
+ setRepositorySession( session.getRepositorySession() );
+
+ MavenProject project = session.getCurrentProject();
+ if ( project != null )
+ {
+ setRepositories( project.getRemotePluginRepositories() );
+ setPom( project.getModel() );
+ }
+
+ setPluginGroups( session.getPluginGroups() );
+ }
+
+ public String getPrefix()
+ {
+ return prefix;
+ }
+
+ public DefaultPluginPrefixRequest setPrefix( String prefix )
+ {
+ this.prefix = prefix;
+
+ return this;
+ }
+
+ public List<String> getPluginGroups()
+ {
+ return pluginGroups;
+ }
+
+ public DefaultPluginPrefixRequest setPluginGroups( List<String> pluginGroups )
+ {
+ if ( pluginGroups != null )
+ {
+ this.pluginGroups = pluginGroups;
+ }
+ else
+ {
+ this.pluginGroups = Collections.emptyList();
+ }
+
+ return this;
+ }
+
+ public Model getPom()
+ {
+ return pom;
+ }
+
+ public DefaultPluginPrefixRequest setPom( Model pom )
+ {
+ this.pom = pom;
+
+ return this;
+ }
+
+ public List<RemoteRepository> getRepositories()
+ {
+ return repositories;
+ }
+
+ public DefaultPluginPrefixRequest setRepositories( List<RemoteRepository> repositories )
+ {
+ if ( repositories != null )
+ {
+ this.repositories = repositories;
+ }
+ else
+ {
+ this.repositories = Collections.emptyList();
+ }
+
+ return this;
+ }
+
+ public RepositorySystemSession getRepositorySession()
+ {
+ return session;
+ }
+
+ public DefaultPluginPrefixRequest setRepositorySession( RepositorySystemSession session )
+ {
+ this.session = session;
+
+ return this;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/prefix/NoPluginFoundForPrefixException.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/prefix/NoPluginFoundForPrefixException.java
new file mode 100644
index 00000000..32870217
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/prefix/NoPluginFoundForPrefixException.java
@@ -0,0 +1,65 @@
+package org.apache.maven.plugin.prefix;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.List;
+
+import org.eclipse.aether.repository.LocalRepository;
+import org.eclipse.aether.repository.RemoteRepository;
+
+public class NoPluginFoundForPrefixException
+ extends Exception
+{
+
+ public NoPluginFoundForPrefixException( String prefix, List<String> pluginGroups, LocalRepository localRepository,
+ List<RemoteRepository> remoteRepositories )
+ {
+ super( "No plugin found for prefix '" + prefix + "' in the current project and in the plugin groups "
+ + pluginGroups + " available from the repositories " + format( localRepository, remoteRepositories ) );
+ }
+
+ private static String format( LocalRepository localRepository, List<RemoteRepository> remoteRepositories )
+ {
+ String repos = "[";
+
+ if ( localRepository != null )
+ {
+ repos += localRepository.getId() + " (" + localRepository.getBasedir() + ")";
+ }
+
+ if ( remoteRepositories != null && !remoteRepositories.isEmpty() )
+ {
+ for ( RemoteRepository repository : remoteRepositories )
+ {
+ repos += ", ";
+
+ if ( repository != null )
+ {
+ repos += repository.getId() + " (" + repository.getUrl() + ")";
+ }
+ }
+ }
+
+ repos += "]";
+
+ return repos;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/prefix/PluginPrefixRequest.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/prefix/PluginPrefixRequest.java
new file mode 100644
index 00000000..23df66ee
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/prefix/PluginPrefixRequest.java
@@ -0,0 +1,115 @@
+package org.apache.maven.plugin.prefix;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.List;
+
+import org.apache.maven.model.Model;
+import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.repository.RemoteRepository;
+
+/**
+ * Collects settings required to resolve a plugin prefix.
+ *
+ * @since 3.0
+ * @author Benjamin Bentmann
+ */
+public interface PluginPrefixRequest
+{
+
+ /**
+ * Gets the prefix of the plugin.
+ *
+ * @return The prefix of the plugin.
+ */
+ String getPrefix();
+
+ /**
+ * Sets the prefix of the plugin.
+ *
+ * @param prefix The prefix of the plugin.
+ * @return This request, never {@code null}.
+ */
+ PluginPrefixRequest setPrefix( String prefix );
+
+ /**
+ * Gets the list of group ids to scan for the plugin prefix.
+ *
+ * @return The list of group ids to scan for the plugin prefix, never {@code null}.
+ */
+ List<String> getPluginGroups();
+
+ /**
+ * Sets the list of group ids to scan for the plugin prefix.
+ *
+ * @param pluginGroups The list of group ids to scan for the plugin prefix, may be {@code null}.
+ * @return This request, never {@code null}.
+ */
+ PluginPrefixRequest setPluginGroups( List<String> pluginGroups );
+
+ /**
+ * Gets the POM whose build plugins are to be scanned for the prefix.
+ *
+ * @return The POM whose build plugins are to be scanned for the prefix or {@code null} to only search the plugin
+ * repositories.
+ */
+ Model getPom();
+
+ /**
+ * Sets the POM whose build plugins are to be scanned for the prefix.
+ *
+ * @param pom The POM whose build plugins are to be scanned for the prefix, may be {@code null} to only search the
+ * plugin repositories.
+ * @return This request, never {@code null}.
+ */
+ PluginPrefixRequest setPom( Model pom );
+
+ /**
+ * Gets the remote repositories to use.
+ *
+ * @return The remote repositories to use, never {@code null}.
+ */
+ List<RemoteRepository> getRepositories();
+
+ /**
+ * Sets the remote repositories to use. <em>Note:</em> When creating a request from a project, be sure to use the
+ * plugin repositories and not the regular project repositories.
+ *
+ * @param repositories The remote repositories to use.
+ * @return This request, never {@code null}.
+ */
+ PluginPrefixRequest setRepositories( List<RemoteRepository> repositories );
+
+ /**
+ * Gets the session to use for repository access.
+ *
+ * @return The repository session or {@code null} if not set.
+ */
+ RepositorySystemSession getRepositorySession();
+
+ /**
+ * Sets the session to use for repository access.
+ *
+ * @param repositorySession The repository session to use.
+ * @return This request, never {@code null}.
+ */
+ PluginPrefixRequest setRepositorySession( RepositorySystemSession repositorySession );
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/prefix/PluginPrefixResolver.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/prefix/PluginPrefixResolver.java
new file mode 100644
index 00000000..943e6833
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/prefix/PluginPrefixResolver.java
@@ -0,0 +1,42 @@
+package org.apache.maven.plugin.prefix;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Resolves a plugin prefix.
+ *
+ * @since 3.0
+ * @author Benjamin Bentmann
+ */
+public interface PluginPrefixResolver
+{
+
+ /**
+ * Resolves the plugin prefix for the specified request.
+ *
+ * @param request The request that holds the details about the plugin and the repositories to consult, must not be
+ * {@code null}.
+ * @return The result of the prefix resolution, never {@code null}.
+ * @throws NoPluginFoundForPrefixException If the plugin prefix could not be resolved.
+ */
+ PluginPrefixResult resolve( PluginPrefixRequest request )
+ throws NoPluginFoundForPrefixException;
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/prefix/PluginPrefixResult.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/prefix/PluginPrefixResult.java
new file mode 100644
index 00000000..8fe1a71a
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/prefix/PluginPrefixResult.java
@@ -0,0 +1,55 @@
+package org.apache.maven.plugin.prefix;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.eclipse.aether.repository.ArtifactRepository;
+
+/**
+ * Describes the result of a plugin prefix resolution request.
+ *
+ * @since 3.0
+ * @author Benjamin Bentmann
+ */
+public interface PluginPrefixResult
+{
+
+ /**
+ * The resolved group id for the plugin.
+ *
+ * @return The resolved group id for the plugin, never {@code null}.
+ */
+ String getGroupId();
+
+ /**
+ * The resolved artifact id for the plugin.
+ *
+ * @return The resolved artifact id for the plugin, never {@code null}.
+ */
+ String getArtifactId();
+
+ /**
+ * The repository from which the plugin prefix was resolved.
+ *
+ * @return The repository from which the plugin prefix was resolved or {@code null} if the prefix was resolved from
+ * the supplied POM.
+ */
+ ArtifactRepository getRepository();
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/prefix/internal/DefaultPluginPrefixResolver.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/prefix/internal/DefaultPluginPrefixResolver.java
new file mode 100644
index 00000000..8d2ad0f7
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/prefix/internal/DefaultPluginPrefixResolver.java
@@ -0,0 +1,294 @@
+package org.apache.maven.plugin.prefix.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.maven.artifact.repository.metadata.Metadata;
+import org.apache.maven.artifact.repository.metadata.io.MetadataReader;
+import org.apache.maven.model.Build;
+import org.apache.maven.model.Plugin;
+import org.apache.maven.plugin.BuildPluginManager;
+import org.apache.maven.plugin.descriptor.PluginDescriptor;
+import org.apache.maven.plugin.prefix.NoPluginFoundForPrefixException;
+import org.apache.maven.plugin.prefix.PluginPrefixRequest;
+import org.apache.maven.plugin.prefix.PluginPrefixResolver;
+import org.apache.maven.plugin.prefix.PluginPrefixResult;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+import org.codehaus.plexus.logging.Logger;
+import org.eclipse.aether.RepositoryEvent.EventType;
+import org.eclipse.aether.DefaultRepositorySystemSession;
+import org.eclipse.aether.RepositoryEvent;
+import org.eclipse.aether.RepositoryListener;
+import org.eclipse.aether.RepositorySystem;
+import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.RequestTrace;
+import org.eclipse.aether.metadata.DefaultMetadata;
+import org.eclipse.aether.repository.ArtifactRepository;
+import org.eclipse.aether.repository.RemoteRepository;
+import org.eclipse.aether.repository.RepositoryPolicy;
+import org.eclipse.aether.resolution.MetadataRequest;
+import org.eclipse.aether.resolution.MetadataResult;
+
+/**
+ * Resolves a plugin prefix.
+ *
+ * @since 3.0
+ * @author Benjamin Bentmann
+ */
+@Component( role = PluginPrefixResolver.class )
+public class DefaultPluginPrefixResolver
+ implements PluginPrefixResolver
+{
+
+ private static final String REPOSITORY_CONTEXT = "plugin";
+
+ @Requirement
+ private Logger logger;
+
+ @Requirement
+ private BuildPluginManager pluginManager;
+
+ @Requirement
+ private RepositorySystem repositorySystem;
+
+ @Requirement
+ private MetadataReader metadataReader;
+
+ public PluginPrefixResult resolve( PluginPrefixRequest request )
+ throws NoPluginFoundForPrefixException
+ {
+ logger.debug( "Resolving plugin prefix " + request.getPrefix() + " from " + request.getPluginGroups() );
+
+ PluginPrefixResult result = resolveFromProject( request );
+
+ if ( result == null )
+ {
+ result = resolveFromRepository( request );
+
+ if ( result == null )
+ {
+ throw new NoPluginFoundForPrefixException( request.getPrefix(), request.getPluginGroups(),
+ request.getRepositorySession().getLocalRepository(),
+ request.getRepositories() );
+ }
+ else if ( logger.isDebugEnabled() )
+ {
+ logger.debug( "Resolved plugin prefix " + request.getPrefix() + " to " + result.getGroupId() + ":"
+ + result.getArtifactId() + " from repository "
+ + ( result.getRepository() != null ? result.getRepository().getId() : "null" ) );
+ }
+ }
+ else if ( logger.isDebugEnabled() )
+ {
+ logger.debug( "Resolved plugin prefix " + request.getPrefix() + " to " + result.getGroupId() + ":"
+ + result.getArtifactId() + " from POM " + request.getPom() );
+ }
+
+ return result;
+ }
+
+ private PluginPrefixResult resolveFromProject( PluginPrefixRequest request )
+ {
+ PluginPrefixResult result = null;
+
+ if ( request.getPom() != null && request.getPom().getBuild() != null )
+ {
+ Build build = request.getPom().getBuild();
+
+ result = resolveFromProject( request, build.getPlugins() );
+
+ if ( result == null && build.getPluginManagement() != null )
+ {
+ result = resolveFromProject( request, build.getPluginManagement().getPlugins() );
+ }
+ }
+
+ return result;
+ }
+
+ private PluginPrefixResult resolveFromProject( PluginPrefixRequest request, List<Plugin> plugins )
+ {
+ for ( Plugin plugin : plugins )
+ {
+ try
+ {
+ PluginDescriptor pluginDescriptor =
+ pluginManager.loadPlugin( plugin, request.getRepositories(), request.getRepositorySession() );
+
+ if ( request.getPrefix().equals( pluginDescriptor.getGoalPrefix() ) )
+ {
+ return new DefaultPluginPrefixResult( plugin );
+ }
+ }
+ catch ( Exception e )
+ {
+ if ( logger.isDebugEnabled() )
+ {
+ logger.warn( "Failed to retrieve plugin descriptor for " + plugin.getId() + ": " + e.getMessage(),
+ e );
+ }
+ else
+ {
+ logger.warn( "Failed to retrieve plugin descriptor for " + plugin.getId() + ": " + e.getMessage() );
+ }
+ }
+ }
+
+ return null;
+ }
+
+ private PluginPrefixResult resolveFromRepository( PluginPrefixRequest request )
+ {
+ RequestTrace trace = RequestTrace.newChild( null, request );
+
+ List<MetadataRequest> requests = new ArrayList<MetadataRequest>();
+
+ for ( String pluginGroup : request.getPluginGroups() )
+ {
+ org.eclipse.aether.metadata.Metadata metadata =
+ new DefaultMetadata( pluginGroup, "maven-metadata.xml", DefaultMetadata.Nature.RELEASE_OR_SNAPSHOT );
+
+ requests.add( new MetadataRequest( metadata, null, REPOSITORY_CONTEXT ).setTrace( trace ) );
+
+ for ( RemoteRepository repository : request.getRepositories() )
+ {
+ requests.add( new MetadataRequest( metadata, repository, REPOSITORY_CONTEXT ).setTrace( trace ) );
+ }
+ }
+
+ // initial try, use locally cached metadata
+
+ List<MetadataResult> results = repositorySystem.resolveMetadata( request.getRepositorySession(), requests );
+ requests.clear();
+
+ PluginPrefixResult result = processResults( request, trace, results, requests );
+
+ if ( result != null )
+ {
+ return result;
+ }
+
+ // second try, refetch all (possibly outdated) metadata that wasn't updated in the first attempt
+
+ if ( !request.getRepositorySession().isOffline() && !requests.isEmpty() )
+ {
+ DefaultRepositorySystemSession session =
+ new DefaultRepositorySystemSession( request.getRepositorySession() );
+ session.setUpdatePolicy( RepositoryPolicy.UPDATE_POLICY_ALWAYS );
+
+ results = repositorySystem.resolveMetadata( session, requests );
+
+ return processResults( request, trace, results, null );
+ }
+
+ return null;
+ }
+
+ private PluginPrefixResult processResults( PluginPrefixRequest request, RequestTrace trace,
+ List<MetadataResult> results, List<MetadataRequest> requests )
+ {
+ for ( MetadataResult res : results )
+ {
+ org.eclipse.aether.metadata.Metadata metadata = res.getMetadata();
+
+ if ( metadata != null )
+ {
+ ArtifactRepository repository = res.getRequest().getRepository();
+ if ( repository == null )
+ {
+ repository = request.getRepositorySession().getLocalRepository();
+ }
+
+ PluginPrefixResult result =
+ resolveFromRepository( request, trace, metadata.getGroupId(), metadata, repository );
+
+ if ( result != null )
+ {
+ return result;
+ }
+ }
+
+ if ( requests != null && !res.isUpdated() )
+ {
+ requests.add( res.getRequest() );
+ }
+ }
+
+ return null;
+ }
+
+ private PluginPrefixResult resolveFromRepository( PluginPrefixRequest request, RequestTrace trace,
+ String pluginGroup,
+ org.eclipse.aether.metadata.Metadata metadata,
+ ArtifactRepository repository )
+ {
+ if ( metadata != null && metadata.getFile() != null && metadata.getFile().isFile() )
+ {
+ try
+ {
+ Map<String, ?> options = Collections.singletonMap( MetadataReader.IS_STRICT, Boolean.FALSE );
+
+ Metadata pluginGroupMetadata = metadataReader.read( metadata.getFile(), options );
+
+ List<org.apache.maven.artifact.repository.metadata.Plugin> plugins = pluginGroupMetadata.getPlugins();
+
+ if ( plugins != null )
+ {
+ for ( org.apache.maven.artifact.repository.metadata.Plugin plugin : plugins )
+ {
+ if ( request.getPrefix().equals( plugin.getPrefix() ) )
+ {
+ return new DefaultPluginPrefixResult( pluginGroup, plugin.getArtifactId(), repository );
+ }
+ }
+ }
+ }
+ catch ( IOException e )
+ {
+ invalidMetadata( request.getRepositorySession(), trace, metadata, repository, e );
+ }
+ }
+
+ return null;
+ }
+
+ private void invalidMetadata( RepositorySystemSession session, RequestTrace trace,
+ org.eclipse.aether.metadata.Metadata metadata, ArtifactRepository repository,
+ Exception exception )
+ {
+ RepositoryListener listener = session.getRepositoryListener();
+ if ( listener != null )
+ {
+ RepositoryEvent.Builder event = new RepositoryEvent.Builder( session, EventType.METADATA_INVALID );
+ event.setTrace( trace );
+ event.setMetadata( metadata );
+ event.setException( exception );
+ event.setRepository( repository );
+ listener.metadataInvalid( event.build() );
+ }
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/prefix/internal/DefaultPluginPrefixResult.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/prefix/internal/DefaultPluginPrefixResult.java
new file mode 100644
index 00000000..6a248bff
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/prefix/internal/DefaultPluginPrefixResult.java
@@ -0,0 +1,90 @@
+package org.apache.maven.plugin.prefix.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.model.Plugin;
+import org.apache.maven.plugin.prefix.PluginPrefixResult;
+import org.eclipse.aether.repository.ArtifactRepository;
+
+/**
+ * Describes the result of a plugin prefix resolution request.
+ *
+ * @since 3.0
+ * @author Benjamin Bentmann
+ */
+class DefaultPluginPrefixResult
+ implements PluginPrefixResult
+{
+
+ private String groupId;
+
+ private String artifactId;
+
+ private ArtifactRepository repository;
+
+ public DefaultPluginPrefixResult()
+ {
+ // does nothing
+ }
+
+ public DefaultPluginPrefixResult( Plugin plugin )
+ {
+ groupId = plugin.getGroupId();
+ artifactId = plugin.getArtifactId();
+ }
+
+ public DefaultPluginPrefixResult( String groupId, String artifactId, ArtifactRepository repository )
+ {
+ this.groupId = groupId;
+ this.artifactId = artifactId;
+ this.repository = repository;
+ }
+
+ public String getGroupId()
+ {
+ return groupId;
+ }
+
+ public void setGroupId( String groupId )
+ {
+ this.groupId = groupId;
+ }
+
+ public String getArtifactId()
+ {
+ return artifactId;
+ }
+
+ public void setArtifactId( String artifactId )
+ {
+ this.artifactId = artifactId;
+ }
+
+ public ArtifactRepository getRepository()
+ {
+ return repository;
+ }
+
+ public void setRepository( ArtifactRepository repository )
+ {
+ this.repository = repository;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/version/DefaultPluginVersionRequest.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/version/DefaultPluginVersionRequest.java
new file mode 100644
index 00000000..9907066b
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/version/DefaultPluginVersionRequest.java
@@ -0,0 +1,165 @@
+package org.apache.maven.plugin.version;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.model.Model;
+import org.apache.maven.model.Plugin;
+import org.apache.maven.project.MavenProject;
+import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.repository.RemoteRepository;
+
+/**
+ * Collects settings required to resolve the version for a plugin.
+ *
+ * @since 3.0
+ * @author Benjamin Bentmann
+ */
+public class DefaultPluginVersionRequest
+ implements PluginVersionRequest
+{
+
+ private String groupId;
+
+ private String artifactId;
+
+ private Model pom;
+
+ private List<RemoteRepository> repositories = Collections.emptyList();
+
+ private RepositorySystemSession session;
+
+ /**
+ * Creates an empty request.
+ */
+ public DefaultPluginVersionRequest()
+ {
+ }
+
+ /**
+ * Creates a request for the specified plugin by copying settings from the specified build session. If the session
+ * has a current project, its plugin repositories will be used as well.
+ *
+ * @param plugin The plugin for which to resolve a version, must not be {@code null}.
+ * @param session The Maven session to use, must not be {@code null}.
+ */
+ public DefaultPluginVersionRequest( Plugin plugin, MavenSession session )
+ {
+ setGroupId( plugin.getGroupId() );
+ setArtifactId( plugin.getArtifactId() );
+
+ setRepositorySession( session.getRepositorySession() );
+
+ MavenProject project = session.getCurrentProject();
+ if ( project != null )
+ {
+ setRepositories( project.getRemotePluginRepositories() );
+ }
+ }
+
+ /**
+ * Creates a request for the specified plugin using the given repository session and plugin repositories.
+ *
+ * @param plugin The plugin for which to resolve a version, must not be {@code null}.
+ * @param session The repository session to use, must not be {@code null}.
+ * @param repositories The plugin repositories to query, may be {@code null}.
+ */
+ public DefaultPluginVersionRequest( Plugin plugin, RepositorySystemSession session,
+ List<RemoteRepository> repositories )
+ {
+ setGroupId( plugin.getGroupId() );
+ setArtifactId( plugin.getArtifactId() );
+
+ setRepositorySession( session );
+
+ setRepositories( repositories );
+ }
+
+ public String getGroupId()
+ {
+ return groupId;
+ }
+
+ public DefaultPluginVersionRequest setGroupId( String groupId )
+ {
+ this.groupId = groupId;
+
+ return this;
+ }
+
+ public String getArtifactId()
+ {
+ return artifactId;
+ }
+
+ public DefaultPluginVersionRequest setArtifactId( String artifactId )
+ {
+ this.artifactId = artifactId;
+
+ return this;
+ }
+
+ public Model getPom()
+ {
+ return pom;
+ }
+
+ public DefaultPluginVersionRequest setPom( Model pom )
+ {
+ this.pom = pom;
+
+ return this;
+ }
+
+ public List<RemoteRepository> getRepositories()
+ {
+ return repositories;
+ }
+
+ public DefaultPluginVersionRequest setRepositories( List<RemoteRepository> repositories )
+ {
+ if ( repositories != null )
+ {
+ this.repositories = repositories;
+ }
+ else
+ {
+ this.repositories = Collections.emptyList();
+ }
+
+ return this;
+ }
+
+ public RepositorySystemSession getRepositorySession()
+ {
+ return session;
+ }
+
+ public DefaultPluginVersionRequest setRepositorySession( RepositorySystemSession session )
+ {
+ this.session = session;
+
+ return this;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/version/PluginVersionNotFoundException.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/version/PluginVersionNotFoundException.java
new file mode 100644
index 00000000..b5539be0
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/version/PluginVersionNotFoundException.java
@@ -0,0 +1,47 @@
+package org.apache.maven.plugin.version;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+public class PluginVersionNotFoundException
+ extends Exception
+{
+ private final String groupId;
+
+ private final String artifactId;
+
+ public PluginVersionNotFoundException( String groupId, String artifactId )
+ {
+ super( "The plugin \'" + groupId + ":" + artifactId + "\' does not exist or no valid version could be found" );
+
+ this.groupId = groupId;
+ this.artifactId = artifactId;
+ }
+
+ public String getGroupId()
+ {
+ return groupId;
+ }
+
+ public String getArtifactId()
+ {
+ return artifactId;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/version/PluginVersionRequest.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/version/PluginVersionRequest.java
new file mode 100644
index 00000000..b22f9e1d
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/version/PluginVersionRequest.java
@@ -0,0 +1,115 @@
+package org.apache.maven.plugin.version;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.List;
+
+import org.apache.maven.model.Model;
+import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.repository.RemoteRepository;
+
+/**
+ * Collects settings required to resolve the version for a plugin.
+ *
+ * @since 3.0
+ * @author Benjamin Bentmann
+ */
+public interface PluginVersionRequest
+{
+
+ /**
+ * Gets the group id of the plugin.
+ *
+ * @return The group id of the plugin.
+ */
+ String getGroupId();
+
+ /**
+ * Sets the group id of the plugin.
+ *
+ * @param groupId The group id of the plugin.
+ * @return This request, never {@code null}.
+ */
+ PluginVersionRequest setGroupId( String groupId );
+
+ /**
+ * Gets the artifact id of the plugin.
+ *
+ * @return The artifact id of the plugin.
+ */
+ String getArtifactId();
+
+ /**
+ * Sets the artifact id of the plugin.
+ *
+ * @param artifactId The artifact id of the plugin.
+ * @return This request, never {@code null}.
+ */
+ PluginVersionRequest setArtifactId( String artifactId );
+
+ /**
+ * Gets the POM whose build plugins are to be scanned for the version.
+ *
+ * @return The POM whose build plugins are to be scanned for the verion or {@code null} to only search the plugin
+ * repositories.
+ */
+ Model getPom();
+
+ /**
+ * Sets the POM whose build plugins are to be scanned for the version.
+ *
+ * @param pom The POM whose build plugins are to be scanned for the version, may be {@code null} to only search the
+ * plugin repositories.
+ * @return This request, never {@code null}.
+ */
+ PluginVersionRequest setPom( Model pom );
+
+ /**
+ * Gets the remote repositories to use.
+ *
+ * @return The remote repositories to use, never {@code null}.
+ */
+ List<RemoteRepository> getRepositories();
+
+ /**
+ * Sets the remote repositories to use. <em>Note:</em> When creating a request from a project, be sure to use the
+ * plugin repositories and not the regular project repositories.
+ *
+ * @param repositories The remote repositories to use.
+ * @return This request, never {@code null}.
+ */
+ PluginVersionRequest setRepositories( List<RemoteRepository> repositories );
+
+ /**
+ * Gets the session to use for repository access.
+ *
+ * @return The repository session or {@code null} if not set.
+ */
+ RepositorySystemSession getRepositorySession();
+
+ /**
+ * Sets the session to use for repository access.
+ *
+ * @param repositorySession The repository session to use.
+ * @return This request, never {@code null}.
+ */
+ PluginVersionRequest setRepositorySession( RepositorySystemSession repositorySession );
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/version/PluginVersionResolutionException.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/version/PluginVersionResolutionException.java
new file mode 100644
index 00000000..84ec0967
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/version/PluginVersionResolutionException.java
@@ -0,0 +1,107 @@
+package org.apache.maven.plugin.version;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.List;
+
+import org.eclipse.aether.repository.LocalRepository;
+import org.eclipse.aether.repository.RemoteRepository;
+
+public class PluginVersionResolutionException
+ extends Exception
+{
+ private final String groupId;
+
+ private final String artifactId;
+
+ private final String baseMessage;
+
+ public PluginVersionResolutionException( String groupId, String artifactId, String baseMessage, Throwable cause )
+ {
+ super( "Error resolving version for plugin \'" + groupId + ":" + artifactId + "\': " + baseMessage, cause );
+
+ this.groupId = groupId;
+ this.artifactId = artifactId;
+ this.baseMessage = baseMessage;
+ }
+
+ public PluginVersionResolutionException( String groupId, String artifactId, String baseMessage )
+ {
+ super( "Error resolving version for plugin \'" + groupId + ":" + artifactId + "\': " + baseMessage );
+
+ this.groupId = groupId;
+ this.artifactId = artifactId;
+ this.baseMessage = baseMessage;
+ }
+
+ public PluginVersionResolutionException( String groupId, String artifactId, LocalRepository localRepository,
+ List<RemoteRepository> remoteRepositories, String baseMessage )
+ {
+ super( "Error resolving version for plugin \'" + groupId + ":" + artifactId + "\' from the repositories "
+ + format( localRepository, remoteRepositories ) + ": " + baseMessage );
+
+ this.groupId = groupId;
+ this.artifactId = artifactId;
+ this.baseMessage = baseMessage;
+ }
+
+ public String getGroupId()
+ {
+ return groupId;
+ }
+
+ public String getArtifactId()
+ {
+ return artifactId;
+ }
+
+ public String getBaseMessage()
+ {
+ return baseMessage;
+ }
+
+ private static String format( LocalRepository localRepository, List<RemoteRepository> remoteRepositories )
+ {
+ String repos = "[";
+
+ if ( localRepository != null )
+ {
+ repos += localRepository.getId() + " (" + localRepository.getBasedir() + ")";
+ }
+
+ if ( remoteRepositories != null && !remoteRepositories.isEmpty() )
+ {
+ for ( RemoteRepository repository : remoteRepositories )
+ {
+ repos += ", ";
+
+ if ( repository != null )
+ {
+ repos += repository.getId() + " (" + repository.getUrl() + ")";
+ }
+ }
+ }
+
+ repos += "]";
+
+ return repos;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/version/PluginVersionResolver.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/version/PluginVersionResolver.java
new file mode 100644
index 00000000..935fdfc5
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/version/PluginVersionResolver.java
@@ -0,0 +1,42 @@
+package org.apache.maven.plugin.version;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Resolves a version for a plugin.
+ *
+ * @since 3.0
+ * @author Benjamin Bentmann
+ */
+public interface PluginVersionResolver
+{
+
+ /**
+ * Resolves the version for the specified request.
+ *
+ * @param request The request that holds the details about the plugin and the repositories to consult, must not be
+ * {@code null}.
+ * @return The result of the version resolution, never {@code null}.
+ * @throws PluginVersionResolutionException If the plugin version could not be resolved.
+ */
+ PluginVersionResult resolve( PluginVersionRequest request )
+ throws PluginVersionResolutionException;
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/version/PluginVersionResult.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/version/PluginVersionResult.java
new file mode 100644
index 00000000..09a69e96
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/version/PluginVersionResult.java
@@ -0,0 +1,47 @@
+package org.apache.maven.plugin.version;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.eclipse.aether.repository.ArtifactRepository;
+
+/**
+ * Describes the result of a plugin version resolution request.
+ *
+ * @since 3.0
+ * @author Benjamin Bentmann
+ */
+public interface PluginVersionResult
+{
+
+ /**
+ * The resolved plugin version.
+ *
+ * @return The resolved plugin version, never {@code null}.
+ */
+ String getVersion();
+
+ /**
+ * The repository from which the plugin version was resolved.
+ *
+ * @return The repository from which the plugin version was resolved, never {@code null}.
+ */
+ ArtifactRepository getRepository();
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/version/internal/DefaultPluginVersionResolver.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/version/internal/DefaultPluginVersionResolver.java
new file mode 100644
index 00000000..76b6bfd6
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/version/internal/DefaultPluginVersionResolver.java
@@ -0,0 +1,408 @@
+package org.apache.maven.plugin.version.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeSet;
+
+import org.apache.maven.artifact.repository.metadata.Metadata;
+import org.apache.maven.artifact.repository.metadata.Versioning;
+import org.apache.maven.artifact.repository.metadata.io.MetadataReader;
+import org.apache.maven.model.Build;
+import org.apache.maven.model.Plugin;
+import org.apache.maven.plugin.MavenPluginManager;
+import org.apache.maven.plugin.PluginResolutionException;
+import org.apache.maven.plugin.descriptor.PluginDescriptor;
+import org.apache.maven.plugin.version.PluginVersionRequest;
+import org.apache.maven.plugin.version.PluginVersionResolutionException;
+import org.apache.maven.plugin.version.PluginVersionResolver;
+import org.apache.maven.plugin.version.PluginVersionResult;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+import org.codehaus.plexus.logging.Logger;
+import org.codehaus.plexus.util.StringUtils;
+import org.eclipse.aether.RepositoryEvent.EventType;
+import org.eclipse.aether.RepositoryEvent;
+import org.eclipse.aether.RepositoryListener;
+import org.eclipse.aether.RepositorySystem;
+import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.RequestTrace;
+import org.eclipse.aether.metadata.DefaultMetadata;
+import org.eclipse.aether.repository.ArtifactRepository;
+import org.eclipse.aether.repository.RemoteRepository;
+import org.eclipse.aether.resolution.MetadataRequest;
+import org.eclipse.aether.resolution.MetadataResult;
+import org.eclipse.aether.util.version.GenericVersionScheme;
+import org.eclipse.aether.version.InvalidVersionSpecificationException;
+import org.eclipse.aether.version.Version;
+import org.eclipse.aether.version.VersionScheme;
+
+/**
+ * Resolves a version for a plugin.
+ *
+ * @since 3.0
+ * @author Benjamin Bentmann
+ */
+@Component( role = PluginVersionResolver.class )
+public class DefaultPluginVersionResolver
+ implements PluginVersionResolver
+{
+
+ private static final String REPOSITORY_CONTEXT = "plugin";
+
+ @Requirement
+ private Logger logger;
+
+ @Requirement
+ private RepositorySystem repositorySystem;
+
+ @Requirement
+ private MetadataReader metadataReader;
+
+ @Requirement
+ private MavenPluginManager pluginManager;
+
+ public PluginVersionResult resolve( PluginVersionRequest request )
+ throws PluginVersionResolutionException
+ {
+ logger.debug( "Resolving plugin version for " + request.getGroupId() + ":" + request.getArtifactId() );
+
+ PluginVersionResult result = resolveFromProject( request );
+
+ if ( result == null )
+ {
+ result = resolveFromRepository( request );
+
+ if ( logger.isDebugEnabled() )
+ {
+ logger.debug( "Resolved plugin version for " + request.getGroupId() + ":" + request.getArtifactId()
+ + " to " + result.getVersion() + " from repository " + result.getRepository() );
+ }
+ }
+ else if ( logger.isDebugEnabled() )
+ {
+ logger.debug( "Resolved plugin version for " + request.getGroupId() + ":" + request.getArtifactId()
+ + " to " + result.getVersion() + " from POM " + request.getPom() );
+ }
+
+ return result;
+ }
+
+ private PluginVersionResult resolveFromRepository( PluginVersionRequest request )
+ throws PluginVersionResolutionException
+ {
+ RequestTrace trace = RequestTrace.newChild( null, request );
+
+ DefaultPluginVersionResult result = new DefaultPluginVersionResult();
+
+ org.eclipse.aether.metadata.Metadata metadata =
+ new DefaultMetadata( request.getGroupId(), request.getArtifactId(), "maven-metadata.xml",
+ DefaultMetadata.Nature.RELEASE_OR_SNAPSHOT );
+
+ List<MetadataRequest> requests = new ArrayList<MetadataRequest>();
+
+ requests.add( new MetadataRequest( metadata, null, REPOSITORY_CONTEXT ).setTrace( trace ) );
+
+ for ( RemoteRepository repository : request.getRepositories() )
+ {
+ requests.add( new MetadataRequest( metadata, repository, REPOSITORY_CONTEXT ).setTrace( trace ) );
+ }
+
+ List<MetadataResult> results = repositorySystem.resolveMetadata( request.getRepositorySession(), requests );
+
+ Versions versions = new Versions();
+
+ for ( MetadataResult res : results )
+ {
+ ArtifactRepository repository = res.getRequest().getRepository();
+ if ( repository == null )
+ {
+ repository = request.getRepositorySession().getLocalRepository();
+ }
+
+ mergeMetadata( request.getRepositorySession(), trace, versions, res.getMetadata(), repository );
+ }
+
+ selectVersion( result, request, versions );
+
+ return result;
+ }
+
+ private void selectVersion( DefaultPluginVersionResult result, PluginVersionRequest request, Versions versions )
+ throws PluginVersionResolutionException
+ {
+ String version = null;
+ ArtifactRepository repo = null;
+
+ if ( StringUtils.isNotEmpty( versions.releaseVersion ) )
+ {
+ version = versions.releaseVersion;
+ repo = versions.releaseRepository;
+ }
+ else if ( StringUtils.isNotEmpty( versions.latestVersion ) )
+ {
+ version = versions.latestVersion;
+ repo = versions.latestRepository;
+ }
+ if ( version != null && !isCompatible( request, version ) )
+ {
+ versions.versions.remove( version );
+ version = null;
+ }
+
+ if ( version == null )
+ {
+ VersionScheme versionScheme = new GenericVersionScheme();
+
+ TreeSet<Version> releases = new TreeSet<Version>( Collections.reverseOrder() );
+ TreeSet<Version> snapshots = new TreeSet<Version>( Collections.reverseOrder() );
+
+ for ( String ver : versions.versions.keySet() )
+ {
+ try
+ {
+ Version v = versionScheme.parseVersion( ver );
+
+ if ( ver.endsWith( "-SNAPSHOT" ) )
+ {
+ snapshots.add( v );
+ }
+ else
+ {
+ releases.add( v );
+ }
+ }
+ catch ( InvalidVersionSpecificationException e )
+ {
+ // ignore
+ }
+ }
+
+ for ( Version v : releases )
+ {
+ String ver = v.toString();
+ if ( isCompatible( request, ver ) )
+ {
+ version = ver;
+ repo = versions.versions.get( version );
+ break;
+ }
+ }
+
+ if ( version == null )
+ {
+ for ( Version v : snapshots )
+ {
+ String ver = v.toString();
+ if ( isCompatible( request, ver ) )
+ {
+ version = ver;
+ repo = versions.versions.get( version );
+ break;
+ }
+ }
+ }
+ }
+
+ if ( version != null )
+ {
+ result.setVersion( version );
+ result.setRepository( repo );
+ }
+ else
+ {
+ throw new PluginVersionResolutionException( request.getGroupId(), request.getArtifactId(),
+ request.getRepositorySession().getLocalRepository(),
+ request.getRepositories(),
+ "Plugin not found in any plugin repository" );
+ }
+ }
+
+ private boolean isCompatible( PluginVersionRequest request, String version )
+ {
+ Plugin plugin = new Plugin();
+ plugin.setGroupId( request.getGroupId() );
+ plugin.setArtifactId( request.getArtifactId() );
+ plugin.setVersion( version );
+
+ PluginDescriptor pluginDescriptor;
+
+ try
+ {
+ pluginDescriptor =
+ pluginManager.getPluginDescriptor( plugin, request.getRepositories(), request.getRepositorySession() );
+ }
+ catch ( PluginResolutionException e )
+ {
+ logger.debug( "Ignoring unresolvable plugin version " + version, e );
+ return false;
+ }
+ catch ( Exception e )
+ {
+ // ignore for now and delay failure to higher level processing
+ return true;
+ }
+
+ try
+ {
+ pluginManager.checkRequiredMavenVersion( pluginDescriptor );
+ }
+ catch ( Exception e )
+ {
+ logger.debug( "Ignoring incompatible plugin version " + version + ": " + e.getMessage() );
+ return false;
+ }
+
+ return true;
+ }
+
+ private void mergeMetadata( RepositorySystemSession session, RequestTrace trace, Versions versions,
+ org.eclipse.aether.metadata.Metadata metadata, ArtifactRepository repository )
+ {
+ if ( metadata != null && metadata.getFile() != null && metadata.getFile().isFile() )
+ {
+ try
+ {
+ Map<String, ?> options = Collections.singletonMap( MetadataReader.IS_STRICT, Boolean.FALSE );
+
+ Metadata repoMetadata = metadataReader.read( metadata.getFile(), options );
+
+ mergeMetadata( versions, repoMetadata, repository );
+ }
+ catch ( IOException e )
+ {
+ invalidMetadata( session, trace, metadata, repository, e );
+ }
+ }
+ }
+
+ private void invalidMetadata( RepositorySystemSession session, RequestTrace trace,
+ org.eclipse.aether.metadata.Metadata metadata, ArtifactRepository repository,
+ Exception exception )
+ {
+ RepositoryListener listener = session.getRepositoryListener();
+ if ( listener != null )
+ {
+ RepositoryEvent.Builder event = new RepositoryEvent.Builder( session, EventType.METADATA_INVALID );
+ event.setTrace( trace );
+ event.setMetadata( metadata );
+ event.setException( exception );
+ event.setRepository( repository );
+ listener.metadataInvalid( event.build() );
+ }
+ }
+
+ private void mergeMetadata( Versions versions, Metadata source, ArtifactRepository repository )
+ {
+ Versioning versioning = source.getVersioning();
+ if ( versioning != null )
+ {
+ String timestamp = StringUtils.clean( versioning.getLastUpdated() );
+
+ if ( StringUtils.isNotEmpty( versioning.getRelease() )
+ && timestamp.compareTo( versions.releaseTimestamp ) > 0 )
+ {
+ versions.releaseVersion = versioning.getRelease();
+ versions.releaseTimestamp = timestamp;
+ versions.releaseRepository = repository;
+ }
+
+ if ( StringUtils.isNotEmpty( versioning.getLatest() )
+ && timestamp.compareTo( versions.latestTimestamp ) > 0 )
+ {
+ versions.latestVersion = versioning.getLatest();
+ versions.latestTimestamp = timestamp;
+ versions.latestRepository = repository;
+ }
+
+ for ( String version : versioning.getVersions() )
+ {
+ if ( !versions.versions.containsKey( version ) )
+ {
+ versions.versions.put( version, repository );
+ }
+ }
+ }
+ }
+
+ private PluginVersionResult resolveFromProject( PluginVersionRequest request )
+ {
+ PluginVersionResult result = null;
+
+ if ( request.getPom() != null && request.getPom().getBuild() != null )
+ {
+ Build build = request.getPom().getBuild();
+
+ result = resolveFromProject( request, build.getPlugins() );
+
+ if ( result == null && build.getPluginManagement() != null )
+ {
+ result = resolveFromProject( request, build.getPluginManagement().getPlugins() );
+ }
+ }
+
+ return result;
+ }
+
+ private PluginVersionResult resolveFromProject( PluginVersionRequest request, List<Plugin> plugins )
+ {
+ for ( Plugin plugin : plugins )
+ {
+ if ( request.getGroupId().equals( plugin.getGroupId() )
+ && request.getArtifactId().equals( plugin.getArtifactId() ) )
+ {
+ if ( plugin.getVersion() != null )
+ {
+ return new DefaultPluginVersionResult( plugin.getVersion() );
+ }
+ else
+ {
+ return null;
+ }
+ }
+ }
+ return null;
+ }
+
+ static class Versions
+ {
+
+ String releaseVersion = "";
+
+ String releaseTimestamp = "";
+
+ ArtifactRepository releaseRepository;
+
+ String latestVersion = "";
+
+ String latestTimestamp = "";
+
+ ArtifactRepository latestRepository;
+
+ Map<String, ArtifactRepository> versions = new LinkedHashMap<String, ArtifactRepository>();
+
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/version/internal/DefaultPluginVersionResult.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/version/internal/DefaultPluginVersionResult.java
new file mode 100644
index 00000000..9027a532
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/plugin/version/internal/DefaultPluginVersionResult.java
@@ -0,0 +1,69 @@
+package org.apache.maven.plugin.version.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.plugin.version.PluginVersionResult;
+import org.eclipse.aether.repository.ArtifactRepository;
+
+/**
+ * Describes the result of a plugin version resolution request.
+ *
+ * @since 3.0
+ * @author Benjamin Bentmann
+ */
+class DefaultPluginVersionResult
+ implements PluginVersionResult
+{
+
+ private String version;
+
+ private ArtifactRepository repository;
+
+ public DefaultPluginVersionResult()
+ {
+ // does nothing
+ }
+
+ public DefaultPluginVersionResult( String version )
+ {
+ this.version = version;
+ }
+
+ public String getVersion()
+ {
+ return version;
+ }
+
+ public void setVersion( String version )
+ {
+ this.version = version;
+ }
+
+ public ArtifactRepository getRepository()
+ {
+ return repository;
+ }
+
+ public void setRepository( ArtifactRepository repository )
+ {
+ this.repository = repository;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/DefaultDependencyResolutionRequest.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/DefaultDependencyResolutionRequest.java
new file mode 100644
index 00000000..cf5b0d70
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/DefaultDependencyResolutionRequest.java
@@ -0,0 +1,82 @@
+package org.apache.maven.project;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.graph.DependencyFilter;
+
+/**
+ * @author Benjamin Bentmann
+ */
+public class DefaultDependencyResolutionRequest
+ implements DependencyResolutionRequest
+{
+
+ private MavenProject project;
+
+ private DependencyFilter filter;
+
+ private RepositorySystemSession session;
+
+ public DefaultDependencyResolutionRequest()
+ {
+ // enables default constructor
+ }
+
+ public DefaultDependencyResolutionRequest( MavenProject project, RepositorySystemSession session )
+ {
+ setMavenProject( project );
+ setRepositorySession( session );
+ }
+
+ public DependencyFilter getResolutionFilter()
+ {
+ return filter;
+ }
+
+ public MavenProject getMavenProject()
+ {
+ return project;
+ }
+
+ public RepositorySystemSession getRepositorySession()
+ {
+ return session;
+ }
+
+ public DependencyResolutionRequest setResolutionFilter( DependencyFilter filter )
+ {
+ this.filter = filter;
+ return this;
+ }
+
+ public DependencyResolutionRequest setMavenProject( MavenProject project )
+ {
+ this.project = project;
+ return this;
+ }
+
+ public DependencyResolutionRequest setRepositorySession( RepositorySystemSession repositorySession )
+ {
+ this.session = repositorySession;
+ return this;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/DefaultDependencyResolutionResult.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/DefaultDependencyResolutionResult.java
new file mode 100644
index 00000000..07c6a2f9
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/DefaultDependencyResolutionResult.java
@@ -0,0 +1,111 @@
+package org.apache.maven.project;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.IdentityHashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.aether.graph.Dependency;
+import org.eclipse.aether.graph.DependencyNode;
+
+/**
+ * @author Benjamin Bentmann
+ */
+class DefaultDependencyResolutionResult
+ implements DependencyResolutionResult
+{
+
+ private DependencyNode root;
+
+ private List<Dependency> dependencies = new ArrayList<Dependency>();
+
+ private List<Dependency> resolvedDependencies = new ArrayList<Dependency>();
+
+ private List<Dependency> unresolvedDependencies = new ArrayList<Dependency>();
+
+ private List<Exception> collectionErrors = new ArrayList<Exception>();
+
+ private Map<Dependency, List<Exception>> resolutionErrors = new IdentityHashMap<Dependency, List<Exception>>();
+
+ public DependencyNode getDependencyGraph()
+ {
+ return root;
+ }
+
+ public void setDependencyGraph( DependencyNode root )
+ {
+ this.root = root;
+ }
+
+ public List<Dependency> getDependencies()
+ {
+ return dependencies;
+ }
+
+ public List<Dependency> getResolvedDependencies()
+ {
+ return resolvedDependencies;
+ }
+
+ public void addResolvedDependency( Dependency dependency )
+ {
+ dependencies.add( dependency );
+ resolvedDependencies.add( dependency );
+ }
+
+ public List<Dependency> getUnresolvedDependencies()
+ {
+ return unresolvedDependencies;
+ }
+
+ public List<Exception> getCollectionErrors()
+ {
+ return collectionErrors;
+ }
+
+ public void setCollectionErrors( List<Exception> exceptions )
+ {
+ if ( exceptions != null )
+ {
+ this.collectionErrors = exceptions;
+ }
+ else
+ {
+ this.collectionErrors = new ArrayList<Exception>();
+ }
+ }
+
+ public List<Exception> getResolutionErrors( Dependency dependency )
+ {
+ List<Exception> errors = resolutionErrors.get( dependency );
+ return ( errors != null ) ? errors : Collections.<Exception>emptyList();
+ }
+
+ public void setResolutionErrors( Dependency dependency, List<Exception> errors )
+ {
+ dependencies.add( dependency );
+ unresolvedDependencies.add( dependency );
+ resolutionErrors.put( dependency, errors );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/DefaultMavenProjectHelper.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/DefaultMavenProjectHelper.java
new file mode 100644
index 00000000..2cce9f6a
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/DefaultMavenProjectHelper.java
@@ -0,0 +1,128 @@
+package org.apache.maven.project;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.util.List;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.handler.ArtifactHandler;
+import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager;
+import org.apache.maven.model.Resource;
+import org.apache.maven.project.artifact.AttachedArtifact;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+import org.codehaus.plexus.logging.AbstractLogEnabled;
+
+@SuppressWarnings( "deprecation" )
+@Component( role = MavenProjectHelper.class )
+public class DefaultMavenProjectHelper
+ extends AbstractLogEnabled
+ implements MavenProjectHelper
+{
+ @Requirement
+ private ArtifactHandlerManager artifactHandlerManager;
+
+ public void attachArtifact( MavenProject project, String artifactType, String artifactClassifier,
+ File artifactFile )
+ {
+ String type = artifactType;
+
+ ArtifactHandler handler = null;
+
+ if ( type != null )
+ {
+ handler = artifactHandlerManager.getArtifactHandler( artifactType );
+ }
+
+ if ( handler == null )
+ {
+ handler = artifactHandlerManager.getArtifactHandler( "jar" );
+ }
+
+ Artifact artifact = new AttachedArtifact( project.getArtifact(), artifactType, artifactClassifier, handler );
+
+ artifact.setFile( artifactFile );
+ artifact.setResolved( true );
+
+ attachArtifact( project, artifact );
+ }
+
+ public void attachArtifact( MavenProject project, String artifactType, File artifactFile )
+ {
+ ArtifactHandler handler = artifactHandlerManager.getArtifactHandler( artifactType );
+
+ Artifact artifact = new AttachedArtifact( project.getArtifact(), artifactType, handler );
+
+ artifact.setFile( artifactFile );
+ artifact.setResolved( true );
+
+ attachArtifact( project, artifact );
+ }
+
+ public void attachArtifact( MavenProject project, File artifactFile, String artifactClassifier )
+ {
+ Artifact projectArtifact = project.getArtifact();
+
+ Artifact artifact =
+ new AttachedArtifact( projectArtifact, projectArtifact.getType(), artifactClassifier,
+ projectArtifact.getArtifactHandler() );
+
+ artifact.setFile( artifactFile );
+ artifact.setResolved( true );
+
+ attachArtifact( project, artifact );
+ }
+
+ /**
+ * Add an attached artifact or replace the file for an existing artifact.
+ *
+ * @see MavenProject#addAttachedArtifact(org.apache.maven.artifact.Artifact)
+ * @param project project reference.
+ * @param artifact artifact to add or replace.
+ */
+ public void attachArtifact( MavenProject project, Artifact artifact )
+ {
+ project.addAttachedArtifact( artifact );
+ }
+
+ public void addResource( MavenProject project, String resourceDirectory, List<String> includes,
+ List<String> excludes )
+ {
+ Resource resource = new Resource();
+ resource.setDirectory( resourceDirectory );
+ resource.setIncludes( includes );
+ resource.setExcludes( excludes );
+
+ project.addResource( resource );
+ }
+
+ public void addTestResource( MavenProject project, String resourceDirectory, List<String> includes,
+ List<String> excludes )
+ {
+ Resource resource = new Resource();
+ resource.setDirectory( resourceDirectory );
+ resource.setIncludes( includes );
+ resource.setExcludes( excludes );
+
+ project.addTestResource( resource );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/DefaultModelBuildingListener.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/DefaultModelBuildingListener.java
new file mode 100644
index 00000000..a5365621
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/DefaultModelBuildingListener.java
@@ -0,0 +1,155 @@
+package org.apache.maven.project;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.List;
+
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.model.Model;
+import org.apache.maven.model.building.AbstractModelBuildingListener;
+import org.apache.maven.model.building.ModelBuildingEvent;
+import org.apache.maven.model.building.ModelProblem.Severity;
+import org.apache.maven.model.building.ModelProblem.Version;
+import org.apache.maven.model.building.ModelProblemCollectorRequest;
+import org.apache.maven.plugin.PluginManagerException;
+import org.apache.maven.plugin.PluginResolutionException;
+import org.apache.maven.plugin.version.PluginVersionResolutionException;
+
+/**
+ * Processes events from the model builder while building the effective model for a {@link MavenProject} instance.
+ *
+ * @author Benjamin Bentmann
+ */
+public class DefaultModelBuildingListener
+ extends AbstractModelBuildingListener
+{
+
+ private MavenProject project;
+
+ private ProjectBuildingHelper projectBuildingHelper;
+
+ private ProjectBuildingRequest projectBuildingRequest;
+
+ private List<ArtifactRepository> remoteRepositories;
+
+ private List<ArtifactRepository> pluginRepositories;
+
+ public DefaultModelBuildingListener( MavenProject project, ProjectBuildingHelper projectBuildingHelper,
+ ProjectBuildingRequest projectBuildingRequest )
+ {
+ if ( project == null )
+ {
+ throw new IllegalArgumentException( "project missing" );
+ }
+ this.project = project;
+
+ if ( projectBuildingHelper == null )
+ {
+ throw new IllegalArgumentException( "project building helper missing" );
+ }
+ this.projectBuildingHelper = projectBuildingHelper;
+
+ if ( projectBuildingRequest == null )
+ {
+ throw new IllegalArgumentException( "project building request missing" );
+ }
+ this.projectBuildingRequest = projectBuildingRequest;
+ this.remoteRepositories = projectBuildingRequest.getRemoteRepositories();
+ this.pluginRepositories = projectBuildingRequest.getPluginArtifactRepositories();
+ }
+
+ /**
+ * Gets the project whose model is being built.
+ *
+ * @return The project, never {@code null}.
+ */
+ public MavenProject getProject()
+ {
+ return project;
+ }
+
+ @Override
+ public void buildExtensionsAssembled( ModelBuildingEvent event )
+ {
+ Model model = event.getModel();
+
+ try
+ {
+ pluginRepositories =
+ projectBuildingHelper.createArtifactRepositories( model.getPluginRepositories(), pluginRepositories,
+ projectBuildingRequest );
+ }
+ catch ( Exception e )
+ {
+ event.getProblems().add( new ModelProblemCollectorRequest( Severity.ERROR, Version.BASE )
+ .setMessage( "Invalid plugin repository: " + e.getMessage() )
+ .setException( e ) );
+ }
+ project.setPluginArtifactRepositories( pluginRepositories );
+
+ if ( event.getRequest().isProcessPlugins() )
+ {
+ try
+ {
+ ProjectRealmCache.CacheRecord record =
+ projectBuildingHelper.createProjectRealm( project, model, projectBuildingRequest );
+
+ project.setClassRealm( record.realm );
+ project.setExtensionDependencyFilter( record.extensionArtifactFilter );
+ }
+ catch ( PluginResolutionException e )
+ {
+ event.getProblems().add( new ModelProblemCollectorRequest( Severity.ERROR, Version.BASE )
+ .setMessage( "Unresolveable build extension: " + e.getMessage() )
+ .setException( e ) );
+ }
+ catch ( PluginVersionResolutionException e )
+ {
+ event.getProblems().add( new ModelProblemCollectorRequest( Severity.ERROR, Version.BASE )
+ .setMessage( "Unresolveable build extension: " + e.getMessage() )
+ .setException( e ) );
+ }
+ catch ( PluginManagerException e )
+ {
+ event.getProblems().add( new ModelProblemCollectorRequest( Severity.ERROR, Version.BASE )
+ .setMessage( "Unresolveable build extension: " + e.getMessage() )
+ .setException( e ) );
+ }
+
+ projectBuildingHelper.selectProjectRealm( project );
+ }
+
+ // build the regular repos after extensions are loaded to allow for custom layouts
+ try
+ {
+ remoteRepositories =
+ projectBuildingHelper.createArtifactRepositories( model.getRepositories(), remoteRepositories,
+ projectBuildingRequest );
+ }
+ catch ( Exception e )
+ {
+ event.getProblems().add( new ModelProblemCollectorRequest( Severity.ERROR, Version.BASE )
+ .setMessage( "Invalid artifact repository: " + e.getMessage() )
+ .setException( e ) );
+ }
+ project.setRemoteArtifactRepositories( remoteRepositories );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuilder.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuilder.java
new file mode 100644
index 00000000..99edc802
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuilder.java
@@ -0,0 +1,929 @@
+package org.apache.maven.project;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.maven.RepositoryUtils;
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.InvalidRepositoryException;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.repository.LegacyLocalRepositoryManager;
+import org.apache.maven.bridge.MavenRepositorySystem;
+import org.apache.maven.model.Build;
+import org.apache.maven.model.Dependency;
+import org.apache.maven.model.DependencyManagement;
+import org.apache.maven.model.DeploymentRepository;
+import org.apache.maven.model.Extension;
+import org.apache.maven.model.Model;
+import org.apache.maven.model.Parent;
+import org.apache.maven.model.Plugin;
+import org.apache.maven.model.Profile;
+import org.apache.maven.model.ReportPlugin;
+import org.apache.maven.model.building.DefaultModelBuildingRequest;
+import org.apache.maven.model.building.DefaultModelProblem;
+import org.apache.maven.model.building.FileModelSource;
+import org.apache.maven.model.building.ModelBuilder;
+import org.apache.maven.model.building.ModelBuildingException;
+import org.apache.maven.model.building.ModelBuildingRequest;
+import org.apache.maven.model.building.ModelBuildingResult;
+import org.apache.maven.model.building.ModelProblem;
+import org.apache.maven.model.building.ModelProcessor;
+import org.apache.maven.model.building.ModelSource;
+import org.apache.maven.model.building.StringModelSource;
+import org.apache.maven.model.resolution.ModelResolver;
+import org.apache.maven.repository.internal.ArtifactDescriptorUtils;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+import org.codehaus.plexus.logging.Logger;
+import org.codehaus.plexus.util.Os;
+import org.codehaus.plexus.util.StringUtils;
+import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.RequestTrace;
+import org.eclipse.aether.impl.RemoteRepositoryManager;
+import org.eclipse.aether.repository.LocalRepositoryManager;
+import org.eclipse.aether.repository.RemoteRepository;
+import org.eclipse.aether.repository.WorkspaceRepository;
+import org.eclipse.aether.resolution.ArtifactRequest;
+import org.eclipse.aether.resolution.ArtifactResult;
+import org.eclipse.aether.resolution.VersionRangeRequest;
+import org.eclipse.aether.resolution.VersionRangeResolutionException;
+import org.eclipse.aether.resolution.VersionRangeResult;
+
+/**
+ */
+@Component( role = ProjectBuilder.class )
+public class DefaultProjectBuilder
+ implements ProjectBuilder
+{
+
+ @Requirement
+ private Logger logger;
+
+ @Requirement
+ private ModelBuilder modelBuilder;
+
+ @Requirement
+ private ModelProcessor modelProcessor;
+
+ @Requirement
+ private ProjectBuildingHelper projectBuildingHelper;
+
+ @Requirement
+ private MavenRepositorySystem repositorySystem;
+
+ @Requirement
+ private org.eclipse.aether.RepositorySystem repoSystem;
+
+ @Requirement
+ private RemoteRepositoryManager repositoryManager;
+
+ @Requirement
+ private ProjectDependenciesResolver dependencyResolver;
+
+ // ----------------------------------------------------------------------
+ // MavenProjectBuilder Implementation
+ // ----------------------------------------------------------------------
+
+ @Override
+ public ProjectBuildingResult build( File pomFile, ProjectBuildingRequest request )
+ throws ProjectBuildingException
+ {
+ return build( pomFile, new FileModelSource( pomFile ), new InternalConfig( request, null ) );
+ }
+
+ @Override
+ public ProjectBuildingResult build( ModelSource modelSource, ProjectBuildingRequest request )
+ throws ProjectBuildingException
+ {
+ return build( null, modelSource, new InternalConfig( request, null ) );
+ }
+
+ private ProjectBuildingResult build( File pomFile, ModelSource modelSource, InternalConfig config )
+ throws ProjectBuildingException
+ {
+ ClassLoader oldContextClassLoader = Thread.currentThread().getContextClassLoader();
+
+ try
+ {
+ ProjectBuildingRequest projectBuildingRequest = config.request;
+
+ MavenProject project = projectBuildingRequest.getProject();
+
+ List<ModelProblem> modelProblems = null;
+ Throwable error = null;
+
+ if ( project == null )
+ {
+ ModelBuildingRequest request = getModelBuildingRequest( config );
+
+ project = new MavenProject();
+ project.setFile( pomFile );
+
+ DefaultModelBuildingListener listener =
+ new DefaultModelBuildingListener( project, projectBuildingHelper, projectBuildingRequest );
+ request.setModelBuildingListener( listener );
+
+ request.setPomFile( pomFile );
+ request.setModelSource( modelSource );
+ request.setLocationTracking( true );
+
+ ModelBuildingResult result;
+ try
+ {
+ result = modelBuilder.build( request );
+ }
+ catch ( ModelBuildingException e )
+ {
+ result = e.getResult();
+ if ( result == null || result.getEffectiveModel() == null )
+ {
+ throw new ProjectBuildingException( e.getModelId(), e.getMessage(), pomFile, e );
+ }
+ // validation error, continue project building and delay failing to help IDEs
+ error = e;
+ }
+
+ modelProblems = result.getProblems();
+
+ initProject( project, Collections.<String, MavenProject>emptyMap(), result,
+ new HashMap<File, Boolean>(), projectBuildingRequest );
+ }
+ else if ( projectBuildingRequest.isResolveDependencies() )
+ {
+ projectBuildingHelper.selectProjectRealm( project );
+ }
+
+ DependencyResolutionResult resolutionResult = null;
+
+ if ( projectBuildingRequest.isResolveDependencies() )
+ {
+ resolutionResult = resolveDependencies( project, config.session );
+ }
+
+ ProjectBuildingResult result = new DefaultProjectBuildingResult( project, modelProblems, resolutionResult );
+
+ if ( error != null )
+ {
+ ProjectBuildingException e = new ProjectBuildingException( Arrays.asList( result ) );
+ e.initCause( error );
+ throw e;
+ }
+
+ return result;
+ }
+ finally
+ {
+ Thread.currentThread().setContextClassLoader( oldContextClassLoader );
+ }
+ }
+
+ private DependencyResolutionResult resolveDependencies( MavenProject project, RepositorySystemSession session )
+ {
+ DependencyResolutionResult resolutionResult;
+
+ try
+ {
+ DefaultDependencyResolutionRequest resolution = new DefaultDependencyResolutionRequest( project, session );
+ resolutionResult = dependencyResolver.resolve( resolution );
+ }
+ catch ( DependencyResolutionException e )
+ {
+ resolutionResult = e.getResult();
+ }
+
+ Set<Artifact> artifacts = new LinkedHashSet<Artifact>();
+ if ( resolutionResult.getDependencyGraph() != null )
+ {
+ RepositoryUtils.toArtifacts( artifacts, resolutionResult.getDependencyGraph().getChildren(),
+ Collections.singletonList( project.getArtifact().getId() ), null );
+
+ // Maven 2.x quirk: an artifact always points at the local repo, regardless whether resolved or not
+ LocalRepositoryManager lrm = session.getLocalRepositoryManager();
+ for ( Artifact artifact : artifacts )
+ {
+ if ( !artifact.isResolved() )
+ {
+ String path = lrm.getPathForLocalArtifact( RepositoryUtils.toArtifact( artifact ) );
+ artifact.setFile( new File( lrm.getRepository().getBasedir(), path ) );
+ }
+ }
+ }
+ project.setResolvedArtifacts( artifacts );
+ project.setArtifacts( artifacts );
+
+ return resolutionResult;
+ }
+
+ private List<String> getProfileIds( List<Profile> profiles )
+ {
+ List<String> ids = new ArrayList<String>( profiles.size() );
+
+ for ( Profile profile : profiles )
+ {
+ ids.add( profile.getId() );
+ }
+
+ return ids;
+ }
+
+ private ModelBuildingRequest getModelBuildingRequest( InternalConfig config )
+ {
+ ProjectBuildingRequest configuration = config.request;
+
+ ModelBuildingRequest request = new DefaultModelBuildingRequest();
+
+ RequestTrace trace = RequestTrace.newChild( null, configuration ).newChild( request );
+
+ ModelResolver resolver =
+ new ProjectModelResolver( config.session, trace, repoSystem, repositoryManager, config.repositories,
+ configuration.getRepositoryMerging(), config.modelPool );
+
+ request.setValidationLevel( configuration.getValidationLevel() );
+ request.setProcessPlugins( configuration.isProcessPlugins() );
+ request.setProfiles( configuration.getProfiles() );
+ request.setActiveProfileIds( configuration.getActiveProfileIds() );
+ request.setInactiveProfileIds( configuration.getInactiveProfileIds() );
+ request.setSystemProperties( configuration.getSystemProperties() );
+ request.setUserProperties( configuration.getUserProperties() );
+ request.setBuildStartTime( configuration.getBuildStartTime() );
+ request.setModelResolver( resolver );
+ request.setModelCache( new ReactorModelCache() );
+
+ return request;
+ }
+
+ @Override
+ public ProjectBuildingResult build( Artifact artifact, ProjectBuildingRequest request )
+ throws ProjectBuildingException
+ {
+ return build( artifact, false, request );
+ }
+
+ @Override
+ public ProjectBuildingResult build( Artifact artifact, boolean allowStubModel, ProjectBuildingRequest request )
+ throws ProjectBuildingException
+ {
+ org.eclipse.aether.artifact.Artifact pomArtifact = RepositoryUtils.toArtifact( artifact );
+ pomArtifact = ArtifactDescriptorUtils.toPomArtifact( pomArtifact );
+
+ InternalConfig config = new InternalConfig( request, null );
+
+ boolean localProject;
+
+ if ( request.isResolveVersionRanges() )
+ {
+ VersionRangeRequest versionRangeRequest = new VersionRangeRequest( pomArtifact, config.repositories, null );
+
+ try
+ {
+ VersionRangeResult versionRangeResult =
+ repoSystem.resolveVersionRange( config.session, versionRangeRequest );
+
+ if ( versionRangeResult.getHighestVersion() == null )
+ {
+ throw new ProjectBuildingException(
+ artifact.getId(), "Error resolving project artifact: No versions matched the requested range",
+ (Throwable) null );
+
+ }
+
+ if ( versionRangeResult.getVersionConstraint() != null
+ && versionRangeResult.getVersionConstraint().getRange() != null
+ && versionRangeResult.getVersionConstraint().getRange().getUpperBound() == null )
+ {
+ throw new ProjectBuildingException(
+ artifact.getId(),
+ "Error resolving project artifact: The requested version range does not specify an upper bound",
+ (Throwable) null );
+
+ }
+
+ pomArtifact = pomArtifact.setVersion( versionRangeResult.getHighestVersion().toString() );
+ }
+ catch ( VersionRangeResolutionException e )
+ {
+ throw new ProjectBuildingException(
+ artifact.getId(), "Error resolving project artifact: " + e.getMessage(), e );
+
+ }
+ }
+
+ try
+ {
+ ArtifactRequest pomRequest = new ArtifactRequest();
+ pomRequest.setArtifact( pomArtifact );
+ pomRequest.setRepositories( config.repositories );
+ ArtifactResult pomResult = repoSystem.resolveArtifact( config.session, pomRequest );
+
+ pomArtifact = pomResult.getArtifact();
+ localProject = pomResult.getRepository() instanceof WorkspaceRepository;
+ }
+ catch ( org.eclipse.aether.resolution.ArtifactResolutionException e )
+ {
+ if ( e.getResults().get( 0 ).isMissing() && allowStubModel )
+ {
+ return build( null, createStubModelSource( artifact ), config );
+ }
+ throw new ProjectBuildingException( artifact.getId(),
+ "Error resolving project artifact: " + e.getMessage(), e );
+ }
+
+ File pomFile = pomArtifact.getFile();
+
+ if ( "pom".equals( artifact.getType() ) )
+ {
+ artifact.selectVersion( pomArtifact.getVersion() );
+ artifact.setFile( pomFile );
+ artifact.setResolved( true );
+ }
+
+ return build( localProject ? pomFile : null, new FileModelSource( pomFile ), config );
+ }
+
+ private ModelSource createStubModelSource( Artifact artifact )
+ {
+ StringBuilder buffer = new StringBuilder( 1024 );
+
+ buffer.append( "<?xml version='1.0'?>" );
+ buffer.append( "<project>" );
+ buffer.append( "<modelVersion>4.0.0</modelVersion>" );
+ buffer.append( "<groupId>" ).append( artifact.getGroupId() ).append( "</groupId>" );
+ buffer.append( "<artifactId>" ).append( artifact.getArtifactId() ).append( "</artifactId>" );
+ buffer.append( "<version>" ).append( artifact.getBaseVersion() ).append( "</version>" );
+ buffer.append( "<packaging>" ).append( artifact.getType() ).append( "</packaging>" );
+ buffer.append( "</project>" );
+
+ return new StringModelSource( buffer, artifact.getId() );
+ }
+
+ @Override
+ public List<ProjectBuildingResult> build( List<File> pomFiles, boolean recursive, ProjectBuildingRequest request )
+ throws ProjectBuildingException
+ {
+ List<ProjectBuildingResult> results = new ArrayList<ProjectBuildingResult>();
+
+ List<InterimResult> interimResults = new ArrayList<InterimResult>();
+
+ ReactorModelPool modelPool = new ReactorModelPool();
+
+ InternalConfig config = new InternalConfig( request, modelPool );
+
+ Map<String, MavenProject> projectIndex = new HashMap<String, MavenProject>( 256 );
+
+ boolean noErrors =
+ build( results, interimResults, projectIndex, pomFiles, new LinkedHashSet<File>(), true, recursive,
+ config );
+
+ populateReactorModelPool( modelPool, interimResults );
+
+ ClassLoader oldContextClassLoader = Thread.currentThread().getContextClassLoader();
+
+ try
+ {
+ noErrors =
+ build( results, new ArrayList<MavenProject>(), projectIndex, interimResults, request,
+ new HashMap<File, Boolean>() ) && noErrors;
+ }
+ finally
+ {
+ Thread.currentThread().setContextClassLoader( oldContextClassLoader );
+ }
+
+ if ( !noErrors )
+ {
+ throw new ProjectBuildingException( results );
+ }
+
+ return results;
+ }
+
+ private boolean build( List<ProjectBuildingResult> results, List<InterimResult> interimResults,
+ Map<String, MavenProject> projectIndex, List<File> pomFiles, Set<File> aggregatorFiles,
+ boolean isRoot, boolean recursive, InternalConfig config )
+ {
+ boolean noErrors = true;
+
+ for ( File pomFile : pomFiles )
+ {
+ aggregatorFiles.add( pomFile );
+
+ if ( !build( results, interimResults, projectIndex, pomFile, aggregatorFiles, isRoot, recursive, config ) )
+ {
+ noErrors = false;
+ }
+
+ aggregatorFiles.remove( pomFile );
+ }
+
+ return noErrors;
+ }
+
+ private boolean build( List<ProjectBuildingResult> results, List<InterimResult> interimResults,
+ Map<String, MavenProject> projectIndex, File pomFile, Set<File> aggregatorFiles,
+ boolean isRoot, boolean recursive, InternalConfig config )
+ {
+ boolean noErrors = true;
+
+ ModelBuildingRequest request = getModelBuildingRequest( config );
+
+ MavenProject project = new MavenProject();
+
+ request.setPomFile( pomFile );
+ request.setTwoPhaseBuilding( true );
+ request.setLocationTracking( true );
+
+ DefaultModelBuildingListener listener =
+ new DefaultModelBuildingListener( project, projectBuildingHelper, config.request );
+ request.setModelBuildingListener( listener );
+
+ try
+ {
+ ModelBuildingResult result = modelBuilder.build( request );
+
+ Model model = result.getEffectiveModel();
+
+ projectIndex.put( result.getModelIds().get( 0 ), project );
+
+ InterimResult interimResult = new InterimResult( pomFile, request, result, listener, isRoot );
+ interimResults.add( interimResult );
+
+ if ( recursive && !model.getModules().isEmpty() )
+ {
+ File basedir = pomFile.getParentFile();
+
+ List<File> moduleFiles = new ArrayList<File>();
+
+ for ( String module : model.getModules() )
+ {
+ if ( StringUtils.isEmpty( module ) )
+ {
+ continue;
+ }
+
+ module = module.replace( '\\', File.separatorChar ).replace( '/', File.separatorChar );
+
+ File moduleFile = new File( basedir, module );
+
+ if ( moduleFile.isDirectory() )
+ {
+ moduleFile = modelProcessor.locatePom( moduleFile );
+ }
+
+ if ( !moduleFile.isFile() )
+ {
+ ModelProblem problem =
+ new DefaultModelProblem( "Child module " + moduleFile + " of " + pomFile
+ + " does not exist", ModelProblem.Severity.ERROR, ModelProblem.Version.BASE, model, -1,
+ -1, null );
+ result.getProblems().add( problem );
+
+ noErrors = false;
+
+ continue;
+ }
+
+ if ( Os.isFamily( Os.FAMILY_WINDOWS ) )
+ {
+ // we don't canonicalize on unix to avoid interfering with symlinks
+ try
+ {
+ moduleFile = moduleFile.getCanonicalFile();
+ }
+ catch ( IOException e )
+ {
+ moduleFile = moduleFile.getAbsoluteFile();
+ }
+ }
+ else
+ {
+ moduleFile = new File( moduleFile.toURI().normalize() );
+ }
+
+ if ( aggregatorFiles.contains( moduleFile ) )
+ {
+ StringBuilder buffer = new StringBuilder( 256 );
+ for ( File aggregatorFile : aggregatorFiles )
+ {
+ buffer.append( aggregatorFile ).append( " -> " );
+ }
+ buffer.append( moduleFile );
+
+ ModelProblem problem =
+ new DefaultModelProblem( "Child module " + moduleFile + " of " + pomFile
+ + " forms aggregation cycle " + buffer, ModelProblem.Severity.ERROR,
+ ModelProblem.Version.BASE, model, -1, -1, null );
+ result.getProblems().add( problem );
+
+ noErrors = false;
+
+ continue;
+ }
+
+ moduleFiles.add( moduleFile );
+ }
+
+ interimResult.modules = new ArrayList<InterimResult>();
+
+ if ( !build( results, interimResult.modules, projectIndex, moduleFiles, aggregatorFiles, false,
+ recursive, config ) )
+ {
+ noErrors = false;
+ }
+ }
+ }
+ catch ( ModelBuildingException e )
+ {
+ results.add( new DefaultProjectBuildingResult( e.getModelId(), pomFile, e.getProblems() ) );
+
+ noErrors = false;
+ }
+
+ return noErrors;
+ }
+
+ static class InterimResult
+ {
+
+ File pomFile;
+
+ ModelBuildingRequest request;
+
+ ModelBuildingResult result;
+
+ DefaultModelBuildingListener listener;
+
+ boolean root;
+
+ List<InterimResult> modules = Collections.emptyList();
+
+ InterimResult( File pomFile, ModelBuildingRequest request, ModelBuildingResult result,
+ DefaultModelBuildingListener listener, boolean root )
+ {
+ this.pomFile = pomFile;
+ this.request = request;
+ this.result = result;
+ this.listener = listener;
+ this.root = root;
+ }
+
+ }
+
+ private void populateReactorModelPool( ReactorModelPool reactorModelPool, List<InterimResult> interimResults )
+ {
+ for ( InterimResult interimResult : interimResults )
+ {
+ Model model = interimResult.result.getEffectiveModel();
+ reactorModelPool.put( model.getGroupId(), model.getArtifactId(), model.getVersion(), model.getPomFile() );
+
+ populateReactorModelPool( reactorModelPool, interimResult.modules );
+ }
+ }
+
+ private boolean build( List<ProjectBuildingResult> results, List<MavenProject> projects,
+ Map<String, MavenProject> projectIndex, List<InterimResult> interimResults,
+ ProjectBuildingRequest request, Map<File, Boolean> profilesXmls )
+ {
+ boolean noErrors = true;
+
+ for ( InterimResult interimResult : interimResults )
+ {
+ try
+ {
+ ModelBuildingResult result = modelBuilder.build( interimResult.request, interimResult.result );
+
+ MavenProject project = interimResult.listener.getProject();
+ initProject( project, projectIndex, result, profilesXmls, request );
+
+ List<MavenProject> modules = new ArrayList<MavenProject>();
+ noErrors =
+ build( results, modules, projectIndex, interimResult.modules, request, profilesXmls ) && noErrors;
+
+ projects.addAll( modules );
+ projects.add( project );
+
+ project.setExecutionRoot( interimResult.root );
+ project.setCollectedProjects( modules );
+
+ results.add( new DefaultProjectBuildingResult( project, result.getProblems(), null ) );
+ }
+ catch ( ModelBuildingException e )
+ {
+ results.add( new DefaultProjectBuildingResult( e.getModelId(), interimResult.pomFile,
+ e.getProblems() ) );
+
+ noErrors = false;
+ }
+ }
+
+ return noErrors;
+ }
+
+ private void initProject( MavenProject project, Map<String, MavenProject> projects, ModelBuildingResult result,
+ Map<File, Boolean> profilesXmls, ProjectBuildingRequest projectBuildingRequest )
+ {
+ Model model = result.getEffectiveModel();
+
+ project.setModel( model );
+ project.setOriginalModel( result.getRawModel() );
+ project.setFile( model.getPomFile() );
+ Parent p = model.getParent();
+ if ( p != null )
+ {
+ project.setParentArtifact( repositorySystem.createProjectArtifact( p.getGroupId(), p.getArtifactId(),
+ p.getVersion() ) );
+ // org.apache.maven.its.mng4834:parent:0.1
+ String parentModelId = result.getModelIds().get( 1 );
+ File parentPomFile = result.getRawModel( parentModelId ).getPomFile();
+ MavenProject parent = projects.get( parentModelId );
+ if ( parent == null )
+ {
+ //
+ // At this point the DefaultModelBuildingListener has fired and it populates the
+ // remote repositories with those found in the pom.xml, along with the existing externally
+ // defined repositories.
+ //
+ projectBuildingRequest.setRemoteRepositories( project.getRemoteArtifactRepositories() );
+ if ( parentPomFile != null )
+ {
+ project.setParentFile( parentPomFile );
+ try
+ {
+ parent = build( parentPomFile, projectBuildingRequest ).getProject();
+ }
+ catch ( ProjectBuildingException e )
+ {
+ // MNG-4488 where let invalid parents slide on by
+ logger.warn( "Failed to build parent project for " + project.getId() );
+ }
+ }
+ else
+ {
+ Artifact parentArtifact = project.getParentArtifact();
+ try
+ {
+ parent = build( parentArtifact, projectBuildingRequest ).getProject();
+ }
+ catch ( ProjectBuildingException e )
+ {
+ // MNG-4488 where let invalid parents slide on by
+ logger.warn( "Failed to build parent project for " + project.getId() );
+ }
+ }
+ }
+ project.setParent( parent );
+ }
+
+ Artifact projectArtifact =
+ repositorySystem.createArtifact( project.getGroupId(), project.getArtifactId(), project.getVersion(), null,
+ project.getPackaging() );
+ project.setArtifact( projectArtifact );
+
+ if ( project.getFile() != null )
+ {
+ Build build = project.getBuild();
+ project.addScriptSourceRoot( build.getScriptSourceDirectory() );
+ project.addCompileSourceRoot( build.getSourceDirectory() );
+ project.addTestCompileSourceRoot( build.getTestSourceDirectory() );
+ }
+
+ List<Profile> activeProfiles = new ArrayList<Profile>();
+ activeProfiles.addAll( result.getActivePomProfiles( result.getModelIds().get( 0 ) ) );
+ activeProfiles.addAll( result.getActiveExternalProfiles() );
+ project.setActiveProfiles( activeProfiles );
+
+ project.setInjectedProfileIds( "external", getProfileIds( result.getActiveExternalProfiles() ) );
+ for ( String modelId : result.getModelIds() )
+ {
+ project.setInjectedProfileIds( modelId, getProfileIds( result.getActivePomProfiles( modelId ) ) );
+ }
+
+ String modelId = findProfilesXml( result, profilesXmls );
+ if ( modelId != null )
+ {
+ ModelProblem problem =
+ new DefaultModelProblem( "Detected profiles.xml alongside " + modelId
+ + ", this file is no longer supported and was ignored" + ", please use the settings.xml instead",
+ ModelProblem.Severity.WARNING, ModelProblem.Version.V30, model, -1, -1, null );
+ result.getProblems().add( problem );
+ }
+
+ //
+ // All the parts that were taken out of MavenProject for Maven 4.0.0
+ //
+
+ project.setProjectBuildingRequest( projectBuildingRequest );
+
+ // pluginArtifacts
+ Set<Artifact> pluginArtifacts = new HashSet<Artifact>();
+ for ( Plugin plugin : project.getBuildPlugins() )
+ {
+ Artifact artifact = repositorySystem.createPluginArtifact( plugin );
+
+ if ( artifact != null )
+ {
+ pluginArtifacts.add( artifact );
+ }
+ }
+ project.setPluginArtifacts( pluginArtifacts );
+
+ // reportArtifacts
+ Set<Artifact> reportArtifacts = new HashSet<Artifact>();
+ for ( ReportPlugin report : project.getReportPlugins() )
+ {
+ Plugin pp = new Plugin();
+ pp.setGroupId( report.getGroupId() );
+ pp.setArtifactId( report.getArtifactId() );
+ pp.setVersion( report.getVersion() );
+
+ Artifact artifact = repositorySystem.createPluginArtifact( pp );
+
+ if ( artifact != null )
+ {
+ reportArtifacts.add( artifact );
+ }
+ }
+ project.setReportArtifacts( reportArtifacts );
+
+ // extensionArtifacts
+ Set<Artifact> extensionArtifacts = new HashSet<Artifact>();
+ List<Extension> extensions = project.getBuildExtensions();
+ if ( extensions != null )
+ {
+ for ( Extension ext : extensions )
+ {
+ String version;
+ if ( StringUtils.isEmpty( ext.getVersion() ) )
+ {
+ version = "RELEASE";
+ }
+ else
+ {
+ version = ext.getVersion();
+ }
+
+ Artifact artifact =
+ repositorySystem.createArtifact( ext.getGroupId(), ext.getArtifactId(), version, null, "jar" );
+
+ if ( artifact != null )
+ {
+ extensionArtifacts.add( artifact );
+ }
+ }
+ }
+ project.setExtensionArtifacts( extensionArtifacts );
+
+ // managedVersionMap
+ Map<String, Artifact> map = null;
+ if ( repositorySystem != null )
+ {
+ List<Dependency> deps;
+ DependencyManagement dependencyManagement = project.getDependencyManagement();
+ if ( ( dependencyManagement != null ) && ( ( deps = dependencyManagement.getDependencies() ) != null )
+ && ( deps.size() > 0 ) )
+ {
+ map = new HashMap<String, Artifact>();
+ for ( Dependency d : dependencyManagement.getDependencies() )
+ {
+ Artifact artifact = repositorySystem.createDependencyArtifact( d );
+
+ if ( artifact != null )
+ {
+ map.put( d.getManagementKey(), artifact );
+ }
+ }
+ }
+ else
+ {
+ map = Collections.emptyMap();
+ }
+ }
+ project.setManagedVersionMap( map );
+
+ // release artifact repository
+ if ( project.getDistributionManagement() != null
+ && project.getDistributionManagement().getRepository() != null )
+ {
+ try
+ {
+ DeploymentRepository r = project.getDistributionManagement().getRepository();
+ if ( !StringUtils.isEmpty( r.getId() ) && !StringUtils.isEmpty( r.getUrl() ) )
+ {
+ ArtifactRepository repo = repositorySystem.buildArtifactRepository( r );
+ repositorySystem.injectProxy( projectBuildingRequest.getRepositorySession(),
+ Arrays.asList( repo ) );
+ repositorySystem.injectAuthentication( projectBuildingRequest.getRepositorySession(),
+ Arrays.asList( repo ) );
+ project.setReleaseArtifactRepository( repo );
+ }
+ }
+ catch ( InvalidRepositoryException e )
+ {
+ throw new IllegalStateException( "Failed to create release distribution repository for "
+ + project.getId(), e );
+ }
+ }
+
+ // snapshot artifact repository
+ if ( project.getDistributionManagement() != null
+ && project.getDistributionManagement().getSnapshotRepository() != null )
+ {
+ try
+ {
+ DeploymentRepository r = project.getDistributionManagement().getSnapshotRepository();
+ if ( !StringUtils.isEmpty( r.getId() ) && !StringUtils.isEmpty( r.getUrl() ) )
+ {
+ ArtifactRepository repo = repositorySystem.buildArtifactRepository( r );
+ repositorySystem.injectProxy( projectBuildingRequest.getRepositorySession(),
+ Arrays.asList( repo ) );
+ repositorySystem.injectAuthentication( projectBuildingRequest.getRepositorySession(),
+ Arrays.asList( repo ) );
+ project.setSnapshotArtifactRepository( repo );
+ }
+ }
+ catch ( InvalidRepositoryException e )
+ {
+ throw new IllegalStateException( "Failed to create snapshot distribution repository for "
+ + project.getId(), e );
+ }
+ }
+ }
+
+ private String findProfilesXml( ModelBuildingResult result, Map<File, Boolean> profilesXmls )
+ {
+ for ( String modelId : result.getModelIds() )
+ {
+ Model model = result.getRawModel( modelId );
+
+ File basedir = model.getProjectDirectory();
+ if ( basedir == null )
+ {
+ break;
+ }
+
+ Boolean profilesXml = profilesXmls.get( basedir );
+ if ( profilesXml == null )
+ {
+ profilesXml = new File( basedir, "profiles.xml" ).exists();
+ profilesXmls.put( basedir, profilesXml );
+ }
+ if ( profilesXml )
+ {
+ return modelId;
+ }
+ }
+
+ return null;
+ }
+
+ class InternalConfig
+ {
+
+ public final ProjectBuildingRequest request;
+
+ public final RepositorySystemSession session;
+
+ public final List<RemoteRepository> repositories;
+
+ public final ReactorModelPool modelPool;
+
+ InternalConfig( ProjectBuildingRequest request, ReactorModelPool modelPool )
+ {
+ this.request = request;
+ this.modelPool = modelPool;
+ session =
+ LegacyLocalRepositoryManager.overlay( request.getLocalRepository(), request.getRepositorySession(),
+ repoSystem );
+ repositories = RepositoryUtils.toRepos( request.getRemoteRepositories() );
+ }
+
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuildingHelper.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuildingHelper.java
new file mode 100644
index 00000000..aea8fdbe
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuildingHelper.java
@@ -0,0 +1,295 @@
+package org.apache.maven.project;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.maven.RepositoryUtils;
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.InvalidRepositoryException;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.classrealm.ClassRealmManager;
+import org.apache.maven.model.Build;
+import org.apache.maven.model.Extension;
+import org.apache.maven.model.Model;
+import org.apache.maven.model.Plugin;
+import org.apache.maven.model.Repository;
+import org.apache.maven.plugin.ExtensionRealmCache;
+import org.apache.maven.plugin.MavenPluginManager;
+import org.apache.maven.plugin.PluginManagerException;
+import org.apache.maven.plugin.PluginResolutionException;
+import org.apache.maven.plugin.version.PluginVersionResolutionException;
+import org.apache.maven.repository.RepositorySystem;
+import org.codehaus.plexus.PlexusContainer;
+import org.codehaus.plexus.classworlds.realm.ClassRealm;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+import org.codehaus.plexus.logging.Logger;
+import org.eclipse.aether.graph.DependencyFilter;
+import org.eclipse.aether.util.filter.ExclusionsDependencyFilter;
+
+/**
+ * Assists the project builder. <strong>Warning:</strong> This is an internal utility class that is only public for
+ * technical reasons, it is not part of the public API. In particular, this class can be changed or deleted without
+ * prior notice.
+ *
+ * @author Benjamin Bentmann
+ */
+@Component( role = ProjectBuildingHelper.class )
+public class DefaultProjectBuildingHelper
+ implements ProjectBuildingHelper
+{
+
+ @Requirement
+ private Logger logger;
+
+ @Requirement
+ private PlexusContainer container;
+
+ @Requirement
+ private ClassRealmManager classRealmManager;
+
+ @Requirement
+ private ProjectRealmCache projectRealmCache;
+
+ @Requirement
+ private RepositorySystem repositorySystem;
+
+ @Requirement
+ private MavenPluginManager pluginManager;
+
+ public List<ArtifactRepository> createArtifactRepositories( List<Repository> pomRepositories,
+ List<ArtifactRepository> externalRepositories,
+ ProjectBuildingRequest request )
+ throws InvalidRepositoryException
+ {
+ List<ArtifactRepository> internalRepositories = new ArrayList<ArtifactRepository>();
+
+ for ( Repository repository : pomRepositories )
+ {
+ internalRepositories.add( repositorySystem.buildArtifactRepository( repository ) );
+ }
+
+ repositorySystem.injectMirror( request.getRepositorySession(), internalRepositories );
+
+ repositorySystem.injectProxy( request.getRepositorySession(), internalRepositories );
+
+ repositorySystem.injectAuthentication( request.getRepositorySession(), internalRepositories );
+
+ List<ArtifactRepository> dominantRepositories;
+ List<ArtifactRepository> recessiveRepositories;
+
+ if ( ProjectBuildingRequest.RepositoryMerging.REQUEST_DOMINANT.equals( request.getRepositoryMerging() ) )
+ {
+ dominantRepositories = externalRepositories;
+ recessiveRepositories = internalRepositories;
+ }
+ else
+ {
+ dominantRepositories = internalRepositories;
+ recessiveRepositories = externalRepositories;
+ }
+
+ List<ArtifactRepository> artifactRepositories = new ArrayList<ArtifactRepository>();
+ Collection<String> repoIds = new HashSet<String>();
+
+ if ( dominantRepositories != null )
+ {
+ for ( ArtifactRepository repository : dominantRepositories )
+ {
+ repoIds.add( repository.getId() );
+ artifactRepositories.add( repository );
+ }
+ }
+
+ if ( recessiveRepositories != null )
+ {
+ for ( ArtifactRepository repository : recessiveRepositories )
+ {
+ if ( repoIds.add( repository.getId() ) )
+ {
+ artifactRepositories.add( repository );
+ }
+ }
+ }
+
+ artifactRepositories = repositorySystem.getEffectiveRepositories( artifactRepositories );
+
+ return artifactRepositories;
+ }
+
+ public synchronized ProjectRealmCache.CacheRecord createProjectRealm( MavenProject project, Model model,
+ ProjectBuildingRequest request )
+ throws PluginResolutionException, PluginVersionResolutionException, PluginManagerException
+ {
+ ClassRealm projectRealm;
+
+ List<Plugin> extensionPlugins = new ArrayList<Plugin>();
+
+ Build build = model.getBuild();
+
+ if ( build != null )
+ {
+ for ( Extension extension : build.getExtensions() )
+ {
+ Plugin plugin = new Plugin();
+ plugin.setGroupId( extension.getGroupId() );
+ plugin.setArtifactId( extension.getArtifactId() );
+ plugin.setVersion( extension.getVersion() );
+ extensionPlugins.add( plugin );
+ }
+
+ for ( Plugin plugin : build.getPlugins() )
+ {
+ if ( plugin.isExtensions() )
+ {
+ extensionPlugins.add( plugin );
+ }
+ }
+ }
+
+ if ( extensionPlugins.isEmpty() )
+ {
+ if ( logger.isDebugEnabled() )
+ {
+ logger.debug( "Extension realms for project " + model.getId() + ": (none)" );
+ }
+
+ return new ProjectRealmCache.CacheRecord( null, null );
+ }
+
+ List<ClassRealm> extensionRealms = new ArrayList<ClassRealm>();
+
+ Map<ClassRealm, List<String>> exportedPackages = new HashMap<ClassRealm, List<String>>();
+
+ Map<ClassRealm, List<String>> exportedArtifacts = new HashMap<ClassRealm, List<String>>();
+
+ List<Artifact> publicArtifacts = new ArrayList<Artifact>();
+
+ for ( Plugin plugin : extensionPlugins )
+ {
+ ExtensionRealmCache.CacheRecord recordRealm =
+ pluginManager.setupExtensionsRealm( project, plugin, request.getRepositorySession() );
+
+ final ClassRealm extensionRealm = recordRealm.realm;
+ final ExtensionDescriptor extensionDescriptor = recordRealm.desciptor;
+ final List<Artifact> artifacts = recordRealm.artifacts;
+
+ extensionRealms.add( extensionRealm );
+ if ( extensionDescriptor != null )
+ {
+ exportedPackages.put( extensionRealm, extensionDescriptor.getExportedPackages() );
+ exportedArtifacts.put( extensionRealm, extensionDescriptor.getExportedArtifacts() );
+ }
+
+ if ( !plugin.isExtensions() && artifacts.size() == 2 && artifacts.get( 0 ).getFile() != null
+ && "plexus-utils".equals( artifacts.get( 1 ).getArtifactId() ) )
+ {
+ /*
+ * This is purely for backward-compat with 2.x where <extensions> consisting of a single artifact where
+ * loaded into the core and hence available to plugins, in contrast to bigger extensions that were
+ * loaded into a dedicated realm which is invisible to plugins (MNG-2749).
+ */
+ publicArtifacts.add( artifacts.get( 0 ) );
+ }
+ }
+
+ if ( logger.isDebugEnabled() )
+ {
+ logger.debug( "Extension realms for project " + model.getId() + ": " + extensionRealms );
+ }
+
+ ProjectRealmCache.Key projectRealmKey = projectRealmCache.createKey( extensionRealms );
+
+ ProjectRealmCache.CacheRecord record = projectRealmCache.get( projectRealmKey );
+
+ if ( record == null )
+ {
+ projectRealm = classRealmManager.createProjectRealm( model, toAetherArtifacts( publicArtifacts ) );
+
+ Set<String> exclusions = new LinkedHashSet<String>();
+
+ for ( ClassRealm extensionRealm : extensionRealms )
+ {
+ List<String> excludes = exportedArtifacts.get( extensionRealm );
+
+ if ( excludes != null )
+ {
+ exclusions.addAll( excludes );
+ }
+
+ List<String> exports = exportedPackages.get( extensionRealm );
+
+ if ( exports == null || exports.isEmpty() )
+ {
+ /*
+ * Most existing extensions don't define exported packages, i.e. no classes are to be exposed to
+ * plugins, yet the components provided by the extension (e.g. artifact handlers) must be
+ * accessible, i.e. we still must import the extension realm into the project realm.
+ */
+ exports = Arrays.asList( extensionRealm.getId() );
+ }
+
+ for ( String export : exports )
+ {
+ projectRealm.importFrom( extensionRealm, export );
+ }
+ }
+
+ DependencyFilter extensionArtifactFilter = null;
+ if ( !exclusions.isEmpty() )
+ {
+ extensionArtifactFilter = new ExclusionsDependencyFilter( exclusions );
+ }
+
+ record = projectRealmCache.put( projectRealmKey, projectRealm, extensionArtifactFilter );
+ }
+
+ projectRealmCache.register( project, projectRealmKey, record );
+
+ return record;
+ }
+
+ public void selectProjectRealm( MavenProject project )
+ {
+ ClassLoader projectRealm = project.getClassRealm();
+
+ if ( projectRealm == null )
+ {
+ projectRealm = classRealmManager.getCoreRealm();
+ }
+
+ Thread.currentThread().setContextClassLoader( projectRealm );
+ }
+
+ private List<org.eclipse.aether.artifact.Artifact> toAetherArtifacts( final List<Artifact> pluginArtifacts )
+ {
+ return new ArrayList<org.eclipse.aether.artifact.Artifact>( RepositoryUtils.toArtifacts( pluginArtifacts ) );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuildingRequest.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuildingRequest.java
new file mode 100644
index 00000000..185e4ca7
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuildingRequest.java
@@ -0,0 +1,339 @@
+package org.apache.maven.project;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Properties;
+
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.model.Profile;
+import org.apache.maven.model.building.ModelBuildingRequest;
+import org.eclipse.aether.RepositorySystemSession;
+
+public class DefaultProjectBuildingRequest
+ implements ProjectBuildingRequest
+{
+
+ private RepositorySystemSession repositorySession;
+
+ private ArtifactRepository localRepository;
+
+ private List<ArtifactRepository> remoteRepositories;
+
+ private List<ArtifactRepository> pluginArtifactRepositories;
+
+ private MavenProject project;
+
+ private int validationLevel = ModelBuildingRequest.VALIDATION_LEVEL_STRICT;
+
+ private boolean processPlugins;
+
+ private List<Profile> profiles;
+
+ private List<String> activeProfileIds;
+
+ private List<String> inactiveProfileIds;
+
+ private Properties systemProperties;
+
+ private Properties userProperties;
+
+ private Date buildStartTime;
+
+ private boolean resolveDependencies;
+
+ private boolean resolveVersionRanges;
+
+ private RepositoryMerging repositoryMerging = RepositoryMerging.POM_DOMINANT;
+
+ public DefaultProjectBuildingRequest()
+ {
+ processPlugins = true;
+ profiles = new ArrayList<Profile>();
+ activeProfileIds = new ArrayList<String>();
+ inactiveProfileIds = new ArrayList<String>();
+ systemProperties = new Properties();
+ userProperties = new Properties();
+ remoteRepositories = new ArrayList<ArtifactRepository>();
+ pluginArtifactRepositories = new ArrayList<ArtifactRepository>();
+ }
+
+ public DefaultProjectBuildingRequest( ProjectBuildingRequest request )
+ {
+ this();
+ setProcessPlugins( request.isProcessPlugins() );
+ setProfiles( request.getProfiles() );
+ setActiveProfileIds( request.getActiveProfileIds() );
+ setInactiveProfileIds( request.getInactiveProfileIds() );
+ setSystemProperties( request.getSystemProperties() );
+ setUserProperties( request.getUserProperties() );
+ setRemoteRepositories( request.getRemoteRepositories() );
+ setPluginArtifactRepositories( request.getPluginArtifactRepositories() );
+ setRepositorySession( request.getRepositorySession() );
+ setLocalRepository( request.getLocalRepository() );
+ setBuildStartTime( request.getBuildStartTime() );
+ setProject( request.getProject() );
+ setResolveDependencies( request.isResolveDependencies() );
+ setValidationLevel( request.getValidationLevel() );
+ }
+
+ public MavenProject getProject()
+ {
+ return project;
+ }
+
+ public void setProject( MavenProject mavenProject )
+ {
+ this.project = mavenProject;
+ }
+
+ public ProjectBuildingRequest setLocalRepository( ArtifactRepository localRepository )
+ {
+ this.localRepository = localRepository;
+ return this;
+ }
+
+ public ArtifactRepository getLocalRepository()
+ {
+ return localRepository;
+ }
+
+ public List<ArtifactRepository> getRemoteRepositories()
+ {
+ return remoteRepositories;
+ }
+
+ public ProjectBuildingRequest setRemoteRepositories( List<ArtifactRepository> remoteRepositories )
+ {
+ if ( remoteRepositories != null )
+ {
+ this.remoteRepositories = new ArrayList<ArtifactRepository>( remoteRepositories );
+ }
+ else
+ {
+ this.remoteRepositories.clear();
+ }
+
+ return this;
+ }
+
+ public List<ArtifactRepository> getPluginArtifactRepositories()
+ {
+ return pluginArtifactRepositories;
+ }
+
+ public ProjectBuildingRequest setPluginArtifactRepositories( List<ArtifactRepository> pluginArtifactRepositories )
+ {
+ if ( pluginArtifactRepositories != null )
+ {
+ this.pluginArtifactRepositories = new ArrayList<ArtifactRepository>( pluginArtifactRepositories );
+ }
+ else
+ {
+ this.pluginArtifactRepositories.clear();
+ }
+
+ return this;
+ }
+
+ public Properties getSystemProperties()
+ {
+ return systemProperties;
+ }
+
+ public ProjectBuildingRequest setSystemProperties( Properties systemProperties )
+ {
+ if ( systemProperties != null )
+ {
+ this.systemProperties = new Properties();
+ synchronized ( systemProperties )
+ { // avoid concurrentmodification if someone else sets/removes an unrelated system property
+ this.systemProperties.putAll( systemProperties );
+ }
+ }
+ else
+ {
+ this.systemProperties.clear();
+ }
+
+ return this;
+ }
+
+ public Properties getUserProperties()
+ {
+ return userProperties;
+ }
+
+ public ProjectBuildingRequest setUserProperties( Properties userProperties )
+ {
+ if ( userProperties != null )
+ {
+ this.userProperties = new Properties();
+ this.userProperties.putAll( userProperties );
+ }
+ else
+ {
+ this.userProperties.clear();
+ }
+
+ return this;
+ }
+
+ public boolean isProcessPlugins()
+ {
+ return processPlugins;
+ }
+
+ public ProjectBuildingRequest setProcessPlugins( boolean processPlugins )
+ {
+ this.processPlugins = processPlugins;
+ return this;
+ }
+
+ public ProjectBuildingRequest setResolveDependencies( boolean resolveDependencies )
+ {
+ this.resolveDependencies = resolveDependencies;
+ return this;
+ }
+
+ public boolean isResolveDependencies()
+ {
+ return resolveDependencies;
+ }
+
+ /** @since 3.2.2 */
+ public ProjectBuildingRequest setResolveVersionRanges( boolean value )
+ {
+ this.resolveVersionRanges = value;
+ return this;
+ }
+
+ /** @since 3.2.2 */
+ public boolean isResolveVersionRanges()
+ {
+ return this.resolveVersionRanges;
+ }
+
+ public ProjectBuildingRequest setValidationLevel( int validationLevel )
+ {
+ this.validationLevel = validationLevel;
+ return this;
+ }
+
+ public int getValidationLevel()
+ {
+ return validationLevel;
+ }
+
+ public List<String> getActiveProfileIds()
+ {
+ return activeProfileIds;
+ }
+
+ public void setActiveProfileIds( List<String> activeProfileIds )
+ {
+ if ( activeProfileIds != null )
+ {
+ this.activeProfileIds = new ArrayList<String>( activeProfileIds );
+ }
+ else
+ {
+ this.activeProfileIds.clear();
+ }
+ }
+
+ public List<String> getInactiveProfileIds()
+ {
+ return inactiveProfileIds;
+ }
+
+ public void setInactiveProfileIds( List<String> inactiveProfileIds )
+ {
+ if ( inactiveProfileIds != null )
+ {
+ this.inactiveProfileIds = new ArrayList<String>( inactiveProfileIds );
+ }
+ else
+ {
+ this.inactiveProfileIds.clear();
+ }
+ }
+
+ public void setProfiles( List<Profile> profiles )
+ {
+ if ( profiles != null )
+ {
+ this.profiles = new ArrayList<Profile>( profiles );
+ }
+ else
+ {
+ this.profiles.clear();
+ }
+ }
+
+ public void addProfile( Profile profile )
+ {
+ profiles.add( profile );
+ }
+
+ public List<Profile> getProfiles()
+ {
+ return profiles;
+ }
+
+ public Date getBuildStartTime()
+ {
+ return buildStartTime;
+ }
+
+ public void setBuildStartTime( Date buildStartTime )
+ {
+ this.buildStartTime = buildStartTime;
+ }
+
+ public RepositorySystemSession getRepositorySession()
+ {
+ return repositorySession;
+ }
+
+ public DefaultProjectBuildingRequest setRepositorySession( RepositorySystemSession repositorySession )
+ {
+ this.repositorySession = repositorySession;
+ return this;
+ }
+
+ public DefaultProjectBuildingRequest setRepositoryMerging( RepositoryMerging repositoryMerging )
+ {
+ if ( repositoryMerging == null )
+ {
+ throw new IllegalArgumentException( "repository merge mode not specified" );
+ }
+ this.repositoryMerging = repositoryMerging;
+ return this;
+ }
+
+ public RepositoryMerging getRepositoryMerging()
+ {
+ return repositoryMerging;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuildingResult.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuildingResult.java
new file mode 100644
index 00000000..b64a395d
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuildingResult.java
@@ -0,0 +1,110 @@
+package org.apache.maven.project;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.maven.model.building.ModelProblem;
+
+/**
+ * Collects the output of the project builder.
+ *
+ * @author Benjamin Bentmann
+ */
+class DefaultProjectBuildingResult
+ implements ProjectBuildingResult
+{
+
+ private String projectId;
+
+ private File pomFile;
+
+ private MavenProject project;
+
+ private List<ModelProblem> problems;
+
+ private DependencyResolutionResult dependencyResolutionResult;
+
+ /**
+ * Creates a new result with the specified contents.
+ *
+ * @param project The project that was built, may be {@code null}.
+ * @param problems The problems that were encouterned, may be {@code null}.
+ * @param dependencyResolutionResult The result of the resolution for the project dependencies, may be {@code null}.
+ */
+ public DefaultProjectBuildingResult( MavenProject project, List<ModelProblem> problems,
+ DependencyResolutionResult dependencyResolutionResult )
+ {
+ this.projectId =
+ ( project != null ) ? project.getGroupId() + ':' + project.getArtifactId() + ':' + project.getVersion()
+ : "";
+ this.pomFile = ( project != null ) ? project.getFile() : null;
+ this.project = project;
+ this.problems = problems;
+ this.dependencyResolutionResult = dependencyResolutionResult;
+ }
+
+ /**
+ * Creates a new result with the specified contents.
+ *
+ * @param projectId The identifier of the project, may be {@code null}.
+ * @param pomFile The POM file from which the project was built, may be {@code null}.
+ * @param problems The problems that were encouterned, may be {@code null}.
+ */
+ public DefaultProjectBuildingResult( String projectId, File pomFile, List<ModelProblem> problems )
+ {
+ this.projectId = ( projectId != null ) ? projectId : "";
+ this.pomFile = pomFile;
+ this.problems = problems;
+ }
+
+ public String getProjectId()
+ {
+ return projectId;
+ }
+
+ public File getPomFile()
+ {
+ return pomFile;
+ }
+
+ public MavenProject getProject()
+ {
+ return project;
+ }
+
+ public List<ModelProblem> getProblems()
+ {
+ if ( problems == null )
+ {
+ problems = new ArrayList<ModelProblem>();
+ }
+
+ return problems;
+ }
+
+ public DependencyResolutionResult getDependencyResolutionResult()
+ {
+ return dependencyResolutionResult;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/DefaultProjectDependenciesResolver.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/DefaultProjectDependenciesResolver.java
new file mode 100644
index 00000000..1287eb14
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/DefaultProjectDependenciesResolver.java
@@ -0,0 +1,333 @@
+package org.apache.maven.project;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.maven.RepositoryUtils;
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.model.Dependency;
+import org.apache.maven.model.DependencyManagement;
+import org.apache.maven.model.Exclusion;
+import org.apache.maven.model.InputLocation;
+import org.apache.maven.model.InputSource;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+import org.codehaus.plexus.logging.Logger;
+import org.codehaus.plexus.util.StringUtils;
+import org.eclipse.aether.DefaultRepositorySystemSession;
+import org.eclipse.aether.RepositorySystem;
+import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.RequestTrace;
+import org.eclipse.aether.artifact.ArtifactProperties;
+import org.eclipse.aether.artifact.ArtifactType;
+import org.eclipse.aether.artifact.ArtifactTypeRegistry;
+import org.eclipse.aether.collection.CollectRequest;
+import org.eclipse.aether.collection.DependencyCollectionException;
+import org.eclipse.aether.graph.DependencyFilter;
+import org.eclipse.aether.graph.DependencyNode;
+import org.eclipse.aether.graph.DependencyVisitor;
+import org.eclipse.aether.resolution.ArtifactResult;
+import org.eclipse.aether.resolution.DependencyRequest;
+import org.eclipse.aether.util.artifact.ArtifactIdUtils;
+import org.eclipse.aether.util.artifact.JavaScopes;
+import org.eclipse.aether.util.graph.manager.DependencyManagerUtils;
+
+/**
+ * @author Benjamin Bentmann
+ */
+@Component( role = ProjectDependenciesResolver.class )
+public class DefaultProjectDependenciesResolver
+ implements ProjectDependenciesResolver
+{
+
+ @Requirement
+ private Logger logger;
+
+ @Requirement
+ private RepositorySystem repoSystem;
+
+ @Requirement
+ private List<RepositorySessionDecorator> decorators;
+
+ public DependencyResolutionResult resolve( DependencyResolutionRequest request )
+ throws DependencyResolutionException
+ {
+ final RequestTrace trace = RequestTrace.newChild( null, request );
+
+ final DefaultDependencyResolutionResult result = new DefaultDependencyResolutionResult();
+
+ final MavenProject project = request.getMavenProject();
+ final DependencyFilter filter = request.getResolutionFilter();
+ RepositorySystemSession session = request.getRepositorySession();
+ ArtifactTypeRegistry stereotypes = session.getArtifactTypeRegistry();
+
+ if ( logger.isDebugEnabled()
+ && session.getConfigProperties().get( DependencyManagerUtils.CONFIG_PROP_VERBOSE ) == null )
+ {
+ DefaultRepositorySystemSession verbose = new DefaultRepositorySystemSession( session );
+ verbose.setConfigProperty( DependencyManagerUtils.CONFIG_PROP_VERBOSE, Boolean.TRUE );
+ session = verbose;
+ }
+
+ for ( RepositorySessionDecorator decorator : decorators )
+ {
+ RepositorySystemSession decorated = decorator.decorate( project, session );
+ if ( decorated != null )
+ {
+ session = decorated;
+ }
+ }
+
+ CollectRequest collect = new CollectRequest();
+ collect.setRootArtifact( RepositoryUtils.toArtifact( project.getArtifact() ) );
+ collect.setRequestContext( "project" );
+ collect.setRepositories( project.getRemoteProjectRepositories() );
+
+ if ( project.getDependencyArtifacts() == null )
+ {
+ for ( Dependency dependency : project.getDependencies() )
+ {
+ if ( StringUtils.isEmpty( dependency.getGroupId() ) || StringUtils.isEmpty( dependency.getArtifactId() )
+ || StringUtils.isEmpty( dependency.getVersion() ) )
+ {
+ // guard against case where best-effort resolution for invalid models is requested
+ continue;
+ }
+ collect.addDependency( RepositoryUtils.toDependency( dependency, stereotypes ) );
+ }
+ }
+ else
+ {
+ Map<String, Dependency> dependencies = new HashMap<String, Dependency>();
+ for ( Dependency dependency : project.getDependencies() )
+ {
+ String classifier = dependency.getClassifier();
+ if ( classifier == null )
+ {
+ ArtifactType type = stereotypes.get( dependency.getType() );
+ if ( type != null )
+ {
+ classifier = type.getClassifier();
+ }
+ }
+ String key =
+ ArtifactIdUtils.toVersionlessId( dependency.getGroupId(), dependency.getArtifactId(),
+ dependency.getType(), classifier );
+ dependencies.put( key, dependency );
+ }
+ for ( Artifact artifact : project.getDependencyArtifacts() )
+ {
+ String key = artifact.getDependencyConflictId();
+ Dependency dependency = dependencies.get( key );
+ Collection<Exclusion> exclusions = dependency != null ? dependency.getExclusions() : null;
+ org.eclipse.aether.graph.Dependency dep = RepositoryUtils.toDependency( artifact, exclusions );
+ if ( !JavaScopes.SYSTEM.equals( dep.getScope() ) && dep.getArtifact().getFile() != null )
+ {
+ // enable re-resolution
+ org.eclipse.aether.artifact.Artifact art = dep.getArtifact();
+ art = art.setFile( null ).setVersion( art.getBaseVersion() );
+ dep = dep.setArtifact( art );
+ }
+ collect.addDependency( dep );
+ }
+ }
+
+ DependencyManagement depMngt = project.getDependencyManagement();
+ if ( depMngt != null )
+ {
+ for ( Dependency dependency : depMngt.getDependencies() )
+ {
+ collect.addManagedDependency( RepositoryUtils.toDependency( dependency, stereotypes ) );
+ }
+ }
+
+ DependencyRequest depRequest = new DependencyRequest( collect, filter );
+ depRequest.setTrace( trace );
+
+ DependencyNode node;
+ try
+ {
+ collect.setTrace( RequestTrace.newChild( trace, depRequest ) );
+ node = repoSystem.collectDependencies( session, collect ).getRoot();
+ result.setDependencyGraph( node );
+ }
+ catch ( DependencyCollectionException e )
+ {
+ result.setDependencyGraph( e.getResult().getRoot() );
+ result.setCollectionErrors( e.getResult().getExceptions() );
+
+ throw new DependencyResolutionException( result, "Could not resolve dependencies for project "
+ + project.getId() + ": " + e.getMessage(), e );
+ }
+
+ depRequest.setRoot( node );
+
+ if ( logger.isWarnEnabled() )
+ {
+ for ( DependencyNode child : node.getChildren() )
+ {
+ if ( !child.getRelocations().isEmpty() )
+ {
+ logger.warn( "The artifact " + child.getRelocations().get( 0 ) + " has been relocated to "
+ + child.getDependency().getArtifact() );
+ }
+ }
+ }
+
+ if ( logger.isDebugEnabled() )
+ {
+ node.accept( new GraphLogger( project ) );
+ }
+
+ try
+ {
+ process( result, repoSystem.resolveDependencies( session, depRequest ).getArtifactResults() );
+ }
+ catch ( org.eclipse.aether.resolution.DependencyResolutionException e )
+ {
+ process( result, e.getResult().getArtifactResults() );
+
+ throw new DependencyResolutionException( result, "Could not resolve dependencies for project "
+ + project.getId() + ": " + e.getMessage(), e );
+ }
+
+ return result;
+ }
+
+ private void process( DefaultDependencyResolutionResult result, Collection<ArtifactResult> results )
+ {
+ for ( ArtifactResult ar : results )
+ {
+ DependencyNode node = ar.getRequest().getDependencyNode();
+ if ( ar.isResolved() )
+ {
+ result.addResolvedDependency( node.getDependency() );
+ }
+ else
+ {
+ result.setResolutionErrors( node.getDependency(), ar.getExceptions() );
+ }
+ }
+ }
+
+ class GraphLogger
+ implements DependencyVisitor
+ {
+
+ private final MavenProject project;
+
+ private String indent = "";
+
+ private Map<String, Dependency> managed;
+
+ public GraphLogger( MavenProject project )
+ {
+ this.project = project;
+ }
+
+ public boolean visitEnter( DependencyNode node )
+ {
+ StringBuilder buffer = new StringBuilder( 128 );
+ buffer.append( indent );
+ org.eclipse.aether.graph.Dependency dep = node.getDependency();
+ if ( dep != null )
+ {
+ org.eclipse.aether.artifact.Artifact art = dep.getArtifact();
+
+ buffer.append( art );
+ buffer.append( ':' ).append( dep.getScope() );
+
+ String premanagedScope = DependencyManagerUtils.getPremanagedScope( node );
+ if ( premanagedScope != null && !premanagedScope.equals( dep.getScope() ) )
+ {
+ buffer.append( " (scope managed from " ).append( premanagedScope );
+ appendManagementSource( buffer, art, "scope" );
+ buffer.append( ")" );
+ }
+
+ String premanagedVersion = DependencyManagerUtils.getPremanagedVersion( node );
+ if ( premanagedVersion != null && !premanagedVersion.equals( art.getVersion() ) )
+ {
+ buffer.append( " (version managed from " ).append( premanagedVersion );
+ appendManagementSource( buffer, art, "version" );
+ buffer.append( ")" );
+ }
+ }
+ else
+ {
+ buffer.append( project.getGroupId() );
+ buffer.append( ':' ).append( project.getArtifactId() );
+ buffer.append( ':' ).append( project.getPackaging() );
+ buffer.append( ':' ).append( project.getVersion() );
+ }
+
+ logger.debug( buffer.toString() );
+ indent += " ";
+ return true;
+ }
+
+ public boolean visitLeave( DependencyNode node )
+ {
+ indent = indent.substring( 0, indent.length() - 3 );
+ return true;
+ }
+
+ private void appendManagementSource( StringBuilder buffer, org.eclipse.aether.artifact.Artifact artifact,
+ String field )
+ {
+ if ( managed == null )
+ {
+ managed = new HashMap<String, Dependency>();
+ if ( project.getDependencyManagement() != null )
+ {
+ for ( Dependency dep : project.getDependencyManagement().getDependencies() )
+ {
+ managed.put( dep.getManagementKey(), dep );
+ }
+ }
+ }
+
+ String key =
+ ArtifactIdUtils.toVersionlessId( artifact.getGroupId(), artifact.getArtifactId(),
+ artifact.getProperty( ArtifactProperties.TYPE, "jar" ),
+ artifact.getClassifier() );
+
+ Dependency dependency = managed.get( key );
+ if ( dependency != null )
+ {
+ InputLocation location = dependency.getLocation( field );
+ if ( location != null )
+ {
+ InputSource source = location.getSource();
+ if ( source != null )
+ {
+ buffer.append( " by " ).append( source.getModelId() );
+ }
+ }
+ }
+ }
+
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/DefaultProjectRealmCache.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/DefaultProjectRealmCache.java
new file mode 100644
index 00000000..53b82bcf
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/DefaultProjectRealmCache.java
@@ -0,0 +1,147 @@
+package org.apache.maven.project;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.codehaus.plexus.classworlds.realm.ClassRealm;
+import org.codehaus.plexus.classworlds.realm.NoSuchRealmException;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.personality.plexus.lifecycle.phase.Disposable;
+import org.eclipse.aether.graph.DependencyFilter;
+
+/**
+ * Default project realm cache implementation. Assumes cached data does not change.
+ */
+@Component( role = ProjectRealmCache.class )
+public class DefaultProjectRealmCache
+ implements ProjectRealmCache, Disposable
+{
+
+ protected static class CacheKey
+ implements Key
+ {
+
+ private final List<? extends ClassRealm> extensionRealms;
+
+ private final int hashCode;
+
+ public CacheKey( List<? extends ClassRealm> extensionRealms )
+ {
+ this.extensionRealms = ( extensionRealms != null ) ? extensionRealms : Collections.<ClassRealm>emptyList();
+
+ this.hashCode = this.extensionRealms.hashCode();
+ }
+
+ @Override
+ public int hashCode()
+ {
+ return hashCode;
+ }
+
+ @Override
+ public boolean equals( Object o )
+ {
+ if ( o == this )
+ {
+ return true;
+ }
+
+ if ( !( o instanceof CacheKey ) )
+ {
+ return false;
+ }
+
+ CacheKey other = (CacheKey) o;
+
+ return extensionRealms.equals( other.extensionRealms );
+ }
+
+ @Override
+ public String toString()
+ {
+ return extensionRealms.toString();
+ }
+ }
+
+ protected final Map<Key, CacheRecord> cache = new ConcurrentHashMap<Key, CacheRecord>();
+
+ @Override
+ public Key createKey( List<? extends ClassRealm> extensionRealms )
+ {
+ return new CacheKey( extensionRealms );
+ }
+
+ public CacheRecord get( Key key )
+ {
+ return cache.get( key );
+ }
+
+ public CacheRecord put( Key key, ClassRealm projectRealm, DependencyFilter extensionArtifactFilter )
+ {
+ if ( projectRealm == null )
+ {
+ throw new NullPointerException();
+ }
+
+ if ( cache.containsKey( key ) )
+ {
+ throw new IllegalStateException( "Duplicate project realm for extensions " + key );
+ }
+
+ CacheRecord record = new CacheRecord( projectRealm, extensionArtifactFilter );
+
+ cache.put( key, record );
+
+ return record;
+ }
+
+ public void flush()
+ {
+ for ( CacheRecord record : cache.values() )
+ {
+ ClassRealm realm = record.realm;
+ try
+ {
+ realm.getWorld().disposeRealm( realm.getId() );
+ }
+ catch ( NoSuchRealmException e )
+ {
+ // ignore
+ }
+ }
+ cache.clear();
+ }
+
+ public void register( MavenProject project, Key key, CacheRecord record )
+ {
+ // default cache does not track record usage
+ }
+
+ @Override
+ public void dispose()
+ {
+ flush();
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/DependencyResolutionException.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/DependencyResolutionException.java
new file mode 100644
index 00000000..50e601e7
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/DependencyResolutionException.java
@@ -0,0 +1,42 @@
+package org.apache.maven.project;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * @author Benjamin Bentmann
+ */
+public class DependencyResolutionException
+ extends Exception
+{
+
+ private DependencyResolutionResult result;
+
+ public DependencyResolutionException( DependencyResolutionResult result, String message, Throwable cause )
+ {
+ super( message, cause );
+ this.result = result;
+ }
+
+ public DependencyResolutionResult getResult()
+ {
+ return result;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/DependencyResolutionRequest.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/DependencyResolutionRequest.java
new file mode 100644
index 00000000..c120a137
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/DependencyResolutionRequest.java
@@ -0,0 +1,81 @@
+package org.apache.maven.project;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.graph.DependencyFilter;
+
+/**
+ * A request to resolve the dependencies of a project.
+ *
+ * @author Benjamin Bentmann
+ */
+public interface DependencyResolutionRequest
+{
+
+ /**
+ * Gets the project to resolve dependencies for.
+ *
+ * @return The project to resolve dependencies for or {@code null} if not set.
+ */
+ MavenProject getMavenProject();
+
+ /**
+ * Sets the project to resolve dependencies for.
+ *
+ * @param project The project to resolve dependencies for, may be {@code null}.
+ * @return This request for chaining, never {@code null}.
+ */
+ DependencyResolutionRequest setMavenProject( MavenProject project );
+
+ /**
+ * Gets the filter used to exclude some dependencies from resolution.
+ *
+ * @return The filter to exclude dependencies from resolution or {@code null} to resolve all dependencies.
+ */
+ DependencyFilter getResolutionFilter();
+
+ /**
+ * Sets the filter used to exclude some dependencies from resolution. Note that this filter only controls the
+ * resolution/download of dependency artifacts, not the inclusion of dependency nodes in the resolved dependency
+ * graph.
+ *
+ * @param filter The filter to exclude dependencies from resolution, may be {@code null} to resolve all
+ * dependencies.
+ * @return This request for chaining, never {@code null}.
+ */
+ DependencyResolutionRequest setResolutionFilter( DependencyFilter filter );
+
+ /**
+ * Gets the session to use for repository access.
+ *
+ * @return The repository session or {@code null} if not set.
+ */
+ RepositorySystemSession getRepositorySession();
+
+ /**
+ * Sets the session to use for repository access.
+ *
+ * @param repositorySession The repository session to use.
+ * @return This request for chaining, never {@code null}.
+ */
+ DependencyResolutionRequest setRepositorySession( RepositorySystemSession repositorySession );
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/DependencyResolutionResult.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/DependencyResolutionResult.java
new file mode 100644
index 00000000..6ad55fae
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/DependencyResolutionResult.java
@@ -0,0 +1,80 @@
+package org.apache.maven.project;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.List;
+
+import org.eclipse.aether.graph.Dependency;
+import org.eclipse.aether.graph.DependencyNode;
+
+/**
+ * The result of a project dependency resolution.
+ *
+ * @author Benjamin Bentmann
+ */
+public interface DependencyResolutionResult
+{
+
+ /**
+ * Gets the dependency graph of the project.
+ *
+ * @return The dependency graph or {@code null} if not available.
+ */
+ DependencyNode getDependencyGraph();
+
+ /**
+ * Gets the transitive dependencies of the project that were not excluded by
+ * {@link DependencyResolutionRequest#getResolutionFilter()}. This list is a union of the results from
+ * {@link #getResolvedDependencies()} and {@link #getUnresolvedDependencies()}.
+ *
+ * @return The transitive dependencies, never {@code null}.
+ */
+ List<Dependency> getDependencies();
+
+ /**
+ * Gets the dependencies that were successfully resolved.
+ *
+ * @return The resolved dependencies, never {@code null}.
+ */
+ List<Dependency> getResolvedDependencies();
+
+ /**
+ * Gets the dependencies that could not be resolved.
+ *
+ * @return The unresolved dependencies, never {@code null}.
+ */
+ List<Dependency> getUnresolvedDependencies();
+
+ /**
+ * Gets the errors that occurred while building the dependency graph.
+ *
+ * @return The errors that occurred while building the dependency graph, never {@code null}.
+ */
+ List<Exception> getCollectionErrors();
+
+ /**
+ * Gets the errors that occurred while resolving the specified dependency.
+ *
+ * @param dependency The dependency for which to retrieve the errors, must not be {@code null}.
+ * @return The resolution errors for the specified dependency, never {@code null}.
+ */
+ List<Exception> getResolutionErrors( Dependency dependency );
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/DuplicateArtifactAttachmentException.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/DuplicateArtifactAttachmentException.java
new file mode 100644
index 00000000..6121473d
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/DuplicateArtifactAttachmentException.java
@@ -0,0 +1,64 @@
+package org.apache.maven.project;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.artifact.Artifact;
+
+/**
+ * This exception is thrown if an application attempts to attach
+ * two of the same artifacts to a single project.
+ *
+ * @author pgier
+ * @author jdcasey
+ * @todo Make this a checked exception, and modify the API of MavenProjectHelper.
+ * Currently, this modification would create compatibility problems for existing plugins.
+ */
+public class DuplicateArtifactAttachmentException
+ extends RuntimeException
+{
+
+ private static final String DEFAULT_MESSAGE = "Duplicate artifact attachment detected.";
+
+ private Artifact artifact;
+
+ private final MavenProject project;
+
+ public DuplicateArtifactAttachmentException( MavenProject project, Artifact artifact )
+ {
+ super( constructMessage( project, artifact ) );
+ this.project = project;
+ this.artifact = artifact;
+ }
+
+ private static String constructMessage( MavenProject project, Artifact artifact )
+ {
+ return DEFAULT_MESSAGE + " (project: " + project.getId() + "; illegal attachment: " + artifact.getId() + ")";
+ }
+
+ public MavenProject getProject()
+ {
+ return project;
+ }
+
+ public Artifact getArtifact()
+ {
+ return artifact;
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/DuplicateProjectException.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/DuplicateProjectException.java
new file mode 100644
index 00000000..f73c46b2
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/DuplicateProjectException.java
@@ -0,0 +1,80 @@
+package org.apache.maven.project;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+
+/**
+ * Exception that occurs when the project list contains duplicate projects instead of ignoring one.
+ *
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ */
+public class DuplicateProjectException
+ extends Exception
+{
+ private final String projectId;
+
+ private final File existingProjectFile;
+
+ private final File conflictingProjectFile;
+
+ /**
+ * @deprecated use {@link #DuplicateProjectException(String, File, File, String)}
+ */
+ public DuplicateProjectException( String message )
+ {
+ this( null, null, null, message );
+ }
+
+ /**
+ * @deprecated use {@link #DuplicateProjectException(String, File, File, String)}
+ */
+ public DuplicateProjectException( String message, Exception e )
+ {
+ super( message, e );
+ this.projectId = null;
+ this.existingProjectFile = null;
+ this.conflictingProjectFile = null;
+ }
+
+ public DuplicateProjectException( String projectId, File existingProjectFile, File conflictingProjectFile,
+ String message )
+ {
+ super( message );
+ this.projectId = projectId;
+ this.existingProjectFile = existingProjectFile;
+ this.conflictingProjectFile = conflictingProjectFile;
+ }
+
+ public String getProjectId()
+ {
+ return projectId;
+ }
+
+ public File getExistingProjectFile()
+ {
+ return existingProjectFile;
+ }
+
+ public File getConflictingProjectFile()
+ {
+ return conflictingProjectFile;
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/ExtensionDescriptor.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/ExtensionDescriptor.java
new file mode 100644
index 00000000..062b8b77
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/ExtensionDescriptor.java
@@ -0,0 +1,88 @@
+package org.apache.maven.project;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Provides metadata about a build extension. <strong>Warning:</strong> This is an internal utility class that is only
+ * public for technical reasons, it is not part of the public API. In particular, this class can be changed or deleted
+ * without prior notice.
+ *
+ * @author Benjamin Bentmann
+ */
+public class ExtensionDescriptor
+{
+
+ private List<String> exportedPackages;
+
+ private List<String> exportedArtifacts;
+
+ ExtensionDescriptor()
+ {
+ // hide constructor
+ }
+
+ public List<String> getExportedPackages()
+ {
+ if ( exportedPackages == null )
+ {
+ exportedPackages = new ArrayList<String>();
+ }
+
+ return exportedPackages;
+ }
+
+ public void setExportedPackages( List<String> exportedPackages )
+ {
+ if ( exportedPackages == null )
+ {
+ this.exportedPackages = null;
+ }
+ else
+ {
+ this.exportedPackages = new ArrayList<String>( exportedPackages );
+ }
+ }
+
+ public List<String> getExportedArtifacts()
+ {
+ if ( exportedArtifacts == null )
+ {
+ exportedArtifacts = new ArrayList<String>();
+ }
+
+ return exportedArtifacts;
+ }
+
+ public void setExportedArtifacts( List<String> exportedArtifacts )
+ {
+ if ( exportedArtifacts == null )
+ {
+ this.exportedArtifacts = null;
+ }
+ else
+ {
+ this.exportedArtifacts = new ArrayList<String>( exportedArtifacts );
+ }
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/ExtensionDescriptorBuilder.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/ExtensionDescriptorBuilder.java
new file mode 100644
index 00000000..c835eff5
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/ExtensionDescriptorBuilder.java
@@ -0,0 +1,168 @@
+package org.apache.maven.project;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.jar.JarFile;
+import java.util.zip.ZipEntry;
+
+import org.codehaus.plexus.util.IOUtil;
+import org.codehaus.plexus.util.ReaderFactory;
+import org.codehaus.plexus.util.xml.Xpp3Dom;
+import org.codehaus.plexus.util.xml.Xpp3DomBuilder;
+import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
+
+/**
+ * Creates an extension descriptor from some XML stream.
+ *
+ * @author Benjamin Bentmann
+ */
+public class ExtensionDescriptorBuilder
+{
+
+ /**
+ * @since 3.3.0
+ */
+ public String getExtensionDescriptorLocation()
+ {
+ return "META-INF/maven/extension.xml";
+ }
+
+ /**
+ * Extracts the extension descriptor (if any) from the specified JAR file.
+ *
+ * @param extensionJar The JAR file or directory to extract the descriptor from, must not be {@code null}.
+ * @return The extracted descriptor or {@code null} if no descriptor was found.
+ * @throws IOException If the descriptor is present but could not be parsed.
+ */
+ public ExtensionDescriptor build( File extensionJar )
+ throws IOException
+ {
+ ExtensionDescriptor extensionDescriptor = null;
+
+ if ( extensionJar.isFile() )
+ {
+ JarFile pluginJar = new JarFile( extensionJar, false );
+ try
+ {
+ ZipEntry pluginDescriptorEntry = pluginJar.getEntry( getExtensionDescriptorLocation() );
+
+ if ( pluginDescriptorEntry != null )
+ {
+ InputStream is = pluginJar.getInputStream( pluginDescriptorEntry );
+
+ try
+ {
+ extensionDescriptor = build( is );
+ }
+ finally
+ {
+ IOUtil.close( is );
+ }
+ }
+ }
+ finally
+ {
+ pluginJar.close();
+ }
+ }
+ else
+ {
+ File pluginXml = new File( extensionJar, getExtensionDescriptorLocation() );
+
+ if ( pluginXml.canRead() )
+ {
+ InputStream is = new BufferedInputStream( new FileInputStream( pluginXml ) );
+ try
+ {
+ extensionDescriptor = build( is );
+ }
+ finally
+ {
+ IOUtil.close( is );
+ }
+ }
+ }
+
+ return extensionDescriptor;
+ }
+
+ /**
+ * @since 3.3.0
+ */
+ public ExtensionDescriptor build( InputStream is )
+ throws IOException
+ {
+ ExtensionDescriptor extensionDescriptor = new ExtensionDescriptor();
+
+ Xpp3Dom dom;
+ try
+ {
+ dom = Xpp3DomBuilder.build( ReaderFactory.newXmlReader( is ) );
+ }
+ catch ( XmlPullParserException e )
+ {
+ throw (IOException) new IOException( e.getMessage() ).initCause( e );
+ }
+
+ if ( !"extension".equals( dom.getName() ) )
+ {
+ throw new IOException( "Unexpected root element \"" + dom.getName() + "\", expected \"extension\"" );
+ }
+
+ extensionDescriptor.setExportedPackages( parseStrings( dom.getChild( "exportedPackages" ) ) );
+
+ extensionDescriptor.setExportedArtifacts( parseStrings( dom.getChild( "exportedArtifacts" ) ) );
+
+ return extensionDescriptor;
+ }
+
+ private List<String> parseStrings( Xpp3Dom dom )
+ {
+ List<String> strings = null;
+
+ if ( dom != null )
+ {
+ strings = new ArrayList<String>();
+
+ for ( Xpp3Dom child : dom.getChildren() )
+ {
+ String string = child.getValue();
+ if ( string != null )
+ {
+ string = string.trim();
+ if ( string.length() > 0 )
+ {
+ strings.add( string );
+ }
+ }
+ }
+ }
+
+ return strings;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/InvalidProjectVersionException.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/InvalidProjectVersionException.java
new file mode 100644
index 00000000..5e42ee46
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/InvalidProjectVersionException.java
@@ -0,0 +1,59 @@
+package org.apache.maven.project;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+
+import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
+
+public class InvalidProjectVersionException
+ extends ProjectBuildingException
+{
+
+ private final String locationInPom;
+
+ private final String offendingVersion;
+
+ public InvalidProjectVersionException( String projectId, String locationInPom, String offendingVersion,
+ File pomFile, InvalidVersionSpecificationException cause )
+ {
+ super( projectId, formatMessage( projectId, locationInPom, offendingVersion, cause ), pomFile, cause );
+ this.locationInPom = locationInPom;
+ this.offendingVersion = offendingVersion;
+ }
+
+ private static String formatMessage( String projectId, String locationInPom, String offendingVersion,
+ InvalidVersionSpecificationException cause )
+ {
+ return "Invalid version: " + offendingVersion + " found for: " + locationInPom + " in project: " + projectId
+ + ". Reason: " + cause.getMessage();
+ }
+
+ public String getOffendingVersion()
+ {
+ return offendingVersion;
+ }
+
+ public String getLocationInPom()
+ {
+ return locationInPom;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/MavenProject.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/MavenProject.java
new file mode 100644
index 00000000..8587a5c3
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/MavenProject.java
@@ -0,0 +1,1976 @@
+package org.apache.maven.project;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+
+import org.apache.maven.RepositoryUtils;
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.ArtifactUtils;
+import org.apache.maven.artifact.DependencyResolutionRequiredException;
+// remove once createArtifacts() is removed
+import org.apache.maven.artifact.factory.ArtifactFactory;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
+import org.apache.maven.model.Build;
+import org.apache.maven.model.CiManagement;
+import org.apache.maven.model.Contributor;
+import org.apache.maven.model.Dependency;
+import org.apache.maven.model.DependencyManagement;
+import org.apache.maven.model.Developer;
+import org.apache.maven.model.DistributionManagement;
+import org.apache.maven.model.Extension;
+import org.apache.maven.model.IssueManagement;
+import org.apache.maven.model.License;
+import org.apache.maven.model.MailingList;
+import org.apache.maven.model.Model;
+import org.apache.maven.model.Organization;
+import org.apache.maven.model.Plugin;
+import org.apache.maven.model.PluginExecution;
+import org.apache.maven.model.PluginManagement;
+import org.apache.maven.model.Prerequisites;
+import org.apache.maven.model.Profile;
+import org.apache.maven.model.ReportPlugin;
+import org.apache.maven.model.ReportSet;
+import org.apache.maven.model.Reporting;
+import org.apache.maven.model.Repository;
+import org.apache.maven.model.Resource;
+import org.apache.maven.model.Scm;
+import org.apache.maven.model.io.xpp3.MavenXpp3Writer;
+import org.apache.maven.project.artifact.InvalidDependencyVersionException;
+import org.apache.maven.project.artifact.MavenMetadataSource;
+import org.codehaus.plexus.classworlds.realm.ClassRealm;
+import org.codehaus.plexus.util.xml.Xpp3Dom;
+import org.eclipse.aether.graph.DependencyFilter;
+import org.eclipse.aether.repository.RemoteRepository;
+
+/**
+ * The concern of the project is provide runtime values based on the model.
+ * <p/>
+ * The values in the model remain untouched but during the process of building a project notions like inheritance and
+ * interpolation can be added. This allows to have an entity which is useful in a runtime while preserving the model so
+ * that it can be marshalled and unmarshalled without being tainted by runtime requirements.
+ * <p/>
+ * <p>
+ * With changes during 3.2.2 release MavenProject is closer to being immutable after construction with the removal of
+ * all components from this class, and the upfront construction taken care of entirely by the @{ProjectBuilder}. There
+ * is still the issue of having to run the lifecycle in order to find all the compile source roots and resource
+ * directories but I hope to take care of this during the Maven 4.0 release (jvz).
+ * </p>
+ */
+public class MavenProject
+ implements Cloneable
+{
+ public static final String EMPTY_PROJECT_GROUP_ID = "unknown";
+
+ public static final String EMPTY_PROJECT_ARTIFACT_ID = "empty-project";
+
+ public static final String EMPTY_PROJECT_VERSION = "0";
+
+ private Model model;
+
+ private MavenProject parent;
+
+ private File file;
+
+ private File basedir;
+
+ private Set<Artifact> resolvedArtifacts;
+
+ private ArtifactFilter artifactFilter;
+
+ private Set<Artifact> artifacts;
+
+ private Artifact parentArtifact;
+
+ private Set<Artifact> pluginArtifacts;
+
+ private List<ArtifactRepository> remoteArtifactRepositories;
+
+ private List<ArtifactRepository> pluginArtifactRepositories;
+
+ private List<RemoteRepository> remoteProjectRepositories;
+
+ private List<RemoteRepository> remotePluginRepositories;
+
+ private List<Artifact> attachedArtifacts;
+
+ private MavenProject executionProject;
+
+ private List<MavenProject> collectedProjects;
+
+ private List<String> compileSourceRoots = new ArrayList<String>();
+
+ private List<String> testCompileSourceRoots = new ArrayList<String>();
+
+ private List<String> scriptSourceRoots = new ArrayList<String>();
+
+ private ArtifactRepository releaseArtifactRepository;
+
+ private ArtifactRepository snapshotArtifactRepository;
+
+ private List<Profile> activeProfiles = new ArrayList<Profile>();
+
+ private Map<String, List<String>> injectedProfileIds = new LinkedHashMap<String, List<String>>();
+
+ private Set<Artifact> dependencyArtifacts;
+
+ private Artifact artifact;
+
+ // calculated.
+ private Map<String, Artifact> artifactMap;
+
+ private Model originalModel;
+
+ private Map<String, Artifact> pluginArtifactMap;
+
+ private Set<Artifact> reportArtifacts;
+
+ private Map<String, Artifact> reportArtifactMap;
+
+ private Set<Artifact> extensionArtifacts;
+
+ private Map<String, Artifact> extensionArtifactMap;
+
+ private Map<String, Artifact> managedVersionMap;
+
+ private Map<String, MavenProject> projectReferences = new HashMap<String, MavenProject>();
+
+ private boolean executionRoot;
+
+ private File parentFile;
+
+ private Map<String, Object> context;
+
+ private ClassRealm classRealm;
+
+ private DependencyFilter extensionDependencyFilter;
+
+ private final Set<String> lifecyclePhases = Collections.synchronizedSet( new LinkedHashSet<String>() );
+
+ public MavenProject()
+ {
+ Model model = new Model();
+
+ model.setGroupId( EMPTY_PROJECT_GROUP_ID );
+ model.setArtifactId( EMPTY_PROJECT_ARTIFACT_ID );
+ model.setVersion( EMPTY_PROJECT_VERSION );
+
+ setModel( model );
+ }
+
+ public MavenProject( Model model )
+ {
+ setModel( model );
+ }
+
+ public MavenProject( MavenProject project )
+ {
+ deepCopy( project );
+ }
+
+ public File getParentFile()
+ {
+ return parentFile;
+ }
+
+ public void setParentFile( File parentFile )
+ {
+ this.parentFile = parentFile;
+ }
+
+ // ----------------------------------------------------------------------
+ // Accessors
+ // ----------------------------------------------------------------------
+
+ public Artifact getArtifact()
+ {
+ return artifact;
+ }
+
+ public void setArtifact( Artifact artifact )
+ {
+ this.artifact = artifact;
+ }
+
+ // @todo I would like to get rid of this. jvz.
+ public Model getModel()
+ {
+ return model;
+ }
+
+ /**
+ * Returns the project corresponding to a declared parent.
+ *
+ * @return the parent, or null if no parent is declared or there was an error building it
+ */
+ public MavenProject getParent()
+ {
+ return parent;
+ }
+
+ public void setParent( MavenProject parent )
+ {
+ this.parent = parent;
+ }
+
+ public boolean hasParent()
+ {
+ return getParent() != null;
+ }
+
+ public File getFile()
+ {
+ return file;
+ }
+
+ public void setFile( File file )
+ {
+ this.file = file;
+ this.basedir = file != null ? file.getParentFile() : null;
+ }
+
+ /**
+ * Sets project {@code file} without changing project {@code basedir}.
+ *
+ * @since 3.2.4
+ */
+ public void setPomFile( File file )
+ {
+ this.file = file;
+ }
+
+ public File getBasedir()
+ {
+ return basedir;
+ }
+
+ public void setDependencies( List<Dependency> dependencies )
+ {
+ getModel().setDependencies( dependencies );
+ }
+
+ public List<Dependency> getDependencies()
+ {
+ return getModel().getDependencies();
+ }
+
+ public DependencyManagement getDependencyManagement()
+ {
+ return getModel().getDependencyManagement();
+ }
+
+ // ----------------------------------------------------------------------
+ // Test and compile sourceroots.
+ // ----------------------------------------------------------------------
+
+ private void addPath( List<String> paths, String path )
+ {
+ if ( path != null )
+ {
+ path = path.trim();
+ if ( path.length() > 0 )
+ {
+ File file = new File( path );
+ if ( file.isAbsolute() )
+ {
+ path = file.getAbsolutePath();
+ }
+ else
+ {
+ path = new File( getBasedir(), path ).getAbsolutePath();
+ }
+
+ if ( !paths.contains( path ) )
+ {
+ paths.add( path );
+ }
+ }
+ }
+ }
+
+ public void addCompileSourceRoot( String path )
+ {
+ addPath( getCompileSourceRoots(), path );
+ }
+
+ public void addTestCompileSourceRoot( String path )
+ {
+ addPath( getTestCompileSourceRoots(), path );
+ }
+
+ public List<String> getCompileSourceRoots()
+ {
+ return compileSourceRoots;
+ }
+
+ public List<String> getTestCompileSourceRoots()
+ {
+ return testCompileSourceRoots;
+ }
+
+ public List<String> getCompileClasspathElements()
+ throws DependencyResolutionRequiredException
+ {
+ List<String> list = new ArrayList<String>( getArtifacts().size() + 1 );
+
+ String d = getBuild().getOutputDirectory();
+ if ( d != null )
+ {
+ list.add( d );
+ }
+
+ for ( Artifact a : getArtifacts() )
+ {
+ if ( a.getArtifactHandler().isAddedToClasspath() )
+ {
+ // TODO: let the scope handler deal with this
+ if ( Artifact.SCOPE_COMPILE.equals( a.getScope() ) || Artifact.SCOPE_PROVIDED.equals( a.getScope() )
+ || Artifact.SCOPE_SYSTEM.equals( a.getScope() ) )
+ {
+ addArtifactPath( a, list );
+ }
+ }
+ }
+
+ return list;
+ }
+
+ // TODO: this checking for file == null happens because the resolver has been confused about the root
+ // artifact or not. things like the stupid dummy artifact coming from surefire.
+ public List<String> getTestClasspathElements()
+ throws DependencyResolutionRequiredException
+ {
+ List<String> list = new ArrayList<String>( getArtifacts().size() + 2 );
+
+ String d = getBuild().getTestOutputDirectory();
+ if ( d != null )
+ {
+ list.add( d );
+ }
+
+ d = getBuild().getOutputDirectory();
+ if ( d != null )
+ {
+ list.add( d );
+ }
+
+ for ( Artifact a : getArtifacts() )
+ {
+ if ( a.getArtifactHandler().isAddedToClasspath() )
+ {
+ addArtifactPath( a, list );
+ }
+ }
+
+ return list;
+ }
+
+ public List<String> getRuntimeClasspathElements()
+ throws DependencyResolutionRequiredException
+ {
+ List<String> list = new ArrayList<String>( getArtifacts().size() + 1 );
+
+ String d = getBuild().getOutputDirectory();
+ if ( d != null )
+ {
+ list.add( d );
+ }
+
+ for ( Artifact a : getArtifacts() )
+ {
+ if ( a.getArtifactHandler().isAddedToClasspath()
+ // TODO: let the scope handler deal with this
+ && ( Artifact.SCOPE_COMPILE.equals( a.getScope() ) || Artifact.SCOPE_RUNTIME.equals( a.getScope() ) ) )
+ {
+ addArtifactPath( a, list );
+ }
+ }
+ return list;
+ }
+
+ // ----------------------------------------------------------------------
+ // Delegate to the model
+ // ----------------------------------------------------------------------
+
+ public void setModelVersion( String pomVersion )
+ {
+ getModel().setModelVersion( pomVersion );
+ }
+
+ public String getModelVersion()
+ {
+ return getModel().getModelVersion();
+ }
+
+ public String getId()
+ {
+ return getModel().getId();
+ }
+
+ public void setGroupId( String groupId )
+ {
+ getModel().setGroupId( groupId );
+ }
+
+ public String getGroupId()
+ {
+ String groupId = getModel().getGroupId();
+
+ if ( ( groupId == null ) && ( getModel().getParent() != null ) )
+ {
+ groupId = getModel().getParent().getGroupId();
+ }
+
+ return groupId;
+ }
+
+ public void setArtifactId( String artifactId )
+ {
+ getModel().setArtifactId( artifactId );
+ }
+
+ public String getArtifactId()
+ {
+ return getModel().getArtifactId();
+ }
+
+ public void setName( String name )
+ {
+ getModel().setName( name );
+ }
+
+ public String getName()
+ {
+ // TODO: this should not be allowed to be null.
+ if ( getModel().getName() != null )
+ {
+ return getModel().getName();
+ }
+ else
+ {
+ return getArtifactId();
+ }
+ }
+
+ public void setVersion( String version )
+ {
+ getModel().setVersion( version );
+ }
+
+ public String getVersion()
+ {
+ String version = getModel().getVersion();
+
+ if ( ( version == null ) && ( getModel().getParent() != null ) )
+ {
+ version = getModel().getParent().getVersion();
+ }
+
+ return version;
+ }
+
+ public String getPackaging()
+ {
+ return getModel().getPackaging();
+ }
+
+ public void setPackaging( String packaging )
+ {
+ getModel().setPackaging( packaging );
+ }
+
+ public void setInceptionYear( String inceptionYear )
+ {
+ getModel().setInceptionYear( inceptionYear );
+ }
+
+ public String getInceptionYear()
+ {
+ return getModel().getInceptionYear();
+ }
+
+ public void setUrl( String url )
+ {
+ getModel().setUrl( url );
+ }
+
+ public String getUrl()
+ {
+ return getModel().getUrl();
+ }
+
+ public Prerequisites getPrerequisites()
+ {
+ return getModel().getPrerequisites();
+ }
+
+ public void setIssueManagement( IssueManagement issueManagement )
+ {
+ getModel().setIssueManagement( issueManagement );
+ }
+
+ public CiManagement getCiManagement()
+ {
+ return getModel().getCiManagement();
+ }
+
+ public void setCiManagement( CiManagement ciManagement )
+ {
+ getModel().setCiManagement( ciManagement );
+ }
+
+ public IssueManagement getIssueManagement()
+ {
+ return getModel().getIssueManagement();
+ }
+
+ public void setDistributionManagement( DistributionManagement distributionManagement )
+ {
+ getModel().setDistributionManagement( distributionManagement );
+ }
+
+ public DistributionManagement getDistributionManagement()
+ {
+ return getModel().getDistributionManagement();
+ }
+
+ public void setDescription( String description )
+ {
+ getModel().setDescription( description );
+ }
+
+ public String getDescription()
+ {
+ return getModel().getDescription();
+ }
+
+ public void setOrganization( Organization organization )
+ {
+ getModel().setOrganization( organization );
+ }
+
+ public Organization getOrganization()
+ {
+ return getModel().getOrganization();
+ }
+
+ public void setScm( Scm scm )
+ {
+ getModel().setScm( scm );
+ }
+
+ public Scm getScm()
+ {
+ return getModel().getScm();
+ }
+
+ public void setMailingLists( List<MailingList> mailingLists )
+ {
+ getModel().setMailingLists( mailingLists );
+ }
+
+ public List<MailingList> getMailingLists()
+ {
+ return getModel().getMailingLists();
+ }
+
+ public void addMailingList( MailingList mailingList )
+ {
+ getModel().addMailingList( mailingList );
+ }
+
+ public void setDevelopers( List<Developer> developers )
+ {
+ getModel().setDevelopers( developers );
+ }
+
+ public List<Developer> getDevelopers()
+ {
+ return getModel().getDevelopers();
+ }
+
+ public void addDeveloper( Developer developer )
+ {
+ getModel().addDeveloper( developer );
+ }
+
+ public void setContributors( List<Contributor> contributors )
+ {
+ getModel().setContributors( contributors );
+ }
+
+ public List<Contributor> getContributors()
+ {
+ return getModel().getContributors();
+ }
+
+ public void addContributor( Contributor contributor )
+ {
+ getModel().addContributor( contributor );
+ }
+
+ public void setBuild( Build build )
+ {
+ getModel().setBuild( build );
+ }
+
+ public Build getBuild()
+ {
+ return getModelBuild();
+ }
+
+ public List<Resource> getResources()
+ {
+ return getBuild().getResources();
+ }
+
+ public List<Resource> getTestResources()
+ {
+ return getBuild().getTestResources();
+ }
+
+ public void addResource( Resource resource )
+ {
+ getBuild().addResource( resource );
+ }
+
+ public void addTestResource( Resource testResource )
+ {
+ getBuild().addTestResource( testResource );
+ }
+
+ public void setLicenses( List<License> licenses )
+ {
+ getModel().setLicenses( licenses );
+ }
+
+ public List<License> getLicenses()
+ {
+ return getModel().getLicenses();
+ }
+
+ public void addLicense( License license )
+ {
+ getModel().addLicense( license );
+ }
+
+ public void setArtifacts( Set<Artifact> artifacts )
+ {
+ this.artifacts = artifacts;
+
+ // flush the calculated artifactMap
+ artifactMap = null;
+ }
+
+ /**
+ * All dependencies that this project has, including transitive ones. Contents are lazily populated, so depending on
+ * what phases have run dependencies in some scopes won't be included. eg. if only compile phase has run,
+ * dependencies with scope test won't be included.
+ *
+ * @return {@link Set} &lt; {@link Artifact} >
+ * @see #getDependencyArtifacts() to get only direct dependencies
+ */
+ public Set<Artifact> getArtifacts()
+ {
+ if ( artifacts == null )
+ {
+ if ( artifactFilter == null || resolvedArtifacts == null )
+ {
+ artifacts = new LinkedHashSet<Artifact>();
+ }
+ else
+ {
+ artifacts = new LinkedHashSet<Artifact>( resolvedArtifacts.size() * 2 );
+ for ( Artifact artifact : resolvedArtifacts )
+ {
+ if ( artifactFilter.include( artifact ) )
+ {
+ artifacts.add( artifact );
+ }
+ }
+ }
+ }
+ return artifacts;
+ }
+
+ public Map<String, Artifact> getArtifactMap()
+ {
+ if ( artifactMap == null )
+ {
+ artifactMap = ArtifactUtils.artifactMapByVersionlessId( getArtifacts() );
+ }
+ return artifactMap;
+ }
+
+ public void setPluginArtifacts( Set<Artifact> pluginArtifacts )
+ {
+ this.pluginArtifacts = pluginArtifacts;
+
+ this.pluginArtifactMap = null;
+ }
+
+ public Set<Artifact> getPluginArtifacts()
+ {
+ return pluginArtifacts;
+ }
+
+ public Map<String, Artifact> getPluginArtifactMap()
+ {
+ if ( pluginArtifactMap == null )
+ {
+ pluginArtifactMap = ArtifactUtils.artifactMapByVersionlessId( getPluginArtifacts() );
+ }
+
+ return pluginArtifactMap;
+ }
+
+ public void setParentArtifact( Artifact parentArtifact )
+ {
+ this.parentArtifact = parentArtifact;
+ }
+
+ public Artifact getParentArtifact()
+ {
+ return parentArtifact;
+ }
+
+ public List<Repository> getRepositories()
+ {
+ return getModel().getRepositories();
+ }
+
+ // ----------------------------------------------------------------------
+ // Plugins
+ // ----------------------------------------------------------------------
+
+ public List<Plugin> getBuildPlugins()
+ {
+ if ( getModel().getBuild() == null )
+ {
+ return Collections.emptyList();
+ }
+ return getModel().getBuild().getPlugins();
+ }
+
+ public List<String> getModules()
+ {
+ return getModel().getModules();
+ }
+
+ public PluginManagement getPluginManagement()
+ {
+ PluginManagement pluginMgmt = null;
+
+ Build build = getModel().getBuild();
+ if ( build != null )
+ {
+ pluginMgmt = build.getPluginManagement();
+ }
+
+ return pluginMgmt;
+ }
+
+ private Build getModelBuild()
+ {
+ Build build = getModel().getBuild();
+
+ if ( build == null )
+ {
+ build = new Build();
+
+ getModel().setBuild( build );
+ }
+
+ return build;
+ }
+
+ public void setRemoteArtifactRepositories( List<ArtifactRepository> remoteArtifactRepositories )
+ {
+ this.remoteArtifactRepositories = remoteArtifactRepositories;
+ this.remoteProjectRepositories = RepositoryUtils.toRepos( getRemoteArtifactRepositories() );
+ }
+
+ public List<ArtifactRepository> getRemoteArtifactRepositories()
+ {
+ if ( remoteArtifactRepositories == null )
+ {
+ remoteArtifactRepositories = new ArrayList<ArtifactRepository>();
+ }
+
+ return remoteArtifactRepositories;
+ }
+
+ public void setPluginArtifactRepositories( List<ArtifactRepository> pluginArtifactRepositories )
+ {
+ this.pluginArtifactRepositories = pluginArtifactRepositories;
+ this.remotePluginRepositories = RepositoryUtils.toRepos( getPluginArtifactRepositories() );
+ }
+
+ /**
+ * @return a list of ArtifactRepository objects constructed from the Repository objects returned by
+ * getPluginRepositories.
+ */
+ public List<ArtifactRepository> getPluginArtifactRepositories()
+ {
+ if ( pluginArtifactRepositories == null )
+ {
+ pluginArtifactRepositories = new ArrayList<ArtifactRepository>();
+ }
+
+ return pluginArtifactRepositories;
+ }
+
+ public ArtifactRepository getDistributionManagementArtifactRepository()
+ {
+ return getArtifact().isSnapshot() && ( getSnapshotArtifactRepository() != null )
+ ? getSnapshotArtifactRepository()
+ : getReleaseArtifactRepository();
+ }
+
+ public List<Repository> getPluginRepositories()
+ {
+ return getModel().getPluginRepositories();
+ }
+
+ public List<RemoteRepository> getRemoteProjectRepositories()
+ {
+ return remoteProjectRepositories;
+ }
+
+ public List<RemoteRepository> getRemotePluginRepositories()
+ {
+ return remotePluginRepositories;
+ }
+
+ public void setActiveProfiles( List<Profile> activeProfiles )
+ {
+ this.activeProfiles = activeProfiles;
+ }
+
+ public List<Profile> getActiveProfiles()
+ {
+ return activeProfiles;
+ }
+
+ public void setInjectedProfileIds( String source, List<String> injectedProfileIds )
+ {
+ if ( injectedProfileIds != null )
+ {
+ this.injectedProfileIds.put( source, new ArrayList<String>( injectedProfileIds ) );
+ }
+ else
+ {
+ this.injectedProfileIds.remove( source );
+ }
+ }
+
+ /**
+ * Gets the identifiers of all profiles that contributed to this project's effective model. This includes active
+ * profiles from the project's POM and all its parent POMs as well as from external sources like the
+ * {@code settings.xml}. The profile identifiers are grouped by the identifier of their source, e.g.
+ * {@code <groupId>:<artifactId>:<version>} for a POM profile or {@code external} for profiles from the
+ * {@code settings.xml}.
+ *
+ * @return The identifiers of all injected profiles, indexed by the source from which the profiles originated, never
+ * {@code null}.
+ */
+ public Map<String, List<String>> getInjectedProfileIds()
+ {
+ return this.injectedProfileIds;
+ }
+
+ /**
+ * Add or replace an artifact. This method is now deprecated. Use the @{MavenProjectHelper} to attach artifacts to a
+ * project. In spite of the 'throws' declaration on this API, this method has never thrown an exception since Maven
+ * 3.0.x. Historically, it logged and ignored a second addition of the same g/a/v/c/t. Now it replaces the file for
+ * the artifact, so that plugins (e.g. shade) can change the pathname of the file for a particular set of
+ * coordinates.
+ *
+ * @param artifact the artifact to add or replace.
+ * @throws DuplicateArtifactAttachmentException
+ */
+ public void addAttachedArtifact( Artifact artifact )
+ throws DuplicateArtifactAttachmentException
+ {
+ getAttachedArtifacts().add( artifact );
+ }
+
+ public List<Artifact> getAttachedArtifacts()
+ {
+ if ( attachedArtifacts == null )
+ {
+ attachedArtifacts = new ArrayList<Artifact>();
+ }
+ return attachedArtifacts;
+ }
+
+ public Xpp3Dom getGoalConfiguration( String pluginGroupId, String pluginArtifactId, String executionId,
+ String goalId )
+ {
+ Xpp3Dom dom = null;
+
+ if ( getBuildPlugins() != null )
+ {
+ for ( Plugin plugin : getBuildPlugins() )
+ {
+ if ( pluginGroupId.equals( plugin.getGroupId() ) && pluginArtifactId.equals( plugin.getArtifactId() ) )
+ {
+ dom = (Xpp3Dom) plugin.getConfiguration();
+
+ if ( executionId != null )
+ {
+ PluginExecution execution = plugin.getExecutionsAsMap().get( executionId );
+ if ( execution != null )
+ {
+ // NOTE: The PluginConfigurationExpander already merged the plugin-level config in
+ dom = (Xpp3Dom) execution.getConfiguration();
+ }
+ }
+ break;
+ }
+ }
+ }
+
+ if ( dom != null )
+ {
+ // make a copy so the original in the POM doesn't get messed with
+ dom = new Xpp3Dom( dom );
+ }
+
+ return dom;
+ }
+
+ public MavenProject getExecutionProject()
+ {
+ return ( executionProject == null ? this : executionProject );
+ }
+
+ public void setExecutionProject( MavenProject executionProject )
+ {
+ this.executionProject = executionProject;
+ }
+
+ public List<MavenProject> getCollectedProjects()
+ {
+ return collectedProjects;
+ }
+
+ public void setCollectedProjects( List<MavenProject> collectedProjects )
+ {
+ this.collectedProjects = collectedProjects;
+ }
+
+ /**
+ * Direct dependencies that this project has.
+ *
+ * @return {@link Set} &lt; {@link Artifact} >
+ * @see #getArtifacts() to get all transitive dependencies
+ */
+ public Set<Artifact> getDependencyArtifacts()
+ {
+ return dependencyArtifacts;
+ }
+
+ public void setDependencyArtifacts( Set<Artifact> dependencyArtifacts )
+ {
+ this.dependencyArtifacts = dependencyArtifacts;
+ }
+
+ public void setReleaseArtifactRepository( ArtifactRepository releaseArtifactRepository )
+ {
+ this.releaseArtifactRepository = releaseArtifactRepository;
+ }
+
+ public void setSnapshotArtifactRepository( ArtifactRepository snapshotArtifactRepository )
+ {
+ this.snapshotArtifactRepository = snapshotArtifactRepository;
+ }
+
+ public void setOriginalModel( Model originalModel )
+ {
+ this.originalModel = originalModel;
+ }
+
+ public Model getOriginalModel()
+ {
+ return originalModel;
+ }
+
+ public void setManagedVersionMap( Map<String, Artifact> map )
+ {
+ managedVersionMap = map;
+ }
+
+ public Map<String, Artifact> getManagedVersionMap()
+ {
+ return managedVersionMap;
+ }
+
+ @Override
+ public boolean equals( Object other )
+ {
+ if ( other == this )
+ {
+ return true;
+ }
+ else if ( !( other instanceof MavenProject ) )
+ {
+ return false;
+ }
+
+ MavenProject that = (MavenProject) other;
+
+ return eq( getArtifactId(), that.getArtifactId() ) && eq( getGroupId(), that.getGroupId() )
+ && eq( getVersion(), that.getVersion() );
+ }
+
+ private static <T> boolean eq( T s1, T s2 )
+ {
+ return ( s1 != null ) ? s1.equals( s2 ) : s2 == null;
+ }
+
+ @Override
+ public int hashCode()
+ {
+ int hash = 17;
+ hash = 31 * hash + getGroupId().hashCode();
+ hash = 31 * hash + getArtifactId().hashCode();
+ hash = 31 * hash + getVersion().hashCode();
+ return hash;
+ }
+
+ public List<Extension> getBuildExtensions()
+ {
+ Build build = getBuild();
+ if ( ( build == null ) || ( build.getExtensions() == null ) )
+ {
+ return Collections.emptyList();
+ }
+ else
+ {
+ return build.getExtensions();
+ }
+ }
+
+ public void addProjectReference( MavenProject project )
+ {
+ projectReferences.put( getProjectReferenceId( project.getGroupId(), project.getArtifactId(),
+ project.getVersion() ), project );
+ }
+
+ public Properties getProperties()
+ {
+ return getModel().getProperties();
+ }
+
+ public List<String> getFilters()
+ {
+ return getBuild().getFilters();
+ }
+
+ public Map<String, MavenProject> getProjectReferences()
+ {
+ return projectReferences;
+ }
+
+ public boolean isExecutionRoot()
+ {
+ return executionRoot;
+ }
+
+ public void setExecutionRoot( boolean executionRoot )
+ {
+ this.executionRoot = executionRoot;
+ }
+
+ public String getDefaultGoal()
+ {
+ return getBuild() != null ? getBuild().getDefaultGoal() : null;
+ }
+
+ public Plugin getPlugin( String pluginKey )
+ {
+ return getBuild().getPluginsAsMap().get( pluginKey );
+ }
+
+ /**
+ * Default toString
+ */
+ @Override
+ public String toString()
+ {
+ StringBuilder sb = new StringBuilder( 128 );
+ sb.append( "MavenProject: " );
+ sb.append( getGroupId() );
+ sb.append( ":" );
+ sb.append( getArtifactId() );
+ sb.append( ":" );
+ sb.append( getVersion() );
+ sb.append( " @ " );
+
+ try
+ {
+ sb.append( getFile().getPath() );
+ }
+ catch ( NullPointerException e )
+ {
+ // don't log it.
+ }
+
+ return sb.toString();
+ }
+
+ /**
+ * @throws CloneNotSupportedException
+ * @since 2.0.9
+ */
+ @Override
+ public MavenProject clone()
+ {
+ MavenProject clone;
+ try
+ {
+ clone = (MavenProject) super.clone();
+ }
+ catch ( CloneNotSupportedException e )
+ {
+ throw new UnsupportedOperationException( e );
+ }
+
+ clone.deepCopy( this );
+
+ return clone;
+ }
+
+ public void setModel( Model model )
+ {
+ this.model = model;
+ }
+
+ protected void setAttachedArtifacts( List<Artifact> attachedArtifacts )
+ {
+ this.attachedArtifacts = attachedArtifacts;
+ }
+
+ protected void setCompileSourceRoots( List<String> compileSourceRoots )
+ {
+ this.compileSourceRoots = compileSourceRoots;
+ }
+
+ protected void setTestCompileSourceRoots( List<String> testCompileSourceRoots )
+ {
+ this.testCompileSourceRoots = testCompileSourceRoots;
+ }
+
+ protected ArtifactRepository getReleaseArtifactRepository()
+ {
+ return releaseArtifactRepository;
+ }
+
+ protected ArtifactRepository getSnapshotArtifactRepository()
+ {
+ return snapshotArtifactRepository;
+ }
+
+ private void deepCopy( MavenProject project )
+ {
+ // disown the parent
+
+ // copy fields
+ setFile( project.getFile() );
+
+ // don't need a deep copy, they don't get modified or added/removed to/from - but make them unmodifiable to be
+ // sure!
+ if ( project.getDependencyArtifacts() != null )
+ {
+ setDependencyArtifacts( Collections.unmodifiableSet( project.getDependencyArtifacts() ) );
+ }
+
+ if ( project.getArtifacts() != null )
+ {
+ setArtifacts( Collections.unmodifiableSet( project.getArtifacts() ) );
+ }
+
+ if ( project.getParentFile() != null )
+ {
+ parentFile = new File( project.getParentFile().getAbsolutePath() );
+ }
+
+ if ( project.getPluginArtifacts() != null )
+ {
+ setPluginArtifacts( Collections.unmodifiableSet( project.getPluginArtifacts() ) );
+ }
+
+ if ( project.getReportArtifacts() != null )
+ {
+ setReportArtifacts( Collections.unmodifiableSet( project.getReportArtifacts() ) );
+ }
+
+ if ( project.getExtensionArtifacts() != null )
+ {
+ setExtensionArtifacts( Collections.unmodifiableSet( project.getExtensionArtifacts() ) );
+ }
+
+ setParentArtifact( ( project.getParentArtifact() ) );
+
+ if ( project.getRemoteArtifactRepositories() != null )
+ {
+ setRemoteArtifactRepositories( Collections.unmodifiableList( project.getRemoteArtifactRepositories() ) );
+ }
+
+ if ( project.getPluginArtifactRepositories() != null )
+ {
+ setPluginArtifactRepositories( Collections.unmodifiableList( project.getPluginArtifactRepositories() ) );
+ }
+
+ if ( project.getActiveProfiles() != null )
+ {
+ setActiveProfiles( ( Collections.unmodifiableList( project.getActiveProfiles() ) ) );
+ }
+
+ if ( project.getAttachedArtifacts() != null )
+ {
+ // clone properties modifyable by plugins in a forked lifecycle
+ setAttachedArtifacts( new ArrayList<Artifact>( project.getAttachedArtifacts() ) );
+ }
+
+ if ( project.getCompileSourceRoots() != null )
+ {
+ // clone source roots
+ setCompileSourceRoots( ( new ArrayList<String>( project.getCompileSourceRoots() ) ) );
+ }
+
+ if ( project.getTestCompileSourceRoots() != null )
+ {
+ setTestCompileSourceRoots( ( new ArrayList<String>( project.getTestCompileSourceRoots() ) ) );
+ }
+
+ if ( project.getScriptSourceRoots() != null )
+ {
+ setScriptSourceRoots( ( new ArrayList<String>( project.getScriptSourceRoots() ) ) );
+ }
+
+ if ( project.getModel() != null )
+ {
+ setModel( project.getModel().clone() );
+ }
+
+ if ( project.getOriginalModel() != null )
+ {
+ setOriginalModel( project.getOriginalModel() );
+ }
+
+ setExecutionRoot( project.isExecutionRoot() );
+
+ if ( project.getArtifact() != null )
+ {
+ setArtifact( ArtifactUtils.copyArtifact( project.getArtifact() ) );
+ }
+
+ if ( project.getManagedVersionMap() != null )
+ {
+ setManagedVersionMap( new HashMap<String, Artifact>( project.getManagedVersionMap() ) );
+ }
+
+ lifecyclePhases.addAll( project.lifecyclePhases );
+ }
+
+ private void addArtifactPath( Artifact artifact, List<String> classpath )
+ {
+ File file = artifact.getFile();
+ if ( file != null )
+ {
+ classpath.add( file.getPath() );
+ }
+ }
+
+ private static String getProjectReferenceId( String groupId, String artifactId, String version )
+ {
+ StringBuilder buffer = new StringBuilder( 128 );
+ buffer.append( groupId ).append( ':' ).append( artifactId ).append( ':' ).append( version );
+ return buffer.toString();
+ }
+
+ /**
+ * Sets the value of the context value of this project identified by the given key. If the supplied value is
+ * <code>null</code>, the context value is removed from this project. Context values are intended to allow core
+ * extensions to associate derived state with project instances.
+ */
+ public void setContextValue( String key, Object value )
+ {
+ if ( context == null )
+ {
+ context = new HashMap<String, Object>();
+ }
+ if ( value != null )
+ {
+ context.put( key, value );
+ }
+ else
+ {
+ context.remove( key );
+ }
+ }
+
+ /**
+ * Returns context value of this project associated with the given key or null if this project has no such value.
+ */
+ public Object getContextValue( String key )
+ {
+ if ( context == null )
+ {
+ return null;
+ }
+ return context.get( key );
+ }
+
+ /**
+ * Sets the project's class realm. <strong>Warning:</strong> This is an internal utility method that is only public
+ * for technical reasons, it is not part of the public API. In particular, this method can be changed or deleted
+ * without prior notice and must not be used by plugins.
+ *
+ * @param classRealm The class realm hosting the build extensions of this project, may be {@code null}.
+ */
+ public void setClassRealm( ClassRealm classRealm )
+ {
+ this.classRealm = classRealm;
+ }
+
+ /**
+ * Gets the project's class realm. This class realm hosts the build extensions of the project.
+ * <strong>Warning:</strong> This is an internal utility method that is only public for technical reasons, it is not
+ * part of the public API. In particular, this method can be changed or deleted without prior notice and must not be
+ * used by plugins.
+ *
+ * @return The project's class realm or {@code null}.
+ */
+ public ClassRealm getClassRealm()
+ {
+ return classRealm;
+ }
+
+ /**
+ * Sets the artifact filter used to exclude shared extension artifacts from plugin realms. <strong>Warning:</strong>
+ * This is an internal utility method that is only public for technical reasons, it is not part of the public API.
+ * In particular, this method can be changed or deleted without prior notice and must not be used by plugins.
+ *
+ * @param extensionDependencyFilter The dependency filter to apply to plugins, may be {@code null}.
+ */
+ public void setExtensionDependencyFilter( DependencyFilter extensionDependencyFilter )
+ {
+ this.extensionDependencyFilter = extensionDependencyFilter;
+ }
+
+ /**
+ * Gets the dependency filter used to exclude shared extension artifacts from plugin realms.
+ * <strong>Warning:</strong> This is an internal utility method that is only public for technical reasons, it is not
+ * part of the public API. In particular, this method can be changed or deleted without prior notice and must not be
+ * used by plugins.
+ *
+ * @return The dependency filter or {@code null}.
+ */
+ public DependencyFilter getExtensionDependencyFilter()
+ {
+ return extensionDependencyFilter;
+ }
+
+ /**
+ * Sets the transitive dependency artifacts that have been resolved/collected for this project.
+ * <strong>Warning:</strong> This is an internal utility method that is only public for technical reasons, it is not
+ * part of the public API. In particular, this method can be changed or deleted without prior notice and must not be
+ * used by plugins.
+ *
+ * @param artifacts The set of artifacts, may be {@code null}.
+ */
+ public void setResolvedArtifacts( Set<Artifact> artifacts )
+ {
+ this.resolvedArtifacts = ( artifacts != null ) ? artifacts : Collections.<Artifact>emptySet();
+ this.artifacts = null;
+ this.artifactMap = null;
+ }
+
+ /**
+ * Sets the scope filter to select the artifacts being exposed to the currently executed mojo.
+ * <strong>Warning:</strong> This is an internal utility method that is only public for technical reasons, it is not
+ * part of the public API. In particular, this method can be changed or deleted without prior notice and must not be
+ * used by plugins.
+ *
+ * @param artifactFilter The artifact filter, may be {@code null} to exclude all artifacts.
+ */
+ public void setArtifactFilter( ArtifactFilter artifactFilter )
+ {
+ this.artifactFilter = artifactFilter;
+ this.artifacts = null;
+ this.artifactMap = null;
+ }
+
+ /**
+ * <strong>Warning:</strong> This is an internal utility method that is only public for technical reasons, it is not
+ * part of the public API. In particular, this method can be changed or deleted without prior notice and must not be
+ * used by plugins.
+ *
+ * @param phase The phase to check for, must not be {@code null}.
+ * @return {@code true} if the phase has been seen.
+ */
+ public boolean hasLifecyclePhase( String phase )
+ {
+ return lifecyclePhases.contains( phase );
+ }
+
+ /**
+ * <strong>Warning:</strong> This is an internal utility method that is only public for technical reasons, it is not
+ * part of the public API. In particular, this method can be changed or deleted without prior notice and must not be
+ * used by plugins.
+ *
+ * @param lifecyclePhase The lifecycle phase to add, must not be {@code null}.
+ */
+ public void addLifecyclePhase( String lifecyclePhase )
+ {
+ lifecyclePhases.add( lifecyclePhase );
+ }
+
+ // ----------------------------------------------------------------------------------------------------------------
+ //
+ //
+ // D E P R E C A T E D
+ //
+ //
+ // ----------------------------------------------------------------------------------------------------------------
+ //
+ // Everything below will be removed for Maven 4.0.0
+ //
+ // ----------------------------------------------------------------------------------------------------------------
+
+ private ProjectBuildingRequest projectBuilderConfiguration;
+
+ private Map<String, String> moduleAdjustments;
+
+ @Deprecated // This appears only to be used in test code
+ public String getModulePathAdjustment( MavenProject moduleProject )
+ throws IOException
+ {
+ // FIXME: This is hacky. What if module directory doesn't match artifactid, and parent
+ // is coming from the repository??
+ String module = moduleProject.getArtifactId();
+
+ File moduleFile = moduleProject.getFile();
+
+ if ( moduleFile != null )
+ {
+ File moduleDir = moduleFile.getCanonicalFile().getParentFile();
+
+ module = moduleDir.getName();
+ }
+
+ if ( moduleAdjustments == null )
+ {
+ moduleAdjustments = new HashMap<String, String>();
+
+ List<String> modules = getModules();
+ if ( modules != null )
+ {
+ for ( String modulePath : modules )
+ {
+ String moduleName = modulePath;
+
+ if ( moduleName.endsWith( "/" ) || moduleName.endsWith( "\\" ) )
+ {
+ moduleName = moduleName.substring( 0, moduleName.length() - 1 );
+ }
+
+ int lastSlash = moduleName.lastIndexOf( '/' );
+
+ if ( lastSlash < 0 )
+ {
+ lastSlash = moduleName.lastIndexOf( '\\' );
+ }
+
+ String adjustment = null;
+
+ if ( lastSlash > -1 )
+ {
+ moduleName = moduleName.substring( lastSlash + 1 );
+ adjustment = modulePath.substring( 0, lastSlash );
+ }
+
+ moduleAdjustments.put( moduleName, adjustment );
+ }
+ }
+ }
+
+ return moduleAdjustments.get( module );
+ }
+
+ @Deprecated
+ public Set<Artifact> createArtifacts( ArtifactFactory artifactFactory, String inheritedScope,
+ ArtifactFilter filter )
+ throws InvalidDependencyVersionException
+ {
+ return MavenMetadataSource.createArtifacts( artifactFactory, getDependencies(), inheritedScope, filter, this );
+ }
+
+ @Deprecated
+ protected void setScriptSourceRoots( List<String> scriptSourceRoots )
+ {
+ this.scriptSourceRoots = scriptSourceRoots;
+ }
+
+ @Deprecated
+ public void addScriptSourceRoot( String path )
+ {
+ if ( path != null )
+ {
+ path = path.trim();
+ if ( path.length() != 0 )
+ {
+ if ( !getScriptSourceRoots().contains( path ) )
+ {
+ getScriptSourceRoots().add( path );
+ }
+ }
+ }
+ }
+
+ @Deprecated
+ public List<String> getScriptSourceRoots()
+ {
+ return scriptSourceRoots;
+ }
+
+ @Deprecated
+ public List<Artifact> getCompileArtifacts()
+ {
+ List<Artifact> list = new ArrayList<Artifact>( getArtifacts().size() );
+
+ for ( Artifact a : getArtifacts() )
+ {
+ // TODO: classpath check doesn't belong here - that's the other method
+ if ( a.getArtifactHandler().isAddedToClasspath() )
+ {
+ // TODO: let the scope handler deal with this
+ if ( Artifact.SCOPE_COMPILE.equals( a.getScope() ) || Artifact.SCOPE_PROVIDED.equals( a.getScope() )
+ || Artifact.SCOPE_SYSTEM.equals( a.getScope() ) )
+ {
+ list.add( a );
+ }
+ }
+ }
+ return list;
+ }
+
+ @Deprecated
+ public List<Dependency> getCompileDependencies()
+ {
+ Set<Artifact> artifacts = getArtifacts();
+
+ if ( ( artifacts == null ) || artifacts.isEmpty() )
+ {
+ return Collections.emptyList();
+ }
+
+ List<Dependency> list = new ArrayList<Dependency>( artifacts.size() );
+
+ for ( Artifact a : getArtifacts() )
+ {
+ // TODO: let the scope handler deal with this
+ if ( Artifact.SCOPE_COMPILE.equals( a.getScope() ) || Artifact.SCOPE_PROVIDED.equals( a.getScope() )
+ || Artifact.SCOPE_SYSTEM.equals( a.getScope() ) )
+ {
+ Dependency dependency = new Dependency();
+
+ dependency.setArtifactId( a.getArtifactId() );
+ dependency.setGroupId( a.getGroupId() );
+ dependency.setVersion( a.getVersion() );
+ dependency.setScope( a.getScope() );
+ dependency.setType( a.getType() );
+ dependency.setClassifier( a.getClassifier() );
+
+ list.add( dependency );
+ }
+ }
+ return list;
+ }
+
+ @Deprecated
+ public List<Artifact> getTestArtifacts()
+ {
+ List<Artifact> list = new ArrayList<Artifact>( getArtifacts().size() );
+
+ for ( Artifact a : getArtifacts() )
+ {
+ // TODO: classpath check doesn't belong here - that's the other method
+ if ( a.getArtifactHandler().isAddedToClasspath() )
+ {
+ list.add( a );
+ }
+ }
+ return list;
+ }
+
+ @Deprecated
+ public List<Dependency> getTestDependencies()
+ {
+ Set<Artifact> artifacts = getArtifacts();
+
+ if ( ( artifacts == null ) || artifacts.isEmpty() )
+ {
+ return Collections.emptyList();
+ }
+
+ List<Dependency> list = new ArrayList<Dependency>( artifacts.size() );
+
+ for ( Artifact a : getArtifacts() )
+ {
+ Dependency dependency = new Dependency();
+
+ dependency.setArtifactId( a.getArtifactId() );
+ dependency.setGroupId( a.getGroupId() );
+ dependency.setVersion( a.getVersion() );
+ dependency.setScope( a.getScope() );
+ dependency.setType( a.getType() );
+ dependency.setClassifier( a.getClassifier() );
+
+ list.add( dependency );
+ }
+ return list;
+ }
+
+ @Deprecated // used by the Maven ITs
+ public List<Dependency> getRuntimeDependencies()
+ {
+ Set<Artifact> artifacts = getArtifacts();
+
+ if ( ( artifacts == null ) || artifacts.isEmpty() )
+ {
+ return Collections.emptyList();
+ }
+
+ List<Dependency> list = new ArrayList<Dependency>( artifacts.size() );
+
+ for ( Artifact a : getArtifacts() )
+ {
+ // TODO: let the scope handler deal with this
+ if ( Artifact.SCOPE_COMPILE.equals( a.getScope() ) || Artifact.SCOPE_RUNTIME.equals( a.getScope() ) )
+ {
+ Dependency dependency = new Dependency();
+
+ dependency.setArtifactId( a.getArtifactId() );
+ dependency.setGroupId( a.getGroupId() );
+ dependency.setVersion( a.getVersion() );
+ dependency.setScope( a.getScope() );
+ dependency.setType( a.getType() );
+ dependency.setClassifier( a.getClassifier() );
+
+ list.add( dependency );
+ }
+ }
+ return list;
+ }
+
+ @Deprecated
+ public List<Artifact> getRuntimeArtifacts()
+ {
+ List<Artifact> list = new ArrayList<Artifact>( getArtifacts().size() );
+
+ for ( Artifact a : getArtifacts() )
+ {
+ // TODO: classpath check doesn't belong here - that's the other method
+ if ( a.getArtifactHandler().isAddedToClasspath()
+ // TODO: let the scope handler deal with this
+ && ( Artifact.SCOPE_COMPILE.equals( a.getScope() ) || Artifact.SCOPE_RUNTIME.equals( a.getScope() ) ) )
+ {
+ list.add( a );
+ }
+ }
+ return list;
+ }
+
+ @Deprecated
+ public List<String> getSystemClasspathElements()
+ throws DependencyResolutionRequiredException
+ {
+ List<String> list = new ArrayList<String>( getArtifacts().size() );
+
+ String d = getBuild().getOutputDirectory();
+ if ( d != null )
+ {
+ list.add( d );
+ }
+
+ for ( Artifact a : getArtifacts() )
+ {
+ if ( a.getArtifactHandler().isAddedToClasspath() )
+ {
+ // TODO: let the scope handler deal with this
+ if ( Artifact.SCOPE_SYSTEM.equals( a.getScope() ) )
+ {
+ addArtifactPath( a, list );
+ }
+ }
+ }
+ return list;
+ }
+
+ @Deprecated
+ public List<Artifact> getSystemArtifacts()
+ {
+ List<Artifact> list = new ArrayList<Artifact>( getArtifacts().size() );
+
+ for ( Artifact a : getArtifacts() )
+ {
+ // TODO: classpath check doesn't belong here - that's the other method
+ if ( a.getArtifactHandler().isAddedToClasspath() )
+ {
+ // TODO: let the scope handler deal with this
+ if ( Artifact.SCOPE_SYSTEM.equals( a.getScope() ) )
+ {
+ list.add( a );
+ }
+ }
+ }
+ return list;
+ }
+
+ @Deprecated
+ public List<Dependency> getSystemDependencies()
+ {
+ Set<Artifact> artifacts = getArtifacts();
+
+ if ( ( artifacts == null ) || artifacts.isEmpty() )
+ {
+ return Collections.emptyList();
+ }
+
+ List<Dependency> list = new ArrayList<Dependency>( artifacts.size() );
+
+ for ( Artifact a : getArtifacts() )
+ {
+ // TODO: let the scope handler deal with this
+ if ( Artifact.SCOPE_SYSTEM.equals( a.getScope() ) )
+ {
+ Dependency dependency = new Dependency();
+
+ dependency.setArtifactId( a.getArtifactId() );
+ dependency.setGroupId( a.getGroupId() );
+ dependency.setVersion( a.getVersion() );
+ dependency.setScope( a.getScope() );
+ dependency.setType( a.getType() );
+ dependency.setClassifier( a.getClassifier() );
+
+ list.add( dependency );
+ }
+ }
+ return list;
+ }
+
+ @Deprecated
+ public void setReporting( Reporting reporting )
+ {
+ getModel().setReporting( reporting );
+ }
+
+ @Deprecated
+ public Reporting getReporting()
+ {
+ return getModel().getReporting();
+ }
+
+ @Deprecated
+ public void setReportArtifacts( Set<Artifact> reportArtifacts )
+ {
+ this.reportArtifacts = reportArtifacts;
+
+ reportArtifactMap = null;
+ }
+
+ @Deprecated
+ public Set<Artifact> getReportArtifacts()
+ {
+ return reportArtifacts;
+ }
+
+ @Deprecated
+ public Map<String, Artifact> getReportArtifactMap()
+ {
+ if ( reportArtifactMap == null )
+ {
+ reportArtifactMap = ArtifactUtils.artifactMapByVersionlessId( getReportArtifacts() );
+ }
+
+ return reportArtifactMap;
+ }
+
+ @Deprecated
+ public void setExtensionArtifacts( Set<Artifact> extensionArtifacts )
+ {
+ this.extensionArtifacts = extensionArtifacts;
+
+ extensionArtifactMap = null;
+ }
+
+ @Deprecated
+ public Set<Artifact> getExtensionArtifacts()
+ {
+ return extensionArtifacts;
+ }
+
+ @Deprecated
+ public Map<String, Artifact> getExtensionArtifactMap()
+ {
+ if ( extensionArtifactMap == null )
+ {
+ extensionArtifactMap = ArtifactUtils.artifactMapByVersionlessId( getExtensionArtifacts() );
+ }
+
+ return extensionArtifactMap;
+ }
+
+ @Deprecated
+ public List<ReportPlugin> getReportPlugins()
+ {
+ if ( getModel().getReporting() == null )
+ {
+ return Collections.emptyList();
+ }
+ return getModel().getReporting().getPlugins();
+
+ }
+
+ @Deprecated
+ public Xpp3Dom getReportConfiguration( String pluginGroupId, String pluginArtifactId, String reportSetId )
+ {
+ Xpp3Dom dom = null;
+
+ // ----------------------------------------------------------------------
+ // I would like to be able to lookup the Mojo object using a key but
+ // we have a limitation in modello that will be remedied shortly. So
+ // for now I have to iterate through and see what we have.
+ // ----------------------------------------------------------------------
+
+ if ( getReportPlugins() != null )
+ {
+ for ( ReportPlugin plugin : getReportPlugins() )
+ {
+ if ( pluginGroupId.equals( plugin.getGroupId() ) && pluginArtifactId.equals( plugin.getArtifactId() ) )
+ {
+ dom = (Xpp3Dom) plugin.getConfiguration();
+
+ if ( reportSetId != null )
+ {
+ ReportSet reportSet = plugin.getReportSetsAsMap().get( reportSetId );
+ if ( reportSet != null )
+ {
+ Xpp3Dom executionConfiguration = (Xpp3Dom) reportSet.getConfiguration();
+ if ( executionConfiguration != null )
+ {
+ Xpp3Dom newDom = new Xpp3Dom( executionConfiguration );
+ dom = Xpp3Dom.mergeXpp3Dom( newDom, dom );
+ }
+ }
+ }
+ break;
+ }
+ }
+ }
+
+ if ( dom != null )
+ {
+ // make a copy so the original in the POM doesn't get messed with
+ dom = new Xpp3Dom( dom );
+ }
+
+ return dom;
+ }
+
+ /**
+ * @deprecated Use MavenProjectHelper.attachArtifact(..) instead.
+ */
+ @Deprecated
+ public void attachArtifact( String type, String classifier, File file )
+ {
+ }
+
+ /**
+ * @deprecated Use {@link org.apache.maven.model.io.ModelWriter}.
+ */
+ @Deprecated
+ public void writeModel( Writer writer )
+ throws IOException
+ {
+ MavenXpp3Writer pomWriter = new MavenXpp3Writer();
+ pomWriter.write( writer, getModel() );
+ }
+
+ /**
+ * @deprecated Use {@link org.apache.maven.model.io.ModelWriter}.
+ */
+ @Deprecated
+ public void writeOriginalModel( Writer writer )
+ throws IOException
+ {
+ MavenXpp3Writer pomWriter = new MavenXpp3Writer();
+ pomWriter.write( writer, getOriginalModel() );
+ }
+
+ @Deprecated
+ public Artifact replaceWithActiveArtifact( Artifact pluginArtifact )
+ {
+ return pluginArtifact;
+ }
+
+ /**
+ * Gets the project building request from which this project instance was created. <strong>Warning:</strong> This is
+ * an utility method that is meant to assist integrators of Maven, it must not be used by Maven plugins.
+ *
+ * @return The project building request or {@code null}.
+ * @since 2.1
+ */
+ @Deprecated
+ public ProjectBuildingRequest getProjectBuildingRequest()
+ {
+ return projectBuilderConfiguration;
+ }
+
+ /**
+ * Sets the project building request from which this project instance was created. <strong>Warning:</strong> This is
+ * an utility method that is meant to assist integrators of Maven, it must not be used by Maven plugins.
+ *
+ * @param projectBuildingRequest The project building request, may be {@code null}.
+ * @since 2.1
+ */
+ // used by maven-dependency-tree
+ @Deprecated
+ public void setProjectBuildingRequest( ProjectBuildingRequest projectBuildingRequest )
+ {
+ this.projectBuilderConfiguration = projectBuildingRequest;
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/MavenProjectHelper.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/MavenProjectHelper.java
new file mode 100644
index 00000000..0b54c004
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/MavenProjectHelper.java
@@ -0,0 +1,76 @@
+package org.apache.maven.project;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.util.List;
+
+/**
+ * Convenience interface for plugins to add or replace artifacts and resources on projects.
+ */
+public interface MavenProjectHelper
+{
+ String ROLE = MavenProjectHelper.class.getName();
+
+ /**
+ * See {@link #attachArtifact(MavenProject, String, String, java.io.File)}, but with type set to null.
+ * @param project project reference.
+ * @param artifactFile artifact file.
+ * @param artifactClassifier artifact classifier.
+ */
+ void attachArtifact( MavenProject project, File artifactFile, String artifactClassifier );
+
+ /**
+ * * See {@link #attachArtifact(MavenProject, String, String, java.io.File)}, but with classifier set to null.
+ * @param project project reference.
+ * @param artifactType artifact type.
+ * @param artifactFile arrifact file.
+ */
+ void attachArtifact( MavenProject project, String artifactType, File artifactFile );
+
+ /**
+ * Add or replace an artifact to the current project.
+ * @param project the project reference.
+ * @param artifactType the type (e.g. jar) or null.
+ * @param artifactClassifier the classifier or null.
+ * @param artifactFile the file for the artifact.
+ */
+ void attachArtifact( MavenProject project, String artifactType, String artifactClassifier, File artifactFile );
+
+ /**
+ * Add a resource directory to the project.
+ * @param project project reference.
+ * @param resourceDirectory directory.
+ * @param includes include patterns.
+ * @param excludes exclude patterns.
+ */
+ void addResource( MavenProject project, String resourceDirectory, List<String> includes, List<String> excludes );
+
+ /**
+ * Add a test resource directory to the project.
+ * @param project project reference.
+ * @param resourceDirectory directory.
+ * @param includes include patterns.
+ * @param excludes exclude patterns.
+ */
+ void addTestResource( MavenProject project, String resourceDirectory, List<String> includes,
+ List<String> excludes );
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/ProjectBuilder.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/ProjectBuilder.java
new file mode 100644
index 00000000..4ac83972
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/ProjectBuilder.java
@@ -0,0 +1,98 @@
+package org.apache.maven.project;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.util.List;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.model.building.ModelSource;
+
+/**
+ * Builds in-memory descriptions of projects.
+ */
+public interface ProjectBuilder
+{
+
+ /**
+ * Builds a project descriptor from the specified POM file.
+ *
+ * @param projectFile The POM file to build the project from, must not be {@code null}.
+ * @param request The project building request that holds further parameters, must not be {@code null}.
+ * @return The result of the project building, never {@code null}.
+ * @throws ProjectBuildingException If the project descriptor could not be successfully built.
+ */
+ ProjectBuildingResult build( File projectFile, ProjectBuildingRequest request )
+ throws ProjectBuildingException;
+
+ /**
+ * Builds a project descriptor for the specified artifact.
+ *
+ * @param projectArtifact The POM artifact to build the project from, must not be {@code null}.
+ * @param request The project building request that holds further parameters, must not be {@code null}.
+ * @return The result of the project building, never {@code null}.
+ * @throws ProjectBuildingException If the project descriptor could not be successfully built.
+ */
+ ProjectBuildingResult build( Artifact projectArtifact, ProjectBuildingRequest request )
+ throws ProjectBuildingException;
+
+ /**
+ * Builds a project descriptor for the specified artifact.
+ *
+ * @param projectArtifact The POM artifact to build the project from, must not be {@code null}.
+ * @param allowStubModel A flag controlling the case of a missing POM artifact. If {@code true} and the specified
+ * POM artifact does not exist, a simple stub model will be returned. If {@code false}, an exception will
+ * be thrown.
+ * @param request The project building request that holds further parameters, must not be {@code null}.
+ * @return The result of the project building, never {@code null}.
+ * @throws ProjectBuildingException If the project descriptor could not be successfully built.
+ */
+ ProjectBuildingResult build( Artifact projectArtifact, boolean allowStubModel, ProjectBuildingRequest request )
+ throws ProjectBuildingException;
+
+ /**
+ * Builds a project descriptor for the specified model source.
+ *
+ * @param modelSource The source of the model to built the project descriptor from, must not be {@code null}.
+ * @param request The project building request that holds further parameters, must not be {@code null}.
+ * @return The result of the project building, never {@code null}.
+ * @throws ProjectBuildingException If the project descriptor could not be successfully built.
+ *
+ * @see org.apache.maven.model.building.ModelSource2
+ */
+ ProjectBuildingResult build( ModelSource modelSource, ProjectBuildingRequest request )
+ throws ProjectBuildingException;
+
+ /**
+ * Builds the projects for the specified POM files and optionally their children.
+ *
+ * @param pomFiles The POM files to build, must not be {@code null}.
+ * @param recursive {@code true} to recursively build sub modules referenced by the POM files, {@code false} to
+ * build only the specified POM files.
+ * @param request The project builder configuration that provides further parameters, must not be {@code null}.
+ * @return The results of the project builder where each result corresponds to one project that was built, never
+ * {@code null}.
+ * @throws ProjectBuildingException If an error was encountered during building of any project.
+ * {@link ProjectBuildingException#getResults()} provides access to the details of the problems.
+ */
+ List<ProjectBuildingResult> build( List<File> pomFiles, boolean recursive, ProjectBuildingRequest request )
+ throws ProjectBuildingException;
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/ProjectBuildingException.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/ProjectBuildingException.java
new file mode 100644
index 00000000..47c12315
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/ProjectBuildingException.java
@@ -0,0 +1,145 @@
+package org.apache.maven.project;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.List;
+
+import org.apache.maven.model.building.ModelProblem;
+import org.apache.maven.model.building.ModelProblemUtils;
+
+/**
+ * @author Jason van Zyl
+ */
+public class ProjectBuildingException
+ extends Exception
+{
+ private final String projectId;
+
+ private File pomFile;
+
+ private List<ProjectBuildingResult> results;
+
+ public ProjectBuildingException( String projectId, String message, Throwable cause )
+ {
+ super( createMessage( message, projectId, null ), cause );
+ this.projectId = projectId;
+ }
+
+ /**
+ * @param projectId
+ * @param message
+ * @param pomFile pom file location
+ */
+ public ProjectBuildingException( String projectId, String message, File pomFile )
+ {
+ super( createMessage( message, projectId, pomFile ) );
+ this.projectId = projectId;
+ this.pomFile = pomFile;
+ }
+
+ /**
+ * @param projectId
+ * @param message
+ * @param pomFile pom file location
+ * @param cause
+ */
+ protected ProjectBuildingException( String projectId, String message, File pomFile, Throwable cause )
+ {
+ super( createMessage( message, projectId, pomFile ), cause );
+ this.projectId = projectId;
+ this.pomFile = pomFile;
+ }
+
+ public ProjectBuildingException( List<ProjectBuildingResult> results )
+ {
+ super( createMessage( results ) );
+ this.projectId = "";
+ this.results = results;
+ }
+
+ public File getPomFile()
+ {
+ return pomFile;
+ }
+
+ /**
+ * @deprecated use {@link #getPomFile()}
+ */
+ public String getPomLocation()
+ {
+ if ( getPomFile() != null )
+ {
+ return getPomFile().getAbsolutePath();
+ }
+ else
+ {
+ return "null";
+ }
+ }
+
+ public String getProjectId()
+ {
+ return projectId;
+ }
+
+ public List<ProjectBuildingResult> getResults()
+ {
+ return results;
+ }
+
+ private static String createMessage( String message, String projectId, File pomFile )
+ {
+ StringBuilder buffer = new StringBuilder( 256 );
+ buffer.append( message );
+ buffer.append( " for project " ).append( projectId );
+ if ( pomFile != null )
+ {
+ buffer.append( " at " ).append( pomFile.getAbsolutePath() );
+ }
+ return buffer.toString();
+ }
+
+ private static String createMessage( List<ProjectBuildingResult> results )
+ {
+ StringWriter buffer = new StringWriter( 1024 );
+
+ PrintWriter writer = new PrintWriter( buffer );
+ writer.println( "Some problems were encountered while processing the POMs:" );
+ for ( ProjectBuildingResult result : results )
+ {
+ for ( ModelProblem problem : result.getProblems() )
+ {
+ writer.print( "[" );
+ writer.print( problem.getSeverity() );
+ writer.print( "] " );
+ writer.print( problem.getMessage() );
+ writer.print( " @ " );
+ writer.println( ModelProblemUtils.formatLocation( problem, result.getProjectId() ) );
+ }
+ }
+ writer.close();
+
+ return buffer.toString();
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/ProjectBuildingHelper.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/ProjectBuildingHelper.java
new file mode 100644
index 00000000..45fff6e6
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/ProjectBuildingHelper.java
@@ -0,0 +1,81 @@
+package org.apache.maven.project;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.List;
+
+import org.apache.maven.artifact.InvalidRepositoryException;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.model.Model;
+import org.apache.maven.model.Repository;
+import org.apache.maven.plugin.PluginManagerException;
+import org.apache.maven.plugin.PluginResolutionException;
+import org.apache.maven.plugin.version.PluginVersionResolutionException;
+
+/**
+ * Assists the project builder. <strong>Warning:</strong> This is an internal utility interface that is only public for
+ * technical reasons, it is not part of the public API. In particular, this interface can be changed or deleted without
+ * prior notice.
+ *
+ * @author Benjamin Bentmann
+ */
+public interface ProjectBuildingHelper
+{
+
+ /**
+ * Creates the effective artifact repositories from the specified POM repositories.
+ *
+ * @param pomRepositories The POM repositories to create the artifact repositories from, must not be {@code null}.
+ * @param externalRepositories The external (and already mirrored) repositories to merge into the result list, may
+ * be {@code null}.
+ * @param request The project building request holding further settings like repository settings, must not be
+ * {@code null}.
+ * @return The effective artifact repositories, never {@code null}.
+ * @throws InvalidRepositoryException
+ */
+ List<ArtifactRepository> createArtifactRepositories( List<Repository> pomRepositories,
+ List<ArtifactRepository> externalRepositories,
+ ProjectBuildingRequest request )
+ throws InvalidRepositoryException;
+
+ /**
+ * Creates the project realm that hosts the build extensions of the specified model.
+ *
+ * @param project The project to create the project realm for, must not be {@code null}
+ * @param model The model to create the project realm for, must not be {@code null}
+ * @param request The project building request holding further settings like repository settings, must not be
+ * {@code null}.
+ * @return The record with the project realm and extension artifact filter, never {@code null}.
+ * @throws PluginResolutionException If any build extension could not be resolved.
+ */
+ ProjectRealmCache.CacheRecord createProjectRealm( MavenProject project, Model model,
+ ProjectBuildingRequest request )
+ throws PluginResolutionException, PluginVersionResolutionException, PluginManagerException;
+
+ /**
+ * Updates the context class loader such that the container will search the project realm when the model builder
+ * injects the lifecycle bindings from the packaging in the next step. The context class loader is to be reset by
+ * the project builder when the project is fully assembled.
+ *
+ * @param project The project whose class realm should be selected, must not be {@code null}.
+ */
+ void selectProjectRealm( MavenProject project );
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/ProjectBuildingRequest.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/ProjectBuildingRequest.java
new file mode 100644
index 00000000..0380278b
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/ProjectBuildingRequest.java
@@ -0,0 +1,194 @@
+package org.apache.maven.project;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Date;
+import java.util.List;
+import java.util.Properties;
+
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.model.Profile;
+import org.eclipse.aether.RepositorySystemSession;
+
+public interface ProjectBuildingRequest
+{
+
+ ProjectBuildingRequest setLocalRepository( ArtifactRepository localRepository );
+
+ ArtifactRepository getLocalRepository();
+
+ ProjectBuildingRequest setRemoteRepositories( List<ArtifactRepository> remoteRepositories );
+
+ List<ArtifactRepository> getRemoteRepositories();
+
+ ProjectBuildingRequest setPluginArtifactRepositories( List<ArtifactRepository> pluginArtifacgRepositories );
+
+ List<ArtifactRepository> getPluginArtifactRepositories();
+
+ /**
+ * Sets the system properties to use for interpolation and profile activation. The system properties are collected
+ * from the runtime environment like {@link System#getProperties()} and environment variables.
+ *
+ * @param systemProperties The system properties, may be {@code null}.
+ * @return This request, never {@code null}.
+ */
+ ProjectBuildingRequest setSystemProperties( Properties systemProperties );
+
+ /**
+ * Gets the system properties to use for interpolation and profile activation. The system properties are collected
+ * from the runtime environment like {@link System#getProperties()} and environment variables.
+ *
+ * @return The system properties, never {@code null}.
+ */
+ Properties getSystemProperties();
+
+ /**
+ * Sets the user properties to use for interpolation and profile activation. The user properties have been
+ * configured directly by the user on his discretion, e.g. via the {@code -Dkey=value} parameter on the command
+ * line.
+ *
+ * @param userProperties The user properties, may be {@code null}.
+ * @return This request, never {@code null}.
+ */
+ ProjectBuildingRequest setUserProperties( Properties userProperties );
+
+ /**
+ * Gets the user properties to use for interpolation and profile activation. The user properties have been
+ * configured directly by the user on his discretion, e.g. via the {@code -Dkey=value} parameter on the command
+ * line.
+ *
+ * @return The user properties, never {@code null}.
+ */
+ Properties getUserProperties();
+
+ void setProject( MavenProject mavenProject );
+
+ MavenProject getProject();
+
+ ProjectBuildingRequest setProcessPlugins( boolean processPlugins );
+
+ boolean isProcessPlugins();
+
+ ProjectBuildingRequest setResolveDependencies( boolean resolveDependencies );
+
+ boolean isResolveDependencies();
+
+ /**
+ * Controls the level of validation to perform on processed models. By default, models are validated in strict mode.
+ *
+ * @param validationLevel The level of validation to perform on processed models, e.g.
+ * {@link org.apache.maven.model.building.ModelBuildingRequest#VALIDATION_LEVEL_STRICT}.
+ * @return This configuration, never {@code null}.
+ */
+ ProjectBuildingRequest setValidationLevel( int validationLevel );
+
+ /**
+ * Gets the level of validation to perform on processed models.
+ *
+ * @return The level of validation to perform on processed models.
+ */
+ int getValidationLevel();
+
+ // Profiles
+
+ /**
+ * Set any active profiles that the {@link ProjectBuilder} should consider while constructing
+ * a {@link MavenProject}.
+ */
+ void setActiveProfileIds( List<String> activeProfileIds );
+
+ List<String> getActiveProfileIds();
+
+ void setInactiveProfileIds( List<String> inactiveProfileIds );
+
+ List<String> getInactiveProfileIds();
+
+ /**
+ * Add a {@link org.apache.maven.model.Profile} that has come from an external source. This may be from a custom
+ * configuration like the MavenCLI settings.xml file, or from a custom dialog in an IDE integration like M2Eclipse.
+ *
+ * @param profile
+ */
+ void addProfile( Profile profile );
+
+ void setProfiles( List<Profile> profiles );
+
+ List<Profile> getProfiles();
+
+ /**
+ * Gets the start time of the build.
+ *
+ * @return The start time of the build or {@code null} if unknown.
+ */
+ Date getBuildStartTime();
+
+ /**
+ * Sets the start time of the build.
+ *
+ * @param buildStartTime The start time of the build, may be {@code null}.
+ */
+ void setBuildStartTime( Date buildStartTime );
+
+ RepositorySystemSession getRepositorySession();
+
+ ProjectBuildingRequest setRepositorySession( RepositorySystemSession repositorySession );
+
+ /**
+ * Sets the merge mode used to combine repositories declared in the POM with the repositories specified in this
+ * request.
+ *
+ * @param mode The repository merge mode, must not be {@code null}.
+ * @return This request for chaining, never {@code null}.
+ * @see #setRemoteRepositories(List)
+ */
+ ProjectBuildingRequest setRepositoryMerging( RepositoryMerging mode );
+
+ /**
+ * Gets the merge mode used to combine repositories declared in the POM with the repositories specified in this
+ * request
+ *
+ * @return The merge mode, never {@code null}.
+ */
+ RepositoryMerging getRepositoryMerging();
+
+ /** @since 3.2.2 */
+ boolean isResolveVersionRanges();
+
+ /** @since 3.2.2 */
+ ProjectBuildingRequest setResolveVersionRanges( boolean value );
+
+ /**
+ * The possible merge modes for combining remote repositories.
+ */
+ enum RepositoryMerging
+ {
+
+ /**
+ * The repositories declared in the POM have precedence over the repositories specified in the request.
+ */
+ POM_DOMINANT,
+
+ /**
+ * The repositories specified in the request have precedence over the repositories declared in the POM.
+ */
+ REQUEST_DOMINANT,
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/ProjectBuildingResult.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/ProjectBuildingResult.java
new file mode 100644
index 00000000..9a43154c
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/ProjectBuildingResult.java
@@ -0,0 +1,74 @@
+package org.apache.maven.project;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.util.List;
+
+import org.apache.maven.model.building.ModelProblem;
+
+/**
+ * Collects the output of the project builder.
+ *
+ * @author Benjamin Bentmann
+ */
+public interface ProjectBuildingResult
+{
+
+ /**
+ * Gets the identifier of the project that could not be built. The general format of the identifier is {@code
+ * <groupId>:<artifactId>:<version>} but some of these coordinates may still be unknown at the point the exception
+ * is thrown so this information is merely meant to assist the user.
+ *
+ * @return The identifier of the project or an empty string if not known, never {@code null}.
+ */
+ String getProjectId();
+
+ /**
+ * Gets the POM file from which the project was built.
+ *
+ * @return The POM file or {@code null} if unknown.
+ */
+ File getPomFile();
+
+ /**
+ * Gets the project that was built.
+ *
+ * @return The project that was built or {@code null} if an error occurred and this result accompanies a
+ * {@link ProjectBuildingException}.
+ */
+ MavenProject getProject();
+
+ /**
+ * Gets the problems that were encountered during the project building.
+ *
+ * @return The problems that were encountered during the project building, can be empty but never {@code null}.
+ */
+ List<ModelProblem> getProblems();
+
+ /**
+ * Gets the result of the dependency resolution for the project.
+ *
+ * @return The result of the dependency resolution for the project or {@code null} if the project dependencies were
+ * not requested.
+ */
+ DependencyResolutionResult getDependencyResolutionResult();
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/ProjectDependenciesResolver.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/ProjectDependenciesResolver.java
new file mode 100644
index 00000000..539055ca
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/ProjectDependenciesResolver.java
@@ -0,0 +1,40 @@
+package org.apache.maven.project;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Resolves the transitive dependencies of a project.
+ *
+ * @author Benjamin Bentmann
+ */
+public interface ProjectDependenciesResolver
+{
+
+ /**
+ * Resolves the transitive dependencies of a project.
+ *
+ * @param request The resolution request holding the parameters, must not be {@code null}.
+ * @return The resolution result, never {@code null}.
+ * @throws DependencyResolutionException If any project dependency could not be resolved.
+ */
+ DependencyResolutionResult resolve( DependencyResolutionRequest request )
+ throws DependencyResolutionException;
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/ProjectModelResolver.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/ProjectModelResolver.java
new file mode 100644
index 00000000..3e33eb57
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/ProjectModelResolver.java
@@ -0,0 +1,248 @@
+package org.apache.maven.project;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import com.google.common.base.Predicate;
+import com.google.common.collect.Iterables;
+
+import org.apache.maven.model.Parent;
+import org.apache.maven.model.Repository;
+import org.apache.maven.model.building.FileModelSource;
+import org.apache.maven.model.building.ModelSource;
+import org.apache.maven.model.resolution.InvalidRepositoryException;
+import org.apache.maven.model.resolution.ModelResolver;
+import org.apache.maven.model.resolution.UnresolvableModelException;
+import org.apache.maven.repository.internal.ArtifactDescriptorUtils;
+import org.eclipse.aether.RepositorySystem;
+import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.RequestTrace;
+import org.eclipse.aether.artifact.Artifact;
+import org.eclipse.aether.artifact.DefaultArtifact;
+import org.eclipse.aether.impl.RemoteRepositoryManager;
+import org.eclipse.aether.repository.RemoteRepository;
+import org.eclipse.aether.resolution.ArtifactRequest;
+import org.eclipse.aether.resolution.ArtifactResolutionException;
+import org.eclipse.aether.resolution.VersionRangeRequest;
+import org.eclipse.aether.resolution.VersionRangeResolutionException;
+import org.eclipse.aether.resolution.VersionRangeResult;
+
+/**
+ * A model resolver to assist building of projects. This resolver gives priority to those repositories that have been
+ * declared in the POM.
+ *
+ * @author Benjamin Bentmann
+ */
+public class ProjectModelResolver
+ implements ModelResolver
+{
+
+ private final RepositorySystemSession session;
+
+ private final RequestTrace trace;
+
+ private final String context = "project";
+
+ private List<RemoteRepository> repositories;
+
+ private List<RemoteRepository> pomRepositories;
+
+ private final List<RemoteRepository> externalRepositories;
+
+ private final RepositorySystem resolver;
+
+ private final RemoteRepositoryManager remoteRepositoryManager;
+
+ private final Set<String> repositoryIds;
+
+ private final ReactorModelPool modelPool;
+
+ private final ProjectBuildingRequest.RepositoryMerging repositoryMerging;
+
+ public ProjectModelResolver( RepositorySystemSession session, RequestTrace trace, RepositorySystem resolver,
+ RemoteRepositoryManager remoteRepositoryManager, List<RemoteRepository> repositories,
+ ProjectBuildingRequest.RepositoryMerging repositoryMerging,
+ ReactorModelPool modelPool )
+ {
+ this.session = session;
+ this.trace = trace;
+ this.resolver = resolver;
+ this.remoteRepositoryManager = remoteRepositoryManager;
+ this.pomRepositories = new ArrayList<RemoteRepository>();
+ List<RemoteRepository> externalRepositories = new ArrayList<RemoteRepository>();
+ externalRepositories.addAll( repositories );
+ this.externalRepositories = Collections.unmodifiableList( externalRepositories );
+ this.repositories = new ArrayList<RemoteRepository>();
+ this.repositories.addAll( externalRepositories );
+ this.repositoryMerging = repositoryMerging;
+ this.repositoryIds = new HashSet<String>();
+ this.modelPool = modelPool;
+ }
+
+ private ProjectModelResolver( ProjectModelResolver original )
+ {
+ this.session = original.session;
+ this.trace = original.trace;
+ this.resolver = original.resolver;
+ this.remoteRepositoryManager = original.remoteRepositoryManager;
+ this.pomRepositories = new ArrayList<RemoteRepository>( original.pomRepositories );
+ this.externalRepositories = original.externalRepositories;
+ this.repositories = new ArrayList<RemoteRepository>( original.repositories );
+ this.repositoryMerging = original.repositoryMerging;
+ this.repositoryIds = new HashSet<String>( original.repositoryIds );
+ this.modelPool = original.modelPool;
+ }
+
+ public void addRepository( Repository repository )
+ throws InvalidRepositoryException
+ {
+ addRepository( repository, false );
+ }
+
+ @Override
+ public void addRepository( final Repository repository, boolean replace )
+ throws InvalidRepositoryException
+ {
+ if ( !repositoryIds.add( repository.getId() ) )
+ {
+ if ( !replace )
+ {
+ return;
+ }
+
+ // Remove any previous repository with this Id
+ removeMatchingRepository( repositories, repository.getId() );
+ removeMatchingRepository( pomRepositories, repository.getId() );
+ }
+
+ List<RemoteRepository> newRepositories =
+ Collections.singletonList( ArtifactDescriptorUtils.toRemoteRepository( repository ) );
+
+ if ( ProjectBuildingRequest.RepositoryMerging.REQUEST_DOMINANT.equals( repositoryMerging ) )
+ {
+ repositories = remoteRepositoryManager.aggregateRepositories( session, repositories, newRepositories,
+ true );
+ }
+ else
+ {
+ pomRepositories =
+ remoteRepositoryManager.aggregateRepositories( session, pomRepositories, newRepositories, true );
+ repositories =
+ remoteRepositoryManager.aggregateRepositories( session, pomRepositories, externalRepositories, false );
+ }
+ }
+
+ private static void removeMatchingRepository( Iterable<RemoteRepository> repositories, final String id )
+ {
+ Iterables.removeIf( repositories, new Predicate<RemoteRepository>()
+ {
+ @Override
+ public boolean apply( RemoteRepository remoteRepository )
+ {
+ return remoteRepository.getId().equals( id );
+ }
+ } );
+ }
+
+ public ModelResolver newCopy()
+ {
+ return new ProjectModelResolver( this );
+ }
+
+ public ModelSource resolveModel( String groupId, String artifactId, String version )
+ throws UnresolvableModelException
+ {
+ File pomFile = null;
+
+ if ( modelPool != null )
+ {
+ pomFile = modelPool.get( groupId, artifactId, version );
+ }
+
+ if ( pomFile == null )
+ {
+ Artifact pomArtifact = new DefaultArtifact( groupId, artifactId, "", "pom", version );
+
+ try
+ {
+ ArtifactRequest request = new ArtifactRequest( pomArtifact, repositories, context );
+ request.setTrace( trace );
+ pomArtifact = resolver.resolveArtifact( session, request ).getArtifact();
+ }
+ catch ( ArtifactResolutionException e )
+ {
+ throw new UnresolvableModelException( e.getMessage(), groupId, artifactId, version, e );
+ }
+
+ pomFile = pomArtifact.getFile();
+ }
+
+ return new FileModelSource( pomFile );
+ }
+
+ public ModelSource resolveModel( Parent parent )
+ throws UnresolvableModelException
+ {
+ Artifact artifact = new DefaultArtifact( parent.getGroupId(), parent.getArtifactId(), "", "pom",
+ parent.getVersion() );
+
+ VersionRangeRequest versionRangeRequest = new VersionRangeRequest( artifact, repositories, context );
+ versionRangeRequest.setTrace( trace );
+
+ try
+ {
+ VersionRangeResult versionRangeResult = resolver.resolveVersionRange( session, versionRangeRequest );
+
+ if ( versionRangeResult.getHighestVersion() == null )
+ {
+ throw new UnresolvableModelException( "No versions matched the requested range '" + parent.getVersion()
+ + "'", parent.getGroupId(), parent.getArtifactId(),
+ parent.getVersion() );
+
+ }
+
+ if ( versionRangeResult.getVersionConstraint() != null
+ && versionRangeResult.getVersionConstraint().getRange() != null
+ && versionRangeResult.getVersionConstraint().getRange().getUpperBound() == null )
+ {
+ throw new UnresolvableModelException( "The requested version range '" + parent.getVersion()
+ + "' does not specify an upper bound", parent.getGroupId(),
+ parent.getArtifactId(), parent.getVersion() );
+
+ }
+
+ parent.setVersion( versionRangeResult.getHighestVersion().toString() );
+ }
+ catch ( VersionRangeResolutionException e )
+ {
+ throw new UnresolvableModelException( e.getMessage(), parent.getGroupId(), parent.getArtifactId(),
+ parent.getVersion(), e );
+
+ }
+
+ return resolveModel( parent.getGroupId(), parent.getArtifactId(), parent.getVersion() );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/ProjectRealmCache.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/ProjectRealmCache.java
new file mode 100644
index 00000000..9265b894
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/ProjectRealmCache.java
@@ -0,0 +1,79 @@
+package org.apache.maven.project;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.List;
+
+import org.codehaus.plexus.classworlds.realm.ClassRealm;
+import org.eclipse.aether.graph.DependencyFilter;
+
+/**
+ * Caches project class realms. <strong>Warning:</strong> This is an internal utility interface that is only public for
+ * technical reasons, it is not part of the public API. In particular, this interface can be changed or deleted without
+ * prior notice.
+ *
+ * @author Igor Fedorenko
+ * @author Benjamin Bentmann
+ */
+public interface ProjectRealmCache
+{
+
+ /**
+ * A cache key.
+ */
+ interface Key
+ {
+ // marker interface for cache keys
+ }
+
+ static class CacheRecord
+ {
+
+ public final ClassRealm realm;
+
+ public final DependencyFilter extensionArtifactFilter;
+
+ public CacheRecord( ClassRealm realm, DependencyFilter extensionArtifactFilter )
+ {
+ this.realm = realm;
+ this.extensionArtifactFilter = extensionArtifactFilter;
+ }
+
+ }
+
+ Key createKey( List<? extends ClassRealm> extensionRealms );
+
+ CacheRecord get( Key key );
+
+ CacheRecord put( Key key, ClassRealm projectRealm, DependencyFilter extensionArtifactFilter );
+
+ void flush();
+
+ /**
+ * Registers the specified cache record for usage with the given project. Integrators can use the information
+ * collected from this method in combination with a custom cache implementation to dispose unused records from the
+ * cache.
+ *
+ * @param project The project that employs the plugin realm, must not be {@code null}.
+ * @param record The cache record being used for the project, must not be {@code null}.
+ */
+ void register( MavenProject project, Key key, CacheRecord record );
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/ProjectSorter.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/ProjectSorter.java
new file mode 100644
index 00000000..16985e2a
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/ProjectSorter.java
@@ -0,0 +1,289 @@
+package org.apache.maven.project;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.maven.artifact.ArtifactUtils;
+import org.apache.maven.model.Dependency;
+import org.apache.maven.model.Extension;
+import org.apache.maven.model.Parent;
+import org.apache.maven.model.Plugin;
+import org.codehaus.plexus.util.StringUtils;
+import org.codehaus.plexus.util.dag.CycleDetectedException;
+import org.codehaus.plexus.util.dag.DAG;
+import org.codehaus.plexus.util.dag.TopologicalSorter;
+import org.codehaus.plexus.util.dag.Vertex;
+
+public class ProjectSorter
+{
+ private DAG dag;
+
+ private List<MavenProject> sortedProjects;
+
+ private Map<String, MavenProject> projectMap;
+
+ private MavenProject topLevelProject;
+
+ /**
+ * Sort a list of projects.
+ * <ul>
+ * <li>collect all the vertices for the projects that we want to build.</li>
+ * <li>iterate through the deps of each project and if that dep is within
+ * the set of projects we want to build then add an edge, otherwise throw
+ * the edge away because that dependency is not within the set of projects
+ * we are trying to build. we assume a closed set.</li>
+ * <li>do a topo sort on the graph that remains.</li>
+ * </ul>
+ * @throws DuplicateProjectException if any projects are duplicated by id
+ */
+ // MAVENAPI FIXME: the DAG used is NOT only used to represent the dependency relation,
+ // but also for <parent>, <build><plugin>, <reports>. We need multiple DAG's
+ // since a DAG can only handle 1 type of relationship properly.
+ // Usecase: This is detected as a cycle:
+ // org.apache.maven:maven-plugin-api -(PARENT)->
+ // org.apache.maven:maven -(inherited REPORTING)->
+ // org.apache.maven.plugins:maven-checkstyle-plugin -(DEPENDENCY)->
+ // org.apache.maven:maven-plugin-api
+ // In this case, both the verify and the report goals are called
+ // in a different lifecycle. Though the compiler-plugin has a valid usecase, although
+ // that seems to work fine. We need to take versions and lifecycle into account.
+ public ProjectSorter( Collection<MavenProject> projects )
+ throws CycleDetectedException, DuplicateProjectException
+ {
+ dag = new DAG();
+
+ // groupId:artifactId:version -> project
+ projectMap = new HashMap<String, MavenProject>( projects.size() * 2 );
+
+ // groupId:artifactId -> (version -> vertex)
+ Map<String, Map<String, Vertex>> vertexMap = new HashMap<String, Map<String, Vertex>>( projects.size() * 2 );
+
+ for ( MavenProject project : projects )
+ {
+ String projectId = getId( project );
+
+ MavenProject conflictingProject = projectMap.put( projectId, project );
+
+ if ( conflictingProject != null )
+ {
+ throw new DuplicateProjectException( projectId, conflictingProject.getFile(), project.getFile(),
+ "Project '" + projectId + "' is duplicated in the reactor" );
+ }
+
+ String projectKey = ArtifactUtils.versionlessKey( project.getGroupId(), project.getArtifactId() );
+
+ Map<String, Vertex> vertices = vertexMap.get( projectKey );
+ if ( vertices == null )
+ {
+ vertices = new HashMap<String, Vertex>( 2, 1 );
+ vertexMap.put( projectKey, vertices );
+ }
+ vertices.put( project.getVersion(), dag.addVertex( projectId ) );
+ }
+
+ for ( Vertex projectVertex : dag.getVerticies() )
+ {
+ String projectId = projectVertex.getLabel();
+
+ MavenProject project = projectMap.get( projectId );
+
+ for ( Dependency dependency : project.getDependencies() )
+ {
+ addEdge( projectMap, vertexMap, project, projectVertex, dependency.getGroupId(),
+ dependency.getArtifactId(), dependency.getVersion(), false, false );
+ }
+
+ Parent parent = project.getModel().getParent();
+
+ if ( parent != null )
+ {
+ // Parent is added as an edge, but must not cause a cycle - so we remove any other edges it has
+ // in conflict
+ addEdge( projectMap, vertexMap, null, projectVertex, parent.getGroupId(), parent.getArtifactId(),
+ parent.getVersion(), true, false );
+ }
+
+ List<Plugin> buildPlugins = project.getBuildPlugins();
+ if ( buildPlugins != null )
+ {
+ for ( Plugin plugin : buildPlugins )
+ {
+ addEdge( projectMap, vertexMap, project, projectVertex, plugin.getGroupId(),
+ plugin.getArtifactId(), plugin.getVersion(), false, true );
+
+ for ( Dependency dependency : plugin.getDependencies() )
+ {
+ addEdge( projectMap, vertexMap, project, projectVertex, dependency.getGroupId(),
+ dependency.getArtifactId(), dependency.getVersion(), false, true );
+ }
+ }
+ }
+
+ List<Extension> buildExtensions = project.getBuildExtensions();
+ if ( buildExtensions != null )
+ {
+ for ( Extension extension : buildExtensions )
+ {
+ addEdge( projectMap, vertexMap, project, projectVertex, extension.getGroupId(),
+ extension.getArtifactId(), extension.getVersion(), false, true );
+ }
+ }
+ }
+
+ List<MavenProject> sortedProjects = new ArrayList<MavenProject>( projects.size() );
+
+ List<String> sortedProjectLabels = TopologicalSorter.sort( dag );
+
+ for ( String id : sortedProjectLabels )
+ {
+ sortedProjects.add( projectMap.get( id ) );
+ }
+
+ this.sortedProjects = Collections.unmodifiableList( sortedProjects );
+ }
+
+ private void addEdge( Map<String, MavenProject> projectMap, Map<String, Map<String, Vertex>> vertexMap,
+ MavenProject project, Vertex projectVertex, String groupId, String artifactId,
+ String version, boolean force, boolean safe )
+ throws CycleDetectedException
+ {
+ String projectKey = ArtifactUtils.versionlessKey( groupId, artifactId );
+
+ Map<String, Vertex> vertices = vertexMap.get( projectKey );
+
+ if ( vertices != null )
+ {
+ if ( isSpecificVersion( version ) )
+ {
+ Vertex vertex = vertices.get( version );
+ if ( vertex != null )
+ {
+ addEdge( projectVertex, vertex, project, projectMap, force, safe );
+ }
+ }
+ else
+ {
+ for ( Vertex vertex : vertices.values() )
+ {
+ addEdge( projectVertex, vertex, project, projectMap, force, safe );
+ }
+ }
+ }
+ }
+
+ private void addEdge( Vertex fromVertex, Vertex toVertex, MavenProject fromProject,
+ Map<String, MavenProject> projectMap, boolean force, boolean safe )
+ throws CycleDetectedException
+ {
+ if ( fromVertex.equals( toVertex ) )
+ {
+ return;
+ }
+
+ if ( fromProject != null )
+ {
+ MavenProject toProject = projectMap.get( toVertex.getLabel() );
+ fromProject.addProjectReference( toProject );
+ }
+
+ if ( force && toVertex.getChildren().contains( fromVertex ) )
+ {
+ dag.removeEdge( toVertex, fromVertex );
+ }
+
+ try
+ {
+ dag.addEdge( fromVertex, toVertex );
+ }
+ catch ( CycleDetectedException e )
+ {
+ if ( !safe )
+ {
+ throw e;
+ }
+ }
+ }
+
+ private boolean isSpecificVersion( String version )
+ {
+ return !( StringUtils.isEmpty( version ) || version.startsWith( "[" ) || version.startsWith( "(" ) );
+ }
+
+ // TODO: !![jc; 28-jul-2005] check this; if we're using '-r' and there are aggregator tasks, this will result in weirdness.
+ public MavenProject getTopLevelProject()
+ {
+ if ( topLevelProject == null )
+ {
+ for ( Iterator<MavenProject> i = sortedProjects.iterator(); i.hasNext() && ( topLevelProject == null ); )
+ {
+ MavenProject project = i.next();
+ if ( project.isExecutionRoot() )
+ {
+ topLevelProject = project;
+ }
+ }
+ }
+
+ return topLevelProject;
+ }
+
+ public List<MavenProject> getSortedProjects()
+ {
+ return sortedProjects;
+ }
+
+ public boolean hasMultipleProjects()
+ {
+ return sortedProjects.size() > 1;
+ }
+
+ public List<String> getDependents( String id )
+ {
+ return dag.getParentLabels( id );
+ }
+
+ public List<String> getDependencies( String id )
+ {
+ return dag.getChildLabels( id );
+ }
+
+ public static String getId( MavenProject project )
+ {
+ return ArtifactUtils.key( project.getGroupId(), project.getArtifactId(), project.getVersion() );
+ }
+
+ public DAG getDAG()
+ {
+ return dag;
+ }
+
+ public Map<String, MavenProject> getProjectMap()
+ {
+ return projectMap;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/ReactorModelCache.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/ReactorModelCache.java
new file mode 100644
index 00000000..24425da1
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/ReactorModelCache.java
@@ -0,0 +1,103 @@
+package org.apache.maven.project;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.maven.model.building.ModelCache;
+
+/**
+ * A simple model cache used to accelerate model building during a reactor build.
+ *
+ * @author Benjamin Bentmann
+ */
+class ReactorModelCache
+ implements ModelCache
+{
+
+ private final Map<CacheKey, Object> models = new HashMap<CacheKey, Object>( 256 );
+
+ public Object get( String groupId, String artifactId, String version, String tag )
+ {
+ return models.get( new CacheKey( groupId, artifactId, version, tag ) );
+ }
+
+ public void put( String groupId, String artifactId, String version, String tag, Object data )
+ {
+ models.put( new CacheKey( groupId, artifactId, version, tag ), data );
+ }
+
+ private static final class CacheKey
+ {
+
+ private final String groupId;
+
+ private final String artifactId;
+
+ private final String version;
+
+ private final String tag;
+
+ private final int hashCode;
+
+ public CacheKey( String groupId, String artifactId, String version, String tag )
+ {
+ this.groupId = ( groupId != null ) ? groupId : "";
+ this.artifactId = ( artifactId != null ) ? artifactId : "";
+ this.version = ( version != null ) ? version : "";
+ this.tag = ( tag != null ) ? tag : "";
+
+ int hash = 17;
+ hash = hash * 31 + this.groupId.hashCode();
+ hash = hash * 31 + this.artifactId.hashCode();
+ hash = hash * 31 + this.version.hashCode();
+ hash = hash * 31 + this.tag.hashCode();
+ hashCode = hash;
+ }
+
+ @Override
+ public boolean equals( Object obj )
+ {
+ if ( this == obj )
+ {
+ return true;
+ }
+
+ if ( !( obj instanceof CacheKey ) )
+ {
+ return false;
+ }
+
+ CacheKey that = (CacheKey) obj;
+
+ return artifactId.equals( that.artifactId ) && groupId.equals( that.groupId )
+ && version.equals( that.version ) && tag.equals( that.tag );
+ }
+
+ @Override
+ public int hashCode()
+ {
+ return hashCode;
+ }
+
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/ReactorModelPool.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/ReactorModelPool.java
new file mode 100644
index 00000000..294fccdb
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/ReactorModelPool.java
@@ -0,0 +1,106 @@
+package org.apache.maven.project;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Holds all POM files that are known to the reactor. This allows the project builder to resolve imported POMs from the
+ * reactor when building another project's effective model.
+ *
+ * @author Benjamin Bentmann
+ */
+class ReactorModelPool
+{
+
+ private final Map<CacheKey, File> pomFiles = new HashMap<CacheKey, File>();
+
+ public File get( String groupId, String artifactId, String version )
+ {
+ return pomFiles.get( new CacheKey( groupId, artifactId, version ) );
+ }
+
+ public void put( String groupId, String artifactId, String version, File pomFile )
+ {
+ pomFiles.put( new CacheKey( groupId, artifactId, version ), pomFile );
+ }
+
+ private static final class CacheKey
+ {
+
+ private final String groupId;
+
+ private final String artifactId;
+
+ private final String version;
+
+ private final int hashCode;
+
+ public CacheKey( String groupId, String artifactId, String version )
+ {
+ this.groupId = ( groupId != null ) ? groupId : "";
+ this.artifactId = ( artifactId != null ) ? artifactId : "";
+ this.version = ( version != null ) ? version : "";
+
+ int hash = 17;
+ hash = hash * 31 + this.groupId.hashCode();
+ hash = hash * 31 + this.artifactId.hashCode();
+ hash = hash * 31 + this.version.hashCode();
+ hashCode = hash;
+ }
+
+ @Override
+ public boolean equals( Object obj )
+ {
+ if ( this == obj )
+ {
+ return true;
+ }
+
+ if ( !( obj instanceof CacheKey ) )
+ {
+ return false;
+ }
+
+ CacheKey that = (CacheKey) obj;
+
+ return artifactId.equals( that.artifactId ) && groupId.equals( that.groupId )
+ && version.equals( that.version );
+ }
+
+ @Override
+ public int hashCode()
+ {
+ return hashCode;
+ }
+
+ @Override
+ public String toString()
+ {
+ StringBuilder buffer = new StringBuilder( 96 );
+ buffer.append( groupId ).append( ':' ).append( artifactId ).append( ':' ).append( version );
+ return buffer.toString();
+ }
+
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/RepositorySessionDecorator.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/RepositorySessionDecorator.java
new file mode 100644
index 00000000..679ee008
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/RepositorySessionDecorator.java
@@ -0,0 +1,36 @@
+package org.apache.maven.project;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.eclipse.aether.RepositorySystemSession;
+
+/**
+ * Component interface that allows per-project customization of Aether repository system sessions.
+ *
+ * @since 3.2.4
+ * @provisional This interface is part of work in progress and can be changed or removed without notice.
+ */
+public interface RepositorySessionDecorator
+{
+ /**
+ * Returns possibly {@code null} Aether repository system session to be used to resolve project dependencies.
+ */
+ RepositorySystemSession decorate( MavenProject project, RepositorySystemSession session );
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/artifact/ActiveProjectArtifact.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/artifact/ActiveProjectArtifact.java
new file mode 100644
index 00000000..6e13d332
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/artifact/ActiveProjectArtifact.java
@@ -0,0 +1,403 @@
+package org.apache.maven.project.artifact;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.handler.ArtifactHandler;
+import org.apache.maven.artifact.metadata.ArtifactMetadata;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
+import org.apache.maven.artifact.versioning.ArtifactVersion;
+import org.apache.maven.artifact.versioning.OverConstrainedVersionException;
+import org.apache.maven.artifact.versioning.VersionRange;
+import org.apache.maven.project.MavenProject;
+
+import java.io.File;
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * Wraps an active project instance to be able to receive updates from its artifact without affecting the original
+ * attributes of this artifact.
+ *
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ * @todo I think this exposes a design flaw in that the immutable and mutable parts of an artifact are in one class and
+ * should be split. ie scope, file, etc depend on the context of use, whereas everything else is immutable.
+ */
+@Deprecated
+public class ActiveProjectArtifact
+ implements Artifact
+{
+ private final Artifact artifact;
+
+ private final MavenProject project;
+
+ public ActiveProjectArtifact( MavenProject project, Artifact artifact )
+ {
+ this.artifact = artifact;
+ this.project = project;
+
+ artifact.setFile( project.getArtifact().getFile() );
+ artifact.setResolved( true );
+ }
+
+ /** {@inheritDoc} */
+ public File getFile()
+ {
+ // we need to get the latest file for the project, not the artifact that was created at one point in time
+ return project.getArtifact().getFile();
+ }
+
+ /** {@inheritDoc} */
+ public String getGroupId()
+ {
+ return artifact.getGroupId();
+ }
+
+ /** {@inheritDoc} */
+ public String getArtifactId()
+ {
+ return artifact.getArtifactId();
+ }
+
+ /** {@inheritDoc} */
+ public String getVersion()
+ {
+ return artifact.getVersion();
+ }
+
+ /** {@inheritDoc} */
+ public void setVersion( String version )
+ {
+ artifact.setVersion( version );
+ }
+
+ /** {@inheritDoc} */
+ public String getScope()
+ {
+ return artifact.getScope();
+ }
+
+ /** {@inheritDoc} */
+ public String getType()
+ {
+ return artifact.getType();
+ }
+
+ /** {@inheritDoc} */
+ public String getClassifier()
+ {
+ return artifact.getClassifier();
+ }
+
+ /** {@inheritDoc} */
+ public boolean hasClassifier()
+ {
+ return artifact.hasClassifier();
+ }
+
+ /** {@inheritDoc} */
+ public void setFile( File destination )
+ {
+ artifact.setFile( destination );
+ project.getArtifact().setFile( destination );
+ }
+
+ /** {@inheritDoc} */
+ public String getBaseVersion()
+ {
+ return artifact.getBaseVersion();
+ }
+
+ /** {@inheritDoc} */
+ public void setBaseVersion( String baseVersion )
+ {
+ artifact.setBaseVersion( baseVersion );
+ }
+
+ /** {@inheritDoc} */
+ public String getId()
+ {
+ return artifact.getId();
+ }
+
+ /** {@inheritDoc} */
+ public String getDependencyConflictId()
+ {
+ return artifact.getDependencyConflictId();
+ }
+
+ /** {@inheritDoc} */
+ public void addMetadata( ArtifactMetadata metadata )
+ {
+ artifact.addMetadata( metadata );
+ }
+
+ /** {@inheritDoc} */
+ public Collection<ArtifactMetadata> getMetadataList()
+ {
+ return artifact.getMetadataList();
+ }
+
+ /** {@inheritDoc} */
+ public void setRepository( ArtifactRepository remoteRepository )
+ {
+ artifact.setRepository( remoteRepository );
+ }
+
+ /** {@inheritDoc} */
+ public ArtifactRepository getRepository()
+ {
+ return artifact.getRepository();
+ }
+
+ /** {@inheritDoc} */
+ public void updateVersion( String version, ArtifactRepository localRepository )
+ {
+ artifact.updateVersion( version, localRepository );
+ }
+
+ /** {@inheritDoc} */
+ public String getDownloadUrl()
+ {
+ return artifact.getDownloadUrl();
+ }
+
+ /** {@inheritDoc} */
+ public void setDownloadUrl( String downloadUrl )
+ {
+ artifact.setDownloadUrl( downloadUrl );
+ }
+
+ /** {@inheritDoc} */
+ public ArtifactFilter getDependencyFilter()
+ {
+ return artifact.getDependencyFilter();
+ }
+
+ /** {@inheritDoc} */
+ public void setDependencyFilter( ArtifactFilter artifactFilter )
+ {
+ artifact.setDependencyFilter( artifactFilter );
+ }
+
+ /** {@inheritDoc} */
+ public ArtifactHandler getArtifactHandler()
+ {
+ return artifact.getArtifactHandler();
+ }
+
+ /** {@inheritDoc} */
+ public List<String> getDependencyTrail()
+ {
+ return artifact.getDependencyTrail();
+ }
+
+ /** {@inheritDoc} */
+ public void setDependencyTrail( List<String> dependencyTrail )
+ {
+ artifact.setDependencyTrail( dependencyTrail );
+ }
+
+ /** {@inheritDoc} */
+ public void setScope( String scope )
+ {
+ artifact.setScope( scope );
+ }
+
+ /** {@inheritDoc} */
+ public VersionRange getVersionRange()
+ {
+ return artifact.getVersionRange();
+ }
+
+ /** {@inheritDoc} */
+ public void setVersionRange( VersionRange newRange )
+ {
+ artifact.setVersionRange( newRange );
+ }
+
+ /** {@inheritDoc} */
+ public void selectVersion( String version )
+ {
+ artifact.selectVersion( version );
+ }
+
+ /** {@inheritDoc} */
+ public void setGroupId( String groupId )
+ {
+ artifact.setGroupId( groupId );
+ }
+
+ /** {@inheritDoc} */
+ public void setArtifactId( String artifactId )
+ {
+ artifact.setArtifactId( artifactId );
+ }
+
+ /** {@inheritDoc} */
+ public boolean isSnapshot()
+ {
+ return artifact.isSnapshot();
+ }
+
+ /** {@inheritDoc} */
+ public int compareTo( Artifact a )
+ {
+ return artifact.compareTo( a );
+ }
+
+ /** {@inheritDoc} */
+ public void setResolved( boolean resolved )
+ {
+ artifact.setResolved( resolved );
+ }
+
+ /** {@inheritDoc} */
+ public boolean isResolved()
+ {
+ return artifact.isResolved();
+ }
+
+ /** {@inheritDoc} */
+ public void setResolvedVersion( String version )
+ {
+ artifact.setResolvedVersion( version );
+ }
+
+ /** {@inheritDoc} */
+ public void setArtifactHandler( ArtifactHandler handler )
+ {
+ artifact.setArtifactHandler( handler );
+ }
+
+ /** {@inheritDoc} */
+ public String toString()
+ {
+ return "active project artifact:\n\tartifact = " + artifact + ";\n\tproject: " + project;
+ }
+
+ /** {@inheritDoc} */
+ public boolean isRelease()
+ {
+ return artifact.isRelease();
+ }
+
+ /** {@inheritDoc} */
+ public void setRelease( boolean release )
+ {
+ artifact.setRelease( release );
+ }
+
+ /** {@inheritDoc} */
+ public List<ArtifactVersion> getAvailableVersions()
+ {
+ return artifact.getAvailableVersions();
+ }
+
+ /** {@inheritDoc} */
+ public void setAvailableVersions( List<ArtifactVersion> versions )
+ {
+ artifact.setAvailableVersions( versions );
+ }
+
+ /** {@inheritDoc} */
+ public boolean isOptional()
+ {
+ return artifact.isOptional();
+ }
+
+ /** {@inheritDoc} */
+ public ArtifactVersion getSelectedVersion()
+ throws OverConstrainedVersionException
+ {
+ return artifact.getSelectedVersion();
+ }
+
+ /** {@inheritDoc} */
+ public boolean isSelectedVersionKnown()
+ throws OverConstrainedVersionException
+ {
+ return artifact.isSelectedVersionKnown();
+ }
+
+ /** {@inheritDoc} */
+ public void setOptional( boolean optional )
+ {
+ artifact.setOptional( optional );
+ }
+
+ /** {@inheritDoc} */
+ public int hashCode()
+ {
+ int result = 17;
+
+ result = 37 * result + getGroupId().hashCode();
+ result = 37 * result + getArtifactId().hashCode();
+ result = 37 * result + getType().hashCode();
+ if ( getVersion() != null )
+ {
+ result = 37 * result + getVersion().hashCode();
+ }
+ result = 37 * result + ( getClassifier() != null ? getClassifier().hashCode() : 0 );
+
+ return result;
+ }
+
+ /** {@inheritDoc} */
+ public boolean equals( Object o )
+ {
+ if ( o == this )
+ {
+ return true;
+ }
+
+ if ( !( o instanceof Artifact ) )
+ {
+ return false;
+ }
+
+ Artifact a = (Artifact) o;
+
+ if ( !a.getGroupId().equals( getGroupId() ) )
+ {
+ return false;
+ }
+ else if ( !a.getArtifactId().equals( getArtifactId() ) )
+ {
+ return false;
+ }
+ else if ( !a.getVersion().equals( getVersion() ) )
+ {
+ return false;
+ }
+ else if ( !a.getType().equals( getType() ) )
+ {
+ return false;
+ }
+ else if ( a.getClassifier() == null ? getClassifier() != null : !a.getClassifier().equals( getClassifier() ) )
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/artifact/ArtifactWithDependencies.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/artifact/ArtifactWithDependencies.java
new file mode 100644
index 00000000..cb06b70f
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/artifact/ArtifactWithDependencies.java
@@ -0,0 +1,33 @@
+package org.apache.maven.project.artifact;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.List;
+
+import org.apache.maven.model.Dependency;
+
+public interface ArtifactWithDependencies
+{
+
+ List<Dependency> getDependencies();
+
+ List<Dependency> getManagedDependencies();
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/artifact/AttachedArtifact.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/artifact/AttachedArtifact.java
new file mode 100644
index 00000000..fd2b956c
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/artifact/AttachedArtifact.java
@@ -0,0 +1,185 @@
+package org.apache.maven.project.artifact;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.DefaultArtifact;
+import org.apache.maven.artifact.InvalidArtifactRTException;
+import org.apache.maven.artifact.handler.ArtifactHandler;
+import org.apache.maven.artifact.metadata.ArtifactMetadata;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.versioning.ArtifactVersion;
+import org.apache.maven.artifact.versioning.VersionRange;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ *<strong>Warning:</strong> This is an internal utility class that is only public for technical reasons, it is not part
+ * of the public API. In particular, this class can be changed or deleted without prior notice. Use
+ * {@link org.apache.maven.project.MavenProjectHelper#attachArtifact} instead.
+ */
+@Deprecated
+public class AttachedArtifact
+ extends DefaultArtifact
+{
+
+ private final Artifact parent;
+
+ public AttachedArtifact( Artifact parent, String type, String classifier, ArtifactHandler artifactHandler )
+ {
+ super( parent.getGroupId(), parent.getArtifactId(), parent.getVersionRange(), parent.getScope(), type,
+ classifier, artifactHandler, parent.isOptional() );
+
+ setDependencyTrail( Collections.singletonList( parent.getId() ) );
+
+ this.parent = parent;
+
+ if ( getId().equals( parent.getId() ) )
+ {
+ throw new InvalidArtifactRTException( parent.getGroupId(), parent.getArtifactId(), parent.getVersion(),
+ parent.getType(), "An attached artifact must have a different ID"
+ + " than its corresponding main artifact." );
+ }
+ }
+
+ public AttachedArtifact( Artifact parent, String type, ArtifactHandler artifactHandler )
+ {
+ this( parent, type, null, artifactHandler );
+ }
+
+ public void setArtifactId( String artifactId )
+ {
+ throw new UnsupportedOperationException( "Cannot change the artifactId for an attached artifact."
+ + " It is derived from the main artifact." );
+ }
+
+ public List<ArtifactVersion> getAvailableVersions()
+ {
+ return parent.getAvailableVersions();
+ }
+
+ public void setAvailableVersions( List<ArtifactVersion> availableVersions )
+ {
+ throw new UnsupportedOperationException( "Cannot change the version information for an attached artifact."
+ + " It is derived from the main artifact." );
+ }
+
+ public String getBaseVersion()
+ {
+ return parent.getBaseVersion();
+ }
+
+ public void setBaseVersion( String baseVersion )
+ {
+ throw new UnsupportedOperationException( "Cannot change the version information for an attached artifact."
+ + " It is derived from the main artifact." );
+ }
+
+ public String getDownloadUrl()
+ {
+ return parent.getDownloadUrl();
+ }
+
+ public void setDownloadUrl( String downloadUrl )
+ {
+ throw new UnsupportedOperationException( "Cannot change the download information for an attached artifact."
+ + " It is derived from the main artifact." );
+ }
+
+ public void setGroupId( String groupId )
+ {
+ throw new UnsupportedOperationException( "Cannot change the groupId for an attached artifact."
+ + " It is derived from the main artifact." );
+ }
+
+ public ArtifactRepository getRepository()
+ {
+ return parent.getRepository();
+ }
+
+ public void setRepository( ArtifactRepository repository )
+ {
+ throw new UnsupportedOperationException( "Cannot change the repository information for an attached artifact."
+ + " It is derived from the main artifact." );
+ }
+
+ public String getScope()
+ {
+ return parent.getScope();
+ }
+
+ public void setScope( String scope )
+ {
+ throw new UnsupportedOperationException( "Cannot change the scoping information for an attached artifact."
+ + " It is derived from the main artifact." );
+ }
+
+ public String getVersion()
+ {
+ return parent.getVersion();
+ }
+
+ public void setVersion( String version )
+ {
+ throw new UnsupportedOperationException( "Cannot change the version information for an attached artifact."
+ + " It is derived from the main artifact." );
+ }
+
+ public VersionRange getVersionRange()
+ {
+ return parent.getVersionRange();
+ }
+
+ public void setVersionRange( VersionRange range )
+ {
+ throw new UnsupportedOperationException( "Cannot change the version information for an attached artifact."
+ + " It is derived from the main artifact." );
+ }
+
+ public boolean isRelease()
+ {
+ return parent.isRelease();
+ }
+
+ public void setRelease( boolean release )
+ {
+ throw new UnsupportedOperationException( "Cannot change the version information for an attached artifact."
+ + " It is derived from the main artifact." );
+ }
+
+ public boolean isSnapshot()
+ {
+ return parent.isSnapshot();
+ }
+
+ public void addMetadata( ArtifactMetadata metadata )
+ {
+ // ignore. The parent artifact will handle metadata.
+ // we must fail silently here to avoid problems with the artifact transformers.
+ }
+
+ public Collection<ArtifactMetadata> getMetadataList()
+ {
+ return Collections.emptyList();
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/artifact/DefaultMavenMetadataCache.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/artifact/DefaultMavenMetadataCache.java
new file mode 100644
index 00000000..07fd11da
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/artifact/DefaultMavenMetadataCache.java
@@ -0,0 +1,347 @@
+package org.apache.maven.project.artifact;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.ArtifactUtils;
+import org.apache.maven.artifact.metadata.ResolutionGroup;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy;
+import org.codehaus.plexus.component.annotations.Component;
+
+@Component( role = MavenMetadataCache.class )
+public class DefaultMavenMetadataCache
+ implements MavenMetadataCache
+{
+
+ protected final Map<CacheKey, CacheRecord> cache = new ConcurrentHashMap<CacheKey, CacheRecord>();
+
+ public static class CacheKey
+ {
+ private final Artifact artifact;
+ private final long pomHash;
+ private final boolean resolveManagedVersions;
+ private final List<ArtifactRepository> repositories = new ArrayList<ArtifactRepository>();
+ private final int hashCode;
+
+ public CacheKey( Artifact artifact, boolean resolveManagedVersions, ArtifactRepository localRepository,
+ List<ArtifactRepository> remoteRepositories )
+ {
+ File file = artifact.getFile();
+ this.artifact = ArtifactUtils.copyArtifact( artifact );
+ if ( "pom".equals( artifact.getType() ) && file != null )
+ {
+ pomHash = file.getPath().hashCode() + file.lastModified();
+ }
+ else
+ {
+ pomHash = 0;
+ }
+ this.resolveManagedVersions = resolveManagedVersions;
+ this.repositories.add( localRepository );
+ this.repositories.addAll( remoteRepositories );
+
+ int hash = 17;
+ hash = hash * 31 + artifactHashCode( artifact );
+ hash = hash * 31 + ( resolveManagedVersions ? 1 : 2 );
+ hash = hash * 31 + repositoriesHashCode( repositories );
+ this.hashCode = hash;
+ }
+
+ @Override
+ public int hashCode()
+ {
+ return hashCode;
+ }
+
+ @Override
+ public boolean equals( Object o )
+ {
+ if ( o == this )
+ {
+ return true;
+ }
+
+ if ( !( o instanceof CacheKey ) )
+ {
+ return false;
+ }
+
+ CacheKey other = (CacheKey) o;
+
+ return pomHash == other.pomHash && artifactEquals( artifact, other.artifact )
+ && resolveManagedVersions == other.resolveManagedVersions
+ && repositoriesEquals( repositories, other.repositories );
+ }
+ }
+
+ private static int artifactHashCode( Artifact a )
+ {
+ int result = 17;
+ result = 31 * result + a.getGroupId().hashCode();
+ result = 31 * result + a.getArtifactId().hashCode();
+ result = 31 * result + a.getType().hashCode();
+ if ( a.getVersion() != null )
+ {
+ result = 31 * result + a.getVersion().hashCode();
+ }
+ result = 31 * result + ( a.getClassifier() != null ? a.getClassifier().hashCode() : 0 );
+ result = 31 * result + ( a.getScope() != null ? a.getScope().hashCode() : 0 );
+ result = 31 * result + ( a.getDependencyFilter() != null ? a.getDependencyFilter().hashCode() : 0 );
+ result = 31 * result + ( a.isOptional() ? 1 : 0 );
+ return result;
+ }
+
+ private static boolean artifactEquals( Artifact a1, Artifact a2 )
+ {
+ if ( a1 == a2 )
+ {
+ return true;
+ }
+
+ return eq( a1.getGroupId(), a2.getGroupId() )
+ && eq( a1.getArtifactId(), a2.getArtifactId() )
+ && eq( a1.getType(), a2.getType() )
+ && eq( a1.getVersion(), a2.getVersion() )
+ && eq( a1.getClassifier(), a2.getClassifier() )
+ && eq( a1.getScope(), a2.getScope() )
+ && eq( a1.getDependencyFilter(), a2.getDependencyFilter() )
+ && a1.isOptional() == a2.isOptional();
+ }
+
+ private static int repositoryHashCode( ArtifactRepository repository )
+ {
+ int result = 17;
+ result = 31 * result + ( repository.getId() != null ? repository.getId().hashCode() : 0 );
+ return result;
+ }
+
+ private static int repositoriesHashCode( List<ArtifactRepository> repositories )
+ {
+ int result = 17;
+ for ( ArtifactRepository repository : repositories )
+ {
+ result = 31 * result + repositoryHashCode( repository );
+ }
+ return result;
+ }
+
+ private static boolean repositoryEquals( ArtifactRepository r1, ArtifactRepository r2 )
+ {
+ if ( r1 == r2 )
+ {
+ return true;
+ }
+
+ return eq( r1.getId(), r2.getId() ) && eq( r1.getUrl(), r2.getUrl() )
+ && repositoryPolicyEquals( r1.getReleases(), r2.getReleases() )
+ && repositoryPolicyEquals( r1.getSnapshots(), r2.getSnapshots() );
+ }
+
+ private static boolean repositoryPolicyEquals( ArtifactRepositoryPolicy p1, ArtifactRepositoryPolicy p2 )
+ {
+ if ( p1 == p2 )
+ {
+ return true;
+ }
+
+ return p1.isEnabled() == p2.isEnabled() && eq( p1.getUpdatePolicy(), p2.getUpdatePolicy() );
+ }
+
+ private static boolean repositoriesEquals( List<ArtifactRepository> r1, List<ArtifactRepository> r2 )
+ {
+ if ( r1.size() != r2.size() )
+ {
+ return false;
+ }
+
+ for ( Iterator<ArtifactRepository> it1 = r1.iterator(), it2 = r2.iterator(); it1.hasNext(); )
+ {
+ if ( !repositoryEquals( it1.next(), it2.next() ) )
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ private static <T> boolean eq( T s1, T s2 )
+ {
+ return s1 != null ? s1.equals( s2 ) : s2 == null;
+ }
+
+ public class CacheRecord
+ {
+ private Artifact pomArtifact;
+ private Artifact relocatedArtifact;
+ private List<Artifact> artifacts;
+ private Map<String, Artifact> managedVersions;
+ private List<ArtifactRepository> remoteRepositories;
+
+ private long length;
+ private long timestamp;
+
+ CacheRecord( Artifact pomArtifact, Artifact relocatedArtifact, Set<Artifact> artifacts,
+ Map<String, Artifact> managedVersions, List<ArtifactRepository> remoteRepositories )
+ {
+ this.pomArtifact = ArtifactUtils.copyArtifact( pomArtifact );
+ this.relocatedArtifact = ArtifactUtils.copyArtifactSafe( relocatedArtifact );
+ this.artifacts = ArtifactUtils.copyArtifacts( artifacts, new ArrayList<Artifact>() );
+ this.remoteRepositories = new ArrayList<ArtifactRepository>( remoteRepositories );
+
+ this.managedVersions = managedVersions;
+ if ( managedVersions != null )
+ {
+ this.managedVersions =
+ ArtifactUtils.copyArtifacts( managedVersions, new LinkedHashMap<String, Artifact>() );
+ }
+
+ File pomFile = pomArtifact.getFile();
+ if ( pomFile != null && pomFile.canRead() )
+ {
+ this.length = pomFile.length();
+ this.timestamp = pomFile.lastModified();
+ }
+ else
+ {
+ this.length = -1;
+ this.timestamp = -1;
+ }
+ }
+
+ public Artifact getArtifact()
+ {
+ return pomArtifact;
+ }
+
+ public Artifact getRelocatedArtifact()
+ {
+ return relocatedArtifact;
+ }
+
+ public List<Artifact> getArtifacts()
+ {
+ return artifacts;
+ }
+
+ public Map<String, Artifact> getManagedVersions()
+ {
+ return managedVersions;
+ }
+
+ public List<ArtifactRepository> getRemoteRepositories()
+ {
+ return remoteRepositories;
+ }
+
+ public boolean isStale()
+ {
+ File pomFile = pomArtifact.getFile();
+ if ( pomFile != null )
+ {
+ if ( pomFile.canRead() )
+ {
+ return length != pomFile.length() || timestamp != pomFile.lastModified();
+ }
+ else
+ {
+ // if the POM didn't exist, retry if any repo is configured to always update
+ boolean snapshot = pomArtifact.isSnapshot();
+ for ( ArtifactRepository repository : remoteRepositories )
+ {
+ ArtifactRepositoryPolicy policy =
+ snapshot ? repository.getSnapshots() : repository.getReleases();
+ if ( ArtifactRepositoryPolicy.UPDATE_POLICY_ALWAYS.equals( policy.getUpdatePolicy() ) )
+ {
+ return true;
+ }
+ }
+ }
+ }
+
+ return length != -1 || timestamp != -1;
+ }
+ }
+
+
+ public ResolutionGroup get( Artifact artifact, boolean resolveManagedVersions, ArtifactRepository localRepository,
+ List<ArtifactRepository> remoteRepositories )
+ {
+ CacheKey cacheKey = newCacheKey( artifact, resolveManagedVersions, localRepository, remoteRepositories );
+
+ CacheRecord cacheRecord = cache.get( cacheKey );
+
+ if ( cacheRecord != null && !cacheRecord.isStale() )
+ {
+ Artifact pomArtifact = ArtifactUtils.copyArtifact( cacheRecord.getArtifact() );
+ Artifact relocatedArtifact = ArtifactUtils.copyArtifactSafe( cacheRecord.getRelocatedArtifact() );
+ Set<Artifact> artifacts =
+ ArtifactUtils.copyArtifacts( cacheRecord.getArtifacts(), new LinkedHashSet<Artifact>() );
+ Map<String, Artifact> managedVersions = cacheRecord.getManagedVersions();
+ if ( managedVersions != null )
+ {
+ managedVersions = ArtifactUtils.copyArtifacts( managedVersions, new LinkedHashMap<String, Artifact>() );
+ }
+ return new ResolutionGroup( pomArtifact, relocatedArtifact, artifacts, managedVersions,
+ cacheRecord.getRemoteRepositories() );
+ }
+
+ cache.remove( cacheKey );
+
+ return null;
+ }
+
+ public void put( Artifact artifact, boolean resolveManagedVersions, ArtifactRepository localRepository,
+ List<ArtifactRepository> remoteRepositories, ResolutionGroup result )
+ {
+ put( newCacheKey( artifact, resolveManagedVersions, localRepository, remoteRepositories ), result );
+ }
+
+ protected CacheKey newCacheKey( Artifact artifact, boolean resolveManagedVersions,
+ ArtifactRepository localRepository, List<ArtifactRepository> remoteRepositories )
+ {
+ return new CacheKey( artifact, resolveManagedVersions, localRepository, remoteRepositories );
+ }
+
+ protected void put( CacheKey cacheKey, ResolutionGroup result )
+ {
+ CacheRecord cacheRecord =
+ new CacheRecord( result.getPomArtifact(), result.getRelocatedArtifact(), result.getArtifacts(),
+ result.getManagedVersions(), result.getResolutionRepositories() );
+
+ cache.put( cacheKey, cacheRecord );
+ }
+
+ public void flush()
+ {
+ cache.clear();
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/artifact/DefaultMetadataSource.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/artifact/DefaultMetadataSource.java
new file mode 100644
index 00000000..91f665b5
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/artifact/DefaultMetadataSource.java
@@ -0,0 +1,37 @@
+package org.apache.maven.project.artifact;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
+import org.codehaus.plexus.component.annotations.Component;
+
+/**
+ * This realizes the metadata source via the default hint to provide backward-compat with Maven 2.x whose Plexus version
+ * registered component descriptors twice: once keyed by role+roleHint and once keyed by role only. This effectively
+ * made the metadata source available with its original role hint ("maven") as well as the default hint.
+ *
+ * @author Benjamin Bentmann
+ */
+@Component( role = ArtifactMetadataSource.class )
+public class DefaultMetadataSource
+ extends MavenMetadataSource
+{
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/artifact/InvalidDependencyVersionException.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/artifact/InvalidDependencyVersionException.java
new file mode 100644
index 00000000..8a1de685
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/artifact/InvalidDependencyVersionException.java
@@ -0,0 +1,55 @@
+package org.apache.maven.project.artifact;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+
+import org.apache.maven.artifact.ArtifactUtils;
+import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
+import org.apache.maven.model.Dependency;
+import org.apache.maven.project.InvalidProjectVersionException;
+
+/**
+ * Thrown if a dependency has an invalid version.
+ *
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ */
+public class InvalidDependencyVersionException
+ extends InvalidProjectVersionException
+{
+ private Dependency dependency;
+
+ public InvalidDependencyVersionException( String projectId, Dependency dependency, File pomFile,
+ InvalidVersionSpecificationException cause )
+ {
+ super( projectId, formatLocationInPom( dependency ), dependency.getVersion(), pomFile, cause );
+ this.dependency = dependency;
+ }
+
+ private static String formatLocationInPom( Dependency dependency )
+ {
+ return "Dependency: " + ArtifactUtils.versionlessKey( dependency.getGroupId(), dependency.getArtifactId() );
+ }
+
+ public Dependency getDependency()
+ {
+ return dependency;
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/artifact/MavenMetadataCache.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/artifact/MavenMetadataCache.java
new file mode 100644
index 00000000..036ee86c
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/artifact/MavenMetadataCache.java
@@ -0,0 +1,38 @@
+package org.apache.maven.project.artifact;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.List;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.metadata.ResolutionGroup;
+
+public interface MavenMetadataCache
+{
+
+ ResolutionGroup get( Artifact artifact, boolean resolveManagedVersions, ArtifactRepository localRepository,
+ List<ArtifactRepository> remoteRepositories );
+
+ void put( Artifact artifact, boolean resolveManagedVersions, ArtifactRepository localRepository,
+ List<ArtifactRepository> remoteRepositories, ResolutionGroup result );
+
+ void flush();
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/artifact/MavenMetadataSource.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/artifact/MavenMetadataSource.java
new file mode 100644
index 00000000..1fb5c545
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/artifact/MavenMetadataSource.java
@@ -0,0 +1,770 @@
+package org.apache.maven.project.artifact;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.factory.ArtifactFactory;
+import org.apache.maven.artifact.metadata.ArtifactMetadataRetrievalException;
+import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
+import org.apache.maven.artifact.metadata.ResolutionGroup;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.repository.metadata.ArtifactRepositoryMetadata;
+import org.apache.maven.artifact.repository.metadata.Metadata;
+import org.apache.maven.artifact.repository.metadata.RepositoryMetadata;
+import org.apache.maven.artifact.repository.metadata.RepositoryMetadataManager;
+import org.apache.maven.artifact.repository.metadata.RepositoryMetadataResolutionException;
+import org.apache.maven.artifact.resolver.ArtifactResolutionException;
+import org.apache.maven.artifact.resolver.MultipleArtifactsNotFoundException;
+import org.apache.maven.artifact.resolver.filter.AndArtifactFilter;
+import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
+import org.apache.maven.artifact.resolver.filter.ExcludesArtifactFilter;
+import org.apache.maven.artifact.versioning.ArtifactVersion;
+import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
+import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
+import org.apache.maven.artifact.versioning.VersionRange;
+import org.apache.maven.model.Dependency;
+import org.apache.maven.model.DependencyManagement;
+import org.apache.maven.model.DistributionManagement;
+import org.apache.maven.model.Exclusion;
+import org.apache.maven.model.Relocation;
+import org.apache.maven.model.building.ModelBuildingException;
+import org.apache.maven.model.building.ModelBuildingRequest;
+import org.apache.maven.model.building.ModelProblem;
+import org.apache.maven.model.resolution.UnresolvableModelException;
+import org.apache.maven.plugin.LegacySupport;
+import org.apache.maven.project.DefaultProjectBuildingRequest;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.project.ProjectBuilder;
+import org.apache.maven.project.ProjectBuildingException;
+import org.apache.maven.project.ProjectBuildingRequest;
+import org.apache.maven.properties.internal.EnvironmentUtils;
+import org.apache.maven.properties.internal.SystemProperties;
+import org.apache.maven.repository.legacy.metadata.DefaultMetadataResolutionRequest;
+import org.apache.maven.repository.legacy.metadata.MetadataResolutionRequest;
+import org.codehaus.plexus.PlexusContainer;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
+import org.codehaus.plexus.logging.Logger;
+import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.repository.RepositoryPolicy;
+import org.eclipse.aether.transfer.ArtifactNotFoundException;
+
+/**
+ * @author Jason van Zyl
+ */
+@Component( role = ArtifactMetadataSource.class, hint = "maven" )
+public class MavenMetadataSource
+ implements ArtifactMetadataSource
+{
+ @Requirement
+ private RepositoryMetadataManager repositoryMetadataManager;
+
+ @Requirement
+ private ArtifactFactory repositorySystem;
+
+ //TODO: This prevents a cycle in the composition which shows us another problem we need to deal with.
+ //@Requirement
+ private ProjectBuilder projectBuilder;
+
+ @Requirement
+ private PlexusContainer container;
+
+ @Requirement
+ private Logger logger;
+
+ @Requirement
+ private MavenMetadataCache cache;
+
+ @Requirement
+ private LegacySupport legacySupport;
+
+ private void injectSession( MetadataResolutionRequest request )
+ {
+ RepositorySystemSession session = legacySupport.getRepositorySession();
+
+ if ( session != null )
+ {
+ request.setOffline( session.isOffline() );
+ request.setForceUpdate( RepositoryPolicy.UPDATE_POLICY_ALWAYS.equals( session.getUpdatePolicy() ) );
+ }
+ }
+
+ public ResolutionGroup retrieve( Artifact artifact, ArtifactRepository localRepository,
+ List<ArtifactRepository> remoteRepositories )
+ throws ArtifactMetadataRetrievalException
+ {
+ return retrieve( artifact, localRepository, remoteRepositories, false );
+ }
+
+ public ResolutionGroup retrieve( Artifact artifact, ArtifactRepository localRepository,
+ List<ArtifactRepository> remoteRepositories, boolean resolveManagedVersions )
+ throws ArtifactMetadataRetrievalException
+ {
+ MetadataResolutionRequest request = new DefaultMetadataResolutionRequest();
+ injectSession( request );
+ request.setArtifact( artifact );
+ request.setLocalRepository( localRepository );
+ request.setRemoteRepositories( remoteRepositories );
+ request.setResolveManagedVersions( resolveManagedVersions );
+ return retrieve( request );
+ }
+
+ public ResolutionGroup retrieve( MetadataResolutionRequest request )
+ throws ArtifactMetadataRetrievalException
+ {
+ Artifact artifact = request.getArtifact();
+
+ //
+ // If we have a system scoped artifact then we do not want any searching in local or remote repositories
+ // and we want artifact resolution to only return the system scoped artifact itself.
+ //
+ if ( artifact.getScope() != null && artifact.getScope().equals( Artifact.SCOPE_SYSTEM ) )
+ {
+ return new ResolutionGroup( null, null, null );
+ }
+
+ ResolutionGroup cached =
+ cache.get( artifact, request.isResolveManagedVersions(), request.getLocalRepository(),
+ request.getRemoteRepositories() );
+
+ if ( cached != null
+ // if the POM has no file, we cached a missing artifact, only return the cached data if no update forced
+ && ( !request.isForceUpdate() || hasFile( cached.getPomArtifact() ) ) )
+ {
+ return cached;
+ }
+
+ List<Dependency> dependencies;
+
+ List<Dependency> managedDependencies = null;
+
+ List<ArtifactRepository> pomRepositories = null;
+
+ Artifact pomArtifact;
+
+ Artifact relocatedArtifact = null;
+
+ //TODO: Not even sure this is really required as the project will be cached in the builder, we'll see this
+ // is currently the biggest hotspot
+ if ( artifact instanceof ArtifactWithDependencies )
+ {
+ pomArtifact = artifact;
+
+ dependencies = ( (ArtifactWithDependencies) artifact ).getDependencies();
+
+ managedDependencies = ( (ArtifactWithDependencies) artifact ).getManagedDependencies();
+ }
+ else
+ {
+ ProjectRelocation rel = retrieveRelocatedProject( artifact, request );
+
+ if ( rel == null )
+ {
+ return null;
+ }
+
+ pomArtifact = rel.pomArtifact;
+
+ relocatedArtifact = rel.relocatedArtifact;
+
+ if ( rel.project == null )
+ {
+ // When this happens we have a Maven 1.x POM, or some invalid POM.
+ // It should have never found its way into Maven 2.x repository but it did.
+ dependencies = Collections.emptyList();
+ }
+ else
+ {
+ dependencies = rel.project.getDependencies();
+
+ DependencyManagement depMngt = rel.project.getDependencyManagement();
+ managedDependencies = ( depMngt != null ) ? depMngt.getDependencies() : null;
+
+ pomRepositories = rel.project.getRemoteArtifactRepositories();
+ }
+ }
+
+ Set<Artifact> artifacts = Collections.<Artifact>emptySet();
+
+ if ( !artifact.getArtifactHandler().isIncludesDependencies() )
+ {
+ artifacts = new LinkedHashSet<Artifact>();
+
+ for ( Dependency dependency : dependencies )
+ {
+ Artifact dependencyArtifact = createDependencyArtifact( dependency, artifact, pomArtifact );
+
+ if ( dependencyArtifact != null )
+ {
+ artifacts.add( dependencyArtifact );
+ }
+ }
+ }
+
+ Map<String, Artifact> managedVersions = null;
+
+ if ( managedDependencies != null && request.isResolveManagedVersions() )
+ {
+ managedVersions = new HashMap<String, Artifact>();
+
+ for ( Dependency managedDependency : managedDependencies )
+ {
+ Artifact managedArtifact = createDependencyArtifact( managedDependency, null, pomArtifact );
+
+ managedVersions.put( managedDependency.getManagementKey(), managedArtifact );
+ }
+ }
+
+ List<ArtifactRepository> aggregatedRepositories =
+ aggregateRepositories( request.getRemoteRepositories(), pomRepositories );
+
+ ResolutionGroup result =
+ new ResolutionGroup( pomArtifact, relocatedArtifact, artifacts, managedVersions, aggregatedRepositories );
+
+ cache.put( artifact, request.isResolveManagedVersions(), request.getLocalRepository(),
+ request.getRemoteRepositories(), result );
+
+ return result;
+ }
+
+ private boolean hasFile( Artifact artifact )
+ {
+ return artifact != null && artifact.getFile() != null && artifact.getFile().exists();
+ }
+
+ private List<ArtifactRepository> aggregateRepositories( List<ArtifactRepository> requestRepositories,
+ List<ArtifactRepository> pomRepositories )
+ {
+ List<ArtifactRepository> repositories = requestRepositories;
+
+ if ( pomRepositories != null && !pomRepositories.isEmpty() )
+ {
+ Map<String, ArtifactRepository> repos = new LinkedHashMap<String, ArtifactRepository>();
+
+ for ( ArtifactRepository repo : requestRepositories )
+ {
+ if ( !repos.containsKey( repo.getId() ) )
+ {
+ repos.put( repo.getId(), repo );
+ }
+ }
+
+ for ( ArtifactRepository repo : pomRepositories )
+ {
+ if ( !repos.containsKey( repo.getId() ) )
+ {
+ repos.put( repo.getId(), repo );
+ }
+ }
+
+ repositories = new ArrayList<ArtifactRepository>( repos.values() );
+ }
+
+ return repositories;
+ }
+
+ private Artifact createDependencyArtifact( Dependency dependency, Artifact owner, Artifact pom )
+ throws ArtifactMetadataRetrievalException
+ {
+ try
+ {
+ String inheritedScope = ( owner != null ) ? owner.getScope() : null;
+
+ ArtifactFilter inheritedFilter = ( owner != null ) ? owner.getDependencyFilter() : null;
+
+ return createDependencyArtifact( repositorySystem, dependency, inheritedScope, inheritedFilter );
+ }
+ catch ( InvalidVersionSpecificationException e )
+ {
+ throw new ArtifactMetadataRetrievalException( "Invalid version for dependency "
+ + dependency.getManagementKey() + ": " + e.getMessage(), e, pom );
+ }
+ }
+
+ private static Artifact createDependencyArtifact( ArtifactFactory factory, Dependency dependency,
+ String inheritedScope, ArtifactFilter inheritedFilter )
+ throws InvalidVersionSpecificationException
+ {
+ String effectiveScope = getEffectiveScope( dependency.getScope(), inheritedScope );
+
+ if ( effectiveScope == null )
+ {
+ return null;
+ }
+
+ VersionRange versionRange = VersionRange.createFromVersionSpec( dependency.getVersion() );
+
+ Artifact dependencyArtifact =
+ factory.createDependencyArtifact( dependency.getGroupId(), dependency.getArtifactId(), versionRange,
+ dependency.getType(), dependency.getClassifier(), effectiveScope,
+ dependency.isOptional() );
+
+ ArtifactFilter dependencyFilter = inheritedFilter;
+
+ if ( dependencyFilter != null && !dependencyFilter.include( dependencyArtifact ) )
+ {
+ return null;
+ }
+
+ if ( Artifact.SCOPE_SYSTEM.equals( effectiveScope ) )
+ {
+ dependencyArtifact.setFile( new File( dependency.getSystemPath() ) );
+ }
+
+ dependencyArtifact.setDependencyFilter( createDependencyFilter( dependency, dependencyFilter ) );
+
+ return dependencyArtifact;
+ }
+
+ private static String getEffectiveScope( String originalScope, String inheritedScope )
+ {
+ String effectiveScope = Artifact.SCOPE_RUNTIME;
+
+ if ( originalScope == null )
+ {
+ originalScope = Artifact.SCOPE_COMPILE;
+ }
+
+ if ( inheritedScope == null )
+ {
+ // direct dependency retains its scope
+ effectiveScope = originalScope;
+ }
+ else if ( Artifact.SCOPE_TEST.equals( originalScope ) || Artifact.SCOPE_PROVIDED.equals( originalScope ) )
+ {
+ // test and provided are not transitive, so exclude them
+ effectiveScope = null;
+ }
+ else if ( Artifact.SCOPE_SYSTEM.equals( originalScope ) )
+ {
+ // system scope come through unchanged...
+ effectiveScope = Artifact.SCOPE_SYSTEM;
+ }
+ else if ( Artifact.SCOPE_COMPILE.equals( originalScope ) && Artifact.SCOPE_COMPILE.equals( inheritedScope ) )
+ {
+ // added to retain compile scope. Remove if you want compile inherited as runtime
+ effectiveScope = Artifact.SCOPE_COMPILE;
+ }
+ else if ( Artifact.SCOPE_TEST.equals( inheritedScope ) )
+ {
+ effectiveScope = Artifact.SCOPE_TEST;
+ }
+ else if ( Artifact.SCOPE_PROVIDED.equals( inheritedScope ) )
+ {
+ effectiveScope = Artifact.SCOPE_PROVIDED;
+ }
+
+ return effectiveScope;
+ }
+
+ private static ArtifactFilter createDependencyFilter( Dependency dependency, ArtifactFilter inheritedFilter )
+ {
+ ArtifactFilter effectiveFilter = inheritedFilter;
+
+ if ( !dependency.getExclusions().isEmpty() )
+ {
+ List<String> exclusions = new ArrayList<String>();
+
+ for ( Exclusion e : dependency.getExclusions() )
+ {
+ exclusions.add( e.getGroupId() + ':' + e.getArtifactId() );
+ }
+
+ effectiveFilter = new ExcludesArtifactFilter( exclusions );
+
+ if ( inheritedFilter != null )
+ {
+ effectiveFilter = new AndArtifactFilter( Arrays.asList( inheritedFilter, effectiveFilter ) );
+ }
+ }
+
+ return effectiveFilter;
+ }
+
+ public List<ArtifactVersion> retrieveAvailableVersions( Artifact artifact, ArtifactRepository localRepository,
+ List<ArtifactRepository> remoteRepositories )
+ throws ArtifactMetadataRetrievalException
+ {
+ MetadataResolutionRequest request = new DefaultMetadataResolutionRequest();
+ injectSession( request );
+ request.setArtifact( artifact );
+ request.setLocalRepository( localRepository );
+ request.setRemoteRepositories( remoteRepositories );
+ return retrieveAvailableVersions( request );
+ }
+
+ public List<ArtifactVersion> retrieveAvailableVersions( MetadataResolutionRequest request )
+ throws ArtifactMetadataRetrievalException
+ {
+ RepositoryMetadata metadata = new ArtifactRepositoryMetadata( request.getArtifact() );
+
+ try
+ {
+ repositoryMetadataManager.resolve( metadata, request );
+ }
+ catch ( RepositoryMetadataResolutionException e )
+ {
+ throw new ArtifactMetadataRetrievalException( e.getMessage(), e, request.getArtifact() );
+ }
+
+ List<String> availableVersions = request.getLocalRepository().findVersions( request.getArtifact() );
+
+ return retrieveAvailableVersionsFromMetadata( metadata.getMetadata(), availableVersions );
+ }
+
+ public List<ArtifactVersion> retrieveAvailableVersionsFromDeploymentRepository( Artifact artifact,
+ ArtifactRepository localRepository,
+ ArtifactRepository deploymentRepository )
+ throws ArtifactMetadataRetrievalException
+ {
+ RepositoryMetadata metadata = new ArtifactRepositoryMetadata( artifact );
+
+ try
+ {
+ repositoryMetadataManager.resolveAlways( metadata, localRepository, deploymentRepository );
+ }
+ catch ( RepositoryMetadataResolutionException e )
+ {
+ throw new ArtifactMetadataRetrievalException( e.getMessage(), e, artifact );
+ }
+
+ List<String> availableVersions = localRepository.findVersions( artifact );
+
+ return retrieveAvailableVersionsFromMetadata( metadata.getMetadata(), availableVersions );
+ }
+
+ private List<ArtifactVersion> retrieveAvailableVersionsFromMetadata( Metadata repoMetadata,
+ List<String> availableVersions )
+ {
+ Collection<String> versions = new LinkedHashSet<String>();
+
+ if ( ( repoMetadata != null ) && ( repoMetadata.getVersioning() != null ) )
+ {
+ versions.addAll( repoMetadata.getVersioning().getVersions() );
+ }
+
+ versions.addAll( availableVersions );
+
+ List<ArtifactVersion> artifactVersions = new ArrayList<ArtifactVersion>( versions.size() );
+
+ for ( String version : versions )
+ {
+ artifactVersions.add( new DefaultArtifactVersion( version ) );
+ }
+
+ return artifactVersions;
+ }
+
+ // USED BY MAVEN ASSEMBLY PLUGIN
+ @Deprecated
+ public static Set<Artifact> createArtifacts( ArtifactFactory artifactFactory, List<Dependency> dependencies,
+ String inheritedScope, ArtifactFilter dependencyFilter,
+ MavenProject project )
+ throws InvalidDependencyVersionException
+ {
+ Set<Artifact> artifacts = new LinkedHashSet<Artifact>();
+
+ for ( Dependency d : dependencies )
+ {
+ Artifact dependencyArtifact;
+ try
+ {
+ dependencyArtifact = createDependencyArtifact( artifactFactory, d, inheritedScope, dependencyFilter );
+ }
+ catch ( InvalidVersionSpecificationException e )
+ {
+ throw new InvalidDependencyVersionException( project.getId(), d, project.getFile(), e );
+ }
+
+ if ( dependencyArtifact != null )
+ {
+ artifacts.add( dependencyArtifact );
+ }
+ }
+
+ return artifacts;
+ }
+
+ private ProjectBuilder getProjectBuilder()
+ {
+ if ( projectBuilder != null )
+ {
+ return projectBuilder;
+ }
+
+ try
+ {
+ projectBuilder = container.lookup( ProjectBuilder.class );
+ }
+ catch ( ComponentLookupException e )
+ {
+ // Won't happen
+ }
+
+ return projectBuilder;
+ }
+
+ private ProjectRelocation retrieveRelocatedProject( Artifact artifact, MetadataResolutionRequest repositoryRequest )
+ throws ArtifactMetadataRetrievalException
+ {
+ MavenProject project;
+
+ Artifact pomArtifact;
+ Artifact relocatedArtifact = null;
+ boolean done = false;
+ do
+ {
+ project = null;
+
+ pomArtifact =
+ repositorySystem.createProjectArtifact( artifact.getGroupId(),
+ artifact.getArtifactId(),
+ artifact.getVersion(), artifact.getScope() );
+
+ if ( "pom".equals( artifact.getType() ) )
+ {
+ pomArtifact.setFile( artifact.getFile() );
+ }
+
+ if ( Artifact.SCOPE_SYSTEM.equals( artifact.getScope() ) )
+ {
+ done = true;
+ }
+ else
+ {
+ try
+ {
+ ProjectBuildingRequest configuration = new DefaultProjectBuildingRequest();
+ configuration.setLocalRepository( repositoryRequest.getLocalRepository() );
+ configuration.setRemoteRepositories( repositoryRequest.getRemoteRepositories() );
+ configuration.setValidationLevel( ModelBuildingRequest.VALIDATION_LEVEL_MINIMAL );
+ configuration.setProcessPlugins( false );
+ configuration.setRepositoryMerging( ProjectBuildingRequest.RepositoryMerging.REQUEST_DOMINANT );
+ configuration.setSystemProperties( getSystemProperties() );
+ configuration.setRepositorySession( legacySupport.getRepositorySession() );
+
+ project = getProjectBuilder().build( pomArtifact, configuration ).getProject();
+ }
+ catch ( ProjectBuildingException e )
+ {
+ ModelProblem missingParentPom = hasMissingParentPom( e );
+ if ( missingParentPom != null )
+ {
+ throw new ArtifactMetadataRetrievalException( "Failed to process POM for "
+ + artifact.getId() + ": " + missingParentPom.getMessage(),
+ missingParentPom.getException(),
+ artifact );
+ }
+
+ String message;
+
+ if ( isMissingPom( e ) )
+ {
+ message = "Missing POM for " + artifact.getId();
+ }
+ else if ( isNonTransferrablePom( e ) )
+ {
+ throw new ArtifactMetadataRetrievalException( "Failed to retrieve POM for "
+ + artifact.getId() + ": " + e.getCause().getMessage(), e.getCause(),
+ artifact );
+ }
+ else
+ {
+ message =
+ "Invalid POM for " + artifact.getId()
+ + ", transitive dependencies (if any) will not be available"
+ + ", enable debug logging for more details";
+ }
+
+ if ( logger.isDebugEnabled() )
+ {
+ message += ": " + e.getMessage();
+ }
+
+ logger.warn( message );
+ }
+
+ if ( project != null )
+ {
+ Relocation relocation = null;
+
+ DistributionManagement distMgmt = project.getDistributionManagement();
+ if ( distMgmt != null )
+ {
+ relocation = distMgmt.getRelocation();
+
+ artifact.setDownloadUrl( distMgmt.getDownloadUrl() );
+ pomArtifact.setDownloadUrl( distMgmt.getDownloadUrl() );
+ }
+
+ if ( relocation != null )
+ {
+ if ( relocation.getGroupId() != null )
+ {
+ artifact.setGroupId( relocation.getGroupId() );
+ relocatedArtifact = artifact;
+ project.setGroupId( relocation.getGroupId() );
+ }
+ if ( relocation.getArtifactId() != null )
+ {
+ artifact.setArtifactId( relocation.getArtifactId() );
+ relocatedArtifact = artifact;
+ project.setArtifactId( relocation.getArtifactId() );
+ }
+ if ( relocation.getVersion() != null )
+ {
+ // note: see MNG-3454. This causes a problem, but fixing it may break more.
+ artifact.setVersionRange( VersionRange.createFromVersion( relocation.getVersion() ) );
+ relocatedArtifact = artifact;
+ project.setVersion( relocation.getVersion() );
+ }
+
+ if ( artifact.getDependencyFilter() != null
+ && !artifact.getDependencyFilter().include( artifact ) )
+ {
+ return null;
+ }
+
+ // MNG-2861: the artifact data has changed. If the available versions where previously
+ // retrieved, we need to update it.
+ // TODO: shouldn't the versions be merged across relocations?
+ List<ArtifactVersion> available = artifact.getAvailableVersions();
+ if ( available != null && !available.isEmpty() )
+ {
+ MetadataResolutionRequest metadataRequest =
+ new DefaultMetadataResolutionRequest( repositoryRequest );
+ metadataRequest.setArtifact( artifact );
+ available = retrieveAvailableVersions( metadataRequest );
+ artifact.setAvailableVersions( available );
+ }
+
+ String message =
+ "\n This artifact has been relocated to " + artifact.getGroupId() + ":"
+ + artifact.getArtifactId() + ":" + artifact.getVersion() + ".\n";
+
+ if ( relocation.getMessage() != null )
+ {
+ message += " " + relocation.getMessage() + "\n";
+ }
+
+ if ( artifact.getDependencyTrail() != null && artifact.getDependencyTrail().size() == 1 )
+ {
+ logger.warn( "While downloading " + pomArtifact.getGroupId() + ":"
+ + pomArtifact.getArtifactId() + ":" + pomArtifact.getVersion() + message + "\n" );
+ }
+ else
+ {
+ logger.debug( "While downloading " + pomArtifact.getGroupId() + ":"
+ + pomArtifact.getArtifactId() + ":" + pomArtifact.getVersion() + message + "\n" );
+ }
+ }
+ else
+ {
+ done = true;
+ }
+ }
+ else
+ {
+ done = true;
+ }
+ }
+ }
+ while ( !done );
+
+ ProjectRelocation rel = new ProjectRelocation();
+ rel.project = project;
+ rel.pomArtifact = pomArtifact;
+ rel.relocatedArtifact = relocatedArtifact;
+
+ return rel;
+ }
+
+ private ModelProblem hasMissingParentPom( ProjectBuildingException e )
+ {
+ if ( e.getCause() instanceof ModelBuildingException )
+ {
+ ModelBuildingException mbe = (ModelBuildingException) e.getCause();
+ for ( ModelProblem problem : mbe.getProblems() )
+ {
+ if ( problem.getException() instanceof UnresolvableModelException )
+ {
+ return problem;
+ }
+ }
+
+ }
+ return null;
+ }
+
+ private boolean isMissingPom( Exception e )
+ {
+ if ( e.getCause() instanceof MultipleArtifactsNotFoundException )
+ {
+ return true;
+ }
+ return e.getCause() instanceof org.eclipse.aether.resolution.ArtifactResolutionException
+ && e.getCause().getCause() instanceof ArtifactNotFoundException;
+ }
+
+ private boolean isNonTransferrablePom( Exception e )
+ {
+ if ( e.getCause() instanceof ArtifactResolutionException )
+ {
+ return true;
+ }
+ return e.getCause() instanceof org.eclipse.aether.resolution.ArtifactResolutionException
+ && !( e.getCause().getCause() instanceof ArtifactNotFoundException );
+ }
+
+ private Properties getSystemProperties()
+ {
+ Properties props = new Properties();
+
+ EnvironmentUtils.addEnvVars( props );
+
+ SystemProperties.addSystemProperties( props );
+
+ return props;
+ }
+
+ private static final class ProjectRelocation
+ {
+ private MavenProject project;
+
+ private Artifact pomArtifact;
+
+ private Artifact relocatedArtifact;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/artifact/PluginArtifact.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/artifact/PluginArtifact.java
new file mode 100644
index 00000000..d348d59c
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/artifact/PluginArtifact.java
@@ -0,0 +1,94 @@
+package org.apache.maven.project.artifact;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.DefaultArtifact;
+import org.apache.maven.artifact.handler.ArtifactHandler;
+import org.apache.maven.model.Dependency;
+import org.apache.maven.model.Plugin;
+
+public class PluginArtifact
+ extends DefaultArtifact
+ implements ArtifactWithDependencies
+{
+ private Plugin plugin;
+
+ public PluginArtifact( Plugin plugin, Artifact pluginArtifact )
+ {
+ super( plugin.getGroupId(), plugin.getArtifactId(), plugin.getVersion(), null, "maven-plugin", null,
+ new PluginArtifactHandler() );
+ this.plugin = plugin;
+ setFile( pluginArtifact.getFile() );
+ setResolved( true );
+ }
+
+ public List<Dependency> getDependencies()
+ {
+ return plugin.getDependencies();
+ }
+
+ public List<Dependency> getManagedDependencies()
+ {
+ return Collections.emptyList();
+ }
+
+ static class PluginArtifactHandler
+ implements ArtifactHandler
+ {
+ public String getClassifier()
+ {
+ return null;
+ }
+
+ public String getDirectory()
+ {
+ return null;
+ }
+
+ public String getExtension()
+ {
+ return "jar";
+ }
+
+ public String getLanguage()
+ {
+ return "none";
+ }
+
+ public String getPackaging()
+ {
+ return "maven-plugin";
+ }
+
+ public boolean isAddedToClasspath()
+ {
+ return true;
+ }
+
+ public boolean isIncludesDependencies()
+ {
+ return false;
+ }
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/artifact/ProjectArtifact.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/artifact/ProjectArtifact.java
new file mode 100644
index 00000000..1d4a2a31
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/artifact/ProjectArtifact.java
@@ -0,0 +1,100 @@
+package org.apache.maven.project.artifact;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.maven.artifact.DefaultArtifact;
+import org.apache.maven.artifact.handler.ArtifactHandler;
+import org.apache.maven.model.Dependency;
+import org.apache.maven.model.DependencyManagement;
+import org.apache.maven.project.MavenProject;
+
+public class ProjectArtifact
+ extends DefaultArtifact
+ implements ArtifactWithDependencies
+{
+ private MavenProject project;
+
+ public ProjectArtifact( MavenProject project )
+ {
+ super( project.getGroupId(), project.getArtifactId(), project.getVersion(), null, "pom", null,
+ new PomArtifactHandler() );
+ this.project = project;
+ setFile( project.getFile() );
+ setResolved( true );
+ }
+
+ public MavenProject getProject()
+ {
+ return project;
+ }
+
+ public List<Dependency> getDependencies()
+ {
+ return project.getDependencies();
+ }
+
+ public List<Dependency> getManagedDependencies()
+ {
+ DependencyManagement depMngt = project.getDependencyManagement();
+ return ( depMngt != null ) ? depMngt.getDependencies() : Collections.<Dependency>emptyList();
+ }
+
+ static class PomArtifactHandler
+ implements ArtifactHandler
+ {
+ public String getClassifier()
+ {
+ return null;
+ }
+
+ public String getDirectory()
+ {
+ return null;
+ }
+
+ public String getExtension()
+ {
+ return "pom";
+ }
+
+ public String getLanguage()
+ {
+ return "none";
+ }
+
+ public String getPackaging()
+ {
+ return "pom";
+ }
+
+ public boolean isAddedToClasspath()
+ {
+ return false;
+ }
+
+ public boolean isIncludesDependencies()
+ {
+ return false;
+ }
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/artifact/ProjectArtifactMetadata.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/artifact/ProjectArtifactMetadata.java
new file mode 100644
index 00000000..7ea99bf0
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/artifact/ProjectArtifactMetadata.java
@@ -0,0 +1,130 @@
+package org.apache.maven.project.artifact;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.metadata.AbstractArtifactMetadata;
+import org.apache.maven.artifact.metadata.ArtifactMetadata;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.repository.metadata.RepositoryMetadataStoreException;
+import org.codehaus.plexus.util.FileUtils;
+
+/**
+ * Attach a POM to an artifact.
+ *
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ */
+public class ProjectArtifactMetadata
+ extends AbstractArtifactMetadata
+{
+ private final File file;
+
+ public ProjectArtifactMetadata( Artifact artifact )
+ {
+ this( artifact, null );
+ }
+
+ public ProjectArtifactMetadata( Artifact artifact, File file )
+ {
+ super( artifact );
+ this.file = file;
+ }
+
+ public File getFile()
+ {
+ return file;
+ }
+
+ public String getRemoteFilename()
+ {
+ return getFilename();
+ }
+
+ public String getLocalFilename( ArtifactRepository repository )
+ {
+ return getFilename();
+ }
+
+ private String getFilename()
+ {
+ return getArtifactId() + "-" + artifact.getVersion() + ".pom";
+ }
+
+ public void storeInLocalRepository( ArtifactRepository localRepository, ArtifactRepository remoteRepository )
+ throws RepositoryMetadataStoreException
+ {
+ File destination =
+ new File( localRepository.getBasedir(), localRepository.pathOfLocalRepositoryMetadata( this,
+ remoteRepository ) );
+
+ // ----------------------------------------------------------------------------
+ // I'm fully aware that the file could just be moved using File.rename but
+ // there are bugs in various JVM that have problems doing this across
+ // different filesystem. So we'll incur the small hit to actually copy
+ // here and be safe. jvz.
+ // ----------------------------------------------------------------------------
+
+ try
+ {
+ FileUtils.copyFile( file, destination );
+ }
+ catch ( IOException e )
+ {
+ throw new RepositoryMetadataStoreException( "Error copying POM to the local repository.", e );
+ }
+ }
+
+ public String toString()
+ {
+ return "project information for " + artifact.getArtifactId() + " " + artifact.getVersion();
+ }
+
+ public boolean storedInArtifactVersionDirectory()
+ {
+ return true;
+ }
+
+ public String getBaseVersion()
+ {
+ return artifact.getBaseVersion();
+ }
+
+ public Object getKey()
+ {
+ return "project " + artifact.getGroupId() + ":" + artifact.getArtifactId();
+ }
+
+ public void merge( ArtifactMetadata metadata )
+ {
+ ProjectArtifactMetadata m = (ProjectArtifactMetadata) metadata;
+ if ( !m.file.equals( file ) )
+ {
+ throw new IllegalStateException( "Cannot add two different pieces of metadata for: " + getKey() );
+ }
+ }
+
+ public void merge( org.apache.maven.repository.legacy.metadata.ArtifactMetadata metadata )
+ {
+ this.merge( (ArtifactMetadata) metadata );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/path/PathTranslator.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/path/PathTranslator.java
new file mode 100644
index 00000000..18e349ac
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/project/path/PathTranslator.java
@@ -0,0 +1,41 @@
+package org.apache.maven.project.path;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+
+import org.apache.maven.model.Model;
+
+/**
+ * @author Jason van Zyl
+ */
+@Deprecated
+public interface PathTranslator
+{
+ String ROLE = PathTranslator.class.getName();
+
+ void alignToBaseDirectory( Model model, File basedir );
+
+ String alignToBaseDirectory( String path, File basedir );
+
+ void unalignFromBaseDirectory( Model model, File basedir );
+
+ String unalignFromBaseDirectory( String directory, File basedir );
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/properties/internal/EnvironmentUtils.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/properties/internal/EnvironmentUtils.java
new file mode 100644
index 00000000..2c3196fb
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/properties/internal/EnvironmentUtils.java
@@ -0,0 +1,70 @@
+package org.apache.maven.properties.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Locale;
+import java.util.Map;
+import java.util.Properties;
+
+import org.codehaus.plexus.util.Os;
+
+/**
+ * Assists the project builder. <strong>Warning:</strong> This is an internal utility class that is only public for
+ * technical reasons, it is not part of the public API. In particular, this class can be changed or deleted without
+ * prior notice.
+ *
+ * @since 3.0
+ * @author Benjamin Bentmann
+ */
+public class EnvironmentUtils
+{
+
+ private static Properties envVars;
+
+ /**
+ * Adds the environment variables in the form of properties whose keys are prefixed with {@code env.}, e.g. {@code
+ * env.PATH}. Unlike native environment variables, properties are always case-sensitive. For the sake of
+ * determinism, the environment variable names will be normalized to upper case on platforms with case-insensitive
+ * variable lookup.
+ *
+ * @param props The properties to add the environment variables to, may be {@code null}.
+ */
+ public static void addEnvVars( Properties props )
+ {
+ if ( props != null )
+ {
+ if ( envVars == null )
+ {
+ Properties tmp = new Properties();
+ boolean caseSensitive = !Os.isFamily( Os.FAMILY_WINDOWS );
+ for ( Map.Entry<String, String> entry : System.getenv().entrySet() )
+ {
+ String key =
+ "env." + ( caseSensitive ? entry.getKey() : entry.getKey().toUpperCase( Locale.ENGLISH ) );
+ tmp.setProperty( key, entry.getValue() );
+ }
+ envVars = tmp;
+ }
+
+ props.putAll( envVars );
+ }
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/properties/internal/SystemProperties.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/properties/internal/SystemProperties.java
new file mode 100644
index 00000000..608df2dc
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/properties/internal/SystemProperties.java
@@ -0,0 +1,51 @@
+package org.apache.maven.properties.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Properties;
+
+/**
+ * @since 3.2.3
+ */
+public class SystemProperties
+{
+ /**
+ * Thread-safe System.properties copy implementation.
+ *
+ * @see http://jira.codehaus.org/browse/MNG-5670
+ */
+ public static void addSystemProperties( Properties props )
+ {
+ for ( String key : System.getProperties().stringPropertyNames() )
+ {
+ props.put( key, System.getProperty( key ) );
+ }
+ }
+
+ /**
+ * Returns System.properties copy.
+ */
+ public static Properties getSystemProperties()
+ {
+ Properties systemProperties = new Properties();
+ addSystemProperties( systemProperties );
+ return systemProperties;
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/repository/ArtifactDoesNotExistException.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/repository/ArtifactDoesNotExistException.java
new file mode 100644
index 00000000..296f4ea5
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/repository/ArtifactDoesNotExistException.java
@@ -0,0 +1,34 @@
+package org.apache.maven.repository;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+public class ArtifactDoesNotExistException
+ extends Exception
+{
+ public ArtifactDoesNotExistException( final String message )
+ {
+ super( message );
+ }
+
+ public ArtifactDoesNotExistException( final String message, final Throwable cause )
+ {
+ super( message, cause );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/repository/ArtifactTransferEvent.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/repository/ArtifactTransferEvent.java
new file mode 100644
index 00000000..80189e7b
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/repository/ArtifactTransferEvent.java
@@ -0,0 +1,343 @@
+package org.apache.maven.repository;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+
+import java.io.File;
+import java.util.EventObject;
+
+/**
+ * TransferEvent is used to notify TransferListeners about progress
+ * in transfer of resources form/to the repository
+ *
+ * @author <a href="michal.maczka@dimatics.com">Michal Maczka</a>
+ */
+public class ArtifactTransferEvent
+ extends EventObject
+{
+ /**
+ * A transfer was attempted, but has not yet commenced.
+ */
+ public static final int TRANSFER_INITIATED = 0;
+
+ /**
+ * A transfer was started.
+ */
+ public static final int TRANSFER_STARTED = 1;
+
+ /**
+ * A transfer is completed.
+ */
+ public static final int TRANSFER_COMPLETED = 2;
+
+ /**
+ * A transfer is in progress.
+ */
+ public static final int TRANSFER_PROGRESS = 3;
+
+ /**
+ * An error occurred during transfer
+ */
+ public static final int TRANSFER_ERROR = 4;
+
+ /**
+ * Indicates GET transfer (from the repository)
+ */
+ public static final int REQUEST_GET = 5;
+
+ /**
+ * Indicates PUT transfer (to the repository)
+ */
+ public static final int REQUEST_PUT = 6;
+
+ private int eventType;
+
+ private int requestType;
+
+ private Exception exception;
+
+ private File localFile;
+
+ private ArtifactTransferResource artifact;
+
+ private long transferredBytes;
+
+ private byte[] dataBuffer;
+
+ private int dataOffset;
+
+ private int dataLength;
+
+ public ArtifactTransferEvent( String wagon, final int eventType, final int requestType,
+ ArtifactTransferResource artifact )
+ {
+ super( wagon );
+
+ setEventType( eventType );
+
+ setRequestType( requestType );
+
+ this.artifact = artifact;
+ }
+
+ public ArtifactTransferEvent( String wagon, final Exception exception, final int requestType,
+ ArtifactTransferResource artifact )
+ {
+ this( wagon, TRANSFER_ERROR, requestType, artifact );
+
+ this.exception = exception;
+ }
+
+ public ArtifactTransferResource getResource()
+ {
+ return artifact;
+ }
+
+ /**
+ * @return Returns the exception.
+ */
+ public Exception getException()
+ {
+ return exception;
+ }
+
+ /**
+ * Returns the request type.
+ *
+ * @return Returns the request type. The Request type is one of
+ * <code>TransferEvent.REQUEST_GET<code> or <code>TransferEvent.REQUEST_PUT<code>
+ */
+ public int getRequestType()
+ {
+ return requestType;
+ }
+
+ /**
+ * Sets the request type
+ *
+ * @param requestType The requestType to set.
+ * The Request type value should be either
+ * <code>TransferEvent.REQUEST_GET<code> or <code>TransferEvent.REQUEST_PUT<code>.
+ * @throws IllegalArgumentException when
+ */
+ public void setRequestType( final int requestType )
+ {
+ switch ( requestType )
+ {
+
+ case REQUEST_PUT:
+ break;
+ case REQUEST_GET:
+ break;
+
+ default :
+ throw new IllegalArgumentException( "Illegal request type: " + requestType );
+ }
+
+ this.requestType = requestType;
+ }
+
+ /**
+ * @return Returns the eventType.
+ */
+ public int getEventType()
+ {
+ return eventType;
+ }
+
+ /**
+ * @param eventType The eventType to set.
+ */
+ public void setEventType( final int eventType )
+ {
+ switch ( eventType )
+ {
+
+ case TRANSFER_INITIATED:
+ break;
+ case TRANSFER_STARTED:
+ break;
+ case TRANSFER_COMPLETED:
+ break;
+ case TRANSFER_PROGRESS:
+ break;
+ case TRANSFER_ERROR:
+ break;
+ default :
+ throw new IllegalArgumentException( "Illegal event type: " + eventType );
+ }
+
+ this.eventType = eventType;
+ }
+
+ /**
+ * @return Returns the local file.
+ */
+ public File getLocalFile()
+ {
+ return localFile;
+ }
+
+ /**
+ * @param localFile The local file to set.
+ */
+ public void setLocalFile( File localFile )
+ {
+ this.localFile = localFile;
+ }
+
+ public long getTransferredBytes()
+ {
+ return transferredBytes;
+ }
+
+ public void setTransferredBytes( long transferredBytes )
+ {
+ this.transferredBytes = transferredBytes;
+ }
+
+ public byte[] getDataBuffer()
+ {
+ return dataBuffer;
+ }
+
+ public void setDataBuffer( byte[] dataBuffer )
+ {
+ this.dataBuffer = dataBuffer;
+ }
+
+ public int getDataOffset()
+ {
+ return dataOffset;
+ }
+
+ public void setDataOffset( int dataOffset )
+ {
+ this.dataOffset = dataOffset;
+ }
+
+ public int getDataLength()
+ {
+ return dataLength;
+ }
+
+ public void setDataLength( int dataLength )
+ {
+ this.dataLength = dataLength;
+ }
+
+ public String toString()
+ {
+ StringBuilder sb = new StringBuilder();
+
+ sb.append( "TransferEvent[" );
+
+ switch ( this.getRequestType() )
+ {
+ case REQUEST_GET:
+ sb.append( "GET" );
+ break;
+ case REQUEST_PUT:
+ sb.append( "PUT" );
+ break;
+ default:
+ sb.append( this.getRequestType() );
+ break;
+ }
+
+ sb.append( "|" );
+ switch ( this.getEventType() )
+ {
+ case TRANSFER_COMPLETED:
+ sb.append( "COMPLETED" );
+ break;
+ case TRANSFER_ERROR:
+ sb.append( "ERROR" );
+ break;
+ case TRANSFER_INITIATED:
+ sb.append( "INITIATED" );
+ break;
+ case TRANSFER_PROGRESS:
+ sb.append( "PROGRESS" );
+ break;
+ case TRANSFER_STARTED:
+ sb.append( "STARTED" );
+ break;
+ default:
+ sb.append( this.getEventType() );
+ break;
+ }
+
+ sb.append( "|" );
+ sb.append( this.getLocalFile() ).append( "|" );
+ sb.append( "]" );
+
+ return sb.toString();
+ }
+
+ public int hashCode()
+ {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + eventType;
+ result = prime * result + ( ( exception == null ) ? 0 : exception.hashCode() );
+ result = prime * result + ( ( localFile == null ) ? 0 : localFile.hashCode() );
+ result = prime * result + requestType;
+ return result;
+ }
+
+ public boolean equals( Object obj )
+ {
+ if ( this == obj )
+ {
+ return true;
+ }
+ if ( ( obj == null ) || ( getClass() != obj.getClass() ) )
+ {
+ return false;
+ }
+ final ArtifactTransferEvent other = (ArtifactTransferEvent) obj;
+ if ( eventType != other.eventType )
+ {
+ return false;
+ }
+ if ( exception == null )
+ {
+ if ( other.exception != null )
+ {
+ return false;
+ }
+ }
+ else if ( !exception.getClass().equals( other.exception.getClass() ) )
+ {
+ return false;
+ }
+ if ( requestType != other.requestType )
+ {
+ return false;
+ }
+ else if ( !source.equals( other.source ) )
+ {
+ return false;
+ }
+ return true;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/repository/ArtifactTransferFailedException.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/repository/ArtifactTransferFailedException.java
new file mode 100644
index 00000000..9315f4c7
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/repository/ArtifactTransferFailedException.java
@@ -0,0 +1,35 @@
+package org.apache.maven.repository;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+public class ArtifactTransferFailedException
+ extends Exception
+{
+ public ArtifactTransferFailedException( final String message )
+ {
+ super( message );
+ }
+
+ public ArtifactTransferFailedException( final String message, final Throwable cause )
+ {
+ super( message, cause );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/repository/ArtifactTransferListener.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/repository/ArtifactTransferListener.java
new file mode 100644
index 00000000..72a56cf0
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/repository/ArtifactTransferListener.java
@@ -0,0 +1,36 @@
+package org.apache.maven.repository;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+public interface ArtifactTransferListener
+{
+ boolean isShowChecksumEvents();
+
+ void setShowChecksumEvents( boolean showChecksumEvents );
+
+ void transferInitiated( ArtifactTransferEvent transferEvent );
+
+ void transferStarted( ArtifactTransferEvent transferEvent );
+
+ void transferProgress( ArtifactTransferEvent transferEvent );
+
+ void transferCompleted( ArtifactTransferEvent transferEvent );
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/repository/ArtifactTransferResource.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/repository/ArtifactTransferResource.java
new file mode 100644
index 00000000..8ed081ff
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/repository/ArtifactTransferResource.java
@@ -0,0 +1,66 @@
+package org.apache.maven.repository;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Describes a resource being uploaded or downloaded by the repository system.
+ *
+ * @author Benjamin Bentmann
+ */
+public interface ArtifactTransferResource
+{
+
+ /**
+ * The base URL of the repository, e.g. "http://repo1.maven.org/maven2/". Unless the URL is unknown, it will be
+ * terminated by a trailing slash.
+ *
+ * @return The base URL of the repository or an empty string if unknown, never {@code null}.
+ */
+ String getRepositoryUrl();
+
+ /**
+ * The path of the artifact relative to the repository's base URL.
+ *
+ * @return The path of the artifact, never {@code null}.
+ */
+ String getName();
+
+ /**
+ * Gets the full URL of the artifact.
+ *
+ * @return The full URL of the artifact, never {@code null}.
+ */
+ String getUrl();
+
+ /**
+ * The size of the artifact in bytes.
+ *
+ * @return The of the artifact in bytes or a negative value if unknown.
+ */
+ long getContentLength();
+
+ /**
+ * Gets the timestamp when the transfer of this artifact was started.
+ *
+ * @return The timestamp when the transfer of this artifact was started.
+ */
+ long getTransferStartTime();
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/repository/DelegatingLocalArtifactRepository.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/repository/DelegatingLocalArtifactRepository.java
new file mode 100644
index 00000000..f47cb4b1
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/repository/DelegatingLocalArtifactRepository.java
@@ -0,0 +1,195 @@
+package org.apache.maven.repository;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedHashSet;
+import java.util.List;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.metadata.ArtifactMetadata;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy;
+import org.apache.maven.artifact.repository.MavenArtifactRepository;
+import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout;
+
+/**
+ * Delegating local artifact repository chains the reactor, IDE workspace
+ * and user local repository.
+ */
+@Deprecated
+public class DelegatingLocalArtifactRepository
+ extends MavenArtifactRepository
+{
+ private LocalArtifactRepository buildReactor;
+
+ private LocalArtifactRepository ideWorkspace;
+
+ private ArtifactRepository userLocalArtifactRepository;
+
+ public DelegatingLocalArtifactRepository( ArtifactRepository artifactRepository )
+ {
+ this.userLocalArtifactRepository = artifactRepository;
+ }
+
+ public void setBuildReactor( LocalArtifactRepository localRepository )
+ {
+ this.buildReactor = localRepository;
+ }
+
+ public void setIdeWorkspace( LocalArtifactRepository localRepository )
+ {
+ this.ideWorkspace = localRepository;
+ }
+
+ public LocalArtifactRepository getIdeWorspace()
+ {
+ return ideWorkspace;
+ }
+
+ @Override
+ public Artifact find( Artifact artifact )
+ {
+ if ( !artifact.isRelease() && buildReactor != null )
+ {
+ artifact = buildReactor.find( artifact );
+ }
+
+ if ( !artifact.isResolved() && ideWorkspace != null )
+ {
+ artifact = ideWorkspace.find( artifact );
+ }
+
+ if ( !artifact.isResolved() )
+ {
+ artifact = userLocalArtifactRepository.find( artifact );
+ }
+
+ return artifact;
+ }
+
+ @Override
+ public List<String> findVersions( Artifact artifact )
+ {
+ Collection<String> versions = new LinkedHashSet<String>();
+
+ if ( buildReactor != null )
+ {
+ versions.addAll( buildReactor.findVersions( artifact ) );
+ }
+
+ if ( ideWorkspace != null )
+ {
+ versions.addAll( ideWorkspace.findVersions( artifact ) );
+ }
+
+ versions.addAll( userLocalArtifactRepository.findVersions( artifact ) );
+
+ return Collections.unmodifiableList( new ArrayList<String>( versions ) );
+ }
+
+ public String pathOfLocalRepositoryMetadata( ArtifactMetadata metadata, ArtifactRepository repository )
+ {
+ return userLocalArtifactRepository.pathOfLocalRepositoryMetadata( metadata, repository );
+ }
+
+ public String getId()
+ {
+ return userLocalArtifactRepository.getId();
+ }
+
+ @Override
+ public String pathOf( Artifact artifact )
+ {
+ return userLocalArtifactRepository.pathOf( artifact );
+ }
+
+ @Override
+ public String getBasedir()
+ {
+ return ( userLocalArtifactRepository != null ) ? userLocalArtifactRepository.getBasedir() : null;
+ }
+
+ @Override
+ public ArtifactRepositoryLayout getLayout()
+ {
+ return userLocalArtifactRepository.getLayout();
+ }
+
+ @Override
+ public ArtifactRepositoryPolicy getReleases()
+ {
+ return userLocalArtifactRepository.getReleases();
+ }
+
+ @Override
+ public ArtifactRepositoryPolicy getSnapshots()
+ {
+ return userLocalArtifactRepository.getSnapshots();
+ }
+
+ @Override
+ public String getKey()
+ {
+ return userLocalArtifactRepository.getKey();
+ }
+
+ @Override
+ public String getUrl()
+ {
+ return userLocalArtifactRepository.getUrl();
+ }
+
+ @Override
+ public int hashCode()
+ {
+ int hash = 17;
+ hash = hash * 31 + ( buildReactor == null ? 0 : buildReactor.hashCode() );
+ hash = hash * 31 + ( ideWorkspace == null ? 0 : ideWorkspace.hashCode() );
+ hash = hash * 31 + ( userLocalArtifactRepository == null ? 0 : userLocalArtifactRepository.hashCode() );
+
+ return hash;
+ }
+
+ @Override
+ public boolean equals( Object obj )
+ {
+ if ( this == obj )
+ {
+ return true;
+ }
+ if ( obj == null )
+ {
+ return false;
+ }
+ if ( getClass() != obj.getClass() )
+ {
+ return false;
+ }
+
+ DelegatingLocalArtifactRepository other = (DelegatingLocalArtifactRepository) obj;
+
+ return eq( buildReactor, other.buildReactor )
+ && eq( ideWorkspace, other.ideWorkspace )
+ && eq( userLocalArtifactRepository, other.userLocalArtifactRepository );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/repository/LocalArtifactRepository.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/repository/LocalArtifactRepository.java
new file mode 100644
index 00000000..e33789e3
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/repository/LocalArtifactRepository.java
@@ -0,0 +1,33 @@
+package org.apache.maven.repository;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.repository.MavenArtifactRepository;
+
+public abstract class LocalArtifactRepository
+ extends MavenArtifactRepository
+{
+ public static final String IDE_WORKSPACE = "ide-workspace";
+
+ public abstract Artifact find( Artifact artifact );
+
+ public abstract boolean hasLocalMetadata();
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/repository/LocalRepositoryNotAccessibleException.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/repository/LocalRepositoryNotAccessibleException.java
new file mode 100644
index 00000000..54e4ef4b
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/repository/LocalRepositoryNotAccessibleException.java
@@ -0,0 +1,44 @@
+package org.apache.maven.repository;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.IOException;
+
+/**
+ * Signals a failure to store files within the local repository.
+ *
+ * @author Benjamin Bentmann
+ */
+public class LocalRepositoryNotAccessibleException
+ extends IOException
+{
+
+ public LocalRepositoryNotAccessibleException( String message, Throwable cause )
+ {
+ super( message );
+ initCause( cause );
+ }
+
+ public LocalRepositoryNotAccessibleException( String message )
+ {
+ super( message );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/repository/RepositorySystem.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/repository/RepositorySystem.java
new file mode 100644
index 00000000..fcc0f777
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/repository/RepositorySystem.java
@@ -0,0 +1,164 @@
+package org.apache.maven.repository;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.util.List;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.InvalidRepositoryException;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy;
+import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout;
+import org.apache.maven.artifact.resolver.ArtifactResolutionRequest;
+import org.apache.maven.artifact.resolver.ArtifactResolutionResult;
+import org.apache.maven.model.Dependency;
+import org.apache.maven.model.Plugin;
+import org.apache.maven.model.Repository;
+import org.apache.maven.settings.Mirror;
+import org.apache.maven.settings.Server;
+import org.eclipse.aether.RepositorySystemSession;
+
+/**
+ * @author Jason van Zyl
+ * @since 3.0-alpha
+ */
+public interface RepositorySystem
+{
+ String DEFAULT_LOCAL_REPO_ID = "local";
+
+ String userHome = System.getProperty( "user.home" );
+
+ File userMavenConfigurationHome = new File( userHome, ".m2" );
+
+ File defaultUserLocalRepository = new File( userMavenConfigurationHome, "repository" );
+
+ String DEFAULT_REMOTE_REPO_ID = "central";
+
+ String DEFAULT_REMOTE_REPO_URL = "https://repo.maven.apache.org/maven2";
+
+ Artifact createArtifact( String groupId, String artifactId, String version, String packaging );
+
+ Artifact createArtifact( String groupId, String artifactId, String version, String scope, String type );
+
+ Artifact createProjectArtifact( String groupId, String artifactId, String version );
+
+ Artifact createArtifactWithClassifier( String groupId, String artifactId, String version, String type,
+ String classifier );
+
+ Artifact createPluginArtifact( Plugin plugin );
+
+ Artifact createDependencyArtifact( Dependency dependency );
+
+ ArtifactRepository buildArtifactRepository( Repository repository )
+ throws InvalidRepositoryException;
+
+ ArtifactRepository createDefaultRemoteRepository()
+ throws InvalidRepositoryException;
+
+ ArtifactRepository createDefaultLocalRepository()
+ throws InvalidRepositoryException;
+
+ ArtifactRepository createLocalRepository( File localRepository )
+ throws InvalidRepositoryException;
+
+ ArtifactRepository createArtifactRepository( String id, String url, ArtifactRepositoryLayout repositoryLayout,
+ ArtifactRepositoryPolicy snapshots,
+ ArtifactRepositoryPolicy releases );
+
+ /**
+ * Calculates the effective repositories for the given input repositories which are assumed to be already mirrored
+ * (if applicable). This process will essentially remove duplicate repositories by merging them into one equivalent
+ * repository. It is worth to point out that merging does not simply choose one of the input repositories and
+ * discards the others but actually combines their possibly different policies.
+ *
+ * @param repositories The original repositories, may be {@code null}.
+ * @return The effective repositories or {@code null} if the input was {@code null}.
+ */
+ List<ArtifactRepository> getEffectiveRepositories( List<ArtifactRepository> repositories );
+
+ /**
+ * Determines the mirror for the specified repository.
+ *
+ * @param repository The repository to determine the mirror for, must not be {@code null}.
+ * @param mirrors The available mirrors, may be {@code null}.
+ * @return The mirror specification for the repository or {@code null} if no mirror matched.
+ */
+ Mirror getMirror( ArtifactRepository repository, List<Mirror> mirrors );
+
+ /**
+ * Injects the mirroring information into the specified repositories. For each repository that is matched by a
+ * mirror, its URL and ID will be updated to match the values from the mirror specification. Repositories without a
+ * matching mirror will pass through unchanged. <em>Note:</em> This method must be called before
+ * {@link #injectAuthentication(List, List)} or the repositories will end up with the wrong credentials.
+ *
+ * @param repositories The repositories into which to inject the mirror information, may be {@code null}.
+ * @param mirrors The available mirrors, may be {@code null}.
+ */
+ void injectMirror( List<ArtifactRepository> repositories, List<Mirror> mirrors );
+
+ /**
+ * Injects the proxy information into the specified repositories. For each repository that is matched by a proxy,
+ * its proxy data will be set accordingly. Repositories without a matching proxy will have their proxy cleared.
+ * <em>Note:</em> This method must be called after {@link #injectMirror(List, List)} or the repositories will end up
+ * with the wrong proxies.
+ *
+ * @param repositories The repositories into which to inject the proxy information, may be {@code null}.
+ * @param proxies The available proxies, may be {@code null}.
+ */
+ void injectProxy( List<ArtifactRepository> repositories, List<org.apache.maven.settings.Proxy> proxies );
+
+ /**
+ * Injects the authentication information into the specified repositories. For each repository that is matched by a
+ * server, its credentials will be updated to match the values from the server specification. Repositories without a
+ * matching server will have their credentials cleared. <em>Note:</em> This method must be called after
+ * {@link #injectMirror(List, List)} or the repositories will end up with the wrong credentials.
+ *
+ * @param repositories The repositories into which to inject the authentication information, may be {@code null}.
+ * @param servers The available servers, may be {@code null}.
+ */
+ void injectAuthentication( List<ArtifactRepository> repositories, List<Server> servers );
+
+ void injectMirror( RepositorySystemSession session, List<ArtifactRepository> repositories );
+
+ void injectProxy( RepositorySystemSession session, List<ArtifactRepository> repositories );
+
+ void injectAuthentication( RepositorySystemSession session, List<ArtifactRepository> repositories );
+
+ ArtifactResolutionResult resolve( ArtifactResolutionRequest request );
+
+ // Install
+
+ // Deploy
+
+ // Map types of artifacts
+
+ //
+ // Raw file transfers
+ //
+ void publish( ArtifactRepository repository, File source, String remotePath,
+ ArtifactTransferListener transferListener )
+ throws ArtifactTransferFailedException;
+
+ void retrieve( ArtifactRepository repository, File destination, String remotePath,
+ ArtifactTransferListener transferListener )
+ throws ArtifactTransferFailedException, ArtifactDoesNotExistException;
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/repository/legacy/metadata/AbstractArtifactMetadata.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/repository/legacy/metadata/AbstractArtifactMetadata.java
new file mode 100644
index 00000000..352e5bbb
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/repository/legacy/metadata/AbstractArtifactMetadata.java
@@ -0,0 +1,65 @@
+package org.apache.maven.repository.legacy.metadata;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.artifact.Artifact;
+
+/**
+ * Common elements of artifact metadata.
+ *
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ */
+public abstract class AbstractArtifactMetadata
+ implements ArtifactMetadata
+{
+ protected Artifact artifact;
+
+ protected AbstractArtifactMetadata( Artifact artifact )
+ {
+ this.artifact = artifact;
+ }
+
+ public boolean storedInGroupDirectory()
+ {
+ return false;
+ }
+
+ public String getGroupId()
+ {
+ return artifact.getGroupId();
+ }
+
+ public String getArtifactId()
+ {
+ return artifact.getArtifactId();
+ }
+
+ public String extendedToString()
+ {
+ StringBuilder buffer = new StringBuilder();
+
+ buffer.append( "\nArtifact Metadata\n--------------------------" );
+ buffer.append( "\nGroupId: " ).append( getGroupId() );
+ buffer.append( "\nArtifactId: " ).append( getArtifactId() );
+ buffer.append( "\nMetadata Type: " ).append( getClass().getName() );
+
+ return buffer.toString();
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/repository/legacy/metadata/ArtifactMetadataRetrievalException.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/repository/legacy/metadata/ArtifactMetadataRetrievalException.java
new file mode 100644
index 00000000..67b4080b
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/repository/legacy/metadata/ArtifactMetadataRetrievalException.java
@@ -0,0 +1,68 @@
+package org.apache.maven.repository.legacy.metadata;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.artifact.Artifact;
+
+/**
+ * Error while retrieving repository metadata from the repository.
+ *
+ * @author <a href="mailto:jason@maven.org">Jason van Zyl</a>
+ */
+public class ArtifactMetadataRetrievalException
+ extends Exception
+{
+ private Artifact artifact;
+
+ /** @deprecated use {@link #ArtifactMetadataRetrievalException(String, Throwable, Artifact)} */
+ @Deprecated
+ public ArtifactMetadataRetrievalException( String message )
+ {
+ this( message, null, null );
+ }
+
+ /** @deprecated use {@link #ArtifactMetadataRetrievalException(String, Throwable, Artifact)} */
+ @Deprecated
+ public ArtifactMetadataRetrievalException( Throwable cause )
+ {
+ this( null, cause, null );
+ }
+
+ /** @deprecated use {@link #ArtifactMetadataRetrievalException(String, Throwable, Artifact)} */
+ @Deprecated
+ public ArtifactMetadataRetrievalException( String message,
+ Throwable cause )
+ {
+ this( message, cause, null );
+ }
+
+ public ArtifactMetadataRetrievalException( String message,
+ Throwable cause,
+ Artifact artifact )
+ {
+ super( message, cause );
+ this.artifact = artifact;
+ }
+
+ public Artifact getArtifact()
+ {
+ return artifact;
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/repository/legacy/metadata/ArtifactMetadataSource.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/repository/legacy/metadata/ArtifactMetadataSource.java
new file mode 100644
index 00000000..aaa0ee34
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/repository/legacy/metadata/ArtifactMetadataSource.java
@@ -0,0 +1,78 @@
+package org.apache.maven.repository.legacy.metadata;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.List;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.versioning.ArtifactVersion;
+
+/**
+ * Provides some metadata operations, like querying the remote repository for a list of versions available for an
+ * artifact.
+ *
+ * @author <a href="mailto:jason@maven.org">Jason van Zyl </a>
+ */
+public interface ArtifactMetadataSource
+{
+
+ ResolutionGroup retrieve( MetadataResolutionRequest request )
+ throws ArtifactMetadataRetrievalException;
+
+ ResolutionGroup retrieve( Artifact artifact, ArtifactRepository localRepository,
+ List<ArtifactRepository> remoteRepositories )
+ throws ArtifactMetadataRetrievalException;
+
+ /**
+ * Get a list of available versions for an artifact in the remote repository
+ *
+ * @param artifact artifact we are interested in. Only <code>groupid</code> and <code>artifactId</code>
+ * are needed, for instance the following code will work
+ * <code>artifactFactory.createProjectArtifact( "org.apache.maven", "maven", "" )</code>
+ * @param localRepository local repository
+ * @param remoteRepositories remote repositories, {@link List} $lt; {@link ArtifactRepository} >
+ * @return {@link List} $lt; {@link ArtifactVersion} >
+ * @throws ArtifactMetadataRetrievalException
+ * in case of error while retrieving repository metadata from the repository.
+ */
+ List<ArtifactVersion> retrieveAvailableVersions( Artifact artifact, ArtifactRepository localRepository,
+ List<ArtifactRepository> remoteRepositories )
+ throws ArtifactMetadataRetrievalException;
+
+ /**
+ * Get a list of available versions for an artifact in the remote deployment repository. This ignores any update
+ * policy checks and mirrors and always retrieves the latest information from the given repository.
+ *
+ * @param artifact artifact we are interested in. Only <code>groupid</code> and <code>artifactId</code> are
+ * needed, for instance the following code will work
+ * <code>artifactFactory.createProjectArtifact( "org.apache.maven", "maven", "" )</code>
+ * @param localRepository local repository
+ * @param remoteRepository remote repository
+ * @return {@link List} $lt; {@link ArtifactVersion} >
+ * @throws ArtifactMetadataRetrievalException
+ * in case of error while retrieving repository metadata from the repository.
+ */
+ List<ArtifactVersion> retrieveAvailableVersionsFromDeploymentRepository( Artifact artifact,
+ ArtifactRepository localRepository,
+ ArtifactRepository remoteRepository )
+ throws ArtifactMetadataRetrievalException;
+
+} \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/repository/legacy/metadata/DefaultMetadataResolutionRequest.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/repository/legacy/metadata/DefaultMetadataResolutionRequest.java
new file mode 100644
index 00000000..93b9d5da
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/repository/legacy/metadata/DefaultMetadataResolutionRequest.java
@@ -0,0 +1,132 @@
+package org.apache.maven.repository.legacy.metadata;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.List;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.repository.DefaultRepositoryRequest;
+import org.apache.maven.artifact.repository.RepositoryRequest;
+import org.apache.maven.artifact.resolver.ArtifactResolutionRequest;
+
+/**
+ * Forms a request to retrieve artifact metadata.
+ *
+ * @author Benjamin Bentmann
+ */
+public class DefaultMetadataResolutionRequest
+ implements MetadataResolutionRequest
+{
+
+ private Artifact artifact;
+
+ private boolean resolveManagedVersions;
+
+ private RepositoryRequest repositoryRequest;
+
+ public DefaultMetadataResolutionRequest()
+ {
+ repositoryRequest = new DefaultRepositoryRequest();
+ }
+
+ public DefaultMetadataResolutionRequest( RepositoryRequest repositoryRequest )
+ {
+ this.repositoryRequest = new DefaultRepositoryRequest( repositoryRequest );
+ }
+
+ public DefaultMetadataResolutionRequest( ArtifactResolutionRequest resolutionRequest )
+ {
+ this.repositoryRequest = new DefaultRepositoryRequest( resolutionRequest );
+ }
+
+ public Artifact getArtifact()
+ {
+ return artifact;
+ }
+
+ public DefaultMetadataResolutionRequest setArtifact( Artifact artifact )
+ {
+ this.artifact = artifact;
+
+ return this;
+ }
+
+ public ArtifactRepository getLocalRepository()
+ {
+ return repositoryRequest.getLocalRepository();
+ }
+
+ public DefaultMetadataResolutionRequest setLocalRepository( ArtifactRepository localRepository )
+ {
+ repositoryRequest.setLocalRepository( localRepository );
+
+ return this;
+ }
+
+ public List<ArtifactRepository> getRemoteRepositories()
+ {
+ return repositoryRequest.getRemoteRepositories();
+ }
+
+ public DefaultMetadataResolutionRequest setRemoteRepositories( List<ArtifactRepository> remoteRepositories )
+ {
+ repositoryRequest.setRemoteRepositories( remoteRepositories );
+
+ return this;
+ }
+
+ public boolean isResolveManagedVersions()
+ {
+ return resolveManagedVersions;
+ }
+
+ public DefaultMetadataResolutionRequest setResolveManagedVersions( boolean resolveManagedVersions )
+ {
+ this.resolveManagedVersions = resolveManagedVersions;
+
+ return this;
+ }
+
+ public boolean isOffline()
+ {
+ return repositoryRequest.isOffline();
+ }
+
+ public DefaultMetadataResolutionRequest setOffline( boolean offline )
+ {
+ repositoryRequest.setOffline( offline );
+
+ return this;
+ }
+
+ public boolean isForceUpdate()
+ {
+ return repositoryRequest.isForceUpdate();
+ }
+
+ public DefaultMetadataResolutionRequest setForceUpdate( boolean forceUpdate )
+ {
+ repositoryRequest.setForceUpdate( forceUpdate );
+
+ return this;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/repository/legacy/metadata/MetadataResolutionRequest.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/repository/legacy/metadata/MetadataResolutionRequest.java
new file mode 100644
index 00000000..a652c977
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/repository/legacy/metadata/MetadataResolutionRequest.java
@@ -0,0 +1,113 @@
+package org.apache.maven.repository.legacy.metadata;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.List;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.repository.RepositoryRequest;
+
+/**
+ * Forms a request to retrieve artifact metadata.
+ *
+ * @author Benjamin Bentmann
+ */
+public interface MetadataResolutionRequest
+ extends RepositoryRequest
+{
+
+ /**
+ * Indicates whether network access to remote repositories has been disabled.
+ *
+ * @return {@code true} if remote access has been disabled, {@code false} otherwise.
+ */
+ boolean isOffline();
+
+ /**
+ * Enables/disables network access to remote repositories.
+ *
+ * @param offline {@code true} to disable remote access, {@code false} to allow network access.
+ * @return This request, never {@code null}.
+ */
+ MetadataResolutionRequest setOffline( boolean offline );
+
+ /**
+ * Gets the artifact to resolve metadata for.
+ *
+ * @return The artifact to resolve metadata for or {@code null} if not set.
+ */
+ Artifact getArtifact();
+
+ /**
+ * Sets the artifact for which to resolve metadata.
+ *
+ * @param artifact The artifact for which to resolve metadata.
+ * @return This request, never {@code null}.
+ */
+ MetadataResolutionRequest setArtifact( Artifact artifact );
+
+ /**
+ * Gets the local repository to use for the resolution.
+ *
+ * @return The local repository to use for the resolution or {@code null} if not set.
+ */
+ ArtifactRepository getLocalRepository();
+
+ /**
+ * Sets the local repository to use for the resolution.
+ *
+ * @param localRepository The local repository to use for the resolution.
+ * @return This request, never {@code null}.
+ */
+ MetadataResolutionRequest setLocalRepository( ArtifactRepository localRepository );
+
+ /**
+ * Gets the remote repositories to use for the resolution.
+ *
+ * @return The remote repositories to use for the resolution, never {@code null}.
+ */
+ List<ArtifactRepository> getRemoteRepositories();
+
+ /**
+ * Sets the remote repositories to use for the resolution.
+ *
+ * @param remoteRepositories The remote repositories to use for the resolution.
+ * @return This request, never {@code null}.
+ */
+ MetadataResolutionRequest setRemoteRepositories( List<ArtifactRepository> remoteRepositories );
+
+ /**
+ * Determines whether the managed version information should be retrieved.
+ *
+ * @return {@code true} if the dependency management information should be retrieved, {@code false} otherwise.
+ */
+ boolean isResolveManagedVersions();
+
+ /**
+ * Enables/disables resolution of the dependency manageemnt information.
+ *
+ * @param resolveManagedVersions {@code true} if the dependency management information should be retrieved, {@code
+ * false} otherwise.
+ * @return This request, never {@code null}.
+ */
+ MetadataResolutionRequest setResolveManagedVersions( boolean resolveManagedVersions );
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/repository/legacy/metadata/ResolutionGroup.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/repository/legacy/metadata/ResolutionGroup.java
new file mode 100644
index 00000000..e942f70a
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/repository/legacy/metadata/ResolutionGroup.java
@@ -0,0 +1,83 @@
+package org.apache.maven.repository.legacy.metadata;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+
+public class ResolutionGroup
+{
+
+ private final Set<Artifact> artifacts;
+
+ private final List<ArtifactRepository> resolutionRepositories;
+
+ private final Artifact pomArtifact;
+
+ private final Artifact relocatedArtifact;
+
+ private final Map<String, Artifact> managedVersions;
+
+ public ResolutionGroup( Artifact pomArtifact, Set<Artifact> artifacts,
+ List<ArtifactRepository> resolutionRepositories )
+ {
+ this( pomArtifact, null, artifacts, null, resolutionRepositories );
+ }
+
+ public ResolutionGroup( Artifact pomArtifact, Artifact relocatedArtifact, Set<Artifact> artifacts,
+ Map<String, Artifact> managedVersions, List<ArtifactRepository> resolutionRepositories )
+ {
+ this.pomArtifact = pomArtifact;
+ this.relocatedArtifact = relocatedArtifact;
+ this.artifacts = artifacts;
+ this.managedVersions = managedVersions;
+ this.resolutionRepositories = resolutionRepositories;
+ }
+
+ public Artifact getPomArtifact()
+ {
+ return pomArtifact;
+ }
+
+ public Artifact getRelocatedArtifact()
+ {
+ return relocatedArtifact;
+ }
+
+ public Set<Artifact> getArtifacts()
+ {
+ return artifacts;
+ }
+
+ public List<ArtifactRepository> getResolutionRepositories()
+ {
+ return resolutionRepositories;
+ }
+
+ public Map<String, Artifact> getManagedVersions()
+ {
+ return managedVersions;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/rtinfo/RuntimeInformation.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/rtinfo/RuntimeInformation.java
new file mode 100644
index 00000000..4e3520db
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/rtinfo/RuntimeInformation.java
@@ -0,0 +1,49 @@
+package org.apache.maven.rtinfo;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Provides information about the current Maven runtime.
+ *
+ * @since 3.0.2
+ */
+public interface RuntimeInformation
+{
+
+ /**
+ * Retrieves the current Maven version, for example "3.0.2".
+ *
+ * @return The current Maven version or an empty string if unknown, never {@code null}.
+ */
+ String getMavenVersion();
+
+ /**
+ * Checks whether the current Maven runtime matches the specified version range. A version range can either use the
+ * usual mathematical syntax "[2.0.10,2.1.0),[3.0,)" or use a single version "2.2.1". The latter is a short form for
+ * "[2.2.1,)", i.e. denotes the minimum version required.
+ *
+ * @param versionRange The version range to match the current Maven runtime against, must not be {@code null}.
+ * @return {@code true} if the current Maven runtime matches the specified version range, {@code false} otherwise.
+ * @throws IllegalArgumentException If the specified version range is {@code null}, empty or otherwise not a valid
+ * version specification.
+ */
+ boolean isMavenVersion( String versionRange );
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/rtinfo/internal/DefaultRuntimeInformation.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/rtinfo/internal/DefaultRuntimeInformation.java
new file mode 100644
index 00000000..6a733f9b
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/rtinfo/internal/DefaultRuntimeInformation.java
@@ -0,0 +1,150 @@
+package org.apache.maven.rtinfo.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Properties;
+
+import org.apache.maven.rtinfo.RuntimeInformation;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+import org.codehaus.plexus.logging.Logger;
+import org.codehaus.plexus.util.IOUtil;
+import org.codehaus.plexus.util.StringUtils;
+import org.eclipse.aether.util.version.GenericVersionScheme;
+import org.eclipse.aether.version.InvalidVersionSpecificationException;
+import org.eclipse.aether.version.Version;
+import org.eclipse.aether.version.VersionConstraint;
+import org.eclipse.aether.version.VersionScheme;
+
+/**
+ * Provides information about the current Maven runtime.
+ */
+@Component( role = RuntimeInformation.class )
+public class DefaultRuntimeInformation
+ implements RuntimeInformation
+{
+
+ @Requirement
+ private Logger logger;
+
+ private String mavenVersion;
+
+ public String getMavenVersion()
+ {
+ if ( mavenVersion == null )
+ {
+ Properties props = new Properties();
+
+ String resource = "META-INF/maven/org.apache.maven/maven-core/pom.properties";
+
+ InputStream is = DefaultRuntimeInformation.class.getResourceAsStream( "/" + resource );
+ if ( is != null )
+ {
+ try
+ {
+ props.load( is );
+ }
+ catch ( IOException e )
+ {
+ String msg = "Could not parse " + resource + ", Maven runtime information not available";
+ if ( logger.isDebugEnabled() )
+ {
+ logger.warn( msg, e );
+ }
+ else
+ {
+ logger.warn( msg );
+ }
+ }
+ finally
+ {
+ IOUtil.close( is );
+ }
+ }
+ else
+ {
+ logger.warn( "Could not locate " + resource
+ + " on classpath, Maven runtime information not available" );
+ }
+
+ String version = props.getProperty( "version", "" ).trim();
+
+ if ( !version.startsWith( "${" ) )
+ {
+ mavenVersion = version;
+ }
+ else
+ {
+ mavenVersion = "";
+ }
+ }
+
+ return mavenVersion;
+ }
+
+ public boolean isMavenVersion( String versionRange )
+ {
+ VersionScheme versionScheme = new GenericVersionScheme();
+
+ if ( versionRange == null )
+ {
+ throw new IllegalArgumentException( "Version range must not be null" );
+ }
+ if ( StringUtils.isBlank( versionRange ) )
+ {
+ throw new IllegalArgumentException( "Version range must not be empty" );
+ }
+
+ VersionConstraint constraint;
+ try
+ {
+ constraint = versionScheme.parseVersionConstraint( versionRange );
+ }
+ catch ( InvalidVersionSpecificationException e )
+ {
+ throw new IllegalArgumentException( e.getMessage(), e );
+ }
+
+ Version current;
+ try
+ {
+ String mavenVersion = getMavenVersion();
+ if ( mavenVersion.length() <= 0 )
+ {
+ throw new IllegalStateException( "Could not determine current Maven version" );
+ }
+
+ current = versionScheme.parseVersion( mavenVersion );
+ }
+ catch ( InvalidVersionSpecificationException e )
+ {
+ throw new IllegalStateException( "Could not parse current Maven version: " + e.getMessage(), e );
+ }
+
+ if ( constraint.getRange() == null )
+ {
+ return constraint.getVersion().compareTo( current ) <= 0;
+ }
+ return constraint.containsVersion( current );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/session/scope/internal/SessionScope.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/session/scope/internal/SessionScope.java
new file mode 100644
index 00000000..6d8913f5
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/session/scope/internal/SessionScope.java
@@ -0,0 +1,169 @@
+package org.apache.maven.session.scope.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.Map;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Maps;
+import com.google.inject.Key;
+import com.google.inject.OutOfScopeException;
+import com.google.inject.Provider;
+import com.google.inject.Scope;
+import com.google.inject.util.Providers;
+
+public class SessionScope
+ implements Scope
+{
+ /**
+ * @since 3.3.0
+ */
+ public static class Memento
+ {
+ final Map<Key<?>, Provider<?>> seeded;
+
+ Memento( final Map<Key<?>, Provider<?>> seeded )
+ {
+ this.seeded = ImmutableMap.copyOf( seeded );
+ }
+ }
+
+ private static final Provider<Object> SEEDED_KEY_PROVIDER = new Provider<Object>()
+ {
+ public Object get()
+ {
+ throw new IllegalStateException();
+ }
+ };
+
+ private static final class ScopeState
+ {
+ public final Map<Key<?>, Provider<?>> seeded = Maps.newHashMap();
+
+ public final Map<Key<?>, Object> provided = Maps.newHashMap();
+ }
+
+ private final ThreadLocal<LinkedList<ScopeState>> values = new ThreadLocal<LinkedList<ScopeState>>();
+
+ public void enter()
+ {
+ LinkedList<ScopeState> stack = values.get();
+ if ( stack == null )
+ {
+ stack = new LinkedList<ScopeState>();
+ values.set( stack );
+ }
+ stack.addFirst( new ScopeState() );
+ }
+
+ /**
+ * @since 3.3.0
+ */
+ public void enter( Memento memento )
+ {
+ enter();
+ getScopeState().seeded.putAll( memento.seeded );
+ }
+
+ private ScopeState getScopeState()
+ {
+ LinkedList<ScopeState> stack = values.get();
+ if ( stack == null || stack.isEmpty() )
+ {
+ throw new IllegalStateException();
+ }
+ return stack.getFirst();
+ }
+
+ public void exit()
+ {
+ final LinkedList<ScopeState> stack = values.get();
+ if ( stack == null || stack.isEmpty() )
+ {
+ throw new IllegalStateException();
+ }
+ stack.removeFirst();
+ if ( stack.isEmpty() )
+ {
+ values.remove();
+ }
+ }
+
+ /**
+ * @since 3.3.0
+ */
+ public Memento memento()
+ {
+ LinkedList<ScopeState> stack = values.get();
+ return new Memento( stack != null ? stack.getFirst().seeded : Collections.<Key<?>, Provider<?>>emptyMap() );
+ }
+
+ public <T> void seed( Class<T> clazz, Provider<T> value )
+ {
+ getScopeState().seeded.put( Key.get( clazz ), value );
+ }
+
+ public <T> void seed( Class<T> clazz, final T value )
+ {
+ getScopeState().seeded.put( Key.get( clazz ), Providers.of( value ) );
+ }
+
+ public <T> Provider<T> scope( final Key<T> key, final Provider<T> unscoped )
+ {
+ return new Provider<T>()
+ {
+ @SuppressWarnings( "unchecked" )
+ public T get()
+ {
+ LinkedList<ScopeState> stack = values.get();
+ if ( stack == null || stack.isEmpty() )
+ {
+ throw new OutOfScopeException( "Cannot access " + key + " outside of a scoping block" );
+ }
+
+ ScopeState state = stack.getFirst();
+
+ Provider<?> seeded = state.seeded.get( key );
+
+ if ( seeded != null )
+ {
+ return (T) seeded.get();
+ }
+
+ T provided = (T) state.provided.get( key );
+ if ( provided == null && unscoped != null )
+ {
+ provided = unscoped.get();
+ state.provided.put( key, provided );
+ }
+
+ return provided;
+ }
+ };
+ }
+
+ @SuppressWarnings( { "unchecked" } )
+ public static <T> Provider<T> seededKeyProvider()
+ {
+ return (Provider<T>) SEEDED_KEY_PROVIDER;
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/session/scope/internal/SessionScopeModule.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/session/scope/internal/SessionScopeModule.java
new file mode 100644
index 00000000..585d683a
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/session/scope/internal/SessionScopeModule.java
@@ -0,0 +1,63 @@
+package org.apache.maven.session.scope.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import org.apache.maven.SessionScoped;
+import org.apache.maven.execution.MavenSession;
+import org.codehaus.plexus.PlexusContainer;
+import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
+
+import com.google.inject.AbstractModule;
+
+@Named
+public class SessionScopeModule
+ extends AbstractModule
+{
+ private final SessionScope scope;
+
+ @Inject
+ public SessionScopeModule()
+ {
+ this( new SessionScope() );
+ }
+
+ public SessionScopeModule( PlexusContainer container )
+ throws ComponentLookupException
+ {
+ this( container.lookup( SessionScope.class ) );
+ }
+
+ private SessionScopeModule( SessionScope scope )
+ {
+ this.scope = scope;
+ }
+
+ @Override
+ protected void configure()
+ {
+ bindScope( SessionScoped.class, scope );
+ bind( SessionScope.class ).toInstance( scope );
+
+ bind( MavenSession.class ).toProvider( SessionScope.<MavenSession>seededKeyProvider() ).in( scope );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/settings/DefaultMavenSettingsBuilder.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/settings/DefaultMavenSettingsBuilder.java
new file mode 100644
index 00000000..820d886e
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/settings/DefaultMavenSettingsBuilder.java
@@ -0,0 +1,158 @@
+package org.apache.maven.settings;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.maven.execution.MavenExecutionRequest;
+import org.apache.maven.properties.internal.SystemProperties;
+import org.apache.maven.settings.building.DefaultSettingsBuildingRequest;
+import org.apache.maven.settings.building.SettingsBuilder;
+import org.apache.maven.settings.building.SettingsBuildingException;
+import org.apache.maven.settings.building.SettingsBuildingRequest;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+import org.codehaus.plexus.logging.AbstractLogEnabled;
+import org.codehaus.plexus.util.StringUtils;
+import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
+
+/**
+ * @author jdcasey
+ */
+@Component( role = MavenSettingsBuilder.class )
+public class DefaultMavenSettingsBuilder
+ extends AbstractLogEnabled
+ implements MavenSettingsBuilder
+{
+
+ @Requirement
+ private SettingsBuilder settingsBuilder;
+
+ public Settings buildSettings()
+ throws IOException, XmlPullParserException
+ {
+ File userSettingsFile =
+ getFile( "${user.home}/.m2/settings.xml", "user.home",
+ MavenSettingsBuilder.ALT_USER_SETTINGS_XML_LOCATION );
+
+ return buildSettings( userSettingsFile );
+ }
+
+ public Settings buildSettings( boolean useCachedSettings )
+ throws IOException, XmlPullParserException
+ {
+ return buildSettings();
+ }
+
+ public Settings buildSettings( File userSettingsFile )
+ throws IOException, XmlPullParserException
+ {
+ File globalSettingsFile =
+ getFile( "${maven.home}/conf/settings.xml", "maven.home",
+ MavenSettingsBuilder.ALT_GLOBAL_SETTINGS_XML_LOCATION );
+
+ SettingsBuildingRequest request = new DefaultSettingsBuildingRequest();
+ request.setUserSettingsFile( userSettingsFile );
+ request.setGlobalSettingsFile( globalSettingsFile );
+ request.setSystemProperties( SystemProperties.getSystemProperties() );
+ return build( request );
+ }
+
+ public Settings buildSettings( File userSettingsFile, boolean useCachedSettings )
+ throws IOException, XmlPullParserException
+ {
+ return buildSettings( userSettingsFile );
+ }
+
+ private Settings build( SettingsBuildingRequest request )
+ throws IOException, XmlPullParserException
+ {
+ try
+ {
+ return settingsBuilder.build( request ).getEffectiveSettings();
+ }
+ catch ( SettingsBuildingException e )
+ {
+ throw (IOException) new IOException( e.getMessage() ).initCause( e );
+ }
+ }
+
+ /** @since 2.1 */
+ public Settings buildSettings( MavenExecutionRequest request )
+ throws IOException, XmlPullParserException
+ {
+ SettingsBuildingRequest settingsRequest = new DefaultSettingsBuildingRequest();
+ settingsRequest.setUserSettingsFile( request.getUserSettingsFile() );
+ settingsRequest.setGlobalSettingsFile( request.getGlobalSettingsFile() );
+ settingsRequest.setUserProperties( request.getUserProperties() );
+ settingsRequest.setSystemProperties( request.getSystemProperties() );
+
+ return build( settingsRequest );
+ }
+
+ private File getFile( String pathPattern, String basedirSysProp, String altLocationSysProp )
+ {
+ // -------------------------------------------------------------------------------------
+ // Alright, here's the justification for all the regexp wizardry below...
+ //
+ // Continuum and other server-like apps may need to locate the user-level and
+ // global-level settings somewhere other than ${user.home} and ${maven.home},
+ // respectively. Using a simple replacement of these patterns will allow them
+ // to specify the absolute path to these files in a customized components.xml
+ // file. Ideally, we'd do full pattern-evaluation against the sysprops, but this
+ // is a first step. There are several replacements below, in order to normalize
+ // the path character before we operate on the string as a regex input, and
+ // in order to avoid surprises with the File construction...
+ // -------------------------------------------------------------------------------------
+
+ String path = System.getProperty( altLocationSysProp );
+
+ if ( StringUtils.isEmpty( path ) )
+ {
+ // TODO: This replacing shouldn't be necessary as user.home should be in the
+ // context of the container and thus the value would be interpolated by Plexus
+ String basedir = System.getProperty( basedirSysProp );
+ if ( basedir == null )
+ {
+ basedir = System.getProperty( "user.dir" );
+ }
+
+ basedir = basedir.replaceAll( "\\\\", "/" );
+ basedir = basedir.replaceAll( "\\$", "\\\\\\$" );
+
+ path = pathPattern.replaceAll( "\\$\\{" + basedirSysProp + "\\}", basedir );
+ path = path.replaceAll( "\\\\", "/" );
+ // ---------------------------------------------------------------------------------
+ // I'm not sure if this last regexp was really intended to disallow the usage of
+ // network paths as user.home directory. Unfortunately it did. I removed it and
+ // have not detected any problems yet.
+ // ---------------------------------------------------------------------------------
+ // path = path.replaceAll( "//", "/" );
+
+ return new File( path ).getAbsoluteFile();
+ }
+ else
+ {
+ return new File( path ).getAbsoluteFile();
+ }
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/settings/MavenSettingsBuilder.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/settings/MavenSettingsBuilder.java
new file mode 100644
index 00000000..c79a843d
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/settings/MavenSettingsBuilder.java
@@ -0,0 +1,81 @@
+package org.apache.maven.settings;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.maven.execution.MavenExecutionRequest;
+import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
+
+/**
+ * @author jdcasey
+ * @author Jason van Zyl
+ */
+@Deprecated
+public interface MavenSettingsBuilder
+{
+
+ String ROLE = MavenSettingsBuilder.class.getName();
+
+ String ALT_USER_SETTINGS_XML_LOCATION = "org.apache.maven.user-settings";
+ String ALT_GLOBAL_SETTINGS_XML_LOCATION = "org.apache.maven.global-settings";
+ String ALT_LOCAL_REPOSITORY_LOCATION = "maven.repo.local";
+
+ Settings buildSettings( MavenExecutionRequest request )
+ throws IOException, XmlPullParserException;
+
+ /**
+ * @return a <code>Settings</code> object from the user settings file.
+ * @throws IOException if any
+ * @throws XmlPullParserException if any
+ */
+ Settings buildSettings()
+ throws IOException, XmlPullParserException;
+
+ /**
+ * @param useCachedSettings if true, doesn't reload the user settings
+ * @return a <code>Settings</code> object from the user settings file.
+ * @throws IOException if any
+ * @throws XmlPullParserException if any
+ */
+ Settings buildSettings( boolean useCachedSettings )
+ throws IOException, XmlPullParserException;
+
+ /**
+ * @param userSettingsFile a given user settings file
+ * @return a <code>Settings</code> object from the user settings file.
+ * @throws IOException if any
+ * @throws XmlPullParserException if any
+ */
+ Settings buildSettings( File userSettingsFile )
+ throws IOException, XmlPullParserException;
+
+ /**
+ * @param userSettingsFile a given user settings file
+ * @param useCachedSettings if true, doesn't reload the user settings
+ * @return a <code>Settings</code> object from the user settings file.
+ * @throws IOException if any
+ * @throws XmlPullParserException if any
+ */
+ Settings buildSettings( File userSettingsFile, boolean useCachedSettings )
+ throws IOException, XmlPullParserException;
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/settings/SettingsConfigurationException.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/settings/SettingsConfigurationException.java
new file mode 100644
index 00000000..6fab6501
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/settings/SettingsConfigurationException.java
@@ -0,0 +1,63 @@
+package org.apache.maven.settings;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * If there was an error in the settings file.
+ *
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ */
+public class SettingsConfigurationException
+ extends Exception
+{
+ private int lineNumber;
+
+ private int columnNumber;
+
+ public SettingsConfigurationException( String message )
+ {
+ super( message );
+ }
+
+ public SettingsConfigurationException( String message, Throwable cause )
+ {
+ super( message, cause );
+ }
+
+ public SettingsConfigurationException( String message, Throwable cause, int lineNumber, int columnNumber )
+ {
+ super( message + ( lineNumber > 0 ? "\n Line: " + lineNumber : "" )
+ + ( columnNumber > 0 ? "\n Column: " + columnNumber : "" ), cause );
+ this.lineNumber = lineNumber;
+ this.columnNumber = columnNumber;
+ }
+
+ public int getColumnNumber()
+ {
+ return columnNumber;
+ }
+
+ public int getLineNumber()
+ {
+ return lineNumber;
+ }
+
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/settings/SettingsUtils.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/settings/SettingsUtils.java
new file mode 100644
index 00000000..8da696e8
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/settings/SettingsUtils.java
@@ -0,0 +1,321 @@
+package org.apache.maven.settings;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.model.ActivationFile;
+import org.apache.maven.settings.merge.MavenSettingsMerger;
+
+import java.util.List;
+
+/**
+ * Several convenience methods to handle settings
+ *
+ * @author <a href="mailto:vincent.siveton@gmail.com">Vincent Siveton</a>
+ */
+public final class SettingsUtils
+{
+
+ private SettingsUtils()
+ {
+ // don't allow construction.
+ }
+
+ /**
+ * @param dominant
+ * @param recessive
+ * @param recessiveSourceLevel
+ */
+ public static void merge( Settings dominant, Settings recessive, String recessiveSourceLevel )
+ {
+ new MavenSettingsMerger().merge( dominant, recessive, recessiveSourceLevel );
+ }
+
+ /**
+ * @param modelProfile
+ * @return a profile
+ */
+ public static Profile convertToSettingsProfile( org.apache.maven.model.Profile modelProfile )
+ {
+ Profile profile = new Profile();
+
+ profile.setId( modelProfile.getId() );
+
+ org.apache.maven.model.Activation modelActivation = modelProfile.getActivation();
+
+ if ( modelActivation != null )
+ {
+ Activation activation = new Activation();
+
+ activation.setActiveByDefault( modelActivation.isActiveByDefault() );
+
+ activation.setJdk( modelActivation.getJdk() );
+
+ org.apache.maven.model.ActivationProperty modelProp = modelActivation.getProperty();
+
+ if ( modelProp != null )
+ {
+ ActivationProperty prop = new ActivationProperty();
+ prop.setName( modelProp.getName() );
+ prop.setValue( modelProp.getValue() );
+ activation.setProperty( prop );
+ }
+
+ org.apache.maven.model.ActivationOS modelOs = modelActivation.getOs();
+
+ if ( modelOs != null )
+ {
+ ActivationOS os = new ActivationOS();
+
+ os.setArch( modelOs.getArch() );
+ os.setFamily( modelOs.getFamily() );
+ os.setName( modelOs.getName() );
+ os.setVersion( modelOs.getVersion() );
+
+ activation.setOs( os );
+ }
+
+ ActivationFile modelFile = modelActivation.getFile();
+
+ if ( modelFile != null )
+ {
+ org.apache.maven.settings.ActivationFile file = new org.apache.maven.settings.ActivationFile();
+
+ file.setExists( modelFile.getExists() );
+ file.setMissing( modelFile.getMissing() );
+
+ activation.setFile( file );
+ }
+
+ profile.setActivation( activation );
+ }
+
+ profile.setProperties( modelProfile.getProperties() );
+
+ List<org.apache.maven.model.Repository> repos = modelProfile.getRepositories();
+ if ( repos != null )
+ {
+ for ( org.apache.maven.model.Repository repo : repos )
+ {
+ profile.addRepository( convertToSettingsRepository( repo ) );
+ }
+ }
+
+ List<org.apache.maven.model.Repository> pluginRepos = modelProfile.getPluginRepositories();
+ if ( pluginRepos != null )
+ {
+ for ( org.apache.maven.model.Repository pluginRepo : pluginRepos )
+ {
+ profile.addPluginRepository( convertToSettingsRepository( pluginRepo ) );
+ }
+ }
+
+ return profile;
+ }
+
+ /**
+ * @param settingsProfile
+ * @return a profile
+ */
+ public static org.apache.maven.model.Profile convertFromSettingsProfile( Profile settingsProfile )
+ {
+ org.apache.maven.model.Profile profile = new org.apache.maven.model.Profile();
+
+ profile.setId( settingsProfile.getId() );
+
+ profile.setSource( "settings.xml" );
+
+ Activation settingsActivation = settingsProfile.getActivation();
+
+ if ( settingsActivation != null )
+ {
+ org.apache.maven.model.Activation activation = new org.apache.maven.model.Activation();
+
+ activation.setActiveByDefault( settingsActivation.isActiveByDefault() );
+
+ activation.setJdk( settingsActivation.getJdk() );
+
+ ActivationProperty settingsProp = settingsActivation.getProperty();
+
+ if ( settingsProp != null )
+ {
+ org.apache.maven.model.ActivationProperty prop = new org.apache.maven.model.ActivationProperty();
+
+ prop.setName( settingsProp.getName() );
+ prop.setValue( settingsProp.getValue() );
+
+ activation.setProperty( prop );
+ }
+
+ ActivationOS settingsOs = settingsActivation.getOs();
+
+ if ( settingsOs != null )
+ {
+ org.apache.maven.model.ActivationOS os = new org.apache.maven.model.ActivationOS();
+
+ os.setArch( settingsOs.getArch() );
+ os.setFamily( settingsOs.getFamily() );
+ os.setName( settingsOs.getName() );
+ os.setVersion( settingsOs.getVersion() );
+
+ activation.setOs( os );
+ }
+
+ org.apache.maven.settings.ActivationFile settingsFile = settingsActivation.getFile();
+
+ if ( settingsFile != null )
+ {
+ ActivationFile file = new ActivationFile();
+
+ file.setExists( settingsFile.getExists() );
+ file.setMissing( settingsFile.getMissing() );
+
+ activation.setFile( file );
+ }
+
+ profile.setActivation( activation );
+ }
+
+ profile.setProperties( settingsProfile.getProperties() );
+
+ List<Repository> repos = settingsProfile.getRepositories();
+ if ( repos != null )
+ {
+ for ( Repository repo : repos )
+ {
+ profile.addRepository( convertFromSettingsRepository( repo ) );
+ }
+ }
+
+ List<Repository> pluginRepos = settingsProfile.getPluginRepositories();
+ if ( pluginRepos != null )
+ {
+ for ( Repository pluginRepo : pluginRepos )
+ {
+ profile.addPluginRepository( convertFromSettingsRepository( pluginRepo ) );
+ }
+ }
+
+ return profile;
+ }
+
+ /**
+ * @param settingsRepo
+ * @return a repository
+ */
+ private static org.apache.maven.model.Repository convertFromSettingsRepository( Repository settingsRepo )
+ {
+ org.apache.maven.model.Repository repo = new org.apache.maven.model.Repository();
+
+ repo.setId( settingsRepo.getId() );
+ repo.setLayout( settingsRepo.getLayout() );
+ repo.setName( settingsRepo.getName() );
+ repo.setUrl( settingsRepo.getUrl() );
+
+ if ( settingsRepo.getSnapshots() != null )
+ {
+ repo.setSnapshots( convertRepositoryPolicy( settingsRepo.getSnapshots() ) );
+ }
+ if ( settingsRepo.getReleases() != null )
+ {
+ repo.setReleases( convertRepositoryPolicy( settingsRepo.getReleases() ) );
+ }
+
+ return repo;
+ }
+
+ /**
+ * @param settingsPolicy
+ * @return a RepositoryPolicy
+ */
+ private static org.apache.maven.model.RepositoryPolicy convertRepositoryPolicy( RepositoryPolicy settingsPolicy )
+ {
+ org.apache.maven.model.RepositoryPolicy policy = new org.apache.maven.model.RepositoryPolicy();
+ policy.setEnabled( settingsPolicy.isEnabled() );
+ policy.setUpdatePolicy( settingsPolicy.getUpdatePolicy() );
+ policy.setChecksumPolicy( settingsPolicy.getChecksumPolicy() );
+ return policy;
+ }
+
+ /**
+ * @param modelRepo
+ * @return a repository
+ */
+ private static Repository convertToSettingsRepository( org.apache.maven.model.Repository modelRepo )
+ {
+ Repository repo = new Repository();
+
+ repo.setId( modelRepo.getId() );
+ repo.setLayout( modelRepo.getLayout() );
+ repo.setName( modelRepo.getName() );
+ repo.setUrl( modelRepo.getUrl() );
+
+ if ( modelRepo.getSnapshots() != null )
+ {
+ repo.setSnapshots( convertRepositoryPolicy( modelRepo.getSnapshots() ) );
+ }
+ if ( modelRepo.getReleases() != null )
+ {
+ repo.setReleases( convertRepositoryPolicy( modelRepo.getReleases() ) );
+ }
+
+ return repo;
+ }
+
+ /**
+ * @param modelPolicy
+ * @return a RepositoryPolicy
+ */
+ private static RepositoryPolicy convertRepositoryPolicy( org.apache.maven.model.RepositoryPolicy modelPolicy )
+ {
+ RepositoryPolicy policy = new RepositoryPolicy();
+ policy.setEnabled( modelPolicy.isEnabled() );
+ policy.setUpdatePolicy( modelPolicy.getUpdatePolicy() );
+ policy.setChecksumPolicy( modelPolicy.getChecksumPolicy() );
+ return policy;
+ }
+
+ /**
+ * @param settings could be null
+ * @return a new instance of settings or null if settings was null.
+ */
+ public static Settings copySettings( Settings settings )
+ {
+ if ( settings == null )
+ {
+ return null;
+ }
+
+ Settings clone = new Settings();
+ clone.setActiveProfiles( settings.getActiveProfiles() );
+ clone.setInteractiveMode( settings.isInteractiveMode() );
+ clone.setLocalRepository( settings.getLocalRepository() );
+ clone.setMirrors( settings.getMirrors() );
+ clone.setModelEncoding( settings.getModelEncoding() );
+ clone.setOffline( settings.isOffline() );
+ clone.setPluginGroups( settings.getPluginGroups() );
+ clone.setProfiles( settings.getProfiles() );
+ clone.setProxies( settings.getProxies() );
+ clone.setServers( settings.getServers() );
+ clone.setSourceLevel( settings.getSourceLevel() );
+ clone.setUsePluginRegistry( settings.isUsePluginRegistry() );
+
+ return clone;
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/DefaultToolchain.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/DefaultToolchain.java
new file mode 100644
index 00000000..043e5e68
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/DefaultToolchain.java
@@ -0,0 +1,190 @@
+package org.apache.maven.toolchain;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.maven.toolchain.model.ToolchainModel;
+import org.codehaus.plexus.logging.Logger;
+
+/**
+ * Default abstract toolchain implementation, to be used as base class for any toolchain implementation
+ * to avoid rewriting usual code.
+ *
+ * @author mkleint
+ * @since 2.0.9
+ */
+public abstract class DefaultToolchain // should have been AbstractToolchain...
+ implements Toolchain, ToolchainPrivate
+{
+
+ private String type;
+
+ private Map<String, RequirementMatcher> provides = new HashMap<String, RequirementMatcher>();
+
+ public static final String KEY_TYPE = "type"; //NOI18N
+
+ private ToolchainModel model;
+
+ private Logger logger;
+
+ /**
+ *
+ * @param model the model, must not be {@code null}
+ * @param logger the logger, must not be {@code null}
+ */
+ protected DefaultToolchain( ToolchainModel model, Logger logger )
+ {
+ this.model = model;
+
+ this.logger = logger;
+ }
+
+ /**
+ *
+ * @param model the model, must not be {@code null}
+ * @param type the type
+ * @param logger the logger, must not be {@code null}
+ */
+ protected DefaultToolchain( ToolchainModel model, String type, Logger logger )
+ {
+ this( model, logger );
+ this.type = type;
+ }
+
+ @Override
+ public final String getType()
+ {
+ return type != null ? type : model.getType();
+ }
+
+ @Override
+ public final ToolchainModel getModel()
+ {
+ return model;
+ }
+
+ public final void addProvideToken( String type, RequirementMatcher matcher )
+ {
+ provides.put( type, matcher );
+ }
+
+ @Override
+ public boolean matchesRequirements( Map<String, String> requirements )
+ {
+ for ( Map.Entry<String, String> requirement : requirements.entrySet() )
+ {
+ String key = requirement.getKey();
+
+ RequirementMatcher matcher = provides.get( key );
+
+ if ( matcher == null )
+ {
+ getLog().debug( "Toolchain " + this + " is missing required property: " + key );
+ return false;
+ }
+ if ( !matcher.matches( requirement.getValue() ) )
+ {
+ getLog().debug( "Toolchain " + this + " doesn't match required property: " + key );
+ return false;
+ }
+ }
+ return true;
+ }
+
+ protected Logger getLog()
+ {
+ return logger;
+ }
+
+ @Override
+ public boolean equals( Object obj )
+ {
+ if ( obj == null )
+ {
+ return false;
+ }
+
+ if ( this == obj )
+ {
+ return true;
+ }
+
+ if ( !( obj instanceof DefaultToolchain ) )
+ {
+ return false;
+ }
+
+ DefaultToolchain other = (DefaultToolchain) obj;
+
+ if ( type == null ? other.type != null : !type.equals( other.type ) )
+ {
+ return false;
+ }
+
+ Properties thisProvides = this.getModel().getProvides();
+ Properties otherProvides = other.getModel().getProvides();
+
+ if ( thisProvides == null ? otherProvides != null : !thisProvides.equals( otherProvides ) )
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ public int hashCode()
+ {
+ int hashCode = ( type == null ) ? 0 : type.hashCode();
+
+ if ( this.getModel().getProvides() != null )
+ {
+ hashCode = 31 * hashCode + this.getModel().getProvides().hashCode();
+ }
+ return hashCode;
+ }
+
+ @Override
+ public String toString()
+ {
+ StringBuilder builder = new StringBuilder();
+ builder.append( "type:" ).append( getType() );
+ builder.append( '{' );
+
+ Iterator<Map.Entry<String, RequirementMatcher>> providesIter = provides.entrySet().iterator();
+ while ( providesIter.hasNext() )
+ {
+ Map.Entry<String, RequirementMatcher> provideEntry = providesIter.next();
+ builder.append( provideEntry.getKey() ).append( " = " ).append( provideEntry.getValue() );
+ if ( providesIter.hasNext() )
+ {
+ builder.append( ';' );
+ }
+ }
+
+ builder.append( '}' );
+
+ return builder.toString();
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/DefaultToolchainManager.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/DefaultToolchainManager.java
new file mode 100644
index 00000000..8093bbd6
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/DefaultToolchainManager.java
@@ -0,0 +1,140 @@
+package org.apache.maven.toolchain;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.plugin.descriptor.PluginDescriptor;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.toolchain.model.ToolchainModel;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+import org.codehaus.plexus.logging.Logger;
+
+/**
+ * @author mkleint
+ */
+@Component( role = ToolchainManager.class )
+public class DefaultToolchainManager
+ implements ToolchainManager
+{
+ @Requirement
+ Logger logger;
+
+ @Requirement( role = ToolchainFactory.class )
+ Map<String, ToolchainFactory> factories;
+
+ @Override
+ public Toolchain getToolchainFromBuildContext( String type, MavenSession session )
+ {
+ Map<String, Object> context = retrieveContext( session );
+
+ ToolchainModel model = (ToolchainModel) context.get( getStorageKey( type ) );
+
+ if ( model != null )
+ {
+ List<Toolchain> toolchains = selectToolchains( Collections.singletonList( model ), type, null );
+
+ if ( !toolchains.isEmpty() )
+ {
+ return toolchains.get( 0 );
+ }
+ }
+
+ return null;
+ }
+
+ @Override
+ public List<Toolchain> getToolchains( MavenSession session, String type, Map<String, String> requirements )
+ {
+ List<ToolchainModel> models = session.getRequest().getToolchains().get( type );
+
+ return selectToolchains( models, type, requirements );
+ }
+
+ private List<Toolchain> selectToolchains( List<ToolchainModel> models, String type,
+ Map<String, String> requirements )
+ {
+ List<Toolchain> toolchains = new ArrayList<Toolchain>();
+
+ if ( models != null )
+ {
+ ToolchainFactory fact = factories.get( type );
+
+ if ( fact == null )
+ {
+ logger.error( "Missing toolchain factory for type: " + type
+ + ". Possibly caused by misconfigured project." );
+ }
+ else
+ {
+ for ( ToolchainModel model : models )
+ {
+ try
+ {
+ ToolchainPrivate toolchain = fact.createToolchain( model );
+ if ( requirements == null || toolchain.matchesRequirements( requirements ) )
+ {
+ toolchains.add( toolchain );
+ }
+ }
+ catch ( MisconfiguredToolchainException ex )
+ {
+ logger.error( "Misconfigured toolchain.", ex );
+ }
+ }
+ }
+ }
+ return toolchains;
+ }
+
+ Map<String, Object> retrieveContext( MavenSession session )
+ {
+ Map<String, Object> context = null;
+
+ if ( session != null )
+ {
+ PluginDescriptor desc = new PluginDescriptor();
+ desc.setGroupId( PluginDescriptor.getDefaultPluginGroupId() );
+ desc.setArtifactId( PluginDescriptor.getDefaultPluginArtifactId( "toolchains" ) );
+
+ MavenProject current = session.getCurrentProject();
+
+ if ( current != null )
+ {
+ //TODO: why is this using the context
+ context = session.getPluginContext( desc, current );
+ }
+ }
+
+ return ( context != null ) ? context : new HashMap<String, Object>();
+ }
+
+ public static final String getStorageKey( String type )
+ {
+ return "toolchain-" + type; // NOI18N
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/DefaultToolchainManagerPrivate.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/DefaultToolchainManagerPrivate.java
new file mode 100644
index 00000000..cac8e297
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/DefaultToolchainManagerPrivate.java
@@ -0,0 +1,82 @@
+package org.apache.maven.toolchain;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.toolchain.model.ToolchainModel;
+import org.codehaus.plexus.component.annotations.Component;
+
+/**
+ * @author mkleint
+ * @author Robert Scholte
+ */
+@Component( role = ToolchainManagerPrivate.class )
+public class DefaultToolchainManagerPrivate
+ extends DefaultToolchainManager
+ implements ToolchainManagerPrivate
+{
+
+ @Override
+ public ToolchainPrivate[] getToolchainsForType( String type, MavenSession context )
+ throws MisconfiguredToolchainException
+ {
+ List<ToolchainPrivate> toRet = new ArrayList<ToolchainPrivate>();
+
+ ToolchainFactory fact = factories.get( type );
+ if ( fact == null )
+ {
+ logger.error( "Missing toolchain factory for type: " + type
+ + ". Possibly caused by misconfigured project." );
+ }
+ else
+ {
+ List<ToolchainModel> availableToolchains = context.getRequest().getToolchains().get( type );
+
+ if ( availableToolchains != null )
+ {
+ for ( ToolchainModel toolchainModel : availableToolchains )
+ {
+ toRet.add( fact.createToolchain( toolchainModel ) );
+ }
+ }
+
+ // add default toolchain
+ ToolchainPrivate tool = fact.createDefaultToolchain();
+ if ( tool != null )
+ {
+ toRet.add( tool );
+ }
+ }
+
+ return toRet.toArray( new ToolchainPrivate[toRet.size()] );
+ }
+
+ @Override
+ public void storeToolchainToBuildContext( ToolchainPrivate toolchain, MavenSession session )
+ {
+ Map<String, Object> context = retrieveContext( session );
+ context.put( getStorageKey( toolchain.getType() ), toolchain.getModel() );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/DefaultToolchainsBuilder.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/DefaultToolchainsBuilder.java
new file mode 100644
index 00000000..5bd3e82a
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/DefaultToolchainsBuilder.java
@@ -0,0 +1,78 @@
+package org.apache.maven.toolchain;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.io.Reader;
+
+import org.apache.maven.toolchain.model.PersistedToolchains;
+import org.apache.maven.toolchain.model.io.xpp3.MavenToolchainsXpp3Reader;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+import org.codehaus.plexus.logging.Logger;
+import org.codehaus.plexus.util.IOUtil;
+import org.codehaus.plexus.util.ReaderFactory;
+
+/**
+ * @author Benjamin Bentmann
+ *
+ * @deprecated instead use {@link org.apache.maven.toolchain.building.DefaultToolchainsBuilder}
+ */
+@Deprecated
+@Component( role = ToolchainsBuilder.class, hint = "default" )
+public class DefaultToolchainsBuilder
+ implements ToolchainsBuilder
+{
+
+ @Requirement
+ private Logger logger;
+
+ public PersistedToolchains build( File userToolchainsFile )
+ throws MisconfiguredToolchainException
+ {
+ PersistedToolchains toolchains = null;
+
+ if ( userToolchainsFile != null && userToolchainsFile.isFile() )
+ {
+ Reader in = null;
+ try
+ {
+ in = ReaderFactory.newXmlReader( userToolchainsFile );
+ toolchains = new MavenToolchainsXpp3Reader().read( in );
+ }
+ catch ( Exception e )
+ {
+ throw new MisconfiguredToolchainException( "Cannot read toolchains file at "
+ + userToolchainsFile.getAbsolutePath(), e );
+ }
+ finally
+ {
+ IOUtil.close( in );
+ }
+ }
+ else if ( userToolchainsFile != null )
+ {
+ logger.debug( "Toolchains configuration was not found at " + userToolchainsFile );
+ }
+
+ return toolchains;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/MisconfiguredToolchainException.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/MisconfiguredToolchainException.java
new file mode 100644
index 00000000..140bc804
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/MisconfiguredToolchainException.java
@@ -0,0 +1,39 @@
+package org.apache.maven.toolchain;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ *
+ * @author mkleint
+ */
+public class MisconfiguredToolchainException
+ extends Exception
+{
+
+ public MisconfiguredToolchainException( String message )
+ {
+ super( message );
+ }
+
+ public MisconfiguredToolchainException( String message, Throwable orig )
+ {
+ super( message, orig );
+ }
+} \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/RequirementMatcher.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/RequirementMatcher.java
new file mode 100644
index 00000000..26390e40
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/RequirementMatcher.java
@@ -0,0 +1,30 @@
+package org.apache.maven.toolchain;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ *
+ * @author mkleint
+ */
+public interface RequirementMatcher
+{
+
+ boolean matches( String requirement );
+} \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/RequirementMatcherFactory.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/RequirementMatcherFactory.java
new file mode 100644
index 00000000..3d6917bd
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/RequirementMatcherFactory.java
@@ -0,0 +1,109 @@
+package org.apache.maven.toolchain;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
+import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
+import org.apache.maven.artifact.versioning.VersionRange;
+
+/**
+ *
+ * @author mkleint
+ */
+public final class RequirementMatcherFactory
+{
+ private RequirementMatcherFactory()
+ {
+ }
+
+ public static RequirementMatcher createExactMatcher( String provideValue )
+ {
+ return new ExactMatcher( provideValue );
+ }
+
+ public static RequirementMatcher createVersionMatcher( String provideValue )
+ {
+ return new VersionMatcher( provideValue );
+ }
+
+ private static final class ExactMatcher
+ implements RequirementMatcher
+ {
+
+ private String provides;
+
+ private ExactMatcher( String provides )
+ {
+ this.provides = provides;
+ }
+
+ @Override
+ public boolean matches( String requirement )
+ {
+ return provides.equalsIgnoreCase( requirement );
+ }
+
+ @Override
+ public String toString()
+ {
+ return provides;
+ }
+ }
+
+ private static final class VersionMatcher
+ implements RequirementMatcher
+ {
+ DefaultArtifactVersion version;
+
+ private VersionMatcher( String version )
+ {
+ this.version = new DefaultArtifactVersion( version );
+ }
+
+ @Override
+ public boolean matches( String requirement )
+ {
+ try
+ {
+ VersionRange range = VersionRange.createFromVersionSpec( requirement );
+ if ( range.hasRestrictions() )
+ {
+ return range.containsVersion( version );
+ }
+ else
+ {
+ return range.getRecommendedVersion().compareTo( version ) == 0;
+ }
+ }
+ catch ( InvalidVersionSpecificationException ex )
+ {
+ //TODO error reporting
+ ex.printStackTrace();
+ return false;
+ }
+ }
+
+ @Override
+ public String toString()
+ {
+ return version.toString();
+ }
+ }
+} \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/Toolchain.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/Toolchain.java
new file mode 100644
index 00000000..2a713465
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/Toolchain.java
@@ -0,0 +1,46 @@
+package org.apache.maven.toolchain;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Toolchain interface.
+ *
+ * @author Milos Kleint
+ * @author Jason van Zyl
+ * @since 2.0.9
+ */
+public interface Toolchain
+{
+
+ /**
+ * get the type of toolchain.
+ *
+ * @return the toolchain type
+ */
+ String getType();
+
+ /**
+ * Gets the platform tool executable.
+ *
+ * @param toolName the tool platform independent tool name.
+ * @return file representing the tool executable, or null if the tool can not be found
+ */
+ String findTool( String toolName );
+} \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/ToolchainFactory.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/ToolchainFactory.java
new file mode 100644
index 00000000..115eede3
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/ToolchainFactory.java
@@ -0,0 +1,44 @@
+package org.apache.maven.toolchain;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.toolchain.model.ToolchainModel;
+
+/**
+ * Internal toolchain factory, to prepare toolchains instances.
+ *
+ * @author mkleint
+ * @since 2.0.9
+ */
+public interface ToolchainFactory
+{
+ /**
+ * Create instance of toolchain.
+ **/
+ ToolchainPrivate createToolchain( ToolchainModel model )
+ throws MisconfiguredToolchainException;
+
+ /**
+ * Returns the default instance of the particular type of toolchain, can return <code>null</code>
+ * if not applicable.
+ * TODO keep around??
+ **/
+ ToolchainPrivate createDefaultToolchain();
+} \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/ToolchainManager.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/ToolchainManager.java
new file mode 100644
index 00000000..8eddac54
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/ToolchainManager.java
@@ -0,0 +1,64 @@
+package org.apache.maven.toolchain;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.List;
+import java.util.Map;
+
+import org.apache.maven.execution.MavenSession;
+
+
+/**
+ * Public API for a toolchain-aware plugin to get expected toolchain instance.
+ *
+ * @author mkleint
+ * @author Robert Scholte
+ * @since 2.0.9
+ */
+public interface ToolchainManager
+{
+
+ // NOTE: Some plugins like Surefire access this field directly!
+ @Deprecated
+ String ROLE = ToolchainManager.class.getName();
+
+ /**
+ * Retrieve toolchain of specified type from build context. It is expected that
+ * <code>maven-toolchains-plugin</code> contains the configuration to select the appropriate
+ * toolchain and is executed at the beginning of the build.
+ *
+ * @param session the Maven session, must not be {@code null}
+ * @param type the type, must not be {@code null}
+ * @return the toolchain selected by <code>maven-toolchains-plugin</code>
+ */
+ Toolchain getToolchainFromBuildContext( String type, MavenSession context );
+
+ /**
+ * Select all toolchains available in user settings matching the type and requirements,
+ * independently from <code>maven-toolchains-plugin</code>.
+ *
+ * @param session the Maven session, must not be {@code null}
+ * @param type the type, must not be {@code null}
+ * @param requirements the requirements, may be {@code null}
+ * @return the matching toolchains, never {@code null}
+ * @since 3.3.0
+ */
+ List<Toolchain> getToolchains( MavenSession session, String type, Map<String, String> requirements );
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/ToolchainManagerPrivate.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/ToolchainManagerPrivate.java
new file mode 100644
index 00000000..6836bf1c
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/ToolchainManagerPrivate.java
@@ -0,0 +1,58 @@
+package org.apache.maven.toolchain;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.execution.MavenSession;
+
+/**
+ * Component for use by the <code>maven-toolchains-plugin</code> only.
+ * It provides API: <ol>
+ * <li>to retrieve every toolchains available in user settings,</li>
+ * <li>to store chosen toolchain into build context for later use by toolchain-aware plugins.</li>
+ * </ol>
+ *
+ * @author mkleint
+ * @since 2.0.9
+ * @see ToolchainManager#getToolchainFromBuildContext(String, MavenSession)
+ */
+public interface ToolchainManagerPrivate
+{
+
+ /**
+ * Retrieves every toolchains of given type available in user settings.
+ *
+ * @param type the type, must not be {@code null}
+ * @param context the Maven session, must not be {@code null}
+ * @since 3.0 (addition of the <code>MavenSession</code> parameter)
+ */
+ ToolchainPrivate[] getToolchainsForType( String type, MavenSession context )
+ throws MisconfiguredToolchainException;
+
+ /**
+ * Stores the toolchain into build context for later use by toolchain-aware plugins.
+ *
+ * @param toolchain the toolchain to store, must not be {@code null}
+ * @param context the Maven session, must not be {@code null}
+ * @since 2.0.9
+ * @see ToolchainManager#getToolchainFromBuildContext(String, MavenSession)
+ */
+ void storeToolchainToBuildContext( ToolchainPrivate toolchain, MavenSession context );
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/ToolchainPrivate.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/ToolchainPrivate.java
new file mode 100644
index 00000000..756cd957
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/ToolchainPrivate.java
@@ -0,0 +1,48 @@
+package org.apache.maven.toolchain;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Map;
+
+import org.apache.maven.toolchain.model.ToolchainModel;
+
+/**
+ * a private contract between the toolchains plugin and the components.
+ * @author mkleint
+ */
+public interface ToolchainPrivate
+ extends Toolchain
+{
+
+ /**
+ * Let the toolchain decide if it matches requirements defined
+ * in the toolchain plugin configuration.
+ * @param requirements Map<String, String> key value pair, may not be {@code null}
+ * @return {@code true} if the requirements match, otherwise {@code false}
+ */
+ boolean matchesRequirements( Map<String, String> requirements );
+
+ /**
+ *
+ * @return the original model wrapped by this interface
+ */
+ ToolchainModel getModel();
+
+} \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/ToolchainsBuilder.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/ToolchainsBuilder.java
new file mode 100644
index 00000000..4bb4052a
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/ToolchainsBuilder.java
@@ -0,0 +1,46 @@
+package org.apache.maven.toolchain;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+
+import org.apache.maven.toolchain.model.PersistedToolchains;
+
+/**
+ * Builds the toolchains model from a previously configured filesystem path to the toolchains file.
+ * <strong>Note:</strong> This is an internal component whose interface can change without prior notice.
+ *
+ * @author Benjamin Bentmann
+ */
+public interface ToolchainsBuilder
+{
+
+ /**
+ * Builds the toolchains model from the configured toolchain files.
+ *
+ * @param userToolchainsFile The path to the toolchains file, may be <code>null</code> to disable parsing.
+ * @return The toolchains model or <code>null</code> if no toolchain file was configured or the configured file does
+ * not exist.
+ * @throws MisconfiguredToolchainException If the toolchain file exists but cannot be parsed.
+ */
+ PersistedToolchains build( File userToolchainsFile )
+ throws MisconfiguredToolchainException;
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/building/DefaultToolchainsBuilder.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/building/DefaultToolchainsBuilder.java
new file mode 100644
index 00000000..7983388b
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/building/DefaultToolchainsBuilder.java
@@ -0,0 +1,138 @@
+package org.apache.maven.toolchain.building;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import org.apache.maven.building.Problem;
+import org.apache.maven.building.ProblemCollector;
+import org.apache.maven.building.ProblemCollectorFactory;
+import org.apache.maven.building.Source;
+import org.apache.maven.toolchain.io.ToolchainsParseException;
+import org.apache.maven.toolchain.io.ToolchainsReader;
+import org.apache.maven.toolchain.merge.MavenToolchainMerger;
+import org.apache.maven.toolchain.model.PersistedToolchains;
+import org.apache.maven.toolchain.model.TrackableBase;
+
+/**
+ *
+ * @author Robert Scholte
+ * @since 3.3.0
+ */
+@Named
+@Singleton
+public class DefaultToolchainsBuilder
+ implements ToolchainsBuilder
+{
+ private MavenToolchainMerger toolchainsMerger = new MavenToolchainMerger();
+
+ @Inject
+ private ToolchainsReader toolchainsReader;
+
+ @Override
+ public ToolchainsBuildingResult build( ToolchainsBuildingRequest request )
+ throws ToolchainsBuildingException
+ {
+ ProblemCollector problems = ProblemCollectorFactory.newInstance( null );
+
+ PersistedToolchains globalToolchains = readToolchains( request.getGlobalToolchainsSource(), request, problems );
+
+ PersistedToolchains userToolchains = readToolchains( request.getUserToolchainsSource(), request, problems );
+
+ toolchainsMerger.merge( userToolchains, globalToolchains, TrackableBase.GLOBAL_LEVEL );
+
+ problems.setSource( "" );
+
+ if ( hasErrors( problems.getProblems() ) )
+ {
+ throw new ToolchainsBuildingException( problems.getProblems() );
+ }
+
+
+ return new DefaultToolchainsBuildingResult( userToolchains, problems.getProblems() );
+ }
+
+ private PersistedToolchains readToolchains( Source toolchainsSource, ToolchainsBuildingRequest request,
+ ProblemCollector problems )
+ {
+ if ( toolchainsSource == null )
+ {
+ return new PersistedToolchains();
+ }
+
+ PersistedToolchains toolchains;
+
+ try
+ {
+ Map<String, ?> options = Collections.singletonMap( ToolchainsReader.IS_STRICT, Boolean.TRUE );
+
+ try
+ {
+ toolchains = toolchainsReader.read( toolchainsSource.getInputStream(), options );
+ }
+ catch ( ToolchainsParseException e )
+ {
+ options = Collections.singletonMap( ToolchainsReader.IS_STRICT, Boolean.FALSE );
+
+ toolchains = toolchainsReader.read( toolchainsSource.getInputStream(), options );
+
+ problems.add( Problem.Severity.WARNING, e.getMessage(), e.getLineNumber(), e.getColumnNumber(),
+ e );
+ }
+ }
+ catch ( ToolchainsParseException e )
+ {
+ problems.add( Problem.Severity.FATAL, "Non-parseable toolchains " + toolchainsSource.getLocation()
+ + ": " + e.getMessage(), e.getLineNumber(), e.getColumnNumber(), e );
+ return new PersistedToolchains();
+ }
+ catch ( IOException e )
+ {
+ problems.add( Problem.Severity.FATAL, "Non-readable toolchains " + toolchainsSource.getLocation()
+ + ": " + e.getMessage(), -1, -1, e );
+ return new PersistedToolchains();
+ }
+
+ return toolchains;
+ }
+
+ private boolean hasErrors( List<Problem> problems )
+ {
+ if ( problems != null )
+ {
+ for ( Problem problem : problems )
+ {
+ if ( Problem.Severity.ERROR.compareTo( problem.getSeverity() ) >= 0 )
+ {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/building/DefaultToolchainsBuildingRequest.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/building/DefaultToolchainsBuildingRequest.java
new file mode 100644
index 00000000..144d724c
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/building/DefaultToolchainsBuildingRequest.java
@@ -0,0 +1,63 @@
+package org.apache.maven.toolchain.building;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.building.Source;
+
+/**
+ * Collects toolchains that control building of effective toolchains.
+ *
+ * @author Robert Scholte
+ * @since 3.3.0
+ */
+public class DefaultToolchainsBuildingRequest
+ implements ToolchainsBuildingRequest
+{
+ private Source globalToolchainsSource;
+
+ private Source userToolchainsSource;
+
+ @Override
+ public Source getGlobalToolchainsSource()
+ {
+ return globalToolchainsSource;
+ }
+
+ @Override
+ public ToolchainsBuildingRequest setGlobalToolchainsSource( Source globalToolchainsSource )
+ {
+ this.globalToolchainsSource = globalToolchainsSource;
+ return this;
+ }
+
+ @Override
+ public Source getUserToolchainsSource()
+ {
+ return userToolchainsSource;
+ }
+
+ @Override
+ public ToolchainsBuildingRequest setUserToolchainsSource( Source userToolchainsSource )
+ {
+ this.userToolchainsSource = userToolchainsSource;
+ return this;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/building/DefaultToolchainsBuildingResult.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/building/DefaultToolchainsBuildingResult.java
new file mode 100644
index 00000000..60ca2441
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/building/DefaultToolchainsBuildingResult.java
@@ -0,0 +1,66 @@
+package org.apache.maven.toolchain.building;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.maven.building.Problem;
+import org.apache.maven.toolchain.model.PersistedToolchains;
+
+/**
+ * Holds the result of the merged toolchains and holds the problems during this build, if any.
+ *
+ * @author Robert Scholte
+ * @since 3.3.0
+ */
+public class DefaultToolchainsBuildingResult
+ implements ToolchainsBuildingResult
+{
+
+ private PersistedToolchains effectiveToolchains;
+
+ private List<Problem> problems;
+
+ /**
+ * Default constructor
+ *
+ * @param effectiveToolchains the merged toolchains, may not be {@code null}
+ * @param problems the problems while building the effectiveToolchains, if any.
+ */
+ public DefaultToolchainsBuildingResult( PersistedToolchains effectiveToolchains, List<Problem> problems )
+ {
+ this.effectiveToolchains = effectiveToolchains;
+ this.problems = ( problems != null ) ? problems : new ArrayList<Problem>();
+ }
+
+ @Override
+ public PersistedToolchains getEffectiveToolchains()
+ {
+ return effectiveToolchains;
+ }
+
+ @Override
+ public List<Problem> getProblems()
+ {
+ return problems;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/building/ToolchainsBuilder.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/building/ToolchainsBuilder.java
new file mode 100644
index 00000000..b2ef0d10
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/building/ToolchainsBuilder.java
@@ -0,0 +1,41 @@
+package org.apache.maven.toolchain.building;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Builds the effective toolchains from a user toolchains file and/or a global toolchains file.
+ *
+ * @author Robert Scholte
+ * @since 3.3.0
+ */
+public interface ToolchainsBuilder
+{
+
+ /**
+ * Builds the effective toolchains of the specified toolchains files.
+ *
+ * @param request The toolchains building request that holds the parameters, must not be {@code null}.
+ * @return The result of the toolchains building, never {@code null}.
+ * @throws ToolchainsBuildingException If the effective toolchains could not be built.
+ */
+ ToolchainsBuildingResult build( ToolchainsBuildingRequest request )
+ throws ToolchainsBuildingException;
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/building/ToolchainsBuildingException.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/building/ToolchainsBuildingException.java
new file mode 100644
index 00000000..56ed1d3e
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/building/ToolchainsBuildingException.java
@@ -0,0 +1,93 @@
+package org.apache.maven.toolchain.building;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.maven.building.Problem;
+
+/**
+ * @author Robert Scholte
+ * @since 3.3.0
+ */
+public class ToolchainsBuildingException
+ extends Exception
+{
+
+ private final List<Problem> problems;
+
+ /**
+ * Creates a new exception with the specified problems.
+ *
+ * @param problems The problems that causes this exception, must not be {@code null}.
+ */
+ public ToolchainsBuildingException( List<Problem> problems )
+ {
+ super( toMessage( problems ) );
+
+ this.problems = new ArrayList<Problem>();
+ if ( problems != null )
+ {
+ this.problems.addAll( problems );
+ }
+ }
+
+ /**
+ * Gets the problems that caused this exception.
+ *
+ * @return The problems that caused this exception, never {@code null}.
+ */
+ public List<Problem> getProblems()
+ {
+ return problems;
+ }
+
+ private static String toMessage( List<Problem> problems )
+ {
+ StringWriter buffer = new StringWriter( 1024 );
+
+ PrintWriter writer = new PrintWriter( buffer );
+
+ writer.print( problems.size() );
+ writer.print( ( problems.size() == 1 ) ? " problem was " : " problems were " );
+ writer.print( "encountered while building the effective toolchains" );
+ writer.println();
+
+ for ( Problem problem : problems )
+ {
+ writer.print( "[" );
+ writer.print( problem.getSeverity() );
+ writer.print( "] " );
+ writer.print( problem.getMessage() );
+ String location = problem.getLocation();
+ if ( !location.isEmpty() )
+ {
+ writer.print( " @ " );
+ writer.print( location );
+ }
+ writer.println();
+ }
+
+ return buffer.toString();
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/building/ToolchainsBuildingRequest.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/building/ToolchainsBuildingRequest.java
new file mode 100644
index 00000000..cf65d4cd
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/building/ToolchainsBuildingRequest.java
@@ -0,0 +1,64 @@
+package org.apache.maven.toolchain.building;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.building.Source;
+
+/**
+ * Collects toolchains that control the building of effective toolchains.
+ *
+ * @author Robert Scholte
+ * @since 3.3.0
+ */
+public interface ToolchainsBuildingRequest
+{
+
+ /**
+ * Gets the global toolchains source.
+ *
+ * @return The global toolchains source or {@code null} if none.
+ */
+ Source getGlobalToolchainsSource();
+
+ /**
+ * Sets the global toolchains source. If both user toolchains and a global toolchains are given, the user toolchains
+ * take precedence.
+ *
+ * @param globalToolchainsSource The global toolchains source, may be {@code null} to disable global toolchains.
+ * @return This request, never {@code null}.
+ */
+ ToolchainsBuildingRequest setGlobalToolchainsSource( Source globalToolchainsSource );
+
+ /**
+ * Gets the user toolchains source.
+ *
+ * @return The user toolchains source or {@code null} if none.
+ */
+ Source getUserToolchainsSource();
+
+ /**
+ * Sets the user toolchains source. If both user toolchains and a global toolchains are given, the user toolchains
+ * take precedence.
+ *
+ * @param userToolchainsSource The user toolchains source, may be {@code null} to disable user toolchains.
+ * @return This request, never {@code null}.
+ */
+ ToolchainsBuildingRequest setUserToolchainsSource( Source userToolchainsSource );
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/building/ToolchainsBuildingResult.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/building/ToolchainsBuildingResult.java
new file mode 100644
index 00000000..592fb98c
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/building/ToolchainsBuildingResult.java
@@ -0,0 +1,50 @@
+package org.apache.maven.toolchain.building;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.List;
+
+import org.apache.maven.building.Problem;
+import org.apache.maven.toolchain.model.PersistedToolchains;
+
+/**
+ * Collects the output of the toolchains builder.
+ *
+ * @author Robert Scholte
+ * @since 3.3.0
+ */
+public interface ToolchainsBuildingResult
+{
+
+ /**
+ * Gets the assembled toolchains.
+ *
+ * @return The assembled toolchains, never {@code null}.
+ */
+ PersistedToolchains getEffectiveToolchains();
+
+ /**
+ * Return a list of problems, if any.
+ *
+ * @return a list of problems, never {@code null}.
+ */
+ List<Problem> getProblems();
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/io/DefaultToolchainsReader.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/io/DefaultToolchainsReader.java
new file mode 100644
index 00000000..8aeefe8b
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/io/DefaultToolchainsReader.java
@@ -0,0 +1,115 @@
+package org.apache.maven.toolchain.io;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.util.Map;
+
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import org.apache.maven.toolchain.model.PersistedToolchains;
+import org.apache.maven.toolchain.model.io.xpp3.MavenToolchainsXpp3Reader;
+import org.codehaus.plexus.util.IOUtil;
+import org.codehaus.plexus.util.ReaderFactory;
+import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
+
+/**
+ * Handles deserialization of toolchains from the default textual format.
+ *
+ * @author Robert Scholte
+ * @since 3.3.0
+ */
+@Named
+@Singleton
+public class DefaultToolchainsReader
+ implements ToolchainsReader
+{
+
+ @Override
+ public PersistedToolchains read( File input, Map<String, ?> options )
+ throws IOException
+ {
+ if ( input == null )
+ {
+ throw new IllegalArgumentException( "input file missing" );
+ }
+
+ return read( ReaderFactory.newXmlReader( input ), options );
+ }
+
+ @Override
+ public PersistedToolchains read( Reader input, Map<String, ?> options )
+ throws IOException
+ {
+ if ( input == null )
+ {
+ throw new IllegalArgumentException( "input reader missing" );
+ }
+
+ try
+ {
+ MavenToolchainsXpp3Reader r = new MavenToolchainsXpp3Reader();
+ return r.read( input, isStrict( options ) );
+ }
+ catch ( XmlPullParserException e )
+ {
+ throw new ToolchainsParseException( e.getMessage(), e.getLineNumber(), e.getColumnNumber(), e );
+ }
+ finally
+ {
+ IOUtil.close( input );
+ }
+ }
+
+ @Override
+ public PersistedToolchains read( InputStream input, Map<String, ?> options )
+ throws IOException
+ {
+ if ( input == null )
+ {
+ throw new IllegalArgumentException( "input stream missing" );
+ }
+
+ try
+ {
+ MavenToolchainsXpp3Reader r = new MavenToolchainsXpp3Reader();
+ return r.read( input, isStrict( options ) );
+ }
+ catch ( XmlPullParserException e )
+ {
+ throw new ToolchainsParseException( e.getMessage(), e.getLineNumber(), e.getColumnNumber(), e );
+ }
+ finally
+ {
+ IOUtil.close( input );
+ }
+ }
+
+ private boolean isStrict( Map<String, ?> options )
+ {
+ Object value = ( options != null ) ? options.get( IS_STRICT ) : null;
+ return value == null || Boolean.parseBoolean( value.toString() );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/io/ToolchainsParseException.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/io/ToolchainsParseException.java
new file mode 100644
index 00000000..95c2aed8
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/io/ToolchainsParseException.java
@@ -0,0 +1,94 @@
+package org.apache.maven.toolchain.io;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.IOException;
+
+/**
+ * Signals a failure to parse the toolchains due to invalid syntax (e.g. non-wellformed XML or unknown elements).
+ *
+ * @author Robert Scholte
+ * @since 3.3.0
+ */
+public class ToolchainsParseException
+ extends IOException
+{
+
+ /**
+ * The one-based index of the line containing the error.
+ */
+ private final int lineNumber;
+
+ /**
+ * The one-based index of the column containing the error.
+ */
+ private final int columnNumber;
+
+ /**
+ * Creates a new parser exception with the specified details.
+ *
+ * @param message The error message, may be {@code null}.
+ * @param lineNumber The one-based index of the line containing the error or {@code -1} if unknown.
+ * @param columnNumber The one-based index of the column containing the error or {@code -1} if unknown.
+ */
+ public ToolchainsParseException( String message, int lineNumber, int columnNumber )
+ {
+ super( message );
+ this.lineNumber = lineNumber;
+ this.columnNumber = columnNumber;
+ }
+
+ /**
+ * Creates a new parser exception with the specified details.
+ *
+ * @param message The error message, may be {@code null}.
+ * @param lineNumber The one-based index of the line containing the error or {@code -1} if unknown.
+ * @param columnNumber The one-based index of the column containing the error or {@code -1} if unknown.
+ * @param cause The nested cause of this error, may be {@code null}.
+ */
+ public ToolchainsParseException( String message, int lineNumber, int columnNumber, Throwable cause )
+ {
+ super( message );
+ initCause( cause );
+ this.lineNumber = lineNumber;
+ this.columnNumber = columnNumber;
+ }
+
+ /**
+ * Gets the one-based index of the line containing the error.
+ *
+ * @return The one-based index of the line containing the error or a non-positive value if unknown.
+ */
+ public int getLineNumber()
+ {
+ return lineNumber;
+ }
+
+ /**
+ * Gets the one-based index of the column containing the error.
+ *
+ * @return The one-based index of the column containing the error or non-positive value if unknown.
+ */
+ public int getColumnNumber()
+ {
+ return columnNumber;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/io/ToolchainsReader.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/io/ToolchainsReader.java
new file mode 100644
index 00000000..44dc2bdc
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/io/ToolchainsReader.java
@@ -0,0 +1,83 @@
+package org.apache.maven.toolchain.io;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.util.Map;
+
+import org.apache.maven.toolchain.model.PersistedToolchains;
+
+/**
+ * Handles deserialization of toolchains from some kind of textual format like XML.
+ *
+ * @author Robert Scholte
+ * @since 3.3.0
+ */
+public interface ToolchainsReader
+{
+
+ /**
+ * The key for the option to enable strict parsing. This option is of type {@link Boolean} and defaults to {@code
+ * true}. If {@code false}, unknown elements will be ignored instead of causing a failure.
+ */
+ String IS_STRICT = "org.apache.maven.toolchains.io.isStrict";
+
+ /**
+ * Reads the toolchains from the specified file.
+ *
+ * @param input The file to deserialize the toolchains from, must not be {@code null}.
+ * @param options The options to use for deserialization, may be {@code null} to use the default values.
+ * @return The deserialized toolchains, never {@code null}.
+ * @throws IOException If the toolchains could not be deserialized.
+ * @throws ToolchainsParseException If the input format could not be parsed.
+ */
+ PersistedToolchains read( File input, Map<String, ?> options )
+ throws IOException, ToolchainsParseException;
+
+ /**
+ * Reads the toolchains from the specified character reader. The reader will be automatically closed before the
+ * method returns.
+ *
+ * @param input The reader to deserialize the toolchains from, must not be {@code null}.
+ * @param options The options to use for deserialization, may be {@code null} to use the default values.
+ * @return The deserialized toolchains, never {@code null}.
+ * @throws IOException If the toolchains could not be deserialized.
+ * @throws ToolchainsParseException If the input format could not be parsed.
+ */
+ PersistedToolchains read( Reader input, Map<String, ?> options )
+ throws IOException, ToolchainsParseException;
+
+ /**
+ * Reads the toolchains from the specified byte stream. The stream will be automatically closed before the method
+ * returns.
+ *
+ * @param input The stream to deserialize the toolchains from, must not be {@code null}.
+ * @param options The options to use for deserialization, may be {@code null} to use the default values.
+ * @return The deserialized toolchains, never {@code null}.
+ * @throws IOException If the toolchains could not be deserialized.
+ * @throws ToolchainsParseException If the input format could not be parsed.
+ */
+ PersistedToolchains read( InputStream input, Map<String, ?> options )
+ throws IOException, ToolchainsParseException;
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/java/DefaultJavaToolChain.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/java/DefaultJavaToolChain.java
new file mode 100644
index 00000000..9cfcff38
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/java/DefaultJavaToolChain.java
@@ -0,0 +1,55 @@
+package org.apache.maven.toolchain.java;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.toolchain.model.ToolchainModel;
+import org.codehaus.plexus.logging.Logger;
+
+/**
+ * Provides backwards compatibility with Maven 3.2.3 and earlier. Clients that do not require compatibility with Maven
+ * 3.2.3 and earlier are encouraged to use {@link JavaToolchainImpl}.
+ * <strong>Note:</strong> This is an internal component whose interface can change without prior notice.
+ *
+ * @deprecated clients that do not require compatibility with Maven 3.2.3 and earlier should link to
+ * {@link JavaToolchainImpl} instead.
+ */
+public class DefaultJavaToolChain
+ extends JavaToolchainImpl
+{
+ public static final String KEY_JAVAHOME = JavaToolchainImpl.KEY_JAVAHOME;
+
+ public DefaultJavaToolChain( ToolchainModel model, Logger logger )
+ {
+ super( model, logger );
+ }
+
+ @Override
+ public String getJavaHome()
+ {
+ return super.getJavaHome();
+ }
+
+ @Override
+ public void setJavaHome( String javaHome )
+ {
+ super.setJavaHome( javaHome );
+ }
+
+} \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/java/JavaToolchain.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/java/JavaToolchain.java
new file mode 100644
index 00000000..cb14ada1
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/java/JavaToolchain.java
@@ -0,0 +1,67 @@
+package org.apache.maven.toolchain.java;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.toolchain.Toolchain;
+
+/**
+ * JDK toolchain interface.
+ *
+ * @author Jason van Zyl
+ * @author Milos Kleint
+ * @since 2.0.9, renamed from JavaToolChain in 3.2.4
+ */
+public interface JavaToolchain
+ extends Toolchain
+{
+// /**
+// * Returns a list of {@link java.io.File}s which represents the bootstrap libraries for the
+// * runtime environment. The Bootstrap libraries include libraries in JRE's
+// * extension directory, if there are any.
+// *
+// * @return List
+// */
+// List getBootstrapLibraries();
+//
+// /**
+// * Returns a list of {@link java.io.File}s which represent the libraries recognized by
+// * default by the platform. Usually it corresponds to contents of CLASSPATH
+// * environment variable.
+// *
+// * @return List
+// */
+// List getStandardLibraries();
+//
+// /**
+// * Returns a {@link java.io.File}s which represent the locations of the source of the JDK,
+// * or an empty collection when the location is not set or is invalid.
+// *
+// * @return List
+// */
+// List getSourceDirectories();
+//
+// /**
+// * Returns a {@link java.io.File}s which represent the locations of the Javadoc for this platform,
+// * or empty collection if the location is not set or invalid
+// *
+// * @return List
+// */
+// List getJavadocFolders();
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/java/JavaToolchainFactory.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/java/JavaToolchainFactory.java
new file mode 100644
index 00000000..cd4aef01
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/java/JavaToolchainFactory.java
@@ -0,0 +1,127 @@
+package org.apache.maven.toolchain.java;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.util.Map.Entry;
+import java.util.Properties;
+
+import org.apache.maven.toolchain.MisconfiguredToolchainException;
+import org.apache.maven.toolchain.RequirementMatcher;
+import org.apache.maven.toolchain.RequirementMatcherFactory;
+import org.apache.maven.toolchain.ToolchainFactory;
+import org.apache.maven.toolchain.ToolchainPrivate;
+import org.apache.maven.toolchain.model.ToolchainModel;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+import org.codehaus.plexus.logging.Logger;
+import org.codehaus.plexus.util.FileUtils;
+import org.codehaus.plexus.util.xml.Xpp3Dom;
+
+/**
+ * JDK toolchain factory.
+ * This is a <code>ToolchainFactory</code> Plexus component registered with
+ * <code>jdk</code> hint.
+ *
+ * @author mkleint
+ * @since 2.0.9, renamed from <code>DefaultJavaToolchainFactory</code> in 3.2.4
+ */
+@Component( role = ToolchainFactory.class, hint = "jdk" )
+public class JavaToolchainFactory
+ implements ToolchainFactory
+{
+
+ @Requirement
+ private Logger logger;
+
+ public ToolchainPrivate createToolchain( ToolchainModel model )
+ throws MisconfiguredToolchainException
+ {
+ if ( model == null )
+ {
+ return null;
+ }
+
+ // use DefaultJavaToolChain for compatibility with maven 3.2.3 and earlier
+
+ @SuppressWarnings( "deprecation" )
+ JavaToolchainImpl jtc = new DefaultJavaToolChain( model, logger );
+
+ // populate the provides section
+ Properties provides = model.getProvides();
+ for ( Entry<Object, Object> provide : provides.entrySet() )
+ {
+ String key = (String) provide.getKey();
+ String value = (String) provide.getValue();
+
+ if ( value == null )
+ {
+ throw new MisconfiguredToolchainException(
+ "Provides token '" + key + "' doesn't have any value configured." );
+ }
+
+ RequirementMatcher matcher;
+ if ( "version".equals( key ) )
+ {
+ matcher = RequirementMatcherFactory.createVersionMatcher( value );
+ }
+ else
+ {
+ matcher = RequirementMatcherFactory.createExactMatcher( value );
+ }
+
+ jtc.addProvideToken( key, matcher );
+ }
+
+ // populate the configuration section
+ Xpp3Dom dom = (Xpp3Dom) model.getConfiguration();
+ Xpp3Dom javahome = dom.getChild( JavaToolchainImpl.KEY_JAVAHOME );
+ if ( javahome == null )
+ {
+ throw new MisconfiguredToolchainException( "Java toolchain without the "
+ + JavaToolchainImpl.KEY_JAVAHOME + " configuration element." );
+ }
+ File normal = new File( FileUtils.normalize( javahome.getValue() ) );
+ if ( normal.exists() )
+ {
+ jtc.setJavaHome( FileUtils.normalize( javahome.getValue() ) );
+ }
+ else
+ {
+ throw new MisconfiguredToolchainException( "Non-existing JDK home configuration at "
+ + normal.getAbsolutePath() );
+ }
+
+ return jtc;
+ }
+
+ public ToolchainPrivate createDefaultToolchain()
+ {
+ //not sure it's necessary to provide a default toolchain here.
+ //only version can be eventually supplied, and
+ return null;
+ }
+
+ protected Logger getLogger()
+ {
+ return logger;
+ }
+
+} \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/java/JavaToolchainImpl.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/java/JavaToolchainImpl.java
new file mode 100644
index 00000000..4a09ee06
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/java/JavaToolchainImpl.java
@@ -0,0 +1,87 @@
+package org.apache.maven.toolchain.java;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+
+import org.apache.maven.toolchain.DefaultToolchain;
+import org.apache.maven.toolchain.model.ToolchainModel;
+import org.codehaus.plexus.logging.Logger;
+import org.codehaus.plexus.util.FileUtils;
+import org.codehaus.plexus.util.Os;
+
+/**
+ * JDK toolchain implementation.
+ *
+ * @author Milos Kleint
+ * @since 2.0.9, renamed from DefaultJavaToolChain in 3.2.4
+ */
+class JavaToolchainImpl
+ extends DefaultToolchain
+ implements JavaToolchain
+{
+ private String javaHome;
+
+ public static final String KEY_JAVAHOME = "jdkHome"; //NOI18N
+
+ public JavaToolchainImpl( ToolchainModel model, Logger logger )
+ {
+ super( model, "jdk", logger );
+ }
+
+ public String getJavaHome()
+ {
+ return javaHome;
+ }
+
+ public void setJavaHome( String javaHome )
+ {
+ this.javaHome = javaHome;
+ }
+
+ public String toString()
+ {
+ return "JDK[" + getJavaHome() + "]";
+ }
+
+ public String findTool( String toolName )
+ {
+ File toRet = findTool( toolName, new File( FileUtils.normalize( getJavaHome() ) ) );
+ if ( toRet != null )
+ {
+ return toRet.getAbsolutePath();
+ }
+ return null;
+ }
+
+ private static File findTool( String toolName, File installFolder )
+ {
+ File bin = new File( installFolder, "bin" ); //NOI18N
+ if ( bin.exists() )
+ {
+ File tool = new File( bin, toolName + ( Os.isFamily( "windows" ) ? ".exe" : "" ) ); // NOI18N
+ if ( tool.exists() )
+ {
+ return tool;
+ }
+ }
+ return null;
+ }
+} \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/merge/MavenToolchainMerger.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/merge/MavenToolchainMerger.java
new file mode 100644
index 00000000..538f79b3
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/java/org/apache/maven/toolchain/merge/MavenToolchainMerger.java
@@ -0,0 +1,103 @@
+package org.apache.maven.toolchain.merge;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.maven.toolchain.model.PersistedToolchains;
+import org.apache.maven.toolchain.model.ToolchainModel;
+import org.codehaus.plexus.util.xml.Xpp3Dom;
+
+/**
+ *
+ * @author Robert Scholte
+ * @since 3.2.4
+ */
+public class MavenToolchainMerger
+{
+
+ public void merge( PersistedToolchains dominant, PersistedToolchains recessive, String recessiveSourceLevel )
+ {
+ if ( dominant == null || recessive == null )
+ {
+ return;
+ }
+
+ recessive.setSourceLevel( recessiveSourceLevel );
+
+ shallowMerge( dominant.getToolchains(), recessive.getToolchains(), recessiveSourceLevel );
+ }
+
+ private void shallowMerge( List<ToolchainModel> dominant, List<ToolchainModel> recessive,
+ String recessiveSourceLevel )
+ {
+ Map<Object, ToolchainModel> merged = new LinkedHashMap<Object, ToolchainModel>();
+
+ for ( ToolchainModel dominantModel : dominant )
+ {
+ Object key = getToolchainModelKey( dominantModel );
+
+ merged.put( key, dominantModel );
+ }
+
+ for ( ToolchainModel recessiveModel : recessive )
+ {
+ Object key = getToolchainModelKey( recessiveModel );
+
+ ToolchainModel dominantModel = merged.get( key );
+ if ( dominantModel == null )
+ {
+ recessiveModel.setSourceLevel( recessiveSourceLevel );
+ dominant.add( recessiveModel );
+ }
+ else
+ {
+ mergeToolchainModel_Configuration( dominantModel, recessiveModel );
+ }
+ }
+ }
+
+ protected void mergeToolchainModel_Configuration( ToolchainModel target,
+ ToolchainModel source )
+ {
+ Xpp3Dom src = (Xpp3Dom) source.getConfiguration();
+ if ( src != null )
+ {
+ Xpp3Dom tgt = (Xpp3Dom) target.getConfiguration();
+ if ( tgt == null )
+ {
+ tgt = Xpp3Dom.mergeXpp3Dom( new Xpp3Dom( src ), tgt );
+ }
+ else
+ {
+ tgt = Xpp3Dom.mergeXpp3Dom( tgt, src );
+ }
+ target.setConfiguration( tgt );
+ }
+ }
+
+ protected Object getToolchainModelKey( ToolchainModel model )
+ {
+ return model;
+ }
+
+} \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/mdo/extension.mdo b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/mdo/extension.mdo
new file mode 100644
index 00000000..4b2e4604
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/mdo/extension.mdo
@@ -0,0 +1,65 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<model xmlns="http://modello.codehaus.org/MODELLO/1.4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://modello.codehaus.org/MODELLO/1.4.0 http://modello.codehaus.org/xsd/modello-1.4.0.xsd">
+ <id>extension</id>
+ <name>ExtensionDescriptor</name>
+ <description><![CDATA[
+ Extension descriptor, stored in <code>META-INF/maven/extension.xml</code> in an extension's jar artifact to
+ precisely control parts of the extension and dependencies to expose.
+ <p><i>Notice:</i> this documentation is generated from a Modello model but the code executed is not generated
+ from this descriptor. Please report if you find anything wrong.</p>
+ ]]></description>
+ <defaults>
+ <default>
+ <key>package</key>
+ <value>extension descriptor XML documentation (no java generation)</value><!-- intentionally non-buildable value -->
+ </default>
+ </defaults>
+ <classes>
+ <class rootElement="true" xml.tagName="extension">
+ <name>ExtensionDescriptor</name>
+ <version>1.0.0</version>
+ <description><![CDATA[Root element of the <code>extension.xml</code> file.]]></description>
+ <fields>
+ <field>
+ <name>exportedPackages</name>
+ <version>1.0.0</version>
+ <association>
+ <type>String</type>
+ <multiplicity>*</multiplicity>
+ </association>
+ <description>Packages from the artifact that are exposed.</description>
+ <!-- TODO explain package vs package.class vs package.* -->
+ </field>
+ <field>
+ <name>exportedArtifacts</name>
+ <version>1.0.0</version>
+ <association>
+ <type>String</type>
+ <multiplicity>*</multiplicity>
+ </association>
+ <description><![CDATA[Artifacts that are exposed: <code>groupId:artifactId</code> file.]]>
+ </description>
+ </field>
+ </fields>
+ </class>
+ </classes>
+</model>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/mdo/toolchains.mdo b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/mdo/toolchains.mdo
new file mode 100644
index 00000000..830a5275
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/mdo/toolchains.mdo
@@ -0,0 +1,231 @@
+<?xml version="1.0"?>
+
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+<model xmlns="http://modello.codehaus.org/MODELLO/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://modello.codehaus.org/MODELLO/1.0.0 http://modello.codehaus.org/xsd/modello-1.0.0.xsd"
+ xml.namespace="http://maven.apache.org/TOOLCHAINS/${version}"
+ xml.schemaLocation="http://maven.apache.org/xsd/toolchains-${version}.xsd">
+ <id>toolchains</id>
+ <name>MavenToolchains</name>
+ <description><![CDATA[
+ <p>This is a reference for the Maven Toolchains descriptor.</p>
+ <p>The default location for the toolchains file is <code>~/.m2/toolchains.xml</code></p>
+ <p>A Toolchain is a preconfigured object that Maven plugins can use for tool configuration retrieval (location and other information).</p>
+ <p>The <a href="/plugins/maven-toolchains-plugin/">toolchains-plugin</a> can read available toolchains on the user's computer
+ and match them against the toolchain requirements of the project (as configured in <code>pom.xml</code>):
+ if match is found, the toolchain instance is made available to other Maven plugins.</p>
+ <p>With <code>jdk</code> toolchain, for example, instead of being stuck with the JDK used to run Maven, all plugins can use
+ the same other JDK instance without hardcoding absolute paths into the <code>pom.xml</code>
+ and without configuring every plugin that require path to JDK tools.</p>
+ <p>See the <a href="/guides/mini/guide-using-toolchains.html">Guide to Using Toolchains</a> for
+ more information.</p>
+ ]]></description>
+
+ <defaults>
+ <default>
+ <key>package</key>
+ <value>org.apache.maven.toolchain.model</value>
+ </default>
+ </defaults>
+
+ <classes>
+ <class java.clone="deep">
+ <name>TrackableBase</name>
+ <version>1.1.0+</version>
+ <description>
+ common base class that contains code to track the source for
+ this instance (USER|GLOBAL)
+ </description>
+ <codeSegments>
+ <codeSegment>
+ <version>1.1.0+</version>
+ <code>
+ <![CDATA[
+ public static final String USER_LEVEL = "user-level";
+ public static final String GLOBAL_LEVEL = "global-level";
+
+ private String sourceLevel = USER_LEVEL;
+ private boolean sourceLevelSet = false;
+
+ public void setSourceLevel( String sourceLevel )
+ {
+ if ( sourceLevelSet )
+ {
+ throw new IllegalStateException( "Cannot reset sourceLevel attribute; it is already set to: " + sourceLevel );
+ }
+ else if ( !( USER_LEVEL.equals( sourceLevel ) || GLOBAL_LEVEL.equals( sourceLevel ) ) )
+ {
+ throw new IllegalArgumentException( "sourceLevel must be one of: {" + USER_LEVEL + "," + GLOBAL_LEVEL + "}" );
+ }
+ else
+ {
+ this.sourceLevel = sourceLevel;
+ this.sourceLevelSet = true;
+ }
+ }
+
+ public String getSourceLevel()
+ {
+ return sourceLevel;
+ }
+ ]]>
+ </code>
+ </codeSegment>
+ </codeSegments>
+ </class>
+ <class rootElement="true" xml.tagName="toolchains" xsd.compositor="sequence">
+ <name>PersistedToolchains</name>
+ <superClass>TrackableBase</superClass>
+ <description><![CDATA[
+ The <code>&lt;toolchains&gt;</code> element is the root of the descriptor.
+ The following table lists all of the possible child elements.
+ ]]></description>
+ <version>1.0.0+</version>
+ <fields>
+ <field>
+ <name>toolchains</name>
+ <version>1.0.0+</version>
+ <description><![CDATA[The toolchain instance definition.]]></description>
+ <association xml.itemsStyle="flat">
+ <type>ToolchainModel</type>
+ <multiplicity>*</multiplicity>
+ </association>
+ </field>
+ </fields>
+ </class>
+ <class>
+ <name>ToolchainModel</name>
+ <superClass>TrackableBase</superClass>
+ <version>1.0.0+</version>
+ <description>Definition of a toolchain instance.</description>
+ <fields>
+ <field>
+ <name>type</name>
+ <version>1.0.0+</version>
+ <!-- <identifier>true</identifier> -->
+ <description>
+ <![CDATA[Type of toolchain:<ul>
+ <li><code>jdk</code> for
+ <a href="http://maven.apache.org/plugins/maven-toolchains-plugin/toolchains/jdk.html">JDK Standard Toolchain</a>,</li>
+ <li>other value for
+ <a href="http://maven.apache.org/plugins/maven-toolchains-plugin/toolchains/custom.html">Custom Toolchain</a></li>
+ </ul>
+ ]]></description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>provides</name>
+ <version>1.0.0/1.0.99</version> <!-- fake upperbound, it's inclusive -->
+ <type>DOM</type> <!-- DOM for Maven 2.0.9/2.3.3 -->
+ <description>
+ <![CDATA[
+ <p>Toolchain identification information, which will be matched against project requirements.</p>
+ <p>Actual content structure is completely open: each toolchain type will define its own format and semantics.</p>
+ <p>In general, this is a properties format: <code>&lt;name&gt;value&lt;/name&gt;</code> with
+ predefined properties names.</p>
+ ]]></description>
+ </field>
+ <field>
+ <name>provides</name>
+ <version>1.1.0+</version>
+ <type>Properties</type> <!-- Properties for Maven 2.3.4+ -->
+ <association xml.mapStyle="inline">
+ <type>String</type>
+ <multiplicity>*</multiplicity>
+ </association>
+ <!-- <identifier>true</identifier> -->
+ <description>
+ <![CDATA[
+ <p>Toolchain identification information, which will be matched against project requirements.</p>
+ <p>For Maven 2.0.9 to 3.2.3, the actual content structure was completely open: each toolchain type would define its own format and semantics.
+ In general, this was a properties format.</p>
+ <p>Since Maven 3.2.4, the type for this field has been changed to Properties to match the de-facto format.</p>
+ <p>Each toolchain defines its own properties names and semantics.</p>
+ ]]></description>
+ </field>
+ <field>
+ <name>configuration</name>
+ <version>1.0.0+</version>
+ <type>DOM</type>
+ <description>
+ <![CDATA[
+ <p>Toolchain configuration information, like location or any information that is to be retrieved.</p>
+ <p>Actual content structure is completely open: each toochain type will define its own format and semantics.</p>
+ <p>In general, this is a properties format: <code>&lt;name&gt;value&lt;/name&gt;</code> with
+ per-toolchain defined properties names.</p>
+ ]]></description>
+ </field>
+ </fields>
+ <codeSegments>
+ <codeSegment>
+ <version>1.1.0+</version>
+ <comment>Generated hashCode() and equals() based on identifier also calls its super, which breaks comparison</comment>
+ <code>
+ <![CDATA[
+ /**
+ * Method hashCode.
+ *
+ * @return int
+ */
+ public int hashCode()
+ {
+ int result = 17;
+
+ result = 37 * result + ( type != null ? type.hashCode() : 0 );
+ result = 37 * result + ( provides != null ? provides.hashCode() : 0 );
+
+ return result;
+ } //-- int hashCode()
+
+ /**
+ * Method equals.
+ *
+ * @param other
+ * @return boolean
+ */
+ public boolean equals( Object other )
+ {
+ if ( this == other )
+ {
+ return true;
+ }
+
+ if ( !( other instanceof ToolchainModel ) )
+ {
+ return false;
+ }
+
+ ToolchainModel that = (ToolchainModel) other;
+ boolean result = true;
+
+ result = result && ( getType() == null ? that.getType() == null : getType().equals( that.getType() ) );
+ result = result && ( getProvides() == null ? that.getProvides() == null : getProvides().equals( that.getProvides() ) );
+
+ return result;
+ } //-- boolean equals( Object )
+ ]]>
+ </code>
+ </codeSegment>
+ </codeSegments>
+ </class>
+ </classes>
+</model>
+
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/resources/META-INF/maven/extension.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/resources/META-INF/maven/extension.xml
new file mode 100644
index 00000000..6abf2186
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/resources/META-INF/maven/extension.xml
@@ -0,0 +1,173 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<extension>
+ <exportedPackages>
+ <!-- maven-* -->
+ <exportedPackage>org.apache.maven.*</exportedPackage>
+ <exportedPackage>org.apache.maven.artifact</exportedPackage>
+ <exportedPackage>org.apache.maven.classrealm</exportedPackage>
+ <exportedPackage>org.apache.maven.cli</exportedPackage>
+ <exportedPackage>org.apache.maven.configuration</exportedPackage>
+ <exportedPackage>org.apache.maven.exception</exportedPackage>
+ <exportedPackage>org.apache.maven.execution</exportedPackage>
+ <exportedPackage>org.apache.maven.execution.scope</exportedPackage>
+ <exportedPackage>org.apache.maven.lifecycle</exportedPackage>
+ <exportedPackage>org.apache.maven.model</exportedPackage>
+ <exportedPackage>org.apache.maven.monitor</exportedPackage>
+ <exportedPackage>org.apache.maven.plugin</exportedPackage>
+ <exportedPackage>org.apache.maven.profiles</exportedPackage>
+ <exportedPackage>org.apache.maven.project</exportedPackage>
+ <exportedPackage>org.apache.maven.reporting</exportedPackage>
+ <exportedPackage>org.apache.maven.repository</exportedPackage>
+ <exportedPackage>org.apache.maven.rtinfo</exportedPackage>
+ <exportedPackage>org.apache.maven.settings</exportedPackage>
+ <exportedPackage>org.apache.maven.toolchain</exportedPackage>
+ <exportedPackage>org.apache.maven.usability</exportedPackage>
+
+
+ <!-- wagon-api -->
+ <exportedPackage>org.apache.maven.wagon.*</exportedPackage>
+ <exportedPackage>org.apache.maven.wagon.authentication</exportedPackage>
+ <exportedPackage>org.apache.maven.wagon.authorization</exportedPackage>
+ <exportedPackage>org.apache.maven.wagon.events</exportedPackage>
+ <exportedPackage>org.apache.maven.wagon.observers</exportedPackage>
+ <exportedPackage>org.apache.maven.wagon.proxy</exportedPackage>
+ <exportedPackage>org.apache.maven.wagon.repository</exportedPackage>
+ <exportedPackage>org.apache.maven.wagon.resource</exportedPackage>
+
+ <!-- aether-api, aether-spi, aether-impl -->
+ <exportedPackage>org.eclipse.aether.*</exportedPackage>
+ <exportedPackage>org.eclipse.aether.artifact</exportedPackage>
+ <exportedPackage>org.eclipse.aether.collection</exportedPackage>
+ <exportedPackage>org.eclipse.aether.deployment</exportedPackage>
+ <exportedPackage>org.eclipse.aether.graph</exportedPackage>
+ <exportedPackage>org.eclipse.aether.impl</exportedPackage>
+ <exportedPackage>org.eclipse.aether.internal.impl</exportedPackage>
+ <exportedPackage>org.eclipse.aether.installation</exportedPackage>
+ <exportedPackage>org.eclipse.aether.metadata</exportedPackage>
+ <exportedPackage>org.eclipse.aether.repository</exportedPackage>
+ <exportedPackage>org.eclipse.aether.resolution</exportedPackage>
+ <exportedPackage>org.eclipse.aether.spi</exportedPackage>
+ <exportedPackage>org.eclipse.aether.transfer</exportedPackage>
+ <exportedPackage>org.eclipse.aether.version</exportedPackage>
+
+ <!-- plexus-classworlds -->
+ <exportedPackage>org.codehaus.plexus.classworlds</exportedPackage>
+
+ <!-- classworlds (for legacy code) -->
+ <exportedPackage>org.codehaus.classworlds</exportedPackage>
+
+ <!-- plexus-utils (for DOM-type fields in maven-model) -->
+ <exportedPackage>org.codehaus.plexus.util.xml.Xpp3Dom</exportedPackage>
+ <exportedPackage>org.codehaus.plexus.util.xml.pull.XmlPullParser</exportedPackage>
+ <exportedPackage>org.codehaus.plexus.util.xml.pull.XmlPullParserException</exportedPackage>
+ <exportedPackage>org.codehaus.plexus.util.xml.pull.XmlSerializer</exportedPackage>
+
+ <!-- plexus-container, plexus-component-annotations -->
+ <exportedPackage>org.codehaus.plexus.*</exportedPackage>
+ <exportedPackage>org.codehaus.plexus.component</exportedPackage>
+ <exportedPackage>org.codehaus.plexus.configuration</exportedPackage>
+ <exportedPackage>org.codehaus.plexus.container</exportedPackage>
+ <exportedPackage>org.codehaus.plexus.context</exportedPackage>
+ <exportedPackage>org.codehaus.plexus.lifecycle</exportedPackage>
+ <exportedPackage>org.codehaus.plexus.logging</exportedPackage>
+ <exportedPackage>org.codehaus.plexus.personality</exportedPackage>
+
+ <!-- javax.inject (JSR-330) -->
+ <exportedPackage>javax.inject.*</exportedPackage>
+ <!-- javax.enterprise.inject (JSR-299) -->
+ <exportedPackage>javax.enterprise.util.*</exportedPackage>
+ <exportedPackage>javax.enterprise.inject.*</exportedPackage>
+
+
+ <!--
+ | We may potentially want to export these, but right now I'm not sure that anything Guice specific needs
+ | to be made available to plugin authors. If we find people are getting fancy and want to take advantage of
+ | Guice specifics we can expose that later. Really some testing needs to be done to see full hiding
+ | of Guice has any impact on what we may categorize as a standard JSR-330 based Tesla/Maven plugin.
+
+ <exportedPackage>com.google.inject.*</exportedPackage>
+ <exportedPackage>com.google.inject.binder.*</exportedPackage>
+ <exportedPackage>com.google.inject.matcher.*</exportedPackage>
+ <exportedPackage>com.google.inject.name.*</exportedPackage>
+ <exportedPackage>com.google.inject.spi.*</exportedPackage>
+ <exportedPackage>com.google.inject.util.*</exportedPackage>
+ -->
+
+ <!-- SLF4J -->
+ <exportedPackage>org.slf4j.*</exportedPackage>
+ <exportedPackage>org.slf4j.spi.*</exportedPackage>
+
+ </exportedPackages>
+
+ <exportedArtifacts>
+ <exportedArtifact>classworlds:classworlds</exportedArtifact>
+ <exportedArtifact>org.codehaus.plexus:plexus-classworlds</exportedArtifact>
+ <exportedArtifact>org.codehaus.plexus:plexus-component-api</exportedArtifact>
+ <exportedArtifact>org.codehaus.plexus:plexus-container-default</exportedArtifact>
+ <exportedArtifact>plexus:plexus-container-default</exportedArtifact>
+ <exportedArtifact>org.sonatype.spice:spice-inject-plexus</exportedArtifact>
+ <exportedArtifact>org.sonatype.sisu:sisu-inject-plexus</exportedArtifact>
+ <exportedArtifact>org.eclipse.sisu:org.eclipse.sisu.plexus</exportedArtifact>
+ <exportedArtifact>org.apache.maven:maven-artifact</exportedArtifact>
+ <exportedArtifact>org.apache.maven:maven-aether-provider</exportedArtifact>
+ <exportedArtifact>org.apache.maven:maven-artifact-manager</exportedArtifact>
+ <exportedArtifact>org.apache.maven:maven-compat</exportedArtifact>
+ <exportedArtifact>org.apache.maven:maven-core</exportedArtifact>
+ <exportedArtifact>org.apache.maven:maven-error-diagnostics</exportedArtifact>
+ <exportedArtifact>org.apache.maven:maven-lifecycle</exportedArtifact>
+ <exportedArtifact>org.apache.maven:maven-model</exportedArtifact>
+ <exportedArtifact>org.apache.maven:maven-model-builder</exportedArtifact>
+ <exportedArtifact>org.apache.maven:maven-monitor</exportedArtifact>
+ <exportedArtifact>org.apache.maven:maven-plugin-api</exportedArtifact>
+ <exportedArtifact>org.apache.maven:maven-plugin-descriptor</exportedArtifact>
+ <exportedArtifact>org.apache.maven:maven-plugin-parameter-documenter</exportedArtifact>
+ <exportedArtifact>org.apache.maven:maven-plugin-registry</exportedArtifact>
+ <exportedArtifact>org.apache.maven:maven-profile</exportedArtifact>
+ <exportedArtifact>org.apache.maven:maven-project</exportedArtifact>
+ <exportedArtifact>org.apache.maven:maven-repository-metadata</exportedArtifact>
+ <exportedArtifact>org.apache.maven:maven-settings</exportedArtifact>
+ <exportedArtifact>org.apache.maven:maven-settings-builder</exportedArtifact>
+ <exportedArtifact>org.apache.maven:maven-toolchain</exportedArtifact>
+ <exportedArtifact>org.apache.maven.wagon:wagon-provider-api</exportedArtifact>
+ <exportedArtifact>org.eclipse.aether:aether-api</exportedArtifact>
+ <exportedArtifact>org.eclipse.aether:aether-spi</exportedArtifact>
+ <exportedArtifact>org.eclipse.aether:aether-impl</exportedArtifact>
+
+ <exportedArtifact>javax.inject:javax.inject</exportedArtifact>
+ <exportedArtifact>org.slf4j:slf4j-api</exportedArtifact>
+
+ <!--
+ | We must also filter out the old or NoClassDefFoundErrors will surface
+ -->
+ <exportedArtifact>org.sonatype.aether:aether-api</exportedArtifact>
+ <exportedArtifact>org.sonatype.aether:aether-spi</exportedArtifact>
+ <exportedArtifact>org.sonatype.aether:aether-impl</exportedArtifact>
+
+ <!--
+ | NOTE: Don't exclude the wagons or any of their dependencies (apart from the wagon API). This would otherwise
+ | provoke linkage errors for wagons contributed by build extensions. We also don't need to exclude the wagons
+ | from plugins. Plugins that use wagons directly and declare the corresponding dependency will simply use a
+ | wagon from their plugin realm.
+ -->
+ </exportedArtifacts>
+</extension> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/resources/META-INF/plexus/artifact-handlers.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/resources/META-INF/plexus/artifact-handlers.xml
new file mode 100644
index 00000000..05795beb
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/resources/META-INF/plexus/artifact-handlers.xml
@@ -0,0 +1,219 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<!--
+
+Artifact handlers are required by the dependency resolution mechanism.
+
+-->
+
+<component-set>
+ <components>
+ <!--
+ | POM
+ |-->
+ <component>
+ <role>org.apache.maven.artifact.handler.ArtifactHandler</role>
+ <role-hint>pom</role-hint>
+ <implementation>org.apache.maven.artifact.handler.DefaultArtifactHandler</implementation>
+ <configuration>
+ <type>pom</type>
+ </configuration>
+ </component>
+
+ <!--
+ | JAR
+ |-->
+ <component>
+ <role>org.apache.maven.artifact.handler.ArtifactHandler</role>
+ <role-hint>jar</role-hint>
+ <implementation>org.apache.maven.artifact.handler.DefaultArtifactHandler</implementation>
+ <configuration>
+ <type>jar</type>
+ <language>java</language>
+ <addedToClasspath>true</addedToClasspath>
+ </configuration>
+ </component>
+
+ <!--
+ | EJB
+ |-->
+ <component>
+ <role>org.apache.maven.artifact.handler.ArtifactHandler</role>
+ <role-hint>ejb</role-hint>
+ <implementation>org.apache.maven.artifact.handler.DefaultArtifactHandler</implementation>
+ <configuration>
+ <type>ejb</type>
+ <extension>jar</extension>
+ <language>java</language>
+ <addedToClasspath>true</addedToClasspath>
+ </configuration>
+ </component>
+ <component>
+ <role>org.apache.maven.artifact.handler.ArtifactHandler</role>
+ <role-hint>ejb-client</role-hint>
+ <implementation>org.apache.maven.artifact.handler.DefaultArtifactHandler</implementation>
+ <configuration>
+ <type>ejb-client</type>
+ <extension>jar</extension>
+ <packaging>ejb</packaging>
+ <classifier>client</classifier>
+ <language>java</language>
+ <addedToClasspath>true</addedToClasspath>
+ </configuration>
+ </component>
+ <component>
+ <role>org.apache.maven.artifact.handler.ArtifactHandler</role>
+ <role-hint>ejb3</role-hint>
+ <implementation>org.apache.maven.artifact.handler.DefaultArtifactHandler</implementation>
+ <configuration>
+ <type>ejb3</type>
+ <includesDependencies>true</includesDependencies>
+ <language>java</language>
+ <addedToClasspath>false</addedToClasspath>
+ </configuration>
+ </component>
+
+ <!--
+ | TEST JAR
+ |-->
+ <component>
+ <role>org.apache.maven.artifact.handler.ArtifactHandler</role>
+ <role-hint>test-jar</role-hint>
+ <implementation>org.apache.maven.artifact.handler.DefaultArtifactHandler</implementation>
+ <configuration>
+ <classifier>tests</classifier>
+ <extension>jar</extension>
+ <type>test-jar</type>
+ <packaging>jar</packaging>
+ <language>java</language>
+ <addedToClasspath>true</addedToClasspath>
+ </configuration>
+ </component>
+
+ <!--
+ | MAVEN PLUGIN
+ |-->
+ <component>
+ <role>org.apache.maven.artifact.handler.ArtifactHandler</role>
+ <role-hint>maven-plugin</role-hint>
+ <implementation>org.apache.maven.artifact.handler.DefaultArtifactHandler</implementation>
+ <configuration>
+ <type>maven-plugin</type>
+ <extension>jar</extension>
+ <language>java</language>
+ <addedToClasspath>true</addedToClasspath>
+ </configuration>
+ </component>
+
+ <!--
+ | SOURCE JAR
+ |-->
+ <component>
+ <role>org.apache.maven.artifact.handler.ArtifactHandler</role>
+ <role-hint>java-source</role-hint>
+ <implementation>org.apache.maven.artifact.handler.DefaultArtifactHandler</implementation>
+ <configuration>
+ <classifier>sources</classifier>
+ <type>java-source</type>
+ <extension>jar</extension>
+ <language>java</language>
+ <addedToClasspath>false</addedToClasspath>
+ </configuration>
+ </component>
+
+ <!--
+ | JAVADOC JAR
+ |-->
+ <component>
+ <role>org.apache.maven.artifact.handler.ArtifactHandler</role>
+ <role-hint>javadoc</role-hint>
+ <implementation>org.apache.maven.artifact.handler.DefaultArtifactHandler</implementation>
+ <configuration>
+ <classifier>javadoc</classifier>
+ <type>javadoc</type>
+ <extension>jar</extension>
+ <language>java</language>
+ <addedToClasspath>true</addedToClasspath>
+ </configuration>
+ </component>
+
+ <!--
+ | WAR
+ |-->
+ <component>
+ <role>org.apache.maven.artifact.handler.ArtifactHandler</role>
+ <role-hint>war</role-hint>
+ <implementation>org.apache.maven.artifact.handler.DefaultArtifactHandler</implementation>
+ <configuration>
+ <type>war</type>
+ <includesDependencies>true</includesDependencies>
+ <language>java</language>
+ <addedToClasspath>false</addedToClasspath>
+ </configuration>
+ </component>
+
+ <!--
+ | EAR
+ |-->
+ <component>
+ <role>org.apache.maven.artifact.handler.ArtifactHandler</role>
+ <role-hint>ear</role-hint>
+ <implementation>org.apache.maven.artifact.handler.DefaultArtifactHandler</implementation>
+ <configuration>
+ <type>ear</type>
+ <includesDependencies>true</includesDependencies>
+ <language>java</language>
+ <addedToClasspath>false</addedToClasspath>
+ </configuration>
+ </component>
+
+ <!--
+ | RAR
+ |-->
+ <component>
+ <role>org.apache.maven.artifact.handler.ArtifactHandler</role>
+ <role-hint>rar</role-hint>
+ <implementation>org.apache.maven.artifact.handler.DefaultArtifactHandler</implementation>
+ <configuration>
+ <type>rar</type>
+ <includesDependencies>true</includesDependencies>
+ <language>java</language>
+ <addedToClasspath>false</addedToClasspath>
+ </configuration>
+ </component>
+
+ <!--
+ | PAR
+ |-->
+ <component>
+ <role>org.apache.maven.artifact.handler.ArtifactHandler</role>
+ <role-hint>par</role-hint>
+ <implementation>org.apache.maven.artifact.handler.DefaultArtifactHandler</implementation>
+ <configuration>
+ <type>par</type>
+ <includesDependencies>true</includesDependencies>
+ <language>java</language>
+ <addedToClasspath>false</addedToClasspath>
+ </configuration>
+ </component>
+ </components>
+</component-set>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/resources/META-INF/plexus/components.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/resources/META-INF/plexus/components.xml
new file mode 100644
index 00000000..3f099cb1
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/resources/META-INF/plexus/components.xml
@@ -0,0 +1,134 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<!--
+ There is currently only one component descriptor that cannot be generated from annotations because of the
+ accompanying configuration. Our options are to embed this information programatically or use a configuration source
+ to pull in the lifecycle information.
+-->
+<component-set>
+ <components>
+ <!-- 'default' lifecycle, without any binding since it is dependent on packaging -->
+ <component>
+ <role>org.apache.maven.lifecycle.Lifecycle</role>
+ <implementation>org.apache.maven.lifecycle.Lifecycle</implementation>
+ <role-hint>default</role-hint>
+ <configuration>
+ <id>default</id>
+ <!-- START SNIPPET: lifecycle -->
+ <phases>
+ <phase>validate</phase>
+ <phase>initialize</phase>
+ <phase>generate-sources</phase>
+ <phase>process-sources</phase>
+ <phase>generate-resources</phase>
+ <phase>process-resources</phase>
+ <phase>compile</phase>
+ <phase>process-classes</phase>
+ <phase>generate-test-sources</phase>
+ <phase>process-test-sources</phase>
+ <phase>generate-test-resources</phase>
+ <phase>process-test-resources</phase>
+ <phase>test-compile</phase>
+ <phase>process-test-classes</phase>
+ <phase>test</phase>
+ <phase>prepare-package</phase>
+ <phase>package</phase>
+ <phase>pre-integration-test</phase>
+ <phase>integration-test</phase>
+ <phase>post-integration-test</phase>
+ <phase>verify</phase>
+ <phase>install</phase>
+ <phase>deploy</phase>
+ </phases>
+ <!-- END SNIPPET: lifecycle -->
+ </configuration>
+ </component>
+
+ <!-- 'clean' lifecycle, with default binding -->
+ <component>
+ <role>org.apache.maven.lifecycle.Lifecycle</role>
+ <implementation>org.apache.maven.lifecycle.Lifecycle</implementation>
+ <role-hint>clean</role-hint>
+ <configuration>
+ <id>clean</id>
+ <!-- START SNIPPET: clean -->
+ <phases>
+ <phase>pre-clean</phase>
+ <phase>clean</phase>
+ <phase>post-clean</phase>
+ </phases>
+ <default-phases>
+ <clean>
+ org.apache.maven.plugins:maven-clean-plugin:2.5:clean
+ </clean>
+ </default-phases>
+ <!-- END SNIPPET: clean -->
+ </configuration>
+ </component>
+
+ <!-- 'site' lifecycle, with default bindings -->
+ <component>
+ <role>org.apache.maven.lifecycle.Lifecycle</role>
+ <implementation>org.apache.maven.lifecycle.Lifecycle</implementation>
+ <role-hint>site</role-hint>
+ <configuration>
+ <id>site</id>
+ <!-- START SNIPPET: site -->
+ <phases>
+ <phase>pre-site</phase>
+ <phase>site</phase>
+ <phase>post-site</phase>
+ <phase>site-deploy</phase>
+ </phases>
+ <default-phases>
+ <site>
+ org.apache.maven.plugins:maven-site-plugin:3.3:site
+ </site>
+ <site-deploy>
+ org.apache.maven.plugins:maven-site-plugin:3.3:deploy
+ </site-deploy>
+ </default-phases>
+ <!-- END SNIPPET: site -->
+ </configuration>
+ </component>
+
+ <component>
+ <role>org.sonatype.plexus.components.sec.dispatcher.SecDispatcher</role>
+ <role-hint>maven</role-hint>
+ <implementation>org.sonatype.plexus.components.sec.dispatcher.DefaultSecDispatcher</implementation>
+ <description>Maven Security dispatcher</description>
+ <requirements>
+ <requirement>
+ <role>org.sonatype.plexus.components.cipher.PlexusCipher</role>
+ <field-name>_cipher</field-name>
+ </requirement>
+ <requirement>
+ <role>org.sonatype.plexus.components.sec.dispatcher.PasswordDecryptor</role>
+ <field-name>_decryptors</field-name>
+ </requirement>
+ </requirements>
+ <configuration>
+ <_configuration-file>~/.m2/settings-security.xml</_configuration-file>
+ </configuration>
+ </component>
+ </components>
+</component-set>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/resources/META-INF/plexus/default-bindings.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/resources/META-INF/plexus/default-bindings.xml
new file mode 100644
index 00000000..79d6c52e
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/resources/META-INF/plexus/default-bindings.xml
@@ -0,0 +1,399 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<!--
+
+Mappings to default lifecycle, specific for each packaging.
+
+-->
+
+<component-set>
+ <components>
+ <!--
+ | POM
+ |-->
+ <component>
+ <role>org.apache.maven.lifecycle.mapping.LifecycleMapping</role>
+ <role-hint>pom</role-hint>
+ <implementation>org.apache.maven.lifecycle.mapping.DefaultLifecycleMapping</implementation>
+ <configuration>
+ <lifecycles>
+ <lifecycle>
+ <id>default</id>
+ <!-- START SNIPPET: pom-lifecycle -->
+ <phases>
+ <install>
+ org.apache.maven.plugins:maven-install-plugin:2.4:install
+ </install>
+ <deploy>
+ org.apache.maven.plugins:maven-deploy-plugin:2.7:deploy
+ </deploy>
+ </phases>
+ <!-- END SNIPPET: pom-lifecycle -->
+ </lifecycle>
+ </lifecycles>
+ </configuration>
+ </component>
+
+ <!--
+ | JAR
+ |-->
+ <component>
+ <role>org.apache.maven.lifecycle.mapping.LifecycleMapping</role>
+ <role-hint>jar</role-hint>
+ <implementation>org.apache.maven.lifecycle.mapping.DefaultLifecycleMapping</implementation>
+ <configuration>
+ <lifecycles>
+ <lifecycle>
+ <id>default</id>
+ <!-- START SNIPPET: jar-lifecycle -->
+ <phases>
+ <process-resources>
+ org.apache.maven.plugins:maven-resources-plugin:2.6:resources
+ </process-resources>
+ <compile>
+ org.apache.maven.plugins:maven-compiler-plugin:3.1:compile
+ </compile>
+ <process-test-resources>
+ org.apache.maven.plugins:maven-resources-plugin:2.6:testResources
+ </process-test-resources>
+ <test-compile>
+ org.apache.maven.plugins:maven-compiler-plugin:3.1:testCompile
+ </test-compile>
+ <test>
+ org.apache.maven.plugins:maven-surefire-plugin:2.12.4:test
+ </test>
+ <package>
+ org.apache.maven.plugins:maven-jar-plugin:2.4:jar
+ </package>
+ <install>
+ org.apache.maven.plugins:maven-install-plugin:2.4:install
+ </install>
+ <deploy>
+ org.apache.maven.plugins:maven-deploy-plugin:2.7:deploy
+ </deploy>
+ </phases>
+ <!-- END SNIPPET: jar-lifecycle -->
+ </lifecycle>
+ </lifecycles>
+ </configuration>
+ </component>
+
+ <!--
+ | EJB
+ |-->
+ <component>
+ <role>org.apache.maven.lifecycle.mapping.LifecycleMapping</role>
+ <role-hint>ejb</role-hint>
+ <implementation>org.apache.maven.lifecycle.mapping.DefaultLifecycleMapping</implementation>
+ <configuration>
+ <lifecycles>
+ <lifecycle>
+ <id>default</id>
+ <!-- START SNIPPET: ejb-lifecycle -->
+ <phases>
+ <process-resources>
+ org.apache.maven.plugins:maven-resources-plugin:2.6:resources
+ </process-resources>
+ <compile>
+ org.apache.maven.plugins:maven-compiler-plugin:3.1:compile
+ </compile>
+ <process-test-resources>
+ org.apache.maven.plugins:maven-resources-plugin:2.6:testResources
+ </process-test-resources>
+ <test-compile>
+ org.apache.maven.plugins:maven-compiler-plugin:3.1:testCompile
+ </test-compile>
+ <test>
+ org.apache.maven.plugins:maven-surefire-plugin:2.12.4:test
+ </test>
+ <package>
+ org.apache.maven.plugins:maven-ejb-plugin:2.3:ejb
+ </package>
+ <install>
+ org.apache.maven.plugins:maven-install-plugin:2.4:install
+ </install>
+ <deploy>
+ org.apache.maven.plugins:maven-deploy-plugin:2.7:deploy
+ </deploy>
+ </phases>
+ <!-- END SNIPPET: ejb-lifecycle -->
+ </lifecycle>
+ </lifecycles>
+ </configuration>
+ </component>
+ <component>
+ <role>org.apache.maven.lifecycle.mapping.LifecycleMapping</role>
+ <role-hint>ejb3</role-hint>
+ <implementation>org.apache.maven.lifecycle.mapping.DefaultLifecycleMapping</implementation>
+ <configuration>
+ <lifecycles>
+ <lifecycle>
+ <id>default</id>
+ <!-- START SNIPPET: ejb3-lifecycle -->
+ <phases>
+ <process-resources>
+ org.apache.maven.plugins:maven-resources-plugin:2.6:resources
+ </process-resources>
+ <compile>
+ org.apache.maven.plugins:maven-compiler-plugin:3.1:compile
+ </compile>
+ <process-test-resources>
+ org.apache.maven.plugins:maven-resources-plugin:2.6:testResources
+ </process-test-resources>
+ <test-compile>
+ org.apache.maven.plugins:maven-compiler-plugin:3.1:testCompile
+ </test-compile>
+ <test>
+ org.apache.maven.plugins:maven-surefire-plugin:2.12.4:test
+ </test>
+ <package>
+ org.apache.maven.plugins:maven-ejb3-plugin:ejb3
+ </package>
+ <install>
+ org.apache.maven.plugins:maven-install-plugin:2.4:install
+ </install>
+ <deploy>
+ org.apache.maven.plugins:maven-deploy-plugin:2.7:deploy
+ </deploy>
+ </phases>
+ <!-- END SNIPPET: ejb3-lifecycle -->
+ </lifecycle>
+ </lifecycles>
+ </configuration>
+ </component>
+
+ <!--
+ | MAVEN PLUGIN
+ |-->
+ <component>
+ <role>org.apache.maven.lifecycle.mapping.LifecycleMapping</role>
+ <role-hint>maven-plugin</role-hint>
+ <implementation>org.apache.maven.lifecycle.mapping.DefaultLifecycleMapping</implementation>
+ <configuration>
+ <lifecycles>
+ <lifecycle>
+ <id>default</id>
+ <!-- START SNIPPET: maven-plugin-lifecycle -->
+ <phases>
+ <process-resources>
+ org.apache.maven.plugins:maven-resources-plugin:2.6:resources
+ </process-resources>
+ <compile>
+ org.apache.maven.plugins:maven-compiler-plugin:3.1:compile
+ </compile>
+ <process-classes>
+ org.apache.maven.plugins:maven-plugin-plugin:3.2:descriptor
+ </process-classes>
+ <process-test-resources>
+ org.apache.maven.plugins:maven-resources-plugin:2.6:testResources
+ </process-test-resources>
+ <test-compile>
+ org.apache.maven.plugins:maven-compiler-plugin:3.1:testCompile
+ </test-compile>
+ <test>
+ org.apache.maven.plugins:maven-surefire-plugin:2.12.4:test
+ </test>
+ <package>
+ org.apache.maven.plugins:maven-jar-plugin:2.4:jar,
+ org.apache.maven.plugins:maven-plugin-plugin:3.2:addPluginArtifactMetadata
+ </package>
+ <install>
+ org.apache.maven.plugins:maven-install-plugin:2.4:install
+ </install>
+ <deploy>
+ org.apache.maven.plugins:maven-deploy-plugin:2.7:deploy
+ </deploy>
+ </phases>
+ <!-- END SNIPPET: maven-plugin-lifecycle -->
+ </lifecycle>
+ </lifecycles>
+ </configuration>
+ </component>
+
+ <!--
+ | WAR
+ |-->
+ <component>
+ <role>org.apache.maven.lifecycle.mapping.LifecycleMapping</role>
+ <role-hint>war</role-hint>
+ <implementation>org.apache.maven.lifecycle.mapping.DefaultLifecycleMapping</implementation>
+ <configuration>
+ <lifecycles>
+ <lifecycle>
+ <id>default</id>
+ <!-- START SNIPPET: war-lifecycle -->
+ <phases>
+ <process-resources>
+ org.apache.maven.plugins:maven-resources-plugin:2.6:resources
+ </process-resources>
+ <compile>
+ org.apache.maven.plugins:maven-compiler-plugin:3.1:compile
+ </compile>
+ <process-test-resources>
+ org.apache.maven.plugins:maven-resources-plugin:2.6:testResources
+ </process-test-resources>
+ <test-compile>
+ org.apache.maven.plugins:maven-compiler-plugin:3.1:testCompile
+ </test-compile>
+ <test>
+ org.apache.maven.plugins:maven-surefire-plugin:2.12.4:test
+ </test>
+ <package>
+ org.apache.maven.plugins:maven-war-plugin:2.2:war
+ </package>
+ <install>
+ org.apache.maven.plugins:maven-install-plugin:2.4:install
+ </install>
+ <deploy>
+ org.apache.maven.plugins:maven-deploy-plugin:2.7:deploy
+ </deploy>
+ </phases>
+ <!-- END SNIPPET: war-lifecycle -->
+ </lifecycle>
+ </lifecycles>
+ </configuration>
+ </component>
+
+ <!--
+ | EAR
+ |-->
+ <component>
+ <role>org.apache.maven.lifecycle.mapping.LifecycleMapping</role>
+ <role-hint>ear</role-hint>
+ <implementation>org.apache.maven.lifecycle.mapping.DefaultLifecycleMapping</implementation>
+ <configuration>
+ <lifecycles>
+ <lifecycle>
+ <id>default</id>
+ <!-- START SNIPPET: ear-lifecycle -->
+ <phases>
+ <generate-resources>
+ org.apache.maven.plugins:maven-ear-plugin:2.8:generate-application-xml
+ </generate-resources>
+ <process-resources>
+ org.apache.maven.plugins:maven-resources-plugin:2.4.3:resources
+ </process-resources>
+ <package>
+ org.apache.maven.plugins:maven-ear-plugin:2.8:ear
+ </package>
+ <install>
+ org.apache.maven.plugins:maven-install-plugin:2.4:install
+ </install>
+ <deploy>
+ org.apache.maven.plugins:maven-deploy-plugin:2.7:deploy
+ </deploy>
+ </phases>
+ <!-- END SNIPPET: ear-lifecycle -->
+ </lifecycle>
+ </lifecycles>
+ </configuration>
+ </component>
+
+ <!--
+ | RAR
+ |-->
+ <component>
+ <role>org.apache.maven.lifecycle.mapping.LifecycleMapping</role>
+ <role-hint>rar</role-hint>
+ <implementation>org.apache.maven.lifecycle.mapping.DefaultLifecycleMapping</implementation>
+ <configuration>
+ <lifecycles>
+ <lifecycle>
+ <id>default</id>
+ <!-- START SNIPPET: rar-lifecycle -->
+ <phases>
+ <process-resources>
+ org.apache.maven.plugins:maven-resources-plugin:2.6:resources
+ </process-resources>
+ <compile>
+ org.apache.maven.plugins:maven-compiler-plugin:3.1:compile
+ </compile>
+ <process-test-resources>
+ org.apache.maven.plugins:maven-resources-plugin:2.6:testResources
+ </process-test-resources>
+ <test-compile>
+ org.apache.maven.plugins:maven-compiler-plugin:3.1:testCompile
+ </test-compile>
+ <test>
+ org.apache.maven.plugins:maven-surefire-plugin:2.12.4:test
+ </test>
+ <package>
+ org.apache.maven.plugins:maven-rar-plugin:2.2:rar
+ </package>
+ <install>
+ org.apache.maven.plugins:maven-install-plugin:2.4:install
+ </install>
+ <deploy>
+ org.apache.maven.plugins:maven-deploy-plugin:2.7:deploy
+ </deploy>
+ </phases>
+ <!-- END SNIPPET: rar-lifecycle -->
+ </lifecycle>
+ </lifecycles>
+ </configuration>
+ </component>
+
+ <!--
+ | PAR
+ |-->
+ <component>
+ <role>org.apache.maven.lifecycle.mapping.LifecycleMapping</role>
+ <role-hint>par</role-hint>
+ <implementation>org.apache.maven.lifecycle.mapping.DefaultLifecycleMapping</implementation>
+ <configuration>
+ <lifecycles>
+ <lifecycle>
+ <id>default</id>
+ <!-- START SNIPPET: par-lifecycle -->
+ <phases>
+ <process-resources>
+ org.apache.maven.plugins:maven-resources-plugin:2.6:resources
+ </process-resources>
+ <compile>
+ org.apache.maven.plugins:maven-compiler-plugin:3.1:compile
+ </compile>
+ <process-test-resources>
+ org.apache.maven.plugins:maven-resources-plugin:2.6:testResources
+ </process-test-resources>
+ <test-compile>
+ org.apache.maven.plugins:maven-compiler-plugin:3.1:testCompile
+ </test-compile>
+ <test>
+ org.apache.maven.plugins:maven-surefire-plugin:2.12.4:test
+ </test>
+ <package>
+ org.apache.maven.plugins:maven-par-plugin:par
+ </package>
+ <install>
+ org.apache.maven.plugins:maven-install-plugin:2.4:install
+ </install>
+ <deploy>
+ org.apache.maven.plugins:maven-deploy-plugin:2.7:deploy
+ </deploy>
+ </phases>
+ <!-- END SNIPPET: par-lifecycle -->
+ </lifecycle>
+ </lifecycles>
+ </configuration>
+ </component>
+ </components>
+</component-set>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/resources/org/apache/maven/messages/build.properties b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/resources/org/apache/maven/messages/build.properties
new file mode 100644
index 00000000..d15784a7
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/resources/org/apache/maven/messages/build.properties
@@ -0,0 +1,23 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+buildNumber=${buildNumber}
+timestamp=${timestamp}
+version=${project.version}
+distributionId=${distributionId}
+distributionShortName=${distributionShortName}
+distributionName=${distributionName} \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/resources/org/apache/maven/messages/messages.properties b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/resources/org/apache/maven/messages/messages.properties
new file mode 100644
index 00000000..d576d7aa
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/resources/org/apache/maven/messages/messages.properties
@@ -0,0 +1,34 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+# --------------------------------------------------------------------------
+# Project Verifier
+# --------------------------------------------------------------------------
+failed.download.warning=WARNING: Failed to download {0}.
+remote.repository.disabled.warning=The use of the remote repository has been disabled.
+directory.nonexistant.warning=Directory {0} does not exist. Attempting to create.
+not.directory.warning={0} is not a directory.
+not.writable.warning={0} is not writable.
+cannot.create.directory.warning=Unable to create directory {0}
+maven.repo.local.unset.warning=maven.repo.local is not set.
+single.unsatisfied.dependency.error=The build cannot continue because of the following unsatisfied dependency:
+multiple.unsatisfied.dependency.error=The build cannot continue because of the following unsatisfied dependencies:
+offline.snapshot.warning=You are working offline so the build will continue, but {0} may be out of date!
+download.message=Attempting to download {0}.
+plugin.loading.error=The plugin {0} could not be loaded.
+empty.descriptor.error=The file {0} you specified has zero length.
+checksum.verification.error=The follow artifact is corrupt: {0}.
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/resources/org/apache/maven/messages/messages_de.properties b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/resources/org/apache/maven/messages/messages_de.properties
new file mode 100644
index 00000000..d5c7dad0
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/resources/org/apache/maven/messages/messages_de.properties
@@ -0,0 +1,34 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+# --------------------------------------------------------------------------
+# Project Verifier
+# --------------------------------------------------------------------------
+failed.download.warning=WARNUNG: Herunterladen von {0} fehlgeschlagen.
+remote.repository.disabled.warning=Verwendung entfernter Repositories deaktiviert.
+directory.nonexistant.warning=Verzeichnis {0} existiert nicht, es wird erstellt.
+not.directory.warning={0} ist kein Verzeichnis.
+not.writable.warning=Kann {0} nicht schreiben.
+cannot.create.directory.warning=Kann Verzeichnis {0} nicht erstellen.
+maven.repo.local.unset.warning=maven.repo.local ist nicht gesetzt.
+single.unsatisfied.dependency.error=Der Vorgang wurde aufgrund der folgenden nicht erf\u00FCllten Abh\u00E4ngigkeit abgebrochen:
+multiple.unsatisfied.dependency.error=Der Vorgang wurde aufgrund der folgenden nicht erf\u00FCllten Abh\u00E4ngigkeiten abgebrochen:
+offline.snapshot.warning={0} ist unter Umst\u00E4nden veraltet. Da Sie offline arbeiten, wird der Vorgang fortgesetzt.
+download.message=Versuche {0} herunterzuladen.
+plugin.loading.error=Kann Plugin {0} nicht laden.
+empty.descriptor.error=Datei {0} ist leer.
+checksum.verification.error=Artefakt {0} ist defekt.
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/resources/org/apache/maven/messages/messages_el.properties b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/resources/org/apache/maven/messages/messages_el.properties
new file mode 100644
index 00000000..40a239e9
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/resources/org/apache/maven/messages/messages_el.properties
@@ -0,0 +1,33 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+# --------------------------------------------------------------------------
+# \u00c5\u00eb\u00e5\u00e3\u00ea\u00f4\u00de\u00f2 \u00d3\u00f7\u00e5\u00e4\u00df\u00ef\u00f5
+# --------------------------------------------------------------------------
+failed.download.warning=\u00d0\u00f1\u00ef\u00f3\u00f9\u00f7\u00de! \u00c1\u00e4\u00fd\u00ed\u00e1\u00f4\u00f9\u00ed \u00e7 \u00ec\u00e5\u00f4\u00e1\u00f6\u00ef\u00f1\u00dc \u00f4\u00ef\u00f5 {0}!
+remote.repository.disabled.warning=\u00c7 \u00f7\u00f1\u00de\u00f3\u00e7 \u00e1\u00f0\u00ef\u00ec\u00e1\u00ea\u00f1\u00f5\u00f3\u00ec\u00dd\u00ed\u00f9\u00ed \u00e1\u00f0\u00ef\u00e8\u00e7\u00ea\u00fe\u00ed \u00dd\u00f7\u00e5\u00e9 \u00e1\u00f0\u00e5\u00ed\u00e5\u00f1\u00e3\u00ef\u00f0\u00ef\u00e9\u00e7\u00e8\u00e5\u00df..
+directory.nonexistant.warning=\u00cf \u00ea\u00e1\u00f4\u00dc\u00eb\u00ef\u00e3\u00ef\u00f2 {0} \u00e4\u00e5\u00ed \u00f5\u00f0\u00dc\u00f1\u00f7\u00e5\u00e9! \u00c4\u00ef\u00ea\u00e9\u00ec\u00dc\u00e6\u00f9 \u00e4\u00e7\u00ec\u00e9\u00ef\u00fd\u00f1\u00e3\u00e7\u00f3\u00e7...
+not.directory.warning={0} \u00e4\u00e5\u00ed \u00e5\u00df\u00ed\u00e1\u00e9 \u00ea\u00e1\u00f4\u00dc\u00eb\u00ef\u00e3\u00ef\u00f2!
+not.writable.warning=\u00c1\u00e4\u00fd\u00ed\u00e1\u00f4\u00f9\u00ed \u00e7 \u00e4\u00e9\u00e5\u00e3\u00e3\u00f1\u00e1\u00f6\u00de \u00f3\u00f4\u00ef {0}!
+cannot.create.directory.warning=\u00c1\u00e4\u00fd\u00ed\u00e1\u00f4\u00f9\u00ed \u00e7 \u00e4\u00e7\u00ec\u00e9\u00ef\u00f5\u00f1\u00e3\u00e5\u00df\u00e1 \u00f4\u00ef\u00fd \u00ea\u00e1\u00f4\u00e1\u00eb\u00fc\u00e3\u00ef\u00f5 {0}!
+maven.repo.local.unset.warning=maven.repo.local \u00e4\u00e5\u00ed \u00dd\u00f7\u00e5\u00e9 \u00ef\u00f1\u00e9\u00f3\u00f4\u00e5\u00df.
+single.unsatisfied.dependency.error= \u00c7 \u00e4\u00e9\u00e1\u00e4\u00e9\u00ea\u00e1\u00f3\u00df\u00e1 \u00e4\u00e5\u00ed \u00ec\u00f0\u00ef\u00f1\u00e5\u00df \u00ed\u00e1 \u00f3\u00f5\u00ed\u00e5\u00f7\u00e9\u00f3\u00f4\u00e5\u00df! \u00cb\u00e5\u00df\u00f0\u00e5\u00e9 \u00e7 \u00e1\u00ea\u00fc\u00eb\u00ef\u00f5\u00e8\u00e7 \u00e5\u00ee\u00dc\u00f1\u00f4\u00e7\u00f3\u00e5\u00e9:
+multiple.unsatisfied.dependency.error=\u00c7 \u00e4\u00e9\u00e1\u00e4\u00e9\u00ea\u00e1\u00f3\u00df\u00e1 \u00e4\u00e5\u00ed \u00ec\u00f0\u00ef\u00f1\u00e5\u00df \u00ed\u00e1 \u00f3\u00f5\u00ed\u00e5\u00f7\u00e9\u00f3\u00f4\u00e5\u00df! \u00cb\u00e5\u00df\u00f0\u00ef\u00f5\u00ed \u00e7 \u00e1\u00ea\u00fc\u00eb\u00ef\u00f5\u00e8\u00e5\u00f2 \u00e5\u00ee\u00e1\u00f1\u00f4\u00de\u00f3\u00e5\u00e9\u00f2:
+offline.snapshot.warning=\u00c5\u00f1\u00e3\u00dc\u00e6\u00e5\u00f3\u00e1\u00e9 \u00e1\u00f0\u00ef\u00f3\u00f5\u00ed\u00e4\u00e5\u00e4\u00ef\u00ec\u00dd\u00ed\u00ef\u00f2! \u00c7 \u00e4\u00e9\u00e1\u00e4\u00e9\u00ea\u00e1\u00f3\u00df\u00e1 \u00e8\u00e1 \u00f3\u00f5\u00ed\u00e5\u00f7\u00df\u00f3\u00e5\u00e9 \u00e1\u00eb\u00eb\u00dc \u00e5\u00df\u00ed\u00e1\u00e9 \u00e4\u00f5\u00ed\u00e1\u00f4\u00fe\u00ed {0} \u00ed\u00e1 \u00ec\u00e7\u00ed \u00e5\u00df\u00ed\u00e1\u00e9 \u00e5\u00ed\u00e7\u00ec\u00e5\u00f1\u00f9\u00ec\u00dd\u00ed\u00ef!
+download.message=\u00d0\u00f1\u00f9\u00f3\u00f0\u00e1\u00e8\u00fe \u00ed\u00e1 \u00ec\u00e5\u00f4\u00e1\u00f6\u00dd\u00f1\u00f9 {0}.
+plugin.loading.error=\u00c1\u00e4\u00fd\u00ed\u00e1\u00f4\u00f9\u00ed \u00ed\u00e1 \u00f6\u00ef\u00f1\u00f4\u00f9\u00e8\u00e5\u00df \u00f4\u00ef plugin {0}!
+empty.descriptor.error=\u00d4\u00ef \u00e1\u00f1\u00f7\u00e5\u00df\u00ef {0} \u00f0\u00ef\u00fd \u00ea\u00e1\u00e8\u00ef\u00f1\u00df\u00f3\u00e1\u00f4\u00e5 \u00dd\u00f7\u00e5\u00e9 \u00ec\u00dd\u00e3\u00e5\u00e8\u00ef\u00f2 \u00ec\u00e7\u00e4\u00dd\u00ed.
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/resources/org/apache/maven/messages/messages_en.properties b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/resources/org/apache/maven/messages/messages_en.properties
new file mode 100644
index 00000000..aaf95bfd
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/resources/org/apache/maven/messages/messages_en.properties
@@ -0,0 +1,23 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+# NOTE:
+# This bundle is intentionally empty because English strings are provided by the base bundle via the parent chain. It
+# must be provided nevertheless such that a request for locale "en" will not erroneously pick up the bundle for the
+# JVM's default locale (which need not be "en"). See the method javadoc about
+# ResourceBundle.getBundle(String, Locale, ClassLoader)
+# for a full description of the lookup strategy.
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/resources/org/apache/maven/messages/messages_es.properties b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/resources/org/apache/maven/messages/messages_es.properties
new file mode 100644
index 00000000..d54395e3
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/resources/org/apache/maven/messages/messages_es.properties
@@ -0,0 +1,33 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+# --------------------------------------------------------------------------
+# Verificador de Proyecto
+# --------------------------------------------------------------------------
+failed.download.warning=\u00a1ATENCION!: \u00a1Imposible descargar {0}!
+remote.repository.disabled.warning=El uso de repositorios remotos est\u00e1 desactivado..
+directory.nonexistant.warning=\u00a1El directorio {0} no existe! Intentando crear...
+not.directory.warning=\u00a1{0} no es un directorio!
+not.writable.warning=\u00a1Imposible escribir en {0}!
+cannot.create.directory.warning=\u00a1Imposible crear el directorio {0}!
+maven.repo.local.unset.warning=\u00a1maven.repo.local no est\u00e1 definido!
+single.unsatisfied.dependency.error=\u00a1El proceso no puede seguir! Falta la siguiente dependencia:
+multiple.unsatisfied.dependency.error=\u00a1El proceso no puede seguir! Faltan las siguientes dependencias:
+offline.snapshot.warning=\u00a1Est\u00e1s trabajando fuera de linea! \u00a1El proceso seguir\u00e1, pero es posible que {0} no est\u00e9 actualizado!
+download.message=Intentando descargar {0}.
+plugin.loading.error=\u00a1No se ha podido cargar el plugin {0}!
+empty.descriptor.error=El fichero especificado, {0} , tiene longitud cero.
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/resources/org/apache/maven/messages/messages_fr.properties b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/resources/org/apache/maven/messages/messages_fr.properties
new file mode 100644
index 00000000..06eb48f5
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/resources/org/apache/maven/messages/messages_fr.properties
@@ -0,0 +1,33 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+# --------------------------------------------------------------------------
+# Project Verifier
+# --------------------------------------------------------------------------
+failed.download.warning=ATTENTION: Impossible de t\u00e9l\u00e9charger {0}.
+remote.repository.disabled.warning=L'utilisation du d\u00e9p\u00f4t distant est d\u00e9sactiv\u00e9e.
+directory.nonexistant.warning=Le r\u00e9pertoire {0} n'existe pas. Tentative de cr\u00e9ation.
+not.directory.warning={0} n'est pas un r\u00e9pertoire.
+not.writable.warning=Impossible d'\u00e9crire sur {0}.
+cannot.create.directory.warning=Impossible de cr\u00e9er le r\u00e9pertoire {0}.
+maven.repo.local.unset.warning=maven.repo.local n'est pas d\u00e9fini.
+single.unsatisfied.dependency.error=Le processus ne peut continuer \u00e0 cause de la d\u00e9pendance manquante suivante:
+multiple.unsatisfied.dependency.error=Le processus ne peut continuer \u00e0 cause des d\u00e9pendances manquantes suivantes:
+offline.snapshot.warning=Vous travaillez hors-connexion, alors le processus va continuer, mais {0} peut ne pas \u00eatre \u00e0 jour!
+download.message=Tentative de t\u00e9l\u00e9chargement de {0}.
+plugin.loading.error=Impossible de charger le plugin {0}.
+empty.descriptor.error=Le fichier {0} que vous avez sp\u00e9cifi\u00e9 est vide.
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/resources/org/apache/maven/messages/messages_ja.properties b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/resources/org/apache/maven/messages/messages_ja.properties
new file mode 100644
index 00000000..e1b65666
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/resources/org/apache/maven/messages/messages_ja.properties
@@ -0,0 +1,34 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+# --------------------------------------------------------------------------
+# Project Verifier
+# --------------------------------------------------------------------------
+failed.download.warning=WARNING: {0} \u306e\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u306b\u5931\u6557\u3057\u307e\u3057\u305f.
+remote.repository.disabled.warning=\u30ea\u30e2\u30fc\u30c8\u30ea\u30dd\u30b8\u30c8\u30ea\u304c\u7121\u52b9\u3067\u3059.
+directory.nonexistant.warning=\u30c7\u30a3\u30ec\u30af\u30c8\u30ea {0} \u304c\u5b58\u5728\u3057\u307e\u305b\u3093. \u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u3092\u4f5c\u6210\u3057\u307e\u3059.
+not.directory.warning={0} \u306f\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u3067\u306f\u3042\u308a\u307e\u305b\u3093.
+not.writable.warning={0} \u306f\u66f8\u304d\u8fbc\u307f\u53ef\u80fd\u3067\u306f\u3042\u308a\u307e\u305b\u3093.
+cannot.create.directory.warning=\u30c7\u30a3\u30ec\u30af\u30c8\u30ea {0} \u3092\u4f5c\u6210\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u305b\u3093.
+maven.repo.local.unset.warning=maven.repo.local \u304c\u8a2d\u5b9a\u3055\u308c\u3066\u3044\u307e\u305b\u3093.
+single.unsatisfied.dependency.error=\u4ee5\u4e0b\u306e\u4f9d\u5b58\u95a2\u4fc2\u304c\u6e80\u305f\u3055\u308c\u306a\u304b\u3063\u305f\u305f\u3081\u3001\u30d3\u30eb\u30c9\u3092\u7d9a\u884c\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u305b\u3093:
+multiple.unsatisfied.dependency.error=\u4ee5\u4e0b\u306e\u3044\u304f\u3064\u304b\u306e\u4f9d\u5b58\u95a2\u4fc2\u304c\u6e80\u305f\u3055\u308c\u306a\u304b\u3063\u305f\u305f\u3081\u3001\u30d3\u30eb\u30c9\u3092\u7d9a\u884c\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u305b\u3093:
+offline.snapshot.warning=\u30aa\u30d5\u30e9\u30a4\u30f3\u30e2\u30fc\u30c9\u3067\u30d3\u30eb\u30c9\u3092\u5b9f\u884c\u3057\u307e\u3059. {0} \u306f\u53e4\u3044\u30d0\u30fc\u30b8\u30e7\u30f3\u304c\u5229\u7528\u3055\u308c\u307e\u3059.
+download.message={0} \u3092\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u3057\u307e\u3059.
+plugin.loading.error=\u30d7\u30e9\u30b0\u30a4\u30f3 {0} \u3092\u30ed\u30fc\u30c9\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u305b\u3093.
+empty.descriptor.error=\u6307\u5b9a\u3057\u305f\u30d5\u30a1\u30a4\u30eb {0} \u306f\u7a7a\u306e\u30d5\u30a1\u30a4\u30eb\u3067\u3059.
+checksum.verification.error=\u30a2\u30fc\u30c6\u30a3\u30d5\u30a1\u30af\u30c8 {0} \u304c\u4e0d\u6b63\u3067\u3059.
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/resources/org/apache/maven/messages/messages_ko.properties b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/resources/org/apache/maven/messages/messages_ko.properties
new file mode 100644
index 00000000..b3f1efac
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/resources/org/apache/maven/messages/messages_ko.properties
@@ -0,0 +1,34 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+# --------------------------------------------------------------------------
+# Project Verifier
+# --------------------------------------------------------------------------
+cannot.create.directory.warning = \uB514\uB809\uD130\uB9AC {0} \uC744/\uB97C \uC0DD\uC131\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.
+checksum.verification.error = \uB2E4\uC74C\uC758 \uC544\uB9AC\uD329\uD2B8(artifact)\uC5D0\uC11C \uC5D0\uB7EC\uAC00 \uBC1C\uC0DD\uD569\uB2C8\uB2E4: {0}
+directory.nonexistant.warning = \uB514\uB809\uD130\uB9AC {0} \uC774/\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4. \uC0DD\uC131\uC744 \uC2DC\uB3C4\uD569\uB2C8\uB2E4.
+download.message = {0} \uC744/\uB97C \uB2E4\uC6B4\uB85C\uB4DC \uD569\uB2C8\uB2E4.
+empty.descriptor.error = \uD30C\uC77C {0} \uC758 \uAE38\uC774\uAC00 0\uC785\uB2C8\uB2E4.
+failed.download.warning = \uACBD\uACE0: {0} \uC744/\uB97C \uB2E4\uC6B4\uB85C\uB4DC \uD558\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4.
+maven.repo.local.unset.warning = maven.repo.local \uC774 \uC124\uC815\uB418\uC5B4\uC788\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.
+multiple.unsatisfied.dependency.error = \uB2E4\uC74C\uC758 \uC758\uC874\uC131\uB4E4\uC744 \uB9CC\uC871\uC2DC\uD0A4\uC9C0 \uBABB\uD588\uAE30 \uB54C\uBB38\uC5D0, \uBE4C\uB4DC\uB97C \uACC4\uC18D \uC9C4\uD589\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.
+not.directory.warning = {0} \uC740/\uB294 \uB514\uB809\uD130\uB9AC\uAC00 \uC544\uB2D9\uB2C8\uB2E4.
+not.writable.warning = {0} \uC740/\uB294 \uC4F0\uAE30\uB97C \uD5C8\uC6A9\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.
+offline.snapshot.warning = \uC624\uD504\uB77C\uC778\uC73C\uB85C \uC791\uC5C5\uD558\uACE0 \uC788\uAE30 \uB54C\uBB38\uC5D0 \uBE4C\uB4DC\uB294 \uACC4\uC18D \uC9C4\uD589\uD558\uC9C0\uB9CC, {0} \uC740/\uB294 \uCD5C\uC2E0 \uBC84\uC804\uC774 \uC544\uB2D0 \uC218\uB3C4 \uC788\uC2B5\uB2C8\uB2E4!
+plugin.loading.error = \uD50C\uB7EC\uADF8\uC778 {0} \uC744/\uB97C \uC77D\uC5B4\uC62C \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.
+remote.repository.disabled.warning = \uC6D0\uACA9 \uC800\uC7A5\uC18C \uC0AC\uC6A9\uC744 \uD5C8\uAC00\uD558\uC9C0 \uC54A\uC740(disabled) \uC0C1\uD0DC\uC785\uB2C8\uB2E4.
+single.unsatisfied.dependency.error = \uB2E4\uC74C\uC758 \uC758\uC874\uC131\uB4E4\uC744 \uB9CC\uC871\uC2DC\uD0A4\uC9C0 \uBABB\uD588\uAE30 \uB54C\uBB38\uC5D0, \uBE4C\uB4DC\uB97C \uACC4\uC18D \uC9C4\uD589\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/resources/org/apache/maven/messages/messages_nl.properties b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/resources/org/apache/maven/messages/messages_nl.properties
new file mode 100644
index 00000000..0e22d6ce
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/resources/org/apache/maven/messages/messages_nl.properties
@@ -0,0 +1,33 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+# --------------------------------------------------------------------------
+# Project Verifier
+# --------------------------------------------------------------------------
+failed.download.warning=WAARSCHUWING: Kan {0} niet downloaden.
+remote.repository.disabled.warning=Het gebruik van de remote repository is uitgezet.
+directory.nonexistant.warning=Directory {0} bestaat niet. Probeer hem aan te maken.
+not.directory.warning={0} is geen directory.
+not.writable.warning={0} is niet schrijfbaar.
+cannot.create.directory.warning=Kan {0} directory niet aanmaken
+maven.repo.local.unset.warning=maven.repo.local is niet ingesteld.
+single.unsatisfied.dependency.error=Het bouwen kan niet doorgaan, omdat de volgende afhankelijkheid niet achterhaald kan worden:
+multiple.unsatisfied.dependency.error=Het bouwen kan niet doorgaan, omdat de volgende afhankelijkheden niet achterhaald kunnen worden:
+offline.snapshot.warning=Je werkt offline, dus het bouwen gaat verder, maar {0} kan eventueel niet up-to-date zijn!
+download.message=Probeer {0} te downloaden.
+plugin.loading.error=De {0} plugin kan niet worden geladen.
+empty.descriptor.error=The {0} file you specified has zero length.
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/resources/org/apache/maven/messages/messages_no.properties b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/resources/org/apache/maven/messages/messages_no.properties
new file mode 100644
index 00000000..af320f6b
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/resources/org/apache/maven/messages/messages_no.properties
@@ -0,0 +1,33 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+# --------------------------------------------------------------------------
+# Project Verifier
+# --------------------------------------------------------------------------
+failed.download.warning=ADVARSEL: Mislykket nedlasting av {0}.
+remote.repository.disabled.warning=Bruk av fjernlager er deaktivert.
+directory.nonexistant.warning=Mappen {0} finnes ikke. Fors\u00f8ker \u00e5 opprette.
+not.directory.warning={0} er ikke en mappe.
+not.writable.warning=Kan ikke skirve til {0}.
+cannot.create.directory.warning=Kan ikke opprette mappen {0}.
+maven.repo.local.unset.warning=maven.repo.local er ikke definert.
+single.unsatisfied.dependency.error=Byggeprosessen kan ikke fortsette p\u00e5 grunn av f\u00f8lgende mislykkede avhengighet:
+multiple.unsatisfied.dependency.error=The build cannot continue because of the following unsatisfied dependencies:
+offline.snapshot.warning=Du arbeider frakoblet. Byggeprosessen vil fortsette, men {0} kan bli utdatert!
+download.message=Fors\u00f8ker \u00e5 laste ned {0}.
+plugin.loading.error=Plugin {0} kunne ikke lastes.
+empty.descriptor.error=The {0} file you specified has zero length.
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/resources/org/apache/maven/messages/messages_pl.properties b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/resources/org/apache/maven/messages/messages_pl.properties
new file mode 100644
index 00000000..36a292bd
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/resources/org/apache/maven/messages/messages_pl.properties
@@ -0,0 +1,33 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+# --------------------------------------------------------------------------
+# Project Verifier
+# --------------------------------------------------------------------------
+failed.download.warning=UWAGA: Nie uda\u0142o si\u0119 sci\u0105gn\u0105\u0107 {0}.
+remote.repository.disabled.warning=Korzystanie ze zdalnego repozytorium jest wy\u0142\u0105czone.
+directory.nonexistant.warning=Katalog {0} nie istnieje. Pr\u00f3buj\u0119 utworzy\u0107.
+not.directory.warning={0} nie jest katalogiem.
+not.writable.warning=Nie mo\u017cesz zapisa\u0107 {0}.
+cannot.create.directory.warning=Nie mo\u017cesz utworzy\u0107 katalogu {0}.
+maven.repo.local.unset.warning=maven.repo.local nie jest zdefiniowane.
+single.unsatisfied.dependency.error=Budownaie przerwane z powodu nast\u0119puj\u0105cej niespe\u0142nionej zale\u017cno\u015bci:
+multiple.unsatisfied.dependency.error=Budownaie przerwane z powodu nast\u0119puj\u0105cych niespe\u0142nionych zale\u017cno\u015bci:
+offline.snapshot.warning=Pracujesz w trybie offline, wi\u0119c budowanie b\u0119dzie kontunuowane, cho\u0107 {0} mo\u017ce by\u0107 nieaktualny!
+download.message=Pr\u00f3buj\u0119 \u015bci\u0105gn\u0105\u0107 {0}.
+plugin.loading.error=Nie uda\u0142o si\u0119 za\u0142adowa\u0107 pluginu {0}.
+empty.descriptor.error=The {0} file you specified has zero length.
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/resources/org/apache/maven/messages/messages_zh_CN.properties b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/resources/org/apache/maven/messages/messages_zh_CN.properties
new file mode 100644
index 00000000..93695186
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/resources/org/apache/maven/messages/messages_zh_CN.properties
@@ -0,0 +1,34 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+# --------------------------------------------------------------------------
+# \u9879\u76ee\u9a8c\u8bc1
+# --------------------------------------------------------------------------
+failed.download.warning=\u8b66\u544a\uff1a {0} \u4e0b\u8f7d\u5931\u8d25\u3002
+remote.repository.disabled.warning=\u7981\u6b62\u4f7f\u7528\u8fdc\u7a0b\u8d44\u6e90\u4ed3\u5e93\u3002
+directory.nonexistant.warning=\u76ee\u5f55 {0} \u4e0d\u5b58\u5728\u3002 \u5c1d\u8bd5\u65b0\u5efa\u4e2d\u2026\u2026
+not.directory.warning={0} \u4e0d\u662f\u76ee\u5f55\u3002
+not.writable.warning={0} \u53ea\u8bfb\u3002
+cannot.create.directory.warning=\u521b\u5efa\u76ee\u5f55 {0} \u5931\u8d25\u3002
+maven.repo.local.unset.warning=\u6ca1\u6709\u8bbe\u7f6e maven.repo.local \u5c5e\u6027\u3002
+single.unsatisfied.dependency.error=\u7531\u4e8e\u4ee5\u4e0b\u7684\u4f9d\u8d56\u7f3a\u5c11\uff0c\u521b\u5efa\u4e0d\u80fd\u8fdb\u884c\uff1a
+multiple.unsatisfied.dependency.error=\u7531\u4e8e\u4ee5\u4e0b\u7684\u4f9d\u8d56\u7f3a\u5c11\uff0c\u521b\u5efa\u4e0d\u80fd\u8fdb\u884c\uff1a
+offline.snapshot.warning=\u79bb\u7ebf\u65f6\u521b\u5efa\uff0c\u53ef\u80fd {0} \u8fc7\u671f\uff01
+download.message=\u5c1d\u8bd5\u4e0b\u8f7d {0}\u2026\u2026
+plugin.loading.error=\u88c5\u5165 plugin {0} \u5931\u8d25\u3002
+empty.descriptor.error=\u6587\u4ef6 {0} \u7684\u957f\u5ea6\u4e3a0\u3002
+checksum.verification.error=\u4ee5\u4e0b\u8d44\u6e90\u5df2\u88ab\u7834\u574f\uff1a{0}\u3002
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/resources/org/apache/maven/project/standalone.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/resources/org/apache/maven/project/standalone.xml
new file mode 100644
index 00000000..acb5be2d
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/main/resources/org/apache/maven/project/standalone.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven</groupId>
+ <artifactId>standalone-pom</artifactId>
+ <version>1</version>
+ <packaging>pom</packaging>
+ <name>Maven Stub Project (No POM)</name>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/site/apt/artifact-handlers.apt b/framework/src/maven/apache-maven-3.3.3/maven-core/src/site/apt/artifact-handlers.apt
new file mode 100644
index 00000000..916161bf
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/site/apt/artifact-handlers.apt
@@ -0,0 +1,59 @@
+~~ Licensed to the Apache Software Foundation (ASF) under one
+~~ or more contributor license agreements. See the NOTICE file
+~~ distributed with this work for additional information
+~~ regarding copyright ownership. The ASF licenses this file
+~~ to you under the Apache License, Version 2.0 (the
+~~ "License"); you may not use this file except in compliance
+~~ with the License. You may obtain a copy of the License at
+~~
+~~ http://www.apache.org/licenses/LICENSE-2.0
+~~
+~~ Unless required by applicable law or agreed to in writing,
+~~ software distributed under the License is distributed on an
+~~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+~~ KIND, either express or implied. See the License for the
+~~ specific language governing permissions and limitations
+~~ under the License.
+
+ ---
+ Default Artifact Handlers Reference
+ ---
+ Hervé Boutemy
+ ---
+ 2013-08-02
+ ---
+
+Default Artifact Handlers Reference
+
+ Some artifact handlers (see {{{../maven-artifact/apidocs/org/apache/maven/artifact/handler/ArtifactHandler.html} API}})
+ are configured by default in <<<META-INF/plexus/artifact-handlers.xml>>>:
+
+*--------------------+------------+------------+---------------+-----------+---------------------+-----------------------+
+|| type || extension || packaging || classifier || language || added to classpath || includesDependencies ||
+*--------------------+------------+------------+---------------+-----------+---------------------+-----------------------+
+| <<<pom>>> | <= type> | <= type> | | none | | |
+*--------------------+------------+------------+---------------+-----------+---------------------+-----------------------+
+| <<<jar>>> | <= type> | <= type> | | java | <<<true>>> | |
+*--------------------+------------+------------+---------------+-----------+---------------------+-----------------------+
+| <<<maven-plugin>>> | <<<jar>>> | <= type> | | java | <<<true>>> | |
+*--------------------+------------+------------+---------------+-----------+---------------------+-----------------------+
+| <<<ejb>>> | <<<jar>>> | <= type> | | java | <<<true>>> | |
+*--------------------+------------+------------+---------------+-----------+---------------------+-----------------------+
+| <<<ejb3>>> | <= type> | <= type> | | java | | <<<true>>> |
+*--------------------+------------+------------+---------------+-----------+---------------------+-----------------------+
+| <<<war>>> | <= type> | <= type> | | java | | <<<true>>> |
+*--------------------+------------+------------+---------------+-----------+---------------------+-----------------------+
+| <<<ear>>> | <= type> | <= type> | | java | | <<<true>>> |
+*--------------------+------------+------------+---------------+-----------+---------------------+-----------------------+
+| <<<rar>>> | <= type> | <= type> | | java | | <<<true>>> |
+*--------------------+------------+------------+---------------+-----------+---------------------+-----------------------+
+| <<<par>>> | <= type> | <= type> | | java | | <<<true>>> |
+*--------------------+------------+------------+---------------+-----------+---------------------+-----------------------+
+| <<<java-source>>> | <<<jar>>> | <= type> | <<<sources>>> | java | | |
+*--------------------+------------+------------+---------------+-----------+---------------------+-----------------------+
+| <<<javadoc>>> | <<<jar>>> | <= type> | <<<javadoc>>> | java | <<<true>>> | |
+*--------------------+------------+------------+---------------+-----------+---------------------+-----------------------+
+| <<<ejb-client>>> | <<<jar>>> | <<<ejb>>> | <<<client>>> | java | <<<true>>> | |
+*--------------------+------------+------------+---------------+-----------+---------------------+-----------------------+
+| <<<test-jar>>> | <<<jar>>> | <<<jar>>> | <<<tests>>> | java | <<<true>>> | |
+*--------------------+------------+------------+---------------+-----------+---------------------+-----------------------+
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/site/apt/configuration-management.apt b/framework/src/maven/apache-maven-3.3.3/maven-core/src/site/apt/configuration-management.apt
new file mode 100644
index 00000000..4af0f0b1
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/site/apt/configuration-management.apt
@@ -0,0 +1,139 @@
+~~ Licensed to the Apache Software Foundation (ASF) under one
+~~ or more contributor license agreements. See the NOTICE file
+~~ distributed with this work for additional information
+~~ regarding copyright ownership. The ASF licenses this file
+~~ to you under the Apache License, Version 2.0 (the
+~~ "License"); you may not use this file except in compliance
+~~ with the License. You may obtain a copy of the License at
+~~
+~~ http://www.apache.org/licenses/LICENSE-2.0
+~~
+~~ Unless required by applicable law or agreed to in writing,
+~~ software distributed under the License is distributed on an
+~~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+~~ KIND, either express or implied. See the License for the
+~~ specific language governing permissions and limitations
+~~ under the License.
+
+ -----
+ Maven configuration management
+ -----
+ The Maven Team
+ -----
+
+Configuration levels in maven
+
+ In maven configuration control happens on four differ levels: the site level, the group level,
+ the project level, and the user level. On the site level you can configure maven for all users
+ utilizing the local installation, the group level allows configuration management for all the projects
+ that belong to the same group, the project level allows configuration management at
+ the project level, and the user level allows users to override settings on
+ the site level, group level and project level.
+
+* Site configuration
+
+ At the site level all configuration is achieved by tweaking the the various files that
+ are available in the ${maven.home}/site-configuration directory
+
++-----+
+${maven.home}
+ |
+ +--- maven.properties
++-----+
+
+* Group configuration
+
+ As far as properties go for an entire build the maven.properties could be placed at
+ the top of the group but I'm not really sure how this might work. There could probably
+ also be a directory for plugins.xml and maven.properties.
+
+* Project configuration
+
+ At the project level all configuration is achieved by tweaking the POM. One of the differences between
+ maven 1.x and 2.x is that all project parameterization occurs in the POM and not from properties
+ files.
+
+ For many of the more advanced features in Maven2 it is critical that POMs be available in the local repository.
+ Features like transitive dependencies and the new parent specification mechanism. The problem we run into is
+ that currently we have information about a project scattered across the project.xml and the
+ various properties files. What needs to be done is to encapsulate all of this in the POM.
+
+ Typically users parameterize the use of plugins, or have custom values like ${user.name}
+ for use in elements like the <developerConnection/>. It would be idea if we
+ could encapsulate everything we need about the project in the POM including
+ plugin parameters and anything else.
+
+ We once had a document that Vincent and I agreed upon and I was about to
+ implement it and then I disappeared for 8 months so it never came to pass.
+
+ So I guess it's important to figure out what people are using propeties
+ files for and see if we can't incorporate it all into the POM. Or if we do
+ have properties file (something I would like to avoid) say they don't
+ contribute in any meaningful way to information in the POM. For example a
+ properties file could be used the specify $ so it can be interpolated in
+ <developerConnection/> but you couldn't use a properties file to specify the
+ version of your project say. Anyway, food for thought to begin with.
+
+ - elements that are critical for pom dissemination
+ - those that are used locally by the user like <developerConnection/>
+
+* User configuration
+
+ User configuration which is utilized site wide are controlled with the ${user.home}/.m2/maven.properties.
+
+ User configuration which is utilized at the project level are controlled with the
+ ${project.home}/maven.properties file.
+
+Plugin configuration
+
+ The configuration of plugins is of the same form as the maven {{{plugin-descriptors}plugin descriptors}}
+ themselves:
+
++-----+
+<plugins>
+ <plugin>
+ <id>xdoc</id>
+ <version>1.0</version>
+ <parameters>
+ <parameter>
+ <name>theme</name>
+ <value>classic</value>
+ </parameter>
+ </parameters>
+ </plugin>
+</plugins>
++-----+
+
+Unified source directory
+
+ Unified source directory structure that is analagous to the repository
+ itself. This way locations of intermediary artifacts of a build would be
+ in a known location. This would also help with developer setup i.e. getting
+ new developers up and running. They could run a maven command and have all
+ their source trees set up in the same way as their collegues.
+
+ here's what I do currently in the netbeans part of the mevenide project to
+ find the relevant subprojects/sibling projects. I check if the user has
+ defined the maven.multiproject.includes property in any of his properties
+ files for the current project. if yes. then I'm able to find projects that
+ can be offered to be opened together with the current project.
+ problems with the current solution are:
+ 1. information is duplicate. once in POM's dependencies and once in the
+ maven.multiproject.includes property.
+ 2. it works without problems only for projects with relative paths, eg. from
+ one CVS repository.. for projects from multiple SCM repositories it's harder
+ to maintain the same relative links on all developer computers.
+ not sure the unified source directory structure addresses this issue.
+
+ Properties
+
+ maven.user.config.dir (system,default=${user.home}/.m2)
+ maven.home (system,user,default=${user.home}/m2)
+ maven.repo.local (system,user,default=${maven.user.config.dir}/repository)
+
+ We need to define what happens in the when things are not setup correctly
+
+ o ~/.m2 directory does not exist
+ o ~/.m2/maven.properties does not exist
+ o if they once existed but now to do not exist
+ o what the installer will take care of of what we can recover from
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/site/apt/default-bindings.apt.vm b/framework/src/maven/apache-maven-3.3.3/maven-core/src/site/apt/default-bindings.apt.vm
new file mode 100644
index 00000000..02d6c4a9
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/site/apt/default-bindings.apt.vm
@@ -0,0 +1,67 @@
+~~ Licensed to the Apache Software Foundation (ASF) under one
+~~ or more contributor license agreements. See the NOTICE file
+~~ distributed with this work for additional information
+~~ regarding copyright ownership. The ASF licenses this file
+~~ to you under the Apache License, Version 2.0 (the
+~~ "License"); you may not use this file except in compliance
+~~ with the License. You may obtain a copy of the License at
+~~
+~~ http://www.apache.org/licenses/LICENSE-2.0
+~~
+~~ Unless required by applicable law or agreed to in writing,
+~~ software distributed under the License is distributed on an
+~~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+~~ KIND, either express or implied. See the License for the
+~~ specific language governing permissions and limitations
+~~ under the License.
+
+ ---
+ Plugin Bindings for Default Lifecycle Reference
+ ---
+ Hervé Boutemy
+ ---
+ 2013-08-02
+ ---
+
+Plugin Bindings for <<<default>>> Lifecycle Reference
+
+ The {{{./lifecycles.html}<<<default>>> lifecycle}} is defined without any plugin binding; plugin bindings are defined separately
+ in <<<META-INF/plexus/default-bindings.xml>>> because they are specific for each packaging:
+
+%{toc|fromDepth=2}
+
+* Plugin bindings for <<<pom>>> packaging
+
+%{snippet|id=pom-lifecycle|file=${project.basedir}/src/main/resources/META-INF/plexus/default-bindings.xml}
+
+* Plugin bindings for <<<jar>>> packaging
+
+%{snippet|id=jar-lifecycle|file=${project.basedir}/src/main/resources/META-INF/plexus/default-bindings.xml}
+
+* Plugin bindings for <<<ejb>>> packaging
+
+%{snippet|id=ejb-lifecycle|file=${project.basedir}/src/main/resources/META-INF/plexus/default-bindings.xml}
+
+* Plugin bindings for <<<ejb3>>> packaging
+
+%{snippet|id=ejb3-lifecycle|file=${project.basedir}/src/main/resources/META-INF/plexus/default-bindings.xml}
+
+* Plugin bindings for <<<maven-plugin>>> packaging
+
+%{snippet|id=maven-plugin-lifecycle|file=${project.basedir}/src/main/resources/META-INF/plexus/default-bindings.xml}
+
+* Plugin bindings for <<<war>>> packaging
+
+%{snippet|id=war-lifecycle|file=${project.basedir}/src/main/resources/META-INF/plexus/default-bindings.xml}
+
+* Plugin bindings for <<<ear>>> packaging
+
+%{snippet|id=ear-lifecycle|file=${project.basedir}/src/main/resources/META-INF/plexus/default-bindings.xml}
+
+* Plugin bindings for <<<rar>>> packaging
+
+%{snippet|id=rar-lifecycle|file=${project.basedir}/src/main/resources/META-INF/plexus/default-bindings.xml}
+
+* Plugin bindings for <<<par>>> packaging
+
+%{snippet|id=par-lifecycle|file=${project.basedir}/src/main/resources/META-INF/plexus/default-bindings.xml}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/site/apt/getting-to-container-configured-mojos.apt b/framework/src/maven/apache-maven-3.3.3/maven-core/src/site/apt/getting-to-container-configured-mojos.apt
new file mode 100644
index 00000000..1c4a487d
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/site/apt/getting-to-container-configured-mojos.apt
@@ -0,0 +1,102 @@
+~~ Licensed to the Apache Software Foundation (ASF) under one
+~~ or more contributor license agreements. See the NOTICE file
+~~ distributed with this work for additional information
+~~ regarding copyright ownership. The ASF licenses this file
+~~ to you under the Apache License, Version 2.0 (the
+~~ "License"); you may not use this file except in compliance
+~~ with the License. You may obtain a copy of the License at
+~~
+~~ http://www.apache.org/licenses/LICENSE-2.0
+~~
+~~ Unless required by applicable law or agreed to in writing,
+~~ software distributed under the License is distributed on an
+~~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+~~ KIND, either express or implied. See the License for the
+~~ specific language governing permissions and limitations
+~~ under the License.
+
+ ---
+ Getting to Plexus-configured Mojos
+ ---
+ John Casey
+ ---
+ 29-April-2005
+
+Abstract
+
+ We're moving toward integrating mojos as first-class plexus components, while
+ at the same time avoiding introducing required plexus dependencies into the
+ mojo development model.
+
+ In order to really achieve this, we need mojo configurations (which are
+ provided both in terms of static expressions that are just looked up, and
+ in terms of user-provided configuration from system properties or the POM).
+ If these mojos are to be first-class components, the configuration from these
+ various sources must be consolidated and injected using the container.
+
+ Currently, mojo configuration is done externally to the container, in the
+ DefaultPluginManager in the maven-core API. In order to get from here to
+ there, we need to do several things to add capability to the default
+ configuration of plexus. This document will detail those changes.
+
+Container Enhancements
+
+* ExpressionEvaluator
+
+ Currently, the expression evaluator used to resolve configuration values
+ is the DefaultExpressionEvaluator, which is a local variable within the
+ implementation of the BasicComponentConfigurator. This ExpressionEvaluator
+ simply returns the expression itself as the resolved value, which adds
+ very little value to the container. Things like ${project.build.resources}
+ are not resolved, and result in a type mismatch for the member injection.
+
+ We need a replacement for DefaultExpressionEvaluator that is capable of
+ traversing an object graph and extracting Object values, not just Strings.
+
+* ComponentConfigurator
+
+ Currently, the container uses BasicComponentConfigurator, to configure
+ components. This wouldn't be a problem, except for the local instance of
+ DefaultExpressionEvaluator used within. See the above discussion for more
+ on why this evaluator is bad. We need to provide either an alternative
+ implementation under a different roleHint, or else replace the
+ BasicComponentConfigurator.
+
+* Other
+
+ We may need to define a new lifecycle/phase to contextualize a mojo right
+ before it's used, and reset it's state afterward. Up to now, the approach
+ of most plexus components has been to avoid instance state like the plague.
+ With the current parameter passing model of mojos, this will not be possible,
+ particularly when we move mojos to a singleton instantiation model, and then
+ run a reactorized project...the successive calls may leave behind configuration
+ artifacts from invocation to invocation.
+
+Maven Modifications
+
+* DefaultPluginManager
+
+ s/getMojoConfiguration()/getConfiguration()/g
+
+ That should re-enable usage of mojo configuration. Ideally, we won't need any
+ of the code that references this method, since the container should provide
+ some way of recontextualizing the mojo, and all we would need to do is inject
+ POM configuration via the lookup method or something.
+
+* PluginDescriptorBuilder
+
+ s/getMojoConfiguration()/getConfiguration()/g
+
+ That should be all there is to it.
+
+* MojoDescriptor
+
+ Remove set/getMojoConfiguration(..), as it will become obsolete.
+
+* MavenSession
+
+ We may need to enable the context injection here, since this will be
+ instantiated per-project. If we always inject the same context parameters,
+ and are careful to inject nulls where things are missing, we should be
+ able to minimize reconfiguration artifacts injected from basic parameters.
+
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/site/apt/index.apt b/framework/src/maven/apache-maven-3.3.3/maven-core/src/site/apt/index.apt
new file mode 100644
index 00000000..f6c26fde
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/site/apt/index.apt
@@ -0,0 +1,77 @@
+~~ Licensed to the Apache Software Foundation (ASF) under one
+~~ or more contributor license agreements. See the NOTICE file
+~~ distributed with this work for additional information
+~~ regarding copyright ownership. The ASF licenses this file
+~~ to you under the Apache License, Version 2.0 (the
+~~ "License"); you may not use this file except in compliance
+~~ with the License. You may obtain a copy of the License at
+~~
+~~ http://www.apache.org/licenses/LICENSE-2.0
+~~
+~~ Unless required by applicable law or agreed to in writing,
+~~ software distributed under the License is distributed on an
+~~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+~~ KIND, either express or implied. See the License for the
+~~ specific language governing permissions and limitations
+~~ under the License.
+
+ -----
+ Introduction
+ -----
+ Hervé Boutemy
+ -----
+ 2013-07-27
+ -----
+
+Maven Core
+
+ Maven Core classes managing the whole build process.
+
+* Useful entry points
+
+ * {{{./lifecycles.html}lifecycles}} and {{{./default-bindings.html}plugin bindings to <<<default>>> lifecycle}},
+
+ * {{{./artifact-handlers.html}default artifact handlers}},
+
+ * <<<Maven>>> component ({{{./apidocs/org/apache/maven/Maven.html}javadoc}}),
+ with its <<<DefaultMaven>>> implementation ({{{./xref/org/apache/maven/DefaultMaven.html}source}}),
+
+ * <<<ProjectBuilder>>> component ({{{./apidocs/org/apache/maven/project/ProjectBuilder.html}javadoc}}),
+ with its <<<DefaultProjectBuilder>>> implementation
+ ({{{./xref/org/apache/maven/project/DefaultProjectBuilder.html}source}}),
+
+ * <<<MavenPluginManager>>> component ({{{./apidocs/org/apache/maven/plugin/MavenPluginManager.html}javadoc}}),
+ with its <<<DefaultMavenPluginManager>>> implementation
+ ({{{./xref/org/apache/maven/plugin/internal/DefaultMavenPluginManager.html}source}}),
+
+ * {{{./apidocs/org/apache/maven/plugin/PluginParameterExpressionEvaluator.html}PluginParameterExpressionEvaluator}}, used to
+ evaluate plugin parameters values during Mojo configuration,
+
+ * {{{/guides/mini/guide-maven-classloading.html}classloader hierarchy}} done by <<<ClassRealmManager>>> component
+ ({{{./apidocs/org/apache/maven/classrealm/ClassRealmManager.html}javadoc}}),
+ with its <<<DefaultClassRealmManager>>> implementation
+ ({{{./xref/org/apache/maven/classrealm/DefaultClassRealmManager.html}source}}), using
+ {{{http://plexus.codehaus.org/plexus-classworlds/}Plexus Classworlds}},
+
+ * {{{./extension.html}extension descriptor}},
+
+ * <<<ExceptionHandler>>> component ({{{./apidocs/org/apache/maven/exception/ExceptionHandler.html}javadoc}}),
+ with its <<<DefaultExceptionHandler>>> implementation
+ ({{{./xref/org/apache/maven/exception/DefaultExceptionHandler.html}source}}), use to transform exception into useful end-user messages.
+
+* Toolchains
+
+ * {{{./toolchains.html}Toolchains descriptor reference}},
+
+ * public API for toolchains-aware plugins: <<<ToolchainManager>>> component ({{{./apidocs/org/apache/maven/toolchain/ToolchainManager.html}javadoc}})
+ with its <<<DefaultToolchainManager>>> implementation ({{{./xref/org/apache/maven/toolchain/DefaultToolchainManager.html}source}}),
+ to get selected <<<Toolchain>>> ({{{./apidocs/org/apache/maven/toolchain/Toolchain.html}javadoc}}) instance,
+
+ * internal <<<ToolchainManagerPrivate>>> component ({{{./apidocs/org/apache/maven/toolchain/ToolchainManagerPrivate.html}javadoc}})
+ with its <<<DefaultToolchainManagerPrivate>>> implementation ({{{./xref/org/apache/maven/toolchain/DefaultToolchainManagerPrivate.html}source}}),
+ to manage toolchain selection,
+
+ * internal JDK toolchain implementation: <<<JavaToolchain>>> interface ({{{./apidocs/org/apache/maven/toolchain/java/JavaToolchain.html}javadoc}}),
+ with its <<<JavaToolchainImpl>>> implementation
+ ({{{./xref/org/apache/maven/toolchain/java/JavaToolchainImpl.html}source}}) and <<<JavaToolchainFactory>>>
+ factory ({{{./xref/org/apache/maven/toolchain/java/JavaToolchainFactory.html}source}}).
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/site/apt/inheritance.apt b/framework/src/maven/apache-maven-3.3.3/maven-core/src/site/apt/inheritance.apt
new file mode 100644
index 00000000..dbf0e2c2
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/site/apt/inheritance.apt
@@ -0,0 +1,100 @@
+~~ Licensed to the Apache Software Foundation (ASF) under one
+~~ or more contributor license agreements. See the NOTICE file
+~~ distributed with this work for additional information
+~~ regarding copyright ownership. The ASF licenses this file
+~~ to you under the Apache License, Version 2.0 (the
+~~ "License"); you may not use this file except in compliance
+~~ with the License. You may obtain a copy of the License at
+~~
+~~ http://www.apache.org/licenses/LICENSE-2.0
+~~
+~~ Unless required by applicable law or agreed to in writing,
+~~ software distributed under the License is distributed on an
+~~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+~~ KIND, either express or implied. See the License for the
+~~ specific language governing permissions and limitations
+~~ under the License.
+
+ -----
+ Inheritance in Maven
+ -----
+ The Maven Team
+ -----
+
+Inheritance in Maven
+
+ In order the understand how inheritance works in Maven there are a few notions that you must be familiar with:
+
+ * The maven super model
+
+ * how parent poms are processed
+
+ * the order in which elements in the POM are overridden
+
+ * minimum element-set for a valid project pom
+
+
+Maven super model
+
+ Inheritance is recursive in Maven but there is a special model which is the implicit super parent in the lineage
+ of models you may specify:
+
+ all of the models that you specify are collected to produce a lineage and then the super model is place at
+ the top of that lineage to provide default values.
+
+ The super model is where we place all the values which we believe to be standard, values that can be shared and
+ utilized across all your maven projects.
+
++-----+
+ m0 <- m1 <- m2
++-----+
+
+ which is transformed into
+
++-----+
+ super model <- m0 <- m1 <- m2
++-----+
+
++-----+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId></groupId>
+ <artifactId></artifactId>
+ <version></version>
+ </parent>
+</project>
++-----+
+
+Extending the POM in the future
+
+ In order to anticipate changes in the structure of the POM as new releases of
+ maven occur, the maven inheritance model must be pinned against a particular
+ modelVersion. This is required so that a change from modelVersion 4.0.0 to
+ 4.1.0 doesn't cause compatibility problems with users who have not upgraded
+ their projects. It also allows for a certain amount of legacy support into the
+ future. Therefore, we should rename this file from pom.xml in the maven-core
+ jarfile to pom-4.0.0.xml (and successive revisions to the base pom made to
+ accommodate changes in the model will be named accordingly - 4.0.1, 4.0.2, ...).
+
+Minimum Element-Set for a Project POM
+
+ In order to furnish a basic set of information which we need to distinguish one
+ project from another, maven requires a minimum set of elements to be specified
+ in each project's pom.xml.
+
+ - [modelVersion] tells maven which version of the object model this project
+ is compliant with (to support future legacy concerns)
+
+ - [artifactId] tells maven what the artifact name is for this particular
+ project. Each project should have a distinct artifactId.
+
+ - [version] tells maven what release of this artifact we're trying to produce.
+ The fact that a project has a distinct pom.xml should indicate a separate
+ release cycle that is also distinct to that project, so a concrete version
+ declaration is required.
+
+ - [name] tells maven what the user-friendly name of this project is. The name
+ element is similar to artifactId in that it is a unique descriptor for
+ this and only this project, and therefore should be concretely defined.
+
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/site/apt/lifecycles.apt.vm b/framework/src/maven/apache-maven-3.3.3/maven-core/src/site/apt/lifecycles.apt.vm
new file mode 100644
index 00000000..3e47bc90
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/site/apt/lifecycles.apt.vm
@@ -0,0 +1,49 @@
+~~ Licensed to the Apache Software Foundation (ASF) under one
+~~ or more contributor license agreements. See the NOTICE file
+~~ distributed with this work for additional information
+~~ regarding copyright ownership. The ASF licenses this file
+~~ to you under the Apache License, Version 2.0 (the
+~~ "License"); you may not use this file except in compliance
+~~ with the License. You may obtain a copy of the License at
+~~
+~~ http://www.apache.org/licenses/LICENSE-2.0
+~~
+~~ Unless required by applicable law or agreed to in writing,
+~~ software distributed under the License is distributed on an
+~~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+~~ KIND, either express or implied. See the License for the
+~~ specific language governing permissions and limitations
+~~ under the License.
+
+ -----
+ Lifecycles Reference
+ -----
+ Hervé Boutemy
+ -----
+ 2013-08-02
+ -----
+
+Lifecycles Reference
+
+ Maven defines 3 lifecycles in <<<META-INF/plexus/components.xml>>>:
+
+%{toc|fromDepth=2}
+
+* <<<default>>> Lifecycle
+
+ <<<default>>> lifecycle is defined <<without>> any associated plugin.
+ Plugin bindings for this lifecycle are {{{./default-bindings.html}defined separately for every packaging}}:
+
+%{snippet|id=lifecycle|file=${project.basedir}/src/main/resources/META-INF/plexus/components.xml}
+
+* <<<clean>>> Lifecycle
+
+ <<<clean>>> lifecycle is defined directly with its plugin bindings.
+
+%{snippet|id=clean|file=${project.basedir}/src/main/resources/META-INF/plexus/components.xml}
+
+* <<<site>>> Lifecycle
+
+ <<<site>>> lifecycle is defined directly with its plugin bindings.
+
+%{snippet|id=site|file=${project.basedir}/src/main/resources/META-INF/plexus/components.xml}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/site/apt/offline-mode.apt b/framework/src/maven/apache-maven-3.3.3/maven-core/src/site/apt/offline-mode.apt
new file mode 100644
index 00000000..faec70fa
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/site/apt/offline-mode.apt
@@ -0,0 +1,269 @@
+~~ Licensed to the Apache Software Foundation (ASF) under one
+~~ or more contributor license agreements. See the NOTICE file
+~~ distributed with this work for additional information
+~~ regarding copyright ownership. The ASF licenses this file
+~~ to you under the Apache License, Version 2.0 (the
+~~ "License"); you may not use this file except in compliance
+~~ with the License. You may obtain a copy of the License at
+~~
+~~ http://www.apache.org/licenses/LICENSE-2.0
+~~
+~~ Unless required by applicable law or agreed to in writing,
+~~ software distributed under the License is distributed on an
+~~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+~~ KIND, either express or implied. See the License for the
+~~ specific language governing permissions and limitations
+~~ under the License.
+
+ ---
+ Offline Mode Design
+ ---
+ John Casey
+ ---
+ 08-April-2005
+ ---
+
+Offline Mode Design
+
+* UPDATE: 18-April-2005
+
+ We cannot take the approach outlined below of detecting which remote
+ repositories are "really" offline, since offline mode is more of a behavior,
+ and this will lead to counter-intuitive results. A different feature may exist
+ unimplemented, which is to detect when the network is down and provide better
+ feedback for that case. However, when offline mode is declared, nothing
+ earmarked as remote should be accessed, regardless of whether it is actually
+ a physically local resource.
+
+ NOTE: One side-effect of this design change is that all offline-mode code can
+ be isolated to maven-core, maven-plugin-descriptor, and [possibly]
+ maven-artifact. Usage of maven-wagon will be determined by an offline-aware
+ manager.
+
+* Assumptions: What is Offline?
+
+ For the purposes of determining the areas sensitive to offline status,
+ it is definitely useful to define what the offline state really means.
+
+ [[1]] This is obvious, but the network/internet is unavailable.
+
+ [[2]] Localhost (127.0.0.1) may also be unavailable if the whole
+ network stack is offline.
+
+ [[3]] "Remote" repositories referenced using the file:// protocol may
+ be available. However, if that file:// url references a
+ file-share, as in the case of an NFS or SMB mount, that will
+ be unavailable.
+
+ So, offline mode has several implications, some of which may not be
+ altogether obvious:
+
+ * Localhost may be unavailable. Therefore, even locally installed
+ server processes which work by conversing over a port may fail.
+
+ * Not all "remote" repositories will fail. Specifically, if the remote
+ repo uses the file:// protocol, and it doesn't refer to a shared
+ filesystem, it will continue to be available.
+
+ The question remaining is: Which level of offline mode will we support? It
+ seems reasonable to assume that users will be able to tell when localhost is
+ not active (in most cases, localhost should be available, even if the rest of
+ the network is not). Therefore, let's concentrate on the state where no
+ network <beyond localhost> exists, and leave the more extreme state to users
+ to diagnose and correct as necessary.
+
+* Why is Offline Mode Important?
+
+ Offline mode is essential for breaking the requirement that m2 operate in a
+ network-connected environment. It means legitimizing a development environment
+ in which there is no network connection, and providing a robust m2 service
+ offering in such circumstances. Introduction of offline mode allows m2 to
+ anticipate the inevitable network failures that accompany being physically
+ disconnected from the network, and adjust it's behavior accordingly.
+
+ It is more than simply understanding that m2 cannot go and check for the
+ latest version of some snapshot artifact. If m2 is offline, SCM operations
+ cannot succeed; no artifact downloads can take place, regardless of whether
+ they are snapshot versions; artifact deployment cannot take place; certain
+ types of tests cannot be setup, since the container used to run them cannot be
+ reached or started.
+
+ All of these operations will produce their own unique errors in the absence of
+ a coordinated offline strategy. In addition, efforts to unite these failing
+ behaviors behind a consistent user interface is much, much more difficult if
+ the system can't tell whether it has access to the network required by these
+ operations.
+
+ Offline mode really means anticipating a lack of network connectivity, and as
+ a result turning off certain services provided by m2 and providing a coherent
+ way of predicting and reporting when network-related failures will take place.
+ It means warning users that since the network is missing, certain features and
+ operations will be unavailable, rather than simply waiting for those
+ operations to fail, then trying to help users decipher the error messages they
+ get as a result.
+
+* Implications for Resolution
+
+** Dependency Resolution
+
+ This one is obvious...we only have access to the repositories using
+ the file:// protocol and living on a truly local filesystem when
+ offline.
+
+** Plugin Resolution
+
+ This is similar to dependency resolution. Plugin repositories not
+ using file:// or not residing on a local (not shared) filesystem will
+ be unavailable.
+
+
+* Implications for Mojo Execution
+
+** Deployment mojos
+
+ The concept of deployment is dependent on the availability of a some
+ remote repository. Just as above, if that repository is not using
+ file:// (which is highly likely to be the case), or the repository is
+ not on a local filesystem, deployment will fail when offline.
+
+** Testing mojos
+
+ This can be a problem if the tests are more than simple unit tests;
+ that is, if they require configuration of a server process, and
+ subsequent testing in-container.
+
+ Since we're only going to concern ourselves with states where localhost is
+ still active, we only need to worry about this case when the server container
+ is <<not>> installed on localhost. This allows the popular pattern of starting
+ a server container in-JVM, running tests against it, and shutting it down.
+
+** SCM mojos
+
+ See below for discussion on SCM-related operations. Any mojo which
+ carries out some analysis or other interaction with a SCM system
+ will likely be unavailable when in offline mode.
+
+
+* Implications for Subsystems
+
+** Maven-Wagon
+
+ Parts of Wagon will continue to function normally. These include:
+
+ * The file wagon, provided the referenced location is on a local
+ filesystem.
+
+ It is not possible to determine whether a file-based location will
+ be available except on a case-by-case basis (or a root-url by
+ root-url basis). We may want to move the offline sensitivity entirely to
+ Maven-Artifact, below, so we can be smarter about testing filesystem-based
+ repositories, etc.
+
+ * If not otherwise specified, all other wagons are assumed to be
+ remote-only, and are therefore sensitive to offline mode.
+
+** Maven-Artifact
+
+ This is wholly dependent on Maven-Wagon, above.
+
+ We could possibly use a flag on a particular Wagon to see whether it supports
+ offline mode, and then test to see if the file-based basedir for an aritfact
+ repository works...if it doesn't work, we can mark that repository offline...
+
+ OTOH, all offline-mode checks can probably be run from Wagon-based APIs.
+
+** Maven-SCM
+
+ In all but trivial examples, SCM operations cannot complete without
+ having access to the versioning server. Therefore, it is assumed that
+ any SCM-related activity will be unavailable when m2 is in offline
+ mode.
+
+** Maven-Core
+
+ We'll examine the different parts of maven-core on a case-by-case
+ basis, below:
+
+*** DefaultLifecycleExecutor
+
+ When binding goals to the project's configured lifecycle, each mojo
+ descriptor should declare whether it requires online/offline status.
+ This value should be a java.lang.Boolean, so it can implement 3VL
+ (three value logic: yes, no, don't-care). The requiresOnline
+ field in the mojo descriptor has the following semantics:
+
+ [true] Online status is required for this mojo to function
+ correctly.
+
+ [false] <<(Default)>> Either status is acceptable for the mojo to
+ execute. It doesn't care.
+
+ The majority of mojos will leave the requiresOnline == false,
+ since online/offline status will be irrelevant, provided they have
+ access to their required artifacts and other classpath elements. In the case
+ of required artifacts and other classpath elemtents, this is assumed by the
+ mojo API to be in a correct state, and will be handled by the Wagon
+ modifications.
+
+
+* Implementation Notes
+
+** Accessibility of offline status
+
+ Offline status should be indicated in the MavenSettings instance, since it
+ can conceivably be set from either the settings.xml or the command-line.
+
+ In the event the '-o' switch is the impetus for setting offline mode, this
+ should result in modification of the active profile in the MavenSettings
+ instance, just as definition of the active profile from the command-line
+ should result in similar modification. This object is not meant to be
+ static within the build process, but rather to be setup as an aggregation of
+ all settings-related information passed into the system.
+
+** Control over downloads
+
+ Find the control point for m2 using maven-wagon. At this point, inject
+ a offline status parameter which is used when retrieving the specific Wagon.
+
+ If <<<offline == true>>>:
+
+ * If the wagon is not bound to "file://", then ignore the request and print
+ a debug message.
+
+ * If the wagon is bound to "file://" then:
+
+ Retrieve the file or base-url file to be "downloaded".
+
+ * If the file (or more usefully, the base-url file) exists, proceed.
+
+ * If the file (or base-url file) doesn't exist, assume that this location
+ is part of a file-share. Ignore the request and print a debug message
+ as above.
+
+** Control over mojos in the lifecycle
+
+ When binding a mojo to the project's lifecycle instance, check the mojo
+ descriptor's requiredConnectivity field.
+
+ * If <<<(offline == true) && (requiresOnline != true)>>>, bind
+ the mojo to the lifecycle.
+
+ In this case, the client is <<offline>>, and the mojo does not require
+ online status.
+
+ * If <<<(offline == false) && (requiresOnline == true)>>>, bind
+ the mojo to the lifecycle.
+
+ In this case, the client is <<online>>, and the mojo either requires
+ <<online>> status, or else doesn't care.
+
+ * Otherwise, don't bind the mojo. Log a debug message to indicate that it is
+ sensitive the the online state of the application, and that this state is
+ currently wrong for execution.
+
+ <<NOTE:>> Do we want to fail when we cannot bind a mojo to the lifecycle
+ because of offline/online status? That would probably indicate that the user
+ was trying to do something they cannot succeed at for now...so we probably
+ should throw an exception in this case.
+
+
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/site/apt/plugin-execution-isolation.apt b/framework/src/maven/apache-maven-3.3.3/maven-core/src/site/apt/plugin-execution-isolation.apt
new file mode 100644
index 00000000..983a9fde
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/site/apt/plugin-execution-isolation.apt
@@ -0,0 +1,57 @@
+~~ Licensed to the Apache Software Foundation (ASF) under one
+~~ or more contributor license agreements. See the NOTICE file
+~~ distributed with this work for additional information
+~~ regarding copyright ownership. The ASF licenses this file
+~~ to you under the Apache License, Version 2.0 (the
+~~ "License"); you may not use this file except in compliance
+~~ with the License. You may obtain a copy of the License at
+~~
+~~ http://www.apache.org/licenses/LICENSE-2.0
+~~
+~~ Unless required by applicable law or agreed to in writing,
+~~ software distributed under the License is distributed on an
+~~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+~~ KIND, either express or implied. See the License for the
+~~ specific language governing permissions and limitations
+~~ under the License.
+
+ -----
+ Maven plugins
+ -----
+ The Maven Team
+ -----
+
+Maven plugin execution isolation
+
+ Maven2 takes advantage of Plexus' ability to execute a component using a
+ ClassWorlds ClassRealm that is populated with the JAR containing the
+ component in question and all of its dependencies. Using ClassWorlds
+ notation for realms we have the following:
+
++-----+
+ [plexus.core]
+ ^
+ |
+ [plexus.core.maven]
+ ^ ^
+ | |
+[plugin0] [plugin1]
++-----+
+
+ The <<<plexus.core>>> realm contains the resources required to run any
+ plexus application; The <<<plexus.core.maven>>> realm contains all of the
+ resources required to run Maven. Each subseqent plugin realm contains the
+ JAR plugin as well as its dependencies. The realms noted above are setup
+ in a hierachical structure where the resources in the parent realms are
+ available but the <<realm is searched first before a search is made in
+ the parent realm>>.
+
+ Plugins are guaranteed to be provided the resources found in
+ <<<plexus.core>>> and <<<plexus.core.maven>>> realms at run-time if required.
+ Plugins can state compile-time dependencies on any of the resources found in
+ the core realms listed above and these dependencies will be included in the
+ plugin descriptor that is generated but when running within Maven these
+ resources will be filtered out. In other words these resources will not
+ be added the realm created for the plugins execution as they are provided
+ in the parent realms.
+
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/site/apt/scripting-support/marmalade-support.apt b/framework/src/maven/apache-maven-3.3.3/maven-core/src/site/apt/scripting-support/marmalade-support.apt
new file mode 100644
index 00000000..7a809662
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/site/apt/scripting-support/marmalade-support.apt
@@ -0,0 +1,196 @@
+~~ Licensed to the Apache Software Foundation (ASF) under one
+~~ or more contributor license agreements. See the NOTICE file
+~~ distributed with this work for additional information
+~~ regarding copyright ownership. The ASF licenses this file
+~~ to you under the Apache License, Version 2.0 (the
+~~ "License"); you may not use this file except in compliance
+~~ with the License. You may obtain a copy of the License at
+~~
+~~ http://www.apache.org/licenses/LICENSE-2.0
+~~
+~~ Unless required by applicable law or agreed to in writing,
+~~ software distributed under the License is distributed on an
+~~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+~~ KIND, either express or implied. See the License for the
+~~ specific language governing permissions and limitations
+~~ under the License.
+
+ ---
+ Marmalade Mojo Support - Notes
+ ---
+ John Casey
+ ---
+ 07-Feb-2005
+ ---
+
+Marmalade Support
+
+*Abstract
+
+ This document will track the design and implementation issues involved in
+ adding support to m2 for marmalade-based mojos.
+
+*Design Notes
+
+ [[1]] <<Marmalade mojo descriptor specification.>>
+
+ As in all mojo specifications, it is ideal that the descriptor for
+ a marmalade-based mojo be inline with the source code. This centralizes
+ all maintenance related to a single mojo to a single point of maintenance.
+
+ The following is what I'm thinking as of now:
+
+ - a marmalade-based mojo should look something like:
+
++---+
+ <mojo xmlns="m2:mojo" xmlns:marmalade-control="marmalade:marmalade-control" marmalade-control:el="none">
+
+ <metadata>
+ <id>mmld</id>
+ <name>mmldCompile</name>
+ <lifecyclePhase>compile</lifecyclePhase>
+ <description>Used to compile marmalade scripts into java beans.</description>
+
+ <requiresDependencyResolution/>
+ <instantiationStrategy/>
+ <executionStrategy/>
+
+ <parameters>
+
+ <parameter>
+ <name>classpath</name>
+ <description>The compilation classpath</description>
+ <type>java.util.List</type>
+ <expression>#pom.artifacts</expression>
+
+ <required/>
+ <validator/>
+ <default/>
+
+ </parameter>
+
+ </parameters>
+
+ </metadata>
+
+ <execute>
+ <!-- Do some stuff. -->
+ </execute>
+
+ </mojo>
++---+
+[NOTE] All empty elements above signify optional elements, usage specification.
+
+ [[2]] <<Marmalade mojo packager.>>
+
+ The marmalade mojo packager will:
+
+ [[a]] Locate all *.mmld files within the scripts directory of the project.
+
+ The scripts directory should be tied to the script language within
+ the POM. Until we have multiple language support in the POM, we'll
+ use something like: <<<xpath(build/marmaladeSourceDirectory)>>>.
+
+ [[b]] For each script found:
+
+ [[i]] Execute the script with "gatherMetadata=true" in the context.
+
+ [[ii]] Retrieve the mojo descriptor from the resulting "metadata"
+ variable in the context.
+
+ [[iii]] Cache the mojo descriptor in aggregator for subsequent
+ output to plugin descriptor file.
+
+ [[c]] Copy all scripts to the target directory. Preserve relative paths.
+
+ [[d]] <<Process Disjoint:>> <Allow other mojo-descriptor collectors to
+ run, aggregating their descriptors in similar fashion to [b.iii]
+ above.>
+
+ [[e]] Use the project's dependencies and other info to form the plugin
+ descriptor's header (non-mojo-specific info).
+
+ [[f]] Use the PluginGenerator from maven-plugin-tools to generate a
+ META-INF/plexus/plugin.xml to the target directory.
+
+ [[g]] Continue with lifecycle.
+
+ This may include compilation of java helper classes, etc. and
+ plugin-artifact packaging, presumably via 'jar:jar' or similar.
+
+ [[3]] <<Marmalade mojo loader.>>
+
+ The marmalade mojo loader will:
+
+ [[a]] Retrieve the implementation spec (this is the path of the script,
+ relative to the root of the plugin filesystem...jar, etc.) to
+ $path.
+
+ [[b]] Use the context classloader to retrieve a reader to $path.
+
+ [[c]] Build the ScriptBuilder corresponding to the script.
+
+ [[d]] Create a new MarmaladeMojo instance which adapts the mojo calling
+ semantics to the creation/execution of a marmalade script.
+
+ Execution involves:
+
+ [[i]] Creating a new MarmaladeScript instance.
+
+ [[ii]] Creating an execution context which references all I/O
+ from the main Maven execution thread, and embeds:
+
+ - #request == MavenExecutionRequest
+
+ - #response == MavenExecutionResponse
+
+ - Any globally configured environmental constraints, such
+ as a global preserve-whitespace setting
+
+ [[iii]] Execution of the script using the execution context.
+
+ [[iv]] Export of the resulting context, minus any surviving input
+ variables, to the MavenExecutionResponse's out-params.
+
+*Implementation Issues
+
+ [[1]] How do we make Maven smart enough to switch loader implementations based
+ on some sub-type of maven-plugin?
+
+ This is important, since the default mojo loader will not be smart
+ enough to do the job, and embedding this behavior in that loader is not
+ scalable or extensible enough to accommodate future expansion into the
+ realms of jython, groovy, etc...
+
+ <<UPDATE:07-FEB-2005>>
+
+ We'll plan on using some sort of language specification in the mojo
+ descriptor to determine which mojo loader to use, then we'll populate
+ the PluginLoader/PluginManager with a map of known languages->loaders.
+
+ [[2]] How do we make the plugin:install process smart enough to switch
+ generator implementations based on some sub-type of maven-plugin?
+
+ This is closely related to [1] above.
+
+ <<UPDATE:07-FEB-2005>>
+
+ See update in [3].
+
+ [[3]] Do we want to allow mixed-bag plugin implementations?
+
+ These might include a mix of standard-java and marmalade mojos. It
+ strikes me that many marmalade-based mojos may use beans/tags that are
+ actually adapter classes for other third-party APIs (why they wouldn't
+ implement everything as java mojos in this cases is beyond me). If they
+ have java source inside the plugin source directory, we should probably
+ compile it and bundle it with the plugin scripts; but what if this source
+ also has mojo annotations? This will have implications for [1] and [2]
+ above.
+
+ <<UPDATE:07-FEB-2005>>
+
+ We will plan on allowing this sort of implementation, and simply start
+ by applying all known generators which have a source directory set in
+ the POM (or later, have a <language/> section, maybe). At any rate,
+ helper classes will be allowed for script-based mojos.
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/site/resources/design/2.1-lifecycle-refactor-class-diagram.png b/framework/src/maven/apache-maven-3.3.3/maven-core/src/site/resources/design/2.1-lifecycle-refactor-class-diagram.png
new file mode 100755
index 00000000..37d666c3
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/site/resources/design/2.1-lifecycle-refactor-class-diagram.png
Binary files differ
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/site/resources/design/2.1-lifecycle-refactor-sequence-diagram.png b/framework/src/maven/apache-maven-3.3.3/maven-core/src/site/resources/design/2.1-lifecycle-refactor-sequence-diagram.png
new file mode 100755
index 00000000..30f19553
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/site/resources/design/2.1-lifecycle-refactor-sequence-diagram.png
Binary files differ
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/site/resources/design/2.1-lifecycle-refactor.graffle b/framework/src/maven/apache-maven-3.3.3/maven-core/src/site/resources/design/2.1-lifecycle-refactor.graffle
new file mode 100755
index 00000000..722bc031
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/site/resources/design/2.1-lifecycle-refactor.graffle
@@ -0,0 +1,4024 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CreationDate</key>
+ <string>2007-03-15 15:23:17 -0400</string>
+ <key>Creator</key>
+ <string>John.alt</string>
+ <key>GraphDocumentVersion</key>
+ <integer>5</integer>
+ <key>GuidesLocked</key>
+ <string>NO</string>
+ <key>GuidesVisible</key>
+ <string>YES</string>
+ <key>ImageCounter</key>
+ <integer>1</integer>
+ <key>LinksVisible</key>
+ <string>NO</string>
+ <key>MagnetsVisible</key>
+ <string>NO</string>
+ <key>MasterSheets</key>
+ <array>
+ <dict>
+ <key>ActiveLayerIndex</key>
+ <integer>0</integer>
+ <key>AutoAdjust</key>
+ <true/>
+ <key>CanvasColor</key>
+ <dict>
+ <key>w</key>
+ <string>1</string>
+ </dict>
+ <key>CanvasOrigin</key>
+ <string>{0, 0}</string>
+ <key>CanvasScale</key>
+ <real>1</real>
+ <key>ColumnAlign</key>
+ <integer>1</integer>
+ <key>ColumnSpacing</key>
+ <real>36</real>
+ <key>DisplayScale</key>
+ <string>1 in = 1 in</string>
+ <key>GraphicsList</key>
+ <array/>
+ <key>GridInfo</key>
+ <dict/>
+ <key>HPages</key>
+ <integer>1</integer>
+ <key>IsPalette</key>
+ <string>NO</string>
+ <key>KeepToScale</key>
+ <false/>
+ <key>Layers</key>
+ <array>
+ <dict>
+ <key>Lock</key>
+ <string>NO</string>
+ <key>Name</key>
+ <string>Layer 1</string>
+ <key>Print</key>
+ <string>YES</string>
+ <key>View</key>
+ <string>YES</string>
+ </dict>
+ </array>
+ <key>LayoutInfo</key>
+ <dict/>
+ <key>Orientation</key>
+ <integer>2</integer>
+ <key>OutlineStyle</key>
+ <string>Basic</string>
+ <key>RowAlign</key>
+ <integer>1</integer>
+ <key>RowSpacing</key>
+ <real>36</real>
+ <key>SheetTitle</key>
+ <string>Master 1</string>
+ <key>UniqueID</key>
+ <integer>1</integer>
+ <key>VPages</key>
+ <integer>1</integer>
+ </dict>
+ </array>
+ <key>ModificationDate</key>
+ <string>2007-03-15 16:57:24 -0400</string>
+ <key>Modifier</key>
+ <string>John.alt</string>
+ <key>NotesVisible</key>
+ <string>NO</string>
+ <key>OriginVisible</key>
+ <string>NO</string>
+ <key>PageBreaks</key>
+ <string>YES</string>
+ <key>PrintInfo</key>
+ <dict>
+ <key>NSBottomMargin</key>
+ <array>
+ <string>float</string>
+ <string>0</string>
+ </array>
+ <key>NSLeftMargin</key>
+ <array>
+ <string>float</string>
+ <string>0</string>
+ </array>
+ <key>NSOrientation</key>
+ <array>
+ <string>int</string>
+ <string>1</string>
+ </array>
+ <key>NSPaperSize</key>
+ <array>
+ <string>size</string>
+ <string>{792, 612}</string>
+ </array>
+ <key>NSRightMargin</key>
+ <array>
+ <string>float</string>
+ <string>0</string>
+ </array>
+ <key>NSTopMargin</key>
+ <array>
+ <string>float</string>
+ <string>0</string>
+ </array>
+ </dict>
+ <key>ReadOnly</key>
+ <string>NO</string>
+ <key>Sheets</key>
+ <array>
+ <dict>
+ <key>ActiveLayerIndex</key>
+ <integer>0</integer>
+ <key>AutoAdjust</key>
+ <true/>
+ <key>CanvasColor</key>
+ <dict>
+ <key>w</key>
+ <string>1</string>
+ </dict>
+ <key>CanvasOrigin</key>
+ <string>{0, 0}</string>
+ <key>CanvasScale</key>
+ <real>1</real>
+ <key>ColumnAlign</key>
+ <integer>1</integer>
+ <key>ColumnSpacing</key>
+ <real>36</real>
+ <key>DisplayScale</key>
+ <string>1 in = 1 in</string>
+ <key>GraphicsList</key>
+ <array>
+ <dict>
+ <key>Bounds</key>
+ <string>{{607.473, 151.036}, {112, 28}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FitText</key>
+ <string>YES</string>
+ <key>FontInfo</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>w</key>
+ <string>0</string>
+ </dict>
+ <key>Font</key>
+ <string>Helvetica</string>
+ <key>Size</key>
+ <real>12</real>
+ </dict>
+ <key>ID</key>
+ <integer>86</integer>
+ <key>Line</key>
+ <dict>
+ <key>ID</key>
+ <integer>72</integer>
+ <key>Position</key>
+ <real>0.31921392679214478</real>
+ <key>RotationType</key>
+ <integer>0</integer>
+ </dict>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Style</key>
+ <dict>
+ <key>shadow</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Text</key>
+ <string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf410
+{\fonttbl\f0\fswiss\fcharset77 Helvetica-Oblique;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\i\fs24 \cf0 deprecated,\
+marked for refactor}</string>
+ </dict>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{584.742, 252.673}, {104, 28}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FitText</key>
+ <string>YES</string>
+ <key>FontInfo</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>w</key>
+ <string>0</string>
+ </dict>
+ <key>Font</key>
+ <string>Helvetica</string>
+ <key>Size</key>
+ <real>12</real>
+ </dict>
+ <key>ID</key>
+ <integer>85</integer>
+ <key>Line</key>
+ <dict>
+ <key>ID</key>
+ <integer>84</integer>
+ <key>Position</key>
+ <real>0.45520344376564026</real>
+ <key>RotationType</key>
+ <integer>0</integer>
+ </dict>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Style</key>
+ <dict>
+ <key>shadow</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Text</key>
+ <string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf410
+{\fonttbl\f0\fswiss\fcharset77 Helvetica-Oblique;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\i\fs24 \cf0 if binding spec \
+uses plugin prefix}</string>
+ </dict>
+ </dict>
+ <dict>
+ <key>Class</key>
+ <string>LineGraphic</string>
+ <key>Head</key>
+ <dict>
+ <key>ID</key>
+ <integer>39</integer>
+ </dict>
+ <key>ID</key>
+ <integer>84</integer>
+ <key>Points</key>
+ <array>
+ <string>{623.954, 304}</string>
+ <string>{652.046, 222}</string>
+ </array>
+ <key>Style</key>
+ <dict>
+ <key>stroke</key>
+ <dict>
+ <key>HeadArrow</key>
+ <string>FilledArrow</string>
+ <key>HopLines</key>
+ <true/>
+ <key>HopType</key>
+ <integer>1</integer>
+ <key>Pattern</key>
+ <integer>1</integer>
+ <key>TailArrow</key>
+ <string>0</string>
+ </dict>
+ </dict>
+ <key>Tail</key>
+ <dict>
+ <key>ID</key>
+ <integer>51</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>Class</key>
+ <string>LineGraphic</string>
+ <key>Head</key>
+ <dict>
+ <key>ID</key>
+ <integer>51</integer>
+ </dict>
+ <key>ID</key>
+ <integer>83</integer>
+ <key>Points</key>
+ <array>
+ <string>{488, 317}</string>
+ <string>{555, 317}</string>
+ </array>
+ <key>Style</key>
+ <dict>
+ <key>stroke</key>
+ <dict>
+ <key>HeadArrow</key>
+ <string>FilledArrow</string>
+ <key>HopLines</key>
+ <true/>
+ <key>HopType</key>
+ <integer>1</integer>
+ <key>TailArrow</key>
+ <string>0</string>
+ </dict>
+ </dict>
+ <key>Tail</key>
+ <dict>
+ <key>ID</key>
+ <integer>48</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>Class</key>
+ <string>LineGraphic</string>
+ <key>Head</key>
+ <dict>
+ <key>ID</key>
+ <integer>54</integer>
+ </dict>
+ <key>ID</key>
+ <integer>82</integer>
+ <key>Points</key>
+ <array>
+ <string>{453.532, 330}</string>
+ <string>{575.468, 366}</string>
+ </array>
+ <key>Style</key>
+ <dict>
+ <key>stroke</key>
+ <dict>
+ <key>HeadArrow</key>
+ <string>FilledArrow</string>
+ <key>HopLines</key>
+ <true/>
+ <key>HopType</key>
+ <integer>1</integer>
+ <key>TailArrow</key>
+ <string>0</string>
+ </dict>
+ </dict>
+ <key>Tail</key>
+ <dict>
+ <key>ID</key>
+ <integer>48</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>Class</key>
+ <string>LineGraphic</string>
+ <key>Head</key>
+ <dict>
+ <key>ID</key>
+ <integer>42</integer>
+ </dict>
+ <key>ID</key>
+ <integer>81</integer>
+ <key>Points</key>
+ <array>
+ <string>{83.5916, 196}</string>
+ <string>{84, 138}</string>
+ <string>{256, 138}</string>
+ <string>{466, 138}</string>
+ <string>{656, 138}</string>
+ <string>{671.008, 99}</string>
+ </array>
+ <key>Style</key>
+ <dict>
+ <key>stroke</key>
+ <dict>
+ <key>HeadArrow</key>
+ <string>FilledArrow</string>
+ <key>HopLines</key>
+ <true/>
+ <key>HopType</key>
+ <integer>1</integer>
+ <key>TailArrow</key>
+ <string>0</string>
+ </dict>
+ </dict>
+ <key>Tail</key>
+ <dict>
+ <key>ID</key>
+ <integer>33</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>Class</key>
+ <string>LineGraphic</string>
+ <key>Head</key>
+ <dict>
+ <key>ID</key>
+ <integer>39</integer>
+ </dict>
+ <key>ID</key>
+ <integer>80</integer>
+ <key>Points</key>
+ <array>
+ <string>{83.6857, 196}</string>
+ <string>{84, 174}</string>
+ <string>{256, 174}</string>
+ <string>{466, 174}</string>
+ <string>{598, 198.252}</string>
+ </array>
+ <key>Style</key>
+ <dict>
+ <key>stroke</key>
+ <dict>
+ <key>HeadArrow</key>
+ <string>FilledArrow</string>
+ <key>HopLines</key>
+ <true/>
+ <key>HopType</key>
+ <integer>1</integer>
+ <key>TailArrow</key>
+ <string>0</string>
+ </dict>
+ </dict>
+ <key>Tail</key>
+ <dict>
+ <key>ID</key>
+ <integer>33</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>Class</key>
+ <string>LineGraphic</string>
+ <key>Head</key>
+ <dict>
+ <key>ID</key>
+ <integer>45</integer>
+ </dict>
+ <key>ID</key>
+ <integer>66</integer>
+ <key>Points</key>
+ <array>
+ <string>{142, 221.044}</string>
+ <string>{195, 231.956}</string>
+ </array>
+ <key>Style</key>
+ <dict>
+ <key>stroke</key>
+ <dict>
+ <key>HeadArrow</key>
+ <string>FilledArrow</string>
+ <key>HopLines</key>
+ <true/>
+ <key>HopType</key>
+ <integer>1</integer>
+ <key>TailArrow</key>
+ <string>0</string>
+ </dict>
+ </dict>
+ <key>Tail</key>
+ <dict>
+ <key>ID</key>
+ <integer>33</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>Class</key>
+ <string>LineGraphic</string>
+ <key>Head</key>
+ <dict>
+ <key>ID</key>
+ <integer>48</integer>
+ </dict>
+ <key>ID</key>
+ <integer>79</integer>
+ <key>Points</key>
+ <array>
+ <string>{106.976, 222}</string>
+ <string>{237, 294}</string>
+ <string>{331, 306.533}</string>
+ </array>
+ <key>Style</key>
+ <dict>
+ <key>stroke</key>
+ <dict>
+ <key>HeadArrow</key>
+ <string>FilledArrow</string>
+ <key>HopLines</key>
+ <true/>
+ <key>HopType</key>
+ <integer>1</integer>
+ <key>TailArrow</key>
+ <string>0</string>
+ </dict>
+ </dict>
+ <key>Tail</key>
+ <dict>
+ <key>ID</key>
+ <integer>33</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>Class</key>
+ <string>LineGraphic</string>
+ <key>Head</key>
+ <dict>
+ <key>ID</key>
+ <integer>39</integer>
+ </dict>
+ <key>ID</key>
+ <integer>78</integer>
+ <key>Points</key>
+ <array>
+ <string>{419.845, 304}</string>
+ <string>{466, 246}</string>
+ <string>{598, 220.362}</string>
+ </array>
+ <key>Style</key>
+ <dict>
+ <key>stroke</key>
+ <dict>
+ <key>HeadArrow</key>
+ <string>FilledArrow</string>
+ <key>HopLines</key>
+ <true/>
+ <key>HopType</key>
+ <integer>1</integer>
+ <key>TailArrow</key>
+ <string>0</string>
+ </dict>
+ </dict>
+ <key>Tail</key>
+ <dict>
+ <key>ID</key>
+ <integer>48</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>Class</key>
+ <string>LineGraphic</string>
+ <key>Head</key>
+ <dict>
+ <key>ID</key>
+ <integer>39</integer>
+ </dict>
+ <key>ID</key>
+ <integer>77</integer>
+ <key>Points</key>
+ <array>
+ <string>{254.456, 231}</string>
+ <string>{256, 210}</string>
+ <string>{466, 210}</string>
+ <string>{598, 209.307}</string>
+ </array>
+ <key>Style</key>
+ <dict>
+ <key>stroke</key>
+ <dict>
+ <key>HeadArrow</key>
+ <string>FilledArrow</string>
+ <key>HopLines</key>
+ <true/>
+ <key>HopType</key>
+ <integer>1</integer>
+ <key>TailArrow</key>
+ <string>0</string>
+ </dict>
+ </dict>
+ <key>Tail</key>
+ <dict>
+ <key>ID</key>
+ <integer>45</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>Class</key>
+ <string>LineGraphic</string>
+ <key>Head</key>
+ <dict>
+ <key>ID</key>
+ <integer>42</integer>
+ </dict>
+ <key>ID</key>
+ <integer>72</integer>
+ <key>Points</key>
+ <array>
+ <string>{658.562, 196}</string>
+ <string>{673.948, 99}</string>
+ </array>
+ <key>Style</key>
+ <dict>
+ <key>stroke</key>
+ <dict>
+ <key>HeadArrow</key>
+ <string>FilledArrow</string>
+ <key>LineType</key>
+ <integer>1</integer>
+ <key>Pattern</key>
+ <integer>1</integer>
+ <key>TailArrow</key>
+ <string>0</string>
+ </dict>
+ </dict>
+ <key>Tail</key>
+ <dict>
+ <key>ID</key>
+ <integer>39</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>Class</key>
+ <string>LineGraphic</string>
+ <key>Head</key>
+ <dict>
+ <key>ID</key>
+ <integer>48</integer>
+ </dict>
+ <key>ID</key>
+ <integer>71</integer>
+ <key>Points</key>
+ <array>
+ <string>{281.281, 257}</string>
+ <string>{381.719, 304}</string>
+ </array>
+ <key>Style</key>
+ <dict>
+ <key>stroke</key>
+ <dict>
+ <key>HeadArrow</key>
+ <string>FilledArrow</string>
+ <key>LineType</key>
+ <integer>1</integer>
+ <key>TailArrow</key>
+ <string>0</string>
+ </dict>
+ </dict>
+ <key>Tail</key>
+ <dict>
+ <key>ID</key>
+ <integer>45</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>Class</key>
+ <string>TableGroup</string>
+ <key>Graphics</key>
+ <array>
+ <dict>
+ <key>Bounds</key>
+ <string>{{524, 366}, {191, 14}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FitText</key>
+ <string>Vertical</string>
+ <key>Flow</key>
+ <string>Resize</string>
+ <key>ID</key>
+ <integer>55</integer>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Style</key>
+ <dict>
+ <key>fill</key>
+ <dict>
+ <key>GradientAngle</key>
+ <real>304</real>
+ <key>GradientCenter</key>
+ <string>{-0.294118, -0.264706}</string>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Text</key>
+ <string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf410
+{\fonttbl\f0\fswiss\fcharset77 Helvetica-Bold;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc
+
+\f0\b\fs24 \cf0 LegacyLifecycleMappingParser}</string>
+ </dict>
+ <key>TextPlacement</key>
+ <integer>0</integer>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{524, 380}, {191, 12}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FitText</key>
+ <string>Vertical</string>
+ <key>Flow</key>
+ <string>Resize</string>
+ <key>ID</key>
+ <integer>56</integer>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Style</key>
+ <dict>
+ <key>fill</key>
+ <dict>
+ <key>GradientAngle</key>
+ <real>304</real>
+ <key>GradientCenter</key>
+ <string>{-0.294118, -0.264706}</string>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Align</key>
+ <integer>0</integer>
+ </dict>
+ <key>TextPlacement</key>
+ <integer>0</integer>
+ </dict>
+ </array>
+ <key>GridH</key>
+ <array>
+ <integer>55</integer>
+ <integer>56</integer>
+ <array/>
+ </array>
+ <key>GroupConnect</key>
+ <string>YES</string>
+ <key>ID</key>
+ <integer>54</integer>
+ </dict>
+ <dict>
+ <key>Class</key>
+ <string>TableGroup</string>
+ <key>Graphics</key>
+ <array>
+ <dict>
+ <key>Bounds</key>
+ <string>{{555, 304}, {129, 14}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FitText</key>
+ <string>Vertical</string>
+ <key>Flow</key>
+ <string>Resize</string>
+ <key>ID</key>
+ <integer>52</integer>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Style</key>
+ <dict>
+ <key>fill</key>
+ <dict>
+ <key>GradientAngle</key>
+ <real>304</real>
+ <key>GradientCenter</key>
+ <string>{-0.294118, -0.264706}</string>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Text</key>
+ <string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf410
+{\fonttbl\f0\fswiss\fcharset77 Helvetica-Bold;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc
+
+\f0\b\fs24 \cf0 MojoBindingFactory}</string>
+ </dict>
+ <key>TextPlacement</key>
+ <integer>0</integer>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{555, 318}, {129, 12}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FitText</key>
+ <string>Vertical</string>
+ <key>Flow</key>
+ <string>Resize</string>
+ <key>ID</key>
+ <integer>53</integer>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Style</key>
+ <dict>
+ <key>fill</key>
+ <dict>
+ <key>GradientAngle</key>
+ <real>304</real>
+ <key>GradientCenter</key>
+ <string>{-0.294118, -0.264706}</string>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Align</key>
+ <integer>0</integer>
+ </dict>
+ <key>TextPlacement</key>
+ <integer>0</integer>
+ </dict>
+ </array>
+ <key>GridH</key>
+ <array>
+ <integer>52</integer>
+ <integer>53</integer>
+ <array/>
+ </array>
+ <key>GroupConnect</key>
+ <string>YES</string>
+ <key>ID</key>
+ <integer>51</integer>
+ </dict>
+ <dict>
+ <key>Class</key>
+ <string>TableGroup</string>
+ <key>Graphics</key>
+ <array>
+ <dict>
+ <key>Bounds</key>
+ <string>{{331, 304}, {157, 14}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FitText</key>
+ <string>Vertical</string>
+ <key>Flow</key>
+ <string>Resize</string>
+ <key>ID</key>
+ <integer>49</integer>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Style</key>
+ <dict>
+ <key>fill</key>
+ <dict>
+ <key>GradientAngle</key>
+ <real>304</real>
+ <key>GradientCenter</key>
+ <string>{-0.294118, -0.264706}</string>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Text</key>
+ <string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf410
+{\fonttbl\f0\fswiss\fcharset77 Helvetica-Bold;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc
+
+\f0\b\fs24 \cf0 LifecycleBindingManager}</string>
+ </dict>
+ <key>TextPlacement</key>
+ <integer>0</integer>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{331, 318}, {157, 12}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FitText</key>
+ <string>Vertical</string>
+ <key>Flow</key>
+ <string>Resize</string>
+ <key>ID</key>
+ <integer>50</integer>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Style</key>
+ <dict>
+ <key>fill</key>
+ <dict>
+ <key>GradientAngle</key>
+ <real>304</real>
+ <key>GradientCenter</key>
+ <string>{-0.294118, -0.264706}</string>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Align</key>
+ <integer>0</integer>
+ </dict>
+ <key>TextPlacement</key>
+ <integer>0</integer>
+ </dict>
+ </array>
+ <key>GridH</key>
+ <array>
+ <integer>49</integer>
+ <integer>50</integer>
+ <array/>
+ </array>
+ <key>GroupConnect</key>
+ <string>YES</string>
+ <key>ID</key>
+ <integer>48</integer>
+ </dict>
+ <dict>
+ <key>Class</key>
+ <string>TableGroup</string>
+ <key>Graphics</key>
+ <array>
+ <dict>
+ <key>Bounds</key>
+ <string>{{195, 231}, {117, 14}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FitText</key>
+ <string>Vertical</string>
+ <key>Flow</key>
+ <string>Resize</string>
+ <key>ID</key>
+ <integer>46</integer>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Style</key>
+ <dict>
+ <key>fill</key>
+ <dict>
+ <key>GradientAngle</key>
+ <real>304</real>
+ <key>GradientCenter</key>
+ <string>{-0.294118, -0.264706}</string>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Text</key>
+ <string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf410
+{\fonttbl\f0\fswiss\fcharset77 Helvetica-Bold;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc
+
+\f0\b\fs24 \cf0 BuildPlanner}</string>
+ </dict>
+ <key>TextPlacement</key>
+ <integer>0</integer>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{195, 245}, {117, 12}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FitText</key>
+ <string>Vertical</string>
+ <key>Flow</key>
+ <string>Resize</string>
+ <key>ID</key>
+ <integer>47</integer>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Style</key>
+ <dict>
+ <key>fill</key>
+ <dict>
+ <key>GradientAngle</key>
+ <real>304</real>
+ <key>GradientCenter</key>
+ <string>{-0.294118, -0.264706}</string>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Align</key>
+ <integer>0</integer>
+ </dict>
+ <key>TextPlacement</key>
+ <integer>0</integer>
+ </dict>
+ </array>
+ <key>GridH</key>
+ <array>
+ <integer>46</integer>
+ <integer>47</integer>
+ <array/>
+ </array>
+ <key>GroupConnect</key>
+ <string>YES</string>
+ <key>ID</key>
+ <integer>45</integer>
+ </dict>
+ <dict>
+ <key>Class</key>
+ <string>TableGroup</string>
+ <key>Graphics</key>
+ <array>
+ <dict>
+ <key>Bounds</key>
+ <string>{{617.51, 73}, {117, 14}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FitText</key>
+ <string>Vertical</string>
+ <key>Flow</key>
+ <string>Resize</string>
+ <key>ID</key>
+ <integer>43</integer>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Style</key>
+ <dict>
+ <key>fill</key>
+ <dict>
+ <key>GradientAngle</key>
+ <real>304</real>
+ <key>GradientCenter</key>
+ <string>{-0.294118, -0.264706}</string>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Text</key>
+ <string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf410
+{\fonttbl\f0\fswiss\fcharset77 Helvetica-Bold;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc
+
+\f0\b\fs24 \cf0 PluginManager}</string>
+ </dict>
+ <key>TextPlacement</key>
+ <integer>0</integer>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{617.51, 87}, {117, 12}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FitText</key>
+ <string>Vertical</string>
+ <key>Flow</key>
+ <string>Resize</string>
+ <key>ID</key>
+ <integer>44</integer>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Style</key>
+ <dict>
+ <key>fill</key>
+ <dict>
+ <key>GradientAngle</key>
+ <real>304</real>
+ <key>GradientCenter</key>
+ <string>{-0.294118, -0.264706}</string>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Align</key>
+ <integer>0</integer>
+ </dict>
+ <key>TextPlacement</key>
+ <integer>0</integer>
+ </dict>
+ </array>
+ <key>GridH</key>
+ <array>
+ <integer>43</integer>
+ <integer>44</integer>
+ <array/>
+ </array>
+ <key>GroupConnect</key>
+ <string>YES</string>
+ <key>ID</key>
+ <integer>42</integer>
+ </dict>
+ <dict>
+ <key>Class</key>
+ <string>TableGroup</string>
+ <key>Graphics</key>
+ <array>
+ <dict>
+ <key>Bounds</key>
+ <string>{{598, 196}, {117, 14}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FitText</key>
+ <string>Vertical</string>
+ <key>Flow</key>
+ <string>Resize</string>
+ <key>ID</key>
+ <integer>40</integer>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Style</key>
+ <dict>
+ <key>fill</key>
+ <dict>
+ <key>GradientAngle</key>
+ <real>304</real>
+ <key>GradientCenter</key>
+ <string>{-0.294118, -0.264706}</string>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Text</key>
+ <string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf410
+{\fonttbl\f0\fswiss\fcharset77 Helvetica-Bold;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc
+
+\f0\b\fs24 \cf0 PluginLoader}</string>
+ </dict>
+ <key>TextPlacement</key>
+ <integer>0</integer>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{598, 210}, {117, 12}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FitText</key>
+ <string>Vertical</string>
+ <key>Flow</key>
+ <string>Resize</string>
+ <key>ID</key>
+ <integer>41</integer>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Style</key>
+ <dict>
+ <key>fill</key>
+ <dict>
+ <key>GradientAngle</key>
+ <real>304</real>
+ <key>GradientCenter</key>
+ <string>{-0.294118, -0.264706}</string>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Align</key>
+ <integer>0</integer>
+ </dict>
+ <key>TextPlacement</key>
+ <integer>0</integer>
+ </dict>
+ </array>
+ <key>GridH</key>
+ <array>
+ <integer>40</integer>
+ <integer>41</integer>
+ <array/>
+ </array>
+ <key>GroupConnect</key>
+ <string>YES</string>
+ <key>ID</key>
+ <integer>39</integer>
+ </dict>
+ <dict>
+ <key>Class</key>
+ <string>TableGroup</string>
+ <key>Graphics</key>
+ <array>
+ <dict>
+ <key>Bounds</key>
+ <string>{{25, 196}, {117, 14}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FitText</key>
+ <string>Vertical</string>
+ <key>Flow</key>
+ <string>Resize</string>
+ <key>ID</key>
+ <integer>34</integer>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Style</key>
+ <dict>
+ <key>fill</key>
+ <dict>
+ <key>GradientAngle</key>
+ <real>304</real>
+ <key>GradientCenter</key>
+ <string>{-0.294118, -0.264706}</string>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Text</key>
+ <string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf410
+{\fonttbl\f0\fswiss\fcharset77 Helvetica-Bold;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc
+
+\f0\b\fs24 \cf0 LifecycleExecutor}</string>
+ </dict>
+ <key>TextPlacement</key>
+ <integer>0</integer>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{25, 210}, {117, 12}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FitText</key>
+ <string>Vertical</string>
+ <key>Flow</key>
+ <string>Resize</string>
+ <key>ID</key>
+ <integer>38</integer>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Style</key>
+ <dict>
+ <key>fill</key>
+ <dict>
+ <key>GradientAngle</key>
+ <real>304</real>
+ <key>GradientCenter</key>
+ <string>{-0.294118, -0.264706}</string>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Align</key>
+ <integer>0</integer>
+ </dict>
+ <key>TextPlacement</key>
+ <integer>0</integer>
+ </dict>
+ </array>
+ <key>GridH</key>
+ <array>
+ <integer>34</integer>
+ <integer>38</integer>
+ <array/>
+ </array>
+ <key>GroupConnect</key>
+ <string>YES</string>
+ <key>ID</key>
+ <integer>33</integer>
+ </dict>
+ </array>
+ <key>GridInfo</key>
+ <dict/>
+ <key>HPages</key>
+ <integer>1</integer>
+ <key>IsPalette</key>
+ <string>NO</string>
+ <key>KeepToScale</key>
+ <false/>
+ <key>Layers</key>
+ <array>
+ <dict>
+ <key>Lock</key>
+ <string>NO</string>
+ <key>Name</key>
+ <string>Layer 1</string>
+ <key>Print</key>
+ <string>YES</string>
+ <key>View</key>
+ <string>YES</string>
+ </dict>
+ </array>
+ <key>LayoutInfo</key>
+ <dict>
+ <key>ChildOrdering</key>
+ <integer>0</integer>
+ <key>HierarchicalOrientation</key>
+ <integer>0</integer>
+ </dict>
+ <key>MasterSheet</key>
+ <string>Master 1</string>
+ <key>Orientation</key>
+ <integer>2</integer>
+ <key>OutlineStyle</key>
+ <string>Basic</string>
+ <key>RowAlign</key>
+ <integer>1</integer>
+ <key>RowSpacing</key>
+ <real>36</real>
+ <key>SheetTitle</key>
+ <string>Canvas 1</string>
+ <key>UniqueID</key>
+ <integer>1</integer>
+ <key>VPages</key>
+ <integer>1</integer>
+ </dict>
+ <dict>
+ <key>ActiveLayerIndex</key>
+ <integer>0</integer>
+ <key>AutoAdjust</key>
+ <true/>
+ <key>CanvasColor</key>
+ <dict>
+ <key>w</key>
+ <string>1</string>
+ </dict>
+ <key>CanvasOrigin</key>
+ <string>{0, 0}</string>
+ <key>CanvasScale</key>
+ <real>1</real>
+ <key>ColumnAlign</key>
+ <integer>1</integer>
+ <key>ColumnSpacing</key>
+ <real>36</real>
+ <key>DisplayScale</key>
+ <string>1 in = 1 in</string>
+ <key>GraphicsList</key>
+ <array>
+ <dict>
+ <key>Bounds</key>
+ <string>{{521.5, 182.853}, {75, 14}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FitText</key>
+ <string>YES</string>
+ <key>Flow</key>
+ <string>Resize</string>
+ <key>FontInfo</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>w</key>
+ <string>0</string>
+ </dict>
+ <key>Font</key>
+ <string>Helvetica</string>
+ <key>Size</key>
+ <real>12</real>
+ </dict>
+ <key>ID</key>
+ <integer>126</integer>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Style</key>
+ <dict>
+ <key>shadow</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Text</key>
+ <string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf410
+{\fonttbl\f0\fswiss\fcharset77 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs24 \cf0 loadPlugin()}</string>
+ </dict>
+ <key>Wrap</key>
+ <string>NO</string>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{437, 221.123}, {92, 14}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FitText</key>
+ <string>YES</string>
+ <key>ID</key>
+ <integer>125</integer>
+ <key>Line</key>
+ <dict>
+ <key>ID</key>
+ <integer>124</integer>
+ <key>Offset</key>
+ <real>18.181819915771484</real>
+ <key>Position</key>
+ <real>0.55852556228637695</real>
+ <key>RotationType</key>
+ <integer>0</integer>
+ </dict>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Style</key>
+ <dict>
+ <key>shadow</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Align</key>
+ <integer>0</integer>
+ <key>Text</key>
+ <string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf410
+{\fonttbl\f0\fswiss\fcharset77 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural
+
+\f0\fs24 \cf0 binding, project}</string>
+ </dict>
+ </dict>
+ <dict>
+ <key>AllowLabelDrop</key>
+ <false/>
+ <key>Class</key>
+ <string>LineGraphic</string>
+ <key>Head</key>
+ <dict>
+ <key>ID</key>
+ <integer>123</integer>
+ </dict>
+ <key>ID</key>
+ <integer>124</integer>
+ <key>Points</key>
+ <array>
+ <string>{398, 209.12}</string>
+ <string>{550.5, 210.592}</string>
+ </array>
+ <key>Style</key>
+ <dict>
+ <key>stroke</key>
+ <dict>
+ <key>HeadArrow</key>
+ <string>FilledArrow</string>
+ <key>HeadScale</key>
+ <real>1.4285709857940674</real>
+ <key>TailArrow</key>
+ <string>StickArrow</string>
+ <key>TailScale</key>
+ <real>1.5</real>
+ </dict>
+ </dict>
+ <key>Tail</key>
+ <dict>
+ <key>ID</key>
+ <integer>79</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{550.5, 203.842}, {17, 27}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>HFlip</key>
+ <string>YES</string>
+ <key>ID</key>
+ <integer>123</integer>
+ <key>Magnets</key>
+ <array>
+ <string>{1, 0.5}</string>
+ <string>{1, -0.5}</string>
+ <string>{-1, 0.5}</string>
+ <string>{-1, -0.5}</string>
+ <string>{0.5, 1}</string>
+ <string>{-0.5, 1}</string>
+ <string>{0.5, -1}</string>
+ <string>{-0.5, -1}</string>
+ </array>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Text</key>
+ <dict>
+ <key>Align</key>
+ <integer>0</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{521.5, 114.705}, {75, 14}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FitText</key>
+ <string>YES</string>
+ <key>Flow</key>
+ <string>Resize</string>
+ <key>FontInfo</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>w</key>
+ <string>0</string>
+ </dict>
+ <key>Font</key>
+ <string>Helvetica</string>
+ <key>Size</key>
+ <real>12</real>
+ </dict>
+ <key>ID</key>
+ <integer>122</integer>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Style</key>
+ <dict>
+ <key>shadow</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Text</key>
+ <string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf410
+{\fonttbl\f0\fswiss\fcharset77 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs24 \cf0 loadPlugin()}</string>
+ </dict>
+ <key>Wrap</key>
+ <string>NO</string>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{436.814, 155.115}, {92, 14}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FitText</key>
+ <string>YES</string>
+ <key>ID</key>
+ <integer>121</integer>
+ <key>Line</key>
+ <dict>
+ <key>ID</key>
+ <integer>120</integer>
+ <key>Offset</key>
+ <real>18.181819915771484</real>
+ <key>Position</key>
+ <real>0.55852556228637695</real>
+ <key>RotationType</key>
+ <integer>0</integer>
+ </dict>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Style</key>
+ <dict>
+ <key>shadow</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Align</key>
+ <integer>0</integer>
+ <key>Text</key>
+ <string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf410
+{\fonttbl\f0\fswiss\fcharset77 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural
+
+\f0\fs24 \cf0 binding, project}</string>
+ </dict>
+ </dict>
+ <dict>
+ <key>AllowLabelDrop</key>
+ <false/>
+ <key>Class</key>
+ <string>LineGraphic</string>
+ <key>Head</key>
+ <dict>
+ <key>ID</key>
+ <integer>119</integer>
+ </dict>
+ <key>ID</key>
+ <integer>120</integer>
+ <key>Points</key>
+ <array>
+ <string>{397.5, 143.273}</string>
+ <string>{550.5, 144.455}</string>
+ </array>
+ <key>Style</key>
+ <dict>
+ <key>stroke</key>
+ <dict>
+ <key>HeadArrow</key>
+ <string>FilledArrow</string>
+ <key>HeadScale</key>
+ <real>1.4285709857940674</real>
+ <key>TailArrow</key>
+ <string>StickArrow</string>
+ <key>TailScale</key>
+ <real>1.5</real>
+ </dict>
+ </dict>
+ <key>Tail</key>
+ <dict>
+ <key>ID</key>
+ <integer>73</integer>
+ <key>Info</key>
+ <integer>4</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{550.5, 137.705}, {17, 27}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>HFlip</key>
+ <string>YES</string>
+ <key>ID</key>
+ <integer>119</integer>
+ <key>Magnets</key>
+ <array>
+ <string>{1, 0.5}</string>
+ <string>{1, -0.5}</string>
+ <string>{-1, 0.5}</string>
+ <string>{-1, -0.5}</string>
+ <string>{0.5, 1}</string>
+ <string>{-0.5, 1}</string>
+ <string>{0.5, -1}</string>
+ <string>{-0.5, -1}</string>
+ </array>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Text</key>
+ <dict>
+ <key>Align</key>
+ <integer>0</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{26, 636}, {131, 14}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FitText</key>
+ <string>YES</string>
+ <key>Flow</key>
+ <string>Resize</string>
+ <key>ID</key>
+ <integer>118</integer>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Style</key>
+ <dict>
+ <key>shadow</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Align</key>
+ <integer>0</integer>
+ <key>Text</key>
+ <string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf410
+{\fonttbl\f0\fswiss\fcharset77 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural
+
+\f0\fs24 \cf0 foreach binding in plan}</string>
+ </dict>
+ <key>Wrap</key>
+ <string>NO</string>
+ </dict>
+ <dict>
+ <key>AllowLabelDrop</key>
+ <false/>
+ <key>Class</key>
+ <string>LineGraphic</string>
+ <key>Head</key>
+ <dict>
+ <key>ID</key>
+ <integer>4</integer>
+ <key>Info</key>
+ <integer>5</integer>
+ </dict>
+ <key>ID</key>
+ <integer>117</integer>
+ <key>OrthogonalBarAutomatic</key>
+ <true/>
+ <key>OrthogonalBarPosition</key>
+ <real>19.371429443359375</real>
+ <key>Points</key>
+ <array>
+ <string>{75.5, 478}</string>
+ <string>{26, 482}</string>
+ <string>{26, 575}</string>
+ <string>{79.125, 616}</string>
+ </array>
+ <key>Style</key>
+ <dict>
+ <key>stroke</key>
+ <dict>
+ <key>HeadArrow</key>
+ <string>0</string>
+ <key>HeadScale</key>
+ <real>0.86000001430511475</real>
+ <key>LineType</key>
+ <integer>2</integer>
+ <key>TailArrow</key>
+ <string>FilledArrow</string>
+ <key>TailScale</key>
+ <real>0.85714292526245117</real>
+ </dict>
+ </dict>
+ <key>Tail</key>
+ <dict>
+ <key>ID</key>
+ <integer>4</integer>
+ <key>Info</key>
+ <integer>1</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{310.653, 581.444}, {179, 14}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FitText</key>
+ <string>YES</string>
+ <key>ID</key>
+ <integer>116</integer>
+ <key>Line</key>
+ <dict>
+ <key>ID</key>
+ <integer>115</integer>
+ <key>Offset</key>
+ <real>18.181819915771484</real>
+ <key>Position</key>
+ <real>0.52437615394592285</real>
+ <key>RotationType</key>
+ <integer>0</integer>
+ </dict>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Style</key>
+ <dict>
+ <key>shadow</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Align</key>
+ <integer>0</integer>
+ <key>Text</key>
+ <string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf410
+{\fonttbl\f0\fswiss\fcharset77 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural
+
+\f0\fs24 \cf0 mojoExecution, project, session}</string>
+ </dict>
+ </dict>
+ <dict>
+ <key>AllowLabelDrop</key>
+ <false/>
+ <key>Class</key>
+ <string>LineGraphic</string>
+ <key>Head</key>
+ <dict>
+ <key>ID</key>
+ <integer>113</integer>
+ <key>Info</key>
+ <integer>2</integer>
+ </dict>
+ <key>ID</key>
+ <integer>115</integer>
+ <key>Points</key>
+ <array>
+ <string>{90, 570}</string>
+ <string>{681.5, 570.5}</string>
+ </array>
+ <key>Style</key>
+ <dict>
+ <key>stroke</key>
+ <dict>
+ <key>HeadArrow</key>
+ <string>FilledArrow</string>
+ <key>HeadScale</key>
+ <real>1.4285709857940674</real>
+ <key>TailArrow</key>
+ <string>StickArrow</string>
+ <key>TailScale</key>
+ <real>1.5</real>
+ </dict>
+ </dict>
+ <key>Tail</key>
+ <dict>
+ <key>ID</key>
+ <integer>4</integer>
+ <key>Info</key>
+ <integer>12</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{646.5, 539}, {87, 14}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FitText</key>
+ <string>YES</string>
+ <key>FontInfo</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>w</key>
+ <string>0</string>
+ </dict>
+ <key>Font</key>
+ <string>Helvetica</string>
+ <key>Size</key>
+ <real>12</real>
+ </dict>
+ <key>ID</key>
+ <integer>114</integer>
+ <key>Line</key>
+ <dict>
+ <key>ID</key>
+ <integer>111</integer>
+ <key>Position</key>
+ <real>0.8310316801071167</real>
+ <key>RotationType</key>
+ <integer>0</integer>
+ </dict>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Style</key>
+ <dict>
+ <key>shadow</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Text</key>
+ <string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf410
+{\fonttbl\f0\fswiss\fcharset77 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs24 \cf0 executeMojo()}</string>
+ </dict>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{681.5, 559}, {17, 46}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>HFlip</key>
+ <string>YES</string>
+ <key>ID</key>
+ <integer>113</integer>
+ <key>Magnets</key>
+ <array>
+ <string>{1, 0.5}</string>
+ <string>{1, -0.5}</string>
+ <string>{-1, 0.5}</string>
+ <string>{-1, -0.5}</string>
+ <string>{0.5, 1}</string>
+ <string>{-0.5, 1}</string>
+ <string>{0.5, -1}</string>
+ <string>{-0.5, -1}</string>
+ </array>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Text</key>
+ <dict>
+ <key>Align</key>
+ <integer>0</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>Class</key>
+ <string>Group</string>
+ <key>Graphics</key>
+ <array>
+ <dict>
+ <key>AllowLabelDrop</key>
+ <false/>
+ <key>Class</key>
+ <string>LineGraphic</string>
+ <key>ID</key>
+ <integer>111</integer>
+ <key>Points</key>
+ <array>
+ <string>{690, 34.5}</string>
+ <string>{690, 650}</string>
+ </array>
+ <key>Style</key>
+ <dict>
+ <key>stroke</key>
+ <dict>
+ <key>HeadArrow</key>
+ <string>0</string>
+ <key>HeadScale</key>
+ <real>1.4285709857940674</real>
+ <key>Pattern</key>
+ <integer>1</integer>
+ <key>TailArrow</key>
+ <string>0</string>
+ <key>TailScale</key>
+ <real>0.5</real>
+ </dict>
+ </dict>
+ <key>Tail</key>
+ <dict>
+ <key>ID</key>
+ <integer>112</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{636, 20}, {108, 14}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FitText</key>
+ <string>Vertical</string>
+ <key>Flow</key>
+ <string>Resize</string>
+ <key>ID</key>
+ <integer>112</integer>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Text</key>
+ <dict>
+ <key>Text</key>
+ <string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf410
+{\fonttbl\f0\fswiss\fcharset77 Helvetica-Bold;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc
+
+\f0\b\fs24 \cf0 \ul \ulc0 PluginManager}</string>
+ </dict>
+ </dict>
+ </array>
+ <key>ID</key>
+ <integer>110</integer>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{287.086, 525.522}, {92, 14}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FitText</key>
+ <string>YES</string>
+ <key>ID</key>
+ <integer>109</integer>
+ <key>Line</key>
+ <dict>
+ <key>ID</key>
+ <integer>108</integer>
+ <key>Offset</key>
+ <real>18.181819915771484</real>
+ <key>Position</key>
+ <real>0.52776741981506348</real>
+ <key>RotationType</key>
+ <integer>0</integer>
+ </dict>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Style</key>
+ <dict>
+ <key>shadow</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Align</key>
+ <integer>0</integer>
+ <key>Text</key>
+ <string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf410
+{\fonttbl\f0\fswiss\fcharset77 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural
+
+\f0\fs24 \cf0 binding, project}</string>
+ </dict>
+ </dict>
+ <dict>
+ <key>AllowLabelDrop</key>
+ <false/>
+ <key>Class</key>
+ <string>LineGraphic</string>
+ <key>Head</key>
+ <dict>
+ <key>ID</key>
+ <integer>106</integer>
+ <key>Info</key>
+ <integer>2</integer>
+ </dict>
+ <key>ID</key>
+ <integer>108</integer>
+ <key>Points</key>
+ <array>
+ <string>{90, 515}</string>
+ <string>{550.5, 513.75}</string>
+ </array>
+ <key>Style</key>
+ <dict>
+ <key>stroke</key>
+ <dict>
+ <key>HeadArrow</key>
+ <string>FilledArrow</string>
+ <key>HeadScale</key>
+ <real>1.4285709857940674</real>
+ <key>TailArrow</key>
+ <string>StickArrow</string>
+ <key>TailScale</key>
+ <real>1.5</real>
+ </dict>
+ </dict>
+ <key>Tail</key>
+ <dict>
+ <key>ID</key>
+ <integer>4</integer>
+ <key>Info</key>
+ <integer>3</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{521.5, 485}, {75, 14}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FitText</key>
+ <string>YES</string>
+ <key>Flow</key>
+ <string>Resize</string>
+ <key>FontInfo</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>w</key>
+ <string>0</string>
+ </dict>
+ <key>Font</key>
+ <string>Helvetica</string>
+ <key>Size</key>
+ <real>12</real>
+ </dict>
+ <key>ID</key>
+ <integer>107</integer>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Style</key>
+ <dict>
+ <key>shadow</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Text</key>
+ <string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf410
+{\fonttbl\f0\fswiss\fcharset77 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs24 \cf0 loadPlugin()}</string>
+ </dict>
+ <key>Wrap</key>
+ <string>NO</string>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{550.5, 507}, {17, 27}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>HFlip</key>
+ <string>YES</string>
+ <key>ID</key>
+ <integer>106</integer>
+ <key>Magnets</key>
+ <array>
+ <string>{1, 0.5}</string>
+ <string>{0.5, -0.25}</string>
+ <string>{-1, 0.5}</string>
+ <string>{-1, -0.5}</string>
+ <string>{0.5, 1}</string>
+ <string>{-0.5, 1}</string>
+ <string>{0.5, -1}</string>
+ <string>{-0.5, -1}</string>
+ </array>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Text</key>
+ <dict>
+ <key>Align</key>
+ <integer>0</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{130.5, 275}, {33, 14}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FitText</key>
+ <string>YES</string>
+ <key>Flow</key>
+ <string>Resize</string>
+ <key>ID</key>
+ <integer>105</integer>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Style</key>
+ <dict>
+ <key>shadow</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Align</key>
+ <integer>0</integer>
+ <key>Text</key>
+ <string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf410
+{\fonttbl\f0\fswiss\fcharset77 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural
+
+\f0\fs24 \cf0 plan}</string>
+ </dict>
+ <key>Wrap</key>
+ <string>NO</string>
+ </dict>
+ <dict>
+ <key>Class</key>
+ <string>LineGraphic</string>
+ <key>Head</key>
+ <dict>
+ <key>ID</key>
+ <integer>4</integer>
+ </dict>
+ <key>ID</key>
+ <integer>66</integer>
+ <key>Points</key>
+ <array>
+ <string>{205.5, 270}</string>
+ <string>{86.375, 270}</string>
+ </array>
+ <key>Style</key>
+ <dict>
+ <key>stroke</key>
+ <dict>
+ <key>HeadArrow</key>
+ <string>FilledArrow</string>
+ <key>HopLines</key>
+ <true/>
+ <key>HopType</key>
+ <integer>1</integer>
+ <key>TailArrow</key>
+ <string>0</string>
+ </dict>
+ </dict>
+ <key>Tail</key>
+ <dict>
+ <key>ID</key>
+ <integer>19</integer>
+ <key>Info</key>
+ <integer>16</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{521.5, 302}, {75, 14}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FitText</key>
+ <string>YES</string>
+ <key>Flow</key>
+ <string>Resize</string>
+ <key>FontInfo</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>w</key>
+ <string>0</string>
+ </dict>
+ <key>Font</key>
+ <string>Helvetica</string>
+ <key>Size</key>
+ <real>12</real>
+ </dict>
+ <key>ID</key>
+ <integer>104</integer>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Style</key>
+ <dict>
+ <key>shadow</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Text</key>
+ <string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf410
+{\fonttbl\f0\fswiss\fcharset77 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs24 \cf0 loadPlugin()}</string>
+ </dict>
+ <key>Wrap</key>
+ <string>NO</string>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{349.413, 453.786}, {92, 14}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FitText</key>
+ <string>YES</string>
+ <key>ID</key>
+ <integer>103</integer>
+ <key>Line</key>
+ <dict>
+ <key>ID</key>
+ <integer>102</integer>
+ <key>Offset</key>
+ <real>18.181819915771484</real>
+ <key>Position</key>
+ <real>0.52776741981506348</real>
+ <key>RotationType</key>
+ <integer>0</integer>
+ </dict>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Style</key>
+ <dict>
+ <key>shadow</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Align</key>
+ <integer>0</integer>
+ <key>Text</key>
+ <string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf410
+{\fonttbl\f0\fswiss\fcharset77 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural
+
+\f0\fs24 \cf0 binding, project}</string>
+ </dict>
+ </dict>
+ <dict>
+ <key>AllowLabelDrop</key>
+ <false/>
+ <key>Class</key>
+ <string>LineGraphic</string>
+ <key>Head</key>
+ <dict>
+ <key>ID</key>
+ <integer>101</integer>
+ </dict>
+ <key>ID</key>
+ <integer>102</integer>
+ <key>Points</key>
+ <array>
+ <string>{222, 443}</string>
+ <string>{550.5, 442.25}</string>
+ </array>
+ <key>Style</key>
+ <dict>
+ <key>stroke</key>
+ <dict>
+ <key>HeadArrow</key>
+ <string>FilledArrow</string>
+ <key>HeadScale</key>
+ <real>1.4285709857940674</real>
+ <key>TailArrow</key>
+ <string>StickArrow</string>
+ <key>TailScale</key>
+ <real>1.5</real>
+ </dict>
+ </dict>
+ <key>Tail</key>
+ <dict>
+ <key>ID</key>
+ <integer>86</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{550.5, 422}, {17, 27}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>HFlip</key>
+ <string>YES</string>
+ <key>ID</key>
+ <integer>101</integer>
+ <key>Magnets</key>
+ <array>
+ <string>{1, 0.5}</string>
+ <string>{0.5, -0.25}</string>
+ <string>{-1, 0.5}</string>
+ <string>{-1, -0.5}</string>
+ <string>{0.5, 1}</string>
+ <string>{-0.5, 1}</string>
+ <string>{0.5, -1}</string>
+ <string>{-0.5, -1}</string>
+ </array>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Text</key>
+ <dict>
+ <key>Align</key>
+ <integer>0</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{521.5, 396.749}, {75, 14}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FitText</key>
+ <string>YES</string>
+ <key>FontInfo</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>w</key>
+ <string>0</string>
+ </dict>
+ <key>Font</key>
+ <string>Helvetica</string>
+ <key>Size</key>
+ <real>12</real>
+ </dict>
+ <key>ID</key>
+ <integer>100</integer>
+ <key>Line</key>
+ <dict>
+ <key>ID</key>
+ <integer>93</integer>
+ <key>Position</key>
+ <real>0.59991699457168579</real>
+ <key>RotationType</key>
+ <integer>0</integer>
+ </dict>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Style</key>
+ <dict>
+ <key>shadow</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Text</key>
+ <string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf410
+{\fonttbl\f0\fswiss\fcharset77 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs24 \cf0 loadPlugin()}</string>
+ </dict>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{349.564, 356.057}, {92, 14}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FitText</key>
+ <string>YES</string>
+ <key>ID</key>
+ <integer>99</integer>
+ <key>Line</key>
+ <dict>
+ <key>ID</key>
+ <integer>98</integer>
+ <key>Offset</key>
+ <real>18.181819915771484</real>
+ <key>Position</key>
+ <real>0.52776741981506348</real>
+ <key>RotationType</key>
+ <integer>0</integer>
+ </dict>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Style</key>
+ <dict>
+ <key>shadow</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Align</key>
+ <integer>0</integer>
+ <key>Text</key>
+ <string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf410
+{\fonttbl\f0\fswiss\fcharset77 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural
+
+\f0\fs24 \cf0 binding, project}</string>
+ </dict>
+ </dict>
+ <dict>
+ <key>AllowLabelDrop</key>
+ <false/>
+ <key>Class</key>
+ <string>LineGraphic</string>
+ <key>Head</key>
+ <dict>
+ <key>ID</key>
+ <integer>95</integer>
+ </dict>
+ <key>ID</key>
+ <integer>98</integer>
+ <key>Points</key>
+ <array>
+ <string>{222.5, 344.456}</string>
+ <string>{550.5, 345.25}</string>
+ </array>
+ <key>Style</key>
+ <dict>
+ <key>stroke</key>
+ <dict>
+ <key>HeadArrow</key>
+ <string>FilledArrow</string>
+ <key>HeadScale</key>
+ <real>1.4285709857940674</real>
+ <key>TailArrow</key>
+ <string>StickArrow</string>
+ <key>TailScale</key>
+ <real>1.5</real>
+ </dict>
+ </dict>
+ <key>Tail</key>
+ <dict>
+ <key>ID</key>
+ <integer>83</integer>
+ <key>Info</key>
+ <integer>9</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>AllowLabelDrop</key>
+ <false/>
+ <key>Class</key>
+ <string>LineGraphic</string>
+ <key>Head</key>
+ <dict>
+ <key>ID</key>
+ <integer>86</integer>
+ <key>Info</key>
+ <integer>3</integer>
+ </dict>
+ <key>ID</key>
+ <integer>97</integer>
+ <key>OrthogonalBarAutomatic</key>
+ <true/>
+ <key>OrthogonalBarPosition</key>
+ <real>-1</real>
+ <key>Points</key>
+ <array>
+ <string>{222.5, 254.5}</string>
+ <string>{309.5, 254}</string>
+ <string>{327, 344}</string>
+ <string>{222.5, 454.079}</string>
+ </array>
+ <key>Style</key>
+ <dict>
+ <key>stroke</key>
+ <dict>
+ <key>HeadArrow</key>
+ <string>0</string>
+ <key>HeadScale</key>
+ <real>0.86000001430511475</real>
+ <key>LineType</key>
+ <integer>2</integer>
+ <key>TailArrow</key>
+ <string>StickArrow</string>
+ <key>TailScale</key>
+ <real>0.85714292526245117</real>
+ </dict>
+ </dict>
+ <key>Tail</key>
+ <dict>
+ <key>ID</key>
+ <integer>19</integer>
+ <key>Info</key>
+ <integer>15</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>AllowLabelDrop</key>
+ <false/>
+ <key>Class</key>
+ <string>LineGraphic</string>
+ <key>Head</key>
+ <dict>
+ <key>ID</key>
+ <integer>83</integer>
+ <key>Info</key>
+ <integer>3</integer>
+ </dict>
+ <key>ID</key>
+ <integer>96</integer>
+ <key>OrthogonalBarAutomatic</key>
+ <true/>
+ <key>OrthogonalBarPosition</key>
+ <real>-1</real>
+ <key>Points</key>
+ <array>
+ <string>{222, 237}</string>
+ <string>{295.5, 237}</string>
+ <string>{295.5, 337}</string>
+ <string>{222.5, 356.792}</string>
+ </array>
+ <key>Style</key>
+ <dict>
+ <key>stroke</key>
+ <dict>
+ <key>HeadArrow</key>
+ <string>0</string>
+ <key>HeadScale</key>
+ <real>0.86000001430511475</real>
+ <key>LineType</key>
+ <integer>2</integer>
+ <key>TailArrow</key>
+ <string>StickArrow</string>
+ <key>TailScale</key>
+ <real>0.85714292526245117</real>
+ </dict>
+ </dict>
+ <key>Tail</key>
+ <dict>
+ <key>ID</key>
+ <integer>19</integer>
+ <key>Info</key>
+ <integer>14</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{550.5, 325}, {17, 27}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>HFlip</key>
+ <string>YES</string>
+ <key>ID</key>
+ <integer>95</integer>
+ <key>Magnets</key>
+ <array>
+ <string>{1, 0.5}</string>
+ <string>{1, -0.5}</string>
+ <string>{-1, 0.5}</string>
+ <string>{-1, -0.5}</string>
+ <string>{0.5, 1}</string>
+ <string>{-0.5, 1}</string>
+ <string>{0.5, -1}</string>
+ <string>{-0.5, -1}</string>
+ </array>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Text</key>
+ <dict>
+ <key>Align</key>
+ <integer>0</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>Class</key>
+ <string>Group</string>
+ <key>Graphics</key>
+ <array>
+ <dict>
+ <key>AllowLabelDrop</key>
+ <false/>
+ <key>Class</key>
+ <string>LineGraphic</string>
+ <key>ID</key>
+ <integer>93</integer>
+ <key>Points</key>
+ <array>
+ <string>{559, 34.5}</string>
+ <string>{559, 650}</string>
+ </array>
+ <key>Style</key>
+ <dict>
+ <key>stroke</key>
+ <dict>
+ <key>HeadArrow</key>
+ <string>0</string>
+ <key>HeadScale</key>
+ <real>1.4285709857940674</real>
+ <key>Pattern</key>
+ <integer>1</integer>
+ <key>TailArrow</key>
+ <string>0</string>
+ <key>TailScale</key>
+ <real>0.5</real>
+ </dict>
+ </dict>
+ <key>Tail</key>
+ <dict>
+ <key>ID</key>
+ <integer>94</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{505, 20}, {108, 14}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FitText</key>
+ <string>Vertical</string>
+ <key>Flow</key>
+ <string>Resize</string>
+ <key>ID</key>
+ <integer>94</integer>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Text</key>
+ <dict>
+ <key>Text</key>
+ <string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf410
+{\fonttbl\f0\fswiss\fcharset77 Helvetica-Bold;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc
+
+\f0\b\fs24 \cf0 \ul \ulc0 PluginLoader}</string>
+ </dict>
+ </dict>
+ </array>
+ <key>ID</key>
+ <integer>92</integer>
+ </dict>
+ <dict>
+ <key>AllowLabelDrop</key>
+ <false/>
+ <key>Class</key>
+ <string>LineGraphic</string>
+ <key>Head</key>
+ <dict>
+ <key>ID</key>
+ <integer>19</integer>
+ <key>Info</key>
+ <integer>13</integer>
+ </dict>
+ <key>ID</key>
+ <integer>91</integer>
+ <key>OrthogonalBarAutomatic</key>
+ <true/>
+ <key>OrthogonalBarPosition</key>
+ <real>-1</real>
+ <key>Points</key>
+ <array>
+ <string>{222.5, 426.798}</string>
+ <string>{321, 420}</string>
+ <string>{301, 249}</string>
+ <string>{222.5, 248.833}</string>
+ </array>
+ <key>Style</key>
+ <dict>
+ <key>stroke</key>
+ <dict>
+ <key>HeadArrow</key>
+ <string>0</string>
+ <key>HeadScale</key>
+ <real>0.86000001430511475</real>
+ <key>LineType</key>
+ <integer>2</integer>
+ <key>TailArrow</key>
+ <string>FilledArrow</string>
+ <key>TailScale</key>
+ <real>0.85714292526245117</real>
+ </dict>
+ </dict>
+ <key>Tail</key>
+ <dict>
+ <key>ID</key>
+ <integer>86</integer>
+ <key>Info</key>
+ <integer>4</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>AllowLabelDrop</key>
+ <false/>
+ <key>Class</key>
+ <string>LineGraphic</string>
+ <key>Head</key>
+ <dict>
+ <key>ID</key>
+ <integer>19</integer>
+ <key>Info</key>
+ <integer>12</integer>
+ </dict>
+ <key>ID</key>
+ <integer>10</integer>
+ <key>OrthogonalBarAutomatic</key>
+ <true/>
+ <key>OrthogonalBarPosition</key>
+ <real>-1</real>
+ <key>Points</key>
+ <array>
+ <string>{222.5, 330.264}</string>
+ <string>{288.5, 330}</string>
+ <string>{288.5, 230}</string>
+ <string>{222.5, 230}</string>
+ </array>
+ <key>Style</key>
+ <dict>
+ <key>stroke</key>
+ <dict>
+ <key>HeadArrow</key>
+ <string>0</string>
+ <key>HeadScale</key>
+ <real>0.86000001430511475</real>
+ <key>LineType</key>
+ <integer>2</integer>
+ <key>TailArrow</key>
+ <string>FilledArrow</string>
+ <key>TailScale</key>
+ <real>0.85714292526245117</real>
+ </dict>
+ </dict>
+ <key>Tail</key>
+ <dict>
+ <key>ID</key>
+ <integer>83</integer>
+ <key>Info</key>
+ <integer>4</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{132.5, 396.158}, {163, 14}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FitText</key>
+ <string>YES</string>
+ <key>Flow</key>
+ <string>Resize</string>
+ <key>FontInfo</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>w</key>
+ <string>0</string>
+ </dict>
+ <key>Font</key>
+ <string>Helvetica</string>
+ <key>Size</key>
+ <real>12</real>
+ </dict>
+ <key>ID</key>
+ <integer>87</integer>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Style</key>
+ <dict>
+ <key>shadow</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Text</key>
+ <string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf410
+{\fonttbl\f0\fswiss\fcharset77 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs24 \cf0 addReportingPlanModifiers()}</string>
+ </dict>
+ <key>Wrap</key>
+ <string>NO</string>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{205.5, 413.158}, {17, 54.5618}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>HFlip</key>
+ <string>YES</string>
+ <key>ID</key>
+ <integer>86</integer>
+ <key>Magnets</key>
+ <array>
+ <string>{1, 0.5}</string>
+ <string>{1, -0.5}</string>
+ <string>{-1, 0.5}</string>
+ <string>{-1, -0.5}</string>
+ <string>{0.5, 1}</string>
+ <string>{-0.5, 1}</string>
+ <string>{0.5, -1}</string>
+ <string>{-0.5, -1}</string>
+ <string>{-0.529412, 0.0497093}</string>
+ </array>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Text</key>
+ <dict>
+ <key>Align</key>
+ <integer>0</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{139.5, 297.124}, {149, 14}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FitText</key>
+ <string>YES</string>
+ <key>FontInfo</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>w</key>
+ <string>0</string>
+ </dict>
+ <key>Font</key>
+ <string>Helvetica</string>
+ <key>Size</key>
+ <real>12</real>
+ </dict>
+ <key>ID</key>
+ <integer>84</integer>
+ <key>Line</key>
+ <dict>
+ <key>ID</key>
+ <integer>17</integer>
+ <key>Position</key>
+ <real>0.43805667757987976</real>
+ <key>RotationType</key>
+ <integer>0</integer>
+ </dict>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Style</key>
+ <dict>
+ <key>shadow</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Text</key>
+ <string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf410
+{\fonttbl\f0\fswiss\fcharset77 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs24 \cf0 addForkedPlanModifiers()}</string>
+ </dict>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{205.5, 317}, {17, 53.056}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>HFlip</key>
+ <string>YES</string>
+ <key>ID</key>
+ <integer>83</integer>
+ <key>Magnets</key>
+ <array>
+ <string>{1, 0.5}</string>
+ <string>{1, -0.5}</string>
+ <string>{-1, 0.5}</string>
+ <string>{-1, -0.5}</string>
+ <string>{0.5, 1}</string>
+ <string>{-0.5, 1}</string>
+ <string>{0.5, -1}</string>
+ <string>{-0.5, -1}</string>
+ <string>{-0.529412, 0.0185184}</string>
+ </array>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Text</key>
+ <dict>
+ <key>Align</key>
+ <integer>0</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{305.436, 220.259}, {47, 14}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FitText</key>
+ <string>YES</string>
+ <key>ID</key>
+ <integer>82</integer>
+ <key>Line</key>
+ <dict>
+ <key>ID</key>
+ <integer>81</integer>
+ <key>Offset</key>
+ <real>18.181819915771484</real>
+ <key>Position</key>
+ <real>0.67475664615631104</real>
+ <key>RotationType</key>
+ <integer>0</integer>
+ </dict>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Style</key>
+ <dict>
+ <key>shadow</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Align</key>
+ <integer>0</integer>
+ <key>Text</key>
+ <string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf410
+{\fonttbl\f0\fswiss\fcharset77 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural
+
+\f0\fs24 \cf0 project}</string>
+ </dict>
+ </dict>
+ <dict>
+ <key>AllowLabelDrop</key>
+ <false/>
+ <key>Class</key>
+ <string>LineGraphic</string>
+ <key>Head</key>
+ <dict>
+ <key>ID</key>
+ <integer>79</integer>
+ <key>Info</key>
+ <integer>2</integer>
+ </dict>
+ <key>ID</key>
+ <integer>81</integer>
+ <key>Points</key>
+ <array>
+ <string>{222, 209}</string>
+ <string>{380.5, 209.115}</string>
+ </array>
+ <key>Style</key>
+ <dict>
+ <key>stroke</key>
+ <dict>
+ <key>HeadArrow</key>
+ <string>FilledArrow</string>
+ <key>HeadScale</key>
+ <real>1.4285709857940674</real>
+ <key>TailArrow</key>
+ <string>StickArrow</string>
+ <key>TailScale</key>
+ <real>1.5</real>
+ </dict>
+ </dict>
+ <key>Tail</key>
+ <dict>
+ <key>ID</key>
+ <integer>19</integer>
+ <key>Info</key>
+ <integer>3</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{311.5, 120.556}, {155, 14}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FitText</key>
+ <string>YES</string>
+ <key>Flow</key>
+ <string>Resize</string>
+ <key>FontInfo</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>w</key>
+ <string>0</string>
+ </dict>
+ <key>Font</key>
+ <string>Helvetica</string>
+ <key>Size</key>
+ <real>12</real>
+ </dict>
+ <key>ID</key>
+ <integer>80</integer>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Style</key>
+ <dict>
+ <key>shadow</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Text</key>
+ <string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf410
+{\fonttbl\f0\fswiss\fcharset77 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs24 \cf0 getBindingsForPackaging()}</string>
+ </dict>
+ <key>Wrap</key>
+ <string>NO</string>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{380.5, 203.842}, {17, 21.0909}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>HFlip</key>
+ <string>YES</string>
+ <key>ID</key>
+ <integer>79</integer>
+ <key>Magnets</key>
+ <array>
+ <string>{1, 0.5}</string>
+ <string>{1, -0.5}</string>
+ <string>{-1, 0.5}</string>
+ <string>{-1, -0.5}</string>
+ <string>{0.5, 1}</string>
+ <string>{-0.5, 1}</string>
+ <string>{0.5, -1}</string>
+ <string>{-0.5, -1}</string>
+ </array>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Text</key>
+ <dict>
+ <key>Align</key>
+ <integer>0</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{260.247, 156.369}, {47, 14}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FitText</key>
+ <string>YES</string>
+ <key>ID</key>
+ <integer>76</integer>
+ <key>Line</key>
+ <dict>
+ <key>ID</key>
+ <integer>75</integer>
+ <key>Offset</key>
+ <real>18.181819915771484</real>
+ <key>Position</key>
+ <real>0.38291174173355103</real>
+ <key>RotationType</key>
+ <integer>0</integer>
+ </dict>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Style</key>
+ <dict>
+ <key>shadow</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Align</key>
+ <integer>0</integer>
+ <key>Text</key>
+ <string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf410
+{\fonttbl\f0\fswiss\fcharset77 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural
+
+\f0\fs24 \cf0 project}</string>
+ </dict>
+ </dict>
+ <dict>
+ <key>AllowLabelDrop</key>
+ <false/>
+ <key>Class</key>
+ <string>LineGraphic</string>
+ <key>ID</key>
+ <integer>75</integer>
+ <key>Points</key>
+ <array>
+ <string>{222.5, 145.7}</string>
+ <string>{382.054, 144.364}</string>
+ </array>
+ <key>Style</key>
+ <dict>
+ <key>stroke</key>
+ <dict>
+ <key>HeadArrow</key>
+ <string>FilledArrow</string>
+ <key>HeadScale</key>
+ <real>1.4285709857940674</real>
+ <key>TailArrow</key>
+ <string>StickArrow</string>
+ <key>TailScale</key>
+ <real>1.5</real>
+ </dict>
+ </dict>
+ <key>Tail</key>
+ <dict>
+ <key>ID</key>
+ <integer>19</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{309, 182.853}, {160, 14}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FitText</key>
+ <string>YES</string>
+ <key>FontInfo</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>w</key>
+ <string>0</string>
+ </dict>
+ <key>Font</key>
+ <string>Helvetica</string>
+ <key>Size</key>
+ <real>12</real>
+ </dict>
+ <key>ID</key>
+ <integer>74</integer>
+ <key>Line</key>
+ <dict>
+ <key>ID</key>
+ <integer>69</integer>
+ <key>Position</key>
+ <real>0.25240078568458557</real>
+ <key>RotationType</key>
+ <integer>0</integer>
+ </dict>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Style</key>
+ <dict>
+ <key>shadow</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Text</key>
+ <string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf410
+{\fonttbl\f0\fswiss\fcharset77 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs24 \cf0 getProjectCustomBindings()}</string>
+ </dict>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{380.5, 138}, {17, 21.0909}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>HFlip</key>
+ <string>YES</string>
+ <key>ID</key>
+ <integer>73</integer>
+ <key>Magnets</key>
+ <array>
+ <string>{1, 0.5}</string>
+ <string>{1, -0.5}</string>
+ <string>{-1, 0.5}</string>
+ <string>{-1, -0.5}</string>
+ <string>{0.5, 1}</string>
+ <string>{-0.5, 1}</string>
+ <string>{0.5, -1}</string>
+ <string>{-0.5, -1}</string>
+ </array>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Text</key>
+ <dict>
+ <key>Align</key>
+ <integer>0</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{259.56, 110.107}, {47, 14}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FitText</key>
+ <string>YES</string>
+ <key>ID</key>
+ <integer>29</integer>
+ <key>Line</key>
+ <dict>
+ <key>ID</key>
+ <integer>7</integer>
+ <key>Offset</key>
+ <real>18.181819915771484</real>
+ <key>Position</key>
+ <real>0.38198670744895935</real>
+ <key>RotationType</key>
+ <integer>0</integer>
+ </dict>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Style</key>
+ <dict>
+ <key>shadow</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Align</key>
+ <integer>0</integer>
+ <key>Text</key>
+ <string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf410
+{\fonttbl\f0\fswiss\fcharset77 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural
+
+\f0\fs24 \cf0 project}</string>
+ </dict>
+ </dict>
+ <dict>
+ <key>AllowLabelDrop</key>
+ <false/>
+ <key>Class</key>
+ <string>LineGraphic</string>
+ <key>Head</key>
+ <dict>
+ <key>ID</key>
+ <integer>71</integer>
+ </dict>
+ <key>ID</key>
+ <integer>7</integer>
+ <key>Points</key>
+ <array>
+ <string>{222.5, 99.6111}</string>
+ <string>{380.5, 97.8182}</string>
+ </array>
+ <key>Style</key>
+ <dict>
+ <key>stroke</key>
+ <dict>
+ <key>HeadArrow</key>
+ <string>FilledArrow</string>
+ <key>HeadScale</key>
+ <real>1.4285709857940674</real>
+ <key>TailArrow</key>
+ <string>StickArrow</string>
+ <key>TailScale</key>
+ <real>1.5</real>
+ </dict>
+ </dict>
+ <key>Tail</key>
+ <dict>
+ <key>ID</key>
+ <integer>19</integer>
+ <key>Info</key>
+ <integer>10</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{329.5, 75.973}, {119, 14}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FitText</key>
+ <string>YES</string>
+ <key>FontInfo</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>w</key>
+ <string>0</string>
+ </dict>
+ <key>Font</key>
+ <string>Helvetica</string>
+ <key>Size</key>
+ <real>12</real>
+ </dict>
+ <key>ID</key>
+ <integer>72</integer>
+ <key>Line</key>
+ <dict>
+ <key>ID</key>
+ <integer>69</integer>
+ <key>Position</key>
+ <real>0.078753873705863953</real>
+ <key>RotationType</key>
+ <integer>0</integer>
+ </dict>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Style</key>
+ <dict>
+ <key>shadow</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Text</key>
+ <string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf410
+{\fonttbl\f0\fswiss\fcharset77 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs24 \cf0 getDefaultBindings()}</string>
+ </dict>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{380.5, 92.5454}, {17, 21.0909}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>HFlip</key>
+ <string>YES</string>
+ <key>ID</key>
+ <integer>71</integer>
+ <key>Magnets</key>
+ <array>
+ <string>{1, 0.5}</string>
+ <string>{1, -0.5}</string>
+ <string>{-1, 0.5}</string>
+ <string>{-1, -0.5}</string>
+ <string>{0.5, 1}</string>
+ <string>{-0.5, 1}</string>
+ <string>{0.5, -1}</string>
+ <string>{-0.5, -1}</string>
+ </array>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Text</key>
+ <dict>
+ <key>Align</key>
+ <integer>0</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>Class</key>
+ <string>Group</string>
+ <key>Graphics</key>
+ <array>
+ <dict>
+ <key>AllowLabelDrop</key>
+ <false/>
+ <key>Class</key>
+ <string>LineGraphic</string>
+ <key>ID</key>
+ <integer>69</integer>
+ <key>Points</key>
+ <array>
+ <string>{389, 34.5}</string>
+ <string>{389, 650}</string>
+ </array>
+ <key>Style</key>
+ <dict>
+ <key>stroke</key>
+ <dict>
+ <key>HeadArrow</key>
+ <string>0</string>
+ <key>HeadScale</key>
+ <real>1.4285709857940674</real>
+ <key>Pattern</key>
+ <integer>1</integer>
+ <key>TailArrow</key>
+ <string>0</string>
+ <key>TailScale</key>
+ <real>0.5</real>
+ </dict>
+ </dict>
+ <key>Tail</key>
+ <dict>
+ <key>ID</key>
+ <integer>70</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{313.5, 20}, {151, 14}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FitText</key>
+ <string>Vertical</string>
+ <key>Flow</key>
+ <string>Resize</string>
+ <key>ID</key>
+ <integer>70</integer>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Text</key>
+ <dict>
+ <key>Text</key>
+ <string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf410
+{\fonttbl\f0\fswiss\fcharset77 Helvetica-Bold;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc
+
+\f0\b\fs24 \cf0 \ul \ulc0 LifecyleBindingManager}</string>
+ </dict>
+ </dict>
+ </array>
+ <key>ID</key>
+ <integer>68</integer>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{108.828, 81.9091}, {81, 14}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FitText</key>
+ <string>YES</string>
+ <key>ID</key>
+ <integer>30</integer>
+ <key>Line</key>
+ <dict>
+ <key>ID</key>
+ <integer>6</integer>
+ <key>Offset</key>
+ <real>10.909090042114258</real>
+ <key>Position</key>
+ <real>0.52006888389587402</real>
+ <key>RotationType</key>
+ <integer>0</integer>
+ </dict>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Style</key>
+ <dict>
+ <key>shadow</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Align</key>
+ <integer>0</integer>
+ <key>Text</key>
+ <string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf410
+{\fonttbl\f0\fswiss\fcharset77 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural
+
+\f0\fs24 \cf0 tasks, project}</string>
+ </dict>
+ </dict>
+ <dict>
+ <key>AllowLabelDrop</key>
+ <false/>
+ <key>Class</key>
+ <string>LineGraphic</string>
+ <key>ID</key>
+ <integer>6</integer>
+ <key>Points</key>
+ <array>
+ <string>{89, 78}</string>
+ <string>{205, 78}</string>
+ </array>
+ <key>Style</key>
+ <dict>
+ <key>stroke</key>
+ <dict>
+ <key>HeadArrow</key>
+ <string>StickArrow</string>
+ <key>HeadScale</key>
+ <real>1.4285709857940674</real>
+ <key>TailArrow</key>
+ <string>0</string>
+ <key>TailScale</key>
+ <real>0.5</real>
+ </dict>
+ </dict>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{155, 53.596}, {118, 14}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FitText</key>
+ <string>YES</string>
+ <key>FontInfo</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>w</key>
+ <string>0</string>
+ </dict>
+ <key>Font</key>
+ <string>Helvetica</string>
+ <key>Size</key>
+ <real>12</real>
+ </dict>
+ <key>ID</key>
+ <integer>20</integer>
+ <key>Line</key>
+ <dict>
+ <key>ID</key>
+ <integer>17</integer>
+ <key>Position</key>
+ <real>0.042397733777761459</real>
+ <key>RotationType</key>
+ <integer>0</integer>
+ </dict>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Style</key>
+ <dict>
+ <key>shadow</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Text</key>
+ <string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf410
+{\fonttbl\f0\fswiss\fcharset77 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs24 \cf0 constructBuildPlan()}</string>
+ </dict>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{205.5, 74}, {17, 208}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>HFlip</key>
+ <string>YES</string>
+ <key>ID</key>
+ <integer>19</integer>
+ <key>Magnets</key>
+ <array>
+ <string>{1, 0.5}</string>
+ <string>{1, -0.5}</string>
+ <string>{-0.470589, 0.149038}</string>
+ <string>{-0.5, -0.197115}</string>
+ <string>{0.5, 1}</string>
+ <string>{-0.5, 1}</string>
+ <string>{0.5, -1}</string>
+ <string>{-0.5, -1}</string>
+ <string>{-0.5, -0.155288}</string>
+ <string>{-0.5, -0.37687}</string>
+ <string>{-0.5, -0.155288}</string>
+ <string>{-0.5, 0.25}</string>
+ <string>{-0.529412, 0.360577}</string>
+ <string>{-0.470589, 0.283654}</string>
+ <string>{-0.529412, 0.389423}</string>
+ <string>{0.5, 0.442308}</string>
+ </array>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Text</key>
+ <dict>
+ <key>Align</key>
+ <integer>0</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>Class</key>
+ <string>Group</string>
+ <key>Graphics</key>
+ <array>
+ <dict>
+ <key>AllowLabelDrop</key>
+ <false/>
+ <key>Class</key>
+ <string>LineGraphic</string>
+ <key>ID</key>
+ <integer>17</integer>
+ <key>Points</key>
+ <array>
+ <string>{214, 34.5002}</string>
+ <string>{214, 650}</string>
+ </array>
+ <key>Style</key>
+ <dict>
+ <key>stroke</key>
+ <dict>
+ <key>HeadArrow</key>
+ <string>0</string>
+ <key>HeadScale</key>
+ <real>1.4285709857940674</real>
+ <key>Pattern</key>
+ <integer>1</integer>
+ <key>TailArrow</key>
+ <string>0</string>
+ <key>TailScale</key>
+ <real>0.5</real>
+ </dict>
+ </dict>
+ <key>Tail</key>
+ <dict>
+ <key>ID</key>
+ <integer>18</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{160, 20.0002}, {108, 14}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FitText</key>
+ <string>Vertical</string>
+ <key>Flow</key>
+ <string>Resize</string>
+ <key>ID</key>
+ <integer>18</integer>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Text</key>
+ <dict>
+ <key>Text</key>
+ <string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf410
+{\fonttbl\f0\fswiss\fcharset77 Helvetica-Bold;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc
+
+\f0\b\fs24 \cf0 \ul \ulc0 BuildPlanner}</string>
+ </dict>
+ </dict>
+ </array>
+ <key>ID</key>
+ <integer>16</integer>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{53.5, 46.7192}, {61, 14}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FitText</key>
+ <string>YES</string>
+ <key>FontInfo</key>
+ <dict>
+ <key>Color</key>
+ <dict>
+ <key>w</key>
+ <string>0</string>
+ </dict>
+ <key>Font</key>
+ <string>Helvetica</string>
+ <key>Size</key>
+ <real>12</real>
+ </dict>
+ <key>ID</key>
+ <integer>5</integer>
+ <key>Line</key>
+ <dict>
+ <key>ID</key>
+ <integer>2</integer>
+ <key>Position</key>
+ <real>0.031224979087710381</real>
+ <key>RotationType</key>
+ <integer>0</integer>
+ </dict>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Style</key>
+ <dict>
+ <key>shadow</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ <key>stroke</key>
+ <dict>
+ <key>Draws</key>
+ <string>NO</string>
+ </dict>
+ </dict>
+ <key>Text</key>
+ <dict>
+ <key>Text</key>
+ <string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf410
+{\fonttbl\f0\fswiss\fcharset77 Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc\pardirnatural
+
+\f0\fs24 \cf0 execute()}</string>
+ </dict>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{75.5, 64}, {14.5, 552}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>HFlip</key>
+ <string>YES</string>
+ <key>ID</key>
+ <integer>4</integer>
+ <key>Magnets</key>
+ <array>
+ <string>{1, 0.5}</string>
+ <string>{1, -0.5}</string>
+ <string>{-0.5, 0.317029}</string>
+ <string>{-1, -0.5}</string>
+ <string>{0.5, 1}</string>
+ <string>{-0.5, 1}</string>
+ <string>{0.5, -1}</string>
+ <string>{-0.5, -1}</string>
+ <string>{-0.25, -0.126812}</string>
+ <string>{-0.568965, 0.302536}</string>
+ <string>{-0.637931, 0.400362}</string>
+ <string>{-0.5, 0.416667}</string>
+ </array>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Text</key>
+ <dict>
+ <key>Align</key>
+ <integer>0</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>Class</key>
+ <string>Group</string>
+ <key>Graphics</key>
+ <array>
+ <dict>
+ <key>AllowLabelDrop</key>
+ <false/>
+ <key>Class</key>
+ <string>LineGraphic</string>
+ <key>ID</key>
+ <integer>2</integer>
+ <key>Points</key>
+ <array>
+ <string>{84, 34.5003}</string>
+ <string>{84, 650}</string>
+ </array>
+ <key>Style</key>
+ <dict>
+ <key>stroke</key>
+ <dict>
+ <key>HeadArrow</key>
+ <string>0</string>
+ <key>HeadScale</key>
+ <real>1.4285709857940674</real>
+ <key>Pattern</key>
+ <integer>1</integer>
+ <key>TailArrow</key>
+ <string>0</string>
+ <key>TailScale</key>
+ <real>0.5</real>
+ </dict>
+ </dict>
+ <key>Tail</key>
+ <dict>
+ <key>ID</key>
+ <integer>3</integer>
+ </dict>
+ </dict>
+ <dict>
+ <key>Bounds</key>
+ <string>{{26, 20.0002}, {116, 14}}</string>
+ <key>Class</key>
+ <string>ShapedGraphic</string>
+ <key>FitText</key>
+ <string>Vertical</string>
+ <key>Flow</key>
+ <string>Resize</string>
+ <key>ID</key>
+ <integer>3</integer>
+ <key>Shape</key>
+ <string>Rectangle</string>
+ <key>Text</key>
+ <dict>
+ <key>Text</key>
+ <string>{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf410
+{\fonttbl\f0\fswiss\fcharset77 Helvetica-Bold;}
+{\colortbl;\red255\green255\blue255;}
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc
+
+\f0\b\fs24 \cf0 \ul \ulc0 LifecycleExecutor}</string>
+ </dict>
+ </dict>
+ </array>
+ <key>ID</key>
+ <integer>1</integer>
+ </dict>
+ </array>
+ <key>GridInfo</key>
+ <dict/>
+ <key>HPages</key>
+ <integer>2</integer>
+ <key>IsPalette</key>
+ <string>NO</string>
+ <key>KeepToScale</key>
+ <false/>
+ <key>Layers</key>
+ <array>
+ <dict>
+ <key>Lock</key>
+ <string>NO</string>
+ <key>Name</key>
+ <string>Layer 1</string>
+ <key>Print</key>
+ <string>YES</string>
+ <key>View</key>
+ <string>YES</string>
+ </dict>
+ </array>
+ <key>LayoutInfo</key>
+ <dict>
+ <key>ChildOrdering</key>
+ <integer>0</integer>
+ <key>HierarchicalOrientation</key>
+ <integer>0</integer>
+ </dict>
+ <key>MasterSheet</key>
+ <string>Master 1</string>
+ <key>Orientation</key>
+ <integer>2</integer>
+ <key>OutlineStyle</key>
+ <string>Basic</string>
+ <key>RowAlign</key>
+ <integer>1</integer>
+ <key>RowSpacing</key>
+ <real>36</real>
+ <key>SheetTitle</key>
+ <string>Canvas 2</string>
+ <key>UniqueID</key>
+ <integer>2</integer>
+ <key>VPages</key>
+ <integer>2</integer>
+ </dict>
+ </array>
+ <key>SmartAlignmentGuidesActive</key>
+ <string>YES</string>
+ <key>SmartDistanceGuidesActive</key>
+ <string>YES</string>
+ <key>UseEntirePage</key>
+ <true/>
+ <key>WindowInfo</key>
+ <dict>
+ <key>CurrentSheet</key>
+ <string>0</string>
+ <key>DrawerOpen</key>
+ <false/>
+ <key>DrawerTab</key>
+ <string>Outline</string>
+ <key>DrawerWidth</key>
+ <real>209</real>
+ <key>FitInWindow</key>
+ <false/>
+ <key>Frame</key>
+ <string>{{6, 123}, {956, 590}}</string>
+ <key>ShowRuler</key>
+ <false/>
+ <key>ShowStatusBar</key>
+ <true/>
+ <key>VisibleRegion</key>
+ <string>{{-94, 0}, {941, 476}}</string>
+ <key>Zoom</key>
+ <string>1</string>
+ </dict>
+</dict>
+</plist>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/site/site.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/site/site.xml
new file mode 100644
index 00000000..2c38d2a0
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/site/site.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project xmlns="http://maven.apache.org/DECORATION/1.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/DECORATION/1.0.0 http://maven.apache.org/xsd/decoration-1.0.0.xsd">
+ <body>
+ <menu name="Overview">
+ <item name="Introduction" href="index.html"/>
+ <item name="JavaDocs" href="apidocs/index.html"/>
+ <item name="Source Xref" href="xref/index.html"/>
+ <!--item name="FAQ" href="faq.html"/-->
+ </menu>
+
+ <menu name="Reference">
+ <item name="Lifecycles" href="lifecycles.html"/>
+ <item name="Plugin Bindings to Default Lifecycle" href="default-bindings.html"/>
+ <item name="Artifact Handlers" href="artifact-handlers.html"/>
+ </menu>
+
+ <menu ref="parent"/>
+ <menu ref="reports"/>
+ </body>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/AbstractCoreMavenComponentTestCase.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/AbstractCoreMavenComponentTestCase.java
new file mode 100644
index 00000000..57d374fd
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/AbstractCoreMavenComponentTestCase.java
@@ -0,0 +1,360 @@
+package org.apache.maven;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Properties;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.InvalidRepositoryException;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.execution.DefaultMavenExecutionRequest;
+import org.apache.maven.execution.DefaultMavenExecutionResult;
+import org.apache.maven.execution.MavenExecutionRequest;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.model.Build;
+import org.apache.maven.model.Dependency;
+import org.apache.maven.model.Exclusion;
+import org.apache.maven.model.Model;
+import org.apache.maven.model.Plugin;
+import org.apache.maven.model.Repository;
+import org.apache.maven.model.RepositoryPolicy;
+import org.apache.maven.project.DefaultProjectBuildingRequest;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.project.ProjectBuildingRequest;
+import org.apache.maven.repository.RepositorySystem;
+import org.apache.maven.repository.internal.MavenRepositorySystemUtils;
+import org.codehaus.plexus.ContainerConfiguration;
+import org.codehaus.plexus.PlexusConstants;
+import org.codehaus.plexus.PlexusTestCase;
+import org.codehaus.plexus.component.annotations.Requirement;
+import org.codehaus.plexus.util.FileUtils;
+import org.eclipse.aether.DefaultRepositorySystemSession;
+import org.eclipse.aether.internal.impl.SimpleLocalRepositoryManagerFactory;
+import org.eclipse.aether.repository.LocalRepository;
+
+public abstract class AbstractCoreMavenComponentTestCase
+ extends PlexusTestCase
+{
+ @Requirement
+ protected RepositorySystem repositorySystem;
+
+ @Requirement
+ protected org.apache.maven.project.ProjectBuilder projectBuilder;
+
+ protected void setUp()
+ throws Exception
+ {
+ repositorySystem = lookup( RepositorySystem.class );
+ projectBuilder = lookup( org.apache.maven.project.ProjectBuilder.class );
+ }
+
+ @Override
+ protected void tearDown()
+ throws Exception
+ {
+ repositorySystem = null;
+ projectBuilder = null;
+ super.tearDown();
+ }
+
+ abstract protected String getProjectsDirectory();
+
+ protected File getProject( String name )
+ throws Exception
+ {
+ File source = new File( new File( getBasedir(), getProjectsDirectory() ), name );
+ File target = new File( new File( getBasedir(), "target" ), name );
+ FileUtils.copyDirectoryStructureIfModified( source, target );
+ return new File( target, "pom.xml" );
+ }
+
+ /**
+ * We need to customize the standard Plexus container with the plugin discovery listener which
+ * is what looks for the META-INF/maven/plugin.xml resources that enter the system when a Maven
+ * plugin is loaded.
+ *
+ * We also need to customize the Plexus container with a standard plugin discovery listener
+ * which is the MavenPluginCollector. When a Maven plugin is discovered the MavenPluginCollector
+ * collects the plugin descriptors which are found.
+ */
+ protected void customizeContainerConfiguration( ContainerConfiguration containerConfiguration )
+ {
+ containerConfiguration.setAutoWiring( true ).setClassPathScanning( PlexusConstants.SCANNING_INDEX );
+ }
+
+ protected MavenExecutionRequest createMavenExecutionRequest( File pom )
+ throws Exception
+ {
+ MavenExecutionRequest request = new DefaultMavenExecutionRequest()
+ .setPom( pom )
+ .setProjectPresent( true )
+ .setShowErrors( true )
+ .setPluginGroups( Arrays.asList( "org.apache.maven.plugins" ) )
+ .setLocalRepository( getLocalRepository() )
+ .setRemoteRepositories( getRemoteRepositories() )
+ .setPluginArtifactRepositories( getPluginArtifactRepositories() )
+ .setGoals( Arrays.asList( "package" ) );
+
+ return request;
+ }
+
+ // layer the creation of a project builder configuration with a request, but this will need to be
+ // a Maven subclass because we don't want to couple maven to the project builder which we need to
+ // separate.
+ protected MavenSession createMavenSession( File pom )
+ throws Exception
+ {
+ return createMavenSession( pom, new Properties() );
+ }
+
+ protected MavenSession createMavenSession( File pom, Properties executionProperties )
+ throws Exception
+ {
+ MavenExecutionRequest request = createMavenExecutionRequest( pom );
+
+ ProjectBuildingRequest configuration = new DefaultProjectBuildingRequest()
+ .setLocalRepository( request.getLocalRepository() )
+ .setRemoteRepositories( request.getRemoteRepositories() )
+ .setPluginArtifactRepositories( request.getPluginArtifactRepositories() )
+ .setSystemProperties( executionProperties );
+
+ MavenProject project = null;
+
+ if ( pom != null )
+ {
+ project = projectBuilder.build( pom, configuration ).getProject();
+ }
+ else
+ {
+ project = createStubMavenProject();
+ project.setRemoteArtifactRepositories( request.getRemoteRepositories() );
+ project.setPluginArtifactRepositories( request.getPluginArtifactRepositories() );
+ }
+
+ initRepoSession( configuration );
+
+ MavenSession session =
+ new MavenSession( getContainer(), configuration.getRepositorySession(), request,
+ new DefaultMavenExecutionResult() );
+ session.setProjects( Arrays.asList( project ) );
+
+ return session;
+ }
+
+ protected void initRepoSession( ProjectBuildingRequest request )
+ throws Exception
+ {
+ File localRepoDir = new File( request.getLocalRepository().getBasedir() );
+ LocalRepository localRepo = new LocalRepository( localRepoDir );
+ DefaultRepositorySystemSession session = MavenRepositorySystemUtils.newSession();
+ session.setLocalRepositoryManager( new SimpleLocalRepositoryManagerFactory().newInstance( session, localRepo ) );
+ request.setRepositorySession( session );
+ }
+
+ protected MavenProject createStubMavenProject()
+ {
+ Model model = new Model();
+ model.setGroupId( "org.apache.maven.test" );
+ model.setArtifactId( "maven-test" );
+ model.setVersion( "1.0" );
+ return new MavenProject( model );
+ }
+
+ protected List<ArtifactRepository> getRemoteRepositories()
+ throws InvalidRepositoryException
+ {
+ File repoDir = new File( getBasedir(), "src/test/remote-repo" ).getAbsoluteFile();
+
+ RepositoryPolicy policy = new RepositoryPolicy();
+ policy.setEnabled( true );
+ policy.setChecksumPolicy( "ignore" );
+ policy.setUpdatePolicy( "always" );
+
+ Repository repository = new Repository();
+ repository.setId( RepositorySystem.DEFAULT_REMOTE_REPO_ID );
+ repository.setUrl( "file://" + repoDir.toURI().getPath() );
+ repository.setReleases( policy );
+ repository.setSnapshots( policy );
+
+ return Arrays.asList( repositorySystem.buildArtifactRepository( repository ) );
+ }
+
+ protected List<ArtifactRepository> getPluginArtifactRepositories()
+ throws InvalidRepositoryException
+ {
+ return getRemoteRepositories();
+ }
+
+ protected ArtifactRepository getLocalRepository()
+ throws InvalidRepositoryException
+ {
+ File repoDir = new File( getBasedir(), "target/local-repo" ).getAbsoluteFile();
+
+ return repositorySystem.createLocalRepository( repoDir );
+ }
+
+ protected class ProjectBuilder
+ {
+ private MavenProject project;
+
+ public ProjectBuilder( MavenProject project )
+ {
+ this.project = project;
+ }
+
+ public ProjectBuilder( String groupId, String artifactId, String version )
+ {
+ Model model = new Model();
+ model.setModelVersion( "4.0.0" );
+ model.setGroupId( groupId );
+ model.setArtifactId( artifactId );
+ model.setVersion( version );
+ model.setBuild( new Build() );
+ project = new MavenProject( model );
+ }
+
+ public ProjectBuilder setGroupId( String groupId )
+ {
+ project.setGroupId( groupId );
+ return this;
+ }
+
+ public ProjectBuilder setArtifactId( String artifactId )
+ {
+ project.setArtifactId( artifactId );
+ return this;
+ }
+
+ public ProjectBuilder setVersion( String version )
+ {
+ project.setVersion( version );
+ return this;
+ }
+
+ // Dependencies
+ //
+ public ProjectBuilder addDependency( String groupId, String artifactId, String version, String scope )
+ {
+ return addDependency( groupId, artifactId, version, scope, (Exclusion)null );
+ }
+
+ public ProjectBuilder addDependency( String groupId, String artifactId, String version, String scope, Exclusion exclusion )
+ {
+ return addDependency( groupId, artifactId, version, scope, null, exclusion );
+ }
+
+ public ProjectBuilder addDependency( String groupId, String artifactId, String version, String scope, String systemPath )
+ {
+ return addDependency( groupId, artifactId, version, scope, systemPath, null );
+ }
+
+ public ProjectBuilder addDependency( String groupId, String artifactId, String version, String scope, String systemPath, Exclusion exclusion )
+ {
+ Dependency d = new Dependency();
+ d.setGroupId( groupId );
+ d.setArtifactId( artifactId );
+ d.setVersion( version );
+ d.setScope( scope );
+
+ if ( systemPath != null && scope.equals( Artifact.SCOPE_SYSTEM ) )
+ {
+ d.setSystemPath( systemPath );
+ }
+
+ if ( exclusion != null )
+ {
+ d.addExclusion( exclusion );
+ }
+
+ project.getDependencies().add( d );
+
+ return this;
+ }
+
+ // Plugins
+ //
+ public ProjectBuilder addPlugin( Plugin plugin )
+ {
+ project.getBuildPlugins().add( plugin );
+ return this;
+ }
+
+ public MavenProject get()
+ {
+ return project;
+ }
+ }
+
+ protected class PluginBuilder
+ {
+ private Plugin plugin;
+
+ public PluginBuilder( String groupId, String artifactId, String version )
+ {
+ plugin = new Plugin();
+ plugin.setGroupId( groupId );
+ plugin.setArtifactId( artifactId );
+ plugin.setVersion( version );
+ }
+
+ // Dependencies
+ //
+ public PluginBuilder addDependency( String groupId, String artifactId, String version, String scope, Exclusion exclusion )
+ {
+ return addDependency( groupId, artifactId, version, scope, exclusion );
+ }
+
+ public PluginBuilder addDependency( String groupId, String artifactId, String version, String scope, String systemPath )
+ {
+ return addDependency( groupId, artifactId, version, scope, systemPath, null );
+ }
+
+ public PluginBuilder addDependency( String groupId, String artifactId, String version, String scope, String systemPath, Exclusion exclusion )
+ {
+ Dependency d = new Dependency();
+ d.setGroupId( groupId );
+ d.setArtifactId( artifactId );
+ d.setVersion( version );
+ d.setScope( scope );
+
+ if ( systemPath != null && scope.equals( Artifact.SCOPE_SYSTEM ) )
+ {
+ d.setSystemPath( systemPath );
+ }
+
+ if ( exclusion != null )
+ {
+ d.addExclusion( exclusion );
+ }
+
+ plugin.getDependencies().add( d );
+
+ return this;
+ }
+
+ public Plugin get()
+ {
+ return plugin;
+ }
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/DefaultMavenTest.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/DefaultMavenTest.java
new file mode 100644
index 00000000..ab073a63
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/DefaultMavenTest.java
@@ -0,0 +1,45 @@
+package org.apache.maven;
+
+import org.apache.maven.execution.MavenExecutionRequest;
+import org.apache.maven.execution.MavenExecutionResult;
+
+import static java.util.Arrays.asList;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+public class DefaultMavenTest extends AbstractCoreMavenComponentTestCase{
+
+ public void testThatErrorDuringProjectDependencyGraphCreationAreStored()
+ throws Exception
+ {
+ Maven maven = getContainer().lookup( Maven.class );
+ MavenExecutionRequest request = createMavenExecutionRequest( getProject( "cyclic-reference" ) ).setGoals( asList("validate") );
+
+ MavenExecutionResult result = maven.execute( request );
+
+ assertEquals( ProjectCycleException.class, result.getExceptions().get( 0 ).getClass() );
+ }
+
+ @Override
+ protected String getProjectsDirectory()
+ {
+ return "src/test/projects/default-maven";
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/MavenLifecycleParticipantTest.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/MavenLifecycleParticipantTest.java
new file mode 100644
index 00000000..17aeab31
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/MavenLifecycleParticipantTest.java
@@ -0,0 +1,173 @@
+package org.apache.maven;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.execution.MavenExecutionRequest;
+import org.apache.maven.execution.MavenExecutionResult;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.model.Dependency;
+import org.apache.maven.project.MavenProject;
+import org.codehaus.plexus.PlexusContainer;
+import org.codehaus.plexus.component.repository.ComponentDescriptor;
+
+public class MavenLifecycleParticipantTest
+ extends AbstractCoreMavenComponentTestCase
+{
+
+ private static final String INJECTED_ARTIFACT_ID = "injected";
+
+ public static class InjectDependencyLifecycleListener
+ extends AbstractMavenLifecycleParticipant
+ {
+
+ @Override
+ public void afterProjectsRead( MavenSession session )
+ {
+ MavenProject project = session.getProjects().get( 0 );
+
+ Dependency dependency = new Dependency();
+ dependency.setArtifactId( INJECTED_ARTIFACT_ID );
+ dependency.setGroupId( "foo" );
+ dependency.setVersion( "1.2.3" );
+ dependency.setScope( "system" );
+ try
+ {
+ dependency.setSystemPath( new File(
+ "src/test/projects/lifecycle-executor/project-with-additional-lifecycle-elements/pom.xml" ).getCanonicalPath() );
+ }
+ catch ( IOException e )
+ {
+ throw new RuntimeException( e );
+ }
+
+ project.getModel().addDependency( dependency );
+ }
+
+ @Override
+ public void afterSessionStart( MavenSession session )
+ {
+ session.getUserProperties().setProperty( "injected", "bar" );
+ }
+
+ }
+
+ public static class InjectReactorDependency
+ extends AbstractMavenLifecycleParticipant
+ {
+ @Override
+ public void afterProjectsRead( MavenSession session )
+ {
+ injectReactorDependency( session.getProjects(), "module-a", "module-b" );
+ }
+
+ private void injectReactorDependency( List<MavenProject> projects, String moduleFrom, String moduleTo )
+ {
+ for ( MavenProject project : projects )
+ {
+ if ( moduleFrom.equals( project.getArtifactId() ) )
+ {
+ Dependency dependency = new Dependency();
+ dependency.setArtifactId( moduleTo );
+ dependency.setGroupId( project.getGroupId() );
+ dependency.setVersion( project.getVersion() );
+
+ project.getModel().addDependency( dependency );
+ }
+ }
+ }
+ }
+
+ @Override
+ protected void setupContainer()
+ {
+ super.setupContainer();
+ }
+
+ @Override
+ protected String getProjectsDirectory()
+ {
+ return "src/test/projects/lifecycle-listener";
+ }
+
+ public void testDependencyInjection()
+ throws Exception
+ {
+ PlexusContainer container = getContainer();
+
+ ComponentDescriptor<? extends AbstractMavenLifecycleParticipant> cd =
+ new ComponentDescriptor<InjectDependencyLifecycleListener>( InjectDependencyLifecycleListener.class,
+ container.getContainerRealm() );
+ cd.setRoleClass( AbstractMavenLifecycleParticipant.class );
+ container.addComponentDescriptor( cd );
+
+ Maven maven = container.lookup( Maven.class );
+ File pom = getProject( "lifecycle-listener-dependency-injection" );
+ MavenExecutionRequest request = createMavenExecutionRequest( pom );
+ request.setGoals( Arrays.asList( "validate" ) );
+ MavenExecutionResult result = maven.execute( request );
+
+ assertFalse( result.getExceptions().toString(), result.hasExceptions() );
+
+ MavenProject project = result.getProject();
+
+ assertEquals( "bar", project.getProperties().getProperty( "foo" ) );
+
+ ArrayList<Artifact> artifacts = new ArrayList<Artifact>( project.getArtifacts() );
+
+ assertEquals( 1, artifacts.size() );
+ assertEquals( INJECTED_ARTIFACT_ID, artifacts.get( 0 ).getArtifactId() );
+ }
+
+ public void testReactorDependencyInjection()
+ throws Exception
+ {
+ List<String> reactorOrder =
+ getReactorOrder( "lifecycle-participant-reactor-dependency-injection", InjectReactorDependency.class );
+ assertEquals( Arrays.asList( "parent", "module-b", "module-a" ), reactorOrder );
+ }
+
+ private <T> List<String> getReactorOrder( String testProject, Class<T> participant )
+ throws Exception
+ {
+ PlexusContainer container = getContainer();
+
+ ComponentDescriptor<T> cd = new ComponentDescriptor<T>( participant, container.getContainerRealm() );
+ cd.setRoleClass( AbstractMavenLifecycleParticipant.class );
+ container.addComponentDescriptor( cd );
+
+ Maven maven = container.lookup( Maven.class );
+ File pom = getProject( testProject );
+ MavenExecutionRequest request = createMavenExecutionRequest( pom );
+ request.setGoals( Arrays.asList( "validate" ) );
+ MavenExecutionResult result = maven.execute( request );
+
+ assertFalse( result.getExceptions().toString(), result.hasExceptions() );
+
+ List<String> order = new ArrayList<String>();
+ for ( MavenProject project : result.getTopologicallySortedProjects() )
+ {
+ order.add( project.getArtifactId() );
+ }
+ return order;
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/MavenTest.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/MavenTest.java
new file mode 100644
index 00000000..3e248604
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/MavenTest.java
@@ -0,0 +1,69 @@
+package org.apache.maven;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+
+import org.apache.maven.exception.ExceptionHandler;
+import org.codehaus.plexus.component.annotations.Requirement;
+
+public class MavenTest
+ extends AbstractCoreMavenComponentTestCase
+{
+ @Requirement
+ private Maven maven;
+
+ @Requirement
+ private ExceptionHandler exceptionHandler;
+
+ protected void setUp()
+ throws Exception
+ {
+ super.setUp();
+ maven = lookup( Maven.class );
+ exceptionHandler = lookup( ExceptionHandler.class );
+ }
+
+ @Override
+ protected void tearDown()
+ throws Exception
+ {
+ maven = null;
+ exceptionHandler = null;
+ super.tearDown();
+ }
+
+ protected String getProjectsDirectory()
+ {
+ return "src/test/projects/lifecycle-executor";
+ }
+
+ public void testLifecycleExecutionUsingADefaultLifecyclePhase()
+ throws Exception
+ {
+ /*
+ File pom = getProject( "project-with-additional-lifecycle-elements" );
+ MavenExecutionRequest request = createMavenExecutionRequest( pom );
+ MavenExecutionResult result = maven.execute( request );
+ if ( result.hasExceptions() )
+ {
+ ExceptionSummary es = exceptionHandler.handleException( result.getExceptions().get( 0 ) );
+ System.out.println( es.getMessage() );
+ es.getException().printStackTrace();
+ fail( "Maven did not execute correctly." );
+ }
+ */
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/ProjectDependenciesResolverTest.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/ProjectDependenciesResolverTest.java
new file mode 100644
index 00000000..ca75c3f1
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/ProjectDependenciesResolverTest.java
@@ -0,0 +1,114 @@
+package org.apache.maven;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+import java.io.File;
+import java.util.Collections;
+import java.util.List;
+import java.util.Properties;
+import java.util.Set;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.project.MavenProject;
+import org.codehaus.plexus.component.annotations.Requirement;
+
+public class ProjectDependenciesResolverTest
+ extends AbstractCoreMavenComponentTestCase
+{
+ @Requirement
+ private ProjectDependenciesResolver resolver;
+
+ protected void setUp()
+ throws Exception
+ {
+ super.setUp();
+ resolver = lookup( ProjectDependenciesResolver.class );
+ }
+
+ @Override
+ protected void tearDown()
+ throws Exception
+ {
+ resolver = null;
+ super.tearDown();
+ }
+
+ protected String getProjectsDirectory()
+ {
+ return "src/test/projects/project-dependencies-resolver";
+ }
+
+ /*
+ public void testExclusionsInDependencies()
+ throws Exception
+ {
+ MavenSession session = createMavenSession( null );
+ MavenProject project = session.getCurrentProject();
+
+ Exclusion exclusion = new Exclusion();
+ exclusion.setGroupId( "org.apache.maven.its" );
+ exclusion.setArtifactId( "a" );
+
+ new ProjectBuilder( project ).addDependency( "org.apache.maven.its", "b", "0.1", Artifact.SCOPE_RUNTIME,
+ exclusion );
+
+ Set<Artifact> artifactDependencies =
+ resolver.resolve( project, Collections.singleton( Artifact.SCOPE_COMPILE ), session );
+ assertEquals( 0, artifactDependencies.size() );
+
+ artifactDependencies = resolver.resolve( project, Collections.singleton( Artifact.SCOPE_RUNTIME ), session );
+ assertEquals( 1, artifactDependencies.size() );
+ assertEquals( "b", artifactDependencies.iterator().next().getArtifactId() );
+ }
+ */
+
+ public void testSystemScopeDependencies()
+ throws Exception
+ {
+ MavenSession session = createMavenSession( null );
+ MavenProject project = session.getCurrentProject();
+
+ new ProjectBuilder( project )
+ .addDependency( "com.mycompany", "system-dependency", "1.0", Artifact.SCOPE_SYSTEM, new File( getBasedir(), "pom.xml" ).getAbsolutePath() );
+
+ Set<Artifact> artifactDependencies =
+ resolver.resolve( project, Collections.singleton( Artifact.SCOPE_COMPILE ), session );
+ assertEquals( 1, artifactDependencies.size() );
+ }
+
+ public void testSystemScopeDependencyIsPresentInTheCompileClasspathElements()
+ throws Exception
+ {
+ File pom = getProject( "it0063" );
+
+ Properties eps = new Properties();
+ eps.setProperty( "jre.home", new File( pom.getParentFile(), "jdk/jre" ).getPath() );
+
+ MavenSession session = createMavenSession( pom, eps );
+ MavenProject project = session.getCurrentProject();
+
+ project.setArtifacts( resolver.resolve( project, Collections.singleton( Artifact.SCOPE_COMPILE ), session ) );
+
+ List<String> elements = project.getCompileClasspathElements();
+ assertEquals( 2, elements.size() );
+
+ @SuppressWarnings( "deprecation" )
+ List<Artifact> artifacts = project.getCompileArtifacts();
+ assertEquals( 1, artifacts.size() );
+ assertTrue( artifacts.get( 0 ).getFile().getName().endsWith( "tools.jar" ) );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/artifact/handler/ArtifactHandlerTest.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/artifact/handler/ArtifactHandlerTest.java
new file mode 100644
index 00000000..ac02e106
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/artifact/handler/ArtifactHandlerTest.java
@@ -0,0 +1,89 @@
+package org.apache.maven.artifact.handler;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.util.List;
+
+import org.codehaus.plexus.PlexusTestCase;
+import org.codehaus.plexus.util.FileUtils;
+
+public class ArtifactHandlerTest
+ extends PlexusTestCase
+{
+ public void testAptConsistency()
+ throws Exception
+ {
+ File apt = getTestFile( "src/site/apt/artifact-handlers.apt" );
+
+ @SuppressWarnings( "unchecked" )
+ List<String> lines = FileUtils.loadFile( apt );
+
+ for ( String line : lines )
+ {
+ if ( line.startsWith( "||" ) )
+ {
+ String[] cols = line.split( "\\|\\|" );
+ String[] expected =
+ new String[] { "", "type", "extension", "packaging", "classifier", "language", "added to classpath",
+ "includesDependencies", "" };
+
+ int i = 0;
+ for ( String col : cols )
+ {
+ assertEquals( "Wrong column header", expected[i++], col.trim() );
+ }
+ }
+ else if ( line.startsWith( "|" ) )
+ {
+ String[] cols = line.split( "\\|" );
+
+ String type = trimApt( cols[1] );
+ String extension = trimApt( cols[2], type );
+ String packaging = trimApt( cols[3], type );
+ String classifier = trimApt( cols[4] );
+ String language = trimApt( cols[5] );
+ String addedToClasspath = trimApt( cols[6] );
+ String includesDependencies = trimApt( cols[7] );
+
+ ArtifactHandler handler = lookup( ArtifactHandler.class, type );
+ assertEquals( type + " extension", handler.getExtension(), extension );
+ assertEquals( type + " packaging", handler.getPackaging(), packaging );
+ assertEquals( type + " classifier", handler.getClassifier(), classifier );
+ assertEquals( type + " language", handler.getLanguage(), language );
+ assertEquals( type + " addedToClasspath", handler.isAddedToClasspath() ? "true" : null, addedToClasspath );
+ assertEquals( type + " includesDependencies", handler.isIncludesDependencies() ? "true" : null, includesDependencies );
+ }
+ }
+ }
+
+ private String trimApt( String content, String type )
+ {
+ String value = trimApt( content );
+ return "= type".equals( value ) ? type : value;
+ }
+
+ private String trimApt( String content )
+ {
+ content = content.replace( '<', ' ' ).replace( '>', ' ' ).trim();
+
+ return ( content.length() == 0 ) ? null : content;
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/configuration/DefaultBeanConfiguratorTest.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/configuration/DefaultBeanConfiguratorTest.java
new file mode 100644
index 00000000..33673e3b
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/configuration/DefaultBeanConfiguratorTest.java
@@ -0,0 +1,148 @@
+package org.apache.maven.configuration;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.io.StringReader;
+
+import org.codehaus.plexus.PlexusTestCase;
+import org.codehaus.plexus.util.xml.Xpp3Dom;
+import org.codehaus.plexus.util.xml.Xpp3DomBuilder;
+import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
+
+/**
+ * @author Benjamin Bentmann
+ */
+public class DefaultBeanConfiguratorTest
+ extends PlexusTestCase
+{
+
+ private BeanConfigurator configurator;
+
+ @Override
+ protected void setUp()
+ throws Exception
+ {
+ super.setUp();
+
+ configurator = lookup( BeanConfigurator.class );
+ }
+
+ @Override
+ protected void tearDown()
+ throws Exception
+ {
+ configurator = null;
+
+ super.tearDown();
+ }
+
+ private Xpp3Dom toConfig( String xml )
+ {
+ try
+ {
+ return Xpp3DomBuilder.build( new StringReader( "<configuration>" + xml + "</configuration>" ) );
+ }
+ catch ( XmlPullParserException e )
+ {
+ throw new IllegalArgumentException( e );
+ }
+ catch ( IOException e )
+ {
+ throw new IllegalArgumentException( e );
+ }
+ }
+
+ public void testMinimal()
+ throws BeanConfigurationException
+ {
+ SomeBean bean = new SomeBean();
+
+ Xpp3Dom config = toConfig( "<file>test</file>" );
+
+ DefaultBeanConfigurationRequest request = new DefaultBeanConfigurationRequest();
+ request.setBean( bean ).setConfiguration( config );
+
+ configurator.configureBean( request );
+
+ assertEquals( new File( "test" ), bean.file );
+ }
+
+ public void testPreAndPostProcessing()
+ throws BeanConfigurationException
+ {
+ SomeBean bean = new SomeBean();
+
+ Xpp3Dom config = toConfig( "<file>${test}</file>" );
+
+ BeanConfigurationValuePreprocessor preprocessor = new BeanConfigurationValuePreprocessor()
+ {
+ public Object preprocessValue( String value, Class<?> type )
+ throws BeanConfigurationException
+ {
+ if ( value != null && value.startsWith( "${" ) && value.endsWith( "}" ) )
+ {
+ return value.substring( 2, value.length() - 1 );
+ }
+ return value;
+ }
+ };
+
+ BeanConfigurationPathTranslator translator = new BeanConfigurationPathTranslator()
+ {
+ public File translatePath( File path )
+ {
+ return new File( "base", path.getPath() ).getAbsoluteFile();
+ }
+ };
+
+ DefaultBeanConfigurationRequest request = new DefaultBeanConfigurationRequest();
+ request.setBean( bean ).setConfiguration( config );
+ request.setValuePreprocessor( preprocessor ).setPathTranslator( translator );
+
+ configurator.configureBean( request );
+
+ assertEquals( new File( "base/test" ).getAbsoluteFile(), bean.file );
+ }
+
+ public void testChildConfigurationElement()
+ throws BeanConfigurationException
+ {
+ SomeBean bean = new SomeBean();
+
+ Xpp3Dom config = toConfig( "<wrapper><file>test</file></wrapper>" );
+
+ DefaultBeanConfigurationRequest request = new DefaultBeanConfigurationRequest();
+ request.setBean( bean ).setConfiguration( config, "wrapper" );
+
+ configurator.configureBean( request );
+
+ assertEquals( new File( "test" ), bean.file );
+ }
+
+ static class SomeBean
+ {
+
+ File file;
+
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/exception/DefaultExceptionHandlerTest.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/exception/DefaultExceptionHandlerTest.java
new file mode 100644
index 00000000..9727bdf8
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/exception/DefaultExceptionHandlerTest.java
@@ -0,0 +1,60 @@
+package org.apache.maven.exception;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.IOException;
+import java.net.ConnectException;
+
+import org.apache.maven.plugin.MojoExecutionException;
+
+import junit.framework.TestCase;
+
+/**
+ * @author <a href="mailto:baerrach@apache.org">Barrie Treloar</a>
+ */
+public class DefaultExceptionHandlerTest
+ extends TestCase
+{
+ /**
+ * Running Maven under JDK7 may cause connection issues because IPv6 is used by default.
+ * <p>
+ * e.g running mvn site:run will cause Jetty to fail.
+ * </p>
+ * <p>
+ * The resolution is to add -Djava.net.preferIPv4Stack=true to the command line as documented in
+ * http://cwiki.apache.org/confluence/display/MAVEN/ConnectException
+ * </p>
+ */
+ public void testJdk7ipv6()
+ {
+ ConnectException connEx = new ConnectException( "Connection refused: connect" );
+ IOException ioEx = new IOException( "Unable to establish loopback connection" );
+ ioEx.initCause( connEx );
+ MojoExecutionException mojoEx =
+ new MojoExecutionException( "Error executing Jetty: Unable to establish loopback connection", ioEx );
+
+ ExceptionHandler exceptionHandler = new DefaultExceptionHandler();
+ ExceptionSummary exceptionSummary = exceptionHandler.handleException( mojoEx );
+
+ String expectedReference = "http://cwiki.apache.org/confluence/display/MAVEN/ConnectException";
+ assertEquals( expectedReference, exceptionSummary.getReference() );
+
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/execution/DefaultMavenExecutionRequestPopulatorTest.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/execution/DefaultMavenExecutionRequestPopulatorTest.java
new file mode 100644
index 00000000..15a7a7b3
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/execution/DefaultMavenExecutionRequestPopulatorTest.java
@@ -0,0 +1,62 @@
+package org.apache.maven.execution;
+
+import java.util.List;
+
+import javax.inject.Inject;
+
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.settings.Profile;
+import org.apache.maven.settings.Repository;
+import org.apache.maven.settings.Settings;
+import org.eclipse.sisu.launch.InjectedTestCase;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+public class DefaultMavenExecutionRequestPopulatorTest
+ extends InjectedTestCase
+{
+ @Inject
+ MavenExecutionRequestPopulator testee;
+
+ public void testPluginRepositoryInjection()
+ throws Exception
+ {
+ MavenExecutionRequest request = new DefaultMavenExecutionRequest();
+
+ Repository r = new Repository();
+ r.setId( "test" );
+ r.setUrl( "file:///test" );
+
+ Profile p = new Profile();
+ p.setId( "test" );
+ p.addPluginRepository( r );
+
+ Settings settings = new Settings();
+ settings.addProfile( p );
+ settings.addActiveProfile( p.getId() );
+
+ testee.populateFromSettings( request, settings );
+
+ List<ArtifactRepository> repositories = request.getPluginArtifactRepositories();
+ assertEquals( 1, repositories.size() );
+ assertEquals( r.getId(), repositories.get( 0 ).getId() );
+ assertEquals( r.getUrl(), repositories.get( 0 ).getUrl() );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/execution/DefaultMavenExecutionTest.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/execution/DefaultMavenExecutionTest.java
new file mode 100644
index 00000000..fbb8b900
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/execution/DefaultMavenExecutionTest.java
@@ -0,0 +1,52 @@
+package org.apache.maven.execution;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.project.MavenProject;
+
+import java.util.List;
+
+import junit.framework.TestCase;
+
+/**
+ * @author Benjamin Bentmann
+ */
+public class DefaultMavenExecutionTest
+ extends TestCase
+{
+
+ public void testCopyDefault()
+ {
+ MavenExecutionRequest original = new DefaultMavenExecutionRequest();
+ MavenExecutionRequest copy = DefaultMavenExecutionRequest.copy( original );
+ assertNotNull( copy );
+ assertNotSame( copy, original );
+ }
+
+ public void testResultWithNullTopologicallySortedProjectsIsEmptyList()
+ {
+ MavenExecutionResult result = new DefaultMavenExecutionResult();
+ result.setTopologicallySortedProjects( null );
+ List<MavenProject> projects = result.getTopologicallySortedProjects();
+ assertNotNull( projects );
+ assertTrue( projects.isEmpty() );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/execution/scope/internal/MojoExecutionScopeTest.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/execution/scope/internal/MojoExecutionScopeTest.java
new file mode 100644
index 00000000..a4eb354c
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/execution/scope/internal/MojoExecutionScopeTest.java
@@ -0,0 +1,122 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.maven.execution.scope.internal;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.maven.execution.MojoExecutionEvent;
+import org.apache.maven.execution.scope.WeakMojoExecutionListener;
+import org.apache.maven.plugin.MojoExecutionException;
+
+import junit.framework.TestCase;
+
+import com.google.inject.Key;
+import com.google.inject.Provider;
+
+public class MojoExecutionScopeTest
+ extends TestCase
+{
+ public void testNestedEnter()
+ throws Exception
+ {
+ MojoExecutionScope scope = new MojoExecutionScope();
+
+ scope.enter();
+
+ Object o1 = new Object();
+ scope.seed( Object.class, o1 );
+ assertSame( o1, scope.scope( Key.get( Object.class ), null ).get() );
+
+ scope.enter();
+ Object o2 = new Object();
+ scope.seed( Object.class, o2 );
+ assertSame( o2, scope.scope( Key.get( Object.class ), null ).get() );
+
+ scope.exit();
+ assertSame( o1, scope.scope( Key.get( Object.class ), null ).get() );
+
+ scope.exit();
+
+ try
+ {
+ scope.exit();
+ fail();
+ }
+ catch ( IllegalStateException expected )
+ {
+ }
+ }
+
+ public void testMultiKeyInstance()
+ throws Exception
+ {
+ MojoExecutionScope scope = new MojoExecutionScope();
+ scope.enter();
+
+ final AtomicInteger beforeExecution = new AtomicInteger();
+ final AtomicInteger afterExecutionSuccess = new AtomicInteger();
+ final AtomicInteger afterExecutionFailure = new AtomicInteger();
+ final WeakMojoExecutionListener instance = new WeakMojoExecutionListener()
+ {
+ @Override
+ public void beforeMojoExecution( MojoExecutionEvent event )
+ throws MojoExecutionException
+ {
+ beforeExecution.incrementAndGet();
+ }
+
+ @Override
+ public void afterMojoExecutionSuccess( MojoExecutionEvent event )
+ throws MojoExecutionException
+ {
+ afterExecutionSuccess.incrementAndGet();
+ }
+
+ @Override
+ public void afterExecutionFailure( MojoExecutionEvent event )
+ {
+ afterExecutionFailure.incrementAndGet();
+ }
+ };
+ assertSame( instance, scope.scope( Key.get( Object.class ), new Provider<Object>()
+ {
+ @Override
+ public Object get()
+ {
+ return instance;
+ }
+ } ).get() );
+ assertSame( instance,
+ scope.scope( Key.get( WeakMojoExecutionListener.class ), new Provider<WeakMojoExecutionListener>()
+ {
+ @Override
+ public WeakMojoExecutionListener get()
+ {
+ return instance;
+ }
+ } ).get() );
+
+ final MojoExecutionEvent event = new MojoExecutionEvent( null, null, null, null );
+ scope.beforeMojoExecution( event );
+ scope.afterMojoExecutionSuccess( event );
+ scope.afterExecutionFailure( event );
+
+ assertEquals( 1, beforeExecution.get() );
+ assertEquals( 1, afterExecutionSuccess.get() );
+ assertEquals( 1, afterExecutionFailure.get() );
+
+ scope.exit();
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/graph/DefaultProjectDependencyGraphTest.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/graph/DefaultProjectDependencyGraphTest.java
new file mode 100644
index 00000000..e2caaeb1
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/graph/DefaultProjectDependencyGraphTest.java
@@ -0,0 +1,172 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.maven.graph;
+
+import junit.framework.TestCase;
+import org.apache.maven.execution.ProjectDependencyGraph;
+import org.apache.maven.model.Dependency;
+import org.apache.maven.project.DuplicateProjectException;
+import org.apache.maven.project.MavenProject;
+import org.codehaus.plexus.util.dag.CycleDetectedException;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * @author Kristian Rosenvold
+ */
+public class DefaultProjectDependencyGraphTest
+ extends TestCase
+{
+
+ private final MavenProject aProject = createA();
+
+ private final MavenProject depender1 = createProject( Arrays.asList( toDependency( aProject ) ), "depender1" );
+
+ private final MavenProject depender2 = createProject( Arrays.asList( toDependency( aProject ) ), "depender2" );
+
+ private final MavenProject depender3 = createProject( Arrays.asList( toDependency( aProject ) ), "depender3" );
+
+ private final MavenProject depender4 =
+ createProject( Arrays.asList( toDependency( aProject ), toDependency( depender3 ) ), "depender4" );
+
+ private final MavenProject transitiveOnly =
+ createProject( Arrays.asList( toDependency( depender3 ) ), "depender5" );
+
+ public void testGetSortedProjects()
+ throws DuplicateProjectException, CycleDetectedException
+ {
+ ProjectDependencyGraph graph = new DefaultProjectDependencyGraph( Arrays.asList( depender1, aProject ) );
+ final List<MavenProject> sortedProjects = graph.getSortedProjects();
+ assertEquals( aProject, sortedProjects.get( 0 ) );
+ assertEquals( depender1, sortedProjects.get( 1 ) );
+ }
+
+ public void testVerifyExpectedParentStructure()
+ throws CycleDetectedException, DuplicateProjectException
+ {
+ // This test verifies the baseline structure used in susequent tests. If this fails, the rest will fail.
+ ProjectDependencyGraph graph = threeProjectsDependingOnASingle();
+ final List<MavenProject> sortedProjects = graph.getSortedProjects();
+ assertEquals( aProject, sortedProjects.get( 0 ) );
+ assertEquals( depender1, sortedProjects.get( 1 ) );
+ assertEquals( depender2, sortedProjects.get( 2 ) );
+ assertEquals( depender3, sortedProjects.get( 3 ) );
+ }
+
+ public void testVerifyThatDownsteamProjectsComeInSortedOrder()
+ throws CycleDetectedException, DuplicateProjectException
+ {
+ final List<MavenProject> downstreamProjects =
+ threeProjectsDependingOnASingle().getDownstreamProjects( aProject, true );
+ assertEquals( depender1, downstreamProjects.get( 0 ) );
+ assertEquals( depender2, downstreamProjects.get( 1 ) );
+ assertEquals( depender3, downstreamProjects.get( 2 ) );
+ }
+
+ public void testTransitivesInOrder()
+ throws CycleDetectedException, DuplicateProjectException
+ {
+ final ProjectDependencyGraph graph =
+ new DefaultProjectDependencyGraph( Arrays.asList( depender1, depender4, depender2, depender3, aProject ) );
+
+ final List<MavenProject> downstreamProjects = graph.getDownstreamProjects( aProject, true );
+ assertEquals( depender1, downstreamProjects.get( 0 ) );
+ assertEquals( depender3, downstreamProjects.get( 1 ) );
+ assertEquals( depender4, downstreamProjects.get( 2 ) );
+ assertEquals( depender2, downstreamProjects.get( 3 ) );
+ }
+
+ public void testNonTransitivesInOrder()
+ throws CycleDetectedException, DuplicateProjectException
+ {
+ final ProjectDependencyGraph graph =
+ new DefaultProjectDependencyGraph( Arrays.asList( depender1, depender4, depender2, depender3, aProject ) );
+
+ final List<MavenProject> downstreamProjects = graph.getDownstreamProjects( aProject, false );
+ assertEquals( depender1, downstreamProjects.get( 0 ) );
+ assertEquals( depender3, downstreamProjects.get( 1 ) );
+ assertEquals( depender4, downstreamProjects.get( 2 ) );
+ assertEquals( depender2, downstreamProjects.get( 3 ) );
+ }
+
+ public void testWithTranistiveOnly()
+ throws CycleDetectedException, DuplicateProjectException
+ {
+ final ProjectDependencyGraph graph = new DefaultProjectDependencyGraph(
+ Arrays.asList( depender1, transitiveOnly, depender2, depender3, aProject ) );
+
+ final List<MavenProject> downstreamProjects = graph.getDownstreamProjects( aProject, true );
+ assertEquals( depender1, downstreamProjects.get( 0 ) );
+ assertEquals( depender3, downstreamProjects.get( 1 ) );
+ assertEquals( transitiveOnly, downstreamProjects.get( 2 ) );
+ assertEquals( depender2, downstreamProjects.get( 3 ) );
+ }
+
+ public void testWithMissingTranistiveOnly()
+ throws CycleDetectedException, DuplicateProjectException
+ {
+ final ProjectDependencyGraph graph = new DefaultProjectDependencyGraph(
+ Arrays.asList( depender1, transitiveOnly, depender2, depender3, aProject ) );
+
+ final List<MavenProject> downstreamProjects = graph.getDownstreamProjects( aProject, false );
+ assertEquals( depender1, downstreamProjects.get( 0 ) );
+ assertEquals( depender3, downstreamProjects.get( 1 ) );
+ assertEquals( depender2, downstreamProjects.get( 2 ) );
+ }
+
+ public void testGetUpstreamProjects()
+ throws CycleDetectedException, DuplicateProjectException
+ {
+ ProjectDependencyGraph graph = threeProjectsDependingOnASingle();
+ final List<MavenProject> downstreamProjects = graph.getUpstreamProjects( depender1, true );
+ assertEquals( aProject, downstreamProjects.get( 0 ) );
+ }
+
+ private ProjectDependencyGraph threeProjectsDependingOnASingle()
+ throws CycleDetectedException, DuplicateProjectException
+ {
+ return new DefaultProjectDependencyGraph( Arrays.asList( depender1, depender2, depender3, aProject ) );
+ }
+
+ private static MavenProject createA()
+ {
+ MavenProject result = new MavenProject();
+ result.setGroupId( "org.apache" );
+ result.setArtifactId( "A" );
+ result.setVersion( "1.2" );
+ return result;
+ }
+
+ static Dependency toDependency( MavenProject mavenProject )
+ {
+ final Dependency dependency = new Dependency();
+ dependency.setArtifactId( mavenProject.getArtifactId() );
+ dependency.setGroupId( mavenProject.getGroupId() );
+ dependency.setVersion( mavenProject.getVersion() );
+ return dependency;
+ }
+
+ private static MavenProject createProject( List<Dependency> dependencies, String artifactId )
+ {
+ MavenProject result = new MavenProject();
+ result.setGroupId( "org.apache" );
+ result.setArtifactId( artifactId );
+ result.setVersion( "1.2" );
+ result.setDependencies( dependencies );
+ return result;
+ }
+
+} \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/DefaultLifecyclesTest.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/DefaultLifecyclesTest.java
new file mode 100644
index 00000000..690532c7
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/DefaultLifecyclesTest.java
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.maven.lifecycle;
+
+import org.codehaus.plexus.PlexusTestCase;
+import org.codehaus.plexus.component.annotations.Requirement;
+
+import java.util.List;
+
+/**
+ * @author Kristian Rosenvold
+ */
+
+public class DefaultLifecyclesTest
+ extends PlexusTestCase
+{
+ @Requirement
+ private DefaultLifecycles defaultLifeCycles;
+
+
+ protected void setUp()
+ throws Exception
+ {
+ super.setUp();
+ defaultLifeCycles = lookup( DefaultLifecycles.class );
+ }
+
+ @Override
+ protected void tearDown()
+ throws Exception
+ {
+ defaultLifeCycles = null;
+ super.tearDown();
+ }
+
+ public void testLifecycle()
+ throws Exception
+ {
+ final List<Lifecycle> cycles = defaultLifeCycles.getLifeCycles();
+ assertNotNull( cycles );
+ final Lifecycle lifecycle = cycles.get( 0 );
+ assertEquals( "default", lifecycle.getId() );
+ assertEquals( 23, lifecycle.getPhases().size() );
+
+ }
+
+} \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/DelegatingMojoExecutionListener.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/DelegatingMojoExecutionListener.java
new file mode 100644
index 00000000..873cc7da
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/DelegatingMojoExecutionListener.java
@@ -0,0 +1,75 @@
+package org.apache.maven.lifecycle;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import org.apache.maven.execution.MojoExecutionEvent;
+import org.apache.maven.execution.MojoExecutionListener;
+import org.apache.maven.plugin.MojoExecutionException;
+
+@Named
+@Singleton
+public class DelegatingMojoExecutionListener
+ implements MojoExecutionListener
+{
+ private final List<MojoExecutionListener> listeners = new CopyOnWriteArrayList<MojoExecutionListener>();
+
+ public void beforeMojoExecution( MojoExecutionEvent event )
+ throws MojoExecutionException
+ {
+ for ( MojoExecutionListener listener : listeners )
+ {
+ listener.beforeMojoExecution( event );
+ }
+ }
+
+ public void afterMojoExecutionSuccess( MojoExecutionEvent event )
+ throws MojoExecutionException
+ {
+ for ( MojoExecutionListener listener : listeners )
+ {
+ listener.afterMojoExecutionSuccess( event );
+ }
+ }
+
+ public void afterExecutionFailure( MojoExecutionEvent event )
+ {
+ for ( MojoExecutionListener listener : listeners )
+ {
+ listener.afterExecutionFailure( event );
+ }
+ }
+
+ public void addMojoExecutionListener( MojoExecutionListener listener )
+ {
+ this.listeners.add( listener );
+ }
+
+ public void removeMojoExecutionListener( MojoExecutionListener listener )
+ {
+ this.listeners.remove( listener );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/DelegatingProjectExecutionListener.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/DelegatingProjectExecutionListener.java
new file mode 100644
index 00000000..233ae256
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/DelegatingProjectExecutionListener.java
@@ -0,0 +1,82 @@
+package org.apache.maven.lifecycle;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import org.apache.maven.execution.ProjectExecutionEvent;
+import org.apache.maven.execution.ProjectExecutionListener;
+
+@Named
+@Singleton
+public class DelegatingProjectExecutionListener
+ implements ProjectExecutionListener
+{
+ private final List<ProjectExecutionListener> listeners = new CopyOnWriteArrayList<ProjectExecutionListener>();
+
+ public void beforeProjectExecution( ProjectExecutionEvent event )
+ throws LifecycleExecutionException
+ {
+ for ( ProjectExecutionListener listener : listeners )
+ {
+ listener.beforeProjectExecution( event );
+ }
+ }
+
+ public void beforeProjectLifecycleExecution( ProjectExecutionEvent event )
+ throws LifecycleExecutionException
+ {
+ for ( ProjectExecutionListener listener : listeners )
+ {
+ listener.beforeProjectLifecycleExecution( event );
+ }
+ }
+
+ public void afterProjectExecutionSuccess( ProjectExecutionEvent event )
+ throws LifecycleExecutionException
+ {
+ for ( ProjectExecutionListener listener : listeners )
+ {
+ listener.afterProjectExecutionSuccess( event );
+ }
+ }
+
+ public void afterProjectExecutionFailure( ProjectExecutionEvent event )
+ {
+ for ( ProjectExecutionListener listener : listeners )
+ {
+ listener.afterProjectExecutionFailure( event );
+ }
+ }
+
+ public void addProjectExecutionListener( ProjectExecutionListener listener )
+ {
+ this.listeners.add( listener );
+ }
+
+ public void removeProjectExecutionListener( ProjectExecutionListener listener )
+ {
+ this.listeners.remove( listener );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/EmptyLifecyclePluginAnalyzer.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/EmptyLifecyclePluginAnalyzer.java
new file mode 100644
index 00000000..f9bbb2ba
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/EmptyLifecyclePluginAnalyzer.java
@@ -0,0 +1,77 @@
+package org.apache.maven.lifecycle;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Collections;
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+import org.apache.maven.model.Plugin;
+import org.apache.maven.model.PluginExecution;
+
+/**
+ * @author Benjamin Bentmann
+ */
+public class EmptyLifecyclePluginAnalyzer
+ implements LifeCyclePluginAnalyzer
+{
+ public Set<Plugin> getPluginsBoundByDefaultToAllLifecycles( String packaging )
+ {
+ Set<Plugin> plugins;
+
+ // NOTE: The upper-case packaging name is intentional, that's a special hinting mode used for certain tests
+ if ( "JAR".equals( packaging ) )
+ {
+ plugins = new LinkedHashSet<Plugin>();
+
+ plugins.add( newPlugin( "maven-compiler-plugin", "compile", "testCompile" ) );
+ plugins.add( newPlugin( "maven-resources-plugin", "resources", "testResources" ) );
+ plugins.add( newPlugin( "maven-surefire-plugin", "test" ) );
+ plugins.add( newPlugin( "maven-jar-plugin", "jar" ) );
+ plugins.add( newPlugin( "maven-install-plugin", "install" ) );
+ plugins.add( newPlugin( "maven-deploy-plugin", "deploy" ) );
+ }
+ else
+ {
+ plugins = Collections.emptySet();
+ }
+
+ return plugins;
+ }
+
+ private Plugin newPlugin( String artifactId, String... goals )
+ {
+ Plugin plugin = new Plugin();
+
+ plugin.setGroupId( "org.apache.maven.plugins" );
+ plugin.setArtifactId( artifactId );
+
+ for ( String goal : goals )
+ {
+ PluginExecution pluginExecution = new PluginExecution();
+ pluginExecution.setId( "default-" + goal );
+ pluginExecution.addGoal( goal );
+ plugin.addExecution( pluginExecution );
+ }
+
+ return plugin;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/LifecycleExecutorSubModulesTest.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/LifecycleExecutorSubModulesTest.java
new file mode 100644
index 00000000..01ebeac0
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/LifecycleExecutorSubModulesTest.java
@@ -0,0 +1,98 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+
+package org.apache.maven.lifecycle;
+
+import org.apache.maven.AbstractCoreMavenComponentTestCase;
+import org.apache.maven.exception.ExceptionHandler;
+import org.apache.maven.lifecycle.internal.LifecycleDependencyResolver;
+import org.apache.maven.lifecycle.internal.LifecycleExecutionPlanCalculator;
+import org.apache.maven.lifecycle.internal.LifecycleModuleBuilder;
+import org.apache.maven.lifecycle.internal.LifecycleTaskSegmentCalculator;
+import org.apache.maven.lifecycle.internal.MojoExecutor;
+import org.codehaus.plexus.component.annotations.Requirement;
+
+/**
+ * Just asserts that it's able to create those components. Handy when plexus gets a nervous breakdown.
+ *
+ * @author Kristian Rosenvold
+ */
+
+public class LifecycleExecutorSubModulesTest
+ extends AbstractCoreMavenComponentTestCase
+{
+ @Requirement
+ private DefaultLifecycles defaultLifeCycles;
+
+ @Requirement
+ private MojoExecutor mojoExecutor;
+
+ @Requirement
+ private LifecycleModuleBuilder lifeCycleBuilder;
+
+ @Requirement
+ private LifecycleDependencyResolver lifeCycleDependencyResolver;
+
+ @Requirement
+ private LifecycleExecutionPlanCalculator lifeCycleExecutionPlanCalculator;
+
+ @Requirement
+ private LifeCyclePluginAnalyzer lifeCyclePluginAnalyzer;
+
+ @Requirement
+ private LifecycleTaskSegmentCalculator lifeCycleTaskSegmentCalculator;
+
+
+ protected void setUp()
+ throws Exception
+ {
+ super.setUp();
+ defaultLifeCycles = lookup( DefaultLifecycles.class );
+ mojoExecutor = lookup( MojoExecutor.class );
+ lifeCycleBuilder = lookup( LifecycleModuleBuilder.class );
+ lifeCycleDependencyResolver = lookup( LifecycleDependencyResolver.class );
+ lifeCycleExecutionPlanCalculator = lookup( LifecycleExecutionPlanCalculator.class );
+ lifeCyclePluginAnalyzer = lookup( LifeCyclePluginAnalyzer.class );
+ lifeCycleTaskSegmentCalculator = lookup( LifecycleTaskSegmentCalculator.class );
+ lookup( ExceptionHandler.class );
+ }
+
+ @Override
+ protected void tearDown()
+ throws Exception
+ {
+ defaultLifeCycles = null;
+ super.tearDown();
+ }
+
+ protected String getProjectsDirectory()
+ {
+ return "src/test/projects/lifecycle-executor";
+ }
+
+ public void testCrweation()
+ throws Exception
+ {
+ assertNotNull( defaultLifeCycles );
+ assertNotNull( mojoExecutor );
+ assertNotNull( lifeCycleBuilder );
+ assertNotNull( lifeCycleDependencyResolver );
+ assertNotNull( lifeCycleExecutionPlanCalculator );
+ assertNotNull( lifeCyclePluginAnalyzer );
+ assertNotNull( lifeCycleTaskSegmentCalculator );
+ }
+
+} \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/LifecycleExecutorTest.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/LifecycleExecutorTest.java
new file mode 100644
index 00000000..99b07e34
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/LifecycleExecutorTest.java
@@ -0,0 +1,553 @@
+package org.apache.maven.lifecycle;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.maven.AbstractCoreMavenComponentTestCase;
+import org.apache.maven.exception.ExceptionHandler;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.execution.MojoExecutionEvent;
+import org.apache.maven.execution.MojoExecutionListener;
+import org.apache.maven.execution.ProjectDependencyGraph;
+import org.apache.maven.execution.ProjectExecutionEvent;
+import org.apache.maven.execution.ProjectExecutionListener;
+import org.apache.maven.lifecycle.internal.DefaultLifecycleTaskSegmentCalculator;
+import org.apache.maven.lifecycle.internal.ExecutionPlanItem;
+import org.apache.maven.lifecycle.internal.LifecycleExecutionPlanCalculator;
+import org.apache.maven.lifecycle.internal.LifecycleTask;
+import org.apache.maven.lifecycle.internal.LifecycleTaskSegmentCalculator;
+import org.apache.maven.lifecycle.internal.MojoDescriptorCreator;
+import org.apache.maven.lifecycle.internal.TaskSegment;
+import org.apache.maven.model.Plugin;
+import org.apache.maven.plugin.MojoExecution;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoNotFoundException;
+import org.apache.maven.plugin.descriptor.MojoDescriptor;
+import org.apache.maven.project.MavenProject;
+import org.codehaus.plexus.component.annotations.Requirement;
+import org.codehaus.plexus.util.xml.Xpp3Dom;
+
+public class LifecycleExecutorTest
+ extends AbstractCoreMavenComponentTestCase
+{
+ @Requirement
+ private DefaultLifecycleExecutor lifecycleExecutor;
+
+ @Requirement
+ private DefaultLifecycleTaskSegmentCalculator lifeCycleTaskSegmentCalculator;
+
+ @Requirement
+ private LifecycleExecutionPlanCalculator lifeCycleExecutionPlanCalculator;
+
+ @Requirement
+ private MojoDescriptorCreator mojoDescriptorCreator;
+
+
+ protected void setUp()
+ throws Exception
+ {
+ super.setUp();
+ lifecycleExecutor = (DefaultLifecycleExecutor) lookup( LifecycleExecutor.class );
+ lifeCycleTaskSegmentCalculator =
+ (DefaultLifecycleTaskSegmentCalculator) lookup( LifecycleTaskSegmentCalculator.class );
+ lifeCycleExecutionPlanCalculator = lookup( LifecycleExecutionPlanCalculator.class );
+ mojoDescriptorCreator = lookup( MojoDescriptorCreator.class );
+ lookup( ExceptionHandler.class );
+ }
+
+ @Override
+ protected void tearDown()
+ throws Exception
+ {
+ lifecycleExecutor = null;
+ super.tearDown();
+ }
+
+ protected String getProjectsDirectory()
+ {
+ return "src/test/projects/lifecycle-executor";
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Tests which exercise the lifecycle executor when it is dealing with default lifecycle phases.
+ // -----------------------------------------------------------------------------------------------
+
+ public void testCalculationOfBuildPlanWithIndividualTaskWherePluginIsSpecifiedInThePom()
+ throws Exception
+ {
+ // We are doing something like "mvn resources:resources" where no version is specified but this
+ // project we are working on has the version specified in the POM so the version should come from there.
+ File pom = getProject( "project-basic" );
+ MavenSession session = createMavenSession( pom );
+ assertEquals( "project-basic", session.getCurrentProject().getArtifactId() );
+ assertEquals( "1.0", session.getCurrentProject().getVersion() );
+ List<MojoExecution> executionPlan = getExecutions( calculateExecutionPlan( session, "resources:resources" ) );
+ assertEquals( 1, executionPlan.size() );
+ MojoExecution mojoExecution = executionPlan.get( 0 );
+ assertNotNull( mojoExecution );
+ assertEquals( "org.apache.maven.plugins",
+ mojoExecution.getMojoDescriptor().getPluginDescriptor().getGroupId() );
+ assertEquals( "maven-resources-plugin",
+ mojoExecution.getMojoDescriptor().getPluginDescriptor().getArtifactId() );
+ assertEquals( "0.1", mojoExecution.getMojoDescriptor().getPluginDescriptor().getVersion() );
+ }
+
+ public void testCalculationOfBuildPlanWithIndividualTaskOfTheCleanLifecycle()
+ throws Exception
+ {
+ // We are doing something like "mvn clean:clean" where no version is specified but this
+ // project we are working on has the version specified in the POM so the version should come from there.
+ File pom = getProject( "project-basic" );
+ MavenSession session = createMavenSession( pom );
+ assertEquals( "project-basic", session.getCurrentProject().getArtifactId() );
+ assertEquals( "1.0", session.getCurrentProject().getVersion() );
+ List<MojoExecution> executionPlan = getExecutions( calculateExecutionPlan( session, "clean" ) );
+ assertEquals( 1, executionPlan.size() );
+ MojoExecution mojoExecution = executionPlan.get( 0 );
+ assertNotNull( mojoExecution );
+ assertEquals( "org.apache.maven.plugins",
+ mojoExecution.getMojoDescriptor().getPluginDescriptor().getGroupId() );
+ assertEquals( "maven-clean-plugin", mojoExecution.getMojoDescriptor().getPluginDescriptor().getArtifactId() );
+ assertEquals( "0.1", mojoExecution.getMojoDescriptor().getPluginDescriptor().getVersion() );
+ }
+
+ public void testCalculationOfBuildPlanWithIndividualTaskOfTheCleanCleanGoal()
+ throws Exception
+ {
+ // We are doing something like "mvn clean:clean" where no version is specified but this
+ // project we are working on has the version specified in the POM so the version should come from there.
+ File pom = getProject( "project-basic" );
+ MavenSession session = createMavenSession( pom );
+ assertEquals( "project-basic", session.getCurrentProject().getArtifactId() );
+ assertEquals( "1.0", session.getCurrentProject().getVersion() );
+ List<MojoExecution> executionPlan = getExecutions( calculateExecutionPlan( session, "clean:clean" ) );
+ assertEquals( 1, executionPlan.size() );
+ MojoExecution mojoExecution = executionPlan.get( 0 );
+ assertNotNull( mojoExecution );
+ assertEquals( "org.apache.maven.plugins",
+ mojoExecution.getMojoDescriptor().getPluginDescriptor().getGroupId() );
+ assertEquals( "maven-clean-plugin", mojoExecution.getMojoDescriptor().getPluginDescriptor().getArtifactId() );
+ assertEquals( "0.1", mojoExecution.getMojoDescriptor().getPluginDescriptor().getVersion() );
+ }
+
+ List<MojoExecution> getExecutions( MavenExecutionPlan mavenExecutionPlan )
+ {
+ List<MojoExecution> result = new ArrayList<MojoExecution>();
+ for ( ExecutionPlanItem executionPlanItem : mavenExecutionPlan )
+ {
+ result.add( executionPlanItem.getMojoExecution() );
+ }
+ return result;
+ }
+
+ // We need to take in multiple lifecycles
+ public void testCalculationOfBuildPlanTasksOfTheCleanLifecycleAndTheInstallLifecycle()
+ throws Exception
+ {
+ File pom = getProject( "project-with-additional-lifecycle-elements" );
+ MavenSession session = createMavenSession( pom );
+ assertEquals( "project-with-additional-lifecycle-elements", session.getCurrentProject().getArtifactId() );
+ assertEquals( "1.0", session.getCurrentProject().getVersion() );
+ List<MojoExecution> executionPlan = getExecutions( calculateExecutionPlan( session, "clean", "install" ) );
+
+ //[01] clean:clean
+ //[02] resources:resources
+ //[03] compiler:compile
+ //[04] it:generate-metadata
+ //[05] resources:testResources
+ //[06] compiler:testCompile
+ //[07] it:generate-test-metadata
+ //[08] surefire:test
+ //[09] jar:jar
+ //[10] install:install
+ //
+ assertEquals( 10, executionPlan.size() );
+
+ assertEquals( "clean:clean", executionPlan.get( 0 ).getMojoDescriptor().getFullGoalName() );
+ assertEquals( "resources:resources", executionPlan.get( 1 ).getMojoDescriptor().getFullGoalName() );
+ assertEquals( "compiler:compile", executionPlan.get( 2 ).getMojoDescriptor().getFullGoalName() );
+ assertEquals( "it:generate-metadata", executionPlan.get( 3 ).getMojoDescriptor().getFullGoalName() );
+ assertEquals( "resources:testResources", executionPlan.get( 4 ).getMojoDescriptor().getFullGoalName() );
+ assertEquals( "compiler:testCompile", executionPlan.get( 5 ).getMojoDescriptor().getFullGoalName() );
+ assertEquals( "it:generate-test-metadata", executionPlan.get( 6 ).getMojoDescriptor().getFullGoalName() );
+ assertEquals( "surefire:test", executionPlan.get( 7 ).getMojoDescriptor().getFullGoalName() );
+ assertEquals( "jar:jar", executionPlan.get( 8 ).getMojoDescriptor().getFullGoalName() );
+ assertEquals( "install:install", executionPlan.get( 9 ).getMojoDescriptor().getFullGoalName() );
+ }
+
+ // We need to take in multiple lifecycles
+ public void testCalculationOfBuildPlanWithMultipleExecutionsOfModello()
+ throws Exception
+ {
+ File pom = getProject( "project-with-multiple-executions" );
+ MavenSession session = createMavenSession( pom );
+ assertEquals( "project-with-multiple-executions", session.getCurrentProject().getArtifactId() );
+ assertEquals( "1.0.1", session.getCurrentProject().getVersion() );
+
+ MavenExecutionPlan plan = calculateExecutionPlan( session, "clean", "install" );
+
+ List<MojoExecution> executions = getExecutions( plan );
+
+ //[01] clean:clean
+ //[02] modello:xpp3-writer
+ //[03] modello:java
+ //[04] modello:xpp3-reader
+ //[05] modello:xpp3-writer
+ //[06] modello:java
+ //[07] modello:xpp3-reader
+ //[08] plugin:descriptor
+ //[09] resources:resources
+ //[10] compiler:compile
+ //[11] resources:testResources
+ //[12] compiler:testCompile
+ //[13] surefire:test
+ //[14] jar:jar
+ //[15] plugin:addPluginArtifactMetadata
+ //[16] install:install
+ //
+
+ assertEquals( 16, executions.size() );
+
+ assertEquals( "clean:clean", executions.get( 0 ).getMojoDescriptor().getFullGoalName() );
+ assertEquals( "it:xpp3-writer", executions.get( 1 ).getMojoDescriptor().getFullGoalName() );
+ assertEquals( "it:java", executions.get( 2 ).getMojoDescriptor().getFullGoalName() );
+ assertEquals( "it:xpp3-reader", executions.get( 3 ).getMojoDescriptor().getFullGoalName() );
+ assertEquals( "it:xpp3-writer", executions.get( 4 ).getMojoDescriptor().getFullGoalName() );
+ assertEquals( "it:java", executions.get( 5 ).getMojoDescriptor().getFullGoalName() );
+ assertEquals( "it:xpp3-reader", executions.get( 6 ).getMojoDescriptor().getFullGoalName() );
+ assertEquals( "resources:resources", executions.get( 7 ).getMojoDescriptor().getFullGoalName() );
+ assertEquals( "compiler:compile", executions.get( 8 ).getMojoDescriptor().getFullGoalName() );
+ assertEquals( "plugin:descriptor", executions.get( 9 ).getMojoDescriptor().getFullGoalName() );
+ assertEquals( "resources:testResources", executions.get( 10 ).getMojoDescriptor().getFullGoalName() );
+ assertEquals( "compiler:testCompile", executions.get( 11 ).getMojoDescriptor().getFullGoalName() );
+ assertEquals( "surefire:test", executions.get( 12 ).getMojoDescriptor().getFullGoalName() );
+ assertEquals( "jar:jar", executions.get( 13 ).getMojoDescriptor().getFullGoalName() );
+ assertEquals( "plugin:addPluginArtifactMetadata", executions.get( 14 ).getMojoDescriptor().getFullGoalName() );
+ assertEquals( "install:install", executions.get( 15 ).getMojoDescriptor().getFullGoalName() );
+
+ assertEquals( "src/main/mdo/remote-resources.mdo",
+ new MojoExecutionXPathContainer( executions.get( 1 ) ).getValue(
+ "configuration/models[1]/model" ) );
+ assertEquals( "src/main/mdo/supplemental-model.mdo",
+ new MojoExecutionXPathContainer( executions.get( 4 ) ).getValue(
+ "configuration/models[1]/model" ) );
+ }
+
+ public void testLifecycleQueryingUsingADefaultLifecyclePhase()
+ throws Exception
+ {
+ File pom = getProject( "project-with-additional-lifecycle-elements" );
+ MavenSession session = createMavenSession( pom );
+ assertEquals( "project-with-additional-lifecycle-elements", session.getCurrentProject().getArtifactId() );
+ assertEquals( "1.0", session.getCurrentProject().getVersion() );
+ List<MojoExecution> executionPlan = getExecutions( calculateExecutionPlan( session, "package" ) );
+
+ //[01] resources:resources
+ //[02] compiler:compile
+ //[03] it:generate-metadata
+ //[04] resources:testResources
+ //[05] compiler:testCompile
+ //[06] plexus-component-metadata:generate-test-metadata
+ //[07] surefire:test
+ //[08] jar:jar
+ //
+ assertEquals( 8, executionPlan.size() );
+
+ assertEquals( "resources:resources", executionPlan.get( 0 ).getMojoDescriptor().getFullGoalName() );
+ assertEquals( "compiler:compile", executionPlan.get( 1 ).getMojoDescriptor().getFullGoalName() );
+ assertEquals( "it:generate-metadata", executionPlan.get( 2 ).getMojoDescriptor().getFullGoalName() );
+ assertEquals( "resources:testResources", executionPlan.get( 3 ).getMojoDescriptor().getFullGoalName() );
+ assertEquals( "compiler:testCompile", executionPlan.get( 4 ).getMojoDescriptor().getFullGoalName() );
+ assertEquals( "it:generate-test-metadata", executionPlan.get( 5 ).getMojoDescriptor().getFullGoalName() );
+ assertEquals( "surefire:test", executionPlan.get( 6 ).getMojoDescriptor().getFullGoalName() );
+ assertEquals( "jar:jar", executionPlan.get( 7 ).getMojoDescriptor().getFullGoalName() );
+ }
+
+ public void testLifecyclePluginsRetrievalForDefaultLifecycle()
+ throws Exception
+ {
+ List<Plugin> plugins =
+ new ArrayList<Plugin>( lifecycleExecutor.getPluginsBoundByDefaultToAllLifecycles( "jar" ) );
+
+ assertEquals( 8, plugins.size() );
+ }
+
+ public void testPluginConfigurationCreation()
+ throws Exception
+ {
+ File pom = getProject( "project-with-additional-lifecycle-elements" );
+ MavenSession session = createMavenSession( pom );
+ MojoDescriptor mojoDescriptor =
+ mojoDescriptorCreator.getMojoDescriptor( "org.apache.maven.its.plugins:maven-it-plugin:0.1:java", session,
+ session.getCurrentProject() );
+ Xpp3Dom dom = MojoDescriptorCreator.convert( mojoDescriptor );
+ System.out.println( dom );
+ }
+
+ MavenExecutionPlan calculateExecutionPlan( MavenSession session, String... tasks )
+ throws Exception
+ {
+ List<TaskSegment> taskSegments =
+ lifeCycleTaskSegmentCalculator.calculateTaskSegments( session, Arrays.asList( tasks ) );
+
+ TaskSegment mergedSegment = new TaskSegment( false );
+
+ for ( TaskSegment taskSegment : taskSegments )
+ {
+ mergedSegment.getTasks().addAll( taskSegment.getTasks() );
+ }
+
+ return lifeCycleExecutionPlanCalculator.calculateExecutionPlan( session, session.getCurrentProject(),
+ mergedSegment.getTasks() );
+ }
+
+ public void testInvalidGoalName()
+ throws Exception
+ {
+ File pom = getProject( "project-basic" );
+ MavenSession session = createMavenSession( pom );
+ try
+ {
+ getExecutions( calculateExecutionPlan( session, "resources:" ) );
+ fail( "expected a MojoNotFoundException" );
+ }
+ catch ( MojoNotFoundException e )
+ {
+ assertEquals( "", e.getGoal() );
+ }
+
+ try
+ {
+ getExecutions( calculateExecutionPlan( session, "org.apache.maven.plugins:maven-resources-plugin:0.1:resources:toomany" ) );
+ fail( "expected a MojoNotFoundException" );
+ }
+ catch ( MojoNotFoundException e )
+ {
+ assertEquals( "resources:toomany", e.getGoal() );
+ }
+ }
+
+
+ public void testPluginPrefixRetrieval()
+ throws Exception
+ {
+ File pom = getProject( "project-basic" );
+ MavenSession session = createMavenSession( pom );
+ Plugin plugin = mojoDescriptorCreator.findPluginForPrefix( "resources", session );
+ assertEquals( "org.apache.maven.plugins", plugin.getGroupId() );
+ assertEquals( "maven-resources-plugin", plugin.getArtifactId() );
+ }
+
+ // Prefixes
+
+ public void testFindingPluginPrefixforCleanClean()
+ throws Exception
+ {
+ File pom = getProject( "project-basic" );
+ MavenSession session = createMavenSession( pom );
+ Plugin plugin = mojoDescriptorCreator.findPluginForPrefix( "clean", session );
+ assertNotNull( plugin );
+ }
+
+ public void testSetupMojoExecution()
+ throws Exception
+ {
+ File pom = getProject( "mojo-configuration" );
+
+ MavenSession session = createMavenSession( pom );
+
+ LifecycleTask task = new LifecycleTask( "generate-sources" );
+ MavenExecutionPlan executionPlan =
+ lifeCycleExecutionPlanCalculator.calculateExecutionPlan( session, session.getCurrentProject(),
+ Arrays.asList( (Object) task ), false );
+
+ MojoExecution execution = executionPlan.getMojoExecutions().get(0);
+ assertEquals(execution.toString(), "maven-it-plugin", execution.getArtifactId());
+ assertNull(execution.getConfiguration());
+
+ lifeCycleExecutionPlanCalculator.setupMojoExecution( session, session.getCurrentProject(), execution );
+ assertNotNull(execution.getConfiguration());
+ assertEquals("1.0", execution.getConfiguration().getChild( "version" ).getAttribute( "default-value" ));
+ }
+
+ public void testExecutionListeners()
+ throws Exception
+ {
+ final File pom = getProject( "project-basic" );
+ final MavenSession session = createMavenSession( pom );
+ session.setProjectDependencyGraph( new ProjectDependencyGraph()
+ {
+ public List<MavenProject> getUpstreamProjects( MavenProject project, boolean transitive )
+ {
+ return Collections.emptyList();
+ }
+
+ public List<MavenProject> getSortedProjects()
+ {
+ return Collections.singletonList( session.getCurrentProject() );
+ }
+
+ public List<MavenProject> getDownstreamProjects( MavenProject project, boolean transitive )
+ {
+ return Collections.emptyList();
+ }
+
+ public java.util.List<MavenProject> getAllSortedProjects()
+ {
+ return Collections.emptyList();
+ }
+ } );
+
+ final List<String> log = new ArrayList<String>();
+
+ MojoExecutionListener mojoListener = new MojoExecutionListener()
+ {
+ public void beforeMojoExecution( MojoExecutionEvent event )
+ throws MojoExecutionException
+ {
+ assertNotNull( event.getSession() );
+ assertNotNull( event.getProject() );
+ assertNotNull( event.getExecution() );
+ assertNotNull( event.getMojo() );
+ assertNull( event.getCause() );
+
+ log.add( "beforeMojoExecution " + event.getProject().getArtifactId() + ":"
+ + event.getExecution().getExecutionId() );
+ }
+
+ public void afterMojoExecutionSuccess( MojoExecutionEvent event )
+ throws MojoExecutionException
+ {
+ assertNotNull( event.getSession() );
+ assertNotNull( event.getProject() );
+ assertNotNull( event.getExecution() );
+ assertNotNull( event.getMojo() );
+ assertNull( event.getCause() );
+
+ log.add( "afterMojoExecutionSuccess " + event.getProject().getArtifactId() + ":"
+ + event.getExecution().getExecutionId() );
+ }
+
+ public void afterExecutionFailure( MojoExecutionEvent event )
+ {
+ assertNotNull( event.getSession() );
+ assertNotNull( event.getProject() );
+ assertNotNull( event.getExecution() );
+ assertNotNull( event.getMojo() );
+ assertNotNull( event.getCause() );
+
+ log.add( "afterExecutionFailure " + event.getProject().getArtifactId() + ":"
+ + event.getExecution().getExecutionId() );
+ }
+ };
+ ProjectExecutionListener projectListener = new ProjectExecutionListener()
+ {
+ public void beforeProjectExecution( ProjectExecutionEvent event )
+ throws LifecycleExecutionException
+ {
+ assertNotNull( event.getSession() );
+ assertNotNull( event.getProject() );
+ assertNull( event.getExecutionPlan() );
+ assertNull( event.getCause() );
+
+ log.add( "beforeProjectExecution " + event.getProject().getArtifactId() );
+ }
+
+ public void beforeProjectLifecycleExecution( ProjectExecutionEvent event )
+ throws LifecycleExecutionException
+ {
+ assertNotNull( event.getSession() );
+ assertNotNull( event.getProject() );
+ assertNotNull( event.getExecutionPlan() );
+ assertNull( event.getCause() );
+
+ log.add( "beforeProjectLifecycleExecution " + event.getProject().getArtifactId() );
+ }
+
+ public void afterProjectExecutionSuccess( ProjectExecutionEvent event )
+ throws LifecycleExecutionException
+ {
+ assertNotNull( event.getSession() );
+ assertNotNull( event.getProject() );
+ assertNotNull( event.getExecutionPlan() );
+ assertNull( event.getCause() );
+
+ log.add( "afterProjectExecutionSuccess " + event.getProject().getArtifactId() );
+ }
+
+ public void afterProjectExecutionFailure( ProjectExecutionEvent event )
+ {
+ assertNotNull( event.getSession() );
+ assertNotNull( event.getProject() );
+ assertNull( event.getExecutionPlan() );
+ assertNotNull( event.getCause() );
+
+ log.add( "afterProjectExecutionFailure " + event.getProject().getArtifactId() );
+ }
+ };
+ lookup( DelegatingProjectExecutionListener.class ).addProjectExecutionListener( projectListener );
+ lookup( DelegatingMojoExecutionListener.class ).addMojoExecutionListener( mojoListener );
+
+ try
+ {
+ lifecycleExecutor.execute( session );
+ }
+ finally
+ {
+ lookup( DelegatingProjectExecutionListener.class ).removeProjectExecutionListener( projectListener );
+ lookup( DelegatingMojoExecutionListener.class ).removeMojoExecutionListener( mojoListener );
+ }
+
+ List<String> expectedLog = Arrays.asList( "beforeProjectExecution project-basic", //
+ "beforeProjectLifecycleExecution project-basic", //
+ "beforeMojoExecution project-basic:default-resources", //
+ "afterMojoExecutionSuccess project-basic:default-resources", //
+ "beforeMojoExecution project-basic:default-compile", //
+ "afterMojoExecutionSuccess project-basic:default-compile", //
+ "beforeMojoExecution project-basic:default-testResources", //
+ "afterMojoExecutionSuccess project-basic:default-testResources", //
+ "beforeMojoExecution project-basic:default-testCompile", //
+ "afterMojoExecutionSuccess project-basic:default-testCompile", //
+ "beforeMojoExecution project-basic:default-test", //
+ "afterMojoExecutionSuccess project-basic:default-test", //
+ "beforeMojoExecution project-basic:default-jar", //
+ "afterMojoExecutionSuccess project-basic:default-jar", //
+ "afterProjectExecutionSuccess project-basic" //
+ );
+
+ assertEventLog( expectedLog, log );
+ }
+
+ private static void assertEventLog( List<String> expectedList, List<String> actualList )
+ {
+ assertEquals( toString( expectedList ), toString( actualList ) );
+ }
+
+ private static String toString( List<String> lines )
+ {
+ StringBuilder sb = new StringBuilder();
+ for ( String line : lines )
+ {
+ sb.append( line ).append( '\n' );
+ }
+ return sb.toString();
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/MavenExecutionPlanTest.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/MavenExecutionPlanTest.java
new file mode 100644
index 00000000..4901a65d
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/MavenExecutionPlanTest.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.apache.maven.lifecycle;
+
+import junit.framework.TestCase;
+
+import org.apache.maven.lifecycle.internal.ExecutionPlanItem;
+import org.apache.maven.lifecycle.internal.stub.DefaultLifecyclesStub;
+import org.apache.maven.lifecycle.internal.stub.LifecycleExecutionPlanCalculatorStub;
+import org.apache.maven.model.Plugin;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * @author Kristian Rosenvold
+ */
+public class MavenExecutionPlanTest
+ extends TestCase
+{
+
+ public void testFindLastInPhase()
+ throws Exception
+ {
+ MavenExecutionPlan plan = LifecycleExecutionPlanCalculatorStub.getProjectAExceutionPlan();
+
+ ExecutionPlanItem expected = plan.findLastInPhase( "package" );
+ ExecutionPlanItem beerPhase = plan.findLastInPhase( "BEER" ); // Beer comes straight after package in stub
+ assertEquals( expected, beerPhase );
+ assertNotNull( expected );
+ }
+
+ public void testThreadSafeMojos()
+ throws Exception
+ {
+ MavenExecutionPlan plan = LifecycleExecutionPlanCalculatorStub.getProjectAExceutionPlan();
+ final Set<Plugin> unSafePlugins = plan.getNonThreadSafePlugins();
+ // There is only a single threadsafe plugin here...
+ assertEquals( plan.size() - 1, unSafePlugins.size() );
+
+ }
+
+
+ public void testFindLastWhenFirst()
+ throws Exception
+ {
+ MavenExecutionPlan plan = LifecycleExecutionPlanCalculatorStub.getProjectAExceutionPlan();
+
+ ExecutionPlanItem beerPhase = plan.findLastInPhase(
+ LifecycleExecutionPlanCalculatorStub.VALIDATE.getPhase() ); // Beer comes straight after package in stub
+ assertNull( beerPhase );
+ }
+
+ public void testFindLastInPhaseMisc()
+ throws Exception
+ {
+ MavenExecutionPlan plan = LifecycleExecutionPlanCalculatorStub.getProjectAExceutionPlan();
+
+ assertNull( plan.findLastInPhase( "pacXkage" ) );
+ // Beer comes straight after package in stub, much like real life.
+ assertNotNull( plan.findLastInPhase( LifecycleExecutionPlanCalculatorStub.INITIALIZE.getPhase() ) );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/MojoExecutionXPathContainer.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/MojoExecutionXPathContainer.java
new file mode 100644
index 00000000..6244cc91
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/MojoExecutionXPathContainer.java
@@ -0,0 +1,72 @@
+package org.apache.maven.lifecycle;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.IOException;
+import java.util.Iterator;
+
+import org.apache.commons.jxpath.JXPathContext;
+import org.apache.commons.jxpath.JXPathNotFoundException;
+import org.apache.commons.jxpath.ri.JXPathContextReferenceImpl;
+import org.apache.maven.plugin.MojoExecution;
+import org.apache.maven.project.harness.Xpp3DomPointerFactory;
+
+public class MojoExecutionXPathContainer
+{
+ private JXPathContext context;
+
+ static
+ {
+ JXPathContextReferenceImpl.addNodePointerFactory( new Xpp3DomPointerFactory() );
+ }
+
+ public MojoExecutionXPathContainer( MojoExecution mojoExecution )
+ throws IOException
+ {
+ context = JXPathContext.newContext( mojoExecution );
+ }
+
+ public Iterator<?> getIteratorForXPathExpression( String expression )
+ {
+ return context.iterate( expression );
+ }
+
+ public boolean containsXPathExpression( String expression )
+ {
+ return context.getValue( expression ) != null;
+ }
+
+ public Object getValue( String expression )
+ {
+ try
+ {
+ return context.getValue( expression );
+ }
+ catch ( JXPathNotFoundException e )
+ {
+ return null;
+ }
+ }
+
+ public boolean xPathExpressionEqualsValue( String expression, String value )
+ {
+ return context.getValue( expression ) != null && context.getValue( expression ).equals( value );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/BuildListCalculatorTest.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/BuildListCalculatorTest.java
new file mode 100644
index 00000000..a0039832
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/BuildListCalculatorTest.java
@@ -0,0 +1,49 @@
+package org.apache.maven.lifecycle.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+import junit.framework.TestCase;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.lifecycle.internal.stub.LifecycleTaskSegmentCalculatorStub;
+import org.apache.maven.lifecycle.internal.stub.ProjectDependencyGraphStub;
+
+import java.util.List;
+
+public class BuildListCalculatorTest
+ extends TestCase
+{
+
+ public void testCalculateProjectBuilds()
+ throws Exception
+ {
+ LifecycleTaskSegmentCalculator lifecycleTaskSegmentCalculator = getTaskSegmentCalculator();
+ BuildListCalculator buildListCalculator = new BuildListCalculator();
+ final MavenSession session = ProjectDependencyGraphStub.getMavenSession();
+ List<TaskSegment> taskSegments = lifecycleTaskSegmentCalculator.calculateTaskSegments( session );
+ final ProjectBuildList buildList = buildListCalculator.calculateProjectBuilds( session, taskSegments );
+ final ProjectBuildList segments = buildList.getByTaskSegment( taskSegments.get( 0 ) );
+ assertEquals( "Stub data contains 3 segments", 3, taskSegments.size() );
+ assertEquals( "Stub data contains 6 items", 6, segments.size() );
+ final ProjectSegment build = segments.get( 0 );
+ assertNotNull( build );
+ }
+
+ private static LifecycleTaskSegmentCalculator getTaskSegmentCalculator()
+ {
+ return new LifecycleTaskSegmentCalculatorStub();
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/BuilderCommonTest.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/BuilderCommonTest.java
new file mode 100644
index 00000000..6f896d85
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/BuilderCommonTest.java
@@ -0,0 +1,76 @@
+package org.apache.maven.lifecycle.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+import junit.framework.TestCase;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.lifecycle.MavenExecutionPlan;
+import org.apache.maven.lifecycle.internal.builder.BuilderCommon;
+import org.apache.maven.lifecycle.internal.stub.LifecycleExecutionPlanCalculatorStub;
+import org.apache.maven.lifecycle.internal.stub.LoggerStub;
+import org.apache.maven.lifecycle.internal.stub.ProjectDependencyGraphStub;
+
+import java.util.HashSet;
+
+/**
+ * @author Kristian Rosenvold
+ */
+public class BuilderCommonTest
+ extends TestCase
+{
+ public void testResolveBuildPlan()
+ throws Exception
+ {
+ MavenSession original = ProjectDependencyGraphStub.getMavenSession();
+
+ final TaskSegment taskSegment1 = new TaskSegment( false );
+ final MavenSession session1 = original.clone();
+ session1.setCurrentProject( ProjectDependencyGraphStub.A );
+
+ final BuilderCommon builderCommon = getBuilderCommon();
+ final MavenExecutionPlan plan =
+ builderCommon.resolveBuildPlan( session1, ProjectDependencyGraphStub.A, taskSegment1,
+ new HashSet<Artifact>() );
+ assertEquals( LifecycleExecutionPlanCalculatorStub.getProjectAExceutionPlan().size(), plan.size() );
+
+ }
+
+
+ public void testHandleBuildError()
+ throws Exception
+ {
+ }
+
+ public void testAttachToThread()
+ throws Exception
+ {
+ }
+
+ public void testGetKey()
+ throws Exception
+ {
+ }
+
+ public static BuilderCommon getBuilderCommon()
+ {
+ final LifecycleDebugLogger logger = new LifecycleDebugLogger( new LoggerStub() );
+ return new BuilderCommon( logger, new LifecycleExecutionPlanCalculatorStub(),
+ new LoggerStub() );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/ConcurrencyDependencyGraphTest.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/ConcurrencyDependencyGraphTest.java
new file mode 100644
index 00000000..9ab06011
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/ConcurrencyDependencyGraphTest.java
@@ -0,0 +1,94 @@
+package org.apache.maven.lifecycle.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.execution.ProjectDependencyGraph;
+import org.apache.maven.lifecycle.LifecycleNotFoundException;
+import org.apache.maven.lifecycle.LifecyclePhaseNotFoundException;
+import org.apache.maven.lifecycle.internal.builder.multithreaded.ConcurrencyDependencyGraph;
+import org.apache.maven.lifecycle.internal.stub.ProjectDependencyGraphStub;
+import org.apache.maven.plugin.InvalidPluginDescriptorException;
+import org.apache.maven.plugin.MojoNotFoundException;
+import org.apache.maven.plugin.PluginDescriptorParsingException;
+import org.apache.maven.plugin.PluginNotFoundException;
+import org.apache.maven.plugin.PluginResolutionException;
+import org.apache.maven.plugin.prefix.NoPluginFoundForPrefixException;
+import org.apache.maven.plugin.version.PluginVersionResolutionException;
+import org.apache.maven.project.MavenProject;
+
+import java.util.List;
+
+import static org.apache.maven.lifecycle.internal.stub.ProjectDependencyGraphStub.*;
+
+/**
+ * @author Kristian Rosenvold
+ */
+public class ConcurrencyDependencyGraphTest
+ extends junit.framework.TestCase
+{
+ public void testConcurrencyGraphPrimaryVersion()
+ throws InvalidPluginDescriptorException, PluginVersionResolutionException, PluginDescriptorParsingException,
+ NoPluginFoundForPrefixException, MojoNotFoundException, PluginNotFoundException, PluginResolutionException,
+ LifecyclePhaseNotFoundException, LifecycleNotFoundException
+ {
+ ProjectDependencyGraph dependencyGraph = new ProjectDependencyGraphStub();
+ final MavenSession session = ProjectDependencyGraphStub.getMavenSession();
+
+ ConcurrencyDependencyGraph graph =
+ new ConcurrencyDependencyGraph( getProjectBuildList( session ), dependencyGraph );
+
+ final List<MavenProject> projectBuilds = graph.getRootSchedulableBuilds();
+ assertEquals( 1, projectBuilds.size() );
+ assertEquals( A, projectBuilds.get( 0 ) );
+
+ final List<MavenProject> subsequent = graph.markAsFinished( A );
+ assertEquals( 2, subsequent.size() );
+ assertEquals( ProjectDependencyGraphStub.B, subsequent.get( 0 ) );
+ assertEquals( C, subsequent.get( 1 ) );
+
+ final List<MavenProject> bDescendants = graph.markAsFinished( B );
+ assertEquals( 1, bDescendants.size() );
+ assertEquals( Y, bDescendants.get( 0 ) );
+
+ final List<MavenProject> cDescendants = graph.markAsFinished( C );
+ assertEquals( 2, cDescendants.size() );
+ assertEquals( X, cDescendants.get( 0 ) );
+ assertEquals( Z, cDescendants.get( 1 ) );
+ }
+
+ public void testConcurrencyGraphDifferentCompletionOrder()
+ throws InvalidPluginDescriptorException, PluginVersionResolutionException, PluginDescriptorParsingException,
+ NoPluginFoundForPrefixException, MojoNotFoundException, PluginNotFoundException, PluginResolutionException,
+ LifecyclePhaseNotFoundException, LifecycleNotFoundException
+ {
+ ProjectDependencyGraph dependencyGraph = new ProjectDependencyGraphStub();
+ final MavenSession session = ProjectDependencyGraphStub.getMavenSession();
+ ConcurrencyDependencyGraph graph =
+ new ConcurrencyDependencyGraph( getProjectBuildList( session ), dependencyGraph );
+
+ graph.markAsFinished( A );
+ final List<MavenProject> cDescendants = graph.markAsFinished( C );
+ assertEquals( 1, cDescendants.size() );
+ assertEquals( Z, cDescendants.get( 0 ) );
+
+ final List<MavenProject> bDescendants = graph.markAsFinished( B );
+ assertEquals( 2, bDescendants.size() );
+ assertEquals( X, bDescendants.get( 0 ) );
+ assertEquals( Y, bDescendants.get( 1 ) );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/LifecycleExecutionPlanCalculatorTest.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/LifecycleExecutionPlanCalculatorTest.java
new file mode 100644
index 00000000..a9af5668
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/LifecycleExecutionPlanCalculatorTest.java
@@ -0,0 +1,82 @@
+package org.apache.maven.lifecycle.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+import org.apache.maven.AbstractCoreMavenComponentTestCase;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.lifecycle.MavenExecutionPlan;
+import org.apache.maven.lifecycle.internal.stub.BuildPluginManagerStub;
+import org.apache.maven.lifecycle.internal.stub.DefaultLifecyclesStub;
+import org.apache.maven.lifecycle.internal.stub.PluginPrefixResolverStub;
+import org.apache.maven.lifecycle.internal.stub.PluginVersionResolverStub;
+import org.apache.maven.lifecycle.internal.stub.ProjectDependencyGraphStub;
+
+/**
+ * @author Kristian Rosenvold>
+ */
+public class LifecycleExecutionPlanCalculatorTest
+ extends AbstractCoreMavenComponentTestCase
+{
+
+ public void testCalculateExecutionPlanWithGoalTasks()
+ throws Exception
+ {
+ MojoDescriptorCreator mojoDescriptorCreator = createMojoDescriptorCreator();
+ LifecycleExecutionPlanCalculator lifecycleExecutionPlanCalculator =
+ createExecutionPlaceCalculator( mojoDescriptorCreator );
+
+ final GoalTask goalTask1 = new GoalTask( "compiler:compile" );
+ final GoalTask goalTask2 = new GoalTask( "surefire:test" );
+ final TaskSegment taskSegment1 = new TaskSegment( false, goalTask1, goalTask2 );
+ final MavenSession session1 = ProjectDependencyGraphStub.getMavenSession( ProjectDependencyGraphStub.A );
+
+ MavenExecutionPlan executionPlan =
+ lifecycleExecutionPlanCalculator.calculateExecutionPlan( session1, ProjectDependencyGraphStub.A,
+ taskSegment1.getTasks() );
+ assertEquals( 2, executionPlan.size() );
+
+ final GoalTask goalTask3 = new GoalTask( "surefire:test" );
+ final TaskSegment taskSegment2 = new TaskSegment( false, goalTask1, goalTask2, goalTask3 );
+ MavenExecutionPlan executionPlan2 =
+ lifecycleExecutionPlanCalculator.calculateExecutionPlan( session1, ProjectDependencyGraphStub.A,
+ taskSegment2.getTasks() );
+ assertEquals( 3, executionPlan2.size() );
+ }
+
+ // Maybe also make one with LifeCycleTasks
+
+ public static LifecycleExecutionPlanCalculator createExecutionPlaceCalculator( MojoDescriptorCreator mojoDescriptorCreator )
+ {
+ LifecyclePluginResolver lifecyclePluginResolver = new LifecyclePluginResolver( new PluginVersionResolverStub() );
+ return new DefaultLifecycleExecutionPlanCalculator( new BuildPluginManagerStub(),
+ DefaultLifecyclesStub.createDefaultLifecycles(),
+ mojoDescriptorCreator, lifecyclePluginResolver );
+ }
+
+ public static MojoDescriptorCreator createMojoDescriptorCreator()
+ {
+ return new MojoDescriptorCreator( new PluginVersionResolverStub(), new BuildPluginManagerStub(),
+ new PluginPrefixResolverStub(),
+ new LifecyclePluginResolver( new PluginVersionResolverStub() ) );
+ }
+
+ @Override
+ protected String getProjectsDirectory()
+ {
+ return "src/test/projects/lifecycle-executor";
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/LifecycleTaskSegmentCalculatorImplTest.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/LifecycleTaskSegmentCalculatorImplTest.java
new file mode 100644
index 00000000..5db316f8
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/LifecycleTaskSegmentCalculatorImplTest.java
@@ -0,0 +1,57 @@
+package org.apache.maven.lifecycle.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import junit.framework.TestCase;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.lifecycle.internal.stub.LifecycleTaskSegmentCalculatorStub;
+import org.apache.maven.lifecycle.internal.stub.ProjectDependencyGraphStub;
+
+import java.util.List;
+
+/**
+ * @author Kristian Rosenvold
+ */
+public class LifecycleTaskSegmentCalculatorImplTest
+ extends TestCase
+{
+ public void testCalculateProjectBuilds()
+ throws Exception
+ {
+ LifecycleTaskSegmentCalculator lifecycleTaskSegmentCalculator = getTaskSegmentCalculator();
+ BuildListCalculator buildListCalculator = new BuildListCalculator();
+ final MavenSession session = ProjectDependencyGraphStub.getMavenSession();
+ List<TaskSegment> taskSegments = lifecycleTaskSegmentCalculator.calculateTaskSegments( session );
+
+ final ProjectBuildList buildList = buildListCalculator.calculateProjectBuilds( session, taskSegments );
+ final ProjectBuildList segments = buildList.getByTaskSegment( taskSegments.get( 0 ) );
+ assertEquals( "Stub data contains 3 segments", 3, taskSegments.size() );
+ assertEquals( "Stub data contains 6 items", 6, segments.size() );
+ final ProjectSegment build = segments.get( 0 );
+ assertNotNull( build );
+ }
+
+ private static LifecycleTaskSegmentCalculator getTaskSegmentCalculator()
+ {
+ return new LifecycleTaskSegmentCalculatorStub();
+ }
+
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/PhaseRecorderTest.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/PhaseRecorderTest.java
new file mode 100644
index 00000000..f3d6422c
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/PhaseRecorderTest.java
@@ -0,0 +1,49 @@
+package org.apache.maven.lifecycle.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+import junit.framework.TestCase;
+
+import org.apache.maven.lifecycle.MavenExecutionPlan;
+import org.apache.maven.lifecycle.internal.stub.LifecycleExecutionPlanCalculatorStub;
+import org.apache.maven.lifecycle.internal.stub.ProjectDependencyGraphStub;
+import org.apache.maven.plugin.MojoExecution;
+
+import java.util.List;
+
+/**
+ * @author Kristian Rosenvold
+ */
+public class PhaseRecorderTest extends TestCase
+{
+ public void testObserveExecution() throws Exception {
+ PhaseRecorder phaseRecorder = new PhaseRecorder( ProjectDependencyGraphStub.A);
+ MavenExecutionPlan plan = LifecycleExecutionPlanCalculatorStub.getProjectAExceutionPlan();
+ final List<MojoExecution> executions = plan.getMojoExecutions();
+
+ final MojoExecution mojoExecution1 = executions.get( 0 );
+ final MojoExecution mojoExecution2 = executions.get( 1 );
+ phaseRecorder.observeExecution( mojoExecution1 );
+
+ assertTrue( ProjectDependencyGraphStub.A.hasLifecyclePhase( mojoExecution1.getLifecyclePhase() ));
+ assertFalse( ProjectDependencyGraphStub.A.hasLifecyclePhase( mojoExecution2.getLifecyclePhase() ));
+
+ assertFalse( phaseRecorder.isDifferentPhase( mojoExecution1));
+ assertTrue( phaseRecorder.isDifferentPhase( mojoExecution2));
+
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/ProjectBuildListTest.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/ProjectBuildListTest.java
new file mode 100644
index 00000000..047ef9fe
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/ProjectBuildListTest.java
@@ -0,0 +1,42 @@
+package org.apache.maven.lifecycle.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+import junit.framework.TestCase;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.lifecycle.internal.stub.ProjectDependencyGraphStub;
+
+/**
+ * @author Kristian Rosenvold
+ */
+public class ProjectBuildListTest
+ extends TestCase
+{
+
+ public void testGetByTaskSegment()
+ throws Exception
+ {
+ final MavenSession session = ProjectDependencyGraphStub.getMavenSession();
+ ProjectBuildList projectBuildList = ProjectDependencyGraphStub.getProjectBuildList( session );
+ TaskSegment taskSegment = projectBuildList.get( 0 ).getTaskSegment();
+ assertTrue( "This test assumes there are at least 6 elements in projectBuilds", projectBuildList.size() >= 6 );
+
+ final ProjectBuildList byTaskSegment = projectBuildList.getByTaskSegment( taskSegment );
+ assertEquals( projectBuildList.size(),
+ byTaskSegment.size() ); // Todo: Make multiple segments on projectBuildList
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/builder/multithreaded/ThreadOutputMuxerTest.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/builder/multithreaded/ThreadOutputMuxerTest.java
new file mode 100644
index 00000000..dc75a947
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/builder/multithreaded/ThreadOutputMuxerTest.java
@@ -0,0 +1,167 @@
+package org.apache.maven.lifecycle.internal.builder.multithreaded;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+import junit.framework.TestCase;
+
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.lifecycle.LifecycleNotFoundException;
+import org.apache.maven.lifecycle.LifecyclePhaseNotFoundException;
+import org.apache.maven.lifecycle.internal.ProjectBuildList;
+import org.apache.maven.lifecycle.internal.ProjectSegment;
+import org.apache.maven.lifecycle.internal.builder.multithreaded.ThreadOutputMuxer;
+import org.apache.maven.lifecycle.internal.stub.ProjectDependencyGraphStub;
+import org.apache.maven.plugin.InvalidPluginDescriptorException;
+import org.apache.maven.plugin.MojoNotFoundException;
+import org.apache.maven.plugin.PluginDescriptorParsingException;
+import org.apache.maven.plugin.PluginNotFoundException;
+import org.apache.maven.plugin.PluginResolutionException;
+import org.apache.maven.plugin.prefix.NoPluginFoundForPrefixException;
+import org.apache.maven.plugin.version.PluginVersionResolutionException;
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.concurrent.CompletionService;
+import java.util.concurrent.ExecutorCompletionService;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+
+/**
+ * @author Kristian Rosenvold
+ */
+public class ThreadOutputMuxerTest
+ extends TestCase
+{
+
+ final String paid = "Paid";
+
+ final String in = "In";
+
+ final String full = "Full";
+
+ public void testSingleThreaded()
+ throws Exception
+ {
+ ProjectBuildList src = getProjectBuildList();
+ ProjectBuildList projectBuildList =
+ new ProjectBuildList( Arrays.asList( src.get( 0 ), src.get( 1 ), src.get( 2 ) ) );
+
+ ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+ PrintStream systemOut = new PrintStream( byteArrayOutputStream );
+ ThreadOutputMuxer threadOutputMuxer = new ThreadOutputMuxer( projectBuildList, systemOut );
+
+ threadOutputMuxer.associateThreadWithProjectSegment( projectBuildList.get( 0 ) );
+ System.out.print( paid ); // No, this does not print to system.out. It's part of the test
+ assertEquals( paid.length(), byteArrayOutputStream.size() );
+ threadOutputMuxer.associateThreadWithProjectSegment( projectBuildList.get( 1 ) );
+ System.out.print( in ); // No, this does not print to system.out. It's part of the test
+ assertEquals( paid.length(), byteArrayOutputStream.size() );
+ threadOutputMuxer.associateThreadWithProjectSegment( projectBuildList.get( 2 ) );
+ System.out.print( full ); // No, this does not print to system.out. It's part of the test
+ assertEquals( paid.length(), byteArrayOutputStream.size() );
+
+ threadOutputMuxer.setThisModuleComplete( projectBuildList.get( 0 ) );
+ threadOutputMuxer.setThisModuleComplete( projectBuildList.get( 1 ) );
+ threadOutputMuxer.setThisModuleComplete( projectBuildList.get( 2 ) );
+ threadOutputMuxer.close();
+ assertEquals( ( paid + in + full ).length(), byteArrayOutputStream.size() );
+ }
+
+ public void testMultiThreaded()
+ throws Exception
+ {
+ ProjectBuildList projectBuildList = getProjectBuildList();
+
+ ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+ PrintStream systemOut = new PrintStream( byteArrayOutputStream );
+ final ThreadOutputMuxer threadOutputMuxer = new ThreadOutputMuxer( projectBuildList, systemOut );
+
+ final List<String> stringList =
+ Arrays.asList( "Thinkin", "of", "a", "master", "plan", "Cuz", "ain’t", "nuthin", "but", "sweat", "inside",
+ "my", "hand" );
+ Iterator<String> lyrics = stringList.iterator();
+
+ ExecutorService executor = Executors.newFixedThreadPool( 10 );
+ CompletionService<ProjectSegment> service = new ExecutorCompletionService<ProjectSegment>( executor );
+
+ List<Future<ProjectSegment>> futures = new ArrayList<Future<ProjectSegment>>();
+ for ( ProjectSegment projectBuild : projectBuildList )
+ {
+ final Future<ProjectSegment> buildFuture =
+ service.submit( new Outputter( threadOutputMuxer, projectBuild, lyrics.next() ) );
+ futures.add( buildFuture );
+ }
+
+ for ( Future<ProjectSegment> future : futures )
+ {
+ future.get();
+ }
+ int expectedLength = 0;
+ for ( int i = 0; i < projectBuildList.size(); i++ )
+ {
+ expectedLength += stringList.get( i ).length();
+ }
+
+ threadOutputMuxer.close();
+ final byte[] bytes = byteArrayOutputStream.toByteArray();
+ String result = new String( bytes );
+ assertEquals( result, expectedLength, bytes.length );
+
+
+ }
+
+ class Outputter
+ implements Callable<ProjectSegment>
+ {
+ private final ThreadOutputMuxer threadOutputMuxer;
+
+ private final ProjectSegment item;
+
+ private final String response;
+
+ Outputter( ThreadOutputMuxer threadOutputMuxer, ProjectSegment item, String response )
+ {
+ this.threadOutputMuxer = threadOutputMuxer;
+ this.item = item;
+ this.response = response;
+ }
+
+ public ProjectSegment call()
+ throws Exception
+ {
+ threadOutputMuxer.associateThreadWithProjectSegment( item );
+ System.out.print( response );
+ threadOutputMuxer.setThisModuleComplete( item );
+ return item;
+ }
+ }
+
+
+ private ProjectBuildList getProjectBuildList()
+ throws InvalidPluginDescriptorException, PluginVersionResolutionException, PluginDescriptorParsingException,
+ NoPluginFoundForPrefixException, MojoNotFoundException, PluginNotFoundException, PluginResolutionException,
+ LifecyclePhaseNotFoundException, LifecycleNotFoundException
+ {
+ final MavenSession session = ProjectDependencyGraphStub.getMavenSession();
+ return ProjectDependencyGraphStub.getProjectBuildList( session );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/AboutTheStubs.html b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/AboutTheStubs.html
new file mode 100644
index 00000000..8ad74b96
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/AboutTheStubs.html
@@ -0,0 +1,55 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<html>
+<head>
+ <title>About these stubs</title>
+</head>
+<body>
+<h2>Design</h2>
+These stubs can be thought of as hand-coded mock obects. They allow unit tests to test only specific
+aspects of a component while ignoring others.
+
+These stubs form an internally consistent data-set that is not expected to change. They are
+used to test the individual components in the lifecycle with data that has expected characteristics
+and can be asserted as desired.
+
+You can change/extend these stubs, and tests should not be breaking too much, since most tests
+assert using expected values from the stubs. Normally, when you try to use data from the stubs that
+have not been properly populated, you'll get a nullpointer in your test and you then have to
+identify which stub creates that specific piece of data.
+
+The most important stubs are:
+LifecycleExecutionPlanCalculatorStub
+ProjectDependencyGraphStub
+
+Since they define the primary structure of the project/build.
+
+The stubs define three top-level targets that are defined in LifecycleTaskSegmentCalculatorStub;
+clean, aggr and install. "aggr" is an aggregating task while clean and install are lifecyclephases.
+There will be three items in the task list for this dataset.
+
+The stubs also exist at different "levels", where one test might wire stubs into a specific live implementation.
+In the next test that same "live implementation" will be used in a stub version instead.
+
+Not all live services have stubs, but can be added as needed.
+</body>
+</html> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/BuildPluginManagerStub.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/BuildPluginManagerStub.java
new file mode 100644
index 00000000..133bcb3a
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/BuildPluginManagerStub.java
@@ -0,0 +1,56 @@
+package org.apache.maven.lifecycle.internal.stub;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+import java.util.List;
+
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.model.Plugin;
+import org.apache.maven.plugin.BuildPluginManager;
+import org.apache.maven.plugin.MojoExecution;
+import org.apache.maven.plugin.descriptor.MojoDescriptor;
+import org.apache.maven.plugin.descriptor.PluginDescriptor;
+import org.codehaus.plexus.classworlds.realm.ClassRealm;
+import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.repository.RemoteRepository;
+
+/**
+ * @author Kristian Rosenvold
+ */
+public class BuildPluginManagerStub
+ implements BuildPluginManager
+{
+
+ public PluginDescriptor loadPlugin( Plugin plugin, List<RemoteRepository> repositories, RepositorySystemSession session )
+ {
+ return null;
+ }
+
+ public MojoDescriptor getMojoDescriptor( Plugin plugin, String goal, List<RemoteRepository> repositories,
+ RepositorySystemSession session )
+ {
+ return MojoExecutorStub.createMojoDescriptor( plugin.getKey() );
+ }
+
+ public ClassRealm getPluginRealm( MavenSession session, PluginDescriptor pluginDescriptor )
+ {
+ return null;
+ }
+
+ public void executeMojo( MavenSession session, MojoExecution execution )
+ {
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/CompletionServiceStub.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/CompletionServiceStub.java
new file mode 100644
index 00000000..10a113e9
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/CompletionServiceStub.java
@@ -0,0 +1,89 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.apache.maven.lifecycle.internal.stub;
+
+import org.apache.maven.lifecycle.internal.ProjectSegment;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.concurrent.CompletionService;
+import java.util.concurrent.Future;
+import java.util.concurrent.FutureTask;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * @author Kristian Rosenvold
+ */
+public class CompletionServiceStub
+ implements CompletionService<ProjectSegment>
+{
+ List<FutureTask<ProjectSegment>> projectBuildFutureTasks =
+ Collections.synchronizedList( new ArrayList<FutureTask<ProjectSegment>>() );
+
+ final boolean finishImmediately;
+
+
+ public int size()
+ {
+ return projectBuildFutureTasks.size();
+ }
+
+ public CompletionServiceStub( boolean finishImmediately )
+ {
+ this.finishImmediately = finishImmediately;
+ }
+
+ public Future<ProjectSegment> submit( Callable<ProjectSegment> task )
+ {
+ FutureTask<ProjectSegment> projectBuildFutureTask = new FutureTask<ProjectSegment>( task );
+ projectBuildFutureTasks.add( projectBuildFutureTask );
+ if ( finishImmediately )
+ {
+ projectBuildFutureTask.run();
+ }
+ return projectBuildFutureTask;
+ }
+
+ public Future<ProjectSegment> submit( Runnable task, ProjectSegment result )
+ {
+ FutureTask<ProjectSegment> projectBuildFutureTask = new FutureTask<ProjectSegment>( task, result );
+ projectBuildFutureTasks.add( projectBuildFutureTask );
+ if ( finishImmediately )
+ {
+ projectBuildFutureTask.run();
+ }
+ return projectBuildFutureTask;
+ }
+
+ public Future<ProjectSegment> take()
+ throws InterruptedException
+ {
+ return null;
+ }
+
+ public Future<ProjectSegment> poll()
+ {
+ return null;
+ }
+
+ public Future<ProjectSegment> poll( long timeout, TimeUnit unit )
+ throws InterruptedException
+ {
+ return null;
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/DefaultLifecyclesStub.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/DefaultLifecyclesStub.java
new file mode 100644
index 00000000..b366953a
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/DefaultLifecyclesStub.java
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.apache.maven.lifecycle.internal.stub;
+
+import org.apache.maven.lifecycle.DefaultLifecycles;
+import org.apache.maven.lifecycle.Lifecycle;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import static org.apache.maven.lifecycle.internal.stub.LifecycleExecutionPlanCalculatorStub.*;
+
+/**
+ * @author Kristian Rosenvold
+ */
+
+public class DefaultLifecyclesStub
+{
+ public static DefaultLifecycles createDefaultLifecycles()
+ {
+
+ List<String> stubDefaultCycle =
+ Arrays.asList( VALIDATE.getPhase(), INITIALIZE.getPhase(), PROCESS_RESOURCES.getPhase(), COMPILE.getPhase(),
+ TEST.getPhase(), PROCESS_TEST_RESOURCES.getPhase(), PACKAGE.getPhase(), "BEER",
+ INSTALL.getPhase() );
+
+ // The two phases below are really for future expansion, some would say they lack a drink
+ // The point being that they do not really have to match the "real" stuff,
+ List<String> stubCleanCycle = Arrays.asList( PRE_CLEAN.getPhase(), CLEAN.getPhase(), POST_CLEAN.getPhase() );
+
+ List<String> stubSiteCycle =
+ Arrays.asList( PRE_SITE.getPhase(), SITE.getPhase(), POST_SITE.getPhase(), SITE_DEPLOY.getPhase() );
+
+ @SuppressWarnings( "unchecked" )
+ Iterator<List<String>> lcs = Arrays.asList( stubDefaultCycle, stubCleanCycle, stubSiteCycle ).iterator();
+
+ Map<String, Lifecycle> lifeCycles = new HashMap<String, Lifecycle>();
+ for ( String s : DefaultLifecycles.STANDARD_LIFECYCLES )
+ {
+ final Lifecycle lifecycle = new Lifecycle( s, lcs.next(), null );
+ lifeCycles.put( s, lifecycle );
+
+ }
+ return new DefaultLifecycles( lifeCycles, new LoggerStub() );
+ }
+
+} \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/ExecutionEventCatapultStub.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/ExecutionEventCatapultStub.java
new file mode 100644
index 00000000..e47ec611
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/ExecutionEventCatapultStub.java
@@ -0,0 +1,42 @@
+package org.apache.maven.lifecycle.internal.stub;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.execution.ExecutionEvent.Type;
+import org.apache.maven.lifecycle.internal.ExecutionEventCatapult;
+import org.apache.maven.plugin.MojoExecution;
+
+/**
+ * @author Benjamin Bentmann
+ */
+public class ExecutionEventCatapultStub
+ implements ExecutionEventCatapult
+{
+
+ public void fire( Type eventType, MavenSession session, MojoExecution mojoExecution )
+ {
+ }
+
+ public void fire( Type eventType, MavenSession session, MojoExecution mojoExecution, Exception exception )
+ {
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/LifeCyclePluginAnalyzerStub.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/LifeCyclePluginAnalyzerStub.java
new file mode 100644
index 00000000..930f5e93
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/LifeCyclePluginAnalyzerStub.java
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.apache.maven.lifecycle.internal.stub;
+
+import org.apache.maven.lifecycle.LifeCyclePluginAnalyzer;
+import org.apache.maven.model.Plugin;
+import org.apache.maven.model.PluginExecution;
+
+import java.util.Collections;
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+/**
+ * @author Kristian Rosenvold
+ */
+public class LifeCyclePluginAnalyzerStub
+ implements LifeCyclePluginAnalyzer
+{
+ public Set<Plugin> getPluginsBoundByDefaultToAllLifecycles( String packaging )
+ {
+ Set<Plugin> plugins;
+
+ // NOTE: The upper-case packaging name is intentional, that's a special hinting mode used for certain tests
+ if ( "JAR".equals( packaging ) )
+ {
+ plugins = new LinkedHashSet<Plugin>();
+
+ plugins.add( newPlugin( "maven-compiler-plugin", "compile", "testCompile" ) );
+ plugins.add( newPlugin( "maven-resources-plugin", "resources", "testResources" ) );
+ plugins.add( newPlugin( "maven-surefire-plugin", "test" ) );
+ plugins.add( newPlugin( "maven-jar-plugin", "jar" ) );
+ plugins.add( newPlugin( "maven-install-plugin", "install" ) );
+ plugins.add( newPlugin( "maven-deploy-plugin", "deploy" ) );
+ }
+ else
+ {
+ plugins = Collections.emptySet();
+ }
+
+ return plugins;
+ }
+
+ private Plugin newPlugin( String artifactId, String... goals )
+ {
+ Plugin plugin = new Plugin();
+
+ plugin.setGroupId( "org.apache.maven.plugins" );
+ plugin.setArtifactId( artifactId );
+
+ for ( String goal : goals )
+ {
+ PluginExecution pluginExecution = new PluginExecution();
+ pluginExecution.setId( "default-" + goal );
+ pluginExecution.addGoal( goal );
+ plugin.addExecution( pluginExecution );
+ }
+
+ return plugin;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/LifecycleExecutionPlanCalculatorStub.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/LifecycleExecutionPlanCalculatorStub.java
new file mode 100644
index 00000000..cd33a353
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/LifecycleExecutionPlanCalculatorStub.java
@@ -0,0 +1,231 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.apache.maven.lifecycle.internal.stub;
+
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.lifecycle.LifecycleNotFoundException;
+import org.apache.maven.lifecycle.LifecyclePhaseNotFoundException;
+import org.apache.maven.lifecycle.MavenExecutionPlan;
+import org.apache.maven.lifecycle.internal.ExecutionPlanItem;
+import org.apache.maven.lifecycle.internal.LifecycleExecutionPlanCalculator;
+import org.apache.maven.lifecycle.internal.ProjectBuildList;
+import org.apache.maven.lifecycle.internal.ProjectSegment;
+import org.apache.maven.model.Plugin;
+import org.apache.maven.plugin.InvalidPluginDescriptorException;
+import org.apache.maven.plugin.MojoExecution;
+import org.apache.maven.plugin.MojoNotFoundException;
+import org.apache.maven.plugin.PluginDescriptorParsingException;
+import org.apache.maven.plugin.PluginNotFoundException;
+import org.apache.maven.plugin.PluginResolutionException;
+import org.apache.maven.plugin.descriptor.MojoDescriptor;
+import org.apache.maven.plugin.descriptor.PluginDescriptor;
+import org.apache.maven.plugin.prefix.NoPluginFoundForPrefixException;
+import org.apache.maven.plugin.version.PluginVersionResolutionException;
+import org.apache.maven.project.MavenProject;
+import org.codehaus.plexus.util.xml.Xpp3Dom;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * @author Kristian Rosenvold
+ */
+public class LifecycleExecutionPlanCalculatorStub
+ implements LifecycleExecutionPlanCalculator
+{
+ // clean
+
+ public final static MojoDescriptor PRE_CLEAN = createMojoDescriptor( "pre-clean" );
+
+ public final static MojoDescriptor CLEAN = createMojoDescriptor( "clean" );
+
+ public final static MojoDescriptor POST_CLEAN = createMojoDescriptor( "post-clean" );
+
+ // default (or at least some of them)
+
+ public final static MojoDescriptor VALIDATE = createMojoDescriptor( "validate" );
+
+ public final static MojoDescriptor INITIALIZE = createMojoDescriptor( "initialize" );
+
+ public final static MojoDescriptor TEST_COMPILE = createMojoDescriptor( "test-compile" );
+
+ public final static MojoDescriptor PROCESS_TEST_RESOURCES = createMojoDescriptor( "process-test-resources" );
+
+ public final static MojoDescriptor PROCESS_RESOURCES = createMojoDescriptor( "process-resources" );
+
+ public final static MojoDescriptor COMPILE = createMojoDescriptor( "compile", true );
+
+ public final static MojoDescriptor TEST = createMojoDescriptor( "test" );
+
+ public final static MojoDescriptor PACKAGE = createMojoDescriptor( "package" );
+
+ public final static MojoDescriptor INSTALL = createMojoDescriptor( "install" );
+
+ // site
+
+ public final static MojoDescriptor PRE_SITE = createMojoDescriptor( "pre-site" );
+
+ public final static MojoDescriptor SITE = createMojoDescriptor( "site" );
+
+ public final static MojoDescriptor POST_SITE = createMojoDescriptor( "post-site" );
+
+ public final static MojoDescriptor SITE_DEPLOY = createMojoDescriptor( "site-deploy" );
+
+
+ public int getNumberOfExceutions( ProjectBuildList projectBuildList )
+ throws InvalidPluginDescriptorException, PluginVersionResolutionException, PluginDescriptorParsingException,
+ NoPluginFoundForPrefixException, MojoNotFoundException, PluginNotFoundException, PluginResolutionException,
+ LifecyclePhaseNotFoundException, LifecycleNotFoundException
+ {
+ int result = 0;
+ for ( ProjectSegment projectBuild : projectBuildList )
+ {
+ MavenExecutionPlan plan = calculateExecutionPlan( projectBuild.getSession(), projectBuild.getProject(),
+ projectBuild.getTaskSegment().getTasks() );
+ result += plan.size();
+ }
+ return result;
+ }
+
+ public void calculateForkedExecutions( MojoExecution mojoExecution, MavenSession session )
+ throws MojoNotFoundException, PluginNotFoundException, PluginResolutionException,
+ PluginDescriptorParsingException, NoPluginFoundForPrefixException, InvalidPluginDescriptorException,
+ LifecyclePhaseNotFoundException, LifecycleNotFoundException, PluginVersionResolutionException
+ {
+ // Maybe do something ?
+ }
+
+ public MavenExecutionPlan calculateExecutionPlan( MavenSession session, MavenProject project, List<Object> tasks,
+ boolean setup )
+ throws PluginNotFoundException, PluginResolutionException, LifecyclePhaseNotFoundException,
+ PluginDescriptorParsingException, MojoNotFoundException, InvalidPluginDescriptorException,
+ NoPluginFoundForPrefixException, LifecycleNotFoundException, PluginVersionResolutionException
+ {
+ if ( project.equals( ProjectDependencyGraphStub.A ) )
+ {
+ return getProjectAExceutionPlan();
+ }
+ if ( project.equals( ProjectDependencyGraphStub.B ) )
+ {
+ return getProjectBExecutionPlan();
+ }
+ // The remaining are basically "for future expansion"
+ List<MojoExecution> me = new ArrayList<MojoExecution>();
+ me.add( createMojoExecution( "resources", "default-resources", PROCESS_RESOURCES ) );
+ me.add( createMojoExecution( "compile", "default-compile", COMPILE ) );
+ return createExecutionPlan( project, me );
+ }
+
+ public MavenExecutionPlan calculateExecutionPlan( MavenSession session, MavenProject project, List<Object> tasks )
+ throws PluginNotFoundException, PluginResolutionException, LifecyclePhaseNotFoundException,
+ PluginDescriptorParsingException, MojoNotFoundException, InvalidPluginDescriptorException,
+ NoPluginFoundForPrefixException, LifecycleNotFoundException, PluginVersionResolutionException
+ {
+ return calculateExecutionPlan( session, project, tasks, true );
+ }
+
+ public void setupMojoExecution( MavenSession session, MavenProject project, MojoExecution mojoExecution )
+ throws PluginNotFoundException, PluginResolutionException, PluginDescriptorParsingException,
+ MojoNotFoundException, InvalidPluginDescriptorException, NoPluginFoundForPrefixException,
+ LifecyclePhaseNotFoundException, LifecycleNotFoundException, PluginVersionResolutionException
+ {
+ }
+
+ public static MavenExecutionPlan getProjectAExceutionPlan()
+ throws PluginNotFoundException, PluginResolutionException, LifecyclePhaseNotFoundException,
+ PluginDescriptorParsingException, MojoNotFoundException, InvalidPluginDescriptorException,
+ NoPluginFoundForPrefixException, LifecycleNotFoundException, PluginVersionResolutionException
+ {
+ List<MojoExecution> me = new ArrayList<MojoExecution>();
+ me.add( createMojoExecution( "initialize", "default-initialize", INITIALIZE ) );
+ me.add( createMojoExecution( "resources", "default-resources", PROCESS_RESOURCES ) );
+ me.add( createMojoExecution( "compile", "default-compile", COMPILE ) );
+ me.add( createMojoExecution( "testResources", "default-testResources", PROCESS_TEST_RESOURCES ) );
+ me.add( createMojoExecution( "testCompile", "default-testCompile", TEST_COMPILE ) );
+ me.add( createMojoExecution( "test", "default-test", TEST ) );
+ me.add( createMojoExecution( "war", "default-war", PACKAGE ) );
+ me.add( createMojoExecution( "install", "default-install", INSTALL ) );
+ return createExecutionPlan( ProjectDependencyGraphStub.A.getExecutionProject(), me );
+ }
+
+ public static MavenExecutionPlan getProjectBExecutionPlan()
+ throws PluginNotFoundException, PluginResolutionException, LifecyclePhaseNotFoundException,
+ PluginDescriptorParsingException, MojoNotFoundException, InvalidPluginDescriptorException,
+ NoPluginFoundForPrefixException, LifecycleNotFoundException, PluginVersionResolutionException
+ {
+ List<MojoExecution> me = new ArrayList<MojoExecution>();
+ me.add( createMojoExecution( "enforce", "enforce-versions", VALIDATE ) );
+ me.add( createMojoExecution( "resources", "default-resources", PROCESS_RESOURCES ) );
+ me.add( createMojoExecution( "compile", "default-compile", COMPILE ) );
+ me.add( createMojoExecution( "testResources", "default-testResources", PROCESS_TEST_RESOURCES ) );
+ me.add( createMojoExecution( "testCompile", "default-testCompile", TEST_COMPILE ) );
+ me.add( createMojoExecution( "test", "default-test", TEST ) );
+ return createExecutionPlan( ProjectDependencyGraphStub.B.getExecutionProject(), me );
+ }
+
+
+ private static MavenExecutionPlan createExecutionPlan( MavenProject project, List<MojoExecution> mojoExecutions )
+ throws InvalidPluginDescriptorException, PluginVersionResolutionException, PluginDescriptorParsingException,
+ NoPluginFoundForPrefixException, MojoNotFoundException, PluginNotFoundException, PluginResolutionException,
+ LifecyclePhaseNotFoundException, LifecycleNotFoundException
+ {
+ final List<ExecutionPlanItem> planItemList =
+ ExecutionPlanItem.createExecutionPlanItems( project, mojoExecutions );
+ return new MavenExecutionPlan( planItemList, DefaultLifecyclesStub.createDefaultLifecycles() );
+ }
+
+ private static MojoExecution createMojoExecution( String goal, String executionId, MojoDescriptor mojoDescriptor )
+ {
+ final Plugin plugin = mojoDescriptor.getPluginDescriptor().getPlugin();
+ MojoExecution result = new MojoExecution( plugin, goal, executionId );
+ result.setConfiguration( new Xpp3Dom( executionId + "-" + goal ) );
+ result.setMojoDescriptor( mojoDescriptor );
+ result.setLifecyclePhase( mojoDescriptor.getPhase() );
+
+ return result;
+
+ }
+
+ public static MojoDescriptor createMojoDescriptor( String phaseName )
+ {
+ return createMojoDescriptor( phaseName, false );
+ }
+
+ public static MojoDescriptor createMojoDescriptor( String phaseName, boolean threadSafe )
+ {
+ final MojoDescriptor mojoDescriptor = new MojoDescriptor();
+ mojoDescriptor.setPhase( phaseName );
+ final PluginDescriptor descriptor = new PluginDescriptor();
+ Plugin plugin = new Plugin();
+ plugin.setArtifactId( "org.apache.maven.test.MavenExecutionPlan" );
+ plugin.setGroupId( "stub-plugin-" + phaseName );
+ descriptor.setPlugin( plugin );
+ descriptor.setArtifactId( "artifact." + phaseName );
+ mojoDescriptor.setPluginDescriptor( descriptor );
+ mojoDescriptor.setThreadSafe( threadSafe );
+ return mojoDescriptor;
+ }
+
+
+ public static Set<String> getScopes()
+ {
+ return new HashSet<String>( Arrays.asList( "compile" ) );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/LifecycleTaskSegmentCalculatorStub.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/LifecycleTaskSegmentCalculatorStub.java
new file mode 100644
index 00000000..695d66dd
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/LifecycleTaskSegmentCalculatorStub.java
@@ -0,0 +1,89 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.apache.maven.lifecycle.internal.stub;
+
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.lifecycle.internal.GoalTask;
+import org.apache.maven.lifecycle.internal.LifecycleTask;
+import org.apache.maven.lifecycle.internal.DefaultLifecycleTaskSegmentCalculator;
+import org.apache.maven.lifecycle.internal.TaskSegment;
+import org.apache.maven.plugin.InvalidPluginDescriptorException;
+import org.apache.maven.plugin.MojoNotFoundException;
+import org.apache.maven.plugin.PluginDescriptorParsingException;
+import org.apache.maven.plugin.PluginNotFoundException;
+import org.apache.maven.plugin.PluginResolutionException;
+import org.apache.maven.plugin.prefix.NoPluginFoundForPrefixException;
+import org.apache.maven.plugin.version.PluginVersionResolutionException;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Kristian Rosenvold
+ */
+public class LifecycleTaskSegmentCalculatorStub
+ extends DefaultLifecycleTaskSegmentCalculator
+{
+ public static final String clean = "clean";
+
+ public static final String aggr = "aggr";
+
+ public static final String install = "install";
+
+
+ public List<TaskSegment> calculateTaskSegments( MavenSession session, List<String> tasks )
+ throws PluginNotFoundException, PluginResolutionException, PluginDescriptorParsingException,
+ MojoNotFoundException, NoPluginFoundForPrefixException, InvalidPluginDescriptorException,
+ PluginVersionResolutionException
+ {
+ List<TaskSegment> taskSegments = new ArrayList<TaskSegment>( tasks.size() );
+
+ TaskSegment currentSegment = null;
+
+ for ( String task : tasks )
+ {
+ if ( aggr.equals( task ) )
+ {
+ boolean aggregating = true;
+
+ if ( currentSegment == null || currentSegment.isAggregating() != aggregating )
+ {
+ currentSegment = new TaskSegment( aggregating );
+ taskSegments.add( currentSegment );
+ }
+
+ currentSegment.getTasks().add( new GoalTask( task ) );
+ }
+ else
+ {
+ // lifecycle phase
+ if ( currentSegment == null || currentSegment.isAggregating() )
+ {
+ currentSegment = new TaskSegment( false );
+ taskSegments.add( currentSegment );
+ }
+ currentSegment.getTasks().add( new LifecycleTask( task ) );
+ }
+ }
+
+ return taskSegments;
+ }
+
+ public boolean requiresProject( MavenSession session )
+ {
+ return true;
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/LoggerStub.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/LoggerStub.java
new file mode 100644
index 00000000..00bb3cfa
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/LoggerStub.java
@@ -0,0 +1,110 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.apache.maven.lifecycle.internal.stub;
+
+import org.codehaus.plexus.logging.Logger;
+
+/**
+ * @author Kristian Rosenvold
+ */
+public class LoggerStub
+ implements Logger
+{
+ public void debug( String s )
+ {
+ }
+
+ public void debug( String s, Throwable throwable )
+ {
+ }
+
+ public boolean isDebugEnabled()
+ {
+ return true;
+ }
+
+ public void info( String s )
+ {
+ }
+
+ public void info( String s, Throwable throwable )
+ {
+ }
+
+ public boolean isInfoEnabled()
+ {
+ return true;
+ }
+
+ public void warn( String s )
+ {
+ }
+
+ public void warn( String s, Throwable throwable )
+ {
+ }
+
+ public boolean isWarnEnabled()
+ {
+ return true;
+ }
+
+ public void error( String s )
+ {
+ }
+
+ public void error( String s, Throwable throwable )
+ {
+ }
+
+ public boolean isErrorEnabled()
+ {
+ return true;
+ }
+
+ public void fatalError( String s )
+ {
+ }
+
+ public void fatalError( String s, Throwable throwable )
+ {
+ }
+
+ public boolean isFatalErrorEnabled()
+ {
+ return true;
+ }
+
+ public Logger getChildLogger( String s )
+ {
+ return null;
+ }
+
+ public int getThreshold()
+ {
+ return 0;
+ }
+
+ public void setThreshold( int i )
+ {
+
+ }
+
+ public String getName()
+ {
+ return "StubLogger";
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/MojoExecutorStub.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/MojoExecutorStub.java
new file mode 100644
index 00000000..a8572ffc
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/MojoExecutorStub.java
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.apache.maven.lifecycle.internal.stub;
+
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.lifecycle.LifecycleExecutionException;
+import org.apache.maven.lifecycle.internal.DependencyContext;
+import org.apache.maven.lifecycle.internal.MojoExecutor;
+import org.apache.maven.lifecycle.internal.PhaseRecorder;
+import org.apache.maven.lifecycle.internal.ProjectIndex;
+import org.apache.maven.plugin.MojoExecution;
+import org.apache.maven.plugin.descriptor.MojoDescriptor;
+import org.apache.maven.plugin.descriptor.PluginDescriptor;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * @author Kristian Rosenvold
+ */
+public class MojoExecutorStub
+ extends MojoExecutor
+{ // This is being lazy instead of making interface
+
+ public List<MojoExecution> executions = Collections.synchronizedList( new ArrayList<MojoExecution>() );
+
+ @Override
+ public void execute( MavenSession session, MojoExecution mojoExecution, ProjectIndex projectIndex,
+ DependencyContext dependencyContext, PhaseRecorder phaseRecorder )
+ throws LifecycleExecutionException
+ {
+ executions.add( mojoExecution );
+ }
+
+ @Override
+ public void execute( MavenSession session, List<MojoExecution> mojoExecutions, ProjectIndex projectIndex )
+ throws LifecycleExecutionException
+ {
+ for ( MojoExecution mojoExecution : mojoExecutions )
+ {
+ executions.add( mojoExecution );
+ }
+ }
+
+
+ public static MojoDescriptor createMojoDescriptor( String mojoDescription )
+ {
+ final PluginDescriptor descriptor = new PluginDescriptor();
+ descriptor.setArtifactId( mojoDescription );
+ final MojoDescriptor mojoDescriptor = new MojoDescriptor();
+ mojoDescriptor.setDescription( mojoDescription );
+ mojoDescriptor.setPluginDescriptor( descriptor );
+ return mojoDescriptor;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/PluginPrefixResolverStub.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/PluginPrefixResolverStub.java
new file mode 100644
index 00000000..a4b54e98
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/PluginPrefixResolverStub.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.apache.maven.lifecycle.internal.stub;
+
+import org.apache.maven.plugin.prefix.NoPluginFoundForPrefixException;
+import org.apache.maven.plugin.prefix.PluginPrefixRequest;
+import org.apache.maven.plugin.prefix.PluginPrefixResolver;
+import org.apache.maven.plugin.prefix.PluginPrefixResult;
+import org.eclipse.aether.repository.ArtifactRepository;
+
+/**
+ * @author Kristian Rosenvold
+ */
+
+public class PluginPrefixResolverStub
+ implements PluginPrefixResolver
+{
+ public PluginPrefixResult resolve( PluginPrefixRequest request )
+ throws NoPluginFoundForPrefixException
+ {
+ return new PluginPrefixResult()
+ {
+ public String getGroupId()
+ {
+ return "com.foobar";
+ }
+
+ public String getArtifactId()
+ {
+ return "bazbaz";
+ }
+
+ public ArtifactRepository getRepository()
+ {
+ return null;
+ }
+ };
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/PluginVersionResolverStub.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/PluginVersionResolverStub.java
new file mode 100644
index 00000000..c79658e8
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/PluginVersionResolverStub.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.apache.maven.lifecycle.internal.stub;
+
+import org.apache.maven.plugin.version.PluginVersionRequest;
+import org.apache.maven.plugin.version.PluginVersionResolutionException;
+import org.apache.maven.plugin.version.PluginVersionResolver;
+import org.apache.maven.plugin.version.PluginVersionResult;
+import org.eclipse.aether.repository.ArtifactRepository;
+
+/**
+ * @author Kristian Rosenvold
+ */
+
+public class PluginVersionResolverStub
+ implements PluginVersionResolver
+{
+
+ public PluginVersionResult resolve( PluginVersionRequest request )
+ throws PluginVersionResolutionException
+ {
+ return new PluginVersionResult()
+ {
+ public String getVersion()
+ {
+ return "0.42";
+ }
+
+ public ArtifactRepository getRepository()
+ {
+ return null;
+ }
+ };
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/ProjectDependenciesResolverStub.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/ProjectDependenciesResolverStub.java
new file mode 100644
index 00000000..4147b36c
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/ProjectDependenciesResolverStub.java
@@ -0,0 +1,109 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.apache.maven.lifecycle.internal.stub;
+
+import org.apache.maven.ProjectDependenciesResolver;
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
+import org.apache.maven.artifact.resolver.ArtifactResolutionException;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.project.DependencyResolutionException;
+import org.apache.maven.project.DependencyResolutionRequest;
+import org.apache.maven.project.DependencyResolutionResult;
+import org.apache.maven.project.MavenProject;
+import org.eclipse.aether.graph.DefaultDependencyNode;
+import org.eclipse.aether.graph.Dependency;
+import org.eclipse.aether.graph.DependencyNode;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * @author Kristian Rosenvold
+ */
+public class ProjectDependenciesResolverStub
+ implements ProjectDependenciesResolver, org.apache.maven.project.ProjectDependenciesResolver
+{
+ public Set<Artifact> resolve( MavenProject project, Collection<String> scopesToResolve, MavenSession session )
+ throws ArtifactResolutionException, ArtifactNotFoundException
+ {
+ return new HashSet<Artifact>();
+ }
+
+ public Set<Artifact> resolve( MavenProject project, Collection<String> scopesToCollect,
+ Collection<String> scopesToResolve, MavenSession session )
+ throws ArtifactResolutionException, ArtifactNotFoundException
+ {
+ return new HashSet<Artifact>();
+ }
+
+ public Set<Artifact> resolve( Collection<? extends MavenProject> projects, Collection<String> scopes,
+ MavenSession session )
+ throws ArtifactResolutionException, ArtifactNotFoundException
+ {
+ return new HashSet<Artifact>();
+ }
+
+ public Set<Artifact> resolve( MavenProject project, Collection<String> scopesToCollect,
+ Collection<String> scopesToResolve, MavenSession session,
+ Set<Artifact> ignoreableArtifacts )
+ throws ArtifactResolutionException, ArtifactNotFoundException
+ {
+ return new HashSet<Artifact>();
+ }
+
+ public DependencyResolutionResult resolve( DependencyResolutionRequest request )
+ throws DependencyResolutionException
+ {
+ return new DependencyResolutionResult()
+ {
+
+ public List<Dependency> getUnresolvedDependencies()
+ {
+ return Collections.emptyList();
+ }
+
+ public List<Dependency> getResolvedDependencies()
+ {
+ return Collections.emptyList();
+ }
+
+ public List<Exception> getResolutionErrors( Dependency dependency )
+ {
+ return Collections.emptyList();
+ }
+
+ public DependencyNode getDependencyGraph()
+ {
+ return new DefaultDependencyNode( (Dependency) null );
+ }
+
+ public List<Dependency> getDependencies()
+ {
+ return Collections.emptyList();
+ }
+
+ public List<Exception> getCollectionErrors()
+ {
+ return Collections.emptyList();
+ }
+ };
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/ProjectDependencyGraphStub.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/ProjectDependencyGraphStub.java
new file mode 100644
index 00000000..38e9fcad
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/ProjectDependencyGraphStub.java
@@ -0,0 +1,227 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.apache.maven.lifecycle.internal.stub;
+
+import org.apache.maven.execution.AbstractExecutionListener;
+import org.apache.maven.execution.DefaultMavenExecutionRequest;
+import org.apache.maven.execution.DefaultMavenExecutionResult;
+import org.apache.maven.execution.MavenExecutionRequest;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.execution.ProjectDependencyGraph;
+import org.apache.maven.lifecycle.LifecycleNotFoundException;
+import org.apache.maven.lifecycle.LifecyclePhaseNotFoundException;
+import org.apache.maven.lifecycle.internal.GoalTask;
+import org.apache.maven.lifecycle.internal.ProjectBuildList;
+import org.apache.maven.lifecycle.internal.ProjectSegment;
+import org.apache.maven.lifecycle.internal.TaskSegment;
+import org.apache.maven.plugin.InvalidPluginDescriptorException;
+import org.apache.maven.plugin.MojoNotFoundException;
+import org.apache.maven.plugin.PluginDescriptorParsingException;
+import org.apache.maven.plugin.PluginNotFoundException;
+import org.apache.maven.plugin.PluginResolutionException;
+import org.apache.maven.plugin.prefix.NoPluginFoundForPrefixException;
+import org.apache.maven.plugin.version.PluginVersionResolutionException;
+import org.apache.maven.project.MavenProject;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * A stub dependency graph that is custom made for testing concurrent build graph evaluations.
+ * <p/>
+ * Implements a graph as follows:
+ * A has no dependencies
+ * B depends on A
+ * C depends on A
+ * X depends on B & C
+ * Y depends on B
+ * Z depends on C
+ *
+ * @author Kristian Rosenvold
+ */
+public class ProjectDependencyGraphStub
+ implements ProjectDependencyGraph
+{
+ public static final MavenProject A = new MavenProject();
+
+ public static final MavenProject B = new MavenProject();
+
+ public static final MavenProject C = new MavenProject();
+
+ public static final MavenProject X = new MavenProject();
+
+ public static final MavenProject Y = new MavenProject();
+
+ public static final MavenProject Z = new MavenProject();
+
+ public static final MavenProject UNKNOWN = new MavenProject();
+
+ static
+ {
+ A.setArtifactId( "A" );
+ B.setArtifactId( "B" );
+ C.setArtifactId( "C" );
+ X.setArtifactId( "X" );
+ Y.setArtifactId( "Y" );
+ Z.setArtifactId( "Z" );
+ }
+
+ // This should probably be moved to a separate stub
+
+ public static ProjectBuildList getProjectBuildList( MavenSession session )
+ throws InvalidPluginDescriptorException, PluginVersionResolutionException, PluginDescriptorParsingException,
+ NoPluginFoundForPrefixException, MojoNotFoundException, PluginNotFoundException, PluginResolutionException,
+ LifecyclePhaseNotFoundException, LifecycleNotFoundException
+ {
+ final List<ProjectSegment> list = getProjectBuilds( session );
+ return new ProjectBuildList( list );
+
+ }
+
+ public static List<ProjectSegment> getProjectBuilds( MavenSession session )
+ throws InvalidPluginDescriptorException, PluginVersionResolutionException, PluginDescriptorParsingException,
+ NoPluginFoundForPrefixException, PluginNotFoundException, MojoNotFoundException, PluginResolutionException,
+ LifecyclePhaseNotFoundException, LifecycleNotFoundException
+ {
+ List<ProjectSegment> projectBuilds = new ArrayList<ProjectSegment>();
+
+ TaskSegment segment = createTaskSegment();
+ projectBuilds.add( createProjectBuild( A, session, segment ) );
+ projectBuilds.add( createProjectBuild( B, session, segment ) );
+ projectBuilds.add( createProjectBuild( C, session, segment ) );
+ projectBuilds.add( createProjectBuild( X, session, segment ) );
+ projectBuilds.add( createProjectBuild( Y, session, segment ) );
+ projectBuilds.add( createProjectBuild( Z, session, segment ) );
+ return projectBuilds;
+ }
+
+ private static ProjectSegment createProjectBuild( MavenProject project, MavenSession session,
+ TaskSegment taskSegment )
+ throws InvalidPluginDescriptorException, PluginVersionResolutionException, PluginDescriptorParsingException,
+ NoPluginFoundForPrefixException, MojoNotFoundException, PluginNotFoundException, PluginResolutionException,
+ LifecyclePhaseNotFoundException, LifecycleNotFoundException
+ {
+ final MavenSession session1 = session.clone();
+ return new ProjectSegment( project, taskSegment, session1 );
+ }
+
+
+ private static TaskSegment createTaskSegment()
+ {
+ TaskSegment result = new TaskSegment( false );
+ result.getTasks().add( new GoalTask( "t1" ) );
+ result.getTasks().add( new GoalTask( "t2" ) );
+ return result;
+ }
+
+ class Dependency
+ {
+ MavenProject dependant;
+
+ MavenProject dependency;
+
+ Dependency( MavenProject dependant, MavenProject dependency )
+ {
+ this.dependant = dependant;
+ this.dependency = dependency;
+ }
+
+ void addIfDownstream( MavenProject mavenProject, List<MavenProject> result )
+ {
+ if ( dependency == mavenProject )
+ {
+ result.add( dependant );
+ }
+ }
+
+ void addIfUpstreamOf( MavenProject mavenProject, List<MavenProject> result )
+ {
+ if ( dependant == mavenProject )
+ {
+ result.add( dependency ); // All projects are the statics from this class
+ }
+ }
+ }
+
+ private List<Dependency> getDependencies()
+ {
+ List<Dependency> dependencies = new ArrayList<Dependency>();
+ dependencies.add( new Dependency( B, A ) );
+ dependencies.add( new Dependency( C, A ) );
+ dependencies.add( new Dependency( X, B ) );
+ dependencies.add( new Dependency( X, C ) );
+ dependencies.add( new Dependency( Y, B ) );
+ dependencies.add( new Dependency( Z, C ) );
+ return dependencies;
+ }
+
+ public List<MavenProject> getSortedProjects()
+ {
+ return Arrays.asList( A, B, C, X, Y, Z ); // I'm not entirely sure about the order but this shold do...
+ }
+
+ public List<MavenProject> getDownstreamProjects( MavenProject project, boolean transitive )
+ {
+ if ( transitive )
+ {
+ throw new RuntimeException( "Not implemented yet" );
+ }
+ List<MavenProject> result = new ArrayList<MavenProject>();
+ for ( Dependency dependency : getDependencies() )
+ {
+ dependency.addIfDownstream( project, result );
+ }
+ return result;
+ }
+
+ public List<MavenProject> getUpstreamProjects( MavenProject project, boolean transitive )
+ {
+ /* if ( transitive )
+ {
+ throw new RuntimeException( "Not implemented yet" );
+ }*/
+ List<MavenProject> result = new ArrayList<MavenProject>();
+ final List<Dependency> dependencies = getDependencies();
+ for ( Dependency dependency : dependencies )
+ {
+ dependency.addIfUpstreamOf( project, result );
+ }
+ return result;
+ }
+
+ public static MavenSession getMavenSession( MavenProject mavenProject )
+ {
+ final MavenSession session = getMavenSession();
+ session.setCurrentProject( mavenProject );
+ return session;
+ }
+
+ public static MavenSession getMavenSession()
+ {
+ final DefaultMavenExecutionResult defaultMavenExecutionResult = new DefaultMavenExecutionResult();
+ MavenExecutionRequest mavenExecutionRequest = new DefaultMavenExecutionRequest();
+ mavenExecutionRequest.setExecutionListener( new AbstractExecutionListener() );
+ mavenExecutionRequest.setGoals( Arrays.asList( "clean", "aggr", "install" ) );
+ mavenExecutionRequest.setDegreeOfConcurrency( 1 );
+ final MavenSession session = new MavenSession( null, null, mavenExecutionRequest, defaultMavenExecutionResult );
+ final ProjectDependencyGraphStub dependencyGraphStub = new ProjectDependencyGraphStub();
+ session.setProjectDependencyGraph( dependencyGraphStub );
+ session.setProjects( dependencyGraphStub.getSortedProjects() );
+ return session;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/ProjectDependencyGraphStubTest.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/ProjectDependencyGraphStubTest.java
new file mode 100644
index 00000000..8c605723
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/ProjectDependencyGraphStubTest.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.apache.maven.lifecycle.internal.stub;
+
+import junit.framework.TestCase;
+import org.apache.maven.project.MavenProject;
+
+import java.util.List;
+
+
+/**
+ * Tests the stub. Yeah, I know.
+ *
+ * @author Kristian Rosenvold
+ */
+
+public class ProjectDependencyGraphStubTest
+ extends TestCase
+{
+ public void testADependencies()
+ {
+ ProjectDependencyGraphStub stub = new ProjectDependencyGraphStub();
+ final List<MavenProject> mavenProjects = stub.getUpstreamProjects( ProjectDependencyGraphStub.A, false );
+ assertEquals( 0, mavenProjects.size() );
+ }
+
+ public void testBDepenencies( ProjectDependencyGraphStub stub )
+ {
+ final List<MavenProject> bProjects = stub.getUpstreamProjects( ProjectDependencyGraphStub.B, false );
+ assertEquals( 1, bProjects.size() );
+ assertTrue( bProjects.contains( ProjectDependencyGraphStub.A ) );
+ }
+
+ public void testCDepenencies( ProjectDependencyGraphStub stub )
+ {
+ final List<MavenProject> cProjects = stub.getUpstreamProjects( ProjectDependencyGraphStub.C, false );
+ assertEquals( 1, cProjects.size() );
+ assertTrue( cProjects.contains( ProjectDependencyGraphStub.C ) );
+ }
+
+ public void testXDepenencies( ProjectDependencyGraphStub stub )
+ {
+ final List<MavenProject> cProjects = stub.getUpstreamProjects( ProjectDependencyGraphStub.X, false );
+ assertEquals( 2, cProjects.size() );
+ assertTrue( cProjects.contains( ProjectDependencyGraphStub.C ) );
+ assertTrue( cProjects.contains( ProjectDependencyGraphStub.B ) );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/plugin/PluginManagerTest.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/plugin/PluginManagerTest.java
new file mode 100644
index 00000000..025e7725
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/plugin/PluginManagerTest.java
@@ -0,0 +1,342 @@
+package org.apache.maven.plugin;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.List;
+
+import org.apache.maven.AbstractCoreMavenComponentTestCase;
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.repository.DefaultRepositoryRequest;
+import org.apache.maven.artifact.repository.RepositoryRequest;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.model.Plugin;
+import org.apache.maven.plugin.descriptor.MojoDescriptor;
+import org.apache.maven.plugin.descriptor.PluginDescriptor;
+import org.apache.maven.project.MavenProject;
+import org.codehaus.plexus.classworlds.realm.ClassRealm;
+import org.codehaus.plexus.component.annotations.Requirement;
+import org.codehaus.plexus.component.repository.ComponentDescriptor;
+
+public class PluginManagerTest
+ extends AbstractCoreMavenComponentTestCase
+{
+ @Requirement
+ private DefaultBuildPluginManager pluginManager;
+
+ protected void setUp()
+ throws Exception
+ {
+ super.setUp();
+ pluginManager = (DefaultBuildPluginManager) lookup( BuildPluginManager.class );
+ }
+
+ @Override
+ protected void tearDown()
+ throws Exception
+ {
+ pluginManager = null;
+ super.tearDown();
+ }
+
+ protected String getProjectsDirectory()
+ {
+ return "src/test/projects/plugin-manager";
+ }
+
+ public void testPluginLoading()
+ throws Exception
+ {
+ MavenSession session = createMavenSession( null );
+ Plugin plugin = new Plugin();
+ plugin.setGroupId( "org.apache.maven.its.plugins" );
+ plugin.setArtifactId( "maven-it-plugin" );
+ plugin.setVersion( "0.1" );
+ PluginDescriptor pluginDescriptor =
+ pluginManager.loadPlugin( plugin, session.getCurrentProject().getRemotePluginRepositories(),
+ session.getRepositorySession() );
+ assertNotNull( pluginDescriptor );
+ }
+
+ public void testMojoDescriptorRetrieval()
+ throws Exception
+ {
+ MavenSession session = createMavenSession( null );
+ String goal = "it";
+ Plugin plugin = new Plugin();
+ plugin.setGroupId( "org.apache.maven.its.plugins" );
+ plugin.setArtifactId( "maven-it-plugin" );
+ plugin.setVersion( "0.1" );
+
+ MojoDescriptor mojoDescriptor =
+ pluginManager.getMojoDescriptor( plugin, goal, session.getCurrentProject().getRemotePluginRepositories(),
+ session.getRepositorySession() );
+ assertNotNull( mojoDescriptor );
+ assertEquals( goal, mojoDescriptor.getGoal() );
+ // igorf: plugin realm comes later
+ // assertNotNull( mojoDescriptor.getRealm() );
+
+ PluginDescriptor pluginDescriptor = mojoDescriptor.getPluginDescriptor();
+ assertNotNull( pluginDescriptor );
+ assertEquals( "org.apache.maven.its.plugins", pluginDescriptor.getGroupId() );
+ assertEquals( "maven-it-plugin", pluginDescriptor.getArtifactId() );
+ assertEquals( "0.1", pluginDescriptor.getVersion() );
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Tests which exercise the lifecycle executor when it is dealing with individual goals.
+ // -----------------------------------------------------------------------------------------------
+
+ //TODO: These two tests display a lack of symmetry with respect to the input which is a free form string and the
+ // mojo descriptor which comes back. All the free form parsing needs to be done somewhere else, this is
+ // really the function of the CLI, and then the pre-processing of that output still needs to be fed into
+ // a hinting process which helps flesh out the full specification of the plugin. The plugin manager should
+ // only deal in concrete terms -- all version finding mumbo jumbo is a customization to base functionality
+ // the plugin manager provides.
+
+ public void testRemoteResourcesPlugin()
+ throws Exception
+ {
+ //TODO: turn an equivalent back on when the RR plugin is released.
+
+ /*
+
+ This will not work until the RR plugin is released to get rid of the binding to the reporting exception which is a mistake.
+
+ This happpens after removing the reporting API from the core:
+
+ java.lang.NoClassDefFoundError: org/apache/maven/reporting/MavenReportException
+
+ MavenSession session = createMavenSession( getProject( "project-with-inheritance" ) );
+ String goal = "process";
+
+ Plugin plugin = new Plugin();
+ plugin.setGroupId( "org.apache.maven.plugins" );
+ plugin.setArtifactId( "maven-remote-resources-plugin" );
+ plugin.setVersion( "1.0-beta-2" );
+
+ MojoDescriptor mojoDescriptor = pluginManager.getMojoDescriptor( plugin, goal, session.getCurrentProject(), session.getLocalRepository() );
+ assertPluginDescriptor( mojoDescriptor, "org.apache.maven.plugins", "maven-remote-resources-plugin", "1.0-beta-2" );
+ MojoExecution mojoExecution = new MojoExecution( mojoDescriptor );
+ pluginManager.executeMojo( session, mojoExecution );
+ */
+ }
+
+ //TODO: this will be the basis of the customizable lifecycle execution so need to figure this out quickly.
+ public void testSurefirePlugin()
+ throws Exception
+ {
+ /*
+ MavenSession session = createMavenSession( getProject( "project-with-inheritance" ) );
+ String goal = "test";
+
+ Plugin plugin = new Plugin();
+ plugin.setGroupId( "org.apache.maven.plugins" );
+ plugin.setArtifactId( "maven-surefire-plugin" );
+ plugin.setVersion( "2.4.2" );
+
+ // The project has already been fully interpolated so getting the raw mojoDescriptor is not going to have the processes configuration.
+ MojoDescriptor mojoDescriptor = pluginManager.getMojoDescriptor( plugin, goal, session.getLocalRepository(), session.getCurrentProject().getPluginArtifactRepositories() );
+ assertPluginDescriptor( mojoDescriptor, "org.apache.maven.plugins", "maven-surefire-plugin", "2.4.2" );
+
+ System.out.println( session.getCurrentProject().getBuild().getPluginsAsMap() );
+
+ Xpp3Dom configuration = (Xpp3Dom) session.getCurrentProject().getBuild().getPluginsAsMap().get( plugin.getKey() ).getExecutions().get( 0 ).getConfiguration();
+ MojoExecution mojoExecution = new MojoExecution( mojoDescriptor, configuration );
+ pluginManager.executeMojo( session, mojoExecution );
+ */
+ }
+
+ public void testMojoConfigurationIsMergedCorrectly()
+ throws Exception
+ {
+ }
+
+ /**
+ * The case where the user wants to specify an alternate version of the underlying tool. Common case
+ * is in the Antlr plugin which comes bundled with a version of Antlr but the user often times needs
+ * to use a specific version. We need to make sure the version that they specify takes precedence.
+ */
+ public void testMojoWhereInternallyStatedDependencyIsOverriddenByProject()
+ throws Exception
+ {
+ }
+
+ /**
+ * The case where you have a plugin in the current build that you want to be used on projects in
+ * the current build.
+ */
+ public void testMojoThatIsPresentInTheCurrentBuild()
+ throws Exception
+ {
+ }
+
+ /**
+ * This is the case where the Mojo wants to execute on every project and then do something at the end
+ * with the results of each project.
+ */
+ public void testAggregatorMojo()
+ throws Exception
+ {
+ }
+
+ /**
+ * This is the case where a Mojo needs the lifecycle run to a certain phase before it can do
+ * anything useful.
+ */
+ public void testMojoThatRequiresExecutionToAGivenPhaseBeforeExecutingItself()
+ throws Exception
+ {
+ }
+
+ // test that mojo which does not require dependency resolution trigger no downloading of dependencies
+
+ // test interpolation of basedir values in mojo configuration
+
+ // test a build where projects use different versions of the same plugin
+
+ public void testThatPluginDependencyThatHasSystemScopeIsResolved()
+ throws Exception
+ {
+ /*
+ File systemPath = new File( getBasedir(), "pom.xml" );
+
+ Plugin plugin = new PluginBuilder( "org.apache.maven", "project-test", "1.0" )
+ .addDependency( "org.apache.maven", "system-dependency", "1.0", Artifact.SCOPE_SYSTEM, systemPath.getAbsolutePath() )
+ .get();
+
+ MavenProject pluginProject = new ProjectBuilder( "org.apache.maven", "project-test", "1.0" )
+ .addPlugin( plugin )
+ .addDependency( "junit", "junit", "3.8.1", Artifact.SCOPE_COMPILE )
+ .get();
+
+ // i'm making this artifact which is assumed to come from a pom in the metadata processor, then it tries to create a POM artifact
+ // and parse it for the dependencies and it blows up.
+ //
+ // we need to pass this through as is so it doesn't get parsed again.
+ Artifact pluginArtifact = new ProjectArtifact( pluginProject );
+
+ Set<Artifact> artifacts = pluginManager.getPluginArtifacts( pluginArtifact, plugin, getLocalRepository(), getPluginArtifactRepositories() );
+ System.out.println( artifacts );
+ */
+
+ MavenSession session = createMavenSession( getProject( "project-contributing-system-scope-plugin-dep" ) );
+ MavenProject project = session.getCurrentProject();
+ Plugin plugin = project.getPlugin( "org.apache.maven.its.plugins:maven-it-plugin" );
+
+ RepositoryRequest repositoryRequest = new DefaultRepositoryRequest();
+ repositoryRequest.setLocalRepository( getLocalRepository() );
+ repositoryRequest.setRemoteRepositories( getPluginArtifactRepositories() );
+
+ PluginDescriptor pluginDescriptor =
+ pluginManager.loadPlugin( plugin, session.getCurrentProject().getRemotePluginRepositories(),
+ session.getRepositorySession() );
+ pluginManager.getPluginRealm( session, pluginDescriptor );
+ List<Artifact> artifacts = pluginDescriptor.getArtifacts();
+
+ for ( Artifact a : artifacts )
+ {
+ if ( a.getGroupId().equals( "org.apache.maven.its.mng3586" ) && a.getArtifactId().equals( "tools" ) )
+ {
+ // The system scoped dependencies will be present in the classloader for the plugin
+ return;
+ }
+ }
+
+ fail( "Can't find the system scoped dependency in the plugin artifacts." );
+ }
+
+ // -----------------------------------------------------------------------------------------------
+ // Testing help
+ // -----------------------------------------------------------------------------------------------
+
+ protected void assertPluginDescriptor( MojoDescriptor mojoDescriptor, String groupId, String artifactId, String version )
+ {
+ assertNotNull( mojoDescriptor );
+ PluginDescriptor pd = mojoDescriptor.getPluginDescriptor();
+ assertNotNull( pd );
+ assertEquals( groupId, pd.getGroupId() );
+ assertEquals( artifactId, pd.getArtifactId() );
+ assertEquals( version, pd.getVersion() );
+ }
+
+ public void testPluginRealmCache()
+ throws Exception
+ {
+ RepositoryRequest repositoryRequest = new DefaultRepositoryRequest();
+ repositoryRequest.setLocalRepository( getLocalRepository() );
+ repositoryRequest.setRemoteRepositories( getPluginArtifactRepositories() );
+
+ // prime realm cache
+ MavenSession session = createMavenSession( getProject( "project-contributing-system-scope-plugin-dep" ) );
+ MavenProject project = session.getCurrentProject();
+ Plugin plugin = project.getPlugin( "org.apache.maven.its.plugins:maven-it-plugin" );
+
+ PluginDescriptor pluginDescriptor =
+ pluginManager.loadPlugin( plugin, session.getCurrentProject().getRemotePluginRepositories(),
+ session.getRepositorySession() );
+ pluginManager.getPluginRealm( session, pluginDescriptor );
+
+ assertEquals( 1, pluginDescriptor.getDependencies().size() );
+
+ for ( ComponentDescriptor<?> descriptor : pluginDescriptor.getComponents() )
+ {
+ assertNotNull( descriptor.getRealm() );
+ assertNotNull( descriptor.getImplementationClass() );
+ }
+
+ // reload plugin realm from cache
+ session = createMavenSession( getProject( "project-contributing-system-scope-plugin-dep" ) );
+ project = session.getCurrentProject();
+ plugin = project.getPlugin( "org.apache.maven.its.plugins:maven-it-plugin" );
+
+ pluginDescriptor =
+ pluginManager.loadPlugin( plugin, session.getCurrentProject().getRemotePluginRepositories(),
+ session.getRepositorySession() );
+ pluginManager.getPluginRealm( session, pluginDescriptor );
+
+ assertEquals( 1, pluginDescriptor.getDependencies().size() );
+
+ for ( ComponentDescriptor<?> descriptor : pluginDescriptor.getComponents() )
+ {
+ assertNotNull( descriptor.getRealm() );
+ assertNotNull( descriptor.getImplementationClass() );
+ }
+ }
+
+ public void testBuildExtensionsPluginLoading()
+ throws Exception
+ {
+ RepositoryRequest repositoryRequest = new DefaultRepositoryRequest();
+ repositoryRequest.setLocalRepository( getLocalRepository() );
+ repositoryRequest.setRemoteRepositories( getPluginArtifactRepositories() );
+
+ // prime realm cache
+ MavenSession session = createMavenSession( getProject( "project-with-build-extensions-plugin" ) );
+ MavenProject project = session.getCurrentProject();
+ Plugin plugin = project.getPlugin( "org.apache.maven.its.plugins:maven-it-plugin" );
+
+ PluginDescriptor pluginDescriptor =
+ pluginManager.loadPlugin( plugin, session.getCurrentProject().getRemotePluginRepositories(),
+ session.getRepositorySession() );
+ ClassRealm pluginRealm = pluginManager.getPluginRealm( session, pluginDescriptor );
+
+ assertEquals(pluginRealm, pluginDescriptor.getComponents().get(0).getRealm());
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/plugin/PluginParameterExceptionTest.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/plugin/PluginParameterExceptionTest.java
new file mode 100644
index 00000000..ead7ae2e
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/plugin/PluginParameterExceptionTest.java
@@ -0,0 +1,164 @@
+package org.apache.maven.plugin;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Collections;
+
+import org.apache.maven.plugin.descriptor.MojoDescriptor;
+import org.apache.maven.plugin.descriptor.Parameter;
+import org.apache.maven.plugin.descriptor.PluginDescriptor;
+
+import junit.framework.TestCase;
+
+/**
+ * MNG-3131
+ *
+ * @author Robert Scholte
+ *
+ */
+public class PluginParameterExceptionTest
+ extends TestCase
+{
+
+ public void testMissingRequiredStringArrayTypeParameter()
+ {
+ MojoDescriptor mojoDescriptor = new MojoDescriptor();
+ mojoDescriptor.setGoal( "goal" );
+ PluginDescriptor pluginDescriptor = new PluginDescriptor();
+ pluginDescriptor.setGoalPrefix( "goalPrefix" );
+ pluginDescriptor.setArtifactId( "artifactId" );
+ mojoDescriptor.setPluginDescriptor( pluginDescriptor );
+
+ Parameter parameter = new Parameter();
+ parameter.setType( "java.lang.String[]" );
+ parameter.setName( "toAddresses" );
+
+ parameter.setRequired( true );
+
+ PluginParameterException exception =
+ new PluginParameterException( mojoDescriptor, Collections.singletonList( parameter ) );
+
+ assertEquals( "One or more required plugin parameters are invalid/missing for 'goalPrefix:goal'\n" +
+ "\n" +
+ "[0] Inside the definition for plugin 'artifactId', specify the following:\n" +
+ "\n" +
+ "<configuration>\n" +
+ " ...\n" +
+ " <toAddresses>\n" +
+ " <item>VALUE</item>\n" +
+ " </toAddresses>\n" +
+ "</configuration>.\n", exception.buildDiagnosticMessage() );
+ }
+
+ public void testMissingRequiredCollectionTypeParameter()
+ {
+ MojoDescriptor mojoDescriptor = new MojoDescriptor();
+ mojoDescriptor.setGoal( "goal" );
+ PluginDescriptor pluginDescriptor = new PluginDescriptor();
+ pluginDescriptor.setGoalPrefix( "goalPrefix" );
+ pluginDescriptor.setArtifactId( "artifactId" );
+ mojoDescriptor.setPluginDescriptor( pluginDescriptor );
+
+ Parameter parameter = new Parameter();
+ parameter.setType( "java.util.List" );
+ parameter.setName( "toAddresses" );
+
+ parameter.setRequired( true );
+
+ PluginParameterException exception =
+ new PluginParameterException( mojoDescriptor, Collections.singletonList( parameter ) );
+
+ assertEquals( "One or more required plugin parameters are invalid/missing for 'goalPrefix:goal'\n" +
+ "\n" +
+ "[0] Inside the definition for plugin 'artifactId', specify the following:\n" +
+ "\n" +
+ "<configuration>\n" +
+ " ...\n" +
+ " <toAddresses>\n" +
+ " <item>VALUE</item>\n" +
+ " </toAddresses>\n" +
+ "</configuration>.\n", exception.buildDiagnosticMessage() );
+ }
+
+ public void testMissingRequiredMapTypeParameter()
+ {
+ MojoDescriptor mojoDescriptor = new MojoDescriptor();
+ mojoDescriptor.setGoal( "goal" );
+ PluginDescriptor pluginDescriptor = new PluginDescriptor();
+ pluginDescriptor.setGoalPrefix( "goalPrefix" );
+ pluginDescriptor.setArtifactId( "artifactId" );
+ mojoDescriptor.setPluginDescriptor( pluginDescriptor );
+
+ Parameter parameter = new Parameter();
+ parameter.setType( "java.util.Map" );
+ parameter.setName( "toAddresses" );
+
+ parameter.setRequired( true );
+
+ PluginParameterException exception =
+ new PluginParameterException( mojoDescriptor, Collections.singletonList( parameter ) );
+
+ assertEquals( "One or more required plugin parameters are invalid/missing for 'goalPrefix:goal'\n" +
+ "\n" +
+ "[0] Inside the definition for plugin 'artifactId', specify the following:\n" +
+ "\n" +
+ "<configuration>\n" +
+ " ...\n" +
+ " <toAddresses>\n" +
+ " <KEY>VALUE</KEY>\n" +
+ " </toAddresses>\n" +
+ "</configuration>.\n", exception.buildDiagnosticMessage() );
+ }
+
+ public void testMissingRequiredPropertiesTypeParameter()
+ {
+ MojoDescriptor mojoDescriptor = new MojoDescriptor();
+ mojoDescriptor.setGoal( "goal" );
+ PluginDescriptor pluginDescriptor = new PluginDescriptor();
+ pluginDescriptor.setGoalPrefix( "goalPrefix" );
+ pluginDescriptor.setArtifactId( "artifactId" );
+ mojoDescriptor.setPluginDescriptor( pluginDescriptor );
+
+ Parameter parameter = new Parameter();
+ parameter.setType( "java.util.Properties" );
+ parameter.setName( "toAddresses" );
+
+ parameter.setRequired( true );
+
+ PluginParameterException exception =
+ new PluginParameterException( mojoDescriptor, Collections.singletonList( parameter ) );
+
+ assertEquals( "One or more required plugin parameters are invalid/missing for 'goalPrefix:goal'\n" +
+ "\n" +
+ "[0] Inside the definition for plugin 'artifactId', specify the following:\n" +
+ "\n" +
+ "<configuration>\n" +
+ " ...\n" +
+ " <toAddresses>\n" +
+ " <property>\n" +
+ " <name>KEY</name>\n" +
+ " <value>VALUE</value>\n" +
+ " </property>\n" +
+ " </toAddresses>\n" +
+ "</configuration>.\n", exception.buildDiagnosticMessage() );
+ }
+
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/plugin/PluginParameterExpressionEvaluatorTest.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/plugin/PluginParameterExpressionEvaluatorTest.java
new file mode 100644
index 00000000..5f6744c9
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/plugin/PluginParameterExpressionEvaluatorTest.java
@@ -0,0 +1,447 @@
+package org.apache.maven.plugin;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.maven.AbstractCoreMavenComponentTestCase;
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.ArtifactUtils;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.execution.DefaultMavenExecutionRequest;
+import org.apache.maven.execution.DefaultMavenExecutionResult;
+import org.apache.maven.execution.MavenExecutionRequest;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.model.Build;
+import org.apache.maven.model.Dependency;
+import org.apache.maven.model.Model;
+import org.apache.maven.plugin.descriptor.MojoDescriptor;
+import org.apache.maven.plugin.descriptor.PluginDescriptor;
+import org.apache.maven.project.DuplicateProjectException;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.repository.RepositorySystem;
+import org.codehaus.plexus.MutablePlexusContainer;
+import org.codehaus.plexus.PlexusContainer;
+import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluator;
+import org.codehaus.plexus.util.dag.CycleDetectedException;
+
+/**
+ * @author Jason van Zyl
+ */
+public class PluginParameterExpressionEvaluatorTest
+ extends AbstractCoreMavenComponentTestCase
+{
+ private static final String FS = System.getProperty( "file.separator" );
+
+ private RepositorySystem factory;
+
+ public void setUp()
+ throws Exception
+ {
+ super.setUp();
+ factory = lookup( RepositorySystem.class );
+ }
+
+ @Override
+ protected void tearDown()
+ throws Exception
+ {
+ factory = null;
+ super.tearDown();
+ }
+
+ public void testPluginDescriptorExpressionReference()
+ throws Exception
+ {
+ MojoExecution exec = newMojoExecution();
+
+ MavenSession session = newMavenSession();
+
+ Object result = new PluginParameterExpressionEvaluator( session, exec ).evaluate( "${plugin}" );
+
+ System.out.println( "Result: " + result );
+
+ assertSame( "${plugin} expression does not return plugin descriptor.",
+ exec.getMojoDescriptor().getPluginDescriptor(),
+ result );
+ }
+
+ public void testPluginArtifactsExpressionReference()
+ throws Exception
+ {
+ MojoExecution exec = newMojoExecution();
+
+ Artifact depArtifact = createArtifact( "group", "artifact", "1" );
+
+ List<Artifact> deps = new ArrayList<Artifact>();
+ deps.add( depArtifact );
+
+ exec.getMojoDescriptor().getPluginDescriptor().setArtifacts( deps );
+
+ MavenSession session = newMavenSession();
+
+ @SuppressWarnings( "unchecked" )
+ List<Artifact> depResults =
+ (List<Artifact>) new PluginParameterExpressionEvaluator( session, exec ).evaluate( "${plugin.artifacts}" );
+
+ System.out.println( "Result: " + depResults );
+
+ assertNotNull( depResults );
+ assertEquals( 1, depResults.size() );
+ assertSame( "dependency artifact is wrong.", depArtifact, depResults.get( 0 ) );
+ }
+
+ public void testPluginArtifactMapExpressionReference()
+ throws Exception
+ {
+ MojoExecution exec = newMojoExecution();
+
+ Artifact depArtifact = createArtifact( "group", "artifact", "1" );
+
+ List<Artifact> deps = new ArrayList<Artifact>();
+ deps.add( depArtifact );
+
+ exec.getMojoDescriptor().getPluginDescriptor().setArtifacts( deps );
+
+ MavenSession session = newMavenSession();
+
+ @SuppressWarnings( "unchecked" )
+ Map<String, Artifact> depResults =
+ (Map<String, Artifact>) new PluginParameterExpressionEvaluator( session, exec ).evaluate( "${plugin.artifactMap}" );
+
+ System.out.println( "Result: " + depResults );
+
+ assertNotNull( depResults );
+ assertEquals( 1, depResults.size() );
+ assertSame( "dependency artifact is wrong.",
+ depArtifact,
+ depResults.get( ArtifactUtils.versionlessKey( depArtifact ) ) );
+ }
+
+ public void testPluginArtifactIdExpressionReference()
+ throws Exception
+ {
+ MojoExecution exec = newMojoExecution();
+
+ MavenSession session = newMavenSession();
+
+ Object result = new PluginParameterExpressionEvaluator( session, exec ).evaluate( "${plugin.artifactId}" );
+
+ System.out.println( "Result: " + result );
+
+ assertSame( "${plugin.artifactId} expression does not return plugin descriptor's artifactId.",
+ exec.getMojoDescriptor().getPluginDescriptor().getArtifactId(),
+ result );
+ }
+
+ public void testValueExtractionWithAPomValueContainingAPath()
+ throws Exception
+ {
+ String expected = getTestFile( "target/test-classes/target/classes" ).getCanonicalPath();
+
+ Build build = new Build();
+ build.setDirectory( expected.substring( 0, expected.length() - "/classes".length() ) );
+
+ Model model = new Model();
+ model.setBuild( build );
+
+ MavenProject project = new MavenProject( model );
+ project.setFile( new File( "pom.xml" ).getCanonicalFile() );
+
+ ExpressionEvaluator expressionEvaluator = createExpressionEvaluator( project, null, new Properties() );
+
+ Object value = expressionEvaluator.evaluate( "${project.build.directory}/classes" );
+ String actual = new File( value.toString() ).getCanonicalPath();
+
+ assertEquals( expected, actual );
+ }
+
+ public void testEscapedVariablePassthrough()
+ throws Exception
+ {
+ String var = "${var}";
+
+ Model model = new Model();
+ model.setVersion( "1" );
+
+ MavenProject project = new MavenProject( model );
+
+ ExpressionEvaluator ee = createExpressionEvaluator( project, null, new Properties() );
+
+ Object value = ee.evaluate( "$" + var );
+
+ assertEquals( var, value );
+ }
+
+ public void testEscapedVariablePassthroughInLargerExpression()
+ throws Exception
+ {
+ String var = "${var}";
+ String key = var + " with version: ${project.version}";
+
+ Model model = new Model();
+ model.setVersion( "1" );
+
+ MavenProject project = new MavenProject( model );
+
+ ExpressionEvaluator ee = createExpressionEvaluator( project, null, new Properties() );
+
+ Object value = ee.evaluate( "$" + key );
+
+ assertEquals( "${var} with version: 1", value );
+ }
+
+ public void testMultipleSubExpressionsInLargerExpression()
+ throws Exception
+ {
+ String key = "${project.artifactId} with version: ${project.version}";
+
+ Model model = new Model();
+ model.setArtifactId( "test" );
+ model.setVersion( "1" );
+
+ MavenProject project = new MavenProject( model );
+
+ ExpressionEvaluator ee = createExpressionEvaluator( project, null, new Properties() );
+
+ Object value = ee.evaluate( key );
+
+ assertEquals( "test with version: 1", value );
+ }
+
+ public void testMissingPOMPropertyRefInLargerExpression()
+ throws Exception
+ {
+ String expr = "/path/to/someproject-${baseVersion}";
+
+ MavenProject project = new MavenProject( new Model() );
+
+ ExpressionEvaluator ee = createExpressionEvaluator( project, null, new Properties() );
+
+ Object value = ee.evaluate( expr );
+
+ assertEquals( expr, value );
+ }
+
+ public void testPOMPropertyExtractionWithMissingProject_WithDotNotation()
+ throws Exception
+ {
+ String key = "m2.name";
+ String checkValue = "value";
+
+ Properties properties = new Properties();
+ properties.setProperty( key, checkValue );
+
+ Model model = new Model();
+ model.setProperties( properties );
+
+ MavenProject project = new MavenProject( model );
+
+ ExpressionEvaluator ee = createExpressionEvaluator( project, null, new Properties() );
+
+ Object value = ee.evaluate( "${" + key + "}" );
+
+ assertEquals( checkValue, value );
+ }
+
+ public void testBasedirExtractionWithMissingProject()
+ throws Exception
+ {
+ ExpressionEvaluator ee = createExpressionEvaluator( null, null, new Properties() );
+
+ Object value = ee.evaluate( "${basedir}" );
+
+ assertEquals( System.getProperty( "user.dir" ), value );
+ }
+
+ public void testValueExtractionFromSystemPropertiesWithMissingProject()
+ throws Exception
+ {
+ String sysprop = "PPEET_sysprop1";
+
+ Properties executionProperties = new Properties();
+
+ if ( executionProperties.getProperty( sysprop ) == null )
+ {
+ executionProperties.setProperty( sysprop, "value" );
+ }
+
+ ExpressionEvaluator ee = createExpressionEvaluator( null, null, executionProperties );
+
+ Object value = ee.evaluate( "${" + sysprop + "}" );
+
+ assertEquals( "value", value );
+ }
+
+ public void testValueExtractionFromSystemPropertiesWithMissingProject_WithDotNotation()
+ throws Exception
+ {
+ String sysprop = "PPEET.sysprop2";
+
+ Properties executionProperties = new Properties();
+
+ if ( executionProperties.getProperty( sysprop ) == null )
+ {
+ executionProperties.setProperty( sysprop, "value" );
+ }
+
+ ExpressionEvaluator ee = createExpressionEvaluator( null, null, executionProperties );
+
+ Object value = ee.evaluate( "${" + sysprop + "}" );
+
+ assertEquals( "value", value );
+ }
+
+ @SuppressWarnings( "deprecation" )
+ private static MavenSession createSession( PlexusContainer container, ArtifactRepository repo, Properties properties )
+ throws CycleDetectedException, DuplicateProjectException
+ {
+ MavenExecutionRequest request = new DefaultMavenExecutionRequest()
+ .setSystemProperties( properties )
+ .setGoals( Collections.<String>emptyList() )
+ .setBaseDirectory( new File( "" ) )
+ .setLocalRepository( repo );
+
+ return new MavenSession( container, request, new DefaultMavenExecutionResult(), Collections.<MavenProject>emptyList() );
+ }
+
+ public void testLocalRepositoryExtraction()
+ throws Exception
+ {
+ ExpressionEvaluator expressionEvaluator =
+ createExpressionEvaluator( createDefaultProject(), null, new Properties() );
+ Object value = expressionEvaluator.evaluate( "${localRepository}" );
+
+ assertEquals( "local", ( (ArtifactRepository) value ).getId() );
+ }
+
+ public void testTwoExpressions()
+ throws Exception
+ {
+ Build build = new Build();
+ build.setDirectory( "expected-directory" );
+ build.setFinalName( "expected-finalName" );
+
+ Model model = new Model();
+ model.setBuild( build );
+
+ ExpressionEvaluator expressionEvaluator =
+ createExpressionEvaluator( new MavenProject( model ), null, new Properties() );
+
+ Object value = expressionEvaluator.evaluate( "${project.build.directory}" + FS + "${project.build.finalName}" );
+
+ assertEquals( "expected-directory" + File.separatorChar + "expected-finalName", value );
+ }
+
+ public void testShouldExtractPluginArtifacts()
+ throws Exception
+ {
+ PluginDescriptor pd = new PluginDescriptor();
+
+ Artifact artifact = createArtifact( "testGroup", "testArtifact", "1.0" );
+
+ pd.setArtifacts( Collections.singletonList( artifact ) );
+
+ ExpressionEvaluator ee = createExpressionEvaluator( createDefaultProject(), pd, new Properties() );
+
+ Object value = ee.evaluate( "${plugin.artifacts}" );
+
+ assertTrue( value instanceof List );
+
+ @SuppressWarnings( "unchecked" )
+ List<Artifact> artifacts = (List<Artifact>) value;
+
+ assertEquals( 1, artifacts.size() );
+
+ Artifact result = artifacts.get( 0 );
+
+ assertEquals( "testGroup", result.getGroupId() );
+ }
+
+ private MavenProject createDefaultProject()
+ {
+ return new MavenProject( new Model() );
+ }
+
+ private ExpressionEvaluator createExpressionEvaluator( MavenProject project, PluginDescriptor pluginDescriptor, Properties executionProperties )
+ throws Exception
+ {
+ ArtifactRepository repo = factory.createDefaultLocalRepository();
+
+ MutablePlexusContainer container = (MutablePlexusContainer) getContainer();
+ MavenSession session = createSession( container, repo, executionProperties );
+ session.setCurrentProject( project );
+
+ MojoDescriptor mojo = new MojoDescriptor();
+ mojo.setPluginDescriptor( pluginDescriptor );
+ mojo.setGoal( "goal" );
+
+ MojoExecution mojoExecution = new MojoExecution( mojo );
+
+ return new PluginParameterExpressionEvaluator( session, mojoExecution );
+ }
+
+ protected Artifact createArtifact( String groupId, String artifactId, String version )
+ throws Exception
+ {
+ Dependency dependency = new Dependency();
+ dependency.setGroupId( groupId );
+ dependency.setArtifactId( artifactId );
+ dependency.setVersion( version );
+ dependency.setType( "jar" );
+ dependency.setScope( "compile" );
+
+ return factory.createDependencyArtifact( dependency );
+ }
+
+ private MojoExecution newMojoExecution()
+ {
+ PluginDescriptor pd = new PluginDescriptor();
+ pd.setArtifactId( "my-plugin" );
+ pd.setGroupId( "org.myco.plugins" );
+ pd.setVersion( "1" );
+
+ MojoDescriptor md = new MojoDescriptor();
+ md.setPluginDescriptor( pd );
+
+ pd.addComponentDescriptor( md );
+
+ return new MojoExecution( md );
+ }
+
+ private MavenSession newMavenSession()
+ throws Exception
+ {
+ return createMavenSession( null );
+ }
+
+ @Override
+ protected String getProjectsDirectory()
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/plugin/internal/DefaultLegacySupportTest.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/plugin/internal/DefaultLegacySupportTest.java
new file mode 100644
index 00000000..d350770c
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/plugin/internal/DefaultLegacySupportTest.java
@@ -0,0 +1,74 @@
+package org.apache.maven.plugin.internal;
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import junit.framework.TestCase;
+import org.apache.maven.execution.DefaultMavenExecutionRequest;
+import org.apache.maven.execution.MavenExecutionRequest;
+import org.apache.maven.execution.MavenSession;
+
+import java.util.concurrent.CountDownLatch;
+
+/**
+ * @author Kristian Rosenvold
+ */
+public class DefaultLegacySupportTest extends TestCase {
+ final CountDownLatch latch = new CountDownLatch(1);
+ final DefaultLegacySupport defaultLegacySupport = new DefaultLegacySupport();
+
+ public void testSetSession() throws Exception {
+
+ MavenExecutionRequest mavenExecutionRequest = new DefaultMavenExecutionRequest();
+ MavenSession m1 = new MavenSession(null, null, mavenExecutionRequest, null);
+ defaultLegacySupport.setSession(m1);
+
+ MyRunnable myRunnable = new MyRunnable();
+ Thread thread = new Thread(myRunnable);
+ thread.start();
+
+ MavenSession m2 = new MavenSession(null, null, mavenExecutionRequest, null);
+ defaultLegacySupport.setSession(m2);
+ latch.countDown();
+ thread.join();
+ assertNull( myRunnable.getSession());
+ }
+
+
+ class MyRunnable implements Runnable {
+
+ private volatile MavenSession session;
+
+ public void run() {
+ try
+ {
+ latch.await();
+ }
+ catch (InterruptedException ingore)
+ {
+ // Test may fail if we get interrupted
+ }
+ session = defaultLegacySupport.getSession();
+ }
+
+ public MavenSession getSession() {
+ return session;
+ }
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/project/AbstractMavenProjectTestCase.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/project/AbstractMavenProjectTestCase.java
new file mode 100644
index 00000000..73bdbcae
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/project/AbstractMavenProjectTestCase.java
@@ -0,0 +1,189 @@
+package org.apache.maven.project;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.Arrays;
+
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout;
+import org.apache.maven.model.building.ModelBuildingException;
+import org.apache.maven.model.building.ModelProblem;
+import org.apache.maven.repository.RepositorySystem;
+import org.apache.maven.repository.internal.MavenRepositorySystemUtils;
+import org.codehaus.plexus.ContainerConfiguration;
+import org.codehaus.plexus.PlexusConstants;
+import org.codehaus.plexus.PlexusTestCase;
+import org.eclipse.aether.DefaultRepositorySystemSession;
+
+/**
+ * @author Jason van Zyl
+ */
+public abstract class AbstractMavenProjectTestCase
+ extends PlexusTestCase
+{
+ protected ProjectBuilder projectBuilder;
+
+ protected RepositorySystem repositorySystem;
+
+ @Override
+ protected void customizeContainerConfiguration( ContainerConfiguration containerConfiguration )
+ {
+ super.customizeContainerConfiguration( containerConfiguration );
+ containerConfiguration.setAutoWiring( true );
+ containerConfiguration.setClassPathScanning( PlexusConstants.SCANNING_INDEX );
+ }
+
+ protected void setUp()
+ throws Exception
+ {
+ super.setUp();
+
+ if ( getContainer().hasComponent( ProjectBuilder.class, "test" ) )
+ {
+ projectBuilder = lookup( ProjectBuilder.class, "test" );
+ }
+ else
+ {
+ // default over to the main project builder...
+ projectBuilder = lookup( ProjectBuilder.class );
+ }
+
+ repositorySystem = lookup( RepositorySystem.class );
+ }
+
+ @Override
+ protected void tearDown()
+ throws Exception
+ {
+ projectBuilder = null;
+
+ super.tearDown();
+ }
+
+ protected ProjectBuilder getProjectBuilder()
+ {
+ return projectBuilder;
+ }
+
+ @Override
+ protected String getCustomConfigurationName()
+ {
+ String name = AbstractMavenProjectTestCase.class.getName().replace( '.', '/' ) + ".xml";
+ System.out.println( name );
+ return name;
+ }
+
+ // ----------------------------------------------------------------------
+ // Local repository
+ // ----------------------------------------------------------------------
+
+ protected File getLocalRepositoryPath()
+ throws FileNotFoundException, URISyntaxException
+ {
+ File markerFile = getFileForClasspathResource( "local-repo/marker.txt" );
+
+ return markerFile.getAbsoluteFile().getParentFile();
+ }
+
+ protected static File getFileForClasspathResource( String resource )
+ throws FileNotFoundException
+ {
+ ClassLoader cloader = Thread.currentThread().getContextClassLoader();
+
+ URL resourceUrl = cloader.getResource( resource );
+
+ if ( resourceUrl == null )
+ {
+ throw new FileNotFoundException( "Unable to find: " + resource );
+ }
+
+ return new File( URI.create( resourceUrl.toString().replaceAll( " ", "%20" ) ) );
+ }
+
+ protected ArtifactRepository getLocalRepository()
+ throws Exception
+ {
+ ArtifactRepositoryLayout repoLayout = lookup( ArtifactRepositoryLayout.class, "legacy" );
+
+ ArtifactRepository r = repositorySystem.createArtifactRepository( "local", "file://" + getLocalRepositoryPath().getAbsolutePath(), repoLayout, null, null );
+
+ return r;
+ }
+
+ // ----------------------------------------------------------------------
+ // Project building
+ // ----------------------------------------------------------------------
+
+ protected MavenProject getProjectWithDependencies( File pom )
+ throws Exception
+ {
+ ProjectBuildingRequest configuration = newBuildingRequest();
+ configuration.setRemoteRepositories( Arrays.asList( new ArtifactRepository[] {} ) );
+ configuration.setProcessPlugins( false );
+ configuration.setResolveDependencies( true );
+
+ try
+ {
+ return projectBuilder.build( pom, configuration ).getProject();
+ }
+ catch ( Exception e )
+ {
+ Throwable cause = e.getCause();
+ if ( cause instanceof ModelBuildingException )
+ {
+ String message = "In: " + pom + "\n\n";
+ for ( ModelProblem problem : ( (ModelBuildingException) cause ).getProblems() )
+ {
+ message += problem + "\n";
+ }
+ System.out.println( message );
+ }
+
+ throw e;
+ }
+ }
+
+ protected MavenProject getProject( File pom )
+ throws Exception
+ {
+ ProjectBuildingRequest configuration = newBuildingRequest();
+
+ return projectBuilder.build( pom, configuration ).getProject();
+ }
+
+ protected ProjectBuildingRequest newBuildingRequest()
+ throws Exception
+ {
+ ProjectBuildingRequest configuration = new DefaultProjectBuildingRequest();
+ configuration.setLocalRepository( getLocalRepository() );
+ initRepoSession( configuration );
+ return configuration;
+ }
+
+ protected void initRepoSession( ProjectBuildingRequest request )
+ {
+ File localRepo = new File( request.getLocalRepository().getBasedir() );
+ DefaultRepositorySystemSession repoSession = MavenRepositorySystemUtils.newSession();
+ repoSession.setLocalRepositoryManager( new LegacyLocalRepositoryManager( localRepo ) );
+ request.setRepositorySession( repoSession );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/project/DefaultMavenProjectBuilderTest.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/project/DefaultMavenProjectBuilderTest.java
new file mode 100644
index 00000000..13c32abb
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/project/DefaultMavenProjectBuilderTest.java
@@ -0,0 +1,193 @@
+package org.apache.maven.project;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout;
+import org.codehaus.plexus.util.FileUtils;
+
+public class DefaultMavenProjectBuilderTest
+ extends AbstractMavenProjectTestCase
+{
+
+ private List<File> filesToDelete = new ArrayList<File>();
+
+ private File localRepoDir;
+
+ @Override
+ public void setUp()
+ throws Exception
+ {
+ super.setUp();
+
+ projectBuilder = lookup( ProjectBuilder.class );
+
+ localRepoDir = new File( System.getProperty( "java.io.tmpdir" ), "local-repo." + System.currentTimeMillis() );
+ localRepoDir.mkdirs();
+
+ filesToDelete.add( localRepoDir );
+ }
+
+ @Override
+ public void tearDown()
+ throws Exception
+ {
+ super.tearDown();
+
+ if ( !filesToDelete.isEmpty() )
+ {
+ for ( File file : filesToDelete )
+ {
+ if ( file.exists() )
+ {
+ if ( file.isDirectory() )
+ {
+ FileUtils.deleteDirectory( file );
+ }
+ else
+ {
+ file.delete();
+ }
+ }
+ }
+ }
+ }
+
+ protected MavenProject getProject( Artifact pom, boolean allowStub )
+ throws Exception
+ {
+ ProjectBuildingRequest configuration = new DefaultProjectBuildingRequest();
+ configuration.setLocalRepository( getLocalRepository() );
+ initRepoSession( configuration );
+
+ return projectBuilder.build( pom, allowStub, configuration ).getProject();
+ }
+
+ /**
+ * Check that we can build ok from the middle pom of a (parent,child,grandchild) heirarchy
+ * @throws Exception
+ */
+ public void testBuildFromMiddlePom() throws Exception
+ {
+ File f1 = getTestFile( "src/test/resources/projects/grandchild-check/child/pom.xml");
+ File f2 = getTestFile( "src/test/resources/projects/grandchild-check/child/grandchild/pom.xml");
+
+ getProject( f1 );
+
+ // it's the building of the grandchild project, having already cached the child project
+ // (but not the parent project), which causes the problem.
+ getProject( f2 );
+ }
+
+ public void testDuplicatePluginDefinitionsMerged()
+ throws Exception
+ {
+ File f1 = getTestFile( "src/test/resources/projects/duplicate-plugins-merged-pom.xml" );
+
+ MavenProject project = getProject( f1 );
+ assertEquals( 2, project.getBuildPlugins().get( 0 ).getDependencies().size() );
+ assertEquals( 2, project.getBuildPlugins().get( 0 ).getExecutions().size() );
+ assertEquals( "first", project.getBuildPlugins().get( 0 ).getExecutions().get( 0 ).getId() );
+ }
+
+ public void testBuildStubModelForMissingRemotePom()
+ throws Exception
+ {
+ Artifact pom = repositorySystem.createProjectArtifact( "org.apache.maven.its", "missing", "0.1" );
+ MavenProject project = getProject( pom, true );
+
+ assertNotNull( project.getArtifactId() );
+
+ assertNotNull( project.getRemoteArtifactRepositories() );
+ assertFalse( project.getRemoteArtifactRepositories().isEmpty() );
+
+ assertNotNull( project.getPluginArtifactRepositories() );
+ assertFalse( project.getPluginArtifactRepositories().isEmpty() );
+
+ assertNull( project.getParent() );
+ assertNull( project.getParentArtifact() );
+
+ assertFalse( project.isExecutionRoot() );
+ }
+
+ @Override
+ protected ArtifactRepository getLocalRepository()
+ throws Exception
+ {
+ ArtifactRepositoryLayout repoLayout = lookup( ArtifactRepositoryLayout.class, "default" );
+ ArtifactRepository r =
+ repositorySystem.createArtifactRepository( "local", "file://" + localRepoDir.getAbsolutePath(), repoLayout,
+ null, null );
+ return r;
+ }
+
+ public void xtestLoop()
+ throws Exception
+ {
+ while ( true )
+ {
+ File f1 = getTestFile( "src/test/resources/projects/duplicate-plugins-merged-pom.xml" );
+ getProject( f1 );
+ }
+ }
+
+ public void testPartialResultUponBadDependencyDeclaration()
+ throws Exception
+ {
+ File pomFile = getTestFile( "src/test/resources/projects/bad-dependency.xml" );
+
+ try
+ {
+ ProjectBuildingRequest request = newBuildingRequest();
+ request.setProcessPlugins( false );
+ request.setResolveDependencies( true );
+ projectBuilder.build( pomFile, request );
+ fail( "Project building did not fail despite invalid POM" );
+ }
+ catch ( ProjectBuildingException e )
+ {
+ List<ProjectBuildingResult> results = e.getResults();
+ assertNotNull( results );
+ assertEquals( 1, results.size() );
+ ProjectBuildingResult result = results.get( 0 );
+ assertNotNull( result );
+ assertNotNull( result.getProject() );
+ assertEquals( 1, result.getProblems().size() );
+ assertEquals( 1, result.getProject().getArtifacts().size() );
+ assertNotNull( result.getDependencyResolutionResult() );
+ }
+ }
+
+ public void testImportScopePomResolvesFromPropertyBasedRepository()
+ throws Exception
+ {
+ File pomFile = getTestFile( "src/test/resources/projects/import-scope-pom-resolves-from-property-based-repository.xml" );
+ ProjectBuildingRequest request = newBuildingRequest();
+ request.setProcessPlugins( false );
+ request.setResolveDependencies( true );
+ projectBuilder.build( pomFile, request );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/project/EmptyLifecycleExecutor.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/project/EmptyLifecycleExecutor.java
new file mode 100644
index 00000000..8ff912fb
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/project/EmptyLifecycleExecutor.java
@@ -0,0 +1,109 @@
+package org.apache.maven.project;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Collections;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.lifecycle.LifecycleExecutor;
+import org.apache.maven.lifecycle.MavenExecutionPlan;
+import org.apache.maven.model.Plugin;
+import org.apache.maven.model.PluginExecution;
+import org.apache.maven.plugin.MojoExecution;
+
+/**
+ * A stub implementation that assumes an empty lifecycle to bypass interaction with the plugin manager and to avoid
+ * plugin artifact resolution from repositories.
+ *
+ * @author Benjamin Bentmann
+ */
+public class EmptyLifecycleExecutor
+ implements LifecycleExecutor
+{
+
+ public MavenExecutionPlan calculateExecutionPlan( MavenSession session, String... tasks )
+ {
+ return new MavenExecutionPlan( null, null );
+ }
+
+ public MavenExecutionPlan calculateExecutionPlan( MavenSession session, boolean setup, String... tasks )
+ {
+ return new MavenExecutionPlan( null, null );
+ }
+
+ public void execute( MavenSession session )
+ {
+ }
+
+ public Set<Plugin> getPluginsBoundByDefaultToAllLifecycles( String packaging )
+ {
+ Set<Plugin> plugins;
+
+ // NOTE: The upper-case packaging name is intentional, that's a special hinting mode used for certain tests
+ if ( "JAR".equals( packaging ) )
+ {
+ plugins = new LinkedHashSet<Plugin>();
+
+ plugins.add( newPlugin( "maven-compiler-plugin", "compile", "testCompile" ) );
+ plugins.add( newPlugin( "maven-resources-plugin", "resources", "testResources" ) );
+ plugins.add( newPlugin( "maven-surefire-plugin", "test" ) );
+ plugins.add( newPlugin( "maven-jar-plugin", "jar" ) );
+ plugins.add( newPlugin( "maven-install-plugin", "install" ) );
+ plugins.add( newPlugin( "maven-deploy-plugin", "deploy" ) );
+ }
+ else
+ {
+ plugins = Collections.emptySet();
+ }
+
+ return plugins;
+ }
+
+ private Plugin newPlugin( String artifactId, String... goals )
+ {
+ Plugin plugin = new Plugin();
+
+ plugin.setGroupId( "org.apache.maven.plugins" );
+ plugin.setArtifactId( artifactId );
+
+ for ( String goal : goals )
+ {
+ PluginExecution pluginExecution = new PluginExecution();
+ pluginExecution.setId( "default-" + goal );
+ pluginExecution.addGoal( goal );
+ plugin.addExecution( pluginExecution );
+ }
+
+ return plugin;
+ }
+
+ public void calculateForkedExecutions( MojoExecution mojoExecution, MavenSession session )
+ {
+ }
+
+ public List<MavenProject> executeForkedExecutions( MojoExecution mojoExecution, MavenSession session )
+ {
+ return Collections.emptyList();
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/project/EmptyProjectBuildingHelper.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/project/EmptyProjectBuildingHelper.java
new file mode 100644
index 00000000..21e37f1f
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/project/EmptyProjectBuildingHelper.java
@@ -0,0 +1,62 @@
+package org.apache.maven.project;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.model.Model;
+import org.apache.maven.model.Repository;
+
+/**
+ * A stub implementation to bypass artifact resolution from repositories.
+ *
+ * @author Benjamin Bentmann
+ */
+public class EmptyProjectBuildingHelper
+ implements ProjectBuildingHelper
+{
+
+ public List<ArtifactRepository> createArtifactRepositories( List<Repository> pomRepositories,
+ List<ArtifactRepository> externalRepositories,
+ ProjectBuildingRequest request )
+ {
+ if ( externalRepositories != null )
+ {
+ return externalRepositories;
+ }
+ else
+ {
+ return new ArrayList<ArtifactRepository>();
+ }
+ }
+
+ public ProjectRealmCache.CacheRecord createProjectRealm( MavenProject proejct,
+ Model model, ProjectBuildingRequest request )
+ {
+ return new ProjectRealmCache.CacheRecord( null, null );
+ }
+
+ public void selectProjectRealm( MavenProject project )
+ {
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/project/ExtensionDescriptorBuilderTest.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/project/ExtensionDescriptorBuilderTest.java
new file mode 100644
index 00000000..68727013
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/project/ExtensionDescriptorBuilderTest.java
@@ -0,0 +1,101 @@
+package org.apache.maven.project;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.util.Arrays;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests {@link ExtensionDescriptorBuilder}.
+ *
+ * @author Benjamin Bentmann
+ */
+public class ExtensionDescriptorBuilderTest
+ extends TestCase
+{
+
+ private ExtensionDescriptorBuilder builder;
+
+ @Override
+ protected void setUp()
+ throws Exception
+ {
+ super.setUp();
+
+ builder = new ExtensionDescriptorBuilder();
+ }
+
+ @Override
+ protected void tearDown()
+ throws Exception
+ {
+ builder = null;
+
+ super.tearDown();
+ }
+
+ private InputStream toStream( String xml )
+ {
+ try
+ {
+ return new ByteArrayInputStream( xml.getBytes( "UTF-8" ) );
+ }
+ catch ( UnsupportedEncodingException e )
+ {
+ throw new IllegalStateException( e );
+ }
+ }
+
+ public void testEmptyDescriptor()
+ throws Exception
+ {
+ String xml = "<extension></extension>";
+
+ ExtensionDescriptor ed = builder.build( toStream( xml ) );
+
+ assertNotNull( ed );
+ assertNotNull( ed.getExportedPackages() );
+ assertTrue( ed.getExportedPackages().isEmpty() );
+ assertNotNull( ed.getExportedArtifacts() );
+ assertTrue( ed.getExportedArtifacts().isEmpty() );
+ }
+
+ public void testCompleteDescriptor()
+ throws Exception
+ {
+ String xml =
+ "<?xml version='1.0' encoding='UTF-8'?>" + "<extension>" + "<exportedPackages>"
+ + "<exportedPackage>a</exportedPackage>" + "<exportedPackage>b</exportedPackage>"
+ + "<exportedPackage>c</exportedPackage>" + "</exportedPackages>" + "<exportedArtifacts>"
+ + "<exportedArtifact>x</exportedArtifact>" + "<exportedArtifact>y</exportedArtifact>"
+ + "<exportedArtifact> z </exportedArtifact>" + "</exportedArtifacts>" + "</extension>";
+
+ ExtensionDescriptor ed = builder.build( toStream( xml ) );
+
+ assertNotNull( ed );
+ assertEquals( Arrays.asList( "a", "b", "c" ), ed.getExportedPackages() );
+ assertEquals( Arrays.asList( "x", "y", "z" ), ed.getExportedArtifacts() );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/project/LegacyLocalRepositoryManager.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/project/LegacyLocalRepositoryManager.java
new file mode 100644
index 00000000..52fdd804
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/project/LegacyLocalRepositoryManager.java
@@ -0,0 +1,192 @@
+package org.apache.maven.project;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+
+import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.artifact.Artifact;
+import org.eclipse.aether.metadata.Metadata;
+import org.eclipse.aether.repository.LocalArtifactRegistration;
+import org.eclipse.aether.repository.LocalArtifactRequest;
+import org.eclipse.aether.repository.LocalArtifactResult;
+import org.eclipse.aether.repository.LocalMetadataRegistration;
+import org.eclipse.aether.repository.LocalMetadataRequest;
+import org.eclipse.aether.repository.LocalMetadataResult;
+import org.eclipse.aether.repository.LocalRepository;
+import org.eclipse.aether.repository.LocalRepositoryManager;
+import org.eclipse.aether.repository.RemoteRepository;
+
+/**
+ * @author Benjamin Bentmann
+ */
+public class LegacyLocalRepositoryManager
+ implements LocalRepositoryManager
+{
+
+ private final LocalRepository repository;
+
+ public LegacyLocalRepositoryManager( File basedir )
+ {
+ this.repository = new LocalRepository( basedir.getAbsoluteFile(), "legacy" );
+ }
+
+ public LocalRepository getRepository()
+ {
+ return repository;
+ }
+
+ public String getPathForLocalArtifact( Artifact artifact )
+ {
+ StringBuilder path = new StringBuilder( 128 );
+
+ path.append( artifact.getGroupId() ).append( '/' );
+
+ path.append( artifact.getExtension() ).append( 's' ).append( '/' );
+
+ path.append( artifact.getArtifactId() ).append( '-' ).append( artifact.getVersion() );
+
+ if ( artifact.getClassifier().length() > 0 )
+ {
+ path.append( '-' ).append( artifact.getClassifier() );
+ }
+
+ path.append( '.' ).append( artifact.getExtension() );
+
+ return path.toString();
+ }
+
+ public String getPathForRemoteArtifact( Artifact artifact, RemoteRepository repository, String context )
+ {
+ return getPathForLocalArtifact( artifact );
+ }
+
+ public String getPathForLocalMetadata( Metadata metadata )
+ {
+ return getPath( metadata, "local" );
+ }
+
+ public String getPathForRemoteMetadata( Metadata metadata, RemoteRepository repository, String context )
+ {
+ return getPath( metadata, getRepositoryKey( repository, context ) );
+ }
+
+ String getRepositoryKey( RemoteRepository repository, String context )
+ {
+ return repository.getId();
+ }
+
+ private String getPath( Metadata metadata, String repositoryKey )
+ {
+ StringBuilder path = new StringBuilder( 128 );
+
+ if ( metadata.getGroupId().length() > 0 )
+ {
+ path.append( metadata.getGroupId().replace( '.', '/' ) ).append( '/' );
+
+ if ( metadata.getArtifactId().length() > 0 )
+ {
+ path.append( metadata.getArtifactId() ).append( '/' );
+
+ if ( metadata.getVersion().length() > 0 )
+ {
+ path.append( metadata.getVersion() ).append( '/' );
+ }
+ }
+ }
+
+ path.append( insertRepositoryKey( metadata.getType(), repositoryKey ) );
+
+ return path.toString();
+ }
+
+ private String insertRepositoryKey( String filename, String repositoryKey )
+ {
+ String result;
+ int idx = filename.indexOf( '.' );
+ if ( idx < 0 )
+ {
+ result = filename + '-' + repositoryKey;
+ }
+ else
+ {
+ result = filename.substring( 0, idx ) + '-' + repositoryKey + filename.substring( idx );
+ }
+ return result;
+ }
+
+ public LocalArtifactResult find( RepositorySystemSession session, LocalArtifactRequest request )
+ {
+ String path = getPathForLocalArtifact( request.getArtifact() );
+ File file = new File( getRepository().getBasedir(), path );
+
+ LocalArtifactResult result = new LocalArtifactResult( request );
+ if ( file.isFile() )
+ {
+ result.setFile( file );
+ result.setAvailable( true );
+ }
+
+ return result;
+ }
+
+ public void add( RepositorySystemSession session, LocalArtifactRegistration request )
+ {
+ // noop
+ }
+
+ public LocalMetadataResult find( RepositorySystemSession session, LocalMetadataRequest request )
+ {
+ LocalMetadataResult result = new LocalMetadataResult( request );
+
+ String path;
+
+ Metadata metadata = request.getMetadata();
+ String context = request.getContext();
+ RemoteRepository remote = request.getRepository();
+
+ if ( remote != null )
+ {
+ path = getPathForRemoteMetadata( metadata, remote, context );
+ }
+ else
+ {
+ path = getPathForLocalMetadata( metadata );
+ }
+
+ File file = new File( getRepository().getBasedir(), path );
+ if ( file.isFile() )
+ {
+ result.setFile( file );
+ }
+
+ return result;
+ }
+
+ public void add( RepositorySystemSession session, LocalMetadataRegistration request )
+ {
+ // noop
+ }
+
+ public String toString()
+ {
+ return String.valueOf( getRepository() );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/project/MavenProjectTest.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/project/MavenProjectTest.java
new file mode 100644
index 00000000..0c5cd07d
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/project/MavenProjectTest.java
@@ -0,0 +1,197 @@
+package org.apache.maven.project;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.maven.lifecycle.internal.stub.LoggerStub;
+import org.apache.maven.model.DependencyManagement;
+import org.apache.maven.model.Model;
+import org.apache.maven.model.Parent;
+import org.apache.maven.model.Profile;
+
+public class MavenProjectTest
+ extends AbstractMavenProjectTestCase
+{
+
+ public void testShouldInterpretChildPathAdjustmentBasedOnModulePaths()
+ throws IOException
+ {
+ Model parentModel = new Model();
+ parentModel.addModule( "../child" );
+
+ MavenProject parentProject = new MavenProject( parentModel );
+
+ Model childModel = new Model();
+ childModel.setArtifactId( "artifact" );
+
+ MavenProject childProject = new MavenProject( childModel );
+
+ File childFile =
+ new File( System.getProperty( "java.io.tmpdir" ), "maven-project-tests" + System.currentTimeMillis()
+ + "/child/pom.xml" );
+
+ childProject.setFile( childFile );
+
+ String adjustment = parentProject.getModulePathAdjustment( childProject );
+
+ assertNotNull( adjustment );
+
+ assertEquals( "..", adjustment );
+ }
+
+ public void testIdentityProtoInheritance()
+ {
+ Parent parent = new Parent();
+
+ parent.setGroupId( "test-group" );
+ parent.setVersion( "1000" );
+ parent.setArtifactId( "test-artifact" );
+
+ Model model = new Model();
+
+ model.setParent( parent );
+ model.setArtifactId( "real-artifact" );
+
+ MavenProject project = new MavenProject( model );
+
+ assertEquals( "groupId proto-inheritance failed.", "test-group", project.getGroupId() );
+ assertEquals( "artifactId is masked.", "real-artifact", project.getArtifactId() );
+ assertEquals( "version proto-inheritance failed.", "1000", project.getVersion() );
+
+ // draw the NPE.
+ project.getId();
+ }
+
+ public void testEmptyConstructor()
+ {
+ MavenProject project = new MavenProject();
+
+ assertEquals( MavenProject.EMPTY_PROJECT_GROUP_ID + ":" + MavenProject.EMPTY_PROJECT_ARTIFACT_ID + ":jar:"
+ + MavenProject.EMPTY_PROJECT_VERSION, project.getId() );
+ }
+
+ public void testClone()
+ throws Exception
+ {
+ File f = getFileForClasspathResource( "canonical-pom.xml" );
+ MavenProject projectToClone = getProject( f );
+
+ MavenProject clonedProject = projectToClone.clone();
+ assertEquals( "maven-core", clonedProject.getArtifactId() );
+ Map<?, ?> clonedMap = clonedProject.getManagedVersionMap();
+ assertNotNull( "ManagedVersionMap not copied", clonedMap );
+ assertTrue( "ManagedVersionMap is not empty", clonedMap.isEmpty() );
+ }
+
+ public void testCloneWithDependencyManagement()
+ throws Exception
+ {
+ File f = getFileForClasspathResource( "dependencyManagement-pom.xml" );
+ MavenProject projectToClone = getProjectWithDependencies( f );
+ DependencyManagement dep = projectToClone.getDependencyManagement();
+ assertNotNull( "No dependencyManagement", dep );
+ List<?> list = dep.getDependencies();
+ assertNotNull( "No dependencies", list );
+ assertTrue( "Empty dependency list", !list.isEmpty() );
+
+ Map<?, ?> map = projectToClone.getManagedVersionMap();
+ assertNotNull( "No ManagedVersionMap", map );
+ assertTrue( "ManagedVersionMap is empty", !map.isEmpty() );
+
+ MavenProject clonedProject = projectToClone.clone();
+ assertEquals( "maven-core", clonedProject.getArtifactId() );
+ Map<?, ?> clonedMap = clonedProject.getManagedVersionMap();
+ assertNotNull( "ManagedVersionMap not copied", clonedMap );
+ assertTrue( "ManagedVersionMap is empty", !clonedMap.isEmpty() );
+ assertTrue( "ManagedVersionMap does not contain test key",
+ clonedMap.containsKey( "maven-test:maven-test-b:jar" ) );
+ }
+
+ public void testGetModulePathAdjustment()
+ throws IOException
+ {
+ Model moduleModel = new Model();
+
+ MavenProject module = new MavenProject( moduleModel );
+ module.setFile( new File( "module-dir/pom.xml" ) );
+
+ Model parentModel = new Model();
+ parentModel.addModule( "../module-dir" );
+
+ MavenProject parent = new MavenProject( parentModel );
+ parent.setFile( new File( "parent-dir/pom.xml" ) );
+
+ String pathAdjustment = parent.getModulePathAdjustment( module );
+
+ assertEquals( "..", pathAdjustment );
+ }
+
+ public void testCloneWithDistributionManagement()
+ throws Exception
+ {
+
+ File f = getFileForClasspathResource( "distributionManagement-pom.xml" );
+ MavenProject projectToClone = getProject( f );
+
+ MavenProject clonedProject = projectToClone.clone();
+ assertNotNull( "clonedProject - distributionManagement", clonedProject.getDistributionManagementArtifactRepository() );
+ }
+
+ public void testCloneWithActiveProfile()
+ throws Exception
+ {
+
+ File f = getFileForClasspathResource( "withActiveByDefaultProfile-pom.xml" );
+ MavenProject projectToClone = getProject( f );
+ List<Profile> activeProfilesOrig = projectToClone.getActiveProfiles();
+
+ assertEquals( "Expecting 1 active profile", 1, activeProfilesOrig.size() );
+
+ MavenProject clonedProject = projectToClone.clone();
+
+ List<Profile> activeProfilesClone = clonedProject.getActiveProfiles();
+
+ assertEquals( "Expecting 1 active profile", 1, activeProfilesClone.size() );
+
+ assertNotSame( "The list of active profiles should have been cloned too but is same", activeProfilesOrig,
+ activeProfilesClone );
+ }
+
+ public void testUndefinedOutputDirectory()
+ throws Exception
+ {
+ MavenProject p = new MavenProject();
+ assertNoNulls( p.getCompileClasspathElements() );
+ assertNoNulls( p.getSystemClasspathElements() );
+ assertNoNulls( p.getRuntimeClasspathElements() );
+ assertNoNulls( p.getTestClasspathElements() );
+ }
+
+ private void assertNoNulls( List<String> elements )
+ {
+ assertFalse( elements.contains( null ) );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/project/PomConstructionTest.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/project/PomConstructionTest.java
new file mode 100644
index 00000000..f17539b1
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/project/PomConstructionTest.java
@@ -0,0 +1,1878 @@
+package org.apache.maven.project;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.maven.artifact.repository.layout.DefaultRepositoryLayout;
+import org.apache.maven.model.Plugin;
+import org.apache.maven.model.PluginExecution;
+import org.apache.maven.model.building.ModelBuildingRequest;
+import org.apache.maven.project.harness.PomTestWrapper;
+import org.apache.maven.repository.RepositorySystem;
+import org.apache.maven.repository.internal.MavenRepositorySystemUtils;
+import org.codehaus.plexus.ContainerConfiguration;
+import org.codehaus.plexus.PlexusConstants;
+import org.codehaus.plexus.PlexusTestCase;
+import org.eclipse.aether.DefaultRepositorySystemSession;
+import org.eclipse.aether.internal.impl.SimpleLocalRepositoryManagerFactory;
+import org.eclipse.aether.repository.LocalRepository;
+
+public class PomConstructionTest
+ extends PlexusTestCase
+{
+ private static String BASE_DIR = "src/test";
+
+ private static String BASE_POM_DIR = BASE_DIR + "/resources-project-builder";
+
+ private static String BASE_MIXIN_DIR = BASE_DIR + "/resources-mixins";
+
+ private DefaultProjectBuilder projectBuilder;
+
+ private RepositorySystem repositorySystem;
+
+ private File testDirectory;
+
+ @Override
+ protected void customizeContainerConfiguration( ContainerConfiguration containerConfiguration )
+ {
+ super.customizeContainerConfiguration( containerConfiguration );
+ containerConfiguration.setAutoWiring( true );
+ containerConfiguration.setClassPathScanning( PlexusConstants.SCANNING_INDEX );
+ }
+
+ protected void setUp()
+ throws Exception
+ {
+ testDirectory = new File( getBasedir(), BASE_POM_DIR );
+ new File( getBasedir(), BASE_MIXIN_DIR );
+ projectBuilder = (DefaultProjectBuilder) lookup( ProjectBuilder.class );
+ repositorySystem = lookup( RepositorySystem.class );
+ }
+
+ @Override
+ protected void tearDown()
+ throws Exception
+ {
+ projectBuilder = null;
+
+ super.tearDown();
+ }
+
+ /**
+ * Will throw exception if url is empty. MNG-4050
+ *
+ * @throws Exception
+ */
+
+ public void testEmptyUrl()
+ throws Exception
+ {
+ buildPom( "empty-distMng-repo-url" );
+ }
+
+ /**
+ * Tests that modules is not overriden by profile
+ *
+ * @throws Exception
+ */
+ /* MNG-786*/
+ public void testProfileModules()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "profile-module", "a" );
+ assertEquals( "test-prop", pom.getValue( "properties[1]/b" ) );// verifies profile applied
+ assertEquals( 4, ( (List<?>) pom.getValue( "modules" ) ).size() );
+ assertEquals( "module-2", pom.getValue( "modules[1]" ) );
+ assertEquals( "module-1", pom.getValue( "modules[2]" ) );
+ assertEquals( "module-3", pom.getValue( "modules[3]" ) );
+ assertEquals( "module-4", pom.getValue( "modules[4]" ) );
+ }
+
+ /**
+ * Will throw exception if doesn't find parent(s) in build
+ *
+ * @throws Exception
+ */
+ public void testParentInheritance()
+ throws Exception
+ {
+ buildPom( "parent-inheritance/sub" );
+ }
+
+ /*MNG-3995*/
+ public void testExecutionConfigurationJoin()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "execution-configuration-join" );
+ assertEquals( 2, ( (List<?>) pom.getValue( "build/plugins[1]/executions[1]/configuration[1]/fileset[1]" ) ).size() );
+ }
+
+ /*MNG-3803*/
+ public void testPluginConfigProperties()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "plugin-config-properties" );
+ assertEquals( "my.property", pom.getValue( "build/plugins[1]/configuration[1]/systemProperties[1]/property[1]/name" ) );
+ }
+
+ /*MNG-3900*/
+ public void testProfilePropertiesInterpolation()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "profile-properties-interpolation", "interpolation-profile" );
+ assertEquals( "PASSED", pom.getValue( "properties[1]/test" ) );
+ assertEquals( "PASSED", pom.getValue( "properties[1]/property" ) );
+ }
+
+
+ // Some better conventions for the test poms needs to be created and each of these tests
+ // that represent a verification of a specification item needs to be a couple lines at most.
+ // The expressions help a lot, but we need a clean to pick up a directory of POMs, automatically load
+ // them into a resolver, create the expression to extract the data to validate the Model, and the URI
+ // to validate the properties. We also need a way to navigate from the Tex specification documents to
+ // the test in question and vice versa. A little Eclipse plugin would do the trick.
+ public void testThatExecutionsWithoutIdsAreMergedAndTheChildWins()
+ throws Exception
+ {
+ PomTestWrapper tester = buildPom( "micromailer" );
+ assertModelEquals( tester, "child-descriptor", "build/plugins[1]/executions[1]/goals[1]" );
+ }
+
+ /*MNG-
+ public void testDependencyScope()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "dependency-scope/sub" );
+
+ }
+
+ /*MNG- 4010*/
+ public void testDuplicateExclusionsDependency()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "duplicate-exclusions-dependency/sub" );
+ assertEquals( 1, ( (List<?>) pom.getValue( "dependencies[1]/exclusions" ) ).size() );
+
+ }
+
+ /*MNG- 4008*/
+ public void testMultipleFilters()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "multiple-filters" );
+ assertEquals( 4, ( (List<?>) pom.getValue( "build/filters" ) ).size() );
+
+ }
+
+ /** MNG-4005: postponed to 3.1
+ public void testValidationErrorUponNonUniqueDependencyKey()
+ throws Exception
+ {
+ try
+ {
+ buildPom( "unique-dependency-key/deps" );
+ fail( "Non-unique dependency keys did not cause validation error" );
+ }
+ catch ( ProjectBuildingException e )
+ {
+ // expected
+ }
+ }
+
+ public void testValidationErrorUponNonUniqueDependencyManagementKey()
+ throws Exception
+ {
+ try
+ {
+ buildPom( "unique-dependency-key/dep-mngt" );
+ fail( "Non-unique dependency keys did not cause validation error" );
+ }
+ catch ( ProjectBuildingException e )
+ {
+ // expected
+ }
+ }
+
+ public void testValidationErrorUponNonUniqueDependencyKeyInProfile()
+ throws Exception
+ {
+ try
+ {
+ buildPom( "unique-dependency-key/deps-in-profile" );
+ fail( "Non-unique dependency keys did not cause validation error" );
+ }
+ catch ( ProjectBuildingException e )
+ {
+ // expected
+ }
+ }
+
+ public void testValidationErrorUponNonUniqueDependencyManagementKeyInProfile()
+ throws Exception
+ {
+ try
+ {
+ buildPom( "unique-dependency-key/dep-mngt-in-profile" );
+ fail( "Non-unique dependency keys did not cause validation error" );
+ }
+ catch ( ProjectBuildingException e )
+ {
+ // expected
+ }
+ }
+ */
+
+ public void testDuplicateDependenciesCauseLastDeclarationToBePickedInLenientMode()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "unique-dependency-key/deps", true, null );
+ assertEquals( 1, ( (List<?>) pom.getValue( "dependencies" ) ).size() );
+ assertEquals( "0.2", pom.getValue( "dependencies[1]/version" ) );
+ }
+
+ /* MNG-3567*/
+ public void testParentInterpolation()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "parent-interpolation/sub" );
+ pom = new PomTestWrapper( pom.getMavenProject().getParent() );
+ assertEquals( "1.3.0-SNAPSHOT", pom.getValue( "build/plugins[1]/version" ) );
+ }
+
+/*
+ public void testMaven()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPomFromMavenProject( "maven-build/sub/pom.xml", null );
+
+ for( String s: pom.getMavenProject().getTestClasspathElements() )
+ {
+ System.out.println( s );
+ }
+
+ }
+ */
+
+ /* MNG-3567*/
+ public void testPluginManagementInherited()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "pluginmanagement-inherited/sub" );
+ assertEquals( "1.0-alpha-21", pom.getValue( "build/plugins[1]/version" ) );
+ }
+
+ /* MNG-2174*/
+ public void testPluginManagementDependencies()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "plugin-management-dependencies/sub", "test" );
+ assertEquals( "1.0-alpha-21", pom.getValue( "build/plugins[1]/version" ) );
+ assertEquals( "1.0", pom.getValue( "build/plugins[1]/dependencies[1]/version" ) );
+ }
+
+
+ /* MNG-3877*/
+ public void testReportingInterpolation()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "reporting-interpolation" );
+ assertEquals( createPath( Arrays.asList( System.getProperty( "user.dir" ), "src", "test",
+ "resources-project-builder", "reporting-interpolation", "target",
+ "site" ) ), pom.getValue( "reporting/outputDirectory" ) );
+ }
+
+
+ public void testPluginOrder()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "plugin-order" );
+ assertEquals( "plexus-component-metadata", pom.getValue( "build/plugins[1]/artifactId" ) );
+ assertEquals( "maven-surefire-plugin", pom.getValue( "build/plugins[2]/artifactId" ) );
+ }
+
+ public void testErroneousJoiningOfDifferentPluginsWithEqualDependencies()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "equal-plugin-deps" );
+ assertEquals( "maven-it-plugin-a", pom.getValue( "build/plugins[1]/artifactId" ) );
+ assertEquals( 1, ( (List<?>) pom.getValue( "build/plugins[1]/dependencies" ) ).size() );
+ assertEquals( "maven-it-plugin-b", pom.getValue( "build/plugins[2]/artifactId" ) );
+ assertEquals( 1, ( (List<?>) pom.getValue( "build/plugins[1]/dependencies" ) ).size() );
+ }
+
+ /** MNG-3821 */
+ public void testErroneousJoiningOfDifferentPluginsWithEqualExecutionIds()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "equal-plugin-exec-ids" );
+ assertEquals( "maven-it-plugin-a", pom.getValue( "build/plugins[1]/artifactId" ) );
+ assertEquals( 1, ( (List<?>) pom.getValue( "build/plugins[1]/executions" ) ).size() );
+ assertEquals( "maven-it-plugin-b", pom.getValue( "build/plugins[2]/artifactId" ) );
+ assertEquals( 1, ( (List<?>) pom.getValue( "build/plugins[1]/executions" ) ).size() );
+ assertEquals( "maven-it-plugin-a", pom.getValue( "reporting/plugins[1]/artifactId" ) );
+ assertEquals( 1, ( (List<?>) pom.getValue( "reporting/plugins[1]/reportSets" ) ).size() );
+ assertEquals( "maven-it-plugin-b", pom.getValue( "reporting/plugins[2]/artifactId" ) );
+ assertEquals( 1, ( (List<?>) pom.getValue( "reporting/plugins[1]/reportSets" ) ).size() );
+ }
+
+ /** MNG-3998 */
+ public void testExecutionConfiguration()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "execution-configuration" );
+ assertEquals( 2, ( (List<?>) pom.getValue( "build/plugins[1]/executions" ) ).size() );
+ assertEquals( "src/main/mdo/nexus.xml",
+ ( pom.getValue( "build/plugins[1]/executions[1]/configuration[1]/model" ) ) );
+ assertEquals( "src/main/mdo/security.xml",
+ ( pom.getValue( "build/plugins[1]/executions[2]/configuration[1]/model" ) ) );
+ }
+
+ /*
+ public void testPluginConfigDuplicate()
+ throws Exception
+{
+ PomTestWrapper pom = buildPom( "plugin-config-duplicate/dup" );
+}
+*/
+
+
+ public void testSingleConfigurationInheritance()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "single-configuration-inheritance" );
+
+ assertEquals( 2, ( (List<?>) pom.getValue( "build/plugins[1]/executions[1]/configuration[1]/rules" ) ).size() );
+ assertEquals( "2.0.6",
+ pom.getValue( "build/plugins[1]/executions[1]/configuration[1]/rules[1]/requireMavenVersion[1]/version" ) );
+ assertEquals( "[1.4,)",
+ pom.getValue( "build/plugins[1]/executions[1]/configuration[1]/rules[1]/requireJavaVersion[1]/version" ) );
+ }
+
+ public void testConfigWithPluginManagement()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "config-with-plugin-mng" );
+ assertEquals( 2, ( (List<?>) pom.getValue( "build/plugins[1]/executions" ) ).size() );
+ assertEquals( "src/main/mdo/security.xml", pom.getValue( "build/plugins[1]/executions[2]/configuration[1]/model" ) );
+ assertEquals( "1.0.8", pom.getValue( "build/plugins[1]/executions[1]/configuration[1]/version" ) );
+ }
+
+ /** MNG-3965 */
+ public void testExecutionConfigurationSubcollections()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "execution-configuration-subcollections" );
+ assertEquals( 2, ( (List<?>) pom.getValue( "build/plugins[1]/executions[1]/configuration[1]/rules[1]/bannedDependencies" ) ).size() );
+ }
+
+ /** MNG-3985 */
+ public void testMultipleRepositories()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "multiple-repos/sub" );
+ assertEquals( 3, ( (List<?>) pom.getValue( "repositories" ) ).size() );
+ }
+
+ /** MNG-3965 */
+ public void testMultipleExecutionIds()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "dual-execution-ids/sub" );
+ assertEquals( 1, ( (List<?>) pom.getValue( "build/plugins[1]/executions" ) ).size() );
+ }
+
+ /** MNG-3997 */
+ public void testConsecutiveEmptyElements()
+ throws Exception
+ {
+ buildPom( "consecutive_empty_elements" );
+ }
+
+ public void testOrderOfGoalsFromPluginExecutionWithoutPluginManagement()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "plugin-exec-goals-order/wo-plugin-mngt" );
+ assertEquals( 5, ( (List<?>) pom.getValue( "build/plugins[1]/executions[1]/goals" ) ).size() );
+ assertEquals( "b", pom.getValue( "build/plugins[1]/executions[1]/goals[1]" ) );
+ assertEquals( "a", pom.getValue( "build/plugins[1]/executions[1]/goals[2]" ) );
+ assertEquals( "d", pom.getValue( "build/plugins[1]/executions[1]/goals[3]" ) );
+ assertEquals( "c", pom.getValue( "build/plugins[1]/executions[1]/goals[4]" ) );
+ assertEquals( "e", pom.getValue( "build/plugins[1]/executions[1]/goals[5]" ) );
+ }
+
+ /* MNG-3886*/
+ public void testOrderOfGoalsFromPluginExecutionWithPluginManagement()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "plugin-exec-goals-order/w-plugin-mngt" );
+ assertEquals( 5, ( (List<?>) pom.getValue( "build/plugins[1]/executions[1]/goals" ) ).size() );
+ assertEquals( "b", pom.getValue( "build/plugins[1]/executions[1]/goals[1]" ) );
+ assertEquals( "a", pom.getValue( "build/plugins[1]/executions[1]/goals[2]" ) );
+ assertEquals( "d", pom.getValue( "build/plugins[1]/executions[1]/goals[3]" ) );
+ assertEquals( "c", pom.getValue( "build/plugins[1]/executions[1]/goals[4]" ) );
+ assertEquals( "e", pom.getValue( "build/plugins[1]/executions[1]/goals[5]" ) );
+ }
+
+ public void testOrderOfPluginExecutionsWithoutPluginManagement()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "plugin-exec-order/wo-plugin-mngt" );
+ assertEquals( 5, ( (List<?>) pom.getValue( "build/plugins[1]/executions" ) ).size() );
+ assertEquals( "b", pom.getValue( "build/plugins[1]/executions[1]/id" ) );
+ assertEquals( "a", pom.getValue( "build/plugins[1]/executions[2]/id" ) );
+ assertEquals( "d", pom.getValue( "build/plugins[1]/executions[3]/id" ) );
+ assertEquals( "c", pom.getValue( "build/plugins[1]/executions[4]/id" ) );
+ assertEquals( "e", pom.getValue( "build/plugins[1]/executions[5]/id" ) );
+ }
+
+ /* MNG-3887 */
+ public void testOrderOfPluginExecutionsWithPluginManagement()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "plugin-exec-order/w-plugin-mngt" );
+ assertEquals( 5, ( (List<?>) pom.getValue( "build/plugins[1]/executions" ) ).size() );
+ assertEquals( "b", pom.getValue( "build/plugins[1]/executions[1]/id" ) );
+ assertEquals( "a", pom.getValue( "build/plugins[1]/executions[2]/id" ) );
+ assertEquals( "d", pom.getValue( "build/plugins[1]/executions[3]/id" ) );
+ assertEquals( "c", pom.getValue( "build/plugins[1]/executions[4]/id" ) );
+ assertEquals( "e", pom.getValue( "build/plugins[1]/executions[5]/id" ) );
+ }
+
+ public void testMergeOfPluginExecutionsWhenChildInheritsPluginVersion()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "plugin-exec-merging-wo-version/sub" );
+ assertEquals( 4, ( (List<?>) pom.getValue( "build/plugins[1]/executions" ) ).size() );
+ }
+
+ /* MNG-3943*/
+ public void testMergeOfPluginExecutionsWhenChildAndParentUseDifferentPluginVersions()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "plugin-exec-merging-version-insensitive/sub" );
+ assertEquals( 4, ( (List<?>) pom.getValue( "build/plugins[1]/executions" ) ).size() );
+ }
+
+
+ public void testInterpolationWithXmlMarkup()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "xml-markup-interpolation" );
+ assertEquals( "<?xml version='1.0'?>Tom&Jerry", pom.getValue( "properties/xmlTest" ) );
+ }
+
+ /* MNG-3925 */
+ public void testOrderOfMergedPluginExecutionsWithoutPluginManagement()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "merged-plugin-exec-order/wo-plugin-mngt/sub" );
+ assertEquals( 5, ( (List<?>) pom.getValue( "build/plugins[1]/executions" ) ).size() );
+ assertEquals( "parent-1", pom.getValue( "build/plugins[1]/executions[1]/goals[1]" ) );
+ assertEquals( "parent-2", pom.getValue( "build/plugins[1]/executions[2]/goals[1]" ) );
+ assertEquals( "child-default", pom.getValue( "build/plugins[1]/executions[3]/goals[1]" ) );
+ assertEquals( "child-1", pom.getValue( "build/plugins[1]/executions[4]/goals[1]" ) );
+ assertEquals( "child-2", pom.getValue( "build/plugins[1]/executions[5]/goals[1]" ) );
+ }
+
+ public void testOrderOfMergedPluginExecutionsWithPluginManagement()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "merged-plugin-exec-order/w-plugin-mngt/sub" );
+ assertEquals( 5, ( (List<?>) pom.getValue( "build/plugins[1]/executions" ) ).size() );
+ assertEquals( "parent-1", pom.getValue( "build/plugins[1]/executions[1]/goals[1]" ) );
+ assertEquals( "parent-2", pom.getValue( "build/plugins[1]/executions[2]/goals[1]" ) );
+ assertEquals( "child-default", pom.getValue( "build/plugins[1]/executions[3]/goals[1]" ) );
+ assertEquals( "child-1", pom.getValue( "build/plugins[1]/executions[4]/goals[1]" ) );
+ assertEquals( "child-2", pom.getValue( "build/plugins[1]/executions[5]/goals[1]" ) );
+ }
+
+ /* MNG-3984*/
+ public void testDifferentContainersWithSameId()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "join-different-containers-same-id" );
+ assertEquals( 1, ( (List<?>) pom.getValue( "build/plugins[1]/executions[1]/goals" ) ).size() );
+ assertEquals( 1, ( (List<?>) pom.getValue( "build/pluginManagement/plugins[@artifactId='maven-it-plugin-b']/executions[1]/goals" ) ).size() );
+ }
+
+ /* MNG-3937*/
+ public void testOrderOfMergedPluginExecutionGoalsWithoutPluginManagement()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "merged-plugin-exec-goals-order/wo-plugin-mngt/sub" );
+
+ assertEquals( 5, ( (List<?>) pom.getValue( "build/plugins[1]/executions[1]/goals" ) ).size() );
+ assertEquals( "child-a", pom.getValue( "build/plugins[1]/executions[1]/goals[1]" ) );
+ assertEquals( "merged", pom.getValue( "build/plugins[1]/executions[1]/goals[2]" ) );
+ assertEquals( "child-b", pom.getValue( "build/plugins[1]/executions[1]/goals[3]" ) );
+ assertEquals( "parent-b", pom.getValue( "build/plugins[1]/executions[1]/goals[4]" ) );
+ assertEquals( "parent-a", pom.getValue( "build/plugins[1]/executions[1]/goals[5]" ) );
+ }
+
+ public void testOrderOfMergedPluginExecutionGoalsWithPluginManagement()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "merged-plugin-exec-goals-order/w-plugin-mngt/sub" );
+ assertEquals( 5, ( (List<?>) pom.getValue( "build/plugins[1]/executions[1]/goals" ) ).size() );
+ assertEquals( "child-a", pom.getValue( "build/plugins[1]/executions[1]/goals[1]" ) );
+ assertEquals( "merged", pom.getValue( "build/plugins[1]/executions[1]/goals[2]" ) );
+ assertEquals( "child-b", pom.getValue( "build/plugins[1]/executions[1]/goals[3]" ) );
+ assertEquals( "parent-b", pom.getValue( "build/plugins[1]/executions[1]/goals[4]" ) );
+ assertEquals( "parent-a", pom.getValue( "build/plugins[1]/executions[1]/goals[5]" ) );
+ }
+
+ /*MNG-3938*/
+ public void testOverridingOfInheritedPluginExecutionsWithoutPluginManagement()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "plugin-exec-merging/wo-plugin-mngt/sub" );
+ assertEquals( 2, ( (List<?>) pom.getValue( "build/plugins[1]/executions" ) ).size() );
+ assertEquals( "child-default", pom.getValue( "build/plugins[1]/executions[@id='default']/phase" ) );
+ assertEquals( "child-non-default", pom.getValue( "build/plugins[1]/executions[@id='non-default']/phase" ) );
+ }
+
+ /* MNG-3938 */
+ public void testOverridingOfInheritedPluginExecutionsWithPluginManagement()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "plugin-exec-merging/w-plugin-mngt/sub" );
+ assertEquals( 2, ( (List<?>) pom.getValue( "build/plugins[1]/executions" ) ).size() );
+ assertEquals( "child-default", pom.getValue( "build/plugins[1]/executions[@id='default']/phase" ) );
+ assertEquals( "child-non-default", pom.getValue( "build/plugins[1]/executions[@id='non-default']/phase" ) );
+ }
+
+
+ /* MNG-3906*/
+ public void testOrderOfMergedPluginDependenciesWithoutPluginManagement()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "merged-plugin-class-path-order/wo-plugin-mngt/sub" );
+
+ assertEquals( 5, ( (List<?>) pom.getValue( "build/plugins[1]/dependencies" ) ).size() );
+ assertNotNull( pom.getValue( "build/plugins[1]/dependencies[1]" ) );
+ assertEquals( "c", pom.getValue( "build/plugins[1]/dependencies[1]/artifactId" ) );
+ assertEquals( "1", pom.getValue( "build/plugins[1]/dependencies[1]/version" ) );
+ assertEquals( "a", pom.getValue( "build/plugins[1]/dependencies[2]/artifactId" ) );
+ assertEquals( "2", pom.getValue( "build/plugins[1]/dependencies[2]/version" ) );
+ assertEquals( "b", pom.getValue( "build/plugins[1]/dependencies[3]/artifactId" ) );
+ assertEquals( "1", pom.getValue( "build/plugins[1]/dependencies[3]/version" ) );
+ assertEquals( "e", pom.getValue( "build/plugins[1]/dependencies[4]/artifactId" ) );
+ assertEquals( "1", pom.getValue( "build/plugins[1]/dependencies[4]/version" ) );
+ assertEquals( "d", pom.getValue( "build/plugins[1]/dependencies[5]/artifactId" ) );
+ assertEquals( "1", pom.getValue( "build/plugins[1]/dependencies[5]/version" ) );
+ }
+
+ public void testOrderOfMergedPluginDependenciesWithPluginManagement()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "merged-plugin-class-path-order/w-plugin-mngt/sub" );
+ assertEquals( 5, ( (List<?>) pom.getValue( "build/plugins[1]/dependencies" ) ).size() );
+ assertEquals( "c", pom.getValue( "build/plugins[1]/dependencies[1]/artifactId" ) );
+ assertEquals( "1", pom.getValue( "build/plugins[1]/dependencies[1]/version" ) );
+ assertEquals( "a", pom.getValue( "build/plugins[1]/dependencies[2]/artifactId" ) );
+ assertEquals( "2", pom.getValue( "build/plugins[1]/dependencies[2]/version" ) );
+ assertEquals( "b", pom.getValue( "build/plugins[1]/dependencies[3]/artifactId" ) );
+ assertEquals( "1", pom.getValue( "build/plugins[1]/dependencies[3]/version" ) );
+ assertEquals( "e", pom.getValue( "build/plugins[1]/dependencies[4]/artifactId" ) );
+ assertEquals( "1", pom.getValue( "build/plugins[1]/dependencies[4]/version" ) );
+ assertEquals( "d", pom.getValue( "build/plugins[1]/dependencies[5]/artifactId" ) );
+ assertEquals( "1", pom.getValue( "build/plugins[1]/dependencies[5]/version" ) );
+ }
+
+ public void testInterpolationOfNestedBuildDirectories()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "nested-build-dir-interpolation" );
+ assertEquals( new File( pom.getBasedir(), "target/classes/dir0" ),
+ new File( (String) pom.getValue( "properties/dir0" ) ) );
+ assertEquals( new File( pom.getBasedir(), "src/test/dir1" ),
+ new File( (String) pom.getValue( "properties/dir1" ) ) );
+ assertEquals( new File( pom.getBasedir(), "target/site/dir2" ),
+ new File( (String) pom.getValue( "properties/dir2" ) ) );
+ }
+
+ public void testAppendArtifactIdOfChildToInheritedUrls()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "url-inheritance/sub" );
+ assertEquals( "http://parent.url/child", pom.getValue( "url" ) );
+ assertEquals( "http://parent.url/org", pom.getValue( "organization/url" ) );
+ assertEquals( "http://parent.url/license.txt", pom.getValue( "licenses[1]/url" ) );
+ assertEquals( "http://parent.url/viewvc/child", pom.getValue( "scm/url" ) );
+ assertEquals( "http://parent.url/scm/child", pom.getValue( "scm/connection" ) );
+ assertEquals( "https://parent.url/scm/child", pom.getValue( "scm/developerConnection" ) );
+ assertEquals( "http://parent.url/issues", pom.getValue( "issueManagement/url" ) );
+ assertEquals( "http://parent.url/ci", pom.getValue( "ciManagement/url" ) );
+ assertEquals( "http://parent.url/dist", pom.getValue( "distributionManagement/repository/url" ) );
+ assertEquals( "http://parent.url/snaps", pom.getValue( "distributionManagement/snapshotRepository/url" ) );
+ assertEquals( "http://parent.url/site/child", pom.getValue( "distributionManagement/site/url" ) );
+ assertEquals( "http://parent.url/download", pom.getValue( "distributionManagement/downloadUrl" ) );
+ }
+
+ /* MNG-3846*/
+ public void testAppendArtifactIdOfParentAndChildToInheritedUrls()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "url-inheritance/another-parent/sub" );
+ assertEquals( "http://parent.url/ap/child", pom.getValue( "url" ) );
+ assertEquals( "http://parent.url/org", pom.getValue( "organization/url" ) );
+ assertEquals( "http://parent.url/license.txt", pom.getValue( "licenses[1]/url" ) );
+ assertEquals( "http://parent.url/viewvc/ap/child", pom.getValue( "scm/url" ) );
+ assertEquals( "http://parent.url/scm/ap/child", pom.getValue( "scm/connection" ) );
+ assertEquals( "https://parent.url/scm/ap/child", pom.getValue( "scm/developerConnection" ) );
+ assertEquals( "http://parent.url/issues", pom.getValue( "issueManagement/url" ) );
+ assertEquals( "http://parent.url/ci", pom.getValue( "ciManagement/url" ) );
+ assertEquals( "http://parent.url/dist", pom.getValue( "distributionManagement/repository/url" ) );
+ assertEquals( "http://parent.url/snaps", pom.getValue( "distributionManagement/snapshotRepository/url" ) );
+ assertEquals( "http://parent.url/site/ap/child", pom.getValue( "distributionManagement/site/url" ) );
+ assertEquals( "http://parent.url/download", pom.getValue( "distributionManagement/downloadUrl" ) );
+ }
+ //*/
+
+ public void testNonInheritedElementsInSubtreesOverriddenByChild()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "limited-inheritance/child" );
+ assertEquals( null, pom.getValue( "organization/url" ) );
+ assertEquals( null, pom.getValue( "issueManagement/system" ) );
+ assertEquals( 0, ( (List<?>) pom.getValue( "ciManagement/notifiers" ) ).size() );
+ assertEquals( "child-distros", pom.getValue( "distributionManagement/repository/id" ) );
+ assertEquals( "ssh://child.url/distros", pom.getValue( "distributionManagement/repository/url" ) );
+ assertEquals( null, pom.getValue( "distributionManagement/repository/name" ) );
+ assertEquals( true, pom.getValue( "distributionManagement/repository/uniqueVersion" ) );
+ assertEquals( "default", pom.getValue( "distributionManagement/repository/layout" ) );
+ assertEquals( "child-snaps", pom.getValue( "distributionManagement/snapshotRepository/id" ) );
+ assertEquals( "ssh://child.url/snaps", pom.getValue( "distributionManagement/snapshotRepository/url" ) );
+ assertEquals( null, pom.getValue( "distributionManagement/snapshotRepository/name" ) );
+ assertEquals( true, pom.getValue( "distributionManagement/snapshotRepository/uniqueVersion" ) );
+ assertEquals( "default", pom.getValue( "distributionManagement/snapshotRepository/layout" ) );
+ assertEquals( "child-site", pom.getValue( "distributionManagement/site/id" ) );
+ assertEquals( "scp://child.url/site", pom.getValue( "distributionManagement/site/url" ) );
+ assertEquals( null, pom.getValue( "distributionManagement/site/name" ) );
+ }
+
+ public void testXmlTextCoalescing()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "xml-coalesce-text" );
+ assertEquals( "A Test Project Property", pom.getValue( "properties/prop0" ) );
+ assertEquals( "That's a test!", pom.getValue( "properties/prop1" ) );
+ assertEquals( 32 * 1024,
+ pom.getValue( "properties/prop2" ).toString().trim().replaceAll( "[\n\r]", "" ).length() );
+ }
+
+ public void testFullInterpolationOfNestedExpressions()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "full-interpolation" );
+ for ( int i = 0; i < 24; i++ )
+ {
+ String index = ( ( i < 10 ) ? "0" : "" ) + i;
+ assertEquals( "PASSED", pom.getValue( "properties/property" + index ) );
+ }
+ }
+
+ public void testInterpolationOfLegacyExpressionsThatDontIncludeTheProjectPrefix()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "unprefixed-expression-interpolation/child" );
+
+ assertEquals( pom.getBasedir(), new File( pom.getValue( "properties/projectDir" ).toString() ) );
+
+ assertEquals( "org.apache.maven.its.mng3831.child", pom.getValue( "properties/projectGroupId" ) );
+ assertEquals( "child", pom.getValue( "properties/projectArtifactId" ) );
+ assertEquals( "2.0-alpha-1", pom.getValue( "properties/projectVersion" ) );
+ assertEquals( "jar", pom.getValue( "properties/projectPackaging" ) );
+
+ assertEquals( "child-name", pom.getValue( "properties/projectName" ) );
+ assertEquals( "child-desc", pom.getValue( "properties/projectDesc" ) );
+ assertEquals( "http://child.org/", pom.getValue( "properties/projectUrl" ) );
+ assertEquals( "2008", pom.getValue( "properties/projectYear" ) );
+ assertEquals( "child-org-name", pom.getValue( "properties/projectOrgName" ) );
+
+ assertEquals( "2.0.0", pom.getValue( "properties/projectPrereqMvn" ) );
+ assertEquals( "http://scm.org/", pom.getValue( "properties/projectScmUrl" ) );
+ assertEquals( "http://issue.org/", pom.getValue( "properties/projectIssueUrl" ) );
+ assertEquals( "http://ci.org/", pom.getValue( "properties/projectCiUrl" ) );
+ assertEquals( "child-dist-repo", pom.getValue( "properties/projectDistRepoName" ) );
+ assertEquals( "http://dist.org/", pom.getValue( "properties/projectDistRepoUrl" ) );
+ assertEquals( "http://site.org/", pom.getValue( "properties/projectDistSiteUrl" ) );
+
+ assertEquals( "org.apache.maven.its.mng3831", pom.getValue( "properties/parentGroupId" ) );
+ assertEquals( "parent", pom.getValue( "properties/parentArtifactId" ) );
+ assertEquals( "1.0", pom.getValue( "properties/parentVersion" ) );
+
+ assertTrue( pom.getValue( "properties/projectBuildOut" ).toString().endsWith( "bin" ) );
+ assertTrue( pom.getValue( "properties/projectSiteOut" ).toString().endsWith( "doc" ) );
+ }
+
+ public void testInterpolationWithBasedirAlignedDirectories()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "basedir-aligned-interpolation" );
+ assertEquals( new File( pom.getBasedir(), "src/main/java" ),
+ new File( pom.getValue( "properties/buildMainSrc" ).toString() ) );
+ assertEquals( new File( pom.getBasedir(), "src/test/java" ),
+ new File( pom.getValue( "properties/buildTestSrc" ).toString() ) );
+ assertEquals( new File( pom.getBasedir(), "src/main/scripts" ),
+ new File( pom.getValue( "properties/buildScriptSrc" ).toString() ) );
+ assertEquals( new File( pom.getBasedir(), "target" ),
+ new File( pom.getValue( "properties/buildOut" ).toString() ) );
+ assertEquals( new File( pom.getBasedir(), "target/classes" ),
+ new File( pom.getValue( "properties/buildMainOut" ).toString() ) );
+ assertEquals( new File( pom.getBasedir(), "target/test-classes" ),
+ new File( pom.getValue( "properties/buildTestOut" ).toString() ) );
+ assertEquals( new File( pom.getBasedir(), "target/site" ),
+ new File( pom.getValue( "properties/siteOut" ).toString() ) );
+ }
+
+ /* MNG-3944*/
+ public void testInterpolationOfBasedirInPomWithUnusualName()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "basedir-interpolation/pom-with-unusual-name.xml" );
+ assertEquals( pom.getBasedir(), new File( pom.getValue( "properties/prop0" ).toString() ) );
+ assertEquals( pom.getBasedir(), new File( pom.getValue( "properties/prop1" ).toString() ) );
+ }
+
+ /* MNG-3979 */
+ public void testJoiningOfContainersWhenChildHasEmptyElements()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "id-container-joining-with-empty-elements/sub" );
+ assertNotNull( pom );
+ }
+
+ public void testOrderOfPluginConfigurationElementsWithoutPluginManagement()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "plugin-config-order/wo-plugin-mngt" );
+ assertEquals( "one", pom.getValue( "build/plugins[1]/configuration/stringParams/stringParam[1]" ) );
+ assertEquals( "two", pom.getValue( "build/plugins[1]/configuration/stringParams/stringParam[2]" ) );
+ assertEquals( "three", pom.getValue( "build/plugins[1]/configuration/stringParams/stringParam[3]" ) );
+ assertEquals( "four", pom.getValue( "build/plugins[1]/configuration/stringParams/stringParam[4]" ) );
+ }
+
+ /* MNG-3827*/
+ public void testOrderOfPluginConfigurationElementsWithPluginManagement()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "plugin-config-order/w-plugin-mngt" );
+ assertEquals( "one", pom.getValue( "build/plugins[1]/configuration/stringParams/stringParam[1]" ) );
+ assertEquals( "two", pom.getValue( "build/plugins[1]/configuration/stringParams/stringParam[2]" ) );
+ assertEquals( "three", pom.getValue( "build/plugins[1]/configuration/stringParams/stringParam[3]" ) );
+ assertEquals( "four", pom.getValue( "build/plugins[1]/configuration/stringParams/stringParam[4]" ) );
+ }
+
+ public void testOrderOfPluginExecutionConfigurationElementsWithoutPluginManagement()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "plugin-exec-config-order/wo-plugin-mngt" );
+ String prefix = "build/plugins[1]/executions[1]/configuration/";
+ assertEquals( "one", pom.getValue( prefix + "stringParams/stringParam[1]" ) );
+ assertEquals( "two", pom.getValue( prefix + "stringParams/stringParam[2]" ) );
+ assertEquals( "three", pom.getValue( prefix + "stringParams/stringParam[3]" ) );
+ assertEquals( "four", pom.getValue( prefix + "stringParams/stringParam[4]" ) );
+ assertEquals( "key1", pom.getValue( prefix + "propertiesParam/property[1]/name" ) );
+ assertEquals( "key2", pom.getValue( prefix + "propertiesParam/property[2]/name" ) );
+ }
+
+ /* MNG-3864*/
+ public void testOrderOfPluginExecutionConfigurationElementsWithPluginManagement()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "plugin-exec-config-order/w-plugin-mngt" );
+ String prefix = "build/plugins[1]/executions[1]/configuration/";
+ assertEquals( "one", pom.getValue( prefix + "stringParams/stringParam[1]" ) );
+ assertEquals( "two", pom.getValue( prefix + "stringParams/stringParam[2]" ) );
+ assertEquals( "three", pom.getValue( prefix + "stringParams/stringParam[3]" ) );
+ assertEquals( "four", pom.getValue( prefix + "stringParams/stringParam[4]" ) );
+ assertEquals( "key1", pom.getValue( prefix + "propertiesParam/property[1]/name" ) );
+ assertEquals( "key2", pom.getValue( prefix + "propertiesParam/property[2]/name" ) );
+ }
+
+ /* MNG-3836*/
+ public void testMergeOfInheritedPluginConfiguration()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "plugin-config-merging/child" );
+
+ String prefix = "build/plugins[1]/configuration/";
+ assertEquals( "PASSED", pom.getValue( prefix + "propertiesFile" ) );
+ assertEquals( "PASSED", pom.getValue( prefix + "parent" ) );
+ assertEquals( "PASSED-1", pom.getValue( prefix + "stringParams/stringParam[1]" ) );
+ assertEquals( "PASSED-3", pom.getValue( prefix + "stringParams/stringParam[2]" ) );
+ assertEquals( "PASSED-2", pom.getValue( prefix + "stringParams/stringParam[3]" ) );
+ assertEquals( "PASSED-4", pom.getValue( prefix + "stringParams/stringParam[4]" ) );
+ assertEquals( "PASSED-1", pom.getValue( prefix + "listParam/listParam[1]" ) );
+ assertEquals( "PASSED-3", pom.getValue( prefix + "listParam/listParam[2]" ) );
+ assertEquals( "PASSED-2", pom.getValue( prefix + "listParam/listParam[3]" ) );
+ assertEquals( "PASSED-4", pom.getValue( prefix + "listParam/listParam[4]" ) );
+ }
+
+ /* MNG-2591 */
+ public void testAppendOfInheritedPluginConfigurationWithNoProfile()
+ throws Exception
+ {
+ testAppendOfInheritedPluginConfiguration( "no-profile" );
+ }
+
+ /* MNG-2591*/
+ public void testAppendOfInheritedPluginConfigurationWithActiveProfile()
+ throws Exception
+ {
+ testAppendOfInheritedPluginConfiguration( "with-profile" );
+ }
+
+ private void testAppendOfInheritedPluginConfiguration( String test )
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "plugin-config-append/" + test + "/subproject" );
+ String prefix = "build/plugins[1]/configuration/";
+ assertEquals( "PARENT-1", pom.getValue( prefix + "stringParams/stringParam[1]" ) );
+ assertEquals( "PARENT-3", pom.getValue( prefix + "stringParams/stringParam[2]" ) );
+ assertEquals( "PARENT-2", pom.getValue( prefix + "stringParams/stringParam[3]" ) );
+ assertEquals( "PARENT-4", pom.getValue( prefix + "stringParams/stringParam[4]" ) );
+ assertEquals( "CHILD-1", pom.getValue( prefix + "stringParams/stringParam[5]" ) );
+ assertEquals( "CHILD-3", pom.getValue( prefix + "stringParams/stringParam[6]" ) );
+ assertEquals( "CHILD-2", pom.getValue( prefix + "stringParams/stringParam[7]" ) );
+ assertEquals( "CHILD-4", pom.getValue( prefix + "stringParams/stringParam[8]" ) );
+ assertEquals( null, pom.getValue( prefix + "stringParams/stringParam[9]" ) );
+ assertEquals( "PARENT-1", pom.getValue( prefix + "listParam/listParam[1]" ) );
+ assertEquals( "PARENT-3", pom.getValue( prefix + "listParam/listParam[2]" ) );
+ assertEquals( "PARENT-2", pom.getValue( prefix + "listParam/listParam[3]" ) );
+ assertEquals( "PARENT-4", pom.getValue( prefix + "listParam/listParam[4]" ) );
+ assertEquals( "CHILD-1", pom.getValue( prefix + "listParam/listParam[5]" ) );
+ assertEquals( "CHILD-3", pom.getValue( prefix + "listParam/listParam[6]" ) );
+ assertEquals( "CHILD-2", pom.getValue( prefix + "listParam/listParam[7]" ) );
+ assertEquals( "CHILD-4", pom.getValue( prefix + "listParam/listParam[8]" ) );
+ assertEquals( null, pom.getValue( prefix + "listParam/listParam[9]" ) );
+ }
+
+ /* MNG-4000 */
+ public void testMultiplePluginExecutionsWithAndWithoutIdsWithoutPluginManagement()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "plugin-exec-w-and-wo-id/wo-plugin-mngt" );
+ assertEquals( 2, ( (List<?>) pom.getValue( "build/plugins[1]/executions" ) ).size() );
+ assertEquals( "log-string", pom.getValue( "build/plugins[1]/executions[1]/goals[1]" ) );
+ assertEquals( "log-string", pom.getValue( "build/plugins[1]/executions[2]/goals[1]" ) );
+ }
+
+ public void testMultiplePluginExecutionsWithAndWithoutIdsWithPluginManagement()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "plugin-exec-w-and-wo-id/w-plugin-mngt" );
+ assertEquals( 2, ( (List<?>) pom.getValue( "build/plugins[1]/executions" ) ).size() );
+ assertEquals( "log-string", pom.getValue( "build/plugins[1]/executions[1]/goals[1]" ) );
+ assertEquals( "log-string", pom.getValue( "build/plugins[1]/executions[2]/goals[1]" ) );
+ }
+
+ public void testDependencyOrderWithoutPluginManagement()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "dependency-order/wo-plugin-mngt" );
+ assertEquals( 4, ( (List<?>) pom.getValue( "dependencies" ) ).size() );
+ assertEquals( "a", pom.getValue( "dependencies[1]/artifactId" ) );
+ assertEquals( "c", pom.getValue( "dependencies[2]/artifactId" ) );
+ assertEquals( "b", pom.getValue( "dependencies[3]/artifactId" ) );
+ assertEquals( "d", pom.getValue( "dependencies[4]/artifactId" ) );
+ }
+
+ public void testDependencyOrderWithPluginManagement()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "dependency-order/w-plugin-mngt" );
+ assertEquals( 4, ( (List<?>) pom.getValue( "dependencies" ) ).size() );
+ assertEquals( "a", pom.getValue( "dependencies[1]/artifactId" ) );
+ assertEquals( "c", pom.getValue( "dependencies[2]/artifactId" ) );
+ assertEquals( "b", pom.getValue( "dependencies[3]/artifactId" ) );
+ assertEquals( "d", pom.getValue( "dependencies[4]/artifactId" ) );
+ }
+
+ public void testBuildDirectoriesUsePlatformSpecificFileSeparator()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "platform-file-separator" );
+ assertPathWithNormalizedFileSeparators( pom.getValue( "build/directory" ) );
+ assertPathWithNormalizedFileSeparators( pom.getValue( "build/outputDirectory" ) );
+ assertPathWithNormalizedFileSeparators( pom.getValue( "build/testOutputDirectory" ) );
+ assertPathWithNormalizedFileSeparators( pom.getValue( "build/sourceDirectory" ) );
+ assertPathWithNormalizedFileSeparators( pom.getValue( "build/testSourceDirectory" ) );
+ assertPathWithNormalizedFileSeparators( pom.getValue( "build/resources[1]/directory" ) );
+ assertPathWithNormalizedFileSeparators( pom.getValue( "build/testResources[1]/directory" ) );
+ assertPathWithNormalizedFileSeparators( pom.getValue( "build/filters[1]" ) );
+ assertPathWithNormalizedFileSeparators( pom.getValue( "reporting/outputDirectory" ) );
+ }
+
+ /* MNG-4008 */
+ public void testMergedFilterOrder()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "merged-filter-order/sub" );
+
+ assertEquals( 7, ( (List<?>) pom.getValue( "build/filters" ) ).size() );
+ assertTrue( pom.getValue( "build/filters[1]" ).toString().endsWith( "child-a.properties" ) );
+ assertTrue( pom.getValue( "build/filters[2]" ).toString().endsWith( "child-c.properties" ) );
+ assertTrue( pom.getValue( "build/filters[3]" ).toString().endsWith( "child-b.properties" ) );
+ assertTrue( pom.getValue( "build/filters[4]" ).toString().endsWith( "child-d.properties" ) );
+ assertTrue( pom.getValue( "build/filters[5]" ).toString().endsWith( "parent-c.properties" ) );
+ assertTrue( pom.getValue( "build/filters[6]" ).toString().endsWith( "parent-b.properties" ) );
+ assertTrue( pom.getValue( "build/filters[7]" ).toString().endsWith( "parent-d.properties" ) );
+ }
+
+ /** MNG-4027*/
+ public void testProfileInjectedDependencies()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "profile-injected-dependencies" );
+ assertEquals( 4, ( (List<?>) pom.getValue( "dependencies" ) ).size() );
+ assertEquals( "a", pom.getValue( "dependencies[1]/artifactId" ) );
+ assertEquals( "c", pom.getValue( "dependencies[2]/artifactId" ) );
+ assertEquals( "b", pom.getValue( "dependencies[3]/artifactId" ) );
+ assertEquals( "d", pom.getValue( "dependencies[4]/artifactId" ) );
+ }
+
+ /** IT-0021*/
+ public void testProfileDependenciesMultipleProfiles()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "profile-dependencies-multiple-profiles", "profile-1", "profile-2" );
+ assertEquals(2, ( (List<?>) pom.getValue( "dependencies" ) ).size() );
+ }
+
+ public void testDependencyInheritance()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "dependency-inheritance/sub" );
+ assertEquals( 1, ( (List<?>) pom.getValue( "dependencies" ) ).size() );
+ assertEquals( "4.4", pom.getValue( "dependencies[1]/version" ) );
+ }
+
+ /** MNG-4034 */
+ public void testManagedProfileDependency()
+ throws Exception
+ {
+ PomTestWrapper pom = this.buildPom( "managed-profile-dependency/sub", "maven-core-it" );
+ assertEquals( 1, ( (List<?>) pom.getValue( "dependencies" ) ).size() );
+ assertEquals( "org.apache.maven.its", pom.getValue( "dependencies[1]/groupId" ) );
+ assertEquals( "maven-core-it-support", pom.getValue( "dependencies[1]/artifactId" ) );
+ assertEquals( "1.3", pom.getValue( "dependencies[1]/version" ) );
+ assertEquals( "runtime", pom.getValue( "dependencies[1]/scope" ) );
+ assertEquals( 1, ( (List<?>) pom.getValue( "dependencies[1]/exclusions" ) ).size() );
+ assertEquals( "commons-lang", pom.getValue( "dependencies[1]/exclusions[1]/groupId" ) );
+ }
+
+ /** MNG-4040 */
+ public void testProfileModuleInheritance()
+ throws Exception
+ {
+ PomTestWrapper pom = this.buildPom( "profile-module-inheritance/sub", "dist" );
+ assertEquals( 0, ( (List<?>) pom.getValue( "modules" ) ).size() );
+ }
+
+ /** MNG-3621 */
+ public void testUncPath()
+ throws Exception
+ {
+ PomTestWrapper pom = this.buildPom( "unc-path/sub" );
+ assertEquals( "file:////host/site/test-child", pom.getValue( "distributionManagement/site/url" ) );
+ }
+
+ /** MNG-2006 */
+ public void testUrlAppendWithChildPathAdjustment()
+ throws Exception
+ {
+ PomTestWrapper pom = this.buildPom( "url-append/child" );
+ assertEquals( "http://project.url/child", pom.getValue( "url" ) );
+ assertEquals( "http://viewvc.project.url/child", pom.getValue( "scm/url" ) );
+ assertEquals( "http://scm.project.url/child", pom.getValue( "scm/connection" ) );
+ assertEquals( "https://scm.project.url/child", pom.getValue( "scm/developerConnection" ) );
+ assertEquals( "http://site.project.url/child", pom.getValue( "distributionManagement/site/url" ) );
+ }
+
+ /** MNG-0479 */
+ public void testRepoInheritance()
+ throws Exception
+ {
+ PomTestWrapper pom = this.buildPom( "repo-inheritance" );
+ assertEquals( 1, ( (List<?>) pom.getValue( "repositories" ) ).size() );
+ assertEquals( "it0043", pom.getValue( "repositories[1]/name" ) );
+ }
+
+ public void testEmptyScm()
+ throws Exception
+ {
+ PomTestWrapper pom = this.buildPom( "empty-scm" );
+ assertNull( pom.getValue( "scm" ) );
+ }
+
+ public void testPluginConfigurationUsingAttributesWithoutPluginManagement()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "plugin-config-attributes/wo-plugin-mngt" );
+ assertEquals( "src", pom.getValue( "build/plugins[1]/configuration/domParam/copy/@todir" ) );
+ assertEquals( "true", pom.getValue( "build/plugins[1]/configuration/domParam/copy/@overwrite" ) );
+ assertEquals( "target", pom.getValue( "build/plugins[1]/configuration/domParam/copy/fileset/@dir" ) );
+ assertEquals( null, pom.getValue( "build/plugins[1]/configuration/domParam/copy/fileset/@todir" ) );
+ assertEquals( null, pom.getValue( "build/plugins[1]/configuration/domParam/copy/fileset/@overwrite" ) );
+ }
+
+ /** MNG-4053*/
+ public void testPluginConfigurationUsingAttributesWithPluginManagement()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "plugin-config-attributes/w-plugin-mngt" );
+ assertEquals( "src", pom.getValue( "build/plugins[1]/configuration/domParam/copy/@todir" ) );
+ assertEquals( "true", pom.getValue( "build/plugins[1]/configuration/domParam/copy/@overwrite" ) );
+ assertEquals( "target", pom.getValue( "build/plugins[1]/configuration/domParam/copy/fileset/@dir" ) );
+ assertEquals( null, pom.getValue( "build/plugins[1]/configuration/domParam/copy/fileset/@todir" ) );
+ assertEquals( null, pom.getValue( "build/plugins[1]/configuration/domParam/copy/fileset/@overwrite" ) );
+ }
+
+ public void testPluginConfigurationUsingAttributesWithPluginManagementAndProfile()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "plugin-config-attributes/w-profile", "maven-core-it" );
+ assertEquals( "src", pom.getValue( "build/plugins[1]/configuration/domParam/copy/@todir" ) );
+ assertEquals( "true", pom.getValue( "build/plugins[1]/configuration/domParam/copy/@overwrite" ) );
+ assertEquals( "target", pom.getValue( "build/plugins[1]/configuration/domParam/copy/fileset/@dir" ) );
+ assertEquals( null, pom.getValue( "build/plugins[1]/configuration/domParam/copy/fileset/@todir" ) );
+ assertEquals( null, pom.getValue( "build/plugins[1]/configuration/domParam/copy/fileset/@overwrite" ) );
+ }
+
+ public void testPomEncoding()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "pom-encoding/utf-8" );
+ assertEquals( "TEST-CHARS: \u00DF\u0131\u03A3\u042F\u05D0\u20AC", pom.getValue( "description" ) );
+ pom = buildPom( "pom-encoding/latin-1" );
+ assertEquals( "TEST-CHARS: \u00C4\u00D6\u00DC\u00E4\u00F6\u00FC\u00DF", pom.getValue( "description" ) );
+ }
+
+ /* MNG-4070 */
+ public void testXmlWhitespaceHandling()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "xml-whitespace/sub" );
+ assertEquals( "org.apache.maven.its.mng4070", pom.getValue( "groupId" ) );
+ }
+
+ /* MNG-3760*/
+ public void testInterpolationOfBaseUrl()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "baseurl-interpolation/pom.xml" );
+ assertEquals( pom.getBasedir().toURI().toString(), pom.getValue( "properties/prop1" ).toString() );
+ }
+
+ /* MNG-3811*/
+ public void testReportingPluginConfig()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "reporting-plugin-config/sub" );
+
+ assertEquals( 3, ( (List<?>) pom.getValue( "reporting/plugins[1]/configuration/stringParams" ) ).size() );
+ assertEquals( "parentParam", pom.getValue( "reporting/plugins[1]/configuration/stringParams[1]/stringParam[1]" ) );
+ assertEquals( "childParam", pom.getValue( "reporting/plugins[1]/configuration/stringParams[1]/stringParam[2]" ) );
+ assertEquals( " preserve space ", pom.getValue( "reporting/plugins[1]/configuration/stringParams[1]/stringParam[3]" ) );
+ assertEquals( "true", pom.getValue( "reporting/plugins[1]/configuration/booleanParam" ) );
+ }
+
+ public void testPropertiesNoDuplication()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "properties-no-duplication/sub" );
+ assertEquals( 1, ( (Properties) pom.getValue( "properties" ) ).size() );
+ assertEquals( "child", pom.getValue( "properties/pomProfile" ) );
+ }
+
+ public void testPomInheritance()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "pom-inheritance/sub" );
+ assertEquals( "parent-description", pom.getValue( "description" ) );
+ assertEquals( "jar", pom.getValue( "packaging" ) );
+ }
+
+ public void testCompleteModelWithoutParent()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "complete-model/wo-parent" );
+
+ testCompleteModel( pom );
+ }
+
+ public void testCompleteModelWithParent()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "complete-model/w-parent/sub" );
+
+ testCompleteModel( pom );
+ }
+
+ private void testCompleteModel( PomTestWrapper pom )
+ throws Exception
+ {
+ assertEquals( "4.0.0", pom.getValue( "modelVersion" ) );
+
+ assertEquals( "org.apache.maven.its.mng", pom.getValue( "groupId" ) );
+ assertEquals( "test", pom.getValue( "artifactId" ) );
+ assertEquals( "0.2", pom.getValue( "version" ) );
+ assertEquals( "pom", pom.getValue( "packaging" ) );
+
+ assertEquals( "project-name", pom.getValue( "name" ) );
+ assertEquals( "project-description", pom.getValue( "description" ) );
+ assertEquals( "http://project.url/", pom.getValue( "url" ) );
+ assertEquals( "2009", pom.getValue( "inceptionYear" ) );
+
+ assertEquals( "project-org", pom.getValue( "organization/name" ) );
+ assertEquals( "http://project-org.url/", pom.getValue( "organization/url" ) );
+
+ assertEquals( 1, ( (List<?>) pom.getValue( "licenses" ) ).size() );
+ assertEquals( "project-license", pom.getValue( "licenses[1]/name" ) );
+ assertEquals( "http://project.url/license", pom.getValue( "licenses[1]/url" ) );
+ assertEquals( "repo", pom.getValue( "licenses[1]/distribution" ) );
+ assertEquals( "free", pom.getValue( "licenses[1]/comments" ) );
+
+ assertEquals( 1, ( (List<?>) pom.getValue( "developers" ) ).size() );
+ assertEquals( "dev", pom.getValue( "developers[1]/id" ) );
+ assertEquals( "project-developer", pom.getValue( "developers[1]/name" ) );
+ assertEquals( "developer@", pom.getValue( "developers[1]/email" ) );
+ assertEquals( "http://developer", pom.getValue( "developers[1]/url" ) );
+ assertEquals( "developer", pom.getValue( "developers[1]/organization" ) );
+ assertEquals( "http://devel.org", pom.getValue( "developers[1]/organizationUrl" ) );
+ assertEquals( "-1", pom.getValue( "developers[1]/timezone" ) );
+ assertEquals( "yes", pom.getValue( "developers[1]/properties/developer" ) );
+ assertEquals( 1, ( (List<?>) pom.getValue( "developers[1]/roles" ) ).size() );
+ assertEquals( "devel", pom.getValue( "developers[1]/roles[1]" ) );
+
+ assertEquals( 1, ( (List<?>) pom.getValue( "contributors" ) ).size() );
+ assertEquals( "project-contributor", pom.getValue( "contributors[1]/name" ) );
+ assertEquals( "contributor@", pom.getValue( "contributors[1]/email" ) );
+ assertEquals( "http://contributor", pom.getValue( "contributors[1]/url" ) );
+ assertEquals( "contributor", pom.getValue( "contributors[1]/organization" ) );
+ assertEquals( "http://contrib.org", pom.getValue( "contributors[1]/organizationUrl" ) );
+ assertEquals( "+1", pom.getValue( "contributors[1]/timezone" ) );
+ assertEquals( "yes", pom.getValue( "contributors[1]/properties/contributor" ) );
+ assertEquals( 1, ( (List<?>) pom.getValue( "contributors[1]/roles" ) ).size() );
+ assertEquals( "contrib", pom.getValue( "contributors[1]/roles[1]" ) );
+
+ assertEquals( 1, ( (List<?>) pom.getValue( "mailingLists" ) ).size() );
+ assertEquals( "project-mailing-list", pom.getValue( "mailingLists[1]/name" ) );
+ assertEquals( "subscribe@", pom.getValue( "mailingLists[1]/subscribe" ) );
+ assertEquals( "unsubscribe@", pom.getValue( "mailingLists[1]/unsubscribe" ) );
+ assertEquals( "post@", pom.getValue( "mailingLists[1]/post" ) );
+ assertEquals( "mail-archive", pom.getValue( "mailingLists[1]/archive" ) );
+ assertEquals( 1, ( (List<?>) pom.getValue( "mailingLists[1]/otherArchives" ) ).size() );
+ assertEquals( "other-archive", pom.getValue( "mailingLists[1]/otherArchives[1]" ) );
+
+ assertEquals( "2.0.1", pom.getValue( "prerequisites/maven" ) );
+
+ assertEquals( "http://project.url/trunk", pom.getValue( "scm/url" ) );
+ assertEquals( "http://project.url/scm", pom.getValue( "scm/connection" ) );
+ assertEquals( "https://project.url/scm", pom.getValue( "scm/developerConnection" ) );
+ assertEquals( "TAG", pom.getValue( "scm/tag" ) );
+
+ assertEquals( "issues", pom.getValue( "issueManagement/system" ) );
+ assertEquals( "http://project.url/issues", pom.getValue( "issueManagement/url" ) );
+
+ assertEquals( "ci", pom.getValue( "ciManagement/system" ) );
+ assertEquals( "http://project.url/ci", pom.getValue( "ciManagement/url" ) );
+ assertEquals( 1, ( (List<?>) pom.getValue( "ciManagement/notifiers" ) ).size() );
+ assertEquals( "irc", pom.getValue( "ciManagement/notifiers[1]/type" ) );
+ assertEquals( "ci@", pom.getValue( "ciManagement/notifiers[1]/address" ) );
+ assertEquals( Boolean.TRUE, pom.getValue( "ciManagement/notifiers[1]/sendOnError" ) );
+ assertEquals( Boolean.FALSE, pom.getValue( "ciManagement/notifiers[1]/sendOnFailure" ) );
+ assertEquals( Boolean.FALSE, pom.getValue( "ciManagement/notifiers[1]/sendOnWarning" ) );
+ assertEquals( Boolean.FALSE, pom.getValue( "ciManagement/notifiers[1]/sendOnSuccess" ) );
+ assertEquals( "ci", pom.getValue( "ciManagement/notifiers[1]/configuration/ciProp" ) );
+
+ assertEquals( "project.distros", pom.getValue( "distributionManagement/repository/id" ) );
+ assertEquals( "distros", pom.getValue( "distributionManagement/repository/name" ) );
+ assertEquals( "http://project.url/dist", pom.getValue( "distributionManagement/repository/url" ) );
+ assertEquals( Boolean.TRUE, pom.getValue( "distributionManagement/repository/uniqueVersion" ) );
+
+ assertEquals( "project.snaps", pom.getValue( "distributionManagement/snapshotRepository/id" ) );
+ assertEquals( "snaps", pom.getValue( "distributionManagement/snapshotRepository/name" ) );
+ assertEquals( "http://project.url/snaps", pom.getValue( "distributionManagement/snapshotRepository/url" ) );
+ assertEquals( Boolean.FALSE, pom.getValue( "distributionManagement/snapshotRepository/uniqueVersion" ) );
+
+ assertEquals( "project.site", pom.getValue( "distributionManagement/site/id" ) );
+ assertEquals( "docs", pom.getValue( "distributionManagement/site/name" ) );
+ assertEquals( "http://project.url/site", pom.getValue( "distributionManagement/site/url" ) );
+
+ assertEquals( "http://project.url/download", pom.getValue( "distributionManagement/downloadUrl" ) );
+ assertEquals( "reloc-gid", pom.getValue( "distributionManagement/relocation/groupId" ) );
+ assertEquals( "reloc-aid", pom.getValue( "distributionManagement/relocation/artifactId" ) );
+ assertEquals( "reloc-version", pom.getValue( "distributionManagement/relocation/version" ) );
+ assertEquals( "project-reloc-msg", pom.getValue( "distributionManagement/relocation/message" ) );
+
+ assertEquals( 1, ( (List<?>) pom.getValue( "modules" ) ).size() );
+ assertEquals( "sub", pom.getValue( "modules[1]" ) );
+
+ assertEquals( 1, ( (Map<?, ?>) pom.getValue( "properties" ) ).size() );
+ assertEquals( "project-property", pom.getValue( "properties[1]/itProperty" ) );
+
+ assertEquals( 1, ( (List<?>) pom.getValue( "dependencyManagement/dependencies" ) ).size() );
+ assertEquals( "org.apache.maven.its", pom.getValue( "dependencyManagement/dependencies[1]/groupId" ) );
+ assertEquals( "managed-dep", pom.getValue( "dependencyManagement/dependencies[1]/artifactId" ) );
+ assertEquals( "0.1", pom.getValue( "dependencyManagement/dependencies[1]/version" ) );
+ assertEquals( "war", pom.getValue( "dependencyManagement/dependencies[1]/type" ) );
+ assertEquals( "runtime", pom.getValue( "dependencyManagement/dependencies[1]/scope" ) );
+ assertEquals( Boolean.FALSE, pom.getValue( "dependencyManagement/dependencies[1]/optional" ) );
+ assertEquals( 1, ( (List<?>) pom.getValue( "dependencyManagement/dependencies[1]/exclusions" ) ).size() );
+ assertEquals( "org.apache.maven.its",
+ pom.getValue( "dependencyManagement/dependencies[1]/exclusions[1]/groupId" ) );
+ assertEquals( "excluded-managed-dep",
+ pom.getValue( "dependencyManagement/dependencies[1]/exclusions[1]/artifactId" ) );
+
+ assertEquals( 1, ( (List<?>) pom.getValue( "dependencies" ) ).size() );
+ assertEquals( "org.apache.maven.its", pom.getValue( "dependencies[1]/groupId" ) );
+ assertEquals( "dep", pom.getValue( "dependencies[1]/artifactId" ) );
+ assertEquals( "0.2", pom.getValue( "dependencies[1]/version" ) );
+ assertEquals( "ejb", pom.getValue( "dependencies[1]/type" ) );
+ assertEquals( "test", pom.getValue( "dependencies[1]/scope" ) );
+ assertEquals( Boolean.TRUE, pom.getValue( "dependencies[1]/optional" ) );
+ assertEquals( 1, ( (List<?>) pom.getValue( "dependencies[1]/exclusions" ) ).size() );
+ assertEquals( "org.apache.maven.its", pom.getValue( "dependencies[1]/exclusions[1]/groupId" ) );
+ assertEquals( "excluded-dep", pom.getValue( "dependencies[1]/exclusions[1]/artifactId" ) );
+
+ assertEquals( 2, ( (List<?>) pom.getValue( "repositories" ) ).size() );
+ assertEquals( "project-remote-repo", pom.getValue( "repositories[1]/id" ) );
+ assertEquals( "http://project.url/remote", pom.getValue( "repositories[1]/url" ) );
+ assertEquals( "repo", pom.getValue( "repositories[1]/name" ) );
+ assertEquals( RepositorySystem.DEFAULT_REMOTE_REPO_ID, pom.getValue( "repositories[2]/id" ) );
+ assertEquals( RepositorySystem.DEFAULT_REMOTE_REPO_URL, pom.getValue( "repositories[2]/url" ) );
+
+ assertEquals( "test", pom.getValue( "build/defaultGoal" ) );
+ assertEquals( "coreit", pom.getValue( "build/finalName" ) );
+
+ assertPathSuffixEquals( "build", pom.getValue( "build/directory" ) );
+ assertPathSuffixEquals( "build/main", pom.getValue( "build/outputDirectory" ) );
+ assertPathSuffixEquals( "build/test", pom.getValue( "build/testOutputDirectory" ) );
+ assertPathSuffixEquals( "sources/main", pom.getValue( "build/sourceDirectory" ) );
+ assertPathSuffixEquals( "sources/test", pom.getValue( "build/testSourceDirectory" ) );
+ assertPathSuffixEquals( "sources/scripts", pom.getValue( "build/scriptSourceDirectory" ) );
+
+ assertEquals( 1, ( (List<?>) pom.getValue( "build/filters" ) ).size() );
+ assertPathSuffixEquals( "src/main/filter/it.properties", pom.getValue( "build/filters[1]" ) );
+
+ assertEquals( 1, ( (List<?>) pom.getValue( "build/resources" ) ).size() );
+ assertPathSuffixEquals( "res/main", pom.getValue( "build/resources[1]/directory" ) );
+ assertPathSuffixEquals( "main", pom.getValue( "build/resources[1]/targetPath" ) );
+ assertEquals( Boolean.TRUE, pom.getValue( "build/resources[1]/filtering" ) );
+ assertEquals( 1, ( (List<?>) pom.getValue( "build/resources[1]/includes" ) ).size() );
+ assertPathSuffixEquals( "main.included", pom.getValue( "build/resources[1]/includes[1]" ) );
+ assertEquals( 1, ( (List<?>) pom.getValue( "build/resources[1]/excludes" ) ).size() );
+ assertPathSuffixEquals( "main.excluded", pom.getValue( "build/resources[1]/excludes[1]" ) );
+
+ assertEquals( 1, ( (List<?>) pom.getValue( "build/testResources" ) ).size() );
+ assertPathSuffixEquals( "res/test", pom.getValue( "build/testResources[1]/directory" ) );
+ assertPathSuffixEquals( "test", pom.getValue( "build/testResources[1]/targetPath" ) );
+ assertEquals( Boolean.TRUE, pom.getValue( "build/testResources[1]/filtering" ) );
+ assertEquals( 1, ( (List<?>) pom.getValue( "build/testResources[1]/includes" ) ).size() );
+ assertPathSuffixEquals( "test.included", pom.getValue( "build/testResources[1]/includes[1]" ) );
+ assertEquals( 1, ( (List<?>) pom.getValue( "build/testResources[1]/excludes" ) ).size() );
+ assertPathSuffixEquals( "test.excluded", pom.getValue( "build/testResources[1]/excludes[1]" ) );
+
+ assertEquals( 1, ( (List<?>) pom.getValue( "build/extensions" ) ).size() );
+ assertEquals( "org.apache.maven.its.ext", pom.getValue( "build/extensions[1]/groupId" ) );
+ assertEquals( "ext", pom.getValue( "build/extensions[1]/artifactId" ) );
+ assertEquals( "3.0", pom.getValue( "build/extensions[1]/version" ) );
+
+ assertEquals( 1, ( (List<?>) pom.getValue( "build/plugins" ) ).size() );
+ assertEquals( "org.apache.maven.its.plugins", pom.getValue( "build/plugins[1]/groupId" ) );
+ assertEquals( "maven-it-plugin-build", pom.getValue( "build/plugins[1]/artifactId" ) );
+ assertEquals( "2.1-SNAPSHOT", pom.getValue( "build/plugins[1]/version" ) );
+ assertEquals( "test.properties", pom.getValue( "build/plugins[1]/configuration/outputFile" ) );
+ assertEquals( 1, ( (List<?>) pom.getValue( "build/plugins[1]/executions" ) ).size() );
+ assertEquals( "test", pom.getValue( "build/plugins[1]/executions[1]/id" ) );
+ assertEquals( "validate", pom.getValue( "build/plugins[1]/executions[1]/phase" ) );
+ assertEquals( "pom.properties", pom.getValue( "build/plugins[1]/executions[1]/configuration/outputFile" ) );
+ assertEquals( 1, ( (List<?>) pom.getValue( "build/plugins[1]/executions[1]/goals" ) ).size() );
+ assertEquals( "eval", pom.getValue( "build/plugins[1]/executions[1]/goals[1]" ) );
+ assertEquals( 1, ( (List<?>) pom.getValue( "build/plugins[1]/dependencies" ) ).size() );
+ assertEquals( "org.apache.maven.its", pom.getValue( "build/plugins[1]/dependencies[1]/groupId" ) );
+ assertEquals( "build-plugin-dep", pom.getValue( "build/plugins[1]/dependencies[1]/artifactId" ) );
+ assertEquals( "0.3", pom.getValue( "build/plugins[1]/dependencies[1]/version" ) );
+ assertEquals( "zip", pom.getValue( "build/plugins[1]/dependencies[1]/type" ) );
+ assertEquals( 1, ( (List<?>) pom.getValue( "build/plugins[1]/dependencies[1]/exclusions" ) ).size() );
+ assertEquals( "org.apache.maven.its", pom.getValue( "build/plugins[1]/dependencies[1]/exclusions[1]/groupId" ) );
+ assertEquals( "excluded-build-plugin-dep",
+ pom.getValue( "build/plugins[1]/dependencies[1]/exclusions[1]/artifactId" ) );
+
+ assertEquals( Boolean.TRUE, pom.getValue( "reporting/excludeDefaults" ) );
+ assertPathSuffixEquals( "docs", pom.getValue( "reporting/outputDirectory" ) );
+
+ assertEquals( 1, ( (List<?>) pom.getValue( "reporting/plugins" ) ).size() );
+ assertEquals( "org.apache.maven.its.plugins", pom.getValue( "reporting/plugins[1]/groupId" ) );
+ assertEquals( "maven-it-plugin-reporting", pom.getValue( "reporting/plugins[1]/artifactId" ) );
+ assertEquals( "2.0-SNAPSHOT", pom.getValue( "reporting/plugins[1]/version" ) );
+ assertEquals( "test.html", pom.getValue( "reporting/plugins[1]/configuration/outputFile" ) );
+ assertEquals( 1, ( (List<?>) pom.getValue( "reporting/plugins[1]/reportSets" ) ).size() );
+ assertEquals( "it", pom.getValue( "reporting/plugins[1]/reportSets[1]/id" ) );
+ assertEquals( "index.html", pom.getValue( "reporting/plugins[1]/reportSets[1]/configuration/outputFile" ) );
+ assertEquals( 1, ( (List<?>) pom.getValue( "reporting/plugins[1]/reportSets[1]/reports" ) ).size() );
+ assertEquals( "run", pom.getValue( "reporting/plugins[1]/reportSets[1]/reports[1]" ) );
+ }
+
+ /* MNG-2309*/
+
+ public void testProfileInjectionOrder()
+ throws Exception
+ {
+ PomTestWrapper pom =
+ buildPom( "profile-injection-order", "pom-a", "pom-b", "pom-e", "pom-c", "pom-d" );
+ assertEquals( "e", pom.getValue( "properties[1]/pomProperty" ) );
+ }
+
+ public void testPropertiesInheritance()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "properties-inheritance/sub" );
+ assertEquals( "parent-property", pom.getValue( "properties/parentProperty" ) );
+ assertEquals( "child-property", pom.getValue( "properties/childProperty" ) );
+ assertEquals( "child-override", pom.getValue( "properties/overriddenProperty" ) );
+ }
+
+ /* MNG-4102*/
+ public void testInheritedPropertiesInterpolatedWithValuesFromChildWithoutProfiles()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "inherited-properties-interpolation/no-profile/sub" );
+
+ assertEquals( "CHILD", pom.getValue( "properties/overridden" ) );
+ assertEquals( "CHILD", pom.getValue( "properties/interpolated" ) );
+ }
+
+ /* MNG-4102 */
+ public void testInheritedPropertiesInterpolatedWithValuesFromChildWithActiveProfiles()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "inherited-properties-interpolation/active-profile/sub" );
+
+ assertEquals( 1, pom.getMavenProject().getModel().getProfiles().size() );
+
+ buildPom( "inherited-properties-interpolation/active-profile/sub", "it-parent", "it-child" );
+ assertEquals( "CHILD", pom.getValue( "properties/overridden" ) );
+ assertEquals( "CHILD", pom.getValue( "properties/interpolated" ) );
+ }
+
+ /* MNG-3545 */
+ public void testProfileDefaultActivation()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "profile-default-deactivation", "profile4" );
+ assertEquals( 1, pom.getMavenProject().getActiveProfiles().size() );
+ assertEquals( 1, ( (List<?>) pom.getValue( "build/plugins" ) ).size() );
+ assertEquals( "2.1", pom.getValue( "build/plugins[1]/version" ) );
+ }
+
+ /* MNG-1995 */
+ public void testBooleanInterpolation()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "boolean-interpolation" );
+ assertTrue ((Boolean) pom.getValue( "repositories[1]/releases/enabled" ) );
+ assertTrue((Boolean) pom.getValue( "build/resources[1]/filtering" ) );
+ }
+
+
+ /* MNG-3899 */
+ public void testBuildExtensionInheritance()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "build-extension-inheritance/sub" );
+ assertEquals( 3, ( (List<?>) pom.getValue( "build/extensions" ) ).size() );
+ assertEquals( "b", pom.getValue( "build/extensions[1]/artifactId" ) );
+ assertEquals( "a", pom.getValue( "build/extensions[2]/artifactId" ) );
+ assertEquals( "0.2", pom.getValue( "build/extensions[2]/version" ) );
+ assertEquals( "c", pom.getValue( "build/extensions[3]/artifactId" ) );
+ }
+
+ /*MNG-1957*/
+ public void testJdkActivation()
+ throws Exception
+ {
+ Properties props = new Properties();
+ props.put( "java.version", "1.5.0_15" );
+
+ PomTestWrapper pom = buildPom( "jdk-activation", props );
+ assertEquals( 3, pom.getMavenProject().getActiveProfiles().size() );
+ assertEquals( "PASSED", pom.getValue( "properties/jdkProperty3" ) );
+ assertEquals( "PASSED", pom.getValue( "properties/jdkProperty2" ) );
+ assertEquals( "PASSED", pom.getValue( "properties/jdkProperty1" ) );
+ }
+
+ /* MNG-2174 */
+ public void testProfilePluginMngDependencies()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "profile-plugin-mng-dependencies/sub", "maven-core-it" );
+ assertEquals( "a", pom.getValue( "build/plugins[1]/dependencies[1]/artifactId" ) );
+ }
+
+ /** MNG-4116 */
+ public void testPercentEncodedUrlsMustNotBeDecoded()
+ throws Exception
+ {
+ PomTestWrapper pom = this.buildPom( "url-no-decoding" );
+ assertEquals( "http://maven.apache.org/spacy%20path", pom.getValue( "url" ) );
+ assertEquals( "http://svn.apache.org/viewvc/spacy%20path", pom.getValue( "scm/url" ) );
+ assertEquals( "scm:svn:svn+ssh://svn.apache.org/spacy%20path", pom.getValue( "scm/connection" ) );
+ assertEquals( "scm:svn:svn+ssh://svn.apache.org/spacy%20path", pom.getValue( "scm/developerConnection" ) );
+ assertEquals( "http://issues.apache.org/spacy%20path", pom.getValue( "issueManagement/url" ) );
+ assertEquals( "http://ci.apache.org/spacy%20path", pom.getValue( "ciManagement/url" ) );
+ assertEquals( "scm:svn:svn+ssh://dist.apache.org/spacy%20path",
+ pom.getValue( "distributionManagement/repository/url" ) );
+ assertEquals( "scm:svn:svn+ssh://snap.apache.org/spacy%20path",
+ pom.getValue( "distributionManagement/snapshotRepository/url" ) );
+ assertEquals( "scm:svn:svn+ssh://site.apache.org/spacy%20path",
+ pom.getValue( "distributionManagement/site/url" ) );
+ }
+
+ public void testPluginManagementInheritance()
+ throws Exception
+ {
+ PomTestWrapper pom = this.buildPom( "plugin-management-inheritance" );
+ assertEquals( "0.1-stub-SNAPSHOT",
+ pom.getValue( "build/pluginManagement/plugins[@artifactId='maven-compiler-plugin']/version" ) );
+ }
+
+ public void testProfilePlugins()
+ throws Exception
+ {
+ PomTestWrapper pom = this.buildPom( "profile-plugins", "standard" );
+ assertEquals( 2, ( (List<?>) pom.getValue( "build/plugins" ) ).size() );
+ assertEquals( "maven-assembly2-plugin", pom.getValue( "build/plugins[2]/artifactId" ) );
+ }
+
+ public void testPluginInheritanceSimple()
+ throws Exception
+ {
+ PomTestWrapper pom = this.buildPom( "plugin-inheritance-simple/sub" );
+ assertEquals( 2, ( (List<?>) pom.getValue( "build/plugins" ) ).size() );
+ }
+
+ public void testPluginManagementDuplicate()
+ throws Exception
+ {
+ PomTestWrapper pom = this.buildPom( "plugin-management-duplicate/sub" );
+ assertEquals( 12, ( (List<?>) pom.getValue( "build/pluginManagement/plugins" ) ).size() );
+ }
+
+ public void testDistributionManagement()
+ throws Exception
+ {
+ PomTestWrapper pom = this.buildPom( "distribution-management" );
+ assertEquals( "legacy", pom.getValue( "distributionManagement/repository/layout" ) );
+ }
+
+ public void testDependencyScopeInheritance()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "dependency-scope-inheritance/sub" );
+ String scope = (String) pom.getValue( "dependencies[1]/scope" );
+ assertEquals( "compile", scope );
+ }
+
+ public void testDependencyScope()
+ throws Exception
+ {
+ buildPom( "dependency-scope/sub" );
+ }
+
+ //This will fail on a validation error if incorrect
+ public void testDependencyManagementWithInterpolation()
+ throws Exception
+ {
+ buildPom( "dependency-management-with-interpolation/sub" );
+ }
+
+ public void testInterpolationWithSystemProperty()
+ throws Exception
+ {
+ Properties sysProps = new Properties();
+ sysProps.setProperty( "system.property", "PASSED" );
+ PomTestWrapper pom = buildPom( "sytem-property-interpolation", sysProps );
+ assertEquals( "PASSED", pom.getValue( "name" ) );
+ }
+
+ /* MNG-4129 */
+ public void testPluginExecutionInheritanceWhenChildDoesNotDeclarePlugin()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "plugin-exec-inheritance/wo-merge" );
+ @SuppressWarnings( "unchecked" )
+ List<PluginExecution> executions =
+ (List<PluginExecution>) pom.getValue( "build/pluginsAsMap[@name='org.apache.maven.its.plugins:maven-it-plugin-log-file']/executions" );
+ assertEquals( 1, executions.size() );
+ assertEquals( "inherited-execution", executions.get( 0 ).getId() );
+ }
+
+ public void testPluginExecutionInheritanceWhenChildDoesDeclarePluginAsWell()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "plugin-exec-inheritance/w-merge" );
+ @SuppressWarnings( "unchecked" )
+ List<PluginExecution> executions =
+ (List<PluginExecution>) pom.getValue( "build/pluginsAsMap[@name='org.apache.maven.its.plugins:maven-it-plugin-log-file']/executions" );
+ assertEquals( 1, executions.size() );
+ assertEquals( "inherited-execution", executions.get( 0 ).getId() );
+ }
+
+ /* MNG-4193 */
+ public void testValidationErrorUponNonUniqueArtifactRepositoryId()
+ throws Exception
+ {
+ try
+ {
+ buildPom( "unique-repo-id/artifact-repo" );
+ fail( "Non-unique repository ids did not cause validation error" );
+ }
+ catch ( ProjectBuildingException e )
+ {
+ // expected
+ }
+ }
+
+ /* MNG-4193 */
+ public void testValidationErrorUponNonUniquePluginRepositoryId()
+ throws Exception
+ {
+ try
+ {
+ buildPom( "unique-repo-id/plugin-repo" );
+ fail( "Non-unique repository ids did not cause validation error" );
+ }
+ catch ( ProjectBuildingException e )
+ {
+ // expected
+ }
+ }
+
+ /* MNG-4193 */
+ public void testValidationErrorUponNonUniqueArtifactRepositoryIdInProfile()
+ throws Exception
+ {
+ try
+ {
+ buildPom( "unique-repo-id/artifact-repo-in-profile" );
+ fail( "Non-unique repository ids did not cause validation error" );
+ }
+ catch ( ProjectBuildingException e )
+ {
+ // expected
+ }
+ }
+
+ /* MNG-4193 */
+ public void testValidationErrorUponNonUniquePluginRepositoryIdInProfile()
+ throws Exception
+ {
+ try
+ {
+ buildPom( "unique-repo-id/plugin-repo-in-profile" );
+ fail( "Non-unique repository ids did not cause validation error" );
+ }
+ catch ( ProjectBuildingException e )
+ {
+ // expected
+ }
+ }
+
+ /** MNG-3843 */
+ public void testPrerequisitesAreNotInherited()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "prerequisites-inheritance/child" );
+ assertSame( null, pom.getValue( "prerequisites" ) );
+ }
+
+ public void testLicensesAreInheritedButNotAggregated()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "licenses-inheritance/child-2" );
+ assertEquals( 1, ( (List<?>) pom.getValue( "licenses" ) ).size() );
+ assertEquals( "child-license", pom.getValue( "licenses[1]/name" ) );
+ assertEquals( "http://child.url/license", pom.getValue( "licenses[1]/url" ) );
+ }
+
+ public void testDevelopersAreInheritedButNotAggregated()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "developers-inheritance/child-2" );
+ assertEquals( 1, ( (List<?>) pom.getValue( "developers" ) ).size() );
+ assertEquals( "child-developer", pom.getValue( "developers[1]/name" ) );
+ }
+
+ public void testContributorsAreInheritedButNotAggregated()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "contributors-inheritance/child-2" );
+ assertEquals( 1, ( (List<?>) pom.getValue( "contributors" ) ).size() );
+ assertEquals( "child-contributor", pom.getValue( "contributors[1]/name" ) );
+ }
+
+ public void testMailingListsAreInheritedButNotAggregated()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "mailing-lists-inheritance/child-2" );
+ assertEquals( 1, ( (List<?>) pom.getValue( "mailingLists" ) ).size() );
+ assertEquals( "child-mailing-list", pom.getValue( "mailingLists[1]/name" ) );
+ }
+
+ public void testPluginInheritanceOrder()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "plugin-inheritance-order/child" );
+
+ assertEquals( "maven-it-plugin-log-file", pom.getValue( "build/plugins[1]/artifactId" ) );
+ assertEquals( "maven-it-plugin-expression", pom.getValue( "build/plugins[2]/artifactId" ) );
+ assertEquals( "maven-it-plugin-configuration", pom.getValue( "build/plugins[3]/artifactId" ) );
+
+ assertEquals( "maven-it-plugin-log-file", pom.getValue( "reporting/plugins[1]/artifactId" ) );
+ assertEquals( "maven-it-plugin-expression", pom.getValue( "reporting/plugins[2]/artifactId" ) );
+ assertEquals( "maven-it-plugin-configuration", pom.getValue( "reporting/plugins[3]/artifactId" ) );
+ }
+
+ public void testCliPropsDominateProjectPropsDuringInterpolation()
+ throws Exception
+ {
+ Properties props = new Properties();
+ props.setProperty( "testProperty", "PASSED" );
+ PomTestWrapper pom = buildPom( "interpolation-cli-wins", props );
+
+ assertEquals( "PASSED", pom.getValue( "properties/interpolatedProperty" ) );
+ }
+
+ public void testParentPomPackagingMustBePom()
+ throws Exception
+ {
+ try
+ {
+ buildPom( "parent-pom-packaging/sub" );
+ fail( "Wrong packaging of parent POM was not rejected" );
+ }
+ catch ( ProjectBuildingException e )
+ {
+ // expected
+ }
+ }
+
+ /** MNG-522, MNG-3018 */
+ public void testManagedPluginConfigurationAppliesToImplicitPluginsIntroducedByPackaging()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "plugin-management-for-implicit-plugin/child" );
+ assertEquals( "passed.txt",
+ pom.getValue( "build/plugins[@artifactId='maven-resources-plugin']/configuration/pathname" ) );
+ assertEquals( "passed.txt",
+ pom.getValue( "build/plugins[@artifactId='maven-it-plugin-log-file']/configuration/logFile" ) );
+ }
+
+ public void testDefaultPluginsExecutionContributedByPackagingExecuteBeforeUserDefinedExecutions()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "plugin-exec-order-and-default-exec" );
+ @SuppressWarnings( "unchecked" )
+ List<PluginExecution> executions =
+ (List<PluginExecution>) pom.getValue( "build/plugins[@artifactId='maven-resources-plugin']/executions" );
+ assertNotNull( executions );
+ assertEquals( 4, executions.size() );
+ assertEquals( "default-resources", executions.get( 0 ).getId() );
+ assertEquals( "default-testResources", executions.get( 1 ).getId() );
+ assertEquals( "test-1", executions.get( 2 ).getId() );
+ assertEquals( "test-2", executions.get( 3 ).getId() );
+ }
+
+ public void testPluginDeclarationsRetainPomOrderAfterInjectionOfDefaultPlugins()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "plugin-exec-order-with-lifecycle" );
+ @SuppressWarnings( "unchecked" )
+ List<Plugin> plugins = (List<Plugin>) pom.getValue( "build/plugins" );
+ int resourcesPlugin = -1;
+ int customPlugin = -1;
+ for ( int i = 0; i < plugins.size(); i++ )
+ {
+ Plugin plugin = plugins.get( i );
+ if ( "maven-resources-plugin".equals( plugin.getArtifactId() ) )
+ {
+ assertTrue( resourcesPlugin < 0 );
+ resourcesPlugin = i;
+ }
+ else if ( "maven-it-plugin-log-file".equals( plugin.getArtifactId() ) )
+ {
+ assertTrue( customPlugin < 0 );
+ customPlugin = i;
+ }
+ }
+ assertTrue( plugins.toString(), customPlugin == resourcesPlugin - 1 );
+ }
+
+ /** MNG-4415 */
+ public void testPluginOrderAfterMergingWithInheritedPlugins()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "plugin-inheritance-merge-order/sub" );
+
+ List<String> expected = new ArrayList<String>();
+ expected.add( "maven-it-plugin-error" );
+ expected.add( "maven-it-plugin-configuration" );
+ expected.add( "maven-it-plugin-dependency-resolution" );
+ expected.add( "maven-it-plugin-packaging" );
+ expected.add( "maven-it-plugin-log-file" );
+ expected.add( "maven-it-plugin-expression" );
+ expected.add( "maven-it-plugin-fork" );
+ expected.add( "maven-it-plugin-touch" );
+
+ List<String> actual = new ArrayList<String>();
+ @SuppressWarnings( "unchecked" )
+ List<Plugin> plugins = (List<Plugin>) pom.getValue( "build/plugins" );
+ for ( Plugin plugin : plugins )
+ {
+ actual.add( plugin.getArtifactId() );
+ }
+
+ actual.retainAll( expected );
+
+ assertEquals( actual, expected );
+ }
+
+ /** MNG-4416 */
+ public void testPluginOrderAfterMergingWithInjectedPlugins()
+ throws Exception
+ {
+ PomTestWrapper pom = buildPom( "plugin-injection-merge-order" );
+
+ List<String> expected = new ArrayList<String>();
+ expected.add( "maven-it-plugin-error" );
+ expected.add( "maven-it-plugin-configuration" );
+ expected.add( "maven-it-plugin-dependency-resolution" );
+ expected.add( "maven-it-plugin-packaging" );
+ expected.add( "maven-it-plugin-log-file" );
+ expected.add( "maven-it-plugin-expression" );
+ expected.add( "maven-it-plugin-fork" );
+ expected.add( "maven-it-plugin-touch" );
+
+ List<String> actual = new ArrayList<String>();
+ @SuppressWarnings( "unchecked" )
+ List<Plugin> plugins = (List<Plugin>) pom.getValue( "build/plugins" );
+ for ( Plugin plugin : plugins )
+ {
+ actual.add( plugin.getArtifactId() );
+ }
+
+ actual.retainAll( expected );
+
+ assertEquals( actual, expected );
+ }
+
+ public void testProjectArtifactIdIsNotInheritedButMandatory()
+ throws Exception
+ {
+ try
+ {
+ buildPom( "artifact-id-inheritance/child" );
+ fail( "Missing artifactId did not cause validation error" );
+ }
+ catch ( ProjectBuildingException e )
+ {
+ // expected
+ }
+ }
+
+ private void assertPathSuffixEquals( String expected, Object actual )
+ {
+ String a = actual.toString();
+ a = a.substring( a.length() - expected.length() ).replace( '\\', '/' );
+ assertEquals( expected, a );
+ }
+
+ private void assertPathWithNormalizedFileSeparators( Object value )
+ {
+ assertEquals( new File( value.toString() ).getPath(), value.toString() );
+ }
+
+ private PomTestWrapper buildPom( String pomPath, String... profileIds )
+ throws Exception
+ {
+ return buildPom( pomPath, null, profileIds );
+ }
+
+ private PomTestWrapper buildPom( String pomPath, Properties executionProperties, String... profileIds )
+ throws Exception
+ {
+ return buildPom( pomPath, false, executionProperties, profileIds );
+ }
+
+ private PomTestWrapper buildPom( String pomPath, boolean lenientValidation, Properties executionProperties,
+ String... profileIds )
+ throws Exception
+ {
+ File pomFile = new File( testDirectory, pomPath );
+ if ( pomFile.isDirectory() )
+ {
+ pomFile = new File( pomFile, "pom.xml" );
+ }
+
+ ProjectBuildingRequest config = new DefaultProjectBuildingRequest();
+
+ String localRepoUrl =
+ System.getProperty( "maven.repo.local", System.getProperty( "user.home" ) + "/.m2/repository" );
+ localRepoUrl = "file://" + localRepoUrl;
+ config.setLocalRepository( repositorySystem.createArtifactRepository( "local", localRepoUrl, new DefaultRepositoryLayout(), null, null ) );
+ config.setActiveProfileIds( Arrays.asList( profileIds ) );
+ config.setSystemProperties( executionProperties );
+ config.setUserProperties( executionProperties );
+ config.setValidationLevel( lenientValidation ? ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_2_0
+ : ModelBuildingRequest.VALIDATION_LEVEL_STRICT );
+
+ DefaultRepositorySystemSession repoSession = MavenRepositorySystemUtils.newSession();
+ LocalRepository localRepo = new LocalRepository( config.getLocalRepository().getBasedir() );
+ repoSession.setLocalRepositoryManager( new SimpleLocalRepositoryManagerFactory().newInstance( repoSession, localRepo ) );
+ config.setRepositorySession( repoSession );
+
+ return new PomTestWrapper( pomFile, projectBuilder.build( pomFile, config ).getProject() );
+ }
+
+ protected void assertModelEquals( PomTestWrapper pom, Object expected, String expression )
+ {
+ assertEquals( expected, pom.getValue( expression ) );
+ }
+
+ private static String createPath( List<String> elements )
+ {
+ StringBuilder buffer = new StringBuilder( 256 );
+ for ( String s : elements )
+ {
+ buffer.append( s ).append( File.separator );
+ }
+ return buffer.toString().substring( 0, buffer.toString().length() - 1 );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/project/ProjectBuilderTest.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/project/ProjectBuilderTest.java
new file mode 100644
index 00000000..5511cb1a
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/project/ProjectBuilderTest.java
@@ -0,0 +1,87 @@
+package org.apache.maven.project;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.util.Properties;
+
+import org.apache.maven.AbstractCoreMavenComponentTestCase;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.model.building.FileModelSource;
+import org.apache.maven.model.building.ModelSource;
+
+public class ProjectBuilderTest
+ extends AbstractCoreMavenComponentTestCase
+{
+ protected String getProjectsDirectory()
+ {
+ return "src/test/projects/project-builder";
+ }
+
+ public void testSystemScopeDependencyIsPresentInTheCompileClasspathElements()
+ throws Exception
+ {
+ File pom = getProject( "it0063" );
+
+ Properties eps = new Properties();
+ eps.setProperty( "jre.home", new File( pom.getParentFile(), "jdk/jre" ).getPath() );
+
+ MavenSession session = createMavenSession( pom, eps );
+ MavenProject project = session.getCurrentProject();
+
+ // Here we will actually not have any artifacts because the ProjectDependenciesResolver is not involved here. So
+ // right now it's not valid to ask for artifacts unless plugins require the artifacts.
+
+ project.getCompileClasspathElements();
+ }
+
+ public void testBuildFromModelSource()
+ throws Exception
+ {
+ File pomFile = new File( "src/test/resources/projects/modelsource/module01/pom.xml" );
+ MavenSession mavenSession = createMavenSession( pomFile );
+ ProjectBuildingRequest configuration = new DefaultProjectBuildingRequest();
+ configuration.setRepositorySession( mavenSession.getRepositorySession() );
+ ModelSource modelSource = new FileModelSource( pomFile );
+ ProjectBuildingResult result =
+ lookup( org.apache.maven.project.ProjectBuilder.class ).build( modelSource, configuration );
+
+ assertNotNull( result.getProject().getParentFile() );
+ }
+
+ public void testVersionlessManagedDependency()
+ throws Exception
+ {
+ File pomFile = new File( "src/test/resources/projects/versionless-managed-dependency.xml" );
+ MavenSession mavenSession = createMavenSession( null );
+ ProjectBuildingRequest configuration = new DefaultProjectBuildingRequest();
+ configuration.setRepositorySession( mavenSession.getRepositorySession() );
+
+ try
+ {
+ lookup( org.apache.maven.project.ProjectBuilder.class ).build( pomFile, configuration );
+ fail();
+ }
+ catch ( ProjectBuildingException e )
+ {
+ // this is expected
+ }
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/project/ProjectSorterTest.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/project/ProjectSorterTest.java
new file mode 100644
index 00000000..5cb45279
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/project/ProjectSorterTest.java
@@ -0,0 +1,363 @@
+package org.apache.maven.project;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import junit.framework.TestCase;
+
+import org.apache.maven.model.Build;
+import org.apache.maven.model.Dependency;
+import org.apache.maven.model.Extension;
+import org.apache.maven.model.Model;
+import org.apache.maven.model.Parent;
+import org.apache.maven.model.Plugin;
+import org.apache.maven.model.PluginManagement;
+import org.codehaus.plexus.util.dag.CycleDetectedException;
+
+/**
+ * Test sorting projects by dependencies.
+ *
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ */
+public class ProjectSorterTest
+ extends TestCase
+{
+
+ private Parent createParent( MavenProject project )
+ {
+ return createParent( project.getGroupId(), project.getArtifactId(), project.getVersion() );
+ }
+
+ private Parent createParent( String groupId, String artifactId, String version )
+ {
+ Parent plugin = new Parent();
+ plugin.setGroupId( groupId );
+ plugin.setArtifactId( artifactId );
+ plugin.setVersion( version );
+ return plugin;
+ }
+
+ private Dependency createDependency( MavenProject project )
+ {
+ return createDependency( project.getGroupId(), project.getArtifactId(), project.getVersion() );
+ }
+
+ private Dependency createDependency( String groupId, String artifactId, String version )
+ {
+ Dependency depdendency = new Dependency();
+ depdendency.setGroupId( groupId );
+ depdendency.setArtifactId( artifactId );
+ depdendency.setVersion( version );
+ return depdendency;
+ }
+
+ private Plugin createPlugin( MavenProject project )
+ {
+ return createPlugin( project.getGroupId(), project.getArtifactId(), project.getVersion() );
+ }
+
+ private Plugin createPlugin( String groupId, String artifactId, String version )
+ {
+ Plugin plugin = new Plugin();
+ plugin.setGroupId( groupId );
+ plugin.setArtifactId( artifactId );
+ plugin.setVersion( version );
+ return plugin;
+ }
+
+ private Extension createExtension( String groupId, String artifactId, String version )
+ {
+ Extension extension = new Extension();
+ extension.setGroupId( groupId );
+ extension.setArtifactId( artifactId );
+ extension.setVersion( version );
+ return extension;
+ }
+
+ private static MavenProject createProject( String groupId, String artifactId, String version )
+ {
+ Model model = new Model();
+ model.setGroupId( groupId );
+ model.setArtifactId( artifactId );
+ model.setVersion( version );
+ model.setBuild( new Build() );
+ return new MavenProject( model );
+ }
+
+ public void testShouldNotFailWhenPluginDepReferencesCurrentProject()
+ throws CycleDetectedException, DuplicateProjectException
+ {
+ MavenProject project = createProject( "group", "artifact", "1.0" );
+
+ Build build = project.getModel().getBuild();
+
+ Plugin plugin = createPlugin( "other.group", "other-artifact", "1.0" );
+
+ Dependency dep = createDependency( "group", "artifact", "1.0" );
+
+ plugin.addDependency( dep );
+
+ build.addPlugin( plugin );
+
+ new ProjectSorter( Collections.singletonList( project ) );
+ }
+
+ public void testShouldNotFailWhenManagedPluginDepReferencesCurrentProject()
+ throws CycleDetectedException, DuplicateProjectException
+ {
+ MavenProject project = createProject( "group", "artifact", "1.0" );
+
+ Build build = project.getModel().getBuild();
+
+ PluginManagement pMgmt = new PluginManagement();
+
+ Plugin plugin = createPlugin( "other.group", "other-artifact", "1.0" );
+
+ Dependency dep = createDependency( "group", "artifact", "1.0" );
+
+ plugin.addDependency( dep );
+
+ pMgmt.addPlugin( plugin );
+
+ build.setPluginManagement( pMgmt );
+
+ new ProjectSorter( Collections.singletonList( project ) );
+ }
+
+ public void testShouldNotFailWhenProjectReferencesNonExistentProject()
+ throws CycleDetectedException, DuplicateProjectException
+ {
+ MavenProject project = createProject( "group", "artifact", "1.0" );
+
+ Build build = project.getModel().getBuild();
+
+ Extension extension = createExtension( "other.group", "other-artifact", "1.0" );
+
+ build.addExtension( extension );
+
+ new ProjectSorter( Collections.singletonList( project ) );
+ }
+
+ public void testMatchingArtifactIdsDifferentGroupIds()
+ throws CycleDetectedException, DuplicateProjectException
+ {
+ List<MavenProject> projects = new ArrayList<MavenProject>();
+ MavenProject project1 = createProject( "groupId1", "artifactId", "1.0" );
+ projects.add( project1 );
+ MavenProject project2 = createProject( "groupId2", "artifactId", "1.0" );
+ projects.add( project2 );
+ project1.getDependencies().add( createDependency( project2 ) );
+
+ projects = new ProjectSorter( projects ).getSortedProjects();
+
+ assertEquals( project2, projects.get( 0 ) );
+ assertEquals( project1, projects.get( 1 ) );
+ }
+
+ public void testMatchingGroupIdsDifferentArtifactIds()
+ throws CycleDetectedException, DuplicateProjectException
+ {
+ List<MavenProject> projects = new ArrayList<MavenProject>();
+ MavenProject project1 = createProject( "groupId", "artifactId1", "1.0" );
+ projects.add( project1 );
+ MavenProject project2 = createProject( "groupId", "artifactId2", "1.0" );
+ projects.add( project2 );
+ project1.getDependencies().add( createDependency( project2 ) );
+
+ projects = new ProjectSorter( projects ).getSortedProjects();
+
+ assertEquals( project2, projects.get( 0 ) );
+ assertEquals( project1, projects.get( 1 ) );
+ }
+
+ public void testMatchingIdsAndVersions()
+ throws CycleDetectedException
+ {
+ List<MavenProject> projects = new ArrayList<MavenProject>();
+ MavenProject project1 = createProject( "groupId", "artifactId", "1.0" );
+ projects.add( project1 );
+ MavenProject project2 = createProject( "groupId", "artifactId", "1.0" );
+ projects.add( project2 );
+
+ try
+ {
+ projects = new ProjectSorter( projects ).getSortedProjects();
+ fail( "Duplicate projects should fail" );
+ }
+ catch ( DuplicateProjectException e )
+ {
+ // expected
+ assertTrue( true );
+ }
+ }
+
+ public void testMatchingIdsAndDifferentVersions()
+ throws CycleDetectedException, DuplicateProjectException
+ {
+ List<MavenProject> projects = new ArrayList<MavenProject>();
+ MavenProject project1 = createProject( "groupId", "artifactId", "1.0" );
+ projects.add( project1 );
+ MavenProject project2 = createProject( "groupId", "artifactId", "2.0" );
+ projects.add( project2 );
+
+ projects = new ProjectSorter( projects ).getSortedProjects();
+ assertEquals( project1, projects.get( 0 ) );
+ assertEquals( project2, projects.get( 1 ) );
+ }
+
+ public void testPluginDependenciesInfluenceSorting()
+ throws Exception
+ {
+ List<MavenProject> projects = new ArrayList<MavenProject>();
+
+ MavenProject parentProject = createProject( "groupId", "parent", "1.0" );
+ projects.add( parentProject );
+
+ MavenProject declaringProject = createProject( "groupId", "declarer", "1.0" );
+ declaringProject.setParent( parentProject );
+ declaringProject.getModel().setParent( createParent( parentProject ) );
+ projects.add( declaringProject );
+
+ MavenProject pluginLevelDepProject = createProject( "groupId", "plugin-level-dep", "1.0" );
+ pluginLevelDepProject.setParent( parentProject );
+ pluginLevelDepProject.getModel().setParent( createParent( parentProject ) );
+ projects.add( pluginLevelDepProject );
+
+ MavenProject pluginProject = createProject( "groupId", "plugin", "1.0" );
+ pluginProject.setParent( parentProject );
+ pluginProject.getModel().setParent( createParent( parentProject ) );
+ projects.add( pluginProject );
+
+ Plugin plugin = createPlugin( pluginProject );
+
+ plugin.addDependency( createDependency( pluginLevelDepProject ) );
+
+ Build build = declaringProject.getModel().getBuild();
+
+ build.addPlugin( plugin );
+
+ projects = new ProjectSorter( projects ).getSortedProjects();
+
+ assertEquals( parentProject, projects.get( 0 ) );
+
+ // the order of these two is non-deterministic, based on when they're added to the reactor.
+ assertTrue( projects.contains( pluginProject ) );
+ assertTrue( projects.contains( pluginLevelDepProject ) );
+
+ // the declaring project MUST be listed after the plugin and its plugin-level dep, though.
+ assertEquals( declaringProject, projects.get( 3 ) );
+ }
+
+ public void testPluginDependenciesInfluenceSorting_DeclarationInParent()
+ throws Exception
+ {
+ List<MavenProject> projects = new ArrayList<MavenProject>();
+
+ MavenProject parentProject = createProject( "groupId", "parent-declarer", "1.0" );
+ projects.add( parentProject );
+
+ MavenProject pluginProject = createProject( "groupId", "plugin", "1.0" );
+ pluginProject.setParent( parentProject );
+ pluginProject.getModel().setParent( createParent( parentProject ) );
+ projects.add( pluginProject );
+
+ MavenProject pluginLevelDepProject = createProject( "groupId", "plugin-level-dep", "1.0" );
+ pluginLevelDepProject.setParent( parentProject );
+ pluginLevelDepProject.getModel().setParent( createParent( parentProject ) );
+ projects.add( pluginLevelDepProject );
+
+ Plugin plugin = createPlugin( pluginProject );
+
+ plugin.addDependency( createDependency( pluginLevelDepProject ) );
+
+ Build build = parentProject.getModel().getBuild();
+
+ build.addPlugin( plugin );
+
+ projects = new ProjectSorter( projects ).getSortedProjects();
+
+ System.out.println( projects );
+
+ assertEquals( parentProject, projects.get( 0 ) );
+
+ // the order of these two is non-deterministic, based on when they're added to the reactor.
+ assertTrue( projects.contains( pluginProject ) );
+ assertTrue( projects.contains( pluginLevelDepProject ) );
+ }
+
+ public void testPluginVersionsAreConsidered()
+ throws Exception
+ {
+ List<MavenProject> projects = new ArrayList<MavenProject>();
+
+ MavenProject pluginProjectA = createProject( "group", "plugin-a", "2.0-SNAPSHOT" );
+ projects.add( pluginProjectA );
+ pluginProjectA.getModel().getBuild().addPlugin( createPlugin( "group", "plugin-b", "1.0" ) );
+
+ MavenProject pluginProjectB = createProject( "group", "plugin-b", "2.0-SNAPSHOT" );
+ projects.add( pluginProjectB );
+ pluginProjectB.getModel().getBuild().addPlugin( createPlugin( "group", "plugin-a", "1.0" ) );
+
+ projects = new ProjectSorter( projects ).getSortedProjects();
+
+ assertTrue( projects.contains( pluginProjectA ) );
+ assertTrue( projects.contains( pluginProjectB ) );
+ }
+
+ public void testDependencyPrecedesProjectThatUsesSpecificDependencyVersion()
+ throws Exception
+ {
+ List<MavenProject> projects = new ArrayList<MavenProject>();
+
+ MavenProject usingProject = createProject( "group", "project", "1.0" );
+ projects.add( usingProject );
+ usingProject.getModel().addDependency( createDependency( "group", "dependency", "1.0" ) );
+
+ MavenProject pluginProject = createProject( "group", "dependency", "1.0" );
+ projects.add( pluginProject );
+
+ projects = new ProjectSorter( projects ).getSortedProjects();
+
+ assertEquals( pluginProject, projects.get( 0 ) );
+ assertEquals( usingProject, projects.get( 1 ) );
+ }
+
+ public void testDependencyPrecedesProjectThatUsesUnresolvedDependencyVersion()
+ throws Exception
+ {
+ List<MavenProject> projects = new ArrayList<MavenProject>();
+
+ MavenProject usingProject = createProject( "group", "project", "1.0" );
+ projects.add( usingProject );
+ usingProject.getModel().addDependency( createDependency( "group", "dependency", "[1.0,)" ) );
+
+ MavenProject pluginProject = createProject( "group", "dependency", "1.0" );
+ projects.add( pluginProject );
+
+ projects = new ProjectSorter( projects ).getSortedProjects();
+
+ assertEquals( pluginProject, projects.get( 0 ) );
+ assertEquals( usingProject, projects.get( 1 ) );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/project/TestMetadataSource.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/project/TestMetadataSource.java
new file mode 100644
index 00000000..67c0037b
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/project/TestMetadataSource.java
@@ -0,0 +1,51 @@
+package org.apache.maven.project;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.List;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.metadata.ArtifactMetadataRetrievalException;
+import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
+import org.apache.maven.artifact.metadata.ResolutionGroup;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.project.artifact.MavenMetadataSource;
+import org.codehaus.plexus.component.annotations.Component;
+
+@SuppressWarnings( "deprecation" )
+@Component( role = ArtifactMetadataSource.class, hint = "classpath" )
+public class TestMetadataSource
+ extends MavenMetadataSource
+{
+ @Override
+ public ResolutionGroup retrieve( Artifact artifact, ArtifactRepository localRepository,
+ List<ArtifactRepository> remoteRepositories )
+ throws ArtifactMetadataRetrievalException
+ {
+ ResolutionGroup rg = super.retrieve( artifact, localRepository, remoteRepositories );
+
+ for ( Artifact a : rg.getArtifacts() )
+ {
+ a.setResolved( true );
+ }
+
+ return rg;
+ }
+} \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/project/artifact/DefaultMavenMetadataCacheTest.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/project/artifact/DefaultMavenMetadataCacheTest.java
new file mode 100644
index 00000000..6b103b2c
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/project/artifact/DefaultMavenMetadataCacheTest.java
@@ -0,0 +1,81 @@
+package org.apache.maven.project.artifact;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Arrays;
+import java.util.Collections;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.resolver.filter.ExcludesArtifactFilter;
+import org.apache.maven.project.artifact.DefaultMavenMetadataCache.CacheKey;
+import org.apache.maven.repository.DelegatingLocalArtifactRepository;
+import org.apache.maven.repository.RepositorySystem;
+import org.codehaus.plexus.PlexusTestCase;
+
+/**
+ * @author Igor Fedorenko
+ */
+public class DefaultMavenMetadataCacheTest
+ extends PlexusTestCase
+{
+ private RepositorySystem repositorySystem;
+
+ protected void setUp()
+ throws Exception
+ {
+ super.setUp();
+ repositorySystem = lookup( RepositorySystem.class );
+ }
+
+ @Override
+ protected void tearDown()
+ throws Exception
+ {
+ repositorySystem = null;
+ super.tearDown();
+ }
+
+ public void testCacheKey()
+ throws Exception
+ {
+ Artifact a1 = repositorySystem.createArtifact( "testGroup", "testArtifact", "1.2.3", "jar" );
+ @SuppressWarnings( "deprecation" )
+ ArtifactRepository lr1 = new DelegatingLocalArtifactRepository( repositorySystem.createDefaultLocalRepository() );
+ ArtifactRepository rr1 = repositorySystem.createDefaultRemoteRepository();
+ a1.setDependencyFilter( new ExcludesArtifactFilter( Arrays.asList( "foo" ) ) );
+
+ Artifact a2 = repositorySystem.createArtifact( "testGroup", "testArtifact", "1.2.3", "jar" );
+ @SuppressWarnings( "deprecation" )
+ ArtifactRepository lr2 = new DelegatingLocalArtifactRepository( repositorySystem.createDefaultLocalRepository() );
+ ArtifactRepository rr2 = repositorySystem.createDefaultRemoteRepository();
+ a2.setDependencyFilter( new ExcludesArtifactFilter( Arrays.asList( "foo" ) ) );
+
+ // sanity checks
+ assertNotSame( a1, a2 );
+ assertNotSame( lr1, lr2 );
+ assertNotSame( rr1, rr2 );
+
+ CacheKey k1 = new CacheKey( a1, false, lr1, Collections.singletonList( rr1 ) );
+ CacheKey k2 = new CacheKey( a2, false, lr2, Collections.singletonList( rr2 ) );
+
+ assertEquals(k1.hashCode(), k2.hashCode());
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/project/artifact/MavenMetadataSourceTest.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/project/artifact/MavenMetadataSourceTest.java
new file mode 100644
index 00000000..9c770da9
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/project/artifact/MavenMetadataSourceTest.java
@@ -0,0 +1,183 @@
+package org.apache.maven.project.artifact;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.repository.RepositorySystem;
+import org.codehaus.plexus.PlexusTestCase;
+
+public class MavenMetadataSourceTest
+ extends PlexusTestCase
+{
+ private RepositorySystem repositorySystem;
+
+ protected void setUp()
+ throws Exception
+ {
+ super.setUp();
+ repositorySystem = lookup( RepositorySystem.class );
+ }
+
+ @Override
+ protected void tearDown()
+ throws Exception
+ {
+ repositorySystem = null;
+ super.tearDown();
+ }
+
+ public void testShouldNotCarryExclusionsOverFromDependencyToDependency()
+ throws Exception
+ {
+ /*
+ Dependency dep1 = new Dependency();
+ dep1.setGroupId( "test" );
+ dep1.setArtifactId( "test-artifact" );
+ dep1.setVersion( "1" );
+ dep1.setType( "jar" );
+
+ Exclusion exc = new Exclusion();
+ exc.setGroupId( "test" );
+ exc.setArtifactId( "test-artifact3" );
+
+ dep1.addExclusion( exc );
+
+ Dependency dep2 = new Dependency();
+ dep2.setGroupId( "test" );
+ dep2.setArtifactId( "test-artifact2" );
+ dep2.setVersion( "1" );
+ dep2.setType( "jar" );
+
+ List deps = new ArrayList();
+ deps.add( dep1 );
+ deps.add( dep2 );
+
+ ArtifactFactory factory = lookup( ArtifactFactory.class );
+
+ ArtifactFilter dependencyFilter = new ScopeArtifactFilter( Artifact.SCOPE_COMPILE );
+
+ MavenProject project = new MavenProject( new Model() );
+
+ Set result = project.createArtifacts( dependencyFilter );
+
+ for ( Iterator it = result.iterator(); it.hasNext(); )
+ {
+ Artifact artifact = ( Artifact ) it.next();
+
+ if ( "test-artifact2".equals( artifact.getArtifactId() ) )
+ {
+ ArtifactFilter filter = artifact.getDependencyFilter();
+
+ assertSame( dependencyFilter, filter );
+ }
+ }
+ */
+ }
+
+ //TODO: restore these if it makes sense
+ /*
+ public void testShouldUseCompileScopeIfDependencyScopeEmpty()
+ throws Exception
+ {
+ String groupId = "org.apache.maven";
+ String artifactId = "maven-model";
+
+ Dependency dep = new Dependency();
+
+ dep.setGroupId( groupId );
+ dep.setArtifactId( artifactId );
+ dep.setVersion( "2.0-alpha-3" );
+
+ Model model = new Model();
+
+ model.addDependency( dep );
+
+ MavenProject project = new MavenProject( model, repositorySystem );
+
+ project.setArtifacts( project.createArtifacts( null ) );
+
+ String key = ArtifactUtils.versionlessKey( groupId, artifactId );
+
+ Map artifactMap = project.getArtifactMap();
+
+ assertNotNull( "artifact-map should not be null.", artifactMap );
+ assertEquals( "artifact-map should contain 1 element.", 1, artifactMap.size() );
+
+ Artifact artifact = (Artifact) artifactMap.get( key );
+
+ assertNotNull( "dependency artifact not found in map.", artifact );
+ assertEquals( "dependency artifact has wrong scope.", Artifact.SCOPE_COMPILE, artifact.getScope() );
+
+ //check for back-propagation of default scope.
+ assertEquals( "default scope NOT back-propagated to dependency.", Artifact.SCOPE_COMPILE, dep.getScope() );
+ }
+
+ public void testShouldUseInjectedTestScopeFromDependencyManagement()
+ throws Exception
+ {
+ String groupId = "org.apache.maven";
+ String artifactId = "maven-model";
+
+ Dependency dep = new Dependency();
+
+ dep.setGroupId( groupId );
+ dep.setArtifactId( artifactId );
+ dep.setVersion( "2.0-alpha-3" );
+
+ Model model = new Model();
+
+ model.addDependency( dep );
+
+ Dependency mgd = new Dependency();
+ mgd.setGroupId( groupId );
+ mgd.setArtifactId( artifactId );
+ mgd.setScope( Artifact.SCOPE_TEST );
+
+ DependencyManagement depMgmt = new DependencyManagement();
+
+ depMgmt.addDependency( mgd );
+
+ model.setDependencyManagement( depMgmt );
+
+ MavenProject project = new MavenProject( model, repositorySystem );
+
+ TestModelDefaultsInjector injector = new TestModelDefaultsInjector();
+
+ injector.injectDefaults( model );
+
+ project.setArtifacts( project.createArtifacts( null ) );
+
+ String key = ArtifactUtils.versionlessKey( groupId, artifactId );
+
+ Map artifactMap = project.getArtifactMap();
+
+ assertNotNull( "artifact-map should not be null.", artifactMap );
+ assertEquals( "artifact-map should contain 1 element.", 1, artifactMap.size() );
+
+ Artifact artifact = (Artifact) artifactMap.get( key );
+
+ assertNotNull( "dependency artifact not found in map.", artifact );
+ assertEquals( "dependency artifact has wrong scope.", Artifact.SCOPE_TEST, artifact.getScope() );
+
+ //check for back-propagation of default scope.
+ assertEquals( "default scope NOT back-propagated to dependency.", Artifact.SCOPE_TEST, dep.getScope() );
+ }
+ */
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/project/canonical/CanonicalProjectBuilderTest.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/project/canonical/CanonicalProjectBuilderTest.java
new file mode 100644
index 00000000..8b6454da
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/project/canonical/CanonicalProjectBuilderTest.java
@@ -0,0 +1,101 @@
+package org.apache.maven.project.canonical;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.util.List;
+
+import org.apache.maven.model.Plugin;
+import org.apache.maven.model.PluginExecution;
+import org.apache.maven.project.AbstractMavenProjectTestCase;
+import org.apache.maven.project.MavenProject;
+import org.codehaus.plexus.util.xml.Xpp3Dom;
+
+/**
+ * @author Jason van Zyl
+ */
+public class CanonicalProjectBuilderTest
+ extends AbstractMavenProjectTestCase
+{
+ public void testProjectBuilder()
+ throws Exception
+ {
+ File f = getFileForClasspathResource( "canonical-pom.xml" );
+
+ MavenProject project = getProject( f );
+
+ // ----------------------------------------------------------------------
+ // Top-level elements
+ // ----------------------------------------------------------------------
+
+ assertEquals( "4.0.0", project.getModelVersion() );
+
+ // ----------------------------------------------------------------------
+ // Plugins
+ // ----------------------------------------------------------------------
+
+ List<Plugin> plugins = project.getBuildPlugins();
+
+ // Plugin0 [plexus]
+
+ String key = "org.apache.maven.plugins:maven-plexus-plugin";
+
+ Plugin plugin = null;
+ for ( Plugin check : plugins )
+ {
+ if ( key.equals( check.getKey() ) )
+ {
+ plugin = check;
+ break;
+ }
+ }
+
+ assertNotNull( plugin );
+
+ assertEquals( "1.0", plugin.getVersion() );
+
+ Xpp3Dom configuration = (Xpp3Dom) plugin.getConfiguration();
+
+ assertEquals( "src/conf/plexus.conf", configuration.getChild( "plexusConfiguration" ).getValue() );
+
+ assertEquals( "src/conf/plexus.properties",
+ configuration.getChild( "plexusConfigurationPropertiesFile" ).getValue() );
+
+ assertEquals( "Continuum", configuration.getChild( "plexusApplicationName" ).getValue() );
+
+ // ----------------------------------------------------------------------
+ // Goal specific configuration
+ // ----------------------------------------------------------------------
+
+ List<PluginExecution> executions = plugin.getExecutions();
+
+ PluginExecution execution = executions.get( 0 );
+
+ String g0 = execution.getGoals().get( 0 );
+
+ assertEquals( "plexus:runtime", g0 );
+
+ configuration = (Xpp3Dom) execution.getConfiguration();
+
+ assertEquals( "ContinuumPro", configuration.getChild( "plexusApplicationName" ).getValue() );
+
+ // Plugin1 [antlr]
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/project/harness/PomTestWrapper.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/project/harness/PomTestWrapper.java
new file mode 100644
index 00000000..c204140a
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/project/harness/PomTestWrapper.java
@@ -0,0 +1,121 @@
+package org.apache.maven.project.harness;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.util.Iterator;
+
+import org.apache.commons.jxpath.JXPathContext;
+import org.apache.commons.jxpath.JXPathNotFoundException;
+import org.apache.commons.jxpath.ri.JXPathContextReferenceImpl;
+import org.apache.maven.project.MavenProject;
+
+public class PomTestWrapper
+{
+
+ private File pomFile;
+
+ private JXPathContext context;
+
+ private MavenProject mavenProject;
+
+ static
+ {
+ JXPathContextReferenceImpl.addNodePointerFactory( new Xpp3DomPointerFactory() );
+ }
+
+ public PomTestWrapper( File pomFile, MavenProject mavenProject )
+ {
+ if ( mavenProject == null )
+ {
+ throw new IllegalArgumentException( "mavenProject: null" );
+ }
+ this.mavenProject = mavenProject;
+ this.pomFile = pomFile;
+ context = JXPathContext.newContext( mavenProject.getModel() );
+ }
+
+ public PomTestWrapper( MavenProject mavenProject )
+ {
+ if ( mavenProject == null )
+ {
+ throw new IllegalArgumentException( "mavenProject: null" );
+ }
+ this.mavenProject = mavenProject;
+ context = JXPathContext.newContext( mavenProject.getModel() );
+ }
+
+ public MavenProject getMavenProject()
+ {
+ return mavenProject;
+ }
+
+ public File getBasedir()
+ {
+ return ( pomFile != null ) ? pomFile.getParentFile() : null;
+ }
+
+ public void setValueOnModel( String expression, Object value )
+ {
+ context.setValue( expression, value );
+ }
+
+ /*
+ public int containerCountForUri( String uri )
+ throws IOException
+ {
+ if ( uri == null || uri.trim().equals( "" ) )
+ {
+ throw new IllegalArgumentException( "uri: null or empty" );
+ }
+ ModelDataSource source = new DefaultModelDataSource();
+ source.init( domainModel.getModelProperties(), null );
+ return source.queryFor( uri ).size();
+ }
+ */
+
+ public Iterator<?> getIteratorForXPathExpression( String expression )
+ {
+ return context.iterate( expression );
+ }
+
+ public boolean containsXPathExpression( String expression )
+ {
+ return context.getValue( expression ) != null;
+ }
+
+ public Object getValue( String expression )
+ {
+ try
+ {
+ return context.getValue( expression );
+ }
+ catch ( JXPathNotFoundException e )
+ {
+ return null;
+ }
+ }
+
+ public boolean xPathExpressionEqualsValue( String expression, String value )
+ {
+ return context.getValue( expression ) != null && context.getValue( expression ).equals( value );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/project/harness/Xpp3DomAttributeIterator.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/project/harness/Xpp3DomAttributeIterator.java
new file mode 100644
index 00000000..2811a848
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/project/harness/Xpp3DomAttributeIterator.java
@@ -0,0 +1,89 @@
+package org.apache.maven.project.harness;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.jxpath.ri.QName;
+import org.apache.commons.jxpath.ri.model.NodeIterator;
+import org.apache.commons.jxpath.ri.model.NodePointer;
+import org.codehaus.plexus.util.xml.Xpp3Dom;
+
+/**
+ * An attribute iterator for JXPath to support <code>Xpp3Dom</code>.
+ *
+ * @author Benjamin Bentmann
+ */
+class Xpp3DomAttributeIterator
+ implements NodeIterator
+{
+
+ private NodePointer parent;
+
+ private Xpp3Dom node;
+
+ private List<Map.Entry<String, String>> attributes;
+
+ private Map.Entry<String, String> attribute;
+
+ private int position;
+
+ public Xpp3DomAttributeIterator( NodePointer parent, QName qname )
+ {
+ this.parent = parent;
+ this.node = (Xpp3Dom) parent.getNode();
+
+ Map<String, String> map = new LinkedHashMap<String, String>();
+ for ( String name : this.node.getAttributeNames() )
+ {
+ if ( name.equals( qname.getName() ) || "*".equals( qname.getName() ) )
+ {
+ String value = this.node.getAttribute( name );
+ map.put( name, value );
+ }
+ }
+ this.attributes = new ArrayList<Map.Entry<String, String>>( map.entrySet() );
+ }
+
+ public NodePointer getNodePointer()
+ {
+ if ( position == 0 )
+ {
+ setPosition( 1 );
+ }
+ return ( attribute == null ) ? null : new Xpp3DomAttributePointer( parent, attribute );
+ }
+
+ public int getPosition()
+ {
+ return position;
+ }
+
+ public boolean setPosition( int position )
+ {
+ this.position = position;
+ attribute = ( position > 0 && position <= attributes.size() ) ? attributes.get( position - 1 ) : null;
+ return attribute != null;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/project/harness/Xpp3DomAttributePointer.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/project/harness/Xpp3DomAttributePointer.java
new file mode 100644
index 00000000..04514b18
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/project/harness/Xpp3DomAttributePointer.java
@@ -0,0 +1,105 @@
+package org.apache.maven.project.harness;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Map;
+
+import org.apache.commons.jxpath.ri.QName;
+import org.apache.commons.jxpath.ri.model.NodePointer;
+
+/**
+ * An attribute pointer for JXPath to support <code>Xpp3Dom</code>.
+ *
+ * @author Benjamin Bentmann
+ */
+class Xpp3DomAttributePointer
+ extends NodePointer
+{
+
+ private Map.Entry<String, String> attrib;
+
+ public Xpp3DomAttributePointer( NodePointer parent, Map.Entry<String, String> attrib )
+ {
+ super( parent );
+ this.attrib = attrib;
+ }
+
+ @Override
+ public int compareChildNodePointers( NodePointer pointer1, NodePointer pointer2 )
+ {
+ // should never happen because attributes have no children
+ return 0;
+ }
+
+ @Override
+ public Object getValue()
+ {
+ return attrib.getValue();
+ }
+
+ @Override
+ public Object getBaseValue()
+ {
+ return attrib;
+ }
+
+ @Override
+ public Object getImmediateNode()
+ {
+ return attrib;
+ }
+
+ @Override
+ public int getLength()
+ {
+ return 1;
+ }
+
+ @Override
+ public QName getName()
+ {
+ return new QName( null, attrib.getKey() );
+ }
+
+ @Override
+ public boolean isActual()
+ {
+ return true;
+ }
+
+ @Override
+ public boolean isCollection()
+ {
+ return false;
+ }
+
+ @Override
+ public boolean isLeaf()
+ {
+ return true;
+ }
+
+ @Override
+ public void setValue( Object value )
+ {
+ throw new UnsupportedOperationException();
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/project/harness/Xpp3DomNodeIterator.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/project/harness/Xpp3DomNodeIterator.java
new file mode 100644
index 00000000..796a5ca0
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/project/harness/Xpp3DomNodeIterator.java
@@ -0,0 +1,161 @@
+package org.apache.maven.project.harness;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.jxpath.ri.Compiler;
+import org.apache.commons.jxpath.ri.compiler.NodeNameTest;
+import org.apache.commons.jxpath.ri.compiler.NodeTest;
+import org.apache.commons.jxpath.ri.compiler.NodeTypeTest;
+import org.apache.commons.jxpath.ri.model.NodeIterator;
+import org.apache.commons.jxpath.ri.model.NodePointer;
+import org.codehaus.plexus.util.StringUtils;
+import org.codehaus.plexus.util.xml.Xpp3Dom;
+
+/**
+ * A node iterator for JXPath to support <code>Xpp3Dom</code>.
+ *
+ * @author Benjamin Bentmann
+ */
+class Xpp3DomNodeIterator
+ implements NodeIterator
+{
+
+ private NodePointer parent;
+
+ private NodeTest test;
+
+ private Xpp3Dom node;
+
+ private Xpp3Dom[] children;
+
+ private List<Xpp3Dom> filteredChildren = new ArrayList<Xpp3Dom>();
+
+ private int filteredIndex;
+
+ private Xpp3Dom child;
+
+ private int position;
+
+ public Xpp3DomNodeIterator( NodePointer parent, NodeTest test, boolean reverse, NodePointer startWith )
+ {
+ this.parent = parent;
+ this.node = (Xpp3Dom) parent.getNode();
+ this.children = this.node.getChildren();
+ if ( startWith != null )
+ {
+ Xpp3Dom startWithNode = (Xpp3Dom) startWith.getNode();
+ for ( ; filteredIndex < children.length; filteredIndex++ )
+ {
+ if ( startWithNode.equals( children[filteredIndex] ) )
+ {
+ filteredIndex++;
+ break;
+ }
+ }
+ }
+ this.test = test;
+ if ( reverse )
+ {
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ public NodePointer getNodePointer()
+ {
+ if ( position == 0 )
+ {
+ setPosition( 1 );
+ }
+ return ( child == null ) ? null : new Xpp3DomNodePointer( parent, child );
+ }
+
+ public int getPosition()
+ {
+ return position;
+ }
+
+ public boolean setPosition( int position )
+ {
+ this.position = position;
+ filterChildren( position );
+ child = ( position > 0 && position <= filteredChildren.size() ) ? filteredChildren.get( position - 1 ) : null;
+ return child != null;
+ }
+
+ private void filterChildren( int position )
+ {
+ for ( ; position > filteredChildren.size() && filteredIndex < children.length; filteredIndex++ )
+ {
+ Xpp3Dom child = children[filteredIndex];
+ if ( testNode( child ) )
+ {
+ filteredChildren.add( child );
+ }
+ }
+ }
+
+ private boolean testNode( Xpp3Dom node )
+ {
+ if ( test == null )
+ {
+ return true;
+ }
+ if ( test instanceof NodeNameTest )
+ {
+ String nodeName = node.getName();
+ if ( StringUtils.isEmpty( nodeName ) )
+ {
+ return false;
+ }
+
+ NodeNameTest nodeNameTest = (NodeNameTest) test;
+ String namespaceURI = nodeNameTest.getNamespaceURI();
+ boolean wildcard = nodeNameTest.isWildcard();
+ String testName = nodeNameTest.getNodeName().getName();
+ String testPrefix = nodeNameTest.getNodeName().getPrefix();
+ if ( wildcard && testPrefix == null )
+ {
+ return true;
+ }
+ if ( wildcard || testName.equals( nodeName ) )
+ {
+ return StringUtils.isEmpty( namespaceURI ) || StringUtils.isEmpty( testPrefix );
+ }
+ return false;
+ }
+ if ( test instanceof NodeTypeTest )
+ {
+ switch ( ( (NodeTypeTest) test ).getNodeType() )
+ {
+ case Compiler.NODE_TYPE_NODE:
+ return true;
+ case Compiler.NODE_TYPE_TEXT:
+ return node.getValue() != null;
+ default:
+ return false;
+ }
+ }
+ return false;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/project/harness/Xpp3DomNodePointer.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/project/harness/Xpp3DomNodePointer.java
new file mode 100644
index 00000000..f93bd892
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/project/harness/Xpp3DomNodePointer.java
@@ -0,0 +1,155 @@
+package org.apache.maven.project.harness;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.jxpath.ri.QName;
+import org.apache.commons.jxpath.ri.compiler.NodeTest;
+import org.apache.commons.jxpath.ri.model.NodeIterator;
+import org.apache.commons.jxpath.ri.model.NodePointer;
+import org.codehaus.plexus.util.xml.Xpp3Dom;
+
+/**
+ * A node pointer for JXPath to support <code>Xpp3Dom</code>.
+ *
+ * @author Benjamin Bentmann
+ */
+class Xpp3DomNodePointer
+ extends NodePointer
+{
+
+ private Xpp3Dom node;
+
+ public Xpp3DomNodePointer( Xpp3Dom node )
+ {
+ super( null );
+ this.node = node;
+ }
+
+ public Xpp3DomNodePointer( NodePointer parent, Xpp3Dom node )
+ {
+ super( parent );
+ this.node = node;
+ }
+
+ @Override
+ public int compareChildNodePointers( NodePointer pointer1, NodePointer pointer2 )
+ {
+ Xpp3Dom node1 = (Xpp3Dom) pointer1.getBaseValue();
+ Xpp3Dom node2 = (Xpp3Dom) pointer2.getBaseValue();
+ if ( node1 == node2 )
+ {
+ return 0;
+ }
+ for ( int i = 0; i < node.getChildCount(); i++ )
+ {
+ Xpp3Dom child = node.getChild( i );
+ if ( child == node1 )
+ {
+ return -1;
+ }
+ if ( child == node2 )
+ {
+ return 1;
+ }
+ }
+ return 0;
+ }
+
+ @Override
+ public Object getValue()
+ {
+ return getValue( node );
+ }
+
+ private static Object getValue( Xpp3Dom node )
+ {
+ if ( node.getValue() != null )
+ {
+ return node.getValue();
+ }
+ else
+ {
+ List<Object> children = new ArrayList<Object>();
+ for ( int i = 0; i < node.getChildCount(); i++ )
+ {
+ children.add( getValue( node.getChild( i ) ) );
+ }
+ return children;
+ }
+ }
+
+ @Override
+ public Object getBaseValue()
+ {
+ return node;
+ }
+
+ @Override
+ public Object getImmediateNode()
+ {
+ return node;
+ }
+
+ @Override
+ public int getLength()
+ {
+ return 1;
+ }
+
+ @Override
+ public QName getName()
+ {
+ return new QName( null, node.getName() );
+ }
+
+ @Override
+ public boolean isCollection()
+ {
+ return false;
+ }
+
+ @Override
+ public boolean isLeaf()
+ {
+ return node.getChildCount() <= 0;
+ }
+
+ @Override
+ public void setValue( Object value )
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public NodeIterator childIterator( NodeTest test, boolean reverse, NodePointer startWith )
+ {
+ return new Xpp3DomNodeIterator( this, test, reverse, startWith );
+ }
+
+ @Override
+ public NodeIterator attributeIterator( QName qname )
+ {
+ return new Xpp3DomAttributeIterator( this, qname );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/project/harness/Xpp3DomPointerFactory.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/project/harness/Xpp3DomPointerFactory.java
new file mode 100644
index 00000000..28c0f8ff
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/project/harness/Xpp3DomPointerFactory.java
@@ -0,0 +1,61 @@
+package org.apache.maven.project.harness;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Locale;
+
+import org.apache.commons.jxpath.ri.QName;
+import org.apache.commons.jxpath.ri.model.NodePointer;
+import org.apache.commons.jxpath.ri.model.NodePointerFactory;
+import org.codehaus.plexus.util.xml.Xpp3Dom;
+
+/**
+ * A node pointer factory for JXPath to support <code>Xpp3Dom</code>.
+ *
+ * @author Benjamin Bentmann
+ */
+public class Xpp3DomPointerFactory
+ implements NodePointerFactory
+{
+
+ public int getOrder()
+ {
+ return 200;
+ }
+
+ public NodePointer createNodePointer( QName name, Object object, Locale locale )
+ {
+ if ( object instanceof Xpp3Dom )
+ {
+ return new Xpp3DomNodePointer( (Xpp3Dom) object );
+ }
+ return null;
+ }
+
+ public NodePointer createNodePointer( NodePointer parent, QName name, Object object )
+ {
+ if ( object instanceof Xpp3Dom )
+ {
+ return new Xpp3DomNodePointer( parent, (Xpp3Dom) object );
+ }
+ return null;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/repository/LegacyRepositoryLayout.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/repository/LegacyRepositoryLayout.java
new file mode 100644
index 00000000..77a6baef
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/repository/LegacyRepositoryLayout.java
@@ -0,0 +1,89 @@
+package org.apache.maven.repository;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.handler.ArtifactHandler;
+import org.apache.maven.artifact.metadata.ArtifactMetadata;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout;
+import org.codehaus.plexus.component.annotations.Component;
+
+/**
+ * @author jdcasey
+ */
+@Component(role=ArtifactRepositoryLayout.class, hint="legacy")
+public class LegacyRepositoryLayout
+ implements ArtifactRepositoryLayout
+{
+ private static final String PATH_SEPARATOR = "/";
+
+ public String getId()
+ {
+ return "legacy";
+ }
+
+ public String pathOf( Artifact artifact )
+ {
+ ArtifactHandler artifactHandler = artifact.getArtifactHandler();
+
+ StringBuilder path = new StringBuilder( 128 );
+
+ path.append( artifact.getGroupId() ).append( '/' );
+ path.append( artifactHandler.getDirectory() ).append( '/' );
+ path.append( artifact.getArtifactId() ).append( '-' ).append( artifact.getVersion() );
+
+ if ( artifact.hasClassifier() )
+ {
+ path.append( '-' ).append( artifact.getClassifier() );
+ }
+
+ if ( artifactHandler.getExtension() != null && artifactHandler.getExtension().length() > 0 )
+ {
+ path.append( '.' ).append( artifactHandler.getExtension() );
+ }
+
+ return path.toString();
+ }
+
+ public String pathOfLocalRepositoryMetadata( ArtifactMetadata metadata,
+ ArtifactRepository repository )
+ {
+ return pathOfRepositoryMetadata( metadata, metadata.getLocalFilename( repository ) );
+ }
+
+ private String pathOfRepositoryMetadata( ArtifactMetadata metadata,
+ String filename )
+ {
+ StringBuilder path = new StringBuilder( 128 );
+
+ path.append( metadata.getGroupId() ).append( PATH_SEPARATOR ).append( "poms" ).append( PATH_SEPARATOR );
+
+ path.append( filename );
+
+ return path.toString();
+ }
+
+ public String pathOfRemoteRepositoryMetadata( ArtifactMetadata metadata )
+ {
+ return pathOfRepositoryMetadata( metadata, metadata.getRemoteFilename() );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/repository/TestArtifactHandler.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/repository/TestArtifactHandler.java
new file mode 100644
index 00000000..db1fecb5
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/repository/TestArtifactHandler.java
@@ -0,0 +1,83 @@
+package org.apache.maven.repository;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.artifact.handler.ArtifactHandler;
+
+/**
+ * Assists unit testing.
+ *
+ * @author Benjamin Bentmann
+ */
+class TestArtifactHandler
+ implements ArtifactHandler
+{
+
+ private String type;
+
+ private String extension;
+
+ public TestArtifactHandler( String type )
+ {
+ this( type, type );
+ }
+
+ public TestArtifactHandler( String type, String extension )
+ {
+ this.type = type;
+ this.extension = extension;
+ }
+
+ public String getClassifier()
+ {
+ return null;
+ }
+
+ public String getDirectory()
+ {
+ return getPackaging() + "s";
+ }
+
+ public String getExtension()
+ {
+ return extension;
+ }
+
+ public String getLanguage()
+ {
+ return "java";
+ }
+
+ public String getPackaging()
+ {
+ return type;
+ }
+
+ public boolean isAddedToClasspath()
+ {
+ return true;
+ }
+
+ public boolean isIncludesDependencies()
+ {
+ return false;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/repository/TestRepositoryConnector.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/repository/TestRepositoryConnector.java
new file mode 100644
index 00000000..91ace4f1
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/repository/TestRepositoryConnector.java
@@ -0,0 +1,123 @@
+package org.apache.maven.repository;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Collection;
+
+import org.codehaus.plexus.util.FileUtils;
+import org.eclipse.aether.artifact.Artifact;
+import org.eclipse.aether.repository.RemoteRepository;
+import org.eclipse.aether.spi.connector.ArtifactDownload;
+import org.eclipse.aether.spi.connector.ArtifactUpload;
+import org.eclipse.aether.spi.connector.MetadataDownload;
+import org.eclipse.aether.spi.connector.MetadataUpload;
+import org.eclipse.aether.spi.connector.RepositoryConnector;
+import org.eclipse.aether.transfer.ArtifactNotFoundException;
+import org.eclipse.aether.transfer.ArtifactTransferException;
+
+/**
+ * @author Benjamin Bentmann
+ */
+public class TestRepositoryConnector
+ implements RepositoryConnector
+{
+
+ private RemoteRepository repository;
+
+ private File basedir;
+
+ public TestRepositoryConnector( RemoteRepository repository )
+ {
+ this.repository = repository;
+ try
+ {
+ basedir = FileUtils.toFile( new URL( repository.getUrl() ) );
+ }
+ catch ( MalformedURLException e )
+ {
+ throw new IllegalStateException( e );
+ }
+ }
+
+ public void close()
+ {
+ }
+
+ public void get( Collection<? extends ArtifactDownload> artifactDownloads,
+ Collection<? extends MetadataDownload> metadataDownloads )
+ {
+ if ( artifactDownloads != null )
+ {
+ for ( ArtifactDownload download : artifactDownloads )
+ {
+ File remoteFile = new File( basedir, path( download.getArtifact() ) );
+ try
+ {
+ FileUtils.copyFile( remoteFile, download.getFile() );
+ }
+ catch ( IOException e )
+ {
+ if ( !remoteFile.exists() )
+ {
+ download.setException( new ArtifactNotFoundException( download.getArtifact(), repository ) );
+ }
+ else
+ {
+ download.setException( new ArtifactTransferException( download.getArtifact(), repository, e ) );
+ }
+ }
+ }
+ }
+ }
+
+ private String path( Artifact artifact )
+ {
+ StringBuilder path = new StringBuilder( 128 );
+
+ path.append( artifact.getGroupId().replace( '.', '/' ) ).append( '/' );
+
+ path.append( artifact.getArtifactId() ).append( '/' );
+
+ path.append( artifact.getBaseVersion() ).append( '/' );
+
+ path.append( artifact.getArtifactId() ).append( '-' ).append( artifact.getVersion() );
+
+ if ( artifact.getClassifier().length() > 0 )
+ {
+ path.append( '-' ).append( artifact.getClassifier() );
+ }
+
+ path.append( '.' ).append( artifact.getExtension() );
+
+ return path.toString();
+ }
+
+ public void put( Collection<? extends ArtifactUpload> artifactUploads,
+ Collection<? extends MetadataUpload> metadataUploads )
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/repository/TestRepositoryConnectorFactory.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/repository/TestRepositoryConnectorFactory.java
new file mode 100644
index 00000000..17fd43f9
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/repository/TestRepositoryConnectorFactory.java
@@ -0,0 +1,48 @@
+package org.apache.maven.repository;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.codehaus.plexus.component.annotations.Component;
+import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.repository.RemoteRepository;
+import org.eclipse.aether.spi.connector.RepositoryConnector;
+import org.eclipse.aether.spi.connector.RepositoryConnectorFactory;
+import org.eclipse.aether.transfer.NoRepositoryConnectorException;
+
+/**
+ * @author Benjamin Bentmann
+ */
+@Component( role = RepositoryConnectorFactory.class, hint = "test" )
+public class TestRepositoryConnectorFactory
+ implements RepositoryConnectorFactory
+{
+
+ public RepositoryConnector newInstance( RepositorySystemSession session, RemoteRepository repository )
+ throws NoRepositoryConnectorException
+ {
+ return new TestRepositoryConnector( repository );
+ }
+
+ public float getPriority()
+ {
+ return 0;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/repository/TestRepositorySystem.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/repository/TestRepositorySystem.java
new file mode 100644
index 00000000..c4afc7a9
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/repository/TestRepositorySystem.java
@@ -0,0 +1,329 @@
+package org.apache.maven.repository;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.DefaultArtifact;
+import org.apache.maven.artifact.InvalidRepositoryException;
+import org.apache.maven.artifact.factory.ArtifactFactory;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy;
+import org.apache.maven.artifact.repository.MavenArtifactRepository;
+import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout;
+import org.apache.maven.artifact.repository.layout.DefaultRepositoryLayout;
+import org.apache.maven.artifact.resolver.ArtifactResolutionRequest;
+import org.apache.maven.artifact.resolver.ArtifactResolutionResult;
+import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
+import org.apache.maven.artifact.versioning.VersionRange;
+import org.apache.maven.model.Dependency;
+import org.apache.maven.model.Model;
+import org.apache.maven.model.Plugin;
+import org.apache.maven.model.Repository;
+import org.apache.maven.model.io.ModelReader;
+import org.apache.maven.project.artifact.ArtifactWithDependencies;
+import org.apache.maven.settings.Mirror;
+import org.apache.maven.settings.Proxy;
+import org.apache.maven.settings.Server;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+import org.codehaus.plexus.util.FileUtils;
+import org.codehaus.plexus.util.StringUtils;
+import org.eclipse.aether.RepositorySystemSession;
+
+/**
+ * @author Benjamin Bentmann
+ */
+@Component( role = RepositorySystem.class )
+public class TestRepositorySystem
+ implements RepositorySystem
+{
+
+ @Requirement
+ private ModelReader modelReader;
+
+ @Requirement
+ private ArtifactFactory artifactFactory;
+
+ public ArtifactRepository buildArtifactRepository( Repository repository )
+ throws InvalidRepositoryException
+ {
+ return new MavenArtifactRepository( repository.getId(), repository.getUrl(), new DefaultRepositoryLayout(),
+ new ArtifactRepositoryPolicy(), new ArtifactRepositoryPolicy() );
+ }
+
+ public Artifact createArtifact( String groupId, String artifactId, String version, String packaging )
+ {
+ return createArtifact( groupId, artifactId, version, null, packaging );
+ }
+
+ public Artifact createArtifact( String groupId, String artifactId, String version, String scope, String type )
+ {
+ return new DefaultArtifact( groupId, artifactId, version, scope, type, null, new TestArtifactHandler( type ) );
+ }
+
+ public ArtifactRepository createArtifactRepository( String id, String url,
+ ArtifactRepositoryLayout repositoryLayout,
+ ArtifactRepositoryPolicy snapshots,
+ ArtifactRepositoryPolicy releases )
+ {
+ return new MavenArtifactRepository( id, url, repositoryLayout, snapshots, releases );
+ }
+
+ public Artifact createArtifactWithClassifier( String groupId, String artifactId, String version, String type,
+ String classifier )
+ {
+ return new DefaultArtifact( groupId, artifactId, version, null, type, classifier,
+ new TestArtifactHandler( type ) );
+ }
+
+ public ArtifactRepository createDefaultLocalRepository()
+ throws InvalidRepositoryException
+ {
+ return createLocalRepository( new File( System.getProperty( "basedir", "" ), "target/local-repo" ).getAbsoluteFile() );
+ }
+
+ public ArtifactRepository createDefaultRemoteRepository()
+ throws InvalidRepositoryException
+ {
+ return new MavenArtifactRepository( DEFAULT_REMOTE_REPO_ID, "file://"
+ + new File( System.getProperty( "basedir", "" ), "src/test/remote-repo" ).toURI().getPath(),
+ new DefaultRepositoryLayout(), new ArtifactRepositoryPolicy(),
+ new ArtifactRepositoryPolicy() );
+ }
+
+ public Artifact createDependencyArtifact( Dependency dependency )
+ {
+ Artifact artifact =
+ new DefaultArtifact( dependency.getGroupId(), dependency.getArtifactId(), dependency.getVersion(),
+ dependency.getScope(), dependency.getType(), dependency.getClassifier(),
+ new TestArtifactHandler( dependency.getType() ) );
+
+ if ( Artifact.SCOPE_SYSTEM.equals( dependency.getScope() ) )
+ {
+ artifact.setFile( new File( dependency.getSystemPath() ) );
+ artifact.setResolved( true );
+ }
+
+ return artifact;
+ }
+
+ public ArtifactRepository createLocalRepository( File localRepository )
+ throws InvalidRepositoryException
+ {
+ return new MavenArtifactRepository( DEFAULT_LOCAL_REPO_ID, "file://" + localRepository.toURI().getPath(),
+ new DefaultRepositoryLayout(), new ArtifactRepositoryPolicy(),
+ new ArtifactRepositoryPolicy() );
+ }
+
+ public Artifact createPluginArtifact( Plugin plugin )
+ {
+ VersionRange versionRange;
+ try
+ {
+ String version = plugin.getVersion();
+ if ( StringUtils.isEmpty( version ) )
+ {
+ version = "RELEASE";
+ }
+ versionRange = VersionRange.createFromVersionSpec( version );
+ }
+ catch ( InvalidVersionSpecificationException e )
+ {
+ return null;
+ }
+
+ return artifactFactory.createPluginArtifact( plugin.getGroupId(), plugin.getArtifactId(), versionRange );
+ }
+
+ public Artifact createProjectArtifact( String groupId, String artifactId, String version )
+ {
+ return createArtifact( groupId, artifactId, version, "pom" );
+ }
+
+ public List<ArtifactRepository> getEffectiveRepositories( List<ArtifactRepository> repositories )
+ {
+ return repositories;
+ }
+
+ public Mirror getMirror( ArtifactRepository repository, List<Mirror> mirrors )
+ {
+ return null;
+ }
+
+ public void injectAuthentication( List<ArtifactRepository> repositories, List<Server> servers )
+ {
+ }
+
+ public void injectMirror( List<ArtifactRepository> repositories, List<Mirror> mirrors )
+ {
+ }
+
+ public void injectProxy( List<ArtifactRepository> repositories, List<Proxy> proxies )
+ {
+ }
+
+ public void publish( ArtifactRepository repository, File source, String remotePath,
+ ArtifactTransferListener transferListener )
+ throws ArtifactTransferFailedException
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ public ArtifactResolutionResult resolve( ArtifactResolutionRequest request )
+ {
+ ArtifactResolutionResult result = new ArtifactResolutionResult();
+
+ if ( request.isResolveRoot() )
+ {
+ try
+ {
+ resolve( request.getArtifact(), request );
+ result.addArtifact( request.getArtifact() );
+ }
+ catch ( IOException e )
+ {
+ result.addMissingArtifact( request.getArtifact() );
+ }
+ }
+
+ if ( request.isResolveTransitively() )
+ {
+ Map<String, Artifact> artifacts = new LinkedHashMap<String, Artifact>();
+
+ if ( request.getArtifactDependencies() != null )
+ {
+ for ( Artifact artifact : request.getArtifactDependencies() )
+ {
+ artifacts.put( artifact.getDependencyConflictId(), artifact );
+ }
+ }
+
+ List<Dependency> dependencies = new ArrayList<Dependency>();
+ if ( request.getArtifact() instanceof ArtifactWithDependencies )
+ {
+ dependencies = ( (ArtifactWithDependencies) request.getArtifact() ).getDependencies();
+ }
+ else
+ {
+ Artifact pomArtifact =
+ createProjectArtifact( request.getArtifact().getGroupId(), request.getArtifact().getArtifactId(),
+ request.getArtifact().getVersion() );
+ File pomFile =
+ new File( request.getLocalRepository().getBasedir(),
+ request.getLocalRepository().pathOf( pomArtifact ) );
+
+ try
+ {
+ Model model = modelReader.read( pomFile, null );
+
+ dependencies = model.getDependencies();
+ }
+ catch ( IOException e )
+ {
+ e.printStackTrace();
+ }
+ }
+
+ for ( Dependency dependency : dependencies )
+ {
+ Artifact artifact = createDependencyArtifact( dependency );
+ if ( !artifacts.containsKey( artifact.getDependencyConflictId() ) )
+ {
+ artifacts.put( artifact.getDependencyConflictId(), artifact );
+ }
+ }
+
+ for ( Artifact artifact : artifacts.values() )
+ {
+ try
+ {
+ resolve( artifact, request );
+ result.addArtifact( artifact );
+ }
+ catch ( IOException e )
+ {
+ result.addMissingArtifact( artifact );
+ }
+ }
+ }
+
+ return result;
+ }
+
+ private void resolve( Artifact artifact, ArtifactResolutionRequest request )
+ throws IOException
+ {
+ if ( Artifact.SCOPE_SYSTEM.equals( artifact.getScope() ) )
+ {
+ return;
+ }
+
+ ArtifactRepository localRepo = request.getLocalRepository();
+
+ File localFile = new File( localRepo.getBasedir(), localRepo.pathOf( artifact ) );
+
+ artifact.setFile( localFile );
+
+ if ( !localFile.exists() )
+ {
+ if ( request.getRemoteRepositories().isEmpty() )
+ {
+ throw new IOException( localFile + " does not exist and no remote repositories are configured" );
+ }
+
+ ArtifactRepository remoteRepo = request.getRemoteRepositories().get( 0 );
+
+ File remoteFile = new File( remoteRepo.getBasedir(), remoteRepo.pathOf( artifact ) );
+
+ FileUtils.copyFile( remoteFile, localFile );
+ }
+
+ artifact.setResolved( true );
+ }
+
+ public void retrieve( ArtifactRepository repository, File destination, String remotePath,
+ ArtifactTransferListener transferListener )
+ throws ArtifactTransferFailedException, ArtifactDoesNotExistException
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void injectMirror( RepositorySystemSession session, List<ArtifactRepository> repositories )
+ {
+ }
+
+ public void injectProxy( RepositorySystemSession session, List<ArtifactRepository> repositories )
+ {
+ }
+
+ public void injectAuthentication( RepositorySystemSession session, List<ArtifactRepository> repositories )
+ {
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/rtinfo/internal/DefaultRuntimeInformationTest.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/rtinfo/internal/DefaultRuntimeInformationTest.java
new file mode 100644
index 00000000..71be9284
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/rtinfo/internal/DefaultRuntimeInformationTest.java
@@ -0,0 +1,81 @@
+package org.apache.maven.rtinfo.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.rtinfo.RuntimeInformation;
+import org.codehaus.plexus.PlexusTestCase;
+
+public class DefaultRuntimeInformationTest
+ extends PlexusTestCase
+{
+
+ public void testGetMavenVersion()
+ throws Exception
+ {
+ RuntimeInformation rtInfo = lookup( RuntimeInformation.class );
+
+ String mavenVersion = rtInfo.getMavenVersion();
+ assertNotNull( mavenVersion );
+ assertTrue( mavenVersion.length() > 0 );
+ }
+
+ public void testIsMavenVersion()
+ throws Exception
+ {
+ RuntimeInformation rtInfo = lookup( RuntimeInformation.class );
+
+ assertTrue( rtInfo.isMavenVersion( "2.0" ) );
+ assertFalse( rtInfo.isMavenVersion( "9.9" ) );
+
+ assertTrue( rtInfo.isMavenVersion( "[2.0.11,2.1.0),[3.0,)" ) );
+ assertFalse( rtInfo.isMavenVersion( "[9.0,)" ) );
+
+ try
+ {
+ rtInfo.isMavenVersion( "[3.0," );
+ fail( "Bad version range wasn't rejected" );
+ }
+ catch ( IllegalArgumentException e )
+ {
+ assertTrue( true );
+ }
+
+ try
+ {
+ rtInfo.isMavenVersion( "" );
+ fail( "Bad version range wasn't rejected" );
+ }
+ catch ( IllegalArgumentException e )
+ {
+ assertTrue( true );
+ }
+
+ try
+ {
+ rtInfo.isMavenVersion( null );
+ fail( "Bad version range wasn't rejected" );
+ }
+ catch ( IllegalArgumentException e )
+ {
+ assertTrue( true );
+ }
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/settings/PomConstructionWithSettingsTest.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/settings/PomConstructionWithSettingsTest.java
new file mode 100644
index 00000000..5c166868
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/settings/PomConstructionWithSettingsTest.java
@@ -0,0 +1,159 @@
+package org.apache.maven.settings;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.io.Reader;
+
+import org.apache.maven.artifact.repository.layout.DefaultRepositoryLayout;
+import org.apache.maven.model.Profile;
+import org.apache.maven.project.DefaultProjectBuilder;
+import org.apache.maven.project.DefaultProjectBuildingRequest;
+import org.apache.maven.project.ProjectBuilder;
+import org.apache.maven.project.ProjectBuildingRequest;
+import org.apache.maven.project.harness.PomTestWrapper;
+import org.apache.maven.repository.RepositorySystem;
+import org.apache.maven.repository.internal.MavenRepositorySystemUtils;
+import org.apache.maven.settings.io.xpp3.SettingsXpp3Reader;
+import org.codehaus.plexus.ContainerConfiguration;
+import org.codehaus.plexus.PlexusConstants;
+import org.codehaus.plexus.PlexusTestCase;
+import org.codehaus.plexus.util.IOUtil;
+import org.codehaus.plexus.util.ReaderFactory;
+import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
+import org.eclipse.aether.DefaultRepositorySystemSession;
+import org.eclipse.aether.internal.impl.SimpleLocalRepositoryManagerFactory;
+import org.eclipse.aether.repository.LocalRepository;
+
+public class PomConstructionWithSettingsTest
+ extends PlexusTestCase
+{
+ private static final String BASE_DIR = "src/test";
+
+ private static final String BASE_POM_DIR = BASE_DIR + "/resources-settings";
+
+ private DefaultProjectBuilder projectBuilder;
+
+ private RepositorySystem repositorySystem;
+
+ private File testDirectory;
+
+ @Override
+ protected void customizeContainerConfiguration( ContainerConfiguration containerConfiguration )
+ {
+ super.customizeContainerConfiguration( containerConfiguration );
+ containerConfiguration.setAutoWiring( true );
+ containerConfiguration.setClassPathScanning( PlexusConstants.SCANNING_INDEX );
+ }
+
+ protected void setUp()
+ throws Exception
+ {
+ testDirectory = new File( getBasedir(), BASE_POM_DIR );
+ projectBuilder = (DefaultProjectBuilder) lookup( ProjectBuilder.class );
+ repositorySystem = lookup( RepositorySystem.class );
+ }
+
+ @Override
+ protected void tearDown()
+ throws Exception
+ {
+ projectBuilder = null;
+
+ super.tearDown();
+ }
+
+ public void testSettingsNoPom() throws Exception
+ {
+ PomTestWrapper pom = buildPom( "settings-no-pom" );
+ assertEquals( "local-profile-prop-value", pom.getValue( "properties/local-profile-prop" ) );
+ }
+
+ /**MNG-4107 */
+ public void testPomAndSettingsInterpolation() throws Exception
+ {
+ PomTestWrapper pom = buildPom( "test-pom-and-settings-interpolation" );
+ assertEquals( "applied", pom.getValue( "properties/settingsProfile" ) );
+ assertEquals( "applied", pom.getValue( "properties/pomProfile" ) );
+ assertEquals( "settings", pom.getValue( "properties/pomVsSettings" ) );
+ assertEquals( "settings", pom.getValue( "properties/pomVsSettingsInterpolated" ) );
+ }
+
+ /**MNG-4107 */
+ public void testRepositories() throws Exception
+ {
+ PomTestWrapper pom = buildPom( "repositories" );
+ assertEquals( "maven-core-it-0", pom.getValue( "repositories[1]/id" ) );
+ }
+
+ private PomTestWrapper buildPom( String pomPath )
+ throws Exception
+ {
+ File pomFile = new File( testDirectory + File.separator + pomPath, "pom.xml" );
+ File settingsFile = new File( testDirectory + File.separator + pomPath, "settings.xml" );
+ Settings settings = readSettingsFile( settingsFile );
+
+ ProjectBuildingRequest config = new DefaultProjectBuildingRequest();
+
+ for ( org.apache.maven.settings.Profile rawProfile : settings.getProfiles() )
+ {
+ Profile profile = SettingsUtils.convertFromSettingsProfile( rawProfile );
+ config.addProfile( profile );
+ }
+
+ String localRepoUrl =
+ System.getProperty( "maven.repo.local", System.getProperty( "user.home" ) + "/.m2/repository" );
+ localRepoUrl = "file://" + localRepoUrl;
+ config.setLocalRepository( repositorySystem.createArtifactRepository( "local", localRepoUrl,
+ new DefaultRepositoryLayout(), null, null ) );
+ config.setActiveProfileIds( settings.getActiveProfiles() );
+
+ DefaultRepositorySystemSession repoSession = MavenRepositorySystemUtils.newSession();
+ LocalRepository localRepo = new LocalRepository( config.getLocalRepository().getBasedir() );
+ repoSession.setLocalRepositoryManager( new SimpleLocalRepositoryManagerFactory().newInstance( repoSession, localRepo ) );
+ config.setRepositorySession( repoSession );
+
+ return new PomTestWrapper( pomFile, projectBuilder.build( pomFile, config ).getProject() );
+ }
+
+ private static Settings readSettingsFile( File settingsFile )
+ throws IOException, XmlPullParserException
+ {
+ Settings settings = null;
+
+ Reader reader = null;
+
+ try
+ {
+ reader = ReaderFactory.newXmlReader( settingsFile );
+
+ SettingsXpp3Reader modelReader = new SettingsXpp3Reader();
+
+ settings = modelReader.read( reader );
+ }
+ finally
+ {
+ IOUtil.close( reader );
+ }
+
+ return settings;
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/settings/SettingsUtilsTest.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/settings/SettingsUtilsTest.java
new file mode 100644
index 00000000..f2231b3f
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/settings/SettingsUtilsTest.java
@@ -0,0 +1,126 @@
+package org.apache.maven.settings;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import junit.framework.TestCase;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+import java.util.Random;
+
+public class SettingsUtilsTest
+ extends TestCase
+{
+
+ public void testShouldAppendRecessivePluginGroupIds()
+ {
+ Settings dominant = new Settings();
+ dominant.addPluginGroup( "org.apache.maven.plugins" );
+ dominant.addPluginGroup( "org.codehaus.modello" );
+
+ Settings recessive = new Settings();
+ recessive.addPluginGroup( "org.codehaus.plexus" );
+
+ SettingsUtils.merge( dominant, recessive, Settings.GLOBAL_LEVEL );
+
+ List<String> pluginGroups = dominant.getPluginGroups();
+
+ assertNotNull( pluginGroups );
+ assertEquals( 3, pluginGroups.size() );
+ assertEquals( "org.apache.maven.plugins", pluginGroups.get( 0 ) );
+ assertEquals( "org.codehaus.modello", pluginGroups.get( 1 ) );
+ assertEquals( "org.codehaus.plexus", pluginGroups.get( 2 ) );
+ }
+
+ public void testRoundTripProfiles()
+ {
+ Random entropy = new Random();
+ Profile p = new Profile();
+ p.setId( "id" + Long.toHexString( entropy.nextLong() ) );
+ Activation a = new Activation();
+ a.setActiveByDefault( entropy.nextBoolean() );
+ a.setJdk( "jdk" + Long.toHexString( entropy.nextLong() ) );
+ ActivationFile af = new ActivationFile();
+ af.setExists( "exists" + Long.toHexString( entropy.nextLong() ) );
+ af.setMissing( "missing" + Long.toHexString( entropy.nextLong() ) );
+ a.setFile( af );
+ ActivationProperty ap = new ActivationProperty();
+ ap.setName( "name" + Long.toHexString( entropy.nextLong() ) );
+ ap.setValue( "value" + Long.toHexString( entropy.nextLong() ) );
+ a.setProperty( ap );
+ ActivationOS ao = new ActivationOS();
+ ao.setArch( "arch" + Long.toHexString( entropy.nextLong() ) );
+ ao.setFamily( "family" + Long.toHexString( entropy.nextLong() ) );
+ ao.setName( "name" + Long.toHexString( entropy.nextLong() ) );
+ ao.setVersion( "version" + Long.toHexString( entropy.nextLong() ) );
+ a.setOs( ao );
+ p.setActivation( a );
+ Properties props = new Properties();
+ int count = entropy.nextInt( 10 );
+ for ( int i = 0; i < count; i++ )
+ {
+ props.setProperty( "name" + Long.toHexString( entropy.nextLong() ),
+ "value" + Long.toHexString( entropy.nextLong() ) );
+ }
+ p.setProperties( props );
+ count = entropy.nextInt( 3 );
+ List<Repository> repos = new ArrayList<Repository>();
+ for ( int i = 0; i < count; i++ )
+ {
+ Repository r = new Repository();
+ r.setId( "id" + Long.toHexString( entropy.nextLong() ) );
+ r.setName( "name" + Long.toHexString( entropy.nextLong() ) );
+ r.setUrl( "url" + Long.toHexString( entropy.nextLong() ) );
+ repos.add( r );
+ }
+ p.setRepositories( repos );
+ count = entropy.nextInt( 3 );
+ repos = new ArrayList<Repository>();
+ for ( int i = 0; i < count; i++ )
+ {
+ Repository r = new Repository();
+ r.setId( "id" + Long.toHexString( entropy.nextLong() ) );
+ r.setName( "name" + Long.toHexString( entropy.nextLong() ) );
+ r.setUrl( "url" + Long.toHexString( entropy.nextLong() ) );
+ repos.add( r );
+ }
+ p.setPluginRepositories( repos );
+
+ Profile clone = SettingsUtils.convertToSettingsProfile( SettingsUtils.convertFromSettingsProfile( p ) );
+
+ assertEquals( p.getId(), clone.getId() );
+ assertEquals( p.getActivation().getJdk(), clone.getActivation().getJdk() );
+ assertEquals( p.getActivation().getFile().getExists(), clone.getActivation().getFile().getExists() );
+ assertEquals( p.getActivation().getFile().getMissing(), clone.getActivation().getFile().getMissing() );
+ assertEquals( p.getActivation().getProperty().getName(), clone.getActivation().getProperty().getName() );
+ assertEquals( p.getActivation().getProperty().getValue(), clone.getActivation().getProperty().getValue() );
+ assertEquals( p.getActivation().getOs().getArch(), clone.getActivation().getOs().getArch() );
+ assertEquals( p.getActivation().getOs().getFamily(), clone.getActivation().getOs().getFamily() );
+ assertEquals( p.getActivation().getOs().getName(), clone.getActivation().getOs().getName() );
+ assertEquals( p.getActivation().getOs().getVersion(), clone.getActivation().getOs().getVersion() );
+ assertEquals( p.getProperties(), clone.getProperties() );
+ assertEquals( p.getRepositories().size(), clone.getRepositories().size() );
+ // TODO deep compare the lists
+ assertEquals( p.getPluginRepositories().size(), clone.getPluginRepositories().size() );
+ // TODO deep compare the lists
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/toolchain/DefaultToolchainManagerPrivateTest.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/toolchain/DefaultToolchainManagerPrivateTest.java
new file mode 100644
index 00000000..28a13bb2
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/toolchain/DefaultToolchainManagerPrivateTest.java
@@ -0,0 +1,166 @@
+package org.apache.maven.toolchain;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.maven.execution.DefaultMavenExecutionRequest;
+import org.apache.maven.execution.MavenExecutionRequest;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.toolchain.model.ToolchainModel;
+import org.codehaus.plexus.logging.Logger;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+public class DefaultToolchainManagerPrivateTest
+{
+ // Mocks to inject into toolchainManager
+ @Mock
+ private Logger logger;
+
+ @InjectMocks
+ private DefaultToolchainManagerPrivate toolchainManager;
+
+ @Mock
+ private ToolchainFactory toolchainFactory_basicType;
+
+ @Mock
+ private ToolchainFactory toolchainFactory_rareType;
+
+ @Before
+ public void setUp()
+ {
+ toolchainManager = new DefaultToolchainManagerPrivate();
+
+ MockitoAnnotations.initMocks( this );
+
+ toolchainManager.factories = new HashMap<String, ToolchainFactory>();
+ toolchainManager.factories.put( "basic", toolchainFactory_basicType );
+ toolchainManager.factories.put( "rare", toolchainFactory_rareType );
+ }
+
+ @Test
+ public void testToolchainsForAvailableType()
+ throws Exception
+ {
+ // prepare
+ MavenSession session = mock( MavenSession.class );
+ MavenExecutionRequest req = new DefaultMavenExecutionRequest();
+ when( session.getRequest() ).thenReturn( req );
+
+ ToolchainPrivate basicToolchain = mock( ToolchainPrivate.class );
+ when( toolchainFactory_basicType.createDefaultToolchain() ).thenReturn( basicToolchain );
+ ToolchainPrivate rareToolchain = mock( ToolchainPrivate.class );
+ when( toolchainFactory_rareType.createDefaultToolchain() ).thenReturn( rareToolchain );
+
+ // execute
+ ToolchainPrivate[] toolchains = toolchainManager.getToolchainsForType( "basic", session );
+
+ // verify
+ verify( logger, never() ).error( anyString() );
+ assertEquals( 1, toolchains.length );
+ }
+
+ @Test
+ public void testToolchainsForUnknownType()
+ throws Exception
+ {
+ // prepare
+ MavenSession session = mock( MavenSession.class );
+ MavenExecutionRequest req = new DefaultMavenExecutionRequest();
+ when( session.getRequest() ).thenReturn( req );
+
+ ToolchainPrivate basicToolchain = mock( ToolchainPrivate.class );
+ when( toolchainFactory_basicType.createDefaultToolchain() ).thenReturn( basicToolchain );
+ ToolchainPrivate rareToolchain = mock( ToolchainPrivate.class );
+ when( toolchainFactory_rareType.createDefaultToolchain() ).thenReturn( rareToolchain );
+
+ // execute
+ ToolchainPrivate[] toolchains = toolchainManager.getToolchainsForType( "unknown", session );
+
+ // verify
+ verify( logger ).error( "Missing toolchain factory for type: unknown. Possibly caused by misconfigured project." );
+ assertEquals( 0, toolchains.length );
+ }
+
+ @Test
+ public void testToolchainsForConfiguredType()
+ throws Exception
+ {
+ // prepare
+ MavenSession session = mock( MavenSession.class );
+ MavenExecutionRequest req = new DefaultMavenExecutionRequest();
+ when( session.getRequest() ).thenReturn( req );
+ Map<String, List<ToolchainModel>> groupedToolchains = new HashMap<String, List<ToolchainModel>>();
+ req.setToolchains( groupedToolchains );
+
+ List<ToolchainModel> basicToolchains = new ArrayList<ToolchainModel>();
+ ToolchainModel basicToolchainModel = new ToolchainModel();
+ basicToolchainModel.setType( "basic" );
+ basicToolchains.add( basicToolchainModel );
+ basicToolchains.add( basicToolchainModel );
+ groupedToolchains.put( "basic", basicToolchains );
+
+ List<ToolchainModel> rareToolchains = new ArrayList<ToolchainModel>();
+ ToolchainModel rareToolchainModel = new ToolchainModel();
+ rareToolchainModel.setType( "rare" );
+ rareToolchains.add( rareToolchainModel );
+ groupedToolchains.put( "rare", rareToolchains );
+
+ // execute
+ ToolchainPrivate[] toolchains = toolchainManager.getToolchainsForType( "basic", session );
+
+ // verify
+ verify( logger, never() ).error( anyString() );
+ assertEquals( 2, toolchains.length );
+ }
+
+ @SuppressWarnings( "unchecked" )
+ @Test( expected = MisconfiguredToolchainException.class )
+ public void testMisconfiguredToolchain()
+ throws Exception
+ {
+ // prepare
+ MavenSession session = mock( MavenSession.class );
+ MavenExecutionRequest req = new DefaultMavenExecutionRequest();
+ when( session.getRequest() ).thenReturn( req );
+ when(toolchainFactory_basicType.createDefaultToolchain()).thenThrow( MisconfiguredToolchainException.class );
+
+ // execute
+ toolchainManager.getToolchainsForType( "basic", session );
+
+ // verify
+ fail( "Should exit with a MisconfiguredToolchainException" );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/toolchain/DefaultToolchainManagerTest.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/toolchain/DefaultToolchainManagerTest.java
new file mode 100644
index 00000000..d464502f
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/toolchain/DefaultToolchainManagerTest.java
@@ -0,0 +1,153 @@
+package org.apache.maven.toolchain;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Matchers.anyMap;
+import static org.mockito.Matchers.isA;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.maven.execution.DefaultMavenExecutionRequest;
+import org.apache.maven.execution.MavenExecutionRequest;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.toolchain.model.ToolchainModel;
+import org.codehaus.plexus.logging.Logger;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+public class DefaultToolchainManagerTest
+{
+ // Mocks to inject into toolchainManager
+ @Mock
+ private Logger logger;
+
+ @InjectMocks
+ private DefaultToolchainManager toolchainManager;
+
+ @Mock
+ private ToolchainFactory toolchainFactory_basicType;
+
+ @Mock
+ private ToolchainFactory toolchainFactory_rareType;
+
+ @Before
+ public void onSetup() throws Exception
+ {
+ toolchainManager = new DefaultToolchainManager();
+
+ MockitoAnnotations.initMocks( this );
+
+ toolchainManager.factories = new HashMap<String, ToolchainFactory>();
+ toolchainManager.factories.put( "basic", toolchainFactory_basicType );
+ toolchainManager.factories.put( "rare", toolchainFactory_rareType );
+ }
+
+ @Test
+ public void testNoModels()
+ {
+ MavenSession session = mock( MavenSession.class );
+ MavenExecutionRequest executionRequest = new DefaultMavenExecutionRequest();
+ when( session.getRequest() ).thenReturn( executionRequest );
+
+ List<Toolchain> toolchains = toolchainManager.getToolchains( session, "unknown", null );
+
+ assertEquals( 0, toolchains.size() );
+ }
+
+ @Test
+ public void testModelNoFactory()
+ {
+ MavenSession session = mock( MavenSession.class );
+ MavenExecutionRequest executionRequest = new DefaultMavenExecutionRequest();
+ Map<String, List<ToolchainModel>> toolchainModels = new HashMap<String, List<ToolchainModel>>();
+ toolchainModels.put( "unknown", Collections.singletonList( new ToolchainModel() ) );
+ executionRequest.setToolchains( toolchainModels );
+ when( session.getRequest() ).thenReturn( executionRequest );
+
+ List<Toolchain> toolchains = toolchainManager.getToolchains( session, "unknown", null );
+
+ assertEquals( 0, toolchains.size() );
+ verify( logger ).error( "Missing toolchain factory for type: unknown. Possibly caused by misconfigured project." );
+ }
+
+ @Test
+ public void testModelAndFactory()
+ {
+ MavenSession session = mock( MavenSession.class );
+ MavenExecutionRequest executionRequest = new DefaultMavenExecutionRequest();
+ Map<String, List<ToolchainModel>> toolchainModels = new HashMap<String, List<ToolchainModel>>();
+ toolchainModels.put( "basic", Arrays.asList( new ToolchainModel(), new ToolchainModel() ) );
+ toolchainModels.put( "rare", Collections.singletonList( new ToolchainModel() ) );
+ executionRequest.setToolchains( toolchainModels );
+ when( session.getRequest() ).thenReturn( executionRequest );
+
+ List<Toolchain> toolchains = toolchainManager.getToolchains( session, "rare", null );
+
+ assertEquals( 1, toolchains.size() );
+ }
+
+ @Test
+ public void testModelsAndFactory()
+ {
+ MavenSession session = mock( MavenSession.class );
+ MavenExecutionRequest executionRequest = new DefaultMavenExecutionRequest();
+ Map<String, List<ToolchainModel>> toolchainModels = new HashMap<String, List<ToolchainModel>>();
+ toolchainModels.put( "basic", Arrays.asList( new ToolchainModel(), new ToolchainModel() ) );
+ toolchainModels.put( "rare", Collections.singletonList( new ToolchainModel() ) );
+ executionRequest.setToolchains( toolchainModels );
+ when( session.getRequest() ).thenReturn( executionRequest );
+
+ List<Toolchain> toolchains = toolchainManager.getToolchains( session, "basic", null );
+
+ assertEquals( 2, toolchains.size() );
+ }
+
+ @Test
+ public void testRequirements()
+ throws Exception
+ {
+ MavenSession session = mock( MavenSession.class );
+ MavenExecutionRequest executionRequest = new DefaultMavenExecutionRequest();
+ Map<String, List<ToolchainModel>> toolchainModels = new HashMap<String, List<ToolchainModel>>();
+ toolchainModels.put( "basic", Arrays.asList( new ToolchainModel(), new ToolchainModel() ) );
+ toolchainModels.put( "rare", Collections.singletonList( new ToolchainModel() ) );
+ executionRequest.setToolchains( toolchainModels );
+ when( session.getRequest() ).thenReturn( executionRequest );
+ ToolchainPrivate basicPrivate = mock( ToolchainPrivate.class );
+ when( basicPrivate.matchesRequirements( anyMap() ) ).thenReturn( false ).thenReturn( true );
+ when( toolchainFactory_basicType.createToolchain( isA( ToolchainModel.class ) ) ).thenReturn( basicPrivate );
+
+ List<Toolchain> toolchains =
+ toolchainManager.getToolchains( session, "basic", Collections.singletonMap( "key", "value" ) );
+
+ assertEquals( 1, toolchains.size() );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/toolchain/DefaultToolchainTest.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/toolchain/DefaultToolchainTest.java
new file mode 100644
index 00000000..3bba8177
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/toolchain/DefaultToolchainTest.java
@@ -0,0 +1,158 @@
+package org.apache.maven.toolchain;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.verify;
+
+import java.io.InputStream;
+import java.util.Collections;
+
+import org.apache.maven.toolchain.java.DefaultJavaToolChain;
+import org.apache.maven.toolchain.model.PersistedToolchains;
+import org.apache.maven.toolchain.model.ToolchainModel;
+import org.apache.maven.toolchain.model.io.xpp3.MavenToolchainsXpp3Reader;
+import org.codehaus.plexus.logging.Logger;
+import org.codehaus.plexus.util.IOUtil;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+public class DefaultToolchainTest
+{
+ @Mock
+ private Logger logger;
+
+ private MavenToolchainsXpp3Reader reader = new MavenToolchainsXpp3Reader();
+
+ @Before
+ public void setUp() throws Exception
+ {
+ MockitoAnnotations.initMocks( this );
+ }
+
+ private DefaultToolchain newDefaultToolchain( ToolchainModel model )
+ {
+ return new DefaultToolchain( model, logger )
+ {
+ @Override
+ public String findTool( String toolName )
+ {
+ return null;
+ }
+ };
+ }
+
+ private DefaultToolchain newDefaultToolchain( ToolchainModel model, String type )
+ {
+ return new DefaultToolchain( model, type, logger )
+ {
+ @Override
+ public String findTool( String toolName )
+ {
+ return null;
+ }
+ };
+ }
+
+ @Test
+ public void testGetModel()
+ {
+ ToolchainModel model = new ToolchainModel();
+ DefaultToolchain toolchain = newDefaultToolchain( model );
+ assertEquals( model, toolchain.getModel() );
+ }
+
+ @Test
+ public void testGetType()
+ {
+ ToolchainModel model = new ToolchainModel();
+ DefaultToolchain toolchain = newDefaultToolchain( model, "TYPE" );
+ assertEquals( "TYPE", toolchain.getType() );
+
+ model.setType( "MODEL_TYPE" );
+ toolchain = newDefaultToolchain( model );
+ assertEquals( "MODEL_TYPE", toolchain.getType() );
+ }
+
+ @Test
+ public void testGetLogger()
+ {
+ ToolchainModel model = new ToolchainModel();
+ DefaultToolchain toolchain = newDefaultToolchain( model );
+ assertEquals( logger, toolchain.getLog() );
+ }
+
+ @Test
+ public void testMissingRequirementProperty()
+ {
+ ToolchainModel model = new ToolchainModel();
+ model.setType( "TYPE" );
+ DefaultToolchain toolchain = newDefaultToolchain( model );
+
+ assertFalse( toolchain.matchesRequirements( Collections.singletonMap( "name", "John Doe" ) ) );
+ verify( logger ).debug( "Toolchain type:TYPE{} is missing required property: name" );
+ }
+
+
+ @Test
+ public void testNonMatchingRequirementProperty()
+ {
+ ToolchainModel model = new ToolchainModel();
+ model.setType( "TYPE" );
+ DefaultToolchain toolchain = newDefaultToolchain( model );
+ toolchain.addProvideToken( "name", RequirementMatcherFactory.createExactMatcher( "Jane Doe" ) );
+
+ assertFalse( toolchain.matchesRequirements( Collections.singletonMap( "name", "John Doe" ) ) );
+ verify( logger ).debug( "Toolchain type:TYPE{name = Jane Doe} doesn't match required property: name" );
+ }
+
+
+ @Test
+ public void testEquals() throws Exception
+ {
+ InputStream jdksIS = null;
+ InputStream jdksExtraIS = null;
+ try
+ {
+ jdksIS = ToolchainModel.class.getResourceAsStream( "toolchains-jdks.xml" );
+ jdksExtraIS = ToolchainModel.class.getResourceAsStream( "toolchains-jdks-extra.xml" );
+
+ PersistedToolchains jdks = reader.read( jdksIS );
+ PersistedToolchains jdksExtra = reader.read( jdksExtraIS );
+
+ DefaultToolchain tc1 = new DefaultJavaToolChain( jdks.getToolchains().get( 0 ), null );
+ DefaultToolchain tc2 = new DefaultJavaToolChain( jdksExtra.getToolchains().get( 0 ), null );
+
+ assertTrue( tc1.equals( tc1 ) );
+ assertFalse( tc1.equals( tc2 ) );
+ assertFalse( tc2.equals( tc1 ) );
+ assertTrue( tc2.equals( tc2 ) );
+ }
+ finally
+ {
+ IOUtil.close( jdksIS );
+ IOUtil.close( jdksExtraIS );
+ }
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/toolchain/RequirementMatcherFactoryTest.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/toolchain/RequirementMatcherFactoryTest.java
new file mode 100644
index 00000000..c102b11f
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/toolchain/RequirementMatcherFactoryTest.java
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.maven.toolchain;
+
+import junit.framework.TestCase;
+
+/**
+ *
+ * @author mkleint
+ */
+public class RequirementMatcherFactoryTest
+ extends TestCase
+{
+
+ public RequirementMatcherFactoryTest( String testName )
+ {
+ super( testName );
+ }
+
+ /**
+ * Test of createExactMatcher method, of class RequirementMatcherFactory.
+ */
+ public void testCreateExactMatcher()
+ {
+ RequirementMatcher matcher;
+ matcher = RequirementMatcherFactory.createExactMatcher( "foo" );
+ assertFalse( matcher.matches( "bar" ) );
+ assertFalse( matcher.matches( "foobar" ) );
+ assertFalse( matcher.matches( "foob" ) );
+ assertTrue( matcher.matches( "foo" ) );
+ }
+
+ /**
+ * Test of createVersionMatcher method, of class RequirementMatcherFactory.
+ */
+ public void testCreateVersionMatcher()
+ {
+ RequirementMatcher matcher;
+ matcher = RequirementMatcherFactory.createVersionMatcher( "1.5.2" );
+ assertFalse( matcher.matches( "1.5" ) );
+ assertTrue( matcher.matches( "1.5.2" ) );
+ assertFalse( matcher.matches( "[1.4,1.5)" ) );
+ assertFalse( matcher.matches( "[1.5,1.5.2)" ) );
+ assertFalse( matcher.matches( "(1.5.2,1.6)" ) );
+ assertTrue( matcher.matches( "(1.4,1.5.2]" ) );
+ assertTrue( matcher.matches( "(1.5,)" ) );
+ assertEquals( "1.5.2", matcher.toString() );
+
+ // Ensure it is not printed as 1.5.0
+ matcher = RequirementMatcherFactory.createVersionMatcher( "1.5" );
+ assertEquals( "1.5", matcher.toString() );
+
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/toolchain/building/DefaultToolchainsBuilderTest.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/toolchain/building/DefaultToolchainsBuilderTest.java
new file mode 100644
index 00000000..80fca094
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/toolchain/building/DefaultToolchainsBuilderTest.java
@@ -0,0 +1,185 @@
+package org.apache.maven.toolchain.building;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyMap;
+import static org.mockito.Mockito.when;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.maven.building.StringSource;
+import org.apache.maven.toolchain.io.ToolchainsParseException;
+import org.apache.maven.toolchain.io.ToolchainsReader;
+import org.apache.maven.toolchain.model.PersistedToolchains;
+import org.apache.maven.toolchain.model.ToolchainModel;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+public class DefaultToolchainsBuilderTest
+{
+ private static final String LS = System.getProperty( "line.separator" );
+
+ @Mock
+ private ToolchainsReader toolchainsReader;
+
+ @InjectMocks
+ private DefaultToolchainsBuilder toolchainBuilder = new DefaultToolchainsBuilder();
+
+ @Before
+ public void onSetup()
+ {
+ MockitoAnnotations.initMocks( this );
+ }
+
+ @Test
+ public void testBuildEmptyRequest()
+ throws Exception
+ {
+ ToolchainsBuildingRequest request = new DefaultToolchainsBuildingRequest();
+ ToolchainsBuildingResult result = toolchainBuilder.build( request );
+ assertNotNull( result.getEffectiveToolchains() );
+ assertNotNull( result.getProblems() );
+ assertEquals( 0, result.getProblems().size() );
+ }
+
+ @Test
+ public void testBuildRequestWithUserToolchains()
+ throws Exception
+ {
+ ToolchainsBuildingRequest request = new DefaultToolchainsBuildingRequest();
+ request.setUserToolchainsSource( new StringSource( "" ) );
+
+ PersistedToolchains userResult = new PersistedToolchains();
+ ToolchainModel toolchain = new ToolchainModel();
+ toolchain.setType( "TYPE" );
+ toolchain.addProvide( "key", "user_value" );
+ userResult.addToolchain( toolchain );
+ when( toolchainsReader.read( any( InputStream.class ), anyMap() ) ).thenReturn( userResult );
+
+ ToolchainsBuildingResult result = toolchainBuilder.build( request );
+ assertNotNull( result.getEffectiveToolchains() );
+ assertEquals( 1, result.getEffectiveToolchains().getToolchains().size() );
+ assertEquals( "TYPE", result.getEffectiveToolchains().getToolchains().get(0).getType() );
+ assertEquals( "user_value", result.getEffectiveToolchains().getToolchains().get(0).getProvides().getProperty( "key" ) );
+ assertNotNull( result.getProblems() );
+ assertEquals( 0, result.getProblems().size() );
+ }
+
+ @Test
+ public void testBuildRequestWithGlobalToolchains()
+ throws Exception
+ {
+ ToolchainsBuildingRequest request = new DefaultToolchainsBuildingRequest();
+ request.setGlobalToolchainsSource( new StringSource( "" ) );
+
+ PersistedToolchains globalResult = new PersistedToolchains();
+ ToolchainModel toolchain = new ToolchainModel();
+ toolchain.setType( "TYPE" );
+ toolchain.addProvide( "key", "global_value" );
+ globalResult.addToolchain( toolchain );
+ when( toolchainsReader.read( any( InputStream.class ), anyMap() ) ).thenReturn( globalResult );
+
+ ToolchainsBuildingResult result = toolchainBuilder.build( request );
+ assertNotNull( result.getEffectiveToolchains() );
+ assertEquals( 1, result.getEffectiveToolchains().getToolchains().size() );
+ assertEquals( "TYPE", result.getEffectiveToolchains().getToolchains().get(0).getType() );
+ assertEquals( "global_value", result.getEffectiveToolchains().getToolchains().get(0).getProvides().getProperty( "key" ) );
+ assertNotNull( result.getProblems() );
+ assertEquals( 0, result.getProblems().size() );
+ }
+
+ @Test
+ public void testBuildRequestWithBothToolchains()
+ throws Exception
+ {
+ ToolchainsBuildingRequest request = new DefaultToolchainsBuildingRequest();
+ request.setGlobalToolchainsSource( new StringSource( "" ) );
+ request.setUserToolchainsSource( new StringSource( "" ) );
+
+ PersistedToolchains userResult = new PersistedToolchains();
+ ToolchainModel userToolchain = new ToolchainModel();
+ userToolchain.setType( "TYPE" );
+ userToolchain.addProvide( "key", "user_value" );
+ userResult.addToolchain( userToolchain );
+
+ PersistedToolchains globalResult = new PersistedToolchains();
+ ToolchainModel globalToolchain = new ToolchainModel();
+ globalToolchain.setType( "TYPE" );
+ globalToolchain.addProvide( "key", "global_value" );
+ globalResult.addToolchain( globalToolchain );
+ when( toolchainsReader.read( any( InputStream.class ), anyMap() ) ).thenReturn( globalResult ).thenReturn( userResult );
+
+ ToolchainsBuildingResult result = toolchainBuilder.build( request );
+ assertNotNull( result.getEffectiveToolchains() );
+ assertEquals( 2, result.getEffectiveToolchains().getToolchains().size() );
+ assertEquals( "TYPE", result.getEffectiveToolchains().getToolchains().get(0).getType() );
+ assertEquals( "user_value", result.getEffectiveToolchains().getToolchains().get(0).getProvides().getProperty( "key" ) );
+ assertEquals( "TYPE", result.getEffectiveToolchains().getToolchains().get(1).getType() );
+ assertEquals( "global_value", result.getEffectiveToolchains().getToolchains().get(1).getProvides().getProperty( "key" ) );
+ assertNotNull( result.getProblems() );
+ assertEquals( 0, result.getProblems().size() );
+ }
+
+ @Test
+ public void testStrictToolchainsParseException() throws Exception
+ {
+ ToolchainsBuildingRequest request = new DefaultToolchainsBuildingRequest();
+ request.setGlobalToolchainsSource( new StringSource( "" ) );
+ ToolchainsParseException parseException = new ToolchainsParseException( "MESSAGE", 4, 2 );
+ when( toolchainsReader.read( any( InputStream.class ), anyMap() ) ).thenThrow( parseException );
+
+ try
+ {
+ toolchainBuilder.build( request );
+ }
+ catch ( ToolchainsBuildingException e )
+ {
+ assertEquals( "1 problem was encountered while building the effective toolchains" + LS +
+ "[FATAL] Non-parseable toolchains (memory): MESSAGE @ line 4, column 2" + LS, e.getMessage() );
+ }
+ }
+
+ @Test
+ public void testIOException() throws Exception
+ {
+ ToolchainsBuildingRequest request = new DefaultToolchainsBuildingRequest();
+ request.setGlobalToolchainsSource( new StringSource( "", "LOCATION" ) );
+ IOException ioException = new IOException( "MESSAGE" );
+ when( toolchainsReader.read( any( InputStream.class ), anyMap() ) ).thenThrow( ioException );
+
+ try
+ {
+ toolchainBuilder.build( request );
+ }
+ catch ( ToolchainsBuildingException e )
+ {
+ assertEquals( "1 problem was encountered while building the effective toolchains" + LS +
+ "[FATAL] Non-readable toolchains LOCATION: MESSAGE" + LS, e.getMessage() );
+ }
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/toolchain/building/ToolchainsBuildingExceptionTest.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/toolchain/building/ToolchainsBuildingExceptionTest.java
new file mode 100644
index 00000000..bf745c2a
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/toolchain/building/ToolchainsBuildingExceptionTest.java
@@ -0,0 +1,73 @@
+package org.apache.maven.toolchain.building;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.Collections;
+
+import org.apache.maven.building.Problem;
+import org.apache.maven.building.ProblemCollector;
+import org.apache.maven.building.ProblemCollectorFactory;
+import org.junit.Test;
+
+public class ToolchainsBuildingExceptionTest
+{
+ private static final String LS = System.getProperty( "line.separator" );
+
+ @Test
+ public void testNoProblems()
+ {
+ ToolchainsBuildingException e = new ToolchainsBuildingException( Collections.<Problem>emptyList() );
+ assertEquals( "0 problems were encountered while building the effective toolchains" + LS, e.getMessage() );
+ }
+
+ @Test
+ public void testOneProblem()
+ {
+ ProblemCollector problemCollector = ProblemCollectorFactory.newInstance( null );
+ problemCollector.add( Problem.Severity.ERROR, "MESSAGE", 3, 5, new Exception() );
+ ToolchainsBuildingException e = new ToolchainsBuildingException( problemCollector.getProblems() );
+ assertEquals( "1 problem was encountered while building the effective toolchains" + LS +
+ "[ERROR] MESSAGE @ line 3, column 5" + LS, e.getMessage() );
+ }
+
+ @Test
+ public void testUnknownPositionAndSource()
+ {
+ ProblemCollector problemCollector = ProblemCollectorFactory.newInstance( null );
+ problemCollector.add( Problem.Severity.ERROR, "MESSAGE", -1, -1, new Exception() );
+ ToolchainsBuildingException e = new ToolchainsBuildingException( problemCollector.getProblems() );
+ assertEquals( "1 problem was encountered while building the effective toolchains" + LS +
+ "[ERROR] MESSAGE" + LS, e.getMessage() );
+ }
+
+ @Test
+ public void testUnknownPosition()
+ {
+ ProblemCollector problemCollector = ProblemCollectorFactory.newInstance( null );
+ problemCollector.setSource( "SOURCE" );
+ problemCollector.add( Problem.Severity.ERROR, "MESSAGE", -1, -1, new Exception() );
+ ToolchainsBuildingException e = new ToolchainsBuildingException( problemCollector.getProblems() );
+ assertEquals( "1 problem was encountered while building the effective toolchains" + LS +
+ "[ERROR] MESSAGE @ SOURCE" + LS, e.getMessage() );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/toolchain/merge/MavenToolchainMergerTest.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/toolchain/merge/MavenToolchainMergerTest.java
new file mode 100644
index 00000000..9183e175
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/java/org/apache/maven/toolchain/merge/MavenToolchainMergerTest.java
@@ -0,0 +1,176 @@
+package org.apache.maven.toolchain.merge;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.InputStream;
+
+import org.apache.maven.toolchain.model.PersistedToolchains;
+import org.apache.maven.toolchain.model.ToolchainModel;
+import org.apache.maven.toolchain.model.TrackableBase;
+import org.apache.maven.toolchain.model.io.xpp3.MavenToolchainsXpp3Reader;
+import org.codehaus.plexus.util.IOUtil;
+import org.codehaus.plexus.util.xml.Xpp3Dom;
+import org.junit.Test;
+
+public class MavenToolchainMergerTest
+{
+ private MavenToolchainMerger merger = new MavenToolchainMerger();
+
+ private MavenToolchainsXpp3Reader reader = new MavenToolchainsXpp3Reader();
+
+ @Test
+ public void testMergeNulls()
+ {
+ merger.merge( null, null, null );
+
+ PersistedToolchains pt = new PersistedToolchains();
+ merger.merge( pt, null, null );
+ merger.merge( null, pt, null );
+ }
+
+ @Test
+ public void testMergeJdk() throws Exception
+ {
+ InputStream isDominant = null;
+ InputStream isRecessive = null;
+ try
+ {
+ isDominant = ToolchainModel.class.getResourceAsStream( "toolchains-jdks.xml" );
+ isRecessive = ToolchainModel.class.getResourceAsStream( "toolchains-jdks.xml" );
+
+ PersistedToolchains dominant = reader.read( isDominant );
+ PersistedToolchains recessive = reader.read( isRecessive );
+ assertEquals( 2, dominant.getToolchains().size() );
+
+ merger.merge( dominant, recessive, TrackableBase.USER_LEVEL );
+ assertEquals( 2, dominant.getToolchains().size() );
+ }
+ finally
+ {
+ IOUtil.close( isDominant );
+ }
+ }
+
+ @Test
+ public void testMergeJdkExtra() throws Exception
+ {
+ InputStream jdksIS = null;
+ InputStream jdksExtraIS = null;
+ try
+ {
+ jdksIS = ToolchainModel.class.getResourceAsStream( "toolchains-jdks.xml" );
+ jdksExtraIS = ToolchainModel.class.getResourceAsStream( "toolchains-jdks-extra.xml" );
+
+ PersistedToolchains jdks = reader.read( jdksIS );
+ PersistedToolchains jdksExtra = reader.read( jdksExtraIS );
+ assertEquals( 2, jdks.getToolchains().size() );
+
+ merger.merge( jdks, jdksExtra, TrackableBase.USER_LEVEL );
+ assertEquals( 4, jdks.getToolchains().size() );
+ assertEquals( 2, jdksExtra.getToolchains().size() );
+ }
+ finally
+ {
+ IOUtil.close( jdksIS );
+ IOUtil.close( jdksExtraIS );
+ }
+
+ try
+ {
+ jdksIS = ToolchainModel.class.getResourceAsStream( "toolchains-jdks.xml" );
+ jdksExtraIS = ToolchainModel.class.getResourceAsStream( "toolchains-jdks-extra.xml" );
+
+ PersistedToolchains jdks = reader.read( jdksIS );
+ PersistedToolchains jdksExtra = reader.read( jdksExtraIS );
+ assertEquals( 2, jdks.getToolchains().size() );
+
+ // switch dominant with reccessive
+ merger.merge( jdksExtra, jdks, TrackableBase.USER_LEVEL );
+ assertEquals( 4, jdksExtra.getToolchains().size() );
+ assertEquals( 2, jdks.getToolchains().size() );
+ }
+ finally
+ {
+ IOUtil.close( jdksIS );
+ IOUtil.close( jdksExtraIS );
+ }
+ }
+
+ @Test
+ public void testMergeJdkExtend() throws Exception
+ {
+ InputStream jdksIS = null;
+ InputStream jdksExtendIS = null;
+ try
+ {
+ jdksIS = ToolchainModel.class.getResourceAsStream( "toolchains-jdks.xml" );
+ jdksExtendIS = ToolchainModel.class.getResourceAsStream( "toolchains-jdks-extend.xml" );
+
+ PersistedToolchains jdks = reader.read( jdksIS );
+ PersistedToolchains jdksExtend = reader.read( jdksExtendIS );
+ assertEquals( 2, jdks.getToolchains().size() );
+
+ merger.merge( jdks, jdksExtend, TrackableBase.USER_LEVEL );
+ assertEquals( 2, jdks.getToolchains().size() );
+ Xpp3Dom config0 = (Xpp3Dom) jdks.getToolchains().get( 0 ).getConfiguration();
+ assertEquals( "lib/tools.jar", config0.getChild( "toolsJar" ).getValue() );
+ assertEquals( 2, config0.getChildCount() );
+ Xpp3Dom config1 = (Xpp3Dom) jdks.getToolchains().get( 1 ).getConfiguration();
+ assertEquals( 2, config1.getChildCount() );
+ assertEquals( "lib/classes.jar", config1.getChild( "toolsJar" ).getValue() );
+ assertEquals( 2, jdksExtend.getToolchains().size() );
+ }
+ finally
+ {
+ IOUtil.close( jdksIS );
+ IOUtil.close( jdksExtendIS );
+ }
+
+ try
+ {
+ jdksIS = ToolchainModel.class.getResourceAsStream( "toolchains-jdks.xml" );
+ jdksExtendIS = ToolchainModel.class.getResourceAsStream( "toolchains-jdks-extend.xml" );
+
+ PersistedToolchains jdks = reader.read( jdksIS );
+ PersistedToolchains jdksExtend = reader.read( jdksExtendIS );
+ assertEquals( 2, jdks.getToolchains().size() );
+
+ // switch dominant with reccessive
+ merger.merge( jdksExtend, jdks, TrackableBase.USER_LEVEL );
+ assertEquals( 2, jdksExtend.getToolchains().size() );
+ Xpp3Dom config0 = (Xpp3Dom) jdksExtend.getToolchains().get( 0 ).getConfiguration();
+ assertEquals( "lib/tools.jar", config0.getChild( "toolsJar" ).getValue() );
+ assertEquals( 2, config0.getChildCount() );
+ Xpp3Dom config1 = (Xpp3Dom) jdksExtend.getToolchains().get( 1 ).getConfiguration();
+ assertEquals( 2, config1.getChildCount() );
+ assertEquals( "lib/classes.jar", config1.getChild( "toolsJar" ).getValue() );
+ assertEquals( 2, jdks.getToolchains().size() );
+ }
+ finally
+ {
+ IOUtil.close( jdksIS );
+ IOUtil.close( jdksExtendIS );
+ }
+
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/default-maven/cyclic-reference/module-a/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/default-maven/cyclic-reference/module-a/pom.xml
new file mode 100644
index 00000000..56ec3412
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/default-maven/cyclic-reference/module-a/pom.xml
@@ -0,0 +1,19 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>cyclic-reference</groupId>
+ <artifactId>parent</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ </parent>
+ <artifactId>module-a</artifactId>
+
+ <dependencies>
+ <dependency>
+ <groupId>cyclic-reference</groupId>
+ <artifactId>module-b</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/default-maven/cyclic-reference/module-b/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/default-maven/cyclic-reference/module-b/pom.xml
new file mode 100644
index 00000000..ffa4f347
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/default-maven/cyclic-reference/module-b/pom.xml
@@ -0,0 +1,19 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>cyclic-reference</groupId>
+ <artifactId>parent</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ </parent>
+ <artifactId>module-b</artifactId>
+
+ <dependencies>
+ <dependency>
+ <groupId>cyclic-reference</groupId>
+ <artifactId>module-a</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/default-maven/cyclic-reference/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/default-maven/cyclic-reference/pom.xml
new file mode 100644
index 00000000..e2666190
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/default-maven/cyclic-reference/pom.xml
@@ -0,0 +1,14 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>cyclic-reference</groupId>
+ <artifactId>parent</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <packaging>pom</packaging>
+
+ <modules>
+ <module>module-a</module>
+ <module>module-b</module>
+ </modules>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/lifecycle-executor/mojo-configuration/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/lifecycle-executor/mojo-configuration/pom.xml
new file mode 100644
index 00000000..a821765b
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/lifecycle-executor/mojo-configuration/pom.xml
@@ -0,0 +1,67 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven.lifecycle.test</groupId>
+ <artifactId>mojo-configuration</artifactId>
+ <packaging>jar</packaging>
+ <version>1.0</version>
+ <name>project-with-additional-lifecycle-elements</name>
+ <url>http://maven.apache.org</url>
+
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-clean-plugin</artifactId>
+ <version>0.1</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>0.1</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-deploy-plugin</artifactId>
+ <version>0.1</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-install-plugin</artifactId>
+ <version>0.1</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <version>0.1</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-plugin-plugin</artifactId>
+ <version>0.1</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>0.1</version>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin</artifactId>
+ <version>0.1</version>
+ <executions>
+ <execution>
+ <goals>
+ <goal>xpp3-reader</goal>
+ </goals>
+ <phase>generate-sources</phase>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/lifecycle-executor/project-basic/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/lifecycle-executor/project-basic/pom.xml
new file mode 100644
index 00000000..ab8584d9
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/lifecycle-executor/project-basic/pom.xml
@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.lifecycle.test</groupId>
+ <artifactId>project-basic</artifactId>
+ <version>1.0</version>
+ <packaging>jar</packaging>
+
+ <name>Test Project</name>
+ <inceptionYear>2009</inceptionYear>
+
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-clean-plugin</artifactId>
+ <version>0.1</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>0.1</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-deploy-plugin</artifactId>
+ <version>0.1</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-install-plugin</artifactId>
+ <version>0.1</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <version>0.1</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-plugin-plugin</artifactId>
+ <version>0.1</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-resources-plugin</artifactId>
+ <version>0.1</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>0.1</version>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/lifecycle-executor/project-with-additional-lifecycle-elements/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/lifecycle-executor/project-with-additional-lifecycle-elements/pom.xml
new file mode 100644
index 00000000..83080888
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/lifecycle-executor/project-with-additional-lifecycle-elements/pom.xml
@@ -0,0 +1,72 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven.lifecycle.test</groupId>
+ <artifactId>project-with-additional-lifecycle-elements</artifactId>
+ <packaging>jar</packaging>
+ <version>1.0</version>
+ <name>project-with-additional-lifecycle-elements</name>
+ <url>http://maven.apache.org</url>
+
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-clean-plugin</artifactId>
+ <version>0.1</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>0.1</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-deploy-plugin</artifactId>
+ <version>0.1</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-install-plugin</artifactId>
+ <version>0.1</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <version>0.1</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-plugin-plugin</artifactId>
+ <version>0.1</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>0.1</version>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin</artifactId>
+ <version>0.1</version>
+ <executions>
+ <execution>
+ <goals>
+ <goal>generate-metadata</goal>
+ <goal>generate-test-metadata</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-resources-plugin</artifactId>
+ <version>0.1</version>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/lifecycle-executor/project-with-additional-lifecycle-elements/src/main/java/org/apache/maven/lifecycle/test/App.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/lifecycle-executor/project-with-additional-lifecycle-elements/src/main/java/org/apache/maven/lifecycle/test/App.java
new file mode 100644
index 00000000..826279cc
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/lifecycle-executor/project-with-additional-lifecycle-elements/src/main/java/org/apache/maven/lifecycle/test/App.java
@@ -0,0 +1,13 @@
+package org.apache.maven.lifecycle.test;
+
+/**
+ * Hello world!
+ *
+ */
+public class App
+{
+ public static void main( String[] args )
+ {
+ System.out.println( "Hello World!" );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/lifecycle-executor/project-with-additional-lifecycle-elements/src/test/java/org/apache/maven/lifecycle/test/AppTest.java b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/lifecycle-executor/project-with-additional-lifecycle-elements/src/test/java/org/apache/maven/lifecycle/test/AppTest.java
new file mode 100644
index 00000000..469cb2c4
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/lifecycle-executor/project-with-additional-lifecycle-elements/src/test/java/org/apache/maven/lifecycle/test/AppTest.java
@@ -0,0 +1,38 @@
+package org.apache.maven.lifecycle.test;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+/**
+ * Unit test for simple App.
+ */
+public class AppTest
+ extends TestCase
+{
+ /**
+ * Create the test case
+ *
+ * @param testName name of the test case
+ */
+ public AppTest( String testName )
+ {
+ super( testName );
+ }
+
+ /**
+ * @return the suite of tests being tested
+ */
+ public static Test suite()
+ {
+ return new TestSuite( AppTest.class );
+ }
+
+ /**
+ * Rigourous Test :-)
+ */
+ public void testApp()
+ {
+ assertTrue( true );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/lifecycle-executor/project-with-inheritance/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/lifecycle-executor/project-with-inheritance/pom.xml
new file mode 100644
index 00000000..0f49e9ae
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/lifecycle-executor/project-with-inheritance/pom.xml
@@ -0,0 +1,628 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-parent</artifactId>
+ <version>11</version>
+ <relativePath>../pom/maven/pom.xml</relativePath>
+ </parent>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven</artifactId>
+ <version>3.0-SNAPSHOT</version>
+ <packaging>pom</packaging>
+ <name>Apache Maven</name>
+ <description>Maven is a project development management and
+ comprehension tool. Based on the concept of a project object model:
+ builds, dependency management, documentation creation, site
+ publication, and distribution publication are all controlled from
+ the declarative file. Maven can be extended by plugins to utilise a
+ number of other development tools for reporting or the build
+ process.
+ </description>
+ <url>http://maven.apache.org/</url>
+ <inceptionYear>2001</inceptionYear>
+ <properties>
+ <classWorldsVersion>1.3</classWorldsVersion>
+ <commonsCliVersion>1.0</commonsCliVersion>
+ <!--
+
+ Do not update this, Doxia will be decoupled completely from 3.x and someone can
+ create a rendering engine for it if they like when the release stabilizes. JVZ
+
+ -->
+ <doxiaVersion>1.0-alpha-9</doxiaVersion>
+ <easyMockVersion>1.2_Java1.3</easyMockVersion>
+ <junitVersion>3.8.1</junitVersion>
+ <plexusVersion>1.0-beta-3.0.7</plexusVersion>
+ <plexusInteractivityVersion>1.0-alpha-6</plexusInteractivityVersion>
+ <plexusInterpolationVersion>1.1</plexusInterpolationVersion>
+ <plexusPluginManagerVersion>1.0-alpha-1</plexusPluginManagerVersion>
+ <plexusUtilsVersion>1.5.8</plexusUtilsVersion>
+ <plexusJetty6Version>1.6</plexusJetty6Version>
+ <plexusWebdavVersion>1.0</plexusWebdavVersion>
+ <wagonVersion>1.0-beta-4</wagonVersion>
+ <modelBuilderVersion>1.7-SNAPSHOT</modelBuilderVersion>
+ <mercuryVersion>1.0-alpha-6-SNAPSHOT</mercuryVersion>
+ <mercuryMp3Version>1.0-alpha-1</mercuryMp3Version>
+ <securityDispatcherVersion>1.2</securityDispatcherVersion>
+ <woodstoxVersion>3.2.6</woodstoxVersion>
+ <modelloVersion>1.0.1-SNAPSHOT</modelloVersion>
+ <jxpathVersion>1.3</jxpathVersion>
+ </properties>
+ <issueManagement>
+ <system>jira</system>
+ <url>http://jira.codehaus.org/browse/MNG</url>
+ </issueManagement>
+ <mailingLists>
+ <mailingList>
+ <name>Maven Developer List</name>
+ <subscribe>dev-subscribe@maven.apache.org</subscribe>
+ <unsubscribe>dev-unsubscribe@maven.apache.org</unsubscribe>
+ <post>dev@maven.apache.org</post>
+ <archive>http://mail-archives.apache.org/mod_mbox/maven-dev</archive>
+ <otherArchives>
+ <otherArchive>http://www.mail-archive.com/dev@maven.apache.org/</otherArchive>
+ <otherArchive>http://www.nabble.com/Maven-Developers-f179.html</otherArchive>
+ <otherArchive>http://maven.dev.markmail.org/</otherArchive>
+ </otherArchives>
+ </mailingList>
+ <mailingList>
+ <name>Maven User List</name>
+ <subscribe>users-subscribe@maven.apache.org</subscribe>
+ <unsubscribe>users-unsubscribe@maven.apache.org</unsubscribe>
+ <post>users@maven.apache.org</post>
+ <archive>http://mail-archives.apache.org/mod_mbox/maven-users</archive>
+ <otherArchives>
+ <otherArchive>http://www.mail-archive.com/users@maven.apache.org/</otherArchive>
+ <otherArchive>http://www.nabble.com/Maven---Users-f178.html</otherArchive>
+ <otherArchive>http://maven.users.markmail.org/</otherArchive>
+ </otherArchives>
+ </mailingList>
+ <mailingList>
+ <name>Maven Issues List</name>
+ <subscribe>issues-subscribe@maven.apache.org</subscribe>
+ <unsubscribe>issues-unsubscribe@maven.apache.org</unsubscribe>
+ <archive>http://mail-archives.apache.org/mod_mbox/maven-issues/</archive>
+ <otherArchives>
+ <otherArchive>http://www.mail-archive.com/issues@maven.apache.org</otherArchive>
+ <otherArchive>http://www.nabble.com/Maven---Issues-f15573.html</otherArchive>
+ <otherArchive>http://maven.issues.markmail.org/</otherArchive>
+ </otherArchives>
+ </mailingList>
+ <mailingList>
+ <name>Maven Commits List</name>
+ <subscribe>commits-subscribe@maven.apache.org</subscribe>
+ <unsubscribe>commits-unsubscribe@maven.apache.org</unsubscribe>
+ <archive>http://mail-archives.apache.org/mod_mbox/maven-commits</archive>
+ <otherArchives>
+ <otherArchive>http://www.mail-archive.com/commits@maven.apache.org</otherArchive>
+ <otherArchive>http://www.nabble.com/Maven---Commits-f15575.html</otherArchive>
+ <otherArchive>http://maven.commits.markmail.org/</otherArchive>
+ </otherArchives>
+ </mailingList>
+ <!--
+ duplication from parent pom - temporary until they inherit
+ properly
+ -->
+ <mailingList>
+ <name>Maven Announcements List</name>
+ <post>announce@maven.apache.org</post>
+ <subscribe>announce-subscribe@maven.apache.org</subscribe>
+ <unsubscribe>announce-unsubscribe@maven.apache.org</unsubscribe>
+ <archive>http://mail-archives.apache.org/mod_mbox/maven-announce/</archive>
+ <otherArchives>
+ <otherArchive>http://www.mail-archive.com/announce@maven.apache.org</otherArchive>
+ <otherArchive>http://www.nabble.com/Maven-Announcements-f15617.html</otherArchive>
+ <otherArchive>http://maven.announce.markmail.org/</otherArchive>
+ </otherArchives>
+ </mailingList>
+ <mailingList>
+ <name>Maven Notifications List</name>
+ <subscribe>notifications-subscribe@maven.apache.org</subscribe>
+ <unsubscribe>notifications-unsubscribe@maven.apache.org</unsubscribe>
+ <archive>http://mail-archives.apache.org/mod_mbox/maven-notifications/</archive>
+ <otherArchives>
+ <otherArchive>http://www.mail-archive.com/notifications@maven.apache.org</otherArchive>
+ <otherArchive>http://www.nabble.com/Maven---Notifications-f15574.html</otherArchive>
+ <otherArchive>http://maven.notifications.markmail.org/</otherArchive>
+ </otherArchives>
+ </mailingList>
+ </mailingLists>
+ <scm>
+ <connection>scm:svn:http://svn.apache.org/repos/asf/maven/components/trunk</connection>
+ <developerConnection>scm:svn:https://svn.apache.org/repos/asf/maven/components/trunk</developerConnection>
+ <url>http://svn.apache.org/viewcvs.cgi/maven/components/trunk</url>
+ </scm>
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-component-metadata</artifactId>
+ <version>${plexusVersion}</version>
+ <executions>
+ <execution>
+ <goals>
+ <goal>generate-metadata</goal>
+ <goal>generate-test-metadata</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>2.0.2</version>
+ <configuration>
+ <source>1.5</source>
+ <target>1.5</target>
+ </configuration>
+ </plugin>
+ <plugin>
+ <artifactId>maven-release-plugin</artifactId>
+ <configuration>
+ <tagBase>https://svn.apache.org/repos/asf/maven/components/tags</tagBase>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.modello</groupId>
+ <artifactId>modello-maven-plugin</artifactId>
+ <version>${modelloVersion}</version>
+ <configuration>
+ <useJava5>true</useJava5>
+ </configuration>
+ <executions>
+ <execution>
+ <id>site-docs</id>
+ <phase>pre-site</phase>
+ <goals>
+ <goal>xdoc</goal>
+ <goal>xsd</goal>
+ </goals>
+ </execution>
+ <execution>
+ <id>standard</id>
+ <goals>
+ <goal>java</goal>
+ <goal>xpp3-reader</goal>
+ <goal>xpp3-writer</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <version>1.0.0</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>2.4.2</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <version>2.2-beta-2</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-resources-plugin</artifactId>
+ <version>2.4-SNAPSHOT</version>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+ <modules>
+ <module>maven-core</module>
+ <module>apache-maven</module>
+ <module>maven-model</module>
+ <module>maven-plugin-api</module>
+ <module>maven-project</module>
+ <module>maven-reporting-api</module>
+ <module>maven-project-builder</module>
+ <module>maven-mercury</module>
+ <module>maven-embedder</module>
+ <module>maven-toolchain</module>
+ <module>maven-compat</module>
+ <module>maven-repository</module>
+ <module>maven-repository-mercury</module>
+ </modules>
+ <!--start-->
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>${junitVersion}</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+ <dependencyManagement>
+ <!--end-->
+ <dependencies>
+ <!-- Maven Modules -->
+ <!--start-->
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-mercury</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-lifecycle</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-reporting-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-profile</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-model</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-project</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-plugin-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-toolchain</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-embedder</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-core</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-project-builder</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-repository</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-compat</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <!--end-->
+ <!-- Plexus -->
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-utils</artifactId>
+ <version>${plexusUtilsVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-container-default</artifactId>
+ <version>${plexusVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-component-annotations</artifactId>
+ <version>${plexusVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-classworlds</artifactId>
+ <version>${classWorldsVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-interpolation</artifactId>
+ <version>${plexusInterpolationVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-interactivity-api</artifactId>
+ <version>${plexusInteractivityVersion}</version>
+ <exclusions>
+ <exclusion>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-component-api</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
+ <!-- Plexus test dependencies -->
+ <dependency>
+ <groupId>org.sonatype.plexus</groupId>
+ <artifactId>plexus-jetty6</artifactId>
+ <version>${plexusJetty6Version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.sonatype.spice</groupId>
+ <artifactId>plexus-webdav</artifactId>
+ <version>${plexusWebdavVersion}</version>
+ <scope>test</scope>
+ </dependency>
+
+ <!-- Wagon -->
+ <dependency>
+ <groupId>org.apache.maven.wagon</groupId>
+ <artifactId>wagon-provider-api</artifactId>
+ <version>${wagonVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.wagon</groupId>
+ <artifactId>wagon-file</artifactId>
+ <version>${wagonVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.wagon</groupId>
+ <artifactId>wagon-http-lightweight</artifactId>
+ <version>${wagonVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.wagon</groupId>
+ <artifactId>wagon-ssh</artifactId>
+ <version>${wagonVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.wagon</groupId>
+ <artifactId>wagon-ssh-external</artifactId>
+ <version>${wagonVersion}</version>
+ </dependency>
+ <!-- Doxia -->
+ <dependency>
+ <groupId>org.apache.maven.doxia</groupId>
+ <artifactId>doxia-sink-api</artifactId>
+ <version>${doxiaVersion}</version>
+ </dependency>
+ <!-- Maven Shared -->
+ <dependency>
+ <groupId>org.sonatype.spice</groupId>
+ <artifactId>model-builder</artifactId>
+ <version>${modelBuilderVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.woodstox</groupId>
+ <artifactId>wstx-asl</artifactId>
+ <version>${woodstoxVersion}</version>
+ </dependency>
+ <!-- Commons -->
+ <dependency>
+ <groupId>commons-cli</groupId>
+ <artifactId>commons-cli</artifactId>
+ <version>${commonsCliVersion}</version>
+ <exclusions>
+ <exclusion>
+ <artifactId>commons-lang</artifactId>
+ <groupId>commons-lang</groupId>
+ </exclusion>
+ <exclusion>
+ <artifactId>commons-logging</artifactId>
+ <groupId>commons-logging</groupId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>commons-jxpath</groupId>
+ <artifactId>commons-jxpath</artifactId>
+ <version>${jxpathVersion}</version>
+ </dependency>
+
+ <!-- Mercury -->
+ <dependency>
+ <groupId>org.apache.maven.mercury</groupId>
+ <artifactId>mercury-artifact</artifactId>
+ <version>${mercuryVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.mercury</groupId>
+ <artifactId>mercury-external</artifactId>
+ <version>${mercuryVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.mercury</groupId>
+ <artifactId>mercury-plexus</artifactId>
+ <version>${mercuryVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.mercury</groupId>
+ <artifactId>mercury-repo-virtual</artifactId>
+ <version>${mercuryVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.sonatype.mercury</groupId>
+ <artifactId>mercury-mp3-cli</artifactId>
+ <version>${mercuryMp3Version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.sonatype.plexus</groupId>
+ <artifactId>plexus-sec-dispatcher</artifactId>
+ <version>${securityDispatcherVersion}</version>
+ </dependency>
+
+
+ <!-- Mercury test dependencies -->
+ <dependency>
+ <groupId>org.apache.maven.mercury</groupId>
+ <artifactId>mercury-repo-local-m2</artifactId>
+ <version>${mercuryVersion}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.mercury</groupId>
+ <artifactId>mercury-repo-remote-m2</artifactId>
+ <version>${mercuryVersion}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.mercury</groupId>
+ <artifactId>mercury-md-sat</artifactId>
+ <version>${mercuryVersion}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.mercury</groupId>
+ <artifactId>mercury-util</artifactId>
+ <version>${mercuryVersion}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.mercury</groupId>
+ <artifactId>mercury-transport-http</artifactId>
+ <version>${mercuryVersion}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.mercury</groupId>
+ <artifactId>mercury-transport-http</artifactId>
+ <version>${mercuryVersion}</version>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.sonatype.plexus</groupId>
+ <artifactId>plexus-plugin-manager</artifactId>
+ <version>${plexusPluginManagerVersion}</version>
+ </dependency>
+ <!--start-->
+ <dependency>
+ <groupId>easymock</groupId>
+ <artifactId>easymock</artifactId>
+ <version>${easyMockVersion}</version>
+ <scope>test</scope>
+ </dependency>
+ <!--end-->
+ </dependencies>
+ <!--start-->
+ </dependencyManagement>
+ <!--end-->
+ <distributionManagement>
+ <site>
+ <id>apache.website</id>
+ <url>scp://people.apache.org/www/maven.apache.org/ref/${project.version}/</url>
+ </site>
+ </distributionManagement>
+ <profiles>
+ <profile>
+ <id>osgi</id>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <executions>
+ <execution>
+ <goals>
+ <goal>manifest</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <!-- Needed for including the manifest, see MJAR-71 -->
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <version>2.1</version>
+ <configuration>
+ <archive>
+ <manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
+ </archive>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ <profile>
+ <id>release</id>
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <inherited>false</inherited>
+ <configuration>
+ <descriptors>
+ <descriptor>src/main/assembly/src.xml</descriptor>
+ </descriptors>
+ <tarLongFileMode>gnu</tarLongFileMode>
+ <finalName>maven-${project.version}-src</finalName>
+ </configuration>
+ <executions>
+ <execution>
+ <id>make-assembly</id>
+ <phase>package</phase>
+ <goals>
+ <goal>single</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ <profile>
+ <id>strict</id>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-enforcer-plugin</artifactId>
+ <version>1.0-alpha-3</version>
+ <executions>
+ <execution>
+ <id>enforce-jdk-15</id>
+ <goals>
+ <goal>enforce</goal>
+ </goals>
+ <configuration>
+ <rules>
+ <requireJavaVersion>
+ <version>1.5</version>
+ </requireJavaVersion>
+ </rules>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/lifecycle-executor/project-with-multiple-executions/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/lifecycle-executor/project-with-multiple-executions/pom.xml
new file mode 100644
index 00000000..e7a38347
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/lifecycle-executor/project-with-multiple-executions/pom.xml
@@ -0,0 +1,112 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>project-with-multiple-executions</artifactId>
+ <version>1.0.1</version>
+ <packaging>maven-plugin</packaging>
+
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-clean-plugin</artifactId>
+ <version>0.1</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>0.1</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-deploy-plugin</artifactId>
+ <version>0.1</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-install-plugin</artifactId>
+ <version>0.1</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <version>0.1</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-plugin-plugin</artifactId>
+ <version>0.1</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-resources-plugin</artifactId>
+ <version>0.1</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>0.1</version>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin</artifactId>
+ <version>0.1</version>
+ <executions>
+ <execution>
+ <id>remote-resources</id>
+ <goals>
+ <goal>xpp3-writer</goal>
+ <goal>java</goal>
+ <goal>xpp3-reader</goal>
+ </goals>
+ <configuration>
+ <version>1.1.0</version>
+ <models>
+ <model>src/main/mdo/remote-resources.mdo</model>
+ </models>
+ </configuration>
+ </execution>
+ <execution>
+ <id>supplemental-models</id>
+ <goals>
+ <goal>xpp3-writer</goal>
+ <goal>java</goal>
+ <goal>xpp3-reader</goal>
+ </goals>
+ <configuration>
+ <version>1.0.0</version>
+ <models>
+ <model>src/main/mdo/supplemental-model.mdo</model>
+ </models>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/lifecycle-executor/project-with-multiple-executions/src/main/mdo/remote-resources.mdo b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/lifecycle-executor/project-with-multiple-executions/src/main/mdo/remote-resources.mdo
new file mode 100644
index 00000000..c64cfbc8
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/lifecycle-executor/project-with-multiple-executions/src/main/mdo/remote-resources.mdo
@@ -0,0 +1,61 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<model>
+ <id>remoteResourcesBundle</id>
+ <name>RemoteResourcesBundle</name>
+ <description><![CDATA[
+ A bundle of remote resources.
+ This is the model specification for remote-resources.xml.
+ ]]></description>
+ <defaults>
+ <default>
+ <key>package</key>
+ <value>org.apache.maven.plugin.resources.remote</value>
+ </default>
+ </defaults>
+ <classes>
+ <class rootElement="true" xml.tagName="remoteResourcesBundle">
+ <name>RemoteResourcesBundle</name>
+ <version>1.1.0</version>
+ <description>Root element of the remote-resources.xml file.</description>
+ <fields>
+ <field>
+ <name>remoteResources</name>
+ <version>1.1.0</version>
+ <description><![CDATA[
+ Remote resources that are contained in a remote resources bundle.
+ ]]></description>
+ <association>
+ <type>String</type>
+ <multiplicity>*</multiplicity>
+ </association>
+ </field>
+ <field>
+ <name>sourceEncoding</name>
+ <version>1.1.0</version>
+ <description><![CDATA[
+ Source encoding of the remote resources contained in the bundle.
+ ]]></description>
+ <type>String</type>
+ </field>
+ </fields>
+ </class>
+ </classes>
+</model>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/lifecycle-executor/project-with-multiple-executions/src/main/mdo/supplemental-model.mdo b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/lifecycle-executor/project-with-multiple-executions/src/main/mdo/supplemental-model.mdo
new file mode 100644
index 00000000..102149df
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/lifecycle-executor/project-with-multiple-executions/src/main/mdo/supplemental-model.mdo
@@ -0,0 +1,61 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<model>
+ <id>supplementalModel</id>
+ <name>SupplementalDataModel</name>
+ <description>Provides access to supplemental POM data models.</description>
+ <defaults>
+ <default>
+ <key>package</key>
+ <value>org.apache.maven.plugin.resources.remote</value>
+ </default>
+ </defaults>
+ <classes>
+ <class rootElement="true" xml.tagName="supplementalDataModels" xsd.compositor="sequence">
+ <name>SupplementalDataModel</name>
+ <version>1.0.0</version>
+ <description>Root element of the supplemental-models.xml file.</description>
+ <fields>
+ <field xml.listStyle="flat">
+ <name>supplement</name>
+ <version>1.0.0</version>
+ <description>Snippets of POM xml files used to supplement the data model.</description>
+ <association>
+ <type>Supplement</type>
+ <multiplicity>*</multiplicity>
+ </association>
+ </field>
+ </fields>
+ </class>
+ <class>
+ <name>Supplement</name>
+ <version>1.0.0</version>
+ <description>A single supplement</description>
+ <fields>
+ <field>
+ <name>project</name>
+ <version>1.0.0</version>
+ <description>Snippets of POM xml files used to supplement the data model.</description>
+ <type>DOM</type>
+ </field>
+ </fields>
+ </class>
+ </classes>
+</model>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/lifecycle-executor/project-with-plugin-level-configuration-only/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/lifecycle-executor/project-with-plugin-level-configuration-only/pom.xml
new file mode 100644
index 00000000..b3bb2dd9
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/lifecycle-executor/project-with-plugin-level-configuration-only/pom.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>project-plugin-level-configuration-only</artifactId>
+ <version>1.0.1</version>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.modello</groupId>
+ <artifactId>modello-maven-plugin</artifactId>
+ <version>1.0.1</version>
+ <configuration>
+ <version>1.1.0</version>
+ <models>
+ <model>src/main/mdo/remote-resources.mdo</model>
+ </models>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/lifecycle-listener/lifecycle-listener-dependency-injection/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/lifecycle-listener/lifecycle-listener-dependency-injection/pom.xml
new file mode 100644
index 00000000..41b99c72
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/lifecycle-listener/lifecycle-listener-dependency-injection/pom.xml
@@ -0,0 +1,30 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.lifecycle-listener.test</groupId>
+ <artifactId>simple</artifactId>
+ <version>1.0</version>
+
+ <properties>
+ <foo>${injected}</foo>
+ </properties>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin</artifactId>
+ <version>0.1</version>
+ <executions>
+ <execution>
+ <id>test</id>
+ <phase>validate</phase>
+ <goals>
+ <goal>it</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/lifecycle-listener/lifecycle-participant-reactor-dependency-injection/module-a/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/lifecycle-listener/lifecycle-participant-reactor-dependency-injection/module-a/pom.xml
new file mode 100644
index 00000000..6a173f61
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/lifecycle-listener/lifecycle-participant-reactor-dependency-injection/module-a/pom.xml
@@ -0,0 +1,12 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>lifecycle-participant-reactor-dependency-injection</groupId>
+ <artifactId>parent</artifactId>
+ <version>1.0</version>
+ </parent>
+
+ <artifactId>module-a</artifactId>
+
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/lifecycle-listener/lifecycle-participant-reactor-dependency-injection/module-b/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/lifecycle-listener/lifecycle-participant-reactor-dependency-injection/module-b/pom.xml
new file mode 100644
index 00000000..795111a2
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/lifecycle-listener/lifecycle-participant-reactor-dependency-injection/module-b/pom.xml
@@ -0,0 +1,12 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>lifecycle-participant-reactor-dependency-injection</groupId>
+ <artifactId>parent</artifactId>
+ <version>1.0</version>
+ </parent>
+
+ <artifactId>module-b</artifactId>
+
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/lifecycle-listener/lifecycle-participant-reactor-dependency-injection/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/lifecycle-listener/lifecycle-participant-reactor-dependency-injection/pom.xml
new file mode 100644
index 00000000..2830b321
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/lifecycle-listener/lifecycle-participant-reactor-dependency-injection/pom.xml
@@ -0,0 +1,13 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>lifecycle-participant-reactor-dependency-injection</groupId>
+ <artifactId>parent</artifactId>
+ <version>1.0</version>
+ <packaging>pom</packaging>
+
+ <modules>
+ <module>module-a</module>
+ <module>module-b</module>
+ </modules>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/mng-5003-plugin-realm-cache/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/mng-5003-plugin-realm-cache/pom.xml
new file mode 100644
index 00000000..55f8e317
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/mng-5003-plugin-realm-cache/pom.xml
@@ -0,0 +1,8 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng5003</groupId>
+ <artifactId>mng-5003-plugin-realm-cache</artifactId>
+ <version>1.0</version>
+
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-contributing-system-scope-plugin-dep/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-contributing-system-scope-plugin-dep/pom.xml
new file mode 100644
index 00000000..a9fa3cac
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-contributing-system-scope-plugin-dep/pom.xml
@@ -0,0 +1,44 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng3586</groupId>
+ <artifactId>test2</artifactId>
+ <version>1.0</version>
+
+ <name>Maven Integration Test :: MNG-3586</name>
+ <description>
+ Test that plugin dependencies with scope system are part of the plugin class realm.
+ </description>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin</artifactId>
+ <version>0.1</version>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven.its.mng3586</groupId>
+ <artifactId>tools</artifactId>
+ <version>1.5.0</version>
+ <scope>system</scope>
+ <systemPath>${basedir}/tools.jar</systemPath>
+ </dependency>
+ </dependencies>
+ <executions>
+ <execution>
+ <id>load</id>
+ <phase>validate</phase>
+ <configuration>
+ <resourcePaths>maven-core-it.properties</resourcePaths>
+ <pluginClassLoaderOutput>target/pcl.properties</pluginClassLoaderOutput>
+ </configuration>
+ <goals>
+ <goal>load</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-contributing-system-scope-plugin-dep/tools.jar b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-contributing-system-scope-plugin-dep/tools.jar
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-contributing-system-scope-plugin-dep/tools.jar
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-with-build-extensions-plugin/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-with-build-extensions-plugin/pom.xml
new file mode 100644
index 00000000..d4e34a5d
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-with-build-extensions-plugin/pom.xml
@@ -0,0 +1,31 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.test</groupId>
+ <artifactId>project-with-build-extensions-plugin</artifactId>
+ <version>1.0</version>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin</artifactId>
+ <version>0.1</version>
+ <extensions>true</extensions>
+ <executions>
+ <execution>
+ <id>load</id>
+ <phase>validate</phase>
+ <configuration>
+ <resourcePaths>maven-core-it.properties</resourcePaths>
+ <pluginClassLoaderOutput>target/pcl.properties</pluginClassLoaderOutput>
+ </configuration>
+ <goals>
+ <goal>load</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-with-inheritance/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-with-inheritance/pom.xml
new file mode 100644
index 00000000..0f49e9ae
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-with-inheritance/pom.xml
@@ -0,0 +1,628 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-parent</artifactId>
+ <version>11</version>
+ <relativePath>../pom/maven/pom.xml</relativePath>
+ </parent>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven</artifactId>
+ <version>3.0-SNAPSHOT</version>
+ <packaging>pom</packaging>
+ <name>Apache Maven</name>
+ <description>Maven is a project development management and
+ comprehension tool. Based on the concept of a project object model:
+ builds, dependency management, documentation creation, site
+ publication, and distribution publication are all controlled from
+ the declarative file. Maven can be extended by plugins to utilise a
+ number of other development tools for reporting or the build
+ process.
+ </description>
+ <url>http://maven.apache.org/</url>
+ <inceptionYear>2001</inceptionYear>
+ <properties>
+ <classWorldsVersion>1.3</classWorldsVersion>
+ <commonsCliVersion>1.0</commonsCliVersion>
+ <!--
+
+ Do not update this, Doxia will be decoupled completely from 3.x and someone can
+ create a rendering engine for it if they like when the release stabilizes. JVZ
+
+ -->
+ <doxiaVersion>1.0-alpha-9</doxiaVersion>
+ <easyMockVersion>1.2_Java1.3</easyMockVersion>
+ <junitVersion>3.8.1</junitVersion>
+ <plexusVersion>1.0-beta-3.0.7</plexusVersion>
+ <plexusInteractivityVersion>1.0-alpha-6</plexusInteractivityVersion>
+ <plexusInterpolationVersion>1.1</plexusInterpolationVersion>
+ <plexusPluginManagerVersion>1.0-alpha-1</plexusPluginManagerVersion>
+ <plexusUtilsVersion>1.5.8</plexusUtilsVersion>
+ <plexusJetty6Version>1.6</plexusJetty6Version>
+ <plexusWebdavVersion>1.0</plexusWebdavVersion>
+ <wagonVersion>1.0-beta-4</wagonVersion>
+ <modelBuilderVersion>1.7-SNAPSHOT</modelBuilderVersion>
+ <mercuryVersion>1.0-alpha-6-SNAPSHOT</mercuryVersion>
+ <mercuryMp3Version>1.0-alpha-1</mercuryMp3Version>
+ <securityDispatcherVersion>1.2</securityDispatcherVersion>
+ <woodstoxVersion>3.2.6</woodstoxVersion>
+ <modelloVersion>1.0.1-SNAPSHOT</modelloVersion>
+ <jxpathVersion>1.3</jxpathVersion>
+ </properties>
+ <issueManagement>
+ <system>jira</system>
+ <url>http://jira.codehaus.org/browse/MNG</url>
+ </issueManagement>
+ <mailingLists>
+ <mailingList>
+ <name>Maven Developer List</name>
+ <subscribe>dev-subscribe@maven.apache.org</subscribe>
+ <unsubscribe>dev-unsubscribe@maven.apache.org</unsubscribe>
+ <post>dev@maven.apache.org</post>
+ <archive>http://mail-archives.apache.org/mod_mbox/maven-dev</archive>
+ <otherArchives>
+ <otherArchive>http://www.mail-archive.com/dev@maven.apache.org/</otherArchive>
+ <otherArchive>http://www.nabble.com/Maven-Developers-f179.html</otherArchive>
+ <otherArchive>http://maven.dev.markmail.org/</otherArchive>
+ </otherArchives>
+ </mailingList>
+ <mailingList>
+ <name>Maven User List</name>
+ <subscribe>users-subscribe@maven.apache.org</subscribe>
+ <unsubscribe>users-unsubscribe@maven.apache.org</unsubscribe>
+ <post>users@maven.apache.org</post>
+ <archive>http://mail-archives.apache.org/mod_mbox/maven-users</archive>
+ <otherArchives>
+ <otherArchive>http://www.mail-archive.com/users@maven.apache.org/</otherArchive>
+ <otherArchive>http://www.nabble.com/Maven---Users-f178.html</otherArchive>
+ <otherArchive>http://maven.users.markmail.org/</otherArchive>
+ </otherArchives>
+ </mailingList>
+ <mailingList>
+ <name>Maven Issues List</name>
+ <subscribe>issues-subscribe@maven.apache.org</subscribe>
+ <unsubscribe>issues-unsubscribe@maven.apache.org</unsubscribe>
+ <archive>http://mail-archives.apache.org/mod_mbox/maven-issues/</archive>
+ <otherArchives>
+ <otherArchive>http://www.mail-archive.com/issues@maven.apache.org</otherArchive>
+ <otherArchive>http://www.nabble.com/Maven---Issues-f15573.html</otherArchive>
+ <otherArchive>http://maven.issues.markmail.org/</otherArchive>
+ </otherArchives>
+ </mailingList>
+ <mailingList>
+ <name>Maven Commits List</name>
+ <subscribe>commits-subscribe@maven.apache.org</subscribe>
+ <unsubscribe>commits-unsubscribe@maven.apache.org</unsubscribe>
+ <archive>http://mail-archives.apache.org/mod_mbox/maven-commits</archive>
+ <otherArchives>
+ <otherArchive>http://www.mail-archive.com/commits@maven.apache.org</otherArchive>
+ <otherArchive>http://www.nabble.com/Maven---Commits-f15575.html</otherArchive>
+ <otherArchive>http://maven.commits.markmail.org/</otherArchive>
+ </otherArchives>
+ </mailingList>
+ <!--
+ duplication from parent pom - temporary until they inherit
+ properly
+ -->
+ <mailingList>
+ <name>Maven Announcements List</name>
+ <post>announce@maven.apache.org</post>
+ <subscribe>announce-subscribe@maven.apache.org</subscribe>
+ <unsubscribe>announce-unsubscribe@maven.apache.org</unsubscribe>
+ <archive>http://mail-archives.apache.org/mod_mbox/maven-announce/</archive>
+ <otherArchives>
+ <otherArchive>http://www.mail-archive.com/announce@maven.apache.org</otherArchive>
+ <otherArchive>http://www.nabble.com/Maven-Announcements-f15617.html</otherArchive>
+ <otherArchive>http://maven.announce.markmail.org/</otherArchive>
+ </otherArchives>
+ </mailingList>
+ <mailingList>
+ <name>Maven Notifications List</name>
+ <subscribe>notifications-subscribe@maven.apache.org</subscribe>
+ <unsubscribe>notifications-unsubscribe@maven.apache.org</unsubscribe>
+ <archive>http://mail-archives.apache.org/mod_mbox/maven-notifications/</archive>
+ <otherArchives>
+ <otherArchive>http://www.mail-archive.com/notifications@maven.apache.org</otherArchive>
+ <otherArchive>http://www.nabble.com/Maven---Notifications-f15574.html</otherArchive>
+ <otherArchive>http://maven.notifications.markmail.org/</otherArchive>
+ </otherArchives>
+ </mailingList>
+ </mailingLists>
+ <scm>
+ <connection>scm:svn:http://svn.apache.org/repos/asf/maven/components/trunk</connection>
+ <developerConnection>scm:svn:https://svn.apache.org/repos/asf/maven/components/trunk</developerConnection>
+ <url>http://svn.apache.org/viewcvs.cgi/maven/components/trunk</url>
+ </scm>
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-component-metadata</artifactId>
+ <version>${plexusVersion}</version>
+ <executions>
+ <execution>
+ <goals>
+ <goal>generate-metadata</goal>
+ <goal>generate-test-metadata</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>2.0.2</version>
+ <configuration>
+ <source>1.5</source>
+ <target>1.5</target>
+ </configuration>
+ </plugin>
+ <plugin>
+ <artifactId>maven-release-plugin</artifactId>
+ <configuration>
+ <tagBase>https://svn.apache.org/repos/asf/maven/components/tags</tagBase>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.modello</groupId>
+ <artifactId>modello-maven-plugin</artifactId>
+ <version>${modelloVersion}</version>
+ <configuration>
+ <useJava5>true</useJava5>
+ </configuration>
+ <executions>
+ <execution>
+ <id>site-docs</id>
+ <phase>pre-site</phase>
+ <goals>
+ <goal>xdoc</goal>
+ <goal>xsd</goal>
+ </goals>
+ </execution>
+ <execution>
+ <id>standard</id>
+ <goals>
+ <goal>java</goal>
+ <goal>xpp3-reader</goal>
+ <goal>xpp3-writer</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <version>1.0.0</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>2.4.2</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <version>2.2-beta-2</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-resources-plugin</artifactId>
+ <version>2.4-SNAPSHOT</version>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+ <modules>
+ <module>maven-core</module>
+ <module>apache-maven</module>
+ <module>maven-model</module>
+ <module>maven-plugin-api</module>
+ <module>maven-project</module>
+ <module>maven-reporting-api</module>
+ <module>maven-project-builder</module>
+ <module>maven-mercury</module>
+ <module>maven-embedder</module>
+ <module>maven-toolchain</module>
+ <module>maven-compat</module>
+ <module>maven-repository</module>
+ <module>maven-repository-mercury</module>
+ </modules>
+ <!--start-->
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>${junitVersion}</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+ <dependencyManagement>
+ <!--end-->
+ <dependencies>
+ <!-- Maven Modules -->
+ <!--start-->
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-mercury</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-lifecycle</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-reporting-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-profile</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-model</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-project</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-plugin-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-toolchain</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-embedder</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-core</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-project-builder</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-repository</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-compat</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <!--end-->
+ <!-- Plexus -->
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-utils</artifactId>
+ <version>${plexusUtilsVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-container-default</artifactId>
+ <version>${plexusVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-component-annotations</artifactId>
+ <version>${plexusVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-classworlds</artifactId>
+ <version>${classWorldsVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-interpolation</artifactId>
+ <version>${plexusInterpolationVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-interactivity-api</artifactId>
+ <version>${plexusInteractivityVersion}</version>
+ <exclusions>
+ <exclusion>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-component-api</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
+ <!-- Plexus test dependencies -->
+ <dependency>
+ <groupId>org.sonatype.plexus</groupId>
+ <artifactId>plexus-jetty6</artifactId>
+ <version>${plexusJetty6Version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.sonatype.spice</groupId>
+ <artifactId>plexus-webdav</artifactId>
+ <version>${plexusWebdavVersion}</version>
+ <scope>test</scope>
+ </dependency>
+
+ <!-- Wagon -->
+ <dependency>
+ <groupId>org.apache.maven.wagon</groupId>
+ <artifactId>wagon-provider-api</artifactId>
+ <version>${wagonVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.wagon</groupId>
+ <artifactId>wagon-file</artifactId>
+ <version>${wagonVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.wagon</groupId>
+ <artifactId>wagon-http-lightweight</artifactId>
+ <version>${wagonVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.wagon</groupId>
+ <artifactId>wagon-ssh</artifactId>
+ <version>${wagonVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.wagon</groupId>
+ <artifactId>wagon-ssh-external</artifactId>
+ <version>${wagonVersion}</version>
+ </dependency>
+ <!-- Doxia -->
+ <dependency>
+ <groupId>org.apache.maven.doxia</groupId>
+ <artifactId>doxia-sink-api</artifactId>
+ <version>${doxiaVersion}</version>
+ </dependency>
+ <!-- Maven Shared -->
+ <dependency>
+ <groupId>org.sonatype.spice</groupId>
+ <artifactId>model-builder</artifactId>
+ <version>${modelBuilderVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.woodstox</groupId>
+ <artifactId>wstx-asl</artifactId>
+ <version>${woodstoxVersion}</version>
+ </dependency>
+ <!-- Commons -->
+ <dependency>
+ <groupId>commons-cli</groupId>
+ <artifactId>commons-cli</artifactId>
+ <version>${commonsCliVersion}</version>
+ <exclusions>
+ <exclusion>
+ <artifactId>commons-lang</artifactId>
+ <groupId>commons-lang</groupId>
+ </exclusion>
+ <exclusion>
+ <artifactId>commons-logging</artifactId>
+ <groupId>commons-logging</groupId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>commons-jxpath</groupId>
+ <artifactId>commons-jxpath</artifactId>
+ <version>${jxpathVersion}</version>
+ </dependency>
+
+ <!-- Mercury -->
+ <dependency>
+ <groupId>org.apache.maven.mercury</groupId>
+ <artifactId>mercury-artifact</artifactId>
+ <version>${mercuryVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.mercury</groupId>
+ <artifactId>mercury-external</artifactId>
+ <version>${mercuryVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.mercury</groupId>
+ <artifactId>mercury-plexus</artifactId>
+ <version>${mercuryVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.mercury</groupId>
+ <artifactId>mercury-repo-virtual</artifactId>
+ <version>${mercuryVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.sonatype.mercury</groupId>
+ <artifactId>mercury-mp3-cli</artifactId>
+ <version>${mercuryMp3Version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.sonatype.plexus</groupId>
+ <artifactId>plexus-sec-dispatcher</artifactId>
+ <version>${securityDispatcherVersion}</version>
+ </dependency>
+
+
+ <!-- Mercury test dependencies -->
+ <dependency>
+ <groupId>org.apache.maven.mercury</groupId>
+ <artifactId>mercury-repo-local-m2</artifactId>
+ <version>${mercuryVersion}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.mercury</groupId>
+ <artifactId>mercury-repo-remote-m2</artifactId>
+ <version>${mercuryVersion}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.mercury</groupId>
+ <artifactId>mercury-md-sat</artifactId>
+ <version>${mercuryVersion}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.mercury</groupId>
+ <artifactId>mercury-util</artifactId>
+ <version>${mercuryVersion}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.mercury</groupId>
+ <artifactId>mercury-transport-http</artifactId>
+ <version>${mercuryVersion}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.mercury</groupId>
+ <artifactId>mercury-transport-http</artifactId>
+ <version>${mercuryVersion}</version>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.sonatype.plexus</groupId>
+ <artifactId>plexus-plugin-manager</artifactId>
+ <version>${plexusPluginManagerVersion}</version>
+ </dependency>
+ <!--start-->
+ <dependency>
+ <groupId>easymock</groupId>
+ <artifactId>easymock</artifactId>
+ <version>${easyMockVersion}</version>
+ <scope>test</scope>
+ </dependency>
+ <!--end-->
+ </dependencies>
+ <!--start-->
+ </dependencyManagement>
+ <!--end-->
+ <distributionManagement>
+ <site>
+ <id>apache.website</id>
+ <url>scp://people.apache.org/www/maven.apache.org/ref/${project.version}/</url>
+ </site>
+ </distributionManagement>
+ <profiles>
+ <profile>
+ <id>osgi</id>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <executions>
+ <execution>
+ <goals>
+ <goal>manifest</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <!-- Needed for including the manifest, see MJAR-71 -->
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <version>2.1</version>
+ <configuration>
+ <archive>
+ <manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
+ </archive>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ <profile>
+ <id>release</id>
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <inherited>false</inherited>
+ <configuration>
+ <descriptors>
+ <descriptor>src/main/assembly/src.xml</descriptor>
+ </descriptors>
+ <tarLongFileMode>gnu</tarLongFileMode>
+ <finalName>maven-${project.version}-src</finalName>
+ </configuration>
+ <executions>
+ <execution>
+ <id>make-assembly</id>
+ <phase>package</phase>
+ <goals>
+ <goal>single</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ <profile>
+ <id>strict</id>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-enforcer-plugin</artifactId>
+ <version>1.0-alpha-3</version>
+ <executions>
+ <execution>
+ <id>enforce-jdk-15</id>
+ <goals>
+ <goal>enforce</goal>
+ </goals>
+ <configuration>
+ <rules>
+ <requireJavaVersion>
+ <version>1.5</version>
+ </requireJavaVersion>
+ </rules>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-with-plugin-classpath-ordering/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-with-plugin-classpath-ordering/pom.xml
new file mode 100644
index 00000000..32124c53
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-with-plugin-classpath-ordering/pom.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng3906</groupId>
+ <artifactId>parent</artifactId>
+ <version>0.1</version>
+ <packaging>pom</packaging>
+
+ <name>Maven Integration Test :: MNG-3906</name>
+ <description>
+ Test that project-level plugin dependencies are properly merged during inheritance.
+ </description>
+
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-class-loader</artifactId>
+ <version>2.1-SNAPSHOT</version>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven.its.mng3906</groupId>
+ <artifactId>e</artifactId>
+ <version>0.1</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.its.mng3906</groupId>
+ <artifactId>a</artifactId>
+ <version>0.1</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.its.mng3906</groupId>
+ <artifactId>d</artifactId>
+ <version>0.1</version>
+ </dependency>
+ </dependencies>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-with-plugin-classpath-ordering/sub/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-with-plugin-classpath-ordering/sub/pom.xml
new file mode 100644
index 00000000..e13262b0
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-with-plugin-classpath-ordering/sub/pom.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.maven.its.mng3906</groupId>
+ <artifactId>parent</artifactId>
+ <version>0.1</version>
+ </parent>
+
+ <artifactId>child</artifactId>
+
+ <name>Maven Integration Test :: MNG-3906</name>
+ <description>
+ Test that project-level plugin dependencies are properly merged during inheritance.
+ </description>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-class-loader</artifactId>
+ <version>2.1-SNAPSHOT</version>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven.its.mng3906</groupId>
+ <artifactId>c</artifactId>
+ <version>0.1</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.its.mng3906</groupId>
+ <artifactId>a</artifactId>
+ <version>0.2</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.its.mng3906</groupId>
+ <artifactId>b</artifactId>
+ <version>0.1</version>
+ </dependency>
+ </dependencies>
+ <executions>
+ <execution>
+ <id>load</id>
+ <phase>validate</phase>
+ <configuration>
+ <resourcePaths>org/apache/maven/its/mng3906/SomeClass.class</resourcePaths>
+ <pluginClassLoaderOutput>target/pcl.properties</pluginClassLoaderOutput>
+ </configuration>
+ <goals>
+ <goal>load</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-with-plugin-classpath-ordering/sub/repo/org/apache/maven/its/mng3906/a/0.1/a-0.1.jar b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-with-plugin-classpath-ordering/sub/repo/org/apache/maven/its/mng3906/a/0.1/a-0.1.jar
new file mode 100644
index 00000000..0db2c9f4
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-with-plugin-classpath-ordering/sub/repo/org/apache/maven/its/mng3906/a/0.1/a-0.1.jar
Binary files differ
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-with-plugin-classpath-ordering/sub/repo/org/apache/maven/its/mng3906/a/0.1/a-0.1.pom b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-with-plugin-classpath-ordering/sub/repo/org/apache/maven/its/mng3906/a/0.1/a-0.1.pom
new file mode 100644
index 00000000..ed095b25
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-with-plugin-classpath-ordering/sub/repo/org/apache/maven/its/mng3906/a/0.1/a-0.1.pom
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng3906</groupId>
+ <artifactId>a</artifactId>
+ <version>0.1</version>
+ <packaging>jar</packaging>
+
+ <distributionManagement>
+ <repository>
+ <id>maven-core-it</id>
+ <url>file:///${basedir}/repo</url>
+ </repository>
+ </distributionManagement>
+
+ <properties>
+ <maven.test.skip>true</maven.test.skip>
+ <updateReleaseInfo>true</updateReleaseInfo>
+ </properties>
+
+ <build>
+ <resources>
+ <resource>
+ <directory>.</directory>
+ <includes>
+ <include>pom.xml</include>
+ <include>src/**</include>
+ </includes>
+ </resource>
+ <resource>
+ <directory>src/main/resources</directory>
+ </resource>
+ </resources>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-with-plugin-classpath-ordering/sub/repo/org/apache/maven/its/mng3906/a/0.2/a-0.2.jar b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-with-plugin-classpath-ordering/sub/repo/org/apache/maven/its/mng3906/a/0.2/a-0.2.jar
new file mode 100644
index 00000000..c5fb69a1
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-with-plugin-classpath-ordering/sub/repo/org/apache/maven/its/mng3906/a/0.2/a-0.2.jar
Binary files differ
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-with-plugin-classpath-ordering/sub/repo/org/apache/maven/its/mng3906/a/0.2/a-0.2.pom b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-with-plugin-classpath-ordering/sub/repo/org/apache/maven/its/mng3906/a/0.2/a-0.2.pom
new file mode 100644
index 00000000..cb5373bd
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-with-plugin-classpath-ordering/sub/repo/org/apache/maven/its/mng3906/a/0.2/a-0.2.pom
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng3906</groupId>
+ <artifactId>a</artifactId>
+ <version>0.2</version>
+ <packaging>jar</packaging>
+
+ <distributionManagement>
+ <repository>
+ <id>maven-core-it</id>
+ <url>file:///${basedir}/repo</url>
+ </repository>
+ </distributionManagement>
+
+ <properties>
+ <maven.test.skip>true</maven.test.skip>
+ <updateReleaseInfo>true</updateReleaseInfo>
+ </properties>
+
+ <build>
+ <resources>
+ <resource>
+ <directory>.</directory>
+ <includes>
+ <include>pom.xml</include>
+ <include>src/**</include>
+ </includes>
+ </resource>
+ <resource>
+ <directory>src/main/resources</directory>
+ </resource>
+ </resources>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-with-plugin-classpath-ordering/sub/repo/org/apache/maven/its/mng3906/a/maven-metadata.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-with-plugin-classpath-ordering/sub/repo/org/apache/maven/its/mng3906/a/maven-metadata.xml
new file mode 100644
index 00000000..472f1c8c
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-with-plugin-classpath-ordering/sub/repo/org/apache/maven/its/mng3906/a/maven-metadata.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?><metadata>
+ <groupId>org.apache.maven.its.mng3906</groupId>
+ <artifactId>a</artifactId>
+ <version>0.1</version>
+ <versioning>
+ <release>0.2</release>
+ <versions>
+ <version>0.1</version>
+ <version>0.2</version>
+ </versions>
+ <lastUpdated>20081214111115</lastUpdated>
+ </versioning>
+</metadata> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-with-plugin-classpath-ordering/sub/repo/org/apache/maven/its/mng3906/b/0.1/b-0.1.jar b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-with-plugin-classpath-ordering/sub/repo/org/apache/maven/its/mng3906/b/0.1/b-0.1.jar
new file mode 100644
index 00000000..7817617f
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-with-plugin-classpath-ordering/sub/repo/org/apache/maven/its/mng3906/b/0.1/b-0.1.jar
Binary files differ
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-with-plugin-classpath-ordering/sub/repo/org/apache/maven/its/mng3906/b/0.1/b-0.1.pom b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-with-plugin-classpath-ordering/sub/repo/org/apache/maven/its/mng3906/b/0.1/b-0.1.pom
new file mode 100644
index 00000000..d4dbbb73
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-with-plugin-classpath-ordering/sub/repo/org/apache/maven/its/mng3906/b/0.1/b-0.1.pom
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng3906</groupId>
+ <artifactId>b</artifactId>
+ <version>0.1</version>
+ <packaging>jar</packaging>
+
+ <distributionManagement>
+ <repository>
+ <id>maven-core-it</id>
+ <url>file:///${basedir}/repo</url>
+ </repository>
+ </distributionManagement>
+
+ <properties>
+ <maven.test.skip>true</maven.test.skip>
+ <updateReleaseInfo>true</updateReleaseInfo>
+ </properties>
+
+ <build>
+ <resources>
+ <resource>
+ <directory>.</directory>
+ <includes>
+ <include>pom.xml</include>
+ <include>src/**</include>
+ </includes>
+ </resource>
+ <resource>
+ <directory>src/main/resources</directory>
+ </resource>
+ </resources>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-with-plugin-classpath-ordering/sub/repo/org/apache/maven/its/mng3906/b/maven-metadata.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-with-plugin-classpath-ordering/sub/repo/org/apache/maven/its/mng3906/b/maven-metadata.xml
new file mode 100644
index 00000000..2847985b
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-with-plugin-classpath-ordering/sub/repo/org/apache/maven/its/mng3906/b/maven-metadata.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?><metadata>
+ <groupId>org.apache.maven.its.mng3906</groupId>
+ <artifactId>b</artifactId>
+ <version>0.1</version>
+ <versioning>
+ <release>0.1</release>
+ <versions>
+ <version>0.1</version>
+ </versions>
+ <lastUpdated>20081214111129</lastUpdated>
+ </versioning>
+</metadata> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-with-plugin-classpath-ordering/sub/repo/org/apache/maven/its/mng3906/c/0.1/c-0.1.jar b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-with-plugin-classpath-ordering/sub/repo/org/apache/maven/its/mng3906/c/0.1/c-0.1.jar
new file mode 100644
index 00000000..a4dcec7a
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-with-plugin-classpath-ordering/sub/repo/org/apache/maven/its/mng3906/c/0.1/c-0.1.jar
Binary files differ
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-with-plugin-classpath-ordering/sub/repo/org/apache/maven/its/mng3906/c/0.1/c-0.1.pom b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-with-plugin-classpath-ordering/sub/repo/org/apache/maven/its/mng3906/c/0.1/c-0.1.pom
new file mode 100644
index 00000000..afc967cb
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-with-plugin-classpath-ordering/sub/repo/org/apache/maven/its/mng3906/c/0.1/c-0.1.pom
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng3906</groupId>
+ <artifactId>c</artifactId>
+ <version>0.1</version>
+ <packaging>jar</packaging>
+
+ <distributionManagement>
+ <repository>
+ <id>maven-core-it</id>
+ <url>file:///${basedir}/repo</url>
+ </repository>
+ </distributionManagement>
+
+ <properties>
+ <maven.test.skip>true</maven.test.skip>
+ <updateReleaseInfo>true</updateReleaseInfo>
+ </properties>
+
+ <build>
+ <resources>
+ <resource>
+ <directory>.</directory>
+ <includes>
+ <include>pom.xml</include>
+ <include>src/**</include>
+ </includes>
+ </resource>
+ <resource>
+ <directory>src/main/resources</directory>
+ </resource>
+ </resources>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-with-plugin-classpath-ordering/sub/repo/org/apache/maven/its/mng3906/c/maven-metadata.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-with-plugin-classpath-ordering/sub/repo/org/apache/maven/its/mng3906/c/maven-metadata.xml
new file mode 100644
index 00000000..bcc92824
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-with-plugin-classpath-ordering/sub/repo/org/apache/maven/its/mng3906/c/maven-metadata.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?><metadata>
+ <groupId>org.apache.maven.its.mng3906</groupId>
+ <artifactId>c</artifactId>
+ <version>0.1</version>
+ <versioning>
+ <release>0.1</release>
+ <versions>
+ <version>0.1</version>
+ </versions>
+ <lastUpdated>20081214111138</lastUpdated>
+ </versioning>
+</metadata> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-with-plugin-classpath-ordering/sub/repo/org/apache/maven/its/mng3906/d/0.1/d-0.1.jar b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-with-plugin-classpath-ordering/sub/repo/org/apache/maven/its/mng3906/d/0.1/d-0.1.jar
new file mode 100644
index 00000000..067491b4
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-with-plugin-classpath-ordering/sub/repo/org/apache/maven/its/mng3906/d/0.1/d-0.1.jar
Binary files differ
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-with-plugin-classpath-ordering/sub/repo/org/apache/maven/its/mng3906/d/0.1/d-0.1.pom b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-with-plugin-classpath-ordering/sub/repo/org/apache/maven/its/mng3906/d/0.1/d-0.1.pom
new file mode 100644
index 00000000..bfd077cb
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-with-plugin-classpath-ordering/sub/repo/org/apache/maven/its/mng3906/d/0.1/d-0.1.pom
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng3906</groupId>
+ <artifactId>d</artifactId>
+ <version>0.1</version>
+ <packaging>jar</packaging>
+
+ <distributionManagement>
+ <repository>
+ <id>maven-core-it</id>
+ <url>file:///${basedir}/repo</url>
+ </repository>
+ </distributionManagement>
+
+ <properties>
+ <maven.test.skip>true</maven.test.skip>
+ <updateReleaseInfo>true</updateReleaseInfo>
+ </properties>
+
+ <build>
+ <resources>
+ <resource>
+ <directory>.</directory>
+ <includes>
+ <include>pom.xml</include>
+ <include>src/**</include>
+ </includes>
+ </resource>
+ <resource>
+ <directory>src/main/resources</directory>
+ </resource>
+ </resources>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-with-plugin-classpath-ordering/sub/repo/org/apache/maven/its/mng3906/d/maven-metadata.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-with-plugin-classpath-ordering/sub/repo/org/apache/maven/its/mng3906/d/maven-metadata.xml
new file mode 100644
index 00000000..06b6e18d
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-with-plugin-classpath-ordering/sub/repo/org/apache/maven/its/mng3906/d/maven-metadata.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?><metadata>
+ <groupId>org.apache.maven.its.mng3906</groupId>
+ <artifactId>d</artifactId>
+ <version>0.1</version>
+ <versioning>
+ <release>0.1</release>
+ <versions>
+ <version>0.1</version>
+ </versions>
+ <lastUpdated>20081214111146</lastUpdated>
+ </versioning>
+</metadata> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-with-plugin-classpath-ordering/sub/repo/org/apache/maven/its/mng3906/e/0.1/e-0.1.jar b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-with-plugin-classpath-ordering/sub/repo/org/apache/maven/its/mng3906/e/0.1/e-0.1.jar
new file mode 100644
index 00000000..2469da59
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-with-plugin-classpath-ordering/sub/repo/org/apache/maven/its/mng3906/e/0.1/e-0.1.jar
Binary files differ
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-with-plugin-classpath-ordering/sub/repo/org/apache/maven/its/mng3906/e/0.1/e-0.1.pom b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-with-plugin-classpath-ordering/sub/repo/org/apache/maven/its/mng3906/e/0.1/e-0.1.pom
new file mode 100644
index 00000000..24f2705e
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-with-plugin-classpath-ordering/sub/repo/org/apache/maven/its/mng3906/e/0.1/e-0.1.pom
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng3906</groupId>
+ <artifactId>e</artifactId>
+ <version>0.1</version>
+ <packaging>jar</packaging>
+
+ <distributionManagement>
+ <repository>
+ <id>maven-core-it</id>
+ <url>file:///${basedir}/repo</url>
+ </repository>
+ </distributionManagement>
+
+ <properties>
+ <maven.test.skip>true</maven.test.skip>
+ <updateReleaseInfo>true</updateReleaseInfo>
+ </properties>
+
+ <build>
+ <resources>
+ <resource>
+ <directory>.</directory>
+ <includes>
+ <include>pom.xml</include>
+ <include>src/**</include>
+ </includes>
+ </resource>
+ <resource>
+ <directory>src/main/resources</directory>
+ </resource>
+ </resources>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-with-plugin-classpath-ordering/sub/repo/org/apache/maven/its/mng3906/e/maven-metadata.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-with-plugin-classpath-ordering/sub/repo/org/apache/maven/its/mng3906/e/maven-metadata.xml
new file mode 100644
index 00000000..95023c7a
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-with-plugin-classpath-ordering/sub/repo/org/apache/maven/its/mng3906/e/maven-metadata.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?><metadata>
+ <groupId>org.apache.maven.its.mng3906</groupId>
+ <artifactId>e</artifactId>
+ <version>0.1</version>
+ <versioning>
+ <release>0.1</release>
+ <versions>
+ <version>0.1</version>
+ </versions>
+ <lastUpdated>20081214111155</lastUpdated>
+ </versioning>
+</metadata> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-with-plugin-classpath-ordering/sub/settings-template.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-with-plugin-classpath-ordering/sub/settings-template.xml
new file mode 100644
index 00000000..cde42158
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/plugin-manager/project-with-plugin-classpath-ordering/sub/settings-template.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<settings>
+ <profiles>
+ <profile>
+ <id>maven-core-it-repo</id>
+ <repositories>
+ <repository>
+ <id>maven-core-it</id>
+ <url>@baseurl@/repo</url>
+ <releases>
+ <checksumPolicy>ignore</checksumPolicy>
+ </releases>
+ <snapshots>
+ <enabled>false</enabled>
+ </snapshots>
+ </repository>
+ </repositories>
+ <pluginRepositories>
+ <pluginRepository>
+ <id>maven-core-it</id>
+ <url>@baseurl@/repo</url>
+ <releases>
+ <checksumPolicy>ignore</checksumPolicy>
+ </releases>
+ <snapshots>
+ <enabled>false</enabled>
+ </snapshots>
+ </pluginRepository>
+ </pluginRepositories>
+ </profile>
+ </profiles>
+ <activeProfiles>
+ <activeProfile>maven-core-it-repo</activeProfile>
+ </activeProfiles>
+</settings>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/project-builder/it0063/jdk/jre/placeholder.txt b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/project-builder/it0063/jdk/jre/placeholder.txt
new file mode 100644
index 00000000..e26e8608
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/project-builder/it0063/jdk/jre/placeholder.txt
@@ -0,0 +1 @@
+need it so that empty folder does not get deleted \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/project-builder/it0063/jdk/lib/tools.jar b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/project-builder/it0063/jdk/lib/tools.jar
new file mode 100644
index 00000000..d6435519
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/project-builder/it0063/jdk/lib/tools.jar
Binary files differ
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/project-builder/it0063/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/project-builder/it0063/pom.xml
new file mode 100644
index 00000000..0d7b08a9
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/project-builder/it0063/pom.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.it0063</groupId>
+ <artifactId>maven-it-it0063</artifactId>
+ <version>1.0</version>
+ <packaging>jar</packaging>
+
+ <name>Maven Integration Test :: it0063</name>
+ <description>Test the use of a system scoped dependency to a (fake) tools.jar.</description>
+
+ <dependencies>
+ <dependency>
+ <groupId>com.sun</groupId>
+ <artifactId>tools</artifactId>
+ <version>1.4.2</version>
+ <scope>system</scope>
+ <systemPath>${jre.home}/../lib/tools.jar</systemPath>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-dependency-resolution</artifactId>
+ <version>2.1-SNAPSHOT</version>
+ <configuration>
+ <compileClassPath>target/compile.txt</compileClassPath>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/project-builder/mng-3023/consumer/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/project-builder/mng-3023/consumer/pom.xml
new file mode 100644
index 00000000..a70b208c
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/project-builder/mng-3023/consumer/pom.xml
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.maven.its.mng3023</groupId>
+ <artifactId>parent</artifactId>
+ <version>1</version>
+ </parent>
+
+ <artifactId>consumer</artifactId>
+
+ <name>Maven Integration Test :: MNG-3023 :: Consumer</name>
+ <description>Test that reactor projects are included in dependency resolution.</description>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven.its.mng3023</groupId>
+ <artifactId>dependency</artifactId>
+ <version>1</version>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-dependency-resolution</artifactId>
+ <version>2.1-SNAPSHOT</version>
+ <executions>
+ <execution>
+ <id>compile-classpath</id>
+ <phase>validate</phase>
+ <goals>
+ <goal>compile</goal>
+ </goals>
+ <configuration>
+ <compileClassPath>${project.build.directory}/compile.classpath</compileClassPath>
+ <significantPathLevels>1</significantPathLevels>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/project-builder/mng-3023/dependency/dependency-1.jar b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/project-builder/mng-3023/dependency/dependency-1.jar
new file mode 100644
index 00000000..d1fb4ec7
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/project-builder/mng-3023/dependency/dependency-1.jar
Binary files differ
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/project-builder/mng-3023/dependency/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/project-builder/mng-3023/dependency/pom.xml
new file mode 100644
index 00000000..e783f85c
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/project-builder/mng-3023/dependency/pom.xml
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.maven.its.mng3023</groupId>
+ <artifactId>parent</artifactId>
+ <version>1</version>
+ </parent>
+
+ <artifactId>dependency</artifactId>
+
+ <name>Maven Integration Test :: MNG-3023 :: Dependency</name>
+ <description>Test that reactor projects are included in dependency resolution.</description>
+
+ <build>
+ <outputDirectory>dependency-classes</outputDirectory>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-artifact</artifactId>
+ <version>2.1-SNAPSHOT</version>
+ <executions>
+ <execution>
+ <id>compile</id>
+ <phase>initialize</phase>
+ <goals>
+ <goal>set</goal>
+ </goals>
+ <configuration>
+ <mainFile>dependency-classes</mainFile>
+ </configuration>
+ </execution>
+ <execution>
+ <id>install</id>
+ <phase>generate-sources</phase>
+ <goals>
+ <goal>set</goal>
+ <goal>attach-pom</goal>
+ <goal>install</goal>
+ </goals>
+ <configuration>
+ <mainFile>dependency-1.jar</mainFile>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/project-builder/mng-3023/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/project-builder/mng-3023/pom.xml
new file mode 100644
index 00000000..23f09ce5
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/project-builder/mng-3023/pom.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng3023</groupId>
+ <artifactId>parent</artifactId>
+ <version>1</version>
+ <packaging>pom</packaging>
+
+ <name>Maven Integration Test :: MNG-3023</name>
+ <description>Test that reactor projects are included in dependency resolution.</description>
+
+ <modules>
+ <module>dependency</module>
+ <module>consumer</module>
+ </modules>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/project-dependencies-resolver/it0063/jdk/jre/placeholder.txt b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/project-dependencies-resolver/it0063/jdk/jre/placeholder.txt
new file mode 100644
index 00000000..e26e8608
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/project-dependencies-resolver/it0063/jdk/jre/placeholder.txt
@@ -0,0 +1 @@
+need it so that empty folder does not get deleted \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/project-dependencies-resolver/it0063/jdk/lib/tools.jar b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/project-dependencies-resolver/it0063/jdk/lib/tools.jar
new file mode 100644
index 00000000..d6435519
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/project-dependencies-resolver/it0063/jdk/lib/tools.jar
Binary files differ
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/project-dependencies-resolver/it0063/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/project-dependencies-resolver/it0063/pom.xml
new file mode 100644
index 00000000..0d7b08a9
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/project-dependencies-resolver/it0063/pom.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.it0063</groupId>
+ <artifactId>maven-it-it0063</artifactId>
+ <version>1.0</version>
+ <packaging>jar</packaging>
+
+ <name>Maven Integration Test :: it0063</name>
+ <description>Test the use of a system scoped dependency to a (fake) tools.jar.</description>
+
+ <dependencies>
+ <dependency>
+ <groupId>com.sun</groupId>
+ <artifactId>tools</artifactId>
+ <version>1.4.2</version>
+ <scope>system</scope>
+ <systemPath>${jre.home}/../lib/tools.jar</systemPath>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-dependency-resolution</artifactId>
+ <version>2.1-SNAPSHOT</version>
+ <configuration>
+ <compileClassPath>target/compile.txt</compileClassPath>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/project-dependencies-resolver/project-with-exclusions/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/project-dependencies-resolver/project-with-exclusions/pom.xml
new file mode 100644
index 00000000..9fae2925
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/projects/project-dependencies-resolver/project-with-exclusions/pom.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven.its.mng4034</groupId>
+ <artifactId>parent</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven.its</groupId>
+ <artifactId>maven-core-it-support</artifactId>
+ <version>1.3</version>
+ <scope>runtime</scope>
+ <exclusions>
+ <exclusion>
+ <groupId>commons-lang</groupId>
+ <artifactId>commons-lang</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/its/a/0.1/a-0.1.jar b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/its/a/0.1/a-0.1.jar
new file mode 100644
index 00000000..609ec21b
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/its/a/0.1/a-0.1.jar
Binary files differ
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/its/a/0.1/a-0.1.pom b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/its/a/0.1/a-0.1.pom
new file mode 100644
index 00000000..f4514188
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/its/a/0.1/a-0.1.pom
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its</groupId>
+ <artifactId>a</artifactId>
+ <version>0.1</version>
+ <packaging>jar</packaging>
+
+ <name>Maven Integration Test :: Dummy Artifact</name>
+ <description>
+
+ </description>
+
+ <distributionManagement>
+ <repository>
+ <id>maven-core-it</id>
+ <url>file:///${basedir}/repo</url>
+ </repository>
+ </distributionManagement>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/its/a/maven-metadata.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/its/a/maven-metadata.xml
new file mode 100644
index 00000000..8099175e
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/its/a/maven-metadata.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<metadata>
+ <groupId>org.apache.maven.its</groupId>
+ <artifactId>a</artifactId>
+ <version>0.1</version>
+ <versioning>
+ <versions>
+ <version>0.1</version>
+ </versions>
+ <lastUpdated>20091023222756</lastUpdated>
+ </versioning>
+</metadata>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/its/b/0.1/b-0.1.jar b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/its/b/0.1/b-0.1.jar
new file mode 100644
index 00000000..19df0485
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/its/b/0.1/b-0.1.jar
Binary files differ
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/its/b/0.1/b-0.1.pom b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/its/b/0.1/b-0.1.pom
new file mode 100644
index 00000000..ca20cbf5
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/its/b/0.1/b-0.1.pom
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its</groupId>
+ <artifactId>b</artifactId>
+ <version>0.1</version>
+ <packaging>jar</packaging>
+
+ <name>Maven Integration Test :: Dummy Artifact</name>
+ <description>
+
+ </description>
+
+ <distributionManagement>
+ <repository>
+ <id>maven-core-it</id>
+ <url>file:///${basedir}/repo</url>
+ </repository>
+ </distributionManagement>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven.its</groupId>
+ <artifactId>a</artifactId>
+ <version>0.1</version>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/its/b/maven-metadata.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/its/b/maven-metadata.xml
new file mode 100644
index 00000000..e77af628
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/its/b/maven-metadata.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<metadata>
+ <groupId>org.apache.maven.its</groupId>
+ <artifactId>b</artifactId>
+ <version>0.1</version>
+ <versioning>
+ <versions>
+ <version>0.1</version>
+ </versions>
+ <lastUpdated>20091023222817</lastUpdated>
+ </versioning>
+</metadata>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/its/plugins/maven-it-plugin/0.1/maven-it-plugin-0.1.jar b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/its/plugins/maven-it-plugin/0.1/maven-it-plugin-0.1.jar
new file mode 100644
index 00000000..84a4bf7a
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/its/plugins/maven-it-plugin/0.1/maven-it-plugin-0.1.jar
Binary files differ
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/its/plugins/maven-it-plugin/0.1/maven-it-plugin-0.1.pom b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/its/plugins/maven-it-plugin/0.1/maven-it-plugin-0.1.pom
new file mode 100644
index 00000000..4cd0ff00
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/its/plugins/maven-it-plugin/0.1/maven-it-plugin-0.1.pom
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin</artifactId>
+ <version>0.1</version>
+ <packaging>maven-plugin</packaging>
+
+ <name>Maven Integration Test Plugin</name>
+ <description>
+ A test plugin to assist testing of Maven core.
+ </description>
+ <inceptionYear>2009</inceptionYear>
+
+ <distributionManagement>
+ <repository>
+ <id>maven-core-it</id>
+ <url>file:///${basedir}/repo</url>
+ </repository>
+ </distributionManagement>
+
+ <properties>
+ <maven.test.skip>true</maven.test.skip>
+ <updateReleaseInfo>true</updateReleaseInfo>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-plugin-api</artifactId>
+ <version>2.0</version>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <resources>
+ <resource>
+ <directory>.</directory>
+ <includes>
+ <include>pom.xml</include>
+ <include>src/**</include>
+ </includes>
+ </resource>
+ <resource>
+ <directory>src/main/resources</directory>
+ </resource>
+ </resources>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/its/plugins/maven-it-plugin/0.1/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/its/plugins/maven-it-plugin/0.1/pom.xml
new file mode 100644
index 00000000..4cd0ff00
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/its/plugins/maven-it-plugin/0.1/pom.xml
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin</artifactId>
+ <version>0.1</version>
+ <packaging>maven-plugin</packaging>
+
+ <name>Maven Integration Test Plugin</name>
+ <description>
+ A test plugin to assist testing of Maven core.
+ </description>
+ <inceptionYear>2009</inceptionYear>
+
+ <distributionManagement>
+ <repository>
+ <id>maven-core-it</id>
+ <url>file:///${basedir}/repo</url>
+ </repository>
+ </distributionManagement>
+
+ <properties>
+ <maven.test.skip>true</maven.test.skip>
+ <updateReleaseInfo>true</updateReleaseInfo>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-plugin-api</artifactId>
+ <version>2.0</version>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <resources>
+ <resource>
+ <directory>.</directory>
+ <includes>
+ <include>pom.xml</include>
+ <include>src/**</include>
+ </includes>
+ </resource>
+ <resource>
+ <directory>src/main/resources</directory>
+ </resource>
+ </resources>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/its/plugins/maven-it-plugin/maven-metadata.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/its/plugins/maven-it-plugin/maven-metadata.xml
new file mode 100644
index 00000000..65155293
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/its/plugins/maven-it-plugin/maven-metadata.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<metadata>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin</artifactId>
+ <version>0.1</version>
+ <versioning>
+ <latest>0.1</latest>
+ <release>0.1</release>
+ <versions>
+ <version>0.1</version>
+ </versions>
+ <lastUpdated>20091023233513</lastUpdated>
+ </versioning>
+</metadata>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/its/plugins/maven-metadata.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/its/plugins/maven-metadata.xml
new file mode 100644
index 00000000..637ec122
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/its/plugins/maven-metadata.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<metadata>
+ <plugins>
+ <plugin>
+ <name>Maven Integration Test Plugin</name>
+ <prefix>it</prefix>
+ <artifactId>maven-it-plugin</artifactId>
+ </plugin>
+ </plugins>
+</metadata>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/maven-plugin-api/2.0/maven-plugin-api-2.0.jar b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/maven-plugin-api/2.0/maven-plugin-api-2.0.jar
new file mode 100644
index 00000000..5150c162
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/maven-plugin-api/2.0/maven-plugin-api-2.0.jar
Binary files differ
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/maven-plugin-api/2.0/maven-plugin-api-2.0.pom b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/maven-plugin-api/2.0/maven-plugin-api-2.0.pom
new file mode 100644
index 00000000..f4ea8d1d
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/maven-plugin-api/2.0/maven-plugin-api-2.0.pom
@@ -0,0 +1,23 @@
+<project>
+ <parent>
+ <artifactId>maven</artifactId>
+ <groupId>org.apache.maven</groupId>
+ <version>2.0</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-plugin-api</artifactId>
+ <name>Maven Plugin API</name>
+ <version>2.0</version>
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>3.8.1</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+ <distributionManagement>
+ <status>deployed</status>
+ </distributionManagement>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/maven/2.0/maven-2.0.pom b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/maven/2.0/maven-2.0.pom
new file mode 100644
index 00000000..3fe5d31d
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/maven/2.0/maven-2.0.pom
@@ -0,0 +1,264 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven</artifactId>
+ <packaging>pom</packaging>
+ <name>Maven</name>
+ <version>2.0</version>
+ <description>Maven is a project development management and comprehension tool. Based on the concept of a project object model: builds, dependency management, documentation creation, site publication, and distribution publication are all controlled from the declarative file. Maven can be extended by plugins to utilise a number of other development tools for reporting or the build process.</description>
+ <url>http://maven.apache.org/maven2/</url>
+ <issueManagement>
+ <system>jira</system>
+ <url>http://jira.codehaus.org/browse/MNG</url>
+ </issueManagement>
+ <ciManagement>
+ <system>continuum</system>
+ <notifiers>
+ <notifier>
+ <configuration>
+ <address>commits@maven.apache.org</address>
+ </configuration>
+ </notifier>
+ </notifiers>
+ </ciManagement>
+ <mailingLists>
+ <mailingList>
+ <name>Maven User List</name>
+ <subscribe>users-subscribe@maven.apache.org</subscribe>
+ <unsubscribe>users-unsubscribe@maven.apache.org</unsubscribe>
+ <post>users@maven.apache.org</post>
+ <archive>http://mail-archives.apache.org/mod_mbox/maven-users</archive>
+ </mailingList>
+ <mailingList>
+ <name>Maven Developer List</name>
+ <subscribe>dev-subscribe@maven.apache.org</subscribe>
+ <unsubscribe>dev-unsubscribe@maven.apache.org</unsubscribe>
+ <post>dev@maven.apache.org</post>
+ <archive>http://mail-archives.apache.org/mod_mbox/maven-dev</archive>
+ </mailingList>
+ <mailingList>
+ <name>Maven Commits List</name>
+ <subscribe>commits-subscribe@maven.apache.org</subscribe>
+ <unsubscribe>commits-unsubscribe@maven.apache.org</unsubscribe>
+ <post>commits@maven.apache.org</post>
+ <archive>http://mail-archives.apache.org/mod_mbox/maven-dev</archive>
+ </mailingList>
+ <mailingList>
+ <name>Apache Announce List</name>
+ <subscribe>announce-subscribe@apache.org</subscribe>
+ <unsubscribe>announce-unsubscribe@apache.org</unsubscribe>
+ <post>announce@apache.org</post>
+ <archive>http://mail-archives.apache.org/mod_mbox/www-announce/</archive>
+ </mailingList>
+ </mailingLists>
+ <developers>
+ <developer>
+ <id>jvanzyl</id>
+ <name>Jason van Zyl</name>
+ <email>jason@maven.org</email>
+ <organization>ASF</organization>
+ <roles>
+ <role>PMC Chair</role>
+ </roles>
+ <timezone>-5</timezone>
+ </developer>
+ <developer>
+ <id>brett</id>
+ <name>Brett Porter</name>
+ <email>brett@apache.org</email>
+ <organization>ASF</organization>
+ <roles>
+ <role>PMC Member</role>
+ </roles>
+ <timezone>+10</timezone>
+ </developer>
+ <developer>
+ <id>evenisse</id>
+ <name>Emmanuel Venisse</name>
+ <email>evenisse@apache.org</email>
+ <organization>ASF</organization>
+ <roles>
+ <role>PMC Member</role>
+ </roles>
+ <timezone>+1</timezone>
+ </developer>
+ <developer>
+ <id>jdcasey</id>
+ <name>John Casey</name>
+ <email>jdcasey@apache.org</email>
+ <organization>ASF</organization>
+ <roles>
+ <role>PMC Member</role>
+ </roles>
+ <timezone>-5</timezone>
+ </developer>
+ <developer>
+ <id>kenney</id>
+ <name>Kenney Westerhof</name>
+ <email>kenney@apache.org</email>
+ <organization>Neonics</organization>
+ <roles>
+ <role>PMC Member</role>
+ </roles>
+ <timezone>+1</timezone>
+ </developer>
+ <developer>
+ <id>trygvis</id>
+ <name>Trygve Laugstol</name>
+ <email>trygvis@apache.org</email>
+ <organization>ASF</organization>
+ <roles>
+ <role>PMC Member</role>
+ </roles>
+ <timezone>+1</timezone>
+ </developer>
+ <developer>
+ <id>vmassol</id>
+ <name>Vincent Massol</name>
+ <email>vmassol@apache.org</email>
+ <organization>ASF</organization>
+ <roles>
+ <role>PMC Member</role>
+ </roles>
+ <timezone>+1</timezone>
+ </developer>
+ <developer>
+ <id>vsiveton</id>
+ <name>Vincent Siveton</name>
+ <email>vsiveton@apache.org</email>
+ <organization>ASF</organization>
+ <roles>
+ <role>Committer</role>
+ </roles>
+ <timezone>-5</timezone>
+ </developer>
+ </developers>
+ <licenses>
+ <license>
+ <name>The Apache Software License, Version 2.0</name>
+ <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
+ <distribution>repo</distribution>
+ </license>
+ </licenses>
+ <scm>
+ <connection>scm:svn:http://svn.apache.org/repos/asf/maven/components/tags/maven-2.0</connection>
+ <developerConnection>scm:svn:https://svn.apache.org/repos/asf/maven/components/tags/maven-2.0</developerConnection>
+ <url>http://svn.apache.org/viewcvs.cgi/maven/components/tags/maven-2.0</url>
+ </scm>
+ <organization>
+ <name>Apache Software Foundation</name>
+ <url>http://www.apache.org/</url>
+ </organization>
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <artifactId>maven-release-plugin</artifactId>
+ <configuration>
+ <tagBase>https://svn.apache.org/repos/asf/maven/components/tags</tagBase>
+ </configuration>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+ <modules>
+ <module>maven-archiver</module>
+ <module>maven-artifact</module>
+ <module>maven-artifact-manager</module>
+ <module>maven-artifact-ant</module>
+ <module>maven-artifact-test</module>
+ <module>maven-core</module>
+ <module>maven-error-diagnostics</module>
+ <module>maven-model</module>
+ <module>maven-monitor</module>
+ <module>maven-plugin-api</module>
+ <module>maven-plugin-descriptor</module>
+ <module>maven-plugin-parameter-documenter</module>
+ <module>maven-plugin-registry</module>
+ <module>maven-plugin-tools</module>
+ <module>maven-profile</module>
+ <module>maven-project</module>
+ <module>maven-reporting</module>
+ <module>maven-repository-metadata</module>
+ <module>maven-script</module>
+ <module>maven-settings</module>
+ </modules>
+ <repositories>
+ <repository>
+ <releases>
+ <enabled>false</enabled>
+ </releases>
+ <id>snapshots</id>
+ <name>Maven Central Development Repository</name>
+ <url>http://snapshots.maven.codehaus.org/maven2</url>
+ </repository>
+ </repositories>
+ <pluginRepositories>
+ <pluginRepository>
+ <releases>
+ <enabled>false</enabled>
+ </releases>
+ <id>snapshots</id>
+ <name>Maven Central Plugins Development Repository</name>
+ <url>http://snapshots.maven.codehaus.org/maven2</url>
+ </pluginRepository>
+ </pluginRepositories>
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>3.8.1</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-container-default</artifactId>
+ <version>1.0-alpha-8</version>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-utils</artifactId>
+ <version>1.0.4</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.wagon</groupId>
+ <artifactId>wagon-provider-api</artifactId>
+ <version>1.0-alpha-5</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.wagon</groupId>
+ <artifactId>wagon-ssh</artifactId>
+ <version>1.0-alpha-5</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.wagon</groupId>
+ <artifactId>wagon-file</artifactId>
+ <version>1.0-alpha-5</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.wagon</groupId>
+ <artifactId>wagon-http-lightweight</artifactId>
+ <version>1.0-alpha-5</version>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+ <distributionManagement>
+ <repository>
+ <id>repo1</id>
+ <name>Maven Central Repository</name>
+ <url>scp://repo1.maven.org/home/projects/maven/repository-staging/to-ibiblio/maven2</url>
+ </repository>
+ <snapshotRepository>
+ <id>snapshots</id>
+ <name>Maven Central Development Repository</name>
+ <url>scp://repo1.maven.org/home/projects/maven/repository-staging/snapshots/maven2</url>
+ </snapshotRepository>
+ <site>
+ <id>website</id>
+ <url>scp://minotaur.apache.org/www/maven.apache.org/maven2/</url>
+ </site>
+ </distributionManagement>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-clean-plugin/0.1/maven-clean-plugin-0.1.jar b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-clean-plugin/0.1/maven-clean-plugin-0.1.jar
new file mode 100644
index 00000000..ee01f101
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-clean-plugin/0.1/maven-clean-plugin-0.1.jar
Binary files differ
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-clean-plugin/0.1/maven-clean-plugin-0.1.pom b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-clean-plugin/0.1/maven-clean-plugin-0.1.pom
new file mode 100644
index 00000000..e4318d07
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-clean-plugin/0.1/maven-clean-plugin-0.1.pom
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-clean-plugin</artifactId>
+ <version>0.1</version>
+ <packaging>maven-plugin</packaging>
+
+ <name>Maven Integration Test Plugin</name>
+ <description>
+ A test plugin to assist testing of Maven core.
+ </description>
+ <inceptionYear>2009</inceptionYear>
+
+ <distributionManagement>
+ <repository>
+ <id>maven-core-it</id>
+ <url>file:///${basedir}/repo</url>
+ </repository>
+ </distributionManagement>
+
+ <properties>
+ <maven.test.skip>true</maven.test.skip>
+ <updateReleaseInfo>true</updateReleaseInfo>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-plugin-api</artifactId>
+ <version>2.0</version>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <resources>
+ <resource>
+ <directory>.</directory>
+ <includes>
+ <include>pom.xml</include>
+ <include>src/**</include>
+ </includes>
+ </resource>
+ <resource>
+ <directory>src/main/resources</directory>
+ </resource>
+ </resources>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-clean-plugin/maven-metadata.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-clean-plugin/maven-metadata.xml
new file mode 100644
index 00000000..91261b37
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-clean-plugin/maven-metadata.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<metadata>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-clean-plugin</artifactId>
+ <version>0.1</version>
+ <versioning>
+ <latest>0.1</latest>
+ <release>0.1</release>
+ <versions>
+ <version>0.1</version>
+ </versions>
+ <lastUpdated>20091023224342</lastUpdated>
+ </versioning>
+</metadata>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-compiler-plugin/0.1/maven-compiler-plugin-0.1.jar b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-compiler-plugin/0.1/maven-compiler-plugin-0.1.jar
new file mode 100644
index 00000000..e5ef4464
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-compiler-plugin/0.1/maven-compiler-plugin-0.1.jar
Binary files differ
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-compiler-plugin/0.1/maven-compiler-plugin-0.1.pom b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-compiler-plugin/0.1/maven-compiler-plugin-0.1.pom
new file mode 100644
index 00000000..22371630
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-compiler-plugin/0.1/maven-compiler-plugin-0.1.pom
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>0.1</version>
+ <packaging>maven-plugin</packaging>
+
+ <name>Maven Integration Test Plugin</name>
+ <description>
+ A test plugin to assist testing of Maven core.
+ </description>
+ <inceptionYear>2009</inceptionYear>
+
+ <distributionManagement>
+ <repository>
+ <id>maven-core-it</id>
+ <url>file:///${basedir}/repo</url>
+ </repository>
+ </distributionManagement>
+
+ <properties>
+ <maven.test.skip>true</maven.test.skip>
+ <updateReleaseInfo>true</updateReleaseInfo>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-plugin-api</artifactId>
+ <version>2.0</version>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <resources>
+ <resource>
+ <directory>.</directory>
+ <includes>
+ <include>pom.xml</include>
+ <include>src/**</include>
+ </includes>
+ </resource>
+ <resource>
+ <directory>src/main/resources</directory>
+ </resource>
+ </resources>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-compiler-plugin/maven-metadata.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-compiler-plugin/maven-metadata.xml
new file mode 100644
index 00000000..544f16ea
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-compiler-plugin/maven-metadata.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<metadata>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>0.1</version>
+ <versioning>
+ <latest>0.1</latest>
+ <release>0.1</release>
+ <versions>
+ <version>0.1</version>
+ </versions>
+ <lastUpdated>20091023224813</lastUpdated>
+ </versioning>
+</metadata>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-deploy-plugin/0.1/maven-deploy-plugin-0.1.jar b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-deploy-plugin/0.1/maven-deploy-plugin-0.1.jar
new file mode 100644
index 00000000..f2432a6d
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-deploy-plugin/0.1/maven-deploy-plugin-0.1.jar
Binary files differ
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-deploy-plugin/0.1/maven-deploy-plugin-0.1.pom b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-deploy-plugin/0.1/maven-deploy-plugin-0.1.pom
new file mode 100644
index 00000000..82ed5748
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-deploy-plugin/0.1/maven-deploy-plugin-0.1.pom
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-deploy-plugin</artifactId>
+ <version>0.1</version>
+ <packaging>maven-plugin</packaging>
+
+ <name>Maven Integration Test Plugin</name>
+ <description>
+ A test plugin to assist testing of Maven core.
+ </description>
+ <inceptionYear>2009</inceptionYear>
+
+ <distributionManagement>
+ <repository>
+ <id>maven-core-it</id>
+ <url>file:///${basedir}/repo</url>
+ </repository>
+ </distributionManagement>
+
+ <properties>
+ <maven.test.skip>true</maven.test.skip>
+ <updateReleaseInfo>true</updateReleaseInfo>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-plugin-api</artifactId>
+ <version>2.0</version>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <resources>
+ <resource>
+ <directory>.</directory>
+ <includes>
+ <include>pom.xml</include>
+ <include>src/**</include>
+ </includes>
+ </resource>
+ <resource>
+ <directory>src/main/resources</directory>
+ </resource>
+ </resources>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-deploy-plugin/maven-metadata.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-deploy-plugin/maven-metadata.xml
new file mode 100644
index 00000000..f0af94c7
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-deploy-plugin/maven-metadata.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<metadata>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-deploy-plugin</artifactId>
+ <version>0.1</version>
+ <versioning>
+ <latest>0.1</latest>
+ <release>0.1</release>
+ <versions>
+ <version>0.1</version>
+ </versions>
+ <lastUpdated>20091023224421</lastUpdated>
+ </versioning>
+</metadata>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-install-plugin/0.1/maven-install-plugin-0.1.jar b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-install-plugin/0.1/maven-install-plugin-0.1.jar
new file mode 100644
index 00000000..a6adb988
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-install-plugin/0.1/maven-install-plugin-0.1.jar
Binary files differ
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-install-plugin/0.1/maven-install-plugin-0.1.pom b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-install-plugin/0.1/maven-install-plugin-0.1.pom
new file mode 100644
index 00000000..1ce2bd06
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-install-plugin/0.1/maven-install-plugin-0.1.pom
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-install-plugin</artifactId>
+ <version>0.1</version>
+ <packaging>maven-plugin</packaging>
+
+ <name>Maven Integration Test Plugin</name>
+ <description>
+ A test plugin to assist testing of Maven core.
+ </description>
+ <inceptionYear>2009</inceptionYear>
+
+ <distributionManagement>
+ <repository>
+ <id>maven-core-it</id>
+ <url>file:///${basedir}/repo</url>
+ </repository>
+ </distributionManagement>
+
+ <properties>
+ <maven.test.skip>true</maven.test.skip>
+ <updateReleaseInfo>true</updateReleaseInfo>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-plugin-api</artifactId>
+ <version>2.0</version>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <resources>
+ <resource>
+ <directory>.</directory>
+ <includes>
+ <include>pom.xml</include>
+ <include>src/**</include>
+ </includes>
+ </resource>
+ <resource>
+ <directory>src/main/resources</directory>
+ </resource>
+ </resources>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-install-plugin/maven-metadata.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-install-plugin/maven-metadata.xml
new file mode 100644
index 00000000..bb528791
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-install-plugin/maven-metadata.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<metadata>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-install-plugin</artifactId>
+ <version>0.1</version>
+ <versioning>
+ <latest>0.1</latest>
+ <release>0.1</release>
+ <versions>
+ <version>0.1</version>
+ </versions>
+ <lastUpdated>20091023224444</lastUpdated>
+ </versioning>
+</metadata>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-jar-plugin/0.1/maven-jar-plugin-0.1.jar b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-jar-plugin/0.1/maven-jar-plugin-0.1.jar
new file mode 100644
index 00000000..0b03b350
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-jar-plugin/0.1/maven-jar-plugin-0.1.jar
Binary files differ
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-jar-plugin/0.1/maven-jar-plugin-0.1.pom b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-jar-plugin/0.1/maven-jar-plugin-0.1.pom
new file mode 100644
index 00000000..d8abdf6f
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-jar-plugin/0.1/maven-jar-plugin-0.1.pom
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <version>0.1</version>
+ <packaging>maven-plugin</packaging>
+
+ <name>Maven Integration Test Plugin</name>
+ <description>
+ A test plugin to assist testing of Maven core.
+ </description>
+ <inceptionYear>2009</inceptionYear>
+
+ <distributionManagement>
+ <repository>
+ <id>maven-core-it</id>
+ <url>file:///${basedir}/repo</url>
+ </repository>
+ </distributionManagement>
+
+ <properties>
+ <maven.test.skip>true</maven.test.skip>
+ <updateReleaseInfo>true</updateReleaseInfo>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-plugin-api</artifactId>
+ <version>2.0</version>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <resources>
+ <resource>
+ <directory>.</directory>
+ <includes>
+ <include>pom.xml</include>
+ <include>src/**</include>
+ </includes>
+ </resource>
+ <resource>
+ <directory>src/main/resources</directory>
+ </resource>
+ </resources>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-jar-plugin/maven-metadata.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-jar-plugin/maven-metadata.xml
new file mode 100644
index 00000000..6b734ad5
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-jar-plugin/maven-metadata.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<metadata>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <version>0.1</version>
+ <versioning>
+ <latest>0.1</latest>
+ <release>0.1</release>
+ <versions>
+ <version>0.1</version>
+ </versions>
+ <lastUpdated>20091023232454</lastUpdated>
+ </versioning>
+</metadata>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-metadata.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-metadata.xml
new file mode 100644
index 00000000..615714cc
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-metadata.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<metadata>
+ <plugins>
+ <plugin>
+ <name>Maven Integration Test Plugin</name>
+ <prefix>clean</prefix>
+ <artifactId>maven-clean-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <name>Maven Integration Test Plugin</name>
+ <prefix>deploy</prefix>
+ <artifactId>maven-deploy-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <name>Maven Integration Test Plugin</name>
+ <prefix>install</prefix>
+ <artifactId>maven-install-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <name>Maven Integration Test Plugin</name>
+ <prefix>jar</prefix>
+ <artifactId>maven-jar-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <name>Maven Integration Test Plugin</name>
+ <prefix>surefire</prefix>
+ <artifactId>maven-surefire-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <name>Maven Integration Test Plugin</name>
+ <prefix>compiler</prefix>
+ <artifactId>maven-compiler-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <name>Maven Integration Test Plugin</name>
+ <prefix>resources</prefix>
+ <artifactId>maven-resources-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <name>Maven Integration Test Plugin</name>
+ <prefix>plugin</prefix>
+ <artifactId>maven-plugin-plugin</artifactId>
+ </plugin>
+ </plugins>
+</metadata>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-plugin-plugin/0.1/maven-plugin-plugin-0.1.jar b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-plugin-plugin/0.1/maven-plugin-plugin-0.1.jar
new file mode 100644
index 00000000..e2eab46e
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-plugin-plugin/0.1/maven-plugin-plugin-0.1.jar
Binary files differ
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-plugin-plugin/0.1/maven-plugin-plugin-0.1.pom b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-plugin-plugin/0.1/maven-plugin-plugin-0.1.pom
new file mode 100644
index 00000000..7df6bdbc
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-plugin-plugin/0.1/maven-plugin-plugin-0.1.pom
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-plugin-plugin</artifactId>
+ <version>0.1</version>
+ <packaging>maven-plugin</packaging>
+
+ <name>Maven Integration Test Plugin</name>
+ <description>
+ A test plugin to assist testing of Maven core.
+ </description>
+ <inceptionYear>2009</inceptionYear>
+
+ <distributionManagement>
+ <repository>
+ <id>maven-core-it</id>
+ <url>file:///${basedir}/repo</url>
+ </repository>
+ </distributionManagement>
+
+ <properties>
+ <maven.test.skip>true</maven.test.skip>
+ <updateReleaseInfo>true</updateReleaseInfo>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-plugin-api</artifactId>
+ <version>2.0</version>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <resources>
+ <resource>
+ <directory>.</directory>
+ <includes>
+ <include>pom.xml</include>
+ <include>src/**</include>
+ </includes>
+ </resource>
+ <resource>
+ <directory>src/main/resources</directory>
+ </resource>
+ </resources>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-plugin-plugin/maven-metadata.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-plugin-plugin/maven-metadata.xml
new file mode 100644
index 00000000..4c29db7d
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-plugin-plugin/maven-metadata.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<metadata>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-plugin-plugin</artifactId>
+ <version>0.1</version>
+ <versioning>
+ <latest>0.1</latest>
+ <release>0.1</release>
+ <versions>
+ <version>0.1</version>
+ </versions>
+ <lastUpdated>20091023225046</lastUpdated>
+ </versioning>
+</metadata>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-resources-plugin/0.1/maven-resources-plugin-0.1.jar b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-resources-plugin/0.1/maven-resources-plugin-0.1.jar
new file mode 100644
index 00000000..ffa11df4
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-resources-plugin/0.1/maven-resources-plugin-0.1.jar
Binary files differ
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-resources-plugin/0.1/maven-resources-plugin-0.1.pom b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-resources-plugin/0.1/maven-resources-plugin-0.1.pom
new file mode 100644
index 00000000..782dbf7d
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-resources-plugin/0.1/maven-resources-plugin-0.1.pom
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-resources-plugin</artifactId>
+ <version>0.1</version>
+ <packaging>maven-plugin</packaging>
+
+ <name>Maven Integration Test Plugin</name>
+ <description>
+ A test plugin to assist testing of Maven core.
+ </description>
+ <inceptionYear>2009</inceptionYear>
+
+ <distributionManagement>
+ <repository>
+ <id>maven-core-it</id>
+ <url>file:///${basedir}/repo</url>
+ </repository>
+ </distributionManagement>
+
+ <properties>
+ <maven.test.skip>true</maven.test.skip>
+ <updateReleaseInfo>true</updateReleaseInfo>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-plugin-api</artifactId>
+ <version>2.0</version>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <resources>
+ <resource>
+ <directory>.</directory>
+ <includes>
+ <include>pom.xml</include>
+ <include>src/**</include>
+ </includes>
+ </resource>
+ <resource>
+ <directory>src/main/resources</directory>
+ </resource>
+ </resources>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-resources-plugin/maven-metadata.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-resources-plugin/maven-metadata.xml
new file mode 100644
index 00000000..38c5503a
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-resources-plugin/maven-metadata.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<metadata>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-resources-plugin</artifactId>
+ <version>0.1</version>
+ <versioning>
+ <latest>0.1</latest>
+ <release>0.1</release>
+ <versions>
+ <version>0.1</version>
+ </versions>
+ <lastUpdated>20091023224958</lastUpdated>
+ </versioning>
+</metadata>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-surefire-plugin/0.1/maven-surefire-plugin-0.1.jar b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-surefire-plugin/0.1/maven-surefire-plugin-0.1.jar
new file mode 100644
index 00000000..989e5837
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-surefire-plugin/0.1/maven-surefire-plugin-0.1.jar
Binary files differ
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-surefire-plugin/0.1/maven-surefire-plugin-0.1.pom b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-surefire-plugin/0.1/maven-surefire-plugin-0.1.pom
new file mode 100644
index 00000000..3588a043
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-surefire-plugin/0.1/maven-surefire-plugin-0.1.pom
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>0.1</version>
+ <packaging>maven-plugin</packaging>
+
+ <name>Maven Integration Test Plugin</name>
+ <description>
+ A test plugin to assist testing of Maven core.
+ </description>
+ <inceptionYear>2009</inceptionYear>
+
+ <distributionManagement>
+ <repository>
+ <id>maven-core-it</id>
+ <url>file:///${basedir}/repo</url>
+ </repository>
+ </distributionManagement>
+
+ <properties>
+ <maven.test.skip>true</maven.test.skip>
+ <updateReleaseInfo>true</updateReleaseInfo>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-plugin-api</artifactId>
+ <version>2.0</version>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <resources>
+ <resource>
+ <directory>.</directory>
+ <includes>
+ <include>pom.xml</include>
+ <include>src/**</include>
+ </includes>
+ </resource>
+ <resource>
+ <directory>src/main/resources</directory>
+ </resource>
+ </resources>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-surefire-plugin/maven-metadata.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-surefire-plugin/maven-metadata.xml
new file mode 100644
index 00000000..c6d1df93
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/apache/maven/plugins/maven-surefire-plugin/maven-metadata.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<metadata>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>0.1</version>
+ <versioning>
+ <latest>0.1</latest>
+ <release>0.1</release>
+ <versions>
+ <version>0.1</version>
+ </versions>
+ <lastUpdated>20091023225125</lastUpdated>
+ </versioning>
+</metadata>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/codehaus/plexus/plexus-utils/1.1/plexus-utils-1.1.jar b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/codehaus/plexus/plexus-utils/1.1/plexus-utils-1.1.jar
new file mode 100644
index 00000000..5c50e177
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/codehaus/plexus/plexus-utils/1.1/plexus-utils-1.1.jar
Binary files differ
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/codehaus/plexus/plexus-utils/1.1/plexus-utils-1.1.pom b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/codehaus/plexus/plexus-utils/1.1/plexus-utils-1.1.pom
new file mode 100644
index 00000000..6cf90799
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/remote-repo/org/codehaus/plexus/plexus-utils/1.1/plexus-utils-1.1.pom
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?><project>
+ <parent>
+ <artifactId>plexus</artifactId>
+ <groupId>org.codehaus.plexus</groupId>
+ <version>1.0.4</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>plexus-utils</artifactId>
+ <name>Plexus Common Utilities</name>
+ <version>1.1</version>
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <excludes>
+ <exclude>org/codehaus/plexus/util/FileBasedTestCase.java</exclude>
+ <exclude>**/Test*.java</exclude>
+ </excludes>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ <distributionManagement>
+ <status>deployed</status>
+ </distributionManagement>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/artifact-id-inheritance/child/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/artifact-id-inheritance/child/pom.xml
new file mode 100644
index 00000000..eee189d4
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/artifact-id-inheritance/child/pom.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.maven.its.mng</groupId>
+ <artifactId>parent</artifactId>
+ <version>0.1</version>
+ </parent>
+
+ <!-- while groupId and version are inherited, artifactId is not and must be specified -->
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/artifact-id-inheritance/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/artifact-id-inheritance/pom.xml
new file mode 100644
index 00000000..f22afbc0
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/artifact-id-inheritance/pom.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng</groupId>
+ <artifactId>parent</artifactId>
+ <version>0.1</version>
+ <packaging>pom</packaging>
+
+ <!--
+ NOTE: This extends the test to check an edge case of URL adjustment which must not error out during inheritance
+ if the child misses the artifactId (as to be reported by validation).
+ -->
+ <url>http://maven.apache.org/</url>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/basedir-aligned-interpolation/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/basedir-aligned-interpolation/pom.xml
new file mode 100644
index 00000000..1885fc48
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/basedir-aligned-interpolation/pom.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng3822</groupId>
+ <artifactId>test1</artifactId>
+ <version>1.0-SNAPSHOT</version>
+
+ <name>Maven Integration Test :: MNG-3822</name>
+ <description>
+ Verify that POM interpolation uses basedir-aligned build directories.
+ </description>
+
+ <properties>
+ <!-- this is where we collect all the interpolated values for the POM dump -->
+ <buildMainSrc>${project.build.sourceDirectory}</buildMainSrc>
+ <buildTestSrc>${project.build.testSourceDirectory}</buildTestSrc>
+ <buildScriptSrc>${project.build.scriptSourceDirectory}</buildScriptSrc>
+ <buildOut>${project.build.directory}</buildOut>
+ <buildMainOut>${project.build.outputDirectory}</buildMainOut>
+ <buildTestOut>${project.build.testOutputDirectory}</buildTestOut>
+ <siteOut>${project.reporting.outputDirectory}</siteOut>
+ </properties>
+
+ <build>
+ <!--
+ NOTE: Deliberately set all build directories to relative paths to ensure they really need basedir alignment.
+ -->
+ <sourceDirectory>src/main/java</sourceDirectory>
+ <testSourceDirectory>src/test/java</testSourceDirectory>
+ <scriptSourceDirectory>src/main/scripts</scriptSourceDirectory>
+ <directory>target</directory>
+ <outputDirectory>target/classes</outputDirectory>
+ <testOutputDirectory>target/test-classes</testOutputDirectory>
+ </build>
+
+ <reporting>
+ <outputDirectory>target/site</outputDirectory>
+ </reporting>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/basedir-interpolation/pom-with-unusual-name.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/basedir-interpolation/pom-with-unusual-name.xml
new file mode 100644
index 00000000..1c037e63
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/basedir-interpolation/pom-with-unusual-name.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng3944</groupId>
+ <artifactId>test1</artifactId>
+ <version>1.0-SNAPSHOT</version>
+
+ <name>Maven Integration Test :: MNG-3944</name>
+ <description>
+ Test that interpolation of ${basedir} works for a POM that is not named "pom.xml"
+ </description>
+
+ <properties>
+ <!-- this is where we collect all the interpolated values for the POM dump -->
+ <prop0>${basedir}</prop0>
+ <prop1>${project.basedir}</prop1>
+ </properties>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/baseurl-interpolation/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/baseurl-interpolation/pom.xml
new file mode 100644
index 00000000..f1d4e6ca
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/baseurl-interpolation/pom.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng3760</groupId>
+ <artifactId>test1</artifactId>
+ <version>1.0-SNAPSHOT</version>
+
+ <name>Maven Integration Test :: MNG-3760</name>
+ <description>
+ Test interpolation of ${project.baseUri}
+ </description>
+
+ <properties>
+ <!-- this is where we collect all the interpolated values for the POM dump -->
+ <prop1>${project.baseUri}</prop1>
+ </properties>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/boolean-interpolation/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/boolean-interpolation/pom.xml
new file mode 100644
index 00000000..992eac1e
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/boolean-interpolation/pom.xml
@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng1995</groupId>
+ <artifactId>test1</artifactId>
+ <version>1.0</version>
+
+ <name>Maven Integration Test :: MNG-1995</name>
+ <description>
+ Verify that POM fields that are of type boolean can be interpolated with expressions.
+ </description>
+
+ <properties>
+ <filter.resources>true</filter.resources>
+ <releasesEnabled>true</releasesEnabled>
+ </properties>
+
+ <repositories>
+ <repository>
+ <id>maven-core-it</id>
+ <url>file:///${basedir}/repo</url>
+ <releases>
+ <!-- That's the boolean POM field we would like to interpolate -->
+ <enabled>${releasesEnabled}</enabled>
+ </releases>
+ </repository>
+ </repositories>
+
+ <build>
+ <resources>
+ <resource>
+ <directory>src/main/resources</directory>
+ <!-- That's the boolean POM field we would like to interpolate -->
+ <filtering>${filter.resources}</filtering>
+ </resource>
+ </resources>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-expression</artifactId>
+ <version>2.1-SNAPSHOT</version>
+ <configuration>
+ <outputFile>target/expression.properties</outputFile>
+ <expressions>
+ <expression>project/build/resources/0/filtering</expression>
+ <expression>project/repositories</expression>
+ </expressions>
+ </configuration>
+ <executions>
+ <execution>
+ <id>test</id>
+ <phase>validate</phase>
+ <goals>
+ <goal>eval</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/build-extension-inheritance/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/build-extension-inheritance/pom.xml
new file mode 100644
index 00000000..262af4fb
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/build-extension-inheritance/pom.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng3899</groupId>
+ <artifactId>parent</artifactId>
+ <version>0.1</version>
+ <packaging>pom</packaging>
+
+ <name>Maven Integration Test :: MNG-3899</name>
+ <description>
+ Test that build extensions are properly merged during inheritance.
+ </description>
+
+ <build>
+ <extensions>
+ <extension>
+ <groupId>org.apache.maven.its.mng3899</groupId>
+ <artifactId>a</artifactId>
+ <version>0.1</version>
+ </extension>
+ <extension>
+ <groupId>org.apache.maven.its.mng3899</groupId>
+ <artifactId>c</artifactId>
+ <version>0.1</version>
+ </extension>
+ </extensions>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/build-extension-inheritance/sub/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/build-extension-inheritance/sub/pom.xml
new file mode 100644
index 00000000..dc8f6f5b
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/build-extension-inheritance/sub/pom.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.maven.its.mng3899</groupId>
+ <artifactId>parent</artifactId>
+ <version>0.1</version>
+ </parent>
+
+ <artifactId>child</artifactId>
+
+ <name>Maven Integration Test :: MNG-3899</name>
+ <description>
+ Test that build extensions are properly merged during inheritance.
+ </description>
+
+ <build>
+ <!-- project extensions should precede inherited extensions -->
+ <extensions>
+ <extension>
+ <groupId>org.apache.maven.its.mng3899</groupId>
+ <artifactId>b</artifactId>
+ <version>0.1</version>
+ </extension>
+ <extension>
+ <!-- project extensions should override inherited extension with equal gid:aid -->
+ <groupId>org.apache.maven.its.mng3899</groupId>
+ <artifactId>a</artifactId>
+ <version>0.2</version>
+ </extension>
+ </extensions>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-expression</artifactId>
+ <version>2.1-SNAPSHOT</version>
+ <executions>
+ <execution>
+ <phase>validate</phase>
+ <goals>
+ <goal>eval</goal>
+ </goals>
+ <configuration>
+ <outputFile>target/extension.properties</outputFile>
+ <expressions>
+ <expression>project/build/extensions</expression>
+ </expressions>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/complete-model/w-parent/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/complete-model/w-parent/pom.xml
new file mode 100644
index 00000000..ebcd7d1e
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/complete-model/w-parent/pom.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng</groupId>
+ <artifactId>parent</artifactId>
+ <version>0.1</version>
+ <packaging>pom</packaging>
+
+ <!-- minimal parent just to have one more level of inheritance -->
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/complete-model/w-parent/sub/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/complete-model/w-parent/sub/pom.xml
new file mode 100644
index 00000000..68ca28dd
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/complete-model/w-parent/sub/pom.xml
@@ -0,0 +1,319 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.maven.its.mng</groupId>
+ <artifactId>parent</artifactId>
+ <version>0.1</version>
+ </parent>
+
+ <groupId>org.apache.maven.its.mng</groupId>
+ <artifactId>test</artifactId>
+ <version>0.2</version>
+ <packaging>pom</packaging>
+
+ <name>project-name</name>
+ <description>project-description</description>
+ <url>http://project.url/</url>
+ <inceptionYear>2009</inceptionYear>
+ <organization>
+ <name>project-org</name>
+ <url>http://project-org.url/</url>
+ </organization>
+ <licenses>
+ <license>
+ <name>project-license</name>
+ <url>http://project.url/license</url>
+ <distribution>repo</distribution>
+ <comments>free</comments>
+ </license>
+ </licenses>
+
+ <developers>
+ <developer>
+ <id>dev</id>
+ <name>project-developer</name>
+ <email>developer@</email>
+ <url>http://developer</url>
+ <organization>developer</organization>
+ <organizationUrl>http://devel.org</organizationUrl>
+ <roles>
+ <role>devel</role>
+ </roles>
+ <timezone>-1</timezone>
+ <properties>
+ <developer>yes</developer>
+ </properties>
+ </developer>
+ </developers>
+ <contributors>
+ <contributor>
+ <name>project-contributor</name>
+ <email>contributor@</email>
+ <url>http://contributor</url>
+ <organization>contributor</organization>
+ <organizationUrl>http://contrib.org</organizationUrl>
+ <roles>
+ <role>contrib</role>
+ </roles>
+ <timezone>+1</timezone>
+ <properties>
+ <contributor>yes</contributor>
+ </properties>
+ </contributor>
+ </contributors>
+
+ <mailingLists>
+ <mailingList>
+ <name>project-mailing-list</name>
+ <subscribe>subscribe@</subscribe>
+ <unsubscribe>unsubscribe@</unsubscribe>
+ <post>post@</post>
+ <archive>mail-archive</archive>
+ <otherArchives>
+ <otherArchive>other-archive</otherArchive>
+ </otherArchives>
+ </mailingList>
+ </mailingLists>
+
+ <prerequisites>
+ <maven>2.0.1</maven>
+ </prerequisites>
+
+ <scm>
+ <url>http://project.url/trunk</url>
+ <connection>http://project.url/scm</connection>
+ <developerConnection>https://project.url/scm</developerConnection>
+ <tag>TAG</tag>
+ </scm>
+ <issueManagement>
+ <system>issues</system>
+ <url>http://project.url/issues</url>
+ </issueManagement>
+ <ciManagement>
+ <system>ci</system>
+ <url>http://project.url/ci</url>
+ <notifiers>
+ <notifier>
+ <type>irc</type>
+ <address>ci@</address>
+ <sendOnError>true</sendOnError>
+ <sendOnFailure>false</sendOnFailure>
+ <sendOnSuccess>false</sendOnSuccess>
+ <sendOnWarning>false</sendOnWarning>
+ <configuration>
+ <ciProp>ci</ciProp>
+ </configuration>
+ </notifier>
+ </notifiers>
+ </ciManagement>
+ <distributionManagement>
+ <repository>
+ <url>http://project.url/dist</url>
+ <id>project.distros</id>
+ <name>distros</name>
+ </repository>
+ <snapshotRepository>
+ <url>http://project.url/snaps</url>
+ <id>project.snaps</id>
+ <name>snaps</name>
+ <uniqueVersion>false</uniqueVersion>
+ </snapshotRepository>
+ <site>
+ <url>http://project.url/site</url>
+ <id>project.site</id>
+ <name>docs</name>
+ </site>
+ <downloadUrl>http://project.url/download</downloadUrl>
+ <relocation>
+ <groupId>reloc-gid</groupId>
+ <artifactId>reloc-aid</artifactId>
+ <version>reloc-version</version>
+ <message>project-reloc-msg</message>
+ </relocation>
+ </distributionManagement>
+
+ <modules>
+ <module>sub</module>
+ </modules>
+
+ <properties>
+ <itProperty>project-property</itProperty>
+ </properties>
+
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven.its</groupId>
+ <artifactId>managed-dep</artifactId>
+ <version>0.1</version>
+ <type>war</type>
+ <scope>runtime</scope>
+ <exclusions>
+ <exclusion>
+ <groupId>org.apache.maven.its</groupId>
+ <artifactId>excluded-managed-dep</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven.its</groupId>
+ <artifactId>dep</artifactId>
+ <version>0.2</version>
+ <type>ejb</type>
+ <scope>test</scope>
+ <optional>true</optional>
+ <exclusions>
+ <exclusion>
+ <groupId>org.apache.maven.its</groupId>
+ <artifactId>excluded-dep</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ </dependencies>
+
+ <repositories>
+ <repository>
+ <id>project-remote-repo</id>
+ <url>http://project.url/remote</url>
+ <name>repo</name>
+ </repository>
+ </repositories>
+
+ <build>
+ <extensions>
+ <extension>
+ <groupId>org.apache.maven.its.ext</groupId>
+ <artifactId>ext</artifactId>
+ <version>3.0</version>
+ </extension>
+ </extensions>
+
+ <defaultGoal>test</defaultGoal>
+ <directory>build</directory>
+ <sourceDirectory>sources/main</sourceDirectory>
+ <scriptSourceDirectory>sources/scripts</scriptSourceDirectory>
+ <testSourceDirectory>sources/test</testSourceDirectory>
+ <outputDirectory>build/main</outputDirectory>
+ <testOutputDirectory>build/test</testOutputDirectory>
+ <finalName>coreit</finalName>
+ <resources>
+ <resource>
+ <directory>res/main</directory>
+ <filtering>true</filtering>
+ <targetPath>main</targetPath>
+ <includes>
+ <include>main.included</include>
+ </includes>
+ <excludes>
+ <exclude>main.excluded</exclude>
+ </excludes>
+ </resource>
+ </resources>
+ <testResources>
+ <testResource>
+ <directory>res/test</directory>
+ <filtering>true</filtering>
+ <targetPath>test</targetPath>
+ <includes>
+ <include>test.included</include>
+ </includes>
+ <excludes>
+ <exclude>test.excluded</exclude>
+ </excludes>
+ </testResource>
+ </testResources>
+ <filters>
+ <filter>src/main/filter/it.properties</filter>
+ </filters>
+
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-build</artifactId>
+ <version>2.1-SNAPSHOT</version>
+ <configuration>
+ <outputFile>test.properties</outputFile>
+ </configuration>
+ <executions>
+ <execution>
+ <id>test</id>
+ <phase>validate</phase>
+ <goals>
+ <goal>eval</goal>
+ </goals>
+ <configuration>
+ <outputFile>pom.properties</outputFile>
+ </configuration>
+ </execution>
+ </executions>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven.its</groupId>
+ <artifactId>build-plugin-dep</artifactId>
+ <version>0.3</version>
+ <type>zip</type>
+ <exclusions>
+ <exclusion>
+ <groupId>org.apache.maven.its</groupId>
+ <artifactId>excluded-build-plugin-dep</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ </dependencies>
+ </plugin>
+ </plugins>
+ </build>
+
+ <reporting>
+ <excludeDefaults>true</excludeDefaults>
+ <outputDirectory>docs</outputDirectory>
+
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-reporting</artifactId>
+ <version>2.0-SNAPSHOT</version>
+ <configuration>
+ <outputFile>test.html</outputFile>
+ </configuration>
+ <reportSets>
+ <reportSet>
+ <id>it</id>
+ <reports>
+ <report>run</report>
+ </reports>
+ <configuration>
+ <outputFile>index.html</outputFile>
+ </configuration>
+ </reportSet>
+ </reportSets>
+ </plugin>
+ </plugins>
+ </reporting>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/complete-model/wo-parent/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/complete-model/wo-parent/pom.xml
new file mode 100644
index 00000000..7b1ad794
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/complete-model/wo-parent/pom.xml
@@ -0,0 +1,313 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng</groupId>
+ <artifactId>test</artifactId>
+ <version>0.2</version>
+ <packaging>pom</packaging>
+
+ <name>project-name</name>
+ <description>project-description</description>
+ <url>http://project.url/</url>
+ <inceptionYear>2009</inceptionYear>
+ <organization>
+ <name>project-org</name>
+ <url>http://project-org.url/</url>
+ </organization>
+ <licenses>
+ <license>
+ <name>project-license</name>
+ <url>http://project.url/license</url>
+ <distribution>repo</distribution>
+ <comments>free</comments>
+ </license>
+ </licenses>
+
+ <developers>
+ <developer>
+ <id>dev</id>
+ <name>project-developer</name>
+ <email>developer@</email>
+ <url>http://developer</url>
+ <organization>developer</organization>
+ <organizationUrl>http://devel.org</organizationUrl>
+ <roles>
+ <role>devel</role>
+ </roles>
+ <timezone>-1</timezone>
+ <properties>
+ <developer>yes</developer>
+ </properties>
+ </developer>
+ </developers>
+ <contributors>
+ <contributor>
+ <name>project-contributor</name>
+ <email>contributor@</email>
+ <url>http://contributor</url>
+ <organization>contributor</organization>
+ <organizationUrl>http://contrib.org</organizationUrl>
+ <roles>
+ <role>contrib</role>
+ </roles>
+ <timezone>+1</timezone>
+ <properties>
+ <contributor>yes</contributor>
+ </properties>
+ </contributor>
+ </contributors>
+
+ <mailingLists>
+ <mailingList>
+ <name>project-mailing-list</name>
+ <subscribe>subscribe@</subscribe>
+ <unsubscribe>unsubscribe@</unsubscribe>
+ <post>post@</post>
+ <archive>mail-archive</archive>
+ <otherArchives>
+ <otherArchive>other-archive</otherArchive>
+ </otherArchives>
+ </mailingList>
+ </mailingLists>
+
+ <prerequisites>
+ <maven>2.0.1</maven>
+ </prerequisites>
+
+ <scm>
+ <url>http://project.url/trunk</url>
+ <connection>http://project.url/scm</connection>
+ <developerConnection>https://project.url/scm</developerConnection>
+ <tag>TAG</tag>
+ </scm>
+ <issueManagement>
+ <system>issues</system>
+ <url>http://project.url/issues</url>
+ </issueManagement>
+ <ciManagement>
+ <system>ci</system>
+ <url>http://project.url/ci</url>
+ <notifiers>
+ <notifier>
+ <type>irc</type>
+ <address>ci@</address>
+ <sendOnError>true</sendOnError>
+ <sendOnFailure>false</sendOnFailure>
+ <sendOnSuccess>false</sendOnSuccess>
+ <sendOnWarning>false</sendOnWarning>
+ <configuration>
+ <ciProp>ci</ciProp>
+ </configuration>
+ </notifier>
+ </notifiers>
+ </ciManagement>
+ <distributionManagement>
+ <repository>
+ <url>http://project.url/dist</url>
+ <id>project.distros</id>
+ <name>distros</name>
+ </repository>
+ <snapshotRepository>
+ <url>http://project.url/snaps</url>
+ <id>project.snaps</id>
+ <name>snaps</name>
+ <uniqueVersion>false</uniqueVersion>
+ </snapshotRepository>
+ <site>
+ <url>http://project.url/site</url>
+ <id>project.site</id>
+ <name>docs</name>
+ </site>
+ <downloadUrl>http://project.url/download</downloadUrl>
+ <relocation>
+ <groupId>reloc-gid</groupId>
+ <artifactId>reloc-aid</artifactId>
+ <version>reloc-version</version>
+ <message>project-reloc-msg</message>
+ </relocation>
+ </distributionManagement>
+
+ <modules>
+ <module>sub</module>
+ </modules>
+
+ <properties>
+ <itProperty>project-property</itProperty>
+ </properties>
+
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven.its</groupId>
+ <artifactId>managed-dep</artifactId>
+ <version>0.1</version>
+ <type>war</type>
+ <scope>runtime</scope>
+ <exclusions>
+ <exclusion>
+ <groupId>org.apache.maven.its</groupId>
+ <artifactId>excluded-managed-dep</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven.its</groupId>
+ <artifactId>dep</artifactId>
+ <version>0.2</version>
+ <type>ejb</type>
+ <scope>test</scope>
+ <optional>true</optional>
+ <exclusions>
+ <exclusion>
+ <groupId>org.apache.maven.its</groupId>
+ <artifactId>excluded-dep</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ </dependencies>
+
+ <repositories>
+ <repository>
+ <id>project-remote-repo</id>
+ <url>http://project.url/remote</url>
+ <name>repo</name>
+ </repository>
+ </repositories>
+
+ <build>
+ <extensions>
+ <extension>
+ <groupId>org.apache.maven.its.ext</groupId>
+ <artifactId>ext</artifactId>
+ <version>3.0</version>
+ </extension>
+ </extensions>
+
+ <defaultGoal>test</defaultGoal>
+ <directory>build</directory>
+ <sourceDirectory>sources/main</sourceDirectory>
+ <scriptSourceDirectory>sources/scripts</scriptSourceDirectory>
+ <testSourceDirectory>sources/test</testSourceDirectory>
+ <outputDirectory>build/main</outputDirectory>
+ <testOutputDirectory>build/test</testOutputDirectory>
+ <finalName>coreit</finalName>
+ <resources>
+ <resource>
+ <directory>res/main</directory>
+ <filtering>true</filtering>
+ <targetPath>main</targetPath>
+ <includes>
+ <include>main.included</include>
+ </includes>
+ <excludes>
+ <exclude>main.excluded</exclude>
+ </excludes>
+ </resource>
+ </resources>
+ <testResources>
+ <testResource>
+ <directory>res/test</directory>
+ <filtering>true</filtering>
+ <targetPath>test</targetPath>
+ <includes>
+ <include>test.included</include>
+ </includes>
+ <excludes>
+ <exclude>test.excluded</exclude>
+ </excludes>
+ </testResource>
+ </testResources>
+ <filters>
+ <filter>src/main/filter/it.properties</filter>
+ </filters>
+
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-build</artifactId>
+ <version>2.1-SNAPSHOT</version>
+ <configuration>
+ <outputFile>test.properties</outputFile>
+ </configuration>
+ <executions>
+ <execution>
+ <id>test</id>
+ <phase>validate</phase>
+ <goals>
+ <goal>eval</goal>
+ </goals>
+ <configuration>
+ <outputFile>pom.properties</outputFile>
+ </configuration>
+ </execution>
+ </executions>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven.its</groupId>
+ <artifactId>build-plugin-dep</artifactId>
+ <version>0.3</version>
+ <type>zip</type>
+ <exclusions>
+ <exclusion>
+ <groupId>org.apache.maven.its</groupId>
+ <artifactId>excluded-build-plugin-dep</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ </dependencies>
+ </plugin>
+ </plugins>
+ </build>
+
+ <reporting>
+ <excludeDefaults>true</excludeDefaults>
+ <outputDirectory>docs</outputDirectory>
+
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-reporting</artifactId>
+ <version>2.0-SNAPSHOT</version>
+ <configuration>
+ <outputFile>test.html</outputFile>
+ </configuration>
+ <reportSets>
+ <reportSet>
+ <id>it</id>
+ <reports>
+ <report>run</report>
+ </reports>
+ <configuration>
+ <outputFile>index.html</outputFile>
+ </configuration>
+ </reportSet>
+ </reportSets>
+ </plugin>
+ </plugins>
+ </reporting>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/config-with-plugin-mng/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/config-with-plugin-mng/pom.xml
new file mode 100644
index 00000000..e13c8a89
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/config-with-plugin-mng/pom.xml
@@ -0,0 +1,39 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.sonatype.nexus</groupId>
+ <artifactId>nexus</artifactId>
+ <version>1.3.0-SNAPSHOT</version>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.modello</groupId>
+ <artifactId>modello-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>nexus.xml</id>
+ <configuration>
+ <version>1.0.8</version>
+ </configuration>
+ </execution>
+ <execution>
+ <id>security.xml</id>
+ <configuration>
+ <version>1.0.0</version>
+ <model>src/main/mdo/security.xml</model>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.modello</groupId>
+ <artifactId>modello-maven-plugin</artifactId>
+ <version>1.0-alpha-21</version>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/consecutive_empty_elements/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/consecutive_empty_elements/pom.xml
new file mode 100644
index 00000000..16d1968f
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/consecutive_empty_elements/pom.xml
@@ -0,0 +1,14 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>test</groupId>
+ <artifactId>artifact</artifactId>
+ <version>1.0</version>
+
+ <developers>
+ <developer>
+ <organization/>
+ <organizationUrl/>
+ </developer>
+ </developers>
+
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/contributors-inheritance/child-2/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/contributors-inheritance/child-2/pom.xml
new file mode 100644
index 00000000..745289fd
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/contributors-inheritance/child-2/pom.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <!--
+ While <contributors> are inherited, they are not aggregated, only the child elements are used.
+ -->
+
+ <parent>
+ <groupId>org.apache.maven.its.mng3843</groupId>
+ <artifactId>parent-1</artifactId>
+ <version>0.1</version>
+ </parent>
+
+ <groupId>org.apache.maven.its.mng3843.child</groupId>
+ <artifactId>child-2</artifactId>
+ <version>0.2</version>
+ <packaging>jar</packaging>
+
+ <contributors>
+ <contributor>
+ <name>child-contributor</name>
+ </contributor>
+ </contributors>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/contributors-inheritance/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/contributors-inheritance/pom.xml
new file mode 100644
index 00000000..1f65eb5f
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/contributors-inheritance/pom.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng3843</groupId>
+ <artifactId>parent-1</artifactId>
+ <version>0.1</version>
+ <packaging>pom</packaging>
+
+ <contributors>
+ <contributor>
+ <name>parent-contributor</name>
+ </contributor>
+ </contributors>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/dependency-inheritance/maven-parent.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/dependency-inheritance/maven-parent.xml
new file mode 100644
index 00000000..6d642626
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/dependency-inheritance/maven-parent.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-parent</artifactId>
+ <version>11</version>
+ <packaging>pom</packaging>
+
+ <name>Apache Maven</name>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/dependency-inheritance/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/dependency-inheritance/pom.xml
new file mode 100644
index 00000000..c2c061c3
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/dependency-inheritance/pom.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-parent</artifactId>
+ <version>11</version>
+ <relativePath>maven-parent.xml</relativePath>
+ </parent>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven</artifactId>
+ <version>3.0-SNAPSHOT</version>
+ <packaging>pom</packaging>
+
+ <properties>
+ <junitVersion>3.8.1</junitVersion>
+ </properties>
+ <!--start-->
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>${junitVersion}</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+ <!--end-->
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/dependency-inheritance/sub/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/dependency-inheritance/sub/pom.xml
new file mode 100644
index 00000000..788c5a72
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/dependency-inheritance/sub/pom.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+ <!--
+ Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE
+ file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by
+ applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language
+ governing permissions and limitations under the License.
+ -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <parent>
+ <artifactId>maven</artifactId>
+ <groupId>org.apache.maven</groupId>
+ <version>3.0-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-project-builder</artifactId>
+ <version>3.0-SNAPSHOT</version>
+ <name>Maven Project Builder</name>
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.4</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/dependency-management-with-interpolation/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/dependency-management-with-interpolation/pom.xml
new file mode 100644
index 00000000..49ffab5a
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/dependency-management-with-interpolation/pom.xml
@@ -0,0 +1,19 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <artifactId>asm-parent</artifactId>
+ <groupId>asm</groupId>
+ <version>3.0</version>
+ <packaging>pom</packaging>
+
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <artifactId>asm-util</artifactId>
+ <groupId>${project.groupId}</groupId>
+ <version>${project.version}</version>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/dependency-management-with-interpolation/sub/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/dependency-management-with-interpolation/sub/pom.xml
new file mode 100644
index 00000000..2423568e
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/dependency-management-with-interpolation/sub/pom.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0"?><project>
+ <parent>
+ <artifactId>asm-parent</artifactId>
+ <groupId>asm</groupId>
+ <version>3.0</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+
+ <artifactId>asm-xml</artifactId>
+ <version>3.0</version>
+ <dependencies>
+ <dependency>
+ <groupId>asm</groupId>
+ <artifactId>asm-util</artifactId>
+ </dependency>
+ </dependencies>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/dependency-order/w-plugin-mngt/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/dependency-order/w-plugin-mngt/pom.xml
new file mode 100644
index 00000000..5882ab5c
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/dependency-order/w-plugin-mngt/pom.xml
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng4003</groupId>
+ <artifactId>test</artifactId>
+ <version>1.0-SNAPSHOT</version>
+
+ <name>Maven Integration Test :: MNG-4003</name>
+ <description>
+ Verify that dependencies survive the project construction in the POM order.
+ </description>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven.its.mng4003</groupId>
+ <artifactId>a</artifactId>
+ <version>1</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.its.mng4003</groupId>
+ <artifactId>c</artifactId>
+ <version>1</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.its.mng4003</groupId>
+ <artifactId>b</artifactId>
+ <version>1</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.its.mng4003</groupId>
+ <artifactId>d</artifactId>
+ <version>1</version>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <!-- NOTE: The combination with a plugin management section is an essential part of the test -->
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <artifactId>maven-clean-plugin</artifactId>
+ <version>2.3</version>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/dependency-order/wo-plugin-mngt/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/dependency-order/wo-plugin-mngt/pom.xml
new file mode 100644
index 00000000..57bd6d0f
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/dependency-order/wo-plugin-mngt/pom.xml
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng4003</groupId>
+ <artifactId>test</artifactId>
+ <version>1.0-SNAPSHOT</version>
+
+ <name>Maven Integration Test :: MNG-4003</name>
+ <description>
+ Verify that dependencies survive the project construction in the POM order.
+ </description>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven.its.mng4003</groupId>
+ <artifactId>a</artifactId>
+ <version>1</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.its.mng4003</groupId>
+ <artifactId>c</artifactId>
+ <version>1</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.its.mng4003</groupId>
+ <artifactId>b</artifactId>
+ <version>1</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.its.mng4003</groupId>
+ <artifactId>d</artifactId>
+ <version>1</version>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <!-- NOTE: The combination with a plugin section is an essential part of the test -->
+ <plugins>
+ <plugin>
+ <artifactId>maven-clean-plugin</artifactId>
+ <version>2.3</version>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/dependency-scope-inheritance/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/dependency-scope-inheritance/pom.xml
new file mode 100644
index 00000000..9f2ab958
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/dependency-scope-inheritance/pom.xml
@@ -0,0 +1,16 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>p0</artifactId>
+ <groupId>maven</groupId>
+ <version>1.0</version>
+ <packaging>pom</packaging>
+
+ <dependencies>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <version>1.0</version>
+ <artifactId>a</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/dependency-scope-inheritance/sub/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/dependency-scope-inheritance/sub/pom.xml
new file mode 100644
index 00000000..80c5570c
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/dependency-scope-inheritance/sub/pom.xml
@@ -0,0 +1,19 @@
+<project>
+ <parent>
+ <artifactId>p0</artifactId>
+ <groupId>maven</groupId>
+ <version>1.0</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven</groupId>
+ <artifactId>p1</artifactId>
+ <version>1.0</version>
+
+ <dependencies>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <version>1.0</version>
+ <artifactId>a</artifactId>
+ </dependency>
+ </dependencies>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/dependency-scope/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/dependency-scope/pom.xml
new file mode 100644
index 00000000..0f9ae5c6
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/dependency-scope/pom.xml
@@ -0,0 +1,18 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven-t10</groupId>
+ <artifactId>p0</artifactId>
+ <packaging>pom</packaging>
+ <name>p0</name>
+ <version>1.0</version>
+
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>t10-a</artifactId>
+ <version>2.0</version>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/dependency-scope/sub/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/dependency-scope/sub/pom.xml
new file mode 100644
index 00000000..8cec33d1
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/dependency-scope/sub/pom.xml
@@ -0,0 +1,24 @@
+<project>
+ <parent>
+ <artifactId>p0</artifactId>
+ <groupId>maven-t10</groupId>
+ <version>1.0</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven-t10</groupId>
+ <artifactId>p1</artifactId>
+ <packaging>pom</packaging>
+ <name>p1</name>
+ <version>1.0</version>
+ <scm>
+ <url>scm-url</url>
+ </scm>
+
+ <dependencies>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>t10-a</artifactId>
+ <version>1.0</version>
+ </dependency>
+ </dependencies>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/developers-inheritance/child-2/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/developers-inheritance/child-2/pom.xml
new file mode 100644
index 00000000..dad2375b
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/developers-inheritance/child-2/pom.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <!--
+ While <developers> are inherited, they are not aggregated, only the child elements are used.
+ -->
+
+ <parent>
+ <groupId>org.apache.maven.its.mng3843</groupId>
+ <artifactId>parent-1</artifactId>
+ <version>0.1</version>
+ </parent>
+
+ <groupId>org.apache.maven.its.mng3843.child</groupId>
+ <artifactId>child-2</artifactId>
+ <version>0.2</version>
+ <packaging>jar</packaging>
+
+ <developers>
+ <developer>
+ <name>child-developer</name>
+ </developer>
+ </developers>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/developers-inheritance/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/developers-inheritance/pom.xml
new file mode 100644
index 00000000..6e7c44d1
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/developers-inheritance/pom.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng3843</groupId>
+ <artifactId>parent-1</artifactId>
+ <version>0.1</version>
+ <packaging>pom</packaging>
+
+ <developers>
+ <developer>
+ <name>parent-developer</name>
+ </developer>
+ </developers>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/distribution-management/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/distribution-management/pom.xml
new file mode 100644
index 00000000..1a0acb08
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/distribution-management/pom.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.it0061</groupId>
+ <artifactId>maven-it-it0061</artifactId>
+ <version>1.0</version>
+ <packaging>jar</packaging>
+
+ <name>Maven Integration Test :: it0061</name>
+
+ <distributionManagement>
+ <repository>
+ <id>test</id>
+ <url>file:target/test-repo</url>
+ <layout>legacy</layout>
+ </repository>
+ </distributionManagement>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/dual-execution-ids/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/dual-execution-ids/pom.xml
new file mode 100644
index 00000000..8833c089
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/dual-execution-ids/pom.xml
@@ -0,0 +1,28 @@
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven.mercury</groupId>
+ <artifactId>mercury-parent</artifactId>
+ <version>1.0.0-alpha-3-SNAPSHOT</version>
+ <packaging>pom</packaging>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-remote-resources-plugin</artifactId>
+ <executions>
+ <execution>
+ <goals>
+ <goal>process</goal>
+ </goals>
+ <configuration>
+ <resourceBundles>
+ <resourceBundle>org.apache:apache-jar-resource-bundle:1.5</resourceBundle>
+ </resourceBundles>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/dual-execution-ids/sub/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/dual-execution-ids/sub/pom.xml
new file mode 100644
index 00000000..6ebd5994
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/dual-execution-ids/sub/pom.xml
@@ -0,0 +1,43 @@
+<project>
+
+<parent>
+ <artifactId>mercury-parent</artifactId>
+ <groupId>org.apache.maven.mercury</groupId>
+ <version>1.0.0-alpha-3-SNAPSHOT</version>
+</parent>
+
+<modelVersion>4.0.0</modelVersion>
+<groupId>org.apache.maven.mercury</groupId>
+<artifactId>mercury-util</artifactId>
+<name>Mercury Shared Utilities</name>
+<version>1.0.0-alpha-3-SNAPSHOT</version>
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <artifactId>maven-remote-resources-plugin</artifactId>
+ <version>1.0</version>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ <plugins>
+ <plugin>
+ <artifactId>maven-remote-resources-plugin</artifactId>
+ <version>1.0</version>
+ <executions>
+ <execution>
+ <id>default</id>
+ <goals>
+ <goal>process</goal>
+ </goals>
+ <configuration>
+ <resourceBundles>
+ <resourceBundle>org.apache:apache-jar-resource-bundle:1.4</resourceBundle>
+ </resourceBundles>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+</build>
+ </project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/duplicate-exclusions-dependency/nexus-parent.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/duplicate-exclusions-dependency/nexus-parent.xml
new file mode 100644
index 00000000..d2ac100c
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/duplicate-exclusions-dependency/nexus-parent.xml
@@ -0,0 +1,29 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.sonatype.nexus</groupId>
+ <artifactId>nexus-parent</artifactId>
+ <version>8-SNAPSHOT</version>
+ <packaging>pom</packaging>
+
+ <properties>
+ <plexus.version>1.0-beta-3.0.5-SNAPSHOT</plexus.version>
+ </properties>
+
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-container-default</artifactId>
+ <version>${plexus.version}</version>
+ <exclusions>
+ <exclusion>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging-api</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/duplicate-exclusions-dependency/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/duplicate-exclusions-dependency/pom.xml
new file mode 100644
index 00000000..b12db4f0
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/duplicate-exclusions-dependency/pom.xml
@@ -0,0 +1,33 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.sonatype.nexus</groupId>
+ <artifactId>nexus-parent</artifactId>
+ <version>8-SNAPSHOT</version>
+ <relativePath>nexus-parent.xml</relativePath>
+ </parent>
+
+ <groupId>org.sonatype.nexus</groupId>
+ <artifactId>nexus</artifactId>
+ <packaging>pom</packaging>
+ <name>Nexus Repository Manager</name>
+ <version>1.3.0-SNAPSHOT</version>
+
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-container-default</artifactId>
+ <scope>provided</scope>
+ <version>${plexus.version}</version>
+ <exclusions>
+ <exclusion>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging-api</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/duplicate-exclusions-dependency/sub/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/duplicate-exclusions-dependency/sub/pom.xml
new file mode 100644
index 00000000..37b166d1
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/duplicate-exclusions-dependency/sub/pom.xml
@@ -0,0 +1,16 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <parent>
+ <groupId>org.sonatype.nexus</groupId>
+ <artifactId>nexus</artifactId>
+ <version>1.3.0-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>nexus-proxy</artifactId>
+ <dependencies>
+ <!-- For App basic -->
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-container-default</artifactId>
+ </dependency>
+ </dependencies>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/empty-distMng-repo-url/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/empty-distMng-repo-url/pom.xml
new file mode 100644
index 00000000..91ce38df
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/empty-distMng-repo-url/pom.xml
@@ -0,0 +1,15 @@
+<project >
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-parent</artifactId>
+ <packaging>pom</packaging>
+ <version>11</version>
+
+ <distributionManagement>
+ <repository>
+ <id>dummy</id>
+ <name>Dummy to avoid accidental deploys</name>
+ <url />
+ </repository>
+ </distributionManagement>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/empty-scm/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/empty-scm/pom.xml
new file mode 100644
index 00000000..a0462ddd
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/empty-scm/pom.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <!--
+ This (almost) minimal POM tests direct inheritance from the super POM.
+ -->
+
+ <groupId>org.apache.maven.its.mng3843</groupId>
+ <artifactId>test-1</artifactId>
+ <version>0.1</version>
+
+ <name>test</name>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-expression</artifactId>
+ <version>2.1-SNAPSHOT</version>
+ <executions>
+ <execution>
+ <phase>validate</phase>
+ <goals>
+ <goal>eval</goal>
+ </goals>
+ <configuration>
+ <outputFile>target/pom.properties</outputFile>
+ <expressions>
+ <expression>project</expression>
+ </expressions>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/equal-plugin-deps/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/equal-plugin-deps/pom.xml
new file mode 100644
index 00000000..d33b2bae
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/equal-plugin-deps/pom.xml
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng3838</groupId>
+ <artifactId>test</artifactId>
+ <version>1.0-SNAPSHOT</version>
+
+ <name>Maven Integration Test :: MNG-3838</name>
+ <description>
+ Verify that using the same dependency for different plugins doesn't blow up the project builder.
+ </description>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-a</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <dependencies>
+ <!-- NOTE: That's exactly the same dependency as for the other plugin. -->
+ <dependency>
+ <groupId>org.apache.maven.its.mng3838</groupId>
+ <artifactId>dep</artifactId>
+ <version>123</version>
+ </dependency>
+ </dependencies>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-b</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <dependencies>
+ <!-- NOTE: That's exactly the same dependency as for the other plugin. -->
+ <dependency>
+ <groupId>org.apache.maven.its.mng3838</groupId>
+ <artifactId>dep</artifactId>
+ <version>123</version>
+ </dependency>
+ </dependencies>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/equal-plugin-exec-ids/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/equal-plugin-exec-ids/pom.xml
new file mode 100644
index 00000000..a05d45d0
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/equal-plugin-exec-ids/pom.xml
@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng3821</groupId>
+ <artifactId>test</artifactId>
+ <version>1.0-SNAPSHOT</version>
+
+ <name>Maven Integration Test :: MNG-3821</name>
+ <description>
+ Verify that using the same id for executions/reportsets of different plugins doesn't blow up the project builder.
+ </description>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-a</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <executions>
+ <execution>
+ <id>the-one-and-only-id</id>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-b</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <executions>
+ <execution>
+ <id>the-one-and-only-id</id>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+ <reporting>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-a</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <reportSets>
+ <reportSet>
+ <id>the-one-and-only-id</id>
+ </reportSet>
+ </reportSets>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-b</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <reportSets>
+ <reportSet>
+ <id>the-one-and-only-id</id>
+ </reportSet>
+ </reportSets>
+ </plugin>
+ </plugins>
+ </reporting>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/execution-configuration-join/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/execution-configuration-join/pom.xml
new file mode 100644
index 00000000..28defaa2
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/execution-configuration-join/pom.xml
@@ -0,0 +1,35 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.sonatype.nexus</groupId>
+ <artifactId>nexus</artifactId>
+ <version>1.3.0-SNAPSHOT</version>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.modello</groupId>
+ <artifactId>modello-maven-plugin</artifactId>
+ <version>1.0-alpha-21</version>
+ </plugin>
+ </plugins>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.modello</groupId>
+ <artifactId>modello-maven-plugin</artifactId>
+ <version>1.0-alpha-21</version>
+ <executions>
+ <execution>
+ <configuration>
+ <fileset dir="${basedir}">
+ <include name="LICENSE.txt" />
+ <include name="NOTICE.txt" />
+ </fileset>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/execution-configuration-subcollections/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/execution-configuration-subcollections/pom.xml
new file mode 100644
index 00000000..e5b19d4e
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/execution-configuration-subcollections/pom.xml
@@ -0,0 +1,42 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>test</groupId>
+ <artifactId>nexus</artifactId>
+ <packaging>pom</packaging>
+ <name>Nexus Repository Manager</name>
+ <version>1.1-M1</version>
+
+ <!-- build information for the project -->
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-enforcer-plugin</artifactId>
+ <version>1.0</version>
+ <executions>
+ <execution>
+ <goals>
+ <goal>enforce</goal>
+ </goals>
+ <id>enforce</id>
+ <configuration>
+ <rules>
+ <bannedDependencies>
+ <excludes>
+ <exclude>commons-logging:*</exclude>
+ </excludes>
+ <message>a</message>
+ </bannedDependencies>
+ <bannedDependencies>
+ <excludes>
+ <exclude>*:plexus-component-api</exclude>
+ </excludes>
+ </bannedDependencies>
+ </rules>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/execution-configuration/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/execution-configuration/pom.xml
new file mode 100644
index 00000000..130174d5
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/execution-configuration/pom.xml
@@ -0,0 +1,58 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.sonatype.nexus</groupId>
+ <artifactId>nexus</artifactId>
+ <version>1.3.0-SNAPSHOT</version>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.modello</groupId>
+ <artifactId>modello-maven-plugin</artifactId>
+ <version>1.0-alpha-21</version>
+ <executions>
+ <execution>
+ <id>nexus.xml</id>
+ <goals>
+ <goal>java</goal>
+ <goal>xpp3-reader</goal>
+ <goal>xpp3-writer</goal>
+ </goals>
+ <configuration>
+ <version>1.0.8</version>
+ <packagedVersions>
+ <packagedVersion>1.0.0</packagedVersion>
+ <packagedVersion>1.0.1</packagedVersion>
+ <packagedVersion>1.0.6</packagedVersion>
+ </packagedVersions>
+ <model>src/main/mdo/nexus.xml</model>
+ </configuration>
+ </execution>
+
+ <execution>
+ <id>security.xml</id>
+ <goals>
+ <goal>java1</goal>
+ <goal>xpp3-reader1</goal>
+ <goal>xpp3-writer1</goal>
+ </goals>
+ <configuration>
+ <version>1.0.0</version>
+ <model>src/main/mdo/security.xml</model>
+ </configuration>
+ </execution>
+
+ </executions>
+ </plugin>
+ </plugins>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.modello</groupId>
+ <artifactId>modello-maven-plugin</artifactId>
+ <version>1.0-alpha-21</version>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/foo/sub/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/foo/sub/pom.xml
new file mode 100644
index 00000000..c5e3d9a6
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/foo/sub/pom.xml
@@ -0,0 +1,418 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+ <!--
+ <parent>
+ <groupId>org.apache.maven.archetype</groupId>
+ <artifactId>maven-archetype</artifactId>
+ <version>2.0-alpha-1</version>
+ </parent>
+ -->
+ <artifactId>archetype-common</artifactId>
+ <name>Maven Archetype Common</name>
+ <packaging>jar</packaging>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>net.sourceforge.jchardet</groupId>
+ <artifactId>jchardet</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>dom4j</groupId>
+ <artifactId>dom4j</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>jdom</groupId>
+ <artifactId>jdom</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-model</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-project</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-container-default</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-utils</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.shared</groupId>
+ <artifactId>maven-plugin-testing-harness</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>commons-io</groupId>
+ <artifactId>commons-io</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-velocity</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>velocity</groupId>
+ <artifactId>velocity</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>dom4j</groupId>
+ <artifactId>dom4j</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>commons-collections</groupId>
+ <artifactId>commons-collections</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.cargo</groupId>
+ <artifactId>cargo-core-api-container</artifactId>
+ <version>0.9</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.cargo</groupId>
+ <artifactId>cargo-core-api-util</artifactId>
+ <version>0.9</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.cargo</groupId>
+ <artifactId>cargo-core-api-generic</artifactId>
+ <version>0.9</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.cargo</groupId>
+ <artifactId>cargo-core-api-module</artifactId>
+ <version>0.9</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.cargo</groupId>
+ <artifactId>cargo-core-container-jetty</artifactId>
+ <version>0.9</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.mortbay.jetty</groupId>
+ <artifactId>jetty</artifactId>
+ <version>6.1.4</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.wagon</groupId>
+ <artifactId>wagon-file</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.wagon</groupId>
+ <artifactId>wagon-http</artifactId>
+ <version>1.0-beta-2</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>archetype-repository</artifactId>
+ <version>${project.version}</version>
+ <type>war</type>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>archetype-proxy</artifactId>
+ <version>${project.version}</version>
+ <type>war</type>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <testResources>
+ <testResource>
+ <directory>src/test/resources</directory>
+ <filtering>true</filtering>
+ </testResource>
+ </testResources>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.modello</groupId>
+ <artifactId>modello-maven-plugin</artifactId>
+ <version>1.0-alpha-14</version>
+ <executions>
+ <execution>
+ <id>archetype-common</id>
+ <goals>
+ <goal>java</goal>
+ <goal>xsd</goal>
+ <goal>xpp3-reader</goal>
+ <goal>xpp3-writer</goal>
+ </goals>
+ <configuration>
+ <version>1.0.0</version>
+ <model>src/main/mdo/archetype-common.mdo</model>
+ </configuration>
+ </execution>
+ <execution>
+ <id>archetype-registry</id>
+ <goals>
+ <goal>java</goal>
+ <goal>xsd</goal>
+ <goal>xpp3-reader</goal>
+ <goal>xpp3-writer</goal>
+ </goals>
+ <configuration>
+ <version>1.0.0</version>
+ <model>src/main/mdo/archetype-registry.mdo</model>
+ </configuration>
+ </execution>
+ <execution>
+ <id>archetype-descriptor</id>
+ <goals>
+ <goal>java</goal>
+ <goal>xsd</goal>
+ <goal>xpp3-reader</goal>
+ <goal>xpp3-writer</goal>
+ </goals>
+ <configuration>
+ <version>1.0.0</version>
+ <model>src/main/mdo/archetype-descriptor.mdo</model>
+ </configuration>
+ </execution>
+ <execution>
+ <id>archetype-catalog</id>
+ <goals>
+ <goal>java</goal>
+ <goal>xsd</goal>
+ <goal>xpp3-reader</goal>
+ <goal>xpp3-writer</goal>
+ </goals>
+ <configuration>
+ <version>1.0.0</version>
+ <model>src/main/mdo/archetype-catalog.mdo</model>
+ </configuration>
+ </execution>
+ <execution>
+ <id>archetype-old</id>
+ <goals>
+ <goal>java</goal>
+ <goal>xsd</goal>
+ <goal>xpp3-reader</goal>
+ <goal>xpp3-writer</goal>
+ </goals>
+ <configuration>
+ <version>1.0.0</version>
+ <model>src/main/mdo/archetype.mdo</model>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>copy</id>
+ <phase>process-test-resources</phase>
+ <goals>
+ <goal>copy-dependencies</goal>
+ </goals>
+ <configuration>
+ <outputDirectory>${project.build.directory}/wars</outputDirectory>
+ <overWriteReleases>true</overWriteReleases>
+ <overWriteSnapshots>true</overWriteSnapshots>
+ <includeTypes>war</includeTypes>
+ <stripVersion>true</stripVersion>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-antrun-plugin</artifactId>
+ <dependencies>
+ <dependency>
+ <groupId>ant</groupId>
+ <artifactId>ant-antlr</artifactId>
+ <version>1.6.5</version>
+ </dependency>
+ </dependencies>
+
+ <executions>
+ <execution>
+ <id>archetype-test</id>
+ <phase>process-test-resources</phase>
+ <configuration>
+ <tasks>
+ <property name="test.projects.name" value="basic" />
+ <property name="test.projects.version" value="1.0" />
+ <property name="test.projects.archetype" value="${test.projects.name}-${test.projects.version}" />
+ <property name="test.projects.source.directory" value="${test.projects.archetype}" />
+ <property name="test.projects.target.directory" value="archetypes/${test.projects.name}/${test.projects.version}" />
+ <property name="test.projects.repository" value="repositories/central" />
+
+ <mkdir dir="${basedir}/target/test-classes/${test.projects.repository}/${test.projects.target.directory}/" />
+
+ <jar destfile="${basedir}/target/test-classes/${test.projects.repository}/${test.projects.target.directory}/${test.projects.archetype}.jar" basedir="${basedir}/src/test/archetypes/${test.projects.source.directory}/" />
+ </tasks>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+
+ <execution>
+ <id>archetype-test-partial</id>
+ <phase>process-test-resources</phase>
+ <configuration>
+ <tasks>
+ <property name="test.projects.name" value="partial" />
+ <property name="test.projects.version" value="1.0" />
+ <property name="test.projects.archetype" value="${test.projects.name}-${test.projects.version}" />
+ <property name="test.projects.source.directory" value="${test.projects.archetype}" />
+ <property name="test.projects.target.directory" value="archetypes/${test.projects.name}/${test.projects.version}" />
+ <property name="test.projects.repository" value="repositories/central" />
+ <mkdir dir="${basedir}/target/test-classes/${test.projects.repository}/${test.projects.target.directory}/" />
+
+ <jar destfile="${basedir}/target/test-classes/${test.projects.repository}/${test.projects.target.directory}/${test.projects.archetype}.jar" basedir="${basedir}/src/test/archetypes/${test.projects.source.directory}/" />
+ </tasks>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+
+ <execution>
+ <id>archetype-test-site</id>
+ <phase>process-test-resources</phase>
+ <configuration>
+ <tasks>
+ <property name="test.projects.name" value="site" />
+ <property name="test.projects.version" value="1.0" />
+ <property name="test.projects.archetype" value="${test.projects.name}-${test.projects.version}" />
+ <property name="test.projects.source.directory" value="${test.projects.archetype}" />
+ <property name="test.projects.target.directory" value="archetypes/${test.projects.name}/${test.projects.version}" />
+ <property name="test.projects.repository" value="repositories/central" />
+
+ <mkdir dir="${basedir}/target/test-classes/${test.projects.repository}/${test.projects.target.directory}/" />
+
+ <jar destfile="${basedir}/target/test-classes/${test.projects.repository}/${test.projects.target.directory}/${test.projects.archetype}.jar" basedir="${basedir}/src/test/archetypes/${test.projects.source.directory}/" />
+ </tasks>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+
+ <execution>
+ <id>archetype-test-old</id>
+ <phase>process-test-resources</phase>
+ <configuration>
+ <tasks>
+ <property name="test.projects.name" value="old" />
+ <property name="test.projects.version" value="1.0" />
+ <property name="test.projects.archetype" value="${test.projects.name}-${test.projects.version}" />
+ <property name="test.projects.source.directory" value="${test.projects.archetype}" />
+ <property name="test.projects.target.directory" value="archetypes/${test.projects.name}/${test.projects.version}" />
+ <property name="test.projects.repository" value="repositories/central" />
+
+ <mkdir dir="${basedir}/target/test-classes/${test.projects.repository}/${test.projects.target.directory}/" />
+
+ <jar destfile="${basedir}/target/test-classes/${test.projects.repository}/${test.projects.target.directory}/${test.projects.archetype}.jar" basedir="${basedir}/src/test/archetypes/${test.projects.source.directory}/" />
+ </tasks>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+
+ <execution>
+ <id>archetype-test-fileset</id>
+ <phase>process-test-resources</phase>
+ <configuration>
+ <tasks>
+ <property name="test.projects.name" value="fileset" />
+ <property name="test.projects.version" value="1.0" />
+ <property name="test.projects.archetype" value="${test.projects.name}-${test.projects.version}" />
+ <property name="test.projects.source.directory" value="${test.projects.archetype}" />
+ <property name="test.projects.target.directory" value="archetypes/${test.projects.name}/${test.projects.version}" />
+ <property name="test.projects.repository" value="repositories/central" />
+
+ <mkdir dir="${basedir}/target/test-classes/${test.projects.repository}/${test.projects.target.directory}/" />
+
+ <jar destfile="${basedir}/target/test-classes/${test.projects.repository}/${test.projects.target.directory}/${test.projects.archetype}.jar" basedir="${basedir}/src/test/archetypes/${test.projects.source.directory}/" />
+ </tasks>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+
+ <execution>
+ <id>repository-metadata</id>
+ <phase>process-test-resources</phase>
+ <configuration>
+ <tasks>
+ <property name="test.projects.source.directory" value="${test.projects.archetype}" />
+ <property name="test.projects.target.directory" value="archetypes" />
+ <property name="test.projects.repository" value="repositories/central" />
+
+ <mkdir dir="${basedir}/target/test-classes/${test.projects.repository}/${test.projects.target.directory}" />
+ </tasks>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <excludes>
+ <exclude>**/ArchetyperRoundtripTest.java</exclude>
+ <exclude>**/ArchetyperRoundtripWithProxyTest.java</exclude>
+ <exclude>**/DefaultRepositoryCrawlerTest.java</exclude>
+ </excludes>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ <reporting>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>cobertura-maven-plugin</artifactId>
+ <version>2.2</version>
+ </plugin>
+ </plugins>
+ </reporting>
+
+ <profiles>
+ <profile>
+ <id>internal-catalog</id>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <includes>
+ <include>**/*Verification.java</include>
+ </includes>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/full-interpolation/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/full-interpolation/pom.xml
new file mode 100644
index 00000000..503dadb9
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/full-interpolation/pom.xml
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng3833</groupId>
+ <artifactId>coreit</artifactId>
+ <version>0.1</version>
+ <packaging>jar</packaging>
+
+ <name>Maven Integration Test :: MNG-3833</name>
+ <description>
+ Test that POM interpolation fully interpolates all properties in data flow chain, i.e. where property
+ A depends on property B, and property B depends on property C and so on.
+ </description>
+
+ <properties>
+ <!--
+ NOTE: Both the ordering (i.e. neither ascending nor descending) and the number of properties is crucial to
+ exhibit the bug.
+ -->
+ <property23>${property22}</property23>
+ <property21>${property20}</property21>
+ <property19>${property18}</property19>
+ <property17>${property16}</property17>
+ <property15>${property14}</property15>
+ <property13>${property12}</property13>
+ <property11>${property10}</property11>
+ <property09>${property08}</property09>
+ <property07>${property06}</property07>
+ <property05>${property04}</property05>
+ <property03>${property02}</property03>
+ <property01>${property00}</property01>
+ <property00>PASSED</property00>
+ <property02>${property01}</property02>
+ <property04>${property03}</property04>
+ <property06>${property05}</property06>
+ <property10>${property09}</property10>
+ <property12>${property11}</property12>
+ <property08>${property07}</property08>
+ <property14>${property13}</property14>
+ <property16>${property15}</property16>
+ <property18>${property17}</property18>
+ <property20>${property19}</property20>
+ <property22>${property21}</property22>
+ </properties>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/id-container-joining-with-empty-elements/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/id-container-joining-with-empty-elements/pom.xml
new file mode 100644
index 00000000..4db43cd4
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/id-container-joining-with-empty-elements/pom.xml
@@ -0,0 +1,97 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng3979</groupId>
+ <artifactId>parent</artifactId>
+ <version>0.1</version>
+ <packaging>pom</packaging>
+
+ <name>Maven Integration Test :: MNG-3979</name>
+ <description>
+ Test that during inheritance the merging/joining of sub trees with equal identifier doesn't crash if the parent
+ POM has a non-empty element and the child POM has an empty element to join.
+ </description>
+
+ <properties>
+ <prop0>test</prop0>
+ </properties>
+
+ <repositories>
+ <repository>
+ <id>equal-repo-id</id>
+ <url>http://maven.apache.org/null</url>
+ <snapshots>
+ <enabled>false</enabled>
+ </snapshots>
+ <releases>
+ <checksumPolicy>ignore</checksumPolicy>
+ </releases>
+ </repository>
+ </repositories>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-log-file</artifactId>
+ <version>2.1-SNAPSHOT</version>
+ <executions>
+ <execution>
+ <id>equal-build-exec-id</id>
+ <phase>initialize</phase>
+ <goals>
+ <goal>reset</goal>
+ </goals>
+ <configuration>
+ <logFile>target/exec.log</logFile>
+ <string>test</string>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+ <reporting>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-log-file</artifactId>
+ <version>2.1-SNAPSHOT</version>
+ <reportSets>
+ <reportSet>
+ <id>equal-report-exec-id</id>
+ <reports>
+ <report>reset</report>
+ </reports>
+ <configuration>
+ <logFile>target/exec.log</logFile>
+ <string>test</string>
+ </configuration>
+ </reportSet>
+ </reportSets>
+ </plugin>
+ </plugins>
+ </reporting>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/id-container-joining-with-empty-elements/sub/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/id-container-joining-with-empty-elements/sub/pom.xml
new file mode 100644
index 00000000..e65d26c2
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/id-container-joining-with-empty-elements/sub/pom.xml
@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.maven.its.mng3979</groupId>
+ <artifactId>parent</artifactId>
+ <version>0.1</version>
+ </parent>
+
+ <artifactId>child</artifactId>
+
+ <name>Maven Integration Test :: MNG-3979</name>
+ <description>
+ Test that during inheritance the merging/joining of sub trees with equal identifier doesn't crash if the parent
+ POM has a non-empty element and the child POM has an empty element to join.
+ </description>
+
+ <properties/>
+
+ <repositories>
+ <repository>
+ <id>equal-repo-id</id>
+ <url>file:///${basedir}/null</url>
+ <snapshots/>
+ <releases/>
+ </repository>
+ </repositories>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-log-file</artifactId>
+ <version>2.1-SNAPSHOT</version>
+ <executions>
+ <execution>
+ <id>equal-build-exec-id</id>
+ <phase>initialize</phase>
+ <goals/>
+ <configuration/>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+ <reporting>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-log-file</artifactId>
+ <version>2.1-SNAPSHOT</version>
+ <reportSets>
+ <reportSet>
+ <id>equal-report-exec-id</id>
+ <reports/>
+ <configuration/>
+ </reportSet>
+ </reportSets>
+ </plugin>
+ </plugins>
+ </reporting>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/inherited-properties-interpolation/active-profile/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/inherited-properties-interpolation/active-profile/pom.xml
new file mode 100644
index 00000000..640cf288
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/inherited-properties-interpolation/active-profile/pom.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng4102</groupId>
+ <artifactId>parent</artifactId>
+ <version>0.1</version>
+ <packaging>pom</packaging>
+
+ <name>Maven Integration Test :: MNG-4102</name>
+ <description>
+ Verify that the effective value of an inherited property reflects the values of any nested property
+ as defined by the child. This boils down to the order of inheritance and (parent) interpolation.
+ </description>
+
+ <properties>
+ <overridden>PARENT</overridden>
+ <!-- Test the effective value of this property in the child when "overridden" is defined by child as well -->
+ <interpolated>${overridden}</interpolated>
+ </properties>
+
+ <profiles>
+ <profile>
+ <id>it-parent</id>
+ <activation>
+ <activeByDefault>true</activeByDefault>
+ </activation>
+ </profile>
+ </profiles>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/inherited-properties-interpolation/active-profile/sub/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/inherited-properties-interpolation/active-profile/sub/pom.xml
new file mode 100644
index 00000000..2aa40ded
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/inherited-properties-interpolation/active-profile/sub/pom.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.maven.its.mng4102</groupId>
+ <artifactId>parent</artifactId>
+ <version>0.1</version>
+ </parent>
+
+ <groupId>org.apache.maven.its.mng4102</groupId>
+ <artifactId>test</artifactId>
+ <version>0.1</version>
+ <packaging>jar</packaging>
+
+ <name>Maven Integration Test :: MNG-4102 :: Child</name>
+ <description>
+ Verify that the effective value of an inherited property reflects the values of any nested property
+ as defined by the child. This boils down to the order of inheritance and (parent) interpolation.
+ </description>
+
+ <properties>
+ <overridden>CHILD</overridden>
+ </properties>
+
+ <profiles>
+ <profile>
+ <id>it-child</id>
+ <activation>
+ <activeByDefault>true</activeByDefault>
+ </activation>
+ </profile>
+ </profiles>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/inherited-properties-interpolation/no-profile/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/inherited-properties-interpolation/no-profile/pom.xml
new file mode 100644
index 00000000..3e11a6d6
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/inherited-properties-interpolation/no-profile/pom.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng4102</groupId>
+ <artifactId>parent</artifactId>
+ <version>0.1</version>
+ <packaging>pom</packaging>
+
+ <name>Maven Integration Test :: MNG-4102</name>
+ <description>
+ Verify that the effective value of an inherited property reflects the values of any nested property
+ as defined by the child. This boils down to the order of inheritance and (parent) interpolation.
+ </description>
+
+ <properties>
+ <overridden>PARENT</overridden>
+ <!-- Test the effective value of this property in the child when "overridden" is defined by child as well -->
+ <interpolated>${overridden}</interpolated>
+ </properties>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/inherited-properties-interpolation/no-profile/sub/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/inherited-properties-interpolation/no-profile/sub/pom.xml
new file mode 100644
index 00000000..49c8fd21
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/inherited-properties-interpolation/no-profile/sub/pom.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.maven.its.mng4102</groupId>
+ <artifactId>parent</artifactId>
+ <version>0.1</version>
+ </parent>
+
+ <groupId>org.apache.maven.its.mng4102</groupId>
+ <artifactId>test</artifactId>
+ <version>0.1</version>
+ <packaging>jar</packaging>
+
+ <name>Maven Integration Test :: MNG-4102 :: Child</name>
+ <description>
+ Verify that the effective value of an inherited property reflects the values of any nested property
+ as defined by the child. This boils down to the order of inheritance and (parent) interpolation.
+ </description>
+
+ <properties>
+ <overridden>CHILD</overridden>
+ </properties>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/interpolation-cli-wins/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/interpolation-cli-wins/pom.xml
new file mode 100644
index 00000000..39d8d9f8
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/interpolation-cli-wins/pom.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng4208</groupId>
+ <artifactId>test</artifactId>
+ <version>0.1</version>
+ <packaging>jar</packaging>
+
+ <name>Maven Integration Test :: MNG-4208</name>
+ <description>
+ Test that CLI properties specified by the user override project properties during interpolation.
+ </description>
+
+ <properties>
+ <testProperty>FAILED</testProperty>
+ <interpolatedProperty>${testProperty}</interpolatedProperty>
+ </properties>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/jdk-activation/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/jdk-activation/pom.xml
new file mode 100644
index 00000000..c0431f58
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/jdk-activation/pom.xml
@@ -0,0 +1,105 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng1957</groupId>
+ <artifactId>test</artifactId>
+ <version>1.0-SNAPSHOT</version>
+
+ <name>Maven Integration Test :: MNG-1957</name>
+ <description>
+ Test that JDK profile activation allows version ranges.
+ </description>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-expression</artifactId>
+ <version>2.1-SNAPSHOT</version>
+ <executions>
+ <execution>
+ <phase>validate</phase>
+ <goals>
+ <goal>eval</goal>
+ </goals>
+ <configuration>
+ <outputFile>target/jdk.properties</outputFile>
+ <expressions>
+ <expression>project/properties</expression>
+ </expressions>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+ <profiles>
+ <profile>
+ <id>test-1</id>
+ <activation>
+ <jdk>[1.4,)</jdk>
+ </activation>
+ <properties>
+ <jdkProperty1>PASSED</jdkProperty1>
+ </properties>
+ </profile>
+ <profile>
+ <id>test-2</id>
+ <activation>
+ <jdk>(,100)</jdk>
+ </activation>
+ <properties>
+ <jdkProperty2>PASSED</jdkProperty2>
+ </properties>
+ </profile>
+ <profile>
+ <id>test-3</id>
+ <activation>
+ <jdk>(1.3,100)</jdk>
+ </activation>
+ <properties>
+ <jdkProperty3>PASSED</jdkProperty3>
+ </properties>
+ </profile>
+ <profile>
+ <id>test-4</id>
+ <activation>
+ <jdk>(100,)</jdk>
+ </activation>
+ <properties>
+ <jdkProperty4>FAILED</jdkProperty4>
+ </properties>
+ </profile>
+ <profile>
+ <id>test-5</id>
+ <activation>
+ <jdk>(,1.4)</jdk>
+ </activation>
+ <properties>
+ <jdkProperty5>FAILED</jdkProperty5>
+ </properties>
+ </profile>
+ </profiles>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/join-different-containers-same-id/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/join-different-containers-same-id/pom.xml
new file mode 100644
index 00000000..b3f48caa
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/join-different-containers-same-id/pom.xml
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>mng3984</groupId>
+ <artifactId>test</artifactId>
+ <version>0.1</version>
+ <packaging>pom</packaging>
+
+ <name>MNG-3984</name>
+
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-b</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <executions>
+ <execution>
+ <id>foo</id>
+ <goals>
+ <goal>a</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-a</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <executions>
+ <execution>
+ <id>foo</id>
+ <goals>
+ <goal>b</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/licenses-inheritance/child-2/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/licenses-inheritance/child-2/pom.xml
new file mode 100644
index 00000000..9fd30bf5
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/licenses-inheritance/child-2/pom.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <!--
+ While <licenses> are inherited, they are not aggregated, only the child licenses are used.
+ -->
+
+ <parent>
+ <groupId>org.apache.maven.its.mng3843</groupId>
+ <artifactId>parent-1</artifactId>
+ <version>0.1</version>
+ </parent>
+
+ <groupId>org.apache.maven.its.mng3843.child</groupId>
+ <artifactId>child-2</artifactId>
+ <version>0.2</version>
+ <packaging>jar</packaging>
+
+ <licenses>
+ <license>
+ <name>child-license</name>
+ <url>http://child.url/license</url>
+ <distribution>repo</distribution>
+ </license>
+ </licenses>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/licenses-inheritance/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/licenses-inheritance/pom.xml
new file mode 100644
index 00000000..641bb37f
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/licenses-inheritance/pom.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng3843</groupId>
+ <artifactId>parent-1</artifactId>
+ <version>0.1</version>
+ <packaging>pom</packaging>
+
+ <licenses>
+ <license>
+ <name>parent-license</name>
+ <url>http://parent.url/license</url>
+ <distribution>repo</distribution>
+ </license>
+ </licenses>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/limited-inheritance/child/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/limited-inheritance/child/pom.xml
new file mode 100644
index 00000000..8e9e6237
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/limited-inheritance/child/pom.xml
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.maven.its.mng3845</groupId>
+ <artifactId>parent</artifactId>
+ <version>0.1</version>
+ </parent>
+
+ <artifactId>child</artifactId>
+
+ <organization>
+ <name>child-org</name>
+ </organization>
+
+ <scm>
+ <developerConnection>https://child.url/scm</developerConnection>
+ </scm>
+ <issueManagement>
+ <url>http://child.url/issues</url>
+ </issueManagement>
+ <ciManagement>
+ <system>child-ci</system>
+ <url>http://child.url/ci</url>
+ </ciManagement>
+ <distributionManagement>
+ <repository>
+ <id>child-distros</id>
+ <url>ssh://child.url/distros</url>
+ </repository>
+ <snapshotRepository>
+ <id>child-snaps</id>
+ <url>ssh://child.url/snaps</url>
+ </snapshotRepository>
+ <site>
+ <id>child-site</id>
+ <url>scp://child.url/site</url>
+ </site>
+ </distributionManagement>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/limited-inheritance/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/limited-inheritance/pom.xml
new file mode 100644
index 00000000..8bbe6eae
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/limited-inheritance/pom.xml
@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng3845</groupId>
+ <artifactId>parent</artifactId>
+ <version>0.1</version>
+ <packaging>pom</packaging>
+
+ <name>Maven Integration Test :: MNG-3845</name>
+ <description>
+ Test that inheritance is all-or-nothing for certain sub-trees of the POM.
+ </description>
+
+ <organization>
+ <name>parent-org</name>
+ <url>http://parent.url/org</url>
+ </organization>
+
+ <scm>
+ <url>http://parent.url/viewvc</url>
+ <connection>http://parent.url/scm</connection>
+ <developerConnection>https://parent.url/scm</developerConnection>
+ <tag>parent-tag</tag>
+ </scm>
+ <issueManagement>
+ <system>parent-issues</system>
+ <url>http://parent.url/issues</url>
+ </issueManagement>
+ <ciManagement>
+ <system>parent-ci</system>
+ <url>http://parent.url/ci</url>
+ <notifiers>
+ <notifier>
+ <type>irc</type>
+ <sendOnError>true</sendOnError>
+ <sendOnFailure>true</sendOnFailure>
+ <sendOnSuccess>false</sendOnSuccess>
+ <sendOnWarning>false</sendOnWarning>
+ <configuration>
+ <address>irc://parent.url/#ci</address>
+ </configuration>
+ </notifier>
+ </notifiers>
+ </ciManagement>
+ <distributionManagement>
+ <repository>
+ <id>parent-distros</id>
+ <name>parent-distros</name>
+ <url>ssh://parent.url/distros</url>
+ <uniqueVersion>false</uniqueVersion>
+ <layout>legacy</layout>
+ </repository>
+ <snapshotRepository>
+ <id>parent-snaps</id>
+ <name>parent-snaps</name>
+ <url>ssh://parent.url/snaps</url>
+ <uniqueVersion>false</uniqueVersion>
+ <layout>legacy</layout>
+ </snapshotRepository>
+ <site>
+ <id>parent-site</id>
+ <name>parent-site</name>
+ <url>scp://parent.url/site</url>
+ </site>
+ </distributionManagement>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/mailing-lists-inheritance/child-2/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/mailing-lists-inheritance/child-2/pom.xml
new file mode 100644
index 00000000..95ce7fe6
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/mailing-lists-inheritance/child-2/pom.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <!--
+ While <mailingLists> are inherited, they are not aggregated, only the child elements are used.
+ -->
+
+ <parent>
+ <groupId>org.apache.maven.its.mng3843</groupId>
+ <artifactId>parent-1</artifactId>
+ <version>0.1</version>
+ </parent>
+
+ <groupId>org.apache.maven.its.mng3843.child</groupId>
+ <artifactId>child-2</artifactId>
+ <version>0.2</version>
+ <packaging>jar</packaging>
+
+ <mailingLists>
+ <mailingList>
+ <name>child-mailing-list</name>
+ </mailingList>
+ </mailingLists>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/mailing-lists-inheritance/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/mailing-lists-inheritance/pom.xml
new file mode 100644
index 00000000..c9b05dfd
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/mailing-lists-inheritance/pom.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng3843</groupId>
+ <artifactId>parent-1</artifactId>
+ <version>0.1</version>
+ <packaging>pom</packaging>
+
+ <mailingLists>
+ <mailingList>
+ <name>parent-mailing-list</name>
+ </mailingList>
+ </mailingLists>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/managed-profile-dependency/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/managed-profile-dependency/pom.xml
new file mode 100644
index 00000000..88c9813a
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/managed-profile-dependency/pom.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng4034</groupId>
+ <artifactId>parent</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <packaging>pom</packaging>
+
+ <name>Maven Integration Test :: MNG-4034</name>
+ <description>
+ Verify that dependencies defined in profiles are subject to the dependency management of the parent.
+ </description>
+
+ <modules>
+ <module>sub</module>
+ </modules>
+
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven.its</groupId>
+ <artifactId>maven-core-it-support</artifactId>
+ <version>1.3</version>
+ <scope>runtime</scope>
+ <exclusions>
+ <exclusion>
+ <groupId>commons-lang</groupId>
+ <artifactId>commons-lang</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/managed-profile-dependency/sub/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/managed-profile-dependency/sub/pom.xml
new file mode 100644
index 00000000..88204fcd
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/managed-profile-dependency/sub/pom.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.maven.its.mng4034</groupId>
+ <artifactId>parent</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ </parent>
+
+ <groupId>org.apache.maven.its.mng4034</groupId>
+ <artifactId>child</artifactId>
+ <version>1.0-SNAPSHOT</version>
+
+ <name>Maven Integration Test :: MNG-4034</name>
+ <description>
+ Verify that dependencies defined in profiles are subject to the dependency management of the parent.
+ </description>
+
+ <profiles>
+ <profile>
+ <id>maven-core-it</id>
+ <activation>
+ <activeByDefault>true</activeByDefault>
+ </activation>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven.its</groupId>
+ <artifactId>maven-core-it-support</artifactId>
+ <!-- version should be injected from dependency management of parent -->
+ </dependency>
+ </dependencies>
+ </profile>
+ </profiles>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/merged-filter-order/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/merged-filter-order/pom.xml
new file mode 100644
index 00000000..6f4df9ac
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/merged-filter-order/pom.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng4008</groupId>
+ <artifactId>parent</artifactId>
+ <version>1.0</version>
+ <packaging>pom</packaging>
+
+ <name>Maven Integration Test :: MNG-4008</name>
+ <description>
+ Verify that filter definitions are properly merged.
+ </description>
+
+ <build>
+ <filters>
+ <!-- NOTE: The first filter is deliberately defined by the child as well, so should not be added twice -->
+ <filter>src/main/filters/child-a.properties</filter>
+ <filter>src/main/filters/parent-c.properties</filter>
+ <filter>src/main/filters/parent-b.properties</filter>
+ <filter>src/main/filters/parent-d.properties</filter>
+ </filters>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/merged-filter-order/sub/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/merged-filter-order/sub/pom.xml
new file mode 100644
index 00000000..7e7155bf
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/merged-filter-order/sub/pom.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.maven.its.mng4008</groupId>
+ <artifactId>parent</artifactId>
+ <version>1.0</version>
+ </parent>
+
+ <groupId>org.apache.maven.its.mng4008</groupId>
+ <artifactId>test</artifactId>
+ <version>1.0</version>
+ <packaging>jar</packaging>
+
+ <name>Maven Integration Test :: MNG-4008</name>
+ <description>
+ Verify that filter definitions are properly merged.
+ </description>
+
+ <build>
+ <filters>
+ <filter>src/main/filters/child-a.properties</filter>
+ <filter>src/main/filters/child-c.properties</filter>
+ <filter>src/main/filters/child-b.properties</filter>
+ <filter>src/main/filters/child-d.properties</filter>
+ </filters>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/merged-plugin-class-path-order/w-plugin-mngt/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/merged-plugin-class-path-order/w-plugin-mngt/pom.xml
new file mode 100644
index 00000000..aba6bdf0
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/merged-plugin-class-path-order/w-plugin-mngt/pom.xml
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng3906</groupId>
+ <artifactId>parent</artifactId>
+ <version>0.1</version>
+ <packaging>pom</packaging>
+
+ <name>Maven Integration Test :: MNG-3906</name>
+ <description>
+ Test that project-level plugin dependencies are properly merged during inheritance.
+ </description>
+
+ <build>
+ <!-- NOTE: This parent uses plugin management -->
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-class-loader</artifactId>
+ <version>2.1-SNAPSHOT</version>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven.its.mng3906</groupId>
+ <artifactId>e</artifactId>
+ <version>1</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.its.mng3906</groupId>
+ <artifactId>a</artifactId>
+ <version>1</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.its.mng3906</groupId>
+ <artifactId>d</artifactId>
+ <version>1</version>
+ </dependency>
+ </dependencies>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/merged-plugin-class-path-order/w-plugin-mngt/sub/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/merged-plugin-class-path-order/w-plugin-mngt/sub/pom.xml
new file mode 100644
index 00000000..1877ea54
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/merged-plugin-class-path-order/w-plugin-mngt/sub/pom.xml
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.maven.its.mng3906</groupId>
+ <artifactId>parent</artifactId>
+ <version>0.1</version>
+ </parent>
+
+ <artifactId>child</artifactId>
+
+ <name>Maven Integration Test :: MNG-3906</name>
+ <description>
+ Test that project-level plugin dependencies are properly merged during inheritance.
+ </description>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-class-loader</artifactId>
+ <version>2.1-SNAPSHOT</version>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven.its.mng3906</groupId>
+ <artifactId>c</artifactId>
+ <version>1</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.its.mng3906</groupId>
+ <artifactId>a</artifactId>
+ <version>2</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.its.mng3906</groupId>
+ <artifactId>b</artifactId>
+ <version>1</version>
+ </dependency>
+ </dependencies>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/merged-plugin-class-path-order/wo-plugin-mngt/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/merged-plugin-class-path-order/wo-plugin-mngt/pom.xml
new file mode 100644
index 00000000..10226cfb
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/merged-plugin-class-path-order/wo-plugin-mngt/pom.xml
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng3906</groupId>
+ <artifactId>parent</artifactId>
+ <version>0.1</version>
+ <packaging>pom</packaging>
+
+ <name>Maven Integration Test :: MNG-3906</name>
+ <description>
+ Test that project-level plugin dependencies are properly merged during inheritance.
+ </description>
+
+ <build>
+ <!-- NOTE: This parent does not use plugin management -->
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-class-loader</artifactId>
+ <version>2.1-SNAPSHOT</version>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven.its.mng3906</groupId>
+ <artifactId>e</artifactId>
+ <version>1</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.its.mng3906</groupId>
+ <artifactId>a</artifactId>
+ <version>1</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.its.mng3906</groupId>
+ <artifactId>d</artifactId>
+ <version>1</version>
+ </dependency>
+ </dependencies>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/merged-plugin-class-path-order/wo-plugin-mngt/sub/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/merged-plugin-class-path-order/wo-plugin-mngt/sub/pom.xml
new file mode 100644
index 00000000..1877ea54
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/merged-plugin-class-path-order/wo-plugin-mngt/sub/pom.xml
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.maven.its.mng3906</groupId>
+ <artifactId>parent</artifactId>
+ <version>0.1</version>
+ </parent>
+
+ <artifactId>child</artifactId>
+
+ <name>Maven Integration Test :: MNG-3906</name>
+ <description>
+ Test that project-level plugin dependencies are properly merged during inheritance.
+ </description>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-class-loader</artifactId>
+ <version>2.1-SNAPSHOT</version>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven.its.mng3906</groupId>
+ <artifactId>c</artifactId>
+ <version>1</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.its.mng3906</groupId>
+ <artifactId>a</artifactId>
+ <version>2</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.its.mng3906</groupId>
+ <artifactId>b</artifactId>
+ <version>1</version>
+ </dependency>
+ </dependencies>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/merged-plugin-exec-goals-order/w-plugin-mngt/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/merged-plugin-exec-goals-order/w-plugin-mngt/pom.xml
new file mode 100644
index 00000000..fc09dba1
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/merged-plugin-exec-goals-order/w-plugin-mngt/pom.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng3937</groupId>
+ <artifactId>parent-2</artifactId>
+ <version>0.1</version>
+ <packaging>pom</packaging>
+
+ <name>Maven Integration Test :: MNG-3937</name>
+ <description>
+ Test that during inheritance/merging of a plugin execution the goals specified by child and parent are properly
+ ordered.
+ </description>
+
+ <build>
+ <!-- This project uses plugin management for the test plugin -->
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-a</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <executions>
+ <execution>
+ <id>merge</id>
+ <phase>validate</phase>
+ <goals>
+ <goal>parent-b</goal>
+ <goal>merged</goal>
+ <goal>parent-a</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/merged-plugin-exec-goals-order/w-plugin-mngt/sub/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/merged-plugin-exec-goals-order/w-plugin-mngt/sub/pom.xml
new file mode 100644
index 00000000..2148aa9b
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/merged-plugin-exec-goals-order/w-plugin-mngt/sub/pom.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.maven.its.mng3937</groupId>
+ <artifactId>parent-2</artifactId>
+ <version>0.1</version>
+ </parent>
+
+ <artifactId>child-2</artifactId>
+
+ <name>Maven Integration Test :: MNG-3937</name>
+ <description>
+ Test that during inheritance/merging of a plugin execution the goals specified by child and parent are properly
+ ordered.
+ </description>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-a</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <executions>
+ <execution>
+ <id>merge</id>
+ <phase>validate</phase>
+ <goals>
+ <goal>child-a</goal>
+ <goal>merged</goal>
+ <goal>child-b</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/merged-plugin-exec-goals-order/wo-plugin-mngt/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/merged-plugin-exec-goals-order/wo-plugin-mngt/pom.xml
new file mode 100644
index 00000000..b9c3f18b
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/merged-plugin-exec-goals-order/wo-plugin-mngt/pom.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng3937</groupId>
+ <artifactId>parent-1</artifactId>
+ <version>0.1</version>
+ <packaging>pom</packaging>
+
+ <name>Maven Integration Test :: MNG-3937</name>
+ <description>
+ Test that during inheritance/merging of a plugin execution the goals specified by child and parent are properly
+ ordered.
+ </description>
+
+ <build>
+ <!-- This project does not use plugin management for the test plugin -->
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-a</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <executions>
+ <execution>
+ <id>merge</id>
+ <phase>validate</phase>
+ <goals>
+ <goal>parent-b</goal>
+ <goal>merged</goal>
+ <goal>parent-a</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/merged-plugin-exec-goals-order/wo-plugin-mngt/sub/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/merged-plugin-exec-goals-order/wo-plugin-mngt/sub/pom.xml
new file mode 100644
index 00000000..fab233b2
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/merged-plugin-exec-goals-order/wo-plugin-mngt/sub/pom.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.maven.its.mng3937</groupId>
+ <artifactId>parent-1</artifactId>
+ <version>0.1</version>
+ </parent>
+
+ <artifactId>child-1</artifactId>
+
+ <name>Maven Integration Test :: MNG-3937</name>
+ <description>
+ Test that during inheritance/merging of a plugin execution the goals specified by child and parent are properly
+ ordered.
+ </description>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-a</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <executions>
+ <execution>
+ <id>merge</id>
+ <phase>validate</phase>
+ <goals>
+ <goal>child-a</goal>
+ <goal>merged</goal>
+ <goal>child-b</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/merged-plugin-exec-order/w-plugin-mngt/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/merged-plugin-exec-order/w-plugin-mngt/pom.xml
new file mode 100644
index 00000000..ee4dedcf
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/merged-plugin-exec-order/w-plugin-mngt/pom.xml
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng3925</groupId>
+ <artifactId>parent</artifactId>
+ <version>0.1</version>
+ <packaging>pom</packaging>
+
+ <name>Maven Integration Test :: MNG-3925</name>
+ <description>
+ Test that plugin executions (in the same phase) are properly ordered after inheritance/merge with
+ parent executions.
+ </description>
+
+ <build>
+ <!-- This project uses plugin management for the test plugin -->
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-a</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <executions>
+ <execution>
+ <id>parent-1</id>
+ <phase>validate</phase>
+ <goals>
+ <goal>parent-1</goal>
+ </goals>
+ </execution>
+ <execution>
+ <id>parent-2</id>
+ <phase>validate</phase>
+ <goals>
+ <goal>parent-2</goal>
+ </goals>
+ </execution>
+ <execution>
+ <!-- NOTE: <id> deliberately omitted to use default value -->
+ <phase>validate</phase>
+ <goals>
+ <goal>parent-default</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/merged-plugin-exec-order/w-plugin-mngt/sub/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/merged-plugin-exec-order/w-plugin-mngt/sub/pom.xml
new file mode 100644
index 00000000..bf777db9
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/merged-plugin-exec-order/w-plugin-mngt/sub/pom.xml
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.maven.its.mng3925</groupId>
+ <artifactId>parent</artifactId>
+ <version>0.1</version>
+ </parent>
+
+ <artifactId>child</artifactId>
+
+ <name>Maven Integration Test :: MNG-3925</name>
+ <description>
+ Test that plugin executions (in the same phase) are properly ordered after inheritance/merge with
+ parent executions.
+ </description>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-a</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <executions>
+ <execution>
+ <id>child-1</id>
+ <phase>validate</phase>
+ <goals>
+ <goal>child-1</goal>
+ </goals>
+ </execution>
+ <execution>
+ <id>child-2</id>
+ <phase>validate</phase>
+ <goals>
+ <goal>child-2</goal>
+ </goals>
+ </execution>
+ <execution>
+ <!-- NOTE: <id> deliberately omitted to use default value -->
+ <phase>validate</phase>
+ <goals>
+ <goal>child-default</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/merged-plugin-exec-order/wo-plugin-mngt/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/merged-plugin-exec-order/wo-plugin-mngt/pom.xml
new file mode 100644
index 00000000..a816975f
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/merged-plugin-exec-order/wo-plugin-mngt/pom.xml
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng3925</groupId>
+ <artifactId>parent</artifactId>
+ <version>0.1</version>
+ <packaging>pom</packaging>
+
+ <name>Maven Integration Test :: MNG-3925</name>
+ <description>
+ Test that plugin executions (in the same phase) are properly ordered after inheritance/merge with
+ parent executions.
+ </description>
+
+ <build>
+ <!-- This project does not use plugin management for the test plugin -->
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-a</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <executions>
+ <execution>
+ <id>parent-1</id>
+ <phase>validate</phase>
+ <goals>
+ <goal>parent-1</goal>
+ </goals>
+ </execution>
+ <execution>
+ <id>parent-2</id>
+ <phase>validate</phase>
+ <goals>
+ <goal>parent-2</goal>
+ </goals>
+ </execution>
+ <execution>
+ <!-- NOTE: <id> deliberately omitted to use default value -->
+ <phase>validate</phase>
+ <goals>
+ <goal>parent-default</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/merged-plugin-exec-order/wo-plugin-mngt/sub/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/merged-plugin-exec-order/wo-plugin-mngt/sub/pom.xml
new file mode 100644
index 00000000..bf777db9
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/merged-plugin-exec-order/wo-plugin-mngt/sub/pom.xml
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.maven.its.mng3925</groupId>
+ <artifactId>parent</artifactId>
+ <version>0.1</version>
+ </parent>
+
+ <artifactId>child</artifactId>
+
+ <name>Maven Integration Test :: MNG-3925</name>
+ <description>
+ Test that plugin executions (in the same phase) are properly ordered after inheritance/merge with
+ parent executions.
+ </description>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-a</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <executions>
+ <execution>
+ <id>child-1</id>
+ <phase>validate</phase>
+ <goals>
+ <goal>child-1</goal>
+ </goals>
+ </execution>
+ <execution>
+ <id>child-2</id>
+ <phase>validate</phase>
+ <goals>
+ <goal>child-2</goal>
+ </goals>
+ </execution>
+ <execution>
+ <!-- NOTE: <id> deliberately omitted to use default value -->
+ <phase>validate</phase>
+ <goals>
+ <goal>child-default</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/micromailer/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/micromailer/pom.xml
new file mode 100644
index 00000000..780faac2
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/micromailer/pom.xml
@@ -0,0 +1,124 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.sonatype.spice</groupId>
+ <artifactId>spice-parent</artifactId>
+ <version>11</version>
+ <relativePath>spice-parent-9.pom</relativePath>
+ </parent>
+
+ <groupId>org.sonatype.micromailer</groupId>
+ <artifactId>micromailer</artifactId>
+ <version>1.0.3</version>
+ <packaging>jar</packaging>
+ <name>Micro Mailer</name>
+ <!-- SCM -->
+ <scm>
+ <connection>scm:svn:http://svn.sonatype.org/spice/trunk/micromailer</connection>
+ <url>http://svn.sonatype.org/spice/trunk/micromailer</url>
+ <developerConnection>scm:svn:https://svn.sonatype.org/spice/trunk/micromailer</developerConnection>
+ </scm>
+
+ <dependencies>
+
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-container-default</artifactId>
+ <version>1.0-alpha-47</version>
+ <type>jar</type>
+ <scope>compile</scope>
+ <exclusions>
+ <exclusion>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging-api</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>log4j</groupId>
+ <artifactId>log4j</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-utils</artifactId>
+ <version>1.5.5</version>
+ <type>jar</type>
+ <scope>compile</scope>
+ </dependency>
+
+ <!-- Mail composition -->
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-velocity</artifactId>
+ <version>1.1.7</version>
+ <type>jar</type>
+ <scope>compile</scope>
+ <exclusions>
+ <exclusion>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-component-api</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>velocity</groupId>
+ <artifactId>velocity</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>commons-collections</groupId>
+ <artifactId>commons-collections</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.velocity</groupId>
+ <artifactId>velocity</artifactId>
+ <version>1.5</version>
+ <type>jar</type>
+ <scope>compile</scope>
+ </dependency>
+
+ <!-- Mail sending -->
+ <dependency>
+ <groupId>javax.mail</groupId>
+ <artifactId>mail</artifactId>
+ <version>1.4</version>
+ <type>jar</type>
+ <scope>compile</scope>
+ </dependency>
+
+ <!-- Testing -->
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>3.8.2</version>
+ <type>jar</type>
+ <scope>test</scope>
+ </dependency>
+
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-maven-plugin</artifactId>
+ <version>1.3.8</version>
+ <executions>
+ <execution>
+ <goals>
+ <goal>child-descriptor</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/micromailer/spice-parent-9.pom b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/micromailer/spice-parent-9.pom
new file mode 100644
index 00000000..695c3c93
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/micromailer/spice-parent-9.pom
@@ -0,0 +1,103 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.sonatype.spice</groupId>
+ <artifactId>spice-parent</artifactId>
+ <version>11</version>
+ <packaging>pom</packaging>
+ <name>Sonatype Spice Components</name>
+
+ <scm>
+ <connection>scm:svn:http://svn.sonatype.org/spice/trunk/spice-parent</connection>
+ <url>http://svn.sonatype.org/spice/trunk/spice-parent</url>
+ <developerConnection>scm:svn:https://svn.sonatype.org/spice/trunk/spice-parent</developerConnection>
+ </scm>
+
+ <properties>
+ <!-- 2008.12.07 Oleg: reverted to 6.1.12 as http transport only works with that version
+ | Please always sync with mercury-http-transport !!
+ -->
+ <jetty.version>6.1.12</jetty.version>
+ </properties>
+
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-container-default</artifactId>
+ <version>1.0-beta-1</version>
+ <exclusions>
+ <exclusion>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging-api</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>log4j</groupId>
+ <artifactId>log4j</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-component-annotations</artifactId>
+ <version>1.0-beta-1</version>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-utils</artifactId>
+ <version>1.5.5</version>
+ </dependency>
+ <dependency>
+ <groupId>org.mortbay.jetty</groupId>
+ <artifactId>jetty</artifactId>
+ <version>${jetty.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.mortbay.jetty</groupId>
+ <artifactId>jetty-client</artifactId>
+ <version>${jetty.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.5</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-component-metadata</artifactId>
+ <version>1.0-beta-1</version>
+ <executions>
+ <execution>
+ <id>process-classes</id>
+ <goals>
+ <goal>generate-metadata</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-maven-plugin</artifactId>
+ <version>1.3.8</version>
+ <executions>
+ <execution>
+ <goals>
+ <goal>descriptor</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/multiple-filters/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/multiple-filters/pom.xml
new file mode 100644
index 00000000..1141efb5
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/multiple-filters/pom.xml
@@ -0,0 +1,17 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>a</groupId>
+ <artifactId>b</artifactId>
+ <version>1.0</version>
+
+ <build>
+ <filters>
+ <filter>src/main/filters/a.properties</filter>
+ <filter>src/main/filters/c.properties</filter>
+ <filter>src/main/filters/b.properties</filter>
+ <filter>src/main/filters/d.properties</filter>
+ </filters>
+ </build>
+
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/multiple-repos/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/multiple-repos/pom.xml
new file mode 100644
index 00000000..e59cd0c3
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/multiple-repos/pom.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>mng3984</groupId>
+ <artifactId>test-1</artifactId>
+ <version>0.1</version>
+ <packaging>pom</packaging>
+
+ <name>MNG-3984</name>
+ <repositories>
+ <repository>
+ <id>central-parent</id>
+ <name>Maven Repository Switchboard</name>
+ <layout>default</layout>
+ <url>http://repo1.maven.org/maven2</url>
+ <snapshots>
+ <enabled>false</enabled>
+ </snapshots>
+ </repository>
+ </repositories>
+
+
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/multiple-repos/sub/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/multiple-repos/sub/pom.xml
new file mode 100644
index 00000000..d7b21020
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/multiple-repos/sub/pom.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>mng3984</groupId>
+ <artifactId>test-1</artifactId>
+ <version>0.1</version>
+ </parent>
+ <groupId>mng3984</groupId>
+ <artifactId>test-2</artifactId>
+ <version>0.1</version>
+
+ <name>MNG-3984</name>
+ <repositories>
+ <repository>
+ <id>central-child</id>
+ <name>Maven Repository Switchboard</name>
+ <layout>default</layout>
+ <url>http://repo1.maven.org/maven2</url>
+ <snapshots>
+ <enabled>false</enabled>
+ </snapshots>
+ </repository>
+ </repositories>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/nested-build-dir-interpolation/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/nested-build-dir-interpolation/pom.xml
new file mode 100644
index 00000000..5632fad4
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/nested-build-dir-interpolation/pom.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng3904</groupId>
+ <artifactId>test</artifactId>
+ <version>0.1</version>
+ <packaging>jar</packaging>
+
+ <name>Maven Integration Test :: MNG-3904</name>
+ <description>
+ Test that properties which refer to build directories which in turn refer to other build directories are
+ properly interpolated.
+ </description>
+
+ <properties>
+ <!-- These are the properties of interest -->
+ <dir0>${project.build.outputDirectory}/dir0</dir0>
+ <dir1>${project.build.testSourceDirectory}/dir1</dir1>
+ <dir2>${project.reporting.outputDirectory}/dir2</dir2>
+ </properties>
+
+ <build>
+ <!-- Test properties which finally refer to ${project.basedir} -->
+ <directory>${project.basedir}/target</directory>
+ <outputDirectory>${project.build.directory}/classes</outputDirectory>
+ <!-- Test properties which finally refer to ${basedir} -->
+ <sourceDirectory>${basedir}/src</sourceDirectory>
+ <testSourceDirectory>${project.build.sourceDirectory}/test</testSourceDirectory>
+ </build>
+
+ <reporting>
+ <outputDirectory>${project.build.directory}/site</outputDirectory>
+ </reporting>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/parent-inheritance/child3.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/parent-inheritance/child3.xml
new file mode 100644
index 00000000..873f6f97
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/parent-inheritance/child3.xml
@@ -0,0 +1,7 @@
+<project>
+ <groupId>gid</groupId>
+ <artifactId>child-3</artifactId>
+ <version>1.0</version>
+ <packaging>pom</packaging>
+ <modelVersion>4.0.0</modelVersion>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/parent-inheritance/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/parent-inheritance/pom.xml
new file mode 100644
index 00000000..89209d79
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/parent-inheritance/pom.xml
@@ -0,0 +1,11 @@
+<project>
+ <parent>
+ <groupId>gid</groupId>
+ <artifactId>child-3</artifactId>
+ <version>1.0</version>
+ <relativePath>child3.xml</relativePath>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>child-2</artifactId>
+ <packaging>pom</packaging>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/parent-inheritance/sub/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/parent-inheritance/sub/pom.xml
new file mode 100644
index 00000000..2d4671ed
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/parent-inheritance/sub/pom.xml
@@ -0,0 +1,9 @@
+<project>
+ <parent>
+ <groupId>gid</groupId>
+ <artifactId>child-2</artifactId>
+ <version>1.0</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>child-1</artifactId>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/parent-interpolation/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/parent-interpolation/pom.xml
new file mode 100644
index 00000000..d2ae6ea2
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/parent-interpolation/pom.xml
@@ -0,0 +1,16 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.sonatype.nexus</groupId>
+ <artifactId>nexus</artifactId>
+ <version>1.3.0-SNAPSHOT</version>
+ <packaging>pom</packaging>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.modello</groupId>
+ <artifactId>modello-maven-plugin</artifactId>
+ <version>${project.version}</version>
+ </plugin>
+ </plugins>
+ </build>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/parent-interpolation/sub/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/parent-interpolation/sub/pom.xml
new file mode 100644
index 00000000..752852b1
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/parent-interpolation/sub/pom.xml
@@ -0,0 +1,9 @@
+<project>
+ <parent>
+ <groupId>org.sonatype.nexus</groupId>
+ <artifactId>nexus</artifactId>
+ <version>1.3.0-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>a</artifactId>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/parent-pom-packaging/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/parent-pom-packaging/pom.xml
new file mode 100644
index 00000000..16952455
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/parent-pom-packaging/pom.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng4283</groupId>
+ <artifactId>parent</artifactId>
+ <version>0.1</version>
+ <!-- NOTE: Any packaging other than "pom" must be rejected for a parent POM -->
+ <packaging>jar</packaging>
+
+ <name>Maven Integration Test :: MNG-4283</name>
+ <description>
+ Test that the model builder fails when a parent POM has not "pom" packaging.
+ </description>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/parent-pom-packaging/sub/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/parent-pom-packaging/sub/pom.xml
new file mode 100644
index 00000000..eca47eb3
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/parent-pom-packaging/sub/pom.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.maven.its.mng4283</groupId>
+ <artifactId>parent</artifactId>
+ <version>0.1</version>
+ </parent>
+
+ <groupId>org.apache.maven.its.mng4283</groupId>
+ <artifactId>test</artifactId>
+ <version>0.1</version>
+ <packaging>jar</packaging>
+
+ <name>Maven Integration Test :: MNG-4283</name>
+ <description>
+ Test that the model builder fails when a parent POM has not "pom" packaging.
+ </description>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/platform-file-separator/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/platform-file-separator/pom.xml
new file mode 100644
index 00000000..26ba2943
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/platform-file-separator/pom.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng3877</groupId>
+ <artifactId>test</artifactId>
+ <version>1.0</version>
+ <packaging>jar</packaging>
+
+ <name>Maven Integration Test :: MNG-3877</name>
+ <description>
+ Verify that paths to project directories use the platform-specific file separator.
+ </description>
+
+ <build>
+ <filters>
+ <filter>src/main/filters/it.properties</filter>
+ </filters>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-config-append/no-profile/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-config-append/no-profile/pom.xml
new file mode 100644
index 00000000..60180d51
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-config-append/no-profile/pom.xml
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng2591</groupId>
+ <artifactId>parent</artifactId>
+ <version>1.0</version>
+ <packaging>pom</packaging>
+
+ <name>Maven Integration Test :: MNG-2591</name>
+ <description>
+ Test aggregation of list configuration items for build plugins when using
+ 'combine.children=append' attribute.
+ </description>
+
+ <modules>
+ <module>subproject</module>
+ </modules>
+
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <!-- inherit via <pluginManagement> -->
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-configuration</artifactId>
+ <version>2.1-SNAPSHOT</version>
+ <inherited>true</inherited>
+ <configuration>
+ <listParam>
+ <!-- NOTE: These values are deliberately not in alpha order! -->
+ <listParam>PARENT-1</listParam>
+ <listParam>PARENT-3</listParam>
+ <listParam>PARENT-2</listParam>
+ <listParam>PARENT-4</listParam>
+ </listParam>
+ </configuration>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ <plugins>
+ <plugin>
+ <!-- inherit not via <pluginManagement> -->
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-configuration</artifactId>
+ <version>2.1-SNAPSHOT</version>
+ <inherited>true</inherited>
+ <configuration>
+ <stringParams>
+ <!-- NOTE: These values are deliberately not in alpha order! -->
+ <stringParam>PARENT-1</stringParam>
+ <stringParam>PARENT-3</stringParam>
+ <stringParam>PARENT-2</stringParam>
+ <stringParam>PARENT-4</stringParam>
+ </stringParams>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-config-append/no-profile/subproject/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-config-append/no-profile/subproject/pom.xml
new file mode 100644
index 00000000..cef53d32
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-config-append/no-profile/subproject/pom.xml
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.maven.its.mng2591</groupId>
+ <artifactId>parent</artifactId>
+ <version>1.0</version>
+ </parent>
+
+ <artifactId>subproject</artifactId>
+ <version>1.0</version>
+ <packaging>jar</packaging>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-configuration</artifactId>
+ <version>2.1-SNAPSHOT</version>
+ <configuration>
+ <propertiesFile>target/config.properties</propertiesFile>
+ <stringParams combine.children="append">
+ <!-- NOTE: These values are deliberately not in alpha order! -->
+ <stringParam>CHILD-1</stringParam>
+ <stringParam>CHILD-3</stringParam>
+ <stringParam>CHILD-2</stringParam>
+ <stringParam>CHILD-4</stringParam>
+ </stringParams>
+ <listParam combine.children="append">
+ <!-- NOTE: These values are deliberately not in alpha order! -->
+ <listParam>CHILD-1</listParam>
+ <listParam>CHILD-3</listParam>
+ <listParam>CHILD-2</listParam>
+ <listParam>CHILD-4</listParam>
+ </listParam>
+ </configuration>
+ <executions>
+ <execution>
+ <id>test</id>
+ <phase>validate</phase>
+ <goals>
+ <goal>config</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-config-append/with-profile/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-config-append/with-profile/pom.xml
new file mode 100644
index 00000000..72ab3f45
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-config-append/with-profile/pom.xml
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng2591</groupId>
+ <artifactId>parent</artifactId>
+ <version>1.0</version>
+ <packaging>pom</packaging>
+
+ <name>Maven Integration Test :: MNG-2591</name>
+ <description>
+ Test aggregation of list configuration items for build plugins when using
+ 'combine.children=append' attribute.
+ </description>
+
+ <modules>
+ <module>subproject</module>
+ </modules>
+
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <!-- inherit via <pluginManagement> -->
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-configuration</artifactId>
+ <version>2.1-SNAPSHOT</version>
+ <inherited>true</inherited>
+ <configuration>
+ <listParam>
+ <!-- NOTE: These values are deliberately not in alpha order! -->
+ <listParam>PARENT-1</listParam>
+ <listParam>PARENT-3</listParam>
+ <listParam>PARENT-2</listParam>
+ <listParam>PARENT-4</listParam>
+ </listParam>
+ </configuration>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ <plugins>
+ <plugin>
+ <!-- inherit not via <pluginManagement> -->
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-configuration</artifactId>
+ <version>2.1-SNAPSHOT</version>
+ <inherited>true</inherited>
+ <configuration>
+ <stringParams>
+ <!-- NOTE: These values are deliberately not in alpha order! -->
+ <stringParam>PARENT-1</stringParam>
+ <stringParam>PARENT-3</stringParam>
+ <stringParam>PARENT-2</stringParam>
+ <stringParam>PARENT-4</stringParam>
+ </stringParams>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+ <profiles>
+ <profile>
+ <!-- an active but empty profile to ensure profile injection does not interfere with plugin configuration -->
+ <id>parent</id>
+ <activation>
+ <activeByDefault>true</activeByDefault>
+ </activation>
+ </profile>
+ </profiles>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-config-append/with-profile/subproject/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-config-append/with-profile/subproject/pom.xml
new file mode 100644
index 00000000..70235030
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-config-append/with-profile/subproject/pom.xml
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.maven.its.mng2591</groupId>
+ <artifactId>parent</artifactId>
+ <version>1.0</version>
+ </parent>
+
+ <artifactId>subproject</artifactId>
+ <version>1.0</version>
+ <packaging>jar</packaging>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-configuration</artifactId>
+ <version>2.1-SNAPSHOT</version>
+ <configuration>
+ <propertiesFile>target/config.properties</propertiesFile>
+ <stringParams combine.children="append">
+ <!-- NOTE: These values are deliberately not in alpha order! -->
+ <stringParam>CHILD-1</stringParam>
+ <stringParam>CHILD-3</stringParam>
+ <stringParam>CHILD-2</stringParam>
+ <stringParam>CHILD-4</stringParam>
+ </stringParams>
+ <listParam combine.children="append">
+ <!-- NOTE: These values are deliberately not in alpha order! -->
+ <listParam>CHILD-1</listParam>
+ <listParam>CHILD-3</listParam>
+ <listParam>CHILD-2</listParam>
+ <listParam>CHILD-4</listParam>
+ </listParam>
+ </configuration>
+ <executions>
+ <execution>
+ <id>test</id>
+ <phase>validate</phase>
+ <goals>
+ <goal>config</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+ <profiles>
+ <profile>
+ <!-- an active but empty profile to ensure profile injection does not interfere with plugin configuration -->
+ <id>child</id>
+ <activation>
+ <activeByDefault>true</activeByDefault>
+ </activation>
+ </profile>
+ </profiles>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-config-attributes/w-plugin-mngt/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-config-attributes/w-plugin-mngt/pom.xml
new file mode 100644
index 00000000..2f350715
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-config-attributes/w-plugin-mngt/pom.xml
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng4053</groupId>
+ <artifactId>test2</artifactId>
+ <version>1.0-SNAPSHOT</version>
+
+ <name>Maven Integration Test :: MNG-4053</name>
+ <description>
+ Verify that attributes in plugin configuration elements are not erroneously duplicated to other elements when
+ plugin management is used.
+ </description>
+
+ <build>
+ <!-- NOTE: This test used plugin management for the IT plugin -->
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-configuration</artifactId>
+ <version>2.1-SNAPSHOT</version>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-configuration</artifactId>
+ <version>2.1-SNAPSHOT</version>
+ <configuration>
+ <propertiesFile>target/config.properties</propertiesFile>
+ <domParam>
+ <copy todir="src" overwrite="true">
+ <fileset dir="target"/>
+ </copy>
+ </domParam>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-config-attributes/w-profile/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-config-attributes/w-profile/pom.xml
new file mode 100644
index 00000000..f2d8c6c0
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-config-attributes/w-profile/pom.xml
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng4053</groupId>
+ <artifactId>test3</artifactId>
+ <version>1.0-SNAPSHOT</version>
+
+ <name>Maven Integration Test :: MNG-4053</name>
+ <description>
+ Verify that attributes in plugin configuration elements are not erroneously duplicated to other elements when
+ plugin management and a profile are used.
+ </description>
+
+ <build>
+ <!-- NOTE: This test used plugin management for the IT plugin -->
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-configuration</artifactId>
+ <version>2.1-SNAPSHOT</version>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+
+ <profiles>
+ <profile>
+ <!-- NOTE: This test injects the plugin configuration via a profile -->
+ <id>maven-core-it</id>
+ <activation>
+ <activeByDefault>true</activeByDefault>
+ </activation>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-configuration</artifactId>
+ <version>2.1-SNAPSHOT</version>
+ <configuration>
+ <propertiesFile>target/config.properties</propertiesFile>
+ <domParam>
+ <copy todir="src" overwrite="true">
+ <fileset dir="target"/>
+ </copy>
+ </domParam>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-config-attributes/wo-plugin-mngt/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-config-attributes/wo-plugin-mngt/pom.xml
new file mode 100644
index 00000000..c844b447
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-config-attributes/wo-plugin-mngt/pom.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng4053</groupId>
+ <artifactId>test1</artifactId>
+ <version>1.0-SNAPSHOT</version>
+
+ <name>Maven Integration Test :: MNG-4053</name>
+ <description>
+ Verify that attributes in plugin configuration elements are not erroneously duplicated to other elements when
+ no plugin management is used.
+ </description>
+
+ <build>
+ <!-- NOTE: This test does not use plugin management for the IT plugin -->
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-configuration</artifactId>
+ <version>2.1-SNAPSHOT</version>
+ <configuration>
+ <propertiesFile>target/config.properties</propertiesFile>
+ <domParam>
+ <copy todir="src" overwrite="true">
+ <fileset dir="target"/>
+ </copy>
+ </domParam>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-config-merging/child/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-config-merging/child/pom.xml
new file mode 100644
index 00000000..f8172448
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-config-merging/child/pom.xml
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.maven.its.mng3836</groupId>
+ <artifactId>parent</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ </parent>
+
+ <groupId>org.apache.maven.its.mng3836</groupId>
+ <artifactId>child</artifactId>
+ <version>1.0-SNAPSHOT</version>
+
+ <name>Maven Integration Test :: MNG-3836</name>
+ <description>
+ Verify that children can *override* inherited plugin configuration.
+ </description>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-configuration</artifactId>
+ <version>2.1-SNAPSHOT</version>
+ <configuration>
+ <!--
+ All of these values should override the ones inherited from the parent. In particular, collections should not
+ be merged with the values given by the parent POM.
+ -->
+ <propertiesFile>PASSED</propertiesFile>
+ <stringParams>
+ <stringParam>PASSED-1</stringParam>
+ <stringParam>PASSED-3</stringParam>
+ <stringParam>PASSED-2</stringParam>
+ <stringParam>PASSED-4</stringParam>
+ </stringParams>
+ <listParam>
+ <listParam>PASSED-1</listParam>
+ <listParam>PASSED-3</listParam>
+ <listParam>PASSED-2</listParam>
+ <listParam>PASSED-4</listParam>
+ </listParam>
+ </configuration>
+ <executions>
+ <execution>
+ <phase>validate</phase>
+ <goals>
+ <goal>config</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-config-merging/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-config-merging/pom.xml
new file mode 100644
index 00000000..12f2c2d6
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-config-merging/pom.xml
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng3836</groupId>
+ <artifactId>parent</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <packaging>pom</packaging>
+
+ <name>Maven Integration Test :: MNG-3836</name>
+ <description>
+ Verify that children can *override* inherited plugin configuration.
+ </description>
+
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-configuration</artifactId>
+ <version>2.1-SNAPSHOT</version>
+ <configuration>
+ <propertiesFile>FAILED</propertiesFile>
+ <stringParams>
+ <stringParam>FAILED-1</stringParam>
+ <stringParam>FAILED-3</stringParam>
+ <stringParam>FAILED-2</stringParam>
+ <stringParam>FAILED-4</stringParam>
+ </stringParams>
+ </configuration>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-configuration</artifactId>
+ <version>2.1-SNAPSHOT</version>
+ <configuration>
+ <propertiesFile>FAILED</propertiesFile>
+ <listParam>
+ <listParam>FAILED-1</listParam>
+ <listParam>FAILED-3</listParam>
+ <listParam>FAILED-2</listParam>
+ <listParam>FAILED-4</listParam>
+ </listParam>
+ <parent>PASSED</parent>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-config-order/w-plugin-mngt/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-config-order/w-plugin-mngt/pom.xml
new file mode 100644
index 00000000..7d7dfd81
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-config-order/w-plugin-mngt/pom.xml
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng3827</groupId>
+ <artifactId>test2</artifactId>
+ <version>1.0-SNAPSHOT</version>
+
+ <name>Maven Integration Test :: MNG-3827</name>
+ <description>
+ Verify that plain plugin configuration works correctly.
+ </description>
+
+ <build>
+ <!-- This project uses plugin management for the test plugin -->
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-configuration</artifactId>
+ <version>2.1-SNAPSHOT</version>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-configuration</artifactId>
+ <configuration>
+ <stringParams>
+ <stringParam>one</stringParam>
+ <stringParam>two</stringParam>
+ <stringParam>three</stringParam>
+ <stringParam>four</stringParam>
+ </stringParams>
+ </configuration>
+ <executions>
+ <execution>
+ <phase>validate</phase>
+ <goals>
+ <goal>config</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-config-order/wo-plugin-mngt/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-config-order/wo-plugin-mngt/pom.xml
new file mode 100644
index 00000000..e300fe1e
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-config-order/wo-plugin-mngt/pom.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng3827</groupId>
+ <artifactId>test1</artifactId>
+ <version>1.0-SNAPSHOT</version>
+
+ <name>Maven Integration Test :: MNG-3827</name>
+ <description>
+ Verify that plain plugin configuration works correctly.
+ </description>
+
+ <build>
+ <!-- This project does not use plugin management for the test plugin -->
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-configuration</artifactId>
+ <version>1.0</version>
+ <configuration>
+ <stringParams>
+ <stringParam>one</stringParam>
+ <stringParam>two</stringParam>
+ <stringParam>three</stringParam>
+ <stringParam>four</stringParam>
+ </stringParams>
+ </configuration>
+ <executions>
+ <execution>
+ <phase>validate</phase>
+ <goals>
+ <goal>config</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-config-properties/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-config-properties/pom.xml
new file mode 100644
index 00000000..e5660391
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-config-properties/pom.xml
@@ -0,0 +1,30 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>a</groupId>
+ <artifactId>b</artifactId>
+ <version>1.0</version>
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ </plugin>
+ </plugins>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>2.4</version>
+ <configuration>
+ <systemProperties>
+ <property>
+ <name>my.property</name>
+ <value>my.value</value>
+ </property>
+ </systemProperties>
+ </configuration>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-exec-config-order/w-plugin-mngt/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-exec-config-order/w-plugin-mngt/pom.xml
new file mode 100644
index 00000000..9f66b49e
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-exec-config-order/w-plugin-mngt/pom.xml
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng3827</groupId>
+ <artifactId>test2</artifactId>
+ <version>1.0-SNAPSHOT</version>
+
+ <name>Maven Integration Test :: MNG-3864</name>
+ <description>
+ Verify that plain per-execution plugin configuration works correctly.
+ </description>
+
+ <build>
+ <!-- This project uses plugin management for the test plugin -->
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-configuration</artifactId>
+ <version>2.1-SNAPSHOT</version>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-configuration</artifactId>
+ <executions>
+ <execution>
+ <phase>validate</phase>
+ <goals>
+ <goal>config</goal>
+ </goals>
+ <configuration>
+ <stringParams>
+ <stringParam>one</stringParam>
+ <stringParam>two</stringParam>
+ <stringParam>three</stringParam>
+ <stringParam>four</stringParam>
+ </stringParams>
+ <propertiesParam>
+ <property>
+ <name>key1</name>
+ <value>value1</value>
+ </property>
+ <property>
+ <name>key2</name>
+ <value>value2</value>
+ </property>
+ </propertiesParam>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-exec-config-order/wo-plugin-mngt/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-exec-config-order/wo-plugin-mngt/pom.xml
new file mode 100644
index 00000000..4e1eafe3
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-exec-config-order/wo-plugin-mngt/pom.xml
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng3827</groupId>
+ <artifactId>test1</artifactId>
+ <version>1.0-SNAPSHOT</version>
+
+ <name>Maven Integration Test :: MNG-3864</name>
+ <description>
+ Verify that plain per-execution plugin configuration works correctly.
+ </description>
+
+ <build>
+ <!-- This project does not use plugin management for the test plugin -->
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-configuration</artifactId>
+ <version>1.0</version>
+ <executions>
+ <execution>
+ <phase>validate</phase>
+ <goals>
+ <goal>config</goal>
+ </goals>
+ <configuration>
+ <stringParams>
+ <stringParam>one</stringParam>
+ <stringParam>two</stringParam>
+ <stringParam>three</stringParam>
+ <stringParam>four</stringParam>
+ </stringParams>
+ <propertiesParam>
+ <property>
+ <name>key1</name>
+ <value>value1</value>
+ </property>
+ <property>
+ <name>key2</name>
+ <value>value2</value>
+ </property>
+ </propertiesParam>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-exec-goals-order/w-plugin-mngt/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-exec-goals-order/w-plugin-mngt/pom.xml
new file mode 100644
index 00000000..d4ac3b0e
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-exec-goals-order/w-plugin-mngt/pom.xml
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng3886</groupId>
+ <artifactId>test</artifactId>
+ <version>0.1</version>
+ <packaging>pom</packaging>
+
+ <name>Maven Integration Test :: MNG-3886</name>
+ <description>
+ Test that the goals from a plugin execution are executed in the order given by the POM, regardless whether
+ plugin management is present or not.
+ </description>
+
+ <build>
+ <!-- This project uses plugin management for the test plugin -->
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-a</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-a</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <executions>
+ <execution>
+ <goals>
+ <goal>b</goal>
+ <goal>a</goal>
+ <goal>d</goal>
+ <goal>c</goal>
+ <goal>e</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-exec-goals-order/wo-plugin-mngt/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-exec-goals-order/wo-plugin-mngt/pom.xml
new file mode 100644
index 00000000..438d9d1a
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-exec-goals-order/wo-plugin-mngt/pom.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng3886</groupId>
+ <artifactId>test</artifactId>
+ <version>0.1</version>
+ <packaging>pom</packaging>
+
+ <name>Maven Integration Test :: MNG-3886</name>
+ <description>
+ Test that the goals from a plugin execution are executed in the order given by the POM, regardless whether
+ plugin management is present or not.
+ </description>
+
+ <build>
+ <!-- This project does not use plugin management for the test plugin -->
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-a</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <executions>
+ <execution>
+ <goals>
+ <goal>b</goal>
+ <goal>a</goal>
+ <goal>d</goal>
+ <goal>c</goal>
+ <goal>e</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-exec-inheritance/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-exec-inheritance/pom.xml
new file mode 100644
index 00000000..2b534d76
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-exec-inheritance/pom.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng4129</groupId>
+ <artifactId>parent</artifactId>
+ <version>0.1</version>
+ <packaging>pom</packaging>
+
+ <name>Maven Integration Test :: MNG-4129</name>
+ <description>
+ Verify that plugin executions defined in the parent with inherited=false are not executed in child modules.
+ </description>
+
+ <modules>
+ <module>child-1</module>
+ <module>child-2</module>
+ </modules>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-log-file</artifactId>
+ <version>2.1-SNAPSHOT</version>
+ <executions>
+ <execution>
+ <id>inherited-execution</id>
+ <inherited>true</inherited>
+ <phase>validate</phase>
+ <goals>
+ <goal>log-string</goal>
+ </goals>
+ <configuration>
+ <logFile>target/executions.txt</logFile>
+ <string>inherited-execution</string>
+ </configuration>
+ </execution>
+ <execution>
+ <id>non-inherited-execution</id>
+ <inherited>false</inherited>
+ <phase>validate</phase>
+ <goals>
+ <goal>log-string</goal>
+ </goals>
+ <configuration>
+ <logFile>target/executions.txt</logFile>
+ <string>non-inherited-execution</string>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-exec-inheritance/w-merge/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-exec-inheritance/w-merge/pom.xml
new file mode 100644
index 00000000..f60cfd5c
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-exec-inheritance/w-merge/pom.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.maven.its.mng4129</groupId>
+ <artifactId>parent</artifactId>
+ <version>0.1</version>
+ </parent>
+
+ <artifactId>child-1</artifactId>
+
+ <name>Maven Integration Test :: MNG-4129 :: Child-1</name>
+ <description>
+ Verify that plugin executions defined in the parent with inherited=false are not executed in child modules.
+ </description>
+
+ <build>
+ <plugins>
+ <!-- NOTE: It's essential part of this test variant to redefine the test plugin again, i.e. trigger plugin merging -->
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-log-file</artifactId>
+ <version>2.1-SNAPSHOT</version>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-exec-inheritance/wo-merge/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-exec-inheritance/wo-merge/pom.xml
new file mode 100644
index 00000000..23cfc0c2
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-exec-inheritance/wo-merge/pom.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.maven.its.mng4129</groupId>
+ <artifactId>parent</artifactId>
+ <version>0.1</version>
+ </parent>
+
+ <artifactId>child-2</artifactId>
+
+ <name>Maven Integration Test :: MNG-4129 :: Child-2</name>
+ <description>
+ Verify that plugin executions defined in the parent with inherited=false are not executed in child modules.
+ </description>
+
+ <build>
+ <plugins>
+ <!-- NOTE: It's essential part of this test variant to *not* define the test plugin again, i.e. bypass plugin merging -->
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-exec-merging-version-insensitive/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-exec-merging-version-insensitive/pom.xml
new file mode 100644
index 00000000..b64af3ae
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-exec-merging-version-insensitive/pom.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng3916</groupId>
+ <artifactId>parent</artifactId>
+ <version>0.1</version>
+ <packaging>pom</packaging>
+
+ <name>Maven Integration Test :: MNG-3943</name>
+ <description>
+ Test that plugin executions are properly merged during inheritance, even if the child uses a different
+ plugin version than the parent.
+ </description>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-a</artifactId>
+ <!-- NOTE: Use different version than child -->
+ <version>1.0</version>
+ <executions>
+ <execution>
+ <id>parent-1</id>
+ <phase>parent-1</phase>
+ </execution>
+ <execution>
+ <id>parent-2</id>
+ <phase>parent-2</phase>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-exec-merging-version-insensitive/sub/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-exec-merging-version-insensitive/sub/pom.xml
new file mode 100644
index 00000000..f96116ad
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-exec-merging-version-insensitive/sub/pom.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.maven.its.mng3916</groupId>
+ <artifactId>parent</artifactId>
+ <version>0.1</version>
+ </parent>
+
+ <artifactId>child</artifactId>
+
+ <name>Maven Integration Test :: MNG-3943</name>
+ <description>
+ Test that plugin executions are properly merged during inheritance, even if the child uses a different
+ plugin version than the parent.
+ </description>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-a</artifactId>
+ <!-- NOTE: Use different version than parent -->
+ <version>2.0</version>
+ <executions>
+ <execution>
+ <id>child-1</id>
+ <phase>child-1</phase>
+ </execution>
+ <execution>
+ <id>child-2</id>
+ <phase>child-2</phase>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-exec-merging-wo-version/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-exec-merging-wo-version/pom.xml
new file mode 100644
index 00000000..127fa259
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-exec-merging-wo-version/pom.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng3916</groupId>
+ <artifactId>parent</artifactId>
+ <version>0.1</version>
+ <packaging>pom</packaging>
+
+ <name>Maven Integration Test :: MNG-3916</name>
+ <description>
+ Test that plugin executions are properly merged during inheritance, even if the child plugin section has no
+ version.
+ </description>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-a</artifactId>
+ <version>1.0</version>
+ <executions>
+ <execution>
+ <id>parent-1</id>
+ <phase>parent-1</phase>
+ </execution>
+ <execution>
+ <id>parent-2</id>
+ <phase>parent-2</phase>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-exec-merging-wo-version/sub/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-exec-merging-wo-version/sub/pom.xml
new file mode 100644
index 00000000..61841aec
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-exec-merging-wo-version/sub/pom.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.maven.its.mng3916</groupId>
+ <artifactId>parent</artifactId>
+ <version>0.1</version>
+ </parent>
+
+ <artifactId>child</artifactId>
+
+ <name>Maven Integration Test :: MNG-3916</name>
+ <description>
+ Test that plugin executions are properly merged during inheritance, even if the child plugin section has no
+ version.
+ </description>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-a</artifactId>
+ <!-- NOTE: <version> element deliberately omitted here -->
+ <executions>
+ <execution>
+ <id>child-1</id>
+ <phase>child-1</phase>
+ </execution>
+ <execution>
+ <id>child-2</id>
+ <phase>child-2</phase>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-exec-merging/w-plugin-mngt/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-exec-merging/w-plugin-mngt/pom.xml
new file mode 100644
index 00000000..6bcfee56
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-exec-merging/w-plugin-mngt/pom.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng3938</groupId>
+ <artifactId>parent</artifactId>
+ <version>0.1</version>
+ <packaging>pom</packaging>
+
+ <name>Maven Integration Test :: MNG-3938</name>
+ <description>
+ Test that plugin executions with the same id are merged during inheritance, especially executions using the
+ default id, regardless whether the id is given explicitly by the user or implicitly assumed from defaults.
+ </description>
+
+ <build>
+ <!-- This project uses plugin management for the test plugin -->
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-a</artifactId>
+ <version>2.1-SNAPSHOT</version>
+ <executions>
+ <execution>
+ <!-- NOTE: Implicitly reference "default" id here, i.e. omit the <id> element -->
+ <phase>parent-default</phase>
+ </execution>
+ <execution>
+ <id>non-default</id>
+ <phase>parent-non-default</phase>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-exec-merging/w-plugin-mngt/sub/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-exec-merging/w-plugin-mngt/sub/pom.xml
new file mode 100644
index 00000000..3129ad02
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-exec-merging/w-plugin-mngt/sub/pom.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.maven.its.mng3938</groupId>
+ <artifactId>parent</artifactId>
+ <version>0.1</version>
+ </parent>
+
+ <artifactId>child</artifactId>
+
+ <name>Maven Integration Test :: MNG-3938</name>
+ <description>
+ Test that plugin executions with the same id are merged during inheritance, especially executions using the
+ default id, regardless whether the id is given explicitly by the user or implicitly assumed from defaults.
+ </description>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-a</artifactId>
+ <version>2.1-SNAPSHOT</version>
+ <executions>
+ <execution>
+ <!-- NOTE: Explicitly reference "default" id here -->
+ <id>default</id>
+ <phase>child-default</phase>
+ </execution>
+ <execution>
+ <id>non-default</id>
+ <phase>child-non-default</phase>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-exec-merging/wo-plugin-mngt/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-exec-merging/wo-plugin-mngt/pom.xml
new file mode 100644
index 00000000..63db85f6
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-exec-merging/wo-plugin-mngt/pom.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng3938</groupId>
+ <artifactId>parent</artifactId>
+ <version>0.1</version>
+ <packaging>pom</packaging>
+
+ <name>Maven Integration Test :: MNG-3938</name>
+ <description>
+ Test that plugin executions with the same id are merged during inheritance, especially executions using the
+ default id, regardless whether the id is given explicitly by the user or implicitly assumed from defaults.
+ </description>
+
+ <build>
+ <!-- This project does not use plugin management for the test plugin -->
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-a</artifactId>
+ <version>2.1-SNAPSHOT</version>
+ <executions>
+ <execution>
+ <!-- NOTE: Implicitly reference "default" id here, i.e. omit the <id> element -->
+ <phase>parent-default</phase>
+ </execution>
+ <execution>
+ <id>non-default</id>
+ <phase>parent-non-default</phase>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-exec-merging/wo-plugin-mngt/sub/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-exec-merging/wo-plugin-mngt/sub/pom.xml
new file mode 100644
index 00000000..3129ad02
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-exec-merging/wo-plugin-mngt/sub/pom.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.maven.its.mng3938</groupId>
+ <artifactId>parent</artifactId>
+ <version>0.1</version>
+ </parent>
+
+ <artifactId>child</artifactId>
+
+ <name>Maven Integration Test :: MNG-3938</name>
+ <description>
+ Test that plugin executions with the same id are merged during inheritance, especially executions using the
+ default id, regardless whether the id is given explicitly by the user or implicitly assumed from defaults.
+ </description>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-a</artifactId>
+ <version>2.1-SNAPSHOT</version>
+ <executions>
+ <execution>
+ <!-- NOTE: Explicitly reference "default" id here -->
+ <id>default</id>
+ <phase>child-default</phase>
+ </execution>
+ <execution>
+ <id>non-default</id>
+ <phase>child-non-default</phase>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-exec-order-and-default-exec/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-exec-order-and-default-exec/pom.xml
new file mode 100644
index 00000000..864fedb9
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-exec-order-and-default-exec/pom.xml
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng4332</groupId>
+ <artifactId>test</artifactId>
+ <version>0.1</version>
+ <!-- NOTE: The upper-case packaging name is intentional and triggers a special mode in the EmptyLifecycleExecutor -->
+ <packaging>JAR</packaging>
+
+ <name>Maven Integration Test :: MNG-4332</name>
+ <description>
+ Verify that default plugin executions contributed by the packaging are executed before user-defined
+ executions from the POM's build section, regardless whether the executions are defined in the regular
+ plugins section or the plugin management section.
+ </description>
+
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <artifactId>maven-resources-plugin</artifactId>
+ <version>2.2</version>
+ <executions>
+ <execution>
+ <id>test-1</id>
+ <goals>
+ <goal>resources</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ <plugins>
+ <plugin>
+ <artifactId>maven-resources-plugin</artifactId>
+ <version>2.2</version>
+ <executions>
+ <execution>
+ <id>test-2</id>
+ <goals>
+ <goal>resources</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-exec-order-with-lifecycle/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-exec-order-with-lifecycle/pom.xml
new file mode 100644
index 00000000..6035e816
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-exec-order-with-lifecycle/pom.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng4341</groupId>
+ <artifactId>test</artifactId>
+ <version>0.1</version>
+ <!-- NOTE: The upper-case packaging name is intentional and triggers a special mode in the EmptyLifecycleExecutor -->
+ <packaging>JAR</packaging>
+
+ <name>Maven Integration Test :: MNG-4341</name>
+ <description>
+ Test that plugins bound to the same phase get executed in POM order even if one of the plugins participates
+ in the default lifecycle bindings for the project's packaging.
+ </description>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-log-file</artifactId>
+ <version>2.1-SNAPSHOT</version>
+ </plugin>
+ <plugin>
+ <!-- NOTE: It's essential that this plugin is also referenced by the default lifecycle bindings -->
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-resources-plugin</artifactId>
+ <version>0.1-stub-SNAPSHOT</version>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-exec-order/w-plugin-mngt/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-exec-order/w-plugin-mngt/pom.xml
new file mode 100644
index 00000000..2c552d4c
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-exec-order/w-plugin-mngt/pom.xml
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng3887</groupId>
+ <artifactId>test</artifactId>
+ <version>0.1</version>
+ <packaging>pom</packaging>
+
+ <name>Maven Integration Test :: MNG-3887</name>
+ <description>
+ Test that multiple plugin executions bound to the same phase are executed in the order given by the POM.
+ </description>
+
+ <build>
+ <!-- This project uses plugin management for the test plugin -->
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-a</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-a</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <executions>
+ <execution>
+ <id>b</id>
+ <phase>validate</phase>
+ </execution>
+ <execution>
+ <id>a</id>
+ <phase>validate</phase>
+ </execution>
+ <execution>
+ <id>d</id>
+ <phase>validate</phase>
+ </execution>
+ <execution>
+ <id>c</id>
+ <phase>validate</phase>
+ </execution>
+ <execution>
+ <id>e</id>
+ <phase>validate</phase>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-exec-order/wo-plugin-mngt/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-exec-order/wo-plugin-mngt/pom.xml
new file mode 100644
index 00000000..c4ceaae3
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-exec-order/wo-plugin-mngt/pom.xml
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng3887</groupId>
+ <artifactId>test</artifactId>
+ <version>0.1</version>
+ <packaging>pom</packaging>
+
+ <name>Maven Integration Test :: MNG-3887</name>
+ <description>
+ Test that multiple plugin executions bound to the same phase are executed in the order given by the POM.
+ </description>
+
+ <build>
+ <!-- This project does not use plugin management for the test plugin -->
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-a</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <executions>
+ <execution>
+ <id>b</id>
+ <phase>validate</phase>
+ </execution>
+ <execution>
+ <id>a</id>
+ <phase>validate</phase>
+ </execution>
+ <execution>
+ <id>d</id>
+ <phase>validate</phase>
+ </execution>
+ <execution>
+ <id>c</id>
+ <phase>validate</phase>
+ </execution>
+ <execution>
+ <id>e</id>
+ <phase>validate</phase>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-exec-w-and-wo-id/w-plugin-mngt/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-exec-w-and-wo-id/w-plugin-mngt/pom.xml
new file mode 100644
index 00000000..fbae181f
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-exec-w-and-wo-id/w-plugin-mngt/pom.xml
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng4000</groupId>
+ <artifactId>test2</artifactId>
+ <version>0.1</version>
+
+ <name>Maven Integration Test :: MNG-4000</name>
+ <description>
+ Test that plugin executions without id are not lost among other plugin executions.
+ </description>
+
+ <build>
+ <!-- NOTE: This test uses plugin management for the IT plugin. -->
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-log-file</artifactId>
+ <version>2.1-SNAPSHOT</version>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-log-file</artifactId>
+ <configuration>
+ <logFile>target/exec.log</logFile>
+ <string>exec</string>
+ </configuration>
+ <executions>
+ <execution>
+ <id>exec-1</id>
+ <phase>validate</phase>
+ <goals>
+ <goal>log-string</goal>
+ </goals>
+ </execution>
+ <execution>
+ <!-- NOTE: <id> deliberately omitted here! -->
+ <phase>validate</phase>
+ <goals>
+ <goal>log-string</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-exec-w-and-wo-id/wo-plugin-mngt/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-exec-w-and-wo-id/wo-plugin-mngt/pom.xml
new file mode 100644
index 00000000..7910084f
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-exec-w-and-wo-id/wo-plugin-mngt/pom.xml
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng4000</groupId>
+ <artifactId>test1</artifactId>
+ <version>0.1</version>
+
+ <name>Maven Integration Test :: MNG-4000</name>
+ <description>
+ Test that plugin executions without id are not lost among other plugin executions.
+ </description>
+
+ <build>
+ <!-- NOTE: This test does not use plugin management for the IT plugin. -->
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-log-file</artifactId>
+ <version>2.1-SNAPSHOT</version>
+ <configuration>
+ <logFile>target/exec.log</logFile>
+ <string>exec</string>
+ </configuration>
+ <executions>
+ <execution>
+ <id>exec-1</id>
+ <phase>validate</phase>
+ <goals>
+ <goal>log-string</goal>
+ </goals>
+ </execution>
+ <execution>
+ <!-- NOTE: <id> deliberately omitted here! -->
+ <phase>validate</phase>
+ <goals>
+ <goal>log-string</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-inheritance-merge-order/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-inheritance-merge-order/pom.xml
new file mode 100644
index 00000000..e42b0306
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-inheritance-merge-order/pom.xml
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng4415</groupId>
+ <artifactId>parent</artifactId>
+ <version>0.1</version>
+ <packaging>pom</packaging>
+
+ <name>Maven Integration Test :: MNG-4415</name>
+ <description>
+ Test that merging of plugins during inheritance follows these rules regarding ordering:
+ parent: X -> A -> B -> D -> E
+ child: Y -> A -> C -> D -> F
+ result: X -> Y -> A -> B -> C -> D -> E -> F
+ </description>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-error</artifactId>
+ <version>2.1-SNAPSHOT</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-dependency-resolution</artifactId>
+ <version>2.1-SNAPSHOT</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-packaging</artifactId>
+ <version>2.1-SNAPSHOT</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-expression</artifactId>
+ <version>2.1-SNAPSHOT</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-fork</artifactId>
+ <version>2.1-SNAPSHOT</version>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-inheritance-merge-order/sub/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-inheritance-merge-order/sub/pom.xml
new file mode 100644
index 00000000..8d44b8cc
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-inheritance-merge-order/sub/pom.xml
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.maven.its.mng4415</groupId>
+ <artifactId>parent</artifactId>
+ <version>0.1</version>
+ </parent>
+
+ <groupId>org.apache.maven.its.mng4415</groupId>
+ <artifactId>test</artifactId>
+ <version>0.1</version>
+
+ <name>Maven Integration Test :: MNG-4415</name>
+ <description>
+ Test that merging of plugins during inheritance follows these rules regarding ordering:
+ parent: X -> A -> B -> D -> E
+ child: Y -> A -> C -> D -> F
+ result: X -> Y -> A -> B -> C -> D -> E -> F
+ </description>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-configuration</artifactId>
+ <version>2.1-SNAPSHOT</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-dependency-resolution</artifactId>
+ <version>2.1-SNAPSHOT</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-log-file</artifactId>
+ <version>2.1-SNAPSHOT</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-expression</artifactId>
+ <version>2.1-SNAPSHOT</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-touch</artifactId>
+ <version>2.1-SNAPSHOT</version>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-inheritance-order/child/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-inheritance-order/child/pom.xml
new file mode 100644
index 00000000..5350fa87
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-inheritance-order/child/pom.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.maven.its.mng3808</groupId>
+ <artifactId>test</artifactId>
+ <version>0.1</version>
+ </parent>
+ <artifactId>child</artifactId>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-configuration</artifactId>
+ <version>2.1-SNAPSHOT</version>
+ </plugin>
+ </plugins>
+ </build>
+
+ <reporting>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-configuration</artifactId>
+ <version>2.1-SNAPSHOT</version>
+ </plugin>
+ </plugins>
+ </reporting>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-inheritance-order/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-inheritance-order/pom.xml
new file mode 100644
index 00000000..f66ae25c
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-inheritance-order/pom.xml
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng3808</groupId>
+ <artifactId>test</artifactId>
+ <version>0.1</version>
+ <packaging>pom</packaging>
+
+ <name>Maven Integration Test :: MNG-3808</name>
+ <description>
+ Test the reports are executeed in the order given in the POM.
+ </description>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-log-file</artifactId>
+ <version>2.1-SNAPSHOT</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-expression</artifactId>
+ <version>2.1-SNAPSHOT</version>
+ </plugin>
+ </plugins>
+ </build>
+
+ <reporting>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-log-file</artifactId>
+ <version>2.1-SNAPSHOT</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-expression</artifactId>
+ <version>2.1-SNAPSHOT</version>
+ </plugin>
+ </plugins>
+ </reporting>
+
+ <modules>
+ <module>child</module>
+ </modules>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-inheritance-simple/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-inheritance-simple/pom.xml
new file mode 100644
index 00000000..b73bfce5
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-inheritance-simple/pom.xml
@@ -0,0 +1,17 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>gid</groupId>
+ <artifactId>aid</artifactId>
+ <version>1.0</version>
+ <packaging>pom</packaging>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.modello</groupId>
+ <artifactId>modello-maven-plugin</artifactId>
+ <version>1.0-alpha-21</version>
+ </plugin>
+ </plugins>
+ </build>
+
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-inheritance-simple/sub/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-inheritance-simple/sub/pom.xml
new file mode 100644
index 00000000..f6ed4dd4
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-inheritance-simple/sub/pom.xml
@@ -0,0 +1,20 @@
+<project>
+ <parent>
+ <groupId>gid</groupId>
+ <artifactId>aid</artifactId>
+ <version>1.0</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.sonatype.nexus</groupId>
+ <artifactId>nexus</artifactId>
+ <version>1.3.0-SNAPSHOT</version>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.modello</groupId>
+ <artifactId>modello-maven-plugin2</artifactId>
+ <version>1.0-alpha-21</version>
+ </plugin>
+ </plugins>
+ </build>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-injection-merge-order/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-injection-merge-order/pom.xml
new file mode 100644
index 00000000..76459e2d
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-injection-merge-order/pom.xml
@@ -0,0 +1,133 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng4416</groupId>
+ <artifactId>test</artifactId>
+ <version>0.1</version>
+
+ <name>Maven Integration Test :: MNG-4416</name>
+ <description>
+ Test that merging of plugins during profile injection follows these rules regarding ordering:
+ model: X -> A -> B -> D -> E
+ profile: Y -> A -> C -> D -> F
+ result: X -> Y -> A -> B -> C -> D -> E -> F
+ </description>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-error</artifactId>
+ <version>2.1-SNAPSHOT</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-dependency-resolution</artifactId>
+ <version>2.1-SNAPSHOT</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-packaging</artifactId>
+ <version>2.1-SNAPSHOT</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-expression</artifactId>
+ <version>2.1-SNAPSHOT</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-fork</artifactId>
+ <version>2.1-SNAPSHOT</version>
+ </plugin>
+ </plugins>
+ </build>
+
+ <profiles>
+ <profile>
+ <id>test</id>
+ <activation>
+ <property>
+ <name>!skip-mng4416</name>
+ </property>
+ </activation>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-configuration</artifactId>
+ <version>2.1-SNAPSHOT</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-dependency-resolution</artifactId>
+ <version>2.1-SNAPSHOT</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-log-file</artifactId>
+ <version>2.1-SNAPSHOT</version>
+ <configuration>
+ <logFile>target/it.properties</logFile>
+ </configuration>
+ <executions>
+ <execution>
+ <id>first</id>
+ <phase>validate</phase>
+ <goals>
+ <goal>reset</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-expression</artifactId>
+ <version>2.1-SNAPSHOT</version>
+ <configuration>
+ <outputFile>target/it.properties</outputFile>
+ <expressions>
+ <expression>project/build/plugins</expression>
+ </expressions>
+ </configuration>
+ <executions>
+ <execution>
+ <id>second</id>
+ <phase>validate</phase>
+ <goals>
+ <goal>eval</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-touch</artifactId>
+ <version>2.1-SNAPSHOT</version>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-management-dependencies/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-management-dependencies/pom.xml
new file mode 100644
index 00000000..bcdb05aa
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-management-dependencies/pom.xml
@@ -0,0 +1,25 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>gid</groupId>
+ <artifactId>aid</artifactId>
+ <version>1.0</version>
+ <packaging>pom</packaging>
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.modello</groupId>
+ <artifactId>modello-maven-plugin</artifactId>
+ <version>1.0-alpha-21</version>
+ <dependencies>
+ <dependency>
+ <groupId>a</groupId>
+ <artifactId>b</artifactId>
+ <version>1.0</version>
+ </dependency>
+ </dependencies>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-management-dependencies/sub/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-management-dependencies/sub/pom.xml
new file mode 100644
index 00000000..7f73423e
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-management-dependencies/sub/pom.xml
@@ -0,0 +1,25 @@
+<project>
+ <parent>
+ <groupId>gid</groupId>
+ <artifactId>aid</artifactId>
+ <version>1.0</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.sonatype.nexus</groupId>
+ <artifactId>nexus</artifactId>
+ <version>1.3.0-SNAPSHOT</version>
+ <profiles>
+ <profile>
+ <id>test</id>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.modello</groupId>
+ <artifactId>modello-maven-plugin</artifactId>
+ <version>1.0-alpha-21</version>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-management-duplicate/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-management-duplicate/pom.xml
new file mode 100644
index 00000000..37e7278a
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-management-duplicate/pom.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+ <!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to you under the Apache License, Version
+ 2.0 (the "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0 Unless required by
+ applicable law or agreed to in writing, software distributed under the
+ License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ CONDITIONS OF ANY KIND, either express or implied. See the License for
+ the specific language governing permissions and limitations under the
+ License.
+ -->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>gid</groupId>
+ <artifactId>aid</artifactId>
+ <version>1.0</version>
+ <packaging>pom</packaging>
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins
+ </groupId>
+ <artifactId>maven-it-plugin-configuration
+ </artifactId>
+ <version>2.1-SNAPSHOT</version>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-management-duplicate/sub/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-management-duplicate/sub/pom.xml
new file mode 100644
index 00000000..5e844b79
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-management-duplicate/sub/pom.xml
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <parent>
+ <groupId>gid</groupId>
+ <artifactId>aid</artifactId>
+ <version>1.0</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng4053</groupId>
+ <artifactId>test2</artifactId>
+ <version>1.0-SNAPSHOT</version>
+
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>0.1-stub-SNAPSHOT</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-jar-plugin</artifactId>
+ <version>0.1-stub-SNAPSHOT</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ <version>0.1-stub-SNAPSHOT</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-resources-plugin</artifactId>
+ <version>0.1-stub-SNAPSHOT</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-source-plugin</artifactId>
+ <version>0.1-stub-SNAPSHOT</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>0.1-stub-SNAPSHOT</version>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-management-for-implicit-plugin/child/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-management-for-implicit-plugin/child/pom.xml
new file mode 100644
index 00000000..fce35882
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-management-for-implicit-plugin/child/pom.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.maven.its.mng0522</groupId>
+ <artifactId>parent</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>child-project</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <!-- NOTE: The upper-case packaging name is intentional and triggers a special mode in the EmptyLifecycleExecutor -->
+ <packaging>JAR</packaging>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-log-file</artifactId>
+ <executions>
+ <execution>
+ <id>test</id>
+ <phase>initialize</phase>
+ <goals>
+ <goal>reset</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-management-for-implicit-plugin/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-management-for-implicit-plugin/pom.xml
new file mode 100644
index 00000000..d9412769
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-management-for-implicit-plugin/pom.xml
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng0522</groupId>
+ <artifactId>parent</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <packaging>pom</packaging>
+
+ <name>Maven Integration Test :: MNG-522</name>
+ <description>Test for pluginManagement injection of plugin configuration.</description>
+
+ <modules>
+ <module>child</module>
+ </modules>
+
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <!-- this checks handling of a plugin which is implicitly bound to the lifecycle -->
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-resources-plugin</artifactId>
+ <version>0.1-stub-SNAPSHOT</version>
+ <configuration>
+ <pathname>passed.txt</pathname>
+ </configuration>
+ </plugin>
+ <plugin>
+ <!-- this checks handling of a plugin which is explicitly bound to the lifecycle -->
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-log-file</artifactId>
+ <version>2.1-SNAPSHOT</version>
+ <configuration>
+ <logFile>passed.txt</logFile>
+ </configuration>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-management-inheritance/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-management-inheritance/pom.xml
new file mode 100644
index 00000000..85b7bd94
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-management-inheritance/pom.xml
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.it0052</groupId>
+ <artifactId>maven-it-it0052</artifactId>
+ <version>1.0</version>
+ <packaging>jar</packaging>
+
+ <name>Maven Integration Test :: it0052</name>
+ <description>Test that source attachment doesn't take place when -DperformRelease=true is missing.</description>
+
+ <!-- NOTE: Use stub versions of the core plugins referenced by the build -->
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>0.1-stub-SNAPSHOT</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-jar-plugin</artifactId>
+ <version>0.1-stub-SNAPSHOT</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ <version>0.1-stub-SNAPSHOT</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-resources-plugin</artifactId>
+ <version>0.1-stub-SNAPSHOT</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-source-plugin</artifactId>
+ <version>0.1-stub-SNAPSHOT</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>0.1-stub-SNAPSHOT</version>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-merge-simple/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-merge-simple/pom.xml
new file mode 100644
index 00000000..10eac25f
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-merge-simple/pom.xml
@@ -0,0 +1,17 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.sonatype.nexus</groupId>
+ <artifactId>nexus-indexer</artifactId>
+ <version>1.1.3-SNAPSHOT</version>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-configuration</artifactId>
+ <version>2.1-SNAPSHOT</version>
+ </plugin>
+ </plugins>
+ </build>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-order/nexus-parent.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-order/nexus-parent.xml
new file mode 100644
index 00000000..607da777
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-order/nexus-parent.xml
@@ -0,0 +1,19 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.sonatype.nexus</groupId>
+ <artifactId>nexus-parent</artifactId>
+ <version>8-SNAPSHOT</version>
+ <packaging>pom</packaging>
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-component-metadata</artifactId>
+ <version>1.4.0</version>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-order/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-order/pom.xml
new file mode 100644
index 00000000..408d17f0
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/plugin-order/pom.xml
@@ -0,0 +1,28 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.sonatype.nexus</groupId>
+ <artifactId>nexus-parent</artifactId>
+ <version>8-SNAPSHOT</version>
+ <relativePath>nexus-parent.xml</relativePath>
+ </parent>
+
+ <groupId>org.sonatype.nexus</groupId>
+ <artifactId>nexus-indexer</artifactId>
+ <version>1.1.3-SNAPSHOT</version>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-component-metadata</artifactId>
+ </plugin>
+
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>2.4.3</version>
+ </plugin>
+ </plugins>
+ </build>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/pluginmanagement-inherited/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/pluginmanagement-inherited/pom.xml
new file mode 100644
index 00000000..477451df
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/pluginmanagement-inherited/pom.xml
@@ -0,0 +1,18 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.sonatype.nexus</groupId>
+ <artifactId>nexus</artifactId>
+ <version>1.3.0-SNAPSHOT</version>
+ <packaging>pom</packaging>
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.modello</groupId>
+ <artifactId>modello-maven-plugin</artifactId>
+ <version>1.0-alpha-21</version>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/pluginmanagement-inherited/sub/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/pluginmanagement-inherited/sub/pom.xml
new file mode 100644
index 00000000..319e6adb
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/pluginmanagement-inherited/sub/pom.xml
@@ -0,0 +1,17 @@
+<project>
+ <parent>
+ <groupId>org.sonatype.nexus</groupId>
+ <artifactId>nexus</artifactId>
+ <version>1.3.0-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>a</artifactId>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.modello</groupId>
+ <artifactId>modello-maven-plugin</artifactId>
+ </plugin>
+ </plugins>
+ </build>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/pom-encoding/latin-1/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/pom-encoding/latin-1/pom.xml
new file mode 100644
index 00000000..b338399f
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/pom-encoding/latin-1/pom.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<!--
+NOTE: This POM's XML declaration intentionally declares Latin-1 encoding.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng2254</groupId>
+ <artifactId>latin-1</artifactId>
+ <version>0.1-SNAPSHOT</version>
+ <packaging>pom</packaging>
+
+ <name>Maven Integration Test :: MNG-2254 :: Latin-1</name>
+ <description>TEST-CHARS: ÄÖÜäöüß</description>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/pom-encoding/utf-8/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/pom-encoding/utf-8/pom.xml
new file mode 100644
index 00000000..4400aa70
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/pom-encoding/utf-8/pom.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<!--
+NOTE: This POM's XML declaration specified no encoding which should therefore default to UTF-8.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng2254</groupId>
+ <artifactId>utf-8</artifactId>
+ <version>0.1-SNAPSHOT</version>
+ <packaging>pom</packaging>
+
+ <name>Maven Integration Test :: MNG-2254 :: UTF-8</name>
+ <description>TEST-CHARS: ßıΣЯ×€</description>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/pom-inheritance/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/pom-inheritance/pom.xml
new file mode 100644
index 00000000..f96a9400
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/pom-inheritance/pom.xml
@@ -0,0 +1,188 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <!--
+ This parent POM overrides most super POM defaults to test inheritance in child modules.
+ -->
+
+ <groupId>org.apache.maven.its.mng3843</groupId>
+ <artifactId>parent-1</artifactId>
+ <version>0.1</version>
+ <packaging>pom</packaging>
+
+ <name>parent-name</name>
+ <description>parent-description</description>
+ <url>http://parent.url/</url>
+ <inceptionYear>2008</inceptionYear>
+ <organization>
+ <name>parent-org</name>
+ <url>http://parent-org.url/</url>
+ </organization>
+ <licenses>
+ <license>
+ <name>parent-license</name>
+ <url>http://parent.url/license</url>
+ <distribution>repo</distribution>
+ </license>
+ </licenses>
+
+ <developers>
+ <developer>
+ <name>parent-developer</name>
+ </developer>
+ </developers>
+ <contributors>
+ <contributor>
+ <name>parent-contributor</name>
+ </contributor>
+ </contributors>
+
+ <mailingLists>
+ <mailingList>
+ <name>parent-mailing-list</name>
+ </mailingList>
+ </mailingLists>
+
+ <prerequisites>
+ <maven>2.0</maven>
+ </prerequisites>
+
+ <modules>
+ <module>child-1</module>
+ <module>child-2</module>
+ </modules>
+
+ <scm>
+ <url>http://parent.url/trunk</url>
+ <connection>http://parent.url/scm</connection>
+ <developerConnection>https://parent.url/scm</developerConnection>
+ </scm>
+ <issueManagement>
+ <url>http://parent.url/issues</url>
+ </issueManagement>
+ <ciManagement>
+ <url>http://parent.url/ci</url>
+ </ciManagement>
+ <distributionManagement>
+ <repository>
+ <url>http://parent.url/dist</url>
+ <id>parent.distros</id>
+ </repository>
+ <snapshotRepository>
+ <url>http://parent.url/snaps</url>
+ <id>parent.snaps</id>
+ </snapshotRepository>
+ <site>
+ <url>http://parent.url/site</url>
+ <id>parent.site</id>
+ </site>
+ <downloadUrl>http://parent.url/download</downloadUrl>
+ <relocation>
+ <message>parent-reloc-msg</message>
+ </relocation>
+ </distributionManagement>
+
+ <properties>
+ <parentProperty>parent-property</parentProperty>
+ <overriddenProperty>parent-property</overriddenProperty>
+ </properties>
+
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven.its.mng3843</groupId>
+ <artifactId>parent-dep-a</artifactId>
+ <version>1</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven.its.mng3843</groupId>
+ <artifactId>parent-dep-b</artifactId>
+ <version>1</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <repositories>
+ <repository>
+ <id>parent-remote-repo</id>
+ <url>http://parent.url/remote</url>
+ </repository>
+ </repositories>
+
+ <build>
+ <defaultGoal>initialize</defaultGoal>
+ <directory>out</directory>
+ <sourceDirectory>src/main</sourceDirectory>
+ <scriptSourceDirectory>src/scripts</scriptSourceDirectory>
+ <testSourceDirectory>src/test</testSourceDirectory>
+ <outputDirectory>out/main</outputDirectory>
+ <testOutputDirectory>out/test</testOutputDirectory>
+ <resources>
+ <resource>
+ <directory>res/main</directory>
+ </resource>
+ </resources>
+ <testResources>
+ <testResource>
+ <directory>res/test</directory>
+ </testResource>
+ </testResources>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-expression</artifactId>
+ <version>2.1-SNAPSHOT</version>
+ <executions>
+ <execution>
+ <phase>validate</phase>
+ <goals>
+ <goal>eval</goal>
+ </goals>
+ <configuration>
+ <outputFile>target/pom.properties</outputFile>
+ <expressions>
+ <expression>project</expression>
+ </expressions>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+ <reporting>
+ <excludeDefaults>true</excludeDefaults>
+ <outputDirectory>site</outputDirectory>
+ </reporting>
+
+ <profiles>
+ <profile>
+ <id>parent-profile</id>
+ </profile>
+ </profiles>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/pom-inheritance/sub/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/pom-inheritance/sub/pom.xml
new file mode 100644
index 00000000..ae749028
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/pom-inheritance/sub/pom.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <!--
+ This minimalistic POM tests mere inheritance from its parent.
+ -->
+
+ <parent>
+ <groupId>org.apache.maven.its.mng3843</groupId>
+ <artifactId>parent-1</artifactId>
+ <version>0.1</version>
+ </parent>
+
+ <artifactId>child-1</artifactId>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/prerequisites-inheritance/child/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/prerequisites-inheritance/child/pom.xml
new file mode 100644
index 00000000..349a0c38
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/prerequisites-inheritance/child/pom.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <!--
+ This minimalistic POM tests mere inheritance from its parent. The <prerequisites> should not be inherited.
+ -->
+
+ <parent>
+ <groupId>org.apache.maven.its.mng3843</groupId>
+ <artifactId>parent-1</artifactId>
+ <version>0.1</version>
+ </parent>
+
+ <artifactId>child-1</artifactId>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/prerequisites-inheritance/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/prerequisites-inheritance/pom.xml
new file mode 100644
index 00000000..3e4d8a45
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/prerequisites-inheritance/pom.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng3843</groupId>
+ <artifactId>parent-1</artifactId>
+ <version>0.1</version>
+ <packaging>pom</packaging>
+
+ <prerequisites>
+ <maven>2.0</maven>
+ </prerequisites>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/profile-default-deactivation/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/profile-default-deactivation/pom.xml
new file mode 100644
index 00000000..dfe19253
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/profile-default-deactivation/pom.xml
@@ -0,0 +1,35 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven.its.mng3545</groupId>
+ <artifactId>test-artifact</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <profiles>
+ <profile>
+ <id>profile1</id>
+ <activation>
+ <activeByDefault>true</activeByDefault>
+ </activation>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-touch</artifactId>
+ <version>2.2</version>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ <profile>
+ <id>profile4</id>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-touch</artifactId>
+ <version>2.1</version>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/profile-dependencies-multiple-profiles/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/profile-dependencies-multiple-profiles/pom.xml
new file mode 100644
index 00000000..d7af4e27
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/profile-dependencies-multiple-profiles/pom.xml
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.it0021</groupId>
+ <artifactId>test</artifactId>
+ <version>1.0-SNAPSHOT</version>
+
+ <name>Maven Integration Test :: it0021</name>
+ <description>
+ Test pom-level profile inclusion (this one is activated by system property).
+ </description>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-dependency-resolution</artifactId>
+ <version>2.1-SNAPSHOT</version>
+ <executions>
+ <execution>
+ <id>test</id>
+ <phase>validate</phase>
+ <goals>
+ <goal>compile</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+ <profiles>
+ <profile>
+ <id>profile-1</id>
+ <activation>
+ <property>
+ <name>includeProfile</name>
+ </property>
+ </activation>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven.its.it0021</groupId>
+ <artifactId>a</artifactId>
+ <version>0.1</version>
+ </dependency>
+ </dependencies>
+ </profile>
+ <profile>
+ <id>profile-2</id>
+ <!-- to be activated explicitly on the CLI by its id -->
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven.its.it0021</groupId>
+ <artifactId>b</artifactId>
+ <version>0.1</version>
+ </dependency>
+ </dependencies>
+ </profile>
+ </profiles>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/profile-injected-dependencies/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/profile-injected-dependencies/pom.xml
new file mode 100644
index 00000000..3fe02fbd
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/profile-injected-dependencies/pom.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng1412</groupId>
+ <artifactId>test</artifactId>
+ <version>0.1-SNAPSHOT</version>
+
+ <name>Maven Integration Test :: MNG-1412</name>
+ <description>
+ Check that dependencies are available in classpath in same order as declared in POM.
+ </description>
+
+ <dependencies>
+ <!-- model dependencies first, in the order given -->
+ <dependency>
+ <groupId>org.apache.maven.its.mng1412</groupId>
+ <artifactId>a</artifactId>
+ <version>0.1</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.its.mng1412</groupId>
+ <artifactId>c</artifactId>
+ <version>0.1</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.its.mng1412</groupId>
+ <artifactId>b</artifactId>
+ <version>0.1</version>
+ </dependency>
+ </dependencies>
+
+ <profiles>
+ <profile>
+ <id>mng-1412</id>
+ <activation>
+ <activeByDefault>true</activeByDefault>
+ </activation>
+ <!-- profile dependencies last, in the order given -->
+ <dependencies>
+ <dependency>
+ <!-- deliberately respecifying this dep to check merging behavior -->
+ <groupId>org.apache.maven.its.mng1412</groupId>
+ <artifactId>a</artifactId>
+ <version>0.1</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.its.mng1412</groupId>
+ <artifactId>d</artifactId>
+ <version>0.1</version>
+ </dependency>
+ </dependencies>
+ </profile>
+ </profiles>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/profile-injection-order/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/profile-injection-order/pom.xml
new file mode 100644
index 00000000..daf4607f
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/profile-injection-order/pom.xml
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng2309</groupId>
+ <artifactId>test</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <packaging>jar</packaging>
+
+ <name>Maven Integration Test :: MNG-2309</name>
+ <description>
+ Test that profiles are injected in declaration order, with the last profile being the most dominant.
+ </description>
+
+ <profiles>
+ <!-- NOTE: Using intentionally more than two profiles to prevent random test success -->
+ <profile>
+ <id>pom-a</id>
+ <properties>
+ <pomProperty>a</pomProperty>
+ </properties>
+ </profile>
+ <profile>
+ <id>pom-b</id>
+ <properties>
+ <pomProperty>b</pomProperty>
+ </properties>
+ </profile>
+ <profile>
+ <id>pom-c</id>
+ <properties>
+ <pomProperty>c</pomProperty>
+ </properties>
+ </profile>
+ <profile>
+ <id>pom-d</id>
+ <properties>
+ <pomProperty>d</pomProperty>
+ </properties>
+ </profile>
+ <profile>
+ <id>pom-e</id>
+ <properties>
+ <pomProperty>e</pomProperty>
+ </properties>
+ </profile>
+ </profiles>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/profile-module-inheritance/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/profile-module-inheritance/pom.xml
new file mode 100644
index 00000000..4e4c40b2
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/profile-module-inheritance/pom.xml
@@ -0,0 +1,18 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.ops4j.pax</groupId>
+ <artifactId>construct</artifactId>
+ <version>1.0</version>
+ <packaging>pom</packaging>
+
+ <profiles>
+ <profile>
+ <id>dist</id>
+ <modules>
+ <module>maven-inherit-plugin</module>
+ <module>maven-pax-plugin</module>
+ </modules>
+ </profile>
+ </profiles>
+
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/profile-module-inheritance/sub/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/profile-module-inheritance/sub/pom.xml
new file mode 100644
index 00000000..60f057cc
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/profile-module-inheritance/sub/pom.xml
@@ -0,0 +1,12 @@
+<project>
+ <parent>
+ <groupId>org.ops4j.pax</groupId>
+ <artifactId>construct</artifactId>
+ <version>1.0</version>
+ </parent>
+
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.ops4j</groupId>
+ <artifactId>maven-inherit-plugin</artifactId>
+ <version>1.1</version>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/profile-module/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/profile-module/pom.xml
new file mode 100644
index 00000000..b6336fd4
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/profile-module/pom.xml
@@ -0,0 +1,24 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>gid</groupId>
+ <artifactId>aid</artifactId>
+ <version>1.0</version>
+ <packaging>pom</packaging>
+ <modules>
+ <module>module-2</module>
+ <module>module-1</module>
+ <module>module-3</module>
+ </modules>
+ <profiles>
+ <profile>
+ <id>a</id>
+ <properties>
+ <b>test-prop</b>
+ </properties>
+ <modules>
+ <module>module-1</module>
+ <module>module-4</module>
+ </modules>
+ </profile>
+ </profiles>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/profile-plugin-mng-dependencies/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/profile-plugin-mng-dependencies/pom.xml
new file mode 100644
index 00000000..e283bb09
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/profile-plugin-mng-dependencies/pom.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng2174</groupId>
+ <artifactId>parent</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <packaging>pom</packaging>
+
+ <name>Maven Integration Test :: MNG-2174</name>
+ <description>
+ Verify that plugin dependencies defined by plugin management of a parent profile are not lost when the
+ parent's main plugin management section is also present.
+ </description>
+
+ <modules>
+ <module>sub</module>
+ </modules>
+
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-class-loader</artifactId>
+ <version>2.1-SNAPSHOT</version>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+
+ <profiles>
+ <profile>
+ <id>maven-core-it</id>
+ <activation>
+ <activeByDefault>true</activeByDefault>
+ </activation>
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-class-loader</artifactId>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven.its.mng2174</groupId>
+ <artifactId>a</artifactId>
+ <version>0.1</version>
+ </dependency>
+ </dependencies>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+ </profile>
+ </profiles>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/profile-plugin-mng-dependencies/sub/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/profile-plugin-mng-dependencies/sub/pom.xml
new file mode 100644
index 00000000..3614e305
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/profile-plugin-mng-dependencies/sub/pom.xml
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.maven.its.mng2174</groupId>
+ <artifactId>parent</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ </parent>
+
+ <groupId>org.apache.maven.its.mng2174</groupId>
+ <artifactId>child</artifactId>
+ <version>1.0-SNAPSHOT</version>
+
+ <name>Maven Integration Test :: MNG-2174</name>
+ <description>
+ Verify that plugin dependencies defined by plugin management of a parent profile are not lost when the
+ parent's main plugin management section is also present.
+ </description>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-class-loader</artifactId>
+ <executions>
+ <execution>
+ <id>test</id>
+ <phase>validate</phase>
+ <configuration>
+ <resourcePaths>mng-2174.properties</resourcePaths>
+ <pluginClassLoaderOutput>target/pcl.properties</pluginClassLoaderOutput>
+ </configuration>
+ <goals>
+ <goal>load</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/profile-plugins/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/profile-plugins/pom.xml
new file mode 100644
index 00000000..32e94d73
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/profile-plugins/pom.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+ <!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to you under the Apache License, Version
+ 2.0 (the "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0 Unless required by
+ applicable law or agreed to in writing, software distributed under
+ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
+ OR CONDITIONS OF ANY KIND, either express or implied. See the
+ License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven</artifactId>
+ <version>3.0-SNAPSHOT</version>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>2.4.3</version>
+ </plugin>
+ </plugins>
+ </build>
+
+ <profiles>
+ <profile>
+ <id>standard</id>
+ <activation>
+ <activeByDefault>true</activeByDefault>
+ </activation>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-assembly2-plugin</artifactId>
+ <version>2.0</version>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/profile-properties-interpolation/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/profile-properties-interpolation/pom.xml
new file mode 100644
index 00000000..a95e253b
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/profile-properties-interpolation/pom.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+ <!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to you under the Apache License, Version
+ 2.0 (the "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0 Unless required by
+ applicable law or agreed to in writing, software distributed under the
+ License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ CONDITIONS OF ANY KIND, either express or implied. See the License for
+ the specific language governing permissions and limitations under the
+ License.
+ -->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng3900 </groupId>
+ <artifactId>test</artifactId>
+ <version>0.1</version>
+ <packaging>jar</packaging>
+
+ <name>Maven Integration Test :: MNG-3900</name>
+ <description>
+ Test that build properties defined via active profiles are used for
+ interpolation.
+ </description>
+
+ <!--
+ These are some POM elements we would like to interpolate with
+ properties from the profile.
+ -->
+ <url>http://maven.apache.org/${test}
+ </url>
+ <properties>
+ <test>FAILED</test>
+ <property>${test}</property>
+ </properties>
+
+ <profiles>
+ <profile>
+ <id>interpolation-profile</id>
+ <!-- This profile defines the properties to use for interpolation. -->
+ <properties>
+ <test>PASSED</test>
+ <test1>PASSED</test1>
+ </properties>
+ </profile>
+ </profiles>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/properties-inheritance/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/properties-inheritance/pom.xml
new file mode 100644
index 00000000..6d17dd3a
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/properties-inheritance/pom.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng3843</groupId>
+ <artifactId>parent-1</artifactId>
+ <version>0.1</version>
+ <packaging>pom</packaging>
+
+ <properties>
+ <parentProperty>parent-property</parentProperty>
+ <overriddenProperty>parent-property</overriddenProperty>
+ </properties>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/properties-inheritance/sub/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/properties-inheritance/sub/pom.xml
new file mode 100644
index 00000000..c5394df5
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/properties-inheritance/sub/pom.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.maven.its.mng3843</groupId>
+ <artifactId>parent-1</artifactId>
+ <version>0.1</version>
+ </parent>
+
+ <groupId>org.apache.maven.its.mng3843.child</groupId>
+ <artifactId>child-2</artifactId>
+ <version>0.2</version>
+ <packaging>jar</packaging>
+
+ <properties>
+ <childProperty>child-property</childProperty>
+ <overriddenProperty>child-override</overriddenProperty>
+ </properties>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/properties-no-duplication/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/properties-no-duplication/pom.xml
new file mode 100644
index 00000000..c74f4465
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/properties-no-duplication/pom.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven.its</groupId>
+ <artifactId>test-parent</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <packaging>pom</packaging>
+ <properties>
+ <pomProfile>parent</pomProfile>
+ </properties>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/properties-no-duplication/sub/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/properties-no-duplication/sub/pom.xml
new file mode 100644
index 00000000..9241b8bb
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/properties-no-duplication/sub/pom.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.maven.its</groupId>
+ <artifactId>test-parent</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ </parent>
+ <groupId>org.apache.maven.its</groupId>
+ <artifactId>test</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <properties>
+ <pomProfile>child</pomProfile>
+ </properties>
+</project>
+
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/repo-inheritance/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/repo-inheritance/pom.xml
new file mode 100644
index 00000000..5c1dacab
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/repo-inheritance/pom.xml
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.it0043</groupId>
+ <artifactId>maven-it-it0043</artifactId>
+ <version>1.0-SNAPSHOT</version>
+
+ <name>Maven Integration Test :: it0043</name>
+ <description>Test for repository inheritence - ensure using the same id overrides the defaults</description>
+
+ <repositories>
+ <repository>
+ <id>central</id>
+ <name>it0043</name>
+ <url>file:///${basedir}/target/maven-core-it0043-repo</url>
+ </repository>
+ </repositories>
+
+ <pluginRepositories>
+ <pluginRepository>
+ <id>central</id>
+ <name>it0043</name>
+ <url>file:///${basedir}/target/maven-core-it0043-repo</url>
+ </pluginRepository>
+ </pluginRepositories>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-expression</artifactId>
+ <version>2.1-SNAPSHOT</version>
+ <configuration>
+ <outputFile>target/expression.properties</outputFile>
+ <expressions>
+ <expression>project/repositories</expression>
+ <expression>project/pluginRepositories</expression>
+ </expressions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/reporting-interpolation/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/reporting-interpolation/pom.xml
new file mode 100644
index 00000000..49df00a8
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/reporting-interpolation/pom.xml
@@ -0,0 +1,6 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>gid</groupId>
+ <artifactId>aid</artifactId>
+ <version>1.0</version>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/reporting-plugin-config/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/reporting-plugin-config/pom.xml
new file mode 100644
index 00000000..fdb455a0
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/reporting-plugin-config/pom.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+ <!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to you under the Apache License, Version
+ 2.0 (the "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0 Unless required by
+ applicable law or agreed to in writing, software distributed under
+ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
+ OR CONDITIONS OF ANY KIND, either express or implied. See the
+ License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng3811</groupId>
+ <artifactId>test-parent</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <packaging>pom</packaging>
+
+ <name>MNG-3811 :: Parent</name>
+ <description>Test inheritance of reporting plugin configuration</description>
+
+ <modules>
+ <module>child</module>
+ </modules>
+
+ <reporting>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-configuration</artifactId>
+ <version>2.1-SNAPSHOT</version>
+ <configuration>
+ <booleanParam>true</booleanParam>
+ <stringParams>
+ <stringParam>parentParam</stringParam>
+ </stringParams>
+ </configuration>
+ </plugin>
+ </plugins>
+ </reporting>
+</project>
+
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/reporting-plugin-config/sub/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/reporting-plugin-config/sub/pom.xml
new file mode 100644
index 00000000..b0768271
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/reporting-plugin-config/sub/pom.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+ <!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to you under the Apache License, Version
+ 2.0 (the "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0 Unless required by
+ applicable law or agreed to in writing, software distributed under
+ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
+ OR CONDITIONS OF ANY KIND, either express or implied. See the
+ License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+<parent>
+ <groupId>org.apache.maven.its.mng3811</groupId>
+ <artifactId>test-parent</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ </parent>
+ <artifactId>test-child</artifactId>
+
+ <name>MNG-3811 :: Child</name>
+
+ <reporting>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-configuration</artifactId>
+ <version>2.1-SNAPSHOT</version>
+ <configuration>
+ <stringParams combine.children="append">
+ <stringParam> childParam </stringParam>
+ <stringParam xml:space="preserve"> preserve space </stringParam>
+ </stringParams>
+ </configuration>
+ </plugin>
+ </plugins>
+ </reporting>
+</project>
+
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/single-configuration-inheritance/jetty-parent.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/single-configuration-inheritance/jetty-parent.xml
new file mode 100644
index 00000000..40031e36
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/single-configuration-inheritance/jetty-parent.xml
@@ -0,0 +1,37 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.mortbay.jetty</groupId>
+ <artifactId>jetty-parent</artifactId>
+ <packaging>pom</packaging>
+ <name>Jetty :: Administrative Parent</name>
+ <version>7</version>
+
+ <build>
+
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-enforcer-plugin</artifactId>
+ <version>1.0-alpha-3</version>
+ <executions>
+ <execution>
+ <id>enforce-java</id>
+ <goals>
+ <goal>enforce</goal>
+ </goals>
+ <configuration>
+ <rules>
+ <requireMavenVersion>
+ <version>[2.0.6,)</version>
+ </requireMavenVersion>
+ <requireJavaVersion>
+ <version>[1.5,)</version>
+ </requireJavaVersion>
+ </rules>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/single-configuration-inheritance/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/single-configuration-inheritance/pom.xml
new file mode 100644
index 00000000..695ffaff
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/single-configuration-inheritance/pom.xml
@@ -0,0 +1,41 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.mortbay.jetty</groupId>
+ <artifactId>jetty-parent</artifactId>
+ <version>7</version>
+ <relativePath>jetty-parent.xml</relativePath>
+ </parent>
+ <groupId>org.mortbay.jetty</groupId>
+ <artifactId>project</artifactId>
+ <packaging>pom</packaging>
+ <name>Jetty Server Project</name>
+ <version>6.1.12</version>
+ <build>
+ <defaultGoal>install</defaultGoal>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-enforcer-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>enforce-java</id>
+ <goals>
+ <goal>enforce</goal>
+ </goals>
+ <configuration>
+ <rules>
+ <requireMavenVersion>
+ <version>2.0.6</version>
+ </requireMavenVersion>
+ <requireJavaVersion>
+ <version>[1.4,)</version>
+ </requireJavaVersion>
+ </rules>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/sytem-property-interpolation/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/sytem-property-interpolation/pom.xml
new file mode 100644
index 00000000..7d48d903
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/sytem-property-interpolation/pom.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>gid</groupId>
+ <artifactId>aid</artifactId>
+ <version>1.0</version>
+
+ <name>${system.property}</name>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/unc-path/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/unc-path/pom.xml
new file mode 100644
index 00000000..be2a825a
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/unc-path/pom.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+ <!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to you under the Apache License, Version
+ 2.0 (the "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0 Unless required by
+ applicable law or agreed to in writing, software distributed under
+ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
+ OR CONDITIONS OF ANY KIND, either express or implied. See the
+ License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng3621</groupId>
+ <artifactId>test-parent</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <packaging>pom</packaging>
+
+ <name>MNG-3621 :: Parent</name>
+ <description>Test inheritance of UNC paths</description>
+
+ <modules>
+ <module>child</module>
+ </modules>
+
+ <distributionManagement>
+ <site>
+ <id>site</id>
+ <url>file:////host/site</url>
+ </site>
+ </distributionManagement>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/unc-path/sub/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/unc-path/sub/pom.xml
new file mode 100644
index 00000000..fddd8723
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/unc-path/sub/pom.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+ <!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to you under the Apache License, Version
+ 2.0 (the "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0 Unless required by
+ applicable law or agreed to in writing, software distributed under
+ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
+ OR CONDITIONS OF ANY KIND, either express or implied. See the
+ License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+<parent>
+ <groupId>org.apache.maven.its.mng3621</groupId>
+ <artifactId>test-parent</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ </parent>
+ <artifactId>test-child</artifactId>
+
+ <name>MNG-3621 :: Child</name>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-expression</artifactId>
+ <version>2.1-SNAPSHOT</version>
+ <configuration>
+ <outputFile>target/pom.properties</outputFile>
+ <expressions>
+ <expression>project/distributionManagement/site/url</expression>
+ </expressions>
+ </configuration>
+ <executions>
+ <execution>
+ <id>test</id>
+ <phase>validate</phase>
+ <goals>
+ <goal>eval</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
+
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/unique-dependency-key/dep-mngt-in-profile/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/unique-dependency-key/dep-mngt-in-profile/pom.xml
new file mode 100644
index 00000000..38ad7f71
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/unique-dependency-key/dep-mngt-in-profile/pom.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng4005</groupId>
+ <artifactId>b</artifactId>
+ <version>0.1</version>
+ <packaging>jar</packaging>
+
+ <profiles>
+ <profile>
+ <id>test</id>
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven.its.mng4005</groupId>
+ <artifactId>a</artifactId>
+ <version>0.1</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.its.mng4005</groupId>
+ <artifactId>a</artifactId>
+ <version>0.2</version>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+ </profile>
+ </profiles>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/unique-dependency-key/dep-mngt/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/unique-dependency-key/dep-mngt/pom.xml
new file mode 100644
index 00000000..de69bb4b
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/unique-dependency-key/dep-mngt/pom.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng4005</groupId>
+ <artifactId>b</artifactId>
+ <version>0.1</version>
+ <packaging>jar</packaging>
+
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven.its.mng4005</groupId>
+ <artifactId>a</artifactId>
+ <version>0.1</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.its.mng4005</groupId>
+ <artifactId>a</artifactId>
+ <version>0.2</version>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/unique-dependency-key/deps-in-profile/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/unique-dependency-key/deps-in-profile/pom.xml
new file mode 100644
index 00000000..8d4ae56d
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/unique-dependency-key/deps-in-profile/pom.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng4005</groupId>
+ <artifactId>b</artifactId>
+ <version>0.1</version>
+ <packaging>jar</packaging>
+
+ <profiles>
+ <profile>
+ <id>test</id>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven.its.mng4005</groupId>
+ <artifactId>a</artifactId>
+ <version>0.1</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.its.mng4005</groupId>
+ <artifactId>a</artifactId>
+ <version>0.2</version>
+ </dependency>
+ </dependencies>
+ </profile>
+ </profiles>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/unique-dependency-key/deps/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/unique-dependency-key/deps/pom.xml
new file mode 100644
index 00000000..a629c9f5
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/unique-dependency-key/deps/pom.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng4005</groupId>
+ <artifactId>b</artifactId>
+ <version>0.1</version>
+ <packaging>jar</packaging>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven.its.mng4005</groupId>
+ <artifactId>a</artifactId>
+ <version>0.1</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.its.mng4005</groupId>
+ <artifactId>a</artifactId>
+ <version>0.2</version>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/unique-repo-id/artifact-repo-in-profile/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/unique-repo-id/artifact-repo-in-profile/pom.xml
new file mode 100644
index 00000000..eb73c4e2
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/unique-repo-id/artifact-repo-in-profile/pom.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng4193</groupId>
+ <artifactId>test</artifactId>
+ <version>0.1</version>
+ <packaging>jar</packaging>
+
+ <name>Maven Integration Test :: MNG-4193</name>
+ <description>
+ Test that multiple artifact repository declarations with the same id cause a validation error even if the
+ repositories are defined within a (non-active) profile.
+ </description>
+
+ <profiles>
+ <profile>
+ <id>test</id>
+ <repositories>
+ <repository>
+ <id>one</id>
+ <url>http://repo1.maven.org/maven2</url>
+ </repository>
+ <repository>
+ <id>one</id>
+ <url>http://repository.codehaus.org/</url>
+ </repository>
+ </repositories>
+ </profile>
+ </profiles>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/unique-repo-id/artifact-repo/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/unique-repo-id/artifact-repo/pom.xml
new file mode 100644
index 00000000..76d4f74a
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/unique-repo-id/artifact-repo/pom.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng4193</groupId>
+ <artifactId>test</artifactId>
+ <version>0.1</version>
+ <packaging>jar</packaging>
+
+ <name>Maven Integration Test :: MNG-4193</name>
+ <description>
+ Test that multiple artifact repository declarations with the same id cause a validation error.
+ </description>
+
+ <repositories>
+ <repository>
+ <id>one</id>
+ <url>http://repo1.maven.org/maven2</url>
+ </repository>
+ <repository>
+ <id>one</id>
+ <url>http://repository.codehaus.org/</url>
+ </repository>
+ </repositories>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/unique-repo-id/plugin-repo-in-profile/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/unique-repo-id/plugin-repo-in-profile/pom.xml
new file mode 100644
index 00000000..ac1fada5
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/unique-repo-id/plugin-repo-in-profile/pom.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng4193</groupId>
+ <artifactId>test</artifactId>
+ <version>0.1</version>
+ <packaging>jar</packaging>
+
+ <name>Maven Integration Test :: MNG-4193</name>
+ <description>
+ Test that multiple plugin repository declarations with the same id cause a validation error even if the
+ repositories are defined within a (non-active) profile.
+ </description>
+
+ <profiles>
+ <profile>
+ <id>test</id>
+ <pluginRepositories>
+ <pluginRepository>
+ <id>one</id>
+ <url>http://repo1.maven.org/maven2</url>
+ </pluginRepository>
+ <pluginRepository>
+ <id>one</id>
+ <url>http://repository.codehaus.org/</url>
+ </pluginRepository>
+ </pluginRepositories>
+ </profile>
+ </profiles>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/unique-repo-id/plugin-repo/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/unique-repo-id/plugin-repo/pom.xml
new file mode 100644
index 00000000..92fd1264
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/unique-repo-id/plugin-repo/pom.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng4193</groupId>
+ <artifactId>test</artifactId>
+ <version>0.1</version>
+ <packaging>jar</packaging>
+
+ <name>Maven Integration Test :: MNG-4193</name>
+ <description>
+ Test that multiple plugin repository declarations with the same id cause a validation error.
+ </description>
+
+ <pluginRepositories>
+ <pluginRepository>
+ <id>one</id>
+ <url>http://repo1.maven.org/maven2</url>
+ </pluginRepository>
+ <pluginRepository>
+ <id>one</id>
+ <url>http://repository.codehaus.org/</url>
+ </pluginRepository>
+ </pluginRepositories>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/unprefixed-expression-interpolation/child/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/unprefixed-expression-interpolation/child/pom.xml
new file mode 100644
index 00000000..9304f5d0
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/unprefixed-expression-interpolation/child/pom.xml
@@ -0,0 +1,104 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.maven.its.mng3831</groupId>
+ <artifactId>parent</artifactId>
+ <version>1.0</version>
+ </parent>
+
+ <groupId>org.apache.maven.its.mng3831.child</groupId>
+ <artifactId>child</artifactId>
+ <version>2.0-alpha-1</version>
+ <packaging>jar</packaging>
+
+ <name>child-name</name>
+ <description>child-desc</description>
+ <url>http://child.org/</url>
+ <inceptionYear>2008</inceptionYear>
+ <organization>
+ <name>child-org-name</name>
+ </organization>
+
+ <prerequisites>
+ <maven>2.0.0</maven>
+ </prerequisites>
+
+ <scm>
+ <url>http://scm.org/</url>
+ </scm>
+ <issueManagement>
+ <url>http://issue.org/</url>
+ </issueManagement>
+ <ciManagement>
+ <url>http://ci.org/</url>
+ </ciManagement>
+ <distributionManagement>
+ <repository>
+ <id>maven-core-it</id>
+ <name>child-dist-repo</name>
+ <url>http://dist.org/</url>
+ </repository>
+ <site>
+ <id>maven-core-it</id>
+ <name>child-site</name>
+ <url>http://site.org/</url>
+ </site>
+ </distributionManagement>
+
+ <properties>
+ <!-- this is where we collect all the interpolated values for the POM dump -->
+ <projectDir>${basedir}</projectDir>
+ <projectGroupId>${groupId}</projectGroupId>
+ <projectArtifactId>${artifactId}</projectArtifactId>
+ <projectVersion>${version}</projectVersion>
+ <projectPackaging>${packaging}</projectPackaging>
+ <projectName>${name}</projectName>
+ <projectDesc>${description}</projectDesc>
+ <projectUrl>${url}</projectUrl>
+ <projectYear>${inceptionYear}</projectYear>
+ <projectOrgName>${organization.name}</projectOrgName>
+ <projectPrereqMvn>${prerequisites.maven}</projectPrereqMvn>
+ <projectScmUrl>${scm.url}</projectScmUrl>
+ <projectIssueUrl>${issueManagement.url}</projectIssueUrl>
+ <projectCiUrl>${ciManagement.url}</projectCiUrl>
+ <projectDistRepoName>${distributionManagement.repository.name}</projectDistRepoName>
+ <projectDistRepoUrl>${distributionManagement.repository.url}</projectDistRepoUrl>
+ <projectDistSiteUrl>${distributionManagement.site.url}</projectDistSiteUrl>
+ <projectBuildOut>${build.outputDirectory}</projectBuildOut>
+ <projectSiteOut>${reporting.outputDirectory}</projectSiteOut>
+ <parentGroupId>${parent.groupId}</parentGroupId>
+ <parentArtifactId>${parent.artifactId}</parentArtifactId>
+ <parentVersion>${parent.version}</parentVersion>
+ </properties>
+
+ <build>
+ <outputDirectory>target/bin</outputDirectory>
+ </build>
+
+ <reporting>
+ <outputDirectory>target/doc</outputDirectory>
+ </reporting>
+
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/unprefixed-expression-interpolation/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/unprefixed-expression-interpolation/pom.xml
new file mode 100644
index 00000000..768a5e98
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/unprefixed-expression-interpolation/pom.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng3831</groupId>
+ <artifactId>parent</artifactId>
+ <version>1.0</version>
+ <packaging>pom</packaging>
+
+ <name>Maven Integration Test :: MNG-3831</name>
+ <description>Test POM interpolation with expressions of the form $ { * } (ugly but real)</description>
+
+ <modules>
+ <module>parent/child</module>
+ </modules>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/url-append/child/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/url-append/child/pom.xml
new file mode 100644
index 00000000..1f377df1
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/url-append/child/pom.xml
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.maven.its.mng2006</groupId>
+ <artifactId>parent</artifactId>
+ <version>0.1</version>
+ <relativePath>../parent/pom.xml</relativePath>
+ </parent>
+
+ <artifactId>child</artifactId>
+ <name>Child Project</name>
+ <description>
+ Test that inheritance of those URLs which automatically append the child's artifact id take the child's
+ relative location to the parent into account.
+ </description>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-expression</artifactId>
+ <version>2.1-SNAPSHOT</version>
+ <executions>
+ <execution>
+ <phase>validate</phase>
+ <goals>
+ <goal>eval</goal>
+ </goals>
+ <configuration>
+ <outputFile>target/pom.properties</outputFile>
+ <expressions>
+ <expression>project/url</expression>
+ <expression>project/scm</expression>
+ <expression>project/distributionManagement/site</expression>
+ </expressions>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/url-append/parent/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/url-append/parent/pom.xml
new file mode 100644
index 00000000..f8b069f8
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/url-append/parent/pom.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng2006</groupId>
+ <artifactId>parent</artifactId>
+ <version>0.1</version>
+ <packaging>pom</packaging>
+
+ <name>Maven Integration Test :: MNG-2006</name>
+ <description>
+ Test that inheritance of those URLs which automatically append the child's artifact id take the child's
+ relative location to the parent into account.
+ </description>
+
+ <modules>
+ <module>../child</module>
+ </modules>
+
+ <url>http://project.url/parent</url>
+
+ <scm>
+ <url>http://viewvc.project.url/parent</url>
+ <connection>http://scm.project.url/parent</connection>
+ <developerConnection>https://scm.project.url/parent</developerConnection>
+ </scm>
+ <distributionManagement>
+ <site>
+ <url>http://site.project.url/parent</url>
+ <id>parent.site</id>
+ </site>
+ </distributionManagement>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/url-inheritance/another-parent/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/url-inheritance/another-parent/pom.xml
new file mode 100644
index 00000000..463772fe
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/url-inheritance/another-parent/pom.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <!-- NOTE: The base directory name of this project deliberately does not match its artifact id! -->
+
+ <parent>
+ <groupId>org.apache.maven.its.mng3846</groupId>
+ <artifactId>parent</artifactId>
+ <version>0.1</version>
+ </parent>
+
+ <artifactId>ap</artifactId>
+ <packaging>pom</packaging>
+ <name>Another Parent to test multi-level URL adjustment</name>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/url-inheritance/another-parent/sub/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/url-inheritance/another-parent/sub/pom.xml
new file mode 100644
index 00000000..128e63d1
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/url-inheritance/another-parent/sub/pom.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <!-- NOTE: The base directory name of this project deliberately does not match its artifact id! -->
+
+ <parent>
+ <groupId>org.apache.maven.its.mng3846</groupId>
+ <artifactId>ap</artifactId>
+ <version>0.1</version>
+ </parent>
+
+ <artifactId>child</artifactId>
+ <name>Child Project</name>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/url-inheritance/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/url-inheritance/pom.xml
new file mode 100644
index 00000000..ed4cdf08
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/url-inheritance/pom.xml
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng3846</groupId>
+ <artifactId>parent</artifactId>
+ <version>0.1</version>
+ <packaging>pom</packaging>
+
+ <name>Maven Integration Test :: MNG-3846</name>
+ <description>
+ Test that inheritance of certain URLs automatically appends the child's artifact id.
+ </description>
+
+ <url>http://parent.url</url>
+ <organization>
+ <name>parent-org</name>
+ <url>http://parent.url/org</url>
+ </organization>
+ <licenses>
+ <license>
+ <name>parent-license</name>
+ <url>http://parent.url/license.txt</url>
+ <distribution>repo</distribution>
+ </license>
+ </licenses>
+
+ <scm>
+ <url>http://parent.url/viewvc</url>
+ <connection>http://parent.url/scm</connection>
+ <developerConnection>https://parent.url/scm</developerConnection>
+ </scm>
+ <issueManagement>
+ <url>http://parent.url/issues</url>
+ </issueManagement>
+ <ciManagement>
+ <url>http://parent.url/ci</url>
+ </ciManagement>
+ <distributionManagement>
+ <repository>
+ <url>http://parent.url/dist</url>
+ <id>parent.distros</id>
+ </repository>
+ <snapshotRepository>
+ <url>http://parent.url/snaps</url>
+ <id>parent.snaps</id>
+ </snapshotRepository>
+ <site>
+ <url>http://parent.url/site</url>
+ <id>parent.site</id>
+ </site>
+ <downloadUrl>http://parent.url/download</downloadUrl>
+ </distributionManagement>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/url-inheritance/sub/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/url-inheritance/sub/pom.xml
new file mode 100644
index 00000000..c8e9c108
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/url-inheritance/sub/pom.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <!-- NOTE: The base directory name of this project deliberately does not match its artifact id! -->
+
+ <parent>
+ <groupId>org.apache.maven.its.mng3846</groupId>
+ <artifactId>parent</artifactId>
+ <version>0.1</version>
+ </parent>
+
+ <artifactId>child</artifactId>
+ <name>Child Project</name>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/url-no-decoding/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/url-no-decoding/pom.xml
new file mode 100644
index 00000000..2dcceb93
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/url-no-decoding/pom.xml
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng4116</groupId>
+ <artifactId>test</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <packaging>jar</packaging>
+
+ <name>Maven Integration Test :: MNG-4116</name>
+ <description>
+ Test that the project builder does not decode URLs (which must be done by the transport layer instead).
+ </description>
+
+ <!-- some URLs using percent-encoded characters -->
+ <url>http://maven.apache.org/spacy%20path</url>
+ <scm>
+ <connection>scm:svn:svn+ssh://svn.apache.org/spacy%20path</connection>
+ <developerConnection>scm:svn:svn+ssh://svn.apache.org/spacy%20path</developerConnection>
+ <url>http://svn.apache.org/viewvc/spacy%20path</url>
+ </scm>
+ <issueManagement>
+ <system>none</system>
+ <url>http://issues.apache.org/spacy%20path</url>
+ </issueManagement>
+ <ciManagement>
+ <system>none</system>
+ <url>http://ci.apache.org/spacy%20path</url>
+ </ciManagement>
+ <distributionManagement>
+ <repository>
+ <id>dist</id>
+ <url>scm:svn:svn+ssh://dist.apache.org/spacy%20path</url>
+ </repository>
+ <snapshotRepository>
+ <id>snap</id>
+ <url>scm:svn:svn+ssh://snap.apache.org/spacy%20path</url>
+ </snapshotRepository>
+ <site>
+ <id>site</id>
+ <url>scm:svn:svn+ssh://site.apache.org/spacy%20path</url>
+ </site>
+ </distributionManagement>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/xml-coalesce-text/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/xml-coalesce-text/pom.xml
new file mode 100644
index 00000000..5822d8d3
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/xml-coalesce-text/pom.xml
@@ -0,0 +1,567 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng3839</groupId>
+ <artifactId>coreit</artifactId>
+ <version>0.1</version>
+ <packaging>jar</packaging>
+
+ <name>Maven Integration Test :: MNG-3839</name>
+ <description>
+ Test that POM parsing properly coalesces text data.
+ </description>
+
+ <properties>
+ <!--
+ This checks the coalescing of CHARACTERS and CDATA events. Note that inner whitespace must be retained.
+ -->
+ <prop0>A <![CDATA[ Test ]]> Project<![CDATA[ ]]>Property</prop0>
+
+ <!--
+ This checks the coalescing of CHARACTERS events that are interleaved with comments. Note that inner whitespace
+ formed by whitespace-only events must be retained.
+ -->
+ <prop1><!-- X -->That's<!-- X --> <!-- X -->a<!-- X --> <!-- X -->test!<!-- X --></prop1>
+
+ <!--
+ This checks the coalescing of CHARACTERS events which would otherwise be reported in chunks of the internal parser
+ buffer size (usually 4 or 8 KB). The text block is designed such that its length is exactly 32 KB after leading
+ and traling whitespace has been removed and all line terminators have been removed.
+ -->
+ <prop2>
+00 KB 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+01 KB 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+02 KB 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+03 KB 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+04 KB 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+05 KB 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+06 KB 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+07 KB 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+08 KB 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+09 KB 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+10 KB 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+11 KB 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+12 KB 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+13 KB 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+14 KB 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+15 KB 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+16 KB 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+17 KB 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+18 KB 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+19 KB 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+20 KB 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+21 KB 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+22 KB 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+23 KB 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+24 KB 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+25 KB 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+26 KB 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+27 KB 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+28 KB 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+29 KB 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+30 KB 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+31 KB 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+0 1 2 3 4 5 6 X
+ </prop2>
+ </properties>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/xml-markup-interpolation/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/xml-markup-interpolation/pom.xml
new file mode 100644
index 00000000..584712fd
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/xml-markup-interpolation/pom.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng3924</groupId>
+ <artifactId>test</artifactId>
+ <version>0.1-SNAPSHOT</version>
+ <packaging>jar</packaging>
+
+ <name>Maven Integration Test :: MNG-3924</name>
+ <description>
+ Test that interpolation of properties that resolve to XML markup doesn't crash the project builder.
+ </description>
+
+ <properties>
+ <!-- That's the property containing escaped XML markup -->
+ <xmlMarkup>&lt;?xml version='1.0'?&gt;Tom&amp;Jerry</xmlMarkup>
+ <!-- That's a property where the above property will be resolved -->
+ <xmlTest>${xmlMarkup}</xmlTest>
+ </properties>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/xml-whitespace/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/xml-whitespace/pom.xml
new file mode 100644
index 00000000..433dd522
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/xml-whitespace/pom.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <!-- NOTE: The ugly formatting is essential part of this test! -->
+ <groupId>
+ org.apache.maven.its.mng4070
+ </groupId>
+ <artifactId>
+ parent
+ </artifactId>
+ <version>
+ 1.0
+ </version>
+ <packaging>
+ pom
+ </packaging>
+
+ <name>Maven Integration Test :: MNG-4070</name>
+ <description>
+ Test that whitespace around artifact coordinates does not change artifact identity.
+ </description>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/xml-whitespace/sub/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/xml-whitespace/sub/pom.xml
new file mode 100644
index 00000000..f5ea684d
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-project-builder/xml-whitespace/sub/pom.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <!-- NOTE: The ugly formatting is essential part of this test! -->
+ <parent>
+ <groupId> org.apache.maven.its.mng4070 </groupId>
+ <artifactId> parent </artifactId>
+ <version> 1.0 </version>
+ </parent>
+
+ <artifactId>subproject</artifactId>
+ <version>1.0</version>
+ <packaging>jar</packaging>
+
+ <name>Maven Integration Test :: MNG-4070 :: Child</name>
+ <description>
+ Test that whitespace around artifact coordinates does not change artifact identity.
+ </description>
+
+ <dependencies>
+ <dependency>
+ <!-- NOTE: The ugly formatting is essential part of this test! -->
+ <groupId> org.apache.maven.its.mng4070 </groupId>
+ <artifactId> a </artifactId>
+ <version> 0.1 </version>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-settings/repositories/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-settings/repositories/pom.xml
new file mode 100644
index 00000000..97023414
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-settings/repositories/pom.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng4107</groupId>
+ <artifactId>test</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <packaging>jar</packaging>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-settings/repositories/settings.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-settings/repositories/settings.xml
new file mode 100644
index 00000000..6f96f0b6
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-settings/repositories/settings.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<settings>
+ <profiles>
+ <profile>
+ <id>maven-core-it-repo</id>
+ <repositories>
+ <repository>
+ <id>maven-core-it-0</id>
+ <url>@baseurl@/repo-0</url>
+ <releases>
+ <checksumPolicy>ignore</checksumPolicy>
+ </releases>
+ <snapshots>
+ <enabled>false</enabled>
+ </snapshots>
+ </repository>
+ </repositories>
+ <pluginRepositories>
+ <pluginRepository>
+ <id>maven-core-it-1</id>
+ <url>@baseurl@/repo-1</url>
+ <releases>
+ <checksumPolicy>ignore</checksumPolicy>
+ </releases>
+ <snapshots>
+ <checksumPolicy>ignore</checksumPolicy>
+ </snapshots>
+ </pluginRepository>
+ </pluginRepositories>
+ </profile>
+ </profiles>
+ <activeProfiles>
+ <activeProfile>maven-core-it-repo</activeProfile>
+ </activeProfiles>
+</settings>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-settings/settings-no-pom/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-settings/settings-no-pom/pom.xml
new file mode 100644
index 00000000..ee627826
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-settings/settings-no-pom/pom.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng3099</groupId>
+ <artifactId>maven-mng3099-plugin</artifactId>
+ <version>1</version>
+ <packaging>maven-plugin</packaging>
+
+ <name>maven-mng3099-plugin</name>
+ <description>Tests properties injected as a result of active profiles in the user settings file.</description>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-settings/settings-no-pom/settings.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-settings/settings-no-pom/settings.xml
new file mode 100644
index 00000000..964e0512
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-settings/settings-no-pom/settings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<settings
+ xmlns="http://maven.apache.org/SETTINGS/1.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
+
+ <profiles>
+ <profile>
+ <id>local-profile</id>
+ <properties>
+ <local-profile-prop>local-profile-prop-value</local-profile-prop>
+ </properties>
+ </profile>
+ </profiles>
+
+ <activeProfiles>
+ <activeProfile>local-profile</activeProfile>
+ </activeProfiles>
+
+</settings>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-settings/test-pom-and-settings-interpolation/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-settings/test-pom-and-settings-interpolation/pom.xml
new file mode 100644
index 00000000..245349a6
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-settings/test-pom-and-settings-interpolation/pom.xml
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng4107</groupId>
+ <artifactId>test</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <packaging>jar</packaging>
+
+ <name>Maven Integration Test :: MNG-4107</name>
+ <description>
+ Test that POM interpolation uses the property values from the dominant profile source (POM vs. profiles.xml
+ vs. settings.xml). This boils down to the proper order of profile injection and interpolation, i.e.
+ interpolate after profiles from all sources are injected.
+ </description>
+
+ <properties>
+ <!-- collect the effective property values as derived by interpolation -->
+ <pomVsSettingsInterpolated>${pomVsSettings}</pomVsSettingsInterpolated>
+ </properties>
+
+ <profiles>
+ <profile>
+ <id>pom</id>
+ <activation>
+ <activeByDefault>true</activeByDefault>
+ </activation>
+ <properties>
+ <pomProfile>applied</pomProfile>
+ <pomVsSettings>pom</pomVsSettings>
+ </properties>
+ </profile>
+ </profiles>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.its.plugins</groupId>
+ <artifactId>maven-it-plugin-expression</artifactId>
+ <version>2.1-SNAPSHOT</version>
+ <executions>
+ <execution>
+ <phase>validate</phase>
+ <goals>
+ <goal>eval</goal>
+ </goals>
+ <configuration>
+ <outputFile>target/pom.properties</outputFile>
+ <expressions>
+ <expression>project/properties</expression>
+ </expressions>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-settings/test-pom-and-settings-interpolation/settings.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-settings/test-pom-and-settings-interpolation/settings.xml
new file mode 100644
index 00000000..2d42d495
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources-settings/test-pom-and-settings-interpolation/settings.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<settings>
+ <profiles>
+ <profile>
+ <id>settings</id>
+ <activation>
+ <activeByDefault>true</activeByDefault>
+ </activation>
+ <properties>
+ <settingsProfile>applied</settingsProfile>
+ <pomVsSettings>settings</pomVsSettings>
+ </properties>
+ </profile>
+ </profiles>
+</settings>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/META-INF/maven/org.apache.maven/maven-core/pom.properties b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/META-INF/maven/org.apache.maven/maven-core/pom.properties
new file mode 100644
index 00000000..ef45373a
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/META-INF/maven/org.apache.maven/maven-core/pom.properties
@@ -0,0 +1 @@
+version=2.1-SNAPSHOT \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/META-INF/plexus/components.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/META-INF/plexus/components.xml
new file mode 100644
index 00000000..714cb36b
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/META-INF/plexus/components.xml
@@ -0,0 +1,113 @@
+<component-set>
+ <components>
+ <component>
+ <role>org.apache.maven.lifecycle.binding.LegacyLifecycleParsingTestComponent</role>
+ <role-hint>default</role-hint>
+ <implementation>org.apache.maven.lifecycle.binding.LegacyLifecycleParsingTestComponent</implementation>
+ <configuration>
+ <lifecycles>
+ <lifecycle>
+ <id>default</id>
+ <phases>
+ <phase>validate</phase>
+ <phase>initialize</phase>
+ <phase>generate-sources</phase>
+ <phase>process-sources</phase>
+ <phase>generate-resources</phase>
+ <phase>process-resources</phase>
+ <phase>compile</phase>
+ <phase>process-classes</phase>
+ <phase>generate-test-sources</phase>
+ <phase>process-test-sources</phase>
+ <phase>generate-test-resources</phase>
+ <phase>process-test-resources</phase>
+ <phase>test-compile</phase>
+ <phase>process-test-classes</phase>
+ <phase>test</phase>
+ <phase>prepare-package</phase>
+ <phase>package</phase>
+ <phase>pre-integration-test</phase>
+ <phase>integration-test</phase>
+ <phase>post-integration-test</phase>
+ <phase>verify</phase>
+ <phase>install</phase>
+ <phase>deploy</phase>
+ </phases>
+ </lifecycle>
+ <lifecycle>
+ <id>clean</id>
+ <phases>
+ <phase>pre-clean</phase>
+ <phase>clean</phase>
+ <phase>post-clean</phase>
+ </phases>
+ <default-phases>
+ <clean>org.apache.maven.plugins:maven-clean-plugin:clean</clean>
+ </default-phases>
+ </lifecycle>
+ <lifecycle>
+ <id>site</id>
+ <phases>
+ <phase>pre-site</phase>
+ <phase>site</phase>
+ <phase>post-site</phase>
+ <phase>site-deploy</phase>
+ </phases>
+ <default-phases>
+ <site>org.apache.maven.plugins:maven-site-plugin:site</site>
+ <site-deploy>org.apache.maven.plugins:maven-site-plugin:deploy</site-deploy>
+ </default-phases>
+ </lifecycle>
+ </lifecycles>
+ </configuration>
+ </component>
+ <component>
+ <role>org.apache.maven.lifecycle.mapping.LifecycleMapping</role>
+ <role-hint>test-mapping</role-hint>
+ <implementation>org.apache.maven.lifecycle.mapping.DefaultLifecycleMapping</implementation>
+ <configuration>
+ <lifecycles>
+ <lifecycle>
+ <id>default</id>
+ <!-- START SNIPPET: pom-lifecycle -->
+
+ <phases>
+ <package>org.apache.maven.plugins:maven-site-plugin:attach-descriptor</package>
+ <install>org.apache.maven.plugins:maven-install-plugin:install</install>
+ <deploy>org.apache.maven.plugins:maven-deploy-plugin:deploy</deploy>
+ </phases>
+ <optional-mojos>
+ <optional-mojo>org.apache.maven.plugins:maven-site-plugin:attach-descriptor</optional-mojo>
+ </optional-mojos>
+ <!-- END SNIPPET: pom-lifecycle -->
+ </lifecycle>
+ </lifecycles>
+ </configuration>
+ </component>
+ <component>
+ <role>org.apache.maven.lifecycle.mapping.LifecycleMapping</role>
+ <role-hint>test-mapping2</role-hint>
+ <implementation>org.apache.maven.lifecycle.mapping.DefaultLifecycleMapping</implementation>
+ <configuration>
+ <lifecycles>
+ <lifecycle>
+ <id>default</id>
+ <!-- START SNIPPET: pom-lifecycle -->
+ <phases>
+ <package>
+ org.apache.maven.plugins:maven-site-plugin:attach-descriptor,
+ org.apache.maven.plugins:maven-clean-plugin:clean
+ </package>
+ <install>org.apache.maven.plugins:maven-install-plugin:install</install>
+ <deploy>org.apache.maven.plugins:maven-deploy-plugin:deploy</deploy>
+ </phases>
+ <optional-mojos>
+ <optional-mojo>org.apache.maven.plugins:maven-site-plugin:attach-descriptor</optional-mojo>
+ </optional-mojos>
+ <!-- END SNIPPET: pom-lifecycle -->
+ </lifecycle>
+ </lifecycles>
+ </configuration>
+ </component>
+ </components>
+</component-set> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/canonical-pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/canonical-pom.xml
new file mode 100644
index 00000000..82bf8725
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/canonical-pom.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>maven</groupId>
+ <artifactId>maven-core</artifactId>
+ <version>2.0-SNAPSHOT</version>
+
+ <name>Maven</name>
+
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-plexus-plugin</artifactId>
+ <version>1.0</version>
+ <configuration>
+ <plexusConfiguration>src/conf/plexus.conf</plexusConfiguration>
+ <plexusConfigurationPropertiesFile>src/conf/plexus.properties</plexusConfigurationPropertiesFile>
+ <plexusApplicationName>Continuum</plexusApplicationName>
+ </configuration>
+ <executions>
+ <execution>
+ <goals>
+ <goal>plexus:runtime</goal>
+ </goals>
+ <configuration>
+ <plexusApplicationName>ContinuumPro</plexusApplicationName>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/dependencyManagement-pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/dependencyManagement-pom.xml
new file mode 100644
index 00000000..2accaca8
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/dependencyManagement-pom.xml
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>maven</groupId>
+ <artifactId>maven-core</artifactId>
+ <version>2.0-SNAPSHOT</version>
+
+ <name>Maven</name>
+
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>maven-test-b</artifactId>
+ <version>1.0</version>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-plexus-plugin</artifactId>
+ <version>1.0</version>
+ <configuration>
+ <plexusConfiguration>src/conf/plexus.conf</plexusConfiguration>
+ <plexusConfigurationPropertiesFile>src/conf/plexus.properties</plexusConfigurationPropertiesFile>
+ <plexusApplicationName>Continuum</plexusApplicationName>
+ </configuration>
+ <executions>
+ <execution>
+ <goals>
+ <goal>plexus:runtime</goal>
+ </goals>
+ <configuration>
+ <plexusApplicationName>ContinuumPro</plexusApplicationName>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/distributionManagement-pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/distributionManagement-pom.xml
new file mode 100644
index 00000000..1a8ee7ff
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/distributionManagement-pom.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>maven</groupId>
+ <artifactId>maven-core</artifactId>
+ <version>2.0-SNAPSHOT</version>
+
+ <name>Maven</name>
+
+ <distributionManagement>
+ <snapshotRepository>
+ <id>repo-id</id>
+ <name>my snapshot repository</name>
+ <url>file:///path/to/snapshot/repo</url>
+ </snapshotRepository>
+ <repository>
+ <id>repo-id2</id>
+ <name>my repository</name>
+ <url>file:///path/to/repo</url>
+ </repository>
+ </distributionManagement>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/maven-test/jars/maven-test-a-1.0.jar b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/maven-test/jars/maven-test-a-1.0.jar
new file mode 100644
index 00000000..257cc564
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/maven-test/jars/maven-test-a-1.0.jar
@@ -0,0 +1 @@
+foo
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/maven-test/jars/maven-test-a-1.1.jar b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/maven-test/jars/maven-test-a-1.1.jar
new file mode 100644
index 00000000..257cc564
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/maven-test/jars/maven-test-a-1.1.jar
@@ -0,0 +1 @@
+foo
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/maven-test/jars/maven-test-b-1.0.jar b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/maven-test/jars/maven-test-b-1.0.jar
new file mode 100644
index 00000000..257cc564
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/maven-test/jars/maven-test-b-1.0.jar
@@ -0,0 +1 @@
+foo
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/maven-test/jars/maven-test-b-1.1.jar b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/maven-test/jars/maven-test-b-1.1.jar
new file mode 100644
index 00000000..257cc564
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/maven-test/jars/maven-test-b-1.1.jar
@@ -0,0 +1 @@
+foo
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/maven-test/jars/maven-test-c-1.0.jar b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/maven-test/jars/maven-test-c-1.0.jar
new file mode 100644
index 00000000..257cc564
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/maven-test/jars/maven-test-c-1.0.jar
@@ -0,0 +1 @@
+foo
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/maven-test/jars/maven-test-c-1.1.jar b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/maven-test/jars/maven-test-c-1.1.jar
new file mode 100644
index 00000000..257cc564
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/maven-test/jars/maven-test-c-1.1.jar
@@ -0,0 +1 @@
+foo
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/maven-test/jars/maven-test-d-1.0.jar b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/maven-test/jars/maven-test-d-1.0.jar
new file mode 100644
index 00000000..257cc564
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/maven-test/jars/maven-test-d-1.0.jar
@@ -0,0 +1 @@
+foo
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/maven-test/jars/maven-test-d-1.1.jar b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/maven-test/jars/maven-test-d-1.1.jar
new file mode 100644
index 00000000..257cc564
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/maven-test/jars/maven-test-d-1.1.jar
@@ -0,0 +1 @@
+foo
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/maven-test/jars/maven-test-d-1.2.jar b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/maven-test/jars/maven-test-d-1.2.jar
new file mode 100644
index 00000000..257cc564
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/maven-test/jars/maven-test-d-1.2.jar
@@ -0,0 +1 @@
+foo
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/maven-test/poms/maven-test-a-1.0.pom b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/maven-test/poms/maven-test-a-1.0.pom
new file mode 100644
index 00000000..93fc0d0b
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/maven-test/poms/maven-test-a-1.0.pom
@@ -0,0 +1,14 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven-test</groupId>
+ <artifactId>maven-test-a</artifactId>
+ <packaging>jar</packaging>
+ <version>1.0</version>
+ <repositories>
+ <repository>
+ <id>central</id>
+ <name>Fake Maven Central Repository</name>
+ <url>file://dummy</url>
+ </repository>
+ </repositories>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/maven-test/poms/maven-test-a-1.1.pom b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/maven-test/poms/maven-test-a-1.1.pom
new file mode 100644
index 00000000..a0830861
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/maven-test/poms/maven-test-a-1.1.pom
@@ -0,0 +1,14 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven-test</groupId>
+ <artifactId>maven-test-a</artifactId>
+ <packaging>jar</packaging>
+ <version>1.1</version>
+ <repositories>
+ <repository>
+ <id>central</id>
+ <name>Fake Maven Central Repository</name>
+ <url>file://dummy</url>
+ </repository>
+ </repositories>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/maven-test/poms/maven-test-b-1.0.pom b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/maven-test/poms/maven-test-b-1.0.pom
new file mode 100644
index 00000000..c173c663
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/maven-test/poms/maven-test-b-1.0.pom
@@ -0,0 +1,7 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven-test</groupId>
+ <artifactId>maven-test-b</artifactId>
+ <packaging>jar</packaging>
+ <version>1.0</version>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/maven-test/poms/maven-test-b-1.1.pom b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/maven-test/poms/maven-test-b-1.1.pom
new file mode 100644
index 00000000..fff241a1
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/maven-test/poms/maven-test-b-1.1.pom
@@ -0,0 +1,7 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven-test</groupId>
+ <artifactId>maven-test-b</artifactId>
+ <packaging>jar</packaging>
+ <version>1.1</version>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/maven-test/poms/maven-test-c-1.0.pom b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/maven-test/poms/maven-test-c-1.0.pom
new file mode 100644
index 00000000..1f049786
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/maven-test/poms/maven-test-c-1.0.pom
@@ -0,0 +1,7 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven-test</groupId>
+ <artifactId>maven-test-c</artifactId>
+ <packaging>jar</packaging>
+ <version>1.0</version>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/maven-test/poms/maven-test-c-1.1.pom b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/maven-test/poms/maven-test-c-1.1.pom
new file mode 100644
index 00000000..8bd52514
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/maven-test/poms/maven-test-c-1.1.pom
@@ -0,0 +1,7 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven-test</groupId>
+ <artifactId>maven-test-c</artifactId>
+ <packaging>jar</packaging>
+ <version>1.1</version>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/maven-test/poms/maven-test-d-1.0.pom b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/maven-test/poms/maven-test-d-1.0.pom
new file mode 100644
index 00000000..ac6ef12e
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/maven-test/poms/maven-test-d-1.0.pom
@@ -0,0 +1,7 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven-test</groupId>
+ <artifactId>maven-test-d</artifactId>
+ <packaging>jar</packaging>
+ <version>1.0</version>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/maven-test/poms/maven-test-d-1.1.pom b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/maven-test/poms/maven-test-d-1.1.pom
new file mode 100644
index 00000000..6e22f608
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/maven-test/poms/maven-test-d-1.1.pom
@@ -0,0 +1,7 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven-test</groupId>
+ <artifactId>maven-test-d</artifactId>
+ <packaging>jar</packaging>
+ <version>1.1</version>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/maven-test/poms/maven-test-d-1.2.pom b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/maven-test/poms/maven-test-d-1.2.pom
new file mode 100644
index 00000000..16f8d905
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/maven-test/poms/maven-test-d-1.2.pom
@@ -0,0 +1,7 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven-test</groupId>
+ <artifactId>maven-test-d</artifactId>
+ <packaging>jar</packaging>
+ <version>1.2</version>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/p0/p1/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/p0/p1/pom.xml
new file mode 100644
index 00000000..7bfca342
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/p0/p1/pom.xml
@@ -0,0 +1,45 @@
+<project>
+ <parent>
+ <artifactId>p0</artifactId>
+ <groupId>maven</groupId>
+ <version>1.0</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven</groupId>
+ <artifactId>p1</artifactId>
+ <packaging>pom</packaging>
+ <name>p1</name>
+ <version>1.0</version>
+ <scm>
+ <url>scm-url</url>
+ </scm>
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>maven-test-b</artifactId>
+ <version>1.0</version>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>maven-test-a</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>maven-test-b</artifactId>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-antrun-plugin</artifactId>
+ <configuration>
+ <tasks><echo>${project.parent.basedir}</echo></tasks>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/p0/p2/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/p0/p2/pom.xml
new file mode 100644
index 00000000..b45ce9c6
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/p0/p2/pom.xml
@@ -0,0 +1,56 @@
+<project>
+ <parent>
+ <artifactId>p0</artifactId>
+ <groupId>maven</groupId>
+ <version>1.0</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven</groupId>
+ <artifactId>p2</artifactId>
+ <packaging>pom</packaging>
+ <name>p2</name>
+ <version>1.0</version>
+ <scm>
+ <url>scm-url</url>
+ </scm>
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>maven</groupId>
+ <artifactId>p1</artifactId>
+ <version>1.0</version>
+ <type>pom</type>
+ <scope>import</scope>
+ </dependency>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>maven-test-c</artifactId>
+ <version>1.0</version>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>maven-test-a</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>maven-test-b</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>maven-test-c</artifactId>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-antrun-plugin</artifactId>
+ <configuration>
+ <tasks><echo>${project.parent.basedir}</echo></tasks>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/p0/p3/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/p0/p3/pom.xml
new file mode 100644
index 00000000..e9648e39
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/p0/p3/pom.xml
@@ -0,0 +1,59 @@
+<project>
+ <parent>
+ <artifactId>p0</artifactId>
+ <groupId>maven</groupId>
+ <version>1.0</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven</groupId>
+ <artifactId>p3</artifactId>
+ <packaging>pom</packaging>
+ <name>p3</name>
+ <version>1.0</version>
+ <scm>
+ <url>scm-url</url>
+ </scm>
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>maven-test-a</artifactId>
+ <version>1.1</version>
+ </dependency>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>maven-test-c</artifactId>
+ <version>1.1</version>
+ </dependency>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>maven-test-d</artifactId>
+ <version>1.0</version>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>maven-test-a</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>maven-test-c</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>maven-test-d</artifactId>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-antrun-plugin</artifactId>
+ <configuration>
+ <tasks><echo>${project.parent.basedir}</echo></tasks>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/p0/p4/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/p0/p4/pom.xml
new file mode 100644
index 00000000..7ffef9d7
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/p0/p4/pom.xml
@@ -0,0 +1,67 @@
+<project>
+ <parent>
+ <artifactId>p0</artifactId>
+ <groupId>maven</groupId>
+ <version>1.0</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven</groupId>
+ <artifactId>p4</artifactId>
+ <packaging>pom</packaging>
+ <name>p4</name>
+ <version>1.0</version>
+ <scm>
+ <url>scm-url</url>
+ </scm>
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>maven</groupId>
+ <artifactId>p2</artifactId>
+ <version>1.0</version>
+ <type>pom</type>
+ <scope>import</scope>
+ </dependency>
+ <dependency>
+ <groupId>maven</groupId>
+ <artifactId>p3</artifactId>
+ <version>1.0</version>
+ <type>pom</type>
+ <scope>import</scope>
+ </dependency>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>maven-test-b</artifactId>
+ <version>1.1</version>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>maven-test-a</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>maven-test-b</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>maven-test-c</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>maven-test-d</artifactId>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-antrun-plugin</artifactId>
+ <configuration>
+ <tasks><echo>${project.parent.basedir}</echo></tasks>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/p0/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/p0/pom.xml
new file mode 100644
index 00000000..3ccf7e63
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/imports-repo/t01/p0/pom.xml
@@ -0,0 +1,26 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven</groupId>
+ <artifactId>p0</artifactId>
+ <packaging>pom</packaging>
+ <name>p0</name>
+ <version>1.0</version>
+ <organization>
+ <name>Codehaus</name>
+ </organization>
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>maven-test-a</artifactId>
+ <version>1.0</version>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+ <modules>
+ <module>p1</module>
+ <module>p2</module>
+ <module>p3</module>
+ <module>p4</module>
+ </modules>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/local-repo/marker.txt b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/local-repo/marker.txt
new file mode 100644
index 00000000..d9bab060
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/local-repo/marker.txt
@@ -0,0 +1 @@
+this is just a marker file. \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/local-repo/maven-test/jars/maven-test-a-1.0.jar b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/local-repo/maven-test/jars/maven-test-a-1.0.jar
new file mode 100644
index 00000000..257cc564
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/local-repo/maven-test/jars/maven-test-a-1.0.jar
@@ -0,0 +1 @@
+foo
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/local-repo/maven-test/jars/maven-test-b-1.0.jar b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/local-repo/maven-test/jars/maven-test-b-1.0.jar
new file mode 100644
index 00000000..257cc564
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/local-repo/maven-test/jars/maven-test-b-1.0.jar
@@ -0,0 +1 @@
+foo
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/local-repo/maven-test/jars/maven-test-c-1.0.jar b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/local-repo/maven-test/jars/maven-test-c-1.0.jar
new file mode 100644
index 00000000..257cc564
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/local-repo/maven-test/jars/maven-test-c-1.0.jar
@@ -0,0 +1 @@
+foo
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/local-repo/maven-test/jars/maven-test-d-1.0.jar b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/local-repo/maven-test/jars/maven-test-d-1.0.jar
new file mode 100644
index 00000000..257cc564
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/local-repo/maven-test/jars/maven-test-d-1.0.jar
@@ -0,0 +1 @@
+foo
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/local-repo/maven-test/poms/maven-test-a-1.0.pom b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/local-repo/maven-test/poms/maven-test-a-1.0.pom
new file mode 100644
index 00000000..6905f6c8
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/local-repo/maven-test/poms/maven-test-a-1.0.pom
@@ -0,0 +1,23 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven-test</groupId>
+ <artifactId>maven-test-a</artifactId>
+ <packaging>jar</packaging>
+ <version>1.0</version>
+ <repositories>
+ <repository>
+ <id>central</id>
+ <name>Fake Maven Central Repository</name>
+ <url>file://dummy</url>
+ </repository>
+ </repositories>
+ <dependencies>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>maven-test-b</artifactId>
+ <version>1.0</version>
+ <type>jar</type>
+ <scope>compile</scope>
+ </dependency>
+ </dependencies>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/local-repo/maven-test/poms/maven-test-b-1.0.pom b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/local-repo/maven-test/poms/maven-test-b-1.0.pom
new file mode 100644
index 00000000..e814951a
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/local-repo/maven-test/poms/maven-test-b-1.0.pom
@@ -0,0 +1,23 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven-test</groupId>
+ <artifactId>maven-test-b</artifactId>
+ <packaging>jar</packaging>
+ <version>1.0</version>
+ <dependencies>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>maven-test-c</artifactId>
+ <version>1.0</version>
+ <type>jar</type>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>maven-test-d</artifactId>
+ <version>1.1</version>
+ <type>jar</type>
+ <scope>compile</scope>
+ </dependency>
+ </dependencies>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/local-repo/maven-test/poms/maven-test-c-1.0.pom b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/local-repo/maven-test/poms/maven-test-c-1.0.pom
new file mode 100644
index 00000000..4631b88f
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/local-repo/maven-test/poms/maven-test-c-1.0.pom
@@ -0,0 +1,16 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven-test</groupId>
+ <artifactId>maven-test-c</artifactId>
+ <packaging>jar</packaging>
+ <version>1.0</version>
+ <dependencies>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>maven-test-d</artifactId>
+ <version>1.2</version>
+ <type>jar</type>
+ <scope>compile</scope>
+ </dependency>
+ </dependencies>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/local-repo/maven-test/poms/maven-test-d-1.1.pom b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/local-repo/maven-test/poms/maven-test-d-1.1.pom
new file mode 100644
index 00000000..6e22f608
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/local-repo/maven-test/poms/maven-test-d-1.1.pom
@@ -0,0 +1,7 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven-test</groupId>
+ <artifactId>maven-test-d</artifactId>
+ <packaging>jar</packaging>
+ <version>1.1</version>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/local-repo/maven-test/poms/maven-test-d-1.2.pom b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/local-repo/maven-test/poms/maven-test-d-1.2.pom
new file mode 100644
index 00000000..6e22f608
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/local-repo/maven-test/poms/maven-test-d-1.2.pom
@@ -0,0 +1,7 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven-test</groupId>
+ <artifactId>maven-test-d</artifactId>
+ <packaging>jar</packaging>
+ <version>1.1</version>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/local-repo/snapshot-test/jars/maven-snapshot-a-1.0-SNAPSHOT.jar b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/local-repo/snapshot-test/jars/maven-snapshot-a-1.0-SNAPSHOT.jar
new file mode 100644
index 00000000..c2c027fe
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/local-repo/snapshot-test/jars/maven-snapshot-a-1.0-SNAPSHOT.jar
@@ -0,0 +1 @@
+local \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/local-repo/snapshot-test/jars/maven-snapshot-a-1.0-SNAPSHOT.jar.snapshot-version b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/local-repo/snapshot-test/jars/maven-snapshot-a-1.0-SNAPSHOT.jar.snapshot-version
new file mode 100644
index 00000000..09f9180f
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/local-repo/snapshot-test/jars/maven-snapshot-a-1.0-SNAPSHOT.jar.snapshot-version
@@ -0,0 +1 @@
+20040101.101010 \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/local-repo/snapshot-test/jars/maven-snapshot-b-1.0-SNAPSHOT.jar b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/local-repo/snapshot-test/jars/maven-snapshot-b-1.0-SNAPSHOT.jar
new file mode 100644
index 00000000..c2c027fe
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/local-repo/snapshot-test/jars/maven-snapshot-b-1.0-SNAPSHOT.jar
@@ -0,0 +1 @@
+local \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/local-repo/snapshot-test/jars/maven-snapshot-b-1.0-SNAPSHOT.jar.snapshot-version b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/local-repo/snapshot-test/jars/maven-snapshot-b-1.0-SNAPSHOT.jar.snapshot-version
new file mode 100644
index 00000000..09f9180f
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/local-repo/snapshot-test/jars/maven-snapshot-b-1.0-SNAPSHOT.jar.snapshot-version
@@ -0,0 +1 @@
+20040101.101010 \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/local-repo/snapshot-test/jars/maven-snapshot-e-1.0-SNAPSHOT.jar b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/local-repo/snapshot-test/jars/maven-snapshot-e-1.0-SNAPSHOT.jar
new file mode 100644
index 00000000..c2c027fe
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/local-repo/snapshot-test/jars/maven-snapshot-e-1.0-SNAPSHOT.jar
@@ -0,0 +1 @@
+local \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/local-repo/snapshot-test/jars/maven-snapshot-e-1.0-SNAPSHOT.jar.snapshot-version b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/local-repo/snapshot-test/jars/maven-snapshot-e-1.0-SNAPSHOT.jar.snapshot-version
new file mode 100644
index 00000000..09f9180f
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/local-repo/snapshot-test/jars/maven-snapshot-e-1.0-SNAPSHOT.jar.snapshot-version
@@ -0,0 +1 @@
+20040101.101010 \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/local-repo/snapshot-test/poms/maven-test-snapshot-resolving-1.0.pom b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/local-repo/snapshot-test/poms/maven-test-snapshot-resolving-1.0.pom
new file mode 100644
index 00000000..64a075f4
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/local-repo/snapshot-test/poms/maven-test-snapshot-resolving-1.0.pom
@@ -0,0 +1,49 @@
+<project>
+ <groupId>snapshot-test</groupId>
+ <artifactId>maven-test-snapshot-resolving</artifactId>
+ <packaging>jar</packaging>
+ <repositories>
+ <repository>
+ <id>central</id>
+ <name>Fake Maven Central Repository</name>
+ <url>file://dummy</url>
+ </repository>
+ </repositories>
+ <dependencies>
+ <dependency>
+ <groupId>snapshot-test</groupId>
+ <artifactId>maven-snapshot-a</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <type>jar</type>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>snapshot-test</groupId>
+ <artifactId>maven-snapshot-b</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <type>jar</type>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>snapshot-test</groupId>
+ <artifactId>maven-snapshot-c</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <type>jar</type>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>snapshot-test</groupId>
+ <artifactId>maven-snapshot-d</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <type>jar</type>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>snapshot-test</groupId>
+ <artifactId>maven-snapshot-e</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <type>jar</type>
+ <scope>compile</scope>
+ </dependency>
+ </dependencies>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/MavenLifecycleParticipantTest.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/MavenLifecycleParticipantTest.xml
new file mode 100644
index 00000000..ebbbf791
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/MavenLifecycleParticipantTest.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<plexus>
+ <components>
+ <component>
+ <role>org.apache.maven.project.ProjectBuildingHelper</role>
+ <implementation>org.apache.maven.project.EmptyProjectBuildingHelper</implementation>
+ </component>
+ </components>
+</plexus>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/execution/test-extension-1.jar b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/execution/test-extension-1.jar
new file mode 100644
index 00000000..0272ee3c
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/execution/test-extension-1.jar
Binary files differ
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/junit/junit/3.8.1/junit-3.8.1.jar b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/junit/junit/3.8.1/junit-3.8.1.jar
new file mode 100644
index 00000000..674d71e8
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/junit/junit/3.8.1/junit-3.8.1.jar
Binary files differ
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/junit/junit/3.8.1/junit-3.8.1.jar.md5 b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/junit/junit/3.8.1/junit-3.8.1.jar.md5
new file mode 100644
index 00000000..92c6c765
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/junit/junit/3.8.1/junit-3.8.1.jar.md5
@@ -0,0 +1 @@
+1f40fb782a4f2cf78f161d32670f7a3a \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/junit/junit/3.8.1/junit-3.8.1.jar.sha1 b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/junit/junit/3.8.1/junit-3.8.1.jar.sha1
new file mode 100644
index 00000000..ed10f030
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/junit/junit/3.8.1/junit-3.8.1.jar.sha1
@@ -0,0 +1 @@
+99129f16442844f6a4a11ae22fbbee40b14d774f \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/junit/junit/3.8.1/junit-3.8.1.pom b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/junit/junit/3.8.1/junit-3.8.1.pom
new file mode 100644
index 00000000..2169a65d
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/junit/junit/3.8.1/junit-3.8.1.pom
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd ">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>3.8.1</version>
+ <name>JUnit</name>
+ <url>http://junit.org</url>
+ <description>
+ JUnit is a regression testing framework written by Erich Gamma and Kent Beck. It is used by the developer who implements unit tests in Java.
+ </description>
+ <organization>
+ <name>JUnit</name>
+ <url>http://www.junit.org</url>
+ </organization>
+ <licenses>
+ <license>
+ <name>Common Public License Version 1.0</name>
+ <url>http://www.opensource.org/licenses/cpl1.0.txt</url>
+ </license>
+ </licenses>
+ <scm>
+ <url>http://junit.cvs.sourceforge.net/junit/</url>
+ </scm>
+ <dependencies>
+ </dependencies>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/junit/junit/3.8.1/junit-3.8.1.pom.md5 b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/junit/junit/3.8.1/junit-3.8.1.pom.md5
new file mode 100644
index 00000000..51e102f6
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/junit/junit/3.8.1/junit-3.8.1.pom.md5
@@ -0,0 +1 @@
+50b40cb7342f52b702e6337d5debf1ae \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/junit/junit/3.8.1/junit-3.8.1.pom.sha1 b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/junit/junit/3.8.1/junit-3.8.1.pom.sha1
new file mode 100644
index 00000000..82ac6705
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/junit/junit/3.8.1/junit-3.8.1.pom.sha1
@@ -0,0 +1 @@
+16d74791c801c89b0071b1680ea0bc85c93417bb \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/apache/3/apache-3.pom b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/apache/3/apache-3.pom
new file mode 100644
index 00000000..1fc7e406
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/apache/3/apache-3.pom
@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ ~ Copyright 2005-2006 The Apache Software Foundation.
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <!-- Shared parent. Doesn't define a lot of things about Apache like general mailing lists, but does
+ define the settings common to all projects at Apache -->
+ <groupId>org.apache</groupId>
+ <artifactId>apache</artifactId>
+ <version>3</version>
+ <packaging>pom</packaging>
+ <name>The Apache Software Foundation</name>
+ <description>
+ The Apache Software Foundation provides support for the Apache community of open-source software projects.
+ The Apache projects are characterized by a collaborative, consensus based development process, an open and
+ pragmatic software license, and a desire to create high quality software that leads the way in its field.
+ We consider ourselves not simply a group of projects sharing a server, but rather a community of developers
+ and users.
+ </description>
+ <licenses>
+ <license>
+ <name>The Apache Software License, Version 2.0</name>
+ <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
+ <distribution>repo</distribution>
+ </license>
+ </licenses>
+ <organization>
+ <name>Apache Software Foundation</name>
+ <url>http://www.apache.org/</url>
+ </organization>
+ <url>http://www.apache.org/</url>
+ <repositories>
+ <repository>
+ <id>apache.snapshots</id>
+ <name>Apache Snapshot Repository</name>
+ <url>http://people.apache.org/repo/m2-snapshot-repository</url>
+ <releases>
+ <enabled>false</enabled>
+ </releases>
+ </repository>
+ </repositories>
+ <distributionManagement>
+ <!-- Site omitted - each project must provide their own -->
+ <repository>
+ <id>apache.releases</id>
+ <name>Apache Release Distribution Repository</name>
+ <url>scp://people.apache.org/www/people.apache.org/repo/m2-ibiblio-rsync-repository</url>
+ </repository>
+ <snapshotRepository>
+ <id>apache.snapshots</id>
+ <name>Apache Development Snapshot Repository</name>
+ <url>scp://people.apache.org/www/people.apache.org/repo/m2-snapshot-repository</url>
+ </snapshotRepository>
+ </distributionManagement>
+ <mailingLists>
+ <mailingList>
+ <name>Apache Announce List</name>
+ <subscribe>announce-subscribe@apache.org</subscribe>
+ <unsubscribe>announce-unsubscribe@apache.org</unsubscribe>
+ <post>announce@apache.org</post>
+ <archive>http://mail-archives.apache.org/mod_mbox/www-announce/</archive>
+ </mailingList>
+ </mailingLists>
+</project>
+
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/apache/3/apache-3.pom.md5 b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/apache/3/apache-3.pom.md5
new file mode 100644
index 00000000..b9d0ea16
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/apache/3/apache-3.pom.md5
@@ -0,0 +1 @@
+c857ebbb5f303f435495e40e6c9e45a2 \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/apache/3/apache-3.pom.sha1 b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/apache/3/apache-3.pom.sha1
new file mode 100644
index 00000000..ffb57bbc
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/apache/3/apache-3.pom.sha1
@@ -0,0 +1 @@
+1bc0010136a890e2fd38d901a0b7ecdf0e3f9871 \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/artifact/maven-artifact/3.0-SNAPSHOT/maven-artifact-3.0-SNAPSHOT.jar b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/artifact/maven-artifact/3.0-SNAPSHOT/maven-artifact-3.0-SNAPSHOT.jar
new file mode 100644
index 00000000..5bc9c06c
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/artifact/maven-artifact/3.0-SNAPSHOT/maven-artifact-3.0-SNAPSHOT.jar
Binary files differ
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/artifact/maven-artifact/3.0-SNAPSHOT/maven-artifact-3.0-SNAPSHOT.jar.md5 b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/artifact/maven-artifact/3.0-SNAPSHOT/maven-artifact-3.0-SNAPSHOT.jar.md5
new file mode 100644
index 00000000..5ff89e83
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/artifact/maven-artifact/3.0-SNAPSHOT/maven-artifact-3.0-SNAPSHOT.jar.md5
@@ -0,0 +1 @@
+430da483dcfb2964a9dcd619c29a6c78 \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/artifact/maven-artifact/3.0-SNAPSHOT/maven-artifact-3.0-SNAPSHOT.jar.sha1 b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/artifact/maven-artifact/3.0-SNAPSHOT/maven-artifact-3.0-SNAPSHOT.jar.sha1
new file mode 100644
index 00000000..a3418804
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/artifact/maven-artifact/3.0-SNAPSHOT/maven-artifact-3.0-SNAPSHOT.jar.sha1
@@ -0,0 +1 @@
+ea9e3f3fdc25f386d5f9ac861a55b6c3bb773d91 \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/artifact/maven-artifact/3.0-SNAPSHOT/maven-artifact-3.0-SNAPSHOT.pom b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/artifact/maven-artifact/3.0-SNAPSHOT/maven-artifact-3.0-SNAPSHOT.pom
new file mode 100644
index 00000000..8de3ce6d
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/artifact/maven-artifact/3.0-SNAPSHOT/maven-artifact-3.0-SNAPSHOT.pom
@@ -0,0 +1,112 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <parent>
+ <artifactId>maven-parent</artifactId>
+ <groupId>org.apache.maven</groupId>
+ <version>5</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven.artifact</groupId>
+ <artifactId>maven-artifact</artifactId>
+ <version>3.0-SNAPSHOT</version>
+ <name>Maven Artifact</name>
+ <scm>
+ <connection>scm:svn:http://svn.apache.org/repos/asf/maven/artifact/trunk</connection>
+ <developerConnection>scm:svn:https://svn.apache.org/repos/asf/maven/artifact/trunk</developerConnection>
+ <url>http://svn.apache.org/viewcvs.cgi/maven/artifact/trunk</url>
+ </scm>
+ <dependencies>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-utils</artifactId>
+ <version>1.4.5</version>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-container-default</artifactId>
+ <version>1.0-alpha-32</version>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-active-collections</artifactId>
+ <version>1.0-beta-1</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.wagon</groupId>
+ <artifactId>wagon-provider-api</artifactId>
+ <version>1.0-beta-2</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.wagon</groupId>
+ <artifactId>wagon-file</artifactId>
+ <version>1.0-beta-2</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>easymock</groupId>
+ <artifactId>easymock</artifactId>
+ <version>1.2_Java1.3</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.modello</groupId>
+ <artifactId>modello-maven-plugin</artifactId>
+ <version>1.0-alpha-17</version>
+ <configuration>
+ <version>1.0.0</version>
+ <model>src/main/mdo/metadata.mdo</model>
+ </configuration>
+ <executions>
+ <execution>
+ <id>site-docs</id>
+ <phase>pre-site</phase>
+ <goals>
+ <goal>xdoc</goal>
+ <goal>xsd</goal>
+ </goals>
+ </execution>
+ <execution>
+ <id>standard</id>
+ <goals>
+ <goal>java</goal>
+ <goal>xpp3-reader</goal>
+ <goal>xpp3-writer</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <excludes>
+ <exclude>**/testutils/**</exclude>
+ </excludes>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/artifact/maven-artifact/3.0-SNAPSHOT/maven-artifact-3.0-SNAPSHOT.pom.md5 b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/artifact/maven-artifact/3.0-SNAPSHOT/maven-artifact-3.0-SNAPSHOT.pom.md5
new file mode 100644
index 00000000..11e35363
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/artifact/maven-artifact/3.0-SNAPSHOT/maven-artifact-3.0-SNAPSHOT.pom.md5
@@ -0,0 +1 @@
+794377b5385c68c660ee9ca26e6b5cf1 \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/artifact/maven-artifact/3.0-SNAPSHOT/maven-artifact-3.0-SNAPSHOT.pom.sha1 b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/artifact/maven-artifact/3.0-SNAPSHOT/maven-artifact-3.0-SNAPSHOT.pom.sha1
new file mode 100644
index 00000000..4beb688d
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/artifact/maven-artifact/3.0-SNAPSHOT/maven-artifact-3.0-SNAPSHOT.pom.sha1
@@ -0,0 +1 @@
+358254e73f075bcfb9d587d0da553083abd0cc45 \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/core/test/test-extension/1/test-extension-1.jar b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/core/test/test-extension/1/test-extension-1.jar
new file mode 100644
index 00000000..0272ee3c
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/core/test/test-extension/1/test-extension-1.jar
Binary files differ
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/core/test/test-extension/1/test-extension-1.pom b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/core/test/test-extension/1/test-extension-1.pom
new file mode 100644
index 00000000..70114e72
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/core/test/test-extension/1/test-extension-1.pom
@@ -0,0 +1,73 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven.core.test</groupId>
+ <artifactId>test-extension</artifactId>
+ <packaging>jar</packaging>
+ <version>1</version>
+ <name>test-extension</name>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven.artifact</groupId>
+ <artifactId>maven-artifact</artifactId>
+ <version>3.0-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-utils</artifactId>
+ <version>1.1</version>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus</artifactId>
+ <version>1.0.11</version>
+ <type>pom</type>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-component-api</artifactId>
+ <version>1.0-alpha-16</version>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-container-default</artifactId>
+ <version>1.0-alpha-16</version>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <version>2.2-beta-2-SNAPSHOT</version>
+ <executions>
+ <execution>
+ <id>repo-assembly</id>
+ <phase>package</phase>
+ <goals>
+ <goal>single</goal>
+ </goals>
+ <configuration>
+ <descriptors>
+ <descriptor>repo.xml</descriptor>
+ </descriptors>
+ <finalName>test-extension</finalName>
+ <appendAssemblyId>true</appendAssemblyId>
+ <outputDirectory>${pom.basedir}/../../resources/org/apache/maven/extension</outputDirectory>
+ <ignoreDirFormatExtensions>true</ignoreDirFormatExtensions>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+ <distributionManagement>
+ <repository>
+ <id>dummy</id>
+ <url>file:///tmp/dummy-repo</url>
+ </repository>
+ </distributionManagement>
+
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/core/test/test-extension/1/test-extension-1.pom.md5 b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/core/test/test-extension/1/test-extension-1.pom.md5
new file mode 100644
index 00000000..ad06718c
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/core/test/test-extension/1/test-extension-1.pom.md5
@@ -0,0 +1 @@
+e8f6e0f4ef9c2ed3fb185ef44165fb40 \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/core/test/test-extension/1/test-extension-1.pom.sha1 b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/core/test/test-extension/1/test-extension-1.pom.sha1
new file mode 100644
index 00000000..6065ee04
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/core/test/test-extension/1/test-extension-1.pom.sha1
@@ -0,0 +1 @@
+88ace5d78ee32fa0ce59714a4a42a73af3b52bd3 \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/core/test/test-lifecycle-and-artifactHandler/1/test-lifecycle-and-artifactHandler-1.jar b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/core/test/test-lifecycle-and-artifactHandler/1/test-lifecycle-and-artifactHandler-1.jar
new file mode 100644
index 00000000..04fe3846
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/core/test/test-lifecycle-and-artifactHandler/1/test-lifecycle-and-artifactHandler-1.jar
Binary files differ
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/core/test/test-lifecycle-and-artifactHandler/1/test-lifecycle-and-artifactHandler-1.pom b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/core/test/test-lifecycle-and-artifactHandler/1/test-lifecycle-and-artifactHandler-1.pom
new file mode 100644
index 00000000..d9e4cde9
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/core/test/test-lifecycle-and-artifactHandler/1/test-lifecycle-and-artifactHandler-1.pom
@@ -0,0 +1,44 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven.core.test</groupId>
+ <artifactId>test-lifecycle-and-artifactHandler</artifactId>
+ <packaging>jar</packaging>
+ <version>1</version>
+ <name>test-lifecycle-and-artifactHandler</name>
+
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <version>2.2-beta-2-SNAPSHOT</version>
+ <executions>
+ <execution>
+ <id>repo-assembly</id>
+ <phase>package</phase>
+ <goals>
+ <goal>single</goal>
+ </goals>
+ <configuration>
+ <descriptors>
+ <descriptor>repo.xml</descriptor>
+ </descriptors>
+ <finalName>test-extension</finalName>
+ <appendAssemblyId>true</appendAssemblyId>
+ <outputDirectory>${pom.basedir}/../../resources/org/apache/maven/extension</outputDirectory>
+ <ignoreDirFormatExtensions>true</ignoreDirFormatExtensions>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+ <distributionManagement>
+ <repository>
+ <id>dummy</id>
+ <url>file:///tmp/dummy-repo</url>
+ </repository>
+ </distributionManagement>
+
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/core/test/test-lifecycle-and-artifactHandler/1/test-lifecycle-and-artifactHandler-1.pom.md5 b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/core/test/test-lifecycle-and-artifactHandler/1/test-lifecycle-and-artifactHandler-1.pom.md5
new file mode 100644
index 00000000..01d51942
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/core/test/test-lifecycle-and-artifactHandler/1/test-lifecycle-and-artifactHandler-1.pom.md5
@@ -0,0 +1 @@
+7f10427af029d20cbea57c21d1aec65e \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/core/test/test-lifecycle-and-artifactHandler/1/test-lifecycle-and-artifactHandler-1.pom.sha1 b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/core/test/test-lifecycle-and-artifactHandler/1/test-lifecycle-and-artifactHandler-1.pom.sha1
new file mode 100644
index 00000000..dac1e45a
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/core/test/test-lifecycle-and-artifactHandler/1/test-lifecycle-and-artifactHandler-1.pom.sha1
@@ -0,0 +1 @@
+ed98c808239aefb0ec51a8b9e96f191da7fd92e6 \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/maven-parent/4/maven-parent-4.pom b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/maven-parent/4/maven-parent-4.pom
new file mode 100644
index 00000000..132d9d73
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/maven-parent/4/maven-parent-4.pom
@@ -0,0 +1,304 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ ~ Copyright 2005-2006 The Apache Software Foundation.
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache</groupId>
+ <artifactId>apache</artifactId>
+ <version>3</version>
+ <relativePath>../asf/pom.xml</relativePath>
+ </parent>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-parent</artifactId>
+ <version>4</version>
+ <packaging>pom</packaging>
+ <name>Apache Maven</name>
+ <description>
+ Maven is a software project management and comprehension tool. Based on the concept of a project object model
+ (POM), Maven can manage a project's build, reporting and documentation from a central piece of information.
+ </description>
+ <url>http://maven.apache.org/</url>
+ <issueManagement>
+ <system>jira</system>
+ <url>http://jira.codehaus.org/browse/MPA</url>
+ </issueManagement>
+ <ciManagement>
+ <system>continuum</system>
+ <url>http://maven.zones.apache.org:8080/continuum</url>
+ <notifiers>
+ <notifier>
+ <type>mail</type>
+ <configuration>
+ <address>notifications@maven.apache.org</address>
+ </configuration>
+ </notifier>
+ </notifiers>
+ </ciManagement>
+ <inceptionYear>2002</inceptionYear>
+ <mailingLists>
+ <mailingList>
+ <name>Maven Announcements List</name>
+ <post>announce@maven.apache.org</post>
+ <subscribe>announce-subscribe@maven.apache.org</subscribe>
+ <unsubscribe>announce-unsubscribe@maven.apache.org</unsubscribe>
+ <archive>http://mail-archives.apache.org/mod_mbox/maven-announce/</archive>
+ </mailingList>
+ <mailingList>
+ <name>Maven Issues List</name>
+ <post>issues@maven.apache.org</post>
+ <subscribe>issues-subscribe@maven.apache.org</subscribe>
+ <unsubscribe>issues-unsubscribe@maven.apache.org</unsubscribe>
+ <archive>http://mail-archives.apache.org/mod_mbox/maven-issues/</archive>
+ </mailingList>
+ <mailingList>
+ <name>Maven Notifications List</name>
+ <post>notifications@maven.apache.org</post>
+ <subscribe>notifications-subscribe@maven.apache.org</subscribe>
+ <unsubscribe>notifications-unsubscribe@maven.apache.org</unsubscribe>
+ <archive>http://mail-archives.apache.org/mod_mbox/maven-notifications/</archive>
+ </mailingList>
+ </mailingLists>
+
+ <developers>
+ <developer>
+ <id>jvanzyl</id>
+ <name>Jason van Zyl</name>
+ <email>jason@maven.org</email>
+ <organization>ASF</organization>
+ <roles>
+ <role>PMC Chair</role>
+ </roles>
+ <timezone>-5</timezone>
+ </developer>
+ <developer>
+ <id>brett</id>
+ <name>Brett Porter</name>
+ <email>brett@apache.org</email>
+ <organization>ASF</organization>
+ <roles>
+ <role>PMC Member</role>
+ </roles>
+ <timezone>+10</timezone>
+ </developer>
+ <developer>
+ <id>evenisse</id>
+ <name>Emmanuel Venisse</name>
+ <email>evenisse@apache.org</email>
+ <organization>ASF</organization>
+ <roles>
+ <role>PMC Member</role>
+ </roles>
+ <timezone>+1</timezone>
+ </developer>
+ <developer>
+ <id>kenney</id>
+ <name>Kenney Westerhof</name>
+ <email>kenney@apache.org</email>
+ <organization>Neonics</organization>
+ <roles>
+ <role>PMC Member</role>
+ </roles>
+ </developer>
+ <developer>
+ <id>snicoll</id>
+ <name>Stephane Nicoll</name>
+ <email>snicoll@apache.org</email>
+ <organization>ASF</organization>
+ <roles>
+ <role>PMC Member</role>
+ </roles>
+ <timezone>+1</timezone>
+ </developer>
+ <developer>
+ <id>vmassol</id>
+ <name>Vincent Massol</name>
+ <email>vmassol@apache.org</email>
+ <organization>ASF</organization>
+ <roles>
+ <role>PMC Member</role>
+ </roles>
+ <timezone>+1</timezone>
+ </developer>
+ <developer>
+ <id>fgiust</id>
+ <name>Fabrizio Giustina</name>
+ <email>fgiust@apache.org</email>
+ <organization>openmind</organization>
+ <roles>
+ <role>PMC Member</role>
+ </roles>
+ <timezone>+1</timezone>
+ </developer>
+ <developer>
+ <id>epunzalan</id>
+ <name>Edwin Punzalan</name>
+ <email>epunzalan@mergere.com</email>
+ <organization>Mergere</organization>
+ <roles>
+ <role>Committer</role>
+ </roles>
+ <timezone>+8</timezone>
+ </developer>
+ <developer>
+ <id>mperham</id>
+ <name>Mike Perham</name>
+ <email>mperham@gmail.com</email>
+ <organization>IBM</organization>
+ <roles>
+ <role>PMC Member</role>
+ </roles>
+ <timezone>-6</timezone>
+ </developer>
+ <developer>
+ <id>jdcasey</id>
+ <name>John Casey</name>
+ <email>jdcasey@apache.org</email>
+ <organization>ASF</organization>
+ <roles>
+ <role>PMC Member</role>
+ </roles>
+ <timezone>-5</timezone>
+ </developer>
+ <developer>
+ <id>trygvis</id>
+ <name>Trygve Laugstol</name>
+ <email>trygvis@apache.org</email>
+ <organization>ASF</organization>
+ <roles>
+ <role>PMC Member</role>
+ </roles>
+ <timezone>+1</timezone>
+ </developer>
+ <developer>
+ <id>vsiveton</id>
+ <name>Vincent Siveton</name>
+ <email>vsiveton@apache.org</email>
+ <organization>ASF</organization>
+ <roles>
+ <role>PMC Member</role>
+ </roles>
+ <timezone>-5</timezone>
+ </developer>
+ <developer>
+ <id>carlos</id>
+ <name>Carlos Sanchez</name>
+ <email>carlos@apache.org</email>
+ <organization>ASF</organization>
+ <roles>
+ <role>PMC Member</role>
+ </roles>
+ <timezone>+1</timezone>
+ </developer>
+ <developer>
+ <id>dennisl</id>
+ <name>Dennis Lundberg</name>
+ <email>dennisl@apache.org</email>
+ <organization>ASF</organization>
+ <roles>
+ <role>PMC Member</role>
+ </roles>
+ <timezone>+1</timezone>
+ </developer>
+ </developers>
+
+ <distributionManagement>
+ <site>
+ <id>apache.website</id>
+ <url>scp://people.apache.org/www/maven.apache.org</url>
+ </site>
+ </distributionManagement>
+
+<!-- Disabled until projects have been made to comply
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-pmd-plugin</artifactId>
+ <executions>
+ <execution>
+ <goals>
+ <goal>cpd-check</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+-->
+
+ <reporting>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-report-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-checkstyle-plugin</artifactId>
+ <configuration>
+ <configLocation>http://svn.apache.org/repos/asf/maven/plugins/trunk/maven-checkstyle-plugin/src/main/resources/config/maven_checks.xml</configLocation>
+ <headerLocation>http://svn.apache.org/repos/asf/maven/plugins/trunk/maven-checkstyle-plugin/src/main/resources/config/maven-header.txt</headerLocation>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-pmd-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>cobertura-maven-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>taglist-maven-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jxr-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ <configuration>
+ <links>
+ <link>http://java.sun.com/j2ee/1.4/docs/api</link>
+ <link>http://java.sun.com/j2se/1.5.0/docs/api</link>
+ <link>http://jakarta.apache.org/commons/collections/apidocs-COLLECTIONS_3_0/</link>
+ <link>http://jakarta.apache.org/commons/dbcp/apidocs/</link>
+ <link>http://jakarta.apache.org/commons/fileupload/apidocs/</link>
+ <link>http://jakarta.apache.org/commons/httpclient/apidocs/</link>
+ <link>http://jakarta.apache.org/commons/logging/apidocs/</link>
+ <link>http://jakarta.apache.org/commons/pool/apidocs/</link>
+ <link>http://www.junit.org/junit/javadoc/</link>
+ <link>http://logging.apache.org/log4j/docs/api/</link>
+ <link>http://jakarta.apache.org/regexp/apidocs/</link>
+ <link>http://jakarta.apache.org/velocity/api/</link>
+ </links>
+ </configuration>
+ </plugin>
+ </plugins>
+ </reporting>
+
+ <scm>
+ <connection>scm:svn:http://svn.apache.org/repos/asf/maven/pom/maven/tags/maven-parent-4</connection>
+ <developerConnection>scm:svn:https://svn.apache.org/repos/asf/maven/pom/maven/tags/maven-parent-4</developerConnection>
+ <url>http://svn.apache.org/viewvc/maven/pom/maven/tags/maven-parent-4</url>
+ </scm>
+</project>
+
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/maven-parent/4/maven-parent-4.pom.md5 b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/maven-parent/4/maven-parent-4.pom.md5
new file mode 100644
index 00000000..9c417645
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/maven-parent/4/maven-parent-4.pom.md5
@@ -0,0 +1 @@
+2a4e926f3a76c6e74b0b126f513ad4e7 \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/maven-parent/4/maven-parent-4.pom.sha1 b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/maven-parent/4/maven-parent-4.pom.sha1
new file mode 100644
index 00000000..b6caacf5
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/maven-parent/4/maven-parent-4.pom.sha1
@@ -0,0 +1 @@
+0fc039b0bd4d17d7c147a30e1d83994629c5297c \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/maven-parent/5/maven-parent-5.pom b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/maven-parent/5/maven-parent-5.pom
new file mode 100644
index 00000000..b3350401
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/maven-parent/5/maven-parent-5.pom
@@ -0,0 +1,466 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache</groupId>
+ <artifactId>apache</artifactId>
+ <version>3</version>
+ <relativePath>../asf/pom.xml</relativePath>
+ </parent>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-parent</artifactId>
+ <version>5</version>
+ <packaging>pom</packaging>
+ <name>Apache Maven</name>
+ <description>
+ Maven is a software project management and comprehension tool. Based on the concept of a project object model
+ (POM), Maven can manage a project's build, reporting and documentation from a central piece of information.
+ </description>
+ <url>http://maven.apache.org/</url>
+ <issueManagement>
+ <system>jira</system>
+ <url>http://jira.codehaus.org/browse/MPA</url>
+ </issueManagement>
+ <ciManagement>
+ <system>continuum</system>
+ <url>http://maven.zones.apache.org/continuum</url>
+ <notifiers>
+ <notifier>
+ <type>mail</type>
+ <configuration>
+ <address>notifications@maven.apache.org</address>
+ </configuration>
+ </notifier>
+ </notifiers>
+ </ciManagement>
+ <inceptionYear>2002</inceptionYear>
+ <mailingLists>
+ <mailingList>
+ <name>Maven Announcements List</name>
+ <post>announce@maven.apache.org</post>
+ <subscribe>announce-subscribe@maven.apache.org</subscribe>
+ <unsubscribe>announce-unsubscribe@maven.apache.org</unsubscribe>
+ <archive>http://mail-archives.apache.org/mod_mbox/maven-announce/</archive>
+ </mailingList>
+ <mailingList>
+ <name>Maven Issues List</name>
+ <post>issues@maven.apache.org</post>
+ <subscribe>issues-subscribe@maven.apache.org</subscribe>
+ <unsubscribe>issues-unsubscribe@maven.apache.org</unsubscribe>
+ <archive>http://mail-archives.apache.org/mod_mbox/maven-issues/</archive>
+ </mailingList>
+ <mailingList>
+ <name>Maven Notifications List</name>
+ <post>notifications@maven.apache.org</post>
+ <subscribe>notifications-subscribe@maven.apache.org</subscribe>
+ <unsubscribe>notifications-unsubscribe@maven.apache.org</unsubscribe>
+ <archive>http://mail-archives.apache.org/mod_mbox/maven-notifications/</archive>
+ </mailingList>
+ </mailingLists>
+
+ <developers>
+ <developer>
+ <id>jvanzyl</id>
+ <name>Jason van Zyl</name>
+ <email>jason@maven.org</email>
+ <organization>ASF</organization>
+ <roles>
+ <role>PMC Chair</role>
+ </roles>
+ <timezone>-5</timezone>
+ </developer>
+ <developer>
+ <id>brett</id>
+ <name>Brett Porter</name>
+ <email>brett@apache.org</email>
+ <organization>ASF</organization>
+ <roles>
+ <role>PMC Member</role>
+ </roles>
+ <timezone>+10</timezone>
+ </developer>
+ <developer>
+ <id>evenisse</id>
+ <name>Emmanuel Venisse</name>
+ <email>evenisse@apache.org</email>
+ <organization>ASF</organization>
+ <roles>
+ <role>PMC Member</role>
+ </roles>
+ <timezone>+1</timezone>
+ </developer>
+ <developer>
+ <id>kenney</id>
+ <name>Kenney Westerhof</name>
+ <email>kenney@apache.org</email>
+ <organization>Neonics</organization>
+ <roles>
+ <role>PMC Member</role>
+ </roles>
+ <timezone>+1</timezone>
+ </developer>
+ <developer>
+ <id>snicoll</id>
+ <name>Stephane Nicoll</name>
+ <email>snicoll@apache.org</email>
+ <organization>ASF</organization>
+ <roles>
+ <role>PMC Member</role>
+ </roles>
+ <timezone>+1</timezone>
+ </developer>
+ <developer>
+ <id>vmassol</id>
+ <name>Vincent Massol</name>
+ <email>vmassol@apache.org</email>
+ <organization>ASF</organization>
+ <roles>
+ <role>PMC Member</role>
+ </roles>
+ <timezone>+1</timezone>
+ </developer>
+ <developer>
+ <id>fgiust</id>
+ <name>Fabrizio Giustina</name>
+ <email>fgiust@apache.org</email>
+ <organization>openmind</organization>
+ <roles>
+ <role>PMC Member</role>
+ </roles>
+ <timezone>+1</timezone>
+ </developer>
+ <developer>
+ <id>epunzalan</id>
+ <name>Edwin Punzalan</name>
+ <email>epunzalan@mergere.com</email>
+ <organization>Mergere</organization>
+ <roles>
+ <role>Committer</role>
+ </roles>
+ <timezone>+8</timezone>
+ </developer>
+ <developer>
+ <id>mperham</id>
+ <name>Mike Perham</name>
+ <email>mperham@gmail.com</email>
+ <organization>IBM</organization>
+ <roles>
+ <role>PMC Member</role>
+ </roles>
+ <timezone>-6</timezone>
+ </developer>
+ <developer>
+ <id>jdcasey</id>
+ <name>John Casey</name>
+ <email>jdcasey@apache.org</email>
+ <organization>ASF</organization>
+ <roles>
+ <role>PMC Member</role>
+ </roles>
+ <timezone>-5</timezone>
+ </developer>
+ <developer>
+ <id>trygvis</id>
+ <name>Trygve Laugstol</name>
+ <email>trygvis@apache.org</email>
+ <organization>ASF</organization>
+ <roles>
+ <role>PMC Member</role>
+ </roles>
+ <timezone>+1</timezone>
+ </developer>
+ <developer>
+ <id>vsiveton</id>
+ <name>Vincent Siveton</name>
+ <email>vsiveton@apache.org</email>
+ <organization>ASF</organization>
+ <roles>
+ <role>PMC Member</role>
+ </roles>
+ <timezone>-5</timezone>
+ </developer>
+ <developer>
+ <id>carlos</id>
+ <name>Carlos Sanchez</name>
+ <email>carlos@apache.org</email>
+ <organization>ASF</organization>
+ <roles>
+ <role>PMC Member</role>
+ </roles>
+ <timezone>+1</timezone>
+ </developer>
+ <developer>
+ <id>dennisl</id>
+ <name>Dennis Lundberg</name>
+ <email>dennisl@apache.org</email>
+ <organization>ASF</organization>
+ <roles>
+ <role>PMC Member</role>
+ </roles>
+ <timezone>+1</timezone>
+ </developer>
+ <developer>
+ <id>aheritier</id>
+ <name>Arnaud Heritier</name>
+ <email>aheritier@apache.org</email>
+ <organization>ASF</organization>
+ <roles>
+ <role>PMC Member</role>
+ </roles>
+ <timezone>+1</timezone>
+ </developer>
+ <developer>
+ <id>handyande</id>
+ <name>Andrew Williams</name>
+ <email>handyande@apache.org</email>
+ <roles>
+ <role>Committer</role>
+ </roles>
+ <timezone>0</timezone>
+ </developer>
+ <developer>
+ <id>jtolentino</id>
+ <name>Ernesto Tolentino Jr.</name>
+ <email>jtolentino@apache.org</email>
+ <organization>ASF</organization>
+ <roles>
+ <role>PMC Member</role>
+ </roles>
+ <timezone>+8</timezone>
+ </developer>
+ <developer>
+ <id>joakime</id>
+ <name>Joakim Erdfelt</name>
+ <email>joakime@apache.org</email>
+ <organization>ASF</organization>
+ <roles>
+ <role>PMC Member</role>
+ </roles>
+ <timezone>-5</timezone>
+ </developer>
+ <developer>
+ <id>jmcconnell</id>
+ <name>Jesse McConnell</name>
+ <email>jmcconnell@apache.org</email>
+ <organization>ASF</organization>
+ <roles>
+ <role>PMC Member</role>
+ </roles>
+ <timezone>-6</timezone>
+ </developer>
+ <developer>
+ <id>wsmoak</id>
+ <name>Wendy Smoak</name>
+ <email>wsmoak@apache.org</email>
+ <roles>
+ <role>Committer</role>
+ </roles>
+ <timezone>-7</timezone>
+ </developer>
+
+ </developers>
+
+ <distributionManagement>
+ <site>
+ <id>apache.website</id>
+ <url>scp://people.apache.org/www/maven.apache.org</url>
+ </site>
+ </distributionManagement>
+
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-release-plugin</artifactId>
+ <version>2.0-beta-4</version>
+ <configuration>
+ <!-- This element will be overriden by children -->
+ <tagBase>https://svn.apache.org/repos/asf/maven/pom/tags</tagBase>
+ <useReleaseProfile>false</useReleaseProfile>
+ <goals>deploy</goals>
+ <arguments>-Prelease</arguments>
+ </configuration>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+
+ <profiles>
+ <profile>
+ <id>ci</id>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-pmd-plugin</artifactId>
+ <executions>
+ <execution>
+ <goals>
+ <goal>cpd-check</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ <profile>
+ <id>reporting</id>
+ <reporting>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-report-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-checkstyle-plugin</artifactId>
+ <configuration>
+ <configLocation>http://svn.apache.org/repos/asf/maven/plugins/trunk/maven-checkstyle-plugin/src/main/resources/config/maven_checks.xml</configLocation>
+ <headerLocation>http://svn.apache.org/repos/asf/maven/plugins/trunk/maven-checkstyle-plugin/src/main/resources/config/maven-header.txt</headerLocation>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-pmd-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>cobertura-maven-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>taglist-maven-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jxr-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ <configuration>
+ <links>
+ <link>http://java.sun.com/j2ee/1.4/docs/api</link>
+ <link>http://java.sun.com/j2se/1.5.0/docs/api</link>
+ <link>http://jakarta.apache.org/commons/collections/apidocs-COLLECTIONS_3_0/</link>
+ <link>http://jakarta.apache.org/commons/dbcp/apidocs/</link>
+ <link>http://jakarta.apache.org/commons/fileupload/apidocs/</link>
+ <link>http://jakarta.apache.org/commons/httpclient/apidocs/</link>
+ <link>http://jakarta.apache.org/commons/logging/apidocs/</link>
+ <link>http://jakarta.apache.org/commons/pool/apidocs/</link>
+ <link>http://www.junit.org/junit/javadoc/</link>
+ <link>http://logging.apache.org/log4j/docs/api/</link>
+ <link>http://jakarta.apache.org/regexp/apidocs/</link>
+ <link>http://jakarta.apache.org/velocity/api/</link>
+ </links>
+ </configuration>
+ </plugin>
+ </plugins>
+ </reporting>
+ </profile>
+ <profile>
+ <id>release</id>
+ <build>
+ <plugins>
+ <!-- We want to sign the artifact, the POM, and all attached artifacts -->
+ <plugin>
+ <artifactId>maven-gpg-plugin</artifactId>
+ <version>1.0-alpha-1</version>
+ <configuration>
+ <passphrase>${gpg.passphrase}</passphrase>
+ </configuration>
+ <executions>
+ <execution>
+ <goals>
+ <goal>sign</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <!-- We want to deploy the artifact to a staging location for perusal -->
+ <plugin>
+ <inherited>true</inherited>
+ <artifactId>maven-deploy-plugin</artifactId>
+ <version>2.3</version>
+ <configuration>
+ <altDeploymentRepository>${deploy.altRepository}</altDeploymentRepository>
+ <updateReleaseInfo>true</updateReleaseInfo>
+ </configuration>
+ </plugin>
+ <!-- We want to package up license resources in the JARs produced -->
+ <plugin>
+ <artifactId>maven-remote-resources-plugin</artifactId>
+ <version>1.0-alpha-1</version>
+ <executions>
+ <execution>
+ <goals>
+ <goal>process</goal>
+ </goals>
+ <configuration>
+ <resourceBundles>
+ <resourceBundle>org.apache:apache-jar-resource-bundle:1.0</resourceBundle>
+ </resourceBundles>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-source-plugin</artifactId>
+ <version>2.0.2</version>
+ <executions>
+ <execution>
+ <id>attach-sources</id>
+ <goals>
+ <goal>jar</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ <version>2.2</version>
+ <executions>
+ <execution>
+ <id>attach-javadocs</id>
+ <goals>
+ <goal>jar</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
+
+ <scm>
+ <connection>scm:svn:https://svn.apache.org/repos/asf/maven/pom/tags/maven-parent-5</connection>
+ <developerConnection>scm:svn:https://svn.apache.org/repos/asf/maven/pom/tags/maven-parent-5</developerConnection>
+ <url>https://svn.apache.org/repos/asf/maven/pom/tags/maven-parent-5</url>
+ </scm>
+</project>
+
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/maven-parent/5/maven-parent-5.pom.md5 b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/maven-parent/5/maven-parent-5.pom.md5
new file mode 100644
index 00000000..27ba3aaf
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/maven-parent/5/maven-parent-5.pom.md5
@@ -0,0 +1 @@
+4da85635ce64dbec5b00232d5bb26453 \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/maven-parent/5/maven-parent-5.pom.sha1 b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/maven-parent/5/maven-parent-5.pom.sha1
new file mode 100644
index 00000000..5d7a3eba
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/maven-parent/5/maven-parent-5.pom.sha1
@@ -0,0 +1 @@
+5c1ab38decaca1ccd08294aeab135047ebbae00d \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/wagon/wagon-provider-api/1.0-beta-2/wagon-provider-api-1.0-beta-2.jar b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/wagon/wagon-provider-api/1.0-beta-2/wagon-provider-api-1.0-beta-2.jar
new file mode 100644
index 00000000..79fcf226
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/wagon/wagon-provider-api/1.0-beta-2/wagon-provider-api-1.0-beta-2.jar
Binary files differ
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/wagon/wagon-provider-api/1.0-beta-2/wagon-provider-api-1.0-beta-2.jar.md5 b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/wagon/wagon-provider-api/1.0-beta-2/wagon-provider-api-1.0-beta-2.jar.md5
new file mode 100644
index 00000000..60aecbcd
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/wagon/wagon-provider-api/1.0-beta-2/wagon-provider-api-1.0-beta-2.jar.md5
@@ -0,0 +1 @@
+f41eb4e07a725eea3332743a29057855 \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/wagon/wagon-provider-api/1.0-beta-2/wagon-provider-api-1.0-beta-2.jar.sha1 b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/wagon/wagon-provider-api/1.0-beta-2/wagon-provider-api-1.0-beta-2.jar.sha1
new file mode 100644
index 00000000..e3f05109
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/wagon/wagon-provider-api/1.0-beta-2/wagon-provider-api-1.0-beta-2.jar.sha1
@@ -0,0 +1 @@
+abd1c9ace6e87c94a4b91f5176aeb09d954b23a3 \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/wagon/wagon-provider-api/1.0-beta-2/wagon-provider-api-1.0-beta-2.pom b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/wagon/wagon-provider-api/1.0-beta-2/wagon-provider-api-1.0-beta-2.pom
new file mode 100644
index 00000000..dca027b2
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/wagon/wagon-provider-api/1.0-beta-2/wagon-provider-api-1.0-beta-2.pom
@@ -0,0 +1,21 @@
+<?xml version="1.0"?><project>
+ <parent>
+ <artifactId>wagon</artifactId>
+ <groupId>org.apache.maven.wagon</groupId>
+ <version>1.0-beta-2</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>wagon-provider-api</artifactId>
+ <name>Maven Wagon API</name>
+ <version>1.0-beta-2</version>
+ <description>Maven Wagon API that defines the contract between different Wagon implementations</description>
+ <dependencies>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-utils</artifactId>
+ </dependency>
+ </dependencies>
+ <distributionManagement>
+ <status>deployed</status>
+ </distributionManagement>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/wagon/wagon-provider-api/1.0-beta-2/wagon-provider-api-1.0-beta-2.pom.md5 b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/wagon/wagon-provider-api/1.0-beta-2/wagon-provider-api-1.0-beta-2.pom.md5
new file mode 100644
index 00000000..0f10b3fd
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/wagon/wagon-provider-api/1.0-beta-2/wagon-provider-api-1.0-beta-2.pom.md5
@@ -0,0 +1 @@
+97f0a0bd0b81520ccccf8736b1fe380c \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/wagon/wagon-provider-api/1.0-beta-2/wagon-provider-api-1.0-beta-2.pom.sha1 b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/wagon/wagon-provider-api/1.0-beta-2/wagon-provider-api-1.0-beta-2.pom.sha1
new file mode 100644
index 00000000..56b9559d
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/wagon/wagon-provider-api/1.0-beta-2/wagon-provider-api-1.0-beta-2.pom.sha1
@@ -0,0 +1 @@
+8b3013d0754edbeb694831ddf1c5d1a0019ee042 \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/wagon/wagon/1.0-beta-2/wagon-1.0-beta-2.pom b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/wagon/wagon/1.0-beta-2/wagon-1.0-beta-2.pom
new file mode 100644
index 00000000..27faa8ef
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/wagon/wagon/1.0-beta-2/wagon-1.0-beta-2.pom
@@ -0,0 +1,170 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>maven-parent</artifactId>
+ <groupId>org.apache.maven</groupId>
+ <version>4</version>
+ <relativePath>../pom/maven/pom.xml</relativePath>
+ </parent>
+ <groupId>org.apache.maven.wagon</groupId>
+ <artifactId>wagon</artifactId>
+ <packaging>pom</packaging>
+ <name>Maven Wagon</name>
+ <version>1.0-beta-2</version>
+ <description>Tools to manage artifacts and deployment</description>
+ <url>http://maven.apache.org/wagon</url>
+
+ <issueManagement>
+ <system>jira</system>
+ <url>http://jira.codehaus.org/browse/WAGON</url>
+ </issueManagement>
+ <inceptionYear>2003</inceptionYear>
+ <mailingLists>
+ <mailingList>
+ <name>Maven Wagon User List</name>
+ <subscribe>wagon-users-subscribe@maven.apache.org</subscribe>
+ <unsubscribe>wagon-users-unsubscribe@maven.apache.org</unsubscribe>
+ <archive>http://mail-archives.apache.org/mod_mbox/maven-wagon-users/</archive>
+ </mailingList>
+ <mailingList>
+ <name>Maven Wagon Developer List</name>
+ <subscribe>wagon-dev-subscribe@maven.apache.org</subscribe>
+ <unsubscribe>wagon-dev-unsubscribe@maven.apache.org</unsubscribe>
+ <archive>http://mail-archives.apache.org/mod_mbox/maven-wagon-dev/</archive>
+ </mailingList>
+ <mailingList>
+ <name>Maven Commits List</name>
+ <subscribe>wagon-commits-subscribe@maven.apache.org</subscribe>
+ <unsubscribe>wagon-commits-unsubscribe@maven.apache.org</unsubscribe>
+ <archive>http://mail-archives.apache.org/mod_mbox/maven-wagon-commits/</archive>
+ </mailingList>
+ </mailingLists>
+ <developers>
+ <developer>
+ <id>michal</id>
+ <name>Michal Maczka</name>
+ <email>michal@codehaus.org</email>
+ <organization>Codehaus</organization>
+ <roles>
+ <role>Developer</role>
+ </roles>
+ </developer>
+ </developers>
+ <scm>
+ <connection>scm:svn:https://svn.apache.org/repos/asf/maven/wagon/tags/wagon-1.0-beta-2</connection>
+ <developerConnection>scm:svn:https://svn.apache.org/repos/asf/maven/wagon/tags/wagon-1.0-beta-2</developerConnection>
+ <url>https://svn.apache.org/repos/asf/maven/wagon/tags/wagon-1.0-beta-2</url>
+ </scm>
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <artifactId>maven-release-plugin</artifactId>
+ <configuration>
+ <tagBase>https://svn.apache.org/repos/asf/maven/wagon/tags</tagBase>
+ </configuration>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+ <modules>
+ <module>wagon-provider-api</module>
+ <module>wagon-provider-test</module>
+ <module>wagon-providers</module>
+ </modules>
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven.wagon</groupId>
+ <artifactId>wagon-provider-api</artifactId>
+ <version>1.0-beta-2</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.wagon</groupId>
+ <artifactId>wagon-provider-test</artifactId>
+ <version>1.0-beta-2</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.wagon</groupId>
+ <artifactId>wagon-ssh-common-test</artifactId>
+ <version>1.0-beta-2</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.wagon</groupId>
+ <artifactId>wagon-ssh-common</artifactId>
+ <version>1.0-beta-2</version>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>3.8.1</version>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-interactivity-api</artifactId>
+ <version>1.0-alpha-4</version>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-container-default</artifactId>
+ <version>1.0-alpha-8</version>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-utils</artifactId>
+ <version>1.0.4</version>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+ <!-- TODO: point to ref location
+ <distributionManagement>
+ <site>
+ <id>apache.website</id>
+ <url>scp://people.apache.org/www/maven.apache.org/wagon/</url>
+ </site>
+ </distributionManagement>
+ -->
+ <profiles>
+ <profile>
+ <id>sharedResources</id>
+ <pluginRepositories>
+ <pluginRepository>
+ <id>people.apache.org</id>
+ <url>http://people.apache.org/repo/m2-snapshot-repository</url>
+ <snapshots>
+ <enabled>true</enabled>
+ </snapshots>
+ </pluginRepository>
+ </pluginRepositories>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-remote-resources-plugin</artifactId>
+ <version>1.0-alpha-1</version>
+ <executions>
+ <execution>
+ <goals>
+ <goal>process</goal>
+ </goals>
+ <configuration>
+ <resourceBundles>
+ <resourceBundle>org.apache:apache-jar-resource-bundle:1.0</resourceBundle>
+ </resourceBundles>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/wagon/wagon/1.0-beta-2/wagon-1.0-beta-2.pom.md5 b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/wagon/wagon/1.0-beta-2/wagon-1.0-beta-2.pom.md5
new file mode 100644
index 00000000..45e066d7
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/wagon/wagon/1.0-beta-2/wagon-1.0-beta-2.pom.md5
@@ -0,0 +1 @@
+e739bffedc84a18c6e10a0958e2006ad \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/wagon/wagon/1.0-beta-2/wagon-1.0-beta-2.pom.sha1 b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/wagon/wagon/1.0-beta-2/wagon-1.0-beta-2.pom.sha1
new file mode 100644
index 00000000..5f82f766
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/apache/maven/wagon/wagon/1.0-beta-2/wagon-1.0-beta-2.pom.sha1
@@ -0,0 +1 @@
+6cf8a47018be792d2b1774d2bacd7541c888ae50 \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-active-collections/1.0-beta-1/plexus-active-collections-1.0-beta-1.jar b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-active-collections/1.0-beta-1/plexus-active-collections-1.0-beta-1.jar
new file mode 100644
index 00000000..d3232758
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-active-collections/1.0-beta-1/plexus-active-collections-1.0-beta-1.jar
Binary files differ
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-active-collections/1.0-beta-1/plexus-active-collections-1.0-beta-1.jar.md5 b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-active-collections/1.0-beta-1/plexus-active-collections-1.0-beta-1.jar.md5
new file mode 100644
index 00000000..1a9a2b6f
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-active-collections/1.0-beta-1/plexus-active-collections-1.0-beta-1.jar.md5
@@ -0,0 +1 @@
+1078ac2103fe666952a3cbcbff19ec71 \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-active-collections/1.0-beta-1/plexus-active-collections-1.0-beta-1.jar.sha1 b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-active-collections/1.0-beta-1/plexus-active-collections-1.0-beta-1.jar.sha1
new file mode 100644
index 00000000..17dbef2e
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-active-collections/1.0-beta-1/plexus-active-collections-1.0-beta-1.jar.sha1
@@ -0,0 +1 @@
+c76ce4f9f1a3d04ef849c1d067519b77f07e01f3 \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-active-collections/1.0-beta-1/plexus-active-collections-1.0-beta-1.pom b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-active-collections/1.0-beta-1/plexus-active-collections-1.0-beta-1.pom
new file mode 100644
index 00000000..80ac6d90
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-active-collections/1.0-beta-1/plexus-active-collections-1.0-beta-1.pom
@@ -0,0 +1,51 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>plexus-components</artifactId>
+ <groupId>org.codehaus.plexus</groupId>
+ <version>1.1.6</version>
+ </parent>
+
+ <artifactId>plexus-active-collections</artifactId>
+ <version>1.0-beta-1</version>
+ <name>Plexus Container-Backed Active Collections</name>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-component-api</artifactId>
+ <version>1.0-alpha-16</version>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-container-default</artifactId>
+ <version>1.0-alpha-16</version>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>3.8.1</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <excludes>
+ <exclude>**/TestComponent.java</exclude>
+ <exclude>**/TestBadComponent.java</exclude>
+ <exclude>**/*TCK.java</exclude>
+ </excludes>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+ <scm>
+ <connection>scm:svn:https://svn.codehaus.org/plexus/tags/plexus-active-collections-1.0-beta-1</connection>
+ <developerConnection>scm:svn:https://svn.codehaus.org/plexus/tags/plexus-active-collections-1.0-beta-1</developerConnection>
+ </scm>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-active-collections/1.0-beta-1/plexus-active-collections-1.0-beta-1.pom.md5 b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-active-collections/1.0-beta-1/plexus-active-collections-1.0-beta-1.pom.md5
new file mode 100644
index 00000000..14519126
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-active-collections/1.0-beta-1/plexus-active-collections-1.0-beta-1.pom.md5
@@ -0,0 +1 @@
+d844f3e1934a76cefc25342bf02f3bff \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-active-collections/1.0-beta-1/plexus-active-collections-1.0-beta-1.pom.sha1 b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-active-collections/1.0-beta-1/plexus-active-collections-1.0-beta-1.pom.sha1
new file mode 100644
index 00000000..5442cbcd
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-active-collections/1.0-beta-1/plexus-active-collections-1.0-beta-1.pom.sha1
@@ -0,0 +1 @@
+cf6a9d40df4ca79c210b2b8a90ce28fffb202769 \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-classworlds/1.2-alpha-10/plexus-classworlds-1.2-alpha-10.jar b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-classworlds/1.2-alpha-10/plexus-classworlds-1.2-alpha-10.jar
new file mode 100644
index 00000000..e2143250
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-classworlds/1.2-alpha-10/plexus-classworlds-1.2-alpha-10.jar
Binary files differ
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-classworlds/1.2-alpha-10/plexus-classworlds-1.2-alpha-10.jar.md5 b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-classworlds/1.2-alpha-10/plexus-classworlds-1.2-alpha-10.jar.md5
new file mode 100644
index 00000000..c7dfa1ea
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-classworlds/1.2-alpha-10/plexus-classworlds-1.2-alpha-10.jar.md5
@@ -0,0 +1 @@
+f55402879506f435a386f2c002ed5001 \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-classworlds/1.2-alpha-10/plexus-classworlds-1.2-alpha-10.jar.sha1 b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-classworlds/1.2-alpha-10/plexus-classworlds-1.2-alpha-10.jar.sha1
new file mode 100644
index 00000000..a333efb8
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-classworlds/1.2-alpha-10/plexus-classworlds-1.2-alpha-10.jar.sha1
@@ -0,0 +1 @@
+fc41205635dab152bf794785be80a0a70fda686e \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-classworlds/1.2-alpha-10/plexus-classworlds-1.2-alpha-10.pom b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-classworlds/1.2-alpha-10/plexus-classworlds-1.2-alpha-10.pom
new file mode 100644
index 00000000..be71f49f
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-classworlds/1.2-alpha-10/plexus-classworlds-1.2-alpha-10.pom
@@ -0,0 +1,94 @@
+<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ ~
+ ~ Copyright 2001-2006 The Codehaus Foundation.
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <parent>
+ <artifactId>plexus</artifactId>
+ <groupId>org.codehaus.plexus</groupId>
+ <version>1.0.10</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-classworlds</artifactId>
+ <packaging>jar</packaging>
+ <name>Plexus Classworlds</name>
+ <version>1.2-alpha-10</version>
+ <description />
+ <inceptionYear>2002</inceptionYear>
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>3.8.1</version>
+ <type>jar</type>
+ <scope>compile</scope>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <forkMode>once</forkMode>
+ </configuration>
+ </plugin>
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <excludes>
+ <exclude>org/codehaus/plexus/classworlds/event/*</exclude>
+ </excludes>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ <profiles>
+ <profile>
+ <id>debug</id>
+ <dependencies>
+ <dependency>
+ <groupId>aspectj</groupId>
+ <artifactId>aspectjrt</artifactId>
+ <version>1.5.0</version>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>aspectj-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <goals>
+ <goal>compile</goal>
+ </goals>
+ </execution>
+ </executions>
+ <configuration>
+ <complianceLevel>1.4</complianceLevel>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
+ <scm>
+ <connection>scm:svn:http://svn.codehaus.org/plexus/plexus-classworlds/tags/plexus-classworlds-1.2-alpha-10</connection>
+ <developerConnection>scm:svn:https://svn.codehaus.org/plexus/plexus-classworlds/tags/plexus-classworlds-1.2-alpha-10</developerConnection>
+ <url>http://fisheye.codehaus.org/browse/plexus/plexus-classworlds/tags/plexus-classworlds-1.2-alpha-10</url>
+ </scm>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-classworlds/1.2-alpha-10/plexus-classworlds-1.2-alpha-10.pom.md5 b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-classworlds/1.2-alpha-10/plexus-classworlds-1.2-alpha-10.pom.md5
new file mode 100644
index 00000000..47dbce55
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-classworlds/1.2-alpha-10/plexus-classworlds-1.2-alpha-10.pom.md5
@@ -0,0 +1 @@
+1a7177f5992983aeb393089af67e51dc \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-classworlds/1.2-alpha-10/plexus-classworlds-1.2-alpha-10.pom.sha1 b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-classworlds/1.2-alpha-10/plexus-classworlds-1.2-alpha-10.pom.sha1
new file mode 100644
index 00000000..eafd9a79
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-classworlds/1.2-alpha-10/plexus-classworlds-1.2-alpha-10.pom.sha1
@@ -0,0 +1 @@
+11215912b045533ec9aaba9f63ea27acf6da850e \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-classworlds/1.2-alpha-7/plexus-classworlds-1.2-alpha-7.jar b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-classworlds/1.2-alpha-7/plexus-classworlds-1.2-alpha-7.jar
new file mode 100644
index 00000000..a8f6a7d3
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-classworlds/1.2-alpha-7/plexus-classworlds-1.2-alpha-7.jar
Binary files differ
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-classworlds/1.2-alpha-7/plexus-classworlds-1.2-alpha-7.jar.md5 b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-classworlds/1.2-alpha-7/plexus-classworlds-1.2-alpha-7.jar.md5
new file mode 100644
index 00000000..09c3bbad
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-classworlds/1.2-alpha-7/plexus-classworlds-1.2-alpha-7.jar.md5
@@ -0,0 +1 @@
+b00a4521e82cd7cdf502039dd59a1ffb \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-classworlds/1.2-alpha-7/plexus-classworlds-1.2-alpha-7.jar.sha1 b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-classworlds/1.2-alpha-7/plexus-classworlds-1.2-alpha-7.jar.sha1
new file mode 100644
index 00000000..9a43138c
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-classworlds/1.2-alpha-7/plexus-classworlds-1.2-alpha-7.jar.sha1
@@ -0,0 +1 @@
+ed03d1eeb9b2576747df0d2883d9006fa5e1febe \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-classworlds/1.2-alpha-7/plexus-classworlds-1.2-alpha-7.pom b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-classworlds/1.2-alpha-7/plexus-classworlds-1.2-alpha-7.pom
new file mode 100644
index 00000000..6e29cd26
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-classworlds/1.2-alpha-7/plexus-classworlds-1.2-alpha-7.pom
@@ -0,0 +1,78 @@
+<?xml version="1.0"?><project>
+ <parent>
+ <artifactId>plexus</artifactId>
+ <groupId>org.codehaus.plexus</groupId>
+ <version>1.0.9</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-classworlds</artifactId>
+ <name>Plexus Classworlds</name>
+ <version>1.2-alpha-7</version>
+ <description></description>
+ <inceptionYear>2002</inceptionYear>
+ <scm>
+ <connection>scm:svn:http://svn.codehaus.org/plexus/plexus-classworlds/tags/plexus-classworlds-1.2-alpha-7</connection>
+ <developerConnection>scm:svn:https://svn.codehaus.org/plexus/plexus-classworlds/tags/plexus-classworlds-1.2-alpha-7</developerConnection>
+ <url>http://fisheye.codehaus.org/browse/plexus/plexus-classworlds/tags/plexus-classworlds-1.2-alpha-7</url>
+ </scm>
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <forkMode>once</forkMode>
+ </configuration>
+ </plugin>
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <excludes>
+ <exclude>org/codehaus/plexus/classworlds/event/*</exclude>
+ </excludes>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ <profiles>
+ <profile>
+ <id>debug</id>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>aspectj-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <goals>
+ <goal>compile</goal>
+ </goals>
+ </execution>
+ </executions>
+ <configuration>
+ <complianceLevel>1.4</complianceLevel>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ <dependencies>
+ <dependency>
+ <groupId>aspectj</groupId>
+ <artifactId>aspectjrt</artifactId>
+ <version>1.5.0</version>
+ </dependency>
+ </dependencies>
+ </profile>
+ </profiles>
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>3.8.1</version>
+ <scope>compile</scope>
+ </dependency>
+ </dependencies>
+ <distributionManagement>
+ <status>deployed</status>
+ </distributionManagement>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-classworlds/1.2-alpha-7/plexus-classworlds-1.2-alpha-7.pom.md5 b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-classworlds/1.2-alpha-7/plexus-classworlds-1.2-alpha-7.pom.md5
new file mode 100644
index 00000000..e9083e79
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-classworlds/1.2-alpha-7/plexus-classworlds-1.2-alpha-7.pom.md5
@@ -0,0 +1 @@
+80962d09b250824806ca66b0bd0ad4c1 \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-classworlds/1.2-alpha-7/plexus-classworlds-1.2-alpha-7.pom.sha1 b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-classworlds/1.2-alpha-7/plexus-classworlds-1.2-alpha-7.pom.sha1
new file mode 100644
index 00000000..4b9e8a40
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-classworlds/1.2-alpha-7/plexus-classworlds-1.2-alpha-7.pom.sha1
@@ -0,0 +1 @@
+6944ec0d0cab19adf167332f7197e045d64a577c \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-component-api/1.0-alpha-16/plexus-component-api-1.0-alpha-16.jar b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-component-api/1.0-alpha-16/plexus-component-api-1.0-alpha-16.jar
new file mode 100644
index 00000000..85669fdd
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-component-api/1.0-alpha-16/plexus-component-api-1.0-alpha-16.jar
Binary files differ
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-component-api/1.0-alpha-16/plexus-component-api-1.0-alpha-16.jar.md5 b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-component-api/1.0-alpha-16/plexus-component-api-1.0-alpha-16.jar.md5
new file mode 100644
index 00000000..1830fc9e
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-component-api/1.0-alpha-16/plexus-component-api-1.0-alpha-16.jar.md5
@@ -0,0 +1 @@
+4fe3c03b97ff12905d0fb10fc5b36766 \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-component-api/1.0-alpha-16/plexus-component-api-1.0-alpha-16.jar.sha1 b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-component-api/1.0-alpha-16/plexus-component-api-1.0-alpha-16.jar.sha1
new file mode 100644
index 00000000..7456120d
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-component-api/1.0-alpha-16/plexus-component-api-1.0-alpha-16.jar.sha1
@@ -0,0 +1 @@
+5a2100a1c6a37804b1abfc70000b0ea33b83b7f9 \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-component-api/1.0-alpha-16/plexus-component-api-1.0-alpha-16.pom b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-component-api/1.0-alpha-16/plexus-component-api-1.0-alpha-16.pom
new file mode 100644
index 00000000..b1511640
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-component-api/1.0-alpha-16/plexus-component-api-1.0-alpha-16.pom
@@ -0,0 +1,63 @@
+<?xml version="1.0"?><project>
+ <parent>
+ <artifactId>plexus-containers</artifactId>
+ <groupId>org.codehaus.plexus</groupId>
+ <version>1.0-alpha-16</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>plexus-component-api</artifactId>
+ <name>Plexus Component API</name>
+ <version>1.0-alpha-16</version>
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>2.2</version>
+ <configuration>
+ <excludes>
+ <exclude>**/Test*.java</exclude>
+ <exclude>**/Abstract*.java</exclude>
+ </excludes>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ <dependencies>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-classworlds</artifactId>
+ </dependency>
+ </dependencies>
+ <reporting>
+ <plugins>
+ <plugin>
+ <artifactId>maven-surefire-report-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <artifactId>maven-pmd-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ <configuration>
+ <links>
+ <link>http://java.sun.com/j2ee/1.4/docs/api</link>
+ <link>http://java.sun.com/j2se/1.5.0/docs/api</link>
+ <link>http://jakarta.apache.org/commons/collections/apidocs-COLLECTIONS_3_0/</link>
+ <link>http://jakarta.apache.org/commons/dbcp/apidocs/</link>
+ <link>http://jakarta.apache.org/commons/fileupload/apidocs/</link>
+ <link>http://jakarta.apache.org/commons/httpclient/apidocs/</link>
+ <link>http://jakarta.apache.org/commons/logging/apidocs/</link>
+ <link>http://jakarta.apache.org/commons/pool/apidocs/</link>
+ <link>http://www.junit.org/junit/javadoc/</link>
+ <link>http://logging.apache.org/log4j/docs/api/</link>
+ <link>http://jakarta.apache.org/regexp/apidocs/</link>
+ <link>http://jakarta.apache.org/velocity/api/</link>
+ </links>
+ </configuration>
+ </plugin>
+ </plugins>
+ </reporting>
+ <distributionManagement>
+ <status>deployed</status>
+ </distributionManagement>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-component-api/1.0-alpha-16/plexus-component-api-1.0-alpha-16.pom.md5 b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-component-api/1.0-alpha-16/plexus-component-api-1.0-alpha-16.pom.md5
new file mode 100644
index 00000000..78fc8ace
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-component-api/1.0-alpha-16/plexus-component-api-1.0-alpha-16.pom.md5
@@ -0,0 +1 @@
+751ea77f1e617aea90f36d7156762bf5 \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-component-api/1.0-alpha-16/plexus-component-api-1.0-alpha-16.pom.sha1 b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-component-api/1.0-alpha-16/plexus-component-api-1.0-alpha-16.pom.sha1
new file mode 100644
index 00000000..dea60884
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-component-api/1.0-alpha-16/plexus-component-api-1.0-alpha-16.pom.sha1
@@ -0,0 +1 @@
+53ad54acd9589c497ba54740f0455fec55db64d7 \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-component-api/1.0-alpha-32/plexus-component-api-1.0-alpha-32.jar b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-component-api/1.0-alpha-32/plexus-component-api-1.0-alpha-32.jar
new file mode 100644
index 00000000..5e3a919c
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-component-api/1.0-alpha-32/plexus-component-api-1.0-alpha-32.jar
Binary files differ
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-component-api/1.0-alpha-32/plexus-component-api-1.0-alpha-32.jar.md5 b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-component-api/1.0-alpha-32/plexus-component-api-1.0-alpha-32.jar.md5
new file mode 100644
index 00000000..beb51a4f
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-component-api/1.0-alpha-32/plexus-component-api-1.0-alpha-32.jar.md5
@@ -0,0 +1 @@
+7146edcc3412c2b54df27edaf66b00a6 \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-component-api/1.0-alpha-32/plexus-component-api-1.0-alpha-32.jar.sha1 b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-component-api/1.0-alpha-32/plexus-component-api-1.0-alpha-32.jar.sha1
new file mode 100644
index 00000000..4a7df6b7
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-component-api/1.0-alpha-32/plexus-component-api-1.0-alpha-32.jar.sha1
@@ -0,0 +1 @@
+b226de4eb8db939dff4e14eb5aa1be045c39f6f4 \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-component-api/1.0-alpha-32/plexus-component-api-1.0-alpha-32.pom b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-component-api/1.0-alpha-32/plexus-component-api-1.0-alpha-32.pom
new file mode 100644
index 00000000..6369d8ec
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-component-api/1.0-alpha-32/plexus-component-api-1.0-alpha-32.pom
@@ -0,0 +1,61 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-containers</artifactId>
+ <version>1.0-alpha-32</version>
+ </parent>
+ <artifactId>plexus-component-api</artifactId>
+ <name>Plexus Component API</name>
+ <version>1.0-alpha-32</version>
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>2.2</version>
+ <configuration>
+ <excludes>
+ <exclude>**/Test*.java</exclude>
+ <exclude>**/Abstract*.java</exclude>
+ </excludes>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ <dependencies>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-classworlds</artifactId>
+ </dependency>
+ </dependencies>
+
+ <reporting>
+ <plugins>
+ <plugin>
+ <artifactId>maven-surefire-report-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <artifactId>maven-pmd-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ <configuration>
+ <links>
+ <link>http://java.sun.com/j2ee/1.4/docs/api</link>
+ <link>http://java.sun.com/j2se/1.5.0/docs/api</link>
+ <link>http://jakarta.apache.org/commons/collections/apidocs-COLLECTIONS_3_0/</link>
+ <link>http://jakarta.apache.org/commons/dbcp/apidocs/</link>
+ <link>http://jakarta.apache.org/commons/fileupload/apidocs/</link>
+ <link>http://jakarta.apache.org/commons/httpclient/apidocs/</link>
+ <link>http://jakarta.apache.org/commons/logging/apidocs/</link>
+ <link>http://jakarta.apache.org/commons/pool/apidocs/</link>
+ <link>http://www.junit.org/junit/javadoc/</link>
+ <link>http://logging.apache.org/log4j/docs/api/</link>
+ <link>http://jakarta.apache.org/regexp/apidocs/</link>
+ <link>http://jakarta.apache.org/velocity/api/</link>
+ </links>
+ </configuration>
+ </plugin>
+ </plugins>
+ </reporting>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-component-api/1.0-alpha-32/plexus-component-api-1.0-alpha-32.pom.md5 b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-component-api/1.0-alpha-32/plexus-component-api-1.0-alpha-32.pom.md5
new file mode 100644
index 00000000..40890b2c
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-component-api/1.0-alpha-32/plexus-component-api-1.0-alpha-32.pom.md5
@@ -0,0 +1 @@
+a181ee89516009cff7658eec175ccb23 \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-component-api/1.0-alpha-32/plexus-component-api-1.0-alpha-32.pom.sha1 b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-component-api/1.0-alpha-32/plexus-component-api-1.0-alpha-32.pom.sha1
new file mode 100644
index 00000000..f854c7a1
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-component-api/1.0-alpha-32/plexus-component-api-1.0-alpha-32.pom.sha1
@@ -0,0 +1 @@
+e214782e714b87b38d5605cb8da53b7d98efde06 \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-components/1.1.6/plexus-components-1.1.6.pom b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-components/1.1.6/plexus-components-1.1.6.pom
new file mode 100644
index 00000000..0afa8021
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-components/1.1.6/plexus-components-1.1.6.pom
@@ -0,0 +1,60 @@
+<!--
+
+ !!!
+
+ NOTE: If you change this file, you MUST bump the version up from 1.0. That is the version of the POM, and was
+ used for releases of plexus-compiler and plexus-archiver in the past.
+
+ !!!
+
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>plexus</artifactId>
+ <groupId>org.codehaus.plexus</groupId>
+ <version>1.0.8</version>
+ </parent>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-components</artifactId>
+ <packaging>pom</packaging>
+ <version>1.1.6</version>
+ <name>Plexus Components Parent Project</name>
+ <!--
+ TODO: should this be pushed down to all the dependencies?
+ - a more stable API JAR may be useful, for the interfaces and classes such as AbstractLogEnabled
+ -->
+ <dependencies>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-container-default</artifactId>
+ <version>1.0-alpha-8</version>
+ </dependency>
+ </dependencies>
+ <modules>
+ <module>plexus-action</module>
+ <module>plexus-archiver</module>
+ <module>plexus-bayesian</module>
+ <module>plexus-command</module>
+ <module>plexus-compiler</module>
+ <module>plexus-drools</module>
+ <module>plexus-formica</module>
+ <module>plexus-formica-web</module>
+ <module>plexus-hibernate</module>
+ <module>plexus-i18n</module>
+ <module>plexus-interactivity</module>
+ <module>plexus-ircbot</module>
+ <module>plexus-jdo</module>
+ <module>plexus-jetty-httpd</module>
+ <module>plexus-jetty</module>
+ <module>plexus-mimetyper</module>
+ <module>plexus-notification</module>
+ <module>plexus-resource</module>
+ <module>plexus-security</module>
+ <module>plexus-summit</module>
+ <module>plexus-taskqueue</module>
+ <module>plexus-velocity</module>
+ <module>plexus-xmlrpc</module>
+ </modules>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-components/1.1.6/plexus-components-1.1.6.pom.md5 b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-components/1.1.6/plexus-components-1.1.6.pom.md5
new file mode 100644
index 00000000..cf57067b
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-components/1.1.6/plexus-components-1.1.6.pom.md5
@@ -0,0 +1 @@
+b76cb94eb4ade475f4743d3656c40899 \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-components/1.1.6/plexus-components-1.1.6.pom.sha1 b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-components/1.1.6/plexus-components-1.1.6.pom.sha1
new file mode 100644
index 00000000..b9f0aa79
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-components/1.1.6/plexus-components-1.1.6.pom.sha1
@@ -0,0 +1 @@
+682713aa402653d0ea5e224870dc899803734519 \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-container-default/1.0-alpha-16/plexus-container-default-1.0-alpha-16.jar b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-container-default/1.0-alpha-16/plexus-container-default-1.0-alpha-16.jar
new file mode 100644
index 00000000..ef2bd907
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-container-default/1.0-alpha-16/plexus-container-default-1.0-alpha-16.jar
Binary files differ
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-container-default/1.0-alpha-16/plexus-container-default-1.0-alpha-16.jar.md5 b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-container-default/1.0-alpha-16/plexus-container-default-1.0-alpha-16.jar.md5
new file mode 100644
index 00000000..fc1ee0b6
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-container-default/1.0-alpha-16/plexus-container-default-1.0-alpha-16.jar.md5
@@ -0,0 +1 @@
+00b4ce443fa584a1998cd6f991ea6514 \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-container-default/1.0-alpha-16/plexus-container-default-1.0-alpha-16.jar.sha1 b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-container-default/1.0-alpha-16/plexus-container-default-1.0-alpha-16.jar.sha1
new file mode 100644
index 00000000..879c8890
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-container-default/1.0-alpha-16/plexus-container-default-1.0-alpha-16.jar.sha1
@@ -0,0 +1 @@
+dcad8d44306c5ecc109b9449f292fb28b75d37ef \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-container-default/1.0-alpha-16/plexus-container-default-1.0-alpha-16.pom b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-container-default/1.0-alpha-16/plexus-container-default-1.0-alpha-16.pom
new file mode 100644
index 00000000..f5ae5489
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-container-default/1.0-alpha-16/plexus-container-default-1.0-alpha-16.pom
@@ -0,0 +1,56 @@
+<?xml version="1.0"?><project>
+ <parent>
+ <artifactId>plexus-containers</artifactId>
+ <groupId>org.codehaus.plexus</groupId>
+ <version>1.0-alpha-16</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>plexus-container-default</artifactId>
+ <name>Default Plexus Container</name>
+ <version>1.0-alpha-16</version>
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <forkMode>once</forkMode>
+ <excludes>
+ <exclude>**/Test*.java</exclude>
+ <exclude>**/Abstract*.java</exclude>
+ </excludes>
+ </configuration>
+ </plugin>
+ <plugin>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <configuration>
+ <descriptorRefs>
+ <descriptorRef>jar-with-dependencies</descriptorRef>
+ </descriptorRefs>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ <dependencies>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-component-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-utils</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-classworlds</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>jmock</groupId>
+ <artifactId>jmock</artifactId>
+ <version>1.0.1</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+ <distributionManagement>
+ <status>deployed</status>
+ </distributionManagement>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-container-default/1.0-alpha-16/plexus-container-default-1.0-alpha-16.pom.md5 b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-container-default/1.0-alpha-16/plexus-container-default-1.0-alpha-16.pom.md5
new file mode 100644
index 00000000..611807a8
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-container-default/1.0-alpha-16/plexus-container-default-1.0-alpha-16.pom.md5
@@ -0,0 +1 @@
+883b6e1e40cccb06c1d1ce93728b0a9d \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-container-default/1.0-alpha-16/plexus-container-default-1.0-alpha-16.pom.sha1 b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-container-default/1.0-alpha-16/plexus-container-default-1.0-alpha-16.pom.sha1
new file mode 100644
index 00000000..ea4d6dc0
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-container-default/1.0-alpha-16/plexus-container-default-1.0-alpha-16.pom.sha1
@@ -0,0 +1 @@
+435f5d09ea241e93acaecd4b6680ddb13a36837d \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-container-default/1.0-alpha-32/plexus-container-default-1.0-alpha-32.jar b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-container-default/1.0-alpha-32/plexus-container-default-1.0-alpha-32.jar
new file mode 100644
index 00000000..308893f6
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-container-default/1.0-alpha-32/plexus-container-default-1.0-alpha-32.jar
Binary files differ
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-container-default/1.0-alpha-32/plexus-container-default-1.0-alpha-32.jar.md5 b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-container-default/1.0-alpha-32/plexus-container-default-1.0-alpha-32.jar.md5
new file mode 100644
index 00000000..291ffea0
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-container-default/1.0-alpha-32/plexus-container-default-1.0-alpha-32.jar.md5
@@ -0,0 +1 @@
+556231599b5413a7c1f16a5fd15be574 \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-container-default/1.0-alpha-32/plexus-container-default-1.0-alpha-32.jar.sha1 b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-container-default/1.0-alpha-32/plexus-container-default-1.0-alpha-32.jar.sha1
new file mode 100644
index 00000000..b8ef047d
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-container-default/1.0-alpha-32/plexus-container-default-1.0-alpha-32.jar.sha1
@@ -0,0 +1 @@
+91410b971f9659f76b0ff26a97b9fbac5de2f69e \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-container-default/1.0-alpha-32/plexus-container-default-1.0-alpha-32.pom b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-container-default/1.0-alpha-32/plexus-container-default-1.0-alpha-32.pom
new file mode 100644
index 00000000..fbfdb2ba
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-container-default/1.0-alpha-32/plexus-container-default-1.0-alpha-32.pom
@@ -0,0 +1,98 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-containers</artifactId>
+ <version>1.0-alpha-32</version>
+ </parent>
+ <artifactId>plexus-container-default</artifactId>
+ <name>Default Plexus Container</name>
+ <version>1.0-alpha-32</version>
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <forkMode>once</forkMode>
+ <excludes>
+ <exclude>**/Test*.java</exclude>
+ <exclude>**/Abstract*.java</exclude>
+ </excludes>
+ </configuration>
+ </plugin>
+ <plugin>
+ <artifactId>shade-maven-plugin</artifactId>
+ <groupId>org.codehaus.mojo</groupId>
+ <version>1.0-alpha-9</version>
+ <executions>
+ <execution>
+ <phase>package</phase>
+ <goals>
+ <goal>shade</goal>
+ </goals>
+ <configuration>
+ <artifactSet>
+ <excludes>
+ <exclude>classworlds:classworlds</exclude>
+ <exclude>junit:junit</exclude>
+ <exclude>jmock:jmock</exclude>
+ <exclude>org.codehaus.plexus:plexus-classworlds</exclude>
+ <exclude>org.codehaus.plexus:plexus-utils</exclude>
+ </excludes>
+ </artifactSet>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ <dependencies>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-component-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-utils</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-classworlds</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>jmock</groupId>
+ <artifactId>jmock</artifactId>
+ <version>1.0.1</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+ <reporting>
+ <plugins>
+ <!--plugin>
+ <artifactId>maven-surefire-report-plugin</artifactId>
+ </plugin-->
+ <plugin>
+ <artifactId>maven-pmd-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ <configuration>
+ <links>
+ <link>http://java.sun.com/j2ee/1.4/docs/api</link>
+ <link>http://java.sun.com/j2se/1.5.0/docs/api</link>
+ <link>http://jakarta.apache.org/commons/collections/apidocs-COLLECTIONS_3_0/</link>
+ <link>http://jakarta.apache.org/commons/dbcp/apidocs/</link>
+ <link>http://jakarta.apache.org/commons/fileupload/apidocs/</link>
+ <link>http://jakarta.apache.org/commons/httpclient/apidocs/</link>
+ <link>http://jakarta.apache.org/commons/logging/apidocs/</link>
+ <link>http://jakarta.apache.org/commons/pool/apidocs/</link>
+ <link>http://www.junit.org/junit/javadoc/</link>
+ <link>http://logging.apache.org/log4j/docs/api/</link>
+ <link>http://jakarta.apache.org/regexp/apidocs/</link>
+ <link>http://jakarta.apache.org/velocity/api/</link>
+ </links>
+ </configuration>
+ </plugin>
+ </plugins>
+ </reporting>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-container-default/1.0-alpha-32/plexus-container-default-1.0-alpha-32.pom.md5 b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-container-default/1.0-alpha-32/plexus-container-default-1.0-alpha-32.pom.md5
new file mode 100644
index 00000000..3b237719
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-container-default/1.0-alpha-32/plexus-container-default-1.0-alpha-32.pom.md5
@@ -0,0 +1 @@
+af4ca0022b674405556b3f397e375adc \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-container-default/1.0-alpha-32/plexus-container-default-1.0-alpha-32.pom.sha1 b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-container-default/1.0-alpha-32/plexus-container-default-1.0-alpha-32.pom.sha1
new file mode 100644
index 00000000..00b60872
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-container-default/1.0-alpha-32/plexus-container-default-1.0-alpha-32.pom.sha1
@@ -0,0 +1 @@
+8f4d09d36a2345a39301dbd77ef9906c795887f7 \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-containers/1.0-alpha-16/plexus-containers-1.0-alpha-16.pom b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-containers/1.0-alpha-16/plexus-containers-1.0-alpha-16.pom
new file mode 100644
index 00000000..5800d75b
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-containers/1.0-alpha-16/plexus-containers-1.0-alpha-16.pom
@@ -0,0 +1,49 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus</artifactId>
+ <version>1.0.9</version>
+ </parent>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-containers</artifactId>
+ <packaging>pom</packaging>
+ <name>Parent Plexus Container POM</name>
+ <version>1.0-alpha-16</version>
+ <modules>
+ <module>plexus-component-api</module>
+ <module>plexus-container-default</module>
+ </modules>
+ <scm>
+ <connection>scm:svn:http://svn.codehaus.org/plexus/plexus-containers/tags/plexus-containers-1.0-alpha-16</connection>
+ <developerConnection>scm:svn:https://svn.codehaus.org/plexus/plexus-containers/tags/plexus-containers-1.0-alpha-16</developerConnection>
+ <url>http://fisheye.codehaus.org/browse/plexus/plexus-containers/tags/plexus-containers-1.0-alpha-16</url>
+ </scm>
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>3.8.1</version>
+ <scope>compile</scope>
+ </dependency>
+ </dependencies>
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-classworlds</artifactId>
+ <version>1.2-alpha-7</version>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-component-api</artifactId>
+ <version>1.0-alpha-16</version>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-utils</artifactId>
+ <version>1.3</version>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-containers/1.0-alpha-16/plexus-containers-1.0-alpha-16.pom.md5 b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-containers/1.0-alpha-16/plexus-containers-1.0-alpha-16.pom.md5
new file mode 100644
index 00000000..3db22e20
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-containers/1.0-alpha-16/plexus-containers-1.0-alpha-16.pom.md5
@@ -0,0 +1 @@
+3eee2016e3e307618048e30f088b546e \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-containers/1.0-alpha-16/plexus-containers-1.0-alpha-16.pom.sha1 b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-containers/1.0-alpha-16/plexus-containers-1.0-alpha-16.pom.sha1
new file mode 100644
index 00000000..3eb36271
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-containers/1.0-alpha-16/plexus-containers-1.0-alpha-16.pom.sha1
@@ -0,0 +1 @@
+46b79dd7d6a8130d2fa81c80b16b695d491548fe \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-containers/1.0-alpha-32/plexus-containers-1.0-alpha-32.pom b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-containers/1.0-alpha-32/plexus-containers-1.0-alpha-32.pom
new file mode 100644
index 00000000..4678bd87
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-containers/1.0-alpha-32/plexus-containers-1.0-alpha-32.pom
@@ -0,0 +1,49 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus</artifactId>
+ <version>1.0.11</version>
+ </parent>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-containers</artifactId>
+ <packaging>pom</packaging>
+ <name>Parent Plexus Container POM</name>
+ <version>1.0-alpha-32</version>
+ <modules>
+ <module>plexus-component-api</module>
+ <module>plexus-container-default</module>
+ </modules>
+ <scm>
+ <connection>scm:svn:http://svn.codehaus.org/plexus/plexus-containers/tags/plexus-containers-1.0-alpha-32</connection>
+ <developerConnection>scm:svn:https://svn.codehaus.org/plexus/plexus-containers/tags/plexus-containers-1.0-alpha-32</developerConnection>
+ <url>http://fisheye.codehaus.org/browse/plexus/plexus-containers/tags/plexus-containers-1.0-alpha-32</url>
+ </scm>
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>3.8.1</version>
+ <scope>compile</scope>
+ </dependency>
+ </dependencies>
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-classworlds</artifactId>
+ <version>1.2-alpha-10</version>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-utils</artifactId>
+ <version>1.4.5</version>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-component-api</artifactId>
+ <version>1.0-alpha-32</version>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-containers/1.0-alpha-32/plexus-containers-1.0-alpha-32.pom.md5 b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-containers/1.0-alpha-32/plexus-containers-1.0-alpha-32.pom.md5
new file mode 100644
index 00000000..41815f08
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-containers/1.0-alpha-32/plexus-containers-1.0-alpha-32.pom.md5
@@ -0,0 +1 @@
+8ac33e07134648d37e2b1253286889a7 \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-containers/1.0-alpha-32/plexus-containers-1.0-alpha-32.pom.sha1 b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-containers/1.0-alpha-32/plexus-containers-1.0-alpha-32.pom.sha1
new file mode 100644
index 00000000..41260716
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-containers/1.0-alpha-32/plexus-containers-1.0-alpha-32.pom.sha1
@@ -0,0 +1 @@
+8486ff9b37d1ade2a4524c6fee72d394f88fbe08 \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-utils/1.1/plexus-utils-1.1.jar b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-utils/1.1/plexus-utils-1.1.jar
new file mode 100644
index 00000000..5c50e177
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-utils/1.1/plexus-utils-1.1.jar
Binary files differ
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-utils/1.1/plexus-utils-1.1.jar.md5 b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-utils/1.1/plexus-utils-1.1.jar.md5
new file mode 100644
index 00000000..a7ca769a
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-utils/1.1/plexus-utils-1.1.jar.md5
@@ -0,0 +1 @@
+49e112a6c1ad24962643ef9494f9cbe1 \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-utils/1.1/plexus-utils-1.1.jar.sha1 b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-utils/1.1/plexus-utils-1.1.jar.sha1
new file mode 100644
index 00000000..28f6dbb5
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-utils/1.1/plexus-utils-1.1.jar.sha1
@@ -0,0 +1 @@
+fa632b7f1cb7c50963d0fb7d818ca93c75c10127 \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-utils/1.1/plexus-utils-1.1.pom b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-utils/1.1/plexus-utils-1.1.pom
new file mode 100644
index 00000000..6cf90799
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-utils/1.1/plexus-utils-1.1.pom
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?><project>
+ <parent>
+ <artifactId>plexus</artifactId>
+ <groupId>org.codehaus.plexus</groupId>
+ <version>1.0.4</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>plexus-utils</artifactId>
+ <name>Plexus Common Utilities</name>
+ <version>1.1</version>
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <excludes>
+ <exclude>org/codehaus/plexus/util/FileBasedTestCase.java</exclude>
+ <exclude>**/Test*.java</exclude>
+ </excludes>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ <distributionManagement>
+ <status>deployed</status>
+ </distributionManagement>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-utils/1.1/plexus-utils-1.1.pom.md5 b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-utils/1.1/plexus-utils-1.1.pom.md5
new file mode 100644
index 00000000..6de9bf47
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-utils/1.1/plexus-utils-1.1.pom.md5
@@ -0,0 +1 @@
+6e902bab552ae52fef5875d27c4cf0a0 \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-utils/1.1/plexus-utils-1.1.pom.sha1 b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-utils/1.1/plexus-utils-1.1.pom.sha1
new file mode 100644
index 00000000..4dc64d4a
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-utils/1.1/plexus-utils-1.1.pom.sha1
@@ -0,0 +1 @@
+15492ecd00920daca9ec15f6acd695b626621e5b \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-utils/1.4.5/plexus-utils-1.4.5.jar b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-utils/1.4.5/plexus-utils-1.4.5.jar
new file mode 100644
index 00000000..449afb9c
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-utils/1.4.5/plexus-utils-1.4.5.jar
Binary files differ
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-utils/1.4.5/plexus-utils-1.4.5.jar.md5 b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-utils/1.4.5/plexus-utils-1.4.5.jar.md5
new file mode 100644
index 00000000..eff56f28
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-utils/1.4.5/plexus-utils-1.4.5.jar.md5
@@ -0,0 +1 @@
+e158df8d1a539cc6482567f9689cc36f \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-utils/1.4.5/plexus-utils-1.4.5.jar.sha1 b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-utils/1.4.5/plexus-utils-1.4.5.jar.sha1
new file mode 100644
index 00000000..953f76d8
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-utils/1.4.5/plexus-utils-1.4.5.jar.sha1
@@ -0,0 +1 @@
+56559396674aacd498c298964b691db0177027c0 \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-utils/1.4.5/plexus-utils-1.4.5.pom b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-utils/1.4.5/plexus-utils-1.4.5.pom
new file mode 100644
index 00000000..bc634a6f
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-utils/1.4.5/plexus-utils-1.4.5.pom
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <parent>
+ <artifactId>plexus</artifactId>
+ <groupId>org.codehaus.plexus</groupId>
+ <version>1.0.11</version>
+ <relativePath>../pom/pom.xml</relativePath>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>plexus-utils</artifactId>
+ <name>Plexus Common Utilities</name>
+ <version>1.4.5</version>
+ <url>http://plexus.codehaus.org/plexus-utils</url>
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <!-- surefire requires plexus-utils to be jdk 1.3 compatible -->
+ <source>1.3</source>
+ <target>1.3</target>
+ </configuration>
+ </plugin>
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <!-- required to ensure the test classes are used, not surefire's plexus-utils -->
+ <childDelegation>true</childDelegation>
+ <excludes>
+ <exclude>org/codehaus/plexus/util/FileBasedTestCase.java</exclude>
+ <exclude>**/Test*.java</exclude>
+ </excludes>
+ <systemProperties>
+ <property>
+ <name>JAVA_HOME</name>
+ <value>${JAVA_HOME}</value>
+ </property>
+ <property>
+ <name>M2_HOME</name>
+ <value>${M2_HOME}</value>
+ </property>
+ </systemProperties>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ <scm>
+ <connection>scm:svn:http://svn.codehaus.org/plexus/plexus-utils/tags/plexus-utils-1.4.5</connection>
+ <developerConnection>scm:svn:https://svn.codehaus.org/plexus/plexus-utils/tags/plexus-utils-1.4.5</developerConnection>
+ <url>http://fisheye.codehaus.org/browse/plexus/plexus-utils/tags/plexus-utils-1.4.5</url>
+ </scm>
+ <reporting>
+ <plugins>
+ <plugin>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <artifactId>maven-jxr-plugin</artifactId>
+ </plugin>
+ </plugins>
+ </reporting>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-utils/1.4.5/plexus-utils-1.4.5.pom.md5 b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-utils/1.4.5/plexus-utils-1.4.5.pom.md5
new file mode 100644
index 00000000..905f70a9
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-utils/1.4.5/plexus-utils-1.4.5.pom.md5
@@ -0,0 +1 @@
+fccab705018ed5559df9f8e815b79aaa \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-utils/1.4.5/plexus-utils-1.4.5.pom.sha1 b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-utils/1.4.5/plexus-utils-1.4.5.pom.sha1
new file mode 100644
index 00000000..247cd943
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus-utils/1.4.5/plexus-utils-1.4.5.pom.sha1
@@ -0,0 +1 @@
+0bdc8a7fbce7d9007a93d289a029b43e1196d85c \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus/1.0.10/plexus-1.0.10.pom b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus/1.0.10/plexus-1.0.10.pom
new file mode 100644
index 00000000..bc94e24b
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus/1.0.10/plexus-1.0.10.pom
@@ -0,0 +1,273 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus</artifactId>
+ <packaging>pom</packaging>
+ <name>Plexus</name>
+ <version>1.0.10</version>
+ <ciManagement>
+ <notifiers>
+ <notifier>
+ <type>mail</type>
+ <configuration>
+ <address>dev@plexus.codehaus.org</address>
+ </configuration>
+ </notifier>
+ <notifier>
+ <type>irc</type>
+ <configuration>
+ <host>irc.codehaus.org</host>
+ <port>6667</port>
+ <channel>#plexus</channel>
+ </configuration>
+ </notifier>
+ </notifiers>
+ </ciManagement>
+ <inceptionYear>2001</inceptionYear>
+ <mailingLists>
+ <mailingList>
+ <name>Plexus User List</name>
+ <subscribe>http://xircles.codehaus.org/manage_email/user%40plexus.codehaus.org</subscribe>
+ <unsubscribe>http://xircles.codehaus.org/manage_email/user%40plexus.codehaus.org</unsubscribe>
+ <archive>http://archive.plexus.codehaus.org/user</archive>
+ </mailingList>
+ <mailingList>
+ <name>Plexus Developer List</name>
+ <subscribe>http://xircles.codehaus.org/manage_email/dev%40plexus.codehaus.org</subscribe>
+ <unsubscribe>http://xircles.codehaus.org/manage_email/dev%40plexus.codehaus.org</unsubscribe>
+ <archive>http://archive.plexus.codehaus.org/dev</archive>
+ </mailingList>
+ <mailingList>
+ <name>Plexus Announce List</name>
+ <subscribe>http://xircles.codehaus.org/manage_email/announce%40plexus.codehaus.org</subscribe>
+ <unsubscribe>http://xircles.codehaus.org/manage_email/announce%40plexus.codehaus.org</unsubscribe>
+ <archive>http://archive.plexus.codehaus.org/announce</archive>
+ </mailingList>
+ <mailingList>
+ <name>Plexus Commit List</name>
+ <subscribe>http://xircles.codehaus.org/manage_email/scm%40plexus.codehaus.org</subscribe>
+ <unsubscribe>http://xircles.codehaus.org/manage_email/scm%40plexus.codehaus.org</unsubscribe>
+ <archive>http://archive.plexus.codehaus.org/scm</archive>
+ </mailingList>
+ </mailingLists>
+ <issueManagement>
+ <system>JIRA</system>
+ <url>http://jira.codehaus.org/browse/PLX</url>
+ </issueManagement>
+
+ <distributionManagement>
+ <repository>
+ <id>codehaus.org</id>
+ <name>Plexus Central Repository</name>
+ <url>dav:https://dav.codehaus.org/repository/plexus</url>
+ </repository>
+ <snapshotRepository>
+ <id>codehaus.org</id>
+ <name>Plexus Central Development Repository</name>
+ <url>dav:https://dav.codehaus.org/snapshots.repository/plexus</url>
+ </snapshotRepository>
+ <site>
+ <id>codehaus.org</id>
+ <url>dav:https://dav.codehaus.org/plexus</url>
+ </site>
+ </distributionManagement>
+ <repositories>
+ <repository>
+ <id>codehaus.snapshots</id>
+ <name>Codehaus Snapshot Development Repository</name>
+ <url>http://snapshots.repository.codehaus.org</url>
+ <releases>
+ <enabled>false</enabled>
+ </releases>
+ </repository>
+ </repositories>
+
+ <developers>
+ <developer>
+ <id>jvanzyl</id>
+ <name>Jason van Zyl</name>
+ <email>jason@maven.org</email>
+ <roles>
+ <role>Developer</role>
+ <role>Release Manager</role>
+ </roles>
+ </developer>
+ <developer>
+ <id>kaz</id>
+ <name>Pete Kazmier</name>
+ <email />
+ <organization />
+ <roles>
+ <role>Developer</role>
+ </roles>
+ </developer>
+ <developer>
+ <id>jtaylor</id>
+ <name>James Taylor</name>
+ <email>james@jamestaylor.org</email>
+ <organization />
+ <roles>
+ <role>Developer</role>
+ </roles>
+ </developer>
+ <developer>
+ <id>dandiep</id>
+ <name>Dan Diephouse</name>
+ <email>dan@envoisolutions.com</email>
+ <organization>Envoi solutions</organization>
+ <roles>
+ <role>Developer</role>
+ </roles>
+ </developer>
+ <developer>
+ <id>kasper</id>
+ <name>Kasper Nielsen</name>
+ <email>apache@kav.dk</email>
+ <organization />
+ <roles>
+ <role>Developer</role>
+ </roles>
+ </developer>
+ <developer>
+ <id>bwalding</id>
+ <name>Ben Walding</name>
+ <email>bwalding@codehaus.org</email>
+ <organization>Walding Consulting Services</organization>
+ <roles>
+ <role>Developer</role>
+ </roles>
+ </developer>
+ <developer>
+ <id>mhw</id>
+ <name>Mark Wilkinson</name>
+ <email>mhw@kremvax.net</email>
+ <roles>
+ <role>Developer</role>
+ </roles>
+ </developer>
+ <developer>
+ <id>michal</id>
+ <name>Michal Maczka</name>
+ <email>mmaczka@interia.pl</email>
+ <roles>
+ <role>Developer</role>
+ </roles>
+ </developer>
+ <developer>
+ <id>evenisse</id>
+ <name>Emmanuel Venisse</name>
+ <email>evenisse@codehaus.org</email>
+ <roles>
+ <role>Developer</role>
+ </roles>
+ </developer>
+ <developer>
+ <name>Trygve Laugstol</name>
+ <id>trygvis</id>
+ <email>trygvis@codehaus.org</email>
+ <roles>
+ <role>Developer</role>
+ </roles>
+ </developer>
+ <developer>
+ <name>Kenney Westerhof</name>
+ <id>kenney</id>
+ <email>kenney@codehaus.org</email>
+ <roles>
+ <role>Developer</role>
+ </roles>
+ </developer>
+ <developer>
+ <name>Carlos Sanchez</name>
+ <id>carlos</id>
+ <email>carlos@codehaus.org</email>
+ <roles>
+ <role>Developer</role>
+ </roles>
+ </developer>
+ <developer>
+ <name>Brett Porter</name>
+ <id>brett</id>
+ <email>brett@codehaus.org</email>
+ <roles>
+ <role>Developer</role>
+ </roles>
+ </developer>
+ <developer>
+ <name>John Casey</name>
+ <id>jdcasey</id>
+ <email>jdcasey@codehaus.org</email>
+ <roles>
+ <role>Developer</role>
+ </roles>
+ </developer>
+ <developer>
+ <name>Andrew Williams</name>
+ <id>handyande</id>
+ <email>andy@handyande.co.uk</email>
+ <roles>
+ <role>Developer</role>
+ </roles>
+ </developer>
+ <developer>
+ <name>Rahul Thakur</name>
+ <id>rahul</id>
+ <email>rahul.thakur.xdev@gmail.com</email>
+ <roles>
+ <role>Developer</role>
+ </roles>
+ </developer>
+ <developer>
+ <name>Joakim Erdfelt</name>
+ <id>joakime</id>
+ <email>joakim@erdfelt.com</email>
+ <roles>
+ <role>Developer</role>
+ </roles>
+ </developer>
+ <developer>
+ <name>Olivier Lamy</name>
+ <id>olamy</id>
+ <email>olamy@codehaus.org</email>
+ <roles>
+ <role>Developer</role>
+ </roles>
+ </developer>
+ </developers>
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>3.8.1</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+ <scm>
+ <connection>scm:svn:http://svn.codehaus.org/plexus/pom/tags/plexus-1.0.10</connection>
+ <developerConnection>scm:svn:https://svn.codehaus.org/plexus/pom/tags/plexus-1.0.10</developerConnection>
+ <url>http://fisheye.codehaus.org/browse/plexus/pom/tags/plexus-1.0.10</url>
+ </scm>
+ <organization>
+ <name>Codehaus</name>
+ <url>http://www.codehaus.org/</url>
+ </organization>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <source>1.4</source>
+ <target>1.4</target>
+ </configuration>
+ </plugin>
+ </plugins>
+ <extensions>
+ <extension>
+ <groupId>org.apache.maven.wagon</groupId>
+ <artifactId>wagon-webdav</artifactId>
+ <version>1.0-beta-2</version>
+ </extension>
+ </extensions>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus/1.0.10/plexus-1.0.10.pom.md5 b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus/1.0.10/plexus-1.0.10.pom.md5
new file mode 100644
index 00000000..7ae43d7e
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus/1.0.10/plexus-1.0.10.pom.md5
@@ -0,0 +1 @@
+6ab958c91424c0d7c3a2cc861867905e \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus/1.0.10/plexus-1.0.10.pom.sha1 b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus/1.0.10/plexus-1.0.10.pom.sha1
new file mode 100644
index 00000000..8ed366f9
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus/1.0.10/plexus-1.0.10.pom.sha1
@@ -0,0 +1 @@
+039c3f6a3cbe1f9e7b4a3309d9d7062b6e390fa7 \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus/1.0.11/plexus-1.0.11.pom b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus/1.0.11/plexus-1.0.11.pom
new file mode 100644
index 00000000..28ee5744
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus/1.0.11/plexus-1.0.11.pom
@@ -0,0 +1,308 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus</artifactId>
+ <packaging>pom</packaging>
+ <name>Plexus</name>
+ <version>1.0.11</version>
+ <ciManagement>
+ <notifiers>
+ <notifier>
+ <type>mail</type>
+ <configuration>
+ <address>dev@plexus.codehaus.org</address>
+ </configuration>
+ </notifier>
+ <notifier>
+ <type>irc</type>
+ <configuration>
+ <host>irc.codehaus.org</host>
+ <port>6667</port>
+ <channel>#plexus</channel>
+ </configuration>
+ </notifier>
+ </notifiers>
+ </ciManagement>
+ <inceptionYear>2001</inceptionYear>
+ <licenses>
+ <license>
+ <name>The Apache Software License, Version 2.0</name>
+ <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
+ <distribution>repo</distribution>
+ </license>
+ </licenses>
+ <mailingLists>
+ <mailingList>
+ <name>Plexus User List</name>
+ <subscribe>http://xircles.codehaus.org/manage_email/user%40plexus.codehaus.org</subscribe>
+ <unsubscribe>http://xircles.codehaus.org/manage_email/user%40plexus.codehaus.org</unsubscribe>
+ <archive>http://archive.plexus.codehaus.org/user</archive>
+ </mailingList>
+ <mailingList>
+ <name>Plexus Developer List</name>
+ <subscribe>http://xircles.codehaus.org/manage_email/dev%40plexus.codehaus.org</subscribe>
+ <unsubscribe>http://xircles.codehaus.org/manage_email/dev%40plexus.codehaus.org</unsubscribe>
+ <archive>http://archive.plexus.codehaus.org/dev</archive>
+ </mailingList>
+ <mailingList>
+ <name>Plexus Announce List</name>
+ <subscribe>http://xircles.codehaus.org/manage_email/announce%40plexus.codehaus.org</subscribe>
+ <unsubscribe>http://xircles.codehaus.org/manage_email/announce%40plexus.codehaus.org</unsubscribe>
+ <archive>http://archive.plexus.codehaus.org/announce</archive>
+ </mailingList>
+ <mailingList>
+ <name>Plexus Commit List</name>
+ <subscribe>http://xircles.codehaus.org/manage_email/scm%40plexus.codehaus.org</subscribe>
+ <unsubscribe>http://xircles.codehaus.org/manage_email/scm%40plexus.codehaus.org</unsubscribe>
+ <archive>http://archive.plexus.codehaus.org/scm</archive>
+ </mailingList>
+ </mailingLists>
+ <issueManagement>
+ <system>JIRA</system>
+ <url>http://jira.codehaus.org/browse/PLX</url>
+ </issueManagement>
+
+ <distributionManagement>
+ <repository>
+ <id>codehaus.org</id>
+ <name>Plexus Central Repository</name>
+ <url>dav:https://dav.codehaus.org/repository/plexus</url>
+ </repository>
+ <snapshotRepository>
+ <id>codehaus.org</id>
+ <name>Plexus Central Development Repository</name>
+ <url>dav:https://dav.codehaus.org/snapshots.repository/plexus</url>
+ </snapshotRepository>
+ <site>
+ <id>codehaus.org</id>
+ <url>dav:https://dav.codehaus.org/plexus</url>
+ </site>
+ </distributionManagement>
+ <repositories>
+ <repository>
+ <id>codehaus.snapshots</id>
+ <name>Codehaus Snapshot Development Repository</name>
+ <url>http://snapshots.repository.codehaus.org</url>
+ <releases>
+ <enabled>false</enabled>
+ </releases>
+ </repository>
+ </repositories>
+
+ <developers>
+ <developer>
+ <id>jvanzyl</id>
+ <name>Jason van Zyl</name>
+ <email>jason@maven.org</email>
+ <roles>
+ <role>Developer</role>
+ <role>Release Manager</role>
+ </roles>
+ </developer>
+ <developer>
+ <id>kaz</id>
+ <name>Pete Kazmier</name>
+ <email />
+ <organization />
+ <roles>
+ <role>Developer</role>
+ </roles>
+ </developer>
+ <developer>
+ <id>jtaylor</id>
+ <name>James Taylor</name>
+ <email>james@jamestaylor.org</email>
+ <organization />
+ <roles>
+ <role>Developer</role>
+ </roles>
+ </developer>
+ <developer>
+ <id>dandiep</id>
+ <name>Dan Diephouse</name>
+ <email>dan@envoisolutions.com</email>
+ <organization>Envoi solutions</organization>
+ <roles>
+ <role>Developer</role>
+ </roles>
+ </developer>
+ <developer>
+ <id>kasper</id>
+ <name>Kasper Nielsen</name>
+ <email>apache@kav.dk</email>
+ <organization />
+ <roles>
+ <role>Developer</role>
+ </roles>
+ </developer>
+ <developer>
+ <id>bwalding</id>
+ <name>Ben Walding</name>
+ <email>bwalding@codehaus.org</email>
+ <organization>Walding Consulting Services</organization>
+ <roles>
+ <role>Developer</role>
+ </roles>
+ </developer>
+ <developer>
+ <id>mhw</id>
+ <name>Mark Wilkinson</name>
+ <email>mhw@kremvax.net</email>
+ <roles>
+ <role>Developer</role>
+ </roles>
+ </developer>
+ <developer>
+ <id>michal</id>
+ <name>Michal Maczka</name>
+ <email>mmaczka@interia.pl</email>
+ <roles>
+ <role>Developer</role>
+ </roles>
+ </developer>
+ <developer>
+ <id>evenisse</id>
+ <name>Emmanuel Venisse</name>
+ <email>evenisse@codehaus.org</email>
+ <roles>
+ <role>Developer</role>
+ </roles>
+ </developer>
+ <developer>
+ <name>Trygve Laugstol</name>
+ <id>trygvis</id>
+ <email>trygvis@codehaus.org</email>
+ <roles>
+ <role>Developer</role>
+ </roles>
+ </developer>
+ <developer>
+ <name>Kenney Westerhof</name>
+ <id>kenney</id>
+ <email>kenney@codehaus.org</email>
+ <roles>
+ <role>Developer</role>
+ </roles>
+ </developer>
+ <developer>
+ <name>Carlos Sanchez</name>
+ <id>carlos</id>
+ <email>carlos@codehaus.org</email>
+ <roles>
+ <role>Developer</role>
+ </roles>
+ </developer>
+ <developer>
+ <name>Brett Porter</name>
+ <id>brett</id>
+ <email>brett@codehaus.org</email>
+ <roles>
+ <role>Developer</role>
+ </roles>
+ </developer>
+ <developer>
+ <name>John Casey</name>
+ <id>jdcasey</id>
+ <email>jdcasey@codehaus.org</email>
+ <roles>
+ <role>Developer</role>
+ </roles>
+ </developer>
+ <developer>
+ <name>Andrew Williams</name>
+ <id>handyande</id>
+ <email>andy@handyande.co.uk</email>
+ <roles>
+ <role>Developer</role>
+ </roles>
+ </developer>
+ <developer>
+ <name>Rahul Thakur</name>
+ <id>rahul</id>
+ <email>rahul.thakur.xdev@gmail.com</email>
+ <roles>
+ <role>Developer</role>
+ </roles>
+ </developer>
+ <developer>
+ <name>Joakim Erdfelt</name>
+ <id>joakime</id>
+ <email>joakim@erdfelt.com</email>
+ <roles>
+ <role>Developer</role>
+ </roles>
+ </developer>
+ <developer>
+ <name>Olivier Lamy</name>
+ <id>olamy</id>
+ <email>olamy@codehaus.org</email>
+ <roles>
+ <role>Developer</role>
+ </roles>
+ </developer>
+ </developers>
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>3.8.1</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+ <scm>
+ <connection>scm:svn:http://svn.codehaus.org/plexus/pom/trunk/</connection>
+ <developerConnection>scm:svn:https://svn.codehaus.org/plexus/pom/trunk/</developerConnection>
+ <url>http://fisheye.codehaus.org/browse/plexus/pom/trunk/</url>
+ </scm>
+ <organization>
+ <name>Codehaus</name>
+ <url>http://www.codehaus.org/</url>
+ </organization>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <source>1.4</source>
+ <target>1.4</target>
+ </configuration>
+ </plugin>
+ <!--
+ <plugin>
+ <artifactId>maven-remote-resources-plugin</artifactId>
+ <version>1.0-alpha-2</version>
+ <executions>
+ <execution>
+ <goals>
+ <goal>process</goal>
+ </goals>
+ <configuration>
+ <resourceBundles>
+ <resourceBundle>org.apache:apache-jar-resource-bundle:1.1.1-SNAPSHOT</resourceBundle>
+ </resourceBundles>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ -->
+ </plugins>
+ <extensions>
+ <extension>
+ <groupId>org.apache.maven.wagon</groupId>
+ <artifactId>wagon-webdav</artifactId>
+ <version>1.0-beta-2</version>
+ </extension>
+ </extensions>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <artifactId>maven-release-plugin</artifactId>
+ <configuration>
+ <goals>deploy</goals>
+ </configuration>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus/1.0.11/plexus-1.0.11.pom.md5 b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus/1.0.11/plexus-1.0.11.pom.md5
new file mode 100644
index 00000000..2cabbba0
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus/1.0.11/plexus-1.0.11.pom.md5
@@ -0,0 +1 @@
+bdf8dcfe0877af604f7e19e9ffdf260b \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus/1.0.11/plexus-1.0.11.pom.sha1 b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus/1.0.11/plexus-1.0.11.pom.sha1
new file mode 100644
index 00000000..1ba2b3af
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus/1.0.11/plexus-1.0.11.pom.sha1
@@ -0,0 +1 @@
+4693d4512d50c5159bef1c49def1d2690a327c30 \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus/1.0.4/plexus-1.0.4.pom b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus/1.0.4/plexus-1.0.4.pom
new file mode 100644
index 00000000..2cf5d569
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus/1.0.4/plexus-1.0.4.pom
@@ -0,0 +1,205 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus</artifactId>
+ <packaging>pom</packaging>
+ <name>Plexus</name>
+ <version>1.0.4</version>
+ <ciManagement>
+ <notifiers>
+ <notifier>
+ <type>mail</type>
+ <configuration>
+ <address>dev@plexus.codehaus.org</address>
+ </configuration>
+ </notifier>
+ <notifier>
+ <type>irc</type>
+ <configuration>
+ <host>irc.codehaus.org</host>
+ <port>6667</port>
+ <channel>#plexus</channel>
+ </configuration>
+ </notifier>
+ </notifiers>
+ </ciManagement>
+ <inceptionYear>2001</inceptionYear>
+ <mailingLists>
+ <mailingList>
+ <name>Plexus Developer List</name>
+ <subscribe>http://lists.codehaus.org/mailman/listinfo/plexus-dev</subscribe>
+ <unsubscribe>http://lists.codehaus.org/mailman/listinfo/plexus-dev</unsubscribe>
+ <archive>http://lists.codehaus.org/pipermail/plexus-dev/</archive>
+ </mailingList>
+ </mailingLists>
+
+ <distributionManagement>
+ <repository>
+ <id>repo1</id>
+ <name>Maven Central Repository</name>
+ <url>scp://repo1.maven.org/home/projects/maven/repository-staging/to-ibiblio/maven2</url>
+ </repository>
+ <snapshotRepository>
+ <id>snapshots</id>
+ <name>Maven Central Development Repository</name>
+ <url>scp://repo1.maven.org/home/projects/maven/repository-staging/snapshots/maven2</url>
+ </snapshotRepository>
+ </distributionManagement>
+ <repositories>
+ <repository>
+ <id>snapshots</id>
+ <name>Maven Snapshot Development Repository</name>
+ <url>http://snapshots.maven.codehaus.org/maven2</url>
+ <releases>
+ <enabled>false</enabled>
+ </releases>
+ </repository>
+ </repositories>
+ <pluginRepositories>
+ <pluginRepository>
+ <id>snapshots-plugins</id>
+ <name>Maven Snapshot Plugins Development Repository</name>
+ <url>http://snapshots.maven.codehaus.org/maven2</url>
+ <releases>
+ <enabled>false</enabled>
+ </releases>
+ </pluginRepository>
+ </pluginRepositories>
+
+ <developers>
+ <developer>
+ <id>jvanzyl</id>
+ <name>Jason van Zyl</name>
+ <email>jason@zenplex.com</email>
+ <organization>Zenplex</organization>
+ <roles>
+ <role>Developer</role>
+ <role>Release Manager</role>
+ </roles>
+ </developer>
+ <developer>
+ <id>kaz</id>
+ <name>Pete Kazmier</name>
+ <email></email>
+ <organization></organization>
+ <roles>
+ <role>Developer</role>
+ </roles>
+ </developer>
+ <developer>
+ <id>jtaylor</id>
+ <name>James Taylor</name>
+ <email>james@jamestaylor.org</email>
+ <organization></organization>
+ <roles>
+ <role>Developer</role>
+ </roles>
+ </developer>
+ <developer>
+ <id>dandiep</id>
+ <name>Dan Diephouse</name>
+ <email>dan@envoisolutions.com</email>
+ <organization>Envoi solutions</organization>
+ <roles>
+ <role>Developer</role>
+ </roles>
+ </developer>
+ <developer>
+ <id>kasper</id>
+ <name>Kasper Nielsen</name>
+ <email>apache@kav.dk</email>
+ <organization></organization>
+ <roles>
+ <role>Developer</role>
+ </roles>
+ </developer>
+ <developer>
+ <id>bwalding</id>
+ <name>Ben Walding</name>
+ <email>bwalding@codehaus.org</email>
+ <organization>Walding Consulting Services</organization>
+ <roles>
+ <role>Developer</role>
+ </roles>
+ </developer>
+ <developer>
+ <id>mhw</id>
+ <name>Mark Wilkinson</name>
+ <email>mhw@kremvax.net</email>
+ <roles>
+ <role>Developer</role>
+ </roles>
+ </developer>
+ <developer>
+ <id>michal</id>
+ <name>Michal Maczka</name>
+ <email>mmaczka@interia.pl</email>
+ <roles>
+ <role>Developer</role>
+ </roles>
+ </developer>
+ <developer>
+ <id>evenisse</id>
+ <name>Emmanuel Venisse</name>
+ <email>evenisse@codehaus.org</email>
+ <roles>
+ <role>Developer</role>
+ </roles>
+ </developer>
+ <developer>
+ <name>Trygve Laugst&oslash;l</name>
+ <id>trygvis</id>
+ <email>trygvis@codehaus.org</email>
+ <roles>
+ <role>Developer</role>
+ </roles>
+ </developer>
+ <developer>
+ <name>Kenney Westerhof</name>
+ <id>kenney</id>
+ <email>kenney@codehaus.org</email>
+ <roles>
+ <role>Developer</role>
+ </roles>
+ </developer>
+ </developers>
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>3.8.1</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+ <scm>
+ <connection>scm:svn:svn://svn.codehaus.org/plexus/scm/trunk/</connection>
+ <developerConnection>scm:svn:https://svn.codehaus.org/plexus/trunk</developerConnection>
+ </scm>
+ <organization>
+ <name>Codehaus</name>
+ <url>http://www.codehaus.org/</url>
+ </organization>
+ <modules>
+ <module>plexus-appserver</module>
+ <module>plexus-archetypes</module>
+ <module>plexus-components</module>
+ <module>plexus-component-factories</module>
+ <module>plexus-containers</module>
+ <module>plexus-logging</module>
+ <module>plexus-maven-plugin</module>
+ <module>plexus-services</module>
+ <module>plexus-tools</module>
+ <module>plexus-utils</module>
+ </modules>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-release-plugin</artifactId>
+ <configuration>
+ <tagBase>https://svn.codehaus.org/plexus/tags</tagBase>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus/1.0.4/plexus-1.0.4.pom.md5 b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus/1.0.4/plexus-1.0.4.pom.md5
new file mode 100644
index 00000000..ec5562d8
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus/1.0.4/plexus-1.0.4.pom.md5
@@ -0,0 +1 @@
+2e97f3a7666e337ce5d2d98b9c384cae \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus/1.0.4/plexus-1.0.4.pom.sha1 b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus/1.0.4/plexus-1.0.4.pom.sha1
new file mode 100644
index 00000000..456d5347
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus/1.0.4/plexus-1.0.4.pom.sha1
@@ -0,0 +1 @@
+06f66b2f7d2eef1d805c11bca91c89984cda4137 \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus/1.0.8/plexus-1.0.8.pom b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus/1.0.8/plexus-1.0.8.pom
new file mode 100644
index 00000000..cba2014f
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus/1.0.8/plexus-1.0.8.pom
@@ -0,0 +1,259 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus</artifactId>
+ <packaging>pom</packaging>
+ <name>Plexus</name>
+ <version>1.0.8</version>
+ <ciManagement>
+ <notifiers>
+ <notifier>
+ <type>mail</type>
+ <configuration>
+ <address>dev@plexus.codehaus.org</address>
+ </configuration>
+ </notifier>
+ <notifier>
+ <type>irc</type>
+ <configuration>
+ <host>irc.codehaus.org</host>
+ <port>6667</port>
+ <channel>#plexus</channel>
+ </configuration>
+ </notifier>
+ </notifiers>
+ </ciManagement>
+ <inceptionYear>2001</inceptionYear>
+ <mailingLists>
+ <mailingList>
+ <name>Plexus Developer List</name>
+ <subscribe>http://lists.codehaus.org/mailman/listinfo/plexus-dev</subscribe>
+ <unsubscribe>http://lists.codehaus.org/mailman/listinfo/plexus-dev</unsubscribe>
+ <archive>http://lists.codehaus.org/pipermail/plexus-dev/</archive>
+ </mailingList>
+ </mailingLists>
+ <issueManagement>
+ <system>JIRA</system>
+ <url>http://jira.codehaus.org/browse/PLX</url>
+ </issueManagement>
+
+ <distributionManagement>
+ <repository>
+ <id>codehaus.org</id>
+ <name>Plexus Central Repository</name>
+ <url>dav:https://dav.codehaus.org/repository/plexus</url>
+ </repository>
+ <snapshotRepository>
+ <id>codehaus.org</id>
+ <name>Plexus Central Development Repository</name>
+ <url>dav:https://dav.codehaus.org/snapshots.repository/plexus</url>
+ </snapshotRepository>
+ <site>
+ <id>codehaus.org</id>
+ <url>dav:https://dav.codehaus.org/plexus</url>
+ </site>
+ </distributionManagement>
+ <repositories>
+ <repository>
+ <id>apache-snapshots</id>
+ <name>Snapshot repository</name>
+ <url>http://people.apache.org/maven-snapshot-repository</url>
+ <releases>
+ <enabled>false</enabled>
+ </releases>
+ </repository>
+ <repository>
+ <id>codehaus-snapshots</id>
+ <name>Codehaus Snapshot Development Repository</name>
+ <url>http://snapshots.repository.codehaus.org</url>
+ <releases>
+ <enabled>false</enabled>
+ </releases>
+ </repository>
+ </repositories>
+ <pluginRepositories>
+ <pluginRepository>
+ <id>codehaus-snapshots</id>
+ <name>Codehaus Snapshot Development Repository</name>
+ <url>http://snapshots.repository.codehaus.org</url>
+ <releases>
+ <enabled>false</enabled>
+ </releases>
+ </pluginRepository>
+ </pluginRepositories>
+
+ <developers>
+ <developer>
+ <id>jvanzyl</id>
+ <name>Jason van Zyl</name>
+ <email>jason@maven.org</email>
+ <roles>
+ <role>Developer</role>
+ <role>Release Manager</role>
+ </roles>
+ </developer>
+ <developer>
+ <id>kaz</id>
+ <name>Pete Kazmier</name>
+ <email></email>
+ <organization></organization>
+ <roles>
+ <role>Developer</role>
+ </roles>
+ </developer>
+ <developer>
+ <id>jtaylor</id>
+ <name>James Taylor</name>
+ <email>james@jamestaylor.org</email>
+ <organization></organization>
+ <roles>
+ <role>Developer</role>
+ </roles>
+ </developer>
+ <developer>
+ <id>dandiep</id>
+ <name>Dan Diephouse</name>
+ <email>dan@envoisolutions.com</email>
+ <organization>Envoi solutions</organization>
+ <roles>
+ <role>Developer</role>
+ </roles>
+ </developer>
+ <developer>
+ <id>kasper</id>
+ <name>Kasper Nielsen</name>
+ <email>apache@kav.dk</email>
+ <organization></organization>
+ <roles>
+ <role>Developer</role>
+ </roles>
+ </developer>
+ <developer>
+ <id>bwalding</id>
+ <name>Ben Walding</name>
+ <email>bwalding@codehaus.org</email>
+ <organization>Walding Consulting Services</organization>
+ <roles>
+ <role>Developer</role>
+ </roles>
+ </developer>
+ <developer>
+ <id>mhw</id>
+ <name>Mark Wilkinson</name>
+ <email>mhw@kremvax.net</email>
+ <roles>
+ <role>Developer</role>
+ </roles>
+ </developer>
+ <developer>
+ <id>michal</id>
+ <name>Michal Maczka</name>
+ <email>mmaczka@interia.pl</email>
+ <roles>
+ <role>Developer</role>
+ </roles>
+ </developer>
+ <developer>
+ <id>evenisse</id>
+ <name>Emmanuel Venisse</name>
+ <email>evenisse@codehaus.org</email>
+ <roles>
+ <role>Developer</role>
+ </roles>
+ </developer>
+ <developer>
+ <name>Trygve Laugstol</name>
+ <id>trygvis</id>
+ <email>trygvis@codehaus.org</email>
+ <roles>
+ <role>Developer</role>
+ </roles>
+ </developer>
+ <developer>
+ <name>Kenney Westerhof</name>
+ <id>kenney</id>
+ <email>kenney@codehaus.org</email>
+ <roles>
+ <role>Developer</role>
+ </roles>
+ </developer>
+ <developer>
+ <name>Carlos Sanchez</name>
+ <id>carlos</id>
+ <email>carlos@codehaus.org</email>
+ <roles>
+ <role>Developer</role>
+ </roles>
+ </developer>
+ <developer>
+ <name>Brett Porter</name>
+ <id>brett</id>
+ <email>brett@codehaus.org</email>
+ <roles>
+ <role>Developer</role>
+ </roles>
+ </developer>
+ <developer>
+ <name>John Casey</name>
+ <id>jdcasey</id>
+ <email>jdcasey@codehaus.org</email>
+ <roles>
+ <role>Developer</role>
+ </roles>
+ </developer>
+ </developers>
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>3.8.1</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+ <scm>
+ <connection>scm:svn:http://svn.codehaus.org/plexus/trunk/</connection>
+ <developerConnection>scm:svn:https://svn.codehaus.org/plexus/trunk</developerConnection>
+ </scm>
+ <organization>
+ <name>Codehaus</name>
+ <url>http://www.codehaus.org/</url>
+ </organization>
+ <modules>
+ <!--
+
+ Until the bug is fixed in Maven which is pulling in the trunk to the
+ appserver build.
+ <module>plexus-appserver</module>
+ -->
+ <module>plexus-archetypes</module>
+ <module>plexus-examples</module>
+ <module>plexus-components</module>
+ <module>plexus-component-factories</module>
+ <module>plexus-containers</module>
+ <module>plexus-logging</module>
+ <module>plexus-maven-plugin</module>
+ <module>plexus-tools</module>
+ <module>plexus-utils</module>
+ </modules>
+ <build>
+ <extensions>
+ <extension>
+ <groupId>org.apache.maven.wagon</groupId>
+ <artifactId>wagon-webdav</artifactId>
+ <version>1.0-beta-1</version>
+ </extension>
+ </extensions>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-release-plugin</artifactId>
+ <configuration>
+ <tagBase>https://svn.codehaus.org/plexus/tags</tagBase>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus/1.0.8/plexus-1.0.8.pom.md5 b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus/1.0.8/plexus-1.0.8.pom.md5
new file mode 100644
index 00000000..e0d40fcd
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus/1.0.8/plexus-1.0.8.pom.md5
@@ -0,0 +1 @@
+2da4039a1c4c959c75d3e6126f2029cf \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus/1.0.8/plexus-1.0.8.pom.sha1 b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus/1.0.8/plexus-1.0.8.pom.sha1
new file mode 100644
index 00000000..5234d563
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus/1.0.8/plexus-1.0.8.pom.sha1
@@ -0,0 +1 @@
+9e7c8432829962afe796b32587c1bfa841a317d5 \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus/1.0.9/plexus-1.0.9.pom b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus/1.0.9/plexus-1.0.9.pom
new file mode 100644
index 00000000..f6fca7c8
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus/1.0.9/plexus-1.0.9.pom
@@ -0,0 +1,257 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus</artifactId>
+ <packaging>pom</packaging>
+ <name>Plexus</name>
+ <version>1.0.9</version>
+ <ciManagement>
+ <notifiers>
+ <notifier>
+ <type>mail</type>
+ <configuration>
+ <address>dev@plexus.codehaus.org</address>
+ </configuration>
+ </notifier>
+ <notifier>
+ <type>irc</type>
+ <configuration>
+ <host>irc.codehaus.org</host>
+ <port>6667</port>
+ <channel>#plexus</channel>
+ </configuration>
+ </notifier>
+ </notifiers>
+ </ciManagement>
+ <inceptionYear>2001</inceptionYear>
+ <mailingLists>
+ <mailingList>
+ <name>Plexus User List</name>
+ <subscribe>http://xircles.codehaus.org/manage_email/user%40plexus.codehaus.org</subscribe>
+ <unsubscribe>http://xircles.codehaus.org/manage_email/user%40plexus.codehaus.org</unsubscribe>
+ <archive>http://archive.plexus.codehaus.org/user</archive>
+ </mailingList>
+ <mailingList>
+ <name>Plexus Developer List</name>
+ <subscribe>http://xircles.codehaus.org/manage_email/dev%40plexus.codehaus.org</subscribe>
+ <unsubscribe>http://xircles.codehaus.org/manage_email/dev%40plexus.codehaus.org</unsubscribe>
+ <archive>http://archive.plexus.codehaus.org/dev</archive>
+ </mailingList>
+ <mailingList>
+ <name>Plexus Announce List</name>
+ <subscribe>http://xircles.codehaus.org/manage_email/announce%40plexus.codehaus.org</subscribe>
+ <unsubscribe>http://xircles.codehaus.org/manage_email/announce%40plexus.codehaus.org</unsubscribe>
+ <archive>http://archive.plexus.codehaus.org/announce</archive>
+ </mailingList>
+ <mailingList>
+ <name>Plexus Commit List</name>
+ <subscribe>http://xircles.codehaus.org/manage_email/scm%40plexus.codehaus.org</subscribe>
+ <unsubscribe>http://xircles.codehaus.org/manage_email/scm%40plexus.codehaus.org</unsubscribe>
+ <archive>http://archive.plexus.codehaus.org/scm</archive>
+ </mailingList>
+ </mailingLists>
+ <issueManagement>
+ <system>JIRA</system>
+ <url>http://jira.codehaus.org/browse/PLX</url>
+ </issueManagement>
+
+ <distributionManagement>
+ <repository>
+ <id>codehaus.org</id>
+ <name>Plexus Central Repository</name>
+ <url>dav:https://dav.codehaus.org/repository/plexus</url>
+ </repository>
+ <snapshotRepository>
+ <id>codehaus.org</id>
+ <name>Plexus Central Development Repository</name>
+ <url>dav:https://dav.codehaus.org/snapshots.repository/plexus</url>
+ </snapshotRepository>
+ <site>
+ <id>codehaus.org</id>
+ <url>dav:https://dav.codehaus.org/plexus</url>
+ </site>
+ </distributionManagement>
+ <repositories>
+ <repository>
+ <id>apache-snapshots</id>
+ <name>Snapshot repository</name>
+ <url>http://people.apache.org/maven-snapshot-repository</url>
+ <releases>
+ <enabled>false</enabled>
+ </releases>
+ </repository>
+ <repository>
+ <id>codehaus-snapshots</id>
+ <name>Codehaus Snapshot Development Repository</name>
+ <url>http://snapshots.repository.codehaus.org</url>
+ <releases>
+ <enabled>false</enabled>
+ </releases>
+ </repository>
+ </repositories>
+ <pluginRepositories>
+ <pluginRepository>
+ <id>codehaus-snapshots</id>
+ <name>Codehaus Snapshot Development Repository</name>
+ <url>http://snapshots.repository.codehaus.org</url>
+ <releases>
+ <enabled>false</enabled>
+ </releases>
+ </pluginRepository>
+ </pluginRepositories>
+
+ <developers>
+ <developer>
+ <id>jvanzyl</id>
+ <name>Jason van Zyl</name>
+ <email>jason@maven.org</email>
+ <roles>
+ <role>Developer</role>
+ <role>Release Manager</role>
+ </roles>
+ </developer>
+ <developer>
+ <id>kaz</id>
+ <name>Pete Kazmier</name>
+ <email />
+ <organization />
+ <roles>
+ <role>Developer</role>
+ </roles>
+ </developer>
+ <developer>
+ <id>jtaylor</id>
+ <name>James Taylor</name>
+ <email>james@jamestaylor.org</email>
+ <organization />
+ <roles>
+ <role>Developer</role>
+ </roles>
+ </developer>
+ <developer>
+ <id>dandiep</id>
+ <name>Dan Diephouse</name>
+ <email>dan@envoisolutions.com</email>
+ <organization>Envoi solutions</organization>
+ <roles>
+ <role>Developer</role>
+ </roles>
+ </developer>
+ <developer>
+ <id>kasper</id>
+ <name>Kasper Nielsen</name>
+ <email>apache@kav.dk</email>
+ <organization />
+ <roles>
+ <role>Developer</role>
+ </roles>
+ </developer>
+ <developer>
+ <id>bwalding</id>
+ <name>Ben Walding</name>
+ <email>bwalding@codehaus.org</email>
+ <organization>Walding Consulting Services</organization>
+ <roles>
+ <role>Developer</role>
+ </roles>
+ </developer>
+ <developer>
+ <id>mhw</id>
+ <name>Mark Wilkinson</name>
+ <email>mhw@kremvax.net</email>
+ <roles>
+ <role>Developer</role>
+ </roles>
+ </developer>
+ <developer>
+ <id>michal</id>
+ <name>Michal Maczka</name>
+ <email>mmaczka@interia.pl</email>
+ <roles>
+ <role>Developer</role>
+ </roles>
+ </developer>
+ <developer>
+ <id>evenisse</id>
+ <name>Emmanuel Venisse</name>
+ <email>evenisse@codehaus.org</email>
+ <roles>
+ <role>Developer</role>
+ </roles>
+ </developer>
+ <developer>
+ <name>Trygve Laugstol</name>
+ <id>trygvis</id>
+ <email>trygvis@codehaus.org</email>
+ <roles>
+ <role>Developer</role>
+ </roles>
+ </developer>
+ <developer>
+ <name>Kenney Westerhof</name>
+ <id>kenney</id>
+ <email>kenney@codehaus.org</email>
+ <roles>
+ <role>Developer</role>
+ </roles>
+ </developer>
+ <developer>
+ <name>Carlos Sanchez</name>
+ <id>carlos</id>
+ <email>carlos@codehaus.org</email>
+ <roles>
+ <role>Developer</role>
+ </roles>
+ </developer>
+ <developer>
+ <name>Brett Porter</name>
+ <id>brett</id>
+ <email>brett@codehaus.org</email>
+ <roles>
+ <role>Developer</role>
+ </roles>
+ </developer>
+ <developer>
+ <name>John Casey</name>
+ <id>jdcasey</id>
+ <email>jdcasey@codehaus.org</email>
+ <roles>
+ <role>Developer</role>
+ </roles>
+ </developer>
+ <developer>
+ <name>Andrew Williams</name>
+ <id>handyande</id>
+ <email>andy@handyande.co.uk</email>
+ <roles>
+ <role>Developer</role>
+ </roles>
+ </developer>
+ </developers>
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>3.8.1</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+ <scm>
+ <connection>scm:svn:http://svn.codehaus.org/plexus/pom/tags/plexus-1.0.9</connection>
+ <developerConnection>scm:svn:https://svn.codehaus.org/plexus/pom/tags/plexus-1.0.9</developerConnection>
+ <url>http://fisheye.codehaus.org/browse/plexus/pom/tags/plexus-1.0.9</url>
+ </scm>
+ <organization>
+ <name>Codehaus</name>
+ <url>http://www.codehaus.org/</url>
+ </organization>
+ <build>
+ <extensions>
+ <extension>
+ <groupId>org.apache.maven.wagon</groupId>
+ <artifactId>wagon-webdav</artifactId>
+ <version>1.0-beta-1</version>
+ </extension>
+ </extensions>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus/1.0.9/plexus-1.0.9.pom.md5 b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus/1.0.9/plexus-1.0.9.pom.md5
new file mode 100644
index 00000000..3910bf8b
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus/1.0.9/plexus-1.0.9.pom.md5
@@ -0,0 +1 @@
+acf338e422e5c0d9c6242e4f21e63dc9 \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus/1.0.9/plexus-1.0.9.pom.sha1 b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus/1.0.9/plexus-1.0.9.pom.sha1
new file mode 100644
index 00000000..df40a701
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/org/codehaus/plexus/plexus/1.0.9/plexus-1.0.9.pom.sha1
@@ -0,0 +1 @@
+89d241b1e5ee6a72d3dd95d9eb90f635deebcdb2 \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/repo-marker.txt b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/repo-marker.txt
new file mode 100644
index 00000000..14a481e1
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/extension/test-extension-repo/repo-marker.txt
@@ -0,0 +1 @@
+This is a marker file to allow the repository to be found in the classpath. \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/lifecycle/LifecycleExecutorTest.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/lifecycle/LifecycleExecutorTest.xml
new file mode 100644
index 00000000..ebbbf791
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/lifecycle/LifecycleExecutorTest.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<plexus>
+ <components>
+ <component>
+ <role>org.apache.maven.project.ProjectBuildingHelper</role>
+ <implementation>org.apache.maven.project.EmptyProjectBuildingHelper</implementation>
+ </component>
+ </components>
+</plexus>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/lifecycle/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/lifecycle/pom.xml
new file mode 100644
index 00000000..fb2f91c3
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/lifecycle/pom.xml
@@ -0,0 +1,628 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-parent</artifactId>
+ <version>11</version>
+ <relativePath>../pom/maven/pom.xml</relativePath>
+ </parent>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven</artifactId>
+ <version>3.0-SNAPSHOT</version>
+ <packaging>pom</packaging>
+ <name>Apache Maven</name>
+ <description>Maven is a project development management and
+ comprehension tool. Based on the concept of a project object model:
+ builds, dependency management, documentation creation, site
+ publication, and distribution publication are all controlled from
+ the declarative file. Maven can be extended by plugins to utilise a
+ number of other development tools for reporting or the build
+ process.
+ </description>
+ <url>http://maven.apache.org/</url>
+ <inceptionYear>2001</inceptionYear>
+ <properties>
+ <classWorldsVersion>1.3</classWorldsVersion>
+ <commonsCliVersion>1.0</commonsCliVersion>
+ <!--
+
+ Do not update this, Doxia will be decoupled completely from 3.x and someone can
+ create a rendering engine for it if they like when the release stabilizes. JVZ
+
+ -->
+ <doxiaVersion>1.0-alpha-9</doxiaVersion>
+ <easyMockVersion>1.2_Java1.3</easyMockVersion>
+ <junitVersion>3.8.1</junitVersion>
+ <plexusVersion>1.0-beta-3.0.7-SNAPSHOT</plexusVersion>
+ <plexusInteractivityVersion>1.0-alpha-6</plexusInteractivityVersion>
+ <plexusInterpolationVersion>1.1</plexusInterpolationVersion>
+ <plexusPluginManagerVersion>1.0-alpha-1</plexusPluginManagerVersion>
+ <plexusUtilsVersion>1.5.8</plexusUtilsVersion>
+ <plexusJetty6Version>1.6</plexusJetty6Version>
+ <plexusWebdavVersion>1.0</plexusWebdavVersion>
+ <wagonVersion>1.0-beta-4</wagonVersion>
+ <modelBuilderVersion>1.7-SNAPSHOT</modelBuilderVersion>
+ <mercuryVersion>1.0-alpha-6-SNAPSHOT</mercuryVersion>
+ <mercuryMp3Version>1.0-alpha-1</mercuryMp3Version>
+ <securityDispatcherVersion>1.2</securityDispatcherVersion>
+ <woodstoxVersion>3.2.6</woodstoxVersion>
+ <modelloVersion>1.0.1-SNAPSHOT</modelloVersion>
+ <jxpathVersion>1.3</jxpathVersion>
+ </properties>
+ <issueManagement>
+ <system>jira</system>
+ <url>http://jira.codehaus.org/browse/MNG</url>
+ </issueManagement>
+ <mailingLists>
+ <mailingList>
+ <name>Maven Developer List</name>
+ <subscribe>dev-subscribe@maven.apache.org</subscribe>
+ <unsubscribe>dev-unsubscribe@maven.apache.org</unsubscribe>
+ <post>dev@maven.apache.org</post>
+ <archive>http://mail-archives.apache.org/mod_mbox/maven-dev</archive>
+ <otherArchives>
+ <otherArchive>http://www.mail-archive.com/dev@maven.apache.org/</otherArchive>
+ <otherArchive>http://www.nabble.com/Maven-Developers-f179.html</otherArchive>
+ <otherArchive>http://maven.dev.markmail.org/</otherArchive>
+ </otherArchives>
+ </mailingList>
+ <mailingList>
+ <name>Maven User List</name>
+ <subscribe>users-subscribe@maven.apache.org</subscribe>
+ <unsubscribe>users-unsubscribe@maven.apache.org</unsubscribe>
+ <post>users@maven.apache.org</post>
+ <archive>http://mail-archives.apache.org/mod_mbox/maven-users</archive>
+ <otherArchives>
+ <otherArchive>http://www.mail-archive.com/users@maven.apache.org/</otherArchive>
+ <otherArchive>http://www.nabble.com/Maven---Users-f178.html</otherArchive>
+ <otherArchive>http://maven.users.markmail.org/</otherArchive>
+ </otherArchives>
+ </mailingList>
+ <mailingList>
+ <name>Maven Issues List</name>
+ <subscribe>issues-subscribe@maven.apache.org</subscribe>
+ <unsubscribe>issues-unsubscribe@maven.apache.org</unsubscribe>
+ <archive>http://mail-archives.apache.org/mod_mbox/maven-issues/</archive>
+ <otherArchives>
+ <otherArchive>http://www.mail-archive.com/issues@maven.apache.org</otherArchive>
+ <otherArchive>http://www.nabble.com/Maven---Issues-f15573.html</otherArchive>
+ <otherArchive>http://maven.issues.markmail.org/</otherArchive>
+ </otherArchives>
+ </mailingList>
+ <mailingList>
+ <name>Maven Commits List</name>
+ <subscribe>commits-subscribe@maven.apache.org</subscribe>
+ <unsubscribe>commits-unsubscribe@maven.apache.org</unsubscribe>
+ <archive>http://mail-archives.apache.org/mod_mbox/maven-commits</archive>
+ <otherArchives>
+ <otherArchive>http://www.mail-archive.com/commits@maven.apache.org</otherArchive>
+ <otherArchive>http://www.nabble.com/Maven---Commits-f15575.html</otherArchive>
+ <otherArchive>http://maven.commits.markmail.org/</otherArchive>
+ </otherArchives>
+ </mailingList>
+ <!--
+ duplication from parent pom - temporary until they inherit
+ properly
+ -->
+ <mailingList>
+ <name>Maven Announcements List</name>
+ <post>announce@maven.apache.org</post>
+ <subscribe>announce-subscribe@maven.apache.org</subscribe>
+ <unsubscribe>announce-unsubscribe@maven.apache.org</unsubscribe>
+ <archive>http://mail-archives.apache.org/mod_mbox/maven-announce/</archive>
+ <otherArchives>
+ <otherArchive>http://www.mail-archive.com/announce@maven.apache.org</otherArchive>
+ <otherArchive>http://www.nabble.com/Maven-Announcements-f15617.html</otherArchive>
+ <otherArchive>http://maven.announce.markmail.org/</otherArchive>
+ </otherArchives>
+ </mailingList>
+ <mailingList>
+ <name>Maven Notifications List</name>
+ <subscribe>notifications-subscribe@maven.apache.org</subscribe>
+ <unsubscribe>notifications-unsubscribe@maven.apache.org</unsubscribe>
+ <archive>http://mail-archives.apache.org/mod_mbox/maven-notifications/</archive>
+ <otherArchives>
+ <otherArchive>http://www.mail-archive.com/notifications@maven.apache.org</otherArchive>
+ <otherArchive>http://www.nabble.com/Maven---Notifications-f15574.html</otherArchive>
+ <otherArchive>http://maven.notifications.markmail.org/</otherArchive>
+ </otherArchives>
+ </mailingList>
+ </mailingLists>
+ <scm>
+ <connection>scm:svn:http://svn.apache.org/repos/asf/maven/components/trunk</connection>
+ <developerConnection>scm:svn:https://svn.apache.org/repos/asf/maven/components/trunk</developerConnection>
+ <url>http://svn.apache.org/viewcvs.cgi/maven/components/trunk</url>
+ </scm>
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-component-metadata</artifactId>
+ <version>${plexusVersion}</version>
+ <executions>
+ <execution>
+ <goals>
+ <goal>generate-metadata</goal>
+ <goal>generate-test-metadata</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>2.0.2</version>
+ <configuration>
+ <source>1.5</source>
+ <target>1.5</target>
+ </configuration>
+ </plugin>
+ <plugin>
+ <artifactId>maven-release-plugin</artifactId>
+ <configuration>
+ <tagBase>https://svn.apache.org/repos/asf/maven/components/tags</tagBase>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.modello</groupId>
+ <artifactId>modello-maven-plugin</artifactId>
+ <version>${modelloVersion}</version>
+ <configuration>
+ <useJava5>true</useJava5>
+ </configuration>
+ <executions>
+ <execution>
+ <id>site-docs</id>
+ <phase>pre-site</phase>
+ <goals>
+ <goal>xdoc</goal>
+ <goal>xsd</goal>
+ </goals>
+ </execution>
+ <execution>
+ <id>standard</id>
+ <goals>
+ <goal>java</goal>
+ <goal>xpp3-reader</goal>
+ <goal>xpp3-writer</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <version>1.0.0</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>2.4.2</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <version>2.2-beta-2</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-resources-plugin</artifactId>
+ <version>2.4-SNAPSHOT</version>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+ <modules>
+ <module>maven-core</module>
+ <module>apache-maven</module>
+ <module>maven-model</module>
+ <module>maven-plugin-api</module>
+ <module>maven-project</module>
+ <module>maven-reporting-api</module>
+ <module>maven-project-builder</module>
+ <module>maven-mercury</module>
+ <module>maven-embedder</module>
+ <module>maven-toolchain</module>
+ <module>maven-compat</module>
+ <module>maven-repository</module>
+ <module>maven-repository-mercury</module>
+ </modules>
+ <!--start-->
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>${junitVersion}</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+ <dependencyManagement>
+ <!--end-->
+ <dependencies>
+ <!-- Maven Modules -->
+ <!--start-->
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-mercury</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-lifecycle</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-reporting-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-profile</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-model</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-project</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-plugin-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-toolchain</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-embedder</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-core</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-project-builder</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-repository</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-compat</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <!--end-->
+ <!-- Plexus -->
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-utils</artifactId>
+ <version>${plexusUtilsVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-container-default</artifactId>
+ <version>${plexusVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-component-annotations</artifactId>
+ <version>${plexusVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-classworlds</artifactId>
+ <version>${classWorldsVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-interpolation</artifactId>
+ <version>${plexusInterpolationVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-interactivity-api</artifactId>
+ <version>${plexusInteractivityVersion}</version>
+ <exclusions>
+ <exclusion>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-component-api</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
+ <!-- Plexus test dependencies -->
+ <dependency>
+ <groupId>org.sonatype.plexus</groupId>
+ <artifactId>plexus-jetty6</artifactId>
+ <version>${plexusJetty6Version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.sonatype.spice</groupId>
+ <artifactId>plexus-webdav</artifactId>
+ <version>${plexusWebdavVersion}</version>
+ <scope>test</scope>
+ </dependency>
+
+ <!-- Wagon -->
+ <dependency>
+ <groupId>org.apache.maven.wagon</groupId>
+ <artifactId>wagon-provider-api</artifactId>
+ <version>${wagonVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.wagon</groupId>
+ <artifactId>wagon-file</artifactId>
+ <version>${wagonVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.wagon</groupId>
+ <artifactId>wagon-http</artifactId>
+ <version>${wagonVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.wagon</groupId>
+ <artifactId>wagon-ssh</artifactId>
+ <version>${wagonVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.wagon</groupId>
+ <artifactId>wagon-ssh-external</artifactId>
+ <version>${wagonVersion}</version>
+ </dependency>
+ <!-- Doxia -->
+ <dependency>
+ <groupId>org.apache.maven.doxia</groupId>
+ <artifactId>doxia-sink-api</artifactId>
+ <version>${doxiaVersion}</version>
+ </dependency>
+ <!-- Maven Shared -->
+ <dependency>
+ <groupId>org.sonatype.spice</groupId>
+ <artifactId>model-builder</artifactId>
+ <version>${modelBuilderVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.woodstox</groupId>
+ <artifactId>wstx-asl</artifactId>
+ <version>${woodstoxVersion}</version>
+ </dependency>
+ <!-- Commons -->
+ <dependency>
+ <groupId>commons-cli</groupId>
+ <artifactId>commons-cli</artifactId>
+ <version>${commonsCliVersion}</version>
+ <exclusions>
+ <exclusion>
+ <artifactId>commons-lang</artifactId>
+ <groupId>commons-lang</groupId>
+ </exclusion>
+ <exclusion>
+ <artifactId>commons-logging</artifactId>
+ <groupId>commons-logging</groupId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>commons-jxpath</groupId>
+ <artifactId>commons-jxpath</artifactId>
+ <version>${jxpathVersion}</version>
+ </dependency>
+
+ <!-- Mercury -->
+ <dependency>
+ <groupId>org.apache.maven.mercury</groupId>
+ <artifactId>mercury-artifact</artifactId>
+ <version>${mercuryVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.mercury</groupId>
+ <artifactId>mercury-external</artifactId>
+ <version>${mercuryVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.mercury</groupId>
+ <artifactId>mercury-plexus</artifactId>
+ <version>${mercuryVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.mercury</groupId>
+ <artifactId>mercury-repo-virtual</artifactId>
+ <version>${mercuryVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.sonatype.mercury</groupId>
+ <artifactId>mercury-mp3-cli</artifactId>
+ <version>${mercuryMp3Version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.sonatype.plexus</groupId>
+ <artifactId>plexus-sec-dispatcher</artifactId>
+ <version>${securityDispatcherVersion}</version>
+ </dependency>
+
+
+ <!-- Mercury test dependencies -->
+ <dependency>
+ <groupId>org.apache.maven.mercury</groupId>
+ <artifactId>mercury-repo-local-m2</artifactId>
+ <version>${mercuryVersion}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.mercury</groupId>
+ <artifactId>mercury-repo-remote-m2</artifactId>
+ <version>${mercuryVersion}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.mercury</groupId>
+ <artifactId>mercury-md-sat</artifactId>
+ <version>${mercuryVersion}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.mercury</groupId>
+ <artifactId>mercury-util</artifactId>
+ <version>${mercuryVersion}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.mercury</groupId>
+ <artifactId>mercury-transport-http</artifactId>
+ <version>${mercuryVersion}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.mercury</groupId>
+ <artifactId>mercury-transport-http</artifactId>
+ <version>${mercuryVersion}</version>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.sonatype.plexus</groupId>
+ <artifactId>plexus-plugin-manager</artifactId>
+ <version>${plexusPluginManagerVersion}</version>
+ </dependency>
+ <!--start-->
+ <dependency>
+ <groupId>easymock</groupId>
+ <artifactId>easymock</artifactId>
+ <version>${easyMockVersion}</version>
+ <scope>test</scope>
+ </dependency>
+ <!--end-->
+ </dependencies>
+ <!--start-->
+ </dependencyManagement>
+ <!--end-->
+ <distributionManagement>
+ <site>
+ <id>apache.website</id>
+ <url>scp://people.apache.org/www/maven.apache.org/ref/${project.version}/</url>
+ </site>
+ </distributionManagement>
+ <profiles>
+ <profile>
+ <id>osgi</id>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <executions>
+ <execution>
+ <goals>
+ <goal>manifest</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <!-- Needed for including the manifest, see MJAR-71 -->
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <version>2.1</version>
+ <configuration>
+ <archive>
+ <manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
+ </archive>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ <profile>
+ <id>release</id>
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <inherited>false</inherited>
+ <configuration>
+ <descriptors>
+ <descriptor>src/main/assembly/src.xml</descriptor>
+ </descriptors>
+ <tarLongFileMode>gnu</tarLongFileMode>
+ <finalName>maven-${project.version}-src</finalName>
+ </configuration>
+ <executions>
+ <execution>
+ <id>make-assembly</id>
+ <phase>package</phase>
+ <goals>
+ <goal>single</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ <profile>
+ <id>strict</id>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-enforcer-plugin</artifactId>
+ <version>1.0-alpha-3</version>
+ <executions>
+ <execution>
+ <id>enforce-jdk-15</id>
+ <goals>
+ <goal>enforce</goal>
+ </goals>
+ <configuration>
+ <rules>
+ <requireJavaVersion>
+ <version>1.5</version>
+ </requireJavaVersion>
+ </rules>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/plugin/PluginManagerTest.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/plugin/PluginManagerTest.xml
new file mode 100644
index 00000000..ebbbf791
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/plugin/PluginManagerTest.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<plexus>
+ <components>
+ <component>
+ <role>org.apache.maven.project.ProjectBuildingHelper</role>
+ <implementation>org.apache.maven.project.EmptyProjectBuildingHelper</implementation>
+ </component>
+ </components>
+</plexus>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/project/AbstractMavenProjectTestCase.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/project/AbstractMavenProjectTestCase.xml
new file mode 100644
index 00000000..e052489b
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/project/AbstractMavenProjectTestCase.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<plexus>
+ <components>
+ <component>
+ <role>org.apache.maven.lifecycle.LifeCyclePluginAnalyzer</role>
+ <implementation>org.apache.maven.lifecycle.EmptyLifecyclePluginAnalyzer</implementation>
+ </component>
+ </components>
+</plexus>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/project/PomConstructionTest.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/project/PomConstructionTest.xml
new file mode 100644
index 00000000..e3c3ab34
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/project/PomConstructionTest.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<plexus>
+ <components>
+ <component>
+ <role>org.apache.maven.lifecycle.LifeCyclePluginAnalyzer</role>
+ <implementation>org.apache.maven.lifecycle.EmptyLifecyclePluginAnalyzer</implementation>
+ </component>
+ <component>
+ <role>org.apache.maven.project.ProjectBuildingHelper</role>
+ <implementation>org.apache.maven.project.EmptyProjectBuildingHelper</implementation>
+ </component>
+ </components>
+</plexus>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/project/workspace/buildFromFile/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/project/workspace/buildFromFile/pom.xml
new file mode 100644
index 00000000..c8a8b85f
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/project/workspace/buildFromFile/pom.xml
@@ -0,0 +1,8 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.tests</groupId>
+ <artifactId>build-from-file</artifactId>
+ <version>1</version>
+
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/project/workspace/buildFromRepo/tests/project-caching/1/project-caching-1.pom b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/project/workspace/buildFromRepo/tests/project-caching/1/project-caching-1.pom
new file mode 100644
index 00000000..d4211765
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/project/workspace/buildFromRepo/tests/project-caching/1/project-caching-1.pom
@@ -0,0 +1,8 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>tests</groupId>
+ <artifactId>project-caching</artifactId>
+ <version>1</version>
+
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/project/workspace/buildFromRepo/tests/project-caching/maven-metadata-local.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/project/workspace/buildFromRepo/tests/project-caching/maven-metadata-local.xml
new file mode 100644
index 00000000..a608b4f8
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/project/workspace/buildFromRepo/tests/project-caching/maven-metadata-local.xml
@@ -0,0 +1,11 @@
+<metadata>
+ <groupId>tests</groupId>
+ <artifactId>project-caching</artifactId>
+ <versioning>
+ <release>1</release>
+ <latest>1</latest>
+ <versions>
+ <version>1</version>
+ </versions>
+ </versioning>
+</metadata> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/project/workspace/buildModelLineage/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/project/workspace/buildModelLineage/pom.xml
new file mode 100644
index 00000000..8f5154fc
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/project/workspace/buildModelLineage/pom.xml
@@ -0,0 +1,7 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>tests</groupId>
+ <artifactId>build-model-lineage</artifactId>
+ <version>1</version>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/project/workspace/resolveParentPom/childAndParent/child/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/project/workspace/resolveParentPom/childAndParent/child/pom.xml
new file mode 100644
index 00000000..4d1d23ee
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/project/workspace/resolveParentPom/childAndParent/child/pom.xml
@@ -0,0 +1,10 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>tests</groupId>
+ <artifactId>childAndParent-parent</artifactId>
+ <version>1</version>
+ </parent>
+
+ <artifactId>childAndParent-child</artifactId>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/project/workspace/resolveParentPom/childAndParent/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/project/workspace/resolveParentPom/childAndParent/pom.xml
new file mode 100644
index 00000000..164506fe
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/project/workspace/resolveParentPom/childAndParent/pom.xml
@@ -0,0 +1,7 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>tests</groupId>
+ <artifactId>childAndParent-parent</artifactId>
+ <version>1</version>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/project/workspace/resolveParentPom/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/project/workspace/resolveParentPom/pom.xml
new file mode 100644
index 00000000..9633029a
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/project/workspace/resolveParentPom/pom.xml
@@ -0,0 +1,10 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>tests</groupId>
+ <artifactId>resolve-parent-pom-parent</artifactId>
+ <version>1</version>
+ </parent>
+
+ <artifactId>resolve-parent-pom</artifactId>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/settings/PomConstructionWithSettingsTest.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/settings/PomConstructionWithSettingsTest.xml
new file mode 100644
index 00000000..c6769290
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/settings/PomConstructionWithSettingsTest.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<plexus>
+ <components>
+ <component>
+ <role>org.apache.maven.lifecycle.LifecycleExecutor</role>
+ <implementation>org.apache.maven.project.EmptyLifecycleExecutor</implementation>
+ </component>
+ </components>
+</plexus>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/toolchain/global.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/toolchain/global.xml
new file mode 100644
index 00000000..cd9be74c
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/toolchain/global.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<toolchains>
+ <toolchain>
+ <type>basic</type>
+ <configuration>
+ <global>true</global>
+ </configuration>
+ </toolchain>
+ <toolchain>
+ <type>rare</type>
+ <configuration>
+ <global>true</global>
+ </configuration>
+ </toolchain>
+</toolchains> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/toolchain/model/toolchains-jdks-extend.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/toolchain/model/toolchains-jdks-extend.xml
new file mode 100644
index 00000000..4fb00930
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/toolchain/model/toolchains-jdks-extend.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<toolchains>
+ <toolchain>
+ <type>jdk</type>
+ <provides>
+ <version>1.5</version>
+ <vendor>sun</vendor>
+ </provides>
+ <configuration>
+ <jdkHome>${env.JAVA_HOME}</jdkHome>
+ <toolsJar>lib/tools.jar</toolsJar>
+ </configuration>
+ </toolchain>
+ <toolchain>
+ <type>jdk</type>
+ <provides>
+ <version>1.6</version>
+ <vendor>sun</vendor>
+ </provides>
+ <configuration>
+ <jdkHome>${env.JAVA_HOME}</jdkHome>
+ <toolsJar>lib/classes.jar</toolsJar>
+ </configuration>
+ </toolchain>
+</toolchains> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/toolchain/model/toolchains-jdks-extra.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/toolchain/model/toolchains-jdks-extra.xml
new file mode 100644
index 00000000..35c32172
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/toolchain/model/toolchains-jdks-extra.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<toolchains>
+ <toolchain>
+ <type>jdk</type>
+ <provides>
+ <version>1.4</version>
+ <vendor>sun</vendor>
+ <!-- no id, so it's considered 'default' -->
+ </provides>
+ <configuration>
+ <jdkHome>${env.JAVA_HOME}</jdkHome>
+ </configuration>
+ </toolchain>
+ <toolchain>
+ <type>jdk</type>
+ <provides>
+ <version>1.7</version>
+ <vendor>ibm</vendor>
+ <id>ibm_17</id>
+ </provides>
+ <configuration>
+ <jdkHome>${env.JAVA_HOME}</jdkHome>
+ </configuration>
+ </toolchain>
+</toolchains> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/toolchain/model/toolchains-jdks.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/toolchain/model/toolchains-jdks.xml
new file mode 100644
index 00000000..5233a338
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/toolchain/model/toolchains-jdks.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<toolchains>
+ <toolchain>
+ <type>jdk</type>
+ <provides>
+ <version>1.5</version>
+ <vendor>sun</vendor>
+ </provides>
+ <configuration>
+ <jdkHome>${env.JAVA_HOME}</jdkHome>
+ </configuration>
+ </toolchain>
+ <toolchain>
+ <type>jdk</type>
+ <provides>
+ <version>1.6</version>
+ <vendor>sun</vendor>
+ </provides>
+ <configuration>
+ <jdkHome>${env.JAVA_HOME}</jdkHome>
+ </configuration>
+ </toolchain>
+</toolchains> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/toolchain/user.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/toolchain/user.xml
new file mode 100644
index 00000000..d11181fc
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/apache/maven/toolchain/user.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<toolchains>
+ <toolchain>
+ <type>basic</type>
+ <configuration>
+ <user>true</user>
+ </configuration>
+ </toolchain>
+ <toolchain>
+ <type>rare</type>
+ <configuration>
+ <user>true</user>
+ </configuration>
+ </toolchain>
+</toolchains> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/codehaus/plexus/plexus-utils/1.1/plexus-utils-1.1.jar b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/codehaus/plexus/plexus-utils/1.1/plexus-utils-1.1.jar
new file mode 100644
index 00000000..5c50e177
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/codehaus/plexus/plexus-utils/1.1/plexus-utils-1.1.jar
Binary files differ
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/codehaus/plexus/plexus-utils/1.1/plexus-utils-1.1.jar.sha1 b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/codehaus/plexus/plexus-utils/1.1/plexus-utils-1.1.jar.sha1
new file mode 100644
index 00000000..28f6dbb5
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/codehaus/plexus/plexus-utils/1.1/plexus-utils-1.1.jar.sha1
@@ -0,0 +1 @@
+fa632b7f1cb7c50963d0fb7d818ca93c75c10127 \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/codehaus/plexus/plexus-utils/1.1/plexus-utils-1.1.pom b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/codehaus/plexus/plexus-utils/1.1/plexus-utils-1.1.pom
new file mode 100644
index 00000000..6cf90799
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/codehaus/plexus/plexus-utils/1.1/plexus-utils-1.1.pom
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?><project>
+ <parent>
+ <artifactId>plexus</artifactId>
+ <groupId>org.codehaus.plexus</groupId>
+ <version>1.0.4</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>plexus-utils</artifactId>
+ <name>Plexus Common Utilities</name>
+ <version>1.1</version>
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <excludes>
+ <exclude>org/codehaus/plexus/util/FileBasedTestCase.java</exclude>
+ <exclude>**/Test*.java</exclude>
+ </excludes>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ <distributionManagement>
+ <status>deployed</status>
+ </distributionManagement>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/codehaus/plexus/plexus-utils/1.1/plexus-utils-1.1.pom.sha1 b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/codehaus/plexus/plexus-utils/1.1/plexus-utils-1.1.pom.sha1
new file mode 100644
index 00000000..4dc64d4a
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/org/codehaus/plexus/plexus-utils/1.1/plexus-utils-1.1.pom.sha1
@@ -0,0 +1 @@
+15492ecd00920daca9ec15f6acd695b626621e5b \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/pom.xml
new file mode 100644
index 00000000..cf4c29c0
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/pom.xml
@@ -0,0 +1,52 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-core</artifactId>
+ <version>2.0-SNAPSHOT</version>
+ <packaging>jar</packaging>
+
+ <name>Maven</name>
+ <inceptionYear>2001</inceptionYear>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-model</artifactId>
+ <version>2.0-SNAPSHOT</version>
+ <type>jar</type>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-plugin</artifactId>
+ <version>2.0-SNAPSHOT</version>
+ <type>jar</type>
+ <scope>compile</scope>
+ </dependency>
+ </dependencies>
+
+ <scm>
+ <connection>scm-connection</connection>
+ </scm>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/project-dynamism/plugin-level-dep.pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/project-dynamism/plugin-level-dep.pom.xml
new file mode 100644
index 00000000..98873675
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/project-dynamism/plugin-level-dep.pom.xml
@@ -0,0 +1,24 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>testing</groupId>
+ <artifactId>plugin-level-dep</artifactId>
+ <packaging>jar</packaging>
+ <version>3.8.1</version>
+
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>2.0.2</version>
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>${pom.version}</version>
+ </dependency>
+ </dependencies>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/project-dynamism/pom-interp.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/project-dynamism/pom-interp.xml
new file mode 100644
index 00000000..40fdb414
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/project-dynamism/pom-interp.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.test</groupId>
+ <artifactId>test-build-dynamism</artifactId>
+ <version>1</version>
+
+ <build>
+ <sourceDirectory>/${project.groupId}/src/main/java</sourceDirectory>
+ <testSourceDirectory>/${pom.groupId}/src/test/java</testSourceDirectory>
+ <scriptSourceDirectory>/${groupId}/src/main/scripts</scriptSourceDirectory>
+
+ <plugins>
+ <plugin>
+ <artifactId>my-plugin</artifactId>
+ <configuration>
+ <testOne>${project.groupId}</testOne>
+ <testTwo>${pom.groupId}</testTwo>
+ <testThree>${groupId}</testThree>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/project-dynamism/pom-relative.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/project-dynamism/pom-relative.xml
new file mode 100644
index 00000000..bb22b3d0
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/project-dynamism/pom-relative.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.test</groupId>
+ <artifactId>test-build-dynamism</artifactId>
+ <version>1</version>
+
+ <properties>
+ <myProperty>${pom.build.directory}</myProperty>
+ </properties>
+
+ <build>
+ <resources>
+ <resource>
+ <directory>${pom.build.directory}/generated-resources/plexus</directory>
+ </resource>
+ </resources>
+
+ <filters>
+ <filter>${pom.build.directory}/generated-filters.properties</filter>
+ </filters>
+
+ <directory>target</directory>
+
+ <sourceDirectory>src/main/java</sourceDirectory>
+ <testSourceDirectory>src/test/java</testSourceDirectory>
+ <scriptSourceDirectory>src/main/scripts</scriptSourceDirectory>
+
+ <outputDirectory>${pom.build.directory}/classes</outputDirectory>
+ <testOutputDirectory>${pom.build.directory}/test-classes</testOutputDirectory>
+ </build>
+
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/project-dynamism/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/project-dynamism/pom.xml
new file mode 100644
index 00000000..37797f2e
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/project-dynamism/pom.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.test</groupId>
+ <artifactId>test-build-dynamism</artifactId>
+ <version>1</version>
+
+ <properties>
+ <myProperty>${pom.build.directory}</myProperty>
+ </properties>
+
+ <build>
+ <resources>
+ <resource>
+ <directory>${pom.build.directory}/generated-resources/plexus</directory>
+ </resource>
+ </resources>
+
+ <filters>
+ <filter>${pom.build.directory}/generated-filters.properties</filter>
+ </filters>
+
+ <directory>target</directory>
+
+ <sourceDirectory>${pom.basedir}/src/main/java</sourceDirectory>
+ <testSourceDirectory>${pom.basedir}/src/test/java</testSourceDirectory>
+ <scriptSourceDirectory>${pom.basedir}/src/main/scripts</scriptSourceDirectory>
+
+ <outputDirectory>${pom.build.directory}/classes</outputDirectory>
+ <testOutputDirectory>${pom.build.directory}/test-classes</testOutputDirectory>
+ </build>
+
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/projects/bad-dependency.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/projects/bad-dependency.xml
new file mode 100644
index 00000000..4b5424ae
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/projects/bad-dependency.xml
@@ -0,0 +1,27 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>test</groupId>
+ <artifactId>invalid</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+
+ <repositories>
+ <repository>
+ <id>central</id>
+ <url>file:src/test/remote-repo</url>
+ </repository>
+ </repositories>
+
+ <dependencies>
+ <dependency>
+ <!-- groupId deliberately missing -->
+ <artifactId>b</artifactId>
+ <version>0.1</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.its</groupId>
+ <artifactId>a</artifactId>
+ <version>0.1</version>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/projects/bad-project.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/projects/bad-project.xml
new file mode 100644
index 00000000..e415318c
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/projects/bad-project.xml
@@ -0,0 +1,20 @@
+i want to be a <!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+POM! \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/projects/base-directory-alignment/project-which-needs-directory-alignment-child.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/projects/base-directory-alignment/project-which-needs-directory-alignment-child.xml
new file mode 100644
index 00000000..ee2207ee
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/projects/base-directory-alignment/project-which-needs-directory-alignment-child.xml
@@ -0,0 +1,33 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+
+ <extend>project-which-needs-directory-alignment.xml</extend>
+
+ <parent>
+ <groupId>maven</groupId>
+ <artifactId>project-which-needs-directory-alignment.xml</artifactId>
+ <version>1.0-beta-9</version>
+ </parent>
+
+ <groupId>maven</groupId>
+ <artifactId>maven-foo</artifactId>
+ <version>1.0</version>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/projects/base-directory-alignment/project-which-needs-directory-alignment.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/projects/base-directory-alignment/project-which-needs-directory-alignment.xml
new file mode 100644
index 00000000..cefbcb04
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/projects/base-directory-alignment/project-which-needs-directory-alignment.xml
@@ -0,0 +1,135 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>maven</groupId>
+ <artifactId>project-which-needs-directory-alignment</artifactId>
+ <name>Maven</name>
+ <version>1.0-beta-9</version>
+ <inceptionYear>2001</inceptionYear>
+ <description>Description</description>
+ <url>http://maven.apache.org/</url>
+
+ <organization>
+ <name>Apache Software Foundation</name>
+ <url>http://apache.org/</url>
+ </organization>
+
+ <scm>
+ <connection>anon-connection</connection>
+ <developerConnection>developer-connection</developerConnection>
+ <url>repository-url</url>
+ </scm>
+
+ <mailingLists>
+ <mailingList>
+ <name>Maven User List</name>
+ <subscribe>subscribe</subscribe>
+ <unsubscribe>unsubscribe</unsubscribe>
+ <archive>archive</archive>
+ </mailingList>
+ </mailingLists>
+
+ <developers>
+ <developer>
+ <name>Jason van Zyl</name>
+ <id>jvanzyl</id>
+ <email>jason@maven.org</email>
+ <organization>Zenplex</organization>
+ <roles>
+ <role>Founder</role>
+ <role>Release Manager</role>
+ </roles>
+ </developer>
+ </developers>
+
+ <contributors>
+ <contributor>
+ <name>Martin van dem Bemt</name>
+ <email>mvdb@mvdb.com</email>
+ </contributor>
+ </contributors>
+
+ <dependencies>
+
+ <dependency>
+ <groupId>g1</groupId>
+ <artifactId>d1</artifactId>
+ <version>1.0</version>
+ </dependency>
+
+ <dependency>
+ <groupId>g2</groupId>
+ <artifactId>d2</artifactId>
+ <version>2.0</version>
+ </dependency>
+
+ <dependency>
+ <groupId>g3</groupId>
+ <artifactId>d3</artifactId>
+ </dependency>
+
+ </dependencies>
+
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>g3</groupId>
+ <artifactId>d3</artifactId>
+ <version>3.0</version>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+
+ <build>
+ <sourceDirectory>sourceDirectory</sourceDirectory>
+ <testSourceDirectory>unitTestSourceDirectory</testSourceDirectory>
+ <resources>
+ <resource>
+ <directory>src/test</directory>
+ <includes>
+ <include>**/*.xml</include>
+ </includes>
+ </resource>
+ </resources>
+ <testResources>
+ <testResource>
+ <directory>src/conf</directory>
+ <includes>
+ <include>*.xsd</include>
+ <include>*.dtd</include>
+ <include>*.mod</include>
+ <include>log4j.properties</include>
+ <include>driver.jelly</include>
+ <include>driver.properties</include>
+ </includes>
+ </testResource>
+ <testResource>
+ <directory>src/messages</directory>
+ <targetPath>org/apache/maven/messages</targetPath>
+ <includes>
+ <include>messages*.properties</include>
+ </includes>
+ </testResource>
+ </testResources>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/projects/base-directory-alignment/subproject/project-which-needs-directory-alignment-child.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/projects/base-directory-alignment/subproject/project-which-needs-directory-alignment-child.xml
new file mode 100644
index 00000000..68775efc
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/projects/base-directory-alignment/subproject/project-which-needs-directory-alignment-child.xml
@@ -0,0 +1,29 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+
+ <extend>../project-which-needs-directory-alignment.xml</extend>
+
+ <parent>
+ <groupId>maven</groupId>
+ <artifactId>project-which-needs-directory-alignment</artifactId>
+ <version>1.0-beta-9</version>
+ </parent>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/projects/build-path-expression-pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/projects/build-path-expression-pom.xml
new file mode 100644
index 00000000..d7e296f4
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/projects/build-path-expression-pom.xml
@@ -0,0 +1,14 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven.project.tests</groupId>
+ <artifactId>build-path-expression</artifactId>
+ <version>1</version>
+ <build>
+ <sourceDirectory>sources</sourceDirectory>
+ <resources>
+ <resource>
+ <directory>${project.build.sourceDirectory}</directory>
+ </resource>
+ </resources>
+ </build>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/projects/build.properties b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/projects/build.properties
new file mode 100644
index 00000000..01626c39
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/projects/build.properties
@@ -0,0 +1,18 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+name = sarel
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/projects/child-which-inherits-from-super-model.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/projects/child-which-inherits-from-super-model.xml
new file mode 100644
index 00000000..58cae23e
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/projects/child-which-inherits-from-super-model.xml
@@ -0,0 +1,28 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<model>
+ <groupId>foo</groupId>
+ <artifactId>bar</artifactId>
+ <name>Babar</name>
+ <version>4.5</version>
+
+ <!-- Build element should be inherited from the super model -->
+
+</model>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/projects/child-with-bogus-parent.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/projects/child-with-bogus-parent.xml
new file mode 100644
index 00000000..a072fc74
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/projects/child-with-bogus-parent.xml
@@ -0,0 +1,29 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<model>
+
+ <extend>${basedir}/bogus.xml</extend>
+
+ <parent>
+ <groupId>maven</groupId>
+ <artifactId>bogus</artifactId>
+ <version>1.0-beta-9</version>
+ </parent>
+</model>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/projects/child.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/projects/child.xml
new file mode 100644
index 00000000..a6d702ce
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/projects/child.xml
@@ -0,0 +1,33 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<model>
+
+ <extend>project.xml</extend>
+
+ <parent>
+ <groupId>maven</groupId>
+ <artifactId>maven-project-test</artifactId>
+ <version>1.0-beta-9</version>
+ </parent>
+
+ <artifactId>child-artifact</artifactId>
+ <groupId>maven</groupId>
+ <version>1.0-beta-9</version>
+</model>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/projects/duplicate-plugins-merged-pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/projects/duplicate-plugins-merged-pom.xml
new file mode 100644
index 00000000..7383109f
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/projects/duplicate-plugins-merged-pom.xml
@@ -0,0 +1,48 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>tests.project</groupId>
+ <artifactId>duplicate-plugin-defs-merged</artifactId>
+ <version>1</version>
+
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <dependencies>
+ <dependency>
+ <groupId>group</groupId>
+ <artifactId>first</artifactId>
+ <version>1</version>
+ </dependency>
+ </dependencies>
+ <executions>
+ <execution>
+ <id>first</id>
+ <goals>
+ <goal>compile</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <dependencies>
+ <dependency>
+ <groupId>group</groupId>
+ <artifactId>second</artifactId>
+ <version>1</version>
+ </dependency>
+ </dependencies>
+ <executions>
+ <execution>
+ <id>second</id>
+ <goals>
+ <goal>compile</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/projects/fully-populated-child.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/projects/fully-populated-child.xml
new file mode 100644
index 00000000..61d6b672
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/projects/fully-populated-child.xml
@@ -0,0 +1,168 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<model>
+ <extend>project.xml</extend>
+ <parent>
+ <groupId>maven</groupId>
+ <artifactId>maven-project-test</artifactId>
+ <version>1.0-beta-9</version>
+ </parent>
+ <modelVersion>3</modelVersion>
+ <groupId>maven</groupId>
+ <artifactId>maven</artifactId>
+ <name>Maven</name>
+ <version>1.0-beta-9</version>
+ <inceptionYear>2001</inceptionYear>
+ <package>org.apache.maven</package>
+ <description>Description</description>
+ <shortDescription>shortDescription</shortDescription>
+ <url>http://maven.apache.org/</url>
+ <issueTrackingUrl>issueTrackingUrl</issueTrackingUrl>
+ <distributionManagement>
+ <repository>
+ <id>childDistributionRepositoryId</id>
+ <name>childDistributionRepositoryName</name>
+ <url>childDistributionRepository</url>
+ </repository>
+ <site>
+ <id>childSiteDistributionId</id>
+ <name>childSiteDistributionName</name>
+ <url>childSiteDistributionUrl</url>
+ </site>
+ </distributionManagement>
+
+ <organization>
+ <name>Apache Software Foundation</name>
+ <url>http://apache.org/</url>
+ <logo>/images/jakarta-logo-blue.gif</logo>
+ </organization>
+
+ <scm>
+ <connection>anon-connection</connection>
+ <developerConnection>developer-connection</developerConnection>
+ <url>repository-url</url>
+ </scm>
+
+ <mailingLists>
+ <mailingList>
+ <name>Maven User List</name>
+ <subscribe>subscribe</subscribe>
+ <unsubscribe>unsubscribe</unsubscribe>
+ <archive>archive</archive>
+ </mailingList>
+ </mailingLists>
+
+ <developers>
+ <developer>
+ <name>Jason van Zyl</name>
+ <id>jvanzyl</id>
+ <email>jason@maven.org</email>
+ <organization>Zenplex</organization>
+ <roles>
+ <role>Founder</role>
+ <role>Release Manager</role>
+ </roles>
+ </developer>
+ </developers>
+
+ <contributors>
+ <contributor>
+ <name>Martin van dem Bemt</name>
+ <email>mvdb@mvdb.com</email>
+ </contributor>
+ </contributors>
+
+ <dependencies>
+
+ <dependency>
+ <groupId>g1</groupId>
+ <artifactId>d1</artifactId>
+ <version>1.0</version>
+ <url>d1-url</url>
+ </dependency>
+
+ <dependency>
+ <groupId>g2</groupId>
+ <artifactId>d2</artifactId>
+ <version>2.0</version>
+ <url>d2-url</url>
+ </dependency>
+
+ </dependencies>
+
+ <build>
+ <nagEmailAddress>jason@maven.org</nagEmailAddress>
+ <sourceDirectory>/sourceDirectory</sourceDirectory>
+ <unitTestSourceDirectory>/unitTestSourceDirectory</unitTestSourceDirectory>
+ <unitTest>
+ <includes>
+ <include>**/*Test.java</include>
+ </includes>
+ <excludes>
+ <exclude>**/RepositoryTest.java</exclude>
+ <exclude>**/JAXPTest.java</exclude>
+ </excludes>
+ <resources>
+ <resource>
+ <directory>${basedir}/src/test</directory>
+ <includes>
+ <include>**/*.xml</include>
+ </includes>
+ </resource>
+ </resources>
+ </unitTest>
+ <resources>
+ <resource>
+ <directory>/src/conf</directory>
+ <includes>
+ <include>*.xsd</include>
+ <include>*.dtd</include>
+ <include>*.mod</include>
+ <include>log4j.properties</include>
+ <include>driver.jelly</include>
+ <include>driver.properties</include>
+ </includes>
+ </resource>
+ <resource>
+ <directory>/src/messages</directory>
+ <targetPath>org/apache/maven/messages</targetPath>
+ <includes>
+ <include>messages*.properties</include>
+ </includes>
+ </resource>
+ </resources>
+ </build>
+
+ <reports>
+ <report>maven-jdepend-plugin</report>
+ <report>maven-checkstyle-plugin</report>
+ <report>maven-changelog-plugin</report>
+ <report>maven-file-activity-plugin</report>
+ <report>maven-developer-activity-plugin</report>
+ <report>maven-javadoc-plugin</report>
+ <report>maven-jxr-plugin</report>
+ <report>maven-junit-report-plugin</report>
+ <report>maven-tasklist-plugin</report>
+ <report>maven-jellydoc-plugin</report>
+ </reports>
+
+</model>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/projects/grandchild-check/child/grandchild/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/projects/grandchild-check/child/grandchild/pom.xml
new file mode 100644
index 00000000..56bed2c9
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/projects/grandchild-check/child/grandchild/pom.xml
@@ -0,0 +1,10 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>grandchildtest</groupId>
+ <artifactId>child</artifactId>
+ <version>1</version>
+ </parent>
+ <artifactId>grandchild</artifactId>
+
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/projects/grandchild-check/child/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/projects/grandchild-check/child/pom.xml
new file mode 100644
index 00000000..0858c6d1
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/projects/grandchild-check/child/pom.xml
@@ -0,0 +1,13 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>grandchildtest</groupId>
+ <artifactId>root-pom</artifactId>
+ <version>1</version>
+ </parent>
+ <artifactId>child</artifactId>
+ <packaging>pom</packaging>
+ <modules>
+ <module>grandchild</module>
+ </modules>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/projects/grandchild-check/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/projects/grandchild-check/pom.xml
new file mode 100644
index 00000000..3b1ebd0e
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/projects/grandchild-check/pom.xml
@@ -0,0 +1,7 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>grandchildtest</groupId>
+ <artifactId>root-pom</artifactId>
+ <version>1</version>
+ <packaging>pom</packaging>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/projects/import-scope-pom-resolves-from-property-based-repository.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/projects/import-scope-pom-resolves-from-property-based-repository.xml
new file mode 100644
index 00000000..4c29a3b9
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/projects/import-scope-pom-resolves-from-property-based-repository.xml
@@ -0,0 +1,31 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>test</groupId>
+ <artifactId>imported-pom-found</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+
+ <properties>
+ <repo.url>file:src/test/remote-repo</repo.url>
+ </properties>
+
+ <repositories>
+ <repository>
+ <id>central</id>
+ <url>${repo.url}</url>
+ </repository>
+ </repositories>
+
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven.its</groupId>
+ <artifactId>a</artifactId>
+ <version>0.1</version>
+ <type>pom</type>
+ <scope>import</scope>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/projects/modelsource/module01/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/projects/modelsource/module01/pom.xml
new file mode 100644
index 00000000..cfaf9e8f
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/projects/modelsource/module01/pom.xml
@@ -0,0 +1,12 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>test.readparent</groupId>
+ <artifactId>local-parent</artifactId>
+ <version>1.0</version>
+ </parent>
+
+ <artifactId>module01</artifactId>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/projects/modelsource/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/projects/modelsource/pom.xml
new file mode 100644
index 00000000..0fe29370
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/projects/modelsource/pom.xml
@@ -0,0 +1,13 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>test.readparent</groupId>
+ <artifactId>local-parent</artifactId>
+ <packaging>pom</packaging>
+ <version>1.0</version>
+
+ <modules>
+ <module>module</module>
+ </modules>
+
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/projects/project.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/projects/project.xml
new file mode 100644
index 00000000..a9119714
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/projects/project.xml
@@ -0,0 +1,162 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<model>
+ <modelVersion>3</modelVersion>
+ <groupId>maven</groupId>
+ <artifactId>maven-project-test</artifactId>
+ <name>Maven</name>
+ <version>1.0-beta-9</version>
+ <inceptionYear>2001</inceptionYear>
+ <package>org.apache.maven</package>
+ <description>Description</description>
+ <shortDescription>shortDescription</shortDescription>
+ <url>http://maven.apache.org/</url>
+ <issueTrackingUrl>issueTrackingUrl</issueTrackingUrl>
+ <distributionManagement>
+ <repository>
+ <id>distributionRepositoryId</id>
+ <name>distributionRepositoryName</name>
+ <url>distributionRepository</url>
+ </repository>
+ <site>
+ <id>siteDistributionId</id>
+ <name>siteDistributionName</name>
+ <url>siteDistributionUrl</url>
+ </site>
+ </distributionManagement>
+
+ <organization>
+ <name>Apache Software Foundation</name>
+ <url>http://apache.org/</url>
+ <logo>/images/jakarta-logo-blue.gif</logo>
+ </organization>
+
+ <scm>
+ <connection>anon-connection</connection>
+ <developerConnection>developer-connection</developerConnection>
+ <url>repository-url</url>
+ </scm>
+
+ <mailingLists>
+ <mailingList>
+ <name>Maven User List</name>
+ <subscribe>subscribe</subscribe>
+ <unsubscribe>unsubscribe</unsubscribe>
+ <archive>archive</archive>
+ </mailingList>
+ </mailingLists>
+
+ <developers>
+ <developer>
+ <name>Jason van Zyl</name>
+ <id>jvanzyl</id>
+ <email>jason@maven.org</email>
+ <organization>Zenplex</organization>
+ <roles>
+ <role>Founder</role>
+ <role>Release Manager</role>
+ </roles>
+ </developer>
+ </developers>
+
+ <contributors>
+ <contributor>
+ <name>Martin van dem Bemt</name>
+ <email>mvdb@mvdb.com</email>
+ </contributor>
+ </contributors>
+
+ <dependencies>
+
+ <dependency>
+ <groupId>g1</groupId>
+ <artifactId>d1</artifactId>
+ <version>1.0</version>
+ <url>d1-url</url>
+ </dependency>
+
+ <dependency>
+ <groupId>g2</groupId>
+ <artifactId>d2</artifactId>
+ <version>2.0</version>
+ <url>d2-url</url>
+ </dependency>
+
+ </dependencies>
+
+ <build>
+ <nagEmailAddress>jason@maven.org</nagEmailAddress>
+ <sourceDirectory>/sourceDirectory</sourceDirectory>
+ <unitTestSourceDirectory>/unitTestSourceDirectory</unitTestSourceDirectory>
+ <unitTest>
+ <includes>
+ <include>**/*Test.java</include>
+ </includes>
+ <excludes>
+ <exclude>**/RepositoryTest.java</exclude>
+ <exclude>**/JAXPTest.java</exclude>
+ </excludes>
+ <resources>
+ <resource>
+ <directory>${basedir}/src/test</directory>
+ <includes>
+ <include>**/*.xml</include>
+ </includes>
+ </resource>
+ </resources>
+ </unitTest>
+ <resources>
+ <resource>
+ <directory>/src/conf</directory>
+ <includes>
+ <include>*.xsd</include>
+ <include>*.dtd</include>
+ <include>*.mod</include>
+ <include>log4j.properties</include>
+ <include>driver.jelly</include>
+ <include>driver.properties</include>
+ </includes>
+ </resource>
+ <resource>
+ <directory>/src/messages</directory>
+ <targetPath>org/apache/maven/messages</targetPath>
+ <includes>
+ <include>messages*.properties</include>
+ </includes>
+ </resource>
+ </resources>
+ </build>
+
+ <reports>
+ <report>maven-jdepend-plugin</report>
+ <report>maven-checkstyle-plugin</report>
+ <report>maven-changelog-plugin</report>
+ <report>maven-file-activity-plugin</report>
+ <report>maven-developer-activity-plugin</report>
+ <report>maven-javadoc-plugin</report>
+ <report>maven-jxr-plugin</report>
+ <report>maven-junit-report-plugin</report>
+ <report>maven-tasklist-plugin</report>
+ <report>maven-jellydoc-plugin</report>
+ </reports>
+
+</model>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/projects/versionless-managed-dependency.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/projects/versionless-managed-dependency.xml
new file mode 100644
index 00000000..40bf2955
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/projects/versionless-managed-dependency.xml
@@ -0,0 +1,24 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>test</groupId>
+ <artifactId>versionless-managed-dependency.xml</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven.its</groupId>
+ <artifactId>a</artifactId>
+ </dependency>
+ </dependencies>
+
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven.its</groupId>
+ <artifactId>a</artifactId>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/remote-repo-1/maven-test/jars/maven-test-b-1.0.jar b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/remote-repo-1/maven-test/jars/maven-test-b-1.0.jar
new file mode 100644
index 00000000..9ff33b6d
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/remote-repo-1/maven-test/jars/maven-test-b-1.0.jar
Binary files differ
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/remote-repo-1/maven-test/jars/maven-test-b-1.0.jar.md5 b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/remote-repo-1/maven-test/jars/maven-test-b-1.0.jar.md5
new file mode 100644
index 00000000..a8406fd7
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/remote-repo-1/maven-test/jars/maven-test-b-1.0.jar.md5
@@ -0,0 +1 @@
+a5c3b5cd0605bb7331d1846cdc14b13b
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/remote-repo-1/maven-test/poms/maven-test-b-1.0.pom b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/remote-repo-1/maven-test/poms/maven-test-b-1.0.pom
new file mode 100644
index 00000000..ed5c2693
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/remote-repo-1/maven-test/poms/maven-test-b-1.0.pom
@@ -0,0 +1,21 @@
+<model>
+ <groupId>maven-test</groupId>
+ <artifactId>maven-test-a</artifactId>
+ <packaging>jar</packaging>
+ <dependencies>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>maven-test-b</artifactId>
+ <version>1.0</version>
+ <type>jar</type>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>maven-test</groupId>
+ <artifactId>maven-test-z</artifactId>
+ <version>1.0</version>
+ <type>jar</type>
+ <scope>compile</scope>
+ </dependency>
+ </dependencies>
+</model> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/remote-repo-1/snapshot-test/jars/maven-snapshot-a-1.0-SNAPSHOT.jar b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/remote-repo-1/snapshot-test/jars/maven-snapshot-a-1.0-SNAPSHOT.jar
new file mode 100644
index 00000000..b3da0186
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/remote-repo-1/snapshot-test/jars/maven-snapshot-a-1.0-SNAPSHOT.jar
@@ -0,0 +1 @@
+remote \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/remote-repo-1/snapshot-test/jars/maven-snapshot-a-1.0-SNAPSHOT.jar.snapshot-version b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/remote-repo-1/snapshot-test/jars/maven-snapshot-a-1.0-SNAPSHOT.jar.snapshot-version
new file mode 100644
index 00000000..c1c3c3e3
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/remote-repo-1/snapshot-test/jars/maven-snapshot-a-1.0-SNAPSHOT.jar.snapshot-version
@@ -0,0 +1 @@
+20050101.101010 \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/remote-repo-1/snapshot-test/jars/maven-snapshot-b-1.0-SNAPSHOT.jar b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/remote-repo-1/snapshot-test/jars/maven-snapshot-b-1.0-SNAPSHOT.jar
new file mode 100644
index 00000000..c2c027fe
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/remote-repo-1/snapshot-test/jars/maven-snapshot-b-1.0-SNAPSHOT.jar
@@ -0,0 +1 @@
+local \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/remote-repo-1/snapshot-test/jars/maven-snapshot-b-1.0-SNAPSHOT.jar.snapshot-version b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/remote-repo-1/snapshot-test/jars/maven-snapshot-b-1.0-SNAPSHOT.jar.snapshot-version
new file mode 100644
index 00000000..b2954fe9
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/remote-repo-1/snapshot-test/jars/maven-snapshot-b-1.0-SNAPSHOT.jar.snapshot-version
@@ -0,0 +1 @@
+20030101.101010 \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/remote-repo-1/snapshot-test/jars/maven-snapshot-c-1.0-SNAPSHOT.jar b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/remote-repo-1/snapshot-test/jars/maven-snapshot-c-1.0-SNAPSHOT.jar
new file mode 100644
index 00000000..b3da0186
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/remote-repo-1/snapshot-test/jars/maven-snapshot-c-1.0-SNAPSHOT.jar
@@ -0,0 +1 @@
+remote \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/remote-repo-1/snapshot-test/jars/maven-snapshot-c-1.0-SNAPSHOT.jar.snapshot-version b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/remote-repo-1/snapshot-test/jars/maven-snapshot-c-1.0-SNAPSHOT.jar.snapshot-version
new file mode 100644
index 00000000..7c5f8a57
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/remote-repo-1/snapshot-test/jars/maven-snapshot-c-1.0-SNAPSHOT.jar.snapshot-version
@@ -0,0 +1 @@
+20040101.101010
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/remote-repo-2/maven-test/jars/maven-test-z-1.0.jar b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/remote-repo-2/maven-test/jars/maven-test-z-1.0.jar
new file mode 100644
index 00000000..257cc564
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/remote-repo-2/maven-test/jars/maven-test-z-1.0.jar
@@ -0,0 +1 @@
+foo
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/withActiveByDefaultProfile-pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/withActiveByDefaultProfile-pom.xml
new file mode 100644
index 00000000..95ee353a
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-core/src/test/resources/withActiveByDefaultProfile-pom.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>maven</groupId>
+ <artifactId>maven-core</artifactId>
+ <version>2.0-SNAPSHOT</version>
+
+ <name>Maven</name>
+
+ <profiles>
+ <profile>
+ <activation>
+ <activeByDefault>true</activeByDefault>
+ </activation>
+ <id>test</id>
+ </profile>
+ </profiles>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/pom.xml
new file mode 100644
index 00000000..c004ea17
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/pom.xml
@@ -0,0 +1,144 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+ <!--
+ Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE
+ file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by
+ applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language
+ governing permissions and limitations under the License.
+ -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven</artifactId>
+ <version>3.3.3</version>
+ </parent>
+
+ <artifactId>maven-embedder</artifactId>
+
+ <name>Maven Embedder</name>
+ <description>Maven embeddable component, with CLI and logging support.</description>
+
+ <scm><!-- remove when git scm url format can accept artifact-id at the end, as automatically inherited -->
+ <connection>scm:git:https://git-wip-us.apache.org/repos/asf/maven.git</connection>
+ <developerConnection>scm:git:https://git-wip-us.apache.org/repos/asf/maven.git</developerConnection>
+ <tag>maven-3.3.3</tag>
+ </scm>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-settings</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-plugin-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-model-builder</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-compat</artifactId>
+ <scope>runtime</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-utils</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-classworlds</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.sisu</groupId>
+ <artifactId>org.eclipse.sisu.plexus</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-component-annotations</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.sonatype.plexus</groupId>
+ <artifactId>plexus-sec-dispatcher</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.sonatype.plexus</groupId>
+ <artifactId>plexus-cipher</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-simple</artifactId>
+ <optional>true</optional>
+ </dependency>
+ <dependency>
+ <groupId>ch.qos.logback</groupId>
+ <artifactId>logback-classic</artifactId>
+ <optional>true</optional>
+ </dependency>
+ <!-- CLI -->
+ <dependency>
+ <groupId>commons-cli</groupId>
+ <artifactId>commons-cli</artifactId>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <resources>
+ <resource>
+ <directory>src/main/resources</directory>
+ <filtering>true</filtering>
+ </resource>
+ </resources>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.rat</groupId>
+ <artifactId>apache-rat-plugin</artifactId>
+ <configuration>
+ <excludes combine.children="append">
+ <exclude>src/main/resources/META-INF/MANIFEST.MF</exclude>
+ <exclude>src/test/*-projects/**</exclude>
+ <exclude>src/test/*-project/**</exclude>
+ <exclude>src/test/plugin-version-references/**</exclude>
+ </excludes>
+ </configuration>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.eclipse.sisu</groupId>
+ <artifactId>sisu-maven-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-component-metadata</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.modello</groupId>
+ <artifactId>modello-maven-plugin</artifactId>
+ <configuration>
+ <version>1.0.0</version>
+ <models>
+ <model>src/main/mdo/core-extensions.mdo</model>
+ </models>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/examples/simple-project/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/examples/simple-project/pom.xml
new file mode 100644
index 00000000..c4ad90d2
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/examples/simple-project/pom.xml
@@ -0,0 +1,39 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven.embedder</groupId>
+ <artifactId>simple-project</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <name>simple-project</name>
+ <url>http://maven.apache.org</url>
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>3.8.1</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+ <properties>
+ <environment>development</environment>
+ </properties>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/examples/simple-project/settings.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/examples/simple-project/settings.xml
new file mode 100644
index 00000000..39709fde
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/examples/simple-project/settings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0"?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<settings>
+ <pluginGroups>
+ <pluginGroup>org.codehaus.tycho</pluginGroup>
+ <pluginGroup>org.sonatype.pwt</pluginGroup>
+ </pluginGroups>
+</settings>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/examples/simple-project/src/main/java/org/apache/maven/embedder/App.java b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/examples/simple-project/src/main/java/org/apache/maven/embedder/App.java
new file mode 100644
index 00000000..06927bff
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/examples/simple-project/src/main/java/org/apache/maven/embedder/App.java
@@ -0,0 +1,28 @@
+package org.apache.maven.embedder;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+/**
+ * Hello world!
+ *
+ */
+public class App
+{
+ public static void main( String[] args )
+ {
+ System.out.println( "Hello World!" );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/examples/simple-project/src/test/java/org/apache/maven/embedder/AppTest.java b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/examples/simple-project/src/test/java/org/apache/maven/embedder/AppTest.java
new file mode 100644
index 00000000..ee90c206
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/examples/simple-project/src/test/java/org/apache/maven/embedder/AppTest.java
@@ -0,0 +1,53 @@
+package org.apache.maven.embedder;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+/**
+ * Unit test for simple App.
+ */
+public class AppTest
+ extends TestCase
+{
+ /**
+ * Create the test case
+ *
+ * @param testName name of the test case
+ */
+ public AppTest( String testName )
+ {
+ super( testName );
+ }
+
+ /**
+ * @return the suite of tests being tested
+ */
+ public static Test suite()
+ {
+ return new TestSuite( AppTest.class );
+ }
+
+ /**
+ * Rigourous Test :-)
+ */
+ public void testApp()
+ {
+ assertTrue( true );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/CLIManager.java b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/CLIManager.java
new file mode 100644
index 00000000..a78e11dc
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/CLIManager.java
@@ -0,0 +1,271 @@
+package org.apache.maven.cli;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.CommandLineParser;
+import org.apache.commons.cli.GnuParser;
+import org.apache.commons.cli.HelpFormatter;
+import org.apache.commons.cli.OptionBuilder;
+import org.apache.commons.cli.Options;
+import org.apache.commons.cli.ParseException;
+
+/**
+ * @author Jason van Zyl
+ */
+public class CLIManager
+{
+ public static final char ALTERNATE_POM_FILE = 'f';
+
+ public static final char BATCH_MODE = 'B';
+
+ public static final char SET_SYSTEM_PROPERTY = 'D';
+
+ public static final char OFFLINE = 'o';
+
+ public static final char QUIET = 'q';
+
+ public static final char DEBUG = 'X';
+
+ public static final char ERRORS = 'e';
+
+ public static final char HELP = 'h';
+
+ public static final char VERSION = 'v';
+
+ public static final char SHOW_VERSION = 'V';
+
+ public static final char NON_RECURSIVE = 'N';
+
+ public static final char UPDATE_SNAPSHOTS = 'U';
+
+ public static final char ACTIVATE_PROFILES = 'P';
+
+ public static final String SUPRESS_SNAPSHOT_UPDATES = "nsu";
+
+ public static final char CHECKSUM_FAILURE_POLICY = 'C';
+
+ public static final char CHECKSUM_WARNING_POLICY = 'c';
+
+ public static final char ALTERNATE_USER_SETTINGS = 's';
+
+ public static final String ALTERNATE_GLOBAL_SETTINGS = "gs";
+
+ public static final char ALTERNATE_USER_TOOLCHAINS = 't';
+
+ public static final String ALTERNATE_GLOBAL_TOOLCHAINS = "gt";
+
+ public static final String FAIL_FAST = "ff";
+
+ public static final String FAIL_AT_END = "fae";
+
+ public static final String FAIL_NEVER = "fn";
+
+ public static final String RESUME_FROM = "rf";
+
+ public static final String PROJECT_LIST = "pl";
+
+ public static final String ALSO_MAKE = "am";
+
+ public static final String ALSO_MAKE_DEPENDENTS = "amd";
+
+ public static final String LOG_FILE = "l";
+
+ public static final String ENCRYPT_MASTER_PASSWORD = "emp";
+
+ public static final String ENCRYPT_PASSWORD = "ep";
+
+ public static final String THREADS = "T";
+
+ public static final String LEGACY_LOCAL_REPOSITORY = "llr";
+
+ public static final String BUILDER = "b";
+
+ protected Options options;
+
+ @SuppressWarnings( { "static-access", "checkstyle:linelength" } )
+ public CLIManager()
+ {
+ options = new Options();
+ options.addOption( OptionBuilder.withLongOpt( "help" ).withDescription( "Display help information" ).create( HELP ) );
+ options.addOption( OptionBuilder.withLongOpt( "file" ).hasArg().withDescription( "Force the use of an alternate POM file (or directory with pom.xml)." ).create( ALTERNATE_POM_FILE ) );
+ options.addOption( OptionBuilder.withLongOpt( "define" ).hasArg().withDescription( "Define a system property" ).create( SET_SYSTEM_PROPERTY ) );
+ options.addOption( OptionBuilder.withLongOpt( "offline" ).withDescription( "Work offline" ).create( OFFLINE ) );
+ options.addOption( OptionBuilder.withLongOpt( "version" ).withDescription( "Display version information" ).create( VERSION ) );
+ options.addOption( OptionBuilder.withLongOpt( "quiet" ).withDescription( "Quiet output - only show errors" ).create( QUIET ) );
+ options.addOption( OptionBuilder.withLongOpt( "debug" ).withDescription( "Produce execution debug output" ).create( DEBUG ) );
+ options.addOption( OptionBuilder.withLongOpt( "errors" ).withDescription( "Produce execution error messages" ).create( ERRORS ) );
+ options.addOption( OptionBuilder.withLongOpt( "non-recursive" ).withDescription( "Do not recurse into sub-projects" ).create( NON_RECURSIVE ) );
+ options.addOption( OptionBuilder.withLongOpt( "update-snapshots" ).withDescription( "Forces a check for missing releases and updated snapshots on remote repositories" ).create( UPDATE_SNAPSHOTS ) );
+ options.addOption( OptionBuilder.withLongOpt( "activate-profiles" ).withDescription( "Comma-delimited list of profiles to activate" ).hasArg().create( ACTIVATE_PROFILES ) );
+ options.addOption( OptionBuilder.withLongOpt( "batch-mode" ).withDescription( "Run in non-interactive (batch) mode" ).create( BATCH_MODE ) );
+ options.addOption( OptionBuilder.withLongOpt( "no-snapshot-updates" ).withDescription( "Suppress SNAPSHOT updates" ).create( SUPRESS_SNAPSHOT_UPDATES ) );
+ options.addOption( OptionBuilder.withLongOpt( "strict-checksums" ).withDescription( "Fail the build if checksums don't match" ).create( CHECKSUM_FAILURE_POLICY ) );
+ options.addOption( OptionBuilder.withLongOpt( "lax-checksums" ).withDescription( "Warn if checksums don't match" ).create( CHECKSUM_WARNING_POLICY ) );
+ options.addOption( OptionBuilder.withLongOpt( "settings" ).withDescription( "Alternate path for the user settings file" ).hasArg().create( ALTERNATE_USER_SETTINGS ) );
+ options.addOption( OptionBuilder.withLongOpt( "global-settings" ).withDescription( "Alternate path for the global settings file" ).hasArg().create( ALTERNATE_GLOBAL_SETTINGS ) );
+ options.addOption( OptionBuilder.withLongOpt( "toolchains" ).withDescription( "Alternate path for the user toolchains file" ).hasArg().create( ALTERNATE_USER_TOOLCHAINS ) );
+ options.addOption( OptionBuilder.withLongOpt( "global-toolchains" ).withDescription( "Alternate path for the global toolchains file" ).hasArg().create( ALTERNATE_GLOBAL_TOOLCHAINS ) );
+ options.addOption( OptionBuilder.withLongOpt( "fail-fast" ).withDescription( "Stop at first failure in reactorized builds" ).create( FAIL_FAST ) );
+ options.addOption( OptionBuilder.withLongOpt( "fail-at-end" ).withDescription( "Only fail the build afterwards; allow all non-impacted builds to continue" ).create( FAIL_AT_END ) );
+ options.addOption( OptionBuilder.withLongOpt( "fail-never" ).withDescription( "NEVER fail the build, regardless of project result" ).create( FAIL_NEVER ) );
+ options.addOption( OptionBuilder.withLongOpt( "resume-from" ).hasArg().withDescription( "Resume reactor from specified project" ).create( RESUME_FROM ) );
+ options.addOption( OptionBuilder.withLongOpt( "projects" ).withDescription( "Comma-delimited list of specified reactor projects to build instead of all projects. A project can be specified by [groupId]:artifactId or by its relative path." ).hasArg().create( PROJECT_LIST ) );
+ options.addOption( OptionBuilder.withLongOpt( "also-make" ).withDescription( "If project list is specified, also build projects required by the list" ).create( ALSO_MAKE ) );
+ options.addOption( OptionBuilder.withLongOpt( "also-make-dependents" ).withDescription( "If project list is specified, also build projects that depend on projects on the list" ).create( ALSO_MAKE_DEPENDENTS ) );
+ options.addOption( OptionBuilder.withLongOpt( "log-file" ).hasArg().withDescription( "Log file to where all build output will go." ).create( LOG_FILE ) );
+ options.addOption( OptionBuilder.withLongOpt( "show-version" ).withDescription( "Display version information WITHOUT stopping build" ).create( SHOW_VERSION ) );
+ options.addOption( OptionBuilder.withLongOpt( "encrypt-master-password" ).hasOptionalArg().withDescription( "Encrypt master security password" ).create( ENCRYPT_MASTER_PASSWORD ) );
+ options.addOption( OptionBuilder.withLongOpt( "encrypt-password" ).hasOptionalArg().withDescription( "Encrypt server password" ).create( ENCRYPT_PASSWORD ) );
+ options.addOption( OptionBuilder.withLongOpt( "threads" ).hasArg().withDescription( "Thread count, for instance 2.0C where C is core multiplied" ).create( THREADS ) );
+ options.addOption( OptionBuilder.withLongOpt( "legacy-local-repository" ).withDescription( "Use Maven 2 Legacy Local Repository behaviour, ie no use of _remote.repositories. Can also be activated by using -Dmaven.legacyLocalRepo=true" ).create( LEGACY_LOCAL_REPOSITORY ) );
+ options.addOption( OptionBuilder.withLongOpt( "builder" ).hasArg().withDescription( "The id of the build strategy to use." ).create( BUILDER ) );
+
+ // Adding this back in for compatibility with the verifier that hard codes this option.
+ options.addOption( OptionBuilder.withLongOpt( "no-plugin-registry" ).withDescription( "Ineffective, only kept for backward compatibility" ).create( "npr" ) );
+ options.addOption( OptionBuilder.withLongOpt( "check-plugin-updates" ).withDescription( "Ineffective, only kept for backward compatibility" ).create( "cpu" ) );
+ options.addOption( OptionBuilder.withLongOpt( "update-plugins" ).withDescription( "Ineffective, only kept for backward compatibility" ).create( "up" ) );
+ options.addOption( OptionBuilder.withLongOpt( "no-plugin-updates" ).withDescription( "Ineffective, only kept for backward compatibility" ).create( "npu" ) );
+ }
+
+ public CommandLine parse( String[] args )
+ throws ParseException
+ {
+ // We need to eat any quotes surrounding arguments...
+ String[] cleanArgs = cleanArgs( args );
+
+ CommandLineParser parser = new GnuParser();
+
+ return parser.parse( options, cleanArgs );
+ }
+
+ private String[] cleanArgs( String[] args )
+ {
+ List<String> cleaned = new ArrayList<String>();
+
+ StringBuilder currentArg = null;
+
+ for ( String arg : args )
+ {
+ boolean addedToBuffer = false;
+
+ if ( arg.startsWith( "\"" ) )
+ {
+ // if we're in the process of building up another arg, push it and start over.
+ // this is for the case: "-Dfoo=bar "-Dfoo2=bar two" (note the first unterminated quote)
+ if ( currentArg != null )
+ {
+ cleaned.add( currentArg.toString() );
+ }
+
+ // start building an argument here.
+ currentArg = new StringBuilder( arg.substring( 1 ) );
+ addedToBuffer = true;
+ }
+
+ // this has to be a separate "if" statement, to capture the case of: "-Dfoo=bar"
+ if ( arg.endsWith( "\"" ) )
+ {
+ String cleanArgPart = arg.substring( 0, arg.length() - 1 );
+
+ // if we're building an argument, keep doing so.
+ if ( currentArg != null )
+ {
+ // if this is the case of "-Dfoo=bar", then we need to adjust the buffer.
+ if ( addedToBuffer )
+ {
+ currentArg.setLength( currentArg.length() - 1 );
+ }
+ // otherwise, we trim the trailing " and append to the buffer.
+ else
+ {
+ // TODO: introducing a space here...not sure what else to do but collapse whitespace
+ currentArg.append( ' ' ).append( cleanArgPart );
+ }
+
+ cleaned.add( currentArg.toString() );
+ }
+ else
+ {
+ cleaned.add( cleanArgPart );
+ }
+
+ currentArg = null;
+
+ continue;
+ }
+
+ // if we haven't added this arg to the buffer, and we ARE building an argument
+ // buffer, then append it with a preceding space...again, not sure what else to
+ // do other than collapse whitespace.
+ // NOTE: The case of a trailing quote is handled by nullifying the arg buffer.
+ if ( !addedToBuffer )
+ {
+ if ( currentArg != null )
+ {
+ currentArg.append( ' ' ).append( arg );
+ }
+ else
+ {
+ cleaned.add( arg );
+ }
+ }
+ }
+
+ if ( currentArg != null )
+ {
+ cleaned.add( currentArg.toString() );
+ }
+
+ int cleanedSz = cleaned.size();
+
+ String[] cleanArgs;
+
+ if ( cleanedSz == 0 )
+ {
+ cleanArgs = args;
+ }
+ else
+ {
+ cleanArgs = cleaned.toArray( new String[cleanedSz] );
+ }
+
+ return cleanArgs;
+ }
+
+ public void displayHelp( PrintStream stdout )
+ {
+ stdout.println();
+
+ PrintWriter pw = new PrintWriter( stdout );
+
+ HelpFormatter formatter = new HelpFormatter();
+
+ formatter.printHelp( pw, HelpFormatter.DEFAULT_WIDTH, "mvn [options] [<goal(s)>] [<phase(s)>]", "\nOptions:",
+ options, HelpFormatter.DEFAULT_LEFT_PAD, HelpFormatter.DEFAULT_DESC_PAD, "\n", false );
+
+ pw.flush();
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/CLIReportingUtils.java b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/CLIReportingUtils.java
new file mode 100644
index 00000000..07863b72
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/CLIReportingUtils.java
@@ -0,0 +1,205 @@
+package org.apache.maven.cli;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Date;
+import java.util.Locale;
+import java.util.Properties;
+import java.util.TimeZone;
+
+import org.codehaus.plexus.util.IOUtil;
+import org.codehaus.plexus.util.Os;
+import org.slf4j.Logger;
+
+/**
+ * Utility class used to report errors, statistics, application version info, etc.
+ *
+ * @author jdcasey
+ *
+ */
+public final class CLIReportingUtils
+{
+ // CHECKSTYLE_OFF: MagicNumber
+ public static final long MB = 1024 * 1024;
+
+ private static final long ONE_SECOND = 1000L;
+ private static final long ONE_MINUTE = 60 * ONE_SECOND;
+ private static final long ONE_HOUR = 60 * ONE_MINUTE;
+ private static final long ONE_DAY = 24 * ONE_HOUR;
+ // CHECKSTYLE_ON: MagicNumber
+
+ public static final String BUILD_VERSION_PROPERTY = "version";
+
+ public static String showVersion()
+ {
+ final String ls = System.getProperty( "line.separator" );
+ Properties properties = getBuildProperties();
+ StringBuilder version = new StringBuilder();
+ version.append( createMavenVersionString( properties ) ).append( ls );
+ version.append( reduce( properties.getProperty( "distributionShortName" ) + " home: "
+ + System.getProperty( "maven.home", "<unknown maven home>" ) ) ).append( ls );
+ version.append( "Java version: " ).append(
+ System.getProperty( "java.version", "<unknown java version>" ) ).append( ", vendor: " ).append(
+ System.getProperty( "java.vendor", "<unknown vendor>" ) ).append( ls );
+ version.append( "Java home: " ).append( System.getProperty( "java.home", "<unknown java home>" ) ).append( ls );
+ version.append( "Default locale: " ).append( Locale.getDefault() ).append( ", platform encoding: " ).append(
+ System.getProperty( "file.encoding", "<unknown encoding>" ) ).append( ls );
+ version.append( "OS name: \"" ).append( Os.OS_NAME ).append( "\", version: \"" ).append( Os.OS_VERSION ).append(
+ "\", arch: \"" ).append( Os.OS_ARCH ).append( "\", family: \"" ).append( Os.OS_FAMILY ).append( "\"" );
+ return version.toString();
+ }
+
+ /**
+ * Create a human readable string containing the Maven version, buildnumber, and time of build
+ *
+ * @param buildProperties The build properties
+ * @return Readable build info
+ */
+ static String createMavenVersionString( Properties buildProperties )
+ {
+ String timestamp = reduce( buildProperties.getProperty( "timestamp" ) );
+ String version = reduce( buildProperties.getProperty( BUILD_VERSION_PROPERTY ) );
+ String rev = reduce( buildProperties.getProperty( "buildNumber" ) );
+ String distributionName = reduce( buildProperties.getProperty( "distributionName" ) );
+
+ String msg = distributionName + " ";
+ msg += ( version != null ? version : "<version unknown>" );
+ if ( rev != null || timestamp != null )
+ {
+ msg += " (";
+ msg += ( rev != null ? rev : "" );
+ if ( timestamp != null )
+ {
+ String ts = formatTimestamp( Long.valueOf( timestamp ) );
+ msg += ( rev != null ? "; " : "" ) + ts;
+ }
+ msg += ")";
+ }
+ return msg;
+ }
+
+ private static String reduce( String s )
+ {
+ return ( s != null ? ( s.startsWith( "${" ) && s.endsWith( "}" ) ? null : s ) : null );
+ }
+
+ static Properties getBuildProperties()
+ {
+ Properties properties = new Properties();
+ InputStream resourceAsStream = null;
+ try
+ {
+ resourceAsStream = MavenCli.class.getResourceAsStream( "/org/apache/maven/messages/build.properties" );
+
+ if ( resourceAsStream != null )
+ {
+ properties.load( resourceAsStream );
+ }
+ }
+ catch ( IOException e )
+ {
+ System.err.println( "Unable determine version from JAR file: " + e.getMessage() );
+ }
+ finally
+ {
+ IOUtil.close( resourceAsStream );
+ }
+
+ return properties;
+ }
+
+ public static void showError( Logger logger, String message, Throwable e, boolean showStackTrace )
+ {
+ if ( showStackTrace )
+ {
+ logger.error( message, e );
+ }
+ else
+ {
+ logger.error( message );
+
+ if ( e != null )
+ {
+ logger.error( e.getMessage() );
+
+ for ( Throwable cause = e.getCause(); cause != null; cause = cause.getCause() )
+ {
+ logger.error( "Caused by: " + cause.getMessage() );
+ }
+ }
+ }
+ }
+
+ public static String formatTimestamp( long timestamp )
+ {
+ // Manual construction of the tz offset because only Java 7 is aware of ISO 8601 time zones
+ TimeZone tz = TimeZone.getDefault();
+ int offset = tz.getRawOffset();
+
+ // Raw offset ignores DST, so check if we are in DST now and add the offset
+ if ( tz.inDaylightTime( new Date( timestamp ) ) )
+ {
+ offset += tz.getDSTSavings();
+ }
+
+ // CHECKSTYLE_OFF: MagicNumber
+ long m = Math.abs( ( offset / ONE_MINUTE ) % 60 );
+ long h = Math.abs( ( offset / ONE_HOUR ) % 24 );
+ // CHECKSTYLE_ON: MagicNumber
+
+ int offsetDir = (int) Math.signum( (float) offset );
+ char offsetSign = offsetDir >= 0 ? '+' : '-';
+ return String.format( "%tFT%<tT%s%02d:%02d", timestamp, offsetSign, h, m );
+ }
+
+ public static String formatDuration( long duration )
+ {
+ // CHECKSTYLE_OFF: MagicNumber
+ long ms = duration % 1000;
+ long s = ( duration / ONE_SECOND ) % 60;
+ long m = ( duration / ONE_MINUTE ) % 60;
+ long h = ( duration / ONE_HOUR ) % 24;
+ long d = duration / ONE_DAY;
+ // CHECKSTYLE_ON: MagicNumber
+
+ String format;
+ if ( d > 0 )
+ {
+ format = "%d d %02d:%02d h";
+ }
+ else if ( h > 0 )
+ {
+ format = "%2$02d:%3$02d h";
+ }
+ else if ( m > 0 )
+ {
+ format = "%3$02d:%4$02d min";
+ }
+ else
+ {
+ format = "%4$d.%5$03d s";
+ }
+
+ return String.format( format, d, h, m, s, ms );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/CliRequest.java b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/CliRequest.java
new file mode 100644
index 00000000..4656dd37
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/CliRequest.java
@@ -0,0 +1,120 @@
+package org.apache.maven.cli;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.util.Properties;
+
+import org.apache.commons.cli.CommandLine;
+import org.apache.maven.execution.DefaultMavenExecutionRequest;
+import org.apache.maven.execution.MavenExecutionRequest;
+import org.codehaus.plexus.classworlds.ClassWorld;
+
+public class CliRequest
+{
+ String[] args;
+
+ CommandLine commandLine;
+
+ ClassWorld classWorld;
+
+ String workingDirectory;
+
+ File multiModuleProjectDirectory;
+
+ boolean debug;
+
+ boolean quiet;
+
+ boolean showErrors = true;
+
+ Properties userProperties = new Properties();
+
+ Properties systemProperties = new Properties();
+
+ MavenExecutionRequest request;
+
+ CliRequest( String[] args, ClassWorld classWorld )
+ {
+ this.args = args;
+ this.classWorld = classWorld;
+ this.request = new DefaultMavenExecutionRequest();
+ }
+
+ public String[] getArgs()
+ {
+ return args;
+ }
+
+ public CommandLine getCommandLine()
+ {
+ return commandLine;
+ }
+
+ public ClassWorld getClassWorld()
+ {
+ return classWorld;
+ }
+
+ public String getWorkingDirectory()
+ {
+ return workingDirectory;
+ }
+
+ public File getMultiModuleProjectDirectory()
+ {
+ return multiModuleProjectDirectory;
+ }
+
+ public boolean isDebug()
+ {
+ return debug;
+ }
+
+ public boolean isQuiet()
+ {
+ return quiet;
+ }
+
+ public boolean isShowErrors()
+ {
+ return showErrors;
+ }
+
+ public Properties getUserProperties()
+ {
+ return userProperties;
+ }
+
+ public Properties getSystemProperties()
+ {
+ return systemProperties;
+ }
+
+ public MavenExecutionRequest getRequest()
+ {
+ return request;
+ }
+
+ public void setUserProperties( Properties properties )
+ {
+ this.userProperties.putAll( properties );
+ }
+} \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java
new file mode 100644
index 00000000..39660956
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java
@@ -0,0 +1,1610 @@
+package org.apache.maven.cli;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.BufferedInputStream;
+import java.io.Console;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Properties;
+import java.util.Set;
+import java.util.StringTokenizer;
+
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.ParseException;
+import org.apache.commons.cli.UnrecognizedOptionException;
+import org.apache.maven.BuildAbort;
+import org.apache.maven.InternalErrorException;
+import org.apache.maven.Maven;
+import org.apache.maven.building.FileSource;
+import org.apache.maven.building.Problem;
+import org.apache.maven.building.Source;
+import org.apache.maven.cli.configuration.ConfigurationProcessor;
+import org.apache.maven.cli.configuration.SettingsXmlConfigurationProcessor;
+import org.apache.maven.cli.event.DefaultEventSpyContext;
+import org.apache.maven.cli.event.ExecutionEventLogger;
+import org.apache.maven.cli.internal.BootstrapCoreExtensionManager;
+import org.apache.maven.cli.internal.extension.model.CoreExtension;
+import org.apache.maven.cli.internal.extension.model.io.xpp3.CoreExtensionsXpp3Reader;
+import org.apache.maven.cli.logging.Slf4jConfiguration;
+import org.apache.maven.cli.logging.Slf4jConfigurationFactory;
+import org.apache.maven.cli.logging.Slf4jLoggerManager;
+import org.apache.maven.cli.logging.Slf4jStdoutLogger;
+import org.apache.maven.cli.transfer.ConsoleMavenTransferListener;
+import org.apache.maven.cli.transfer.QuietMavenTransferListener;
+import org.apache.maven.cli.transfer.Slf4jMavenTransferListener;
+import org.apache.maven.eventspy.internal.EventSpyDispatcher;
+import org.apache.maven.exception.DefaultExceptionHandler;
+import org.apache.maven.exception.ExceptionHandler;
+import org.apache.maven.exception.ExceptionSummary;
+import org.apache.maven.execution.DefaultMavenExecutionRequest;
+import org.apache.maven.execution.ExecutionListener;
+import org.apache.maven.execution.MavenExecutionRequest;
+import org.apache.maven.execution.MavenExecutionRequestPopulationException;
+import org.apache.maven.execution.MavenExecutionRequestPopulator;
+import org.apache.maven.execution.MavenExecutionResult;
+import org.apache.maven.extension.internal.CoreExports;
+import org.apache.maven.extension.internal.CoreExtensionEntry;
+import org.apache.maven.lifecycle.LifecycleExecutionException;
+import org.apache.maven.model.building.ModelProcessor;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.properties.internal.EnvironmentUtils;
+import org.apache.maven.properties.internal.SystemProperties;
+import org.apache.maven.toolchain.building.DefaultToolchainsBuildingRequest;
+import org.apache.maven.toolchain.building.ToolchainsBuilder;
+import org.apache.maven.toolchain.building.ToolchainsBuildingResult;
+import org.codehaus.plexus.ContainerConfiguration;
+import org.codehaus.plexus.DefaultContainerConfiguration;
+import org.codehaus.plexus.DefaultPlexusContainer;
+import org.codehaus.plexus.PlexusConstants;
+import org.codehaus.plexus.PlexusContainer;
+import org.codehaus.plexus.classworlds.ClassWorld;
+import org.codehaus.plexus.classworlds.realm.ClassRealm;
+import org.codehaus.plexus.classworlds.realm.NoSuchRealmException;
+import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
+import org.codehaus.plexus.logging.LoggerManager;
+import org.codehaus.plexus.util.IOUtil;
+import org.codehaus.plexus.util.StringUtils;
+import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
+import org.eclipse.aether.transfer.TransferListener;
+import org.slf4j.ILoggerFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.sonatype.plexus.components.cipher.DefaultPlexusCipher;
+import org.sonatype.plexus.components.sec.dispatcher.DefaultSecDispatcher;
+import org.sonatype.plexus.components.sec.dispatcher.SecDispatcher;
+import org.sonatype.plexus.components.sec.dispatcher.SecUtil;
+import org.sonatype.plexus.components.sec.dispatcher.model.SettingsSecurity;
+
+import com.google.common.base.Charsets;
+import com.google.common.io.Files;
+import com.google.inject.AbstractModule;
+
+// TODO: push all common bits back to plexus cli and prepare for transition to Guice. We don't need 50 ways to make CLIs
+
+/**
+ * @author Jason van Zyl
+ * @noinspection UseOfSystemOutOrSystemErr,ACCESS_STATIC_VIA_INSTANCE
+ */
+public class MavenCli
+{
+ public static final String LOCAL_REPO_PROPERTY = "maven.repo.local";
+
+ public static final String THREADS_DEPRECATED = "maven.threads.experimental";
+
+ public static final String MULTIMODULE_PROJECT_DIRECTORY = "maven.multiModuleProjectDirectory";
+
+ @SuppressWarnings( "checkstyle:constantname" )
+ public static final String userHome = System.getProperty( "user.home" );
+
+ @SuppressWarnings( "checkstyle:constantname" )
+ public static final File userMavenConfigurationHome = new File( userHome, ".m2" );
+
+ /**
+ * @deprecated use {@link SettingsXmlConfigurationProcessor#DEFAULT_USER_SETTINGS_FILE}
+ */
+ public static final File DEFAULT_USER_SETTINGS_FILE = SettingsXmlConfigurationProcessor.DEFAULT_USER_SETTINGS_FILE;
+
+ /**
+ * @deprecated use {@link SettingsXmlConfigurationProcessor#DEFAULT_GLOBAL_SETTINGS_FILE}
+ */
+ public static final File DEFAULT_GLOBAL_SETTINGS_FILE =
+ SettingsXmlConfigurationProcessor.DEFAULT_GLOBAL_SETTINGS_FILE;
+
+ public static final File DEFAULT_USER_TOOLCHAINS_FILE = new File( userMavenConfigurationHome, "toolchains.xml" );
+
+ public static final File DEFAULT_GLOBAL_TOOLCHAINS_FILE =
+ new File( System.getProperty( "maven.home", System.getProperty( "user.dir", "" ) ), "conf/toolchains.xml" );
+
+ private static final String EXT_CLASS_PATH = "maven.ext.class.path";
+
+ private static final String EXTENSIONS_FILENAME = ".mvn/extensions.xml";
+
+ private ClassWorld classWorld;
+
+ private LoggerManager plexusLoggerManager;
+
+ private ILoggerFactory slf4jLoggerFactory;
+
+ private Logger slf4jLogger;
+
+ private EventSpyDispatcher eventSpyDispatcher;
+
+ private ModelProcessor modelProcessor;
+
+ private Maven maven;
+
+ private MavenExecutionRequestPopulator executionRequestPopulator;
+
+ private ToolchainsBuilder toolchainsBuilder;
+
+ private DefaultSecDispatcher dispatcher;
+
+ private Map<String, ConfigurationProcessor> configurationProcessors;
+
+ public MavenCli()
+ {
+ this( null );
+ }
+
+ // This supports painless invocation by the Verifier during embedded execution of the core ITs
+ public MavenCli( ClassWorld classWorld )
+ {
+ this.classWorld = classWorld;
+ }
+
+ public static void main( String[] args )
+ {
+ int result = main( args, null );
+
+ System.exit( result );
+ }
+
+ /** @noinspection ConfusingMainMethod */
+ public static int main( String[] args, ClassWorld classWorld )
+ {
+ MavenCli cli = new MavenCli();
+ return cli.doMain( new CliRequest( args, classWorld ) );
+ }
+
+ // TODO: need to externalize CliRequest
+ public static int doMain( String[] args, ClassWorld classWorld )
+ {
+ MavenCli cli = new MavenCli();
+ return cli.doMain( new CliRequest( args, classWorld ) );
+ }
+
+ // This supports painless invocation by the Verifier during embedded execution of the core ITs
+ public int doMain( String[] args, String workingDirectory, PrintStream stdout, PrintStream stderr )
+ {
+ PrintStream oldout = System.out;
+ PrintStream olderr = System.err;
+
+ final Set<String> realms;
+ if ( classWorld != null )
+ {
+ realms = new HashSet<String>();
+ for ( ClassRealm realm : classWorld.getRealms() )
+ {
+ realms.add( realm.getId() );
+ }
+ }
+ else
+ {
+ realms = Collections.emptySet();
+ }
+
+ try
+ {
+ if ( stdout != null )
+ {
+ System.setOut( stdout );
+ }
+ if ( stderr != null )
+ {
+ System.setErr( stderr );
+ }
+
+ CliRequest cliRequest = new CliRequest( args, classWorld );
+ cliRequest.workingDirectory = workingDirectory;
+
+ return doMain( cliRequest );
+ }
+ finally
+ {
+ if ( classWorld != null )
+ {
+ for ( ClassRealm realm : new ArrayList<ClassRealm>( classWorld.getRealms() ) )
+ {
+ String realmId = realm.getId();
+ if ( !realms.contains( realmId ) )
+ {
+ try
+ {
+ classWorld.disposeRealm( realmId );
+ }
+ catch ( NoSuchRealmException ignored )
+ {
+ // can't happen
+ }
+ }
+ }
+ }
+ System.setOut( oldout );
+ System.setErr( olderr );
+ }
+ }
+
+ // TODO: need to externalize CliRequest
+ public int doMain( CliRequest cliRequest )
+ {
+ PlexusContainer localContainer = null;
+ try
+ {
+ initialize( cliRequest );
+ cli( cliRequest );
+ logging( cliRequest );
+ version( cliRequest );
+ properties( cliRequest );
+ localContainer = container( cliRequest );
+ commands( cliRequest );
+ configure( cliRequest );
+ toolchains( cliRequest );
+ populateRequest( cliRequest );
+ encryption( cliRequest );
+ repository( cliRequest );
+ return execute( cliRequest );
+ }
+ catch ( ExitException e )
+ {
+ return e.exitCode;
+ }
+ catch ( UnrecognizedOptionException e )
+ {
+ // pure user error, suppress stack trace
+ return 1;
+ }
+ catch ( BuildAbort e )
+ {
+ CLIReportingUtils.showError( slf4jLogger, "ABORTED", e, cliRequest.showErrors );
+
+ return 2;
+ }
+ catch ( Exception e )
+ {
+ CLIReportingUtils.showError( slf4jLogger, "Error executing Maven.", e, cliRequest.showErrors );
+
+ return 1;
+ }
+ finally
+ {
+ if ( localContainer != null )
+ {
+ localContainer.dispose();
+ }
+ }
+ }
+
+ void initialize( CliRequest cliRequest )
+ throws ExitException
+ {
+ if ( cliRequest.workingDirectory == null )
+ {
+ cliRequest.workingDirectory = System.getProperty( "user.dir" );
+ }
+
+ if ( cliRequest.multiModuleProjectDirectory == null )
+ {
+ String basedirProperty = System.getProperty( MULTIMODULE_PROJECT_DIRECTORY );
+ if ( basedirProperty == null )
+ {
+ System.err.format( "-D%s system propery is not set."
+ + " Check $M2_HOME environment variable and mvn script match.", MULTIMODULE_PROJECT_DIRECTORY );
+ throw new ExitException( 1 );
+ }
+ File basedir = basedirProperty != null ? new File( basedirProperty ) : new File( "" );
+ try
+ {
+ cliRequest.multiModuleProjectDirectory = basedir.getCanonicalFile();
+ }
+ catch ( IOException e )
+ {
+ cliRequest.multiModuleProjectDirectory = basedir.getAbsoluteFile();
+ }
+ }
+
+ //
+ // Make sure the Maven home directory is an absolute path to save us from confusion with say drive-relative
+ // Windows paths.
+ //
+ String mavenHome = System.getProperty( "maven.home" );
+
+ if ( mavenHome != null )
+ {
+ System.setProperty( "maven.home", new File( mavenHome ).getAbsolutePath() );
+ }
+ }
+
+ void cli( CliRequest cliRequest )
+ throws Exception
+ {
+ //
+ // Parsing errors can happen during the processing of the arguments and we prefer not having to check if
+ // the logger is null and construct this so we can use an SLF4J logger everywhere.
+ //
+ slf4jLogger = new Slf4jStdoutLogger();
+
+ CLIManager cliManager = new CLIManager();
+
+ List<String> args = new ArrayList<String>();
+
+ try
+ {
+ File configFile = new File( cliRequest.multiModuleProjectDirectory, ".mvn/maven.config" );
+
+ if ( configFile.isFile() )
+ {
+ for ( String arg : Files.toString( configFile, Charsets.UTF_8 ).split( "\\s+" ) )
+ {
+ args.add( arg );
+ }
+
+ CommandLine config = cliManager.parse( args.toArray( new String[args.size()] ) );
+ List<?> unrecongized = config.getArgList();
+ if ( !unrecongized.isEmpty() )
+ {
+ throw new ParseException( "Unrecognized maven.config entries: " + unrecongized );
+ }
+ }
+ }
+ catch ( ParseException e )
+ {
+ System.err.println( "Unable to parse maven.config: " + e.getMessage() );
+ cliManager.displayHelp( System.out );
+ throw e;
+ }
+
+ try
+ {
+ args.addAll( 0, Arrays.asList( cliRequest.args ) );
+ cliRequest.commandLine = cliManager.parse( args.toArray( new String[args.size()] ) );
+ }
+ catch ( ParseException e )
+ {
+ System.err.println( "Unable to parse command line options: " + e.getMessage() );
+ cliManager.displayHelp( System.out );
+ throw e;
+ }
+
+ if ( cliRequest.commandLine.hasOption( CLIManager.HELP ) )
+ {
+ cliManager.displayHelp( System.out );
+ throw new ExitException( 0 );
+ }
+
+ if ( cliRequest.commandLine.hasOption( CLIManager.VERSION ) )
+ {
+ System.out.println( CLIReportingUtils.showVersion() );
+ throw new ExitException( 0 );
+ }
+ }
+
+ /**
+ * configure logging
+ */
+ private void logging( CliRequest cliRequest )
+ {
+ cliRequest.debug = cliRequest.commandLine.hasOption( CLIManager.DEBUG );
+ cliRequest.quiet = !cliRequest.debug && cliRequest.commandLine.hasOption( CLIManager.QUIET );
+ cliRequest.showErrors = cliRequest.debug || cliRequest.commandLine.hasOption( CLIManager.ERRORS );
+
+ slf4jLoggerFactory = LoggerFactory.getILoggerFactory();
+ Slf4jConfiguration slf4jConfiguration = Slf4jConfigurationFactory.getConfiguration( slf4jLoggerFactory );
+
+ if ( cliRequest.debug )
+ {
+ cliRequest.request.setLoggingLevel( MavenExecutionRequest.LOGGING_LEVEL_DEBUG );
+ slf4jConfiguration.setRootLoggerLevel( Slf4jConfiguration.Level.DEBUG );
+ }
+ else if ( cliRequest.quiet )
+ {
+ cliRequest.request.setLoggingLevel( MavenExecutionRequest.LOGGING_LEVEL_ERROR );
+ slf4jConfiguration.setRootLoggerLevel( Slf4jConfiguration.Level.ERROR );
+ }
+ // else fall back to default log level specified in conf
+ // see http://jira.codehaus.org/browse/MNG-2570
+
+ if ( cliRequest.commandLine.hasOption( CLIManager.LOG_FILE ) )
+ {
+ File logFile = new File( cliRequest.commandLine.getOptionValue( CLIManager.LOG_FILE ) );
+ logFile = resolveFile( logFile, cliRequest.workingDirectory );
+
+ // redirect stdout and stderr to file
+ try
+ {
+ PrintStream ps = new PrintStream( new FileOutputStream( logFile ) );
+ System.setOut( ps );
+ System.setErr( ps );
+ }
+ catch ( FileNotFoundException e )
+ {
+ //
+ // Ignore
+ //
+ }
+ }
+
+ slf4jConfiguration.activate();
+
+ plexusLoggerManager = new Slf4jLoggerManager();
+ slf4jLogger = slf4jLoggerFactory.getLogger( this.getClass().getName() );
+ }
+
+ private void version( CliRequest cliRequest )
+ {
+ if ( cliRequest.debug || cliRequest.commandLine.hasOption( CLIManager.SHOW_VERSION ) )
+ {
+ System.out.println( CLIReportingUtils.showVersion() );
+ }
+ }
+
+ private void commands( CliRequest cliRequest )
+ {
+ if ( cliRequest.showErrors )
+ {
+ slf4jLogger.info( "Error stacktraces are turned on." );
+ }
+
+ if ( MavenExecutionRequest.CHECKSUM_POLICY_WARN.equals( cliRequest.request.getGlobalChecksumPolicy() ) )
+ {
+ slf4jLogger.info( "Disabling strict checksum verification on all artifact downloads." );
+ }
+ else if ( MavenExecutionRequest.CHECKSUM_POLICY_FAIL.equals( cliRequest.request.getGlobalChecksumPolicy() ) )
+ {
+ slf4jLogger.info( "Enabling strict checksum verification on all artifact downloads." );
+ }
+ }
+
+ private void properties( CliRequest cliRequest )
+ {
+ populateProperties( cliRequest.commandLine, cliRequest.systemProperties, cliRequest.userProperties );
+ }
+
+ private PlexusContainer container( CliRequest cliRequest )
+ throws Exception
+ {
+ if ( cliRequest.classWorld == null )
+ {
+ cliRequest.classWorld = new ClassWorld( "plexus.core", Thread.currentThread().getContextClassLoader() );
+ }
+
+ ClassRealm coreRealm = cliRequest.classWorld.getClassRealm( "plexus.core" );
+ if ( coreRealm == null )
+ {
+ coreRealm = cliRequest.classWorld.getRealms().iterator().next();
+ }
+
+ List<File> extClassPath = parseExtClasspath( cliRequest );
+
+ CoreExtensionEntry coreEntry = CoreExtensionEntry.discoverFrom( coreRealm );
+ List<CoreExtensionEntry> extensions =
+ loadCoreExtensions( cliRequest, coreRealm, coreEntry.getExportedArtifacts() );
+
+ ClassRealm containerRealm = setupContainerRealm( cliRequest.classWorld, coreRealm, extClassPath, extensions );
+
+ ContainerConfiguration cc = new DefaultContainerConfiguration()
+ .setClassWorld( cliRequest.classWorld )
+ .setRealm( containerRealm )
+ .setClassPathScanning( PlexusConstants.SCANNING_INDEX )
+ .setAutoWiring( true )
+ .setName( "maven" );
+
+ Set<String> exportedArtifacts = new HashSet<String>( coreEntry.getExportedArtifacts() );
+ Set<String> exportedPackages = new HashSet<String>( coreEntry.getExportedPackages() );
+ for ( CoreExtensionEntry extension : extensions )
+ {
+ exportedArtifacts.addAll( extension.getExportedArtifacts() );
+ exportedPackages.addAll( extension.getExportedPackages() );
+ }
+
+ final CoreExports exports = new CoreExports( containerRealm, exportedArtifacts, exportedPackages );
+
+ DefaultPlexusContainer container = new DefaultPlexusContainer( cc, new AbstractModule()
+ {
+ @Override
+ protected void configure()
+ {
+ bind( ILoggerFactory.class ).toInstance( slf4jLoggerFactory );
+ bind( CoreExports.class ).toInstance( exports );
+ }
+ } );
+
+ // NOTE: To avoid inconsistencies, we'll use the TCCL exclusively for lookups
+ container.setLookupRealm( null );
+
+ container.setLoggerManager( plexusLoggerManager );
+
+ for ( CoreExtensionEntry extension : extensions )
+ {
+ container.discoverComponents( extension.getClassRealm() );
+ }
+
+ customizeContainer( container );
+
+ container.getLoggerManager().setThresholds( cliRequest.request.getLoggingLevel() );
+
+ Thread.currentThread().setContextClassLoader( container.getContainerRealm() );
+
+ eventSpyDispatcher = container.lookup( EventSpyDispatcher.class );
+
+ DefaultEventSpyContext eventSpyContext = new DefaultEventSpyContext();
+ Map<String, Object> data = eventSpyContext.getData();
+ data.put( "plexus", container );
+ data.put( "workingDirectory", cliRequest.workingDirectory );
+ data.put( "systemProperties", cliRequest.systemProperties );
+ data.put( "userProperties", cliRequest.userProperties );
+ data.put( "versionProperties", CLIReportingUtils.getBuildProperties() );
+ eventSpyDispatcher.init( eventSpyContext );
+
+ // refresh logger in case container got customized by spy
+ slf4jLogger = slf4jLoggerFactory.getLogger( this.getClass().getName() );
+
+ maven = container.lookup( Maven.class );
+
+ executionRequestPopulator = container.lookup( MavenExecutionRequestPopulator.class );
+
+ modelProcessor = createModelProcessor( container );
+
+ configurationProcessors = container.lookupMap( ConfigurationProcessor.class );
+
+ toolchainsBuilder = container.lookup( ToolchainsBuilder.class );
+
+ dispatcher = (DefaultSecDispatcher) container.lookup( SecDispatcher.class, "maven" );
+
+ return container;
+ }
+
+ private List<CoreExtensionEntry> loadCoreExtensions( CliRequest cliRequest, ClassRealm containerRealm,
+ Set<String> providedArtifacts )
+ {
+ if ( cliRequest.multiModuleProjectDirectory == null )
+ {
+ return Collections.emptyList();
+ }
+
+ File extensionsFile = new File( cliRequest.multiModuleProjectDirectory, EXTENSIONS_FILENAME );
+ if ( !extensionsFile.isFile() )
+ {
+ return Collections.emptyList();
+ }
+
+ try
+ {
+ List<CoreExtension> extensions = readCoreExtensionsDescriptor( extensionsFile );
+ if ( extensions.isEmpty() )
+ {
+ return Collections.emptyList();
+ }
+
+ ContainerConfiguration cc = new DefaultContainerConfiguration() //
+ .setClassWorld( cliRequest.classWorld ) //
+ .setRealm( containerRealm ) //
+ .setClassPathScanning( PlexusConstants.SCANNING_INDEX ) //
+ .setAutoWiring( true ) //
+ .setName( "maven" );
+
+ DefaultPlexusContainer container = new DefaultPlexusContainer( cc, new AbstractModule()
+ {
+ @Override
+ protected void configure()
+ {
+ bind( ILoggerFactory.class ).toInstance( slf4jLoggerFactory );
+ }
+ } );
+
+ try
+ {
+ container.setLookupRealm( null );
+
+ container.setLoggerManager( plexusLoggerManager );
+
+ container.getLoggerManager().setThresholds( cliRequest.request.getLoggingLevel() );
+
+ Thread.currentThread().setContextClassLoader( container.getContainerRealm() );
+
+ executionRequestPopulator = container.lookup( MavenExecutionRequestPopulator.class );
+
+ configurationProcessors = container.lookupMap( ConfigurationProcessor.class );
+
+ configure( cliRequest );
+
+ MavenExecutionRequest request = DefaultMavenExecutionRequest.copy( cliRequest.request );
+
+ request = populateRequest( cliRequest, request );
+
+ request = executionRequestPopulator.populateDefaults( request );
+
+ BootstrapCoreExtensionManager resolver = container.lookup( BootstrapCoreExtensionManager.class );
+
+ return resolver.loadCoreExtensions( request, providedArtifacts, extensions );
+ }
+ finally
+ {
+ executionRequestPopulator = null;
+ container.dispose();
+ }
+ }
+ catch ( RuntimeException e )
+ {
+ // runtime exceptions are most likely bugs in maven, let them bubble up to the user
+ throw e;
+ }
+ catch ( Exception e )
+ {
+ slf4jLogger.warn( "Failed to read extensions descriptor " + extensionsFile + ": " + e.getMessage() );
+ }
+ return Collections.emptyList();
+ }
+
+ private List<CoreExtension> readCoreExtensionsDescriptor( File extensionsFile )
+ throws IOException, XmlPullParserException
+ {
+ CoreExtensionsXpp3Reader parser = new CoreExtensionsXpp3Reader();
+ InputStream is = null;
+ try
+ {
+ is = new BufferedInputStream( new FileInputStream( extensionsFile ) );
+ return parser.read( is ).getExtensions();
+ }
+ finally
+ {
+ IOUtil.close( is );
+ }
+ }
+
+ private ClassRealm setupContainerRealm( ClassWorld classWorld, ClassRealm coreRealm, List<File> extClassPath,
+ List<CoreExtensionEntry> extensions )
+ throws Exception
+ {
+ if ( !extClassPath.isEmpty() || !extensions.isEmpty() )
+ {
+ ClassRealm extRealm = classWorld.newRealm( "maven.ext", null );
+
+ extRealm.setParentRealm( coreRealm );
+
+ slf4jLogger.debug( "Populating class realm " + extRealm.getId() );
+
+ for ( File file : extClassPath )
+ {
+ slf4jLogger.debug( " Included " + file );
+
+ extRealm.addURL( file.toURI().toURL() );
+ }
+
+ for ( CoreExtensionEntry entry : reverse( extensions ) )
+ {
+ Set<String> exportedPackages = entry.getExportedPackages();
+ ClassRealm realm = entry.getClassRealm();
+ for ( String exportedPackage : exportedPackages )
+ {
+ extRealm.importFrom( realm, exportedPackage );
+ }
+ if ( exportedPackages.isEmpty() )
+ {
+ // sisu uses realm imports to establish component visibility
+ extRealm.importFrom( realm, realm.getId() );
+ }
+ }
+
+ return extRealm;
+ }
+
+ return coreRealm;
+ }
+
+ private static <T> List<T> reverse( List<T> list )
+ {
+ List<T> copy = new ArrayList<T>( list );
+ Collections.reverse( copy );
+ return copy;
+ }
+
+ private List<File> parseExtClasspath( CliRequest cliRequest )
+ {
+ String extClassPath = cliRequest.userProperties.getProperty( EXT_CLASS_PATH );
+ if ( extClassPath == null )
+ {
+ extClassPath = cliRequest.systemProperties.getProperty( EXT_CLASS_PATH );
+ }
+
+ List<File> jars = new ArrayList<File>();
+
+ if ( StringUtils.isNotEmpty( extClassPath ) )
+ {
+ for ( String jar : StringUtils.split( extClassPath, File.pathSeparator ) )
+ {
+ File file = resolveFile( new File( jar ), cliRequest.workingDirectory );
+
+ slf4jLogger.debug( " Included " + file );
+
+ jars.add( file );
+ }
+ }
+
+ return jars;
+ }
+
+ //
+ // This should probably be a separate tool and not be baked into Maven.
+ //
+ private void encryption( CliRequest cliRequest )
+ throws Exception
+ {
+ if ( cliRequest.commandLine.hasOption( CLIManager.ENCRYPT_MASTER_PASSWORD ) )
+ {
+ String passwd = cliRequest.commandLine.getOptionValue( CLIManager.ENCRYPT_MASTER_PASSWORD );
+
+ if ( passwd == null )
+ {
+ Console cons = System.console();
+ char[] password = ( cons == null ) ? null : cons.readPassword( "Master password: " );
+ if ( password != null )
+ {
+ // Cipher uses Strings
+ passwd = String.copyValueOf( password );
+
+ // Sun/Oracle advises to empty the char array
+ java.util.Arrays.fill( password, ' ' );
+ }
+ }
+
+ DefaultPlexusCipher cipher = new DefaultPlexusCipher();
+
+ System.out.println( cipher.encryptAndDecorate( passwd,
+ DefaultSecDispatcher.SYSTEM_PROPERTY_SEC_LOCATION ) );
+
+ throw new ExitException( 0 );
+ }
+ else if ( cliRequest.commandLine.hasOption( CLIManager.ENCRYPT_PASSWORD ) )
+ {
+ String passwd = cliRequest.commandLine.getOptionValue( CLIManager.ENCRYPT_PASSWORD );
+
+ if ( passwd == null )
+ {
+ Console cons = System.console();
+ char[] password = ( cons == null ) ? null : cons.readPassword( "Password: " );
+ if ( password != null )
+ {
+ // Cipher uses Strings
+ passwd = String.copyValueOf( password );
+
+ // Sun/Oracle advises to empty the char array
+ java.util.Arrays.fill( password, ' ' );
+ }
+ }
+
+ String configurationFile = dispatcher.getConfigurationFile();
+
+ if ( configurationFile.startsWith( "~" ) )
+ {
+ configurationFile = System.getProperty( "user.home" ) + configurationFile.substring( 1 );
+ }
+
+ String file = System.getProperty( DefaultSecDispatcher.SYSTEM_PROPERTY_SEC_LOCATION, configurationFile );
+
+ String master = null;
+
+ SettingsSecurity sec = SecUtil.read( file, true );
+ if ( sec != null )
+ {
+ master = sec.getMaster();
+ }
+
+ if ( master == null )
+ {
+ throw new IllegalStateException( "Master password is not set in the setting security file: " + file );
+ }
+
+ DefaultPlexusCipher cipher = new DefaultPlexusCipher();
+ String masterPasswd = cipher.decryptDecorated( master, DefaultSecDispatcher.SYSTEM_PROPERTY_SEC_LOCATION );
+ System.out.println( cipher.encryptAndDecorate( passwd, masterPasswd ) );
+
+ throw new ExitException( 0 );
+ }
+ }
+
+ private void repository( CliRequest cliRequest )
+ throws Exception
+ {
+ if ( cliRequest.commandLine.hasOption( CLIManager.LEGACY_LOCAL_REPOSITORY )
+ || Boolean.getBoolean( "maven.legacyLocalRepo" ) )
+ {
+ cliRequest.request.setUseLegacyLocalRepository( true );
+ }
+ }
+
+ private int execute( CliRequest cliRequest ) throws MavenExecutionRequestPopulationException
+ {
+ MavenExecutionRequest request = executionRequestPopulator.populateDefaults( cliRequest.request );
+
+ eventSpyDispatcher.onEvent( request );
+
+ MavenExecutionResult result = maven.execute( request );
+
+ eventSpyDispatcher.onEvent( result );
+
+ eventSpyDispatcher.close();
+
+ if ( result.hasExceptions() )
+ {
+ ExceptionHandler handler = new DefaultExceptionHandler();
+
+ Map<String, String> references = new LinkedHashMap<String, String>();
+
+ MavenProject project = null;
+
+ for ( Throwable exception : result.getExceptions() )
+ {
+ ExceptionSummary summary = handler.handleException( exception );
+
+ logSummary( summary, references, "", cliRequest.showErrors );
+
+ if ( project == null && exception instanceof LifecycleExecutionException )
+ {
+ project = ( (LifecycleExecutionException) exception ).getProject();
+ }
+ }
+
+ slf4jLogger.error( "" );
+
+ if ( !cliRequest.showErrors )
+ {
+ slf4jLogger.error( "To see the full stack trace of the errors, re-run Maven with the -e switch." );
+ }
+ if ( !slf4jLogger.isDebugEnabled() )
+ {
+ slf4jLogger.error( "Re-run Maven using the -X switch to enable full debug logging." );
+ }
+
+ if ( !references.isEmpty() )
+ {
+ slf4jLogger.error( "" );
+ slf4jLogger.error( "For more information about the errors and possible solutions"
+ + ", please read the following articles:" );
+
+ for ( Map.Entry<String, String> entry : references.entrySet() )
+ {
+ slf4jLogger.error( entry.getValue() + " " + entry.getKey() );
+ }
+ }
+
+ if ( project != null && !project.equals( result.getTopologicallySortedProjects().get( 0 ) ) )
+ {
+ slf4jLogger.error( "" );
+ slf4jLogger.error( "After correcting the problems, you can resume the build with the command" );
+ slf4jLogger.error( " mvn <goals> -rf :" + project.getArtifactId() );
+ }
+
+ if ( MavenExecutionRequest.REACTOR_FAIL_NEVER.equals( cliRequest.request.getReactorFailureBehavior() ) )
+ {
+ slf4jLogger.info( "Build failures were ignored." );
+
+ return 0;
+ }
+ else
+ {
+ return 1;
+ }
+ }
+ else
+ {
+ return 0;
+ }
+ }
+
+ private void logSummary( ExceptionSummary summary, Map<String, String> references, String indent,
+ boolean showErrors )
+ {
+ String referenceKey = "";
+
+ if ( StringUtils.isNotEmpty( summary.getReference() ) )
+ {
+ referenceKey = references.get( summary.getReference() );
+ if ( referenceKey == null )
+ {
+ referenceKey = "[Help " + ( references.size() + 1 ) + "]";
+ references.put( summary.getReference(), referenceKey );
+ }
+ }
+
+ String msg = summary.getMessage();
+
+ if ( StringUtils.isNotEmpty( referenceKey ) )
+ {
+ if ( msg.indexOf( '\n' ) < 0 )
+ {
+ msg += " -> " + referenceKey;
+ }
+ else
+ {
+ msg += "\n-> " + referenceKey;
+ }
+ }
+
+ String[] lines = msg.split( "(\r\n)|(\r)|(\n)" );
+
+ for ( int i = 0; i < lines.length; i++ )
+ {
+ String line = indent + lines[i].trim();
+
+ if ( ( i == lines.length - 1 )
+ && ( showErrors || ( summary.getException() instanceof InternalErrorException ) ) )
+ {
+ slf4jLogger.error( line, summary.getException() );
+ }
+ else
+ {
+ slf4jLogger.error( line );
+ }
+ }
+
+ indent += " ";
+
+ for ( ExceptionSummary child : summary.getChildren() )
+ {
+ logSummary( child, references, indent, showErrors );
+ }
+ }
+
+ @SuppressWarnings( "checkstyle:methodlength" )
+ private void configure( CliRequest cliRequest )
+ throws Exception
+ {
+ //
+ // This is not ideal but there are events specifically for configuration from the CLI which I don't
+ // believe are really valid but there are ITs which assert the right events are published so this
+ // needs to be supported so the EventSpyDispatcher needs to be put in the CliRequest so that
+ // it can be accessed by configuration processors.
+ //
+ cliRequest.request.setEventSpyDispatcher( eventSpyDispatcher );
+
+ //
+ // We expect at most 2 implementations to be available. The SettingsXmlConfigurationProcessor implementation
+ // is always available in the core and likely always will be, but we may have another ConfigurationProcessor
+ // present supplied by the user. The rule is that we only allow the execution of one ConfigurationProcessor.
+ // If there is more than one then we execute the one supplied by the user, otherwise we execute the
+ // the default SettingsXmlConfigurationProcessor.
+ //
+ int userSuppliedConfigurationProcessorCount = configurationProcessors.size() - 1;
+
+ if ( userSuppliedConfigurationProcessorCount == 0 )
+ {
+ //
+ // Our settings.xml source is historically how we have configured Maven from the CLI so we are going to
+ // have to honour its existence forever. So let's run it.
+ //
+ configurationProcessors.get( SettingsXmlConfigurationProcessor.HINT ).process( cliRequest );
+ }
+ else if ( userSuppliedConfigurationProcessorCount == 1 )
+ {
+ //
+ // Run the user supplied ConfigurationProcessor
+ //
+ for ( Entry<String, ConfigurationProcessor> entry : configurationProcessors.entrySet() )
+ {
+ String hint = entry.getKey();
+ if ( !hint.equals( SettingsXmlConfigurationProcessor.HINT ) )
+ {
+ ConfigurationProcessor configurationProcessor = entry.getValue();
+ configurationProcessor.process( cliRequest );
+ }
+ }
+ }
+ else if ( userSuppliedConfigurationProcessorCount > 1 )
+ {
+ //
+ // There are too many ConfigurationProcessors so we don't know which one to run so report the error.
+ //
+ StringBuffer sb = new StringBuffer(
+ String.format( "\nThere can only be one user supplied ConfigurationProcessor, there are %s:\n\n",
+ userSuppliedConfigurationProcessorCount ) );
+ for ( Entry<String, ConfigurationProcessor> entry : configurationProcessors.entrySet() )
+ {
+ String hint = entry.getKey();
+ if ( !hint.equals( SettingsXmlConfigurationProcessor.HINT ) )
+ {
+ ConfigurationProcessor configurationProcessor = entry.getValue();
+ sb.append( String.format( "%s\n", configurationProcessor.getClass().getName() ) );
+ }
+ }
+ sb.append( String.format( "\n" ) );
+ throw new Exception( sb.toString() );
+ }
+ }
+
+ @SuppressWarnings( "checkstyle:methodlength" )
+ private void toolchains( CliRequest cliRequest )
+ throws Exception
+ {
+ File userToolchainsFile;
+
+ if ( cliRequest.commandLine.hasOption( CLIManager.ALTERNATE_USER_TOOLCHAINS ) )
+ {
+ userToolchainsFile =
+ new File( cliRequest.commandLine.getOptionValue( CLIManager.ALTERNATE_USER_TOOLCHAINS ) );
+ userToolchainsFile = resolveFile( userToolchainsFile, cliRequest.workingDirectory );
+
+ if ( !userToolchainsFile.isFile() )
+ {
+ throw new FileNotFoundException( "The specified user toolchains file does not exist: "
+ + userToolchainsFile );
+ }
+ }
+ else
+ {
+ userToolchainsFile = DEFAULT_USER_TOOLCHAINS_FILE;
+ }
+
+ File globalToolchainsFile;
+
+ if ( cliRequest.commandLine.hasOption( CLIManager.ALTERNATE_GLOBAL_TOOLCHAINS ) )
+ {
+ globalToolchainsFile =
+ new File( cliRequest.commandLine.getOptionValue( CLIManager.ALTERNATE_GLOBAL_TOOLCHAINS ) );
+ globalToolchainsFile = resolveFile( globalToolchainsFile, cliRequest.workingDirectory );
+
+ if ( !globalToolchainsFile.isFile() )
+ {
+ throw new FileNotFoundException( "The specified global toolchains file does not exist: "
+ + globalToolchainsFile );
+ }
+ }
+ else
+ {
+ globalToolchainsFile = DEFAULT_GLOBAL_TOOLCHAINS_FILE;
+ }
+
+ cliRequest.request.setGlobalToolchainsFile( globalToolchainsFile );
+ cliRequest.request.setUserToolchainsFile( userToolchainsFile );
+
+ DefaultToolchainsBuildingRequest toolchainsRequest = new DefaultToolchainsBuildingRequest();
+ if ( globalToolchainsFile.isFile() )
+ {
+ toolchainsRequest.setGlobalToolchainsSource( new FileSource( globalToolchainsFile ) );
+ }
+ if ( userToolchainsFile.isFile() )
+ {
+ toolchainsRequest.setUserToolchainsSource( new FileSource( userToolchainsFile ) );
+ }
+
+ eventSpyDispatcher.onEvent( toolchainsRequest );
+
+ slf4jLogger.debug( "Reading global toolchains from "
+ + getLocation( toolchainsRequest.getGlobalToolchainsSource(), globalToolchainsFile ) );
+ slf4jLogger.debug( "Reading user toolchains from "
+ + getLocation( toolchainsRequest.getUserToolchainsSource(), userToolchainsFile ) );
+
+ ToolchainsBuildingResult toolchainsResult = toolchainsBuilder.build( toolchainsRequest );
+
+ eventSpyDispatcher.onEvent( toolchainsRequest );
+
+ executionRequestPopulator.populateFromToolchains( cliRequest.request,
+ toolchainsResult.getEffectiveToolchains() );
+
+ if ( !toolchainsResult.getProblems().isEmpty() && slf4jLogger.isWarnEnabled() )
+ {
+ slf4jLogger.warn( "" );
+ slf4jLogger.warn( "Some problems were encountered while building the effective toolchains" );
+
+ for ( Problem problem : toolchainsResult.getProblems() )
+ {
+ slf4jLogger.warn( problem.getMessage() + " @ " + problem.getLocation() );
+ }
+
+ slf4jLogger.warn( "" );
+ }
+ }
+
+ private Object getLocation( Source source, File defaultLocation )
+ {
+ if ( source != null )
+ {
+ return source.getLocation();
+ }
+ return defaultLocation;
+ }
+
+ private MavenExecutionRequest populateRequest( CliRequest cliRequest )
+ {
+ return populateRequest( cliRequest, cliRequest.request );
+ }
+
+ private MavenExecutionRequest populateRequest( CliRequest cliRequest, MavenExecutionRequest request )
+ {
+ CommandLine commandLine = cliRequest.commandLine;
+ String workingDirectory = cliRequest.workingDirectory;
+ boolean quiet = cliRequest.quiet;
+ boolean showErrors = cliRequest.showErrors;
+
+ String[] deprecatedOptions = { "up", "npu", "cpu", "npr" };
+ for ( String deprecatedOption : deprecatedOptions )
+ {
+ if ( commandLine.hasOption( deprecatedOption ) )
+ {
+ slf4jLogger.warn( "Command line option -" + deprecatedOption
+ + " is deprecated and will be removed in future Maven versions." );
+ }
+ }
+
+ // ----------------------------------------------------------------------
+ // Now that we have everything that we need we will fire up plexus and
+ // bring the maven component to life for use.
+ // ----------------------------------------------------------------------
+
+ if ( commandLine.hasOption( CLIManager.BATCH_MODE ) )
+ {
+ request.setInteractiveMode( false );
+ }
+
+ boolean noSnapshotUpdates = false;
+ if ( commandLine.hasOption( CLIManager.SUPRESS_SNAPSHOT_UPDATES ) )
+ {
+ noSnapshotUpdates = true;
+ }
+
+ // ----------------------------------------------------------------------
+ //
+ // ----------------------------------------------------------------------
+
+ @SuppressWarnings( "unchecked" )
+ List<String> goals = commandLine.getArgList();
+
+ boolean recursive = true;
+
+ // this is the default behavior.
+ String reactorFailureBehaviour = MavenExecutionRequest.REACTOR_FAIL_FAST;
+
+ if ( commandLine.hasOption( CLIManager.NON_RECURSIVE ) )
+ {
+ recursive = false;
+ }
+
+ if ( commandLine.hasOption( CLIManager.FAIL_FAST ) )
+ {
+ reactorFailureBehaviour = MavenExecutionRequest.REACTOR_FAIL_FAST;
+ }
+ else if ( commandLine.hasOption( CLIManager.FAIL_AT_END ) )
+ {
+ reactorFailureBehaviour = MavenExecutionRequest.REACTOR_FAIL_AT_END;
+ }
+ else if ( commandLine.hasOption( CLIManager.FAIL_NEVER ) )
+ {
+ reactorFailureBehaviour = MavenExecutionRequest.REACTOR_FAIL_NEVER;
+ }
+
+ if ( commandLine.hasOption( CLIManager.OFFLINE ) )
+ {
+ request.setOffline( true );
+ }
+
+ boolean updateSnapshots = false;
+
+ if ( commandLine.hasOption( CLIManager.UPDATE_SNAPSHOTS ) )
+ {
+ updateSnapshots = true;
+ }
+
+ String globalChecksumPolicy = null;
+
+ if ( commandLine.hasOption( CLIManager.CHECKSUM_FAILURE_POLICY ) )
+ {
+ globalChecksumPolicy = MavenExecutionRequest.CHECKSUM_POLICY_FAIL;
+ }
+ else if ( commandLine.hasOption( CLIManager.CHECKSUM_WARNING_POLICY ) )
+ {
+ globalChecksumPolicy = MavenExecutionRequest.CHECKSUM_POLICY_WARN;
+ }
+
+ File baseDirectory = new File( workingDirectory, "" ).getAbsoluteFile();
+
+ // ----------------------------------------------------------------------
+ // Profile Activation
+ // ----------------------------------------------------------------------
+
+ List<String> activeProfiles = new ArrayList<String>();
+
+ List<String> inactiveProfiles = new ArrayList<String>();
+
+ if ( commandLine.hasOption( CLIManager.ACTIVATE_PROFILES ) )
+ {
+ String[] profileOptionValues = commandLine.getOptionValues( CLIManager.ACTIVATE_PROFILES );
+ if ( profileOptionValues != null )
+ {
+ for ( String profileOptionValue : profileOptionValues )
+ {
+ StringTokenizer profileTokens = new StringTokenizer( profileOptionValue, "," );
+
+ while ( profileTokens.hasMoreTokens() )
+ {
+ String profileAction = profileTokens.nextToken().trim();
+
+ if ( profileAction.startsWith( "-" ) || profileAction.startsWith( "!" ) )
+ {
+ inactiveProfiles.add( profileAction.substring( 1 ) );
+ }
+ else if ( profileAction.startsWith( "+" ) )
+ {
+ activeProfiles.add( profileAction.substring( 1 ) );
+ }
+ else
+ {
+ activeProfiles.add( profileAction );
+ }
+ }
+ }
+ }
+ }
+
+ TransferListener transferListener;
+
+ if ( quiet )
+ {
+ transferListener = new QuietMavenTransferListener();
+ }
+ else if ( request.isInteractiveMode() && !cliRequest.commandLine.hasOption( CLIManager.LOG_FILE ) )
+ {
+ //
+ // If we're logging to a file then we don't want the console transfer listener as it will spew
+ // download progress all over the place
+ //
+ transferListener = getConsoleTransferListener();
+ }
+ else
+ {
+ transferListener = getBatchTransferListener();
+ }
+
+ ExecutionListener executionListener = new ExecutionEventLogger();
+ if ( eventSpyDispatcher != null )
+ {
+ executionListener = eventSpyDispatcher.chainListener( executionListener );
+ }
+
+ String alternatePomFile = null;
+ if ( commandLine.hasOption( CLIManager.ALTERNATE_POM_FILE ) )
+ {
+ alternatePomFile = commandLine.getOptionValue( CLIManager.ALTERNATE_POM_FILE );
+ }
+
+ File userToolchainsFile;
+ if ( commandLine.hasOption( CLIManager.ALTERNATE_USER_TOOLCHAINS ) )
+ {
+ userToolchainsFile = new File( commandLine.getOptionValue( CLIManager.ALTERNATE_USER_TOOLCHAINS ) );
+ userToolchainsFile = resolveFile( userToolchainsFile, workingDirectory );
+ }
+ else
+ {
+ userToolchainsFile = MavenCli.DEFAULT_USER_TOOLCHAINS_FILE;
+ }
+
+ request.setBaseDirectory( baseDirectory ).setGoals( goals )
+ .setSystemProperties( cliRequest.systemProperties )
+ .setUserProperties( cliRequest.userProperties )
+ .setReactorFailureBehavior( reactorFailureBehaviour ) // default: fail fast
+ .setRecursive( recursive ) // default: true
+ .setShowErrors( showErrors ) // default: false
+ .addActiveProfiles( activeProfiles ) // optional
+ .addInactiveProfiles( inactiveProfiles ) // optional
+ .setExecutionListener( executionListener )
+ .setTransferListener( transferListener ) // default: batch mode which goes along with interactive
+ .setUpdateSnapshots( updateSnapshots ) // default: false
+ .setNoSnapshotUpdates( noSnapshotUpdates ) // default: false
+ .setGlobalChecksumPolicy( globalChecksumPolicy ) // default: warn
+ .setMultiModuleProjectDirectory( cliRequest.multiModuleProjectDirectory );
+
+ if ( alternatePomFile != null )
+ {
+ File pom = resolveFile( new File( alternatePomFile ), workingDirectory );
+ if ( pom.isDirectory() )
+ {
+ pom = new File( pom, "pom.xml" );
+ }
+
+ request.setPom( pom );
+ }
+ else if ( modelProcessor != null )
+ {
+ File pom = modelProcessor.locatePom( baseDirectory );
+
+ if ( pom.isFile() )
+ {
+ request.setPom( pom );
+ }
+ }
+
+ if ( ( request.getPom() != null ) && ( request.getPom().getParentFile() != null ) )
+ {
+ request.setBaseDirectory( request.getPom().getParentFile() );
+ }
+
+ if ( commandLine.hasOption( CLIManager.RESUME_FROM ) )
+ {
+ request.setResumeFrom( commandLine.getOptionValue( CLIManager.RESUME_FROM ) );
+ }
+
+ if ( commandLine.hasOption( CLIManager.PROJECT_LIST ) )
+ {
+ String[] projectOptionValues = commandLine.getOptionValues( CLIManager.PROJECT_LIST );
+
+ List<String> inclProjects = new ArrayList<String>();
+ List<String> exclProjects = new ArrayList<String>();
+
+ if ( projectOptionValues != null )
+ {
+ for ( String projectOptionValue : projectOptionValues )
+ {
+ StringTokenizer projectTokens = new StringTokenizer( projectOptionValue, "," );
+
+ while ( projectTokens.hasMoreTokens() )
+ {
+ String projectAction = projectTokens.nextToken().trim();
+
+ if ( projectAction.startsWith( "-" ) || projectAction.startsWith( "!" ) )
+ {
+ exclProjects.add( projectAction.substring( 1 ) );
+ }
+ else if ( projectAction.startsWith( "+" ) )
+ {
+ inclProjects.add( projectAction.substring( 1 ) );
+ }
+ else
+ {
+ inclProjects.add( projectAction );
+ }
+ }
+ }
+ }
+
+ request.setSelectedProjects( inclProjects );
+ request.setExcludedProjects( exclProjects );
+ }
+
+ if ( commandLine.hasOption( CLIManager.ALSO_MAKE )
+ && !commandLine.hasOption( CLIManager.ALSO_MAKE_DEPENDENTS ) )
+ {
+ request.setMakeBehavior( MavenExecutionRequest.REACTOR_MAKE_UPSTREAM );
+ }
+ else if ( !commandLine.hasOption( CLIManager.ALSO_MAKE )
+ && commandLine.hasOption( CLIManager.ALSO_MAKE_DEPENDENTS ) )
+ {
+ request.setMakeBehavior( MavenExecutionRequest.REACTOR_MAKE_DOWNSTREAM );
+ }
+ else if ( commandLine.hasOption( CLIManager.ALSO_MAKE )
+ && commandLine.hasOption( CLIManager.ALSO_MAKE_DEPENDENTS ) )
+ {
+ request.setMakeBehavior( MavenExecutionRequest.REACTOR_MAKE_BOTH );
+ }
+
+ String localRepoProperty = request.getUserProperties().getProperty( MavenCli.LOCAL_REPO_PROPERTY );
+
+ if ( localRepoProperty == null )
+ {
+ localRepoProperty = request.getSystemProperties().getProperty( MavenCli.LOCAL_REPO_PROPERTY );
+ }
+
+ if ( localRepoProperty != null )
+ {
+ request.setLocalRepositoryPath( localRepoProperty );
+ }
+
+ request.setCacheNotFound( true );
+ request.setCacheTransferError( false );
+
+ //
+ // Builder, concurrency and parallelism
+ //
+ // We preserve the existing methods for builder selection which is to look for various inputs in the threading
+ // configuration. We don't have an easy way to allow a pluggable builder to provide its own configuration
+ // parameters but this is sufficient for now. Ultimately we want components like Builders to provide a way to
+ // extend the command line to accept its own configuration parameters.
+ //
+ final String threadConfiguration = commandLine.hasOption( CLIManager.THREADS )
+ ? commandLine.getOptionValue( CLIManager.THREADS )
+ : request.getSystemProperties().getProperty(
+ MavenCli.THREADS_DEPRECATED ); // TODO: Remove this setting. Note that the int-tests use it
+
+ if ( threadConfiguration != null )
+ {
+ //
+ // Default to the standard multithreaded builder
+ //
+ request.setBuilderId( "multithreaded" );
+
+ if ( threadConfiguration.contains( "C" ) )
+ {
+ request.setDegreeOfConcurrency( calculateDegreeOfConcurrencyWithCoreMultiplier( threadConfiguration ) );
+ }
+ else
+ {
+ request.setDegreeOfConcurrency( Integer.valueOf( threadConfiguration ) );
+ }
+ }
+
+ //
+ // Allow the builder to be overriden by the user if requested. The builders are now pluggable.
+ //
+ if ( commandLine.hasOption( CLIManager.BUILDER ) )
+ {
+ request.setBuilderId( commandLine.getOptionValue( CLIManager.BUILDER ) );
+ }
+
+ return request;
+ }
+
+ int calculateDegreeOfConcurrencyWithCoreMultiplier( String threadConfiguration )
+ {
+ int procs = Runtime.getRuntime().availableProcessors();
+ return (int) ( Float.valueOf( threadConfiguration.replace( "C", "" ) ) * procs );
+ }
+
+ static File resolveFile( File file, String workingDirectory )
+ {
+ if ( file == null )
+ {
+ return null;
+ }
+ else if ( file.isAbsolute() )
+ {
+ return file;
+ }
+ else if ( file.getPath().startsWith( File.separator ) )
+ {
+ // drive-relative Windows path
+ return file.getAbsoluteFile();
+ }
+ else
+ {
+ return new File( workingDirectory, file.getPath() ).getAbsoluteFile();
+ }
+ }
+
+ // ----------------------------------------------------------------------
+ // System properties handling
+ // ----------------------------------------------------------------------
+
+ static void populateProperties( CommandLine commandLine, Properties systemProperties, Properties userProperties )
+ {
+ EnvironmentUtils.addEnvVars( systemProperties );
+
+ // ----------------------------------------------------------------------
+ // Options that are set on the command line become system properties
+ // and therefore are set in the session properties. System properties
+ // are most dominant.
+ // ----------------------------------------------------------------------
+
+ if ( commandLine.hasOption( CLIManager.SET_SYSTEM_PROPERTY ) )
+ {
+ String[] defStrs = commandLine.getOptionValues( CLIManager.SET_SYSTEM_PROPERTY );
+
+ if ( defStrs != null )
+ {
+ for ( String defStr : defStrs )
+ {
+ setCliProperty( defStr, userProperties );
+ }
+ }
+ }
+
+ SystemProperties.addSystemProperties( systemProperties );
+
+ // ----------------------------------------------------------------------
+ // Properties containing info about the currently running version of Maven
+ // These override any corresponding properties set on the command line
+ // ----------------------------------------------------------------------
+
+ Properties buildProperties = CLIReportingUtils.getBuildProperties();
+
+ String mavenVersion = buildProperties.getProperty( CLIReportingUtils.BUILD_VERSION_PROPERTY );
+ systemProperties.setProperty( "maven.version", mavenVersion );
+
+ String mavenBuildVersion = CLIReportingUtils.createMavenVersionString( buildProperties );
+ systemProperties.setProperty( "maven.build.version", mavenBuildVersion );
+ }
+
+ private static void setCliProperty( String property, Properties properties )
+ {
+ String name;
+
+ String value;
+
+ int i = property.indexOf( "=" );
+
+ if ( i <= 0 )
+ {
+ name = property.trim();
+
+ value = "true";
+ }
+ else
+ {
+ name = property.substring( 0, i ).trim();
+
+ value = property.substring( i + 1 );
+ }
+
+ properties.setProperty( name, value );
+
+ // ----------------------------------------------------------------------
+ // I'm leaving the setting of system properties here as not to break
+ // the SystemPropertyProfileActivator. This won't harm embedding. jvz.
+ // ----------------------------------------------------------------------
+
+ System.setProperty( name, value );
+ }
+
+ static class ExitException
+ extends Exception
+ {
+ @SuppressWarnings( "checkstyle:visibilitymodifier" )
+ public int exitCode;
+
+ public ExitException( int exitCode )
+ {
+ this.exitCode = exitCode;
+ }
+ }
+
+ //
+ // Customizations available via the CLI
+ //
+
+ protected TransferListener getConsoleTransferListener()
+ {
+ return new ConsoleMavenTransferListener( System.out );
+ }
+
+ protected TransferListener getBatchTransferListener()
+ {
+ return new Slf4jMavenTransferListener();
+ }
+
+ protected void customizeContainer( PlexusContainer container )
+ {
+ }
+
+ protected ModelProcessor createModelProcessor( PlexusContainer container )
+ throws ComponentLookupException
+ {
+ return container.lookup( ModelProcessor.class );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/configuration/ConfigurationProcessor.java b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/configuration/ConfigurationProcessor.java
new file mode 100644
index 00000000..75fb9b91
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/configuration/ConfigurationProcessor.java
@@ -0,0 +1,28 @@
+package org.apache.maven.cli.configuration;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.cli.CliRequest;
+
+public interface ConfigurationProcessor
+{
+ void process( CliRequest request )
+ throws Exception;
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/configuration/SettingsXmlConfigurationProcessor.java b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/configuration/SettingsXmlConfigurationProcessor.java
new file mode 100644
index 00000000..791a2267
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/configuration/SettingsXmlConfigurationProcessor.java
@@ -0,0 +1,290 @@
+package org.apache.maven.cli.configuration;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.util.List;
+
+import org.apache.commons.cli.CommandLine;
+import org.apache.maven.artifact.InvalidRepositoryException;
+import org.apache.maven.bridge.MavenRepositorySystem;
+import org.apache.maven.building.Source;
+import org.apache.maven.cli.CLIManager;
+import org.apache.maven.cli.CliRequest;
+import org.apache.maven.execution.MavenExecutionRequest;
+import org.apache.maven.execution.MavenExecutionRequestPopulationException;
+import org.apache.maven.settings.Mirror;
+import org.apache.maven.settings.Proxy;
+import org.apache.maven.settings.Repository;
+import org.apache.maven.settings.Server;
+import org.apache.maven.settings.Settings;
+import org.apache.maven.settings.SettingsUtils;
+import org.apache.maven.settings.building.DefaultSettingsBuildingRequest;
+import org.apache.maven.settings.building.SettingsBuilder;
+import org.apache.maven.settings.building.SettingsBuildingRequest;
+import org.apache.maven.settings.building.SettingsBuildingResult;
+import org.apache.maven.settings.building.SettingsProblem;
+import org.apache.maven.settings.crypto.SettingsDecrypter;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+import org.slf4j.Logger;
+
+@Component( role = ConfigurationProcessor.class, hint = SettingsXmlConfigurationProcessor.HINT )
+public class SettingsXmlConfigurationProcessor
+ implements ConfigurationProcessor
+{
+ public static final String HINT = "settings";
+
+ public static final String USER_HOME = System.getProperty( "user.home" );
+
+ public static final File USER_MAVEN_CONFIGURATION_HOME = new File( USER_HOME, ".m2" );
+
+ public static final File DEFAULT_USER_SETTINGS_FILE = new File( USER_MAVEN_CONFIGURATION_HOME, "settings.xml" );
+
+ public static final File DEFAULT_GLOBAL_SETTINGS_FILE = new File( System.getProperty( "maven.home", System
+ .getProperty( "user.dir", "" ) ), "conf/settings.xml" );
+
+ @Requirement
+ private Logger logger;
+
+ @Requirement
+ private SettingsBuilder settingsBuilder;
+
+ @Requirement
+ private SettingsDecrypter settingsDecrypter;
+
+ @Override
+ public void process( CliRequest cliRequest )
+ throws Exception
+ {
+ CommandLine commandLine = cliRequest.getCommandLine();
+ String workingDirectory = cliRequest.getWorkingDirectory();
+ MavenExecutionRequest request = cliRequest.getRequest();
+
+ File userSettingsFile;
+
+ if ( commandLine.hasOption( CLIManager.ALTERNATE_USER_SETTINGS ) )
+ {
+ userSettingsFile = new File( commandLine.getOptionValue( CLIManager.ALTERNATE_USER_SETTINGS ) );
+ userSettingsFile = resolveFile( userSettingsFile, workingDirectory );
+
+ if ( !userSettingsFile.isFile() )
+ {
+ throw new FileNotFoundException( "The specified user settings file does not exist: "
+ + userSettingsFile );
+ }
+ }
+ else
+ {
+ userSettingsFile = DEFAULT_USER_SETTINGS_FILE;
+ }
+
+ File globalSettingsFile;
+
+ if ( commandLine.hasOption( CLIManager.ALTERNATE_GLOBAL_SETTINGS ) )
+ {
+ globalSettingsFile = new File( commandLine.getOptionValue( CLIManager.ALTERNATE_GLOBAL_SETTINGS ) );
+ globalSettingsFile = resolveFile( globalSettingsFile, workingDirectory );
+
+ if ( !globalSettingsFile.isFile() )
+ {
+ throw new FileNotFoundException( "The specified global settings file does not exist: "
+ + globalSettingsFile );
+ }
+ }
+ else
+ {
+ globalSettingsFile = DEFAULT_GLOBAL_SETTINGS_FILE;
+ }
+
+ request.setGlobalSettingsFile( globalSettingsFile );
+ request.setUserSettingsFile( userSettingsFile );
+
+ SettingsBuildingRequest settingsRequest = new DefaultSettingsBuildingRequest();
+ settingsRequest.setGlobalSettingsFile( globalSettingsFile );
+ settingsRequest.setUserSettingsFile( userSettingsFile );
+ settingsRequest.setSystemProperties( cliRequest.getSystemProperties() );
+ settingsRequest.setUserProperties( cliRequest.getUserProperties() );
+
+ if ( request.getEventSpyDispatcher() != null )
+ {
+ request.getEventSpyDispatcher().onEvent( settingsRequest );
+ }
+
+ logger.debug( "Reading global settings from "
+ + getLocation( settingsRequest.getGlobalSettingsSource(), settingsRequest.getGlobalSettingsFile() ) );
+ logger.debug( "Reading user settings from "
+ + getLocation( settingsRequest.getUserSettingsSource(), settingsRequest.getUserSettingsFile() ) );
+
+ SettingsBuildingResult settingsResult = settingsBuilder.build( settingsRequest );
+
+ if ( request.getEventSpyDispatcher() != null )
+ {
+ request.getEventSpyDispatcher().onEvent( settingsResult );
+ }
+
+ populateFromSettings( request, settingsResult.getEffectiveSettings() );
+
+ if ( !settingsResult.getProblems().isEmpty() && logger.isWarnEnabled() )
+ {
+ logger.warn( "" );
+ logger.warn( "Some problems were encountered while building the effective settings" );
+
+ for ( SettingsProblem problem : settingsResult.getProblems() )
+ {
+ logger.warn( problem.getMessage() + " @ " + problem.getLocation() );
+ }
+ logger.warn( "" );
+ }
+ }
+
+ private MavenExecutionRequest populateFromSettings( MavenExecutionRequest request, Settings settings )
+ throws MavenExecutionRequestPopulationException
+ {
+ if ( settings == null )
+ {
+ return request;
+ }
+
+ request.setOffline( settings.isOffline() );
+
+ request.setInteractiveMode( settings.isInteractiveMode() );
+
+ request.setPluginGroups( settings.getPluginGroups() );
+
+ request.setLocalRepositoryPath( settings.getLocalRepository() );
+
+ for ( Server server : settings.getServers() )
+ {
+ server = server.clone();
+
+ request.addServer( server );
+ }
+
+ // <proxies>
+ // <proxy>
+ // <active>true</active>
+ // <protocol>http</protocol>
+ // <host>proxy.somewhere.com</host>
+ // <port>8080</port>
+ // <username>proxyuser</username>
+ // <password>somepassword</password>
+ // <nonProxyHosts>www.google.com|*.somewhere.com</nonProxyHosts>
+ // </proxy>
+ // </proxies>
+
+ for ( Proxy proxy : settings.getProxies() )
+ {
+ if ( !proxy.isActive() )
+ {
+ continue;
+ }
+
+ proxy = proxy.clone();
+
+ request.addProxy( proxy );
+ }
+
+ // <mirrors>
+ // <mirror>
+ // <id>nexus</id>
+ // <mirrorOf>*</mirrorOf>
+ // <url>http://repository.sonatype.org/content/groups/public</url>
+ // </mirror>
+ // </mirrors>
+
+ for ( Mirror mirror : settings.getMirrors() )
+ {
+ mirror = mirror.clone();
+
+ request.addMirror( mirror );
+ }
+
+ request.setActiveProfiles( settings.getActiveProfiles() );
+
+ for ( org.apache.maven.settings.Profile rawProfile : settings.getProfiles() )
+ {
+ request.addProfile( SettingsUtils.convertFromSettingsProfile( rawProfile ) );
+
+ if ( settings.getActiveProfiles().contains( rawProfile.getId() ) )
+ {
+ List<Repository> remoteRepositories = rawProfile.getRepositories();
+ for ( Repository remoteRepository : remoteRepositories )
+ {
+ try
+ {
+ request.addRemoteRepository(
+ MavenRepositorySystem.buildArtifactRepository( remoteRepository ) );
+ }
+ catch ( InvalidRepositoryException e )
+ {
+ // do nothing for now
+ }
+ }
+
+ List<Repository> pluginRepositories = rawProfile.getPluginRepositories();
+ for ( Repository pluginRepository : pluginRepositories )
+ {
+ try
+ {
+ request.addPluginArtifactRepository(
+ MavenRepositorySystem.buildArtifactRepository( pluginRepository ) );
+ }
+ catch ( InvalidRepositoryException e )
+ {
+ // do nothing for now
+ }
+ }
+ }
+ }
+ return request;
+ }
+
+ private Object getLocation( Source source, File defaultLocation )
+ {
+ if ( source != null )
+ {
+ return source.getLocation();
+ }
+ return defaultLocation;
+ }
+
+ static File resolveFile( File file, String workingDirectory )
+ {
+ if ( file == null )
+ {
+ return null;
+ }
+ else if ( file.isAbsolute() )
+ {
+ return file;
+ }
+ else if ( file.getPath().startsWith( File.separator ) )
+ {
+ // drive-relative Windows path
+ return file.getAbsoluteFile();
+ }
+ else
+ {
+ return new File( workingDirectory, file.getPath() ).getAbsoluteFile();
+ }
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/event/DefaultEventSpyContext.java b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/event/DefaultEventSpyContext.java
new file mode 100644
index 00000000..7c7976ab
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/event/DefaultEventSpyContext.java
@@ -0,0 +1,38 @@
+package org.apache.maven.cli.event;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.maven.eventspy.EventSpy;
+
+public class DefaultEventSpyContext
+ implements EventSpy.Context
+{
+
+ private final Map<String, Object> data = new HashMap<String, Object>();
+
+ public Map<String, Object> getData()
+ {
+ return data;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/event/ExecutionEventLogger.java b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/event/ExecutionEventLogger.java
new file mode 100644
index 00000000..ad3ad3a4
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/event/ExecutionEventLogger.java
@@ -0,0 +1,381 @@
+package org.apache.maven.cli.event;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import static org.apache.maven.cli.CLIReportingUtils.formatDuration;
+import static org.apache.maven.cli.CLIReportingUtils.formatTimestamp;
+
+import org.apache.maven.execution.AbstractExecutionListener;
+import org.apache.maven.execution.BuildFailure;
+import org.apache.maven.execution.BuildSuccess;
+import org.apache.maven.execution.BuildSummary;
+import org.apache.maven.execution.ExecutionEvent;
+import org.apache.maven.execution.MavenExecutionResult;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.plugin.MojoExecution;
+import org.apache.maven.plugin.descriptor.MojoDescriptor;
+import org.apache.maven.project.MavenProject;
+import org.codehaus.plexus.util.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Logs execution events to logger, eventually user-supplied.
+ *
+ * @author Benjamin Bentmann
+ */
+public class ExecutionEventLogger
+ extends AbstractExecutionListener
+{
+ private final Logger logger;
+
+ private static final int LINE_LENGTH = 72;
+ private static final int MAX_PADDED_BUILD_TIME_DURATION_LENGTH = 9;
+ private static final int MAX_PROJECT_NAME_LENGTH = 52;
+
+ public ExecutionEventLogger()
+ {
+ logger = LoggerFactory.getLogger( ExecutionEventLogger.class );
+ }
+
+ // TODO should we deprecate?
+ public ExecutionEventLogger( Logger logger )
+ {
+ if ( logger == null )
+ {
+ throw new IllegalArgumentException( "logger missing" );
+ }
+
+ this.logger = logger;
+ }
+
+ private static String chars( char c, int count )
+ {
+ StringBuilder buffer = new StringBuilder( count );
+
+ for ( int i = count; i > 0; i-- )
+ {
+ buffer.append( c );
+ }
+
+ return buffer.toString();
+ }
+
+ @Override
+ public void projectDiscoveryStarted( ExecutionEvent event )
+ {
+ if ( logger.isInfoEnabled() )
+ {
+ logger.info( "Scanning for projects..." );
+ }
+ }
+
+ @Override
+ public void sessionStarted( ExecutionEvent event )
+ {
+ if ( logger.isInfoEnabled() && event.getSession().getProjects().size() > 1 )
+ {
+ logger.info( chars( '-', LINE_LENGTH ) );
+
+ logger.info( "Reactor Build Order:" );
+
+ logger.info( "" );
+
+ for ( MavenProject project : event.getSession().getProjects() )
+ {
+ logger.info( project.getName() );
+ }
+ }
+ }
+
+ @Override
+ public void sessionEnded( ExecutionEvent event )
+ {
+ if ( logger.isInfoEnabled() )
+ {
+ if ( event.getSession().getProjects().size() > 1 )
+ {
+ logReactorSummary( event.getSession() );
+ }
+
+ logResult( event.getSession() );
+
+ logStats( event.getSession() );
+
+ logger.info( chars( '-', LINE_LENGTH ) );
+ }
+ }
+
+ private void logReactorSummary( MavenSession session )
+ {
+ logger.info( chars( '-', LINE_LENGTH ) );
+
+ logger.info( "Reactor Summary:" );
+
+ logger.info( "" );
+
+ MavenExecutionResult result = session.getResult();
+
+ for ( MavenProject project : session.getProjects() )
+ {
+ StringBuilder buffer = new StringBuilder( 128 );
+
+ buffer.append( project.getName() );
+ buffer.append( ' ' );
+
+ if ( buffer.length() <= MAX_PROJECT_NAME_LENGTH )
+ {
+ while ( buffer.length() < MAX_PROJECT_NAME_LENGTH )
+ {
+ buffer.append( '.' );
+ }
+ buffer.append( ' ' );
+ }
+
+ BuildSummary buildSummary = result.getBuildSummary( project );
+
+ if ( buildSummary == null )
+ {
+ buffer.append( "SKIPPED" );
+ }
+ else if ( buildSummary instanceof BuildSuccess )
+ {
+ buffer.append( "SUCCESS [" );
+ String buildTimeDuration = formatDuration( buildSummary.getTime() );
+ int padSize = MAX_PADDED_BUILD_TIME_DURATION_LENGTH - buildTimeDuration.length();
+ if ( padSize > 0 )
+ {
+ buffer.append( chars( ' ', padSize ) );
+ }
+ buffer.append( buildTimeDuration );
+ buffer.append( "]" );
+ }
+ else if ( buildSummary instanceof BuildFailure )
+ {
+ buffer.append( "FAILURE [" );
+ String buildTimeDuration = formatDuration( buildSummary.getTime() );
+ int padSize = MAX_PADDED_BUILD_TIME_DURATION_LENGTH - buildTimeDuration.length();
+ if ( padSize > 0 )
+ {
+ buffer.append( chars( ' ', padSize ) );
+ }
+ buffer.append( buildTimeDuration );
+ buffer.append( "]" );
+ }
+
+ logger.info( buffer.toString() );
+ }
+ }
+
+ private void logResult( MavenSession session )
+ {
+ logger.info( chars( '-', LINE_LENGTH ) );
+
+ if ( session.getResult().hasExceptions() )
+ {
+ logger.info( "BUILD FAILURE" );
+ }
+ else
+ {
+ logger.info( "BUILD SUCCESS" );
+ }
+ }
+
+ private void logStats( MavenSession session )
+ {
+ logger.info( chars( '-', LINE_LENGTH ) );
+
+ long finish = System.currentTimeMillis();
+
+ long time = finish - session.getRequest().getStartTime().getTime();
+
+ String wallClock = session.getRequest().getDegreeOfConcurrency() > 1 ? " (Wall Clock)" : "";
+
+ logger.info( "Total time: " + formatDuration( time ) + wallClock );
+
+ logger.info( "Finished at: " + formatTimestamp( finish ) );
+
+ System.gc();
+
+ Runtime r = Runtime.getRuntime();
+
+ long mb = 1024 * 1024;
+
+ logger.info( "Final Memory: " + ( r.totalMemory() - r.freeMemory() ) / mb + "M/" + r.totalMemory() / mb + "M" );
+ }
+
+ @Override
+ public void projectSkipped( ExecutionEvent event )
+ {
+ if ( logger.isInfoEnabled() )
+ {
+ logger.info( chars( ' ', LINE_LENGTH ) );
+ logger.info( chars( '-', LINE_LENGTH ) );
+
+ logger.info( "Skipping " + event.getProject().getName() );
+ logger.info( "This project has been banned from the build due to previous failures." );
+
+ logger.info( chars( '-', LINE_LENGTH ) );
+ }
+ }
+
+ @Override
+ public void projectStarted( ExecutionEvent event )
+ {
+ if ( logger.isInfoEnabled() )
+ {
+ logger.info( chars( ' ', LINE_LENGTH ) );
+ logger.info( chars( '-', LINE_LENGTH ) );
+
+ logger.info( "Building " + event.getProject().getName() + " " + event.getProject().getVersion() );
+
+ logger.info( chars( '-', LINE_LENGTH ) );
+ }
+ }
+
+ @Override
+ public void mojoSkipped( ExecutionEvent event )
+ {
+ if ( logger.isWarnEnabled() )
+ {
+ logger.warn( "Goal " + event.getMojoExecution().getGoal()
+ + " requires online mode for execution but Maven is currently offline, skipping" );
+ }
+ }
+
+ /**
+ * <pre>--- mojo-artifactId:version:goal (mojo-executionId) @ project-artifactId ---</pre>
+ */
+ @Override
+ public void mojoStarted( ExecutionEvent event )
+ {
+ if ( logger.isInfoEnabled() )
+ {
+ StringBuilder buffer = new StringBuilder( 128 );
+
+ buffer.append( "--- " );
+ append( buffer, event.getMojoExecution() );
+ append( buffer, event.getProject() );
+ buffer.append( " ---" );
+
+ logger.info( "" );
+ logger.info( buffer.toString() );
+ }
+ }
+
+ /**
+ * <pre>>>> mojo-artifactId:version:goal (mojo-executionId) > :forked-goal @ project-artifactId >>></pre>
+ * <pre>>>> mojo-artifactId:version:goal (mojo-executionId) > [lifecycle]phase @ project-artifactId >>></pre>
+ */
+ @Override
+ public void forkStarted( ExecutionEvent event )
+ {
+ if ( logger.isInfoEnabled() )
+ {
+ StringBuilder buffer = new StringBuilder( 128 );
+
+ buffer.append( ">>> " );
+ append( buffer, event.getMojoExecution() );
+ buffer.append( " > " );
+ appendForkInfo( buffer, event.getMojoExecution().getMojoDescriptor() );
+ append( buffer, event.getProject() );
+ buffer.append( " >>>" );
+
+ logger.info( "" );
+ logger.info( buffer.toString() );
+ }
+ }
+
+ // CHECKSTYLE_OFF: LineLength
+ /**
+ * <pre>&lt;&lt;&lt; mojo-artifactId:version:goal (mojo-executionId) &lt; :forked-goal @ project-artifactId &lt;&lt;&lt;</pre>
+ * <pre>&lt;&lt;&lt; mojo-artifactId:version:goal (mojo-executionId) &lt; [lifecycle]phase @ project-artifactId &lt;&lt;&lt;</pre>
+ */
+ // CHECKSTYLE_ON: LineLength
+ @Override
+ public void forkSucceeded( ExecutionEvent event )
+ {
+ if ( logger.isInfoEnabled() )
+ {
+ StringBuilder buffer = new StringBuilder( 128 );
+
+ buffer.append( "<<< " );
+ append( buffer, event.getMojoExecution() );
+ buffer.append( " < " );
+ appendForkInfo( buffer, event.getMojoExecution().getMojoDescriptor() );
+ append( buffer, event.getProject() );
+ buffer.append( " <<<" );
+
+ logger.info( "" );
+ logger.info( buffer.toString() );
+ }
+ }
+
+ private void append( StringBuilder buffer, MojoExecution me )
+ {
+ buffer.append( me.getArtifactId() ).append( ':' ).append( me.getVersion() );
+ buffer.append( ':' ).append( me.getGoal() );
+ if ( me.getExecutionId() != null )
+ {
+ buffer.append( " (" ).append( me.getExecutionId() ).append( ')' );
+ }
+ }
+
+ private void appendForkInfo( StringBuilder buffer, MojoDescriptor md )
+ {
+ if ( StringUtils.isNotEmpty( md.getExecutePhase() ) )
+ {
+ // forked phase
+ if ( StringUtils.isNotEmpty( md.getExecuteLifecycle() ) )
+ {
+ buffer.append( '[' );
+ buffer.append( md.getExecuteLifecycle() );
+ buffer.append( ']' );
+ }
+ buffer.append( md.getExecutePhase() );
+ }
+ else
+ {
+ // forked goal
+ buffer.append( ':' );
+ buffer.append( md.getExecuteGoal() );
+ }
+ }
+
+ private void append( StringBuilder buffer, MavenProject project )
+ {
+ buffer.append( " @ " ).append( project.getArtifactId() );
+ }
+
+ @Override
+ public void forkedProjectStarted( ExecutionEvent event )
+ {
+ if ( logger.isInfoEnabled() && event.getMojoExecution().getForkedExecutions().size() > 1 )
+ {
+ logger.info( chars( ' ', LINE_LENGTH ) );
+ logger.info( chars( '>', LINE_LENGTH ) );
+
+ logger.info( "Forking " + event.getProject().getName() + " " + event.getProject().getVersion() );
+
+ logger.info( chars( '>', LINE_LENGTH ) );
+ }
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/internal/BootstrapCoreExtensionManager.java b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/internal/BootstrapCoreExtensionManager.java
new file mode 100644
index 00000000..a431bded
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/internal/BootstrapCoreExtensionManager.java
@@ -0,0 +1,143 @@
+package org.apache.maven.cli.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import org.apache.maven.RepositoryUtils;
+import org.apache.maven.cli.internal.extension.model.CoreExtension;
+import org.apache.maven.execution.MavenExecutionRequest;
+import org.apache.maven.extension.internal.CoreExtensionEntry;
+import org.apache.maven.internal.aether.DefaultRepositorySystemSessionFactory;
+import org.apache.maven.model.Plugin;
+import org.apache.maven.plugin.PluginResolutionException;
+import org.apache.maven.plugin.internal.DefaultPluginDependenciesResolver;
+import org.codehaus.plexus.DefaultPlexusContainer;
+import org.codehaus.plexus.PlexusContainer;
+import org.codehaus.plexus.classworlds.ClassWorld;
+import org.codehaus.plexus.classworlds.realm.ClassRealm;
+import org.codehaus.plexus.logging.Logger;
+import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.artifact.Artifact;
+import org.eclipse.aether.graph.DependencyFilter;
+import org.eclipse.aether.graph.DependencyNode;
+import org.eclipse.aether.repository.RemoteRepository;
+import org.eclipse.aether.util.filter.ExclusionsDependencyFilter;
+import org.eclipse.aether.util.graph.visitor.PreorderNodeListGenerator;
+
+@Named
+public class BootstrapCoreExtensionManager
+{
+ private final Logger log;
+
+ private final DefaultPluginDependenciesResolver pluginDependenciesResolver;
+
+ private final DefaultRepositorySystemSessionFactory repositorySystemSessionFactory;
+
+ private final ClassWorld classWorld;
+
+ private final ClassRealm parentRealm;
+
+ @Inject
+ public BootstrapCoreExtensionManager( Logger log, DefaultPluginDependenciesResolver pluginDependenciesResolver,
+ DefaultRepositorySystemSessionFactory repositorySystemSessionFactory,
+ PlexusContainer container )
+ {
+ this.log = log;
+ this.pluginDependenciesResolver = pluginDependenciesResolver;
+ this.repositorySystemSessionFactory = repositorySystemSessionFactory;
+ this.classWorld = ( (DefaultPlexusContainer) container ).getClassWorld();
+ this.parentRealm = container.getContainerRealm();
+ }
+
+ public List<CoreExtensionEntry> loadCoreExtensions( MavenExecutionRequest request, Set<String> providedArtifacts,
+ List<CoreExtension> extensions )
+ throws Exception
+ {
+ RepositorySystemSession repoSession = repositorySystemSessionFactory.newRepositorySession( request );
+ List<RemoteRepository> repositories = RepositoryUtils.toRepos( request.getPluginArtifactRepositories() );
+
+ return resolveCoreExtensions( repoSession, repositories, providedArtifacts, extensions );
+ }
+
+ private List<CoreExtensionEntry> resolveCoreExtensions( RepositorySystemSession repoSession,
+ List<RemoteRepository> repositories,
+ Set<String> providedArtifacts,
+ List<CoreExtension> configuration )
+ throws Exception
+ {
+ List<CoreExtensionEntry> extensions = new ArrayList<CoreExtensionEntry>();
+
+ DependencyFilter dependencyFilter = new ExclusionsDependencyFilter( providedArtifacts );
+
+ for ( CoreExtension extension : configuration )
+ {
+ List<Artifact> artifacts = resolveExtension( extension, repoSession, repositories, dependencyFilter );
+ if ( !artifacts.isEmpty() )
+ {
+ extensions.add( createExtension( extension, artifacts ) );
+ }
+ }
+
+ return Collections.unmodifiableList( extensions );
+ }
+
+ private CoreExtensionEntry createExtension( CoreExtension extension, List<Artifact> artifacts )
+ throws Exception
+ {
+ String realmId =
+ "coreExtension>" + extension.getGroupId() + ":" + extension.getArtifactId() + ":" + extension.getVersion();
+ ClassRealm realm = classWorld.newRealm( realmId, null );
+ log.debug( "Populating class realm " + realm.getId() );
+ realm.setParentRealm( parentRealm );
+ for ( Artifact artifact : artifacts )
+ {
+ File file = artifact.getFile();
+ log.debug( " Included " + file );
+ realm.addURL( file.toURI().toURL() );
+ }
+ return CoreExtensionEntry.discoverFrom( realm, Collections.singleton( artifacts.get( 0 ).getFile() ) );
+ }
+
+ private List<Artifact> resolveExtension( CoreExtension extension, RepositorySystemSession repoSession,
+ List<RemoteRepository> repositories, DependencyFilter dependencyFilter )
+ throws PluginResolutionException
+ {
+ Plugin plugin = new Plugin();
+ plugin.setGroupId( extension.getGroupId() );
+ plugin.setArtifactId( extension.getArtifactId() );
+ plugin.setVersion( extension.getVersion() );
+
+ DependencyNode root =
+ pluginDependenciesResolver.resolveCoreExtension( plugin, dependencyFilter, repositories, repoSession );
+ PreorderNodeListGenerator nlg = new PreorderNodeListGenerator();
+ root.accept( nlg );
+ List<Artifact> artifacts = nlg.getArtifacts( false );
+
+ return artifacts;
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/logging/BaseSlf4jConfiguration.java b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/logging/BaseSlf4jConfiguration.java
new file mode 100644
index 00000000..33e9920e
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/logging/BaseSlf4jConfiguration.java
@@ -0,0 +1,45 @@
+package org.apache.maven.cli.logging;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Abstract implementation.
+ *
+ * @author Hervé Boutemy
+ * @since 3.1.0
+ */
+public class BaseSlf4jConfiguration
+ implements Slf4jConfiguration
+{
+ private final Logger logger = LoggerFactory.getLogger( BaseSlf4jConfiguration.class );
+
+ public void setRootLoggerLevel( Level level )
+ {
+ logger.warn( "setRootLoggerLevel: operation not supported" );
+ }
+
+ public void activate()
+ {
+ logger.warn( "reset(): operation not supported" );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/logging/Slf4jConfiguration.java b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/logging/Slf4jConfiguration.java
new file mode 100644
index 00000000..5f4b64d3
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/logging/Slf4jConfiguration.java
@@ -0,0 +1,47 @@
+package org.apache.maven.cli.logging;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Interface for configuration operations on loggers, which are not available in slf4j, then require per-slf4f-binding
+ * implementation.
+ *
+ * @author Hervé Boutemy
+ * @since 3.1.0
+ */
+public interface Slf4jConfiguration
+{
+ public static enum Level
+ {
+ DEBUG, INFO, ERROR
+ }
+
+ /**
+ * Set root logging level.
+ *
+ * @param level the level
+ */
+ void setRootLoggerLevel( Level level );
+
+ /**
+ * Activate logging implementation configuration (if necessary).
+ */
+ void activate();
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/logging/Slf4jConfigurationFactory.java b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/logging/Slf4jConfigurationFactory.java
new file mode 100644
index 00000000..b50d9442
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/logging/Slf4jConfigurationFactory.java
@@ -0,0 +1,91 @@
+package org.apache.maven.cli.logging;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.Enumeration;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+
+import org.apache.maven.cli.logging.impl.UnsupportedSlf4jBindingConfiguration;
+import org.codehaus.plexus.util.PropertyUtils;
+import org.slf4j.ILoggerFactory;
+
+/**
+ * Slf4jConfiguration factory, loading implementations from <code>META-INF/maven/slf4j-configuration.properties</code>
+ * configuration files in class loader: key is the class name of the ILoggerFactory, value is the class name of
+ * the corresponding Slf4jConfiguration.
+ *
+ * @author Hervé Boutemy
+ * @since 3.1.0
+ */
+public class Slf4jConfigurationFactory
+{
+ public static final String RESOURCE = "META-INF/maven/slf4j-configuration.properties";
+
+ public static Slf4jConfiguration getConfiguration( ILoggerFactory loggerFactory )
+ {
+ Map<URL, Set<Object>> supported = new LinkedHashMap<URL, Set<Object>>();
+
+ String slf4jBinding = loggerFactory.getClass().getCanonicalName();
+
+ try
+ {
+ Enumeration<URL> resources = Slf4jConfigurationFactory.class.getClassLoader().getResources( RESOURCE );
+
+ while ( resources.hasMoreElements() )
+ {
+ URL resource = resources.nextElement();
+
+ Properties conf = PropertyUtils.loadProperties( resource.openStream() );
+
+ String impl = conf.getProperty( slf4jBinding );
+
+ if ( impl != null )
+ {
+ return (Slf4jConfiguration) Class.forName( impl ).newInstance();
+ }
+
+ supported.put( resource, conf.keySet() );
+ }
+ }
+ catch ( IOException e )
+ {
+ e.printStackTrace();
+ }
+ catch ( InstantiationException e )
+ {
+ e.printStackTrace();
+ }
+ catch ( IllegalAccessException e )
+ {
+ e.printStackTrace();
+ }
+ catch ( ClassNotFoundException e )
+ {
+ e.printStackTrace();
+ }
+
+ return new UnsupportedSlf4jBindingConfiguration( slf4jBinding, supported );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/logging/Slf4jLogger.java b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/logging/Slf4jLogger.java
new file mode 100644
index 00000000..39574642
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/logging/Slf4jLogger.java
@@ -0,0 +1,145 @@
+package org.apache.maven.cli.logging;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.codehaus.plexus.logging.Logger;
+
+/**
+ * Adapt an SLF4J logger to a Plexus logger, ignoring Plexus logger API parts that are not classical and
+ * probably not really used.
+ *
+ * @author Jason van Zyl
+ * @since 3.1.0
+ */
+public class Slf4jLogger
+ implements Logger
+{
+
+ private org.slf4j.Logger logger;
+
+ public Slf4jLogger( org.slf4j.Logger logger )
+ {
+ this.logger = logger;
+ }
+
+ public void debug( String message )
+ {
+ logger.debug( message );
+ }
+
+ public void debug( String message, Throwable throwable )
+ {
+ logger.debug( message, throwable );
+ }
+
+ public boolean isDebugEnabled()
+ {
+ return logger.isDebugEnabled();
+ }
+
+ public void info( String message )
+ {
+ logger.info( message );
+ }
+
+ public void info( String message, Throwable throwable )
+ {
+ logger.info( message, throwable );
+ }
+
+ public boolean isInfoEnabled()
+ {
+ return logger.isInfoEnabled();
+ }
+
+ public void warn( String message )
+ {
+ logger.warn( message );
+ }
+
+ public void warn( String message, Throwable throwable )
+ {
+ logger.warn( message, throwable );
+ }
+
+ public boolean isWarnEnabled()
+ {
+ return logger.isWarnEnabled();
+ }
+
+ public void error( String message )
+ {
+ logger.error( message );
+ }
+
+ public void error( String message, Throwable throwable )
+ {
+ logger.error( message, throwable );
+ }
+
+ public boolean isErrorEnabled()
+ {
+ return logger.isErrorEnabled();
+ }
+
+ public void fatalError( String message )
+ {
+ logger.error( message );
+ }
+
+ public void fatalError( String message, Throwable throwable )
+ {
+ logger.error( message, throwable );
+ }
+
+ public boolean isFatalErrorEnabled()
+ {
+ return logger.isErrorEnabled();
+ }
+
+ /**
+ * <b>Warning</b>: ignored (always return <code>0 == Logger.LEVEL_DEBUG</code>).
+ */
+ public int getThreshold()
+ {
+ return 0;
+ }
+
+ /**
+ * <b>Warning</b>: ignored.
+ */
+ public void setThreshold( int threshold )
+ {
+ }
+
+ /**
+ * <b>Warning</b>: ignored (always return <code>null</code>).
+ */
+ public Logger getChildLogger( String name )
+ {
+ return null;
+ }
+
+ public String getName()
+ {
+ return logger.getName();
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/logging/Slf4jLoggerManager.java b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/logging/Slf4jLoggerManager.java
new file mode 100644
index 00000000..529f19eb
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/logging/Slf4jLoggerManager.java
@@ -0,0 +1,111 @@
+package org.apache.maven.cli.logging;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.codehaus.plexus.logging.Logger;
+import org.codehaus.plexus.logging.LoggerManager;
+import org.slf4j.ILoggerFactory;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Use an SLF4J {@link org.slf4j.ILoggerFactory} as a backing for a Plexus
+ * {@link org.codehaus.plexus.logging.LoggerManager},
+ * ignoring Plexus logger API parts that are not classical and probably not really used.
+ *
+ * @author Jason van Zyl
+ * @since 3.1
+ */
+public class Slf4jLoggerManager
+ implements LoggerManager
+{
+
+ private ILoggerFactory loggerFactory;
+
+ public Slf4jLoggerManager()
+ {
+ loggerFactory = LoggerFactory.getILoggerFactory();
+ }
+
+ public Logger getLoggerForComponent( String role )
+ {
+ return new Slf4jLogger( loggerFactory.getLogger( role ) );
+ }
+
+ /**
+ * The logger name for a component with a non-null hint is <code>role.hint</code>.
+ * <b>Warning</b>: this does not conform to logger name as class name convention.
+ * (and what about <code>null</code> and <code>default</code> hint equivalence?)
+ */
+ public Logger getLoggerForComponent( String role, String hint )
+ {
+ return ( null == hint
+ ? getLoggerForComponent( role )
+ : new Slf4jLogger( loggerFactory.getLogger( role + '.' + hint ) ) );
+ }
+
+ //
+ // Trying to give loggers back is a bad idea. Ceki said so :-)
+ // notice to self: what was this method supposed to do?
+ //
+ /**
+ * <b>Warning</b>: ignored.
+ */
+ public void returnComponentLogger( String role )
+ {
+ }
+
+ /**
+ * <b>Warning</b>: ignored.
+ */
+ public void returnComponentLogger( String role, String hint )
+ {
+ }
+
+ /**
+ * <b>Warning</b>: ignored (always return <code>0</code>).
+ */
+ public int getThreshold()
+ {
+ return 0;
+ }
+
+ /**
+ * <b>Warning</b>: ignored.
+ */
+ public void setThreshold( int threshold )
+ {
+ }
+
+ /**
+ * <b>Warning</b>: ignored.
+ */
+ public void setThresholds( int threshold )
+ {
+ }
+
+ /**
+ * <b>Warning</b>: ignored (always return <code>0</code>).
+ */
+ public int getActiveLoggerCount()
+ {
+ return 0;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/logging/Slf4jStdoutLogger.java b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/logging/Slf4jStdoutLogger.java
new file mode 100644
index 00000000..64b9bfde
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/logging/Slf4jStdoutLogger.java
@@ -0,0 +1,306 @@
+package org.apache.maven.cli.logging;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.PrintStream;
+
+import org.slf4j.Logger;
+import org.slf4j.Marker;
+
+/**
+ * @since 3.1.0
+ */
+public class Slf4jStdoutLogger
+ implements Logger
+{
+ private static final String ERROR = "[ERROR] ";
+
+ private PrintStream out = System.out;
+
+ //
+ // These are the only methods we need in our primordial logger
+ //
+ public void error( String msg )
+ {
+ out.print( ERROR );
+ out.println( msg );
+ }
+
+ public void error( String msg, Throwable t )
+ {
+ error( msg );
+
+ if ( null != t )
+ {
+ t.printStackTrace( out );
+ }
+ }
+
+ //
+ // Don't need any of this
+ //
+ public String getName()
+ {
+ return null;
+ }
+
+ public boolean isTraceEnabled()
+ {
+ return false;
+ }
+
+ public void trace( String msg )
+ {
+ }
+
+ public void trace( String format, Object arg )
+ {
+ }
+
+ public void trace( String format, Object arg1, Object arg2 )
+ {
+ }
+
+ public void trace( String format, Object... arguments )
+ {
+ }
+
+ public void trace( String msg, Throwable t )
+ {
+ }
+
+ public boolean isTraceEnabled( Marker marker )
+ {
+ return false;
+ }
+
+ public void trace( Marker marker, String msg )
+ {
+ }
+
+ public void trace( Marker marker, String format, Object arg )
+ {
+ }
+
+ public void trace( Marker marker, String format, Object arg1, Object arg2 )
+ {
+ }
+
+ public void trace( Marker marker, String format, Object... argArray )
+ {
+ }
+
+ public void trace( Marker marker, String msg, Throwable t )
+ {
+ }
+
+ public boolean isDebugEnabled()
+ {
+ return false;
+ }
+
+ public void debug( String msg )
+ {
+ }
+
+ public void debug( String format, Object arg )
+ {
+ }
+
+ public void debug( String format, Object arg1, Object arg2 )
+ {
+ }
+
+ public void debug( String format, Object... arguments )
+ {
+ }
+
+ public void debug( String msg, Throwable t )
+ {
+ }
+
+ public boolean isDebugEnabled( Marker marker )
+ {
+ return false;
+ }
+
+ public void debug( Marker marker, String msg )
+ {
+ }
+
+ public void debug( Marker marker, String format, Object arg )
+ {
+ }
+
+ public void debug( Marker marker, String format, Object arg1, Object arg2 )
+ {
+ }
+
+ public void debug( Marker marker, String format, Object... arguments )
+ {
+ }
+
+ public void debug( Marker marker, String msg, Throwable t )
+ {
+ }
+
+ public boolean isInfoEnabled()
+ {
+ return false;
+ }
+
+ public void info( String msg )
+ {
+ }
+
+ public void info( String format, Object arg )
+ {
+ }
+
+ public void info( String format, Object arg1, Object arg2 )
+ {
+ }
+
+ public void info( String format, Object... arguments )
+ {
+ }
+
+ public void info( String msg, Throwable t )
+ {
+ }
+
+ public boolean isInfoEnabled( Marker marker )
+ {
+ return false;
+ }
+
+ public void info( Marker marker, String msg )
+ {
+ }
+
+ public void info( Marker marker, String format, Object arg )
+ {
+ }
+
+ public void info( Marker marker, String format, Object arg1, Object arg2 )
+ {
+ }
+
+ public void info( Marker marker, String format, Object... arguments )
+ {
+ }
+
+ public void info( Marker marker, String msg, Throwable t )
+ {
+ }
+
+ public boolean isWarnEnabled()
+ {
+ return false;
+ }
+
+ public void warn( String msg )
+ {
+ }
+
+ public void warn( String format, Object arg )
+ {
+ }
+
+ public void warn( String format, Object... arguments )
+ {
+ }
+
+ public void warn( String format, Object arg1, Object arg2 )
+ {
+ }
+
+ public void warn( String msg, Throwable t )
+ {
+ }
+
+ public boolean isWarnEnabled( Marker marker )
+ {
+ return false;
+ }
+
+ public void warn( Marker marker, String msg )
+ {
+ }
+
+ public void warn( Marker marker, String format, Object arg )
+ {
+ }
+
+ public void warn( Marker marker, String format, Object arg1, Object arg2 )
+ {
+ }
+
+ public void warn( Marker marker, String format, Object... arguments )
+ {
+ }
+
+ public void warn( Marker marker, String msg, Throwable t )
+ {
+ }
+
+ public boolean isErrorEnabled()
+ {
+ return false;
+ }
+
+ public void error( String format, Object arg )
+ {
+ }
+
+ public void error( String format, Object arg1, Object arg2 )
+ {
+ }
+
+ public void error( String format, Object... arguments )
+ {
+ }
+
+ public boolean isErrorEnabled( Marker marker )
+ {
+ return false;
+ }
+
+ public void error( Marker marker, String msg )
+ {
+ }
+
+ public void error( Marker marker, String format, Object arg )
+ {
+ }
+
+ public void error( Marker marker, String format, Object arg1, Object arg2 )
+ {
+ }
+
+ public void error( Marker marker, String format, Object... arguments )
+ {
+ }
+
+ public void error( Marker marker, String msg, Throwable t )
+ {
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/logging/impl/Log4j2Configuration.java b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/logging/impl/Log4j2Configuration.java
new file mode 100644
index 00000000..b24ea9cf
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/logging/impl/Log4j2Configuration.java
@@ -0,0 +1,59 @@
+package org.apache.maven.cli.logging.impl;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.cli.logging.BaseSlf4jConfiguration;
+
+/**
+ * Configuration for slf4j-log4j2.
+ *
+ * @author Hervé Boutemy
+ * @since 3.1.0
+ */
+public class Log4j2Configuration
+ extends BaseSlf4jConfiguration
+{
+ @Override
+ public void setRootLoggerLevel( Level level )
+ {
+ String value;
+ switch ( level )
+ {
+ case DEBUG:
+ value = "debug";
+ break;
+
+ case INFO:
+ value = "info";
+ break;
+
+ default:
+ value = "error";
+ break;
+ }
+ System.setProperty( "maven.logging.root.level", value );
+ }
+
+ @Override
+ public void activate()
+ {
+ // no op
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/logging/impl/LogbackConfiguration.java b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/logging/impl/LogbackConfiguration.java
new file mode 100644
index 00000000..5d9fab74
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/logging/impl/LogbackConfiguration.java
@@ -0,0 +1,61 @@
+package org.apache.maven.cli.logging.impl;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.cli.logging.BaseSlf4jConfiguration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Configuration for slf4j-logback.
+ *
+ * @author Hervé Boutemy
+ * @since 3.1.0
+ */
+public class LogbackConfiguration
+ extends BaseSlf4jConfiguration
+{
+ @Override
+ public void setRootLoggerLevel( Level level )
+ {
+ ch.qos.logback.classic.Level value;
+ switch ( level )
+ {
+ case DEBUG:
+ value = ch.qos.logback.classic.Level.DEBUG;
+ break;
+
+ case INFO:
+ value = ch.qos.logback.classic.Level.INFO;
+ break;
+
+ default:
+ value = ch.qos.logback.classic.Level.ERROR;
+ break;
+ }
+ ( (ch.qos.logback.classic.Logger) LoggerFactory.getLogger( Logger.ROOT_LOGGER_NAME ) ).setLevel( value );
+ }
+
+ @Override
+ public void activate()
+ {
+ // no op
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/logging/impl/Slf4jSimpleConfiguration.java b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/logging/impl/Slf4jSimpleConfiguration.java
new file mode 100644
index 00000000..3961059d
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/logging/impl/Slf4jSimpleConfiguration.java
@@ -0,0 +1,63 @@
+package org.apache.maven.cli.logging.impl;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.cli.logging.BaseSlf4jConfiguration;
+import org.slf4j.MavenSlf4jFriend;
+import org.slf4j.impl.MavenSlf4jSimpleFriend;
+
+/**
+ * Configuration for slf4j-simple.
+ *
+ * @author Hervé Boutemy
+ * @since 3.1.0
+ */
+public class Slf4jSimpleConfiguration
+ extends BaseSlf4jConfiguration
+{
+ @Override
+ public void setRootLoggerLevel( Level level )
+ {
+ String value;
+ switch ( level )
+ {
+ case DEBUG:
+ value = "debug";
+ break;
+
+ case INFO:
+ value = "info";
+ break;
+
+ default:
+ value = "error";
+ break;
+ }
+ System.setProperty( "org.slf4j.simpleLogger.defaultLogLevel", value );
+ }
+
+ @Override
+ public void activate()
+ {
+ // property for root logger level or System.out redirection need to be taken into account
+ MavenSlf4jFriend.reset();
+ MavenSlf4jSimpleFriend.init();
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/logging/impl/UnsupportedSlf4jBindingConfiguration.java b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/logging/impl/UnsupportedSlf4jBindingConfiguration.java
new file mode 100644
index 00000000..2e91b251
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/logging/impl/UnsupportedSlf4jBindingConfiguration.java
@@ -0,0 +1,72 @@
+package org.apache.maven.cli.logging.impl;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.net.URL;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.maven.cli.logging.BaseSlf4jConfiguration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Pseudo-configuration for unsupported slf4j binding.
+ *
+ * @author Hervé Boutemy
+ * @since 3.2.4
+ */
+public class UnsupportedSlf4jBindingConfiguration
+ extends BaseSlf4jConfiguration
+{
+ private final Logger logger = LoggerFactory.getLogger( UnsupportedSlf4jBindingConfiguration.class );
+
+ private String slf4jBinding;
+
+ private Map<URL, Set<Object>> supported;
+
+ public UnsupportedSlf4jBindingConfiguration( String slf4jBinding, Map<URL, Set<Object>> supported )
+ {
+ this.slf4jBinding = slf4jBinding;
+ this.supported = supported;
+ }
+
+ @Override
+ public void activate()
+ {
+ logger.warn( "The SLF4J binding actually used is not supported by Maven: " + slf4jBinding );
+ logger.warn( "Maven supported bindings are:" );
+
+ String ls = System.getProperty( "line.separator" );
+
+ for ( Map.Entry<URL, Set<Object>> entry : supported.entrySet() )
+ {
+ StringBuilder sb = new StringBuilder();
+ sb.append( "(from " ).append( entry.getKey().toExternalForm() ).append( ")" );
+
+ for ( Object binding : entry.getValue() )
+ {
+ sb.append( ls ).append( "- " ).append( binding );
+ }
+
+ logger.warn( sb.toString() );
+ }
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/transfer/AbstractMavenTransferListener.java b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/transfer/AbstractMavenTransferListener.java
new file mode 100644
index 00000000..58b1a5dc
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/transfer/AbstractMavenTransferListener.java
@@ -0,0 +1,90 @@
+package org.apache.maven.cli.transfer;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.PrintStream;
+import java.text.DecimalFormat;
+import java.text.DecimalFormatSymbols;
+import java.util.Locale;
+
+import org.eclipse.aether.transfer.AbstractTransferListener;
+import org.eclipse.aether.transfer.TransferCancelledException;
+import org.eclipse.aether.transfer.TransferEvent;
+import org.eclipse.aether.transfer.TransferResource;
+
+public abstract class AbstractMavenTransferListener
+ extends AbstractTransferListener
+{
+
+ protected PrintStream out;
+
+ protected AbstractMavenTransferListener( PrintStream out )
+ {
+ this.out = out;
+ }
+
+ @Override
+ public void transferInitiated( TransferEvent event )
+ {
+ String message = event.getRequestType() == TransferEvent.RequestType.PUT ? "Uploading" : "Downloading";
+
+ out.println( message + ": " + event.getResource().getRepositoryUrl() + event.getResource().getResourceName() );
+ }
+
+ @Override
+ public void transferCorrupted( TransferEvent event )
+ throws TransferCancelledException
+ {
+ TransferResource resource = event.getResource();
+
+ out.println( "[WARNING] " + event.getException().getMessage() + " for " + resource.getRepositoryUrl()
+ + resource.getResourceName() );
+ }
+
+ @Override
+ public void transferSucceeded( TransferEvent event )
+ {
+ TransferResource resource = event.getResource();
+ long contentLength = event.getTransferredBytes();
+ if ( contentLength >= 0 )
+ {
+ String type = ( event.getRequestType() == TransferEvent.RequestType.PUT ? "Uploaded" : "Downloaded" );
+ String len = contentLength >= 1024 ? toKB( contentLength ) + " KB" : contentLength + " B";
+
+ String throughput = "";
+ long duration = System.currentTimeMillis() - resource.getTransferStartTime();
+ if ( duration > 0 )
+ {
+ DecimalFormat format = new DecimalFormat( "0.0", new DecimalFormatSymbols( Locale.ENGLISH ) );
+ double kbPerSec = ( contentLength / 1024.0 ) / ( duration / 1000.0 );
+ throughput = " at " + format.format( kbPerSec ) + " KB/sec";
+ }
+
+ out.println( type + ": " + resource.getRepositoryUrl() + resource.getResourceName() + " (" + len
+ + throughput + ")" );
+ }
+ }
+
+ protected long toKB( long bytes )
+ {
+ return ( bytes + 1023 ) / 1024;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/transfer/BatchModeMavenTransferListener.java b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/transfer/BatchModeMavenTransferListener.java
new file mode 100644
index 00000000..0e20f17f
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/transfer/BatchModeMavenTransferListener.java
@@ -0,0 +1,32 @@
+package org.apache.maven.cli.transfer;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.PrintStream;
+
+public class BatchModeMavenTransferListener
+ extends AbstractMavenTransferListener
+{
+ public BatchModeMavenTransferListener( PrintStream out )
+ {
+ super( out );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/transfer/ConsoleMavenTransferListener.java b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/transfer/ConsoleMavenTransferListener.java
new file mode 100644
index 00000000..46725024
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/transfer/ConsoleMavenTransferListener.java
@@ -0,0 +1,133 @@
+package org.apache.maven.cli.transfer;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.PrintStream;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.eclipse.aether.transfer.TransferCancelledException;
+import org.eclipse.aether.transfer.TransferEvent;
+import org.eclipse.aether.transfer.TransferResource;
+
+/**
+ * Console download progress meter.
+ *
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ */
+public class ConsoleMavenTransferListener
+ extends AbstractMavenTransferListener
+{
+
+ private Map<TransferResource, Long> downloads = new ConcurrentHashMap<TransferResource, Long>();
+
+ private int lastLength;
+
+ public ConsoleMavenTransferListener( PrintStream out )
+ {
+ super( out );
+ }
+
+ @Override
+ public void transferProgressed( TransferEvent event )
+ throws TransferCancelledException
+ {
+ TransferResource resource = event.getResource();
+ downloads.put( resource, event.getTransferredBytes() );
+
+ StringBuilder buffer = new StringBuilder( 64 );
+
+ for ( Map.Entry<TransferResource, Long> entry : downloads.entrySet() )
+ {
+ long total = entry.getKey().getContentLength();
+ Long complete = entry.getValue();
+ // NOTE: This null check guards against http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6312056
+ if ( complete != null )
+ {
+ buffer.append( getStatus( complete, total ) ).append( " " );
+ }
+ }
+
+ int pad = lastLength - buffer.length();
+ lastLength = buffer.length();
+ pad( buffer, pad );
+ buffer.append( '\r' );
+
+ out.print( buffer.toString() );
+ }
+
+ private String getStatus( long complete, long total )
+ {
+ if ( total >= 1024 )
+ {
+ return toKB( complete ) + "/" + toKB( total ) + " KB ";
+ }
+ else if ( total >= 0 )
+ {
+ return complete + "/" + total + " B ";
+ }
+ else if ( complete >= 1024 )
+ {
+ return toKB( complete ) + " KB ";
+ }
+ else
+ {
+ return complete + " B ";
+ }
+ }
+
+ private void pad( StringBuilder buffer, int spaces )
+ {
+ String block = " ";
+ while ( spaces > 0 )
+ {
+ int n = Math.min( spaces, block.length() );
+ buffer.append( block, 0, n );
+ spaces -= n;
+ }
+ }
+
+ @Override
+ public void transferSucceeded( TransferEvent event )
+ {
+ transferCompleted( event );
+
+ super.transferSucceeded( event );
+ }
+
+ @Override
+ public void transferFailed( TransferEvent event )
+ {
+ transferCompleted( event );
+
+ super.transferFailed( event );
+ }
+
+ private void transferCompleted( TransferEvent event )
+ {
+ downloads.remove( event.getResource() );
+
+ StringBuilder buffer = new StringBuilder( 64 );
+ pad( buffer, lastLength );
+ buffer.append( '\r' );
+ out.print( buffer.toString() );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/transfer/QuietMavenTransferListener.java b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/transfer/QuietMavenTransferListener.java
new file mode 100644
index 00000000..fd9f52cf
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/transfer/QuietMavenTransferListener.java
@@ -0,0 +1,31 @@
+package org.apache.maven.cli.transfer;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.eclipse.aether.transfer.AbstractTransferListener;
+
+/**
+ * @author Benjamin Bentmann
+ */
+public class QuietMavenTransferListener
+ extends AbstractTransferListener
+{
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/transfer/Slf4jMavenTransferListener.java b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/transfer/Slf4jMavenTransferListener.java
new file mode 100644
index 00000000..bb72db36
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/transfer/Slf4jMavenTransferListener.java
@@ -0,0 +1,97 @@
+package org.apache.maven.cli.transfer;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.text.DecimalFormat;
+import java.text.DecimalFormatSymbols;
+import java.util.Locale;
+
+import org.eclipse.aether.transfer.AbstractTransferListener;
+import org.eclipse.aether.transfer.TransferCancelledException;
+import org.eclipse.aether.transfer.TransferEvent;
+import org.eclipse.aether.transfer.TransferResource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class Slf4jMavenTransferListener
+ extends AbstractTransferListener
+{
+
+ protected final Logger out;
+
+ public Slf4jMavenTransferListener()
+ {
+ this.out = LoggerFactory.getLogger( Slf4jMavenTransferListener.class );
+ }
+
+ // TODO should we deprecate?
+ public Slf4jMavenTransferListener( Logger out )
+ {
+ this.out = out;
+ }
+
+ @Override
+ public void transferInitiated( TransferEvent event )
+ {
+ String message = event.getRequestType() == TransferEvent.RequestType.PUT ? "Uploading" : "Downloading";
+
+ out.info( message + ": " + event.getResource().getRepositoryUrl() + event.getResource().getResourceName() );
+ }
+
+ @Override
+ public void transferCorrupted( TransferEvent event )
+ throws TransferCancelledException
+ {
+ TransferResource resource = event.getResource();
+
+ out.warn( event.getException().getMessage() + " for " + resource.getRepositoryUrl()
+ + resource.getResourceName() );
+ }
+
+ @Override
+ public void transferSucceeded( TransferEvent event )
+ {
+ TransferResource resource = event.getResource();
+ long contentLength = event.getTransferredBytes();
+ if ( contentLength >= 0 )
+ {
+ String type = ( event.getRequestType() == TransferEvent.RequestType.PUT ? "Uploaded" : "Downloaded" );
+ String len = contentLength >= 1024 ? toKB( contentLength ) + " KB" : contentLength + " B";
+
+ String throughput = "";
+ long duration = System.currentTimeMillis() - resource.getTransferStartTime();
+ if ( duration > 0 )
+ {
+ DecimalFormat format = new DecimalFormat( "0.0", new DecimalFormatSymbols( Locale.ENGLISH ) );
+ double kbPerSec = ( contentLength / 1024.0 ) / ( duration / 1000.0 );
+ throughput = " at " + format.format( kbPerSec ) + " KB/sec";
+ }
+
+ out.info( type + ": " + resource.getRepositoryUrl() + resource.getResourceName() + " (" + len
+ + throughput + ")" );
+ }
+ }
+
+ protected long toKB( long bytes )
+ {
+ return ( bytes + 1023 ) / 1024;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/slf4j/MavenSlf4jFriend.java b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/slf4j/MavenSlf4jFriend.java
new file mode 100644
index 00000000..8a430537
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/slf4j/MavenSlf4jFriend.java
@@ -0,0 +1,35 @@
+package org.slf4j;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Utility for Maven to access Slf4j internals through package access.
+ * Use with precaution, since this is not normally intended for production use.
+ */
+public class MavenSlf4jFriend
+{
+ /**
+ * Reset Slf4j internal state.
+ */
+ public static void reset()
+ {
+ LoggerFactory.reset();
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/slf4j/impl/MavenSlf4jSimpleFriend.java b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/slf4j/impl/MavenSlf4jSimpleFriend.java
new file mode 100644
index 00000000..bffd18c6
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/slf4j/impl/MavenSlf4jSimpleFriend.java
@@ -0,0 +1,40 @@
+package org.slf4j.impl;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.slf4j.ILoggerFactory;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Utility for Maven to access Slf4j-Simple internals through package access.
+ * Use with precaution, since this is not normally intended for production use.
+ */
+public class MavenSlf4jSimpleFriend
+{
+ public static void init()
+ {
+ SimpleLogger.init();
+ ILoggerFactory loggerFactory = LoggerFactory.getILoggerFactory();
+ if ( loggerFactory instanceof SimpleLoggerFactory )
+ {
+ ( (SimpleLoggerFactory) loggerFactory ).reset();
+ }
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/mdo/core-extensions.mdo b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/mdo/core-extensions.mdo
new file mode 100644
index 00000000..3a8d80ad
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/mdo/core-extensions.mdo
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<model xmlns="http://modello.codehaus.org/MODELLO/1.4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://modello.codehaus.org/MODELLO/1.4.0 http://modello.codehaus.org/xsd/modello-1.4.0.xsd"
+ xml.namespace="http://maven.apache.org/EXTENSIONS/${version}"
+ xml.schemaLocation="http://maven.apache.org/xsd/core-extensions-${version}.xsd">
+
+ <id>core-extensions</id>
+ <name>CoreExtensions</name>
+ <description><![CDATA[
+ <p>This is a reference for the Core Extensions descriptor.</p>
+ <p>The default location for the Core Extensions descriptor file is <code>${maven.projectBasedir}/.mvn/extensions.xml</code></p>
+ ]]></description>
+
+ <defaults>
+ <default>
+ <key>package</key>
+ <value>org.apache.maven.cli.internal.extension.model</value>
+ </default>
+ </defaults>
+
+ <classes>
+ <class rootElement="true" xml.tagName="extensions" xsd.compositor="sequence">
+ <name>CoreExtensions</name>
+ <description>Extensions to load.</description>
+ <version>1.0.0+</version>
+ <fields>
+ <field>
+ <name>extensions</name>
+ <description>A set of build extensions to use from this project.</description>
+ <version>1.0.0+</version>
+ <association xml.itemsStyle="flat">
+ <type>CoreExtension</type>
+ <multiplicity>*</multiplicity>
+ </association>
+ </field>
+ </fields>
+ </class>
+ <class xml.tagName="extension">
+ <name>CoreExtension</name>
+ <description>Describes a build extension to utilise.</description>
+ <version>1.0.0+</version>
+ <fields>
+ <field>
+ <name>groupId</name>
+ <description>The group ID of the extension's artifact.</description>
+ <version>1.0.0+</version>
+ <required>true</required>
+ <type>String</type>
+ </field>
+ <field>
+ <name>artifactId</name>
+ <description>The artifact ID of the extension.</description>
+ <version>1.0.0+</version>
+ <required>true</required>
+ <type>String</type>
+ </field>
+ <field>
+ <name>version</name>
+ <description>The version of the extension.</description>
+ <version>1.0.0+</version>
+ <required>true</required>
+ <type>String</type>
+ </field>
+ </fields>
+ </class>
+ </classes>
+</model>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/resources/META-INF/MANIFEST.MF b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/resources/META-INF/MANIFEST.MF
new file mode 100644
index 00000000..57576ed9
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/resources/META-INF/MANIFEST.MF
@@ -0,0 +1,7 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Maven 2.x Embedder Plug-in
+Bundle-Vendor: maven.org
+Bundle-SymbolicName: org.maven.ide.embedder
+Bundle-Version: ${bundleVersion}
+Bundle-ClassPath: .
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/resources/META-INF/maven/slf4j-configuration.properties b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/resources/META-INF/maven/slf4j-configuration.properties
new file mode 100644
index 00000000..87418363
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/resources/META-INF/maven/slf4j-configuration.properties
@@ -0,0 +1,22 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+# key = Slf4j effective logger factory implementation
+# value = corresponding o.a.m.cli.logging.Slf4jConfiguration class
+org.slf4j.impl.SimpleLoggerFactory org.apache.maven.cli.logging.impl.Slf4jSimpleConfiguration
+org.slf4j.helpers.Log4jLoggerFactory org.apache.maven.cli.logging.impl.Log4j2Configuration
+ch.qos.logback.classic.LoggerContext org.apache.maven.cli.logging.impl.LogbackConfiguration
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/site/apt/cli.apt.vm b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/site/apt/cli.apt.vm
new file mode 100644
index 00000000..b5dcae71
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/site/apt/cli.apt.vm
@@ -0,0 +1,28 @@
+~~ Licensed to the Apache Software Foundation (ASF) under one
+~~ or more contributor license agreements. See the NOTICE file
+~~ distributed with this work for additional information
+~~ regarding copyright ownership. The ASF licenses this file
+~~ to you under the Apache License, Version 2.0 (the
+~~ "License"); you may not use this file except in compliance
+~~ with the License. You may obtain a copy of the License at
+~~
+~~ http://www.apache.org/licenses/LICENSE-2.0
+~~
+~~ Unless required by applicable law or agreed to in writing,
+~~ software distributed under the License is distributed on an
+~~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+~~ KIND, either express or implied. See the License for the
+~~ specific language governing permissions and limitations
+~~ under the License.
+
+ -----
+ Maven CLI Options Reference
+ -----
+ Hervé Boutemy
+ -----
+ 2012-04-29
+ -----
+
+Maven CLI Options Reference
+
+%{snippet|file=${project.basedir}/target/test-classes/options.html|verbatim=false}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/site/apt/index.apt.vm b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/site/apt/index.apt.vm
new file mode 100644
index 00000000..519fdae2
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/site/apt/index.apt.vm
@@ -0,0 +1,42 @@
+~~ Licensed to the Apache Software Foundation (ASF) under one
+~~ or more contributor license agreements. See the NOTICE file
+~~ distributed with this work for additional information
+~~ regarding copyright ownership. The ASF licenses this file
+~~ to you under the Apache License, Version 2.0 (the
+~~ "License"); you may not use this file except in compliance
+~~ with the License. You may obtain a copy of the License at
+~~
+~~ http://www.apache.org/licenses/LICENSE-2.0
+~~
+~~ Unless required by applicable law or agreed to in writing,
+~~ software distributed under the License is distributed on an
+~~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+~~ KIND, either express or implied. See the License for the
+~~ specific language governing permissions and limitations
+~~ under the License.
+
+ -----
+ ${project.name}
+ -----
+ Hervé Boutemy
+ -----
+ 2015-03-12
+ -----
+
+${project.name}
+
+ ${project.description}
+
+* References
+
+ * {{{./cli.html}CLI options}},
+
+ * {{{./logging.html}logging API}}.
+
+ * since 3.3.0, per project settings can be defined by files in <<<.mvn/>>> directory:
+
+ * <<<.mvn/jvm.config>>> containing jvm options,
+
+ * <<<.mvn/maven.config>>> containing Maven command-line parameter,
+
+ * <<<.mvn/extensions.xml>>> containing {{{./core-extensions.html}a list of extensions}}.
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/site/apt/logging.apt b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/site/apt/logging.apt
new file mode 100644
index 00000000..cc9257d3
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/site/apt/logging.apt
@@ -0,0 +1,112 @@
+~~ Licensed to the Apache Software Foundation (ASF) under one
+~~ or more contributor license agreements. See the NOTICE file
+~~ distributed with this work for additional information
+~~ regarding copyright ownership. The ASF licenses this file
+~~ to you under the Apache License, Version 2.0 (the
+~~ "License"); you may not use this file except in compliance
+~~ with the License. You may obtain a copy of the License at
+~~
+~~ http://www.apache.org/licenses/LICENSE-2.0
+~~
+~~ Unless required by applicable law or agreed to in writing,
+~~ software distributed under the License is distributed on an
+~~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+~~ KIND, either express or implied. See the License for the
+~~ specific language governing permissions and limitations
+~~ under the License.
+
+ -----
+ Maven Logging
+ -----
+ Hervé Boutemy
+ -----
+ 2013-08-02
+ -----
+
+Maven Logging
+
+ End-user logging documentation is available {{{/maven-logging.html}in Maven site}}.
+ This documentation is focused on internal implementation details.
+
+* Logging API
+
+ Maven uses
+ {{{http://plexus.codehaus.org/plexus-containers/plexus-container-default/apidocs/org/codehaus/plexus/logging/package-summary.html}Plexus
+ Container logging API}}, like any other Plexus components, ie
+ {{{http://plexus.codehaus.org/plexus-containers/plexus-container-default/apidocs/org/codehaus/plexus/logging/LoggerManager.html}LoggerManager}}
+ / {{{http://plexus.codehaus.org/plexus-containers/plexus-container-default/apidocs/org/codehaus/plexus/logging/Logger.html}Logger}}.
+
+ Starting with Maven 3.1.0:
+
+ * Maven supports SLF4J API logging API too, ie {{{http://slf4j.org/apidocs/org/slf4j/LoggerFactory.html}LoggerFactory}} /
+ {{{http://slf4j.org/apidocs/org/slf4j/Logger.html}Logger}},
+
+ * instead of implementing Plexus logging API itself with basic output to console, Maven implements it using SLF4J API in
+ {{{./apidocs/org/apache/maven/cli/logging/Slf4jLoggerManager.html}Slf4jLoggerManager}}
+ / {{{./apidocs/org/apache/maven/cli/logging/Slf4jLogger.html}Slf4jLogger}}.
+
+
+* Logging Implementation
+
+ Maven 3.1.0 ships bundled with {{{http://www.slf4j.org/apidocs/org/slf4j/impl/SimpleLogger.html}SLF4J simple logger}},
+ but is ready to use other logging implementations: SLF4J is responsible for loading the implementation, referred to as
+ {{{http://www.slf4j.org/manual.html#swapping}"SLF4J bindings"}}.
+
+ Logging configuration loading is actually done by logging implementation, without any Maven extensions to support merging
+ Maven installation configuration with per-user configuration for example:
+ `${maven.home}/conf/logging` directory was added to core's classpath (see `${maven.home}/bin/m2.conf`). See your implementation
+ documentation for details on file names, formats, and so on.
+
+ During Maven initialization, Maven tweaks default root logging level to match CLI verbosity choice. Since such feature isn't available
+ in SLF4J API, logging implementation specific extensions need to be added into Maven to support these CLI options: see
+ {{{./apidocs/org/apache/maven/cli/logging/Slf4jConfigurationFactory.html}Slf4jConfigurationFactory}} /
+ {{{./apidocs/org/apache/maven/cli/logging/Slf4jConfiguration.html}Slf4jConfiguration}}.
+
+* Getting Logger Instance
+
+ Plexus Logger and LoggerManager can be injected in Plexus component using Plexus annotations
+
++------+
+import org.codehaus.plexus.logging.Logger;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+
+@Component( role = MyComponent.class )
+public class DefaultMyComponent
+ implements MyComponent
+{
+ @Requirement
+ private Logger logger;
+
+ @Requirement
+ private LoggerManager loggerManager;
+}
++------+
+
+ Starting with Maven 3.1.0, SLF4J Logger can be used directly too, without Plexus. Of course, this will only work when run under
+ Maven 3.1.0, then this technique can be used safely only in Maven core components or in plugins/component not requiring
+ compatibility with previous Maven versions.
+
++-----+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class MyClass
+{
+ final Logger logger = LoggerFactory.getLogger( MyClass.class );
+}
++-----+
+
+* Logger Name
+
+ Before Maven 3.1.0, with logging implementation done in Maven, logger name wasn't used by basic console logging implementation:
+ they are as-is, without clear convention on when to pass logger from class to class or when to create a new logger.
+
+ Starting with Maven 3.1.0, logging implementation can be of greatest use if logger names are well defined. This definition still
+ needs to be defined and implemented:
+
+ * classical "class name" pattern?
+
+ * Maven-specific name hierarchy?
+
+ * a mix (some with class name, some with Maven-specific hierarchy)?
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/site/site.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/site/site.xml
new file mode 100644
index 00000000..71dc6c84
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/site/site.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project xmlns="http://maven.apache.org/DECORATION/1.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/DECORATION/1.0.0 http://maven.apache.org/xsd/decoration-1.0.0.xsd">
+ <body>
+ <menu name="Overview">
+ <item name="Introduction" href="index.html"/>
+ <item name="JavaDocs" href="apidocs/index.html"/>
+ <item name="Source Xref" href="xref/index.html"/>
+ <!--item name="FAQ" href="faq.html"/-->
+ </menu>
+
+ <menu name="Reference">
+ <item name="CLI options" href="cli.html"/>
+ </menu>
+
+ <menu ref="parent"/>
+ <menu ref="reports"/>
+ </body>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/embedder-test-project/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/embedder-test-project/pom.xml
new file mode 100644
index 00000000..aed15161
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/embedder-test-project/pom.xml
@@ -0,0 +1,48 @@
+
+ <!--
+ Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE
+ file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by
+ applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language
+ governing permissions and limitations under the License.
+ -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>embedder-test-project</artifactId>
+ <packaging>jar</packaging>
+ <version>1.0-SNAPSHOT</version>
+ <name>Maven Quick Start Archetype</name>
+ <url>http://maven.apache.org</url>
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>3.8.1</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+ <profiles>
+ <profile>
+ <id>embedderProfile</id>
+ <properties>
+ <embedderProfile>true</embedderProfile>
+ <name>jason</name>
+ <occupation>somnambulance</occupation>
+ </properties>
+ </profile>
+ </profiles>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>2.4.3</version>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/embedder-test-project/src/main/java/org/apache/maven/App.java b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/embedder-test-project/src/main/java/org/apache/maven/App.java
new file mode 100644
index 00000000..3902bac5
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/embedder-test-project/src/main/java/org/apache/maven/App.java
@@ -0,0 +1,13 @@
+package org.apache.maven;
+
+/**
+ * Hello world!
+ *
+ */
+public class App
+{
+ public static void main( String[] args )
+ {
+ System.out.println( "Hello World!" );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/embedder-test-project/src/test/java/org/apache/maven/AppTest.java b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/embedder-test-project/src/test/java/org/apache/maven/AppTest.java
new file mode 100644
index 00000000..7a879cec
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/embedder-test-project/src/test/java/org/apache/maven/AppTest.java
@@ -0,0 +1,38 @@
+package org.apache.maven;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+/**
+ * Unit test for simple App.
+ */
+public class AppTest
+ extends TestCase
+{
+ /**
+ * Create the test case
+ *
+ * @param testName name of the test case
+ */
+ public AppTest( String testName )
+ {
+ super( testName );
+ }
+
+ /**
+ * @return the suite of tests being tested
+ */
+ public static Test suite()
+ {
+ return new TestSuite( AppTest.class );
+ }
+
+ /**
+ * Rigourous Test :-)
+ */
+ public void testApp()
+ {
+ assertTrue( true );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/aggregate-mojo-failure/plugin/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/aggregate-mojo-failure/plugin/pom.xml
new file mode 100644
index 00000000..a0dfb082
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/aggregate-mojo-failure/plugin/pom.xml
@@ -0,0 +1,49 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven.errortest</groupId>
+ <artifactId>aggregate-mojo-failure-maven-plugin</artifactId>
+ <packaging>maven-plugin</packaging>
+ <version>1</version>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-plugin-api</artifactId>
+ <version>2.0</version>
+ </dependency>
+ </dependencies>
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>2.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-deploy-plugin</artifactId>
+ <version>2.3</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-install-plugin</artifactId>
+ <version>2.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-resources-plugin</artifactId>
+ <version>2.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-jar-plugin</artifactId>
+ <version>2.1</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>2.0.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-plugin-plugin</artifactId>
+ <version>2.3</version>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/aggregate-mojo-failure/plugin/src/main/java/org/plugin/TestPlugin.java b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/aggregate-mojo-failure/plugin/src/main/java/org/plugin/TestPlugin.java
new file mode 100644
index 00000000..ec251830
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/aggregate-mojo-failure/plugin/src/main/java/org/plugin/TestPlugin.java
@@ -0,0 +1,36 @@
+package org.plugin;
+
+import org.apache.maven.plugin.Mojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugin.logging.Log;
+
+/**
+ * @goal test
+ * @aggregator
+ *
+ * @author jdcasey
+ */
+public class TestPlugin
+ implements Mojo
+{
+
+ private Log log;
+
+ public void execute()
+ throws MojoExecutionException, MojoFailureException
+ {
+ throw new MojoFailureException( this, "This mojo will always fail.", "This mojo is programmed to fail at all times, to express certain error-reporting functions." );
+ }
+
+ public Log getLog()
+ {
+ return log;
+ }
+
+ public void setLog( Log log )
+ {
+ this.log = log;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/aggregate-mojo-failure/project/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/aggregate-mojo-failure/project/pom.xml
new file mode 100644
index 00000000..cddcc140
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/aggregate-mojo-failure/project/pom.xml
@@ -0,0 +1,25 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>aggregate-mojo-failure</artifactId>
+ <version>1</version>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/bad-build-plan/plugin/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/bad-build-plan/plugin/pom.xml
new file mode 100644
index 00000000..0a0c0d77
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/bad-build-plan/plugin/pom.xml
@@ -0,0 +1,49 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven.errortest</groupId>
+ <artifactId>bad-build-plan-maven-plugin</artifactId>
+ <packaging>maven-plugin</packaging>
+ <version>1</version>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-plugin-api</artifactId>
+ <version>2.0</version>
+ </dependency>
+ </dependencies>
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>2.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-deploy-plugin</artifactId>
+ <version>2.3</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-install-plugin</artifactId>
+ <version>2.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-resources-plugin</artifactId>
+ <version>2.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-jar-plugin</artifactId>
+ <version>2.1</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>2.0.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-plugin-plugin</artifactId>
+ <version>2.3</version>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/bad-build-plan/plugin/src/main/java/org/plugin/TestPlugin.java b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/bad-build-plan/plugin/src/main/java/org/plugin/TestPlugin.java
new file mode 100644
index 00000000..b5e6ecd5
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/bad-build-plan/plugin/src/main/java/org/plugin/TestPlugin.java
@@ -0,0 +1,35 @@
+package org.plugin;
+
+import org.apache.maven.plugin.Mojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugin.logging.Log;
+
+/**
+ * @goal test
+ * @execute goal="my:something:else:that:is:wrong"
+ *
+ * @author jdcasey
+ */
+public class TestPlugin
+ implements Mojo
+{
+
+ private Log log;
+
+ public void execute()
+ throws MojoExecutionException, MojoFailureException
+ {
+ }
+
+ public Log getLog()
+ {
+ return log;
+ }
+
+ public void setLog( Log log )
+ {
+ this.log = log;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/bad-build-plan/project/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/bad-build-plan/project/pom.xml
new file mode 100644
index 00000000..6a4bcda3
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/bad-build-plan/project/pom.xml
@@ -0,0 +1,25 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>bad-build-plan</artifactId>
+ <version>1</version>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/bad-dep-version/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/bad-dep-version/pom.xml
new file mode 100644
index 00000000..cfd29708
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/bad-dep-version/pom.xml
@@ -0,0 +1,33 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>bad-dep-version</artifactId>
+ <version>1</version>
+
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>[3.1,</version>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/bad-ext-direct-deps/local-repo/org/apache/maven/errortest/test-maven-ext/1/test-maven-ext-1.pom b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/bad-ext-direct-deps/local-repo/org/apache/maven/errortest/test-maven-ext/1/test-maven-ext-1.pom
new file mode 100644
index 00000000..dcaf397e
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/bad-ext-direct-deps/local-repo/org/apache/maven/errortest/test-maven-ext/1/test-maven-ext-1.pom
@@ -0,0 +1,34 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven.errortest</groupId>
+ <artifactId>test-maven-ext</artifactId>
+ <version>1</version>
+
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>[3.8,</version>
+ </dependency>
+ </dependencies>
+
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/bad-ext-direct-deps/project/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/bad-ext-direct-deps/project/pom.xml
new file mode 100644
index 00000000..6d06469f
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/bad-ext-direct-deps/project/pom.xml
@@ -0,0 +1,35 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven.errortest</groupId>
+ <artifactId>bad-ext-direct-deps</artifactId>
+ <version>1</version>
+
+ <build>
+ <extensions>
+ <extension>
+ <groupId>org.apache.maven.errortest</groupId>
+ <artifactId>test-maven-ext</artifactId>
+ <version>1</version>
+ </extension>
+ </extensions>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/bad-ext-plugin-dep-ver/local-repo/org/apache/maven/errortest/bad-ext-plugin-dep-ver-maven-plugin/1/bad-ext-plugin-dep-ver-maven-plugin-1.jar b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/bad-ext-plugin-dep-ver/local-repo/org/apache/maven/errortest/bad-ext-plugin-dep-ver-maven-plugin/1/bad-ext-plugin-dep-ver-maven-plugin-1.jar
new file mode 100644
index 00000000..7d849019
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/bad-ext-plugin-dep-ver/local-repo/org/apache/maven/errortest/bad-ext-plugin-dep-ver-maven-plugin/1/bad-ext-plugin-dep-ver-maven-plugin-1.jar
Binary files differ
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/bad-ext-plugin-dep-ver/local-repo/org/apache/maven/errortest/bad-ext-plugin-dep-ver-maven-plugin/1/bad-ext-plugin-dep-ver-maven-plugin-1.pom b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/bad-ext-plugin-dep-ver/local-repo/org/apache/maven/errortest/bad-ext-plugin-dep-ver-maven-plugin/1/bad-ext-plugin-dep-ver-maven-plugin-1.pom
new file mode 100644
index 00000000..3c7f3f3f
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/bad-ext-plugin-dep-ver/local-repo/org/apache/maven/errortest/bad-ext-plugin-dep-ver-maven-plugin/1/bad-ext-plugin-dep-ver-maven-plugin-1.pom
@@ -0,0 +1,55 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven.errortest</groupId>
+ <artifactId>bad-ext-plugin-dep-ver-maven-plugin</artifactId>
+ <packaging>maven-plugin</packaging>
+ <version>1</version>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-plugin-api</artifactId>
+ <version>2.0</version>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>[3.8.1,</version>
+ </dependency>
+ </dependencies>
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>2.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-deploy-plugin</artifactId>
+ <version>2.3</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-install-plugin</artifactId>
+ <version>2.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-resources-plugin</artifactId>
+ <version>2.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-jar-plugin</artifactId>
+ <version>2.1</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>2.0.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-plugin-plugin</artifactId>
+ <version>2.3</version>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/bad-ext-plugin-dep-ver/plugin/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/bad-ext-plugin-dep-ver/plugin/pom.xml
new file mode 100644
index 00000000..2c3da51d
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/bad-ext-plugin-dep-ver/plugin/pom.xml
@@ -0,0 +1,57 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven.errortest</groupId>
+ <artifactId>bad-ext-plugin-maven-ver-maven-plugin</artifactId>
+ <packaging>maven-plugin</packaging>
+ <version>1</version>
+
+ <!--
+ <prerequisites>
+ <maven>10</maven>
+ </prerequisites>
+
+ -->
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-plugin-api</artifactId>
+ <version>2.0</version>
+ </dependency>
+ </dependencies>
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>2.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-deploy-plugin</artifactId>
+ <version>2.3</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-install-plugin</artifactId>
+ <version>2.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-resources-plugin</artifactId>
+ <version>2.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-jar-plugin</artifactId>
+ <version>2.1</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>2.0.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-plugin-plugin</artifactId>
+ <version>2.3</version>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/bad-ext-plugin-dep-ver/plugin/src/main/java/org/plugin/TestPlugin.java b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/bad-ext-plugin-dep-ver/plugin/src/main/java/org/plugin/TestPlugin.java
new file mode 100644
index 00000000..5836f1e0
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/bad-ext-plugin-dep-ver/plugin/src/main/java/org/plugin/TestPlugin.java
@@ -0,0 +1,33 @@
+package org.plugin;
+
+import org.apache.maven.plugin.Mojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugin.logging.Log;
+
+/**
+ * @goal test
+ */
+public class TestPlugin
+ implements Mojo
+{
+
+ private Log log;
+
+ public void execute()
+ throws MojoExecutionException, MojoFailureException
+ {
+ throw new MojoExecutionException( "This is meant to fail." );
+ }
+
+ public Log getLog()
+ {
+ return log;
+ }
+
+ public void setLog( Log log )
+ {
+ this.log = log;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/bad-ext-plugin-dep-ver/project/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/bad-ext-plugin-dep-ver/project/pom.xml
new file mode 100644
index 00000000..9001cdca
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/bad-ext-plugin-dep-ver/project/pom.xml
@@ -0,0 +1,37 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>bad-ext-plugin-dep-ver</artifactId>
+ <version>1</version>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.errortest</groupId>
+ <artifactId>bad-ext-plugin-dep-ver-maven-plugin</artifactId>
+ <version>1</version>
+ <extensions>true</extensions>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/bad-ext-plugin-maven-ver/local-repo/org/apache/maven/errortest/bad-ext-plugin-maven-ver-maven-plugin/1/bad-ext-plugin-maven-ver-maven-plugin-1.jar b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/bad-ext-plugin-maven-ver/local-repo/org/apache/maven/errortest/bad-ext-plugin-maven-ver-maven-plugin/1/bad-ext-plugin-maven-ver-maven-plugin-1.jar
new file mode 100644
index 00000000..7d849019
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/bad-ext-plugin-maven-ver/local-repo/org/apache/maven/errortest/bad-ext-plugin-maven-ver-maven-plugin/1/bad-ext-plugin-maven-ver-maven-plugin-1.jar
Binary files differ
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/bad-ext-plugin-maven-ver/local-repo/org/apache/maven/errortest/bad-ext-plugin-maven-ver-maven-plugin/1/bad-ext-plugin-maven-ver-maven-plugin-1.pom b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/bad-ext-plugin-maven-ver/local-repo/org/apache/maven/errortest/bad-ext-plugin-maven-ver-maven-plugin/1/bad-ext-plugin-maven-ver-maven-plugin-1.pom
new file mode 100644
index 00000000..ffe6141e
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/bad-ext-plugin-maven-ver/local-repo/org/apache/maven/errortest/bad-ext-plugin-maven-ver-maven-plugin/1/bad-ext-plugin-maven-ver-maven-plugin-1.pom
@@ -0,0 +1,54 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven.errortest</groupId>
+ <artifactId>bad-ext-plugin-maven-ver-maven-plugin</artifactId>
+ <packaging>maven-plugin</packaging>
+ <version>1</version>
+
+ <prerequisites>
+ <maven>10</maven>
+ </prerequisites>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-plugin-api</artifactId>
+ <version>2.0</version>
+ </dependency>
+ </dependencies>
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>2.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-deploy-plugin</artifactId>
+ <version>2.3</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-install-plugin</artifactId>
+ <version>2.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-resources-plugin</artifactId>
+ <version>2.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-jar-plugin</artifactId>
+ <version>2.1</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>2.0.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-plugin-plugin</artifactId>
+ <version>2.3</version>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/bad-ext-plugin-maven-ver/local-repo/org/apache/maven/errortest/bad-ext-plugin-maven-ver-maven-plugin/maven-metadata-local.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/bad-ext-plugin-maven-ver/local-repo/org/apache/maven/errortest/bad-ext-plugin-maven-ver-maven-plugin/maven-metadata-local.xml
new file mode 100644
index 00000000..184a5f7d
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/bad-ext-plugin-maven-ver/local-repo/org/apache/maven/errortest/bad-ext-plugin-maven-ver-maven-plugin/maven-metadata-local.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0"?><metadata>
+ <groupId>org.apache.maven.errortest</groupId>
+ <artifactId>bad-ext-plugin-maven-ver-maven-plugin</artifactId>
+ <versioning>
+ <latest>1</latest>
+ <release>1</release>
+ <versions>
+ <version>1</version>
+ </versions>
+ <lastUpdated>20070331131500</lastUpdated>
+ </versioning>
+</metadata>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/bad-ext-plugin-maven-ver/plugin/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/bad-ext-plugin-maven-ver/plugin/pom.xml
new file mode 100644
index 00000000..2c3da51d
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/bad-ext-plugin-maven-ver/plugin/pom.xml
@@ -0,0 +1,57 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven.errortest</groupId>
+ <artifactId>bad-ext-plugin-maven-ver-maven-plugin</artifactId>
+ <packaging>maven-plugin</packaging>
+ <version>1</version>
+
+ <!--
+ <prerequisites>
+ <maven>10</maven>
+ </prerequisites>
+
+ -->
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-plugin-api</artifactId>
+ <version>2.0</version>
+ </dependency>
+ </dependencies>
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>2.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-deploy-plugin</artifactId>
+ <version>2.3</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-install-plugin</artifactId>
+ <version>2.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-resources-plugin</artifactId>
+ <version>2.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-jar-plugin</artifactId>
+ <version>2.1</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>2.0.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-plugin-plugin</artifactId>
+ <version>2.3</version>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/bad-ext-plugin-maven-ver/plugin/src/main/java/org/plugin/TestPlugin.java b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/bad-ext-plugin-maven-ver/plugin/src/main/java/org/plugin/TestPlugin.java
new file mode 100644
index 00000000..5836f1e0
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/bad-ext-plugin-maven-ver/plugin/src/main/java/org/plugin/TestPlugin.java
@@ -0,0 +1,33 @@
+package org.plugin;
+
+import org.apache.maven.plugin.Mojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugin.logging.Log;
+
+/**
+ * @goal test
+ */
+public class TestPlugin
+ implements Mojo
+{
+
+ private Log log;
+
+ public void execute()
+ throws MojoExecutionException, MojoFailureException
+ {
+ throw new MojoExecutionException( "This is meant to fail." );
+ }
+
+ public Log getLog()
+ {
+ return log;
+ }
+
+ public void setLog( Log log )
+ {
+ this.log = log;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/bad-ext-plugin-maven-ver/project/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/bad-ext-plugin-maven-ver/project/pom.xml
new file mode 100644
index 00000000..3ab28183
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/bad-ext-plugin-maven-ver/project/pom.xml
@@ -0,0 +1,37 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>bad-ext-plugin-maven-ver</artifactId>
+ <version>1</version>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.errortest</groupId>
+ <artifactId>bad-ext-plugin-maven-ver-maven-plugin</artifactId>
+ <version>1</version>
+ <extensions>true</extensions>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/bad-maven-version/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/bad-maven-version/pom.xml
new file mode 100644
index 00000000..db547ca5
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/bad-maven-version/pom.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?><project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven.errortest</groupId>
+ <artifactId>bad-maven-version</artifactId>
+ <version>1</version>
+
+ <prerequisites>
+ <maven>10</maven>
+ </prerequisites>
+
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/bad-mg-dep-version/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/bad-mg-dep-version/pom.xml
new file mode 100644
index 00000000..4bb4c461
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/bad-mg-dep-version/pom.xml
@@ -0,0 +1,35 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>bad-mg-dep-version</artifactId>
+ <version>1</version>
+
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>[3.1,</version>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/bad-non-dep-version/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/bad-non-dep-version/pom.xml
new file mode 100644
index 00000000..dd2cff37
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/bad-non-dep-version/pom.xml
@@ -0,0 +1,35 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>bad-non-dep-version</artifactId>
+ <version>1</version>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>[3.1,</version>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/bad-profile-repo/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/bad-profile-repo/pom.xml
new file mode 100644
index 00000000..d7a73754
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/bad-profile-repo/pom.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?><project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven.errortest</groupId>
+ <artifactId>bad-profile-repo</artifactId>
+ <version>1</version>
+
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/bad-profile-repo/profiles.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/bad-profile-repo/profiles.xml
new file mode 100644
index 00000000..43e20d8b
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/bad-profile-repo/profiles.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+<profilesXml>
+ <profiles>
+ <profile>
+ <id>test</id>
+ <repositories>
+ <repository>
+ <id>test-repo</id>
+ <url>http://www.google.com/</url>
+ <layout>nothing-special</layout>
+ </repository>
+ </repositories>
+ </profile>
+ </profiles>
+ <activeProfiles>
+ <activeProfile>test</activeProfile>
+ </activeProfiles>
+</profilesXml> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/config-rdonly-mojo-param/plugin/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/config-rdonly-mojo-param/plugin/pom.xml
new file mode 100644
index 00000000..73a96583
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/config-rdonly-mojo-param/plugin/pom.xml
@@ -0,0 +1,49 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven.errortest</groupId>
+ <artifactId>config-rdonly-mojo-param-maven-plugin</artifactId>
+ <packaging>maven-plugin</packaging>
+ <version>1</version>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-plugin-api</artifactId>
+ <version>2.0</version>
+ </dependency>
+ </dependencies>
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>2.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-deploy-plugin</artifactId>
+ <version>2.3</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-install-plugin</artifactId>
+ <version>2.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-resources-plugin</artifactId>
+ <version>2.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-jar-plugin</artifactId>
+ <version>2.1</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>2.0.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-plugin-plugin</artifactId>
+ <version>2.3</version>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/config-rdonly-mojo-param/plugin/src/main/java/org/plugin/TestPlugin.java b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/config-rdonly-mojo-param/plugin/src/main/java/org/plugin/TestPlugin.java
new file mode 100644
index 00000000..6aa5c335
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/config-rdonly-mojo-param/plugin/src/main/java/org/plugin/TestPlugin.java
@@ -0,0 +1,39 @@
+package org.plugin;
+
+import org.apache.maven.plugin.Mojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugin.logging.Log;
+
+/**
+ * @goal test
+ */
+public class TestPlugin
+ implements Mojo
+{
+
+ private Log log;
+
+ /**
+ * @parameter default-value="something"
+ * @required
+ * @readonly
+ */
+ private String param;
+
+ public void execute()
+ throws MojoExecutionException, MojoFailureException
+ {
+ }
+
+ public Log getLog()
+ {
+ return log;
+ }
+
+ public void setLog( Log log )
+ {
+ this.log = log;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/config-rdonly-mojo-param/project/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/config-rdonly-mojo-param/project/pom.xml
new file mode 100644
index 00000000..e2c74121
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/config-rdonly-mojo-param/project/pom.xml
@@ -0,0 +1,47 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>config-rdonly-mojo-param</artifactId>
+ <version>1</version>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.errortest</groupId>
+ <artifactId>config-rdonly-mojo-param-maven-plugin</artifactId>
+ <version>1</version>
+ <executions>
+ <execution>
+ <id>test-run</id>
+ <phase>initialize</phase>
+ <goals>
+ <goal>test</goal>
+ </goals>
+ <configuration>
+ <param>something-else</param>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/deploy-repo-creation-err/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/deploy-repo-creation-err/pom.xml
new file mode 100644
index 00000000..d766e418
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/deploy-repo-creation-err/pom.xml
@@ -0,0 +1,41 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>deploy-repo-creation-err</artifactId>
+ <version>1</version>
+
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>3.8.1</version>
+ </dependency>
+ </dependencies>
+
+ <distributionManagement>
+ <repository>
+ <id>test</id>
+ <url>http://www.google.com</url>
+ <layout>nothing</layout>
+ </repository>
+ </distributionManagement>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/duplicated-attachments/plugin/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/duplicated-attachments/plugin/pom.xml
new file mode 100644
index 00000000..21222df6
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/duplicated-attachments/plugin/pom.xml
@@ -0,0 +1,54 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven.errortest</groupId>
+ <artifactId>duplicated-attachments-maven-plugin</artifactId>
+ <packaging>maven-plugin</packaging>
+ <version>1</version>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-plugin-api</artifactId>
+ <version>2.0</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-project</artifactId>
+ <version>2.0.7</version>
+ </dependency>
+ </dependencies>
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>2.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-deploy-plugin</artifactId>
+ <version>2.3</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-install-plugin</artifactId>
+ <version>2.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-resources-plugin</artifactId>
+ <version>2.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-jar-plugin</artifactId>
+ <version>2.1</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>2.0.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-plugin-plugin</artifactId>
+ <version>2.3</version>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/duplicated-attachments/plugin/src/main/java/org/plugin/TestPlugin.java b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/duplicated-attachments/plugin/src/main/java/org/plugin/TestPlugin.java
new file mode 100644
index 00000000..6b0f61ad
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/duplicated-attachments/plugin/src/main/java/org/plugin/TestPlugin.java
@@ -0,0 +1,50 @@
+package org.plugin;
+
+import org.apache.maven.plugin.Mojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugin.logging.Log;
+import org.apache.maven.project.MavenProjectHelper;
+import org.apache.maven.project.MavenProject;
+
+/**
+ * @goal test
+ *
+ * @author jdcasey
+ */
+public class TestPlugin
+ implements Mojo
+{
+
+ private Log log;
+
+ /**
+ * @component
+ */
+ private MavenProjectHelper mavenProjectHelper;
+
+ /**
+ * @parameter default-value="${project}"
+ * @required
+ * @readonly
+ */
+ private MavenProject project;
+
+ public void execute()
+ throws MojoExecutionException, MojoFailureException
+ {
+ mavenProjectHelper.attachArtifact( project, "pom", "classifier", project.getFile() );
+ mavenProjectHelper.attachArtifact( project, "pom", "classifier", project.getFile() );
+ }
+
+ public Log getLog()
+ {
+ return log;
+ }
+
+ public void setLog( Log log )
+ {
+ this.log = log;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/duplicated-attachments/project/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/duplicated-attachments/project/pom.xml
new file mode 100644
index 00000000..a9517c94
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/duplicated-attachments/project/pom.xml
@@ -0,0 +1,25 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>duplicated-attachments</artifactId>
+ <version>1</version>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/err-loading-plugin/local-repo/org/apache/maven/errortest/err-loading-plugin-maven-plugin/1/err-loading-plugin-maven-plugin-1.jar b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/err-loading-plugin/local-repo/org/apache/maven/errortest/err-loading-plugin-maven-plugin/1/err-loading-plugin-maven-plugin-1.jar
new file mode 100644
index 00000000..7d849019
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/err-loading-plugin/local-repo/org/apache/maven/errortest/err-loading-plugin-maven-plugin/1/err-loading-plugin-maven-plugin-1.jar
Binary files differ
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/err-loading-plugin/local-repo/org/apache/maven/errortest/err-loading-plugin-maven-plugin/1/err-loading-plugin-maven-plugin-1.pom b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/err-loading-plugin/local-repo/org/apache/maven/errortest/err-loading-plugin-maven-plugin/1/err-loading-plugin-maven-plugin-1.pom
new file mode 100644
index 00000000..7ac04909
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/err-loading-plugin/local-repo/org/apache/maven/errortest/err-loading-plugin-maven-plugin/1/err-loading-plugin-maven-plugin-1.pom
@@ -0,0 +1,55 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven.errortest</groupId>
+ <artifactId>err-loading-plugin-maven-plugin</artifactId>
+ <packaging>maven-plugin</packaging>
+ <version>1</version>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-plugin-api</artifactId>
+ <version>2.0</version>
+ </dependency>
+ <dependency>
+ <groupId>nothing</groupId>
+ <artifactId>nothing</artifactId>
+ <version>1</version>
+ </dependency>
+ </dependencies>
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>2.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-deploy-plugin</artifactId>
+ <version>2.3</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-install-plugin</artifactId>
+ <version>2.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-resources-plugin</artifactId>
+ <version>2.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-jar-plugin</artifactId>
+ <version>2.1</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>2.0.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-plugin-plugin</artifactId>
+ <version>2.3</version>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/err-loading-plugin/project/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/err-loading-plugin/project/pom.xml
new file mode 100644
index 00000000..c210cfba
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/err-loading-plugin/project/pom.xml
@@ -0,0 +1,45 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>err-loading-plugin</artifactId>
+ <version>1</version>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.errortest</groupId>
+ <artifactId>err-loading-plugin-maven-plugin</artifactId>
+ <version>1</version>
+ <executions>
+ <execution>
+ <id>test-run</id>
+ <phase>initialize</phase>
+ <goals>
+ <goal>test</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/err-resolving-ext-plugin/local-repo/org/apache/maven/errortest/dep/1/dep-1.pom b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/err-resolving-ext-plugin/local-repo/org/apache/maven/errortest/dep/1/dep-1.pom
new file mode 100644
index 00000000..e6dd7a2b
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/err-resolving-ext-plugin/local-repo/org/apache/maven/errortest/dep/1/dep-1.pom
@@ -0,0 +1,16 @@
+<?xml version="1.0"?>
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven.errortest</groupId>
+ <artifactId>dep</artifactId>
+ <version>1</version>
+ <packaging>pom</packaging>
+
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>[4.0,4.1]</version>
+ </dependency>
+ </dependencies>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/err-resolving-ext-plugin/local-repo/org/apache/maven/errortest/err-resolving-ext-plugin-maven-plugin/1/err-resolving-ext-plugin-maven-plugin-1.jar b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/err-resolving-ext-plugin/local-repo/org/apache/maven/errortest/err-resolving-ext-plugin-maven-plugin/1/err-resolving-ext-plugin-maven-plugin-1.jar
new file mode 100644
index 00000000..7d849019
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/err-resolving-ext-plugin/local-repo/org/apache/maven/errortest/err-resolving-ext-plugin-maven-plugin/1/err-resolving-ext-plugin-maven-plugin-1.jar
Binary files differ
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/err-resolving-ext-plugin/local-repo/org/apache/maven/errortest/err-resolving-ext-plugin-maven-plugin/1/err-resolving-ext-plugin-maven-plugin-1.pom b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/err-resolving-ext-plugin/local-repo/org/apache/maven/errortest/err-resolving-ext-plugin-maven-plugin/1/err-resolving-ext-plugin-maven-plugin-1.pom
new file mode 100644
index 00000000..e520ccc9
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/err-resolving-ext-plugin/local-repo/org/apache/maven/errortest/err-resolving-ext-plugin-maven-plugin/1/err-resolving-ext-plugin-maven-plugin-1.pom
@@ -0,0 +1,60 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven.errortest</groupId>
+ <artifactId>err-resolving-ext-plugin-maven-plugin</artifactId>
+ <packaging>maven-plugin</packaging>
+ <version>1</version>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-plugin-api</artifactId>
+ <version>2.0</version>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>[3.8.1,3.8.2]</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.errortest</groupId>
+ <artifactId>dep</artifactId>
+ <version>1</version>
+ </dependency>
+ </dependencies>
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>2.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-deploy-plugin</artifactId>
+ <version>2.3</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-install-plugin</artifactId>
+ <version>2.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-resources-plugin</artifactId>
+ <version>2.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-jar-plugin</artifactId>
+ <version>2.1</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>2.0.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-plugin-plugin</artifactId>
+ <version>2.3</version>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/err-resolving-ext-plugin/project/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/err-resolving-ext-plugin/project/pom.xml
new file mode 100644
index 00000000..1339c66c
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/err-resolving-ext-plugin/project/pom.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?><project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven.errortest</groupId>
+ <artifactId>err-resolving-ext-plugin</artifactId>
+ <version>1</version>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.errortest</groupId>
+ <artifactId>err-resolving-ext-plugin-maven-plugin</artifactId>
+ <version>1</version>
+ <extensions>true</extensions>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/err-resolving-project-dep/project/local-repo/org/apache/maven/errortest/dep/1/dep-1.pom b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/err-resolving-project-dep/project/local-repo/org/apache/maven/errortest/dep/1/dep-1.pom
new file mode 100644
index 00000000..e6dd7a2b
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/err-resolving-project-dep/project/local-repo/org/apache/maven/errortest/dep/1/dep-1.pom
@@ -0,0 +1,16 @@
+<?xml version="1.0"?>
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven.errortest</groupId>
+ <artifactId>dep</artifactId>
+ <version>1</version>
+ <packaging>pom</packaging>
+
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>[4.0,4.1]</version>
+ </dependency>
+ </dependencies>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/err-resolving-project-dep/project/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/err-resolving-project-dep/project/pom.xml
new file mode 100644
index 00000000..d0b755c6
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/err-resolving-project-dep/project/pom.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?><project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven.errortest</groupId>
+ <artifactId>err-resolving-project-dep</artifactId>
+ <version>1</version>
+
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>[3.8.1,3.8.2]</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.errortest</groupId>
+ <artifactId>dep</artifactId>
+ <version>1</version>
+ <type>pom</type>
+ </dependency>
+ </dependencies>
+
+ <repositories>
+ <repository>
+ <id>repo</id>
+ <url>file://localhost/${basedir}/local-repo</url>
+ </repository>
+ </repositories>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/err-resolving-project-dep/project/src/main/java/org/apache/maven/test/error/mojoFailure/App.java b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/err-resolving-project-dep/project/src/main/java/org/apache/maven/test/error/mojoFailure/App.java
new file mode 100644
index 00000000..dd4102a3
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/err-resolving-project-dep/project/src/main/java/org/apache/maven/test/error/mojoFailure/App.java
@@ -0,0 +1,13 @@
+package org.apache.maven.test.error.mojoFailure;
+
+/**
+ * Hello world!
+ *
+ */
+public class App
+{
+ public static void main( String[] args )
+ {
+ System.out.println( "Hello World!" );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/err-resolving-project-dep/project/src/test/java/org/apache/maven/test/error/mojoFailure/AppTest.java b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/err-resolving-project-dep/project/src/test/java/org/apache/maven/test/error/mojoFailure/AppTest.java
new file mode 100644
index 00000000..7e0144ac
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/err-resolving-project-dep/project/src/test/java/org/apache/maven/test/error/mojoFailure/AppTest.java
@@ -0,0 +1,38 @@
+package org.apache.maven.test.error.mojoFailure;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+/**
+ * Unit test for simple App.
+ */
+public class AppTest
+ extends TestCase
+{
+ /**
+ * Create the test case
+ *
+ * @param testName name of the test case
+ */
+ public AppTest( String testName )
+ {
+ super( testName );
+ }
+
+ /**
+ * @return the suite of tests being tested
+ */
+ public static Test suite()
+ {
+ return new TestSuite( AppTest.class );
+ }
+
+ /**
+ * Rigourous Test :-)
+ */
+ public void testApp()
+ {
+ assertTrue( true );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/ext-deps-resolve-err/local-repo/org/apache/maven/errortest/test-maven-ext-dep/1/test-maven-ext-dep-1.pom b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/ext-deps-resolve-err/local-repo/org/apache/maven/errortest/test-maven-ext-dep/1/test-maven-ext-dep-1.pom
new file mode 100644
index 00000000..71edcf4d
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/ext-deps-resolve-err/local-repo/org/apache/maven/errortest/test-maven-ext-dep/1/test-maven-ext-dep-1.pom
@@ -0,0 +1,26 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven.errortest</groupId>
+ <artifactId>test-maven-ext-dep</artifactId>
+ <version>1</ver>
+
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/ext-deps-resolve-err/local-repo/org/apache/maven/errortest/test-maven-ext/1/test-maven-ext-1.pom b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/ext-deps-resolve-err/local-repo/org/apache/maven/errortest/test-maven-ext/1/test-maven-ext-1.pom
new file mode 100644
index 00000000..cd40200d
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/ext-deps-resolve-err/local-repo/org/apache/maven/errortest/test-maven-ext/1/test-maven-ext-1.pom
@@ -0,0 +1,34 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven.errortest</groupId>
+ <artifactId>test-maven-ext</artifactId>
+ <version>1</version>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven.errortest</groupId>
+ <artifactId>test-maven-ext-dep</artifactId>
+ <version>1</version>
+ </dependency>
+ </dependencies>
+
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/ext-deps-resolve-err/project/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/ext-deps-resolve-err/project/pom.xml
new file mode 100644
index 00000000..8da15606
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/ext-deps-resolve-err/project/pom.xml
@@ -0,0 +1,35 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven.errortest</groupId>
+ <artifactId>ext-deps-resolve-err</artifactId>
+ <version>1</version>
+
+ <build>
+ <extensions>
+ <extension>
+ <groupId>org.apache.maven.errortest</groupId>
+ <artifactId>test-maven-ext</artifactId>
+ <version>1</version>
+ </extension>
+ </extensions>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/ext-plugin-artifact-missing/local-repo/org/apache/maven/errortest/ext-plugin-artifact-missing-maven-plugin/1/ext-plugin-artifact-missing-maven-plugin-1.pom b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/ext-plugin-artifact-missing/local-repo/org/apache/maven/errortest/ext-plugin-artifact-missing-maven-plugin/1/ext-plugin-artifact-missing-maven-plugin-1.pom
new file mode 100644
index 00000000..b7f7d529
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/ext-plugin-artifact-missing/local-repo/org/apache/maven/errortest/ext-plugin-artifact-missing-maven-plugin/1/ext-plugin-artifact-missing-maven-plugin-1.pom
@@ -0,0 +1,55 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven.errortest</groupId>
+ <artifactId>ext-plugin-artifact-missing-maven-plugin</artifactId>
+ <packaging>maven-plugin</packaging>
+ <version>1</version>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-plugin-api</artifactId>
+ <version>2.0</version>
+ </dependency>
+ <dependency>
+ <groupId>nothing</groupId>
+ <artifactId>nothing</artifactId>
+ <version>1</version>
+ </dependency>
+ </dependencies>
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>2.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-deploy-plugin</artifactId>
+ <version>2.3</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-install-plugin</artifactId>
+ <version>2.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-resources-plugin</artifactId>
+ <version>2.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-jar-plugin</artifactId>
+ <version>2.1</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>2.0.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-plugin-plugin</artifactId>
+ <version>2.3</version>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/ext-plugin-artifact-missing/project/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/ext-plugin-artifact-missing/project/pom.xml
new file mode 100644
index 00000000..6565fd44
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/ext-plugin-artifact-missing/project/pom.xml
@@ -0,0 +1,37 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>ext-plugin-artifact-missing</artifactId>
+ <version>1</version>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.errortest</groupId>
+ <artifactId>ext-plugin-artifact-missing-maven-plugin</artifactId>
+ <version>1</version>
+ <extensions>true</extensions>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/ext-plugin-realm-error/plugin/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/ext-plugin-realm-error/plugin/pom.xml
new file mode 100644
index 00000000..e8e5218c
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/ext-plugin-realm-error/plugin/pom.xml
@@ -0,0 +1,49 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven.errortest</groupId>
+ <artifactId>test-maven-ext-plugin</artifactId>
+ <packaging>maven-plugin</packaging>
+ <version>1</version>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-plugin-api</artifactId>
+ <version>2.0</version>
+ </dependency>
+ </dependencies>
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>2.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-deploy-plugin</artifactId>
+ <version>2.3</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-install-plugin</artifactId>
+ <version>2.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-resources-plugin</artifactId>
+ <version>2.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-jar-plugin</artifactId>
+ <version>2.1</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>2.0.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-plugin-plugin</artifactId>
+ <version>2.3</version>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/ext-plugin-realm-error/plugin/src/main/java/org/plugin/ComponentOne.java b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/ext-plugin-realm-error/plugin/src/main/java/org/plugin/ComponentOne.java
new file mode 100644
index 00000000..49b7686e
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/ext-plugin-realm-error/plugin/src/main/java/org/plugin/ComponentOne.java
@@ -0,0 +1,8 @@
+package org.plugin;
+
+public class ComponentOne
+{
+
+ private ComponentTwo two;
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/ext-plugin-realm-error/plugin/src/main/java/org/plugin/ComponentTwo.java b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/ext-plugin-realm-error/plugin/src/main/java/org/plugin/ComponentTwo.java
new file mode 100644
index 00000000..0a82f578
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/ext-plugin-realm-error/plugin/src/main/java/org/plugin/ComponentTwo.java
@@ -0,0 +1,8 @@
+package org.plugin;
+
+public class ComponentTwo
+{
+
+ private ComponentOne one;
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/ext-plugin-realm-error/plugin/src/main/java/org/plugin/TestPlugin.java b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/ext-plugin-realm-error/plugin/src/main/java/org/plugin/TestPlugin.java
new file mode 100644
index 00000000..4b4a1e4d
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/ext-plugin-realm-error/plugin/src/main/java/org/plugin/TestPlugin.java
@@ -0,0 +1,39 @@
+package org.plugin;
+
+import org.apache.maven.plugin.Mojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugin.logging.Log;
+
+/**
+ * @goal test
+ *
+ * @author jdcasey
+ */
+public class TestPlugin
+ implements Mojo
+{
+
+ private Log log;
+
+ /**
+ * @component
+ */
+ private ComponentOne one;
+
+ public void execute()
+ throws MojoExecutionException, MojoFailureException
+ {
+ }
+
+ public Log getLog()
+ {
+ return log;
+ }
+
+ public void setLog( Log log )
+ {
+ this.log = log;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/ext-plugin-realm-error/plugin/src/main/resources/META-INF/plexus/components.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/ext-plugin-realm-error/plugin/src/main/resources/META-INF/plexus/components.xml
new file mode 100644
index 00000000..ddc1eee5
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/ext-plugin-realm-error/plugin/src/main/resources/META-INF/plexus/components.xml
@@ -0,0 +1,25 @@
+<component-set>
+ <components>
+ <component>
+ <role>org.test.ComponentOne</role>
+ <role-hint>default</role-hint>
+ <implementation>org.test.ComponentOne</implementation>
+ <requirements>
+ <requirement>
+ <role>org.test.ComponentTwo</role>
+ </requirement>
+ </requirements>
+ </component>
+
+ <component>
+ <role>org.test.ComponentTwo</role>
+ <role-hint>default</role-hint>
+ <implementation>org.test.ComponentTwo</implementation>
+ <requirements>
+ <requirement>
+ <role>org.test.ComponentOne</role>
+ </requirement>
+ </requirements>
+ </component>
+ </components>
+</component-set> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/ext-plugin-realm-error/project/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/ext-plugin-realm-error/project/pom.xml
new file mode 100644
index 00000000..513e00c8
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/ext-plugin-realm-error/project/pom.xml
@@ -0,0 +1,36 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven.errortest</groupId>
+ <artifactId>ext-plugin-realm-error</artifactId>
+ <version>1</version>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.errortest</groupId>
+ <artifactId>test-maven-ext-plugin</artifactId>
+ <version>1</version>
+ <extensions>true</extensions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/ext-plugin-version-err/local-repo/org/apache/maven/errortest/ext-plugin-version-err-maven-plugin/1/ext-plugin-version-err-maven-plugin-1.jar b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/ext-plugin-version-err/local-repo/org/apache/maven/errortest/ext-plugin-version-err-maven-plugin/1/ext-plugin-version-err-maven-plugin-1.jar
new file mode 100644
index 00000000..7d849019
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/ext-plugin-version-err/local-repo/org/apache/maven/errortest/ext-plugin-version-err-maven-plugin/1/ext-plugin-version-err-maven-plugin-1.jar
Binary files differ
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/ext-plugin-version-err/local-repo/org/apache/maven/errortest/ext-plugin-version-err-maven-plugin/1/ext-plugin-version-err-maven-plugin-1.pom b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/ext-plugin-version-err/local-repo/org/apache/maven/errortest/ext-plugin-version-err-maven-plugin/1/ext-plugin-version-err-maven-plugin-1.pom
new file mode 100644
index 00000000..5aab61d9
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/ext-plugin-version-err/local-repo/org/apache/maven/errortest/ext-plugin-version-err-maven-plugin/1/ext-plugin-version-err-maven-plugin-1.pom
@@ -0,0 +1,50 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven.errortest</groupId>
+ <artifactId>ext-plugin-version-err-maven-plugin</artifactId>
+ <packaging>maven-plugin</packaging>
+ <version>1</version>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-plugin-api</artifactId>
+ <version>2.0</version>
+ </dependency>
+ </dependencies>
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>2.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-deploy-plugin</artifactId>
+ <version>2.3</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-install-plugin</artifactId>
+ <version>2.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-resources-plugin</artifactId>
+ <version>2.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-jar-plugin</artifactId>
+ <version>2.1</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>2.0.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-plugin-plugin</artifactId>
+ <version>2.3</version>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/ext-plugin-version-err/local-repo/org/apache/maven/errortest/ext-plugin-version-err-maven-plugin/maven-metadata-local.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/ext-plugin-version-err/local-repo/org/apache/maven/errortest/ext-plugin-version-err-maven-plugin/maven-metadata-local.xml
new file mode 100644
index 00000000..2a3d1c56
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/ext-plugin-version-err/local-repo/org/apache/maven/errortest/ext-plugin-version-err-maven-plugin/maven-metadata-local.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0"?><metadata>
+ <groupId>org.apache.maven.errortest</groupId>
+ <artifactId>ext-plugin-version-err-maven-plugin</artifactId>
+ <versioning>
+ <versions>
+ <version>1</version>
+ </versions>
+ <lastUpdated>20070331131500</lastUpdated>
+ </versioning>
+</metadata>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/ext-plugin-version-err/plugin/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/ext-plugin-version-err/plugin/pom.xml
new file mode 100644
index 00000000..2c3da51d
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/ext-plugin-version-err/plugin/pom.xml
@@ -0,0 +1,57 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven.errortest</groupId>
+ <artifactId>bad-ext-plugin-maven-ver-maven-plugin</artifactId>
+ <packaging>maven-plugin</packaging>
+ <version>1</version>
+
+ <!--
+ <prerequisites>
+ <maven>10</maven>
+ </prerequisites>
+
+ -->
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-plugin-api</artifactId>
+ <version>2.0</version>
+ </dependency>
+ </dependencies>
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>2.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-deploy-plugin</artifactId>
+ <version>2.3</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-install-plugin</artifactId>
+ <version>2.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-resources-plugin</artifactId>
+ <version>2.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-jar-plugin</artifactId>
+ <version>2.1</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>2.0.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-plugin-plugin</artifactId>
+ <version>2.3</version>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/ext-plugin-version-err/plugin/src/main/java/org/plugin/TestPlugin.java b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/ext-plugin-version-err/plugin/src/main/java/org/plugin/TestPlugin.java
new file mode 100644
index 00000000..5836f1e0
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/ext-plugin-version-err/plugin/src/main/java/org/plugin/TestPlugin.java
@@ -0,0 +1,33 @@
+package org.plugin;
+
+import org.apache.maven.plugin.Mojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugin.logging.Log;
+
+/**
+ * @goal test
+ */
+public class TestPlugin
+ implements Mojo
+{
+
+ private Log log;
+
+ public void execute()
+ throws MojoExecutionException, MojoFailureException
+ {
+ throw new MojoExecutionException( "This is meant to fail." );
+ }
+
+ public Log getLog()
+ {
+ return log;
+ }
+
+ public void setLog( Log log )
+ {
+ this.log = log;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/ext-plugin-version-err/project/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/ext-plugin-version-err/project/pom.xml
new file mode 100644
index 00000000..ad6effce
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/ext-plugin-version-err/project/pom.xml
@@ -0,0 +1,36 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>ext-plugin-version-err</artifactId>
+ <version>1</version>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.errortest</groupId>
+ <artifactId>ext-plugin-version-err-maven-plugin</artifactId>
+ <extensions>true</extensions>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/ext-realm-error/ext/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/ext-realm-error/ext/pom.xml
new file mode 100644
index 00000000..a5677067
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/ext-realm-error/ext/pom.xml
@@ -0,0 +1,38 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven.errortest</groupId>
+ <artifactId>test-maven-ext</artifactId>
+ <version>1</version>
+
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>2.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-deploy-plugin</artifactId>
+ <version>2.3</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-install-plugin</artifactId>
+ <version>2.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-resources-plugin</artifactId>
+ <version>2.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-jar-plugin</artifactId>
+ <version>2.1</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>2.0.2</version>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/ext-realm-error/ext/src/main/java/org/ext/App.java b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/ext-realm-error/ext/src/main/java/org/ext/App.java
new file mode 100644
index 00000000..0701b7ae
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/ext-realm-error/ext/src/main/java/org/ext/App.java
@@ -0,0 +1,13 @@
+package org.ext;
+
+/**
+ * Hello world!
+ *
+ */
+public class App
+{
+ public static void main( String[] args )
+ {
+ System.out.println( "Hello World!" );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/ext-realm-error/ext/src/main/resources/META-INF/plexus/components.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/ext-realm-error/ext/src/main/resources/META-INF/plexus/components.xml
new file mode 100644
index 00000000..18664051
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/ext-realm-error/ext/src/main/resources/META-INF/plexus/components.xml
@@ -0,0 +1 @@
+this is an error. \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/ext-realm-error/project/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/ext-realm-error/project/pom.xml
new file mode 100644
index 00000000..85e9a9fb
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/ext-realm-error/project/pom.xml
@@ -0,0 +1,35 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven.errortest</groupId>
+ <artifactId>ext-realm-error</artifactId>
+ <version>1</version>
+
+ <build>
+ <extensions>
+ <extension>
+ <groupId>org.apache.maven.errortest</groupId>
+ <artifactId>test-maven-ext</artifactId>
+ <version>1</version>
+ </extension>
+ </extensions>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/interp-from-model/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/interp-from-model/pom.xml
new file mode 100644
index 00000000..a840870f
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/interp-from-model/pom.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?><project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven.errortest</groupId>
+ <artifactId>interp-from-model</artifactId>
+ <version>${version}</version>
+
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/interp-from-project/project/local-repo/org/test/bad-pom/1/bad-pom-1.pom b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/interp-from-project/project/local-repo/org/test/bad-pom/1/bad-pom-1.pom
new file mode 100644
index 00000000..b1f29c49
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/interp-from-project/project/local-repo/org/test/bad-pom/1/bad-pom-1.pom
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?><project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.test</groupId>
+ <artifactId>bad-pom</artifactId>
+ <version>1</version>
+
+ <packaging>${packaging}</packaging>
+
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/interp-from-project/project/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/interp-from-project/project/pom.xml
new file mode 100644
index 00000000..bb50b45c
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/interp-from-project/project/pom.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?><project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven.errortest</groupId>
+ <artifactId>interp-from-project</artifactId>
+ <version>1</version>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.test</groupId>
+ <artifactId>bad-pom</artifactId>
+ <version>1</version>
+ <type>pom</type>
+ </dependency>
+ </dependencies>
+
+ <repositories>
+ <repository>
+ <id>repo</id>
+ <url>file://localhost/${basedir}/local-repo</url>
+ </repository>
+ </repositories>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/load-extern-profiles-ioex/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/load-extern-profiles-ioex/pom.xml
new file mode 100644
index 00000000..2a924b8c
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/load-extern-profiles-ioex/pom.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?><project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven.errortest</groupId>
+ <artifactId>load-extern-profiles-ioex</artifactId>
+ <version>1</version>
+
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/load-extern-profiles-xex/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/load-extern-profiles-xex/pom.xml
new file mode 100644
index 00000000..fdaa3d43
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/load-extern-profiles-xex/pom.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?><project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven.errortest</groupId>
+ <artifactId>load-extern-profiles-xex</artifactId>
+ <version>1</version>
+
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/load-extern-profiles-xex/profiles.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/load-extern-profiles-xex/profiles.xml
new file mode 100644
index 00000000..e99fc60b
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/load-extern-profiles-xex/profiles.xml
@@ -0,0 +1,4 @@
+<profilesXml>
+ <profiles>
+ </profile>
+</profilesXml> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/missing-direct-invoke-mojo/plugin/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/missing-direct-invoke-mojo/plugin/pom.xml
new file mode 100644
index 00000000..5895c2a9
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/missing-direct-invoke-mojo/plugin/pom.xml
@@ -0,0 +1,49 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven.errortest</groupId>
+ <artifactId>missing-direct-invoke-mojo-maven-plugin</artifactId>
+ <packaging>maven-plugin</packaging>
+ <version>1</version>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-plugin-api</artifactId>
+ <version>2.0</version>
+ </dependency>
+ </dependencies>
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>2.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-deploy-plugin</artifactId>
+ <version>2.3</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-install-plugin</artifactId>
+ <version>2.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-resources-plugin</artifactId>
+ <version>2.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-jar-plugin</artifactId>
+ <version>2.1</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>2.0.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-plugin-plugin</artifactId>
+ <version>2.3</version>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/missing-direct-invoke-mojo/plugin/src/main/java/org/plugin/TestPlugin.java b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/missing-direct-invoke-mojo/plugin/src/main/java/org/plugin/TestPlugin.java
new file mode 100644
index 00000000..bfd8a7f4
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/missing-direct-invoke-mojo/plugin/src/main/java/org/plugin/TestPlugin.java
@@ -0,0 +1,36 @@
+package org.plugin;
+
+import org.apache.maven.plugin.Mojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugin.logging.Log;
+
+/**
+ * @goal test-unused
+ * @aggregator
+ *
+ * @author jdcasey
+ */
+public class TestPlugin
+ implements Mojo
+{
+
+ private Log log;
+
+ public void execute()
+ throws MojoExecutionException, MojoFailureException
+ {
+ throw new MojoFailureException( this, "This mojo will always fail.", "This mojo is programmed to fail at all times, to express certain error-reporting functions." );
+ }
+
+ public Log getLog()
+ {
+ return log;
+ }
+
+ public void setLog( Log log )
+ {
+ this.log = log;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/missing-module-pom/child1/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/missing-module-pom/child1/pom.xml
new file mode 100644
index 00000000..7ff5c598
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/missing-module-pom/child1/pom.xml
@@ -0,0 +1,19 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<project>
+ <parent>
+ <artifactId>missing-module-pom</artifactId>
+ <groupId>org.apache.maven.errortest</groupId>
+ <version>1</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>missing-module-pom-child1</artifactId>
+
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>3.8.1</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/missing-module-pom/child1/src/main/java/org/test/App.java b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/missing-module-pom/child1/src/main/java/org/test/App.java
new file mode 100644
index 00000000..2c825a09
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/missing-module-pom/child1/src/main/java/org/test/App.java
@@ -0,0 +1,13 @@
+package org.test;
+
+/**
+ * Hello world!
+ *
+ */
+public class App
+{
+ public static void main( String[] args )
+ {
+ System.out.println( "Hello World!" );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/missing-module-pom/child1/src/test/java/org/test/AppTest.java b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/missing-module-pom/child1/src/test/java/org/test/AppTest.java
new file mode 100644
index 00000000..e4e81e21
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/missing-module-pom/child1/src/test/java/org/test/AppTest.java
@@ -0,0 +1,38 @@
+package org.test;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+/**
+ * Unit test for simple App.
+ */
+public class AppTest
+ extends TestCase
+{
+ /**
+ * Create the test case
+ *
+ * @param testName name of the test case
+ */
+ public AppTest( String testName )
+ {
+ super( testName );
+ }
+
+ /**
+ * @return the suite of tests being tested
+ */
+ public static Test suite()
+ {
+ return new TestSuite( AppTest.class );
+ }
+
+ /**
+ * Rigourous Test :-)
+ */
+ public void testApp()
+ {
+ assertTrue( true );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/missing-module-pom/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/missing-module-pom/pom.xml
new file mode 100644
index 00000000..ff895b80
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/missing-module-pom/pom.xml
@@ -0,0 +1,13 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<project xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:schemaLocation='http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd' xmlns='http://maven.apache.org/POM/4.0.0'>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven.errortest</groupId>
+ <artifactId>missing-module-pom</artifactId>
+ <packaging>pom</packaging>
+ <version>1</version>
+
+ <modules>
+ <module>child1</module>
+ <module>child2</module>
+ </modules>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/missing-parent-pom/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/missing-parent-pom/pom.xml
new file mode 100644
index 00000000..e0ab9f6d
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/missing-parent-pom/pom.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?><project>
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.maven.errortest</groupId>
+ <artifactId>missing-parent-pom-parent</artifactId>
+ <version>1</version>
+ </parent>
+
+ <artifactId>missing-parent-pom</artifactId>
+
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/missing-req-mojo-param/plugin/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/missing-req-mojo-param/plugin/pom.xml
new file mode 100644
index 00000000..6e53240d
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/missing-req-mojo-param/plugin/pom.xml
@@ -0,0 +1,49 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven.errortest</groupId>
+ <artifactId>missing-req-mojo-param-maven-plugin</artifactId>
+ <packaging>maven-plugin</packaging>
+ <version>1</version>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-plugin-api</artifactId>
+ <version>2.0</version>
+ </dependency>
+ </dependencies>
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>2.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-deploy-plugin</artifactId>
+ <version>2.3</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-install-plugin</artifactId>
+ <version>2.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-resources-plugin</artifactId>
+ <version>2.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-jar-plugin</artifactId>
+ <version>2.1</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>2.0.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-plugin-plugin</artifactId>
+ <version>2.3</version>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/missing-req-mojo-param/plugin/src/main/java/org/plugin/TestPlugin.java b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/missing-req-mojo-param/plugin/src/main/java/org/plugin/TestPlugin.java
new file mode 100644
index 00000000..51b71a87
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/missing-req-mojo-param/plugin/src/main/java/org/plugin/TestPlugin.java
@@ -0,0 +1,38 @@
+package org.plugin;
+
+import org.apache.maven.plugin.Mojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugin.logging.Log;
+
+/**
+ * @goal test
+ */
+public class TestPlugin
+ implements Mojo
+{
+
+ private Log log;
+
+ /**
+ * @parameter
+ * @required
+ */
+ private String requiredParam;
+
+ public void execute()
+ throws MojoExecutionException, MojoFailureException
+ {
+ }
+
+ public Log getLog()
+ {
+ return log;
+ }
+
+ public void setLog( Log log )
+ {
+ this.log = log;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/missing-req-mojo-param/project/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/missing-req-mojo-param/project/pom.xml
new file mode 100644
index 00000000..b5c9852b
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/missing-req-mojo-param/project/pom.xml
@@ -0,0 +1,25 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>missing-req-mojo-param</artifactId>
+ <version>1</version>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/mojo-config-error/plugin/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/mojo-config-error/plugin/pom.xml
new file mode 100644
index 00000000..de32947a
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/mojo-config-error/plugin/pom.xml
@@ -0,0 +1,49 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven.errortest</groupId>
+ <artifactId>mojo-config-error-maven-plugin</artifactId>
+ <version>1</version>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-plugin-api</artifactId>
+ <version>2.0</version>
+ </dependency>
+ </dependencies>
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>2.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-deploy-plugin</artifactId>
+ <version>2.3</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-install-plugin</artifactId>
+ <version>2.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-resources-plugin</artifactId>
+ <version>2.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-jar-plugin</artifactId>
+ <version>2.1</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>2.0.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-plugin-plugin</artifactId>
+ <version>2.3</version>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/mojo-config-error/plugin/src/main/java/org/plugin/TestPlugin.java b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/mojo-config-error/plugin/src/main/java/org/plugin/TestPlugin.java
new file mode 100644
index 00000000..5836f1e0
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/mojo-config-error/plugin/src/main/java/org/plugin/TestPlugin.java
@@ -0,0 +1,33 @@
+package org.plugin;
+
+import org.apache.maven.plugin.Mojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugin.logging.Log;
+
+/**
+ * @goal test
+ */
+public class TestPlugin
+ implements Mojo
+{
+
+ private Log log;
+
+ public void execute()
+ throws MojoExecutionException, MojoFailureException
+ {
+ throw new MojoExecutionException( "This is meant to fail." );
+ }
+
+ public Log getLog()
+ {
+ return log;
+ }
+
+ public void setLog( Log log )
+ {
+ this.log = log;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/mojo-config-error/plugin/src/main/resources/META-INF/maven/plugin.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/mojo-config-error/plugin/src/main/resources/META-INF/maven/plugin.xml
new file mode 100644
index 00000000..35697de7
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/mojo-config-error/plugin/src/main/resources/META-INF/maven/plugin.xml
@@ -0,0 +1,38 @@
+<plugin>
+ <description></description>
+ <groupId>org.apache.maven.errortest</groupId>
+ <artifactId>mojo-config-error-maven-plugin</artifactId>
+ <version>1</version>
+ <goalPrefix>mojo-config-error</goalPrefix>
+ <isolatedRealm>false</isolatedRealm>
+ <inheritedByDefault>true</inheritedByDefault>
+ <mojos>
+ <mojo>
+ <goal>test</goal>
+ <description></description>
+ <requiresDirectInvocation>false</requiresDirectInvocation>
+ <requiresProject>true</requiresProject>
+ <requiresReports>false</requiresReports>
+ <aggregator>false</aggregator>
+ <requiresOnline>false</requiresOnline>
+ <inheritedByDefault>true</inheritedByDefault>
+ <implementation>org.plugin.TestPlugin</implementation>
+ <language>java</language>
+ <instantiationStrategy>per-lookup</instantiationStrategy>
+ <executionStrategy>once-per-session</executionStrategy>
+ <parameters>
+ <parameter>
+ <name>param</name>
+ <type>java.lang.String</type>
+ <required>true</required>
+ <editable>false</editable>
+ <description></description>
+ </parameter>
+ </parameters>
+ <configuration>
+ <param implementation="java.lang.String" default-value="something"/>
+ </configuration>
+ </mojo>
+ </mojos>
+ <dependencies/>
+</plugin>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/mojo-config-error/project/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/mojo-config-error/project/pom.xml
new file mode 100644
index 00000000..9d63df51
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/mojo-config-error/project/pom.xml
@@ -0,0 +1,45 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>mojo-config-error</artifactId>
+ <version>1</version>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.errortest</groupId>
+ <artifactId>mojo-config-error-maven-plugin</artifactId>
+ <version>1</version>
+ <executions>
+ <execution>
+ <id>test-run</id>
+ <phase>initialize</phase>
+ <goals>
+ <goal>test</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/mojo-exec-err/plugin/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/mojo-exec-err/plugin/pom.xml
new file mode 100644
index 00000000..3347d3c7
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/mojo-exec-err/plugin/pom.xml
@@ -0,0 +1,49 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven.errortest</groupId>
+ <artifactId>mojo-exec-err-maven-plugin</artifactId>
+ <packaging>maven-plugin</packaging>
+ <version>1</version>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-plugin-api</artifactId>
+ <version>2.0</version>
+ </dependency>
+ </dependencies>
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>2.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-deploy-plugin</artifactId>
+ <version>2.3</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-install-plugin</artifactId>
+ <version>2.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-resources-plugin</artifactId>
+ <version>2.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-jar-plugin</artifactId>
+ <version>2.1</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>2.0.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-plugin-plugin</artifactId>
+ <version>2.3</version>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/mojo-exec-err/plugin/src/main/java/org/plugin/TestPlugin.java b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/mojo-exec-err/plugin/src/main/java/org/plugin/TestPlugin.java
new file mode 100644
index 00000000..5836f1e0
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/mojo-exec-err/plugin/src/main/java/org/plugin/TestPlugin.java
@@ -0,0 +1,33 @@
+package org.plugin;
+
+import org.apache.maven.plugin.Mojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugin.logging.Log;
+
+/**
+ * @goal test
+ */
+public class TestPlugin
+ implements Mojo
+{
+
+ private Log log;
+
+ public void execute()
+ throws MojoExecutionException, MojoFailureException
+ {
+ throw new MojoExecutionException( "This is meant to fail." );
+ }
+
+ public Log getLog()
+ {
+ return log;
+ }
+
+ public void setLog( Log log )
+ {
+ this.log = log;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/mojo-exec-err/project/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/mojo-exec-err/project/pom.xml
new file mode 100644
index 00000000..1f10d0fe
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/mojo-exec-err/project/pom.xml
@@ -0,0 +1,26 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>mojo-exec-err</artifactId>
+ <version>1</version>
+
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/mojo-lookup-err/plugin/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/mojo-lookup-err/plugin/pom.xml
new file mode 100644
index 00000000..66adaf00
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/mojo-lookup-err/plugin/pom.xml
@@ -0,0 +1,54 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven.errortest</groupId>
+ <artifactId>mojo-lookup-err-maven-plugin</artifactId>
+ <packaging>maven-plugin</packaging>
+ <version>1</version>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-plugin-api</artifactId>
+ <version>2.0</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-project</artifactId>
+ <version>2.0</version>
+ </dependency>
+ </dependencies>
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>2.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-deploy-plugin</artifactId>
+ <version>2.3</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-install-plugin</artifactId>
+ <version>2.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-resources-plugin</artifactId>
+ <version>2.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-jar-plugin</artifactId>
+ <version>2.1</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>2.0.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-plugin-plugin</artifactId>
+ <version>2.3</version>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/mojo-lookup-err/plugin/src/main/java/org/plugin/TestPlugin.java b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/mojo-lookup-err/plugin/src/main/java/org/plugin/TestPlugin.java
new file mode 100644
index 00000000..bc2e712d
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/mojo-lookup-err/plugin/src/main/java/org/plugin/TestPlugin.java
@@ -0,0 +1,42 @@
+package org.plugin;
+
+import org.apache.maven.plugin.Mojo;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugin.logging.Log;
+
+/**
+ * @goal test
+ * @requiresProject false
+ *
+ * @author jdcasey
+ */
+public class TestPlugin
+ implements Mojo
+{
+
+ private Log log;
+
+ /**
+ * @component role-hint="nonexistant"
+ */
+ private MavenProject project;
+
+ public void execute()
+ throws MojoExecutionException, MojoFailureException
+ {
+ throw new MojoExecutionException( "THIS SHOULD NEVER BE CALLED." );
+ }
+
+ public Log getLog()
+ {
+ return log;
+ }
+
+ public void setLog( Log log )
+ {
+ this.log = log;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/mojo-lookup-err/project/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/mojo-lookup-err/project/pom.xml
new file mode 100644
index 00000000..cddcc140
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/mojo-lookup-err/project/pom.xml
@@ -0,0 +1,25 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>aggregate-mojo-failure</artifactId>
+ <version>1</version>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/parent-parse-ioex/child/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/parent-parse-ioex/child/pom.xml
new file mode 100644
index 00000000..b70261d1
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/parent-parse-ioex/child/pom.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?><project>
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>parent-parse-ioex</artifactId>
+ <groupId>org.apache.maven.errortest</groupId>
+ <version>1</version>
+ </parent>
+ <artifactId>parent-parse-ioex-child</artifactId>
+
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/parent-parse-ioex/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/parent-parse-ioex/pom.xml
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/parent-parse-ioex/pom.xml
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/parent-parse-xex/child/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/parent-parse-xex/child/pom.xml
new file mode 100644
index 00000000..3961dd48
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/parent-parse-xex/child/pom.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?><project>
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>parent-parse-xex</artifactId>
+ <groupId>org.apache.maven.errortest</groupId>
+ <version>1</version>
+ </parent>
+ <artifactId>parent-parse-xex-child</artifactId>
+
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/parent-parse-xex/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/parent-parse-xex/pom.xml
new file mode 100644
index 00000000..7ac14c6c
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/parent-parse-xex/pom.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?><project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven.errortest</groupId>
+ <artifactId>parent-parse-xex</artifactId>
+ <version>1</ver>
+
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/profile-activator-err/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/profile-activator-err/pom.xml
new file mode 100644
index 00000000..031ce1e9
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/profile-activator-err/pom.xml
@@ -0,0 +1,39 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>profile-activator-err</artifactId>
+ <version>1</version>
+
+ <profiles>
+ <profile>
+ <id>faulty</id>
+ <activation>
+ <custom>
+ <type>nothing</type>
+ <configuration>
+ <foo>bar</foo>
+ </configuration>
+ </custom>
+ </activation>
+ </profile>
+ </profiles>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/profile-activator-lookup-err/ext/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/profile-activator-lookup-err/ext/pom.xml
new file mode 100644
index 00000000..0f93b9e6
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/profile-activator-lookup-err/ext/pom.xml
@@ -0,0 +1,38 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven.errortest</groupId>
+ <artifactId>profile-activator-lookup-err-ext</artifactId>
+ <version>1</version>
+
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>2.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-deploy-plugin</artifactId>
+ <version>2.3</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-install-plugin</artifactId>
+ <version>2.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-resources-plugin</artifactId>
+ <version>2.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-jar-plugin</artifactId>
+ <version>2.1</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>2.0.2</version>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/profile-activator-lookup-err/ext/src/main/java/org/ext/App.java b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/profile-activator-lookup-err/ext/src/main/java/org/ext/App.java
new file mode 100644
index 00000000..0701b7ae
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/profile-activator-lookup-err/ext/src/main/java/org/ext/App.java
@@ -0,0 +1,13 @@
+package org.ext;
+
+/**
+ * Hello world!
+ *
+ */
+public class App
+{
+ public static void main( String[] args )
+ {
+ System.out.println( "Hello World!" );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/profile-activator-lookup-err/ext/src/main/resources/META-INF/plexus/components.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/profile-activator-lookup-err/ext/src/main/resources/META-INF/plexus/components.xml
new file mode 100644
index 00000000..74a2963c
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/profile-activator-lookup-err/ext/src/main/resources/META-INF/plexus/components.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0"?>
+<component-set>
+ <components>
+ <component>
+ <role>org.apache.maven.profiles.activation.ProfileActivator</role>
+ <role-hint>faulty</role-hint>
+ <implementation>org.ext.App</implementation>
+ <requirements>
+ <requirement>
+ <role>org.apache.maven.artifact.ArtifactResolver</role>
+ <field-name>artifactResolver</field-name>
+ </requirement>
+ </requirements>
+ </component>
+ </components>
+</component-set> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/profile-activator-lookup-err/project/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/profile-activator-lookup-err/project/pom.xml
new file mode 100644
index 00000000..a34b838d
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/profile-activator-lookup-err/project/pom.xml
@@ -0,0 +1,46 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven.errortest</groupId>
+ <artifactId>profile-activator-lookup-err</artifactId>
+ <version>1</version>
+
+ <profiles>
+ <profile>
+ <id>test-profile</id>
+ <activation>
+ <property>
+ <name>java.version</name>
+ </property>
+ </activation>
+ </profile>
+ </profiles>
+
+ <build>
+ <extensions>
+ <extension>
+ <groupId>org.apache.maven.errortest</groupId>
+ <artifactId>profile-activator-lookup-err-ext</artifactId>
+ <version>1</version>
+ </extension>
+ </extensions>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/project-collision/mod1/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/project-collision/mod1/pom.xml
new file mode 100644
index 00000000..ebb7ee78
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/project-collision/mod1/pom.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?><project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.errortest</groupId>
+ <artifactId>module</artifactId>
+ <version>1</version>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/project-collision/mod2/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/project-collision/mod2/pom.xml
new file mode 100644
index 00000000..ebb7ee78
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/project-collision/mod2/pom.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?><project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.errortest</groupId>
+ <artifactId>module</artifactId>
+ <version>1</version>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/project-collision/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/project-collision/pom.xml
new file mode 100644
index 00000000..9e11c6d1
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/project-collision/pom.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?><project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven.errortest</groupId>
+ <artifactId>project-collision</artifactId>
+ <version>1</version>
+ <packaging>pom</packaging>
+
+ <modules>
+ <module>mod1</module>
+ <module>mod2</module>
+ </modules>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/project-cycle/dep/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/project-cycle/dep/pom.xml
new file mode 100644
index 00000000..eb1f08fd
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/project-cycle/dep/pom.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?><project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.maven.errortest</groupId>
+ <artifactId>project-cycle</artifactId>
+ <version>1</version>
+ </parent>
+
+ <groupId>org.apache.maven.errortest</groupId>
+ <artifactId>project-cycle-dep</artifactId>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/project-cycle/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/project-cycle/pom.xml
new file mode 100644
index 00000000..75c53e7b
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/project-cycle/pom.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?><project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven.errortest</groupId>
+ <artifactId>project-cycle</artifactId>
+ <version>1</version>
+ <packaging>pom</packaging>
+
+ <modules>
+ <module>dep</module>
+ </modules>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven.errortest</groupId>
+ <artifactId>project-cycle-dep</artifactId>
+ <version>1</version>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/project-dep-missing/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/project-dep-missing/pom.xml
new file mode 100644
index 00000000..3c297ac1
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/project-dep-missing/pom.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?><project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven.errortest</groupId>
+ <artifactId>project-dep-missing</artifactId>
+ <version>1</version>
+
+ <repositories>
+ <repository>
+ <id>central</id>
+ <url>file://${java.io.tmpdir}</url>
+ </repository>
+ </repositories>
+
+ <dependencies>
+ <dependency>
+ <groupId>not</groupId>
+ <artifactId>found</artifactId>
+ <version>3.8.1</version>
+ </dependency>
+ </dependencies>
+
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/project-dep-missing/src/main/java/org/apache/maven/test/error/mojoFailure/App.java b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/project-dep-missing/src/main/java/org/apache/maven/test/error/mojoFailure/App.java
new file mode 100644
index 00000000..dd4102a3
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/project-dep-missing/src/main/java/org/apache/maven/test/error/mojoFailure/App.java
@@ -0,0 +1,13 @@
+package org.apache.maven.test.error.mojoFailure;
+
+/**
+ * Hello world!
+ *
+ */
+public class App
+{
+ public static void main( String[] args )
+ {
+ System.out.println( "Hello World!" );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/project-dep-missing/src/test/java/org/apache/maven/test/error/mojoFailure/AppTest.java b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/project-dep-missing/src/test/java/org/apache/maven/test/error/mojoFailure/AppTest.java
new file mode 100644
index 00000000..7e0144ac
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/project-dep-missing/src/test/java/org/apache/maven/test/error/mojoFailure/AppTest.java
@@ -0,0 +1,38 @@
+package org.apache.maven.test.error.mojoFailure;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+/**
+ * Unit test for simple App.
+ */
+public class AppTest
+ extends TestCase
+{
+ /**
+ * Create the test case
+ *
+ * @param testName name of the test case
+ */
+ public AppTest( String testName )
+ {
+ super( testName );
+ }
+
+ /**
+ * @return the suite of tests being tested
+ */
+ public static Test suite()
+ {
+ return new TestSuite( AppTest.class );
+ }
+
+ /**
+ * Rigourous Test :-)
+ */
+ public void testApp()
+ {
+ assertTrue( true );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/project-mojo-failure/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/project-mojo-failure/pom.xml
new file mode 100644
index 00000000..9323d4ea
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/project-mojo-failure/pom.xml
@@ -0,0 +1,17 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven.test.error</groupId>
+ <artifactId>project-mojo-failure</artifactId>
+ <packaging>jar</packaging>
+ <version>1</version>
+
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>3.8.1</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/project-mojo-failure/src/main/java/org/apache/maven/test/error/mojoFailure/App.java b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/project-mojo-failure/src/main/java/org/apache/maven/test/error/mojoFailure/App.java
new file mode 100644
index 00000000..89f091d2
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/project-mojo-failure/src/main/java/org/apache/maven/test/error/mojoFailure/App.java
@@ -0,0 +1,14 @@
+package org.apache.maven.test.error.mojoFailure;
+
+/**
+ * Hello world!
+ *
+ */
+public class App
+{
+ public static void main( String[] args )
+ {
+ System.out.println( "Hello World!" );
+ StringUtils utils;
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/project-mojo-failure/src/test/java/org/apache/maven/test/error/mojoFailure/AppTest.java b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/project-mojo-failure/src/test/java/org/apache/maven/test/error/mojoFailure/AppTest.java
new file mode 100644
index 00000000..7e0144ac
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/project-mojo-failure/src/test/java/org/apache/maven/test/error/mojoFailure/AppTest.java
@@ -0,0 +1,38 @@
+package org.apache.maven.test.error.mojoFailure;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+/**
+ * Unit test for simple App.
+ */
+public class AppTest
+ extends TestCase
+{
+ /**
+ * Create the test case
+ *
+ * @param testName name of the test case
+ */
+ public AppTest( String testName )
+ {
+ super( testName );
+ }
+
+ /**
+ * @return the suite of tests being tested
+ */
+ public static Test suite()
+ {
+ return new TestSuite( AppTest.class );
+ }
+
+ /**
+ * Rigourous Test :-)
+ */
+ public void testApp()
+ {
+ assertTrue( true );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/project-parse-xex/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/project-parse-xex/pom.xml
new file mode 100644
index 00000000..fd68be6e
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/project-parse-xex/pom.xml
@@ -0,0 +1,25 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>project-parse-xex</artifactId>
+ <version>1</ver>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/project-validation/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/project-validation/pom.xml
new file mode 100644
index 00000000..9f66c18b
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/project-validation/pom.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?><project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven.errortest</groupId>
+ <artifactId>project-validation</artifactId>
+ <version>1</version>
+
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/repo-creation-err/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/repo-creation-err/pom.xml
new file mode 100644
index 00000000..d0574bd0
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/error-reporting-projects/repo-creation-err/pom.xml
@@ -0,0 +1,41 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>repo-creation-err</artifactId>
+ <version>1</version>
+
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>3.8.1</version>
+ </dependency>
+ </dependencies>
+
+ <repositories>
+ <repository>
+ <id>test</id>
+ <url>http://www.google.com</url>
+ <layout>nothing</layout>
+ </repository>
+ </repositories>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/eventing-projects/read-with-deps/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/eventing-projects/read-with-deps/pom.xml
new file mode 100644
index 00000000..169b3921
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/eventing-projects/read-with-deps/pom.xml
@@ -0,0 +1,15 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>testing</groupId>
+ <artifactId>read-with-deps</artifactId>
+ <version>1</version>
+
+ <dependencies>
+ <dependency>
+ <groupId>tests</groupId>
+ <artifactId>dep</artifactId>
+ <version>1</version>
+ <type>pom</type>
+ </dependency>
+ </dependencies>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/eventing-projects/read-with-deps/repo/tests/dep/1/dep-1.pom b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/eventing-projects/read-with-deps/repo/tests/dep/1/dep-1.pom
new file mode 100644
index 00000000..175bf210
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/eventing-projects/read-with-deps/repo/tests/dep/1/dep-1.pom
@@ -0,0 +1,6 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>testing</groupId>
+ <artifactId>dep</artifactId>
+ <version>1</version>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/eventing-projects/simple-read-project/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/eventing-projects/simple-read-project/pom.xml
new file mode 100644
index 00000000..9a3f6be4
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/eventing-projects/simple-read-project/pom.xml
@@ -0,0 +1,6 @@
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>testing</groupId>
+ <artifactId>simple-read-project</artifactId>
+ <version>1</version>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/extensions/META-INF/plexus/components.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/extensions/META-INF/plexus/components.xml
new file mode 100644
index 00000000..f38af597
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/extensions/META-INF/plexus/components.xml
@@ -0,0 +1,28 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<component-set>
+ <components>
+ <component>
+ <role>org.apache.maven.artifact.factory.ArtifactFactory</role>
+ <role-hint>default</role-hint>
+ <implementation>org.apache.maven.embedder.CustomArtifactFactory</implementation>
+ </component>
+ </components>
+</component-set> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/java/org/apache/maven/cli/CLIManagerTest.java b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/java/org/apache/maven/cli/CLIManagerTest.java
new file mode 100644
index 00000000..163d9d9d
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/java/org/apache/maven/cli/CLIManagerTest.java
@@ -0,0 +1,108 @@
+package org.apache.maven.cli;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+import org.apache.commons.cli.Option;
+import org.codehaus.plexus.PlexusTestCase;
+import org.codehaus.plexus.util.FileUtils;
+
+/**
+ * Pseudo test to generate documentation fragment about supported CLI options.
+ * TODO such documentation generation code should not be necessary as unit test but should be run
+ * during site generation (Velocity? Doxia macro?)
+ */
+public class CLIManagerTest
+ extends PlexusTestCase
+{
+ private final static String LS = System.getProperty( "line.separator" );
+
+ private static class OptionComparator
+ implements Comparator<Option>
+ {
+ public int compare( Option opt1, Option opt2 )
+ {
+ return opt1.getOpt().compareToIgnoreCase( opt2.getOpt() );
+ }
+ }
+
+ private static class CLIManagerExtension
+ extends CLIManager
+ {
+ public Collection<Option> getOptions()
+ {
+ @SuppressWarnings( "unchecked" )
+ List<Option> optList = new ArrayList<Option>( options.getOptions() );
+ Collections.sort( optList, new OptionComparator() );
+ return optList;
+ }
+ }
+
+ public String getOptionsAsHtml()
+ {
+ StringBuilder sb = new StringBuilder();
+ boolean a = true;
+ sb.append( "<table border='1' class='zebra-striped'><tr class='a'><th><b>Options</b></th><th><b>Description</b></th></tr>" );
+ for ( Option option : new CLIManagerExtension().getOptions() )
+ {
+ a = !a;
+ sb.append( "<tr class='" ).append( a ? 'a' : 'b' ).append( "'><td><code>-<a name='" );
+ sb.append( option.getOpt() );
+ sb.append( "'>" );
+ sb.append( option.getOpt() );
+ sb.append( "</a>,--<a name='" );
+ sb.append( option.getLongOpt() );
+ sb.append( "'>" );
+ sb.append( option.getLongOpt() );
+ sb.append( "</a>" );
+ if ( option.hasArg() )
+ {
+ if ( option.hasArgName() )
+ {
+ sb.append( " &lt;" ).append( option.getArgName() ).append( "&gt;" );
+ }
+ else
+ {
+ sb.append( ' ' );
+ }
+ }
+ sb.append( "</code></td><td>" );
+ sb.append( option.getDescription() );
+ sb.append( "</td></tr>" );
+ sb.append( LS );
+ }
+ sb.append( "</table>" );
+ return sb.toString();
+ }
+
+ public void testOptionsAsHtml()
+ throws IOException
+ {
+ File options = getTestFile( "target/test-classes/options.html" );
+ FileUtils.fileWrite( options, "UTF-8", getOptionsAsHtml() );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/java/org/apache/maven/cli/CLIReportingUtilsTest.java b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/java/org/apache/maven/cli/CLIReportingUtilsTest.java
new file mode 100644
index 00000000..65488c7c
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/java/org/apache/maven/cli/CLIReportingUtilsTest.java
@@ -0,0 +1,40 @@
+package org.apache.maven.cli;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import junit.framework.TestCase;
+
+public class CLIReportingUtilsTest
+ extends TestCase
+{
+
+ public void testFormatDuration()
+ {
+ assertEquals( "0.001 s", CLIReportingUtils.formatDuration( 1 ) );
+ assertEquals( "0.999 s", CLIReportingUtils.formatDuration( 1000 - 1 ) );
+ assertEquals( "1.000 s", CLIReportingUtils.formatDuration( 1000 ) );
+ assertEquals( "59.999 s", CLIReportingUtils.formatDuration( 60 * 1000 - 1 ) );
+ assertEquals( "01:00 min", CLIReportingUtils.formatDuration( 60 * 1000 ) );
+ assertEquals( "59:59 min", CLIReportingUtils.formatDuration( 60 * 60 * 1000 - 1 ) );
+ assertEquals( "01:00 h", CLIReportingUtils.formatDuration( 60 * 60 * 1000 ) );
+ assertEquals( "23:59 h", CLIReportingUtils.formatDuration( 24 * 60 * 60 * 1000 - 1 ) );
+ assertEquals( "1 d 00:00 h", CLIReportingUtils.formatDuration( 24 * 60 * 60 * 1000 ) );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/java/org/apache/maven/cli/MavenCliTest.java b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/java/org/apache/maven/cli/MavenCliTest.java
new file mode 100644
index 00000000..c8d75b10
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/java/org/apache/maven/cli/MavenCliTest.java
@@ -0,0 +1,110 @@
+package org.apache.maven.cli;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+
+import junit.framework.TestCase;
+
+import org.apache.commons.cli.ParseException;
+
+public class MavenCliTest
+ extends TestCase
+{
+ private MavenCli cli;
+
+ private String origBasedir;
+
+ protected void setUp()
+ {
+ cli = new MavenCli();
+ origBasedir = System.getProperty( MavenCli.MULTIMODULE_PROJECT_DIRECTORY );
+ }
+
+ @Override
+ protected void tearDown()
+ throws Exception
+ {
+ if ( origBasedir != null )
+ {
+ System.setProperty( MavenCli.MULTIMODULE_PROJECT_DIRECTORY, origBasedir );
+ }
+ else
+ {
+ System.getProperties().remove( MavenCli.MULTIMODULE_PROJECT_DIRECTORY );
+ }
+ super.tearDown();
+ }
+
+ public void testCalculateDegreeOfConcurrencyWithCoreMultiplier()
+ {
+ int cores = Runtime.getRuntime().availableProcessors();
+ // -T2.2C
+ assertEquals( (int) ( cores * 2.2 ), cli.calculateDegreeOfConcurrencyWithCoreMultiplier( "C2.2" ) );
+ // -TC2.2
+ assertEquals( (int) ( cores * 2.2 ), cli.calculateDegreeOfConcurrencyWithCoreMultiplier( "2.2C" ) );
+
+ try
+ {
+ cli.calculateDegreeOfConcurrencyWithCoreMultiplier( "CXXX" );
+ fail( "Should have failed with a NumberFormatException" );
+ }
+ catch ( NumberFormatException e )
+ {
+ // carry on
+ }
+ }
+
+ public void testMavenConfig()
+ throws Exception
+ {
+ System.setProperty( MavenCli.MULTIMODULE_PROJECT_DIRECTORY, new File( "src/test/projects/config" ).getCanonicalPath() );
+ CliRequest request = new CliRequest( new String[0], null );
+
+ // read .mvn/maven.config
+ cli.initialize( request );
+ cli.cli( request );
+ assertEquals( "multithreaded", request.commandLine.getOptionValue( "builder" ) );
+ assertEquals( "8", request.commandLine.getOptionValue( "threads" ) );
+
+ // override from command line
+ request = new CliRequest( new String[] { "--builder", "foobar" }, null );
+ cli.cli( request );
+ assertEquals( "foobar", request.commandLine.getOptionValue( "builder" ) );
+ }
+
+ public void testMavenConfigInvalid()
+ throws Exception
+ {
+ System.setProperty( MavenCli.MULTIMODULE_PROJECT_DIRECTORY, new File( "src/test/projects/config-illegal" ).getCanonicalPath() );
+ CliRequest request = new CliRequest( new String[0], null );
+
+ cli.initialize( request );
+ try
+ {
+ cli.cli( request );
+ fail();
+ }
+ catch ( ParseException expected )
+ {
+
+ }
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/plugin-version-references/jar-pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/plugin-version-references/jar-pom.xml
new file mode 100644
index 00000000..1cce9991
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/plugin-version-references/jar-pom.xml
@@ -0,0 +1,32 @@
+<project>
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>2.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-deploy-plugin</artifactId>
+ <version>2.3</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-install-plugin</artifactId>
+ <version>2.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-resources-plugin</artifactId>
+ <version>2.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-jar-plugin</artifactId>
+ <version>2.1</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>2.0.2</version>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/plugin-version-references/maven-plugin-pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/plugin-version-references/maven-plugin-pom.xml
new file mode 100644
index 00000000..7cfd6a2f
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/plugin-version-references/maven-plugin-pom.xml
@@ -0,0 +1,36 @@
+<project>
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>2.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-deploy-plugin</artifactId>
+ <version>2.3</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-install-plugin</artifactId>
+ <version>2.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-resources-plugin</artifactId>
+ <version>2.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-jar-plugin</artifactId>
+ <version>2.1</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>2.0.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-plugin-plugin</artifactId>
+ <version>2.3</version>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/projects/bad-module-non-recursive/badmodule/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/projects/bad-module-non-recursive/badmodule/pom.xml
new file mode 100644
index 00000000..7efc0a2c
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/projects/bad-module-non-recursive/badmodule/pom.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?><project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>other</groupId>
+ <artifactId>parent</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+ </parent>
+
+ <groupId>badmodule</groupId>
+ <artifactId>badmodule</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/projects/bad-module-non-recursive/goodmodule/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/projects/bad-module-non-recursive/goodmodule/pom.xml
new file mode 100644
index 00000000..639315ed
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/projects/bad-module-non-recursive/goodmodule/pom.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?><project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>badmodule</groupId>
+ <artifactId>parent</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+ </parent>
+
+ <groupId>badmodule</groupId>
+ <artifactId>good</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/projects/bad-module-non-recursive/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/projects/bad-module-non-recursive/pom.xml
new file mode 100644
index 00000000..890e7c84
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/projects/bad-module-non-recursive/pom.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?><project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>badmodule</groupId>
+ <artifactId>parent</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+ <packaging>pom</packaging>
+
+ <modules>
+ <module>goodmodule</module>
+ <module>badmodule</module>
+ </modules>
+
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/projects/config-illegal/.mvn/maven.config b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/projects/config-illegal/.mvn/maven.config
new file mode 100644
index 00000000..8541464a
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/projects/config-illegal/.mvn/maven.config
@@ -0,0 +1 @@
+deploy
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/projects/config/.mvn/maven.config b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/projects/config/.mvn/maven.config
new file mode 100644
index 00000000..3d0f13b2
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/projects/config/.mvn/maven.config
@@ -0,0 +1,2 @@
+-T8 --builder
+ multithreaded
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/projects/invalid-goal/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/projects/invalid-goal/pom.xml
new file mode 100644
index 00000000..d72b515a
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/projects/invalid-goal/pom.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.maven.its.mng</groupId>
+ <artifactId>test1</artifactId>
+ <version>1.0-SNAPSHOT</version>
+
+ <packaging>jar</packaging>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-site-plugin</artifactId>
+ <version>2.0-beta-7</version>
+
+ <executions>
+ <execution>
+ <goals>
+ <goal>invalid-goal</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/projects/isolated-project-getting-parent-pom/project/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/projects/isolated-project-getting-parent-pom/project/pom.xml
new file mode 100644
index 00000000..d5973975
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/projects/isolated-project-getting-parent-pom/project/pom.xml
@@ -0,0 +1,13 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.codehaus.m2eclipse</groupId>
+ <artifactId>parent</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ </parent>
+ <artifactId>project-1</artifactId>
+ <packaging>jar</packaging>
+ <name>project-1</name>
+ <url>http://maven.apache.org</url>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/projects/isolated-project-getting-parent-pom/project/src/main/java/org/codehaus/m2eclipse/App.java b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/projects/isolated-project-getting-parent-pom/project/src/main/java/org/codehaus/m2eclipse/App.java
new file mode 100644
index 00000000..f959dc43
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/projects/isolated-project-getting-parent-pom/project/src/main/java/org/codehaus/m2eclipse/App.java
@@ -0,0 +1,13 @@
+package org.codehaus.m2eclipse;
+
+/**
+ * Hello world!
+ *
+ */
+public class App
+{
+ public static void main( String[] args )
+ {
+ System.out.println( "Hello World!" );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/projects/isolated-project-getting-parent-pom/project/src/test/java/org/codehaus/m2eclipse/AppTest.java b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/projects/isolated-project-getting-parent-pom/project/src/test/java/org/codehaus/m2eclipse/AppTest.java
new file mode 100644
index 00000000..69af0613
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/projects/isolated-project-getting-parent-pom/project/src/test/java/org/codehaus/m2eclipse/AppTest.java
@@ -0,0 +1,38 @@
+package org.codehaus.m2eclipse;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+/**
+ * Unit test for simple App.
+ */
+public class AppTest
+ extends TestCase
+{
+ /**
+ * Create the test case
+ *
+ * @param testName name of the test case
+ */
+ public AppTest( String testName )
+ {
+ super( testName );
+ }
+
+ /**
+ * @return the suite of tests being tested
+ */
+ public static Test suite()
+ {
+ return new TestSuite( AppTest.class );
+ }
+
+ /**
+ * Rigourous Test :-)
+ */
+ public void testApp()
+ {
+ assertTrue( true );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/projects/isolated-project-getting-parent-pom/repository/org/codehaus/m2eclipse/parent/1.0-SNAPSHOT/maven-metadata-company.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/projects/isolated-project-getting-parent-pom/repository/org/codehaus/m2eclipse/parent/1.0-SNAPSHOT/maven-metadata-company.xml
new file mode 100644
index 00000000..15db1b0d
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/projects/isolated-project-getting-parent-pom/repository/org/codehaus/m2eclipse/parent/1.0-SNAPSHOT/maven-metadata-company.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?><metadata>
+ <groupId>org.codehaus.m2eclipse</groupId>
+ <artifactId>parent</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <versioning>
+ <snapshot>
+ <localCopy>true</localCopy>
+ </snapshot>
+ <lastUpdated>20070930165921</lastUpdated>
+ </versioning>
+</metadata> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/projects/isolated-project-getting-parent-pom/repository/org/codehaus/m2eclipse/parent/1.0-SNAPSHOT/parent-1.0-SNAPSHOT.pom b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/projects/isolated-project-getting-parent-pom/repository/org/codehaus/m2eclipse/parent/1.0-SNAPSHOT/parent-1.0-SNAPSHOT.pom
new file mode 100644
index 00000000..4aaf1686
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/projects/isolated-project-getting-parent-pom/repository/org/codehaus/m2eclipse/parent/1.0-SNAPSHOT/parent-1.0-SNAPSHOT.pom
@@ -0,0 +1,18 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.codehaus.m2eclipse</groupId>
+ <artifactId>parent</artifactId>
+ <packaging>pom</packaging>
+ <version>1.0-SNAPSHOT</version>
+ <name>parent</name>
+ <url>http://maven.apache.org</url>
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>3.8.1</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/projects/isolated-project-getting-parent-pom/repository/org/codehaus/m2eclipse/parent/maven-metadata-local.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/projects/isolated-project-getting-parent-pom/repository/org/codehaus/m2eclipse/parent/maven-metadata-local.xml
new file mode 100644
index 00000000..5c4412d2
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/projects/isolated-project-getting-parent-pom/repository/org/codehaus/m2eclipse/parent/maven-metadata-local.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?><metadata>
+ <groupId>org.codehaus.m2eclipse</groupId>
+ <artifactId>parent</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <versioning>
+ <versions>
+ <version>1.0-SNAPSHOT</version>
+ </versions>
+ <lastUpdated>20070930165921</lastUpdated>
+ </versioning>
+</metadata> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/projects/isolated-project-getting-parent-pom/settings.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/projects/isolated-project-getting-parent-pom/settings.xml
new file mode 100644
index 00000000..60c25eb8
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/projects/isolated-project-getting-parent-pom/settings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0"?>
+<settings>
+ <profiles>
+ <profile>
+ <id>company</id>
+ <repositories>
+ <repository>
+ <id>repo</id>
+ <url>file:///tmp/repo</url>
+ <snapshots>
+ <enabled>true</enabled>
+ </snapshots>
+ <releases>
+ <enabled>false</enabled>
+ </releases>
+ </repository>
+ </repositories>
+ </profile>
+ </profiles>
+ <activeProfiles>
+ <activeProfile>company</activeProfile>
+ </activeProfiles>
+</settings>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/projects/optional-dep/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/projects/optional-dep/pom.xml
new file mode 100644
index 00000000..56c99e13
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/projects/optional-dep/pom.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>optionaldependency</groupId>
+ <artifactId>p01</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+
+ <!--
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>3.8.1</version>
+ <optional>false</optional>
+ </dependency>
+ </dependencies>
+ -->
+
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/projects/readProject-missingModuleIgnored/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/projects/readProject-missingModuleIgnored/pom.xml
new file mode 100644
index 00000000..851987fe
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/projects/readProject-missingModuleIgnored/pom.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?><project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>missing.module</groupId>
+ <artifactId>parent</artifactId>
+ <version>1</version>
+ <packaging>pom</packaging>
+
+ <modules>
+ <module>child1</module>
+ </modules>
+
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/projects/readProject-withScmInheritance/modules/child1/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/projects/readProject-withScmInheritance/modules/child1/pom.xml
new file mode 100644
index 00000000..d269726d
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/projects/readProject-withScmInheritance/modules/child1/pom.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?><project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>scm.inherit</groupId>
+ <artifactId>parent</artifactId>
+ <version>1</version>
+ <relativePath>../../pom.xml</relativePath>
+ </parent>
+
+ <artifactId>child1</artifactId>
+
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/projects/readProject-withScmInheritance/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/projects/readProject-withScmInheritance/pom.xml
new file mode 100644
index 00000000..3323e47d
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/projects/readProject-withScmInheritance/pom.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?><project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>scm.inherit</groupId>
+ <artifactId>parent</artifactId>
+ <version>1</version>
+ <packaging>pom</packaging>
+
+ <scm>
+ <connection>scm:svn:http://host/trunk/parent</connection>
+ <developerConnection>scm:svn:https://host/trunk/parent</developerConnection>
+ <url>http://host/viewer?path=/trunk/parent</url>
+ </scm>
+
+ <modules>
+ <module>modules/child1</module>
+ </modules>
+
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/resources/META-INF/maven/org.apache.maven/maven-core/pom.properties b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/resources/META-INF/maven/org.apache.maven/maven-core/pom.properties
new file mode 100644
index 00000000..8b958ebb
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/resources/META-INF/maven/org.apache.maven/maven-core/pom.properties
@@ -0,0 +1,18 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+version=2.1-SNAPSHOT \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/resources/pom-with-distribution-status.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/resources/pom-with-distribution-status.xml
new file mode 100644
index 00000000..0bece7fe
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/resources/pom-with-distribution-status.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>test</artifactId>
+ <version>1.0</version>
+ <distributionManagement>
+ <status>deployed</status>
+ </distributionManagement>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/resources/pom-without-dependencies.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/resources/pom-without-dependencies.xml
new file mode 100644
index 00000000..ad2d6aa3
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/resources/pom-without-dependencies.xml
@@ -0,0 +1,30 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-model</artifactId>
+ <name>Maven Embedder Test Project</name>
+ <version>1.0</version>
+ <description>Maven Embedder Test Project Without Any Dependencies</description>
+ <dependencies>
+ <!-- no dependencies! -->
+ </dependencies>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/resources/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/resources/pom.xml
new file mode 100644
index 00000000..c226875a
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/resources/pom.xml
@@ -0,0 +1,34 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-model</artifactId>
+ <name>Maven Embedder Test Project</name>
+ <version>1.0</version>
+ <description>Maven Embedder Test Project</description>
+ <dependencies>
+ <dependency>
+ <groupId>plexus</groupId>
+ <artifactId>plexus-utils</artifactId>
+ <version>1.0.2</version>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/resources/pom2.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/resources/pom2.xml
new file mode 100644
index 00000000..b99ad32e
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/resources/pom2.xml
@@ -0,0 +1,48 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>embedder-test-project2</artifactId>
+ <packaging>jar</packaging>
+ <version>1.0-SNAPSHOT</version>
+ <name>Maven Quick Start Archetype</name>
+ <url>http://maven.apache.org</url>
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>3.8.2</version>
+ <scope>test</scope>
+ <type>mkleint</type>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <!-- it's here just for the extensions tag -->
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>2.4.3</version>
+ <extensions>true</extensions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/resources/settings/invalid-settings.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/resources/settings/invalid-settings.xml
new file mode 100644
index 00000000..a6e0ea96
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/resources/settings/invalid-settings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0"?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<settings>
+ <!-- Missing end tag below -->
+ <localRepository>/Users/jvanzyl/maven-repo-local</localRepository
+</settings>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/resources/settings/valid-settings.xml b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/resources/settings/valid-settings.xml
new file mode 100644
index 00000000..a7693343
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/test/resources/settings/valid-settings.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0"?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<settings>
+ <localRepository>/global/maven/local-repository</localRepository>
+ <pluginGroups>
+ <pluginGroup>org.codehaus.tycho</pluginGroup>
+ <pluginGroup>org.sonatype.pwt</pluginGroup>
+ </pluginGroups>
+</settings>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/pom.xml
new file mode 100644
index 00000000..2b514052
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/pom.xml
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+ <!--
+ Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE
+ file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by
+ applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language
+ governing permissions and limitations under the License.
+ -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven</artifactId>
+ <version>3.3.3</version>
+ </parent>
+
+ <artifactId>maven-model-builder</artifactId>
+
+ <name>Maven Model Builder</name>
+ <description>The effective model builder, with inheritance, profile activation, interpolation, ...</description>
+
+ <scm><!-- remove when git scm url format can accept artifact-id at the end, as automatically inherited -->
+ <connection>scm:git:https://git-wip-us.apache.org/repos/asf/maven.git</connection>
+ <developerConnection>scm:git:https://git-wip-us.apache.org/repos/asf/maven.git</developerConnection>
+ <tag>maven-3.3.3</tag>
+ </scm>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-utils</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-interpolation</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-component-annotations</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-model</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-builder-support</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.sisu</groupId>
+ <artifactId>org.eclipse.sisu.plexus</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.sonatype.sisu</groupId>
+ <artifactId>sisu-guice</artifactId>
+ <classifier>no_aop</classifier>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>xmlunit</groupId>
+ <artifactId>xmlunit</artifactId>
+ <version>1.3</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-component-metadata</artifactId>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/AbstractModelBuildingListener.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/AbstractModelBuildingListener.java
new file mode 100644
index 00000000..5138776a
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/AbstractModelBuildingListener.java
@@ -0,0 +1,37 @@
+package org.apache.maven.model.building;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Provides a skeleton implementation for model building listeners. The methods of this class are empty.
+ *
+ * @author Benjamin Bentmann
+ */
+public class AbstractModelBuildingListener
+ implements ModelBuildingListener
+{
+
+ @Override
+ public void buildExtensionsAssembled( ModelBuildingEvent event )
+ {
+ // default does nothing
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuilder.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuilder.java
new file mode 100644
index 00000000..52b3c9c8
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuilder.java
@@ -0,0 +1,1309 @@
+package org.apache.maven.model.building;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+
+import static org.apache.maven.model.building.Result.error;
+import static org.apache.maven.model.building.Result.newResult;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.maven.model.Activation;
+import org.apache.maven.model.Build;
+import org.apache.maven.model.Dependency;
+import org.apache.maven.model.DependencyManagement;
+import org.apache.maven.model.InputLocation;
+import org.apache.maven.model.InputSource;
+import org.apache.maven.model.Model;
+import org.apache.maven.model.Parent;
+import org.apache.maven.model.Plugin;
+import org.apache.maven.model.PluginManagement;
+import org.apache.maven.model.Profile;
+import org.apache.maven.model.Repository;
+import org.apache.maven.model.building.ModelProblem.Severity;
+import org.apache.maven.model.building.ModelProblem.Version;
+import org.apache.maven.model.composition.DependencyManagementImporter;
+import org.apache.maven.model.inheritance.InheritanceAssembler;
+import org.apache.maven.model.interpolation.ModelInterpolator;
+import org.apache.maven.model.io.ModelParseException;
+import org.apache.maven.model.management.DependencyManagementInjector;
+import org.apache.maven.model.management.PluginManagementInjector;
+import org.apache.maven.model.normalization.ModelNormalizer;
+import org.apache.maven.model.path.ModelPathTranslator;
+import org.apache.maven.model.path.ModelUrlNormalizer;
+import org.apache.maven.model.plugin.LifecycleBindingsInjector;
+import org.apache.maven.model.plugin.PluginConfigurationExpander;
+import org.apache.maven.model.plugin.ReportConfigurationExpander;
+import org.apache.maven.model.plugin.ReportingConverter;
+import org.apache.maven.model.profile.DefaultProfileActivationContext;
+import org.apache.maven.model.profile.ProfileInjector;
+import org.apache.maven.model.profile.ProfileSelector;
+import org.apache.maven.model.resolution.InvalidRepositoryException;
+import org.apache.maven.model.resolution.ModelResolver;
+import org.apache.maven.model.resolution.UnresolvableModelException;
+import org.apache.maven.model.resolution.WorkspaceModelResolver;
+import org.apache.maven.model.superpom.SuperPomProvider;
+import org.apache.maven.model.validation.ModelValidator;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+
+/**
+ * @author Benjamin Bentmann
+ */
+@Component( role = ModelBuilder.class )
+public class DefaultModelBuilder
+ implements ModelBuilder
+{
+ @Requirement
+ private ModelProcessor modelProcessor;
+
+ @Requirement
+ private ModelValidator modelValidator;
+
+ @Requirement
+ private ModelNormalizer modelNormalizer;
+
+ @Requirement
+ private ModelInterpolator modelInterpolator;
+
+ @Requirement
+ private ModelPathTranslator modelPathTranslator;
+
+ @Requirement
+ private ModelUrlNormalizer modelUrlNormalizer;
+
+ @Requirement
+ private SuperPomProvider superPomProvider;
+
+ @Requirement
+ private InheritanceAssembler inheritanceAssembler;
+
+ @Requirement
+ private ProfileSelector profileSelector;
+
+ @Requirement
+ private ProfileInjector profileInjector;
+
+ @Requirement
+ private PluginManagementInjector pluginManagementInjector;
+
+ @Requirement
+ private DependencyManagementInjector dependencyManagementInjector;
+
+ @Requirement
+ private DependencyManagementImporter dependencyManagementImporter;
+
+ @Requirement( optional = true )
+ private LifecycleBindingsInjector lifecycleBindingsInjector;
+
+ @Requirement
+ private PluginConfigurationExpander pluginConfigurationExpander;
+
+ @Requirement
+ private ReportConfigurationExpander reportConfigurationExpander;
+
+ @Requirement
+ private ReportingConverter reportingConverter;
+
+ public DefaultModelBuilder setModelProcessor( ModelProcessor modelProcessor )
+ {
+ this.modelProcessor = modelProcessor;
+ return this;
+ }
+
+ public DefaultModelBuilder setModelValidator( ModelValidator modelValidator )
+ {
+ this.modelValidator = modelValidator;
+ return this;
+ }
+
+ public DefaultModelBuilder setModelNormalizer( ModelNormalizer modelNormalizer )
+ {
+ this.modelNormalizer = modelNormalizer;
+ return this;
+ }
+
+ public DefaultModelBuilder setModelInterpolator( ModelInterpolator modelInterpolator )
+ {
+ this.modelInterpolator = modelInterpolator;
+ return this;
+ }
+
+ public DefaultModelBuilder setModelPathTranslator( ModelPathTranslator modelPathTranslator )
+ {
+ this.modelPathTranslator = modelPathTranslator;
+ return this;
+ }
+
+ public DefaultModelBuilder setModelUrlNormalizer( ModelUrlNormalizer modelUrlNormalizer )
+ {
+ this.modelUrlNormalizer = modelUrlNormalizer;
+ return this;
+ }
+
+ public DefaultModelBuilder setSuperPomProvider( SuperPomProvider superPomProvider )
+ {
+ this.superPomProvider = superPomProvider;
+ return this;
+ }
+
+ public DefaultModelBuilder setProfileSelector( ProfileSelector profileSelector )
+ {
+ this.profileSelector = profileSelector;
+ return this;
+ }
+
+ public DefaultModelBuilder setProfileInjector( ProfileInjector profileInjector )
+ {
+ this.profileInjector = profileInjector;
+ return this;
+ }
+
+ public DefaultModelBuilder setInheritanceAssembler( InheritanceAssembler inheritanceAssembler )
+ {
+ this.inheritanceAssembler = inheritanceAssembler;
+ return this;
+ }
+
+ public DefaultModelBuilder setDependencyManagementImporter( DependencyManagementImporter depMngmntImporter )
+ {
+ this.dependencyManagementImporter = depMngmntImporter;
+ return this;
+ }
+
+ public DefaultModelBuilder setDependencyManagementInjector( DependencyManagementInjector depMngmntInjector )
+ {
+ this.dependencyManagementInjector = depMngmntInjector;
+ return this;
+ }
+
+ public DefaultModelBuilder setLifecycleBindingsInjector( LifecycleBindingsInjector lifecycleBindingsInjector )
+ {
+ this.lifecycleBindingsInjector = lifecycleBindingsInjector;
+ return this;
+ }
+
+ public DefaultModelBuilder setPluginConfigurationExpander( PluginConfigurationExpander pluginConfigurationExpander )
+ {
+ this.pluginConfigurationExpander = pluginConfigurationExpander;
+ return this;
+ }
+
+ public DefaultModelBuilder setPluginManagementInjector( PluginManagementInjector pluginManagementInjector )
+ {
+ this.pluginManagementInjector = pluginManagementInjector;
+ return this;
+ }
+
+ public DefaultModelBuilder setReportConfigurationExpander( ReportConfigurationExpander reportConfigurationExpander )
+ {
+ this.reportConfigurationExpander = reportConfigurationExpander;
+ return this;
+ }
+
+ public DefaultModelBuilder setReportingConverter( ReportingConverter reportingConverter )
+ {
+ this.reportingConverter = reportingConverter;
+ return this;
+ }
+
+ @Override
+ public ModelBuildingResult build( ModelBuildingRequest request )
+ throws ModelBuildingException
+ {
+ // phase 1
+ DefaultModelBuildingResult result = new DefaultModelBuildingResult();
+
+ DefaultModelProblemCollector problems = new DefaultModelProblemCollector( result );
+
+ // profile activation
+ DefaultProfileActivationContext profileActivationContext = getProfileActivationContext( request );
+
+ problems.setSource( "(external profiles)" );
+ List<Profile> activeExternalProfiles = profileSelector.getActiveProfiles( request.getProfiles(),
+ profileActivationContext, problems );
+
+ result.setActiveExternalProfiles( activeExternalProfiles );
+
+ if ( !activeExternalProfiles.isEmpty() )
+ {
+ Properties profileProps = new Properties();
+ for ( Profile profile : activeExternalProfiles )
+ {
+ profileProps.putAll( profile.getProperties() );
+ }
+ profileProps.putAll( profileActivationContext.getUserProperties() );
+ profileActivationContext.setUserProperties( profileProps );
+ }
+
+ // read and validate raw model
+ Model inputModel = request.getRawModel();
+ if ( inputModel == null )
+ {
+ inputModel = readModel( request.getModelSource(), request.getPomFile(), request, problems );
+ }
+
+ problems.setRootModel( inputModel );
+
+ ModelData resultData = new ModelData( request.getModelSource(), inputModel );
+ ModelData superData = new ModelData( null, getSuperModel() );
+
+ Collection<String> parentIds = new LinkedHashSet<String>();
+ List<ModelData> lineage = new ArrayList<ModelData>();
+
+ for ( ModelData currentData = resultData; currentData != null; )
+ {
+ lineage.add( currentData );
+
+ Model rawModel = currentData.getModel();
+ currentData.setRawModel( rawModel );
+
+ Model tmpModel = rawModel.clone();
+ currentData.setModel( tmpModel );
+
+ problems.setSource( tmpModel );
+
+ // model normalization
+ modelNormalizer.mergeDuplicates( tmpModel, request, problems );
+
+ profileActivationContext.setProjectProperties( tmpModel.getProperties() );
+
+ List<Profile> activePomProfiles = profileSelector.getActiveProfiles( rawModel.getProfiles(),
+ profileActivationContext, problems );
+ currentData.setActiveProfiles( activePomProfiles );
+
+ Map<String, Activation> interpolatedActivations = getProfileActivations( rawModel, false );
+ injectProfileActivations( tmpModel, interpolatedActivations );
+
+ // profile injection
+ for ( Profile activeProfile : activePomProfiles )
+ {
+ profileInjector.injectProfile( tmpModel, activeProfile, request, problems );
+ }
+
+ if ( currentData == resultData )
+ {
+ for ( Profile activeProfile : activeExternalProfiles )
+ {
+ profileInjector.injectProfile( tmpModel, activeProfile, request, problems );
+ }
+ }
+
+ if ( currentData == superData )
+ {
+ break;
+ }
+
+ configureResolver( request.getModelResolver(), tmpModel, problems );
+
+ ModelData parentData = readParent( tmpModel, currentData.getSource(), request, problems );
+
+ if ( parentData == null )
+ {
+ currentData = superData;
+ }
+ else if ( currentData == resultData )
+ { // First iteration - add initial parent id after version resolution.
+ currentData.setGroupId( currentData.getRawModel().getGroupId() == null ? parentData.getGroupId()
+ : currentData.getRawModel()
+ .getGroupId() );
+
+ currentData.setVersion( currentData.getRawModel().getVersion() == null ? parentData.getVersion()
+ : currentData.getRawModel()
+ .getVersion() );
+
+ currentData.setArtifactId( currentData.getRawModel().getArtifactId() );
+ parentIds.add( currentData.getId() );
+ // Reset - only needed for 'getId'.
+ currentData.setGroupId( null );
+ currentData.setArtifactId( null );
+ currentData.setVersion( null );
+ currentData = parentData;
+ }
+ else if ( !parentIds.add( parentData.getId() ) )
+ {
+ String message = "The parents form a cycle: ";
+ for ( String modelId : parentIds )
+ {
+ message += modelId + " -> ";
+ }
+ message += parentData.getId();
+
+ problems.add( new ModelProblemCollectorRequest( ModelProblem.Severity.FATAL, ModelProblem.Version.BASE )
+ .setMessage( message ) );
+
+ throw problems.newModelBuildingException();
+ }
+ else
+ {
+ currentData = parentData;
+ }
+ }
+
+ problems.setSource( inputModel );
+ checkPluginVersions( lineage, request, problems );
+
+ // inheritance assembly
+ assembleInheritance( lineage, request, problems );
+
+ Model resultModel = resultData.getModel();
+
+ problems.setSource( resultModel );
+ problems.setRootModel( resultModel );
+
+ // model interpolation
+ resultModel = interpolateModel( resultModel, request, problems );
+ resultData.setModel( resultModel );
+
+ // url normalization
+ modelUrlNormalizer.normalize( resultModel, request );
+
+ // Now the fully interpolated model is available: reconfigure the resolver
+ configureResolver( request.getModelResolver(), resultModel, problems, true );
+
+ resultData.setGroupId( resultModel.getGroupId() );
+ resultData.setArtifactId( resultModel.getArtifactId() );
+ resultData.setVersion( resultModel.getVersion() );
+
+ result.setEffectiveModel( resultModel );
+
+ for ( ModelData currentData : lineage )
+ {
+ String modelId = ( currentData != superData ) ? currentData.getId() : "";
+
+ result.addModelId( modelId );
+ result.setActivePomProfiles( modelId, currentData.getActiveProfiles() );
+ result.setRawModel( modelId, currentData.getRawModel() );
+ }
+
+ if ( !request.isTwoPhaseBuilding() )
+ {
+ build( request, result );
+ }
+
+ return result;
+ }
+
+ @Override
+ public ModelBuildingResult build( ModelBuildingRequest request, ModelBuildingResult result )
+ throws ModelBuildingException
+ {
+ return build( request, result, new LinkedHashSet<String>() );
+ }
+
+ private ModelBuildingResult build( ModelBuildingRequest request, ModelBuildingResult result,
+ Collection<String> imports )
+ throws ModelBuildingException
+ {
+ // phase 2
+ Model resultModel = result.getEffectiveModel();
+
+ DefaultModelProblemCollector problems = new DefaultModelProblemCollector( result );
+ problems.setSource( resultModel );
+ problems.setRootModel( resultModel );
+
+ // model path translation
+ modelPathTranslator.alignToBaseDirectory( resultModel, resultModel.getProjectDirectory(), request );
+
+ // plugin management injection
+ pluginManagementInjector.injectManagement( resultModel, request, problems );
+
+ fireEvent( resultModel, request, problems, ModelBuildingEventCatapult.BUILD_EXTENSIONS_ASSEMBLED );
+
+ if ( request.isProcessPlugins() )
+ {
+ if ( lifecycleBindingsInjector == null )
+ {
+ throw new IllegalStateException( "lifecycle bindings injector is missing" );
+ }
+
+ // lifecycle bindings injection
+ lifecycleBindingsInjector.injectLifecycleBindings( resultModel, request, problems );
+ }
+
+ // dependency management import
+ importDependencyManagement( resultModel, request, problems, imports );
+
+ // dependency management injection
+ dependencyManagementInjector.injectManagement( resultModel, request, problems );
+
+ modelNormalizer.injectDefaultValues( resultModel, request, problems );
+
+ if ( request.isProcessPlugins() )
+ {
+ // reports configuration
+ reportConfigurationExpander.expandPluginConfiguration( resultModel, request, problems );
+
+ // reports conversion to decoupled site plugin
+ reportingConverter.convertReporting( resultModel, request, problems );
+
+ // plugins configuration
+ pluginConfigurationExpander.expandPluginConfiguration( resultModel, request, problems );
+ }
+
+ // effective model validation
+ modelValidator.validateEffectiveModel( resultModel, request, problems );
+
+ if ( hasModelErrors( problems ) )
+ {
+ throw problems.newModelBuildingException();
+ }
+
+ return result;
+ }
+
+ @Override
+ public Result<? extends Model> buildRawModel( File pomFile, int validationLevel, boolean locationTracking )
+ {
+ final ModelBuildingRequest request = new DefaultModelBuildingRequest().setValidationLevel( validationLevel )
+ .setLocationTracking( locationTracking );
+ final DefaultModelProblemCollector collector =
+ new DefaultModelProblemCollector( new DefaultModelBuildingResult() );
+ try
+ {
+ return newResult( readModel( null, pomFile, request, collector ), collector.getProblems() );
+ }
+ catch ( ModelBuildingException e )
+ {
+ return error( collector.getProblems() );
+ }
+ }
+
+ private Model readModel( ModelSource modelSource, File pomFile, ModelBuildingRequest request,
+ DefaultModelProblemCollector problems )
+ throws ModelBuildingException
+ {
+ Model model;
+
+ if ( modelSource == null )
+ {
+ if ( pomFile != null )
+ {
+ modelSource = new FileModelSource( pomFile );
+ }
+ else
+ {
+ throw new IllegalArgumentException( "neither model source nor input file are specified" );
+ }
+ }
+
+ problems.setSource( modelSource.getLocation() );
+ try
+ {
+ boolean strict = request.getValidationLevel() >= ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_2_0;
+ InputSource source = request.isLocationTracking() ? new InputSource() : null;
+
+ Map<String, Object> options = new HashMap<String, Object>();
+ options.put( ModelProcessor.IS_STRICT, strict );
+ options.put( ModelProcessor.INPUT_SOURCE, source );
+ options.put( ModelProcessor.SOURCE, modelSource );
+
+ try
+ {
+ model = modelProcessor.read( modelSource.getInputStream(), options );
+ }
+ catch ( ModelParseException e )
+ {
+ if ( !strict )
+ {
+ throw e;
+ }
+
+ options.put( ModelProcessor.IS_STRICT, Boolean.FALSE );
+
+ try
+ {
+ model = modelProcessor.read( modelSource.getInputStream(), options );
+ }
+ catch ( ModelParseException ne )
+ {
+ // still unreadable even in non-strict mode, rethrow original error
+ throw e;
+ }
+
+ if ( pomFile != null )
+ {
+ problems.add( new ModelProblemCollectorRequest( Severity.ERROR, Version.V20 )
+ .setMessage( "Malformed POM " + modelSource.getLocation() + ": " + e.getMessage() )
+ .setException( e ) );
+ }
+ else
+ {
+ problems.add( new ModelProblemCollectorRequest( Severity.WARNING, Version.V20 )
+ .setMessage( "Malformed POM " + modelSource.getLocation() + ": " + e.getMessage() )
+ .setException( e ) );
+ }
+ }
+
+ if ( source != null )
+ {
+ source.setModelId( ModelProblemUtils.toId( model ) );
+ source.setLocation( modelSource.getLocation() );
+ }
+ }
+ catch ( ModelParseException e )
+ {
+ problems.add( new ModelProblemCollectorRequest( Severity.FATAL, Version.BASE )
+ .setMessage( "Non-parseable POM " + modelSource.getLocation() + ": " + e.getMessage() )
+ .setException( e ) );
+ throw problems.newModelBuildingException();
+ }
+ catch ( IOException e )
+ {
+ String msg = e.getMessage();
+ if ( msg == null || msg.length() <= 0 )
+ {
+ // NOTE: There's java.nio.charset.MalformedInputException and sun.io.MalformedInputException
+ if ( e.getClass().getName().endsWith( "MalformedInputException" ) )
+ {
+ msg = "Some input bytes do not match the file encoding.";
+ }
+ else
+ {
+ msg = e.getClass().getSimpleName();
+ }
+ }
+ problems.add( new ModelProblemCollectorRequest( Severity.FATAL, Version.BASE )
+ .setMessage( "Non-readable POM " + modelSource.getLocation() + ": " + msg ).setException( e ) );
+ throw problems.newModelBuildingException();
+ }
+
+ model.setPomFile( pomFile );
+
+ problems.setSource( model );
+ modelValidator.validateRawModel( model, request, problems );
+
+ if ( hasFatalErrors( problems ) )
+ {
+ throw problems.newModelBuildingException();
+ }
+
+ return model;
+ }
+
+ private DefaultProfileActivationContext getProfileActivationContext( ModelBuildingRequest request )
+ {
+ DefaultProfileActivationContext context = new DefaultProfileActivationContext();
+
+ context.setActiveProfileIds( request.getActiveProfileIds() );
+ context.setInactiveProfileIds( request.getInactiveProfileIds() );
+ context.setSystemProperties( request.getSystemProperties() );
+ context.setUserProperties( request.getUserProperties() );
+ context.setProjectDirectory( ( request.getPomFile() != null ) ? request.getPomFile().getParentFile() : null );
+
+ return context;
+ }
+
+ private void configureResolver( ModelResolver modelResolver, Model model, DefaultModelProblemCollector problems )
+ {
+ configureResolver( modelResolver, model, problems, false );
+ }
+
+ private void configureResolver( ModelResolver modelResolver, Model model, DefaultModelProblemCollector problems,
+ boolean replaceRepositories )
+ {
+ if ( modelResolver == null )
+ {
+ return;
+ }
+
+ problems.setSource( model );
+
+ List<Repository> repositories = model.getRepositories();
+
+ for ( Repository repository : repositories )
+ {
+ try
+ {
+ modelResolver.addRepository( repository, replaceRepositories );
+ }
+ catch ( InvalidRepositoryException e )
+ {
+ problems.add( new ModelProblemCollectorRequest( Severity.ERROR, Version.BASE )
+ .setMessage( "Invalid repository " + repository.getId() + ": " + e.getMessage() )
+ .setLocation( repository.getLocation( "" ) ).setException( e ) );
+ }
+ }
+ }
+
+ private void checkPluginVersions( List<ModelData> lineage, ModelBuildingRequest request,
+ ModelProblemCollector problems )
+ {
+ if ( request.getValidationLevel() < ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_2_0 )
+ {
+ return;
+ }
+
+ Map<String, Plugin> plugins = new HashMap<String, Plugin>();
+ Map<String, String> versions = new HashMap<String, String>();
+ Map<String, String> managedVersions = new HashMap<String, String>();
+
+ for ( int i = lineage.size() - 1; i >= 0; i-- )
+ {
+ Model model = lineage.get( i ).getModel();
+ Build build = model.getBuild();
+ if ( build != null )
+ {
+ for ( Plugin plugin : build.getPlugins() )
+ {
+ String key = plugin.getKey();
+ if ( versions.get( key ) == null )
+ {
+ versions.put( key, plugin.getVersion() );
+ plugins.put( key, plugin );
+ }
+ }
+ PluginManagement mngt = build.getPluginManagement();
+ if ( mngt != null )
+ {
+ for ( Plugin plugin : mngt.getPlugins() )
+ {
+ String key = plugin.getKey();
+ if ( managedVersions.get( key ) == null )
+ {
+ managedVersions.put( key, plugin.getVersion() );
+ }
+ }
+ }
+ }
+ }
+
+ for ( String key : versions.keySet() )
+ {
+ if ( versions.get( key ) == null && managedVersions.get( key ) == null )
+ {
+ InputLocation location = plugins.get( key ).getLocation( "" );
+ problems
+ .add( new ModelProblemCollectorRequest( Severity.WARNING, Version.V20 )
+ .setMessage( "'build.plugins.plugin.version' for " + key + " is missing." )
+ .setLocation( location ) );
+ }
+ }
+ }
+
+ private void assembleInheritance( List<ModelData> lineage, ModelBuildingRequest request,
+ ModelProblemCollector problems )
+ {
+ for ( int i = lineage.size() - 2; i >= 0; i-- )
+ {
+ Model parent = lineage.get( i + 1 ).getModel();
+ Model child = lineage.get( i ).getModel();
+ inheritanceAssembler.assembleModelInheritance( child, parent, request, problems );
+ }
+ }
+
+ private Map<String, Activation> getProfileActivations( Model model, boolean clone )
+ {
+ Map<String, Activation> activations = new HashMap<String, Activation>();
+ for ( Profile profile : model.getProfiles() )
+ {
+ Activation activation = profile.getActivation();
+
+ if ( activation == null )
+ {
+ continue;
+ }
+
+ if ( clone )
+ {
+ activation = activation.clone();
+ }
+
+ activations.put( profile.getId(), activation );
+ }
+
+ return activations;
+ }
+
+ private void injectProfileActivations( Model model, Map<String, Activation> activations )
+ {
+ for ( Profile profile : model.getProfiles() )
+ {
+ Activation activation = profile.getActivation();
+
+ if ( activation == null )
+ {
+ continue;
+ }
+
+ // restore activation
+ profile.setActivation( activations.get( profile.getId() ) );
+ }
+ }
+
+ private Model interpolateModel( Model model, ModelBuildingRequest request, ModelProblemCollector problems )
+ {
+ // save profile activations before interpolation, since they are evaluated with limited scope
+ Map<String, Activation> originalActivations = getProfileActivations( model, true );
+
+ Model result = modelInterpolator.interpolateModel( model, model.getProjectDirectory(), request, problems );
+ result.setPomFile( model.getPomFile() );
+
+ // restore profiles with file activation to their value before full interpolation
+ injectProfileActivations( model, originalActivations );
+
+ return result;
+ }
+
+ private ModelData readParent( Model childModel, ModelSource childSource, ModelBuildingRequest request,
+ DefaultModelProblemCollector problems )
+ throws ModelBuildingException
+ {
+ ModelData parentData;
+
+ Parent parent = childModel.getParent();
+
+ if ( parent != null )
+ {
+ String groupId = parent.getGroupId();
+ String artifactId = parent.getArtifactId();
+ String version = parent.getVersion();
+
+ parentData = getCache( request.getModelCache(), groupId, artifactId, version, ModelCacheTag.RAW );
+
+ if ( parentData == null )
+ {
+ parentData = readParentLocally( childModel, childSource, request, problems );
+
+ if ( parentData == null )
+ {
+ parentData = readParentExternally( childModel, request, problems );
+ }
+
+ putCache( request.getModelCache(), groupId, artifactId, version, ModelCacheTag.RAW, parentData );
+ }
+ else
+ {
+ /*
+ * NOTE: This is a sanity check of the cache hit. If the cached parent POM was locally resolved, the
+ * child's <relativePath> should point at that parent, too. If it doesn't, we ignore the cache and
+ * resolve externally, to mimic the behavior if the cache didn't exist in the first place. Otherwise,
+ * the cache would obscure a bad POM.
+ */
+
+ File pomFile = parentData.getModel().getPomFile();
+ if ( pomFile != null )
+ {
+ ModelSource expectedParentSource = getParentPomFile( childModel, childSource );
+
+ if ( expectedParentSource instanceof ModelSource2
+ && !pomFile.toURI().equals( ( (ModelSource2) expectedParentSource ).getLocationURI() ) )
+ {
+ parentData = readParentExternally( childModel, request, problems );
+ }
+ }
+ }
+
+ Model parentModel = parentData.getModel();
+
+ if ( !"pom".equals( parentModel.getPackaging() ) )
+ {
+ problems.add( new ModelProblemCollectorRequest( Severity.ERROR, Version.BASE )
+ .setMessage( "Invalid packaging for parent POM " + ModelProblemUtils.toSourceHint( parentModel )
+ + ", must be \"pom\" but is \"" + parentModel.getPackaging() + "\"" )
+ .setLocation( parentModel.getLocation( "packaging" ) ) );
+ }
+ }
+ else
+ {
+ parentData = null;
+ }
+
+ return parentData;
+ }
+
+ private ModelData readParentLocally( Model childModel, ModelSource childSource, ModelBuildingRequest request,
+ DefaultModelProblemCollector problems )
+ throws ModelBuildingException
+ {
+ final Parent parent = childModel.getParent();
+ final ModelSource candidateSource;
+ final Model candidateModel;
+ final WorkspaceModelResolver resolver = request.getWorkspaceModelResolver();
+ if ( resolver == null )
+ {
+ candidateSource = getParentPomFile( childModel, childSource );
+
+ if ( candidateSource == null )
+ {
+ return null;
+ }
+
+ File pomFile = null;
+ if ( candidateSource instanceof FileModelSource )
+ {
+ pomFile = ( (FileModelSource) candidateSource ).getPomFile();
+ }
+
+ candidateModel = readModel( candidateSource, pomFile, request, problems );
+ }
+ else
+ {
+ try
+ {
+ candidateModel =
+ resolver.resolveRawModel( parent.getGroupId(), parent.getArtifactId(), parent.getVersion() );
+ }
+ catch ( UnresolvableModelException e )
+ {
+ problems.add( new ModelProblemCollectorRequest( Severity.FATAL, Version.BASE ) //
+ .setMessage( e.getMessage().toString() ).setLocation( parent.getLocation( "" ) ).setException( e ) );
+ throw problems.newModelBuildingException();
+ }
+ if ( candidateModel == null )
+ {
+ return null;
+ }
+ candidateSource = new FileModelSource( candidateModel.getPomFile() );
+ }
+
+ //
+ // TODO:jvz Why isn't all this checking the job of the duty of the workspace resolver, we know that we
+ // have a model that is suitable, yet more checks are done here and the one for the version is problematic
+ // before because with parents as ranges it will never work in this scenario.
+ //
+
+ String groupId = candidateModel.getGroupId();
+ if ( groupId == null && candidateModel.getParent() != null )
+ {
+ groupId = candidateModel.getParent().getGroupId();
+ }
+ String artifactId = candidateModel.getArtifactId();
+ String version = candidateModel.getVersion();
+ if ( version == null && candidateModel.getParent() != null )
+ {
+ version = candidateModel.getParent().getVersion();
+ }
+
+ if ( groupId == null || !groupId.equals( parent.getGroupId() ) || artifactId == null
+ || !artifactId.equals( parent.getArtifactId() ) )
+ {
+ StringBuilder buffer = new StringBuilder( 256 );
+ buffer.append( "'parent.relativePath'" );
+ if ( childModel != problems.getRootModel() )
+ {
+ buffer.append( " of POM " ).append( ModelProblemUtils.toSourceHint( childModel ) );
+ }
+ buffer.append( " points at " ).append( groupId ).append( ":" ).append( artifactId );
+ buffer.append( " instead of " ).append( parent.getGroupId() ).append( ":" );
+ buffer.append( parent.getArtifactId() ).append( ", please verify your project structure" );
+
+ problems.setSource( childModel );
+ problems.add( new ModelProblemCollectorRequest( Severity.WARNING, Version.BASE )
+ .setMessage( buffer.toString() ).setLocation( parent.getLocation( "" ) ) );
+ return null;
+ }
+
+ //
+ // Here we just need to know that a version is fine to use but this validation we can do in our workspace
+ // resolver.
+ //
+
+ /*
+ * if ( version == null || !version.equals( parent.getVersion() ) ) { return null; }
+ */
+
+ ModelData parentData = new ModelData( candidateSource, candidateModel, groupId, artifactId, version );
+
+ return parentData;
+ }
+
+ private ModelSource getParentPomFile( Model childModel, ModelSource source )
+ {
+ if ( !( source instanceof ModelSource2 ) )
+ {
+ return null;
+ }
+
+ String parentPath = childModel.getParent().getRelativePath();
+
+ if ( parentPath == null || parentPath.length() <= 0 )
+ {
+ return null;
+ }
+
+ return ( (ModelSource2) source ).getRelatedSource( parentPath );
+ }
+
+ private ModelData readParentExternally( Model childModel, ModelBuildingRequest request,
+ DefaultModelProblemCollector problems )
+ throws ModelBuildingException
+ {
+ problems.setSource( childModel );
+
+ Parent parent = childModel.getParent().clone();
+
+ String groupId = parent.getGroupId();
+ String artifactId = parent.getArtifactId();
+ String version = parent.getVersion();
+
+ ModelResolver modelResolver = request.getModelResolver();
+
+ if ( modelResolver == null )
+ {
+ throw new IllegalArgumentException( "no model resolver provided, cannot resolve parent POM "
+ + ModelProblemUtils.toId( groupId, artifactId, version ) + " for POM "
+ + ModelProblemUtils.toSourceHint( childModel ) );
+ }
+
+ ModelSource modelSource;
+ try
+ {
+ modelSource = modelResolver.resolveModel( parent );
+ }
+ catch ( UnresolvableModelException e )
+ {
+ StringBuilder buffer = new StringBuilder( 256 );
+ buffer.append( "Non-resolvable parent POM" );
+ if ( !containsCoordinates( e.getMessage(), groupId, artifactId, version ) )
+ {
+ buffer.append( " " ).append( ModelProblemUtils.toId( groupId, artifactId, version ) );
+ }
+ if ( childModel != problems.getRootModel() )
+ {
+ buffer.append( " for " ).append( ModelProblemUtils.toId( childModel ) );
+ }
+ buffer.append( ": " ).append( e.getMessage() );
+ if ( childModel.getProjectDirectory() != null )
+ {
+ if ( parent.getRelativePath() == null || parent.getRelativePath().length() <= 0 )
+ {
+ buffer.append( " and 'parent.relativePath' points at no local POM" );
+ }
+ else
+ {
+ buffer.append( " and 'parent.relativePath' points at wrong local POM" );
+ }
+ }
+
+ problems.add( new ModelProblemCollectorRequest( Severity.FATAL, Version.BASE )
+ .setMessage( buffer.toString() ).setLocation( parent.getLocation( "" ) ).setException( e ) );
+ throw problems.newModelBuildingException();
+ }
+
+ ModelBuildingRequest lenientRequest = request;
+ if ( request.getValidationLevel() > ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_2_0 )
+ {
+ lenientRequest = new FilterModelBuildingRequest( request )
+ {
+ @Override
+ public int getValidationLevel()
+ {
+ return ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_2_0;
+ }
+ };
+ }
+
+ Model parentModel = readModel( modelSource, null, lenientRequest, problems );
+
+ if ( !parent.getVersion().equals( version ) )
+ {
+ if ( childModel.getVersion() == null )
+ {
+ problems.add( new ModelProblemCollectorRequest( Severity.FATAL, Version.V31 )
+ .setMessage( "Version must be a constant" ).setLocation( childModel.getLocation( "" ) ) );
+
+ }
+ else
+ {
+ if ( childModel.getVersion().indexOf( "${" ) > -1 )
+ {
+ problems.add( new ModelProblemCollectorRequest( Severity.FATAL, Version.V31 )
+ .setMessage( "Version must be a constant" )
+ .setLocation( childModel.getLocation( "version" ) ) );
+
+ }
+ }
+
+ // MNG-2199: What else to check here ?
+ }
+
+ ModelData parentData = new ModelData( modelSource, parentModel, parent.getGroupId(), parent.getArtifactId(),
+ parent.getVersion() );
+
+ return parentData;
+ }
+
+ private Model getSuperModel()
+ {
+ return superPomProvider.getSuperModel( "4.0.0" ).clone();
+ }
+
+ private void importDependencyManagement( Model model, ModelBuildingRequest request,
+ DefaultModelProblemCollector problems, Collection<String> importIds )
+ {
+ DependencyManagement depMngt = model.getDependencyManagement();
+
+ if ( depMngt == null )
+ {
+ return;
+ }
+
+ String importing = model.getGroupId() + ':' + model.getArtifactId() + ':' + model.getVersion();
+
+ importIds.add( importing );
+
+ final WorkspaceModelResolver workspaceResolver = request.getWorkspaceModelResolver();
+ final ModelResolver modelResolver = request.getModelResolver();
+
+ ModelBuildingRequest importRequest = null;
+
+ List<DependencyManagement> importMngts = null;
+
+ for ( Iterator<Dependency> it = depMngt.getDependencies().iterator(); it.hasNext(); )
+ {
+ Dependency dependency = it.next();
+
+ if ( !"pom".equals( dependency.getType() ) || !"import".equals( dependency.getScope() ) )
+ {
+ continue;
+ }
+
+ it.remove();
+
+ String groupId = dependency.getGroupId();
+ String artifactId = dependency.getArtifactId();
+ String version = dependency.getVersion();
+
+ if ( groupId == null || groupId.length() <= 0 )
+ {
+ problems.add( new ModelProblemCollectorRequest( Severity.ERROR, Version.BASE )
+ .setMessage( "'dependencyManagement.dependencies.dependency.groupId' for "
+ + dependency.getManagementKey() + " is missing." )
+ .setLocation( dependency.getLocation( "" ) ) );
+ continue;
+ }
+ if ( artifactId == null || artifactId.length() <= 0 )
+ {
+ problems.add( new ModelProblemCollectorRequest( Severity.ERROR, Version.BASE )
+ .setMessage( "'dependencyManagement.dependencies.dependency.artifactId' for "
+ + dependency.getManagementKey() + " is missing." )
+ .setLocation( dependency.getLocation( "" ) ) );
+ continue;
+ }
+ if ( version == null || version.length() <= 0 )
+ {
+ problems.add( new ModelProblemCollectorRequest( Severity.ERROR, Version.BASE )
+ .setMessage( "'dependencyManagement.dependencies.dependency.version' for "
+ + dependency.getManagementKey() + " is missing." )
+ .setLocation( dependency.getLocation( "" ) ) );
+ continue;
+ }
+
+ String imported = groupId + ':' + artifactId + ':' + version;
+
+ if ( importIds.contains( imported ) )
+ {
+ String message = "The dependencies of type=pom and with scope=import form a cycle: ";
+ for ( String modelId : importIds )
+ {
+ message += modelId + " -> ";
+ }
+ message += imported;
+ problems.add( new ModelProblemCollectorRequest( Severity.ERROR, Version.BASE ).setMessage( message ) );
+
+ continue;
+ }
+
+ DependencyManagement importMngt = getCache( request.getModelCache(), groupId, artifactId, version,
+ ModelCacheTag.IMPORT );
+
+ if ( importMngt == null )
+ {
+ if ( workspaceResolver == null && modelResolver == null )
+ {
+ throw new IllegalArgumentException( "no model resolver provided, cannot resolve import POM "
+ + ModelProblemUtils.toId( groupId, artifactId, version ) + " for POM "
+ + ModelProblemUtils.toSourceHint( model ) );
+ }
+
+ Model importModel = null;
+ if ( workspaceResolver != null )
+ {
+ try
+ {
+ importModel = workspaceResolver.resolveEffectiveModel( groupId, artifactId, version );
+ }
+ catch ( UnresolvableModelException e )
+ {
+ problems.add( new ModelProblemCollectorRequest( Severity.FATAL, Version.BASE )
+ .setMessage( e.getMessage().toString() ).setException( e ) );
+ continue;
+ }
+ }
+
+ // no workspace resolver or workspace resolver returned null (i.e. model not in workspace)
+ if ( importModel == null )
+ {
+ final ModelSource importSource;
+ try
+ {
+ importSource = modelResolver.resolveModel( groupId, artifactId, version );
+ }
+ catch ( UnresolvableModelException e )
+ {
+ StringBuilder buffer = new StringBuilder( 256 );
+ buffer.append( "Non-resolvable import POM" );
+ if ( !containsCoordinates( e.getMessage(), groupId, artifactId, version ) )
+ {
+ buffer.append( " " ).append( ModelProblemUtils.toId( groupId, artifactId, version ) );
+ }
+ buffer.append( ": " ).append( e.getMessage() );
+
+ problems.add( new ModelProblemCollectorRequest( Severity.ERROR, Version.BASE )
+ .setMessage( buffer.toString() ).setLocation( dependency.getLocation( "" ) )
+ .setException( e ) );
+ continue;
+ }
+
+ if ( importRequest == null )
+ {
+ importRequest = new DefaultModelBuildingRequest();
+ importRequest.setValidationLevel( ModelBuildingRequest.VALIDATION_LEVEL_MINIMAL );
+ importRequest.setModelCache( request.getModelCache() );
+ importRequest.setSystemProperties( request.getSystemProperties() );
+ importRequest.setUserProperties( request.getUserProperties() );
+ importRequest.setLocationTracking( request.isLocationTracking() );
+ }
+
+ importRequest.setModelSource( importSource );
+ importRequest.setModelResolver( modelResolver.newCopy() );
+
+ final ModelBuildingResult importResult;
+ try
+ {
+ importResult = build( importRequest );
+ }
+ catch ( ModelBuildingException e )
+ {
+ problems.addAll( e.getProblems() );
+ continue;
+ }
+
+ problems.addAll( importResult.getProblems() );
+
+ importModel = importResult.getEffectiveModel();
+ }
+
+ importMngt = importModel.getDependencyManagement();
+
+ if ( importMngt == null )
+ {
+ importMngt = new DependencyManagement();
+ }
+
+ putCache( request.getModelCache(), groupId, artifactId, version, ModelCacheTag.IMPORT, importMngt );
+ }
+
+ if ( importMngts == null )
+ {
+ importMngts = new ArrayList<DependencyManagement>();
+ }
+
+ importMngts.add( importMngt );
+ }
+
+ importIds.remove( importing );
+
+ dependencyManagementImporter.importManagement( model, importMngts, request, problems );
+ }
+
+ private <T> void putCache( ModelCache modelCache, String groupId, String artifactId, String version,
+ ModelCacheTag<T> tag, T data )
+ {
+ if ( modelCache != null )
+ {
+ modelCache.put( groupId, artifactId, version, tag.getName(), tag.intoCache( data ) );
+ }
+ }
+
+ private <T> T getCache( ModelCache modelCache, String groupId, String artifactId, String version,
+ ModelCacheTag<T> tag )
+ {
+ if ( modelCache != null )
+ {
+ Object data = modelCache.get( groupId, artifactId, version, tag.getName() );
+ if ( data != null )
+ {
+ return tag.fromCache( tag.getType().cast( data ) );
+ }
+ }
+ return null;
+ }
+
+ private void fireEvent( Model model, ModelBuildingRequest request, ModelProblemCollector problems,
+ ModelBuildingEventCatapult catapult )
+ throws ModelBuildingException
+ {
+ ModelBuildingListener listener = request.getModelBuildingListener();
+
+ if ( listener != null )
+ {
+ ModelBuildingEvent event = new DefaultModelBuildingEvent( model, request, problems );
+
+ catapult.fire( listener, event );
+ }
+ }
+
+ private boolean containsCoordinates( String message, String groupId, String artifactId, String version )
+ {
+ return message != null && ( groupId == null || message.contains( groupId ) )
+ && ( artifactId == null || message.contains( artifactId ) )
+ && ( version == null || message.contains( version ) );
+ }
+
+ protected boolean hasModelErrors( ModelProblemCollectorExt problems )
+ {
+ if ( problems instanceof DefaultModelProblemCollector )
+ {
+ return ( (DefaultModelProblemCollector) problems ).hasErrors();
+ }
+ else
+ {
+ // the default execution path only knows the DefaultModelProblemCollector,
+ // only reason it's not in signature is because it's package private
+ throw new IllegalStateException();
+ }
+ }
+
+ protected boolean hasFatalErrors( ModelProblemCollectorExt problems )
+ {
+ if ( problems instanceof DefaultModelProblemCollector )
+ {
+ return ( (DefaultModelProblemCollector) problems ).hasFatalErrors();
+ }
+ else
+ {
+ // the default execution path only knows the DefaultModelProblemCollector,
+ // only reason it's not in signature is because it's package private
+ throw new IllegalStateException();
+ }
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuilderFactory.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuilderFactory.java
new file mode 100644
index 00000000..36a0f46a
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuilderFactory.java
@@ -0,0 +1,243 @@
+package org.apache.maven.model.building;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.model.Model;
+import org.apache.maven.model.composition.DefaultDependencyManagementImporter;
+import org.apache.maven.model.composition.DependencyManagementImporter;
+import org.apache.maven.model.inheritance.DefaultInheritanceAssembler;
+import org.apache.maven.model.inheritance.InheritanceAssembler;
+import org.apache.maven.model.interpolation.ModelInterpolator;
+import org.apache.maven.model.interpolation.StringSearchModelInterpolator;
+import org.apache.maven.model.io.DefaultModelReader;
+import org.apache.maven.model.io.ModelReader;
+import org.apache.maven.model.locator.DefaultModelLocator;
+import org.apache.maven.model.locator.ModelLocator;
+import org.apache.maven.model.management.DefaultDependencyManagementInjector;
+import org.apache.maven.model.management.DefaultPluginManagementInjector;
+import org.apache.maven.model.management.DependencyManagementInjector;
+import org.apache.maven.model.management.PluginManagementInjector;
+import org.apache.maven.model.normalization.DefaultModelNormalizer;
+import org.apache.maven.model.normalization.ModelNormalizer;
+import org.apache.maven.model.path.DefaultModelPathTranslator;
+import org.apache.maven.model.path.DefaultModelUrlNormalizer;
+import org.apache.maven.model.path.DefaultPathTranslator;
+import org.apache.maven.model.path.DefaultUrlNormalizer;
+import org.apache.maven.model.path.ModelPathTranslator;
+import org.apache.maven.model.path.ModelUrlNormalizer;
+import org.apache.maven.model.path.PathTranslator;
+import org.apache.maven.model.path.UrlNormalizer;
+import org.apache.maven.model.plugin.DefaultPluginConfigurationExpander;
+import org.apache.maven.model.plugin.DefaultReportConfigurationExpander;
+import org.apache.maven.model.plugin.DefaultReportingConverter;
+import org.apache.maven.model.plugin.LifecycleBindingsInjector;
+import org.apache.maven.model.plugin.PluginConfigurationExpander;
+import org.apache.maven.model.plugin.ReportConfigurationExpander;
+import org.apache.maven.model.plugin.ReportingConverter;
+import org.apache.maven.model.profile.DefaultProfileInjector;
+import org.apache.maven.model.profile.DefaultProfileSelector;
+import org.apache.maven.model.profile.ProfileInjector;
+import org.apache.maven.model.profile.ProfileSelector;
+import org.apache.maven.model.profile.activation.FileProfileActivator;
+import org.apache.maven.model.profile.activation.JdkVersionProfileActivator;
+import org.apache.maven.model.profile.activation.OperatingSystemProfileActivator;
+import org.apache.maven.model.profile.activation.ProfileActivator;
+import org.apache.maven.model.profile.activation.PropertyProfileActivator;
+import org.apache.maven.model.superpom.DefaultSuperPomProvider;
+import org.apache.maven.model.superpom.SuperPomProvider;
+import org.apache.maven.model.validation.DefaultModelValidator;
+import org.apache.maven.model.validation.ModelValidator;
+
+/**
+ * A factory to create model builder instances when no dependency injection is available. <em>Note:</em> This class is
+ * only meant as a utility for developers that want to employ the model builder outside of the Maven build system, Maven
+ * plugins should always acquire model builder instances via dependency injection. Developers might want to subclass
+ * this factory to provide custom implementations for some of the components used by the model builder.
+ *
+ * @author Benjamin Bentmann
+ */
+public class DefaultModelBuilderFactory
+{
+
+ protected ModelProcessor newModelProcessor()
+ {
+ DefaultModelProcessor processor = new DefaultModelProcessor();
+ processor.setModelLocator( newModelLocator() );
+ processor.setModelReader( newModelReader() );
+ return processor;
+ }
+
+ protected ModelLocator newModelLocator()
+ {
+ return new DefaultModelLocator();
+ }
+
+ protected ModelReader newModelReader()
+ {
+ return new DefaultModelReader();
+ }
+
+ protected ProfileSelector newProfileSelector()
+ {
+ DefaultProfileSelector profileSelector = new DefaultProfileSelector();
+
+ for ( ProfileActivator activator : newProfileActivators() )
+ {
+ profileSelector.addProfileActivator( activator );
+ }
+
+ return profileSelector;
+ }
+
+ protected ProfileActivator[] newProfileActivators()
+ {
+ return new ProfileActivator[] { new JdkVersionProfileActivator(), new OperatingSystemProfileActivator(),
+ new PropertyProfileActivator(), new FileProfileActivator().setPathTranslator( newPathTranslator() ) };
+ }
+
+ protected UrlNormalizer newUrlNormalizer()
+ {
+ return new DefaultUrlNormalizer();
+ }
+
+ protected PathTranslator newPathTranslator()
+ {
+ return new DefaultPathTranslator();
+ }
+
+ protected ModelInterpolator newModelInterpolator()
+ {
+ UrlNormalizer normalizer = newUrlNormalizer();
+ PathTranslator pathTranslator = newPathTranslator();
+ return new StringSearchModelInterpolator().setPathTranslator( pathTranslator ).setUrlNormalizer( normalizer );
+ }
+
+ protected ModelValidator newModelValidator()
+ {
+ return new DefaultModelValidator();
+ }
+
+ protected ModelNormalizer newModelNormalizer()
+ {
+ return new DefaultModelNormalizer();
+ }
+
+ protected ModelPathTranslator newModelPathTranslator()
+ {
+ return new DefaultModelPathTranslator().setPathTranslator( newPathTranslator() );
+ }
+
+ protected ModelUrlNormalizer newModelUrlNormalizer()
+ {
+ return new DefaultModelUrlNormalizer().setUrlNormalizer( newUrlNormalizer() );
+ }
+
+ protected InheritanceAssembler newInheritanceAssembler()
+ {
+ return new DefaultInheritanceAssembler();
+ }
+
+ protected ProfileInjector newProfileInjector()
+ {
+ return new DefaultProfileInjector();
+ }
+
+ protected SuperPomProvider newSuperPomProvider()
+ {
+ return new DefaultSuperPomProvider().setModelProcessor( newModelProcessor() );
+ }
+
+ protected DependencyManagementImporter newDependencyManagementImporter()
+ {
+ return new DefaultDependencyManagementImporter();
+ }
+
+ protected DependencyManagementInjector newDependencyManagementInjector()
+ {
+ return new DefaultDependencyManagementInjector();
+ }
+
+ protected LifecycleBindingsInjector newLifecycleBindingsInjector()
+ {
+ return new StubLifecycleBindingsInjector();
+ }
+
+ protected PluginManagementInjector newPluginManagementInjector()
+ {
+ return new DefaultPluginManagementInjector();
+ }
+
+ protected PluginConfigurationExpander newPluginConfigurationExpander()
+ {
+ return new DefaultPluginConfigurationExpander();
+ }
+
+ protected ReportConfigurationExpander newReportConfigurationExpander()
+ {
+ return new DefaultReportConfigurationExpander();
+ }
+
+ protected ReportingConverter newReportingConverter()
+ {
+ return new DefaultReportingConverter();
+ }
+
+ /**
+ * Creates a new model builder instance.
+ *
+ * @return The new model builder instance, never {@code null}.
+ */
+ public DefaultModelBuilder newInstance()
+ {
+ DefaultModelBuilder modelBuilder = new DefaultModelBuilder();
+
+ modelBuilder.setModelProcessor( newModelProcessor() );
+ modelBuilder.setModelValidator( newModelValidator() );
+ modelBuilder.setModelNormalizer( newModelNormalizer() );
+ modelBuilder.setModelPathTranslator( newModelPathTranslator() );
+ modelBuilder.setModelUrlNormalizer( newModelUrlNormalizer() );
+ modelBuilder.setModelInterpolator( newModelInterpolator() );
+ modelBuilder.setInheritanceAssembler( newInheritanceAssembler() );
+ modelBuilder.setProfileInjector( newProfileInjector() );
+ modelBuilder.setProfileSelector( newProfileSelector() );
+ modelBuilder.setSuperPomProvider( newSuperPomProvider() );
+ modelBuilder.setDependencyManagementImporter( newDependencyManagementImporter() );
+ modelBuilder.setDependencyManagementInjector( newDependencyManagementInjector() );
+ modelBuilder.setLifecycleBindingsInjector( newLifecycleBindingsInjector() );
+ modelBuilder.setPluginManagementInjector( newPluginManagementInjector() );
+ modelBuilder.setPluginConfigurationExpander( newPluginConfigurationExpander() );
+ modelBuilder.setReportConfigurationExpander( newReportConfigurationExpander() );
+ modelBuilder.setReportingConverter( newReportingConverter() );
+
+ return modelBuilder;
+ }
+
+ private static class StubLifecycleBindingsInjector
+ implements LifecycleBindingsInjector
+ {
+
+ @Override
+ public void injectLifecycleBindings( Model model, ModelBuildingRequest request, ModelProblemCollector problems )
+ {
+ }
+
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuildingEvent.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuildingEvent.java
new file mode 100644
index 00000000..f72403b2
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuildingEvent.java
@@ -0,0 +1,64 @@
+package org.apache.maven.model.building;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.model.Model;
+
+/**
+ * Holds data relevant for a model building event.
+ *
+ * @author Benjamin Bentmann
+ */
+class DefaultModelBuildingEvent
+ implements ModelBuildingEvent
+{
+
+ private final Model model;
+
+ private final ModelBuildingRequest request;
+
+ private final ModelProblemCollector problems;
+
+ public DefaultModelBuildingEvent( Model model, ModelBuildingRequest request, ModelProblemCollector problems )
+ {
+ this.model = model;
+ this.request = request;
+ this.problems = problems;
+ }
+
+ @Override
+ public Model getModel()
+ {
+ return model;
+ }
+
+ @Override
+ public ModelBuildingRequest getRequest()
+ {
+ return request;
+ }
+
+ @Override
+ public ModelProblemCollector getProblems()
+ {
+ return problems;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuildingRequest.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuildingRequest.java
new file mode 100644
index 00000000..8b4a01b3
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuildingRequest.java
@@ -0,0 +1,408 @@
+package org.apache.maven.model.building;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Properties;
+
+import org.apache.maven.model.Model;
+import org.apache.maven.model.Profile;
+import org.apache.maven.model.resolution.ModelResolver;
+import org.apache.maven.model.resolution.WorkspaceModelResolver;
+
+/**
+ * Collects settings that control building of effective models.
+ *
+ * @author Benjamin Bentmann
+ */
+public class DefaultModelBuildingRequest
+ implements ModelBuildingRequest
+{
+
+ private Model rawModel;
+
+ private File pomFile;
+
+ private ModelSource modelSource;
+
+ private int validationLevel = VALIDATION_LEVEL_STRICT;
+
+ private boolean processPlugins;
+
+ private boolean twoPhaseBuilding;
+
+ private boolean locationTracking;
+
+ private List<Profile> profiles;
+
+ private List<String> activeProfileIds;
+
+ private List<String> inactiveProfileIds;
+
+ private Properties systemProperties;
+
+ private Properties userProperties;
+
+ private Date buildStartTime;
+
+ private ModelResolver modelResolver;
+
+ private ModelBuildingListener modelBuildingListener;
+
+ private ModelCache modelCache;
+
+ private WorkspaceModelResolver workspaceResolver;
+
+ /**
+ * Creates an empty request.
+ */
+ public DefaultModelBuildingRequest()
+ {
+ }
+
+ /**
+ * Creates a shallow copy of the specified request.
+ *
+ * @param request The request to copy, must not be {@code null}.
+ */
+ public DefaultModelBuildingRequest( ModelBuildingRequest request )
+ {
+ setPomFile( request.getPomFile() );
+ setModelSource( request.getModelSource() );
+ setValidationLevel( request.getValidationLevel() );
+ setProcessPlugins( request.isProcessPlugins() );
+ setTwoPhaseBuilding( request.isTwoPhaseBuilding() );
+ setProfiles( request.getProfiles() );
+ setActiveProfileIds( request.getActiveProfileIds() );
+ setInactiveProfileIds( request.getInactiveProfileIds() );
+ setSystemProperties( request.getSystemProperties() );
+ setUserProperties( request.getUserProperties() );
+ setBuildStartTime( request.getBuildStartTime() );
+ setModelResolver( request.getModelResolver() );
+ setModelBuildingListener( request.getModelBuildingListener() );
+ setModelCache( request.getModelCache() );
+ }
+
+ @Override
+ public File getPomFile()
+ {
+ return pomFile;
+ }
+
+ @Override
+ public DefaultModelBuildingRequest setPomFile( File pomFile )
+ {
+ this.pomFile = ( pomFile != null ) ? pomFile.getAbsoluteFile() : null;
+
+ return this;
+ }
+
+ @Override
+ public synchronized ModelSource getModelSource()
+ {
+ if ( modelSource == null && pomFile != null )
+ {
+ modelSource = new FileModelSource( pomFile );
+ }
+ return modelSource;
+ }
+
+ @Override
+ public DefaultModelBuildingRequest setModelSource( ModelSource modelSource )
+ {
+ this.modelSource = modelSource;
+
+ return this;
+ }
+
+ @Override
+ public int getValidationLevel()
+ {
+ return validationLevel;
+ }
+
+ @Override
+ public DefaultModelBuildingRequest setValidationLevel( int validationLevel )
+ {
+ this.validationLevel = validationLevel;
+
+ return this;
+ }
+
+ @Override
+ public boolean isProcessPlugins()
+ {
+ return processPlugins;
+ }
+
+ @Override
+ public DefaultModelBuildingRequest setProcessPlugins( boolean processPlugins )
+ {
+ this.processPlugins = processPlugins;
+
+ return this;
+ }
+
+ @Override
+ public boolean isTwoPhaseBuilding()
+ {
+ return twoPhaseBuilding;
+ }
+
+ @Override
+ public DefaultModelBuildingRequest setTwoPhaseBuilding( boolean twoPhaseBuilding )
+ {
+ this.twoPhaseBuilding = twoPhaseBuilding;
+
+ return this;
+ }
+
+ @Override
+ public boolean isLocationTracking()
+ {
+ return locationTracking;
+ }
+
+ @Override
+ public DefaultModelBuildingRequest setLocationTracking( boolean locationTracking )
+ {
+ this.locationTracking = locationTracking;
+
+ return this;
+ }
+
+ @Override
+ public List<Profile> getProfiles()
+ {
+ if ( profiles == null )
+ {
+ profiles = new ArrayList<Profile>();
+ }
+
+ return profiles;
+ }
+
+ @Override
+ public DefaultModelBuildingRequest setProfiles( List<Profile> profiles )
+ {
+ if ( profiles != null )
+ {
+ this.profiles = new ArrayList<Profile>( profiles );
+ }
+ else
+ {
+ this.profiles = null;
+ }
+
+ return this;
+ }
+
+ @Override
+ public List<String> getActiveProfileIds()
+ {
+ if ( activeProfileIds == null )
+ {
+ activeProfileIds = new ArrayList<String>();
+ }
+
+ return activeProfileIds;
+ }
+
+ @Override
+ public DefaultModelBuildingRequest setActiveProfileIds( List<String> activeProfileIds )
+ {
+ if ( activeProfileIds != null )
+ {
+ this.activeProfileIds = new ArrayList<String>( activeProfileIds );
+ }
+ else
+ {
+ this.activeProfileIds = null;
+ }
+
+ return this;
+ }
+
+ @Override
+ public List<String> getInactiveProfileIds()
+ {
+ if ( inactiveProfileIds == null )
+ {
+ inactiveProfileIds = new ArrayList<String>();
+ }
+
+ return inactiveProfileIds;
+ }
+
+ @Override
+ public DefaultModelBuildingRequest setInactiveProfileIds( List<String> inactiveProfileIds )
+ {
+ if ( inactiveProfileIds != null )
+ {
+ this.inactiveProfileIds = new ArrayList<String>( inactiveProfileIds );
+ }
+ else
+ {
+ this.inactiveProfileIds = null;
+ }
+
+ return this;
+ }
+
+ @Override
+ public Properties getSystemProperties()
+ {
+ if ( systemProperties == null )
+ {
+ systemProperties = new Properties();
+ }
+
+ return systemProperties;
+ }
+
+ @Override
+ public DefaultModelBuildingRequest setSystemProperties( Properties systemProperties )
+ {
+ if ( systemProperties != null )
+ {
+ this.systemProperties = new Properties();
+ this.systemProperties.putAll( systemProperties );
+ }
+ else
+ {
+ this.systemProperties = null;
+ }
+
+ return this;
+ }
+
+ @Override
+ public Properties getUserProperties()
+ {
+ if ( userProperties == null )
+ {
+ userProperties = new Properties();
+ }
+
+ return userProperties;
+ }
+
+ @Override
+ public DefaultModelBuildingRequest setUserProperties( Properties userProperties )
+ {
+ if ( userProperties != null )
+ {
+ this.userProperties = new Properties();
+ this.userProperties.putAll( userProperties );
+ }
+ else
+ {
+ this.userProperties = null;
+ }
+
+ return this;
+ }
+
+ @Override
+ public Date getBuildStartTime()
+ {
+ return buildStartTime;
+ }
+
+ @Override
+ public ModelBuildingRequest setBuildStartTime( Date buildStartTime )
+ {
+ this.buildStartTime = buildStartTime;
+
+ return this;
+ }
+
+ @Override
+ public ModelResolver getModelResolver()
+ {
+ return this.modelResolver;
+ }
+
+ @Override
+ public DefaultModelBuildingRequest setModelResolver( ModelResolver modelResolver )
+ {
+ this.modelResolver = modelResolver;
+
+ return this;
+ }
+
+ @Override
+ public ModelBuildingListener getModelBuildingListener()
+ {
+ return modelBuildingListener;
+ }
+
+ @Override
+ public ModelBuildingRequest setModelBuildingListener( ModelBuildingListener modelBuildingListener )
+ {
+ this.modelBuildingListener = modelBuildingListener;
+
+ return this;
+ }
+
+ @Override
+ public ModelCache getModelCache()
+ {
+ return this.modelCache;
+ }
+
+ @Override
+ public DefaultModelBuildingRequest setModelCache( ModelCache modelCache )
+ {
+ this.modelCache = modelCache;
+
+ return this;
+ }
+
+ @Override
+ public Model getRawModel()
+ {
+ return rawModel;
+ }
+
+ @Override
+ public ModelBuildingRequest setRawModel( Model rawModel )
+ {
+ this.rawModel = rawModel;
+ return this;
+ }
+
+ @Override
+ public WorkspaceModelResolver getWorkspaceModelResolver()
+ {
+ return workspaceResolver;
+ }
+
+ @Override
+ public ModelBuildingRequest setWorkspaceModelResolver( WorkspaceModelResolver workspaceResolver )
+ {
+ this.workspaceResolver = workspaceResolver;
+ return this;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuildingResult.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuildingResult.java
new file mode 100644
index 00000000..61fb434a
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuildingResult.java
@@ -0,0 +1,180 @@
+package org.apache.maven.model.building;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.maven.model.Model;
+import org.apache.maven.model.Profile;
+
+/**
+ * Collects the output of the model builder.
+ *
+ * @author Benjamin Bentmann
+ */
+class DefaultModelBuildingResult
+ implements ModelBuildingResult
+{
+
+ private Model effectiveModel;
+
+ private List<String> modelIds;
+
+ private Map<String, Model> rawModels;
+
+ private Map<String, List<Profile>> activePomProfiles;
+
+ private List<Profile> activeExternalProfiles;
+
+ private List<ModelProblem> problems;
+
+ public DefaultModelBuildingResult()
+ {
+ modelIds = new ArrayList<String>();
+ rawModels = new HashMap<String, Model>();
+ activePomProfiles = new HashMap<String, List<Profile>>();
+ activeExternalProfiles = new ArrayList<Profile>();
+ problems = new ArrayList<ModelProblem>();
+ }
+
+ @Override
+ public Model getEffectiveModel()
+ {
+ return effectiveModel;
+ }
+
+ public DefaultModelBuildingResult setEffectiveModel( Model model )
+ {
+ this.effectiveModel = model;
+
+ return this;
+ }
+
+ @Override
+ public List<String> getModelIds()
+ {
+ return modelIds;
+ }
+
+ public DefaultModelBuildingResult addModelId( String modelId )
+ {
+ if ( modelId == null )
+ {
+ throw new IllegalArgumentException( "no model identifier specified" );
+ }
+
+ modelIds.add( modelId );
+
+ return this;
+ }
+
+ @Override
+ public Model getRawModel()
+ {
+ return rawModels.get( modelIds.get( 0 ) );
+ }
+
+ @Override
+ public Model getRawModel( String modelId )
+ {
+ return rawModels.get( modelId );
+ }
+
+ public DefaultModelBuildingResult setRawModel( String modelId, Model rawModel )
+ {
+ if ( modelId == null )
+ {
+ throw new IllegalArgumentException( "no model identifier specified" );
+ }
+
+ rawModels.put( modelId, rawModel );
+
+ return this;
+ }
+
+ @Override
+ public List<Profile> getActivePomProfiles( String modelId )
+ {
+ return activePomProfiles.get( modelId );
+ }
+
+ public DefaultModelBuildingResult setActivePomProfiles( String modelId, List<Profile> activeProfiles )
+ {
+ if ( modelId == null )
+ {
+ throw new IllegalArgumentException( "no model identifier specified" );
+ }
+
+ if ( activeProfiles != null )
+ {
+ this.activePomProfiles.put( modelId, new ArrayList<Profile>( activeProfiles ) );
+ }
+ else
+ {
+ this.activePomProfiles.remove( modelId );
+ }
+
+ return this;
+ }
+
+ @Override
+ public List<Profile> getActiveExternalProfiles()
+ {
+ return activeExternalProfiles;
+ }
+
+ public DefaultModelBuildingResult setActiveExternalProfiles( List<Profile> activeProfiles )
+ {
+ if ( activeProfiles != null )
+ {
+ this.activeExternalProfiles = new ArrayList<Profile>( activeProfiles );
+ }
+ else
+ {
+ this.activeExternalProfiles.clear();
+ }
+
+ return this;
+ }
+
+ @Override
+ public List<ModelProblem> getProblems()
+ {
+ return problems;
+ }
+
+ public DefaultModelBuildingResult setProblems( List<ModelProblem> problems )
+ {
+ if ( problems != null )
+ {
+ this.problems = new ArrayList<ModelProblem>( problems );
+ }
+ else
+ {
+ this.problems.clear();
+ }
+
+ return this;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelProblem.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelProblem.java
new file mode 100644
index 00000000..0892f0a5
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelProblem.java
@@ -0,0 +1,175 @@
+package org.apache.maven.model.building;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.model.Model;
+
+/**
+ * Describes a problem that was encountered during model building. A problem can either be an exception that was thrown
+ * or a simple string message. In addition, a problem carries a hint about its source, e.g. the POM file that exhibits
+ * the problem.
+ *
+ * @author Benjamin Bentmann
+ */
+public class DefaultModelProblem
+ implements ModelProblem
+{
+
+ private final String source;
+
+ private final int lineNumber;
+
+ private final int columnNumber;
+
+ private final String modelId;
+
+ private final String message;
+
+ private final Exception exception;
+
+ private final Severity severity;
+
+ private final Version version;
+
+
+ /**
+ * Creates a new problem with the specified message and exception.
+ *
+ * @param message The message describing the problem, may be {@code null}.
+ * @param severity The severity level of the problem, may be {@code null} to default to
+ * {@link ModelProblem.Severity#ERROR}.
+ * @param source The source of the problem, may be {@code null}.
+ * @param lineNumber The one-based index of the line containing the error or {@code -1} if unknown.
+ * @param columnNumber The one-based index of the column containing the error or {@code -1} if unknown.
+ * @param exception The exception that caused this problem, may be {@code null}.
+ */
+ //mkleint: does this need to be public?
+ public DefaultModelProblem( String message, Severity severity, Version version, Model source, int lineNumber,
+ int columnNumber, Exception exception )
+ {
+ this( message, severity, version, ModelProblemUtils.toPath( source ), lineNumber, columnNumber,
+ ModelProblemUtils.toId( source ), exception );
+ }
+
+ /**
+ * Creates a new problem with the specified message and exception.
+ *
+ * @param message The message describing the problem, may be {@code null}.
+ * @param severity The severity level of the problem, may be {@code null} to default to
+ * {@link ModelProblem.Severity#ERROR}.
+ * @param version The version since the problem is relevant
+ * @param source A hint about the source of the problem like a file path, may be {@code null}.
+ * @param lineNumber The one-based index of the line containing the problem or {@code -1} if unknown.
+ * @param columnNumber The one-based index of the column containing the problem or {@code -1} if unknown.
+ * @param modelId The identifier of the model that exhibits the problem, may be {@code null}.
+ * @param exception The exception that caused this problem, may be {@code null}.
+ */
+ //mkleint: does this need to be public?
+ public DefaultModelProblem( String message, Severity severity, Version version, String source, int lineNumber,
+ int columnNumber, String modelId, Exception exception )
+ {
+ this.message = message;
+ this.severity = ( severity != null ) ? severity : Severity.ERROR;
+ this.source = ( source != null ) ? source : "";
+ this.lineNumber = lineNumber;
+ this.columnNumber = columnNumber;
+ this.modelId = ( modelId != null ) ? modelId : "";
+ this.exception = exception;
+ this.version = version;
+ }
+
+ @Override
+ public String getSource()
+ {
+ return source;
+ }
+
+ @Override
+ public int getLineNumber()
+ {
+ return lineNumber;
+ }
+
+ @Override
+ public int getColumnNumber()
+ {
+ return columnNumber;
+ }
+
+ @Override
+ public String getModelId()
+ {
+ return modelId;
+ }
+
+ @Override
+ public Exception getException()
+ {
+ return exception;
+ }
+
+ @Override
+ public String getMessage()
+ {
+ String msg;
+
+ if ( message != null && message.length() > 0 )
+ {
+ msg = message;
+ }
+ else
+ {
+ msg = exception.getMessage();
+
+ if ( msg == null )
+ {
+ msg = "";
+ }
+ }
+
+ return msg;
+ }
+
+ @Override
+ public Severity getSeverity()
+ {
+ return severity;
+ }
+
+ @Override
+ public Version getVersion()
+ {
+ return version;
+ }
+
+
+ @Override
+ public String toString()
+ {
+ StringBuilder buffer = new StringBuilder( 128 );
+
+ buffer.append( "[" ).append( getSeverity() ).append( "] " );
+ buffer.append( getMessage() );
+ buffer.append( " @ " ).append( ModelProblemUtils.formatLocation( this, null ) );
+
+ return buffer.toString();
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelProblemCollector.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelProblemCollector.java
new file mode 100644
index 00000000..89d5cb21
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelProblemCollector.java
@@ -0,0 +1,200 @@
+package org.apache.maven.model.building;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.EnumSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.maven.model.Model;
+import org.apache.maven.model.io.ModelParseException;
+
+/**
+ * Collects problems that are encountered during model building. The primary purpose of this component is to account for
+ * the fact that the problem reporter has/should not have information about the calling context and hence cannot provide
+ * an expressive source hint for the model problem. Instead, the source hint is configured by the model builder before
+ * it delegates to other components that potentially encounter problems. Then, the problem reporter can focus on
+ * providing a simple error message, leaving the donkey work of creating a nice model problem to this component.
+ *
+ * @author Benjamin Bentmann
+ */
+class DefaultModelProblemCollector
+ implements ModelProblemCollectorExt
+{
+
+ private final ModelBuildingResult result;
+
+ private List<ModelProblem> problems;
+
+ private String source;
+
+ private Model sourceModel;
+
+ private Model rootModel;
+
+ private Set<ModelProblem.Severity> severities = EnumSet.noneOf( ModelProblem.Severity.class );
+
+ public DefaultModelProblemCollector( ModelBuildingResult result )
+ {
+ this.result = result;
+ this.problems = result.getProblems();
+
+ for ( ModelProblem problem : this.problems )
+ {
+ severities.add( problem.getSeverity() );
+ }
+ }
+
+ public boolean hasFatalErrors()
+ {
+ return severities.contains( ModelProblem.Severity.FATAL );
+ }
+
+ public boolean hasErrors()
+ {
+ return severities.contains( ModelProblem.Severity.ERROR ) || severities.contains( ModelProblem.Severity.FATAL );
+ }
+
+ @Override
+ public List<ModelProblem> getProblems()
+ {
+ return problems;
+ }
+
+ public void setSource( String source )
+ {
+ this.source = source;
+ this.sourceModel = null;
+ }
+
+ public void setSource( Model source )
+ {
+ this.sourceModel = source;
+ this.source = null;
+
+ if ( rootModel == null )
+ {
+ rootModel = source;
+ }
+ }
+
+ private String getSource()
+ {
+ if ( source == null && sourceModel != null )
+ {
+ source = ModelProblemUtils.toPath( sourceModel );
+ }
+ return source;
+ }
+
+ private String getModelId()
+ {
+ return ModelProblemUtils.toId( sourceModel );
+ }
+
+ public void setRootModel( Model rootModel )
+ {
+ this.rootModel = rootModel;
+ }
+
+ public Model getRootModel()
+ {
+ return rootModel;
+ }
+
+ public String getRootModelId()
+ {
+ return ModelProblemUtils.toId( rootModel );
+ }
+
+ public void add( ModelProblem problem )
+ {
+ problems.add( problem );
+
+ severities.add( problem.getSeverity() );
+ }
+
+ public void addAll( List<ModelProblem> problems )
+ {
+ this.problems.addAll( problems );
+
+ for ( ModelProblem problem : problems )
+ {
+ severities.add( problem.getSeverity() );
+ }
+ }
+
+ @Override
+ public void add( ModelProblemCollectorRequest req )
+ {
+ int line = -1;
+ int column = -1;
+ String source = null;
+ String modelId = null;
+
+ if ( req.getLocation() != null )
+ {
+ line = req.getLocation().getLineNumber();
+ column = req.getLocation().getColumnNumber();
+ if ( req.getLocation().getSource() != null )
+ {
+ modelId = req.getLocation().getSource().getModelId();
+ source = req.getLocation().getSource().getLocation();
+ }
+ }
+
+ if ( modelId == null )
+ {
+ modelId = getModelId();
+ source = getSource();
+ }
+
+ if ( line <= 0 && column <= 0 && req.getException() instanceof ModelParseException )
+ {
+ ModelParseException e = (ModelParseException) req.getException();
+ line = e.getLineNumber();
+ column = e.getColumnNumber();
+ }
+
+ ModelProblem problem =
+ new DefaultModelProblem( req.getMessage(), req.getSeverity(), req.getVersion(), source, line, column,
+ modelId, req.getException() );
+
+ add( problem );
+ }
+
+ public ModelBuildingException newModelBuildingException()
+ {
+ ModelBuildingResult result = this.result;
+ if ( result.getModelIds().isEmpty() )
+ {
+ DefaultModelBuildingResult tmp = new DefaultModelBuildingResult();
+ tmp.setEffectiveModel( result.getEffectiveModel() );
+ tmp.setProblems( getProblems() );
+ tmp.setActiveExternalProfiles( result.getActiveExternalProfiles() );
+ String id = getRootModelId();
+ tmp.addModelId( id );
+ tmp.setRawModel( id, getRootModel() );
+ result = tmp;
+ }
+ return new ModelBuildingException( result );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelProcessor.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelProcessor.java
new file mode 100644
index 00000000..a4d5fa93
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelProcessor.java
@@ -0,0 +1,84 @@
+package org.apache.maven.model.building;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.util.Map;
+
+import org.apache.maven.model.Model;
+import org.apache.maven.model.io.ModelReader;
+import org.apache.maven.model.locator.ModelLocator;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+
+@Component( role = ModelProcessor.class )
+public class DefaultModelProcessor
+ implements ModelProcessor
+{
+
+ @Requirement
+ private ModelLocator locator;
+
+ @Requirement
+ private ModelReader reader;
+
+ public DefaultModelProcessor setModelLocator( ModelLocator locator )
+ {
+ this.locator = locator;
+ return this;
+ }
+
+ public DefaultModelProcessor setModelReader( ModelReader reader )
+ {
+ this.reader = reader;
+ return this;
+ }
+
+ @Override
+ public File locatePom( File projectDirectory )
+ {
+ return locator.locatePom( projectDirectory );
+ }
+
+ @Override
+ public Model read( File input, Map<String, ?> options )
+ throws IOException
+ {
+ return reader.read( input, options );
+ }
+
+ @Override
+ public Model read( Reader input, Map<String, ?> options )
+ throws IOException
+ {
+ return reader.read( input, options );
+ }
+
+ @Override
+ public Model read( InputStream input, Map<String, ?> options )
+ throws IOException
+ {
+ return reader.read( input, options );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/FileModelSource.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/FileModelSource.java
new file mode 100644
index 00000000..a2e11417
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/FileModelSource.java
@@ -0,0 +1,83 @@
+package org.apache.maven.model.building;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.net.URI;
+
+import org.apache.maven.building.FileSource;
+
+/**
+ * Wraps an ordinary {@link File} as a model source.
+ *
+ * @author Benjamin Bentmann
+ */
+public class FileModelSource extends FileSource implements ModelSource2
+{
+
+ /**
+ * Creates a new model source backed by the specified file.
+ *
+ * @param pomFile The POM file, must not be {@code null}.
+ */
+ public FileModelSource( File pomFile )
+ {
+ super( pomFile );
+ }
+
+ /**
+ *
+ * @return the file of this source
+ *
+ * @deprecated instead use {@link #getFile()}
+ */
+ @Deprecated
+ public File getPomFile()
+ {
+ return getFile();
+ }
+
+ @Override
+ public ModelSource2 getRelatedSource( String relPath )
+ {
+ relPath = relPath.replace( '\\', File.separatorChar ).replace( '/', File.separatorChar );
+
+ File relatedPom = new File( getFile().getParentFile(), relPath );
+
+ if ( relatedPom.isDirectory() )
+ {
+ // TODO figure out how to reuse ModelLocator.locatePom(File) here
+ relatedPom = new File( relatedPom, "pom.xml" );
+ }
+
+ if ( relatedPom.isFile() && relatedPom.canRead() )
+ {
+ return new FileModelSource( new File( relatedPom.toURI().normalize() ) );
+ }
+
+ return null;
+ }
+
+ @Override
+ public URI getLocationURI()
+ {
+ return getFile().toURI();
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/FilterModelBuildingRequest.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/FilterModelBuildingRequest.java
new file mode 100644
index 00000000..c5c2cbfa
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/FilterModelBuildingRequest.java
@@ -0,0 +1,285 @@
+package org.apache.maven.model.building;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.util.Date;
+import java.util.List;
+import java.util.Properties;
+
+import org.apache.maven.model.Model;
+import org.apache.maven.model.Profile;
+import org.apache.maven.model.resolution.ModelResolver;
+import org.apache.maven.model.resolution.WorkspaceModelResolver;
+
+/**
+ * A model building request that delegates all methods invocations to another request, meant for easy transformations by
+ * subclassing.
+ *
+ * @author Benjamin Bentmann
+ */
+class FilterModelBuildingRequest
+ implements ModelBuildingRequest
+{
+
+ protected ModelBuildingRequest request;
+
+ public FilterModelBuildingRequest( ModelBuildingRequest request )
+ {
+ this.request = request;
+ }
+
+ @Override
+ public File getPomFile()
+ {
+ return request.getPomFile();
+ }
+
+ @Override
+ public FilterModelBuildingRequest setPomFile( File pomFile )
+ {
+ request.setPomFile( pomFile );
+
+ return this;
+ }
+
+ @Override
+ public ModelSource getModelSource()
+ {
+ return request.getModelSource();
+ }
+
+ @Override
+ public FilterModelBuildingRequest setModelSource( ModelSource modelSource )
+ {
+ request.setModelSource( modelSource );
+
+ return this;
+ }
+
+ @Override
+ public int getValidationLevel()
+ {
+ return request.getValidationLevel();
+ }
+
+ @Override
+ public FilterModelBuildingRequest setValidationLevel( int validationLevel )
+ {
+ request.setValidationLevel( validationLevel );
+
+ return this;
+ }
+
+ @Override
+ public boolean isProcessPlugins()
+ {
+ return request.isProcessPlugins();
+ }
+
+ @Override
+ public FilterModelBuildingRequest setProcessPlugins( boolean processPlugins )
+ {
+ request.setProcessPlugins( processPlugins );
+
+ return this;
+ }
+
+ @Override
+ public boolean isTwoPhaseBuilding()
+ {
+ return request.isTwoPhaseBuilding();
+ }
+
+ @Override
+ public FilterModelBuildingRequest setTwoPhaseBuilding( boolean twoPhaseBuilding )
+ {
+ request.setTwoPhaseBuilding( twoPhaseBuilding );
+
+ return this;
+ }
+
+ @Override
+ public boolean isLocationTracking()
+ {
+ return request.isLocationTracking();
+ }
+
+ @Override
+ public FilterModelBuildingRequest setLocationTracking( boolean locationTracking )
+ {
+ request.setLocationTracking( locationTracking );
+
+ return this;
+ }
+
+ @Override
+ public List<Profile> getProfiles()
+ {
+ return request.getProfiles();
+ }
+
+ @Override
+ public FilterModelBuildingRequest setProfiles( List<Profile> profiles )
+ {
+ request.setProfiles( profiles );
+
+ return this;
+ }
+
+ @Override
+ public List<String> getActiveProfileIds()
+ {
+ return request.getActiveProfileIds();
+ }
+
+ @Override
+ public FilterModelBuildingRequest setActiveProfileIds( List<String> activeProfileIds )
+ {
+ request.setActiveProfileIds( activeProfileIds );
+
+ return this;
+ }
+
+ @Override
+ public List<String> getInactiveProfileIds()
+ {
+ return request.getInactiveProfileIds();
+ }
+
+ @Override
+ public FilterModelBuildingRequest setInactiveProfileIds( List<String> inactiveProfileIds )
+ {
+ request.setInactiveProfileIds( inactiveProfileIds );
+
+ return this;
+ }
+
+ @Override
+ public Properties getSystemProperties()
+ {
+ return request.getSystemProperties();
+ }
+
+ @Override
+ public FilterModelBuildingRequest setSystemProperties( Properties systemProperties )
+ {
+ request.setSystemProperties( systemProperties );
+
+ return this;
+ }
+
+ @Override
+ public Properties getUserProperties()
+ {
+ return request.getUserProperties();
+ }
+
+ @Override
+ public FilterModelBuildingRequest setUserProperties( Properties userProperties )
+ {
+ request.setUserProperties( userProperties );
+
+ return this;
+ }
+
+ @Override
+ public Date getBuildStartTime()
+ {
+ return request.getBuildStartTime();
+ }
+
+ @Override
+ public ModelBuildingRequest setBuildStartTime( Date buildStartTime )
+ {
+ request.setBuildStartTime( buildStartTime );
+
+ return this;
+ }
+
+ @Override
+ public ModelResolver getModelResolver()
+ {
+ return request.getModelResolver();
+ }
+
+ @Override
+ public FilterModelBuildingRequest setModelResolver( ModelResolver modelResolver )
+ {
+ request.setModelResolver( modelResolver );
+
+ return this;
+ }
+
+ @Override
+ public ModelBuildingListener getModelBuildingListener()
+ {
+ return request.getModelBuildingListener();
+ }
+
+ @Override
+ public ModelBuildingRequest setModelBuildingListener( ModelBuildingListener modelBuildingListener )
+ {
+ request.setModelBuildingListener( modelBuildingListener );
+
+ return this;
+ }
+
+ @Override
+ public ModelCache getModelCache()
+ {
+ return request.getModelCache();
+ }
+
+ @Override
+ public FilterModelBuildingRequest setModelCache( ModelCache modelCache )
+ {
+ request.setModelCache( modelCache );
+
+ return this;
+ }
+
+ @Override
+ public Model getRawModel()
+ {
+ return request.getRawModel();
+ }
+
+ @Override
+ public ModelBuildingRequest setRawModel( Model rawModel )
+ {
+ request.setRawModel( rawModel );
+ return this;
+ }
+
+ @Override
+ public WorkspaceModelResolver getWorkspaceModelResolver()
+ {
+ return request.getWorkspaceModelResolver();
+ }
+
+ @Override
+ public ModelBuildingRequest setWorkspaceModelResolver( WorkspaceModelResolver workspaceResolver )
+ {
+ request.setWorkspaceModelResolver( workspaceResolver );
+ return this;
+ }
+
+} \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelBuilder.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelBuilder.java
new file mode 100644
index 00000000..2a49a213
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelBuilder.java
@@ -0,0 +1,67 @@
+package org.apache.maven.model.building;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+
+import org.apache.maven.model.Model;
+
+/**
+ * Builds the effective model from a POM.
+ *
+ * @author Benjamin Bentmann
+ */
+public interface ModelBuilder
+{
+
+ /**
+ * Builds the effective model of the specified POM.
+ *
+ * @param request The model building request that holds the parameters, must not be {@code null}.
+ * @return The result of the model building, never {@code null}.
+ * @throws ModelBuildingException If the effective model could not be built.
+ */
+ ModelBuildingResult build( ModelBuildingRequest request )
+ throws ModelBuildingException;
+
+ /**
+ * Builds the effective model by completing the specified interim result which was produced by a previous call to
+ * {@link #build(ModelBuildingRequest)} with {@link ModelBuildingRequest#isTwoPhaseBuilding()} being {@code true}.
+ * The model building request passed to this method must be the same as the one used for the first phase of the
+ * model building.
+ *
+ * @param request The model building request that holds the parameters, must not be {@code null}.
+ * @param result The interim result of the first phase of model building, must not be {@code null}.
+ * @return The result of the model building, never {@code null}.
+ * @throws ModelBuildingException If the effective model could not be built.
+ */
+ ModelBuildingResult build( ModelBuildingRequest request, ModelBuildingResult result )
+ throws ModelBuildingException;
+
+ /**
+ * Performs only the part of {@link ModelBuilder#build(ModelBuildingRequest)} that loads the raw model
+ *
+ * @param request
+ * @return
+ * @throws ModelBuildingException
+ */
+ Result<? extends Model> buildRawModel( File pomFile, int validationLevel, boolean locationTracking );
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelBuildingEvent.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelBuildingEvent.java
new file mode 100644
index 00000000..2995b1bf
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelBuildingEvent.java
@@ -0,0 +1,53 @@
+package org.apache.maven.model.building;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.model.Model;
+
+/**
+ * Holds data relevant for a model building event.
+ *
+ * @author Benjamin Bentmann
+ */
+public interface ModelBuildingEvent
+{
+
+ /**
+ * Gets the model being built. The precise state of this model depends on the event being fired.
+ *
+ * @return The model being built, never {@code null}.
+ */
+ Model getModel();
+
+ /**
+ * Gets the model building request being processed.
+ *
+ * @return The model building request being processed, never {@code null}.
+ */
+ ModelBuildingRequest getRequest();
+
+ /**
+ * Gets the container used to collect problems that were encountered while processing the event.
+ *
+ * @return The container used to collect problems that were encountered, never {@code null}.
+ */
+ ModelProblemCollector getProblems();
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelBuildingEventCatapult.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelBuildingEventCatapult.java
new file mode 100644
index 00000000..092dc4e0
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelBuildingEventCatapult.java
@@ -0,0 +1,48 @@
+package org.apache.maven.model.building;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Assists in firing events from a generic method by abstracting from the actual callback method to be called on the
+ * listener.
+ *
+ * @author Benjamin Bentmann
+ */
+interface ModelBuildingEventCatapult
+{
+
+ /**
+ * Notifies the specified listener of the given event.
+ *
+ * @param listener The listener to notify, must not be {@code null}.
+ * @param event The event to fire, must not be {@code null}.
+ */
+ void fire( ModelBuildingListener listener, ModelBuildingEvent event );
+
+ ModelBuildingEventCatapult BUILD_EXTENSIONS_ASSEMBLED = new ModelBuildingEventCatapult()
+ {
+ @Override
+ public void fire( ModelBuildingListener listener, ModelBuildingEvent event )
+ {
+ listener.buildExtensionsAssembled( event );
+ }
+ };
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelBuildingException.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelBuildingException.java
new file mode 100644
index 00000000..434cb591
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelBuildingException.java
@@ -0,0 +1,180 @@
+package org.apache.maven.model.building;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.maven.model.Model;
+
+/**
+ * Signals one ore more errors during model building. The model builder tries to collect as many problems as possible
+ * before eventually failing to provide callers with rich error information. Use {@link #getProblems()} to query the
+ * details of the failure.
+ *
+ * @author Benjamin Bentmann
+ */
+public class ModelBuildingException
+ extends Exception
+{
+
+ private final ModelBuildingResult result;
+
+ /**
+ * Creates a new exception with the specified problems.
+ *
+ * @param model The model that could not be built, may be {@code null}.
+ * @param modelId The identifier of the model that could not be built, may be {@code null}.
+ * @param problems The problems that causes this exception, may be {@code null}.
+ * @deprecated Use {@link #ModelBuildingException(ModelBuildingResult)} instead.
+ */
+ @Deprecated
+ public ModelBuildingException( Model model, String modelId, List<ModelProblem> problems )
+ {
+ super( toMessage( modelId, problems ) );
+
+ if ( model != null )
+ {
+ DefaultModelBuildingResult tmp = new DefaultModelBuildingResult();
+ if ( modelId == null )
+ {
+ modelId = "";
+ }
+ tmp.addModelId( modelId );
+ tmp.setRawModel( modelId, model );
+ tmp.setProblems( problems );
+ result = tmp;
+ }
+ else
+ {
+ result = null;
+ }
+ }
+
+ /**
+ * Creates a new exception from the specified interim result and its associated problems.
+ *
+ * @param result The interim result, may be {@code null}.
+ */
+ public ModelBuildingException( ModelBuildingResult result )
+ {
+ super( toMessage( result ) );
+ this.result = result;
+ }
+
+ /**
+ * Gets the interim result of the model building up to the point where it failed.
+ *
+ * @return The interim model building result or {@code null} if not available.
+ */
+ public ModelBuildingResult getResult()
+ {
+ return result;
+ }
+
+ /**
+ * Gets the model that could not be built properly.
+ *
+ * @return The erroneous model or {@code null} if not available.
+ */
+ public Model getModel()
+ {
+ if ( result == null )
+ {
+ return null;
+ }
+ if ( result.getEffectiveModel() != null )
+ {
+ return result.getEffectiveModel();
+ }
+ return result.getRawModel();
+ }
+
+ /**
+ * Gets the identifier of the POM whose effective model could not be built. The general format of the identifier is
+ * {@code <groupId>:<artifactId>:<version>} but some of these coordinates may still be unknown at the point the
+ * exception is thrown so this information is merely meant to assist the user.
+ *
+ * @return The identifier of the POM or an empty string if not known, never {@code null}.
+ */
+ public String getModelId()
+ {
+ if ( result == null || result.getModelIds().isEmpty() )
+ {
+ return "";
+ }
+ return result.getModelIds().get( 0 );
+ }
+
+ /**
+ * Gets the problems that caused this exception.
+ *
+ * @return The problems that caused this exception, never {@code null}.
+ */
+ public List<ModelProblem> getProblems()
+ {
+ if ( result == null )
+ {
+ return Collections.emptyList();
+ }
+ return result.getProblems();
+ }
+
+ private static String toMessage( ModelBuildingResult result )
+ {
+ if ( result != null && !result.getModelIds().isEmpty() )
+ {
+ return toMessage( result.getModelIds().get( 0 ), result.getProblems() );
+ }
+ return null;
+ }
+
+ private static String toMessage( String modelId, List<ModelProblem> problems )
+ {
+ StringWriter buffer = new StringWriter( 1024 );
+
+ PrintWriter writer = new PrintWriter( buffer );
+
+ writer.print( problems.size() );
+ writer.print( ( problems.size() == 1 ) ? " problem was " : " problems were " );
+ writer.print( "encountered while building the effective model" );
+ if ( modelId != null && modelId.length() > 0 )
+ {
+ writer.print( " for " );
+ writer.print( modelId );
+ }
+ writer.println();
+
+ for ( ModelProblem problem : problems )
+ {
+ writer.print( "[" );
+ writer.print( problem.getSeverity() );
+ writer.print( "] " );
+ writer.print( problem.getMessage() );
+ writer.print( " @ " );
+ writer.println( ModelProblemUtils.formatLocation( problem, modelId ) );
+ }
+
+ return buffer.toString();
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelBuildingListener.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelBuildingListener.java
new file mode 100644
index 00000000..21029cc8
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelBuildingListener.java
@@ -0,0 +1,40 @@
+package org.apache.maven.model.building;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Defines events that the model builder fires during construction of the effective model. When a listener encounteres
+ * errors while processing the event, it can report these problems via {@link ModelBuildingEvent#getProblems()}.
+ * <em>Note:</em> To cope with future extensions to this interface, it is strongly recommended to extend
+ * {@link AbstractModelBuildingListener} rather than to directly implement this interface.
+ *
+ * @author Benjamin Bentmann
+ */
+public interface ModelBuildingListener
+{
+
+ /**
+ * Notifies the listener that the model has been constructed to the extent where build extensions can be processed.
+ *
+ * @param event The details about the event.
+ */
+ void buildExtensionsAssembled( ModelBuildingEvent event );
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelBuildingRequest.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelBuildingRequest.java
new file mode 100644
index 00000000..c10274db
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelBuildingRequest.java
@@ -0,0 +1,338 @@
+package org.apache.maven.model.building;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.util.Date;
+import java.util.List;
+import java.util.Properties;
+
+import org.apache.maven.model.Model;
+import org.apache.maven.model.Profile;
+import org.apache.maven.model.resolution.ModelResolver;
+import org.apache.maven.model.resolution.WorkspaceModelResolver;
+
+/**
+ * Collects settings that control the building of effective models.
+ *
+ * @author Benjamin Bentmann
+ */
+public interface ModelBuildingRequest
+{
+
+ /**
+ * Denotes minimal validation of POMs. This validation level is meant for processing of POMs from repositories
+ * during metadata retrieval.
+ */
+ int VALIDATION_LEVEL_MINIMAL = 0;
+
+ /**
+ * Denotes validation as performed by Maven 2.0. This validation level is meant as a compatibility mode to allow
+ * users to migrate their projects.
+ */
+ int VALIDATION_LEVEL_MAVEN_2_0 = 20;
+
+ /**
+ * Denotes validation as performed by Maven 3.0. This validation level is meant for existing projects.
+ */
+ int VALIDATION_LEVEL_MAVEN_3_0 = 30;
+
+ /**
+ * Denotes validation as performed by Maven 3.1. This validation level is meant for new projects.
+ */
+ int VALIDATION_LEVEL_MAVEN_3_1 = 31;
+
+ /**
+ * Denotes strict validation as recommended by the current Maven version.
+ */
+ int VALIDATION_LEVEL_STRICT = VALIDATION_LEVEL_MAVEN_3_0;
+
+ /**
+ * Gets the raw model to build. If not set, model source will be used to load raw model.
+ *
+ * @return The raw model to build or {@code null} if not set.
+ */
+ Model getRawModel();
+
+ /**
+ * Set raw model.
+ *
+ * @param model
+ */
+ ModelBuildingRequest setRawModel( Model rawModel );
+
+ /**
+ * Gets the source of the POM to process.
+ *
+ * @return The source of the POM or {@code null} if not set.
+ */
+ ModelSource getModelSource();
+
+ /**
+ * Sets the source of the POM to process. Eventually, either {@link #setModelSource(ModelSource)} or
+ * {@link #setPomFile(File)} must be set.
+ *
+ * @param modelSource The source of the POM to process, may be {@code null}.
+ * @return This request, never {@code null}.
+ */
+ ModelBuildingRequest setModelSource( ModelSource modelSource );
+
+ /**
+ * Gets the POM file of the project to build.
+ *
+ * @return The POM file of the project or {@code null} if not applicable (i.e. when processing a POM from the
+ * repository).
+ */
+ File getPomFile();
+
+ /**
+ * Sets the POM file of the project to build. Note that providing the path to a POM file via this method will make
+ * the model builder operate in project mode. This mode is meant for effective models that are employed during the
+ * build process of a local project. Hence the effective model will support the notion of a project directory. To
+ * build the model for a POM from the repository, use {@link #setModelSource(ModelSource)} in combination with a
+ * {@link FileModelSource} instead.
+ *
+ * @param pomFile The POM file of the project to build the effective model for, may be {@code null} to build the
+ * model of some POM from the repository.
+ * @return This request, never {@code null}.
+ */
+ ModelBuildingRequest setPomFile( File pomFile );
+
+ /**
+ * Gets the level of validation to perform on processed models.
+ *
+ * @return The level of validation to perform on processed models.
+ */
+ int getValidationLevel();
+
+ /**
+ * Sets the level of validation to perform on processed models. For building of projects,
+ * {@link #VALIDATION_LEVEL_STRICT} should be used to ensure proper building. For the mere retrievel of dependencies
+ * during artifact resolution, {@link #VALIDATION_LEVEL_MINIMAL} should be used to account for models of poor
+ * quality. By default, models are validated in strict mode.
+ *
+ * @param validationLevel The level of validation to perform on processed models.
+ * @return This request, never {@code null}.
+ */
+ ModelBuildingRequest setValidationLevel( int validationLevel );
+
+ /**
+ * Indicates whether plugin executions and configurations should be processed. If enabled, lifecycle-induced plugin
+ * executions will be injected into the model and common plugin configuration will be propagated to individual
+ * executions.
+ *
+ * @return {@code true} if plugins should be processed, {@code false} otherwise.
+ */
+ boolean isProcessPlugins();
+
+ /**
+ * Controls the processing of plugin executions and configurations.
+ *
+ * @param processPlugins {@code true} to enable plugin processing, {@code false} otherwise.
+ * @return This request, never {@code null}.
+ */
+ ModelBuildingRequest setProcessPlugins( boolean processPlugins );
+
+ /**
+ * Indicates whether the model building should happen in two phases. If enabled, the initial invocation of the model
+ * builder will only produce an interim result which may be used to analyze inter-model dependencies before the
+ * final invocation of the model builder is performed.
+ *
+ * @return {@code true} if two-phase building is enabled, {@code false} if the model should be build in a single
+ * step.
+ */
+ boolean isTwoPhaseBuilding();
+
+ /**
+ * Enables/disables two-phase building. If enabled, the initial invocation of the model builder will only produce an
+ * interim result which may be used to analyze inter-model dependencies before the final invocation of the model
+ * builder is performed.
+ *
+ * @param twoPhaseBuilding {@code true} to enable two-phase building, {@code false} if the model should be build in
+ * a single step.
+ * @return This request, never {@code null}.
+ */
+ ModelBuildingRequest setTwoPhaseBuilding( boolean twoPhaseBuilding );
+
+ /**
+ * Indicates whether the model should track the line/column number of the model source from which it was parsed.
+ *
+ * @return {@code true} if location tracking is enabled, {@code false} otherwise.
+ */
+ boolean isLocationTracking();
+
+ /**
+ * Enables/disables the tracking of line/column numbers for the model source being parsed. By default, input
+ * locations are not tracked.
+ *
+ * @param locationTracking {@code true} to enable location tracking, {@code false} to disable it.
+ * @return This request, never {@code null}.
+ */
+ ModelBuildingRequest setLocationTracking( boolean locationTracking );
+
+ /**
+ * Gets the external profiles that should be considered for model building.
+ *
+ * @return The external profiles that should be considered for model building, never {@code null}.
+ */
+ List<Profile> getProfiles();
+
+ /**
+ * Sets the external profiles that should be considered for model building.
+ *
+ * @param profiles The external profiles that should be considered for model building, may be {@code null}.
+ * @return This request, never {@code null}.
+ */
+ ModelBuildingRequest setProfiles( List<Profile> profiles );
+
+ /**
+ * Gets the identifiers of those profiles that should be activated by explicit demand.
+ *
+ * @return The identifiers of those profiles to activate, never {@code null}.
+ */
+ List<String> getActiveProfileIds();
+
+ /**
+ * Sets the identifiers of those profiles that should be activated by explicit demand.
+ *
+ * @param activeProfileIds The identifiers of those profiles to activate, may be {@code null}.
+ * @return This request, never {@code null}.
+ */
+ ModelBuildingRequest setActiveProfileIds( List<String> activeProfileIds );
+
+ /**
+ * Gets the identifiers of those profiles that should be deactivated by explicit demand.
+ *
+ * @return The identifiers of those profiles to deactivate, never {@code null}.
+ */
+ List<String> getInactiveProfileIds();
+
+ /**
+ * Sets the identifiers of those profiles that should be deactivated by explicit demand.
+ *
+ * @param inactiveProfileIds The identifiers of those profiles to deactivate, may be {@code null}.
+ * @return This request, never {@code null}.
+ */
+ ModelBuildingRequest setInactiveProfileIds( List<String> inactiveProfileIds );
+
+ /**
+ * Gets the system properties to use for interpolation and profile activation. The system properties are collected
+ * from the runtime environment like {@link System#getProperties()} and environment variables.
+ *
+ * @return The system properties, never {@code null}.
+ */
+ Properties getSystemProperties();
+
+ /**
+ * Sets the system properties to use for interpolation and profile activation. The system properties are collected
+ * from the runtime environment like {@link System#getProperties()} and environment variables.
+ *
+ * @param systemProperties The system properties, may be {@code null}.
+ * @return This request, never {@code null}.
+ */
+ ModelBuildingRequest setSystemProperties( Properties systemProperties );
+
+ /**
+ * Gets the user properties to use for interpolation and profile activation. The user properties have been
+ * configured directly by the user on his discretion, e.g. via the {@code -Dkey=value} parameter on the command
+ * line.
+ *
+ * @return The user properties, never {@code null}.
+ */
+ Properties getUserProperties();
+
+ /**
+ * Sets the user properties to use for interpolation and profile activation. The user properties have been
+ * configured directly by the user on his discretion, e.g. via the {@code -Dkey=value} parameter on the command
+ * line.
+ *
+ * @param userProperties The user properties, may be {@code null}.
+ * @return This request, never {@code null}.
+ */
+ ModelBuildingRequest setUserProperties( Properties userProperties );
+
+ /**
+ * Gets the start time of the build.
+ *
+ * @return The start time of the build or {@code null} if unknown.
+ */
+ Date getBuildStartTime();
+
+ /**
+ * Sets the start time of the build.
+ *
+ * @param buildStartTime The start time of the build, may be {@code null}.
+ * @return This request, never {@code null}.
+ */
+ ModelBuildingRequest setBuildStartTime( Date buildStartTime );
+
+ /**
+ * Gets the model resolver to use for resolution of mixins or parents that are not locally reachable from the
+ * project directory.
+ *
+ * @return The model resolver or {@code null} if not set.
+ */
+ ModelResolver getModelResolver();
+
+ /**
+ * Sets the model resolver to use for resolution of mixins or parents that are not locally reachable from the
+ * project directory.
+ *
+ * @param modelResolver The model resolver to use, may be {@code null}.
+ * @return This request, never {@code null}.
+ */
+ ModelBuildingRequest setModelResolver( ModelResolver modelResolver );
+
+ /**
+ * Gets the model building listener to notify during the build process.
+ *
+ * @return The model building listener to notify or {@code null} if none.
+ */
+ ModelBuildingListener getModelBuildingListener();
+
+ /**
+ * Sets the model building listener to notify during the build process.
+ *
+ * @param modelBuildingListener The model building listener to notify, may be {@code null}.
+ * @return This request, never {@code null}.
+ */
+ ModelBuildingRequest setModelBuildingListener( ModelBuildingListener modelBuildingListener );
+
+ /**
+ * Gets the model cache to use for reuse of previously built models.
+ *
+ * @return The model cache or {@code null} if not set.
+ */
+ ModelCache getModelCache();
+
+ /**
+ * Sets the model cache to use for reuse of previously built models. This is an optional component that serves
+ * performance optimizations.
+ *
+ * @param modelCache The model cache to use, may be {@code null}.
+ * @return This request, never {@code null}.
+ */
+ ModelBuildingRequest setModelCache( ModelCache modelCache );
+
+ WorkspaceModelResolver getWorkspaceModelResolver();
+
+ ModelBuildingRequest setWorkspaceModelResolver( WorkspaceModelResolver workspaceResolver );
+
+} \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelBuildingResult.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelBuildingResult.java
new file mode 100644
index 00000000..44b12958
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelBuildingResult.java
@@ -0,0 +1,99 @@
+package org.apache.maven.model.building;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.List;
+
+import org.apache.maven.model.Model;
+import org.apache.maven.model.Profile;
+
+/**
+ * Collects the output of the model builder.
+ *
+ * @author Benjamin Bentmann
+ */
+public interface ModelBuildingResult
+{
+
+ /**
+ * Gets the sequence of model identifiers that denote the lineage of models from which the effective model was
+ * constructed. Model identifiers have the form {@code <groupId>:<artifactId>:<version>}. The first identifier from
+ * the list denotes the model on which the model builder was originally invoked. The last identifier will always be
+ * an empty string that by definition denotes the super POM.
+ *
+ * @return The model identifiers from the lineage of models, never {@code null}.
+ */
+ List<String> getModelIds();
+
+ /**
+ * Gets the assembled model.
+ *
+ * @return The assembled model, never {@code null}.
+ */
+ Model getEffectiveModel();
+
+ /**
+ * Gets the raw model as it was read from the input model source. Apart from basic validation, the raw model has not
+ * undergone any updates by the model builder, e.g. reflects neither inheritance nor interpolation.
+ *
+ * @return The raw model, never {@code null}.
+ */
+ Model getRawModel();
+
+ /**
+ * Gets the specified raw model as it was read from a model source. Apart from basic validation, a raw model has not
+ * undergone any updates by the model builder, e.g. reflects neither inheritance nor interpolation. The model
+ * identifier should be from the collection obtained by {@link #getModelIds()}. As a special case, an empty string
+ * can be used as the identifier for the super POM.
+ *
+ * @param modelId The identifier of the desired raw model, must not be {@code null}.
+ * @return The raw model or {@code null} if the specified model id does not refer to a known model.
+ */
+ Model getRawModel( String modelId );
+
+ /**
+ * Gets the profiles from the specified model that were active during model building. The model identifier should be
+ * from the collection obtained by {@link #getModelIds()}. As a special case, an empty string can be used as the
+ * identifier for the super POM.
+ *
+ * @param modelId The identifier of the model whose active profiles should be retrieved, must not be {@code null}.
+ * @return The active profiles of the model or an empty list if none or {@code null} if the specified model id does
+ * not refer to a known model.
+ */
+ List<Profile> getActivePomProfiles( String modelId );
+
+ /**
+ * Gets the external profiles that were active during model building. External profiles are those that were
+ * contributed by {@link ModelBuildingRequest#getProfiles()}.
+ *
+ * @return The active external profiles or an empty list if none, never {@code null}.
+ */
+ List<Profile> getActiveExternalProfiles();
+
+ /**
+ * Gets the problems that were encountered during the model building. Note that only problems of severity
+ * {@link ModelProblem.Severity#WARNING} and below are reported here. Problems with a higher severity level cause
+ * the model builder to fail with a {@link ModelBuildingException}.
+ *
+ * @return The problems that were encountered during the model building, can be empty but never {@code null}.
+ */
+ List<ModelProblem> getProblems();
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelCache.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelCache.java
new file mode 100644
index 00000000..132a5113
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelCache.java
@@ -0,0 +1,56 @@
+package org.apache.maven.model.building;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Caches auxiliary data used during model building like already processed raw/effective models. The data in the cache
+ * is meant for exclusive consumption by the model builder and is opaque to the cache implementation. The cache key is
+ * formed by a combination of group id, artifact id, version and tag. The first three components generally refer to the
+ * identify of a model. The tag allows for further classification of the associated data on the sole discretion of the
+ * model builder.
+ *
+ * @author Benjamin Bentmann
+ */
+public interface ModelCache
+{
+
+ /**
+ * Puts the specified data into the cache.
+ *
+ * @param groupId The group id of the cache record, must not be {@code null}.
+ * @param artifactId The artifact id of the cache record, must not be {@code null}.
+ * @param version The version of the cache record, must not be {@code null}.
+ * @param tag The tag of the cache record, must not be {@code null}.
+ * @param data The data to store in the cache, must not be {@code null}.
+ */
+ void put( String groupId, String artifactId, String version, String tag, Object data );
+
+ /**
+ * Gets the specified data from the cache.
+ *
+ * @param groupId The group id of the cache record, must not be {@code null}.
+ * @param artifactId The artifact id of the cache record, must not be {@code null}.
+ * @param version The version of the cache record, must not be {@code null}.
+ * @param tag The tag of the cache record, must not be {@code null}.
+ * @return The requested data or {@code null} if none was present in the cache.
+ */
+ Object get( String groupId, String artifactId, String version, String tag );
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelCacheTag.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelCacheTag.java
new file mode 100644
index 00000000..8452f967
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelCacheTag.java
@@ -0,0 +1,132 @@
+package org.apache.maven.model.building;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.model.DependencyManagement;
+import org.apache.maven.model.Model;
+
+/**
+ * Describes a tag used by the model builder to access a {@link ModelCache}. This interface basically aggregates a name
+ * and a class to provide some type safety when working with the otherwise untyped cache.
+ *
+ * @author Benjamin Bentmann
+ * @param <T> The type of data associated with the tag.
+ */
+interface ModelCacheTag<T>
+{
+
+ /**
+ * Gets the name of the tag.
+ *
+ * @return The name of the tag, must not be {@code null}.
+ */
+ String getName();
+
+ /**
+ * Gets the type of data associated with this tag.
+ *
+ * @return The type of data, must not be {@code null}.
+ */
+ Class<T> getType();
+
+ /**
+ * Creates a copy of the data suitable for storage in the cache. The original data to store can be mutated after the
+ * cache is populated but the state of the cache must not change so we need to make a copy.
+ *
+ * @param data The data to store in the cache, must not be {@code null}.
+ * @return The data being stored in the cache, never {@code null}.
+ */
+ T intoCache( T data );
+
+ /**
+ * Creates a copy of the data suitable for retrieval from the cache. The retrieved data can be mutated after the
+ * cache is queried but the state of the cache must not change so we need to make a copy.
+ *
+ * @param data The data to retrieve from the cache, must not be {@code null}.
+ * @return The data being retrieved from the cache, never {@code null}.
+ */
+ T fromCache( T data );
+
+ /**
+ * The tag used to denote raw model data.
+ */
+ ModelCacheTag<ModelData> RAW = new ModelCacheTag<ModelData>()
+ {
+
+ @Override
+ public String getName()
+ {
+ return "raw";
+ }
+
+ @Override
+ public Class<ModelData> getType()
+ {
+ return ModelData.class;
+ }
+
+ @Override
+ public ModelData intoCache( ModelData data )
+ {
+ Model model = ( data.getModel() != null ) ? data.getModel().clone() : null;
+ return new ModelData( data.getSource(), model, data.getGroupId(), data.getArtifactId(), data.getVersion() );
+ }
+
+ @Override
+ public ModelData fromCache( ModelData data )
+ {
+ return intoCache( data );
+ }
+
+ };
+
+ /**
+ * The tag used to denote an effective dependency management section from an imported model.
+ */
+ ModelCacheTag<DependencyManagement> IMPORT = new ModelCacheTag<DependencyManagement>()
+ {
+
+ @Override
+ public String getName()
+ {
+ return "import";
+ }
+
+ @Override
+ public Class<DependencyManagement> getType()
+ {
+ return DependencyManagement.class;
+ }
+
+ @Override
+ public DependencyManagement intoCache( DependencyManagement data )
+ {
+ return ( data != null ) ? data.clone() : null;
+ }
+
+ @Override
+ public DependencyManagement fromCache( DependencyManagement data )
+ {
+ return intoCache( data );
+ }
+
+ };
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelData.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelData.java
new file mode 100644
index 00000000..4fefe0df
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelData.java
@@ -0,0 +1,222 @@
+package org.apache.maven.model.building;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.List;
+
+import org.apache.maven.model.Model;
+import org.apache.maven.model.Profile;
+
+/**
+ * Holds a model along with some auxiliary information. This internal utility class assists the model builder during POM
+ * processing by providing a means to transport information that cannot be (easily) extracted from the model itself.
+ *
+ * @author Benjamin Bentmann
+ */
+class ModelData
+{
+ private final ModelSource source;
+
+ private Model model;
+
+ private Model rawModel;
+
+ private List<Profile> activeProfiles;
+
+ private String groupId;
+
+ private String artifactId;
+
+ private String version;
+
+ /**
+ * Creates a new container for the specified model.
+ *
+ * @param model The model to wrap, may be {@code null}.
+ */
+ public ModelData( ModelSource source, Model model )
+ {
+ this.source = source;
+ this.model = model;
+ }
+
+ /**
+ * Creates a new container for the specified model.
+ *
+ * @param model The model to wrap, may be {@code null}.
+ * @param groupId The effective group identifier of the model, may be {@code null}.
+ * @param artifactId The effective artifact identifier of the model, may be {@code null}.
+ * @param version The effective version of the model, may be {@code null}.
+ */
+ public ModelData( ModelSource source, Model model, String groupId, String artifactId, String version )
+ {
+ this.source = source;
+ this.model = model;
+ setGroupId( groupId );
+ setArtifactId( artifactId );
+ setVersion( version );
+ }
+
+ public ModelSource getSource()
+ {
+ return source;
+ }
+
+ /**
+ * Gets the model being wrapped.
+ *
+ * @return The model or {@code null} if not set.
+ */
+ public Model getModel()
+ {
+ return model;
+ }
+
+ /**
+ * Sets the model being wrapped.
+ *
+ * @param model The model, may be {@code null}.
+ */
+ public void setModel( Model model )
+ {
+ this.model = model;
+ }
+
+ /**
+ * Gets the raw model being wrapped.
+ *
+ * @return The raw model or {@code null} if not set.
+ */
+ public Model getRawModel()
+ {
+ return rawModel;
+ }
+
+ /**
+ * Sets the raw model being wrapped.
+ *
+ * @param rawModel The raw model, may be {@code null}.
+ */
+ public void setRawModel( Model rawModel )
+ {
+ this.rawModel = rawModel;
+ }
+
+ /**
+ * Gets the active profiles from the model.
+ *
+ * @return The active profiles or {@code null} if not set.
+ */
+ public List<Profile> getActiveProfiles()
+ {
+ return activeProfiles;
+ }
+
+ /**
+ * Sets the active profiles from the model.
+ *
+ * @param activeProfiles The active profiles, may be {@code null}.
+ */
+ public void setActiveProfiles( List<Profile> activeProfiles )
+ {
+ this.activeProfiles = activeProfiles;
+ }
+
+ /**
+ * Gets the effective group identifier of the model.
+ *
+ * @return The effective group identifier of the model or an empty string if unknown, never {@code null}.
+ */
+ public String getGroupId()
+ {
+ return ( groupId != null ) ? groupId : "";
+ }
+
+ /**
+ * Sets the effective group identifier of the model.
+ *
+ * @param groupId The effective group identifier of the model, may be {@code null}.
+ */
+ public void setGroupId( String groupId )
+ {
+ this.groupId = groupId;
+ }
+
+ /**
+ * Gets the effective artifact identifier of the model.
+ *
+ * @return The effective artifact identifier of the model or an empty string if unknown, never {@code null}.
+ */
+ public String getArtifactId()
+ {
+ return ( artifactId != null ) ? artifactId : "";
+ }
+
+ /**
+ * Sets the effective artifact identifier of the model.
+ *
+ * @param artifactId The effective artifact identifier of the model, may be {@code null}.
+ */
+ public void setArtifactId( String artifactId )
+ {
+ this.artifactId = artifactId;
+ }
+
+ /**
+ * Gets the effective version of the model.
+ *
+ * @return The effective version of the model or an empty string if unknown, never {@code null}.
+ */
+ public String getVersion()
+ {
+ return ( version != null ) ? version : "";
+ }
+
+ /**
+ * Sets the effective version of the model.
+ *
+ * @param version The effective version of the model, may be {@code null}.
+ */
+ public void setVersion( String version )
+ {
+ this.version = version;
+ }
+
+ /**
+ * Gets the effective identifier of the model in the form {@code <groupId>:<artifactId>:<version>}.
+ *
+ * @return The effective identifier of the model, never {@code null}.
+ */
+ public String getId()
+ {
+ StringBuilder buffer = new StringBuilder( 96 );
+
+ buffer.append( getGroupId() ).append( ':' ).append( getArtifactId() ).append( ':' ).append( getVersion() );
+
+ return buffer.toString();
+ }
+
+ @Override
+ public String toString()
+ {
+ return String.valueOf( model );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelProblem.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelProblem.java
new file mode 100644
index 00000000..43272bac
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelProblem.java
@@ -0,0 +1,117 @@
+package org.apache.maven.model.building;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Describes a problem that was encountered during model building. A problem can either be an exception that was thrown
+ * or a simple string message. In addition, a problem carries a hint about its source, e.g. the POM file that exhibits
+ * the problem.
+ *
+ * @author Benjamin Bentmann
+ */
+public interface ModelProblem
+{
+
+ /**
+ * The different severity levels for a problem, in decreasing order.
+ */
+ enum Severity
+ {
+
+ FATAL, //
+ ERROR, //
+ WARNING //
+
+ }
+
+ enum Version
+ {
+ //based on ModeBuildingResult.validationLevel
+ BASE,
+ V20,
+ V30,
+ V31
+ }
+
+ /**
+ * Gets the hint about the source of the problem. While the syntax of this hint is unspecified and depends on the
+ * creator of the problem, the general expectation is that the hint provides sufficient information to the user to
+ * track the problem back to its origin. A concrete example for such a source hint can be the file path or URL from
+ * which a POM was read.
+ *
+ * @return The hint about the source of the problem or an empty string if unknown, never {@code null}.
+ */
+ String getSource();
+
+ /**
+ * Gets the one-based index of the line containing the problem. The line number should refer to some text file that
+ * is given by {@link #getSource()}.
+ *
+ * @return The one-based index of the line containing the problem or a non-positive value if unknown.
+ */
+ int getLineNumber();
+
+ /**
+ * Gets the one-based index of the column containing the problem. The column number should refer to some text file
+ * that is given by {@link #getSource()}.
+ *
+ * @return The one-based index of the column containing the problem or non-positive value if unknown.
+ */
+ int getColumnNumber();
+
+ /**
+ * Gets the identifier of the model from which the problem originated. While the general form of this identifier is
+ * <code>groupId:artifactId:version</code> the returned identifier need not be complete. The identifier is derived
+ * from the information that is available at the point the problem occurs and as such merely serves as a best effort
+ * to provide information to the user to track the problem back to its origin.
+ *
+ * @return The identifier of the model from which the problem originated or an empty string if unknown, never
+ * {@code null}.
+ */
+ String getModelId();
+
+ /**
+ * Gets the exception that caused this problem (if any).
+ *
+ * @return The exception that caused this problem or {@code null} if not applicable.
+ */
+ Exception getException();
+
+ /**
+ * Gets the message that describes this problem.
+ *
+ * @return The message describing this problem, never {@code null}.
+ */
+ String getMessage();
+
+ /**
+ * Gets the severity level of this problem.
+ *
+ * @return The severity level of this problem, never {@code null}.
+ */
+ Severity getSeverity();
+
+ /**
+ * Gets the applicable maven version/validation level of this problem
+ * @return The version, never {@code null}.
+ */
+ Version getVersion();
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelProblemCollector.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelProblemCollector.java
new file mode 100644
index 00000000..e9561e54
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelProblemCollector.java
@@ -0,0 +1,41 @@
+package org.apache.maven.model.building;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Collects problems that are encountered during model building. The primary purpose of this component is to account for
+ * the fact that the problem reporter has/should not have information about the calling context and hence cannot provide
+ * an expressive source hint for the model problem. Instead, the source hint is configured by the model builder before
+ * it delegates to other components that potentially encounter problems. Then, the problem reporter can focus on
+ * providing a simple error message, leaving the donkey work of creating a nice model problem to this component.
+ *
+ * @author Benjamin Bentmann
+ */
+public interface ModelProblemCollector
+{
+
+ /**
+ * Adds the specified problem.
+ *
+ * @param req must not be null
+ */
+ void add( ModelProblemCollectorRequest req );
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelProblemCollectorExt.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelProblemCollectorExt.java
new file mode 100644
index 00000000..7977d3a6
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelProblemCollectorExt.java
@@ -0,0 +1,37 @@
+package org.apache.maven.model.building;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.List;
+
+/**
+ * Extends the ModelproblemCollector by the capacity of returning the collected problems.
+ * @author Milos Kleint
+ */
+public interface ModelProblemCollectorExt extends ModelProblemCollector
+{
+
+ /**
+ * The collected problems.
+ * @return a list of model problems encountered, never {@code null}
+ */
+ List<ModelProblem> getProblems();
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelProblemCollectorRequest.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelProblemCollectorRequest.java
new file mode 100644
index 00000000..d213cc48
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelProblemCollectorRequest.java
@@ -0,0 +1,101 @@
+package org.apache.maven.model.building;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.model.InputLocation;
+import org.apache.maven.model.building.ModelProblem.Severity;
+import org.apache.maven.model.building.ModelProblem.Version;
+
+/**
+ * Class to wrap request parameters to ModelProblemCollector.addProblem
+ *
+ * @author mkleint
+ */
+public final class ModelProblemCollectorRequest
+{
+
+ private final ModelProblem.Severity severity;
+ private final ModelProblem.Version version;
+ private Exception exception;
+ private String message;
+ private InputLocation location;
+
+ /**
+ * Create a new request with mandatory parameters.
+ * @param severity
+ * @param version
+ */
+ public ModelProblemCollectorRequest( Severity severity, Version version )
+ {
+ this.severity = severity;
+ this.version = version;
+ if ( severity == null )
+ {
+ throw new IllegalStateException( "No severity declared" );
+ }
+ if ( version == null )
+ {
+ throw new IllegalStateException( "No version declared." );
+ }
+ }
+
+ public Severity getSeverity()
+ {
+ return severity;
+ }
+
+ public Version getVersion()
+ {
+ return version;
+ }
+
+ public Exception getException()
+ {
+ return exception;
+ }
+
+ public ModelProblemCollectorRequest setException( Exception exception )
+ {
+ this.exception = exception;
+ return this;
+ }
+
+ public String getMessage()
+ {
+ return message;
+ }
+
+ public ModelProblemCollectorRequest setMessage( String message )
+ {
+ this.message = message;
+ return this;
+ }
+
+ public InputLocation getLocation()
+ {
+ return location;
+ }
+
+ public ModelProblemCollectorRequest setLocation( InputLocation location )
+ {
+ this.location = location;
+ return this;
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelProblemUtils.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelProblemUtils.java
new file mode 100644
index 00000000..806c28d4
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelProblemUtils.java
@@ -0,0 +1,171 @@
+package org.apache.maven.model.building;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+
+import org.apache.maven.model.Model;
+
+/**
+ * Assists in the handling of model problems.
+ *
+ * @author Benjamin Bentmann
+ */
+public class ModelProblemUtils
+{
+
+ /**
+ * Creates a user-friendly source hint for the specified model.
+ *
+ * @param model The model to create a source hint for, may be {@code null}.
+ * @return The user-friendly source hint, never {@code null}.
+ */
+ static String toSourceHint( Model model )
+ {
+ if ( model == null )
+ {
+ return "";
+ }
+
+ StringBuilder buffer = new StringBuilder( 192 );
+
+ buffer.append( toId( model ) );
+
+ File pomFile = model.getPomFile();
+ if ( pomFile != null )
+ {
+ buffer.append( " (" ).append( pomFile ).append( ")" );
+ }
+
+ return buffer.toString();
+ }
+
+ static String toPath( Model model )
+ {
+ String path = "";
+
+ if ( model != null )
+ {
+ File pomFile = model.getPomFile();
+
+ if ( pomFile != null )
+ {
+ path = pomFile.getAbsolutePath();
+ }
+ }
+
+ return path;
+ }
+
+ static String toId( Model model )
+ {
+ if ( model == null )
+ {
+ return "";
+ }
+
+ String groupId = model.getGroupId();
+ if ( groupId == null && model.getParent() != null )
+ {
+ groupId = model.getParent().getGroupId();
+ }
+
+ String artifactId = model.getArtifactId();
+
+ String version = model.getVersion();
+ if ( version == null )
+ {
+ version = "[unknown-version]";
+ }
+
+ return toId( groupId, artifactId, version );
+ }
+
+ /**
+ * Creates a user-friendly artifact id from the specified coordinates.
+ *
+ * @param groupId The group id, may be {@code null}.
+ * @param artifactId The artifact id, may be {@code null}.
+ * @param version The version, may be {@code null}.
+ * @return The user-friendly artifact id, never {@code null}.
+ */
+ static String toId( String groupId, String artifactId, String version )
+ {
+ StringBuilder buffer = new StringBuilder( 96 );
+
+ buffer.append( ( groupId != null && groupId.length() > 0 ) ? groupId : "[unknown-group-id]" );
+ buffer.append( ':' );
+ buffer.append( ( artifactId != null && artifactId.length() > 0 ) ? artifactId : "[unknown-artifact-id]" );
+ buffer.append( ':' );
+ buffer.append( ( version != null && version.length() > 0 ) ? version : "[unknown-version]" );
+
+ return buffer.toString();
+ }
+
+ /**
+ * Creates a string with all location details for the specified model problem. If the project identifier is
+ * provided, the generated location will omit the model id and source information and only give line/column
+ * information for problems originating directly from this POM.
+ *
+ * @param problem The problem whose location should be formatted, must not be {@code null}.
+ * @param projectId The {@code <groupId>:<artifactId>:<version>} of the corresponding project, may be {@code null}
+ * to force output of model id and source.
+ * @return The formatted problem location or an empty string if unknown, never {@code null}.
+ */
+ public static String formatLocation( ModelProblem problem, String projectId )
+ {
+ StringBuilder buffer = new StringBuilder( 256 );
+
+ if ( !problem.getModelId().equals( projectId ) )
+ {
+ buffer.append( problem.getModelId() );
+
+ if ( problem.getSource().length() > 0 )
+ {
+ if ( buffer.length() > 0 )
+ {
+ buffer.append( ", " );
+ }
+ buffer.append( problem.getSource() );
+ }
+ }
+
+ if ( problem.getLineNumber() > 0 )
+ {
+ if ( buffer.length() > 0 )
+ {
+ buffer.append( ", " );
+ }
+ buffer.append( "line " ).append( problem.getLineNumber() );
+ }
+
+ if ( problem.getColumnNumber() > 0 )
+ {
+ if ( buffer.length() > 0 )
+ {
+ buffer.append( ", " );
+ }
+ buffer.append( "column " ).append( problem.getColumnNumber() );
+ }
+
+ return buffer.toString();
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelProcessor.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelProcessor.java
new file mode 100644
index 00000000..ca34845c
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelProcessor.java
@@ -0,0 +1,32 @@
+package org.apache.maven.model.building;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.model.io.ModelReader;
+import org.apache.maven.model.locator.ModelLocator;
+
+@SuppressWarnings( "checkstyle:interfaceistype" )
+public interface ModelProcessor
+ extends ModelLocator, ModelReader
+{
+
+ String SOURCE = "org.apache.maven.model.building.source";
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelSource.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelSource.java
new file mode 100644
index 00000000..5db8edba
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelSource.java
@@ -0,0 +1,38 @@
+package org.apache.maven.model.building;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.building.Source;
+
+/**
+ * Provides access to the contents of a POM independently of the backing store (e.g. file system, database, memory).
+ * <p>
+ * This interface does not support loading of parent POM(s) from the same backing store, integrators are strongly
+ * encouraged to implement {@link ModelSource2} instead of implementing this interface directly.
+ *
+ * @author Benjamin Bentmann
+ * @see ModelSource2
+ * @deprecated instead use {@link Source}
+ */
+@Deprecated
+public interface ModelSource extends Source
+{
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelSource2.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelSource2.java
new file mode 100644
index 00000000..3e123d08
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelSource2.java
@@ -0,0 +1,56 @@
+package org.apache.maven.model.building;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.net.URI;
+
+/**
+ * Provides access to the contents of a POM independently of the backing store (e.g. file system, database, memory).
+ * <p>
+ * Unlike {@link ModelSource}, this interface supports loading of parent POM(s) from the same backing store and allows
+ * construction of MavenProject instances without the need to have parent POM(s) available from local or remote
+ * repositories.
+ * <p>
+ * ModelSource2 instances are cached in {@link ModelBuildingRequest#getModelCache()}. Implementations must guarantee
+ * that the connection to the backing store remains active until request's {@link ModelCache} is discarded or flushed.
+ */
+public interface ModelSource2
+ extends ModelSource
+{
+ /**
+ * Returns model source identified by a path relative to this model source POM. Implementation <strong>MUST</strong>
+ * be able to accept <code>relPath</code> parameter values that
+ * <ul>
+ * <li>use either / or \ file path separator</li>
+ * <li>have .. parent directory references</li>
+ * <li>point either at file or directory, in the latter case POM file name 'pom.xml' needs to be used by the
+ * requested model source.</li>
+ * </ul>
+ *
+ * @param relPath is the path of the requested model source relative to this model source POM.
+ * @return related model source or <code>null</code> if no such model source.
+ */
+ ModelSource2 getRelatedSource( String relPath );
+
+ /**
+ * Returns location of the POM, never <code>null</code>.
+ */
+ URI getLocationURI();
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/Result.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/Result.java
new file mode 100644
index 00000000..a9628977
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/Result.java
@@ -0,0 +1,255 @@
+package org.apache.maven.model.building;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import static com.google.common.base.Predicates.in;
+import static com.google.common.collect.Iterables.any;
+import static com.google.common.collect.Iterables.concat;
+import static com.google.common.collect.Iterables.transform;
+import static java.util.Collections.singleton;
+import static java.util.EnumSet.of;
+import static org.apache.maven.model.building.ModelProblem.Severity.ERROR;
+import static org.apache.maven.model.building.ModelProblem.Severity.FATAL;
+
+import java.util.Arrays;
+import java.util.Collections;
+
+import org.apache.maven.model.building.ModelProblem.Severity;
+
+import com.google.common.base.Function;
+import com.google.common.base.Predicates;
+import com.google.common.collect.Iterables;
+
+/**
+ * There are various forms of results that are represented by this class:
+ * <ol>
+ * <li>success - in which case only the model field is set
+ * <li>success with warnings - model field + non-error model problems
+ * <li>error - no model, but diagnostics
+ * <li>error - (partial) model and diagnostics
+ * </ol>
+ * Could encode these variants as subclasses, but kept in one for now
+ *
+ * @author bbusjaeger
+ * @param <T>
+ */
+public class Result<T>
+{
+
+ /**
+ * Success without warnings
+ *
+ * @param model
+ * @return
+ */
+ public static <T> Result<T> success( T model )
+ {
+ return success( model, Collections.<ModelProblem>emptyList() );
+ }
+
+ /**
+ * Success with warnings
+ *
+ * @param model
+ * @param problems
+ * @return
+ */
+ public static <T> Result<T> success( T model, Iterable<? extends ModelProblem> problems )
+ {
+ assert !hasErrors( problems );
+ return new Result<T>( false, model, problems );
+ }
+
+ /**
+ * Success with warnings
+ *
+ * @param model
+ * @param results
+ * @return
+ */
+ public static <T> Result<T> success( T model, Result<?>... results )
+ {
+ return success( model, Iterables.concat( Iterables.transform( Arrays.asList( results ), GET_PROBLEMS ) ) );
+ }
+
+ /**
+ * Error with problems describing the cause
+ *
+ * @param problems
+ * @return
+ */
+ public static <T> Result<T> error( Iterable<? extends ModelProblem> problems )
+ {
+ return error( null, problems );
+ }
+
+ public static <T> Result<T> error( T model )
+ {
+ return error( model, Collections.<ModelProblem>emptyList() );
+ }
+
+ public static <T> Result<T> error( Result<?> result )
+ {
+ return error( result.getProblems() );
+ }
+
+ public static <T> Result<T> error( Result<?>... results )
+ {
+ return error( Iterables.concat( Iterables.transform( Arrays.asList( results ), GET_PROBLEMS ) ) );
+ }
+
+ /**
+ * Error with partial result and problems describing the cause
+ *
+ * @param model
+ * @param problems
+ * @return
+ */
+ public static <T> Result<T> error( T model, Iterable<? extends ModelProblem> problems )
+ {
+ return new Result<T>( true, model, problems );
+ }
+
+ /**
+ * New result - determine whether error or success by checking problems for errors
+ *
+ * @param model
+ * @param problems
+ * @return
+ */
+ public static <T> Result<T> newResult( T model, Iterable<? extends ModelProblem> problems )
+ {
+ return new Result<T>( hasErrors( problems ), model, problems );
+ }
+
+ /**
+ * New result consisting of given result and new problem. Convenience for newResult(result.get(),
+ * concat(result.getProblems(),problems)).
+ *
+ * @param result
+ * @param problem
+ * @return
+ */
+ public static <T> Result<T> addProblem( Result<T> result, ModelProblem problem )
+ {
+ return addProblems( result, singleton( problem ) );
+ }
+
+ /**
+ * New result that includes the given
+ *
+ * @param result
+ * @param problems
+ * @return
+ */
+ public static <T> Result<T> addProblems( Result<T> result, Iterable<? extends ModelProblem> problems )
+ {
+ return new Result<T>( result.hasErrors() || hasErrors( problems ), result.get(), concat( result.getProblems(),
+ problems ) );
+ }
+
+ public static <T> Result<T> addProblems( Result<T> result, Result<?>... results )
+ {
+ return addProblems( result, Iterables.concat( Iterables.transform( Arrays.asList( results ), GET_PROBLEMS ) ) );
+ }
+
+ /**
+ * Turns the given results into a single result by combining problems and models into single collection.
+ *
+ * @param results
+ * @return
+ */
+ public static <T> Result<Iterable<T>> newResultSet( Iterable<? extends Result<? extends T>> results )
+ {
+ final boolean hasErrors = any( transform( results, new Function<Result<?>, Boolean>()
+ {
+ @Override
+ public Boolean apply( Result<?> input )
+ {
+ return input.hasErrors();
+ }
+ } ), Predicates.equalTo( true ) );
+ final Iterable<T> models = transform( results, new Function<Result<? extends T>, T>()
+ {
+ @Override
+ public T apply( Result<? extends T> input )
+ {
+ return input.get();
+ }
+ } );
+ final Iterable<ModelProblem> problems = concat( transform( results, GET_PROBLEMS ) );
+ return new Result<Iterable<T>>( hasErrors, models, problems );
+ }
+
+ // helper to determine if problems contain error
+ private static boolean hasErrors( Iterable<? extends ModelProblem> problems )
+ {
+ return any( transform( problems, new Function<ModelProblem, Severity>()
+ {
+ @Override
+ public Severity apply( ModelProblem input )
+ {
+ return input.getSeverity();
+ }
+ } ), in( of( ERROR, FATAL ) ) );
+ }
+
+ /**
+ * Class definition
+ */
+
+ private final boolean errors;
+
+ private final T value;
+
+ private final Iterable<? extends ModelProblem> problems;
+
+ private Result( boolean errors, T model, Iterable<? extends ModelProblem> problems )
+ {
+ this.errors = errors;
+ this.value = model;
+ this.problems = problems;
+ }
+
+ public Iterable<? extends ModelProblem> getProblems()
+ {
+ return problems;
+ }
+
+ public T get()
+ {
+ return value;
+ }
+
+ public boolean hasErrors()
+ {
+ return errors;
+ }
+
+ private static final Function<Result<?>, Iterable<? extends ModelProblem>> GET_PROBLEMS =
+ new Function<Result<?>, Iterable<? extends ModelProblem>>()
+ {
+ @Override
+ public Iterable<? extends ModelProblem> apply( Result<?> input )
+ {
+ return input.getProblems();
+ }
+ };
+} \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/StringModelSource.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/StringModelSource.java
new file mode 100644
index 00000000..cf9c4ce1
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/StringModelSource.java
@@ -0,0 +1,56 @@
+package org.apache.maven.model.building;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.building.StringSource;
+
+/**
+ * Wraps an ordinary {@link CharSequence} as a model source.
+ *
+ * @author Benjamin Bentmann
+ *
+ * @deprecated instead use {@link StringSource}
+ */
+@Deprecated
+public class StringModelSource extends StringSource
+ implements ModelSource
+{
+
+ /**
+ * Creates a new model source backed by the specified string.
+ *
+ * @param pom The POM's string representation, may be empty or {@code null}.
+ */
+ public StringModelSource( CharSequence pom )
+ {
+ this( pom, null );
+ }
+
+ /**
+ * Creates a new model source backed by the specified string.
+ *
+ * @param pom The POM's string representation, may be empty or {@code null}.
+ * @param location The location to report for this use, may be {@code null}.
+ */
+ public StringModelSource( CharSequence pom, String location )
+ {
+ super( pom, location );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/UrlModelSource.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/UrlModelSource.java
new file mode 100644
index 00000000..e41d74b3
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/building/UrlModelSource.java
@@ -0,0 +1,46 @@
+package org.apache.maven.model.building;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.net.URL;
+
+import org.apache.maven.building.UrlSource;
+
+/**
+ * Wraps an ordinary {@link URL} as a model source.
+ *
+ * @author Benjamin Bentmann
+ *
+ * @deprecated instead use {@link UrlSource}
+ */
+@Deprecated
+public class UrlModelSource extends UrlSource
+ implements ModelSource
+{
+ /**
+ * Creates a new model source backed by the specified URL.
+ *
+ * @param pomUrl The POM file, must not be {@code null}.
+ */
+ public UrlModelSource( URL pomUrl )
+ {
+ super( pomUrl );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/composition/DefaultDependencyManagementImporter.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/composition/DefaultDependencyManagementImporter.java
new file mode 100644
index 00000000..5860af65
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/composition/DefaultDependencyManagementImporter.java
@@ -0,0 +1,83 @@
+package org.apache.maven.model.composition;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.maven.model.Dependency;
+import org.apache.maven.model.DependencyManagement;
+import org.apache.maven.model.Model;
+import org.apache.maven.model.building.ModelBuildingRequest;
+import org.apache.maven.model.building.ModelProblemCollector;
+import org.codehaus.plexus.component.annotations.Component;
+
+/**
+ * Handles the import of dependency management from other models into the target model.
+ *
+ * @author Benjamin Bentmann
+ */
+@Component( role = DependencyManagementImporter.class )
+public class DefaultDependencyManagementImporter
+ implements DependencyManagementImporter
+{
+
+ @Override
+ public void importManagement( Model target, List<? extends DependencyManagement> sources,
+ ModelBuildingRequest request, ModelProblemCollector problems )
+ {
+ if ( sources != null && !sources.isEmpty() )
+ {
+ Map<String, Dependency> dependencies = new LinkedHashMap<String, Dependency>();
+
+ DependencyManagement depMngt = target.getDependencyManagement();
+
+ if ( depMngt != null )
+ {
+ for ( Dependency dependency : depMngt.getDependencies() )
+ {
+ dependencies.put( dependency.getManagementKey(), dependency );
+ }
+ }
+ else
+ {
+ depMngt = new DependencyManagement();
+ target.setDependencyManagement( depMngt );
+ }
+
+ for ( DependencyManagement source : sources )
+ {
+ for ( Dependency dependency : source.getDependencies() )
+ {
+ String key = dependency.getManagementKey();
+ if ( !dependencies.containsKey( key ) )
+ {
+ dependencies.put( key, dependency );
+ }
+ }
+ }
+
+ depMngt.setDependencies( new ArrayList<Dependency>( dependencies.values() ) );
+ }
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/composition/DependencyManagementImporter.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/composition/DependencyManagementImporter.java
new file mode 100644
index 00000000..06496429
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/composition/DependencyManagementImporter.java
@@ -0,0 +1,48 @@
+package org.apache.maven.model.composition;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.List;
+
+import org.apache.maven.model.DependencyManagement;
+import org.apache.maven.model.Model;
+import org.apache.maven.model.building.ModelBuildingRequest;
+import org.apache.maven.model.building.ModelProblemCollector;
+
+/**
+ * Handles the import of dependency management from other models into the target model.
+ *
+ * @author Benjamin Bentmann
+ */
+public interface DependencyManagementImporter
+{
+
+ /**
+ * Imports the specified dependency management sections into the given target model.
+ *
+ * @param target The model into which to import the dependency management section, must not be <code>null</code>.
+ * @param sources The dependency management sections to import, may be <code>null</code>.
+ * @param request The model building request that holds further settings, must not be {@code null}.
+ * @param problems The container used to collect problems that were encountered, must not be {@code null}.
+ */
+ void importManagement( Model target, List<? extends DependencyManagement> sources, ModelBuildingRequest request,
+ ModelProblemCollector problems );
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/inheritance/DefaultInheritanceAssembler.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/inheritance/DefaultInheritanceAssembler.java
new file mode 100644
index 00000000..609f441e
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/inheritance/DefaultInheritanceAssembler.java
@@ -0,0 +1,255 @@
+package org.apache.maven.model.inheritance;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.maven.model.Model;
+import org.apache.maven.model.Plugin;
+import org.apache.maven.model.PluginContainer;
+import org.apache.maven.model.ReportPlugin;
+import org.apache.maven.model.Reporting;
+import org.apache.maven.model.building.ModelBuildingRequest;
+import org.apache.maven.model.building.ModelProblemCollector;
+import org.apache.maven.model.merge.MavenModelMerger;
+import org.codehaus.plexus.component.annotations.Component;
+
+/**
+ * Handles inheritance of model values.
+ *
+ * @author Benjamin Bentmann
+ */
+@Component( role = InheritanceAssembler.class )
+public class DefaultInheritanceAssembler
+ implements InheritanceAssembler
+{
+
+ private InheritanceModelMerger merger = new InheritanceModelMerger();
+
+ @Override
+ public void assembleModelInheritance( Model child, Model parent, ModelBuildingRequest request,
+ ModelProblemCollector problems )
+ {
+ Map<Object, Object> hints = new HashMap<Object, Object>();
+ hints.put( MavenModelMerger.CHILD_PATH_ADJUSTMENT, getChildPathAdjustment( child, parent ) );
+ merger.merge( child, parent, false, hints );
+ }
+
+ /**
+ * Calculates the relative path from the base directory of the parent to the parent directory of the base directory
+ * of the child. The general idea is to adjust inherited URLs to match the project layout (in SCM).
+ *
+ * <p>This calculation is only a heuristic based on our conventions.
+ * In detail, the algo relies on the following assumptions: <ul>
+ * <li>The parent uses aggregation and refers to the child via the modules section</li>
+ * <li>The module path to the child is considered to
+ * point at the POM rather than its base directory if the path ends with ".xml" (ignoring case)</li>
+ * <li>The name of the child's base directory matches the artifact id of the child.</li>
+ * </ul>
+ * Note that for the sake of independence from the user
+ * environment, the filesystem is intentionally not used for the calculation.</p>
+ *
+ * @param child The child model, must not be <code>null</code>.
+ * @param parent The parent model, may be <code>null</code>.
+ * @return The path adjustment, can be empty but never <code>null</code>.
+ */
+ private String getChildPathAdjustment( Model child, Model parent )
+ {
+ String adjustment = "";
+
+ if ( parent != null )
+ {
+ String childName = child.getArtifactId();
+
+ /*
+ * This logic exists only for the sake of backward-compat with 2.x (MNG-5000). In generally, it is wrong to
+ * base URL inheritance on the project directory names as this information is unavailable for POMs in the
+ * repository. In other words, projects where artifactId != projectDirName will see different effective URLs
+ * depending on how the POM was constructed.
+ */
+ File childDirectory = child.getProjectDirectory();
+ if ( childDirectory != null )
+ {
+ childName = childDirectory.getName();
+ }
+
+ for ( String module : parent.getModules() )
+ {
+ module = module.replace( '\\', '/' );
+
+ if ( module.regionMatches( true, module.length() - 4, ".xml", 0, 4 ) )
+ {
+ module = module.substring( 0, module.lastIndexOf( '/' ) + 1 );
+ }
+
+ String moduleName = module;
+ if ( moduleName.endsWith( "/" ) )
+ {
+ moduleName = moduleName.substring( 0, moduleName.length() - 1 );
+ }
+
+ int lastSlash = moduleName.lastIndexOf( '/' );
+
+ moduleName = moduleName.substring( lastSlash + 1 );
+
+ if ( moduleName.equals( childName ) && lastSlash >= 0 )
+ {
+ adjustment = module.substring( 0, lastSlash );
+ break;
+ }
+ }
+ }
+
+ return adjustment;
+ }
+
+ protected static class InheritanceModelMerger
+ extends MavenModelMerger
+ {
+
+ @Override
+ protected void mergePluginContainer_Plugins( PluginContainer target, PluginContainer source,
+ boolean sourceDominant, Map<Object, Object> context )
+ {
+ List<Plugin> src = source.getPlugins();
+ if ( !src.isEmpty() )
+ {
+ List<Plugin> tgt = target.getPlugins();
+ Map<Object, Plugin> master = new LinkedHashMap<Object, Plugin>( src.size() * 2 );
+
+ for ( Plugin element : src )
+ {
+ if ( element.isInherited() || !element.getExecutions().isEmpty() )
+ {
+ // NOTE: Enforce recursive merge to trigger merging/inheritance logic for executions
+ Plugin plugin = new Plugin();
+ plugin.setLocation( "", element.getLocation( "" ) );
+ plugin.setGroupId( null );
+ mergePlugin( plugin, element, sourceDominant, context );
+
+ Object key = getPluginKey( element );
+
+ master.put( key, plugin );
+ }
+ }
+
+ Map<Object, List<Plugin>> predecessors = new LinkedHashMap<Object, List<Plugin>>();
+ List<Plugin> pending = new ArrayList<Plugin>();
+ for ( Plugin element : tgt )
+ {
+ Object key = getPluginKey( element );
+ Plugin existing = master.get( key );
+ if ( existing != null )
+ {
+ mergePlugin( element, existing, sourceDominant, context );
+
+ master.put( key, element );
+
+ if ( !pending.isEmpty() )
+ {
+ predecessors.put( key, pending );
+ pending = new ArrayList<Plugin>();
+ }
+ }
+ else
+ {
+ pending.add( element );
+ }
+ }
+
+ List<Plugin> result = new ArrayList<Plugin>( src.size() + tgt.size() );
+ for ( Map.Entry<Object, Plugin> entry : master.entrySet() )
+ {
+ List<Plugin> pre = predecessors.get( entry.getKey() );
+ if ( pre != null )
+ {
+ result.addAll( pre );
+ }
+ result.add( entry.getValue() );
+ }
+ result.addAll( pending );
+
+ target.setPlugins( result );
+ }
+ }
+
+ @Override
+ protected void mergePlugin( Plugin target, Plugin source, boolean sourceDominant, Map<Object, Object> context )
+ {
+ if ( source.isInherited() )
+ {
+ mergeConfigurationContainer( target, source, sourceDominant, context );
+ }
+ mergePlugin_GroupId( target, source, sourceDominant, context );
+ mergePlugin_ArtifactId( target, source, sourceDominant, context );
+ mergePlugin_Version( target, source, sourceDominant, context );
+ mergePlugin_Extensions( target, source, sourceDominant, context );
+ mergePlugin_Dependencies( target, source, sourceDominant, context );
+ mergePlugin_Executions( target, source, sourceDominant, context );
+ }
+
+ @Override
+ protected void mergeReporting_Plugins( Reporting target, Reporting source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ List<ReportPlugin> src = source.getPlugins();
+ if ( !src.isEmpty() )
+ {
+ List<ReportPlugin> tgt = target.getPlugins();
+ Map<Object, ReportPlugin> merged =
+ new LinkedHashMap<Object, ReportPlugin>( ( src.size() + tgt.size() ) * 2 );
+
+ for ( ReportPlugin element : src )
+ {
+ Object key = getReportPluginKey( element );
+ if ( element.isInherited() )
+ {
+ // NOTE: Enforce recursive merge to trigger merging/inheritance logic for executions as well
+ ReportPlugin plugin = new ReportPlugin();
+ plugin.setLocation( "", element.getLocation( "" ) );
+ plugin.setGroupId( null );
+ mergeReportPlugin( plugin, element, sourceDominant, context );
+
+ merged.put( key, plugin );
+ }
+ }
+
+ for ( ReportPlugin element : tgt )
+ {
+ Object key = getReportPluginKey( element );
+ ReportPlugin existing = merged.get( key );
+ if ( existing != null )
+ {
+ mergeReportPlugin( element, existing, sourceDominant, context );
+ }
+ merged.put( key, element );
+ }
+
+ target.setPlugins( new ArrayList<ReportPlugin>( merged.values() ) );
+ }
+ }
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/inheritance/InheritanceAssembler.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/inheritance/InheritanceAssembler.java
new file mode 100644
index 00000000..a191e52d
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/inheritance/InheritanceAssembler.java
@@ -0,0 +1,48 @@
+package org.apache.maven.model.inheritance;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.model.Model;
+import org.apache.maven.model.building.ModelBuildingRequest;
+import org.apache.maven.model.building.ModelProblemCollector;
+
+/**
+ * Handles inheritance of model values.
+ *
+ * @author Benjamin Bentmann
+ */
+public interface InheritanceAssembler
+{
+
+ /**
+ * Merges values from the specified parent model into the given child model. Implementations are expected to keep
+ * parent and child completely decoupled by injecting deep copies of objects into the child rather than the original
+ * objects from the parent.
+ *
+ * @param child The child model into which to merge the values inherited from the parent, must not be
+ * <code>null</code>.
+ * @param parent The (read-only) parent model from which to inherit the values, may be <code>null</code>.
+ * @param request The model building request that holds further settings, must not be {@code null}.
+ * @param problems The container used to collect problems that were encountered, must not be {@code null}.
+ */
+ void assembleModelInheritance( Model child, Model parent, ModelBuildingRequest request,
+ ModelProblemCollector problems );
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/AbstractStringBasedModelInterpolator.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/AbstractStringBasedModelInterpolator.java
new file mode 100644
index 00000000..1390a4ed
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/AbstractStringBasedModelInterpolator.java
@@ -0,0 +1,271 @@
+package org.apache.maven.model.interpolation;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Properties;
+
+import org.apache.maven.model.Model;
+import org.apache.maven.model.building.ModelBuildingRequest;
+import org.apache.maven.model.building.ModelProblem.Severity;
+import org.apache.maven.model.building.ModelProblem.Version;
+import org.apache.maven.model.building.ModelProblemCollector;
+import org.apache.maven.model.building.ModelProblemCollectorRequest;
+import org.apache.maven.model.path.PathTranslator;
+import org.apache.maven.model.path.UrlNormalizer;
+import org.codehaus.plexus.component.annotations.Requirement;
+import org.codehaus.plexus.interpolation.AbstractValueSource;
+import org.codehaus.plexus.interpolation.InterpolationException;
+import org.codehaus.plexus.interpolation.InterpolationPostProcessor;
+import org.codehaus.plexus.interpolation.Interpolator;
+import org.codehaus.plexus.interpolation.MapBasedValueSource;
+import org.codehaus.plexus.interpolation.ObjectBasedValueSource;
+import org.codehaus.plexus.interpolation.PrefixAwareRecursionInterceptor;
+import org.codehaus.plexus.interpolation.PrefixedObjectValueSource;
+import org.codehaus.plexus.interpolation.PrefixedValueSourceWrapper;
+import org.codehaus.plexus.interpolation.RecursionInterceptor;
+import org.codehaus.plexus.interpolation.ValueSource;
+
+/**
+ * Use a regular expression search to find and resolve expressions within the POM.
+ *
+ * @author jdcasey Created on Feb 3, 2005
+ */
+public abstract class AbstractStringBasedModelInterpolator
+ implements ModelInterpolator
+{
+ private static final List<String> PROJECT_PREFIXES = Arrays.asList( "pom.", "project." );
+
+ private static final Collection<String> TRANSLATED_PATH_EXPRESSIONS;
+
+ static
+ {
+ Collection<String> translatedPrefixes = new HashSet<String>();
+
+ // MNG-1927, MNG-2124, MNG-3355:
+ // If the build section is present and the project directory is non-null, we should make
+ // sure interpolation of the directories below uses translated paths.
+ // Afterward, we'll double back and translate any paths that weren't covered during interpolation via the
+ // code below...
+ translatedPrefixes.add( "build.directory" );
+ translatedPrefixes.add( "build.outputDirectory" );
+ translatedPrefixes.add( "build.testOutputDirectory" );
+ translatedPrefixes.add( "build.sourceDirectory" );
+ translatedPrefixes.add( "build.testSourceDirectory" );
+ translatedPrefixes.add( "build.scriptSourceDirectory" );
+ translatedPrefixes.add( "reporting.outputDirectory" );
+
+ TRANSLATED_PATH_EXPRESSIONS = translatedPrefixes;
+ }
+
+ @Requirement
+ private PathTranslator pathTranslator;
+
+ @Requirement
+ private UrlNormalizer urlNormalizer;
+
+ private Interpolator interpolator;
+
+ private RecursionInterceptor recursionInterceptor;
+
+ public AbstractStringBasedModelInterpolator()
+ {
+ interpolator = createInterpolator();
+ recursionInterceptor = new PrefixAwareRecursionInterceptor( PROJECT_PREFIXES );
+ }
+
+ public AbstractStringBasedModelInterpolator setPathTranslator( PathTranslator pathTranslator )
+ {
+ this.pathTranslator = pathTranslator;
+ return this;
+ }
+
+ public AbstractStringBasedModelInterpolator setUrlNormalizer( UrlNormalizer urlNormalizer )
+ {
+ this.urlNormalizer = urlNormalizer;
+ return this;
+ }
+
+ protected List<ValueSource> createValueSources( final Model model, final File projectDir,
+ final ModelBuildingRequest config,
+ final ModelProblemCollector problems )
+ {
+ Properties modelProperties = model.getProperties();
+
+ ValueSource modelValueSource1 = new PrefixedObjectValueSource( PROJECT_PREFIXES, model, false );
+ if ( config.getValidationLevel() >= ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_2_0 )
+ {
+ modelValueSource1 = new ProblemDetectingValueSource( modelValueSource1, "pom.", "project.", problems );
+ }
+
+ ValueSource modelValueSource2 = new ObjectBasedValueSource( model );
+ if ( config.getValidationLevel() >= ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_2_0 )
+ {
+ modelValueSource2 = new ProblemDetectingValueSource( modelValueSource2, "", "project.", problems );
+ }
+
+ // NOTE: Order counts here!
+ List<ValueSource> valueSources = new ArrayList<ValueSource>( 9 );
+
+ if ( projectDir != null )
+ {
+ ValueSource basedirValueSource = new PrefixedValueSourceWrapper( new AbstractValueSource( false )
+ {
+ @Override
+ public Object getValue( String expression )
+ {
+ if ( "basedir".equals( expression ) )
+ {
+ return projectDir.getAbsolutePath();
+ }
+ return null;
+ }
+ }, PROJECT_PREFIXES, true );
+ valueSources.add( basedirValueSource );
+
+ ValueSource baseUriValueSource = new PrefixedValueSourceWrapper( new AbstractValueSource( false )
+ {
+ @Override
+ public Object getValue( String expression )
+ {
+ if ( "baseUri".equals( expression ) )
+ {
+ return projectDir.getAbsoluteFile().toURI().toString();
+ }
+ return null;
+ }
+ }, PROJECT_PREFIXES, false );
+ valueSources.add( baseUriValueSource );
+ valueSources.add( new BuildTimestampValueSource( config.getBuildStartTime(), modelProperties ) );
+ }
+
+ valueSources.add( modelValueSource1 );
+
+ valueSources.add( new MapBasedValueSource( config.getUserProperties() ) );
+
+ valueSources.add( new MapBasedValueSource( modelProperties ) );
+
+ valueSources.add( new MapBasedValueSource( config.getSystemProperties() ) );
+
+ valueSources.add( new AbstractValueSource( false )
+ {
+ @Override
+ public Object getValue( String expression )
+ {
+ return config.getSystemProperties().getProperty( "env." + expression );
+ }
+ } );
+
+ valueSources.add( modelValueSource2 );
+
+ return valueSources;
+ }
+
+ protected List<? extends InterpolationPostProcessor> createPostProcessors( final Model model,
+ final File projectDir,
+ final ModelBuildingRequest config )
+ {
+ List<InterpolationPostProcessor> processors = new ArrayList<InterpolationPostProcessor>( 2 );
+ if ( projectDir != null )
+ {
+ processors.add( new PathTranslatingPostProcessor( PROJECT_PREFIXES, TRANSLATED_PATH_EXPRESSIONS,
+ projectDir, pathTranslator ) );
+ }
+ processors.add( new UrlNormalizingPostProcessor( urlNormalizer ) );
+ return processors;
+ }
+
+ protected String interpolateInternal( String src, List<? extends ValueSource> valueSources,
+ List<? extends InterpolationPostProcessor> postProcessors,
+ ModelProblemCollector problems )
+ {
+ if ( !src.contains( "${" ) )
+ {
+ return src;
+ }
+
+ String result = src;
+ synchronized ( this )
+ {
+
+ for ( ValueSource vs : valueSources )
+ {
+ interpolator.addValueSource( vs );
+ }
+
+ for ( InterpolationPostProcessor postProcessor : postProcessors )
+ {
+ interpolator.addPostProcessor( postProcessor );
+ }
+
+ try
+ {
+ try
+ {
+ result = interpolator.interpolate( result, recursionInterceptor );
+ }
+ catch ( InterpolationException e )
+ {
+ problems.add( new ModelProblemCollectorRequest( Severity.ERROR, Version.BASE )
+ .setMessage( e.getMessage() ).setException( e ) );
+ }
+
+ interpolator.clearFeedback();
+ }
+ finally
+ {
+ for ( ValueSource vs : valueSources )
+ {
+ interpolator.removeValuesSource( vs );
+ }
+
+ for ( InterpolationPostProcessor postProcessor : postProcessors )
+ {
+ interpolator.removePostProcessor( postProcessor );
+ }
+ }
+ }
+
+ return result;
+ }
+
+ protected RecursionInterceptor getRecursionInterceptor()
+ {
+ return recursionInterceptor;
+ }
+
+ protected void setRecursionInterceptor( RecursionInterceptor recursionInterceptor )
+ {
+ this.recursionInterceptor = recursionInterceptor;
+ }
+
+ protected abstract Interpolator createInterpolator();
+
+ protected final Interpolator getInterpolator()
+ {
+ return interpolator;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/BuildTimestampValueSource.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/BuildTimestampValueSource.java
new file mode 100644
index 00000000..30809b85
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/BuildTimestampValueSource.java
@@ -0,0 +1,47 @@
+package org.apache.maven.model.interpolation;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Date;
+import java.util.Properties;
+
+import org.codehaus.plexus.interpolation.AbstractValueSource;
+
+class BuildTimestampValueSource
+ extends AbstractValueSource
+{
+ private final MavenBuildTimestamp mavenBuildTimestamp;
+
+ public BuildTimestampValueSource( Date startTime, Properties properties )
+ {
+ super( false );
+ this.mavenBuildTimestamp = new MavenBuildTimestamp( startTime, properties );
+ }
+
+ @Override
+ public Object getValue( String expression )
+ {
+ if ( "build.timestamp".equals( expression ) || "maven.build.timestamp".equals( expression ) )
+ {
+ return mavenBuildTimestamp.formattedTimestamp();
+ }
+ return null;
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/MavenBuildTimestamp.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/MavenBuildTimestamp.java
new file mode 100644
index 00000000..447f0efe
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/MavenBuildTimestamp.java
@@ -0,0 +1,70 @@
+package org.apache.maven.model.interpolation;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Properties;
+import java.util.TimeZone;
+
+public class MavenBuildTimestamp
+{
+ // ISO 8601-compliant timestamp for machine readability
+ public static final String DEFAULT_BUILD_TIMESTAMP_FORMAT = "yyyy-MM-dd'T'HH:mm:ss'Z'";
+
+ public static final String BUILD_TIMESTAMP_FORMAT_PROPERTY = "maven.build.timestamp.format";
+
+ private String formattedTimestamp;
+
+ public MavenBuildTimestamp()
+ {
+ this( new Date() );
+ }
+
+ public MavenBuildTimestamp( Date time )
+ {
+ this( time, DEFAULT_BUILD_TIMESTAMP_FORMAT );
+ }
+
+ public MavenBuildTimestamp( Date time, Properties properties )
+ {
+ this( time, properties != null ? properties.getProperty( BUILD_TIMESTAMP_FORMAT_PROPERTY ) : null );
+ }
+
+ public MavenBuildTimestamp( Date time, String timestampFormat )
+ {
+ if ( timestampFormat == null )
+ {
+ timestampFormat = DEFAULT_BUILD_TIMESTAMP_FORMAT;
+ }
+ if ( time == null )
+ {
+ time = new Date();
+ }
+ SimpleDateFormat dateFormat = new SimpleDateFormat( timestampFormat );
+ dateFormat.setTimeZone( TimeZone.getTimeZone( "UTC" ) );
+ formattedTimestamp = dateFormat.format( time );
+ }
+
+ public String formattedTimestamp()
+ {
+ return formattedTimestamp;
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/ModelInterpolator.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/ModelInterpolator.java
new file mode 100644
index 00000000..d2b01c1d
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/ModelInterpolator.java
@@ -0,0 +1,54 @@
+package org.apache.maven.model.interpolation;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.model.Model;
+import org.apache.maven.model.building.ModelBuildingRequest;
+import org.apache.maven.model.building.ModelProblemCollector;
+
+import java.io.File;
+
+/**
+ * Replaces expressions of the form <tt>${token}</tt> with their effective values. Effective values are basically
+ * calculated from the elements of the model itself and the execution properties from the building request.
+ *
+ * @author jdcasey
+ * <p/>
+ * Created on Feb 2, 2005
+ */
+public interface ModelInterpolator
+{
+
+ /**
+ * Interpolates expressions in the specified model. Note that implementations are free to either interpolate the
+ * provided model directly or to create a clone of the model and interpolate the clone. Callers should always use
+ * the returned model and must not rely on the input model being updated.
+ *
+ * @param model The model to interpolate, must not be {@code null}.
+ * @param projectDir The project directory, may be {@code null} if the model does not belong to a local project but
+ * to some artifact's metadata.
+ * @param request The model building request that holds further settings, must not be {@code null}.
+ * @param problems The container used to collect problems that were encountered, must not be {@code null}.
+ * @return The interpolated model, never {@code null}.
+ */
+ Model interpolateModel( Model model, File projectDir, ModelBuildingRequest request,
+ ModelProblemCollector problems );
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/PathTranslatingPostProcessor.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/PathTranslatingPostProcessor.java
new file mode 100644
index 00000000..1aeafddc
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/PathTranslatingPostProcessor.java
@@ -0,0 +1,67 @@
+package org.apache.maven.model.interpolation;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.model.path.PathTranslator;
+import org.codehaus.plexus.interpolation.InterpolationPostProcessor;
+import org.codehaus.plexus.interpolation.util.ValueSourceUtils;
+
+import java.io.File;
+import java.util.Collection;
+import java.util.List;
+
+/**
+ *
+ */
+class PathTranslatingPostProcessor
+ implements InterpolationPostProcessor
+{
+
+ private final Collection<String> unprefixedPathKeys;
+ private final File projectDir;
+ private final PathTranslator pathTranslator;
+ private final List<String> expressionPrefixes;
+
+ public PathTranslatingPostProcessor( List<String> expressionPrefixes, Collection<String> unprefixedPathKeys,
+ File projectDir, PathTranslator pathTranslator )
+ {
+ this.expressionPrefixes = expressionPrefixes;
+ this.unprefixedPathKeys = unprefixedPathKeys;
+ this.projectDir = projectDir;
+ this.pathTranslator = pathTranslator;
+ }
+
+ @Override
+ public Object execute( String expression, Object value )
+ {
+ if ( value != null )
+ {
+ expression = ValueSourceUtils.trimPrefix( expression, expressionPrefixes, true );
+
+ if ( unprefixedPathKeys.contains( expression ) )
+ {
+ return pathTranslator.alignToBaseDirectory( String.valueOf( value ), projectDir );
+ }
+ }
+
+ return null;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/ProblemDetectingValueSource.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/ProblemDetectingValueSource.java
new file mode 100644
index 00000000..be5b227e
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/ProblemDetectingValueSource.java
@@ -0,0 +1,87 @@
+package org.apache.maven.model.interpolation;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.List;
+
+import org.apache.maven.model.building.ModelProblemCollector;
+import org.apache.maven.model.building.ModelProblem.Severity;
+import org.apache.maven.model.building.ModelProblem.Version;
+import org.apache.maven.model.building.ModelProblemCollectorRequest;
+import org.codehaus.plexus.interpolation.ValueSource;
+
+/**
+ * Wraps another value source and intercepts interpolated expressions, checking for problems.
+ *
+ * @author Benjamin Bentmann
+ */
+class ProblemDetectingValueSource
+ implements ValueSource
+{
+
+ private final ValueSource valueSource;
+
+ private final String bannedPrefix;
+
+ private final String newPrefix;
+
+ private final ModelProblemCollector problems;
+
+ public ProblemDetectingValueSource( ValueSource valueSource, String bannedPrefix, String newPrefix,
+ ModelProblemCollector problems )
+ {
+ this.valueSource = valueSource;
+ this.bannedPrefix = bannedPrefix;
+ this.newPrefix = newPrefix;
+ this.problems = problems;
+ }
+
+ @Override
+ public Object getValue( String expression )
+ {
+ Object value = valueSource.getValue( expression );
+
+ if ( value != null && expression.startsWith( bannedPrefix ) )
+ {
+ String msg = "The expression ${" + expression + "} is deprecated.";
+ if ( newPrefix != null && newPrefix.length() > 0 )
+ {
+ msg += " Please use ${" + newPrefix + expression.substring( bannedPrefix.length() ) + "} instead.";
+ }
+ problems.add( new ModelProblemCollectorRequest( Severity.WARNING, Version.V20 ).setMessage( msg ) );
+ }
+
+ return value;
+ }
+
+ @Override
+ @SuppressWarnings( "unchecked" )
+ public List getFeedback()
+ {
+ return valueSource.getFeedback();
+ }
+
+ @Override
+ public void clearFeedback()
+ {
+ valueSource.clearFeedback();
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/StringSearchModelInterpolator.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/StringSearchModelInterpolator.java
new file mode 100644
index 00000000..c40f9bd5
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/StringSearchModelInterpolator.java
@@ -0,0 +1,504 @@
+package org.apache.maven.model.interpolation;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.model.Model;
+import org.apache.maven.model.building.ModelBuildingRequest;
+import org.apache.maven.model.building.ModelProblem.Severity;
+import org.apache.maven.model.building.ModelProblem.Version;
+import org.apache.maven.model.building.ModelProblemCollector;
+import org.apache.maven.model.building.ModelProblemCollectorRequest;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.interpolation.InterpolationPostProcessor;
+import org.codehaus.plexus.interpolation.Interpolator;
+import org.codehaus.plexus.interpolation.StringSearchInterpolator;
+import org.codehaus.plexus.interpolation.ValueSource;
+
+import java.io.File;
+import java.lang.reflect.Array;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+@Component( role = ModelInterpolator.class )
+public class StringSearchModelInterpolator
+ extends AbstractStringBasedModelInterpolator
+{
+
+ private static final Map<Class<?>, InterpolateObjectAction.CacheItem> CACHED_ENTRIES =
+ new ConcurrentHashMap<Class<?>, InterpolateObjectAction.CacheItem>( 80, 0.75f, 2 );
+ // Empirical data from 3.x, actual =40
+
+
+ @Override
+ public Model interpolateModel( Model model, File projectDir, ModelBuildingRequest config,
+ ModelProblemCollector problems )
+ {
+ interpolateObject( model, model, projectDir, config, problems );
+
+ return model;
+ }
+
+ protected void interpolateObject( Object obj, Model model, File projectDir, ModelBuildingRequest config,
+ ModelProblemCollector problems )
+ {
+ try
+ {
+ List<? extends ValueSource> valueSources = createValueSources( model, projectDir, config, problems );
+ List<? extends InterpolationPostProcessor> postProcessors =
+ createPostProcessors( model, projectDir, config );
+
+ InterpolateObjectAction action =
+ new InterpolateObjectAction( obj, valueSources, postProcessors, this, problems );
+
+ AccessController.doPrivileged( action );
+ }
+ finally
+ {
+ getInterpolator().clearAnswers();
+ }
+ }
+
+ @Override
+ protected Interpolator createInterpolator()
+ {
+ StringSearchInterpolator interpolator = new StringSearchInterpolator();
+ interpolator.setCacheAnswers( true );
+
+ return interpolator;
+ }
+
+ private static final class InterpolateObjectAction
+ implements PrivilegedAction<Object>
+ {
+
+ private final LinkedList<Object> interpolationTargets;
+
+ private final StringSearchModelInterpolator modelInterpolator;
+
+ private final List<? extends ValueSource> valueSources;
+
+ private final List<? extends InterpolationPostProcessor> postProcessors;
+
+ private final ModelProblemCollector problems;
+
+ public InterpolateObjectAction( Object target, List<? extends ValueSource> valueSources,
+ List<? extends InterpolationPostProcessor> postProcessors,
+ StringSearchModelInterpolator modelInterpolator,
+ ModelProblemCollector problems )
+ {
+ this.valueSources = valueSources;
+ this.postProcessors = postProcessors;
+
+ this.interpolationTargets = new LinkedList<Object>();
+ interpolationTargets.add( target );
+
+ this.modelInterpolator = modelInterpolator;
+
+ this.problems = problems;
+ }
+
+ @Override
+ public Object run()
+ {
+ while ( !interpolationTargets.isEmpty() )
+ {
+ Object obj = interpolationTargets.removeFirst();
+
+ traverseObjectWithParents( obj.getClass(), obj );
+ }
+
+ return null;
+ }
+
+
+ private String interpolate( String value )
+ {
+ return modelInterpolator.interpolateInternal( value, valueSources, postProcessors, problems );
+ }
+
+ private void traverseObjectWithParents( Class<?> cls, Object target )
+ {
+ if ( cls == null )
+ {
+ return;
+ }
+
+ CacheItem cacheEntry = getCacheEntry( cls );
+ if ( cacheEntry.isArray() )
+ {
+ evaluateArray( target, this );
+ }
+ else if ( cacheEntry.isQualifiedForInterpolation )
+ {
+ cacheEntry.interpolate( target, this );
+
+ traverseObjectWithParents( cls.getSuperclass(), target );
+ }
+ }
+
+
+ private CacheItem getCacheEntry( Class<?> cls )
+ {
+ CacheItem cacheItem = CACHED_ENTRIES.get( cls );
+ if ( cacheItem == null )
+ {
+ cacheItem = new CacheItem( cls );
+ CACHED_ENTRIES.put( cls, cacheItem );
+ }
+ return cacheItem;
+ }
+
+ private static void evaluateArray( Object target, InterpolateObjectAction ctx )
+ {
+ int len = Array.getLength( target );
+ for ( int i = 0; i < len; i++ )
+ {
+ Object value = Array.get( target, i );
+ if ( value != null )
+ {
+ if ( String.class == value.getClass() )
+ {
+ String interpolated = ctx.interpolate( (String) value );
+
+ if ( !interpolated.equals( value ) )
+ {
+ Array.set( target, i, interpolated );
+ }
+ }
+ else
+ {
+ ctx.interpolationTargets.add( value );
+ }
+ }
+ }
+ }
+
+ private static class CacheItem
+ {
+ private final boolean isArray;
+
+ private final boolean isQualifiedForInterpolation;
+
+ private final CacheField[] fields;
+
+ private boolean isQualifiedForInterpolation( Class<?> cls )
+ {
+ return !cls.getName().startsWith( "java" );
+ }
+
+ private boolean isQualifiedForInterpolation( Field field, Class<?> fieldType )
+ {
+ if ( Map.class.equals( fieldType ) && "locations".equals( field.getName() ) )
+ {
+ return false;
+ }
+
+ //noinspection SimplifiableIfStatement
+ if ( fieldType.isPrimitive() )
+ {
+ return false;
+ }
+
+ return !"parent".equals( field.getName() );
+ }
+
+ CacheItem( Class clazz )
+ {
+ this.isQualifiedForInterpolation = isQualifiedForInterpolation( clazz );
+ this.isArray = clazz.isArray();
+ List<CacheField> fields = new ArrayList<CacheField>();
+ for ( Field currentField : clazz.getDeclaredFields() )
+ {
+ Class<?> type = currentField.getType();
+ if ( isQualifiedForInterpolation( currentField, type ) )
+ {
+ if ( String.class == type )
+ {
+ if ( !Modifier.isFinal( currentField.getModifiers() ) )
+ {
+ fields.add( new StringField( currentField ) );
+ }
+ }
+ else if ( List.class.isAssignableFrom( type ) )
+ {
+ fields.add( new ListField( currentField ) );
+ }
+ else if ( Collection.class.isAssignableFrom( type ) )
+ {
+ throw new RuntimeException( "We dont interpolate into collections, use a list instead" );
+ }
+ else if ( Map.class.isAssignableFrom( type ) )
+ {
+ fields.add( new MapField( currentField ) );
+ }
+ else
+ {
+ fields.add( new ObjectField( currentField ) );
+ }
+ }
+
+ }
+ this.fields = fields.toArray( new CacheField[fields.size()] );
+
+ }
+
+ public void interpolate( Object target, InterpolateObjectAction interpolateObjectAction )
+ {
+ for ( CacheField field : fields )
+ {
+ field.interpolate( target, interpolateObjectAction );
+ }
+ }
+
+ public boolean isArray()
+ {
+ return isArray;
+ }
+ }
+
+ abstract static class CacheField
+ {
+ protected final Field field;
+
+ CacheField( Field field )
+ {
+ this.field = field;
+ }
+
+ void interpolate( Object target, InterpolateObjectAction interpolateObjectAction )
+ {
+ synchronized ( field )
+ {
+ boolean isAccessible = field.isAccessible();
+ field.setAccessible( true );
+ try
+ {
+ doInterpolate( target, interpolateObjectAction );
+ }
+ catch ( IllegalArgumentException e )
+ {
+ interpolateObjectAction.problems.add(
+ new ModelProblemCollectorRequest( Severity.ERROR, Version.BASE ).setMessage(
+ "Failed to interpolate field3: " + field + " on class: "
+ + field.getType().getName() ).setException(
+ e ) ); // todo: Not entirely the same message
+ }
+ catch ( IllegalAccessException e )
+ {
+ interpolateObjectAction.problems.add(
+ new ModelProblemCollectorRequest( Severity.ERROR, Version.BASE ).setMessage(
+ "Failed to interpolate field4: " + field + " on class: "
+ + field.getType().getName() ).setException( e ) );
+ }
+ finally
+ {
+ field.setAccessible( isAccessible );
+ }
+ }
+
+
+ }
+
+ abstract void doInterpolate( Object target, InterpolateObjectAction ctx )
+ throws IllegalAccessException;
+ }
+
+ static final class StringField
+ extends CacheField
+ {
+ StringField( Field field )
+ {
+ super( field );
+ }
+
+ @Override
+ void doInterpolate( Object target, InterpolateObjectAction ctx )
+ throws IllegalAccessException
+ {
+ String value = (String) field.get( target );
+ if ( value == null )
+ {
+ return;
+ }
+
+ String interpolated = ctx.interpolate( value );
+
+ if ( !interpolated.equals( value ) )
+ {
+ field.set( target, interpolated );
+ }
+ }
+ }
+
+ static final class ListField
+ extends CacheField
+ {
+ ListField( Field field )
+ {
+ super( field );
+ }
+
+ @Override
+ void doInterpolate( Object target, InterpolateObjectAction ctx )
+ throws IllegalAccessException
+ {
+ @SuppressWarnings( "unchecked" ) List<Object> c = (List<Object>) field.get( target );
+ if ( c == null )
+ {
+ return;
+ }
+
+ int size = c.size();
+ Object value;
+ for ( int i = 0; i < size; i++ )
+ {
+
+ value = c.get( i );
+
+ if ( value != null )
+ {
+ if ( String.class == value.getClass() )
+ {
+ String interpolated = ctx.interpolate( (String) value );
+
+ if ( !interpolated.equals( value ) )
+ {
+ try
+ {
+ c.set( i, interpolated );
+ }
+ catch ( UnsupportedOperationException e )
+ {
+ return;
+ }
+ }
+ }
+ else
+ {
+ if ( value.getClass().isArray() )
+ {
+ evaluateArray( value, ctx );
+ }
+ else
+ {
+ ctx.interpolationTargets.add( value );
+ }
+ }
+ }
+ }
+ }
+ }
+
+ static final class MapField
+ extends CacheField
+ {
+ MapField( Field field )
+ {
+ super( field );
+ }
+
+ @Override
+ void doInterpolate( Object target, InterpolateObjectAction ctx )
+ throws IllegalAccessException
+ {
+ @SuppressWarnings( "unchecked" ) Map<Object, Object> m = (Map<Object, Object>) field.get( target );
+ if ( m == null || m.isEmpty() )
+ {
+ return;
+ }
+
+ for ( Map.Entry<Object, Object> entry : m.entrySet() )
+ {
+ Object value = entry.getValue();
+
+ if ( value == null )
+ {
+ continue;
+ }
+
+ if ( String.class == value.getClass() )
+ {
+ String interpolated = ctx.interpolate( (String) value );
+
+ if ( !interpolated.equals( value ) )
+ {
+ try
+ {
+ entry.setValue( interpolated );
+ }
+ catch ( UnsupportedOperationException ignore )
+ {
+ // nop
+ }
+ }
+ }
+ else if ( value.getClass().isArray() )
+ {
+ evaluateArray( value, ctx );
+ }
+ else
+ {
+ ctx.interpolationTargets.add( value );
+ }
+ }
+ }
+ }
+
+ static final class ObjectField
+ extends CacheField
+ {
+ private final boolean isArray;
+
+ ObjectField( Field field )
+ {
+ super( field );
+ this.isArray = field.getType().isArray();
+ }
+
+ @Override
+ void doInterpolate( Object target, InterpolateObjectAction ctx )
+ throws IllegalAccessException
+ {
+ Object value = field.get( target );
+ if ( value != null )
+ {
+ if ( isArray )
+ {
+ evaluateArray( value, ctx );
+ }
+ else
+ {
+ ctx.interpolationTargets.add( value );
+ }
+ }
+ }
+ }
+
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/UrlNormalizingPostProcessor.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/UrlNormalizingPostProcessor.java
new file mode 100644
index 00000000..63fb82d6
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/interpolation/UrlNormalizingPostProcessor.java
@@ -0,0 +1,69 @@
+package org.apache.maven.model.interpolation;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.maven.model.path.UrlNormalizer;
+import org.codehaus.plexus.interpolation.InterpolationPostProcessor;
+
+/**
+ * Ensures that expressions referring to URLs evaluate to normalized URLs.
+ *
+ * @author Benjamin Bentmann
+ */
+class UrlNormalizingPostProcessor
+ implements InterpolationPostProcessor
+{
+
+ private static final Set<String> URL_EXPRESSIONS;
+
+ static
+ {
+ Set<String> expressions = new HashSet<String>();
+ expressions.add( "project.url" );
+ expressions.add( "project.scm.url" );
+ expressions.add( "project.scm.connection" );
+ expressions.add( "project.scm.developerConnection" );
+ expressions.add( "project.distributionManagement.site.url" );
+
+ URL_EXPRESSIONS = expressions;
+ }
+
+ private UrlNormalizer normalizer;
+
+ public UrlNormalizingPostProcessor( UrlNormalizer normalizer )
+ {
+ this.normalizer = normalizer;
+ }
+
+ @Override
+ public Object execute( String expression, Object value )
+ {
+ if ( value != null && URL_EXPRESSIONS.contains( expression ) )
+ {
+ return normalizer.normalize( value.toString() );
+ }
+
+ return null;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/io/DefaultModelReader.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/io/DefaultModelReader.java
new file mode 100644
index 00000000..c927b60f
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/io/DefaultModelReader.java
@@ -0,0 +1,134 @@
+package org.apache.maven.model.io;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.util.Map;
+
+import org.apache.maven.model.InputSource;
+import org.apache.maven.model.Model;
+import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
+import org.apache.maven.model.io.xpp3.MavenXpp3ReaderEx;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.util.IOUtil;
+import org.codehaus.plexus.util.ReaderFactory;
+import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
+
+/**
+ * Handles deserialization of a model from some kind of textual format like XML.
+ *
+ * @author Benjamin Bentmann
+ */
+@Component( role = ModelReader.class )
+public class DefaultModelReader
+ implements ModelReader
+{
+
+ @Override
+ public Model read( File input, Map<String, ?> options )
+ throws IOException
+ {
+ if ( input == null )
+ {
+ throw new IllegalArgumentException( "input file missing" );
+ }
+
+ Model model = read( new FileInputStream( input ), options );
+
+ model.setPomFile( input );
+
+ return model;
+ }
+
+ @Override
+ public Model read( Reader input, Map<String, ?> options )
+ throws IOException
+ {
+ if ( input == null )
+ {
+ throw new IllegalArgumentException( "input reader missing" );
+ }
+
+ try
+ {
+ return read( input, isStrict( options ), getSource( options ) );
+ }
+ finally
+ {
+ IOUtil.close( input );
+ }
+ }
+
+ @Override
+ public Model read( InputStream input, Map<String, ?> options )
+ throws IOException
+ {
+ if ( input == null )
+ {
+ throw new IllegalArgumentException( "input stream missing" );
+ }
+
+ try
+ {
+ return read( ReaderFactory.newXmlReader( input ), isStrict( options ), getSource( options ) );
+ }
+ finally
+ {
+ IOUtil.close( input );
+ }
+ }
+
+ private boolean isStrict( Map<String, ?> options )
+ {
+ Object value = ( options != null ) ? options.get( IS_STRICT ) : null;
+ return value == null || Boolean.parseBoolean( value.toString() );
+ }
+
+ private InputSource getSource( Map<String, ?> options )
+ {
+ Object value = ( options != null ) ? options.get( INPUT_SOURCE ) : null;
+ return (InputSource) value;
+ }
+
+ private Model read( Reader reader, boolean strict, InputSource source )
+ throws IOException
+ {
+ try
+ {
+ if ( source != null )
+ {
+ return new MavenXpp3ReaderEx().read( reader, strict, source );
+ }
+ else
+ {
+ return new MavenXpp3Reader().read( reader, strict );
+ }
+ }
+ catch ( XmlPullParserException e )
+ {
+ throw new ModelParseException( e.getMessage(), e.getLineNumber(), e.getColumnNumber(), e );
+ }
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/io/DefaultModelWriter.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/io/DefaultModelWriter.java
new file mode 100644
index 00000000..7294de3c
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/io/DefaultModelWriter.java
@@ -0,0 +1,118 @@
+package org.apache.maven.model.io;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+import java.util.Map;
+
+import org.apache.maven.model.Model;
+import org.apache.maven.model.io.xpp3.MavenXpp3Writer;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.util.IOUtil;
+import org.codehaus.plexus.util.WriterFactory;
+
+/**
+ * Handles serialization of a model into some kind of textual format like XML.
+ *
+ * @author Benjamin Bentmann
+ */
+@Component( role = ModelWriter.class )
+public class DefaultModelWriter
+ implements ModelWriter
+{
+
+ @Override
+ public void write( File output, Map<String, Object> options, Model model )
+ throws IOException
+ {
+ if ( output == null )
+ {
+ throw new IllegalArgumentException( "output file missing" );
+ }
+
+ if ( model == null )
+ {
+ throw new IllegalArgumentException( "model missing" );
+ }
+
+ output.getParentFile().mkdirs();
+
+ write( WriterFactory.newXmlWriter( output ), options, model );
+ }
+
+ @Override
+ public void write( Writer output, Map<String, Object> options, Model model )
+ throws IOException
+ {
+ if ( output == null )
+ {
+ throw new IllegalArgumentException( "output writer missing" );
+ }
+
+ if ( model == null )
+ {
+ throw new IllegalArgumentException( "model missing" );
+ }
+
+ try
+ {
+ MavenXpp3Writer w = new MavenXpp3Writer();
+ w.write( output, model );
+ }
+ finally
+ {
+ IOUtil.close( output );
+ }
+ }
+
+ @Override
+ public void write( OutputStream output, Map<String, Object> options, Model model )
+ throws IOException
+ {
+ if ( output == null )
+ {
+ throw new IllegalArgumentException( "output stream missing" );
+ }
+
+ if ( model == null )
+ {
+ throw new IllegalArgumentException( "model missing" );
+ }
+
+ try
+ {
+ String encoding = model.getModelEncoding();
+ if ( encoding == null || encoding.length() <= 0 )
+ {
+ encoding = "UTF-8";
+ }
+ write( new OutputStreamWriter( output, encoding ), options, model );
+ }
+ finally
+ {
+ IOUtil.close( output );
+ }
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/io/ModelParseException.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/io/ModelParseException.java
new file mode 100644
index 00000000..1b2cbc34
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/io/ModelParseException.java
@@ -0,0 +1,93 @@
+package org.apache.maven.model.io;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.IOException;
+
+/**
+ * Signals a failure to parse the POM due to invalid syntax (e.g. non-wellformed XML or unknown elements).
+ *
+ * @author Benjamin Bentmann
+ */
+public class ModelParseException
+ extends IOException
+{
+
+ /**
+ * The one-based index of the line containing the error.
+ */
+ private final int lineNumber;
+
+ /**
+ * The one-based index of the column containing the error.
+ */
+ private final int columnNumber;
+
+ /**
+ * Creates a new parser exception with the specified details.
+ *
+ * @param message The error message, may be {@code null}.
+ * @param lineNumber The one-based index of the line containing the error or {@code -1} if unknown.
+ * @param columnNumber The one-based index of the column containing the error or {@code -1} if unknown.
+ */
+ public ModelParseException( String message, int lineNumber, int columnNumber )
+ {
+ super( message );
+ this.lineNumber = lineNumber;
+ this.columnNumber = columnNumber;
+ }
+
+ /**
+ * Creates a new parser exception with the specified details.
+ *
+ * @param message The error message, may be {@code null}.
+ * @param lineNumber The one-based index of the line containing the error or {@code -1} if unknown.
+ * @param columnNumber The one-based index of the column containing the error or {@code -1} if unknown.
+ * @param cause The nested cause of this error, may be {@code null}.
+ */
+ public ModelParseException( String message, int lineNumber, int columnNumber, Throwable cause )
+ {
+ super( message );
+ initCause( cause );
+ this.lineNumber = lineNumber;
+ this.columnNumber = columnNumber;
+ }
+
+ /**
+ * Gets the one-based index of the line containing the error.
+ *
+ * @return The one-based index of the line containing the error or a non-positive value if unknown.
+ */
+ public int getLineNumber()
+ {
+ return lineNumber;
+ }
+
+ /**
+ * Gets the one-based index of the column containing the error.
+ *
+ * @return The one-based index of the column containing the error or non-positive value if unknown.
+ */
+ public int getColumnNumber()
+ {
+ return columnNumber;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/io/ModelReader.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/io/ModelReader.java
new file mode 100644
index 00000000..75a5ebee
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/io/ModelReader.java
@@ -0,0 +1,89 @@
+package org.apache.maven.model.io;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.util.Map;
+
+import org.apache.maven.model.Model;
+
+/**
+ * Handles deserialization of a model from some kind of textual format like XML.
+ *
+ * @author Benjamin Bentmann
+ */
+public interface ModelReader
+{
+
+ /**
+ * The key for the option to enable strict parsing. This option is of type {@link Boolean} and defaults to {@code
+ * true}. If {@code false}, unknown elements will be ignored instead of causing a failure.
+ */
+ String IS_STRICT = "org.apache.maven.model.io.isStrict";
+
+ /**
+ * The key for the option to enable tracking of line/column numbers. This option is of type
+ * {@link org.apache.maven.model.InputSource} and defaults to {@code null}. Providing an input source enables
+ * location tracking.
+ */
+ String INPUT_SOURCE = "org.apache.maven.model.io.inputSource";
+
+ /**
+ * Reads the model from the specified file.
+ *
+ * @param input The file to deserialize the model from, must not be {@code null}.
+ * @param options The options to use for deserialization, may be {@code null} to use the default values.
+ * @return The deserialized model, never {@code null}.
+ * @throws IOException If the model could not be deserialized.
+ * @throws ModelParseException If the input format could not be parsed.
+ */
+ Model read( File input, Map<String, ?> options )
+ throws IOException, ModelParseException;
+
+ /**
+ * Reads the model from the specified character reader. The reader will be automatically closed before the method
+ * returns.
+ *
+ * @param input The reader to deserialize the model from, must not be {@code null}.
+ * @param options The options to use for deserialization, may be {@code null} to use the default values.
+ * @return The deserialized model, never {@code null}.
+ * @throws IOException If the model could not be deserialized.
+ * @throws ModelParseException If the input format could not be parsed.
+ */
+ Model read( Reader input, Map<String, ?> options )
+ throws IOException, ModelParseException;
+
+ /**
+ * Reads the model from the specified byte stream. The stream will be automatically closed before the method
+ * returns.
+ *
+ * @param input The stream to deserialize the model from, must not be {@code null}.
+ * @param options The options to use for deserialization, may be {@code null} to use the default values.
+ * @return The deserialized model, never {@code null}.
+ * @throws IOException If the model could not be deserialized.
+ * @throws ModelParseException If the input format could not be parsed.
+ */
+ Model read( InputStream input, Map<String, ?> options )
+ throws IOException, ModelParseException;
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/io/ModelWriter.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/io/ModelWriter.java
new file mode 100644
index 00000000..af7e0cab
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/io/ModelWriter.java
@@ -0,0 +1,74 @@
+package org.apache.maven.model.io;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.Writer;
+import java.util.Map;
+
+import org.apache.maven.model.Model;
+
+/**
+ * Handles serialization of a model into some kind of textual format like XML.
+ *
+ * @author Benjamin Bentmann
+ */
+public interface ModelWriter
+{
+
+ /**
+ * Writes the supplied model to the specified file. Any non-existing parent directories of the output file will be
+ * created automatically.
+ *
+ * @param output The file to serialize the model to, must not be {@code null}.
+ * @param options The options to use for serialization, may be {@code null} to use the default values.
+ * @param model The model to serialize, must not be {@code null}.
+ * @throws IOException If the model could not be serialized.
+ */
+ void write( File output, Map<String, Object> options, Model model )
+ throws IOException;
+
+ /**
+ * Writes the supplied model to the specified character writer. The writer will be automatically closed before the
+ * method returns.
+ *
+ * @param output The writer to serialize the model to, must not be {@code null}.
+ * @param options The options to use for serialization, may be {@code null} to use the default values.
+ * @param model The model to serialize, must not be {@code null}.
+ * @throws IOException If the model could not be serialized.
+ */
+ void write( Writer output, Map<String, Object> options, Model model )
+ throws IOException;
+
+ /**
+ * Writes the supplied model to the specified byte stream. The stream will be automatically closed before the method
+ * returns.
+ *
+ * @param output The stream to serialize the model to, must not be {@code null}.
+ * @param options The options to use for serialization, may be {@code null} to use the default values.
+ * @param model The model to serialize, must not be {@code null}.
+ * @throws IOException If the model could not be serialized.
+ */
+ void write( OutputStream output, Map<String, Object> options, Model model )
+ throws IOException;
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/locator/DefaultModelLocator.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/locator/DefaultModelLocator.java
new file mode 100644
index 00000000..299da65f
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/locator/DefaultModelLocator.java
@@ -0,0 +1,42 @@
+package org.apache.maven.model.locator;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+
+import org.codehaus.plexus.component.annotations.Component;
+
+/**
+ * Locates a POM file within a project base directory.
+ *
+ * @author Benjamin Bentmann
+ */
+@Component( role = ModelLocator.class )
+public class DefaultModelLocator
+ implements ModelLocator
+{
+
+ @Override
+ public File locatePom( File projectDirectory )
+ {
+ return new File( projectDirectory, "pom.xml" );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/locator/ModelLocator.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/locator/ModelLocator.java
new file mode 100644
index 00000000..3aa0045c
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/locator/ModelLocator.java
@@ -0,0 +1,44 @@
+package org.apache.maven.model.locator;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+
+/**
+ * Locates a POM file within a project base directory.
+ *
+ * @author Benjamin Bentmann
+ */
+public interface ModelLocator
+{
+
+ /**
+ * Locates the POM file within the specified project directory. In case the given project directory does not exist
+ * or does not contain a POM file, the return value indicates the expected path to the POM file. Sub directories of
+ * the project directory will not be considered when locating the POM file. The return value will be an absolute
+ * path if the project directory is given as an absolute path.
+ *
+ * @param projectDirectory The (possibly non-existent) base directory to locate the POM file in, must not be {@code
+ * null}.
+ * @return The path to the (possibly non-existent) POM file, never {@code null}.
+ */
+ File locatePom( File projectDirectory );
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/management/DefaultDependencyManagementInjector.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/management/DefaultDependencyManagementInjector.java
new file mode 100644
index 00000000..bfeafcb7
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/management/DefaultDependencyManagementInjector.java
@@ -0,0 +1,110 @@
+package org.apache.maven.model.management;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.maven.model.Dependency;
+import org.apache.maven.model.DependencyManagement;
+import org.apache.maven.model.Exclusion;
+import org.apache.maven.model.Model;
+import org.apache.maven.model.building.ModelBuildingRequest;
+import org.apache.maven.model.building.ModelProblemCollector;
+import org.apache.maven.model.merge.MavenModelMerger;
+import org.codehaus.plexus.component.annotations.Component;
+
+/**
+ * Handles injection of dependency management into the model.
+ *
+ * @author Benjamin Bentmann
+ */
+@Component( role = DependencyManagementInjector.class )
+public class DefaultDependencyManagementInjector
+ implements DependencyManagementInjector
+{
+
+ private ManagementModelMerger merger = new ManagementModelMerger();
+
+ @Override
+ public void injectManagement( Model model, ModelBuildingRequest request, ModelProblemCollector problems )
+ {
+ merger.mergeManagedDependencies( model );
+ }
+
+ protected static class ManagementModelMerger
+ extends MavenModelMerger
+ {
+
+ public void mergeManagedDependencies( Model model )
+ {
+ DependencyManagement dependencyManagement = model.getDependencyManagement();
+ if ( dependencyManagement != null )
+ {
+ Map<Object, Dependency> dependencies = new HashMap<Object, Dependency>();
+ Map<Object, Object> context = Collections.emptyMap();
+
+ for ( Dependency dependency : model.getDependencies() )
+ {
+ Object key = getDependencyKey( dependency );
+ dependencies.put( key, dependency );
+ }
+
+ for ( Dependency managedDependency : dependencyManagement.getDependencies() )
+ {
+ Object key = getDependencyKey( managedDependency );
+ Dependency dependency = dependencies.get( key );
+ if ( dependency != null )
+ {
+ mergeDependency( dependency, managedDependency, false, context );
+ }
+ }
+ }
+ }
+
+ @Override
+ protected void mergeDependency_Optional( Dependency target, Dependency source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ // optional flag is not managed
+ }
+
+ @Override
+ protected void mergeDependency_Exclusions( Dependency target, Dependency source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ List<Exclusion> tgt = target.getExclusions();
+ if ( tgt.isEmpty() )
+ {
+ List<Exclusion> src = source.getExclusions();
+
+ for ( Exclusion element : src )
+ {
+ Exclusion clone = element.clone();
+ target.addExclusion( clone );
+ }
+ }
+ }
+
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/management/DefaultPluginManagementInjector.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/management/DefaultPluginManagementInjector.java
new file mode 100644
index 00000000..75d7d878
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/management/DefaultPluginManagementInjector.java
@@ -0,0 +1,137 @@
+package org.apache.maven.model.management;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.maven.model.Build;
+import org.apache.maven.model.Model;
+import org.apache.maven.model.Plugin;
+import org.apache.maven.model.PluginContainer;
+import org.apache.maven.model.PluginExecution;
+import org.apache.maven.model.PluginManagement;
+import org.apache.maven.model.building.ModelBuildingRequest;
+import org.apache.maven.model.building.ModelProblemCollector;
+import org.apache.maven.model.merge.MavenModelMerger;
+import org.codehaus.plexus.component.annotations.Component;
+
+/**
+ * Handles injection of plugin management into the model.
+ *
+ * @author Benjamin Bentmann
+ */
+@Component( role = PluginManagementInjector.class )
+public class DefaultPluginManagementInjector
+ implements PluginManagementInjector
+{
+
+ private ManagementModelMerger merger = new ManagementModelMerger();
+
+ @Override
+ public void injectManagement( Model model, ModelBuildingRequest request, ModelProblemCollector problems )
+ {
+ merger.mergeManagedBuildPlugins( model );
+ }
+
+ protected static class ManagementModelMerger
+ extends MavenModelMerger
+ {
+
+ public void mergeManagedBuildPlugins( Model model )
+ {
+ Build build = model.getBuild();
+ if ( build != null )
+ {
+ PluginManagement pluginManagement = build.getPluginManagement();
+ if ( pluginManagement != null )
+ {
+ mergePluginContainer_Plugins( build, pluginManagement );
+ }
+ }
+ }
+
+ private void mergePluginContainer_Plugins( PluginContainer target, PluginContainer source )
+ {
+ List<Plugin> src = source.getPlugins();
+ if ( !src.isEmpty() )
+ {
+ List<Plugin> tgt = target.getPlugins();
+
+ Map<Object, Plugin> managedPlugins = new LinkedHashMap<Object, Plugin>( src.size() * 2 );
+
+ Map<Object, Object> context = Collections.emptyMap();
+
+ for ( Plugin element : src )
+ {
+ Object key = getPluginKey( element );
+ managedPlugins.put( key, element );
+ }
+
+ for ( Plugin element : tgt )
+ {
+ Object key = getPluginKey( element );
+ Plugin managedPlugin = managedPlugins.get( key );
+ if ( managedPlugin != null )
+ {
+ mergePlugin( element, managedPlugin, false, context );
+ }
+ }
+ }
+ }
+
+ @Override
+ protected void mergePlugin_Executions( Plugin target, Plugin source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ List<PluginExecution> src = source.getExecutions();
+ if ( !src.isEmpty() )
+ {
+ List<PluginExecution> tgt = target.getExecutions();
+
+ Map<Object, PluginExecution> merged =
+ new LinkedHashMap<Object, PluginExecution>( ( src.size() + tgt.size() ) * 2 );
+
+ for ( PluginExecution element : src )
+ {
+ Object key = getPluginExecutionKey( element );
+ merged.put( key, element.clone() );
+ }
+
+ for ( PluginExecution element : tgt )
+ {
+ Object key = getPluginExecutionKey( element );
+ PluginExecution existing = merged.get( key );
+ if ( existing != null )
+ {
+ mergePluginExecution( element, existing, sourceDominant, context );
+ }
+ merged.put( key, element );
+ }
+
+ target.setExecutions( new ArrayList<PluginExecution>( merged.values() ) );
+ }
+ }
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/management/DependencyManagementInjector.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/management/DependencyManagementInjector.java
new file mode 100644
index 00000000..3b70a09c
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/management/DependencyManagementInjector.java
@@ -0,0 +1,44 @@
+package org.apache.maven.model.management;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.model.Model;
+import org.apache.maven.model.building.ModelBuildingRequest;
+import org.apache.maven.model.building.ModelProblemCollector;
+
+/**
+ * Handles injection of dependency management into the model.
+ *
+ * @author Benjamin Bentmann
+ */
+public interface DependencyManagementInjector
+{
+
+ /**
+ * Merges default values from the dependency management section of the given model into itself.
+ *
+ * @param model The model into which to merge the values specified by its dependency management sections, must not
+ * be <code>null</code>.
+ * @param request The model building request that holds further settings, must not be {@code null}.
+ * @param problems The container used to collect problems that were encountered, must not be {@code null}.
+ */
+ void injectManagement( Model model, ModelBuildingRequest request, ModelProblemCollector problems );
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/management/PluginManagementInjector.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/management/PluginManagementInjector.java
new file mode 100644
index 00000000..7384fdf0
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/management/PluginManagementInjector.java
@@ -0,0 +1,44 @@
+package org.apache.maven.model.management;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.model.Model;
+import org.apache.maven.model.building.ModelBuildingRequest;
+import org.apache.maven.model.building.ModelProblemCollector;
+
+/**
+ * Handles injection of plugin management into the model.
+ *
+ * @author Benjamin Bentmann
+ */
+public interface PluginManagementInjector
+{
+
+ /**
+ * Merges default values from the plugin management section of the given model into itself.
+ *
+ * @param model The model into which to merge the values specified by its plugin management section, must not be
+ * <code>null</code>.
+ * @param request The model building request that holds further settings, must not be {@code null}.
+ * @param problems The container used to collect problems that were encountered, must not be {@code null}.
+ */
+ void injectManagement( Model model, ModelBuildingRequest request, ModelProblemCollector problems );
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/merge/MavenModelMerger.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/merge/MavenModelMerger.java
new file mode 100644
index 00000000..2727a111
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/merge/MavenModelMerger.java
@@ -0,0 +1,729 @@
+package org.apache.maven.model.merge;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.maven.model.BuildBase;
+import org.apache.maven.model.CiManagement;
+import org.apache.maven.model.Contributor;
+import org.apache.maven.model.Dependency;
+import org.apache.maven.model.DeploymentRepository;
+import org.apache.maven.model.Developer;
+import org.apache.maven.model.DistributionManagement;
+import org.apache.maven.model.Exclusion;
+import org.apache.maven.model.Extension;
+import org.apache.maven.model.InputLocation;
+import org.apache.maven.model.IssueManagement;
+import org.apache.maven.model.License;
+import org.apache.maven.model.MailingList;
+import org.apache.maven.model.Model;
+import org.apache.maven.model.ModelBase;
+import org.apache.maven.model.Organization;
+import org.apache.maven.model.Plugin;
+import org.apache.maven.model.PluginExecution;
+import org.apache.maven.model.ReportPlugin;
+import org.apache.maven.model.ReportSet;
+import org.apache.maven.model.Repository;
+import org.apache.maven.model.RepositoryBase;
+import org.apache.maven.model.Scm;
+import org.apache.maven.model.Site;
+
+/**
+ * The domain-specific model merger for the Maven POM, overriding generic code from parent class when necessary with
+ * more adapted algorithms.
+ *
+ * @author Benjamin Bentmann
+ */
+public class MavenModelMerger
+ extends ModelMerger
+{
+
+ /**
+ * The hint key for the child path adjustment used during inheritance for URL calculations.
+ */
+ public static final String CHILD_PATH_ADJUSTMENT = "child-path-adjustment";
+
+ /**
+ * The context key for the artifact id of the target model.
+ */
+ private static final String ARTIFACT_ID = "artifact-id";
+
+ @Override
+ protected void mergeModel( Model target, Model source, boolean sourceDominant, Map<Object, Object> context )
+ {
+ context.put( ARTIFACT_ID, target.getArtifactId() );
+
+ super.mergeModel( target, source, sourceDominant, context );
+ }
+
+ @Override
+ protected void mergeModel_Name( Model target, Model source, boolean sourceDominant, Map<Object, Object> context )
+ {
+ String src = source.getName();
+ if ( src != null )
+ {
+ if ( sourceDominant )
+ {
+ target.setName( src );
+ target.setLocation( "name", source.getLocation( "name" ) );
+ }
+ }
+ }
+
+ @Override
+ protected void mergeModel_Url( Model target, Model source, boolean sourceDominant, Map<Object, Object> context )
+ {
+ String src = source.getUrl();
+ if ( src != null )
+ {
+ if ( sourceDominant )
+ {
+ target.setUrl( src );
+ target.setLocation( "url", source.getLocation( "url" ) );
+ }
+ else if ( target.getUrl() == null )
+ {
+ target.setUrl( appendPath( src, context ) );
+ target.setLocation( "url", source.getLocation( "url" ) );
+ }
+ }
+ }
+
+ /*
+ * TODO: Whether the merge continues recursively into an existing node or not could be an option for the generated
+ * merger
+ */
+ @Override
+ protected void mergeModel_Organization( Model target, Model source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ Organization src = source.getOrganization();
+ if ( src != null )
+ {
+ Organization tgt = target.getOrganization();
+ if ( tgt == null )
+ {
+ tgt = new Organization();
+ tgt.setLocation( "", src.getLocation( "" ) );
+ target.setOrganization( tgt );
+ mergeOrganization( tgt, src, sourceDominant, context );
+ }
+ }
+ }
+
+ @Override
+ protected void mergeModel_IssueManagement( Model target, Model source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ IssueManagement src = source.getIssueManagement();
+ if ( src != null )
+ {
+ IssueManagement tgt = target.getIssueManagement();
+ if ( tgt == null )
+ {
+ tgt = new IssueManagement();
+ tgt.setLocation( "", src.getLocation( "" ) );
+ target.setIssueManagement( tgt );
+ mergeIssueManagement( tgt, src, sourceDominant, context );
+ }
+ }
+ }
+
+ @Override
+ protected void mergeModel_CiManagement( Model target, Model source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ CiManagement src = source.getCiManagement();
+ if ( src != null )
+ {
+ CiManagement tgt = target.getCiManagement();
+ if ( tgt == null )
+ {
+ tgt = new CiManagement();
+ tgt.setLocation( "", src.getLocation( "" ) );
+ target.setCiManagement( tgt );
+ mergeCiManagement( tgt, src, sourceDominant, context );
+ }
+ }
+ }
+
+ @Override
+ protected void mergeModel_ModelVersion( Model target, Model source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ // neither inherited nor injected
+ }
+
+ @Override
+ protected void mergeModel_ArtifactId( Model target, Model source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ // neither inherited nor injected
+ }
+
+ @Override
+ protected void mergeModel_Profiles( Model target, Model source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ // neither inherited nor injected
+ }
+
+ @Override
+ protected void mergeModel_Prerequisites( Model target, Model source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ // neither inherited nor injected
+ }
+
+ @Override
+ protected void mergeModel_Licenses( Model target, Model source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ if ( target.getLicenses().isEmpty() )
+ {
+ target.setLicenses( new ArrayList<License>( source.getLicenses() ) );
+ }
+ }
+
+ @Override
+ protected void mergeModel_Developers( Model target, Model source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ if ( target.getDevelopers().isEmpty() )
+ {
+ target.setDevelopers( new ArrayList<Developer>( source.getDevelopers() ) );
+ }
+ }
+
+ @Override
+ protected void mergeModel_Contributors( Model target, Model source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ if ( target.getContributors().isEmpty() )
+ {
+ target.setContributors( new ArrayList<Contributor>( source.getContributors() ) );
+ }
+ }
+
+ @Override
+ protected void mergeModel_MailingLists( Model target, Model source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ if ( target.getMailingLists().isEmpty() )
+ {
+ target.setMailingLists( new ArrayList<MailingList>( source.getMailingLists() ) );
+ }
+ }
+
+ @Override
+ protected void mergeModelBase_Modules( ModelBase target, ModelBase source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ List<String> src = source.getModules();
+ if ( !src.isEmpty() && sourceDominant )
+ {
+ List<Integer> indices = new ArrayList<Integer>();
+ List<String> tgt = target.getModules();
+ Set<String> excludes = new LinkedHashSet<String>( tgt );
+ List<String> merged = new ArrayList<String>( tgt.size() + src.size() );
+ merged.addAll( tgt );
+ for ( int i = 0, n = tgt.size(); i < n; i++ )
+ {
+ indices.add( i );
+ }
+ for ( int i = 0, n = src.size(); i < n; i++ )
+ {
+ String s = src.get( i );
+ if ( !excludes.contains( s ) )
+ {
+ merged.add( s );
+ indices.add( ~i );
+ }
+ }
+ target.setModules( merged );
+ target.setLocation( "modules", InputLocation.merge( target.getLocation( "modules" ),
+ source.getLocation( "modules" ), indices ) );
+ }
+ }
+
+ /*
+ * TODO: The order of the merged list could be controlled by an attribute in the model association: target-first,
+ * source-first, dominant-first, recessive-first
+ */
+ @Override
+ protected void mergeModelBase_Repositories( ModelBase target, ModelBase source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ List<Repository> src = source.getRepositories();
+ if ( !src.isEmpty() )
+ {
+ List<Repository> tgt = target.getRepositories();
+ Map<Object, Repository> merged = new LinkedHashMap<Object, Repository>( ( src.size() + tgt.size() ) * 2 );
+
+ List<Repository> dominant, recessive;
+ if ( sourceDominant )
+ {
+ dominant = src;
+ recessive = tgt;
+ }
+ else
+ {
+ dominant = tgt;
+ recessive = src;
+ }
+
+ for ( Repository element : dominant )
+ {
+ Object key = getRepositoryKey( element );
+ merged.put( key, element );
+ }
+
+ for ( Repository element : recessive )
+ {
+ Object key = getRepositoryKey( element );
+ if ( !merged.containsKey( key ) )
+ {
+ merged.put( key, element );
+ }
+ }
+
+ target.setRepositories( new ArrayList<Repository>( merged.values() ) );
+ }
+ }
+
+ @Override
+ protected void mergeModelBase_PluginRepositories( ModelBase target, ModelBase source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ List<Repository> src = source.getPluginRepositories();
+ if ( !src.isEmpty() )
+ {
+ List<Repository> tgt = target.getPluginRepositories();
+ Map<Object, Repository> merged = new LinkedHashMap<Object, Repository>( ( src.size() + tgt.size() ) * 2 );
+
+ List<Repository> dominant, recessive;
+ if ( sourceDominant )
+ {
+ dominant = src;
+ recessive = tgt;
+ }
+ else
+ {
+ dominant = tgt;
+ recessive = src;
+ }
+
+ for ( Repository element : dominant )
+ {
+ Object key = getRepositoryKey( element );
+ merged.put( key, element );
+ }
+
+ for ( Repository element : recessive )
+ {
+ Object key = getRepositoryKey( element );
+ if ( !merged.containsKey( key ) )
+ {
+ merged.put( key, element );
+ }
+ }
+
+ target.setPluginRepositories( new ArrayList<Repository>( merged.values() ) );
+ }
+ }
+
+ /*
+ * TODO: Whether duplicates should be removed looks like an option for the generated merger.
+ */
+ @Override
+ protected void mergeBuildBase_Filters( BuildBase target, BuildBase source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ List<String> src = source.getFilters();
+ if ( !src.isEmpty() )
+ {
+ List<String> tgt = target.getFilters();
+ Set<String> excludes = new LinkedHashSet<String>( tgt );
+ List<String> merged = new ArrayList<String>( tgt.size() + src.size() );
+ merged.addAll( tgt );
+ for ( String s : src )
+ {
+ if ( !excludes.contains( s ) )
+ {
+ merged.add( s );
+ }
+ }
+ target.setFilters( merged );
+ }
+ }
+
+ @Override
+ protected void mergeBuildBase_Resources( BuildBase target, BuildBase source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ if ( sourceDominant || target.getResources().isEmpty() )
+ {
+ super.mergeBuildBase_Resources( target, source, sourceDominant, context );
+ }
+ }
+
+ @Override
+ protected void mergeBuildBase_TestResources( BuildBase target, BuildBase source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ if ( sourceDominant || target.getTestResources().isEmpty() )
+ {
+ super.mergeBuildBase_TestResources( target, source, sourceDominant, context );
+ }
+ }
+
+ @Override
+ protected void mergeDistributionManagement_Repository( DistributionManagement target,
+ DistributionManagement source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ DeploymentRepository src = source.getRepository();
+ if ( src != null )
+ {
+ DeploymentRepository tgt = target.getRepository();
+ if ( sourceDominant || tgt == null )
+ {
+ tgt = new DeploymentRepository();
+ tgt.setLocation( "", src.getLocation( "" ) );
+ target.setRepository( tgt );
+ mergeDeploymentRepository( tgt, src, sourceDominant, context );
+ }
+ }
+ }
+
+ @Override
+ protected void mergeDistributionManagement_SnapshotRepository( DistributionManagement target,
+ DistributionManagement source,
+ boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ DeploymentRepository src = source.getSnapshotRepository();
+ if ( src != null )
+ {
+ DeploymentRepository tgt = target.getSnapshotRepository();
+ if ( sourceDominant || tgt == null )
+ {
+ tgt = new DeploymentRepository();
+ tgt.setLocation( "", src.getLocation( "" ) );
+ target.setSnapshotRepository( tgt );
+ mergeDeploymentRepository( tgt, src, sourceDominant, context );
+ }
+ }
+ }
+
+ @Override
+ protected void mergeDistributionManagement_Site( DistributionManagement target, DistributionManagement source,
+ boolean sourceDominant, Map<Object, Object> context )
+ {
+ Site src = source.getSite();
+ if ( src != null )
+ {
+ Site tgt = target.getSite();
+ if ( sourceDominant || tgt == null )
+ {
+ tgt = new Site();
+ tgt.setLocation( "", src.getLocation( "" ) );
+ target.setSite( tgt );
+ mergeSite( tgt, src, sourceDominant, context );
+ }
+ }
+ }
+
+ @Override
+ protected void mergeSite_Url( Site target, Site source, boolean sourceDominant, Map<Object, Object> context )
+ {
+ String src = source.getUrl();
+ if ( src != null )
+ {
+ if ( sourceDominant )
+ {
+ target.setUrl( src );
+ target.setLocation( "url", source.getLocation( "url" ) );
+ }
+ else if ( target.getUrl() == null )
+ {
+ target.setUrl( appendPath( src, context ) );
+ target.setLocation( "url", source.getLocation( "url" ) );
+ }
+ }
+ }
+
+ @Override
+ protected void mergeScm_Url( Scm target, Scm source, boolean sourceDominant, Map<Object, Object> context )
+ {
+ String src = source.getUrl();
+ if ( src != null )
+ {
+ if ( sourceDominant )
+ {
+ target.setUrl( src );
+ target.setLocation( "url", source.getLocation( "url" ) );
+ }
+ else if ( target.getUrl() == null )
+ {
+ target.setUrl( appendPath( src, context ) );
+ target.setLocation( "url", source.getLocation( "url" ) );
+ }
+ }
+ }
+
+ @Override
+ protected void mergeScm_Connection( Scm target, Scm source, boolean sourceDominant, Map<Object, Object> context )
+ {
+ String src = source.getConnection();
+ if ( src != null )
+ {
+ if ( sourceDominant )
+ {
+ target.setConnection( src );
+ target.setLocation( "connection", source.getLocation( "connection" ) );
+ }
+ else if ( target.getConnection() == null )
+ {
+ target.setConnection( appendPath( src, context ) );
+ target.setLocation( "connection", source.getLocation( "connection" ) );
+ }
+ }
+ }
+
+ @Override
+ protected void mergeScm_DeveloperConnection( Scm target, Scm source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ String src = source.getDeveloperConnection();
+ if ( src != null )
+ {
+ if ( sourceDominant )
+ {
+ target.setDeveloperConnection( src );
+ target.setLocation( "developerConnection", source.getLocation( "developerConnection" ) );
+ }
+ else if ( target.getDeveloperConnection() == null )
+ {
+ target.setDeveloperConnection( appendPath( src, context ) );
+ target.setLocation( "developerConnection", source.getLocation( "developerConnection" ) );
+ }
+ }
+ }
+
+ @Override
+ protected void mergePlugin_Executions( Plugin target, Plugin source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ List<PluginExecution> src = source.getExecutions();
+ if ( !src.isEmpty() )
+ {
+ List<PluginExecution> tgt = target.getExecutions();
+ Map<Object, PluginExecution> merged =
+ new LinkedHashMap<Object, PluginExecution>( ( src.size() + tgt.size() ) * 2 );
+
+ for ( PluginExecution element : src )
+ {
+ if ( sourceDominant
+ || ( element.getInherited() != null ? element.isInherited() : source.isInherited() ) )
+ {
+ Object key = getPluginExecutionKey( element );
+ merged.put( key, element );
+ }
+ }
+
+ for ( PluginExecution element : tgt )
+ {
+ Object key = getPluginExecutionKey( element );
+ PluginExecution existing = merged.get( key );
+ if ( existing != null )
+ {
+ mergePluginExecution( element, existing, sourceDominant, context );
+ }
+ merged.put( key, element );
+ }
+
+ target.setExecutions( new ArrayList<PluginExecution>( merged.values() ) );
+ }
+ }
+
+ @Override
+ protected void mergePluginExecution_Goals( PluginExecution target, PluginExecution source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ List<String> src = source.getGoals();
+ if ( !src.isEmpty() )
+ {
+ List<String> tgt = target.getGoals();
+ Set<String> excludes = new LinkedHashSet<String>( tgt );
+ List<String> merged = new ArrayList<String>( tgt.size() + src.size() );
+ merged.addAll( tgt );
+ for ( String s : src )
+ {
+ if ( !excludes.contains( s ) )
+ {
+ merged.add( s );
+ }
+ }
+ target.setGoals( merged );
+ }
+ }
+
+ @Override
+ protected void mergeReportPlugin_ReportSets( ReportPlugin target, ReportPlugin source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ List<ReportSet> src = source.getReportSets();
+ if ( !src.isEmpty() )
+ {
+ List<ReportSet> tgt = target.getReportSets();
+ Map<Object, ReportSet> merged = new LinkedHashMap<Object, ReportSet>( ( src.size() + tgt.size() ) * 2 );
+
+ for ( ReportSet rset : src )
+ {
+ if ( sourceDominant || ( rset.getInherited() != null ? rset.isInherited() : source.isInherited() ) )
+ {
+ Object key = getReportSetKey( rset );
+ merged.put( key, rset );
+ }
+ }
+
+ for ( ReportSet element : tgt )
+ {
+ Object key = getReportSetKey( element );
+ ReportSet existing = merged.get( key );
+ if ( existing != null )
+ {
+ mergeReportSet( element, existing, sourceDominant, context );
+ }
+ merged.put( key, element );
+ }
+
+ target.setReportSets( new ArrayList<ReportSet>( merged.values() ) );
+ }
+ }
+
+ @Override
+ protected Object getDependencyKey( Dependency dependency )
+ {
+ return dependency.getManagementKey();
+ }
+
+ @Override
+ protected Object getPluginKey( Plugin plugin )
+ {
+ return plugin.getKey();
+ }
+
+ @Override
+ protected Object getPluginExecutionKey( PluginExecution pluginExecution )
+ {
+ return pluginExecution.getId();
+ }
+
+ @Override
+ protected Object getReportPluginKey( ReportPlugin reportPlugin )
+ {
+ return reportPlugin.getKey();
+ }
+
+ @Override
+ protected Object getReportSetKey( ReportSet reportSet )
+ {
+ return reportSet.getId();
+ }
+
+ @Override
+ protected Object getRepositoryBaseKey( RepositoryBase repositoryBase )
+ {
+ return repositoryBase.getId();
+ }
+
+ @Override
+ protected Object getExtensionKey( Extension extension )
+ {
+ return extension.getGroupId() + ':' + extension.getArtifactId();
+ }
+
+ @Override
+ protected Object getExclusionKey( Exclusion exclusion )
+ {
+ return exclusion.getGroupId() + ':' + exclusion.getArtifactId();
+ }
+
+ private String appendPath( String parentPath, Map<Object, Object> context )
+ {
+ Object artifactId = context.get( ARTIFACT_ID );
+ Object childPathAdjustment = context.get( CHILD_PATH_ADJUSTMENT );
+
+ if ( artifactId != null && childPathAdjustment != null )
+ {
+ return appendPath( parentPath, artifactId.toString(), childPathAdjustment.toString() );
+ }
+ else
+ {
+ return parentPath;
+ }
+ }
+
+ private String appendPath( String parentPath, String childPath, String pathAdjustment )
+ {
+ String path = parentPath;
+ path = concatPath( path, pathAdjustment );
+ path = concatPath( path, childPath );
+ return path;
+ }
+
+ private String concatPath( String base, String path )
+ {
+ String result = base;
+
+ if ( path != null && path.length() > 0 )
+ {
+ if ( ( result.endsWith( "/" ) && !path.startsWith( "/" ) )
+ || ( !result.endsWith( "/" ) && path.startsWith( "/" ) ) )
+ {
+ result += path;
+ }
+ else if ( result.endsWith( "/" ) && path.startsWith( "/" ) )
+ {
+ result += path.substring( 1 );
+ }
+ else
+ {
+ result += '/';
+ result += path;
+ }
+ if ( base.endsWith( "/" ) && !result.endsWith( "/" ) )
+ {
+ result += '/';
+ }
+ }
+
+ return result;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/normalization/DefaultModelNormalizer.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/normalization/DefaultModelNormalizer.java
new file mode 100644
index 00000000..262dd3f5
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/normalization/DefaultModelNormalizer.java
@@ -0,0 +1,135 @@
+package org.apache.maven.model.normalization;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.maven.model.Build;
+import org.apache.maven.model.Dependency;
+import org.apache.maven.model.Model;
+import org.apache.maven.model.Plugin;
+import org.apache.maven.model.building.ModelBuildingRequest;
+import org.apache.maven.model.building.ModelProblemCollector;
+import org.apache.maven.model.merge.MavenModelMerger;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.util.StringUtils;
+
+/**
+ * Handles normalization of a model.
+ *
+ * @author Benjamin Bentmann
+ */
+@Component( role = ModelNormalizer.class )
+public class DefaultModelNormalizer
+ implements ModelNormalizer
+{
+
+ private DuplicateMerger merger = new DuplicateMerger();
+
+ @Override
+ public void mergeDuplicates( Model model, ModelBuildingRequest request, ModelProblemCollector problems )
+ {
+ Build build = model.getBuild();
+ if ( build != null )
+ {
+ List<Plugin> plugins = build.getPlugins();
+ Map<Object, Plugin> normalized = new LinkedHashMap<Object, Plugin>( plugins.size() * 2 );
+
+ for ( Plugin plugin : plugins )
+ {
+ Object key = plugin.getKey();
+ Plugin first = normalized.get( key );
+ if ( first != null )
+ {
+ merger.mergePlugin( plugin, first );
+ }
+ normalized.put( key, plugin );
+ }
+
+ if ( plugins.size() != normalized.size() )
+ {
+ build.setPlugins( new ArrayList<Plugin>( normalized.values() ) );
+ }
+ }
+
+ /*
+ * NOTE: This is primarily to keep backward-compat with Maven 2.x which did not validate that dependencies are
+ * unique within a single POM. Upon multiple declarations, 2.x just kept the last one but retained the order of
+ * the first occurrence. So when we're in lenient/compat mode, we have to deal with such broken POMs and mimic
+ * the way 2.x works. When we're in strict mode, the removal of duplicates just saves other merging steps from
+ * aftereffects and bogus error messages.
+ */
+ List<Dependency> dependencies = model.getDependencies();
+ Map<String, Dependency> normalized = new LinkedHashMap<String, Dependency>( dependencies.size() * 2 );
+
+ for ( Dependency dependency : dependencies )
+ {
+ normalized.put( dependency.getManagementKey(), dependency );
+ }
+
+ if ( dependencies.size() != normalized.size() )
+ {
+ model.setDependencies( new ArrayList<Dependency>( normalized.values() ) );
+ }
+ }
+
+ protected static class DuplicateMerger
+ extends MavenModelMerger
+ {
+
+ public void mergePlugin( Plugin target, Plugin source )
+ {
+ super.mergePlugin( target, source, false, Collections.emptyMap() );
+ }
+
+ }
+
+ @Override
+ public void injectDefaultValues( Model model, ModelBuildingRequest request, ModelProblemCollector problems )
+ {
+ injectDependencyDefaults( model.getDependencies() );
+
+ Build build = model.getBuild();
+ if ( build != null )
+ {
+ for ( Plugin plugin : build.getPlugins() )
+ {
+ injectDependencyDefaults( plugin.getDependencies() );
+ }
+ }
+ }
+
+ private void injectDependencyDefaults( List<Dependency> dependencies )
+ {
+ for ( Dependency dependency : dependencies )
+ {
+ if ( StringUtils.isEmpty( dependency.getScope() ) )
+ {
+ // we cannot set this directly in the MDO due to the interactions with dependency management
+ dependency.setScope( "compile" );
+ }
+ }
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/normalization/ModelNormalizer.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/normalization/ModelNormalizer.java
new file mode 100644
index 00000000..7cab86b6
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/normalization/ModelNormalizer.java
@@ -0,0 +1,54 @@
+package org.apache.maven.model.normalization;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.model.Model;
+import org.apache.maven.model.building.ModelBuildingRequest;
+import org.apache.maven.model.building.ModelProblemCollector;
+
+/**
+ * Handles normalization of a model. In this context, normalization is the process of producing a canonical
+ * representation for models that physically look different but are semantically equivalent.
+ *
+ * @author Benjamin Bentmann
+ */
+public interface ModelNormalizer
+{
+
+ /**
+ * Merges duplicate elements like multiple declarations of the same build plugin in the specified model.
+ *
+ * @param model The model whose duplicate elements should be merged, must not be {@code null}.
+ * @param request The model building request that holds further settings, must not be {@code null}.
+ * @param problems The container used to collect problems that were encountered, must not be {@code null}.
+ */
+ void mergeDuplicates( Model model, ModelBuildingRequest request, ModelProblemCollector problems );
+
+ /**
+ * Sets default values in the specified model that for technical reasons cannot be set directly in the Modello
+ * definition.
+ *
+ * @param model The model in which to set the default values, must not be {@code null}.
+ * @param request The model building request that holds further settings, must not be {@code null}.
+ * @param problems The container used to collect problems that were encountered, must not be {@code null}.
+ */
+ void injectDefaultValues( Model model, ModelBuildingRequest request, ModelProblemCollector problems );
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/path/DefaultModelPathTranslator.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/path/DefaultModelPathTranslator.java
new file mode 100644
index 00000000..51fa60e6
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/path/DefaultModelPathTranslator.java
@@ -0,0 +1,111 @@
+package org.apache.maven.model.path;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.maven.model.Build;
+import org.apache.maven.model.Model;
+import org.apache.maven.model.Reporting;
+import org.apache.maven.model.Resource;
+import org.apache.maven.model.building.ModelBuildingRequest;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+
+/**
+ * Resolves relative paths within a model against a specific base directory.
+ *
+ * @author Benjamin Bentmann
+ */
+@Component( role = ModelPathTranslator.class )
+public class DefaultModelPathTranslator
+ implements ModelPathTranslator
+{
+
+ @Requirement
+ private PathTranslator pathTranslator;
+
+ public DefaultModelPathTranslator setPathTranslator( PathTranslator pathTranslator )
+ {
+ this.pathTranslator = pathTranslator;
+ return this;
+ }
+
+ @Override
+ public void alignToBaseDirectory( Model model, File basedir, ModelBuildingRequest request )
+ {
+ if ( model == null || basedir == null )
+ {
+ return;
+ }
+
+ Build build = model.getBuild();
+
+ if ( build != null )
+ {
+ build.setDirectory( alignToBaseDirectory( build.getDirectory(), basedir ) );
+
+ build.setSourceDirectory( alignToBaseDirectory( build.getSourceDirectory(), basedir ) );
+
+ build.setTestSourceDirectory( alignToBaseDirectory( build.getTestSourceDirectory(), basedir ) );
+
+ build.setScriptSourceDirectory( alignToBaseDirectory( build.getScriptSourceDirectory(), basedir ) );
+
+ for ( Resource resource : build.getResources() )
+ {
+ resource.setDirectory( alignToBaseDirectory( resource.getDirectory(), basedir ) );
+ }
+
+ for ( Resource resource : build.getTestResources() )
+ {
+ resource.setDirectory( alignToBaseDirectory( resource.getDirectory(), basedir ) );
+ }
+
+ if ( build.getFilters() != null )
+ {
+ List<String> filters = new ArrayList<String>( build.getFilters().size() );
+ for ( String filter : build.getFilters() )
+ {
+ filters.add( alignToBaseDirectory( filter, basedir ) );
+ }
+ build.setFilters( filters );
+ }
+
+ build.setOutputDirectory( alignToBaseDirectory( build.getOutputDirectory(), basedir ) );
+
+ build.setTestOutputDirectory( alignToBaseDirectory( build.getTestOutputDirectory(), basedir ) );
+ }
+
+ Reporting reporting = model.getReporting();
+
+ if ( reporting != null )
+ {
+ reporting.setOutputDirectory( alignToBaseDirectory( reporting.getOutputDirectory(), basedir ) );
+ }
+ }
+
+ private String alignToBaseDirectory( String path, File basedir )
+ {
+ return pathTranslator.alignToBaseDirectory( path, basedir );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/path/DefaultModelUrlNormalizer.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/path/DefaultModelUrlNormalizer.java
new file mode 100644
index 00000000..2093f8fb
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/path/DefaultModelUrlNormalizer.java
@@ -0,0 +1,84 @@
+package org.apache.maven.model.path;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.model.DistributionManagement;
+import org.apache.maven.model.Model;
+import org.apache.maven.model.Scm;
+import org.apache.maven.model.Site;
+import org.apache.maven.model.building.ModelBuildingRequest;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+
+/**
+ * Normalizes URLs to remove the ugly parent references "../" that got potentially inserted by URL adjustment during
+ * model inheritance.
+ *
+ * @author Benjamin Bentmann
+ */
+@Component( role = ModelUrlNormalizer.class )
+public class DefaultModelUrlNormalizer
+ implements ModelUrlNormalizer
+{
+
+ @Requirement
+ private UrlNormalizer urlNormalizer;
+
+ public DefaultModelUrlNormalizer setUrlNormalizer( UrlNormalizer urlNormalizer )
+ {
+ this.urlNormalizer = urlNormalizer;
+ return this;
+ }
+
+ @Override
+ public void normalize( Model model, ModelBuildingRequest request )
+ {
+ if ( model == null )
+ {
+ return;
+ }
+
+ model.setUrl( normalize( model.getUrl() ) );
+
+ Scm scm = model.getScm();
+ if ( scm != null )
+ {
+ scm.setUrl( normalize( scm.getUrl() ) );
+ scm.setConnection( normalize( scm.getConnection() ) );
+ scm.setDeveloperConnection( normalize( scm.getDeveloperConnection() ) );
+ }
+
+ DistributionManagement dist = model.getDistributionManagement();
+ if ( dist != null )
+ {
+ Site site = dist.getSite();
+ if ( site != null )
+ {
+ site.setUrl( normalize( site.getUrl() ) );
+ }
+ }
+ }
+
+ private String normalize( String url )
+ {
+ return urlNormalizer.normalize( url );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/path/DefaultPathTranslator.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/path/DefaultPathTranslator.java
new file mode 100644
index 00000000..1ad9d034
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/path/DefaultPathTranslator.java
@@ -0,0 +1,66 @@
+package org.apache.maven.model.path;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+
+import org.codehaus.plexus.component.annotations.Component;
+
+/**
+ * Resolves relative paths against a specific base directory.
+ *
+ * @author Benjamin Bentmann
+ */
+@Component( role = PathTranslator.class )
+public class DefaultPathTranslator
+ implements PathTranslator
+{
+
+ @Override
+ public String alignToBaseDirectory( String path, File basedir )
+ {
+ String result = path;
+
+ if ( path != null && basedir != null )
+ {
+ path = path.replace( '\\', File.separatorChar ).replace( '/', File.separatorChar );
+
+ File file = new File( path );
+ if ( file.isAbsolute() )
+ {
+ // path was already absolute, just normalize file separator and we're done
+ result = file.getPath();
+ }
+ else if ( file.getPath().startsWith( File.separator ) )
+ {
+ // drive-relative Windows path, don't align with project directory but with drive root
+ result = file.getAbsolutePath();
+ }
+ else
+ {
+ // an ordinary relative path, align with project directory
+ result = new File( new File( basedir, path ).toURI().normalize() ).getAbsolutePath();
+ }
+ }
+
+ return result;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/path/DefaultUrlNormalizer.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/path/DefaultUrlNormalizer.java
new file mode 100644
index 00000000..120b02f1
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/path/DefaultUrlNormalizer.java
@@ -0,0 +1,65 @@
+package org.apache.maven.model.path;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.codehaus.plexus.component.annotations.Component;
+
+/**
+ * Normalizes a URL.
+ *
+ * @author Benjamin Bentmann
+ */
+@Component( role = UrlNormalizer.class )
+public class DefaultUrlNormalizer
+ implements UrlNormalizer
+{
+
+ @Override
+ public String normalize( String url )
+ {
+ String result = url;
+
+ if ( result != null )
+ {
+ while ( true )
+ {
+ int idx = result.indexOf( "/../" );
+ if ( idx <= 0 )
+ {
+ break;
+ }
+ int parent = idx - 1;
+ while ( parent >= 0 && result.charAt( parent ) == '/' )
+ {
+ parent--;
+ }
+ parent = result.lastIndexOf( '/', parent );
+ if ( parent < 0 )
+ {
+ break;
+ }
+ result = result.substring( 0, parent ) + result.substring( idx + 3 );
+ }
+ }
+
+ return result;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/path/ModelPathTranslator.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/path/ModelPathTranslator.java
new file mode 100644
index 00000000..2bd39c55
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/path/ModelPathTranslator.java
@@ -0,0 +1,45 @@
+package org.apache.maven.model.path;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+
+import org.apache.maven.model.Model;
+import org.apache.maven.model.building.ModelBuildingRequest;
+
+/**
+ * Resolves relative paths of a model against a specific base directory.
+ *
+ * @author Jason van Zyl
+ */
+public interface ModelPathTranslator
+{
+
+ /**
+ * Resolves the well-known paths of the specified model against the given base directory. Paths within plugin
+ * configuration are not processed.
+ *
+ * @param model The model whose paths should be resolved, may be {@code null}.
+ * @param basedir The base directory to resolve relative paths against, may be {@code null}.
+ * @param request The model building request that holds further settings, must not be {@code null}.
+ */
+ void alignToBaseDirectory( Model model, File basedir, ModelBuildingRequest request );
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/path/ModelUrlNormalizer.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/path/ModelUrlNormalizer.java
new file mode 100644
index 00000000..8325b05d
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/path/ModelUrlNormalizer.java
@@ -0,0 +1,42 @@
+package org.apache.maven.model.path;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.model.Model;
+import org.apache.maven.model.building.ModelBuildingRequest;
+
+/**
+ * Normalizes URLs to remove the ugly parent references "../" that got potentially inserted by URL adjustment during
+ * model inheritance.
+ *
+ * @author Benjamin Bentmann
+ */
+public interface ModelUrlNormalizer
+{
+
+ /**
+ * Normalizes the well-known URLs of the specified model.
+ *
+ * @param model The model whose URLs should be normalized, may be {@code null}.
+ * @param request The model building request that holds further settings, must not be {@code null}.
+ */
+ void normalize( Model model, ModelBuildingRequest request );
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/path/PathTranslator.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/path/PathTranslator.java
new file mode 100644
index 00000000..c416e6ab
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/path/PathTranslator.java
@@ -0,0 +1,43 @@
+package org.apache.maven.model.path;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+
+/**
+ * Resolves relative paths against a specific base directory.
+ *
+ * @author Jason van Zyl
+ */
+public interface PathTranslator
+{
+
+ /**
+ * Resolves the specified path against the given base directory. The resolved path will be absolute and uses the
+ * platform-specific file separator if a base directory is given. Otherwise, the input path will be returned
+ * unaltered.
+ *
+ * @param path The path to resolve, may be {@code null}.
+ * @param basedir The base directory to resolve relative paths against, may be {@code null}.
+ * @return The resolved path or {@code null} if the input path was {@code null}.
+ */
+ String alignToBaseDirectory( String path, File basedir );
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/path/UrlNormalizer.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/path/UrlNormalizer.java
new file mode 100644
index 00000000..b2e4a7b1
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/path/UrlNormalizer.java
@@ -0,0 +1,39 @@
+package org.apache.maven.model.path;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Normalizes a URL to remove the ugly parent references "../" that got potentially inserted by URL adjustment during
+ * model inheritance.
+ *
+ * @author Benjamin Bentmann
+ */
+public interface UrlNormalizer
+{
+
+ /**
+ * Normalizes the specified URL.
+ *
+ * @param url The URL to normalize, may be {@code null}.
+ * @return The normalized URL or {@code null} if the input was {@code null}.
+ */
+ String normalize( String url );
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/plugin/DefaultPluginConfigurationExpander.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/plugin/DefaultPluginConfigurationExpander.java
new file mode 100644
index 00000000..dc7cf13b
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/plugin/DefaultPluginConfigurationExpander.java
@@ -0,0 +1,83 @@
+package org.apache.maven.model.plugin;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.List;
+
+import org.apache.maven.model.Build;
+import org.apache.maven.model.Model;
+import org.apache.maven.model.Plugin;
+import org.apache.maven.model.PluginExecution;
+import org.apache.maven.model.PluginManagement;
+import org.apache.maven.model.building.ModelBuildingRequest;
+import org.apache.maven.model.building.ModelProblemCollector;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.util.xml.Xpp3Dom;
+
+/**
+ * Handles expansion of general build plugin configuration into individual executions.
+ *
+ * @author Benjamin Bentmann
+ */
+@Component( role = PluginConfigurationExpander.class )
+public class DefaultPluginConfigurationExpander
+ implements PluginConfigurationExpander
+{
+
+ @Override
+ public void expandPluginConfiguration( Model model, ModelBuildingRequest request, ModelProblemCollector problems )
+ {
+ Build build = model.getBuild();
+
+ if ( build != null )
+ {
+ expand( build.getPlugins() );
+
+ PluginManagement pluginManagement = build.getPluginManagement();
+
+ if ( pluginManagement != null )
+ {
+ expand( pluginManagement.getPlugins() );
+ }
+ }
+ }
+
+ private void expand( List<Plugin> plugins )
+ {
+ for ( Plugin plugin : plugins )
+ {
+ Xpp3Dom pluginConfiguration = (Xpp3Dom) plugin.getConfiguration();
+
+ if ( pluginConfiguration != null )
+ {
+ for ( PluginExecution execution : plugin.getExecutions() )
+ {
+ Xpp3Dom executionConfiguration = (Xpp3Dom) execution.getConfiguration();
+
+ executionConfiguration =
+ Xpp3Dom.mergeXpp3Dom( executionConfiguration, new Xpp3Dom( pluginConfiguration ) );
+
+ execution.setConfiguration( executionConfiguration );
+ }
+ }
+ }
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/plugin/DefaultReportConfigurationExpander.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/plugin/DefaultReportConfigurationExpander.java
new file mode 100644
index 00000000..9c842994
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/plugin/DefaultReportConfigurationExpander.java
@@ -0,0 +1,65 @@
+package org.apache.maven.model.plugin;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.model.Model;
+import org.apache.maven.model.ReportPlugin;
+import org.apache.maven.model.ReportSet;
+import org.apache.maven.model.Reporting;
+import org.apache.maven.model.building.ModelBuildingRequest;
+import org.apache.maven.model.building.ModelProblemCollector;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.util.xml.Xpp3Dom;
+
+/**
+ * Handles expansion of general report plugin configuration into individual report sets.
+ *
+ * @author Benjamin Bentmann
+ */
+@Component( role = ReportConfigurationExpander.class )
+public class DefaultReportConfigurationExpander
+ implements ReportConfigurationExpander
+{
+
+ @Override
+ public void expandPluginConfiguration( Model model, ModelBuildingRequest request, ModelProblemCollector problems )
+ {
+ Reporting reporting = model.getReporting();
+
+ if ( reporting != null )
+ {
+ for ( ReportPlugin reportPlugin : reporting.getPlugins() )
+ {
+ Xpp3Dom parentDom = (Xpp3Dom) reportPlugin.getConfiguration();
+
+ if ( parentDom != null )
+ {
+ for ( ReportSet execution : reportPlugin.getReportSets() )
+ {
+ Xpp3Dom childDom = (Xpp3Dom) execution.getConfiguration();
+ childDom = Xpp3Dom.mergeXpp3Dom( childDom, new Xpp3Dom( parentDom ) );
+ execution.setConfiguration( childDom );
+ }
+ }
+ }
+ }
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/plugin/DefaultReportingConverter.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/plugin/DefaultReportingConverter.java
new file mode 100644
index 00000000..d918d9e8
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/plugin/DefaultReportingConverter.java
@@ -0,0 +1,240 @@
+package org.apache.maven.model.plugin;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.model.Build;
+import org.apache.maven.model.Model;
+import org.apache.maven.model.Plugin;
+import org.apache.maven.model.PluginManagement;
+import org.apache.maven.model.ReportPlugin;
+import org.apache.maven.model.ReportSet;
+import org.apache.maven.model.Reporting;
+import org.apache.maven.model.building.ModelBuildingRequest;
+import org.apache.maven.model.building.ModelProblemCollector;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.util.StringUtils;
+import org.codehaus.plexus.util.xml.Xpp3Dom;
+
+/**
+ * Handles conversion of the legacy reporting section into the configuration of the new Maven Site Plugin.
+ *
+ * @author Benjamin Bentmann
+ */
+@Component( role = ReportingConverter.class )
+public class DefaultReportingConverter
+ implements ReportingConverter
+{
+
+ @Override
+ public void convertReporting( Model model, ModelBuildingRequest request, ModelProblemCollector problems )
+ {
+ Reporting reporting = model.getReporting();
+
+ if ( reporting == null )
+ {
+ return;
+ }
+
+ Build build = model.getBuild();
+
+ if ( build == null )
+ {
+ build = new Build();
+ model.setBuild( build );
+ }
+
+ Plugin sitePlugin = findSitePlugin( build );
+
+ if ( sitePlugin == null )
+ {
+ sitePlugin = new Plugin();
+ sitePlugin.setArtifactId( "maven-site-plugin" );
+ PluginManagement pluginManagement = build.getPluginManagement();
+ if ( pluginManagement == null )
+ {
+ pluginManagement = new PluginManagement();
+ build.setPluginManagement( pluginManagement );
+ }
+ pluginManagement.addPlugin( sitePlugin );
+ }
+
+ Xpp3Dom configuration = (Xpp3Dom) sitePlugin.getConfiguration();
+
+ if ( configuration == null )
+ {
+ configuration = new Xpp3Dom( "configuration" );
+ sitePlugin.setConfiguration( configuration );
+ }
+
+ Xpp3Dom reportPlugins = configuration.getChild( "reportPlugins" );
+
+ if ( reportPlugins != null )
+ {
+ // new-style report configuration already present, assume user handled entire conversion
+ return;
+ }
+
+ if ( configuration.getChild( "outputDirectory" ) == null )
+ {
+ addDom( configuration, "outputDirectory", reporting.getOutputDirectory() );
+ }
+
+ reportPlugins = new Xpp3Dom( "reportPlugins" );
+ configuration.addChild( reportPlugins );
+
+ boolean hasMavenProjectInfoReportsPlugin = false;
+
+ /* waiting for MSITE-484 before deprecating <reporting> section
+ if ( !reporting.getPlugins().isEmpty()
+ && request.getValidationLevel() >= ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_3_1 )
+ {
+
+ problems.add( new ModelProblemCollectorRequest( Severity.WARNING, Version.V31 )
+ .setMessage( "The <reporting> section is deprecated, please move the reports to the <configuration>"
+ + " section of the new Maven Site Plugin." )
+ .setLocation( reporting.getLocation( "" ) ) );
+ }*/
+
+ for ( ReportPlugin plugin : reporting.getPlugins() )
+ {
+ Xpp3Dom reportPlugin = convert( plugin );
+ reportPlugins.addChild( reportPlugin );
+
+ if ( !reporting.isExcludeDefaults() && !hasMavenProjectInfoReportsPlugin
+ && "org.apache.maven.plugins".equals( plugin.getGroupId() )
+ && "maven-project-info-reports-plugin".equals( plugin.getArtifactId() ) )
+ {
+ hasMavenProjectInfoReportsPlugin = true;
+ }
+ }
+
+ if ( !reporting.isExcludeDefaults() && !hasMavenProjectInfoReportsPlugin )
+ {
+ Xpp3Dom dom = new Xpp3Dom( "reportPlugin" );
+
+ addDom( dom, "groupId", "org.apache.maven.plugins" );
+ addDom( dom, "artifactId", "maven-project-info-reports-plugin" );
+
+ reportPlugins.addChild( dom );
+ }
+ }
+
+ private Plugin findSitePlugin( Build build )
+ {
+ for ( Plugin plugin : build.getPlugins() )
+ {
+ if ( isSitePlugin( plugin ) )
+ {
+ return plugin;
+ }
+ }
+
+ PluginManagement pluginManagement = build.getPluginManagement();
+ if ( pluginManagement != null )
+ {
+ for ( Plugin plugin : pluginManagement.getPlugins() )
+ {
+ if ( isSitePlugin( plugin ) )
+ {
+ return plugin;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ private boolean isSitePlugin( Plugin plugin )
+ {
+ return "maven-site-plugin".equals( plugin.getArtifactId() )
+ && "org.apache.maven.plugins".equals( plugin.getGroupId() );
+ }
+
+ private Xpp3Dom convert( ReportPlugin plugin )
+ {
+ Xpp3Dom dom = new Xpp3Dom( "reportPlugin" );
+
+ addDom( dom, "groupId", plugin.getGroupId() );
+ addDom( dom, "artifactId", plugin.getArtifactId() );
+ addDom( dom, "version", plugin.getVersion() );
+
+ Xpp3Dom configuration = (Xpp3Dom) plugin.getConfiguration();
+ if ( configuration != null )
+ {
+ configuration = new Xpp3Dom( configuration );
+ dom.addChild( configuration );
+ }
+
+ if ( !plugin.getReportSets().isEmpty() )
+ {
+ Xpp3Dom reportSets = new Xpp3Dom( "reportSets" );
+ for ( ReportSet reportSet : plugin.getReportSets() )
+ {
+ Xpp3Dom rs = convert( reportSet );
+ reportSets.addChild( rs );
+ }
+ dom.addChild( reportSets );
+ }
+
+ return dom;
+ }
+
+ private Xpp3Dom convert( ReportSet reportSet )
+ {
+ Xpp3Dom dom = new Xpp3Dom( "reportSet" );
+
+ addDom( dom, "id", reportSet.getId() );
+
+ Xpp3Dom configuration = (Xpp3Dom) reportSet.getConfiguration();
+ if ( configuration != null )
+ {
+ configuration = new Xpp3Dom( configuration );
+ dom.addChild( configuration );
+ }
+
+ if ( !reportSet.getReports().isEmpty() )
+ {
+ Xpp3Dom reports = new Xpp3Dom( "reports" );
+ for ( String report : reportSet.getReports() )
+ {
+ addDom( reports, "report", report );
+ }
+ dom.addChild( reports );
+ }
+
+ return dom;
+ }
+
+ private void addDom( Xpp3Dom parent, String childName, String childValue )
+ {
+ if ( StringUtils.isNotEmpty( childValue ) )
+ {
+ parent.addChild( newDom( childName, childValue ) );
+ }
+ }
+
+ private Xpp3Dom newDom( String name, String value )
+ {
+ Xpp3Dom dom = new Xpp3Dom( name );
+ dom.setValue( value );
+ return dom;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/plugin/LifecycleBindingsInjector.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/plugin/LifecycleBindingsInjector.java
new file mode 100644
index 00000000..9c0f06de
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/plugin/LifecycleBindingsInjector.java
@@ -0,0 +1,46 @@
+package org.apache.maven.model.plugin;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.model.Model;
+import org.apache.maven.model.building.ModelBuildingRequest;
+import org.apache.maven.model.building.ModelProblemCollector;
+
+/**
+ * Handles injection of plugin executions induced by the lifecycle bindings for a packaging.
+ *
+ * @author Benjamin Bentmann
+ */
+public interface LifecycleBindingsInjector
+{
+
+ /**
+ * Injects plugin executions induced by lifecycle bindings into the specified model. The model has already undergone
+ * injection of plugin management so any plugins that are injected by lifecycle bindings and are not already present
+ * in the model's plugin section need to be subjected to the model's plugin management.
+ *
+ * @param model The model into which to inject the default plugin executions for its packaging, must not be
+ * <code>null</code>.
+ * @param request The model building request that holds further settings, must not be {@code null}.
+ * @param problems The container used to collect problems that were encountered, must not be {@code null}.
+ */
+ void injectLifecycleBindings( Model model, ModelBuildingRequest request, ModelProblemCollector problems );
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/plugin/PluginConfigurationExpander.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/plugin/PluginConfigurationExpander.java
new file mode 100644
index 00000000..23994aa6
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/plugin/PluginConfigurationExpander.java
@@ -0,0 +1,43 @@
+package org.apache.maven.model.plugin;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.model.Model;
+import org.apache.maven.model.building.ModelBuildingRequest;
+import org.apache.maven.model.building.ModelProblemCollector;
+
+/**
+ * Handles expansion of general build plugin configuration into individual executions.
+ *
+ * @author Benjamin Bentmann
+ */
+public interface PluginConfigurationExpander
+{
+
+ /**
+ * Merges values from general build plugin configuration into the individual plugin executions of the given model.
+ *
+ * @param model The model whose build plugin configuration should be expanded, must not be <code>null</code>.
+ * @param request The model building request that holds further settings, must not be {@code null}.
+ * @param problems The container used to collect problems that were encountered, must not be {@code null}.
+ */
+ void expandPluginConfiguration( Model model, ModelBuildingRequest request, ModelProblemCollector problems );
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/plugin/ReportConfigurationExpander.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/plugin/ReportConfigurationExpander.java
new file mode 100644
index 00000000..28ad5962
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/plugin/ReportConfigurationExpander.java
@@ -0,0 +1,43 @@
+package org.apache.maven.model.plugin;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.model.Model;
+import org.apache.maven.model.building.ModelBuildingRequest;
+import org.apache.maven.model.building.ModelProblemCollector;
+
+/**
+ * Handles expansion of general report plugin configuration into individual report sets.
+ *
+ * @author Benjamin Bentmann
+ */
+public interface ReportConfigurationExpander
+{
+
+ /**
+ * Merges values from general report plugin configuration into the individual reports sets of the given model.
+ *
+ * @param model The model whose report plugin configuration should be expanded, must not be <code>null</code>.
+ * @param request The model building request that holds further settings, must not be {@code null}.
+ * @param problems The container used to collect problems that were encountered, must not be {@code null}.
+ */
+ void expandPluginConfiguration( Model model, ModelBuildingRequest request, ModelProblemCollector problems );
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/plugin/ReportingConverter.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/plugin/ReportingConverter.java
new file mode 100644
index 00000000..c5ea338c
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/plugin/ReportingConverter.java
@@ -0,0 +1,43 @@
+package org.apache.maven.model.plugin;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.model.Model;
+import org.apache.maven.model.building.ModelBuildingRequest;
+import org.apache.maven.model.building.ModelProblemCollector;
+
+/**
+ * Handles conversion of the legacy reporting section into the configuration of the new Maven Site Plugin.
+ *
+ * @author Benjamin Bentmann
+ */
+public interface ReportingConverter
+{
+
+ /**
+ * Converts values from model's reporting section into the configuration for the new Maven Site Plugin.
+ *
+ * @param model The model whose reporting section should be converted, must not be <code>null</code>.
+ * @param request The model building request that holds further settings, must not be {@code null}.
+ * @param problems The container used to collect problems that were encountered, must not be {@code null}.
+ */
+ void convertReporting( Model model, ModelBuildingRequest request, ModelProblemCollector problems );
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/profile/DefaultProfileActivationContext.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/profile/DefaultProfileActivationContext.java
new file mode 100644
index 00000000..bb38a2e0
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/profile/DefaultProfileActivationContext.java
@@ -0,0 +1,259 @@
+package org.apache.maven.model.profile;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+/**
+ * Describes the environmental context used to determine the activation status of profiles.
+ *
+ * @author Benjamin Bentmann
+ */
+public class DefaultProfileActivationContext
+ implements ProfileActivationContext
+{
+
+ private List<String> activeProfileIds = Collections.emptyList();
+
+ private List<String> inactiveProfileIds = Collections.emptyList();
+
+ private Map<String, String> systemProperties = Collections.emptyMap();
+
+ private Map<String, String> userProperties = Collections.emptyMap();
+
+ private Map<String, String> projectProperties = Collections.emptyMap();
+
+ private File projectDirectory;
+
+ @Override
+ public List<String> getActiveProfileIds()
+ {
+ return activeProfileIds;
+ }
+
+ /**
+ * Sets the identifiers of those profiles that should be activated by explicit demand.
+ *
+ * @param activeProfileIds The identifiers of those profiles to activate, may be {@code null}.
+ * @return This context, never {@code null}.
+ */
+ public DefaultProfileActivationContext setActiveProfileIds( List<String> activeProfileIds )
+ {
+ if ( activeProfileIds != null )
+ {
+ this.activeProfileIds = Collections.unmodifiableList( activeProfileIds );
+ }
+ else
+ {
+ this.activeProfileIds = Collections.emptyList();
+ }
+
+ return this;
+ }
+
+ @Override
+ public List<String> getInactiveProfileIds()
+ {
+ return inactiveProfileIds;
+ }
+
+ /**
+ * Sets the identifiers of those profiles that should be deactivated by explicit demand.
+ *
+ * @param inactiveProfileIds The identifiers of those profiles to deactivate, may be {@code null}.
+ * @return This context, never {@code null}.
+ */
+ public DefaultProfileActivationContext setInactiveProfileIds( List<String> inactiveProfileIds )
+ {
+ if ( inactiveProfileIds != null )
+ {
+ this.inactiveProfileIds = Collections.unmodifiableList( inactiveProfileIds );
+ }
+ else
+ {
+ this.inactiveProfileIds = Collections.emptyList();
+ }
+
+ return this;
+ }
+
+ @Override
+ public Map<String, String> getSystemProperties()
+ {
+ return systemProperties;
+ }
+
+ /**
+ * Sets the system properties to use for interpolation and profile activation. The system properties are collected
+ * from the runtime environment like {@link System#getProperties()} and environment variables.
+ *
+ * @param systemProperties The system properties, may be {@code null}.
+ * @return This context, never {@code null}.
+ */
+ @SuppressWarnings( "unchecked" )
+ public DefaultProfileActivationContext setSystemProperties( Properties systemProperties )
+ {
+ if ( systemProperties != null )
+ {
+ this.systemProperties = Collections.unmodifiableMap( (Map) systemProperties );
+ }
+ else
+ {
+ this.systemProperties = Collections.emptyMap();
+ }
+
+ return this;
+ }
+
+ /**
+ * Sets the system properties to use for interpolation and profile activation. The system properties are collected
+ * from the runtime environment like {@link System#getProperties()} and environment variables.
+ *
+ * @param systemProperties The system properties, may be {@code null}.
+ * @return This context, never {@code null}.
+ */
+ public DefaultProfileActivationContext setSystemProperties( Map<String, String> systemProperties )
+ {
+ if ( systemProperties != null )
+ {
+ this.systemProperties = Collections.unmodifiableMap( systemProperties );
+ }
+ else
+ {
+ this.systemProperties = Collections.emptyMap();
+ }
+
+ return this;
+ }
+
+ @Override
+ public Map<String, String> getUserProperties()
+ {
+ return userProperties;
+ }
+
+ /**
+ * Sets the user properties to use for interpolation and profile activation. The user properties have been
+ * configured directly by the user on his discretion, e.g. via the {@code -Dkey=value} parameter on the command
+ * line.
+ *
+ * @param userProperties The user properties, may be {@code null}.
+ * @return This context, never {@code null}.
+ */
+ @SuppressWarnings( "unchecked" )
+ public DefaultProfileActivationContext setUserProperties( Properties userProperties )
+ {
+ if ( userProperties != null )
+ {
+ this.userProperties = Collections.unmodifiableMap( (Map) userProperties );
+ }
+ else
+ {
+ this.userProperties = Collections.emptyMap();
+ }
+
+ return this;
+ }
+
+ /**
+ * Sets the user properties to use for interpolation and profile activation. The user properties have been
+ * configured directly by the user on his discretion, e.g. via the {@code -Dkey=value} parameter on the command
+ * line.
+ *
+ * @param userProperties The user properties, may be {@code null}.
+ * @return This context, never {@code null}.
+ */
+ public DefaultProfileActivationContext setUserProperties( Map<String, String> userProperties )
+ {
+ if ( userProperties != null )
+ {
+ this.userProperties = Collections.unmodifiableMap( userProperties );
+ }
+ else
+ {
+ this.userProperties = Collections.emptyMap();
+ }
+
+ return this;
+ }
+
+ @Override
+ public File getProjectDirectory()
+ {
+ return projectDirectory;
+ }
+
+ /**
+ * Sets the base directory of the current project.
+ *
+ * @param projectDirectory The base directory of the current project, may be {@code null} if profile activation
+ * happens in the context of metadata retrieval rather than project building.
+ * @return This context, never {@code null}.
+ */
+ public DefaultProfileActivationContext setProjectDirectory( File projectDirectory )
+ {
+ this.projectDirectory = projectDirectory;
+
+ return this;
+ }
+
+ @Override
+ public Map<String, String> getProjectProperties()
+ {
+ return projectProperties;
+ }
+
+ public DefaultProfileActivationContext setProjectProperties( Properties projectProperties )
+ {
+ if ( projectProperties != null )
+ {
+
+ this.projectProperties = Collections.unmodifiableMap( toMap( projectProperties ) );
+ }
+ else
+ {
+ this.projectProperties = Collections.emptyMap();
+ }
+
+ return this;
+ }
+
+ private Map<String, String> toMap( Properties properties )
+ {
+ if ( properties == null )
+ {
+ return Collections.emptyMap();
+ }
+ Map<String, String> map = new HashMap<String, String>();
+ Enumeration keys = properties.keys();
+ while ( keys.hasMoreElements() )
+ {
+ String key = (String) keys.nextElement();
+ map.put( key, properties.getProperty( key ) );
+ }
+ return map;
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/profile/DefaultProfileInjector.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/profile/DefaultProfileInjector.java
new file mode 100644
index 00000000..aeed0235
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/profile/DefaultProfileInjector.java
@@ -0,0 +1,249 @@
+package org.apache.maven.model.profile;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.maven.model.Build;
+import org.apache.maven.model.BuildBase;
+import org.apache.maven.model.Model;
+import org.apache.maven.model.ModelBase;
+import org.apache.maven.model.Plugin;
+import org.apache.maven.model.PluginContainer;
+import org.apache.maven.model.PluginExecution;
+import org.apache.maven.model.Profile;
+import org.apache.maven.model.ReportPlugin;
+import org.apache.maven.model.ReportSet;
+import org.apache.maven.model.Reporting;
+import org.apache.maven.model.building.ModelBuildingRequest;
+import org.apache.maven.model.building.ModelProblemCollector;
+import org.apache.maven.model.merge.MavenModelMerger;
+import org.codehaus.plexus.component.annotations.Component;
+
+/**
+ * Handles profile injection into the model.
+ *
+ * @author Benjamin Bentmann
+ */
+@Component( role = ProfileInjector.class )
+public class DefaultProfileInjector
+ implements ProfileInjector
+{
+
+ private ProfileModelMerger merger = new ProfileModelMerger();
+
+ @Override
+ public void injectProfile( Model model, Profile profile, ModelBuildingRequest request,
+ ModelProblemCollector problems )
+ {
+ if ( profile != null )
+ {
+ merger.mergeModelBase( model, profile );
+
+ if ( profile.getBuild() != null )
+ {
+ if ( model.getBuild() == null )
+ {
+ model.setBuild( new Build() );
+ }
+ merger.mergeBuildBase( model.getBuild(), profile.getBuild() );
+ }
+ }
+ }
+
+ protected static class ProfileModelMerger
+ extends MavenModelMerger
+ {
+
+ public void mergeModelBase( ModelBase target, ModelBase source )
+ {
+ mergeModelBase( target, source, true, Collections.emptyMap() );
+ }
+
+ public void mergeBuildBase( BuildBase target, BuildBase source )
+ {
+ mergeBuildBase( target, source, true, Collections.emptyMap() );
+ }
+
+ @Override
+ protected void mergePluginContainer_Plugins( PluginContainer target, PluginContainer source,
+ boolean sourceDominant, Map<Object, Object> context )
+ {
+ List<Plugin> src = source.getPlugins();
+ if ( !src.isEmpty() )
+ {
+ List<Plugin> tgt = target.getPlugins();
+ Map<Object, Plugin> master = new LinkedHashMap<Object, Plugin>( tgt.size() * 2 );
+
+ for ( Plugin element : tgt )
+ {
+ Object key = getPluginKey( element );
+ master.put( key, element );
+ }
+
+ Map<Object, List<Plugin>> predecessors = new LinkedHashMap<Object, List<Plugin>>();
+ List<Plugin> pending = new ArrayList<Plugin>();
+ for ( Plugin element : src )
+ {
+ Object key = getPluginKey( element );
+ Plugin existing = master.get( key );
+ if ( existing != null )
+ {
+ mergePlugin( existing, element, sourceDominant, context );
+
+ if ( !pending.isEmpty() )
+ {
+ predecessors.put( key, pending );
+ pending = new ArrayList<Plugin>();
+ }
+ }
+ else
+ {
+ pending.add( element );
+ }
+ }
+
+ List<Plugin> result = new ArrayList<Plugin>( src.size() + tgt.size() );
+ for ( Map.Entry<Object, Plugin> entry : master.entrySet() )
+ {
+ List<Plugin> pre = predecessors.get( entry.getKey() );
+ if ( pre != null )
+ {
+ result.addAll( pre );
+ }
+ result.add( entry.getValue() );
+ }
+ result.addAll( pending );
+
+ target.setPlugins( result );
+ }
+ }
+
+ @Override
+ protected void mergePlugin_Executions( Plugin target, Plugin source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ List<PluginExecution> src = source.getExecutions();
+ if ( !src.isEmpty() )
+ {
+ List<PluginExecution> tgt = target.getExecutions();
+ Map<Object, PluginExecution> merged =
+ new LinkedHashMap<Object, PluginExecution>( ( src.size() + tgt.size() ) * 2 );
+
+ for ( PluginExecution element : tgt )
+ {
+ Object key = getPluginExecutionKey( element );
+ merged.put( key, element );
+ }
+
+ for ( PluginExecution element : src )
+ {
+ Object key = getPluginExecutionKey( element );
+ PluginExecution existing = merged.get( key );
+ if ( existing != null )
+ {
+ mergePluginExecution( existing, element, sourceDominant, context );
+ }
+ else
+ {
+ merged.put( key, element );
+ }
+ }
+
+ target.setExecutions( new ArrayList<PluginExecution>( merged.values() ) );
+ }
+ }
+
+ @Override
+ protected void mergeReporting_Plugins( Reporting target, Reporting source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ List<ReportPlugin> src = source.getPlugins();
+ if ( !src.isEmpty() )
+ {
+ List<ReportPlugin> tgt = target.getPlugins();
+ Map<Object, ReportPlugin> merged =
+ new LinkedHashMap<Object, ReportPlugin>( ( src.size() + tgt.size() ) * 2 );
+
+ for ( ReportPlugin element : tgt )
+ {
+ Object key = getReportPluginKey( element );
+ merged.put( key, element );
+ }
+
+ for ( ReportPlugin element : src )
+ {
+ Object key = getReportPluginKey( element );
+ ReportPlugin existing = merged.get( key );
+ if ( existing == null )
+ {
+ merged.put( key, element );
+ }
+ else
+ {
+ mergeReportPlugin( existing, element, sourceDominant, context );
+ }
+ }
+
+ target.setPlugins( new ArrayList<ReportPlugin>( merged.values() ) );
+ }
+ }
+
+ @Override
+ protected void mergeReportPlugin_ReportSets( ReportPlugin target, ReportPlugin source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ List<ReportSet> src = source.getReportSets();
+ if ( !src.isEmpty() )
+ {
+ List<ReportSet> tgt = target.getReportSets();
+ Map<Object, ReportSet> merged = new LinkedHashMap<Object, ReportSet>( ( src.size() + tgt.size() ) * 2 );
+
+ for ( ReportSet element : tgt )
+ {
+ Object key = getReportSetKey( element );
+ merged.put( key, element );
+ }
+
+ for ( ReportSet element : src )
+ {
+ Object key = getReportSetKey( element );
+ ReportSet existing = merged.get( key );
+ if ( existing != null )
+ {
+ mergeReportSet( existing, element, sourceDominant, context );
+ }
+ else
+ {
+ merged.put( key, element );
+ }
+ }
+
+ target.setReportSets( new ArrayList<ReportSet>( merged.values() ) );
+ }
+ }
+
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/profile/DefaultProfileSelector.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/profile/DefaultProfileSelector.java
new file mode 100644
index 00000000..512476a1
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/profile/DefaultProfileSelector.java
@@ -0,0 +1,143 @@
+package org.apache.maven.model.profile;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+
+import org.apache.maven.model.Activation;
+import org.apache.maven.model.Profile;
+import org.apache.maven.model.building.ModelProblemCollector;
+import org.apache.maven.model.building.ModelProblem.Severity;
+import org.apache.maven.model.building.ModelProblem.Version;
+import org.apache.maven.model.building.ModelProblemCollectorRequest;
+import org.apache.maven.model.profile.activation.ProfileActivator;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+
+/**
+ * Calculates the active profiles among a given collection of profiles.
+ *
+ * @author Benjamin Bentmann
+ */
+@Component( role = ProfileSelector.class )
+public class DefaultProfileSelector
+ implements ProfileSelector
+{
+
+ @Requirement( role = ProfileActivator.class )
+ private List<ProfileActivator> activators = new ArrayList<ProfileActivator>();
+
+ public DefaultProfileSelector addProfileActivator( ProfileActivator profileActivator )
+ {
+ if ( profileActivator != null )
+ {
+ activators.add( profileActivator );
+ }
+ return this;
+ }
+
+ @Override
+ public List<Profile> getActiveProfiles( Collection<Profile> profiles, ProfileActivationContext context,
+ ModelProblemCollector problems )
+ {
+ Collection<String> activatedIds = new HashSet<String>( context.getActiveProfileIds() );
+ Collection<String> deactivatedIds = new HashSet<String>( context.getInactiveProfileIds() );
+
+ List<Profile> activeProfiles = new ArrayList<Profile>( profiles.size() );
+ List<Profile> activePomProfilesByDefault = new ArrayList<Profile>();
+ boolean activatedPomProfileNotByDefault = false;
+
+ for ( Profile profile : profiles )
+ {
+ if ( !deactivatedIds.contains( profile.getId() ) )
+ {
+ if ( activatedIds.contains( profile.getId() ) || isActive( profile, context, problems ) )
+ {
+ activeProfiles.add( profile );
+
+ if ( Profile.SOURCE_POM.equals( profile.getSource() ) )
+ {
+ activatedPomProfileNotByDefault = true;
+ }
+ }
+ else if ( isActiveByDefault( profile ) )
+ {
+ if ( Profile.SOURCE_POM.equals( profile.getSource() ) )
+ {
+ activePomProfilesByDefault.add( profile );
+ }
+ else
+ {
+ activeProfiles.add( profile );
+ }
+ }
+
+ }
+ }
+
+ if ( !activatedPomProfileNotByDefault )
+ {
+ activeProfiles.addAll( activePomProfilesByDefault );
+ }
+
+ return activeProfiles;
+ }
+
+ private boolean isActive( Profile profile, ProfileActivationContext context, ModelProblemCollector problems )
+ {
+ boolean isActive = false;
+ for ( ProfileActivator activator : activators )
+ {
+ if ( activator.presentInConfig( profile, context, problems ) )
+ {
+ isActive = true;
+ }
+ }
+ for ( ProfileActivator activator : activators )
+ {
+ try
+ {
+ if ( activator.presentInConfig( profile, context, problems ) )
+ {
+ isActive &= activator.isActive( profile, context, problems );
+ }
+ }
+ catch ( RuntimeException e )
+ {
+ problems.add( new ModelProblemCollectorRequest( Severity.ERROR, Version.BASE )
+ .setMessage( "Failed to determine activation for profile " + profile.getId() )
+ .setLocation( profile.getLocation( "" ) )
+ .setException( e ) );
+ return false;
+ }
+ }
+ return isActive;
+ }
+
+ private boolean isActiveByDefault( Profile profile )
+ {
+ Activation activation = profile.getActivation();
+ return activation != null && activation.isActiveByDefault();
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/profile/ProfileActivationContext.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/profile/ProfileActivationContext.java
new file mode 100644
index 00000000..d501e660
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/profile/ProfileActivationContext.java
@@ -0,0 +1,79 @@
+package org.apache.maven.model.profile;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Describes the environmental context used to determine the activation status of profiles.
+ *
+ * @author Benjamin Bentmann
+ */
+public interface ProfileActivationContext
+{
+
+ /**
+ * Gets the identifiers of those profiles that should be activated by explicit demand.
+ *
+ * @return The identifiers of those profiles to activate, never {@code null}.
+ */
+ List<String> getActiveProfileIds();
+
+ /**
+ * Gets the identifiers of those profiles that should be deactivated by explicit demand.
+ *
+ * @return The identifiers of those profiles to deactivate, never {@code null}.
+ */
+ List<String> getInactiveProfileIds();
+
+ /**
+ * Gets the system properties to use for interpolation and profile activation. The system properties are collected
+ * from the runtime environment like {@link System#getProperties()} and environment variables.
+ *
+ * @return The execution properties, never {@code null}.
+ */
+ Map<String, String> getSystemProperties();
+
+ /**
+ * Gets the user properties to use for interpolation and profile activation. The user properties have been
+ * configured directly by the user on his discretion, e.g. via the {@code -Dkey=value} parameter on the command
+ * line.
+ *
+ * @return The user properties, never {@code null}.
+ */
+ Map<String, String> getUserProperties();
+
+ /**
+ * Gets the base directory of the current project (if any).
+ *
+ * @return The base directory of the current project or {@code null} if none.
+ */
+ File getProjectDirectory();
+
+ /**
+ * Gets current calculated project properties
+ *
+ * @return The project properties, never {@code null}.
+ */
+ Map<String, String> getProjectProperties();
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/profile/ProfileInjector.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/profile/ProfileInjector.java
new file mode 100644
index 00000000..fbd7ddf0
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/profile/ProfileInjector.java
@@ -0,0 +1,46 @@
+package org.apache.maven.model.profile;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.model.Model;
+import org.apache.maven.model.Profile;
+import org.apache.maven.model.building.ModelBuildingRequest;
+import org.apache.maven.model.building.ModelProblemCollector;
+
+/**
+ * Handles profile injection into the model.
+ *
+ * @author Benjamin Bentmann
+ */
+public interface ProfileInjector
+{
+
+ /**
+ * Merges values from the specified profile into the given model. Implementations are expected to keep the profile
+ * and model completely decoupled by injecting deep copies rather than the original objects from the profile.
+ *
+ * @param model The model into which to merge the values defined by the profile, must not be <code>null</code>.
+ * @param profile The (read-only) profile whose values should be injected, may be <code>null</code>.
+ * @param request The model building request that holds further settings, must not be {@code null}.
+ * @param problems The container used to collect problems that were encountered, must not be {@code null}.
+ */
+ void injectProfile( Model model, Profile profile, ModelBuildingRequest request, ModelProblemCollector problems );
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/profile/ProfileSelector.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/profile/ProfileSelector.java
new file mode 100644
index 00000000..53ea8d9c
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/profile/ProfileSelector.java
@@ -0,0 +1,49 @@
+package org.apache.maven.model.profile;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Collection;
+import java.util.List;
+
+import org.apache.maven.model.Profile;
+import org.apache.maven.model.building.ModelProblemCollector;
+
+/**
+ * Calculates the active profiles among a given collection of profiles.
+ *
+ * @author Benjamin Bentmann
+ */
+public interface ProfileSelector
+{
+
+ /**
+ * Determines the profiles which are active in the specified activation context. Active profiles will eventually be
+ * injected into the model.
+ *
+ * @param profiles The profiles whose activation status should be determined, must not be {@code null}.
+ * @param context The environmental context used to determine the activation status of a profile, must not be
+ * {@code null}.
+ * @param problems The container used to collect problems that were encountered, must not be {@code null}.
+ * @return The profiles that have been activated, never {@code null}.
+ */
+ List<Profile> getActiveProfiles( Collection<Profile> profiles, ProfileActivationContext context,
+ ModelProblemCollector problems );
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/profile/activation/FileProfileActivator.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/profile/activation/FileProfileActivator.java
new file mode 100644
index 00000000..c0dcce23
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/profile/activation/FileProfileActivator.java
@@ -0,0 +1,192 @@
+package org.apache.maven.model.profile.activation;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+
+import org.apache.maven.model.Activation;
+import org.apache.maven.model.ActivationFile;
+import org.apache.maven.model.Profile;
+import org.apache.maven.model.building.ModelProblemCollector;
+import org.apache.maven.model.building.ModelProblem.Severity;
+import org.apache.maven.model.building.ModelProblem.Version;
+import org.apache.maven.model.building.ModelProblemCollectorRequest;
+import org.apache.maven.model.path.PathTranslator;
+import org.apache.maven.model.profile.ProfileActivationContext;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+import org.codehaus.plexus.interpolation.AbstractValueSource;
+import org.codehaus.plexus.interpolation.MapBasedValueSource;
+import org.codehaus.plexus.interpolation.RegexBasedInterpolator;
+import org.codehaus.plexus.util.StringUtils;
+
+/**
+ * Determines profile activation based on the existence/absence of some file.
+ * File name interpolation support is limited to <code>${basedir}</code> (since Maven 3,
+ * see <a href="http://jira.codehaus.org/browse/MNG-2363">MNG-2363</a>),
+ * System properties and request properties.
+ * <code>${project.basedir}</code> is intentionally not supported as this form would suggest that other
+ * <code>${project.*}</code> expressions can be used, which is however beyond the design.
+ *
+ * @author Benjamin Bentmann
+ * @see ActivationFile
+ * @see org.apache.maven.model.validation.DefaultModelValidator#validateRawModel
+ */
+@Component( role = ProfileActivator.class, hint = "file" )
+public class FileProfileActivator
+ implements ProfileActivator
+{
+
+ @Requirement
+ private PathTranslator pathTranslator;
+
+ public FileProfileActivator setPathTranslator( PathTranslator pathTranslator )
+ {
+ this.pathTranslator = pathTranslator;
+ return this;
+ }
+
+ @Override
+ public boolean isActive( Profile profile, ProfileActivationContext context, ModelProblemCollector problems )
+ {
+ Activation activation = profile.getActivation();
+
+ if ( activation == null )
+ {
+ return false;
+ }
+
+ ActivationFile file = activation.getFile();
+
+ if ( file == null )
+ {
+ return false;
+ }
+
+ String path;
+ boolean missing;
+
+ if ( StringUtils.isNotEmpty( file.getExists() ) )
+ {
+ path = file.getExists();
+ missing = false;
+ }
+ else if ( StringUtils.isNotEmpty( file.getMissing() ) )
+ {
+ path = file.getMissing();
+ missing = true;
+ }
+ else
+ {
+ return false;
+ }
+
+ RegexBasedInterpolator interpolator = new RegexBasedInterpolator();
+
+ final File basedir = context.getProjectDirectory();
+
+ if ( basedir != null )
+ {
+ interpolator.addValueSource( new AbstractValueSource( false )
+ {
+ @Override
+ public Object getValue( String expression )
+ {
+ /*
+ * NOTE: We intentionally only support ${basedir} and not ${project.basedir} as the latter form
+ * would suggest that other project.* expressions can be used which is however beyond the design.
+ */
+ if ( "basedir".equals( expression ) )
+ {
+ return basedir.getAbsolutePath();
+ }
+ return null;
+ }
+ } );
+ }
+ else if ( path.contains( "${basedir}" ) )
+ {
+ return false;
+ }
+
+ interpolator.addValueSource( new MapBasedValueSource( context.getProjectProperties() ) );
+
+ interpolator.addValueSource( new MapBasedValueSource( context.getUserProperties() ) );
+
+ interpolator.addValueSource( new MapBasedValueSource( context.getSystemProperties() ) );
+
+ try
+ {
+ path = interpolator.interpolate( path, "" );
+ }
+ catch ( Exception e )
+ {
+ problems.add( new ModelProblemCollectorRequest( Severity.ERROR, Version.BASE )
+ .setMessage( "Failed to interpolate file location " + path + " for profile " + profile.getId()
+ + ": " + e.getMessage() )
+ .setLocation( file.getLocation( missing ? "missing" : "exists" ) )
+ .setException( e ) );
+ return false;
+ }
+
+ path = pathTranslator.alignToBaseDirectory( path, basedir );
+
+ // replace activation value with interpolated value
+ if ( missing )
+ {
+ file.setMissing( path );
+ }
+ else
+ {
+ file.setExists( path );
+ }
+
+ File f = new File( path );
+
+ if ( !f.isAbsolute() )
+ {
+ return false;
+ }
+
+ boolean fileExists = f.exists();
+
+ return missing ? !fileExists : fileExists;
+ }
+
+ @Override
+ public boolean presentInConfig( Profile profile, ProfileActivationContext context, ModelProblemCollector problems )
+ {
+ Activation activation = profile.getActivation();
+
+ if ( activation == null )
+ {
+ return false;
+ }
+
+ ActivationFile file = activation.getFile();
+
+ if ( file == null )
+ {
+ return false;
+ }
+ return true;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/profile/activation/JdkVersionProfileActivator.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/profile/activation/JdkVersionProfileActivator.java
new file mode 100644
index 00000000..e981bfd3
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/profile/activation/JdkVersionProfileActivator.java
@@ -0,0 +1,224 @@
+package org.apache.maven.model.profile.activation;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.maven.model.Activation;
+import org.apache.maven.model.Profile;
+import org.apache.maven.model.building.ModelProblemCollector;
+import org.apache.maven.model.building.ModelProblem.Severity;
+import org.apache.maven.model.building.ModelProblem.Version;
+import org.apache.maven.model.building.ModelProblemCollectorRequest;
+import org.apache.maven.model.profile.ProfileActivationContext;
+import org.codehaus.plexus.component.annotations.Component;
+
+/**
+ * Determines profile activation based on the version of the current Java runtime.
+ *
+ * @author Benjamin Bentmann
+ * @see Activation#getJdk()
+ */
+@Component( role = ProfileActivator.class, hint = "jdk-version" )
+public class JdkVersionProfileActivator
+ implements ProfileActivator
+{
+
+ @Override
+ public boolean isActive( Profile profile, ProfileActivationContext context, ModelProblemCollector problems )
+ {
+ Activation activation = profile.getActivation();
+
+ if ( activation == null )
+ {
+ return false;
+ }
+
+ String jdk = activation.getJdk();
+
+ if ( jdk == null )
+ {
+ return false;
+ }
+
+ String version = context.getSystemProperties().get( "java.version" );
+
+ if ( version == null || version.length() <= 0 )
+ {
+ problems.add( new ModelProblemCollectorRequest( Severity.ERROR, Version.BASE )
+ .setMessage( "Failed to determine Java version for profile " + profile.getId() )
+ .setLocation( activation.getLocation( "jdk" ) ) );
+ return false;
+ }
+
+ if ( jdk.startsWith( "!" ) )
+ {
+ return !version.startsWith( jdk.substring( 1 ) );
+ }
+ else if ( isRange( jdk ) )
+ {
+ return isInRange( version, getRange( jdk ) );
+ }
+ else
+ {
+ return version.startsWith( jdk );
+ }
+ }
+
+ @Override
+ public boolean presentInConfig( Profile profile, ProfileActivationContext context, ModelProblemCollector problems )
+ {
+ Activation activation = profile.getActivation();
+
+ if ( activation == null )
+ {
+ return false;
+ }
+
+ String jdk = activation.getJdk();
+
+ if ( jdk == null )
+ {
+ return false;
+ }
+ return true;
+ }
+
+ private static boolean isInRange( String value, List<RangeValue> range )
+ {
+ int leftRelation = getRelationOrder( value, range.get( 0 ), true );
+
+ if ( leftRelation == 0 )
+ {
+ return true;
+ }
+
+ if ( leftRelation < 0 )
+ {
+ return false;
+ }
+
+ return getRelationOrder( value, range.get( 1 ), false ) <= 0;
+ }
+
+ private static int getRelationOrder( String value, RangeValue rangeValue, boolean isLeft )
+ {
+ if ( rangeValue.value.length() <= 0 )
+ {
+ return isLeft ? 1 : -1;
+ }
+
+ value = value.replaceAll( "[^0-9\\.\\-\\_]", "" );
+
+ List<String> valueTokens = new ArrayList<String>( Arrays.asList( value.split( "[\\.\\-\\_]" ) ) );
+ List<String> rangeValueTokens = new ArrayList<String>( Arrays.asList( rangeValue.value.split( "\\." ) ) );
+
+ addZeroTokens( valueTokens, 3 );
+ addZeroTokens( rangeValueTokens, 3 );
+
+ for ( int i = 0; i < 3; i++ )
+ {
+ int x = Integer.parseInt( valueTokens.get( i ) );
+ int y = Integer.parseInt( rangeValueTokens.get( i ) );
+ if ( x < y )
+ {
+ return -1;
+ }
+ else if ( x > y )
+ {
+ return 1;
+ }
+ }
+ if ( !rangeValue.closed )
+ {
+ return isLeft ? -1 : 1;
+ }
+ return 0;
+ }
+
+ private static void addZeroTokens( List<String> tokens, int max )
+ {
+ while ( tokens.size() < max )
+ {
+ tokens.add( "0" );
+ }
+ }
+
+ private static boolean isRange( String value )
+ {
+ return value.startsWith( "[" ) || value.startsWith( "(" );
+ }
+
+ private static List<RangeValue> getRange( String range )
+ {
+ List<RangeValue> ranges = new ArrayList<RangeValue>();
+
+ for ( String token : range.split( "," ) )
+ {
+ if ( token.startsWith( "[" ) )
+ {
+ ranges.add( new RangeValue( token.replace( "[", "" ), true ) );
+ }
+ else if ( token.startsWith( "(" ) )
+ {
+ ranges.add( new RangeValue( token.replace( "(", "" ), false ) );
+ }
+ else if ( token.endsWith( "]" ) )
+ {
+ ranges.add( new RangeValue( token.replace( "]", "" ), true ) );
+ }
+ else if ( token.endsWith( ")" ) )
+ {
+ ranges.add( new RangeValue( token.replace( ")", "" ), false ) );
+ }
+ else if ( token.length() <= 0 )
+ {
+ ranges.add( new RangeValue( "", false ) );
+ }
+ }
+ if ( ranges.size() < 2 )
+ {
+ ranges.add( new RangeValue( "99999999", false ) );
+ }
+ return ranges;
+ }
+
+ private static class RangeValue
+ {
+ private String value;
+
+ private boolean closed;
+
+ RangeValue( String value, boolean closed )
+ {
+ this.value = value.trim();
+ this.closed = closed;
+ }
+
+ @Override
+ public String toString()
+ {
+ return value;
+ }
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/profile/activation/OperatingSystemProfileActivator.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/profile/activation/OperatingSystemProfileActivator.java
new file mode 100644
index 00000000..30abb1fa
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/profile/activation/OperatingSystemProfileActivator.java
@@ -0,0 +1,168 @@
+package org.apache.maven.model.profile.activation;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.model.Activation;
+import org.apache.maven.model.ActivationOS;
+import org.apache.maven.model.Profile;
+import org.apache.maven.model.building.ModelProblemCollector;
+import org.apache.maven.model.profile.ProfileActivationContext;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.util.Os;
+
+/**
+ * Determines profile activation based on the operating system of the current runtime platform.
+ *
+ * @author Benjamin Bentmann
+ * @see ActivationOS
+ */
+@Component( role = ProfileActivator.class, hint = "os" )
+public class OperatingSystemProfileActivator
+ implements ProfileActivator
+{
+
+ @Override
+ public boolean isActive( Profile profile, ProfileActivationContext context, ModelProblemCollector problems )
+ {
+ Activation activation = profile.getActivation();
+
+ if ( activation == null )
+ {
+ return false;
+ }
+
+ ActivationOS os = activation.getOs();
+
+ if ( os == null )
+ {
+ return false;
+ }
+
+ boolean active = ensureAtLeastOneNonNull( os );
+
+ if ( active && os.getFamily() != null )
+ {
+ active = determineFamilyMatch( os.getFamily() );
+ }
+ if ( active && os.getName() != null )
+ {
+ active = determineNameMatch( os.getName() );
+ }
+ if ( active && os.getArch() != null )
+ {
+ active = determineArchMatch( os.getArch() );
+ }
+ if ( active && os.getVersion() != null )
+ {
+ active = determineVersionMatch( os.getVersion() );
+ }
+
+ return active;
+ }
+
+ @Override
+ public boolean presentInConfig( Profile profile, ProfileActivationContext context, ModelProblemCollector problems )
+ {
+ Activation activation = profile.getActivation();
+
+ if ( activation == null )
+ {
+ return false;
+ }
+
+ ActivationOS os = activation.getOs();
+
+ if ( os == null )
+ {
+ return false;
+ }
+ return true;
+ }
+
+ private boolean ensureAtLeastOneNonNull( ActivationOS os )
+ {
+ return os.getArch() != null || os.getFamily() != null || os.getName() != null || os.getVersion() != null;
+ }
+
+ private boolean determineVersionMatch( String version )
+ {
+ String test = version;
+ boolean reverse = false;
+
+ if ( test.startsWith( "!" ) )
+ {
+ reverse = true;
+ test = test.substring( 1 );
+ }
+
+ boolean result = Os.isVersion( test );
+
+ return reverse ? !result : result;
+ }
+
+ private boolean determineArchMatch( String arch )
+ {
+ String test = arch;
+ boolean reverse = false;
+
+ if ( test.startsWith( "!" ) )
+ {
+ reverse = true;
+ test = test.substring( 1 );
+ }
+
+ boolean result = Os.isArch( test );
+
+ return reverse ? !result : result;
+ }
+
+ private boolean determineNameMatch( String name )
+ {
+ String test = name;
+ boolean reverse = false;
+
+ if ( test.startsWith( "!" ) )
+ {
+ reverse = true;
+ test = test.substring( 1 );
+ }
+
+ boolean result = Os.isName( test );
+
+ return reverse ? !result : result;
+ }
+
+ private boolean determineFamilyMatch( String family )
+ {
+ String test = family;
+ boolean reverse = false;
+
+ if ( test.startsWith( "!" ) )
+ {
+ reverse = true;
+ test = test.substring( 1 );
+ }
+
+ boolean result = Os.isFamily( test );
+
+ return reverse ? !result : result;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/profile/activation/ProfileActivator.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/profile/activation/ProfileActivator.java
new file mode 100644
index 00000000..0547e742
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/profile/activation/ProfileActivator.java
@@ -0,0 +1,59 @@
+package org.apache.maven.model.profile.activation;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.model.Profile;
+import org.apache.maven.model.building.ModelProblemCollector;
+import org.apache.maven.model.profile.ProfileActivationContext;
+
+/**
+ * Determines whether a profile should be activated.
+ *
+ * @author Benjamin Bentmann
+ */
+public interface ProfileActivator
+{
+
+ /**
+ * Determines whether the specified profile is active in the given activator context.
+ *
+ * @param profile The profile whose activation status should be determined, must not be {@code null}.
+ * @param context The environmental context used to determine the activation status of the profile, must not be
+ * {@code null}.
+ * @param problems The container used to collect problems (e.g. bad syntax) that were encountered, must not be
+ * {@code null}.
+ * @return {@code true} if the profile is active, {@code false} otherwise.
+ */
+ boolean isActive( Profile profile, ProfileActivationContext context, ModelProblemCollector problems );
+
+ /**
+ * Determines whether specified activation method is present in configuration or not. It should help to have AND
+ * between activation conditions
+ * Need for solving http://jira.codehaus.org/browse/MNG-4565
+ * @param profile The profile whose activation status should be determined, must not be {@code null}.
+ * @param context The environmental context used to determine the activation status of the profile, must not be
+ * {@code null}.
+ * @param problems The container used to collect problems (e.g. bad syntax) that were encountered, must not be
+ * {@code null}.
+ * @return {@code true} if the profile is active, {@code false} otherwise.
+ */
+ boolean presentInConfig( Profile profile, ProfileActivationContext context, ModelProblemCollector problems );
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/profile/activation/PropertyProfileActivator.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/profile/activation/PropertyProfileActivator.java
new file mode 100644
index 00000000..ba7886f0
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/profile/activation/PropertyProfileActivator.java
@@ -0,0 +1,126 @@
+package org.apache.maven.model.profile.activation;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.model.Activation;
+import org.apache.maven.model.ActivationProperty;
+import org.apache.maven.model.Profile;
+import org.apache.maven.model.building.ModelProblemCollector;
+import org.apache.maven.model.building.ModelProblem.Severity;
+import org.apache.maven.model.building.ModelProblem.Version;
+import org.apache.maven.model.building.ModelProblemCollectorRequest;
+import org.apache.maven.model.profile.ProfileActivationContext;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.util.StringUtils;
+
+/**
+ * Determines profile activation based on the existence or value of some execution property.
+ *
+ * @author Benjamin Bentmann
+ * @see ActivationProperty
+ */
+@Component( role = ProfileActivator.class, hint = "property" )
+public class PropertyProfileActivator
+ implements ProfileActivator
+{
+
+ @Override
+ public boolean isActive( Profile profile, ProfileActivationContext context, ModelProblemCollector problems )
+ {
+ Activation activation = profile.getActivation();
+
+ if ( activation == null )
+ {
+ return false;
+ }
+
+ ActivationProperty property = activation.getProperty();
+
+ if ( property == null )
+ {
+ return false;
+ }
+
+ String name = property.getName();
+ boolean reverseName = false;
+
+ if ( name != null && name.startsWith( "!" ) )
+ {
+ reverseName = true;
+ name = name.substring( 1 );
+ }
+
+ if ( name == null || name.length() <= 0 )
+ {
+ problems.add( new ModelProblemCollectorRequest( Severity.ERROR, Version.BASE )
+ .setMessage( "The property name is required to activate the profile " + profile.getId() )
+ .setLocation( property.getLocation( "" ) ) );
+ return false;
+ }
+
+ String sysValue = context.getUserProperties().get( name );
+ if ( sysValue == null )
+ {
+ sysValue = context.getSystemProperties().get( name );
+ }
+
+ String propValue = property.getValue();
+ if ( StringUtils.isNotEmpty( propValue ) )
+ {
+ boolean reverseValue = false;
+ if ( propValue.startsWith( "!" ) )
+ {
+ reverseValue = true;
+ propValue = propValue.substring( 1 );
+ }
+
+ // we have a value, so it has to match the system value...
+ boolean result = propValue.equals( sysValue );
+
+ return reverseValue ? !result : result;
+ }
+ else
+ {
+ boolean result = StringUtils.isNotEmpty( sysValue );
+
+ return reverseName ? !result : result;
+ }
+ }
+
+ @Override
+ public boolean presentInConfig( Profile profile, ProfileActivationContext context, ModelProblemCollector problems )
+ {
+ Activation activation = profile.getActivation();
+
+ if ( activation == null )
+ {
+ return false;
+ }
+
+ ActivationProperty property = activation.getProperty();
+
+ if ( property == null )
+ {
+ return false;
+ }
+ return true;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/resolution/InvalidRepositoryException.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/resolution/InvalidRepositoryException.java
new file mode 100644
index 00000000..303aff08
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/resolution/InvalidRepositoryException.java
@@ -0,0 +1,73 @@
+package org.apache.maven.model.resolution;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.model.Repository;
+
+/**
+ * Signals an error when adding a repository to the model resolver.
+ *
+ * @author Benjamin Bentmann
+ */
+public class InvalidRepositoryException
+ extends Exception
+{
+
+ /**
+ * The repository that raised this error, can be {@code null}.
+ */
+ private Repository repository;
+
+ /**
+ * Creates a new exception with specified detail message and cause for the given repository.
+ *
+ * @param message The detail message, may be {@code null}.
+ * @param repository The repository that caused the error, may be {@code null}.
+ * @param cause The cause, may be {@code null}.
+ */
+ public InvalidRepositoryException( String message, Repository repository, Throwable cause )
+ {
+ super( message, cause );
+ this.repository = repository;
+ }
+
+ /**
+ * Creates a new exception with specified detail message for the given repository.
+ *
+ * @param message The detail message, may be {@code null}.
+ * @param repository The repository that caused the error, may be {@code null}.
+ */
+ public InvalidRepositoryException( String message, Repository repository )
+ {
+ super( message );
+ this.repository = repository;
+ }
+
+ /**
+ * Gets the repository that causes this error (if any).
+ *
+ * @return The repository that causes this error or {@code null} if not known.
+ */
+ public Repository getRepository()
+ {
+ return repository;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/resolution/ModelResolver.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/resolution/ModelResolver.java
new file mode 100644
index 00000000..c81a5369
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/resolution/ModelResolver.java
@@ -0,0 +1,93 @@
+package org.apache.maven.model.resolution;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.model.Parent;
+import org.apache.maven.model.Repository;
+import org.apache.maven.model.building.ModelSource;
+
+/**
+ * Resolves a POM from its coordinates. During the build process, the
+ * {@link org.apache.maven.model.building.ModelBuilder} will add any relevant repositories to the model resolver. In
+ * other words, the model resolver is stateful and should not be reused across multiple model building requests.
+ *
+ * @author Benjamin Bentmann
+ */
+public interface ModelResolver
+{
+
+ /**
+ * Tries to resolve the POM for the specified coordinates.
+ *
+ * @param groupId The group identifier of the POM, must not be {@code null}.
+ * @param artifactId The artifact identifier of the POM, must not be {@code null}.
+ * @param version The version of the POM, must not be {@code null}.
+ * @return The source of the requested POM, never {@code null}.
+ * @throws UnresolvableModelException If the POM could not be resolved from any configured repository.
+ */
+ ModelSource resolveModel( String groupId, String artifactId, String version )
+ throws UnresolvableModelException;
+
+ /**
+ * Tries to resolve the POM for the specified parent coordinates possibly updating {@code parent}.
+ *
+ * @param parent The parent coordinates to resolve, must not be {@code null}.
+ * @return The source of the requested POM, never {@code null}.
+ * @throws UnresolvableModelException If the POM could not be resolved from any configured repository.
+ * @since 3.2.2
+ */
+ ModelSource resolveModel( Parent parent )
+ throws UnresolvableModelException;
+
+ /**
+ * Adds a repository to use for subsequent resolution requests. The order in which repositories are added matters,
+ * repositories that were added first should also be searched first. When multiple repositories with the same
+ * identifier are added, only the first repository being added will be used.
+ *
+ * @param repository The repository to add to the internal search chain, must not be {@code null}.
+ * @throws InvalidRepositoryException If the repository could not be added (e.g. due to invalid URL or layout).
+ */
+ void addRepository( Repository repository )
+ throws InvalidRepositoryException;
+
+ /**
+ * Adds a repository to use for subsequent resolution requests. The order in which repositories are added matters,
+ * repositories that were added first should also be searched first. When multiple repositories with the same
+ * identifier are added, then the value of the replace argument is determines the behaviour.
+ *
+ * If replace is false than any existing repository with the same Id will remain in use. If replace
+ * is true the new repository replaces the original.
+ *
+ * @param repository The repository to add to the internal search chain, must not be {@code null}.
+ * @throws InvalidRepositoryException If the repository could not be added (e.g. due to invalid URL or layout).
+ */
+ void addRepository( Repository repository, boolean replace )
+ throws InvalidRepositoryException;
+
+ /**
+ * Clones this resolver for usage in a forked resolution process. In general, implementors need not provide a deep
+ * clone. The only requirement is that invocations of {@link #addRepository(Repository)} on the clone do not affect
+ * the state of the original resolver and vice versa.
+ *
+ * @return The cloned resolver, never {@code null}.
+ */
+ ModelResolver newCopy();
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/resolution/UnresolvableModelException.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/resolution/UnresolvableModelException.java
new file mode 100644
index 00000000..bdb623ac
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/resolution/UnresolvableModelException.java
@@ -0,0 +1,126 @@
+package org.apache.maven.model.resolution;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Signals an error when resolving the path to an external model.
+ *
+ * @author Benjamin Bentmann
+ */
+public class UnresolvableModelException
+ extends Exception
+{
+
+ /**
+ * The group id of the unresolvable model.
+ */
+ private final String groupId;
+
+ /**
+ * The artifact id of the unresolvable model.
+ */
+ private final String artifactId;
+
+ /**
+ * The version of the unresolvable model.
+ */
+ private final String version;
+
+ /**
+ * Creates a new exception with specified detail message and cause.
+ *
+ * @param message The detail message, may be {@code null}.
+ * @param groupId The group id of the unresolvable model, may be {@code null}.
+ * @param artifactId The artifact id of the unresolvable model, may be {@code null}.
+ * @param version The version of the unresolvable model, may be {@code null}.
+ * @param cause The cause, may be {@code null}.
+ */
+ public UnresolvableModelException( String message, String groupId, String artifactId, String version,
+ Throwable cause )
+ {
+ super( message, cause );
+ this.groupId = ( groupId != null ) ? groupId : "";
+ this.artifactId = ( artifactId != null ) ? artifactId : "";
+ this.version = ( version != null ) ? version : "";
+ }
+
+ /**
+ * Creates a new exception with specified detail message.
+ *
+ * @param message The detail message, may be {@code null}.
+ * @param groupId The group id of the unresolvable model, may be {@code null}.
+ * @param artifactId The artifact id of the unresolvable model, may be {@code null}.
+ * @param version The version of the unresolvable model, may be {@code null}.
+ */
+ public UnresolvableModelException( String message, String groupId, String artifactId, String version )
+ {
+ super( message );
+ this.groupId = ( groupId != null ) ? groupId : "";
+ this.artifactId = ( artifactId != null ) ? artifactId : "";
+ this.version = ( version != null ) ? version : "";
+ }
+
+ /**
+ * Creates a new exception with specified cause
+ *
+ * @param cause
+ * @param groupId
+ * @param artifactId
+ * @param version
+ */
+ public UnresolvableModelException( Throwable cause, String groupId, String artifactId, String version )
+ {
+ super( cause );
+ this.groupId = groupId;
+ this.artifactId = artifactId;
+ this.version = version;
+ }
+
+ /**
+ * Gets the group id of the unresolvable model.
+ *
+ * @return The group id of the unresolvable model, can be empty but never {@code null}.
+ */
+ public String getGroupId()
+ {
+ return groupId;
+ }
+
+ /**
+ * Gets the artifact id of the unresolvable model.
+ *
+ * @return The artifact id of the unresolvable model, can be empty but never {@code null}.
+ */
+ public String getArtifactId()
+ {
+ return artifactId;
+ }
+
+ /**
+ * Gets the version of the unresolvable model.
+ *
+ * @return The version of the unresolvable model, can be empty but never {@code null}.
+ */
+ public String getVersion()
+ {
+ return version;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/resolution/WorkspaceModelResolver.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/resolution/WorkspaceModelResolver.java
new file mode 100644
index 00000000..d12edea7
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/resolution/WorkspaceModelResolver.java
@@ -0,0 +1,33 @@
+package org.apache.maven.model.resolution;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.model.Model;
+
+public interface WorkspaceModelResolver
+{
+
+ Model resolveRawModel( String groupId, String artifactId, String versionConstraint )
+ throws UnresolvableModelException;
+
+ Model resolveEffectiveModel( String groupId, String artifactId, String versionConstraint )
+ throws UnresolvableModelException;
+
+} \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/superpom/DefaultSuperPomProvider.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/superpom/DefaultSuperPomProvider.java
new file mode 100644
index 00000000..7d4f66a8
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/superpom/DefaultSuperPomProvider.java
@@ -0,0 +1,87 @@
+package org.apache.maven.model.superpom;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.maven.model.Model;
+import org.apache.maven.model.building.ModelProcessor;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+
+/**
+ * Provides the super POM that all models implicitly inherit from.
+ *
+ * @author Benjamin Bentmann
+ */
+@Component( role = SuperPomProvider.class )
+public class DefaultSuperPomProvider
+ implements SuperPomProvider
+{
+
+ /**
+ * The cached super POM, lazily created.
+ */
+ private Model superModel;
+
+ @Requirement
+ private ModelProcessor modelProcessor;
+
+ public DefaultSuperPomProvider setModelProcessor( ModelProcessor modelProcessor )
+ {
+ this.modelProcessor = modelProcessor;
+ return this;
+ }
+
+ @Override
+ public Model getSuperModel( String version )
+ {
+ if ( superModel == null )
+ {
+ String resource = "/org/apache/maven/model/pom-" + version + ".xml";
+
+ InputStream is = getClass().getResourceAsStream( resource );
+
+ if ( is == null )
+ {
+ throw new IllegalStateException( "The super POM " + resource + " was not found"
+ + ", please verify the integrity of your Maven installation" );
+ }
+
+ try
+ {
+ Map<String, String> options = new HashMap<String, String>();
+ options.put( "xml:4.0.0", "xml:4.0.0" );
+ superModel = modelProcessor.read( is, options );
+ }
+ catch ( IOException e )
+ {
+ throw new IllegalStateException( "The super POM " + resource + " is damaged"
+ + ", please verify the integrity of your Maven installation", e );
+ }
+ }
+
+ return superModel;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/superpom/SuperPomProvider.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/superpom/SuperPomProvider.java
new file mode 100644
index 00000000..3f44fb7e
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/superpom/SuperPomProvider.java
@@ -0,0 +1,42 @@
+package org.apache.maven.model.superpom;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.model.Model;
+
+/**
+ * Provides the super POM that all models implicitly inherit from.
+ *
+ * @author Benjamin Bentmann
+ */
+public interface SuperPomProvider
+{
+
+ /**
+ * Gets the super POM for the specified model version. The returned model is supposed to be read-only, i.e. if the
+ * caller intends to make updates to the model the return value must be cloned before updating to ensure the
+ * modifications don't affect future retrievals of the super POM.
+ *
+ * @param version The model version to retrieve the super POM for (e.g. "4.0.0"), must not be {@code null}.
+ * @return The super POM, never {@code null}.
+ */
+ Model getSuperModel( String version );
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/validation/DefaultModelValidator.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/validation/DefaultModelValidator.java
new file mode 100644
index 00000000..dd7bd4e2
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/validation/DefaultModelValidator.java
@@ -0,0 +1,1076 @@
+package org.apache.maven.model.validation;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.regex.Pattern;
+
+import org.apache.maven.model.Activation;
+import org.apache.maven.model.ActivationFile;
+import org.apache.maven.model.Build;
+import org.apache.maven.model.BuildBase;
+import org.apache.maven.model.Dependency;
+import org.apache.maven.model.DependencyManagement;
+import org.apache.maven.model.DistributionManagement;
+import org.apache.maven.model.Exclusion;
+import org.apache.maven.model.InputLocation;
+import org.apache.maven.model.InputLocationTracker;
+import org.apache.maven.model.Model;
+import org.apache.maven.model.Parent;
+import org.apache.maven.model.Plugin;
+import org.apache.maven.model.PluginExecution;
+import org.apache.maven.model.PluginManagement;
+import org.apache.maven.model.Profile;
+import org.apache.maven.model.ReportPlugin;
+import org.apache.maven.model.Reporting;
+import org.apache.maven.model.Repository;
+import org.apache.maven.model.Resource;
+import org.apache.maven.model.building.ModelBuildingRequest;
+import org.apache.maven.model.building.ModelProblem.Severity;
+import org.apache.maven.model.building.ModelProblem.Version;
+import org.apache.maven.model.building.ModelProblemCollector;
+import org.apache.maven.model.building.ModelProblemCollectorRequest;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.util.StringUtils;
+
+/**
+ * @author <a href="mailto:trygvis@inamo.no">Trygve Laugst&oslash;l</a>
+ */
+@Component( role = ModelValidator.class )
+public class DefaultModelValidator
+ implements ModelValidator
+{
+
+ private static final Pattern ID_REGEX = Pattern.compile( "[A-Za-z0-9_\\-.]+" );
+
+ private static final Pattern ID_WITH_WILDCARDS_REGEX = Pattern.compile( "[A-Za-z0-9_\\-.?*]+" );
+
+ private static final String ILLEGAL_FS_CHARS = "\\/:\"<>|?*";
+
+ private static final String ILLEGAL_VERSION_CHARS = ILLEGAL_FS_CHARS;
+
+ private static final String ILLEGAL_REPO_ID_CHARS = ILLEGAL_FS_CHARS;
+
+ @Override
+ public void validateRawModel( Model m, ModelBuildingRequest request, ModelProblemCollector problems )
+ {
+ Parent parent = m.getParent();
+ if ( parent != null )
+ {
+ validateStringNotEmpty( "parent.groupId", problems, Severity.FATAL, Version.BASE, parent.getGroupId(),
+ parent );
+
+ validateStringNotEmpty( "parent.artifactId", problems, Severity.FATAL, Version.BASE,
+ parent.getArtifactId(), parent );
+
+ validateStringNotEmpty( "parent.version", problems, Severity.FATAL, Version.BASE, parent.getVersion(),
+ parent );
+
+ if ( equals( parent.getGroupId(), m.getGroupId() )
+ && equals( parent.getArtifactId(), m.getArtifactId() ) )
+ {
+ addViolation( problems, Severity.FATAL, Version.BASE, "parent.artifactId", null, "must be changed"
+ + ", the parent element cannot have the same groupId:artifactId as the project.", parent );
+ }
+ }
+
+ if ( request.getValidationLevel() >= ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_2_0 )
+ {
+ Severity errOn30 = getSeverity( request, ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_3_0 );
+
+ validateEnum( "modelVersion", problems, Severity.ERROR, Version.V20, m.getModelVersion(), null, m,
+ "4.0.0" );
+
+ validateStringNoExpression( "groupId", problems, Severity.WARNING, Version.V20, m.getGroupId(), m );
+ if ( parent == null )
+ {
+ validateStringNotEmpty( "groupId", problems, Severity.FATAL, Version.V20, m.getGroupId(), m );
+ }
+
+ validateStringNoExpression( "artifactId", problems, Severity.WARNING, Version.V20, m.getArtifactId(), m );
+ validateStringNotEmpty( "artifactId", problems, Severity.FATAL, Version.V20, m.getArtifactId(), m );
+
+ validateVersionNoExpression( "version", problems, Severity.WARNING, Version.V20, m.getVersion(), m );
+ if ( parent == null )
+ {
+ validateStringNotEmpty( "version", problems, Severity.FATAL, Version.V20, m.getVersion(), m );
+ }
+
+ validate20RawDependencies( problems, m.getDependencies(), "dependencies.dependency", request );
+
+ if ( m.getDependencyManagement() != null )
+ {
+ validate20RawDependencies( problems, m.getDependencyManagement().getDependencies(),
+ "dependencyManagement.dependencies.dependency", request );
+ }
+
+ validateRawRepositories( problems, m.getRepositories(), "repositories.repository", request );
+
+ validateRawRepositories( problems, m.getPluginRepositories(), "pluginRepositories.pluginRepository",
+ request );
+
+ Build build = m.getBuild();
+ if ( build != null )
+ {
+ validate20RawPlugins( problems, build.getPlugins(), "build.plugins.plugin", request );
+
+ PluginManagement mngt = build.getPluginManagement();
+ if ( mngt != null )
+ {
+ validate20RawPlugins( problems, mngt.getPlugins(), "build.pluginManagement.plugins.plugin",
+ request );
+ }
+ }
+
+ Set<String> profileIds = new HashSet<String>();
+
+ for ( Profile profile : m.getProfiles() )
+ {
+ String prefix = "profiles.profile[" + profile.getId() + "]";
+
+ if ( !profileIds.add( profile.getId() ) )
+ {
+ addViolation( problems, errOn30, Version.V20, "profiles.profile.id", null,
+ "must be unique but found duplicate profile with id " + profile.getId(), profile );
+ }
+
+ validate30RawProfileActivation( problems, profile.getActivation(), profile.getId(), prefix
+ + ".activation", request );
+
+ validate20RawDependencies( problems, profile.getDependencies(), prefix + ".dependencies.dependency",
+ request );
+
+ if ( profile.getDependencyManagement() != null )
+ {
+ validate20RawDependencies( problems, profile.getDependencyManagement().getDependencies(), prefix
+ + ".dependencyManagement.dependencies.dependency", request );
+ }
+
+ validateRawRepositories( problems, profile.getRepositories(), prefix + ".repositories.repository",
+ request );
+
+ validateRawRepositories( problems, profile.getPluginRepositories(), prefix
+ + ".pluginRepositories.pluginRepository", request );
+
+ BuildBase buildBase = profile.getBuild();
+ if ( buildBase != null )
+ {
+ validate20RawPlugins( problems, buildBase.getPlugins(), prefix + ".plugins.plugin", request );
+
+ PluginManagement mngt = buildBase.getPluginManagement();
+ if ( mngt != null )
+ {
+ validate20RawPlugins( problems, mngt.getPlugins(), prefix + ".pluginManagement.plugins.plugin",
+ request );
+ }
+ }
+ }
+ }
+ }
+
+ private void validate30RawProfileActivation( ModelProblemCollector problems, Activation activation,
+ String sourceHint, String prefix, ModelBuildingRequest request )
+ {
+ if ( activation == null )
+ {
+ return;
+ }
+
+ ActivationFile file = activation.getFile();
+
+ if ( file != null )
+ {
+ String path;
+ boolean missing;
+
+ if ( StringUtils.isNotEmpty( file.getExists() ) )
+ {
+ path = file.getExists();
+ missing = false;
+ }
+ else if ( StringUtils.isNotEmpty( file.getMissing() ) )
+ {
+ path = file.getMissing();
+ missing = true;
+ }
+ else
+ {
+ return;
+ }
+
+ if ( path.contains( "${project.basedir}" ) )
+ {
+ addViolation( problems,
+ Severity.WARNING,
+ Version.V30,
+ prefix + ( missing ? ".file.missing" : ".file.exists" ),
+ null,
+ "Failed to interpolate file location " + path + " for profile " + sourceHint
+ + ": ${project.basedir} expression not supported during profile activation, "
+ + "use ${basedir} instead",
+ file.getLocation( missing ? "missing" : "exists" ) );
+ }
+ else if ( hasProjectExpression( path ) )
+ {
+ addViolation( problems,
+ Severity.WARNING,
+ Version.V30,
+ prefix + ( missing ? ".file.missing" : ".file.exists" ),
+ null,
+ "Failed to interpolate file location "
+ + path
+ + " for profile "
+ + sourceHint
+ + ": ${project.*} expressions are not supported during profile activation",
+ file.getLocation( missing ? "missing" : "exists" ) );
+ }
+ }
+ }
+
+ private void validate20RawPlugins( ModelProblemCollector problems, List<Plugin> plugins, String prefix,
+ ModelBuildingRequest request )
+ {
+ Severity errOn31 = getSeverity( request, ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_3_1 );
+
+ Map<String, Plugin> index = new HashMap<String, Plugin>();
+
+ for ( Plugin plugin : plugins )
+ {
+ String key = plugin.getKey();
+
+ Plugin existing = index.get( key );
+
+ if ( existing != null )
+ {
+ addViolation( problems, errOn31, Version.V20, prefix + ".(groupId:artifactId)", null,
+ "must be unique but found duplicate declaration of plugin " + key, plugin );
+ }
+ else
+ {
+ index.put( key, plugin );
+ }
+
+ Set<String> executionIds = new HashSet<String>();
+
+ for ( PluginExecution exec : plugin.getExecutions() )
+ {
+ if ( !executionIds.add( exec.getId() ) )
+ {
+ addViolation( problems, Severity.ERROR, Version.V20, prefix + "[" + plugin.getKey()
+ + "].executions.execution.id", null, "must be unique but found duplicate execution with id "
+ + exec.getId(), exec );
+ }
+ }
+ }
+ }
+
+ @Override
+ public void validateEffectiveModel( Model m, ModelBuildingRequest request, ModelProblemCollector problems )
+ {
+ validateStringNotEmpty( "modelVersion", problems, Severity.ERROR, Version.BASE, m.getModelVersion(), m );
+
+ validateId( "groupId", problems, m.getGroupId(), m );
+
+ validateId( "artifactId", problems, m.getArtifactId(), m );
+
+ validateStringNotEmpty( "packaging", problems, Severity.ERROR, Version.BASE, m.getPackaging(), m );
+
+ if ( !m.getModules().isEmpty() )
+ {
+ if ( !"pom".equals( m.getPackaging() ) )
+ {
+ addViolation( problems, Severity.ERROR, Version.BASE, "packaging", null,
+ "with value '" + m.getPackaging() + "' is invalid. Aggregator projects "
+ + "require 'pom' as packaging.", m );
+ }
+
+ for ( int i = 0, n = m.getModules().size(); i < n; i++ )
+ {
+ String module = m.getModules().get( i );
+ if ( StringUtils.isBlank( module ) )
+ {
+ addViolation( problems, Severity.ERROR, Version.BASE, "modules.module[" + i + "]", null,
+ "has been specified without a path to the project directory.",
+ m.getLocation( "modules" ) );
+ }
+ }
+ }
+
+ validateStringNotEmpty( "version", problems, Severity.ERROR, Version.BASE, m.getVersion(), m );
+
+ Severity errOn30 = getSeverity( request, ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_3_0 );
+
+ validateEffectiveDependencies( problems, m.getDependencies(), false, request );
+
+ DependencyManagement mgmt = m.getDependencyManagement();
+ if ( mgmt != null )
+ {
+ validateEffectiveDependencies( problems, mgmt.getDependencies(), true, request );
+ }
+
+ if ( request.getValidationLevel() >= ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_2_0 )
+ {
+ Set<String> modules = new HashSet<String>();
+ for ( int i = 0, n = m.getModules().size(); i < n; i++ )
+ {
+ String module = m.getModules().get( i );
+ if ( !modules.add( module ) )
+ {
+ addViolation( problems, Severity.ERROR, Version.V20, "modules.module[" + i + "]", null,
+ "specifies duplicate child module " + module, m.getLocation( "modules" ) );
+ }
+ }
+
+ Severity errOn31 = getSeverity( request, ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_3_1 );
+
+ validateBannedCharacters( "version", problems, errOn31, Version.V20, m.getVersion(), null, m,
+ ILLEGAL_VERSION_CHARS );
+ validate20ProperSnapshotVersion( "version", problems, errOn31, Version.V20, m.getVersion(), null, m );
+
+ Build build = m.getBuild();
+ if ( build != null )
+ {
+ for ( Plugin p : build.getPlugins() )
+ {
+ validateStringNotEmpty( "build.plugins.plugin.artifactId", problems, Severity.ERROR, Version.V20,
+ p.getArtifactId(), p );
+
+ validateStringNotEmpty( "build.plugins.plugin.groupId", problems, Severity.ERROR, Version.V20,
+ p.getGroupId(), p );
+
+ validate20PluginVersion( "build.plugins.plugin.version", problems, p.getVersion(), p.getKey(), p,
+ request );
+
+ validateBoolean( "build.plugins.plugin.inherited", problems, errOn30, Version.V20,
+ p.getInherited(), p.getKey(), p );
+
+ validateBoolean( "build.plugins.plugin.extensions", problems, errOn30, Version.V20,
+ p.getExtensions(), p.getKey(), p );
+
+ validate20EffectivePluginDependencies( problems, p, request );
+ }
+
+ validate20RawResources( problems, build.getResources(), "build.resources.resource", request );
+
+ validate20RawResources( problems, build.getTestResources(), "build.testResources.testResource",
+ request );
+ }
+
+ Reporting reporting = m.getReporting();
+ if ( reporting != null )
+ {
+ for ( ReportPlugin p : reporting.getPlugins() )
+ {
+ validateStringNotEmpty( "reporting.plugins.plugin.artifactId", problems, Severity.ERROR,
+ Version.V20, p.getArtifactId(), p );
+
+ validateStringNotEmpty( "reporting.plugins.plugin.groupId", problems, Severity.ERROR, Version.V20,
+ p.getGroupId(), p );
+ }
+ }
+
+ for ( Repository repository : m.getRepositories() )
+ {
+ validate20EffectiveRepository( problems, repository, "repositories.repository", request );
+ }
+
+ for ( Repository repository : m.getPluginRepositories() )
+ {
+ validate20EffectiveRepository( problems, repository, "pluginRepositories.pluginRepository", request );
+ }
+
+ DistributionManagement distMgmt = m.getDistributionManagement();
+ if ( distMgmt != null )
+ {
+ if ( distMgmt.getStatus() != null )
+ {
+ addViolation( problems, Severity.ERROR, Version.V20, "distributionManagement.status", null,
+ "must not be specified.", distMgmt );
+ }
+
+ validate20EffectiveRepository( problems, distMgmt.getRepository(), "distributionManagement.repository",
+ request );
+ validate20EffectiveRepository( problems, distMgmt.getSnapshotRepository(),
+ "distributionManagement.snapshotRepository", request );
+ }
+ }
+ }
+
+ private void validate20RawDependencies( ModelProblemCollector problems, List<Dependency> dependencies,
+ String prefix, ModelBuildingRequest request )
+ {
+ Severity errOn30 = getSeverity( request, ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_3_0 );
+ Severity errOn31 = getSeverity( request, ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_3_1 );
+
+ Map<String, Dependency> index = new HashMap<String, Dependency>();
+
+ for ( Dependency dependency : dependencies )
+ {
+ String key = dependency.getManagementKey();
+
+ if ( "import".equals( dependency.getScope() ) )
+ {
+ if ( !"pom".equals( dependency.getType() ) )
+ {
+ addViolation( problems, Severity.WARNING, Version.V20, prefix + ".type", key,
+ "must be 'pom' to import the managed dependencies.", dependency );
+ }
+ else if ( StringUtils.isNotEmpty( dependency.getClassifier() ) )
+ {
+ addViolation( problems, errOn30, Version.V20, prefix + ".classifier", key,
+ "must be empty, imported POM cannot have a classifier.", dependency );
+ }
+ }
+ else if ( "system".equals( dependency.getScope() ) )
+ {
+ String sysPath = dependency.getSystemPath();
+ if ( StringUtils.isNotEmpty( sysPath ) )
+ {
+ if ( !hasExpression( sysPath ) )
+ {
+ addViolation( problems, Severity.WARNING, Version.V20, prefix + ".systemPath", key,
+ "should use a variable instead of a hard-coded path " + sysPath, dependency );
+ }
+ else if ( sysPath.contains( "${basedir}" ) || sysPath.contains( "${project.basedir}" ) )
+ {
+ addViolation( problems, Severity.WARNING, Version.V20, prefix + ".systemPath", key,
+ "should not point at files within the project directory, " + sysPath
+ + " will be unresolvable by dependent projects", dependency );
+ }
+ }
+ }
+
+ Dependency existing = index.get( key );
+
+ if ( existing != null )
+ {
+ String msg;
+ if ( equals( existing.getVersion(), dependency.getVersion() ) )
+ {
+ msg =
+ "duplicate declaration of version "
+ + StringUtils.defaultString( dependency.getVersion(), "(?)" );
+ }
+ else
+ {
+ msg =
+ "version " + StringUtils.defaultString( existing.getVersion(), "(?)" ) + " vs "
+ + StringUtils.defaultString( dependency.getVersion(), "(?)" );
+ }
+
+ addViolation( problems, errOn31, Version.V20, prefix + ".(groupId:artifactId:type:classifier)", null,
+ "must be unique: " + key + " -> " + msg, dependency );
+ }
+ else
+ {
+ index.put( key, dependency );
+ }
+ }
+ }
+
+ private void validateEffectiveDependencies( ModelProblemCollector problems, List<Dependency> dependencies,
+ boolean management, ModelBuildingRequest request )
+ {
+ Severity errOn30 = getSeverity( request, ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_3_0 );
+
+ String prefix = management ? "dependencyManagement.dependencies.dependency." : "dependencies.dependency.";
+
+ for ( Dependency d : dependencies )
+ {
+ validateEffectiveDependency( problems, d, management, prefix, request );
+
+ if ( request.getValidationLevel() >= ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_2_0 )
+ {
+ validateBoolean( prefix + "optional", problems, errOn30, Version.V20, d.getOptional(),
+ d.getManagementKey(), d );
+
+ if ( !management )
+ {
+ validateVersion( prefix + "version", problems, errOn30, Version.V20, d.getVersion(),
+ d.getManagementKey(), d );
+
+ /*
+ * TODO: Extensions like Flex Mojos use custom scopes like "merged", "internal", "external", etc.
+ * In order to don't break backward-compat with those, only warn but don't error out.
+ */
+ validateEnum( prefix + "scope", problems, Severity.WARNING, Version.V20, d.getScope(),
+ d.getManagementKey(), d, "provided", "compile", "runtime", "test", "system" );
+ }
+ }
+ }
+ }
+
+ private void validate20EffectivePluginDependencies( ModelProblemCollector problems, Plugin plugin,
+ ModelBuildingRequest request )
+ {
+ List<Dependency> dependencies = plugin.getDependencies();
+
+ if ( !dependencies.isEmpty() )
+ {
+ String prefix = "build.plugins.plugin[" + plugin.getKey() + "].dependencies.dependency.";
+
+ Severity errOn30 = getSeverity( request, ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_3_0 );
+
+ for ( Dependency d : dependencies )
+ {
+ validateEffectiveDependency( problems, d, false, prefix, request );
+
+ validateVersion( prefix + "version", problems, errOn30, Version.BASE, d.getVersion(),
+ d.getManagementKey(), d );
+
+ validateEnum( prefix + "scope", problems, errOn30, Version.BASE, d.getScope(), d.getManagementKey(), d,
+ "compile", "runtime", "system" );
+ }
+ }
+ }
+
+ private void validateEffectiveDependency( ModelProblemCollector problems, Dependency d, boolean management,
+ String prefix, ModelBuildingRequest request )
+ {
+ validateId( prefix + "artifactId", problems, Severity.ERROR, Version.BASE, d.getArtifactId(),
+ d.getManagementKey(), d );
+
+ validateId( prefix + "groupId", problems, Severity.ERROR, Version.BASE, d.getGroupId(), d.getManagementKey(),
+ d );
+
+ if ( !management )
+ {
+ validateStringNotEmpty( prefix + "type", problems, Severity.ERROR, Version.BASE, d.getType(),
+ d.getManagementKey(), d );
+
+ validateDependencyVersion( problems, d, prefix );
+ }
+
+ if ( "system".equals( d.getScope() ) )
+ {
+ String systemPath = d.getSystemPath();
+
+ if ( StringUtils.isEmpty( systemPath ) )
+ {
+ addViolation( problems, Severity.ERROR, Version.BASE, prefix + "systemPath", d.getManagementKey(),
+ "is missing.", d );
+ }
+ else
+ {
+ File sysFile = new File( systemPath );
+ if ( !sysFile.isAbsolute() )
+ {
+ addViolation( problems, Severity.ERROR, Version.BASE, prefix + "systemPath", d.getManagementKey(),
+ "must specify an absolute path but is " + systemPath, d );
+ }
+ else if ( !sysFile.isFile() )
+ {
+ String msg = "refers to a non-existing file " + sysFile.getAbsolutePath();
+ systemPath = systemPath.replace( '/', File.separatorChar ).replace( '\\', File.separatorChar );
+ String jdkHome =
+ request.getSystemProperties().getProperty( "java.home", "" ) + File.separator + "..";
+ if ( systemPath.startsWith( jdkHome ) )
+ {
+ msg += ". Please verify that you run Maven using a JDK and not just a JRE.";
+ }
+ addViolation( problems, Severity.WARNING, Version.BASE, prefix + "systemPath",
+ d.getManagementKey(), msg, d );
+ }
+ }
+ }
+ else if ( StringUtils.isNotEmpty( d.getSystemPath() ) )
+ {
+ addViolation( problems, Severity.ERROR, Version.BASE, prefix + "systemPath", d.getManagementKey(),
+ "must be omitted." + " This field may only be specified for a dependency with system scope.",
+ d );
+ }
+
+ if ( request.getValidationLevel() >= ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_2_0 )
+ {
+ for ( Exclusion exclusion : d.getExclusions() )
+ {
+ if ( request.getValidationLevel() < ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_3_0 )
+ {
+ validateId( prefix + "exclusions.exclusion.groupId", problems, Severity.WARNING, Version.V20,
+ exclusion.getGroupId(), d.getManagementKey(), exclusion );
+
+ validateId( prefix + "exclusions.exclusion.artifactId", problems, Severity.WARNING, Version.V20,
+ exclusion.getArtifactId(), d.getManagementKey(), exclusion );
+ }
+ else
+ {
+ validateIdWithWildcards( prefix + "exclusions.exclusion.groupId", problems, Severity.WARNING,
+ Version.V30, exclusion.getGroupId(), d.getManagementKey(), exclusion );
+
+ validateIdWithWildcards( prefix + "exclusions.exclusion.artifactId", problems, Severity.WARNING,
+ Version.V30, exclusion.getArtifactId(), d.getManagementKey(), exclusion );
+ }
+ }
+ }
+ }
+
+ /**
+ * @since 3.2.4
+ */
+ protected void validateDependencyVersion( ModelProblemCollector problems, Dependency d, String prefix )
+ {
+ validateStringNotEmpty( prefix + "version", problems, Severity.ERROR, Version.BASE, d.getVersion(),
+ d.getManagementKey(), d );
+ }
+
+ private void validateRawRepositories( ModelProblemCollector problems, List<Repository> repositories, String prefix,
+ ModelBuildingRequest request )
+ {
+ Map<String, Repository> index = new HashMap<String, Repository>();
+
+ for ( Repository repository : repositories )
+ {
+ validateStringNotEmpty( prefix + ".id", problems, Severity.ERROR, Version.V20, repository.getId(),
+ repository );
+
+ validateStringNotEmpty( prefix + "[" + repository.getId() + "].url", problems, Severity.ERROR, Version.V20,
+ repository.getUrl(), repository );
+
+ String key = repository.getId();
+
+ Repository existing = index.get( key );
+
+ if ( existing != null )
+ {
+ Severity errOn30 = getSeverity( request, ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_3_0 );
+
+ addViolation( problems, errOn30, Version.V20, prefix + ".id", null,
+ "must be unique: " + repository.getId() + " -> " + existing.getUrl() + " vs "
+ + repository.getUrl(), repository );
+ }
+ else
+ {
+ index.put( key, repository );
+ }
+ }
+ }
+
+ private void validate20EffectiveRepository( ModelProblemCollector problems, Repository repository, String prefix,
+ ModelBuildingRequest request )
+ {
+ if ( repository != null )
+ {
+ Severity errOn31 = getSeverity( request, ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_3_1 );
+
+ validateBannedCharacters( prefix + ".id", problems, errOn31, Version.V20, repository.getId(), null,
+ repository, ILLEGAL_REPO_ID_CHARS );
+
+ if ( "local".equals( repository.getId() ) )
+ {
+ addViolation( problems, errOn31, Version.V20, prefix + ".id", null, "must not be 'local'"
+ + ", this identifier is reserved for the local repository"
+ + ", using it for other repositories will corrupt your repository metadata.", repository );
+ }
+
+ if ( "legacy".equals( repository.getLayout() ) )
+ {
+ addViolation( problems, Severity.WARNING, Version.V20, prefix + ".layout", repository.getId(),
+ "uses the unsupported value 'legacy', artifact resolution might fail.", repository );
+ }
+ }
+ }
+
+ private void validate20RawResources( ModelProblemCollector problems, List<Resource> resources, String prefix,
+ ModelBuildingRequest request )
+ {
+ Severity errOn30 = getSeverity( request, ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_3_0 );
+
+ for ( Resource resource : resources )
+ {
+ validateStringNotEmpty( prefix + ".directory", problems, Severity.ERROR, Version.V20,
+ resource.getDirectory(), resource );
+
+ validateBoolean( prefix + ".filtering", problems, errOn30, Version.V20, resource.getFiltering(),
+ resource.getDirectory(), resource );
+ }
+ }
+
+ // ----------------------------------------------------------------------
+ // Field validation
+ // ----------------------------------------------------------------------
+
+ private boolean validateId( String fieldName, ModelProblemCollector problems, String id,
+ InputLocationTracker tracker )
+ {
+ return validateId( fieldName, problems, Severity.ERROR, Version.BASE, id, null, tracker );
+ }
+
+ private boolean validateId( String fieldName, ModelProblemCollector problems, Severity severity, Version version,
+ String id, String sourceHint, InputLocationTracker tracker )
+ {
+ if ( !validateStringNotEmpty( fieldName, problems, severity, version, id, sourceHint, tracker ) )
+ {
+ return false;
+ }
+ else
+ {
+ boolean match = ID_REGEX.matcher( id ).matches();
+ if ( !match )
+ {
+ addViolation( problems, severity, version, fieldName, sourceHint, "with value '" + id
+ + "' does not match a valid id pattern.", tracker );
+ }
+ return match;
+ }
+ }
+
+ private boolean validateIdWithWildcards( String fieldName, ModelProblemCollector problems, Severity severity,
+ Version version, String id, String sourceHint,
+ InputLocationTracker tracker )
+ {
+ if ( !validateStringNotEmpty( fieldName, problems, severity, version, id, sourceHint, tracker ) )
+ {
+ return false;
+ }
+ else
+ {
+ boolean match = ID_WITH_WILDCARDS_REGEX.matcher( id ).matches();
+ if ( !match )
+ {
+ addViolation( problems, severity, version, fieldName, sourceHint, "with value '" + id
+ + "' does not match a valid id pattern.", tracker );
+ }
+ return match;
+ }
+ }
+
+
+ private boolean validateStringNoExpression( String fieldName, ModelProblemCollector problems, Severity severity,
+ Version version, String string, InputLocationTracker tracker )
+ {
+ if ( !hasExpression( string ) )
+ {
+ return true;
+ }
+
+ addViolation( problems, severity, version, fieldName, null, "contains an expression but should be a constant.",
+ tracker );
+
+ return false;
+ }
+
+ private boolean validateVersionNoExpression( String fieldName, ModelProblemCollector problems, Severity severity,
+ Version version, String string, InputLocationTracker tracker )
+ {
+
+ if ( !hasExpression( string ) )
+ {
+ return true;
+ }
+
+ //
+ // Acceptable versions for continuous delivery
+ //
+ // changelist
+ // revision
+ // sha1
+ //
+ if ( string.trim().contains( "${changelist}" ) || string.trim().contains( "${revision}" )
+ || string.trim().contains( "${sha1}" ) )
+ {
+ return true;
+ }
+
+ addViolation( problems, severity, version, fieldName, null, "contains an expression but should be a constant.",
+ tracker );
+
+ return false;
+ }
+
+ private boolean hasExpression( String value )
+ {
+ return value != null && value.contains( "${" );
+ }
+
+ private boolean hasProjectExpression( String value )
+ {
+ return value != null && value.contains( "${project." );
+ }
+
+ private boolean validateStringNotEmpty( String fieldName, ModelProblemCollector problems, Severity severity,
+ Version version, String string, InputLocationTracker tracker )
+ {
+ return validateStringNotEmpty( fieldName, problems, severity, version, string, null, tracker );
+ }
+
+ /**
+ * Asserts:
+ * <p/>
+ * <ul>
+ * <li><code>string != null</code>
+ * <li><code>string.length > 0</code>
+ * </ul>
+ */
+ private boolean validateStringNotEmpty( String fieldName, ModelProblemCollector problems, Severity severity,
+ Version version, String string, String sourceHint,
+ InputLocationTracker tracker )
+ {
+ if ( !validateNotNull( fieldName, problems, severity, version, string, sourceHint, tracker ) )
+ {
+ return false;
+ }
+
+ if ( string.length() > 0 )
+ {
+ return true;
+ }
+
+ addViolation( problems, severity, version, fieldName, sourceHint, "is missing.", tracker );
+
+ return false;
+ }
+
+ /**
+ * Asserts:
+ * <p/>
+ * <ul>
+ * <li><code>string != null</code>
+ * </ul>
+ */
+ private boolean validateNotNull( String fieldName, ModelProblemCollector problems, Severity severity,
+ Version version, Object object, String sourceHint, InputLocationTracker tracker )
+ {
+ if ( object != null )
+ {
+ return true;
+ }
+
+ addViolation( problems, severity, version, fieldName, sourceHint, "is missing.", tracker );
+
+ return false;
+ }
+
+ private boolean validateBoolean( String fieldName, ModelProblemCollector problems, Severity severity,
+ Version version, String string, String sourceHint, InputLocationTracker tracker )
+ {
+ if ( string == null || string.length() <= 0 )
+ {
+ return true;
+ }
+
+ if ( "true".equalsIgnoreCase( string ) || "false".equalsIgnoreCase( string ) )
+ {
+ return true;
+ }
+
+ addViolation( problems, severity, version, fieldName, sourceHint, "must be 'true' or 'false' but is '" + string
+ + "'.", tracker );
+
+ return false;
+ }
+
+ private boolean validateEnum( String fieldName, ModelProblemCollector problems, Severity severity, Version version,
+ String string, String sourceHint, InputLocationTracker tracker,
+ String... validValues )
+ {
+ if ( string == null || string.length() <= 0 )
+ {
+ return true;
+ }
+
+ List<String> values = Arrays.asList( validValues );
+
+ if ( values.contains( string ) )
+ {
+ return true;
+ }
+
+ addViolation( problems, severity, version, fieldName, sourceHint, "must be one of " + values + " but is '"
+ + string + "'.", tracker );
+
+ return false;
+ }
+
+ private boolean validateBannedCharacters( String fieldName, ModelProblemCollector problems, Severity severity,
+ Version version, String string, String sourceHint,
+ InputLocationTracker tracker, String banned )
+ {
+ if ( string != null )
+ {
+ for ( int i = string.length() - 1; i >= 0; i-- )
+ {
+ if ( banned.indexOf( string.charAt( i ) ) >= 0 )
+ {
+ addViolation( problems, severity, version, fieldName, sourceHint,
+ "must not contain any of these characters " + banned + " but found "
+ + string.charAt( i ), tracker );
+ return false;
+ }
+ }
+ }
+
+ return true;
+ }
+
+ private boolean validateVersion( String fieldName, ModelProblemCollector problems, Severity severity,
+ Version version, String string, String sourceHint, InputLocationTracker tracker )
+ {
+ if ( string == null || string.length() <= 0 )
+ {
+ return true;
+ }
+
+ if ( hasExpression( string ) )
+ {
+ addViolation( problems, severity, version, fieldName, sourceHint,
+ "must be a valid version but is '" + string + "'.", tracker );
+ return false;
+ }
+
+ return validateBannedCharacters( fieldName, problems, severity, version, string, sourceHint, tracker,
+ ILLEGAL_VERSION_CHARS );
+
+ }
+
+ private boolean validate20ProperSnapshotVersion( String fieldName, ModelProblemCollector problems,
+ Severity severity, Version version, String string,
+ String sourceHint, InputLocationTracker tracker )
+ {
+ if ( string == null || string.length() <= 0 )
+ {
+ return true;
+ }
+
+ if ( string.endsWith( "SNAPSHOT" ) && !string.endsWith( "-SNAPSHOT" ) )
+ {
+ addViolation( problems, severity, version, fieldName, sourceHint,
+ "uses an unsupported snapshot version format, should be '*-SNAPSHOT' instead.", tracker );
+ return false;
+ }
+
+ return true;
+ }
+
+ private boolean validate20PluginVersion( String fieldName, ModelProblemCollector problems, String string,
+ String sourceHint, InputLocationTracker tracker,
+ ModelBuildingRequest request )
+ {
+ if ( string == null )
+ {
+ // NOTE: The check for missing plugin versions is handled directly by the model builder
+ return true;
+ }
+
+ Severity errOn30 = getSeverity( request, ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_3_0 );
+
+ if ( !validateVersion( fieldName, problems, errOn30, Version.V20, string, sourceHint, tracker ) )
+ {
+ return false;
+ }
+
+ if ( string.length() <= 0 || "RELEASE".equals( string ) || "LATEST".equals( string ) )
+ {
+ addViolation( problems, errOn30, Version.V20, fieldName, sourceHint, "must be a valid version but is '"
+ + string + "'.", tracker );
+ return false;
+ }
+
+ return true;
+ }
+
+ private static void addViolation( ModelProblemCollector problems, Severity severity, Version version,
+ String fieldName, String sourceHint, String message,
+ InputLocationTracker tracker )
+ {
+ StringBuilder buffer = new StringBuilder( 256 );
+ buffer.append( '\'' ).append( fieldName ).append( '\'' );
+
+ if ( sourceHint != null )
+ {
+ buffer.append( " for " ).append( sourceHint );
+ }
+
+ buffer.append( ' ' ).append( message );
+
+ problems.add( new ModelProblemCollectorRequest( severity, version )
+ .setMessage( buffer.toString() ).setLocation( getLocation( fieldName, tracker ) ) );
+ }
+
+ private static InputLocation getLocation( String fieldName, InputLocationTracker tracker )
+ {
+ InputLocation location = null;
+
+ if ( tracker != null )
+ {
+ if ( fieldName != null )
+ {
+ Object key = fieldName;
+
+ int idx = fieldName.lastIndexOf( '.' );
+ if ( idx >= 0 )
+ {
+ fieldName = fieldName.substring( idx + 1 );
+ key = fieldName;
+ }
+
+ if ( fieldName.endsWith( "]" ) )
+ {
+ key = fieldName.substring( fieldName.lastIndexOf( '[' ) + 1, fieldName.length() - 1 );
+ try
+ {
+ key = Integer.valueOf( key.toString() );
+ }
+ catch ( NumberFormatException e )
+ {
+ // use key as is
+ }
+ }
+
+ location = tracker.getLocation( key );
+ }
+
+ if ( location == null )
+ {
+ location = tracker.getLocation( "" );
+ }
+ }
+
+ return location;
+ }
+
+ private static boolean equals( String s1, String s2 )
+ {
+ return StringUtils.clean( s1 ).equals( StringUtils.clean( s2 ) );
+ }
+
+ private static Severity getSeverity( ModelBuildingRequest request, int errorThreshold )
+ {
+ return getSeverity( request.getValidationLevel(), errorThreshold );
+ }
+
+ private static Severity getSeverity( int validationLevel, int errorThreshold )
+ {
+ if ( validationLevel < errorThreshold )
+ {
+ return Severity.WARNING;
+ }
+ else
+ {
+ return Severity.ERROR;
+ }
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/validation/ModelValidator.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/validation/ModelValidator.java
new file mode 100644
index 00000000..84e3fadd
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/java/org/apache/maven/model/validation/ModelValidator.java
@@ -0,0 +1,54 @@
+package org.apache.maven.model.validation;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.model.Model;
+import org.apache.maven.model.building.ModelBuildingRequest;
+import org.apache.maven.model.building.ModelProblemCollector;
+
+/**
+ * Checks the model for missing or invalid values.
+ *
+ * @author <a href="mailto:trygvis@inamo.no">Trygve Laugst&oslash;l</a>
+ */
+public interface ModelValidator
+{
+
+ /**
+ * Checks the specified (raw) model for missing or invalid values. The raw model is directly created from the POM
+ * file and has not been subjected to inheritance, interpolation or profile/default injection.
+ *
+ * @param model The model to validate, must not be {@code null}.
+ * @param request The model building request that holds further settings, must not be {@code null}.
+ * @param problems The container used to collect problems that were encountered, must not be {@code null}.
+ */
+ void validateRawModel( Model model, ModelBuildingRequest request, ModelProblemCollector problems );
+
+ /**
+ * Checks the specified (effective) model for missing or invalid values. The effective model is fully assembled and
+ * has undergone inheritance, interpolation and other model operations.
+ *
+ * @param model The model to validate, must not be {@code null}.
+ * @param request The model building request that holds further settings, must not be {@code null}.
+ * @param problems The container used to collect problems that were encountered, must not be {@code null}.
+ */
+ void validateEffectiveModel( Model model, ModelBuildingRequest request, ModelProblemCollector problems );
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/mdo/profiles.mdo b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/mdo/profiles.mdo
new file mode 100644
index 00000000..26f0d122
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/mdo/profiles.mdo
@@ -0,0 +1,399 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<model xmlns="http://modello.codehaus.org/MODELLO/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://modello.codehaus.org/MODELLO/1.0.0 http://modello.codehaus.org/xsd/modello-1.0.0.xsd"
+ xml.namespace="http://maven.apache.org/PROFILES/${version}"
+ xml.schemaLocation="http://maven.apache.org/xsd/profiles-${version}.xsd">
+ <id>profiles</id>
+ <name>Profiles</name>
+ <description><![CDATA[
+ Project-local overrides to the build process based on detected or user-provided environmental parameters.
+ This is the model specification for ${basedir}/profiles.xml.
+ ]]></description>
+ <defaults>
+ <default>
+ <key>package</key>
+ <value>org.apache.maven.profiles</value>
+ </default>
+ </defaults>
+ <classes>
+ <class rootElement="true" xml.tagName="profilesXml">
+ <name>ProfilesRoot</name>
+ <version>1.0.0</version>
+ <description>Root element of the profiles.xml file.</description>
+ <fields>
+ <field>
+ <name>profiles</name>
+ <version>1.0.0</version>
+ <description><![CDATA[
+ Configuration of build profiles for adjusting the build
+ according to environmental parameters
+ ]]></description>
+ <association>
+ <type>Profile</type>
+ <multiplicity>*</multiplicity>
+ </association>
+ </field>
+ <field>
+ <name>activeProfiles</name>
+ <version>1.0.0</version>
+ <description><![CDATA[
+ List of manually-activated build profiles, specified in the order in which
+ they should be applied.
+ ]]></description>
+ <association>
+ <type>String</type>
+ <multiplicity>*</multiplicity>
+ </association>
+ </field>
+ </fields>
+ </class>
+ <class>
+ <name>Profile</name>
+ <version>1.0.0</version>
+ <description><![CDATA[
+ Modifications to the build process which is keyed on some
+ sort of environmental parameter.
+ ]]></description>
+ <fields>
+ <field>
+ <name>id</name>
+ <required>true</required>
+ <version>1.0.0</version>
+ <type>String</type>
+ <defaultValue>default</defaultValue>
+ <description>The ID of this build profile, for activation
+ purposes.</description>
+ </field>
+ <field>
+ <name>activation</name>
+ <version>1.0.0</version>
+ <description><![CDATA[The conditional logic which will automatically
+ trigger the inclusion of this profile.]]></description>
+ <association>
+ <type>Activation</type>
+ </association>
+ </field>
+ <field>
+ <name>properties</name>
+ <description>Extended configuration specific to this profile goes
+ here.</description>
+ <type>Properties</type>
+ <association xml.mapStyle="inline">
+ <type>String</type>
+ <multiplicity>*</multiplicity>
+ </association>
+ </field>
+ <field>
+ <name>repositories</name>
+ <version>1.0.0</version>
+ <description><![CDATA[The lists of the remote repositories]]>
+ </description>
+ <association>
+ <type>Repository</type>
+ <multiplicity>*</multiplicity>
+ </association>
+ </field>
+ <field>
+ <name>pluginRepositories</name>
+ <version>1.0.0</version>
+ <description><![CDATA[
+ The lists of the remote repositories for discovering plugins
+ ]]></description>
+ <association>
+ <type>Repository</type>
+ <multiplicity>*</multiplicity>
+ </association>
+ <comment><![CDATA[ This may be removed or relocated in the near
+ future. It is undecided whether plugins really need a remote
+ repository set of their own. ]]></comment>
+ </field>
+ </fields>
+ </class>
+ <class>
+ <name>Activation</name>
+ <version>1.0.0</version>
+ <description><![CDATA[
+ The conditions within the build runtime environment which will trigger
+ the automatic inclusion of the parent build profile.
+ ]]></description>
+ <fields>
+ <field>
+ <name>activeByDefault</name>
+ <version>1.0.0</version>
+ <type>boolean</type>
+ <description>Flag specifying whether this profile is active as a default.</description>
+ </field>
+ <field>
+ <name>jdk</name>
+ <version>1.0.0</version>
+ <type>String</type>
+ <description><![CDATA[
+ Specifies that this profile will be activated when a matching JDK is detected.
+ ]]></description>
+ </field>
+ <field>
+ <name>os</name>
+ <version>1.0.0</version>
+ <description><![CDATA[
+ Specifies that this profile will be activated when matching OS attributes are detected.
+ ]]></description>
+ <association>
+ <type>ActivationOS</type>
+ </association>
+ </field>
+ <field>
+ <name>property</name>
+ <version>1.0.0</version>
+ <description><![CDATA[
+ Specifies that this profile will be activated when this System property is specified.
+ ]]></description>
+ <association>
+ <type>ActivationProperty</type>
+ </association>
+ </field>
+ <field>
+ <name>file</name>
+ <version>1.0.0</version>
+ <description><![CDATA[
+ Specifies that this profile will be activated based on existence of a file.
+ ]]></description>
+ <association>
+ <type>ActivationFile</type>
+ </association>
+ </field>
+ </fields>
+ </class>
+
+ <!-- TODO: reproduced from maven-model/maven.mdo, instead should inherit code and link to external docs -->
+ <class>
+ <name>RepositoryBase</name>
+ <version>1.0.0</version>
+ <description><![CDATA[
+ Repository contains the information needed
+ for establishing connections with remote repoistory
+ ]]></description>
+ <fields>
+ <field>
+ <name>id</name>
+ <version>1.0.0</version>
+ <description><![CDATA[
+ A unique identifier for a repository.
+ ]]></description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>name</name>
+ <version>1.0.0</version>
+ <description><![CDATA[
+ Human readable name of the repository
+ ]]></description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>url</name>
+ <version>1.0.0</version>
+ <description><![CDATA[
+ The url of the repository
+ ]]></description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>layout</name>
+ <version>1.0.0</version>
+ <description>The type of layout this repository uses for locating and storing artifacts - can be "legacy" or
+ "default".</description>
+ <type>String</type>
+ <defaultValue>default</defaultValue>
+ </field>
+ </fields>
+ <codeSegments>
+ <codeSegment>
+ <version>1.0.0</version>
+ <code><![CDATA[
+ public boolean equals( Object obj )
+ {
+ RepositoryBase other = (RepositoryBase) obj;
+
+ boolean retValue = false;
+
+ if ( id != null )
+ {
+ retValue = id.equals( other.id );
+ }
+
+ return retValue;
+ }
+ ]]></code>
+ </codeSegment>
+ </codeSegments>
+ </class>
+ <class>
+ <name>Repository</name>
+ <superClass>RepositoryBase</superClass>
+ <version>1.0.0</version>
+ <description>
+ Repository contains the information needed for establishing connections with remote repoistory
+ </description>
+ <fields>
+ <field>
+ <name>releases</name>
+ <version>1.0.0</version>
+ <description>How to handle downloading of releases from this repository</description>
+ <association>
+ <type>RepositoryPolicy</type>
+ </association>
+ </field>
+ <field>
+ <name>snapshots</name>
+ <version>1.0.0</version>
+ <description>How to handle downloading of snapshots from this repository</description>
+ <association>
+ <type>RepositoryPolicy</type>
+ </association>
+ </field>
+ </fields>
+ <!-- prevent modello generation of an incorrect equals method. Could be avoided by using <identity/> tags to mark ID as the only identity field -->
+ <codeSegments>
+ <codeSegment>
+ <version>1.0.0</version>
+ <code><![CDATA[
+ public boolean equals( Object obj )
+ {
+ return super.equals( obj );
+ }
+ ]]></code>
+ </codeSegment>
+ </codeSegments>
+ </class>
+
+ <class>
+ <name>RepositoryPolicy</name>
+ <version>1.0.0</version>
+ <description>Download policy</description>
+ <fields>
+ <field>
+ <name>enabled</name>
+ <version>1.0.0</version>
+ <description>Whether to use this repository for downloading this type of artifact</description>
+ <type>boolean</type>
+ <defaultValue>true</defaultValue>
+ </field>
+ <field>
+ <name>updatePolicy</name>
+ <version>1.0.0</version>
+ <description>
+ The frequency for downloading updates - can be "always", "daily" (default), "interval:XXX" (in minutes) or
+ "never" (only if it doesn't exist locally).
+ </description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>checksumPolicy</name>
+ <version>1.0.0</version>
+ <description>What to do when verification of an artifact checksum fails - warn, fail, etc. Valid values are
+ "fail" or "warn"</description>
+ <type>String</type>
+ </field>
+ </fields>
+ </class>
+ <class>
+ <name>ActivationProperty</name>
+ <version>1.0.0</version>
+ <description><![CDATA[
+ This is the property specification used to activate a profile. If the value field is empty,
+ then the existence of the named property will activate the profile, otherwise it does a case-sensitive
+ match against the property value as well.
+ ]]></description>
+ <fields>
+ <field>
+ <name>name</name>
+ <version>1.0.0</version>
+ <type>String</type>
+ <required>true</required>
+ <description>The name of the property to be used to activate a profile</description>
+ </field>
+ <field>
+ <name>value</name>
+ <version>1.0.0</version>
+ <type>String</type>
+ <description>The value of the property to be used to activate a profile</description>
+ </field>
+ </fields>
+ </class>
+ <class>
+ <name>ActivationFile</name>
+ <version>1.0.0</version>
+ <description><![CDATA[
+ This is the file specification used to activate a profile. The missing value will be a the location
+ of a file that needs to exist, and if it doesn't the profile must run. On the other hand exists will test
+ for the existence of the file and if it is there will run the profile.
+ ]]></description>
+ <fields>
+ <field>
+ <name>missing</name>
+ <version>1.0.0</version>
+ <type>String</type>
+ <description>The name of the file that should be missing to activate a profile</description>
+ </field>
+ <field>
+ <name>exists</name>
+ <version>1.0.0</version>
+ <type>String</type>
+ <description>The name of the file that should exist to activate a profile</description>
+ </field>
+ </fields>
+ </class>
+ <class>
+ <name>ActivationOS</name>
+ <version>1.0.0</version>
+ <description><![CDATA[
+ This is an activator which will detect an operating system's attributes in order to activate
+ its profile.
+ ]]></description>
+ <fields>
+ <field>
+ <name>name</name>
+ <version>1.0.0</version>
+ <type>String</type>
+ <description>The name of the OS to be used to activate a profile</description>
+ </field>
+ <field>
+ <name>family</name>
+ <version>1.0.0</version>
+ <type>String</type>
+ <description>The general family of the OS to be used to activate a profile (e.g. 'windows')</description>
+ </field>
+ <field>
+ <name>arch</name>
+ <version>1.0.0</version>
+ <type>String</type>
+ <description>The architecture of the OS to be used to activate a profile</description>
+ </field>
+ <field>
+ <name>version</name>
+ <version>1.0.0</version>
+ <type>String</type>
+ <description>The version of the OS to be used to activate a profile</description>
+ </field>
+ </fields>
+ </class>
+ </classes>
+</model>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/resources/org/apache/maven/model/pom-4.0.0.xml b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/resources/org/apache/maven/model/pom-4.0.0.xml
new file mode 100644
index 00000000..91492a92
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/main/resources/org/apache/maven/model/pom-4.0.0.xml
@@ -0,0 +1,150 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<!-- START SNIPPET: superpom -->
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <repositories>
+ <repository>
+ <id>central</id>
+ <name>Central Repository</name>
+ <url>https://repo.maven.apache.org/maven2</url>
+ <layout>default</layout>
+ <snapshots>
+ <enabled>false</enabled>
+ </snapshots>
+ </repository>
+ </repositories>
+
+ <pluginRepositories>
+ <pluginRepository>
+ <id>central</id>
+ <name>Central Repository</name>
+ <url>https://repo.maven.apache.org/maven2</url>
+ <layout>default</layout>
+ <snapshots>
+ <enabled>false</enabled>
+ </snapshots>
+ <releases>
+ <updatePolicy>never</updatePolicy>
+ </releases>
+ </pluginRepository>
+ </pluginRepositories>
+
+ <build>
+ <directory>${project.basedir}/target</directory>
+ <outputDirectory>${project.build.directory}/classes</outputDirectory>
+ <finalName>${project.artifactId}-${project.version}</finalName>
+ <testOutputDirectory>${project.build.directory}/test-classes</testOutputDirectory>
+ <sourceDirectory>${project.basedir}/src/main/java</sourceDirectory>
+ <scriptSourceDirectory>${project.basedir}/src/main/scripts</scriptSourceDirectory>
+ <testSourceDirectory>${project.basedir}/src/test/java</testSourceDirectory>
+ <resources>
+ <resource>
+ <directory>${project.basedir}/src/main/resources</directory>
+ </resource>
+ </resources>
+ <testResources>
+ <testResource>
+ <directory>${project.basedir}/src/test/resources</directory>
+ </testResource>
+ </testResources>
+ <pluginManagement>
+ <!-- NOTE: These plugins will be removed from future versions of the super POM -->
+ <!-- They are kept for the moment as they are very unlikely to conflict with lifecycle mappings (MNG-4453) -->
+ <plugins>
+ <plugin>
+ <artifactId>maven-antrun-plugin</artifactId>
+ <version>1.3</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <version>2.2-beta-5</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <version>2.8</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-release-plugin</artifactId>
+ <version>2.3.2</version>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+
+ <reporting>
+ <outputDirectory>${project.build.directory}/site</outputDirectory>
+ </reporting>
+
+ <profiles>
+ <!-- NOTE: The release profile will be removed from future versions of the super POM -->
+ <profile>
+ <id>release-profile</id>
+
+ <activation>
+ <property>
+ <name>performRelease</name>
+ <value>true</value>
+ </property>
+ </activation>
+
+ <build>
+ <plugins>
+ <plugin>
+ <inherited>true</inherited>
+ <artifactId>maven-source-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>attach-sources</id>
+ <goals>
+ <goal>jar</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <inherited>true</inherited>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>attach-javadocs</id>
+ <goals>
+ <goal>jar</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <inherited>true</inherited>
+ <artifactId>maven-deploy-plugin</artifactId>
+ <configuration>
+ <updateReleaseInfo>true</updateReleaseInfo>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
+
+</project>
+<!-- END SNIPPET: superpom -->
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/site/apt/index.apt b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/site/apt/index.apt
new file mode 100644
index 00000000..64cb805c
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/site/apt/index.apt
@@ -0,0 +1,187 @@
+~~ Licensed to the Apache Software Foundation (ASF) under one
+~~ or more contributor license agreements. See the NOTICE file
+~~ distributed with this work for additional information
+~~ regarding copyright ownership. The ASF licenses this file
+~~ to you under the Apache License, Version 2.0 (the
+~~ "License"); you may not use this file except in compliance
+~~ with the License. You may obtain a copy of the License at
+~~
+~~ http://www.apache.org/licenses/LICENSE-2.0
+~~
+~~ Unless required by applicable law or agreed to in writing,
+~~ software distributed under the License is distributed on an
+~~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+~~ KIND, either express or implied. See the License for the
+~~ specific language governing permissions and limitations
+~~ under the License.
+
+ -----
+ Introduction
+ -----
+ Hervé Boutemy
+ -----
+ 2013-03-19
+ -----
+
+Maven Model Builder
+
+ The effective model builder, with profile activation, inheritance, interpolation, ...
+
+ The main component is <<<ModelBuilder>>>
+ ({{{./apidocs/org/apache/maven/model/building/ModelBuilder.html}javadoc}},
+ {{{./xref/org/apache/maven/model/building/ModelBuilder.html}source}}),
+ with its <<<DefaultModelBuilder>>> implementation
+ ({{{./apidocs/org/apache/maven/model/building/DefaultModelBuilder.html}javadoc}},
+ {{{./xref/org/apache/maven/model/building/DefaultModelBuilder.html}source}})
+ that manages the steps sequence.
+
+ The sequence is divided into 2 phases:
+
+ * phase 1
+
+ ** profile activation: see {{{./apidocs/org/apache/maven/model/profile/activation/package-summary.html}available activators}}.
+ Notice that model interpolation hasn't happened yet, then interpolation for file-based activation is limited to
+ <<<$\{basedir}>>> (since Maven 3), System properties and request properties
+
+ ** raw model validation: <<<ModelValidator>>> ({{{./apidocs/org/apache/maven/model/validation/ModelValidator.html}javadoc}}),
+ with its <<<DefaultModelValidator>>> implementation
+ ({{{./xref/org/apache/maven/model/validation/DefaultModelValidator.html}source}})
+
+ ** model normalization - merge duplicates: <<<ModelNormalizer>>> ({{{./apidocs/org/apache/maven/model/normalization/ModelNormalizer.html}javadoc}}),
+ with its <<<DefaultModelNormalizer>>> implementation
+ ({{{./xref/org/apache/maven/model/normalization/DefaultModelNormalizer.html}source}})
+
+ ** profile injection: <<<ProfileInjector>>> ({{{./apidocs/org/apache/maven/model/profile/ProfileInjector.html}javadoc}}),
+ with its <<<DefaultProfileInjector>>> implementation
+ ({{{./xref/org/apache/maven/model/profile/DefaultProfileInjector.html}source}})
+
+ ** parent resolution until {{{./super-pom.html}super-pom}}
+
+ ** inheritance assembly: <<<InheritanceAssembler>>> ({{{./apidocs/org/apache/maven/model/inheritance/InheritanceAssembler.html}javadoc}}),
+ with its <<<DefaultInheritanceAssembler>>> implementation
+ ({{{./xref/org/apache/maven/model/inheritance/DefaultInheritanceAssembler.html}source}})
+
+ ** model interpolation (see below)
+
+ ** url normalization: <<<UrlNormalizer>>> ({{{./apidocs/org/apache/maven/model/path/UrlNormalizer.html}javadoc}}),
+ with its <<<DefaultUrlNormalizer>>> implementation
+ ({{{./xref/org/apache/maven/model/path/DefaultUrlNormalizer.html}source}})
+
+ []
+
+ * phase 2, with optional plugin processing
+
+ ** model path translation: <<<ModelPathTranslator>>> ({{{./apidocs/org/apache/maven/model/path/ModelPathTranslator.html}javadoc}}),
+ with its <<<DefaultModelPathTranslator>>> implementation
+ ({{{./xref/org/apache/maven/model/path/DefaultModelPathTranslator.html}source}})
+
+ ** plugin management injection: <<<PluginManagementInjector>>> ({{{./apidocs/org/apache/maven/model/management/PluginManagementInjector.html}javadoc}}),
+ with its <<<DefaultPluginManagementInjector>>> implementation
+ ({{{./xref/org/apache/maven/model/management/DefaultPluginManagementInjector.html}source}})
+
+ ** <(optional)> lifecycle bindings injection: <<<LifecycleBindingsInjector>>> ({{{./apidocs/org/apache/maven/model/plugin/LifecycleBindingsInjector.html}javadoc}}),
+ with its <<<DefaultLifecycleBindingsInjector>>> implementation
+ ({{{./xref/org/apache/maven/model/plugin/DefaultLifecycleBindingsInjector.html}source}})
+
+ ** dependency management import (for dependencies of type <<<pom>>> in the <<<\<dependencyManagement\>>>> section)
+
+ ** dependency management injection: <<<DependencyManagementInjector>>> ({{{./apidocs/org/apache/maven/model/management/DependencyManagementInjector.html}javadoc}}),
+ with its <<<DefaultDependencyManagementInjector>>> implementation
+ ({{{./xref/org/apache/maven/model/management/DefaultDependencyManagementInjector.html}source}})
+
+ ** model normalization - inject default values: <<<ModelNormalizer>>> ({{{./apidocs/org/apache/maven/model/normalization/ModelNormalizer.html}javadoc}}),
+ with its <<<DefaultModelNormalizer>>> implementation
+ ({{{./xref/org/apache/maven/model/normalization/DefaultModelNormalizer.html}source}})
+
+ ** <(optional)> reports configuration: <<<ReportConfigurationExpander>>> ({{{./apidocs/org/apache/maven/model/plugin/ReportConfigurationExpander.html}javadoc}}),
+ with its <<<DefaultReportConfigurationExpander>>> implementation
+ ({{{./xref/org/apache/maven/model/plugin/DefaultReportConfigurationExpander.html}source}})
+
+ ** <(optional)> reports conversion to decoupled site plugin: <<<ReportingConverter>>> ({{{./apidocs/org/apache/maven/model/plugin/ReportingConverter.html}javadoc}}),
+ with its <<<DefaultReportingConverter>>> implementation
+ ({{{./xref/org/apache/maven/model/plugin/DefaultReportingConverter.html}source}})
+
+ ** <(optional)> plugins configuration: <<<PluginConfigurationExpander>>> ({{{./apidocs/org/apache/maven/model/plugin/PluginConfigurationExpander.html}javadoc}}),
+ with its <<<DefaultPluginConfigurationExpander>>> implementation
+ ({{{./xref/org/apache/maven/model/plugin/DefaultPluginConfigurationExpander.html}source}})
+
+ ** effective model validation: <<<ModelValidator>>> ({{{./apidocs/org/apache/maven/model/validation/ModelValidator.html}javadoc}}),
+ with its <<<DefaultModelValidator>>> implementation
+ ({{{./xref/org/apache/maven/model/validation/DefaultModelValidator.html}source}})
+
+ []
+
+ []
+
+
+* Model Interpolation
+
+ Model Interpolation consists in replacing <<<$\{...\}>>> with calculated value. It is done in <<<StringSearchModelInterpolator>>>
+ ({{{./apidocs/org/apache/maven/model/interpolation/StringSearchModelInterpolator.html}javadoc}},
+ {{{./xref/org/apache/maven/model/interpolation/StringSearchModelInterpolator.html}source}}).
+
+ Notice that model interpolation happens <after> profile activation, then profile activation doesn't benefit from every values:
+ interpolation for file-based activation is limited to <<<$\{basedir}>>> (which was introduced in Maven 3 and is not deprecated
+ in this context), System properties and request properties.
+
+ Values are evaluated in sequence from different syntaxes:
+
+*----+------+------+
+|| value || evaluation result || common examples ||
+*----+------+------+
+| <<<project.*>>>\
+<<<pom.*>>> (<deprecated>)\
+<<<*>>> (<deprecated>) | POM content (see {{{../maven-model/maven.html}POM reference}}) | <<<$\{project.version\}>>>\
+ | | <<<$\{project.build.finalName\}>>>\
+ | | <<<$\{project.artifactId\}>>>\
+ | | <<<$\{project.build.directory\}>>> |
+*----+------+------+
+| <<<project.basedir>>>\
+<<<pom.basedir>>> (<deprecated>)\
+<<<basedir>>> (<deprecated>) | the directory containing the <<<pom.xml>>> file | <<<$\{project.basedir\}>>> |
+*----+------+------+
+| <<<project.baseUri>>>\
+<<<pom.baseUri>>> (<deprecated>) | the directory containing the <<<pom.xml>>> file as URI | <<<$\{project.baseUri\}>>> |
+*----+------+------+
+| <<<build.timestamp>>>\
+<<<maven.build.timestamp>>> | the UTC timestamp of build start, in <<<yyyy-MM-dd'T'HH:mm:ss'Z'>>> default format, which can be overridden with <<<maven.build.timestamp.format>>> POM property | <<<$\{maven.build.timestamp\}>>> |
+*----+------+------+
+| <<<*>>> | user properties, set from CLI with <<<-Dproperty=value>>> | <<<$\{skipTests\}>>> |
+*----+------+------+
+| <<<*>>> | model properties, such as project properties set in the pom | <<<$\{any.key\}>>> |
+*----+------+------+
+| <<<maven.home>>> | The path to the current Maven home. | <<<$\{maven.home\}>>> |
+*----+------+------+
+| <<<maven.version>>> | The version number of the current Maven execution <(since 3.0.4)>. For example, "<<<3.0.5>>>". | <<<$\{maven.version\}>>> |
+*----+------+------+
+| <<<maven.build.version>>> | The full build version of the current Maven execution <(since 3.0.4)>. For example, "<<<Apache Maven 3.2.2 (r01de14724cdef164cd33c7c8c2fe155faf9602da; 2013-02-19T14:51:28+01:00)>>>". | <<<$\{maven.build.version\}>>> |
+*----+------+------+
+| <<<*>>> | Java system properties (see {{{http://download.oracle.com/javase/6/docs/api/java/lang/System.html#getProperties()}JDK reference}}) | <<<$\{user.home\}>>>\
+ | | <<<$\{java.home\}>>> |
+*----+------+------+
+| <<<env.*>>>\
+<<<*>>> | environment variables | <<<$\{env.PATH\}>>> |
+*----+------+------+
+| <<<settings.*>>> | Local user settings (see {{{../maven-settings/settings.xml/settings.html}settings reference}}) | <<<$\{settings.localRepository\}>>> |
+*----+------+------+
+
+** Notice
+
+ * after model interpolation, <<<$\{...\}>>> content can remain in the model that will be evaluated later
+ when setting plugin parameters. This happens in particular with <<<settings.*>>> values for
+ {{{../maven-settings/settings.html}Settings Model}},
+
+ * encoding configuration have been defined as POM properties looking like POM content but not added to POM model to maintain
+ compatibility with previous Maven versions:
+
+ * <<<$\{project.build.sourceEncoding\}>>> for
+ {{{http://docs.codehaus.org/display/MAVENUSER/POM+Element+for+Source+File+Encoding}source files encoding}}
+ (defaults to platform encoding)
+
+ * <<<$\{project.reporting.outputEncoding\}>>> for
+ {{{https://cwiki.apache.org/confluence/display/MAVENOLD/Reporting+Encoding+Configuration}reporting output files encoding}}
+ (defaults to <<<UTF-8>>>)
+
+ []
+
+ []
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/site/apt/super-pom.apt.vm b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/site/apt/super-pom.apt.vm
new file mode 100644
index 00000000..df86d70e
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/site/apt/super-pom.apt.vm
@@ -0,0 +1,30 @@
+~~ Licensed to the Apache Software Foundation (ASF) under one
+~~ or more contributor license agreements. See the NOTICE file
+~~ distributed with this work for additional information
+~~ regarding copyright ownership. The ASF licenses this file
+~~ to you under the Apache License, Version 2.0 (the
+~~ "License"); you may not use this file except in compliance
+~~ with the License. You may obtain a copy of the License at
+~~
+~~ http://www.apache.org/licenses/LICENSE-2.0
+~~
+~~ Unless required by applicable law or agreed to in writing,
+~~ software distributed under the License is distributed on an
+~~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+~~ KIND, either express or implied. See the License for the
+~~ specific language governing permissions and limitations
+~~ under the License.
+
+ -----
+ Super POM
+ -----
+ Hervé Boutemy
+ -----
+ 2011-09-12
+ -----
+
+Super POM
+
+ All models implicitly inherit from a super-POM:
+
+%{snippet|id=superpom|file=${project.build.sourceDirectory}/../resources/org/apache/maven/model/pom-4.0.0.xml}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/site/site.xml b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/site/site.xml
new file mode 100644
index 00000000..04f54455
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/site/site.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project xmlns="http://maven.apache.org/DECORATION/1.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/DECORATION/1.0.0 http://maven.apache.org/xsd/decoration-1.0.0.xsd">
+ <body>
+ <menu name="Overview">
+ <item name="Introduction" href="index.html"/>
+ <item name="JavaDocs" href="apidocs/index.html"/>
+ <item name="Source Xref" href="xref/index.html"/>
+ <!--item name="FAQ" href="faq.html"/-->
+ </menu>
+
+ <menu name="Reference">
+ <item name="Super POM" href="super-pom.html"/>
+ </menu>
+
+ <menu ref="parent"/>
+ <menu ref="reports"/>
+ </body>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/java/org/apache/maven/model/building/ComplexActivationTest.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/java/org/apache/maven/model/building/ComplexActivationTest.java
new file mode 100644
index 00000000..9ef31b3d
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/java/org/apache/maven/model/building/ComplexActivationTest.java
@@ -0,0 +1,60 @@
+package org.apache.maven.model.building;
+
+ /*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import junit.framework.TestCase;
+
+import java.io.File;
+import java.util.Properties;
+
+/**
+ * @author Konstantin Perikov
+ */
+public class ComplexActivationTest
+ extends TestCase
+{
+
+ private File getPom( String name )
+ {
+ return new File( "src/test/resources/poms/factory/" + name + ".xml" ).getAbsoluteFile();
+ }
+
+ public void testAndConditionInActivation()
+ throws Exception
+ {
+ Properties sysProperties = new Properties();
+ sysProperties.setProperty( "myproperty", "test" );
+
+ ModelBuilder builder = new DefaultModelBuilderFactory().newInstance();
+ assertNotNull( builder );
+
+ DefaultModelBuildingRequest request = new DefaultModelBuildingRequest();
+ request.setProcessPlugins( true );
+ request.setPomFile( getPom( "complex" ) );
+ request.setSystemProperties( sysProperties );
+
+ ModelBuildingResult result = builder.build( request );
+ assertNotNull( result );
+ assertNotNull( result.getEffectiveModel() );
+ assertEquals( "activated-1", result.getEffectiveModel().getProperties().get( "profile.file" ) );
+ assertNull( result.getEffectiveModel().getProperties().get( "profile.miss" ) );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/java/org/apache/maven/model/building/DefaultModelBuilderFactoryTest.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/java/org/apache/maven/model/building/DefaultModelBuilderFactoryTest.java
new file mode 100644
index 00000000..90b65a4c
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/java/org/apache/maven/model/building/DefaultModelBuilderFactoryTest.java
@@ -0,0 +1,59 @@
+package org.apache.maven.model.building;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+
+import org.codehaus.plexus.util.xml.Xpp3Dom;
+
+import junit.framework.TestCase;
+
+/**
+ * @author Benjamin Bentmann
+ */
+public class DefaultModelBuilderFactoryTest
+ extends TestCase
+{
+
+ private File getPom( String name )
+ {
+ return new File( "src/test/resources/poms/factory/" + name + ".xml" ).getAbsoluteFile();
+ }
+
+ public void testCompleteWiring()
+ throws Exception
+ {
+ ModelBuilder builder = new DefaultModelBuilderFactory().newInstance();
+ assertNotNull( builder );
+
+ DefaultModelBuildingRequest request = new DefaultModelBuildingRequest();
+ request.setProcessPlugins( true );
+ request.setPomFile( getPom( "simple" ) );
+
+ ModelBuildingResult result = builder.build( request );
+ assertNotNull( result );
+ assertNotNull( result.getEffectiveModel() );
+ assertEquals( "activated", result.getEffectiveModel().getProperties().get( "profile.file" ) );
+ Xpp3Dom conf = (Xpp3Dom) result.getEffectiveModel().getBuild().getPlugins().get( 0 ).getConfiguration();
+ assertEquals( "1.5", conf.getChild( "source" ).getValue() );
+ assertEquals( " 1.5 ", conf.getChild( "target" ).getValue() );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/java/org/apache/maven/model/building/SimpleProblemCollector.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/java/org/apache/maven/model/building/SimpleProblemCollector.java
new file mode 100644
index 00000000..bb0ccff9
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/java/org/apache/maven/model/building/SimpleProblemCollector.java
@@ -0,0 +1,89 @@
+package org.apache.maven.model.building;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.maven.model.Model;
+
+
+/**
+ * A simple model problem collector for testing the model building components.
+ *
+ * @author Benjamin Bentmann
+ */
+public class SimpleProblemCollector
+ implements ModelProblemCollector
+{
+ private Model model;
+
+ private List<String> warnings = new ArrayList<String>();
+
+ private List<String> errors = new ArrayList<String>();
+
+ private List<String> fatals = new ArrayList<String>();
+
+ public SimpleProblemCollector()
+ {
+ }
+
+ public SimpleProblemCollector( Model model )
+ {
+ this.model = model;
+ }
+
+ public Model getModel()
+ {
+ return model;
+ }
+
+ public List<String> getWarnings()
+ {
+ return warnings;
+ }
+
+ public List<String> getErrors()
+ {
+ return errors;
+ }
+
+ public List<String> getFatals()
+ {
+ return fatals;
+ }
+
+ public void add( ModelProblemCollectorRequest req )
+ {
+ switch ( req.getSeverity() )
+ {
+ case FATAL:
+ fatals.add( req.getMessage() );
+ break;
+ case ERROR:
+ errors.add( req.getMessage() );
+ break;
+ case WARNING:
+ warnings.add( req.getMessage() );
+ break;
+ }
+
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/java/org/apache/maven/model/inheritance/DefaultInheritanceAssemblerTest.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/java/org/apache/maven/model/inheritance/DefaultInheritanceAssemblerTest.java
new file mode 100644
index 00000000..1aef12ec
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/java/org/apache/maven/model/inheritance/DefaultInheritanceAssemblerTest.java
@@ -0,0 +1,108 @@
+package org.apache.maven.model.inheritance;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.Reader;
+
+import org.apache.maven.model.Model;
+import org.apache.maven.model.building.SimpleProblemCollector;
+import org.apache.maven.model.io.ModelParseException;
+import org.apache.maven.model.io.ModelReader;
+import org.apache.maven.model.io.ModelWriter;
+import org.codehaus.plexus.PlexusTestCase;
+import org.codehaus.plexus.util.IOUtil;
+import org.custommonkey.xmlunit.XMLAssert;
+import org.custommonkey.xmlunit.XMLUnit;
+
+/**
+ * @author Hervé Boutemy
+ */
+public class DefaultInheritanceAssemblerTest
+ extends PlexusTestCase
+{
+ private ModelReader reader;
+
+ private ModelWriter writer;
+
+ private InheritanceAssembler assembler;
+
+ @Override
+ protected void setUp()
+ throws Exception
+ {
+ super.setUp();
+
+ reader = lookup( ModelReader.class );
+ writer = lookup( ModelWriter.class );
+ assembler = lookup( InheritanceAssembler.class );
+ }
+
+ private File getPom( String name )
+ {
+ return getTestFile( "src/test/resources/poms/inheritance/" + name + ".xml" );
+ }
+
+ private Model getModel( String name )
+ throws ModelParseException, IOException
+ {
+ return reader.read( getPom( name ), null );
+ }
+
+ public void testPluginConfiguration()
+ throws Exception
+ {
+ Model parent = getModel( "plugin-configuration-parent" );
+
+ Model child = getModel( "plugin-configuration-child" );
+
+ SimpleProblemCollector problems = new SimpleProblemCollector();
+
+ assembler.assembleModelInheritance( child, parent, null, problems );
+
+ File actual = getTestFile( "target/test-classes/poms/inheritance/plugin-configuration-actual.xml" );
+
+ writer.write( actual, null, child );
+
+ // check with getPom( "plugin-configuration-effective" )
+ Reader control = null;
+ Reader test = null;
+ try
+ {
+ File expected = getPom( "plugin-configuration-expected" );
+ control = new InputStreamReader( new FileInputStream( expected ), "UTF-8" );
+
+ test = new InputStreamReader( new FileInputStream( actual ), "UTF-8" );
+
+ XMLUnit.setIgnoreComments( true );
+ XMLUnit.setIgnoreWhitespace( true );
+ XMLAssert.assertXMLEqual( control, test );
+ }
+ catch ( IOException ioe )
+ {
+ IOUtil.close( control );
+ IOUtil.close( test );
+ }
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/java/org/apache/maven/model/interpolation/AbstractModelInterpolatorTest.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/java/org/apache/maven/model/interpolation/AbstractModelInterpolatorTest.java
new file mode 100644
index 00000000..99842dfe
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/java/org/apache/maven/model/interpolation/AbstractModelInterpolatorTest.java
@@ -0,0 +1,494 @@
+package org.apache.maven.model.interpolation;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.model.Build;
+import org.apache.maven.model.Dependency;
+import org.apache.maven.model.Model;
+import org.apache.maven.model.Organization;
+import org.apache.maven.model.Repository;
+import org.apache.maven.model.Resource;
+import org.apache.maven.model.Scm;
+import org.apache.maven.model.building.DefaultModelBuildingRequest;
+import org.apache.maven.model.building.ModelBuildingRequest;
+import org.apache.maven.model.building.SimpleProblemCollector;
+import org.apache.maven.model.path.PathTranslator;
+import org.codehaus.plexus.PlexusTestCase;
+
+import java.io.File;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Properties;
+import java.util.TimeZone;
+
+/**
+ * @author jdcasey
+ */
+public abstract class AbstractModelInterpolatorTest
+ extends PlexusTestCase
+{
+ private Properties context;
+
+ protected void setUp()
+ throws Exception
+ {
+ super.setUp();
+
+ context = new Properties();
+ context.put( "basedir", "myBasedir" );
+ context.put( "project.baseUri", "myBaseUri" );
+ }
+
+
+ protected void assertProblemFree( SimpleProblemCollector collector )
+ {
+ assertEquals( "Expected no errors", 0, collector.getErrors().size() );
+ assertEquals( "Expected no warnings", 0, collector.getWarnings().size() );
+ assertEquals( "Expected no fatals", 0, collector.getFatals().size() );
+ }
+
+ protected void assertColllectorState( int numFatals, int numErrors, int numWarnings,
+ SimpleProblemCollector collector )
+ {
+ assertEquals( "Errors", numErrors, collector.getErrors().size() );
+ assertEquals( "Warnings", numWarnings, collector.getWarnings().size() );
+ assertEquals( "Fatals", numFatals, collector.getFatals().size() );
+ }
+
+ private ModelBuildingRequest createModelBuildingRequest( Properties p )
+ {
+ ModelBuildingRequest config = new DefaultModelBuildingRequest();
+ if ( p != null )
+ {
+ config.setSystemProperties( p );
+ }
+ return config;
+ }
+
+ public void testDefaultBuildTimestampFormatShouldFormatTimeIn24HourFormat()
+ {
+ Calendar cal = Calendar.getInstance();
+ cal.setTimeZone(TimeZone.getTimeZone("UTC"));
+ cal.set( Calendar.HOUR, 12 );
+ cal.set( Calendar.AM_PM, Calendar.AM );
+
+ // just to make sure all the bases are covered...
+ cal.set( Calendar.HOUR_OF_DAY, 0 );
+ cal.set( Calendar.MINUTE, 16 );
+ cal.set( Calendar.SECOND, 0 );
+ cal.set( Calendar.YEAR, 1976 );
+ cal.set( Calendar.MONTH, Calendar.NOVEMBER );
+ cal.set( Calendar.DATE, 11 );
+
+ Date firstTestDate = cal.getTime();
+
+ cal.set( Calendar.HOUR, 11 );
+ cal.set( Calendar.AM_PM, Calendar.PM );
+
+ // just to make sure all the bases are covered...
+ cal.set( Calendar.HOUR_OF_DAY, 23 );
+
+ Date secondTestDate = cal.getTime();
+
+ SimpleDateFormat format =
+ new SimpleDateFormat( MavenBuildTimestamp.DEFAULT_BUILD_TIMESTAMP_FORMAT );
+ format.setTimeZone(TimeZone.getTimeZone("UTC"));
+ assertEquals( "1976-11-11T00:16:00Z", format.format( firstTestDate ) );
+ assertEquals( "1976-11-11T23:16:00Z", format.format( secondTestDate ) );
+ }
+
+ public void testDefaultBuildTimestampFormatWithLocalTimeZoneMidnightRollover()
+ {
+ Calendar cal = Calendar.getInstance();
+ cal.setTimeZone(TimeZone.getTimeZone("Europe/Berlin"));
+
+ cal.set( Calendar.HOUR_OF_DAY, 1 );
+ cal.set( Calendar.MINUTE, 16 );
+ cal.set( Calendar.SECOND, 0 );
+ cal.set( Calendar.YEAR, 2014 );
+ cal.set( Calendar.MONTH, Calendar.JUNE );
+ cal.set( Calendar.DATE, 16 );
+
+ Date firstTestDate = cal.getTime();
+
+ cal.set( Calendar.MONTH, Calendar.NOVEMBER );
+
+ Date secondTestDate = cal.getTime();
+
+ SimpleDateFormat format =
+ new SimpleDateFormat( MavenBuildTimestamp.DEFAULT_BUILD_TIMESTAMP_FORMAT );
+ format.setTimeZone(TimeZone.getTimeZone("UTC"));
+ assertEquals( "2014-06-15T23:16:00Z", format.format( firstTestDate ) );
+ assertEquals( "2014-11-16T00:16:00Z", format.format( secondTestDate ) );
+ }
+
+ public void testShouldNotThrowExceptionOnReferenceToNonExistentValue()
+ throws Exception
+ {
+ Model model = new Model();
+
+ Scm scm = new Scm();
+ scm.setConnection( "${test}/somepath" );
+
+ model.setScm( scm );
+
+ ModelInterpolator interpolator = createInterpolator();
+
+ final SimpleProblemCollector collector = new SimpleProblemCollector();
+ Model out =
+ interpolator.interpolateModel( model, new File( "." ), createModelBuildingRequest( context ), collector );
+
+ assertProblemFree( collector );
+ assertEquals( "${test}/somepath", out.getScm().getConnection() );
+ }
+
+ public void testShouldThrowExceptionOnRecursiveScmConnectionReference()
+ throws Exception
+ {
+ Model model = new Model();
+
+ Scm scm = new Scm();
+ scm.setConnection( "${project.scm.connection}/somepath" );
+
+ model.setScm( scm );
+
+ try
+ {
+ ModelInterpolator interpolator = createInterpolator();
+
+ final SimpleProblemCollector collector = new SimpleProblemCollector();
+ interpolator.interpolateModel( model, null, createModelBuildingRequest( context ), collector );
+ assertColllectorState( 0, 1, 0, collector );
+ }
+ catch ( Exception e )
+ {
+
+ }
+ }
+
+ public void testShouldNotThrowExceptionOnReferenceToValueContainingNakedExpression()
+ throws Exception
+ {
+ Model model = new Model();
+
+ Scm scm = new Scm();
+ scm.setConnection( "${test}/somepath" );
+
+ model.setScm( scm );
+
+ model.addProperty( "test", "test" );
+
+ ModelInterpolator interpolator = createInterpolator();
+
+ final SimpleProblemCollector collector = new SimpleProblemCollector();
+ Model out =
+ interpolator.interpolateModel( model, new File( "." ), createModelBuildingRequest( context ), collector );
+
+ assertProblemFree( collector );
+
+ assertEquals( "test/somepath", out.getScm().getConnection() );
+ }
+
+ public void testShouldInterpolateOrganizationNameCorrectly()
+ throws Exception
+ {
+ String orgName = "MyCo";
+
+ Model model = new Model();
+ model.setName( "${pom.organization.name} Tools" );
+
+ Organization org = new Organization();
+ org.setName( orgName );
+
+ model.setOrganization( org );
+
+ ModelInterpolator interpolator = createInterpolator();
+
+ Model out =
+ interpolator.interpolateModel( model, new File( "." ), createModelBuildingRequest( context ),
+ new SimpleProblemCollector() );
+
+ assertEquals( orgName + " Tools", out.getName() );
+ }
+
+ public void testShouldInterpolateDependencyVersionToSetSameAsProjectVersion()
+ throws Exception
+ {
+ Model model = new Model();
+ model.setVersion( "3.8.1" );
+
+ Dependency dep = new Dependency();
+ dep.setVersion( "${version}" );
+
+ model.addDependency( dep );
+
+ ModelInterpolator interpolator = createInterpolator();
+
+ final SimpleProblemCollector collector = new SimpleProblemCollector();
+ Model out =
+ interpolator.interpolateModel( model, new File( "." ), createModelBuildingRequest( context ), collector );
+ assertColllectorState(0, 0, 1, collector );
+
+ assertEquals( "3.8.1", ( out.getDependencies().get( 0 ) ).getVersion() );
+ }
+
+ public void testShouldNotInterpolateDependencyVersionWithInvalidReference()
+ throws Exception
+ {
+ Model model = new Model();
+ model.setVersion( "3.8.1" );
+
+ Dependency dep = new Dependency();
+ dep.setVersion( "${something}" );
+
+ model.addDependency( dep );
+
+ /*
+ // This is the desired behaviour, however there are too many crappy poms in the repo and an issue with the
+ // timing of executing the interpolation
+
+ try
+ {
+ new RegexBasedModelInterpolator().interpolate( model, context );
+ fail( "Should have failed to interpolate with invalid reference" );
+ }
+ catch ( ModelInterpolationException expected )
+ {
+ assertTrue( true );
+ }
+ */
+
+ ModelInterpolator interpolator = createInterpolator();
+
+ final SimpleProblemCollector collector = new SimpleProblemCollector();
+ Model out =
+ interpolator.interpolateModel( model, new File( "." ), createModelBuildingRequest( context ), collector );
+ assertProblemFree( collector );
+
+ assertEquals( "${something}", ( out.getDependencies().get( 0 ) ).getVersion() );
+ }
+
+ public void testTwoReferences()
+ throws Exception
+ {
+ Model model = new Model();
+ model.setVersion( "3.8.1" );
+ model.setArtifactId( "foo" );
+
+ Dependency dep = new Dependency();
+ dep.setVersion( "${artifactId}-${version}" );
+
+ model.addDependency( dep );
+
+ ModelInterpolator interpolator = createInterpolator();
+
+ final SimpleProblemCollector collector = new SimpleProblemCollector();
+ Model out =
+ interpolator.interpolateModel( model, new File( "." ), createModelBuildingRequest( context ), collector );
+ assertColllectorState( 0, 0, 2, collector );
+
+ assertEquals( "foo-3.8.1", ( out.getDependencies().get( 0 ) ).getVersion() );
+ }
+
+ public void testBasedir()
+ throws Exception
+ {
+ Model model = new Model();
+ model.setVersion( "3.8.1" );
+ model.setArtifactId( "foo" );
+
+ Repository repository = new Repository();
+
+ repository.setUrl( "file://localhost/${basedir}/temp-repo" );
+
+ model.addRepository( repository );
+
+ ModelInterpolator interpolator = createInterpolator();
+
+ final SimpleProblemCollector collector = new SimpleProblemCollector();
+ Model out = interpolator.interpolateModel( model, null, createModelBuildingRequest( context ), collector );
+ assertProblemFree( collector );
+
+ assertEquals( "file://localhost/myBasedir/temp-repo", ( out.getRepositories().get( 0 ) ).getUrl() );
+ }
+
+ public void testBaseUri()
+ throws Exception
+ {
+ Model model = new Model();
+ model.setVersion( "3.8.1" );
+ model.setArtifactId( "foo" );
+
+ Repository repository = new Repository();
+
+ repository.setUrl( "${project.baseUri}/temp-repo" );
+
+ model.addRepository( repository );
+
+ ModelInterpolator interpolator = createInterpolator();
+
+ final SimpleProblemCollector collector = new SimpleProblemCollector();
+ Model out = interpolator.interpolateModel( model, null, createModelBuildingRequest( context ), collector );
+ assertProblemFree( collector );
+
+ assertEquals( "myBaseUri/temp-repo", ( out.getRepositories().get( 0 ) ).getUrl() );
+ }
+
+ public void testEnvars()
+ throws Exception
+ {
+ Properties context = new Properties();
+
+ context.put( "env.HOME", "/path/to/home" );
+
+ Model model = new Model();
+
+ Properties modelProperties = new Properties();
+
+ modelProperties.setProperty( "outputDirectory", "${env.HOME}" );
+
+ model.setProperties( modelProperties );
+
+ ModelInterpolator interpolator = createInterpolator();
+
+ final SimpleProblemCollector collector = new SimpleProblemCollector();
+ Model out =
+ interpolator.interpolateModel( model, new File( "." ), createModelBuildingRequest( context ), collector );
+ assertProblemFree( collector );
+
+ assertEquals( "/path/to/home", out.getProperties().getProperty( "outputDirectory" ) );
+ }
+
+ public void testEnvarExpressionThatEvaluatesToNullReturnsTheLiteralString()
+ throws Exception
+ {
+ Model model = new Model();
+
+ Properties modelProperties = new Properties();
+
+ modelProperties.setProperty( "outputDirectory", "${env.DOES_NOT_EXIST}" );
+
+ model.setProperties( modelProperties );
+
+ ModelInterpolator interpolator = createInterpolator();
+
+ final SimpleProblemCollector collector = new SimpleProblemCollector();
+ Model out =
+ interpolator.interpolateModel( model, new File( "." ), createModelBuildingRequest( context ), collector );
+ assertProblemFree( collector );
+
+ assertEquals( out.getProperties().getProperty( "outputDirectory" ), "${env.DOES_NOT_EXIST}" );
+ }
+
+ public void testExpressionThatEvaluatesToNullReturnsTheLiteralString()
+ throws Exception
+ {
+ Model model = new Model();
+
+ Properties modelProperties = new Properties();
+
+ modelProperties.setProperty( "outputDirectory", "${DOES_NOT_EXIST}" );
+
+ model.setProperties( modelProperties );
+
+ ModelInterpolator interpolator = createInterpolator();
+
+ final SimpleProblemCollector collector = new SimpleProblemCollector();
+ Model out =
+ interpolator.interpolateModel( model, new File( "." ), createModelBuildingRequest( context ), collector );
+ assertProblemFree( collector );
+
+ assertEquals( out.getProperties().getProperty( "outputDirectory" ), "${DOES_NOT_EXIST}" );
+ }
+
+ public void testShouldInterpolateSourceDirectoryReferencedFromResourceDirectoryCorrectly()
+ throws Exception
+ {
+ Model model = new Model();
+
+ Build build = new Build();
+ build.setSourceDirectory( "correct" );
+
+ Resource res = new Resource();
+ res.setDirectory( "${project.build.sourceDirectory}" );
+
+ build.addResource( res );
+
+ Resource res2 = new Resource();
+ res2.setDirectory( "${pom.build.sourceDirectory}" );
+
+ build.addResource( res2 );
+
+ Resource res3 = new Resource();
+ res3.setDirectory( "${build.sourceDirectory}" );
+
+ build.addResource( res3 );
+
+ model.setBuild( build );
+
+ ModelInterpolator interpolator = createInterpolator();
+
+ final SimpleProblemCollector collector = new SimpleProblemCollector();
+ Model out = interpolator.interpolateModel( model, null, createModelBuildingRequest( context ), collector );
+ assertColllectorState( 0, 0, 2, collector );
+
+
+ List<Resource> outResources = out.getBuild().getResources();
+ Iterator<Resource> resIt = outResources.iterator();
+
+ assertEquals( build.getSourceDirectory(), resIt.next().getDirectory() );
+ assertEquals( build.getSourceDirectory(), resIt.next().getDirectory() );
+ assertEquals( build.getSourceDirectory(), resIt.next().getDirectory() );
+ }
+
+ public void testShouldInterpolateUnprefixedBasedirExpression()
+ throws Exception
+ {
+ File basedir = new File( "/test/path" );
+ Model model = new Model();
+ Dependency dep = new Dependency();
+ dep.setSystemPath( "${basedir}/artifact.jar" );
+
+ model.addDependency( dep );
+
+ ModelInterpolator interpolator = createInterpolator();
+
+ final SimpleProblemCollector collector = new SimpleProblemCollector();
+ Model result = interpolator.interpolateModel( model, basedir, createModelBuildingRequest( context ), collector );
+ assertProblemFree( collector );
+
+
+ List<Dependency> rDeps = result.getDependencies();
+ assertNotNull( rDeps );
+ assertEquals( 1, rDeps.size() );
+ assertEquals( new File( basedir, "artifact.jar" ).getAbsolutePath(),
+ new File( rDeps.get( 0 ).getSystemPath() ).getAbsolutePath() );
+ }
+
+ protected abstract ModelInterpolator createInterpolator( PathTranslator translator )
+ throws Exception;
+
+ protected abstract ModelInterpolator createInterpolator()
+ throws Exception;
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/java/org/apache/maven/model/interpolation/MavenBuildTimestampTest.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/java/org/apache/maven/model/interpolation/MavenBuildTimestampTest.java
new file mode 100644
index 00000000..8af32fc5
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/java/org/apache/maven/model/interpolation/MavenBuildTimestampTest.java
@@ -0,0 +1,38 @@
+package org.apache.maven.model.interpolation;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Date;
+import java.util.Properties;
+
+import junit.framework.TestCase;
+
+public class MavenBuildTimestampTest
+ extends TestCase
+{
+ public void testMavenBuildTimestampUsesUTC()
+ {
+ Properties interpolationProperties = new Properties();
+ interpolationProperties.setProperty( "maven.build.timestamp.format", "yyyyMMdd'T'HHmm'Z'" );
+ MavenBuildTimestamp timestamp = new MavenBuildTimestamp( new Date(), interpolationProperties );
+ String formattedTimestamp = timestamp.formattedTimestamp();
+ assertTrue( "We expect the UTC marker at the end of the timestamp.", formattedTimestamp.endsWith( "Z" ) );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/java/org/apache/maven/model/interpolation/StringSearchModelInterpolatorTest.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/java/org/apache/maven/model/interpolation/StringSearchModelInterpolatorTest.java
new file mode 100644
index 00000000..c4cae3d4
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/java/org/apache/maven/model/interpolation/StringSearchModelInterpolatorTest.java
@@ -0,0 +1,505 @@
+package org.apache.maven.model.interpolation;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.model.InputLocation;
+import org.apache.maven.model.InputSource;
+import org.apache.maven.model.Model;
+import org.apache.maven.model.building.DefaultModelBuildingRequest;
+import org.apache.maven.model.building.ModelBuildingRequest;
+import org.apache.maven.model.building.SimpleProblemCollector;
+
+import java.io.File;
+import java.util.*;
+import java.util.concurrent.Callable;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Future;
+import java.util.concurrent.FutureTask;
+
+/**
+ * @author jdcasey
+ * @author Benjamin Bentmann
+ */
+public class StringSearchModelInterpolatorTest
+ extends AbstractModelInterpolatorTest
+{
+
+ protected ModelInterpolator interpolator;
+
+ @Override
+ protected void setUp()
+ throws Exception
+ {
+ super.setUp();
+ interpolator = lookup( ModelInterpolator.class );
+ }
+
+
+ protected ModelInterpolator createInterpolator( org.apache.maven.model.path.PathTranslator translator )
+ throws Exception
+ {
+ return this.interpolator;
+ }
+
+ protected ModelInterpolator createInterpolator()
+ throws Exception
+ {
+ return this.interpolator;
+ }
+
+ public void testInterpolateStringArray()
+ throws Exception
+ {
+ Model model = new Model();
+
+ Properties p = new Properties();
+ p.setProperty( "key", "value" );
+ p.setProperty( "key2", "value2" );
+
+ String[] values = { "${key}", "${key2}" };
+
+ StringSearchModelInterpolator interpolator = (StringSearchModelInterpolator) createInterpolator();
+
+ ModelBuildingRequest config = createModelBuildingRequest(p);
+
+ final SimpleProblemCollector collector = new SimpleProblemCollector();
+ interpolator.interpolateObject( values, model, new File( "." ), config, collector );
+ assertProblemFree( collector );
+
+ assertEquals( "value", values[0] );
+ assertEquals( "value2", values[1] );
+ }
+
+ private ModelBuildingRequest createModelBuildingRequest( Properties p )
+ {
+ ModelBuildingRequest config = new DefaultModelBuildingRequest();
+ config.setSystemProperties( p );
+ return config;
+ }
+
+ public void testInterpolateObjectWithStringArrayField()
+ throws Exception
+ {
+ Model model = new Model();
+
+ Properties p = new Properties();
+ p.setProperty( "key", "value" );
+ p.setProperty( "key2", "value2" );
+
+ String[] values = { "${key}", "${key2}" };
+
+ ObjectWithStringArrayField obj = new ObjectWithStringArrayField( values );
+
+ StringSearchModelInterpolator interpolator = (StringSearchModelInterpolator) createInterpolator();
+
+ ModelBuildingRequest config = createModelBuildingRequest( p );
+
+ final SimpleProblemCollector collector = new SimpleProblemCollector();
+ interpolator.interpolateObject( obj, model, new File( "." ), config, collector );
+ assertProblemFree( collector );
+
+ assertEquals( "value", obj.values[0] );
+ assertEquals( "value2", obj.values[1] );
+ }
+
+ public void testInterpolateObjectWithStringListField()
+ throws Exception
+ {
+ Model model = new Model();
+
+ Properties p = new Properties();
+ p.setProperty( "key", "value" );
+ p.setProperty( "key2", "value2" );
+
+ List<String> values = new ArrayList<String>();
+ values.add( "${key}" );
+ values.add( "${key2}" );
+
+ ObjectWithListField obj = new ObjectWithListField( values );
+
+ StringSearchModelInterpolator interpolator = (StringSearchModelInterpolator) createInterpolator();
+
+ ModelBuildingRequest config = createModelBuildingRequest( p );
+
+ final SimpleProblemCollector collector = new SimpleProblemCollector();
+ interpolator.interpolateObject( obj, model, new File( "." ), config, collector );
+ assertProblemFree( collector );
+
+ assertEquals( "value", obj.values.get( 0 ) );
+ assertEquals( "value2", obj.values.get( 1 ) );
+ }
+
+ public void testInterpolateObjectWithStringListFieldAndOneLiteralValue()
+ throws Exception
+ {
+ Model model = new Model();
+
+ Properties p = new Properties();
+ p.setProperty( "key", "value" );
+ p.setProperty( "key2", "value2" );
+
+ List<String> values = new ArrayList<String>();
+ values.add( "key" );
+ values.add( "${key2}" );
+
+ ObjectWithListField obj = new ObjectWithListField( values );
+
+ StringSearchModelInterpolator interpolator = (StringSearchModelInterpolator) createInterpolator();
+
+ ModelBuildingRequest config = createModelBuildingRequest( p );
+
+ final SimpleProblemCollector collector = new SimpleProblemCollector();
+ interpolator.interpolateObject( obj, model, new File( "." ), config, collector );
+ assertProblemFree( collector );
+
+ assertEquals( "key", obj.values.get( 0 ) );
+ assertEquals( "value2", obj.values.get( 1 ) );
+ }
+
+ public void testInterpolateObjectWithUnmodifiableStringListField()
+ throws Exception
+ {
+ Model model = new Model();
+
+ Properties p = new Properties();
+ p.setProperty( "key", "value" );
+ p.setProperty( "key2", "value2" );
+
+ List<String> values = Collections.unmodifiableList( Collections.singletonList( "${key}" ) );
+
+ ObjectWithListField obj = new ObjectWithListField( values );
+
+ StringSearchModelInterpolator interpolator = (StringSearchModelInterpolator) createInterpolator();
+
+ ModelBuildingRequest config = createModelBuildingRequest( p );
+
+ final SimpleProblemCollector collector = new SimpleProblemCollector();
+ interpolator.interpolateObject( obj, model, new File( "." ), config, collector );
+ assertProblemFree( collector );
+
+ assertEquals( "${key}", obj.values.get( 0 ) );
+ }
+
+ public void testInterpolateObjectWithStringArrayListField()
+ throws Exception
+ {
+ Model model = new Model();
+
+ Properties p = new Properties();
+ p.setProperty( "key", "value" );
+ p.setProperty( "key2", "value2" );
+ p.setProperty( "key3", "value3" );
+ p.setProperty( "key4", "value4" );
+
+ List<String[]> values = new ArrayList<String[]>();
+ values.add( new String[] { "${key}", "${key2}" } );
+ values.add( new String[] { "${key3}", "${key4}" } );
+
+ ObjectWithListField obj = new ObjectWithListField( values );
+
+ StringSearchModelInterpolator interpolator = (StringSearchModelInterpolator) createInterpolator();
+
+ ModelBuildingRequest config = createModelBuildingRequest( p );
+
+ final SimpleProblemCollector collector = new SimpleProblemCollector();
+ interpolator.interpolateObject( obj, model, new File( "." ), config, collector );
+ assertProblemFree( collector );
+
+ assertEquals( "value", ( (String[]) obj.values.get( 0 ) )[0] );
+ assertEquals( "value2", ( (String[]) obj.values.get( 0 ) )[1] );
+ assertEquals( "value3", ( (String[]) obj.values.get( 1 ) )[0] );
+ assertEquals( "value4", ( (String[]) obj.values.get( 1 ) )[1] );
+ }
+
+ public void testInterpolateObjectWithStringToStringMapField()
+ throws Exception
+ {
+ Model model = new Model();
+
+ Properties p = new Properties();
+ p.setProperty( "key", "value" );
+ p.setProperty( "key2", "value2" );
+
+ Map<String, String> values = new HashMap<String, String>();
+ values.put( "key", "${key}" );
+ values.put( "key2", "${key2}" );
+
+ ObjectWithMapField obj = new ObjectWithMapField( values );
+
+ StringSearchModelInterpolator interpolator = (StringSearchModelInterpolator) createInterpolator();
+
+ ModelBuildingRequest config = createModelBuildingRequest( p );
+
+ final SimpleProblemCollector collector = new SimpleProblemCollector();
+ interpolator.interpolateObject( obj, model, new File( "." ), config, collector );
+ assertProblemFree( collector );
+
+ assertEquals( "value", obj.values.get( "key" ) );
+ assertEquals( "value2", obj.values.get( "key2" ) );
+ }
+
+ public void testInterpolateObjectWithStringToStringMapFieldAndOneLiteralValue()
+ throws Exception
+ {
+ Model model = new Model();
+
+ Properties p = new Properties();
+ p.setProperty( "key", "value" );
+ p.setProperty( "key2", "value2" );
+
+ Map<String, String> values = new HashMap<String, String>();
+ values.put( "key", "val" );
+ values.put( "key2", "${key2}" );
+
+ ObjectWithMapField obj = new ObjectWithMapField( values );
+
+ StringSearchModelInterpolator interpolator = (StringSearchModelInterpolator) createInterpolator();
+
+ ModelBuildingRequest config = createModelBuildingRequest( p );
+
+ final SimpleProblemCollector collector = new SimpleProblemCollector();
+ interpolator.interpolateObject( obj, model, new File( "." ), config, collector );
+ assertProblemFree( collector );
+
+ assertEquals( "val", obj.values.get( "key" ) );
+ assertEquals( "value2", obj.values.get( "key2" ) );
+ }
+
+ public void testInterpolateObjectWithUnmodifiableStringToStringMapField()
+ throws Exception
+ {
+ Model model = new Model();
+
+ Properties p = new Properties();
+ p.setProperty( "key", "value" );
+ p.setProperty( "key2", "value2" );
+
+ Map<String, String> values = Collections.unmodifiableMap( Collections.singletonMap( "key", "${key}" ) );
+
+ ObjectWithMapField obj = new ObjectWithMapField( values );
+
+ StringSearchModelInterpolator interpolator = (StringSearchModelInterpolator) createInterpolator();
+
+ ModelBuildingRequest config = createModelBuildingRequest( p );
+
+ final SimpleProblemCollector collector = new SimpleProblemCollector();
+ interpolator.interpolateObject( obj, model, new File( "." ), config, collector );
+ assertProblemFree( collector );
+
+ assertEquals( "${key}", obj.values.get( "key" ) );
+ }
+
+ public void testInterpolateObjectWithStringToStringArrayMapField()
+ throws Exception
+ {
+ Model model = new Model();
+
+ Properties p = new Properties();
+ p.setProperty( "key", "value" );
+ p.setProperty( "key2", "value2" );
+ p.setProperty( "key3", "value3" );
+ p.setProperty( "key4", "value4" );
+
+ Map<String, String[]> values = new HashMap<String, String[]>();
+ values.put( "key", new String[] { "${key}", "${key2}" } );
+ values.put( "key2", new String[] { "${key3}", "${key4}" } );
+
+ ObjectWithMapField obj = new ObjectWithMapField( values );
+
+ StringSearchModelInterpolator interpolator = (StringSearchModelInterpolator) createInterpolator();
+
+ ModelBuildingRequest config = createModelBuildingRequest( p );
+
+ final SimpleProblemCollector collector = new SimpleProblemCollector();
+ interpolator.interpolateObject( obj, model, new File( "." ), config, collector );
+ assertProblemFree( collector );
+
+ assertEquals( "value", ( (String[]) obj.values.get( "key" ) )[0] );
+ assertEquals( "value2", ( (String[]) obj.values.get( "key" ) )[1] );
+ assertEquals( "value3", ( (String[]) obj.values.get( "key2" ) )[0] );
+ assertEquals( "value4", ( (String[]) obj.values.get( "key2" ) )[1] );
+ }
+
+
+ public void testConcurrentInterpolation()
+ throws Exception
+ {
+ final Model model = new Model();
+
+ final Properties p = new Properties();
+ p.setProperty( "key", "value" );
+ p.setProperty( "key2", "value2" );
+ p.setProperty( "key3", "value3" );
+ p.setProperty( "key4", "value4" );
+ p.setProperty( "key5", "value5" );
+
+ final StringSearchModelInterpolator interpolator = (StringSearchModelInterpolator) createInterpolator();
+
+
+ int numItems = 100;
+ final CountDownLatch countDownLatch = new CountDownLatch(1);
+
+ List<Future<SimpleProblemCollector>> futures = new ArrayList<Future<SimpleProblemCollector>>();
+ for ( int i = 0; i < numItems; i++ )
+ {
+ Callable<SimpleProblemCollector> future = new Callable<SimpleProblemCollector>()
+ {
+ public SimpleProblemCollector call()
+ throws Exception
+ {
+ final ObjectWithMixedProtection obj = getValueList();
+ final ModelBuildingRequest config = createModelBuildingRequest( p );
+
+ countDownLatch.await();
+ final SimpleProblemCollector collector = new SimpleProblemCollector();
+ interpolator.interpolateObject( obj, model, new File( "." ), config, collector );
+ return collector;
+ }
+ };
+ FutureTask<SimpleProblemCollector> task = new FutureTask<SimpleProblemCollector>( future );
+ futures.add( task );
+ new Thread( task ).start();
+ }
+ countDownLatch.countDown(); // Start all the threads
+ for ( Future<SimpleProblemCollector> result : futures )
+ {
+ SimpleProblemCollector problemCollector = result.get(); // ArrayIndexOutOfBoundsException are typical indication of threading issues
+ assertProblemFree( problemCollector );
+ }
+ }
+
+ private ObjectWithMixedProtection getValueList()
+ {
+ List<String[]> values = new ArrayList<String[]>();
+
+ values.add( new String[] { "${key}", "${key2}" } );
+ values.add( new String[] { "${key3}", "${key4}" } );
+ List<String> values2 = new ArrayList<String>();
+ values.add( new String[] { "${key}", "${key2}" } );
+ values.add( new String[] { "${key3}", "${key4}" } );
+ List<String> values3 = new ArrayList<String>();
+ values.add( new String[] { "${key}", "${key2}" } );
+ values.add( new String[] { "${key3}", "${key4}" } );
+
+ return new ObjectWithMixedProtection( values, values2, values3, "${key5}" );
+ }
+
+
+ private static final class ObjectWithStringArrayField
+ {
+ private final String[] values;
+
+ public ObjectWithStringArrayField( String[] values )
+ {
+ this.values = values;
+ }
+ }
+
+ private static final class ObjectWithListField
+ {
+ private final List<?> values;
+
+ public ObjectWithListField( List<?> values )
+ {
+ this.values = values;
+ }
+ }
+
+ private static final class ObjectWithMapField
+ {
+ private final Map<?, ?> values;
+
+ public ObjectWithMapField( Map<?, ?> values )
+ {
+ this.values = values;
+ }
+ }
+
+ @SuppressWarnings( "unused" )
+ private static final class ObjectWithMixedProtection
+ {
+ private List<?> values1;
+ protected List<?> values2;
+ List<?> values3;
+ private String fooBar;
+
+ private ObjectWithMixedProtection( List<?> values1, List<?> values2, List<?> values3 )
+ {
+ this.values1 = values1;
+ this.values2 = values2;
+ this.values3 = values3;
+ }
+
+ private ObjectWithMixedProtection( List<?> values1, List<?> values2, List<?> values3, String fooBar )
+ {
+ this.values1 = values1;
+ this.values2 = values2;
+ this.values3 = values3;
+ this.fooBar = fooBar;
+ }
+
+ public String getFooBar()
+ {
+ return fooBar;
+ }
+ }
+
+ public void testFinalFieldsExcludedFromInterpolation()
+ {
+ Properties props = new Properties();
+ props.setProperty( "expression", "value" );
+ DefaultModelBuildingRequest request = new DefaultModelBuildingRequest();
+ request.setUserProperties( props );
+
+ SimpleProblemCollector problems = new SimpleProblemCollector();
+ StringSearchModelInterpolator interpolator = new StringSearchModelInterpolator();
+ interpolator.interpolateObject( new ClassWithFinalField(), new Model(), null, request, problems );
+
+ assertProblemFree( problems );
+ }
+
+ static class ClassWithFinalField
+ {
+ public static final String CONSTANT = "${expression}";
+ }
+
+ public void testLocationTrackerShouldBeExcludedFromInterpolation()
+ {
+ Properties props = new Properties();
+ props.setProperty( "expression", "value" );
+ DefaultModelBuildingRequest request = new DefaultModelBuildingRequest();
+ request.setUserProperties( props );
+
+ InputSource source = new InputSource();
+ source.setLocation( "${expression}" );
+ source.setModelId( "${expression}" );
+ Model model = new Model();
+ model.setLocation( "", new InputLocation( 1, 1, source ) );
+
+ SimpleProblemCollector problems = new SimpleProblemCollector();
+ StringSearchModelInterpolator interpolator = new StringSearchModelInterpolator();
+ interpolator.interpolateObject( model, model, null, request, problems );
+
+ assertProblemFree( problems );
+ assertEquals( "${expression}", source.getLocation() );
+ assertEquals( "${expression}", source.getModelId() );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/java/org/apache/maven/model/path/DefaultUrlNormalizerTest.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/java/org/apache/maven/model/path/DefaultUrlNormalizerTest.java
new file mode 100644
index 00000000..88fdc9cf
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/java/org/apache/maven/model/path/DefaultUrlNormalizerTest.java
@@ -0,0 +1,85 @@
+package org.apache.maven.model.path;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import junit.framework.TestCase;
+
+/**
+ * @author Benjamin Bentmann
+ */
+public class DefaultUrlNormalizerTest
+ extends TestCase
+{
+
+ private UrlNormalizer normalizer;
+
+ @Override
+ protected void setUp()
+ throws Exception
+ {
+ super.setUp();
+
+ normalizer = new DefaultUrlNormalizer();
+ }
+
+ @Override
+ protected void tearDown()
+ throws Exception
+ {
+ normalizer = null;
+
+ super.tearDown();
+ }
+
+ private String normalize( String url )
+ {
+ return normalizer.normalize( url );
+ }
+
+ public void testNullSafe()
+ {
+ assertNull( normalize( null ) );
+ }
+
+ public void testTrailingSlash()
+ {
+ assertEquals( "", normalize( "" ) );
+ assertEquals( "http://server.org/dir", normalize( "http://server.org/dir" ) );
+ assertEquals( "http://server.org/dir/", normalize( "http://server.org/dir/" ) );
+ }
+
+ public void testRemovalOfParentRefs()
+ {
+ assertEquals( "http://server.org/child", normalize( "http://server.org/parent/../child" ) );
+ assertEquals( "http://server.org/child", normalize( "http://server.org/grand/parent/../../child" ) );
+
+ assertEquals( "http://server.org//child", normalize( "http://server.org/parent/..//child" ) );
+ assertEquals( "http://server.org/child", normalize( "http://server.org/parent//../child" ) );
+ }
+
+ public void testPreservationOfDoubleSlashes()
+ {
+ assertEquals( "scm:hg:ssh://localhost//home/user", normalize( "scm:hg:ssh://localhost//home/user" ) );
+ assertEquals( "file:////UNC/server", normalize( "file:////UNC/server" ) );
+ assertEquals( "[fetch=]http://server.org/[push=]ssh://server.org/",
+ normalize( "[fetch=]http://server.org/[push=]ssh://server.org/" ) );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/java/org/apache/maven/model/profile/activation/AbstractProfileActivatorTest.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/java/org/apache/maven/model/profile/activation/AbstractProfileActivatorTest.java
new file mode 100644
index 00000000..0ec3b326
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/java/org/apache/maven/model/profile/activation/AbstractProfileActivatorTest.java
@@ -0,0 +1,92 @@
+package org.apache.maven.model.profile.activation;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Properties;
+
+import org.apache.maven.model.Profile;
+import org.apache.maven.model.building.SimpleProblemCollector;
+import org.apache.maven.model.profile.DefaultProfileActivationContext;
+import org.apache.maven.model.profile.ProfileActivationContext;
+import org.codehaus.plexus.PlexusTestCase;
+import org.codehaus.plexus.component.annotations.Component;
+
+/**
+ * Provides common services to test {@link ProfileActivator} implementations.
+ *
+ * @author Benjamin Bentmann
+ */
+public abstract class AbstractProfileActivatorTest<T extends ProfileActivator>
+ extends PlexusTestCase
+{
+
+ private Class<T> activatorClass;
+
+ private String roleHint;
+
+ protected T activator;
+
+ public AbstractProfileActivatorTest( Class<T> activatorClass )
+ {
+ if ( activatorClass == null )
+ {
+ throw new IllegalArgumentException( "class of profile activator to test is not specified" );
+ }
+
+ this.activatorClass = activatorClass;
+
+ roleHint = activatorClass.getAnnotation( Component.class ).hint();
+ }
+
+ @Override
+ protected void setUp()
+ throws Exception
+ {
+ super.setUp();
+
+ activator = activatorClass.cast( lookup( ProfileActivator.class, roleHint ) );
+ }
+
+ @Override
+ protected void tearDown()
+ throws Exception
+ {
+ activator = null;
+
+ super.tearDown();
+ }
+
+ protected ProfileActivationContext newContext( final Properties userProperties, final Properties systemProperties )
+ {
+ DefaultProfileActivationContext context = new DefaultProfileActivationContext();
+ return context.setUserProperties( userProperties ).setSystemProperties( systemProperties );
+ }
+
+ protected void assertActivation( boolean active, Profile profile, ProfileActivationContext context )
+ {
+ SimpleProblemCollector problems = new SimpleProblemCollector();
+
+ assertEquals( active, activator.isActive( profile, context, problems ) );
+
+ assertEquals( problems.getErrors().toString(), 0, problems.getErrors().size() );
+ assertEquals( problems.getWarnings().toString(), 0, problems.getWarnings().size() );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/java/org/apache/maven/model/profile/activation/JdkVersionProfileActivatorTest.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/java/org/apache/maven/model/profile/activation/JdkVersionProfileActivatorTest.java
new file mode 100644
index 00000000..440f120b
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/java/org/apache/maven/model/profile/activation/JdkVersionProfileActivatorTest.java
@@ -0,0 +1,185 @@
+package org.apache.maven.model.profile.activation;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Properties;
+
+import org.apache.maven.model.Activation;
+import org.apache.maven.model.Profile;
+
+/**
+ * Tests {@link JdkVersionProfileActivator}.
+ *
+ * @author Benjamin Bentmann
+ */
+public class JdkVersionProfileActivatorTest
+ extends AbstractProfileActivatorTest<JdkVersionProfileActivator>
+{
+
+ public JdkVersionProfileActivatorTest()
+ {
+ super( JdkVersionProfileActivator.class );
+ }
+
+ private Profile newProfile( String jdkVersion )
+ {
+ Activation a = new Activation();
+ a.setJdk( jdkVersion );
+
+ Profile p = new Profile();
+ p.setActivation( a );
+
+ return p;
+ }
+
+ private Properties newProperties( String javaVersion )
+ {
+ Properties props = new Properties();
+ props.setProperty( "java.version", javaVersion );
+ return props;
+ }
+
+ public void testNullSafe()
+ throws Exception
+ {
+ Profile p = new Profile();
+
+ assertActivation( false, p, newContext( null, null ) );
+
+ p.setActivation( new Activation() );
+
+ assertActivation( false, p, newContext( null, null ) );
+ }
+
+ public void testPrefix()
+ throws Exception
+ {
+ Profile profile = newProfile( "1.4" );
+
+ assertActivation( true, profile, newContext( null, newProperties( "1.4" ) ) );
+ assertActivation( true, profile, newContext( null, newProperties( "1.4.2" ) ) );
+ assertActivation( true, profile, newContext( null, newProperties( "1.4.2_09" ) ) );
+ assertActivation( true, profile, newContext( null, newProperties( "1.4.2_09-b03" ) ) );
+
+ assertActivation( false, profile, newContext( null, newProperties( "1.3" ) ) );
+
+ assertActivation( false, profile, newContext( null, newProperties( "1.5" ) ) );
+ }
+
+ public void testPrefixNegated()
+ throws Exception
+ {
+ Profile profile = newProfile( "!1.4" );
+
+ assertActivation( false, profile, newContext( null, newProperties( "1.4" ) ) );
+ assertActivation( false, profile, newContext( null, newProperties( "1.4.2" ) ) );
+ assertActivation( false, profile, newContext( null, newProperties( "1.4.2_09" ) ) );
+ assertActivation( false, profile, newContext( null, newProperties( "1.4.2_09-b03" ) ) );
+
+ assertActivation( true, profile, newContext( null, newProperties( "1.3" ) ) );
+
+ assertActivation( true, profile, newContext( null, newProperties( "1.5" ) ) );
+ }
+
+ public void testVersionRangeInclusiveBounds()
+ throws Exception
+ {
+ Profile profile = newProfile( "[1.5,1.6]" );
+
+ assertActivation( false, profile, newContext( null, newProperties( "1.4" ) ) );
+ assertActivation( false, profile, newContext( null, newProperties( "1.4.2" ) ) );
+ assertActivation( false, profile, newContext( null, newProperties( "1.4.2_09" ) ) );
+ assertActivation( false, profile, newContext( null, newProperties( "1.4.2_09-b03" ) ) );
+
+ assertActivation( true, profile, newContext( null, newProperties( "1.5" ) ) );
+ assertActivation( true, profile, newContext( null, newProperties( "1.5.0" ) ) );
+ assertActivation( true, profile, newContext( null, newProperties( "1.5.0_09" ) ) );
+ assertActivation( true, profile, newContext( null, newProperties( "1.5.0_09-b03" ) ) );
+ assertActivation( true, profile, newContext( null, newProperties( "1.5.1" ) ) );
+
+ assertActivation( true, profile, newContext( null, newProperties( "1.6" ) ) );
+ assertActivation( true, profile, newContext( null, newProperties( "1.6.0" ) ) );
+ assertActivation( true, profile, newContext( null, newProperties( "1.6.0_09" ) ) );
+ assertActivation( true, profile, newContext( null, newProperties( "1.6.0_09-b03" ) ) );
+ }
+
+ public void testVersionRangeExclusiveBounds()
+ throws Exception
+ {
+ Profile profile = newProfile( "(1.3,1.6)" );
+
+ assertActivation( false, profile, newContext( null, newProperties( "1.3" ) ) );
+ assertActivation( false, profile, newContext( null, newProperties( "1.3.0" ) ) );
+ assertActivation( false, profile, newContext( null, newProperties( "1.3.0_09" ) ) );
+ assertActivation( false, profile, newContext( null, newProperties( "1.3.0_09-b03" ) ) );
+
+ assertActivation( true, profile, newContext( null, newProperties( "1.3.1" ) ) );
+ assertActivation( true, profile, newContext( null, newProperties( "1.3.1_09" ) ) );
+ assertActivation( true, profile, newContext( null, newProperties( "1.3.1_09-b03" ) ) );
+
+ assertActivation( true, profile, newContext( null, newProperties( "1.5" ) ) );
+ assertActivation( true, profile, newContext( null, newProperties( "1.5.0" ) ) );
+ assertActivation( true, profile, newContext( null, newProperties( "1.5.0_09" ) ) );
+ assertActivation( true, profile, newContext( null, newProperties( "1.5.0_09-b03" ) ) );
+ assertActivation( true, profile, newContext( null, newProperties( "1.5.1" ) ) );
+
+ assertActivation( false, profile, newContext( null, newProperties( "1.6" ) ) );
+ }
+
+ public void testVersionRangeInclusiveLowerBound()
+ throws Exception
+ {
+ Profile profile = newProfile( "[1.5,)" );
+
+ assertActivation( false, profile, newContext( null, newProperties( "1.4" ) ) );
+ assertActivation( false, profile, newContext( null, newProperties( "1.4.2" ) ) );
+ assertActivation( false, profile, newContext( null, newProperties( "1.4.2_09" ) ) );
+ assertActivation( false, profile, newContext( null, newProperties( "1.4.2_09-b03" ) ) );
+
+ assertActivation( true, profile, newContext( null, newProperties( "1.5" ) ) );
+ assertActivation( true, profile, newContext( null, newProperties( "1.5.0" ) ) );
+ assertActivation( true, profile, newContext( null, newProperties( "1.5.0_09" ) ) );
+ assertActivation( true, profile, newContext( null, newProperties( "1.5.0_09-b03" ) ) );
+ assertActivation( true, profile, newContext( null, newProperties( "1.5.1" ) ) );
+
+ assertActivation( true, profile, newContext( null, newProperties( "1.6" ) ) );
+ assertActivation( true, profile, newContext( null, newProperties( "1.6.0" ) ) );
+ assertActivation( true, profile, newContext( null, newProperties( "1.6.0_09" ) ) );
+ assertActivation( true, profile, newContext( null, newProperties( "1.6.0_09-b03" ) ) );
+ }
+
+ public void testVersionRangeExclusiveUpperBound()
+ throws Exception
+ {
+ Profile profile = newProfile( "(,1.6)" );
+
+ assertActivation( true, profile, newContext( null, newProperties( "1.5" ) ) );
+ assertActivation( true, profile, newContext( null, newProperties( "1.5.0" ) ) );
+ assertActivation( true, profile, newContext( null, newProperties( "1.5.0_09" ) ) );
+ assertActivation( true, profile, newContext( null, newProperties( "1.5.0_09-b03" ) ) );
+ assertActivation( true, profile, newContext( null, newProperties( "1.5.1" ) ) );
+
+ assertActivation( false, profile, newContext( null, newProperties( "1.6" ) ) );
+ assertActivation( false, profile, newContext( null, newProperties( "1.6.0" ) ) );
+ assertActivation( false, profile, newContext( null, newProperties( "1.6.0_09" ) ) );
+ assertActivation( false, profile, newContext( null, newProperties( "1.6.0_09-b03" ) ) );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/java/org/apache/maven/model/profile/activation/PropertyProfileActivatorTest.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/java/org/apache/maven/model/profile/activation/PropertyProfileActivatorTest.java
new file mode 100644
index 00000000..73ab967e
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/java/org/apache/maven/model/profile/activation/PropertyProfileActivatorTest.java
@@ -0,0 +1,185 @@
+package org.apache.maven.model.profile.activation;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Properties;
+
+import org.apache.maven.model.Activation;
+import org.apache.maven.model.ActivationProperty;
+import org.apache.maven.model.Profile;
+
+/**
+ * Tests {@link PropertyProfileActivator}.
+ *
+ * @author Benjamin Bentmann
+ */
+public class PropertyProfileActivatorTest
+ extends AbstractProfileActivatorTest<PropertyProfileActivator>
+{
+
+ public PropertyProfileActivatorTest()
+ {
+ super( PropertyProfileActivator.class );
+ }
+
+ private Profile newProfile( String key, String value )
+ {
+ ActivationProperty ap = new ActivationProperty();
+ ap.setName( key );
+ ap.setValue( value );
+
+ Activation a = new Activation();
+ a.setProperty( ap );
+
+ Profile p = new Profile();
+ p.setActivation( a );
+
+ return p;
+ }
+
+ private Properties newProperties( String key, String value )
+ {
+ Properties props = new Properties();
+ props.setProperty( key, value );
+ return props;
+ }
+
+ public void testNullSafe()
+ throws Exception
+ {
+ Profile p = new Profile();
+
+ assertActivation( false, p, newContext( null, null ) );
+
+ p.setActivation( new Activation() );
+
+ assertActivation( false, p, newContext( null, null ) );
+ }
+
+ public void testWithNameOnly_UserProperty()
+ throws Exception
+ {
+ Profile profile = newProfile( "prop", null );
+
+ assertActivation( true, profile, newContext( newProperties( "prop", "value" ), null ) );
+
+ assertActivation( false, profile, newContext( newProperties( "prop", "" ), null ) );
+
+ assertActivation( false, profile, newContext( newProperties( "other", "value" ), null ) );
+ }
+
+ public void testWithNameOnly_SystemProperty()
+ throws Exception
+ {
+ Profile profile = newProfile( "prop", null );
+
+ assertActivation( true, profile, newContext( null, newProperties( "prop", "value" ) ) );
+
+ assertActivation( false, profile, newContext( null, newProperties( "prop", "" ) ) );
+
+ assertActivation( false, profile, newContext( null, newProperties( "other", "value" ) ) );
+ }
+
+ public void testWithNegatedNameOnly_UserProperty()
+ throws Exception
+ {
+ Profile profile = newProfile( "!prop", null );
+
+ assertActivation( false, profile, newContext( newProperties( "prop", "value" ), null ) );
+
+ assertActivation( true, profile, newContext( newProperties( "prop", "" ), null ) );
+
+ assertActivation( true, profile, newContext( newProperties( "other", "value" ), null ) );
+ }
+
+ public void testWithNegatedNameOnly_SystemProperty()
+ throws Exception
+ {
+ Profile profile = newProfile( "!prop", null );
+
+ assertActivation( false, profile, newContext( null, newProperties( "prop", "value" ) ) );
+
+ assertActivation( true, profile, newContext( null, newProperties( "prop", "" ) ) );
+
+ assertActivation( true, profile, newContext( null, newProperties( "other", "value" ) ) );
+ }
+
+ public void testWithValue_UserProperty()
+ throws Exception
+ {
+ Profile profile = newProfile( "prop", "value" );
+
+ assertActivation( true, profile, newContext( newProperties( "prop", "value" ), null ) );
+
+ assertActivation( false, profile, newContext( newProperties( "prop", "other" ), null ) );
+
+ assertActivation( false, profile, newContext( newProperties( "prop", "" ), null ) );
+ }
+
+ public void testWithValue_SystemProperty()
+ throws Exception
+ {
+ Profile profile = newProfile( "prop", "value" );
+
+ assertActivation( true, profile, newContext( null, newProperties( "prop", "value" ) ) );
+
+ assertActivation( false, profile, newContext( null, newProperties( "prop", "other" ) ) );
+
+ assertActivation( false, profile, newContext( null, newProperties( "other", "" ) ) );
+ }
+
+ public void testWithNegatedValue_UserProperty()
+ throws Exception
+ {
+ Profile profile = newProfile( "prop", "!value" );
+
+ assertActivation( false, profile, newContext( newProperties( "prop", "value" ), null ) );
+
+ assertActivation( true, profile, newContext( newProperties( "prop", "other" ), null ) );
+
+ assertActivation( true, profile, newContext( newProperties( "prop", "" ), null ) );
+ }
+
+ public void testWithNegatedValue_SystemProperty()
+ throws Exception
+ {
+ Profile profile = newProfile( "prop", "!value" );
+
+ assertActivation( false, profile, newContext( null, newProperties( "prop", "value" ) ) );
+
+ assertActivation( true, profile, newContext( null, newProperties( "prop", "other" ) ) );
+
+ assertActivation( true, profile, newContext( null, newProperties( "other", "" ) ) );
+ }
+
+ public void testWithValue_UserPropertyDominantOverSystemProperty()
+ throws Exception
+ {
+ Profile profile = newProfile( "prop", "value" );
+
+ Properties props1 = newProperties( "prop", "value" );
+ Properties props2 = newProperties( "prop", "other" );
+
+ assertActivation( true, profile, newContext( props1, props2 ) );
+
+ assertActivation( false, profile, newContext( props2, props1 ) );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/java/org/apache/maven/model/validation/DefaultModelValidatorTest.java b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/java/org/apache/maven/model/validation/DefaultModelValidatorTest.java
new file mode 100644
index 00000000..dde532d8
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/java/org/apache/maven/model/validation/DefaultModelValidatorTest.java
@@ -0,0 +1,630 @@
+package org.apache.maven.model.validation;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.InputStream;
+import java.util.List;
+
+import org.apache.maven.model.Model;
+import org.apache.maven.model.building.DefaultModelBuildingRequest;
+import org.apache.maven.model.building.ModelBuildingRequest;
+import org.apache.maven.model.building.SimpleProblemCollector;
+import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
+import org.codehaus.plexus.PlexusTestCase;
+
+/**
+ * @author <a href="mailto:trygvis@inamo.no">Trygve Laugst&oslash;l</a>
+ */
+public class DefaultModelValidatorTest
+ extends PlexusTestCase
+{
+
+ private ModelValidator validator;
+
+ private Model read( String pom )
+ throws Exception
+ {
+ String resource = "/poms/validation/" + pom;
+ InputStream is = getClass().getResourceAsStream( resource );
+ assertNotNull( "missing resource: " + resource, is );
+ return new MavenXpp3Reader().read( is );
+ }
+
+ private SimpleProblemCollector validate( String pom )
+ throws Exception
+ {
+ return validateEffective( pom, ModelBuildingRequest.VALIDATION_LEVEL_STRICT );
+ }
+
+ private SimpleProblemCollector validateRaw( String pom )
+ throws Exception
+ {
+ return validateRaw( pom, ModelBuildingRequest.VALIDATION_LEVEL_STRICT );
+ }
+
+ private SimpleProblemCollector validateEffective( String pom, int level )
+ throws Exception
+ {
+ ModelBuildingRequest request = new DefaultModelBuildingRequest().setValidationLevel( level );
+
+ SimpleProblemCollector problems = new SimpleProblemCollector( read( pom ) );
+
+ validator.validateEffectiveModel( problems.getModel(), request, problems );
+
+ return problems;
+ }
+
+ private SimpleProblemCollector validateRaw( String pom, int level )
+ throws Exception
+ {
+ ModelBuildingRequest request = new DefaultModelBuildingRequest().setValidationLevel( level );
+
+ SimpleProblemCollector problems = new SimpleProblemCollector( read( pom ) );
+
+ validator.validateRawModel( problems.getModel(), request, problems );
+
+ return problems;
+ }
+
+ private void assertContains( String msg, String substring )
+ {
+ assertTrue( "\"" + substring + "\" was not found in: " + msg, msg.contains( substring ) );
+ }
+
+ @Override
+ protected void setUp()
+ throws Exception
+ {
+ super.setUp();
+
+ validator = lookup( ModelValidator.class );
+ }
+
+ @Override
+ protected void tearDown()
+ throws Exception
+ {
+ this.validator = null;
+
+ super.tearDown();
+ }
+
+ private void assertViolations( SimpleProblemCollector result, int fatals, int errors, int warnings )
+ {
+ assertEquals( String.valueOf( result.getFatals() ), fatals, result.getFatals().size() );
+ assertEquals( String.valueOf( result.getErrors() ), errors, result.getErrors().size() );
+ assertEquals( String.valueOf( result.getWarnings() ), warnings, result.getWarnings().size() );
+ }
+
+ public void testMissingModelVersion()
+ throws Exception
+ {
+ SimpleProblemCollector result = validate( "missing-modelVersion-pom.xml" );
+
+ assertViolations( result, 0, 1, 0 );
+
+ assertEquals( "'modelVersion' is missing.", result.getErrors().get( 0 ) );
+ }
+
+ public void testBadModelVersion()
+ throws Exception
+ {
+ SimpleProblemCollector result =
+ validateRaw( "bad-modelVersion.xml", ModelBuildingRequest.VALIDATION_LEVEL_STRICT );
+
+ assertViolations( result, 0, 1, 0 );
+
+ assertTrue( result.getErrors().get( 0 ).contains( "modelVersion" ) );
+ }
+
+ public void testMissingArtifactId()
+ throws Exception
+ {
+ SimpleProblemCollector result = validate( "missing-artifactId-pom.xml" );
+
+ assertViolations( result, 0, 1, 0 );
+
+ assertEquals( "'artifactId' is missing.", result.getErrors().get( 0 ) );
+ }
+
+ public void testMissingGroupId()
+ throws Exception
+ {
+ SimpleProblemCollector result = validate( "missing-groupId-pom.xml" );
+
+ assertViolations( result, 0, 1, 0 );
+
+ assertEquals( "'groupId' is missing.", result.getErrors().get( 0 ) );
+ }
+
+ public void testInvalidIds()
+ throws Exception
+ {
+ SimpleProblemCollector result = validate( "invalid-ids-pom.xml" );
+
+ assertViolations( result, 0, 2, 0 );
+
+ assertEquals( "'groupId' with value 'o/a/m' does not match a valid id pattern.", result.getErrors().get( 0 ) );
+
+ assertEquals( "'artifactId' with value 'm$-do$' does not match a valid id pattern.", result.getErrors().get( 1 ) );
+ }
+
+ public void testMissingType()
+ throws Exception
+ {
+ SimpleProblemCollector result = validate( "missing-type-pom.xml" );
+
+ assertViolations( result, 0, 1, 0 );
+
+ assertEquals( "'packaging' is missing.", result.getErrors().get( 0 ) );
+ }
+
+ public void testMissingVersion()
+ throws Exception
+ {
+ SimpleProblemCollector result = validate( "missing-version-pom.xml" );
+
+ assertViolations( result, 0, 1, 0 );
+
+ assertEquals( "'version' is missing.", result.getErrors().get( 0 ) );
+ }
+
+ public void testInvalidAggregatorPackaging()
+ throws Exception
+ {
+ SimpleProblemCollector result = validate( "invalid-aggregator-packaging-pom.xml" );
+
+ assertViolations( result, 0, 1, 0 );
+
+ assertTrue( result.getErrors().get( 0 ).contains( "Aggregator projects require 'pom' as packaging." ) );
+ }
+
+ public void testMissingDependencyArtifactId()
+ throws Exception
+ {
+ SimpleProblemCollector result = validate( "missing-dependency-artifactId-pom.xml" );
+
+ assertViolations( result, 0, 1, 0 );
+
+ assertTrue( result.getErrors().get( 0 ).contains(
+ "'dependencies.dependency.artifactId' for groupId:null:jar is missing" ) );
+ }
+
+ public void testMissingDependencyGroupId()
+ throws Exception
+ {
+ SimpleProblemCollector result = validate( "missing-dependency-groupId-pom.xml" );
+
+ assertViolations( result, 0, 1, 0 );
+
+ assertTrue( result.getErrors().get( 0 ).contains(
+ "'dependencies.dependency.groupId' for null:artifactId:jar is missing" ) );
+ }
+
+ public void testMissingDependencyVersion()
+ throws Exception
+ {
+ SimpleProblemCollector result = validate( "missing-dependency-version-pom.xml" );
+
+ assertViolations( result, 0, 1, 0 );
+
+ assertTrue( result.getErrors().get( 0 ).contains(
+ "'dependencies.dependency.version' for groupId:artifactId:jar is missing" ) );
+ }
+
+ public void testMissingDependencyManagementArtifactId()
+ throws Exception
+ {
+ SimpleProblemCollector result = validate( "missing-dependency-mgmt-artifactId-pom.xml" );
+
+ assertViolations( result, 0, 1, 0 );
+
+ assertTrue( result.getErrors().get( 0 ).contains(
+ "'dependencyManagement.dependencies.dependency.artifactId' for groupId:null:jar is missing" ) );
+ }
+
+ public void testMissingDependencyManagementGroupId()
+ throws Exception
+ {
+ SimpleProblemCollector result = validate( "missing-dependency-mgmt-groupId-pom.xml" );
+
+ assertViolations( result, 0, 1, 0 );
+
+ assertTrue( result.getErrors().get( 0 ).contains(
+ "'dependencyManagement.dependencies.dependency.groupId' for null:artifactId:jar is missing" ) );
+ }
+
+ public void testMissingAll()
+ throws Exception
+ {
+ SimpleProblemCollector result = validate( "missing-1-pom.xml" );
+
+ assertViolations( result, 0, 4, 0 );
+
+ List<String> messages = result.getErrors();
+
+ assertTrue( messages.contains( "\'modelVersion\' is missing." ) );
+ assertTrue( messages.contains( "\'groupId\' is missing." ) );
+ assertTrue( messages.contains( "\'artifactId\' is missing." ) );
+ assertTrue( messages.contains( "\'version\' is missing." ) );
+ // type is inherited from the super pom
+ }
+
+ public void testMissingPluginArtifactId()
+ throws Exception
+ {
+ SimpleProblemCollector result = validate( "missing-plugin-artifactId-pom.xml" );
+
+ assertViolations( result, 0, 1, 0 );
+
+ assertEquals( "'build.plugins.plugin.artifactId' is missing.", result.getErrors().get( 0 ) );
+ }
+
+ public void testEmptyPluginVersion()
+ throws Exception
+ {
+ SimpleProblemCollector result = validate( "empty-plugin-version.xml" );
+
+ assertViolations( result, 0, 1, 0 );
+
+ assertEquals( "'build.plugins.plugin.version' for org.apache.maven.plugins:maven-it-plugin"
+ + " must be a valid version but is ''.", result.getErrors().get( 0 ) );
+ }
+
+ public void testMissingRepositoryId()
+ throws Exception
+ {
+ SimpleProblemCollector result =
+ validateRaw( "missing-repository-id-pom.xml", ModelBuildingRequest.VALIDATION_LEVEL_STRICT );
+
+ assertViolations( result, 0, 4, 0 );
+
+ assertEquals( "'repositories.repository.id' is missing.", result.getErrors().get( 0 ) );
+
+ assertEquals( "'repositories.repository[null].url' is missing.", result.getErrors().get( 1 ) );
+
+ assertEquals( "'pluginRepositories.pluginRepository.id' is missing.", result.getErrors().get( 2 ) );
+
+ assertEquals( "'pluginRepositories.pluginRepository[null].url' is missing.", result.getErrors().get( 3 ) );
+ }
+
+ public void testMissingResourceDirectory()
+ throws Exception
+ {
+ SimpleProblemCollector result = validate( "missing-resource-directory-pom.xml" );
+
+ assertViolations( result, 0, 2, 0 );
+
+ assertEquals( "'build.resources.resource.directory' is missing.", result.getErrors().get( 0 ) );
+
+ assertEquals( "'build.testResources.testResource.directory' is missing.", result.getErrors().get( 1 ) );
+ }
+
+ public void testBadPluginDependencyScope()
+ throws Exception
+ {
+ SimpleProblemCollector result = validate( "bad-plugin-dependency-scope.xml" );
+
+ assertViolations( result, 0, 3, 0 );
+
+ assertTrue( result.getErrors().get( 0 ).contains( "test:d" ) );
+
+ assertTrue( result.getErrors().get( 1 ).contains( "test:e" ) );
+
+ assertTrue( result.getErrors().get( 2 ).contains( "test:f" ) );
+ }
+
+ public void testBadDependencyScope()
+ throws Exception
+ {
+ SimpleProblemCollector result = validate( "bad-dependency-scope.xml" );
+
+ assertViolations( result, 0, 0, 2 );
+
+ assertTrue( result.getWarnings().get( 0 ).contains( "test:f" ) );
+
+ assertTrue( result.getWarnings().get( 1 ).contains( "test:g" ) );
+ }
+
+ public void testBadDependencyVersion()
+ throws Exception
+ {
+ SimpleProblemCollector result = validate( "bad-dependency-version.xml" );
+
+ assertViolations( result, 0, 2, 0 );
+
+ assertContains( result.getErrors().get( 0 ),
+ "'dependencies.dependency.version' for test:b:jar must be a valid version" );
+ assertContains( result.getErrors().get( 1 ),
+ "'dependencies.dependency.version' for test:c:jar must not contain any of these characters" );
+ }
+
+ public void testDuplicateModule()
+ throws Exception
+ {
+ SimpleProblemCollector result = validate( "duplicate-module.xml" );
+
+ assertViolations( result, 0, 1, 0 );
+
+ assertTrue( result.getErrors().get( 0 ).contains( "child" ) );
+ }
+
+ public void testDuplicateProfileId()
+ throws Exception
+ {
+ SimpleProblemCollector result = validateRaw( "duplicate-profile-id.xml" );
+
+ assertViolations( result, 0, 1, 0 );
+
+ assertTrue( result.getErrors().get( 0 ).contains( "non-unique-id" ) );
+ }
+
+ public void testBadPluginVersion()
+ throws Exception
+ {
+ SimpleProblemCollector result = validate( "bad-plugin-version.xml" );
+
+ assertViolations( result, 0, 4, 0 );
+
+ assertContains( result.getErrors().get( 0 ),
+ "'build.plugins.plugin.version' for test:mip must be a valid version" );
+ assertContains( result.getErrors().get( 1 ),
+ "'build.plugins.plugin.version' for test:rmv must be a valid version" );
+ assertContains( result.getErrors().get( 2 ),
+ "'build.plugins.plugin.version' for test:lmv must be a valid version" );
+ assertContains( result.getErrors().get( 3 ),
+ "'build.plugins.plugin.version' for test:ifsc must not contain any of these characters" );
+ }
+
+ public void testDistributionManagementStatus()
+ throws Exception
+ {
+ SimpleProblemCollector result = validate( "distribution-management-status.xml" );
+
+ assertViolations( result, 0, 1, 0 );
+
+ assertTrue( result.getErrors().get( 0 ).contains( "distributionManagement.status" ) );
+ }
+
+ public void testIncompleteParent()
+ throws Exception
+ {
+ SimpleProblemCollector result = validateRaw( "incomplete-parent.xml" );
+
+ assertViolations( result, 3, 0, 0 );
+
+ assertTrue( result.getFatals().get( 0 ).contains( "parent.groupId" ) );
+ assertTrue( result.getFatals().get( 1 ).contains( "parent.artifactId" ) );
+ assertTrue( result.getFatals().get( 2 ).contains( "parent.version" ) );
+ }
+
+ public void testHardCodedSystemPath()
+ throws Exception
+ {
+ SimpleProblemCollector result = validateRaw( "hard-coded-system-path.xml" );
+
+ assertViolations( result, 0, 0, 1 );
+
+ assertTrue( result.getWarnings().get( 0 ).contains( "test:a:jar" ) );
+ }
+
+ public void testEmptyModule()
+ throws Exception
+ {
+ SimpleProblemCollector result = validate( "empty-module.xml" );
+
+ assertViolations( result, 0, 1, 0 );
+
+ assertTrue( result.getErrors().get( 0 ).contains( "'modules.module[0]' has been specified without a path" ) );
+ }
+
+ public void testDuplicatePlugin()
+ throws Exception
+ {
+ SimpleProblemCollector result = validateRaw( "duplicate-plugin.xml" );
+
+ assertViolations( result, 0, 0, 4 );
+
+ assertTrue( result.getWarnings().get( 0 ).contains( "duplicate declaration of plugin test:duplicate" ) );
+ assertTrue( result.getWarnings().get( 1 ).contains( "duplicate declaration of plugin test:managed-duplicate" ) );
+ assertTrue( result.getWarnings().get( 2 ).contains( "duplicate declaration of plugin profile:duplicate" ) );
+ assertTrue( result.getWarnings().get( 3 ).contains( "duplicate declaration of plugin profile:managed-duplicate" ) );
+ }
+
+ public void testDuplicatePluginExecution()
+ throws Exception
+ {
+ SimpleProblemCollector result = validateRaw( "duplicate-plugin-execution.xml" );
+
+ assertViolations( result, 0, 4, 0 );
+
+ assertContains( result.getErrors().get( 0 ), "duplicate execution with id a" );
+ assertContains( result.getErrors().get( 1 ), "duplicate execution with id default" );
+ assertContains( result.getErrors().get( 2 ), "duplicate execution with id c" );
+ assertContains( result.getErrors().get( 3 ), "duplicate execution with id b" );
+ }
+
+ public void testReservedRepositoryId()
+ throws Exception
+ {
+ SimpleProblemCollector result = validate( "reserved-repository-id.xml" );
+
+ assertViolations( result, 0, 0, 4 );
+
+ assertContains( result.getWarnings().get( 0 ), "'repositories.repository.id'" + " must not be 'local'" );
+ assertContains( result.getWarnings().get( 1 ), "'pluginRepositories.pluginRepository.id' must not be 'local'" );
+ assertContains( result.getWarnings().get( 2 ), "'distributionManagement.repository.id' must not be 'local'" );
+ assertContains( result.getWarnings().get( 3 ),
+ "'distributionManagement.snapshotRepository.id' must not be 'local'" );
+ }
+
+ public void testMissingPluginDependencyGroupId()
+ throws Exception
+ {
+ SimpleProblemCollector result = validate( "missing-plugin-dependency-groupId.xml" );
+
+ assertViolations( result, 0, 1, 0 );
+
+ assertTrue( result.getErrors().get( 0 ).contains( ":a:" ) );
+ }
+
+ public void testMissingPluginDependencyArtifactId()
+ throws Exception
+ {
+ SimpleProblemCollector result = validate( "missing-plugin-dependency-artifactId.xml" );
+
+ assertViolations( result, 0, 1, 0 );
+
+ assertTrue( result.getErrors().get( 0 ).contains( "test:" ) );
+ }
+
+ public void testMissingPluginDependencyVersion()
+ throws Exception
+ {
+ SimpleProblemCollector result = validate( "missing-plugin-dependency-version.xml" );
+
+ assertViolations( result, 0, 1, 0 );
+
+ assertTrue( result.getErrors().get( 0 ).contains( "test:a" ) );
+ }
+
+ public void testBadPluginDependencyVersion()
+ throws Exception
+ {
+ SimpleProblemCollector result = validate( "bad-plugin-dependency-version.xml" );
+
+ assertViolations( result, 0, 1, 0 );
+
+ assertTrue( result.getErrors().get( 0 ).contains( "test:b" ) );
+ }
+
+ public void testBadVersion()
+ throws Exception
+ {
+ SimpleProblemCollector result = validate( "bad-version.xml" );
+
+ assertViolations( result, 0, 0, 1 );
+
+ assertContains( result.getWarnings().get( 0 ), "'version' must not contain any of these characters" );
+ }
+
+ public void testBadSnapshotVersion()
+ throws Exception
+ {
+ SimpleProblemCollector result = validate( "bad-snapshot-version.xml" );
+
+ assertViolations( result, 0, 0, 1 );
+
+ assertContains( result.getWarnings().get( 0 ), "'version' uses an unsupported snapshot version format" );
+ }
+
+ public void testBadRepositoryId()
+ throws Exception
+ {
+ SimpleProblemCollector result = validate( "bad-repository-id.xml" );
+
+ assertViolations( result, 0, 0, 4 );
+
+ assertContains( result.getWarnings().get( 0 ),
+ "'repositories.repository.id' must not contain any of these characters" );
+ assertContains( result.getWarnings().get( 1 ),
+ "'pluginRepositories.pluginRepository.id' must not contain any of these characters" );
+ assertContains( result.getWarnings().get( 2 ),
+ "'distributionManagement.repository.id' must not contain any of these characters" );
+ assertContains( result.getWarnings().get( 3 ),
+ "'distributionManagement.snapshotRepository.id' must not contain any of these characters" );
+ }
+
+ public void testBadDependencyExclusionId()
+ throws Exception
+ {
+ SimpleProblemCollector result = validateEffective( "bad-dependency-exclusion-id.xml", ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_2_0 );
+
+ assertViolations( result, 0, 0, 2 );
+
+ assertContains( result.getWarnings().get( 0 ),
+ "'dependencies.dependency.exclusions.exclusion.groupId' for gid:aid:jar" );
+ assertContains( result.getWarnings().get( 1 ),
+ "'dependencies.dependency.exclusions.exclusion.artifactId' for gid:aid:jar" );
+
+ // MNG-3832: Aether (part of M3+) supports wildcard expressions for exclusions
+
+ SimpleProblemCollector result_30 = validate( "bad-dependency-exclusion-id.xml" );
+
+ assertViolations( result_30, 0, 0, 0 );
+
+ }
+
+ public void testMissingDependencyExclusionId()
+ throws Exception
+ {
+ SimpleProblemCollector result = validate( "missing-dependency-exclusion-id.xml" );
+
+ assertViolations( result, 0, 0, 2 );
+
+ assertContains( result.getWarnings().get( 0 ),
+ "'dependencies.dependency.exclusions.exclusion.groupId' for gid:aid:jar is missing" );
+ assertContains( result.getWarnings().get( 1 ),
+ "'dependencies.dependency.exclusions.exclusion.artifactId' for gid:aid:jar is missing" );
+ }
+
+ public void testBadImportScopeType()
+ throws Exception
+ {
+ SimpleProblemCollector result = validateRaw( "bad-import-scope-type.xml" );
+
+ assertViolations( result, 0, 0, 1 );
+
+ assertContains( result.getWarnings().get( 0 ),
+ "'dependencyManagement.dependencies.dependency.type' for test:a:jar must be 'pom'" );
+ }
+
+ public void testBadImportScopeClassifier()
+ throws Exception
+ {
+ SimpleProblemCollector result = validateRaw( "bad-import-scope-classifier.xml" );
+
+ assertViolations( result, 0, 1, 0 );
+
+ assertContains( result.getErrors().get( 0 ),
+ "'dependencyManagement.dependencies.dependency.classifier' for test:a:pom:cls must be empty" );
+ }
+
+ public void testSystemPathRefersToProjectBasedir()
+ throws Exception
+ {
+ SimpleProblemCollector result = validateRaw( "basedir-system-path.xml" );
+
+ assertViolations( result, 0, 0, 2 );
+
+ assertContains( result.getWarnings().get( 0 ), "'dependencies.dependency.systemPath' for test:a:jar "
+ + "should not point at files within the project directory" );
+ assertContains( result.getWarnings().get( 1 ), "'dependencies.dependency.systemPath' for test:b:jar "
+ + "should not point at files within the project directory" );
+ }
+
+ public void testMissingReportPluginVersion()
+ throws Exception
+ {
+ SimpleProblemCollector result = validate( "missing-report-version-pom.xml" );
+
+ assertViolations( result, 0, 0, 0 );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/factory/complex.xml b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/factory/complex.xml
new file mode 100644
index 00000000..80060ffb
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/factory/complex.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>test</groupId>
+ <artifactId>test</artifactId>
+ <version>0.1-SNAPSHOT</version>
+ <packaging>pom</packaging>
+
+ <properties>
+ <my.filter.value>hello</my.filter.value>
+ </properties>
+
+ <profiles>
+ <profile>
+ <id>two-conditions</id>
+ <activation>
+ <file>
+ <exists>simple.xml</exists>
+ </file>
+ <property>
+ <name>myproperty</name>
+ <value>test</value>
+ </property>
+ </activation>
+ <properties>
+ <profile.file>activated-1</profile.file>
+ </properties>
+ </profile>
+ <profile>
+ <id>another-two-conditions</id>
+ <activation>
+ <property>
+ <name>myproperty</name>
+ <value>test</value>
+ </property>
+ <file>
+ <missing>simple.xml</missing>
+ </file>
+ </activation>
+ <properties>
+ <profile.miss>activated-2</profile.miss>
+ </properties>
+ </profile>
+ </profiles>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/factory/simple.xml b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/factory/simple.xml
new file mode 100644
index 00000000..71900731
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/factory/simple.xml
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>test</groupId>
+ <artifactId>test</artifactId>
+ <version>0.1-SNAPSHOT</version>
+ <packaging>pom</packaging>
+
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>2.1</version>
+ <configuration>
+ <source> 1.5 </source>
+ <target xml:space="preserve"> 1.5 </target>
+ </configuration>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>test</id>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+ <profiles>
+ <profile>
+ <id>default</id>
+ <activation>
+ <activeByDefault>true</activeByDefault>
+ </activation>
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ </properties>
+ </profile>
+ <profile>
+ <id>file</id>
+ <activation>
+ <file>
+ <exists>simple.xml</exists>
+ </file>
+ </activation>
+ <properties>
+ <profile.file>activated</profile.file>
+ </properties>
+ </profile>
+ </profiles>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/inheritance/plugin-configuration-child.xml b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/inheritance/plugin-configuration-child.xml
new file mode 100644
index 00000000..feb3cb89
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/inheritance/plugin-configuration-child.xml
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <artifactId>child</artifactId>
+ <version>12-SNAPSHOT</version>
+
+ <mailingLists>
+ <!--mailingList> MNG-3124: no way to add a list to parent content, only full override
+ <name>child</name>
+ <post>post@mailing.list.com</post>
+ <subscribe>subscribe@mailing.list.com</subscribe>
+ <unsubscribe>unsubscribe@mailing.list.com</unsubscribe>
+ </mailingList-->
+ </mailingLists>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>inheritance.configuration</groupId>
+ <artifactId>default</artifactId>
+ <version>3.0</version>
+ <configuration>
+ <defaults>
+ <parent>child</parent>
+ <child>child</child>
+ </defaults>
+ <appends combine.children="append">
+ <parent>child</parent>
+ <child>child</child>
+ </appends>
+ <overrides combine.self="override">
+ <parent>child</parent>
+ <child>child</child>
+ </overrides>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/inheritance/plugin-configuration-expected.xml b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/inheritance/plugin-configuration-expected.xml
new file mode 100644
index 00000000..00a21f3d
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/inheritance/plugin-configuration-expected.xml
@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>inheritance</groupId>
+ <artifactId>child</artifactId>
+ <version>12-SNAPSHOT</version>
+
+ <!-- name is not inherited, but description is -->
+ <description>Model inheritance description</description>
+ <url>http://www.apache.org/child/</url><!-- child's artifactId appended to parent url -->
+
+ <mailingLists>
+ <mailingList>
+ <name>parent</name>
+ <post>post@mailing.list.com</post>
+ <subscribe>subscribe@mailing.list.com</subscribe>
+ <unsubscribe>unsubscribe@mailing.list.com</unsubscribe>
+ </mailingList>
+ </mailingLists>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>inheritance.configuration</groupId>
+ <artifactId>default</artifactId>
+ <version>3.0</version>
+ <configuration>
+ <defaults><!-- equivalent to combine.children="merge" combine.self="merge" -->
+ <!-- merge the content of the configuration element according to element name -->
+ <parent>child</parent>
+ <child>child</child>
+ <parent-only>parent</parent-only>
+ </defaults>
+ <appends combine.children="append">
+ <parent-only>parent</parent-only>
+ <parent>parent</parent>
+ <parent>child</parent>
+ <child>child</child>
+ </appends>
+ <overrides combine.self="override">
+ <parent>child</parent>
+ <child>child</child>
+ </overrides>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+ <reporting>
+ <plugins>
+ <plugin>
+ <artifactId>MNG-5115</artifactId>
+ <reportSets>
+ <reportSet>
+ <id>default-inherited</id>
+ <reports>
+ <report>to-be-inherited</report>
+ </reports>
+ </reportSet>
+ <!-- reportSet with inherited=false is not here -->
+ </reportSets>
+ </plugin>
+ </plugins>
+ </reporting>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/inheritance/plugin-configuration-parent.xml b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/inheritance/plugin-configuration-parent.xml
new file mode 100644
index 00000000..2b973a15
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/inheritance/plugin-configuration-parent.xml
@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>inheritance</groupId>
+ <artifactId>parent</artifactId>
+ <version>11-SNAPSHOT</version>
+
+ <name>Model inheritance test</name>
+ <description>Model inheritance description</description>
+ <url>http://www.apache.org/</url>
+
+ <mailingLists>
+ <mailingList>
+ <name>parent</name>
+ <post>post@mailing.list.com</post>
+ <subscribe>subscribe@mailing.list.com</subscribe>
+ <unsubscribe>unsubscribe@mailing.list.com</unsubscribe>
+ </mailingList>
+ </mailingLists>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>inheritance.configuration</groupId>
+ <artifactId>default</artifactId>
+ <version>2.0</version>
+ <configuration>
+ <defaults>
+ <parent-only>parent</parent-only>
+ <parent>parent</parent>
+ </defaults>
+ <appends>
+ <parent-only>parent</parent-only>
+ <parent>parent</parent>
+ </appends>
+ <overrides>
+ <parent-only>parent</parent-only>
+ <parent>parent</parent>
+ </overrides>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+ <reporting>
+ <plugins>
+ <plugin>
+ <artifactId>MNG-5115</artifactId>
+ <reportSets>
+ <reportSet>
+ <id>default-inherited</id>
+ <reports>
+ <report>to-be-inherited</report>
+ </reports>
+ </reportSet>
+ <reportSet>
+ <id>inherited-false</id>
+ <inherited>false</inherited>
+ <reports>
+ <report>not-to-be-inherited</report>
+ </reports>
+ </reportSet>
+ </reportSets>
+ </plugin>
+ </plugins>
+ </reporting>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/bad-dependency-exclusion-id.xml b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/bad-dependency-exclusion-id.xml
new file mode 100644
index 00000000..1e02b154
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/bad-dependency-exclusion-id.xml
@@ -0,0 +1,40 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>foo</artifactId>
+ <groupId>foo</groupId>
+ <version>99.44</version>
+ <packaging>jar</packaging>
+
+ <dependencies>
+ <dependency>
+ <groupId>gid</groupId>
+ <artifactId>aid</artifactId>
+ <version>1.0</version>
+ <exclusions>
+ <exclusion>
+ <groupId>test?</groupId>
+ <artifactId>*</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/bad-dependency-scope.xml b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/bad-dependency-scope.xml
new file mode 100644
index 00000000..0ae0b45f
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/bad-dependency-scope.xml
@@ -0,0 +1,69 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>aid</artifactId>
+ <groupId>gid</groupId>
+ <version>0.1</version>
+
+ <dependencies>
+ <dependency>
+ <groupId>test</groupId>
+ <artifactId>a</artifactId>
+ <version>0.2</version>
+ </dependency>
+ <dependency>
+ <groupId>test</groupId>
+ <artifactId>b</artifactId>
+ <version>0.2</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>test</groupId>
+ <artifactId>c</artifactId>
+ <version>0.2</version>
+ <scope>runtime</scope>
+ </dependency>
+ <dependency>
+ <groupId>test</groupId>
+ <artifactId>d</artifactId>
+ <version>0.2</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>test</groupId>
+ <artifactId>e</artifactId>
+ <version>0.2</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>test</groupId>
+ <artifactId>f</artifactId>
+ <version>0.2</version>
+ <scope>import</scope>
+ </dependency>
+ <dependency>
+ <groupId>test</groupId>
+ <artifactId>g</artifactId>
+ <version>0.2</version>
+ <scope>optional</scope>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/bad-dependency-version.xml b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/bad-dependency-version.xml
new file mode 100644
index 00000000..cb75e7b7
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/bad-dependency-version.xml
@@ -0,0 +1,43 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>aid</artifactId>
+ <groupId>gid</groupId>
+ <version>0.1</version>
+
+ <dependencies>
+ <dependency>
+ <groupId>test</groupId>
+ <artifactId>a</artifactId>
+ <version>0.2</version>
+ </dependency>
+ <dependency>
+ <groupId>test</groupId>
+ <artifactId>b</artifactId>
+ <version>${missing.property}</version>
+ </dependency>
+ <dependency>
+ <groupId>test</groupId>
+ <artifactId>c</artifactId>
+ <version>1/1</version>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/bad-import-scope-classifier.xml b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/bad-import-scope-classifier.xml
new file mode 100644
index 00000000..83313451
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/bad-import-scope-classifier.xml
@@ -0,0 +1,38 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>aid</artifactId>
+ <groupId>gid</groupId>
+ <version>0.1</version>
+
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>test</groupId>
+ <artifactId>a</artifactId>
+ <version>0.1</version>
+ <scope>import</scope>
+ <type>pom</type>
+ <classifier>cls</classifier>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/bad-import-scope-type.xml b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/bad-import-scope-type.xml
new file mode 100644
index 00000000..fb505c54
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/bad-import-scope-type.xml
@@ -0,0 +1,37 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>aid</artifactId>
+ <groupId>gid</groupId>
+ <version>0.1</version>
+
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>test</groupId>
+ <artifactId>a</artifactId>
+ <version>0.1</version>
+ <scope>import</scope>
+ <!-- missing type=pom -->
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/bad-modelVersion.xml b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/bad-modelVersion.xml
new file mode 100644
index 00000000..1f381b3b
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/bad-modelVersion.xml
@@ -0,0 +1,25 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>99.0.0</modelVersion>
+ <groupId>foo</groupId>
+ <artifactId>bar</artifactId>
+ <version>0.1</version>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/bad-plugin-dependency-scope.xml b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/bad-plugin-dependency-scope.xml
new file mode 100644
index 00000000..3b06e620
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/bad-plugin-dependency-scope.xml
@@ -0,0 +1,70 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>aid</artifactId>
+ <groupId>gid</groupId>
+ <version>0.1</version>
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-it-plugin</artifactId>
+ <version>0.1</version>
+ <dependencies>
+ <dependency>
+ <groupId>test</groupId>
+ <artifactId>a</artifactId>
+ <version>0.2</version>
+ </dependency>
+ <dependency>
+ <groupId>test</groupId>
+ <artifactId>b</artifactId>
+ <version>0.2</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>test</groupId>
+ <artifactId>c</artifactId>
+ <version>0.2</version>
+ <scope>runtime</scope>
+ </dependency>
+ <dependency>
+ <groupId>test</groupId>
+ <artifactId>d</artifactId>
+ <version>0.2</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>test</groupId>
+ <artifactId>e</artifactId>
+ <version>0.2</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>test</groupId>
+ <artifactId>f</artifactId>
+ <version>0.2</version>
+ <scope>import</scope>
+ </dependency>
+ </dependencies>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/bad-plugin-dependency-version.xml b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/bad-plugin-dependency-version.xml
new file mode 100644
index 00000000..64382529
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/bad-plugin-dependency-version.xml
@@ -0,0 +1,46 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>aid</artifactId>
+ <groupId>gid</groupId>
+ <version>0.1</version>
+
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-it-plugin</artifactId>
+ <version>1.0</version>
+ <dependencies>
+ <dependency>
+ <groupId>test</groupId>
+ <artifactId>a</artifactId>
+ <version>0.1</version>
+ </dependency>
+ <dependency>
+ <groupId>test</groupId>
+ <artifactId>b</artifactId>
+ <version>${missing.property}</version>
+ </dependency>
+ </dependencies>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/bad-plugin-version.xml b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/bad-plugin-version.xml
new file mode 100644
index 00000000..2ca936aa
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/bad-plugin-version.xml
@@ -0,0 +1,55 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>aid</artifactId>
+ <groupId>gid</groupId>
+ <version>0.1</version>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>test</groupId>
+ <artifactId>good</artifactId>
+ <version>1.0</version>
+ </plugin>
+ <plugin>
+ <groupId>test</groupId>
+ <artifactId>mip</artifactId>
+ <version>${missing.property}</version>
+ </plugin>
+ <plugin>
+ <groupId>test</groupId>
+ <artifactId>rmv</artifactId>
+ <version>RELEASE</version>
+ </plugin>
+ <plugin>
+ <groupId>test</groupId>
+ <artifactId>lmv</artifactId>
+ <version>LATEST</version>
+ </plugin>
+ <plugin>
+ <groupId>test</groupId>
+ <artifactId>ifsc</artifactId>
+ <version>1/1</version>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/bad-repository-id.xml b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/bad-repository-id.xml
new file mode 100644
index 00000000..70553eb3
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/bad-repository-id.xml
@@ -0,0 +1,50 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>gid</groupId>
+ <artifactId>aid</artifactId>
+ <version>1.0</version>
+
+ <repositories>
+ <repository>
+ <id>this/is\bad</id>
+ <url>http://localhost</url>
+ </repository>
+ </repositories>
+ <pluginRepositories>
+ <pluginRepository>
+ <id>this/is\bad</id>
+ <url>http://localhost</url>
+ </pluginRepository>
+ </pluginRepositories>
+
+ <distributionManagement>
+ <repository>
+ <id>this/is\bad</id>
+ <url>http://localhost</url>
+ </repository>
+ <snapshotRepository>
+ <id>this/is\bad</id>
+ <url>http://localhost</url>
+ </snapshotRepository>
+ </distributionManagement>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/bad-snapshot-version.xml b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/bad-snapshot-version.xml
new file mode 100644
index 00000000..70b5ddcb
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/bad-snapshot-version.xml
@@ -0,0 +1,25 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>foo</groupId>
+ <artifactId>bar</artifactId>
+ <version>1.2.3.SNAPSHOT</version>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/bad-version.xml b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/bad-version.xml
new file mode 100644
index 00000000..bf6a1fc8
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/bad-version.xml
@@ -0,0 +1,25 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>foo</groupId>
+ <artifactId>bar</artifactId>
+ <version>this\is/bad</version>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/basedir-system-path.xml b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/basedir-system-path.xml
new file mode 100644
index 00000000..24d49d3d
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/basedir-system-path.xml
@@ -0,0 +1,42 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>aid</artifactId>
+ <groupId>gid</groupId>
+ <version>0.1</version>
+
+ <dependencies>
+ <dependency>
+ <groupId>test</groupId>
+ <artifactId>a</artifactId>
+ <version>0.2</version>
+ <scope>system</scope>
+ <systemPath>${basedir}/lib/a.jar</systemPath>
+ </dependency>
+ <dependency>
+ <groupId>test</groupId>
+ <artifactId>b</artifactId>
+ <version>0.1</version>
+ <scope>system</scope>
+ <systemPath>${project.basedir}/lib/b.jar</systemPath>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/distribution-management-status.xml b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/distribution-management-status.xml
new file mode 100644
index 00000000..3a5968b0
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/distribution-management-status.xml
@@ -0,0 +1,29 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>foo</groupId>
+ <artifactId>bar</artifactId>
+ <version>0.1</version>
+
+ <distributionManagement>
+ <status>generated</status>
+ </distributionManagement>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/duplicate-module.xml b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/duplicate-module.xml
new file mode 100644
index 00000000..d3ef528f
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/duplicate-module.xml
@@ -0,0 +1,31 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>aid</artifactId>
+ <groupId>gid</groupId>
+ <version>0.1</version>
+ <packaging>pom</packaging>
+
+ <modules>
+ <module>child</module>
+ <module>child</module>
+ </modules>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/duplicate-plugin-execution.xml b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/duplicate-plugin-execution.xml
new file mode 100644
index 00000000..0d4256de
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/duplicate-plugin-execution.xml
@@ -0,0 +1,103 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>aid</artifactId>
+ <groupId>gid</groupId>
+ <version>0.1</version>
+ <packaging>pom</packaging>
+
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>build</groupId>
+ <artifactId>managed-plugin</artifactId>
+ <executions>
+ <execution>
+ <phase>test</phase>
+ </execution>
+ <execution>
+ <phase>test</phase>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>build</groupId>
+ <artifactId>plugin</artifactId>
+ <executions>
+ <execution>
+ <id>a</id>
+ <phase>test</phase>
+ </execution>
+ <execution>
+ <id>a</id>
+ <phase>test</phase>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+ <profiles>
+ <profile>
+ <id>test</id>
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>profile</groupId>
+ <artifactId>managed-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>b</id>
+ <phase>test</phase>
+ </execution>
+ <execution>
+ <id>b</id>
+ <phase>test</phase>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>profile</groupId>
+ <artifactId>plugin</artifactId>
+ <executions>
+ <execution>
+ <id>c</id>
+ <phase>test</phase>
+ </execution>
+ <execution>
+ <id>c</id>
+ <phase>test</phase>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/duplicate-plugin.xml b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/duplicate-plugin.xml
new file mode 100644
index 00000000..06a6a657
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/duplicate-plugin.xml
@@ -0,0 +1,81 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>aid</artifactId>
+ <groupId>gid</groupId>
+ <version>0.1</version>
+ <packaging>pom</packaging>
+
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>test</groupId>
+ <artifactId>managed-duplicate</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>test</groupId>
+ <artifactId>managed-duplicate</artifactId>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>test</groupId>
+ <artifactId>duplicate</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>test</groupId>
+ <artifactId>duplicate</artifactId>
+ </plugin>
+ </plugins>
+ </build>
+
+ <profiles>
+ <profile>
+ <id>test</id>
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>profile</groupId>
+ <artifactId>managed-duplicate</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>profile</groupId>
+ <artifactId>managed-duplicate</artifactId>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>profile</groupId>
+ <artifactId>duplicate</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>profile</groupId>
+ <artifactId>duplicate</artifactId>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/duplicate-profile-id.xml b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/duplicate-profile-id.xml
new file mode 100644
index 00000000..2379c3db
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/duplicate-profile-id.xml
@@ -0,0 +1,35 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>aid</artifactId>
+ <groupId>gid</groupId>
+ <version>0.1</version>
+ <packaging>pom</packaging>
+
+ <profiles>
+ <profile>
+ <id>non-unique-id</id>
+ </profile>
+ <profile>
+ <id>non-unique-id</id>
+ </profile>
+ </profiles>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/empty-module.xml b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/empty-module.xml
new file mode 100644
index 00000000..f7a91d1d
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/empty-module.xml
@@ -0,0 +1,30 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>aid</artifactId>
+ <groupId>gid</groupId>
+ <version>0.1</version>
+ <packaging>pom</packaging>
+
+ <modules>
+ <module> </module>
+ </modules>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/empty-plugin-version.xml b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/empty-plugin-version.xml
new file mode 100644
index 00000000..340efc5c
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/empty-plugin-version.xml
@@ -0,0 +1,34 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>foo</artifactId>
+ <groupId>bar</groupId>
+ <version>1.0</version>
+ <packaging>pack</packaging>
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-it-plugin</artifactId>
+ <version></version>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/hard-coded-system-path.xml b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/hard-coded-system-path.xml
new file mode 100644
index 00000000..b5a4dd67
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/hard-coded-system-path.xml
@@ -0,0 +1,42 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>aid</artifactId>
+ <groupId>gid</groupId>
+ <version>0.1</version>
+
+ <dependencies>
+ <dependency>
+ <groupId>test</groupId>
+ <artifactId>a</artifactId>
+ <version>0.2</version>
+ <scope>system</scope>
+ <systemPath>should-use-variables-and-not-hard-code-this-path</systemPath>
+ </dependency>
+ <dependency>
+ <groupId>test</groupId>
+ <artifactId>b</artifactId>
+ <version>0.1</version>
+ <scope>system</scope>
+ <systemPath>${java.home}/lib/good.jar</systemPath>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/incomplete-parent.xml b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/incomplete-parent.xml
new file mode 100644
index 00000000..2fc94d57
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/incomplete-parent.xml
@@ -0,0 +1,30 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <!-- all fields missing -->
+ </parent>
+
+ <artifactId>aid</artifactId>
+ <groupId>gid</groupId>
+ <version>0.1</version>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/invalid-aggregator-packaging-pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/invalid-aggregator-packaging-pom.xml
new file mode 100644
index 00000000..977f5db4
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/invalid-aggregator-packaging-pom.xml
@@ -0,0 +1,30 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>foo</artifactId>
+ <groupId>foo</groupId>
+ <version>99.44</version>
+ <packaging>bleh</packaging>
+
+ <modules>
+ <module>test-module</module>
+ </modules>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/invalid-ids-pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/invalid-ids-pom.xml
new file mode 100644
index 00000000..bbb8e9c8
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/invalid-ids-pom.xml
@@ -0,0 +1,26 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>o/a/m</groupId>
+ <artifactId>m$-do$</artifactId>
+ <version>99.44</version>
+ <packaging>bleh</packaging>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/missing-1-pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/missing-1-pom.xml
new file mode 100644
index 00000000..fe297e6e
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/missing-1-pom.xml
@@ -0,0 +1,21 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/missing-artifactId-pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/missing-artifactId-pom.xml
new file mode 100644
index 00000000..39f0d7bc
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/missing-artifactId-pom.xml
@@ -0,0 +1,25 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>foo</groupId>
+ <version>99.44</version>
+ <packaging>bleh</packaging>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/missing-dependency-artifactId-pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/missing-dependency-artifactId-pom.xml
new file mode 100644
index 00000000..3a5b6479
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/missing-dependency-artifactId-pom.xml
@@ -0,0 +1,32 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>foo</artifactId>
+ <groupId>foo</groupId>
+ <version>99.44</version>
+ <packaging>bleh</packaging>
+ <dependencies>
+ <dependency>
+ <groupId>groupId</groupId>
+ <version>1.0</version>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/missing-dependency-exclusion-id.xml b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/missing-dependency-exclusion-id.xml
new file mode 100644
index 00000000..b9baada1
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/missing-dependency-exclusion-id.xml
@@ -0,0 +1,39 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>foo</artifactId>
+ <groupId>foo</groupId>
+ <version>99.44</version>
+ <packaging>jar</packaging>
+
+ <dependencies>
+ <dependency>
+ <groupId>gid</groupId>
+ <artifactId>aid</artifactId>
+ <version>1.0</version>
+ <exclusions>
+ <exclusion>
+ <groupId></groupId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/missing-dependency-groupId-pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/missing-dependency-groupId-pom.xml
new file mode 100644
index 00000000..5799c572
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/missing-dependency-groupId-pom.xml
@@ -0,0 +1,32 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>foo</artifactId>
+ <groupId>foo</groupId>
+ <version>99.44</version>
+ <packaging>bleh</packaging>
+ <dependencies>
+ <dependency>
+ <artifactId>artifactId</artifactId>
+ <version>1.0</version>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/missing-dependency-mgmt-artifactId-pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/missing-dependency-mgmt-artifactId-pom.xml
new file mode 100644
index 00000000..e050ef43
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/missing-dependency-mgmt-artifactId-pom.xml
@@ -0,0 +1,34 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>foo</artifactId>
+ <groupId>foo</groupId>
+ <version>99.44</version>
+ <packaging>bleh</packaging>
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>groupId</groupId>
+ <version>version</version>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/missing-dependency-mgmt-groupId-pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/missing-dependency-mgmt-groupId-pom.xml
new file mode 100644
index 00000000..a012d0f5
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/missing-dependency-mgmt-groupId-pom.xml
@@ -0,0 +1,34 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>foo</artifactId>
+ <groupId>foo</groupId>
+ <version>99.44</version>
+ <packaging>bleh</packaging>
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <artifactId>artifactId</artifactId>
+ <version>version</version>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/missing-dependency-mgmt-version-pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/missing-dependency-mgmt-version-pom.xml
new file mode 100644
index 00000000..cc5ff5b3
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/missing-dependency-mgmt-version-pom.xml
@@ -0,0 +1,34 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>foo</artifactId>
+ <groupId>foo</groupId>
+ <version>99.44</version>
+ <packaging>bleh</packaging>
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <artifactId>artifactId</artifactId>
+ <groupId>groupId</groupId>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/missing-dependency-version-pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/missing-dependency-version-pom.xml
new file mode 100644
index 00000000..217b036d
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/missing-dependency-version-pom.xml
@@ -0,0 +1,32 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>foo</artifactId>
+ <groupId>foo</groupId>
+ <version>99.44</version>
+ <packaging>bleh</packaging>
+ <dependencies>
+ <dependency>
+ <artifactId>artifactId</artifactId>
+ <groupId>groupId</groupId>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/missing-groupId-pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/missing-groupId-pom.xml
new file mode 100644
index 00000000..528b8b6a
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/missing-groupId-pom.xml
@@ -0,0 +1,25 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>bar</artifactId>
+ <version>99.44</version>
+ <packaging>bleh</packaging>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/missing-modelVersion-pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/missing-modelVersion-pom.xml
new file mode 100644
index 00000000..f0273d9e
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/missing-modelVersion-pom.xml
@@ -0,0 +1,25 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <groupId>foo</groupId>
+ <artifactId>foo</artifactId>
+ <version>99.44</version>
+ <packaging>bleh</packaging>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/missing-plugin-artifactId-pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/missing-plugin-artifactId-pom.xml
new file mode 100644
index 00000000..27e27d6b
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/missing-plugin-artifactId-pom.xml
@@ -0,0 +1,33 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>foo</artifactId>
+ <groupId>foo</groupId>
+ <version>99.44</version>
+ <packaging>bleh</packaging>
+ <build>
+ <plugins>
+ <plugin>
+ <version>1.0</version>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/missing-plugin-dependency-artifactId.xml b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/missing-plugin-dependency-artifactId.xml
new file mode 100644
index 00000000..5c21e363
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/missing-plugin-dependency-artifactId.xml
@@ -0,0 +1,41 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>aid</artifactId>
+ <groupId>gid</groupId>
+ <version>1.0</version>
+
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-it-plugin</artifactId>
+ <version>1.0</version>
+ <dependencies>
+ <dependency>
+ <groupId>test</groupId>
+ <!-- artifact id missing -->
+ <version>2.0</version>
+ </dependency>
+ </dependencies>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/missing-plugin-dependency-groupId.xml b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/missing-plugin-dependency-groupId.xml
new file mode 100644
index 00000000..831c05f2
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/missing-plugin-dependency-groupId.xml
@@ -0,0 +1,41 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>aid</artifactId>
+ <groupId>gid</groupId>
+ <version>1.0</version>
+
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-it-plugin</artifactId>
+ <version>1.0</version>
+ <dependencies>
+ <dependency>
+ <!-- groupd id missing -->
+ <artifactId>a</artifactId>
+ <version>2.0</version>
+ </dependency>
+ </dependencies>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/missing-plugin-dependency-version.xml b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/missing-plugin-dependency-version.xml
new file mode 100644
index 00000000..29e0b7e7
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/missing-plugin-dependency-version.xml
@@ -0,0 +1,41 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>aid</artifactId>
+ <groupId>gid</groupId>
+ <version>1.0</version>
+
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-it-plugin</artifactId>
+ <version>1.0</version>
+ <dependencies>
+ <dependency>
+ <groupId>test</groupId>
+ <artifactId>a</artifactId>
+ <!-- version missing -->
+ </dependency>
+ </dependencies>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/missing-plugin-version-pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/missing-plugin-version-pom.xml
new file mode 100644
index 00000000..b0ea7aa7
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/missing-plugin-version-pom.xml
@@ -0,0 +1,33 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>foo</artifactId>
+ <groupId>foo</groupId>
+ <version>99.44</version>
+ <packaging>bleh</packaging>
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-it-plugin</artifactId>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/missing-report-artifactId-pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/missing-report-artifactId-pom.xml
new file mode 100644
index 00000000..4cb5649c
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/missing-report-artifactId-pom.xml
@@ -0,0 +1,33 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>foo</artifactId>
+ <groupId>foo</groupId>
+ <version>99.44</version>
+ <packaging>bleh</packaging>
+ <reporting>
+ <plugins>
+ <plugin>
+
+ </plugin>
+ </plugins>
+ </reporting>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/missing-report-version-pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/missing-report-version-pom.xml
new file mode 100644
index 00000000..46a560f6
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/missing-report-version-pom.xml
@@ -0,0 +1,57 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>foo</artifactId>
+ <groupId>foo</groupId>
+ <version>99.44</version>
+ <packaging>bleh</packaging>
+
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <artifactId>maven-from-pluginManagement-plugin</artifactId>
+ <version>1.0</version>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ <plugins>
+ <plugin>
+ <artifactId>maven-from-plugins-plugin</artifactId>
+ <version>1.0</version>
+ </plugin>
+ </plugins>
+ </build>
+
+ <reporting>
+ <plugins>
+ <plugin>
+ <artifactId>maven-noversion-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <artifactId>maven-from-plugins-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <artifactId>maven-from-pluginManagement-plugin</artifactId>
+ </plugin>
+ </plugins>
+ </reporting>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/missing-repository-id-pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/missing-repository-id-pom.xml
new file mode 100644
index 00000000..1d385f29
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/missing-repository-id-pom.xml
@@ -0,0 +1,36 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>foo</artifactId>
+ <groupId>foo</groupId>
+ <version>99.44</version>
+ <packaging>bleh</packaging>
+ <repositories>
+ <repository>
+
+ </repository>
+ </repositories>
+ <pluginRepositories>
+ <pluginRepository>
+
+ </pluginRepository>
+ </pluginRepositories>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/missing-resource-directory-pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/missing-resource-directory-pom.xml
new file mode 100644
index 00000000..232db095
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/missing-resource-directory-pom.xml
@@ -0,0 +1,38 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>foo</artifactId>
+ <groupId>foo</groupId>
+ <version>99.44</version>
+ <packaging>bleh</packaging>
+ <build>
+ <resources>
+ <resource>
+
+ </resource>
+ </resources>
+ <testResources>
+ <testResource>
+
+ </testResource>
+ </testResources>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/missing-type-pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/missing-type-pom.xml
new file mode 100644
index 00000000..663e58ad
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/missing-type-pom.xml
@@ -0,0 +1,26 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>foo</groupId>
+ <artifactId>bar</artifactId>
+ <version>99.44</version>
+ <packaging></packaging>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/missing-version-pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/missing-version-pom.xml
new file mode 100644
index 00000000..2a111f19
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/missing-version-pom.xml
@@ -0,0 +1,25 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>foo</groupId>
+ <artifactId>bar</artifactId>
+ <packaging>bleh</packaging>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/reserved-repository-id.xml b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/reserved-repository-id.xml
new file mode 100644
index 00000000..90a6c88c
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model-builder/src/test/resources/poms/validation/reserved-repository-id.xml
@@ -0,0 +1,50 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>gid</groupId>
+ <artifactId>aid</artifactId>
+ <version>99.44</version>
+
+ <repositories>
+ <repository>
+ <id>local</id>
+ <url>http://localhost</url>
+ </repository>
+ </repositories>
+ <pluginRepositories>
+ <pluginRepository>
+ <id>local</id>
+ <url>http://localhost</url>
+ </pluginRepository>
+ </pluginRepositories>
+
+ <distributionManagement>
+ <repository>
+ <id>local</id>
+ <url>http://localhost</url>
+ </repository>
+ <snapshotRepository>
+ <id>local</id>
+ <url>http://localhost</url>
+ </snapshotRepository>
+ </distributionManagement>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-model/pom.xml
new file mode 100644
index 00000000..851c3e32
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model/pom.xml
@@ -0,0 +1,132 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven</artifactId>
+ <version>3.3.3</version>
+ </parent>
+
+ <artifactId>maven-model</artifactId>
+
+ <name>Maven Model</name>
+ <description>Model for Maven POM (Project Object Model)</description>
+
+ <scm><!-- remove when git scm url format can accept artifact-id at the end, as automatically inherited -->
+ <connection>scm:git:https://git-wip-us.apache.org/repos/asf/maven.git</connection>
+ <developerConnection>scm:git:https://git-wip-us.apache.org/repos/asf/maven.git</developerConnection>
+ <tag>maven-3.3.3</tag>
+ </scm>
+
+ <properties>
+ <checkstyle.violation.ignore>FileLength</checkstyle.violation.ignore>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-utils</artifactId>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.modello</groupId>
+ <artifactId>modello-maven-plugin</artifactId>
+ <configuration>
+ <version>4.0.0</version>
+ <models>
+ <model>src/main/mdo/maven.mdo</model>
+ </models>
+ </configuration>
+ <executions>
+ <execution>
+ <id>standard</id>
+ <goals>
+ <goal>java</goal>
+ <goal>xpp3-reader</goal>
+ <goal>xpp3-extended-reader</goal>
+ <goal>xpp3-writer</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-site-plugin</artifactId>
+ <configuration>
+ <!-- Exclude the navigation file for Maven 1 sites
+ as it interferes with the site generation. -->
+ <moduleExcludes>
+ <xdoc>navigation.xml</xdoc>
+ </moduleExcludes>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+ <profiles>
+ <profile>
+ <id>all-models</id>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.modello</groupId>
+ <artifactId>modello-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>v3</id>
+ <goals>
+ <goal>java</goal>
+ <goal>xpp3-writer</goal>
+ <goal>xpp3-reader</goal>
+ <goal>xsd</goal>
+ </goals>
+ <configuration>
+ <version>3.0.0</version>
+ <packageWithVersion>true</packageWithVersion>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <artifactId>maven-jar-plugin</artifactId>
+ <executions>
+ <execution>
+ <phase>package</phase>
+ <goals>
+ <goal>jar</goal>
+ </goals>
+ <configuration>
+ <classifier>all</classifier>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model/src/main/java/org/apache/maven/model/io/xpp3/package-info.java b/framework/src/maven/apache-maven-3.3.3/maven-model/src/main/java/org/apache/maven/model/io/xpp3/package-info.java
new file mode 100644
index 00000000..648607ce
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model/src/main/java/org/apache/maven/model/io/xpp3/package-info.java
@@ -0,0 +1,30 @@
+// CHECKSTYLE_OFF: RegexpHeader|LineLength
+/**
+ * XML reader and writer classes for Maven POM, generated from <code>maven.mdo</code> model.
+ * These classes use
+ * <a href="http://plexus.codehaus.org/plexus-utils/apidocs/org/codehaus/plexus/util/xml/pull/package-summary.html">plexus-utils'
+ * XML Pull Parser API</a> for their internal XML handling and
+ * <a href="http://plexus.codehaus.org/plexus-utils/apidocs/org/codehaus/plexus/util/xml/Xpp3DomBuilder.html">Xpp3DomBuilder</a> +
+ * <a href="http://plexus.codehaus.org/plexus-utils/apidocs/org/codehaus/plexus/util/xml/Xpp3Dom.html">Xpp3Dom</a> for
+ * DOM content representation (see <code>&lt;configuration&gt;</code> elements).
+ */
+package org.apache.maven.model.io.xpp3;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */ \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model/src/main/java/org/apache/maven/model/merge/ModelMerger.java b/framework/src/maven/apache-maven-3.3.3/maven-model/src/main/java/org/apache/maven/model/merge/ModelMerger.java
new file mode 100644
index 00000000..b671d981
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model/src/main/java/org/apache/maven/model/merge/ModelMerger.java
@@ -0,0 +1,2924 @@
+package org.apache.maven.model.merge;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.maven.model.Activation;
+import org.apache.maven.model.Build;
+import org.apache.maven.model.BuildBase;
+import org.apache.maven.model.CiManagement;
+import org.apache.maven.model.ConfigurationContainer;
+import org.apache.maven.model.Contributor;
+import org.apache.maven.model.Dependency;
+import org.apache.maven.model.DependencyManagement;
+import org.apache.maven.model.DeploymentRepository;
+import org.apache.maven.model.Developer;
+import org.apache.maven.model.DistributionManagement;
+import org.apache.maven.model.Exclusion;
+import org.apache.maven.model.Extension;
+import org.apache.maven.model.FileSet;
+import org.apache.maven.model.InputLocation;
+import org.apache.maven.model.IssueManagement;
+import org.apache.maven.model.License;
+import org.apache.maven.model.MailingList;
+import org.apache.maven.model.Model;
+import org.apache.maven.model.ModelBase;
+import org.apache.maven.model.Notifier;
+import org.apache.maven.model.Organization;
+import org.apache.maven.model.Parent;
+import org.apache.maven.model.PatternSet;
+import org.apache.maven.model.Plugin;
+import org.apache.maven.model.PluginConfiguration;
+import org.apache.maven.model.PluginContainer;
+import org.apache.maven.model.PluginExecution;
+import org.apache.maven.model.PluginManagement;
+import org.apache.maven.model.Prerequisites;
+import org.apache.maven.model.Profile;
+import org.apache.maven.model.Relocation;
+import org.apache.maven.model.ReportPlugin;
+import org.apache.maven.model.ReportSet;
+import org.apache.maven.model.Reporting;
+import org.apache.maven.model.Repository;
+import org.apache.maven.model.RepositoryBase;
+import org.apache.maven.model.RepositoryPolicy;
+import org.apache.maven.model.Resource;
+import org.apache.maven.model.Scm;
+import org.apache.maven.model.Site;
+import org.codehaus.plexus.util.xml.Xpp3Dom;
+
+/**
+ * This is a hand-crafted prototype of the default model merger that should eventually be generated by Modello by a new
+ * Java plugin. Code structure to merge source (read-only) object into the target object is:<ul>
+ * <li><code>merge<i>Classname</i>( <i>Classname</i> target, <i>Classname</i> source, boolean sourceDominant,
+ * Map<Object, Object> context )</code> for each model class</li>
+ * <li><code>merge<i>Classname</i>_<i>FieldName</i>( <i>Classname</i> target, <i>Classname</i> source, boolean
+ * sourceDominant, Map<Object, Object> context )</code> for each field of each model class</li>
+ * <li><code>Object get<i>Classname</i>Key( <i>Classname</i> <i>classname</i> )</code>
+ * for each class that is used in a list</li>
+ * </ul>
+ * Code is written like it could be generated, with default behaviour to be overridden when necessary.
+ * This is particularly the case for <code>Object get<i>Classname</i>Key( <i>Classname</i> <i>classname</i> )</code>
+ * method, which by default return the object itself and is expected to be overridden to calculate better suited key
+ * value.
+ *
+ * @author Benjamin Bentmann
+ */
+@SuppressWarnings( { "checkstyle:methodname" } )
+public class ModelMerger
+{
+
+ /**
+ * Merges the specified source object into the given target object.
+ *
+ * @param target The target object whose existing contents should be merged with the source, must not be
+ * <code>null</code>.
+ * @param source The (read-only) source object that should be merged into the target object, may be
+ * <code>null</code>.
+ * @param sourceDominant A flag indicating whether either the target object or the source object provides the
+ * dominant data.
+ * @param hints A set of key-value pairs that customized merger implementations can use to carry domain-specific
+ * information along, may be <code>null</code>.
+ */
+ public void merge( Model target, Model source, boolean sourceDominant, Map<?, ?> hints )
+ {
+ if ( target == null )
+ {
+ throw new IllegalArgumentException( "target missing" );
+ }
+
+ if ( source == null )
+ {
+ return;
+ }
+
+ Map<Object, Object> context = new HashMap<Object, Object>();
+ if ( hints != null )
+ {
+ context.putAll( hints );
+ }
+
+ mergeModel( target, source, sourceDominant, context );
+ }
+
+ protected void mergeModel( Model target, Model source, boolean sourceDominant, Map<Object, Object> context )
+ {
+ mergeModelBase( target, source, sourceDominant, context );
+
+ mergeModel_ModelVersion( target, source, sourceDominant, context );
+ mergeModel_Parent( target, source, sourceDominant, context );
+ mergeModel_GroupId( target, source, sourceDominant, context );
+ mergeModel_ArtifactId( target, source, sourceDominant, context );
+ mergeModel_Version( target, source, sourceDominant, context );
+ mergeModel_Packaging( target, source, sourceDominant, context );
+ mergeModel_Name( target, source, sourceDominant, context );
+ mergeModel_Description( target, source, sourceDominant, context );
+ mergeModel_Url( target, source, sourceDominant, context );
+ mergeModel_InceptionYear( target, source, sourceDominant, context );
+ mergeModel_Organization( target, source, sourceDominant, context );
+ mergeModel_Licenses( target, source, sourceDominant, context );
+ mergeModel_MailingLists( target, source, sourceDominant, context );
+ mergeModel_Developers( target, source, sourceDominant, context );
+ mergeModel_Contributors( target, source, sourceDominant, context );
+ mergeModel_IssueManagement( target, source, sourceDominant, context );
+ mergeModel_Scm( target, source, sourceDominant, context );
+ mergeModel_CiManagement( target, source, sourceDominant, context );
+ mergeModel_Prerequisites( target, source, sourceDominant, context );
+ mergeModel_Build( target, source, sourceDominant, context );
+ mergeModel_Profiles( target, source, sourceDominant, context );
+ }
+
+ protected void mergeModel_ModelVersion( Model target, Model source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ String src = source.getModelVersion();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getModelVersion() == null )
+ {
+ target.setModelVersion( src );
+ target.setLocation( "modelVersion", source.getLocation( "modelVersion" ) );
+ }
+ }
+ }
+
+ protected void mergeModel_Parent( Model target, Model source, boolean sourceDominant, Map<Object, Object> context )
+ {
+ Parent src = source.getParent();
+ if ( src != null )
+ {
+ Parent tgt = target.getParent();
+ if ( tgt == null )
+ {
+ tgt = new Parent();
+ tgt.setRelativePath( null );
+ target.setParent( tgt );
+ }
+ mergeParent( tgt, src, sourceDominant, context );
+ }
+ }
+
+ protected void mergeModel_GroupId( Model target, Model source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ String src = source.getGroupId();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getGroupId() == null )
+ {
+ target.setGroupId( src );
+ target.setLocation( "groupId", source.getLocation( "groupId" ) );
+ }
+ }
+ }
+
+ protected void mergeModel_ArtifactId( Model target, Model source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ String src = source.getArtifactId();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getArtifactId() == null )
+ {
+ target.setArtifactId( src );
+ target.setLocation( "artifactId", source.getLocation( "artifactId" ) );
+ }
+ }
+ }
+
+ protected void mergeModel_Version( Model target, Model source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ String src = source.getVersion();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getVersion() == null )
+ {
+ target.setVersion( src );
+ target.setLocation( "version", source.getLocation( "version" ) );
+ }
+ }
+ }
+
+ protected void mergeModel_Packaging( Model target, Model source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ String src = source.getPackaging();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getPackaging() == null )
+ {
+ target.setPackaging( src );
+ target.setLocation( "packaging", source.getLocation( "packaging" ) );
+ }
+ }
+ }
+
+ protected void mergeModel_Name( Model target, Model source, boolean sourceDominant, Map<Object, Object> context )
+ {
+ String src = source.getName();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getName() == null )
+ {
+ target.setName( src );
+ target.setLocation( "name", source.getLocation( "name" ) );
+ }
+ }
+ }
+
+ protected void mergeModel_Description( Model target, Model source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ String src = source.getDescription();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getDescription() == null )
+ {
+ target.setDescription( src );
+ target.setLocation( "description", source.getLocation( "description" ) );
+ }
+ }
+ }
+
+ protected void mergeModel_Url( Model target, Model source, boolean sourceDominant, Map<Object, Object> context )
+ {
+ String src = source.getUrl();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getUrl() == null )
+ {
+ target.setUrl( src );
+ target.setLocation( "url", source.getLocation( "url" ) );
+ }
+ }
+ }
+
+ protected void mergeModel_InceptionYear( Model target, Model source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ String src = source.getInceptionYear();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getInceptionYear() == null )
+ {
+ target.setInceptionYear( src );
+ target.setLocation( "inceptionYear", source.getLocation( "inceptionYear" ) );
+ }
+ }
+ }
+
+ protected void mergeModel_Organization( Model target, Model source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ Organization src = source.getOrganization();
+ if ( src != null )
+ {
+ Organization tgt = target.getOrganization();
+ if ( tgt == null )
+ {
+ tgt = new Organization();
+ target.setOrganization( tgt );
+ }
+ mergeOrganization( tgt, src, sourceDominant, context );
+ }
+ }
+
+ protected void mergeModel_Licenses( Model target, Model source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ List<License> src = source.getLicenses();
+ if ( !src.isEmpty() )
+ {
+ List<License> tgt = target.getLicenses();
+ Map<Object, License> merged = new LinkedHashMap<Object, License>( ( src.size() + tgt.size() ) * 2 );
+
+ for ( License element : tgt )
+ {
+ Object key = getLicenseKey( element );
+ merged.put( key, element );
+ }
+
+ for ( License element : src )
+ {
+ Object key = getLicenseKey( element );
+ if ( sourceDominant || !merged.containsKey( key ) )
+ {
+ merged.put( key, element );
+ }
+ }
+
+ target.setLicenses( new ArrayList<License>( merged.values() ) );
+ }
+ }
+
+ protected void mergeModel_MailingLists( Model target, Model source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ List<MailingList> src = source.getMailingLists();
+ if ( !src.isEmpty() )
+ {
+ List<MailingList> tgt = target.getMailingLists();
+ Map<Object, MailingList> merged = new LinkedHashMap<Object, MailingList>( ( src.size() + tgt.size() ) * 2 );
+
+ for ( MailingList element : tgt )
+ {
+ Object key = getMailingListKey( element );
+ merged.put( key, element );
+ }
+
+ for ( MailingList element : src )
+ {
+ Object key = getMailingListKey( element );
+ if ( sourceDominant || !merged.containsKey( key ) )
+ {
+ merged.put( key, element );
+ }
+ }
+
+ target.setMailingLists( new ArrayList<MailingList>( merged.values() ) );
+ }
+ }
+
+ protected void mergeModel_Developers( Model target, Model source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ List<Developer> src = source.getDevelopers();
+ if ( !src.isEmpty() )
+ {
+ List<Developer> tgt = target.getDevelopers();
+ Map<Object, Developer> merged = new LinkedHashMap<Object, Developer>( ( src.size() + tgt.size() ) * 2 );
+
+ for ( Developer element : tgt )
+ {
+ Object key = getDeveloperKey( element );
+ merged.put( key, element );
+ }
+
+ for ( Developer element : src )
+ {
+ Object key = getDeveloperKey( element );
+ if ( sourceDominant || !merged.containsKey( key ) )
+ {
+ merged.put( key, element );
+ }
+ }
+
+ target.setDevelopers( new ArrayList<Developer>( merged.values() ) );
+ }
+ }
+
+ protected void mergeModel_Contributors( Model target, Model source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ List<Contributor> src = source.getContributors();
+ if ( !src.isEmpty() )
+ {
+ List<Contributor> tgt = target.getContributors();
+ Map<Object, Contributor> merged = new LinkedHashMap<Object, Contributor>( ( src.size() + tgt.size() ) * 2 );
+
+ for ( Contributor element : tgt )
+ {
+ Object key = getContributorKey( element );
+ merged.put( key, element );
+ }
+
+ for ( Contributor element : src )
+ {
+ Object key = getContributorKey( element );
+ if ( sourceDominant || !merged.containsKey( key ) )
+ {
+ merged.put( key, element );
+ }
+ }
+
+ target.setContributors( new ArrayList<Contributor>( merged.values() ) );
+ }
+ }
+
+ protected void mergeModel_IssueManagement( Model target, Model source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ IssueManagement src = source.getIssueManagement();
+ if ( src != null )
+ {
+ IssueManagement tgt = target.getIssueManagement();
+ if ( tgt == null )
+ {
+ tgt = new IssueManagement();
+ target.setIssueManagement( tgt );
+ }
+ mergeIssueManagement( tgt, src, sourceDominant, context );
+ }
+ }
+
+ protected void mergeModel_Scm( Model target, Model source, boolean sourceDominant, Map<Object, Object> context )
+ {
+ Scm src = source.getScm();
+ if ( src != null )
+ {
+ Scm tgt = target.getScm();
+ if ( tgt == null )
+ {
+ tgt = new Scm();
+ tgt.setTag( null );
+ target.setScm( tgt );
+ }
+ mergeScm( tgt, src, sourceDominant, context );
+ }
+ }
+
+ protected void mergeModel_CiManagement( Model target, Model source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ CiManagement src = source.getCiManagement();
+ if ( src != null )
+ {
+ CiManagement tgt = target.getCiManagement();
+ if ( tgt == null )
+ {
+ tgt = new CiManagement();
+ target.setCiManagement( tgt );
+ }
+ mergeCiManagement( tgt, src, sourceDominant, context );
+ }
+ }
+
+ protected void mergeModel_Prerequisites( Model target, Model source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ Prerequisites src = source.getPrerequisites();
+ if ( src != null )
+ {
+ Prerequisites tgt = target.getPrerequisites();
+ if ( tgt == null )
+ {
+ tgt = new Prerequisites();
+ tgt.setMaven( null );
+ target.setPrerequisites( tgt );
+ }
+ mergePrerequisites( tgt, src, sourceDominant, context );
+ }
+ }
+
+ protected void mergeModel_Build( Model target, Model source, boolean sourceDominant, Map<Object, Object> context )
+ {
+ Build src = source.getBuild();
+ if ( src != null )
+ {
+ Build tgt = target.getBuild();
+ if ( tgt == null )
+ {
+ tgt = new Build();
+ target.setBuild( tgt );
+ }
+ mergeBuild( tgt, src, sourceDominant, context );
+ }
+ }
+
+ protected void mergeModel_Profiles( Model target, Model source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ List<Profile> src = source.getProfiles();
+ if ( !src.isEmpty() )
+ {
+ List<Profile> tgt = target.getProfiles();
+ Map<Object, Profile> merged = new LinkedHashMap<Object, Profile>( ( src.size() + tgt.size() ) * 2 );
+
+ for ( Profile element : tgt )
+ {
+ Object key = getProfileKey( element );
+ merged.put( key, element );
+ }
+
+ for ( Profile element : src )
+ {
+ Object key = getProfileKey( element );
+ if ( sourceDominant || !merged.containsKey( key ) )
+ {
+ merged.put( key, element );
+ }
+ }
+
+ target.setProfiles( new ArrayList<Profile>( merged.values() ) );
+ }
+ }
+
+ protected void mergeModelBase( ModelBase target, ModelBase source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ mergeModelBase_DistributionManagement( target, source, sourceDominant, context );
+ mergeModelBase_Modules( target, source, sourceDominant, context );
+ mergeModelBase_Repositories( target, source, sourceDominant, context );
+ mergeModelBase_PluginRepositories( target, source, sourceDominant, context );
+ mergeModelBase_Dependencies( target, source, sourceDominant, context );
+ mergeModelBase_Reporting( target, source, sourceDominant, context );
+ mergeModelBase_DependencyManagement( target, source, sourceDominant, context );
+ mergeModelBase_Properties( target, source, sourceDominant, context );
+ }
+
+ protected void mergeModelBase_Modules( ModelBase target, ModelBase source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ List<String> src = source.getModules();
+ if ( !src.isEmpty() )
+ {
+ List<String> tgt = target.getModules();
+ List<String> merged = new ArrayList<String>( tgt.size() + src.size() );
+ merged.addAll( tgt );
+ merged.addAll( src );
+ target.setModules( merged );
+ }
+ }
+
+ protected void mergeModelBase_Dependencies( ModelBase target, ModelBase source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ List<Dependency> src = source.getDependencies();
+ if ( !src.isEmpty() )
+ {
+ List<Dependency> tgt = target.getDependencies();
+ Map<Object, Dependency> merged = new LinkedHashMap<Object, Dependency>( ( src.size() + tgt.size() ) * 2 );
+
+ for ( Dependency element : tgt )
+ {
+ Object key = getDependencyKey( element );
+ merged.put( key, element );
+ }
+
+ for ( Dependency element : src )
+ {
+ Object key = getDependencyKey( element );
+ if ( sourceDominant || !merged.containsKey( key ) )
+ {
+ merged.put( key, element );
+ }
+ }
+
+ target.setDependencies( new ArrayList<Dependency>( merged.values() ) );
+ }
+ }
+
+ protected void mergeModelBase_Repositories( ModelBase target, ModelBase source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ List<Repository> src = source.getRepositories();
+ if ( !src.isEmpty() )
+ {
+ List<Repository> tgt = target.getRepositories();
+ Map<Object, Repository> merged = new LinkedHashMap<Object, Repository>( ( src.size() + tgt.size() ) * 2 );
+
+ for ( Repository element : tgt )
+ {
+ Object key = getRepositoryKey( element );
+ merged.put( key, element );
+ }
+
+ for ( Repository element : src )
+ {
+ Object key = getRepositoryKey( element );
+ if ( sourceDominant || !merged.containsKey( key ) )
+ {
+ merged.put( key, element );
+ }
+ }
+
+ target.setRepositories( new ArrayList<Repository>( merged.values() ) );
+ }
+ }
+
+ protected void mergeModelBase_PluginRepositories( ModelBase target, ModelBase source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ List<Repository> src = source.getPluginRepositories();
+ if ( !src.isEmpty() )
+ {
+ List<Repository> tgt = target.getPluginRepositories();
+ Map<Object, Repository> merged = new LinkedHashMap<Object, Repository>( ( src.size() + tgt.size() ) * 2 );
+
+ for ( Repository element : tgt )
+ {
+ Object key = getRepositoryKey( element );
+ merged.put( key, element );
+ }
+
+ for ( Repository element : src )
+ {
+ Object key = getRepositoryKey( element );
+ if ( sourceDominant || !merged.containsKey( key ) )
+ {
+ merged.put( key, element );
+ }
+ }
+
+ target.setPluginRepositories( new ArrayList<Repository>( merged.values() ) );
+ }
+ }
+
+ protected void mergeModelBase_DistributionManagement( ModelBase target, ModelBase source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ DistributionManagement src = source.getDistributionManagement();
+ if ( src != null )
+ {
+ DistributionManagement tgt = target.getDistributionManagement();
+ if ( tgt == null )
+ {
+ tgt = new DistributionManagement();
+ target.setDistributionManagement( tgt );
+ }
+ mergeDistributionManagement( tgt, src, sourceDominant, context );
+ }
+ }
+
+ protected void mergeModelBase_Reporting( ModelBase target, ModelBase source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ Reporting src = source.getReporting();
+ if ( src != null )
+ {
+ Reporting tgt = target.getReporting();
+ if ( tgt == null )
+ {
+ tgt = new Reporting();
+ target.setReporting( tgt );
+ }
+ mergeReporting( tgt, src, sourceDominant, context );
+ }
+ }
+
+ protected void mergeModelBase_DependencyManagement( ModelBase target, ModelBase source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ DependencyManagement src = source.getDependencyManagement();
+ if ( src != null )
+ {
+ DependencyManagement tgt = target.getDependencyManagement();
+ if ( tgt == null )
+ {
+ tgt = new DependencyManagement();
+ target.setDependencyManagement( tgt );
+ }
+ mergeDependencyManagement( tgt, src, sourceDominant, context );
+ }
+ }
+
+ protected void mergeModelBase_Properties( ModelBase target, ModelBase source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ Properties merged = new Properties();
+ if ( sourceDominant )
+ {
+ merged.putAll( target.getProperties() );
+ merged.putAll( source.getProperties() );
+ }
+ else
+ {
+ merged.putAll( source.getProperties() );
+ merged.putAll( target.getProperties() );
+ }
+ target.setProperties( merged );
+ target.setLocation( "properties", InputLocation.merge( target.getLocation( "properties" ),
+ source.getLocation( "properties" ), sourceDominant ) );
+ }
+
+ protected void mergeDistributionManagement( DistributionManagement target, DistributionManagement source,
+ boolean sourceDominant, Map<Object, Object> context )
+ {
+ mergeDistributionManagement_Repository( target, source, sourceDominant, context );
+ mergeDistributionManagement_SnapshotRepository( target, source, sourceDominant, context );
+ mergeDistributionManagement_Site( target, source, sourceDominant, context );
+ mergeDistributionManagement_Status( target, source, sourceDominant, context );
+ mergeDistributionManagement_DownloadUrl( target, source, sourceDominant, context );
+ }
+
+ protected void mergeDistributionManagement_Repository( DistributionManagement target,
+ DistributionManagement source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ DeploymentRepository src = source.getRepository();
+ if ( src != null )
+ {
+ DeploymentRepository tgt = target.getRepository();
+ if ( tgt == null )
+ {
+ tgt = new DeploymentRepository();
+ target.setRepository( tgt );
+ }
+ mergeDeploymentRepository( tgt, src, sourceDominant, context );
+ }
+ }
+
+ protected void mergeDistributionManagement_SnapshotRepository( DistributionManagement target,
+ DistributionManagement source,
+ boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ DeploymentRepository src = source.getSnapshotRepository();
+ if ( src != null )
+ {
+ DeploymentRepository tgt = target.getSnapshotRepository();
+ if ( tgt == null )
+ {
+ tgt = new DeploymentRepository();
+ target.setSnapshotRepository( tgt );
+ }
+ mergeDeploymentRepository( tgt, src, sourceDominant, context );
+ }
+ }
+
+ protected void mergeDistributionManagement_Site( DistributionManagement target, DistributionManagement source,
+ boolean sourceDominant, Map<Object, Object> context )
+ {
+ Site src = source.getSite();
+ if ( src != null )
+ {
+ Site tgt = target.getSite();
+ if ( tgt == null )
+ {
+ tgt = new Site();
+ target.setSite( tgt );
+ }
+ mergeSite( tgt, src, sourceDominant, context );
+ }
+ }
+
+ protected void mergeDistributionManagement_Status( DistributionManagement target, DistributionManagement source,
+ boolean sourceDominant, Map<Object, Object> context )
+ {
+ String src = source.getStatus();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getStatus() == null )
+ {
+ target.setStatus( src );
+ target.setLocation( "status", source.getLocation( "status" ) );
+ }
+ }
+ }
+
+ protected void mergeDistributionManagement_DownloadUrl( DistributionManagement target,
+ DistributionManagement source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ String src = source.getDownloadUrl();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getDownloadUrl() == null )
+ {
+ target.setDownloadUrl( src );
+ target.setLocation( "downloadUrl", source.getLocation( "downloadUrl" ) );
+ }
+ }
+ }
+
+ protected void mergeRelocation( Relocation target, Relocation source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ mergeRelocation_GroupId( target, source, sourceDominant, context );
+ mergeRelocation_ArtifactId( target, source, sourceDominant, context );
+ mergeRelocation_Version( target, source, sourceDominant, context );
+ mergeRelocation_Message( target, source, sourceDominant, context );
+ }
+
+ protected void mergeRelocation_GroupId( Relocation target, Relocation source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ String src = source.getGroupId();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getGroupId() == null )
+ {
+ target.setGroupId( src );
+ target.setLocation( "groupId", source.getLocation( "groupId" ) );
+ }
+ }
+ }
+
+ protected void mergeRelocation_ArtifactId( Relocation target, Relocation source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ String src = source.getArtifactId();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getArtifactId() == null )
+ {
+ target.setArtifactId( src );
+ target.setLocation( "artifactId", source.getLocation( "artifactId" ) );
+ }
+ }
+ }
+
+ protected void mergeRelocation_Version( Relocation target, Relocation source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ String src = source.getVersion();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getVersion() == null )
+ {
+ target.setVersion( src );
+ target.setLocation( "version", source.getLocation( "version" ) );
+ }
+ }
+ }
+
+ protected void mergeRelocation_Message( Relocation target, Relocation source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ String src = source.getMessage();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getMessage() == null )
+ {
+ target.setMessage( src );
+ target.setLocation( "message", source.getLocation( "message" ) );
+ }
+ }
+ }
+
+ protected void mergeDeploymentRepository( DeploymentRepository target, DeploymentRepository source,
+ boolean sourceDominant, Map<Object, Object> context )
+ {
+ mergeRepository( target, source, sourceDominant, context );
+ mergeDeploymentRepository_UniqueVersion( target, source, sourceDominant, context );
+ }
+
+ protected void mergeDeploymentRepository_UniqueVersion( DeploymentRepository target, DeploymentRepository source,
+ boolean sourceDominant, Map<Object, Object> context )
+ {
+ if ( sourceDominant )
+ {
+ target.setUniqueVersion( source.isUniqueVersion() );
+ target.setLocation( "uniqueVersion", source.getLocation( "uniqueVersion" ) );
+ }
+ }
+
+ protected void mergeSite( Site target, Site source, boolean sourceDominant, Map<Object, Object> context )
+ {
+ mergeSite_Id( target, source, sourceDominant, context );
+ mergeSite_Name( target, source, sourceDominant, context );
+ mergeSite_Url( target, source, sourceDominant, context );
+ }
+
+ protected void mergeSite_Id( Site target, Site source, boolean sourceDominant, Map<Object, Object> context )
+ {
+ String src = source.getId();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getId() == null )
+ {
+ target.setId( src );
+ target.setLocation( "id", source.getLocation( "id" ) );
+ }
+ }
+ }
+
+ protected void mergeSite_Name( Site target, Site source, boolean sourceDominant, Map<Object, Object> context )
+ {
+ String src = source.getName();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getName() == null )
+ {
+ target.setName( src );
+ target.setLocation( "name", source.getLocation( "name" ) );
+ }
+ }
+ }
+
+ protected void mergeSite_Url( Site target, Site source, boolean sourceDominant, Map<Object, Object> context )
+ {
+ String src = source.getUrl();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getUrl() == null )
+ {
+ target.setUrl( src );
+ target.setLocation( "url", source.getLocation( "url" ) );
+ }
+ }
+ }
+
+ protected void mergeRepository( Repository target, Repository source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ mergeRepositoryBase( target, source, sourceDominant, context );
+ mergeRepository_Releases( target, source, sourceDominant, context );
+ mergeRepository_Snapshots( target, source, sourceDominant, context );
+ }
+
+ protected void mergeRepository_Releases( Repository target, Repository source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ RepositoryPolicy src = source.getReleases();
+ if ( src != null )
+ {
+ RepositoryPolicy tgt = target.getReleases();
+ if ( tgt == null )
+ {
+ tgt = new RepositoryPolicy();
+ target.setReleases( tgt );
+ }
+ mergeRepositoryPolicy( tgt, src, sourceDominant, context );
+ }
+ }
+
+ protected void mergeRepository_Snapshots( Repository target, Repository source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ RepositoryPolicy src = source.getSnapshots();
+ if ( src != null )
+ {
+ RepositoryPolicy tgt = target.getSnapshots();
+ if ( tgt == null )
+ {
+ tgt = new RepositoryPolicy();
+ target.setSnapshots( tgt );
+ }
+ mergeRepositoryPolicy( tgt, src, sourceDominant, context );
+ }
+ }
+
+ protected void mergeRepositoryBase( RepositoryBase target, RepositoryBase source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ mergeRepositoryBase_Id( target, source, sourceDominant, context );
+ mergeRepositoryBase_Name( target, source, sourceDominant, context );
+ mergeRepositoryBase_Url( target, source, sourceDominant, context );
+ mergeRepositoryBase_Layout( target, source, sourceDominant, context );
+ }
+
+ protected void mergeRepositoryBase_Id( RepositoryBase target, RepositoryBase source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ String src = source.getId();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getId() == null )
+ {
+ target.setId( src );
+ target.setLocation( "id", source.getLocation( "id" ) );
+ }
+ }
+ }
+
+ protected void mergeRepositoryBase_Url( RepositoryBase target, RepositoryBase source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ String src = source.getUrl();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getUrl() == null )
+ {
+ target.setUrl( src );
+ target.setLocation( "url", source.getLocation( "url" ) );
+ }
+ }
+ }
+
+ protected void mergeRepositoryBase_Name( RepositoryBase target, RepositoryBase source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ String src = source.getName();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getName() == null )
+ {
+ target.setName( src );
+ target.setLocation( "name", source.getLocation( "name" ) );
+ }
+ }
+ }
+
+ protected void mergeRepositoryBase_Layout( RepositoryBase target, RepositoryBase source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ String src = source.getLayout();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getLayout() == null )
+ {
+ target.setLayout( src );
+ target.setLocation( "layout", source.getLocation( "layout" ) );
+ }
+ }
+ }
+
+ protected void mergeRepositoryPolicy( RepositoryPolicy target, RepositoryPolicy source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ mergeRepositoryPolicy_Enabled( target, source, sourceDominant, context );
+ mergeRepositoryPolicy_UpdatePolicy( target, source, sourceDominant, context );
+ mergeRepositoryPolicy_ChecksumPolicy( target, source, sourceDominant, context );
+ }
+
+ protected void mergeRepositoryPolicy_Enabled( RepositoryPolicy target, RepositoryPolicy source,
+ boolean sourceDominant, Map<Object, Object> context )
+ {
+ String src = source.getEnabled();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getEnabled() == null )
+ {
+ target.setEnabled( src );
+ target.setLocation( "enabled", source.getLocation( "enabled" ) );
+ }
+ }
+ }
+
+ protected void mergeRepositoryPolicy_UpdatePolicy( RepositoryPolicy target, RepositoryPolicy source,
+ boolean sourceDominant, Map<Object, Object> context )
+ {
+ String src = source.getUpdatePolicy();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getUpdatePolicy() == null )
+ {
+ target.setUpdatePolicy( src );
+ target.setLocation( "updatePolicy", source.getLocation( "updatePolicy" ) );
+ }
+ }
+ }
+
+ protected void mergeRepositoryPolicy_ChecksumPolicy( RepositoryPolicy target, RepositoryPolicy source,
+ boolean sourceDominant, Map<Object, Object> context )
+ {
+ String src = source.getChecksumPolicy();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getChecksumPolicy() == null )
+ {
+ target.setChecksumPolicy( src );
+ target.setLocation( "checksumPolicy", source.getLocation( "checksumPolicy" ) );
+ }
+ }
+ }
+
+ protected void mergeDependency( Dependency target, Dependency source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ mergeDependency_GroupId( target, source, sourceDominant, context );
+ mergeDependency_ArtifactId( target, source, sourceDominant, context );
+ mergeDependency_Version( target, source, sourceDominant, context );
+ mergeDependency_Type( target, source, sourceDominant, context );
+ mergeDependency_Classifier( target, source, sourceDominant, context );
+ mergeDependency_Scope( target, source, sourceDominant, context );
+ mergeDependency_SystemPath( target, source, sourceDominant, context );
+ mergeDependency_Optional( target, source, sourceDominant, context );
+ mergeDependency_Exclusions( target, source, sourceDominant, context );
+ }
+
+ protected void mergeDependency_GroupId( Dependency target, Dependency source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ String src = source.getGroupId();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getGroupId() == null )
+ {
+ target.setGroupId( src );
+ target.setLocation( "groupId", source.getLocation( "groupId" ) );
+ }
+ }
+ }
+
+ protected void mergeDependency_ArtifactId( Dependency target, Dependency source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ String src = source.getArtifactId();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getArtifactId() == null )
+ {
+ target.setArtifactId( src );
+ target.setLocation( "artifactId", source.getLocation( "artifactId" ) );
+ }
+ }
+ }
+
+ protected void mergeDependency_Version( Dependency target, Dependency source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ String src = source.getVersion();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getVersion() == null )
+ {
+ target.setVersion( src );
+ target.setLocation( "version", source.getLocation( "version" ) );
+ }
+ }
+ }
+
+ protected void mergeDependency_Type( Dependency target, Dependency source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ String src = source.getType();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getType() == null )
+ {
+ target.setType( src );
+ target.setLocation( "type", source.getLocation( "type" ) );
+ }
+ }
+ }
+
+ protected void mergeDependency_Classifier( Dependency target, Dependency source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ String src = source.getClassifier();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getClassifier() == null )
+ {
+ target.setClassifier( src );
+ target.setLocation( "classifier", source.getLocation( "classifier" ) );
+ }
+ }
+ }
+
+ protected void mergeDependency_Scope( Dependency target, Dependency source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ String src = source.getScope();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getScope() == null )
+ {
+ target.setScope( src );
+ target.setLocation( "scope", source.getLocation( "scope" ) );
+ }
+ }
+ }
+
+ protected void mergeDependency_SystemPath( Dependency target, Dependency source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ String src = source.getSystemPath();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getSystemPath() == null )
+ {
+ target.setSystemPath( src );
+ target.setLocation( "systemPath", source.getLocation( "systemPath" ) );
+ }
+ }
+ }
+
+ protected void mergeDependency_Optional( Dependency target, Dependency source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ String src = source.getOptional();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getOptional() == null )
+ {
+ target.setOptional( src );
+ target.setLocation( "optional", source.getLocation( "optional" ) );
+ }
+ }
+ }
+
+ protected void mergeDependency_Exclusions( Dependency target, Dependency source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ List<Exclusion> src = source.getExclusions();
+ if ( !src.isEmpty() )
+ {
+ List<Exclusion> tgt = target.getExclusions();
+
+ Map<Object, Exclusion> merged = new LinkedHashMap<Object, Exclusion>( ( src.size() + tgt.size() ) * 2 );
+
+ for ( Exclusion element : tgt )
+ {
+ Object key = getExclusionKey( element );
+ merged.put( key, element );
+ }
+
+ for ( Exclusion element : src )
+ {
+ Object key = getExclusionKey( element );
+ if ( sourceDominant || !merged.containsKey( key ) )
+ {
+ merged.put( key, element );
+ }
+ }
+
+ target.setExclusions( new ArrayList<Exclusion>( merged.values() ) );
+ }
+ }
+
+ protected void mergeExclusion( Exclusion target, Exclusion source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ mergeExclusion_GroupId( target, source, sourceDominant, context );
+ mergeExclusion_ArtifactId( target, source, sourceDominant, context );
+ }
+
+ protected void mergeExclusion_GroupId( Exclusion target, Exclusion source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ String src = source.getGroupId();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getGroupId() == null )
+ {
+ target.setGroupId( src );
+ target.setLocation( "groupId", source.getLocation( "groupId" ) );
+ }
+ }
+ }
+
+ protected void mergeExclusion_ArtifactId( Exclusion target, Exclusion source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ String src = source.getArtifactId();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getArtifactId() == null )
+ {
+ target.setArtifactId( src );
+ target.setLocation( "artifactId", source.getLocation( "artifactId" ) );
+ }
+ }
+ }
+
+ protected void mergeReporting( Reporting target, Reporting source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ mergeReporting_OutputDirectory( target, source, sourceDominant, context );
+ mergeReporting_ExcludeDefaults( target, source, sourceDominant, context );
+ mergeReporting_Plugins( target, source, sourceDominant, context );
+ }
+
+ protected void mergeReporting_OutputDirectory( Reporting target, Reporting source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ String src = source.getOutputDirectory();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getOutputDirectory() == null )
+ {
+ target.setOutputDirectory( src );
+ target.setLocation( "outputDirectory", source.getLocation( "outputDirectory" ) );
+ }
+ }
+ }
+
+ protected void mergeReporting_ExcludeDefaults( Reporting target, Reporting source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ String src = source.getExcludeDefaults();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getExcludeDefaults() == null )
+ {
+ target.setExcludeDefaults( src );
+ target.setLocation( "excludeDefaults", source.getLocation( "excludeDefaults" ) );
+ }
+ }
+ }
+
+ protected void mergeReporting_Plugins( Reporting target, Reporting source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ List<ReportPlugin> src = source.getPlugins();
+ if ( !src.isEmpty() )
+ {
+ List<ReportPlugin> tgt = target.getPlugins();
+ Map<Object, ReportPlugin> merged =
+ new LinkedHashMap<Object, ReportPlugin>( ( src.size() + tgt.size() ) * 2 );
+
+ for ( ReportPlugin element : tgt )
+ {
+ Object key = getReportPluginKey( element );
+ merged.put( key, element );
+ }
+
+ for ( ReportPlugin element : src )
+ {
+ Object key = getReportPluginKey( element );
+ if ( sourceDominant || !merged.containsKey( key ) )
+ {
+ merged.put( key, element );
+ }
+ }
+
+ target.setPlugins( new ArrayList<ReportPlugin>( merged.values() ) );
+ }
+ }
+
+ protected void mergeReportPlugin( ReportPlugin target, ReportPlugin source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ mergeConfigurationContainer( target, source, sourceDominant, context );
+ mergeReportPlugin_GroupId( target, source, sourceDominant, context );
+ mergeReportPlugin_ArtifactId( target, source, sourceDominant, context );
+ mergeReportPlugin_Version( target, source, sourceDominant, context );
+ mergeReportPlugin_ReportSets( target, source, sourceDominant, context );
+ }
+
+ protected void mergeReportPlugin_GroupId( ReportPlugin target, ReportPlugin source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ String src = source.getGroupId();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getGroupId() == null )
+ {
+ target.setGroupId( src );
+ target.setLocation( "groupId", source.getLocation( "groupId" ) );
+ }
+ }
+ }
+
+ protected void mergeReportPlugin_ArtifactId( ReportPlugin target, ReportPlugin source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ String src = source.getArtifactId();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getArtifactId() == null )
+ {
+ target.setArtifactId( src );
+ target.setLocation( "artifactId", source.getLocation( "artifactId" ) );
+ }
+ }
+ }
+
+ protected void mergeReportPlugin_Version( ReportPlugin target, ReportPlugin source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ String src = source.getVersion();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getVersion() == null )
+ {
+ target.setVersion( src );
+ target.setLocation( "version", source.getLocation( "version" ) );
+ }
+ }
+ }
+
+ protected void mergeReportPlugin_ReportSets( ReportPlugin target, ReportPlugin source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ List<ReportSet> src = source.getReportSets();
+ if ( !src.isEmpty() )
+ {
+ List<ReportSet> tgt = target.getReportSets();
+ Map<Object, ReportSet> merged = new LinkedHashMap<Object, ReportSet>( ( src.size() + tgt.size() ) * 2 );
+
+ for ( ReportSet element : tgt )
+ {
+ Object key = getReportSetKey( element );
+ merged.put( key, element );
+ }
+
+ for ( ReportSet element : src )
+ {
+ Object key = getReportSetKey( element );
+ if ( sourceDominant || !merged.containsKey( key ) )
+ {
+ merged.put( key, element );
+ }
+ }
+
+ target.setReportSets( new ArrayList<ReportSet>( merged.values() ) );
+ }
+ }
+
+ protected void mergeReportSet( ReportSet target, ReportSet source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ mergeConfigurationContainer( target, source, sourceDominant, context );
+ mergeReportSet_Id( target, source, sourceDominant, context );
+ mergeReportSet_Reports( target, source, sourceDominant, context );
+ }
+
+ protected void mergeReportSet_Id( ReportSet target, ReportSet source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ String src = source.getId();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getId() == null )
+ {
+ target.setId( src );
+ target.setLocation( "id", source.getLocation( "id" ) );
+ }
+ }
+ }
+
+ protected void mergeReportSet_Reports( ReportSet target, ReportSet source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ List<String> src = source.getReports();
+ if ( !src.isEmpty() )
+ {
+ List<String> tgt = target.getReports();
+ List<String> merged = new ArrayList<String>( tgt.size() + src.size() );
+ merged.addAll( tgt );
+ merged.addAll( src );
+ target.setReports( merged );
+ }
+ }
+
+ protected void mergeDependencyManagement( DependencyManagement target, DependencyManagement source,
+ boolean sourceDominant, Map<Object, Object> context )
+ {
+ mergeDependencyManagement_Dependencies( target, source, sourceDominant, context );
+ }
+
+ protected void mergeDependencyManagement_Dependencies( DependencyManagement target, DependencyManagement source,
+ boolean sourceDominant, Map<Object, Object> context )
+ {
+ List<Dependency> src = source.getDependencies();
+ if ( !src.isEmpty() )
+ {
+ List<Dependency> tgt = target.getDependencies();
+ Map<Object, Dependency> merged = new LinkedHashMap<Object, Dependency>( ( src.size() + tgt.size() ) * 2 );
+
+ for ( Dependency element : tgt )
+ {
+ Object key = getDependencyKey( element );
+ merged.put( key, element );
+ }
+
+ for ( Dependency element : src )
+ {
+ Object key = getDependencyKey( element );
+ if ( sourceDominant || !merged.containsKey( key ) )
+ {
+ merged.put( key, element );
+ }
+ }
+
+ target.setDependencies( new ArrayList<Dependency>( merged.values() ) );
+ }
+ }
+
+ protected void mergeParent( Parent target, Parent source, boolean sourceDominant, Map<Object, Object> context )
+ {
+ mergeParent_GroupId( target, source, sourceDominant, context );
+ mergeParent_ArtifactId( target, source, sourceDominant, context );
+ mergeParent_Version( target, source, sourceDominant, context );
+ mergeParent_RelativePath( target, source, sourceDominant, context );
+ }
+
+ protected void mergeParent_GroupId( Parent target, Parent source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ String src = source.getGroupId();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getGroupId() == null )
+ {
+ target.setGroupId( src );
+ target.setLocation( "groupId", source.getLocation( "groupId" ) );
+ }
+ }
+ }
+
+ protected void mergeParent_ArtifactId( Parent target, Parent source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ String src = source.getArtifactId();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getArtifactId() == null )
+ {
+ target.setArtifactId( src );
+ target.setLocation( "artifactId", source.getLocation( "artifactId" ) );
+ }
+ }
+ }
+
+ protected void mergeParent_Version( Parent target, Parent source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ String src = source.getVersion();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getVersion() == null )
+ {
+ target.setVersion( src );
+ target.setLocation( "version", source.getLocation( "version" ) );
+ }
+ }
+ }
+
+ protected void mergeParent_RelativePath( Parent target, Parent source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ String src = source.getRelativePath();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getRelativePath() == null )
+ {
+ target.setRelativePath( src );
+ target.setLocation( "relativePath", source.getLocation( "relativePath" ) );
+ }
+ }
+ }
+
+ protected void mergeOrganization( Organization target, Organization source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ mergeOrganization_Name( target, source, sourceDominant, context );
+ mergeOrganization_Url( target, source, sourceDominant, context );
+ }
+
+ protected void mergeOrganization_Name( Organization target, Organization source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ String src = source.getName();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getName() == null )
+ {
+ target.setName( src );
+ target.setLocation( "name", source.getLocation( "name" ) );
+ }
+ }
+ }
+
+ protected void mergeOrganization_Url( Organization target, Organization source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ String src = source.getUrl();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getUrl() == null )
+ {
+ target.setUrl( src );
+ target.setLocation( "url", source.getLocation( "url" ) );
+ }
+ }
+ }
+
+ protected void mergeLicense( License target, License source, boolean sourceDominant, Map<Object, Object> context )
+ {
+ mergeLicense_Name( target, source, sourceDominant, context );
+ mergeLicense_Url( target, source, sourceDominant, context );
+ mergeLicense_Distribution( target, source, sourceDominant, context );
+ mergeLicense_Comments( target, source, sourceDominant, context );
+ }
+
+ protected void mergeLicense_Name( License target, License source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ String src = source.getName();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getName() == null )
+ {
+ target.setName( src );
+ target.setLocation( "name", source.getLocation( "name" ) );
+ }
+ }
+ }
+
+ protected void mergeLicense_Url( License target, License source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ String src = source.getUrl();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getUrl() == null )
+ {
+ target.setUrl( src );
+ target.setLocation( "url", source.getLocation( "url" ) );
+ }
+ }
+ }
+
+ protected void mergeLicense_Distribution( License target, License source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ String src = source.getDistribution();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getDistribution() == null )
+ {
+ target.setDistribution( src );
+ target.setLocation( "distribution", source.getLocation( "distribution" ) );
+ }
+ }
+ }
+
+ protected void mergeLicense_Comments( License target, License source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ String src = source.getComments();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getComments() == null )
+ {
+ target.setComments( src );
+ target.setLocation( "comments", source.getLocation( "comments" ) );
+ }
+ }
+ }
+
+ protected void mergeMailingList( MailingList target, MailingList source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ mergeMailingList_Name( target, source, sourceDominant, context );
+ mergeMailingList_Subscribe( target, source, sourceDominant, context );
+ mergeMailingList_Unsubscribe( target, source, sourceDominant, context );
+ mergeMailingList_Post( target, source, sourceDominant, context );
+ mergeMailingList_OtherArchives( target, source, sourceDominant, context );
+ }
+
+ protected void mergeMailingList_Name( MailingList target, MailingList source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ String src = source.getName();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getName() == null )
+ {
+ target.setName( src );
+ target.setLocation( "name", source.getLocation( "name" ) );
+ }
+ }
+ }
+
+ protected void mergeMailingList_Subscribe( MailingList target, MailingList source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ String src = source.getSubscribe();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getSubscribe() == null )
+ {
+ target.setSubscribe( src );
+ target.setLocation( "subscribe", source.getLocation( "subscribe" ) );
+ }
+ }
+ }
+
+ protected void mergeMailingList_Unsubscribe( MailingList target, MailingList source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ String src = source.getUnsubscribe();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getUnsubscribe() == null )
+ {
+ target.setUnsubscribe( src );
+ target.setLocation( "unsubscribe", source.getLocation( "unsubscribe" ) );
+ }
+ }
+ }
+
+ protected void mergeMailingList_Post( MailingList target, MailingList source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ String src = source.getPost();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getPost() == null )
+ {
+ target.setPost( src );
+ target.setLocation( "post", source.getLocation( "post" ) );
+ }
+ }
+ }
+
+ protected void mergeMailingList_Archive( MailingList target, MailingList source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ String src = source.getArchive();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getArchive() == null )
+ {
+ target.setArchive( src );
+ target.setLocation( "archive", source.getLocation( "archive" ) );
+ }
+ }
+ }
+
+ protected void mergeMailingList_OtherArchives( MailingList target, MailingList source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ List<String> src = source.getOtherArchives();
+ if ( !src.isEmpty() )
+ {
+ List<String> tgt = target.getOtherArchives();
+ List<String> merged = new ArrayList<String>( tgt.size() + src.size() );
+ merged.addAll( tgt );
+ merged.addAll( src );
+ target.setOtherArchives( merged );
+ }
+ }
+
+ protected void mergeDeveloper( Developer target, Developer source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ mergeContributor( target, source, sourceDominant, context );
+ mergeDeveloper_Id( target, source, sourceDominant, context );
+ }
+
+ protected void mergeDeveloper_Id( Developer target, Developer source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ String src = source.getId();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getId() == null )
+ {
+ target.setId( src );
+ target.setLocation( "id", source.getLocation( "id" ) );
+ }
+ }
+ }
+
+ protected void mergeContributor( Contributor target, Contributor source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ mergeContributor_Name( target, source, sourceDominant, context );
+ mergeContributor_Email( target, source, sourceDominant, context );
+ mergeContributor_Url( target, source, sourceDominant, context );
+ mergeContributor_Organization( target, source, sourceDominant, context );
+ mergeContributor_OrganizationUrl( target, source, sourceDominant, context );
+ mergeContributor_Timezone( target, source, sourceDominant, context );
+ mergeContributor_Roles( target, source, sourceDominant, context );
+ mergeContributor_Properties( target, source, sourceDominant, context );
+ }
+
+ protected void mergeContributor_Name( Contributor target, Contributor source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ String src = source.getName();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getName() == null )
+ {
+ target.setName( src );
+ target.setLocation( "name", source.getLocation( "name" ) );
+ }
+ }
+ }
+
+ protected void mergeContributor_Email( Contributor target, Contributor source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ String src = source.getEmail();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getEmail() == null )
+ {
+ target.setEmail( src );
+ target.setLocation( "email", source.getLocation( "email" ) );
+ }
+ }
+ }
+
+ protected void mergeContributor_Url( Contributor target, Contributor source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ String src = source.getUrl();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getUrl() == null )
+ {
+ target.setUrl( src );
+ target.setLocation( "url", source.getLocation( "url" ) );
+ }
+ }
+ }
+
+ protected void mergeContributor_Organization( Contributor target, Contributor source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ String src = source.getOrganization();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getOrganization() == null )
+ {
+ target.setOrganization( src );
+ target.setLocation( "organization", source.getLocation( "organization" ) );
+ }
+ }
+ }
+
+ protected void mergeContributor_OrganizationUrl( Contributor target, Contributor source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ String src = source.getOrganizationUrl();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getOrganizationUrl() == null )
+ {
+ target.setOrganizationUrl( src );
+ target.setLocation( "organizationUrl", source.getLocation( "organizationUrl" ) );
+ }
+ }
+ }
+
+ protected void mergeContributor_Timezone( Contributor target, Contributor source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ String src = source.getTimezone();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getTimezone() == null )
+ {
+ target.setTimezone( src );
+ target.setLocation( "timezone", source.getLocation( "timezone" ) );
+ }
+ }
+ }
+
+ protected void mergeContributor_Roles( Contributor target, Contributor source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ List<String> src = source.getRoles();
+ if ( !src.isEmpty() )
+ {
+ List<String> tgt = target.getRoles();
+ List<String> merged = new ArrayList<String>( tgt.size() + src.size() );
+ merged.addAll( tgt );
+ merged.addAll( src );
+ target.setRoles( merged );
+ }
+ }
+
+ protected void mergeContributor_Properties( Contributor target, Contributor source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ Properties merged = new Properties();
+ if ( sourceDominant )
+ {
+ merged.putAll( target.getProperties() );
+ merged.putAll( source.getProperties() );
+ }
+ else
+ {
+ merged.putAll( source.getProperties() );
+ merged.putAll( target.getProperties() );
+ }
+ target.setProperties( merged );
+ target.setLocation( "properties", InputLocation.merge( target.getLocation( "properties" ),
+ source.getLocation( "properties" ), sourceDominant ) );
+ }
+
+ protected void mergeIssueManagement( IssueManagement target, IssueManagement source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ mergeIssueManagement_Url( target, source, sourceDominant, context );
+ mergeIssueManagement_System( target, source, sourceDominant, context );
+ }
+
+ protected void mergeIssueManagement_System( IssueManagement target, IssueManagement source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ String src = source.getSystem();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getSystem() == null )
+ {
+ target.setSystem( src );
+ target.setLocation( "system", source.getLocation( "system" ) );
+ }
+ }
+ }
+
+ protected void mergeIssueManagement_Url( IssueManagement target, IssueManagement source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ String src = source.getUrl();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getUrl() == null )
+ {
+ target.setUrl( src );
+ target.setLocation( "url", source.getLocation( "url" ) );
+ }
+ }
+ }
+
+ protected void mergeScm( Scm target, Scm source, boolean sourceDominant, Map<Object, Object> context )
+ {
+ mergeScm_Url( target, source, sourceDominant, context );
+ mergeScm_Connection( target, source, sourceDominant, context );
+ mergeScm_DeveloperConnection( target, source, sourceDominant, context );
+ mergeScm_Tag( target, source, sourceDominant, context );
+ }
+
+ protected void mergeScm_Url( Scm target, Scm source, boolean sourceDominant, Map<Object, Object> context )
+ {
+ String src = source.getUrl();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getUrl() == null )
+ {
+ target.setUrl( src );
+ target.setLocation( "url", source.getLocation( "url" ) );
+ }
+ }
+ }
+
+ protected void mergeScm_Connection( Scm target, Scm source, boolean sourceDominant, Map<Object, Object> context )
+ {
+ String src = source.getConnection();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getConnection() == null )
+ {
+ target.setConnection( src );
+ target.setLocation( "connection", source.getLocation( "connection" ) );
+ }
+ }
+ }
+
+ protected void mergeScm_DeveloperConnection( Scm target, Scm source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ String src = source.getDeveloperConnection();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getDeveloperConnection() == null )
+ {
+ target.setDeveloperConnection( src );
+ target.setLocation( "developerConnection", source.getLocation( "developerConnection" ) );
+ }
+ }
+ }
+
+ protected void mergeScm_Tag( Scm target, Scm source, boolean sourceDominant, Map<Object, Object> context )
+ {
+ String src = source.getTag();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getTag() == null )
+ {
+ target.setTag( src );
+ target.setLocation( "tag", source.getLocation( "tag" ) );
+ }
+ }
+ }
+
+ protected void mergeCiManagement( CiManagement target, CiManagement source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ mergeCiManagement_System( target, source, sourceDominant, context );
+ mergeCiManagement_Url( target, source, sourceDominant, context );
+ mergeCiManagement_Notifiers( target, source, sourceDominant, context );
+ }
+
+ protected void mergeCiManagement_System( CiManagement target, CiManagement source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ String src = source.getSystem();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getSystem() == null )
+ {
+ target.setSystem( src );
+ target.setLocation( "system", source.getLocation( "system" ) );
+ }
+ }
+ }
+
+ protected void mergeCiManagement_Url( CiManagement target, CiManagement source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ String src = source.getUrl();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getUrl() == null )
+ {
+ target.setUrl( src );
+ target.setLocation( "url", source.getLocation( "url" ) );
+ }
+ }
+ }
+
+ protected void mergeCiManagement_Notifiers( CiManagement target, CiManagement source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ List<Notifier> src = source.getNotifiers();
+ if ( !src.isEmpty() )
+ {
+ List<Notifier> tgt = target.getNotifiers();
+ Map<Object, Notifier> merged = new LinkedHashMap<Object, Notifier>( ( src.size() + tgt.size() ) * 2 );
+
+ for ( Notifier element : tgt )
+ {
+ Object key = getNotifierKey( element );
+ merged.put( key, element );
+ }
+
+ for ( Notifier element : src )
+ {
+ Object key = getNotifierKey( element );
+ if ( sourceDominant || !merged.containsKey( key ) )
+ {
+ merged.put( key, element );
+ }
+ }
+
+ target.setNotifiers( new ArrayList<Notifier>( merged.values() ) );
+ }
+ }
+
+ protected void mergeNotifier( Notifier target, Notifier source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ mergeNotifier_Type( target, source, sourceDominant, context );
+ mergeNotifier_Address( target, source, sourceDominant, context );
+ mergeNotifier_Configuration( target, source, sourceDominant, context );
+ mergeNotifier_SendOnError( target, source, sourceDominant, context );
+ mergeNotifier_SendOnFailure( target, source, sourceDominant, context );
+ mergeNotifier_SendOnSuccess( target, source, sourceDominant, context );
+ mergeNotifier_SendOnWarning( target, source, sourceDominant, context );
+ }
+
+ protected void mergeNotifier_Type( Notifier target, Notifier source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ String src = source.getType();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getType() == null )
+ {
+ target.setType( src );
+ }
+ }
+ }
+
+ protected void mergeNotifier_Address( Notifier target, Notifier source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ String src = source.getAddress();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getAddress() == null )
+ {
+ target.setAddress( src );
+ }
+ }
+ }
+
+ protected void mergeNotifier_Configuration( Notifier target, Notifier source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ Properties merged = new Properties();
+ if ( sourceDominant )
+ {
+ merged.putAll( target.getConfiguration() );
+ merged.putAll( source.getConfiguration() );
+ }
+ else
+ {
+ merged.putAll( source.getConfiguration() );
+ merged.putAll( target.getConfiguration() );
+ }
+ target.setConfiguration( merged );
+ }
+
+ protected void mergeNotifier_SendOnError( Notifier target, Notifier source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ if ( sourceDominant )
+ {
+ target.setSendOnError( source.isSendOnError() );
+ }
+ }
+
+ protected void mergeNotifier_SendOnFailure( Notifier target, Notifier source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ if ( sourceDominant )
+ {
+ target.setSendOnFailure( source.isSendOnFailure() );
+ }
+ }
+
+ protected void mergeNotifier_SendOnSuccess( Notifier target, Notifier source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ if ( sourceDominant )
+ {
+ target.setSendOnSuccess( source.isSendOnSuccess() );
+ }
+ }
+
+ protected void mergeNotifier_SendOnWarning( Notifier target, Notifier source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ if ( sourceDominant )
+ {
+ target.setSendOnWarning( source.isSendOnWarning() );
+ }
+ }
+
+ protected void mergePrerequisites( Prerequisites target, Prerequisites source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ mergePrerequisites_Maven( target, source, sourceDominant, context );
+ }
+
+ protected void mergePrerequisites_Maven( Prerequisites target, Prerequisites source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ String src = source.getMaven();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getMaven() == null )
+ {
+ target.setMaven( src );
+ target.setLocation( "maven", source.getLocation( "maven" ) );
+ }
+ }
+ }
+
+ protected void mergeBuild( Build target, Build source, boolean sourceDominant, Map<Object, Object> context )
+ {
+ mergeBuildBase( target, source, sourceDominant, context );
+ mergeBuild_SourceDirectory( target, source, sourceDominant, context );
+ mergeBuild_ScriptSourceDirectory( target, source, sourceDominant, context );
+ mergeBuild_TestSourceDirectory( target, source, sourceDominant, context );
+ mergeBuild_OutputDirectory( target, source, sourceDominant, context );
+ mergeBuild_TestOutputDirectory( target, source, sourceDominant, context );
+ mergeBuild_Extensions( target, source, sourceDominant, context );
+ }
+
+ protected void mergeBuild_SourceDirectory( Build target, Build source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ String src = source.getSourceDirectory();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getSourceDirectory() == null )
+ {
+ target.setSourceDirectory( src );
+ target.setLocation( "sourceDirectory", source.getLocation( "sourceDirectory" ) );
+ }
+ }
+ }
+
+ protected void mergeBuild_ScriptSourceDirectory( Build target, Build source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ String src = source.getScriptSourceDirectory();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getScriptSourceDirectory() == null )
+ {
+ target.setScriptSourceDirectory( src );
+ target.setLocation( "scriptSourceDirectory", source.getLocation( "scriptSourceDirectory" ) );
+ }
+ }
+ }
+
+ protected void mergeBuild_TestSourceDirectory( Build target, Build source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ String src = source.getTestSourceDirectory();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getTestSourceDirectory() == null )
+ {
+ target.setTestSourceDirectory( src );
+ target.setLocation( "testSourceDirectory", source.getLocation( "testSourceDirectory" ) );
+ }
+ }
+ }
+
+ protected void mergeBuild_OutputDirectory( Build target, Build source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ String src = source.getOutputDirectory();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getOutputDirectory() == null )
+ {
+ target.setOutputDirectory( src );
+ target.setLocation( "outputDirectory", source.getLocation( "outputDirectory" ) );
+ }
+ }
+ }
+
+ protected void mergeBuild_TestOutputDirectory( Build target, Build source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ String src = source.getTestOutputDirectory();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getTestOutputDirectory() == null )
+ {
+ target.setTestOutputDirectory( src );
+ target.setLocation( "testOutputDirectory", source.getLocation( "testOutputDirectory" ) );
+ }
+ }
+ }
+
+ protected void mergeBuild_Extensions( Build target, Build source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ List<Extension> src = source.getExtensions();
+ if ( !src.isEmpty() )
+ {
+ List<Extension> tgt = target.getExtensions();
+ Map<Object, Extension> merged = new LinkedHashMap<Object, Extension>( ( src.size() + tgt.size() ) * 2 );
+
+ for ( Extension element : tgt )
+ {
+ Object key = getExtensionKey( element );
+ merged.put( key, element );
+ }
+
+ for ( Extension element : src )
+ {
+ Object key = getExtensionKey( element );
+ if ( sourceDominant || !merged.containsKey( key ) )
+ {
+ merged.put( key, element );
+ }
+ }
+
+ target.setExtensions( new ArrayList<Extension>( merged.values() ) );
+ }
+ }
+
+ protected void mergeExtension( Extension target, Extension source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ mergeExtension_GroupId( target, source, sourceDominant, context );
+ mergeExtension_ArtifactId( target, source, sourceDominant, context );
+ mergeExtension_Version( target, source, sourceDominant, context );
+ }
+
+ protected void mergeExtension_GroupId( Extension target, Extension source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ String src = source.getGroupId();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getGroupId() == null )
+ {
+ target.setGroupId( src );
+ target.setLocation( "groupId", source.getLocation( "groupId" ) );
+ }
+ }
+ }
+
+ protected void mergeExtension_ArtifactId( Extension target, Extension source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ String src = source.getArtifactId();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getArtifactId() == null )
+ {
+ target.setArtifactId( src );
+ target.setLocation( "artifactId", source.getLocation( "artifactId" ) );
+ }
+ }
+ }
+
+ protected void mergeExtension_Version( Extension target, Extension source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ String src = source.getVersion();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getVersion() == null )
+ {
+ target.setVersion( src );
+ target.setLocation( "version", source.getLocation( "version" ) );
+ }
+ }
+ }
+
+ protected void mergeBuildBase( BuildBase target, BuildBase source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ mergePluginConfiguration( target, source, sourceDominant, context );
+ mergeBuildBase_DefaultGoal( target, source, sourceDominant, context );
+ mergeBuildBase_FinalName( target, source, sourceDominant, context );
+ mergeBuildBase_Directory( target, source, sourceDominant, context );
+ mergeBuildBase_Resources( target, source, sourceDominant, context );
+ mergeBuildBase_TestResources( target, source, sourceDominant, context );
+ mergeBuildBase_Filters( target, source, sourceDominant, context );
+ }
+
+ protected void mergeBuildBase_DefaultGoal( BuildBase target, BuildBase source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ String src = source.getDefaultGoal();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getDefaultGoal() == null )
+ {
+ target.setDefaultGoal( src );
+ target.setLocation( "defaultGoal", source.getLocation( "defaultGoal" ) );
+ }
+ }
+ }
+
+ protected void mergeBuildBase_Directory( BuildBase target, BuildBase source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ String src = source.getDirectory();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getDirectory() == null )
+ {
+ target.setDirectory( src );
+ target.setLocation( "directory", source.getLocation( "directory" ) );
+ }
+ }
+ }
+
+ protected void mergeBuildBase_FinalName( BuildBase target, BuildBase source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ String src = source.getFinalName();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getFinalName() == null )
+ {
+ target.setFinalName( src );
+ target.setLocation( "finalName", source.getLocation( "finalName" ) );
+ }
+ }
+ }
+
+ protected void mergeBuildBase_Filters( BuildBase target, BuildBase source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ List<String> src = source.getFilters();
+ if ( !src.isEmpty() )
+ {
+ List<String> tgt = target.getFilters();
+ List<String> merged = new ArrayList<String>( tgt.size() + src.size() );
+ merged.addAll( tgt );
+ merged.addAll( src );
+ target.setFilters( merged );
+ }
+ }
+
+ protected void mergeBuildBase_Resources( BuildBase target, BuildBase source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ List<Resource> src = source.getResources();
+ if ( !src.isEmpty() )
+ {
+ List<Resource> tgt = target.getResources();
+ Map<Object, Resource> merged = new LinkedHashMap<Object, Resource>( ( src.size() + tgt.size() ) * 2 );
+
+ for ( Resource element : tgt )
+ {
+ Object key = getResourceKey( element );
+ merged.put( key, element );
+ }
+
+ for ( Resource element : src )
+ {
+ Object key = getResourceKey( element );
+ if ( sourceDominant || !merged.containsKey( key ) )
+ {
+ merged.put( key, element );
+ }
+ }
+
+ target.setResources( new ArrayList<Resource>( merged.values() ) );
+ }
+ }
+
+ protected void mergeBuildBase_TestResources( BuildBase target, BuildBase source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ List<Resource> src = source.getTestResources();
+ if ( !src.isEmpty() )
+ {
+ List<Resource> tgt = target.getTestResources();
+ Map<Object, Resource> merged = new LinkedHashMap<Object, Resource>( ( src.size() + tgt.size() ) * 2 );
+
+ for ( Resource element : tgt )
+ {
+ Object key = getResourceKey( element );
+ merged.put( key, element );
+ }
+
+ for ( Resource element : src )
+ {
+ Object key = getResourceKey( element );
+ if ( sourceDominant || !merged.containsKey( key ) )
+ {
+ merged.put( key, element );
+ }
+ }
+
+ target.setTestResources( new ArrayList<Resource>( merged.values() ) );
+ }
+ }
+
+ protected void mergePluginConfiguration( PluginConfiguration target, PluginConfiguration source,
+ boolean sourceDominant, Map<Object, Object> context )
+ {
+ mergePluginContainer( target, source, sourceDominant, context );
+ mergePluginConfiguration_PluginManagement( target, source, sourceDominant, context );
+ }
+
+ protected void mergePluginConfiguration_PluginManagement( PluginConfiguration target, PluginConfiguration source,
+ boolean sourceDominant, Map<Object, Object> context )
+ {
+ PluginManagement src = source.getPluginManagement();
+ if ( src != null )
+ {
+ PluginManagement tgt = target.getPluginManagement();
+ if ( tgt == null )
+ {
+ tgt = new PluginManagement();
+ target.setPluginManagement( tgt );
+ }
+ mergePluginManagement( tgt, src, sourceDominant, context );
+ }
+ }
+
+ protected void mergePluginContainer( PluginContainer target, PluginContainer source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ mergePluginContainer_Plugins( target, source, sourceDominant, context );
+ }
+
+ protected void mergePluginContainer_Plugins( PluginContainer target, PluginContainer source,
+ boolean sourceDominant, Map<Object, Object> context )
+ {
+ List<Plugin> src = source.getPlugins();
+ if ( !src.isEmpty() )
+ {
+ List<Plugin> tgt = target.getPlugins();
+ Map<Object, Plugin> merged = new LinkedHashMap<Object, Plugin>( ( src.size() + tgt.size() ) * 2 );
+
+ for ( Plugin element : tgt )
+ {
+ Object key = getPluginKey( element );
+ merged.put( key, element );
+ }
+
+ for ( Plugin element : src )
+ {
+ Object key = getPluginKey( element );
+ if ( sourceDominant || !merged.containsKey( key ) )
+ {
+ merged.put( key, element );
+ }
+ }
+
+ target.setPlugins( new ArrayList<Plugin>( merged.values() ) );
+ }
+ }
+
+ protected void mergePluginManagement( PluginManagement target, PluginManagement source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ mergePluginContainer( target, source, sourceDominant, context );
+ }
+
+ protected void mergePlugin( Plugin target, Plugin source, boolean sourceDominant, Map<Object, Object> context )
+ {
+ mergeConfigurationContainer( target, source, sourceDominant, context );
+ mergePlugin_GroupId( target, source, sourceDominant, context );
+ mergePlugin_ArtifactId( target, source, sourceDominant, context );
+ mergePlugin_Version( target, source, sourceDominant, context );
+ mergePlugin_Extensions( target, source, sourceDominant, context );
+ mergePlugin_Dependencies( target, source, sourceDominant, context );
+ mergePlugin_Executions( target, source, sourceDominant, context );
+ }
+
+ protected void mergePlugin_GroupId( Plugin target, Plugin source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ String src = source.getGroupId();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getGroupId() == null )
+ {
+ target.setGroupId( src );
+ target.setLocation( "groupId", source.getLocation( "groupId" ) );
+ }
+ }
+ }
+
+ protected void mergePlugin_ArtifactId( Plugin target, Plugin source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ String src = source.getArtifactId();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getArtifactId() == null )
+ {
+ target.setArtifactId( src );
+ target.setLocation( "artifactId", source.getLocation( "artifactId" ) );
+ }
+ }
+ }
+
+ protected void mergePlugin_Version( Plugin target, Plugin source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ String src = source.getVersion();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getVersion() == null )
+ {
+ target.setVersion( src );
+ target.setLocation( "version", source.getLocation( "version" ) );
+ }
+ }
+ }
+
+ protected void mergePlugin_Extensions( Plugin target, Plugin source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ String src = source.getExtensions();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getExtensions() == null )
+ {
+ target.setExtensions( src );
+ target.setLocation( "extensions", source.getLocation( "extensions" ) );
+ }
+ }
+ }
+
+ protected void mergePlugin_Dependencies( Plugin target, Plugin source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ List<Dependency> src = source.getDependencies();
+ if ( !src.isEmpty() )
+ {
+ List<Dependency> tgt = target.getDependencies();
+ Map<Object, Dependency> merged = new LinkedHashMap<Object, Dependency>( ( src.size() + tgt.size() ) * 2 );
+
+ for ( Dependency element : tgt )
+ {
+ Object key = getDependencyKey( element );
+ merged.put( key, element );
+ }
+
+ for ( Dependency element : src )
+ {
+ Object key = getDependencyKey( element );
+ if ( sourceDominant || !merged.containsKey( key ) )
+ {
+ merged.put( key, element );
+ }
+ }
+
+ target.setDependencies( new ArrayList<Dependency>( merged.values() ) );
+ }
+ }
+
+ protected void mergePlugin_Executions( Plugin target, Plugin source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ List<PluginExecution> src = source.getExecutions();
+ if ( !src.isEmpty() )
+ {
+ List<PluginExecution> tgt = target.getExecutions();
+
+ Map<Object, PluginExecution> merged =
+ new LinkedHashMap<Object, PluginExecution>( ( src.size() + tgt.size() ) * 2 );
+
+ for ( PluginExecution element : tgt )
+ {
+ Object key = getPluginExecutionKey( element );
+ merged.put( key, element );
+ }
+
+ for ( PluginExecution element : src )
+ {
+ Object key = getPluginExecutionKey( element );
+ if ( sourceDominant || !merged.containsKey( key ) )
+ {
+ merged.put( key, element );
+ }
+ }
+
+ target.setExecutions( new ArrayList<PluginExecution>( merged.values() ) );
+ }
+ }
+
+ protected void mergeConfigurationContainer( ConfigurationContainer target, ConfigurationContainer source,
+ boolean sourceDominant, Map<Object, Object> context )
+ {
+ mergeConfigurationContainer_Inherited( target, source, sourceDominant, context );
+ mergeConfigurationContainer_Configuration( target, source, sourceDominant, context );
+ }
+
+ protected void mergeConfigurationContainer_Inherited( ConfigurationContainer target, ConfigurationContainer source,
+ boolean sourceDominant, Map<Object, Object> context )
+ {
+ String src = source.getInherited();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getInherited() == null )
+ {
+ target.setInherited( src );
+ target.setLocation( "inherited", source.getLocation( "inherited" ) );
+ }
+ }
+ }
+
+ protected void mergeConfigurationContainer_Configuration( ConfigurationContainer target,
+ ConfigurationContainer source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ Xpp3Dom src = (Xpp3Dom) source.getConfiguration();
+ if ( src != null )
+ {
+ Xpp3Dom tgt = (Xpp3Dom) target.getConfiguration();
+ if ( sourceDominant || tgt == null )
+ {
+ tgt = Xpp3Dom.mergeXpp3Dom( new Xpp3Dom( src ), tgt );
+ }
+ else
+ {
+ tgt = Xpp3Dom.mergeXpp3Dom( tgt, src );
+ }
+ target.setConfiguration( tgt );
+ }
+ }
+
+ protected void mergePluginExecution( PluginExecution target, PluginExecution source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ mergeConfigurationContainer( target, source, sourceDominant, context );
+ mergePluginExecution_Id( target, source, sourceDominant, context );
+ mergePluginExecution_Phase( target, source, sourceDominant, context );
+ mergePluginExecution_Goals( target, source, sourceDominant, context );
+ }
+
+ protected void mergePluginExecution_Id( PluginExecution target, PluginExecution source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ String src = source.getId();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getId() == null )
+ {
+ target.setId( src );
+ target.setLocation( "id", source.getLocation( "id" ) );
+ }
+ }
+ }
+
+ protected void mergePluginExecution_Phase( PluginExecution target, PluginExecution source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ String src = source.getPhase();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getPhase() == null )
+ {
+ target.setPhase( src );
+ target.setLocation( "phase", source.getLocation( "phase" ) );
+ }
+ }
+ }
+
+ protected void mergePluginExecution_Goals( PluginExecution target, PluginExecution source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ List<String> src = source.getGoals();
+ if ( !src.isEmpty() )
+ {
+ List<String> tgt = target.getGoals();
+ List<String> merged = new ArrayList<String>( tgt.size() + src.size() );
+ merged.addAll( tgt );
+ merged.addAll( src );
+ target.setGoals( merged );
+ }
+ }
+
+ protected void mergeResource( Resource target, Resource source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ mergeFileSet( target, source, sourceDominant, context );
+ mergeResource_TargetPath( target, source, sourceDominant, context );
+ mergeResource_Filtering( target, source, sourceDominant, context );
+ mergeResource_MergeId( target, source, sourceDominant, context );
+ }
+
+ protected void mergeResource_TargetPath( Resource target, Resource source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ String src = source.getTargetPath();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getTargetPath() == null )
+ {
+ target.setTargetPath( src );
+ target.setLocation( "targetPath", source.getLocation( "targetPath" ) );
+ }
+ }
+ }
+
+ protected void mergeResource_Filtering( Resource target, Resource source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ String src = source.getFiltering();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getFiltering() == null )
+ {
+ target.setFiltering( src );
+ target.setLocation( "filtering", source.getLocation( "filtering" ) );
+ }
+ }
+ }
+
+ protected void mergeResource_MergeId( Resource target, Resource source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ String src = source.getMergeId();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getMergeId() == null )
+ {
+ target.setMergeId( src );
+ }
+ }
+ }
+
+ protected void mergeFileSet( FileSet target, FileSet source, boolean sourceDominant, Map<Object, Object> context )
+ {
+ mergePatternSet( target, source, sourceDominant, context );
+ mergeFileSet_Directory( target, source, sourceDominant, context );
+ }
+
+ protected void mergeFileSet_Directory( FileSet target, FileSet source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ String src = source.getDirectory();
+ if ( src != null )
+ {
+ if ( sourceDominant || target.getDirectory() == null )
+ {
+ target.setDirectory( src );
+ target.setLocation( "directory", source.getLocation( "directory" ) );
+ }
+ }
+ }
+
+ protected void mergePatternSet( PatternSet target, PatternSet source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ mergePatternSet_Includes( target, source, sourceDominant, context );
+ mergePatternSet_Excludes( target, source, sourceDominant, context );
+ }
+
+ protected void mergePatternSet_Includes( PatternSet target, PatternSet source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ List<String> src = source.getIncludes();
+ if ( !src.isEmpty() )
+ {
+ List<String> tgt = target.getIncludes();
+ List<String> merged = new ArrayList<String>( tgt.size() + src.size() );
+ merged.addAll( tgt );
+ merged.addAll( src );
+ target.setIncludes( merged );
+ }
+ }
+
+ protected void mergePatternSet_Excludes( PatternSet target, PatternSet source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ List<String> src = source.getExcludes();
+ if ( !src.isEmpty() )
+ {
+ List<String> tgt = target.getExcludes();
+ List<String> merged = new ArrayList<String>( tgt.size() + src.size() );
+ merged.addAll( tgt );
+ merged.addAll( src );
+ target.setExcludes( merged );
+ }
+ }
+
+ protected void mergeProfile( Profile target, Profile source, boolean sourceDominant, Map<Object, Object> context )
+ {
+ mergeModelBase( target, source, sourceDominant, context );
+ // TODO
+ }
+
+ protected void mergeActivation( Activation target, Activation source, boolean sourceDominant,
+ Map<Object, Object> context )
+ {
+ // TODO
+ }
+
+ protected Object getDependencyKey( Dependency dependency )
+ {
+ return dependency;
+ }
+
+ protected Object getPluginKey( Plugin plugin )
+ {
+ return plugin;
+ }
+
+ protected Object getPluginExecutionKey( PluginExecution pluginExecution )
+ {
+ return pluginExecution;
+ }
+
+ protected Object getReportPluginKey( ReportPlugin reportPlugin )
+ {
+ return reportPlugin;
+ }
+
+ protected Object getReportSetKey( ReportSet reportSet )
+ {
+ return reportSet;
+ }
+
+ protected Object getLicenseKey( License license )
+ {
+ return license;
+ }
+
+ protected Object getMailingListKey( MailingList mailingList )
+ {
+ return mailingList;
+ }
+
+ protected Object getDeveloperKey( Developer developer )
+ {
+ return developer;
+ }
+
+ protected Object getContributorKey( Contributor contributor )
+ {
+ return contributor;
+ }
+
+ protected Object getProfileKey( Profile profile )
+ {
+ return profile;
+ }
+
+ protected Object getRepositoryKey( Repository repository )
+ {
+ return getRepositoryBaseKey( repository );
+ }
+
+ protected Object getRepositoryBaseKey( RepositoryBase repositoryBase )
+ {
+ return repositoryBase;
+ }
+
+ protected Object getNotifierKey( Notifier notifier )
+ {
+ return notifier;
+ }
+
+ protected Object getResourceKey( Resource resource )
+ {
+ return resource;
+ }
+
+ protected Object getExtensionKey( Extension extension )
+ {
+ return extension;
+ }
+
+ protected Object getExclusionKey( Exclusion exclusion )
+ {
+ return exclusion;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model/src/main/java/org/apache/maven/model/merge/package-info.java b/framework/src/maven/apache-maven-3.3.3/maven-model/src/main/java/org/apache/maven/model/merge/package-info.java
new file mode 100644
index 00000000..eaa2d174
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model/src/main/java/org/apache/maven/model/merge/package-info.java
@@ -0,0 +1,24 @@
+// CHECKSTYLE_OFF: RegexpHeader
+/**
+ * POM merger.
+ */
+package org.apache.maven.model.merge;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model/src/main/java/org/apache/maven/model/package-info.java b/framework/src/maven/apache-maven-3.3.3/maven-model/src/main/java/org/apache/maven/model/package-info.java
new file mode 100644
index 00000000..88d3fa07
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model/src/main/java/org/apache/maven/model/package-info.java
@@ -0,0 +1,25 @@
+// CHECKSTYLE_OFF: RegexpHeader
+/**
+ * Maven POM (Project Object Model) classes, generated from <code>maven.mdo</code> model.
+ * The root class is {@link org.apache.maven.model.Model}.
+ */
+package org.apache.maven.model;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */ \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model/src/main/mdo/maven.mdo b/framework/src/maven/apache-maven-3.3.3/maven-model/src/main/mdo/maven.mdo
new file mode 100644
index 00000000..2821ea62
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model/src/main/mdo/maven.mdo
@@ -0,0 +1,3649 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+
+<!--
+ | Improvements:
+ |
+ | o add specification element to a field, this would be more a technical description of
+ | what is allowed in the field.
+ |
+ | o validators: there could be several levels of validation. Simple type validation could
+ | be done with a regex, but we need inter-field validation and rules which could be
+ | dealt with by something like drools.
+ |
+ | o i18n: would be good to be able to have names/descriptions/specifications
+ | in as many languages as possible. (see MNG-3626)
+ |
+ | o annotation mechanism so that changes to the model can be accurately tracked.
+ |
+ | o need to clean up all the descriptions, matching anything to the current project-descriptor.xml file and
+ | improving on that
+ |
+ | o use enums where appropriate (eg dependency scope)
+ |
+ | o a number of elements have a groupId/artifactId and sometimes version. It would be good to have them all extend one
+ | definition of these types
+ |
+-->
+<model xmlns="http://modello.codehaus.org/MODELLO/1.4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://modello.codehaus.org/MODELLO/1.4.0 http://modello.codehaus.org/xsd/modello-1.4.0.xsd"
+ xml.namespace="http://maven.apache.org/POM/${version}"
+ xml.schemaLocation="http://maven.apache.org/xsd/maven-${version}.xsd">
+ <id>maven</id>
+ <name>Maven</name>
+ <description>
+ <![CDATA[
+ <p>This is a reference for the Maven project descriptor used in Maven.</p>
+ <p>An XSD is available at:</p>
+ <ul>
+ <li><a href="http://maven.apache.org/xsd/maven-v3_0_0.xsd">http://maven.apache.org/xsd/maven-v3_0_0.xsd</a> for Maven 1.1.</li>
+ <li><a href="http://maven.apache.org/xsd/maven-4.0.0.xsd">http://maven.apache.org/xsd/maven-4.0.0.xsd</a> for Maven 2.0.</li>
+ </ul>
+ ]]>
+ </description>
+ <defaults>
+ <default>
+ <key>package</key>
+ <value>org.apache.maven.model</value>
+ </default>
+ </defaults>
+ <classes>
+ <class rootElement="true" xml.tagName="project" java.clone.hook="cloneHook">
+ <name>Model</name>
+ <superClass>ModelBase</superClass>
+ <description>
+ <![CDATA[
+ The <code>&lt;project&gt;</code> element is the root of the descriptor.
+ The following table lists all of the possible child elements.
+ ]]>
+ </description>
+ <version>3.0.0+</version>
+ <fields>
+
+ <!-- ====================================================================== -->
+ <!-- Model Version -->
+ <!-- ====================================================================== -->
+
+ <field>
+ <name>pomVersion</name>
+ <version>3.0.0</version>
+ <required>true</required>
+ <type>String</type>
+ <description>
+ <![CDATA[
+ Declares to which version of project descriptor this POM conforms.
+ The only valid value is <code>3</code>.
+ ]]>
+ </description>
+ </field>
+ <field>
+ <name>modelVersion</name>
+ <version>4.0.0+</version>
+ <required>true</required>
+ <description>Declares to which version of project descriptor this POM conforms.</description>
+ <type>String</type>
+ </field>
+
+ <!-- ====================================================================== -->
+ <!-- Parent Model -->
+ <!-- ====================================================================== -->
+
+ <field xdoc.separator="blank">
+ <name>extend</name>
+ <version>3.0.0</version>
+ <description>
+ <![CDATA[
+ The location of the parent project, if one exists. Values from the
+ parent project will be the default for this project if they are
+ left unspecified. The path may be absolute, or relative to the
+ current <code>project.xml</code> file. For example,
+ <code>&lt;extend&gt;${basedir}/../project.xml&lt;/extend&gt;</code>.
+ ]]>
+ </description>
+ <type>String</type>
+ </field>
+ <field xdoc.separator="blank">
+ <name>parent</name>
+ <version>4.0.0+</version>
+ <description>The location of the parent project, if one exists. Values from the parent
+ project will be the default for this project if they are left unspecified. The location
+ is given as a group ID, artifact ID and version.</description>
+ <association>
+ <type>Parent</type>
+ </association>
+ </field>
+
+ <!-- ====================================================================== -->
+ <!-- groupId/artifactId/Version/Packaging -->
+ <!-- ====================================================================== -->
+
+ <field xdoc.separator="blank">
+ <name>groupId</name>
+ <version>3.0.0+</version>
+ <required>true</required>
+ <description>
+ <![CDATA[
+ A universally unique identifier for a project. It is normal to
+ use a fully-qualified package name to distinguish it from other
+ projects with a similar name (eg. <code>org.apache.maven</code>).
+ ]]>
+ </description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>artifactId</name>
+ <version>3.0.0+</version>
+ <required>true</required>
+ <description>The identifier for this artifact that is unique within the group given by the
+ group ID. An artifact is something that is either produced or used by a project.
+ Examples of artifacts produced by Maven for a project include: JARs, source and binary
+ distributions, and WARs.</description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>id</name>
+ <version>3.0.0</version>
+ <required>true</required>
+ <description>
+ <![CDATA[
+ <b>Deprecated</b>. When used, this sets both the <code>groupId</code>
+ and <code>artifactId</code> elements if they were previously empty.
+ ]]>
+ </description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>currentVersion</name>
+ <description>The current version of the artifact produced by this project.</description>
+ <version>3.0.0</version>
+ <required>true</required>
+ <type>String</type>
+ </field>
+ <field>
+ <name>version</name>
+ <version>4.0.0+</version>
+ <required>true</required>
+ <description>The current version of the artifact produced by this project.</description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>versions</name>
+ <version>3.0.0</version>
+ <description>Contains information on previous versions of the project.</description>
+ <association>
+ <type>Version</type>
+ <multiplicity>*</multiplicity>
+ </association>
+ </field>
+ <field>
+ <name>packaging</name>
+ <version>4.0.0+</version>
+ <description>
+ <![CDATA[
+ The type of artifact this project produces, for example <code>jar</code>
+ <code>war</code>
+ <code>ear</code>
+ <code>pom</code>.
+ Plugins can create their own packaging, and
+ therefore their own packaging types,
+ so this list does not contain all possible types.
+ ]]>
+ </description>
+ <type>String</type>
+ <defaultValue>jar</defaultValue>
+ </field>
+
+ <!-- ====================================================================== -->
+ <!-- Elements which describe a project -->
+ <!-- ====================================================================== -->
+
+ <field xdoc.separator="blank">
+ <name>name</name>
+ <version>3.0.0+</version>
+ <required>true</required>
+ <description>The full name of the project.</description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>shortDescription</name>
+ <version>3.0.0</version>
+ <description>A short description of the project. The short description should be limited
+ to a single line.</description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>description</name>
+ <version>3.0.0+</version>
+ <description>A detailed description of the project, used by Maven whenever it needs to
+ describe the project, such as on the web site. While this element can be specified as
+ CDATA to enable the use of HTML tags within the description, it is discouraged to allow
+ plain text representation. If you need to modify the index page of the generated web
+ site, you are able to specify your own instead of adjusting this text.</description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>url</name>
+ <version>3.0.0+</version>
+ <description>
+ <![CDATA[
+ The URL to the project's homepage.
+ <br /><b>Default value is</b>: parent value [+ path adjustment] + artifactId
+ ]]>
+ </description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>siteAddress</name>
+ <version>3.0.0</version>
+ <description>The hostname of the web server that hosts the project's web site. This is
+ used when the web site is deployed.</description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>siteDirectory</name>
+ <version>3.0.0</version>
+ <description>The directory on the web server where the public web site for this project
+ resides. This is used when the web site is deployed.</description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>inceptionYear</name>
+ <version>3.0.0+</version>
+ <required>true</required>
+ <description>The year of the project's inception, specified with 4 digits. This value is
+ used when generating copyright notices as well as being informational.</description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>logo</name>
+ <version>3.0.0</version>
+ <description>
+ <![CDATA[
+ The URL of the project's logo image. This can be an URL relative
+ to the base directory of the generated web site,
+ (e.g., <code>/images/project-logo.png</code>) or an absolute URL
+ (e.g., <code>http://my.corp/project-logo.png</code>). This is used
+ when generating the project documentation.
+ ]]>
+ </description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>organization</name>
+ <version>3.0.0+</version>
+ <description>This element describes various attributes of the organization to which the
+ project belongs. These attributes are utilized when documentation is created (for
+ copyright notices and links).</description>
+ <alias>organisation</alias>
+ <association>
+ <type>Organization</type>
+ </association>
+ </field>
+ <field>
+ <name>licenses</name>
+ <version>3.0.0+</version>
+ <description>
+ <![CDATA[
+ This element describes all of the licenses for this project.
+ Each license is described by a <code>license</code> element, which
+ is then described by additional elements.
+ Projects should only list the license(s) that applies to the project
+ and not the licenses that apply to dependencies.
+ If multiple licenses are listed, it is assumed that the user can select
+ any of them, not that they must accept all.
+ ]]>
+ </description>
+ <association>
+ <type>License</type>
+ <multiplicity>*</multiplicity>
+ </association>
+ </field>
+ <field xdoc.separator="blank">
+ <name>developers</name>
+ <version>3.0.0+</version>
+ <description>Describes the committers of a project.</description>
+ <association>
+ <type>Developer</type>
+ <multiplicity>*</multiplicity>
+ </association>
+ </field>
+ <field>
+ <name>contributors</name>
+ <version>3.0.0+</version>
+ <description>Describes the contributors to a project that are not yet committers.</description>
+ <association>
+ <type>Contributor</type>
+ <multiplicity>*</multiplicity>
+ </association>
+ </field>
+ <field xdoc.separator="blank">
+ <name>mailingLists</name>
+ <version>3.0.0+</version>
+ <description>Contains information about a project's mailing lists.</description>
+ <association>
+ <type>MailingList</type>
+ <multiplicity>*</multiplicity>
+ </association>
+ </field>
+
+ <!-- ====================================================================== -->
+ <!-- Build prerequisites -->
+ <!-- ====================================================================== -->
+
+ <field xdoc.separator="blank">
+ <name>prerequisites</name>
+ <version>4.0.0+</version>
+ <description>Describes the prerequisites in the build environment for this project.</description>
+ <association>
+ <type>Prerequisites</type>
+ </association>
+ </field>
+
+ <!-- ====================================================================== -->
+ <!-- SCM -->
+ <!-- ====================================================================== -->
+
+ <field xdoc.separator="blank">
+ <name>branches</name>
+ <version>3.0.0</version>
+ <description>
+ <![CDATA[
+ Contains information on SCM branches of the project.
+ ]]>
+ </description>
+ <association>
+ <type>Branch</type>
+ <multiplicity>*</multiplicity>
+ </association>
+ </field>
+ <field>
+ <name>repository</name>
+ <version>3.0.0</version>
+ <description>Specification for the SCM used by the project, such as CVS, Subversion, etc.</description>
+ <association>
+ <type>Repository</type>
+ </association>
+ </field>
+ <field xdoc.separator="blank" xml.insertParentFieldsUpTo="modules">
+ <name>scm</name>
+ <version>4.0.0+</version>
+ <description>Specification for the SCM used by the project, such as CVS, Subversion, etc.</description>
+ <association>
+ <type>Scm</type>
+ </association>
+ </field>
+
+ <!-- ====================================================================== -->
+ <!-- Issue Tracking -->
+ <!-- ====================================================================== -->
+
+ <field xdoc.separator="blank">
+ <name>issueTrackingUrl</name>
+ <version>3.0.0</version>
+ <description>The URL of the project's issue tracking system.</description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>issueManagement</name>
+ <version>4.0.0+</version>
+ <description>The project's issue management system information.</description>
+ <association>
+ <type>IssueManagement</type>
+ </association>
+ </field>
+
+ <!-- ====================================================================== -->
+ <!-- CI Management -->
+ <!-- ====================================================================== -->
+
+ <field>
+ <name>gumpRepositoryId</name>
+ <version>3.0.0</version>
+ <description>This is the repository identifier in Gump that this project is part of.</description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>ciManagement</name>
+ <version>4.0.0+</version>
+ <description>The project's continuous integration information.</description>
+ <association>
+ <type>CiManagement</type>
+ </association>
+ </field>
+
+ <!-- ====================================================================== -->
+ <!-- Distribution Management -->
+ <!-- ====================================================================== -->
+
+ <field>
+ <name>distributionSite</name>
+ <version>3.0.0</version>
+ <description>
+ <![CDATA[
+ The server where the final distributions will be published. This is used when the
+ distributions are deployed. If this isn't defined, the central repository is used instead as
+ determined by <code>maven.repo.central</code> and <code>maven.repo.central.directory</code>.
+ ]]>
+ </description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>distributionDirectory</name>
+ <version>3.0.0</version>
+ <description>The directory on the web server where the final distributions will be
+ published. This is used when the distributions are deployed.</description>
+ <type>String</type>
+ </field>
+
+ <!-- ====================================================================== -->
+ <!-- Specific version 3 -->
+ <!-- ====================================================================== -->
+
+ <field>
+ <name>packageGroups</name>
+ <version>3.0.0</version>
+ <description>Package groups required for complete javadocs.</description>
+ <association>
+ <type>PackageGroup</type>
+ <multiplicity>*</multiplicity>
+ </association>
+ </field>
+ <field>
+ <name>reports</name>
+ <version>3.0.0</version>
+ <description>
+ <![CDATA[
+ This element includes the specification of reports to be
+ included in a Maven-generated site. These reports will be run
+ when a user executes <code>maven site</code>. All of the
+ reports will be included in the navigation bar for browsing in
+ the order they are specified.
+ ]]>
+ </description>
+ <association>
+ <type>String</type>
+ <multiplicity>*</multiplicity>
+ </association>
+ </field>
+ <field>
+ <name>properties</name>
+ <version>3.0.0</version>
+ <description>
+ <![CDATA[
+ Project properties that will be used by various plugins.
+ The format is <code>&lt;name&gt;value&lt;/name&gt;</code>.
+ ]]>
+ </description>
+ <type>Properties</type>
+ <association xml.mapStyle="inline">
+ <type>String</type>
+ <multiplicity>*</multiplicity>
+ </association>
+ </field>
+ <field xml.tagName="package">
+ <name>packageName</name>
+ <version>3.0.0</version>
+ <type>String</type>
+ <description>The Java package name of the project. This value is used when generating
+ JavaDoc.</description>
+ </field>
+
+ <!-- ====================================================================== -->
+ <!-- Build -->
+ <!-- ====================================================================== -->
+
+ <field xdoc.separator="blank" xml.insertParentFieldsUpTo="pluginRepositories">
+ <name>build</name>
+ <version>3.0.0+</version>
+ <required>true</required>
+ <description>Information required to build the project.</description>
+ <association>
+ <type>Build</type>
+ </association>
+ </field>
+
+ <!-- ====================================================================== -->
+ <!-- Profiles -->
+ <!-- ====================================================================== -->
+
+ <field xdoc.separator="blank" xml.insertParentFieldsUpTo="reporting">
+ <name>profiles</name>
+ <version>4.0.0+</version>
+ <description>A listing of project-local build profiles which will modify the build process
+ when activated.</description>
+ <association>
+ <type>Profile</type>
+ <multiplicity>*</multiplicity>
+ </association>
+ </field>
+ </fields>
+ <codeSegments>
+ <codeSegment>
+ <version>3.0.0</version>
+ <code>
+ <![CDATA[
+ public void setVersion(String version)
+ {
+ this.currentVersion = version;
+ }
+
+ public String getVersion()
+ {
+ return currentVersion;
+ }
+
+ /* We need this because we can't use package as a field name.*/
+ public void setPackage(String packageName)
+ {
+ this.packageName = packageName;
+ }
+
+ public String getPackage()
+ {
+ return packageName;
+ }
+ ]]>
+ </code>
+ </codeSegment>
+ <codeSegment>
+ <version>4.0.0+</version>
+ <code>
+ <![CDATA[
+ private void cloneHook( Model copy )
+ {
+ copy.pomFile = pomFile;
+ }
+
+ /**
+ * The POM from which this model originated. This is transient runtime state and therefore not managed by Modello.
+ */
+ private java.io.File pomFile;
+
+ /**
+ * Gets the POM file for the corresponding project (if any).
+ *
+ * @return The POM file from which this model originated or {@code null} if this model does not belong to a local
+ * project (e.g. describes the metadata of some artifact from the repository).
+ */
+ public java.io.File getPomFile()
+ {
+ return pomFile;
+ }
+
+ public void setPomFile( java.io.File pomFile )
+ {
+ this.pomFile = ( pomFile != null ) ? pomFile.getAbsoluteFile() : null;
+ }
+
+ /**
+ * Gets the base directory for the corresponding project (if any).
+ *
+ * @return The base directory for the corresponding project or {@code null} if this model does not belong to a local
+ * project (e.g. describes the metadata of some artifact from the repository).
+ */
+ public java.io.File getProjectDirectory()
+ {
+ return ( pomFile != null ) ? pomFile.getParentFile() : null;
+ }
+
+ /**
+ * @return the model id as <code>groupId:artifactId:packaging:version</code>
+ */
+ public String getId()
+ {
+ StringBuilder id = new StringBuilder( 64 );
+
+ id.append( ( getGroupId() == null ) ? "[inherited]" : getGroupId() );
+ id.append( ":" );
+ id.append( getArtifactId() );
+ id.append( ":" );
+ id.append( getPackaging() );
+ id.append( ":" );
+ id.append( ( getVersion() == null ) ? "[inherited]" : getVersion() );
+
+ return id.toString();
+ }
+
+ @Override
+ public String toString()
+ {
+ return getId();
+ }
+ ]]>
+ </code>
+ </codeSegment>
+ </codeSegments>
+ </class>
+ <class java.clone="deep">
+ <name>ModelBase</name>
+ <version>3.0.0+</version>
+ <description>
+ <![CDATA[
+ Base class for the <code>Model</code> and the <code>Profile</code> objects.
+ ]]>
+ </description>
+ <fields>
+ <field xdoc.separator="blank">
+ <name>modules</name>
+ <version>4.0.0+</version>
+ <description>The modules (sometimes called subprojects) to build as a part of this
+ project. Each module listed is a relative path to the directory containing the module.
+ To be consistent with the way default urls are calculated from parent, it is recommended
+ to have module names match artifact ids.</description>
+ <association>
+ <type>String</type>
+ <multiplicity>*</multiplicity>
+ </association>
+ </field>
+ <field xdoc.separator="blank">
+ <name>distributionManagement</name>
+ <version>4.0.0+</version>
+ <description>Distribution information for a project that enables deployment of the site
+ and artifacts to remote web servers and repositories respectively.</description>
+ <association>
+ <type>DistributionManagement</type>
+ </association>
+ </field>
+ <field xdoc.separator="blank">
+ <name>properties</name>
+ <version>4.0.0+</version>
+ <description>
+ <![CDATA[
+ Properties that can be used throughout the POM as a substitution, and
+ are used as filters in resources if enabled.
+ The format is <code>&lt;name&gt;value&lt;/name&gt;</code>.
+ ]]>
+ </description>
+ <type>Properties</type>
+ <association xml.mapStyle="inline">
+ <type>String</type>
+ <multiplicity>*</multiplicity>
+ </association>
+ </field>
+ <field xdoc.separator="blank">
+ <name>dependencyManagement</name>
+ <version>4.0.0+</version>
+ <required>false</required>
+ <description>Default dependency information for projects that inherit from this one. The
+ dependencies in this section are not immediately resolved. Instead, when a POM derived
+ from this one declares a dependency described by a matching groupId and artifactId, the
+ version and other values from this section are used for that dependency if they were not
+ already specified.</description>
+ <association>
+ <type>DependencyManagement</type>
+ </association>
+ </field>
+ <field>
+ <name>dependencies</name>
+ <version>3.0.0+</version>
+ <description>
+ <![CDATA[
+ This element describes all of the dependencies associated with a
+ project.
+ These dependencies are used to construct a classpath for your
+ project during the build process. They are automatically downloaded from the
+ repositories defined in this project.
+ See <a href="http://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html">the
+ dependency mechanism</a> for more information.
+ ]]>
+ </description>
+ <association>
+ <type>Dependency</type>
+ <multiplicity>*</multiplicity>
+ </association>
+ </field>
+ <field xdoc.separator="blank">
+ <name>repositories</name>
+ <version>4.0.0+</version>
+ <description>The lists of the remote repositories for discovering dependencies and
+ extensions.</description>
+ <association>
+ <type>Repository</type>
+ <multiplicity>*</multiplicity>
+ </association>
+ </field>
+ <field>
+ <name>pluginRepositories</name>
+ <version>4.0.0+</version>
+ <description>The lists of the remote repositories for discovering plugins for builds and
+ reports.</description>
+ <association>
+ <type>Repository</type>
+ <multiplicity>*</multiplicity>
+ </association>
+ </field>
+ <field xdoc.separator="blank">
+ <name>reports</name>
+ <version>4.0.0+</version>
+ <description>
+ <![CDATA[
+ <b>Deprecated</b>. Now ignored by Maven.
+ ]]>
+ </description>
+ <type>DOM</type>
+ </field>
+ <field>
+ <name>reporting</name>
+ <version>4.0.0+</version>
+ <description>
+ <![CDATA[
+ This element includes the specification of report plugins to use
+ to generate the reports on the Maven-generated site.
+ These reports will be run when a user executes <code>mvn site</code>.
+ All of the reports will be included in the navigation bar for browsing.
+ ]]>
+ </description>
+ <association>
+ <type>Reporting</type>
+ </association>
+ </field>
+ </fields>
+ </class>
+ <class>
+ <name>Branch</name>
+ <version>3.0.0</version>
+ <description>Contains information on the SCM branches of the project.</description>
+ <fields>
+ <field>
+ <name>tag</name>
+ <version>3.0.0</version>
+ <required>true</required>
+ <description>The branch tag in the version control system (e.g. cvs) used by the project
+ for the source code associated with this branch of the project.</description>
+ <type>String</type>
+ </field>
+ </fields>
+ </class>
+ <class java.clone="deep">
+ <name>PluginContainer</name>
+ <version>3.0.0+</version>
+ <description>Contains the plugins informations for the project.</description>
+ <fields>
+ <field>
+ <name>plugins</name>
+ <version>4.0.0+</version>
+ <description>The list of plugins to use.</description>
+ <association>
+ <type>Plugin</type>
+ <multiplicity>*</multiplicity>
+ </association>
+ </field>
+ </fields>
+ <codeSegments>
+ <codeSegment>
+ <version>4.0.0+</version>
+ <code>
+ <![CDATA[
+ java.util.Map<String, Plugin> pluginMap;
+
+ /**
+ * Reset the <code>pluginsMap</code> field to <code>null</code>
+ */
+ public synchronized void flushPluginMap()
+ {
+ this.pluginMap = null;
+ }
+
+ /**
+ * @return a Map of plugins field with <code>Plugins#getKey()</code> as key
+ * @see org.apache.maven.model.Plugin#getKey()
+ */
+ public synchronized java.util.Map<String, Plugin> getPluginsAsMap()
+ {
+ if ( pluginMap == null )
+ {
+ pluginMap = new java.util.LinkedHashMap<String, Plugin>();
+ if ( plugins != null )
+ {
+ for ( java.util.Iterator<Plugin> it = plugins.iterator(); it.hasNext(); )
+ {
+ Plugin plugin = (Plugin) it.next();
+ pluginMap.put( plugin.getKey(), plugin );
+ }
+ }
+ }
+
+ return pluginMap;
+ }
+ ]]>
+ </code>
+ </codeSegment>
+ </codeSegments>
+ </class>
+ <class>
+ <name>PluginConfiguration</name>
+ <version>3.0.0+</version>
+ <superClass>PluginContainer</superClass>
+ <description>Contains the plugins management informations for the project.</description>
+ <fields>
+ <!-- [ jdcasey:06-Mar-2005 ] Added to handle version management, etc. for
+ | plugins to be used in sub-projects. -->
+ <field>
+ <name>pluginManagement</name>
+ <version>4.0.0+</version>
+ <required>false</required>
+ <description>Default plugin information to be made available for reference by projects
+ derived from this one. This plugin configuration will not be resolved or bound to the
+ lifecycle unless referenced. Any local configuration for a given plugin will override
+ the plugin's entire definition here.</description>
+ <association>
+ <type>PluginManagement</type>
+ </association>
+ </field>
+ </fields>
+ </class>
+ <class>
+ <name>BuildBase</name>
+ <version>3.0.0+</version>
+ <superClass>PluginConfiguration</superClass>
+ <description>Generic informations for a build.</description>
+ <fields>
+ <field>
+ <name>defaultGoal</name>
+ <version>3.0.0+</version>
+ <description>The default goal (or phase in Maven 2) to execute when none is specified for
+ the project. Note that in case of a multi-module build, only the default goal of the top-level
+ project is relevant, i.e. the default goals of child modules are ignored. Since Maven 3,
+ multiple goals/phases can be separated by whitespace.</description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>resources</name>
+ <version>3.0.0+</version>
+ <description>This element describes all of the classpath resources such as properties
+ files associated with a project. These resources are often included in the final
+ package.</description>
+ <association>
+ <type>Resource</type>
+ <multiplicity>*</multiplicity>
+ </association>
+ </field>
+ <field>
+ <name>testResources</name>
+ <version>4.0.0+</version>
+ <description>This element describes all of the classpath resources such as properties
+ files associated with a project's unit tests.</description>
+ <association>
+ <type>Resource</type>
+ <multiplicity>*</multiplicity>
+ </association>
+ </field>
+ <field>
+ <name>directory</name>
+ <version>4.0.0+</version>
+ <description>The directory where all files generated by the build are placed.</description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>finalName</name>
+ <version>4.0.0+</version>
+ <description>
+ <![CDATA[
+ The filename (excluding the extension, and with no path information) that
+ the produced artifact will be called.
+ The default value is <code>${artifactId}-${version}</code>.
+ ]]>
+ </description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>filters</name>
+ <version>4.0.0+</version>
+ <description>The list of filter properties files that are used when filtering is enabled.</description>
+ <association>
+ <type>String</type>
+ <multiplicity>*</multiplicity>
+ </association>
+ </field>
+ </fields>
+ </class>
+ <class>
+ <name>Build</name>
+ <version>3.0.0+</version>
+ <superClass>BuildBase</superClass>
+ <description>
+ <![CDATA[
+ The <code>&lt;build&gt;</code> element contains informations required to build the project.
+ ]]>
+ </description>
+ <fields>
+ <field>
+ <name>nagEmailAddress</name>
+ <version>3.0.0</version>
+ <description>An address to which notifications regarding the status of builds for this
+ project can be sent. This is intended for use by tools which do unattended builds, for
+ example those providing for continuous integration.</description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>sourceDirectory</name>
+ <version>3.0.0+</version>
+ <required>true</required>
+ <description>This element specifies a directory containing the source of the project. The
+ generated build system will compile the source in this directory when the project is
+ built. The path given is relative to the project descriptor.</description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>scriptSourceDirectory</name>
+ <version>4.0.0+</version>
+ <required>true</required>
+ <description>This element specifies a directory containing the script sources of the
+ project. This directory is meant to be different from the sourceDirectory, in that its
+ contents will be copied to the output directory in most cases (since scripts are
+ interpreted rather than compiled).</description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>unitTestSourceDirectory</name>
+ <version>3.0.0</version>
+ <required>true</required>
+ <description>This element specifies a directory containing the unit test source of the
+ project. The generated build system will compile these directories when the project is
+ being tested. The path given is relative to the project descriptor.</description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>testSourceDirectory</name>
+ <version>4.0.0+</version>
+ <required>true</required>
+ <description>This element specifies a directory containing the unit test source of the
+ project. The generated build system will compile these directories when the project is
+ being tested. The path given is relative to the project descriptor.</description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>aspectSourceDirectory</name>
+ <version>3.0.0</version>
+ <description>This element specifies a directory containing Aspect sources of the project.
+ The generated build system will compile the Aspects in this directory when the project
+ is built if Aspects have been enabled. The path given is relative to the project
+ descriptor.</description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>integrationUnitTestSourceDirectory</name>
+ <version>3.0.0</version>
+ <description>
+ <![CDATA[
+ This element is <b>deprecated</b> and should no longer be used.
+ Initially it was used by the first Cactus plugin. Now
+ the location of the Cactus test sources is defined
+ through a plugin property. See the Cactus plugin
+ <a href="http://jakarta.apache.org/cactus/integration/maven/properties.html">properties</a>
+ page.
+ ]]>
+ </description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>sourceModifications</name>
+ <version>3.0.0</version>
+ <required>true</required>
+ <description>This element describes all of the sourceModifications associated with a
+ project. These modifications are used to exclude or include various source depending on
+ the environment the build is running in.</description>
+ <association>
+ <type>SourceModification</type>
+ <multiplicity>*</multiplicity>
+ </association>
+ </field>
+ <field>
+ <name>unitTest</name>
+ <version>3.0.0</version>
+ <required>true</required>
+ <description>This element specifies unit tests associated with the project.</description>
+ <defaultValue>new UnitTest()</defaultValue>
+ <association>
+ <type>UnitTest</type>
+ </association>
+ </field>
+ <field>
+ <name>outputDirectory</name>
+ <version>4.0.0+</version>
+ <description>The directory where compiled application classes are placed.</description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>testOutputDirectory</name>
+ <version>4.0.0+</version>
+ <description>The directory where compiled test classes are placed.</description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>extensions</name>
+ <version>4.0.0+</version>
+ <description>A set of build extensions to use from this project.</description>
+ <association>
+ <type>Extension</type>
+ <multiplicity>*</multiplicity>
+ </association>
+ </field>
+ </fields>
+ </class>
+ <class java.clone="deep">
+ <name>CiManagement</name>
+ <version>4.0.0+</version>
+ <description>
+ <![CDATA[
+ The <code>&lt;CiManagement&gt;</code> element contains informations required to the
+ continuous integration system of the project.
+ ]]>
+ </description>
+ <fields>
+ <field>
+ <name>system</name>
+ <version>4.0.0+</version>
+ <description>
+ <![CDATA[
+ The name of the continuous integration system, e.g. <code>continuum</code>.
+ ]]>
+ </description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>url</name>
+ <version>4.0.0+</version>
+ <description>URL for the continuous integration system used by the project if it has a web
+ interface.</description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>notifiers</name>
+ <version>4.0.0+</version>
+ <description>Configuration for notifying developers/users when a build is unsuccessful,
+ including user information and notification mode.</description>
+ <association>
+ <multiplicity>*</multiplicity>
+ <type>Notifier</type>
+ </association>
+ </field>
+ </fields>
+ </class>
+ <class java.clone="deep">
+ <name>Notifier</name>
+ <description>Configures one method for notifying users/developers when a build breaks.</description>
+ <version>4.0.0+</version>
+ <fields>
+ <field>
+ <name>type</name>
+ <version>4.0.0+</version>
+ <defaultValue>mail</defaultValue>
+ <type>String</type>
+ <description>The mechanism used to deliver notifications.</description>
+ </field>
+ <field>
+ <name>sendOnError</name>
+ <version>4.0.0+</version>
+ <defaultValue>true</defaultValue>
+ <type>boolean</type>
+ <description>Whether to send notifications on error.</description>
+ </field>
+ <field>
+ <name>sendOnFailure</name>
+ <version>4.0.0+</version>
+ <defaultValue>true</defaultValue>
+ <type>boolean</type>
+ <description>Whether to send notifications on failure.</description>
+ </field>
+ <field>
+ <name>sendOnSuccess</name>
+ <version>4.0.0+</version>
+ <defaultValue>true</defaultValue>
+ <type>boolean</type>
+ <description>Whether to send notifications on success.</description>
+ </field>
+ <field>
+ <name>sendOnWarning</name>
+ <version>4.0.0+</version>
+ <defaultValue>true</defaultValue>
+ <type>boolean</type>
+ <description>Whether to send notifications on warning.</description>
+ </field>
+ <!-- TODO: Remove it after continuum alpha-3 release -->
+ <field>
+ <name>address</name>
+ <version>4.0.0+</version>
+ <type>String</type>
+ <description>
+ <![CDATA[
+ <b>Deprecated</b>. Where to send the notification to - eg email address.
+ ]]>
+ </description>
+ </field>
+ <field>
+ <name>configuration</name>
+ <description>Extended configuration specific to this notifier goes here.</description>
+ <type>Properties</type>
+ <association xml.mapStyle="inline">
+ <type>String</type>
+ <multiplicity>*</multiplicity>
+ </association>
+ </field>
+ </fields>
+ </class>
+ <class java.clone="deep">
+ <name>Contributor</name>
+ <description>Description of a person who has contributed to the project, but who does not have
+ commit privileges. Usually, these contributions come in the form of patches submitted.</description>
+ <version>3.0.0+</version>
+ <fields>
+ <field>
+ <name>name</name>
+ <version>3.0.0+</version>
+ <description>The full name of the contributor.</description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>email</name>
+ <version>3.0.0+</version>
+ <description>The email address of the contributor.</description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>url</name>
+ <version>3.0.0+</version>
+ <description>The URL for the homepage of the contributor.</description>
+ <type>String</type>
+ </field>
+ <!-- TODO: should this just be a single Organization element -->
+ <field>
+ <name>organization</name>
+ <alias>organisation</alias>
+ <version>3.0.0+</version>
+ <description>The organization to which the contributor belongs.</description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>organizationUrl</name>
+ <alias>organisationUrl</alias>
+ <version>3.0.0+</version>
+ <description>The URL of the organization.</description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>roles</name>
+ <version>3.0.0+</version>
+ <description>
+ <![CDATA[
+ The roles the contributor plays in the project. Each role is described by a
+ <code>role</code> element, the body of which is a role name. This can also be used to
+ describe the contribution.
+ ]]>
+ </description>
+ <association>
+ <type>String</type>
+ <multiplicity>*</multiplicity>
+ </association>
+ </field>
+ <field>
+ <name>timezone</name>
+ <version>3.0.0+</version>
+ <description>
+ <![CDATA[
+ The timezone the contributor is in. Typically, this is a number in the range
+ <a href="http://en.wikipedia.org/wiki/UTC%E2%88%9212:00">-12</a> to <a href="http://en.wikipedia.org/wiki/UTC%2B14:00">+14</a>
+ or a valid time zone id like "America/Montreal" (UTC-05:00) or "Europe/Paris" (UTC+01:00).
+ ]]>
+ </description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>properties</name>
+ <version>3.0.0+</version>
+ <description>Properties about the contributor, such as an instant messenger handle.</description>
+ <type>Properties</type>
+ <association xml.mapStyle="inline">
+ <type>String</type>
+ <multiplicity>*</multiplicity>
+ </association>
+ </field>
+ </fields>
+ </class>
+ <class java.clone="deep">
+ <name>Dependency</name>
+ <version>3.0.0+</version>
+ <description>
+ <![CDATA[
+ The <code>&lt;dependency&gt;</code> element contains information about a dependency
+ of the project.
+ ]]>
+ </description>
+ <fields>
+ <field>
+ <name>id</name>
+ <version>3.0.0</version>
+ <required>true</required>
+ <description>
+ <![CDATA[
+ <b>Deprecated</b>. Please use <code>groupId</code> and
+ <code>artifactId</code> together instead.
+ ]]>
+ </description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>groupId</name>
+ <version>3.0.0+</version>
+ <required>true</required>
+ <description>
+ <![CDATA[
+ The project group that produced the dependency, e.g.
+ <code>org.apache.maven</code>.
+ ]]>
+ </description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>artifactId</name>
+ <version>3.0.0+</version>
+ <required>true</required>
+ <description>
+ <![CDATA[
+ The unique id for an artifact produced by the project group, e.g.
+ <code>maven-artifact</code>.
+ ]]>
+ </description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>version</name>
+ <version>3.0.0+</version>
+ <description>
+ <![CDATA[
+ The version of the dependency, e.g. <code>3.2.1</code>. In Maven 2, this can also be
+ specified as a range of versions.
+ ]]>
+ </description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>url</name>
+ <version>3.0.0</version>
+ <description>This url will be provided to the user if the jar file cannot be downloaded
+ from the central repository.</description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>jar</name>
+ <version>3.0.0</version>
+ <description>Literal name of the artifact in the repository. Used to override the
+ calculated artifact name.</description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>type</name>
+ <version>3.0.0</version>
+ <description>
+ <![CDATA[
+ The type of dependency. While it
+ usually represents the extension on the filename of the dependency,
+ that is not always the case.
+ Some examples are <code>jar</code>, <code>war</code>, and <code>plugin</code>.
+ A dependency of type <code>plugin</code> is loaded as a Maven plugin and
+ not added to the project build classpath.
+ ]]>
+ </description>
+ <type>String</type>
+ <defaultValue>jar</defaultValue>
+ </field>
+ <field>
+ <name>type</name>
+ <version>4.0.0+</version>
+ <description>
+ <![CDATA[
+ The type of dependency. While it
+ usually represents the extension on the filename of the dependency,
+ that is not always the case. A type can be mapped to a different
+ extension and a classifier.
+ The type often corresponds to the packaging used, though this is also
+ not always the case.
+ Some examples are <code>jar</code>, <code>war</code>, <code>ejb-client</code>
+ and <code>test-jar</code>: see <a href="../maven-core/artifact-handlers.html">default
+ artifact handlers</a> for a list.
+ New types can be defined by plugins that set
+ <code>extensions</code> to <code>true</code>, so this is not a complete list.
+ ]]>
+ </description>
+ <type>String</type>
+ <defaultValue>jar</defaultValue>
+ </field>
+ <field>
+ <name>classifier</name>
+ <version>4.0.0+</version>
+ <description>
+ <![CDATA[
+ The classifier of the dependency. It is appended to
+ the filename after the version. This allows:
+ <ul>
+ <li>refering to attached artifact, for example <code>sources</code> and <code>javadoc</code>:
+ see <a href="../maven-core/artifact-handlers.html">default artifact handlers</a> for a list,</li>
+ <li>distinguishing two artifacts
+ that belong to the same POM but were built differently.
+ For example, <code>jdk14</code> and <code>jdk15</code>.</li>
+ </ul>
+ ]]>
+ </description>
+ <type>String</type>
+ <required>false</required>
+ </field>
+ <field>
+ <name>properties</name>
+ <version>3.0.0</version>
+ <description>
+ <![CDATA[
+ Properties about the dependency. Various plugins allow you to
+ mark dependencies with properties. For example the war plugin looks for a
+ <code>war.bundle</code> property, and if found will include the
+ dependency in <code>WEB-INF/lib</code>.
+ ]]>
+ </description>
+ <type>Properties</type>
+ <association xml.mapStyle="inline">
+ <type>String</type>
+ <multiplicity>*</multiplicity>
+ </association>
+ </field>
+ <field>
+ <name>scope</name>
+ <version>4.0.0+</version>
+ <description>
+ <![CDATA[
+ The scope of the dependency - <code>compile</code>, <code>runtime</code>,
+ <code>test</code>, <code>system</code>, and <code>provided</code>. Used to
+ calculate the various classpaths used for compilation, testing, and so on.
+ It also assists in determining which artifacts to include in a distribution of
+ this project. For more information, see
+ <a href="http://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html">the
+ dependency mechanism</a>.
+ ]]>
+ </description>
+ <type>String</type>
+ <!-- This default has to be enforced at the maven-artifact layer, to allow
+ | injection of defaults from <dependencyManagement/>.
+ | TODO: how can we document it?
+ |-->
+ <!-- defaultValue>compile</defaultValue -->
+ </field>
+ <field>
+ <name>systemPath</name>
+ <version>4.0.0+</version>
+ <description>
+ <![CDATA[
+ FOR SYSTEM SCOPE ONLY. Note that use of this property is <b>discouraged</b>
+ and may be replaced in later versions. This specifies the path on the filesystem
+ for this dependency.
+ Requires an absolute path for the value, not relative.
+ Use a property that gives the machine specific absolute path,
+ e.g. <code>${java.home}</code>.
+ ]]>
+ </description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>exclusions</name>
+ <version>4.0.0+</version>
+ <description>Lists a set of artifacts that should be excluded from this dependency's
+ artifact list when it comes to calculating transitive dependencies.</description>
+ <association>
+ <type>Exclusion</type>
+ <multiplicity>*</multiplicity>
+ </association>
+ </field>
+ <field>
+ <name>optional</name>
+ <version>4.0.0+</version>
+ <description>
+ <![CDATA[
+ Indicates the dependency is optional for use of this library. While the
+ version of the dependency will be taken into account for dependency calculation if the
+ library is used elsewhere, it will not be passed on transitively. Note: While the type
+ of this field is <code>String</code> for technical reasons, the semantic type is actually
+ <code>Boolean</code>. Default value is <code>false</code>.
+ ]]>
+ </description>
+ <type>String</type>
+ </field>
+ </fields>
+ <codeSegments>
+ <codeSegment>
+ <version>3.0.0</version>
+ <code>
+ <![CDATA[
+ /**
+ * @see java.lang.Object#toString()
+ */
+ public String toString()
+ {
+ return groupId + "/" + type + "s:" + artifactId + "-" + version;
+ }
+ ]]>
+ </code>
+ </codeSegment>
+ <codeSegment>
+ <version>4.0.0+</version>
+ <code>
+ <![CDATA[
+ public boolean isOptional()
+ {
+ return ( optional != null ) ? Boolean.parseBoolean( optional ) : false;
+ }
+
+ public void setOptional( boolean optional )
+ {
+ this.optional = String.valueOf( optional );
+ }
+
+ /**
+ * @see java.lang.Object#toString()
+ */
+ public String toString()
+ {
+ return "Dependency {groupId=" + groupId + ", artifactId=" + artifactId + ", version=" + version + ", type=" + type + "}";
+ }
+ ]]>
+ </code>
+ </codeSegment>
+ <codeSegment>
+ <version>4.0.0+</version>
+ <code>
+ <![CDATA[
+ private String managementKey;
+
+ /**
+ * @return the management key as <code>groupId:artifactId:type</code>
+ */
+ public String getManagementKey()
+ {
+ if ( managementKey == null )
+ {
+ managementKey = groupId + ":" + artifactId + ":" + type + ( classifier != null ? ":" + classifier : "" );
+ }
+ return managementKey;
+ }
+ ]]>
+ </code>
+ </codeSegment>
+ <codeSegment>
+ <version>3.0.0</version>
+ <code>
+ <![CDATA[
+ /**
+ * @return the key as <code>id:type</code>
+ */
+ public String getKey()
+ {
+ return getId() + ":" + getType();
+ }
+
+ /**
+ * @return the groupId as artifact directory
+ */
+ public String getArtifactDirectory()
+ {
+ return getGroupId();
+ }
+
+ /**
+ * @return the artifact name as <code>artifactId-version.extension</code> if &lt;jar/&gt; not set
+ */
+ public String getArtifact()
+ {
+ // If the jar name has been explicty set then use that. This
+ // is when the <jar/> element is explicity used in the POM.
+ if ( getJar() != null)
+ {
+ return getJar();
+ }
+
+ String artifact;
+
+ if ("ejb-client".equals(getType())) {
+ artifact = getArtifactId() + "-" + getVersion() + "-client." + getExtension();
+ } else {
+ artifact = getArtifactId() + "-" + getVersion() + "." + getExtension();
+ }
+
+ return artifact;
+ }
+
+ public String getTypeDirectory()
+ {
+ String path;
+ if (getType().equals("ejb-client")) {
+ path = "ejbs";
+ } else {
+ path = getType() + "s";
+ }
+
+ return path;
+ }
+
+ public String getExtension()
+ {
+ if ("ejb".equals(getType()) || "ejb-client".equals(getType()) || "plugin".equals(getType()) || "aspect".equals(getType()) || "uberjar".equals(getType())) return "jar";
+ return getType();
+ }
+
+ public boolean isAddedToClasspath()
+ {
+ return ("jar".equals(getType()) || "ejb".equals(getType()) || "ejb-client".equals(getType()) || "sar".equals(getType()));
+ }
+
+ public boolean isPlugin()
+ {
+ return ("plugin".equals(getType()));
+ }
+
+ public String getProperty( String property )
+ {
+ return getProperties().getProperty( property );
+ }
+
+ /**
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ public boolean equals( Object o )
+ {
+ if ( this == o )
+ {
+ return true;
+ }
+
+ if ( !( o instanceof Dependency ) )
+ {
+ return false;
+ }
+
+ Dependency d = (Dependency) o;
+ return getId().equals( d.getId() );
+ }
+
+ /**
+ * @see java.lang.Object#hashCode()
+ */
+ public int hashCode()
+ {
+ return getId().hashCode();
+ }
+ ]]>
+ </code>
+ </codeSegment>
+ </codeSegments>
+ </class>
+ <class>
+ <superClass>Contributor</superClass>
+ <name>Developer</name>
+ <description>Information about one of the committers on this project.</description>
+ <version>3.0.0+</version>
+ <fields>
+ <field>
+ <name>id</name>
+ <version>3.0.0+</version>
+ <description>The unique ID of the developer in the SCM.</description>
+ <type>String</type>
+ </field>
+ </fields>
+ </class>
+ <class java.clone="deep">
+ <name>Exclusion</name>
+ <version>4.0.0+</version>
+ <description>
+ <![CDATA[
+ The <code>&lt;exclusion&gt;</code> element contains informations required to exclude
+ an artifact to the project.
+ ]]>
+ </description>
+ <fields>
+ <field>
+ <name>artifactId</name>
+ <version>4.0.0+</version>
+ <description>The artifact ID of the project to exclude.</description>
+ <type>String</type>
+ <required>true</required>
+ </field>
+ <field>
+ <name>groupId</name>
+ <version>4.0.0+</version>
+ <description>The group ID of the project to exclude.</description>
+ <type>String</type>
+ <required>true</required>
+ </field>
+ </fields>
+ </class>
+ <class java.clone="deep">
+ <name>IssueManagement</name>
+ <description>Information about the issue tracking (or bug tracking) system used to manage this
+ project.</description>
+ <version>4.0.0+</version>
+ <fields>
+ <field>
+ <name>system</name>
+ <version>4.0.0+</version>
+ <description>The name of the issue management system, e.g. Bugzilla</description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>url</name>
+ <version>4.0.0+</version>
+ <description>URL for the issue management system used by the project.</description>
+ <type>String</type>
+ </field>
+ </fields>
+ </class>
+ <class java.clone="deep">
+ <name>DistributionManagement</name>
+ <version>4.0.0+</version>
+ <description>This elements describes all that pertains to distribution for a project. It is
+ primarily used for deployment of artifacts and the site produced by the build.</description>
+ <fields>
+ <field>
+ <name>repository</name>
+ <version>4.0.0+</version>
+ <description>Information needed to deploy the artifacts generated by the project to a
+ remote repository.</description>
+ <association>
+ <type>DeploymentRepository</type>
+ </association>
+ </field>
+ <field>
+ <name>snapshotRepository</name>
+ <version>4.0.0+</version>
+ <description>
+ <![CDATA[
+ Where to deploy snapshots of artifacts to. If not given, it defaults to the
+ <code>repository</code> element.
+ ]]>
+ </description>
+ <association>
+ <type>DeploymentRepository</type>
+ </association>
+ </field>
+ <field>
+ <name>site</name>
+ <description>Information needed for deploying the web site of the project.</description>
+ <version>4.0.0+</version>
+ <association>
+ <type>Site</type>
+ </association>
+ </field>
+ <field>
+ <name>downloadUrl</name>
+ <version>4.0.0+</version>
+ <description>
+ <![CDATA[
+ The URL of the project's download page. If not given users will be
+ referred to the homepage given by <code>url</code>.
+ This is given to assist in locating artifacts that are not in the repository due to
+ licensing restrictions.
+ ]]>
+ </description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>relocation</name>
+ <version>4.0.0+</version>
+ <description>Relocation information of the artifact if it has been moved to a new group ID
+ and/or artifact ID.</description>
+ <association>
+ <type>Relocation</type>
+ </association>
+ </field>
+ <field>
+ <name>status</name>
+ <version>4.0.0+</version>
+ <description>
+ <![CDATA[
+ Gives the status of this artifact in the remote repository.
+ This must not be set in your local project, as it is updated by
+ tools placing it in the reposiory. Valid values are: <code>none</code> (default),
+ <code>converted</code> (repository manager converted this from an Maven 1 POM),
+ <code>partner</code>
+ (directly synced from a partner Maven 2 repository), <code>deployed</code> (was deployed from a Maven 2
+ instance), <code>verified</code> (has been hand verified as correct and final).
+ ]]>
+ </description>
+ <required>false</required>
+ <type>String</type>
+ </field>
+ </fields>
+ </class>
+ <class java.clone="deep">
+ <name>License</name>
+ <description>Describes the licenses for this project. This is used to generate the license
+ page of the project's web site, as well as being taken into consideration in other reporting
+ and validation. The licenses listed for the project are that of the project itself, and not
+ of dependencies.</description>
+ <version>3.0.0+</version>
+ <fields>
+ <field>
+ <name>name</name>
+ <version>3.0.0+</version>
+ <description>The full legal name of the license.</description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>url</name>
+ <version>3.0.0+</version>
+ <description>The official url for the license text.</description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>distribution</name>
+ <version>3.0.0+</version>
+ <description>
+ <![CDATA[
+ The primary method by which this project may be distributed.
+ <dl>
+ <dt>repo</dt>
+ <dd>may be downloaded from the Maven repository</dd>
+ <dt>manual</dt>
+ <dd>user must manually download and install the dependency.</dd>
+ </dl>
+ ]]>
+ </description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>comments</name>
+ <description>Addendum information pertaining to this license.</description>
+ <version>3.0.0+</version>
+ <type>String</type>
+ </field>
+ </fields>
+ </class>
+ <class java.clone="deep">
+ <name>MailingList</name>
+ <version>3.0.0+</version>
+ <description>This element describes all of the mailing lists associated with a project. The
+ auto-generated site references this information.</description>
+ <fields>
+ <field>
+ <name>name</name>
+ <version>3.0.0+</version>
+ <description>
+ <![CDATA[
+ The name of the mailing list.
+ ]]>
+ </description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>subscribe</name>
+ <version>3.0.0+</version>
+ <description>
+ <![CDATA[
+ The email address or link that can be used to subscribe to
+ the mailing list. If this is an email address, a
+ <code>mailto:</code> link will automatically be created
+ when the documentation is created.
+ ]]>
+ </description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>unsubscribe</name>
+ <version>3.0.0+</version>
+ <description>
+ <![CDATA[
+ The email address or link that can be used to unsubscribe to
+ the mailing list. If this is an email address, a
+ <code>mailto:</code> link will automatically be created
+ when the documentation is created.
+ ]]>
+ </description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>post</name>
+ <version>3.0.0+</version>
+ <description>
+ <![CDATA[
+ The email address or link that can be used to post to
+ the mailing list. If this is an email address, a
+ <code>mailto:</code> link will automatically be created
+ when the documentation is created.
+ ]]>
+ </description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>archive</name>
+ <version>3.0.0+</version>
+ <description>The link to a URL where you can browse the mailing list archive.</description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>otherArchives</name>
+ <version>3.0.0+</version>
+ <description>The link to alternate URLs where you can browse the list archive.</description>
+ <association>
+ <type>String</type>
+ <multiplicity>*</multiplicity>
+ </association>
+ </field>
+ </fields>
+ <comment>We could probably have a specific element for a dev mailing list for things like CI,
+ and maybe even a specific element for the user and scm mailing lists. Then leave the more
+ lose structure for any other type of mailing list.</comment>
+ </class>
+ <class java.clone="deep">
+ <name>Organization</name>
+ <description>Specifies the organization that produces this project.</description>
+ <version>3.0.0+</version>
+ <fields>
+ <field>
+ <name>name</name>
+ <version>3.0.0+</version>
+ <description>The full name of the organization.</description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>url</name>
+ <version>3.0.0+</version>
+ <description>The URL to the organization's home page.</description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>logo</name>
+ <version>3.0.0</version>
+ <description>
+ <![CDATA[
+ The URL to the organization's logo image. This can be an URL relative
+ to the base directory of the generated web site,
+ (e.g., <code>/images/org-logo.png</code>) or an absolute URL
+ (e.g., <code>http://my.corp/logo.png</code>). This value is used
+ when generating the project documentation.
+ ]]>
+ </description>
+ <type>String</type>
+ </field>
+ </fields>
+ </class>
+ <class>
+ <name>PackageGroup</name>
+ <version>3.0.0</version>
+ <description>A JavaDoc package group.</description>
+ <fields>
+ <field>
+ <name>title</name>
+ <version>3.0.0</version>
+ <description>The title to use for the package group.</description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>packages</name>
+ <version>3.0.0</version>
+ <description>The packages in the group</description>
+ <type>String</type>
+ </field>
+ </fields>
+ </class>
+ <class java.clone="deep">
+ <name>PatternSet</name>
+ <version>3.0.0+</version>
+ <description>Definition of include or exclude patterns.</description>
+ <fields>
+ <field>
+ <name>includes</name>
+ <version>3.0.0+</version>
+ <description>
+ <![CDATA[
+ A list of patterns to include, e.g. <code>**&#47;*.xml</code>.
+ ]]>
+ </description>
+ <association>
+ <type>String</type>
+ <multiplicity>*</multiplicity>
+ </association>
+ </field>
+ <field>
+ <name>excludes</name>
+ <version>3.0.0+</version>
+ <description>
+ <![CDATA[
+ A list of patterns to exclude, e.g. <code>**&#47;*.xml</code>
+ ]]>
+ </description>
+ <association>
+ <type>String</type>
+ <multiplicity>*</multiplicity>
+ </association>
+ </field>
+ </fields>
+ <codeSegments>
+ <codeSegment>
+ <version>4.0.0+</version>
+ <code>
+ <![CDATA[
+ /**
+ * @see java.lang.Object#toString()
+ */
+ public String toString()
+ {
+ StringBuilder sb = new StringBuilder( 128 );
+
+ sb.append("PatternSet [includes: {");
+ for (java.util.Iterator i = getIncludes().iterator(); i.hasNext(); )
+ {
+ String str = (String) i.next();
+ sb.append(str).append(", ");
+ }
+ if (sb.substring(sb.length() - 2).equals(", ")) sb.delete(sb.length() - 2, sb.length());
+
+ sb.append("}, excludes: {");
+ for (java.util.Iterator i = getExcludes().iterator(); i.hasNext(); )
+ {
+ String str = (String) i.next();
+ sb.append(str).append(", ");
+ }
+ if (sb.substring(sb.length() - 2).equals(", ")) sb.delete(sb.length() - 2, sb.length());
+
+ sb.append("}]");
+ return sb.toString();
+ }
+ ]]>
+ </code>
+ </codeSegment>
+ </codeSegments>
+ </class>
+ <class java.clone="deep">
+ <name>Parent</name>
+ <version>4.0.0+</version>
+ <description>
+ <![CDATA[
+ The <code>&lt;parent&gt;</code> element contains information required to locate the parent project from which
+ this project will inherit from.
+ <strong>Note:</strong> The children of this element are not interpolated and must be given as literal values.
+ ]]>
+ </description>
+ <fields>
+ <field>
+ <name>groupId</name>
+ <version>4.0.0+</version>
+ <description>The group id of the parent project to inherit from.</description>
+ <required>true</required>
+ <type>String</type>
+ </field>
+ <field>
+ <name>artifactId</name>
+ <version>4.0.0+</version>
+ <description>The artifact id of the parent project to inherit from.</description>
+ <required>true</required>
+ <type>String</type>
+ </field>
+ <field>
+ <name>version</name>
+ <version>4.0.0+</version>
+ <description>The version of the parent project to inherit.</description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>relativePath</name>
+ <version>4.0.0+</version>
+ <description>
+ <![CDATA[
+ The relative path of the parent <code>pom.xml</code> file within the check out.
+ If not specified, it defaults to <code>../pom.xml</code>.
+ Maven looks for the parent POM first in this location on
+ the filesystem, then the local repository, and lastly in the remote repo.
+ <code>relativePath</code> allows you to select a different location,
+ for example when your structure is flat, or deeper without an intermediate parent POM.
+ However, the group ID, artifact ID and version are still required,
+ and must match the file in the location given or it will revert to the repository for the POM.
+ This feature is only for enhancing the development in a local checkout of that project.
+ Set the value to an empty string in case you want to disable the feature and always resolve
+ the parent POM from the repositories.
+ ]]>
+ </description>
+ <type>String</type>
+ <defaultValue>../pom.xml</defaultValue>
+ </field>
+ </fields>
+ <codeSegments>
+ <codeSegment>
+ <version>4.0.0+</version>
+ <code>
+ <![CDATA[
+ /**
+ * @return the id as <code>groupId:artifactId:version</code>
+ */
+ public String getId()
+ {
+ StringBuilder id = new StringBuilder( 64 );
+
+ id.append( getGroupId() );
+ id.append( ":" );
+ id.append( getArtifactId() );
+ id.append( ":" );
+ id.append( "pom" );
+ id.append( ":" );
+ id.append( getVersion() );
+
+ return id.toString();
+ }
+
+ @Override
+ public String toString()
+ {
+ return getId();
+ }
+ ]]>
+ </code>
+ </codeSegment>
+ </codeSegments>
+
+ </class>
+ <class>
+ <name>Repository</name>
+ <version>3.0.0</version>
+ <description>
+ <![CDATA[
+ The <code>&lt;repository&gt;</code> element contains informations required to a repository
+ used by the project.
+ ]]>
+ </description>
+ <fields>
+ <field>
+ <name>connection</name>
+ <version>3.0.0</version>
+ <description>
+ <![CDATA[
+ The source control management system URL
+ that describes the repository and how to connect to the
+ repository. For more information, see the
+ <a href="http://maven.apache.org/scm/scm-url-format.html">URL format</a>
+ and <a href="http://maven.apache.org/scm/scms-overview.html">list of supported SCMs</a>.
+ This connection is read-only.
+ ]]>
+ </description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>developerConnection</name>
+ <version>3.0.0</version>
+ <description>
+ <![CDATA[
+ Just like <code>connection</code>, but for developers, i.e. this scm connection
+ will not be read only.
+ ]]>
+ </description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>url</name>
+ <version>3.0.0</version>
+ <description>The URL to the project's browsable SCM repository, such as ViewVC or Fisheye.</description>
+ <type>String</type>
+ </field>
+ </fields>
+ </class>
+ <class java.clone="deep">
+ <name>Scm</name>
+ <version>4.0.0+</version>
+ <description>
+ <![CDATA[
+ The <code>&lt;scm&gt;</code> element contains informations required to the SCM
+ (Source Control Management) of the project.
+ ]]>
+ </description>
+ <fields>
+ <field>
+ <name>connection</name>
+ <version>4.0.0+</version>
+ <description>
+ <![CDATA[
+ The source control management system URL
+ that describes the repository and how to connect to the
+ repository. For more information, see the
+ <a href="http://maven.apache.org/scm/scm-url-format.html">URL format</a>
+ and <a href="http://maven.apache.org/scm/scms-overview.html">list of supported SCMs</a>.
+ This connection is read-only.
+ <br /><b>Default value is</b>: parent value [+ path adjustment] + artifactId
+ ]]>
+ </description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>developerConnection</name>
+ <version>4.0.0+</version>
+ <description>
+ <![CDATA[
+ Just like <code>connection</code>, but for developers, i.e. this scm connection
+ will not be read only.
+ <br /><b>Default value is</b>: parent value [+ path adjustment] + artifactId
+ ]]>
+ </description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>tag</name>
+ <version>4.0.0+</version>
+ <description>The tag of current code. By default, it's set to HEAD during development.</description>
+ <type>String</type>
+ <defaultValue>HEAD</defaultValue>
+ </field>
+ <field>
+ <name>url</name>
+ <version>4.0.0+</version>
+ <description>
+ <![CDATA[
+ The URL to the project's browsable SCM repository, such as ViewVC or Fisheye.
+ <br /><b>Default value is</b>: parent value [+ path adjustment] + artifactId
+ ]]>
+ </description>
+ <type>String</type>
+ </field>
+ </fields>
+ </class>
+ <class>
+ <name>FileSet</name>
+ <version>3.0.0+</version>
+ <superClass>PatternSet</superClass>
+ <description>A PatternSet for files.</description>
+ <fields>
+ <field>
+ <name>directory</name>
+ <version>3.0.0+</version>
+ <description>Describe the directory where the resources are stored. The path is relative
+ to the POM.</description>
+ <type>String</type>
+ </field>
+ </fields>
+ <codeSegments>
+ <codeSegment>
+ <version>4.0.0+</version>
+ <code>
+ <![CDATA[
+ /**
+ * @see java.lang.Object#toString()
+ */
+ public String toString()
+ {
+ return "FileSet {directory: " + getDirectory() + ", " + super.toString() + "}";
+ }
+ ]]>
+ </code>
+ </codeSegment>
+ </codeSegments>
+ </class>
+ <class>
+ <name>Resource</name>
+ <description>This element describes all of the classpath resources associated with a project
+ or unit tests.</description>
+ <version>3.0.0+</version>
+ <superClass>FileSet</superClass>
+ <fields>
+ <field>
+ <name>targetPath</name>
+ <version>3.0.0+</version>
+ <description>
+ <![CDATA[
+ Describe the resource target path. The path is relative to the target/classes
+ directory (i.e. <code>${project.build.outputDirectory}</code>).
+ For example, if you want that resource to appear in a specific package
+ (<code>org.apache.maven.messages</code>), you must specify this
+ element with this value: <code>org/apache/maven/messages</code>.
+ This is not required if you simply put the resources in that directory
+ structure at the source, however.
+ ]]>
+ </description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>filtering</name>
+ <version>3.0.0+</version>
+ <description>
+ <![CDATA[
+ Whether resources are filtered to replace tokens with parameterised values or not.
+ The values are taken from the <code>properties</code> element and from the
+ properties in the files listed in the <code>filters</code> element. Note: While the type
+ of this field is <code>String</code> for technical reasons, the semantic type is actually
+ <code>Boolean</code>. Default value is <code>false</code>.
+ ]]>
+ </description>
+ <type>String</type>
+ </field>
+ <field xml.transient="true">
+ <name>mergeId</name>
+ <version>4.0.0+</version>
+ <description>
+ <![CDATA[
+ FOR INTERNAL USE ONLY. This is a unique identifier assigned to each
+ resource to allow Maven to merge changes to this resource that take
+ place during the execution of a plugin. This field must be managed
+ by the generated parser and formatter classes in order to allow it
+ to survive model interpolation.
+ ]]>
+ </description>
+ <type>String</type>
+ </field>
+ </fields>
+ <codeSegments>
+ <codeSegment>
+ <version>4.0.0+</version>
+ <code>
+ <![CDATA[
+ private static int mergeIdCounter = 0;
+
+ public void initMergeId()
+ {
+ if ( getMergeId() == null )
+ {
+ setMergeId( "resource-" + (mergeIdCounter++) );
+ }
+ }
+
+ public boolean isFiltering()
+ {
+ return ( filtering != null ) ? Boolean.parseBoolean( filtering ) : false;
+ }
+
+ public void setFiltering( boolean filtering )
+ {
+ this.filtering = String.valueOf( filtering );
+ }
+
+ /**
+ * @see java.lang.Object#toString()
+ */
+ public String toString()
+ {
+ return "Resource {targetPath: " + getTargetPath() + ", filtering: " + isFiltering() + ", " + super.toString() + "}";
+ }
+ ]]>
+ </code>
+ </codeSegment>
+ </codeSegments>
+ </class>
+ <class>
+ <name>SourceModification</name>
+ <description>This element describes all of the source modifications associated with a project.
+ These modifications are used to exclude or include various source depending on the
+ environment the build is running in.</description>
+ <version>3.0.0</version>
+ <superClass>FileSet</superClass>
+ <fields>
+ <field>
+ <name>className</name>
+ <version>3.0.0</version>
+ <description>
+ <![CDATA[
+ If the class with this name can <b>not</b> be
+ loaded, then the includes and excludes specified below
+ will be applied to the contents of the <code>sourceDirectory</code>.
+ ]]>
+ </description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>property</name>
+ <version>3.0.0</version>
+ <description>
+ <![CDATA[
+ If the property with this name is <b>not</b> set,
+ then the includes and excludes specified below
+ will be applied to the contents of the <code>sourceDirectory</code>.
+ ]]>
+ </description>
+ <type>String</type>
+ </field>
+ </fields>
+ </class>
+ <class>
+ <name>UnitTest</name>
+ <version>3.0.0</version>
+ <superClass>PatternSet</superClass>
+ <description>A PatternSet for unit tests.</description>
+ <fields>
+ <field>
+ <name>resources</name>
+ <version>3.0.0</version>
+ <description>The classpath resources to use when executing the unit tests.</description>
+ <association>
+ <type>Resource</type>
+ <multiplicity>*</multiplicity>
+ </association>
+ </field>
+ </fields>
+ </class>
+ <class>
+ <name>Version</name>
+ <version>3.0.0</version>
+ <description>
+ <![CDATA[
+ This element describes each of the previous versions of the
+ project. Each version is described by a <code>version</code>
+ element
+ ]]>
+ </description>
+ <fields>
+ <field>
+ <name>name</name>
+ <version>3.0.0</version>
+ <description>
+ <![CDATA[
+ The external version number under which this release was distributed. Examples include:
+ <code>1.0</code>,
+ <code>1.1-alpha1</code>,
+ <code>1.2-beta</code>,
+ <code>1.3.2</code> etc.
+ ]]>
+ </description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>tag</name>
+ <version>3.0.0</version>
+ <description>The name given in the SCM (e.g. CVS) used by the project for the source code
+ associated with this version of the project.</description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>id</name>
+ <version>3.0.0</version>
+ <description>A unique identifier for a version. This is usually identical to the name.</description>
+ <type>String</type>
+ </field>
+ </fields>
+ <codeSegments>
+ <codeSegment>
+ <version>3.0.0</version>
+ <code>
+ <![CDATA[
+ /**
+ * @see java.lang.Object#toString()
+ */
+ public String toString()
+ {
+ return getId();
+ }
+ ]]>
+ </code>
+ </codeSegment>
+ </codeSegments>
+ </class>
+
+ <class java.clone="deep">
+ <name>RepositoryBase</name>
+ <version>4.0.0+</version>
+ <description>A repository contains the information needed for establishing connections with
+ remote repository.</description>
+ <fields>
+ <field>
+ <name>id</name>
+ <version>4.0.0+</version>
+ <required>true</required>
+ <identifier>true</identifier>
+ <description>
+ <![CDATA[
+ A unique identifier for a repository. This is used to match the repository
+ to configuration in the <code>settings.xml</code> file, for example. Furthermore, the identifier is
+ used during POM inheritance and profile injection to detect repositories that should be merged.
+ ]]>
+ </description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>name</name>
+ <version>4.0.0+</version>
+ <description>Human readable name of the repository.</description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>url</name>
+ <version>4.0.0+</version>
+ <required>true</required>
+ <description>
+ <![CDATA[
+ The url of the repository, in the form <code>protocol://hostname/path</code>.
+ ]]>
+ </description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>layout</name>
+ <version>4.0.0+</version>
+ <description>
+ <![CDATA[
+ The type of layout this repository uses for locating and storing artifacts -
+ can be <code>legacy</code> or <code>default</code>.
+ ]]>
+ </description>
+ <type>String</type>
+ <defaultValue>default</defaultValue>
+ </field>
+ </fields>
+ </class>
+
+ <class>
+ <name>Repository</name>
+ <superClass>RepositoryBase</superClass>
+ <version>4.0.0+</version>
+ <description>A repository contains the information needed for establishing connections with
+ remote repository.</description>
+ <fields>
+ <field>
+ <name>releases</name>
+ <version>4.0.0+</version>
+ <description>How to handle downloading of releases from this repository.</description>
+ <association>
+ <type>RepositoryPolicy</type>
+ </association>
+ </field>
+ <field>
+ <name>snapshots</name>
+ <version>4.0.0+</version>
+ <description>How to handle downloading of snapshots from this repository.</description>
+ <association>
+ <type>RepositoryPolicy</type>
+ </association>
+ </field>
+ </fields>
+ </class>
+
+ <class>
+ <name>DeploymentRepository</name>
+ <superClass>Repository</superClass>
+ <version>4.0.0+</version>
+ <description>Repository contains the information needed for deploying to the remote
+ repository.</description>
+ <fields>
+ <field>
+ <name>uniqueVersion</name>
+ <description>Whether to assign snapshots a unique version comprised of the timestamp and
+ build number, or to use the same version each time</description>
+ <type>boolean</type>
+ <defaultValue>true</defaultValue>
+ <version>4.0.0+</version>
+ </field>
+ </fields>
+ </class>
+
+ <class java.clone="deep">
+ <name>RepositoryPolicy</name>
+ <version>4.0.0+</version>
+ <description>Download policy.</description>
+ <fields>
+ <field>
+ <name>enabled</name>
+ <version>4.0.0+</version>
+ <description>
+ <![CDATA[
+ Whether to use this repository for downloading this type of artifact. Note: While the type
+ of this field is <code>String</code> for technical reasons, the semantic type is actually
+ <code>Boolean</code>. Default value is <code>true</code>.
+ ]]>
+ </description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>updatePolicy</name>
+ <version>4.0.0+</version>
+ <description>
+ <![CDATA[
+ The frequency for downloading updates - can be
+ <code>always,</code>
+ <code>daily</code>
+ (default),
+ <code>interval:XXX</code>
+ (in minutes) or
+ <code>never</code>
+ (only if it doesn't exist locally).
+ ]]>
+ </description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>checksumPolicy</name>
+ <version>4.0.0+</version>
+ <description>
+ <![CDATA[
+ What to do when verification of an artifact checksum fails. Valid values are
+ <code>ignore</code>
+ ,
+ <code>fail</code>
+ or
+ <code>warn</code>
+ (the default).
+ ]]>
+ </description>
+ <type>String</type>
+ </field>
+ </fields>
+ <codeSegments>
+ <codeSegment>
+ <version>4.0.0+</version>
+ <code>
+ <![CDATA[
+
+ public boolean isEnabled()
+ {
+ return ( enabled != null ) ? Boolean.parseBoolean( enabled ) : true;
+ }
+
+ public void setEnabled( boolean enabled )
+ {
+ this.enabled = String.valueOf( enabled );
+ }
+
+ ]]>
+ </code>
+ </codeSegment>
+ </codeSegments>
+ </class>
+
+ <!--@todo find better solution for management of site deployments -->
+ <class java.clone="deep">
+ <name>Site</name>
+ <version>4.0.0+</version>
+ <description>Contains the information needed for deploying websites.</description>
+ <fields>
+ <field>
+ <name>id</name>
+ <version>4.0.0+</version>
+ <description>
+ <![CDATA[
+ A unique identifier for a deployment location. This is used to match the
+ site to configuration in the <code>settings.xml</code> file, for example.
+ ]]>
+ </description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>name</name>
+ <version>4.0.0+</version>
+ <description>Human readable name of the deployment location.</description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>url</name>
+ <version>4.0.0+</version>
+ <description>
+ <![CDATA[
+ The url of the location where website is deployed, in the form <code>protocol://hostname/path</code>.
+ <br /><b>Default value is</b>: parent value [+ path adjustment] + artifactId
+ ]]>
+ </description>
+ <type>String</type>
+ </field>
+ </fields>
+ </class>
+
+ <class java.clone="deep">
+ <name>ConfigurationContainer</name>
+ <version>4.0.0+</version>
+ <description>Contains the configuration information of the container like Plugin.</description>
+ <fields>
+ <field>
+ <name>inherited</name>
+ <version>4.0.0+</version>
+ <description>
+ <![CDATA[
+ Whether any configuration should be propagated to child POMs. Note: While the type
+ of this field is <code>String</code> for technical reasons, the semantic type is actually
+ <code>Boolean</code>. Default value is <code>true</code>.
+ ]]>
+ </description>
+ <type>String</type>
+ </field>
+ <field>
+ <description>
+ <![CDATA[
+ <p>The configuration as DOM object.</p>
+ <p>By default, every element content is trimmed, but starting with Maven 3.1.0, you can add
+ <code>xml:space="preserve"</code> to elements you want to preserve whitespace.</p>
+ <p>You can control how child POMs inherit configuration from parent POMs by adding <code>combine.children</code>
+ or <code>combine.self</code> attributes to the children of the configuration element:</p>
+ <ul>
+ <li><code>combine.children</code>: available values are <code>merge</code> (default) and <code>append</code>,</li>
+ <li><code>combine.self</code>: available values are <code>merge</code> (default) and <code>override</code>.</li>
+ </ul>
+ <p>See <a href="http://maven.apache.org/pom.html#Plugins">POM Reference documentation</a> and
+ <a href="http://plexus.codehaus.org/plexus-utils/apidocs/org/codehaus/plexus/util/xml/Xpp3DomUtils.html">Xpp3DomUtils</a>
+ for more information.</p>
+ ]]>
+ </description>
+ <name>configuration</name>
+ <type>DOM</type>
+ </field>
+ </fields>
+ <codeSegments>
+ <codeSegment>
+ <version>4.0.0+</version>
+ <code>
+ <![CDATA[
+ public boolean isInherited()
+ {
+ return ( inherited != null ) ? Boolean.parseBoolean( inherited ) : true;
+ }
+
+ public void setInherited( boolean inherited )
+ {
+ this.inherited = String.valueOf( inherited );
+ }
+
+ private boolean inheritanceApplied = true;
+
+ public void unsetInheritanceApplied()
+ {
+ this.inheritanceApplied = false;
+ }
+
+ public boolean isInheritanceApplied()
+ {
+ return inheritanceApplied;
+ }
+ ]]>
+ </code>
+ </codeSegment>
+ </codeSegments>
+ </class>
+ <class>
+ <name>Plugin</name>
+ <version>4.0.0+</version>
+ <superClass>ConfigurationContainer</superClass>
+ <description>
+ <![CDATA[
+ The <code>&lt;plugin&gt;</code> element contains informations required for a plugin.
+ ]]>
+ </description>
+ <fields>
+ <field>
+ <name>groupId</name>
+ <description>The group ID of the plugin in the repository.</description>
+ <version>4.0.0+</version>
+ <type>String</type>
+ <defaultValue>org.apache.maven.plugins</defaultValue>
+ </field>
+ <field>
+ <name>artifactId</name>
+ <description>The artifact ID of the plugin in the repository.</description>
+ <version>4.0.0+</version>
+ <type>String</type>
+ <required>true</required>
+ </field>
+ <field>
+ <name>version</name>
+ <version>4.0.0+</version>
+ <description>The version (or valid range of versions) of the plugin to be used.</description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>extensions</name>
+ <version>4.0.0+</version>
+ <type>String</type>
+ <description>
+ <![CDATA[
+ Whether to load Maven extensions (such as packaging and type handlers) from
+ this plugin. For performance reasons, this should only be enabled when necessary. Note: While the type
+ of this field is <code>String</code> for technical reasons, the semantic type is actually
+ <code>Boolean</code>. Default value is <code>false</code>.
+ ]]>
+ </description>
+ </field>
+ <field>
+ <name>executions</name>
+ <version>4.0.0+</version>
+ <description>Multiple specifications of a set of goals to execute during the build
+ lifecycle, each having (possibly) a different configuration.</description>
+ <association>
+ <type>PluginExecution</type>
+ <multiplicity>*</multiplicity>
+ </association>
+ </field>
+ <field>
+ <name>dependencies</name>
+ <description>Additional dependencies that this project needs to introduce to the plugin's
+ classloader.</description>
+ <version>4.0.0+</version>
+ <association>
+ <type>Dependency</type>
+ <multiplicity>*</multiplicity>
+ </association>
+ </field>
+ <field>
+ <name>goals</name>
+ <version>4.0.0+</version>
+ <description>
+ <![CDATA[
+ <b>Deprecated</b>. Unused by Maven.
+ ]]>
+ </description>
+ <type>DOM</type>
+ </field>
+ </fields>
+ <codeSegments>
+ <codeSegment>
+ <version>4.0.0+</version>
+ <code>
+ <![CDATA[
+ public boolean isExtensions()
+ {
+ return ( extensions != null ) ? Boolean.parseBoolean( extensions ) : false;
+ }
+
+ public void setExtensions( boolean extensions )
+ {
+ this.extensions = String.valueOf( extensions );
+ }
+
+ private java.util.Map<String, PluginExecution> executionMap = null;
+
+ /**
+ * Reset the <code>executionMap</code> field to <code>null</code>
+ */
+ public void flushExecutionMap()
+ {
+ this.executionMap = null;
+ }
+
+ /**
+ * @return a Map of executions field with <code>PluginExecution#getId()</code> as key
+ * @see org.apache.maven.model.PluginExecution#getId()
+ */
+ public java.util.Map<String, PluginExecution> getExecutionsAsMap()
+ {
+ if ( executionMap == null )
+ {
+ executionMap = new java.util.LinkedHashMap<String, PluginExecution>();
+ if ( getExecutions() != null )
+ {
+ for ( java.util.Iterator<PluginExecution> i = getExecutions().iterator(); i.hasNext(); )
+ {
+ PluginExecution exec = (PluginExecution) i.next();
+
+ if ( executionMap.containsKey( exec.getId() ) )
+ {
+ throw new IllegalStateException( "You cannot have two plugin executions with the same (or missing) <id/> elements.\nOffending execution\n\nId: \'" + exec.getId() + "\'\nPlugin:\'" + getKey() + "\'\n\n" );
+ }
+
+ executionMap.put( exec.getId(), exec );
+ }
+ }
+ }
+
+ return executionMap;
+ }
+
+ /**
+ * Gets the identifier of the plugin.
+ *
+ * @return The plugin id in the form {@code <groupId>:<artifactId>:<version>}, never {@code null}.
+ */
+ public String getId()
+ {
+ StringBuilder id = new StringBuilder( 128 );
+
+ id.append( ( getGroupId() == null ) ? "[unknown-group-id]" : getGroupId() );
+ id.append( ":" );
+ id.append( ( getArtifactId() == null ) ? "[unknown-artifact-id]" : getArtifactId() );
+ id.append( ":" );
+ id.append( ( getVersion() == null ) ? "[unknown-version]" : getVersion() );
+
+ return id.toString();
+ }
+
+ //TODO we shall reset key variable when groupId/artifactId change
+ private String key = null;
+ /**
+ * @return the key of the plugin, ie <code>groupId:artifactId</code>
+ */
+ public String getKey()
+ {
+ if ( key == null )
+ {
+ key = constructKey( groupId, artifactId );
+ }
+ return key;
+ }
+
+ /**
+ * @param groupId
+ * @param artifactId
+ * @return the key of the plugin, ie <code>groupId:artifactId</code>
+ */
+ public static String constructKey( String groupId, String artifactId )
+ {
+ return groupId + ":" + artifactId;
+ }
+
+ /**
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ public boolean equals( Object other )
+ {
+ if ( other instanceof Plugin )
+ {
+ Plugin otherPlugin = (Plugin) other;
+
+ return getKey().equals( otherPlugin.getKey() );
+ }
+
+ return false;
+ }
+
+ /**
+ * @see java.lang.Object#hashCode()
+ */
+ public int hashCode()
+ {
+ return getKey().hashCode();
+ }
+
+ /**
+ * @see java.lang.Object#toString()
+ */
+ public String toString()
+ {
+ return "Plugin [" + getKey() + "]";
+ }
+ ]]>
+ </code>
+ </codeSegment>
+ </codeSegments>
+ </class>
+ <class>
+ <name>PluginExecution</name>
+ <version>4.0.0+</version>
+ <superClass>ConfigurationContainer</superClass>
+ <description>
+ <![CDATA[
+ The <code>&lt;execution&gt;</code> element contains informations required for the
+ execution of a plugin.
+ ]]>
+ </description>
+ <fields>
+ <field>
+ <name>id</name>
+ <version>4.0.0+</version>
+ <type>String</type>
+ <defaultValue>default</defaultValue>
+ <description>The identifier of this execution for labelling the goals during the build,
+ and for matching executions to merge during inheritance and profile injection.</description>
+ </field>
+ <field>
+ <name>phase</name>
+ <version>4.0.0+</version>
+ <type>String</type>
+ <description>The build lifecycle phase to bind the goals in this execution to. If omitted,
+ the goals will be bound to the default phase specified by the plugin. </description>
+ </field>
+ <field xml.transient="true">
+ <name>priority</name>
+ <version>4.0.0+</version>
+ <type>int</type>
+ <description>
+ <![CDATA[
+ The priority of this execution compared to other executions which are bound to the same phase.
+ <strong>Warning:</strong> This is an internal utility property that is only public for technical reasons,
+ it is not part of the public API. In particular, this property can be changed or deleted without prior
+ notice.
+ ]]>
+ </description>
+ </field>
+ <field>
+ <name>goals</name>
+ <version>4.0.0+</version>
+ <description>The goals to execute with the given configuration.</description>
+ <association>
+ <type>String</type>
+ <multiplicity>*</multiplicity>
+ </association>
+ </field>
+ </fields>
+ <codeSegments>
+ <codeSegment>
+ <version>4.0.0+</version>
+ <code>
+ <![CDATA[
+ public static final String DEFAULT_EXECUTION_ID = "default";
+
+ @Override
+ public String toString()
+ {
+ return getId();
+ }
+ ]]>
+ </code>
+ </codeSegment>
+ </codeSegments>
+ </class>
+ <class java.clone="deep">
+ <name>DependencyManagement</name>
+ <version>4.0.0+</version>
+ <description>Section for management of default dependency information for use in a group of
+ POMs.</description>
+ <fields>
+ <field>
+ <name>dependencies</name>
+ <version>4.0.0+</version>
+ <description>The dependencies specified here are not used until they are referenced in a
+ POM within the group. This allows the specification of a "standard" version for a
+ particular dependency.</description>
+ <association>
+ <type>Dependency</type>
+ <multiplicity>*</multiplicity>
+ </association>
+ </field>
+ </fields>
+ </class>
+ <class>
+ <name>PluginManagement</name>
+ <version>4.0.0+</version>
+ <superClass>PluginContainer</superClass>
+ <description>Section for management of default plugin information for use in a group of POMs.
+ </description>
+ </class>
+ <class java.clone="deep">
+ <name>Reporting</name>
+ <version>4.0.0+</version>
+ <description>Section for management of reports and their configuration.</description>
+ <fields>
+ <field>
+ <name>excludeDefaults</name>
+ <version>4.0.0+</version>
+ <type>String</type>
+ <description>
+ <![CDATA[
+ If true, then the default reports are not included in the site generation.
+ This includes the reports in the "Project Info" menu. Note: While the type
+ of this field is <code>String</code> for technical reasons, the semantic type is actually
+ <code>Boolean</code>. Default value is <code>false</code>.
+ ]]>
+ </description>
+ </field>
+ <field>
+ <name>outputDirectory</name>
+ <version>4.0.0+</version>
+ <type>String</type>
+ <description>
+ <![CDATA[
+ Where to store all of the generated reports. The default is
+ <code>${project.build.directory}/site</code>
+ .
+ ]]>
+ </description>
+ <!-- TODO: why isn't default set here? -->
+ </field>
+ <field>
+ <name>plugins</name>
+ <version>4.0.0+</version>
+ <description>The reporting plugins to use and their configuration.</description>
+ <association>
+ <type>ReportPlugin</type>
+ <multiplicity>*</multiplicity>
+ </association>
+ </field>
+ </fields>
+ <codeSegments>
+ <codeSegment>
+ <version>4.0.0+</version>
+ <code>
+ <![CDATA[
+ public boolean isExcludeDefaults()
+ {
+ return ( excludeDefaults != null ) ? Boolean.parseBoolean( excludeDefaults ) : false;
+ }
+
+ public void setExcludeDefaults( boolean excludeDefaults )
+ {
+ this.excludeDefaults = String.valueOf( excludeDefaults );
+ }
+
+ java.util.Map<String, ReportPlugin> reportPluginMap;
+
+ /**
+ * Reset the <code>reportPluginMap</code> field to <code>null</code>
+ */
+ public synchronized void flushReportPluginMap()
+ {
+ this.reportPluginMap = null;
+ }
+
+ /**
+ * @return a Map of plugins field with <code>ReportPlugin#getKey()</code> as key
+ * @see org.apache.maven.model.ReportPlugin#getKey()
+ */
+ public synchronized java.util.Map<String, ReportPlugin> getReportPluginsAsMap()
+ {
+ if ( reportPluginMap == null )
+ {
+ reportPluginMap = new java.util.LinkedHashMap<String, ReportPlugin>();
+ if ( getPlugins() != null )
+ {
+ for ( java.util.Iterator<ReportPlugin> it = getPlugins().iterator(); it.hasNext(); )
+ {
+ ReportPlugin reportPlugin = (ReportPlugin) it.next();
+ reportPluginMap.put( reportPlugin.getKey(), reportPlugin );
+ }
+ }
+ }
+
+ return reportPluginMap;
+ }
+ ]]>
+ </code>
+ </codeSegment>
+ </codeSegments>
+ </class>
+ <!-- Profile support -->
+ <class>
+ <name>Profile</name>
+ <superClass>ModelBase</superClass>
+ <version>4.0.0+</version>
+ <description>Modifications to the build process which is activated based on environmental
+ parameters or command line arguments.</description>
+ <fields>
+ <field>
+ <name>id</name>
+ <required>true</required>
+ <version>4.0.0+</version>
+ <type>String</type>
+ <defaultValue>default</defaultValue>
+ <description>The identifier of this build profile. This is used for command line
+ activation, and identifies profiles to be merged.
+ </description>
+ </field>
+ <field>
+ <name>activation</name>
+ <version>4.0.0+</version>
+ <description>The conditional logic which will automatically trigger the inclusion of this
+ profile.</description>
+ <association>
+ <type>Activation</type>
+ </association>
+ </field>
+ <field xml.tagName="build">
+ <name>build</name>
+ <version>4.0.0+</version>
+ <required>true</required>
+ <description>Information required to build the project.</description>
+ <association>
+ <type>BuildBase</type>
+ </association>
+ </field>
+ </fields>
+ <codeSegments>
+ <codeSegment>
+ <version>4.0.0+</version>
+ <code>
+ <![CDATA[
+ public static final String SOURCE_POM = "pom";
+
+ public static final String SOURCE_SETTINGS = "settings.xml";
+
+ // We don't want this to be parseable...it's sort of 'hidden'
+ // default source for this profile is in the pom itself.
+ private String source = SOURCE_POM;
+
+ public void setSource( String source )
+ {
+ this.source = source;
+ }
+
+ public String getSource()
+ {
+ return source;
+ }
+
+ /**
+ * @see java.lang.Object#toString()
+ */
+ public String toString()
+ {
+ return "Profile {id: " + getId() + ", source: " + getSource() + "}";
+ }
+ ]]>
+ </code>
+ </codeSegment>
+ </codeSegments>
+ </class>
+ <class java.clone="deep">
+ <name>Activation</name>
+ <version>4.0.0+</version>
+ <description>The conditions within the build runtime environment which will trigger the
+ automatic inclusion of the build profile. Multiple conditions can be defined, which must
+ be all satisfied to activate the profile.
+ </description>
+ <fields>
+ <field>
+ <name>activeByDefault</name>
+ <version>4.0.0+</version>
+ <type>boolean</type>
+ <description>If set to true, this profile will be active unless another profile in this
+ pom is activated using the command line -P option or by one of that profile's
+ activators.</description>
+ </field>
+ <field>
+ <name>jdk</name>
+ <version>4.0.0+</version>
+ <type>String</type>
+ <description>
+ <![CDATA[
+ Specifies that this profile will be activated when a matching JDK is detected.
+ For example, <code>1.4</code> only activates on JDKs versioned 1.4,
+ while <code>!1.4</code> matches any JDK that is not version 1.4. Ranges are supported too:
+ <code>[1.5,)</code> activates when the JDK is 1.5 minimum.
+ ]]>
+ </description>
+ </field>
+ <field>
+ <name>os</name>
+ <version>4.0.0+</version>
+ <description>Specifies that this profile will be activated when matching operating system
+ attributes are detected.</description>
+ <association>
+ <type>ActivationOS</type>
+ </association>
+ </field>
+ <field>
+ <name>property</name>
+ <version>4.0.0+</version>
+ <description>Specifies that this profile will be activated when this system property is
+ specified.</description>
+ <association>
+ <type>ActivationProperty</type>
+ </association>
+ </field>
+ <field>
+ <name>file</name>
+ <version>4.0.0+</version>
+ <description>Specifies that this profile will be activated based on existence of a file.</description>
+ <association>
+ <type>ActivationFile</type>
+ </association>
+ </field>
+ <!--
+ This could be included once we teach Maven to deal with multiple versions of the model
+ <field>
+ <name>custom</name>
+ <version>4.0.0+</version>
+ <description>Describes a custom profile activation trigger, brought in via build
+ extension.</description>
+ <association>
+ <type>ActivationCustom</type>
+ </association>
+ </field>
+ -->
+ </fields>
+ </class>
+ <class java.clone="deep">
+ <name>ActivationProperty</name>
+ <version>4.0.0+</version>
+ <description>This is the property specification used to activate a profile. If the value field
+ is empty, then the existence of the named property will activate the profile, otherwise it
+ does a case-sensitive match against the property value as well.</description>
+ <fields>
+ <field>
+ <name>name</name>
+ <version>4.0.0+</version>
+ <type>String</type>
+ <required>true</required>
+ <description>The name of the property to be used to activate a profile.</description>
+ </field>
+ <field>
+ <name>value</name>
+ <version>4.0.0+</version>
+ <type>String</type>
+ <description>The value of the property required to activate a profile.</description>
+ </field>
+ </fields>
+ </class>
+ <class java.clone="deep">
+ <name>ActivationOS</name>
+ <version>4.0.0+</version>
+ <description>This is an activator which will detect an operating system's attributes in order
+ to activate its profile.</description>
+ <fields>
+ <field>
+ <name>name</name>
+ <version>4.0.0+</version>
+ <type>String</type>
+ <description>
+ <![CDATA[
+ The name of the operating system to be used to activate the profile. This must be an exact match
+ of the <code>${os.name}</code> Java property, such as <code>Windows XP</code>.
+ ]]>
+ </description>
+ </field>
+ <field>
+ <name>family</name>
+ <version>4.0.0+</version>
+ <type>String</type>
+ <description>
+ <![CDATA[
+ The general family of the OS to be used to activate the profile, such as
+ <code>windows</code> or <code>unix</code>.
+ ]]>
+ </description>
+ </field>
+ <field>
+ <name>arch</name>
+ <version>4.0.0+</version>
+ <type>String</type>
+ <description>The architecture of the operating system to be used to activate the
+ profile.</description>
+ </field>
+ <field>
+ <name>version</name>
+ <version>4.0.0+</version>
+ <type>String</type>
+ <description>The version of the operating system to be used to activate the
+ profile.</description>
+ </field>
+ </fields>
+ </class>
+ <class java.clone="deep">
+ <name>ActivationFile</name>
+ <version>4.0.0+</version>
+ <description><![CDATA[This is the file specification used to activate the profile. The <code>missing</code> value
+ is the location of a file that needs to exist, and if it doesn't, the profile will be
+ activated. On the other hand, <code>exists</code> will test for the existence of the file and if it is
+ there, the profile will be activated.<br/>
+ Variable interpolation for these file specifications is limited to <code>${basedir}</code>,
+ System properties and request properties.]]></description>
+ <fields>
+ <field>
+ <name>missing</name>
+ <version>4.0.0+</version>
+ <type>String</type>
+ <description>The name of the file that must be missing to activate the
+ profile.</description>
+ </field>
+ <field>
+ <name>exists</name>
+ <version>4.0.0+</version>
+ <type>String</type>
+ <description>The name of the file that must exist to activate the profile.</description>
+ </field>
+ </fields>
+ </class>
+ <!--
+ This can be put back in when we figure out how to have multiple model versions
+ <class>
+ <name>ActivationCustom</name>
+ <version>4.0.0+</version>
+ <description>This activation allows users to specify their own custom trigger for a profile.</description>
+ <fields>
+ <field>
+ <name>configuration</name>
+ <version>4.0.0+</version>
+ <type>DOM</type>
+ <description>The specification for triggering the profile according to the rules of the
+ custom activation type.</description>
+ </field>
+ <field>
+ <name>type</name>
+ <version>4.0.0+</version>
+ <type>String</type>
+ <description>The type (role-hint) of activation which is to be used to activate the
+ profile.</description>
+ </field>
+ </fields>
+ </class>
+ -->
+ <!-- /BuildProfile support -->
+ <class xml.tagName="plugin" java.clone="deep">
+ <name>ReportPlugin</name>
+ <version>4.0.0+</version>
+ <superClass>ConfigurationContainer</superClass>
+ <description>
+ <![CDATA[
+ The <code>&lt;plugin&gt;</code> element contains informations required for a report plugin.
+ ]]>
+ </description>
+ <fields>
+ <field>
+ <name>groupId</name>
+ <version>4.0.0+</version>
+ <type>String</type>
+ <required>true</required>
+ <defaultValue>org.apache.maven.plugins</defaultValue>
+ <description>The group ID of the reporting plugin in the repository.</description>
+ </field>
+ <field>
+ <name>artifactId</name>
+ <version>4.0.0+</version>
+ <type>String</type>
+ <required>true</required>
+ <description>The artifact ID of the reporting plugin in the repository.</description>
+ </field>
+ <field>
+ <name>version</name>
+ <version>4.0.0+</version>
+ <description>The version of the reporting plugin to be used.</description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>reportSets</name>
+ <version>4.0.0+</version>
+ <description>
+ <![CDATA[
+ Multiple specifications of a set of reports, each having (possibly) different
+ configuration. This is the reporting parallel to an <code>execution</code> in the build.
+ ]]>
+ </description>
+ <association>
+ <type>ReportSet</type>
+ <multiplicity>*</multiplicity>
+ </association>
+ </field>
+ </fields>
+ <codeSegments>
+ <codeSegment>
+ <version>4.0.0+</version>
+ <code>
+ <![CDATA[
+ private java.util.Map<String, ReportSet> reportSetMap = null;
+
+ /**
+ * Reset the <code>reportSetMap</code> field to <code>null</code>
+ */
+ public void flushReportSetMap()
+ {
+ this.reportSetMap = null;
+ }
+
+ /**
+ * @return a Map of reportSets field with <code>ReportSet#getId()</code> as key
+ * @see org.apache.maven.model.ReportSet#getId()
+ */
+ public java.util.Map<String, ReportSet> getReportSetsAsMap()
+ {
+ if ( reportSetMap == null )
+ {
+ reportSetMap = new java.util.LinkedHashMap<String, ReportSet>();
+ if ( getReportSets() != null )
+ {
+ for ( java.util.Iterator<ReportSet> i = getReportSets().iterator(); i.hasNext(); )
+ {
+ ReportSet reportSet = (ReportSet) i.next();
+ reportSetMap.put( reportSet.getId(), reportSet );
+ }
+ }
+ }
+
+ return reportSetMap;
+ }
+
+ /**
+ * @return the key of the report plugin, ie <code>groupId:artifactId</code>
+ */
+ public String getKey()
+ {
+ return constructKey( groupId, artifactId );
+ }
+
+ /**
+ * @param groupId
+ * @param artifactId
+ * @return the key of the report plugin, ie <code>groupId:artifactId</code>
+ */
+ public static String constructKey( String groupId, String artifactId )
+ {
+ return groupId + ":" + artifactId;
+ }
+ ]]>
+ </code>
+ </codeSegment>
+ </codeSegments>
+ </class>
+ <class java.clone="deep">
+ <name>ReportSet</name>
+ <version>4.0.0+</version>
+ <superClass>ConfigurationContainer</superClass>
+ <description>Represents a set of reports and configuration to be used to generate them.</description>
+ <fields>
+ <field>
+ <name>id</name>
+ <type>String</type>
+ <required>true</required>
+ <description>The unique id for this report set, to be used during POM inheritance and profile injection
+ for merging of report sets.
+ </description>
+ <defaultValue>default</defaultValue>
+ </field>
+ <field>
+ <name>reports</name>
+ <version>4.0.0+</version>
+ <required>true</required>
+ <description>The list of reports from this plugin which should be generated from this set.</description>
+ <association>
+ <type>String</type>
+ <multiplicity>*</multiplicity>
+ </association>
+ </field>
+ </fields>
+ <codeSegments>
+ <codeSegment>
+ <version>4.0.0+</version>
+ <code>
+ <![CDATA[
+ @Override
+ public String toString()
+ {
+ return getId();
+ }
+ ]]>
+ </code>
+ </codeSegment>
+ </codeSegments>
+ </class>
+ <class java.clone="deep">
+ <name>Prerequisites</name>
+ <version>4.0.0+</version>
+ <description>Describes the prerequisites a project can have.</description>
+ <fields>
+ <field>
+ <name>maven</name>
+ <version>4.0.0+</version>
+ <type>String</type>
+ <defaultValue>2.0</defaultValue>
+ <description><![CDATA[
+ The minimum version of Maven required to build the project.<br />
+ If this project builds a plugin, this is in addition the minimum version of Maven required to use
+ the resulting plugin.]]>
+ </description>
+ <required>false</required>
+ </field>
+ </fields>
+ </class>
+ <class java.clone="deep">
+ <name>Relocation</name>
+ <version>4.0.0+</version>
+ <description>Describes where an artifact has moved to. If any of the values are omitted, it is
+ assumed to be the same as it was before.</description>
+ <fields>
+ <field>
+ <name>groupId</name>
+ <version>4.0.0+</version>
+ <description>The group ID the artifact has moved to.</description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>artifactId</name>
+ <version>4.0.0+</version>
+ <description>The new artifact ID of the artifact.</description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>version</name>
+ <version>4.0.0+</version>
+ <description>The new version of the artifact.</description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>message</name>
+ <version>4.0.0+</version>
+ <description>An additional message to show the user about the move, such as the reason.</description>
+ <type>String</type>
+ </field>
+ </fields>
+ </class>
+ <class java.clone="deep">
+ <name>Extension</name>
+ <version>4.0.0+</version>
+ <description>Describes a build extension to utilise.</description>
+ <fields>
+ <field>
+ <name>groupId</name>
+ <version>4.0.0+</version>
+ <description>The group ID of the extension's artifact.</description>
+ <required>true</required>
+ <type>String</type>
+ </field>
+ <field>
+ <name>artifactId</name>
+ <version>4.0.0+</version>
+ <description>The artifact ID of the extension.</description>
+ <required>true</required>
+ <type>String</type>
+ </field>
+ <field>
+ <name>version</name>
+ <version>4.0.0+</version>
+ <description>The version of the extension.</description>
+ <type>String</type>
+ </field>
+ </fields>
+ <codeSegments>
+ <codeSegment>
+ <version>4.0.0+</version>
+ <code>
+ <![CDATA[
+ /**
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ public boolean equals( Object o )
+ {
+ if ( this == o )
+ {
+ return true;
+ }
+
+ if ( !( o instanceof Extension ) )
+ {
+ return false;
+ }
+
+ Extension e = (Extension) o;
+
+ if ( !equal( e.getArtifactId(), getArtifactId() ) )
+ {
+ return false;
+ }
+ else if ( !equal( e.getGroupId(), getGroupId() ) )
+ {
+ return false;
+ }
+ else if ( !equal( e.getVersion(), getVersion() ) )
+ {
+ return false;
+ }
+ return true;
+ }
+
+ private static <T> boolean equal( T obj1, T obj2 )
+ {
+ return ( obj1 != null ) ? obj1.equals( obj2 ) : obj2 == null;
+ }
+
+ /**
+ * @see java.lang.Object#hashCode()
+ */
+ public int hashCode()
+ {
+ int result = 17;
+ result = 37 * result + ( getArtifactId() != null ? getArtifactId().hashCode() : 0 );
+ result = 37 * result + ( getGroupId() != null ? getGroupId().hashCode() : 0 );
+ result = 37 * result + ( getVersion() != null ? getVersion().hashCode() : 0 );
+ return result;
+ }
+ ]]>
+ </code>
+ </codeSegment>
+ </codeSegments>
+ </class>
+ <class locationTracker="locations" java.clone="shallow">
+ <name>InputLocation</name>
+ <version>4.0.0+</version>
+ <fields>
+ <!-- line, column and source fields are auto-generated by Modello -->
+ </fields>
+ <codeSegments>
+ <codeSegment>
+ <version>4.0.0+</version>
+ <code>
+ <![CDATA[
+
+ @Override
+ public String toString()
+ {
+ return getLineNumber() + " : " + getColumnNumber() + ", " + getSource();
+ }
+ ]]>
+ </code>
+ </codeSegment>
+ </codeSegments>
+ </class>
+ <class sourceTracker="source" java.clone="shallow">
+ <name>InputSource</name>
+ <version>4.0.0+</version>
+ <fields>
+ <field>
+ <name>modelId</name>
+ <version>4.0.0+</version>
+ <type>String</type>
+ <description>
+ <![CDATA[
+ The identifier of the POM in the format {@code <groupId>:<artifactId>:<version>}.
+ ]]>
+ </description>
+ </field>
+ <field>
+ <name>location</name>
+ <version>4.0.0+</version>
+ <type>String</type>
+ <description>
+ <![CDATA[
+ The path/URL of the POM or {@code null} if unknown.
+ ]]>
+ </description>
+ </field>
+ </fields>
+ <codeSegments>
+ <codeSegment>
+ <version>4.0.0+</version>
+ <code>
+ <![CDATA[
+ @Override
+ public String toString()
+ {
+ return getModelId() + " " + getLocation();
+ }
+ ]]>
+ </code>
+ </codeSegment>
+ </codeSegments>
+ </class>
+ </classes>
+</model>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model/src/site/apt/index.apt b/framework/src/maven/apache-maven-3.3.3/maven-model/src/site/apt/index.apt
new file mode 100644
index 00000000..77ec5081
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model/src/site/apt/index.apt
@@ -0,0 +1,39 @@
+~~ Licensed to the Apache Software Foundation (ASF) under one
+~~ or more contributor license agreements. See the NOTICE file
+~~ distributed with this work for additional information
+~~ regarding copyright ownership. The ASF licenses this file
+~~ to you under the Apache License, Version 2.0 (the
+~~ "License"); you may not use this file except in compliance
+~~ with the License. You may obtain a copy of the License at
+~~
+~~ http://www.apache.org/licenses/LICENSE-2.0
+~~
+~~ Unless required by applicable law or agreed to in writing,
+~~ software distributed under the License is distributed on an
+~~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+~~ KIND, either express or implied. See the License for the
+~~ specific language governing permissions and limitations
+~~ under the License.
+
+ -----
+ Introduction
+ -----
+ Jason van Zyl
+ Vincent Siveton
+ Hervé Boutemy
+ -----
+ 2011-06-12
+ -----
+
+Maven Model
+
+ This is strictly the model for Maven POM (Project Object Model), so really just plain objects. All the effective model
+ building logic from multiple POMs and building context is done in {{{../maven-model-builder/}Maven Model Builder}}.
+
+ The following are generated from this model:
+
+ * {{{./apidocs/index.html}Java sources}} with Reader and Writers for the Xpp3 XML parser
+
+ * A {{{./maven.html}Descriptor Reference}}
+
+ * An XSD {{{http://maven.apache.org/xsd/maven-v3_0_0.xsd}for Maven 1.1}} and {{{http://maven.apache.org/xsd/maven-4.0.0.xsd}for Maven 2.0}}.
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model/src/site/site.xml b/framework/src/maven/apache-maven-3.3.3/maven-model/src/site/site.xml
new file mode 100644
index 00000000..3a16bf98
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model/src/site/site.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project xmlns="http://maven.apache.org/DECORATION/1.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/DECORATION/1.0.0 http://maven.apache.org/xsd/decoration-1.0.0.xsd">
+ <body>
+ <menu name="Overview">
+ <item name="Introduction" href="index.html"/>
+ <item name="JavaDocs" href="apidocs/index.html"/>
+ <item name="Source Xref" href="xref/index.html"/>
+ <!--item name="FAQ" href="faq.html"/-->
+ </menu>
+
+ <menu ref="parent"/>
+ <menu ref="reports"/>
+ </body>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model/src/site/xdoc/navigation.xml b/framework/src/maven/apache-maven-3.3.3/maven-model/src/site/xdoc/navigation.xml
new file mode 100644
index 00000000..110a953d
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model/src/site/xdoc/navigation.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+<project name="Project Descriptor">
+ <title>Project Descriptor</title>
+ <body>
+ <breadcrumbs>
+ <item name="Apache" href="http://www.apache.org" />
+ <item name="Maven" href="http://maven.apache.org/" />
+ <item name="Maven 1.x" href="http://maven.apache.org/maven-1.x/" />
+ <item name="Reference" href="http://maven.apache.org/maven-1.x/reference/index.html" />
+ </breadcrumbs>
+ <menu name="Maven Project Descriptor">
+ <item name="About" href="/index.html" />
+ <item name="Model Documentation" href="/maven.html" />
+ <item name="API Docs" href="/apidocs/" target="_blank" />
+ </menu>
+ </body>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/ActivationFileTest.java b/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/ActivationFileTest.java
new file mode 100644
index 00000000..f88da581
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/ActivationFileTest.java
@@ -0,0 +1,56 @@
+package org.apache.maven.model;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import junit.framework.TestCase;
+
+/**
+ * Tests {@code ActivationFile}.
+ *
+ * @author Benjamin Bentmann
+ */
+public class ActivationFileTest
+ extends TestCase
+{
+
+ public void testHashCodeNullSafe()
+ {
+ new ActivationFile().hashCode();
+ }
+
+ public void testEqualsNullSafe()
+ {
+ assertFalse( new ActivationFile().equals( null ) );
+
+ new ActivationFile().equals( new ActivationFile() );
+ }
+
+ public void testEqualsIdentity()
+ {
+ ActivationFile thing = new ActivationFile();
+ assertTrue( thing.equals( thing ) );
+ }
+
+ public void testToStringNullSafe()
+ {
+ assertNotNull( new ActivationFile().toString() );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/ActivationOSTest.java b/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/ActivationOSTest.java
new file mode 100644
index 00000000..f0d30450
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/ActivationOSTest.java
@@ -0,0 +1,56 @@
+package org.apache.maven.model;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import junit.framework.TestCase;
+
+/**
+ * Tests {@code ActivationOS}.
+ *
+ * @author Benjamin Bentmann
+ */
+public class ActivationOSTest
+ extends TestCase
+{
+
+ public void testHashCodeNullSafe()
+ {
+ new ActivationOS().hashCode();
+ }
+
+ public void testEqualsNullSafe()
+ {
+ assertFalse( new ActivationOS().equals( null ) );
+
+ new ActivationOS().equals( new ActivationOS() );
+ }
+
+ public void testEqualsIdentity()
+ {
+ ActivationOS thing = new ActivationOS();
+ assertTrue( thing.equals( thing ) );
+ }
+
+ public void testToStringNullSafe()
+ {
+ assertNotNull( new ActivationOS().toString() );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/ActivationPropertyTest.java b/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/ActivationPropertyTest.java
new file mode 100644
index 00000000..5f5e048a
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/ActivationPropertyTest.java
@@ -0,0 +1,56 @@
+package org.apache.maven.model;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import junit.framework.TestCase;
+
+/**
+ * Tests {@code ActivationProperty}.
+ *
+ * @author Benjamin Bentmann
+ */
+public class ActivationPropertyTest
+ extends TestCase
+{
+
+ public void testHashCodeNullSafe()
+ {
+ new ActivationProperty().hashCode();
+ }
+
+ public void testEqualsNullSafe()
+ {
+ assertFalse( new ActivationProperty().equals( null ) );
+
+ new ActivationProperty().equals( new ActivationProperty() );
+ }
+
+ public void testEqualsIdentity()
+ {
+ ActivationProperty thing = new ActivationProperty();
+ assertTrue( thing.equals( thing ) );
+ }
+
+ public void testToStringNullSafe()
+ {
+ assertNotNull( new ActivationProperty().toString() );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/ActivationTest.java b/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/ActivationTest.java
new file mode 100644
index 00000000..f6d0f910
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/ActivationTest.java
@@ -0,0 +1,56 @@
+package org.apache.maven.model;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import junit.framework.TestCase;
+
+/**
+ * Tests {@code Activation}.
+ *
+ * @author Benjamin Bentmann
+ */
+public class ActivationTest
+ extends TestCase
+{
+
+ public void testHashCodeNullSafe()
+ {
+ new Activation().hashCode();
+ }
+
+ public void testEqualsNullSafe()
+ {
+ assertFalse( new Activation().equals( null ) );
+
+ new Activation().equals( new Activation() );
+ }
+
+ public void testEqualsIdentity()
+ {
+ Activation thing = new Activation();
+ assertTrue( thing.equals( thing ) );
+ }
+
+ public void testToStringNullSafe()
+ {
+ assertNotNull( new Activation().toString() );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/BuildTest.java b/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/BuildTest.java
new file mode 100644
index 00000000..80a60d57
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/BuildTest.java
@@ -0,0 +1,56 @@
+package org.apache.maven.model;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import junit.framework.TestCase;
+
+/**
+ * Tests {@code Build}.
+ *
+ * @author Benjamin Bentmann
+ */
+public class BuildTest
+ extends TestCase
+{
+
+ public void testHashCodeNullSafe()
+ {
+ new Build().hashCode();
+ }
+
+ public void testEqualsNullSafe()
+ {
+ assertFalse( new Build().equals( null ) );
+
+ new Build().equals( new Build() );
+ }
+
+ public void testEqualsIdentity()
+ {
+ Build thing = new Build();
+ assertTrue( thing.equals( thing ) );
+ }
+
+ public void testToStringNullSafe()
+ {
+ assertNotNull( new Build().toString() );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/CiManagementTest.java b/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/CiManagementTest.java
new file mode 100644
index 00000000..7194c844
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/CiManagementTest.java
@@ -0,0 +1,56 @@
+package org.apache.maven.model;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import junit.framework.TestCase;
+
+/**
+ * Tests {@code CiManagement}.
+ *
+ * @author Benjamin Bentmann
+ */
+public class CiManagementTest
+ extends TestCase
+{
+
+ public void testHashCodeNullSafe()
+ {
+ new CiManagement().hashCode();
+ }
+
+ public void testEqualsNullSafe()
+ {
+ assertFalse( new CiManagement().equals( null ) );
+
+ new CiManagement().equals( new CiManagement() );
+ }
+
+ public void testEqualsIdentity()
+ {
+ CiManagement thing = new CiManagement();
+ assertTrue( thing.equals( thing ) );
+ }
+
+ public void testToStringNullSafe()
+ {
+ assertNotNull( new CiManagement().toString() );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/ContributorTest.java b/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/ContributorTest.java
new file mode 100644
index 00000000..491b99ae
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/ContributorTest.java
@@ -0,0 +1,56 @@
+package org.apache.maven.model;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import junit.framework.TestCase;
+
+/**
+ * Tests {@code Contributor}.
+ *
+ * @author Benjamin Bentmann
+ */
+public class ContributorTest
+ extends TestCase
+{
+
+ public void testHashCodeNullSafe()
+ {
+ new Contributor().hashCode();
+ }
+
+ public void testEqualsNullSafe()
+ {
+ assertFalse( new Contributor().equals( null ) );
+
+ new Contributor().equals( new Contributor() );
+ }
+
+ public void testEqualsIdentity()
+ {
+ Contributor thing = new Contributor();
+ assertTrue( thing.equals( thing ) );
+ }
+
+ public void testToStringNullSafe()
+ {
+ assertNotNull( new Contributor().toString() );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/DependencyManagementTest.java b/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/DependencyManagementTest.java
new file mode 100644
index 00000000..7702c62f
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/DependencyManagementTest.java
@@ -0,0 +1,56 @@
+package org.apache.maven.model;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import junit.framework.TestCase;
+
+/**
+ * Tests {@code DependencyManagement}.
+ *
+ * @author Benjamin Bentmann
+ */
+public class DependencyManagementTest
+ extends TestCase
+{
+
+ public void testHashCodeNullSafe()
+ {
+ new DependencyManagement().hashCode();
+ }
+
+ public void testEqualsNullSafe()
+ {
+ assertFalse( new DependencyManagement().equals( null ) );
+
+ new DependencyManagement().equals( new DependencyManagement() );
+ }
+
+ public void testEqualsIdentity()
+ {
+ DependencyManagement thing = new DependencyManagement();
+ assertTrue( thing.equals( thing ) );
+ }
+
+ public void testToStringNullSafe()
+ {
+ assertNotNull( new DependencyManagement().toString() );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/DependencyTest.java b/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/DependencyTest.java
new file mode 100644
index 00000000..ec0a8336
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/DependencyTest.java
@@ -0,0 +1,56 @@
+package org.apache.maven.model;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import junit.framework.TestCase;
+
+/**
+ * Tests {@code Dependency}.
+ *
+ * @author Benjamin Bentmann
+ */
+public class DependencyTest
+ extends TestCase
+{
+
+ public void testHashCodeNullSafe()
+ {
+ new Dependency().hashCode();
+ }
+
+ public void testEqualsNullSafe()
+ {
+ assertFalse( new Dependency().equals( null ) );
+
+ new Dependency().equals( new Dependency() );
+ }
+
+ public void testEqualsIdentity()
+ {
+ Dependency thing = new Dependency();
+ assertTrue( thing.equals( thing ) );
+ }
+
+ public void testToStringNullSafe()
+ {
+ assertNotNull( new Dependency().toString() );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/DeploymentRepositoryTest.java b/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/DeploymentRepositoryTest.java
new file mode 100644
index 00000000..169ec650
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/DeploymentRepositoryTest.java
@@ -0,0 +1,56 @@
+package org.apache.maven.model;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import junit.framework.TestCase;
+
+/**
+ * Tests {@code DeploymentRepository}.
+ *
+ * @author Benjamin Bentmann
+ */
+public class DeploymentRepositoryTest
+ extends TestCase
+{
+
+ public void testHashCodeNullSafe()
+ {
+ new DeploymentRepository().hashCode();
+ }
+
+ public void testEqualsNullSafe()
+ {
+ assertFalse( new DeploymentRepository().equals( null ) );
+
+ new DeploymentRepository().equals( new DeploymentRepository() );
+ }
+
+ public void testEqualsIdentity()
+ {
+ DeploymentRepository thing = new DeploymentRepository();
+ assertTrue( thing.equals( thing ) );
+ }
+
+ public void testToStringNullSafe()
+ {
+ assertNotNull( new DeploymentRepository().toString() );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/DeveloperTest.java b/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/DeveloperTest.java
new file mode 100644
index 00000000..c0dfe56d
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/DeveloperTest.java
@@ -0,0 +1,56 @@
+package org.apache.maven.model;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import junit.framework.TestCase;
+
+/**
+ * Tests {@code Developer}.
+ *
+ * @author Benjamin Bentmann
+ */
+public class DeveloperTest
+ extends TestCase
+{
+
+ public void testHashCodeNullSafe()
+ {
+ new Developer().hashCode();
+ }
+
+ public void testEqualsNullSafe()
+ {
+ assertFalse( new Developer().equals( null ) );
+
+ new Developer().equals( new Developer() );
+ }
+
+ public void testEqualsIdentity()
+ {
+ Developer thing = new Developer();
+ assertTrue( thing.equals( thing ) );
+ }
+
+ public void testToStringNullSafe()
+ {
+ assertNotNull( new Developer().toString() );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/DistributionManagementTest.java b/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/DistributionManagementTest.java
new file mode 100644
index 00000000..0314d61b
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/DistributionManagementTest.java
@@ -0,0 +1,56 @@
+package org.apache.maven.model;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import junit.framework.TestCase;
+
+/**
+ * Tests {@code DistributionManagement}.
+ *
+ * @author Benjamin Bentmann
+ */
+public class DistributionManagementTest
+ extends TestCase
+{
+
+ public void testHashCodeNullSafe()
+ {
+ new DistributionManagement().hashCode();
+ }
+
+ public void testEqualsNullSafe()
+ {
+ assertFalse( new DistributionManagement().equals( null ) );
+
+ new DistributionManagement().equals( new DistributionManagement() );
+ }
+
+ public void testEqualsIdentity()
+ {
+ DistributionManagement thing = new DistributionManagement();
+ assertTrue( thing.equals( thing ) );
+ }
+
+ public void testToStringNullSafe()
+ {
+ assertNotNull( new DistributionManagement().toString() );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/ExclusionTest.java b/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/ExclusionTest.java
new file mode 100644
index 00000000..6febaceb
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/ExclusionTest.java
@@ -0,0 +1,56 @@
+package org.apache.maven.model;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import junit.framework.TestCase;
+
+/**
+ * Tests {@code Exclusion}.
+ *
+ * @author Benjamin Bentmann
+ */
+public class ExclusionTest
+ extends TestCase
+{
+
+ public void testHashCodeNullSafe()
+ {
+ new Exclusion().hashCode();
+ }
+
+ public void testEqualsNullSafe()
+ {
+ assertFalse( new Exclusion().equals( null ) );
+
+ new Exclusion().equals( new Exclusion() );
+ }
+
+ public void testEqualsIdentity()
+ {
+ Exclusion thing = new Exclusion();
+ assertTrue( thing.equals( thing ) );
+ }
+
+ public void testToStringNullSafe()
+ {
+ assertNotNull( new Exclusion().toString() );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/ExtensionTest.java b/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/ExtensionTest.java
new file mode 100644
index 00000000..4b8cd8a1
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/ExtensionTest.java
@@ -0,0 +1,56 @@
+package org.apache.maven.model;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import junit.framework.TestCase;
+
+/**
+ * Tests {@code Extension}.
+ *
+ * @author Benjamin Bentmann
+ */
+public class ExtensionTest
+ extends TestCase
+{
+
+ public void testHashCodeNullSafe()
+ {
+ new Extension().hashCode();
+ }
+
+ public void testEqualsNullSafe()
+ {
+ assertFalse( new Extension().equals( null ) );
+
+ new Extension().equals( new Extension() );
+ }
+
+ public void testEqualsIdentity()
+ {
+ Extension thing = new Extension();
+ assertTrue( thing.equals( thing ) );
+ }
+
+ public void testToStringNullSafe()
+ {
+ assertNotNull( new Extension().toString() );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/IssueManagementTest.java b/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/IssueManagementTest.java
new file mode 100644
index 00000000..5e50c157
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/IssueManagementTest.java
@@ -0,0 +1,56 @@
+package org.apache.maven.model;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import junit.framework.TestCase;
+
+/**
+ * Tests {@code IssueManagement}.
+ *
+ * @author Benjamin Bentmann
+ */
+public class IssueManagementTest
+ extends TestCase
+{
+
+ public void testHashCodeNullSafe()
+ {
+ new IssueManagement().hashCode();
+ }
+
+ public void testEqualsNullSafe()
+ {
+ assertFalse( new IssueManagement().equals( null ) );
+
+ new IssueManagement().equals( new IssueManagement() );
+ }
+
+ public void testEqualsIdentity()
+ {
+ IssueManagement thing = new IssueManagement();
+ assertTrue( thing.equals( thing ) );
+ }
+
+ public void testToStringNullSafe()
+ {
+ assertNotNull( new IssueManagement().toString() );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/LicenseTest.java b/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/LicenseTest.java
new file mode 100644
index 00000000..179921b2
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/LicenseTest.java
@@ -0,0 +1,56 @@
+package org.apache.maven.model;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import junit.framework.TestCase;
+
+/**
+ * Tests {@code License}.
+ *
+ * @author Benjamin Bentmann
+ */
+public class LicenseTest
+ extends TestCase
+{
+
+ public void testHashCodeNullSafe()
+ {
+ new License().hashCode();
+ }
+
+ public void testEqualsNullSafe()
+ {
+ assertFalse( new License().equals( null ) );
+
+ new License().equals( new License() );
+ }
+
+ public void testEqualsIdentity()
+ {
+ License thing = new License();
+ assertTrue( thing.equals( thing ) );
+ }
+
+ public void testToStringNullSafe()
+ {
+ assertNotNull( new License().toString() );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/MailingListTest.java b/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/MailingListTest.java
new file mode 100644
index 00000000..61296952
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/MailingListTest.java
@@ -0,0 +1,56 @@
+package org.apache.maven.model;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import junit.framework.TestCase;
+
+/**
+ * Tests {@code MailingList}.
+ *
+ * @author Benjamin Bentmann
+ */
+public class MailingListTest
+ extends TestCase
+{
+
+ public void testHashCodeNullSafe()
+ {
+ new MailingList().hashCode();
+ }
+
+ public void testEqualsNullSafe()
+ {
+ assertFalse( new MailingList().equals( null ) );
+
+ new MailingList().equals( new MailingList() );
+ }
+
+ public void testEqualsIdentity()
+ {
+ MailingList thing = new MailingList();
+ assertTrue( thing.equals( thing ) );
+ }
+
+ public void testToStringNullSafe()
+ {
+ assertNotNull( new MailingList().toString() );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/ModelTest.java b/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/ModelTest.java
new file mode 100644
index 00000000..c9ec4da9
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/ModelTest.java
@@ -0,0 +1,56 @@
+package org.apache.maven.model;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import junit.framework.TestCase;
+
+/**
+ * Tests {@code Model}.
+ *
+ * @author Benjamin Bentmann
+ */
+public class ModelTest
+ extends TestCase
+{
+
+ public void testHashCodeNullSafe()
+ {
+ new Model().hashCode();
+ }
+
+ public void testEqualsNullSafe()
+ {
+ assertFalse( new Model().equals( null ) );
+
+ new Model().equals( new Model() );
+ }
+
+ public void testEqualsIdentity()
+ {
+ Model thing = new Model();
+ assertTrue( thing.equals( thing ) );
+ }
+
+ public void testToStringNullSafe()
+ {
+ assertNotNull( new Model().toString() );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/NotifierTest.java b/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/NotifierTest.java
new file mode 100644
index 00000000..4e5d0685
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/NotifierTest.java
@@ -0,0 +1,56 @@
+package org.apache.maven.model;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import junit.framework.TestCase;
+
+/**
+ * Tests {@code Notifier}.
+ *
+ * @author Benjamin Bentmann
+ */
+public class NotifierTest
+ extends TestCase
+{
+
+ public void testHashCodeNullSafe()
+ {
+ new Notifier().hashCode();
+ }
+
+ public void testEqualsNullSafe()
+ {
+ assertFalse( new Notifier().equals( null ) );
+
+ new Notifier().equals( new Notifier() );
+ }
+
+ public void testEqualsIdentity()
+ {
+ Notifier thing = new Notifier();
+ assertTrue( thing.equals( thing ) );
+ }
+
+ public void testToStringNullSafe()
+ {
+ assertNotNull( new Notifier().toString() );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/OrganizationTest.java b/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/OrganizationTest.java
new file mode 100644
index 00000000..48abe77e
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/OrganizationTest.java
@@ -0,0 +1,56 @@
+package org.apache.maven.model;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import junit.framework.TestCase;
+
+/**
+ * Tests {@code Organization}.
+ *
+ * @author Benjamin Bentmann
+ */
+public class OrganizationTest
+ extends TestCase
+{
+
+ public void testHashCodeNullSafe()
+ {
+ new Organization().hashCode();
+ }
+
+ public void testEqualsNullSafe()
+ {
+ assertFalse( new Organization().equals( null ) );
+
+ new Organization().equals( new Organization() );
+ }
+
+ public void testEqualsIdentity()
+ {
+ Organization thing = new Organization();
+ assertTrue( thing.equals( thing ) );
+ }
+
+ public void testToStringNullSafe()
+ {
+ assertNotNull( new Organization().toString() );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/ParentTest.java b/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/ParentTest.java
new file mode 100644
index 00000000..78d45672
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/ParentTest.java
@@ -0,0 +1,56 @@
+package org.apache.maven.model;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import junit.framework.TestCase;
+
+/**
+ * Tests {@code Parent}.
+ *
+ * @author Benjamin Bentmann
+ */
+public class ParentTest
+ extends TestCase
+{
+
+ public void testHashCodeNullSafe()
+ {
+ new Parent().hashCode();
+ }
+
+ public void testEqualsNullSafe()
+ {
+ assertFalse( new Parent().equals( null ) );
+
+ new Parent().equals( new Parent() );
+ }
+
+ public void testEqualsIdentity()
+ {
+ Parent thing = new Parent();
+ assertTrue( thing.equals( thing ) );
+ }
+
+ public void testToStringNullSafe()
+ {
+ assertNotNull( new Parent().toString() );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/PluginConfigurationTest.java b/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/PluginConfigurationTest.java
new file mode 100644
index 00000000..cbb123d5
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/PluginConfigurationTest.java
@@ -0,0 +1,56 @@
+package org.apache.maven.model;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import junit.framework.TestCase;
+
+/**
+ * Tests {@code PluginConfiguration}.
+ *
+ * @author Benjamin Bentmann
+ */
+public class PluginConfigurationTest
+ extends TestCase
+{
+
+ public void testHashCodeNullSafe()
+ {
+ new PluginConfiguration().hashCode();
+ }
+
+ public void testEqualsNullSafe()
+ {
+ assertFalse( new PluginConfiguration().equals( null ) );
+
+ new PluginConfiguration().equals( new PluginConfiguration() );
+ }
+
+ public void testEqualsIdentity()
+ {
+ PluginConfiguration thing = new PluginConfiguration();
+ assertTrue( thing.equals( thing ) );
+ }
+
+ public void testToStringNullSafe()
+ {
+ assertNotNull( new PluginConfiguration().toString() );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/PluginContainerTest.java b/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/PluginContainerTest.java
new file mode 100644
index 00000000..878298cf
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/PluginContainerTest.java
@@ -0,0 +1,56 @@
+package org.apache.maven.model;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import junit.framework.TestCase;
+
+/**
+ * Tests {@code PluginContainer}.
+ *
+ * @author Benjamin Bentmann
+ */
+public class PluginContainerTest
+ extends TestCase
+{
+
+ public void testHashCodeNullSafe()
+ {
+ new PluginContainer().hashCode();
+ }
+
+ public void testEqualsNullSafe()
+ {
+ assertFalse( new PluginContainer().equals( null ) );
+
+ new PluginContainer().equals( new PluginContainer() );
+ }
+
+ public void testEqualsIdentity()
+ {
+ PluginContainer thing = new PluginContainer();
+ assertTrue( thing.equals( thing ) );
+ }
+
+ public void testToStringNullSafe()
+ {
+ assertNotNull( new PluginContainer().toString() );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/PluginExecutionTest.java b/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/PluginExecutionTest.java
new file mode 100644
index 00000000..e8fff512
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/PluginExecutionTest.java
@@ -0,0 +1,56 @@
+package org.apache.maven.model;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import junit.framework.TestCase;
+
+/**
+ * Tests {@code PluginExecution}.
+ *
+ * @author Benjamin Bentmann
+ */
+public class PluginExecutionTest
+ extends TestCase
+{
+
+ public void testHashCodeNullSafe()
+ {
+ new PluginExecution().hashCode();
+ }
+
+ public void testEqualsNullSafe()
+ {
+ assertFalse( new PluginExecution().equals( null ) );
+
+ new PluginExecution().equals( new PluginExecution() );
+ }
+
+ public void testEqualsIdentity()
+ {
+ PluginExecution thing = new PluginExecution();
+ assertTrue( thing.equals( thing ) );
+ }
+
+ public void testToStringNullSafe()
+ {
+ assertNotNull( new PluginExecution().toString() );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/PluginManagementTest.java b/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/PluginManagementTest.java
new file mode 100644
index 00000000..571399fe
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/PluginManagementTest.java
@@ -0,0 +1,56 @@
+package org.apache.maven.model;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import junit.framework.TestCase;
+
+/**
+ * Tests {@code PluginManagement}.
+ *
+ * @author Benjamin Bentmann
+ */
+public class PluginManagementTest
+ extends TestCase
+{
+
+ public void testHashCodeNullSafe()
+ {
+ new PluginManagement().hashCode();
+ }
+
+ public void testEqualsNullSafe()
+ {
+ assertFalse( new PluginManagement().equals( null ) );
+
+ new PluginManagement().equals( new PluginManagement() );
+ }
+
+ public void testEqualsIdentity()
+ {
+ PluginManagement thing = new PluginManagement();
+ assertTrue( thing.equals( thing ) );
+ }
+
+ public void testToStringNullSafe()
+ {
+ assertNotNull( new PluginManagement().toString() );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/PluginTest.java b/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/PluginTest.java
new file mode 100644
index 00000000..582145e0
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/PluginTest.java
@@ -0,0 +1,56 @@
+package org.apache.maven.model;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import junit.framework.TestCase;
+
+/**
+ * Tests {@code Plugin}.
+ *
+ * @author Benjamin Bentmann
+ */
+public class PluginTest
+ extends TestCase
+{
+
+ public void testHashCodeNullSafe()
+ {
+ new Plugin().hashCode();
+ }
+
+ public void testEqualsNullSafe()
+ {
+ assertFalse( new Plugin().equals( null ) );
+
+ new Plugin().equals( new Plugin() );
+ }
+
+ public void testEqualsIdentity()
+ {
+ Plugin thing = new Plugin();
+ assertTrue( thing.equals( thing ) );
+ }
+
+ public void testToStringNullSafe()
+ {
+ assertNotNull( new Plugin().toString() );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/PrerequisitesTest.java b/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/PrerequisitesTest.java
new file mode 100644
index 00000000..727f2c3f
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/PrerequisitesTest.java
@@ -0,0 +1,56 @@
+package org.apache.maven.model;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import junit.framework.TestCase;
+
+/**
+ * Tests {@code Prerequisites}.
+ *
+ * @author Benjamin Bentmann
+ */
+public class PrerequisitesTest
+ extends TestCase
+{
+
+ public void testHashCodeNullSafe()
+ {
+ new Prerequisites().hashCode();
+ }
+
+ public void testEqualsNullSafe()
+ {
+ assertFalse( new Prerequisites().equals( null ) );
+
+ new Prerequisites().equals( new Prerequisites() );
+ }
+
+ public void testEqualsIdentity()
+ {
+ Prerequisites thing = new Prerequisites();
+ assertTrue( thing.equals( thing ) );
+ }
+
+ public void testToStringNullSafe()
+ {
+ assertNotNull( new Prerequisites().toString() );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/ProfileTest.java b/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/ProfileTest.java
new file mode 100644
index 00000000..512e2a88
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/ProfileTest.java
@@ -0,0 +1,56 @@
+package org.apache.maven.model;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import junit.framework.TestCase;
+
+/**
+ * Tests {@code Profile}.
+ *
+ * @author Benjamin Bentmann
+ */
+public class ProfileTest
+ extends TestCase
+{
+
+ public void testHashCodeNullSafe()
+ {
+ new Profile().hashCode();
+ }
+
+ public void testEqualsNullSafe()
+ {
+ assertFalse( new Profile().equals( null ) );
+
+ new Profile().equals( new Profile() );
+ }
+
+ public void testEqualsIdentity()
+ {
+ Profile thing = new Profile();
+ assertTrue( thing.equals( thing ) );
+ }
+
+ public void testToStringNullSafe()
+ {
+ assertNotNull( new Profile().toString() );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/RelocationTest.java b/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/RelocationTest.java
new file mode 100644
index 00000000..265304d8
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/RelocationTest.java
@@ -0,0 +1,56 @@
+package org.apache.maven.model;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import junit.framework.TestCase;
+
+/**
+ * Tests {@code Relocation}.
+ *
+ * @author Benjamin Bentmann
+ */
+public class RelocationTest
+ extends TestCase
+{
+
+ public void testHashCodeNullSafe()
+ {
+ new Relocation().hashCode();
+ }
+
+ public void testEqualsNullSafe()
+ {
+ assertFalse( new Relocation().equals( null ) );
+
+ new Relocation().equals( new Relocation() );
+ }
+
+ public void testEqualsIdentity()
+ {
+ Relocation thing = new Relocation();
+ assertTrue( thing.equals( thing ) );
+ }
+
+ public void testToStringNullSafe()
+ {
+ assertNotNull( new Relocation().toString() );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/ReportPluginTest.java b/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/ReportPluginTest.java
new file mode 100644
index 00000000..d10cb791
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/ReportPluginTest.java
@@ -0,0 +1,56 @@
+package org.apache.maven.model;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import junit.framework.TestCase;
+
+/**
+ * Tests {@code ReportPlugin}.
+ *
+ * @author Benjamin Bentmann
+ */
+public class ReportPluginTest
+ extends TestCase
+{
+
+ public void testHashCodeNullSafe()
+ {
+ new ReportPlugin().hashCode();
+ }
+
+ public void testEqualsNullSafe()
+ {
+ assertFalse( new ReportPlugin().equals( null ) );
+
+ new ReportPlugin().equals( new ReportPlugin() );
+ }
+
+ public void testEqualsIdentity()
+ {
+ ReportPlugin thing = new ReportPlugin();
+ assertTrue( thing.equals( thing ) );
+ }
+
+ public void testToStringNullSafe()
+ {
+ assertNotNull( new ReportPlugin().toString() );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/ReportSetTest.java b/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/ReportSetTest.java
new file mode 100644
index 00000000..2f514153
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/ReportSetTest.java
@@ -0,0 +1,56 @@
+package org.apache.maven.model;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import junit.framework.TestCase;
+
+/**
+ * Tests {@code ReportSet}.
+ *
+ * @author Benjamin Bentmann
+ */
+public class ReportSetTest
+ extends TestCase
+{
+
+ public void testHashCodeNullSafe()
+ {
+ new ReportSet().hashCode();
+ }
+
+ public void testEqualsNullSafe()
+ {
+ assertFalse( new ReportSet().equals( null ) );
+
+ new ReportSet().equals( new ReportSet() );
+ }
+
+ public void testEqualsIdentity()
+ {
+ ReportSet thing = new ReportSet();
+ assertTrue( thing.equals( thing ) );
+ }
+
+ public void testToStringNullSafe()
+ {
+ assertNotNull( new ReportSet().toString() );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/ReportingTest.java b/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/ReportingTest.java
new file mode 100644
index 00000000..dbc0fa22
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/ReportingTest.java
@@ -0,0 +1,56 @@
+package org.apache.maven.model;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import junit.framework.TestCase;
+
+/**
+ * Tests {@code Reporting}.
+ *
+ * @author Benjamin Bentmann
+ */
+public class ReportingTest
+ extends TestCase
+{
+
+ public void testHashCodeNullSafe()
+ {
+ new Reporting().hashCode();
+ }
+
+ public void testEqualsNullSafe()
+ {
+ assertFalse( new Reporting().equals( null ) );
+
+ new Reporting().equals( new Reporting() );
+ }
+
+ public void testEqualsIdentity()
+ {
+ Reporting thing = new Reporting();
+ assertTrue( thing.equals( thing ) );
+ }
+
+ public void testToStringNullSafe()
+ {
+ assertNotNull( new Reporting().toString() );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/RepositoryPolicyTest.java b/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/RepositoryPolicyTest.java
new file mode 100644
index 00000000..3ae34350
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/RepositoryPolicyTest.java
@@ -0,0 +1,56 @@
+package org.apache.maven.model;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import junit.framework.TestCase;
+
+/**
+ * Tests {@code RepositoryPolicy}.
+ *
+ * @author Benjamin Bentmann
+ */
+public class RepositoryPolicyTest
+ extends TestCase
+{
+
+ public void testHashCodeNullSafe()
+ {
+ new RepositoryPolicy().hashCode();
+ }
+
+ public void testEqualsNullSafe()
+ {
+ assertFalse( new RepositoryPolicy().equals( null ) );
+
+ new RepositoryPolicy().equals( new RepositoryPolicy() );
+ }
+
+ public void testEqualsIdentity()
+ {
+ RepositoryPolicy thing = new RepositoryPolicy();
+ assertTrue( thing.equals( thing ) );
+ }
+
+ public void testToStringNullSafe()
+ {
+ assertNotNull( new RepositoryPolicy().toString() );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/RepositoryTest.java b/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/RepositoryTest.java
new file mode 100644
index 00000000..b68b70a1
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/RepositoryTest.java
@@ -0,0 +1,56 @@
+package org.apache.maven.model;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import junit.framework.TestCase;
+
+/**
+ * Tests {@code Repository}.
+ *
+ * @author Benjamin Bentmann
+ */
+public class RepositoryTest
+ extends TestCase
+{
+
+ public void testHashCodeNullSafe()
+ {
+ new Repository().hashCode();
+ }
+
+ public void testEqualsNullSafe()
+ {
+ assertFalse( new Repository().equals( null ) );
+
+ new Repository().equals( new Repository() );
+ }
+
+ public void testEqualsIdentity()
+ {
+ Repository thing = new Repository();
+ assertTrue( thing.equals( thing ) );
+ }
+
+ public void testToStringNullSafe()
+ {
+ assertNotNull( new Repository().toString() );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/ResourceTest.java b/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/ResourceTest.java
new file mode 100644
index 00000000..fa40ab43
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/ResourceTest.java
@@ -0,0 +1,56 @@
+package org.apache.maven.model;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import junit.framework.TestCase;
+
+/**
+ * Tests {@code Resource}.
+ *
+ * @author Benjamin Bentmann
+ */
+public class ResourceTest
+ extends TestCase
+{
+
+ public void testHashCodeNullSafe()
+ {
+ new Resource().hashCode();
+ }
+
+ public void testEqualsNullSafe()
+ {
+ assertFalse( new Resource().equals( null ) );
+
+ new Resource().equals( new Resource() );
+ }
+
+ public void testEqualsIdentity()
+ {
+ Resource thing = new Resource();
+ assertTrue( thing.equals( thing ) );
+ }
+
+ public void testToStringNullSafe()
+ {
+ assertNotNull( new Resource().toString() );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/ScmTest.java b/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/ScmTest.java
new file mode 100644
index 00000000..4d769931
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/ScmTest.java
@@ -0,0 +1,56 @@
+package org.apache.maven.model;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import junit.framework.TestCase;
+
+/**
+ * Tests {@code Scm}.
+ *
+ * @author Benjamin Bentmann
+ */
+public class ScmTest
+ extends TestCase
+{
+
+ public void testHashCodeNullSafe()
+ {
+ new Scm().hashCode();
+ }
+
+ public void testEqualsNullSafe()
+ {
+ assertFalse( new Scm().equals( null ) );
+
+ new Scm().equals( new Scm() );
+ }
+
+ public void testEqualsIdentity()
+ {
+ Scm thing = new Scm();
+ assertTrue( thing.equals( thing ) );
+ }
+
+ public void testToStringNullSafe()
+ {
+ assertNotNull( new Scm().toString() );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/SiteTest.java b/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/SiteTest.java
new file mode 100644
index 00000000..84896bb4
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-model/src/test/java/org/apache/maven/model/SiteTest.java
@@ -0,0 +1,56 @@
+package org.apache.maven.model;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import junit.framework.TestCase;
+
+/**
+ * Tests {@code Site}.
+ *
+ * @author Benjamin Bentmann
+ */
+public class SiteTest
+ extends TestCase
+{
+
+ public void testHashCodeNullSafe()
+ {
+ new Site().hashCode();
+ }
+
+ public void testEqualsNullSafe()
+ {
+ assertFalse( new Site().equals( null ) );
+
+ new Site().equals( new Site() );
+ }
+
+ public void testEqualsIdentity()
+ {
+ Site thing = new Site();
+ assertTrue( thing.equals( thing ) );
+ }
+
+ public void testToStringNullSafe()
+ {
+ assertNotNull( new Site().toString() );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-plugin-api/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-plugin-api/pom.xml
new file mode 100644
index 00000000..40e7c0f9
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-plugin-api/pom.xml
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven</artifactId>
+ <version>3.3.3</version>
+ </parent>
+
+ <artifactId>maven-plugin-api</artifactId>
+
+ <name>Maven Plugin API</name>
+ <description>The API for plugins - Mojos - development.</description>
+
+ <scm><!-- remove when git scm url format can accept artifact-id at the end, as automatically inherited -->
+ <connection>scm:git:https://git-wip-us.apache.org/repos/asf/maven.git</connection>
+ <developerConnection>scm:git:https://git-wip-us.apache.org/repos/asf/maven.git</developerConnection>
+ <tag>maven-3.3.3</tag>
+ </scm>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-model</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-artifact</artifactId>
+ <exclusions>
+ <exclusion>
+ <artifactId>wagon-provider-api</artifactId>
+ <groupId>org.apache.maven.wagon</groupId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.sisu</groupId>
+ <artifactId>org.eclipse.sisu.plexus</artifactId>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.modello</groupId>
+ <artifactId>modello-maven-plugin</artifactId>
+ <configuration>
+ <models>
+ <model>src/main/mdo/lifecycle.mdo</model>
+ </models>
+ <version>1.0.0</version>
+ </configuration>
+ <executions>
+ <execution>
+ <id>plugin-site-doc</id>
+ <phase>pre-site</phase>
+ <goals>
+ <goal>xdoc</goal>
+ </goals>
+ <configuration>
+ <models>
+ <model>src/main/mdo/plugin.mdo</model>
+ </models>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/main/java/org/apache/maven/monitor/logging/DefaultLog.java b/framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/main/java/org/apache/maven/monitor/logging/DefaultLog.java
new file mode 100644
index 00000000..4fee2e25
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/main/java/org/apache/maven/monitor/logging/DefaultLog.java
@@ -0,0 +1,131 @@
+package org.apache.maven.monitor.logging;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.plugin.logging.Log;
+import org.codehaus.plexus.logging.Logger;
+
+/**
+ * @author jdcasey
+ */
+public class DefaultLog
+ implements Log
+{
+
+ private final Logger logger;
+
+ public DefaultLog( Logger logger )
+ {
+ this.logger = logger;
+ }
+
+ public void debug( CharSequence content )
+ {
+ logger.debug( toString( content ) );
+ }
+
+ private String toString( CharSequence content )
+ {
+ if ( content == null )
+ {
+ return "";
+ }
+ else
+ {
+ return content.toString();
+ }
+ }
+
+ public void debug( CharSequence content, Throwable error )
+ {
+ logger.debug( toString( content ), error );
+ }
+
+ public void debug( Throwable error )
+ {
+ logger.debug( "", error );
+ }
+
+ public void info( CharSequence content )
+ {
+ logger.info( toString( content ) );
+ }
+
+ public void info( CharSequence content, Throwable error )
+ {
+ logger.info( toString( content ), error );
+ }
+
+ public void info( Throwable error )
+ {
+ logger.info( "", error );
+ }
+
+ public void warn( CharSequence content )
+ {
+ logger.warn( toString( content ) );
+ }
+
+ public void warn( CharSequence content, Throwable error )
+ {
+ logger.warn( toString( content ), error );
+ }
+
+ public void warn( Throwable error )
+ {
+ logger.warn( "", error );
+ }
+
+ public void error( CharSequence content )
+ {
+ logger.error( toString( content ) );
+ }
+
+ public void error( CharSequence content, Throwable error )
+ {
+ logger.error( toString( content ), error );
+ }
+
+ public void error( Throwable error )
+ {
+ logger.error( "", error );
+ }
+
+ public boolean isDebugEnabled()
+ {
+ return logger.isDebugEnabled();
+ }
+
+ public boolean isInfoEnabled()
+ {
+ return logger.isInfoEnabled();
+ }
+
+ public boolean isWarnEnabled()
+ {
+ return logger.isWarnEnabled();
+ }
+
+ public boolean isErrorEnabled()
+ {
+ return logger.isErrorEnabled();
+ }
+
+} \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/main/java/org/apache/maven/plugin/AbstractMojo.java b/framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/main/java/org/apache/maven/plugin/AbstractMojo.java
new file mode 100644
index 00000000..d33e9bfc
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/main/java/org/apache/maven/plugin/AbstractMojo.java
@@ -0,0 +1,198 @@
+package org.apache.maven.plugin;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Map;
+
+import org.apache.maven.plugin.logging.Log;
+import org.apache.maven.plugin.logging.SystemStreamLog;
+
+/**
+ * Abstract class to provide most of the infrastructure required to implement a <code>Mojo</code> except for
+ * the execute method.
+ * <br/>
+ * The implementation should have a <code>goal</code> annotation in the class-level javadoc annotation:
+ * <pre>
+ * &#47;&#42;&#42;
+ * &#42; &#64;goal goalName
+ * &#42;&#47;
+ * </pre>
+ *
+ * There are also a number of class-level javadoc annotations which can be used to control how and when the
+ * <code>Mojo</code> is executed:
+ * <br/>
+ * <br/>
+ *
+ * <table border="1">
+ * <tr bgcolor="#CCCCCC">
+ * <th>Descriptor Element</th>
+ * <th>Annotation</th>
+ * <th>Required?</th>
+ * <th>Notes</th>
+ * </tr>
+ * <tr>
+ * <td>goal</td>
+ * <td>@goal &lt;goalName&gt;</td>
+ * <td>Yes</td>
+ * <td>The name for the Mojo that users will reference from the command line to execute the Mojo directly,
+ * or inside a POM in order to provide Mojo-specific configuration.</td>
+ * </tr>
+ * <tr>
+ * <td>implementation</td>
+ * <td>none (detected)</td>
+ * <td>Yes</td>
+ * <td>The Mojo's fully-qualified class name (or script path in the case of non-Java Mojos).</td>
+ * </tr>
+ * <tr>
+ * <td>language</td>
+ * <td>none (detected)</td>
+ * <td>No. Default: <code>java</code></td>
+ * <td>The implementation language for this Mojo (Java, beanshell, etc.).</td>
+ * </tr>
+ * <tr>
+ * <td>configurator</td>
+ * <td>@configurator &lt;roleHint&gt;</td>
+ * <td>No</td>
+ * <td>The configurator type to use when injecting parameter values into this Mojo. The value is normally
+ * deduced from the Mojo's implementation language, but can be specified to allow a custom
+ * ComponentConfigurator implementation to be used.
+ * <br/>
+ * <i>NOTE: This will only be used in very special cases, using a highly controlled vocabulary of possible
+ * values. (Elements like this are why it's a good idea to use the descriptor tools.)</i>
+ * </td>
+ * </tr>
+ * <tr>
+ * <td>phase</td>
+ * <td>@phase &lt;phaseName&gt;</td>
+ * <td>No</td>
+ * <td>Binds this Mojo to a particular phase of the standard build lifecycle, if specified.
+ * <br/>
+ * <i>NOTE: This is only required if this Mojo is to participate in the standard build process.</i>
+ * </td>
+ * </tr>
+ * <tr>
+ * <td>execute</td>
+ * <td>@execute [phase=&lt;phaseName&gt;|goal=&lt;goalName&gt;] [lifecycle=&lt;lifecycleId&gt;]</td>
+ * <td>No</td>
+ * <td>When this goal is invoked, it will first invoke a parallel lifecycle, ending at the given phase.
+ * If a goal is provided instead of a phase, that goal will be executed in isolation.
+ * The execution of either will not affect the current project, but instead make available the
+ * <code>${executedProject}</code> expression if required. An alternate lifecycle can also be provided:
+ * for more information see the documentation on the
+ * <a href="http://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html"
+ * target="_blank">build lifecycle</a>.
+ * </td>
+ * </tr>
+ * <tr>
+ * <td>requiresDependencyResolution</td>
+ * <td>@requiresDependencyResolution &lt;requiredScope&gt;</td>
+ * <td>No</td>
+ * <td>Flags this Mojo as requiring the dependencies in the specified scope (or an implied scope) to be
+ * resolved before it can execute.
+ * <br/>
+ * <i>NOTE: Currently supports <b>compile</b>, <b>runtime</b>, and <b>test</b> scopes.</i>
+ * </td>
+ * </tr>
+ * <tr>
+ * <td>description</td>
+ * <td>none (detected)</td>
+ * <td>No</td>
+ * <td>The description of this Mojo's functionality. <i>Using the toolset, this will be the class-level
+ * Javadoc description provided.
+ * <br/>
+ * <i>NOTE: While this is not a required part of the Mojo specification, it <b>SHOULD</b> be provided to
+ * enable future tool support for browsing, etc. and for clarity.</i>
+ * </td>
+ * </tr>
+ * <tr>
+ * <td>parameters</td>
+ * <td>N/A</td>
+ * <td>No</td>
+ * <td>Specifications for the parameters which this Mojo uses will be provided in <b>parameter</b> sub-elements
+ * in this section.
+ * <br/>
+ * <i>NOTE: Parameters are discussed in more detail below.</i>
+ * </td>
+ * </tr>
+ * </table>
+ *
+ * @see <a href="http://maven.apache.org/guides/plugin/guide-java-plugin-development.html" target="_blank">Guide to Developing Java Plugins</a>
+ * @see <a href="http://maven.apache.org/guides/mini/guide-configuring-plugins.html" target="_blank">Guide to Configuring Plug-ins</a>
+ * @see <a href="http://maven.apache.org/developers/mojo-api-specification.html" target="_blank">Mojo API Specification</a>
+ *
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ * @author jdcasey
+ * @author <a href="mailto:vincent.siveton@gmail.com">Vincent Siveton</a>
+ */
+public abstract class AbstractMojo
+ implements Mojo, ContextEnabled
+{
+ /** Instance logger */
+ private Log log;
+
+ /** Plugin container context */
+ private Map pluginContext;
+
+ /**
+ * @see org.apache.maven.plugin.Mojo#setLog(org.apache.maven.plugin.logging.Log)
+ */
+ public void setLog( Log log )
+ {
+ this.log = log;
+ }
+
+ /**
+ * Returns the logger that has been injected into this mojo. If no logger has been setup yet, a
+ * <code>SystemStreamLog</code> logger will be created and returned.
+ * <br/><br/>
+ * <strong>Note:</strong>
+ * The logger returned by this method must not be cached in an instance field during the construction of the mojo.
+ * This would cause the mojo to use a wrongly configured default logger when being run by Maven. The proper logger
+ * gets injected by the Plexus container <em>after</em> the mojo has been constructed. Therefore, simply call this
+ * method directly whenever you need the logger, it is fast enough and needs no caching.
+ *
+ * @see org.apache.maven.plugin.Mojo#getLog()
+ */
+ public Log getLog()
+ {
+ if ( log == null )
+ {
+ log = new SystemStreamLog();
+ }
+
+ return log;
+ }
+
+ /**
+ * @see org.apache.maven.plugin.ContextEnabled#getPluginContext()
+ */
+ public Map getPluginContext()
+ {
+ return pluginContext;
+ }
+
+ /**
+ * @see org.apache.maven.plugin.ContextEnabled#setPluginContext(java.util.Map)
+ */
+ public void setPluginContext( Map pluginContext )
+ {
+ this.pluginContext = pluginContext;
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/main/java/org/apache/maven/plugin/AbstractMojoExecutionException.java b/framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/main/java/org/apache/maven/plugin/AbstractMojoExecutionException.java
new file mode 100644
index 00000000..52aded3d
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/main/java/org/apache/maven/plugin/AbstractMojoExecutionException.java
@@ -0,0 +1,53 @@
+package org.apache.maven.plugin;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Base exception.
+ *
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ */
+public abstract class AbstractMojoExecutionException
+ extends Exception
+{
+ protected Object source;
+
+ protected String longMessage;
+
+ public AbstractMojoExecutionException( String message )
+ {
+ super( message );
+ }
+
+ public AbstractMojoExecutionException( String message, Throwable cause )
+ {
+ super( message, cause );
+ }
+
+ public String getLongMessage()
+ {
+ return longMessage;
+ }
+
+ public Object getSource()
+ {
+ return source;
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/main/java/org/apache/maven/plugin/ContextEnabled.java b/framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/main/java/org/apache/maven/plugin/ContextEnabled.java
new file mode 100644
index 00000000..d63cb49b
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/main/java/org/apache/maven/plugin/ContextEnabled.java
@@ -0,0 +1,45 @@
+package org.apache.maven.plugin;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Map;
+
+/**
+ * Interface to allow <code>Mojos</code> to communicate with each others <code>Mojos</code>, other than
+ * project's source root and project's attachment.
+ * <br/>
+ * The plugin manager would pull the context out of the plugin container context, and populate it into the Mojo.
+ *
+ * @author jdcasey
+ */
+public interface ContextEnabled
+{
+ /**
+ * Set a new shared context <code>Map</code> to a mojo before executing it.
+ *
+ * @param pluginContext a new <code>Map</code>
+ */
+ void setPluginContext( Map pluginContext );
+
+ /**
+ * @return a <code>Map</code> stored in the plugin container's context.
+ */
+ Map getPluginContext();
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/main/java/org/apache/maven/plugin/Mojo.java b/framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/main/java/org/apache/maven/plugin/Mojo.java
new file mode 100644
index 00000000..76a2aad7
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/main/java/org/apache/maven/plugin/Mojo.java
@@ -0,0 +1,72 @@
+package org.apache.maven.plugin;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.plugin.logging.Log;
+
+/**
+ * This interface forms the contract required for <code>Mojos</code> to interact with the <code>Maven</code>
+ * infrastructure.
+ * <br/>
+ * It features an <code>execute()</code> method, which triggers the Mojo's build-process behavior, and can throw
+ * a MojoExecutionException or MojoFailureException if error conditions occur.
+ * <br/>
+ * Also included is the <code>setLog(...)</code> method, which simply allows Maven to inject a logging mechanism which
+ * will allow the Mojo to communicate to the outside world through standard Maven channels.
+ *
+ * @author Jason van Zyl
+ */
+public interface Mojo
+{
+ /** The component <code>role</code> hint for Plexus container */
+ String ROLE = Mojo.class.getName();
+
+ /**
+ * Perform whatever build-process behavior this <code>Mojo</code> implements.
+ * <br/>
+ * This is the main trigger for the <code>Mojo</code> inside the <code>Maven</code> system, and allows
+ * the <code>Mojo</code> to communicate errors.
+ *
+ * @throws MojoExecutionException if an unexpected problem occurs.
+ * Throwing this exception causes a "BUILD ERROR" message to be displayed.
+ * @throws MojoFailureException if an expected problem (such as a compilation failure) occurs.
+ * Throwing this exception causes a "BUILD FAILURE" message to be displayed.
+ */
+ void execute()
+ throws MojoExecutionException, MojoFailureException;
+
+ /**
+ * Inject a standard <code>Maven</code> logging mechanism to allow this <code>Mojo</code> to communicate events
+ * and feedback to the user.
+ *
+ * @param log a new logger
+ */
+ // TODO: not sure about this here, and may want a getLog on here as well/instead
+ void setLog( Log log );
+
+ /**
+ * Furnish access to the standard Maven logging mechanism which is managed in this base class.
+ *
+ * @return a log4j-like logger object which allows plugins to create messages at levels of <code>"debug"</code>,
+ * <code>"info"</code>, <code>"warn"</code>, and <code>"error"</code>. This logger is the accepted means to display
+ * information to the user.
+ */
+ Log getLog();
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/main/java/org/apache/maven/plugin/MojoExecutionException.java b/framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/main/java/org/apache/maven/plugin/MojoExecutionException.java
new file mode 100644
index 00000000..b440af02
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/main/java/org/apache/maven/plugin/MojoExecutionException.java
@@ -0,0 +1,80 @@
+package org.apache.maven.plugin;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * An exception occurring during the execution of a plugin.
+ * <br/>
+ * Throwing this exception causes a "BUILD ERROR" message to be displayed.
+ *
+ * @author Brett Porter
+ */
+public class MojoExecutionException
+ extends AbstractMojoExecutionException
+{
+ /**
+ * Construct a new <code>MojoExecutionException</code> exception providing the source and a short and long message:
+ * these messages are used to improve the message written at the end of Maven build.
+ *
+ * @param source
+ * @param shortMessage
+ * @param longMessage
+ */
+ public MojoExecutionException( Object source, String shortMessage, String longMessage )
+ {
+ super( shortMessage );
+ this.source = source;
+ this.longMessage = longMessage;
+ }
+
+ /**
+ * Construct a new <code>MojoExecutionException</code> exception wrapping an underlying <code>Exception</code>
+ * and providing a <code>message</code>.
+ *
+ * @param message
+ * @param cause
+ */
+ public MojoExecutionException( String message, Exception cause )
+ {
+ super( message, cause );
+ }
+
+ /**
+ * Construct a new <code>MojoExecutionException</code> exception wrapping an underlying <code>Throwable</code>
+ * and providing a <code>message</code>.
+ *
+ * @param message
+ * @param cause
+ */
+ public MojoExecutionException( String message, Throwable cause )
+ {
+ super( message, cause );
+ }
+
+ /**
+ * Construct a new <code>MojoExecutionException</code> exception providing a <code>message</code>.
+ *
+ * @param message
+ */
+ public MojoExecutionException( String message )
+ {
+ super( message );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/main/java/org/apache/maven/plugin/MojoFailureException.java b/framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/main/java/org/apache/maven/plugin/MojoFailureException.java
new file mode 100644
index 00000000..28dc43d3
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/main/java/org/apache/maven/plugin/MojoFailureException.java
@@ -0,0 +1,69 @@
+package org.apache.maven.plugin;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * An exception occurring during the execution of a plugin (such as a compilation failure).
+ * <br/>
+ * Throwing this exception causes a "BUILD FAILURE" message to be displayed.
+ *
+ * @author Brett Porter
+ */
+public class MojoFailureException
+ extends AbstractMojoExecutionException
+{
+ /**
+ * Construct a new <code>MojoFailureException</code> exception providing the source and a short and long message:
+ * these messages are used to improve the message written at the end of Maven build.
+ *
+ * @param source
+ * @param shortMessage
+ * @param longMessage
+ */
+ public MojoFailureException( Object source, String shortMessage, String longMessage )
+ {
+ super( shortMessage );
+ this.source = source;
+ this.longMessage = longMessage;
+ }
+
+ /**
+ * Construct a new <code>MojoFailureException</code> exception providing a message.
+ *
+ * @param message
+ */
+ public MojoFailureException( String message )
+ {
+ super( message );
+ }
+
+ /**
+ * Construct a new <code>MojoFailureException</code> exception wrapping an underlying <code>Throwable</code>
+ * and providing a <code>message</code>.
+ *
+ * @param message
+ * @param cause
+ * @since 2.0.9
+ */
+ public MojoFailureException( String message, Throwable cause )
+ {
+ super( message, cause );
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/main/java/org/apache/maven/plugin/MojoNotFoundException.java b/framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/main/java/org/apache/maven/plugin/MojoNotFoundException.java
new file mode 100644
index 00000000..4d99546a
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/main/java/org/apache/maven/plugin/MojoNotFoundException.java
@@ -0,0 +1,85 @@
+package org.apache.maven.plugin;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.maven.plugin.descriptor.MojoDescriptor;
+import org.apache.maven.plugin.descriptor.PluginDescriptor;
+
+public class MojoNotFoundException
+ extends Exception
+{
+ private String goal;
+
+ private PluginDescriptor pluginDescriptor;
+
+ public MojoNotFoundException( String goal, PluginDescriptor pluginDescriptor )
+ {
+ super( toMessage( goal, pluginDescriptor ) );
+
+ this.goal = goal;
+ this.pluginDescriptor = pluginDescriptor;
+ }
+
+ public String getGoal()
+ {
+ return goal;
+ }
+
+ public PluginDescriptor getPluginDescriptor()
+ {
+ return pluginDescriptor;
+ }
+
+ private static String toMessage( String goal, PluginDescriptor pluginDescriptor )
+ {
+ StringBuilder buffer = new StringBuilder( 256 );
+
+ buffer.append( "Could not find goal '" ).append( goal ).append( "'" );
+
+ if ( pluginDescriptor != null )
+ {
+ buffer.append( " in plugin " ).append( pluginDescriptor.getId() );
+
+ buffer.append( " among available goals " );
+ List<MojoDescriptor> mojos = pluginDescriptor.getMojos();
+ if ( mojos != null )
+ {
+ for ( Iterator<MojoDescriptor> it = mojos.iterator(); it.hasNext(); )
+ {
+ MojoDescriptor mojo = it.next();
+ if ( mojo != null )
+ {
+ buffer.append( mojo.getGoal() );
+ }
+ if ( it.hasNext() )
+ {
+ buffer.append( ", " );
+ }
+ }
+ }
+ }
+
+ return buffer.toString();
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/DuplicateMojoDescriptorException.java b/framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/DuplicateMojoDescriptorException.java
new file mode 100644
index 00000000..b236c8c7
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/DuplicateMojoDescriptorException.java
@@ -0,0 +1,34 @@
+package org.apache.maven.plugin.descriptor;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+public class DuplicateMojoDescriptorException
+ extends InvalidPluginDescriptorException
+{
+
+ public DuplicateMojoDescriptorException( String goalPrefix, String goal, String existingImplementation,
+ String newImplementation )
+ {
+ super( "Goal: " + goal + " already exists in the plugin descriptor for prefix: " + goalPrefix
+ + "\nExisting implementation is: " + existingImplementation
+ + "\nConflicting implementation is: " + newImplementation );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/DuplicateParameterException.java b/framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/DuplicateParameterException.java
new file mode 100644
index 00000000..4cad9b7c
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/DuplicateParameterException.java
@@ -0,0 +1,31 @@
+package org.apache.maven.plugin.descriptor;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+public class DuplicateParameterException
+ extends InvalidPluginDescriptorException
+{
+
+ public DuplicateParameterException( String message )
+ {
+ super( message );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/InvalidParameterException.java b/framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/InvalidParameterException.java
new file mode 100644
index 00000000..557a3d54
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/InvalidParameterException.java
@@ -0,0 +1,37 @@
+package org.apache.maven.plugin.descriptor;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * @author Jason van Zyl
+ */
+public class InvalidParameterException
+ extends InvalidPluginDescriptorException
+{
+ public InvalidParameterException( String element, int i )
+ {
+ super( "The " + element + " element in parameter # " + i + " is invalid. It cannot be null." );
+ }
+
+ public InvalidParameterException( String message, Throwable cause )
+ {
+ super( message, cause );
+ }
+} \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/InvalidPluginDescriptorException.java b/framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/InvalidPluginDescriptorException.java
new file mode 100644
index 00000000..4b8e7397
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/InvalidPluginDescriptorException.java
@@ -0,0 +1,38 @@
+package org.apache.maven.plugin.descriptor;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.codehaus.plexus.configuration.PlexusConfigurationException;
+
+public class InvalidPluginDescriptorException
+ extends PlexusConfigurationException
+{
+
+ public InvalidPluginDescriptorException( String message, Throwable cause )
+ {
+ super( message, cause );
+ }
+
+ public InvalidPluginDescriptorException( String message )
+ {
+ super( message );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/MojoDescriptor.java b/framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/MojoDescriptor.java
new file mode 100644
index 00000000..bc2d5554
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/MojoDescriptor.java
@@ -0,0 +1,719 @@
+package org.apache.maven.plugin.descriptor;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.maven.plugin.Mojo;
+import org.codehaus.plexus.component.repository.ComponentDescriptor;
+import org.codehaus.plexus.configuration.PlexusConfiguration;
+import org.codehaus.plexus.configuration.xml.XmlPlexusConfiguration;
+
+/**
+ * The bean containing the Mojo descriptor.
+ * <br/>
+ * For more information about the usage tag, have a look to:
+ * <a href="http://maven.apache.org/developers/mojo-api-specification.html">
+ * http://maven.apache.org/developers/mojo-api-specification.html</a>
+ *
+ * @todo is there a need for the delegation of MavenMojoDescriptor to this?
+ * Why not just extend ComponentDescriptor here?
+ */
+public class MojoDescriptor
+ extends ComponentDescriptor<Mojo>
+ implements Cloneable
+{
+ /** The Plexus component type */
+ public static final String MAVEN_PLUGIN = "maven-plugin";
+
+ /** "once-per-session" execution strategy */
+ public static final String SINGLE_PASS_EXEC_STRATEGY = "once-per-session";
+
+ /** "always" execution strategy */
+ public static final String MULTI_PASS_EXEC_STRATEGY = "always";
+
+ private static final String DEFAULT_INSTANTIATION_STRATEGY = "per-lookup";
+
+ private static final String DEFAULT_LANGUAGE = "java";
+
+ private List<Parameter> parameters;
+
+ private Map<String, Parameter> parameterMap;
+
+ /** By default, the execution strategy is "once-per-session" */
+ private String executionStrategy = SINGLE_PASS_EXEC_STRATEGY;
+
+ /**
+ * The goal name for the Mojo, that users will reference from the command line to execute the Mojo directly, or
+ * inside a POM in order to provide Mojo-specific configuration.
+ */
+ private String goal;
+
+ /**
+ * Defines a default phase to bind a mojo execution to if the user does not explicitly set a phase in the POM.
+ * <i>Note:</i> This will not automagically make a mojo run when the plugin declaration is added to the POM. It
+ * merely enables the user to omit the <code>&lt;phase&gt;</code> element from the surrounding
+ * <code>&lt;execution&gt;</code> element.
+ */
+ private String phase;
+
+ /** Specify the version when the Mojo was added to the API. Similar to Javadoc since. */
+ private String since;
+
+ /** Reference the invocation phase of the Mojo. */
+ private String executePhase;
+
+ /** Reference the invocation goal of the Mojo. */
+ private String executeGoal;
+
+ /** Reference the invocation lifecycle of the Mojo. */
+ private String executeLifecycle;
+
+ /**
+ * Specify the version when the Mojo was deprecated to the API. Similar to Javadoc deprecated. This will trigger a
+ * warning when a user tries to configure a parameter marked as deprecated.
+ */
+ private String deprecated;
+
+ /**
+ * Flags this Mojo to run it in a multi module way, i.e. aggregate the build with the set of projects listed as
+ * modules. By default, no need to aggregate the Maven project and its child modules
+ */
+ private boolean aggregator = false;
+
+ // ----------------------------------------------------------------------
+ //
+ // ----------------------------------------------------------------------
+
+ /** Specify the required dependencies in a specified scope */
+ private String dependencyResolutionRequired = null;
+
+ /**
+ * The scope of (transitive) dependencies that should be collected but not resolved.
+ * @since 3.0-alpha-3
+ */
+ private String dependencyCollectionRequired;
+
+ /** By default, the Mojo needs a Maven project to be executed */
+ private boolean projectRequired = true;
+
+ /** By default, the Mojo is assumed to work offline as well */
+ private boolean onlineRequired = false;
+
+ /** Plugin configuration */
+ private PlexusConfiguration mojoConfiguration;
+
+ /** Plugin descriptor */
+ private PluginDescriptor pluginDescriptor;
+
+ /** By default, the Mojo is inherited */
+ private boolean inheritedByDefault = true;
+
+ /** By default, the Mojo cannot be invoked directly */
+ private boolean directInvocationOnly = false;
+
+ /** By default, the Mojo don't need reports to run */
+ private boolean requiresReports = false;
+
+ /**
+ * By default, mojos are not threadsafe
+ * @since 3.0-beta-2
+ */
+ private boolean threadSafe = false;
+
+ /**
+ * Default constructor.
+ */
+ public MojoDescriptor()
+ {
+ setInstantiationStrategy( DEFAULT_INSTANTIATION_STRATEGY );
+ setComponentFactory( DEFAULT_LANGUAGE );
+ }
+
+ // ----------------------------------------------------------------------
+ //
+ // ----------------------------------------------------------------------
+
+ /**
+ * @return the language of this Mojo, i.e. <code>java</code>
+ */
+ public String getLanguage()
+ {
+ return getComponentFactory();
+ }
+
+ /**
+ * @param language the new language
+ */
+ public void setLanguage( String language )
+ {
+ setComponentFactory( language );
+ }
+
+ /**
+ * @return <code>true</code> if the Mojo is deprecated, <code>false</code> otherwise.
+ */
+ public String getDeprecated()
+ {
+ return deprecated;
+ }
+
+ /**
+ * @param deprecated <code>true</code> to deprecate the Mojo, <code>false</code> otherwise.
+ */
+ public void setDeprecated( String deprecated )
+ {
+ this.deprecated = deprecated;
+ }
+
+ /**
+ * @return the list of parameters
+ */
+ public List<Parameter> getParameters()
+ {
+ return parameters;
+ }
+
+ /**
+ * @param parameters the new list of parameters
+ * @throws DuplicateParameterException if any
+ */
+ public void setParameters( List<Parameter> parameters )
+ throws DuplicateParameterException
+ {
+ for ( Parameter parameter : parameters )
+ {
+ addParameter( parameter );
+ }
+ }
+
+ /**
+ * @param parameter add a new parameter
+ * @throws DuplicateParameterException if any
+ */
+ public void addParameter( Parameter parameter )
+ throws DuplicateParameterException
+ {
+ if ( parameters != null && parameters.contains( parameter ) )
+ {
+ throw new DuplicateParameterException( parameter.getName()
+ + " has been declared multiple times in mojo with goal: " + getGoal() + " (implementation: "
+ + getImplementation() + ")" );
+ }
+
+ if ( parameters == null )
+ {
+ parameters = new LinkedList<Parameter>();
+ }
+
+ parameters.add( parameter );
+ }
+
+ /**
+ * @return the list parameters as a Map
+ */
+ public Map<String, Parameter> getParameterMap()
+ {
+ if ( parameterMap == null )
+ {
+ parameterMap = new HashMap<String, Parameter>();
+
+ if ( parameters != null )
+ {
+ for ( Parameter pd : parameters )
+ {
+ parameterMap.put( pd.getName(), pd );
+ }
+ }
+ }
+
+ return parameterMap;
+ }
+
+ // ----------------------------------------------------------------------
+ // Dependency requirement
+ // ----------------------------------------------------------------------
+
+ /**
+ * @param requiresDependencyResolution the new required dependencies in a specified scope
+ */
+ public void setDependencyResolutionRequired( String requiresDependencyResolution )
+ {
+ this.dependencyResolutionRequired = requiresDependencyResolution;
+ }
+
+ public String getDependencyResolutionRequired()
+ {
+ return dependencyResolutionRequired;
+ }
+
+ /**
+ * @return the required dependencies in a specified scope
+ * @TODO the name is not intelligible
+ */
+ @Deprecated
+ public String isDependencyResolutionRequired()
+ {
+ return dependencyResolutionRequired;
+ }
+
+ /**
+ * @since 3.0-alpha-3
+ */
+ public void setDependencyCollectionRequired( String requiresDependencyCollection )
+ {
+ this.dependencyCollectionRequired = requiresDependencyCollection;
+ }
+
+ /**
+ * Gets the scope of (transitive) dependencies that should be collected. Dependency collection refers to the process
+ * of calculating the complete dependency tree in terms of artifact coordinates. In contrast to dependency
+ * resolution, this does not include the download of the files for the dependency artifacts. It is meant for mojos
+ * that only want to analyze the set of transitive dependencies, in particular during early lifecycle phases where
+ * full dependency resolution might fail due to projects which haven't been built yet.
+ *
+ * @return The scope of (transitive) dependencies that should be collected or {@code null} if none.
+ * @since 3.0-alpha-3
+ */
+ public String getDependencyCollectionRequired()
+ {
+ return dependencyCollectionRequired;
+ }
+
+ // ----------------------------------------------------------------------
+ // Project requirement
+ // ----------------------------------------------------------------------
+
+ /**
+ * @param requiresProject <code>true</code> if the Mojo needs a Maven project to be executed, <code>false</code>
+ * otherwise.
+ */
+ public void setProjectRequired( boolean requiresProject )
+ {
+ this.projectRequired = requiresProject;
+ }
+
+ /**
+ * @return <code>true</code> if the Mojo needs a Maven project to be executed, <code>false</code> otherwise.
+ */
+ public boolean isProjectRequired()
+ {
+ return projectRequired;
+ }
+
+ // ----------------------------------------------------------------------
+ // Online vs. Offline requirement
+ // ----------------------------------------------------------------------
+
+ /**
+ * @param requiresOnline <code>true</code> if the Mojo is online, <code>false</code> otherwise.
+ */
+ public void setOnlineRequired( boolean requiresOnline )
+ {
+ this.onlineRequired = requiresOnline;
+ }
+
+ /**
+ * @return <code>true</code> if the Mojo is online, <code>false</code> otherwise.
+ */
+ // blech! this isn't even intelligible as a method name. provided for
+ // consistency...
+ public boolean isOnlineRequired()
+ {
+ return onlineRequired;
+ }
+
+ /**
+ * @return <code>true</code> if the Mojo is online, <code>false</code> otherwise.
+ */
+ // more english-friendly method...keep the code clean! :)
+ public boolean requiresOnline()
+ {
+ return onlineRequired;
+ }
+
+ /**
+ * @return the binded phase name of the Mojo
+ */
+ public String getPhase()
+ {
+ return phase;
+ }
+
+ /**
+ * @param phase the new binded phase name of the Mojo
+ */
+ public void setPhase( String phase )
+ {
+ this.phase = phase;
+ }
+
+ /**
+ * @return the version when the Mojo was added to the API
+ */
+ public String getSince()
+ {
+ return since;
+ }
+
+ /**
+ * @param since the new version when the Mojo was added to the API
+ */
+ public void setSince( String since )
+ {
+ this.since = since;
+ }
+
+ /**
+ * @return The goal name of the Mojo
+ */
+ public String getGoal()
+ {
+ return goal;
+ }
+
+ /**
+ * @param goal The new goal name of the Mojo
+ */
+ public void setGoal( String goal )
+ {
+ this.goal = goal;
+ }
+
+ /**
+ * @return the invocation phase of the Mojo
+ */
+ public String getExecutePhase()
+ {
+ return executePhase;
+ }
+
+ /**
+ * @param executePhase the new invocation phase of the Mojo
+ */
+ public void setExecutePhase( String executePhase )
+ {
+ this.executePhase = executePhase;
+ }
+
+ /**
+ * @return <code>true</code> if the Mojo uses <code>always</code> for the <code>executionStrategy</code>
+ */
+ public boolean alwaysExecute()
+ {
+ return MULTI_PASS_EXEC_STRATEGY.equals( executionStrategy );
+ }
+
+ /**
+ * @return the execution strategy
+ */
+ public String getExecutionStrategy()
+ {
+ return executionStrategy;
+ }
+
+ /**
+ * @param executionStrategy the new execution strategy
+ */
+ public void setExecutionStrategy( String executionStrategy )
+ {
+ this.executionStrategy = executionStrategy;
+ }
+
+ /**
+ * @return the mojo configuration
+ */
+ public PlexusConfiguration getMojoConfiguration()
+ {
+ if ( mojoConfiguration == null )
+ {
+ mojoConfiguration = new XmlPlexusConfiguration( "configuration" );
+ }
+ return mojoConfiguration;
+ }
+
+ /**
+ * @param mojoConfiguration a new mojo configuration
+ */
+ public void setMojoConfiguration( PlexusConfiguration mojoConfiguration )
+ {
+ this.mojoConfiguration = mojoConfiguration;
+ }
+
+ /** {@inheritDoc} */
+ public String getRole()
+ {
+ return Mojo.ROLE;
+ }
+
+ /** {@inheritDoc} */
+ public String getRoleHint()
+ {
+ return getId();
+ }
+
+ /**
+ * @return the id of the mojo, based on the goal name
+ */
+ public String getId()
+ {
+ return getPluginDescriptor().getId() + ":" + getGoal();
+ }
+
+ /**
+ * @return the full goal name
+ * @see PluginDescriptor#getGoalPrefix()
+ * @see #getGoal()
+ */
+ public String getFullGoalName()
+ {
+ return getPluginDescriptor().getGoalPrefix() + ":" + getGoal();
+ }
+
+ /** {@inheritDoc} */
+ public String getComponentType()
+ {
+ return MAVEN_PLUGIN;
+ }
+
+ /**
+ * @return the plugin descriptor
+ */
+ public PluginDescriptor getPluginDescriptor()
+ {
+ return pluginDescriptor;
+ }
+
+ /**
+ * @param pluginDescriptor the new plugin descriptor
+ */
+ public void setPluginDescriptor( PluginDescriptor pluginDescriptor )
+ {
+ this.pluginDescriptor = pluginDescriptor;
+ }
+
+ /**
+ * @return <code>true</code> if the Mojo is herited, <code>false</code> otherwise.
+ */
+ public boolean isInheritedByDefault()
+ {
+ return inheritedByDefault;
+ }
+
+ /**
+ * @param inheritedByDefault <code>true</code> if the Mojo is herited, <code>false</code> otherwise.
+ */
+ public void setInheritedByDefault( boolean inheritedByDefault )
+ {
+ this.inheritedByDefault = inheritedByDefault;
+ }
+
+ /** {@inheritDoc} */
+ public boolean equals( Object object )
+ {
+ if ( this == object )
+ {
+ return true;
+ }
+
+ if ( object instanceof MojoDescriptor )
+ {
+ MojoDescriptor other = (MojoDescriptor) object;
+
+ if ( !compareObjects( getPluginDescriptor(), other.getPluginDescriptor() ) )
+ {
+ return false;
+ }
+
+ return compareObjects( getGoal(), other.getGoal() );
+
+ }
+
+ return false;
+ }
+
+ private boolean compareObjects( Object first, Object second )
+ {
+ if ( first == second )
+ {
+ return true;
+ }
+
+ if ( first == null || second == null )
+ {
+ return false;
+ }
+
+ return first.equals( second );
+ }
+
+ /** {@inheritDoc} */
+ public int hashCode()
+ {
+ int result = 1;
+
+ String goal = getGoal();
+
+ if ( goal != null )
+ {
+ result += goal.hashCode();
+ }
+
+ PluginDescriptor pd = getPluginDescriptor();
+
+ if ( pd != null )
+ {
+ result -= pd.hashCode();
+ }
+
+ return result;
+ }
+
+ /**
+ * @return the invocation lifecycle of the Mojo
+ */
+ public String getExecuteLifecycle()
+ {
+ return executeLifecycle;
+ }
+
+ /**
+ * @param executeLifecycle the new invocation lifecycle of the Mojo
+ */
+ public void setExecuteLifecycle( String executeLifecycle )
+ {
+ this.executeLifecycle = executeLifecycle;
+ }
+
+ /**
+ * @param aggregator <code>true</code> if the Mojo uses the Maven project and its child modules,
+ * <code>false</code> otherwise.
+ */
+ public void setAggregator( boolean aggregator )
+ {
+ this.aggregator = aggregator;
+ }
+
+ /**
+ * @return <code>true</code> if the Mojo uses the Maven project and its child modules,
+ * <code>false</code> otherwise.
+ */
+ public boolean isAggregator()
+ {
+ return aggregator;
+ }
+
+ /**
+ * @return <code>true</code> if the Mojo cannot be invoked directly, <code>false</code> otherwise.
+ */
+ public boolean isDirectInvocationOnly()
+ {
+ return directInvocationOnly;
+ }
+
+ /**
+ * @param directInvocationOnly <code>true</code> if the Mojo cannot be invoked directly,
+ * <code>false</code> otherwise.
+ */
+ public void setDirectInvocationOnly( boolean directInvocationOnly )
+ {
+ this.directInvocationOnly = directInvocationOnly;
+ }
+
+ /**
+ * @return <code>true</code> if the Mojo needs reports to run, <code>false</code> otherwise.
+ */
+ public boolean isRequiresReports()
+ {
+ return requiresReports;
+ }
+
+ /**
+ * @param requiresReports <code>true</code> if the Mojo needs reports to run, <code>false</code> otherwise.
+ */
+ public void setRequiresReports( boolean requiresReports )
+ {
+ this.requiresReports = requiresReports;
+ }
+
+ /**
+ * @param executeGoal the new invocation goal of the Mojo
+ */
+ public void setExecuteGoal( String executeGoal )
+ {
+ this.executeGoal = executeGoal;
+ }
+
+ /**
+ * @return the invocation goal of the Mojo
+ */
+ public String getExecuteGoal()
+ {
+ return executeGoal;
+ }
+
+
+ /**
+ * @return True if the <code>Mojo</code> is thread-safe and can be run safely in parallel
+ * @since 3.0-beta-2
+ */
+ public boolean isThreadSafe()
+ {
+ return threadSafe;
+ }
+
+ /**
+ * @param threadSafe indicates that the mojo is thread-safe and can be run safely in parallel
+ * @since 3.0-beta-2
+ */
+ public void setThreadSafe( boolean threadSafe )
+ {
+ this.threadSafe = threadSafe;
+ }
+
+ /**
+ * @return {@code true} if this mojo forks either a goal or the lifecycle, {@code false} otherwise.
+ */
+ public boolean isForking()
+ {
+ return ( getExecuteGoal() != null && getExecuteGoal().length() > 0 )
+ || ( getExecutePhase() != null && getExecutePhase().length() > 0 );
+ }
+
+ /**
+ * Creates a shallow copy of this mojo descriptor.
+ */
+ @Override
+ public MojoDescriptor clone()
+ {
+ try
+ {
+ return (MojoDescriptor) super.clone();
+ }
+ catch ( CloneNotSupportedException e )
+ {
+ throw new UnsupportedOperationException( e );
+ }
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/Parameter.java b/framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/Parameter.java
new file mode 100644
index 00000000..6c5036bc
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/Parameter.java
@@ -0,0 +1,207 @@
+package org.apache.maven.plugin.descriptor;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * @author Jason van Zyl
+ */
+public class Parameter
+ implements Cloneable
+{
+ private String alias;
+
+ private String name;
+
+ private String type;
+
+ private boolean required;
+
+ private boolean editable = true;
+
+ private String description;
+
+ private String expression;
+
+ private String deprecated;
+
+ private String defaultValue;
+
+ private String implementation;
+
+ private Requirement requirement;
+
+ private String since;
+
+ // ----------------------------------------------------------------------
+ //
+ // ----------------------------------------------------------------------
+
+ public String getName()
+ {
+ return name;
+ }
+
+ public void setName( String name )
+ {
+ this.name = name;
+ }
+
+ public String getType()
+ {
+ return type;
+ }
+
+ public void setType( String type )
+ {
+ this.type = type;
+ }
+
+ public boolean isRequired()
+ {
+ return required;
+ }
+
+ public void setRequired( boolean required )
+ {
+ this.required = required;
+ }
+
+ public String getDescription()
+ {
+ return description;
+ }
+
+ public void setDescription( String description )
+ {
+ this.description = description;
+ }
+
+ public String getExpression()
+ {
+ return expression;
+ }
+
+ public void setExpression( String expression )
+ {
+ this.expression = expression;
+ }
+
+ public String getDeprecated()
+ {
+ return deprecated;
+ }
+
+ public void setDeprecated( String deprecated )
+ {
+ this.deprecated = deprecated;
+ }
+
+ public int hashCode()
+ {
+ return name.hashCode();
+ }
+
+ public boolean equals( Object other )
+ {
+ return ( other instanceof Parameter ) && getName().equals( ( (Parameter) other ).getName() );
+ }
+
+ public String getAlias()
+ {
+ return alias;
+ }
+
+ public void setAlias( String alias )
+ {
+ this.alias = alias;
+ }
+
+ public boolean isEditable()
+ {
+ return editable;
+ }
+
+ public void setEditable( boolean editable )
+ {
+ this.editable = editable;
+ }
+
+ public void setDefaultValue( String defaultValue )
+ {
+ this.defaultValue = defaultValue;
+ }
+
+ public String getDefaultValue()
+ {
+ return defaultValue;
+ }
+
+ public String toString()
+ {
+ return "Mojo parameter [name: \'" + getName() + "\'; alias: \'" + getAlias() + "\']";
+ }
+
+ public Requirement getRequirement()
+ {
+ return requirement;
+ }
+
+ public void setRequirement( Requirement requirement )
+ {
+ this.requirement = requirement;
+ }
+
+ public String getImplementation()
+ {
+ return implementation;
+ }
+
+ public void setImplementation( String implementation )
+ {
+ this.implementation = implementation;
+ }
+
+ public String getSince()
+ {
+ return since;
+ }
+
+ public void setSince( String since )
+ {
+ this.since = since;
+ }
+
+ /**
+ * Creates a shallow copy of this parameter.
+ */
+ @Override
+ public Parameter clone()
+ {
+ try
+ {
+ return (Parameter) super.clone();
+ }
+ catch ( CloneNotSupportedException e )
+ {
+ throw new UnsupportedOperationException( e );
+ }
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/PluginDescriptor.java b/framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/PluginDescriptor.java
new file mode 100644
index 00000000..1d6f1be4
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/PluginDescriptor.java
@@ -0,0 +1,445 @@
+package org.apache.maven.plugin.descriptor;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.ArtifactUtils;
+import org.apache.maven.model.Plugin;
+import org.apache.maven.plugin.lifecycle.Lifecycle;
+import org.apache.maven.plugin.lifecycle.LifecycleConfiguration;
+import org.apache.maven.plugin.lifecycle.io.xpp3.LifecycleMappingsXpp3Reader;
+import org.codehaus.plexus.classworlds.realm.ClassRealm;
+import org.codehaus.plexus.component.repository.ComponentSetDescriptor;
+import org.codehaus.plexus.util.IOUtil;
+import org.codehaus.plexus.util.ReaderFactory;
+import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
+
+/**
+ * @author Jason van Zyl
+ */
+public class PluginDescriptor
+ extends ComponentSetDescriptor
+ implements Cloneable
+{
+
+ private static final String LIFECYCLE_DESCRIPTOR = "META-INF/maven/lifecycle.xml";
+
+ private String groupId;
+
+ private String artifactId;
+
+ private String version;
+
+ private String goalPrefix;
+
+ private String source;
+
+ private boolean inheritedByDefault = true;
+
+ private List<Artifact> artifacts;
+
+ private ClassRealm classRealm;
+
+ // calculated on-demand.
+ private Map<String, Artifact> artifactMap;
+
+ private Set<Artifact> introducedDependencyArtifacts;
+
+ private String name;
+
+ private String description;
+
+ private String requiredMavenVersion;
+
+ private Plugin plugin;
+
+ private Artifact pluginArtifact;
+
+ private Map<String, Lifecycle> lifecycleMappings;
+
+ // ----------------------------------------------------------------------
+ //
+ // ----------------------------------------------------------------------
+
+ @SuppressWarnings( { "unchecked", "rawtypes" } )
+ public List<MojoDescriptor> getMojos()
+ {
+ return (List) getComponents();
+ }
+
+ public void addMojo( MojoDescriptor mojoDescriptor )
+ throws DuplicateMojoDescriptorException
+ {
+ MojoDescriptor existing = null;
+ // this relies heavily on the equals() and hashCode() for ComponentDescriptor,
+ // which uses role:roleHint for identity...and roleHint == goalPrefix:goal.
+ // role does not vary for Mojos.
+ List<MojoDescriptor> mojos = getMojos();
+
+ if ( mojos != null && mojos.contains( mojoDescriptor ) )
+ {
+ int indexOf = mojos.indexOf( mojoDescriptor );
+
+ existing = mojos.get( indexOf );
+ }
+
+ if ( existing != null )
+ {
+ throw new DuplicateMojoDescriptorException( getGoalPrefix(), mojoDescriptor.getGoal(), existing
+ .getImplementation(), mojoDescriptor.getImplementation() );
+ }
+ else
+ {
+ addComponentDescriptor( mojoDescriptor );
+ }
+ }
+
+ public String getGroupId()
+ {
+ return groupId;
+ }
+
+ public void setGroupId( String groupId )
+ {
+ this.groupId = groupId;
+ }
+
+ public String getArtifactId()
+ {
+ return artifactId;
+ }
+
+ public void setArtifactId( String artifactId )
+ {
+ this.artifactId = artifactId;
+ }
+
+ // ----------------------------------------------------------------------
+ // Dependencies
+ // ----------------------------------------------------------------------
+
+ public static String constructPluginKey( String groupId, String artifactId, String version )
+ {
+ return groupId + ":" + artifactId + ":" + version;
+ }
+
+ public String getPluginLookupKey()
+ {
+ return groupId + ":" + artifactId;
+ }
+
+ public String getId()
+ {
+ return constructPluginKey( groupId, artifactId, version );
+ }
+
+ public static String getDefaultPluginArtifactId( String id )
+ {
+ return "maven-" + id + "-plugin";
+ }
+
+ public static String getDefaultPluginGroupId()
+ {
+ return "org.apache.maven.plugins";
+ }
+
+ /**
+ * Parse maven-...-plugin.
+ *
+ * @todo move to plugin-tools-api as a default only
+ */
+ public static String getGoalPrefixFromArtifactId( String artifactId )
+ {
+ if ( "maven-plugin-plugin".equals( artifactId ) )
+ {
+ return "plugin";
+ }
+ else
+ {
+ return artifactId.replaceAll( "-?maven-?", "" ).replaceAll( "-?plugin-?", "" );
+ }
+ }
+
+ public String getGoalPrefix()
+ {
+ return goalPrefix;
+ }
+
+ public void setGoalPrefix( String goalPrefix )
+ {
+ this.goalPrefix = goalPrefix;
+ }
+
+ public void setVersion( String version )
+ {
+ this.version = version;
+ }
+
+ public String getVersion()
+ {
+ return version;
+ }
+
+ public void setSource( String source )
+ {
+ this.source = source;
+ }
+
+ public String getSource()
+ {
+ return source;
+ }
+
+ public boolean isInheritedByDefault()
+ {
+ return inheritedByDefault;
+ }
+
+ public void setInheritedByDefault( boolean inheritedByDefault )
+ {
+ this.inheritedByDefault = inheritedByDefault;
+ }
+
+ /**
+ * Gets the artifacts that make up the plugin's class realm, excluding artifacts shadowed by the Maven core realm
+ * like {@code maven-project}.
+ *
+ * @return The plugin artifacts, never {@code null}.
+ */
+ public List<Artifact> getArtifacts()
+ {
+ return artifacts;
+ }
+
+ public void setArtifacts( List<Artifact> artifacts )
+ {
+ this.artifacts = artifacts;
+
+ // clear the calculated artifactMap
+ artifactMap = null;
+ }
+
+ /**
+ * The map of artifacts accessible by the versionlessKey, i.e. groupId:artifactId
+ *
+ * @return a Map of artifacts, never {@code null}
+ * @see #getArtifacts()
+ */
+ public Map<String, Artifact> getArtifactMap()
+ {
+ if ( artifactMap == null )
+ {
+ artifactMap = ArtifactUtils.artifactMapByVersionlessId( getArtifacts() );
+ }
+
+ return artifactMap;
+ }
+
+ public boolean equals( Object object )
+ {
+ if ( this == object )
+ {
+ return true;
+ }
+
+ return object instanceof PluginDescriptor && getId().equals( ( (PluginDescriptor) object ).getId() );
+ }
+
+ public int hashCode()
+ {
+ return 10 + getId().hashCode();
+ }
+
+ public MojoDescriptor getMojo( String goal )
+ {
+ if ( getMojos() == null )
+ {
+ return null; // no mojo in this POM
+ }
+
+ // TODO: could we use a map? Maybe if the parent did that for components too, as this is too vulnerable to
+ // changes above not being propagated to the map
+ for ( MojoDescriptor desc : getMojos() )
+ {
+ if ( goal.equals( desc.getGoal() ) )
+ {
+ return desc;
+ }
+ }
+ return null;
+ }
+
+ public void setClassRealm( ClassRealm classRealm )
+ {
+ this.classRealm = classRealm;
+ }
+
+ public ClassRealm getClassRealm()
+ {
+ return classRealm;
+ }
+
+ public void setIntroducedDependencyArtifacts( Set<Artifact> introducedDependencyArtifacts )
+ {
+ this.introducedDependencyArtifacts = introducedDependencyArtifacts;
+ }
+
+ public Set<Artifact> getIntroducedDependencyArtifacts()
+ {
+ return ( introducedDependencyArtifacts != null ) ? introducedDependencyArtifacts
+ : Collections.<Artifact>emptySet();
+ }
+
+ public void setName( String name )
+ {
+ this.name = name;
+ }
+
+ public String getName()
+ {
+ return name;
+ }
+
+ public void setDescription( String description )
+ {
+ this.description = description;
+ }
+
+ public String getDescription()
+ {
+ return description;
+ }
+
+ public void setRequiredMavenVersion( String requiredMavenVersion )
+ {
+ this.requiredMavenVersion = requiredMavenVersion;
+ }
+
+ public String getRequiredMavenVersion()
+ {
+ return requiredMavenVersion;
+ }
+
+ public void setPlugin( Plugin plugin )
+ {
+ this.plugin = plugin;
+ }
+
+ public Plugin getPlugin()
+ {
+ return plugin;
+ }
+
+ public Artifact getPluginArtifact()
+ {
+ return pluginArtifact;
+ }
+
+ public void setPluginArtifact( Artifact pluginArtifact )
+ {
+ this.pluginArtifact = pluginArtifact;
+ }
+
+ public Lifecycle getLifecycleMapping( String lifecycleId )
+ throws IOException, XmlPullParserException
+ {
+ if ( lifecycleMappings == null )
+ {
+ LifecycleConfiguration lifecycleConfiguration;
+
+ Reader reader = null;
+ try
+ {
+ reader = ReaderFactory.newXmlReader( getDescriptorStream( LIFECYCLE_DESCRIPTOR ) );
+
+ lifecycleConfiguration = new LifecycleMappingsXpp3Reader().read( reader );
+ }
+ finally
+ {
+ IOUtil.close( reader );
+ }
+
+ lifecycleMappings = new HashMap<String, Lifecycle>();
+
+ for ( Lifecycle lifecycle : lifecycleConfiguration.getLifecycles() )
+ {
+ lifecycleMappings.put( lifecycle.getId(), lifecycle );
+ }
+ }
+
+ return lifecycleMappings.get( lifecycleId );
+ }
+
+ private InputStream getDescriptorStream( String descriptor )
+ throws IOException
+ {
+ File pluginFile = ( pluginArtifact != null ) ? pluginArtifact.getFile() : null;
+ if ( pluginFile == null )
+ {
+ throw new IllegalStateException( "plugin main artifact has not been resolved for " + getId() );
+ }
+
+ if ( pluginFile.isFile() )
+ {
+ try
+ {
+ return new URL( "jar:" + pluginFile.toURI() + "!/" + descriptor ).openStream();
+ }
+ catch ( MalformedURLException e )
+ {
+ throw new IllegalStateException( e );
+ }
+ }
+ else
+ {
+ return new FileInputStream( new File( pluginFile, descriptor ) );
+ }
+ }
+
+ /**
+ * Creates a shallow copy of this plugin descriptor.
+ */
+ @Override
+ public PluginDescriptor clone()
+ {
+ try
+ {
+ return (PluginDescriptor) super.clone();
+ }
+ catch ( CloneNotSupportedException e )
+ {
+ throw new UnsupportedOperationException( e );
+ }
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/PluginDescriptorBuilder.java b/framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/PluginDescriptorBuilder.java
new file mode 100644
index 00000000..66b16916
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/PluginDescriptorBuilder.java
@@ -0,0 +1,358 @@
+package org.apache.maven.plugin.descriptor;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.IOException;
+import java.io.Reader;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.codehaus.plexus.component.repository.ComponentDependency;
+import org.codehaus.plexus.component.repository.ComponentRequirement;
+import org.codehaus.plexus.configuration.PlexusConfiguration;
+import org.codehaus.plexus.configuration.PlexusConfigurationException;
+import org.codehaus.plexus.configuration.xml.XmlPlexusConfiguration;
+import org.codehaus.plexus.util.xml.Xpp3DomBuilder;
+import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
+
+/**
+ * @author Jason van Zyl
+ */
+public class PluginDescriptorBuilder
+{
+ public PluginDescriptor build( Reader reader )
+ throws PlexusConfigurationException
+ {
+ return build( reader, null );
+ }
+
+ public PluginDescriptor build( Reader reader, String source )
+ throws PlexusConfigurationException
+ {
+ PlexusConfiguration c = buildConfiguration( reader );
+
+ PluginDescriptor pluginDescriptor = new PluginDescriptor();
+
+ pluginDescriptor.setSource( source );
+ pluginDescriptor.setGroupId( c.getChild( "groupId" ).getValue() );
+ pluginDescriptor.setArtifactId( c.getChild( "artifactId" ).getValue() );
+ pluginDescriptor.setVersion( c.getChild( "version" ).getValue() );
+ pluginDescriptor.setGoalPrefix( c.getChild( "goalPrefix" ).getValue() );
+
+ pluginDescriptor.setName( c.getChild( "name" ).getValue() );
+ pluginDescriptor.setDescription( c.getChild( "description" ).getValue() );
+
+ String isolatedRealm = c.getChild( "isolatedRealm" ).getValue();
+
+ if ( isolatedRealm != null )
+ {
+ pluginDescriptor.setIsolatedRealm( Boolean.parseBoolean( isolatedRealm ) );
+ }
+
+ String inheritedByDefault = c.getChild( "inheritedByDefault" ).getValue();
+
+ if ( inheritedByDefault != null )
+ {
+ pluginDescriptor.setInheritedByDefault( Boolean.parseBoolean( inheritedByDefault ) );
+ }
+
+ // ----------------------------------------------------------------------
+ // Components
+ // ----------------------------------------------------------------------
+
+ PlexusConfiguration[] mojoConfigurations = c.getChild( "mojos" ).getChildren( "mojo" );
+
+ for ( PlexusConfiguration component : mojoConfigurations )
+ {
+ MojoDescriptor mojoDescriptor = buildComponentDescriptor( component, pluginDescriptor );
+
+ pluginDescriptor.addMojo( mojoDescriptor );
+ }
+
+ // ----------------------------------------------------------------------
+ // Dependencies
+ // ----------------------------------------------------------------------
+
+ PlexusConfiguration[] dependencyConfigurations = c.getChild( "dependencies" ).getChildren( "dependency" );
+
+ List<ComponentDependency> dependencies = new ArrayList<ComponentDependency>();
+
+ for ( PlexusConfiguration d : dependencyConfigurations )
+ {
+ ComponentDependency cd = new ComponentDependency();
+
+ cd.setArtifactId( d.getChild( "artifactId" ).getValue() );
+
+ cd.setGroupId( d.getChild( "groupId" ).getValue() );
+
+ cd.setType( d.getChild( "type" ).getValue() );
+
+ cd.setVersion( d.getChild( "version" ).getValue() );
+
+ dependencies.add( cd );
+ }
+
+ pluginDescriptor.setDependencies( dependencies );
+
+ return pluginDescriptor;
+ }
+
+ public MojoDescriptor buildComponentDescriptor( PlexusConfiguration c, PluginDescriptor pluginDescriptor )
+ throws PlexusConfigurationException
+ {
+ MojoDescriptor mojo = new MojoDescriptor();
+ mojo.setPluginDescriptor( pluginDescriptor );
+
+ mojo.setGoal( c.getChild( "goal" ).getValue() );
+
+ mojo.setImplementation( c.getChild( "implementation" ).getValue() );
+
+ PlexusConfiguration langConfig = c.getChild( "language" );
+
+ if ( langConfig != null )
+ {
+ mojo.setLanguage( langConfig.getValue() );
+ }
+
+ PlexusConfiguration configuratorConfig = c.getChild( "configurator" );
+
+ if ( configuratorConfig != null )
+ {
+ mojo.setComponentConfigurator( configuratorConfig.getValue() );
+ }
+
+ PlexusConfiguration composerConfig = c.getChild( "composer" );
+
+ if ( composerConfig != null )
+ {
+ mojo.setComponentComposer( composerConfig.getValue() );
+ }
+
+ String since = c.getChild( "since" ).getValue();
+
+ if ( since != null )
+ {
+ mojo.setSince( since );
+ }
+
+ PlexusConfiguration deprecated = c.getChild( "deprecated", false );
+
+ if ( deprecated != null )
+ {
+ mojo.setDeprecated( deprecated.getValue() );
+ }
+
+ String phase = c.getChild( "phase" ).getValue();
+
+ if ( phase != null )
+ {
+ mojo.setPhase( phase );
+ }
+
+ String executePhase = c.getChild( "executePhase" ).getValue();
+
+ if ( executePhase != null )
+ {
+ mojo.setExecutePhase( executePhase );
+ }
+
+ String executeMojo = c.getChild( "executeGoal" ).getValue();
+
+ if ( executeMojo != null )
+ {
+ mojo.setExecuteGoal( executeMojo );
+ }
+
+ String executeLifecycle = c.getChild( "executeLifecycle" ).getValue();
+
+ if ( executeLifecycle != null )
+ {
+ mojo.setExecuteLifecycle( executeLifecycle );
+ }
+
+ mojo.setInstantiationStrategy( c.getChild( "instantiationStrategy" ).getValue() );
+
+ mojo.setDescription( c.getChild( "description" ).getValue() );
+
+ PlexusConfiguration dependencyResolution = c.getChild( "requiresDependencyResolution", false );
+
+ if ( dependencyResolution != null )
+ {
+ mojo.setDependencyResolutionRequired( dependencyResolution.getValue() );
+ }
+
+ PlexusConfiguration dependencyCollection = c.getChild( "requiresDependencyCollection", false );
+
+ if ( dependencyCollection != null )
+ {
+ mojo.setDependencyCollectionRequired( dependencyCollection.getValue() );
+ }
+
+ String directInvocationOnly = c.getChild( "requiresDirectInvocation" ).getValue();
+
+ if ( directInvocationOnly != null )
+ {
+ mojo.setDirectInvocationOnly( Boolean.parseBoolean( directInvocationOnly ) );
+ }
+
+ String requiresProject = c.getChild( "requiresProject" ).getValue();
+
+ if ( requiresProject != null )
+ {
+ mojo.setProjectRequired( Boolean.parseBoolean( requiresProject ) );
+ }
+
+ String requiresReports = c.getChild( "requiresReports" ).getValue();
+
+ if ( requiresReports != null )
+ {
+ mojo.setRequiresReports( Boolean.parseBoolean( requiresReports ) );
+ }
+
+ String aggregator = c.getChild( "aggregator" ).getValue();
+
+ if ( aggregator != null )
+ {
+ mojo.setAggregator( Boolean.parseBoolean( aggregator ) );
+ }
+
+ String requiresOnline = c.getChild( "requiresOnline" ).getValue();
+
+ if ( requiresOnline != null )
+ {
+ mojo.setOnlineRequired( Boolean.parseBoolean( requiresOnline ) );
+ }
+
+ String inheritedByDefault = c.getChild( "inheritedByDefault" ).getValue();
+
+ if ( inheritedByDefault != null )
+ {
+ mojo.setInheritedByDefault( Boolean.parseBoolean( inheritedByDefault ) );
+ }
+
+ String threadSafe = c.getChild( "threadSafe" ).getValue();
+
+ if ( threadSafe != null )
+ {
+ mojo.setThreadSafe( Boolean.parseBoolean( threadSafe ) );
+ }
+
+ // ----------------------------------------------------------------------
+ // Configuration
+ // ----------------------------------------------------------------------
+
+ PlexusConfiguration mojoConfig = c.getChild( "configuration" );
+ mojo.setMojoConfiguration( mojoConfig );
+
+ // ----------------------------------------------------------------------
+ // Parameters
+ // ----------------------------------------------------------------------
+
+ PlexusConfiguration[] parameterConfigurations = c.getChild( "parameters" ).getChildren( "parameter" );
+
+ List<Parameter> parameters = new ArrayList<Parameter>();
+
+ for ( PlexusConfiguration d : parameterConfigurations )
+ {
+ Parameter parameter = new Parameter();
+
+ parameter.setName( d.getChild( "name" ).getValue() );
+
+ parameter.setAlias( d.getChild( "alias" ).getValue() );
+
+ parameter.setType( d.getChild( "type" ).getValue() );
+
+ String required = d.getChild( "required" ).getValue();
+
+ parameter.setRequired( Boolean.parseBoolean( required ) );
+
+ PlexusConfiguration editableConfig = d.getChild( "editable" );
+
+ // we need the null check for pre-build legacy plugins...
+ if ( editableConfig != null )
+ {
+ String editable = d.getChild( "editable" ).getValue();
+
+ parameter.setEditable( editable == null || Boolean.parseBoolean( editable ) );
+ }
+
+ parameter.setDescription( d.getChild( "description" ).getValue() );
+
+ parameter.setDeprecated( d.getChild( "deprecated" ).getValue() );
+
+ parameter.setImplementation( d.getChild( "implementation" ).getValue() );
+
+ PlexusConfiguration paramConfig = mojoConfig.getChild( parameter.getName(), false );
+ if ( paramConfig != null )
+ {
+ parameter.setExpression( paramConfig.getValue( null ) );
+ parameter.setDefaultValue( paramConfig.getAttribute( "default-value" ) );
+ }
+
+ parameters.add( parameter );
+ }
+
+ mojo.setParameters( parameters );
+
+ // TODO: this should not need to be handed off...
+
+ // ----------------------------------------------------------------------
+ // Requirements
+ // ----------------------------------------------------------------------
+
+ PlexusConfiguration[] requirements = c.getChild( "requirements" ).getChildren( "requirement" );
+
+ for ( PlexusConfiguration requirement : requirements )
+ {
+ ComponentRequirement cr = new ComponentRequirement();
+
+ cr.setRole( requirement.getChild( "role" ).getValue() );
+
+ cr.setRoleHint( requirement.getChild( "role-hint" ).getValue() );
+
+ cr.setFieldName( requirement.getChild( "field-name" ).getValue() );
+
+ mojo.addRequirement( cr );
+ }
+
+ return mojo;
+ }
+
+ // ----------------------------------------------------------------------
+ //
+ // ----------------------------------------------------------------------
+
+ public PlexusConfiguration buildConfiguration( Reader configuration )
+ throws PlexusConfigurationException
+ {
+ try
+ {
+ return new XmlPlexusConfiguration( Xpp3DomBuilder.build( configuration ) );
+ }
+ catch ( IOException e )
+ {
+ throw new PlexusConfigurationException( e.getMessage(), e );
+ }
+ catch ( XmlPullParserException e )
+ {
+ throw new PlexusConfigurationException( e.getMessage(), e );
+ }
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/Requirement.java b/framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/Requirement.java
new file mode 100644
index 00000000..1526b039
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/Requirement.java
@@ -0,0 +1,72 @@
+package org.apache.maven.plugin.descriptor;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Describes a component requirement.
+ *
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ */
+public class Requirement
+ implements Cloneable
+{
+ private final String role;
+
+ private final String roleHint;
+
+ public Requirement( String role )
+ {
+ this.role = role;
+ this.roleHint = null;
+ }
+
+ public Requirement( String role, String roleHint )
+ {
+ this.role = role;
+ this.roleHint = roleHint;
+ }
+
+ public String getRole()
+ {
+ return role;
+ }
+
+ public String getRoleHint()
+ {
+ return roleHint;
+ }
+
+ /**
+ * Creates a shallow copy of this requirement.
+ */
+ @Override
+ public Requirement clone()
+ {
+ try
+ {
+ return (Requirement) super.clone();
+ }
+ catch ( CloneNotSupportedException e )
+ {
+ throw new UnsupportedOperationException( e );
+ }
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/main/java/org/apache/maven/plugin/logging/Log.java b/framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/main/java/org/apache/maven/plugin/logging/Log.java
new file mode 100644
index 00000000..8d3bf1f9
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/main/java/org/apache/maven/plugin/logging/Log.java
@@ -0,0 +1,158 @@
+package org.apache.maven.plugin.logging;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * This interface supplies the API for providing feedback to the user from the <code>Mojo</code>, using standard
+ * <code>Maven</code> channels.
+ * <br/>
+ * There should be no big surprises here, although you may notice that the methods accept
+ * <code>java.lang.CharSequence</code> rather than <code>java.lang.String</code>. This is provided mainly as a
+ * convenience, to enable developers to pass things like <code>java.lang.StringBuffer</code> directly into the logger,
+ * rather than formatting first by calling <code>toString()</code>.
+ *
+ * @author jdcasey
+ */
+public interface Log
+{
+ /**
+ * @return true if the <b>debug</b> error level is enabled
+ */
+ boolean isDebugEnabled();
+
+ /**
+ * Send a message to the user in the <b>debug</b> error level.
+ *
+ * @param content
+ */
+ void debug( CharSequence content );
+
+ /**
+ * Send a message (and accompanying exception) to the user in the <b>debug</b> error level.
+ * <br/>
+ * The error's stacktrace will be output when this error level is enabled.
+ *
+ * @param content
+ * @param error
+ */
+ void debug( CharSequence content, Throwable error );
+
+ /**
+ * Send an exception to the user in the <b>debug</b> error level.
+ * <br/>
+ * The stack trace for this exception will be output when this error level is enabled.
+ *
+ * @param error
+ */
+ void debug( Throwable error );
+
+ /**
+ * @return true if the <b>info</b> error level is enabled
+ */
+ boolean isInfoEnabled();
+
+ /**
+ * Send a message to the user in the <b>info</b> error level.
+ *
+ * @param content
+ */
+ void info( CharSequence content );
+
+ /**
+ * Send a message (and accompanying exception) to the user in the <b>info</b> error level.
+ * <br/>
+ * The error's stacktrace will be output when this error level is enabled.
+ *
+ * @param content
+ * @param error
+ */
+ void info( CharSequence content, Throwable error );
+
+ /**
+ * Send an exception to the user in the <b>info</b> error level.
+ * <br/>
+ * The stack trace for this exception will be output when this error level is enabled.
+ *
+ * @param error
+ */
+ void info( Throwable error );
+
+ /**
+ * @return true if the <b>warn</b> error level is enabled
+ */
+ boolean isWarnEnabled();
+
+ /**
+ * Send a message to the user in the <b>warn</b> error level.
+ *
+ * @param content
+ */
+ void warn( CharSequence content );
+
+ /**
+ * Send a message (and accompanying exception) to the user in the <b>warn</b> error level.
+ * <br/>
+ * The error's stacktrace will be output when this error level is enabled.
+ *
+ * @param content
+ * @param error
+ */
+ void warn( CharSequence content, Throwable error );
+
+ /**
+ * Send an exception to the user in the <b>warn</b> error level.
+ * <br/>
+ * The stack trace for this exception will be output when this error level is enabled.
+ *
+ * @param error
+ */
+ void warn( Throwable error );
+
+ /**
+ * @return true if the <b>error</b> error level is enabled
+ */
+ boolean isErrorEnabled();
+
+ /**
+ * Send a message to the user in the <b>error</b> error level.
+ *
+ * @param content
+ */
+ void error( CharSequence content );
+
+ /**
+ * Send a message (and accompanying exception) to the user in the <b>error</b> error level.
+ * <br/>
+ * The error's stacktrace will be output when this error level is enabled.
+ *
+ * @param content
+ * @param error
+ */
+ void error( CharSequence content, Throwable error );
+
+ /**
+ * Send an exception to the user in the <b>error</b> error level.
+ * <br/>
+ * The stack trace for this exception will be output when this error level is enabled.
+ *
+ * @param error
+ */
+ void error( Throwable error );
+} \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/main/java/org/apache/maven/plugin/logging/SystemStreamLog.java b/framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/main/java/org/apache/maven/plugin/logging/SystemStreamLog.java
new file mode 100644
index 00000000..90475bf5
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/main/java/org/apache/maven/plugin/logging/SystemStreamLog.java
@@ -0,0 +1,196 @@
+package org.apache.maven.plugin.logging;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+/**
+ * Logger with "standard" output and error output stream.
+ *
+ * @author jdcasey
+ */
+public class SystemStreamLog
+ implements Log
+{
+ /**
+ * @see org.apache.maven.plugin.logging.Log#debug(java.lang.CharSequence)
+ */
+ public void debug( CharSequence content )
+ {
+ print( "debug", content );
+ }
+
+ /**
+ * @see org.apache.maven.plugin.logging.Log#debug(java.lang.CharSequence, java.lang.Throwable)
+ */
+ public void debug( CharSequence content, Throwable error )
+ {
+ print( "debug", content, error );
+ }
+
+ /**
+ * @see org.apache.maven.plugin.logging.Log#debug(java.lang.Throwable)
+ */
+ public void debug( Throwable error )
+ {
+ print( "debug", error );
+ }
+
+ /**
+ * @see org.apache.maven.plugin.logging.Log#info(java.lang.CharSequence)
+ */
+ public void info( CharSequence content )
+ {
+ print( "info", content );
+ }
+
+ /**
+ * @see org.apache.maven.plugin.logging.Log#info(java.lang.CharSequence, java.lang.Throwable)
+ */
+ public void info( CharSequence content, Throwable error )
+ {
+ print( "info", content, error );
+ }
+
+ /**
+ * @see org.apache.maven.plugin.logging.Log#info(java.lang.Throwable)
+ */
+ public void info( Throwable error )
+ {
+ print( "info", error );
+ }
+
+ /**
+ * @see org.apache.maven.plugin.logging.Log#warn(java.lang.CharSequence)
+ */
+ public void warn( CharSequence content )
+ {
+ print( "warn", content );
+ }
+
+ /**
+ * @see org.apache.maven.plugin.logging.Log#warn(java.lang.CharSequence, java.lang.Throwable)
+ */
+ public void warn( CharSequence content, Throwable error )
+ {
+ print( "warn", content, error );
+ }
+
+ /**
+ * @see org.apache.maven.plugin.logging.Log#warn(java.lang.Throwable)
+ */
+ public void warn( Throwable error )
+ {
+ print( "warn", error );
+ }
+
+ /**
+ * @see org.apache.maven.plugin.logging.Log#error(java.lang.CharSequence)
+ */
+ public void error( CharSequence content )
+ {
+ System.err.println( "[error] " + content.toString() );
+ }
+
+ /**
+ * @see org.apache.maven.plugin.logging.Log#error(java.lang.CharSequence, java.lang.Throwable)
+ */
+ public void error( CharSequence content, Throwable error )
+ {
+ StringWriter sWriter = new StringWriter();
+ PrintWriter pWriter = new PrintWriter( sWriter );
+
+ error.printStackTrace( pWriter );
+
+ System.err.println( "[error] " + content.toString() + "\n\n" + sWriter.toString() );
+ }
+
+ /**
+ * @see org.apache.maven.plugin.logging.Log#error(java.lang.Throwable)
+ */
+ public void error( Throwable error )
+ {
+ StringWriter sWriter = new StringWriter();
+ PrintWriter pWriter = new PrintWriter( sWriter );
+
+ error.printStackTrace( pWriter );
+
+ System.err.println( "[error] " + sWriter.toString() );
+ }
+
+ /**
+ * @see org.apache.maven.plugin.logging.Log#isDebugEnabled()
+ */
+ public boolean isDebugEnabled()
+ {
+ // TODO: Not sure how best to set these for this implementation...
+ return false;
+ }
+
+ /**
+ * @see org.apache.maven.plugin.logging.Log#isInfoEnabled()
+ */
+ public boolean isInfoEnabled()
+ {
+ return true;
+ }
+
+ /**
+ * @see org.apache.maven.plugin.logging.Log#isWarnEnabled()
+ */
+ public boolean isWarnEnabled()
+ {
+ return true;
+ }
+
+ /**
+ * @see org.apache.maven.plugin.logging.Log#isErrorEnabled()
+ */
+ public boolean isErrorEnabled()
+ {
+ return true;
+ }
+
+ private void print( String prefix, CharSequence content )
+ {
+ System.out.println( "[" + prefix + "] " + content.toString() );
+ }
+
+ private void print( String prefix, Throwable error )
+ {
+ StringWriter sWriter = new StringWriter();
+ PrintWriter pWriter = new PrintWriter( sWriter );
+
+ error.printStackTrace( pWriter );
+
+ System.out.println( "[" + prefix + "] " + sWriter.toString() );
+ }
+
+ private void print( String prefix, CharSequence content, Throwable error )
+ {
+ StringWriter sWriter = new StringWriter();
+ PrintWriter pWriter = new PrintWriter( sWriter );
+
+ error.printStackTrace( pWriter );
+
+ System.out.println( "[" + prefix + "] " + content.toString() + "\n\n" + sWriter.toString() );
+ }
+} \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/main/mdo/lifecycle.mdo b/framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/main/mdo/lifecycle.mdo
new file mode 100644
index 00000000..2335d15c
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/main/mdo/lifecycle.mdo
@@ -0,0 +1,129 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<model xmlns="http://modello.codehaus.org/MODELLO/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://modello.codehaus.org/MODELLO/1.0.0 http://modello.codehaus.org/xsd/modello-1.0.0.xsd"
+ xml.namespace="http://maven.apache.org/LIFECYCLE/${version}"
+ xml.schemaLocation="http://maven.apache.org/xsd/lifecycle-${version}.xsd">
+ <id>lifecycle-mappings</id>
+ <name>LifecycleMappings</name>
+ <description><![CDATA[
+ Configuration of custom lifecycle mappings for the plugin, as generally stored in
+ <code>META-INF/maven/lifecycle.xml</code> in a plugin's jar artifact.
+ ]]></description>
+ <defaults>
+ <default>
+ <key>package</key>
+ <value>org.apache.maven.plugin.lifecycle</value>
+ </default>
+ </defaults>
+ <classes>
+ <class rootElement="true" xml.tagName="lifecycles" xsd.compositor="sequence">
+ <name>LifecycleConfiguration</name>
+ <version>1.0.0</version>
+ <description><![CDATA[Root element of the <code>lifecycle.xml</code> file.]]></description>
+ <fields>
+ <field>
+ <name>lifecycles</name>
+ <version>1.0.0</version>
+ <association xml.itemsStyle="flat">
+ <type>Lifecycle</type>
+ <multiplicity>*</multiplicity>
+ </association>
+ </field>
+ </fields>
+ </class>
+ <class>
+ <name>Lifecycle</name>
+ <version>1.0.0</version>
+ <description><![CDATA[
+ A custom lifecycle mapping definition.
+ ]]></description>
+ <fields>
+ <field>
+ <name>id</name>
+ <required>true</required>
+ <version>1.0.0</version>
+ <type>String</type>
+ <description>The ID of this lifecycle, for identification in the mojo descriptor.</description>
+ </field>
+ <field>
+ <name>phases</name>
+ <version>1.0.0</version>
+ <description>The phase mappings for this lifecycle.</description>
+ <association>
+ <type>Phase</type>
+ <multiplicity>*</multiplicity>
+ </association>
+ </field>
+ </fields>
+ </class>
+ <class>
+ <name>Phase</name>
+ <version>1.0.0</version>
+ <description>A phase mapping definition.</description>
+ <fields>
+ <field>
+ <name>id</name>
+ <required>true</required>
+ <version>1.0.0</version>
+ <type>String</type>
+ <description>The ID of this phase, eg &lt;code&gt;generate-sources&lt;/code&gt;.</description>
+ </field>
+ <field>
+ <name>executions</name>
+ <version>1.0.0</version>
+ <description>The goals to execute within the phase.</description>
+ <association>
+ <type>Execution</type>
+ <multiplicity>*</multiplicity>
+ </association>
+ </field>
+ <field>
+ <name>configuration</name>
+ <version>1.0.0</version>
+ <type>DOM</type>
+ <description>Configuration to pass to all goals run in this phase.</description>
+ </field>
+ </fields>
+ </class>
+ <class>
+ <name>Execution</name>
+ <version>1.0.0</version>
+ <description>A set of goals to execute.</description>
+ <fields>
+ <field>
+ <name>configuration</name>
+ <version>1.0.0</version>
+ <type>DOM</type>
+ <description>Configuration to pass to the goals.</description>
+ </field>
+ <field>
+ <name>goals</name>
+ <version>1.0.0</version>
+ <description>The goals to execute.</description>
+ <association>
+ <type>String</type>
+ <multiplicity>*</multiplicity>
+ </association>
+ </field>
+ </fields>
+ </class>
+ </classes>
+</model>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/main/mdo/plugin.mdo b/framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/main/mdo/plugin.mdo
new file mode 100644
index 00000000..83bf3bf3
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/main/mdo/plugin.mdo
@@ -0,0 +1,525 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<model xmlns="http://modello.codehaus.org/MODELLO/1.4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://modello.codehaus.org/MODELLO/1.4.0 http://modello.codehaus.org/xsd/modello-1.4.0.xsd">
+ <id>plugin</id>
+ <name>PluginDescriptor</name>
+ <description><![CDATA[
+ Plugin descriptor, stored in <code>META-INF/maven/plugin.xml</code> in a plugin's jar artifact.
+ This descriptor is generally generated from plugin sources, using
+ <a href="/plugins/maven-plugin-plugin/">maven-plugin-plugin</a>.
+ <p><i>Notice:</i> this documentation is generated from a Modello model but the code executed is not generated
+ from this descriptor. Please report if you find anything wrong.</p>
+ ]]></description>
+ <defaults>
+ <default>
+ <key>package</key>
+ <value>plugin descriptor XML documentation (no java generation)</value><!-- intentionally non-buildable value -->
+ </default>
+ </defaults>
+ <classes>
+ <class rootElement="true" xml.tagName="plugin">
+ <name>PluginDescriptor</name>
+ <version>1.0.0</version>
+ <description><![CDATA[Root element of the <code>plugin.xml</code> file.]]></description>
+ <!-- see o.a.m.plugin.descriptor.PluginDescriptor -->
+ <fields>
+ <field>
+ <name>name</name>
+ <version>1.0.0</version>
+ <description>Name of the plugin.</description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>description</name>
+ <version>1.0.0</version>
+ <description>Description of the plugin.</description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>groupId</name>
+ <version>1.0.0</version>
+ <description>The group id of the plugin.</description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>artifactId</name>
+ <version>1.0.0</version>
+ <description>The artifact id of the plugin.</description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>version</name>
+ <version>1.0.0</version>
+ <description>The version of the plugin.</description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>goalPrefix</name>
+ <version>1.0.0</version>
+ <description></description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>isolatedRealm</name>
+ <version>1.0.0</version>
+ <description></description>
+ <type>boolean</type>
+ <defaultValue>false</defaultValue>
+ </field>
+ <field>
+ <name>inheritedByDefault</name>
+ <version>1.0.0</version>
+ <description></description>
+ <type>boolean</type>
+ <defaultValue>true</defaultValue>
+ </field>
+ <field xdoc.separator="blank">
+ <name>mojos</name>
+ <version>1.0.0</version>
+ <association>
+ <type>MojoDescriptor</type>
+ <multiplicity>*</multiplicity>
+ </association>
+ <description>Description of each Mojo provided by the plugin.</description>
+ </field>
+ <field xdoc.separator="blank">
+ <name>dependencies</name>
+ <version>1.0.0</version>
+ <association>
+ <type>Dependency</type>
+ <multiplicity>*</multiplicity>
+ </association>
+ <description>
+ A set of dependencies which the plugin requires in order to function. This enables the plugin to function
+ independently of its POM (or at least to declare the libraries it needs to run).
+ </description>
+ </field>
+ </fields>
+ </class>
+
+ <class>
+ <name>MojoDescriptor</name>
+ <version>1.0.0</version>
+ <description><![CDATA[
+ A Mojo description.
+ ]]></description>
+ <!-- see o.a.m.plugin.descriptor.MojoDescriptor -->
+ <fields>
+ <field>
+ <name>goal</name>
+ <required>true</required>
+ <version>1.0.0</version>
+ <type>String</type>
+ <description>
+ The goal name for the Mojo, that users will reference from the command line to execute the Mojo directly,
+ or inside a POM in order to provide Mojo-specific configuration.
+ </description>
+ </field>
+ <field>
+ <name>description</name>
+ <version>1.0.0</version>
+ <type>String</type>
+ <description>The description of this Mojo's functionality.</description>
+ </field>
+ <field>
+ <name>implementation</name>
+ <version>1.0.0</version>
+ <type>String</type>
+ <description>
+ The Mojo's fully-qualified class name (or script path in the case of non-Java Mojos).
+ </description>
+ </field>
+ <field>
+ <name>language</name>
+ <version>1.0.0</version>
+ <type>String</type>
+ <defaultValue>java</defaultValue>
+ <description>The implementation language for this Mojo (java, beanshell, etc.).</description>
+ </field>
+ <field>
+ <name>phase</name>
+ <version>1.0.0</version>
+ <type>String</type>
+ <description><![CDATA[
+ Defines a default phase to bind a mojo execution to if the user does not explicitly set a phase in the POM.
+ <i>Note:</i> This will not automagically make a mojo run when the plugin declaration is added
+ to the POM. It merely enables the user to omit the <code>&lt;phase&gt;</code> element from the
+ surrounding <code>&lt;execution&gt;</code> element.
+ ]]></description>
+ </field>
+ <field>
+ <name>executePhase</name>
+ <version>1.0.0</version>
+ <type>String</type>
+ <description>Reference the invocation phase of the Mojo.</description>
+ </field>
+ <field>
+ <name>executeGoal</name>
+ <version>1.0.0</version>
+ <type>String</type>
+ <description>Reference the invocation goal of the Mojo.</description>
+ </field>
+ <field>
+ <name>executeLifecycle</name>
+ <version>1.0.0</version>
+ <type>String</type>
+ <description></description>
+ </field>
+ <field>
+ <name>requiresDependencyResolution</name>
+ <version>1.0.0</version>
+ <type>String</type>
+ <defaultValue>runtime</defaultValue>
+ <description><![CDATA[
+ Flags this Mojo as requiring the dependencies in the specified class path to be resolved before it can
+ execute: <code>compile</code>, <code>runtime</code>, <code>test</code>,
+ <code>compile+runtime</code> (since Maven 3.0) or <code>runtime+system</code> (since Maven 3.0)
+ ]]></description>
+ </field>
+ <field>
+ <name>requiresDependencyCollection</name>
+ <version>1.0.0</version>
+ <type>String</type>
+ <description><![CDATA[
+ Flags this mojo as requiring information about the dependencies that would make up the specified class
+ path. As the name suggests, this is similar to requiresDependencyResolution and supports the same values.
+ The important difference is this will not resolve the files for the dependencies, i.e. the artifacts
+ associated with a Maven project can lack a file. As such, this annotation is meant for mojos that only
+ want to analyze the set of transitive dependencies, in particular during early lifecycle phases where
+ full dependency resolution might fail due to projects which haven't been built yet.
+ ]]></description>
+ </field>
+ <field>
+ <name>requiresDirectInvocation</name>
+ <version>1.0.0</version>
+ <type>boolean</type>
+ <description>Flags this Mojo to be invoked directly only.</description>
+ <defaultValue>false</defaultValue>
+ </field>
+ <field>
+ <name>requiresProject</name>
+ <version>1.0.0</version>
+ <type>boolean</type>
+ <description>Flags this Mojo to require running inside of a project.</description>
+ <defaultValue>true</defaultValue>
+ </field>
+ <field>
+ <name>requiresReports</name>
+ <version>1.0.0</version>
+ <type>boolean</type>
+ <description>Flags this Mojo to require running inside of a reports context. Unsupported since Maven 3.0.</description>
+ <defaultValue>false</defaultValue>
+ </field>
+ <field>
+ <name>requiresOnline</name>
+ <version>1.0.0</version>
+ <type>boolean</type>
+ <description>Flags this Mojo to require online mode for its operation.</description>
+ <defaultValue>false</defaultValue>
+ </field>
+ <field>
+ <name>aggregator</name>
+ <version>1.0.0</version>
+ <type>boolean</type>
+ <description>
+ Flags this Mojo to run it in a multi module way, i.e. aggregate the build with the set of projects
+ listed as modules.
+ </description>
+ <defaultValue>false</defaultValue>
+ </field>
+ <field>
+ <name>inheritedByDefault</name>
+ <version>1.0.0</version>
+ <type>boolean</type>
+ <description>Specify that the Mojo is inherited.</description>
+ <defaultValue>true</defaultValue>
+ </field>
+ <field>
+ <name>threadSafe</name>
+ <version>1.0.0</version>
+ <type>boolean</type>
+ <description>
+ Marks this mojo as being thread-safe, i.e. the mojo safely supports concurrent execution during parallel
+ builds. Mojos without this annotation will make Maven output a warning when used during a parallel build
+ session. Since Maven 3.0.
+ </description>
+ <defaultValue>false</defaultValue>
+ </field>
+ <field>
+ <name>instantiationStrategy</name>
+ <version>1.0.0</version>
+ <type>String</type>
+ <defaultValue>per-lookup</defaultValue>
+ <description>Specify the instantiation strategy.</description>
+ </field>
+ <field>
+ <name>executionStrategy</name>
+ <version>1.0.0</version>
+ <type>String</type>
+ <description><![CDATA[
+ Specify the execution strategy: <code>once-per-session</code>, <code>always</code>.
+ ]]></description>
+ <defaultValue>once-per-session</defaultValue>
+ </field>
+ <field>
+ <name>since</name>
+ <version>1.0.0</version>
+ <type>String</type>
+ <description>Specify the version when the Mojo was added to the API. Similar to Javadoc since.</description>
+ </field>
+ <field>
+ <name>deprecated</name>
+ <version>1.0.0</version>
+ <type>String</type>
+ <description>
+ Specify the version when the Mojo was deprecated to the API. Similar to Javadoc deprecated. This will
+ trigger a warning when a user tries to configure a parameter marked as deprecated.
+ </description>
+ </field>
+ <field>
+ <name>configurator</name>
+ <version>1.0.0</version>
+ <type>String</type>
+ <description>
+ The configurator type to use when injecting parameter values into this Mojo. The value is normally deduced
+ from the Mojo's implementation language, but can be specified to allow a custom ComponentConfigurator
+ implementation to be used.
+ </description>
+ </field>
+ <field>
+ <name>composer</name>
+ <version>1.0.0</version>
+ <type>String</type>
+ <description></description>
+ </field>
+ <field xdoc.separator="blank">
+ <name>parameters</name>
+ <version>1.0.0</version>
+ <description></description>
+ <association>
+ <type>Parameter</type>
+ <multiplicity>*</multiplicity>
+ </association>
+ </field>
+ <field>
+ <name>configuration</name>
+ <version>1.0.0</version>
+ <description></description>
+ <association xml.tagName="paramName">
+ <type>Configuration</type>
+ <multiplicity>*</multiplicity>
+ </association>
+ </field>
+ <field xdoc.separator="blank">
+ <name>requirements</name>
+ <version>1.0.0</version>
+ <description></description>
+ <association>
+ <type>Requirement</type>
+ <multiplicity>*</multiplicity>
+ </association>
+ </field>
+ </fields>
+ </class>
+
+ <class>
+ <name>Parameter</name>
+ <version>1.0.0</version>
+ <description>A phase mapping definition.</description>
+ <!-- see o.a.m.plugin.descriptor.Parameter -->
+ <fields>
+ <field>
+ <name>name</name>
+ <version>1.0.0</version>
+ <type>String</type>
+ <required>true</required>
+ <description>
+ The name of the parameter, to be used while configuring this parameter from the Mojo's declared defaults
+ or from the POM.
+ </description>
+ </field>
+ <field>
+ <name>alias</name>
+ <version>1.0.0</version>
+ <type>String</type>
+ <description>
+ Specifies an alias which can be used to configure this parameter from the POM.
+ This is primarily useful to improve user-friendliness, where Mojo field names are not intuitive to the
+ user or are otherwise not conducive to configuration via the POM.
+ </description>
+ </field>
+ <field>
+ <name>type</name>
+ <version>1.0.0</version>
+ <type>String</type>
+ <required>true</required>
+ <description>
+ The Java type for this parameter. This is used to validate the result of any expressions used to calculate
+ the value which should be injected into the Mojo for this parameter.
+ </description>
+ </field>
+ <field>
+ <name>required</name>
+ <version>1.0.0</version>
+ <type>boolean</type>
+ <description>
+ Whether this parameter is required for the Mojo to function. This is used to validate the configuration
+ for a Mojo before it is injected, and before the Mojo is executed from some half-state.
+ </description>
+ </field>
+ <field>
+ <name>editable</name>
+ <version>1.0.0</version>
+ <type>boolean</type>
+ <defaultValue>true</defaultValue>
+ <description><![CDATA[
+ Specifies that this parameter can be configured directly by the user (as in the case of POM-specified
+ configuration). This is useful when you want to force the user to use common POM elements rather than
+ plugin configurations, as in the case where you want to use the artifact's final name as a parameter. In
+ this case, you want the user to modify <code>&lt;build&gt;&lt;finalName/&gt;&lt;/build&gt;</code> rather
+ than specifying a value for finalName directly in the plugin configuration section. It is also useful to
+ ensure that - for example - a List-typed parameter which expects items of type Artifact doesn't get a List
+ full of Strings.
+ ]]></description>
+ </field>
+ <field>
+ <name>implementation</name>
+ <version>1.0.0</version>
+ <type>String</type>
+ <description></description>
+ </field>
+ <field>
+ <name>description</name>
+ <version>1.0.0</version>
+ <type>String</type>
+ <description>The description of this parameter's use inside the Mojo.</description>
+ </field>
+ <field>
+ <name>since</name>
+ <version>1.0.0</version>
+ <type>String</type>
+ <description>Specify the version when the parameter was added to the API. Similar to Javadoc since.</description>
+ </field>
+ <field>
+ <name>deprecated</name>
+ <version>1.0.0</version>
+ <type>String</type>
+ <description>
+ Specify the version when the parameter was deprecated to the API. Similar to Javadoc deprecated.
+ This will trigger a warning when a user tries to configure a parameter marked as deprecated.
+ </description>
+ </field>
+ </fields>
+ </class>
+
+ <class>
+ <name>Configuration</name>
+ <version>1.0.0</version>
+ <description>A parameter configuration.</description>
+ <!-- see o.a.m.plugin.descriptor.Parameter -->
+ <fields>
+ <field xml.content="true">
+ <name>expression</name>
+ <required>true</required>
+ <version>1.0.0</version>
+ <type>String</type>
+ <description>Parameter expression, to let user override default value with a system property, pom property or settings property.</description>
+ </field>
+ <field xml.attribute="true" xml.tagName="implementation">
+ <name>implementation</name>
+ <version>1.0.0</version>
+ <type>String</type>
+ <description></description>
+ </field>
+ <field xml.attribute="true" xml.tagName="default-value">
+ <name>defaultValue</name>
+ <version>1.0.0</version>
+ <type>String</type>
+ <description>The default value, as an expression that will be evaluated at injection or run-time.</description>
+ </field>
+ </fields>
+ </class>
+
+ <class>
+ <name>Requirement</name>
+ <version>1.0.0</version>
+ <description>Describes a component requirement.</description>
+ <!-- see o.a.m.plugin.descriptor.Requirement -->
+ <fields>
+ <field>
+ <name>role</name>
+ <required>true</required>
+ <version>1.0.0</version>
+ <type>String</type>
+ <description></description>
+ </field>
+ <field xml.tagName="role-hint">
+ <name>roleHint</name>
+ <version>1.0.0</version>
+ <type>String</type>
+ <description></description>
+ </field>
+ <field xml.tagName="field-name">
+ <name>fieldName</name>
+ <required>true</required>
+ <version>1.0.0</version>
+ <type>String</type>
+ <description>The field name which has this requirement.</description>
+ </field>
+ </fields>
+ </class>
+
+ <class>
+ <name>Dependency</name>
+ <version>1.0.0</version>
+ <description>Definition of a dependency, needed by the plugin at runtime.</description>
+ <fields>
+ <field>
+ <name>groupId</name>
+ <required>true</required>
+ <version>1.0.0</version>
+ <type>String</type>
+ <description>The group id of the dependency.</description>
+ </field>
+ <field>
+ <name>artifactId</name>
+ <required>true</required>
+ <version>1.0.0</version>
+ <type>String</type>
+ <description>The artifact id of the dependency.</description>
+ </field>
+ <field>
+ <name>version</name>
+ <version>1.0.0</version>
+ <type>String</type>
+ <description>The version of the dependency.</description>
+ </field>
+ <field>
+ <name>type</name>
+ <version>1.0.0</version>
+ <type>String</type>
+ <defaultValue>jar</defaultValue>
+ <description>The type of dependency.</description>
+ </field>
+ </fields>
+ </class>
+ </classes>
+</model>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/site/apt/index.apt b/framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/site/apt/index.apt
new file mode 100644
index 00000000..6eb59556
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/site/apt/index.apt
@@ -0,0 +1,39 @@
+~~ Licensed to the Apache Software Foundation (ASF) under one
+~~ or more contributor license agreements. See the NOTICE file
+~~ distributed with this work for additional information
+~~ regarding copyright ownership. The ASF licenses this file
+~~ to you under the Apache License, Version 2.0 (the
+~~ "License"); you may not use this file except in compliance
+~~ with the License. You may obtain a copy of the License at
+~~
+~~ http://www.apache.org/licenses/LICENSE-2.0
+~~
+~~ Unless required by applicable law or agreed to in writing,
+~~ software distributed under the License is distributed on an
+~~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+~~ KIND, either express or implied. See the License for the
+~~ specific language governing permissions and limitations
+~~ under the License.
+
+ -----
+ Introduction
+ -----
+ Hervé Boutemy
+ -----
+ 2012-06-02
+ -----
+
+Maven Plugin API
+
+ The API for plugins - composed of goals implemented by Mojos - development.
+
+ A plugin is described in a {{{./plugin.html}<<<META-INF/maven/plugin.xml>>> plugin descriptor}},
+ generally generated from plugin sources using {{{/plugin-tools/maven-plugin-plugin/}maven-plugin-plugin}}.
+
+* See Also
+
+ * {{{/developers/mojo-api-specification.html}Mojo API Specification}}
+
+ * {{{/plugin-tools/}plugin-tools}}
+
+ * {{{/plugin-testing/}plugin-testing}}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/site/site.xml b/framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/site/site.xml
new file mode 100644
index 00000000..9594af1b
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/site/site.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+
+<project xmlns="http://maven.apache.org/DECORATION/1.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/DECORATION/1.0.0 http://maven.apache.org/xsd/decoration-1.0.0.xsd">
+ <body>
+ <menu name="Overview">
+ <item name="Introduction" href="index.html"/>
+ <item name="JavaDocs" href="apidocs/index.html"/>
+ <item name="Source Xref" href="xref/index.html"/>
+ <!--item name="FAQ" href="faq.html"/-->
+ </menu>
+ <menu name="Reference">
+ <item name="lifecycle.xml" href="lifecycle-mappings.html"/>
+ <item name="plugin.xml" href="plugin.html"/>
+ </menu>
+
+ <menu ref="parent"/>
+ <menu ref="reports"/>
+ </body>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/test/java/org/apache/maven/plugin/descriptor/PluginDescriptorBuilderTest.java b/framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/test/java/org/apache/maven/plugin/descriptor/PluginDescriptorBuilderTest.java
new file mode 100644
index 00000000..799e3af0
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/test/java/org/apache/maven/plugin/descriptor/PluginDescriptorBuilderTest.java
@@ -0,0 +1,133 @@
+package org.apache.maven.plugin.descriptor;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.IOException;
+import java.io.Reader;
+
+import org.codehaus.plexus.component.repository.ComponentDependency;
+import org.codehaus.plexus.component.repository.ComponentRequirement;
+import org.codehaus.plexus.configuration.PlexusConfiguration;
+import org.codehaus.plexus.configuration.PlexusConfigurationException;
+import org.codehaus.plexus.util.ReaderFactory;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests {@link PluginDescriptorBuilder}.
+ *
+ * @author Benjamin Bentmann
+ */
+public class PluginDescriptorBuilderTest
+ extends TestCase
+{
+
+ private PluginDescriptor build( String resource )
+ throws IOException, PlexusConfigurationException
+ {
+ Reader reader = ReaderFactory.newXmlReader( getClass().getResourceAsStream( resource ) );
+
+ return new PluginDescriptorBuilder().build( reader );
+ }
+
+ public void testBuildReader()
+ throws Exception
+ {
+ PluginDescriptor pd = build( "/plugin.xml" );
+
+ assertEquals( "org.apache.maven.plugins", pd.getGroupId() );
+ assertEquals( "maven-jar-plugin", pd.getArtifactId() );
+ assertEquals( "2.3-SNAPSHOT", pd.getVersion() );
+ assertEquals( "jar", pd.getGoalPrefix() );
+ assertEquals( "plugin-description", pd.getDescription() );
+ assertEquals( false, pd.isIsolatedRealm() );
+ assertEquals( true, pd.isInheritedByDefault() );
+ assertEquals( 2, pd.getMojos().size() );
+ assertEquals( 1, pd.getDependencies().size() );
+
+ MojoDescriptor md = pd.getMojos().get( 0 );
+
+ assertEquals( "jar", md.getGoal() );
+ assertEquals( "mojo-description", md.getDescription() );
+ assertEquals( "runtime", md.getDependencyResolutionRequired() );
+ assertEquals( "test", md.getDependencyCollectionRequired() );
+ assertEquals( false, md.isAggregator() );
+ assertEquals( false, md.isDirectInvocationOnly() );
+ assertEquals( true, md.isInheritedByDefault() );
+ assertEquals( false, md.isOnlineRequired() );
+ assertEquals( true, md.isProjectRequired() );
+ assertEquals( false, md.isThreadSafe() );
+ assertEquals( "package", md.getPhase() );
+ assertEquals( "org.apache.maven.plugin.jar.JarMojo", md.getImplementation() );
+ assertEquals( "antrun", md.getComponentConfigurator() );
+ assertEquals( "java", md.getLanguage() );
+ assertEquals( "per-lookup", md.getInstantiationStrategy() );
+ assertEquals( "some-goal", md.getExecuteGoal() );
+ assertEquals( "generate-sources", md.getExecutePhase() );
+ assertEquals( "cobertura", md.getExecuteLifecycle() );
+ assertEquals( "2.2", md.getSince() );
+ assertEquals( "deprecated-mojo", md.getDeprecated() );
+ assertEquals( 1, md.getRequirements().size() );
+ assertEquals( 1, md.getParameters().size() );
+
+ assertNotNull( md.getMojoConfiguration() );
+ assertEquals( 1, md.getMojoConfiguration().getChildCount() );
+
+ PlexusConfiguration pc = md.getMojoConfiguration().getChild( 0 );
+
+ assertEquals( "${jar.finalName}", pc.getValue() );
+ assertEquals( "${project.build.finalName}", pc.getAttribute( "default-value" ) );
+ assertEquals( "java.lang.String", pc.getAttribute( "implementation" ) );
+
+ Parameter mp = md.getParameters().get( 0 );
+
+ assertEquals( "finalName", mp.getName() );
+ assertEquals( "jarName", mp.getAlias() );
+ assertEquals( "java.lang.String", mp.getType() );
+ assertEquals( "java.lang.String", mp.getImplementation() );
+ assertEquals( true, mp.isEditable() );
+ assertEquals( false, mp.isRequired() );
+ assertEquals( "parameter-description", mp.getDescription() );
+ assertEquals( "deprecated-parameter", mp.getDeprecated() );
+ assertEquals( "${jar.finalName}", mp.getExpression() );
+ assertEquals( "${project.build.finalName}", mp.getDefaultValue() );
+
+ ComponentRequirement cr = md.getRequirements().get( 0 );
+
+ assertEquals( "org.codehaus.plexus.archiver.Archiver", cr.getRole() );
+ assertEquals( "jar", cr.getRoleHint() );
+ assertEquals( "jarArchiver", cr.getFieldName() );
+
+ ComponentDependency cd = pd.getDependencies().get( 0 );
+
+ assertEquals( "org.apache.maven", cd.getGroupId() );
+ assertEquals( "maven-plugin-api", cd.getArtifactId() );
+ assertEquals( "2.0.6", cd.getVersion() );
+ assertEquals( "jar", cd.getType() );
+
+ md = pd.getMojos().get( 1 );
+
+ assertEquals( "war", md.getGoal() );
+ assertEquals( null, md.getDependencyResolutionRequired() );
+ assertEquals( null, md.getDependencyCollectionRequired() );
+ assertEquals( true, md.isThreadSafe() );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/test/java/org/apache/maven/plugin/lifecycle/LifecycleXpp3ReaderTest.java b/framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/test/java/org/apache/maven/plugin/lifecycle/LifecycleXpp3ReaderTest.java
new file mode 100644
index 00000000..18c02ecc
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/test/java/org/apache/maven/plugin/lifecycle/LifecycleXpp3ReaderTest.java
@@ -0,0 +1,55 @@
+package org.apache.maven.plugin.lifecycle;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.IOException;
+
+import junit.framework.TestCase;
+
+import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
+
+/**
+ * Test the lifecycle reader.
+ *
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ */
+public class LifecycleXpp3ReaderTest
+ extends TestCase
+{
+ public void testLifecycleReader()
+ throws IOException, XmlPullParserException
+ {/*
+ LifecycleMappingsXpp3Reader reader = new LifecycleMappingsXpp3Reader();
+ LifecycleConfiguration config = reader.read( new InputStreamReader( getClass().getResourceAsStream( "/lifecycle.xml" ) ) );
+ assertEquals( "check number of lifecycles", 1, config.getLifecycles().size() );
+ Lifecycle l = (Lifecycle) config.getLifecycles().iterator().next();
+ assertEquals( "check id", "clover", l.getId() );
+ assertEquals( "check number of phases", 1, l.getPhases().size() );
+ Phase p = (Phase) l.getPhases().iterator().next();
+ assertEquals( "check id", "generate-sources", p.getId() );
+ assertEquals( "check number of executions", 1, p.getExecutions().size() );
+ Execution e = (Execution) p.getExecutions().iterator().next();
+ assertEquals( "check configuration", "true", ((Xpp3Dom) e.getConfiguration()).getChild( "debug" ).getValue() );
+ assertEquals( "check number of goals", 1, e.getGoals().size() );
+ String g = (String) e.getGoals().iterator().next();
+ assertEquals( "check goal", "clover:compiler", g );
+ */
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/test/resources/lifecycle.xml b/framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/test/resources/lifecycle.xml
new file mode 100644
index 00000000..ebec5892
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/test/resources/lifecycle.xml
@@ -0,0 +1,39 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<lifecycles>
+ <lifecycle>
+ <id>clover</id>
+ <phases>
+ <phase>
+ <id>generate-sources</id>
+ <executions>
+ <execution>
+ <configuration>
+ <debug>true</debug>
+ </configuration>
+ <goals>
+ <goal>clover:compiler</goal>
+ </goals>
+ </execution>
+ </executions>
+ </phase>
+ </phases>
+ </lifecycle>
+</lifecycles>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/test/resources/plugin.xml b/framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/test/resources/plugin.xml
new file mode 100644
index 00000000..6b972113
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-plugin-api/src/test/resources/plugin.xml
@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<plugin>
+ <description>plugin-description</description>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <version>2.3-SNAPSHOT</version>
+ <goalPrefix>jar</goalPrefix>
+ <isolatedRealm>false</isolatedRealm>
+ <inheritedByDefault>true</inheritedByDefault>
+ <mojos>
+ <mojo>
+ <goal>jar</goal>
+ <description>mojo-description</description>
+ <requiresDependencyResolution>runtime</requiresDependencyResolution>
+ <requiresDependencyCollection>test</requiresDependencyCollection>
+ <requiresDirectInvocation>false</requiresDirectInvocation>
+ <requiresProject>true</requiresProject>
+ <requiresReports>false</requiresReports>
+ <aggregator>false</aggregator>
+ <requiresOnline>false</requiresOnline>
+ <inheritedByDefault>true</inheritedByDefault>
+ <phase>package</phase>
+ <implementation>org.apache.maven.plugin.jar.JarMojo</implementation>
+ <language>java</language>
+ <instantiationStrategy>per-lookup</instantiationStrategy>
+ <executionStrategy>once-per-session</executionStrategy>
+ <deprecated>deprecated-mojo</deprecated>
+ <since>2.2</since>
+ <executePhase>generate-sources</executePhase>
+ <executeGoal>some-goal</executeGoal>
+ <executeLifecycle>cobertura</executeLifecycle>
+ <configurator>antrun</configurator>
+ <parameters>
+ <parameter>
+ <name>finalName</name>
+ <alias>jarName</alias>
+ <type>java.lang.String</type>
+ <implementation>java.lang.String</implementation>
+ <required>false</required>
+ <editable>true</editable>
+ <description>parameter-description</description>
+ <deprecated>deprecated-parameter</deprecated>
+ </parameter>
+ </parameters>
+ <configuration>
+ <finalName implementation="java.lang.String" default-value="${project.build.finalName}">${jar.finalName}</finalName>
+ </configuration>
+ <requirements>
+ <requirement>
+ <role>org.codehaus.plexus.archiver.Archiver</role>
+ <role-hint>jar</role-hint>
+ <field-name>jarArchiver</field-name>
+ </requirement>
+ </requirements>
+ </mojo>
+ <mojo>
+ <goal>war</goal>
+ <threadSafe>true</threadSafe>
+ </mojo>
+ </mojos>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-plugin-api</artifactId>
+ <type>jar</type>
+ <version>2.0.6</version>
+ </dependency>
+ </dependencies>
+</plugin>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-repository-metadata/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-repository-metadata/pom.xml
new file mode 100644
index 00000000..e9181539
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-repository-metadata/pom.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven</artifactId>
+ <version>3.3.3</version>
+ </parent>
+
+ <artifactId>maven-repository-metadata</artifactId>
+
+ <name>Maven Repository Metadata Model</name>
+ <description>Per-directory local and remote repository metadata.</description>
+
+ <scm><!-- remove when git scm url format can accept artifact-id at the end, as automatically inherited -->
+ <connection>scm:git:https://git-wip-us.apache.org/repos/asf/maven.git</connection>
+ <developerConnection>scm:git:https://git-wip-us.apache.org/repos/asf/maven.git</developerConnection>
+ <tag>maven-3.3.3</tag>
+ </scm>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-utils</artifactId>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.modello</groupId>
+ <artifactId>modello-maven-plugin</artifactId>
+ <configuration>
+ <version>1.1.0</version>
+ <models>
+ <model>src/main/mdo/metadata.mdo</model>
+ </models>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-repository-metadata/src/main/mdo/metadata.mdo b/framework/src/maven/apache-maven-3.3.3/maven-repository-metadata/src/main/mdo/metadata.mdo
new file mode 100644
index 00000000..97920027
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-repository-metadata/src/main/mdo/metadata.mdo
@@ -0,0 +1,371 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<model xmlns="http://modello.codehaus.org/MODELLO/1.4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://modello.codehaus.org/MODELLO/1.4.0 http://modello.codehaus.org/xsd/modello-1.4.0.xsd"
+ xsd.namespace="http://maven.apache.org/METADATA/${version}"
+ xml.schemaLocation="http://maven.apache.org/xsd/metadata-${version}.xsd">
+ <id>repository-metadata</id>
+ <name>Metadata</name>
+ <description><![CDATA[
+ <p>Per-directory repository metadata, for directories representing un-versioned artifact, snapshot artifact
+ or a group containing Maven plugins.</p>
+ <p>Notice that most metadata content has a meaning when the directory represents
+ an artifact (<code>groupId</code>, <code>artifactId</code>, <code>versioning</code>), but
+ <code>plugins</code> is used when the directory represents a group.</p>]]>
+ </description>
+ <defaults>
+ <default>
+ <key>package</key>
+ <value>org.apache.maven.artifact.repository.metadata</value>
+ </default>
+ </defaults>
+ <classes>
+ <class rootElement="true" java.clone="deep">
+ <name>Metadata</name>
+ <version>1.0.0+</version>
+ <fields>
+ <field xml.attribute="true">
+ <name>modelVersion</name>
+ <version>1.1.0+</version>
+ <type>String</type>
+ <description>The version of the underlying metadata model.</description>
+ </field>
+ <field>
+ <name>groupId</name>
+ <version>1.0.0+</version>
+ <type>String</type>
+ <description>The groupId that this directory represents, if any.</description>
+ </field>
+ <field>
+ <name>artifactId</name>
+ <version>1.0.0+</version>
+ <type>String</type>
+ <description>The artifactId that this directory represents, if any.</description>
+ </field>
+ <field>
+ <name>version</name>
+ <version>1.0.0+</version>
+ <type>String</type>
+ <description>The version that this directory represents, if any. It is used for artifact snapshots only.</description>
+ </field>
+ <field>
+ <name>versioning</name>
+ <version>1.0.0+</version>
+ <association>
+ <type>Versioning</type>
+ </association>
+ <description>Versioning information for the artifact.</description>
+ </field>
+ <field xdoc.separator="blank">
+ <name>plugins</name>
+ <version>1.0.0+</version>
+ <description>The set of plugin mappings for the group represented by this directory</description>
+ <association>
+ <type>Plugin</type>
+ <multiplicity>*</multiplicity>
+ </association>
+ </field>
+ </fields>
+ <codeSegments>
+ <codeSegment>
+ <version>1.0.0+</version>
+ <code><![CDATA[
+ public boolean merge( Metadata sourceMetadata )
+ {
+ boolean changed = false;
+
+ for ( Plugin plugin : sourceMetadata.getPlugins() )
+ {
+ boolean found = false;
+
+ for ( Plugin preExisting : getPlugins() )
+ {
+ if ( preExisting.getPrefix().equals( plugin.getPrefix() ) )
+ {
+ found = true;
+ break;
+ }
+ }
+
+ if ( !found )
+ {
+ Plugin mappedPlugin = new Plugin();
+
+ mappedPlugin.setArtifactId( plugin.getArtifactId() );
+
+ mappedPlugin.setPrefix( plugin.getPrefix() );
+
+ mappedPlugin.setName( plugin.getName() );
+
+ addPlugin( mappedPlugin );
+
+ changed = true;
+ }
+ }
+
+ Versioning versioning = sourceMetadata.getVersioning();
+ if ( versioning != null )
+ {
+ Versioning v = getVersioning();
+ if ( v == null )
+ {
+ v = new Versioning();
+ setVersioning( v );
+ changed = true;
+ }
+
+ for ( String version : versioning.getVersions() )
+ {
+ if ( !v.getVersions().contains( version ) )
+ {
+ changed = true;
+ v.getVersions().add( version );
+ }
+ }
+
+ if ( "null".equals( versioning.getLastUpdated() ) )
+ {
+ versioning.setLastUpdated( null );
+ }
+
+ if ( "null".equals( v.getLastUpdated() ) )
+ {
+ v.setLastUpdated( null );
+ }
+
+ if ( versioning.getLastUpdated() == null || versioning.getLastUpdated().length() == 0 )
+ {
+ // this should only be for historical reasons - we assume local is newer
+ versioning.setLastUpdated( v.getLastUpdated() );
+ }
+
+ if ( v.getLastUpdated() == null || v.getLastUpdated().length() == 0
+ || versioning.getLastUpdated().compareTo( v.getLastUpdated() ) >= 0 )
+ {
+ changed = true;
+ v.setLastUpdated( versioning.getLastUpdated() );
+
+ if ( versioning.getRelease() != null )
+ {
+ changed = true;
+ v.setRelease( versioning.getRelease() );
+ }
+ if ( versioning.getLatest() != null )
+ {
+ changed = true;
+ v.setLatest( versioning.getLatest() );
+ }
+
+ Snapshot s = v.getSnapshot();
+ Snapshot snapshot = versioning.getSnapshot();
+ if ( snapshot != null )
+ {
+ if ( s == null )
+ {
+ s = new Snapshot();
+ v.setSnapshot( s );
+ changed = true;
+ }
+
+ // overwrite
+ if ( s.getTimestamp() == null ? snapshot.getTimestamp() != null
+ : !s.getTimestamp().equals( snapshot.getTimestamp() ) )
+ {
+ s.setTimestamp( snapshot.getTimestamp() );
+ changed = true;
+ }
+ if ( s.getBuildNumber() != snapshot.getBuildNumber() )
+ {
+ s.setBuildNumber( snapshot.getBuildNumber() );
+ changed = true;
+ }
+ if ( s.isLocalCopy() != snapshot.isLocalCopy() )
+ {
+ s.setLocalCopy( snapshot.isLocalCopy() );
+ changed = true;
+ }
+ }
+ }
+ }
+ return changed;
+ }
+ ]]></code>
+ </codeSegment>
+ </codeSegments>
+ </class>
+ <class java.clone="deep">
+ <name>Versioning</name>
+ <version>1.0.0+</version>
+ <description>Versioning information for an artifact (un-versioned or snapshot)</description>
+ <fields>
+ <field>
+ <name>latest</name>
+ <version>1.0.0+</version>
+ <type>String</type>
+ <description>What the latest version in the directory is, including snapshots</description>
+ </field>
+ <field>
+ <name>release</name>
+ <version>1.0.0+</version>
+ <type>String</type>
+ <description>What the latest version in the directory is, of the releases only</description>
+ </field>
+ <field>
+ <name>snapshot</name>
+ <version>1.0.0+</version>
+ <association>
+ <type>Snapshot</type>
+ </association>
+ <description>The current snapshot data in use for this version (artifact snapshots only)</description>
+ </field>
+ <field>
+ <name>versions</name>
+ <version>1.0.0+</version>
+ <description>Versions available of the artifact (both releases and snapshots)</description>
+ <association>
+ <type>String</type>
+ <multiplicity>*</multiplicity>
+ </association>
+ </field>
+ <field>
+ <name>lastUpdated</name>
+ <version>1.0.0+</version>
+ <type>String</type>
+ <description>When the metadata was last updated</description>
+ </field>
+ <field>
+ <name>snapshotVersions</name>
+ <version>1.1.0+</version>
+ <description>Information for each sub-artifact available in this artifact snapshot.</description>
+ <association>
+ <type>SnapshotVersion</type>
+ <multiplicity>*</multiplicity>
+ </association>
+ </field>
+ </fields>
+ <codeSegments>
+ <codeSegment>
+ <version>1.0.0+</version>
+ <code><![CDATA[
+ public void updateTimestamp()
+ {
+ setLastUpdatedTimestamp( new java.util.Date() );
+ }
+
+ public void setLastUpdatedTimestamp( java.util.Date date )
+ {
+ java.util.TimeZone timezone = java.util.TimeZone.getTimeZone( "UTC" );
+ java.text.DateFormat fmt = new java.text.SimpleDateFormat( "yyyyMMddHHmmss" );
+ fmt.setTimeZone( timezone );
+ setLastUpdated( fmt.format( date ) );
+ }
+ ]]></code>
+ </codeSegment>
+ </codeSegments>
+ </class>
+ <class java.clone="deep">
+ <name>Snapshot</name>
+ <version>1.0.0+</version>
+ <description>Snapshot data for the current artifact version</description>
+ <fields>
+ <field>
+ <name>timestamp</name>
+ <version>1.0.0+</version>
+ <description>The time it was deployed</description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>buildNumber</name>
+ <version>1.0.0+</version>
+ <description>The incremental build number</description>
+ <type>int</type>
+ </field>
+ <field>
+ <name>localCopy</name>
+ <version>1.0.0+</version>
+ <description>Whether to use a local copy instead (with filename that includes the base version)</description>
+ <type>boolean</type>
+ <defaultValue>false</defaultValue>
+ </field>
+ </fields>
+ </class>
+ <class java.clone="deep">
+ <name>SnapshotVersion</name>
+ <version>1.1.0+</version>
+ <description>Versioning information for a sub-artifact of the current snapshot artifact.</description>
+ <fields>
+ <field>
+ <name>classifier</name>
+ <version>1.1.0+</version>
+ <type>String</type>
+ <description>The classifier of the sub-artifact.</description>
+ <defaultValue></defaultValue>
+ </field>
+ <field>
+ <name>extension</name>
+ <version>1.1.0+</version>
+ <type>String</type>
+ <description>The file extension of thesub-artifact.</description>
+ </field>
+ <field xml.tagName="value">
+ <name>version</name>
+ <version>1.1.0+</version>
+ <type>String</type>
+ <description>The resolved snapshot version of the sub-artifact.</description>
+ </field>
+ <field>
+ <name>updated</name>
+ <version>1.1.0+</version>
+ <type>String</type>
+ <description>The timestamp when this version information was last updated. The timestamp is expressed using UTC in the format yyyyMMddHHmmss.</description>
+ </field>
+ </fields>
+ </class>
+ <class java.clone="deep">
+ <name>Plugin</name>
+ <version>1.0.0+</version>
+ <description>Mapping information for a single plugin within this group</description>
+ <comment>NOTE: plugin version is _NOT_ included here, since it is resolved using a separate algorithm in plugins' artifact.</comment>
+ <fields>
+ <field>
+ <name>name</name>
+ <type>String</type>
+ <required>true</required>
+ <version>1.0.0+</version>
+ <description>Display name for the plugin.</description>
+ </field>
+ <field>
+ <name>prefix</name>
+ <type>String</type>
+ <required>true</required>
+ <version>1.0.0+</version>
+ <description>The plugin invocation prefix (i.e. eclipse for eclipse:eclipse)</description>
+ </field>
+ <field>
+ <name>artifactId</name>
+ <type>String</type>
+ <required>true</required>
+ <version>1.0.0+</version>
+ <description>The plugin artifactId</description>
+ </field>
+ </fields>
+ </class>
+ </classes>
+</model>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-repository-metadata/src/site/apt/index.apt b/framework/src/maven/apache-maven-3.3.3/maven-repository-metadata/src/site/apt/index.apt
new file mode 100644
index 00000000..194fc0df
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-repository-metadata/src/site/apt/index.apt
@@ -0,0 +1,52 @@
+~~ Licensed to the Apache Software Foundation (ASF) under one
+~~ or more contributor license agreements. See the NOTICE file
+~~ distributed with this work for additional information
+~~ regarding copyright ownership. The ASF licenses this file
+~~ to you under the Apache License, Version 2.0 (the
+~~ "License"); you may not use this file except in compliance
+~~ with the License. You may obtain a copy of the License at
+~~
+~~ http://www.apache.org/licenses/LICENSE-2.0
+~~
+~~ Unless required by applicable law or agreed to in writing,
+~~ software distributed under the License is distributed on an
+~~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+~~ KIND, either express or implied. See the License for the
+~~ specific language governing permissions and limitations
+~~ under the License.
+
+ -----
+ Introduction
+ -----
+ Hervé Boutemy
+ -----
+ 2009-04-26
+ -----
+
+Maven Repository Metadata Model
+
+ This is strictly the model for Maven Repository Metadata, so really just plain objects.
+
+ Maven Repository Metadata is available in directories representing:
+
+ [[1]] an un-versioned artifact: it gives informations about available versions of the artifact,
+
+ [[2]] a snapshot artifact: it gives precise information on the snapshot,
+
+ [[3]] a group containing Maven plugins artifacts: it gives informations on plugins available in this group.
+
+ []
+
+ The metadata file name is:
+
+ * <<<maven-metadata.xml>>> in a remote repository,
+
+ * <<<maven-metadata-\<repo-id>.xml>>> in a local repository, for metatada from a repository with <<<repo-id>>> identifier.
+
+ []
+
+ The following are generated from this model:
+
+ * {{{./apidocs/index.html}Java sources}} with Reader and Writers for the Xpp3 XML parser, to read and write <<<maven-metadata(-*).xml>>> files
+
+ * A {{{./repository-metadata.html}Descriptor Reference}}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-repository-metadata/src/site/site.xml b/framework/src/maven/apache-maven-3.3.3/maven-repository-metadata/src/site/site.xml
new file mode 100644
index 00000000..0471f895
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-repository-metadata/src/site/site.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project xmlns="http://maven.apache.org/DECORATION/1.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/DECORATION/1.0.0 http://maven.apache.org/xsd/decoration-1.0.0.xsd">
+ <body>
+ <menu name="Overview">
+ <item name="Introduction" href="index.html"/>
+ <item name="JavaDocs" href="apidocs/index.html"/>
+ <!--item name="Source Xref" href="xref/index.html"/-->
+ <!--item name="FAQ" href="faq.html"/-->
+ </menu>
+
+ <menu ref="parent"/>
+ <menu ref="reports"/>
+ </body>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/pom.xml
new file mode 100644
index 00000000..d716840d
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/pom.xml
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven</artifactId>
+ <version>3.3.3</version>
+ </parent>
+
+ <artifactId>maven-settings-builder</artifactId>
+
+ <name>Maven Settings Builder</name>
+ <description>The effective settings builder, with inheritance and password decryption.</description>
+
+ <scm><!-- remove when git scm url format can accept artifact-id at the end, as automatically inherited -->
+ <connection>scm:git:https://git-wip-us.apache.org/repos/asf/maven.git</connection>
+ <developerConnection>scm:git:https://git-wip-us.apache.org/repos/asf/maven.git</developerConnection>
+ <tag>maven-3.3.3</tag>
+ </scm>
+
+ <contributors>
+ <contributor>
+ <name>Thomas Meyer</name>
+ </contributor>
+ </contributors>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-builder-support</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-utils</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-interpolation</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-component-annotations</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-settings</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.sonatype.plexus</groupId>
+ <artifactId>plexus-sec-dispatcher</artifactId>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-component-metadata</artifactId>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/building/DefaultSettingsBuilder.java b/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/building/DefaultSettingsBuilder.java
new file mode 100644
index 00000000..3cdae7d0
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/building/DefaultSettingsBuilder.java
@@ -0,0 +1,277 @@
+package org.apache.maven.settings.building;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.maven.building.FileSource;
+import org.apache.maven.building.Source;
+import org.apache.maven.settings.Settings;
+import org.apache.maven.settings.TrackableBase;
+import org.apache.maven.settings.io.SettingsParseException;
+import org.apache.maven.settings.io.SettingsReader;
+import org.apache.maven.settings.io.SettingsWriter;
+import org.apache.maven.settings.merge.MavenSettingsMerger;
+import org.apache.maven.settings.validation.SettingsValidator;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+import org.codehaus.plexus.interpolation.EnvarBasedValueSource;
+import org.codehaus.plexus.interpolation.InterpolationException;
+import org.codehaus.plexus.interpolation.InterpolationPostProcessor;
+import org.codehaus.plexus.interpolation.PropertiesBasedValueSource;
+import org.codehaus.plexus.interpolation.RegexBasedInterpolator;
+
+/**
+ * Builds the effective settings from a user settings file and/or a global settings file.
+ *
+ * @author Benjamin Bentmann
+ */
+@Component( role = SettingsBuilder.class )
+public class DefaultSettingsBuilder
+ implements SettingsBuilder
+{
+
+ @Requirement
+ private SettingsReader settingsReader;
+
+ @Requirement
+ private SettingsWriter settingsWriter;
+
+ @Requirement
+ private SettingsValidator settingsValidator;
+
+ private MavenSettingsMerger settingsMerger = new MavenSettingsMerger();
+
+ public DefaultSettingsBuilder setSettingsReader( SettingsReader settingsReader )
+ {
+ this.settingsReader = settingsReader;
+ return this;
+ }
+
+ public DefaultSettingsBuilder setSettingsWriter( SettingsWriter settingsWriter )
+ {
+ this.settingsWriter = settingsWriter;
+ return this;
+ }
+
+ public DefaultSettingsBuilder setSettingsValidator( SettingsValidator settingsValidator )
+ {
+ this.settingsValidator = settingsValidator;
+ return this;
+ }
+
+ @Override
+ public SettingsBuildingResult build( SettingsBuildingRequest request )
+ throws SettingsBuildingException
+ {
+ DefaultSettingsProblemCollector problems = new DefaultSettingsProblemCollector( null );
+
+ Source globalSettingsSource =
+ getSettingsSource( request.getGlobalSettingsFile(), request.getGlobalSettingsSource() );
+ Settings globalSettings = readSettings( globalSettingsSource, request, problems );
+
+ Source userSettingsSource =
+ getSettingsSource( request.getUserSettingsFile(), request.getUserSettingsSource() );
+ Settings userSettings = readSettings( userSettingsSource, request, problems );
+
+ settingsMerger.merge( userSettings, globalSettings, TrackableBase.GLOBAL_LEVEL );
+
+ problems.setSource( "" );
+
+ userSettings = interpolate( userSettings, request, problems );
+
+ // for the special case of a drive-relative Windows path, make sure it's absolute to save plugins from trouble
+ String localRepository = userSettings.getLocalRepository();
+ if ( localRepository != null && localRepository.length() > 0 )
+ {
+ File file = new File( localRepository );
+ if ( !file.isAbsolute() && file.getPath().startsWith( File.separator ) )
+ {
+ userSettings.setLocalRepository( file.getAbsolutePath() );
+ }
+ }
+
+ if ( hasErrors( problems.getProblems() ) )
+ {
+ throw new SettingsBuildingException( problems.getProblems() );
+ }
+
+ return new DefaultSettingsBuildingResult( userSettings, problems.getProblems() );
+ }
+
+ private boolean hasErrors( List<SettingsProblem> problems )
+ {
+ if ( problems != null )
+ {
+ for ( SettingsProblem problem : problems )
+ {
+ if ( SettingsProblem.Severity.ERROR.compareTo( problem.getSeverity() ) >= 0 )
+ {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ private Source getSettingsSource( File settingsFile, Source settingsSource )
+ {
+ if ( settingsSource != null )
+ {
+ return settingsSource;
+ }
+ else if ( settingsFile != null && settingsFile.exists() )
+ {
+ return new FileSource( settingsFile );
+ }
+ return null;
+ }
+
+ private Settings readSettings( Source settingsSource, SettingsBuildingRequest request,
+ DefaultSettingsProblemCollector problems )
+ {
+ if ( settingsSource == null )
+ {
+ return new Settings();
+ }
+
+ problems.setSource( settingsSource.getLocation() );
+
+ Settings settings;
+
+ try
+ {
+ Map<String, ?> options = Collections.singletonMap( SettingsReader.IS_STRICT, Boolean.TRUE );
+
+ try
+ {
+ settings = settingsReader.read( settingsSource.getInputStream(), options );
+ }
+ catch ( SettingsParseException e )
+ {
+ options = Collections.singletonMap( SettingsReader.IS_STRICT, Boolean.FALSE );
+
+ settings = settingsReader.read( settingsSource.getInputStream(), options );
+
+ problems.add( SettingsProblem.Severity.WARNING, e.getMessage(), e.getLineNumber(), e.getColumnNumber(),
+ e );
+ }
+ }
+ catch ( SettingsParseException e )
+ {
+ problems.add( SettingsProblem.Severity.FATAL, "Non-parseable settings " + settingsSource.getLocation()
+ + ": " + e.getMessage(), e.getLineNumber(), e.getColumnNumber(), e );
+ return new Settings();
+ }
+ catch ( IOException e )
+ {
+ problems.add( SettingsProblem.Severity.FATAL, "Non-readable settings " + settingsSource.getLocation()
+ + ": " + e.getMessage(), -1, -1, e );
+ return new Settings();
+ }
+
+ settingsValidator.validate( settings, problems );
+
+ return settings;
+ }
+
+ private Settings interpolate( Settings settings, SettingsBuildingRequest request,
+ SettingsProblemCollector problems )
+ {
+ StringWriter writer = new StringWriter( 1024 * 4 );
+
+ try
+ {
+ settingsWriter.write( writer, null, settings );
+ }
+ catch ( IOException e )
+ {
+ throw new IllegalStateException( "Failed to serialize settings to memory", e );
+ }
+
+ String serializedSettings = writer.toString();
+
+ RegexBasedInterpolator interpolator = new RegexBasedInterpolator();
+
+ interpolator.addValueSource( new PropertiesBasedValueSource( request.getUserProperties() ) );
+
+ interpolator.addValueSource( new PropertiesBasedValueSource( request.getSystemProperties() ) );
+
+ try
+ {
+ interpolator.addValueSource( new EnvarBasedValueSource() );
+ }
+ catch ( IOException e )
+ {
+ problems.add( SettingsProblem.Severity.WARNING, "Failed to use environment variables for interpolation: "
+ + e.getMessage(), -1, -1, e );
+ }
+
+ interpolator.addPostProcessor( new InterpolationPostProcessor()
+ {
+ @Override
+ public Object execute( String expression, Object value )
+ {
+ if ( value != null )
+ {
+ // we're going to parse this back in as XML so we need to escape XML markup
+ value = value.toString().replace( "&", "&amp;" ).replace( "<", "&lt;" ).replace( ">", "&gt;" );
+ return value;
+ }
+ return null;
+ }
+ } );
+
+ try
+ {
+ serializedSettings = interpolator.interpolate( serializedSettings, "settings" );
+ }
+ catch ( InterpolationException e )
+ {
+ problems.add( SettingsProblem.Severity.ERROR, "Failed to interpolate settings: " + e.getMessage(), -1, -1,
+ e );
+
+ return settings;
+ }
+
+ Settings result;
+ try
+ {
+ Map<String, ?> options = Collections.singletonMap( SettingsReader.IS_STRICT, Boolean.FALSE );
+ result = settingsReader.read( new StringReader( serializedSettings ), options );
+ }
+ catch ( IOException e )
+ {
+ problems.add( SettingsProblem.Severity.ERROR, "Failed to interpolate settings: " + e.getMessage(), -1, -1,
+ e );
+ return settings;
+ }
+
+ return result;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/building/DefaultSettingsBuilderFactory.java b/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/building/DefaultSettingsBuilderFactory.java
new file mode 100644
index 00000000..e728ec55
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/building/DefaultSettingsBuilderFactory.java
@@ -0,0 +1,71 @@
+package org.apache.maven.settings.building;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.settings.io.DefaultSettingsReader;
+import org.apache.maven.settings.io.DefaultSettingsWriter;
+import org.apache.maven.settings.io.SettingsReader;
+import org.apache.maven.settings.io.SettingsWriter;
+import org.apache.maven.settings.validation.DefaultSettingsValidator;
+import org.apache.maven.settings.validation.SettingsValidator;
+
+/**
+ * A factory to create settings builder instances when no dependency injection is available. <em>Note:</em> This class
+ * is only meant as a utility for developers that want to employ the settings builder outside of the Maven build system,
+ * Maven plugins should always acquire settings builder instances via dependency injection. Developers might want to
+ * subclass this factory to provide custom implementations for some of the components used by the settings builder.
+ *
+ * @author Benjamin Bentmann
+ */
+public class DefaultSettingsBuilderFactory
+{
+
+ protected SettingsReader newSettingsReader()
+ {
+ return new DefaultSettingsReader();
+ }
+
+ protected SettingsWriter newSettingsWriter()
+ {
+ return new DefaultSettingsWriter();
+ }
+
+ protected SettingsValidator newSettingsValidator()
+ {
+ return new DefaultSettingsValidator();
+ }
+
+ /**
+ * Creates a new settings builder instance.
+ *
+ * @return The new settings builder instance, never {@code null}.
+ */
+ public DefaultSettingsBuilder newInstance()
+ {
+ DefaultSettingsBuilder builder = new DefaultSettingsBuilder();
+
+ builder.setSettingsReader( newSettingsReader() );
+ builder.setSettingsWriter( newSettingsWriter() );
+ builder.setSettingsValidator( newSettingsValidator() );
+
+ return builder;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/building/DefaultSettingsBuildingRequest.java b/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/building/DefaultSettingsBuildingRequest.java
new file mode 100644
index 00000000..5a4824e0
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/building/DefaultSettingsBuildingRequest.java
@@ -0,0 +1,160 @@
+package org.apache.maven.settings.building;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.util.Properties;
+
+/**
+ * Collects settings that control building of effective settings.
+ *
+ * @author Benjamin Bentmann
+ */
+public class DefaultSettingsBuildingRequest
+ implements SettingsBuildingRequest
+{
+
+ private File globalSettingsFile;
+
+ private File userSettingsFile;
+
+ private SettingsSource globalSettingsSource;
+
+ private SettingsSource userSettingsSource;
+
+ private Properties systemProperties;
+
+ private Properties userProperties;
+
+ @Override
+ public File getGlobalSettingsFile()
+ {
+ return globalSettingsFile;
+ }
+
+ @Override
+ public DefaultSettingsBuildingRequest setGlobalSettingsFile( File globalSettingsFile )
+ {
+ this.globalSettingsFile = globalSettingsFile;
+
+ return this;
+ }
+
+ @Override
+ public SettingsSource getGlobalSettingsSource()
+ {
+ return globalSettingsSource;
+ }
+
+ @Override
+ public DefaultSettingsBuildingRequest setGlobalSettingsSource( SettingsSource globalSettingsSource )
+ {
+ this.globalSettingsSource = globalSettingsSource;
+
+ return this;
+ }
+
+ @Override
+ public File getUserSettingsFile()
+ {
+ return userSettingsFile;
+ }
+
+ @Override
+ public DefaultSettingsBuildingRequest setUserSettingsFile( File userSettingsFile )
+ {
+ this.userSettingsFile = userSettingsFile;
+
+ return this;
+ }
+
+ @Override
+ public SettingsSource getUserSettingsSource()
+ {
+ return userSettingsSource;
+ }
+
+ @Override
+ public DefaultSettingsBuildingRequest setUserSettingsSource( SettingsSource userSettingsSource )
+ {
+ this.userSettingsSource = userSettingsSource;
+
+ return this;
+ }
+
+ @Override
+ public Properties getSystemProperties()
+ {
+ if ( systemProperties == null )
+ {
+ systemProperties = new Properties();
+ }
+
+ return systemProperties;
+ }
+
+ @Override
+ public DefaultSettingsBuildingRequest setSystemProperties( Properties systemProperties )
+ {
+ if ( systemProperties != null )
+ {
+ this.systemProperties = new Properties();
+ // MNG-5670 guard against ConcurrentModificationException
+ for ( String key : System.getProperties().stringPropertyNames() )
+ {
+ this.systemProperties.put( key, System.getProperty( key ) );
+ }
+ }
+ else
+ {
+ this.systemProperties = null;
+ }
+
+ return this;
+ }
+
+ @Override
+ public Properties getUserProperties()
+ {
+ if ( userProperties == null )
+ {
+ userProperties = new Properties();
+ }
+
+ return userProperties;
+ }
+
+ @Override
+ public DefaultSettingsBuildingRequest setUserProperties( Properties userProperties )
+ {
+ if ( userProperties != null )
+ {
+ this.userProperties = new Properties();
+ this.userProperties.putAll( userProperties );
+ }
+ else
+ {
+ this.userProperties = null;
+ }
+
+ return this;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/building/DefaultSettingsBuildingResult.java b/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/building/DefaultSettingsBuildingResult.java
new file mode 100644
index 00000000..5c1392a6
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/building/DefaultSettingsBuildingResult.java
@@ -0,0 +1,58 @@
+package org.apache.maven.settings.building;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.maven.settings.Settings;
+
+/**
+ * Collects the output of the settings builder.
+ *
+ * @author Benjamin Bentmann
+ */
+class DefaultSettingsBuildingResult
+ implements SettingsBuildingResult
+{
+
+ private Settings effectiveSettings;
+
+ private List<SettingsProblem> problems;
+
+ public DefaultSettingsBuildingResult( Settings effectiveSettings, List<SettingsProblem> problems )
+ {
+ this.effectiveSettings = effectiveSettings;
+ this.problems = ( problems != null ) ? problems : new ArrayList<SettingsProblem>();
+ }
+
+ @Override
+ public Settings getEffectiveSettings()
+ {
+ return effectiveSettings;
+ }
+
+ @Override
+ public List<SettingsProblem> getProblems()
+ {
+ return problems;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/building/DefaultSettingsProblem.java b/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/building/DefaultSettingsProblem.java
new file mode 100644
index 00000000..b261fa1d
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/building/DefaultSettingsProblem.java
@@ -0,0 +1,166 @@
+package org.apache.maven.settings.building;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Describes a problem that was encountered during settings building. A problem can either be an exception that was
+ * thrown or a simple string message. In addition, a problem carries a hint about its source, e.g. the settings file
+ * that exhibits the problem.
+ *
+ * @author Benjamin Bentmann
+ */
+public class DefaultSettingsProblem
+ implements SettingsProblem
+{
+
+ private final String source;
+
+ private final int lineNumber;
+
+ private final int columnNumber;
+
+ private final String message;
+
+ private final Exception exception;
+
+ private final Severity severity;
+
+ /**
+ * Creates a new problem with the specified message and exception.
+ *
+ * @param message The message describing the problem, may be {@code null}.
+ * @param severity The severity level of the problem, may be {@code null} to default to
+ * {@link SettingsProblem.Severity#ERROR}.
+ * @param source A hint about the source of the problem like a file path, may be {@code null}.
+ * @param lineNumber The one-based index of the line containing the problem or {@code -1} if unknown.
+ * @param columnNumber The one-based index of the column containing the problem or {@code -1} if unknown.
+ * @param exception The exception that caused this problem, may be {@code null}.
+ */
+ public DefaultSettingsProblem( String message, Severity severity, String source, int lineNumber, int columnNumber,
+ Exception exception )
+ {
+ this.message = message;
+ this.severity = ( severity != null ) ? severity : Severity.ERROR;
+ this.source = ( source != null ) ? source : "";
+ this.lineNumber = lineNumber;
+ this.columnNumber = columnNumber;
+ this.exception = exception;
+ }
+
+ @Override
+ public String getSource()
+ {
+ return source;
+ }
+
+ @Override
+ public int getLineNumber()
+ {
+ return lineNumber;
+ }
+
+ @Override
+ public int getColumnNumber()
+ {
+ return columnNumber;
+ }
+
+ @Override
+ public String getLocation()
+ {
+ StringBuilder buffer = new StringBuilder( 256 );
+
+ if ( getSource().length() > 0 )
+ {
+ if ( buffer.length() > 0 )
+ {
+ buffer.append( ", " );
+ }
+ buffer.append( getSource() );
+ }
+
+ if ( getLineNumber() > 0 )
+ {
+ if ( buffer.length() > 0 )
+ {
+ buffer.append( ", " );
+ }
+ buffer.append( "line " ).append( getLineNumber() );
+ }
+
+ if ( getColumnNumber() > 0 )
+ {
+ if ( buffer.length() > 0 )
+ {
+ buffer.append( ", " );
+ }
+ buffer.append( "column " ).append( getColumnNumber() );
+ }
+
+ return buffer.toString();
+ }
+
+ @Override
+ public Exception getException()
+ {
+ return exception;
+ }
+
+ @Override
+ public String getMessage()
+ {
+ String msg;
+
+ if ( message != null && message.length() > 0 )
+ {
+ msg = message;
+ }
+ else
+ {
+ msg = exception.getMessage();
+
+ if ( msg == null )
+ {
+ msg = "";
+ }
+ }
+
+ return msg;
+ }
+
+ @Override
+ public Severity getSeverity()
+ {
+ return severity;
+ }
+
+ @Override
+ public String toString()
+ {
+ StringBuilder buffer = new StringBuilder( 128 );
+
+ buffer.append( "[" ).append( getSeverity() ).append( "] " );
+ buffer.append( getMessage() );
+ buffer.append( " @ " ).append( getLocation() );
+
+ return buffer.toString();
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/building/DefaultSettingsProblemCollector.java b/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/building/DefaultSettingsProblemCollector.java
new file mode 100644
index 00000000..6721379b
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/building/DefaultSettingsProblemCollector.java
@@ -0,0 +1,70 @@
+package org.apache.maven.settings.building;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.maven.settings.io.SettingsParseException;
+
+/**
+ * Collects problems that are encountered during settings building.
+ *
+ * @author Benjamin Bentmann
+ */
+class DefaultSettingsProblemCollector
+ implements SettingsProblemCollector
+{
+
+ private List<SettingsProblem> problems;
+
+ private String source;
+
+ public DefaultSettingsProblemCollector( List<SettingsProblem> problems )
+ {
+ this.problems = ( problems != null ) ? problems : new ArrayList<SettingsProblem>();
+ }
+
+ public List<SettingsProblem> getProblems()
+ {
+ return problems;
+ }
+
+ public void setSource( String source )
+ {
+ this.source = source;
+ }
+
+ @Override
+ public void add( SettingsProblem.Severity severity, String message, int line, int column, Exception cause )
+ {
+ if ( line <= 0 && column <= 0 && ( cause instanceof SettingsParseException ) )
+ {
+ SettingsParseException e = (SettingsParseException) cause;
+ line = e.getLineNumber();
+ column = e.getColumnNumber();
+ }
+
+ SettingsProblem problem = new DefaultSettingsProblem( message, severity, source, line, column, cause );
+
+ problems.add( problem );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/building/FileSettingsSource.java b/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/building/FileSettingsSource.java
new file mode 100644
index 00000000..3c2d32ac
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/building/FileSettingsSource.java
@@ -0,0 +1,59 @@
+package org.apache.maven.settings.building;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+
+import org.apache.maven.building.FileSource;
+
+/**
+ * Wraps an ordinary {@link File} as a settings source.
+ *
+ * @author Benjamin Bentmann
+ *
+ * @deprecated instead use {@link FileSource}
+ */
+@Deprecated
+public class FileSettingsSource extends FileSource
+ implements SettingsSource
+{
+
+ /**
+ * Creates a new settings source backed by the specified file.
+ *
+ * @param settingsFile The settings file, must not be {@code null}.
+ */
+ public FileSettingsSource( File settingsFile )
+ {
+ super( settingsFile );
+ }
+
+ /**
+ * Gets the settings file of this model source.
+ *
+ * @return The underlying settings file, never {@code null}.
+ * @deprecated instead use {@link #getFile()}
+ */
+ @Deprecated
+ public File getSettingsFile()
+ {
+ return getFile();
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/building/SettingsBuilder.java b/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/building/SettingsBuilder.java
new file mode 100644
index 00000000..61e34e99
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/building/SettingsBuilder.java
@@ -0,0 +1,40 @@
+package org.apache.maven.settings.building;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Builds the effective settings from a user settings file and/or a global settings file.
+ *
+ * @author Benjamin Bentmann
+ */
+public interface SettingsBuilder
+{
+
+ /**
+ * Builds the effective settings of the specified settings files.
+ *
+ * @param request The settings building request that holds the parameters, must not be {@code null}.
+ * @return The result of the settings building, never {@code null}.
+ * @throws SettingsBuildingException If the effective settings could not be built.
+ */
+ SettingsBuildingResult build( SettingsBuildingRequest request )
+ throws SettingsBuildingException;
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/building/SettingsBuildingException.java b/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/building/SettingsBuildingException.java
new file mode 100644
index 00000000..f7d48e4b
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/building/SettingsBuildingException.java
@@ -0,0 +1,90 @@
+package org.apache.maven.settings.building;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Signals one ore more errors during settings building. The settings builder tries to collect as many problems as
+ * possible before eventually failing to provide callers with rich error information. Use {@link #getProblems()} to
+ * query the details of the failure.
+ *
+ * @author Benjamin Bentmann
+ */
+public class SettingsBuildingException
+ extends Exception
+{
+
+ private final List<SettingsProblem> problems;
+
+ /**
+ * Creates a new exception with the specified problems.
+ *
+ * @param problems The problems that causes this exception, may be {@code null}.
+ */
+ public SettingsBuildingException( List<SettingsProblem> problems )
+ {
+ super( toMessage( problems ) );
+
+ this.problems = new ArrayList<SettingsProblem>();
+ if ( problems != null )
+ {
+ this.problems.addAll( problems );
+ }
+ }
+
+ /**
+ * Gets the problems that caused this exception.
+ *
+ * @return The problems that caused this exception, never {@code null}.
+ */
+ public List<SettingsProblem> getProblems()
+ {
+ return problems;
+ }
+
+ private static String toMessage( List<SettingsProblem> problems )
+ {
+ StringWriter buffer = new StringWriter( 1024 );
+
+ PrintWriter writer = new PrintWriter( buffer );
+
+ writer.print( problems.size() );
+ writer.print( ( problems.size() == 1 ) ? " problem was " : " problems were " );
+ writer.print( "encountered while building the effective settings" );
+ writer.println();
+
+ for ( SettingsProblem problem : problems )
+ {
+ writer.print( "[" );
+ writer.print( problem.getSeverity() );
+ writer.print( "] " );
+ writer.print( problem.getMessage() );
+ writer.print( " @ " );
+ writer.println( problem.getLocation() );
+ }
+
+ return buffer.toString();
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/building/SettingsBuildingRequest.java b/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/building/SettingsBuildingRequest.java
new file mode 100644
index 00000000..92d87d80
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/building/SettingsBuildingRequest.java
@@ -0,0 +1,131 @@
+package org.apache.maven.settings.building;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.util.Properties;
+
+/**
+ * Collects settings that control the building of effective settings.
+ *
+ * @author Benjamin Bentmann
+ */
+public interface SettingsBuildingRequest
+{
+
+ /**
+ * Gets the global settings file.
+ *
+ * @return The global settings file or {@code null} if none.
+ */
+ File getGlobalSettingsFile();
+
+ /**
+ * Sets the global settings file. A non-existent settings file is equivalent to empty settings. If both user
+ * settings and global settings are given, the user settings take precedence.
+ *
+ * @param globalSettingsFile The global settings file, may be {@code null} to disable global settings.
+ * @return This request, never {@code null}.
+ */
+ SettingsBuildingRequest setGlobalSettingsFile( File globalSettingsFile );
+
+ /**
+ * Gets the global settings source.
+ *
+ * @return The global settings source or {@code null} if none.
+ */
+ SettingsSource getGlobalSettingsSource();
+
+ /**
+ * Sets the global settings source. If both user settings and a global settings are given, the user settings take
+ * precedence.
+ *
+ * @param globalSettingsSource The global settings source, may be {@code null} to disable global settings.
+ * @return This request, never {@code null}.
+ */
+ SettingsBuildingRequest setGlobalSettingsSource( SettingsSource globalSettingsSource );
+
+ /**
+ * Gets the user settings file.
+ *
+ * @return The user settings file or {@code null} if none.
+ */
+ File getUserSettingsFile();
+
+ /**
+ * Sets the user settings file. A non-existent settings file is equivalent to empty settings. If both a user
+ * settings file and a global settings file are given, the user settings take precedence.
+ *
+ * @param userSettingsFile The user settings file, may be {@code null} to disable user settings.
+ * @return This request, never {@code null}.
+ */
+ SettingsBuildingRequest setUserSettingsFile( File userSettingsFile );
+
+ /**
+ * Gets the user settings source.
+ *
+ * @return The user settings source or {@code null} if none.
+ */
+ SettingsSource getUserSettingsSource();
+
+ /**
+ * Sets the user settings source. If both user settings and a global settings are given, the user settings take
+ * precedence.
+ *
+ * @param userSettingsSource The user settings source, may be {@code null} to disable user settings.
+ * @return This request, never {@code null}.
+ */
+ SettingsBuildingRequest setUserSettingsSource( SettingsSource userSettingsSource );
+
+ /**
+ * Gets the system properties to use for interpolation. The system properties are collected from the runtime
+ * environment like {@link System#getProperties()} and environment variables.
+ *
+ * @return The system properties, never {@code null}.
+ */
+ Properties getSystemProperties();
+
+ /**
+ * Sets the system properties to use for interpolation. The system properties are collected from the runtime
+ * environment like {@link System#getProperties()} and environment variables.
+ *
+ * @param systemProperties The system properties, may be {@code null}.
+ * @return This request, never {@code null}.
+ */
+ SettingsBuildingRequest setSystemProperties( Properties systemProperties );
+
+ /**
+ * Gets the user properties to use for interpolation. The user properties have been configured directly by the user
+ * on his discretion, e.g. via the {@code -Dkey=value} parameter on the command line.
+ *
+ * @return The user properties, never {@code null}.
+ */
+ Properties getUserProperties();
+
+ /**
+ * Sets the user properties to use for interpolation. The user properties have been configured directly by the user
+ * on his discretion, e.g. via the {@code -Dkey=value} parameter on the command line.
+ *
+ * @param userProperties The user properties, may be {@code null}.
+ * @return This request, never {@code null}.
+ */
+ SettingsBuildingRequest setUserProperties( Properties userProperties );
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/building/SettingsBuildingResult.java b/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/building/SettingsBuildingResult.java
new file mode 100644
index 00000000..43b2359f
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/building/SettingsBuildingResult.java
@@ -0,0 +1,50 @@
+package org.apache.maven.settings.building;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.List;
+
+import org.apache.maven.settings.Settings;
+
+/**
+ * Collects the output of the settings builder.
+ *
+ * @author Benjamin Bentmann
+ */
+public interface SettingsBuildingResult
+{
+
+ /**
+ * Gets the assembled settings.
+ *
+ * @return The assembled settings, never {@code null}.
+ */
+ Settings getEffectiveSettings();
+
+ /**
+ * Gets the problems that were encountered during the settings building. Note that only problems of severity
+ * {@link SettingsProblem.Severity#WARNING} and below are reported here. Problems with a higher severity level cause
+ * the settings builder to fail with a {@link SettingsBuildingException}.
+ *
+ * @return The problems that were encountered during the settings building, can be empty but never {@code null}.
+ */
+ List<SettingsProblem> getProblems();
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/building/SettingsProblem.java b/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/building/SettingsProblem.java
new file mode 100644
index 00000000..e9e563d9
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/building/SettingsProblem.java
@@ -0,0 +1,100 @@
+package org.apache.maven.settings.building;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Describes a problem that was encountered during settings building. A problem can either be an exception that was
+ * thrown or a simple string message. In addition, a problem carries a hint about its source, e.g. the settings file
+ * that exhibits the problem.
+ *
+ * @author Benjamin Bentmann
+ */
+public interface SettingsProblem
+{
+
+ /**
+ * The different severity levels for a problem, in decreasing order.
+ */
+ enum Severity
+ {
+
+ FATAL, //
+ ERROR, //
+ WARNING //
+
+ }
+
+ /**
+ * Gets the hint about the source of the problem. While the syntax of this hint is unspecified and depends on the
+ * creator of the problem, the general expectation is that the hint provides sufficient information to the user to
+ * track the problem back to its origin. A concrete example for such a source hint can be the file path or URL from
+ * which the settings were read.
+ *
+ * @return The hint about the source of the problem or an empty string if unknown, never {@code null}.
+ */
+ String getSource();
+
+ /**
+ * Gets the one-based index of the line containing the problem. The line number should refer to some text file that
+ * is given by {@link #getSource()}.
+ *
+ * @return The one-based index of the line containing the problem or a non-positive value if unknown.
+ */
+ int getLineNumber();
+
+ /**
+ * Gets the one-based index of the column containing the problem. The column number should refer to some text file
+ * that is given by {@link #getSource()}.
+ *
+ * @return The one-based index of the column containing the problem or non-positive value if unknown.
+ */
+ int getColumnNumber();
+
+ /**
+ * Gets the location of the problem. The location is a user-friendly combination of the values from
+ * {@link #getSource()}, {@link #getLineNumber()} and {@link #getColumnNumber()}. The exact syntax of the returned
+ * value is undefined.
+ *
+ * @return The location of the problem, never {@code null}.
+ */
+ String getLocation();
+
+ /**
+ * Gets the exception that caused this problem (if any).
+ *
+ * @return The exception that caused this problem or {@code null} if not applicable.
+ */
+ Exception getException();
+
+ /**
+ * Gets the message that describes this problem.
+ *
+ * @return The message describing this problem, never {@code null}.
+ */
+ String getMessage();
+
+ /**
+ * Gets the severity level of this problem.
+ *
+ * @return The severity level of this problem, never {@code null}.
+ */
+ Severity getSeverity();
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/building/SettingsProblemCollector.java b/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/building/SettingsProblemCollector.java
new file mode 100644
index 00000000..63869c0a
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/building/SettingsProblemCollector.java
@@ -0,0 +1,41 @@
+package org.apache.maven.settings.building;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Collects problems that are encountered during settings building.
+ *
+ * @author Benjamin Bentmann
+ */
+public interface SettingsProblemCollector
+{
+
+ /**
+ * Adds the specified problem.
+ *
+ * @param severity The severity of the problem, must not be {@code null}.
+ * @param message The detail message of the problem, may be {@code null}.
+ * @param line The one-based index of the line containing the problem or {@code -1} if unknown.
+ * @param column The one-based index of the column containing the problem or {@code -1} if unknown.
+ * @param cause The cause of the problem, may be {@code null}.
+ */
+ void add( SettingsProblem.Severity severity, String message, int line, int column, Exception cause );
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/building/SettingsSource.java b/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/building/SettingsSource.java
new file mode 100644
index 00000000..413a3570
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/building/SettingsSource.java
@@ -0,0 +1,35 @@
+package org.apache.maven.settings.building;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.building.Source;
+
+/**
+ * Provides access to the contents of settings independently of the backing store (e.g. file system, database, memory).
+ *
+ * @author Benjamin Bentmann
+ *
+ * @deprecated instead use {@link Source}
+ */
+@Deprecated
+public interface SettingsSource extends Source
+{
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/building/StringSettingsSource.java b/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/building/StringSettingsSource.java
new file mode 100644
index 00000000..dbe97580
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/building/StringSettingsSource.java
@@ -0,0 +1,69 @@
+package org.apache.maven.settings.building;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.building.StringSource;
+
+/**
+ * Wraps an ordinary {@link CharSequence} as a settings source.
+ *
+ * @author Benjamin Bentmann
+ *
+ * @deprecated instead use {@link StringSource}
+ */
+@Deprecated
+public class StringSettingsSource extends StringSource
+ implements SettingsSource
+{
+
+ /**
+ * Creates a new settings source backed by the specified string.
+ *
+ * @param settings The settings' string representation, may be empty or {@code null}.
+ */
+ public StringSettingsSource( CharSequence settings )
+ {
+ this( settings, null );
+ }
+
+ /**
+ * Creates a new settings source backed by the specified string.
+ *
+ * @param settings The settings' string representation, may be empty or {@code null}.
+ * @param location The location to report for this use, may be {@code null}.
+ */
+ public StringSettingsSource( CharSequence settings, String location )
+ {
+ super( settings, location );
+ }
+
+ /**
+ * Gets the character sequence of this settings source.
+ *
+ * @return The underlying character stream, never {@code null}.
+ * @deprecated instead use {@link #getContent()}
+ */
+ @Deprecated
+ public String getSettings()
+ {
+ return getContent();
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/building/UrlSettingsSource.java b/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/building/UrlSettingsSource.java
new file mode 100644
index 00000000..2b40f648
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/building/UrlSettingsSource.java
@@ -0,0 +1,60 @@
+package org.apache.maven.settings.building;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.net.URL;
+
+import org.apache.maven.building.UrlSource;
+
+/**
+ * Wraps an ordinary {@link URL} as a settings source.
+ *
+ * @author Benjamin Bentmann
+ *
+ * @deprecated instead use {@link UrlSource}
+ */
+@Deprecated
+public class UrlSettingsSource extends UrlSource
+ implements SettingsSource
+{
+
+ /**
+ * Creates a new model source backed by the specified URL.
+ *
+ * @param settingsUrl The settings URL, must not be {@code null}.
+ */
+ public UrlSettingsSource( URL settingsUrl )
+ {
+ super( settingsUrl );
+ }
+
+ /**
+ * Gets the settings URL of this model source.
+ *
+ * @return The underlying settings URL, never {@code null}.
+ * @deprecated instead use {@link #getUrl()}
+ */
+ @Deprecated
+ public URL getSettingsUrl()
+ {
+ return getUrl();
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/crypto/DefaultSettingsDecrypter.java b/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/crypto/DefaultSettingsDecrypter.java
new file mode 100644
index 00000000..acdb4b25
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/crypto/DefaultSettingsDecrypter.java
@@ -0,0 +1,110 @@
+package org.apache.maven.settings.crypto;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.maven.settings.Proxy;
+import org.apache.maven.settings.Server;
+import org.apache.maven.settings.building.DefaultSettingsProblem;
+import org.apache.maven.settings.building.SettingsProblem;
+import org.apache.maven.settings.building.SettingsProblem.Severity;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+import org.sonatype.plexus.components.sec.dispatcher.SecDispatcher;
+import org.sonatype.plexus.components.sec.dispatcher.SecDispatcherException;
+
+/**
+ * Decrypts passwords in the settings.
+ *
+ * @author Benjamin Bentmann
+ */
+@Component( role = SettingsDecrypter.class )
+public class DefaultSettingsDecrypter
+ implements SettingsDecrypter
+{
+
+ @Requirement( hint = "maven" )
+ private SecDispatcher securityDispatcher;
+
+ @Override
+ public SettingsDecryptionResult decrypt( SettingsDecryptionRequest request )
+ {
+ List<SettingsProblem> problems = new ArrayList<SettingsProblem>();
+
+ List<Server> servers = new ArrayList<Server>();
+
+ for ( Server server : request.getServers() )
+ {
+ server = server.clone();
+
+ servers.add( server );
+
+ try
+ {
+ server.setPassword( decrypt( server.getPassword() ) );
+ }
+ catch ( SecDispatcherException e )
+ {
+ problems.add( new DefaultSettingsProblem( "Failed to decrypt password for server " + server.getId()
+ + ": " + e.getMessage(), Severity.ERROR, "server: " + server.getId(), -1, -1, e ) );
+ }
+
+ try
+ {
+ server.setPassphrase( decrypt( server.getPassphrase() ) );
+ }
+ catch ( SecDispatcherException e )
+ {
+ problems.add( new DefaultSettingsProblem( "Failed to decrypt passphrase for server " + server.getId()
+ + ": " + e.getMessage(), Severity.ERROR, "server: " + server.getId(), -1, -1, e ) );
+ }
+ }
+
+ List<Proxy> proxies = new ArrayList<Proxy>();
+
+ for ( Proxy proxy : request.getProxies() )
+ {
+ proxy = proxy.clone();
+
+ proxies.add( proxy );
+
+ try
+ {
+ proxy.setPassword( decrypt( proxy.getPassword() ) );
+ }
+ catch ( SecDispatcherException e )
+ {
+ problems.add( new DefaultSettingsProblem( "Failed to decrypt password for proxy " + proxy.getId()
+ + ": " + e.getMessage(), Severity.ERROR, "proxy: " + proxy.getId(), -1, -1, e ) );
+ }
+ }
+
+ return new DefaultSettingsDecryptionResult( servers, proxies, problems );
+ }
+
+ private String decrypt( String str )
+ throws SecDispatcherException
+ {
+ return ( str == null ) ? null : securityDispatcher.decrypt( str );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/crypto/DefaultSettingsDecryptionRequest.java b/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/crypto/DefaultSettingsDecryptionRequest.java
new file mode 100644
index 00000000..31185f1e
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/crypto/DefaultSettingsDecryptionRequest.java
@@ -0,0 +1,120 @@
+package org.apache.maven.settings.crypto;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.maven.settings.Proxy;
+import org.apache.maven.settings.Server;
+import org.apache.maven.settings.Settings;
+
+/**
+ * Collects parameters that control the decryption of settings.
+ *
+ * @author Benjamin Bentmann
+ */
+public class DefaultSettingsDecryptionRequest
+ implements SettingsDecryptionRequest
+{
+
+ private List<Server> servers;
+
+ private List<Proxy> proxies;
+
+ /**
+ * Creates an empty request.
+ */
+ public DefaultSettingsDecryptionRequest()
+ {
+ // does nothing
+ }
+
+ /**
+ * Creates a new request to decrypt the specified settings.
+ *
+ * @param settings The settings to decrypt, must not be {@code null}.
+ */
+ public DefaultSettingsDecryptionRequest( Settings settings )
+ {
+ setServers( settings.getServers() );
+ setProxies( settings.getProxies() );
+ }
+
+ /**
+ * Creates a new request to decrypt the specified server.
+ *
+ * @param server The server to decrypt, must not be {@code null}.
+ */
+ public DefaultSettingsDecryptionRequest( Server server )
+ {
+ this.servers = new ArrayList<Server>( Arrays.asList( server ) );
+ }
+
+ /**
+ * Creates a new request to decrypt the specified proxy.
+ *
+ * @param proxy The proxy to decrypt, must not be {@code null}.
+ */
+ public DefaultSettingsDecryptionRequest( Proxy proxy )
+ {
+ this.proxies = new ArrayList<Proxy>( Arrays.asList( proxy ) );
+ }
+
+ @Override
+ public List<Server> getServers()
+ {
+ if ( servers == null )
+ {
+ servers = new ArrayList<Server>();
+ }
+
+ return servers;
+ }
+
+ @Override
+ public DefaultSettingsDecryptionRequest setServers( List<Server> servers )
+ {
+ this.servers = servers;
+
+ return this;
+ }
+
+ @Override
+ public List<Proxy> getProxies()
+ {
+ if ( proxies == null )
+ {
+ proxies = new ArrayList<Proxy>();
+ }
+
+ return proxies;
+ }
+
+ @Override
+ public DefaultSettingsDecryptionRequest setProxies( List<Proxy> proxies )
+ {
+ this.proxies = proxies;
+
+ return this;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/crypto/DefaultSettingsDecryptionResult.java b/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/crypto/DefaultSettingsDecryptionResult.java
new file mode 100644
index 00000000..33ee5a1a
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/crypto/DefaultSettingsDecryptionResult.java
@@ -0,0 +1,81 @@
+package org.apache.maven.settings.crypto;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.maven.settings.Proxy;
+import org.apache.maven.settings.Server;
+import org.apache.maven.settings.building.SettingsProblem;
+
+/**
+ * Collects the output of the settings decrypter.
+ *
+ * @author Benjamin Bentmann
+ */
+class DefaultSettingsDecryptionResult
+ implements SettingsDecryptionResult
+{
+
+ private List<Server> servers;
+
+ private List<Proxy> proxies;
+
+ private List<SettingsProblem> problems;
+
+ public DefaultSettingsDecryptionResult( List<Server> servers, List<Proxy> proxies, List<SettingsProblem> problems )
+ {
+ this.servers = ( servers != null ) ? servers : new ArrayList<Server>();
+ this.proxies = ( proxies != null ) ? proxies : new ArrayList<Proxy>();
+ this.problems = ( problems != null ) ? problems : new ArrayList<SettingsProblem>();
+ }
+
+ @Override
+ public Server getServer()
+ {
+ return servers.isEmpty() ? null : servers.get( 0 );
+ }
+
+ @Override
+ public List<Server> getServers()
+ {
+ return servers;
+ }
+
+ @Override
+ public Proxy getProxy()
+ {
+ return proxies.isEmpty() ? null : proxies.get( 0 );
+ }
+
+ @Override
+ public List<Proxy> getProxies()
+ {
+ return proxies;
+ }
+
+ @Override
+ public List<SettingsProblem> getProblems()
+ {
+ return problems;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/crypto/SettingsDecrypter.java b/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/crypto/SettingsDecrypter.java
new file mode 100644
index 00000000..b34c3944
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/crypto/SettingsDecrypter.java
@@ -0,0 +1,38 @@
+package org.apache.maven.settings.crypto;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Decrypts passwords in the settings.
+ *
+ * @author Benjamin Bentmann
+ */
+public interface SettingsDecrypter
+{
+
+ /**
+ * Decrypts passwords in the settings.
+ *
+ * @param request The settings decryption request that holds the parameters, must not be {@code null}.
+ * @return The result of the settings decryption, never {@code null}.
+ */
+ SettingsDecryptionResult decrypt( SettingsDecryptionRequest request );
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/crypto/SettingsDecryptionRequest.java b/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/crypto/SettingsDecryptionRequest.java
new file mode 100644
index 00000000..b344a99e
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/crypto/SettingsDecryptionRequest.java
@@ -0,0 +1,65 @@
+package org.apache.maven.settings.crypto;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.List;
+
+import org.apache.maven.settings.Proxy;
+import org.apache.maven.settings.Server;
+
+/**
+ * Collects parameters that control the decryption of settings.
+ *
+ * @author Benjamin Bentmann
+ */
+public interface SettingsDecryptionRequest
+{
+
+ /**
+ * Gets the servers whose passwords should be decrypted.
+ *
+ * @return The servers to decrypt, never {@code null}.
+ */
+ List<Server> getServers();
+
+ /**
+ * Sets the servers whose passwords should be decrypted.
+ *
+ * @param servers The servers to decrypt, may be {@code null}.
+ * @return This request, never {@code null}.
+ */
+ SettingsDecryptionRequest setServers( List<Server> servers );
+
+ /**
+ * Gets the proxies whose passwords should be decrypted.
+ *
+ * @return The proxies to decrypt, never {@code null}.
+ */
+ List<Proxy> getProxies();
+
+ /**
+ * Sets the proxies whose passwords should be decrypted.
+ *
+ * @param proxies The proxies to decrypt, may be {@code null}.
+ * @return This request, never {@code null}.
+ */
+ SettingsDecryptionRequest setProxies( List<Proxy> proxies );
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/crypto/SettingsDecryptionResult.java b/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/crypto/SettingsDecryptionResult.java
new file mode 100644
index 00000000..5b7b1f4b
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/crypto/SettingsDecryptionResult.java
@@ -0,0 +1,71 @@
+package org.apache.maven.settings.crypto;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.List;
+
+import org.apache.maven.settings.Proxy;
+import org.apache.maven.settings.Server;
+import org.apache.maven.settings.building.SettingsProblem;
+
+/**
+ * Collects the output of the settings decrypter.
+ *
+ * @author Benjamin Bentmann
+ */
+public interface SettingsDecryptionResult
+{
+
+ /**
+ * Gets the decrypted server. This is a convenience method to retrieve the first element from {@link #getServers()}.
+ *
+ * @return The decrypted server or {@code null}.
+ */
+ Server getServer();
+
+ /**
+ * Gets the decrypted servers.
+ *
+ * @return The decrypted server, can be empty but never {@code null}.
+ */
+ List<Server> getServers();
+
+ /**
+ * Gets the decrypted proxy. This is a convenience method to retrieve the first element from {@link #getProxies()}.
+ *
+ * @return The decrypted proxy or {@code null}.
+ */
+ Proxy getProxy();
+
+ /**
+ * Gets the decrypted proxies.
+ *
+ * @return The decrypted proxy, can be empty but never {@code null}.
+ */
+ List<Proxy> getProxies();
+
+ /**
+ * Gets the problems that were encountered during the settings decryption.
+ *
+ * @return The problems that were encountered during the decryption, can be empty but never {@code null}.
+ */
+ List<SettingsProblem> getProblems();
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/io/DefaultSettingsReader.java b/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/io/DefaultSettingsReader.java
new file mode 100644
index 00000000..590423ef
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/io/DefaultSettingsReader.java
@@ -0,0 +1,113 @@
+package org.apache.maven.settings.io;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.util.Map;
+
+import org.apache.maven.settings.Settings;
+import org.apache.maven.settings.io.xpp3.SettingsXpp3Reader;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.util.IOUtil;
+import org.codehaus.plexus.util.ReaderFactory;
+import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
+
+/**
+ * Handles deserialization of settings from the default textual format.
+ *
+ * @author Benjamin Bentmann
+ */
+@Component( role = SettingsReader.class )
+public class DefaultSettingsReader
+ implements SettingsReader
+{
+
+ @Override
+ public Settings read( File input, Map<String, ?> options )
+ throws IOException
+ {
+ if ( input == null )
+ {
+ throw new IllegalArgumentException( "input file missing" );
+ }
+
+ Settings settings = read( ReaderFactory.newXmlReader( input ), options );
+
+ return settings;
+ }
+
+ @Override
+ public Settings read( Reader input, Map<String, ?> options )
+ throws IOException
+ {
+ if ( input == null )
+ {
+ throw new IllegalArgumentException( "input reader missing" );
+ }
+
+ try
+ {
+ SettingsXpp3Reader r = new SettingsXpp3Reader();
+ return r.read( input, isStrict( options ) );
+ }
+ catch ( XmlPullParserException e )
+ {
+ throw new SettingsParseException( e.getMessage(), e.getLineNumber(), e.getColumnNumber(), e );
+ }
+ finally
+ {
+ IOUtil.close( input );
+ }
+ }
+
+ @Override
+ public Settings read( InputStream input, Map<String, ?> options )
+ throws IOException
+ {
+ if ( input == null )
+ {
+ throw new IllegalArgumentException( "input stream missing" );
+ }
+
+ try
+ {
+ SettingsXpp3Reader r = new SettingsXpp3Reader();
+ return r.read( input, isStrict( options ) );
+ }
+ catch ( XmlPullParserException e )
+ {
+ throw new SettingsParseException( e.getMessage(), e.getLineNumber(), e.getColumnNumber(), e );
+ }
+ finally
+ {
+ IOUtil.close( input );
+ }
+ }
+
+ private boolean isStrict( Map<String, ?> options )
+ {
+ Object value = ( options != null ) ? options.get( IS_STRICT ) : null;
+ return value == null || Boolean.parseBoolean( value.toString() );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/io/DefaultSettingsWriter.java b/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/io/DefaultSettingsWriter.java
new file mode 100644
index 00000000..88f78a03
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/io/DefaultSettingsWriter.java
@@ -0,0 +1,118 @@
+package org.apache.maven.settings.io;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+import java.util.Map;
+
+import org.apache.maven.settings.Settings;
+import org.apache.maven.settings.io.xpp3.SettingsXpp3Writer;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.util.IOUtil;
+import org.codehaus.plexus.util.WriterFactory;
+
+/**
+ * Handles serialization of settings into the default textual format.
+ *
+ * @author Benjamin Bentmann
+ */
+@Component( role = SettingsWriter.class )
+public class DefaultSettingsWriter
+ implements SettingsWriter
+{
+
+ @Override
+ public void write( File output, Map<String, Object> options, Settings settings )
+ throws IOException
+ {
+ if ( output == null )
+ {
+ throw new IllegalArgumentException( "output file missing" );
+ }
+
+ if ( settings == null )
+ {
+ throw new IllegalArgumentException( "settings missing" );
+ }
+
+ output.getParentFile().mkdirs();
+
+ write( WriterFactory.newXmlWriter( output ), options, settings );
+ }
+
+ @Override
+ public void write( Writer output, Map<String, Object> options, Settings settings )
+ throws IOException
+ {
+ if ( output == null )
+ {
+ throw new IllegalArgumentException( "output writer missing" );
+ }
+
+ if ( settings == null )
+ {
+ throw new IllegalArgumentException( "settings missing" );
+ }
+
+ try
+ {
+ SettingsXpp3Writer w = new SettingsXpp3Writer();
+ w.write( output, settings );
+ }
+ finally
+ {
+ IOUtil.close( output );
+ }
+ }
+
+ @Override
+ public void write( OutputStream output, Map<String, Object> options, Settings settings )
+ throws IOException
+ {
+ if ( output == null )
+ {
+ throw new IllegalArgumentException( "output stream missing" );
+ }
+
+ if ( settings == null )
+ {
+ throw new IllegalArgumentException( "settings missing" );
+ }
+
+ try
+ {
+ String encoding = settings.getModelEncoding();
+ if ( encoding == null || encoding.length() <= 0 )
+ {
+ encoding = "UTF-8";
+ }
+ write( new OutputStreamWriter( output, encoding ), options, settings );
+ }
+ finally
+ {
+ IOUtil.close( output );
+ }
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/io/SettingsParseException.java b/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/io/SettingsParseException.java
new file mode 100644
index 00000000..425e6d8e
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/io/SettingsParseException.java
@@ -0,0 +1,93 @@
+package org.apache.maven.settings.io;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.IOException;
+
+/**
+ * Signals a failure to parse the settings due to invalid syntax (e.g. non-wellformed XML or unknown elements).
+ *
+ * @author Benjamin Bentmann
+ */
+public class SettingsParseException
+ extends IOException
+{
+
+ /**
+ * The one-based index of the line containing the error.
+ */
+ private final int lineNumber;
+
+ /**
+ * The one-based index of the column containing the error.
+ */
+ private final int columnNumber;
+
+ /**
+ * Creates a new parser exception with the specified details.
+ *
+ * @param message The error message, may be {@code null}.
+ * @param lineNumber The one-based index of the line containing the error or {@code -1} if unknown.
+ * @param columnNumber The one-based index of the column containing the error or {@code -1} if unknown.
+ */
+ public SettingsParseException( String message, int lineNumber, int columnNumber )
+ {
+ super( message );
+ this.lineNumber = lineNumber;
+ this.columnNumber = columnNumber;
+ }
+
+ /**
+ * Creates a new parser exception with the specified details.
+ *
+ * @param message The error message, may be {@code null}.
+ * @param lineNumber The one-based index of the line containing the error or {@code -1} if unknown.
+ * @param columnNumber The one-based index of the column containing the error or {@code -1} if unknown.
+ * @param cause The nested cause of this error, may be {@code null}.
+ */
+ public SettingsParseException( String message, int lineNumber, int columnNumber, Throwable cause )
+ {
+ super( message );
+ initCause( cause );
+ this.lineNumber = lineNumber;
+ this.columnNumber = columnNumber;
+ }
+
+ /**
+ * Gets the one-based index of the line containing the error.
+ *
+ * @return The one-based index of the line containing the error or a non-positive value if unknown.
+ */
+ public int getLineNumber()
+ {
+ return lineNumber;
+ }
+
+ /**
+ * Gets the one-based index of the column containing the error.
+ *
+ * @return The one-based index of the column containing the error or non-positive value if unknown.
+ */
+ public int getColumnNumber()
+ {
+ return columnNumber;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/io/SettingsReader.java b/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/io/SettingsReader.java
new file mode 100644
index 00000000..7817df65
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/io/SettingsReader.java
@@ -0,0 +1,82 @@
+package org.apache.maven.settings.io;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.util.Map;
+
+import org.apache.maven.settings.Settings;
+
+/**
+ * Handles deserialization of settings from some kind of textual format like XML.
+ *
+ * @author Benjamin Bentmann
+ */
+public interface SettingsReader
+{
+
+ /**
+ * The key for the option to enable strict parsing. This option is of type {@link Boolean} and defaults to {@code
+ * true}. If {@code false}, unknown elements will be ignored instead of causing a failure.
+ */
+ String IS_STRICT = "org.apache.maven.settings.io.isStrict";
+
+ /**
+ * Reads the settings from the specified file.
+ *
+ * @param input The file to deserialize the settings from, must not be {@code null}.
+ * @param options The options to use for deserialization, may be {@code null} to use the default values.
+ * @return The deserialized settings, never {@code null}.
+ * @throws IOException If the settings could not be deserialized.
+ * @throws SettingsParseException If the input format could not be parsed.
+ */
+ Settings read( File input, Map<String, ?> options )
+ throws IOException, SettingsParseException;
+
+ /**
+ * Reads the settings from the specified character reader. The reader will be automatically closed before the method
+ * returns.
+ *
+ * @param input The reader to deserialize the settings from, must not be {@code null}.
+ * @param options The options to use for deserialization, may be {@code null} to use the default values.
+ * @return The deserialized settings, never {@code null}.
+ * @throws IOException If the settings could not be deserialized.
+ * @throws SettingsParseException If the input format could not be parsed.
+ */
+ Settings read( Reader input, Map<String, ?> options )
+ throws IOException, SettingsParseException;
+
+ /**
+ * Reads the settings from the specified byte stream. The stream will be automatically closed before the method
+ * returns.
+ *
+ * @param input The stream to deserialize the settings from, must not be {@code null}.
+ * @param options The options to use for deserialization, may be {@code null} to use the default values.
+ * @return The deserialized settings, never {@code null}.
+ * @throws IOException If the settings could not be deserialized.
+ * @throws SettingsParseException If the input format could not be parsed.
+ */
+ Settings read( InputStream input, Map<String, ?> options )
+ throws IOException, SettingsParseException;
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/io/SettingsWriter.java b/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/io/SettingsWriter.java
new file mode 100644
index 00000000..54bfcf0c
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/io/SettingsWriter.java
@@ -0,0 +1,74 @@
+package org.apache.maven.settings.io;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.Writer;
+import java.util.Map;
+
+import org.apache.maven.settings.Settings;
+
+/**
+ * Handles serialization of settings into some kind of textual format like XML.
+ *
+ * @author Benjamin Bentmann
+ */
+public interface SettingsWriter
+{
+
+ /**
+ * Writes the supplied settings to the specified file. Any non-existing parent directories of the output file will
+ * be created automatically.
+ *
+ * @param output The file to serialize the settings to, must not be {@code null}.
+ * @param options The options to use for serialization, may be {@code null} to use the default values.
+ * @param settings The settings to serialize, must not be {@code null}.
+ * @throws IOException If the settings could not be serialized.
+ */
+ void write( File output, Map<String, Object> options, Settings settings )
+ throws IOException;
+
+ /**
+ * Writes the supplied settings to the specified character writer. The writer will be automatically closed before
+ * the method returns.
+ *
+ * @param output The writer to serialize the settings to, must not be {@code null}.
+ * @param options The options to use for serialization, may be {@code null} to use the default values.
+ * @param settings The settings to serialize, must not be {@code null}.
+ * @throws IOException If the settings could not be serialized.
+ */
+ void write( Writer output, Map<String, Object> options, Settings settings )
+ throws IOException;
+
+ /**
+ * Writes the supplied settings to the specified byte stream. The stream will be automatically closed before the
+ * method returns.
+ *
+ * @param output The stream to serialize the settings to, must not be {@code null}.
+ * @param options The options to use for serialization, may be {@code null} to use the default values.
+ * @param settings The settings to serialize, must not be {@code null}.
+ * @throws IOException If the settings could not be serialized.
+ */
+ void write( OutputStream output, Map<String, Object> options, Settings settings )
+ throws IOException;
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/merge/MavenSettingsMerger.java b/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/merge/MavenSettingsMerger.java
new file mode 100644
index 00000000..fd419fb2
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/merge/MavenSettingsMerger.java
@@ -0,0 +1,142 @@
+package org.apache.maven.settings.merge;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.maven.settings.IdentifiableBase;
+import org.apache.maven.settings.Settings;
+import org.codehaus.plexus.util.StringUtils;
+
+/**
+ * @author <a href="mailto:vincent.siveton@gmail.com">Vincent Siveton</a>
+ * @author Benjamin Bentmann
+ */
+public class MavenSettingsMerger
+{
+
+ /**
+ * @param dominant
+ * @param recessive
+ * @param recessiveSourceLevel
+ */
+ public void merge( Settings dominant, Settings recessive, String recessiveSourceLevel )
+ {
+ if ( dominant == null || recessive == null )
+ {
+ return;
+ }
+
+ recessive.setSourceLevel( recessiveSourceLevel );
+
+ List<String> dominantActiveProfiles = dominant.getActiveProfiles();
+ List<String> recessiveActiveProfiles = recessive.getActiveProfiles();
+
+ if ( recessiveActiveProfiles != null )
+ {
+ if ( dominantActiveProfiles == null )
+ {
+ dominantActiveProfiles = new ArrayList<String>();
+ dominant.setActiveProfiles( dominantActiveProfiles );
+ }
+
+ for ( String profileId : recessiveActiveProfiles )
+ {
+ if ( !dominantActiveProfiles.contains( profileId ) )
+ {
+ dominantActiveProfiles.add( profileId );
+ }
+ }
+ }
+
+ List<String> dominantPluginGroupIds = dominant.getPluginGroups();
+
+ List<String> recessivePluginGroupIds = recessive.getPluginGroups();
+
+ if ( recessivePluginGroupIds != null )
+ {
+ if ( dominantPluginGroupIds == null )
+ {
+ dominantPluginGroupIds = new ArrayList<String>();
+ dominant.setPluginGroups( dominantPluginGroupIds );
+ }
+
+ for ( String pluginGroupId : recessivePluginGroupIds )
+ {
+ if ( !dominantPluginGroupIds.contains( pluginGroupId ) )
+ {
+ dominantPluginGroupIds.add( pluginGroupId );
+ }
+ }
+ }
+
+ if ( StringUtils.isEmpty( dominant.getLocalRepository() ) )
+ {
+ dominant.setLocalRepository( recessive.getLocalRepository() );
+ }
+
+ shallowMergeById( dominant.getMirrors(), recessive.getMirrors(), recessiveSourceLevel );
+ shallowMergeById( dominant.getServers(), recessive.getServers(), recessiveSourceLevel );
+ shallowMergeById( dominant.getProxies(), recessive.getProxies(), recessiveSourceLevel );
+ shallowMergeById( dominant.getProfiles(), recessive.getProfiles(), recessiveSourceLevel );
+
+ }
+
+ /**
+ * @param dominant
+ * @param recessive
+ * @param recessiveSourceLevel
+ */
+ private static <T extends IdentifiableBase> void shallowMergeById( List<T> dominant, List<T> recessive,
+ String recessiveSourceLevel )
+ {
+ Map<String, T> dominantById = mapById( dominant );
+
+ for ( T identifiable : recessive )
+ {
+ if ( !dominantById.containsKey( identifiable.getId() ) )
+ {
+ identifiable.setSourceLevel( recessiveSourceLevel );
+
+ dominant.add( identifiable );
+ }
+ }
+ }
+
+ /**
+ * @param identifiables
+ * @return a map
+ */
+ private static <T extends IdentifiableBase> Map<String, T> mapById( List<T> identifiables )
+ {
+ Map<String, T> byId = new HashMap<String, T>();
+
+ for ( T identifiable : identifiables )
+ {
+ byId.put( identifiable.getId(), identifiable );
+ }
+
+ return byId;
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/validation/DefaultSettingsValidator.java b/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/validation/DefaultSettingsValidator.java
new file mode 100644
index 00000000..5d17456d
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/validation/DefaultSettingsValidator.java
@@ -0,0 +1,285 @@
+package org.apache.maven.settings.validation;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.maven.settings.Mirror;
+import org.apache.maven.settings.Profile;
+import org.apache.maven.settings.Repository;
+import org.apache.maven.settings.Proxy;
+import org.apache.maven.settings.Server;
+import org.apache.maven.settings.Settings;
+import org.apache.maven.settings.building.SettingsProblem.Severity;
+import org.apache.maven.settings.building.SettingsProblemCollector;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.util.StringUtils;
+
+/**
+ * @author Milos Kleint
+ */
+@Component( role = SettingsValidator.class )
+public class DefaultSettingsValidator
+ implements SettingsValidator
+{
+
+ private static final String ID_REGEX = "[A-Za-z0-9_\\-.]+";
+
+ private static final String ILLEGAL_FS_CHARS = "\\/:\"<>|?*";
+
+ private static final String ILLEGAL_REPO_ID_CHARS = ILLEGAL_FS_CHARS;
+
+ @Override
+ public void validate( Settings settings, SettingsProblemCollector problems )
+ {
+ if ( settings.isUsePluginRegistry() )
+ {
+ addViolation( problems, Severity.WARNING, "usePluginRegistry", null, "is deprecated and has no effect." );
+ }
+
+ List<String> pluginGroups = settings.getPluginGroups();
+
+ if ( pluginGroups != null )
+ {
+ for ( int i = 0; i < pluginGroups.size(); i++ )
+ {
+ String pluginGroup = pluginGroups.get( i ).trim();
+
+ if ( StringUtils.isBlank( pluginGroup ) )
+ {
+ addViolation( problems, Severity.ERROR, "pluginGroups.pluginGroup[" + i + "]", null,
+ "must not be empty" );
+ }
+ else if ( !pluginGroup.matches( ID_REGEX ) )
+ {
+ addViolation( problems, Severity.ERROR, "pluginGroups.pluginGroup[" + i + "]", null,
+ "must denote a valid group id and match the pattern " + ID_REGEX );
+ }
+ }
+ }
+
+ List<Server> servers = settings.getServers();
+
+ if ( servers != null )
+ {
+ Set<String> serverIds = new HashSet<String>();
+
+ for ( int i = 0; i < servers.size(); i++ )
+ {
+ Server server = servers.get( i );
+
+ validateStringNotEmpty( problems, "servers.server[" + i + "].id", server.getId(), null );
+
+ if ( !serverIds.add( server.getId() ) )
+ {
+ addViolation( problems, Severity.WARNING, "servers.server.id", null,
+ "must be unique but found duplicate server with id " + server.getId() );
+ }
+ }
+ }
+
+ List<Mirror> mirrors = settings.getMirrors();
+
+ if ( mirrors != null )
+ {
+ for ( Mirror mirror : mirrors )
+ {
+ validateStringNotEmpty( problems, "mirrors.mirror.id", mirror.getId(), mirror.getUrl() );
+
+ validateBannedCharacters( problems, "mirrors.mirror.id", Severity.WARNING, mirror.getId(), null,
+ ILLEGAL_REPO_ID_CHARS );
+
+ if ( "local".equals( mirror.getId() ) )
+ {
+ addViolation( problems, Severity.WARNING, "mirrors.mirror.id", null, "must not be 'local'"
+ + ", this identifier is reserved for the local repository"
+ + ", using it for other repositories will corrupt your repository metadata." );
+ }
+
+ validateStringNotEmpty( problems, "mirrors.mirror.url", mirror.getUrl(), mirror.getId() );
+
+ validateStringNotEmpty( problems, "mirrors.mirror.mirrorOf", mirror.getMirrorOf(), mirror.getId() );
+ }
+ }
+
+ List<Profile> profiles = settings.getProfiles();
+
+ if ( profiles != null )
+ {
+ Set<String> profileIds = new HashSet<String>();
+
+ for ( Profile profile : profiles )
+ {
+ if ( !profileIds.add( profile.getId() ) )
+ {
+ addViolation( problems, Severity.WARNING, "profiles.profile.id", null,
+ "must be unique but found duplicate profile with id " + profile.getId() );
+ }
+
+ String prefix = "profiles.profile[" + profile.getId() + "].";
+
+ validateRepositories( problems, profile.getRepositories(), prefix + "repositories.repository" );
+ validateRepositories( problems, profile.getPluginRepositories(), prefix
+ + "pluginRepositories.pluginRepository" );
+ }
+ }
+
+ List<Proxy> proxies = settings.getProxies();
+
+ if ( proxies != null )
+ {
+ Set<String> proxyIds = new HashSet<String>();
+
+ for ( Proxy proxy : proxies )
+ {
+ if ( !proxyIds.add( proxy.getId() ) )
+ {
+ addViolation( problems, Severity.WARNING, "proxies.proxy.id", null,
+ "must be unique but found duplicate proxy with id " + proxy.getId() );
+ }
+ validateStringNotEmpty( problems, "proxies.proxy.host", proxy.getHost(), proxy.getId() );
+ }
+ }
+ }
+
+ private void validateRepositories( SettingsProblemCollector problems, List<Repository> repositories, String prefix )
+ {
+ Set<String> repoIds = new HashSet<String>();
+
+ for ( Repository repository : repositories )
+ {
+ validateStringNotEmpty( problems, prefix + ".id", repository.getId(), repository.getUrl() );
+
+ validateBannedCharacters( problems, prefix + ".id", Severity.WARNING, repository.getId(), null,
+ ILLEGAL_REPO_ID_CHARS );
+
+ if ( "local".equals( repository.getId() ) )
+ {
+ addViolation( problems, Severity.WARNING, prefix + ".id", null, "must not be 'local'"
+ + ", this identifier is reserved for the local repository"
+ + ", using it for other repositories will corrupt your repository metadata." );
+ }
+
+ if ( !repoIds.add( repository.getId() ) )
+ {
+ addViolation( problems, Severity.WARNING, prefix + ".id", null,
+ "must be unique but found duplicate repository with id " + repository.getId() );
+ }
+
+ validateStringNotEmpty( problems, prefix + ".url", repository.getUrl(), repository.getId() );
+
+ if ( "legacy".equals( repository.getLayout() ) )
+ {
+ addViolation( problems, Severity.WARNING, prefix + ".layout", repository.getId(),
+ "uses the unsupported value 'legacy', artifact resolution might fail." );
+ }
+ }
+ }
+
+ // ----------------------------------------------------------------------
+ // Field validation
+ // ----------------------------------------------------------------------
+
+ /**
+ * Asserts:
+ * <p/>
+ * <ul>
+ * <li><code>string.length != null</code>
+ * <li><code>string.length > 0</code>
+ * </ul>
+ */
+ private static boolean validateStringNotEmpty( SettingsProblemCollector problems, String fieldName, String string,
+ String sourceHint )
+ {
+ if ( !validateNotNull( problems, fieldName, string, sourceHint ) )
+ {
+ return false;
+ }
+
+ if ( string.length() > 0 )
+ {
+ return true;
+ }
+
+ addViolation( problems, Severity.ERROR, fieldName, sourceHint, "is missing" );
+
+ return false;
+ }
+
+ /**
+ * Asserts:
+ * <p/>
+ * <ul>
+ * <li><code>string != null</code>
+ * </ul>
+ */
+ private static boolean validateNotNull( SettingsProblemCollector problems, String fieldName, Object object,
+ String sourceHint )
+ {
+ if ( object != null )
+ {
+ return true;
+ }
+
+ addViolation( problems, Severity.ERROR, fieldName, sourceHint, "is missing" );
+
+ return false;
+ }
+
+ private static boolean validateBannedCharacters( SettingsProblemCollector problems, String fieldName,
+ Severity severity, String string, String sourceHint,
+ String banned )
+ {
+ if ( string != null )
+ {
+ for ( int i = string.length() - 1; i >= 0; i-- )
+ {
+ if ( banned.indexOf( string.charAt( i ) ) >= 0 )
+ {
+ addViolation( problems, severity, fieldName, sourceHint,
+ "must not contain any of these characters " + banned + " but found "
+ + string.charAt( i ) );
+ return false;
+ }
+ }
+ }
+
+ return true;
+ }
+
+ private static void addViolation( SettingsProblemCollector problems, Severity severity, String fieldName,
+ String sourceHint, String message )
+ {
+ StringBuilder buffer = new StringBuilder( 256 );
+ buffer.append( '\'' ).append( fieldName ).append( '\'' );
+
+ if ( sourceHint != null )
+ {
+ buffer.append( " for " ).append( sourceHint );
+ }
+
+ buffer.append( ' ' ).append( message );
+
+ problems.add( severity, buffer.toString(), -1, -1, null );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/validation/SettingsValidator.java b/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/validation/SettingsValidator.java
new file mode 100644
index 00000000..79745eca
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/main/java/org/apache/maven/settings/validation/SettingsValidator.java
@@ -0,0 +1,41 @@
+package org.apache.maven.settings.validation;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.settings.Settings;
+import org.apache.maven.settings.building.SettingsProblemCollector;
+
+/**
+ * Validate a model settings
+ *
+ * @author Milos Kleint
+ */
+public interface SettingsValidator
+{
+
+ /**
+ * Validate the specified settings.
+ *
+ * @param settings The settings to validate, must not be {@code null}.
+ * @param problems The container used to collect problems that were encountered, must not be {@code null}.
+ */
+ void validate( Settings settings, SettingsProblemCollector problems );
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/site/site.xml b/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/site/site.xml
new file mode 100644
index 00000000..3a16bf98
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/site/site.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project xmlns="http://maven.apache.org/DECORATION/1.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/DECORATION/1.0.0 http://maven.apache.org/xsd/decoration-1.0.0.xsd">
+ <body>
+ <menu name="Overview">
+ <item name="Introduction" href="index.html"/>
+ <item name="JavaDocs" href="apidocs/index.html"/>
+ <item name="Source Xref" href="xref/index.html"/>
+ <!--item name="FAQ" href="faq.html"/-->
+ </menu>
+
+ <menu ref="parent"/>
+ <menu ref="reports"/>
+ </body>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/test/java/org/apache/maven/settings/building/DefaultSettingsBuilderFactoryTest.java b/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/test/java/org/apache/maven/settings/building/DefaultSettingsBuilderFactoryTest.java
new file mode 100644
index 00000000..722abf32
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/test/java/org/apache/maven/settings/building/DefaultSettingsBuilderFactoryTest.java
@@ -0,0 +1,53 @@
+package org.apache.maven.settings.building;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+
+import junit.framework.TestCase;
+
+/**
+ * @author Benjamin Bentmann
+ */
+public class DefaultSettingsBuilderFactoryTest
+ extends TestCase
+{
+
+ private File getSettings( String name )
+ {
+ return new File( "src/test/resources/settings/factory/" + name + ".xml" ).getAbsoluteFile();
+ }
+
+ public void testCompleteWiring()
+ throws Exception
+ {
+ SettingsBuilder builder = new DefaultSettingsBuilderFactory().newInstance();
+ assertNotNull( builder );
+
+ DefaultSettingsBuildingRequest request = new DefaultSettingsBuildingRequest();
+ request.setSystemProperties( System.getProperties() );
+ request.setUserSettingsFile( getSettings( "simple" ) );
+
+ SettingsBuildingResult result = builder.build( request );
+ assertNotNull( result );
+ assertNotNull( result.getEffectiveSettings() );
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/test/java/org/apache/maven/settings/validation/DefaultSettingsValidatorTest.java b/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/test/java/org/apache/maven/settings/validation/DefaultSettingsValidatorTest.java
new file mode 100644
index 00000000..8c7f21d8
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/test/java/org/apache/maven/settings/validation/DefaultSettingsValidatorTest.java
@@ -0,0 +1,244 @@
+package org.apache.maven.settings.validation;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.List;
+
+import junit.framework.TestCase;
+
+import org.apache.maven.settings.Mirror;
+import org.apache.maven.settings.Profile;
+import org.apache.maven.settings.Proxy;
+import org.apache.maven.settings.Repository;
+import org.apache.maven.settings.Server;
+import org.apache.maven.settings.Settings;
+import org.apache.maven.settings.building.SettingsProblemCollector;
+import org.apache.maven.settings.building.SettingsProblem.Severity;
+
+/**
+ * @author mkleint
+ */
+public class DefaultSettingsValidatorTest
+ extends TestCase
+{
+
+ private DefaultSettingsValidator validator;
+
+ protected void setUp()
+ throws Exception
+ {
+ super.setUp();
+
+ validator = new DefaultSettingsValidator();
+ }
+
+ protected void tearDown()
+ throws Exception
+ {
+ validator = null;
+
+ super.tearDown();
+ }
+
+ private void assertContains( String msg, String substring )
+ {
+ assertTrue( "\"" + substring + "\" was not found in: " + msg, msg.contains( substring ) );
+ }
+
+ public void testValidate()
+ {
+ Settings model = new Settings();
+ Profile prof = new Profile();
+ prof.setId( "xxx" );
+ model.addProfile( prof );
+ SimpleProblemCollector problems = new SimpleProblemCollector();
+ validator.validate( model, problems );
+ assertEquals( 0, problems.messages.size() );
+
+ Repository repo = new Repository();
+ prof.addRepository( repo );
+ problems = new SimpleProblemCollector();
+ validator.validate( model, problems );
+ assertEquals( 2, problems.messages.size() );
+
+ repo.setUrl( "http://xxx.xxx.com" );
+ problems = new SimpleProblemCollector();
+ validator.validate( model, problems );
+ assertEquals( 1, problems.messages.size() );
+
+ repo.setId( "xxx" );
+ problems = new SimpleProblemCollector();
+ validator.validate( model, problems );
+ assertEquals( 0, problems.messages.size() );
+ }
+
+ public void testValidateMirror()
+ throws Exception
+ {
+ Settings settings = new Settings();
+ Mirror mirror = new Mirror();
+ mirror.setId( "local" );
+ settings.addMirror( mirror );
+ mirror = new Mirror();
+ mirror.setId( "illegal\\:/chars" );
+ mirror.setUrl( "http://void" );
+ mirror.setMirrorOf( "void" );
+ settings.addMirror( mirror );
+
+ SimpleProblemCollector problems = new SimpleProblemCollector();
+ validator.validate( settings, problems );
+ assertEquals( 4, problems.messages.size() );
+ assertContains( problems.messages.get( 0 ), "'mirrors.mirror.id' must not be 'local'" );
+ assertContains( problems.messages.get( 1 ), "'mirrors.mirror.url' for local is missing" );
+ assertContains( problems.messages.get( 2 ), "'mirrors.mirror.mirrorOf' for local is missing" );
+ assertContains( problems.messages.get( 3 ), "'mirrors.mirror.id' must not contain any of these characters" );
+ }
+
+ public void testValidateRepository()
+ throws Exception
+ {
+ Profile profile = new Profile();
+ Repository repo = new Repository();
+ repo.setId( "local" );
+ profile.addRepository( repo );
+ repo = new Repository();
+ repo.setId( "illegal\\:/chars" );
+ repo.setUrl( "http://void" );
+ profile.addRepository( repo );
+ Settings settings = new Settings();
+ settings.addProfile( profile );
+
+ SimpleProblemCollector problems = new SimpleProblemCollector();
+ validator.validate( settings, problems );
+ assertEquals( 3, problems.messages.size() );
+ assertContains( problems.messages.get( 0 ),
+ "'profiles.profile[default].repositories.repository.id' must not be 'local'" );
+ assertContains( problems.messages.get( 1 ),
+ "'profiles.profile[default].repositories.repository.url' for local is missing" );
+ assertContains( problems.messages.get( 2 ),
+ "'profiles.profile[default].repositories.repository.id' must not contain any of these characters" );
+ }
+
+ public void testValidateUniqueServerId()
+ throws Exception
+ {
+ Settings settings = new Settings();
+ Server server1 = new Server();
+ server1.setId( "test" );
+ settings.addServer( server1 );
+ Server server2 = new Server();
+ server2.setId( "test" );
+ settings.addServer( server2 );
+
+ SimpleProblemCollector problems = new SimpleProblemCollector();
+ validator.validate( settings, problems );
+ assertEquals( 1, problems.messages.size() );
+ assertContains( problems.messages.get( 0 ),
+ "'servers.server.id' must be unique but found duplicate server with id test" );
+ }
+
+ public void testValidateUniqueProfileId()
+ throws Exception
+ {
+ Settings settings = new Settings();
+ Profile profile1 = new Profile();
+ profile1.setId( "test" );
+ settings.addProfile( profile1 );
+ Profile profile2 = new Profile();
+ profile2.setId( "test" );
+ settings.addProfile( profile2 );
+
+ SimpleProblemCollector problems = new SimpleProblemCollector();
+ validator.validate( settings, problems );
+ assertEquals( 1, problems.messages.size() );
+ assertContains( problems.messages.get( 0 ),
+ "'profiles.profile.id' must be unique but found duplicate profile with id test" );
+ }
+
+ public void testValidateUniqueRepositoryId()
+ throws Exception
+ {
+ Settings settings = new Settings();
+ Profile profile = new Profile();
+ profile.setId( "pro" );
+ settings.addProfile( profile );
+ Repository repo1 = new Repository();
+ repo1.setUrl( "http://apache.org/" );
+ repo1.setId( "test" );
+ profile.addRepository( repo1 );
+ Repository repo2 = new Repository();
+ repo2.setUrl( "http://apache.org/" );
+ repo2.setId( "test" );
+ profile.addRepository( repo2 );
+
+ SimpleProblemCollector problems = new SimpleProblemCollector();
+ validator.validate( settings, problems );
+ assertEquals( 1, problems.messages.size() );
+ assertContains( problems.messages.get( 0 ), "'profiles.profile[pro].repositories.repository.id' must be unique"
+ + " but found duplicate repository with id test" );
+ }
+
+ public void testValidateUniqueProxyId()
+ throws Exception
+ {
+ Settings settings = new Settings();
+ Proxy proxy = new Proxy();
+ String id = null;
+ proxy.setId( id );
+ proxy.setHost("www.example.com");
+ settings.addProxy( proxy );
+ settings.addProxy( proxy );
+
+ SimpleProblemCollector problems = new SimpleProblemCollector();
+ validator.validate( settings, problems );
+ assertEquals( 1, problems.messages.size() );
+ assertContains( problems.messages.get( 0 ), "'proxies.proxy.id' must be unique"
+ + " but found duplicate proxy with id " + id );
+
+ }
+
+ public void testValidateProxy()
+ throws Exception
+ {
+ Settings settings = new Settings();
+ Proxy proxy1 = new Proxy();
+ settings.addProxy( proxy1 );
+
+ SimpleProblemCollector problems = new SimpleProblemCollector();
+ validator.validate( settings, problems );
+ assertEquals( 1, problems.messages.size() );
+ assertContains( problems.messages.get( 0 ), "'proxies.proxy.host' for default is missing" );
+ }
+
+ private static class SimpleProblemCollector
+ implements SettingsProblemCollector
+ {
+
+ public List<String> messages = new ArrayList<String>();
+
+ public void add( Severity severity, String message, int line, int column, Exception cause )
+ {
+ messages.add( message );
+ }
+
+ }
+
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/test/resources/settings/factory/simple.xml b/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/test/resources/settings/factory/simple.xml
new file mode 100644
index 00000000..ea664bac
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-settings-builder/src/test/resources/settings/factory/simple.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<settings>
+ <localRepository>${user.home}/.m2/repository</localRepository>
+</settings>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-settings/pom.xml b/framework/src/maven/apache-maven-3.3.3/maven-settings/pom.xml
new file mode 100644
index 00000000..e5909a72
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-settings/pom.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven</artifactId>
+ <version>3.3.3</version>
+ </parent>
+
+ <artifactId>maven-settings</artifactId>
+
+ <name>Maven Settings</name>
+ <description>Maven Settings model.</description>
+
+ <scm><!-- remove when git scm url format can accept artifact-id at the end, as automatically inherited -->
+ <connection>scm:git:https://git-wip-us.apache.org/repos/asf/maven.git</connection>
+ <developerConnection>scm:git:https://git-wip-us.apache.org/repos/asf/maven.git</developerConnection>
+ <tag>maven-3.3.3</tag>
+ </scm>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-utils</artifactId>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.modello</groupId>
+ <artifactId>modello-maven-plugin</artifactId>
+ <configuration>
+ <version>1.1.0</version>
+ <models>
+ <model>src/main/mdo/settings.mdo</model>
+ </models>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-settings/src/main/java/org/apache/maven/settings/RuntimeInfo.java b/framework/src/maven/apache-maven-3.3.3/maven-settings/src/main/java/org/apache/maven/settings/RuntimeInfo.java
new file mode 100644
index 00000000..9020037f
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-settings/src/main/java/org/apache/maven/settings/RuntimeInfo.java
@@ -0,0 +1,55 @@
+package org.apache.maven.settings;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+
+/**
+ * To handle runtime informations like local repository or profiles.
+ *
+ */
+@Deprecated
+public class RuntimeInfo
+{
+ @SuppressWarnings( "checkstyle:constantname" )
+ public static final String userHome = System.getProperty( "user.home" );
+
+ @SuppressWarnings( "checkstyle:constantname" )
+ public static final File userMavenConfigurationHome = new File( userHome, ".m2" );
+
+ public static final File DEFAULT_USER_SETTINGS_FILE = new File( userMavenConfigurationHome, "settings.xml" );
+
+ private File settings;
+
+ public RuntimeInfo()
+ {
+ this.settings = DEFAULT_USER_SETTINGS_FILE;
+ }
+
+ public RuntimeInfo( File settings )
+ {
+ this.settings = settings;
+ }
+
+ public File getFile()
+ {
+ return settings;
+ }
+}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-settings/src/main/mdo/settings.mdo b/framework/src/maven/apache-maven-3.3.3/maven-settings/src/main/mdo/settings.mdo
new file mode 100644
index 00000000..4e43a466
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-settings/src/main/mdo/settings.mdo
@@ -0,0 +1,1077 @@
+<?xml version="1.0"?>
+
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+
+<model xmlns="http://modello.codehaus.org/MODELLO/1.4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://modello.codehaus.org/MODELLO/1.4.0 http://modello.codehaus.org/xsd/modello-1.4.0.xsd"
+ xml.namespace="http://maven.apache.org/SETTINGS/${version}"
+ xml.schemaLocation="http://maven.apache.org/xsd/settings-${version}.xsd">
+ <id>settings</id>
+ <name>Settings</name>
+ <description>
+ <![CDATA[
+ <p>This is a reference for the user-specific configuration for Maven.</p>
+ <p>Includes things that should not be distributed with the pom.xml file, such as developer identity, along with
+ local settings, like proxy information.</p>
+ <p>The default location for the settings file is <i>~/.m2/settings.xml</i></p>
+ <p>An XSD is available at:</p>
+ <ul>
+ <li><a href="http://maven.apache.org/xsd/settings-1.0.0.xsd">http://maven.apache.org/xsd/settings-1.0.0.xsd</a>.</li>
+ </ul>
+ ]]>
+ </description>
+ <defaults>
+ <default>
+ <key>package</key>
+ <value>org.apache.maven.settings</value>
+ </default>
+ </defaults>
+ <classes>
+ <class java.clone="deep">
+ <name>TrackableBase</name>
+ <version>1.0.0+</version>
+ <description>
+ common base class that contains code to track the source for
+ this instance (USER|GLOBAL)
+ </description>
+ <codeSegments>
+ <codeSegment>
+ <version>1.0.0+</version>
+ <code>
+ <![CDATA[
+ public static final String USER_LEVEL = "user-level";
+ public static final String GLOBAL_LEVEL = "global-level";
+
+ private String sourceLevel = USER_LEVEL;
+ private boolean sourceLevelSet = false;
+
+ public void setSourceLevel( String sourceLevel )
+ {
+ if ( sourceLevelSet )
+ {
+ throw new IllegalStateException( "Cannot reset sourceLevel attribute; it is already set to: " + sourceLevel );
+ }
+ else if ( !( USER_LEVEL.equals( sourceLevel ) || GLOBAL_LEVEL.equals( sourceLevel ) ) )
+ {
+ throw new IllegalArgumentException( "sourceLevel must be one of: {" + USER_LEVEL + "," + GLOBAL_LEVEL + "}" );
+ }
+ else
+ {
+ this.sourceLevel = sourceLevel;
+ this.sourceLevelSet = true;
+ }
+ }
+
+ public String getSourceLevel()
+ {
+ return sourceLevel;
+ }
+ ]]>
+ </code>
+ </codeSegment>
+ </codeSegments>
+ </class>
+ <class>
+ <name>IdentifiableBase</name>
+ <superClass>TrackableBase</superClass>
+ <version>1.0.0+</version>
+ <description>
+ <![CDATA[
+ Base class for <code>Mirror</code>, <code>Profile</code>, <code>Proxy</code> and <code>Server</code>.
+ ]]></description>
+ <fields>
+ <field>
+ <name>id</name>
+ <version>1.0.0+</version>
+ <type>String</type>
+ <defaultValue>default</defaultValue>
+ <required>true</required>
+ </field>
+ </fields>
+ </class>
+ <class rootElement="true" xml.tagName="settings">
+ <name>Settings</name>
+ <version>1.0.0+</version>
+ <superClass>TrackableBase</superClass>
+ <description>
+ Root element of the user configuration file.
+ </description>
+ <fields>
+ <field>
+ <name>localRepository</name>
+ <version>1.0.0+</version>
+ <required>true</required>
+ <description>
+ <![CDATA[
+ The local repository.<br /><b>Default value is:</b> <tt>${user.home}/.m2/repository</tt>
+ ]]>
+ </description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>interactiveMode</name>
+ <version>1.0.0+</version>
+ <description>
+ <![CDATA[
+ Whether Maven should attempt to interact with the user for input.
+ ]]>
+ </description>
+ <type>boolean</type>
+ <defaultValue>true</defaultValue>
+ </field>
+ <field>
+ <name>usePluginRegistry</name>
+ <version>1.0.0+</version>
+ <description>
+ <![CDATA[
+ Whether Maven should use the plugin-registry.xml file to manage plugin versions.
+ ]]>
+ </description>
+ <type>boolean</type>
+ <defaultValue>false</defaultValue>
+ </field>
+ <!-- [JC] Not ready to use yet, so I'm making if unavailable for now. -->
+ <!-- field>
+ <name>passwordStore</name>
+ <version>1.0.0+</version>
+ <required>false</required>
+ <description><![CDATA[The keystore used to store passwords.]]></description>
+ <type>String</type>
+ </field -->
+ <field>
+ <name>offline</name>
+ <version>1.0.0+</version>
+ <required>false</required>
+ <description>
+ <![CDATA[
+ Indicate whether maven should operate in offline mode full-time.
+ ]]>
+ </description>
+ <type>boolean</type>
+ <defaultValue>false</defaultValue>
+ </field>
+ <!-- [JC] Not ready to use yet, so I'm making if unavailable for now. -->
+ <!-- field>
+ <name>jdks</name>
+ <version>1.0.0+</version>
+ <description><![CDATA[
+ Configuration for different java environment profiles. One good use
+ for this might be to configure both JDK 1.4 and JDK 1.5 to work with
+ maven. Profiles will allow switching of entire java environments
+ based on the profile id, either in the defaults section below, or on
+ the command line.
+ ]]></description>
+ <association>
+ <type>Jdk</type>
+ <multiplicity>*</multiplicity>
+ </association>
+ </field -->
+ <field xdoc.separator="blank">
+ <name>proxies</name>
+ <version>1.0.0+</version>
+ <description>
+ <![CDATA[
+ Configuration for different proxy profiles. Multiple proxy profiles
+ might come in handy for anyone working from a notebook or other
+ mobile platform, to enable easy switching of entire proxy
+ configurations by simply specifying the profile id, again either from
+ the command line or from the defaults section below.
+ ]]>
+ </description>
+ <association>
+ <type>Proxy</type>
+ <multiplicity>*</multiplicity>
+ </association>
+ </field>
+ <field xdoc.separator="blank">
+ <name>servers</name>
+ <version>1.0.0+</version>
+ <description>
+ <![CDATA[
+ Configuration of server-specific settings, mainly authentication
+ method. This allows configuration of authentication on a per-server
+ basis.
+ ]]>
+ </description>
+ <association>
+ <type>Server</type>
+ <multiplicity>*</multiplicity>
+ </association>
+ </field>
+ <field xdoc.separator="blank">
+ <name>mirrors</name>
+ <version>1.0.0+</version>
+ <description>
+ Configuration of download mirrors for repositories.
+ </description>
+ <association>
+ <type>Mirror</type>
+ <multiplicity>*</multiplicity>
+ </association>
+ </field>
+ <field xdoc.separator="blank">
+ <name>profiles</name>
+ <version>1.0.0+</version>
+ <description>
+ <![CDATA[
+ Configuration of build profiles for adjusting the build
+ according to environmental parameters.
+ ]]>
+ </description>
+ <association>
+ <type>Profile</type>
+ <multiplicity>*</multiplicity>
+ </association>
+ </field>
+ <field xdoc.separator="blank">
+ <name>activeProfiles</name>
+ <version>1.0.0+</version>
+ <description>
+ <![CDATA[
+ List of manually-activated build profiles, specified in the order in which
+ they should be applied.
+ ]]>
+ </description>
+ <association>
+ <type>String</type>
+ <multiplicity>*</multiplicity>
+ </association>
+ </field>
+ <field>
+ <name>pluginGroups</name>
+ <version>1.0.0+</version>
+ <description>
+ List of groupIds to search for a plugin when that plugin
+ groupId is not explicitly provided.
+ </description>
+ <association>
+ <type>String</type>
+ <multiplicity>*</multiplicity>
+ </association>
+ </field>
+ </fields>
+ <codeSegments>
+ <codeSegment>
+ <version>1.0.0+</version>
+ <code>
+ <![CDATA[
+ public Boolean getInteractiveMode()
+ {
+ return Boolean.valueOf( isInteractiveMode() );
+ }
+
+ private Proxy activeProxy;
+
+ /**
+ * Reset the <code>activeProxy</code> field to <code>null</code>
+ */
+ public void flushActiveProxy()
+ {
+ this.activeProxy = null;
+ }
+
+ /**
+ * @return the first active proxy
+ */
+ public synchronized Proxy getActiveProxy()
+ {
+ if ( activeProxy == null )
+ {
+ java.util.List<Proxy> proxies = getProxies();
+ if ( proxies != null && !proxies.isEmpty() )
+ {
+ for ( Proxy proxy : proxies )
+ {
+ if ( proxy.isActive() )
+ {
+ activeProxy = proxy;
+ break;
+ }
+ }
+ }
+ }
+
+ return activeProxy;
+ }
+
+ public Server getServer( String serverId )
+ {
+ Server match = null;
+
+ java.util.List<Server> servers = getServers();
+ if ( servers != null && serverId != null )
+ {
+ for ( Server server : servers )
+ {
+ if ( serverId.equals( server.getId() ) )
+ {
+ match = server;
+ break;
+ }
+ }
+ }
+
+ return match;
+ }
+
+ @Deprecated
+ public Mirror getMirrorOf( String repositoryId )
+ {
+ Mirror match = null;
+
+ java.util.List<Mirror> mirrors = getMirrors();
+ if ( mirrors != null && repositoryId != null )
+ {
+ for ( Mirror mirror : mirrors )
+ {
+ if ( repositoryId.equals( mirror.getMirrorOf() ) )
+ {
+ match = mirror;
+ break;
+ }
+ }
+ }
+
+ return match;
+ }
+
+ private java.util.Map<String, Profile> profileMap;
+
+ /**
+ * Reset the <code>profileMap</code> field to <code>null</code>
+ */
+ public void flushProfileMap()
+ {
+ this.profileMap = null;
+ }
+
+ /**
+ * @return a Map of profiles field with <code>Profile#getId()</code> as key
+ * @see org.apache.maven.settings.Profile#getId()
+ */
+ public java.util.Map<String, Profile> getProfilesAsMap()
+ {
+ if ( profileMap == null )
+ {
+ profileMap = new java.util.LinkedHashMap<String, Profile>();
+
+ if ( getProfiles() != null )
+ {
+ for ( Profile profile : getProfiles() )
+ {
+ profileMap.put( profile.getId(), profile );
+ }
+ }
+ }
+
+ return profileMap;
+ }
+ ]]>
+ </code>
+ </codeSegment>
+ </codeSegments>
+ </class>
+ <!-- @todo: is any of this too CVS specific? Investigate other SCMs -->
+ <!-- [JC] Commenting out until we're ready to use it... -->
+ <!-- class>
+ <name>Jdk</name>
+ <version>1.0.0+</version>
+ <superClass>TrackableBase</superClass>
+ <description><![CDATA[Describes one Java environment]]></description>
+ <fields>
+ <field>
+ <name>active</name>
+ <version>1.0.0+</version>
+ <required>false</required>
+ <defaultValue>false</defaultValue>
+ <description><![CDATA[Whether this JDK is the active one.]]></description>
+ <type>boolean</type>
+ </field>
+ <field>
+ <name>version</name>
+ <version>1.0.0+</version>
+ <required>true</required>
+ <description><![CDATA[The JDK major version (eg. '1.4').]]></description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>javaHome</name>
+ <version>1.0.0+</version>
+ <required>true</required>
+ <description><![CDATA[The JDK home.]]></description>
+ <type>String</type>
+ </field>
+ </fields>
+ </class -->
+ <class>
+ <name>Proxy</name>
+ <version>1.0.0+</version>
+ <superClass>IdentifiableBase</superClass>
+ <description>
+ <![CDATA[
+ The <code>&lt;proxy&gt;</code> element contains informations required to a proxy settings.
+ ]]></description>
+ <fields>
+ <field>
+ <name>active</name>
+ <version>1.0.0+</version>
+ <required>false</required>
+ <defaultValue>true</defaultValue>
+ <description>
+ <![CDATA[
+ Whether this proxy configuration is the active one.
+ ]]>
+ </description>
+ <type>boolean</type>
+ </field>
+ <field>
+ <name>protocol</name>
+ <version>1.0.0+</version>
+ <description>
+ <![CDATA[
+ The proxy protocol.
+ ]]>
+ </description>
+ <type>String</type>
+ <defaultValue>http</defaultValue>
+ </field>
+ <field>
+ <name>username</name>
+ <version>1.0.0+</version>
+ <description>
+ <![CDATA[
+ The proxy user.
+ ]]>
+ </description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>password</name>
+ <version>1.0.0+</version>
+ <description>
+ <![CDATA[
+ The proxy password.
+ ]]>
+ </description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>port</name>
+ <version>1.0.0+</version>
+ <description>
+ <![CDATA[
+ The proxy port.
+ ]]>
+ </description>
+ <type>int</type>
+ <defaultValue>8080</defaultValue>
+ </field>
+ <field>
+ <name>host</name>
+ <version>1.0.0+</version>
+ <description>
+ <![CDATA[
+ The proxy host.
+ ]]>
+ </description>
+ <type>String</type>
+ <required>true</required>
+ </field>
+ <field>
+ <name>nonProxyHosts</name>
+ <version>1.0.0+</version>
+ <description>
+ <![CDATA[
+ The list of non-proxied hosts (delimited by |).
+ ]]>
+ </description>
+ <type>String</type>
+ </field>
+ </fields>
+ </class>
+ <class>
+ <name>Server</name>
+ <version>1.0.0+</version>
+ <superClass>IdentifiableBase</superClass>
+ <description>
+ <![CDATA[
+ The <code>&lt;server&gt;</code> element contains informations required to a server settings.
+ ]]></description>
+ <fields>
+ <field>
+ <name>username</name>
+ <version>1.0.0+</version>
+ <description>
+ <![CDATA[
+ The username used to authenticate.
+ ]]>
+ </description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>password</name>
+ <version>1.0.0+</version>
+ <description>
+ <![CDATA[
+ The password used in conjunction with the username to authenticate.
+ ]]>
+ </description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>privateKey</name>
+ <version>1.0.0+</version>
+ <description>
+ <![CDATA[
+ The private key location used to authenticate.
+ ]]>
+ </description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>passphrase</name>
+ <version>1.0.0+</version>
+ <description>
+ <![CDATA[
+ The passphrase used in conjunction with the privateKey to authenticate.
+ ]]>
+ </description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>filePermissions</name>
+ <version>1.0.0+</version>
+ <description>
+ <![CDATA[
+ The permissions for files when they are created.
+ ]]>
+ </description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>directoryPermissions</name>
+ <version>1.0.0+</version>
+ <description>
+ <![CDATA[
+ The permissions for directories when they are created.
+ ]]>
+ </description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>configuration</name>
+ <type>DOM</type>
+ <description>
+ <![CDATA[
+ Extra configuration for the transport layer.
+ ]]>
+ </description>
+ </field>
+ </fields>
+ </class>
+ <class>
+ <name>Mirror</name>
+ <version>1.0.0+</version>
+ <superClass>IdentifiableBase</superClass>
+ <description>
+ A download mirror for a given repository.
+ </description>
+ <fields>
+ <field>
+ <name>mirrorOf</name>
+ <required>true</required>
+ <version>1.0.0+</version>
+ <type>String</type>
+ <description>
+ The server ID of the repository being mirrored, eg
+ "central". This MUST NOT match the mirror id.
+ </description>
+ </field>
+ <field>
+ <name>name</name>
+ <required>false</required>
+ <version>1.0.0+</version>
+ <type>String</type>
+ <description>
+ The optional name that describes the mirror.
+ </description>
+ </field>
+ <field>
+ <name>url</name>
+ <required>true</required>
+ <version>1.0.0+</version>
+ <type>String</type>
+ <description>The URL of the mirror repository.</description>
+ </field>
+ <field>
+ <name>layout</name>
+ <version>1.1.0+</version>
+ <type>String</type>
+ <defaultValue>default</defaultValue>
+ <description>The layout of the mirror repository. Since Maven 3.</description>
+ </field>
+ <field>
+ <name>mirrorOfLayouts</name>
+ <version>1.1.0+</version>
+ <type>String</type>
+ <defaultValue>default,legacy</defaultValue>
+ <description>
+ The layouts of repositories being mirrored. This value can be used to restrict the usage
+ of the mirror to repositories with a matching layout (apart from a matching id). Since Maven 3.
+ </description>
+ </field>
+ </fields>
+ <codeSegments>
+ <codeSegment>
+ <version>1.0.0+</version>
+ <code>
+ <![CDATA[
+
+ public String toString()
+ {
+ StringBuilder sb = new StringBuilder( 128 );
+ sb.append( "Mirror[" );
+ sb.append( "id=" ).append( this.getId() );
+ sb.append( ",mirrorOf=" ).append( mirrorOf );
+ sb.append( ",url=" ).append( this.url );
+ sb.append( ",name=" ).append( this.name );
+ sb.append( "]" );
+ return sb.toString();
+ }
+ ]]>
+ </code>
+ </codeSegment>
+ </codeSegments>
+ </class>
+ <!-- Profile support -->
+ <class>
+ <name>Profile</name>
+ <version>1.0.0+</version>
+ <superClass>IdentifiableBase</superClass>
+ <description>
+ <![CDATA[
+ Modifications to the build process which is keyed on some
+ sort of environmental parameter.
+ ]]>
+ </description>
+ <fields>
+ <field>
+ <name>activation</name>
+ <version>1.0.0+</version>
+ <description>
+ <![CDATA[
+ The conditional logic which will automatically
+ trigger the inclusion of this profile.
+ ]]>
+ </description>
+ <association>
+ <type>Activation</type>
+ </association>
+ </field>
+ <field>
+ <name>properties</name>
+ <description>
+ <![CDATA[
+ Extended configuration specific to this profile goes here.
+ Contents take the form of
+ <code>&lt;property.name&gt;property.value&lt;/property.name&gt;</code>
+ ]]>
+ </description>
+ <type>Properties</type>
+ <association xml.mapStyle="inline">
+ <type>String</type>
+ <multiplicity>*</multiplicity>
+ </association>
+ </field>
+ <field xdoc.separator="blank">
+ <name>repositories</name>
+ <version>1.0.0+</version>
+ <description>
+ <![CDATA[
+ The lists of the remote repositories.
+ ]]>
+ </description>
+ <association>
+ <type>Repository</type>
+ <multiplicity>*</multiplicity>
+ </association>
+ </field>
+ <field>
+ <name>pluginRepositories</name>
+ <version>1.0.0+</version>
+ <description>
+ <![CDATA[
+ The lists of the remote repositories for discovering plugins.
+ ]]>
+ </description>
+ <association>
+ <type>Repository</type>
+ <multiplicity>*</multiplicity>
+ </association>
+ <comment>
+ <![CDATA[
+ This may be removed or relocated in the near
+ future. It is undecided whether plugins really need a remote
+ repository set of their own.
+ ]]>
+ </comment>
+ </field>
+ </fields>
+ </class>
+ <class java.clone="deep">
+ <name>Activation</name>
+ <version>1.0.0+</version>
+ <description>
+ <![CDATA[
+ The conditions within the build runtime environment which will trigger
+ the automatic inclusion of the parent build profile.
+ ]]>
+ </description>
+ <fields>
+ <field>
+ <name>activeByDefault</name>
+ <version>1.0.0+</version>
+ <type>boolean</type>
+ <description>
+ Flag specifying whether this profile is active as a default.
+ </description>
+ </field>
+ <field>
+ <name>jdk</name>
+ <version>1.0.0+</version>
+ <type>String</type>
+ <description>
+ <![CDATA[
+ Specifies that this profile will be activated when a matching JDK is detected.
+ ]]>
+ </description>
+ </field>
+ <field>
+ <name>os</name>
+ <version>1.0.0+</version>
+ <description>
+ <![CDATA[
+ Specifies that this profile will be activated when matching OS attributes are detected.
+ ]]>
+ </description>
+ <association>
+ <type>ActivationOS</type>
+ </association>
+ </field>
+ <field>
+ <name>property</name>
+ <version>1.0.0+</version>
+ <description>
+ <![CDATA[
+ Specifies that this profile will be activated when this System property is specified.
+ ]]>
+ </description>
+ <association>
+ <type>ActivationProperty</type>
+ </association>
+ </field>
+ <field>
+ <name>file</name>
+ <version>1.0.0+</version>
+ <description>
+ <![CDATA[
+ Specifies that this profile will be activated based on existence of a file.
+ ]]>
+ </description>
+ <association>
+ <type>ActivationFile</type>
+ </association>
+ </field>
+ </fields>
+ </class>
+
+ <!-- TODO: reproduced from maven-model/maven.mdo, instead should inherit code and link to external docs -->
+ <class java.clone="deep">
+ <name>RepositoryBase</name>
+ <version>1.0.0+</version>
+ <description>
+ <![CDATA[
+ Repository contains the information needed
+ for establishing connections with remote repoistory
+ ]]>
+ </description>
+ <fields>
+ <field>
+ <name>id</name>
+ <version>1.0.0+</version>
+ <description>
+ <![CDATA[
+ A unique identifier for a repository.
+ ]]>
+ </description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>name</name>
+ <version>1.0.0+</version>
+ <description>
+ <![CDATA[
+ Human readable name of the repository.
+ ]]>
+ </description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>url</name>
+ <version>1.0.0+</version>
+ <description>
+ <![CDATA[
+ The url of the repository.
+ ]]>
+ </description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>layout</name>
+ <version>1.0.0+</version>
+ <description>
+ The type of layout this repository uses for locating and
+ storing artifacts - can be "legacy" or "default".
+ </description>
+ <type>String</type>
+ <defaultValue>default</defaultValue>
+ </field>
+ </fields>
+ <codeSegments>
+ <codeSegment>
+ <version>1.0.0+</version>
+ <code>
+ <![CDATA[
+ /**
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ public boolean equals( Object obj )
+ {
+ RepositoryBase other = (RepositoryBase) obj;
+
+ boolean retValue = false;
+
+ if ( id != null )
+ {
+ retValue = id.equals( other.id );
+ }
+
+ return retValue;
+ }
+ ]]>
+ </code>
+ </codeSegment>
+ </codeSegments>
+ </class>
+
+ <class>
+ <name>Repository</name>
+ <superClass>RepositoryBase</superClass>
+ <version>1.0.0+</version>
+ <description>
+ Repository contains the information needed for establishing
+ connections with remote repository
+ </description>
+ <fields>
+ <field>
+ <name>releases</name>
+ <version>1.0.0+</version>
+ <description>
+ How to handle downloading of releases from this repository
+ </description>
+ <association>
+ <type>RepositoryPolicy</type>
+ </association>
+ </field>
+ <field>
+ <name>snapshots</name>
+ <version>1.0.0+</version>
+ <description>
+ How to handle downloading of snapshots from this repository
+ </description>
+ <association>
+ <type>RepositoryPolicy</type>
+ </association>
+ </field>
+ </fields>
+ <!-- prevent Modello generation of an incorrect equals method. Could be avoided by using <identity/> tags to mark ID as the only identity field -->
+ <codeSegments>
+ <codeSegment>
+ <version>1.0.0+</version>
+ <code>
+ <![CDATA[
+ /**
+ * @see org.apache.maven.settings.RepositoryBase#equals(java.lang.Object)
+ */
+ public boolean equals( Object obj )
+ {
+ return super.equals( obj );
+ }
+ ]]>
+ </code>
+ </codeSegment>
+ </codeSegments>
+ </class>
+
+ <class java.clone="deep">
+ <name>RepositoryPolicy</name>
+ <version>1.0.0+</version>
+ <description>Download policy</description>
+ <fields>
+ <field>
+ <name>enabled</name>
+ <version>1.0.0+</version>
+ <description>
+ Whether to use this repository for downloading this type of
+ artifact.
+ </description>
+ <type>boolean</type>
+ <defaultValue>true</defaultValue>
+ </field>
+ <field>
+ <name>updatePolicy</name>
+ <version>1.0.0+</version>
+ <description>
+ The frequency for downloading updates - can be "always",
+ "daily" (default), "interval:XXX" (in minutes) or "never"
+ (only if it doesn't exist locally).
+ </description>
+ <type>String</type>
+ </field>
+ <field>
+ <name>checksumPolicy</name>
+ <version>1.0.0+</version>
+ <description>
+ What to do when verification of an artifact checksum fails -
+ warn, fail, etc. Valid values are "fail" or "warn".
+ </description>
+ <type>String</type>
+ </field>
+ </fields>
+ </class>
+
+ <class java.clone="deep">
+ <name>ActivationProperty</name>
+ <version>1.0.0+</version>
+ <description>
+ <![CDATA[
+ This is the property specification used to activate a profile. If the value field is empty,
+ then the existence of the named property will activate the profile, otherwise it does a case-sensitive
+ match against the property value as well.
+ ]]>
+ </description>
+ <fields>
+ <field>
+ <name>name</name>
+ <version>1.0.0+</version>
+ <type>String</type>
+ <required>true</required>
+ <description>
+ The name of the property to be used to activate a profile.
+ </description>
+ </field>
+ <field>
+ <name>value</name>
+ <version>1.0.0+</version>
+ <type>String</type>
+ <description>
+ The value of the property to be used to activate a profile.
+ </description>
+ </field>
+ </fields>
+ </class>
+ <class java.clone="deep">
+ <name>ActivationOS</name>
+ <version>1.0.0+</version>
+ <description>
+ <![CDATA[
+ This is an activator which will detect an operating system's attributes in order to activate
+ its profile.
+ ]]>
+ </description>
+ <fields>
+ <field>
+ <name>name</name>
+ <version>1.0.0+</version>
+ <type>String</type>
+ <description>
+ The name of the OS to be used to activate a profile.
+ </description>
+ </field>
+ <field>
+ <name>family</name>
+ <version>1.0.0+</version>
+ <type>String</type>
+ <description>
+ The general family of the OS to be used to activate a
+ profile (e.g. 'windows')
+ </description>
+ </field>
+ <field>
+ <name>arch</name>
+ <version>1.0.0+</version>
+ <type>String</type>
+ <description>
+ The architecture of the OS to be used to activate a profile.
+ </description>
+ </field>
+ <field>
+ <name>version</name>
+ <version>1.0.0+</version>
+ <type>String</type>
+ <description>
+ The version of the OS to be used to activate a profile.
+ </description>
+ </field>
+ </fields>
+ </class>
+ <class java.clone="deep">
+ <name>ActivationFile</name>
+ <version>1.0.0+</version>
+ <description>
+ <![CDATA[
+ This is the file specification used to activate a profile. The missing value will be a the location
+ of a file that needs to exist, and if it doesn't the profile must run. On the other hand exists will test
+ for the existence of the file and if it is there will run the profile.
+ ]]>
+ </description>
+ <fields>
+ <field>
+ <name>missing</name>
+ <version>1.0.0+</version>
+ <type>String</type>
+ <description>
+ The name of the file that should be missing to activate a
+ profile.
+ </description>
+ </field>
+ <field>
+ <name>exists</name>
+ <version>1.0.0+</version>
+ <type>String</type>
+ <description>
+ The name of the file that should exist to activate a profile.
+ </description>
+ </field>
+ </fields>
+ </class>
+ <!-- /BuildProfile support -->
+ </classes>
+</model>
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-settings/src/site/apt/index.apt b/framework/src/maven/apache-maven-3.3.3/maven-settings/src/site/apt/index.apt
new file mode 100644
index 00000000..6e404e83
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-settings/src/site/apt/index.apt
@@ -0,0 +1,36 @@
+~~ Licensed to the Apache Software Foundation (ASF) under one
+~~ or more contributor license agreements. See the NOTICE file
+~~ distributed with this work for additional information
+~~ regarding copyright ownership. The ASF licenses this file
+~~ to you under the Apache License, Version 2.0 (the
+~~ "License"); you may not use this file except in compliance
+~~ with the License. You may obtain a copy of the License at
+~~
+~~ http://www.apache.org/licenses/LICENSE-2.0
+~~
+~~ Unless required by applicable law or agreed to in writing,
+~~ software distributed under the License is distributed on an
+~~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+~~ KIND, either express or implied. See the License for the
+~~ specific language governing permissions and limitations
+~~ under the License.
+
+ -----
+ Introduction
+ -----
+ Vincent Siveton
+ -----
+ 2006-11-04
+ -----
+
+Maven Settings Model
+
+ This is strictly the model for Maven settings.
+
+ The following are generated from this model:
+
+ * {{{./apidocs/index.html}Java sources}} with Reader and Writers for the Xpp3 XML parser
+
+ * A {{{./settings.html}Descriptor Reference}}
+
+ * An {{{http://maven.apache.org/xsd/settings-1.0.0.xsd}XSD}}
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-settings/src/site/site.xml b/framework/src/maven/apache-maven-3.3.3/maven-settings/src/site/site.xml
new file mode 100644
index 00000000..3a16bf98
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-settings/src/site/site.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project xmlns="http://maven.apache.org/DECORATION/1.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/DECORATION/1.0.0 http://maven.apache.org/xsd/decoration-1.0.0.xsd">
+ <body>
+ <menu name="Overview">
+ <item name="Introduction" href="index.html"/>
+ <item name="JavaDocs" href="apidocs/index.html"/>
+ <item name="Source Xref" href="xref/index.html"/>
+ <!--item name="FAQ" href="faq.html"/-->
+ </menu>
+
+ <menu ref="parent"/>
+ <menu ref="reports"/>
+ </body>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/pom.xml b/framework/src/maven/apache-maven-3.3.3/pom.xml
new file mode 100644
index 00000000..6812e823
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/pom.xml
@@ -0,0 +1,654 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+ <!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to you under the Apache License, Version
+ 2.0 (the "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0 Unless required by
+ applicable law or agreed to in writing, software distributed under
+ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
+ OR CONDITIONS OF ANY KIND, either express or implied. See the
+ License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-parent</artifactId>
+ <version>26</version>
+ <relativePath>../pom/maven/pom.xml</relativePath>
+ </parent>
+
+ <artifactId>maven</artifactId>
+ <version>3.3.3</version>
+ <packaging>pom</packaging>
+
+ <name>Apache Maven</name>
+ <description>Maven is a software build management and
+ comprehension tool. Based on the concept of a project object model:
+ builds, dependency management, documentation creation, site
+ publication, and distribution publication are all controlled from
+ the declarative file. Maven can be extended by plugins to utilise a
+ number of other development tools for reporting or the build
+ process.
+ </description>
+ <url>http://maven.apache.org/ref/${project.version}</url>
+ <inceptionYear>2001</inceptionYear>
+
+ <properties>
+ <maven.compiler.source>1.7</maven.compiler.source>
+ <maven.compiler.target>1.7</maven.compiler.target>
+ <classWorldsVersion>2.5.2</classWorldsVersion>
+ <commonsCliVersion>1.2</commonsCliVersion>
+ <junitVersion>4.11</junitVersion>
+ <plexusVersion>1.5.5</plexusVersion>
+ <plexusInterpolationVersion>1.21</plexusInterpolationVersion>
+ <plexusUtilsVersion>3.0.20</plexusUtilsVersion>
+ <!-- Latest version of Guava that works with Sisu -->
+ <guavaVersion>18.0</guavaVersion>
+ <guiceVersion>3.2.5</guiceVersion>
+ <sisuInjectVersion>0.3.0</sisuInjectVersion>
+ <wagonVersion>2.9</wagonVersion> <!-- Verify SNAPSHOT for MNG-5605 -->
+ <securityDispatcherVersion>1.3</securityDispatcherVersion>
+ <cipherVersion>1.7</cipherVersion>
+ <modelloVersion>1.8.1</modelloVersion>
+ <jxpathVersion>1.3</jxpathVersion>
+ <aetherVersion>1.0.2.v20150114</aetherVersion>
+ <slf4jVersion>1.7.5</slf4jVersion>
+ <maven.test.redirectTestOutputToFile>true</maven.test.redirectTestOutputToFile>
+ <!-- Control the name of the distribution and information output by mvn -->
+ <distributionId>apache-maven</distributionId>
+ <distributionShortName>Maven</distributionShortName>
+ <distributionName>Apache Maven</distributionName>
+ <maven.site.path>ref/3-LATEST</maven.site.path>
+ <checkstyle.violation.ignore>RedundantThrows,NewlineAtEndOfFile,ParameterNumber,MethodLength,FileLength,JavadocType,MagicNumber,InnerAssignment,MethodName</checkstyle.violation.ignore>
+ <checkstyle.excludes>**/package-info.java</checkstyle.excludes>
+ </properties>
+
+ <modules>
+ <module>maven-plugin-api</module>
+ <module>maven-builder-support</module>
+ <module>maven-model</module>
+ <module>maven-model-builder</module>
+ <module>maven-core</module>
+ <module>maven-settings</module>
+ <module>maven-settings-builder</module>
+ <module>maven-artifact</module>
+ <module>maven-aether-provider</module>
+ <module>maven-repository-metadata</module>
+ <module>maven-embedder</module>
+ <module>maven-compat</module>
+ <module>apache-maven</module>
+ </modules>
+
+ <scm>
+ <connection>scm:git:https://git-wip-us.apache.org/repos/asf/maven.git</connection>
+ <developerConnection>scm:git:https://git-wip-us.apache.org/repos/asf/maven.git</developerConnection>
+ <url>https://github.com/apache/maven/tree/${project.scm.tag}</url>
+ <tag>maven-3.3.3</tag>
+ </scm>
+ <issueManagement>
+ <system>jira</system>
+ <url>https://issues.apache.org/jira/browse/MNG</url>
+ </issueManagement>
+ <ciManagement>
+ <system>Jenkins</system>
+ <url>https://builds.apache.org/job/maven-3.x/</url>
+ </ciManagement>
+ <distributionManagement>
+ <downloadUrl>http://maven.apache.org/download.html</downloadUrl>
+ <site>
+ <id>apache.website</id>
+ <url>scm:svn:https://svn.apache.org/repos/infra/websites/production/maven/components/${maven.site.path}</url>
+ </site>
+ </distributionManagement>
+
+ <contributors>
+ <contributor>
+ <name>Stuart McCulloch</name>
+ </contributor>
+ <contributor>
+ <name>Christian Schulte (MNG-2199)</name>
+ </contributor>
+ <contributor>
+ <name>Christopher Tubbs (MNG-4226)</name>
+ </contributor>
+ <contributor>
+ <name>Konstantin Perikov (MNG-4565)</name>
+ </contributor>
+ <contributor>
+ <name>SĂ©bastian Le Merdy (MNG-5613)</name>
+ </contributor>
+ <contributor>
+ <name>Mark Ingram (MNG-5639)</name>
+ </contributor>
+ <contributor>
+ <name>Phil Pratt-Szeliga (MNG-5645)</name>
+ </contributor>
+ </contributors>
+
+ <prerequisites>
+ <maven>2.2.1</maven>
+ </prerequisites>
+
+ <!--bootstrap-start-comment-->
+ <dependencyManagement>
+ <!--bootstrap-end-comment-->
+ <dependencies>
+ <!-- Maven Modules -->
+ <!--bootstrap-start-comment-->
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-model</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-settings</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-settings-builder</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-plugin-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-embedder</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-core</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-model-builder</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-compat</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-artifact</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-aether-provider</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-repository-metadata</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-builder-support</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <!--bootstrap-end-comment-->
+ <!-- Plexus -->
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-utils</artifactId>
+ <version>${plexusUtilsVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ <version>${guavaVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.sonatype.sisu</groupId>
+ <artifactId>sisu-guice</artifactId>
+ <version>${guiceVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.sonatype.sisu</groupId>
+ <artifactId>sisu-guice</artifactId>
+ <version>${guiceVersion}</version>
+ <classifier>no_aop</classifier>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.sisu</groupId>
+ <artifactId>org.eclipse.sisu.plexus</artifactId>
+ <version>${sisuInjectVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-component-annotations</artifactId>
+ <version>${plexusVersion}</version>
+ <exclusions>
+ <exclusion>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-classworlds</artifactId>
+ <version>${classWorldsVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-interpolation</artifactId>
+ <version>${plexusInterpolationVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ <version>${slf4jVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-simple</artifactId>
+ <version>${slf4jVersion}</version>
+ <optional>true</optional>
+ </dependency>
+ <dependency>
+ <groupId>ch.qos.logback</groupId>
+ <artifactId>logback-classic</artifactId>
+ <version>1.0.7</version>
+ <optional>true</optional>
+ </dependency>
+ <!-- Wagon -->
+ <dependency>
+ <groupId>org.apache.maven.wagon</groupId>
+ <artifactId>wagon-provider-api</artifactId>
+ <version>${wagonVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.wagon</groupId>
+ <artifactId>wagon-file</artifactId>
+ <version>${wagonVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.wagon</groupId>
+ <artifactId>wagon-http</artifactId>
+ <version>${wagonVersion}</version>
+ <classifier>shaded</classifier>
+ <exclusions>
+ <exclusion>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <!-- Repository -->
+ <dependency>
+ <groupId>org.eclipse.aether</groupId>
+ <artifactId>aether-api</artifactId>
+ <version>${aetherVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.aether</groupId>
+ <artifactId>aether-spi</artifactId>
+ <version>${aetherVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.aether</groupId>
+ <artifactId>aether-impl</artifactId>
+ <version>${aetherVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.aether</groupId>
+ <artifactId>aether-util</artifactId>
+ <version>${aetherVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.aether</groupId>
+ <artifactId>aether-connector-basic</artifactId>
+ <version>${aetherVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.aether</groupId>
+ <artifactId>aether-transport-wagon</artifactId>
+ <version>${aetherVersion}</version>
+ </dependency>
+ <!-- Commons -->
+ <dependency>
+ <groupId>commons-cli</groupId>
+ <artifactId>commons-cli</artifactId>
+ <version>${commonsCliVersion}</version>
+ <exclusions>
+ <exclusion>
+ <groupId>commons-lang</groupId>
+ <artifactId>commons-lang</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>commons-jxpath</groupId>
+ <artifactId>commons-jxpath</artifactId>
+ <version>${jxpathVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.sonatype.plexus</groupId>
+ <artifactId>plexus-sec-dispatcher</artifactId>
+ <version>${securityDispatcherVersion}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.sonatype.plexus</groupId>
+ <artifactId>plexus-cipher</artifactId>
+ <version>${cipherVersion}</version>
+ </dependency>
+ </dependencies>
+ <!--bootstrap-start-comment-->
+ </dependencyManagement>
+ <!--bootstrap-end-comment-->
+ <!--bootstrap-start-comment-->
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>${junitVersion}</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+ <!--bootstrap-end-comment-->
+
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-component-metadata</artifactId>
+ <version>${plexusVersion}</version>
+ <executions>
+ <execution>
+ <goals>
+ <goal>generate-metadata</goal>
+ <goal>generate-test-metadata</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.eclipse.sisu</groupId>
+ <artifactId>sisu-maven-plugin</artifactId>
+ <version>${sisuInjectVersion}</version>
+ <executions>
+ <execution>
+ <goals>
+ <goal>main-index</goal>
+ <goal>test-index</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-release-plugin</artifactId>
+ <configuration>
+ <autoVersionSubmodules>true</autoVersionSubmodules>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <argLine>-Xmx256m</argLine>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.modello</groupId>
+ <artifactId>modello-maven-plugin</artifactId>
+ <version>${modelloVersion}</version>
+ <executions>
+ <execution>
+ <id>site-docs</id>
+ <phase>pre-site</phase>
+ <goals>
+ <goal>xdoc</goal>
+ <goal>xsd</goal>
+ </goals>
+ </execution>
+ <execution>
+ <id>standard</id>
+ <goals>
+ <goal>java</goal>
+ <goal>xpp3-reader</goal>
+ <goal>xpp3-writer</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <version>1.0.0</version>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>buildnumber-maven-plugin</artifactId>
+ <version>1.2</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-site-plugin</artifactId>
+ <configuration>
+ <topSiteURL>scm:svn:https://svn.apache.org/repos/infra/websites/production/maven/content/${maven.site.path}</topSiteURL>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-scm-publish-plugin</artifactId>
+ <version>1.1</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.rat</groupId>
+ <artifactId>apache-rat-plugin</artifactId>
+ <configuration>
+ <excludes>
+ <exclude>src/test/resources*/**</exclude>
+ <exclude>src/test/projects/**</exclude>
+ <exclude>src/test/remote-repo/**</exclude>
+ <exclude>**/*.odg</exclude>
+ </excludes>
+ </configuration>
+ </plugin>
+ <!--This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build itself.-->
+ <plugin>
+ <groupId>org.eclipse.m2e</groupId>
+ <artifactId>lifecycle-mapping</artifactId>
+ <version>1.0.0</version>
+ <configuration>
+ <lifecycleMappingMetadata>
+ <pluginExecutions>
+ <pluginExecution>
+ <pluginExecutionFilter>
+ <groupId>org.apache.rat</groupId>
+ <artifactId>apache-rat-plugin</artifactId>
+ <versionRange>[0.10,)</versionRange>
+ <goals>
+ <goal>check</goal>
+ </goals>
+ </pluginExecutionFilter>
+ <action>
+ <ignore />
+ </action>
+ </pluginExecution>
+ </pluginExecutions>
+ </lifecycleMappingMetadata>
+ </configuration>
+ </plugin>
+ <plugin><!-- TODO remove when upgrading parent to 27 -->
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-checkstyle-plugin</artifactId>
+ <version>2.14</version>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>animal-sniffer-maven-plugin</artifactId>
+ <version>1.13</version>
+ <configuration>
+ <signature>
+ <groupId>org.codehaus.mojo.signature</groupId>
+ <artifactId>java16</artifactId>
+ <version>1.1</version>
+ </signature>
+ </configuration>
+ <executions>
+ <execution>
+ <id>check-java-1.6-compat</id>
+ <phase>process-classes</phase>
+ <goals>
+ <goal>check</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-doap-plugin</artifactId>
+ <version>1.1</version>
+ <configuration>
+ <asfExtOptions>
+ <charter>The mission of the Apache Maven project is to create and maintain software
+ libraries that provide a widely-used project build tool, targeting mainly Java
+ development. Apache Maven promotes the use of dependencies via a
+ standardized coordinate system, binary plugins, and a standard build
+ lifecycle.</charter>
+ </asfExtOptions>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.rat</groupId>
+ <artifactId>apache-rat-plugin</artifactId>
+ <configuration>
+ <excludes combine.children="append">
+ <exclude>bootstrap/**</exclude>
+ <exclude>README.bootstrap.txt</exclude>
+ <exclude>.repository/**</exclude> <!-- jenkins with local maven repository -->
+ <exclude>.maven/spy.log</exclude> <!-- hudson maven3 integration log -->
+ <exclude>.java-version</exclude>
+ </excludes>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+ <profiles>
+ <profile>
+ <id>apache-release</id>
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>source-release-assembly</id>
+ <configuration>
+ <!-- we have a dedicated distribution module -->
+ <skipAssembly>true</skipAssembly>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ <profile>
+ <id>reporting</id>
+ <reporting>
+ <plugins>
+ <plugin><!-- TODO remove when upgrading parent to 27 -->
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-project-info-reports-plugin</artifactId>
+ <version>2.8</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ <configuration>
+ <linksource>true</linksource>
+ <notimestamp>true</notimestamp>
+ <quiet>true</quiet>
+ <links combine.children="append">
+ <link>http://download.eclipse.org/aether/aether-core/${aetherVersion}/apidocs/</link>
+ <link>http://plexus.codehaus.org/plexus-containers/plexus-container-default/apidocs/</link>
+ </links>
+ </configuration>
+ <reportSets>
+ <reportSet>
+ <id>aggregate</id>
+ <inherited>false</inherited>
+ <reports>
+ <report>aggregate</report>
+ </reports>
+ </reportSet>
+ </reportSets>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jxr-plugin</artifactId>
+ <reportSets>
+ <reportSet>
+ <id>aggregate</id>
+ <inherited>false</inherited>
+ <reports>
+ <report>aggregate</report>
+ </reports>
+ </reportSet>
+ </reportSets>
+ </plugin>
+ <plugin><!-- TODO remove when upgrading parent to 27 -->
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-checkstyle-plugin</artifactId>
+ <version>2.13</version>
+ </plugin>
+ </plugins>
+ </reporting>
+ </profile>
+ <profile>
+ <id>maven-repo-local</id>
+ <activation>
+ <property>
+ <name>maven.repo.local</name>
+ </property>
+ </activation>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <systemProperties combine.children="append">
+ <property>
+ <!-- Pass this through to the tests (if set!) to have them pick the right repository -->
+ <name>maven.repo.local</name>
+ <value>${maven.repo.local}</value>
+ </property>
+ </systemProperties>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
+</project>
diff --git a/framework/src/maven/apache-maven-3.3.3/src/site/resources/images/maven-deps.png b/framework/src/maven/apache-maven-3.3.3/src/site/resources/images/maven-deps.png
new file mode 100644
index 00000000..d23033fb
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/src/site/resources/images/maven-deps.png
Binary files differ
diff --git a/framework/src/maven/apache-maven-3.3.3/src/site/site.xml b/framework/src/maven/apache-maven-3.3.3/src/site/site.xml
new file mode 100644
index 00000000..bcc61034
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/src/site/site.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project xmlns="http://maven.apache.org/DECORATION/1.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/DECORATION/1.1.0 http://maven.apache.org/xsd/decoration-1.1.0.xsd"
+ name="Apache Maven">
+
+ <bannerLeft>
+ <name>${project.name}</name>
+ <src>http://maven.apache.org/images/apache-maven-project.png</src>
+ <href>http://maven.apache.org/</href>
+ </bannerLeft>
+ <bannerRight>
+ <src>http://maven.apache.org/images/maventxt_logo_200.gif</src>
+ </bannerRight>
+
+ <skin>
+ <groupId>org.apache.maven.skins</groupId>
+ <artifactId>maven-fluido-skin</artifactId>
+ <version>1.3.0</version>
+ </skin>
+
+ <body>
+ <breadcrumbs>
+ <item name="Ref" href="../" />
+ <item name="Maven ${project.version}" href="./" />
+ </breadcrumbs>
+
+ <menu name="Overview">
+ <item name="Introduction" href="index.html"/>
+ <item name="JavaDocs" href="apidocs/index.html"/>
+ <item name="Source Xref" href="xref/index.html"/>
+ <!--item name="FAQ" href="faq.html"/-->
+ </menu>
+
+ <menu name="Descriptors Reference">
+ <item name="POM" href="./maven-model/maven.html"/>
+ <item name="Settings" href="./maven-settings/settings.html"/>
+ <item name="Toolchains" href="./maven-core/toolchains.html"/>
+ </menu>
+
+ <menu name="Reference">
+ <item name="Lifecycles" href="./maven-core/lifecycles.html"/>
+ <item name="Plugin Bindings to Default Lifecycle" href="./maven-core/default-bindings.html"/>
+ <item name="Artifact Handlers" href="./maven-core/artifact-handlers.html"/>
+ <item name="CLI options" href="./maven-embedder/cli.html"/>
+ </menu>
+
+ <menu name="Development">
+ <item name="Maven Developer Centre" href="../../developers/index.html"/>
+ <item name="Maven Core ITs" href="../../core-its/index.html"/>
+ </menu>
+
+ <menu ref="modules"/>
+ <menu ref="reports"/>
+ </body>
+</project> \ No newline at end of file
diff --git a/framework/src/maven/apache-maven-3.3.3/src/site/xdoc/index.xml b/framework/src/maven/apache-maven-3.3.3/src/site/xdoc/index.xml
new file mode 100644
index 00000000..918824c4
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/src/site/xdoc/index.xml
@@ -0,0 +1,76 @@
+<?xml version="1.0"?>
+
+<!--
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+
+<document>
+
+ <properties>
+ <title>Introduction</title>
+ <author email="hboutemy_AT_apache_DOT_org">Hervé Boutemy</author>
+ </properties>
+
+ <body>
+
+ <section name="Apache Maven 3.x">
+
+ <p>Maven is a project development management and
+ comprehension tool. Based on the concept of a project object model:
+ builds, dependency management, documentation creation, site
+ publication, and distribution publication are all controlled from
+ <a href="./maven-model/maven.html">the <code>pom.xml</code> declarative file</a>. Maven can be extended by
+ <a href="http://maven.apache.org/plugins/">plugins</a> to utilise a
+ number of other development tools for reporting or the build
+ process.</p>
+
+ <p>
+ <img src="images/maven-deps.png" width="784" height="595" border="0" usemap="#Maven_dependencies" />
+ <map name="Maven_dependencies">
+ <area shape="rect" coords="228,1,361,36" alt="apache-maven" href="apache-maven/" />
+ <area shape="rect" coords="228,58,361,95" alt="maven-embedder" href="maven-embedder/" />
+ <area shape="rect" coords="228,116,361,152" alt="maven-compat" href="maven-compat/" />
+ <area shape="rect" coords="228,175,361,211" alt="maven-core" href="maven-core/" />
+ <area shape="rect" coords="118,233,275,269" alt="maven-aether-provider" href="maven-aether-provider/" />
+ <area shape="rect" coords="0,287,192,323" alt="maven-repository-metadata" href="maven-repository-metadata/" />
+ <area shape="rect" coords="245,342,343,378" alt="maven-plugin-api" href="maven-plugin-api/" />
+ <area shape="rect" coords="253,401,336,436" alt="maven-artifact" href="maven-artifact/" />
+ <area shape="rect" coords="296,234,442,270" alt="maven-builder-support" href="maven-builder-support/" />
+ <area shape="rect" coords="382,176,528,211" alt="maven-settings-builder" href="maven-settings-builder/" />
+ <area shape="rect" coords="446,234,537,269" alt="maven-settings" href="maven-settings/" />
+ <area shape="rect" coords="388,284,521,319" alt="maven-model-builder" href="maven-model-builder/" />
+ <area shape="rect" coords="409,342,500,378" alt="maven-model" href="maven-model/" />
+ <area shape="rect" coords="551,58,707,94" alt="commons-cli" href="http://commons.apache.org/cli/" />
+ <area shape="rect" coords="551,116,739,152" alt="wagon-provider-api" href="http://maven.apache.org/wagon/wagon-provider-api/" />
+ <area shape="rect" coords="550,175,690,211" alt="plexus-sec-dispatcher" href="http://plexus.codehaus.org/plexus-components/plexus-sec-dispatcher/project-reports.html" />
+ <area shape="rect" coords="581,230,660,265" alt="plexus-cipher" href="http://plexus.codehaus.org/plexus-components/plexus-cipher/project-reports.html" />
+ <area shape="rect" coords="551,284,707,320" alt="plexus-interpolation" href="http://plexus.codehaus.org/plexus-components/plexus-interpolation/" />
+ <area shape="rect" coords="551,359,776,395" alt="plexus-component-annotations" href="http://plexus.codehaus.org/plexus-containers/plexus-component-annotations/" />
+ <area shape="rect" coords="550,401,682,437" alt="plexus-classworlds" href="http://plexus.codehaus.org/plexus-classworlds/" />
+ <area shape="rect" coords="685,455,775,491" alt="plexus-utils" href="http://plexus.codehaus.org/plexus-utils/" />
+ <area shape="rect" coords="542,167,783,502" alt="plexus" href="http://plexus.codehaus.org/" />
+ <area shape="rect" coords="68,338,240,482" alt="aether" href="http://www.eclipse.org/projects/project_summary.php?projectid=technology.aether" />
+ <area shape="rect" coords="388,393,520,594" alt="sisu" href="http://www.eclipse.org/projects/project_summary.php?projectid=technology.sisu" />
+ <area shape="rect" coords="519,518,621,554" alt="guice" href="http://code.google.com/p/google-guice/" />
+ </map>
+ </p>
+ </section>
+
+ </body>
+
+</document>
diff --git a/framework/src/maven/apache-maven-3.3.3/src/site/xdoc/maven-deps.odg b/framework/src/maven/apache-maven-3.3.3/src/site/xdoc/maven-deps.odg
new file mode 100644
index 00000000..9d4193a8
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/src/site/xdoc/maven-deps.odg
Binary files differ